diff --git a/external/mit/isl/dist/AUTHORS b/external/mit/isl/dist/AUTHORS new file mode 100644 index 000000000000..4f7c2d6a458a --- /dev/null +++ b/external/mit/isl/dist/AUTHORS @@ -0,0 +1,71 @@ +isl was written by + + Sven Verdoolaege +2006-2007 Leiden Institute of Advanced Computer Science + Universiteit Leiden + Niels Bohrweg 1 + 2333 CA Leiden + The Netherlands +2008-2009 K.U.Leuven + Departement Computerwetenschappen + Celestijnenlaan 200A + B-3001 Leuven + Belgium +2010-2011 INRIA Saclay - Ile-de-France + Parc Club Orsay Universite, ZAC des vignes, 4 rue Jacques Monod + 91893 Orsay + France +2011-2012 consultant for Leiden Institute of Advanced Computer Science +2012-2014 Ecole Normale Superieure + 45 rue d'Ulm, 75230 Paris + France +2014-2015 INRIA Rocquencourt + Domaine de Voluceau - Rocquencourt, B.P. 105 + 78153 Le Chesnay + France +2015-2022 Polly Labs +2018-2021 Cerebras Systems + 175 S San Antonio Rd + Los Altos, CA + USA +2021-2022 Cerebras Systems + 1237 E Arques Ave + Sunnyvale, CA + USA + +Contributions by + +Mythri Alle +Riyadh Baghdadi +Serge Belyshev +Basile Clement +Albert Cohen +Ray Donnelly +Johannes Doerfert +Andi Drebes +Ron Estrin +Clement Foyer +Armin Groesslinger +Tobias Grosser +Frederik Harwath +Alexandre Isoard +Andreas Kloeckner +Michael Kruse +Manjunath Kudlur +Alexander Matz +Chielo Newctle +Riccardo Mori +Sebastian Pop +Louis-Noel Pouchet +Benoit Pradelle +Uday Bondhugula +Andreas Simbuerger +Tianjiao Sun +Malhar Thakkar +Sergei Trofimovich +Miheer Vaidya +Sven van Haastregt +Matt Whitlock +Oleksandr Zinenko + +The merge sort implementation was written by Jeffrey Stedfast. diff --git a/external/mit/isl/dist/ChangeLog b/external/mit/isl/dist/ChangeLog new file mode 100644 index 000000000000..a05f1522a960 --- /dev/null +++ b/external/mit/isl/dist/ChangeLog @@ -0,0 +1,267 @@ +version: 0.26 +date: Sat Apr 1 05:10:53 PM CEST 2023 +changes: + - fix inherited overloaded methods in Python bindings + - decompose topological sort of clusters in incremental scheduler + - improved isl_pw_aff_list_{min,max} + - add some convenience functions + - more exports to (templated C++) bindings + - slightly improved conversion from binary relation to function +--- +version: 0.25 +date: Sat 02 Jul 2022 11:14:57 AM CEST +changes: + - support (type safe) user object on id in bindings + - more exports to (templated C++) bindings + - add some convenience functions +--- +version: 0.24 +date: Sun 25 Apr 2021 03:56:37 PM CEST +changes: + - improved (C++) bindings (inherit methods, renamed exports) + - initial templated C++ bindings + - detect bounds on constant polynomials as tight +--- +version: 0.23 +date: Sun 01 Nov 2020 02:41:20 PM CET +changes: + - minor improvements to coalescing + - use build compiler to build extract_interface + - add some convenience functions + - ignore parameters in isl_union_* hash tables +--- +version: 0.22.1 +date: Sun Jan 12 10:48:18 CET 2020 +changes: + - fix error handling +--- +version: 0.22 +date: Fri Nov 1 18:39:30 CET 2019 +changes: + - require C++11 to generate bindings + - improved bindings + - scheduler fix involving fixed dimensions + - accept ranges in tuples during parsing + - add some convenience functions +--- +version: 0.21 +date: Sat Mar 9 15:25:29 CET 2019 +changes: + - preliminary C++ bindings + - use incremental scheduler by default + - introduce isl_size type + - rename isl_ast_op_type to isl_ast_expr_op_type + - fix coalescing bugs + - use isl_bool to return extra boolean argument +--- +version: 0.20 +date: Sat Jul 21 18:10:08 CEST 2018 +changes: + - keep track of domain in 0D isl_multi_pw_aff and isl_multi_union_pw_aff + - add isl_aff_eval and isl_pw_aff_eval + - add fixed-size rectangular box hull +--- +version: 0.19 +date: Sat Mar 3 10:44:49 CET 2018 +changes: + - minor improvements to coalescing + - minor improvement to parametric integer programming + - try harder to avoid large coefficients in scheduler + - support kill accesses in dependence analysis + - drop deprecated isl_int + - drop deprecated band forests + - drop deprecated functions +--- +version: 0.18 +date: Sun Dec 18 11:01:58 CET 2016 +changes: + - improve elimination of redundant existentially quantified variables + - improve coalescing + - improve parametric integer programming + - preserve isolate option in isl_schedule_node_band_split + - print AST nodes in YAML format + - minor improvements to Python bindings +--- +version: 0.17.1 +date: Fri May 6 12:02:48 CEST 2016 +changes: + - fix bug in coalescing treatment +--- +version: 0.17 +date: Tue May 3 14:26:43 CEST 2016 +changes: + - optionally combine SCCs incrementally in scheduler + - optionally maximize coincidence in scheduler + - optionally avoid loop coalescing in scheduler + - fix handling of nested integer divisions + - optionally detect min/max expressions during AST generation + - minor AST generator improvements + - simplify stride constraints + - improve support for expansions in schedule trees +--- +version: 0.16.1 +date: Thu Jan 14 18:08:06 CET 2016 +changes: + - fix bug in simplification +--- +version: 0.16 +date: Tue Jan 12 09:56:16 CET 2016 +changes: + - add 32 bit integer optimization for IMath + - minor AST generator improvements + - add isl_union_flow_get_full_{may,must}_dependence + - minor improvements to Python bindings + - minor improvements to set and map printing +--- +version: 0.15 +date: Thu Jun 11 12:45:33 CEST 2015 +changes: + - improve coalescing + - add isl_union_access_info_compute_flow + - add mark nodes in AST + - add isl_union_pw_aff and isl_multi_union_pw_aff + - add schedule trees + - deprecate band forests + - deprecate separation_class AST generation option + - introduce isl_bool and isl_stat types +--- +version: 0.14.1 +date: Thu Apr 9 12:57:23 CEST 2015 +changes: + - fix bug in affine expression normalization + - fix handling of conditional validity constraints +--- +version: 0.14 +date: Sat Oct 25 16:08:47 CEST 2014 +changes: + - support IMath as an optional replacement for GMP + - minor AST generator improvements +--- +version: 0.13 +date: Mon Apr 14 11:08:45 CEST 2014 +changes: + - deprecate isl_int + - improved support for multi piecewise quasi-affine expressions + - allow the user to impose a bound on the number of low-level operations + - add isl_id_to_ast_expr and isl_id_to_pw_aff + - add isl_schedule_constraints + - hide internal structure of isl_vec + - remove support for piplib +--- +version: 0.12.2 +date: Sun Jan 12 12:09:46 CET 2014 +changes: + - MinGW-w64 build fix + - fix simplification bug +--- +version: 0.12.1 +date: Wed Jul 24 12:54:46 CEST 2013 +changes: + - handle malloc returning NULL on zero-size allocation + - fix regression in AST generator +--- +version: 0.12 +date: Sun Jun 23 20:23:05 CEST 2013 +changes: + - add isl_val abstraction +--- +version: 0.11.2 +date: Tue Apr 9 18:45:10 CEST 2013 +changes: + - make code generation output the same on Solaris + - fix some hard to trigger bugs +--- +version: 0.11.1 +date: Mon Dec 10 11:55:30 CET 2012 +changes: + - add LICENSE file to distribution + - make code generation output independent of endianness +--- +version: 0.11 +date: Mon Dec 3 08:17:18 CET 2012 +changes: + - change license from LGPL 2.1 to MIT + - add support for multi piecewise quasi-affine expressions + - add code generation + - various minor bug fixes +--- +version: 0.10 +date: Sun Jun 3 18:00:16 CEST 2012 +changes: + - support for interaction with dependence analysis + - add public API for vectors + - improved support for (piecewise) multi quasi-affine expressions + - various minor bug fixes +--- +version: 0.09 +date: Sat Dec 17 18:19:26 CET 2011 +changes: + - improved argument parsing + - hide internal structure of isl_options + - improved support for parameter sets + - configurable scheduling +--- +version: 0.08 +date: Fri Oct 21 12:36:20 CEST 2011 +changes: + - improved parsing + - drop isl_div abstraction + - rename isl_dim to isl_space + - |- + explicitly differentiate between spaces of maps, + sets and parameter sets + - add support for identifiers + - add support for (piecewise) multi quasi-affine expressions + - preliminary Python bindings +--- +version: 0.07 +date: Tue Jul 12 19:34:51 CEST 2011 +changes: + - hide internal structures of isl_div and isl_constraint + - preliminary scheduling + - add support for local spaces and (piecewise) quasi-affine expressions +--- +version: 0.06 +date: Fri Mar 18 15:59:16 CET 2011 +changes: + - improved parsing + - consistency changes in API + - hide internal structure of isl_ctx +--- +version: 0.05.1 +date: Wed Jan 5 10:21:42 CET 2011 +changes: + - fix simple symmetry detection in parametric integer programming +--- +version: 0.05 +date: Thu Dec 23 17:03:14 CET 2010 +changes: + - rename header files from isl_header.h to isl/header.h + - add higher level interface for dependence analysis + - improved argument parsing + - optionally triangulate domains during Bernstein expansion + - support extended PolyLib format + - hide internal structure of some data types + - improved coalescing + - add simple symmetry detection in parametric integer programming +--- +version: 0.04 +date: Fri Sep 10 12:57:50 CEST 2010 +changes: + - rename isl_pw_qpolynomial_fold_add + - add isl_map_apply_pw_qpolynomial_fold + - support named and nested spaces + - support union sets and maps + - add public API for matrices +--- +version: 0.03 +date: Tue Jun 29 13:16:46 CEST 2010 +changes: + - new printing functions + - support for "may" accesses in dependence analysis + - improved coalescing + - improved transitive closure + - fix several hard to trigger bugs + - improved argument parsing + - support parametric vertex enumeration for barvinok + - optionally use Bernstein expansion to compute bounds diff --git a/external/mit/isl/dist/GIT_HEAD_ID b/external/mit/isl/dist/GIT_HEAD_ID new file mode 100644 index 000000000000..f30ff7b8760d --- /dev/null +++ b/external/mit/isl/dist/GIT_HEAD_ID @@ -0,0 +1 @@ +isl-0.26 diff --git a/external/mit/isl/dist/LICENSE b/external/mit/isl/dist/LICENSE new file mode 100644 index 000000000000..e93f5973e005 --- /dev/null +++ b/external/mit/isl/dist/LICENSE @@ -0,0 +1,19 @@ +MIT License (MIT) + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/external/mit/isl/dist/Makefile.am b/external/mit/isl/dist/Makefile.am new file mode 100644 index 000000000000..35da88f44c3a --- /dev/null +++ b/external/mit/isl/dist/Makefile.am @@ -0,0 +1,719 @@ +if HAVE_CLANG +if HAVE_CXX11 +MAYBE_INTERFACE = interface +FORCE: +interface/extract_interface$(BUILD_EXEEXT): FORCE + $(MAKE) $(AM_MAKEFLAGS) -C interface extract_interface$(BUILD_EXEEXT) +endif +endif +SUBDIRS = . $(MAYBE_INTERFACE) doc +DIST_SUBDIRS = $(MAYBE_INTERFACE) doc + +ACLOCAL_AMFLAGS = -I m4 +AUTOMAKE_OPTIONS = nostdinc subdir-objects + +lib_LTLIBRARIES = libisl.la +noinst_PROGRAMS = isl_test isl_polyhedron_sample isl_pip \ + isl_polyhedron_minimize isl_polytope_scan \ + isl_polyhedron_detect_equalities \ + isl_polyhedron_remove_redundant_equalities isl_cat \ + isl_closure isl_bound isl_schedule isl_codegen isl_test_int \ + isl_flow isl_flow_cmp isl_schedule_cmp +TESTS = isl_test codegen_test.sh pip_test.sh bound_test.sh isl_test_int \ + flow_test.sh schedule_test.sh +if HAVE_CPP_ISL_H + CPP_H = include/isl/cpp.h include/isl/typed_cpp.h +if HAVE_CXX11 + noinst_PROGRAMS += isl_test2 isl_test_cpp + TESTS += isl_test2 isl_test_cpp isl_test_cpp_failed.sh +endif +if HAVE_CXX17 + noinst_PROGRAMS += isl_test_cpp17 isl_test_cpp17-checked + TESTS += isl_test_cpp17 isl_test_cpp17-checked +endif +endif +if HAVE_CLANG +if HAVE_CXX11 + noinst_PROGRAMS += isl_test_cpp-checked isl_test_cpp-checked-conversion + TESTS += isl_test_cpp-checked isl_test_cpp-checked-conversion +if HAVE_PYTHON + TESTS += isl_test_python.py + noinst_PYTHON = interface/isl.py + isl_test_python.py: interface/isl.py libisl.la +endif +endif +endif +TEST_EXTENSIONS = .py +AM_TESTS_ENVIRONMENT = \ + export PYTHONPATH=interface; \ + export ISL_DYLD_LIBRARY_PATH=.libs; \ + export LD_LIBRARY_PATH=".libs:$(LD_LIBRARY_PATH)"; +PY_LOG_COMPILER = $(PYTHON) + +if IMATH_FOR_MP + +MP_SRC = \ + 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 + +noinst_PROGRAMS += isl_test_imath +TESTS += isl_test_imath + +if SMALL_INT_OPT +MP_SRC += isl_int_sioimath.h \ + isl_int_sioimath.c \ + isl_val_sioimath.c +else +MP_SRC += isl_val_imath.c +endif + +MP_INCLUDE_H = +endif + +if GMP_FOR_MP +if NEED_GET_MEMORY_FUNCTIONS +GET_MEMORY_FUNCTIONS=mp_get_memory_functions.c +endif + +MP_SRC = \ + $(GET_MEMORY_FUNCTIONS) \ + isl_int_gmp.h \ + isl_gmp.c \ + isl_val_gmp.c + +MP_INCLUDE_H = include/isl/val_gmp.h +endif + +includes = -I. -I$(srcdir) -I$(srcdir)/include -Iinclude/ +AM_CPPFLAGS = $(includes) @MP_CPPFLAGS@ +AM_CFLAGS = @WARNING_FLAGS@ @MP_CFLAGS@ + +libisl_la_SOURCES = \ + $(MP_SRC) \ + isl_aff.c \ + isl_aff_map.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_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_box.c \ + 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 \ + isl_ilp.c \ + isl_ilp_private.h \ + isl_input.c \ + isl_int.h \ + isl_list_private.h \ + isl_local_private.h \ + isl_local.h \ + isl_local.c \ + isl_local_space_private.h \ + isl_local_space.c \ + isl_lp.c \ + isl_lp_private.h \ + isl_map.c \ + isl_map_list.c \ + isl_map_simplify.c \ + isl_map_subtract.c \ + isl_map_private.h \ + isl_map_to_basic_set.c \ + isl_mat.c \ + isl_mat_private.h \ + isl_morph.c \ + isl_morph.h \ + isl_id.c \ + isl_id_private.h \ + isl_obj.c \ + isl_options.c \ + isl_options_private.h \ + isl_output.c \ + isl_output_private.h \ + isl_point_private.h \ + isl_point.c \ + isl_polynomial_private.h \ + isl_polynomial.c \ + isl_printer_private.h \ + isl_printer.c \ + print.c \ + isl_range.c \ + isl_range.h \ + isl_reordering.c \ + isl_reordering.h \ + isl_sample.h \ + isl_sample.c \ + isl_scan.c \ + isl_scan.h \ + isl_schedule.c \ + isl_schedule_band.c \ + isl_schedule_band.h \ + isl_schedule_node.c \ + isl_schedule_node_private.h \ + isl_schedule_read.c \ + isl_schedule_tree.c \ + isl_schedule_tree.h \ + isl_schedule_private.h \ + isl_schedule_constraints.c \ + isl_schedule_constraints.h \ + isl_scheduler.c \ + isl_scheduler.h \ + isl_scheduler_clustering.c \ + isl_scheduler_clustering.h \ + isl_scheduler_scc.c \ + isl_scheduler_scc.h \ + 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_set_to_ast_graft_list.c \ + isl_set_to_ast_graft_list.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 \ + isl_vertices_private.h \ + isl_vertices.c \ + isl_yaml.h +libisl_la_LIBADD = @MP_LIBS@ +libisl_la_LDFLAGS = -version-info @versioninfo@ \ + @MP_LDFLAGS@ + +isl_test_LDFLAGS = @MP_LDFLAGS@ +isl_test_LDADD = libisl.la @MP_LIBS@ + +isl_test2_SOURCES = \ + isl_test2.cc \ + include/isl/cpp.h +isl_test2_LDFLAGS = @MP_LDFLAGS@ +isl_test2_LDADD = libisl.la @MP_LIBS@ + +isl_test_int_LDFLAGS = @MP_LDFLAGS@ +isl_test_int_LDADD = libisl.la @MP_LIBS@ + +if IMATH_FOR_MP +isl_test_imath_LDFLAGS = @MP_LDFLAGS@ +isl_test_imath_LDADD = libisl.la @MP_LIBS@ +endif + +isl_polyhedron_sample_LDADD = libisl.la +isl_polyhedron_sample_SOURCES = \ + polyhedron_sample.c + +isl_pip_LDFLAGS = @MP_LDFLAGS@ +isl_pip_LDADD = libisl.la @MP_LIBS@ +isl_pip_SOURCES = \ + pip.c + +isl_schedule_LDFLAGS = @MP_LDFLAGS@ +isl_schedule_LDADD = libisl.la @MP_LIBS@ +isl_schedule_SOURCES = \ + schedule.c + +isl_schedule_cmp_LDFLAGS = @MP_LDFLAGS@ +isl_schedule_cmp_LDADD = libisl.la @MP_LIBS@ +isl_schedule_cmp_SOURCES = \ + schedule_cmp.c + +isl_flow_LDFLAGS = @MP_LDFLAGS@ +isl_flow_LDADD = libisl.la @MP_LIBS@ +isl_flow_SOURCES = \ + flow.c + +isl_flow_cmp_LDFLAGS = @MP_LDFLAGS@ +isl_flow_cmp_LDADD = libisl.la @MP_LIBS@ +isl_flow_cmp_SOURCES = \ + flow_cmp.c + +isl_codegen_LDFLAGS = @MP_LDFLAGS@ +isl_codegen_LDADD = libisl.la @MP_LIBS@ +isl_codegen_SOURCES = \ + codegen.c + +isl_bound_LDFLAGS = @MP_LDFLAGS@ +isl_bound_LDADD = libisl.la @MP_LIBS@ +isl_bound_SOURCES = \ + bound.c + +isl_polyhedron_minimize_LDFLAGS = @MP_LDFLAGS@ +isl_polyhedron_minimize_LDADD = libisl.la @MP_LIBS@ +isl_polyhedron_minimize_SOURCES = \ + polyhedron_minimize.c + +isl_polytope_scan_LDADD = libisl.la +isl_polytope_scan_SOURCES = \ + polytope_scan.c + +isl_polyhedron_detect_equalities_LDADD = libisl.la +isl_polyhedron_detect_equalities_SOURCES = \ + polyhedron_detect_equalities.c + +isl_polyhedron_remove_redundant_equalities_LDADD = libisl.la +isl_polyhedron_remove_redundant_equalities_SOURCES = \ + polyhedron_remove_redundant_equalities.c + +isl_cat_LDADD = libisl.la +isl_cat_SOURCES = \ + cat.c + +isl_closure_LDADD = libisl.la +isl_closure_SOURCES = \ + closure.c + +isl_test_cpp_CPPFLAGS = $(AM_CPPFLAGS) -UCOMPILE_ERROR +isl_test_cpp_SOURCES = \ + isl_test_cpp.cc \ + include/isl/cpp.h +isl_test_cpp_LDFLAGS = @MP_LDFLAGS@ +isl_test_cpp_LDADD = libisl.la @MP_LIBS@ + +# This program is not meant to be compiled by default. +# In fact it is meant not to be compilable. +# It is identical to isl_test_cpp, except that it gets compiled +# with the COMPILE_ERROR flag set. +EXTRA_PROGRAMS = isl_test_cpp_failed +isl_test_cpp_failed_CPPFLAGS = $(AM_CPPFLAGS) -DCOMPILE_ERROR +isl_test_cpp_failed_SOURCES = \ + isl_test_cpp.cc \ + include/isl/cpp.h +isl_test_cpp_failed_LDFLAGS = @MP_LDFLAGS@ +isl_test_cpp_failed_LDADD = libisl.la @MP_LIBS@ + +isl_test_cpp17_SOURCES = \ + isl_test_cpp17.cc \ + include/isl/cpp.h +isl_test_cpp17_LDFLAGS = @MP_LDFLAGS@ +isl_test_cpp17_LDADD = libisl.la @MP_LIBS@ + +isl_test_cpp_checked_SOURCES = \ + isl_test_cpp-checked.cc \ + include/isl/cpp-checked.h +isl_test_cpp_checked_LDFLAGS = @MP_LDFLAGS@ +isl_test_cpp_checked_LDADD = libisl.la @MP_LIBS@ + +isl_test_cpp17_checked_SOURCES = \ + isl_test_cpp17-checked.cc \ + include/isl/cpp.h +isl_test_cpp17_checked_LDFLAGS = @MP_LDFLAGS@ +isl_test_cpp17_checked_LDADD = libisl.la @MP_LIBS@ + +isl_test_cpp_checked_conversion_SOURCES = \ + isl_test_cpp-checked-conversion.cc \ + include/isl/cpp-checked-conversion.h +isl_test_cpp_checked_conversion_LDFLAGS = @MP_LDFLAGS@ +isl_test_cpp_checked_conversion_LDADD = libisl.la @MP_LIBS@ + +# dummy library that captures the dependencies on all headers +# that are relevant for the bindings +noinst_LIBRARIES = libdep.a +libdep_a_SOURCES = dep.c + +if HAVE_CLANG +if HAVE_CXX11 +interface/isldlname.py: libisl.la + $(AM_V_GEN) $(GREP) dlname $< | $(SED) -e 's/dlname/isl_dlname/' > $@ +interface/isl.py: interface/extract_interface$(BUILD_EXEEXT) libdep.a \ + python/isl.py.top interface/isldlname.py + (cat interface/isldlname.py $(srcdir)/python/isl.py.top && \ + interface/extract_interface$(BUILD_EXEEXT) --language=python \ + $(includes) $(srcdir)/all.h) \ + > $@ || (rm $@ && false) + +include/isl/cpp.h: interface/extract_interface$(BUILD_EXEEXT) libdep.a \ + cpp/cpp.h.top cpp/cpp.h.bot + $(MKDIR_P) "include/isl" && \ + (cat $(srcdir)/cpp/cpp.h.top $(srcdir)/all.h && \ + interface/extract_interface$(BUILD_EXEEXT) --language=cpp \ + $(includes) $(srcdir)/all.h && \ + cat $(srcdir)/cpp/cpp.h.bot) \ + > $@ || (rm $@ && false) + +include/isl/cpp-checked.h: interface/extract_interface$(BUILD_EXEEXT) libdep.a \ + cpp/cpp-checked.h.top cpp/cpp-checked.h.bot + $(MKDIR_P) "include/isl" && \ + (cat $(srcdir)/cpp/cpp-checked.h.top $(srcdir)/all.h && \ + interface/extract_interface$(BUILD_EXEEXT) \ + --language=cpp-checked \ + $(includes) $(srcdir)/all.h && \ + cat $(srcdir)/cpp/cpp-checked.h.bot) \ + > $@ || (rm $@ && false) + +include/isl/cpp-checked-conversion.h: \ + interface/extract_interface$(BUILD_EXEEXT) \ + libdep.a \ + cpp/cpp-checked-conversion.h.top \ + cpp/cpp-checked-conversion.h.bot + $(MKDIR_P) "include/isl" && \ + (cat $(srcdir)/cpp/cpp-checked-conversion.h.top && \ + interface/extract_interface$(BUILD_EXEEXT) \ + --language=cpp-checked-conversion \ + $(includes) $(srcdir)/all.h && \ + cat $(srcdir)/cpp/cpp-checked-conversion.h.bot) \ + > $@ || (rm $@ && false) + +include/isl/typed_cpp.h: interface/extract_interface$(BUILD_EXEEXT) \ + libdep.a cpp/typed_cpp.h.top cpp/typed_cpp.h.bot + $(MKDIR_P) "include/isl" && \ + (cat $(srcdir)/cpp/typed_cpp.h.top && \ + interface/extract_interface$(BUILD_EXEEXT) \ + --language=template-cpp \ + $(includes) $(srcdir)/all.h && \ + cat $(srcdir)/cpp/typed_cpp.h.bot) \ + > $@ || (rm $@ && false) +endif +endif + +nodist_pkginclude_HEADERS = \ + include/isl/stdint.h +pkginclude_HEADERS = \ + $(CPP_H) \ + $(MP_INCLUDE_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/constraint.h \ + include/isl/ctx.h \ + include/isl/fixed_box.h \ + include/isl/flow.h \ + include/isl/id.h \ + include/isl/id_type.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/space_type.h \ + include/isl/stream.h \ + include/isl/stride_info.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/val_type.h \ + include/isl/vec.h \ + include/isl/version.h \ + include/isl/vertices.h + +if HAVE_CLANG +if HAVE_CXX11 + CPP_INTERFACES = \ + include/isl/cpp.h \ + include/isl/cpp-checked.h \ + include/isl/cpp-checked-conversion.h \ + include/isl/typed_cpp.h +endif +endif +BUILT_SOURCES = gitversion.h $(CPP_INTERFACES) +CLEANFILES = \ + gitversion.h \ + interface/isldlname.py \ + interface/isl.py \ + interface/isl.pyc \ + interface/__pycache__/*.pyc \ + $(CPP_INTERFACES) + +DISTCLEANFILES = \ + isl-uninstalled.sh \ + isl-uninstalled.pc \ + isl.pc \ + isl.pc.in \ + include/isl/stdint.h + +EXTRA_DIST = \ + LICENSE \ + isl_config_post.h \ + isl_aff_lex_templ.c \ + isl_align_params_templ.c \ + isl_align_params_bin_templ.c \ + isl_ast_node_set_field_templ.c \ + basis_reduction_templ.c \ + isl_bind_domain_templ.c \ + bset_to_bmap.c \ + bset_from_bmap.c \ + isl_check_named_params_templ.c \ + check_parse_fail_test_templ.c \ + check_reparse_templ.c \ + check_reparse_test_templ.c \ + check_single_reference_templ.c \ + check_type_range_templ.c \ + isl_copy_tuple_id_templ.c \ + isl_domain_factor_templ.c \ + isl_drop_unused_params_templ.c \ + extract_key.c \ + isl_from_range_templ.c \ + isl_ilp_opt_fn_val_templ.c \ + isl_ilp_opt_multi_val_templ.c \ + isl_ilp_opt_val_templ.c \ + has_single_reference_templ.c \ + isl_insert_domain_templ.c \ + isl_list_macro.h \ + isl_list_templ.c \ + isl_list_templ.h \ + isl_list_read_templ.c \ + isl_list_read_yaml_templ.c \ + isl_map_bound_templ.c \ + isl_map_lexopt_templ.c \ + isl_maybe_ast_graft_list.h \ + isl_maybe_map.h \ + isl_multi_macro.h \ + isl_multi_bind_templ.c \ + isl_multi_explicit_domain.c \ + isl_multi_pw_aff_explicit_domain.c \ + isl_multi_union_pw_aff_explicit_domain.c \ + isl_multi_no_explicit_domain.c \ + isl_multi_no_domain_templ.c \ + isl_multi_templ.c \ + isl_multi_templ.h \ + isl_multi_add_constant_templ.c \ + isl_multi_align_set.c \ + isl_multi_align_union_set.c \ + isl_multi_apply_templ.c \ + isl_multi_apply_explicit_domain_templ.c \ + isl_multi_apply_no_explicit_domain_templ.c \ + isl_multi_apply_set_explicit_domain_templ.c \ + isl_multi_apply_set_no_explicit_domain_templ.c \ + isl_multi_apply_union_set_explicit_domain_templ.c \ + isl_multi_arith_templ.c \ + isl_multi_bin_val_templ.c \ + isl_multi_bind_domain_templ.c \ + isl_multi_check_domain_templ.c \ + isl_multi_cmp.c \ + isl_multi_coalesce.c \ + isl_multi_dim_id_templ.c \ + isl_multi_dims.c \ + isl_multi_domain_templ.c \ + isl_multi_domain_reverse_templ.c \ + isl_multi_floor.c \ + isl_multi_from_base_templ.c \ + isl_multi_from_tuple_templ.c \ + isl_multi_gist.c \ + isl_multi_hash.c \ + isl_multi_insert_domain_templ.c \ + isl_multi_intersect.c \ + isl_multi_identity_templ.c \ + isl_multi_locals_templ.c \ + isl_multi_min_max_templ.c \ + isl_multi_move_dims_templ.c \ + isl_multi_nan_templ.c \ + isl_multi_param_templ.c \ + isl_multi_product_templ.c \ + isl_multi_pw_aff_pullback_templ.c \ + isl_multi_read_no_explicit_domain_templ.c \ + isl_multi_splice_templ.c \ + isl_multi_tuple_id_templ.c \ + isl_multi_un_op_templ.c \ + isl_multi_unbind_params_templ.c \ + isl_multi_union_add_templ.c \ + isl_multi_zero_templ.c \ + isl_multi_zero_space_templ.c \ + isl_opt_mpa_templ.c \ + opt_type.h \ + print_templ.c \ + print_templ_yaml.c \ + print_yaml_field_templ.c \ + isl_power_templ.c \ + isl_project_out_all_params_templ.c \ + isl_project_out_param_templ.c \ + isl_pw_macro.h \ + isl_pw_templ.c \ + isl_pw_templ.h \ + isl_pw_add_constant_templ.c \ + isl_pw_add_constant_multi_val_templ.c \ + isl_pw_add_constant_val_templ.c \ + isl_pw_add_disjoint_templ.c \ + isl_pw_bind_domain_templ.c \ + isl_pw_domain_reverse_templ.c \ + isl_pw_eval.c \ + isl_pw_fix_templ.c \ + isl_pw_from_range_templ.c \ + isl_pw_hash.c \ + isl_pw_insert_dims_templ.c \ + isl_pw_insert_domain_templ.c \ + isl_pw_lift_templ.c \ + isl_pw_locals_templ.c \ + isl_pw_morph_templ.c \ + isl_pw_move_dims_templ.c \ + isl_pw_neg_templ.c \ + isl_pw_opt_templ.c \ + isl_pw_print_templ.c \ + isl_pw_pullback_templ.c \ + isl_pw_range_tuple_id_templ.c \ + isl_pw_scale_templ.c \ + isl_pw_split_dims_templ.c \ + isl_pw_sub_templ.c \ + isl_pw_un_op_templ.c \ + isl_pw_union_opt.c \ + isl_read_from_str_templ.c \ + read_in_string_templ.c \ + set_to_map.c \ + set_from_map.c \ + set_list_from_map_list_inl.c \ + isl_stream_read_pw_with_params_templ.c \ + isl_stream_read_with_params_templ.c \ + isl_tab_lexopt_templ.c \ + isl_test_list_templ.c \ + isl_test_plain_equal_templ.c \ + isl_type_check_equal_space_templ.c \ + isl_type_check_match_range_multi_val.c \ + isl_type_has_equal_space_bin_templ.c \ + isl_type_has_equal_space_templ.c \ + isl_type_has_space_templ.c \ + isl_unbind_params_templ.c \ + uset_to_umap.c \ + uset_from_umap.c \ + isl_union_macro.h \ + isl_union_templ.c \ + isl_union_single.c \ + isl_union_multi.c \ + isl_union_domain_reverse_templ.c \ + isl_union_eval.c \ + isl_union_locals_templ.c \ + isl_union_map_lex_templ.c \ + isl_union_neg.c \ + isl_union_print_templ.c \ + isl_union_pw_templ.c \ + isl_union_sub_templ.c \ + libisl-gdb.py \ + doc/CodingStyle \ + doc/SubmittingPatches \ + doc/implementation.tex \ + doc/isl.bib \ + doc/mypod2latex \ + doc/manual.tex \ + doc/reading.tex \ + doc/user.pod \ + imath/gmp_compat.c \ + imath/gmp_compat.h \ + imath/imath.c \ + imath/imath.h \ + imath/imrat.c \ + imath/imrat.h \ + all.h \ + cpp \ + python \ + isl_test_cpp-generic.cc \ + isl_test_cpp_failed.sh \ + isl_test_cpp17-generic.cc \ + isl_test_python.py \ + test_inputs + +dist-hook: + echo @GIT_HEAD_VERSION@ > $(distdir)/GIT_HEAD_ID + (cd doc; make manual.pdf) + cp doc/manual.pdf $(distdir)/doc/ + +pkgconfigdir=$(pkgconfig_libdir) +pkgconfig_DATA = $(pkgconfig_libfile) + +gitversion.h: @GIT_HEAD@ + $(AM_V_GEN)echo '#define GIT_HEAD_ID "'@GIT_HEAD_VERSION@'"' > $@ + +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)/libisl-gdb.py \ + $(DESTDIR)$(libdir)/$$libisl-gdb.py; \ + test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)"; \ + $(INSTALL_DATA) $(srcdir)/libisl-gdb.py \ + $(DESTDIR)$(libdir)/$$libisl-gdb.py; \ + esac + +uninstall-local: + @libisl=`sed -ne "/^library_names=/{s/.*='//;s/'$$//;s/ .*//;p;}" \ + $(builddir)/libisl.la`; \ + if test -n "$${libisl}"; then \ + rm -f $(DESTDIR)$(libdir)/$$libisl-gdb.py; \ + fi diff --git a/external/mit/isl/dist/Makefile.in b/external/mit/isl/dist/Makefile.in new file mode 100644 index 000000000000..5a87ed1002ea --- /dev/null +++ b/external/mit/isl/dist/Makefile.in @@ -0,0 +1,3165 @@ +# Makefile.in generated by automake 1.16.5 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2021 Free Software Foundation, Inc. + +# This Makefile.in 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. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + + + + + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +noinst_PROGRAMS = isl_test$(EXEEXT) isl_polyhedron_sample$(EXEEXT) \ + isl_pip$(EXEEXT) isl_polyhedron_minimize$(EXEEXT) \ + isl_polytope_scan$(EXEEXT) \ + isl_polyhedron_detect_equalities$(EXEEXT) \ + isl_polyhedron_remove_redundant_equalities$(EXEEXT) \ + isl_cat$(EXEEXT) isl_closure$(EXEEXT) isl_bound$(EXEEXT) \ + isl_schedule$(EXEEXT) isl_codegen$(EXEEXT) \ + isl_test_int$(EXEEXT) isl_flow$(EXEEXT) isl_flow_cmp$(EXEEXT) \ + isl_schedule_cmp$(EXEEXT) $(am__EXEEXT_1) $(am__EXEEXT_2) \ + $(am__EXEEXT_3) $(am__EXEEXT_4) +TESTS = isl_test$(EXEEXT) codegen_test.sh pip_test.sh bound_test.sh \ + isl_test_int$(EXEEXT) flow_test.sh schedule_test.sh \ + $(am__EXEEXT_5) $(am__EXEEXT_2) $(am__EXEEXT_3) \ + $(am__append_7) $(am__EXEEXT_4) +@HAVE_CPP_ISL_H_TRUE@@HAVE_CXX11_TRUE@am__append_1 = isl_test2 isl_test_cpp +@HAVE_CPP_ISL_H_TRUE@@HAVE_CXX11_TRUE@am__append_2 = isl_test2 isl_test_cpp isl_test_cpp_failed.sh +@HAVE_CPP_ISL_H_TRUE@@HAVE_CXX17_TRUE@am__append_3 = isl_test_cpp17 isl_test_cpp17-checked +@HAVE_CPP_ISL_H_TRUE@@HAVE_CXX17_TRUE@am__append_4 = isl_test_cpp17 isl_test_cpp17-checked +@HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@am__append_5 = isl_test_cpp-checked isl_test_cpp-checked-conversion +@HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@am__append_6 = isl_test_cpp-checked isl_test_cpp-checked-conversion +@HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@@HAVE_PYTHON_TRUE@am__append_7 = isl_test_python.py +@IMATH_FOR_MP_TRUE@am__append_8 = isl_test_imath +@IMATH_FOR_MP_TRUE@am__append_9 = isl_test_imath +@IMATH_FOR_MP_TRUE@@SMALL_INT_OPT_TRUE@am__append_10 = isl_int_sioimath.h \ +@IMATH_FOR_MP_TRUE@@SMALL_INT_OPT_TRUE@ isl_int_sioimath.c \ +@IMATH_FOR_MP_TRUE@@SMALL_INT_OPT_TRUE@ isl_val_sioimath.c + +@IMATH_FOR_MP_TRUE@@SMALL_INT_OPT_FALSE@am__append_11 = isl_val_imath.c +EXTRA_PROGRAMS = isl_test_cpp_failed$(EXEEXT) +subdir = . +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ax_c___attribute__.m4 \ + $(top_srcdir)/m4/ax_cc_maxopt.m4 \ + $(top_srcdir)/m4/ax_check_compile_flag.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_cxx_compile_stdcxx_11_no_override.m4 \ + $(top_srcdir)/m4/ax_cxx_compile_stdcxx_17.m4 \ + $(top_srcdir)/m4/ax_detect_git_head.m4 \ + $(top_srcdir)/m4/ax_detect_gmp.m4 \ + $(top_srcdir)/m4/ax_detect_imath.m4 \ + $(top_srcdir)/m4/ax_gcc_archflag.m4 \ + $(top_srcdir)/m4/ax_gcc_warn_unused_result.m4 \ + $(top_srcdir)/m4/ax_gcc_x86_cpuid.m4 \ + $(top_srcdir)/m4/ax_prog_cc_for_build.m4 \ + $(top_srcdir)/m4/ax_set_warning_flags.m4 \ + $(top_srcdir)/m4/ax_submodule.m4 $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \ + $(am__configure_deps) $(am__noinst_PYTHON_DIST) \ + $(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 +CONFIG_HEADER = isl_config.h +CONFIG_CLEAN_FILES = isl_srcdir.c bound_test.sh codegen_test.sh \ + pip_test.sh flow_test.sh schedule_test.sh +CONFIG_CLEAN_VPATH_FILES = +@HAVE_CPP_ISL_H_TRUE@@HAVE_CXX11_TRUE@am__EXEEXT_1 = \ +@HAVE_CPP_ISL_H_TRUE@@HAVE_CXX11_TRUE@ isl_test2$(EXEEXT) \ +@HAVE_CPP_ISL_H_TRUE@@HAVE_CXX11_TRUE@ isl_test_cpp$(EXEEXT) +@HAVE_CPP_ISL_H_TRUE@@HAVE_CXX17_TRUE@am__EXEEXT_2 = \ +@HAVE_CPP_ISL_H_TRUE@@HAVE_CXX17_TRUE@ isl_test_cpp17$(EXEEXT) \ +@HAVE_CPP_ISL_H_TRUE@@HAVE_CXX17_TRUE@ isl_test_cpp17-checked$(EXEEXT) +@HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@am__EXEEXT_3 = isl_test_cpp-checked$(EXEEXT) \ +@HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@ isl_test_cpp-checked-conversion$(EXEEXT) +@IMATH_FOR_MP_TRUE@am__EXEEXT_4 = isl_test_imath$(EXEEXT) +PROGRAMS = $(noinst_PROGRAMS) +LIBRARIES = $(noinst_LIBRARIES) +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(pkgconfigdir)" \ + "$(DESTDIR)$(pkgincludedir)" "$(DESTDIR)$(pkgincludedir)" +LTLIBRARIES = $(lib_LTLIBRARIES) +ARFLAGS = cru +AM_V_AR = $(am__v_AR_@AM_V@) +am__v_AR_ = $(am__v_AR_@AM_DEFAULT_V@) +am__v_AR_0 = @echo " AR " $@; +am__v_AR_1 = +libdep_a_AR = $(AR) $(ARFLAGS) +libdep_a_LIBADD = +am_libdep_a_OBJECTS = dep.$(OBJEXT) +libdep_a_OBJECTS = $(am_libdep_a_OBJECTS) +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_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_map.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_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_box.c \ + 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 \ + isl_ilp.c isl_ilp_private.h isl_input.c isl_int.h \ + isl_list_private.h isl_local_private.h isl_local.h isl_local.c \ + isl_local_space_private.h isl_local_space.c isl_lp.c \ + isl_lp_private.h isl_map.c isl_map_list.c isl_map_simplify.c \ + isl_map_subtract.c isl_map_private.h isl_map_to_basic_set.c \ + isl_mat.c isl_mat_private.h isl_morph.c isl_morph.h isl_id.c \ + isl_id_private.h isl_obj.c isl_options.c isl_options_private.h \ + isl_output.c isl_output_private.h isl_point_private.h \ + isl_point.c isl_polynomial_private.h isl_polynomial.c \ + isl_printer_private.h isl_printer.c print.c isl_range.c \ + isl_range.h isl_reordering.c isl_reordering.h isl_sample.h \ + isl_sample.c isl_scan.c isl_scan.h isl_schedule.c \ + isl_schedule_band.c isl_schedule_band.h isl_schedule_node.c \ + isl_schedule_node_private.h isl_schedule_read.c \ + isl_schedule_tree.c isl_schedule_tree.h isl_schedule_private.h \ + isl_schedule_constraints.c isl_schedule_constraints.h \ + isl_scheduler.c isl_scheduler.h isl_scheduler_clustering.c \ + isl_scheduler_clustering.h isl_scheduler_scc.c \ + isl_scheduler_scc.h 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_set_to_ast_graft_list.c isl_set_to_ast_graft_list.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 \ + isl_vertices_private.h isl_vertices.c isl_yaml.h +@GMP_FOR_MP_TRUE@@NEED_GET_MEMORY_FUNCTIONS_TRUE@am__objects_1 = mp_get_memory_functions.lo +am__dirstamp = $(am__leading_dot)dirstamp +@IMATH_FOR_MP_TRUE@@SMALL_INT_OPT_TRUE@am__objects_2 = \ +@IMATH_FOR_MP_TRUE@@SMALL_INT_OPT_TRUE@ isl_int_sioimath.lo \ +@IMATH_FOR_MP_TRUE@@SMALL_INT_OPT_TRUE@ isl_val_sioimath.lo +@IMATH_FOR_MP_TRUE@@SMALL_INT_OPT_FALSE@am__objects_3 = \ +@IMATH_FOR_MP_TRUE@@SMALL_INT_OPT_FALSE@ isl_val_imath.lo +@GMP_FOR_MP_FALSE@@IMATH_FOR_MP_TRUE@am__objects_4 = isl_imath.lo \ +@GMP_FOR_MP_FALSE@@IMATH_FOR_MP_TRUE@ imath_wrap/gmp_compat.lo \ +@GMP_FOR_MP_FALSE@@IMATH_FOR_MP_TRUE@ imath_wrap/imath.lo \ +@GMP_FOR_MP_FALSE@@IMATH_FOR_MP_TRUE@ imath_wrap/imrat.lo \ +@GMP_FOR_MP_FALSE@@IMATH_FOR_MP_TRUE@ $(am__objects_2) \ +@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 +am_libisl_la_OBJECTS = $(am__objects_4) isl_aff.lo isl_aff_map.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_box.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_scheduler_clustering.lo isl_scheduler_scc.lo \ + isl_set_list.lo isl_sort.lo isl_space.lo isl_stream.lo \ + isl_seq.lo isl_set_to_ast_graft_list.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 +libisl_la_OBJECTS = $(am_libisl_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +libisl_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(libisl_la_LDFLAGS) $(LDFLAGS) -o $@ +am_isl_bound_OBJECTS = bound.$(OBJEXT) +isl_bound_OBJECTS = $(am_isl_bound_OBJECTS) +isl_bound_DEPENDENCIES = libisl.la +isl_bound_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(isl_bound_LDFLAGS) $(LDFLAGS) -o $@ +am_isl_cat_OBJECTS = cat.$(OBJEXT) +isl_cat_OBJECTS = $(am_isl_cat_OBJECTS) +isl_cat_DEPENDENCIES = libisl.la +am_isl_closure_OBJECTS = closure.$(OBJEXT) +isl_closure_OBJECTS = $(am_isl_closure_OBJECTS) +isl_closure_DEPENDENCIES = libisl.la +am_isl_codegen_OBJECTS = codegen.$(OBJEXT) +isl_codegen_OBJECTS = $(am_isl_codegen_OBJECTS) +isl_codegen_DEPENDENCIES = libisl.la +isl_codegen_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(isl_codegen_LDFLAGS) $(LDFLAGS) -o $@ +am_isl_flow_OBJECTS = flow.$(OBJEXT) +isl_flow_OBJECTS = $(am_isl_flow_OBJECTS) +isl_flow_DEPENDENCIES = libisl.la +isl_flow_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(isl_flow_LDFLAGS) $(LDFLAGS) -o $@ +am_isl_flow_cmp_OBJECTS = flow_cmp.$(OBJEXT) +isl_flow_cmp_OBJECTS = $(am_isl_flow_cmp_OBJECTS) +isl_flow_cmp_DEPENDENCIES = libisl.la +isl_flow_cmp_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(isl_flow_cmp_LDFLAGS) $(LDFLAGS) -o $@ +am_isl_pip_OBJECTS = pip.$(OBJEXT) +isl_pip_OBJECTS = $(am_isl_pip_OBJECTS) +isl_pip_DEPENDENCIES = libisl.la +isl_pip_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(isl_pip_LDFLAGS) $(LDFLAGS) -o $@ +am_isl_polyhedron_detect_equalities_OBJECTS = \ + polyhedron_detect_equalities.$(OBJEXT) +isl_polyhedron_detect_equalities_OBJECTS = \ + $(am_isl_polyhedron_detect_equalities_OBJECTS) +isl_polyhedron_detect_equalities_DEPENDENCIES = libisl.la +am_isl_polyhedron_minimize_OBJECTS = polyhedron_minimize.$(OBJEXT) +isl_polyhedron_minimize_OBJECTS = \ + $(am_isl_polyhedron_minimize_OBJECTS) +isl_polyhedron_minimize_DEPENDENCIES = libisl.la +isl_polyhedron_minimize_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(AM_CFLAGS) $(CFLAGS) $(isl_polyhedron_minimize_LDFLAGS) \ + $(LDFLAGS) -o $@ +am_isl_polyhedron_remove_redundant_equalities_OBJECTS = \ + polyhedron_remove_redundant_equalities.$(OBJEXT) +isl_polyhedron_remove_redundant_equalities_OBJECTS = \ + $(am_isl_polyhedron_remove_redundant_equalities_OBJECTS) +isl_polyhedron_remove_redundant_equalities_DEPENDENCIES = libisl.la +am_isl_polyhedron_sample_OBJECTS = polyhedron_sample.$(OBJEXT) +isl_polyhedron_sample_OBJECTS = $(am_isl_polyhedron_sample_OBJECTS) +isl_polyhedron_sample_DEPENDENCIES = libisl.la +am_isl_polytope_scan_OBJECTS = polytope_scan.$(OBJEXT) +isl_polytope_scan_OBJECTS = $(am_isl_polytope_scan_OBJECTS) +isl_polytope_scan_DEPENDENCIES = libisl.la +am_isl_schedule_OBJECTS = schedule.$(OBJEXT) +isl_schedule_OBJECTS = $(am_isl_schedule_OBJECTS) +isl_schedule_DEPENDENCIES = libisl.la +isl_schedule_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(isl_schedule_LDFLAGS) $(LDFLAGS) -o $@ +am_isl_schedule_cmp_OBJECTS = schedule_cmp.$(OBJEXT) +isl_schedule_cmp_OBJECTS = $(am_isl_schedule_cmp_OBJECTS) +isl_schedule_cmp_DEPENDENCIES = libisl.la +isl_schedule_cmp_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(AM_CFLAGS) $(CFLAGS) $(isl_schedule_cmp_LDFLAGS) $(LDFLAGS) \ + -o $@ +isl_test_SOURCES = isl_test.c +isl_test_OBJECTS = isl_test.$(OBJEXT) +isl_test_DEPENDENCIES = libisl.la +isl_test_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(isl_test_LDFLAGS) $(LDFLAGS) -o $@ +am_isl_test2_OBJECTS = isl_test2.$(OBJEXT) +isl_test2_OBJECTS = $(am_isl_test2_OBJECTS) +isl_test2_DEPENDENCIES = libisl.la +isl_test2_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ + $(CXXFLAGS) $(isl_test2_LDFLAGS) $(LDFLAGS) -o $@ +am_isl_test_cpp_OBJECTS = isl_test_cpp-isl_test_cpp.$(OBJEXT) +isl_test_cpp_OBJECTS = $(am_isl_test_cpp_OBJECTS) +isl_test_cpp_DEPENDENCIES = libisl.la +isl_test_cpp_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ + $(CXXFLAGS) $(isl_test_cpp_LDFLAGS) $(LDFLAGS) -o $@ +am_isl_test_cpp_checked_OBJECTS = isl_test_cpp-checked.$(OBJEXT) +isl_test_cpp_checked_OBJECTS = $(am_isl_test_cpp_checked_OBJECTS) +isl_test_cpp_checked_DEPENDENCIES = libisl.la +isl_test_cpp_checked_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \ + $(AM_CXXFLAGS) $(CXXFLAGS) $(isl_test_cpp_checked_LDFLAGS) \ + $(LDFLAGS) -o $@ +am_isl_test_cpp_checked_conversion_OBJECTS = \ + isl_test_cpp-checked-conversion.$(OBJEXT) +isl_test_cpp_checked_conversion_OBJECTS = \ + $(am_isl_test_cpp_checked_conversion_OBJECTS) +isl_test_cpp_checked_conversion_DEPENDENCIES = libisl.la +isl_test_cpp_checked_conversion_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \ + $(AM_CXXFLAGS) $(CXXFLAGS) \ + $(isl_test_cpp_checked_conversion_LDFLAGS) $(LDFLAGS) -o $@ +am_isl_test_cpp17_OBJECTS = isl_test_cpp17.$(OBJEXT) +isl_test_cpp17_OBJECTS = $(am_isl_test_cpp17_OBJECTS) +isl_test_cpp17_DEPENDENCIES = libisl.la +isl_test_cpp17_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \ + $(AM_CXXFLAGS) $(CXXFLAGS) $(isl_test_cpp17_LDFLAGS) \ + $(LDFLAGS) -o $@ +am_isl_test_cpp17_checked_OBJECTS = isl_test_cpp17-checked.$(OBJEXT) +isl_test_cpp17_checked_OBJECTS = $(am_isl_test_cpp17_checked_OBJECTS) +isl_test_cpp17_checked_DEPENDENCIES = libisl.la +isl_test_cpp17_checked_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \ + $(AM_CXXFLAGS) $(CXXFLAGS) $(isl_test_cpp17_checked_LDFLAGS) \ + $(LDFLAGS) -o $@ +am_isl_test_cpp_failed_OBJECTS = \ + isl_test_cpp_failed-isl_test_cpp.$(OBJEXT) +isl_test_cpp_failed_OBJECTS = $(am_isl_test_cpp_failed_OBJECTS) +isl_test_cpp_failed_DEPENDENCIES = libisl.la +isl_test_cpp_failed_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \ + $(AM_CXXFLAGS) $(CXXFLAGS) $(isl_test_cpp_failed_LDFLAGS) \ + $(LDFLAGS) -o $@ +isl_test_imath_SOURCES = isl_test_imath.c +isl_test_imath_OBJECTS = isl_test_imath.$(OBJEXT) +@IMATH_FOR_MP_TRUE@isl_test_imath_DEPENDENCIES = libisl.la +isl_test_imath_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(AM_CFLAGS) $(CFLAGS) $(isl_test_imath_LDFLAGS) $(LDFLAGS) -o \ + $@ +isl_test_int_SOURCES = isl_test_int.c +isl_test_int_OBJECTS = isl_test_int.$(OBJEXT) +isl_test_int_DEPENDENCIES = libisl.la +isl_test_int_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(isl_test_int_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/basis_reduction_tab.Plo \ + ./$(DEPDIR)/bound.Po ./$(DEPDIR)/cat.Po ./$(DEPDIR)/closure.Po \ + ./$(DEPDIR)/codegen.Po ./$(DEPDIR)/dep.Po ./$(DEPDIR)/flow.Po \ + ./$(DEPDIR)/flow_cmp.Po ./$(DEPDIR)/isl_aff.Plo \ + ./$(DEPDIR)/isl_aff_map.Plo ./$(DEPDIR)/isl_affine_hull.Plo \ + ./$(DEPDIR)/isl_arg.Plo ./$(DEPDIR)/isl_ast.Plo \ + ./$(DEPDIR)/isl_ast_build.Plo \ + ./$(DEPDIR)/isl_ast_build_expr.Plo \ + ./$(DEPDIR)/isl_ast_codegen.Plo ./$(DEPDIR)/isl_ast_graft.Plo \ + ./$(DEPDIR)/isl_bernstein.Plo ./$(DEPDIR)/isl_blk.Plo \ + ./$(DEPDIR)/isl_bound.Plo ./$(DEPDIR)/isl_box.Plo \ + ./$(DEPDIR)/isl_coalesce.Plo ./$(DEPDIR)/isl_constraint.Plo \ + ./$(DEPDIR)/isl_convex_hull.Plo ./$(DEPDIR)/isl_ctx.Plo \ + ./$(DEPDIR)/isl_deprecated.Plo ./$(DEPDIR)/isl_dim_map.Plo \ + ./$(DEPDIR)/isl_equalities.Plo \ + ./$(DEPDIR)/isl_factorization.Plo ./$(DEPDIR)/isl_farkas.Plo \ + ./$(DEPDIR)/isl_ffs.Plo ./$(DEPDIR)/isl_flow.Plo \ + ./$(DEPDIR)/isl_fold.Plo ./$(DEPDIR)/isl_gmp.Plo \ + ./$(DEPDIR)/isl_hash.Plo ./$(DEPDIR)/isl_id.Plo \ + ./$(DEPDIR)/isl_id_to_ast_expr.Plo \ + ./$(DEPDIR)/isl_id_to_id.Plo ./$(DEPDIR)/isl_id_to_pw_aff.Plo \ + ./$(DEPDIR)/isl_ilp.Plo ./$(DEPDIR)/isl_imath.Plo \ + ./$(DEPDIR)/isl_input.Plo ./$(DEPDIR)/isl_int_sioimath.Plo \ + ./$(DEPDIR)/isl_local.Plo ./$(DEPDIR)/isl_local_space.Plo \ + ./$(DEPDIR)/isl_lp.Plo ./$(DEPDIR)/isl_map.Plo \ + ./$(DEPDIR)/isl_map_list.Plo ./$(DEPDIR)/isl_map_simplify.Plo \ + ./$(DEPDIR)/isl_map_subtract.Plo \ + ./$(DEPDIR)/isl_map_to_basic_set.Plo ./$(DEPDIR)/isl_mat.Plo \ + ./$(DEPDIR)/isl_morph.Plo ./$(DEPDIR)/isl_obj.Plo \ + ./$(DEPDIR)/isl_options.Plo ./$(DEPDIR)/isl_output.Plo \ + ./$(DEPDIR)/isl_point.Plo ./$(DEPDIR)/isl_polynomial.Plo \ + ./$(DEPDIR)/isl_printer.Plo ./$(DEPDIR)/isl_range.Plo \ + ./$(DEPDIR)/isl_reordering.Plo ./$(DEPDIR)/isl_sample.Plo \ + ./$(DEPDIR)/isl_scan.Plo ./$(DEPDIR)/isl_schedule.Plo \ + ./$(DEPDIR)/isl_schedule_band.Plo \ + ./$(DEPDIR)/isl_schedule_constraints.Plo \ + ./$(DEPDIR)/isl_schedule_node.Plo \ + ./$(DEPDIR)/isl_schedule_read.Plo \ + ./$(DEPDIR)/isl_schedule_tree.Plo \ + ./$(DEPDIR)/isl_scheduler.Plo \ + ./$(DEPDIR)/isl_scheduler_clustering.Plo \ + ./$(DEPDIR)/isl_scheduler_scc.Plo ./$(DEPDIR)/isl_seq.Plo \ + ./$(DEPDIR)/isl_set_list.Plo \ + ./$(DEPDIR)/isl_set_to_ast_graft_list.Plo \ + ./$(DEPDIR)/isl_sort.Plo ./$(DEPDIR)/isl_space.Plo \ + ./$(DEPDIR)/isl_stream.Plo ./$(DEPDIR)/isl_stride.Plo \ + ./$(DEPDIR)/isl_tab.Plo ./$(DEPDIR)/isl_tab_pip.Plo \ + ./$(DEPDIR)/isl_tarjan.Plo ./$(DEPDIR)/isl_test.Po \ + ./$(DEPDIR)/isl_test2.Po \ + ./$(DEPDIR)/isl_test_cpp-checked-conversion.Po \ + ./$(DEPDIR)/isl_test_cpp-checked.Po \ + ./$(DEPDIR)/isl_test_cpp-isl_test_cpp.Po \ + ./$(DEPDIR)/isl_test_cpp17-checked.Po \ + ./$(DEPDIR)/isl_test_cpp17.Po \ + ./$(DEPDIR)/isl_test_cpp_failed-isl_test_cpp.Po \ + ./$(DEPDIR)/isl_test_imath.Po ./$(DEPDIR)/isl_test_int.Po \ + ./$(DEPDIR)/isl_transitive_closure.Plo \ + ./$(DEPDIR)/isl_union_map.Plo ./$(DEPDIR)/isl_val.Plo \ + ./$(DEPDIR)/isl_val_gmp.Plo ./$(DEPDIR)/isl_val_imath.Plo \ + ./$(DEPDIR)/isl_val_sioimath.Plo ./$(DEPDIR)/isl_vec.Plo \ + ./$(DEPDIR)/isl_version.Plo ./$(DEPDIR)/isl_vertices.Plo \ + ./$(DEPDIR)/mp_get_memory_functions.Plo ./$(DEPDIR)/pip.Po \ + ./$(DEPDIR)/polyhedron_detect_equalities.Po \ + ./$(DEPDIR)/polyhedron_minimize.Po \ + ./$(DEPDIR)/polyhedron_remove_redundant_equalities.Po \ + ./$(DEPDIR)/polyhedron_sample.Po ./$(DEPDIR)/polytope_scan.Po \ + ./$(DEPDIR)/print.Plo ./$(DEPDIR)/schedule.Po \ + ./$(DEPDIR)/schedule_cmp.Po \ + imath_wrap/$(DEPDIR)/gmp_compat.Plo \ + imath_wrap/$(DEPDIR)/imath.Plo imath_wrap/$(DEPDIR)/imrat.Plo +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CXXFLAGS) $(CXXFLAGS) +AM_V_CXX = $(am__v_CXX_@AM_V@) +am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) +am__v_CXX_0 = @echo " CXX " $@; +am__v_CXX_1 = +CXXLD = $(CXX) +CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ + $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) +am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) +am__v_CXXLD_0 = @echo " CXXLD " $@; +am__v_CXXLD_1 = +SOURCES = $(libdep_a_SOURCES) $(libisl_la_SOURCES) \ + $(isl_bound_SOURCES) $(isl_cat_SOURCES) $(isl_closure_SOURCES) \ + $(isl_codegen_SOURCES) $(isl_flow_SOURCES) \ + $(isl_flow_cmp_SOURCES) $(isl_pip_SOURCES) \ + $(isl_polyhedron_detect_equalities_SOURCES) \ + $(isl_polyhedron_minimize_SOURCES) \ + $(isl_polyhedron_remove_redundant_equalities_SOURCES) \ + $(isl_polyhedron_sample_SOURCES) $(isl_polytope_scan_SOURCES) \ + $(isl_schedule_SOURCES) $(isl_schedule_cmp_SOURCES) isl_test.c \ + $(isl_test2_SOURCES) $(isl_test_cpp_SOURCES) \ + $(isl_test_cpp_checked_SOURCES) \ + $(isl_test_cpp_checked_conversion_SOURCES) \ + $(isl_test_cpp17_SOURCES) $(isl_test_cpp17_checked_SOURCES) \ + $(isl_test_cpp_failed_SOURCES) isl_test_imath.c isl_test_int.c +DIST_SOURCES = $(libdep_a_SOURCES) $(am__libisl_la_SOURCES_DIST) \ + $(isl_bound_SOURCES) $(isl_cat_SOURCES) $(isl_closure_SOURCES) \ + $(isl_codegen_SOURCES) $(isl_flow_SOURCES) \ + $(isl_flow_cmp_SOURCES) $(isl_pip_SOURCES) \ + $(isl_polyhedron_detect_equalities_SOURCES) \ + $(isl_polyhedron_minimize_SOURCES) \ + $(isl_polyhedron_remove_redundant_equalities_SOURCES) \ + $(isl_polyhedron_sample_SOURCES) $(isl_polytope_scan_SOURCES) \ + $(isl_schedule_SOURCES) $(isl_schedule_cmp_SOURCES) isl_test.c \ + $(isl_test2_SOURCES) $(isl_test_cpp_SOURCES) \ + $(isl_test_cpp_checked_SOURCES) \ + $(isl_test_cpp_checked_conversion_SOURCES) \ + $(isl_test_cpp17_SOURCES) $(isl_test_cpp17_checked_SOURCES) \ + $(isl_test_cpp_failed_SOURCES) isl_test_imath.c isl_test_int.c +RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ + ctags-recursive dvi-recursive html-recursive info-recursive \ + install-data-recursive install-dvi-recursive \ + install-exec-recursive install-html-recursive \ + install-info-recursive install-pdf-recursive \ + install-ps-recursive install-recursive installcheck-recursive \ + installdirs-recursive pdf-recursive ps-recursive \ + tags-recursive uninstall-recursive +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__noinst_PYTHON_DIST = interface/isl.py +am__py_compile = PYTHON=$(PYTHON) $(SHELL) $(py_compile) +py_compile = $(top_srcdir)/py-compile +DATA = $(pkgconfig_DATA) +am__pkginclude_HEADERS_DIST = include/isl/cpp.h \ + include/isl/typed_cpp.h 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/constraint.h \ + include/isl/ctx.h include/isl/fixed_box.h include/isl/flow.h \ + include/isl/id.h include/isl/id_type.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/space_type.h include/isl/stream.h \ + include/isl/stride_info.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/val_type.h include/isl/vec.h include/isl/version.h \ + include/isl/vertices.h +HEADERS = $(nodist_pkginclude_HEADERS) $(pkginclude_HEADERS) +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +am__recursive_targets = \ + $(RECURSIVE_TARGETS) \ + $(RECURSIVE_CLEAN_TARGETS) \ + $(am__extra_recursive_targets) +AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ + cscope check recheck distdir distdir-am dist dist-all \ + distcheck +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) \ + isl_config.h.in +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +am__tty_colors_dummy = \ + mgn= red= grn= lgn= blu= brg= std=; \ + am__color_tests=no +am__tty_colors = { \ + $(am__tty_colors_dummy); \ + if test "X$(AM_COLOR_TESTS)" = Xno; then \ + am__color_tests=no; \ + elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ + am__color_tests=yes; \ + elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ + am__color_tests=yes; \ + fi; \ + if test $$am__color_tests = yes; then \ + red=''; \ + grn=''; \ + lgn=''; \ + blu=''; \ + mgn=''; \ + brg=''; \ + std=''; \ + fi; \ +} +am__recheck_rx = ^[ ]*:recheck:[ ]* +am__global_test_result_rx = ^[ ]*:global-test-result:[ ]* +am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]* +# A command that, given a newline-separated list of test names on the +# standard input, print the name of the tests that are to be re-run +# upon "make recheck". +am__list_recheck_tests = $(AWK) '{ \ + recheck = 1; \ + while ((rc = (getline line < ($$0 ".trs"))) != 0) \ + { \ + if (rc < 0) \ + { \ + if ((getline line2 < ($$0 ".log")) < 0) \ + recheck = 0; \ + break; \ + } \ + else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \ + { \ + recheck = 0; \ + break; \ + } \ + else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \ + { \ + break; \ + } \ + }; \ + if (recheck) \ + print $$0; \ + close ($$0 ".trs"); \ + close ($$0 ".log"); \ +}' +# A command that, given a newline-separated list of test names on the +# standard input, create the global log from their .trs and .log files. +am__create_global_log = $(AWK) ' \ +function fatal(msg) \ +{ \ + print "fatal: making $@: " msg | "cat >&2"; \ + exit 1; \ +} \ +function rst_section(header) \ +{ \ + print header; \ + len = length(header); \ + for (i = 1; i <= len; i = i + 1) \ + printf "="; \ + printf "\n\n"; \ +} \ +{ \ + copy_in_global_log = 1; \ + global_test_result = "RUN"; \ + while ((rc = (getline line < ($$0 ".trs"))) != 0) \ + { \ + if (rc < 0) \ + fatal("failed to read from " $$0 ".trs"); \ + if (line ~ /$(am__global_test_result_rx)/) \ + { \ + sub("$(am__global_test_result_rx)", "", line); \ + sub("[ ]*$$", "", line); \ + global_test_result = line; \ + } \ + else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \ + copy_in_global_log = 0; \ + }; \ + if (copy_in_global_log) \ + { \ + rst_section(global_test_result ": " $$0); \ + while ((rc = (getline line < ($$0 ".log"))) != 0) \ + { \ + if (rc < 0) \ + fatal("failed to read from " $$0 ".log"); \ + print line; \ + }; \ + printf "\n"; \ + }; \ + close ($$0 ".trs"); \ + close ($$0 ".log"); \ +}' +# Restructured Text title. +am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; } +# Solaris 10 'make', and several other traditional 'make' implementations, +# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it +# by disabling -e (using the XSI extension "set +e") if it's set. +am__sh_e_setup = case $$- in *e*) set +e;; esac +# Default flags passed to test drivers. +am__common_driver_flags = \ + --color-tests "$$am__color_tests" \ + --enable-hard-errors "$$am__enable_hard_errors" \ + --expect-failure "$$am__expect_failure" +# To be inserted before the command running the test. Creates the +# directory for the log if needed. Stores in $dir the directory +# containing $f, in $tst the test, in $log the log. Executes the +# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and +# passes TESTS_ENVIRONMENT. Set up options for the wrapper that +# will run the test scripts (or their associated LOG_COMPILER, if +# thy have one). +am__check_pre = \ +$(am__sh_e_setup); \ +$(am__vpath_adj_setup) $(am__vpath_adj) \ +$(am__tty_colors); \ +srcdir=$(srcdir); export srcdir; \ +case "$@" in \ + */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \ + *) am__odir=.;; \ +esac; \ +test "x$$am__odir" = x"." || test -d "$$am__odir" \ + || $(MKDIR_P) "$$am__odir" || exit $$?; \ +if test -f "./$$f"; then dir=./; \ +elif test -f "$$f"; then dir=; \ +else dir="$(srcdir)/"; fi; \ +tst=$$dir$$f; log='$@'; \ +if test -n '$(DISABLE_HARD_ERRORS)'; then \ + am__enable_hard_errors=no; \ +else \ + am__enable_hard_errors=yes; \ +fi; \ +case " $(XFAIL_TESTS) " in \ + *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \ + am__expect_failure=yes;; \ + *) \ + am__expect_failure=no;; \ +esac; \ +$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT) +# A shell command to get the names of the tests scripts with any registered +# extension removed (i.e., equivalently, the names of the test logs, with +# the '.log' extension removed). The result is saved in the shell variable +# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly, +# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)", +# since that might cause problem with VPATH rewrites for suffix-less tests. +# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'. +am__set_TESTS_bases = \ + bases='$(TEST_LOGS)'; \ + bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \ + bases=`echo $$bases` +AM_TESTSUITE_SUMMARY_HEADER = ' for $(PACKAGE_STRING)' +RECHECK_LOGS = $(TEST_LOGS) +@HAVE_CPP_ISL_H_TRUE@@HAVE_CXX11_TRUE@am__EXEEXT_5 = \ +@HAVE_CPP_ISL_H_TRUE@@HAVE_CXX11_TRUE@ isl_test2$(EXEEXT) \ +@HAVE_CPP_ISL_H_TRUE@@HAVE_CXX11_TRUE@ isl_test_cpp$(EXEEXT) \ +@HAVE_CPP_ISL_H_TRUE@@HAVE_CXX11_TRUE@ isl_test_cpp_failed.sh +TEST_SUITE_LOG = test-suite.log +LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver +LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS) +am__set_b = \ + case '$@' in \ + */*) \ + case '$*' in \ + */*) b='$*';; \ + *) b=`echo '$@' | sed 's/\.log$$//'`; \ + esac;; \ + *) \ + b='$*';; \ + esac +am__test_logs1 = $(TESTS:=.log) +am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log) +TEST_LOGS = $(am__test_logs2:.py.log=.log) +PY_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver +PY_LOG_COMPILE = $(PY_LOG_COMPILER) $(AM_PY_LOG_FLAGS) $(PY_LOG_FLAGS) +am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/bound_test.sh.in \ + $(srcdir)/codegen_test.sh.in $(srcdir)/flow_test.sh.in \ + $(srcdir)/isl_config.h.in $(srcdir)/isl_srcdir.c.in \ + $(srcdir)/pip_test.sh.in $(srcdir)/schedule_test.sh.in AUTHORS \ + ChangeLog README compile config.guess config.sub depcomp \ + install-sh ltmain.sh missing py-compile test-driver +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +distdir = $(PACKAGE)-$(VERSION) +top_distdir = $(distdir) +am__remove_distdir = \ + if test -d "$(distdir)"; then \ + find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ + && rm -rf "$(distdir)" \ + || { sleep 5 && rm -rf "$(distdir)"; }; \ + else :; fi +am__post_remove_distdir = $(am__remove_distdir) +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +DIST_ARCHIVES = $(distdir).tar.gz +GZIP_ENV = --best +DIST_TARGETS = dist-gzip +# Exists only to be overridden by the user if desired. +AM_DISTCHECK_DVI_TARGET = dvi +distuninstallcheck_listfiles = find . -type f -print +am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ + | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' +distcleancheck_listfiles = find . -type f -print +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BUILD_EXEEXT = @BUILD_EXEEXT@ +BUILD_OBJEXT = @BUILD_OBJEXT@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CCDEPMODE_FOR_BUILD = @CCDEPMODE_FOR_BUILD@ +CC_FOR_BUILD = @CC_FOR_BUILD@ +CFLAGS = @CFLAGS@ +CFLAGS_FOR_BUILD = @CFLAGS_FOR_BUILD@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CPPFLAGS_FOR_BUILD = @CPPFLAGS_FOR_BUILD@ +CPP_FOR_BUILD = @CPP_FOR_BUILD@ +CSCOPE = @CSCOPE@ +CTAGS = @CTAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH = @CYGPATH@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ETAGS = @ETAGS@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GIT_HEAD = @GIT_HEAD@ +GIT_HEAD_ID = @GIT_HEAD_ID@ +GIT_HEAD_VERSION = @GIT_HEAD_VERSION@ +GREP = @GREP@ +HAVE_CXX11 = @HAVE_CXX11@ +HAVE_CXX17 = @HAVE_CXX17@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LDFLAGS_FOR_BUILD = @LDFLAGS_FOR_BUILD@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +MP_CFLAGS = @MP_CFLAGS@ +MP_CPPFLAGS = @MP_CPPFLAGS@ +MP_LDFLAGS = @MP_LDFLAGS@ +MP_LIBS = @MP_LIBS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OS_SRCDIR = @OS_SRCDIR@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +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@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +WARNING_FLAGS = @WARNING_FLAGS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CC_FOR_BUILD = @ac_ct_CC_FOR_BUILD@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +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@ +srcdir = @srcdir@ +subdirs = @subdirs@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +versioninfo = @versioninfo@ +@HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@MAYBE_INTERFACE = interface +SUBDIRS = . $(MAYBE_INTERFACE) doc +DIST_SUBDIRS = $(MAYBE_INTERFACE) doc +ACLOCAL_AMFLAGS = -I m4 +AUTOMAKE_OPTIONS = nostdinc subdir-objects +lib_LTLIBRARIES = libisl.la +@HAVE_CPP_ISL_H_TRUE@CPP_H = include/isl/cpp.h include/isl/typed_cpp.h +@HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@@HAVE_PYTHON_TRUE@noinst_PYTHON = interface/isl.py +TEST_EXTENSIONS = .py +AM_TESTS_ENVIRONMENT = \ + export PYTHONPATH=interface; \ + export ISL_DYLD_LIBRARY_PATH=.libs; \ + export LD_LIBRARY_PATH=".libs:$(LD_LIBRARY_PATH)"; + +PY_LOG_COMPILER = $(PYTHON) +@GMP_FOR_MP_TRUE@MP_SRC = \ +@GMP_FOR_MP_TRUE@ $(GET_MEMORY_FUNCTIONS) \ +@GMP_FOR_MP_TRUE@ isl_int_gmp.h \ +@GMP_FOR_MP_TRUE@ isl_gmp.c \ +@GMP_FOR_MP_TRUE@ isl_val_gmp.c + +@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_10) \ +@IMATH_FOR_MP_TRUE@ $(am__append_11) +@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 +includes = -I. -I$(srcdir) -I$(srcdir)/include -Iinclude/ +AM_CPPFLAGS = $(includes) @MP_CPPFLAGS@ +AM_CFLAGS = @WARNING_FLAGS@ @MP_CFLAGS@ +libisl_la_SOURCES = \ + $(MP_SRC) \ + isl_aff.c \ + isl_aff_map.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_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_box.c \ + 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 \ + isl_ilp.c \ + isl_ilp_private.h \ + isl_input.c \ + isl_int.h \ + isl_list_private.h \ + isl_local_private.h \ + isl_local.h \ + isl_local.c \ + isl_local_space_private.h \ + isl_local_space.c \ + isl_lp.c \ + isl_lp_private.h \ + isl_map.c \ + isl_map_list.c \ + isl_map_simplify.c \ + isl_map_subtract.c \ + isl_map_private.h \ + isl_map_to_basic_set.c \ + isl_mat.c \ + isl_mat_private.h \ + isl_morph.c \ + isl_morph.h \ + isl_id.c \ + isl_id_private.h \ + isl_obj.c \ + isl_options.c \ + isl_options_private.h \ + isl_output.c \ + isl_output_private.h \ + isl_point_private.h \ + isl_point.c \ + isl_polynomial_private.h \ + isl_polynomial.c \ + isl_printer_private.h \ + isl_printer.c \ + print.c \ + isl_range.c \ + isl_range.h \ + isl_reordering.c \ + isl_reordering.h \ + isl_sample.h \ + isl_sample.c \ + isl_scan.c \ + isl_scan.h \ + isl_schedule.c \ + isl_schedule_band.c \ + isl_schedule_band.h \ + isl_schedule_node.c \ + isl_schedule_node_private.h \ + isl_schedule_read.c \ + isl_schedule_tree.c \ + isl_schedule_tree.h \ + isl_schedule_private.h \ + isl_schedule_constraints.c \ + isl_schedule_constraints.h \ + isl_scheduler.c \ + isl_scheduler.h \ + isl_scheduler_clustering.c \ + isl_scheduler_clustering.h \ + isl_scheduler_scc.c \ + isl_scheduler_scc.h \ + 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_set_to_ast_graft_list.c \ + isl_set_to_ast_graft_list.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 \ + isl_vertices_private.h \ + isl_vertices.c \ + isl_yaml.h + +libisl_la_LIBADD = @MP_LIBS@ +libisl_la_LDFLAGS = -version-info @versioninfo@ \ + @MP_LDFLAGS@ + +isl_test_LDFLAGS = @MP_LDFLAGS@ +isl_test_LDADD = libisl.la @MP_LIBS@ +isl_test2_SOURCES = \ + isl_test2.cc \ + include/isl/cpp.h + +isl_test2_LDFLAGS = @MP_LDFLAGS@ +isl_test2_LDADD = libisl.la @MP_LIBS@ +isl_test_int_LDFLAGS = @MP_LDFLAGS@ +isl_test_int_LDADD = libisl.la @MP_LIBS@ +@IMATH_FOR_MP_TRUE@isl_test_imath_LDFLAGS = @MP_LDFLAGS@ +@IMATH_FOR_MP_TRUE@isl_test_imath_LDADD = libisl.la @MP_LIBS@ +isl_polyhedron_sample_LDADD = libisl.la +isl_polyhedron_sample_SOURCES = \ + polyhedron_sample.c + +isl_pip_LDFLAGS = @MP_LDFLAGS@ +isl_pip_LDADD = libisl.la @MP_LIBS@ +isl_pip_SOURCES = \ + pip.c + +isl_schedule_LDFLAGS = @MP_LDFLAGS@ +isl_schedule_LDADD = libisl.la @MP_LIBS@ +isl_schedule_SOURCES = \ + schedule.c + +isl_schedule_cmp_LDFLAGS = @MP_LDFLAGS@ +isl_schedule_cmp_LDADD = libisl.la @MP_LIBS@ +isl_schedule_cmp_SOURCES = \ + schedule_cmp.c + +isl_flow_LDFLAGS = @MP_LDFLAGS@ +isl_flow_LDADD = libisl.la @MP_LIBS@ +isl_flow_SOURCES = \ + flow.c + +isl_flow_cmp_LDFLAGS = @MP_LDFLAGS@ +isl_flow_cmp_LDADD = libisl.la @MP_LIBS@ +isl_flow_cmp_SOURCES = \ + flow_cmp.c + +isl_codegen_LDFLAGS = @MP_LDFLAGS@ +isl_codegen_LDADD = libisl.la @MP_LIBS@ +isl_codegen_SOURCES = \ + codegen.c + +isl_bound_LDFLAGS = @MP_LDFLAGS@ +isl_bound_LDADD = libisl.la @MP_LIBS@ +isl_bound_SOURCES = \ + bound.c + +isl_polyhedron_minimize_LDFLAGS = @MP_LDFLAGS@ +isl_polyhedron_minimize_LDADD = libisl.la @MP_LIBS@ +isl_polyhedron_minimize_SOURCES = \ + polyhedron_minimize.c + +isl_polytope_scan_LDADD = libisl.la +isl_polytope_scan_SOURCES = \ + polytope_scan.c + +isl_polyhedron_detect_equalities_LDADD = libisl.la +isl_polyhedron_detect_equalities_SOURCES = \ + polyhedron_detect_equalities.c + +isl_polyhedron_remove_redundant_equalities_LDADD = libisl.la +isl_polyhedron_remove_redundant_equalities_SOURCES = \ + polyhedron_remove_redundant_equalities.c + +isl_cat_LDADD = libisl.la +isl_cat_SOURCES = \ + cat.c + +isl_closure_LDADD = libisl.la +isl_closure_SOURCES = \ + closure.c + +isl_test_cpp_CPPFLAGS = $(AM_CPPFLAGS) -UCOMPILE_ERROR +isl_test_cpp_SOURCES = \ + isl_test_cpp.cc \ + include/isl/cpp.h + +isl_test_cpp_LDFLAGS = @MP_LDFLAGS@ +isl_test_cpp_LDADD = libisl.la @MP_LIBS@ +isl_test_cpp_failed_CPPFLAGS = $(AM_CPPFLAGS) -DCOMPILE_ERROR +isl_test_cpp_failed_SOURCES = \ + isl_test_cpp.cc \ + include/isl/cpp.h + +isl_test_cpp_failed_LDFLAGS = @MP_LDFLAGS@ +isl_test_cpp_failed_LDADD = libisl.la @MP_LIBS@ +isl_test_cpp17_SOURCES = \ + isl_test_cpp17.cc \ + include/isl/cpp.h + +isl_test_cpp17_LDFLAGS = @MP_LDFLAGS@ +isl_test_cpp17_LDADD = libisl.la @MP_LIBS@ +isl_test_cpp_checked_SOURCES = \ + isl_test_cpp-checked.cc \ + include/isl/cpp-checked.h + +isl_test_cpp_checked_LDFLAGS = @MP_LDFLAGS@ +isl_test_cpp_checked_LDADD = libisl.la @MP_LIBS@ +isl_test_cpp17_checked_SOURCES = \ + isl_test_cpp17-checked.cc \ + include/isl/cpp.h + +isl_test_cpp17_checked_LDFLAGS = @MP_LDFLAGS@ +isl_test_cpp17_checked_LDADD = libisl.la @MP_LIBS@ +isl_test_cpp_checked_conversion_SOURCES = \ + isl_test_cpp-checked-conversion.cc \ + include/isl/cpp-checked-conversion.h + +isl_test_cpp_checked_conversion_LDFLAGS = @MP_LDFLAGS@ +isl_test_cpp_checked_conversion_LDADD = libisl.la @MP_LIBS@ + +# dummy library that captures the dependencies on all headers +# that are relevant for the bindings +noinst_LIBRARIES = libdep.a +libdep_a_SOURCES = dep.c +nodist_pkginclude_HEADERS = \ + include/isl/stdint.h + +pkginclude_HEADERS = \ + $(CPP_H) \ + $(MP_INCLUDE_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/constraint.h \ + include/isl/ctx.h \ + include/isl/fixed_box.h \ + include/isl/flow.h \ + include/isl/id.h \ + include/isl/id_type.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/space_type.h \ + include/isl/stream.h \ + include/isl/stride_info.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/val_type.h \ + include/isl/vec.h \ + include/isl/version.h \ + include/isl/vertices.h + +@HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@CPP_INTERFACES = \ +@HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@ include/isl/cpp.h \ +@HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@ include/isl/cpp-checked.h \ +@HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@ include/isl/cpp-checked-conversion.h \ +@HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@ include/isl/typed_cpp.h + +BUILT_SOURCES = gitversion.h $(CPP_INTERFACES) +CLEANFILES = \ + gitversion.h \ + interface/isldlname.py \ + interface/isl.py \ + interface/isl.pyc \ + interface/__pycache__/*.pyc \ + $(CPP_INTERFACES) + +DISTCLEANFILES = \ + isl-uninstalled.sh \ + isl-uninstalled.pc \ + isl.pc \ + isl.pc.in \ + include/isl/stdint.h + +EXTRA_DIST = \ + LICENSE \ + isl_config_post.h \ + isl_aff_lex_templ.c \ + isl_align_params_templ.c \ + isl_align_params_bin_templ.c \ + isl_ast_node_set_field_templ.c \ + basis_reduction_templ.c \ + isl_bind_domain_templ.c \ + bset_to_bmap.c \ + bset_from_bmap.c \ + isl_check_named_params_templ.c \ + check_parse_fail_test_templ.c \ + check_reparse_templ.c \ + check_reparse_test_templ.c \ + check_single_reference_templ.c \ + check_type_range_templ.c \ + isl_copy_tuple_id_templ.c \ + isl_domain_factor_templ.c \ + isl_drop_unused_params_templ.c \ + extract_key.c \ + isl_from_range_templ.c \ + isl_ilp_opt_fn_val_templ.c \ + isl_ilp_opt_multi_val_templ.c \ + isl_ilp_opt_val_templ.c \ + has_single_reference_templ.c \ + isl_insert_domain_templ.c \ + isl_list_macro.h \ + isl_list_templ.c \ + isl_list_templ.h \ + isl_list_read_templ.c \ + isl_list_read_yaml_templ.c \ + isl_map_bound_templ.c \ + isl_map_lexopt_templ.c \ + isl_maybe_ast_graft_list.h \ + isl_maybe_map.h \ + isl_multi_macro.h \ + isl_multi_bind_templ.c \ + isl_multi_explicit_domain.c \ + isl_multi_pw_aff_explicit_domain.c \ + isl_multi_union_pw_aff_explicit_domain.c \ + isl_multi_no_explicit_domain.c \ + isl_multi_no_domain_templ.c \ + isl_multi_templ.c \ + isl_multi_templ.h \ + isl_multi_add_constant_templ.c \ + isl_multi_align_set.c \ + isl_multi_align_union_set.c \ + isl_multi_apply_templ.c \ + isl_multi_apply_explicit_domain_templ.c \ + isl_multi_apply_no_explicit_domain_templ.c \ + isl_multi_apply_set_explicit_domain_templ.c \ + isl_multi_apply_set_no_explicit_domain_templ.c \ + isl_multi_apply_union_set_explicit_domain_templ.c \ + isl_multi_arith_templ.c \ + isl_multi_bin_val_templ.c \ + isl_multi_bind_domain_templ.c \ + isl_multi_check_domain_templ.c \ + isl_multi_cmp.c \ + isl_multi_coalesce.c \ + isl_multi_dim_id_templ.c \ + isl_multi_dims.c \ + isl_multi_domain_templ.c \ + isl_multi_domain_reverse_templ.c \ + isl_multi_floor.c \ + isl_multi_from_base_templ.c \ + isl_multi_from_tuple_templ.c \ + isl_multi_gist.c \ + isl_multi_hash.c \ + isl_multi_insert_domain_templ.c \ + isl_multi_intersect.c \ + isl_multi_identity_templ.c \ + isl_multi_locals_templ.c \ + isl_multi_min_max_templ.c \ + isl_multi_move_dims_templ.c \ + isl_multi_nan_templ.c \ + isl_multi_param_templ.c \ + isl_multi_product_templ.c \ + isl_multi_pw_aff_pullback_templ.c \ + isl_multi_read_no_explicit_domain_templ.c \ + isl_multi_splice_templ.c \ + isl_multi_tuple_id_templ.c \ + isl_multi_un_op_templ.c \ + isl_multi_unbind_params_templ.c \ + isl_multi_union_add_templ.c \ + isl_multi_zero_templ.c \ + isl_multi_zero_space_templ.c \ + isl_opt_mpa_templ.c \ + opt_type.h \ + print_templ.c \ + print_templ_yaml.c \ + print_yaml_field_templ.c \ + isl_power_templ.c \ + isl_project_out_all_params_templ.c \ + isl_project_out_param_templ.c \ + isl_pw_macro.h \ + isl_pw_templ.c \ + isl_pw_templ.h \ + isl_pw_add_constant_templ.c \ + isl_pw_add_constant_multi_val_templ.c \ + isl_pw_add_constant_val_templ.c \ + isl_pw_add_disjoint_templ.c \ + isl_pw_bind_domain_templ.c \ + isl_pw_domain_reverse_templ.c \ + isl_pw_eval.c \ + isl_pw_fix_templ.c \ + isl_pw_from_range_templ.c \ + isl_pw_hash.c \ + isl_pw_insert_dims_templ.c \ + isl_pw_insert_domain_templ.c \ + isl_pw_lift_templ.c \ + isl_pw_locals_templ.c \ + isl_pw_morph_templ.c \ + isl_pw_move_dims_templ.c \ + isl_pw_neg_templ.c \ + isl_pw_opt_templ.c \ + isl_pw_print_templ.c \ + isl_pw_pullback_templ.c \ + isl_pw_range_tuple_id_templ.c \ + isl_pw_scale_templ.c \ + isl_pw_split_dims_templ.c \ + isl_pw_sub_templ.c \ + isl_pw_un_op_templ.c \ + isl_pw_union_opt.c \ + isl_read_from_str_templ.c \ + read_in_string_templ.c \ + set_to_map.c \ + set_from_map.c \ + set_list_from_map_list_inl.c \ + isl_stream_read_pw_with_params_templ.c \ + isl_stream_read_with_params_templ.c \ + isl_tab_lexopt_templ.c \ + isl_test_list_templ.c \ + isl_test_plain_equal_templ.c \ + isl_type_check_equal_space_templ.c \ + isl_type_check_match_range_multi_val.c \ + isl_type_has_equal_space_bin_templ.c \ + isl_type_has_equal_space_templ.c \ + isl_type_has_space_templ.c \ + isl_unbind_params_templ.c \ + uset_to_umap.c \ + uset_from_umap.c \ + isl_union_macro.h \ + isl_union_templ.c \ + isl_union_single.c \ + isl_union_multi.c \ + isl_union_domain_reverse_templ.c \ + isl_union_eval.c \ + isl_union_locals_templ.c \ + isl_union_map_lex_templ.c \ + isl_union_neg.c \ + isl_union_print_templ.c \ + isl_union_pw_templ.c \ + isl_union_sub_templ.c \ + libisl-gdb.py \ + doc/CodingStyle \ + doc/SubmittingPatches \ + doc/implementation.tex \ + doc/isl.bib \ + doc/mypod2latex \ + doc/manual.tex \ + doc/reading.tex \ + doc/user.pod \ + imath/gmp_compat.c \ + imath/gmp_compat.h \ + imath/imath.c \ + imath/imath.h \ + imath/imrat.c \ + imath/imrat.h \ + all.h \ + cpp \ + python \ + isl_test_cpp-generic.cc \ + isl_test_cpp_failed.sh \ + isl_test_cpp17-generic.cc \ + isl_test_python.py \ + test_inputs + +pkgconfigdir = $(pkgconfig_libdir) +pkgconfig_DATA = $(pkgconfig_libfile) +all: $(BUILT_SOURCES) isl_config.h + $(MAKE) $(AM_MAKEFLAGS) all-recursive + +.SUFFIXES: +.SUFFIXES: .c .cc .lo .log .o .obj .py .py$(EXEEXT) .trs +am--refresh: Makefile + @: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \ + $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + echo ' $(SHELL) ./config.status'; \ + $(SHELL) ./config.status;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + $(SHELL) ./config.status --recheck + +$(top_srcdir)/configure: $(am__configure_deps) + $(am__cd) $(srcdir) && $(AUTOCONF) +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) +$(am__aclocal_m4_deps): + +isl_config.h: stamp-h1 + @test -f $@ || rm -f stamp-h1 + @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1 + +stamp-h1: $(srcdir)/isl_config.h.in $(top_builddir)/config.status + @rm -f stamp-h1 + cd $(top_builddir) && $(SHELL) ./config.status isl_config.h +$(srcdir)/isl_config.h.in: $(am__configure_deps) + ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) + rm -f stamp-h1 + touch $@ + +distclean-hdr: + -rm -f isl_config.h stamp-h1 +isl_srcdir.c: $(top_builddir)/config.status $(srcdir)/isl_srcdir.c.in + cd $(top_builddir) && $(SHELL) ./config.status $@ +bound_test.sh: $(top_builddir)/config.status $(srcdir)/bound_test.sh.in + cd $(top_builddir) && $(SHELL) ./config.status $@ +codegen_test.sh: $(top_builddir)/config.status $(srcdir)/codegen_test.sh.in + cd $(top_builddir) && $(SHELL) ./config.status $@ +pip_test.sh: $(top_builddir)/config.status $(srcdir)/pip_test.sh.in + cd $(top_builddir) && $(SHELL) ./config.status $@ +flow_test.sh: $(top_builddir)/config.status $(srcdir)/flow_test.sh.in + cd $(top_builddir) && $(SHELL) ./config.status $@ +schedule_test.sh: $(top_builddir)/config.status $(srcdir)/schedule_test.sh.in + cd $(top_builddir) && $(SHELL) ./config.status $@ + +clean-noinstPROGRAMS: + @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list + +clean-noinstLIBRARIES: + -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) + +install-libLTLIBRARIES: $(lib_LTLIBRARIES) + @$(NORMAL_INSTALL) + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ + } + +uninstall-libLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ + done + +clean-libLTLIBRARIES: + -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) + @list='$(lib_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +libdep.a: $(libdep_a_OBJECTS) $(libdep_a_DEPENDENCIES) $(EXTRA_libdep_a_DEPENDENCIES) + $(AM_V_at)-rm -f libdep.a + $(AM_V_AR)$(libdep_a_AR) libdep.a $(libdep_a_OBJECTS) $(libdep_a_LIBADD) + $(AM_V_at)$(RANLIB) libdep.a +imath_wrap/$(am__dirstamp): + @$(MKDIR_P) imath_wrap + @: > imath_wrap/$(am__dirstamp) +imath_wrap/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) imath_wrap/$(DEPDIR) + @: > imath_wrap/$(DEPDIR)/$(am__dirstamp) +imath_wrap/gmp_compat.lo: imath_wrap/$(am__dirstamp) \ + imath_wrap/$(DEPDIR)/$(am__dirstamp) +imath_wrap/imath.lo: imath_wrap/$(am__dirstamp) \ + imath_wrap/$(DEPDIR)/$(am__dirstamp) +imath_wrap/imrat.lo: imath_wrap/$(am__dirstamp) \ + imath_wrap/$(DEPDIR)/$(am__dirstamp) + +libisl.la: $(libisl_la_OBJECTS) $(libisl_la_DEPENDENCIES) $(EXTRA_libisl_la_DEPENDENCIES) + $(AM_V_CCLD)$(libisl_la_LINK) -rpath $(libdir) $(libisl_la_OBJECTS) $(libisl_la_LIBADD) $(LIBS) + +isl_bound$(EXEEXT): $(isl_bound_OBJECTS) $(isl_bound_DEPENDENCIES) $(EXTRA_isl_bound_DEPENDENCIES) + @rm -f isl_bound$(EXEEXT) + $(AM_V_CCLD)$(isl_bound_LINK) $(isl_bound_OBJECTS) $(isl_bound_LDADD) $(LIBS) + +isl_cat$(EXEEXT): $(isl_cat_OBJECTS) $(isl_cat_DEPENDENCIES) $(EXTRA_isl_cat_DEPENDENCIES) + @rm -f isl_cat$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(isl_cat_OBJECTS) $(isl_cat_LDADD) $(LIBS) + +isl_closure$(EXEEXT): $(isl_closure_OBJECTS) $(isl_closure_DEPENDENCIES) $(EXTRA_isl_closure_DEPENDENCIES) + @rm -f isl_closure$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(isl_closure_OBJECTS) $(isl_closure_LDADD) $(LIBS) + +isl_codegen$(EXEEXT): $(isl_codegen_OBJECTS) $(isl_codegen_DEPENDENCIES) $(EXTRA_isl_codegen_DEPENDENCIES) + @rm -f isl_codegen$(EXEEXT) + $(AM_V_CCLD)$(isl_codegen_LINK) $(isl_codegen_OBJECTS) $(isl_codegen_LDADD) $(LIBS) + +isl_flow$(EXEEXT): $(isl_flow_OBJECTS) $(isl_flow_DEPENDENCIES) $(EXTRA_isl_flow_DEPENDENCIES) + @rm -f isl_flow$(EXEEXT) + $(AM_V_CCLD)$(isl_flow_LINK) $(isl_flow_OBJECTS) $(isl_flow_LDADD) $(LIBS) + +isl_flow_cmp$(EXEEXT): $(isl_flow_cmp_OBJECTS) $(isl_flow_cmp_DEPENDENCIES) $(EXTRA_isl_flow_cmp_DEPENDENCIES) + @rm -f isl_flow_cmp$(EXEEXT) + $(AM_V_CCLD)$(isl_flow_cmp_LINK) $(isl_flow_cmp_OBJECTS) $(isl_flow_cmp_LDADD) $(LIBS) + +isl_pip$(EXEEXT): $(isl_pip_OBJECTS) $(isl_pip_DEPENDENCIES) $(EXTRA_isl_pip_DEPENDENCIES) + @rm -f isl_pip$(EXEEXT) + $(AM_V_CCLD)$(isl_pip_LINK) $(isl_pip_OBJECTS) $(isl_pip_LDADD) $(LIBS) + +isl_polyhedron_detect_equalities$(EXEEXT): $(isl_polyhedron_detect_equalities_OBJECTS) $(isl_polyhedron_detect_equalities_DEPENDENCIES) $(EXTRA_isl_polyhedron_detect_equalities_DEPENDENCIES) + @rm -f isl_polyhedron_detect_equalities$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(isl_polyhedron_detect_equalities_OBJECTS) $(isl_polyhedron_detect_equalities_LDADD) $(LIBS) + +isl_polyhedron_minimize$(EXEEXT): $(isl_polyhedron_minimize_OBJECTS) $(isl_polyhedron_minimize_DEPENDENCIES) $(EXTRA_isl_polyhedron_minimize_DEPENDENCIES) + @rm -f isl_polyhedron_minimize$(EXEEXT) + $(AM_V_CCLD)$(isl_polyhedron_minimize_LINK) $(isl_polyhedron_minimize_OBJECTS) $(isl_polyhedron_minimize_LDADD) $(LIBS) + +isl_polyhedron_remove_redundant_equalities$(EXEEXT): $(isl_polyhedron_remove_redundant_equalities_OBJECTS) $(isl_polyhedron_remove_redundant_equalities_DEPENDENCIES) $(EXTRA_isl_polyhedron_remove_redundant_equalities_DEPENDENCIES) + @rm -f isl_polyhedron_remove_redundant_equalities$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(isl_polyhedron_remove_redundant_equalities_OBJECTS) $(isl_polyhedron_remove_redundant_equalities_LDADD) $(LIBS) + +isl_polyhedron_sample$(EXEEXT): $(isl_polyhedron_sample_OBJECTS) $(isl_polyhedron_sample_DEPENDENCIES) $(EXTRA_isl_polyhedron_sample_DEPENDENCIES) + @rm -f isl_polyhedron_sample$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(isl_polyhedron_sample_OBJECTS) $(isl_polyhedron_sample_LDADD) $(LIBS) + +isl_polytope_scan$(EXEEXT): $(isl_polytope_scan_OBJECTS) $(isl_polytope_scan_DEPENDENCIES) $(EXTRA_isl_polytope_scan_DEPENDENCIES) + @rm -f isl_polytope_scan$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(isl_polytope_scan_OBJECTS) $(isl_polytope_scan_LDADD) $(LIBS) + +isl_schedule$(EXEEXT): $(isl_schedule_OBJECTS) $(isl_schedule_DEPENDENCIES) $(EXTRA_isl_schedule_DEPENDENCIES) + @rm -f isl_schedule$(EXEEXT) + $(AM_V_CCLD)$(isl_schedule_LINK) $(isl_schedule_OBJECTS) $(isl_schedule_LDADD) $(LIBS) + +isl_schedule_cmp$(EXEEXT): $(isl_schedule_cmp_OBJECTS) $(isl_schedule_cmp_DEPENDENCIES) $(EXTRA_isl_schedule_cmp_DEPENDENCIES) + @rm -f isl_schedule_cmp$(EXEEXT) + $(AM_V_CCLD)$(isl_schedule_cmp_LINK) $(isl_schedule_cmp_OBJECTS) $(isl_schedule_cmp_LDADD) $(LIBS) + +isl_test$(EXEEXT): $(isl_test_OBJECTS) $(isl_test_DEPENDENCIES) $(EXTRA_isl_test_DEPENDENCIES) + @rm -f isl_test$(EXEEXT) + $(AM_V_CCLD)$(isl_test_LINK) $(isl_test_OBJECTS) $(isl_test_LDADD) $(LIBS) + +isl_test2$(EXEEXT): $(isl_test2_OBJECTS) $(isl_test2_DEPENDENCIES) $(EXTRA_isl_test2_DEPENDENCIES) + @rm -f isl_test2$(EXEEXT) + $(AM_V_CXXLD)$(isl_test2_LINK) $(isl_test2_OBJECTS) $(isl_test2_LDADD) $(LIBS) + +isl_test_cpp$(EXEEXT): $(isl_test_cpp_OBJECTS) $(isl_test_cpp_DEPENDENCIES) $(EXTRA_isl_test_cpp_DEPENDENCIES) + @rm -f isl_test_cpp$(EXEEXT) + $(AM_V_CXXLD)$(isl_test_cpp_LINK) $(isl_test_cpp_OBJECTS) $(isl_test_cpp_LDADD) $(LIBS) + +isl_test_cpp-checked$(EXEEXT): $(isl_test_cpp_checked_OBJECTS) $(isl_test_cpp_checked_DEPENDENCIES) $(EXTRA_isl_test_cpp_checked_DEPENDENCIES) + @rm -f isl_test_cpp-checked$(EXEEXT) + $(AM_V_CXXLD)$(isl_test_cpp_checked_LINK) $(isl_test_cpp_checked_OBJECTS) $(isl_test_cpp_checked_LDADD) $(LIBS) + +isl_test_cpp-checked-conversion$(EXEEXT): $(isl_test_cpp_checked_conversion_OBJECTS) $(isl_test_cpp_checked_conversion_DEPENDENCIES) $(EXTRA_isl_test_cpp_checked_conversion_DEPENDENCIES) + @rm -f isl_test_cpp-checked-conversion$(EXEEXT) + $(AM_V_CXXLD)$(isl_test_cpp_checked_conversion_LINK) $(isl_test_cpp_checked_conversion_OBJECTS) $(isl_test_cpp_checked_conversion_LDADD) $(LIBS) + +isl_test_cpp17$(EXEEXT): $(isl_test_cpp17_OBJECTS) $(isl_test_cpp17_DEPENDENCIES) $(EXTRA_isl_test_cpp17_DEPENDENCIES) + @rm -f isl_test_cpp17$(EXEEXT) + $(AM_V_CXXLD)$(isl_test_cpp17_LINK) $(isl_test_cpp17_OBJECTS) $(isl_test_cpp17_LDADD) $(LIBS) + +isl_test_cpp17-checked$(EXEEXT): $(isl_test_cpp17_checked_OBJECTS) $(isl_test_cpp17_checked_DEPENDENCIES) $(EXTRA_isl_test_cpp17_checked_DEPENDENCIES) + @rm -f isl_test_cpp17-checked$(EXEEXT) + $(AM_V_CXXLD)$(isl_test_cpp17_checked_LINK) $(isl_test_cpp17_checked_OBJECTS) $(isl_test_cpp17_checked_LDADD) $(LIBS) + +isl_test_cpp_failed$(EXEEXT): $(isl_test_cpp_failed_OBJECTS) $(isl_test_cpp_failed_DEPENDENCIES) $(EXTRA_isl_test_cpp_failed_DEPENDENCIES) + @rm -f isl_test_cpp_failed$(EXEEXT) + $(AM_V_CXXLD)$(isl_test_cpp_failed_LINK) $(isl_test_cpp_failed_OBJECTS) $(isl_test_cpp_failed_LDADD) $(LIBS) + +isl_test_imath$(EXEEXT): $(isl_test_imath_OBJECTS) $(isl_test_imath_DEPENDENCIES) $(EXTRA_isl_test_imath_DEPENDENCIES) + @rm -f isl_test_imath$(EXEEXT) + $(AM_V_CCLD)$(isl_test_imath_LINK) $(isl_test_imath_OBJECTS) $(isl_test_imath_LDADD) $(LIBS) + +isl_test_int$(EXEEXT): $(isl_test_int_OBJECTS) $(isl_test_int_DEPENDENCIES) $(EXTRA_isl_test_int_DEPENDENCIES) + @rm -f isl_test_int$(EXEEXT) + $(AM_V_CCLD)$(isl_test_int_LINK) $(isl_test_int_OBJECTS) $(isl_test_int_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + -rm -f imath_wrap/*.$(OBJEXT) + -rm -f imath_wrap/*.lo + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/basis_reduction_tab.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bound.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cat.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/closure.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/codegen.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dep.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/flow.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/flow_cmp.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_aff.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_aff_map.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_affine_hull.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_arg.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_ast.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_ast_build.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_ast_build_expr.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_ast_codegen.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_ast_graft.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_bernstein.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_blk.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_bound.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_box.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_coalesce.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_constraint.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_convex_hull.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_ctx.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_deprecated.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_dim_map.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_equalities.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_factorization.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_farkas.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_ffs.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_flow.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_fold.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_gmp.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_hash.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_id.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_id_to_ast_expr.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_id_to_id.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_id_to_pw_aff.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_ilp.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_imath.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_input.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_int_sioimath.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_local.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_local_space.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_lp.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_map.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_map_list.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_map_simplify.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_map_subtract.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_map_to_basic_set.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_mat.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_morph.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_obj.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_options.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_output.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_point.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_polynomial.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_printer.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_range.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_reordering.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_sample.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_scan.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_schedule.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_schedule_band.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_schedule_constraints.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_schedule_node.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_schedule_read.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_schedule_tree.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_scheduler.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_scheduler_clustering.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_scheduler_scc.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_seq.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_set_list.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_set_to_ast_graft_list.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_sort.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_space.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_stream.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_stride.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_tab.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_tab_pip.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_tarjan.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_test.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_test2.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_test_cpp-checked-conversion.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_test_cpp-checked.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_test_cpp-isl_test_cpp.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_test_cpp17-checked.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_test_cpp17.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_test_cpp_failed-isl_test_cpp.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_test_imath.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_test_int.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_transitive_closure.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_union_map.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_val.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_val_gmp.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_val_imath.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_val_sioimath.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_vec.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_version.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_vertices.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mp_get_memory_functions.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pip.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/polyhedron_detect_equalities.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/polyhedron_minimize.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/polyhedron_remove_redundant_equalities.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/polyhedron_sample.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/polytope_scan.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/print.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/schedule.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/schedule_cmp.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@imath_wrap/$(DEPDIR)/gmp_compat.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@imath_wrap/$(DEPDIR)/imath.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@imath_wrap/$(DEPDIR)/imrat.Plo@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +.cc.o: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< + +.cc.obj: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.cc.lo: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $< + +isl_test_cpp-isl_test_cpp.o: isl_test_cpp.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(isl_test_cpp_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT isl_test_cpp-isl_test_cpp.o -MD -MP -MF $(DEPDIR)/isl_test_cpp-isl_test_cpp.Tpo -c -o isl_test_cpp-isl_test_cpp.o `test -f 'isl_test_cpp.cc' || echo '$(srcdir)/'`isl_test_cpp.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/isl_test_cpp-isl_test_cpp.Tpo $(DEPDIR)/isl_test_cpp-isl_test_cpp.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='isl_test_cpp.cc' object='isl_test_cpp-isl_test_cpp.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(isl_test_cpp_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o isl_test_cpp-isl_test_cpp.o `test -f 'isl_test_cpp.cc' || echo '$(srcdir)/'`isl_test_cpp.cc + +isl_test_cpp-isl_test_cpp.obj: isl_test_cpp.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(isl_test_cpp_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT isl_test_cpp-isl_test_cpp.obj -MD -MP -MF $(DEPDIR)/isl_test_cpp-isl_test_cpp.Tpo -c -o isl_test_cpp-isl_test_cpp.obj `if test -f 'isl_test_cpp.cc'; then $(CYGPATH_W) 'isl_test_cpp.cc'; else $(CYGPATH_W) '$(srcdir)/isl_test_cpp.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/isl_test_cpp-isl_test_cpp.Tpo $(DEPDIR)/isl_test_cpp-isl_test_cpp.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='isl_test_cpp.cc' object='isl_test_cpp-isl_test_cpp.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(isl_test_cpp_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o isl_test_cpp-isl_test_cpp.obj `if test -f 'isl_test_cpp.cc'; then $(CYGPATH_W) 'isl_test_cpp.cc'; else $(CYGPATH_W) '$(srcdir)/isl_test_cpp.cc'; fi` + +isl_test_cpp_failed-isl_test_cpp.o: isl_test_cpp.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(isl_test_cpp_failed_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT isl_test_cpp_failed-isl_test_cpp.o -MD -MP -MF $(DEPDIR)/isl_test_cpp_failed-isl_test_cpp.Tpo -c -o isl_test_cpp_failed-isl_test_cpp.o `test -f 'isl_test_cpp.cc' || echo '$(srcdir)/'`isl_test_cpp.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/isl_test_cpp_failed-isl_test_cpp.Tpo $(DEPDIR)/isl_test_cpp_failed-isl_test_cpp.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='isl_test_cpp.cc' object='isl_test_cpp_failed-isl_test_cpp.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(isl_test_cpp_failed_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o isl_test_cpp_failed-isl_test_cpp.o `test -f 'isl_test_cpp.cc' || echo '$(srcdir)/'`isl_test_cpp.cc + +isl_test_cpp_failed-isl_test_cpp.obj: isl_test_cpp.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(isl_test_cpp_failed_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT isl_test_cpp_failed-isl_test_cpp.obj -MD -MP -MF $(DEPDIR)/isl_test_cpp_failed-isl_test_cpp.Tpo -c -o isl_test_cpp_failed-isl_test_cpp.obj `if test -f 'isl_test_cpp.cc'; then $(CYGPATH_W) 'isl_test_cpp.cc'; else $(CYGPATH_W) '$(srcdir)/isl_test_cpp.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/isl_test_cpp_failed-isl_test_cpp.Tpo $(DEPDIR)/isl_test_cpp_failed-isl_test_cpp.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='isl_test_cpp.cc' object='isl_test_cpp_failed-isl_test_cpp.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(isl_test_cpp_failed_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o isl_test_cpp_failed-isl_test_cpp.obj `if test -f 'isl_test_cpp.cc'; then $(CYGPATH_W) 'isl_test_cpp.cc'; else $(CYGPATH_W) '$(srcdir)/isl_test_cpp.cc'; fi` + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + -rm -rf imath_wrap/.libs imath_wrap/_libs + +distclean-libtool: + -rm -f libtool config.lt +install-pkgconfigDATA: $(pkgconfig_DATA) + @$(NORMAL_INSTALL) + @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(pkgconfigdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)" || 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_DATA) $$files '$(DESTDIR)$(pkgconfigdir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgconfigdir)" || exit $$?; \ + done + +uninstall-pkgconfigDATA: + @$(NORMAL_UNINSTALL) + @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-nodist_pkgincludeHEADERS: $(nodist_pkginclude_HEADERS) + @$(NORMAL_INSTALL) + @list='$(nodist_pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(pkgincludedir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(pkgincludedir)" || 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)$(pkgincludedir)'"; \ + $(INSTALL_HEADER) $$files "$(DESTDIR)$(pkgincludedir)" || exit $$?; \ + done + +uninstall-nodist_pkgincludeHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(nodist_pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(pkgincludedir)'; $(am__uninstall_files_from_dir) +install-pkgincludeHEADERS: $(pkginclude_HEADERS) + @$(NORMAL_INSTALL) + @list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(pkgincludedir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(pkgincludedir)" || 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)$(pkgincludedir)'"; \ + $(INSTALL_HEADER) $$files "$(DESTDIR)$(pkgincludedir)" || exit $$?; \ + done + +uninstall-pkgincludeHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(pkgincludedir)'; $(am__uninstall_files_from_dir) + +# This directory's subdirectories are mostly independent; you can cd +# into them and run 'make' without going through this Makefile. +# To change the values of 'make' variables: instead of editing Makefiles, +# (1) if the variable is set in 'config.status', edit 'config.status' +# (which will cause the Makefiles to be regenerated when you run 'make'); +# (2) otherwise, pass the desired values on the 'make' command line. +$(am__recursive_targets): + @fail=; \ + if $(am__make_keepgoing); then \ + failcom='fail=yes'; \ + else \ + failcom='exit 1'; \ + fi; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-recursive +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-recursive + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscope: cscope.files + test ! -s cscope.files \ + || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS) +clean-cscope: + -rm -f cscope.files +cscope.files: clean-cscope cscopelist +cscopelist: cscopelist-recursive + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + -rm -f cscope.out cscope.in.out cscope.po.out cscope.files + +# Recover from deleted '.trs' file; this should ensure that +# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create +# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells +# to avoid problems with "make -n". +.log.trs: + rm -f $< $@ + $(MAKE) $(AM_MAKEFLAGS) $< + +# Leading 'am--fnord' is there to ensure the list of targets does not +# expand to empty, as could happen e.g. with make check TESTS=''. +am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck) +am--force-recheck: + @: + +$(TEST_SUITE_LOG): $(TEST_LOGS) + @$(am__set_TESTS_bases); \ + am__f_ok () { test -f "$$1" && test -r "$$1"; }; \ + redo_bases=`for i in $$bases; do \ + am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \ + done`; \ + if test -n "$$redo_bases"; then \ + redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \ + redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \ + if $(am__make_dryrun); then :; else \ + rm -f $$redo_logs && rm -f $$redo_results || exit 1; \ + fi; \ + fi; \ + if test -n "$$am__remaking_logs"; then \ + echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \ + "recursion detected" >&2; \ + elif test -n "$$redo_logs"; then \ + am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \ + fi; \ + if $(am__make_dryrun); then :; else \ + st=0; \ + errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \ + for i in $$redo_bases; do \ + test -f $$i.trs && test -r $$i.trs \ + || { echo "$$errmsg $$i.trs" >&2; st=1; }; \ + test -f $$i.log && test -r $$i.log \ + || { echo "$$errmsg $$i.log" >&2; st=1; }; \ + done; \ + test $$st -eq 0 || exit 1; \ + fi + @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \ + ws='[ ]'; \ + results=`for b in $$bases; do echo $$b.trs; done`; \ + test -n "$$results" || results=/dev/null; \ + all=` grep "^$$ws*:test-result:" $$results | wc -l`; \ + pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \ + fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \ + skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \ + xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \ + xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \ + error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \ + if test `expr $$fail + $$xpass + $$error` -eq 0; then \ + success=true; \ + else \ + success=false; \ + fi; \ + br='==================='; br=$$br$$br$$br$$br; \ + result_count () \ + { \ + if test x"$$1" = x"--maybe-color"; then \ + maybe_colorize=yes; \ + elif test x"$$1" = x"--no-color"; then \ + maybe_colorize=no; \ + else \ + echo "$@: invalid 'result_count' usage" >&2; exit 4; \ + fi; \ + shift; \ + desc=$$1 count=$$2; \ + if test $$maybe_colorize = yes && test $$count -gt 0; then \ + color_start=$$3 color_end=$$std; \ + else \ + color_start= color_end=; \ + fi; \ + echo "$${color_start}# $$desc $$count$${color_end}"; \ + }; \ + create_testsuite_report () \ + { \ + result_count $$1 "TOTAL:" $$all "$$brg"; \ + result_count $$1 "PASS: " $$pass "$$grn"; \ + result_count $$1 "SKIP: " $$skip "$$blu"; \ + result_count $$1 "XFAIL:" $$xfail "$$lgn"; \ + result_count $$1 "FAIL: " $$fail "$$red"; \ + result_count $$1 "XPASS:" $$xpass "$$red"; \ + result_count $$1 "ERROR:" $$error "$$mgn"; \ + }; \ + { \ + echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \ + $(am__rst_title); \ + create_testsuite_report --no-color; \ + echo; \ + echo ".. contents:: :depth: 2"; \ + echo; \ + for b in $$bases; do echo $$b; done \ + | $(am__create_global_log); \ + } >$(TEST_SUITE_LOG).tmp || exit 1; \ + mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \ + if $$success; then \ + col="$$grn"; \ + else \ + col="$$red"; \ + test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \ + fi; \ + echo "$${col}$$br$${std}"; \ + echo "$${col}Testsuite summary"$(AM_TESTSUITE_SUMMARY_HEADER)"$${std}"; \ + echo "$${col}$$br$${std}"; \ + create_testsuite_report --maybe-color; \ + echo "$$col$$br$$std"; \ + if $$success; then :; else \ + echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \ + if test -n "$(PACKAGE_BUGREPORT)"; then \ + echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \ + fi; \ + echo "$$col$$br$$std"; \ + fi; \ + $$success || exit 1 + +check-TESTS: + @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list + @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list + @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) + @set +e; $(am__set_TESTS_bases); \ + log_list=`for i in $$bases; do echo $$i.log; done`; \ + trs_list=`for i in $$bases; do echo $$i.trs; done`; \ + log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \ + $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \ + exit $$?; +recheck: all + @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) + @set +e; $(am__set_TESTS_bases); \ + bases=`for i in $$bases; do echo $$i; done \ + | $(am__list_recheck_tests)` || exit 1; \ + log_list=`for i in $$bases; do echo $$i.log; done`; \ + log_list=`echo $$log_list`; \ + $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \ + am__force_recheck=am--force-recheck \ + TEST_LOGS="$$log_list"; \ + exit $$? +isl_test.log: isl_test$(EXEEXT) + @p='isl_test$(EXEEXT)'; \ + b='isl_test'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +codegen_test.sh.log: codegen_test.sh + @p='codegen_test.sh'; \ + b='codegen_test.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +pip_test.sh.log: pip_test.sh + @p='pip_test.sh'; \ + b='pip_test.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +bound_test.sh.log: bound_test.sh + @p='bound_test.sh'; \ + b='bound_test.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +isl_test_int.log: isl_test_int$(EXEEXT) + @p='isl_test_int$(EXEEXT)'; \ + b='isl_test_int'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +flow_test.sh.log: flow_test.sh + @p='flow_test.sh'; \ + b='flow_test.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +schedule_test.sh.log: schedule_test.sh + @p='schedule_test.sh'; \ + b='schedule_test.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +isl_test2.log: isl_test2$(EXEEXT) + @p='isl_test2$(EXEEXT)'; \ + b='isl_test2'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +isl_test_cpp.log: isl_test_cpp$(EXEEXT) + @p='isl_test_cpp$(EXEEXT)'; \ + b='isl_test_cpp'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +isl_test_cpp_failed.sh.log: isl_test_cpp_failed.sh + @p='isl_test_cpp_failed.sh'; \ + b='isl_test_cpp_failed.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +isl_test_cpp17.log: isl_test_cpp17$(EXEEXT) + @p='isl_test_cpp17$(EXEEXT)'; \ + b='isl_test_cpp17'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +isl_test_cpp17-checked.log: isl_test_cpp17-checked$(EXEEXT) + @p='isl_test_cpp17-checked$(EXEEXT)'; \ + b='isl_test_cpp17-checked'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +isl_test_cpp-checked.log: isl_test_cpp-checked$(EXEEXT) + @p='isl_test_cpp-checked$(EXEEXT)'; \ + b='isl_test_cpp-checked'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +isl_test_cpp-checked-conversion.log: isl_test_cpp-checked-conversion$(EXEEXT) + @p='isl_test_cpp-checked-conversion$(EXEEXT)'; \ + b='isl_test_cpp-checked-conversion'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +isl_test_imath.log: isl_test_imath$(EXEEXT) + @p='isl_test_imath$(EXEEXT)'; \ + b='isl_test_imath'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +.py.log: + @p='$<'; \ + $(am__set_b); \ + $(am__check_pre) $(PY_LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_PY_LOG_DRIVER_FLAGS) $(PY_LOG_DRIVER_FLAGS) -- $(PY_LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +@am__EXEEXT_TRUE@.py$(EXEEXT).log: +@am__EXEEXT_TRUE@ @p='$<'; \ +@am__EXEEXT_TRUE@ $(am__set_b); \ +@am__EXEEXT_TRUE@ $(am__check_pre) $(PY_LOG_DRIVER) --test-name "$$f" \ +@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \ +@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_PY_LOG_DRIVER_FLAGS) $(PY_LOG_DRIVER_FLAGS) -- $(PY_LOG_COMPILE) \ +@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT) +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + $(am__remove_distdir) + test -d "$(distdir)" || mkdir "$(distdir)" + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + $(am__make_dryrun) \ + || test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$(top_distdir)" distdir="$(distdir)" \ + dist-hook + -test -n "$(am__skip_mode_fix)" \ + || find "$(distdir)" -type d ! -perm -755 \ + -exec chmod u+rwx,go+rx {} \; -o \ + ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ + || chmod -R a+r "$(distdir)" +dist-gzip: distdir + tardir=$(distdir) && $(am__tar) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).tar.gz + $(am__post_remove_distdir) + +dist-bzip2: distdir + tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 + $(am__post_remove_distdir) + +dist-lzip: distdir + tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz + $(am__post_remove_distdir) + +dist-xz: distdir + tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz + $(am__post_remove_distdir) + +dist-zstd: distdir + tardir=$(distdir) && $(am__tar) | zstd -c $${ZSTD_CLEVEL-$${ZSTD_OPT--19}} >$(distdir).tar.zst + $(am__post_remove_distdir) + +dist-tarZ: distdir + @echo WARNING: "Support for distribution archives compressed with" \ + "legacy program 'compress' is deprecated." >&2 + @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 + tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z + $(am__post_remove_distdir) + +dist-shar: distdir + @echo WARNING: "Support for shar distribution archives is" \ + "deprecated." >&2 + @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 + shar $(distdir) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).shar.gz + $(am__post_remove_distdir) + +dist-zip: distdir + -rm -f $(distdir).zip + zip -rq $(distdir).zip $(distdir) + $(am__post_remove_distdir) + +dist dist-all: + $(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:' + $(am__post_remove_distdir) + +# This target untars the dist file and tries a VPATH configuration. Then +# it guarantees that the distribution is self-contained by making another +# tarfile. +distcheck: dist + case '$(DIST_ARCHIVES)' in \ + *.tar.gz*) \ + eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).tar.gz | $(am__untar) ;;\ + *.tar.bz2*) \ + bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ + *.tar.lz*) \ + lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ + *.tar.xz*) \ + xz -dc $(distdir).tar.xz | $(am__untar) ;;\ + *.tar.Z*) \ + uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ + *.shar.gz*) \ + eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).shar.gz | unshar ;;\ + *.zip*) \ + unzip $(distdir).zip ;;\ + *.tar.zst*) \ + zstd -dc $(distdir).tar.zst | $(am__untar) ;;\ + esac + chmod -R a-w $(distdir) + chmod u+w $(distdir) + mkdir $(distdir)/_build $(distdir)/_build/sub $(distdir)/_inst + chmod a-w $(distdir) + test -d $(distdir)/_build || exit 0; \ + dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ + && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ + && am__cwd=`pwd` \ + && $(am__cd) $(distdir)/_build/sub \ + && ../../configure \ + $(AM_DISTCHECK_CONFIGURE_FLAGS) \ + $(DISTCHECK_CONFIGURE_FLAGS) \ + --srcdir=../.. --prefix="$$dc_install_base" \ + && $(MAKE) $(AM_MAKEFLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) $(AM_DISTCHECK_DVI_TARGET) \ + && $(MAKE) $(AM_MAKEFLAGS) check \ + && $(MAKE) $(AM_MAKEFLAGS) install \ + && $(MAKE) $(AM_MAKEFLAGS) installcheck \ + && $(MAKE) $(AM_MAKEFLAGS) uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ + distuninstallcheck \ + && chmod -R a-w "$$dc_install_base" \ + && ({ \ + (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ + distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ + } || { rm -rf "$$dc_destdir"; exit 1; }) \ + && rm -rf "$$dc_destdir" \ + && $(MAKE) $(AM_MAKEFLAGS) dist \ + && rm -rf $(DIST_ARCHIVES) \ + && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ + && cd "$$am__cwd" \ + || exit 1 + $(am__post_remove_distdir) + @(echo "$(distdir) archives ready for distribution: "; \ + list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ + sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' +distuninstallcheck: + @test -n '$(distuninstallcheck_dir)' || { \ + echo 'ERROR: trying to run $@ with an empty' \ + '$$(distuninstallcheck_dir)' >&2; \ + exit 1; \ + }; \ + $(am__cd) '$(distuninstallcheck_dir)' || { \ + echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \ + exit 1; \ + }; \ + test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left after uninstall:" ; \ + if test -n "$(DESTDIR)"; then \ + echo " (check DESTDIR support)"; \ + fi ; \ + $(distuninstallcheck_listfiles) ; \ + exit 1; } >&2 +distcleancheck: distclean + @if test '$(srcdir)' = . ; then \ + echo "ERROR: distcleancheck can only run from a VPATH build" ; \ + exit 1 ; \ + fi + @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left in build directory after distclean:" ; \ + $(distcleancheck_listfiles) ; \ + exit 1; } >&2 +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) check-TESTS +check: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) check-recursive +all-am: Makefile $(PROGRAMS) $(LIBRARIES) $(LTLIBRARIES) $(DATA) \ + $(HEADERS) isl_config.h +install-EXTRAPROGRAMS: install-libLTLIBRARIES + +installdirs: installdirs-recursive +installdirs-am: + for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(pkgincludedir)" "$(DESTDIR)$(pkgincludedir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) install-recursive +install-exec: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS) + -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs) + -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -rm -f imath_wrap/$(DEPDIR)/$(am__dirstamp) + -rm -f imath_wrap/$(am__dirstamp) + -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) +clean: clean-recursive + +clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ + clean-noinstLIBRARIES clean-noinstPROGRAMS mostlyclean-am + +distclean: distclean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -f ./$(DEPDIR)/basis_reduction_tab.Plo + -rm -f ./$(DEPDIR)/bound.Po + -rm -f ./$(DEPDIR)/cat.Po + -rm -f ./$(DEPDIR)/closure.Po + -rm -f ./$(DEPDIR)/codegen.Po + -rm -f ./$(DEPDIR)/dep.Po + -rm -f ./$(DEPDIR)/flow.Po + -rm -f ./$(DEPDIR)/flow_cmp.Po + -rm -f ./$(DEPDIR)/isl_aff.Plo + -rm -f ./$(DEPDIR)/isl_aff_map.Plo + -rm -f ./$(DEPDIR)/isl_affine_hull.Plo + -rm -f ./$(DEPDIR)/isl_arg.Plo + -rm -f ./$(DEPDIR)/isl_ast.Plo + -rm -f ./$(DEPDIR)/isl_ast_build.Plo + -rm -f ./$(DEPDIR)/isl_ast_build_expr.Plo + -rm -f ./$(DEPDIR)/isl_ast_codegen.Plo + -rm -f ./$(DEPDIR)/isl_ast_graft.Plo + -rm -f ./$(DEPDIR)/isl_bernstein.Plo + -rm -f ./$(DEPDIR)/isl_blk.Plo + -rm -f ./$(DEPDIR)/isl_bound.Plo + -rm -f ./$(DEPDIR)/isl_box.Plo + -rm -f ./$(DEPDIR)/isl_coalesce.Plo + -rm -f ./$(DEPDIR)/isl_constraint.Plo + -rm -f ./$(DEPDIR)/isl_convex_hull.Plo + -rm -f ./$(DEPDIR)/isl_ctx.Plo + -rm -f ./$(DEPDIR)/isl_deprecated.Plo + -rm -f ./$(DEPDIR)/isl_dim_map.Plo + -rm -f ./$(DEPDIR)/isl_equalities.Plo + -rm -f ./$(DEPDIR)/isl_factorization.Plo + -rm -f ./$(DEPDIR)/isl_farkas.Plo + -rm -f ./$(DEPDIR)/isl_ffs.Plo + -rm -f ./$(DEPDIR)/isl_flow.Plo + -rm -f ./$(DEPDIR)/isl_fold.Plo + -rm -f ./$(DEPDIR)/isl_gmp.Plo + -rm -f ./$(DEPDIR)/isl_hash.Plo + -rm -f ./$(DEPDIR)/isl_id.Plo + -rm -f ./$(DEPDIR)/isl_id_to_ast_expr.Plo + -rm -f ./$(DEPDIR)/isl_id_to_id.Plo + -rm -f ./$(DEPDIR)/isl_id_to_pw_aff.Plo + -rm -f ./$(DEPDIR)/isl_ilp.Plo + -rm -f ./$(DEPDIR)/isl_imath.Plo + -rm -f ./$(DEPDIR)/isl_input.Plo + -rm -f ./$(DEPDIR)/isl_int_sioimath.Plo + -rm -f ./$(DEPDIR)/isl_local.Plo + -rm -f ./$(DEPDIR)/isl_local_space.Plo + -rm -f ./$(DEPDIR)/isl_lp.Plo + -rm -f ./$(DEPDIR)/isl_map.Plo + -rm -f ./$(DEPDIR)/isl_map_list.Plo + -rm -f ./$(DEPDIR)/isl_map_simplify.Plo + -rm -f ./$(DEPDIR)/isl_map_subtract.Plo + -rm -f ./$(DEPDIR)/isl_map_to_basic_set.Plo + -rm -f ./$(DEPDIR)/isl_mat.Plo + -rm -f ./$(DEPDIR)/isl_morph.Plo + -rm -f ./$(DEPDIR)/isl_obj.Plo + -rm -f ./$(DEPDIR)/isl_options.Plo + -rm -f ./$(DEPDIR)/isl_output.Plo + -rm -f ./$(DEPDIR)/isl_point.Plo + -rm -f ./$(DEPDIR)/isl_polynomial.Plo + -rm -f ./$(DEPDIR)/isl_printer.Plo + -rm -f ./$(DEPDIR)/isl_range.Plo + -rm -f ./$(DEPDIR)/isl_reordering.Plo + -rm -f ./$(DEPDIR)/isl_sample.Plo + -rm -f ./$(DEPDIR)/isl_scan.Plo + -rm -f ./$(DEPDIR)/isl_schedule.Plo + -rm -f ./$(DEPDIR)/isl_schedule_band.Plo + -rm -f ./$(DEPDIR)/isl_schedule_constraints.Plo + -rm -f ./$(DEPDIR)/isl_schedule_node.Plo + -rm -f ./$(DEPDIR)/isl_schedule_read.Plo + -rm -f ./$(DEPDIR)/isl_schedule_tree.Plo + -rm -f ./$(DEPDIR)/isl_scheduler.Plo + -rm -f ./$(DEPDIR)/isl_scheduler_clustering.Plo + -rm -f ./$(DEPDIR)/isl_scheduler_scc.Plo + -rm -f ./$(DEPDIR)/isl_seq.Plo + -rm -f ./$(DEPDIR)/isl_set_list.Plo + -rm -f ./$(DEPDIR)/isl_set_to_ast_graft_list.Plo + -rm -f ./$(DEPDIR)/isl_sort.Plo + -rm -f ./$(DEPDIR)/isl_space.Plo + -rm -f ./$(DEPDIR)/isl_stream.Plo + -rm -f ./$(DEPDIR)/isl_stride.Plo + -rm -f ./$(DEPDIR)/isl_tab.Plo + -rm -f ./$(DEPDIR)/isl_tab_pip.Plo + -rm -f ./$(DEPDIR)/isl_tarjan.Plo + -rm -f ./$(DEPDIR)/isl_test.Po + -rm -f ./$(DEPDIR)/isl_test2.Po + -rm -f ./$(DEPDIR)/isl_test_cpp-checked-conversion.Po + -rm -f ./$(DEPDIR)/isl_test_cpp-checked.Po + -rm -f ./$(DEPDIR)/isl_test_cpp-isl_test_cpp.Po + -rm -f ./$(DEPDIR)/isl_test_cpp17-checked.Po + -rm -f ./$(DEPDIR)/isl_test_cpp17.Po + -rm -f ./$(DEPDIR)/isl_test_cpp_failed-isl_test_cpp.Po + -rm -f ./$(DEPDIR)/isl_test_imath.Po + -rm -f ./$(DEPDIR)/isl_test_int.Po + -rm -f ./$(DEPDIR)/isl_transitive_closure.Plo + -rm -f ./$(DEPDIR)/isl_union_map.Plo + -rm -f ./$(DEPDIR)/isl_val.Plo + -rm -f ./$(DEPDIR)/isl_val_gmp.Plo + -rm -f ./$(DEPDIR)/isl_val_imath.Plo + -rm -f ./$(DEPDIR)/isl_val_sioimath.Plo + -rm -f ./$(DEPDIR)/isl_vec.Plo + -rm -f ./$(DEPDIR)/isl_version.Plo + -rm -f ./$(DEPDIR)/isl_vertices.Plo + -rm -f ./$(DEPDIR)/mp_get_memory_functions.Plo + -rm -f ./$(DEPDIR)/pip.Po + -rm -f ./$(DEPDIR)/polyhedron_detect_equalities.Po + -rm -f ./$(DEPDIR)/polyhedron_minimize.Po + -rm -f ./$(DEPDIR)/polyhedron_remove_redundant_equalities.Po + -rm -f ./$(DEPDIR)/polyhedron_sample.Po + -rm -f ./$(DEPDIR)/polytope_scan.Po + -rm -f ./$(DEPDIR)/print.Plo + -rm -f ./$(DEPDIR)/schedule.Po + -rm -f ./$(DEPDIR)/schedule_cmp.Po + -rm -f imath_wrap/$(DEPDIR)/gmp_compat.Plo + -rm -f imath_wrap/$(DEPDIR)/imath.Plo + -rm -f imath_wrap/$(DEPDIR)/imrat.Plo + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-hdr distclean-libtool distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: install-data-local install-nodist_pkgincludeHEADERS \ + install-pkgconfigDATA install-pkgincludeHEADERS + +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: install-libLTLIBRARIES + +install-html: install-html-recursive + +install-html-am: + +install-info: install-info-recursive + +install-info-am: + +install-man: + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -rf $(top_srcdir)/autom4te.cache + -rm -f ./$(DEPDIR)/basis_reduction_tab.Plo + -rm -f ./$(DEPDIR)/bound.Po + -rm -f ./$(DEPDIR)/cat.Po + -rm -f ./$(DEPDIR)/closure.Po + -rm -f ./$(DEPDIR)/codegen.Po + -rm -f ./$(DEPDIR)/dep.Po + -rm -f ./$(DEPDIR)/flow.Po + -rm -f ./$(DEPDIR)/flow_cmp.Po + -rm -f ./$(DEPDIR)/isl_aff.Plo + -rm -f ./$(DEPDIR)/isl_aff_map.Plo + -rm -f ./$(DEPDIR)/isl_affine_hull.Plo + -rm -f ./$(DEPDIR)/isl_arg.Plo + -rm -f ./$(DEPDIR)/isl_ast.Plo + -rm -f ./$(DEPDIR)/isl_ast_build.Plo + -rm -f ./$(DEPDIR)/isl_ast_build_expr.Plo + -rm -f ./$(DEPDIR)/isl_ast_codegen.Plo + -rm -f ./$(DEPDIR)/isl_ast_graft.Plo + -rm -f ./$(DEPDIR)/isl_bernstein.Plo + -rm -f ./$(DEPDIR)/isl_blk.Plo + -rm -f ./$(DEPDIR)/isl_bound.Plo + -rm -f ./$(DEPDIR)/isl_box.Plo + -rm -f ./$(DEPDIR)/isl_coalesce.Plo + -rm -f ./$(DEPDIR)/isl_constraint.Plo + -rm -f ./$(DEPDIR)/isl_convex_hull.Plo + -rm -f ./$(DEPDIR)/isl_ctx.Plo + -rm -f ./$(DEPDIR)/isl_deprecated.Plo + -rm -f ./$(DEPDIR)/isl_dim_map.Plo + -rm -f ./$(DEPDIR)/isl_equalities.Plo + -rm -f ./$(DEPDIR)/isl_factorization.Plo + -rm -f ./$(DEPDIR)/isl_farkas.Plo + -rm -f ./$(DEPDIR)/isl_ffs.Plo + -rm -f ./$(DEPDIR)/isl_flow.Plo + -rm -f ./$(DEPDIR)/isl_fold.Plo + -rm -f ./$(DEPDIR)/isl_gmp.Plo + -rm -f ./$(DEPDIR)/isl_hash.Plo + -rm -f ./$(DEPDIR)/isl_id.Plo + -rm -f ./$(DEPDIR)/isl_id_to_ast_expr.Plo + -rm -f ./$(DEPDIR)/isl_id_to_id.Plo + -rm -f ./$(DEPDIR)/isl_id_to_pw_aff.Plo + -rm -f ./$(DEPDIR)/isl_ilp.Plo + -rm -f ./$(DEPDIR)/isl_imath.Plo + -rm -f ./$(DEPDIR)/isl_input.Plo + -rm -f ./$(DEPDIR)/isl_int_sioimath.Plo + -rm -f ./$(DEPDIR)/isl_local.Plo + -rm -f ./$(DEPDIR)/isl_local_space.Plo + -rm -f ./$(DEPDIR)/isl_lp.Plo + -rm -f ./$(DEPDIR)/isl_map.Plo + -rm -f ./$(DEPDIR)/isl_map_list.Plo + -rm -f ./$(DEPDIR)/isl_map_simplify.Plo + -rm -f ./$(DEPDIR)/isl_map_subtract.Plo + -rm -f ./$(DEPDIR)/isl_map_to_basic_set.Plo + -rm -f ./$(DEPDIR)/isl_mat.Plo + -rm -f ./$(DEPDIR)/isl_morph.Plo + -rm -f ./$(DEPDIR)/isl_obj.Plo + -rm -f ./$(DEPDIR)/isl_options.Plo + -rm -f ./$(DEPDIR)/isl_output.Plo + -rm -f ./$(DEPDIR)/isl_point.Plo + -rm -f ./$(DEPDIR)/isl_polynomial.Plo + -rm -f ./$(DEPDIR)/isl_printer.Plo + -rm -f ./$(DEPDIR)/isl_range.Plo + -rm -f ./$(DEPDIR)/isl_reordering.Plo + -rm -f ./$(DEPDIR)/isl_sample.Plo + -rm -f ./$(DEPDIR)/isl_scan.Plo + -rm -f ./$(DEPDIR)/isl_schedule.Plo + -rm -f ./$(DEPDIR)/isl_schedule_band.Plo + -rm -f ./$(DEPDIR)/isl_schedule_constraints.Plo + -rm -f ./$(DEPDIR)/isl_schedule_node.Plo + -rm -f ./$(DEPDIR)/isl_schedule_read.Plo + -rm -f ./$(DEPDIR)/isl_schedule_tree.Plo + -rm -f ./$(DEPDIR)/isl_scheduler.Plo + -rm -f ./$(DEPDIR)/isl_scheduler_clustering.Plo + -rm -f ./$(DEPDIR)/isl_scheduler_scc.Plo + -rm -f ./$(DEPDIR)/isl_seq.Plo + -rm -f ./$(DEPDIR)/isl_set_list.Plo + -rm -f ./$(DEPDIR)/isl_set_to_ast_graft_list.Plo + -rm -f ./$(DEPDIR)/isl_sort.Plo + -rm -f ./$(DEPDIR)/isl_space.Plo + -rm -f ./$(DEPDIR)/isl_stream.Plo + -rm -f ./$(DEPDIR)/isl_stride.Plo + -rm -f ./$(DEPDIR)/isl_tab.Plo + -rm -f ./$(DEPDIR)/isl_tab_pip.Plo + -rm -f ./$(DEPDIR)/isl_tarjan.Plo + -rm -f ./$(DEPDIR)/isl_test.Po + -rm -f ./$(DEPDIR)/isl_test2.Po + -rm -f ./$(DEPDIR)/isl_test_cpp-checked-conversion.Po + -rm -f ./$(DEPDIR)/isl_test_cpp-checked.Po + -rm -f ./$(DEPDIR)/isl_test_cpp-isl_test_cpp.Po + -rm -f ./$(DEPDIR)/isl_test_cpp17-checked.Po + -rm -f ./$(DEPDIR)/isl_test_cpp17.Po + -rm -f ./$(DEPDIR)/isl_test_cpp_failed-isl_test_cpp.Po + -rm -f ./$(DEPDIR)/isl_test_imath.Po + -rm -f ./$(DEPDIR)/isl_test_int.Po + -rm -f ./$(DEPDIR)/isl_transitive_closure.Plo + -rm -f ./$(DEPDIR)/isl_union_map.Plo + -rm -f ./$(DEPDIR)/isl_val.Plo + -rm -f ./$(DEPDIR)/isl_val_gmp.Plo + -rm -f ./$(DEPDIR)/isl_val_imath.Plo + -rm -f ./$(DEPDIR)/isl_val_sioimath.Plo + -rm -f ./$(DEPDIR)/isl_vec.Plo + -rm -f ./$(DEPDIR)/isl_version.Plo + -rm -f ./$(DEPDIR)/isl_vertices.Plo + -rm -f ./$(DEPDIR)/mp_get_memory_functions.Plo + -rm -f ./$(DEPDIR)/pip.Po + -rm -f ./$(DEPDIR)/polyhedron_detect_equalities.Po + -rm -f ./$(DEPDIR)/polyhedron_minimize.Po + -rm -f ./$(DEPDIR)/polyhedron_remove_redundant_equalities.Po + -rm -f ./$(DEPDIR)/polyhedron_sample.Po + -rm -f ./$(DEPDIR)/polytope_scan.Po + -rm -f ./$(DEPDIR)/print.Plo + -rm -f ./$(DEPDIR)/schedule.Po + -rm -f ./$(DEPDIR)/schedule_cmp.Po + -rm -f imath_wrap/$(DEPDIR)/gmp_compat.Plo + -rm -f imath_wrap/$(DEPDIR)/imath.Plo + -rm -f imath_wrap/$(DEPDIR)/imrat.Plo + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +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-exec install-strip + +.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ + am--depfiles am--refresh check check-TESTS check-am clean \ + clean-cscope clean-generic clean-libLTLIBRARIES clean-libtool \ + clean-noinstLIBRARIES clean-noinstPROGRAMS cscope \ + cscopelist-am ctags ctags-am dist dist-all dist-bzip2 \ + dist-gzip dist-hook dist-lzip dist-shar dist-tarZ dist-xz \ + dist-zip dist-zstd distcheck distclean distclean-compile \ + distclean-generic distclean-hdr 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-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 \ + installdirs installdirs-am maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + recheck tags tags-am uninstall uninstall-am \ + uninstall-libLTLIBRARIES uninstall-local \ + uninstall-nodist_pkgincludeHEADERS uninstall-pkgconfigDATA \ + uninstall-pkgincludeHEADERS + +.PRECIOUS: Makefile + +@HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@FORCE: +@HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@interface/extract_interface$(BUILD_EXEEXT): FORCE +@HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@ $(MAKE) $(AM_MAKEFLAGS) -C interface extract_interface$(BUILD_EXEEXT) +@HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@@HAVE_PYTHON_TRUE@ isl_test_python.py: interface/isl.py libisl.la + +@HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@interface/isldlname.py: libisl.la +@HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@ $(AM_V_GEN) $(GREP) dlname $< | $(SED) -e 's/dlname/isl_dlname/' > $@ +@HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@interface/isl.py: interface/extract_interface$(BUILD_EXEEXT) libdep.a \ +@HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@ python/isl.py.top interface/isldlname.py +@HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@ (cat interface/isldlname.py $(srcdir)/python/isl.py.top && \ +@HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@ interface/extract_interface$(BUILD_EXEEXT) --language=python \ +@HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@ $(includes) $(srcdir)/all.h) \ +@HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@ > $@ || (rm $@ && false) + +@HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@include/isl/cpp.h: interface/extract_interface$(BUILD_EXEEXT) libdep.a \ +@HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@ cpp/cpp.h.top cpp/cpp.h.bot +@HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@ $(MKDIR_P) "include/isl" && \ +@HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@ (cat $(srcdir)/cpp/cpp.h.top $(srcdir)/all.h && \ +@HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@ interface/extract_interface$(BUILD_EXEEXT) --language=cpp \ +@HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@ $(includes) $(srcdir)/all.h && \ +@HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@ cat $(srcdir)/cpp/cpp.h.bot) \ +@HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@ > $@ || (rm $@ && false) + +@HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@include/isl/cpp-checked.h: interface/extract_interface$(BUILD_EXEEXT) libdep.a \ +@HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@ cpp/cpp-checked.h.top cpp/cpp-checked.h.bot +@HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@ $(MKDIR_P) "include/isl" && \ +@HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@ (cat $(srcdir)/cpp/cpp-checked.h.top $(srcdir)/all.h && \ +@HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@ interface/extract_interface$(BUILD_EXEEXT) \ +@HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@ --language=cpp-checked \ +@HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@ $(includes) $(srcdir)/all.h && \ +@HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@ cat $(srcdir)/cpp/cpp-checked.h.bot) \ +@HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@ > $@ || (rm $@ && false) + +@HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@include/isl/cpp-checked-conversion.h: \ +@HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@ interface/extract_interface$(BUILD_EXEEXT) \ +@HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@ libdep.a \ +@HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@ cpp/cpp-checked-conversion.h.top \ +@HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@ cpp/cpp-checked-conversion.h.bot +@HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@ $(MKDIR_P) "include/isl" && \ +@HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@ (cat $(srcdir)/cpp/cpp-checked-conversion.h.top && \ +@HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@ interface/extract_interface$(BUILD_EXEEXT) \ +@HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@ --language=cpp-checked-conversion \ +@HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@ $(includes) $(srcdir)/all.h && \ +@HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@ cat $(srcdir)/cpp/cpp-checked-conversion.h.bot) \ +@HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@ > $@ || (rm $@ && false) + +@HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@include/isl/typed_cpp.h: interface/extract_interface$(BUILD_EXEEXT) \ +@HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@ libdep.a cpp/typed_cpp.h.top cpp/typed_cpp.h.bot +@HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@ $(MKDIR_P) "include/isl" && \ +@HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@ (cat $(srcdir)/cpp/typed_cpp.h.top && \ +@HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@ interface/extract_interface$(BUILD_EXEEXT) \ +@HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@ --language=template-cpp \ +@HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@ $(includes) $(srcdir)/all.h && \ +@HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@ cat $(srcdir)/cpp/typed_cpp.h.bot) \ +@HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@ > $@ || (rm $@ && false) + +dist-hook: + echo @GIT_HEAD_VERSION@ > $(distdir)/GIT_HEAD_ID + (cd doc; make manual.pdf) + cp doc/manual.pdf $(distdir)/doc/ + +gitversion.h: @GIT_HEAD@ + $(AM_V_GEN)echo '#define GIT_HEAD_ID "'@GIT_HEAD_VERSION@'"' > $@ + +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)/libisl-gdb.py \ + $(DESTDIR)$(libdir)/$$libisl-gdb.py; \ + test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)"; \ + $(INSTALL_DATA) $(srcdir)/libisl-gdb.py \ + $(DESTDIR)$(libdir)/$$libisl-gdb.py; \ + esac + +uninstall-local: + @libisl=`sed -ne "/^library_names=/{s/.*='//;s/'$$//;s/ .*//;p;}" \ + $(builddir)/libisl.la`; \ + if test -n "$${libisl}"; then \ + rm -f $(DESTDIR)$(libdir)/$$libisl-gdb.py; \ + fi + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/external/mit/isl/dist/README b/external/mit/isl/dist/README new file mode 100644 index 000000000000..e7a5f7d20c7d --- /dev/null +++ b/external/mit/isl/dist/README @@ -0,0 +1,53 @@ +isl is a thread-safe C library for manipulating sets and relations +of integer points bounded by affine constraints. The descriptions of +the sets and relations may involve both parameters and existentially +quantified variables. All computations are performed in exact integer +arithmetic using GMP. + +isl is released under the MIT license, but depends on the LGPL GMP +library. + +Minimal compilation instructions: + + ./configure + make + make install + +If you are taking the source from the git repository, then you first +need to do + + git clone git://repo.or.cz/isl.git + ./autogen.sh + +For more information, see doc/user.pod or the generated documentation. + +New releases are announced on http://groups.google.com/group/isl-announce + +If you use isl, you can let me know by stacking +https://www.openhub.net/p/isl on Open Hub. + +For bug reports, feature requests and questions, +contact http://groups.google.com/group/isl-development + +Whenever you report a bug, please mention the exact version of isl +that you are using (output of "./isl_cat --version"). If you are unable +to compile isl, then report the git version (output of "git describe") +or the version included in the name of the tarball. + +If you use isl for your research, you are invited do cite +the following paper and/or the paper(s) describing the specific +operations you use. + +@incollection{Verdoolaege2010isl, + author = {Verdoolaege, Sven}, + title = {isl: An Integer Set Library for the Polyhedral Model}, + booktitle = {Mathematical Software - ICMS 2010}, + series = {Lecture Notes in Computer Science}, + editor = {Fukuda, Komei and Hoeven, Joris and Joswig, Michael and + Takayama, Nobuki}, + publisher = {Springer}, + isbn = {978-3-642-15581-9}, + pages = {299-302}, + volume = {6327}, + year = {2010} +} diff --git a/external/mit/isl/dist/aclocal.m4 b/external/mit/isl/dist/aclocal.m4 new file mode 100644 index 000000000000..4623a76bd1d9 --- /dev/null +++ b/external/mit/isl/dist/aclocal.m4 @@ -0,0 +1,1533 @@ +# generated automatically by aclocal 1.16.5 -*- Autoconf -*- + +# Copyright (C) 1996-2021 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. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) +m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.71],, +[m4_warning([this file was generated for autoconf 2.71. +You have another version of autoconf. It may work, but is not guaranteed to. +If you have problems, you may need to regenerate the build system entirely. +To do so, use the procedure documented by the package, typically 'autoreconf'.])]) + +# Copyright (C) 2002-2021 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_AUTOMAKE_VERSION(VERSION) +# ---------------------------- +# Automake X.Y traces this macro to ensure aclocal.m4 has been +# generated from the m4 files accompanying Automake X.Y. +# (This private macro should not be called outside this file.) +AC_DEFUN([AM_AUTOMAKE_VERSION], +[am__api_version='1.16' +dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to +dnl require some minimum version. Point them to the right macro. +m4_if([$1], [1.16.5], [], + [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl +]) + +# _AM_AUTOCONF_VERSION(VERSION) +# ----------------------------- +# aclocal traces this macro to find the Autoconf version. +# This is a private macro too. Using m4_define simplifies +# the logic in aclocal, which can simply ignore this definition. +m4_define([_AM_AUTOCONF_VERSION], []) + +# AM_SET_CURRENT_AUTOMAKE_VERSION +# ------------------------------- +# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. +# This function is AC_REQUIREd by AM_INIT_AUTOMAKE. +AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], +[AM_AUTOMAKE_VERSION([1.16.5])dnl +m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) + +# AM_AUX_DIR_EXPAND -*- Autoconf -*- + +# Copyright (C) 2001-2021 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. + +# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets +# $ac_aux_dir to '$srcdir/foo'. In other projects, it is set to +# '$srcdir', '$srcdir/..', or '$srcdir/../..'. +# +# Of course, Automake must honor this variable whenever it calls a +# tool from the auxiliary directory. The problem is that $srcdir (and +# therefore $ac_aux_dir as well) can be either absolute or relative, +# depending on how configure is run. This is pretty annoying, since +# it makes $ac_aux_dir quite unusable in subdirectories: in the top +# source directory, any form will work fine, but in subdirectories a +# relative path needs to be adjusted first. +# +# $ac_aux_dir/missing +# fails when called from a subdirectory if $ac_aux_dir is relative +# $top_srcdir/$ac_aux_dir/missing +# fails if $ac_aux_dir is absolute, +# fails when called from a subdirectory in a VPATH build with +# a relative $ac_aux_dir +# +# The reason of the latter failure is that $top_srcdir and $ac_aux_dir +# are both prefixed by $srcdir. In an in-source build this is usually +# harmless because $srcdir is '.', but things will broke when you +# start a VPATH build or use an absolute $srcdir. +# +# So we could use something similar to $top_srcdir/$ac_aux_dir/missing, +# iff we strip the leading $srcdir from $ac_aux_dir. That would be: +# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` +# and then we would define $MISSING as +# MISSING="\${SHELL} $am_aux_dir/missing" +# This will work as long as MISSING is not called from configure, because +# unfortunately $(top_srcdir) has no meaning in configure. +# However there are other variables, like CC, which are often used in +# configure, and could therefore not use this "fixed" $ac_aux_dir. +# +# Another solution, used here, is to always expand $ac_aux_dir to an +# absolute PATH. The drawback is that using absolute paths prevent a +# configured tree to be moved without reconfiguration. + +AC_DEFUN([AM_AUX_DIR_EXPAND], +[AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl +# Expand $ac_aux_dir to an absolute path. +am_aux_dir=`cd "$ac_aux_dir" && pwd` +]) + +# AM_CONDITIONAL -*- Autoconf -*- + +# Copyright (C) 1997-2021 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_CONDITIONAL(NAME, SHELL-CONDITION) +# ------------------------------------- +# Define a conditional. +AC_DEFUN([AM_CONDITIONAL], +[AC_PREREQ([2.52])dnl + m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], + [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl +AC_SUBST([$1_TRUE])dnl +AC_SUBST([$1_FALSE])dnl +_AM_SUBST_NOTMAKE([$1_TRUE])dnl +_AM_SUBST_NOTMAKE([$1_FALSE])dnl +m4_define([_AM_COND_VALUE_$1], [$2])dnl +if $2; then + $1_TRUE= + $1_FALSE='#' +else + $1_TRUE='#' + $1_FALSE= +fi +AC_CONFIG_COMMANDS_PRE( +[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then + AC_MSG_ERROR([[conditional "$1" was never defined. +Usually this means the macro was only invoked conditionally.]]) +fi])]) + +# Copyright (C) 1999-2021 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. + + +# There are a few dirty hacks below to avoid letting 'AC_PROG_CC' be +# written in clear, in which case automake, when reading aclocal.m4, +# will think it sees a *use*, and therefore will trigger all it's +# C support machinery. Also note that it means that autoscan, seeing +# CC etc. in the Makefile, will ask for an AC_PROG_CC use... + + +# _AM_DEPENDENCIES(NAME) +# ---------------------- +# See how the compiler implements dependency checking. +# NAME is "CC", "CXX", "OBJC", "OBJCXX", "UPC", or "GJC". +# We try a few techniques and use that to set a single cache variable. +# +# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was +# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular +# dependency, and given that the user is not expected to run this macro, +# just rely on AC_PROG_CC. +AC_DEFUN([_AM_DEPENDENCIES], +[AC_REQUIRE([AM_SET_DEPDIR])dnl +AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl +AC_REQUIRE([AM_MAKE_INCLUDE])dnl +AC_REQUIRE([AM_DEP_TRACK])dnl + +m4_if([$1], [CC], [depcc="$CC" am_compiler_list=], + [$1], [CXX], [depcc="$CXX" am_compiler_list=], + [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'], + [$1], [OBJCXX], [depcc="$OBJCXX" am_compiler_list='gcc3 gcc'], + [$1], [UPC], [depcc="$UPC" am_compiler_list=], + [$1], [GCJ], [depcc="$GCJ" am_compiler_list='gcc3 gcc'], + [depcc="$$1" am_compiler_list=]) + +AC_CACHE_CHECK([dependency style of $depcc], + [am_cv_$1_dependencies_compiler_type], +[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named 'D' -- because '-MD' means "put the output + # in D". + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_$1_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` + fi + am__universal=false + m4_case([$1], [CC], + [case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac], + [CXX], + [case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac]) + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with + # Solaris 10 /bin/sh. + echo '/* dummy */' > sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with '-c' and '-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle '-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs. + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # After this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested. + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok '-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_$1_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_$1_dependencies_compiler_type=none +fi +]) +AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) +AM_CONDITIONAL([am__fastdep$1], [ + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) +]) + + +# AM_SET_DEPDIR +# ------------- +# Choose a directory name for dependency files. +# This macro is AC_REQUIREd in _AM_DEPENDENCIES. +AC_DEFUN([AM_SET_DEPDIR], +[AC_REQUIRE([AM_SET_LEADING_DOT])dnl +AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl +]) + + +# AM_DEP_TRACK +# ------------ +AC_DEFUN([AM_DEP_TRACK], +[AC_ARG_ENABLE([dependency-tracking], [dnl +AS_HELP_STRING( + [--enable-dependency-tracking], + [do not reject slow dependency extractors]) +AS_HELP_STRING( + [--disable-dependency-tracking], + [speeds up one-time build])]) +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' + am__nodep='_no' +fi +AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) +AC_SUBST([AMDEPBACKSLASH])dnl +_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl +AC_SUBST([am__nodep])dnl +_AM_SUBST_NOTMAKE([am__nodep])dnl +]) + +# Generate code to set up dependency tracking. -*- Autoconf -*- + +# Copyright (C) 1999-2021 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_OUTPUT_DEPENDENCY_COMMANDS +# ------------------------------ +AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], +[{ + # Older Autoconf quotes --file arguments for eval, but not when files + # are listed without --file. Let's play safe and only enable the eval + # if we detect the quoting. + # TODO: see whether this extra hack can be removed once we start + # requiring Autoconf 2.70 or later. + AS_CASE([$CONFIG_FILES], + [*\'*], [eval set x "$CONFIG_FILES"], + [*], [set x $CONFIG_FILES]) + shift + # Used to flag and report bootstrapping failures. + am_rc=0 + for am_mf + do + # Strip MF so we end up with the name of the file. + am_mf=`AS_ECHO(["$am_mf"]) | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile which includes + # dependency-tracking related rules and includes. + # Grep'ing the whole file directly is not great: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + sed -n 's,^am--depfiles:.*,X,p' "$am_mf" | grep X >/dev/null 2>&1 \ + || continue + am_dirpart=`AS_DIRNAME(["$am_mf"])` + am_filepart=`AS_BASENAME(["$am_mf"])` + AM_RUN_LOG([cd "$am_dirpart" \ + && sed -e '/# am--include-marker/d' "$am_filepart" \ + | $MAKE -f - am--depfiles]) || am_rc=$? + done + if test $am_rc -ne 0; then + AC_MSG_FAILURE([Something went wrong bootstrapping makefile fragments + for automatic dependency tracking. If GNU make was not used, consider + re-running the configure script with MAKE="gmake" (or whatever is + necessary). You can also try re-running configure with the + '--disable-dependency-tracking' option to at least be able to build + the package (albeit without support for automatic dependency tracking).]) + fi + AS_UNSET([am_dirpart]) + AS_UNSET([am_filepart]) + AS_UNSET([am_mf]) + AS_UNSET([am_rc]) + rm -f conftest-deps.mk +} +])# _AM_OUTPUT_DEPENDENCY_COMMANDS + + +# AM_OUTPUT_DEPENDENCY_COMMANDS +# ----------------------------- +# This macro should only be invoked once -- use via AC_REQUIRE. +# +# This code is only required when automatic dependency tracking is enabled. +# This creates each '.Po' and '.Plo' makefile fragment that we'll need in +# order to bootstrap the dependency handling code. +AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], +[AC_CONFIG_COMMANDS([depfiles], + [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], + [AMDEP_TRUE="$AMDEP_TRUE" MAKE="${MAKE-make}"])]) + +# Do all the work for Automake. -*- Autoconf -*- + +# Copyright (C) 1996-2021 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. + +# This macro actually does too much. Some checks are only needed if +# your package does certain things. But this isn't really a big deal. + +dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O. +m4_define([AC_PROG_CC], +m4_defn([AC_PROG_CC]) +[_AM_PROG_CC_C_O +]) + +# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) +# AM_INIT_AUTOMAKE([OPTIONS]) +# ----------------------------------------------- +# The call with PACKAGE and VERSION arguments is the old style +# call (pre autoconf-2.50), which is being phased out. PACKAGE +# and VERSION should now be passed to AC_INIT and removed from +# the call to AM_INIT_AUTOMAKE. +# We support both call styles for the transition. After +# the next Automake release, Autoconf can make the AC_INIT +# arguments mandatory, and then we can depend on a new Autoconf +# release and drop the old call support. +AC_DEFUN([AM_INIT_AUTOMAKE], +[AC_PREREQ([2.65])dnl +m4_ifdef([_$0_ALREADY_INIT], + [m4_fatal([$0 expanded multiple times +]m4_defn([_$0_ALREADY_INIT]))], + [m4_define([_$0_ALREADY_INIT], m4_expansion_stack)])dnl +dnl Autoconf wants to disallow AM_ names. We explicitly allow +dnl the ones we care about. +m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl +AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl +AC_REQUIRE([AC_PROG_INSTALL])dnl +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi +AC_SUBST([CYGPATH_W]) + +# Define the identity of the package. +dnl Distinguish between old-style and new-style calls. +m4_ifval([$2], +[AC_DIAGNOSE([obsolete], + [$0: two- and three-arguments forms are deprecated.]) +m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl + AC_SUBST([PACKAGE], [$1])dnl + AC_SUBST([VERSION], [$2])], +[_AM_SET_OPTIONS([$1])dnl +dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. +m4_if( + m4_ifset([AC_PACKAGE_NAME], [ok]):m4_ifset([AC_PACKAGE_VERSION], [ok]), + [ok:ok],, + [m4_fatal([AC_INIT should be called with package and version arguments])])dnl + AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl + AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl + +_AM_IF_OPTION([no-define],, +[AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package]) + AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl + +# Some tools Automake needs. +AC_REQUIRE([AM_SANITY_CHECK])dnl +AC_REQUIRE([AC_ARG_PROGRAM])dnl +AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}]) +AM_MISSING_PROG([AUTOCONF], [autoconf]) +AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}]) +AM_MISSING_PROG([AUTOHEADER], [autoheader]) +AM_MISSING_PROG([MAKEINFO], [makeinfo]) +AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl +AC_REQUIRE([AC_PROG_MKDIR_P])dnl +# For better backward compatibility. To be removed once Automake 1.9.x +# dies out for good. For more background, see: +# +# +AC_SUBST([mkdir_p], ['$(MKDIR_P)']) +# We need awk for the "check" target (and possibly the TAP driver). The +# system "awk" is bad on some platforms. +AC_REQUIRE([AC_PROG_AWK])dnl +AC_REQUIRE([AC_PROG_MAKE_SET])dnl +AC_REQUIRE([AM_SET_LEADING_DOT])dnl +_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], + [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], + [_AM_PROG_TAR([v7])])]) +_AM_IF_OPTION([no-dependencies],, +[AC_PROVIDE_IFELSE([AC_PROG_CC], + [_AM_DEPENDENCIES([CC])], + [m4_define([AC_PROG_CC], + m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl +AC_PROVIDE_IFELSE([AC_PROG_CXX], + [_AM_DEPENDENCIES([CXX])], + [m4_define([AC_PROG_CXX], + m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl +AC_PROVIDE_IFELSE([AC_PROG_OBJC], + [_AM_DEPENDENCIES([OBJC])], + [m4_define([AC_PROG_OBJC], + m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl +AC_PROVIDE_IFELSE([AC_PROG_OBJCXX], + [_AM_DEPENDENCIES([OBJCXX])], + [m4_define([AC_PROG_OBJCXX], + m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl +]) +# Variables for tags utilities; see am/tags.am +if test -z "$CTAGS"; then + CTAGS=ctags +fi +AC_SUBST([CTAGS]) +if test -z "$ETAGS"; then + ETAGS=etags +fi +AC_SUBST([ETAGS]) +if test -z "$CSCOPE"; then + CSCOPE=cscope +fi +AC_SUBST([CSCOPE]) + +AC_REQUIRE([AM_SILENT_RULES])dnl +dnl The testsuite driver may need to know about EXEEXT, so add the +dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This +dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below. +AC_CONFIG_COMMANDS_PRE(dnl +[m4_provide_if([_AM_COMPILER_EXEEXT], + [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl + +# POSIX will say in a future version that running "rm -f" with no argument +# is OK; and we want to be able to make that assumption in our Makefile +# recipes. So use an aggressive probe to check that the usage we want is +# actually supported "in the wild" to an acceptable degree. +# See automake bug#10828. +# To make any issue more visible, cause the running configure to be aborted +# by default if the 'rm' program in use doesn't match our expectations; the +# user can still override this though. +if rm -f && rm -fr && rm -rf; then : OK; else + cat >&2 <<'END' +Oops! + +Your 'rm' program seems unable to run without file operands specified +on the command line, even when the '-f' option is present. This is contrary +to the behaviour of most rm programs out there, and not conforming with +the upcoming POSIX standard: + +Please tell bug-automake@gnu.org about your system, including the value +of your $PATH and any error possibly output before this message. This +can help us improve future automake versions. + +END + if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then + echo 'Configuration will proceed anyway, since you have set the' >&2 + echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 + echo >&2 + else + cat >&2 <<'END' +Aborting the configuration process, to ensure you take notice of the issue. + +You can download and install GNU coreutils to get an 'rm' implementation +that behaves properly: . + +If you want to complete the configuration process using your problematic +'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM +to "yes", and re-run configure. + +END + AC_MSG_ERROR([Your 'rm' program is bad, sorry.]) + fi +fi +dnl The trailing newline in this macro's definition is deliberate, for +dnl backward compatibility and to allow trailing 'dnl'-style comments +dnl after the AM_INIT_AUTOMAKE invocation. See automake bug#16841. +]) + +dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not +dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further +dnl mangled by Autoconf and run in a shell conditional statement. +m4_define([_AC_COMPILER_EXEEXT], +m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) + +# When config.status generates a header, we must update the stamp-h file. +# This file resides in the same directory as the config header +# that is generated. The stamp files are numbered to have different names. + +# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the +# loop where config.status creates the headers, so we can generate +# our stamp files there. +AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], +[# Compute $1's index in $config_headers. +_am_arg=$1 +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $_am_arg | $_am_arg:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) + +# Copyright (C) 2001-2021 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_PROG_INSTALL_SH +# ------------------ +# Define $install_sh. +AC_DEFUN([AM_PROG_INSTALL_SH], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +if test x"${install_sh+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; + *) + install_sh="\${SHELL} $am_aux_dir/install-sh" + esac +fi +AC_SUBST([install_sh])]) + +# Copyright (C) 2003-2021 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. + +# Check whether the underlying file-system supports filenames +# with a leading dot. For instance MS-DOS doesn't. +AC_DEFUN([AM_SET_LEADING_DOT], +[rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null +AC_SUBST([am__leading_dot])]) + +# Check to see how 'make' treats includes. -*- Autoconf -*- + +# Copyright (C) 2001-2021 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_MAKE_INCLUDE() +# ----------------- +# Check whether make has an 'include' directive that can support all +# the idioms we need for our automatic dependency tracking code. +AC_DEFUN([AM_MAKE_INCLUDE], +[AC_MSG_CHECKING([whether ${MAKE-make} supports the include directive]) +cat > confinc.mk << 'END' +am__doit: + @echo this is the am__doit target >confinc.out +.PHONY: am__doit +END +am__include="#" +am__quote= +# BSD make does it like this. +echo '.include "confinc.mk" # ignored' > confmf.BSD +# Other make implementations (GNU, Solaris 10, AIX) do it like this. +echo 'include confinc.mk # ignored' > confmf.GNU +_am_result=no +for s in GNU BSD; do + AM_RUN_LOG([${MAKE-make} -f confmf.$s && cat confinc.out]) + AS_CASE([$?:`cat confinc.out 2>/dev/null`], + ['0:this is the am__doit target'], + [AS_CASE([$s], + [BSD], [am__include='.include' am__quote='"'], + [am__include='include' am__quote=''])]) + if test "$am__include" != "#"; then + _am_result="yes ($s style)" + break + fi +done +rm -f confinc.* confmf.* +AC_MSG_RESULT([${_am_result}]) +AC_SUBST([am__include])]) +AC_SUBST([am__quote])]) + +# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- + +# Copyright (C) 1997-2021 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_MISSING_PROG(NAME, PROGRAM) +# ------------------------------ +AC_DEFUN([AM_MISSING_PROG], +[AC_REQUIRE([AM_MISSING_HAS_RUN]) +$1=${$1-"${am_missing_run}$2"} +AC_SUBST($1)]) + +# AM_MISSING_HAS_RUN +# ------------------ +# Define MISSING if not defined so far and test if it is modern enough. +# If it is, set am_missing_run to use it, otherwise, to nothing. +AC_DEFUN([AM_MISSING_HAS_RUN], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +AC_REQUIRE_AUX_FILE([missing])dnl +if test x"${MISSING+set}" != xset; then + MISSING="\${SHELL} '$am_aux_dir/missing'" +fi +# Use eval to expand $SHELL +if eval "$MISSING --is-lightweight"; then + am_missing_run="$MISSING " +else + am_missing_run= + AC_MSG_WARN(['missing' script is too old or missing]) +fi +]) + +# Helper functions for option handling. -*- Autoconf -*- + +# Copyright (C) 2001-2021 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_MANGLE_OPTION(NAME) +# ----------------------- +AC_DEFUN([_AM_MANGLE_OPTION], +[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) + +# _AM_SET_OPTION(NAME) +# -------------------- +# Set option NAME. Presently that only means defining a flag for this option. +AC_DEFUN([_AM_SET_OPTION], +[m4_define(_AM_MANGLE_OPTION([$1]), [1])]) + +# _AM_SET_OPTIONS(OPTIONS) +# ------------------------ +# OPTIONS is a space-separated list of Automake options. +AC_DEFUN([_AM_SET_OPTIONS], +[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) + +# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) +# ------------------------------------------- +# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. +AC_DEFUN([_AM_IF_OPTION], +[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) + +# Copyright (C) 1999-2021 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_PROG_CC_C_O +# --------------- +# Like AC_PROG_CC_C_O, but changed for automake. We rewrite AC_PROG_CC +# to automatically call this. +AC_DEFUN([_AM_PROG_CC_C_O], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +AC_REQUIRE_AUX_FILE([compile])dnl +AC_LANG_PUSH([C])dnl +AC_CACHE_CHECK( + [whether $CC understands -c and -o together], + [am_cv_prog_cc_c_o], + [AC_LANG_CONFTEST([AC_LANG_PROGRAM([])]) + # Make sure it works both with $CC and with simple cc. + # Following AC_PROG_CC_C_O, we do the test twice because some + # compilers refuse to overwrite an existing .o file with -o, + # though they will create one. + am_cv_prog_cc_c_o=yes + for am_i in 1 2; do + if AM_RUN_LOG([$CC -c conftest.$ac_ext -o conftest2.$ac_objext]) \ + && test -f conftest2.$ac_objext; then + : OK + else + am_cv_prog_cc_c_o=no + break + fi + done + rm -f core conftest* + unset am_i]) +if test "$am_cv_prog_cc_c_o" != yes; then + # Losing compiler, so override with the script. + # FIXME: It is wrong to rewrite CC. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__CC in this case, + # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" + CC="$am_aux_dir/compile $CC" +fi +AC_LANG_POP([C])]) + +# For backward compatibility. +AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) + +# Copyright (C) 1999-2021 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 dnl + python3.11 python3.10 dnl + python3.9 python3.8 python3.7 python3.6 python3.5 python3.4 python3.3 dnl + python3.2 python3.1 python3.0 dnl + python2.7 python2.6 python2.5 python2.4 python2.3 python2.2 python2.1 dnl + 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. Although site.py simply uses + dnl sys.version[:3], printing that failed with Python 3.10, since the + dnl trailing zero was eliminated. So now we output just the major + dnl and minor version numbers, as numbers. Apparently the tertiary + dnl version is not of interest. + dnl + AC_CACHE_CHECK([for $am_display_PYTHON version], [am_cv_python_version], + [am_cv_python_version=`$PYTHON -c "import sys; print ('%u.%u' % sys.version_info[[:2]])"`]) + AC_SUBST([PYTHON_VERSION], [$am_cv_python_version]) + + dnl At times, e.g., when building shared libraries, you may want + dnl to know which OS platform Python thinks this is. + dnl + 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]) + + dnl emacs-page + dnl If --with-python-sys-prefix is given, use the values of sys.prefix + dnl and sys.exec_prefix for the corresponding values of PYTHON_PREFIX + dnl and PYTHON_EXEC_PREFIX. Otherwise, use the GNU ${prefix} and + dnl ${exec_prefix} variables. + dnl + dnl The two are made distinct variables so they can be overridden if + dnl need be, although general consensus is that you shouldn't need + dnl this separation. + dnl + dnl Also allow directly setting the prefixes via configure options, + dnl overriding any default. + dnl + if test "x$prefix" = xNONE; then + am__usable_prefix=$ac_default_prefix + else + am__usable_prefix=$prefix + fi + + # Allow user to request using sys.* values from Python, + # instead of the GNU $prefix values. + AC_ARG_WITH([python-sys-prefix], + [AS_HELP_STRING([--with-python-sys-prefix], + [use Python's sys.prefix and sys.exec_prefix values])], + [am_use_python_sys=:], + [am_use_python_sys=false]) + + # Allow user to override whatever the default Python prefix is. + AC_ARG_WITH([python_prefix], + [AS_HELP_STRING([--with-python_prefix], + [override the default PYTHON_PREFIX])], + [am_python_prefix_subst=$withval + am_cv_python_prefix=$withval + AC_MSG_CHECKING([for explicit $am_display_PYTHON prefix]) + AC_MSG_RESULT([$am_cv_python_prefix])], + [ + if $am_use_python_sys; then + # using python sys.prefix value, not GNU + AC_CACHE_CHECK([for python default $am_display_PYTHON prefix], + [am_cv_python_prefix], + [am_cv_python_prefix=`$PYTHON -c "import sys; sys.stdout.write(sys.prefix)"`]) + + dnl If sys.prefix is a subdir of $prefix, replace the literal value of + dnl $prefix with a variable reference so it can be overridden. + case $am_cv_python_prefix in + $am__usable_prefix*) + am__strip_prefix=`echo "$am__usable_prefix" | sed 's|.|.|g'` + am_python_prefix_subst=`echo "$am_cv_python_prefix" | sed "s,^$am__strip_prefix,\\${prefix},"` + ;; + *) + am_python_prefix_subst=$am_cv_python_prefix + ;; + esac + else # using GNU prefix value, not python sys.prefix + am_python_prefix_subst='${prefix}' + am_python_prefix=$am_python_prefix_subst + AC_MSG_CHECKING([for GNU default $am_display_PYTHON prefix]) + AC_MSG_RESULT([$am_python_prefix]) + fi]) + # Substituting python_prefix_subst value. + AC_SUBST([PYTHON_PREFIX], [$am_python_prefix_subst]) + + # emacs-page Now do it all over again for Python exec_prefix, but with yet + # another conditional: fall back to regular prefix if that was specified. + AC_ARG_WITH([python_exec_prefix], + [AS_HELP_STRING([--with-python_exec_prefix], + [override the default PYTHON_EXEC_PREFIX])], + [am_python_exec_prefix_subst=$withval + am_cv_python_exec_prefix=$withval + AC_MSG_CHECKING([for explicit $am_display_PYTHON exec_prefix]) + AC_MSG_RESULT([$am_cv_python_exec_prefix])], + [ + # no explicit --with-python_exec_prefix, but if + # --with-python_prefix was given, use its value for python_exec_prefix too. + AS_IF([test -n "$with_python_prefix"], + [am_python_exec_prefix_subst=$with_python_prefix + am_cv_python_exec_prefix=$with_python_prefix + AC_MSG_CHECKING([for python_prefix-given $am_display_PYTHON exec_prefix]) + AC_MSG_RESULT([$am_cv_python_exec_prefix])], + [ + # Set am__usable_exec_prefix whether using GNU or Python values, + # since we use that variable for pyexecdir. + if test "x$exec_prefix" = xNONE; then + am__usable_exec_prefix=$am__usable_prefix + else + am__usable_exec_prefix=$exec_prefix + fi + # + if $am_use_python_sys; then # using python sys.exec_prefix, not GNU + AC_CACHE_CHECK([for python default $am_display_PYTHON exec_prefix], + [am_cv_python_exec_prefix], + [am_cv_python_exec_prefix=`$PYTHON -c "import sys; sys.stdout.write(sys.exec_prefix)"`]) + dnl If sys.exec_prefix is a subdir of $exec_prefix, replace the + dnl literal value of $exec_prefix with a variable reference so it can + dnl be overridden. + case $am_cv_python_exec_prefix in + $am__usable_exec_prefix*) + am__strip_prefix=`echo "$am__usable_exec_prefix" | sed 's|.|.|g'` + am_python_exec_prefix_subst=`echo "$am_cv_python_exec_prefix" | sed "s,^$am__strip_prefix,\\${exec_prefix},"` + ;; + *) + am_python_exec_prefix_subst=$am_cv_python_exec_prefix + ;; + esac + else # using GNU $exec_prefix, not python sys.exec_prefix + am_python_exec_prefix_subst='${exec_prefix}' + am_python_exec_prefix=$am_python_exec_prefix_subst + AC_MSG_CHECKING([for GNU default $am_display_PYTHON exec_prefix]) + AC_MSG_RESULT([$am_python_exec_prefix]) + fi])]) + # Substituting python_exec_prefix_subst. + AC_SUBST([PYTHON_EXEC_PREFIX], [$am_python_exec_prefix_subst]) + + # Factor out some code duplication into this shell variable. + 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: +# +try: + from platform import python_implementation + if python_implementation() == 'CPython' and sys.version[[:3]] == '2.7': + can_use_sysconfig = 0 +except ImportError: + pass" + + dnl emacs-page Set up 4 directories: + + dnl 1. 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. + dnl + AC_CACHE_CHECK([for $am_display_PYTHON script directory (pythondir)], + [am_cv_python_pythondir], + [if test "x$am_cv_python_prefix" = x; then + am_py_prefix=$am__usable_prefix + else + am_py_prefix=$am_cv_python_prefix + fi + am_cv_python_pythondir=`$PYTHON -c " +$am_python_setup_sysconfig +if can_use_sysconfig: + if hasattr(sysconfig, 'get_default_scheme'): + scheme = sysconfig.get_default_scheme() + else: + scheme = sysconfig._get_default_scheme() + if scheme == 'posix_local': + # Debian's default scheme installs to /usr/local/ but we want to find headers in /usr/ + scheme = 'posix_prefix' + sitedir = sysconfig.get_path('purelib', scheme, 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 2. 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. + dnl + AC_SUBST([pkgpythondir], [\${pythondir}/$PACKAGE]) + + dnl 3. pyexecdir: directory for installing python extension modules + dnl (shared libraries). + dnl Query distutils for this directory. + dnl + AC_CACHE_CHECK([for $am_display_PYTHON extension module directory (pyexecdir)], + [am_cv_python_pyexecdir], + [if test "x$am_cv_python_exec_prefix" = x; then + am_py_exec_prefix=$am__usable_exec_prefix + else + am_py_exec_prefix=$am_cv_python_exec_prefix + fi + am_cv_python_pyexecdir=`$PYTHON -c " +$am_python_setup_sysconfig +if can_use_sysconfig: + if hasattr(sysconfig, 'get_default_scheme'): + scheme = sysconfig.get_default_scheme() + else: + scheme = sysconfig._get_default_scheme() + if scheme == 'posix_local': + # Debian's default scheme installs to /usr/local/ but we want to find headers in /usr/ + scheme = 'posix_prefix' + sitedir = sysconfig.get_path('platlib', scheme, vars={'platbase':'$am_py_exec_prefix'}) +else: + from distutils import sysconfig + sitedir = sysconfig.get_python_lib(1, 0, prefix='$am_py_exec_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 4. pkgpyexecdir: $(pyexecdir)/$(PACKAGE) + dnl + 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-2021 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_RUN_LOG(COMMAND) +# ------------------- +# Run COMMAND, save the exit status in ac_status, and log it. +# (This has been adapted from Autoconf's _AC_RUN_LOG macro.) +AC_DEFUN([AM_RUN_LOG], +[{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD + ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + (exit $ac_status); }]) + +# Check to make sure that the build environment is sane. -*- Autoconf -*- + +# Copyright (C) 1996-2021 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_SANITY_CHECK +# --------------- +AC_DEFUN([AM_SANITY_CHECK], +[AC_MSG_CHECKING([whether build environment is sane]) +# Reject unsafe characters in $srcdir or the absolute working directory +# name. Accept space and tab only in the latter. +am_lf=' +' +case `pwd` in + *[[\\\"\#\$\&\'\`$am_lf]]*) + AC_MSG_ERROR([unsafe absolute working directory name]);; +esac +case $srcdir in + *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) + AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);; +esac + +# Do 'set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + am_has_slept=no + for am_try in 1 2; do + echo "timestamp, slept: $am_has_slept" > conftest.file + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$[*]" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + if test "$[*]" != "X $srcdir/configure conftest.file" \ + && test "$[*]" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken + alias in your environment]) + fi + if test "$[2]" = conftest.file || test $am_try -eq 2; then + break + fi + # Just in case. + sleep 1 + am_has_slept=yes + done + test "$[2]" = conftest.file + ) +then + # Ok. + : +else + AC_MSG_ERROR([newly created file is older than distributed files! +Check your system clock]) +fi +AC_MSG_RESULT([yes]) +# If we didn't sleep, we still need to ensure time stamps of config.status and +# generated files are strictly newer. +am_sleep_pid= +if grep 'slept: no' conftest.file >/dev/null 2>&1; then + ( sleep 1 ) & + am_sleep_pid=$! +fi +AC_CONFIG_COMMANDS_PRE( + [AC_MSG_CHECKING([that generated files are newer than configure]) + if test -n "$am_sleep_pid"; then + # Hide warnings about reused PIDs. + wait $am_sleep_pid 2>/dev/null + fi + AC_MSG_RESULT([done])]) +rm -f conftest.file +]) + +# Copyright (C) 2009-2021 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_SILENT_RULES([DEFAULT]) +# -------------------------- +# Enable less verbose build rules; with the default set to DEFAULT +# ("yes" being less verbose, "no" or empty being verbose). +AC_DEFUN([AM_SILENT_RULES], +[AC_ARG_ENABLE([silent-rules], [dnl +AS_HELP_STRING( + [--enable-silent-rules], + [less verbose build output (undo: "make V=1")]) +AS_HELP_STRING( + [--disable-silent-rules], + [verbose build output (undo: "make V=0")])dnl +]) +case $enable_silent_rules in @%:@ ((( + yes) AM_DEFAULT_VERBOSITY=0;; + no) AM_DEFAULT_VERBOSITY=1;; + *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);; +esac +dnl +dnl A few 'make' implementations (e.g., NonStop OS and NextStep) +dnl do not support nested variable expansions. +dnl See automake bug#9928 and bug#10237. +am_make=${MAKE-make} +AC_CACHE_CHECK([whether $am_make supports nested variables], + [am_cv_make_support_nested_variables], + [if AS_ECHO([['TRUE=$(BAR$(V)) +BAR0=false +BAR1=true +V=1 +am__doit: + @$(TRUE) +.PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then + am_cv_make_support_nested_variables=yes +else + am_cv_make_support_nested_variables=no +fi]) +if test $am_cv_make_support_nested_variables = yes; then + dnl Using '$V' instead of '$(V)' breaks IRIX make. + AM_V='$(V)' + AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' +else + AM_V=$AM_DEFAULT_VERBOSITY + AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY +fi +AC_SUBST([AM_V])dnl +AM_SUBST_NOTMAKE([AM_V])dnl +AC_SUBST([AM_DEFAULT_V])dnl +AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl +AC_SUBST([AM_DEFAULT_VERBOSITY])dnl +AM_BACKSLASH='\' +AC_SUBST([AM_BACKSLASH])dnl +_AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl +]) + +# Copyright (C) 2001-2021 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_PROG_INSTALL_STRIP +# --------------------- +# One issue with vendor 'install' (even GNU) is that you can't +# specify the program used to strip binaries. This is especially +# annoying in cross-compiling environments, where the build's strip +# is unlikely to handle the host's binaries. +# Fortunately install-sh will honor a STRIPPROG variable, so we +# always use install-sh in "make install-strip", and initialize +# STRIPPROG with the value of the STRIP variable (set by the user). +AC_DEFUN([AM_PROG_INSTALL_STRIP], +[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +# Installed binaries are usually stripped using 'strip' when the user +# run "make install-strip". However 'strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the 'STRIP' environment variable to overrule this program. +dnl Don't test for $cross_compiling = yes, because it might be 'maybe'. +if test "$cross_compiling" != no; then + AC_CHECK_TOOL([STRIP], [strip], :) +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" +AC_SUBST([INSTALL_STRIP_PROGRAM])]) + +# Copyright (C) 2006-2021 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_SUBST_NOTMAKE(VARIABLE) +# --------------------------- +# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. +# This macro is traced by Automake. +AC_DEFUN([_AM_SUBST_NOTMAKE]) + +# AM_SUBST_NOTMAKE(VARIABLE) +# -------------------------- +# Public sister of _AM_SUBST_NOTMAKE. +AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) + +# Check how to create a tarball. -*- Autoconf -*- + +# Copyright (C) 2004-2021 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_PROG_TAR(FORMAT) +# -------------------- +# Check how to create a tarball in format FORMAT. +# FORMAT should be one of 'v7', 'ustar', or 'pax'. +# +# Substitute a variable $(am__tar) that is a command +# writing to stdout a FORMAT-tarball containing the directory +# $tardir. +# tardir=directory && $(am__tar) > result.tar +# +# Substitute a variable $(am__untar) that extract such +# a tarball read from stdin. +# $(am__untar) < result.tar +# +AC_DEFUN([_AM_PROG_TAR], +[# Always define AMTAR for backward compatibility. Yes, it's still used +# in the wild :-( We should find a proper way to deprecate it ... +AC_SUBST([AMTAR], ['$${TAR-tar}']) + +# We'll loop over all known methods to create a tar archive until one works. +_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' + +m4_if([$1], [v7], + [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], + + [m4_case([$1], + [ustar], + [# The POSIX 1988 'ustar' format is defined with fixed-size fields. + # There is notably a 21 bits limit for the UID and the GID. In fact, + # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343 + # and bug#13588). + am_max_uid=2097151 # 2^21 - 1 + am_max_gid=$am_max_uid + # The $UID and $GID variables are not portable, so we need to resort + # to the POSIX-mandated id(1) utility. Errors in the 'id' calls + # below are definitely unexpected, so allow the users to see them + # (that is, avoid stderr redirection). + am_uid=`id -u || echo unknown` + am_gid=`id -g || echo unknown` + AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format]) + if test $am_uid -le $am_max_uid; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + _am_tools=none + fi + AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format]) + if test $am_gid -le $am_max_gid; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + _am_tools=none + fi], + + [pax], + [], + + [m4_fatal([Unknown tar format])]) + + AC_MSG_CHECKING([how to create a $1 tar archive]) + + # Go ahead even if we have the value already cached. We do so because we + # need to set the values for the 'am__tar' and 'am__untar' variables. + _am_tools=${am_cv_prog_tar_$1-$_am_tools} + + for _am_tool in $_am_tools; do + case $_am_tool in + gnutar) + for _am_tar in tar gnutar gtar; do + AM_RUN_LOG([$_am_tar --version]) && break + done + am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' + am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' + am__untar="$_am_tar -xf -" + ;; + plaintar) + # Must skip GNU tar: if it does not support --format= it doesn't create + # ustar tarball either. + (tar --version) >/dev/null 2>&1 && continue + am__tar='tar chf - "$$tardir"' + am__tar_='tar chf - "$tardir"' + am__untar='tar xf -' + ;; + pax) + am__tar='pax -L -x $1 -w "$$tardir"' + am__tar_='pax -L -x $1 -w "$tardir"' + am__untar='pax -r' + ;; + cpio) + am__tar='find "$$tardir" -print | cpio -o -H $1 -L' + am__tar_='find "$tardir" -print | cpio -o -H $1 -L' + am__untar='cpio -i -H $1 -d' + ;; + none) + am__tar=false + am__tar_=false + am__untar=false + ;; + esac + + # If the value was cached, stop now. We just wanted to have am__tar + # and am__untar set. + test -n "${am_cv_prog_tar_$1}" && break + + # tar/untar a dummy directory, and stop if the command works. + rm -rf conftest.dir + mkdir conftest.dir + echo GrepMe > conftest.dir/file + AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) + rm -rf conftest.dir + if test -s conftest.tar; then + AM_RUN_LOG([$am__untar /dev/null 2>&1 && break + fi + done + rm -rf conftest.dir + + AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) + AC_MSG_RESULT([$am_cv_prog_tar_$1])]) + +AC_SUBST([am__tar]) +AC_SUBST([am__untar]) +]) # _AM_PROG_TAR + +m4_include([m4/ax_c___attribute__.m4]) +m4_include([m4/ax_cc_maxopt.m4]) +m4_include([m4/ax_check_compile_flag.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_cxx_compile_stdcxx_11_no_override.m4]) +m4_include([m4/ax_cxx_compile_stdcxx_17.m4]) +m4_include([m4/ax_detect_git_head.m4]) +m4_include([m4/ax_detect_gmp.m4]) +m4_include([m4/ax_detect_imath.m4]) +m4_include([m4/ax_gcc_archflag.m4]) +m4_include([m4/ax_gcc_warn_unused_result.m4]) +m4_include([m4/ax_gcc_x86_cpuid.m4]) +m4_include([m4/ax_prog_cc_for_build.m4]) +m4_include([m4/ax_set_warning_flags.m4]) +m4_include([m4/ax_submodule.m4]) +m4_include([m4/libtool.m4]) +m4_include([m4/ltoptions.m4]) +m4_include([m4/ltsugar.m4]) +m4_include([m4/ltversion.m4]) +m4_include([m4/lt~obsolete.m4]) diff --git a/external/mit/isl/dist/all.h b/external/mit/isl/dist/all.h new file mode 100644 index 000000000000..73b80959f4b5 --- /dev/null +++ b/external/mit/isl/dist/all.h @@ -0,0 +1,15 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include diff --git a/external/mit/isl/dist/basis_reduction_tab.c b/external/mit/isl/dist/basis_reduction_tab.c new file mode 100644 index 000000000000..b42f677312ba --- /dev/null +++ b/external/mit/isl/dist/basis_reduction_tab.c @@ -0,0 +1,293 @@ +/* + * 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 + */ + +#include +#include +#include +#include "isl_tab.h" +#include +#include + +struct tab_lp { + struct isl_ctx *ctx; + struct isl_vec *row; + struct isl_tab *tab; + struct isl_tab_undo **stack; + isl_int *obj; + isl_int opt; + isl_int opt_denom; + isl_int tmp; + isl_int tmp2; + int neq; + unsigned dim; + /* number of constraints in initial product tableau */ + int con_offset; + /* objective function has fixed or no integer value */ + int is_fixed; +}; + +#ifdef USE_GMP_FOR_MP +#define GBR_type mpq_t +#define GBR_init(v) mpq_init(v) +#define GBR_clear(v) mpq_clear(v) +#define GBR_set(a,b) mpq_set(a,b) +#define GBR_set_ui(a,b) mpq_set_ui(a,b,1) +#define GBR_mul(a,b,c) mpq_mul(a,b,c) +#define GBR_lt(a,b) (mpq_cmp(a,b) < 0) +#define GBR_is_zero(a) (mpq_sgn(a) == 0) +#define GBR_numref(a) mpq_numref(a) +#define GBR_denref(a) mpq_denref(a) +#define GBR_floor(a,b) mpz_fdiv_q(a,GBR_numref(b),GBR_denref(b)) +#define GBR_ceil(a,b) mpz_cdiv_q(a,GBR_numref(b),GBR_denref(b)) +#define GBR_set_num_neg(a, b) mpz_neg(GBR_numref(*a), b); +#define GBR_set_den(a, b) mpz_set(GBR_denref(*a), b); +#endif /* USE_GMP_FOR_MP */ + +#ifdef USE_IMATH_FOR_MP +#include + +#define GBR_type mp_rat +#define GBR_init(v) v = mp_rat_alloc() +#define GBR_clear(v) mp_rat_free(v) +#define GBR_set(a,b) mp_rat_copy(b,a) +#define GBR_set_ui(a,b) mp_rat_set_uvalue(a,b,1) +#define GBR_mul(a,b,c) mp_rat_mul(b,c,a) +#define GBR_lt(a,b) (mp_rat_compare(a,b) < 0) +#define GBR_is_zero(a) (mp_rat_compare_zero(a) == 0) +#ifdef USE_SMALL_INT_OPT +#define GBR_numref(a) isl_sioimath_encode_big(mp_rat_numer_ref(a)) +#define GBR_denref(a) isl_sioimath_encode_big(mp_rat_denom_ref(a)) +#define GBR_floor(a, b) isl_sioimath_fdiv_q((a), GBR_numref(b), GBR_denref(b)) +#define GBR_ceil(a, b) isl_sioimath_cdiv_q((a), GBR_numref(b), GBR_denref(b)) +#define GBR_set_num_neg(a, b) \ + do { \ + isl_sioimath_scratchspace_t scratch; \ + impz_neg(mp_rat_numer_ref(*a), \ + isl_sioimath_bigarg_src(*b, &scratch));\ + } while (0) +#define GBR_set_den(a, b) \ + do { \ + isl_sioimath_scratchspace_t scratch; \ + impz_set(mp_rat_denom_ref(*a), \ + isl_sioimath_bigarg_src(*b, &scratch));\ + } while (0) +#else /* USE_SMALL_INT_OPT */ +#define GBR_numref(a) mp_rat_numer_ref(a) +#define GBR_denref(a) mp_rat_denom_ref(a) +#define GBR_floor(a,b) impz_fdiv_q(a,GBR_numref(b),GBR_denref(b)) +#define GBR_ceil(a,b) impz_cdiv_q(a,GBR_numref(b),GBR_denref(b)) +#define GBR_set_num_neg(a, b) impz_neg(GBR_numref(*a), b) +#define GBR_set_den(a, b) impz_set(GBR_denref(*a), b) +#endif /* USE_SMALL_INT_OPT */ +#endif /* USE_IMATH_FOR_MP */ + +static struct tab_lp *init_lp(struct isl_tab *tab); +static void set_lp_obj(struct tab_lp *lp, isl_int *row, int dim); +static int solve_lp(struct tab_lp *lp); +static void get_obj_val(struct tab_lp* lp, GBR_type *F); +static void delete_lp(struct tab_lp *lp); +static int add_lp_row(struct tab_lp *lp, isl_int *row, int dim); +static void get_alpha(struct tab_lp* lp, int row, GBR_type *alpha); +static int del_lp_row(struct tab_lp *lp) WARN_UNUSED; +static int cut_lp_to_hyperplane(struct tab_lp *lp, isl_int *row); + +#define GBR_LP struct tab_lp +#define GBR_lp_init(P) init_lp(P) +#define GBR_lp_set_obj(lp, obj, dim) set_lp_obj(lp, obj, dim) +#define GBR_lp_solve(lp) solve_lp(lp) +#define GBR_lp_get_obj_val(lp, F) get_obj_val(lp, F) +#define GBR_lp_delete(lp) delete_lp(lp) +#define GBR_lp_next_row(lp) lp->neq +#define GBR_lp_add_row(lp, row, dim) add_lp_row(lp, row, dim) +#define GBR_lp_get_alpha(lp, row, alpha) get_alpha(lp, row, alpha) +#define GBR_lp_del_row(lp) del_lp_row(lp) +#define GBR_lp_is_fixed(lp) (lp)->is_fixed +#define GBR_lp_cut(lp, obj) cut_lp_to_hyperplane(lp, obj) +#include "basis_reduction_templ.c" + +/* Set up a tableau for the Cartesian product of bset with itself. + * This could be optimized by first setting up a tableau for bset + * and then performing the Cartesian product on the tableau. + */ +static struct isl_tab *gbr_tab(struct isl_tab *tab, struct isl_vec *row) +{ + unsigned dim; + struct isl_tab *prod; + + if (!tab || !row) + return NULL; + + dim = tab->n_var; + prod = isl_tab_product(tab, tab); + if (isl_tab_extend_cons(prod, 3 * dim + 1) < 0) { + isl_tab_free(prod); + return NULL; + } + return prod; +} + +static struct tab_lp *init_lp(struct isl_tab *tab) +{ + struct tab_lp *lp = NULL; + + if (!tab) + return NULL; + + lp = isl_calloc_type(tab->mat->ctx, struct tab_lp); + if (!lp) + return NULL; + + isl_int_init(lp->opt); + isl_int_init(lp->opt_denom); + isl_int_init(lp->tmp); + isl_int_init(lp->tmp2); + + lp->dim = tab->n_var; + + lp->ctx = tab->mat->ctx; + isl_ctx_ref(lp->ctx); + + lp->stack = isl_alloc_array(lp->ctx, struct isl_tab_undo *, lp->dim); + + lp->row = isl_vec_alloc(lp->ctx, 1 + 2 * lp->dim); + if (!lp->row) + goto error; + lp->tab = gbr_tab(tab, lp->row); + if (!lp->tab) + goto error; + lp->con_offset = lp->tab->n_con; + lp->obj = NULL; + lp->neq = 0; + + return lp; +error: + delete_lp(lp); + return NULL; +} + +static void set_lp_obj(struct tab_lp *lp, isl_int *row, int dim) +{ + lp->obj = row; +} + +static int solve_lp(struct tab_lp *lp) +{ + enum isl_lp_result res; + unsigned flags = 0; + + lp->is_fixed = 0; + + isl_int_set_si(lp->row->el[0], 0); + isl_seq_cpy(lp->row->el + 1, lp->obj, lp->dim); + isl_seq_neg(lp->row->el + 1 + lp->dim, lp->obj, lp->dim); + if (lp->neq) + flags = ISL_TAB_SAVE_DUAL; + res = isl_tab_min(lp->tab, lp->row->el, lp->ctx->one, + &lp->opt, &lp->opt_denom, flags); + isl_int_mul_ui(lp->opt_denom, lp->opt_denom, 2); + if (isl_int_abs_lt(lp->opt, lp->opt_denom)) { + struct isl_vec *sample = isl_tab_get_sample_value(lp->tab); + if (!sample) + return -1; + isl_seq_inner_product(lp->obj, sample->el + 1, lp->dim, &lp->tmp); + isl_seq_inner_product(lp->obj, sample->el + 1 + lp->dim, lp->dim, &lp->tmp2); + isl_int_cdiv_q(lp->tmp, lp->tmp, sample->el[0]); + isl_int_fdiv_q(lp->tmp2, lp->tmp2, sample->el[0]); + if (isl_int_ge(lp->tmp, lp->tmp2)) + lp->is_fixed = 1; + isl_vec_free(sample); + } + isl_int_divexact_ui(lp->opt_denom, lp->opt_denom, 2); + if (res < 0) + return -1; + if (res != isl_lp_ok) + isl_die(lp->ctx, isl_error_internal, + "unexpected missing (bounded) solution", return -1); + return 0; +} + +/* The current objective function has a fixed (or no) integer value. + * Cut the tableau to the hyperplane that fixes this value in + * both halves of the tableau. + * Return 1 if the resulting tableau is empty. + */ +static int cut_lp_to_hyperplane(struct tab_lp *lp, isl_int *row) +{ + enum isl_lp_result res; + + isl_int_set_si(lp->row->el[0], 0); + isl_seq_cpy(lp->row->el + 1, row, lp->dim); + isl_seq_clr(lp->row->el + 1 + lp->dim, lp->dim); + res = isl_tab_min(lp->tab, lp->row->el, lp->ctx->one, + &lp->tmp, NULL, 0); + if (res != isl_lp_ok) + return -1; + + isl_int_neg(lp->row->el[0], lp->tmp); + if (isl_tab_add_eq(lp->tab, lp->row->el) < 0) + return -1; + + isl_seq_cpy(lp->row->el + 1 + lp->dim, row, lp->dim); + isl_seq_clr(lp->row->el + 1, lp->dim); + if (isl_tab_add_eq(lp->tab, lp->row->el) < 0) + return -1; + + lp->con_offset += 2; + + return lp->tab->empty; +} + +static void get_obj_val(struct tab_lp* lp, GBR_type *F) +{ + GBR_set_num_neg(F, lp->opt); + GBR_set_den(F, lp->opt_denom); +} + +static void delete_lp(struct tab_lp *lp) +{ + if (!lp) + return; + + isl_int_clear(lp->opt); + isl_int_clear(lp->opt_denom); + isl_int_clear(lp->tmp); + isl_int_clear(lp->tmp2); + isl_vec_free(lp->row); + free(lp->stack); + isl_tab_free(lp->tab); + isl_ctx_deref(lp->ctx); + free(lp); +} + +static int add_lp_row(struct tab_lp *lp, isl_int *row, int dim) +{ + lp->stack[lp->neq] = isl_tab_snap(lp->tab); + + isl_int_set_si(lp->row->el[0], 0); + isl_seq_cpy(lp->row->el + 1, row, lp->dim); + isl_seq_neg(lp->row->el + 1 + lp->dim, row, lp->dim); + + if (isl_tab_add_valid_eq(lp->tab, lp->row->el) < 0) + return -1; + + return lp->neq++; +} + +static void get_alpha(struct tab_lp* lp, int row, GBR_type *alpha) +{ + row += lp->con_offset; + GBR_set_num_neg(alpha, lp->tab->dual->el[1 + row]); + GBR_set_den(alpha, lp->tab->dual->el[0]); +} + +static int del_lp_row(struct tab_lp *lp) +{ + lp->neq--; + return isl_tab_rollback(lp->tab, lp->stack[lp->neq]); +} diff --git a/external/mit/isl/dist/basis_reduction_templ.c b/external/mit/isl/dist/basis_reduction_templ.c new file mode 100644 index 000000000000..290da7dc29d7 --- /dev/null +++ b/external/mit/isl/dist/basis_reduction_templ.c @@ -0,0 +1,355 @@ +/* + * Copyright 2006-2007 Universiteit Leiden + * Copyright 2008-2009 Katholieke Universiteit Leuven + * + * Use of this software is governed by the MIT license + * + * Written by Sven Verdoolaege, Leiden Institute of Advanced Computer Science, + * Universiteit Leiden, Niels Bohrweg 1, 2333 CA Leiden, The Netherlands + * and K.U.Leuven, Departement Computerwetenschappen, Celestijnenlaan 200A, + * B-3001 Leuven, Belgium + */ + +#include +#include +#include +#include +#include +#include "isl_basis_reduction.h" + +static void save_alpha(GBR_LP *lp, int first, int n, GBR_type *alpha) +{ + int i; + + for (i = 0; i < n; ++i) + GBR_lp_get_alpha(lp, first + i, &alpha[i]); +} + +/* Compute a reduced basis for the set represented by the tableau "tab". + * tab->basis, which must be initialized by the calling function to an affine + * unimodular basis, is updated to reflect the reduced basis. + * The first tab->n_zero rows of the basis (ignoring the constant row) + * are assumed to correspond to equalities and are left untouched. + * tab->n_zero is updated to reflect any additional equalities that + * have been detected in the first rows of the new basis. + * The final tab->n_unbounded rows of the basis are assumed to correspond + * to unbounded directions and are also left untouched. + * In particular this means that the remaining rows are assumed to + * correspond to bounded directions. + * + * This function implements the algorithm described in + * "An Implementation of the Generalized Basis Reduction Algorithm + * for Integer Programming" of Cook el al. to compute a reduced basis. + * We use \epsilon = 1/4. + * + * If ctx->opt->gbr_only_first is set, the user is only interested + * in the first direction. In this case we stop the basis reduction when + * the width in the first direction becomes smaller than 2. + */ +struct isl_tab *isl_tab_compute_reduced_basis(struct isl_tab *tab) +{ + unsigned dim; + struct isl_ctx *ctx; + struct isl_mat *B; + int i; + GBR_LP *lp = NULL; + GBR_type F_old, alpha, F_new; + int row; + isl_int tmp; + struct isl_vec *b_tmp; + GBR_type *F = NULL; + GBR_type *alpha_buffer[2] = { NULL, NULL }; + GBR_type *alpha_saved; + GBR_type F_saved; + int use_saved = 0; + isl_int mu[2]; + GBR_type mu_F[2]; + GBR_type two; + GBR_type one; + int empty = 0; + int fixed = 0; + int fixed_saved = 0; + int mu_fixed[2]; + int n_bounded; + int gbr_only_first; + + if (!tab) + return NULL; + + if (tab->empty) + return tab; + + ctx = tab->mat->ctx; + gbr_only_first = ctx->opt->gbr_only_first; + dim = tab->n_var; + B = tab->basis; + if (!B) + return tab; + + n_bounded = dim - tab->n_unbounded; + if (n_bounded <= tab->n_zero + 1) + return tab; + + isl_int_init(tmp); + isl_int_init(mu[0]); + isl_int_init(mu[1]); + + GBR_init(alpha); + GBR_init(F_old); + GBR_init(F_new); + GBR_init(F_saved); + GBR_init(mu_F[0]); + GBR_init(mu_F[1]); + GBR_init(two); + GBR_init(one); + + b_tmp = isl_vec_alloc(ctx, dim); + if (!b_tmp) + goto error; + + F = isl_alloc_array(ctx, GBR_type, n_bounded); + alpha_buffer[0] = isl_alloc_array(ctx, GBR_type, n_bounded); + alpha_buffer[1] = isl_alloc_array(ctx, GBR_type, n_bounded); + alpha_saved = alpha_buffer[0]; + + if (!F || !alpha_buffer[0] || !alpha_buffer[1]) + goto error; + + for (i = 0; i < n_bounded; ++i) { + GBR_init(F[i]); + GBR_init(alpha_buffer[0][i]); + GBR_init(alpha_buffer[1][i]); + } + + GBR_set_ui(two, 2); + GBR_set_ui(one, 1); + + lp = GBR_lp_init(tab); + if (!lp) + goto error; + + i = tab->n_zero; + + GBR_lp_set_obj(lp, B->row[1+i]+1, dim); + ctx->stats->gbr_solved_lps++; + if (GBR_lp_solve(lp) < 0) + goto error; + GBR_lp_get_obj_val(lp, &F[i]); + + if (GBR_lt(F[i], one)) { + if (!GBR_is_zero(F[i])) { + empty = GBR_lp_cut(lp, B->row[1+i]+1); + if (empty) + goto done; + GBR_set_ui(F[i], 0); + } + tab->n_zero++; + } + + do { + if (i+1 == tab->n_zero) { + GBR_lp_set_obj(lp, B->row[1+i+1]+1, dim); + ctx->stats->gbr_solved_lps++; + if (GBR_lp_solve(lp) < 0) + goto error; + GBR_lp_get_obj_val(lp, &F_new); + fixed = GBR_lp_is_fixed(lp); + GBR_set_ui(alpha, 0); + } else if (use_saved) { + row = GBR_lp_next_row(lp); + GBR_set(F_new, F_saved); + fixed = fixed_saved; + GBR_set(alpha, alpha_saved[i]); + } else { + row = GBR_lp_add_row(lp, B->row[1+i]+1, dim); + GBR_lp_set_obj(lp, B->row[1+i+1]+1, dim); + ctx->stats->gbr_solved_lps++; + if (GBR_lp_solve(lp) < 0) + goto error; + GBR_lp_get_obj_val(lp, &F_new); + fixed = GBR_lp_is_fixed(lp); + + GBR_lp_get_alpha(lp, row, &alpha); + + if (i > 0) + save_alpha(lp, row-i, i, alpha_saved); + + if (GBR_lp_del_row(lp) < 0) + goto error; + } + GBR_set(F[i+1], F_new); + + GBR_floor(mu[0], alpha); + GBR_ceil(mu[1], alpha); + + if (isl_int_eq(mu[0], mu[1])) + isl_int_set(tmp, mu[0]); + else { + int j; + + for (j = 0; j <= 1; ++j) { + isl_int_set(tmp, mu[j]); + isl_seq_combine(b_tmp->el, + ctx->one, B->row[1+i+1]+1, + tmp, B->row[1+i]+1, dim); + GBR_lp_set_obj(lp, b_tmp->el, dim); + ctx->stats->gbr_solved_lps++; + if (GBR_lp_solve(lp) < 0) + goto error; + GBR_lp_get_obj_val(lp, &mu_F[j]); + mu_fixed[j] = GBR_lp_is_fixed(lp); + if (i > 0) + save_alpha(lp, row-i, i, alpha_buffer[j]); + } + + if (GBR_lt(mu_F[0], mu_F[1])) + j = 0; + else + j = 1; + + isl_int_set(tmp, mu[j]); + GBR_set(F_new, mu_F[j]); + fixed = mu_fixed[j]; + alpha_saved = alpha_buffer[j]; + } + isl_seq_combine(B->row[1+i+1]+1, ctx->one, B->row[1+i+1]+1, + tmp, B->row[1+i]+1, dim); + + if (i+1 == tab->n_zero && fixed) { + if (!GBR_is_zero(F[i+1])) { + empty = GBR_lp_cut(lp, B->row[1+i+1]+1); + if (empty) + goto done; + GBR_set_ui(F[i+1], 0); + } + tab->n_zero++; + } + + GBR_set(F_old, F[i]); + + use_saved = 0; + /* mu_F[0] = 4 * F_new; mu_F[1] = 3 * F_old */ + GBR_set_ui(mu_F[0], 4); + GBR_mul(mu_F[0], mu_F[0], F_new); + GBR_set_ui(mu_F[1], 3); + GBR_mul(mu_F[1], mu_F[1], F_old); + if (GBR_lt(mu_F[0], mu_F[1])) { + B = isl_mat_swap_rows(B, 1 + i, 1 + i + 1); + if (i > tab->n_zero) { + use_saved = 1; + GBR_set(F_saved, F_new); + fixed_saved = fixed; + if (GBR_lp_del_row(lp) < 0) + goto error; + --i; + } else { + GBR_set(F[tab->n_zero], F_new); + if (gbr_only_first && GBR_lt(F[tab->n_zero], two)) + break; + + if (fixed) { + if (!GBR_is_zero(F[tab->n_zero])) { + empty = GBR_lp_cut(lp, B->row[1+tab->n_zero]+1); + if (empty) + goto done; + GBR_set_ui(F[tab->n_zero], 0); + } + tab->n_zero++; + } + } + } else { + GBR_lp_add_row(lp, B->row[1+i]+1, dim); + ++i; + } + } while (i < n_bounded - 1); + + if (0) { +done: + if (empty < 0) { +error: + isl_mat_free(B); + B = NULL; + } + } + + GBR_lp_delete(lp); + + if (alpha_buffer[1]) + for (i = 0; i < n_bounded; ++i) { + GBR_clear(F[i]); + GBR_clear(alpha_buffer[0][i]); + GBR_clear(alpha_buffer[1][i]); + } + free(F); + free(alpha_buffer[0]); + free(alpha_buffer[1]); + + isl_vec_free(b_tmp); + + GBR_clear(alpha); + GBR_clear(F_old); + GBR_clear(F_new); + GBR_clear(F_saved); + GBR_clear(mu_F[0]); + GBR_clear(mu_F[1]); + GBR_clear(two); + GBR_clear(one); + + isl_int_clear(tmp); + isl_int_clear(mu[0]); + isl_int_clear(mu[1]); + + tab->basis = B; + + return tab; +} + +/* Compute an affine form of a reduced basis of the given basic + * non-parametric set, which is assumed to be bounded and not + * include any integer divisions. + * The first column and the first row correspond to the constant term. + * + * If the input contains any equalities, we first create an initial + * basis with the equalities first. Otherwise, we start off with + * the identity matrix. + */ +__isl_give isl_mat *isl_basic_set_reduced_basis(__isl_keep isl_basic_set *bset) +{ + struct isl_mat *basis; + struct isl_tab *tab; + + if (isl_basic_set_check_no_locals(bset) < 0 || + isl_basic_set_check_no_params(bset) < 0) + return NULL; + + tab = isl_tab_from_basic_set(bset, 0); + if (!tab) + return NULL; + + if (bset->n_eq == 0) + tab->basis = isl_mat_identity(bset->ctx, 1 + tab->n_var); + else { + isl_mat *eq; + isl_size nvar = isl_basic_set_dim(bset, isl_dim_all); + if (nvar < 0) + goto error; + eq = isl_mat_sub_alloc6(bset->ctx, bset->eq, 0, bset->n_eq, + 1, nvar); + eq = isl_mat_left_hermite(eq, 0, NULL, &tab->basis); + tab->basis = isl_mat_lin_to_aff(tab->basis); + tab->n_zero = bset->n_eq; + isl_mat_free(eq); + } + tab = isl_tab_compute_reduced_basis(tab); + if (!tab) + return NULL; + + basis = isl_mat_copy(tab->basis); + + isl_tab_free(tab); + + return basis; +error: + isl_tab_free(tab); + return NULL; +} diff --git a/external/mit/isl/dist/bound.c b/external/mit/isl/dist/bound.c new file mode 100644 index 000000000000..ec79b3be506f --- /dev/null +++ b/external/mit/isl/dist/bound.c @@ -0,0 +1,289 @@ +#include +#include +#include +#include +#include +#include +#include + +struct bound_options { + struct isl_options *isl; + unsigned verify; + int print_all; + int continue_on_error; +}; + +ISL_ARGS_START(struct bound_options, bound_options_args) +ISL_ARG_CHILD(struct bound_options, isl, "isl", &isl_options_args, + "isl options") +ISL_ARG_BOOL(struct bound_options, verify, 'T', "verify", 0, NULL) +ISL_ARG_BOOL(struct bound_options, print_all, 'A', "print-all", 0, NULL) +ISL_ARG_BOOL(struct bound_options, continue_on_error, '\0', "continue-on-error", 0, NULL) +ISL_ARGS_END + +ISL_ARG_DEF(bound_options, struct bound_options, bound_options_args) + +static __isl_give isl_set *set_bounds(__isl_take isl_set *set) +{ + isl_size nparam; + int i, r; + isl_point *pt, *pt2; + isl_set *box; + + nparam = isl_set_dim(set, isl_dim_param); + if (nparam < 0) + return isl_set_free(set); + r = nparam >= 8 ? 5 : nparam >= 5 ? 15 : 50; + + pt = isl_set_sample_point(isl_set_copy(set)); + pt2 = isl_point_copy(pt); + + for (i = 0; i < nparam; ++i) { + pt = isl_point_add_ui(pt, isl_dim_param, i, r); + pt2 = isl_point_sub_ui(pt2, isl_dim_param, i, r); + } + + box = isl_set_box_from_points(pt, pt2); + + return isl_set_intersect(set, box); +} + +struct verify_point_bound { + struct bound_options *options; + int stride; + int n; + int exact; + int error; + + isl_pw_qpolynomial_fold *pwf; + isl_pw_qpolynomial_fold *bound; +}; + +static isl_stat verify_point(__isl_take isl_point *pnt, void *user) +{ + int i; + isl_size nparam; + struct verify_point_bound *vpb = (struct verify_point_bound *) user; + isl_val *v; + isl_ctx *ctx; + isl_pw_qpolynomial_fold *pwf; + isl_val *bound = NULL; + isl_val *opt = NULL; + isl_set *dom = NULL; + isl_printer *p; + const char *minmax; + isl_bool bounded; + int sign; + int ok; + FILE *out = vpb->options->print_all ? stdout : stderr; + + vpb->n--; + + if (1) { + minmax = "ub"; + sign = 1; + } else { + minmax = "lb"; + sign = -1; + } + + ctx = isl_point_get_ctx(pnt); + p = isl_printer_to_file(ctx, out); + + pwf = isl_pw_qpolynomial_fold_copy(vpb->pwf); + + nparam = isl_pw_qpolynomial_fold_dim(pwf, isl_dim_param); + if (nparam < 0) + pwf = isl_pw_qpolynomial_fold_free(pwf); + for (i = 0; i < nparam; ++i) { + 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( + isl_pw_qpolynomial_fold_copy(vpb->bound), + isl_point_copy(pnt)); + + dom = isl_pw_qpolynomial_fold_domain(isl_pw_qpolynomial_fold_copy(pwf)); + bounded = isl_set_is_bounded(dom); + + if (bounded < 0) + goto error; + + if (!bounded) + opt = isl_pw_qpolynomial_fold_eval( + isl_pw_qpolynomial_fold_copy(pwf), + isl_set_sample_point(isl_set_copy(dom))); + else if (sign > 0) + opt = isl_pw_qpolynomial_fold_max(isl_pw_qpolynomial_fold_copy(pwf)); + else + opt = isl_pw_qpolynomial_fold_min(isl_pw_qpolynomial_fold_copy(pwf)); + + if (vpb->exact && bounded) + ok = isl_val_eq(opt, bound); + else if (sign > 0) + ok = isl_val_le(opt, bound); + else + ok = isl_val_le(bound, opt); + if (ok < 0) + goto error; + + if (vpb->options->print_all || !ok) { + p = isl_printer_print_str(p, minmax); + p = isl_printer_print_str(p, "("); + for (i = 0; i < nparam; ++i) { + if (i) + p = isl_printer_print_str(p, ", "); + 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); + p = isl_printer_print_str(p, ", "); + p = isl_printer_print_str(p, bounded ? "opt" : "sample"); + p = isl_printer_print_str(p, " = "); + p = isl_printer_print_val(p, opt); + if (ok) + p = isl_printer_print_str(p, ". OK"); + else + p = isl_printer_print_str(p, ". NOT OK"); + p = isl_printer_end_line(p); + } else if ((vpb->n % vpb->stride) == 0) { + p = isl_printer_print_str(p, "o"); + p = isl_printer_flush(p); + } + + if (0) { +error: + ok = 0; + } + + isl_pw_qpolynomial_fold_free(pwf); + isl_val_free(bound); + isl_val_free(opt); + isl_point_free(pnt); + isl_set_free(dom); + + isl_printer_free(p); + + if (!ok) + vpb->error = 1; + + if (vpb->options->continue_on_error) + ok = 1; + + return (vpb->n >= 1 && ok) ? isl_stat_ok : isl_stat_error; +} + +static int check_solution(__isl_take isl_pw_qpolynomial_fold *pwf, + __isl_take isl_pw_qpolynomial_fold *bound, int exact, + struct bound_options *options) +{ + struct verify_point_bound vpb; + isl_int count, max; + isl_set *dom; + isl_set *context; + int i, r, n; + + dom = isl_pw_qpolynomial_fold_domain(isl_pw_qpolynomial_fold_copy(pwf)); + context = isl_set_params(isl_set_copy(dom)); + context = isl_set_remove_divs(context); + context = set_bounds(context); + + isl_int_init(count); + isl_int_init(max); + + isl_int_set_si(max, 200); + r = isl_set_count_upto(context, max, &count); + assert(r >= 0); + n = isl_int_get_si(count); + + isl_int_clear(max); + isl_int_clear(count); + + vpb.options = options; + vpb.pwf = pwf; + vpb.bound = bound; + vpb.n = n; + vpb.stride = n > 70 ? 1 + (n + 1)/70 : 1; + vpb.error = 0; + vpb.exact = exact; + + if (!options->print_all) { + for (i = 0; i < vpb.n; i += vpb.stride) + printf("."); + printf("\r"); + fflush(stdout); + } + + isl_set_foreach_point(context, verify_point, &vpb); + + isl_set_free(context); + isl_set_free(dom); + isl_pw_qpolynomial_fold_free(pwf); + isl_pw_qpolynomial_fold_free(bound); + + if (!options->print_all) + printf("\n"); + + if (vpb.error) { + fprintf(stderr, "Check failed !\n"); + return -1; + } + + return 0; +} + +int main(int argc, char **argv) +{ + isl_ctx *ctx; + isl_pw_qpolynomial_fold *copy; + isl_pw_qpolynomial_fold *pwf; + isl_stream *s; + struct isl_obj obj; + struct bound_options *options; + isl_bool exact; + int r = 0; + + options = bound_options_new_with_defaults(); + assert(options); + argc = bound_options_parse(options, argc, argv, ISL_ARG_ALL); + + ctx = isl_ctx_alloc_with_options(&bound_options_args, options); + + s = isl_stream_new_file(ctx, stdin); + obj = isl_stream_read_obj(s); + if (obj.type == isl_obj_pw_qpolynomial) + pwf = isl_pw_qpolynomial_fold_from_pw_qpolynomial(isl_fold_max, + obj.v); + else if (obj.type == isl_obj_pw_qpolynomial_fold) + pwf = obj.v; + else { + obj.type->free(obj.v); + isl_die(ctx, isl_error_invalid, "invalid input", goto error); + } + + if (options->verify) + copy = isl_pw_qpolynomial_fold_copy(pwf); + + pwf = isl_pw_qpolynomial_fold_bound(pwf, &exact); + pwf = isl_pw_qpolynomial_fold_coalesce(pwf); + + if (options->verify) { + r = check_solution(copy, pwf, exact, options); + } else { + if (!exact) + printf("# NOT exact\n"); + isl_pw_qpolynomial_fold_print(pwf, stdout, 0); + fprintf(stdout, "\n"); + isl_pw_qpolynomial_fold_free(pwf); + } + +error: + isl_stream_free(s); + + isl_ctx_free(ctx); + + return r; +} diff --git a/external/mit/isl/dist/bound_test.sh.in b/external/mit/isl/dist/bound_test.sh.in new file mode 100755 index 000000000000..8f2f1ffb5ff1 --- /dev/null +++ b/external/mit/isl/dist/bound_test.sh.in @@ -0,0 +1,36 @@ +#!/bin/sh + +EXEEXT=@EXEEXT@ +srcdir=@srcdir@ + +BOUND_TESTS="\ + basicLinear2.pwqp \ + basicLinear.pwqp \ + basicTestParameterPosNeg.pwqp \ + basicTest.pwqp \ + devos.pwqp \ + equality1.pwqp \ + equality2.pwqp \ + equality3.pwqp \ + equality4.pwqp \ + equality5.pwqp \ + faddeev.pwqp \ + linearExample.pwqp \ + neg.pwqp \ + philippe3vars3pars.pwqp \ + philippe3vars.pwqp \ + philippeNeg.pwqp \ + philippePolynomialCoeff1P.pwqp \ + philippePolynomialCoeff.pwqp \ + philippe.pwqp \ + product.pwqp \ + split.pwqp \ + test3Deg3Var.pwqp \ + toplas.pwqp \ + unexpanded.pwqp" + +for i in $BOUND_TESTS; do + echo $i; + ./isl_bound$EXEEXT -T --bound=bernstein < $srcdir/test_inputs/$i || exit + ./isl_bound$EXEEXT -T --bound=range < $srcdir/test_inputs/$i || exit +done diff --git a/external/mit/isl/dist/bset_from_bmap.c b/external/mit/isl/dist/bset_from_bmap.c new file mode 100644 index 000000000000..958508031d9c --- /dev/null +++ b/external/mit/isl/dist/bset_from_bmap.c @@ -0,0 +1,8 @@ +#include + +/* Return the basic set that was treated as the basic map "bmap". + */ +static __isl_give isl_basic_set *bset_from_bmap(__isl_take isl_basic_map *bmap) +{ + return (isl_basic_set *) bmap; +} diff --git a/external/mit/isl/dist/bset_to_bmap.c b/external/mit/isl/dist/bset_to_bmap.c new file mode 100644 index 000000000000..874fe7107c4e --- /dev/null +++ b/external/mit/isl/dist/bset_to_bmap.c @@ -0,0 +1,10 @@ +#include + +/* Treat "bset" as a basic map. + * Internally, isl_basic_set is defined to isl_basic_map, so in practice, + * this function performs a redundant cast. + */ +static __isl_give isl_basic_map *bset_to_bmap(__isl_take isl_basic_set *bset) +{ + return (isl_basic_map *) bset; +} diff --git a/external/mit/isl/dist/cat.c b/external/mit/isl/dist/cat.c new file mode 100644 index 000000000000..c483383d94f8 --- /dev/null +++ b/external/mit/isl/dist/cat.c @@ -0,0 +1,69 @@ +#include +#include +#include +#include +#include + +struct isl_arg_choice cat_format[] = { + {"isl", ISL_FORMAT_ISL}, + {"omega", ISL_FORMAT_OMEGA}, + {"polylib", ISL_FORMAT_POLYLIB}, + {"ext-polylib", ISL_FORMAT_EXT_POLYLIB}, + {"latex", ISL_FORMAT_LATEX}, + {"C", ISL_FORMAT_C}, + {0} +}; + +struct isl_arg_choice cat_yaml_style[] = { + { "block", ISL_YAML_STYLE_BLOCK }, + { "flow", ISL_YAML_STYLE_FLOW }, + { 0 } +}; + +struct cat_options { + struct isl_options *isl; + unsigned format; + unsigned yaml_style; +}; + +ISL_ARGS_START(struct cat_options, cat_options_args) +ISL_ARG_CHILD(struct cat_options, isl, "isl", &isl_options_args, "isl options") +ISL_ARG_CHOICE(struct cat_options, format, 0, "format", \ + cat_format, ISL_FORMAT_ISL, "output format") +ISL_ARG_CHOICE(struct cat_options, yaml_style, 0, "yaml-style", \ + cat_yaml_style, ISL_YAML_STYLE_BLOCK, "output YAML style") +ISL_ARGS_END + +ISL_ARG_DEF(cat_options, struct cat_options, cat_options_args) + +int main(int argc, char **argv) +{ + struct isl_ctx *ctx; + isl_stream *s; + struct isl_obj obj; + struct cat_options *options; + isl_printer *p; + + options = cat_options_new_with_defaults(); + assert(options); + argc = cat_options_parse(options, argc, argv, ISL_ARG_ALL); + + ctx = isl_ctx_alloc_with_options(&cat_options_args, options); + + s = isl_stream_new_file(ctx, stdin); + obj = isl_stream_read_obj(s); + isl_stream_free(s); + + p = isl_printer_to_file(ctx, stdout); + p = isl_printer_set_output_format(p, options->format); + p = isl_printer_set_yaml_style(p, options->yaml_style); + p = obj.type->print(p, obj.v); + p = isl_printer_end_line(p); + isl_printer_free(p); + + obj.type->free(obj.v); + + isl_ctx_free(ctx); + + return 0; +} diff --git a/external/mit/isl/dist/check_parse_fail_test_templ.c b/external/mit/isl/dist/check_parse_fail_test_templ.c new file mode 100644 index 000000000000..6fba085ea381 --- /dev/null +++ b/external/mit/isl/dist/check_parse_fail_test_templ.c @@ -0,0 +1,46 @@ +/* + * Copyright 2021 Cerebras Systems + * + * Use of this software is governed by the MIT license + * + * Written by Sven Verdoolaege, + * Cerebras Systems, 1237 E Arques Ave, Sunnyvale, CA, USA + */ + +#define xCAT(A,B) A ## B +#define CAT(A,B) xCAT(A,B) +#undef TYPE +#define TYPE CAT(isl_,BASE) +#define xFN(TYPE,NAME) TYPE ## _ ## NAME +#define FN(TYPE,NAME) xFN(TYPE,NAME) + +#undef TESTS +#define TESTS CAT(parse_,CAT(BASE,_fail_tests)) + +/* Test parsing of objects of type TYPE + * that are expected to fail. + */ +static isl_stat FN(check,TESTS)(isl_ctx *ctx) +{ + int i, n; + int on_error; + + on_error = isl_options_get_on_error(ctx); + isl_options_set_on_error(ctx, ISL_ON_ERROR_CONTINUE); + n = ARRAY_SIZE(TESTS); + for (i = 0; i < n; ++i) { + TYPE *obj; + + obj = FN(TYPE,read_from_str)(ctx, TESTS[i]); + FN(TYPE,free)(obj); + if (obj) + break; + } + isl_options_set_on_error(ctx, on_error); + if (i < n) + isl_die(ctx, isl_error_unknown, + "parsing not expected to succeed", + return isl_stat_error); + + return isl_stat_ok; +} diff --git a/external/mit/isl/dist/check_reparse_templ.c b/external/mit/isl/dist/check_reparse_templ.c new file mode 100644 index 000000000000..333c44cbc52f --- /dev/null +++ b/external/mit/isl/dist/check_reparse_templ.c @@ -0,0 +1,32 @@ +#define xCAT(A,B) A ## B +#define CAT(A,B) xCAT(A,B) +#undef TYPE +#define TYPE CAT(isl_,BASE) +#define xFN(TYPE,NAME) TYPE ## _ ## NAME +#define FN(TYPE,NAME) xFN(TYPE,NAME) + +/* Check that printing "obj" and parsing the output results + * in the same expression. + */ +static isl_stat FN(check_reparse,BASE)(isl_ctx *ctx, + __isl_take TYPE *obj) +{ + char *str; + isl_bool equal; + TYPE *obj2; + + str = FN(TYPE,to_str)(obj); + obj2 = FN(TYPE,read_from_str)(ctx, str); + free(str); + equal = FN(TYPE,plain_is_equal)(obj, obj2); + FN(TYPE,free)(obj); + FN(TYPE,free)(obj2); + if (equal < 0) + return isl_stat_error; + if (!equal) + isl_die(ctx, isl_error_unknown, + "parsed function not equal to original", + return isl_stat_error); + + return isl_stat_ok; +} diff --git a/external/mit/isl/dist/check_reparse_test_templ.c b/external/mit/isl/dist/check_reparse_test_templ.c new file mode 100644 index 000000000000..0a0740ac688d --- /dev/null +++ b/external/mit/isl/dist/check_reparse_test_templ.c @@ -0,0 +1,29 @@ +#define xCAT(A,B) A ## B +#define CAT(A,B) xCAT(A,B) +#undef TYPE +#define TYPE CAT(isl_,BASE) +#define xFN(TYPE,NAME) TYPE ## _ ## NAME +#define FN(TYPE,NAME) xFN(TYPE,NAME) + +#undef TESTS +#define TESTS CAT(reparse_,CAT(BASE,_tests)) + +/* Test parsing of objects of type TYPE by printing + * the expressions and checking that parsing the output results + * in the same expression. + * Do this for a set of expressions parsed from strings. + */ +static isl_stat FN(check,TESTS)(isl_ctx *ctx) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(TESTS); ++i) { + TYPE *obj; + + obj = FN(TYPE,read_from_str)(ctx, TESTS[i]); + if (FN(check_reparse,BASE)(ctx, obj) < 0) + return isl_stat_error; + } + + return isl_stat_ok; +} diff --git a/external/mit/isl/dist/check_single_reference_templ.c b/external/mit/isl/dist/check_single_reference_templ.c new file mode 100644 index 000000000000..20970b4aa75a --- /dev/null +++ b/external/mit/isl/dist/check_single_reference_templ.c @@ -0,0 +1,19 @@ +#define xFN(TYPE,NAME) TYPE ## _ ## NAME +#define FN(TYPE,NAME) xFN(TYPE,NAME) + +/* Check that "obj" has a single reference. + * That is, check that "obj" can be changed inplace. + */ +isl_stat FN(TYPE,check_single_reference)(__isl_keep TYPE *obj) +{ + isl_bool single; + + single = FN(TYPE,has_single_reference)(obj); + if (single < 0) + return isl_stat_error; + if (!single) + isl_die(FN(TYPE,get_ctx)(obj), isl_error_invalid, + "object should have a single reference", + return isl_stat_error); + return isl_stat_ok; +} diff --git a/external/mit/isl/dist/check_type_range_templ.c b/external/mit/isl/dist/check_type_range_templ.c new file mode 100644 index 000000000000..4e4c1e2fc36f --- /dev/null +++ b/external/mit/isl/dist/check_type_range_templ.c @@ -0,0 +1,20 @@ +#define xFN(TYPE,NAME) TYPE ## _ ## NAME +#define FN(TYPE,NAME) xFN(TYPE,NAME) + +/* Check that there are "n" dimensions of type "type" starting at "first" + * in "obj". + */ +isl_stat FN(TYPE,check_range)(__isl_keep TYPE *obj, + enum isl_dim_type type, unsigned first, unsigned n) +{ + isl_size dim; + + dim = FN(TYPE,dim)(obj, type); + if (dim < 0) + return isl_stat_error; + if (first + n > dim || first + n < first) + isl_die(FN(TYPE,get_ctx)(obj), isl_error_invalid, + "position or range out of bounds", + return isl_stat_error); + return isl_stat_ok; +} diff --git a/external/mit/isl/dist/closure.c b/external/mit/isl/dist/closure.c new file mode 100644 index 000000000000..22235b051ced --- /dev/null +++ b/external/mit/isl/dist/closure.c @@ -0,0 +1,39 @@ +#include +#include +#include + +int main(int argc, char **argv) +{ + struct isl_ctx *ctx; + struct isl_map *map; + struct isl_options *options; + isl_printer *p; + isl_bool exact; + + options = isl_options_new_with_defaults(); + assert(options); + argc = isl_options_parse(options, argc, argv, ISL_ARG_ALL); + + ctx = isl_ctx_alloc_with_options(&isl_options_args, options); + + p = isl_printer_to_file(ctx, stdout); + + map = isl_map_read_from_file(ctx, stdin); + map = isl_map_transitive_closure(map, &exact); + if (!exact) + p = isl_printer_print_str(p, "# NOT exact\n"); + p = isl_printer_print_map(p, map); + p = isl_printer_end_line(p); + map = isl_map_compute_divs(map); + map = isl_map_coalesce(map); + p = isl_printer_print_str(p, "# coalesced\n"); + p = isl_printer_print_map(p, map); + p = isl_printer_end_line(p); + isl_map_free(map); + + isl_printer_free(p); + + isl_ctx_free(ctx); + + return 0; +} diff --git a/external/mit/isl/dist/codegen.c b/external/mit/isl/dist/codegen.c new file mode 100644 index 000000000000..6b001de74786 --- /dev/null +++ b/external/mit/isl/dist/codegen.c @@ -0,0 +1,249 @@ +/* + * Copyright 2012,2014 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 + */ + +/* This program prints an AST that scans the domain elements of + * the domain of a given schedule in the order specified by + * the schedule tree or by their image(s) in the schedule map. + * + * The input consists of either a schedule tree or + * a sequence of three sets/relations. + * - a schedule map + * - a context + * - a relation describing AST generation options + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct options { + struct isl_options *isl; + unsigned atomic; + unsigned separate; +}; + +ISL_ARGS_START(struct options, options_args) +ISL_ARG_CHILD(struct options, isl, "isl", &isl_options_args, "isl options") +ISL_ARG_BOOL(struct options, atomic, 0, "atomic", 0, + "globally set the atomic option") +ISL_ARG_BOOL(struct options, separate, 0, "separate", 0, + "globally set the separate option") +ISL_ARGS_END + +ISL_ARG_DEF(cg_options, struct options, options_args) +ISL_ARG_CTX_DEF(cg_options, struct options, options_args) + +/* Return a universal, 1-dimensional set with the given name. + */ +static __isl_give isl_union_set *universe(isl_ctx *ctx, const char *name) +{ + isl_space *space; + + space = isl_space_set_alloc(ctx, 0, 1); + space = isl_space_set_tuple_name(space, isl_dim_set, name); + return isl_union_set_from_set(isl_set_universe(space)); +} + +/* Set the "name" option for the entire schedule domain. + */ +static __isl_give isl_union_map *set_universe(__isl_take isl_union_map *opt, + __isl_keep isl_union_map *schedule, const char *name) +{ + isl_ctx *ctx; + isl_union_set *domain, *target; + isl_union_map *option; + + ctx = isl_union_map_get_ctx(opt); + + domain = isl_union_map_range(isl_union_map_copy(schedule)); + domain = isl_union_set_universe(domain); + target = universe(ctx, name); + option = isl_union_map_from_domain_and_range(domain, target); + opt = isl_union_map_union(opt, option); + + return opt; +} + +/* Update the build options based on the user-specified options. + * + * If the --separate or --atomic options were specified, then + * we clear any separate or atomic options that may already exist in "opt". + */ +static __isl_give isl_ast_build *set_options(__isl_take isl_ast_build *build, + __isl_take isl_union_map *opt, struct options *options, + __isl_keep isl_union_map *schedule) +{ + if (options->separate || options->atomic) { + isl_ctx *ctx; + isl_union_set *target; + + ctx = isl_union_map_get_ctx(schedule); + + target = universe(ctx, "separate"); + opt = isl_union_map_subtract_range(opt, target); + target = universe(ctx, "atomic"); + opt = isl_union_map_subtract_range(opt, target); + } + + if (options->separate) + opt = set_universe(opt, schedule, "separate"); + if (options->atomic) + opt = set_universe(opt, schedule, "atomic"); + + build = isl_ast_build_set_options(build, opt); + + return build; +} + +/* Construct an AST in case the schedule is specified by a union map. + * + * We read the context and the options from "s" and construct the AST. + */ +static __isl_give isl_ast_node *construct_ast_from_union_map( + __isl_take isl_union_map *schedule, __isl_keep isl_stream *s) +{ + isl_set *context; + isl_union_map *options_map; + isl_ast_build *build; + isl_ast_node *tree; + struct options *options; + + options = isl_ctx_peek_cg_options(isl_stream_get_ctx(s)); + + context = isl_stream_read_set(s); + options_map = isl_stream_read_union_map(s); + + build = isl_ast_build_from_context(context); + build = set_options(build, options_map, options, schedule); + tree = isl_ast_build_node_from_schedule_map(build, schedule); + isl_ast_build_free(build); + + return tree; +} + +/* If "node" is a band node, then replace the AST build options + * by "options". + */ +static __isl_give isl_schedule_node *node_set_options( + __isl_take isl_schedule_node *node, void *user) +{ + enum isl_ast_loop_type *type = user; + int i; + isl_size n; + + if (isl_schedule_node_get_type(node) != isl_schedule_node_band) + return node; + + n = isl_schedule_node_band_n_member(node); + if (n < 0) + return isl_schedule_node_free(node); + for (i = 0; i < n; ++i) + node = isl_schedule_node_band_member_set_ast_loop_type(node, + i, *type); + return node; +} + +/* Replace the AST build options on all band nodes if requested + * by the user. + */ +static __isl_give isl_schedule *schedule_set_options( + __isl_take isl_schedule *schedule, struct options *options) +{ + enum isl_ast_loop_type type; + + if (!options->separate && !options->atomic) + return schedule; + + type = options->separate ? isl_ast_loop_separate : isl_ast_loop_atomic; + schedule = isl_schedule_map_schedule_node_bottom_up(schedule, + &node_set_options, &type); + + return schedule; +} + +/* Construct an AST in case the schedule is specified by a schedule tree. + */ +static __isl_give isl_ast_node *construct_ast_from_schedule( + __isl_take isl_schedule *schedule) +{ + isl_ast_build *build; + isl_ast_node *tree; + struct options *options; + + options = isl_ctx_peek_cg_options(isl_schedule_get_ctx(schedule)); + + build = isl_ast_build_alloc(isl_schedule_get_ctx(schedule)); + schedule = schedule_set_options(schedule, options); + tree = isl_ast_build_node_from_schedule(build, schedule); + isl_ast_build_free(build); + + return tree; +} + +/* Read an object from stdin. + * If it is a (union) map, then assume an input specified by + * schedule map, context and options and construct an AST from + * those elements + * If it is a schedule object, then construct the AST from the schedule. + */ +int main(int argc, char **argv) +{ + isl_ctx *ctx; + isl_stream *s; + isl_ast_node *tree = NULL; + struct options *options; + isl_printer *p; + struct isl_obj obj; + int r = EXIT_SUCCESS; + + options = cg_options_new_with_defaults(); + assert(options); + ctx = isl_ctx_alloc_with_options(&options_args, options); + isl_options_set_ast_build_detect_min_max(ctx, 1); + isl_options_set_ast_print_outermost_block(ctx, 0); + argc = cg_options_parse(options, argc, argv, ISL_ARG_ALL); + + s = isl_stream_new_file(ctx, stdin); + obj = isl_stream_read_obj(s); + if (obj.v == NULL) { + r = EXIT_FAILURE; + } else if (obj.type == isl_obj_map) { + isl_union_map *umap; + + umap = isl_union_map_from_map(obj.v); + tree = construct_ast_from_union_map(umap, s); + } else if (obj.type == isl_obj_union_map) { + tree = construct_ast_from_union_map(obj.v, s); + } else if (obj.type == isl_obj_schedule) { + tree = construct_ast_from_schedule(obj.v); + } else { + obj.type->free(obj.v); + isl_die(ctx, isl_error_invalid, "unknown input", + r = EXIT_FAILURE); + } + isl_stream_free(s); + + p = isl_printer_to_file(ctx, stdout); + p = isl_printer_set_output_format(p, ISL_FORMAT_C); + p = isl_printer_print_ast_node(p, tree); + isl_printer_free(p); + + isl_ast_node_free(tree); + + isl_ctx_free(ctx); + return r; +} diff --git a/external/mit/isl/dist/codegen_test.sh.in b/external/mit/isl/dist/codegen_test.sh.in new file mode 100644 index 000000000000..5b519e71063a --- /dev/null +++ b/external/mit/isl/dist/codegen_test.sh.in @@ -0,0 +1,30 @@ +#!/bin/sh + +EXEEXT=@EXEEXT@ +srcdir=@srcdir@ + +failed=0 + +for i in $srcdir/test_inputs/codegen/*.st \ + $srcdir/test_inputs/codegen/cloog/*.st; do + echo $i; + base=`basename $i .st` + test=test-$base.c + dir=`dirname $i` + ref=$dir/$base.c + (./isl_codegen$EXEEXT < $i > $test && + diff -uw $ref $test && rm $test) || failed=1 +done +for i in $srcdir/test_inputs/codegen/*.in \ + $srcdir/test_inputs/codegen/omega/*.in \ + $srcdir/test_inputs/codegen/pldi2012/*.in; do + echo $i; + base=`basename $i .in` + test=test-$base.c + dir=`dirname $i` + ref=$dir/$base.c + (./isl_codegen$EXEEXT < $i > $test && + diff -uw $ref $test && rm $test) || failed=1 +done + +test $failed -eq 0 || exit diff --git a/external/mit/isl/dist/compile b/external/mit/isl/dist/compile new file mode 100755 index 000000000000..df363c8fbfbc --- /dev/null +++ b/external/mit/isl/dist/compile @@ -0,0 +1,348 @@ +#! /bin/sh +# Wrapper for compilers which do not understand '-c -o'. + +scriptversion=2018-03-07.03; # UTC + +# Copyright (C) 1999-2021 Free Software Foundation, Inc. +# Written by Tom Tromey . +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# This file is maintained in Automake, please report +# bugs to or send patches to +# . + +nl=' +' + +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent tools from complaining about whitespace usage. +IFS=" "" $nl" + +file_conv= + +# func_file_conv build_file lazy +# Convert a $build file to $host form and store it in $file +# Currently only supports Windows hosts. If the determined conversion +# type is listed in (the comma separated) LAZY, no conversion will +# take place. +func_file_conv () +{ + file=$1 + case $file in + / | /[!/]*) # absolute file, and not a UNC file + if test -z "$file_conv"; then + # lazily determine how to convert abs files + case `uname -s` in + MINGW*) + file_conv=mingw + ;; + CYGWIN* | MSYS*) + file_conv=cygwin + ;; + *) + file_conv=wine + ;; + esac + fi + case $file_conv/,$2, in + *,$file_conv,*) + ;; + mingw/*) + file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` + ;; + cygwin/* | msys/*) + file=`cygpath -m "$file" || echo "$file"` + ;; + wine/*) + file=`winepath -w "$file" || echo "$file"` + ;; + esac + ;; + esac +} + +# func_cl_dashL linkdir +# Make cl look for libraries in LINKDIR +func_cl_dashL () +{ + func_file_conv "$1" + if test -z "$lib_path"; then + lib_path=$file + else + lib_path="$lib_path;$file" + fi + linker_opts="$linker_opts -LIBPATH:$file" +} + +# func_cl_dashl library +# Do a library search-path lookup for cl +func_cl_dashl () +{ + lib=$1 + found=no + save_IFS=$IFS + IFS=';' + for dir in $lib_path $LIB + do + IFS=$save_IFS + if $shared && test -f "$dir/$lib.dll.lib"; then + found=yes + lib=$dir/$lib.dll.lib + break + fi + if test -f "$dir/$lib.lib"; then + found=yes + lib=$dir/$lib.lib + break + fi + if test -f "$dir/lib$lib.a"; then + found=yes + lib=$dir/lib$lib.a + break + fi + done + IFS=$save_IFS + + if test "$found" != yes; then + lib=$lib.lib + fi +} + +# func_cl_wrapper cl arg... +# Adjust compile command to suit cl +func_cl_wrapper () +{ + # Assume a capable shell + lib_path= + shared=: + linker_opts= + for arg + do + if test -n "$eat"; then + eat= + else + case $1 in + -o) + # configure might choose to run compile as 'compile cc -o foo foo.c'. + eat=1 + case $2 in + *.o | *.[oO][bB][jJ]) + func_file_conv "$2" + set x "$@" -Fo"$file" + shift + ;; + *) + func_file_conv "$2" + set x "$@" -Fe"$file" + shift + ;; + esac + ;; + -I) + eat=1 + func_file_conv "$2" mingw + set x "$@" -I"$file" + shift + ;; + -I*) + func_file_conv "${1#-I}" mingw + set x "$@" -I"$file" + shift + ;; + -l) + eat=1 + func_cl_dashl "$2" + set x "$@" "$lib" + shift + ;; + -l*) + func_cl_dashl "${1#-l}" + set x "$@" "$lib" + shift + ;; + -L) + eat=1 + func_cl_dashL "$2" + ;; + -L*) + func_cl_dashL "${1#-L}" + ;; + -static) + shared=false + ;; + -Wl,*) + arg=${1#-Wl,} + save_ifs="$IFS"; IFS=',' + for flag in $arg; do + IFS="$save_ifs" + linker_opts="$linker_opts $flag" + done + IFS="$save_ifs" + ;; + -Xlinker) + eat=1 + linker_opts="$linker_opts $2" + ;; + -*) + set x "$@" "$1" + shift + ;; + *.cc | *.CC | *.cxx | *.CXX | *.[cC]++) + func_file_conv "$1" + set x "$@" -Tp"$file" + shift + ;; + *.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO]) + func_file_conv "$1" mingw + set x "$@" "$file" + shift + ;; + *) + set x "$@" "$1" + shift + ;; + esac + fi + shift + done + if test -n "$linker_opts"; then + linker_opts="-link$linker_opts" + fi + exec "$@" $linker_opts + exit 1 +} + +eat= + +case $1 in + '') + echo "$0: No command. Try '$0 --help' for more information." 1>&2 + exit 1; + ;; + -h | --h*) + cat <<\EOF +Usage: compile [--help] [--version] PROGRAM [ARGS] + +Wrapper for compilers which do not understand '-c -o'. +Remove '-o dest.o' from ARGS, run PROGRAM with the remaining +arguments, and rename the output as expected. + +If you are trying to build a whole package this is not the +right script to run: please start by reading the file 'INSTALL'. + +Report bugs to . +EOF + exit $? + ;; + -v | --v*) + echo "compile $scriptversion" + exit $? + ;; + cl | *[/\\]cl | cl.exe | *[/\\]cl.exe | \ + icl | *[/\\]icl | icl.exe | *[/\\]icl.exe ) + func_cl_wrapper "$@" # Doesn't return... + ;; +esac + +ofile= +cfile= + +for arg +do + if test -n "$eat"; then + eat= + else + case $1 in + -o) + # configure might choose to run compile as 'compile cc -o foo foo.c'. + # So we strip '-o arg' only if arg is an object. + eat=1 + case $2 in + *.o | *.obj) + ofile=$2 + ;; + *) + set x "$@" -o "$2" + shift + ;; + esac + ;; + *.c) + cfile=$1 + set x "$@" "$1" + shift + ;; + *) + set x "$@" "$1" + shift + ;; + esac + fi + shift +done + +if test -z "$ofile" || test -z "$cfile"; then + # If no '-o' option was seen then we might have been invoked from a + # pattern rule where we don't need one. That is ok -- this is a + # normal compilation that the losing compiler can handle. If no + # '.c' file was seen then we are probably linking. That is also + # ok. + exec "$@" +fi + +# Name of file we expect compiler to create. +cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'` + +# Create the lock directory. +# Note: use '[/\\:.-]' here to ensure that we don't use the same name +# that we are using for the .o file. Also, base the name on the expected +# object file name, since that is what matters with a parallel build. +lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d +while true; do + if mkdir "$lockdir" >/dev/null 2>&1; then + break + fi + sleep 1 +done +# FIXME: race condition here if user kills between mkdir and trap. +trap "rmdir '$lockdir'; exit 1" 1 2 15 + +# Run the compile. +"$@" +ret=$? + +if test -f "$cofile"; then + test "$cofile" = "$ofile" || mv "$cofile" "$ofile" +elif test -f "${cofile}bj"; then + test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile" +fi + +rmdir "$lockdir" +exit $ret + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'before-save-hook 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC0" +# time-stamp-end: "; # UTC" +# End: diff --git a/external/mit/isl/dist/config.guess b/external/mit/isl/dist/config.guess new file mode 100755 index 000000000000..7f76b6228f73 --- /dev/null +++ b/external/mit/isl/dist/config.guess @@ -0,0 +1,1754 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright 1992-2022 Free Software Foundation, Inc. + +# shellcheck disable=SC2006,SC2268 # see below for rationale + +timestamp='2022-01-09' + +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that +# program. This Exception is an additional permission under section 7 +# of the GNU General Public License, version 3 ("GPLv3"). +# +# Originally written by Per Bothner; maintained since 2000 by Ben Elliston. +# +# You can get the latest version of this script from: +# https://git.savannah.gnu.org/cgit/config.git/plain/config.guess +# +# Please send patches to . + + +# The "shellcheck disable" line above the timestamp inhibits complaints +# about features and limitations of the classic Bourne shell that were +# superseded or lifted in POSIX. However, this script identifies a wide +# variety of pre-POSIX systems that do not have POSIX shells at all, and +# even some reasonably current systems (Solaris 10 as case-in-point) still +# have a pre-POSIX /bin/sh. + + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Options: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright 1992-2022 Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + +# Just in case it came from the environment. +GUESS= + +# CC_FOR_BUILD -- compiler used by this script. Note that the use of a +# compiler to aid in system detection is discouraged as it requires +# temporary files to be created and, as you can see below, it is a +# headache to deal with in a portable fashion. + +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +# Portable tmp directory creation inspired by the Autoconf team. + +tmp= +# shellcheck disable=SC2172 +trap 'test -z "$tmp" || rm -fr "$tmp"' 0 1 2 13 15 + +set_cc_for_build() { + # prevent multiple calls if $tmp is already set + test "$tmp" && return 0 + : "${TMPDIR=/tmp}" + # shellcheck disable=SC2039,SC3028 + { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir "$tmp" 2>/dev/null) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir "$tmp" 2>/dev/null) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } + dummy=$tmp/dummy + case ${CC_FOR_BUILD-},${HOST_CC-},${CC-} in + ,,) echo "int x;" > "$dummy.c" + for driver in cc gcc c89 c99 ; do + if ($driver -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then + CC_FOR_BUILD=$driver + break + fi + done + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; + esac +} + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 1994-08-24) +if test -f /.attbin/uname ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +case $UNAME_SYSTEM in +Linux|GNU|GNU/*) + LIBC=unknown + + set_cc_for_build + cat <<-EOF > "$dummy.c" + #include + #if defined(__UCLIBC__) + LIBC=uclibc + #elif defined(__dietlibc__) + LIBC=dietlibc + #elif defined(__GLIBC__) + LIBC=gnu + #else + #include + /* First heuristic to detect musl libc. */ + #ifdef __DEFINED_va_list + LIBC=musl + #endif + #endif + EOF + cc_set_libc=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'` + eval "$cc_set_libc" + + # Second heuristic to detect musl libc. + if [ "$LIBC" = unknown ] && + command -v ldd >/dev/null && + ldd --version 2>&1 | grep -q ^musl; then + LIBC=musl + fi + + # If the system lacks a compiler, then just pick glibc. + # We could probably try harder. + if [ "$LIBC" = unknown ]; then + LIBC=gnu + fi + ;; +esac + +# Note: order is significant - the case branches are not exclusive. + +case $UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION in + *:NetBSD:*:*) + # NetBSD (nbsd) targets should (where applicable) match one or + # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \ + /sbin/sysctl -n hw.machine_arch 2>/dev/null || \ + /usr/sbin/sysctl -n hw.machine_arch 2>/dev/null || \ + echo unknown)` + case $UNAME_MACHINE_ARCH in + aarch64eb) machine=aarch64_be-unknown ;; + armeb) machine=armeb-unknown ;; + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + sh5el) machine=sh5le-unknown ;; + earmv*) + arch=`echo "$UNAME_MACHINE_ARCH" | sed -e 's,^e\(armv[0-9]\).*$,\1,'` + endian=`echo "$UNAME_MACHINE_ARCH" | sed -ne 's,^.*\(eb\)$,\1,p'` + machine=${arch}${endian}-unknown + ;; + *) machine=$UNAME_MACHINE_ARCH-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently (or will in the future) and ABI. + case $UNAME_MACHINE_ARCH in + earm*) + os=netbsdelf + ;; + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + set_cc_for_build + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ELF__ + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # Determine ABI tags. + case $UNAME_MACHINE_ARCH in + earm*) + expr='s/^earmv[0-9]/-eabi/;s/eb$//' + abi=`echo "$UNAME_MACHINE_ARCH" | sed -e "$expr"` + ;; + esac + # The OS release + # Debian GNU/NetBSD machines have a different userland, and + # thus, need a distinct triplet. However, they do not need + # kernel version information, so it can be replaced with a + # suitable tag, in the style of linux-gnu. + case $UNAME_VERSION in + Debian*) + release='-gnu' + ;; + *) + release=`echo "$UNAME_RELEASE" | sed -e 's/[-_].*//' | cut -d. -f1,2` + ;; + esac + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + GUESS=$machine-${os}${release}${abi-} + ;; + *:Bitrig:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` + GUESS=$UNAME_MACHINE_ARCH-unknown-bitrig$UNAME_RELEASE + ;; + *:OpenBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` + GUESS=$UNAME_MACHINE_ARCH-unknown-openbsd$UNAME_RELEASE + ;; + *:SecBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/SecBSD.//'` + GUESS=$UNAME_MACHINE_ARCH-unknown-secbsd$UNAME_RELEASE + ;; + *:LibertyBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'` + GUESS=$UNAME_MACHINE_ARCH-unknown-libertybsd$UNAME_RELEASE + ;; + *:MidnightBSD:*:*) + GUESS=$UNAME_MACHINE-unknown-midnightbsd$UNAME_RELEASE + ;; + *:ekkoBSD:*:*) + GUESS=$UNAME_MACHINE-unknown-ekkobsd$UNAME_RELEASE + ;; + *:SolidBSD:*:*) + GUESS=$UNAME_MACHINE-unknown-solidbsd$UNAME_RELEASE + ;; + *:OS108:*:*) + GUESS=$UNAME_MACHINE-unknown-os108_$UNAME_RELEASE + ;; + macppc:MirBSD:*:*) + GUESS=powerpc-unknown-mirbsd$UNAME_RELEASE + ;; + *:MirBSD:*:*) + GUESS=$UNAME_MACHINE-unknown-mirbsd$UNAME_RELEASE + ;; + *:Sortix:*:*) + GUESS=$UNAME_MACHINE-unknown-sortix + ;; + *:Twizzler:*:*) + GUESS=$UNAME_MACHINE-unknown-twizzler + ;; + *:Redox:*:*) + GUESS=$UNAME_MACHINE-unknown-redox + ;; + mips:OSF1:*.*) + GUESS=mips-dec-osf1 + ;; + alpha:OSF1:*:*) + # Reset EXIT trap before exiting to avoid spurious non-zero exit code. + trap '' 0 + case $UNAME_RELEASE in + *4.0) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + ;; + *5.*) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` + ;; + esac + # According to Compaq, /usr/sbin/psrinfo has been available on + # OSF/1 and Tru64 systems produced since 1995. I hope that + # covers most systems running today. This code pipes the CPU + # types through head -n 1, so we only detect the type of CPU 0. + ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` + case $ALPHA_CPU_TYPE in + "EV4 (21064)") + UNAME_MACHINE=alpha ;; + "EV4.5 (21064)") + UNAME_MACHINE=alpha ;; + "LCA4 (21066/21068)") + UNAME_MACHINE=alpha ;; + "EV5 (21164)") + UNAME_MACHINE=alphaev5 ;; + "EV5.6 (21164A)") + UNAME_MACHINE=alphaev56 ;; + "EV5.6 (21164PC)") + UNAME_MACHINE=alphapca56 ;; + "EV5.7 (21164PC)") + UNAME_MACHINE=alphapca57 ;; + "EV6 (21264)") + UNAME_MACHINE=alphaev6 ;; + "EV6.7 (21264A)") + UNAME_MACHINE=alphaev67 ;; + "EV6.8CB (21264C)") + UNAME_MACHINE=alphaev68 ;; + "EV6.8AL (21264B)") + UNAME_MACHINE=alphaev68 ;; + "EV6.8CX (21264D)") + UNAME_MACHINE=alphaev68 ;; + "EV6.9A (21264/EV69A)") + UNAME_MACHINE=alphaev69 ;; + "EV7 (21364)") + UNAME_MACHINE=alphaev7 ;; + "EV7.9 (21364A)") + UNAME_MACHINE=alphaev79 ;; + esac + # A Pn.n version is a patched version. + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + OSF_REL=`echo "$UNAME_RELEASE" | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` + GUESS=$UNAME_MACHINE-dec-osf$OSF_REL + ;; + Amiga*:UNIX_System_V:4.0:*) + GUESS=m68k-unknown-sysv4 + ;; + *:[Aa]miga[Oo][Ss]:*:*) + GUESS=$UNAME_MACHINE-unknown-amigaos + ;; + *:[Mm]orph[Oo][Ss]:*:*) + GUESS=$UNAME_MACHINE-unknown-morphos + ;; + *:OS/390:*:*) + GUESS=i370-ibm-openedition + ;; + *:z/VM:*:*) + GUESS=s390-ibm-zvmoe + ;; + *:OS400:*:*) + GUESS=powerpc-ibm-os400 + ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + GUESS=arm-acorn-riscix$UNAME_RELEASE + ;; + arm*:riscos:*:*|arm*:RISCOS:*:*) + GUESS=arm-unknown-riscos + ;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + GUESS=hppa1.1-hitachi-hiuxmpp + ;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + case `(/bin/universe) 2>/dev/null` in + att) GUESS=pyramid-pyramid-sysv3 ;; + *) GUESS=pyramid-pyramid-bsd ;; + esac + ;; + NILE*:*:*:dcosx) + GUESS=pyramid-pyramid-svr4 + ;; + DRS?6000:unix:4.0:6*) + GUESS=sparc-icl-nx6 + ;; + DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) + case `/usr/bin/uname -p` in + sparc) GUESS=sparc-icl-nx7 ;; + esac + ;; + s390x:SunOS:*:*) + SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` + GUESS=$UNAME_MACHINE-ibm-solaris2$SUN_REL + ;; + sun4H:SunOS:5.*:*) + SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` + GUESS=sparc-hal-solaris2$SUN_REL + ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` + GUESS=sparc-sun-solaris2$SUN_REL + ;; + i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) + GUESS=i386-pc-auroraux$UNAME_RELEASE + ;; + i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) + set_cc_for_build + SUN_ARCH=i386 + # If there is a compiler, see if it is configured for 64-bit objects. + # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. + # This test works for both compilers. + if test "$CC_FOR_BUILD" != no_compiler_found; then + if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS="" $CC_FOR_BUILD -m64 -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + SUN_ARCH=x86_64 + fi + fi + SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` + GUESS=$SUN_ARCH-pc-solaris2$SUN_REL + ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` + GUESS=sparc-sun-solaris3$SUN_REL + ;; + sun4*:SunOS:*:*) + case `/usr/bin/arch -k` in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/-/_/'` + GUESS=sparc-sun-sunos$SUN_REL + ;; + sun3*:SunOS:*:*) + GUESS=m68k-sun-sunos$UNAME_RELEASE + ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x$UNAME_RELEASE" = x && UNAME_RELEASE=3 + case `/bin/arch` in + sun3) + GUESS=m68k-sun-sunos$UNAME_RELEASE + ;; + sun4) + GUESS=sparc-sun-sunos$UNAME_RELEASE + ;; + esac + ;; + aushp:SunOS:*:*) + GUESS=sparc-auspex-sunos$UNAME_RELEASE + ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + GUESS=m68k-atari-mint$UNAME_RELEASE + ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + GUESS=m68k-atari-mint$UNAME_RELEASE + ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + GUESS=m68k-atari-mint$UNAME_RELEASE + ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + GUESS=m68k-milan-mint$UNAME_RELEASE + ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + GUESS=m68k-hades-mint$UNAME_RELEASE + ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + GUESS=m68k-unknown-mint$UNAME_RELEASE + ;; + m68k:machten:*:*) + GUESS=m68k-apple-machten$UNAME_RELEASE + ;; + powerpc:machten:*:*) + GUESS=powerpc-apple-machten$UNAME_RELEASE + ;; + RISC*:Mach:*:*) + GUESS=mips-dec-mach_bsd4.3 + ;; + RISC*:ULTRIX:*:*) + GUESS=mips-dec-ultrix$UNAME_RELEASE + ;; + VAX*:ULTRIX*:*:*) + GUESS=vax-dec-ultrix$UNAME_RELEASE + ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + GUESS=clipper-intergraph-clix$UNAME_RELEASE + ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + set_cc_for_build + sed 's/^ //' << EOF > "$dummy.c" +#ifdef __cplusplus +#include /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD -o "$dummy" "$dummy.c" && + dummyarg=`echo "$UNAME_RELEASE" | sed -n 's/\([0-9]*\).*/\1/p'` && + SYSTEM_NAME=`"$dummy" "$dummyarg"` && + { echo "$SYSTEM_NAME"; exit; } + GUESS=mips-mips-riscos$UNAME_RELEASE + ;; + Motorola:PowerMAX_OS:*:*) + GUESS=powerpc-motorola-powermax + ;; + Motorola:*:4.3:PL8-*) + GUESS=powerpc-harris-powermax + ;; + Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) + GUESS=powerpc-harris-powermax + ;; + Night_Hawk:Power_UNIX:*:*) + GUESS=powerpc-harris-powerunix + ;; + m88k:CX/UX:7*:*) + GUESS=m88k-harris-cxux7 + ;; + m88k:*:4*:R4*) + GUESS=m88k-motorola-sysv4 + ;; + m88k:*:3*:R3*) + GUESS=m88k-motorola-sysv3 + ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if test "$UNAME_PROCESSOR" = mc88100 || test "$UNAME_PROCESSOR" = mc88110 + then + if test "$TARGET_BINARY_INTERFACE"x = m88kdguxelfx || \ + test "$TARGET_BINARY_INTERFACE"x = x + then + GUESS=m88k-dg-dgux$UNAME_RELEASE + else + GUESS=m88k-dg-dguxbcs$UNAME_RELEASE + fi + else + GUESS=i586-dg-dgux$UNAME_RELEASE + fi + ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + GUESS=m88k-dolphin-sysv3 + ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + GUESS=m88k-motorola-sysv3 + ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + GUESS=m88k-tektronix-sysv3 + ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + GUESS=m68k-tektronix-bsd + ;; + *:IRIX*:*:*) + IRIX_REL=`echo "$UNAME_RELEASE" | sed -e 's/-/_/g'` + GUESS=mips-sgi-irix$IRIX_REL + ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + GUESS=romp-ibm-aix # uname -m gives an 8 hex-code CPU id + ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + GUESS=i386-ibm-aix + ;; + ia64:AIX:*:*) + if test -x /usr/bin/oslevel ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=$UNAME_VERSION.$UNAME_RELEASE + fi + GUESS=$UNAME_MACHINE-ibm-aix$IBM_REV + ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + set_cc_for_build + sed 's/^ //' << EOF > "$dummy.c" + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + if $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` + then + GUESS=$SYSTEM_NAME + else + GUESS=rs6000-ibm-aix3.2.5 + fi + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + GUESS=rs6000-ibm-aix3.2.4 + else + GUESS=rs6000-ibm-aix3.2 + fi + ;; + *:AIX:*:[4567]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + if /usr/sbin/lsattr -El "$IBM_CPU_ID" | grep ' POWER' >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if test -x /usr/bin/lslpp ; then + IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc | \ + awk -F: '{ print $3 }' | sed s/[0-9]*$/0/` + else + IBM_REV=$UNAME_VERSION.$UNAME_RELEASE + fi + GUESS=$IBM_ARCH-ibm-aix$IBM_REV + ;; + *:AIX:*:*) + GUESS=rs6000-ibm-aix + ;; + ibmrt:4.4BSD:*|romp-ibm:4.4BSD:*) + GUESS=romp-ibm-bsd4.4 + ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + GUESS=romp-ibm-bsd$UNAME_RELEASE # 4.3 with uname added to + ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + GUESS=rs6000-bull-bosx + ;; + DPX/2?00:B.O.S.:*:*) + GUESS=m68k-bull-sysv3 + ;; + 9000/[34]??:4.3bsd:1.*:*) + GUESS=m68k-hp-bsd + ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + GUESS=m68k-hp-bsd4.4 + ;; + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*.[0B]*//'` + case $UNAME_MACHINE in + 9000/31?) HP_ARCH=m68000 ;; + 9000/[34]??) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + if test -x /usr/bin/getconf; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case $sc_cpu_version in + 523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0 + 528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case $sc_kernel_bits in + 32) HP_ARCH=hppa2.0n ;; + 64) HP_ARCH=hppa2.0w ;; + '') HP_ARCH=hppa2.0 ;; # HP-UX 10.20 + esac ;; + esac + fi + if test "$HP_ARCH" = ""; then + set_cc_for_build + sed 's/^ //' << EOF > "$dummy.c" + + #define _HPUX_SOURCE + #include + #include + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS="" $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null) && HP_ARCH=`"$dummy"` + test -z "$HP_ARCH" && HP_ARCH=hppa + fi ;; + esac + if test "$HP_ARCH" = hppa2.0w + then + set_cc_for_build + + # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating + # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler + # generating 64-bit code. GNU and HP use different nomenclature: + # + # $ CC_FOR_BUILD=cc ./config.guess + # => hppa2.0w-hp-hpux11.23 + # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess + # => hppa64-hp-hpux11.23 + + if echo __LP64__ | (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | + grep -q __LP64__ + then + HP_ARCH=hppa2.0w + else + HP_ARCH=hppa64 + fi + fi + GUESS=$HP_ARCH-hp-hpux$HPUX_REV + ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*.[0B]*//'` + GUESS=ia64-hp-hpux$HPUX_REV + ;; + 3050*:HI-UX:*:*) + set_cc_for_build + sed 's/^ //' << EOF > "$dummy.c" + #include + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` && + { echo "$SYSTEM_NAME"; exit; } + GUESS=unknown-hitachi-hiuxwe2 + ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:*) + GUESS=hppa1.1-hp-bsd + ;; + 9000/8??:4.3bsd:*:*) + GUESS=hppa1.0-hp-bsd + ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + GUESS=hppa1.0-hp-mpeix + ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:*) + GUESS=hppa1.1-hp-osf + ;; + hp8??:OSF1:*:*) + GUESS=hppa1.0-hp-osf + ;; + i*86:OSF1:*:*) + if test -x /usr/sbin/sysversion ; then + GUESS=$UNAME_MACHINE-unknown-osf1mk + else + GUESS=$UNAME_MACHINE-unknown-osf1 + fi + ;; + parisc*:Lites*:*:*) + GUESS=hppa1.1-hp-lites + ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + GUESS=c1-convex-bsd + ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + GUESS=c34-convex-bsd + ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + GUESS=c38-convex-bsd + ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + GUESS=c4-convex-bsd + ;; + CRAY*Y-MP:*:*:*) + CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` + GUESS=ymp-cray-unicos$CRAY_REL + ;; + CRAY*[A-Z]90:*:*:*) + echo "$UNAME_MACHINE"-cray-unicos"$UNAME_RELEASE" \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ + -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*TS:*:*:*) + CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` + GUESS=t90-cray-unicos$CRAY_REL + ;; + CRAY*T3E:*:*:*) + CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` + GUESS=alphaev5-cray-unicosmk$CRAY_REL + ;; + CRAY*SV1:*:*:*) + CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` + GUESS=sv1-cray-unicos$CRAY_REL + ;; + *:UNICOS/mp:*:*) + CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` + GUESS=craynv-cray-unicosmp$CRAY_REL + ;; + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` + FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` + FUJITSU_REL=`echo "$UNAME_RELEASE" | sed -e 's/ /_/'` + GUESS=${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL} + ;; + 5000:UNIX_System_V:4.*:*) + FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` + FUJITSU_REL=`echo "$UNAME_RELEASE" | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'` + GUESS=sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL} + ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + GUESS=$UNAME_MACHINE-pc-bsdi$UNAME_RELEASE + ;; + sparc*:BSD/OS:*:*) + GUESS=sparc-unknown-bsdi$UNAME_RELEASE + ;; + *:BSD/OS:*:*) + GUESS=$UNAME_MACHINE-unknown-bsdi$UNAME_RELEASE + ;; + arm:FreeBSD:*:*) + UNAME_PROCESSOR=`uname -p` + set_cc_for_build + if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_PCS_VFP + then + FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` + GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL-gnueabi + else + FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` + GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL-gnueabihf + fi + ;; + *:FreeBSD:*:*) + UNAME_PROCESSOR=`/usr/bin/uname -p` + case $UNAME_PROCESSOR in + amd64) + UNAME_PROCESSOR=x86_64 ;; + i386) + UNAME_PROCESSOR=i586 ;; + esac + FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` + GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL + ;; + i*:CYGWIN*:*) + GUESS=$UNAME_MACHINE-pc-cygwin + ;; + *:MINGW64*:*) + GUESS=$UNAME_MACHINE-pc-mingw64 + ;; + *:MINGW*:*) + GUESS=$UNAME_MACHINE-pc-mingw32 + ;; + *:MSYS*:*) + GUESS=$UNAME_MACHINE-pc-msys + ;; + i*:PW*:*) + GUESS=$UNAME_MACHINE-pc-pw32 + ;; + *:SerenityOS:*:*) + GUESS=$UNAME_MACHINE-pc-serenity + ;; + *:Interix*:*) + case $UNAME_MACHINE in + x86) + GUESS=i586-pc-interix$UNAME_RELEASE + ;; + authenticamd | genuineintel | EM64T) + GUESS=x86_64-unknown-interix$UNAME_RELEASE + ;; + IA64) + GUESS=ia64-unknown-interix$UNAME_RELEASE + ;; + esac ;; + i*:UWIN*:*) + GUESS=$UNAME_MACHINE-pc-uwin + ;; + amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) + GUESS=x86_64-pc-cygwin + ;; + prep*:SunOS:5.*:*) + SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` + GUESS=powerpcle-unknown-solaris2$SUN_REL + ;; + *:GNU:*:*) + # the GNU system + GNU_ARCH=`echo "$UNAME_MACHINE" | sed -e 's,[-/].*$,,'` + GNU_REL=`echo "$UNAME_RELEASE" | sed -e 's,/.*$,,'` + GUESS=$GNU_ARCH-unknown-$LIBC$GNU_REL + ;; + *:GNU/*:*:*) + # other systems with GNU libc and userland + GNU_SYS=`echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"` + GNU_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` + GUESS=$UNAME_MACHINE-unknown-$GNU_SYS$GNU_REL-$LIBC + ;; + *:Minix:*:*) + GUESS=$UNAME_MACHINE-unknown-minix + ;; + aarch64:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + aarch64_be:Linux:*:*) + UNAME_MACHINE=aarch64_be + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' /proc/cpuinfo 2>/dev/null` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep -q ld.so.1 + if test "$?" = 0 ; then LIBC=gnulibc1 ; fi + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + arc:Linux:*:* | arceb:Linux:*:* | arc32:Linux:*:* | arc64:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + arm*:Linux:*:*) + set_cc_for_build + if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_EABI__ + then + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + else + if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_PCS_VFP + then + GUESS=$UNAME_MACHINE-unknown-linux-${LIBC}eabi + else + GUESS=$UNAME_MACHINE-unknown-linux-${LIBC}eabihf + fi + fi + ;; + avr32*:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + cris:Linux:*:*) + GUESS=$UNAME_MACHINE-axis-linux-$LIBC + ;; + crisv32:Linux:*:*) + GUESS=$UNAME_MACHINE-axis-linux-$LIBC + ;; + e2k:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + frv:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + hexagon:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + i*86:Linux:*:*) + GUESS=$UNAME_MACHINE-pc-linux-$LIBC + ;; + ia64:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + k1om:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + loongarch32:Linux:*:* | loongarch64:Linux:*:* | loongarchx32:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + m32r*:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + m68*:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + mips:Linux:*:* | mips64:Linux:*:*) + set_cc_for_build + IS_GLIBC=0 + test x"${LIBC}" = xgnu && IS_GLIBC=1 + sed 's/^ //' << EOF > "$dummy.c" + #undef CPU + #undef mips + #undef mipsel + #undef mips64 + #undef mips64el + #if ${IS_GLIBC} && defined(_ABI64) + LIBCABI=gnuabi64 + #else + #if ${IS_GLIBC} && defined(_ABIN32) + LIBCABI=gnuabin32 + #else + LIBCABI=${LIBC} + #endif + #endif + + #if ${IS_GLIBC} && defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6 + CPU=mipsisa64r6 + #else + #if ${IS_GLIBC} && !defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6 + CPU=mipsisa32r6 + #else + #if defined(__mips64) + CPU=mips64 + #else + CPU=mips + #endif + #endif + #endif + + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + MIPS_ENDIAN=el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + MIPS_ENDIAN= + #else + MIPS_ENDIAN= + #endif + #endif +EOF + cc_set_vars=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU\|^MIPS_ENDIAN\|^LIBCABI'` + eval "$cc_set_vars" + test "x$CPU" != x && { echo "$CPU${MIPS_ENDIAN}-unknown-linux-$LIBCABI"; exit; } + ;; + mips64el:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + openrisc*:Linux:*:*) + GUESS=or1k-unknown-linux-$LIBC + ;; + or32:Linux:*:* | or1k*:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + padre:Linux:*:*) + GUESS=sparc-unknown-linux-$LIBC + ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + GUESS=hppa64-unknown-linux-$LIBC + ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) GUESS=hppa1.1-unknown-linux-$LIBC ;; + PA8*) GUESS=hppa2.0-unknown-linux-$LIBC ;; + *) GUESS=hppa-unknown-linux-$LIBC ;; + esac + ;; + ppc64:Linux:*:*) + GUESS=powerpc64-unknown-linux-$LIBC + ;; + ppc:Linux:*:*) + GUESS=powerpc-unknown-linux-$LIBC + ;; + ppc64le:Linux:*:*) + GUESS=powerpc64le-unknown-linux-$LIBC + ;; + ppcle:Linux:*:*) + GUESS=powerpcle-unknown-linux-$LIBC + ;; + riscv32:Linux:*:* | riscv32be:Linux:*:* | riscv64:Linux:*:* | riscv64be:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + s390:Linux:*:* | s390x:Linux:*:*) + GUESS=$UNAME_MACHINE-ibm-linux-$LIBC + ;; + sh64*:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + sh*:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + tile*:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + vax:Linux:*:*) + GUESS=$UNAME_MACHINE-dec-linux-$LIBC + ;; + x86_64:Linux:*:*) + set_cc_for_build + LIBCABI=$LIBC + if test "$CC_FOR_BUILD" != no_compiler_found; then + if (echo '#ifdef __ILP32__'; echo IS_X32; echo '#endif') | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_X32 >/dev/null + then + LIBCABI=${LIBC}x32 + fi + fi + GUESS=$UNAME_MACHINE-pc-linux-$LIBCABI + ;; + xtensa*:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + i*86:DYNIX/ptx:4*:*) + # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. + # earlier versions are messed up and put the nodename in both + # sysname and nodename. + GUESS=i386-sequent-sysv4 + ;; + i*86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + GUESS=$UNAME_MACHINE-pc-sysv4.2uw$UNAME_VERSION + ;; + i*86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + GUESS=$UNAME_MACHINE-pc-os2-emx + ;; + i*86:XTS-300:*:STOP) + GUESS=$UNAME_MACHINE-unknown-stop + ;; + i*86:atheos:*:*) + GUESS=$UNAME_MACHINE-unknown-atheos + ;; + i*86:syllable:*:*) + GUESS=$UNAME_MACHINE-pc-syllable + ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) + GUESS=i386-unknown-lynxos$UNAME_RELEASE + ;; + i*86:*DOS:*:*) + GUESS=$UNAME_MACHINE-pc-msdosdjgpp + ;; + i*86:*:4.*:*) + UNAME_REL=`echo "$UNAME_RELEASE" | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + GUESS=$UNAME_MACHINE-univel-sysv$UNAME_REL + else + GUESS=$UNAME_MACHINE-pc-sysv$UNAME_REL + fi + ;; + i*86:*:5:[678]*) + # UnixWare 7.x, OpenUNIX and OpenServer 6. + case `/bin/uname -X | grep "^Machine"` in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + GUESS=$UNAME_MACHINE-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` + (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + GUESS=$UNAME_MACHINE-pc-sco$UNAME_REL + else + GUESS=$UNAME_MACHINE-pc-sysv32 + fi + ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i586. + # Note: whatever this is, it MUST be the same as what config.sub + # prints for the "djgpp" host, or else GDB configure will decide that + # this is a cross-build. + GUESS=i586-pc-msdosdjgpp + ;; + Intel:Mach:3*:*) + GUESS=i386-pc-mach3 + ;; + paragon:*:*:*) + GUESS=i860-intel-osf1 + ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + GUESS=i860-stardent-sysv$UNAME_RELEASE # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + GUESS=i860-unknown-sysv$UNAME_RELEASE # Unknown i860-SVR4 + fi + ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + GUESS=m68010-convergent-sysv + ;; + mc68k:UNIX:SYSTEM5:3.51m) + GUESS=m68k-convergent-sysv + ;; + M680?0:D-NIX:5.3:*) + GUESS=m68k-diab-dnix + ;; + M68*:*:R3V[5678]*:*) + test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; + 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4; exit; } ;; + NCR*:*:4.2:* | MPRAS*:*:4.2:*) + OS_REL='.3' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } + /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ + && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + GUESS=m68k-unknown-lynxos$UNAME_RELEASE + ;; + mc68030:UNIX_System_V:4.*:*) + GUESS=m68k-atari-sysv4 + ;; + TSUNAMI:LynxOS:2.*:*) + GUESS=sparc-unknown-lynxos$UNAME_RELEASE + ;; + rs6000:LynxOS:2.*:*) + GUESS=rs6000-unknown-lynxos$UNAME_RELEASE + ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) + GUESS=powerpc-unknown-lynxos$UNAME_RELEASE + ;; + SM[BE]S:UNIX_SV:*:*) + GUESS=mips-dde-sysv$UNAME_RELEASE + ;; + RM*:ReliantUNIX-*:*:*) + GUESS=mips-sni-sysv4 + ;; + RM*:SINIX-*:*:*) + GUESS=mips-sni-sysv4 + ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + GUESS=$UNAME_MACHINE-sni-sysv4 + else + GUESS=ns32k-sni-sysv + fi + ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + GUESS=i586-unisys-sysv4 + ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + GUESS=hppa1.1-stratus-sysv4 + ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + GUESS=i860-stratus-sysv4 + ;; + i*86:VOS:*:*) + # From Paul.Green@stratus.com. + GUESS=$UNAME_MACHINE-stratus-vos + ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + GUESS=hppa1.1-stratus-vos + ;; + mc68*:A/UX:*:*) + GUESS=m68k-apple-aux$UNAME_RELEASE + ;; + news*:NEWS-OS:6*:*) + GUESS=mips-sony-newsos6 + ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if test -d /usr/nec; then + GUESS=mips-nec-sysv$UNAME_RELEASE + else + GUESS=mips-unknown-sysv$UNAME_RELEASE + fi + ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + GUESS=powerpc-be-beos + ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + GUESS=powerpc-apple-beos + ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + GUESS=i586-pc-beos + ;; + BePC:Haiku:*:*) # Haiku running on Intel PC compatible. + GUESS=i586-pc-haiku + ;; + x86_64:Haiku:*:*) + GUESS=x86_64-unknown-haiku + ;; + SX-4:SUPER-UX:*:*) + GUESS=sx4-nec-superux$UNAME_RELEASE + ;; + SX-5:SUPER-UX:*:*) + GUESS=sx5-nec-superux$UNAME_RELEASE + ;; + SX-6:SUPER-UX:*:*) + GUESS=sx6-nec-superux$UNAME_RELEASE + ;; + SX-7:SUPER-UX:*:*) + GUESS=sx7-nec-superux$UNAME_RELEASE + ;; + SX-8:SUPER-UX:*:*) + GUESS=sx8-nec-superux$UNAME_RELEASE + ;; + SX-8R:SUPER-UX:*:*) + GUESS=sx8r-nec-superux$UNAME_RELEASE + ;; + SX-ACE:SUPER-UX:*:*) + GUESS=sxace-nec-superux$UNAME_RELEASE + ;; + Power*:Rhapsody:*:*) + GUESS=powerpc-apple-rhapsody$UNAME_RELEASE + ;; + *:Rhapsody:*:*) + GUESS=$UNAME_MACHINE-apple-rhapsody$UNAME_RELEASE + ;; + arm64:Darwin:*:*) + GUESS=aarch64-apple-darwin$UNAME_RELEASE + ;; + *:Darwin:*:*) + UNAME_PROCESSOR=`uname -p` + case $UNAME_PROCESSOR in + unknown) UNAME_PROCESSOR=powerpc ;; + esac + if command -v xcode-select > /dev/null 2> /dev/null && \ + ! xcode-select --print-path > /dev/null 2> /dev/null ; then + # Avoid executing cc if there is no toolchain installed as + # cc will be a stub that puts up a graphical alert + # prompting the user to install developer tools. + CC_FOR_BUILD=no_compiler_found + else + set_cc_for_build + fi + if test "$CC_FOR_BUILD" != no_compiler_found; then + if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + case $UNAME_PROCESSOR in + i386) UNAME_PROCESSOR=x86_64 ;; + powerpc) UNAME_PROCESSOR=powerpc64 ;; + esac + fi + # On 10.4-10.6 one might compile for PowerPC via gcc -arch ppc + if (echo '#ifdef __POWERPC__'; echo IS_PPC; echo '#endif') | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_PPC >/dev/null + then + UNAME_PROCESSOR=powerpc + fi + elif test "$UNAME_PROCESSOR" = i386 ; then + # uname -m returns i386 or x86_64 + UNAME_PROCESSOR=$UNAME_MACHINE + fi + GUESS=$UNAME_PROCESSOR-apple-darwin$UNAME_RELEASE + ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = x86; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + GUESS=$UNAME_PROCESSOR-$UNAME_MACHINE-nto-qnx$UNAME_RELEASE + ;; + *:QNX:*:4*) + GUESS=i386-pc-qnx + ;; + NEO-*:NONSTOP_KERNEL:*:*) + GUESS=neo-tandem-nsk$UNAME_RELEASE + ;; + NSE-*:NONSTOP_KERNEL:*:*) + GUESS=nse-tandem-nsk$UNAME_RELEASE + ;; + NSR-*:NONSTOP_KERNEL:*:*) + GUESS=nsr-tandem-nsk$UNAME_RELEASE + ;; + NSV-*:NONSTOP_KERNEL:*:*) + GUESS=nsv-tandem-nsk$UNAME_RELEASE + ;; + NSX-*:NONSTOP_KERNEL:*:*) + GUESS=nsx-tandem-nsk$UNAME_RELEASE + ;; + *:NonStop-UX:*:*) + GUESS=mips-compaq-nonstopux + ;; + BS2000:POSIX*:*:*) + GUESS=bs2000-siemens-sysv + ;; + DS/*:UNIX_System_V:*:*) + GUESS=$UNAME_MACHINE-$UNAME_SYSTEM-$UNAME_RELEASE + ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + if test "${cputype-}" = 386; then + UNAME_MACHINE=i386 + elif test "x${cputype-}" != x; then + UNAME_MACHINE=$cputype + fi + GUESS=$UNAME_MACHINE-unknown-plan9 + ;; + *:TOPS-10:*:*) + GUESS=pdp10-unknown-tops10 + ;; + *:TENEX:*:*) + GUESS=pdp10-unknown-tenex + ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + GUESS=pdp10-dec-tops20 + ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + GUESS=pdp10-xkl-tops20 + ;; + *:TOPS-20:*:*) + GUESS=pdp10-unknown-tops20 + ;; + *:ITS:*:*) + GUESS=pdp10-unknown-its + ;; + SEI:*:*:SEIUX) + GUESS=mips-sei-seiux$UNAME_RELEASE + ;; + *:DragonFly:*:*) + DRAGONFLY_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` + GUESS=$UNAME_MACHINE-unknown-dragonfly$DRAGONFLY_REL + ;; + *:*VMS:*:*) + UNAME_MACHINE=`(uname -p) 2>/dev/null` + case $UNAME_MACHINE in + A*) GUESS=alpha-dec-vms ;; + I*) GUESS=ia64-dec-vms ;; + V*) GUESS=vax-dec-vms ;; + esac ;; + *:XENIX:*:SysV) + GUESS=i386-pc-xenix + ;; + i*86:skyos:*:*) + SKYOS_REL=`echo "$UNAME_RELEASE" | sed -e 's/ .*$//'` + GUESS=$UNAME_MACHINE-pc-skyos$SKYOS_REL + ;; + i*86:rdos:*:*) + GUESS=$UNAME_MACHINE-pc-rdos + ;; + i*86:Fiwix:*:*) + GUESS=$UNAME_MACHINE-pc-fiwix + ;; + *:AROS:*:*) + GUESS=$UNAME_MACHINE-unknown-aros + ;; + x86_64:VMkernel:*:*) + GUESS=$UNAME_MACHINE-unknown-esx + ;; + amd64:Isilon\ OneFS:*:*) + GUESS=x86_64-unknown-onefs + ;; + *:Unleashed:*:*) + GUESS=$UNAME_MACHINE-unknown-unleashed$UNAME_RELEASE + ;; +esac + +# Do we have a guess based on uname results? +if test "x$GUESS" != x; then + echo "$GUESS" + exit +fi + +# No uname command or uname output not recognized. +set_cc_for_build +cat > "$dummy.c" < +#include +#endif +#if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__) +#if defined (vax) || defined (__vax) || defined (__vax__) || defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__) +#include +#if defined(_SIZE_T_) || defined(SIGLOST) +#include +#endif +#endif +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); +#endif + +#if defined (vax) +#if !defined (ultrix) +#include +#if defined (BSD) +#if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +#else +#if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +#else + printf ("vax-dec-bsd\n"); exit (0); +#endif +#endif +#else + printf ("vax-dec-bsd\n"); exit (0); +#endif +#else +#if defined(_SIZE_T_) || defined(SIGLOST) + struct utsname un; + uname (&un); + printf ("vax-dec-ultrix%s\n", un.release); exit (0); +#else + printf ("vax-dec-ultrix\n"); exit (0); +#endif +#endif +#endif +#if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__) +#if defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__) +#if defined(_SIZE_T_) || defined(SIGLOST) + struct utsname *un; + uname (&un); + printf ("mips-dec-ultrix%s\n", un.release); exit (0); +#else + printf ("mips-dec-ultrix\n"); exit (0); +#endif +#endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null && SYSTEM_NAME=`"$dummy"` && + { echo "$SYSTEM_NAME"; exit; } + +# Apollos put the system type in the environment. +test -d /usr/apollo && { echo "$ISP-apollo-$SYSTYPE"; exit; } + +echo "$0: unable to guess system type" >&2 + +case $UNAME_MACHINE:$UNAME_SYSTEM in + mips:Linux | mips64:Linux) + # If we got here on MIPS GNU/Linux, output extra information. + cat >&2 <&2 <&2 </dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = "$UNAME_MACHINE" +UNAME_RELEASE = "$UNAME_RELEASE" +UNAME_SYSTEM = "$UNAME_SYSTEM" +UNAME_VERSION = "$UNAME_VERSION" +EOF +fi + +exit 1 + +# Local variables: +# eval: (add-hook 'before-save-hook 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/external/mit/isl/dist/config.sub b/external/mit/isl/dist/config.sub new file mode 100755 index 000000000000..dba16e84c77c --- /dev/null +++ b/external/mit/isl/dist/config.sub @@ -0,0 +1,1890 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright 1992-2022 Free Software Foundation, Inc. + +# shellcheck disable=SC2006,SC2268 # see below for rationale + +timestamp='2022-01-03' + +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that +# program. This Exception is an additional permission under section 7 +# of the GNU General Public License, version 3 ("GPLv3"). + + +# Please send patches to . +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# You can get the latest version of this script from: +# https://git.savannah.gnu.org/cgit/config.git/plain/config.sub + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +# The "shellcheck disable" line above the timestamp inhibits complaints +# about features and limitations of the classic Bourne shell that were +# superseded or lifted in POSIX. However, this script identifies a wide +# variety of pre-POSIX systems that do not have POSIX shells at all, and +# even some reasonably current systems (Solaris 10 as case-in-point) still +# have a pre-POSIX /bin/sh. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS + +Canonicalize a configuration name. + +Options: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.sub ($timestamp) + +Copyright 1992-2022 Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo "$1" + exit ;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +esac + +# Split fields of configuration type +# shellcheck disable=SC2162 +saved_IFS=$IFS +IFS="-" read field1 field2 field3 field4 <&2 + exit 1 + ;; + *-*-*-*) + basic_machine=$field1-$field2 + basic_os=$field3-$field4 + ;; + *-*-*) + # Ambiguous whether COMPANY is present, or skipped and KERNEL-OS is two + # parts + maybe_os=$field2-$field3 + case $maybe_os in + nto-qnx* | linux-* | uclinux-uclibc* \ + | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* \ + | netbsd*-eabi* | kopensolaris*-gnu* | cloudabi*-eabi* \ + | storm-chaos* | os2-emx* | rtmk-nova*) + basic_machine=$field1 + basic_os=$maybe_os + ;; + android-linux) + basic_machine=$field1-unknown + basic_os=linux-android + ;; + *) + basic_machine=$field1-$field2 + basic_os=$field3 + ;; + esac + ;; + *-*) + # A lone config we happen to match not fitting any pattern + case $field1-$field2 in + decstation-3100) + basic_machine=mips-dec + basic_os= + ;; + *-*) + # Second component is usually, but not always the OS + case $field2 in + # Prevent following clause from handling this valid os + sun*os*) + basic_machine=$field1 + basic_os=$field2 + ;; + zephyr*) + basic_machine=$field1-unknown + basic_os=$field2 + ;; + # Manufacturers + dec* | mips* | sequent* | encore* | pc533* | sgi* | sony* \ + | att* | 7300* | 3300* | delta* | motorola* | sun[234]* \ + | unicom* | ibm* | next | hp | isi* | apollo | altos* \ + | convergent* | ncr* | news | 32* | 3600* | 3100* \ + | hitachi* | c[123]* | convex* | sun | crds | omron* | dg \ + | ultra | tti* | harris | dolphin | highlevel | gould \ + | cbm | ns | masscomp | apple | axis | knuth | cray \ + | microblaze* | sim | cisco \ + | oki | wec | wrs | winbond) + basic_machine=$field1-$field2 + basic_os= + ;; + *) + basic_machine=$field1 + basic_os=$field2 + ;; + esac + ;; + esac + ;; + *) + # Convert single-component short-hands not valid as part of + # multi-component configurations. + case $field1 in + 386bsd) + basic_machine=i386-pc + basic_os=bsd + ;; + a29khif) + basic_machine=a29k-amd + basic_os=udi + ;; + adobe68k) + basic_machine=m68010-adobe + basic_os=scout + ;; + alliant) + basic_machine=fx80-alliant + basic_os= + ;; + altos | altos3068) + basic_machine=m68k-altos + basic_os= + ;; + am29k) + basic_machine=a29k-none + basic_os=bsd + ;; + amdahl) + basic_machine=580-amdahl + basic_os=sysv + ;; + amiga) + basic_machine=m68k-unknown + basic_os= + ;; + amigaos | amigados) + basic_machine=m68k-unknown + basic_os=amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + basic_os=sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + basic_os=sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + basic_os=bsd + ;; + aros) + basic_machine=i386-pc + basic_os=aros + ;; + aux) + basic_machine=m68k-apple + basic_os=aux + ;; + balance) + basic_machine=ns32k-sequent + basic_os=dynix + ;; + blackfin) + basic_machine=bfin-unknown + basic_os=linux + ;; + cegcc) + basic_machine=arm-unknown + basic_os=cegcc + ;; + convex-c1) + basic_machine=c1-convex + basic_os=bsd + ;; + convex-c2) + basic_machine=c2-convex + basic_os=bsd + ;; + convex-c32) + basic_machine=c32-convex + basic_os=bsd + ;; + convex-c34) + basic_machine=c34-convex + basic_os=bsd + ;; + convex-c38) + basic_machine=c38-convex + basic_os=bsd + ;; + cray) + basic_machine=j90-cray + basic_os=unicos + ;; + crds | unos) + basic_machine=m68k-crds + basic_os= + ;; + da30) + basic_machine=m68k-da30 + basic_os= + ;; + decstation | pmax | pmin | dec3100 | decstatn) + basic_machine=mips-dec + basic_os= + ;; + delta88) + basic_machine=m88k-motorola + basic_os=sysv3 + ;; + dicos) + basic_machine=i686-pc + basic_os=dicos + ;; + djgpp) + basic_machine=i586-pc + basic_os=msdosdjgpp + ;; + ebmon29k) + basic_machine=a29k-amd + basic_os=ebmon + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + basic_os=ose + ;; + gmicro) + basic_machine=tron-gmicro + basic_os=sysv + ;; + go32) + basic_machine=i386-pc + basic_os=go32 + ;; + h8300hms) + basic_machine=h8300-hitachi + basic_os=hms + ;; + h8300xray) + basic_machine=h8300-hitachi + basic_os=xray + ;; + h8500hms) + basic_machine=h8500-hitachi + basic_os=hms + ;; + harris) + basic_machine=m88k-harris + basic_os=sysv3 + ;; + hp300 | hp300hpux) + basic_machine=m68k-hp + basic_os=hpux + ;; + hp300bsd) + basic_machine=m68k-hp + basic_os=bsd + ;; + hppaosf) + basic_machine=hppa1.1-hp + basic_os=osf + ;; + hppro) + basic_machine=hppa1.1-hp + basic_os=proelf + ;; + i386mach) + basic_machine=i386-mach + basic_os=mach + ;; + isi68 | isi) + basic_machine=m68k-isi + basic_os=sysv + ;; + m68knommu) + basic_machine=m68k-unknown + basic_os=linux + ;; + magnum | m3230) + basic_machine=mips-mips + basic_os=sysv + ;; + merlin) + basic_machine=ns32k-utek + basic_os=sysv + ;; + mingw64) + basic_machine=x86_64-pc + basic_os=mingw64 + ;; + mingw32) + basic_machine=i686-pc + basic_os=mingw32 + ;; + mingw32ce) + basic_machine=arm-unknown + basic_os=mingw32ce + ;; + monitor) + basic_machine=m68k-rom68k + basic_os=coff + ;; + morphos) + basic_machine=powerpc-unknown + basic_os=morphos + ;; + moxiebox) + basic_machine=moxie-unknown + basic_os=moxiebox + ;; + msdos) + basic_machine=i386-pc + basic_os=msdos + ;; + msys) + basic_machine=i686-pc + basic_os=msys + ;; + mvs) + basic_machine=i370-ibm + basic_os=mvs + ;; + nacl) + basic_machine=le32-unknown + basic_os=nacl + ;; + ncr3000) + basic_machine=i486-ncr + basic_os=sysv4 + ;; + netbsd386) + basic_machine=i386-pc + basic_os=netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + basic_os=linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + basic_os=newsos + ;; + news1000) + basic_machine=m68030-sony + basic_os=newsos + ;; + necv70) + basic_machine=v70-nec + basic_os=sysv + ;; + nh3000) + basic_machine=m68k-harris + basic_os=cxux + ;; + nh[45]000) + basic_machine=m88k-harris + basic_os=cxux + ;; + nindy960) + basic_machine=i960-intel + basic_os=nindy + ;; + mon960) + basic_machine=i960-intel + basic_os=mon960 + ;; + nonstopux) + basic_machine=mips-compaq + basic_os=nonstopux + ;; + os400) + basic_machine=powerpc-ibm + basic_os=os400 + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + basic_os=ose + ;; + os68k) + basic_machine=m68k-none + basic_os=os68k + ;; + paragon) + basic_machine=i860-intel + basic_os=osf + ;; + parisc) + basic_machine=hppa-unknown + basic_os=linux + ;; + psp) + basic_machine=mipsallegrexel-sony + basic_os=psp + ;; + pw32) + basic_machine=i586-unknown + basic_os=pw32 + ;; + rdos | rdos64) + basic_machine=x86_64-pc + basic_os=rdos + ;; + rdos32) + basic_machine=i386-pc + basic_os=rdos + ;; + rom68k) + basic_machine=m68k-rom68k + basic_os=coff + ;; + sa29200) + basic_machine=a29k-amd + basic_os=udi + ;; + sei) + basic_machine=mips-sei + basic_os=seiux + ;; + sequent) + basic_machine=i386-sequent + basic_os= + ;; + sps7) + basic_machine=m68k-bull + basic_os=sysv2 + ;; + st2000) + basic_machine=m68k-tandem + basic_os= + ;; + stratus) + basic_machine=i860-stratus + basic_os=sysv4 + ;; + sun2) + basic_machine=m68000-sun + basic_os= + ;; + sun2os3) + basic_machine=m68000-sun + basic_os=sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + basic_os=sunos4 + ;; + sun3) + basic_machine=m68k-sun + basic_os= + ;; + sun3os3) + basic_machine=m68k-sun + basic_os=sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + basic_os=sunos4 + ;; + sun4) + basic_machine=sparc-sun + basic_os= + ;; + sun4os3) + basic_machine=sparc-sun + basic_os=sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + basic_os=sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + basic_os=solaris2 + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + basic_os= + ;; + sv1) + basic_machine=sv1-cray + basic_os=unicos + ;; + symmetry) + basic_machine=i386-sequent + basic_os=dynix + ;; + t3e) + basic_machine=alphaev5-cray + basic_os=unicos + ;; + t90) + basic_machine=t90-cray + basic_os=unicos + ;; + toad1) + basic_machine=pdp10-xkl + basic_os=tops20 + ;; + tpf) + basic_machine=s390x-ibm + basic_os=tpf + ;; + udi29k) + basic_machine=a29k-amd + basic_os=udi + ;; + ultra3) + basic_machine=a29k-nyu + basic_os=sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + basic_os=none + ;; + vaxv) + basic_machine=vax-dec + basic_os=sysv + ;; + vms) + basic_machine=vax-dec + basic_os=vms + ;; + vsta) + basic_machine=i386-pc + basic_os=vsta + ;; + vxworks960) + basic_machine=i960-wrs + basic_os=vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + basic_os=vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + basic_os=vxworks + ;; + xbox) + basic_machine=i686-pc + basic_os=mingw32 + ;; + ymp) + basic_machine=ymp-cray + basic_os=unicos + ;; + *) + basic_machine=$1 + basic_os= + ;; + esac + ;; +esac + +# Decode 1-component or ad-hoc basic machines +case $basic_machine in + # Here we handle the default manufacturer of certain CPU types. It is in + # some cases the only manufacturer, in others, it is the most popular. + w89k) + cpu=hppa1.1 + vendor=winbond + ;; + op50n) + cpu=hppa1.1 + vendor=oki + ;; + op60c) + cpu=hppa1.1 + vendor=oki + ;; + ibm*) + cpu=i370 + vendor=ibm + ;; + orion105) + cpu=clipper + vendor=highlevel + ;; + mac | mpw | mac-mpw) + cpu=m68k + vendor=apple + ;; + pmac | pmac-mpw) + cpu=powerpc + vendor=apple + ;; + + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + cpu=m68000 + vendor=att + ;; + 3b*) + cpu=we32k + vendor=att + ;; + bluegene*) + cpu=powerpc + vendor=ibm + basic_os=cnk + ;; + decsystem10* | dec10*) + cpu=pdp10 + vendor=dec + basic_os=tops10 + ;; + decsystem20* | dec20*) + cpu=pdp10 + vendor=dec + basic_os=tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + cpu=m68k + vendor=motorola + ;; + dpx2*) + cpu=m68k + vendor=bull + basic_os=sysv3 + ;; + encore | umax | mmax) + cpu=ns32k + vendor=encore + ;; + elxsi) + cpu=elxsi + vendor=elxsi + basic_os=${basic_os:-bsd} + ;; + fx2800) + cpu=i860 + vendor=alliant + ;; + genix) + cpu=ns32k + vendor=ns + ;; + h3050r* | hiux*) + cpu=hppa1.1 + vendor=hitachi + basic_os=hiuxwe2 + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + cpu=hppa1.0 + vendor=hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + cpu=m68000 + vendor=hp + ;; + hp9k3[2-9][0-9]) + cpu=m68k + vendor=hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + cpu=hppa1.0 + vendor=hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + cpu=hppa1.1 + vendor=hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + cpu=hppa1.1 + vendor=hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + cpu=hppa1.1 + vendor=hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + cpu=hppa1.1 + vendor=hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + cpu=hppa1.0 + vendor=hp + ;; + i*86v32) + cpu=`echo "$1" | sed -e 's/86.*/86/'` + vendor=pc + basic_os=sysv32 + ;; + i*86v4*) + cpu=`echo "$1" | sed -e 's/86.*/86/'` + vendor=pc + basic_os=sysv4 + ;; + i*86v) + cpu=`echo "$1" | sed -e 's/86.*/86/'` + vendor=pc + basic_os=sysv + ;; + i*86sol2) + cpu=`echo "$1" | sed -e 's/86.*/86/'` + vendor=pc + basic_os=solaris2 + ;; + j90 | j90-cray) + cpu=j90 + vendor=cray + basic_os=${basic_os:-unicos} + ;; + iris | iris4d) + cpu=mips + vendor=sgi + case $basic_os in + irix*) + ;; + *) + basic_os=irix4 + ;; + esac + ;; + miniframe) + cpu=m68000 + vendor=convergent + ;; + *mint | mint[0-9]* | *MiNT | *MiNT[0-9]*) + cpu=m68k + vendor=atari + basic_os=mint + ;; + news-3600 | risc-news) + cpu=mips + vendor=sony + basic_os=newsos + ;; + next | m*-next) + cpu=m68k + vendor=next + case $basic_os in + openstep*) + ;; + nextstep*) + ;; + ns2*) + basic_os=nextstep2 + ;; + *) + basic_os=nextstep3 + ;; + esac + ;; + np1) + cpu=np1 + vendor=gould + ;; + op50n-* | op60c-*) + cpu=hppa1.1 + vendor=oki + basic_os=proelf + ;; + pa-hitachi) + cpu=hppa1.1 + vendor=hitachi + basic_os=hiuxwe2 + ;; + pbd) + cpu=sparc + vendor=tti + ;; + pbb) + cpu=m68k + vendor=tti + ;; + pc532) + cpu=ns32k + vendor=pc532 + ;; + pn) + cpu=pn + vendor=gould + ;; + power) + cpu=power + vendor=ibm + ;; + ps2) + cpu=i386 + vendor=ibm + ;; + rm[46]00) + cpu=mips + vendor=siemens + ;; + rtpc | rtpc-*) + cpu=romp + vendor=ibm + ;; + sde) + cpu=mipsisa32 + vendor=sde + basic_os=${basic_os:-elf} + ;; + simso-wrs) + cpu=sparclite + vendor=wrs + basic_os=vxworks + ;; + tower | tower-32) + cpu=m68k + vendor=ncr + ;; + vpp*|vx|vx-*) + cpu=f301 + vendor=fujitsu + ;; + w65) + cpu=w65 + vendor=wdc + ;; + w89k-*) + cpu=hppa1.1 + vendor=winbond + basic_os=proelf + ;; + none) + cpu=none + vendor=none + ;; + leon|leon[3-9]) + cpu=sparc + vendor=$basic_machine + ;; + leon-*|leon[3-9]-*) + cpu=sparc + vendor=`echo "$basic_machine" | sed 's/-.*//'` + ;; + + *-*) + # shellcheck disable=SC2162 + saved_IFS=$IFS + IFS="-" read cpu vendor <&2 + exit 1 + ;; + esac + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $vendor in + digital*) + vendor=dec + ;; + commodore*) + vendor=cbm + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if test x$basic_os != x +then + +# First recognize some ad-hoc cases, or perhaps split kernel-os, or else just +# set os. +case $basic_os in + gnu/linux*) + kernel=linux + os=`echo "$basic_os" | sed -e 's|gnu/linux|gnu|'` + ;; + os2-emx) + kernel=os2 + os=`echo "$basic_os" | sed -e 's|os2-emx|emx|'` + ;; + nto-qnx*) + kernel=nto + os=`echo "$basic_os" | sed -e 's|nto-qnx|qnx|'` + ;; + *-*) + # shellcheck disable=SC2162 + saved_IFS=$IFS + IFS="-" read kernel os <&2 + exit 1 + ;; +esac + +# As a final step for OS-related things, validate the OS-kernel combination +# (given a valid OS), if there is a kernel. +case $kernel-$os in + linux-gnu* | linux-dietlibc* | linux-android* | linux-newlib* \ + | linux-musl* | linux-relibc* | linux-uclibc* ) + ;; + uclinux-uclibc* ) + ;; + -dietlibc* | -newlib* | -musl* | -relibc* | -uclibc* ) + # These are just libc implementations, not actual OSes, and thus + # require a kernel. + echo "Invalid configuration \`$1': libc \`$os' needs explicit kernel." 1>&2 + exit 1 + ;; + kfreebsd*-gnu* | kopensolaris*-gnu*) + ;; + vxworks-simlinux | vxworks-simwindows | vxworks-spe) + ;; + nto-qnx*) + ;; + os2-emx) + ;; + *-eabi* | *-gnueabi*) + ;; + -*) + # Blank kernel with real OS is always fine. + ;; + *-*) + echo "Invalid configuration \`$1': Kernel \`$kernel' not known to work with OS \`$os'." 1>&2 + exit 1 + ;; +esac + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +case $vendor in + unknown) + case $cpu-$os in + *-riscix*) + vendor=acorn + ;; + *-sunos*) + vendor=sun + ;; + *-cnk* | *-aix*) + vendor=ibm + ;; + *-beos*) + vendor=be + ;; + *-hpux*) + vendor=hp + ;; + *-mpeix*) + vendor=hp + ;; + *-hiux*) + vendor=hitachi + ;; + *-unos*) + vendor=crds + ;; + *-dgux*) + vendor=dg + ;; + *-luna*) + vendor=omron + ;; + *-genix*) + vendor=ns + ;; + *-clix*) + vendor=intergraph + ;; + *-mvs* | *-opened*) + vendor=ibm + ;; + *-os400*) + vendor=ibm + ;; + s390-* | s390x-*) + vendor=ibm + ;; + *-ptx*) + vendor=sequent + ;; + *-tpf*) + vendor=ibm + ;; + *-vxsim* | *-vxworks* | *-windiss*) + vendor=wrs + ;; + *-aux*) + vendor=apple + ;; + *-hms*) + vendor=hitachi + ;; + *-mpw* | *-macos*) + vendor=apple + ;; + *-*mint | *-mint[0-9]* | *-*MiNT | *-MiNT[0-9]*) + vendor=atari + ;; + *-vos*) + vendor=stratus + ;; + esac + ;; +esac + +echo "$cpu-$vendor-${kernel:+$kernel-}$os" +exit + +# Local variables: +# eval: (add-hook 'before-save-hook 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/external/mit/isl/dist/configure b/external/mit/isl/dist/configure new file mode 100755 index 000000000000..7dfaacf57f75 --- /dev/null +++ b/external/mit/isl/dist/configure @@ -0,0 +1,28573 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.71 for isl 0.26. +# +# Report bugs to . +# +# +# Copyright (C) 1992-1996, 1998-2017, 2020-2021 Free Software Foundation, +# Inc. +# +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +as_nop=: +if test ${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1 +then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else $as_nop + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + + +# Reset variables that may have inherited troublesome values from +# the environment. + +# IFS needs to be set, to space, tab, and newline, in precisely that order. +# (If _AS_PATH_WALK were called with IFS unset, it would have the +# side effect of setting IFS to empty, thus disabling word splitting.) +# Quoting is to prevent editors from complaining about space-tab. +as_nl=' +' +export as_nl +IFS=" "" $as_nl" + +PS1='$ ' +PS2='> ' +PS4='+ ' + +# Ensure predictable behavior from utilities with locale-dependent output. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# We cannot yet rely on "unset" to work, but we need these variables +# to be unset--not just set to an empty or harmless value--now, to +# avoid bugs in old shells (e.g. pre-3.0 UWIN ksh). This construct +# also avoids known problems related to "unset" and subshell syntax +# in other old shells (e.g. bash 2.01 and pdksh 5.2.14). +for as_var in BASH_ENV ENV MAIL MAILPATH CDPATH +do eval test \${$as_var+y} \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done + +# Ensure that fds 0, 1, and 2 are open. +if (exec 3>&0) 2>/dev/null; then :; else exec 0&1) 2>/dev/null; then :; else exec 1>/dev/null; fi +if (exec 3>&2) ; then :; else exec 2>/dev/null; fi + +# The user is always right. +if ${PATH_SEPARATOR+false} :; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + test -r "$as_dir$0" && as_myself=$as_dir$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + printf "%s\n" "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + + +# Use a proper internal environment variable to ensure we don't fall + # into an infinite loop, continuously re-executing ourselves. + if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then + _as_can_reexec=no; export _as_can_reexec; + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +printf "%s\n" "$0: could not re-execute with $CONFIG_SHELL" >&2 +exit 255 + fi + # We don't want this to propagate to other subprocesses. + { _as_can_reexec=; unset _as_can_reexec;} +if test "x$CONFIG_SHELL" = x; then + as_bourne_compatible="as_nop=: +if test \${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1 +then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else \$as_nop + case \`(set -o) 2>/dev/null\` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi +" + as_required="as_fn_return () { (exit \$1); } +as_fn_success () { as_fn_return 0; } +as_fn_failure () { as_fn_return 1; } +as_fn_ret_success () { return 0; } +as_fn_ret_failure () { return 1; } + +exitcode=0 +as_fn_success || { exitcode=1; echo as_fn_success failed.; } +as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } +as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } +as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } +if ( set x; as_fn_ret_success y && test x = \"\$1\" ) +then : + +else \$as_nop + exitcode=1; echo positional parameters were not saved. +fi +test x\$exitcode = x0 || exit 1 +blah=\$(echo \$(echo blah)) +test x\"\$blah\" = xblah || exit 1 +test -x / || exit 1" + as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO + as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO + eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && + test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 +test \$(( 1 + 1 )) = 2 || exit 1 + + test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || ( + ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' + ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO + ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO + PATH=/empty FPATH=/empty; export PATH FPATH + test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\ + || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1" + if (eval "$as_required") 2>/dev/null +then : + as_have_required=yes +else $as_nop + as_have_required=no +fi + if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null +then : + +else $as_nop + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_found=false +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + as_found=: + case $as_dir in #( + /*) + for as_base in sh bash ksh sh5; do + # Try only shells that exist, to save several forks. + as_shell=$as_dir$as_base + if { test -f "$as_shell" || test -f "$as_shell.exe"; } && + as_run=a "$as_shell" -c "$as_bourne_compatible""$as_required" 2>/dev/null +then : + CONFIG_SHELL=$as_shell as_have_required=yes + if as_run=a "$as_shell" -c "$as_bourne_compatible""$as_suggested" 2>/dev/null +then : + break 2 +fi +fi + done;; + esac + as_found=false +done +IFS=$as_save_IFS +if $as_found +then : + +else $as_nop + if { test -f "$SHELL" || test -f "$SHELL.exe"; } && + as_run=a "$SHELL" -c "$as_bourne_compatible""$as_required" 2>/dev/null +then : + CONFIG_SHELL=$SHELL as_have_required=yes +fi +fi + + + if test "x$CONFIG_SHELL" != x +then : + export CONFIG_SHELL + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +printf "%s\n" "$0: could not re-execute with $CONFIG_SHELL" >&2 +exit 255 +fi + + if test x$as_have_required = xno +then : + printf "%s\n" "$0: This script requires a shell more modern than all" + printf "%s\n" "$0: the shells that I found on your system." + if test ${ZSH_VERSION+y} ; then + printf "%s\n" "$0: In particular, zsh $ZSH_VERSION has bugs and should" + printf "%s\n" "$0: be upgraded to zsh 4.3.4 or later." + else + printf "%s\n" "$0: Please tell bug-autoconf@gnu.org and +$0: isl-development@googlegroups.com about your system, +$0: including any error possibly output before this +$0: message. Then install a modern shell, or manually run +$0: the script under such a shell if you do have one." + fi + exit 1 +fi +fi +fi +SHELL=${CONFIG_SHELL-/bin/sh} +export SHELL +# Unset more variables known to interfere with behavior of common tools. +CLICOLOR_FORCE= GREP_OPTIONS= +unset CLICOLOR_FORCE GREP_OPTIONS + +## --------------------- ## +## M4sh Shell Functions. ## +## --------------------- ## +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset + + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit +# as_fn_nop +# --------- +# Do nothing but, unlike ":", preserve the value of $?. +as_fn_nop () +{ + return $? +} +as_nop=as_fn_nop + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`printf "%s\n" "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +printf "%s\n" X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null +then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else $as_nop + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null +then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else $as_nop + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + +# as_fn_nop +# --------- +# Do nothing but, unlike ":", preserve the value of $?. +as_fn_nop () +{ + return $? +} +as_nop=as_fn_nop + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + printf "%s\n" "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +printf "%s\n" X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + + + as_lineno_1=$LINENO as_lineno_1a=$LINENO + as_lineno_2=$LINENO as_lineno_2a=$LINENO + eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && + test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { + # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { printf "%s\n" "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } + + # If we had to re-execute with $CONFIG_SHELL, we're ensured to have + # already done that, so ensure we don't try to do so again and fall + # in an infinite loop. This has already happened in practice. + _as_can_reexec=no; export _as_can_reexec + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + + +# Determine whether it's possible to make 'echo' print without a newline. +# These variables are no longer used directly by Autoconf, but are AC_SUBSTed +# for compatibility with existing Makefiles. +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +# For backward compatibility with old third-party macros, we provide +# the shell variables $as_echo and $as_echo_n. New code should use +# AS_ECHO(["message"]) and AS_ECHO_N(["message"]), respectively. +as_echo='printf %s\n' +as_echo_n='printf %s' + + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -pR'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -pR' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -pR' + fi +else + as_ln_s='cp -pR' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +as_test_x='test -x' +as_executable_p=as_fn_executable_p + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + +SHELL=${CONFIG_SHELL-/bin/sh} + + +test -n "$DJDIR" || exec 7<&0 &1 + +# Name of the host. +# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_clean_files= +ac_config_libobj_dir=. +LIBOBJS= +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= + +# Identity of this package. +PACKAGE_NAME='isl' +PACKAGE_TARNAME='isl' +PACKAGE_VERSION='0.26' +PACKAGE_STRING='isl 0.26' +PACKAGE_BUGREPORT='isl-development@googlegroups.com' +PACKAGE_URL='' + +# Factoring default headers for most tests. +ac_includes_default="\ +#include +#ifdef HAVE_STDIO_H +# include +#endif +#ifdef HAVE_STDLIB_H +# include +#endif +#ifdef HAVE_STRING_H +# include +#endif +#ifdef HAVE_INTTYPES_H +# include +#endif +#ifdef HAVE_STDINT_H +# include +#endif +#ifdef HAVE_STRINGS_H +# include +#endif +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_SYS_STAT_H +# include +#endif +#ifdef HAVE_UNISTD_H +# include +#endif" + +ac_header_c_list= +enable_option_checking=no +ac_subst_vars='am__EXEEXT_FALSE +am__EXEEXT_TRUE +LTLIBOBJS +LIBOBJS +subdirs +GIT_HEAD_VERSION +GIT_HEAD +GIT_HEAD_ID +pkgconfig_libfile +pkgconfig_libdir +WARNING_FLAGS +HAVE_CPP_ISL_H_FALSE +HAVE_CPP_ISL_H_TRUE +HAVE_CLANG_FALSE +HAVE_CLANG_TRUE +SMALL_INT_OPT_FALSE +SMALL_INT_OPT_TRUE +HAVE_CXX17_FALSE +HAVE_CXX17_TRUE +HAVE_CXX11_FALSE +HAVE_CXX11_TRUE +GMP_FOR_MP_FALSE +GMP_FOR_MP_TRUE +IMATH_FOR_MP_FALSE +IMATH_FOR_MP_TRUE +NEED_GET_MEMORY_FUNCTIONS_FALSE +NEED_GET_MEMORY_FUNCTIONS_TRUE +MP_LIBS +MP_LDFLAGS +MP_CFLAGS +MP_CPPFLAGS +GENERATE_DOC_FALSE +GENERATE_DOC_TRUE +OS_SRCDIR +POD2HTML +PDFLATEX +PERL +CYGPATH +HAVE_PYTHON_FALSE +HAVE_PYTHON_TRUE +pkgpyexecdir +pyexecdir +pkgpythondir +pythondir +PYTHON_EXEC_PREFIX +PYTHON_PREFIX +PYTHON_PLATFORM +PYTHON_VERSION +PYTHON +CXXCPP +LT_SYS_LIBRARY_PATH +OTOOL64 +OTOOL +LIPO +NMEDIT +DSYMUTIL +MANIFEST_TOOL +RANLIB +ac_ct_AR +AR +DLLTOOL +OBJDUMP +LN_S +NM +ac_ct_DUMPBIN +DUMPBIN +LD +FGREP +EGREP +LIBTOOL +HAVE_CXX17 +HAVE_CXX11 +GREP +PRTDIAG +SED +host_os +host_vendor +host_cpu +host +LDFLAGS_FOR_BUILD +CPPFLAGS_FOR_BUILD +CFLAGS_FOR_BUILD +CCDEPMODE_FOR_BUILD +BUILD_OBJEXT +BUILD_EXEEXT +CPP_FOR_BUILD +ac_ct_CC_FOR_BUILD +CC_FOR_BUILD +build_os +build_vendor +build_cpu +build +CPP +am__fastdepCXX_FALSE +am__fastdepCXX_TRUE +CXXDEPMODE +ac_ct_CXX +CXXFLAGS +CXX +am__fastdepCC_FALSE +am__fastdepCC_TRUE +CCDEPMODE +am__nodep +AMDEPBACKSLASH +AMDEP_FALSE +AMDEP_TRUE +am__include +DEPDIR +OBJEXT +EXEEXT +ac_ct_CC +CPPFLAGS +LDFLAGS +CFLAGS +CC +versioninfo +AM_BACKSLASH +AM_DEFAULT_VERBOSITY +AM_DEFAULT_V +AM_V +CSCOPE +ETAGS +CTAGS +am__untar +am__tar +AMTAR +am__leading_dot +SET_MAKE +AWK +mkdir_p +MKDIR_P +INSTALL_STRIP_PROGRAM +STRIP +install_sh +MAKEINFO +AUTOHEADER +AUTOMAKE +AUTOCONF +ACLOCAL +VERSION +PACKAGE +CYGPATH_W +am__isrc +INSTALL_DATA +INSTALL_SCRIPT +INSTALL_PROGRAM +target_alias +host_alias +build_alias +LIBS +ECHO_T +ECHO_N +ECHO_C +DEFS +mandir +localedir +libdir +psdir +pdfdir +dvidir +htmldir +infodir +docdir +oldincludedir +includedir +runstatedir +localstatedir +sharedstatedir +sysconfdir +datadir +datarootdir +libexecdir +sbindir +bindir +program_transform_name +prefix +exec_prefix +PACKAGE_URL +PACKAGE_BUGREPORT +PACKAGE_STRING +PACKAGE_VERSION +PACKAGE_TARNAME +PACKAGE_NAME +PATH_SEPARATOR +SHELL +am__quote' +ac_subst_files='' +ac_user_opts=' +enable_option_checking +enable_silent_rules +enable_dependency_tracking +enable_portable_binary +with_gcc_arch +enable_shared +enable_static +with_pic +enable_fast_install +with_aix_soname +with_gnu_ld +with_sysroot +enable_libtool_lock +with_python_sys_prefix +with_python_prefix +with_python_exec_prefix +with_int +with_gmp +with_gmp_prefix +with_gmp_exec_prefix +with_gmp_builddir +with_clang +with_clang_prefix +with_clang_exec_prefix +' + ac_precious_vars='build_alias +host_alias +target_alias +CC +CFLAGS +LDFLAGS +LIBS +CPPFLAGS +CXX +CXXFLAGS +CCC +CPP +LT_SYS_LIBRARY_PATH +CXXCPP +PYTHON' +ac_subdirs_all='interface' + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +ac_unrecognized_opts= +ac_unrecognized_sep= +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +# (The list follows the same order as the GNU Coding Standards.) +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datarootdir='${prefix}/share' +datadir='${datarootdir}' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +runstatedir='${localstatedir}/run' +includedir='${prefix}/include' +oldincludedir='/usr/include' +docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' +infodir='${datarootdir}/info' +htmldir='${docdir}' +dvidir='${docdir}' +pdfdir='${docdir}' +psdir='${docdir}' +libdir='${exec_prefix}/lib' +localedir='${datarootdir}/locale' +mandir='${datarootdir}/man' + +ac_prev= +ac_dashdash= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval $ac_prev=\$ac_option + ac_prev= + continue + fi + + case $ac_option in + *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *=) ac_optarg= ;; + *) ac_optarg=yes ;; + esac + + case $ac_dashdash$ac_option in + --) + ac_dashdash=yes ;; + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=*) + datadir=$ac_optarg ;; + + -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ + | --dataroo | --dataro | --datar) + ac_prev=datarootdir ;; + -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ + | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) + datarootdir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: \`$ac_useropt'" + ac_useropt_orig=$ac_useropt + ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=no ;; + + -docdir | --docdir | --docdi | --doc | --do) + ac_prev=docdir ;; + -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) + docdir=$ac_optarg ;; + + -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) + ac_prev=dvidir ;; + -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) + dvidir=$ac_optarg ;; + + -enable-* | --enable-*) + ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: \`$ac_useropt'" + ac_useropt_orig=$ac_useropt + ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=\$ac_optarg ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) + ac_prev=htmldir ;; + -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ + | --ht=*) + htmldir=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localedir | --localedir | --localedi | --localed | --locale) + ac_prev=localedir ;; + -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) + localedir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst | --locals) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) + ac_prev=pdfdir ;; + -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) + pdfdir=$ac_optarg ;; + + -psdir | --psdir | --psdi | --psd | --ps) + ac_prev=psdir ;; + -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) + psdir=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -runstatedir | --runstatedir | --runstatedi | --runstated \ + | --runstate | --runstat | --runsta | --runst | --runs \ + | --run | --ru | --r) + ac_prev=runstatedir ;; + -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ + | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ + | --run=* | --ru=* | --r=*) + runstatedir=$ac_optarg ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: \`$ac_useropt'" + ac_useropt_orig=$ac_useropt + ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=\$ac_optarg ;; + + -without-* | --without-*) + ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: \`$ac_useropt'" + ac_useropt_orig=$ac_useropt + ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=no ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) as_fn_error $? "unrecognized option: \`$ac_option' +Try \`$0 --help' for more information" + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + case $ac_envvar in #( + '' | [0-9]* | *[!_$as_cr_alnum]* ) + as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; + esac + eval $ac_envvar=\$ac_optarg + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + printf "%s\n" "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + printf "%s\n" "$as_me: WARNING: invalid host type: $ac_option" >&2 + : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + as_fn_error $? "missing argument to $ac_option" +fi + +if test -n "$ac_unrecognized_opts"; then + case $enable_option_checking in + no) ;; + fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; + *) printf "%s\n" "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; + esac +fi + +# Check all directory arguments for consistency. +for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ + datadir sysconfdir sharedstatedir localstatedir includedir \ + oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ + libdir localedir mandir runstatedir +do + eval ac_val=\$$ac_var + # Remove trailing slashes. + case $ac_val in + */ ) + ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` + eval $ac_var=\$ac_val;; + esac + # Be sure to have absolute directory names. + case $ac_val in + [\\/$]* | ?:[\\/]* ) continue;; + NONE | '' ) case $ac_var in *prefix ) continue;; esac;; + esac + as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +ac_pwd=`pwd` && test -n "$ac_pwd" && +ac_ls_di=`ls -di .` && +ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || + as_fn_error $? "working directory cannot be determined" +test "X$ac_ls_di" = "X$ac_pwd_ls_di" || + as_fn_error $? "pwd does not report name of working directory" + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then the parent directory. + ac_confdir=`$as_dirname -- "$as_myself" || +$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_myself" : 'X\(//\)[^/]' \| \ + X"$as_myself" : 'X\(//\)$' \| \ + X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || +printf "%s\n" X"$as_myself" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r "$srcdir/$ac_unique_file"; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r "$srcdir/$ac_unique_file"; then + test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." + as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" +fi +ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" +ac_abs_confdir=`( + cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" + pwd)` +# When building in place, set srcdir=. +if test "$ac_abs_confdir" = "$ac_pwd"; then + srcdir=. +fi +# Remove unnecessary trailing slashes from srcdir. +# Double slashes in file names in object file debugging info +# mess up M-x gdb in Emacs. +case $srcdir in +*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; +esac +for ac_var in $ac_precious_vars; do + eval ac_env_${ac_var}_set=\${${ac_var}+set} + eval ac_env_${ac_var}_value=\$${ac_var} + eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} + eval ac_cv_env_${ac_var}_value=\$${ac_var} +done + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures isl 0.26 to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking ...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] + --datadir=DIR read-only architecture-independent data [DATAROOTDIR] + --infodir=DIR info documentation [DATAROOTDIR/info] + --localedir=DIR locale-dependent data [DATAROOTDIR/locale] + --mandir=DIR man documentation [DATAROOTDIR/man] + --docdir=DIR documentation root [DATAROOTDIR/doc/isl] + --htmldir=DIR html documentation [DOCDIR] + --dvidir=DIR dvi documentation [DOCDIR] + --pdfdir=DIR pdf documentation [DOCDIR] + --psdir=DIR ps documentation [DOCDIR] +_ACEOF + + cat <<\_ACEOF + +Program names: + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM run sed PROGRAM on installed program names + +System types: + --build=BUILD configure for building on BUILD [guessed] + --host=HOST cross-compile to build programs to run on HOST [BUILD] +_ACEOF +fi + +if test -n "$ac_init_help"; then + case $ac_init_help in + short | recursive ) echo "Configuration of isl 0.26:";; + esac + cat <<\_ACEOF + +Optional Features: + --disable-option-checking ignore unrecognized --enable/--with options + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --enable-silent-rules less verbose build output (undo: "make V=1") + --disable-silent-rules verbose build output (undo: "make V=0") + --enable-dependency-tracking + do not reject slow dependency extractors + --disable-dependency-tracking + speeds up one-time build + --enable-portable-binary + disable compiler optimizations that would produce + unportable binaries + --enable-shared[=PKGS] build shared libraries [default=yes] + --enable-static[=PKGS] build static libraries [default=yes] + --enable-fast-install[=PKGS] + optimize for fast installation [default=yes] + --disable-libtool-lock avoid locking (might break parallel builds) + +Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --with-gcc-arch= use architecture for gcc -march/-mtune, + instead of guessing + --with-pic[=PKGS] try to use only PIC/non-PIC objects [default=use + both] + --with-aix-soname=aix|svr4|both + shared library versioning (aka "SONAME") variant to + provide on AIX, [default=aix]. + --with-gnu-ld assume the C compiler uses GNU ld [default=no] + --with-sysroot[=DIR] Search for dependent libraries within DIR (or the + compiler's sysroot if not specified). + --with-python-sys-prefix + use Python's sys.prefix and sys.exec_prefix values + --with-python_prefix override the default PYTHON_PREFIX + --with-python_exec_prefix + override the default PYTHON_EXEC_PREFIX + --with-int=gmp|imath|imath-32 + Which package to use to represent multi-precision + integers [default=gmp] + --with-gmp=system|build Which gmp to use [default=system] + --with-gmp-prefix=DIR Prefix of gmp installation + --with-gmp-exec-prefix=DIR + Exec prefix of gmp installation + --with-gmp-builddir=DIR Location of gmp builddir + --with-clang=system|no Which clang to use [default=no] + --with-clang-prefix=DIR Prefix of clang installation + --with-clang-exec-prefix=DIR + Exec prefix of clang installation + +Some influential environment variables: + CC C compiler command + CFLAGS C compiler flags + LDFLAGS linker flags, e.g. -L if you have libraries in a + nonstandard directory + LIBS libraries to pass to the linker, e.g. -l + CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if + you have headers in a nonstandard directory + CXX C++ compiler command + CXXFLAGS C++ compiler flags + CPP C preprocessor + LT_SYS_LIBRARY_PATH + User-defined run-time library search path. + CXXCPP C++ preprocessor + PYTHON the Python interpreter + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +Report bugs to . +_ACEOF +ac_status=$? +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d "$ac_dir" || + { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || + continue + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`printf "%s\n" "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`printf "%s\n" "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + cd "$ac_dir" || { ac_status=$?; continue; } + # Check for configure.gnu first; this name is used for a wrapper for + # Metaconfig's "Configure" on case-insensitive file systems. + if test -f "$ac_srcdir/configure.gnu"; then + echo && + $SHELL "$ac_srcdir/configure.gnu" --help=recursive + elif test -f "$ac_srcdir/configure"; then + echo && + $SHELL "$ac_srcdir/configure" --help=recursive + else + printf "%s\n" "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi || ac_status=$? + cd "$ac_pwd" || { ac_status=$?; break; } + done +fi + +test -n "$ac_init_help" && exit $ac_status +if $ac_init_version; then + cat <<\_ACEOF +isl configure 0.26 +generated by GNU Autoconf 2.71 + +Copyright (C) 2021 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit +fi + +## ------------------------ ## +## Autoconf initialization. ## +## ------------------------ ## + +# ac_fn_c_try_compile LINENO +# -------------------------- +# Try to compile conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest.beam + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +printf "%s\n" "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext +then : + ac_retval=0 +else $as_nop + printf "%s\n" "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_compile + +# ac_fn_cxx_try_compile LINENO +# ---------------------------- +# Try to compile conftest.$ac_ext, and return whether this succeeded. +ac_fn_cxx_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest.beam + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +printf "%s\n" "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext +then : + ac_retval=0 +else $as_nop + printf "%s\n" "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_cxx_try_compile + +# ac_fn_c_try_cpp LINENO +# ---------------------- +# Try to preprocess conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_cpp () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +printf "%s\n" "$ac_try_echo"; } >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } > conftest.i && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + } +then : + ac_retval=0 +else $as_nop + printf "%s\n" "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_cpp + +# ac_fn_c_try_run LINENO +# ---------------------- +# Try to run conftest.$ac_ext, and return whether this succeeded. Assumes that +# executables *can* be run. +ac_fn_c_try_run () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +printf "%s\n" "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +printf "%s\n" "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; } +then : + ac_retval=0 +else $as_nop + printf "%s\n" "$as_me: program exited with status $ac_status" >&5 + printf "%s\n" "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=$ac_status +fi + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_run + +# ac_fn_c_try_link LINENO +# ----------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_link () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest.beam conftest$ac_exeext + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +printf "%s\n" "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + test -x conftest$ac_exeext + } +then : + ac_retval=0 +else $as_nop + printf "%s\n" "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information + # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would + # interfere with the next link command; also delete a directory that is + # left behind by Apple's compiler. We do this before executing the actions. + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_link + +# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists and can be compiled using the include files in +# INCLUDES, setting the cache variable VAR accordingly. +ac_fn_c_check_header_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +printf %s "checking for $2... " >&6; } +if eval test \${$3+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + eval "$3=yes" +else $as_nop + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +fi +eval ac_res=\$$3 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_header_compile + +# ac_fn_c_check_func LINENO FUNC VAR +# ---------------------------------- +# Tests whether FUNC exists, setting the cache variable VAR accordingly +ac_fn_c_check_func () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +printf %s "checking for $2... " >&6; } +if eval test \${$3+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +/* Define $2 to an innocuous variant, in case declares $2. + For example, HP-UX 11i declares gettimeofday. */ +#define $2 innocuous_$2 + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $2 (); below. */ + +#include +#undef $2 + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $2 (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$2 || defined __stub___$2 +choke me +#endif + +int +main (void) +{ +return $2 (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + eval "$3=yes" +else $as_nop + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +fi +eval ac_res=\$$3 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_func + +# ac_fn_cxx_try_cpp LINENO +# ------------------------ +# Try to preprocess conftest.$ac_ext, and return whether this succeeded. +ac_fn_cxx_try_cpp () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +printf "%s\n" "$ac_try_echo"; } >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } > conftest.i && { + test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || + test ! -s conftest.err + } +then : + ac_retval=0 +else $as_nop + printf "%s\n" "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_cxx_try_cpp + +# ac_fn_cxx_try_link LINENO +# ------------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. +ac_fn_cxx_try_link () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest.beam conftest$ac_exeext + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +printf "%s\n" "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + test -x conftest$ac_exeext + } +then : + ac_retval=0 +else $as_nop + printf "%s\n" "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information + # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would + # interfere with the next link command; also delete a directory that is + # left behind by Apple's compiler. We do this before executing the actions. + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_cxx_try_link + +# ac_fn_c_check_type LINENO TYPE VAR INCLUDES +# ------------------------------------------- +# Tests whether TYPE exists after having included INCLUDES, setting cache +# variable VAR accordingly. +ac_fn_c_check_type () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +printf %s "checking for $2... " >&6; } +if eval test \${$3+y} +then : + printf %s "(cached) " >&6 +else $as_nop + eval "$3=no" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main (void) +{ +if (sizeof ($2)) + return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main (void) +{ +if (sizeof (($2))) + return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + +else $as_nop + eval "$3=yes" +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +fi +eval ac_res=\$$3 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_type + +# ac_fn_c_compute_int LINENO EXPR VAR INCLUDES +# -------------------------------------------- +# Tries to find the compile-time value of EXPR in a program that includes +# INCLUDES, setting VAR accordingly. Returns whether the value could be +# computed +ac_fn_c_compute_int () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if test "$cross_compiling" = yes; then + # Depending upon the size, compute the lo and hi bounds. +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main (void) +{ +static int test_array [1 - 2 * !(($2) >= 0)]; +test_array [0] = 0; +return test_array [0]; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_lo=0 ac_mid=0 + while :; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main (void) +{ +static int test_array [1 - 2 * !(($2) <= $ac_mid)]; +test_array [0] = 0; +return test_array [0]; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_hi=$ac_mid; break +else $as_nop + as_fn_arith $ac_mid + 1 && ac_lo=$as_val + if test $ac_lo -le $ac_mid; then + ac_lo= ac_hi= + break + fi + as_fn_arith 2 '*' $ac_mid + 1 && ac_mid=$as_val +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + done +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main (void) +{ +static int test_array [1 - 2 * !(($2) < 0)]; +test_array [0] = 0; +return test_array [0]; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_hi=-1 ac_mid=-1 + while :; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main (void) +{ +static int test_array [1 - 2 * !(($2) >= $ac_mid)]; +test_array [0] = 0; +return test_array [0]; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_lo=$ac_mid; break +else $as_nop + as_fn_arith '(' $ac_mid ')' - 1 && ac_hi=$as_val + if test $ac_mid -le $ac_hi; then + ac_lo= ac_hi= + break + fi + as_fn_arith 2 '*' $ac_mid && ac_mid=$as_val +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + done +else $as_nop + ac_lo= ac_hi= +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +# Binary search between lo and hi bounds. +while test "x$ac_lo" != "x$ac_hi"; do + as_fn_arith '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo && ac_mid=$as_val + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main (void) +{ +static int test_array [1 - 2 * !(($2) <= $ac_mid)]; +test_array [0] = 0; +return test_array [0]; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_hi=$ac_mid +else $as_nop + as_fn_arith '(' $ac_mid ')' + 1 && ac_lo=$as_val +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +done +case $ac_lo in #(( +?*) eval "$3=\$ac_lo"; ac_retval=0 ;; +'') ac_retval=1 ;; +esac + else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +static long int longval (void) { return $2; } +static unsigned long int ulongval (void) { return $2; } +#include +#include +int +main (void) +{ + + FILE *f = fopen ("conftest.val", "w"); + if (! f) + return 1; + if (($2) < 0) + { + long int i = longval (); + if (i != ($2)) + return 1; + fprintf (f, "%ld", i); + } + else + { + unsigned long int i = ulongval (); + if (i != ($2)) + return 1; + fprintf (f, "%lu", i); + } + /* Do not output a trailing newline, as this causes \r\n confusion + on some platforms. */ + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO" +then : + echo >>conftest.val; read $3 &5 +printf %s "checking whether $as_decl_name is declared... " >&6; } +if eval test \${$3+y} +then : + printf %s "(cached) " >&6 +else $as_nop + as_decl_use=`echo $2|sed -e 's/(/((/' -e 's/)/) 0&/' -e 's/,/) 0& (/g'` + eval ac_save_FLAGS=\$$6 + as_fn_append $6 " $5" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main (void) +{ +#ifndef $as_decl_name +#ifdef __cplusplus + (void) $as_decl_use; +#else + (void) $as_decl_name; +#endif +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + eval "$3=yes" +else $as_nop + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + eval $6=\$ac_save_FLAGS + +fi +eval ac_res=\$$3 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_check_decl +ac_configure_args_raw= +for ac_arg +do + case $ac_arg in + *\'*) + ac_arg=`printf "%s\n" "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + as_fn_append ac_configure_args_raw " '$ac_arg'" +done + +case $ac_configure_args_raw in + *$as_nl*) + ac_safe_unquote= ;; + *) + ac_unsafe_z='|&;<>()$`\\"*?[ '' ' # This string ends in space, tab. + ac_unsafe_a="$ac_unsafe_z#~" + ac_safe_unquote="s/ '\\([^$ac_unsafe_a][^$ac_unsafe_z]*\\)'/ \\1/g" + ac_configure_args_raw=` printf "%s\n" "$ac_configure_args_raw" | sed "$ac_safe_unquote"`;; +esac + +cat >config.log <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by isl $as_me 0.26, which was +generated by GNU Autoconf 2.71. Invocation command line was + + $ $0$ac_configure_args_raw + +_ACEOF +exec 5>>config.log +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + printf "%s\n" "PATH: $as_dir" + done +IFS=$as_save_IFS + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *\'*) + ac_arg=`printf "%s\n" "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; + 2) + as_fn_append ac_configure_args1 " '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + as_fn_append ac_configure_args " '$ac_arg'" + ;; + esac + done +done +{ ac_configure_args0=; unset ac_configure_args0;} +{ ac_configure_args1=; unset ac_configure_args1;} + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Use '\'' to represent an apostrophe within the trap. +# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. +trap 'exit_status=$? + # Sanitize IFS. + IFS=" "" $as_nl" + # Save into config.log some information that might help in debugging. + { + echo + + printf "%s\n" "## ---------------- ## +## Cache variables. ## +## ---------------- ##" + echo + # The following way of writing the cache mishandles newlines in values, +( + for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +printf "%s\n" "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + (set) 2>&1 | + case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + sed -n \ + "s/'\''/'\''\\\\'\'''\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" + ;; #( + *) + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) + echo + + printf "%s\n" "## ----------------- ## +## Output variables. ## +## ----------------- ##" + echo + for ac_var in $ac_subst_vars + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`printf "%s\n" "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + printf "%s\n" "$ac_var='\''$ac_val'\''" + done | sort + echo + + if test -n "$ac_subst_files"; then + printf "%s\n" "## ------------------- ## +## File substitutions. ## +## ------------------- ##" + echo + for ac_var in $ac_subst_files + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`printf "%s\n" "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + printf "%s\n" "$ac_var='\''$ac_val'\''" + done | sort + echo + fi + + if test -s confdefs.h; then + printf "%s\n" "## ----------- ## +## confdefs.h. ## +## ----------- ##" + echo + cat confdefs.h + echo + fi + test "$ac_signal" != 0 && + printf "%s\n" "$as_me: caught signal $ac_signal" + printf "%s\n" "$as_me: exit $exit_status" + } >&5 + rm -f core *.core core.conftest.* && + rm -f -r conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status +' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -f -r conftest* confdefs.h + +printf "%s\n" "/* confdefs.h */" > confdefs.h + +# Predefined preprocessor variables. + +printf "%s\n" "#define PACKAGE_NAME \"$PACKAGE_NAME\"" >>confdefs.h + +printf "%s\n" "#define PACKAGE_TARNAME \"$PACKAGE_TARNAME\"" >>confdefs.h + +printf "%s\n" "#define PACKAGE_VERSION \"$PACKAGE_VERSION\"" >>confdefs.h + +printf "%s\n" "#define PACKAGE_STRING \"$PACKAGE_STRING\"" >>confdefs.h + +printf "%s\n" "#define PACKAGE_BUGREPORT \"$PACKAGE_BUGREPORT\"" >>confdefs.h + +printf "%s\n" "#define PACKAGE_URL \"$PACKAGE_URL\"" >>confdefs.h + + +# Let the site file select an alternate cache file if it wants to. +# Prefer an explicitly selected file to automatically selected ones. +if test -n "$CONFIG_SITE"; then + ac_site_files="$CONFIG_SITE" +elif test "x$prefix" != xNONE; then + ac_site_files="$prefix/share/config.site $prefix/etc/config.site" +else + ac_site_files="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" +fi + +for ac_site_file in $ac_site_files +do + case $ac_site_file in #( + */*) : + ;; #( + *) : + ac_site_file=./$ac_site_file ;; +esac + if test -f "$ac_site_file" && test -r "$ac_site_file"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 +printf "%s\n" "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" \ + || { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "failed to load site script $ac_site_file +See \`config.log' for more details" "$LINENO" 5; } + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special files + # actually), so we avoid doing that. DJGPP emulates it as a regular file. + if test /dev/null != "$cache_file" && test -f "$cache_file"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 +printf "%s\n" "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . "$cache_file";; + *) . "./$cache_file";; + esac + fi +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 +printf "%s\n" "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Test code for whether the C compiler supports C89 (global declarations) +ac_c_conftest_c89_globals=' +/* Does the compiler advertise C89 conformance? + Do not test the value of __STDC__, because some compilers set it to 0 + while being otherwise adequately conformant. */ +#if !defined __STDC__ +# error "Compiler does not advertise C89 conformance" +#endif + +#include +#include +struct stat; +/* Most of the following tests are stolen from RCS 5.7 src/conf.sh. */ +struct buf { int x; }; +struct buf * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not \xHH hex character constants. + These do not provoke an error unfortunately, instead are silently treated + as an "x". The following induces an error, until -std is added to get + proper ANSI mode. Curiously \x00 != x always comes out true, for an + array size at least. It is necessary to write \x00 == 0 to get something + that is true only with -std. */ +int osf4_cc_array ['\''\x00'\'' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) '\''x'\'' +int xlc6_cc_array[FOO(a) == '\''x'\'' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, int *(*)(struct buf *, struct stat *, int), + int, int);' + +# Test code for whether the C compiler supports C89 (body of main). +ac_c_conftest_c89_main=' +ok |= (argc == 0 || f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]); +' + +# Test code for whether the C compiler supports C99 (global declarations) +ac_c_conftest_c99_globals=' +// Does the compiler advertise C99 conformance? +#if !defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L +# error "Compiler does not advertise C99 conformance" +#endif + +#include +extern int puts (const char *); +extern int printf (const char *, ...); +extern int dprintf (int, const char *, ...); +extern void *malloc (size_t); + +// Check varargs macros. These examples are taken from C99 6.10.3.5. +// dprintf is used instead of fprintf to avoid needing to declare +// FILE and stderr. +#define debug(...) dprintf (2, __VA_ARGS__) +#define showlist(...) puts (#__VA_ARGS__) +#define report(test,...) ((test) ? puts (#test) : printf (__VA_ARGS__)) +static void +test_varargs_macros (void) +{ + int x = 1234; + int y = 5678; + debug ("Flag"); + debug ("X = %d\n", x); + showlist (The first, second, and third items.); + report (x>y, "x is %d but y is %d", x, y); +} + +// Check long long types. +#define BIG64 18446744073709551615ull +#define BIG32 4294967295ul +#define BIG_OK (BIG64 / BIG32 == 4294967297ull && BIG64 % BIG32 == 0) +#if !BIG_OK + #error "your preprocessor is broken" +#endif +#if BIG_OK +#else + #error "your preprocessor is broken" +#endif +static long long int bignum = -9223372036854775807LL; +static unsigned long long int ubignum = BIG64; + +struct incomplete_array +{ + int datasize; + double data[]; +}; + +struct named_init { + int number; + const wchar_t *name; + double average; +}; + +typedef const char *ccp; + +static inline int +test_restrict (ccp restrict text) +{ + // See if C++-style comments work. + // Iterate through items via the restricted pointer. + // Also check for declarations in for loops. + for (unsigned int i = 0; *(text+i) != '\''\0'\''; ++i) + continue; + return 0; +} + +// Check varargs and va_copy. +static bool +test_varargs (const char *format, ...) +{ + va_list args; + va_start (args, format); + va_list args_copy; + va_copy (args_copy, args); + + const char *str = ""; + int number = 0; + float fnumber = 0; + + while (*format) + { + switch (*format++) + { + case '\''s'\'': // string + str = va_arg (args_copy, const char *); + break; + case '\''d'\'': // int + number = va_arg (args_copy, int); + break; + case '\''f'\'': // float + fnumber = va_arg (args_copy, double); + break; + default: + break; + } + } + va_end (args_copy); + va_end (args); + + return *str && number && fnumber; +} +' + +# Test code for whether the C compiler supports C99 (body of main). +ac_c_conftest_c99_main=' + // Check bool. + _Bool success = false; + success |= (argc != 0); + + // Check restrict. + if (test_restrict ("String literal") == 0) + success = true; + char *restrict newvar = "Another string"; + + // Check varargs. + success &= test_varargs ("s, d'\'' f .", "string", 65, 34.234); + test_varargs_macros (); + + // Check flexible array members. + struct incomplete_array *ia = + malloc (sizeof (struct incomplete_array) + (sizeof (double) * 10)); + ia->datasize = 10; + for (int i = 0; i < ia->datasize; ++i) + ia->data[i] = i * 1.234; + + // Check named initializers. + struct named_init ni = { + .number = 34, + .name = L"Test wide string", + .average = 543.34343, + }; + + ni.number = 58; + + int dynamic_array[ni.number]; + dynamic_array[0] = argv[0][0]; + dynamic_array[ni.number - 1] = 543; + + // work around unused variable warnings + ok |= (!success || bignum == 0LL || ubignum == 0uLL || newvar[0] == '\''x'\'' + || dynamic_array[ni.number - 1] != 543); +' + +# Test code for whether the C compiler supports C11 (global declarations) +ac_c_conftest_c11_globals=' +// Does the compiler advertise C11 conformance? +#if !defined __STDC_VERSION__ || __STDC_VERSION__ < 201112L +# error "Compiler does not advertise C11 conformance" +#endif + +// Check _Alignas. +char _Alignas (double) aligned_as_double; +char _Alignas (0) no_special_alignment; +extern char aligned_as_int; +char _Alignas (0) _Alignas (int) aligned_as_int; + +// Check _Alignof. +enum +{ + int_alignment = _Alignof (int), + int_array_alignment = _Alignof (int[100]), + char_alignment = _Alignof (char) +}; +_Static_assert (0 < -_Alignof (int), "_Alignof is signed"); + +// Check _Noreturn. +int _Noreturn does_not_return (void) { for (;;) continue; } + +// Check _Static_assert. +struct test_static_assert +{ + int x; + _Static_assert (sizeof (int) <= sizeof (long int), + "_Static_assert does not work in struct"); + long int y; +}; + +// Check UTF-8 literals. +#define u8 syntax error! +char const utf8_literal[] = u8"happens to be ASCII" "another string"; + +// Check duplicate typedefs. +typedef long *long_ptr; +typedef long int *long_ptr; +typedef long_ptr long_ptr; + +// Anonymous structures and unions -- taken from C11 6.7.2.1 Example 1. +struct anonymous +{ + union { + struct { int i; int j; }; + struct { int k; long int l; } w; + }; + int m; +} v1; +' + +# Test code for whether the C compiler supports C11 (body of main). +ac_c_conftest_c11_main=' + _Static_assert ((offsetof (struct anonymous, i) + == offsetof (struct anonymous, w.k)), + "Anonymous union alignment botch"); + v1.i = 2; + v1.w.k = 5; + ok |= v1.i != 5; +' + +# Test code for whether the C compiler supports C11 (complete). +ac_c_conftest_c11_program="${ac_c_conftest_c89_globals} +${ac_c_conftest_c99_globals} +${ac_c_conftest_c11_globals} + +int +main (int argc, char **argv) +{ + int ok = 0; + ${ac_c_conftest_c89_main} + ${ac_c_conftest_c99_main} + ${ac_c_conftest_c11_main} + return ok; +} +" + +# Test code for whether the C compiler supports C99 (complete). +ac_c_conftest_c99_program="${ac_c_conftest_c89_globals} +${ac_c_conftest_c99_globals} + +int +main (int argc, char **argv) +{ + int ok = 0; + ${ac_c_conftest_c89_main} + ${ac_c_conftest_c99_main} + return ok; +} +" + +# Test code for whether the C compiler supports C89 (complete). +ac_c_conftest_c89_program="${ac_c_conftest_c89_globals} + +int +main (int argc, char **argv) +{ + int ok = 0; + ${ac_c_conftest_c89_main} + return ok; +} +" + +# Test code for whether the C++ compiler supports C++98 (global declarations) +ac_cxx_conftest_cxx98_globals=' +// Does the compiler advertise C++98 conformance? +#if !defined __cplusplus || __cplusplus < 199711L +# error "Compiler does not advertise C++98 conformance" +#endif + +// These inclusions are to reject old compilers that +// lack the unsuffixed header files. +#include +#include + +// and are *not* freestanding headers in C++98. +extern void assert (int); +namespace std { + extern int strcmp (const char *, const char *); +} + +// Namespaces, exceptions, and templates were all added after "C++ 2.0". +using std::exception; +using std::strcmp; + +namespace { + +void test_exception_syntax() +{ + try { + throw "test"; + } catch (const char *s) { + // Extra parentheses suppress a warning when building autoconf itself, + // due to lint rules shared with more typical C programs. + assert (!(strcmp) (s, "test")); + } +} + +template struct test_template +{ + T const val; + explicit test_template(T t) : val(t) {} + template T add(U u) { return static_cast(u) + val; } +}; + +} // anonymous namespace +' + +# Test code for whether the C++ compiler supports C++98 (body of main) +ac_cxx_conftest_cxx98_main=' + assert (argc); + assert (! argv[0]); +{ + test_exception_syntax (); + test_template tt (2.0); + assert (tt.add (4) == 6.0); + assert (true && !false); +} +' + +# Test code for whether the C++ compiler supports C++11 (global declarations) +ac_cxx_conftest_cxx11_globals=' +// Does the compiler advertise C++ 2011 conformance? +#if !defined __cplusplus || __cplusplus < 201103L +# error "Compiler does not advertise C++11 conformance" +#endif + +namespace cxx11test +{ + constexpr int get_val() { return 20; } + + struct testinit + { + int i; + double d; + }; + + class delegate + { + public: + delegate(int n) : n(n) {} + delegate(): delegate(2354) {} + + virtual int getval() { return this->n; }; + protected: + int n; + }; + + class overridden : public delegate + { + public: + overridden(int n): delegate(n) {} + virtual int getval() override final { return this->n * 2; } + }; + + class nocopy + { + public: + nocopy(int i): i(i) {} + nocopy() = default; + nocopy(const nocopy&) = delete; + nocopy & operator=(const nocopy&) = delete; + private: + int i; + }; + + // for testing lambda expressions + template Ret eval(Fn f, Ret v) + { + return f(v); + } + + // for testing variadic templates and trailing return types + template auto sum(V first) -> V + { + return first; + } + template auto sum(V first, Args... rest) -> V + { + return first + sum(rest...); + } +} +' + +# Test code for whether the C++ compiler supports C++11 (body of main) +ac_cxx_conftest_cxx11_main=' +{ + // Test auto and decltype + auto a1 = 6538; + auto a2 = 48573953.4; + auto a3 = "String literal"; + + int total = 0; + for (auto i = a3; *i; ++i) { total += *i; } + + decltype(a2) a4 = 34895.034; +} +{ + // Test constexpr + short sa[cxx11test::get_val()] = { 0 }; +} +{ + // Test initializer lists + cxx11test::testinit il = { 4323, 435234.23544 }; +} +{ + // Test range-based for + int array[] = {9, 7, 13, 15, 4, 18, 12, 10, 5, 3, + 14, 19, 17, 8, 6, 20, 16, 2, 11, 1}; + for (auto &x : array) { x += 23; } +} +{ + // Test lambda expressions + using cxx11test::eval; + assert (eval ([](int x) { return x*2; }, 21) == 42); + double d = 2.0; + assert (eval ([&](double x) { return d += x; }, 3.0) == 5.0); + assert (d == 5.0); + assert (eval ([=](double x) mutable { return d += x; }, 4.0) == 9.0); + assert (d == 5.0); +} +{ + // Test use of variadic templates + using cxx11test::sum; + auto a = sum(1); + auto b = sum(1, 2); + auto c = sum(1.0, 2.0, 3.0); +} +{ + // Test constructor delegation + cxx11test::delegate d1; + cxx11test::delegate d2(); + cxx11test::delegate d3(45); +} +{ + // Test override and final + cxx11test::overridden o1(55464); +} +{ + // Test nullptr + char *c = nullptr; +} +{ + // Test template brackets + test_template<::test_template> v(test_template(12)); +} +{ + // Unicode literals + char const *utf8 = u8"UTF-8 string \u2500"; + char16_t const *utf16 = u"UTF-8 string \u2500"; + char32_t const *utf32 = U"UTF-32 string \u2500"; +} +' + +# Test code for whether the C compiler supports C++11 (complete). +ac_cxx_conftest_cxx11_program="${ac_cxx_conftest_cxx98_globals} +${ac_cxx_conftest_cxx11_globals} + +int +main (int argc, char **argv) +{ + int ok = 0; + ${ac_cxx_conftest_cxx98_main} + ${ac_cxx_conftest_cxx11_main} + return ok; +} +" + +# Test code for whether the C compiler supports C++98 (complete). +ac_cxx_conftest_cxx98_program="${ac_cxx_conftest_cxx98_globals} +int +main (int argc, char **argv) +{ + int ok = 0; + ${ac_cxx_conftest_cxx98_main} + return ok; +} +" + +as_fn_append ac_header_c_list " stdio.h stdio_h HAVE_STDIO_H" +as_fn_append ac_header_c_list " stdlib.h stdlib_h HAVE_STDLIB_H" +as_fn_append ac_header_c_list " string.h string_h HAVE_STRING_H" +as_fn_append ac_header_c_list " inttypes.h inttypes_h HAVE_INTTYPES_H" +as_fn_append ac_header_c_list " stdint.h stdint_h HAVE_STDINT_H" +as_fn_append ac_header_c_list " strings.h strings_h HAVE_STRINGS_H" +as_fn_append ac_header_c_list " sys/stat.h sys_stat_h HAVE_SYS_STAT_H" +as_fn_append ac_header_c_list " sys/types.h sys_types_h HAVE_SYS_TYPES_H" +as_fn_append ac_header_c_list " unistd.h unistd_h HAVE_UNISTD_H" + +# Auxiliary files required by this configure script. +ac_aux_files="ltmain.sh config.guess config.sub compile missing install-sh" + +# Locations in which to look for auxiliary files. +ac_aux_dir_candidates="${srcdir}/." + +# Search for a directory containing all of the required auxiliary files, +# $ac_aux_files, from the $PATH-style list $ac_aux_dir_candidates. +# If we don't find one directory that contains all the files we need, +# we report the set of missing files from the *first* directory in +# $ac_aux_dir_candidates and give up. +ac_missing_aux_files="" +ac_first_candidate=: +printf "%s\n" "$as_me:${as_lineno-$LINENO}: looking for aux files: $ac_aux_files" >&5 +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_found=false +for as_dir in $ac_aux_dir_candidates +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + as_found=: + + printf "%s\n" "$as_me:${as_lineno-$LINENO}: trying $as_dir" >&5 + ac_aux_dir_found=yes + ac_install_sh= + for ac_aux in $ac_aux_files + do + # As a special case, if "install-sh" is required, that requirement + # can be satisfied by any of "install-sh", "install.sh", or "shtool", + # and $ac_install_sh is set appropriately for whichever one is found. + if test x"$ac_aux" = x"install-sh" + then + if test -f "${as_dir}install-sh"; then + printf "%s\n" "$as_me:${as_lineno-$LINENO}: ${as_dir}install-sh found" >&5 + ac_install_sh="${as_dir}install-sh -c" + elif test -f "${as_dir}install.sh"; then + printf "%s\n" "$as_me:${as_lineno-$LINENO}: ${as_dir}install.sh found" >&5 + ac_install_sh="${as_dir}install.sh -c" + elif test -f "${as_dir}shtool"; then + printf "%s\n" "$as_me:${as_lineno-$LINENO}: ${as_dir}shtool found" >&5 + ac_install_sh="${as_dir}shtool install -c" + else + ac_aux_dir_found=no + if $ac_first_candidate; then + ac_missing_aux_files="${ac_missing_aux_files} install-sh" + else + break + fi + fi + else + if test -f "${as_dir}${ac_aux}"; then + printf "%s\n" "$as_me:${as_lineno-$LINENO}: ${as_dir}${ac_aux} found" >&5 + else + ac_aux_dir_found=no + if $ac_first_candidate; then + ac_missing_aux_files="${ac_missing_aux_files} ${ac_aux}" + else + break + fi + fi + fi + done + if test "$ac_aux_dir_found" = yes; then + ac_aux_dir="$as_dir" + break + fi + ac_first_candidate=false + + as_found=false +done +IFS=$as_save_IFS +if $as_found +then : + +else $as_nop + as_fn_error $? "cannot find required auxiliary files:$ac_missing_aux_files" "$LINENO" 5 +fi + + +# These three variables are undocumented and unsupported, +# and are intended to be withdrawn in a future Autoconf release. +# They can cause serious problems if a builder's source tree is in a directory +# whose full name contains unusual characters. +if test -f "${ac_aux_dir}config.guess"; then + ac_config_guess="$SHELL ${ac_aux_dir}config.guess" +fi +if test -f "${ac_aux_dir}config.sub"; then + ac_config_sub="$SHELL ${ac_aux_dir}config.sub" +fi +if test -f "$ac_aux_dir/configure"; then + ac_configure="$SHELL ${ac_aux_dir}configure" +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in $ac_precious_vars; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val=\$ac_cv_env_${ac_var}_value + eval ac_new_val=\$ac_env_${ac_var}_value + case $ac_old_set,$ac_new_set in + set,) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +printf "%s\n" "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 +printf "%s\n" "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + # differences in whitespace do not lead to failure. + ac_old_val_w=`echo x $ac_old_val` + ac_new_val_w=`echo x $ac_new_val` + if test "$ac_old_val_w" != "$ac_new_val_w"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 +printf "%s\n" "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + ac_cache_corrupted=: + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 +printf "%s\n" "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} + eval $ac_var=\$ac_old_val + fi + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 +printf "%s\n" "$as_me: former value: \`$ac_old_val'" >&2;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 +printf "%s\n" "$as_me: current value: \`$ac_new_val'" >&2;} + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *\'*) ac_arg=$ac_var=`printf "%s\n" "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) as_fn_append ac_configure_args " '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 +printf "%s\n" "$as_me: error: changes in the environment can compromise the build" >&2;} + as_fn_error $? "run \`${MAKE-make} distclean' and/or \`rm $cache_file' + and start over" "$LINENO" 5 +fi +## -------------------- ## +## Main body of script. ## +## -------------------- ## + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + + +am__api_version='1.16' + + + + # Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +# Reject install programs that cannot install multiple files. +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 +printf %s "checking for a BSD-compatible install... " >&6; } +if test -z "$INSTALL"; then +if test ${ac_cv_path_install+y} +then : + printf %s "(cached) " >&6 +else $as_nop + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + # Account for fact that we put trailing slashes in our PATH walk. +case $as_dir in #(( + ./ | /[cC]/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_prog$ac_exec_ext"; then + if test $ac_prog = install && + grep dspmsg "$as_dir$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + rm -rf conftest.one conftest.two conftest.dir + echo one > conftest.one + echo two > conftest.two + mkdir conftest.dir + if "$as_dir$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir/" && + test -s conftest.one && test -s conftest.two && + test -s conftest.dir/conftest.one && + test -s conftest.dir/conftest.two + then + ac_cv_path_install="$as_dir$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + fi + done + done + ;; +esac + + done +IFS=$as_save_IFS + +rm -rf conftest.one conftest.two conftest.dir + +fi + if test ${ac_cv_path_install+y}; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. Don't cache a + # value for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + INSTALL=$ac_install_sh + fi +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 +printf "%s\n" "$INSTALL" >&6; } + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 +printf %s "checking whether build environment is sane... " >&6; } +# Reject unsafe characters in $srcdir or the absolute working directory +# name. Accept space and tab only in the latter. +am_lf=' +' +case `pwd` in + *[\\\"\#\$\&\'\`$am_lf]*) + as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; +esac +case $srcdir in + *[\\\"\#\$\&\'\`$am_lf\ \ ]*) + as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;; +esac + +# Do 'set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + am_has_slept=no + for am_try in 1 2; do + echo "timestamp, slept: $am_has_slept" > conftest.file + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$*" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + if test "$*" != "X $srcdir/configure conftest.file" \ + && test "$*" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + as_fn_error $? "ls -t appears to fail. Make sure there is not a broken + alias in your environment" "$LINENO" 5 + fi + if test "$2" = conftest.file || test $am_try -eq 2; then + break + fi + # Just in case. + sleep 1 + am_has_slept=yes + done + test "$2" = conftest.file + ) +then + # Ok. + : +else + as_fn_error $? "newly created file is older than distributed files! +Check your system clock" "$LINENO" 5 +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } +# If we didn't sleep, we still need to ensure time stamps of config.status and +# generated files are strictly newer. +am_sleep_pid= +if grep 'slept: no' conftest.file >/dev/null 2>&1; then + ( sleep 1 ) & + am_sleep_pid=$! +fi + +rm -f conftest.file + +test "$program_prefix" != NONE && + program_transform_name="s&^&$program_prefix&;$program_transform_name" +# Use a double $ so make ignores it. +test "$program_suffix" != NONE && + program_transform_name="s&\$&$program_suffix&;$program_transform_name" +# Double any \ or $. +# By default was `s,x,x', remove it if useless. +ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' +program_transform_name=`printf "%s\n" "$program_transform_name" | sed "$ac_script"` + + +# Expand $ac_aux_dir to an absolute path. +am_aux_dir=`cd "$ac_aux_dir" && pwd` + + + if test x"${MISSING+set}" != xset; then + MISSING="\${SHELL} '$am_aux_dir/missing'" +fi +# Use eval to expand $SHELL +if eval "$MISSING --is-lightweight"; then + am_missing_run="$MISSING " +else + am_missing_run= + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5 +printf "%s\n" "$as_me: WARNING: 'missing' script is too old or missing" >&2;} +fi + +if test x"${install_sh+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; + *) + install_sh="\${SHELL} $am_aux_dir/install-sh" + esac +fi + +# Installed binaries are usually stripped using 'strip' when the user +# run "make install-strip". However 'strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the 'STRIP' environment variable to overrule this program. +if test "$cross_compiling" != no; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_STRIP+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 +printf "%s\n" "$STRIP" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_STRIP+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_STRIP="strip" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 +printf "%s\n" "$ac_ct_STRIP" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a race-free mkdir -p" >&5 +printf %s "checking for a race-free mkdir -p... " >&6; } +if test -z "$MKDIR_P"; then + if test ${ac_cv_path_mkdir+y} +then : + printf %s "(cached) " >&6 +else $as_nop + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_prog in mkdir gmkdir; do + for ac_exec_ext in '' $ac_executable_extensions; do + as_fn_executable_p "$as_dir$ac_prog$ac_exec_ext" || continue + case `"$as_dir$ac_prog$ac_exec_ext" --version 2>&1` in #( + 'mkdir ('*'coreutils) '* | \ + 'BusyBox '* | \ + 'mkdir (fileutils) '4.1*) + ac_cv_path_mkdir=$as_dir$ac_prog$ac_exec_ext + break 3;; + esac + done + done + done +IFS=$as_save_IFS + +fi + + test -d ./--version && rmdir ./--version + if test ${ac_cv_path_mkdir+y}; then + MKDIR_P="$ac_cv_path_mkdir -p" + else + # As a last resort, use the slow shell script. Don't cache a + # value for MKDIR_P within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + MKDIR_P="$ac_install_sh -d" + fi +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 +printf "%s\n" "$MKDIR_P" >&6; } + +for ac_prog in gawk mawk nawk awk +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_AWK+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$AWK"; then + ac_cv_prog_AWK="$AWK" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_AWK="$ac_prog" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AWK=$ac_cv_prog_AWK +if test -n "$AWK"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 +printf "%s\n" "$AWK" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + + test -n "$AWK" && break +done + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +printf %s "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } +set x ${MAKE-make} +ac_make=`printf "%s\n" "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` +if eval test \${ac_cv_prog_make_${ac_make}_set+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat >conftest.make <<\_ACEOF +SHELL = /bin/sh +all: + @echo '@@@%%%=$(MAKE)=@@@%%%' +_ACEOF +# GNU make sometimes prints "make[1]: Entering ...", which would confuse us. +case `${MAKE-make} -f conftest.make 2>/dev/null` in + *@@@%%%=?*=@@@%%%*) + eval ac_cv_prog_make_${ac_make}_set=yes;; + *) + eval ac_cv_prog_make_${ac_make}_set=no;; +esac +rm -f conftest.make +fi +if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + SET_MAKE= +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + SET_MAKE="MAKE=${MAKE-make}" +fi + +rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null + +# Check whether --enable-silent-rules was given. +if test ${enable_silent_rules+y} +then : + enableval=$enable_silent_rules; +fi + +case $enable_silent_rules in # ((( + yes) AM_DEFAULT_VERBOSITY=0;; + no) AM_DEFAULT_VERBOSITY=1;; + *) AM_DEFAULT_VERBOSITY=1;; +esac +am_make=${MAKE-make} +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 +printf %s "checking whether $am_make supports nested variables... " >&6; } +if test ${am_cv_make_support_nested_variables+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if printf "%s\n" 'TRUE=$(BAR$(V)) +BAR0=false +BAR1=true +V=1 +am__doit: + @$(TRUE) +.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then + am_cv_make_support_nested_variables=yes +else + am_cv_make_support_nested_variables=no +fi +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 +printf "%s\n" "$am_cv_make_support_nested_variables" >&6; } +if test $am_cv_make_support_nested_variables = yes; then + AM_V='$(V)' + AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' +else + AM_V=$AM_DEFAULT_VERBOSITY + AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY +fi +AM_BACKSLASH='\' + +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + am__isrc=' -I$(srcdir)' + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi + + +# Define the identity of the package. + PACKAGE='isl' + VERSION='0.26' + + +printf "%s\n" "#define PACKAGE \"$PACKAGE\"" >>confdefs.h + + +printf "%s\n" "#define VERSION \"$VERSION\"" >>confdefs.h + +# Some tools Automake needs. + +ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} + + +AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} + + +AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} + + +AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} + + +MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} + +# For better backward compatibility. To be removed once Automake 1.9.x +# dies out for good. For more background, see: +# +# +mkdir_p='$(MKDIR_P)' + +# We need awk for the "check" target (and possibly the TAP driver). The +# system "awk" is bad on some platforms. +# Always define AMTAR for backward compatibility. Yes, it's still used +# in the wild :-( We should find a proper way to deprecate it ... +AMTAR='$${TAR-tar}' + + +# We'll loop over all known methods to create a tar archive until one works. +_am_tools='gnutar pax cpio none' + +am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' + + + + + +# Variables for tags utilities; see am/tags.am +if test -z "$CTAGS"; then + CTAGS=ctags +fi + +if test -z "$ETAGS"; then + ETAGS=etags +fi + +if test -z "$CSCOPE"; then + CSCOPE=cscope +fi + + + +# POSIX will say in a future version that running "rm -f" with no argument +# is OK; and we want to be able to make that assumption in our Makefile +# recipes. So use an aggressive probe to check that the usage we want is +# actually supported "in the wild" to an acceptable degree. +# See automake bug#10828. +# To make any issue more visible, cause the running configure to be aborted +# by default if the 'rm' program in use doesn't match our expectations; the +# user can still override this though. +if rm -f && rm -fr && rm -rf; then : OK; else + cat >&2 <<'END' +Oops! + +Your 'rm' program seems unable to run without file operands specified +on the command line, even when the '-f' option is present. This is contrary +to the behaviour of most rm programs out there, and not conforming with +the upcoming POSIX standard: + +Please tell bug-automake@gnu.org about your system, including the value +of your $PATH and any error possibly output before this message. This +can help us improve future automake versions. + +END + if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then + echo 'Configuration will proceed anyway, since you have set the' >&2 + echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 + echo >&2 + else + cat >&2 <<'END' +Aborting the configuration process, to ensure you take notice of the issue. + +You can download and install GNU coreutils to get an 'rm' implementation +that behaves properly: . + +If you want to complete the configuration process using your problematic +'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM +to "yes", and re-run configure. + +END + as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5 + fi +fi + +# Check whether --enable-silent-rules was given. +if test ${enable_silent_rules+y} +then : + enableval=$enable_silent_rules; +fi + +case $enable_silent_rules in # ((( + yes) AM_DEFAULT_VERBOSITY=0;; + no) AM_DEFAULT_VERBOSITY=1;; + *) AM_DEFAULT_VERBOSITY=0;; +esac +am_make=${MAKE-make} +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 +printf %s "checking whether $am_make supports nested variables... " >&6; } +if test ${am_cv_make_support_nested_variables+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if printf "%s\n" 'TRUE=$(BAR$(V)) +BAR0=false +BAR1=true +V=1 +am__doit: + @$(TRUE) +.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then + am_cv_make_support_nested_variables=yes +else + am_cv_make_support_nested_variables=no +fi +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 +printf "%s\n" "$am_cv_make_support_nested_variables" >&6; } +if test $am_cv_make_support_nested_variables = yes; then + AM_V='$(V)' + AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' +else + AM_V=$AM_DEFAULT_VERBOSITY + AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY +fi +AM_BACKSLASH='\' + + +versioninfo=26:0:3 + +if test "x$prefix" != "xNONE"; then + prefix_wd=`cd $prefix && pwd` + srcdir_wd=`cd $srcdir && pwd` + wd=`pwd` + if test "x$prefix_wd" = "x$srcdir_wd"; then + as_fn_error $? "Installation in source directory not supported" "$LINENO" 5 + fi + if test "x$prefix_wd" = "x$wd"; then + as_fn_error $? "Installation in build directory not supported" "$LINENO" 5 + fi +fi + + + + + + + + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_CC+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +printf "%s\n" "$CC" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_CC+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="gcc" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +printf "%s\n" "$ac_ct_CC" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_CC+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +printf "%s\n" "$CC" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + + fi +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_CC+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + if test "$as_dir$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +printf "%s\n" "$CC" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl.exe + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_CC+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +printf "%s\n" "$CC" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl.exe +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_CC+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="$ac_prog" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +printf "%s\n" "$ac_ct_CC" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}clang", so it can be a program name with args. +set dummy ${ac_tool_prefix}clang; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_CC+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}clang" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +printf "%s\n" "$CC" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "clang", so it can be a program name with args. +set dummy clang; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_CC+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="clang" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +printf "%s\n" "$ac_ct_CC" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +fi + + +test -z "$CC" && { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "no acceptable C compiler found in \$PATH +See \`config.log' for more details" "$LINENO" 5; } + +# Provide some information about the compiler. +printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion -version; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +printf "%s\n" "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 +printf %s "checking whether the C compiler works... " >&6; } +ac_link_default=`printf "%s\n" "$ac_link" | sed 's/ -o *conftest[^ ]*//'` + +# The possible output files: +ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" + +ac_rmfiles= +for ac_file in $ac_files +do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + * ) ac_rmfiles="$ac_rmfiles $ac_file";; + esac +done +rm -f $ac_rmfiles + +if { { ac_try="$ac_link_default" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +printf "%s\n" "$ac_try_echo"; } >&5 + (eval "$ac_link_default") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +then : + # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. +# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' +# in a Makefile. We should not override ac_cv_exeext if it was cached, +# so that the user can short-circuit this test for compilers unknown to +# Autoconf. +for ac_file in $ac_files '' +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + if test ${ac_cv_exeext+y} && test "$ac_cv_exeext" != no; + then :; else + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + fi + # We set ac_cv_exeext here because the later test for it is not + # safe: cross compilers may not add the suffix if given an `-o' + # argument, so we may need to know it at that point already. + # Even if this section looks crufty: it has the advantage of + # actually working. + break;; + * ) + break;; + esac +done +test "$ac_cv_exeext" = no && ac_cv_exeext= + +else $as_nop + ac_file='' +fi +if test -z "$ac_file" +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +printf "%s\n" "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "C compiler cannot create executables +See \`config.log' for more details" "$LINENO" 5; } +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 +printf %s "checking for C compiler default output file name... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 +printf "%s\n" "$ac_file" >&6; } +ac_exeext=$ac_cv_exeext + +rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 +printf %s "checking for suffix of executables... " >&6; } +if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +printf "%s\n" "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +then : + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + break;; + * ) break;; + esac +done +else $as_nop + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest conftest$ac_cv_exeext +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 +printf "%s\n" "$ac_cv_exeext" >&6; } + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main (void) +{ +FILE *f = fopen ("conftest.out", "w"); + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +ac_clean_files="$ac_clean_files conftest.out" +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 +printf %s "checking whether we are cross compiling... " >&6; } +if test "$cross_compiling" != yes; then + { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +printf "%s\n" "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if { ac_try='./conftest$ac_cv_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +printf "%s\n" "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details" "$LINENO" 5; } + fi + fi +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 +printf "%s\n" "$cross_compiling" >&6; } + +rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out +ac_clean_files=$ac_clean_files_save +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 +printf %s "checking for suffix of object files... " >&6; } +if test ${ac_cv_objext+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +printf "%s\n" "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +then : + for ac_file in conftest.o conftest.obj conftest.*; do + test -f "$ac_file" || continue; + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else $as_nop + printf "%s\n" "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of object files: cannot compile +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 +printf "%s\n" "$ac_cv_objext" >&6; } +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports GNU C" >&5 +printf %s "checking whether the compiler supports GNU C... " >&6; } +if test ${ac_cv_c_compiler_gnu+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_compiler_gnu=yes +else $as_nop + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 +printf "%s\n" "$ac_cv_c_compiler_gnu" >&6; } +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +if test $ac_compiler_gnu = yes; then + GCC=yes +else + GCC= +fi +ac_test_CFLAGS=${CFLAGS+y} +ac_save_CFLAGS=$CFLAGS +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 +printf %s "checking whether $CC accepts -g... " >&6; } +if test ${ac_cv_prog_cc_g+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_prog_cc_g=yes +else $as_nop + CFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + +else $as_nop + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_prog_cc_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 +printf "%s\n" "$ac_cv_prog_cc_g" >&6; } +if test $ac_test_CFLAGS; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +ac_prog_cc_stdc=no +if test x$ac_prog_cc_stdc = xno +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C11 features" >&5 +printf %s "checking for $CC option to enable C11 features... " >&6; } +if test ${ac_cv_prog_cc_c11+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_cv_prog_cc_c11=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_c_conftest_c11_program +_ACEOF +for ac_arg in '' -std=gnu11 +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_prog_cc_c11=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam + test "x$ac_cv_prog_cc_c11" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC +fi + +if test "x$ac_cv_prog_cc_c11" = xno +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +printf "%s\n" "unsupported" >&6; } +else $as_nop + if test "x$ac_cv_prog_cc_c11" = x +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +printf "%s\n" "none needed" >&6; } +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c11" >&5 +printf "%s\n" "$ac_cv_prog_cc_c11" >&6; } + CC="$CC $ac_cv_prog_cc_c11" +fi + ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c11 + ac_prog_cc_stdc=c11 +fi +fi +if test x$ac_prog_cc_stdc = xno +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C99 features" >&5 +printf %s "checking for $CC option to enable C99 features... " >&6; } +if test ${ac_cv_prog_cc_c99+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_cv_prog_cc_c99=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_c_conftest_c99_program +_ACEOF +for ac_arg in '' -std=gnu99 -std=c99 -c99 -qlanglvl=extc1x -qlanglvl=extc99 -AC99 -D_STDC_C99= +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_prog_cc_c99=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam + test "x$ac_cv_prog_cc_c99" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC +fi + +if test "x$ac_cv_prog_cc_c99" = xno +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +printf "%s\n" "unsupported" >&6; } +else $as_nop + if test "x$ac_cv_prog_cc_c99" = x +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +printf "%s\n" "none needed" >&6; } +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c99" >&5 +printf "%s\n" "$ac_cv_prog_cc_c99" >&6; } + CC="$CC $ac_cv_prog_cc_c99" +fi + ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c99 + ac_prog_cc_stdc=c99 +fi +fi +if test x$ac_prog_cc_stdc = xno +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C89 features" >&5 +printf %s "checking for $CC option to enable C89 features... " >&6; } +if test ${ac_cv_prog_cc_c89+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_c_conftest_c89_program +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_prog_cc_c89=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC +fi + +if test "x$ac_cv_prog_cc_c89" = xno +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +printf "%s\n" "unsupported" >&6; } +else $as_nop + if test "x$ac_cv_prog_cc_c89" = x +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +printf "%s\n" "none needed" >&6; } +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 +printf "%s\n" "$ac_cv_prog_cc_c89" >&6; } + CC="$CC $ac_cv_prog_cc_c89" +fi + ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c89 + ac_prog_cc_stdc=c89 +fi +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5 +printf %s "checking whether $CC understands -c and -o together... " >&6; } +if test ${am_cv_prog_cc_c_o+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF + # Make sure it works both with $CC and with simple cc. + # Following AC_PROG_CC_C_O, we do the test twice because some + # compilers refuse to overwrite an existing .o file with -o, + # though they will create one. + am_cv_prog_cc_c_o=yes + for am_i in 1 2; do + if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5 + ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } \ + && test -f conftest2.$ac_objext; then + : OK + else + am_cv_prog_cc_c_o=no + break + fi + done + rm -f core conftest* + unset am_i +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5 +printf "%s\n" "$am_cv_prog_cc_c_o" >&6; } +if test "$am_cv_prog_cc_c_o" != yes; then + # Losing compiler, so override with the script. + # FIXME: It is wrong to rewrite CC. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__CC in this case, + # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" + CC="$am_aux_dir/compile $CC" +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +DEPDIR="${am__leading_dot}deps" + +ac_config_commands="$ac_config_commands depfiles" + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} supports the include directive" >&5 +printf %s "checking whether ${MAKE-make} supports the include directive... " >&6; } +cat > confinc.mk << 'END' +am__doit: + @echo this is the am__doit target >confinc.out +.PHONY: am__doit +END +am__include="#" +am__quote= +# BSD make does it like this. +echo '.include "confinc.mk" # ignored' > confmf.BSD +# Other make implementations (GNU, Solaris 10, AIX) do it like this. +echo 'include confinc.mk # ignored' > confmf.GNU +_am_result=no +for s in GNU BSD; do + { echo "$as_me:$LINENO: ${MAKE-make} -f confmf.$s && cat confinc.out" >&5 + (${MAKE-make} -f confmf.$s && cat confinc.out) >&5 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + case $?:`cat confinc.out 2>/dev/null` in #( + '0:this is the am__doit target') : + case $s in #( + BSD) : + am__include='.include' am__quote='"' ;; #( + *) : + am__include='include' am__quote='' ;; +esac ;; #( + *) : + ;; +esac + if test "$am__include" != "#"; then + _am_result="yes ($s style)" + break + fi +done +rm -f confinc.* confmf.* +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: ${_am_result}" >&5 +printf "%s\n" "${_am_result}" >&6; } + +# Check whether --enable-dependency-tracking was given. +if test ${enable_dependency_tracking+y} +then : + enableval=$enable_dependency_tracking; +fi + +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' + am__nodep='_no' +fi + if test "x$enable_dependency_tracking" != xno; then + AMDEP_TRUE= + AMDEP_FALSE='#' +else + AMDEP_TRUE='#' + AMDEP_FALSE= +fi + + + +depcc="$CC" am_compiler_list= + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 +printf %s "checking dependency style of $depcc... " >&6; } +if test ${am_cv_CC_dependencies_compiler_type+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named 'D' -- because '-MD' means "put the output + # in D". + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CC_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + am__universal=false + case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with + # Solaris 10 /bin/sh. + echo '/* dummy */' > sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with '-c' and '-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle '-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs. + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # After this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested. + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok '-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CC_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CC_dependencies_compiler_type=none +fi + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 +printf "%s\n" "$am_cv_CC_dependencies_compiler_type" >&6; } +CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type + + if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then + am__fastdepCC_TRUE= + am__fastdepCC_FALSE='#' +else + am__fastdepCC_TRUE='#' + am__fastdepCC_FALSE= +fi + + + + + + + + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +if test -z "$CXX"; then + if test -n "$CCC"; then + CXX=$CCC + else + if test -n "$ac_tool_prefix"; then + for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC clang++ + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_CXX+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$CXX"; then + ac_cv_prog_CXX="$CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CXX=$ac_cv_prog_CXX +if test -n "$CXX"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 +printf "%s\n" "$CXX" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + + test -n "$CXX" && break + done +fi +if test -z "$CXX"; then + ac_ct_CXX=$CXX + for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC clang++ +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_CXX+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$ac_ct_CXX"; then + ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CXX="$ac_prog" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CXX=$ac_cv_prog_ac_ct_CXX +if test -n "$ac_ct_CXX"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5 +printf "%s\n" "$ac_ct_CXX" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + + test -n "$ac_ct_CXX" && break +done + + if test "x$ac_ct_CXX" = x; then + CXX="g++" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CXX=$ac_ct_CXX + fi +fi + + fi +fi +# Provide some information about the compiler. +printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +printf "%s\n" "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports GNU C++" >&5 +printf %s "checking whether the compiler supports GNU C++... " >&6; } +if test ${ac_cv_cxx_compiler_gnu+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO" +then : + ac_compiler_gnu=yes +else $as_nop + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +ac_cv_cxx_compiler_gnu=$ac_compiler_gnu + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5 +printf "%s\n" "$ac_cv_cxx_compiler_gnu" >&6; } +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + +if test $ac_compiler_gnu = yes; then + GXX=yes +else + GXX= +fi +ac_test_CXXFLAGS=${CXXFLAGS+y} +ac_save_CXXFLAGS=$CXXFLAGS +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5 +printf %s "checking whether $CXX accepts -g... " >&6; } +if test ${ac_cv_prog_cxx_g+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_save_cxx_werror_flag=$ac_cxx_werror_flag + ac_cxx_werror_flag=yes + ac_cv_prog_cxx_g=no + CXXFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO" +then : + ac_cv_prog_cxx_g=yes +else $as_nop + CXXFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO" +then : + +else $as_nop + ac_cxx_werror_flag=$ac_save_cxx_werror_flag + CXXFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO" +then : + ac_cv_prog_cxx_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ac_cxx_werror_flag=$ac_save_cxx_werror_flag +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5 +printf "%s\n" "$ac_cv_prog_cxx_g" >&6; } +if test $ac_test_CXXFLAGS; then + CXXFLAGS=$ac_save_CXXFLAGS +elif test $ac_cv_prog_cxx_g = yes; then + if test "$GXX" = yes; then + CXXFLAGS="-g -O2" + else + CXXFLAGS="-g" + fi +else + if test "$GXX" = yes; then + CXXFLAGS="-O2" + else + CXXFLAGS= + fi +fi +ac_prog_cxx_stdcxx=no +if test x$ac_prog_cxx_stdcxx = xno +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CXX option to enable C++11 features" >&5 +printf %s "checking for $CXX option to enable C++11 features... " >&6; } +if test ${ac_cv_prog_cxx_11+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_cv_prog_cxx_11=no +ac_save_CXX=$CXX +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_cxx_conftest_cxx11_program +_ACEOF +for ac_arg in '' -std=gnu++11 -std=gnu++0x -std=c++11 -std=c++0x -qlanglvl=extended0x -AA +do + CXX="$ac_save_CXX $ac_arg" + if ac_fn_cxx_try_compile "$LINENO" +then : + ac_cv_prog_cxx_cxx11=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam + test "x$ac_cv_prog_cxx_cxx11" != "xno" && break +done +rm -f conftest.$ac_ext +CXX=$ac_save_CXX +fi + +if test "x$ac_cv_prog_cxx_cxx11" = xno +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +printf "%s\n" "unsupported" >&6; } +else $as_nop + if test "x$ac_cv_prog_cxx_cxx11" = x +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +printf "%s\n" "none needed" >&6; } +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_cxx11" >&5 +printf "%s\n" "$ac_cv_prog_cxx_cxx11" >&6; } + CXX="$CXX $ac_cv_prog_cxx_cxx11" +fi + ac_cv_prog_cxx_stdcxx=$ac_cv_prog_cxx_cxx11 + ac_prog_cxx_stdcxx=cxx11 +fi +fi +if test x$ac_prog_cxx_stdcxx = xno +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CXX option to enable C++98 features" >&5 +printf %s "checking for $CXX option to enable C++98 features... " >&6; } +if test ${ac_cv_prog_cxx_98+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_cv_prog_cxx_98=no +ac_save_CXX=$CXX +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_cxx_conftest_cxx98_program +_ACEOF +for ac_arg in '' -std=gnu++98 -std=c++98 -qlanglvl=extended -AA +do + CXX="$ac_save_CXX $ac_arg" + if ac_fn_cxx_try_compile "$LINENO" +then : + ac_cv_prog_cxx_cxx98=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam + test "x$ac_cv_prog_cxx_cxx98" != "xno" && break +done +rm -f conftest.$ac_ext +CXX=$ac_save_CXX +fi + +if test "x$ac_cv_prog_cxx_cxx98" = xno +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +printf "%s\n" "unsupported" >&6; } +else $as_nop + if test "x$ac_cv_prog_cxx_cxx98" = x +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +printf "%s\n" "none needed" >&6; } +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_cxx98" >&5 +printf "%s\n" "$ac_cv_prog_cxx_cxx98" >&6; } + CXX="$CXX $ac_cv_prog_cxx_cxx98" +fi + ac_cv_prog_cxx_stdcxx=$ac_cv_prog_cxx_cxx98 + ac_prog_cxx_stdcxx=cxx98 +fi +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +depcc="$CXX" am_compiler_list= + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 +printf %s "checking dependency style of $depcc... " >&6; } +if test ${am_cv_CXX_dependencies_compiler_type+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named 'D' -- because '-MD' means "put the output + # in D". + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CXX_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + am__universal=false + case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with + # Solaris 10 /bin/sh. + echo '/* dummy */' > sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with '-c' and '-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle '-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs. + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # After this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested. + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok '-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CXX_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CXX_dependencies_compiler_type=none +fi + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_CXX_dependencies_compiler_type" >&5 +printf "%s\n" "$am_cv_CXX_dependencies_compiler_type" >&6; } +CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type + + if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then + am__fastdepCXX_TRUE= + am__fastdepCXX_FALSE='#' +else + am__fastdepCXX_TRUE='#' + am__fastdepCXX_FALSE= +fi + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 +printf %s "checking how to run the C preprocessor... " >&6; } +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if test ${ac_cv_prog_CPP+y} +then : + printf %s "(cached) " >&6 +else $as_nop + # Double quotes because $CC needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" cpp /lib/cpp + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO" +then : + +else $as_nop + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO" +then : + # Broken: success on invalid input. +continue +else $as_nop + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok +then : + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 +printf "%s\n" "$CPP" >&6; } +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO" +then : + +else $as_nop + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO" +then : + # Broken: success on invalid input. +continue +else $as_nop + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok +then : + +else $as_nop + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details" "$LINENO" 5; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + + # Make sure we can run config.sub. +$SHELL "${ac_aux_dir}config.sub" sun4 >/dev/null 2>&1 || + as_fn_error $? "cannot run $SHELL ${ac_aux_dir}config.sub" "$LINENO" 5 + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 +printf %s "checking build system type... " >&6; } +if test ${ac_cv_build+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_build_alias=$build_alias +test "x$ac_build_alias" = x && + ac_build_alias=`$SHELL "${ac_aux_dir}config.guess"` +test "x$ac_build_alias" = x && + as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 +ac_cv_build=`$SHELL "${ac_aux_dir}config.sub" $ac_build_alias` || + as_fn_error $? "$SHELL ${ac_aux_dir}config.sub $ac_build_alias failed" "$LINENO" 5 + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 +printf "%s\n" "$ac_cv_build" >&6; } +case $ac_cv_build in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; +esac +build=$ac_cv_build +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_build +shift +build_cpu=$1 +build_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +build_os=$* +IFS=$ac_save_IFS +case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac + + + + +cross_compiling_build=no + +ac_build_tool_prefix= +if test -n "$build" +then : + ac_build_tool_prefix="$build-" +elif test -n "$build_alias" +then : + ac_build_tool_prefix="$build_alias-" +fi + +ac_ext=c +ac_cpp='$CPP_FOR_BUILD $CPPFLAGS_FOR_BUILD' +ac_compile='$CC_FOR_BUILD -c $CFLAGS_FOR_BUILD $CPPFLAGS_FOR_BUILD conftest.$ac_ext >&5' +ac_link='$CC_FOR_BUILD -o conftest$ac_build_exeext $CFLAGS_FOR_BUILD $CPPFLAGS_FOR_BUILD $LDFLAGS_FOR_BUILD conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_build_c_compiler_gnu + + +was_set_c_compiler_gnu=${ac_cv_c_compiler_gnu+y} +if test ${was_set_c_compiler_gnu} +then : + saved_c_compiler_gnu=$ac_cv_c_compiler_gnu + { ac_cv_c_compiler_gnu=; unset ac_cv_c_compiler_gnu;} +fi + +ac_ext=c +ac_cpp='$CPP_FOR_BUILD $CPPFLAGS_FOR_BUILD' +ac_compile='$CC_FOR_BUILD -c $CFLAGS_FOR_BUILD $CPPFLAGS_FOR_BUILD conftest.$ac_ext >&5' +ac_link='$CC_FOR_BUILD -o conftest$ac_build_exeext $CFLAGS_FOR_BUILD $CPPFLAGS_FOR_BUILD $LDFLAGS_FOR_BUILD conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_build_c_compiler_gnu +if test -n "$ac_build_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_build_tool_prefix}gcc; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_CC_FOR_BUILD+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$CC_FOR_BUILD"; then + ac_cv_prog_CC_FOR_BUILD="$CC_FOR_BUILD" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_CC_FOR_BUILD="${ac_build_tool_prefix}gcc" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC_FOR_BUILD=$ac_cv_prog_CC_FOR_BUILD +if test -n "$CC_FOR_BUILD"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC_FOR_BUILD" >&5 +printf "%s\n" "$CC_FOR_BUILD" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC_FOR_BUILD"; then + ac_ct_CC_FOR_BUILD=$CC_FOR_BUILD + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_CC_FOR_BUILD+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$ac_ct_CC_FOR_BUILD"; then + ac_cv_prog_ac_ct_CC_FOR_BUILD="$ac_ct_CC_FOR_BUILD" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC_FOR_BUILD="gcc" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC_FOR_BUILD=$ac_cv_prog_ac_ct_CC_FOR_BUILD +if test -n "$ac_ct_CC_FOR_BUILD"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC_FOR_BUILD" >&5 +printf "%s\n" "$ac_ct_CC_FOR_BUILD" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + if test "x$ac_ct_CC_FOR_BUILD" = x; then + CC_FOR_BUILD="" + else + case $cross_compiling_build:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with build triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with build triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC_FOR_BUILD=$ac_ct_CC_FOR_BUILD + fi +else + CC_FOR_BUILD="$ac_cv_prog_CC_FOR_BUILD" +fi + +if test -z "$CC_FOR_BUILD"; then + if test -n "$ac_build_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_build_tool_prefix}cc; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_CC_FOR_BUILD+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$CC_FOR_BUILD"; then + ac_cv_prog_CC_FOR_BUILD="$CC_FOR_BUILD" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_CC_FOR_BUILD="${ac_build_tool_prefix}cc" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC_FOR_BUILD=$ac_cv_prog_CC_FOR_BUILD +if test -n "$CC_FOR_BUILD"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC_FOR_BUILD" >&5 +printf "%s\n" "$CC_FOR_BUILD" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + + fi +fi +if test -z "$CC_FOR_BUILD"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_CC_FOR_BUILD+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$CC_FOR_BUILD"; then + ac_cv_prog_CC_FOR_BUILD="$CC_FOR_BUILD" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + if test "$as_dir$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC_FOR_BUILD="cc" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC_FOR_BUILD + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC_FOR_BUILD to just the basename; use the full file name. + shift + ac_cv_prog_CC_FOR_BUILD="$as_dir$ac_word${1+' '}$@" + fi +fi +fi +fi +CC_FOR_BUILD=$ac_cv_prog_CC_FOR_BUILD +if test -n "$CC_FOR_BUILD"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC_FOR_BUILD" >&5 +printf "%s\n" "$CC_FOR_BUILD" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + +fi +if test -z "$CC_FOR_BUILD"; then + if test -n "$ac_build_tool_prefix"; then + for ac_prog in cl.exe + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_build_tool_prefix$ac_prog; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_CC_FOR_BUILD+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$CC_FOR_BUILD"; then + ac_cv_prog_CC_FOR_BUILD="$CC_FOR_BUILD" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_CC_FOR_BUILD="$ac_build_tool_prefix$ac_prog" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC_FOR_BUILD=$ac_cv_prog_CC_FOR_BUILD +if test -n "$CC_FOR_BUILD"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC_FOR_BUILD" >&5 +printf "%s\n" "$CC_FOR_BUILD" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + + test -n "$CC_FOR_BUILD" && break + done +fi +if test -z "$CC_FOR_BUILD"; then + ac_ct_CC_FOR_BUILD=$CC_FOR_BUILD + for ac_prog in cl.exe +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_CC_FOR_BUILD+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$ac_ct_CC_FOR_BUILD"; then + ac_cv_prog_ac_ct_CC_FOR_BUILD="$ac_ct_CC_FOR_BUILD" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC_FOR_BUILD="$ac_prog" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC_FOR_BUILD=$ac_cv_prog_ac_ct_CC_FOR_BUILD +if test -n "$ac_ct_CC_FOR_BUILD"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC_FOR_BUILD" >&5 +printf "%s\n" "$ac_ct_CC_FOR_BUILD" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + + test -n "$ac_ct_CC_FOR_BUILD" && break +done + + if test "x$ac_ct_CC_FOR_BUILD" = x; then + CC_FOR_BUILD="" + else + case $cross_compiling_build:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with build triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with build triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC_FOR_BUILD=$ac_ct_CC_FOR_BUILD + fi +fi + +fi +if test -z "$CC_FOR_BUILD"; then + if test -n "$ac_build_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}clang", so it can be a program name with args. +set dummy ${ac_build_tool_prefix}clang; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_CC_FOR_BUILD+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$CC_FOR_BUILD"; then + ac_cv_prog_CC_FOR_BUILD="$CC_FOR_BUILD" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_CC_FOR_BUILD="${ac_build_tool_prefix}clang" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC_FOR_BUILD=$ac_cv_prog_CC_FOR_BUILD +if test -n "$CC_FOR_BUILD"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC_FOR_BUILD" >&5 +printf "%s\n" "$CC_FOR_BUILD" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC_FOR_BUILD"; then + ac_ct_CC_FOR_BUILD=$CC_FOR_BUILD + # Extract the first word of "clang", so it can be a program name with args. +set dummy clang; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_CC_FOR_BUILD+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$ac_ct_CC_FOR_BUILD"; then + ac_cv_prog_ac_ct_CC_FOR_BUILD="$ac_ct_CC_FOR_BUILD" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC_FOR_BUILD="clang" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC_FOR_BUILD=$ac_cv_prog_ac_ct_CC_FOR_BUILD +if test -n "$ac_ct_CC_FOR_BUILD"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC_FOR_BUILD" >&5 +printf "%s\n" "$ac_ct_CC_FOR_BUILD" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + if test "x$ac_ct_CC_FOR_BUILD" = x; then + CC_FOR_BUILD="" + else + case $cross_compiling_build:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with build triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with build triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC_FOR_BUILD=$ac_ct_CC_FOR_BUILD + fi +else + CC_FOR_BUILD="$ac_cv_prog_CC_FOR_BUILD" +fi + +fi + + +test -z "$CC_FOR_BUILD" && { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "no acceptable C compiler found in \$PATH +See \`config.log' for more details" "$LINENO" 5; } + +# Provide some information about the compiler. +printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion -version; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +printf "%s\n" "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports GNU C" >&5 +printf %s "checking whether the compiler supports GNU C... " >&6; } +if test ${ac_cv_c_compiler_gnu+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_compiler_gnu=yes +else $as_nop + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_build_objext conftest.beam conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 +printf "%s\n" "$ac_cv_c_compiler_gnu" >&6; } +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +if test $ac_compiler_gnu = yes; then + GCC_FOR_BUILD=yes +else + GCC_FOR_BUILD= +fi +ac_test_CFLAGS=${CFLAGS_FOR_BUILD+y} +ac_save_CFLAGS=$CFLAGS_FOR_BUILD +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC_FOR_BUILD accepts -g" >&5 +printf %s "checking whether $CC_FOR_BUILD accepts -g... " >&6; } +if test ${ac_cv_build_prog_cc_g+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_build_prog_cc_g=no + CFLAGS_FOR_BUILD="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_build_prog_cc_g=yes +else $as_nop + CFLAGS_FOR_BUILD="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + +else $as_nop + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS_FOR_BUILD="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_build_prog_cc_g=yes +fi +rm -f core conftest.err conftest.$ac_build_objext conftest.beam conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_build_objext conftest.beam conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_build_objext conftest.beam conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build_prog_cc_g" >&5 +printf "%s\n" "$ac_cv_build_prog_cc_g" >&6; } +if test $ac_test_CFLAGS; then + CFLAGS_FOR_BUILD=$ac_save_CFLAGS +elif test $ac_cv_build_prog_cc_g = yes; then + if test "$GCC_FOR_BUILD" = yes; then + CFLAGS_FOR_BUILD="-g -O2" + else + CFLAGS_FOR_BUILD="-g" + fi +else + if test "$GCC_FOR_BUILD" = yes; then + CFLAGS_FOR_BUILD="-O2" + else + CFLAGS_FOR_BUILD= + fi +fi +ac_prog_cc_stdc=no +if test x$ac_prog_cc_stdc = xno +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC_FOR_BUILD option to enable C11 features" >&5 +printf %s "checking for $CC_FOR_BUILD option to enable C11 features... " >&6; } +if test ${ac_cv_build_prog_cc_c11+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_cv_build_prog_cc_c11=no +ac_save_CC=$CC_FOR_BUILD +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_c_conftest_c11_program +_ACEOF +for ac_arg in '' -std=gnu11 +do + CC_FOR_BUILD="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_build_prog_cc_c11=$ac_arg +fi +rm -f core conftest.err conftest.$ac_build_objext conftest.beam + test "x$ac_cv_build_prog_cc_c11" != "xno" && break +done +rm -f conftest.$ac_ext +CC_FOR_BUILD=$ac_save_CC +fi + +if test "x$ac_cv_build_prog_cc_c11" = xno +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +printf "%s\n" "unsupported" >&6; } +else $as_nop + if test "x$ac_cv_build_prog_cc_c11" = x +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +printf "%s\n" "none needed" >&6; } +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build_prog_cc_c11" >&5 +printf "%s\n" "$ac_cv_build_prog_cc_c11" >&6; } + CC_FOR_BUILD="$CC_FOR_BUILD $ac_cv_build_prog_cc_c11" +fi + ac_cv_prog_cc_stdc=$ac_cv_build_prog_cc_c11 + ac_prog_cc_stdc=c11 +fi +fi +if test x$ac_prog_cc_stdc = xno +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC_FOR_BUILD option to enable C99 features" >&5 +printf %s "checking for $CC_FOR_BUILD option to enable C99 features... " >&6; } +if test ${ac_cv_build_prog_cc_c99+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_cv_build_prog_cc_c99=no +ac_save_CC=$CC_FOR_BUILD +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_c_conftest_c99_program +_ACEOF +for ac_arg in '' -std=gnu99 -std=c99 -c99 -qlanglvl=extc1x -qlanglvl=extc99 -AC99 -D_STDC_C99= +do + CC_FOR_BUILD="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_build_prog_cc_c99=$ac_arg +fi +rm -f core conftest.err conftest.$ac_build_objext conftest.beam + test "x$ac_cv_build_prog_cc_c99" != "xno" && break +done +rm -f conftest.$ac_ext +CC_FOR_BUILD=$ac_save_CC +fi + +if test "x$ac_cv_build_prog_cc_c99" = xno +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +printf "%s\n" "unsupported" >&6; } +else $as_nop + if test "x$ac_cv_build_prog_cc_c99" = x +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +printf "%s\n" "none needed" >&6; } +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build_prog_cc_c99" >&5 +printf "%s\n" "$ac_cv_build_prog_cc_c99" >&6; } + CC_FOR_BUILD="$CC_FOR_BUILD $ac_cv_build_prog_cc_c99" +fi + ac_cv_prog_cc_stdc=$ac_cv_build_prog_cc_c99 + ac_prog_cc_stdc=c99 +fi +fi +if test x$ac_prog_cc_stdc = xno +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC_FOR_BUILD option to enable C89 features" >&5 +printf %s "checking for $CC_FOR_BUILD option to enable C89 features... " >&6; } +if test ${ac_cv_build_prog_cc_c89+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_cv_build_prog_cc_c89=no +ac_save_CC=$CC_FOR_BUILD +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_c_conftest_c89_program +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC_FOR_BUILD="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_build_prog_cc_c89=$ac_arg +fi +rm -f core conftest.err conftest.$ac_build_objext conftest.beam + test "x$ac_cv_build_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC_FOR_BUILD=$ac_save_CC +fi + +if test "x$ac_cv_build_prog_cc_c89" = xno +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +printf "%s\n" "unsupported" >&6; } +else $as_nop + if test "x$ac_cv_build_prog_cc_c89" = x +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +printf "%s\n" "none needed" >&6; } +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build_prog_cc_c89" >&5 +printf "%s\n" "$ac_cv_build_prog_cc_c89" >&6; } + CC_FOR_BUILD="$CC_FOR_BUILD $ac_cv_build_prog_cc_c89" +fi + ac_cv_prog_cc_stdc=$ac_cv_build_prog_cc_c89 + ac_prog_cc_stdc=c89 +fi +fi + +ac_ext=c +ac_cpp='$CPP_FOR_BUILD $CPPFLAGS_FOR_BUILD' +ac_compile='$CC_FOR_BUILD -c $CFLAGS_FOR_BUILD $CPPFLAGS_FOR_BUILD conftest.$ac_ext >&5' +ac_link='$CC_FOR_BUILD -o conftest$ac_build_exeext $CFLAGS_FOR_BUILD $CPPFLAGS_FOR_BUILD $LDFLAGS_FOR_BUILD conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_build_c_compiler_gnu + + + ac_ext=c +ac_cpp='$CPP_FOR_BUILD $CPPFLAGS_FOR_BUILD' +ac_compile='$CC_FOR_BUILD -c $CFLAGS_FOR_BUILD $CPPFLAGS_FOR_BUILD conftest.$ac_ext >&5' +ac_link='$CC_FOR_BUILD -o conftest$ac_build_exeext $CFLAGS_FOR_BUILD $CPPFLAGS_FOR_BUILD $LDFLAGS_FOR_BUILD conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_build_c_compiler_gnu +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC_FOR_BUILD understands -c and -o together" >&5 +printf %s "checking whether $CC_FOR_BUILD understands -c and -o together... " >&6; } +if test ${am_cv_build_prog_cc_c_o+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF + # Make sure it works both with $CC and with simple cc. + # Following AC_PROG_CC_C_O, we do the test twice because some + # compilers refuse to overwrite an existing .o file with -o, + # though they will create one. + am_cv_build_prog_cc_c_o=yes + for am_i in 1 2; do + if { echo "$as_me:$LINENO: $CC_FOR_BUILD -c conftest.$ac_ext -o conftest2.$ac_build_objext" >&5 + ($CC_FOR_BUILD -c conftest.$ac_ext -o conftest2.$ac_build_objext) >&5 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } \ + && test -f conftest2.$ac_build_objext; then + : OK + else + am_cv_build_prog_cc_c_o=no + break + fi + done + rm -f core conftest* + unset am_i +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_build_prog_cc_c_o" >&5 +printf "%s\n" "$am_cv_build_prog_cc_c_o" >&6; } +if test "$am_cv_build_prog_cc_c_o" != yes; then + # Losing compiler, so override with the script. + # FIXME: It is wrong to rewrite CC. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__CC in this case, + # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" + CC_FOR_BUILD="$am_aux_dir/compile $CC_FOR_BUILD" +fi +ac_ext=c +ac_cpp='$CPP_FOR_BUILD $CPPFLAGS_FOR_BUILD' +ac_compile='$CC_FOR_BUILD -c $CFLAGS_FOR_BUILD $CPPFLAGS_FOR_BUILD conftest.$ac_ext >&5' +ac_link='$CC_FOR_BUILD -o conftest$ac_build_exeext $CFLAGS_FOR_BUILD $CPPFLAGS_FOR_BUILD $LDFLAGS_FOR_BUILD conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_build_c_compiler_gnu + + +depcc="$CC_FOR_BUILD" am_compiler_list= + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 +printf %s "checking dependency style of $depcc... " >&6; } +if test ${am_cv_build_CC_dependencies_compiler_type+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named 'D' -- because '-MD' means "put the output + # in D". + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_build_CC_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + am__universal=false + case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with + # Solaris 10 /bin/sh. + echo '/* dummy */' > sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with '-c' and '-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle '-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs. + am__obj=sub/conftest.${BUILD_OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # After this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested. + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok '-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${BUILD_OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_build_CC_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_build_CC_dependencies_compiler_type=none +fi + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_build_CC_dependencies_compiler_type" >&5 +printf "%s\n" "$am_cv_build_CC_dependencies_compiler_type" >&6; } +CCDEPMODE=depmode=$am_cv_build_CC_dependencies_compiler_type + + if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_build_CC_dependencies_compiler_type" = gcc3; then + am__fastdepCC_build_TRUE= + am__fastdepCC_build_FALSE='#' +else + am__fastdepCC_build_TRUE='#' + am__fastdepCC_build_FALSE= +fi + + + +if test ${was_set_c_compiler_gnu} +then : + ac_cv_c_compiler_gnu=$saved_c_compiler_gnu +fi + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 +printf %s "checking whether the C compiler works... " >&6; } +ac_link_default=`printf "%s\n" "$ac_link" | sed 's/ -o *conftest[^ ]*//'` + +# The possible output files: +ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" + +ac_rmfiles= +for ac_file in $ac_files +do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + * ) ac_rmfiles="$ac_rmfiles $ac_file";; + esac +done +rm -f $ac_rmfiles + +if { { ac_try="$ac_link_default" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +printf "%s\n" "$ac_try_echo"; } >&5 + (eval "$ac_link_default") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +then : + # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. +# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' +# in a Makefile. We should not override ac_cv_exeext if it was cached, +# so that the user can short-circuit this test for compilers unknown to +# Autoconf. +for ac_file in $ac_files '' +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + if test ${ac_cv_build_exeext+y} && test "$ac_cv_build_exeext" != no; + then :; else + ac_cv_build_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + fi + # We set ac_cv_exeext here because the later test for it is not + # safe: cross compilers may not add the suffix if given an `-o' + # argument, so we may need to know it at that point already. + # Even if this section looks crufty: it has the advantage of + # actually working. + break;; + * ) + break;; + esac +done +test "$ac_cv_build_exeext" = no && ac_cv_build_exeext= + +else $as_nop + ac_file='' +fi +if test -z "$ac_file" +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +printf "%s\n" "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "C compiler cannot create executables +See \`config.log' for more details" "$LINENO" 5; } +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 +printf %s "checking for C compiler default output file name... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 +printf "%s\n" "$ac_file" >&6; } +ac_build_exeext=$ac_cv_build_exeext + +rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_build_exeext b.out +ac_clean_files=$ac_clean_files_save +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 +printf %s "checking for suffix of executables... " >&6; } +if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +printf "%s\n" "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +then : + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + *.* ) ac_cv_build_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + break;; + * ) break;; + esac +done +else $as_nop + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest conftest$ac_cv_build_exeext +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build_exeext" >&5 +printf "%s\n" "$ac_cv_build_exeext" >&6; } + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_build_exeext +ac_build_exeext=$BUILD_EXEEXT +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main (void) +{ +FILE *f = fopen ("conftest.out", "w"); + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +ac_clean_files="$ac_clean_files conftest.out" +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 +printf %s "checking whether we are cross compiling... " >&6; } +if test "$cross_compiling_build" != yes; then + { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +printf "%s\n" "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if { ac_try='./conftest$ac_cv_build_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +printf "%s\n" "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then + cross_compiling_build=no + else + if test "$cross_compiling_build" = maybe; then + cross_compiling_build=yes + else + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot run C compiled programs. +If you meant to cross compile, use \`--build'. +See \`config.log' for more details" "$LINENO" 5; } + fi + fi +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $cross_compiling_build" >&5 +printf "%s\n" "$cross_compiling_build" >&6; } + +rm -f conftest.$ac_ext conftest$ac_cv_build_exeext conftest.out +ac_clean_files=$ac_clean_files_save + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 +printf %s "checking for suffix of object files... " >&6; } +if test ${ac_cv_build_objext+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +printf "%s\n" "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +then : + for ac_file in conftest.o conftest.obj conftest.*; do + test -f "$ac_file" || continue; + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; + *) ac_cv_build_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else $as_nop + printf "%s\n" "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of object files: cannot compile +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest.$ac_cv_build_objext conftest.$ac_ext +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build_objext" >&5 +printf "%s\n" "$ac_cv_build_objext" >&6; } +OBJEXT=$ac_cv_build_objext +ac_build_objext=$BUILD_OBJEXT + +ac_ext=c +ac_cpp='$CPP_FOR_BUILD $CPPFLAGS_FOR_BUILD' +ac_compile='$CC_FOR_BUILD -c $CFLAGS_FOR_BUILD $CPPFLAGS_FOR_BUILD conftest.$ac_ext >&5' +ac_link='$CC_FOR_BUILD -o conftest$ac_build_exeext $CFLAGS_FOR_BUILD $CPPFLAGS_FOR_BUILD $LDFLAGS_FOR_BUILD conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_build_c_compiler_gnu +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 +printf %s "checking how to run the C preprocessor... " >&6; } +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP_FOR_BUILD" && test -d "$CPP_FOR_BUILD"; then + CPP_FOR_BUILD= +fi +if test -z "$CPP_FOR_BUILD"; then + if test ${ac_cv_build_prog_CPP+y} +then : + printf %s "(cached) " >&6 +else $as_nop + # Double quotes because $CC needs to be expanded + for CPP_FOR_BUILD in "$CC_FOR_BUILD -E" "$CC_FOR_BUILD -E -traditional-cpp" cpp /lib/cpp + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO" +then : + +else $as_nop + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO" +then : + # Broken: success on invalid input. +continue +else $as_nop + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok +then : + break +fi + + done + ac_cv_build_prog_CPP=$CPP_FOR_BUILD + +fi + CPP_FOR_BUILD=$ac_cv_build_prog_CPP +else + ac_cv_build_prog_CPP=$CPP_FOR_BUILD +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CPP_FOR_BUILD" >&5 +printf "%s\n" "$CPP_FOR_BUILD" >&6; } +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO" +then : + +else $as_nop + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO" +then : + # Broken: success on invalid input. +continue +else $as_nop + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok +then : + +else $as_nop + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "C preprocessor \"$CPP_FOR_BUILD\" fails sanity check +See \`config.log' for more details" "$LINENO" 5; } +fi + +ac_ext=c +ac_cpp='$CPP_FOR_BUILD $CPPFLAGS_FOR_BUILD' +ac_compile='$CC_FOR_BUILD -c $CFLAGS_FOR_BUILD $CPPFLAGS_FOR_BUILD conftest.$ac_ext >&5' +ac_link='$CC_FOR_BUILD -o conftest$ac_build_exeext $CFLAGS_FOR_BUILD $CPPFLAGS_FOR_BUILD $LDFLAGS_FOR_BUILD conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_build_c_compiler_gnu + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +EXEEXT=$ac_cv_exeext +BUILD_EXEEXT=$ac_cv_build_exeext; ac_build_exeext=$ac_cv_build_exeext +OBJEXT=$ac_cv_objext +BUILD_OBJEXT=$ac_cv_build_objext; ac_build_objext=$ac_cv_build_objext +CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type +CCDEPMODE_FOR_BUILD=depmode=$am_cv_build_CC_dependencies_compiler_type + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C compiler vendor" >&5 +printf %s "checking for C compiler vendor... " >&6; } +if test ${ax_cv_c_compiler_vendor+y} +then : + printf %s "(cached) " >&6 +else $as_nop + + vendors=" + intel: __ICC,__ECC,__INTEL_COMPILER + ibm: __xlc__,__xlC__,__IBMC__,__IBMCPP__,__ibmxl__ + pathscale: __PATHCC__,__PATHSCALE__ + clang: __clang__ + cray: _CRAYC + fujitsu: __FUJITSU + sdcc: SDCC,__SDCC + sx: _SX + nvhpc: __NVCOMPILER + portland: __PGI + pcc: __PCC__ + gnu: __GNUC__ + sun: __SUNPRO_C,__SUNPRO_CC,__SUNPRO_F90,__SUNPRO_F95 + hp: __HP_cc,__HP_aCC + dec: __DECC,__DECCXX,__DECC_VER,__DECCXX_VER + borland: __BORLANDC__,__CODEGEARC__,__TURBOC__ + comeau: __COMO__ + kai: __KCC + lcc: __LCC__ + sgi: __sgi,sgi + microsoft: _MSC_VER + metrowerks: __MWERKS__ + watcom: __WATCOMC__ + tcc: __TINYC__ + unknown: UNKNOWN + " + for ventest in $vendors; do + case $ventest in + *:) + vendor=$ventest + continue + ;; + *) + vencpp="defined("`echo $ventest | sed 's/,/) || defined(/g'`")" + ;; + esac + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + +#if !($vencpp) + thisisanerror; +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + break +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + done + + ax_cv_c_compiler_vendor=`echo $vendor | cut -d: -f1` + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_c_compiler_vendor" >&5 +printf "%s\n" "$ax_cv_c_compiler_vendor" >&6; } + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 +printf %s "checking host system type... " >&6; } +if test ${ac_cv_host+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test "x$host_alias" = x; then + ac_cv_host=$ac_cv_build +else + ac_cv_host=`$SHELL "${ac_aux_dir}config.sub" $host_alias` || + as_fn_error $? "$SHELL ${ac_aux_dir}config.sub $host_alias failed" "$LINENO" 5 +fi + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 +printf "%s\n" "$ac_cv_host" >&6; } +case $ac_cv_host in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; +esac +host=$ac_cv_host +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_host +shift +host_cpu=$1 +host_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +host_os=$* +IFS=$ac_save_IFS +case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 +printf %s "checking for a sed that does not truncate output... " >&6; } +if test ${ac_cv_path_SED+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ + for ac_i in 1 2 3 4 5 6 7; do + ac_script="$ac_script$as_nl$ac_script" + done + echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed + { ac_script=; unset ac_script;} + if test -z "$SED"; then + ac_path_SED_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_prog in sed gsed + do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_SED="$as_dir$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_SED" || continue +# Check for GNU ac_path_SED and select it if it is found. + # Check for GNU $ac_path_SED +case `"$ac_path_SED" --version 2>&1` in +*GNU*) + ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; +*) + ac_count=0 + printf %s 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + printf "%s\n" '' >> "conftest.nl" + "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_SED_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_SED="$ac_path_SED" + ac_path_SED_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_SED_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_SED"; then + as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 + fi +else + ac_cv_path_SED=$SED +fi + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 +printf "%s\n" "$ac_cv_path_SED" >&6; } + SED="$ac_cv_path_SED" + rm -f conftest.sed + + + + + + +# Check whether --enable-portable-binary was given. +if test ${enable_portable_binary+y} +then : + enableval=$enable_portable_binary; acx_maxopt_portable=$enableval +else $as_nop + acx_maxopt_portable=no +fi + + +# Try to determine "good" native compiler flags if none specified via CFLAGS +if test "x$ac_test_CFLAGS" = "x"; then + case $ax_cv_c_compiler_vendor in + dec) CFLAGS="$CFLAGS -newc -w0 -O5 -ansi_alias -ansi_args -fp_reorder -tune host" + if test "x$acx_maxopt_portable" = xno; then + CFLAGS="$CFLAGS -arch host" + fi;; + + sun) CFLAGS="$CFLAGS -native -fast -xO5 -dalign" + if test "x$acx_maxopt_portable" = xyes; then + CFLAGS="$CFLAGS -xarch=generic" + fi;; + + hp) CFLAGS="$CFLAGS +Oall +Optrs_ansi +DSnative" + if test "x$acx_maxopt_portable" = xyes; then + CFLAGS="$CFLAGS +DAportable" + fi;; + + ibm) if test "x$acx_maxopt_portable" = xno; then + xlc_opt="-qarch=auto -qtune=auto" + else + xlc_opt="-qtune=auto" + fi + as_CACHEVAR=`printf "%s\n" "ax_cv_check_cflags__$xlc_opt" | $as_tr_sh` +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts $xlc_opt" >&5 +printf %s "checking whether C compiler accepts $xlc_opt... " >&6; } +if eval test \${$as_CACHEVAR+y} +then : + printf %s "(cached) " >&6 +else $as_nop + + ax_check_save_flags=$CFLAGS + CFLAGS="$CFLAGS $xlc_opt" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + eval "$as_CACHEVAR=yes" +else $as_nop + eval "$as_CACHEVAR=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + CFLAGS=$ax_check_save_flags +fi +eval ac_res=\$$as_CACHEVAR + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } +if eval test \"x\$"$as_CACHEVAR"\" = x"yes" +then : + CFLAGS="$CFLAGS -O3 -qansialias -w $xlc_opt" +else $as_nop + CFLAGS="$CFLAGS -O3 -qansialias -w" + echo "******************************************************" + echo "* You seem to have the IBM C compiler. It is *" + echo "* recommended for best performance that you use: *" + echo "* *" + echo "* CFLAGS=-O3 -qarch=xxx -qtune=xxx -qansialias -w *" + echo "* ^^^ ^^^ *" + echo "* where xxx is pwr2, pwr3, 604, or whatever kind of *" + echo "* CPU you have. (Set the CFLAGS environment var. *" + echo "* and re-run configure.) For more info, man cc. *" + echo "******************************************************" +fi + + ;; + + intel) CFLAGS="$CFLAGS -O3 -ansi_alias" + if test "x$acx_maxopt_portable" = xno; then + icc_archflag=unknown + icc_flags="" + case $host_cpu in + i686*|x86_64*) + # icc accepts gcc assembly syntax, so these should work: + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for x86 cpuid 0 output" >&5 +printf %s "checking for x86 cpuid 0 output... " >&6; } +if test ${ax_cv_gcc_x86_cpuid_0+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test "$cross_compiling" = yes +then : + ax_cv_gcc_x86_cpuid_0=unknown +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main (void) +{ + + int op = 0, level = 0, eax, ebx, ecx, edx; + FILE *f; + __asm__ __volatile__ ("xchg %%ebx, %1\n" + "cpuid\n" + "xchg %%ebx, %1\n" + : "=a" (eax), "=r" (ebx), "=c" (ecx), "=d" (edx) + : "a" (op), "2" (level)); + + f = fopen("conftest_cpuid", "w"); if (!f) return 1; + fprintf(f, "%x:%x:%x:%x\n", eax, ebx, ecx, edx); + fclose(f); + return 0; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO" +then : + ax_cv_gcc_x86_cpuid_0=`cat conftest_cpuid`; rm -f conftest_cpuid +else $as_nop + ax_cv_gcc_x86_cpuid_0=unknown; rm -f conftest_cpuid +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_gcc_x86_cpuid_0" >&5 +printf "%s\n" "$ax_cv_gcc_x86_cpuid_0" >&6; } +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for x86 cpuid 1 output" >&5 +printf %s "checking for x86 cpuid 1 output... " >&6; } +if test ${ax_cv_gcc_x86_cpuid_1+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test "$cross_compiling" = yes +then : + ax_cv_gcc_x86_cpuid_1=unknown +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main (void) +{ + + int op = 1, level = 0, eax, ebx, ecx, edx; + FILE *f; + __asm__ __volatile__ ("xchg %%ebx, %1\n" + "cpuid\n" + "xchg %%ebx, %1\n" + : "=a" (eax), "=r" (ebx), "=c" (ecx), "=d" (edx) + : "a" (op), "2" (level)); + + f = fopen("conftest_cpuid", "w"); if (!f) return 1; + fprintf(f, "%x:%x:%x:%x\n", eax, ebx, ecx, edx); + fclose(f); + return 0; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO" +then : + ax_cv_gcc_x86_cpuid_1=`cat conftest_cpuid`; rm -f conftest_cpuid +else $as_nop + ax_cv_gcc_x86_cpuid_1=unknown; rm -f conftest_cpuid +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_gcc_x86_cpuid_1" >&5 +printf "%s\n" "$ax_cv_gcc_x86_cpuid_1" >&6; } +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + + case $ax_cv_gcc_x86_cpuid_0 in # see AX_GCC_ARCHFLAG + *:756e6547:6c65746e:49656e69) # Intel + case $ax_cv_gcc_x86_cpuid_1 in + *0?6[78ab]?:*:*:*|?6[78ab]?:*:*:*|6[78ab]?:*:*:*) icc_flags="-xK" ;; + *0?6[9d]?:*:*:*|?6[9d]?:*:*:*|6[9d]?:*:*:*|*1?65?:*:*:*) icc_flags="-xSSE2 -xB -xK" ;; + *0?6e?:*:*:*|?6e?:*:*:*|6e?:*:*:*) icc_flags="-xSSE3 -xP -xO -xB -xK" ;; + *0?6f?:*:*:*|?6f?:*:*:*|6f?:*:*:*|*1?66?:*:*:*) icc_flags="-xSSSE3 -xT -xB -xK" ;; + *1?6[7d]?:*:*:*) icc_flags="-xSSE4.1 -xS -xT -xB -xK" ;; + *1?6[aef]?:*:*:*|*2?6[5cef]?:*:*:*) icc_flags="-xSSE4.2 -xS -xT -xB -xK" ;; + *2?6[ad]?:*:*:*) icc_flags="-xAVX -SSE4.2 -xS -xT -xB -xK" ;; + *3?6[ae]?:*:*:*) icc_flags="-xCORE-AVX-I -xAVX -SSE4.2 -xS -xT -xB -xK" ;; + *3?6[cf]?:*:*:*|*4?6[56]?:*:*:*) icc_flags="-xCORE-AVX2 -xCORE-AVX-I -xAVX -SSE4.2 -xS -xT -xB -xK" ;; + *000?f[346]?:*:*:*|?f[346]?:*:*:*|f[346]?:*:*:*) icc_flags="-xSSE3 -xP -xO -xN -xW -xK" ;; + *00??f??:*:*:*|??f??:*:*:*|?f??:*:*:*|f??:*:*:*) icc_flags="-xSSE2 -xN -xW -xK" ;; + esac ;; + esac ;; + esac + if test "x$icc_flags" != x; then + for flag in $icc_flags; do + as_CACHEVAR=`printf "%s\n" "ax_cv_check_cflags__$flag" | $as_tr_sh` +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts $flag" >&5 +printf %s "checking whether C compiler accepts $flag... " >&6; } +if eval test \${$as_CACHEVAR+y} +then : + printf %s "(cached) " >&6 +else $as_nop + + ax_check_save_flags=$CFLAGS + CFLAGS="$CFLAGS $flag" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + eval "$as_CACHEVAR=yes" +else $as_nop + eval "$as_CACHEVAR=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + CFLAGS=$ax_check_save_flags +fi +eval ac_res=\$$as_CACHEVAR + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } +if eval test \"x\$"$as_CACHEVAR"\" = x"yes" +then : + icc_archflag=$flag; break +else $as_nop + : +fi + + done + fi + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for icc architecture flag" >&5 +printf %s "checking for icc architecture flag... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $icc_archflag" >&5 +printf "%s\n" "$icc_archflag" >&6; } + if test "x$icc_archflag" != xunknown; then + CFLAGS="$CFLAGS $icc_archflag" + fi + fi + ;; + + nvhpc) + # default optimization flags for nvhpc + CFLAGS="$CFLAGS -O3" + ;; + + gnu) + # default optimization flags for gcc on all systems + CFLAGS="$CFLAGS -O3 -fomit-frame-pointer" + + # -malign-double for x86 systems + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -malign-double" >&5 +printf %s "checking whether C compiler accepts -malign-double... " >&6; } +if test ${ax_cv_check_cflags___malign_double+y} +then : + printf %s "(cached) " >&6 +else $as_nop + + ax_check_save_flags=$CFLAGS + CFLAGS="$CFLAGS -malign-double" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ax_cv_check_cflags___malign_double=yes +else $as_nop + ax_cv_check_cflags___malign_double=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + CFLAGS=$ax_check_save_flags +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___malign_double" >&5 +printf "%s\n" "$ax_cv_check_cflags___malign_double" >&6; } +if test "x$ax_cv_check_cflags___malign_double" = xyes +then : + CFLAGS="$CFLAGS -malign-double" +else $as_nop + : +fi + + + # -fstrict-aliasing for gcc-2.95+ + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -fstrict-aliasing" >&5 +printf %s "checking whether C compiler accepts -fstrict-aliasing... " >&6; } +if test ${ax_cv_check_cflags___fstrict_aliasing+y} +then : + printf %s "(cached) " >&6 +else $as_nop + + ax_check_save_flags=$CFLAGS + CFLAGS="$CFLAGS -fstrict-aliasing" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ax_cv_check_cflags___fstrict_aliasing=yes +else $as_nop + ax_cv_check_cflags___fstrict_aliasing=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + CFLAGS=$ax_check_save_flags +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___fstrict_aliasing" >&5 +printf "%s\n" "$ax_cv_check_cflags___fstrict_aliasing" >&6; } +if test "x$ax_cv_check_cflags___fstrict_aliasing" = xyes +then : + CFLAGS="$CFLAGS -fstrict-aliasing" +else $as_nop + : +fi + + + # note that we enable "unsafe" fp optimization with other compilers, too + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -ffast-math" >&5 +printf %s "checking whether C compiler accepts -ffast-math... " >&6; } +if test ${ax_cv_check_cflags___ffast_math+y} +then : + printf %s "(cached) " >&6 +else $as_nop + + ax_check_save_flags=$CFLAGS + CFLAGS="$CFLAGS -ffast-math" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ax_cv_check_cflags___ffast_math=yes +else $as_nop + ax_cv_check_cflags___ffast_math=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + CFLAGS=$ax_check_save_flags +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___ffast_math" >&5 +printf "%s\n" "$ax_cv_check_cflags___ffast_math" >&6; } +if test "x$ax_cv_check_cflags___ffast_math" = xyes +then : + CFLAGS="$CFLAGS -ffast-math" +else $as_nop + : +fi + + + + + + + + +# Check whether --with-gcc-arch was given. +if test ${with_gcc_arch+y} +then : + withval=$with_gcc_arch; ax_gcc_arch=$withval +else $as_nop + ax_gcc_arch=yes +fi + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for gcc architecture flag" >&5 +printf %s "checking for gcc architecture flag... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: " >&5 +printf "%s\n" "" >&6; } +if test ${ax_cv_gcc_archflag+y} +then : + printf %s "(cached) " >&6 +else $as_nop + +ax_cv_gcc_archflag="unknown" + +if test "$GCC" = yes; then + +if test "x$ax_gcc_arch" = xyes; then +ax_gcc_arch="" +if test "$cross_compiling" = no; then +case $host_cpu in + i[3456]86*|x86_64*|amd64*) # use cpuid codes + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for x86 cpuid 0 output" >&5 +printf %s "checking for x86 cpuid 0 output... " >&6; } +if test ${ax_cv_gcc_x86_cpuid_0+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test "$cross_compiling" = yes +then : + ax_cv_gcc_x86_cpuid_0=unknown +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main (void) +{ + + int op = 0, level = 0, eax, ebx, ecx, edx; + FILE *f; + __asm__ __volatile__ ("xchg %%ebx, %1\n" + "cpuid\n" + "xchg %%ebx, %1\n" + : "=a" (eax), "=r" (ebx), "=c" (ecx), "=d" (edx) + : "a" (op), "2" (level)); + + f = fopen("conftest_cpuid", "w"); if (!f) return 1; + fprintf(f, "%x:%x:%x:%x\n", eax, ebx, ecx, edx); + fclose(f); + return 0; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO" +then : + ax_cv_gcc_x86_cpuid_0=`cat conftest_cpuid`; rm -f conftest_cpuid +else $as_nop + ax_cv_gcc_x86_cpuid_0=unknown; rm -f conftest_cpuid +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_gcc_x86_cpuid_0" >&5 +printf "%s\n" "$ax_cv_gcc_x86_cpuid_0" >&6; } +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for x86 cpuid 1 output" >&5 +printf %s "checking for x86 cpuid 1 output... " >&6; } +if test ${ax_cv_gcc_x86_cpuid_1+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test "$cross_compiling" = yes +then : + ax_cv_gcc_x86_cpuid_1=unknown +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main (void) +{ + + int op = 1, level = 0, eax, ebx, ecx, edx; + FILE *f; + __asm__ __volatile__ ("xchg %%ebx, %1\n" + "cpuid\n" + "xchg %%ebx, %1\n" + : "=a" (eax), "=r" (ebx), "=c" (ecx), "=d" (edx) + : "a" (op), "2" (level)); + + f = fopen("conftest_cpuid", "w"); if (!f) return 1; + fprintf(f, "%x:%x:%x:%x\n", eax, ebx, ecx, edx); + fclose(f); + return 0; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO" +then : + ax_cv_gcc_x86_cpuid_1=`cat conftest_cpuid`; rm -f conftest_cpuid +else $as_nop + ax_cv_gcc_x86_cpuid_1=unknown; rm -f conftest_cpuid +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_gcc_x86_cpuid_1" >&5 +printf "%s\n" "$ax_cv_gcc_x86_cpuid_1" >&6; } +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + + case $ax_cv_gcc_x86_cpuid_0 in + *:756e6547:6c65746e:49656e69) # Intel + case $ax_cv_gcc_x86_cpuid_1 in + *5[4578]?:*:*:*) ax_gcc_arch="pentium-mmx pentium" ;; + *5[123]?:*:*:*) ax_gcc_arch=pentium ;; + *0?61?:*:*:*|?61?:*:*:*|61?:*:*:*) ax_gcc_arch=pentiumpro ;; + *0?6[356]?:*:*:*|?6[356]?:*:*:*|6[356]?:*:*:*) ax_gcc_arch="pentium2 pentiumpro" ;; + *0?6[78ab]?:*:*:*|?6[78ab]?:*:*:*|6[78ab]?:*:*:*) ax_gcc_arch="pentium3 pentiumpro" ;; + *0?6[9d]?:*:*:*|?6[9d]?:*:*:*|6[9d]?:*:*:*|*1?65?:*:*:*) ax_gcc_arch="pentium-m pentium3 pentiumpro" ;; + *0?6e?:*:*:*|?6e?:*:*:*|6e?:*:*:*) ax_gcc_arch="yonah pentium-m pentium3 pentiumpro" ;; + *0?6f?:*:*:*|?6f?:*:*:*|6f?:*:*:*|*1?66?:*:*:*) ax_gcc_arch="core2 pentium-m pentium3 pentiumpro" ;; + *1?6[7d]?:*:*:*) ax_gcc_arch="penryn core2 pentium-m pentium3 pentiumpro" ;; + *1?6[aef]?:*:*:*|*2?6e?:*:*:*) ax_gcc_arch="nehalem corei7 core2 pentium-m pentium3 pentiumpro" ;; + *2?6[5cf]?:*:*:*) ax_gcc_arch="westmere corei7 core2 pentium-m pentium3 pentiumpro" ;; + *2?6[ad]?:*:*:*) ax_gcc_arch="sandybridge corei7-avx corei7 core2 pentium-m pentium3 pentiumpro" ;; + *3?6[ae]?:*:*:*) ax_gcc_arch="ivybridge core-avx-i corei7-avx corei7 core2 pentium-m pentium3 pentiumpro" ;; + *3?6[cf]?:*:*:*|*4?6[56]?:*:*:*) ax_gcc_arch="haswell core-avx2 core-avx-i corei7-avx corei7 core2 pentium-m pentium3 pentiumpro" ;; + *3?6d?:*:*:*|*4?6[7f]?:*:*:*|*5?66?:*:*:*) ax_gcc_arch="broadwell core-avx2 core-avx-i corei7-avx corei7 core2 pentium-m pentium3 pentiumpro" ;; + *1?6c?:*:*:*|*2?6[67]?:*:*:*|*3?6[56]?:*:*:*) ax_gcc_arch="bonnell atom core2 pentium-m pentium3 pentiumpro" ;; + *3?67?:*:*:*|*[45]?6[ad]?:*:*:*) ax_gcc_arch="silvermont atom core2 pentium-m pentium3 pentiumpro" ;; + *000?f[012]?:*:*:*|?f[012]?:*:*:*|f[012]?:*:*:*) ax_gcc_arch="pentium4 pentiumpro" ;; + *000?f[346]?:*:*:*|?f[346]?:*:*:*|f[346]?:*:*:*) ax_gcc_arch="nocona prescott pentium4 pentiumpro" ;; + # fallback + *5??:*:*:*) ax_gcc_arch=pentium ;; + *??6??:*:*:*) ax_gcc_arch="core2 pentiumpro" ;; + *6??:*:*:*) ax_gcc_arch=pentiumpro ;; + *00??f??:*:*:*|??f??:*:*:*|?f??:*:*:*|f??:*:*:*) ax_gcc_arch="pentium4 pentiumpro" ;; + esac ;; + *:68747541:444d4163:69746e65) # AMD + case $ax_cv_gcc_x86_cpuid_1 in + *5[67]?:*:*:*) ax_gcc_arch=k6 ;; + *5[8]?:*:*:*) ax_gcc_arch="k6-2 k6" ;; + *5[9d]?:*:*:*) ax_gcc_arch="k6-3 k6" ;; + *6[12]?:*:*:*) ax_gcc_arch="athlon k7" ;; + *6[34]?:*:*:*) ax_gcc_arch="athlon-tbird k7" ;; + *6[678a]?:*:*:*) ax_gcc_arch="athlon-xp athlon-4 athlon k7" ;; + *000?f[4578bcef]?:*:*:*|?f[4578bcef]?:*:*:*|f[4578bcef]?:*:*:*|*001?f[4578bcf]?:*:*:*|1?f[4578bcf]?:*:*:*) ax_gcc_arch="athlon64 k8" ;; + *002?f[13457bcf]?:*:*:*|2?f[13457bcf]?:*:*:*|*004?f[138bcf]?:*:*:*|4?f[138bcf]?:*:*:*|*005?f[df]?:*:*:*|5?f[df]?:*:*:*|*006?f[8bcf]?:*:*:*|6?f[8bcf]?:*:*:*|*007?f[cf]?:*:*:*|7?f[cf]?:*:*:*|*00c?f1?:*:*:*|c?f1?:*:*:*|*020?f3?:*:*:*|20?f3?:*:*:*) ax_gcc_arch="athlon64-sse3 k8-sse3 athlon64 k8" ;; + *010?f[245689a]?:*:*:*|10?f[245689a]?:*:*:*|*030?f1?:*:*:*|30?f1?:*:*:*) ax_gcc_arch="barcelona amdfam10 k8" ;; + *050?f[12]?:*:*:*|50?f[12]?:*:*:*) ax_gcc_arch="btver1 amdfam10 k8" ;; + *060?f1?:*:*:*|60?f1?:*:*:*) ax_gcc_arch="bdver1 amdfam10 k8" ;; + *060?f2?:*:*:*|60?f2?:*:*:*|*061?f[03]?:*:*:*|61?f[03]?:*:*:*) ax_gcc_arch="bdver2 bdver1 amdfam10 k8" ;; + *063?f0?:*:*:*|63?f0?:*:*:*) ax_gcc_arch="bdver3 bdver2 bdver1 amdfam10 k8" ;; + *07[03]?f0?:*:*:*|7[03]?f0?:*:*:*) ax_gcc_arch="btver2 btver1 amdfam10 k8" ;; + # fallback + *0[13]??f??:*:*:*|[13]??f??:*:*:*) ax_gcc_arch="barcelona amdfam10 k8" ;; + *020?f??:*:*:*|20?f??:*:*:*) ax_gcc_arch="athlon64-sse3 k8-sse3 athlon64 k8" ;; + *05??f??:*:*:*|5??f??:*:*:*) ax_gcc_arch="btver1 amdfam10 k8" ;; + *060?f??:*:*:*|60?f??:*:*:*) ax_gcc_arch="bdver1 amdfam10 k8" ;; + *061?f??:*:*:*|61?f??:*:*:*) ax_gcc_arch="bdver2 bdver1 amdfam10 k8" ;; + *06??f??:*:*:*|6??f??:*:*:*) ax_gcc_arch="bdver3 bdver2 bdver1 amdfam10 k8" ;; + *070?f??:*:*:*|70?f??:*:*:*) ax_gcc_arch="btver2 btver1 amdfam10 k8" ;; + *???f??:*:*:*) ax_gcc_arch="amdfam10 k8" ;; + esac ;; + *:746e6543:736c7561:48727561) # IDT / VIA (Centaur) + case $ax_cv_gcc_x86_cpuid_1 in + *54?:*:*:*) ax_gcc_arch=winchip-c6 ;; + *5[89]?:*:*:*) ax_gcc_arch=winchip2 ;; + *66?:*:*:*) ax_gcc_arch=winchip2 ;; + *6[78]?:*:*:*) ax_gcc_arch=c3 ;; + *6[9adf]?:*:*:*) ax_gcc_arch="c3-2 c3" ;; + esac ;; + esac + if test x"$ax_gcc_arch" = x; then # fallback + case $host_cpu in + i586*) ax_gcc_arch=pentium ;; + i686*) ax_gcc_arch=pentiumpro ;; + esac + fi + ;; + + sparc*) + # Extract the first word of "prtdiag", so it can be a program name with args. +set dummy prtdiag; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_path_PRTDIAG+y} +then : + printf %s "(cached) " >&6 +else $as_nop + case $PRTDIAG in + [\\/]* | ?:[\\/]*) + ac_cv_path_PRTDIAG="$PRTDIAG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_dummy="$PATH:/usr/platform/`uname -i`/sbin/:/usr/platform/`uname -m`/sbin/" +for as_dir in $as_dummy +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_path_PRTDIAG="$as_dir$ac_word$ac_exec_ext" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + test -z "$ac_cv_path_PRTDIAG" && ac_cv_path_PRTDIAG="prtdiag" + ;; +esac +fi +PRTDIAG=$ac_cv_path_PRTDIAG +if test -n "$PRTDIAG"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PRTDIAG" >&5 +printf "%s\n" "$PRTDIAG" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + + cputype=`(((grep cpu /proc/cpuinfo | cut -d: -f2) ; ($PRTDIAG -v |grep -i sparc) ; grep -i cpu /var/run/dmesg.boot ) | head -n 1) 2> /dev/null` + cputype=`echo "$cputype" | tr -d ' -' | $SED 's/SPARCIIi/SPARCII/' |tr $as_cr_LETTERS $as_cr_letters` + case $cputype in + *ultrasparciv*) ax_gcc_arch="ultrasparc4 ultrasparc3 ultrasparc v9" ;; + *ultrasparciii*) ax_gcc_arch="ultrasparc3 ultrasparc v9" ;; + *ultrasparc*) ax_gcc_arch="ultrasparc v9" ;; + *supersparc*|*tms390z5[05]*) ax_gcc_arch="supersparc v8" ;; + *hypersparc*|*rt62[056]*) ax_gcc_arch="hypersparc v8" ;; + *cypress*) ax_gcc_arch=cypress ;; + esac ;; + + alphaev5) ax_gcc_arch=ev5 ;; + alphaev56) ax_gcc_arch=ev56 ;; + alphapca56) ax_gcc_arch="pca56 ev56" ;; + alphapca57) ax_gcc_arch="pca57 pca56 ev56" ;; + alphaev6) ax_gcc_arch=ev6 ;; + alphaev67) ax_gcc_arch=ev67 ;; + alphaev68) ax_gcc_arch="ev68 ev67" ;; + alphaev69) ax_gcc_arch="ev69 ev68 ev67" ;; + alphaev7) ax_gcc_arch="ev7 ev69 ev68 ev67" ;; + alphaev79) ax_gcc_arch="ev79 ev7 ev69 ev68 ev67" ;; + + powerpc*) + cputype=`((grep cpu /proc/cpuinfo | head -n 1 | cut -d: -f2 | cut -d, -f1 | $SED 's/ //g') ; /usr/bin/machine ; /bin/machine; grep CPU /var/run/dmesg.boot | head -n 1 | cut -d" " -f2) 2> /dev/null` + cputype=`echo $cputype | $SED -e 's/ppc//g;s/ *//g'` + case $cputype in + *750*) ax_gcc_arch="750 G3" ;; + *740[0-9]*) ax_gcc_arch="$cputype 7400 G4" ;; + *74[4-5][0-9]*) ax_gcc_arch="$cputype 7450 G4" ;; + *74[0-9][0-9]*) ax_gcc_arch="$cputype G4" ;; + *970*) ax_gcc_arch="970 G5 power4";; + *POWER4*|*power4*|*gq*) ax_gcc_arch="power4 970";; + *POWER5*|*power5*|*gr*|*gs*) ax_gcc_arch="power5 power4 970";; + 603ev|8240) ax_gcc_arch="$cputype 603e 603";; + *POWER7*) ax_gcc_arch="power7";; + *POWER8*) ax_gcc_arch="power8";; + *POWER9*) ax_gcc_arch="power9";; + *POWER10*) ax_gcc_arch="power10";; + *) ax_gcc_arch=$cputype ;; + esac + ax_gcc_arch="$ax_gcc_arch powerpc" + ;; + aarch64) + cpuimpl=`grep 'CPU implementer' /proc/cpuinfo 2> /dev/null | cut -d: -f2 | tr -d " " | head -n 1` + cpuarch=`grep 'CPU architecture' /proc/cpuinfo 2> /dev/null | cut -d: -f2 | tr -d " " | head -n 1` + cpuvar=`grep 'CPU variant' /proc/cpuinfo 2> /dev/null | cut -d: -f2 | tr -d " " | head -n 1` + case $cpuimpl in + 0x42) case $cpuarch in + 8) case $cpuvar in + 0x0) ax_gcc_arch="thunderx2t99 vulcan armv8.1-a armv8-a+lse armv8-a native" ;; + esac + ;; + esac + ;; + 0x43) case $cpuarch in + 8) case $cpuvar in + 0x0) ax_gcc_arch="thunderx armv8-a native" ;; + 0x1) ax_gcc_arch="thunderx+lse armv8.1-a armv8-a+lse armv8-a native" ;; + esac + ;; + esac + ;; + esac + ;; +esac +fi # not cross-compiling +fi # guess arch + +if test "x$ax_gcc_arch" != x -a "x$ax_gcc_arch" != xno; then +if test "x$acx_maxopt_portable" = xyes; then # if we require portable code + flag_prefixes="-mtune=" + if test "x$ax_cv_c_compiler_vendor" = xclang; then flag_prefixes="-march="; fi + # -mcpu=$arch and m$arch generate nonportable code on every arch except + # x86. And some other arches (e.g. Alpha) don't accept -mtune. Grrr. + case $host_cpu in i*86|x86_64*|amd64*) flag_prefixes="$flag_prefixes -mcpu= -m";; esac +else + flag_prefixes="-march= -mcpu= -m" +fi +for flag_prefix in $flag_prefixes; do + for arch in $ax_gcc_arch; do + flag="$flag_prefix$arch" + as_CACHEVAR=`printf "%s\n" "ax_cv_check_cflags__$flag" | $as_tr_sh` +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts $flag" >&5 +printf %s "checking whether C compiler accepts $flag... " >&6; } +if eval test \${$as_CACHEVAR+y} +then : + printf %s "(cached) " >&6 +else $as_nop + + ax_check_save_flags=$CFLAGS + CFLAGS="$CFLAGS $flag" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + eval "$as_CACHEVAR=yes" +else $as_nop + eval "$as_CACHEVAR=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + CFLAGS=$ax_check_save_flags +fi +eval ac_res=\$$as_CACHEVAR + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } +if eval test \"x\$"$as_CACHEVAR"\" = x"yes" +then : + if test "x$ax_cv_c_compiler_vendor" = xclang; then + if test "x$acx_maxopt_portable" = xyes; then + if test "x$flag" = "x-march=$arch"; then flag=-mtune=$arch; fi + fi + fi; ax_cv_gcc_archflag=$flag; break +else $as_nop + : +fi + + done + test "x$ax_cv_gcc_archflag" = xunknown || break +done +fi + +fi # $GCC=yes + +fi + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for gcc architecture flag" >&5 +printf %s "checking for gcc architecture flag... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_gcc_archflag" >&5 +printf "%s\n" "$ax_cv_gcc_archflag" >&6; } +if test "x$ax_cv_gcc_archflag" = xunknown; then + : +else + CFLAGS="$CFLAGS $ax_cv_gcc_archflag" +fi + + + # drop to -O1 for gcc 4.2 + $CC --version | + sed -e 's/.* \([0-9][0-9]*\)\.\([0-9][0-9]*\).*/\1 \2/' | + (read major minor + if test $major -eq 4 -a $minor -eq 2; then + exit 0 + fi + exit 1 + ) && CFLAGS="-O1" + ;; + + microsoft) + # default optimization flags for MSVC opt builds + CFLAGS="$CFLAGS -O2" + ;; + esac + + if test -z "$CFLAGS"; then + echo "" + echo "********************************************************" + echo "* WARNING: Don't know the best CFLAGS for this system *" + echo "* Use ./configure CFLAGS=... to specify your own flags *" + echo "* (otherwise, a default of CFLAGS=-O3 will be used) *" + echo "********************************************************" + echo "" + CFLAGS="$CFLAGS -O3" + fi + + as_CACHEVAR=`printf "%s\n" "ax_cv_check_cflags__$CFLAGS" | $as_tr_sh` +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts $CFLAGS" >&5 +printf %s "checking whether C compiler accepts $CFLAGS... " >&6; } +if eval test \${$as_CACHEVAR+y} +then : + printf %s "(cached) " >&6 +else $as_nop + + ax_check_save_flags=$CFLAGS + CFLAGS="$CFLAGS $CFLAGS" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + eval "$as_CACHEVAR=yes" +else $as_nop + eval "$as_CACHEVAR=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + CFLAGS=$ax_check_save_flags +fi +eval ac_res=\$$as_CACHEVAR + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } +if eval test \"x\$"$as_CACHEVAR"\" = x"yes" +then : + : +else $as_nop + + echo "" + echo "********************************************************" + echo "* WARNING: The guessed CFLAGS don't seem to work with *" + echo "* your compiler. *" + echo "* Use ./configure CFLAGS=... to specify your own flags *" + echo "********************************************************" + echo "" + +fi + + +fi + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports function __attribute__((__warn_unused_result__))" >&5 +printf %s "checking whether the compiler supports function __attribute__((__warn_unused_result__))... " >&6; } +if test ${ax_cv_gcc_warn_unused_result+y} +then : + printf %s "(cached) " >&6 +else $as_nop + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +__attribute__((__warn_unused_result__)) + int f(int i) { return i; } +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ax_cv_gcc_warn_unused_result=yes +else $as_nop + ax_cv_gcc_warn_unused_result=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_gcc_warn_unused_result" >&5 +printf "%s\n" "$ax_cv_gcc_warn_unused_result" >&6; } + if test "$ax_cv_gcc_warn_unused_result" = yes; then + +printf "%s\n" "#define GCC_WARN_UNUSED_RESULT __attribute__((__warn_unused_result__))" >>confdefs.h + + fi + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for __attribute__" >&5 +printf %s "checking for __attribute__... " >&6; } +if test ${ax_cv___attribute__+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + static void foo(void) __attribute__ ((unused)); + static void + foo(void) { + exit(1); + } + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ax_cv___attribute__=yes +else $as_nop + ax_cv___attribute__=no + +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv___attribute__" >&5 +printf "%s\n" "$ax_cv___attribute__" >&6; } + if test "$ax_cv___attribute__" = "yes"; then + +printf "%s\n" "#define HAVE___ATTRIBUTE__ 1" >>confdefs.h + + fi + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 +printf %s "checking for grep that handles long lines and -e... " >&6; } +if test ${ac_cv_path_GREP+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -z "$GREP"; then + ac_path_GREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_prog in grep ggrep + do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_GREP="$as_dir$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_GREP" || continue +# Check for GNU ac_path_GREP and select it if it is found. + # Check for GNU $ac_path_GREP +case `"$ac_path_GREP" --version 2>&1` in +*GNU*) + ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; +*) + ac_count=0 + printf %s 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + printf "%s\n" 'GREP' >> "conftest.nl" + "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_GREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_GREP="$ac_path_GREP" + ac_path_GREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_GREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_GREP"; then + as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_GREP=$GREP +fi + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 +printf "%s\n" "$ac_cv_path_GREP" >&6; } + GREP="$ac_cv_path_GREP" + + + echo $CXX | $GREP -e "-std=" > /dev/null 2> /dev/null + if test $? -eq 0; then + ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + ac_success=no + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CXX supports C++11 features by default" >&5 +printf %s "checking whether $CXX supports C++11 features by default... " >&6; } +if test ${ax_cv_cxx_compile_cxx11+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +// If the compiler admits that it is not ready for C++11, why torture it? +// Hopefully, this will speed up the test. + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 201103L + +#error "This is not a C++11 compiler" + +#else + +namespace cxx11 +{ + + namespace test_static_assert + { + + template + struct check + { + static_assert(sizeof(int) <= sizeof(T), "not big enough"); + }; + + } + + namespace test_final_override + { + + struct Base + { + virtual ~Base() {} + virtual void f() {} + }; + + struct Derived : public Base + { + virtual ~Derived() override {} + virtual void f() override {} + }; + + } + + namespace test_double_right_angle_brackets + { + + template < typename T > + struct check {}; + + typedef check single_type; + typedef check> double_type; + typedef check>> triple_type; + typedef check>>> quadruple_type; + + } + + namespace test_decltype + { + + int + f() + { + int a = 1; + decltype(a) b = 2; + return a + b; + } + + } + + namespace test_type_deduction + { + + template < typename T1, typename T2 > + struct is_same + { + static const bool value = false; + }; + + template < typename T > + struct is_same + { + static const bool value = true; + }; + + template < typename T1, typename T2 > + auto + add(T1 a1, T2 a2) -> decltype(a1 + a2) + { + return a1 + a2; + } + + int + test(const int c, volatile int v) + { + static_assert(is_same::value == true, ""); + static_assert(is_same::value == false, ""); + static_assert(is_same::value == false, ""); + auto ac = c; + auto av = v; + auto sumi = ac + av + 'x'; + auto sumf = ac + av + 1.0; + static_assert(is_same::value == true, ""); + static_assert(is_same::value == true, ""); + static_assert(is_same::value == true, ""); + static_assert(is_same::value == false, ""); + static_assert(is_same::value == true, ""); + return (sumf > 0.0) ? sumi : add(c, v); + } + + } + + namespace test_noexcept + { + + int f() { return 0; } + int g() noexcept { return 0; } + + static_assert(noexcept(f()) == false, ""); + static_assert(noexcept(g()) == true, ""); + + } + + namespace test_constexpr + { + + template < typename CharT > + unsigned long constexpr + strlen_c_r(const CharT *const s, const unsigned long acc) noexcept + { + return *s ? strlen_c_r(s + 1, acc + 1) : acc; + } + + template < typename CharT > + unsigned long constexpr + strlen_c(const CharT *const s) noexcept + { + return strlen_c_r(s, 0UL); + } + + static_assert(strlen_c("") == 0UL, ""); + static_assert(strlen_c("1") == 1UL, ""); + static_assert(strlen_c("example") == 7UL, ""); + static_assert(strlen_c("another\0example") == 7UL, ""); + + } + + namespace test_rvalue_references + { + + template < int N > + struct answer + { + static constexpr int value = N; + }; + + answer<1> f(int&) { return answer<1>(); } + answer<2> f(const int&) { return answer<2>(); } + answer<3> f(int&&) { return answer<3>(); } + + void + test() + { + int i = 0; + const int c = 0; + static_assert(decltype(f(i))::value == 1, ""); + static_assert(decltype(f(c))::value == 2, ""); + static_assert(decltype(f(0))::value == 3, ""); + } + + } + + namespace test_uniform_initialization + { + + struct test + { + static const int zero {}; + static const int one {1}; + }; + + static_assert(test::zero == 0, ""); + static_assert(test::one == 1, ""); + + } + + namespace test_lambdas + { + + void + test1() + { + auto lambda1 = [](){}; + auto lambda2 = lambda1; + lambda1(); + lambda2(); + } + + int + test2() + { + auto a = [](int i, int j){ return i + j; }(1, 2); + auto b = []() -> int { return '0'; }(); + auto c = [=](){ return a + b; }(); + auto d = [&](){ return c; }(); + auto e = [a, &b](int x) mutable { + const auto identity = [](int y){ return y; }; + for (auto i = 0; i < a; ++i) + a += b--; + return x + identity(a + b); + }(0); + return a + b + c + d + e; + } + + int + test3() + { + const auto nullary = [](){ return 0; }; + const auto unary = [](int x){ return x; }; + using nullary_t = decltype(nullary); + using unary_t = decltype(unary); + const auto higher1st = [](nullary_t f){ return f(); }; + const auto higher2nd = [unary](nullary_t f1){ + return [unary, f1](unary_t f2){ return f2(unary(f1())); }; + }; + return higher1st(nullary) + higher2nd(nullary)(unary); + } + + } + + namespace test_variadic_templates + { + + template + struct sum; + + template + struct sum + { + static constexpr auto value = N0 + sum::value; + }; + + template <> + struct sum<> + { + static constexpr auto value = 0; + }; + + static_assert(sum<>::value == 0, ""); + static_assert(sum<1>::value == 1, ""); + static_assert(sum<23>::value == 23, ""); + static_assert(sum<1, 2>::value == 3, ""); + static_assert(sum<5, 5, 11>::value == 21, ""); + static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, ""); + + } + + // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae + // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function + // because of this. + namespace test_template_alias_sfinae + { + + struct foo {}; + + template + using member = typename T::member_type; + + template + void func(...) {} + + template + void func(member*) {} + + void test(); + + void test() { func(0); } + + } + +} // namespace cxx11 + +#endif // __cplusplus >= 201103L + + + +_ACEOF +if ac_fn_cxx_try_compile "$LINENO" +then : + ax_cv_cxx_compile_cxx11=yes +else $as_nop + ax_cv_cxx_compile_cxx11=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_cxx_compile_cxx11" >&5 +printf "%s\n" "$ax_cv_cxx_compile_cxx11" >&6; } + if test x$ax_cv_cxx_compile_cxx11 = xyes; then + ac_success=yes + fi + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + if test x$ac_success = xno; then + HAVE_CXX11=0 + else + HAVE_CXX11=1 + +printf "%s\n" "#define HAVE_CXX11 1" >>confdefs.h + + fi + + + else + ax_cxx_compile_alternatives="11 0x" ax_cxx_compile_cxx11_required=false + ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + ac_success=no + + + + + + if test x$ac_success = xno; then + for alternative in ${ax_cxx_compile_alternatives}; do + for switch in -std=c++${alternative} +std=c++${alternative} "-h std=c++${alternative}"; do + cachevar=`printf "%s\n" "ax_cv_cxx_compile_cxx11_$switch" | $as_tr_sh` + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CXX supports C++11 features with $switch" >&5 +printf %s "checking whether $CXX supports C++11 features with $switch... " >&6; } +if eval test \${$cachevar+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_save_CXX="$CXX" + CXX="$CXX $switch" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +// If the compiler admits that it is not ready for C++11, why torture it? +// Hopefully, this will speed up the test. + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 201103L + +#error "This is not a C++11 compiler" + +#else + +namespace cxx11 +{ + + namespace test_static_assert + { + + template + struct check + { + static_assert(sizeof(int) <= sizeof(T), "not big enough"); + }; + + } + + namespace test_final_override + { + + struct Base + { + virtual ~Base() {} + virtual void f() {} + }; + + struct Derived : public Base + { + virtual ~Derived() override {} + virtual void f() override {} + }; + + } + + namespace test_double_right_angle_brackets + { + + template < typename T > + struct check {}; + + typedef check single_type; + typedef check> double_type; + typedef check>> triple_type; + typedef check>>> quadruple_type; + + } + + namespace test_decltype + { + + int + f() + { + int a = 1; + decltype(a) b = 2; + return a + b; + } + + } + + namespace test_type_deduction + { + + template < typename T1, typename T2 > + struct is_same + { + static const bool value = false; + }; + + template < typename T > + struct is_same + { + static const bool value = true; + }; + + template < typename T1, typename T2 > + auto + add(T1 a1, T2 a2) -> decltype(a1 + a2) + { + return a1 + a2; + } + + int + test(const int c, volatile int v) + { + static_assert(is_same::value == true, ""); + static_assert(is_same::value == false, ""); + static_assert(is_same::value == false, ""); + auto ac = c; + auto av = v; + auto sumi = ac + av + 'x'; + auto sumf = ac + av + 1.0; + static_assert(is_same::value == true, ""); + static_assert(is_same::value == true, ""); + static_assert(is_same::value == true, ""); + static_assert(is_same::value == false, ""); + static_assert(is_same::value == true, ""); + return (sumf > 0.0) ? sumi : add(c, v); + } + + } + + namespace test_noexcept + { + + int f() { return 0; } + int g() noexcept { return 0; } + + static_assert(noexcept(f()) == false, ""); + static_assert(noexcept(g()) == true, ""); + + } + + namespace test_constexpr + { + + template < typename CharT > + unsigned long constexpr + strlen_c_r(const CharT *const s, const unsigned long acc) noexcept + { + return *s ? strlen_c_r(s + 1, acc + 1) : acc; + } + + template < typename CharT > + unsigned long constexpr + strlen_c(const CharT *const s) noexcept + { + return strlen_c_r(s, 0UL); + } + + static_assert(strlen_c("") == 0UL, ""); + static_assert(strlen_c("1") == 1UL, ""); + static_assert(strlen_c("example") == 7UL, ""); + static_assert(strlen_c("another\0example") == 7UL, ""); + + } + + namespace test_rvalue_references + { + + template < int N > + struct answer + { + static constexpr int value = N; + }; + + answer<1> f(int&) { return answer<1>(); } + answer<2> f(const int&) { return answer<2>(); } + answer<3> f(int&&) { return answer<3>(); } + + void + test() + { + int i = 0; + const int c = 0; + static_assert(decltype(f(i))::value == 1, ""); + static_assert(decltype(f(c))::value == 2, ""); + static_assert(decltype(f(0))::value == 3, ""); + } + + } + + namespace test_uniform_initialization + { + + struct test + { + static const int zero {}; + static const int one {1}; + }; + + static_assert(test::zero == 0, ""); + static_assert(test::one == 1, ""); + + } + + namespace test_lambdas + { + + void + test1() + { + auto lambda1 = [](){}; + auto lambda2 = lambda1; + lambda1(); + lambda2(); + } + + int + test2() + { + auto a = [](int i, int j){ return i + j; }(1, 2); + auto b = []() -> int { return '0'; }(); + auto c = [=](){ return a + b; }(); + auto d = [&](){ return c; }(); + auto e = [a, &b](int x) mutable { + const auto identity = [](int y){ return y; }; + for (auto i = 0; i < a; ++i) + a += b--; + return x + identity(a + b); + }(0); + return a + b + c + d + e; + } + + int + test3() + { + const auto nullary = [](){ return 0; }; + const auto unary = [](int x){ return x; }; + using nullary_t = decltype(nullary); + using unary_t = decltype(unary); + const auto higher1st = [](nullary_t f){ return f(); }; + const auto higher2nd = [unary](nullary_t f1){ + return [unary, f1](unary_t f2){ return f2(unary(f1())); }; + }; + return higher1st(nullary) + higher2nd(nullary)(unary); + } + + } + + namespace test_variadic_templates + { + + template + struct sum; + + template + struct sum + { + static constexpr auto value = N0 + sum::value; + }; + + template <> + struct sum<> + { + static constexpr auto value = 0; + }; + + static_assert(sum<>::value == 0, ""); + static_assert(sum<1>::value == 1, ""); + static_assert(sum<23>::value == 23, ""); + static_assert(sum<1, 2>::value == 3, ""); + static_assert(sum<5, 5, 11>::value == 21, ""); + static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, ""); + + } + + // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae + // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function + // because of this. + namespace test_template_alias_sfinae + { + + struct foo {}; + + template + using member = typename T::member_type; + + template + void func(...) {} + + template + void func(member*) {} + + void test(); + + void test() { func(0); } + + } + +} // namespace cxx11 + +#endif // __cplusplus >= 201103L + + + +_ACEOF +if ac_fn_cxx_try_compile "$LINENO" +then : + eval $cachevar=yes +else $as_nop + eval $cachevar=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + CXX="$ac_save_CXX" +fi +eval ac_res=\$$cachevar + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } + if eval test x\$$cachevar = xyes; then + CXX="$CXX $switch" + if test -n "$CXXCPP" ; then + CXXCPP="$CXXCPP $switch" + fi + ac_success=yes + break + fi + done + if test x$ac_success = xyes; then + break + fi + done + fi + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + if test x$ax_cxx_compile_cxx11_required = xtrue; then + if test x$ac_success = xno; then + as_fn_error $? "*** A compiler with support for C++11 language features is required." "$LINENO" 5 + fi + fi + if test x$ac_success = xno; then + HAVE_CXX11=0 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: No compiler with C++11 support was found" >&5 +printf "%s\n" "$as_me: No compiler with C++11 support was found" >&6;} + else + HAVE_CXX11=1 + +printf "%s\n" "#define HAVE_CXX11 1" >>confdefs.h + + fi + + + fi + + ax_cxx_compile_alternatives="17 1z" ax_cxx_compile_cxx17_required=false + ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + ac_success=no + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CXX supports C++17 features by default" >&5 +printf %s "checking whether $CXX supports C++17 features by default... " >&6; } +if test ${ax_cv_cxx_compile_cxx17+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +// If the compiler admits that it is not ready for C++11, why torture it? +// Hopefully, this will speed up the test. + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 201103L + +#error "This is not a C++11 compiler" + +#else + +namespace cxx11 +{ + + namespace test_static_assert + { + + template + struct check + { + static_assert(sizeof(int) <= sizeof(T), "not big enough"); + }; + + } + + namespace test_final_override + { + + struct Base + { + virtual ~Base() {} + virtual void f() {} + }; + + struct Derived : public Base + { + virtual ~Derived() override {} + virtual void f() override {} + }; + + } + + namespace test_double_right_angle_brackets + { + + template < typename T > + struct check {}; + + typedef check single_type; + typedef check> double_type; + typedef check>> triple_type; + typedef check>>> quadruple_type; + + } + + namespace test_decltype + { + + int + f() + { + int a = 1; + decltype(a) b = 2; + return a + b; + } + + } + + namespace test_type_deduction + { + + template < typename T1, typename T2 > + struct is_same + { + static const bool value = false; + }; + + template < typename T > + struct is_same + { + static const bool value = true; + }; + + template < typename T1, typename T2 > + auto + add(T1 a1, T2 a2) -> decltype(a1 + a2) + { + return a1 + a2; + } + + int + test(const int c, volatile int v) + { + static_assert(is_same::value == true, ""); + static_assert(is_same::value == false, ""); + static_assert(is_same::value == false, ""); + auto ac = c; + auto av = v; + auto sumi = ac + av + 'x'; + auto sumf = ac + av + 1.0; + static_assert(is_same::value == true, ""); + static_assert(is_same::value == true, ""); + static_assert(is_same::value == true, ""); + static_assert(is_same::value == false, ""); + static_assert(is_same::value == true, ""); + return (sumf > 0.0) ? sumi : add(c, v); + } + + } + + namespace test_noexcept + { + + int f() { return 0; } + int g() noexcept { return 0; } + + static_assert(noexcept(f()) == false, ""); + static_assert(noexcept(g()) == true, ""); + + } + + namespace test_constexpr + { + + template < typename CharT > + unsigned long constexpr + strlen_c_r(const CharT *const s, const unsigned long acc) noexcept + { + return *s ? strlen_c_r(s + 1, acc + 1) : acc; + } + + template < typename CharT > + unsigned long constexpr + strlen_c(const CharT *const s) noexcept + { + return strlen_c_r(s, 0UL); + } + + static_assert(strlen_c("") == 0UL, ""); + static_assert(strlen_c("1") == 1UL, ""); + static_assert(strlen_c("example") == 7UL, ""); + static_assert(strlen_c("another\0example") == 7UL, ""); + + } + + namespace test_rvalue_references + { + + template < int N > + struct answer + { + static constexpr int value = N; + }; + + answer<1> f(int&) { return answer<1>(); } + answer<2> f(const int&) { return answer<2>(); } + answer<3> f(int&&) { return answer<3>(); } + + void + test() + { + int i = 0; + const int c = 0; + static_assert(decltype(f(i))::value == 1, ""); + static_assert(decltype(f(c))::value == 2, ""); + static_assert(decltype(f(0))::value == 3, ""); + } + + } + + namespace test_uniform_initialization + { + + struct test + { + static const int zero {}; + static const int one {1}; + }; + + static_assert(test::zero == 0, ""); + static_assert(test::one == 1, ""); + + } + + namespace test_lambdas + { + + void + test1() + { + auto lambda1 = [](){}; + auto lambda2 = lambda1; + lambda1(); + lambda2(); + } + + int + test2() + { + auto a = [](int i, int j){ return i + j; }(1, 2); + auto b = []() -> int { return '0'; }(); + auto c = [=](){ return a + b; }(); + auto d = [&](){ return c; }(); + auto e = [a, &b](int x) mutable { + const auto identity = [](int y){ return y; }; + for (auto i = 0; i < a; ++i) + a += b--; + return x + identity(a + b); + }(0); + return a + b + c + d + e; + } + + int + test3() + { + const auto nullary = [](){ return 0; }; + const auto unary = [](int x){ return x; }; + using nullary_t = decltype(nullary); + using unary_t = decltype(unary); + const auto higher1st = [](nullary_t f){ return f(); }; + const auto higher2nd = [unary](nullary_t f1){ + return [unary, f1](unary_t f2){ return f2(unary(f1())); }; + }; + return higher1st(nullary) + higher2nd(nullary)(unary); + } + + } + + namespace test_variadic_templates + { + + template + struct sum; + + template + struct sum + { + static constexpr auto value = N0 + sum::value; + }; + + template <> + struct sum<> + { + static constexpr auto value = 0; + }; + + static_assert(sum<>::value == 0, ""); + static_assert(sum<1>::value == 1, ""); + static_assert(sum<23>::value == 23, ""); + static_assert(sum<1, 2>::value == 3, ""); + static_assert(sum<5, 5, 11>::value == 21, ""); + static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, ""); + + } + + // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae + // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function + // because of this. + namespace test_template_alias_sfinae + { + + struct foo {}; + + template + using member = typename T::member_type; + + template + void func(...) {} + + template + void func(member*) {} + + void test(); + + void test() { func(0); } + + } + +} // namespace cxx11 + +#endif // __cplusplus >= 201103L + + + + +// If the compiler admits that it is not ready for C++14, why torture it? +// Hopefully, this will speed up the test. + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 201402L + +#error "This is not a C++14 compiler" + +#else + +namespace cxx14 +{ + + namespace test_polymorphic_lambdas + { + + int + test() + { + const auto lambda = [](auto&&... args){ + const auto istiny = [](auto x){ + return (sizeof(x) == 1UL) ? 1 : 0; + }; + const int aretiny[] = { istiny(args)... }; + return aretiny[0]; + }; + return lambda(1, 1L, 1.0f, '1'); + } + + } + + namespace test_binary_literals + { + + constexpr auto ivii = 0b0000000000101010; + static_assert(ivii == 42, "wrong value"); + + } + + namespace test_generalized_constexpr + { + + template < typename CharT > + constexpr unsigned long + strlen_c(const CharT *const s) noexcept + { + auto length = 0UL; + for (auto p = s; *p; ++p) + ++length; + return length; + } + + static_assert(strlen_c("") == 0UL, ""); + static_assert(strlen_c("x") == 1UL, ""); + static_assert(strlen_c("test") == 4UL, ""); + static_assert(strlen_c("another\0test") == 7UL, ""); + + } + + namespace test_lambda_init_capture + { + + int + test() + { + auto x = 0; + const auto lambda1 = [a = x](int b){ return a + b; }; + const auto lambda2 = [a = lambda1(x)](){ return a; }; + return lambda2(); + } + + } + + namespace test_digit_separators + { + + constexpr auto ten_million = 100'000'000; + static_assert(ten_million == 100000000, ""); + + } + + namespace test_return_type_deduction + { + + auto f(int& x) { return x; } + decltype(auto) g(int& x) { return x; } + + template < typename T1, typename T2 > + struct is_same + { + static constexpr auto value = false; + }; + + template < typename T > + struct is_same + { + static constexpr auto value = true; + }; + + int + test() + { + auto x = 0; + static_assert(is_same::value, ""); + static_assert(is_same::value, ""); + return x; + } + + } + +} // namespace cxx14 + +#endif // __cplusplus >= 201402L + + + + +// If the compiler admits that it is not ready for C++17, why torture it? +// Hopefully, this will speed up the test. + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 201703L + +#error "This is not a C++17 compiler" + +#else + +#include +#include +#include + +namespace cxx17 +{ + + namespace test_constexpr_lambdas + { + + constexpr int foo = [](){return 42;}(); + + } + + namespace test::nested_namespace::definitions + { + + } + + namespace test_fold_expression + { + + template + int multiply(Args... args) + { + return (args * ... * 1); + } + + template + bool all(Args... args) + { + return (args && ...); + } + + } + + namespace test_extended_static_assert + { + + static_assert (true); + + } + + namespace test_auto_brace_init_list + { + + auto foo = {5}; + auto bar {5}; + + static_assert(std::is_same, decltype(foo)>::value); + static_assert(std::is_same::value); + } + + namespace test_typename_in_template_template_parameter + { + + template typename X> struct D; + + } + + namespace test_fallthrough_nodiscard_maybe_unused_attributes + { + + int f1() + { + return 42; + } + + [[nodiscard]] int f2() + { + [[maybe_unused]] auto unused = f1(); + + switch (f1()) + { + case 17: + f1(); + [[fallthrough]]; + case 42: + f1(); + } + return f1(); + } + + } + + namespace test_extended_aggregate_initialization + { + + struct base1 + { + int b1, b2 = 42; + }; + + struct base2 + { + base2() { + b3 = 42; + } + int b3; + }; + + struct derived : base1, base2 + { + int d; + }; + + derived d1 {{1, 2}, {}, 4}; // full initialization + derived d2 {{}, {}, 4}; // value-initialized bases + + } + + namespace test_general_range_based_for_loop + { + + struct iter + { + int i; + + int& operator* () + { + return i; + } + + const int& operator* () const + { + return i; + } + + iter& operator++() + { + ++i; + return *this; + } + }; + + struct sentinel + { + int i; + }; + + bool operator== (const iter& i, const sentinel& s) + { + return i.i == s.i; + } + + bool operator!= (const iter& i, const sentinel& s) + { + return !(i == s); + } + + struct range + { + iter begin() const + { + return {0}; + } + + sentinel end() const + { + return {5}; + } + }; + + void f() + { + range r {}; + + for (auto i : r) + { + [[maybe_unused]] auto v = i; + } + } + + } + + namespace test_lambda_capture_asterisk_this_by_value + { + + struct t + { + int i; + int foo() + { + return [*this]() + { + return i; + }(); + } + }; + + } + + namespace test_enum_class_construction + { + + enum class byte : unsigned char + {}; + + byte foo {42}; + + } + + namespace test_constexpr_if + { + + template + int f () + { + if constexpr(cond) + { + return 13; + } + else + { + return 42; + } + } + + } + + namespace test_selection_statement_with_initializer + { + + int f() + { + return 13; + } + + int f2() + { + if (auto i = f(); i > 0) + { + return 3; + } + + switch (auto i = f(); i + 4) + { + case 17: + return 2; + + default: + return 1; + } + } + + } + + namespace test_template_argument_deduction_for_class_templates + { + + template + struct pair + { + pair (T1 p1, T2 p2) + : m1 {p1}, + m2 {p2} + {} + + T1 m1; + T2 m2; + }; + + void f() + { + [[maybe_unused]] auto p = pair{13, 42u}; + } + + } + + namespace test_non_type_auto_template_parameters + { + + template + struct B + {}; + + B<5> b1; + B<'a'> b2; + + } + + namespace test_structured_bindings + { + + int arr[2] = { 1, 2 }; + std::pair pr = { 1, 2 }; + + auto f1() -> int(&)[2] + { + return arr; + } + + auto f2() -> std::pair& + { + return pr; + } + + struct S + { + int x1 : 2; + volatile double y1; + }; + + S f3() + { + return {}; + } + + auto [ x1, y1 ] = f1(); + auto& [ xr1, yr1 ] = f1(); + auto [ x2, y2 ] = f2(); + auto& [ xr2, yr2 ] = f2(); + const auto [ x3, y3 ] = f3(); + + } + + namespace test_exception_spec_type_system + { + + struct Good {}; + struct Bad {}; + + void g1() noexcept; + void g2(); + + template + Bad + f(T*, T*); + + template + Good + f(T1*, T2*); + + static_assert (std::is_same_v); + + } + + namespace test_inline_variables + { + + template void f(T) + {} + + template inline T g(T) + { + return T{}; + } + + template<> inline void f<>(int) + {} + + template<> int g<>(int) + { + return 5; + } + + } + +} // namespace cxx17 + +#endif // __cplusplus < 201703L + + + +_ACEOF +if ac_fn_cxx_try_compile "$LINENO" +then : + ax_cv_cxx_compile_cxx17=yes +else $as_nop + ax_cv_cxx_compile_cxx17=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_cxx_compile_cxx17" >&5 +printf "%s\n" "$ax_cv_cxx_compile_cxx17" >&6; } + if test x$ax_cv_cxx_compile_cxx17 = xyes; then + ac_success=yes + fi + + if test x$ac_success = xno; then + for alternative in ${ax_cxx_compile_alternatives}; do + switch="-std=gnu++${alternative}" + cachevar=`printf "%s\n" "ax_cv_cxx_compile_cxx17_$switch" | $as_tr_sh` + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CXX supports C++17 features with $switch" >&5 +printf %s "checking whether $CXX supports C++17 features with $switch... " >&6; } +if eval test \${$cachevar+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_save_CXX="$CXX" + CXX="$CXX $switch" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +// If the compiler admits that it is not ready for C++11, why torture it? +// Hopefully, this will speed up the test. + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 201103L + +#error "This is not a C++11 compiler" + +#else + +namespace cxx11 +{ + + namespace test_static_assert + { + + template + struct check + { + static_assert(sizeof(int) <= sizeof(T), "not big enough"); + }; + + } + + namespace test_final_override + { + + struct Base + { + virtual ~Base() {} + virtual void f() {} + }; + + struct Derived : public Base + { + virtual ~Derived() override {} + virtual void f() override {} + }; + + } + + namespace test_double_right_angle_brackets + { + + template < typename T > + struct check {}; + + typedef check single_type; + typedef check> double_type; + typedef check>> triple_type; + typedef check>>> quadruple_type; + + } + + namespace test_decltype + { + + int + f() + { + int a = 1; + decltype(a) b = 2; + return a + b; + } + + } + + namespace test_type_deduction + { + + template < typename T1, typename T2 > + struct is_same + { + static const bool value = false; + }; + + template < typename T > + struct is_same + { + static const bool value = true; + }; + + template < typename T1, typename T2 > + auto + add(T1 a1, T2 a2) -> decltype(a1 + a2) + { + return a1 + a2; + } + + int + test(const int c, volatile int v) + { + static_assert(is_same::value == true, ""); + static_assert(is_same::value == false, ""); + static_assert(is_same::value == false, ""); + auto ac = c; + auto av = v; + auto sumi = ac + av + 'x'; + auto sumf = ac + av + 1.0; + static_assert(is_same::value == true, ""); + static_assert(is_same::value == true, ""); + static_assert(is_same::value == true, ""); + static_assert(is_same::value == false, ""); + static_assert(is_same::value == true, ""); + return (sumf > 0.0) ? sumi : add(c, v); + } + + } + + namespace test_noexcept + { + + int f() { return 0; } + int g() noexcept { return 0; } + + static_assert(noexcept(f()) == false, ""); + static_assert(noexcept(g()) == true, ""); + + } + + namespace test_constexpr + { + + template < typename CharT > + unsigned long constexpr + strlen_c_r(const CharT *const s, const unsigned long acc) noexcept + { + return *s ? strlen_c_r(s + 1, acc + 1) : acc; + } + + template < typename CharT > + unsigned long constexpr + strlen_c(const CharT *const s) noexcept + { + return strlen_c_r(s, 0UL); + } + + static_assert(strlen_c("") == 0UL, ""); + static_assert(strlen_c("1") == 1UL, ""); + static_assert(strlen_c("example") == 7UL, ""); + static_assert(strlen_c("another\0example") == 7UL, ""); + + } + + namespace test_rvalue_references + { + + template < int N > + struct answer + { + static constexpr int value = N; + }; + + answer<1> f(int&) { return answer<1>(); } + answer<2> f(const int&) { return answer<2>(); } + answer<3> f(int&&) { return answer<3>(); } + + void + test() + { + int i = 0; + const int c = 0; + static_assert(decltype(f(i))::value == 1, ""); + static_assert(decltype(f(c))::value == 2, ""); + static_assert(decltype(f(0))::value == 3, ""); + } + + } + + namespace test_uniform_initialization + { + + struct test + { + static const int zero {}; + static const int one {1}; + }; + + static_assert(test::zero == 0, ""); + static_assert(test::one == 1, ""); + + } + + namespace test_lambdas + { + + void + test1() + { + auto lambda1 = [](){}; + auto lambda2 = lambda1; + lambda1(); + lambda2(); + } + + int + test2() + { + auto a = [](int i, int j){ return i + j; }(1, 2); + auto b = []() -> int { return '0'; }(); + auto c = [=](){ return a + b; }(); + auto d = [&](){ return c; }(); + auto e = [a, &b](int x) mutable { + const auto identity = [](int y){ return y; }; + for (auto i = 0; i < a; ++i) + a += b--; + return x + identity(a + b); + }(0); + return a + b + c + d + e; + } + + int + test3() + { + const auto nullary = [](){ return 0; }; + const auto unary = [](int x){ return x; }; + using nullary_t = decltype(nullary); + using unary_t = decltype(unary); + const auto higher1st = [](nullary_t f){ return f(); }; + const auto higher2nd = [unary](nullary_t f1){ + return [unary, f1](unary_t f2){ return f2(unary(f1())); }; + }; + return higher1st(nullary) + higher2nd(nullary)(unary); + } + + } + + namespace test_variadic_templates + { + + template + struct sum; + + template + struct sum + { + static constexpr auto value = N0 + sum::value; + }; + + template <> + struct sum<> + { + static constexpr auto value = 0; + }; + + static_assert(sum<>::value == 0, ""); + static_assert(sum<1>::value == 1, ""); + static_assert(sum<23>::value == 23, ""); + static_assert(sum<1, 2>::value == 3, ""); + static_assert(sum<5, 5, 11>::value == 21, ""); + static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, ""); + + } + + // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae + // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function + // because of this. + namespace test_template_alias_sfinae + { + + struct foo {}; + + template + using member = typename T::member_type; + + template + void func(...) {} + + template + void func(member*) {} + + void test(); + + void test() { func(0); } + + } + +} // namespace cxx11 + +#endif // __cplusplus >= 201103L + + + + +// If the compiler admits that it is not ready for C++14, why torture it? +// Hopefully, this will speed up the test. + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 201402L + +#error "This is not a C++14 compiler" + +#else + +namespace cxx14 +{ + + namespace test_polymorphic_lambdas + { + + int + test() + { + const auto lambda = [](auto&&... args){ + const auto istiny = [](auto x){ + return (sizeof(x) == 1UL) ? 1 : 0; + }; + const int aretiny[] = { istiny(args)... }; + return aretiny[0]; + }; + return lambda(1, 1L, 1.0f, '1'); + } + + } + + namespace test_binary_literals + { + + constexpr auto ivii = 0b0000000000101010; + static_assert(ivii == 42, "wrong value"); + + } + + namespace test_generalized_constexpr + { + + template < typename CharT > + constexpr unsigned long + strlen_c(const CharT *const s) noexcept + { + auto length = 0UL; + for (auto p = s; *p; ++p) + ++length; + return length; + } + + static_assert(strlen_c("") == 0UL, ""); + static_assert(strlen_c("x") == 1UL, ""); + static_assert(strlen_c("test") == 4UL, ""); + static_assert(strlen_c("another\0test") == 7UL, ""); + + } + + namespace test_lambda_init_capture + { + + int + test() + { + auto x = 0; + const auto lambda1 = [a = x](int b){ return a + b; }; + const auto lambda2 = [a = lambda1(x)](){ return a; }; + return lambda2(); + } + + } + + namespace test_digit_separators + { + + constexpr auto ten_million = 100'000'000; + static_assert(ten_million == 100000000, ""); + + } + + namespace test_return_type_deduction + { + + auto f(int& x) { return x; } + decltype(auto) g(int& x) { return x; } + + template < typename T1, typename T2 > + struct is_same + { + static constexpr auto value = false; + }; + + template < typename T > + struct is_same + { + static constexpr auto value = true; + }; + + int + test() + { + auto x = 0; + static_assert(is_same::value, ""); + static_assert(is_same::value, ""); + return x; + } + + } + +} // namespace cxx14 + +#endif // __cplusplus >= 201402L + + + + +// If the compiler admits that it is not ready for C++17, why torture it? +// Hopefully, this will speed up the test. + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 201703L + +#error "This is not a C++17 compiler" + +#else + +#include +#include +#include + +namespace cxx17 +{ + + namespace test_constexpr_lambdas + { + + constexpr int foo = [](){return 42;}(); + + } + + namespace test::nested_namespace::definitions + { + + } + + namespace test_fold_expression + { + + template + int multiply(Args... args) + { + return (args * ... * 1); + } + + template + bool all(Args... args) + { + return (args && ...); + } + + } + + namespace test_extended_static_assert + { + + static_assert (true); + + } + + namespace test_auto_brace_init_list + { + + auto foo = {5}; + auto bar {5}; + + static_assert(std::is_same, decltype(foo)>::value); + static_assert(std::is_same::value); + } + + namespace test_typename_in_template_template_parameter + { + + template typename X> struct D; + + } + + namespace test_fallthrough_nodiscard_maybe_unused_attributes + { + + int f1() + { + return 42; + } + + [[nodiscard]] int f2() + { + [[maybe_unused]] auto unused = f1(); + + switch (f1()) + { + case 17: + f1(); + [[fallthrough]]; + case 42: + f1(); + } + return f1(); + } + + } + + namespace test_extended_aggregate_initialization + { + + struct base1 + { + int b1, b2 = 42; + }; + + struct base2 + { + base2() { + b3 = 42; + } + int b3; + }; + + struct derived : base1, base2 + { + int d; + }; + + derived d1 {{1, 2}, {}, 4}; // full initialization + derived d2 {{}, {}, 4}; // value-initialized bases + + } + + namespace test_general_range_based_for_loop + { + + struct iter + { + int i; + + int& operator* () + { + return i; + } + + const int& operator* () const + { + return i; + } + + iter& operator++() + { + ++i; + return *this; + } + }; + + struct sentinel + { + int i; + }; + + bool operator== (const iter& i, const sentinel& s) + { + return i.i == s.i; + } + + bool operator!= (const iter& i, const sentinel& s) + { + return !(i == s); + } + + struct range + { + iter begin() const + { + return {0}; + } + + sentinel end() const + { + return {5}; + } + }; + + void f() + { + range r {}; + + for (auto i : r) + { + [[maybe_unused]] auto v = i; + } + } + + } + + namespace test_lambda_capture_asterisk_this_by_value + { + + struct t + { + int i; + int foo() + { + return [*this]() + { + return i; + }(); + } + }; + + } + + namespace test_enum_class_construction + { + + enum class byte : unsigned char + {}; + + byte foo {42}; + + } + + namespace test_constexpr_if + { + + template + int f () + { + if constexpr(cond) + { + return 13; + } + else + { + return 42; + } + } + + } + + namespace test_selection_statement_with_initializer + { + + int f() + { + return 13; + } + + int f2() + { + if (auto i = f(); i > 0) + { + return 3; + } + + switch (auto i = f(); i + 4) + { + case 17: + return 2; + + default: + return 1; + } + } + + } + + namespace test_template_argument_deduction_for_class_templates + { + + template + struct pair + { + pair (T1 p1, T2 p2) + : m1 {p1}, + m2 {p2} + {} + + T1 m1; + T2 m2; + }; + + void f() + { + [[maybe_unused]] auto p = pair{13, 42u}; + } + + } + + namespace test_non_type_auto_template_parameters + { + + template + struct B + {}; + + B<5> b1; + B<'a'> b2; + + } + + namespace test_structured_bindings + { + + int arr[2] = { 1, 2 }; + std::pair pr = { 1, 2 }; + + auto f1() -> int(&)[2] + { + return arr; + } + + auto f2() -> std::pair& + { + return pr; + } + + struct S + { + int x1 : 2; + volatile double y1; + }; + + S f3() + { + return {}; + } + + auto [ x1, y1 ] = f1(); + auto& [ xr1, yr1 ] = f1(); + auto [ x2, y2 ] = f2(); + auto& [ xr2, yr2 ] = f2(); + const auto [ x3, y3 ] = f3(); + + } + + namespace test_exception_spec_type_system + { + + struct Good {}; + struct Bad {}; + + void g1() noexcept; + void g2(); + + template + Bad + f(T*, T*); + + template + Good + f(T1*, T2*); + + static_assert (std::is_same_v); + + } + + namespace test_inline_variables + { + + template void f(T) + {} + + template inline T g(T) + { + return T{}; + } + + template<> inline void f<>(int) + {} + + template<> int g<>(int) + { + return 5; + } + + } + +} // namespace cxx17 + +#endif // __cplusplus < 201703L + + + +_ACEOF +if ac_fn_cxx_try_compile "$LINENO" +then : + eval $cachevar=yes +else $as_nop + eval $cachevar=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + CXX="$ac_save_CXX" +fi +eval ac_res=\$$cachevar + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } + if eval test x\$$cachevar = xyes; then + CXX="$CXX $switch" + if test -n "$CXXCPP" ; then + CXXCPP="$CXXCPP $switch" + fi + ac_success=yes + break + fi + done + fi + + if test x$ac_success = xno; then + for alternative in ${ax_cxx_compile_alternatives}; do + for switch in -std=c++${alternative} +std=c++${alternative} "-h std=c++${alternative}"; do + cachevar=`printf "%s\n" "ax_cv_cxx_compile_cxx17_$switch" | $as_tr_sh` + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CXX supports C++17 features with $switch" >&5 +printf %s "checking whether $CXX supports C++17 features with $switch... " >&6; } +if eval test \${$cachevar+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_save_CXX="$CXX" + CXX="$CXX $switch" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +// If the compiler admits that it is not ready for C++11, why torture it? +// Hopefully, this will speed up the test. + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 201103L + +#error "This is not a C++11 compiler" + +#else + +namespace cxx11 +{ + + namespace test_static_assert + { + + template + struct check + { + static_assert(sizeof(int) <= sizeof(T), "not big enough"); + }; + + } + + namespace test_final_override + { + + struct Base + { + virtual ~Base() {} + virtual void f() {} + }; + + struct Derived : public Base + { + virtual ~Derived() override {} + virtual void f() override {} + }; + + } + + namespace test_double_right_angle_brackets + { + + template < typename T > + struct check {}; + + typedef check single_type; + typedef check> double_type; + typedef check>> triple_type; + typedef check>>> quadruple_type; + + } + + namespace test_decltype + { + + int + f() + { + int a = 1; + decltype(a) b = 2; + return a + b; + } + + } + + namespace test_type_deduction + { + + template < typename T1, typename T2 > + struct is_same + { + static const bool value = false; + }; + + template < typename T > + struct is_same + { + static const bool value = true; + }; + + template < typename T1, typename T2 > + auto + add(T1 a1, T2 a2) -> decltype(a1 + a2) + { + return a1 + a2; + } + + int + test(const int c, volatile int v) + { + static_assert(is_same::value == true, ""); + static_assert(is_same::value == false, ""); + static_assert(is_same::value == false, ""); + auto ac = c; + auto av = v; + auto sumi = ac + av + 'x'; + auto sumf = ac + av + 1.0; + static_assert(is_same::value == true, ""); + static_assert(is_same::value == true, ""); + static_assert(is_same::value == true, ""); + static_assert(is_same::value == false, ""); + static_assert(is_same::value == true, ""); + return (sumf > 0.0) ? sumi : add(c, v); + } + + } + + namespace test_noexcept + { + + int f() { return 0; } + int g() noexcept { return 0; } + + static_assert(noexcept(f()) == false, ""); + static_assert(noexcept(g()) == true, ""); + + } + + namespace test_constexpr + { + + template < typename CharT > + unsigned long constexpr + strlen_c_r(const CharT *const s, const unsigned long acc) noexcept + { + return *s ? strlen_c_r(s + 1, acc + 1) : acc; + } + + template < typename CharT > + unsigned long constexpr + strlen_c(const CharT *const s) noexcept + { + return strlen_c_r(s, 0UL); + } + + static_assert(strlen_c("") == 0UL, ""); + static_assert(strlen_c("1") == 1UL, ""); + static_assert(strlen_c("example") == 7UL, ""); + static_assert(strlen_c("another\0example") == 7UL, ""); + + } + + namespace test_rvalue_references + { + + template < int N > + struct answer + { + static constexpr int value = N; + }; + + answer<1> f(int&) { return answer<1>(); } + answer<2> f(const int&) { return answer<2>(); } + answer<3> f(int&&) { return answer<3>(); } + + void + test() + { + int i = 0; + const int c = 0; + static_assert(decltype(f(i))::value == 1, ""); + static_assert(decltype(f(c))::value == 2, ""); + static_assert(decltype(f(0))::value == 3, ""); + } + + } + + namespace test_uniform_initialization + { + + struct test + { + static const int zero {}; + static const int one {1}; + }; + + static_assert(test::zero == 0, ""); + static_assert(test::one == 1, ""); + + } + + namespace test_lambdas + { + + void + test1() + { + auto lambda1 = [](){}; + auto lambda2 = lambda1; + lambda1(); + lambda2(); + } + + int + test2() + { + auto a = [](int i, int j){ return i + j; }(1, 2); + auto b = []() -> int { return '0'; }(); + auto c = [=](){ return a + b; }(); + auto d = [&](){ return c; }(); + auto e = [a, &b](int x) mutable { + const auto identity = [](int y){ return y; }; + for (auto i = 0; i < a; ++i) + a += b--; + return x + identity(a + b); + }(0); + return a + b + c + d + e; + } + + int + test3() + { + const auto nullary = [](){ return 0; }; + const auto unary = [](int x){ return x; }; + using nullary_t = decltype(nullary); + using unary_t = decltype(unary); + const auto higher1st = [](nullary_t f){ return f(); }; + const auto higher2nd = [unary](nullary_t f1){ + return [unary, f1](unary_t f2){ return f2(unary(f1())); }; + }; + return higher1st(nullary) + higher2nd(nullary)(unary); + } + + } + + namespace test_variadic_templates + { + + template + struct sum; + + template + struct sum + { + static constexpr auto value = N0 + sum::value; + }; + + template <> + struct sum<> + { + static constexpr auto value = 0; + }; + + static_assert(sum<>::value == 0, ""); + static_assert(sum<1>::value == 1, ""); + static_assert(sum<23>::value == 23, ""); + static_assert(sum<1, 2>::value == 3, ""); + static_assert(sum<5, 5, 11>::value == 21, ""); + static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, ""); + + } + + // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae + // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function + // because of this. + namespace test_template_alias_sfinae + { + + struct foo {}; + + template + using member = typename T::member_type; + + template + void func(...) {} + + template + void func(member*) {} + + void test(); + + void test() { func(0); } + + } + +} // namespace cxx11 + +#endif // __cplusplus >= 201103L + + + + +// If the compiler admits that it is not ready for C++14, why torture it? +// Hopefully, this will speed up the test. + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 201402L + +#error "This is not a C++14 compiler" + +#else + +namespace cxx14 +{ + + namespace test_polymorphic_lambdas + { + + int + test() + { + const auto lambda = [](auto&&... args){ + const auto istiny = [](auto x){ + return (sizeof(x) == 1UL) ? 1 : 0; + }; + const int aretiny[] = { istiny(args)... }; + return aretiny[0]; + }; + return lambda(1, 1L, 1.0f, '1'); + } + + } + + namespace test_binary_literals + { + + constexpr auto ivii = 0b0000000000101010; + static_assert(ivii == 42, "wrong value"); + + } + + namespace test_generalized_constexpr + { + + template < typename CharT > + constexpr unsigned long + strlen_c(const CharT *const s) noexcept + { + auto length = 0UL; + for (auto p = s; *p; ++p) + ++length; + return length; + } + + static_assert(strlen_c("") == 0UL, ""); + static_assert(strlen_c("x") == 1UL, ""); + static_assert(strlen_c("test") == 4UL, ""); + static_assert(strlen_c("another\0test") == 7UL, ""); + + } + + namespace test_lambda_init_capture + { + + int + test() + { + auto x = 0; + const auto lambda1 = [a = x](int b){ return a + b; }; + const auto lambda2 = [a = lambda1(x)](){ return a; }; + return lambda2(); + } + + } + + namespace test_digit_separators + { + + constexpr auto ten_million = 100'000'000; + static_assert(ten_million == 100000000, ""); + + } + + namespace test_return_type_deduction + { + + auto f(int& x) { return x; } + decltype(auto) g(int& x) { return x; } + + template < typename T1, typename T2 > + struct is_same + { + static constexpr auto value = false; + }; + + template < typename T > + struct is_same + { + static constexpr auto value = true; + }; + + int + test() + { + auto x = 0; + static_assert(is_same::value, ""); + static_assert(is_same::value, ""); + return x; + } + + } + +} // namespace cxx14 + +#endif // __cplusplus >= 201402L + + + + +// If the compiler admits that it is not ready for C++17, why torture it? +// Hopefully, this will speed up the test. + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 201703L + +#error "This is not a C++17 compiler" + +#else + +#include +#include +#include + +namespace cxx17 +{ + + namespace test_constexpr_lambdas + { + + constexpr int foo = [](){return 42;}(); + + } + + namespace test::nested_namespace::definitions + { + + } + + namespace test_fold_expression + { + + template + int multiply(Args... args) + { + return (args * ... * 1); + } + + template + bool all(Args... args) + { + return (args && ...); + } + + } + + namespace test_extended_static_assert + { + + static_assert (true); + + } + + namespace test_auto_brace_init_list + { + + auto foo = {5}; + auto bar {5}; + + static_assert(std::is_same, decltype(foo)>::value); + static_assert(std::is_same::value); + } + + namespace test_typename_in_template_template_parameter + { + + template typename X> struct D; + + } + + namespace test_fallthrough_nodiscard_maybe_unused_attributes + { + + int f1() + { + return 42; + } + + [[nodiscard]] int f2() + { + [[maybe_unused]] auto unused = f1(); + + switch (f1()) + { + case 17: + f1(); + [[fallthrough]]; + case 42: + f1(); + } + return f1(); + } + + } + + namespace test_extended_aggregate_initialization + { + + struct base1 + { + int b1, b2 = 42; + }; + + struct base2 + { + base2() { + b3 = 42; + } + int b3; + }; + + struct derived : base1, base2 + { + int d; + }; + + derived d1 {{1, 2}, {}, 4}; // full initialization + derived d2 {{}, {}, 4}; // value-initialized bases + + } + + namespace test_general_range_based_for_loop + { + + struct iter + { + int i; + + int& operator* () + { + return i; + } + + const int& operator* () const + { + return i; + } + + iter& operator++() + { + ++i; + return *this; + } + }; + + struct sentinel + { + int i; + }; + + bool operator== (const iter& i, const sentinel& s) + { + return i.i == s.i; + } + + bool operator!= (const iter& i, const sentinel& s) + { + return !(i == s); + } + + struct range + { + iter begin() const + { + return {0}; + } + + sentinel end() const + { + return {5}; + } + }; + + void f() + { + range r {}; + + for (auto i : r) + { + [[maybe_unused]] auto v = i; + } + } + + } + + namespace test_lambda_capture_asterisk_this_by_value + { + + struct t + { + int i; + int foo() + { + return [*this]() + { + return i; + }(); + } + }; + + } + + namespace test_enum_class_construction + { + + enum class byte : unsigned char + {}; + + byte foo {42}; + + } + + namespace test_constexpr_if + { + + template + int f () + { + if constexpr(cond) + { + return 13; + } + else + { + return 42; + } + } + + } + + namespace test_selection_statement_with_initializer + { + + int f() + { + return 13; + } + + int f2() + { + if (auto i = f(); i > 0) + { + return 3; + } + + switch (auto i = f(); i + 4) + { + case 17: + return 2; + + default: + return 1; + } + } + + } + + namespace test_template_argument_deduction_for_class_templates + { + + template + struct pair + { + pair (T1 p1, T2 p2) + : m1 {p1}, + m2 {p2} + {} + + T1 m1; + T2 m2; + }; + + void f() + { + [[maybe_unused]] auto p = pair{13, 42u}; + } + + } + + namespace test_non_type_auto_template_parameters + { + + template + struct B + {}; + + B<5> b1; + B<'a'> b2; + + } + + namespace test_structured_bindings + { + + int arr[2] = { 1, 2 }; + std::pair pr = { 1, 2 }; + + auto f1() -> int(&)[2] + { + return arr; + } + + auto f2() -> std::pair& + { + return pr; + } + + struct S + { + int x1 : 2; + volatile double y1; + }; + + S f3() + { + return {}; + } + + auto [ x1, y1 ] = f1(); + auto& [ xr1, yr1 ] = f1(); + auto [ x2, y2 ] = f2(); + auto& [ xr2, yr2 ] = f2(); + const auto [ x3, y3 ] = f3(); + + } + + namespace test_exception_spec_type_system + { + + struct Good {}; + struct Bad {}; + + void g1() noexcept; + void g2(); + + template + Bad + f(T*, T*); + + template + Good + f(T1*, T2*); + + static_assert (std::is_same_v); + + } + + namespace test_inline_variables + { + + template void f(T) + {} + + template inline T g(T) + { + return T{}; + } + + template<> inline void f<>(int) + {} + + template<> int g<>(int) + { + return 5; + } + + } + +} // namespace cxx17 + +#endif // __cplusplus < 201703L + + + +_ACEOF +if ac_fn_cxx_try_compile "$LINENO" +then : + eval $cachevar=yes +else $as_nop + eval $cachevar=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + CXX="$ac_save_CXX" +fi +eval ac_res=\$$cachevar + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } + if eval test x\$$cachevar = xyes; then + CXX="$CXX $switch" + if test -n "$CXXCPP" ; then + CXXCPP="$CXXCPP $switch" + fi + ac_success=yes + break + fi + done + if test x$ac_success = xyes; then + break + fi + done + fi + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + if test x$ax_cxx_compile_cxx17_required = xtrue; then + if test x$ac_success = xno; then + as_fn_error $? "*** A compiler with support for C++17 language features is required." "$LINENO" 5 + fi + fi + if test x$ac_success = xno; then + HAVE_CXX17=0 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: No compiler with C++17 support was found" >&5 +printf "%s\n" "$as_me: No compiler with C++17 support was found" >&6;} + else + HAVE_CXX17=1 + +printf "%s\n" "#define HAVE_CXX17 1" >>confdefs.h + + fi + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 +printf %s "checking for grep that handles long lines and -e... " >&6; } +if test ${ac_cv_path_GREP+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -z "$GREP"; then + ac_path_GREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_prog in grep ggrep + do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_GREP="$as_dir$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_GREP" || continue +# Check for GNU ac_path_GREP and select it if it is found. + # Check for GNU $ac_path_GREP +case `"$ac_path_GREP" --version 2>&1` in +*GNU*) + ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; +*) + ac_count=0 + printf %s 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + printf "%s\n" 'GREP' >> "conftest.nl" + "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_GREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_GREP="$ac_path_GREP" + ac_path_GREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_GREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_GREP"; then + as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_GREP=$GREP +fi + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 +printf "%s\n" "$ac_cv_path_GREP" >&6; } + GREP="$ac_cv_path_GREP" + + +case `pwd` in + *\ * | *\ *) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5 +printf "%s\n" "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;; +esac + + + +macro_version='2.4.6' +macro_revision='2.4.6' + + + + + + + + + + + + + + +ltmain=$ac_aux_dir/ltmain.sh + +# Backslashify metacharacters that are still active within +# double-quoted strings. +sed_quote_subst='s/\(["`$\\]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\(["`\\]\)/\\\1/g' + +# Sed substitution to delay expansion of an escaped shell variable in a +# double_quote_subst'ed string. +delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' + +# Sed substitution to delay expansion of an escaped single quote. +delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' + +# Sed substitution to avoid accidental globbing in evaled expressions +no_glob_subst='s/\*/\\\*/g' + +ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5 +printf %s "checking how to print strings... " >&6; } +# Test print first, because it will be a builtin if present. +if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ + test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='print -r --' +elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='printf %s\n' +else + # Use this function as a fallback that always works. + func_fallback_echo () + { + eval 'cat <<_LTECHO_EOF +$1 +_LTECHO_EOF' + } + ECHO='func_fallback_echo' +fi + +# func_echo_all arg... +# Invoke $ECHO with all args, space-separated. +func_echo_all () +{ + $ECHO "" +} + +case $ECHO in + printf*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: printf" >&5 +printf "%s\n" "printf" >&6; } ;; + print*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: print -r" >&5 +printf "%s\n" "print -r" >&6; } ;; + *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: cat" >&5 +printf "%s\n" "cat" >&6; } ;; +esac + + + + + + + + + + + + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 +printf %s "checking for a sed that does not truncate output... " >&6; } +if test ${ac_cv_path_SED+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ + for ac_i in 1 2 3 4 5 6 7; do + ac_script="$ac_script$as_nl$ac_script" + done + echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed + { ac_script=; unset ac_script;} + if test -z "$SED"; then + ac_path_SED_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_prog in sed gsed + do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_SED="$as_dir$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_SED" || continue +# Check for GNU ac_path_SED and select it if it is found. + # Check for GNU $ac_path_SED +case `"$ac_path_SED" --version 2>&1` in +*GNU*) + ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; +*) + ac_count=0 + printf %s 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + printf "%s\n" '' >> "conftest.nl" + "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_SED_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_SED="$ac_path_SED" + ac_path_SED_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_SED_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_SED"; then + as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 + fi +else + ac_cv_path_SED=$SED +fi + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 +printf "%s\n" "$ac_cv_path_SED" >&6; } + SED="$ac_cv_path_SED" + rm -f conftest.sed + +test -z "$SED" && SED=sed +Xsed="$SED -e 1s/^X//" + + + + + + + + + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 +printf %s "checking for egrep... " >&6; } +if test ${ac_cv_path_EGREP+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 + then ac_cv_path_EGREP="$GREP -E" + else + if test -z "$EGREP"; then + ac_path_EGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_prog in egrep + do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_EGREP="$as_dir$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_EGREP" || continue +# Check for GNU ac_path_EGREP and select it if it is found. + # Check for GNU $ac_path_EGREP +case `"$ac_path_EGREP" --version 2>&1` in +*GNU*) + ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; +*) + ac_count=0 + printf %s 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + printf "%s\n" 'EGREP' >> "conftest.nl" + "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_EGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_EGREP="$ac_path_EGREP" + ac_path_EGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_EGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_EGREP"; then + as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_EGREP=$EGREP +fi + + fi +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 +printf "%s\n" "$ac_cv_path_EGREP" >&6; } + EGREP="$ac_cv_path_EGREP" + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5 +printf %s "checking for fgrep... " >&6; } +if test ${ac_cv_path_FGREP+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1 + then ac_cv_path_FGREP="$GREP -F" + else + if test -z "$FGREP"; then + ac_path_FGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_prog in fgrep + do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_FGREP="$as_dir$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_FGREP" || continue +# Check for GNU ac_path_FGREP and select it if it is found. + # Check for GNU $ac_path_FGREP +case `"$ac_path_FGREP" --version 2>&1` in +*GNU*) + ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;; +*) + ac_count=0 + printf %s 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + printf "%s\n" 'FGREP' >> "conftest.nl" + "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_FGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_FGREP="$ac_path_FGREP" + ac_path_FGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_FGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_FGREP"; then + as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_FGREP=$FGREP +fi + + fi +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5 +printf "%s\n" "$ac_cv_path_FGREP" >&6; } + FGREP="$ac_cv_path_FGREP" + + +test -z "$GREP" && GREP=grep + + + + + + + + + + + + + + + + + + + +# Check whether --with-gnu-ld was given. +if test ${with_gnu_ld+y} +then : + withval=$with_gnu_ld; test no = "$withval" || with_gnu_ld=yes +else $as_nop + with_gnu_ld=no +fi + +ac_prog=ld +if test yes = "$GCC"; then + # Check if gcc -print-prog-name=ld gives a path. + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 +printf %s "checking for ld used by $CC... " >&6; } + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return, which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [\\/]* | ?:[\\/]*) + re_direlt='/[^/][^/]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` + while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do + ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD=$ac_prog + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test yes = "$with_gnu_ld"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 +printf %s "checking for GNU ld... " >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 +printf %s "checking for non-GNU ld... " >&6; } +fi +if test ${lt_cv_path_LD+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -z "$LD"; then + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS=$lt_save_ifs + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD=$ac_dir/$ac_prog + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 &5 +printf "%s\n" "$LD" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi +test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 +printf %s "checking if the linker ($LD) is GNU ld... " >&6; } +if test ${lt_cv_prog_gnu_ld+y} +then : + printf %s "(cached) " >&6 +else $as_nop + # I'd rather use --version here, but apparently some GNU lds only accept -v. +case `$LD -v 2>&1 &5 +printf "%s\n" "$lt_cv_prog_gnu_ld" >&6; } +with_gnu_ld=$lt_cv_prog_gnu_ld + + + + + + + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5 +printf %s "checking for BSD- or MS-compatible name lister (nm)... " >&6; } +if test ${lt_cv_path_NM+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$NM"; then + # Let the user override the test. + lt_cv_path_NM=$NM +else + lt_nm_to_check=${ac_tool_prefix}nm + if test -n "$ac_tool_prefix" && test "$build" = "$host"; then + lt_nm_to_check="$lt_nm_to_check nm" + fi + for lt_tmp_nm in $lt_nm_to_check; do + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR + for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do + IFS=$lt_save_ifs + test -z "$ac_dir" && ac_dir=. + tmp_nm=$ac_dir/$lt_tmp_nm + if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext"; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the 'sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + # Tru64's nm complains that /dev/null is an invalid object file + # MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty + case $build_os in + mingw*) lt_bad_file=conftest.nm/nofile ;; + *) lt_bad_file=/dev/null ;; + esac + case `"$tmp_nm" -B $lt_bad_file 2>&1 | sed '1q'` in + *$lt_bad_file* | *'Invalid file or object type'*) + lt_cv_path_NM="$tmp_nm -B" + break 2 + ;; + *) + case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in + */dev/null*) + lt_cv_path_NM="$tmp_nm -p" + break 2 + ;; + *) + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + ;; + esac + ;; + esac + fi + done + IFS=$lt_save_ifs + done + : ${lt_cv_path_NM=no} +fi +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5 +printf "%s\n" "$lt_cv_path_NM" >&6; } +if test no != "$lt_cv_path_NM"; then + NM=$lt_cv_path_NM +else + # Didn't find any BSD compatible name lister, look for dumpbin. + if test -n "$DUMPBIN"; then : + # Let the user override the test. + else + if test -n "$ac_tool_prefix"; then + for ac_prog in dumpbin "link -dump" + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_DUMPBIN+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$DUMPBIN"; then + ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DUMPBIN=$ac_cv_prog_DUMPBIN +if test -n "$DUMPBIN"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5 +printf "%s\n" "$DUMPBIN" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + + test -n "$DUMPBIN" && break + done +fi +if test -z "$DUMPBIN"; then + ac_ct_DUMPBIN=$DUMPBIN + for ac_prog in dumpbin "link -dump" +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_DUMPBIN+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$ac_ct_DUMPBIN"; then + ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_DUMPBIN="$ac_prog" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN +if test -n "$ac_ct_DUMPBIN"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5 +printf "%s\n" "$ac_ct_DUMPBIN" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + + test -n "$ac_ct_DUMPBIN" && break +done + + if test "x$ac_ct_DUMPBIN" = x; then + DUMPBIN=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DUMPBIN=$ac_ct_DUMPBIN + fi +fi + + case `$DUMPBIN -symbols -headers /dev/null 2>&1 | sed '1q'` in + *COFF*) + DUMPBIN="$DUMPBIN -symbols -headers" + ;; + *) + DUMPBIN=: + ;; + esac + fi + + if test : != "$DUMPBIN"; then + NM=$DUMPBIN + fi +fi +test -z "$NM" && NM=nm + + + + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5 +printf %s "checking the name lister ($NM) interface... " >&6; } +if test ${lt_cv_nm_interface+y} +then : + printf %s "(cached) " >&6 +else $as_nop + lt_cv_nm_interface="BSD nm" + echo "int some_variable = 0;" > conftest.$ac_ext + (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5) + (eval "$ac_compile" 2>conftest.err) + cat conftest.err >&5 + (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5) + (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) + cat conftest.err >&5 + (eval echo "\"\$as_me:$LINENO: output\"" >&5) + cat conftest.out >&5 + if $GREP 'External.*some_variable' conftest.out > /dev/null; then + lt_cv_nm_interface="MS dumpbin" + fi + rm -f conftest* +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5 +printf "%s\n" "$lt_cv_nm_interface" >&6; } + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 +printf %s "checking whether ln -s works... " >&6; } +LN_S=$as_ln_s +if test "$LN_S" = "ln -s"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 +printf "%s\n" "no, using $LN_S" >&6; } +fi + +# find the maximum length of command line arguments +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5 +printf %s "checking the maximum length of command line arguments... " >&6; } +if test ${lt_cv_sys_max_cmd_len+y} +then : + printf %s "(cached) " >&6 +else $as_nop + i=0 + teststring=ABCD + + case $build_os in + msdosdjgpp*) + # On DJGPP, this test can blow up pretty badly due to problems in libc + # (any single argument exceeding 2000 bytes causes a buffer overrun + # during glob expansion). Even if it were fixed, the result of this + # check would be larger than it should be. + lt_cv_sys_max_cmd_len=12288; # 12K is about right + ;; + + gnu*) + # Under GNU Hurd, this test is not required because there is + # no limit to the length of command line arguments. + # Libtool will interpret -1 as no limit whatsoever + lt_cv_sys_max_cmd_len=-1; + ;; + + cygwin* | mingw* | cegcc*) + # On Win9x/ME, this test blows up -- it succeeds, but takes + # about 5 minutes as the teststring grows exponentially. + # Worse, since 9x/ME are not pre-emptively multitasking, + # you end up with a "frozen" computer, even though with patience + # the test eventually succeeds (with a max line length of 256k). + # Instead, let's just punt: use the minimum linelength reported by + # all of the supported platforms: 8192 (on NT/2K/XP). + lt_cv_sys_max_cmd_len=8192; + ;; + + mint*) + # On MiNT this can take a long time and run out of memory. + lt_cv_sys_max_cmd_len=8192; + ;; + + amigaos*) + # On AmigaOS with pdksh, this test takes hours, literally. + # So we just punt and use a minimum line length of 8192. + lt_cv_sys_max_cmd_len=8192; + ;; + + bitrig* | darwin* | dragonfly* | freebsd* | netbsd* | openbsd*) + # This has been around since 386BSD, at least. Likely further. + if test -x /sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` + elif test -x /usr/sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` + else + lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs + fi + # And add a safety zone + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + ;; + + interix*) + # We know the value 262144 and hardcode it with a safety zone (like BSD) + lt_cv_sys_max_cmd_len=196608 + ;; + + os2*) + # The test takes a long time on OS/2. + lt_cv_sys_max_cmd_len=8192 + ;; + + osf*) + # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure + # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not + # nice to cause kernel panics so lets avoid the loop below. + # First set a reasonable default. + lt_cv_sys_max_cmd_len=16384 + # + if test -x /sbin/sysconfig; then + case `/sbin/sysconfig -q proc exec_disable_arg_limit` in + *1*) lt_cv_sys_max_cmd_len=-1 ;; + esac + fi + ;; + sco3.2v5*) + lt_cv_sys_max_cmd_len=102400 + ;; + sysv5* | sco5v6* | sysv4.2uw2*) + kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` + if test -n "$kargmax"; then + lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'` + else + lt_cv_sys_max_cmd_len=32768 + fi + ;; + *) + lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` + if test -n "$lt_cv_sys_max_cmd_len" && \ + test undefined != "$lt_cv_sys_max_cmd_len"; then + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + else + # Make teststring a little bigger before we do anything with it. + # a 1K string should be a reasonable start. + for i in 1 2 3 4 5 6 7 8; do + teststring=$teststring$teststring + done + SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} + # If test is not a shell built-in, we'll probably end up computing a + # maximum length that is only half of the actual maximum length, but + # we can't tell. + while { test X`env echo "$teststring$teststring" 2>/dev/null` \ + = "X$teststring$teststring"; } >/dev/null 2>&1 && + test 17 != "$i" # 1/2 MB should be enough + do + i=`expr $i + 1` + teststring=$teststring$teststring + done + # Only check the string length outside the loop. + lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` + teststring= + # Add a significant safety factor because C++ compilers can tack on + # massive amounts of additional arguments before passing them to the + # linker. It appears as though 1/2 is a usable value. + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` + fi + ;; + esac + +fi + +if test -n "$lt_cv_sys_max_cmd_len"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5 +printf "%s\n" "$lt_cv_sys_max_cmd_len" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none" >&5 +printf "%s\n" "none" >&6; } +fi +max_cmd_len=$lt_cv_sys_max_cmd_len + + + + + + +: ${CP="cp -f"} +: ${MV="mv -f"} +: ${RM="rm -f"} + +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + lt_unset=unset +else + lt_unset=false +fi + + + + + +# test EBCDIC or ASCII +case `echo X|tr X '\101'` in + A) # ASCII based system + # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr + lt_SP2NL='tr \040 \012' + lt_NL2SP='tr \015\012 \040\040' + ;; + *) # EBCDIC based system + lt_SP2NL='tr \100 \n' + lt_NL2SP='tr \r\n \100\100' + ;; +esac + + + + + + + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to $host format" >&5 +printf %s "checking how to convert $build file names to $host format... " >&6; } +if test ${lt_cv_to_host_file_cmd+y} +then : + printf %s "(cached) " >&6 +else $as_nop + case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 + ;; + esac + ;; + *-*-cygwin* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin + ;; + esac + ;; + * ) # unhandled hosts (and "normal" native builds) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; +esac + +fi + +to_host_file_cmd=$lt_cv_to_host_file_cmd +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5 +printf "%s\n" "$lt_cv_to_host_file_cmd" >&6; } + + + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5 +printf %s "checking how to convert $build file names to toolchain format... " >&6; } +if test ${lt_cv_to_tool_file_cmd+y} +then : + printf %s "(cached) " >&6 +else $as_nop + #assume ordinary cross tools, or native build. +lt_cv_to_tool_file_cmd=func_convert_file_noop +case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 + ;; + esac + ;; +esac + +fi + +to_tool_file_cmd=$lt_cv_to_tool_file_cmd +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5 +printf "%s\n" "$lt_cv_to_tool_file_cmd" >&6; } + + + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5 +printf %s "checking for $LD option to reload object files... " >&6; } +if test ${lt_cv_ld_reload_flag+y} +then : + printf %s "(cached) " >&6 +else $as_nop + lt_cv_ld_reload_flag='-r' +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5 +printf "%s\n" "$lt_cv_ld_reload_flag" >&6; } +reload_flag=$lt_cv_ld_reload_flag +case $reload_flag in +"" | " "*) ;; +*) reload_flag=" $reload_flag" ;; +esac +reload_cmds='$LD$reload_flag -o $output$reload_objs' +case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + if test yes != "$GCC"; then + reload_cmds=false + fi + ;; + darwin*) + if test yes = "$GCC"; then + reload_cmds='$LTCC $LTCFLAGS -nostdlib $wl-r -o $output$reload_objs' + else + reload_cmds='$LD$reload_flag -o $output$reload_objs' + fi + ;; +esac + + + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. +set dummy ${ac_tool_prefix}objdump; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_OBJDUMP+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$OBJDUMP"; then + ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OBJDUMP=$ac_cv_prog_OBJDUMP +if test -n "$OBJDUMP"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 +printf "%s\n" "$OBJDUMP" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OBJDUMP"; then + ac_ct_OBJDUMP=$OBJDUMP + # Extract the first word of "objdump", so it can be a program name with args. +set dummy objdump; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_OBJDUMP+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$ac_ct_OBJDUMP"; then + ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_OBJDUMP="objdump" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP +if test -n "$ac_ct_OBJDUMP"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 +printf "%s\n" "$ac_ct_OBJDUMP" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + if test "x$ac_ct_OBJDUMP" = x; then + OBJDUMP="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OBJDUMP=$ac_ct_OBJDUMP + fi +else + OBJDUMP="$ac_cv_prog_OBJDUMP" +fi + +test -z "$OBJDUMP" && OBJDUMP=objdump + + + + + + + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5 +printf %s "checking how to recognize dependent libraries... " >&6; } +if test ${lt_cv_deplibs_check_method+y} +then : + printf %s "(cached) " >&6 +else $as_nop + lt_cv_file_magic_cmd='$MAGIC_CMD' +lt_cv_file_magic_test_file= +lt_cv_deplibs_check_method='unknown' +# Need to set the preceding variable on all platforms that support +# interlibrary dependencies. +# 'none' -- dependencies not supported. +# 'unknown' -- same as none, but documents that we really don't know. +# 'pass_all' -- all dependencies passed with no checks. +# 'test_compile' -- check by making test program. +# 'file_magic [[regex]]' -- check by looking for files in library path +# that responds to the $file_magic_cmd with a given extended regex. +# If you have 'file' or equivalent on your system and you're not sure +# whether 'pass_all' will *always* work, you probably want this one. + +case $host_os in +aix[4-9]*) + lt_cv_deplibs_check_method=pass_all + ;; + +beos*) + lt_cv_deplibs_check_method=pass_all + ;; + +bsdi[45]*) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' + lt_cv_file_magic_cmd='/usr/bin/file -L' + lt_cv_file_magic_test_file=/shlib/libc.so + ;; + +cygwin*) + # func_win32_libid is a shell function defined in ltmain.sh + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + ;; + +mingw* | pw32*) + # Base MSYS/MinGW do not provide the 'file' command needed by + # func_win32_libid shell function, so use a weaker test based on 'objdump', + # unless we find 'file', for example because we are cross-compiling. + if ( file / ) >/dev/null 2>&1; then + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + else + # Keep this pattern in sync with the one in func_win32_libid. + lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' + lt_cv_file_magic_cmd='$OBJDUMP -f' + fi + ;; + +cegcc*) + # use the weaker test based on 'objdump'. See mingw*. + lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + ;; + +darwin* | rhapsody*) + lt_cv_deplibs_check_method=pass_all + ;; + +freebsd* | dragonfly*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + case $host_cpu in + i*86 ) + # Not sure whether the presence of OpenBSD here was a mistake. + # Let's accept both of them until this is cleared up. + lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + ;; + esac + else + lt_cv_deplibs_check_method=pass_all + fi + ;; + +haiku*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20* | hpux11*) + lt_cv_file_magic_cmd=/usr/bin/file + case $host_cpu in + ia64*) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64' + lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so + ;; + hppa*64*) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]' + lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl + ;; + *) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library' + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + esac + ;; + +interix[3-9]*) + # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$' + ;; + +irix5* | irix6* | nonstopux*) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$' + fi + ;; + +newos6*) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +*nto* | *qnx*) + lt_cv_deplibs_check_method=pass_all + ;; + +openbsd* | bitrig*) + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' + fi + ;; + +osf3* | osf4* | osf5*) + lt_cv_deplibs_check_method=pass_all + ;; + +rdos*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv4 | sysv4.3*) + case $host_vendor in + motorola) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + ncr) + lt_cv_deplibs_check_method=pass_all + ;; + sequent) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' + ;; + sni) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib" + lt_cv_file_magic_test_file=/lib/libc.so + ;; + siemens) + lt_cv_deplibs_check_method=pass_all + ;; + pc) + lt_cv_deplibs_check_method=pass_all + ;; + esac + ;; + +tpf*) + lt_cv_deplibs_check_method=pass_all + ;; +os2*) + lt_cv_deplibs_check_method=pass_all + ;; +esac + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5 +printf "%s\n" "$lt_cv_deplibs_check_method" >&6; } + +file_magic_glob= +want_nocaseglob=no +if test "$build" = "$host"; then + case $host_os in + mingw* | pw32*) + if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then + want_nocaseglob=yes + else + file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[\1]\/[\1]\/g;/g"` + fi + ;; + esac +fi + +file_magic_cmd=$lt_cv_file_magic_cmd +deplibs_check_method=$lt_cv_deplibs_check_method +test -z "$deplibs_check_method" && deplibs_check_method=unknown + + + + + + + + + + + + + + + + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args. +set dummy ${ac_tool_prefix}dlltool; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_DLLTOOL+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$DLLTOOL"; then + ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DLLTOOL=$ac_cv_prog_DLLTOOL +if test -n "$DLLTOOL"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5 +printf "%s\n" "$DLLTOOL" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_DLLTOOL"; then + ac_ct_DLLTOOL=$DLLTOOL + # Extract the first word of "dlltool", so it can be a program name with args. +set dummy dlltool; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_DLLTOOL+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$ac_ct_DLLTOOL"; then + ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_DLLTOOL="dlltool" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL +if test -n "$ac_ct_DLLTOOL"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5 +printf "%s\n" "$ac_ct_DLLTOOL" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + if test "x$ac_ct_DLLTOOL" = x; then + DLLTOOL="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DLLTOOL=$ac_ct_DLLTOOL + fi +else + DLLTOOL="$ac_cv_prog_DLLTOOL" +fi + +test -z "$DLLTOOL" && DLLTOOL=dlltool + + + + + + + + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5 +printf %s "checking how to associate runtime and link libraries... " >&6; } +if test ${lt_cv_sharedlib_from_linklib_cmd+y} +then : + printf %s "(cached) " >&6 +else $as_nop + lt_cv_sharedlib_from_linklib_cmd='unknown' + +case $host_os in +cygwin* | mingw* | pw32* | cegcc*) + # two different shell functions defined in ltmain.sh; + # decide which one to use based on capabilities of $DLLTOOL + case `$DLLTOOL --help 2>&1` in + *--identify-strict*) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib + ;; + *) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback + ;; + esac + ;; +*) + # fallback: assume linklib IS sharedlib + lt_cv_sharedlib_from_linklib_cmd=$ECHO + ;; +esac + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5 +printf "%s\n" "$lt_cv_sharedlib_from_linklib_cmd" >&6; } +sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd +test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO + + + + + + + +if test -n "$ac_tool_prefix"; then + for ac_prog in ar + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_AR+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$AR"; then + ac_cv_prog_AR="$AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_AR="$ac_tool_prefix$ac_prog" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AR=$ac_cv_prog_AR +if test -n "$AR"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 +printf "%s\n" "$AR" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + + test -n "$AR" && break + done +fi +if test -z "$AR"; then + ac_ct_AR=$AR + for ac_prog in ar +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_AR+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$ac_ct_AR"; then + ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_AR="$ac_prog" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_AR=$ac_cv_prog_ac_ct_AR +if test -n "$ac_ct_AR"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 +printf "%s\n" "$ac_ct_AR" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + + test -n "$ac_ct_AR" && break +done + + if test "x$ac_ct_AR" = x; then + AR="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + AR=$ac_ct_AR + fi +fi + +: ${AR=ar} +: ${AR_FLAGS=cr} + + + + + + + + + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5 +printf %s "checking for archiver @FILE support... " >&6; } +if test ${lt_cv_ar_at_file+y} +then : + printf %s "(cached) " >&6 +else $as_nop + lt_cv_ar_at_file=no + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + echo conftest.$ac_objext > conftest.lst + lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5' + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 + (eval $lt_ar_try) 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if test 0 -eq "$ac_status"; then + # Ensure the archiver fails upon bogus file names. + rm -f conftest.$ac_objext libconftest.a + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 + (eval $lt_ar_try) 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if test 0 -ne "$ac_status"; then + lt_cv_ar_at_file=@ + fi + fi + rm -f conftest.* libconftest.a + +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5 +printf "%s\n" "$lt_cv_ar_at_file" >&6; } + +if test no = "$lt_cv_ar_at_file"; then + archiver_list_spec= +else + archiver_list_spec=$lt_cv_ar_at_file +fi + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_STRIP+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 +printf "%s\n" "$STRIP" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_STRIP+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_STRIP="strip" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 +printf "%s\n" "$ac_ct_STRIP" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + +test -z "$STRIP" && STRIP=: + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_RANLIB+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +RANLIB=$ac_cv_prog_RANLIB +if test -n "$RANLIB"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 +printf "%s\n" "$RANLIB" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_RANLIB"; then + ac_ct_RANLIB=$RANLIB + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_RANLIB+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$ac_ct_RANLIB"; then + ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_RANLIB="ranlib" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB +if test -n "$ac_ct_RANLIB"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 +printf "%s\n" "$ac_ct_RANLIB" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + if test "x$ac_ct_RANLIB" = x; then + RANLIB=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + RANLIB=$ac_ct_RANLIB + fi +else + RANLIB="$ac_cv_prog_RANLIB" +fi + +test -z "$RANLIB" && RANLIB=: + + + + + + +# Determine commands to create old-style static archives. +old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' +old_postinstall_cmds='chmod 644 $oldlib' +old_postuninstall_cmds= + +if test -n "$RANLIB"; then + case $host_os in + bitrig* | openbsd*) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" + ;; + *) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" + ;; + esac + old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" +fi + +case $host_os in + darwin*) + lock_old_archive_extraction=yes ;; + *) + lock_old_archive_extraction=no ;; +esac + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + + +# Check for command to grab the raw symbol name followed by C symbol from nm. +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5 +printf %s "checking command to parse $NM output from $compiler object... " >&6; } +if test ${lt_cv_sys_global_symbol_pipe+y} +then : + printf %s "(cached) " >&6 +else $as_nop + +# These are sane defaults that work on at least a few old systems. +# [They come from Ultrix. What could be older than Ultrix?!! ;)] + +# Character class describing NM global symbol codes. +symcode='[BCDEGRST]' + +# Regexp to match symbols that can be accessed directly from C. +sympat='\([_A-Za-z][_A-Za-z0-9]*\)' + +# Define system-specific variables. +case $host_os in +aix*) + symcode='[BCDT]' + ;; +cygwin* | mingw* | pw32* | cegcc*) + symcode='[ABCDGISTW]' + ;; +hpux*) + if test ia64 = "$host_cpu"; then + symcode='[ABCDEGRST]' + fi + ;; +irix* | nonstopux*) + symcode='[BCDEGRST]' + ;; +osf*) + symcode='[BCDEGQRST]' + ;; +solaris*) + symcode='[BDRT]' + ;; +sco3.2v5*) + symcode='[DT]' + ;; +sysv4.2uw2*) + symcode='[DT]' + ;; +sysv5* | sco5v6* | unixware* | OpenUNIX*) + symcode='[ABDT]' + ;; +sysv4) + symcode='[DFNSTU]' + ;; +esac + +# If we're using GNU nm, then use its standard symbol codes. +case `$NM -V 2>&1` in +*GNU* | *'with BFD'*) + symcode='[ABCDGIRSTW]' ;; +esac + +if test "$lt_cv_nm_interface" = "MS dumpbin"; then + # Gets list of data symbols to import. + lt_cv_sys_global_symbol_to_import="sed -n -e 's/^I .* \(.*\)$/\1/p'" + # Adjust the below global symbol transforms to fixup imported variables. + lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'" + lt_c_name_hook=" -e 's/^I .* \(.*\)$/ {\"\1\", (void *) 0},/p'" + lt_c_name_lib_hook="\ + -e 's/^I .* \(lib.*\)$/ {\"\1\", (void *) 0},/p'\ + -e 's/^I .* \(.*\)$/ {\"lib\1\", (void *) 0},/p'" +else + # Disable hooks by default. + lt_cv_sys_global_symbol_to_import= + lt_cdecl_hook= + lt_c_name_hook= + lt_c_name_lib_hook= +fi + +# Transform an extracted symbol line into a proper C declaration. +# Some systems (esp. on ia64) link data and code symbols differently, +# so use this general approach. +lt_cv_sys_global_symbol_to_cdecl="sed -n"\ +$lt_cdecl_hook\ +" -e 's/^T .* \(.*\)$/extern int \1();/p'"\ +" -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'" + +# Transform an extracted symbol line into symbol name and symbol address +lt_cv_sys_global_symbol_to_c_name_address="sed -n"\ +$lt_c_name_hook\ +" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ +" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/p'" + +# Transform an extracted symbol line into symbol name with lib prefix and +# symbol address. +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n"\ +$lt_c_name_lib_hook\ +" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ +" -e 's/^$symcode$symcode* .* \(lib.*\)$/ {\"\1\", (void *) \&\1},/p'"\ +" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"lib\1\", (void *) \&\1},/p'" + +# Handle CRLF in mingw tool chain +opt_cr= +case $build_os in +mingw*) + opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp + ;; +esac + +# Try without a prefix underscore, then with it. +for ac_symprfx in "" "_"; do + + # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. + symxfrm="\\1 $ac_symprfx\\2 \\2" + + # Write the raw and C identifiers. + if test "$lt_cv_nm_interface" = "MS dumpbin"; then + # Fake it for dumpbin and say T for any non-static function, + # D for any global variable and I for any imported variable. + # Also find C++ and __fastcall symbols from MSVC++, + # which start with @ or ?. + lt_cv_sys_global_symbol_pipe="$AWK '"\ +" {last_section=section; section=\$ 3};"\ +" /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ +" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ +" /^ *Symbol name *: /{split(\$ 0,sn,\":\"); si=substr(sn[2],2)};"\ +" /^ *Type *: code/{print \"T\",si,substr(si,length(prfx))};"\ +" /^ *Type *: data/{print \"I\",si,substr(si,length(prfx))};"\ +" \$ 0!~/External *\|/{next};"\ +" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ +" {if(hide[section]) next};"\ +" {f=\"D\"}; \$ 0~/\(\).*\|/{f=\"T\"};"\ +" {split(\$ 0,a,/\||\r/); split(a[2],s)};"\ +" s[1]~/^[@?]/{print f,s[1],s[1]; next};"\ +" s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\ +" ' prfx=^$ac_symprfx" + else + lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" + fi + lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" + + # Check to see that the pipe works correctly. + pipe_works=no + + rm -f conftest* + cat > conftest.$ac_ext <<_LT_EOF +#ifdef __cplusplus +extern "C" { +#endif +char nm_test_var; +void nm_test_func(void); +void nm_test_func(void){} +#ifdef __cplusplus +} +#endif +int main(){nm_test_var='a';nm_test_func();return(0);} +_LT_EOF + + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + # Now try to grab the symbols. + nlist=conftest.nm + $ECHO "$as_me:$LINENO: $NM conftest.$ac_objext | $lt_cv_sys_global_symbol_pipe > $nlist" >&5 + if eval "$NM" conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist 2>&5 && test -s "$nlist"; then + # Try sorting and uniquifying the output. + if sort "$nlist" | uniq > "$nlist"T; then + mv -f "$nlist"T "$nlist" + else + rm -f "$nlist"T + fi + + # Make sure that we snagged all the symbols we need. + if $GREP ' nm_test_var$' "$nlist" >/dev/null; then + if $GREP ' nm_test_func$' "$nlist" >/dev/null; then + cat <<_LT_EOF > conftest.$ac_ext +/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ +#if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE +/* DATA imports from DLLs on WIN32 can't be const, because runtime + relocations are performed -- see ld's documentation on pseudo-relocs. */ +# define LT_DLSYM_CONST +#elif defined __osf__ +/* This system does not cope well with relocations in const data. */ +# define LT_DLSYM_CONST +#else +# define LT_DLSYM_CONST const +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +_LT_EOF + # Now generate the symbol file. + eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' + + cat <<_LT_EOF >> conftest.$ac_ext + +/* The mapping between symbol names and symbols. */ +LT_DLSYM_CONST struct { + const char *name; + void *address; +} +lt__PROGRAM__LTX_preloaded_symbols[] = +{ + { "@PROGRAM@", (void *) 0 }, +_LT_EOF + $SED "s/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext + cat <<\_LT_EOF >> conftest.$ac_ext + {0, (void *) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt__PROGRAM__LTX_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif +_LT_EOF + # Now try linking the two files. + mv conftest.$ac_objext conftstm.$ac_objext + lt_globsym_save_LIBS=$LIBS + lt_globsym_save_CFLAGS=$CFLAGS + LIBS=conftstm.$ac_objext + CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s conftest$ac_exeext; then + pipe_works=yes + fi + LIBS=$lt_globsym_save_LIBS + CFLAGS=$lt_globsym_save_CFLAGS + else + echo "cannot find nm_test_func in $nlist" >&5 + fi + else + echo "cannot find nm_test_var in $nlist" >&5 + fi + else + echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5 + fi + else + echo "$progname: failed program was:" >&5 + cat conftest.$ac_ext >&5 + fi + rm -rf conftest* conftst* + + # Do not use the global_symbol_pipe unless it works. + if test yes = "$pipe_works"; then + break + else + lt_cv_sys_global_symbol_pipe= + fi +done + +fi + +if test -z "$lt_cv_sys_global_symbol_pipe"; then + lt_cv_sys_global_symbol_to_cdecl= +fi +if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: failed" >&5 +printf "%s\n" "failed" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: ok" >&5 +printf "%s\n" "ok" >&6; } +fi + +# Response file support. +if test "$lt_cv_nm_interface" = "MS dumpbin"; then + nm_file_list_spec='@' +elif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then + nm_file_list_spec='@' +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5 +printf %s "checking for sysroot... " >&6; } + +# Check whether --with-sysroot was given. +if test ${with_sysroot+y} +then : + withval=$with_sysroot; +else $as_nop + with_sysroot=no +fi + + +lt_sysroot= +case $with_sysroot in #( + yes) + if test yes = "$GCC"; then + lt_sysroot=`$CC --print-sysroot 2>/dev/null` + fi + ;; #( + /*) + lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` + ;; #( + no|'') + ;; #( + *) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $with_sysroot" >&5 +printf "%s\n" "$with_sysroot" >&6; } + as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5 + ;; +esac + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5 +printf "%s\n" "${lt_sysroot:-no}" >&6; } + + + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a working dd" >&5 +printf %s "checking for a working dd... " >&6; } +if test ${ac_cv_path_lt_DD+y} +then : + printf %s "(cached) " >&6 +else $as_nop + printf 0123456789abcdef0123456789abcdef >conftest.i +cat conftest.i conftest.i >conftest2.i +: ${lt_DD:=$DD} +if test -z "$lt_DD"; then + ac_path_lt_DD_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_prog in dd + do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_lt_DD="$as_dir$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_lt_DD" || continue +if "$ac_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then + cmp -s conftest.i conftest.out \ + && ac_cv_path_lt_DD="$ac_path_lt_DD" ac_path_lt_DD_found=: +fi + $ac_path_lt_DD_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_lt_DD"; then + : + fi +else + ac_cv_path_lt_DD=$lt_DD +fi + +rm -f conftest.i conftest2.i conftest.out +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_lt_DD" >&5 +printf "%s\n" "$ac_cv_path_lt_DD" >&6; } + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to truncate binary pipes" >&5 +printf %s "checking how to truncate binary pipes... " >&6; } +if test ${lt_cv_truncate_bin+y} +then : + printf %s "(cached) " >&6 +else $as_nop + printf 0123456789abcdef0123456789abcdef >conftest.i +cat conftest.i conftest.i >conftest2.i +lt_cv_truncate_bin= +if "$ac_cv_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then + cmp -s conftest.i conftest.out \ + && lt_cv_truncate_bin="$ac_cv_path_lt_DD bs=4096 count=1" +fi +rm -f conftest.i conftest2.i conftest.out +test -z "$lt_cv_truncate_bin" && lt_cv_truncate_bin="$SED -e 4q" +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_truncate_bin" >&5 +printf "%s\n" "$lt_cv_truncate_bin" >&6; } + + + + + + + +# Calculate cc_basename. Skip known compiler wrappers and cross-prefix. +func_cc_basename () +{ + for cc_temp in $*""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac + done + func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` +} + +# Check whether --enable-libtool-lock was given. +if test ${enable_libtool_lock+y} +then : + enableval=$enable_libtool_lock; +fi + +test no = "$enable_libtool_lock" || enable_libtool_lock=yes + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case $host in +ia64-*-hpux*) + # Find out what ABI is being produced by ac_compile, and set mode + # options accordingly. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.$ac_objext` in + *ELF-32*) + HPUX_IA64_MODE=32 + ;; + *ELF-64*) + HPUX_IA64_MODE=64 + ;; + esac + fi + rm -rf conftest* + ;; +*-*-irix6*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. + echo '#line '$LINENO' "configure"' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + if test yes = "$lt_cv_prog_gnu_ld"; then + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -melf32bsmip" + ;; + *N32*) + LD="${LD-ld} -melf32bmipn32" + ;; + *64-bit*) + LD="${LD-ld} -melf64bmip" + ;; + esac + else + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + fi + rm -rf conftest* + ;; + +mips64*-*linux*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. + echo '#line '$LINENO' "configure"' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + emul=elf + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + emul="${emul}32" + ;; + *64-bit*) + emul="${emul}64" + ;; + esac + case `/usr/bin/file conftest.$ac_objext` in + *MSB*) + emul="${emul}btsmip" + ;; + *LSB*) + emul="${emul}ltsmip" + ;; + esac + case `/usr/bin/file conftest.$ac_objext` in + *N32*) + emul="${emul}n32" + ;; + esac + LD="${LD-ld} -m $emul" + fi + rm -rf conftest* + ;; + +x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ +s390*-*linux*|s390*-*tpf*|sparc*-*linux*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. Note that the listed cases only cover the + # situations where additional linker options are needed (such as when + # doing 32-bit compilation for a host where ld defaults to 64-bit, or + # vice versa); the common cases where no linker options are needed do + # not appear in the list. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.o` in + *32-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_i386_fbsd" + ;; + x86_64-*linux*) + case `/usr/bin/file conftest.o` in + *x86-64*) + LD="${LD-ld} -m elf32_x86_64" + ;; + *) + LD="${LD-ld} -m elf_i386" + ;; + esac + ;; + powerpc64le-*linux*) + LD="${LD-ld} -m elf32lppclinux" + ;; + powerpc64-*linux*) + LD="${LD-ld} -m elf32ppclinux" + ;; + s390x-*linux*) + LD="${LD-ld} -m elf_s390" + ;; + sparc64-*linux*) + LD="${LD-ld} -m elf32_sparc" + ;; + esac + ;; + *64-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_x86_64_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_x86_64" + ;; + powerpcle-*linux*) + LD="${LD-ld} -m elf64lppc" + ;; + powerpc-*linux*) + LD="${LD-ld} -m elf64ppc" + ;; + s390*-*linux*|s390*-*tpf*) + LD="${LD-ld} -m elf64_s390" + ;; + sparc*-*linux*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS=$CFLAGS + CFLAGS="$CFLAGS -belf" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5 +printf %s "checking whether the C compiler needs -belf... " >&6; } +if test ${lt_cv_cc_needs_belf+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + lt_cv_cc_needs_belf=yes +else $as_nop + lt_cv_cc_needs_belf=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5 +printf "%s\n" "$lt_cv_cc_needs_belf" >&6; } + if test yes != "$lt_cv_cc_needs_belf"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS=$SAVE_CFLAGS + fi + ;; +*-*solaris*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.o` in + *64-bit*) + case $lt_cv_prog_gnu_ld in + yes*) + case $host in + i?86-*-solaris*|x86_64-*-solaris*) + LD="${LD-ld} -m elf_x86_64" + ;; + sparc*-*-solaris*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + # GNU ld 2.21 introduced _sol2 emulations. Use them if available. + if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then + LD=${LD-ld}_sol2 + fi + ;; + *) + if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then + LD="${LD-ld} -64" + fi + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; +esac + +need_locks=$enable_libtool_lock + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args. +set dummy ${ac_tool_prefix}mt; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_MANIFEST_TOOL+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$MANIFEST_TOOL"; then + ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL +if test -n "$MANIFEST_TOOL"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5 +printf "%s\n" "$MANIFEST_TOOL" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_MANIFEST_TOOL"; then + ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL + # Extract the first word of "mt", so it can be a program name with args. +set dummy mt; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_MANIFEST_TOOL+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$ac_ct_MANIFEST_TOOL"; then + ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_MANIFEST_TOOL="mt" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL +if test -n "$ac_ct_MANIFEST_TOOL"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5 +printf "%s\n" "$ac_ct_MANIFEST_TOOL" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + if test "x$ac_ct_MANIFEST_TOOL" = x; then + MANIFEST_TOOL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL + fi +else + MANIFEST_TOOL="$ac_cv_prog_MANIFEST_TOOL" +fi + +test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5 +printf %s "checking if $MANIFEST_TOOL is a manifest tool... " >&6; } +if test ${lt_cv_path_mainfest_tool+y} +then : + printf %s "(cached) " >&6 +else $as_nop + lt_cv_path_mainfest_tool=no + echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5 + $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out + cat conftest.err >&5 + if $GREP 'Manifest Tool' conftest.out > /dev/null; then + lt_cv_path_mainfest_tool=yes + fi + rm -f conftest* +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5 +printf "%s\n" "$lt_cv_path_mainfest_tool" >&6; } +if test yes != "$lt_cv_path_mainfest_tool"; then + MANIFEST_TOOL=: +fi + + + + + + + case $host_os in + rhapsody* | darwin*) + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args. +set dummy ${ac_tool_prefix}dsymutil; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_DSYMUTIL+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$DSYMUTIL"; then + ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DSYMUTIL=$ac_cv_prog_DSYMUTIL +if test -n "$DSYMUTIL"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5 +printf "%s\n" "$DSYMUTIL" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_DSYMUTIL"; then + ac_ct_DSYMUTIL=$DSYMUTIL + # Extract the first word of "dsymutil", so it can be a program name with args. +set dummy dsymutil; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_DSYMUTIL+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$ac_ct_DSYMUTIL"; then + ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_DSYMUTIL="dsymutil" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL +if test -n "$ac_ct_DSYMUTIL"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5 +printf "%s\n" "$ac_ct_DSYMUTIL" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + if test "x$ac_ct_DSYMUTIL" = x; then + DSYMUTIL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DSYMUTIL=$ac_ct_DSYMUTIL + fi +else + DSYMUTIL="$ac_cv_prog_DSYMUTIL" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args. +set dummy ${ac_tool_prefix}nmedit; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_NMEDIT+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$NMEDIT"; then + ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +NMEDIT=$ac_cv_prog_NMEDIT +if test -n "$NMEDIT"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5 +printf "%s\n" "$NMEDIT" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_NMEDIT"; then + ac_ct_NMEDIT=$NMEDIT + # Extract the first word of "nmedit", so it can be a program name with args. +set dummy nmedit; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_NMEDIT+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$ac_ct_NMEDIT"; then + ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_NMEDIT="nmedit" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT +if test -n "$ac_ct_NMEDIT"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5 +printf "%s\n" "$ac_ct_NMEDIT" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + if test "x$ac_ct_NMEDIT" = x; then + NMEDIT=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + NMEDIT=$ac_ct_NMEDIT + fi +else + NMEDIT="$ac_cv_prog_NMEDIT" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args. +set dummy ${ac_tool_prefix}lipo; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_LIPO+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$LIPO"; then + ac_cv_prog_LIPO="$LIPO" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_LIPO="${ac_tool_prefix}lipo" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +LIPO=$ac_cv_prog_LIPO +if test -n "$LIPO"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5 +printf "%s\n" "$LIPO" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_LIPO"; then + ac_ct_LIPO=$LIPO + # Extract the first word of "lipo", so it can be a program name with args. +set dummy lipo; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_LIPO+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$ac_ct_LIPO"; then + ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_LIPO="lipo" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO +if test -n "$ac_ct_LIPO"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5 +printf "%s\n" "$ac_ct_LIPO" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + if test "x$ac_ct_LIPO" = x; then + LIPO=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + LIPO=$ac_ct_LIPO + fi +else + LIPO="$ac_cv_prog_LIPO" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args. +set dummy ${ac_tool_prefix}otool; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_OTOOL+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$OTOOL"; then + ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_OTOOL="${ac_tool_prefix}otool" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OTOOL=$ac_cv_prog_OTOOL +if test -n "$OTOOL"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5 +printf "%s\n" "$OTOOL" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OTOOL"; then + ac_ct_OTOOL=$OTOOL + # Extract the first word of "otool", so it can be a program name with args. +set dummy otool; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_OTOOL+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$ac_ct_OTOOL"; then + ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_OTOOL="otool" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL +if test -n "$ac_ct_OTOOL"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5 +printf "%s\n" "$ac_ct_OTOOL" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + if test "x$ac_ct_OTOOL" = x; then + OTOOL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OTOOL=$ac_ct_OTOOL + fi +else + OTOOL="$ac_cv_prog_OTOOL" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args. +set dummy ${ac_tool_prefix}otool64; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_OTOOL64+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$OTOOL64"; then + ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OTOOL64=$ac_cv_prog_OTOOL64 +if test -n "$OTOOL64"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5 +printf "%s\n" "$OTOOL64" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OTOOL64"; then + ac_ct_OTOOL64=$OTOOL64 + # Extract the first word of "otool64", so it can be a program name with args. +set dummy otool64; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_OTOOL64+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$ac_ct_OTOOL64"; then + ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_OTOOL64="otool64" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64 +if test -n "$ac_ct_OTOOL64"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5 +printf "%s\n" "$ac_ct_OTOOL64" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + if test "x$ac_ct_OTOOL64" = x; then + OTOOL64=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OTOOL64=$ac_ct_OTOOL64 + fi +else + OTOOL64="$ac_cv_prog_OTOOL64" +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5 +printf %s "checking for -single_module linker flag... " >&6; } +if test ${lt_cv_apple_cc_single_mod+y} +then : + printf %s "(cached) " >&6 +else $as_nop + lt_cv_apple_cc_single_mod=no + if test -z "$LT_MULTI_MODULE"; then + # By default we will add the -single_module flag. You can override + # by either setting the environment variable LT_MULTI_MODULE + # non-empty at configure time, or by adding -multi_module to the + # link flags. + rm -rf libconftest.dylib* + echo "int foo(void){return 1;}" > conftest.c + echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ +-dynamiclib -Wl,-single_module conftest.c" >&5 + $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ + -dynamiclib -Wl,-single_module conftest.c 2>conftest.err + _lt_result=$? + # If there is a non-empty error log, and "single_module" + # appears in it, assume the flag caused a linker warning + if test -s conftest.err && $GREP single_module conftest.err; then + cat conftest.err >&5 + # Otherwise, if the output was created with a 0 exit code from + # the compiler, it worked. + elif test -f libconftest.dylib && test 0 = "$_lt_result"; then + lt_cv_apple_cc_single_mod=yes + else + cat conftest.err >&5 + fi + rm -rf libconftest.dylib* + rm -f conftest.* + fi +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5 +printf "%s\n" "$lt_cv_apple_cc_single_mod" >&6; } + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5 +printf %s "checking for -exported_symbols_list linker flag... " >&6; } +if test ${lt_cv_ld_exported_symbols_list+y} +then : + printf %s "(cached) " >&6 +else $as_nop + lt_cv_ld_exported_symbols_list=no + save_LDFLAGS=$LDFLAGS + echo "_main" > conftest.sym + LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + lt_cv_ld_exported_symbols_list=yes +else $as_nop + lt_cv_ld_exported_symbols_list=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS=$save_LDFLAGS + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5 +printf "%s\n" "$lt_cv_ld_exported_symbols_list" >&6; } + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5 +printf %s "checking for -force_load linker flag... " >&6; } +if test ${lt_cv_ld_force_load+y} +then : + printf %s "(cached) " >&6 +else $as_nop + lt_cv_ld_force_load=no + cat > conftest.c << _LT_EOF +int forced_loaded() { return 2;} +_LT_EOF + echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5 + $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5 + echo "$AR cr libconftest.a conftest.o" >&5 + $AR cr libconftest.a conftest.o 2>&5 + echo "$RANLIB libconftest.a" >&5 + $RANLIB libconftest.a 2>&5 + cat > conftest.c << _LT_EOF +int main() { return 0;} +_LT_EOF + echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5 + $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err + _lt_result=$? + if test -s conftest.err && $GREP force_load conftest.err; then + cat conftest.err >&5 + elif test -f conftest && test 0 = "$_lt_result" && $GREP forced_load conftest >/dev/null 2>&1; then + lt_cv_ld_force_load=yes + else + cat conftest.err >&5 + fi + rm -f conftest.err libconftest.a conftest conftest.c + rm -rf conftest.dSYM + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5 +printf "%s\n" "$lt_cv_ld_force_load" >&6; } + case $host_os in + rhapsody* | darwin1.[012]) + _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;; + darwin1.*) + _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; + darwin*) # darwin 5.x on + # if running on 10.5 or later, the deployment target defaults + # to the OS version, if on x86, and 10.4, the deployment + # target defaults to 10.4. Don't you love it? + case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in + 10.0,*86*-darwin8*|10.0,*-darwin[912]*) + _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; + 10.[012][,.]*) + _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; + 10.*|11.*) + _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; + esac + ;; + esac + if test yes = "$lt_cv_apple_cc_single_mod"; then + _lt_dar_single_mod='$single_module' + fi + if test yes = "$lt_cv_ld_exported_symbols_list"; then + _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym' + else + _lt_dar_export_syms='~$NMEDIT -s $output_objdir/$libname-symbols.expsym $lib' + fi + if test : != "$DSYMUTIL" && test no = "$lt_cv_ld_force_load"; then + _lt_dsymutil='~$DSYMUTIL $lib || :' + else + _lt_dsymutil= + fi + ;; + esac + +# func_munge_path_list VARIABLE PATH +# ----------------------------------- +# VARIABLE is name of variable containing _space_ separated list of +# directories to be munged by the contents of PATH, which is string +# having a format: +# "DIR[:DIR]:" +# string "DIR[ DIR]" will be prepended to VARIABLE +# ":DIR[:DIR]" +# string "DIR[ DIR]" will be appended to VARIABLE +# "DIRP[:DIRP]::[DIRA:]DIRA" +# string "DIRP[ DIRP]" will be prepended to VARIABLE and string +# "DIRA[ DIRA]" will be appended to VARIABLE +# "DIR[:DIR]" +# VARIABLE will be replaced by "DIR[ DIR]" +func_munge_path_list () +{ + case x$2 in + x) + ;; + *:) + eval $1=\"`$ECHO $2 | $SED 's/:/ /g'` \$$1\" + ;; + x:*) + eval $1=\"\$$1 `$ECHO $2 | $SED 's/:/ /g'`\" + ;; + *::*) + eval $1=\"\$$1\ `$ECHO $2 | $SED -e 's/.*:://' -e 's/:/ /g'`\" + eval $1=\"`$ECHO $2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \$$1\" + ;; + *) + eval $1=\"`$ECHO $2 | $SED 's/:/ /g'`\" + ;; + esac +} + +ac_header= ac_cache= +for ac_item in $ac_header_c_list +do + if test $ac_cache; then + ac_fn_c_check_header_compile "$LINENO" $ac_header ac_cv_header_$ac_cache "$ac_includes_default" + if eval test \"x\$ac_cv_header_$ac_cache\" = xyes; then + printf "%s\n" "#define $ac_item 1" >> confdefs.h + fi + ac_header= ac_cache= + elif test $ac_header; then + ac_cache=$ac_item + else + ac_header=$ac_item + fi +done + + + + + + + + +if test $ac_cv_header_stdlib_h = yes && test $ac_cv_header_string_h = yes +then : + +printf "%s\n" "#define STDC_HEADERS 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default +" +if test "x$ac_cv_header_dlfcn_h" = xyes +then : + printf "%s\n" "#define HAVE_DLFCN_H 1" >>confdefs.h + +fi + + + +func_stripname_cnf () +{ + case $2 in + .*) func_stripname_result=`$ECHO "$3" | $SED "s%^$1%%; s%\\\\$2\$%%"`;; + *) func_stripname_result=`$ECHO "$3" | $SED "s%^$1%%; s%$2\$%%"`;; + esac +} # func_stripname_cnf + + + + + +# Set options + + + + enable_dlopen=no + + + enable_win32_dll=no + + + # Check whether --enable-shared was given. +if test ${enable_shared+y} +then : + enableval=$enable_shared; p=${PACKAGE-default} + case $enableval in + yes) enable_shared=yes ;; + no) enable_shared=no ;; + *) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for pkg in $enableval; do + IFS=$lt_save_ifs + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS=$lt_save_ifs + ;; + esac +else $as_nop + enable_shared=yes +fi + + + + + + + + + + # Check whether --enable-static was given. +if test ${enable_static+y} +then : + enableval=$enable_static; p=${PACKAGE-default} + case $enableval in + yes) enable_static=yes ;; + no) enable_static=no ;; + *) + enable_static=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for pkg in $enableval; do + IFS=$lt_save_ifs + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS=$lt_save_ifs + ;; + esac +else $as_nop + enable_static=yes +fi + + + + + + + + + + +# Check whether --with-pic was given. +if test ${with_pic+y} +then : + withval=$with_pic; lt_p=${PACKAGE-default} + case $withval in + yes|no) pic_mode=$withval ;; + *) + pic_mode=default + # Look at the argument we got. We use all the common list separators. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for lt_pkg in $withval; do + IFS=$lt_save_ifs + if test "X$lt_pkg" = "X$lt_p"; then + pic_mode=yes + fi + done + IFS=$lt_save_ifs + ;; + esac +else $as_nop + pic_mode=default +fi + + + + + + + + + # Check whether --enable-fast-install was given. +if test ${enable_fast_install+y} +then : + enableval=$enable_fast_install; p=${PACKAGE-default} + case $enableval in + yes) enable_fast_install=yes ;; + no) enable_fast_install=no ;; + *) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for pkg in $enableval; do + IFS=$lt_save_ifs + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS=$lt_save_ifs + ;; + esac +else $as_nop + enable_fast_install=yes +fi + + + + + + + + + shared_archive_member_spec= +case $host,$enable_shared in +power*-*-aix[5-9]*,yes) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking which variant of shared library versioning to provide" >&5 +printf %s "checking which variant of shared library versioning to provide... " >&6; } + +# Check whether --with-aix-soname was given. +if test ${with_aix_soname+y} +then : + withval=$with_aix_soname; case $withval in + aix|svr4|both) + ;; + *) + as_fn_error $? "Unknown argument to --with-aix-soname" "$LINENO" 5 + ;; + esac + lt_cv_with_aix_soname=$with_aix_soname +else $as_nop + if test ${lt_cv_with_aix_soname+y} +then : + printf %s "(cached) " >&6 +else $as_nop + lt_cv_with_aix_soname=aix +fi + + with_aix_soname=$lt_cv_with_aix_soname +fi + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $with_aix_soname" >&5 +printf "%s\n" "$with_aix_soname" >&6; } + if test aix != "$with_aix_soname"; then + # For the AIX way of multilib, we name the shared archive member + # based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o', + # and 'shr.imp' or 'shr_64.imp', respectively, for the Import File. + # Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag, + # the AIX toolchain works better with OBJECT_MODE set (default 32). + if test 64 = "${OBJECT_MODE-32}"; then + shared_archive_member_spec=shr_64 + else + shared_archive_member_spec=shr + fi + fi + ;; +*) + with_aix_soname=aix + ;; +esac + + + + + + + + + + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS=$ltmain + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +test -z "$LN_S" && LN_S="ln -s" + + + + + + + + + + + + + + +if test -n "${ZSH_VERSION+set}"; then + setopt NO_GLOB_SUBST +fi + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5 +printf %s "checking for objdir... " >&6; } +if test ${lt_cv_objdir+y} +then : + printf %s "(cached) " >&6 +else $as_nop + rm -f .libs 2>/dev/null +mkdir .libs 2>/dev/null +if test -d .libs; then + lt_cv_objdir=.libs +else + # MS-DOS does not allow filenames that begin with a dot. + lt_cv_objdir=_libs +fi +rmdir .libs 2>/dev/null +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5 +printf "%s\n" "$lt_cv_objdir" >&6; } +objdir=$lt_cv_objdir + + + + + +printf "%s\n" "#define LT_OBJDIR \"$lt_cv_objdir/\"" >>confdefs.h + + + + +case $host_os in +aix3*) + # AIX sometimes has problems with the GCC collect2 program. For some + # reason, if we set the COLLECT_NAMES environment variable, the problems + # vanish in a puff of smoke. + if test set != "${COLLECT_NAMES+set}"; then + COLLECT_NAMES= + export COLLECT_NAMES + fi + ;; +esac + +# Global variables: +ofile=libtool +can_build_shared=yes + +# All known linkers require a '.a' archive for static linking (except MSVC, +# which needs '.lib'). +libext=a + +with_gnu_ld=$lt_cv_prog_gnu_ld + +old_CC=$CC +old_CFLAGS=$CFLAGS + +# Set sane defaults for various variables +test -z "$CC" && CC=cc +test -z "$LTCC" && LTCC=$CC +test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS +test -z "$LD" && LD=ld +test -z "$ac_objext" && ac_objext=o + +func_cc_basename $compiler +cc_basename=$func_cc_basename_result + + +# Only perform the check for file, if the check method requires it +test -z "$MAGIC_CMD" && MAGIC_CMD=file +case $deplibs_check_method in +file_magic*) + if test "$file_magic_cmd" = '$MAGIC_CMD'; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5 +printf %s "checking for ${ac_tool_prefix}file... " >&6; } +if test ${lt_cv_path_MAGIC_CMD+y} +then : + printf %s "(cached) " >&6 +else $as_nop + case $MAGIC_CMD in +[\\/*] | ?:[\\/]*) + lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD=$MAGIC_CMD + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR + ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" + for ac_dir in $ac_dummy; do + IFS=$lt_save_ifs + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/${ac_tool_prefix}file"; then + lt_cv_path_MAGIC_CMD=$ac_dir/"${ac_tool_prefix}file" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD=$lt_cv_path_MAGIC_CMD + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS=$lt_save_ifs + MAGIC_CMD=$lt_save_MAGIC_CMD + ;; +esac +fi + +MAGIC_CMD=$lt_cv_path_MAGIC_CMD +if test -n "$MAGIC_CMD"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 +printf "%s\n" "$MAGIC_CMD" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + + + + +if test -z "$lt_cv_path_MAGIC_CMD"; then + if test -n "$ac_tool_prefix"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for file" >&5 +printf %s "checking for file... " >&6; } +if test ${lt_cv_path_MAGIC_CMD+y} +then : + printf %s "(cached) " >&6 +else $as_nop + case $MAGIC_CMD in +[\\/*] | ?:[\\/]*) + lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD=$MAGIC_CMD + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR + ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" + for ac_dir in $ac_dummy; do + IFS=$lt_save_ifs + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/file"; then + lt_cv_path_MAGIC_CMD=$ac_dir/"file" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD=$lt_cv_path_MAGIC_CMD + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS=$lt_save_ifs + MAGIC_CMD=$lt_save_MAGIC_CMD + ;; +esac +fi + +MAGIC_CMD=$lt_cv_path_MAGIC_CMD +if test -n "$MAGIC_CMD"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 +printf "%s\n" "$MAGIC_CMD" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + + else + MAGIC_CMD=: + fi +fi + + fi + ;; +esac + +# Use C for the default configuration in the libtool script + +lt_save_CC=$CC +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +# Source file extension for C test sources. +ac_ext=c + +# Object file extension for compiled C test sources. +objext=o +objext=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(){return(0);}' + + + + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + +# Save the default compiler, since it gets overwritten when the other +# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. +compiler_DEFAULT=$CC + +# save warnings/boilerplate of simple test code +ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$RM conftest* + +ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$RM -r conftest* + + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... +if test -n "$compiler"; then + +lt_prog_compiler_no_builtin_flag= + +if test yes = "$GCC"; then + case $cc_basename in + nvcc*) + lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;; + *) + lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;; + esac + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 +printf %s "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; } +if test ${lt_cv_prog_compiler_rtti_exceptions+y} +then : + printf %s "(cached) " >&6 +else $as_nop + lt_cv_prog_compiler_rtti_exceptions=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="-fno-rtti -fno-exceptions" ## exclude from sc_useless_quotes_in_assignment + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_rtti_exceptions=yes + fi + fi + $RM conftest* + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 +printf "%s\n" "$lt_cv_prog_compiler_rtti_exceptions" >&6; } + +if test yes = "$lt_cv_prog_compiler_rtti_exceptions"; then + lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions" +else + : +fi + +fi + + + + + + + lt_prog_compiler_wl= +lt_prog_compiler_pic= +lt_prog_compiler_static= + + + if test yes = "$GCC"; then + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_static='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test ia64 = "$host_cpu"; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static='-Bstatic' + fi + lt_prog_compiler_pic='-fPIC' + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + lt_prog_compiler_pic='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the '-m68020' flag to GCC prevents building anything better, + # like '-m68040'. + lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + lt_prog_compiler_pic='-DDLL_EXPORT' + case $host_os in + os2*) + lt_prog_compiler_static='$wl-static' + ;; + esac + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic='-fno-common' + ;; + + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + lt_prog_compiler_static= + ;; + + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic='-fPIC' + ;; + esac + ;; + + interix[3-9]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + + msdosdjgpp*) + # Just because we use GCC doesn't mean we suddenly get shared libraries + # on systems that don't support them. + lt_prog_compiler_can_build_shared=no + enable_shared=no + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic='-fPIC -shared' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic=-Kconform_pic + fi + ;; + + *) + lt_prog_compiler_pic='-fPIC' + ;; + esac + + case $cc_basename in + nvcc*) # Cuda Compiler Driver 2.2 + lt_prog_compiler_wl='-Xlinker ' + if test -n "$lt_prog_compiler_pic"; then + lt_prog_compiler_pic="-Xcompiler $lt_prog_compiler_pic" + fi + ;; + esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in + aix*) + lt_prog_compiler_wl='-Wl,' + if test ia64 = "$host_cpu"; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static='-Bstatic' + else + lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp' + fi + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic='-fno-common' + case $cc_basename in + nagfor*) + # NAG Fortran compiler + lt_prog_compiler_wl='-Wl,-Wl,,' + lt_prog_compiler_pic='-PIC' + lt_prog_compiler_static='-Bstatic' + ;; + esac + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_prog_compiler_pic='-DDLL_EXPORT' + case $host_os in + os2*) + lt_prog_compiler_static='$wl-static' + ;; + esac + ;; + + hpux9* | hpux10* | hpux11*) + lt_prog_compiler_wl='-Wl,' + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic='+Z' + ;; + esac + # Is there a better lt_prog_compiler_static that works with the bundled CC? + lt_prog_compiler_static='$wl-a ${wl}archive' + ;; + + irix5* | irix6* | nonstopux*) + lt_prog_compiler_wl='-Wl,' + # PIC (with -KPIC) is the default. + lt_prog_compiler_static='-non_shared' + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + case $cc_basename in + # old Intel for x86_64, which still supported -KPIC. + ecc*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-static' + ;; + # flang / f18. f95 an alias for gfortran or flang on Debian + flang* | f18* | f95*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; + # icc used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + icc* | ifort*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; + # Lahey Fortran 8.1. + lf95*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='--shared' + lt_prog_compiler_static='--static' + ;; + nagfor*) + # NAG Fortran compiler + lt_prog_compiler_wl='-Wl,-Wl,,' + lt_prog_compiler_pic='-PIC' + lt_prog_compiler_static='-Bstatic' + ;; + tcc*) + # Fabrice Bellard et al's Tiny C Compiler + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; + pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group compilers (*not* the Pentium gcc compiler, + # which looks to be a dead project) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fpic' + lt_prog_compiler_static='-Bstatic' + ;; + ccc*) + lt_prog_compiler_wl='-Wl,' + # All Alpha code is PIC. + lt_prog_compiler_static='-non_shared' + ;; + xl* | bgxl* | bgf* | mpixl*) + # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-qpic' + lt_prog_compiler_static='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [1-7].* | *Sun*Fortran*\ 8.[0-3]*) + # Sun Fortran 8.3 passes all unrecognized flags to the linker + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='' + ;; + *Sun\ F* | *Sun*Fortran*) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='-Qoption ld ' + ;; + *Sun\ C*) + # Sun C 5.9 + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='-Wl,' + ;; + *Intel*\ [CF]*Compiler*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; + *Portland\ Group*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fpic' + lt_prog_compiler_static='-Bstatic' + ;; + esac + ;; + esac + ;; + + newsos6) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic='-fPIC -shared' + ;; + + osf3* | osf4* | osf5*) + lt_prog_compiler_wl='-Wl,' + # All OSF/1 code is PIC. + lt_prog_compiler_static='-non_shared' + ;; + + rdos*) + lt_prog_compiler_static='-non_shared' + ;; + + solaris*) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + case $cc_basename in + f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) + lt_prog_compiler_wl='-Qoption ld ';; + *) + lt_prog_compiler_wl='-Wl,';; + esac + ;; + + sunos4*) + lt_prog_compiler_wl='-Qoption ld ' + lt_prog_compiler_pic='-PIC' + lt_prog_compiler_static='-Bstatic' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic='-Kconform_pic' + lt_prog_compiler_static='-Bstatic' + fi + ;; + + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + unicos*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_can_build_shared=no + ;; + + uts4*) + lt_prog_compiler_pic='-pic' + lt_prog_compiler_static='-Bstatic' + ;; + + *) + lt_prog_compiler_can_build_shared=no + ;; + esac + fi + +case $host_os in + # For platforms that do not support PIC, -DPIC is meaningless: + *djgpp*) + lt_prog_compiler_pic= + ;; + *) + lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC" + ;; +esac + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 +printf %s "checking for $compiler option to produce PIC... " >&6; } +if test ${lt_cv_prog_compiler_pic+y} +then : + printf %s "(cached) " >&6 +else $as_nop + lt_cv_prog_compiler_pic=$lt_prog_compiler_pic +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5 +printf "%s\n" "$lt_cv_prog_compiler_pic" >&6; } +lt_prog_compiler_pic=$lt_cv_prog_compiler_pic + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$lt_prog_compiler_pic"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 +printf %s "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; } +if test ${lt_cv_prog_compiler_pic_works+y} +then : + printf %s "(cached) " >&6 +else $as_nop + lt_cv_prog_compiler_pic_works=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$lt_prog_compiler_pic -DPIC" ## exclude from sc_useless_quotes_in_assignment + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_pic_works=yes + fi + fi + $RM conftest* + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5 +printf "%s\n" "$lt_cv_prog_compiler_pic_works" >&6; } + +if test yes = "$lt_cv_prog_compiler_pic_works"; then + case $lt_prog_compiler_pic in + "" | " "*) ;; + *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;; + esac +else + lt_prog_compiler_pic= + lt_prog_compiler_can_build_shared=no +fi + +fi + + + + + + + + + + + +# +# Check to make sure the static flag actually works. +# +wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\" +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 +printf %s "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } +if test ${lt_cv_prog_compiler_static_works+y} +then : + printf %s "(cached) " >&6 +else $as_nop + lt_cv_prog_compiler_static_works=no + save_LDFLAGS=$LDFLAGS + LDFLAGS="$LDFLAGS $lt_tmp_static_flag" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_static_works=yes + fi + else + lt_cv_prog_compiler_static_works=yes + fi + fi + $RM -r conftest* + LDFLAGS=$save_LDFLAGS + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5 +printf "%s\n" "$lt_cv_prog_compiler_static_works" >&6; } + +if test yes = "$lt_cv_prog_compiler_static_works"; then + : +else + lt_prog_compiler_static= +fi + + + + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +printf %s "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if test ${lt_cv_prog_compiler_c_o+y} +then : + printf %s "(cached) " >&6 +else $as_nop + lt_cv_prog_compiler_c_o=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 +printf "%s\n" "$lt_cv_prog_compiler_c_o" >&6; } + + + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +printf %s "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if test ${lt_cv_prog_compiler_c_o+y} +then : + printf %s "(cached) " >&6 +else $as_nop + lt_cv_prog_compiler_c_o=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 +printf "%s\n" "$lt_cv_prog_compiler_c_o" >&6; } + + + + +hard_links=nottested +if test no = "$lt_cv_prog_compiler_c_o" && test no != "$need_locks"; then + # do not overwrite the value of need_locks provided by the user + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 +printf %s "checking if we can lock with hard links... " >&6; } + hard_links=yes + $RM conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 +printf "%s\n" "$hard_links" >&6; } + if test no = "$hard_links"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&5 +printf "%s\n" "$as_me: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&2;} + need_locks=warn + fi +else + need_locks=no +fi + + + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +printf %s "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } + + runpath_var= + allow_undefined_flag= + always_export_symbols=no + archive_cmds= + archive_expsym_cmds= + compiler_needs_object=no + enable_shared_with_static_runtimes=no + export_dynamic_flag_spec= + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + hardcode_automatic=no + hardcode_direct=no + hardcode_direct_absolute=no + hardcode_libdir_flag_spec= + hardcode_libdir_separator= + hardcode_minus_L=no + hardcode_shlibpath_var=unsupported + inherit_rpath=no + link_all_deplibs=unknown + module_cmds= + module_expsym_cmds= + old_archive_from_new_cmds= + old_archive_from_expsyms_cmds= + thread_safe_flag_spec= + whole_archive_flag_spec= + # include_expsyms should be a list of space-separated symbols to be *always* + # included in the symbol list + include_expsyms= + # exclude_expsyms can be an extended regexp of symbols to exclude + # it will be wrapped by ' (' and ')$', so one must not match beginning or + # end of line. Example: 'a|bc|.*d.*' will exclude the symbols 'a' and 'bc', + # as well as any symbol that contains 'd'. + exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' + # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out + # platforms (ab)use it in PIC code, but their linkers get confused if + # the symbol is explicitly referenced. Since portable code cannot + # rely on this symbol name, it's probably fine to never include it in + # preloaded symbol tables. + # Exclude shared library initialization/finalization symbols. + extract_expsyms_cmds= + + case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test yes != "$GCC"; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd* | bitrig*) + with_gnu_ld=no + ;; + linux* | k*bsd*-gnu | gnu*) + link_all_deplibs=no + ;; + esac + + ld_shlibs=yes + + # On some targets, GNU ld is compatible enough with the native linker + # that we're better off using the native interface for both. + lt_use_gnu_ld_interface=no + if test yes = "$with_gnu_ld"; then + case $host_os in + aix*) + # The AIX port of GNU ld has always aspired to compatibility + # with the native linker. However, as the warning in the GNU ld + # block says, versions before 2.19.5* couldn't really create working + # shared libraries, regardless of the interface used. + case `$LD -v 2>&1` in + *\ \(GNU\ Binutils\)\ 2.19.5*) ;; + *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;; + *\ \(GNU\ Binutils\)\ [3-9]*) ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + fi + + if test yes = "$lt_use_gnu_ld_interface"; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='$wl' + + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + runpath_var=LD_RUN_PATH + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + export_dynamic_flag_spec='$wl--export-dynamic' + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then + whole_archive_flag_spec=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' + else + whole_archive_flag_spec= + fi + supports_anon_versioning=no + case `$LD -v | $SED -e 's/(^)\+)\s\+//' 2>&1` in + *GNU\ gold*) supports_anon_versioning=yes ;; + *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 + *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... + *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... + *\ 2.11.*) ;; # other 2.11 versions + *) supports_anon_versioning=yes ;; + esac + + # See if GNU ld supports shared libraries. + case $host_os in + aix[3-9]*) + # On AIX/PPC, the GNU linker is very broken + if test ia64 != "$host_cpu"; then + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: the GNU linker, at least up to release 2.19, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to install binutils +*** 2.20 or above, or modify your PATH so that a non-GNU linker is found. +*** You will then need to restart the configuration process. + +_LT_EOF + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds='' + ;; + m68k) + archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + ;; + esac + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + allow_undefined_flag=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + else + ld_shlibs=no + fi + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, + # as there is no search path for DLLs. + hardcode_libdir_flag_spec='-L$libdir' + export_dynamic_flag_spec='$wl--export-all-symbols' + allow_undefined_flag=unsupported + always_export_symbols=no + enable_shared_with_static_runtimes=yes + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' + exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file, use it as + # is; otherwise, prepend EXPORTS... + archive_expsym_cmds='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + ld_shlibs=no + fi + ;; + + haiku*) + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + link_all_deplibs=yes + ;; + + os2*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + allow_undefined_flag=unsupported + shrext_cmds=.dll + archive_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + archive_expsym_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + prefix_cmds="$SED"~ + if test EXPORTS = "`$SED 1q $export_symbols`"; then + prefix_cmds="$prefix_cmds -e 1d"; + fi~ + prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ + cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' + enable_shared_with_static_runtimes=yes + ;; + + interix[3-9]*) + hardcode_direct=no + hardcode_shlibpath_var=no + hardcode_libdir_flag_spec='$wl-rpath,$libdir' + export_dynamic_flag_spec='$wl-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + archive_expsym_cmds='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + + gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) + tmp_diet=no + if test linux-dietlibc = "$host_os"; then + case $cc_basename in + diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) + esac + fi + if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ + && test no = "$tmp_diet" + then + tmp_addflag=' $pic_flag' + tmp_sharedflag='-shared' + case $cc_basename,$host_cpu in + pgcc*) # Portland Group C compiler + whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + tmp_addflag=' $pic_flag' + ;; + pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group f77 and f90 compilers + whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; + efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 + tmp_addflag=' -i_dynamic -nofor_main' ;; + ifc* | ifort*) # Intel Fortran compiler + tmp_addflag=' -nofor_main' ;; + lf95*) # Lahey Fortran 8.1 + whole_archive_flag_spec= + tmp_sharedflag='--shared' ;; + nagfor*) # NAGFOR 5.3 + tmp_sharedflag='-Wl,-shared' ;; + xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below) + tmp_sharedflag='-qmkshrobj' + tmp_addflag= ;; + nvcc*) # Cuda Compiler Driver 2.2 + whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + compiler_needs_object=yes + ;; + esac + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) # Sun C 5.9 + whole_archive_flag_spec='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + compiler_needs_object=yes + tmp_sharedflag='-G' ;; + *Sun\ F*) # Sun Fortran 8.3 + tmp_sharedflag='-G' ;; + esac + archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + + if test yes = "$supports_anon_versioning"; then + archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' + fi + + case $cc_basename in + tcc*) + export_dynamic_flag_spec='-rdynamic' + ;; + xlf* | bgf* | bgxlf* | mpixlf*) + # IBM XL Fortran 10.1 on PPC cannot create shared libs itself + whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive' + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' + if test yes = "$supports_anon_versioning"; then + archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' + fi + ;; + esac + else + ld_shlibs=no + fi + ;; + + netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris*) + if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 cannot +*** reliably create shared libraries on SCO systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.16.91.0.3 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + ;; + *) + # For security reasons, it is highly recommended that you always + # use absolute paths for naming shared libraries, and exclude the + # DT_RUNPATH tag from executables and libraries. But doing so + # requires that you compile everything twice, which is a pain. + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + esac + ;; + + sunos4*) + archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + *) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + esac + + if test no = "$ld_shlibs"; then + runpath_var= + hardcode_libdir_flag_spec= + export_dynamic_flag_spec= + whole_archive_flag_spec= + fi + else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + allow_undefined_flag=unsupported + always_export_symbols=yes + archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + hardcode_minus_L=yes + if test yes = "$GCC" && test -z "$lt_prog_compiler_static"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + hardcode_direct=unsupported + fi + ;; + + aix[4-9]*) + if test ia64 = "$host_cpu"; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag= + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to GNU nm, but means don't demangle to AIX nm. + # Without the "-l" option, or with the "-B" option, AIX nm treats + # weak defined symbols like other global defined symbols, whereas + # GNU nm marks them as "W". + # While the 'weak' keyword is ignored in the Export File, we need + # it in the Import File for the 'aix-soname' feature, so we have + # to replace the "-B" option with "-P" for AIX nm. + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' + else + export_symbols_cmds='`func_echo_all $NM | $SED -e '\''s/B\([^B]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && (substr(\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' + fi + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # have runtime linking enabled, and use it for executables. + # For shared libraries, we enable/disable runtime linking + # depending on the kind of the shared library created - + # when "with_aix_soname,aix_use_runtimelinking" is: + # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables + # "aix,yes" lib.so shared, rtl:yes, for executables + # lib.a static archive + # "both,no" lib.so.V(shr.o) shared, rtl:yes + # lib.a(lib.so.V) shared, rtl:no, for executables + # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables + # lib.a(lib.so.V) shared, rtl:no + # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables + # lib.a static archive + case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) + for ld_flag in $LDFLAGS; do + if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then + aix_use_runtimelinking=yes + break + fi + done + if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then + # With aix-soname=svr4, we create the lib.so.V shared archives only, + # so we don't have lib.a shared libs to link our executables. + # We have to force runtime linking in this case. + aix_use_runtimelinking=yes + LDFLAGS="$LDFLAGS -Wl,-brtl" + fi + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + archive_cmds='' + hardcode_direct=yes + hardcode_direct_absolute=yes + hardcode_libdir_separator=':' + link_all_deplibs=yes + file_list_spec='$wl-f,' + case $with_aix_soname,$aix_use_runtimelinking in + aix,*) ;; # traditional, no import file + svr4,* | *,yes) # use import file + # The Import File defines what to hardcode. + hardcode_direct=no + hardcode_direct_absolute=no + ;; + esac + + if test yes = "$GCC"; then + case $host_os in aix4.[012]|aix4.[012].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`$CC -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + hardcode_direct=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + hardcode_minus_L=yes + hardcode_libdir_flag_spec='-L$libdir' + hardcode_libdir_separator= + fi + ;; + esac + shared_flag='-shared' + if test yes = "$aix_use_runtimelinking"; then + shared_flag="$shared_flag "'$wl-G' + fi + # Need to ensure runtime linking is disabled for the traditional + # shared library, or the linker may eventually find shared libraries + # /with/ Import File - we do not want to mix them. + shared_flag_aix='-shared' + shared_flag_svr4='-shared $wl-G' + else + # not using gcc + if test ia64 = "$host_cpu"; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test yes = "$aix_use_runtimelinking"; then + shared_flag='$wl-G' + else + shared_flag='$wl-bM:SRE' + fi + shared_flag_aix='$wl-bM:SRE' + shared_flag_svr4='$wl-G' + fi + fi + + export_dynamic_flag_spec='$wl-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + always_export_symbols=yes + if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + allow_undefined_flag='-berok' + # Determine the default libpath from the value encoded in an + # empty executable. + if test set = "${lt_cv_aix_libpath+set}"; then + aix_libpath=$lt_cv_aix_libpath +else + if test ${lt_cv_aix_libpath_+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + + lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }' + lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_=/usr/lib:/lib + fi + +fi + + aix_libpath=$lt_cv_aix_libpath_ +fi + + hardcode_libdir_flag_spec='$wl-blibpath:$libdir:'"$aix_libpath" + archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag + else + if test ia64 = "$host_cpu"; then + hardcode_libdir_flag_spec='$wl-R $libdir:/usr/lib:/lib' + allow_undefined_flag="-z nodefs" + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + if test set = "${lt_cv_aix_libpath+set}"; then + aix_libpath=$lt_cv_aix_libpath +else + if test ${lt_cv_aix_libpath_+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + + lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }' + lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_=/usr/lib:/lib + fi + +fi + + aix_libpath=$lt_cv_aix_libpath_ +fi + + hardcode_libdir_flag_spec='$wl-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + no_undefined_flag=' $wl-bernotok' + allow_undefined_flag=' $wl-berok' + if test yes = "$with_gnu_ld"; then + # We only use this code for GNU lds that support --whole-archive. + whole_archive_flag_spec='$wl--whole-archive$convenience $wl--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + whole_archive_flag_spec='$convenience' + fi + archive_cmds_need_lc=yes + archive_expsym_cmds='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' + # -brtl affects multiple linker settings, -berok does not and is overridden later + compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([, ]\\)%-berok\\1%g"`' + if test svr4 != "$with_aix_soname"; then + # This is similar to how AIX traditionally builds its shared libraries. + archive_expsym_cmds="$archive_expsym_cmds"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' + fi + if test aix != "$with_aix_soname"; then + archive_expsym_cmds="$archive_expsym_cmds"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' + else + # used by -dlpreopen to get the symbols + archive_expsym_cmds="$archive_expsym_cmds"'~$MV $output_objdir/$realname.d/$soname $output_objdir' + fi + archive_expsym_cmds="$archive_expsym_cmds"'~$RM -r $output_objdir/$realname.d' + fi + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds='' + ;; + m68k) + archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + ;; + esac + ;; + + bsdi[45]*) + export_dynamic_flag_spec=-rdynamic + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + case $cc_basename in + cl*) + # Native MSVC + hardcode_libdir_flag_spec=' ' + allow_undefined_flag=unsupported + always_export_symbols=yes + file_list_spec='@' + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=.dll + # FIXME: Setting linknames here is a bad hack. + archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' + archive_expsym_cmds='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then + cp "$export_symbols" "$output_objdir/$soname.def"; + echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; + else + $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' + # The linker will not automatically build a static lib if we build a DLL. + # _LT_TAGVAR(old_archive_from_new_cmds, )='true' + enable_shared_with_static_runtimes=yes + exclude_expsyms='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols' + # Don't use ranlib + old_postinstall_cmds='chmod 644 $oldlib' + postlink_cmds='lt_outputfile="@OUTPUT@"~ + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile=$lt_outputfile.exe + lt_tool_outputfile=$lt_tool_outputfile.exe + ;; + esac~ + if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' + ;; + *) + # Assume MSVC wrapper + hardcode_libdir_flag_spec=' ' + allow_undefined_flag=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=.dll + # FIXME: Setting linknames here is a bad hack. + archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + old_archive_from_new_cmds='true' + # FIXME: Should let the user specify the lib program. + old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs' + enable_shared_with_static_runtimes=yes + ;; + esac + ;; + + darwin* | rhapsody*) + + + archive_cmds_need_lc=no + hardcode_direct=no + hardcode_automatic=yes + hardcode_shlibpath_var=unsupported + if test yes = "$lt_cv_ld_force_load"; then + whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' + + else + whole_archive_flag_spec='' + fi + link_all_deplibs=yes + allow_undefined_flag=$_lt_dar_allow_undefined + case $cc_basename in + ifort*|nagfor*) _lt_dar_can_shared=yes ;; + *) _lt_dar_can_shared=$GCC ;; + esac + if test yes = "$_lt_dar_can_shared"; then + output_verbose_link_cmd=func_echo_all + archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil" + module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil" + archive_expsym_cmds="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" + module_expsym_cmds="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" + + else + ld_shlibs=no + fi + + ;; + + dgux*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2.*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd* | dragonfly*) + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + hpux9*) + if test yes = "$GCC"; then + archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' + else + archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' + fi + hardcode_libdir_flag_spec='$wl+b $wl$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + export_dynamic_flag_spec='$wl-E' + ;; + + hpux10*) + if test yes,no = "$GCC,$with_gnu_ld"; then + archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + fi + if test no = "$with_gnu_ld"; then + hardcode_libdir_flag_spec='$wl+b $wl$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + hardcode_direct_absolute=yes + export_dynamic_flag_spec='$wl-E' + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + fi + ;; + + hpux11*) + if test yes,no = "$GCC,$with_gnu_ld"; then + case $host_cpu in + hppa*64*) + archive_cmds='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + else + case $host_cpu in + hppa*64*) + archive_cmds='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + + # Older versions of the 11.00 compiler do not understand -b yet + # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5 +printf %s "checking if $CC understands -b... " >&6; } +if test ${lt_cv_prog_compiler__b+y} +then : + printf %s "(cached) " >&6 +else $as_nop + lt_cv_prog_compiler__b=no + save_LDFLAGS=$LDFLAGS + LDFLAGS="$LDFLAGS -b" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler__b=yes + fi + else + lt_cv_prog_compiler__b=yes + fi + fi + $RM -r conftest* + LDFLAGS=$save_LDFLAGS + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5 +printf "%s\n" "$lt_cv_prog_compiler__b" >&6; } + +if test yes = "$lt_cv_prog_compiler__b"; then + archive_cmds='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' +else + archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' +fi + + ;; + esac + fi + if test no = "$with_gnu_ld"; then + hardcode_libdir_flag_spec='$wl+b $wl$libdir' + hardcode_libdir_separator=: + + case $host_cpu in + hppa*64*|ia64*) + hardcode_direct=no + hardcode_shlibpath_var=no + ;; + *) + hardcode_direct=yes + hardcode_direct_absolute=yes + export_dynamic_flag_spec='$wl-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + ;; + esac + fi + ;; + + irix5* | irix6* | nonstopux*) + if test yes = "$GCC"; then + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + # Try to use the -exported_symbol ld option, if it does not + # work, assume that -exports_file does not work either and + # implicitly export all symbols. + # This should be the same for all languages, so no per-tag cache variable. + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5 +printf %s "checking whether the $host_os linker accepts -exported_symbol... " >&6; } +if test ${lt_cv_irix_exported_symbol+y} +then : + printf %s "(cached) " >&6 +else $as_nop + save_LDFLAGS=$LDFLAGS + LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +int foo (void) { return 0; } +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + lt_cv_irix_exported_symbol=yes +else $as_nop + lt_cv_irix_exported_symbol=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS=$save_LDFLAGS +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5 +printf "%s\n" "$lt_cv_irix_exported_symbol" >&6; } + if test yes = "$lt_cv_irix_exported_symbol"; then + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib' + fi + link_all_deplibs=no + else + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib' + fi + archive_cmds_need_lc='no' + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + hardcode_libdir_separator=: + inherit_rpath=yes + link_all_deplibs=yes + ;; + + linux*) + case $cc_basename in + tcc*) + # Fabrice Bellard et al's Tiny C Compiler + ld_shlibs=yes + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + newsos6) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + hardcode_libdir_separator=: + hardcode_shlibpath_var=no + ;; + + *nto* | *qnx*) + ;; + + openbsd* | bitrig*) + if test -f /usr/libexec/ld.so; then + hardcode_direct=yes + hardcode_shlibpath_var=no + hardcode_direct_absolute=yes + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $wl-retain-symbols-file,$export_symbols' + hardcode_libdir_flag_spec='$wl-rpath,$libdir' + export_dynamic_flag_spec='$wl-E' + else + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='$wl-rpath,$libdir' + fi + else + ld_shlibs=no + fi + ;; + + os2*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + allow_undefined_flag=unsupported + shrext_cmds=.dll + archive_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + archive_expsym_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + prefix_cmds="$SED"~ + if test EXPORTS = "`$SED 1q $export_symbols`"; then + prefix_cmds="$prefix_cmds -e 1d"; + fi~ + prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ + cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' + enable_shared_with_static_runtimes=yes + ;; + + osf3*) + if test yes = "$GCC"; then + allow_undefined_flag=' $wl-expect_unresolved $wl\*' + archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + fi + archive_cmds_need_lc='no' + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + hardcode_libdir_separator=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test yes = "$GCC"; then + allow_undefined_flag=' $wl-expect_unresolved $wl\*' + archive_cmds='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $wl-input $wl$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~$RM $lib.exp' + + # Both c and cxx compiler support -rpath directly + hardcode_libdir_flag_spec='-rpath $libdir' + fi + archive_cmds_need_lc='no' + hardcode_libdir_separator=: + ;; + + solaris*) + no_undefined_flag=' -z defs' + if test yes = "$GCC"; then + wlarc='$wl' + archive_cmds='$CC -shared $pic_flag $wl-z ${wl}text $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared $pic_flag $wl-z ${wl}text $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + else + case `$CC -V 2>&1` in + *"Compilers 5.0"*) + wlarc='' + archive_cmds='$LD -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $linker_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $LD -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' + ;; + *) + wlarc='$wl' + archive_cmds='$CC -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + ;; + esac + fi + hardcode_libdir_flag_spec='-R$libdir' + hardcode_shlibpath_var=no + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands '-z linker_flag'. GCC discards it without '$wl', + # but is careful enough not to reorder. + # Supported since Solaris 2.6 (maybe 2.5.1?) + if test yes = "$GCC"; then + whole_archive_flag_spec='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' + else + whole_archive_flag_spec='-z allextract$convenience -z defaultextract' + fi + ;; + esac + link_all_deplibs=yes + ;; + + sunos4*) + if test sequent = "$host_vendor"; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + archive_cmds='$CC -G $wl-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + hardcode_libdir_flag_spec='-L$libdir' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + sysv4) + case $host_vendor in + sni) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' + reload_cmds='$CC -r -o $output$reload_objs' + hardcode_direct=no + ;; + motorola) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + hardcode_shlibpath_var=no + ;; + + sysv4.3*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + export_dynamic_flag_spec='-Bexport' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + ld_shlibs=yes + fi + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) + no_undefined_flag='$wl-z,text' + archive_cmds_need_lc=no + hardcode_shlibpath_var=no + runpath_var='LD_RUN_PATH' + + if test yes = "$GCC"; then + archive_cmds='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We CANNOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + no_undefined_flag='$wl-z,text' + allow_undefined_flag='$wl-z,nodefs' + archive_cmds_need_lc=no + hardcode_shlibpath_var=no + hardcode_libdir_flag_spec='$wl-R,$libdir' + hardcode_libdir_separator=':' + link_all_deplibs=yes + export_dynamic_flag_spec='$wl-Bexport' + runpath_var='LD_RUN_PATH' + + if test yes = "$GCC"; then + archive_cmds='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + uts4*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + *) + ld_shlibs=no + ;; + esac + + if test sni = "$host_vendor"; then + case $host in + sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + export_dynamic_flag_spec='$wl-Blargedynsym' + ;; + esac + fi + fi + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5 +printf "%s\n" "$ld_shlibs" >&6; } +test no = "$ld_shlibs" && can_build_shared=no + +with_gnu_ld=$with_gnu_ld + + + + + + + + + + + + + + + +# +# Do we need to explicitly link libc? +# +case "x$archive_cmds_need_lc" in +x|xyes) + # Assume -lc should be added + archive_cmds_need_lc=yes + + if test yes,yes = "$GCC,$enable_shared"; then + case $archive_cmds in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 +printf %s "checking whether -lc should be explicitly linked in... " >&6; } +if test ${lt_cv_archive_cmds_need_lc+y} +then : + printf %s "(cached) " >&6 +else $as_nop + $RM conftest* + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$lt_prog_compiler_wl + pic_flag=$lt_prog_compiler_pic + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$allow_undefined_flag + allow_undefined_flag= + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 + (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + then + lt_cv_archive_cmds_need_lc=no + else + lt_cv_archive_cmds_need_lc=yes + fi + allow_undefined_flag=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $RM conftest* + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5 +printf "%s\n" "$lt_cv_archive_cmds_need_lc" >&6; } + archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc + ;; + esac + fi + ;; +esac + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 +printf %s "checking dynamic linker characteristics... " >&6; } + +if test yes = "$GCC"; then + case $host_os in + darwin*) lt_awk_arg='/^libraries:/,/LR/' ;; + *) lt_awk_arg='/^libraries:/' ;; + esac + case $host_os in + mingw* | cegcc*) lt_sed_strip_eq='s|=\([A-Za-z]:\)|\1|g' ;; + *) lt_sed_strip_eq='s|=/|/|g' ;; + esac + lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` + case $lt_search_path_spec in + *\;*) + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` + ;; + *) + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` + ;; + esac + # Ok, now we have the path, separated by spaces, we can step through it + # and add multilib dir if necessary... + lt_tmp_lt_search_path_spec= + lt_multi_os_dir=/`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` + # ...but if some path component already ends with the multilib dir we assume + # that all is fine and trust -print-search-dirs as is (GCC 4.2? or newer). + case "$lt_multi_os_dir; $lt_search_path_spec " in + "/; "* | "/.; "* | "/./; "* | *"$lt_multi_os_dir "* | *"$lt_multi_os_dir/ "*) + lt_multi_os_dir= + ;; + esac + for lt_sys_path in $lt_search_path_spec; do + if test -d "$lt_sys_path$lt_multi_os_dir"; then + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path$lt_multi_os_dir" + elif test -n "$lt_multi_os_dir"; then + test -d "$lt_sys_path" && \ + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" + fi + done + lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' +BEGIN {RS = " "; FS = "/|\n";} { + lt_foo = ""; + lt_count = 0; + for (lt_i = NF; lt_i > 0; lt_i--) { + if ($lt_i != "" && $lt_i != ".") { + if ($lt_i == "..") { + lt_count++; + } else { + if (lt_count == 0) { + lt_foo = "/" $lt_i lt_foo; + } else { + lt_count--; + } + } + } + } + if (lt_foo != "") { lt_freq[lt_foo]++; } + if (lt_freq[lt_foo] == 1) { print lt_foo; } +}'` + # AWK program above erroneously prepends '/' to C:/dos/paths + # for these hosts. + case $host_os in + mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ + $SED 's|/\([A-Za-z]:\)|\1|g'` ;; + esac + sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` +else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" +fi +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=.so +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + + + +case $host_os in +aix3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='$libname$release$shared_ext$major' + ;; + +aix[4-9]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test ia64 = "$host_cpu"; then + # AIX 5 supports IA64 + library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line '#! .'. This would cause the generated library to + # depend on '.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[01] | aix4.[01].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # Using Import Files as archive members, it is possible to support + # filename-based versioning of shared library archives on AIX. While + # this would work for both with and without runtime linking, it will + # prevent static linking of such archives. So we do filename-based + # shared library versioning with .so extension only, which is used + # when both runtime linking and shared linking is enabled. + # Unfortunately, runtime linking may impact performance, so we do + # not want this to be the default eventually. Also, we use the + # versioned .so libs for executables only if there is the -brtl + # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only. + # To allow for filename-based versioning support, we need to create + # libNAME.so.V as an archive file, containing: + # *) an Import File, referring to the versioned filename of the + # archive as well as the shared archive member, telling the + # bitwidth (32 or 64) of that shared object, and providing the + # list of exported symbols of that shared object, eventually + # decorated with the 'weak' keyword + # *) the shared object with the F_LOADONLY flag set, to really avoid + # it being seen by the linker. + # At run time we better use the real file rather than another symlink, + # but for link time we create the symlink libNAME.so -> libNAME.so.V + + case $with_aix_soname,$aix_use_runtimelinking in + # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + aix,yes) # traditional libtool + dynamic_linker='AIX unversionable lib.so' + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + ;; + aix,no) # traditional AIX only + dynamic_linker='AIX lib.a(lib.so.V)' + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='$libname$release.a $libname.a' + soname_spec='$libname$release$shared_ext$major' + ;; + svr4,*) # full svr4 only + dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o)" + library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' + # We do not specify a path in Import Files, so LIBPATH fires. + shlibpath_overrides_runpath=yes + ;; + *,yes) # both, prefer svr4 + dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o), lib.a(lib.so.V)" + library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' + # unpreferred sharedlib libNAME.a needs extra handling + postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"' + postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"' + # We do not specify a path in Import Files, so LIBPATH fires. + shlibpath_overrides_runpath=yes + ;; + *,no) # both, prefer aix + dynamic_linker="AIX lib.a(lib.so.V), lib.so.V($shared_archive_member_spec.o)" + library_names_spec='$libname$release.a $libname.a' + soname_spec='$libname$release$shared_ext$major' + # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling + postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)' + postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"' + ;; + esac + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + case $host_cpu in + powerpc) + # Since July 2007 AmigaOS4 officially supports .so libraries. + # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + ;; + m68k) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + esac + ;; + +beos*) + library_names_spec='$libname$shared_ext' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[45]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32* | cegcc*) + version_type=windows + shrext_cmds=.dll + need_version=no + need_lib_prefix=no + + case $GCC,$cc_basename in + yes,*) + # gcc + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api" + ;; + mingw* | cegcc*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + ;; + esac + dynamic_linker='Win32 ld.exe' + ;; + + *,cl*) + # Native MSVC + libname_spec='$name' + soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + library_names_spec='$libname.dll.lib' + + case $build_os in + mingw*) + sys_lib_search_path_spec= + lt_save_ifs=$IFS + IFS=';' + for lt_path in $LIB + do + IFS=$lt_save_ifs + # Let DOS variable expansion print the short 8.3 style file name. + lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` + sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" + done + IFS=$lt_save_ifs + # Convert to MSYS style. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` + ;; + cygwin*) + # Convert to unix form, then to dos form, then back to unix form + # but this time dos style (no spaces!) so that the unix form looks + # like /cygdrive/c/PROGRA~1:/cygdr... + sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` + sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` + sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + ;; + *) + sys_lib_search_path_spec=$LIB + if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then + # It is most probably a Windows format PATH. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + # FIXME: find the short name or the path components, as spaces are + # common. (e.g. "Program Files" -> "PROGRA~1") + ;; + esac + + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + dynamic_linker='Win32 link.exe' + ;; + + *) + # Assume MSVC wrapper + library_names_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext $libname.lib' + dynamic_linker='Win32 ld.exe' + ;; + esac + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$major$shared_ext $libname$shared_ext' + soname_spec='$libname$release$major$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' + + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib" + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[23].*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2.*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[01]* | freebsdelf3.[01]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ + freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +haiku*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + dynamic_linker="$host_os runtime_loader" + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LIBRARY_PATH + shlibpath_overrides_runpath=no + sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + if test 32 = "$HPUX_IA64_MODE"; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + sys_lib_dlsearch_path_spec=/usr/lib/hpux32 + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + sys_lib_dlsearch_path_spec=/usr/lib/hpux64 + fi + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555, ... + postinstall_cmds='chmod 555 $lib' + # or fails outright, so override atomically: + install_override_mode=555 + ;; + +interix[3-9]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test yes = "$lt_cv_prog_gnu_ld"; then + version_type=linux # correct to gnu/linux during the next big refactor + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='$libname$release$shared_ext$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff" + sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +linux*android*) + version_type=none # Android doesn't support versioned libraries. + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext' + soname_spec='$libname$release$shared_ext' + finish_cmds= + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + dynamic_linker='Android linker' + # Don't embed -rpath directories since the linker doesn't support them. + hardcode_libdir_flag_spec='-L$libdir' + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + + # Some binutils ld are patched to set DT_RUNPATH + if test ${lt_cv_shlibpath_overrides_runpath+y} +then : + printf %s "(cached) " >&6 +else $as_nop + lt_cv_shlibpath_overrides_runpath=no + save_LDFLAGS=$LDFLAGS + save_libdir=$libdir + eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \ + LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\"" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null +then : + lt_cv_shlibpath_overrides_runpath=yes +fi +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS=$save_LDFLAGS + libdir=$save_libdir + +fi + + shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Ideally, we could use ldconfig to report *all* directores which are + # searched for libraries, however this is still not possible. Aside from not + # being certain /sbin/ldconfig is available, command + # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64, + # even though it is searched at run-time. Try to do the best guess by + # appending ld.so.conf contents (and includes) to the search path. + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsdelf*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='NetBSD ld.elf_so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +*nto* | *qnx*) + version_type=qnx + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='ldqnx.so' + ;; + +openbsd* | bitrig*) + version_type=sunos + sys_lib_dlsearch_path_spec=/usr/lib + need_lib_prefix=no + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then + need_version=no + else + need_version=yes + fi + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +os2*) + libname_spec='$name' + version_type=windows + shrext_cmds=.dll + need_version=no + need_lib_prefix=no + # OS/2 can only load a DLL with a base name of 8 characters or less. + soname_spec='`test -n "$os2dllname" && libname="$os2dllname"; + v=$($ECHO $release$versuffix | tr -d .-); + n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _); + $ECHO $n$v`$shared_ext' + library_names_spec='${libname}_dll.$libext' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=BEGINLIBPATH + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='$libname$release$shared_ext$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + +rdos*) + dynamic_linker=no + ;; + +solaris*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test yes = "$with_gnu_ld"; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec; then + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext' + soname_spec='$libname$shared_ext.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=sco + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + if test yes = "$with_gnu_ld"; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +tpf*) + # TPF is a cross-target only. Preferred cross-host = GNU/Linux. + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +uts4*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 +printf "%s\n" "$dynamic_linker" >&6; } +test no = "$dynamic_linker" && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test yes = "$GCC"; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then + sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec +fi + +if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then + sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec +fi + +# remember unaugmented sys_lib_dlsearch_path content for libtool script decls... +configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec + +# ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code +func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH" + +# to be used as default LT_SYS_LIBRARY_PATH value in generated libtool +configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 +printf %s "checking how to hardcode library paths into programs... " >&6; } +hardcode_action= +if test -n "$hardcode_libdir_flag_spec" || + test -n "$runpath_var" || + test yes = "$hardcode_automatic"; then + + # We can hardcode non-existent directories. + if test no != "$hardcode_direct" && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, )" && + test no != "$hardcode_minus_L"; then + # Linking always hardcodes the temporary library directory. + hardcode_action=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + hardcode_action=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + hardcode_action=unsupported +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5 +printf "%s\n" "$hardcode_action" >&6; } + +if test relink = "$hardcode_action" || + test yes = "$inherit_rpath"; then + # Fast installation is not supported + enable_fast_install=no +elif test yes = "$shlibpath_overrides_runpath" || + test no = "$enable_shared"; then + # Fast installation is not necessary + enable_fast_install=needless +fi + + + + + + + if test yes != "$enable_dlopen"; then + enable_dlopen=unknown + enable_dlopen_self=unknown + enable_dlopen_self_static=unknown +else + lt_cv_dlopen=no + lt_cv_dlopen_libs= + + case $host_os in + beos*) + lt_cv_dlopen=load_add_on + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ;; + + mingw* | pw32* | cegcc*) + lt_cv_dlopen=LoadLibrary + lt_cv_dlopen_libs= + ;; + + cygwin*) + lt_cv_dlopen=dlopen + lt_cv_dlopen_libs= + ;; + + darwin*) + # if libdl is installed we need to link against it + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 +printf %s "checking for dlopen in -ldl... " >&6; } +if test ${ac_cv_lib_dl_dlopen+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +char dlopen (); +int +main (void) +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_dl_dlopen=yes +else $as_nop + ac_cv_lib_dl_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 +printf "%s\n" "$ac_cv_lib_dl_dlopen" >&6; } +if test "x$ac_cv_lib_dl_dlopen" = xyes +then : + lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl +else $as_nop + + lt_cv_dlopen=dyld + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + +fi + + ;; + + tpf*) + # Don't try to run any link tests for TPF. We know it's impossible + # because TPF is a cross-compiler, and we know how we open DSOs. + lt_cv_dlopen=dlopen + lt_cv_dlopen_libs= + lt_cv_dlopen_self=no + ;; + + *) + ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load" +if test "x$ac_cv_func_shl_load" = xyes +then : + lt_cv_dlopen=shl_load +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5 +printf %s "checking for shl_load in -ldld... " >&6; } +if test ${ac_cv_lib_dld_shl_load+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +char shl_load (); +int +main (void) +{ +return shl_load (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_dld_shl_load=yes +else $as_nop + ac_cv_lib_dld_shl_load=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5 +printf "%s\n" "$ac_cv_lib_dld_shl_load" >&6; } +if test "x$ac_cv_lib_dld_shl_load" = xyes +then : + lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld +else $as_nop + ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen" +if test "x$ac_cv_func_dlopen" = xyes +then : + lt_cv_dlopen=dlopen +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 +printf %s "checking for dlopen in -ldl... " >&6; } +if test ${ac_cv_lib_dl_dlopen+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +char dlopen (); +int +main (void) +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_dl_dlopen=yes +else $as_nop + ac_cv_lib_dl_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 +printf "%s\n" "$ac_cv_lib_dl_dlopen" >&6; } +if test "x$ac_cv_lib_dl_dlopen" = xyes +then : + lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5 +printf %s "checking for dlopen in -lsvld... " >&6; } +if test ${ac_cv_lib_svld_dlopen+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsvld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +char dlopen (); +int +main (void) +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_svld_dlopen=yes +else $as_nop + ac_cv_lib_svld_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5 +printf "%s\n" "$ac_cv_lib_svld_dlopen" >&6; } +if test "x$ac_cv_lib_svld_dlopen" = xyes +then : + lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5 +printf %s "checking for dld_link in -ldld... " >&6; } +if test ${ac_cv_lib_dld_dld_link+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +char dld_link (); +int +main (void) +{ +return dld_link (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_dld_dld_link=yes +else $as_nop + ac_cv_lib_dld_dld_link=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5 +printf "%s\n" "$ac_cv_lib_dld_dld_link" >&6; } +if test "x$ac_cv_lib_dld_dld_link" = xyes +then : + lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld +fi + + +fi + + +fi + + +fi + + +fi + + +fi + + ;; + esac + + if test no = "$lt_cv_dlopen"; then + enable_dlopen=no + else + enable_dlopen=yes + fi + + case $lt_cv_dlopen in + dlopen) + save_CPPFLAGS=$CPPFLAGS + test yes = "$ac_cv_header_dlfcn_h" && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + + save_LDFLAGS=$LDFLAGS + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + + save_LIBS=$LIBS + LIBS="$lt_cv_dlopen_libs $LIBS" + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5 +printf %s "checking whether a program can dlopen itself... " >&6; } +if test ${lt_cv_dlopen_self+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test yes = "$cross_compiling"; then : + lt_cv_dlopen_self=cross +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +#line $LINENO "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +/* When -fvisibility=hidden is used, assume the code has been annotated + correspondingly for the symbols needed. */ +#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +int fnord () __attribute__((visibility("default"))); +#endif + +int fnord () { return 42; } +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else + { + if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + else puts (dlerror ()); + } + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +} +_LT_EOF + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s "conftest$ac_exeext" 2>/dev/null; then + (./conftest; exit; ) >&5 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; + x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; + x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;; + esac + else : + # compilation failed + lt_cv_dlopen_self=no + fi +fi +rm -fr conftest* + + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5 +printf "%s\n" "$lt_cv_dlopen_self" >&6; } + + if test yes = "$lt_cv_dlopen_self"; then + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5 +printf %s "checking whether a statically linked program can dlopen itself... " >&6; } +if test ${lt_cv_dlopen_self_static+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test yes = "$cross_compiling"; then : + lt_cv_dlopen_self_static=cross +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +#line $LINENO "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +/* When -fvisibility=hidden is used, assume the code has been annotated + correspondingly for the symbols needed. */ +#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +int fnord () __attribute__((visibility("default"))); +#endif + +int fnord () { return 42; } +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else + { + if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + else puts (dlerror ()); + } + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +} +_LT_EOF + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s "conftest$ac_exeext" 2>/dev/null; then + (./conftest; exit; ) >&5 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; + x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; + x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;; + esac + else : + # compilation failed + lt_cv_dlopen_self_static=no + fi +fi +rm -fr conftest* + + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5 +printf "%s\n" "$lt_cv_dlopen_self_static" >&6; } + fi + + CPPFLAGS=$save_CPPFLAGS + LDFLAGS=$save_LDFLAGS + LIBS=$save_LIBS + ;; + esac + + case $lt_cv_dlopen_self in + yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; + *) enable_dlopen_self=unknown ;; + esac + + case $lt_cv_dlopen_self_static in + yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; + *) enable_dlopen_self_static=unknown ;; + esac +fi + + + + + + + + + + + + + + + + + +striplib= +old_striplib= +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5 +printf %s "checking whether stripping libraries is possible... " >&6; } +if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then + test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" + test -z "$striplib" && striplib="$STRIP --strip-unneeded" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } +else +# FIXME - insert some real tests, host_os isn't really good enough + case $host_os in + darwin*) + if test -n "$STRIP"; then + striplib="$STRIP -x" + old_striplib="$STRIP -S" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + fi + ;; + *) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + ;; + esac +fi + + + + + + + + + + + + + # Report what library types will actually be built + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5 +printf %s "checking if libtool supports shared libraries... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5 +printf "%s\n" "$can_build_shared" >&6; } + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5 +printf %s "checking whether to build shared libraries... " >&6; } + test no = "$can_build_shared" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test yes = "$enable_shared" && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + + aix[4-9]*) + if test ia64 != "$host_cpu"; then + case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in + yes,aix,yes) ;; # shared object as lib.so file only + yes,svr4,*) ;; # shared object as lib.so archive member only + yes,*) enable_static=no ;; # shared object in lib.a archive as well + esac + fi + ;; + esac + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5 +printf "%s\n" "$enable_shared" >&6; } + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5 +printf %s "checking whether to build static libraries... " >&6; } + # Make sure either enable_shared or enable_static is yes. + test yes = "$enable_shared" || enable_static=yes + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5 +printf "%s\n" "$enable_static" >&6; } + + + + +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +CC=$lt_save_CC + + if test -n "$CXX" && ( test no != "$CXX" && + ( (test g++ = "$CXX" && `g++ -v >/dev/null 2>&1` ) || + (test g++ != "$CXX"))); then + ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to run the C++ preprocessor" >&5 +printf %s "checking how to run the C++ preprocessor... " >&6; } +if test -z "$CXXCPP"; then + if test ${ac_cv_prog_CXXCPP+y} +then : + printf %s "(cached) " >&6 +else $as_nop + # Double quotes because $CXX needs to be expanded + for CXXCPP in "$CXX -E" cpp /lib/cpp + do + ac_preproc_ok=false +for ac_cxx_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + Syntax error +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO" +then : + +else $as_nop + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO" +then : + # Broken: success on invalid input. +continue +else $as_nop + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok +then : + break +fi + + done + ac_cv_prog_CXXCPP=$CXXCPP + +fi + CXXCPP=$ac_cv_prog_CXXCPP +else + ac_cv_prog_CXXCPP=$CXXCPP +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CXXCPP" >&5 +printf "%s\n" "$CXXCPP" >&6; } +ac_preproc_ok=false +for ac_cxx_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + Syntax error +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO" +then : + +else $as_nop + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO" +then : + # Broken: success on invalid input. +continue +else $as_nop + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok +then : + +else $as_nop + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "C++ preprocessor \"$CXXCPP\" fails sanity check +See \`config.log' for more details" "$LINENO" 5; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +else + _lt_caught_CXX_error=yes +fi + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + +archive_cmds_need_lc_CXX=no +allow_undefined_flag_CXX= +always_export_symbols_CXX=no +archive_expsym_cmds_CXX= +compiler_needs_object_CXX=no +export_dynamic_flag_spec_CXX= +hardcode_direct_CXX=no +hardcode_direct_absolute_CXX=no +hardcode_libdir_flag_spec_CXX= +hardcode_libdir_separator_CXX= +hardcode_minus_L_CXX=no +hardcode_shlibpath_var_CXX=unsupported +hardcode_automatic_CXX=no +inherit_rpath_CXX=no +module_cmds_CXX= +module_expsym_cmds_CXX= +link_all_deplibs_CXX=unknown +old_archive_cmds_CXX=$old_archive_cmds +reload_flag_CXX=$reload_flag +reload_cmds_CXX=$reload_cmds +no_undefined_flag_CXX= +whole_archive_flag_spec_CXX= +enable_shared_with_static_runtimes_CXX=no + +# Source file extension for C++ test sources. +ac_ext=cpp + +# Object file extension for compiled C++ test sources. +objext=o +objext_CXX=$objext + +# No sense in running all these tests if we already determined that +# the CXX compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test yes != "$_lt_caught_CXX_error"; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="int some_variable = 0;" + + # Code to be used in simple link tests + lt_simple_link_test_code='int main(int, char *[]) { return(0); }' + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + + + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + + + # save warnings/boilerplate of simple test code + ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$RM conftest* + + ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$RM -r conftest* + + + # Allow CC to be a program name with arguments. + lt_save_CC=$CC + lt_save_CFLAGS=$CFLAGS + lt_save_LD=$LD + lt_save_GCC=$GCC + GCC=$GXX + lt_save_with_gnu_ld=$with_gnu_ld + lt_save_path_LD=$lt_cv_path_LD + if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then + lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx + else + $as_unset lt_cv_prog_gnu_ld + fi + if test -n "${lt_cv_path_LDCXX+set}"; then + lt_cv_path_LD=$lt_cv_path_LDCXX + else + $as_unset lt_cv_path_LD + fi + test -z "${LDCXX+set}" || LD=$LDCXX + CC=${CXX-"c++"} + CFLAGS=$CXXFLAGS + compiler=$CC + compiler_CXX=$CC + func_cc_basename $compiler +cc_basename=$func_cc_basename_result + + + if test -n "$compiler"; then + # We don't want -fno-exception when compiling C++ code, so set the + # no_builtin_flag separately + if test yes = "$GXX"; then + lt_prog_compiler_no_builtin_flag_CXX=' -fno-builtin' + else + lt_prog_compiler_no_builtin_flag_CXX= + fi + + if test yes = "$GXX"; then + # Set up default GNU C++ configuration + + + +# Check whether --with-gnu-ld was given. +if test ${with_gnu_ld+y} +then : + withval=$with_gnu_ld; test no = "$withval" || with_gnu_ld=yes +else $as_nop + with_gnu_ld=no +fi + +ac_prog=ld +if test yes = "$GCC"; then + # Check if gcc -print-prog-name=ld gives a path. + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 +printf %s "checking for ld used by $CC... " >&6; } + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return, which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [\\/]* | ?:[\\/]*) + re_direlt='/[^/][^/]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` + while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do + ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD=$ac_prog + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test yes = "$with_gnu_ld"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 +printf %s "checking for GNU ld... " >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 +printf %s "checking for non-GNU ld... " >&6; } +fi +if test ${lt_cv_path_LD+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -z "$LD"; then + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS=$lt_save_ifs + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD=$ac_dir/$ac_prog + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 &5 +printf "%s\n" "$LD" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi +test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 +printf %s "checking if the linker ($LD) is GNU ld... " >&6; } +if test ${lt_cv_prog_gnu_ld+y} +then : + printf %s "(cached) " >&6 +else $as_nop + # I'd rather use --version here, but apparently some GNU lds only accept -v. +case `$LD -v 2>&1 &5 +printf "%s\n" "$lt_cv_prog_gnu_ld" >&6; } +with_gnu_ld=$lt_cv_prog_gnu_ld + + + + + + + + # Check if GNU C++ uses GNU ld as the underlying linker, since the + # archiving commands below assume that GNU ld is being used. + if test yes = "$with_gnu_ld"; then + archive_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + + hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir' + export_dynamic_flag_spec_CXX='$wl--export-dynamic' + + # If archive_cmds runs LD, not CC, wlarc should be empty + # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to + # investigate it a little bit more. (MM) + wlarc='$wl' + + # ancient GNU ld didn't support --whole-archive et. al. + if eval "`$CC -print-prog-name=ld` --help 2>&1" | + $GREP 'no-whole-archive' > /dev/null; then + whole_archive_flag_spec_CXX=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' + else + whole_archive_flag_spec_CXX= + fi + else + with_gnu_ld=no + wlarc= + + # A generic and very simple default shared library creation + # command for GNU C++ for the case where it uses the native + # linker, instead of GNU ld. If possible, this setting should + # overridden to take advantage of the native linker features on + # the platform it is being used on. + archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + fi + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' + + else + GXX=no + with_gnu_ld=no + wlarc= + fi + + # PORTME: fill in a description of your system's C++ link characteristics + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +printf %s "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } + ld_shlibs_CXX=yes + case $host_os in + aix3*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + aix[4-9]*) + if test ia64 = "$host_cpu"; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag= + else + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # have runtime linking enabled, and use it for executables. + # For shared libraries, we enable/disable runtime linking + # depending on the kind of the shared library created - + # when "with_aix_soname,aix_use_runtimelinking" is: + # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables + # "aix,yes" lib.so shared, rtl:yes, for executables + # lib.a static archive + # "both,no" lib.so.V(shr.o) shared, rtl:yes + # lib.a(lib.so.V) shared, rtl:no, for executables + # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables + # lib.a(lib.so.V) shared, rtl:no + # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables + # lib.a static archive + case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) + for ld_flag in $LDFLAGS; do + case $ld_flag in + *-brtl*) + aix_use_runtimelinking=yes + break + ;; + esac + done + if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then + # With aix-soname=svr4, we create the lib.so.V shared archives only, + # so we don't have lib.a shared libs to link our executables. + # We have to force runtime linking in this case. + aix_use_runtimelinking=yes + LDFLAGS="$LDFLAGS -Wl,-brtl" + fi + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + archive_cmds_CXX='' + hardcode_direct_CXX=yes + hardcode_direct_absolute_CXX=yes + hardcode_libdir_separator_CXX=':' + link_all_deplibs_CXX=yes + file_list_spec_CXX='$wl-f,' + case $with_aix_soname,$aix_use_runtimelinking in + aix,*) ;; # no import file + svr4,* | *,yes) # use import file + # The Import File defines what to hardcode. + hardcode_direct_CXX=no + hardcode_direct_absolute_CXX=no + ;; + esac + + if test yes = "$GXX"; then + case $host_os in aix4.[012]|aix4.[012].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`$CC -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + hardcode_direct_CXX=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + hardcode_minus_L_CXX=yes + hardcode_libdir_flag_spec_CXX='-L$libdir' + hardcode_libdir_separator_CXX= + fi + esac + shared_flag='-shared' + if test yes = "$aix_use_runtimelinking"; then + shared_flag=$shared_flag' $wl-G' + fi + # Need to ensure runtime linking is disabled for the traditional + # shared library, or the linker may eventually find shared libraries + # /with/ Import File - we do not want to mix them. + shared_flag_aix='-shared' + shared_flag_svr4='-shared $wl-G' + else + # not using gcc + if test ia64 = "$host_cpu"; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test yes = "$aix_use_runtimelinking"; then + shared_flag='$wl-G' + else + shared_flag='$wl-bM:SRE' + fi + shared_flag_aix='$wl-bM:SRE' + shared_flag_svr4='$wl-G' + fi + fi + + export_dynamic_flag_spec_CXX='$wl-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to + # export. + always_export_symbols_CXX=yes + if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + # The "-G" linker flag allows undefined symbols. + no_undefined_flag_CXX='-bernotok' + # Determine the default libpath from the value encoded in an empty + # executable. + if test set = "${lt_cv_aix_libpath+set}"; then + aix_libpath=$lt_cv_aix_libpath +else + if test ${lt_cv_aix_libpath__CXX+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO" +then : + + lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }' + lt_cv_aix_libpath__CXX=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$lt_cv_aix_libpath__CXX"; then + lt_cv_aix_libpath__CXX=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + if test -z "$lt_cv_aix_libpath__CXX"; then + lt_cv_aix_libpath__CXX=/usr/lib:/lib + fi + +fi + + aix_libpath=$lt_cv_aix_libpath__CXX +fi + + hardcode_libdir_flag_spec_CXX='$wl-blibpath:$libdir:'"$aix_libpath" + + archive_expsym_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag + else + if test ia64 = "$host_cpu"; then + hardcode_libdir_flag_spec_CXX='$wl-R $libdir:/usr/lib:/lib' + allow_undefined_flag_CXX="-z nodefs" + archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + if test set = "${lt_cv_aix_libpath+set}"; then + aix_libpath=$lt_cv_aix_libpath +else + if test ${lt_cv_aix_libpath__CXX+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO" +then : + + lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }' + lt_cv_aix_libpath__CXX=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$lt_cv_aix_libpath__CXX"; then + lt_cv_aix_libpath__CXX=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + if test -z "$lt_cv_aix_libpath__CXX"; then + lt_cv_aix_libpath__CXX=/usr/lib:/lib + fi + +fi + + aix_libpath=$lt_cv_aix_libpath__CXX +fi + + hardcode_libdir_flag_spec_CXX='$wl-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + no_undefined_flag_CXX=' $wl-bernotok' + allow_undefined_flag_CXX=' $wl-berok' + if test yes = "$with_gnu_ld"; then + # We only use this code for GNU lds that support --whole-archive. + whole_archive_flag_spec_CXX='$wl--whole-archive$convenience $wl--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + whole_archive_flag_spec_CXX='$convenience' + fi + archive_cmds_need_lc_CXX=yes + archive_expsym_cmds_CXX='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' + # -brtl affects multiple linker settings, -berok does not and is overridden later + compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([, ]\\)%-berok\\1%g"`' + if test svr4 != "$with_aix_soname"; then + # This is similar to how AIX traditionally builds its shared + # libraries. Need -bnortl late, we may have -brtl in LDFLAGS. + archive_expsym_cmds_CXX="$archive_expsym_cmds_CXX"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' + fi + if test aix != "$with_aix_soname"; then + archive_expsym_cmds_CXX="$archive_expsym_cmds_CXX"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' + else + # used by -dlpreopen to get the symbols + archive_expsym_cmds_CXX="$archive_expsym_cmds_CXX"'~$MV $output_objdir/$realname.d/$soname $output_objdir' + fi + archive_expsym_cmds_CXX="$archive_expsym_cmds_CXX"'~$RM -r $output_objdir/$realname.d' + fi + fi + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + allow_undefined_flag_CXX=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + archive_cmds_CXX='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + else + ld_shlibs_CXX=no + fi + ;; + + chorus*) + case $cc_basename in + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + cygwin* | mingw* | pw32* | cegcc*) + case $GXX,$cc_basename in + ,cl* | no,cl*) + # Native MSVC + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + hardcode_libdir_flag_spec_CXX=' ' + allow_undefined_flag_CXX=unsupported + always_export_symbols_CXX=yes + file_list_spec_CXX='@' + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=.dll + # FIXME: Setting linknames here is a bad hack. + archive_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' + archive_expsym_cmds_CXX='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then + cp "$export_symbols" "$output_objdir/$soname.def"; + echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; + else + $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' + # The linker will not automatically build a static lib if we build a DLL. + # _LT_TAGVAR(old_archive_from_new_cmds, CXX)='true' + enable_shared_with_static_runtimes_CXX=yes + # Don't use ranlib + old_postinstall_cmds_CXX='chmod 644 $oldlib' + postlink_cmds_CXX='lt_outputfile="@OUTPUT@"~ + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile=$lt_outputfile.exe + lt_tool_outputfile=$lt_tool_outputfile.exe + ;; + esac~ + func_to_tool_file "$lt_outputfile"~ + if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' + ;; + *) + # g++ + # _LT_TAGVAR(hardcode_libdir_flag_spec, CXX) is actually meaningless, + # as there is no search path for DLLs. + hardcode_libdir_flag_spec_CXX='-L$libdir' + export_dynamic_flag_spec_CXX='$wl--export-all-symbols' + allow_undefined_flag_CXX=unsupported + always_export_symbols_CXX=no + enable_shared_with_static_runtimes_CXX=yes + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file, use it as + # is; otherwise, prepend EXPORTS... + archive_expsym_cmds_CXX='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + ld_shlibs_CXX=no + fi + ;; + esac + ;; + darwin* | rhapsody*) + + + archive_cmds_need_lc_CXX=no + hardcode_direct_CXX=no + hardcode_automatic_CXX=yes + hardcode_shlibpath_var_CXX=unsupported + if test yes = "$lt_cv_ld_force_load"; then + whole_archive_flag_spec_CXX='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' + + else + whole_archive_flag_spec_CXX='' + fi + link_all_deplibs_CXX=yes + allow_undefined_flag_CXX=$_lt_dar_allow_undefined + case $cc_basename in + ifort*|nagfor*) _lt_dar_can_shared=yes ;; + *) _lt_dar_can_shared=$GCC ;; + esac + if test yes = "$_lt_dar_can_shared"; then + output_verbose_link_cmd=func_echo_all + archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil" + module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil" + archive_expsym_cmds_CXX="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" + module_expsym_cmds_CXX="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" + if test yes != "$lt_cv_apple_cc_single_mod"; then + archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dsymutil" + archive_expsym_cmds_CXX="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dar_export_syms$_lt_dsymutil" + fi + + else + ld_shlibs_CXX=no + fi + + ;; + + os2*) + hardcode_libdir_flag_spec_CXX='-L$libdir' + hardcode_minus_L_CXX=yes + allow_undefined_flag_CXX=unsupported + shrext_cmds=.dll + archive_cmds_CXX='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + archive_expsym_cmds_CXX='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + prefix_cmds="$SED"~ + if test EXPORTS = "`$SED 1q $export_symbols`"; then + prefix_cmds="$prefix_cmds -e 1d"; + fi~ + prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ + cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + old_archive_From_new_cmds_CXX='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' + enable_shared_with_static_runtimes_CXX=yes + ;; + + dgux*) + case $cc_basename in + ec++*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + ghcx*) + # Green Hills C++ Compiler + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + freebsd2.*) + # C++ shared libraries reported to be fairly broken before + # switch to ELF + ld_shlibs_CXX=no + ;; + + freebsd-elf*) + archive_cmds_need_lc_CXX=no + ;; + + freebsd* | dragonfly*) + # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF + # conventions + ld_shlibs_CXX=yes + ;; + + haiku*) + archive_cmds_CXX='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + link_all_deplibs_CXX=yes + ;; + + hpux9*) + hardcode_libdir_flag_spec_CXX='$wl+b $wl$libdir' + hardcode_libdir_separator_CXX=: + export_dynamic_flag_spec_CXX='$wl-E' + hardcode_direct_CXX=yes + hardcode_minus_L_CXX=yes # Not in the search PATH, + # but as the default + # location of the library. + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + aCC*) + archive_cmds_CXX='$RM $output_objdir/$soname~$CC -b $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP " \-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test yes = "$GXX"; then + archive_cmds_CXX='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' + else + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + fi + ;; + esac + ;; + + hpux10*|hpux11*) + if test no = "$with_gnu_ld"; then + hardcode_libdir_flag_spec_CXX='$wl+b $wl$libdir' + hardcode_libdir_separator_CXX=: + + case $host_cpu in + hppa*64*|ia64*) + ;; + *) + export_dynamic_flag_spec_CXX='$wl-E' + ;; + esac + fi + case $host_cpu in + hppa*64*|ia64*) + hardcode_direct_CXX=no + hardcode_shlibpath_var_CXX=no + ;; + *) + hardcode_direct_CXX=yes + hardcode_direct_absolute_CXX=yes + hardcode_minus_L_CXX=yes # Not in the search PATH, + # but as the default + # location of the library. + ;; + esac + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + aCC*) + case $host_cpu in + hppa*64*) + archive_cmds_CXX='$CC -b $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + archive_cmds_CXX='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + archive_cmds_CXX='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP " \-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test yes = "$GXX"; then + if test no = "$with_gnu_ld"; then + case $host_cpu in + hppa*64*) + archive_cmds_CXX='$CC -shared -nostdlib -fPIC $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + archive_cmds_CXX='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + archive_cmds_CXX='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + fi + else + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + fi + ;; + esac + ;; + + interix[3-9]*) + hardcode_direct_CXX=no + hardcode_shlibpath_var_CXX=no + hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir' + export_dynamic_flag_spec_CXX='$wl-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + archive_cmds_CXX='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + archive_expsym_cmds_CXX='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + irix5* | irix6*) + case $cc_basename in + CC*) + # SGI C++ + archive_cmds_CXX='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + + # Archives containing C++ object files must be created using + # "CC -ar", where "CC" is the IRIX C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + old_archive_cmds_CXX='$CC -ar -WR,-u -o $oldlib $oldobjs' + ;; + *) + if test yes = "$GXX"; then + if test no = "$with_gnu_ld"; then + archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + else + archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` -o $lib' + fi + fi + link_all_deplibs_CXX=yes + ;; + esac + hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir' + hardcode_libdir_separator_CXX=: + inherit_rpath_CXX=yes + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + archive_expsym_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib $wl-retain-symbols-file,$export_symbols; mv \$templib $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + + hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir' + export_dynamic_flag_spec_CXX='$wl--export-dynamic' + + # Archives containing C++ object files must be created using + # "CC -Bstatic", where "CC" is the KAI C++ compiler. + old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' + ;; + icpc* | ecpc* ) + # Intel C++ + with_gnu_ld=yes + # version 8.0 and above of icpc choke on multiply defined symbols + # if we add $predep_objects and $postdep_objects, however 7.1 and + # earlier do not add the objects themselves. + case `$CC -V 2>&1` in + *"Version 7."*) + archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + ;; + *) # Version 8.0 or newer + tmp_idyn= + case $host_cpu in + ia64*) tmp_idyn=' -i_dynamic';; + esac + archive_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + ;; + esac + archive_cmds_need_lc_CXX=no + hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir' + export_dynamic_flag_spec_CXX='$wl--export-dynamic' + whole_archive_flag_spec_CXX='$wl--whole-archive$convenience $wl--no-whole-archive' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + case `$CC -V` in + *pgCC\ [1-5].* | *pgcpp\ [1-5].*) + prelink_cmds_CXX='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ + compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' + old_archive_cmds_CXX='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ + $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ + $RANLIB $oldlib' + archive_cmds_CXX='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + ;; + *) # Version 6 and above use weak symbols + archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + ;; + esac + + hardcode_libdir_flag_spec_CXX='$wl--rpath $wl$libdir' + export_dynamic_flag_spec_CXX='$wl--export-dynamic' + whole_archive_flag_spec_CXX='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + ;; + cxx*) + # Compaq C++ + archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib $wl-retain-symbols-file $wl$export_symbols' + + runpath_var=LD_RUN_PATH + hardcode_libdir_flag_spec_CXX='-rpath $libdir' + hardcode_libdir_separator_CXX=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' + ;; + xl* | mpixl* | bgxl*) + # IBM XL 8.0 on PPC, with GNU ld + hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir' + export_dynamic_flag_spec_CXX='$wl--export-dynamic' + archive_cmds_CXX='$CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + if test yes = "$supports_anon_versioning"; then + archive_expsym_cmds_CXX='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' + fi + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + no_undefined_flag_CXX=' -zdefs' + archive_cmds_CXX='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + archive_expsym_cmds_CXX='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file $wl$export_symbols' + hardcode_libdir_flag_spec_CXX='-R$libdir' + whole_archive_flag_spec_CXX='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + compiler_needs_object_CXX=yes + + # Not sure whether something based on + # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 + # would be better. + output_verbose_link_cmd='func_echo_all' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs' + ;; + esac + ;; + esac + ;; + + lynxos*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + + m88k*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + + mvs*) + case $cc_basename in + cxx*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds_CXX='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' + wlarc= + hardcode_libdir_flag_spec_CXX='-R$libdir' + hardcode_direct_CXX=yes + hardcode_shlibpath_var_CXX=no + fi + # Workaround some broken pre-1.5 toolchains + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' + ;; + + *nto* | *qnx*) + ld_shlibs_CXX=yes + ;; + + openbsd* | bitrig*) + if test -f /usr/libexec/ld.so; then + hardcode_direct_CXX=yes + hardcode_shlibpath_var_CXX=no + hardcode_direct_absolute_CXX=yes + archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir' + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`"; then + archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file,$export_symbols -o $lib' + export_dynamic_flag_spec_CXX='$wl-E' + whole_archive_flag_spec_CXX=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' + fi + output_verbose_link_cmd=func_echo_all + else + ld_shlibs_CXX=no + fi + ;; + + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + + hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir' + hardcode_libdir_separator_CXX=: + + # Archives containing C++ object files must be created using + # the KAI C++ compiler. + case $host in + osf3*) old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' ;; + *) old_archive_cmds_CXX='$CC -o $oldlib $oldobjs' ;; + esac + ;; + RCC*) + # Rational C++ 2.4.1 + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + cxx*) + case $host in + osf3*) + allow_undefined_flag_CXX=' $wl-expect_unresolved $wl\*' + archive_cmds_CXX='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $soname `test -n "$verstring" && func_echo_all "$wl-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir' + ;; + *) + allow_undefined_flag_CXX=' -expect_unresolved \*' + archive_cmds_CXX='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + archive_expsym_cmds_CXX='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ + echo "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname $wl-input $wl$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~ + $RM $lib.exp' + hardcode_libdir_flag_spec_CXX='-rpath $libdir' + ;; + esac + + hardcode_libdir_separator_CXX=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test yes,no = "$GXX,$with_gnu_ld"; then + allow_undefined_flag_CXX=' $wl-expect_unresolved $wl\*' + case $host in + osf3*) + archive_cmds_CXX='$CC -shared -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + ;; + *) + archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + ;; + esac + + hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir' + hardcode_libdir_separator_CXX=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' + + else + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + fi + ;; + esac + ;; + + psos*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + lcc*) + # Lucid + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + solaris*) + case $cc_basename in + CC* | sunCC*) + # Sun C++ 4.2, 5.x and Centerline C++ + archive_cmds_need_lc_CXX=yes + no_undefined_flag_CXX=' -zdefs' + archive_cmds_CXX='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G$allow_undefined_flag $wl-M $wl$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + hardcode_libdir_flag_spec_CXX='-R$libdir' + hardcode_shlibpath_var_CXX=no + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands '-z linker_flag'. + # Supported since Solaris 2.6 (maybe 2.5.1?) + whole_archive_flag_spec_CXX='-z allextract$convenience -z defaultextract' + ;; + esac + link_all_deplibs_CXX=yes + + output_verbose_link_cmd='func_echo_all' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs' + ;; + gcx*) + # Green Hills C++ Compiler + archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' + + # The C++ compiler must be used to create the archive. + old_archive_cmds_CXX='$CC $LDFLAGS -archive -o $oldlib $oldobjs' + ;; + *) + # GNU C++ compiler with Solaris linker + if test yes,no = "$GXX,$with_gnu_ld"; then + no_undefined_flag_CXX=' $wl-z ${wl}defs' + if $CC --version | $GREP -v '^2\.7' > /dev/null; then + archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' + archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared $pic_flag -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' + else + # g++ 2.7 appears to require '-G' NOT '-shared' on this + # platform. + archive_cmds_CXX='$CC -G -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' + archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' + fi + + hardcode_libdir_flag_spec_CXX='$wl-R $wl$libdir' + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + whole_archive_flag_spec_CXX='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' + ;; + esac + fi + ;; + esac + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) + no_undefined_flag_CXX='$wl-z,text' + archive_cmds_need_lc_CXX=no + hardcode_shlibpath_var_CXX=no + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + archive_cmds_CXX='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds_CXX='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We CANNOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + no_undefined_flag_CXX='$wl-z,text' + allow_undefined_flag_CXX='$wl-z,nodefs' + archive_cmds_need_lc_CXX=no + hardcode_shlibpath_var_CXX=no + hardcode_libdir_flag_spec_CXX='$wl-R,$libdir' + hardcode_libdir_separator_CXX=':' + link_all_deplibs_CXX=yes + export_dynamic_flag_spec_CXX='$wl-Bexport' + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + archive_cmds_CXX='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + old_archive_cmds_CXX='$CC -Tprelink_objects $oldobjs~ + '"$old_archive_cmds_CXX" + reload_cmds_CXX='$CC -Tprelink_objects $reload_objs~ + '"$reload_cmds_CXX" + ;; + *) + archive_cmds_CXX='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + vxworks*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5 +printf "%s\n" "$ld_shlibs_CXX" >&6; } + test no = "$ld_shlibs_CXX" && can_build_shared=no + + GCC_CXX=$GXX + LD_CXX=$LD + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + # Dependencies to place before and after the object being linked: +predep_objects_CXX= +postdep_objects_CXX= +predeps_CXX= +postdeps_CXX= +compiler_lib_search_path_CXX= + +cat > conftest.$ac_ext <<_LT_EOF +class Foo +{ +public: + Foo (void) { a = 0; } +private: + int a; +}; +_LT_EOF + + +_lt_libdeps_save_CFLAGS=$CFLAGS +case "$CC $CFLAGS " in #( +*\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; +*\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; +*\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;; +esac + +if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + # Parse the compiler output and extract the necessary + # objects, libraries and library flags. + + # Sentinel used to keep track of whether or not we are before + # the conftest object file. + pre_test_object_deps_done=no + + for p in `eval "$output_verbose_link_cmd"`; do + case $prev$p in + + -L* | -R* | -l*) + # Some compilers place space between "-{L,R}" and the path. + # Remove the space. + if test x-L = "$p" || + test x-R = "$p"; then + prev=$p + continue + fi + + # Expand the sysroot to ease extracting the directories later. + if test -z "$prev"; then + case $p in + -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;; + -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;; + -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;; + esac + fi + case $p in + =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; + esac + if test no = "$pre_test_object_deps_done"; then + case $prev in + -L | -R) + # Internal compiler library paths should come after those + # provided the user. The postdeps already come after the + # user supplied libs so there is no need to process them. + if test -z "$compiler_lib_search_path_CXX"; then + compiler_lib_search_path_CXX=$prev$p + else + compiler_lib_search_path_CXX="${compiler_lib_search_path_CXX} $prev$p" + fi + ;; + # The "-l" case would never come before the object being + # linked, so don't bother handling this case. + esac + else + if test -z "$postdeps_CXX"; then + postdeps_CXX=$prev$p + else + postdeps_CXX="${postdeps_CXX} $prev$p" + fi + fi + prev= + ;; + + *.lto.$objext) ;; # Ignore GCC LTO objects + *.$objext) + # This assumes that the test object file only shows up + # once in the compiler output. + if test "$p" = "conftest.$objext"; then + pre_test_object_deps_done=yes + continue + fi + + if test no = "$pre_test_object_deps_done"; then + if test -z "$predep_objects_CXX"; then + predep_objects_CXX=$p + else + predep_objects_CXX="$predep_objects_CXX $p" + fi + else + if test -z "$postdep_objects_CXX"; then + postdep_objects_CXX=$p + else + postdep_objects_CXX="$postdep_objects_CXX $p" + fi + fi + ;; + + *) ;; # Ignore the rest. + + esac + done + + # Clean up. + rm -f a.out a.exe +else + echo "libtool.m4: error: problem compiling CXX test program" +fi + +$RM -f confest.$objext +CFLAGS=$_lt_libdeps_save_CFLAGS + +# PORTME: override above test on systems where it is broken +case $host_os in +interix[3-9]*) + # Interix 3.5 installs completely hosed .la files for C++, so rather than + # hack all around it, let's just trust "g++" to DTRT. + predep_objects_CXX= + postdep_objects_CXX= + postdeps_CXX= + ;; +esac + + +case " $postdeps_CXX " in +*" -lc "*) archive_cmds_need_lc_CXX=no ;; +esac + compiler_lib_search_dirs_CXX= +if test -n "${compiler_lib_search_path_CXX}"; then + compiler_lib_search_dirs_CXX=`echo " ${compiler_lib_search_path_CXX}" | $SED -e 's! -L! !g' -e 's!^ !!'` +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + lt_prog_compiler_wl_CXX= +lt_prog_compiler_pic_CXX= +lt_prog_compiler_static_CXX= + + + # C++ specific cases for pic, static, wl, etc. + if test yes = "$GXX"; then + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test ia64 = "$host_cpu"; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static_CXX='-Bstatic' + fi + lt_prog_compiler_pic_CXX='-fPIC' + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + lt_prog_compiler_pic_CXX='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the '-m68020' flag to GCC prevents building anything better, + # like '-m68040'. + lt_prog_compiler_pic_CXX='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + mingw* | cygwin* | os2* | pw32* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + lt_prog_compiler_pic_CXX='-DDLL_EXPORT' + case $host_os in + os2*) + lt_prog_compiler_static_CXX='$wl-static' + ;; + esac + ;; + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic_CXX='-fno-common' + ;; + *djgpp*) + # DJGPP does not support shared libraries at all + lt_prog_compiler_pic_CXX= + ;; + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + lt_prog_compiler_static_CXX= + ;; + interix[3-9]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic_CXX=-Kconform_pic + fi + ;; + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + ;; + *) + lt_prog_compiler_pic_CXX='-fPIC' + ;; + esac + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic_CXX='-fPIC -shared' + ;; + *) + lt_prog_compiler_pic_CXX='-fPIC' + ;; + esac + else + case $host_os in + aix[4-9]*) + # All AIX code is PIC. + if test ia64 = "$host_cpu"; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static_CXX='-Bstatic' + else + lt_prog_compiler_static_CXX='-bnso -bI:/lib/syscalls.exp' + fi + ;; + chorus*) + case $cc_basename in + cxch68*) + # Green Hills C++ Compiler + # _LT_TAGVAR(lt_prog_compiler_static, CXX)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" + ;; + esac + ;; + mingw* | cygwin* | os2* | pw32* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_prog_compiler_pic_CXX='-DDLL_EXPORT' + ;; + dgux*) + case $cc_basename in + ec++*) + lt_prog_compiler_pic_CXX='-KPIC' + ;; + ghcx*) + # Green Hills C++ Compiler + lt_prog_compiler_pic_CXX='-pic' + ;; + *) + ;; + esac + ;; + freebsd* | dragonfly*) + # FreeBSD uses GNU C++ + ;; + hpux9* | hpux10* | hpux11*) + case $cc_basename in + CC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='$wl-a ${wl}archive' + if test ia64 != "$host_cpu"; then + lt_prog_compiler_pic_CXX='+Z' + fi + ;; + aCC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='$wl-a ${wl}archive' + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic_CXX='+Z' + ;; + esac + ;; + *) + ;; + esac + ;; + interix*) + # This is c89, which is MS Visual C++ (no shared libs) + # Anyone wants to do a port? + ;; + irix5* | irix6* | nonstopux*) + case $cc_basename in + CC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='-non_shared' + # CC pic flag -KPIC is the default. + ;; + *) + ;; + esac + ;; + linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + case $cc_basename in + KCC*) + # KAI C++ Compiler + lt_prog_compiler_wl_CXX='--backend -Wl,' + lt_prog_compiler_pic_CXX='-fPIC' + ;; + ecpc* ) + # old Intel C++ for x86_64, which still supported -KPIC. + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-static' + ;; + icpc* ) + # Intel C++, used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-fPIC' + lt_prog_compiler_static_CXX='-static' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-fpic' + lt_prog_compiler_static_CXX='-Bstatic' + ;; + cxx*) + # Compaq C++ + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + lt_prog_compiler_pic_CXX= + lt_prog_compiler_static_CXX='-non_shared' + ;; + xlc* | xlC* | bgxl[cC]* | mpixl[cC]*) + # IBM XL 8.0, 9.0 on PPC and BlueGene + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-qpic' + lt_prog_compiler_static_CXX='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-Bstatic' + lt_prog_compiler_wl_CXX='-Qoption ld ' + ;; + esac + ;; + esac + ;; + lynxos*) + ;; + m88k*) + ;; + mvs*) + case $cc_basename in + cxx*) + lt_prog_compiler_pic_CXX='-W c,exportall' + ;; + *) + ;; + esac + ;; + netbsd* | netbsdelf*-gnu) + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic_CXX='-fPIC -shared' + ;; + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + lt_prog_compiler_wl_CXX='--backend -Wl,' + ;; + RCC*) + # Rational C++ 2.4.1 + lt_prog_compiler_pic_CXX='-pic' + ;; + cxx*) + # Digital/Compaq C++ + lt_prog_compiler_wl_CXX='-Wl,' + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + lt_prog_compiler_pic_CXX= + lt_prog_compiler_static_CXX='-non_shared' + ;; + *) + ;; + esac + ;; + psos*) + ;; + solaris*) + case $cc_basename in + CC* | sunCC*) + # Sun C++ 4.2, 5.x and Centerline C++ + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-Bstatic' + lt_prog_compiler_wl_CXX='-Qoption ld ' + ;; + gcx*) + # Green Hills C++ Compiler + lt_prog_compiler_pic_CXX='-PIC' + ;; + *) + ;; + esac + ;; + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + lt_prog_compiler_pic_CXX='-pic' + lt_prog_compiler_static_CXX='-Bstatic' + ;; + lcc*) + # Lucid + lt_prog_compiler_pic_CXX='-pic' + ;; + *) + ;; + esac + ;; + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + case $cc_basename in + CC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-Bstatic' + ;; + esac + ;; + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + lt_prog_compiler_pic_CXX='-KPIC' + ;; + *) + ;; + esac + ;; + vxworks*) + ;; + *) + lt_prog_compiler_can_build_shared_CXX=no + ;; + esac + fi + +case $host_os in + # For platforms that do not support PIC, -DPIC is meaningless: + *djgpp*) + lt_prog_compiler_pic_CXX= + ;; + *) + lt_prog_compiler_pic_CXX="$lt_prog_compiler_pic_CXX -DPIC" + ;; +esac + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 +printf %s "checking for $compiler option to produce PIC... " >&6; } +if test ${lt_cv_prog_compiler_pic_CXX+y} +then : + printf %s "(cached) " >&6 +else $as_nop + lt_cv_prog_compiler_pic_CXX=$lt_prog_compiler_pic_CXX +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_CXX" >&5 +printf "%s\n" "$lt_cv_prog_compiler_pic_CXX" >&6; } +lt_prog_compiler_pic_CXX=$lt_cv_prog_compiler_pic_CXX + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$lt_prog_compiler_pic_CXX"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works" >&5 +printf %s "checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works... " >&6; } +if test ${lt_cv_prog_compiler_pic_works_CXX+y} +then : + printf %s "(cached) " >&6 +else $as_nop + lt_cv_prog_compiler_pic_works_CXX=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$lt_prog_compiler_pic_CXX -DPIC" ## exclude from sc_useless_quotes_in_assignment + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_pic_works_CXX=yes + fi + fi + $RM conftest* + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works_CXX" >&5 +printf "%s\n" "$lt_cv_prog_compiler_pic_works_CXX" >&6; } + +if test yes = "$lt_cv_prog_compiler_pic_works_CXX"; then + case $lt_prog_compiler_pic_CXX in + "" | " "*) ;; + *) lt_prog_compiler_pic_CXX=" $lt_prog_compiler_pic_CXX" ;; + esac +else + lt_prog_compiler_pic_CXX= + lt_prog_compiler_can_build_shared_CXX=no +fi + +fi + + + + + +# +# Check to make sure the static flag actually works. +# +wl=$lt_prog_compiler_wl_CXX eval lt_tmp_static_flag=\"$lt_prog_compiler_static_CXX\" +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 +printf %s "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } +if test ${lt_cv_prog_compiler_static_works_CXX+y} +then : + printf %s "(cached) " >&6 +else $as_nop + lt_cv_prog_compiler_static_works_CXX=no + save_LDFLAGS=$LDFLAGS + LDFLAGS="$LDFLAGS $lt_tmp_static_flag" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_static_works_CXX=yes + fi + else + lt_cv_prog_compiler_static_works_CXX=yes + fi + fi + $RM -r conftest* + LDFLAGS=$save_LDFLAGS + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works_CXX" >&5 +printf "%s\n" "$lt_cv_prog_compiler_static_works_CXX" >&6; } + +if test yes = "$lt_cv_prog_compiler_static_works_CXX"; then + : +else + lt_prog_compiler_static_CXX= +fi + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +printf %s "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if test ${lt_cv_prog_compiler_c_o_CXX+y} +then : + printf %s "(cached) " >&6 +else $as_nop + lt_cv_prog_compiler_c_o_CXX=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o_CXX=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5 +printf "%s\n" "$lt_cv_prog_compiler_c_o_CXX" >&6; } + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +printf %s "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if test ${lt_cv_prog_compiler_c_o_CXX+y} +then : + printf %s "(cached) " >&6 +else $as_nop + lt_cv_prog_compiler_c_o_CXX=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o_CXX=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5 +printf "%s\n" "$lt_cv_prog_compiler_c_o_CXX" >&6; } + + + + +hard_links=nottested +if test no = "$lt_cv_prog_compiler_c_o_CXX" && test no != "$need_locks"; then + # do not overwrite the value of need_locks provided by the user + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 +printf %s "checking if we can lock with hard links... " >&6; } + hard_links=yes + $RM conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 +printf "%s\n" "$hard_links" >&6; } + if test no = "$hard_links"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&5 +printf "%s\n" "$as_me: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&2;} + need_locks=warn + fi +else + need_locks=no +fi + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +printf %s "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } + + export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + exclude_expsyms_CXX='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' + case $host_os in + aix[4-9]*) + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to GNU nm, but means don't demangle to AIX nm. + # Without the "-l" option, or with the "-B" option, AIX nm treats + # weak defined symbols like other global defined symbols, whereas + # GNU nm marks them as "W". + # While the 'weak' keyword is ignored in the Export File, we need + # it in the Import File for the 'aix-soname' feature, so we have + # to replace the "-B" option with "-P" for AIX nm. + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + export_symbols_cmds_CXX='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' + else + export_symbols_cmds_CXX='`func_echo_all $NM | $SED -e '\''s/B\([^B]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && (substr(\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' + fi + ;; + pw32*) + export_symbols_cmds_CXX=$ltdll_cmds + ;; + cygwin* | mingw* | cegcc*) + case $cc_basename in + cl*) + exclude_expsyms_CXX='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' + ;; + *) + export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' + exclude_expsyms_CXX='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' + ;; + esac + ;; + linux* | k*bsd*-gnu | gnu*) + link_all_deplibs_CXX=no + ;; + *) + export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + ;; + esac + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5 +printf "%s\n" "$ld_shlibs_CXX" >&6; } +test no = "$ld_shlibs_CXX" && can_build_shared=no + +with_gnu_ld_CXX=$with_gnu_ld + + + + + + +# +# Do we need to explicitly link libc? +# +case "x$archive_cmds_need_lc_CXX" in +x|xyes) + # Assume -lc should be added + archive_cmds_need_lc_CXX=yes + + if test yes,yes = "$GCC,$enable_shared"; then + case $archive_cmds_CXX in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 +printf %s "checking whether -lc should be explicitly linked in... " >&6; } +if test ${lt_cv_archive_cmds_need_lc_CXX+y} +then : + printf %s "(cached) " >&6 +else $as_nop + $RM conftest* + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$lt_prog_compiler_wl_CXX + pic_flag=$lt_prog_compiler_pic_CXX + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$allow_undefined_flag_CXX + allow_undefined_flag_CXX= + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 + (eval $archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + then + lt_cv_archive_cmds_need_lc_CXX=no + else + lt_cv_archive_cmds_need_lc_CXX=yes + fi + allow_undefined_flag_CXX=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $RM conftest* + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc_CXX" >&5 +printf "%s\n" "$lt_cv_archive_cmds_need_lc_CXX" >&6; } + archive_cmds_need_lc_CXX=$lt_cv_archive_cmds_need_lc_CXX + ;; + esac + fi + ;; +esac + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 +printf %s "checking dynamic linker characteristics... " >&6; } + +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=.so +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + + + +case $host_os in +aix3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='$libname$release$shared_ext$major' + ;; + +aix[4-9]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test ia64 = "$host_cpu"; then + # AIX 5 supports IA64 + library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line '#! .'. This would cause the generated library to + # depend on '.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[01] | aix4.[01].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # Using Import Files as archive members, it is possible to support + # filename-based versioning of shared library archives on AIX. While + # this would work for both with and without runtime linking, it will + # prevent static linking of such archives. So we do filename-based + # shared library versioning with .so extension only, which is used + # when both runtime linking and shared linking is enabled. + # Unfortunately, runtime linking may impact performance, so we do + # not want this to be the default eventually. Also, we use the + # versioned .so libs for executables only if there is the -brtl + # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only. + # To allow for filename-based versioning support, we need to create + # libNAME.so.V as an archive file, containing: + # *) an Import File, referring to the versioned filename of the + # archive as well as the shared archive member, telling the + # bitwidth (32 or 64) of that shared object, and providing the + # list of exported symbols of that shared object, eventually + # decorated with the 'weak' keyword + # *) the shared object with the F_LOADONLY flag set, to really avoid + # it being seen by the linker. + # At run time we better use the real file rather than another symlink, + # but for link time we create the symlink libNAME.so -> libNAME.so.V + + case $with_aix_soname,$aix_use_runtimelinking in + # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + aix,yes) # traditional libtool + dynamic_linker='AIX unversionable lib.so' + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + ;; + aix,no) # traditional AIX only + dynamic_linker='AIX lib.a(lib.so.V)' + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='$libname$release.a $libname.a' + soname_spec='$libname$release$shared_ext$major' + ;; + svr4,*) # full svr4 only + dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o)" + library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' + # We do not specify a path in Import Files, so LIBPATH fires. + shlibpath_overrides_runpath=yes + ;; + *,yes) # both, prefer svr4 + dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o), lib.a(lib.so.V)" + library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' + # unpreferred sharedlib libNAME.a needs extra handling + postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"' + postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"' + # We do not specify a path in Import Files, so LIBPATH fires. + shlibpath_overrides_runpath=yes + ;; + *,no) # both, prefer aix + dynamic_linker="AIX lib.a(lib.so.V), lib.so.V($shared_archive_member_spec.o)" + library_names_spec='$libname$release.a $libname.a' + soname_spec='$libname$release$shared_ext$major' + # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling + postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)' + postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"' + ;; + esac + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + case $host_cpu in + powerpc) + # Since July 2007 AmigaOS4 officially supports .so libraries. + # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + ;; + m68k) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + esac + ;; + +beos*) + library_names_spec='$libname$shared_ext' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[45]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32* | cegcc*) + version_type=windows + shrext_cmds=.dll + need_version=no + need_lib_prefix=no + + case $GCC,$cc_basename in + yes,*) + # gcc + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + + ;; + mingw* | cegcc*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + ;; + esac + dynamic_linker='Win32 ld.exe' + ;; + + *,cl*) + # Native MSVC + libname_spec='$name' + soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + library_names_spec='$libname.dll.lib' + + case $build_os in + mingw*) + sys_lib_search_path_spec= + lt_save_ifs=$IFS + IFS=';' + for lt_path in $LIB + do + IFS=$lt_save_ifs + # Let DOS variable expansion print the short 8.3 style file name. + lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` + sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" + done + IFS=$lt_save_ifs + # Convert to MSYS style. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` + ;; + cygwin*) + # Convert to unix form, then to dos form, then back to unix form + # but this time dos style (no spaces!) so that the unix form looks + # like /cygdrive/c/PROGRA~1:/cygdr... + sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` + sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` + sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + ;; + *) + sys_lib_search_path_spec=$LIB + if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then + # It is most probably a Windows format PATH. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + # FIXME: find the short name or the path components, as spaces are + # common. (e.g. "Program Files" -> "PROGRA~1") + ;; + esac + + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + dynamic_linker='Win32 link.exe' + ;; + + *) + # Assume MSVC wrapper + library_names_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext $libname.lib' + dynamic_linker='Win32 ld.exe' + ;; + esac + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$major$shared_ext $libname$shared_ext' + soname_spec='$libname$release$major$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' + + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[23].*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2.*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[01]* | freebsdelf3.[01]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ + freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +haiku*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + dynamic_linker="$host_os runtime_loader" + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LIBRARY_PATH + shlibpath_overrides_runpath=no + sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + if test 32 = "$HPUX_IA64_MODE"; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + sys_lib_dlsearch_path_spec=/usr/lib/hpux32 + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + sys_lib_dlsearch_path_spec=/usr/lib/hpux64 + fi + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555, ... + postinstall_cmds='chmod 555 $lib' + # or fails outright, so override atomically: + install_override_mode=555 + ;; + +interix[3-9]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test yes = "$lt_cv_prog_gnu_ld"; then + version_type=linux # correct to gnu/linux during the next big refactor + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='$libname$release$shared_ext$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff" + sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +linux*android*) + version_type=none # Android doesn't support versioned libraries. + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext' + soname_spec='$libname$release$shared_ext' + finish_cmds= + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + dynamic_linker='Android linker' + # Don't embed -rpath directories since the linker doesn't support them. + hardcode_libdir_flag_spec_CXX='-L$libdir' + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + + # Some binutils ld are patched to set DT_RUNPATH + if test ${lt_cv_shlibpath_overrides_runpath+y} +then : + printf %s "(cached) " >&6 +else $as_nop + lt_cv_shlibpath_overrides_runpath=no + save_LDFLAGS=$LDFLAGS + save_libdir=$libdir + eval "libdir=/foo; wl=\"$lt_prog_compiler_wl_CXX\"; \ + LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec_CXX\"" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO" +then : + if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null +then : + lt_cv_shlibpath_overrides_runpath=yes +fi +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS=$save_LDFLAGS + libdir=$save_libdir + +fi + + shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Ideally, we could use ldconfig to report *all* directores which are + # searched for libraries, however this is still not possible. Aside from not + # being certain /sbin/ldconfig is available, command + # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64, + # even though it is searched at run-time. Try to do the best guess by + # appending ld.so.conf contents (and includes) to the search path. + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsdelf*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='NetBSD ld.elf_so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +*nto* | *qnx*) + version_type=qnx + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='ldqnx.so' + ;; + +openbsd* | bitrig*) + version_type=sunos + sys_lib_dlsearch_path_spec=/usr/lib + need_lib_prefix=no + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then + need_version=no + else + need_version=yes + fi + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +os2*) + libname_spec='$name' + version_type=windows + shrext_cmds=.dll + need_version=no + need_lib_prefix=no + # OS/2 can only load a DLL with a base name of 8 characters or less. + soname_spec='`test -n "$os2dllname" && libname="$os2dllname"; + v=$($ECHO $release$versuffix | tr -d .-); + n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _); + $ECHO $n$v`$shared_ext' + library_names_spec='${libname}_dll.$libext' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=BEGINLIBPATH + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='$libname$release$shared_ext$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + +rdos*) + dynamic_linker=no + ;; + +solaris*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test yes = "$with_gnu_ld"; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec; then + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext' + soname_spec='$libname$shared_ext.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=sco + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + if test yes = "$with_gnu_ld"; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +tpf*) + # TPF is a cross-target only. Preferred cross-host = GNU/Linux. + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +uts4*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 +printf "%s\n" "$dynamic_linker" >&6; } +test no = "$dynamic_linker" && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test yes = "$GCC"; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then + sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec +fi + +if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then + sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec +fi + +# remember unaugmented sys_lib_dlsearch_path content for libtool script decls... +configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec + +# ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code +func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH" + +# to be used as default LT_SYS_LIBRARY_PATH value in generated libtool +configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 +printf %s "checking how to hardcode library paths into programs... " >&6; } +hardcode_action_CXX= +if test -n "$hardcode_libdir_flag_spec_CXX" || + test -n "$runpath_var_CXX" || + test yes = "$hardcode_automatic_CXX"; then + + # We can hardcode non-existent directories. + if test no != "$hardcode_direct_CXX" && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, CXX)" && + test no != "$hardcode_minus_L_CXX"; then + # Linking always hardcodes the temporary library directory. + hardcode_action_CXX=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + hardcode_action_CXX=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + hardcode_action_CXX=unsupported +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $hardcode_action_CXX" >&5 +printf "%s\n" "$hardcode_action_CXX" >&6; } + +if test relink = "$hardcode_action_CXX" || + test yes = "$inherit_rpath_CXX"; then + # Fast installation is not supported + enable_fast_install=no +elif test yes = "$shlibpath_overrides_runpath" || + test no = "$enable_shared"; then + # Fast installation is not necessary + enable_fast_install=needless +fi + + + + + + + + fi # test -n "$compiler" + + CC=$lt_save_CC + CFLAGS=$lt_save_CFLAGS + LDCXX=$LD + LD=$lt_save_LD + GCC=$lt_save_GCC + with_gnu_ld=$lt_save_with_gnu_ld + lt_cv_path_LDCXX=$lt_cv_path_LD + lt_cv_path_LD=$lt_save_path_LD + lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld + lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld +fi # test yes != "$_lt_caught_CXX_error" + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + + + + + + + + + + + + + + ac_config_commands="$ac_config_commands libtool" + + + + +# Only expand once: + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 +printf %s "checking for a sed that does not truncate output... " >&6; } +if test ${ac_cv_path_SED+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ + for ac_i in 1 2 3 4 5 6 7; do + ac_script="$ac_script$as_nl$ac_script" + done + echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed + { ac_script=; unset ac_script;} + if test -z "$SED"; then + ac_path_SED_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_prog in sed gsed + do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_SED="$as_dir$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_SED" || continue +# Check for GNU ac_path_SED and select it if it is found. + # Check for GNU $ac_path_SED +case `"$ac_path_SED" --version 2>&1` in +*GNU*) + ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; +*) + ac_count=0 + printf %s 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + printf "%s\n" '' >> "conftest.nl" + "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_SED_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_SED="$ac_path_SED" + ac_path_SED_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_SED_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_SED"; then + as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 + fi +else + ac_cv_path_SED=$SED +fi + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 +printf "%s\n" "$ac_cv_path_SED" >&6; } + SED="$ac_cv_path_SED" + rm -f conftest.sed + + + + + + + + if test -n "$PYTHON"; then + # If the user set $PYTHON, use it and don't search something else. + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $PYTHON version is >= 3.6" >&5 +printf %s "checking whether $PYTHON version is >= 3.6... " >&6; } + 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, '3.6'.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)" + if { echo "$as_me:$LINENO: $PYTHON -c "$prog"" >&5 + ($PYTHON -c "$prog") >&5 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + as_fn_error $? "Python interpreter is too old" "$LINENO" 5 +fi + am_display_PYTHON=$PYTHON + else + # Otherwise, try each interpreter until we find one that satisfies + # VERSION. + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a Python interpreter with version >= 3.6" >&5 +printf %s "checking for a Python interpreter with version >= 3.6... " >&6; } +if test ${am_cv_pathless_PYTHON+y} +then : + printf %s "(cached) " >&6 +else $as_nop + + for am_cv_pathless_PYTHON in python python2 python3 python3.11 python3.10 python3.9 python3.8 python3.7 python3.6 python3.5 python3.4 python3.3 python3.2 python3.1 python3.0 python2.7 python2.6 python2.5 python2.4 python2.3 python2.2 python2.1 python2.0 none; do + test "$am_cv_pathless_PYTHON" = none && break + 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, '3.6'.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)" + if { echo "$as_me:$LINENO: $am_cv_pathless_PYTHON -c "$prog"" >&5 + ($am_cv_pathless_PYTHON -c "$prog") >&5 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +then : + break +fi + done +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_pathless_PYTHON" >&5 +printf "%s\n" "$am_cv_pathless_PYTHON" >&6; } + # Set $PYTHON to the absolute path of $am_cv_pathless_PYTHON. + if test "$am_cv_pathless_PYTHON" = none; then + PYTHON=: + else + # Extract the first word of "$am_cv_pathless_PYTHON", so it can be a program name with args. +set dummy $am_cv_pathless_PYTHON; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_path_PYTHON+y} +then : + printf %s "(cached) " >&6 +else $as_nop + case $PYTHON in + [\\/]* | ?:[\\/]*) + ac_cv_path_PYTHON="$PYTHON" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_path_PYTHON="$as_dir$ac_word$ac_exec_ext" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +PYTHON=$ac_cv_path_PYTHON +if test -n "$PYTHON"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PYTHON" >&5 +printf "%s\n" "$PYTHON" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + + fi + am_display_PYTHON=$am_cv_pathless_PYTHON + fi + + + if test "$PYTHON" = :; then + : + else + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $am_display_PYTHON version" >&5 +printf %s "checking for $am_display_PYTHON version... " >&6; } +if test ${am_cv_python_version+y} +then : + printf %s "(cached) " >&6 +else $as_nop + am_cv_python_version=`$PYTHON -c "import sys; print ('%u.%u' % sys.version_info[:2])"` +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_python_version" >&5 +printf "%s\n" "$am_cv_python_version" >&6; } + PYTHON_VERSION=$am_cv_python_version + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $am_display_PYTHON platform" >&5 +printf %s "checking for $am_display_PYTHON platform... " >&6; } +if test ${am_cv_python_platform+y} +then : + printf %s "(cached) " >&6 +else $as_nop + am_cv_python_platform=`$PYTHON -c "import sys; sys.stdout.write(sys.platform)"` +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_python_platform" >&5 +printf "%s\n" "$am_cv_python_platform" >&6; } + PYTHON_PLATFORM=$am_cv_python_platform + + + if test "x$prefix" = xNONE; then + am__usable_prefix=$ac_default_prefix + else + am__usable_prefix=$prefix + fi + + # Allow user to request using sys.* values from Python, + # instead of the GNU $prefix values. + +# Check whether --with-python-sys-prefix was given. +if test ${with_python_sys_prefix+y} +then : + withval=$with_python_sys_prefix; am_use_python_sys=: +else $as_nop + am_use_python_sys=false +fi + + + # Allow user to override whatever the default Python prefix is. + +# Check whether --with-python_prefix was given. +if test ${with_python_prefix+y} +then : + withval=$with_python_prefix; am_python_prefix_subst=$withval + am_cv_python_prefix=$withval + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for explicit $am_display_PYTHON prefix" >&5 +printf %s "checking for explicit $am_display_PYTHON prefix... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_python_prefix" >&5 +printf "%s\n" "$am_cv_python_prefix" >&6; } +else $as_nop + + if $am_use_python_sys; then + # using python sys.prefix value, not GNU + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for python default $am_display_PYTHON prefix" >&5 +printf %s "checking for python default $am_display_PYTHON prefix... " >&6; } +if test ${am_cv_python_prefix+y} +then : + printf %s "(cached) " >&6 +else $as_nop + am_cv_python_prefix=`$PYTHON -c "import sys; sys.stdout.write(sys.prefix)"` +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_python_prefix" >&5 +printf "%s\n" "$am_cv_python_prefix" >&6; } + + case $am_cv_python_prefix in + $am__usable_prefix*) + am__strip_prefix=`echo "$am__usable_prefix" | sed 's|.|.|g'` + am_python_prefix_subst=`echo "$am_cv_python_prefix" | sed "s,^$am__strip_prefix,\\${prefix},"` + ;; + *) + am_python_prefix_subst=$am_cv_python_prefix + ;; + esac + else # using GNU prefix value, not python sys.prefix + am_python_prefix_subst='${prefix}' + am_python_prefix=$am_python_prefix_subst + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for GNU default $am_display_PYTHON prefix" >&5 +printf %s "checking for GNU default $am_display_PYTHON prefix... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_python_prefix" >&5 +printf "%s\n" "$am_python_prefix" >&6; } + fi +fi + + # Substituting python_prefix_subst value. + PYTHON_PREFIX=$am_python_prefix_subst + + + # emacs-page Now do it all over again for Python exec_prefix, but with yet + # another conditional: fall back to regular prefix if that was specified. + +# Check whether --with-python_exec_prefix was given. +if test ${with_python_exec_prefix+y} +then : + withval=$with_python_exec_prefix; am_python_exec_prefix_subst=$withval + am_cv_python_exec_prefix=$withval + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for explicit $am_display_PYTHON exec_prefix" >&5 +printf %s "checking for explicit $am_display_PYTHON exec_prefix... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_python_exec_prefix" >&5 +printf "%s\n" "$am_cv_python_exec_prefix" >&6; } +else $as_nop + + # no explicit --with-python_exec_prefix, but if + # --with-python_prefix was given, use its value for python_exec_prefix too. + if test -n "$with_python_prefix" +then : + am_python_exec_prefix_subst=$with_python_prefix + am_cv_python_exec_prefix=$with_python_prefix + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for python_prefix-given $am_display_PYTHON exec_prefix" >&5 +printf %s "checking for python_prefix-given $am_display_PYTHON exec_prefix... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_python_exec_prefix" >&5 +printf "%s\n" "$am_cv_python_exec_prefix" >&6; } +else $as_nop + + # Set am__usable_exec_prefix whether using GNU or Python values, + # since we use that variable for pyexecdir. + if test "x$exec_prefix" = xNONE; then + am__usable_exec_prefix=$am__usable_prefix + else + am__usable_exec_prefix=$exec_prefix + fi + # + if $am_use_python_sys; then # using python sys.exec_prefix, not GNU + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for python default $am_display_PYTHON exec_prefix" >&5 +printf %s "checking for python default $am_display_PYTHON exec_prefix... " >&6; } +if test ${am_cv_python_exec_prefix+y} +then : + printf %s "(cached) " >&6 +else $as_nop + am_cv_python_exec_prefix=`$PYTHON -c "import sys; sys.stdout.write(sys.exec_prefix)"` +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_python_exec_prefix" >&5 +printf "%s\n" "$am_cv_python_exec_prefix" >&6; } + case $am_cv_python_exec_prefix in + $am__usable_exec_prefix*) + am__strip_prefix=`echo "$am__usable_exec_prefix" | sed 's|.|.|g'` + am_python_exec_prefix_subst=`echo "$am_cv_python_exec_prefix" | sed "s,^$am__strip_prefix,\\${exec_prefix},"` + ;; + *) + am_python_exec_prefix_subst=$am_cv_python_exec_prefix + ;; + esac + else # using GNU $exec_prefix, not python sys.exec_prefix + am_python_exec_prefix_subst='${exec_prefix}' + am_python_exec_prefix=$am_python_exec_prefix_subst + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for GNU default $am_display_PYTHON exec_prefix" >&5 +printf %s "checking for GNU default $am_display_PYTHON exec_prefix... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_python_exec_prefix" >&5 +printf "%s\n" "$am_python_exec_prefix" >&6; } + fi +fi +fi + + # Substituting python_exec_prefix_subst. + PYTHON_EXEC_PREFIX=$am_python_exec_prefix_subst + + + # Factor out some code duplication into this shell variable. + 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: +# +try: + from platform import python_implementation + if python_implementation() == 'CPython' and sys.version[:3] == '2.7': + can_use_sysconfig = 0 +except ImportError: + pass" + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $am_display_PYTHON script directory (pythondir)" >&5 +printf %s "checking for $am_display_PYTHON script directory (pythondir)... " >&6; } +if test ${am_cv_python_pythondir+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test "x$am_cv_python_prefix" = x; then + am_py_prefix=$am__usable_prefix + else + am_py_prefix=$am_cv_python_prefix + fi + am_cv_python_pythondir=`$PYTHON -c " +$am_python_setup_sysconfig +if can_use_sysconfig: + if hasattr(sysconfig, 'get_default_scheme'): + scheme = sysconfig.get_default_scheme() + else: + scheme = sysconfig._get_default_scheme() + if scheme == 'posix_local': + # Debian's default scheme installs to /usr/local/ but we want to find headers in /usr/ + scheme = 'posix_prefix' + sitedir = sysconfig.get_path('purelib', scheme, 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 + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_python_pythondir" >&5 +printf "%s\n" "$am_cv_python_pythondir" >&6; } + pythondir=$am_cv_python_pythondir + + + pkgpythondir=\${pythondir}/$PACKAGE + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $am_display_PYTHON extension module directory (pyexecdir)" >&5 +printf %s "checking for $am_display_PYTHON extension module directory (pyexecdir)... " >&6; } +if test ${am_cv_python_pyexecdir+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test "x$am_cv_python_exec_prefix" = x; then + am_py_exec_prefix=$am__usable_exec_prefix + else + am_py_exec_prefix=$am_cv_python_exec_prefix + fi + am_cv_python_pyexecdir=`$PYTHON -c " +$am_python_setup_sysconfig +if can_use_sysconfig: + if hasattr(sysconfig, 'get_default_scheme'): + scheme = sysconfig.get_default_scheme() + else: + scheme = sysconfig._get_default_scheme() + if scheme == 'posix_local': + # Debian's default scheme installs to /usr/local/ but we want to find headers in /usr/ + scheme = 'posix_prefix' + sitedir = sysconfig.get_path('platlib', scheme, vars={'platbase':'$am_py_exec_prefix'}) +else: + from distutils import sysconfig + sitedir = sysconfig.get_python_lib(1, 0, prefix='$am_py_exec_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 + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_python_pyexecdir" >&5 +printf "%s\n" "$am_cv_python_pyexecdir" >&6; } + pyexecdir=$am_cv_python_pyexecdir + + + pkgpyexecdir=\${pyexecdir}/$PACKAGE + + + + fi + + if test "$PYTHON" != :; then + HAVE_PYTHON_TRUE= + HAVE_PYTHON_FALSE='#' +else + HAVE_PYTHON_TRUE='#' + HAVE_PYTHON_FALSE= +fi + + +# Extract the first word of "cygpath", so it can be a program name with args. +set dummy cygpath; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_CYGPATH+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$CYGPATH"; then + ac_cv_prog_CYGPATH="$CYGPATH" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_CYGPATH="cygpath" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CYGPATH=$ac_cv_prog_CYGPATH +if test -n "$CYGPATH"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CYGPATH" >&5 +printf "%s\n" "$CYGPATH" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + +# Extract the first word of "perl", so it can be a program name with args. +set dummy perl; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_PERL+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$PERL"; then + ac_cv_prog_PERL="$PERL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_PERL="perl" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +PERL=$ac_cv_prog_PERL +if test -n "$PERL"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PERL" >&5 +printf "%s\n" "$PERL" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + +# Extract the first word of "pdflatex", so it can be a program name with args. +set dummy pdflatex; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_PDFLATEX+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$PDFLATEX"; then + ac_cv_prog_PDFLATEX="$PDFLATEX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_PDFLATEX="pdflatex" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +PDFLATEX=$ac_cv_prog_PDFLATEX +if test -n "$PDFLATEX"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PDFLATEX" >&5 +printf "%s\n" "$PDFLATEX" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + +# Extract the first word of "pod2html", so it can be a program name with args. +set dummy pod2html; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_POD2HTML+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$POD2HTML"; then + ac_cv_prog_POD2HTML="$POD2HTML" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_POD2HTML="pod2html" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +POD2HTML=$ac_cv_prog_POD2HTML +if test -n "$POD2HTML"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $POD2HTML" >&5 +printf "%s\n" "$POD2HTML" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + + + +if test "$host_os" = "mingw32" -a -n "$CYGPATH"; then + OS_SRCDIR=`$CYGPATH -m "$srcdir"` +else + OS_SRCDIR="$srcdir" +fi + + if test -n "$PERL" -a -n "$PDFLATEX" -a -n "$POD2HTML"; then + GENERATE_DOC_TRUE= + GENERATE_DOC_FALSE='#' +else + GENERATE_DOC_TRUE='#' + GENERATE_DOC_FALSE= +fi + + +# ------ AX CREATE STDINT H ------------------------------------- +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdint types" >&5 +printf %s "checking for stdint types... " >&6; } +ac_stdint_h=`echo include/isl/stdint.h` +# try to shortcircuit - if the default include path of the compiler +# can find a "stdint.h" header then we assume that all compilers can. +if test ${ac_cv_header_stdint_t+y} +then : + printf %s "(cached) " >&6 +else $as_nop + +old_CXXFLAGS="$CXXFLAGS" ; CXXFLAGS="" +old_CPPFLAGS="$CPPFLAGS" ; CPPFLAGS="" +old_CFLAGS="$CFLAGS" ; CFLAGS="" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main (void) +{ +int_least32_t v = 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_stdint_result="(assuming C99 compatible system)" + ac_cv_header_stdint_t="stdint.h"; +else $as_nop + ac_cv_header_stdint_t="" +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +if test "$GCC" = "yes" && test ".$ac_cv_header_stdint_t" = "."; then +CFLAGS="-std=c99" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main (void) +{ +int_least32_t v = 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: your GCC compiler has a defunct stdint.h for its default-mode" >&5 +printf "%s\n" "$as_me: WARNING: your GCC compiler has a defunct stdint.h for its default-mode" >&2;} +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +fi +CXXFLAGS="$old_CXXFLAGS" +CPPFLAGS="$old_CPPFLAGS" +CFLAGS="$old_CFLAGS" +fi + + +v="... $ac_cv_header_stdint_h" +if test "$ac_stdint_h" = "stdint.h" ; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: (are you sure you want them in ./stdint.h?)" >&5 +printf "%s\n" "(are you sure you want them in ./stdint.h?)" >&6; } +elif test "$ac_stdint_h" = "inttypes.h" ; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: (are you sure you want them in ./inttypes.h?)" >&5 +printf "%s\n" "(are you sure you want them in ./inttypes.h?)" >&6; } +elif test "_$ac_cv_header_stdint_t" = "_" ; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: (putting them into $ac_stdint_h)$v" >&5 +printf "%s\n" "(putting them into $ac_stdint_h)$v" >&6; } +else + ac_cv_header_stdint="$ac_cv_header_stdint_t" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdint (shortcircuit)" >&5 +printf "%s\n" "$ac_cv_header_stdint (shortcircuit)" >&6; } +fi + +if test "_$ac_cv_header_stdint_t" = "_" ; then # cannot shortcircuit.. + + +inttype_headers=`echo | sed -e 's/,/ /g'` + +ac_cv_stdint_result="(no helpful system typedefs seen)" + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdint uintptr_t" >&5 +printf %s "checking for stdint uintptr_t... " >&6; } +if test ${ac_cv_header_stdint_x+y} +then : + printf %s "(cached) " >&6 +else $as_nop + + ac_cv_header_stdint_x="" # the 1997 typedefs (inttypes.h) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: (..)" >&5 +printf "%s\n" "(..)" >&6; } + for i in stdint.h inttypes.h sys/inttypes.h $inttype_headers + do + unset ac_cv_type_uintptr_t + unset ac_cv_type_uint64_t + ac_fn_c_check_type "$LINENO" "uintptr_t" "ac_cv_type_uintptr_t" "#include <$i> +" +if test "x$ac_cv_type_uintptr_t" = xyes +then : + ac_cv_header_stdint_x=$i +else $as_nop + continue +fi + + ac_fn_c_check_type "$LINENO" "uint64_t" "ac_cv_type_uint64_t" "#include<$i> +" +if test "x$ac_cv_type_uint64_t" = xyes +then : + and64="/uint64_t" +else $as_nop + and64="" +fi + + ac_cv_stdint_result="(seen uintptr_t$and64 in $i)" + break + done + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdint uintptr_t" >&5 +printf %s "checking for stdint uintptr_t... " >&6; } + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdint_x" >&5 +printf "%s\n" "$ac_cv_header_stdint_x" >&6; } + + +if test "_$ac_cv_header_stdint_x" = "_" ; then + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdint uint32_t" >&5 +printf %s "checking for stdint uint32_t... " >&6; } +if test ${ac_cv_header_stdint_o+y} +then : + printf %s "(cached) " >&6 +else $as_nop + + ac_cv_header_stdint_o="" # the 1995 typedefs (sys/inttypes.h) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: (..)" >&5 +printf "%s\n" "(..)" >&6; } + for i in inttypes.h sys/inttypes.h stdint.h $inttype_headers + do + unset ac_cv_type_uint32_t + unset ac_cv_type_uint64_t + ac_fn_c_check_type "$LINENO" "uint32_t" "ac_cv_type_uint32_t" "#include <$i> +" +if test "x$ac_cv_type_uint32_t" = xyes +then : + ac_cv_header_stdint_o=$i +else $as_nop + continue +fi + + ac_fn_c_check_type "$LINENO" "uint64_t" "ac_cv_type_uint64_t" "#include<$i> +" +if test "x$ac_cv_type_uint64_t" = xyes +then : + and64="/uint64_t" +else $as_nop + and64="" +fi + + ac_cv_stdint_result="(seen uint32_t$and64 in $i)" + break + break; + done + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdint uint32_t" >&5 +printf %s "checking for stdint uint32_t... " >&6; } + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdint_o" >&5 +printf "%s\n" "$ac_cv_header_stdint_o" >&6; } + +fi + +if test "_$ac_cv_header_stdint_x" = "_" ; then +if test "_$ac_cv_header_stdint_o" = "_" ; then + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdint u_int32_t" >&5 +printf %s "checking for stdint u_int32_t... " >&6; } +if test ${ac_cv_header_stdint_u+y} +then : + printf %s "(cached) " >&6 +else $as_nop + + ac_cv_header_stdint_u="" # the BSD typedefs (sys/types.h) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: (..)" >&5 +printf "%s\n" "(..)" >&6; } + for i in sys/types.h inttypes.h sys/inttypes.h $inttype_headers ; do + unset ac_cv_type_u_int32_t + unset ac_cv_type_u_int64_t + ac_fn_c_check_type "$LINENO" "u_int32_t" "ac_cv_type_u_int32_t" "#include <$i> +" +if test "x$ac_cv_type_u_int32_t" = xyes +then : + ac_cv_header_stdint_u=$i +else $as_nop + continue +fi + + ac_fn_c_check_type "$LINENO" "u_int64_t" "ac_cv_type_u_int64_t" "#include<$i> +" +if test "x$ac_cv_type_u_int64_t" = xyes +then : + and64="/u_int64_t" +else $as_nop + and64="" +fi + + ac_cv_stdint_result="(seen u_int32_t$and64 in $i)" + break + break; + done + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdint u_int32_t" >&5 +printf %s "checking for stdint u_int32_t... " >&6; } + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdint_u" >&5 +printf "%s\n" "$ac_cv_header_stdint_u" >&6; } + +fi fi + +if test "_$ac_cv_header_stdint_x" = "_" ; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdint datatype model" >&5 +printf %s "checking for stdint datatype model... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: (..)" >&5 +printf "%s\n" "(..)" >&6; } + + # The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking size of char" >&5 +printf %s "checking size of char... " >&6; } +if test ${ac_cv_sizeof_char+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (char))" "ac_cv_sizeof_char" "$ac_includes_default" +then : + +else $as_nop + if test "$ac_cv_type_char" = yes; then + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (char) +See \`config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_char=0 + fi +fi + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_char" >&5 +printf "%s\n" "$ac_cv_sizeof_char" >&6; } + + + +printf "%s\n" "#define SIZEOF_CHAR $ac_cv_sizeof_char" >>confdefs.h + + + # The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking size of short" >&5 +printf %s "checking size of short... " >&6; } +if test ${ac_cv_sizeof_short+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (short))" "ac_cv_sizeof_short" "$ac_includes_default" +then : + +else $as_nop + if test "$ac_cv_type_short" = yes; then + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (short) +See \`config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_short=0 + fi +fi + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_short" >&5 +printf "%s\n" "$ac_cv_sizeof_short" >&6; } + + + +printf "%s\n" "#define SIZEOF_SHORT $ac_cv_sizeof_short" >>confdefs.h + + + # The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking size of int" >&5 +printf %s "checking size of int... " >&6; } +if test ${ac_cv_sizeof_int+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (int))" "ac_cv_sizeof_int" "$ac_includes_default" +then : + +else $as_nop + if test "$ac_cv_type_int" = yes; then + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (int) +See \`config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_int=0 + fi +fi + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_int" >&5 +printf "%s\n" "$ac_cv_sizeof_int" >&6; } + + + +printf "%s\n" "#define SIZEOF_INT $ac_cv_sizeof_int" >>confdefs.h + + + # The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking size of long" >&5 +printf %s "checking size of long... " >&6; } +if test ${ac_cv_sizeof_long+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long))" "ac_cv_sizeof_long" "$ac_includes_default" +then : + +else $as_nop + if test "$ac_cv_type_long" = yes; then + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (long) +See \`config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_long=0 + fi +fi + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long" >&5 +printf "%s\n" "$ac_cv_sizeof_long" >&6; } + + + +printf "%s\n" "#define SIZEOF_LONG $ac_cv_sizeof_long" >>confdefs.h + + + # The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking size of void*" >&5 +printf %s "checking size of void*... " >&6; } +if test ${ac_cv_sizeof_voidp+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (void*))" "ac_cv_sizeof_voidp" "$ac_includes_default" +then : + +else $as_nop + if test "$ac_cv_type_voidp" = yes; then + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (void*) +See \`config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_voidp=0 + fi +fi + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_voidp" >&5 +printf "%s\n" "$ac_cv_sizeof_voidp" >&6; } + + + +printf "%s\n" "#define SIZEOF_VOIDP $ac_cv_sizeof_voidp" >>confdefs.h + + + ac_cv_char_data_model="" + ac_cv_char_data_model="$ac_cv_char_data_model$ac_cv_sizeof_char" + ac_cv_char_data_model="$ac_cv_char_data_model$ac_cv_sizeof_short" + ac_cv_char_data_model="$ac_cv_char_data_model$ac_cv_sizeof_int" + ac_cv_long_data_model="" + ac_cv_long_data_model="$ac_cv_long_data_model$ac_cv_sizeof_int" + ac_cv_long_data_model="$ac_cv_long_data_model$ac_cv_sizeof_long" + ac_cv_long_data_model="$ac_cv_long_data_model$ac_cv_sizeof_voidp" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking data model" >&5 +printf %s "checking data model... " >&6; } + case "$ac_cv_char_data_model/$ac_cv_long_data_model" in + 122/242) ac_cv_data_model="IP16" ; n="standard 16bit machine" ;; + 122/244) ac_cv_data_model="LP32" ; n="standard 32bit machine" ;; + 122/*) ac_cv_data_model="i16" ; n="unusual int16 model" ;; + 124/444) ac_cv_data_model="ILP32" ; n="standard 32bit unixish" ;; + 124/488) ac_cv_data_model="LP64" ; n="standard 64bit unixish" ;; + 124/448) ac_cv_data_model="LLP64" ; n="unusual 64bit unixish" ;; + 124/*) ac_cv_data_model="i32" ; n="unusual int32 model" ;; + 128/888) ac_cv_data_model="ILP64" ; n="unusual 64bit numeric" ;; + 128/*) ac_cv_data_model="i64" ; n="unusual int64 model" ;; + 222/*2) ac_cv_data_model="DSP16" ; n="strict 16bit dsptype" ;; + 333/*3) ac_cv_data_model="DSP24" ; n="strict 24bit dsptype" ;; + 444/*4) ac_cv_data_model="DSP32" ; n="strict 32bit dsptype" ;; + 666/*6) ac_cv_data_model="DSP48" ; n="strict 48bit dsptype" ;; + 888/*8) ac_cv_data_model="DSP64" ; n="strict 64bit dsptype" ;; + 222/*|333/*|444/*|666/*|888/*) : + ac_cv_data_model="iDSP" ; n="unusual dsptype" ;; + *) ac_cv_data_model="none" ; n="very unusual model" ;; + esac + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_data_model ($ac_cv_long_data_model, $n)" >&5 +printf "%s\n" "$ac_cv_data_model ($ac_cv_long_data_model, $n)" >&6; } + +fi + +if test "_$ac_cv_header_stdint_x" != "_" ; then + ac_cv_header_stdint="$ac_cv_header_stdint_x" +elif test "_$ac_cv_header_stdint_o" != "_" ; then + ac_cv_header_stdint="$ac_cv_header_stdint_o" +elif test "_$ac_cv_header_stdint_u" != "_" ; then + ac_cv_header_stdint="$ac_cv_header_stdint_u" +else + ac_cv_header_stdint="stddef.h" +fi + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for extra inttypes in chosen header" >&5 +printf %s "checking for extra inttypes in chosen header... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: ($ac_cv_header_stdint)" >&5 +printf "%s\n" "($ac_cv_header_stdint)" >&6; } +unset ac_cv_type_int_least32_t +unset ac_cv_type_int_fast32_t +ac_fn_c_check_type "$LINENO" "int_least32_t" "ac_cv_type_int_least32_t" "#include <$ac_cv_header_stdint> +" +if test "x$ac_cv_type_int_least32_t" = xyes +then : + +fi + +ac_fn_c_check_type "$LINENO" "int_fast32_t" "ac_cv_type_int_fast32_t" "#include<$ac_cv_header_stdint> +" +if test "x$ac_cv_type_int_fast32_t" = xyes +then : + +fi + +ac_fn_c_check_type "$LINENO" "intmax_t" "ac_cv_type_intmax_t" "#include <$ac_cv_header_stdint> +" +if test "x$ac_cv_type_intmax_t" = xyes +then : + +fi + + +fi # shortcircuit to system "stdint.h" +# ------------------ PREPARE VARIABLES ------------------------------ +if test "$GCC" = "yes" ; then +ac_cv_stdint_message="using gnu compiler "`$CC --version | head -1` +else +ac_cv_stdint_message="using $CC" +fi + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: make use of $ac_cv_header_stdint in $ac_stdint_h $ac_cv_stdint_result" >&5 +printf "%s\n" "make use of $ac_cv_header_stdint in $ac_stdint_h $ac_cv_stdint_result" >&6; } + +# ----------------- DONE inttypes.h checks START header ------------- +ac_config_commands="$ac_config_commands $ac_stdint_h" + + + + +# Check whether --with-int was given. +if test ${with_int+y} +then : + withval=$with_int; +else $as_nop + with_int=gmp +fi + +case "$with_int" in +gmp|imath|imath-32) + ;; +*) + as_fn_error $? "bad value ${withval} for --with-int (use gmp, imath or imath-32)" "$LINENO" 5 +esac + + + + + +case "$with_int" in +gmp) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC options needed to detect all undeclared functions" >&5 +printf %s "checking for $CC options needed to detect all undeclared functions... " >&6; } +if test ${ac_cv_c_undeclared_builtin_options+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_save_CFLAGS=$CFLAGS + ac_cv_c_undeclared_builtin_options='cannot detect' + for ac_arg in '' -fno-builtin; do + CFLAGS="$ac_save_CFLAGS $ac_arg" + # This test program should *not* compile successfully. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ +(void) strchr; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + +else $as_nop + # This test program should compile successfully. + # No library function is consistently available on + # freestanding implementations, so test against a dummy + # declaration. Include always-available headers on the + # off chance that they somehow elicit warnings. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include +#include +extern void ac_decl (int, char *); + +int +main (void) +{ +(void) ac_decl (0, (char *) 0); + (void) ac_decl; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + if test x"$ac_arg" = x +then : + ac_cv_c_undeclared_builtin_options='none needed' +else $as_nop + ac_cv_c_undeclared_builtin_options=$ac_arg +fi + break +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + done + CFLAGS=$ac_save_CFLAGS + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_undeclared_builtin_options" >&5 +printf "%s\n" "$ac_cv_c_undeclared_builtin_options" >&6; } + case $ac_cv_c_undeclared_builtin_options in #( + 'cannot detect') : + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot make $CC report undeclared builtins +See \`config.log' for more details" "$LINENO" 5; } ;; #( + 'none needed') : + ac_c_undeclared_builtin_options='' ;; #( + *) : + ac_c_undeclared_builtin_options=$ac_cv_c_undeclared_builtin_options ;; +esac + + + +printf "%s\n" "#define USE_GMP_FOR_MP /**/" >>confdefs.h + + + + +# Check whether --with-gmp was given. +if test ${with_gmp+y} +then : + withval=$with_gmp; +fi + +case "system" in +system|build) + +# Check whether --with-gmp_prefix was given. +if test ${with_gmp_prefix+y} +then : + withval=$with_gmp_prefix; +fi + + +# Check whether --with-gmp_exec_prefix was given. +if test ${with_gmp_exec_prefix+y} +then : + withval=$with_gmp_exec_prefix; +fi + +esac + +# Check whether --with-gmp_builddir was given. +if test ${with_gmp_builddir+y} +then : + withval=$with_gmp_builddir; +fi + +if test "x$with_gmp_prefix" != "x" -a "x$with_gmp_exec_prefix" = "x"; then + with_gmp_exec_prefix=$with_gmp_prefix +fi +if test "x$with_gmp_prefix" != "x" -o "x$with_gmp_exec_prefix" != "x"; then + if test "x$with_gmp" != "x" -a "x$with_gmp" != "xyes" -a "x$with_gmp" != "xsystem"; then + as_fn_error $? "Setting $with_gmp_prefix implies use of system gmp" "$LINENO" 5 + fi + with_gmp="system" +fi +if test "x$with_gmp_builddir" != "x"; then + if test "x$with_gmp" != "x" -a "x$with_gmp" != "xyes" -a "x$with_gmp" != "xbuild"; then + as_fn_error $? "Setting $with_gmp_builddir implies use of build gmp" "$LINENO" 5 + fi + with_gmp="build" + gmp_srcdir=`echo @abs_srcdir@ | $with_gmp_builddir/config.status --file=-` + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: gmp sources in $gmp_srcdir" >&5 +printf "%s\n" "$as_me: gmp sources in $gmp_srcdir" >&6;} +fi +if test "x$with_gmp_exec_prefix" != "x"; then + export PKG_CONFIG_PATH="$with_gmp_exec_prefix/lib/pkgconfig${PKG_CONFIG_PATH+:$PKG_CONFIG_PATH}" +fi +case "$with_gmp" in +system|build) + ;; +*) + case "system" in + bundled) + if test -d $srcdir/.git -a \ + -d $srcdir/gmp -a \ + ! -d $srcdir/gmp/.git; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: git repo detected, but submodule gmp not initialized" >&5 +printf "%s\n" "$as_me: WARNING: git repo detected, but submodule gmp not initialized" >&2;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: You may want to run" >&5 +printf "%s\n" "$as_me: WARNING: You may want to run" >&2;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: git submodule init" >&5 +printf "%s\n" "$as_me: WARNING: git submodule init" >&2;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: git submodule update" >&5 +printf "%s\n" "$as_me: WARNING: git submodule update" >&2;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: sh autogen.sh" >&5 +printf "%s\n" "$as_me: WARNING: sh autogen.sh" >&2;} + fi + if test -f $srcdir/gmp/configure; then + with_gmp="bundled" + else + with_gmp="no" + fi + ;; + *) + with_gmp="system" + ;; + esac + ;; +esac +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking which gmp to use" >&5 +printf %s "checking which gmp to use... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $with_gmp" >&5 +printf "%s\n" "$with_gmp" >&6; } + + +case "$with_gmp" in +system) + if test "x$with_gmp_prefix" != "x"; then + MP_CPPFLAGS="-I$with_gmp_prefix/include" + MP_LDFLAGS="-L$with_gmp_prefix/lib" + fi + MP_LIBS=-lgmp + SAVE_CPPFLAGS="$CPPFLAGS" + SAVE_LDFLAGS="$LDFLAGS" + SAVE_LIBS="$LIBS" + CPPFLAGS="$MP_CPPFLAGS $CPPFLAGS" + LDFLAGS="$MP_LDFLAGS $LDFLAGS" + LIBS="$MP_LIBS $LIBS" + ac_fn_c_check_header_compile "$LINENO" "gmp.h" "ac_cv_header_gmp_h" "$ac_includes_default" +if test "x$ac_cv_header_gmp_h" = xyes +then : + +else $as_nop + as_fn_error $? "gmp.h header not found" "$LINENO" 5 +fi + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for main in -lgmp" >&5 +printf %s "checking for main in -lgmp... " >&6; } +if test ${ac_cv_lib_gmp_main+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_check_lib_save_LIBS=$LIBS +LIBS="-lgmp $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main (void) +{ +return main (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_gmp_main=yes +else $as_nop + ac_cv_lib_gmp_main=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_gmp_main" >&5 +printf "%s\n" "$ac_cv_lib_gmp_main" >&6; } +if test "x$ac_cv_lib_gmp_main" = xyes +then : + printf "%s\n" "#define HAVE_LIBGMP 1" >>confdefs.h + + LIBS="-lgmp $LIBS" + +else $as_nop + as_fn_error $? "gmp library not found" "$LINENO" 5 +fi + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main (void) +{ + + mpz_t n, d; + if (mpz_divisible_p(n, d)) + mpz_divexact_ui(n, n, 4); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + +else $as_nop + as_fn_error $? "gmp library too old" "$LINENO" 5 +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + CPPFLAGS="$SAVE_CPPFLAGS" + LDFLAGS="$SAVE_LDFLAGS" + LIBS="$SAVE_LIBS" + ;; +build) + MP_CPPFLAGS="-I$gmp_srcdir -I$with_gmp_builddir" + MP_LIBS="$with_gmp_builddir/libgmp.la" + ;; +esac +SAVE_CPPFLAGS="$CPPFLAGS" +SAVE_LDFLAGS="$LDFLAGS" +SAVE_LIBS="$LIBS" +CPPFLAGS="$MP_CPPFLAGS $CPPFLAGS" +LDFLAGS="$MP_LDFLAGS $LDFLAGS" +LIBS="$MP_LIBS $LIBS" +need_get_memory_functions=false +ac_fn_check_decl "$LINENO" "mp_get_memory_functions" "ac_cv_have_decl_mp_get_memory_functions" "#include +" "$ac_c_undeclared_builtin_options" "CFLAGS" +if test "x$ac_cv_have_decl_mp_get_memory_functions" = xyes +then : + ac_have_decl=1 +else $as_nop + ac_have_decl=0 +fi +printf "%s\n" "#define HAVE_DECL_MP_GET_MEMORY_FUNCTIONS $ac_have_decl" >>confdefs.h +if test $ac_have_decl = 1 +then : + +else $as_nop + + need_get_memory_functions=true + +fi + +CPPFLAGS="$SAVE_CPPFLAGS" +LDFLAGS="$SAVE_LDFLAGS" +LIBS="$SAVE_LIBS" + if test x$need_get_memory_functions = xtrue; then + NEED_GET_MEMORY_FUNCTIONS_TRUE= + NEED_GET_MEMORY_FUNCTIONS_FALSE='#' +else + NEED_GET_MEMORY_FUNCTIONS_TRUE='#' + NEED_GET_MEMORY_FUNCTIONS_FALSE= +fi + + + ;; +imath|imath-32) + + +printf "%s\n" "#define USE_IMATH_FOR_MP /**/" >>confdefs.h + + +MP_CPPFLAGS="-I$srcdir/imath_wrap" +MP_LDFLAGS="" +MP_LIBS="" + +SAVE_CPPFLAGS="$CPPFLAGS" +CPPFLAGS="$MP_CPPFLAGS $CPPFLAGS" +ac_fn_c_check_header_compile "$LINENO" "imath.h" "ac_cv_header_imath_h" "$ac_includes_default" +if test "x$ac_cv_header_imath_h" = xyes +then : + +else $as_nop + as_fn_error $? "imath.h header not found" "$LINENO" 5 +fi + +ac_fn_c_check_header_compile "$LINENO" "gmp_compat.h" "ac_cv_header_gmp_compat_h" "$ac_includes_default" +if test "x$ac_cv_header_gmp_compat_h" = xyes +then : + +else $as_nop + as_fn_error $? "gmp_compat.h header not found" "$LINENO" 5 +fi + +CPPFLAGS="$SAVE_CPPFLAGS" + + if test x = xfalse; then + NEED_GET_MEMORY_FUNCTIONS_TRUE= + NEED_GET_MEMORY_FUNCTIONS_FALSE='#' +else + NEED_GET_MEMORY_FUNCTIONS_TRUE='#' + NEED_GET_MEMORY_FUNCTIONS_FALSE= +fi + + + ;; +esac +if test "x$with_int" = "ximath-32" -a "x$GCC" = "xyes"; then + MP_CFLAGS="-std=gnu99 $MP_CFLAGS" +fi + + if test x$with_int = ximath -o x$with_int = ximath-32; then + IMATH_FOR_MP_TRUE= + IMATH_FOR_MP_FALSE='#' +else + IMATH_FOR_MP_TRUE='#' + IMATH_FOR_MP_FALSE= +fi + + if test x$with_int = xgmp; then + GMP_FOR_MP_TRUE= + GMP_FOR_MP_FALSE='#' +else + GMP_FOR_MP_TRUE='#' + GMP_FOR_MP_FALSE= +fi + + + if test "x$HAVE_CXX11" = "x1"; then + HAVE_CXX11_TRUE= + HAVE_CXX11_FALSE='#' +else + HAVE_CXX11_TRUE='#' + HAVE_CXX11_FALSE= +fi + + if test "x$HAVE_CXX17" = "x1"; then + HAVE_CXX17_TRUE= + HAVE_CXX17_FALSE='#' +else + HAVE_CXX17_TRUE='#' + HAVE_CXX17_FALSE= +fi + + if test "x$with_int" = "ximath-32"; then + SMALL_INT_OPT_TRUE= + SMALL_INT_OPT_FALSE='#' +else + SMALL_INT_OPT_TRUE='#' + SMALL_INT_OPT_FALSE= +fi + +if test "x$with_int" = "ximath-32" +then : + + +printf "%s\n" "#define USE_SMALL_INT_OPT /**/" >>confdefs.h + + +fi + +ac_fn_check_decl "$LINENO" "ffs" "ac_cv_have_decl_ffs" "#include +" "$ac_c_undeclared_builtin_options" "CFLAGS" +if test "x$ac_cv_have_decl_ffs" = xyes +then : + ac_have_decl=1 +else $as_nop + ac_have_decl=0 +fi +printf "%s\n" "#define HAVE_DECL_FFS $ac_have_decl" >>confdefs.h + +ac_fn_check_decl "$LINENO" "__builtin_ffs" "ac_cv_have_decl___builtin_ffs" "$ac_includes_default" "$ac_c_undeclared_builtin_options" "CFLAGS" +if test "x$ac_cv_have_decl___builtin_ffs" = xyes +then : + ac_have_decl=1 +else $as_nop + ac_have_decl=0 +fi +printf "%s\n" "#define HAVE_DECL___BUILTIN_FFS $ac_have_decl" >>confdefs.h + +ac_fn_check_decl "$LINENO" "_BitScanForward" "ac_cv_have_decl__BitScanForward" "#include +" "$ac_c_undeclared_builtin_options" "CFLAGS" +if test "x$ac_cv_have_decl__BitScanForward" = xyes +then : + ac_have_decl=1 +else $as_nop + ac_have_decl=0 +fi +printf "%s\n" "#define HAVE_DECL__BITSCANFORWARD $ac_have_decl" >>confdefs.h + +if test "x$ac_cv_have_decl_ffs" = xno -a \ + "x$ac_cv_have_decl___builtin_ffs" = xno -a \ + "x$ac_cv_have_decl__BitScanForward" = xno; then + as_fn_error $? "No ffs implementation found" "$LINENO" 5 +fi +ac_fn_check_decl "$LINENO" "strcasecmp" "ac_cv_have_decl_strcasecmp" "#include +" "$ac_c_undeclared_builtin_options" "CFLAGS" +if test "x$ac_cv_have_decl_strcasecmp" = xyes +then : + ac_have_decl=1 +else $as_nop + ac_have_decl=0 +fi +printf "%s\n" "#define HAVE_DECL_STRCASECMP $ac_have_decl" >>confdefs.h +ac_fn_check_decl "$LINENO" "strncasecmp" "ac_cv_have_decl_strncasecmp" "#include +" "$ac_c_undeclared_builtin_options" "CFLAGS" +if test "x$ac_cv_have_decl_strncasecmp" = xyes +then : + ac_have_decl=1 +else $as_nop + ac_have_decl=0 +fi +printf "%s\n" "#define HAVE_DECL_STRNCASECMP $ac_have_decl" >>confdefs.h + +ac_fn_check_decl "$LINENO" "_stricmp" "ac_cv_have_decl__stricmp" "#include +" "$ac_c_undeclared_builtin_options" "CFLAGS" +if test "x$ac_cv_have_decl__stricmp" = xyes +then : + ac_have_decl=1 +else $as_nop + ac_have_decl=0 +fi +printf "%s\n" "#define HAVE_DECL__STRICMP $ac_have_decl" >>confdefs.h +ac_fn_check_decl "$LINENO" "_strnicmp" "ac_cv_have_decl__strnicmp" "#include +" "$ac_c_undeclared_builtin_options" "CFLAGS" +if test "x$ac_cv_have_decl__strnicmp" = xyes +then : + ac_have_decl=1 +else $as_nop + ac_have_decl=0 +fi +printf "%s\n" "#define HAVE_DECL__STRNICMP $ac_have_decl" >>confdefs.h + +if test "x$ac_cv_have_decl_strcasecmp" = xno -a \ + "x$ac_cv_have_decl__stricmp" = xno; then + as_fn_error $? "No strcasecmp implementation found" "$LINENO" 5 +fi +if test "x$ac_cv_have_decl_strncasecmp" = xno -a \ + "x$ac_cv_have_decl__strnicmp" = xno; then + as_fn_error $? "No strncasecmp implementation found" "$LINENO" 5 +fi +ac_fn_check_decl "$LINENO" "snprintf" "ac_cv_have_decl_snprintf" "#include +" "$ac_c_undeclared_builtin_options" "CFLAGS" +if test "x$ac_cv_have_decl_snprintf" = xyes +then : + ac_have_decl=1 +else $as_nop + ac_have_decl=0 +fi +printf "%s\n" "#define HAVE_DECL_SNPRINTF $ac_have_decl" >>confdefs.h +ac_fn_check_decl "$LINENO" "_snprintf" "ac_cv_have_decl__snprintf" "#include +" "$ac_c_undeclared_builtin_options" "CFLAGS" +if test "x$ac_cv_have_decl__snprintf" = xyes +then : + ac_have_decl=1 +else $as_nop + ac_have_decl=0 +fi +printf "%s\n" "#define HAVE_DECL__SNPRINTF $ac_have_decl" >>confdefs.h + +if test "x$ac_cv_have_decl_snprintf" = xno -a \ + "x$ac_cv_have_decl__snprintf" = xno; then + as_fn_error $? "No snprintf implementation found" "$LINENO" 5 +fi + + + + +# Check whether --with-clang was given. +if test ${with_clang+y} +then : + withval=$with_clang; +fi + +case "system" in +system|no) + +# Check whether --with-clang_prefix was given. +if test ${with_clang_prefix+y} +then : + withval=$with_clang_prefix; +fi + + +# Check whether --with-clang_exec_prefix was given. +if test ${with_clang_exec_prefix+y} +then : + withval=$with_clang_exec_prefix; +fi + +esac + +if test "x$with_clang_prefix" != "x" -a "x$with_clang_exec_prefix" = "x"; then + with_clang_exec_prefix=$with_clang_prefix +fi +if test "x$with_clang_prefix" != "x" -o "x$with_clang_exec_prefix" != "x"; then + if test "x$with_clang" != "x" -a "x$with_clang" != "xyes" -a "x$with_clang" != "xsystem"; then + as_fn_error $? "Setting $with_clang_prefix implies use of system clang" "$LINENO" 5 + fi + with_clang="system" +fi +if test "x$with_clang_builddir" != "x"; then + if test "x$with_clang" != "x" -a "x$with_clang" != "xyes" -a "x$with_clang" != "xbuild"; then + as_fn_error $? "Setting $with_clang_builddir implies use of build clang" "$LINENO" 5 + fi + with_clang="build" + clang_srcdir=`echo @abs_srcdir@ | $with_clang_builddir/config.status --file=-` + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: clang sources in $clang_srcdir" >&5 +printf "%s\n" "$as_me: clang sources in $clang_srcdir" >&6;} +fi +if test "x$with_clang_exec_prefix" != "x"; then + export PKG_CONFIG_PATH="$with_clang_exec_prefix/lib/pkgconfig${PKG_CONFIG_PATH+:$PKG_CONFIG_PATH}" +fi +case "$with_clang" in +system|no) + ;; +*) + case "no" in + bundled) + if test -d $srcdir/.git -a \ + -d $srcdir/clang -a \ + ! -d $srcdir/clang/.git; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: git repo detected, but submodule clang not initialized" >&5 +printf "%s\n" "$as_me: WARNING: git repo detected, but submodule clang not initialized" >&2;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: You may want to run" >&5 +printf "%s\n" "$as_me: WARNING: You may want to run" >&2;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: git submodule init" >&5 +printf "%s\n" "$as_me: WARNING: git submodule init" >&2;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: git submodule update" >&5 +printf "%s\n" "$as_me: WARNING: git submodule update" >&2;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: sh autogen.sh" >&5 +printf "%s\n" "$as_me: WARNING: sh autogen.sh" >&2;} + fi + if test -f $srcdir/clang/configure; then + with_clang="bundled" + else + with_clang="no" + fi + ;; + *) + with_clang="no" + ;; + esac + ;; +esac +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking which clang to use" >&5 +printf %s "checking which clang to use... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $with_clang" >&5 +printf "%s\n" "$with_clang" >&6; } + + + if test $with_clang = system; then + HAVE_CLANG_TRUE= + HAVE_CLANG_FALSE='#' +else + HAVE_CLANG_TRUE='#' + HAVE_CLANG_FALSE= +fi + + if (test $with_clang = system -a "x$HAVE_CXX11" = "x1") || \ + test -f $srcdir/include/isl/cpp.h; then + HAVE_CPP_ISL_H_TRUE= + HAVE_CPP_ISL_H_FALSE='#' +else + HAVE_CPP_ISL_H_TRUE='#' + HAVE_CPP_ISL_H_FALSE= +fi + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C compiler vendor" >&5 +printf %s "checking for C compiler vendor... " >&6; } +if test ${ax_cv_c_compiler_vendor+y} +then : + printf %s "(cached) " >&6 +else $as_nop + + vendors=" + intel: __ICC,__ECC,__INTEL_COMPILER + ibm: __xlc__,__xlC__,__IBMC__,__IBMCPP__,__ibmxl__ + pathscale: __PATHCC__,__PATHSCALE__ + clang: __clang__ + cray: _CRAYC + fujitsu: __FUJITSU + sdcc: SDCC,__SDCC + sx: _SX + nvhpc: __NVCOMPILER + portland: __PGI + pcc: __PCC__ + gnu: __GNUC__ + sun: __SUNPRO_C,__SUNPRO_CC,__SUNPRO_F90,__SUNPRO_F95 + hp: __HP_cc,__HP_aCC + dec: __DECC,__DECCXX,__DECC_VER,__DECCXX_VER + borland: __BORLANDC__,__CODEGEARC__,__TURBOC__ + comeau: __COMO__ + kai: __KCC + lcc: __LCC__ + sgi: __sgi,sgi + microsoft: _MSC_VER + metrowerks: __MWERKS__ + watcom: __WATCOMC__ + tcc: __TINYC__ + unknown: UNKNOWN + " + for ventest in $vendors; do + case $ventest in + *:) + vendor=$ventest + continue + ;; + *) + vencpp="defined("`echo $ventest | sed 's/,/) || defined(/g'`")" + ;; + esac + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + +#if !($vencpp) + thisisanerror; +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + break +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + done + + ax_cv_c_compiler_vendor=`echo $vendor | cut -d: -f1` + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_c_compiler_vendor" >&5 +printf "%s\n" "$ax_cv_c_compiler_vendor" >&6; } + + + WARNING_FLAGS="" + + if test "${ax_cv_c_compiler_vendor}" = "clang"; then + WARNING_FLAGS="-Wall" + fi + + + + +PACKAGE_CFLAGS="$MP_CPPFLAGS" +PACKAGE_LDFLAGS="$MP_LDFLAGS" +PACKAGE_LIBS="-lisl $MP_LIBS" + +# we need the expanded forms... +test "x$prefix" = xNONE && prefix=$ac_default_prefix +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking our pkgconfig libname" >&5 +printf %s "checking our pkgconfig libname... " >&6; } +test ".$ax_create_pkgconfig_libname" != "." || \ +ax_create_pkgconfig_libname="${PACKAGE_NAME}" +test ".$ax_create_pkgconfig_libname" != "." || \ +ax_create_pkgconfig_libname="$PACKAGE" +ax_create_pkgconfig_libname=`eval echo "$ax_create_pkgconfig_libname"` +ax_create_pkgconfig_libname=`eval echo "$ax_create_pkgconfig_libname"` +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_create_pkgconfig_libname" >&5 +printf "%s\n" "$ax_create_pkgconfig_libname" >&6; } + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking our pkgconfig version" >&5 +printf %s "checking our pkgconfig version... " >&6; } +test ".$ax_create_pkgconfig_version" != "." || \ +ax_create_pkgconfig_version="${PACKAGE_VERSION}" +test ".$ax_create_pkgconfig_version" != "." || \ +ax_create_pkgconfig_version="$VERSION" +ax_create_pkgconfig_version=`eval echo "$ax_create_pkgconfig_version"` +ax_create_pkgconfig_version=`eval echo "$ax_create_pkgconfig_version"` +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_create_pkgconfig_version" >&5 +printf "%s\n" "$ax_create_pkgconfig_version" >&6; } + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking our pkgconfig_libdir" >&5 +printf %s "checking our pkgconfig_libdir... " >&6; } +test ".$pkgconfig_libdir" = "." && \ +pkgconfig_libdir='${libdir}/pkgconfig' +ax_create_pkgconfig_libdir=`eval echo "$pkgconfig_libdir"` +ax_create_pkgconfig_libdir=`eval echo "$ax_create_pkgconfig_libdir"` +ax_create_pkgconfig_libdir=`eval echo "$ax_create_pkgconfig_libdir"` +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $pkgconfig_libdir" >&5 +printf "%s\n" "$pkgconfig_libdir" >&6; } +test "$pkgconfig_libdir" != "$ax_create_pkgconfig_libdir" && ( +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: expanded our pkgconfig_libdir... $ax_create_pkgconfig_libdir" >&5 +printf "%s\n" "expanded our pkgconfig_libdir... $ax_create_pkgconfig_libdir" >&6; }) + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking our pkgconfig_libfile" >&5 +printf %s "checking our pkgconfig_libfile... " >&6; } +test ".$pkgconfig_libfile" != "." || \ +pkgconfig_libfile="$ax_create_pkgconfig_libname.pc" +ax_create_pkgconfig_libfile=`eval echo "$pkgconfig_libfile"` +ax_create_pkgconfig_libfile=`eval echo "$ax_create_pkgconfig_libfile"` +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $pkgconfig_libfile" >&5 +printf "%s\n" "$pkgconfig_libfile" >&6; } +test "$pkgconfig_libfile" != "$ax_create_pkgconfig_libfile" && ( +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: expanded our pkgconfig_libfile... $ax_create_pkgconfig_libfile" >&5 +printf "%s\n" "expanded our pkgconfig_libfile... $ax_create_pkgconfig_libfile" >&6; }) + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking our package / suffix" >&5 +printf %s "checking our package / suffix... " >&6; } +ax_create_pkgconfig_suffix="$program_suffix" +test ".$ax_create_pkgconfig_suffix" != .NONE || ax_create_pkgconfig_suffix="" +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: ${PACKAGE_NAME} / ${ax_create_pkgconfig_suffix}" >&5 +printf "%s\n" "${PACKAGE_NAME} / ${ax_create_pkgconfig_suffix}" >&6; } + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking our pkgconfig description" >&5 +printf %s "checking our pkgconfig description... " >&6; } +ax_create_pkgconfig_description="$PACKAGE_SUMMARY" +test ".$ax_create_pkgconfig_description" != "." || \ +ax_create_pkgconfig_description="$ax_create_pkgconfig_libname Library" +ax_create_pkgconfig_description=`eval echo "$ax_create_pkgconfig_description"` +ax_create_pkgconfig_description=`eval echo "$ax_create_pkgconfig_description"` +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_create_pkgconfig_description" >&5 +printf "%s\n" "$ax_create_pkgconfig_description" >&6; } + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking our pkgconfig requires" >&5 +printf %s "checking our pkgconfig requires... " >&6; } +ax_create_pkgconfig_requires="$PACKAGE_REQUIRES" +ax_create_pkgconfig_requires=`eval echo "$ax_create_pkgconfig_requires"` +ax_create_pkgconfig_requires=`eval echo "$ax_create_pkgconfig_requires"` +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_create_pkgconfig_requires" >&5 +printf "%s\n" "$ax_create_pkgconfig_requires" >&6; } + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking our pkgconfig ext libs" >&5 +printf %s "checking our pkgconfig ext libs... " >&6; } +ax_create_pkgconfig_pkglibs="$PACKAGE_LIBS" +test ".$ax_create_pkgconfig_pkglibs" != "." || ax_create_pkgconfig_pkglibs="-l$ax_create_pkgconfig_libname" +ax_create_pkgconfig_libs="$ax_create_pkgconfig_pkglibs $LIBS" +ax_create_pkgconfig_libs=`eval echo "$ax_create_pkgconfig_libs"` +ax_create_pkgconfig_libs=`eval echo "$ax_create_pkgconfig_libs"` +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_create_pkgconfig_libs" >&5 +printf "%s\n" "$ax_create_pkgconfig_libs" >&6; } + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking our pkgconfig cppflags" >&5 +printf %s "checking our pkgconfig cppflags... " >&6; } +ax_create_pkgconfig_cppflags="$PACKAGE_CFLAGS" +ax_create_pkgconfig_cppflags=`eval echo "$ax_create_pkgconfig_cppflags"` +ax_create_pkgconfig_cppflags=`eval echo "$ax_create_pkgconfig_cppflags"` +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_create_pkgconfig_cppflags" >&5 +printf "%s\n" "$ax_create_pkgconfig_cppflags" >&6; } + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking our pkgconfig ldflags" >&5 +printf %s "checking our pkgconfig ldflags... " >&6; } +ax_create_pkgconfig_ldflags="$PACKAGE_LDFLAGS" +ax_create_pkgconfig_ldflags=`eval echo "$ax_create_pkgconfig_ldflags"` +ax_create_pkgconfig_ldflags=`eval echo "$ax_create_pkgconfig_ldflags"` +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_create_pkgconfig_ldflags" >&5 +printf "%s\n" "$ax_create_pkgconfig_ldflags" >&6; } + +test ".$ax_create_pkgconfig_generate" != "." || \ +ax_create_pkgconfig_generate="$ax_create_pkgconfig_libname.pc" +ax_create_pkgconfig_generate=`eval echo "$ax_create_pkgconfig_generate"` +ax_create_pkgconfig_generate=`eval echo "$ax_create_pkgconfig_generate"` +test "$pkgconfig_libfile" != "$ax_create_pkgconfig_generate" && ( +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: generate the pkgconfig later... $ax_create_pkgconfig_generate" >&5 +printf "%s\n" "generate the pkgconfig later... $ax_create_pkgconfig_generate" >&6; }) + +if test ".$ax_create_pkgconfig_src_libdir" = "." ; then +ax_create_pkgconfig_src_libdir=`pwd` +ax_create_pkgconfig_src_libdir=`$as_dirname -- "$ax_create_pkgconfig_src_libdir/$ax_create_pkgconfig_generate" || +$as_expr X"$ax_create_pkgconfig_src_libdir/$ax_create_pkgconfig_generate" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ax_create_pkgconfig_src_libdir/$ax_create_pkgconfig_generate" : 'X\(//\)[^/]' \| \ + X"$ax_create_pkgconfig_src_libdir/$ax_create_pkgconfig_generate" : 'X\(//\)$' \| \ + X"$ax_create_pkgconfig_src_libdir/$ax_create_pkgconfig_generate" : 'X\(/\)' \| . 2>/dev/null || +printf "%s\n" X"$ax_create_pkgconfig_src_libdir/$ax_create_pkgconfig_generate" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` +test ! -d $ax_create_pkgconfig_src_libdir/src || \ +ax_create_pkgconfig_src_libdir="$ax_create_pkgconfig_src_libdir/src" +case ".$objdir" in +*libs) ax_create_pkgconfig_src_libdir="$ax_create_pkgconfig_src_libdir/$objdir" ;; esac +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: noninstalled pkgconfig -L $ax_create_pkgconfig_src_libdir" >&5 +printf "%s\n" "noninstalled pkgconfig -L $ax_create_pkgconfig_src_libdir" >&6; } +fi + +if test ".$ax_create_pkgconfig_src_headers" = "." ; then +ax_create_pkgconfig_src_headers=`pwd` +v="$ac_top_srcdir" ; +test ".$v" != "." || v="$ax_spec_dir" +test ".$v" != "." || v="$srcdir" +case "$v" in /*) ax_create_pkgconfig_src_headers="" ;; esac +ax_create_pkgconfig_src_headers=`$as_dirname -- "$ax_create_pkgconfig_src_headers/$v/x" || +$as_expr X"$ax_create_pkgconfig_src_headers/$v/x" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ax_create_pkgconfig_src_headers/$v/x" : 'X\(//\)[^/]' \| \ + X"$ax_create_pkgconfig_src_headers/$v/x" : 'X\(//\)$' \| \ + X"$ax_create_pkgconfig_src_headers/$v/x" : 'X\(/\)' \| . 2>/dev/null || +printf "%s\n" X"$ax_create_pkgconfig_src_headers/$v/x" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` +test ! -d $ax_create_pkgconfig_src_headers/include || \ +ax_create_pkgconfig_src_headers="$ax_create_pkgconfig_src_headers/include" +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: noninstalled pkgconfig -I $ax_create_pkgconfig_src_headers" >&5 +printf "%s\n" "noninstalled pkgconfig -I $ax_create_pkgconfig_src_headers" >&6; } +fi + + +ac_config_commands="$ac_config_commands $ax_create_pkgconfig_generate" + + + + + + + if test -f $srcdir/.git; then + gitdir=`GIT_DIR=$srcdir/.git git rev-parse --git-dir` + GIT_HEAD="$gitdir/index" + GIT_REPO="$gitdir" + GIT_HEAD_ID=`GIT_DIR=$GIT_REPO git describe --always` + elif test -f $srcdir/.git/HEAD; then + GIT_HEAD="$srcdir/.git/index" + GIT_REPO="$srcdir/.git" + GIT_HEAD_ID=`GIT_DIR=$GIT_REPO git describe --always` + elif test -f $srcdir/GIT_HEAD_ID; then + GIT_HEAD_ID=`cat $srcdir/GIT_HEAD_ID` + else + mysrcdir=`(cd $srcdir; pwd)` + head=`basename $mysrcdir | sed -e 's/.*-//'` + head2=`echo $head | sed -e 's/^0-9a-f//'` + head3=`echo $head2 | sed -e 's/........................................//'` + if test "x$head3" = "x" -a "x$head" = "x$head2"; then + GIT_HEAD_ID="$head" + else + GIT_HEAD_ID="UNKNOWN" + fi + fi + if test -z "$GIT_REPO" ; then + GIT_HEAD_VERSION="$GIT_HEAD_ID" + else + GIT_HEAD_VERSION="\`GIT_DIR=$GIT_REPO git describe --always\`" + fi + + + +ac_config_headers="$ac_config_headers isl_config.h" + +ac_config_files="$ac_config_files isl_srcdir.c" + +ac_config_files="$ac_config_files Makefile" + +ac_config_files="$ac_config_files doc/Makefile" + +if test $with_clang = system; then + + +subdirs="$subdirs interface" + +fi +ac_config_files="$ac_config_files bound_test.sh" + +ac_config_files="$ac_config_files codegen_test.sh" + +ac_config_files="$ac_config_files pip_test.sh" + +ac_config_files="$ac_config_files flow_test.sh" + +ac_config_files="$ac_config_files schedule_test.sh" + +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, we kill variables containing newlines. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +( + for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +printf "%s\n" "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + + (set) 2>&1 | + case $as_nl`(ac_space=' '; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + # `set' does not quote correctly, so add quotes: double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \. + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; #( + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) | + sed ' + /^ac_cv_env_/b end + t clear + :clear + s/^\([^=]*\)=\(.*[{}].*\)$/test ${\1+y} || &/ + t end + s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + :end' >>confcache +if diff "$cache_file" confcache >/dev/null 2>&1; then :; else + if test -w "$cache_file"; then + if test "x$cache_file" != "x/dev/null"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 +printf "%s\n" "$as_me: updating cache $cache_file" >&6;} + if test ! -f "$cache_file" || test -h "$cache_file"; then + cat confcache >"$cache_file" + else + case $cache_file in #( + */* | ?:*) + mv -f confcache "$cache_file"$$ && + mv -f "$cache_file"$$ "$cache_file" ;; #( + *) + mv -f confcache "$cache_file" ;; + esac + fi + fi + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 +printf "%s\n" "$as_me: not updating unwritable cache $cache_file" >&6;} + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +DEFS=-DHAVE_CONFIG_H + +ac_libobjs= +ac_ltlibobjs= +U= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' + ac_i=`printf "%s\n" "$ac_i" | sed "$ac_script"` + # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR + # will be set to the directory where LIBOBJS objects are built. + as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" + as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5 +printf %s "checking that generated files are newer than configure... " >&6; } + if test -n "$am_sleep_pid"; then + # Hide warnings about reused PIDs. + wait $am_sleep_pid 2>/dev/null + fi + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: done" >&5 +printf "%s\n" "done" >&6; } + if test -n "$EXEEXT"; then + am__EXEEXT_TRUE= + am__EXEEXT_FALSE='#' +else + am__EXEEXT_TRUE='#' + am__EXEEXT_FALSE= +fi + +if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then + as_fn_error $? "conditional \"AMDEP\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then + as_fn_error $? "conditional \"am__fastdepCC\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then + as_fn_error $? "conditional \"am__fastdepCXX\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then + as_fn_error $? "conditional \"am__fastdepCC\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${HAVE_PYTHON_TRUE}" && test -z "${HAVE_PYTHON_FALSE}"; then + as_fn_error $? "conditional \"HAVE_PYTHON\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${GENERATE_DOC_TRUE}" && test -z "${GENERATE_DOC_FALSE}"; then + as_fn_error $? "conditional \"GENERATE_DOC\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${NEED_GET_MEMORY_FUNCTIONS_TRUE}" && test -z "${NEED_GET_MEMORY_FUNCTIONS_FALSE}"; then + as_fn_error $? "conditional \"NEED_GET_MEMORY_FUNCTIONS\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${NEED_GET_MEMORY_FUNCTIONS_TRUE}" && test -z "${NEED_GET_MEMORY_FUNCTIONS_FALSE}"; then + as_fn_error $? "conditional \"NEED_GET_MEMORY_FUNCTIONS\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${IMATH_FOR_MP_TRUE}" && test -z "${IMATH_FOR_MP_FALSE}"; then + as_fn_error $? "conditional \"IMATH_FOR_MP\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${GMP_FOR_MP_TRUE}" && test -z "${GMP_FOR_MP_FALSE}"; then + as_fn_error $? "conditional \"GMP_FOR_MP\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${HAVE_CXX11_TRUE}" && test -z "${HAVE_CXX11_FALSE}"; then + as_fn_error $? "conditional \"HAVE_CXX11\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${HAVE_CXX17_TRUE}" && test -z "${HAVE_CXX17_FALSE}"; then + as_fn_error $? "conditional \"HAVE_CXX17\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${SMALL_INT_OPT_TRUE}" && test -z "${SMALL_INT_OPT_FALSE}"; then + as_fn_error $? "conditional \"SMALL_INT_OPT\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${HAVE_CLANG_TRUE}" && test -z "${HAVE_CLANG_FALSE}"; then + as_fn_error $? "conditional \"HAVE_CLANG\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${HAVE_CPP_ISL_H_TRUE}" && test -z "${HAVE_CPP_ISL_H_FALSE}"; then + as_fn_error $? "conditional \"HAVE_CPP_ISL_H\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi + +: "${CONFIG_STATUS=./config.status}" +ac_write_fail=0 +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 +printf "%s\n" "$as_me: creating $CONFIG_STATUS" >&6;} +as_write_fail=0 +cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false + +SHELL=\${CONFIG_SHELL-$SHELL} +export SHELL +_ASEOF +cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +as_nop=: +if test ${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1 +then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else $as_nop + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + + +# Reset variables that may have inherited troublesome values from +# the environment. + +# IFS needs to be set, to space, tab, and newline, in precisely that order. +# (If _AS_PATH_WALK were called with IFS unset, it would have the +# side effect of setting IFS to empty, thus disabling word splitting.) +# Quoting is to prevent editors from complaining about space-tab. +as_nl=' +' +export as_nl +IFS=" "" $as_nl" + +PS1='$ ' +PS2='> ' +PS4='+ ' + +# Ensure predictable behavior from utilities with locale-dependent output. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# We cannot yet rely on "unset" to work, but we need these variables +# to be unset--not just set to an empty or harmless value--now, to +# avoid bugs in old shells (e.g. pre-3.0 UWIN ksh). This construct +# also avoids known problems related to "unset" and subshell syntax +# in other old shells (e.g. bash 2.01 and pdksh 5.2.14). +for as_var in BASH_ENV ENV MAIL MAILPATH CDPATH +do eval test \${$as_var+y} \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done + +# Ensure that fds 0, 1, and 2 are open. +if (exec 3>&0) 2>/dev/null; then :; else exec 0&1) 2>/dev/null; then :; else exec 1>/dev/null; fi +if (exec 3>&2) ; then :; else exec 2>/dev/null; fi + +# The user is always right. +if ${PATH_SEPARATOR+false} :; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + test -r "$as_dir$0" && as_myself=$as_dir$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + printf "%s\n" "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + printf "%s\n" "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + + + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset + +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null +then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else $as_nop + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null +then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else $as_nop + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +printf "%s\n" X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + + +# Determine whether it's possible to make 'echo' print without a newline. +# These variables are no longer used directly by Autoconf, but are AC_SUBSTed +# for compatibility with existing Makefiles. +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +# For backward compatibility with old third-party macros, we provide +# the shell variables $as_echo and $as_echo_n. New code should use +# AS_ECHO(["message"]) and AS_ECHO_N(["message"]), respectively. +as_echo='printf %s\n' +as_echo_n='printf %s' + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -pR'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -pR' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -pR' + fi +else + as_ln_s='cp -pR' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`printf "%s\n" "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +printf "%s\n" X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +as_test_x='test -x' +as_executable_p=as_fn_executable_p + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +exec 6>&1 +## ----------------------------------- ## +## Main body of $CONFIG_STATUS script. ## +## ----------------------------------- ## +_ASEOF +test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# Save the log message, to keep $0 and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. +ac_log=" +This file was extended by isl $as_me 0.26, which was +generated by GNU Autoconf 2.71. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + +_ACEOF + +case $ac_config_files in *" +"*) set x $ac_config_files; shift; ac_config_files=$*;; +esac + +case $ac_config_headers in *" +"*) set x $ac_config_headers; shift; ac_config_headers=$*;; +esac + + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# Files that config.status was made for. +config_files="$ac_config_files" +config_headers="$ac_config_headers" +config_commands="$ac_config_commands" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +ac_cs_usage="\ +\`$as_me' instantiates files and other configuration actions +from templates according to the current configuration. Unless the files +and actions are specified as TAGs, all are instantiated by default. + +Usage: $0 [OPTION]... [TAG]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit + --config print configuration, then exit + -q, --quiet, --silent + do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE + +Configuration files: +$config_files + +Configuration headers: +$config_headers + +Configuration commands: +$config_commands + +Report bugs to ." + +_ACEOF +ac_cs_config=`printf "%s\n" "$ac_configure_args" | sed "$ac_safe_unquote"` +ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\''/g"` +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_cs_config='$ac_cs_config_escaped' +ac_cs_version="\\ +isl config.status 0.26 +configured by $0, generated by GNU Autoconf 2.71, + with options \\"\$ac_cs_config\\" + +Copyright (C) 2021 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." + +ac_pwd='$ac_pwd' +srcdir='$srcdir' +INSTALL='$INSTALL' +MKDIR_P='$MKDIR_P' +AWK='$AWK' +test -n "\$AWK" || AWK=awk +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# The default lists apply if the user does not specify any file. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=?*) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` + ac_shift=: + ;; + --*=) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg= + ac_shift=: + ;; + *) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + printf "%s\n" "$ac_cs_version"; exit ;; + --config | --confi | --conf | --con | --co | --c ) + printf "%s\n" "$ac_cs_config"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`printf "%s\n" "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + '') as_fn_error $? "missing file argument" ;; + esac + as_fn_append CONFIG_FILES " '$ac_optarg'" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`printf "%s\n" "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + as_fn_append CONFIG_HEADERS " '$ac_optarg'" + ac_need_defaults=false;; + --he | --h) + # Conflict between --help and --header + as_fn_error $? "ambiguous option: \`$1' +Try \`$0 --help' for more information.";; + --help | --hel | -h ) + printf "%s\n" "$ac_cs_usage"; exit ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) as_fn_error $? "unrecognized option: \`$1' +Try \`$0 --help' for more information." ;; + + *) as_fn_append ac_config_targets " $1" + ac_need_defaults=false ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +if \$ac_cs_recheck; then + set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion + shift + \printf "%s\n" "running CONFIG_SHELL=$SHELL \$*" >&6 + CONFIG_SHELL='$SHELL' + export CONFIG_SHELL + exec "\$@" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + printf "%s\n" "$ac_log" +} >&5 + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# +# INIT-COMMANDS +# +AMDEP_TRUE="$AMDEP_TRUE" MAKE="${MAKE-make}" + + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +sed_quote_subst='$sed_quote_subst' +double_quote_subst='$double_quote_subst' +delay_variable_subst='$delay_variable_subst' +macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`' +macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`' +enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`' +enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`' +pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`' +enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`' +shared_archive_member_spec='`$ECHO "$shared_archive_member_spec" | $SED "$delay_single_quote_subst"`' +SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`' +ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`' +PATH_SEPARATOR='`$ECHO "$PATH_SEPARATOR" | $SED "$delay_single_quote_subst"`' +host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`' +host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`' +host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`' +build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`' +build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`' +build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`' +SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`' +Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`' +GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`' +EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`' +FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`' +LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`' +NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`' +LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`' +max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`' +ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`' +exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`' +lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`' +lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`' +lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`' +lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`' +lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`' +reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`' +reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`' +OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`' +deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`' +file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`' +file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`' +want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`' +DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`' +sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`' +AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`' +AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`' +archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`' +STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`' +RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`' +old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`' +old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`' +old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`' +lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`' +CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`' +CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`' +compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`' +GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_import='`$ECHO "$lt_cv_sys_global_symbol_to_import" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`' +lt_cv_nm_interface='`$ECHO "$lt_cv_nm_interface" | $SED "$delay_single_quote_subst"`' +nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`' +lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`' +lt_cv_truncate_bin='`$ECHO "$lt_cv_truncate_bin" | $SED "$delay_single_quote_subst"`' +objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`' +MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`' +lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`' +need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`' +MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`' +DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`' +NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`' +LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`' +OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`' +OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`' +libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`' +shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`' +extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`' +archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`' +enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`' +export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`' +whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`' +compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`' +old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`' +old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`' +archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`' +archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`' +module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`' +module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`' +with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`' +allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`' +no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`' +hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`' +hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`' +hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`' +hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`' +hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`' +inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`' +link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`' +always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`' +export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`' +exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`' +include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`' +prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`' +postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`' +file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`' +variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`' +need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`' +need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`' +version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`' +runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`' +shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`' +shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`' +libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`' +library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`' +soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`' +install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`' +postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`' +postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`' +finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`' +finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`' +hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`' +sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`' +configure_time_dlsearch_path='`$ECHO "$configure_time_dlsearch_path" | $SED "$delay_single_quote_subst"`' +configure_time_lt_sys_library_path='`$ECHO "$configure_time_lt_sys_library_path" | $SED "$delay_single_quote_subst"`' +hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`' +enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`' +enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`' +enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`' +old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`' +striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`' +compiler_lib_search_dirs='`$ECHO "$compiler_lib_search_dirs" | $SED "$delay_single_quote_subst"`' +predep_objects='`$ECHO "$predep_objects" | $SED "$delay_single_quote_subst"`' +postdep_objects='`$ECHO "$postdep_objects" | $SED "$delay_single_quote_subst"`' +predeps='`$ECHO "$predeps" | $SED "$delay_single_quote_subst"`' +postdeps='`$ECHO "$postdeps" | $SED "$delay_single_quote_subst"`' +compiler_lib_search_path='`$ECHO "$compiler_lib_search_path" | $SED "$delay_single_quote_subst"`' +LD_CXX='`$ECHO "$LD_CXX" | $SED "$delay_single_quote_subst"`' +reload_flag_CXX='`$ECHO "$reload_flag_CXX" | $SED "$delay_single_quote_subst"`' +reload_cmds_CXX='`$ECHO "$reload_cmds_CXX" | $SED "$delay_single_quote_subst"`' +old_archive_cmds_CXX='`$ECHO "$old_archive_cmds_CXX" | $SED "$delay_single_quote_subst"`' +compiler_CXX='`$ECHO "$compiler_CXX" | $SED "$delay_single_quote_subst"`' +GCC_CXX='`$ECHO "$GCC_CXX" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_no_builtin_flag_CXX='`$ECHO "$lt_prog_compiler_no_builtin_flag_CXX" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_pic_CXX='`$ECHO "$lt_prog_compiler_pic_CXX" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_wl_CXX='`$ECHO "$lt_prog_compiler_wl_CXX" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_static_CXX='`$ECHO "$lt_prog_compiler_static_CXX" | $SED "$delay_single_quote_subst"`' +lt_cv_prog_compiler_c_o_CXX='`$ECHO "$lt_cv_prog_compiler_c_o_CXX" | $SED "$delay_single_quote_subst"`' +archive_cmds_need_lc_CXX='`$ECHO "$archive_cmds_need_lc_CXX" | $SED "$delay_single_quote_subst"`' +enable_shared_with_static_runtimes_CXX='`$ECHO "$enable_shared_with_static_runtimes_CXX" | $SED "$delay_single_quote_subst"`' +export_dynamic_flag_spec_CXX='`$ECHO "$export_dynamic_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' +whole_archive_flag_spec_CXX='`$ECHO "$whole_archive_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' +compiler_needs_object_CXX='`$ECHO "$compiler_needs_object_CXX" | $SED "$delay_single_quote_subst"`' +old_archive_from_new_cmds_CXX='`$ECHO "$old_archive_from_new_cmds_CXX" | $SED "$delay_single_quote_subst"`' +old_archive_from_expsyms_cmds_CXX='`$ECHO "$old_archive_from_expsyms_cmds_CXX" | $SED "$delay_single_quote_subst"`' +archive_cmds_CXX='`$ECHO "$archive_cmds_CXX" | $SED "$delay_single_quote_subst"`' +archive_expsym_cmds_CXX='`$ECHO "$archive_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`' +module_cmds_CXX='`$ECHO "$module_cmds_CXX" | $SED "$delay_single_quote_subst"`' +module_expsym_cmds_CXX='`$ECHO "$module_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`' +with_gnu_ld_CXX='`$ECHO "$with_gnu_ld_CXX" | $SED "$delay_single_quote_subst"`' +allow_undefined_flag_CXX='`$ECHO "$allow_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`' +no_undefined_flag_CXX='`$ECHO "$no_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_flag_spec_CXX='`$ECHO "$hardcode_libdir_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_separator_CXX='`$ECHO "$hardcode_libdir_separator_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_direct_CXX='`$ECHO "$hardcode_direct_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_direct_absolute_CXX='`$ECHO "$hardcode_direct_absolute_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_minus_L_CXX='`$ECHO "$hardcode_minus_L_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_shlibpath_var_CXX='`$ECHO "$hardcode_shlibpath_var_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_automatic_CXX='`$ECHO "$hardcode_automatic_CXX" | $SED "$delay_single_quote_subst"`' +inherit_rpath_CXX='`$ECHO "$inherit_rpath_CXX" | $SED "$delay_single_quote_subst"`' +link_all_deplibs_CXX='`$ECHO "$link_all_deplibs_CXX" | $SED "$delay_single_quote_subst"`' +always_export_symbols_CXX='`$ECHO "$always_export_symbols_CXX" | $SED "$delay_single_quote_subst"`' +export_symbols_cmds_CXX='`$ECHO "$export_symbols_cmds_CXX" | $SED "$delay_single_quote_subst"`' +exclude_expsyms_CXX='`$ECHO "$exclude_expsyms_CXX" | $SED "$delay_single_quote_subst"`' +include_expsyms_CXX='`$ECHO "$include_expsyms_CXX" | $SED "$delay_single_quote_subst"`' +prelink_cmds_CXX='`$ECHO "$prelink_cmds_CXX" | $SED "$delay_single_quote_subst"`' +postlink_cmds_CXX='`$ECHO "$postlink_cmds_CXX" | $SED "$delay_single_quote_subst"`' +file_list_spec_CXX='`$ECHO "$file_list_spec_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_action_CXX='`$ECHO "$hardcode_action_CXX" | $SED "$delay_single_quote_subst"`' +compiler_lib_search_dirs_CXX='`$ECHO "$compiler_lib_search_dirs_CXX" | $SED "$delay_single_quote_subst"`' +predep_objects_CXX='`$ECHO "$predep_objects_CXX" | $SED "$delay_single_quote_subst"`' +postdep_objects_CXX='`$ECHO "$postdep_objects_CXX" | $SED "$delay_single_quote_subst"`' +predeps_CXX='`$ECHO "$predeps_CXX" | $SED "$delay_single_quote_subst"`' +postdeps_CXX='`$ECHO "$postdeps_CXX" | $SED "$delay_single_quote_subst"`' +compiler_lib_search_path_CXX='`$ECHO "$compiler_lib_search_path_CXX" | $SED "$delay_single_quote_subst"`' + +LTCC='$LTCC' +LTCFLAGS='$LTCFLAGS' +compiler='$compiler_DEFAULT' + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +\$1 +_LTECHO_EOF' +} + +# Quote evaled strings. +for var in SHELL \ +ECHO \ +PATH_SEPARATOR \ +SED \ +GREP \ +EGREP \ +FGREP \ +LD \ +NM \ +LN_S \ +lt_SP2NL \ +lt_NL2SP \ +reload_flag \ +OBJDUMP \ +deplibs_check_method \ +file_magic_cmd \ +file_magic_glob \ +want_nocaseglob \ +DLLTOOL \ +sharedlib_from_linklib_cmd \ +AR \ +AR_FLAGS \ +archiver_list_spec \ +STRIP \ +RANLIB \ +CC \ +CFLAGS \ +compiler \ +lt_cv_sys_global_symbol_pipe \ +lt_cv_sys_global_symbol_to_cdecl \ +lt_cv_sys_global_symbol_to_import \ +lt_cv_sys_global_symbol_to_c_name_address \ +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \ +lt_cv_nm_interface \ +nm_file_list_spec \ +lt_cv_truncate_bin \ +lt_prog_compiler_no_builtin_flag \ +lt_prog_compiler_pic \ +lt_prog_compiler_wl \ +lt_prog_compiler_static \ +lt_cv_prog_compiler_c_o \ +need_locks \ +MANIFEST_TOOL \ +DSYMUTIL \ +NMEDIT \ +LIPO \ +OTOOL \ +OTOOL64 \ +shrext_cmds \ +export_dynamic_flag_spec \ +whole_archive_flag_spec \ +compiler_needs_object \ +with_gnu_ld \ +allow_undefined_flag \ +no_undefined_flag \ +hardcode_libdir_flag_spec \ +hardcode_libdir_separator \ +exclude_expsyms \ +include_expsyms \ +file_list_spec \ +variables_saved_for_relink \ +libname_spec \ +library_names_spec \ +soname_spec \ +install_override_mode \ +finish_eval \ +old_striplib \ +striplib \ +compiler_lib_search_dirs \ +predep_objects \ +postdep_objects \ +predeps \ +postdeps \ +compiler_lib_search_path \ +LD_CXX \ +reload_flag_CXX \ +compiler_CXX \ +lt_prog_compiler_no_builtin_flag_CXX \ +lt_prog_compiler_pic_CXX \ +lt_prog_compiler_wl_CXX \ +lt_prog_compiler_static_CXX \ +lt_cv_prog_compiler_c_o_CXX \ +export_dynamic_flag_spec_CXX \ +whole_archive_flag_spec_CXX \ +compiler_needs_object_CXX \ +with_gnu_ld_CXX \ +allow_undefined_flag_CXX \ +no_undefined_flag_CXX \ +hardcode_libdir_flag_spec_CXX \ +hardcode_libdir_separator_CXX \ +exclude_expsyms_CXX \ +include_expsyms_CXX \ +file_list_spec_CXX \ +compiler_lib_search_dirs_CXX \ +predep_objects_CXX \ +postdep_objects_CXX \ +predeps_CXX \ +postdeps_CXX \ +compiler_lib_search_path_CXX; do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[\\\\\\\`\\"\\\$]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +# Double-quote double-evaled strings. +for var in reload_cmds \ +old_postinstall_cmds \ +old_postuninstall_cmds \ +old_archive_cmds \ +extract_expsyms_cmds \ +old_archive_from_new_cmds \ +old_archive_from_expsyms_cmds \ +archive_cmds \ +archive_expsym_cmds \ +module_cmds \ +module_expsym_cmds \ +export_symbols_cmds \ +prelink_cmds \ +postlink_cmds \ +postinstall_cmds \ +postuninstall_cmds \ +finish_cmds \ +sys_lib_search_path_spec \ +configure_time_dlsearch_path \ +configure_time_lt_sys_library_path \ +reload_cmds_CXX \ +old_archive_cmds_CXX \ +old_archive_from_new_cmds_CXX \ +old_archive_from_expsyms_cmds_CXX \ +archive_cmds_CXX \ +archive_expsym_cmds_CXX \ +module_cmds_CXX \ +module_expsym_cmds_CXX \ +export_symbols_cmds_CXX \ +prelink_cmds_CXX \ +postlink_cmds_CXX; do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[\\\\\\\`\\"\\\$]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +ac_aux_dir='$ac_aux_dir' + +# See if we are running on zsh, and set the options that allow our +# commands through without removal of \ escapes INIT. +if test -n "\${ZSH_VERSION+set}"; then + setopt NO_GLOB_SUBST +fi + + + PACKAGE='$PACKAGE' + VERSION='$VERSION' + RM='$RM' + ofile='$ofile' + + + + + +# variables for create stdint.h replacement +PACKAGE="$PACKAGE" +VERSION="$VERSION" +ac_stdint_h="$ac_stdint_h" +_ac_stdint_h=`printf "%s\n" "_$PACKAGE-$ac_stdint_h" | $as_tr_cpp` +ac_cv_stdint_message="$ac_cv_stdint_message" +ac_cv_header_stdint_t="$ac_cv_header_stdint_t" +ac_cv_header_stdint_x="$ac_cv_header_stdint_x" +ac_cv_header_stdint_o="$ac_cv_header_stdint_o" +ac_cv_header_stdint_u="$ac_cv_header_stdint_u" +ac_cv_type_uint64_t="$ac_cv_type_uint64_t" +ac_cv_type_u_int64_t="$ac_cv_type_u_int64_t" +ac_cv_char_data_model="$ac_cv_char_data_model" +ac_cv_long_data_model="$ac_cv_long_data_model" +ac_cv_type_int_least32_t="$ac_cv_type_int_least32_t" +ac_cv_type_int_fast32_t="$ac_cv_type_int_fast32_t" +ac_cv_type_intmax_t="$ac_cv_type_intmax_t" + + +ax_create_pkgconfig_generate="$ax_create_pkgconfig_generate" +pkgconfig_prefix='$prefix' +pkgconfig_execprefix='$exec_prefix' +pkgconfig_bindir='$bindir' +pkgconfig_libdir='$libdir' +pkgconfig_includedir='$includedir' +pkgconfig_datarootdir='$datarootdir' +pkgconfig_datadir='$datadir' +pkgconfig_sysconfdir='$sysconfdir' +pkgconfig_suffix='$ax_create_pkgconfig_suffix' +pkgconfig_package='$PACKAGE_NAME' +pkgconfig_libname='$ax_create_pkgconfig_libname' +pkgconfig_description='$ax_create_pkgconfig_description' +pkgconfig_version='$ax_create_pkgconfig_version' +pkgconfig_requires='$ax_create_pkgconfig_requires' +pkgconfig_libs='$ax_create_pkgconfig_libs' +pkgconfig_ldflags='$ax_create_pkgconfig_ldflags' +pkgconfig_cppflags='$ax_create_pkgconfig_cppflags' +pkgconfig_src_libdir='$ax_create_pkgconfig_src_libdir' +pkgconfig_src_headers='$ax_create_pkgconfig_src_headers' + + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + +# Handling of arguments. +for ac_config_target in $ac_config_targets +do + case $ac_config_target in + "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; + "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;; + "$ac_stdint_h") CONFIG_COMMANDS="$CONFIG_COMMANDS $ac_stdint_h" ;; + "$ax_create_pkgconfig_generate") CONFIG_COMMANDS="$CONFIG_COMMANDS $ax_create_pkgconfig_generate" ;; + "isl_config.h") CONFIG_HEADERS="$CONFIG_HEADERS isl_config.h" ;; + "isl_srcdir.c") CONFIG_FILES="$CONFIG_FILES isl_srcdir.c" ;; + "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "doc/Makefile") CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;; + "bound_test.sh") CONFIG_FILES="$CONFIG_FILES bound_test.sh" ;; + "codegen_test.sh") CONFIG_FILES="$CONFIG_FILES codegen_test.sh" ;; + "pip_test.sh") CONFIG_FILES="$CONFIG_FILES pip_test.sh" ;; + "flow_test.sh") CONFIG_FILES="$CONFIG_FILES flow_test.sh" ;; + "schedule_test.sh") CONFIG_FILES="$CONFIG_FILES schedule_test.sh" ;; + + *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; + esac +done + + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test ${CONFIG_FILES+y} || CONFIG_FILES=$config_files + test ${CONFIG_HEADERS+y} || CONFIG_HEADERS=$config_headers + test ${CONFIG_COMMANDS+y} || CONFIG_COMMANDS=$config_commands +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason against having it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to `$tmp'. +$debug || +{ + tmp= ac_tmp= + trap 'exit_status=$? + : "${ac_tmp:=$tmp}" + { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status +' 0 + trap 'as_fn_exit 1' 1 2 13 15 +} +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && + test -d "$tmp" +} || +{ + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") +} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 +ac_tmp=$tmp + +# Set up the scripts for CONFIG_FILES section. +# No need to generate them if there are no CONFIG_FILES. +# This happens for instance with `./config.status config.h'. +if test -n "$CONFIG_FILES"; then + + +ac_cr=`echo X | tr X '\015'` +# On cygwin, bash can eat \r inside `` if the user requested igncr. +# But we know of no other shell where ac_cr would be empty at this +# point, so we can use a bashism as a fallback. +if test "x$ac_cr" = x; then + eval ac_cr=\$\'\\r\' +fi +ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` +if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then + ac_cs_awk_cr='\\r' +else + ac_cs_awk_cr=$ac_cr +fi + +echo 'BEGIN {' >"$ac_tmp/subs1.awk" && +_ACEOF + + +{ + echo "cat >conf$$subs.awk <<_ACEOF" && + echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && + echo "_ACEOF" +} >conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 +ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + . ./conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + + ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` + if test $ac_delim_n = $ac_delim_num; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done +rm -f conf$$subs.sh + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && +_ACEOF +sed -n ' +h +s/^/S["/; s/!.*/"]=/ +p +g +s/^[^!]*!// +:repl +t repl +s/'"$ac_delim"'$// +t delim +:nl +h +s/\(.\{148\}\)..*/\1/ +t more1 +s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ +p +n +b repl +:more1 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t nl +:delim +h +s/\(.\{148\}\)..*/\1/ +t more2 +s/["\\]/\\&/g; s/^/"/; s/$/"/ +p +b +:more2 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t delim +' >$CONFIG_STATUS || ac_write_fail=1 +rm -f conf$$subs.awk +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +_ACAWK +cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && + for (key in S) S_is_set[key] = 1 + FS = "" + +} +{ + line = $ 0 + nfields = split(line, field, "@") + substed = 0 + len = length(field[1]) + for (i = 2; i < nfields; i++) { + key = field[i] + keylen = length(key) + if (S_is_set[key]) { + value = S[key] + line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) + len += length(value) + length(field[++i]) + substed = 1 + } else + len += 1 + keylen + } + + print line +} + +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then + sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" +else + cat +fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ + || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 +_ACEOF + +# VPATH may cause trouble with some makes, so we remove sole $(srcdir), +# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ +h +s/// +s/^/:/ +s/[ ]*$/:/ +s/:\$(srcdir):/:/g +s/:\${srcdir}:/:/g +s/:@srcdir@:/:/g +s/^:*// +s/:*$// +x +s/\(=[ ]*\).*/\1/ +G +s/\n// +s/^[^=]*=[ ]*$// +}' +fi + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +fi # test -n "$CONFIG_FILES" + +# Set up the scripts for CONFIG_HEADERS section. +# No need to generate them if there are no CONFIG_HEADERS. +# This happens for instance with `./config.status Makefile'. +if test -n "$CONFIG_HEADERS"; then +cat >"$ac_tmp/defines.awk" <<\_ACAWK || +BEGIN { +_ACEOF + +# Transform confdefs.h into an awk script `defines.awk', embedded as +# here-document in config.status, that substitutes the proper values into +# config.h.in to produce config.h. + +# Create a delimiter string that does not exist in confdefs.h, to ease +# handling of long lines. +ac_delim='%!_!# ' +for ac_last_try in false false :; do + ac_tt=`sed -n "/$ac_delim/p" confdefs.h` + if test -z "$ac_tt"; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done + +# For the awk script, D is an array of macro values keyed by name, +# likewise P contains macro parameters if any. Preserve backslash +# newline sequences. + +ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* +sed -n ' +s/.\{148\}/&'"$ac_delim"'/g +t rset +:rset +s/^[ ]*#[ ]*define[ ][ ]*/ / +t def +d +:def +s/\\$// +t bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3"/p +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p +d +:bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3\\\\\\n"\\/p +t cont +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p +t cont +d +:cont +n +s/.\{148\}/&'"$ac_delim"'/g +t clear +:clear +s/\\$// +t bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/"/p +d +:bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p +b cont +' >$CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + for (key in D) D_is_set[key] = 1 + FS = "" +} +/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { + line = \$ 0 + split(line, arg, " ") + if (arg[1] == "#") { + defundef = arg[2] + mac1 = arg[3] + } else { + defundef = substr(arg[1], 2) + mac1 = arg[2] + } + split(mac1, mac2, "(") #) + macro = mac2[1] + prefix = substr(line, 1, index(line, defundef) - 1) + if (D_is_set[macro]) { + # Preserve the white space surrounding the "#". + print prefix "define", macro P[macro] D[macro] + next + } else { + # Replace #undef with comments. This is necessary, for example, + # in the case of _POSIX_SOURCE, which is predefined and required + # on some systems where configure will not decide to define it. + if (defundef == "undef") { + print "/*", prefix defundef, macro, "*/" + next + } + } +} +{ print } +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 +fi # test -n "$CONFIG_HEADERS" + + +eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" +shift +for ac_tag +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift + + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$ac_tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain `:'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; + esac + case $ac_f in *\'*) ac_f=`printf "%s\n" "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac + as_fn_append ac_file_inputs " '$ac_f'" + done + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input='Generated from '` + printf "%s\n" "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' + `' by configure.' + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 +printf "%s\n" "$as_me: creating $ac_file" >&6;} + fi + # Neutralize special characters interpreted by sed in replacement strings. + case $configure_input in #( + *\&* | *\|* | *\\* ) + ac_sed_conf_input=`printf "%s\n" "$configure_input" | + sed 's/[\\\\&|]/\\\\&/g'`;; #( + *) ac_sed_conf_input=$configure_input;; + esac + + case $ac_tag in + *:-:* | *:-) cat >"$ac_tmp/stdin" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; + esac + ;; + esac + + ac_dir=`$as_dirname -- "$ac_file" || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +printf "%s\n" X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir="$ac_dir"; as_fn_mkdir_p + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`printf "%s\n" "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`printf "%s\n" "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + case $ac_mode in + :F) + # + # CONFIG_FILE + # + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; + esac + ac_MKDIR_P=$MKDIR_P + case $MKDIR_P in + [\\/$]* | ?:[\\/]* ) ;; + */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; + esac +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= +ac_sed_dataroot=' +/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p' +case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +printf "%s\n" "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + ac_datarootdir_hack=' + s&@datadir@&$datadir&g + s&@docdir@&$docdir&g + s&@infodir@&$infodir&g + s&@localedir@&$localedir&g + s&@mandir@&$mandir&g + s&\\\${datarootdir}&$datarootdir&g' ;; +esac +_ACEOF + +# Neutralize VPATH when `$srcdir' = `.'. +# Shell code in configure.ac might set extrasub. +# FIXME: do we really want to maintain this feature? +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_sed_extra="$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s|@configure_input@|$ac_sed_conf_input|;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@top_build_prefix@&$ac_top_build_prefix&;t t +s&@srcdir@&$ac_srcdir&;t t +s&@abs_srcdir@&$ac_abs_srcdir&;t t +s&@top_srcdir@&$ac_top_srcdir&;t t +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +s&@builddir@&$ac_builddir&;t t +s&@abs_builddir@&$ac_abs_builddir&;t t +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +s&@INSTALL@&$ac_INSTALL&;t t +s&@MKDIR_P@&$ac_MKDIR_P&;t t +$ac_datarootdir_hack +" +eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ + >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ + "$ac_tmp/out"`; test -z "$ac_out"; } && + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&5 +printf "%s\n" "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&2;} + + rm -f "$ac_tmp/stdin" + case $ac_file in + -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; + *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; + esac \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + ;; + :H) + # + # CONFIG_HEADER + # + if test x"$ac_file" != x-; then + { + printf "%s\n" "/* $configure_input */" >&1 \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" + } >"$ac_tmp/config.h" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 +printf "%s\n" "$as_me: $ac_file is unchanged" >&6;} + else + rm -f "$ac_file" + mv "$ac_tmp/config.h" "$ac_file" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + fi + else + printf "%s\n" "/* $configure_input */" >&1 \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ + || as_fn_error $? "could not create -" "$LINENO" 5 + fi +# Compute "$ac_file"'s index in $config_headers. +_am_arg="$ac_file" +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $_am_arg | $_am_arg:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || +$as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$_am_arg" : 'X\(//\)[^/]' \| \ + X"$_am_arg" : 'X\(//\)$' \| \ + X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || +printf "%s\n" X"$_am_arg" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'`/stamp-h$_am_stamp_count + ;; + + :C) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 +printf "%s\n" "$as_me: executing $ac_file commands" >&6;} + ;; + esac + + + case $ac_file$ac_mode in + "depfiles":C) test x"$AMDEP_TRUE" != x"" || { + # Older Autoconf quotes --file arguments for eval, but not when files + # are listed without --file. Let's play safe and only enable the eval + # if we detect the quoting. + # TODO: see whether this extra hack can be removed once we start + # requiring Autoconf 2.70 or later. + case $CONFIG_FILES in #( + *\'*) : + eval set x "$CONFIG_FILES" ;; #( + *) : + set x $CONFIG_FILES ;; #( + *) : + ;; +esac + shift + # Used to flag and report bootstrapping failures. + am_rc=0 + for am_mf + do + # Strip MF so we end up with the name of the file. + am_mf=`printf "%s\n" "$am_mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile which includes + # dependency-tracking related rules and includes. + # Grep'ing the whole file directly is not great: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + sed -n 's,^am--depfiles:.*,X,p' "$am_mf" | grep X >/dev/null 2>&1 \ + || continue + am_dirpart=`$as_dirname -- "$am_mf" || +$as_expr X"$am_mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$am_mf" : 'X\(//\)[^/]' \| \ + X"$am_mf" : 'X\(//\)$' \| \ + X"$am_mf" : 'X\(/\)' \| . 2>/dev/null || +printf "%s\n" X"$am_mf" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + am_filepart=`$as_basename -- "$am_mf" || +$as_expr X/"$am_mf" : '.*/\([^/][^/]*\)/*$' \| \ + X"$am_mf" : 'X\(//\)$' \| \ + X"$am_mf" : 'X\(/\)' \| . 2>/dev/null || +printf "%s\n" X/"$am_mf" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + { echo "$as_me:$LINENO: cd "$am_dirpart" \ + && sed -e '/# am--include-marker/d' "$am_filepart" \ + | $MAKE -f - am--depfiles" >&5 + (cd "$am_dirpart" \ + && sed -e '/# am--include-marker/d' "$am_filepart" \ + | $MAKE -f - am--depfiles) >&5 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } || am_rc=$? + done + if test $am_rc -ne 0; then + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "Something went wrong bootstrapping makefile fragments + for automatic dependency tracking. If GNU make was not used, consider + re-running the configure script with MAKE=\"gmake\" (or whatever is + necessary). You can also try re-running configure with the + '--disable-dependency-tracking' option to at least be able to build + the package (albeit without support for automatic dependency tracking). +See \`config.log' for more details" "$LINENO" 5; } + fi + { am_dirpart=; unset am_dirpart;} + { am_filepart=; unset am_filepart;} + { am_mf=; unset am_mf;} + { am_rc=; unset am_rc;} + rm -f conftest-deps.mk +} + ;; + "libtool":C) + + # See if we are running on zsh, and set the options that allow our + # commands through without removal of \ escapes. + if test -n "${ZSH_VERSION+set}"; then + setopt NO_GLOB_SUBST + fi + + cfgfile=${ofile}T + trap "$RM \"$cfgfile\"; exit 1" 1 2 15 + $RM "$cfgfile" + + cat <<_LT_EOF >> "$cfgfile" +#! $SHELL +# Generated automatically by $as_me ($PACKAGE) $VERSION +# NOTE: Changes made to this file will be lost: look at ltmain.sh. + +# Provide generalized library-building support services. +# Written by Gordon Matzigkeit, 1996 + +# Copyright (C) 2014 Free Software Foundation, Inc. +# This is free software; see the source for copying conditions. There is NO +# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +# GNU Libtool is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of of the License, or +# (at your option) any later version. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program or library that is built +# using GNU Libtool, you may include this file under the same +# distribution terms that you use for the rest of that program. +# +# GNU Libtool is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + + +# The names of the tagged configurations supported by this script. +available_tags='CXX ' + +# Configured defaults for sys_lib_dlsearch_path munging. +: \${LT_SYS_LIBRARY_PATH="$configure_time_lt_sys_library_path"} + +# ### BEGIN LIBTOOL CONFIG + +# Which release of libtool.m4 was used? +macro_version=$macro_version +macro_revision=$macro_revision + +# Whether or not to build shared libraries. +build_libtool_libs=$enable_shared + +# Whether or not to build static libraries. +build_old_libs=$enable_static + +# What type of objects to build. +pic_mode=$pic_mode + +# Whether or not to optimize for fast installation. +fast_install=$enable_fast_install + +# Shared archive member basename,for filename based shared library versioning on AIX. +shared_archive_member_spec=$shared_archive_member_spec + +# Shell to use when invoking shell scripts. +SHELL=$lt_SHELL + +# An echo program that protects backslashes. +ECHO=$lt_ECHO + +# The PATH separator for the build system. +PATH_SEPARATOR=$lt_PATH_SEPARATOR + +# The host system. +host_alias=$host_alias +host=$host +host_os=$host_os + +# The build system. +build_alias=$build_alias +build=$build +build_os=$build_os + +# A sed program that does not truncate output. +SED=$lt_SED + +# Sed that helps us avoid accidentally triggering echo(1) options like -n. +Xsed="\$SED -e 1s/^X//" + +# A grep program that handles long lines. +GREP=$lt_GREP + +# An ERE matcher. +EGREP=$lt_EGREP + +# A literal string matcher. +FGREP=$lt_FGREP + +# A BSD- or MS-compatible name lister. +NM=$lt_NM + +# Whether we need soft or hard links. +LN_S=$lt_LN_S + +# What is the maximum length of a command? +max_cmd_len=$max_cmd_len + +# Object file suffix (normally "o"). +objext=$ac_objext + +# Executable file suffix (normally ""). +exeext=$exeext + +# whether the shell understands "unset". +lt_unset=$lt_unset + +# turn spaces into newlines. +SP2NL=$lt_lt_SP2NL + +# turn newlines into spaces. +NL2SP=$lt_lt_NL2SP + +# convert \$build file names to \$host format. +to_host_file_cmd=$lt_cv_to_host_file_cmd + +# convert \$build files to toolchain format. +to_tool_file_cmd=$lt_cv_to_tool_file_cmd + +# An object symbol dumper. +OBJDUMP=$lt_OBJDUMP + +# Method to check whether dependent libraries are shared objects. +deplibs_check_method=$lt_deplibs_check_method + +# Command to use when deplibs_check_method = "file_magic". +file_magic_cmd=$lt_file_magic_cmd + +# How to find potential files when deplibs_check_method = "file_magic". +file_magic_glob=$lt_file_magic_glob + +# Find potential files using nocaseglob when deplibs_check_method = "file_magic". +want_nocaseglob=$lt_want_nocaseglob + +# DLL creation program. +DLLTOOL=$lt_DLLTOOL + +# Command to associate shared and link libraries. +sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd + +# The archiver. +AR=$lt_AR + +# Flags to create an archive. +AR_FLAGS=$lt_AR_FLAGS + +# How to feed a file listing to the archiver. +archiver_list_spec=$lt_archiver_list_spec + +# A symbol stripping program. +STRIP=$lt_STRIP + +# Commands used to install an old-style archive. +RANLIB=$lt_RANLIB +old_postinstall_cmds=$lt_old_postinstall_cmds +old_postuninstall_cmds=$lt_old_postuninstall_cmds + +# Whether to use a lock for old archive extraction. +lock_old_archive_extraction=$lock_old_archive_extraction + +# A C compiler. +LTCC=$lt_CC + +# LTCC compiler flags. +LTCFLAGS=$lt_CFLAGS + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe + +# Transform the output of nm in a proper C declaration. +global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl + +# Transform the output of nm into a list of symbols to manually relocate. +global_symbol_to_import=$lt_lt_cv_sys_global_symbol_to_import + +# Transform the output of nm in a C name address pair. +global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address + +# Transform the output of nm in a C name address pair when lib prefix is needed. +global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix + +# The name lister interface. +nm_interface=$lt_lt_cv_nm_interface + +# Specify filename containing input files for \$NM. +nm_file_list_spec=$lt_nm_file_list_spec + +# The root where to search for dependent libraries,and where our libraries should be installed. +lt_sysroot=$lt_sysroot + +# Command to truncate a binary pipe. +lt_truncate_bin=$lt_lt_cv_truncate_bin + +# The name of the directory that contains temporary libtool files. +objdir=$objdir + +# Used to examine libraries when file_magic_cmd begins with "file". +MAGIC_CMD=$MAGIC_CMD + +# Must we lock files when doing compilation? +need_locks=$lt_need_locks + +# Manifest tool. +MANIFEST_TOOL=$lt_MANIFEST_TOOL + +# Tool to manipulate archived DWARF debug symbol files on Mac OS X. +DSYMUTIL=$lt_DSYMUTIL + +# Tool to change global to local symbols on Mac OS X. +NMEDIT=$lt_NMEDIT + +# Tool to manipulate fat objects and archives on Mac OS X. +LIPO=$lt_LIPO + +# ldd/readelf like tool for Mach-O binaries on Mac OS X. +OTOOL=$lt_OTOOL + +# ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4. +OTOOL64=$lt_OTOOL64 + +# Old archive suffix (normally "a"). +libext=$libext + +# Shared library suffix (normally ".so"). +shrext_cmds=$lt_shrext_cmds + +# The commands to extract the exported symbol list from a shared archive. +extract_expsyms_cmds=$lt_extract_expsyms_cmds + +# Variables whose values should be saved in libtool wrapper scripts and +# restored at link time. +variables_saved_for_relink=$lt_variables_saved_for_relink + +# Do we need the "lib" prefix for modules? +need_lib_prefix=$need_lib_prefix + +# Do we need a version for libraries? +need_version=$need_version + +# Library versioning type. +version_type=$version_type + +# Shared library runtime path variable. +runpath_var=$runpath_var + +# Shared library path variable. +shlibpath_var=$shlibpath_var + +# Is shlibpath searched before the hard-coded library search path? +shlibpath_overrides_runpath=$shlibpath_overrides_runpath + +# Format of library name prefix. +libname_spec=$lt_libname_spec + +# List of archive names. First name is the real one, the rest are links. +# The last name is the one that the linker finds with -lNAME +library_names_spec=$lt_library_names_spec + +# The coded name of the library, if different from the real name. +soname_spec=$lt_soname_spec + +# Permission mode override for installation of shared libraries. +install_override_mode=$lt_install_override_mode + +# Command to use after installation of a shared archive. +postinstall_cmds=$lt_postinstall_cmds + +# Command to use after uninstallation of a shared archive. +postuninstall_cmds=$lt_postuninstall_cmds + +# Commands used to finish a libtool library installation in a directory. +finish_cmds=$lt_finish_cmds + +# As "finish_cmds", except a single script fragment to be evaled but +# not shown. +finish_eval=$lt_finish_eval + +# Whether we should hardcode library paths into libraries. +hardcode_into_libs=$hardcode_into_libs + +# Compile-time system search path for libraries. +sys_lib_search_path_spec=$lt_sys_lib_search_path_spec + +# Detected run-time system search path for libraries. +sys_lib_dlsearch_path_spec=$lt_configure_time_dlsearch_path + +# Explicit LT_SYS_LIBRARY_PATH set during ./configure time. +configure_time_lt_sys_library_path=$lt_configure_time_lt_sys_library_path + +# Whether dlopen is supported. +dlopen_support=$enable_dlopen + +# Whether dlopen of programs is supported. +dlopen_self=$enable_dlopen_self + +# Whether dlopen of statically linked programs is supported. +dlopen_self_static=$enable_dlopen_self_static + +# Commands to strip libraries. +old_striplib=$lt_old_striplib +striplib=$lt_striplib + + +# The linker used to build libraries. +LD=$lt_LD + +# How to create reloadable object files. +reload_flag=$lt_reload_flag +reload_cmds=$lt_reload_cmds + +# Commands used to build an old-style archive. +old_archive_cmds=$lt_old_archive_cmds + +# A language specific compiler. +CC=$lt_compiler + +# Is the compiler the GNU compiler? +with_gcc=$GCC + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag + +# Additional compiler flags for building library objects. +pic_flag=$lt_lt_prog_compiler_pic + +# How to pass a linker flag through the compiler. +wl=$lt_lt_prog_compiler_wl + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_lt_prog_compiler_static + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_lt_cv_prog_compiler_c_o + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$archive_cmds_need_lc + +# Whether or not to disallow shared libs when runtime libs are static. +allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec + +# Whether the compiler copes with passing no objects directly. +compiler_needs_object=$lt_compiler_needs_object + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds + +# Commands used to build a shared archive. +archive_cmds=$lt_archive_cmds +archive_expsym_cmds=$lt_archive_expsym_cmds + +# Commands used to build a loadable module if different from building +# a shared archive. +module_cmds=$lt_module_cmds +module_expsym_cmds=$lt_module_expsym_cmds + +# Whether we are building with GNU ld or not. +with_gnu_ld=$lt_with_gnu_ld + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag + +# Flag that enforces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec + +# Whether we need a single "-rpath" flag with a separated argument. +hardcode_libdir_separator=$lt_hardcode_libdir_separator + +# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes +# DIR into the resulting binary. +hardcode_direct=$hardcode_direct + +# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes +# DIR into the resulting binary and the resulting library dependency is +# "absolute",i.e impossible to change by setting \$shlibpath_var if the +# library is relocated. +hardcode_direct_absolute=$hardcode_direct_absolute + +# Set to "yes" if using the -LDIR flag during linking hardcodes DIR +# into the resulting binary. +hardcode_minus_L=$hardcode_minus_L + +# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR +# into the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var + +# Set to "yes" if building a shared library automatically hardcodes DIR +# into the library and all subsequent libraries and executables linked +# against it. +hardcode_automatic=$hardcode_automatic + +# Set to yes if linker adds runtime paths of dependent libraries +# to runtime path list. +inherit_rpath=$inherit_rpath + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs + +# Set to "yes" if exported symbols are required. +always_export_symbols=$always_export_symbols + +# The commands to list exported symbols. +export_symbols_cmds=$lt_export_symbols_cmds + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms + +# Commands necessary for linking programs (against libraries) with templates. +prelink_cmds=$lt_prelink_cmds + +# Commands necessary for finishing linking programs. +postlink_cmds=$lt_postlink_cmds + +# Specify filename containing input files. +file_list_spec=$lt_file_list_spec + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action + +# The directories searched by this compiler when creating a shared library. +compiler_lib_search_dirs=$lt_compiler_lib_search_dirs + +# Dependencies to place before and after the objects being linked to +# create a shared library. +predep_objects=$lt_predep_objects +postdep_objects=$lt_postdep_objects +predeps=$lt_predeps +postdeps=$lt_postdeps + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path=$lt_compiler_lib_search_path + +# ### END LIBTOOL CONFIG + +_LT_EOF + + cat <<'_LT_EOF' >> "$cfgfile" + +# ### BEGIN FUNCTIONS SHARED WITH CONFIGURE + +# func_munge_path_list VARIABLE PATH +# ----------------------------------- +# VARIABLE is name of variable containing _space_ separated list of +# directories to be munged by the contents of PATH, which is string +# having a format: +# "DIR[:DIR]:" +# string "DIR[ DIR]" will be prepended to VARIABLE +# ":DIR[:DIR]" +# string "DIR[ DIR]" will be appended to VARIABLE +# "DIRP[:DIRP]::[DIRA:]DIRA" +# string "DIRP[ DIRP]" will be prepended to VARIABLE and string +# "DIRA[ DIRA]" will be appended to VARIABLE +# "DIR[:DIR]" +# VARIABLE will be replaced by "DIR[ DIR]" +func_munge_path_list () +{ + case x$2 in + x) + ;; + *:) + eval $1=\"`$ECHO $2 | $SED 's/:/ /g'` \$$1\" + ;; + x:*) + eval $1=\"\$$1 `$ECHO $2 | $SED 's/:/ /g'`\" + ;; + *::*) + eval $1=\"\$$1\ `$ECHO $2 | $SED -e 's/.*:://' -e 's/:/ /g'`\" + eval $1=\"`$ECHO $2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \$$1\" + ;; + *) + eval $1=\"`$ECHO $2 | $SED 's/:/ /g'`\" + ;; + esac +} + + +# Calculate cc_basename. Skip known compiler wrappers and cross-prefix. +func_cc_basename () +{ + for cc_temp in $*""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac + done + func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` +} + + +# ### END FUNCTIONS SHARED WITH CONFIGURE + +_LT_EOF + + case $host_os in + aix3*) + cat <<\_LT_EOF >> "$cfgfile" +# AIX sometimes has problems with the GCC collect2 program. For some +# reason, if we set the COLLECT_NAMES environment variable, the problems +# vanish in a puff of smoke. +if test set != "${COLLECT_NAMES+set}"; then + COLLECT_NAMES= + export COLLECT_NAMES +fi +_LT_EOF + ;; + esac + + + +ltmain=$ac_aux_dir/ltmain.sh + + + # We use sed instead of cat because bash on DJGPP gets confused if + # if finds mixed CR/LF and LF-only lines. Since sed operates in + # text mode, it properly converts lines to CR/LF. This bash problem + # is reportedly fixed, but why not run on old versions too? + sed '$q' "$ltmain" >> "$cfgfile" \ + || (rm -f "$cfgfile"; exit 1) + + mv -f "$cfgfile" "$ofile" || + (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") + chmod +x "$ofile" + + + cat <<_LT_EOF >> "$ofile" + +# ### BEGIN LIBTOOL TAG CONFIG: CXX + +# The linker used to build libraries. +LD=$lt_LD_CXX + +# How to create reloadable object files. +reload_flag=$lt_reload_flag_CXX +reload_cmds=$lt_reload_cmds_CXX + +# Commands used to build an old-style archive. +old_archive_cmds=$lt_old_archive_cmds_CXX + +# A language specific compiler. +CC=$lt_compiler_CXX + +# Is the compiler the GNU compiler? +with_gcc=$GCC_CXX + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_CXX + +# Additional compiler flags for building library objects. +pic_flag=$lt_lt_prog_compiler_pic_CXX + +# How to pass a linker flag through the compiler. +wl=$lt_lt_prog_compiler_wl_CXX + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_lt_prog_compiler_static_CXX + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_lt_cv_prog_compiler_c_o_CXX + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$archive_cmds_need_lc_CXX + +# Whether or not to disallow shared libs when runtime libs are static. +allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_CXX + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_CXX + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec_CXX + +# Whether the compiler copes with passing no objects directly. +compiler_needs_object=$lt_compiler_needs_object_CXX + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_CXX + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_CXX + +# Commands used to build a shared archive. +archive_cmds=$lt_archive_cmds_CXX +archive_expsym_cmds=$lt_archive_expsym_cmds_CXX + +# Commands used to build a loadable module if different from building +# a shared archive. +module_cmds=$lt_module_cmds_CXX +module_expsym_cmds=$lt_module_expsym_cmds_CXX + +# Whether we are building with GNU ld or not. +with_gnu_ld=$lt_with_gnu_ld_CXX + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag_CXX + +# Flag that enforces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag_CXX + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_CXX + +# Whether we need a single "-rpath" flag with a separated argument. +hardcode_libdir_separator=$lt_hardcode_libdir_separator_CXX + +# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes +# DIR into the resulting binary. +hardcode_direct=$hardcode_direct_CXX + +# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes +# DIR into the resulting binary and the resulting library dependency is +# "absolute",i.e impossible to change by setting \$shlibpath_var if the +# library is relocated. +hardcode_direct_absolute=$hardcode_direct_absolute_CXX + +# Set to "yes" if using the -LDIR flag during linking hardcodes DIR +# into the resulting binary. +hardcode_minus_L=$hardcode_minus_L_CXX + +# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR +# into the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var_CXX + +# Set to "yes" if building a shared library automatically hardcodes DIR +# into the library and all subsequent libraries and executables linked +# against it. +hardcode_automatic=$hardcode_automatic_CXX + +# Set to yes if linker adds runtime paths of dependent libraries +# to runtime path list. +inherit_rpath=$inherit_rpath_CXX + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs_CXX + +# Set to "yes" if exported symbols are required. +always_export_symbols=$always_export_symbols_CXX + +# The commands to list exported symbols. +export_symbols_cmds=$lt_export_symbols_cmds_CXX + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms_CXX + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms_CXX + +# Commands necessary for linking programs (against libraries) with templates. +prelink_cmds=$lt_prelink_cmds_CXX + +# Commands necessary for finishing linking programs. +postlink_cmds=$lt_postlink_cmds_CXX + +# Specify filename containing input files. +file_list_spec=$lt_file_list_spec_CXX + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action_CXX + +# The directories searched by this compiler when creating a shared library. +compiler_lib_search_dirs=$lt_compiler_lib_search_dirs_CXX + +# Dependencies to place before and after the objects being linked to +# create a shared library. +predep_objects=$lt_predep_objects_CXX +postdep_objects=$lt_postdep_objects_CXX +predeps=$lt_predeps_CXX +postdeps=$lt_postdeps_CXX + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path=$lt_compiler_lib_search_path_CXX + +# ### END LIBTOOL TAG CONFIG: CXX +_LT_EOF + + ;; + "$ac_stdint_h":C) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating $ac_stdint_h : $_ac_stdint_h" >&5 +printf "%s\n" "$as_me: creating $ac_stdint_h : $_ac_stdint_h" >&6;} +ac_stdint=$tmp/_stdint.h + +echo "#ifndef" $_ac_stdint_h >$ac_stdint +echo "#define" $_ac_stdint_h "1" >>$ac_stdint +echo "#ifndef" _GENERATED_STDINT_H >>$ac_stdint +echo "#define" _GENERATED_STDINT_H '"'$PACKAGE $VERSION'"' >>$ac_stdint +echo "/* generated $ac_cv_stdint_message */" >>$ac_stdint +if test "_$ac_cv_header_stdint_t" != "_" ; then +echo "#define _STDINT_HAVE_STDINT_H" "1" >>$ac_stdint +echo "#include " >>$ac_stdint +echo "#endif" >>$ac_stdint +echo "#endif" >>$ac_stdint +else + +cat >>$ac_stdint < +#else +#include + +/* .................... configured part ............................ */ + +STDINT_EOF + +echo "/* whether we have a C99 compatible stdint header file */" >>$ac_stdint +if test "_$ac_cv_header_stdint_x" != "_" ; then + ac_header="$ac_cv_header_stdint_x" + echo "#define _STDINT_HEADER_INTPTR" '"'"$ac_header"'"' >>$ac_stdint +else + echo "/* #undef _STDINT_HEADER_INTPTR */" >>$ac_stdint +fi + +echo "/* whether we have a C96 compatible inttypes header file */" >>$ac_stdint +if test "_$ac_cv_header_stdint_o" != "_" ; then + ac_header="$ac_cv_header_stdint_o" + echo "#define _STDINT_HEADER_UINT32" '"'"$ac_header"'"' >>$ac_stdint +else + echo "/* #undef _STDINT_HEADER_UINT32 */" >>$ac_stdint +fi + +echo "/* whether we have a BSD compatible inet types header */" >>$ac_stdint +if test "_$ac_cv_header_stdint_u" != "_" ; then + ac_header="$ac_cv_header_stdint_u" + echo "#define _STDINT_HEADER_U_INT32" '"'"$ac_header"'"' >>$ac_stdint +else + echo "/* #undef _STDINT_HEADER_U_INT32 */" >>$ac_stdint +fi + +echo "" >>$ac_stdint + +if test "_$ac_header" != "_" ; then if test "$ac_header" != "stddef.h" ; then + echo "#include <$ac_header>" >>$ac_stdint + echo "" >>$ac_stdint +fi fi + +echo "/* which 64bit typedef has been found */" >>$ac_stdint +if test "$ac_cv_type_uint64_t" = "yes" ; then +echo "#define _STDINT_HAVE_UINT64_T" "1" >>$ac_stdint +else +echo "/* #undef _STDINT_HAVE_UINT64_T */" >>$ac_stdint +fi +if test "$ac_cv_type_u_int64_t" = "yes" ; then +echo "#define _STDINT_HAVE_U_INT64_T" "1" >>$ac_stdint +else +echo "/* #undef _STDINT_HAVE_U_INT64_T */" >>$ac_stdint +fi +echo "" >>$ac_stdint + +echo "/* which type model has been detected */" >>$ac_stdint +if test "_$ac_cv_char_data_model" != "_" ; then +echo "#define _STDINT_CHAR_MODEL" "$ac_cv_char_data_model" >>$ac_stdint +echo "#define _STDINT_LONG_MODEL" "$ac_cv_long_data_model" >>$ac_stdint +else +echo "/* #undef _STDINT_CHAR_MODEL // skipped */" >>$ac_stdint +echo "/* #undef _STDINT_LONG_MODEL // skipped */" >>$ac_stdint +fi +echo "" >>$ac_stdint + +echo "/* whether int_least types were detected */" >>$ac_stdint +if test "$ac_cv_type_int_least32_t" = "yes"; then +echo "#define _STDINT_HAVE_INT_LEAST32_T" "1" >>$ac_stdint +else +echo "/* #undef _STDINT_HAVE_INT_LEAST32_T */" >>$ac_stdint +fi +echo "/* whether int_fast types were detected */" >>$ac_stdint +if test "$ac_cv_type_int_fast32_t" = "yes"; then +echo "#define _STDINT_HAVE_INT_FAST32_T" "1" >>$ac_stdint +else +echo "/* #undef _STDINT_HAVE_INT_FAST32_T */" >>$ac_stdint +fi +echo "/* whether intmax_t type was detected */" >>$ac_stdint +if test "$ac_cv_type_intmax_t" = "yes"; then +echo "#define _STDINT_HAVE_INTMAX_T" "1" >>$ac_stdint +else +echo "/* #undef _STDINT_HAVE_INTMAX_T */" >>$ac_stdint +fi +echo "" >>$ac_stdint + + cat >>$ac_stdint <= 199901L +#define _HAVE_UINT64_T +#define _HAVE_LONGLONG_UINT64_T +typedef long long int64_t; +typedef unsigned long long uint64_t; + +#elif !defined __STRICT_ANSI__ +#if defined _MSC_VER || defined __WATCOMC__ || defined __BORLANDC__ +#define _HAVE_UINT64_T +typedef __int64 int64_t; +typedef unsigned __int64 uint64_t; + +#elif defined __GNUC__ || defined __MWERKS__ || defined __ELF__ +/* note: all ELF-systems seem to have loff-support which needs 64-bit */ +#if !defined _NO_LONGLONG +#define _HAVE_UINT64_T +#define _HAVE_LONGLONG_UINT64_T +typedef long long int64_t; +typedef unsigned long long uint64_t; +#endif + +#elif defined __alpha || (defined __mips && defined _ABIN32) +#if !defined _NO_LONGLONG +typedef long int64_t; +typedef unsigned long uint64_t; +#endif + /* compiler/cpu type to define int64_t */ +#endif +#endif +#endif + +#if defined _STDINT_HAVE_U_INT_TYPES +/* int8_t int16_t int32_t defined by inet code, redeclare the u_intXX types */ +typedef u_int8_t uint8_t; +typedef u_int16_t uint16_t; +typedef u_int32_t uint32_t; + +/* glibc compatibility */ +#ifndef __int8_t_defined +#define __int8_t_defined +#endif +#endif + +#ifdef _STDINT_NEED_INT_MODEL_T +/* we must guess all the basic types. Apart from byte-addressable system, */ +/* there a few 32-bit-only dsp-systems that we guard with BYTE_MODEL 8-} */ +/* (btw, those nibble-addressable systems are way off, or so we assume) */ + + +#if defined _STDINT_BYTE_MODEL +#if _STDINT_LONG_MODEL+0 == 242 +/* 2:4:2 = IP16 = a normal 16-bit system */ +typedef unsigned char uint8_t; +typedef unsigned short uint16_t; +typedef unsigned long uint32_t; +#ifndef __int8_t_defined +#define __int8_t_defined +typedef char int8_t; +typedef short int16_t; +typedef long int32_t; +#endif +#elif _STDINT_LONG_MODEL+0 == 244 || _STDINT_LONG_MODEL == 444 +/* 2:4:4 = LP32 = a 32-bit system derived from a 16-bit */ +/* 4:4:4 = ILP32 = a normal 32-bit system */ +typedef unsigned char uint8_t; +typedef unsigned short uint16_t; +typedef unsigned int uint32_t; +#ifndef __int8_t_defined +#define __int8_t_defined +typedef char int8_t; +typedef short int16_t; +typedef int int32_t; +#endif +#elif _STDINT_LONG_MODEL+0 == 484 || _STDINT_LONG_MODEL+0 == 488 +/* 4:8:4 = IP32 = a 32-bit system prepared for 64-bit */ +/* 4:8:8 = LP64 = a normal 64-bit system */ +typedef unsigned char uint8_t; +typedef unsigned short uint16_t; +typedef unsigned int uint32_t; +#ifndef __int8_t_defined +#define __int8_t_defined +typedef char int8_t; +typedef short int16_t; +typedef int int32_t; +#endif +/* this system has a "long" of 64bit */ +#ifndef _HAVE_UINT64_T +#define _HAVE_UINT64_T +typedef unsigned long uint64_t; +typedef long int64_t; +#endif +#elif _STDINT_LONG_MODEL+0 == 448 +/* LLP64 a 64-bit system derived from a 32-bit system */ +typedef unsigned char uint8_t; +typedef unsigned short uint16_t; +typedef unsigned int uint32_t; +#ifndef __int8_t_defined +#define __int8_t_defined +typedef char int8_t; +typedef short int16_t; +typedef int int32_t; +#endif +/* assuming the system has a "long long" */ +#ifndef _HAVE_UINT64_T +#define _HAVE_UINT64_T +#define _HAVE_LONGLONG_UINT64_T +typedef unsigned long long uint64_t; +typedef long long int64_t; +#endif +#else +#define _STDINT_NO_INT32_T +#endif +#else +#define _STDINT_NO_INT8_T +#define _STDINT_NO_INT32_T +#endif +#endif + +/* + * quote from SunOS-5.8 sys/inttypes.h: + * Use at your own risk. As of February 1996, the committee is squarely + * behind the fixed sized types; the "least" and "fast" types are still being + * discussed. The probability that the "fast" types may be removed before + * the standard is finalized is high enough that they are not currently + * implemented. + */ + +#if defined _STDINT_NEED_INT_LEAST_T +typedef int8_t int_least8_t; +typedef int16_t int_least16_t; +typedef int32_t int_least32_t; +#ifdef _HAVE_UINT64_T +typedef int64_t int_least64_t; +#endif + +typedef uint8_t uint_least8_t; +typedef uint16_t uint_least16_t; +typedef uint32_t uint_least32_t; +#ifdef _HAVE_UINT64_T +typedef uint64_t uint_least64_t; +#endif + /* least types */ +#endif + +#if defined _STDINT_NEED_INT_FAST_T +typedef int8_t int_fast8_t; +typedef int int_fast16_t; +typedef int32_t int_fast32_t; +#ifdef _HAVE_UINT64_T +typedef int64_t int_fast64_t; +#endif + +typedef uint8_t uint_fast8_t; +typedef unsigned uint_fast16_t; +typedef uint32_t uint_fast32_t; +#ifdef _HAVE_UINT64_T +typedef uint64_t uint_fast64_t; +#endif + /* fast types */ +#endif + +#ifdef _STDINT_NEED_INTMAX_T +#ifdef _HAVE_UINT64_T +typedef int64_t intmax_t; +typedef uint64_t uintmax_t; +#else +typedef long intmax_t; +typedef unsigned long uintmax_t; +#endif +#endif + +#ifdef _STDINT_NEED_INTPTR_T +#ifndef __intptr_t_defined +#define __intptr_t_defined +/* we encourage using "long" to store pointer values, never use "int" ! */ +#if _STDINT_LONG_MODEL+0 == 242 || _STDINT_LONG_MODEL+0 == 484 +typedef unsigned int uintptr_t; +typedef int intptr_t; +#elif _STDINT_LONG_MODEL+0 == 244 || _STDINT_LONG_MODEL+0 == 444 +typedef unsigned long uintptr_t; +typedef long intptr_t; +#elif _STDINT_LONG_MODEL+0 == 448 && defined _HAVE_UINT64_T +typedef uint64_t uintptr_t; +typedef int64_t intptr_t; +#else /* matches typical system types ILP32 and LP64 - but not IP16 or LLP64 */ +typedef unsigned long uintptr_t; +typedef long intptr_t; +#endif +#endif +#endif + +/* The ISO C99 standard specifies that in C++ implementations these + should only be defined if explicitly requested. */ +#if !defined __cplusplus || defined __STDC_CONSTANT_MACROS +#ifndef UINT32_C + +/* Signed. */ +# define INT8_C(c) c +# define INT16_C(c) c +# define INT32_C(c) c +# ifdef _HAVE_LONGLONG_UINT64_T +# define INT64_C(c) c ## L +# else +# define INT64_C(c) c ## LL +# endif + +/* Unsigned. */ +# define UINT8_C(c) c ## U +# define UINT16_C(c) c ## U +# define UINT32_C(c) c ## U +# ifdef _HAVE_LONGLONG_UINT64_T +# define UINT64_C(c) c ## UL +# else +# define UINT64_C(c) c ## ULL +# endif + +/* Maximal type. */ +# ifdef _HAVE_LONGLONG_UINT64_T +# define INTMAX_C(c) c ## L +# define UINTMAX_C(c) c ## UL +# else +# define INTMAX_C(c) c ## LL +# define UINTMAX_C(c) c ## ULL +# endif + + /* literalnumbers */ +#endif +#endif + +/* These limits are merrily those of a two complement byte-oriented system */ + +/* Minimum of signed integral types. */ +# define INT8_MIN (-128) +# define INT16_MIN (-32767-1) +# define INT32_MIN (-2147483647-1) +#ifndef INT64_MIN +# define INT64_MIN (-__INT64_C(9223372036854775807)-1) +#endif +/* Maximum of signed integral types. */ +# define INT8_MAX (127) +# define INT16_MAX (32767) +# define INT32_MAX (2147483647) +#ifndef INT64_MAX +# define INT64_MAX (__INT64_C(9223372036854775807)) +#endif + +/* Maximum of unsigned integral types. */ +#ifndef UINT8_MAX +# define UINT8_MAX (255) +#endif +#ifndef UINT16_MAX +# define UINT16_MAX (65535) +#endif +# define UINT32_MAX (4294967295U) +#ifndef UINT64_MAX +# define UINT64_MAX (__UINT64_C(18446744073709551615)) +#endif + +/* Minimum of signed integral types having a minimum size. */ +# define INT_LEAST8_MIN INT8_MIN +# define INT_LEAST16_MIN INT16_MIN +# define INT_LEAST32_MIN INT32_MIN +# define INT_LEAST64_MIN INT64_MIN +/* Maximum of signed integral types having a minimum size. */ +# define INT_LEAST8_MAX INT8_MAX +# define INT_LEAST16_MAX INT16_MAX +# define INT_LEAST32_MAX INT32_MAX +# define INT_LEAST64_MAX INT64_MAX + +/* Maximum of unsigned integral types having a minimum size. */ +# define UINT_LEAST8_MAX UINT8_MAX +# define UINT_LEAST16_MAX UINT16_MAX +# define UINT_LEAST32_MAX UINT32_MAX +# define UINT_LEAST64_MAX UINT64_MAX + + /* shortcircuit*/ +#endif + /* once */ +#endif +#endif +STDINT_EOF +fi + if cmp -s $ac_stdint_h $ac_stdint 2>/dev/null; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: $ac_stdint_h is unchanged" >&5 +printf "%s\n" "$as_me: $ac_stdint_h is unchanged" >&6;} + else + ac_dir=`$as_dirname -- "$ac_stdint_h" || +$as_expr X"$ac_stdint_h" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_stdint_h" : 'X\(//\)[^/]' \| \ + X"$ac_stdint_h" : 'X\(//\)$' \| \ + X"$ac_stdint_h" : 'X\(/\)' \| . 2>/dev/null || +printf "%s\n" X"$ac_stdint_h" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir="$ac_dir"; as_fn_mkdir_p + rm -f $ac_stdint_h + mv $ac_stdint $ac_stdint_h + fi + ;; + "$ax_create_pkgconfig_generate":C) +pkgconfig_generate="$ax_create_pkgconfig_generate" +if test ! -f "$pkgconfig_generate.in" +then generate="true" +elif grep ' generated by configure ' $pkgconfig_generate.in >/dev/null +then generate="true" +else generate="false"; +fi +if $generate ; then +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating $pkgconfig_generate.in" >&5 +printf "%s\n" "$as_me: creating $pkgconfig_generate.in" >&6;} +cat > $pkgconfig_generate.in <&5 +printf "%s\n" "$as_me: creating $pkgconfig_generate" >&6;} +cat >conftest.sed < $pkgconfig_generate +if test ! -s $pkgconfig_generate ; then + as_fn_error $? "$pkgconfig_generate is empty" "$LINENO" 5 +fi ; rm conftest.sed # DONE generate $pkgconfig_generate +pkgconfig_uninstalled=`echo $pkgconfig_generate |sed 's/.pc$/-uninstalled.pc/'` +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating $pkgconfig_uninstalled" >&5 +printf "%s\n" "$as_me: creating $pkgconfig_uninstalled" >&6;} +cat >conftest.sed < $pkgconfig_uninstalled +if test ! -s $pkgconfig_uninstalled ; then + as_fn_error $? "$pkgconfig_uninstalled is empty" "$LINENO" 5 +fi ; rm conftest.sed # DONE generate $pkgconfig_uninstalled + pkgconfig_requires_add=`echo ${pkgconfig_requires}` +if test ".$pkgconfig_requires_add" != "." ; then + pkgconfig_requires_add="pkg-config $pkgconfig_requires_add" + else pkgconfig_requires_add=":" ; fi +pkgconfig_uninstalled=`echo $pkgconfig_generate |sed 's/.pc$/-uninstalled.sh/'` +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating $pkgconfig_uninstalled" >&5 +printf "%s\n" "$as_me: creating $pkgconfig_uninstalled" >&6;} +cat >conftest.sed <Name:>for option\\; do case \"\$option\" in --list-all|--name) echo > +s>Description: *>\\;\\; --help) pkg-config --help \\; echo Buildscript Of > +s>Version: *>\\;\\; --modversion|--version) echo > +s>Requires:>\\;\\; --requires) echo $pkgconfig_requires_add> +s>Libs: *>\\;\\; --libs) echo > +s>Cflags: *>\\;\\; --cflags) echo > +/--libs)/a\\ + $pkgconfig_requires_add +/--cflags)/a\\ + $pkgconfig_requires_add\\ +;; --variable=*) eval echo '\$'\`echo \$option | sed -e 's/.*=//'\`\\ +;; --uninstalled) exit 0 \\ +;; *) ;; esac done +AXEOF +sed -f conftest.sed $pkgconfig_generate.in > $pkgconfig_uninstalled +if test ! -s $pkgconfig_uninstalled ; then + as_fn_error $? "$pkgconfig_uninstalled is empty" "$LINENO" 5 +fi ; rm conftest.sed # DONE generate $pkgconfig_uninstalled + ;; + "bound_test.sh":F) chmod +x bound_test.sh ;; + "codegen_test.sh":F) chmod +x codegen_test.sh ;; + "pip_test.sh":F) chmod +x pip_test.sh ;; + "flow_test.sh":F) chmod +x flow_test.sh ;; + "schedule_test.sh":F) chmod +x schedule_test.sh ;; + + esac +done # for ac_tag + + +as_fn_exit 0 +_ACEOF +ac_clean_files=$ac_clean_files_save + +test $ac_write_fail = 0 || + as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || as_fn_exit 1 +fi + +# +# CONFIG_SUBDIRS section. +# +if test "$no_recursion" != yes; then + + # Remove --cache-file, --srcdir, and --disable-option-checking arguments + # so they do not pile up. + ac_sub_configure_args= + ac_prev= + eval "set x $ac_configure_args" + shift + for ac_arg + do + if test -n "$ac_prev"; then + ac_prev= + continue + fi + case $ac_arg in + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* \ + | --c=*) + ;; + --config-cache | -C) + ;; + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + ;; + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + ;; + --disable-option-checking) + ;; + *) + case $ac_arg in + *\'*) ac_arg=`printf "%s\n" "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + as_fn_append ac_sub_configure_args " '$ac_arg'" ;; + esac + done + + # Always prepend --prefix to ensure using the same prefix + # in subdir configurations. + ac_arg="--prefix=$prefix" + case $ac_arg in + *\'*) ac_arg=`printf "%s\n" "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + ac_sub_configure_args="'$ac_arg' $ac_sub_configure_args" + + # Pass --silent + if test "$silent" = yes; then + ac_sub_configure_args="--silent $ac_sub_configure_args" + fi + + # Always prepend --disable-option-checking to silence warnings, since + # different subdirs can have different --enable and --with options. + ac_sub_configure_args="--disable-option-checking $ac_sub_configure_args" + + ac_popdir=`pwd` + for ac_dir in : $subdirs; do test "x$ac_dir" = x: && continue + + # Do not complain, so a configure script can configure whichever + # parts of a large source tree are present. + test -d "$srcdir/$ac_dir" || continue + + ac_msg="=== configuring in $ac_dir (`pwd`/$ac_dir)" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: $ac_msg" >&5 + printf "%s\n" "$ac_msg" >&6 + as_dir="$ac_dir"; as_fn_mkdir_p + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`printf "%s\n" "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`printf "%s\n" "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + cd "$ac_dir" + + # Check for configure.gnu first; this name is used for a wrapper for + # Metaconfig's "Configure" on case-insensitive file systems. + if test -f "$ac_srcdir/configure.gnu"; then + ac_sub_configure=$ac_srcdir/configure.gnu + elif test -f "$ac_srcdir/configure"; then + ac_sub_configure=$ac_srcdir/configure + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: no configuration information is in $ac_dir" >&5 +printf "%s\n" "$as_me: WARNING: no configuration information is in $ac_dir" >&2;} + ac_sub_configure= + fi + + # The recursion is here. + if test -n "$ac_sub_configure"; then + # Make the cache file name correct relative to the subdirectory. + case $cache_file in + [\\/]* | ?:[\\/]* ) ac_sub_cache_file=$cache_file ;; + *) # Relative name. + ac_sub_cache_file=$ac_top_build_prefix$cache_file ;; + esac + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: running $SHELL $ac_sub_configure $ac_sub_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_srcdir" >&5 +printf "%s\n" "$as_me: running $SHELL $ac_sub_configure $ac_sub_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_srcdir" >&6;} + # The eval makes quoting arguments work. + eval "\$SHELL \"\$ac_sub_configure\" $ac_sub_configure_args \ + --cache-file=\"\$ac_sub_cache_file\" --srcdir=\"\$ac_srcdir\"" || + as_fn_error $? "$ac_sub_configure failed for $ac_dir" "$LINENO" 5 + fi + + cd "$ac_popdir" + done +fi +if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 +printf "%s\n" "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} +fi + + diff --git a/external/mit/isl/dist/configure.ac b/external/mit/isl/dist/configure.ac new file mode 100644 index 000000000000..a8934381a901 --- /dev/null +++ b/external/mit/isl/dist/configure.ac @@ -0,0 +1,147 @@ +AC_INIT([isl], [0.26], [isl-development@googlegroups.com]) +AC_CONFIG_AUX_DIR([.]) +AC_CONFIG_MACRO_DIR([m4]) +AM_INIT_AUTOMAKE([foreign]) +m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])]) +AC_SUBST(versioninfo) +versioninfo=26:0:3 + +if test "x$prefix" != "xNONE"; then + prefix_wd=`cd $prefix && pwd` + srcdir_wd=`cd $srcdir && pwd` + wd=`pwd` + if test "x$prefix_wd" = "x$srcdir_wd"; then + AC_MSG_ERROR(Installation in source directory not supported) + fi + if test "x$prefix_wd" = "x$wd"; then + AC_MSG_ERROR(Installation in build directory not supported) + fi +fi + +AC_PROG_CC +AC_PROG_CXX +AX_PROG_CC_FOR_BUILD + +AX_CC_MAXOPT +AX_GCC_WARN_UNUSED_RESULT +AX_C___ATTRIBUTE__ + +AX_CXX_COMPILE_STDCXX_11_NO_OVERRIDE +AX_CXX_COMPILE_STDCXX_17([], [optional]) + +AC_PROG_GREP +LT_INIT +AC_PROG_SED +AM_PATH_PYTHON([3.6], [], [:]) +AM_CONDITIONAL([HAVE_PYTHON], [test "$PYTHON" != :]) + +AC_CHECK_PROG(CYGPATH, cygpath, cygpath, []) +AC_CHECK_PROG(PERL, perl, perl, []) +AC_CHECK_PROG(PDFLATEX, pdflatex, pdflatex, []) +AC_CHECK_PROG(POD2HTML, pod2html, pod2html, []) + +AC_SUBST(OS_SRCDIR) +if test "$host_os" = "mingw32" -a -n "$CYGPATH"; then + OS_SRCDIR=`$CYGPATH -m "$srcdir"` +else + OS_SRCDIR="$srcdir" +fi + +AM_CONDITIONAL(GENERATE_DOC, test -n "$PERL" -a -n "$PDFLATEX" -a -n "$POD2HTML") + +AX_CREATE_STDINT_H(include/isl/stdint.h) + +AC_ARG_WITH([int], + [AS_HELP_STRING([--with-int=gmp|imath|imath-32], + [Which package to use to represent + multi-precision integers [default=gmp]])], + [], [with_int=gmp]) +case "$with_int" in +gmp|imath|imath-32) + ;; +*) + AC_MSG_ERROR( + [bad value ${withval} for --with-int (use gmp, imath or imath-32)]) +esac + +AC_SUBST(MP_CPPFLAGS) +AC_SUBST(MP_CFLAGS) +AC_SUBST(MP_LDFLAGS) +AC_SUBST(MP_LIBS) +case "$with_int" in +gmp) + AX_DETECT_GMP + ;; +imath|imath-32) + AX_DETECT_IMATH + ;; +esac +if test "x$with_int" = "ximath-32" -a "x$GCC" = "xyes"; then + MP_CFLAGS="-std=gnu99 $MP_CFLAGS" +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(HAVE_CXX17, test "x$HAVE_CXX17" = "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]) +]) + +AC_CHECK_DECLS(ffs,[],[],[#include ]) +AC_CHECK_DECLS(__builtin_ffs,[],[],[]) +AC_CHECK_DECLS([_BitScanForward],[],[],[#include ]) +if test "x$ac_cv_have_decl_ffs" = xno -a \ + "x$ac_cv_have_decl___builtin_ffs" = xno -a \ + "x$ac_cv_have_decl__BitScanForward" = xno; then + AC_MSG_ERROR([No ffs implementation found]) +fi +AC_CHECK_DECLS([strcasecmp,strncasecmp],[],[],[#include ]) +AC_CHECK_DECLS([_stricmp,_strnicmp],[],[],[#include ]) +if test "x$ac_cv_have_decl_strcasecmp" = xno -a \ + "x$ac_cv_have_decl__stricmp" = xno; then + AC_MSG_ERROR([No strcasecmp implementation found]) +fi +if test "x$ac_cv_have_decl_strncasecmp" = xno -a \ + "x$ac_cv_have_decl__strnicmp" = xno; then + AC_MSG_ERROR([No strncasecmp implementation found]) +fi +AC_CHECK_DECLS([snprintf,_snprintf],[],[],[#include ]) +if test "x$ac_cv_have_decl_snprintf" = xno -a \ + "x$ac_cv_have_decl__snprintf" = xno; then + AC_MSG_ERROR([No snprintf implementation found]) +fi + +AX_SUBMODULE(clang,system|no,no) +AM_CONDITIONAL(HAVE_CLANG, test $with_clang = system) +AM_CONDITIONAL(HAVE_CPP_ISL_H, + [(test $with_clang = system -a "x$HAVE_CXX11" = "x1") || \ + test -f $srcdir/include/isl/cpp.h]) + +AX_SET_WARNING_FLAGS + +AC_SUBST(WARNING_FLAGS) + +PACKAGE_CFLAGS="$MP_CPPFLAGS" +PACKAGE_LDFLAGS="$MP_LDFLAGS" +PACKAGE_LIBS="-lisl $MP_LIBS" +AX_CREATE_PKGCONFIG_INFO + +AX_DETECT_GIT_HEAD + +AH_BOTTOM([#include ]) +AC_CONFIG_HEADERS(isl_config.h) +AC_CONFIG_FILES(isl_srcdir.c) +AC_CONFIG_FILES(Makefile) +AC_CONFIG_FILES(doc/Makefile) +if test $with_clang = system; then + AC_CONFIG_SUBDIRS(interface) +fi +AC_CONFIG_FILES([bound_test.sh], [chmod +x bound_test.sh]) +AC_CONFIG_FILES([codegen_test.sh], [chmod +x codegen_test.sh]) +AC_CONFIG_FILES([pip_test.sh], [chmod +x pip_test.sh]) +AC_CONFIG_FILES([flow_test.sh], [chmod +x flow_test.sh]) +AC_CONFIG_FILES([schedule_test.sh], [chmod +x schedule_test.sh]) +AC_OUTPUT diff --git a/external/mit/isl/dist/cpp/cpp-checked-conversion.h.bot b/external/mit/isl/dist/cpp/cpp-checked-conversion.h.bot new file mode 100644 index 000000000000..35ef16362e12 --- /dev/null +++ b/external/mit/isl/dist/cpp/cpp-checked-conversion.h.bot @@ -0,0 +1,2 @@ + +#endif /* ISL_CPP_CHECKED_CONVERSION */ diff --git a/external/mit/isl/dist/cpp/cpp-checked-conversion.h.top b/external/mit/isl/dist/cpp/cpp-checked-conversion.h.top new file mode 100644 index 000000000000..402fc3dc9c07 --- /dev/null +++ b/external/mit/isl/dist/cpp/cpp-checked-conversion.h.top @@ -0,0 +1,14 @@ +/// These are automatically generated conversions between +/// the default and the checked 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_CHECKED_CONVERSION +#define ISL_CPP_CHECKED_CONVERSION + +#include +#include + diff --git a/external/mit/isl/dist/cpp/cpp-checked.h.bot b/external/mit/isl/dist/cpp/cpp-checked.h.bot new file mode 100644 index 000000000000..4d66f89a9e16 --- /dev/null +++ b/external/mit/isl/dist/cpp/cpp-checked.h.bot @@ -0,0 +1,2 @@ + +#endif /* ISL_CPP_CHECKED */ diff --git a/external/mit/isl/dist/cpp/cpp-checked.h.top b/external/mit/isl/dist/cpp/cpp-checked.h.top new file mode 100644 index 000000000000..6d62fb11037d --- /dev/null +++ b/external/mit/isl/dist/cpp/cpp-checked.h.top @@ -0,0 +1,200 @@ +/// These are automatically generated checked 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_CHECKED +#define ISL_CPP_CHECKED + +#include +#include + +#include +#include +#include +#include +#include + +#if __cplusplus >= 201703L +#include +#include +#endif + +namespace isl { +namespace checked { + +#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); \ + abort(); \ + } while (0) + +/* Class used to check that isl::checked::boolean, + * isl::checked::stat and isl::checked::size values are checked for errors. + */ +struct checker { + bool checked = false; + ~checker() { + ISLPP_ASSERT(checked, "IMPLEMENTATION ERROR: Unchecked state"); + } +}; + +class boolean { +private: + mutable std::shared_ptr check = std::make_shared(); + isl_bool val; + + friend boolean manage(isl_bool val); + boolean(isl_bool val): val(val) {} +public: + static boolean error() { + return boolean(isl_bool_error); + } + boolean() + : val(isl_bool_error) {} + + /* implicit */ boolean(bool val) + : val(val ? isl_bool_true : isl_bool_false) {} + + isl_bool release() { + auto tmp = val; + val = isl_bool_error; + check->checked = true; + return tmp; + } + + bool is_error() const { check->checked = true; return val == isl_bool_error; } + bool is_false() const { check->checked = true; return val == isl_bool_false; } + bool is_true() const { check->checked = true; return val == isl_bool_true; } + + explicit operator bool() const { + ISLPP_ASSERT(check->checked, "IMPLEMENTATION ERROR: Unchecked error state"); + ISLPP_ASSERT(!is_error(), "IMPLEMENTATION ERROR: Unhandled error state"); + return is_true(); + } + + boolean negate() { + if (val == isl_bool_true) + val = isl_bool_false; + else if (val == isl_bool_false) + val = isl_bool_true; + return *this; + } + + boolean operator!() const { + return boolean(*this).negate(); + } +}; + +inline boolean manage(isl_bool val) { + return 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; + } +#if __cplusplus >= 201703L + static void free_user(void *user) { + std::any *p = static_cast(user); + delete p; + } +#endif +}; + +/* Class encapsulating an isl_stat value. + */ +class stat { +private: + mutable std::shared_ptr check = std::make_shared(); + isl_stat val; + + friend stat manage(isl_stat val); + stat(isl_stat val) : val(val) {} +public: + static stat ok() { + return stat(isl_stat_ok); + } + static stat error() { + return stat(isl_stat_error); + } + stat() : val(isl_stat_error) {} + + isl_stat release() { + check->checked = true; + return val; + } + + bool is_error() const { + check->checked = true; + return val == isl_stat_error; + } + bool is_ok() const { + check->checked = true; + return val == isl_stat_ok; + } +}; + +inline stat manage(isl_stat val) +{ + return stat(val); +} + +/* Class encapsulating an isl_size value. + */ +class size { +private: + mutable std::shared_ptr check = std::make_shared(); + isl_size val; + + friend size manage(isl_size val); + size(isl_size val) : val(val) {} +public: + size() : val(isl_size_error) {} + + isl_size release() { + auto tmp = val; + val = isl_size_error; + check->checked = true; + return tmp; + } + + bool is_error() const { + check->checked = true; + return val == isl_size_error; + } + + explicit operator unsigned() const { + ISLPP_ASSERT(check->checked, + "IMPLEMENTATION ERROR: Unchecked error state"); + ISLPP_ASSERT(!is_error(), + "IMPLEMENTATION ERROR: Unhandled error state"); + return val; + } +}; + +inline size manage(isl_size val) +{ + return size(val); +} + +} +} // namespace isl + diff --git a/external/mit/isl/dist/cpp/cpp.h.bot b/external/mit/isl/dist/cpp/cpp.h.bot new file mode 100644 index 000000000000..f98e87c7ce40 --- /dev/null +++ b/external/mit/isl/dist/cpp/cpp.h.bot @@ -0,0 +1,2 @@ + +#endif /* ISL_CPP */ diff --git a/external/mit/isl/dist/cpp/cpp.h.top b/external/mit/isl/dist/cpp/cpp.h.top new file mode 100644 index 000000000000..9af6f48d24b8 --- /dev/null +++ b/external/mit/isl/dist/cpp/cpp.h.top @@ -0,0 +1,267 @@ +/// 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 +#define ISL_CPP + +#include +#include + +#include +#include +#include +#include +#include +#include + +#if __cplusplus >= 201703L +#include +#include +#endif + +/* ISL_USE_EXCEPTIONS should be defined to 1 if exceptions are available. + * gcc and clang define __cpp_exceptions; MSVC and xlC define _CPPUNWIND. + * Older versions of gcc (e.g., 4.9) only define __EXCEPTIONS. + * If exceptions are not available, any error condition will result + * in an abort. + */ +#ifndef ISL_USE_EXCEPTIONS +#if defined(__cpp_exceptions) || defined(_CPPUNWIND) || defined(__EXCEPTIONS) +#define ISL_USE_EXCEPTIONS 1 +#else +#define ISL_USE_EXCEPTIONS 0 +#endif +#endif + +namespace isl { + +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; + } +#if __cplusplus >= 201703L + static void free_user(void *user) { + std::any *p = static_cast(user); + delete p; + } +#endif +}; + +/* Macros hiding try/catch. + * If exceptions are not available, then no exceptions will be thrown and + * there is nothing to catch. + */ +#if ISL_USE_EXCEPTIONS +#define ISL_CPP_TRY try +#define ISL_CPP_CATCH_ALL catch (...) +#else +#define ISL_CPP_TRY if (1) +#define ISL_CPP_CATCH_ALL if (0) +#endif + +#if ISL_USE_EXCEPTIONS + +/* Class capturing isl errors. + * + * The what() return value is stored in a reference counted string + * to ensure that the copy constructor and the assignment operator + * do not throw any exceptions. + */ +class exception : public std::exception { + std::shared_ptr what_str; + +protected: + inline exception(const char *what_arg, const char *msg, + const char *file, int line); +public: + exception() {} + exception(const char *what_arg) { + what_str = std::make_shared(what_arg); + } + static inline void throw_error(enum isl_error error, const char *msg, + const char *file, int line); + virtual const char *what() const noexcept { + return what_str->c_str(); + } + + /* Default behavior on error conditions that occur inside isl calls + * performed from inside the bindings. + * In the case exceptions are available, isl should continue + * without printing a warning since the warning message + * will be included in the exception thrown from inside the bindings. + */ + static constexpr auto on_error = ISL_ON_ERROR_CONTINUE; + /* Wrapper for throwing an exception with the given message. + */ + static void throw_invalid(const char *msg, const char *file, int line) { + throw_error(isl_error_invalid, msg, file, line); + } + static inline void throw_last_error(ctx ctx); +}; + +/* Create an exception of a type described by "what_arg", with + * error message "msg" in line "line" of file "file". + * + * Create a string holding the what() return value that + * corresponds to what isl would have printed. + * If no error message or no error file was set, then use "what_arg" instead. + */ +exception::exception(const char *what_arg, const char *msg, const char *file, + int line) +{ + if (!msg || !file) + what_str = std::make_shared(what_arg); + else + what_str = std::make_shared(std::string(file) + + ":" + std::to_string(line) + ": " + msg); +} + +class exception_abort : public exception { + friend exception; + exception_abort(const char *msg, const char *file, int line) : + exception("execution aborted", msg, file, line) {} +}; + +class exception_alloc : public exception { + friend exception; + exception_alloc(const char *msg, const char *file, int line) : + exception("memory allocation failure", msg, file, line) {} +}; + +class exception_unknown : public exception { + friend exception; + exception_unknown(const char *msg, const char *file, int line) : + exception("unknown failure", msg, file, line) {} +}; + +class exception_internal : public exception { + friend exception; + exception_internal(const char *msg, const char *file, int line) : + exception("internal error", msg, file, line) {} +}; + +class exception_invalid : public exception { + friend exception; + exception_invalid(const char *msg, const char *file, int line) : + exception("invalid argument", msg, file, line) {} +}; + +class exception_quota : public exception { + friend exception; + exception_quota(const char *msg, const char *file, int line) : + exception("quota exceeded", msg, file, line) {} +}; + +class exception_unsupported : public exception { + friend exception; + exception_unsupported(const char *msg, const char *file, int line) : + exception("unsupported operation", msg, file, line) {} +}; + +/* Throw an exception of the class that corresponds to "error", with + * error message "msg" in line "line" of file "file". + * + * isl_error_none is treated as an invalid error type. + */ +void exception::throw_error(enum isl_error error, const char *msg, + const char *file, int line) +{ + switch (error) { + case isl_error_none: + break; + case isl_error_abort: throw exception_abort(msg, file, line); + case isl_error_alloc: throw exception_alloc(msg, file, line); + case isl_error_unknown: throw exception_unknown(msg, file, line); + case isl_error_internal: throw exception_internal(msg, file, line); + case isl_error_invalid: throw exception_invalid(msg, file, line); + case isl_error_quota: throw exception_quota(msg, file, line); + case isl_error_unsupported: + throw exception_unsupported(msg, file, line); + } + + throw exception_invalid("invalid error type", file, line); +} + +/* Throw an exception corresponding to the last error on "ctx" and + * reset the error. + * + * If "ctx" is NULL or if it is not in an error state at the start, + * then an invalid argument exception is thrown. + */ +void exception::throw_last_error(ctx ctx) +{ + enum isl_error error; + const char *msg, *file; + int line; + + error = isl_ctx_last_error(ctx.get()); + msg = isl_ctx_last_error_msg(ctx.get()); + file = isl_ctx_last_error_file(ctx.get()); + line = isl_ctx_last_error_line(ctx.get()); + isl_ctx_reset_error(ctx.get()); + + throw_error(error, msg, file, line); +} + +#else + +#include +#include + +class exception { +public: + /* Default behavior on error conditions that occur inside isl calls + * performed from inside the bindings. + * In the case exceptions are not available, isl should abort. + */ + static constexpr auto on_error = ISL_ON_ERROR_ABORT; + /* Wrapper for throwing an exception with the given message. + * In the case exceptions are not available, print an error and abort. + */ + static void throw_invalid(const char *msg, const char *file, int line) { + fprintf(stderr, "%s:%d: %s\n", file, line, msg); + abort(); + } + /* Throw an exception corresponding to the last + * error on "ctx". + * isl should already abort when an error condition occurs, + * so this function should never be called. + */ + static void throw_last_error(ctx ctx) { + abort(); + } +}; + +#endif + +/* Helper class for setting the on_error and resetting the option + * to the original value when leaving the scope. + */ +class options_scoped_set_on_error { + isl_ctx *ctx; + int saved_on_error; +public: + options_scoped_set_on_error(class ctx ctx, int on_error) { + this->ctx = ctx.get(); + saved_on_error = isl_options_get_on_error(this->ctx); + isl_options_set_on_error(this->ctx, on_error); + } + ~options_scoped_set_on_error() { + isl_options_set_on_error(ctx, saved_on_error); + } +}; + +} // namespace isl + diff --git a/external/mit/isl/dist/cpp/typed_cpp.h.bot b/external/mit/isl/dist/cpp/typed_cpp.h.bot new file mode 100644 index 000000000000..af20081f181d --- /dev/null +++ b/external/mit/isl/dist/cpp/typed_cpp.h.bot @@ -0,0 +1,5 @@ + +} // namespace typed +} // namespace isl + +#endif /* ISL_TYPED_CPP */ diff --git a/external/mit/isl/dist/cpp/typed_cpp.h.top b/external/mit/isl/dist/cpp/typed_cpp.h.top new file mode 100644 index 000000000000..d89eb4102ca0 --- /dev/null +++ b/external/mit/isl/dist/cpp/typed_cpp.h.top @@ -0,0 +1,21 @@ +/// These are automatically generated templated 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_TYPED_CPP +#define ISL_TYPED_CPP + +#include + +#include + +namespace isl { +namespace typed { + +template +struct pair {}; + +struct Anonymous; diff --git a/external/mit/isl/dist/dep.c b/external/mit/isl/dist/dep.c new file mode 100644 index 000000000000..3344a3cb8554 --- /dev/null +++ b/external/mit/isl/dist/dep.c @@ -0,0 +1 @@ +#include "all.h" diff --git a/external/mit/isl/dist/depcomp b/external/mit/isl/dist/depcomp new file mode 100755 index 000000000000..715e34311ed2 --- /dev/null +++ b/external/mit/isl/dist/depcomp @@ -0,0 +1,791 @@ +#! /bin/sh +# depcomp - compile a program generating dependencies as side-effects + +scriptversion=2018-03-07.03; # UTC + +# Copyright (C) 1999-2021 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Originally written by Alexandre Oliva . + +case $1 in + '') + echo "$0: No command. Try '$0 --help' for more information." 1>&2 + exit 1; + ;; + -h | --h*) + cat <<\EOF +Usage: depcomp [--help] [--version] PROGRAM [ARGS] + +Run PROGRAMS ARGS to compile a file, generating dependencies +as side-effects. + +Environment variables: + depmode Dependency tracking mode. + source Source file read by 'PROGRAMS ARGS'. + object Object file output by 'PROGRAMS ARGS'. + DEPDIR directory where to store dependencies. + depfile Dependency file to output. + tmpdepfile Temporary file to use when outputting dependencies. + libtool Whether libtool is used (yes/no). + +Report bugs to . +EOF + exit $? + ;; + -v | --v*) + echo "depcomp $scriptversion" + exit $? + ;; +esac + +# Get the directory component of the given path, and save it in the +# global variables '$dir'. Note that this directory component will +# be either empty or ending with a '/' character. This is deliberate. +set_dir_from () +{ + case $1 in + */*) dir=`echo "$1" | sed -e 's|/[^/]*$|/|'`;; + *) dir=;; + esac +} + +# Get the suffix-stripped basename of the given path, and save it the +# global variable '$base'. +set_base_from () +{ + base=`echo "$1" | sed -e 's|^.*/||' -e 's/\.[^.]*$//'` +} + +# If no dependency file was actually created by the compiler invocation, +# we still have to create a dummy depfile, to avoid errors with the +# Makefile "include basename.Plo" scheme. +make_dummy_depfile () +{ + echo "#dummy" > "$depfile" +} + +# Factor out some common post-processing of the generated depfile. +# Requires the auxiliary global variable '$tmpdepfile' to be set. +aix_post_process_depfile () +{ + # If the compiler actually managed to produce a dependency file, + # post-process it. + if test -f "$tmpdepfile"; then + # Each line is of the form 'foo.o: dependency.h'. + # Do two passes, one to just change these to + # $object: dependency.h + # and one to simply output + # dependency.h: + # which is needed to avoid the deleted-header problem. + { sed -e "s,^.*\.[$lower]*:,$object:," < "$tmpdepfile" + sed -e "s,^.*\.[$lower]*:[$tab ]*,," -e 's,$,:,' < "$tmpdepfile" + } > "$depfile" + rm -f "$tmpdepfile" + else + make_dummy_depfile + fi +} + +# A tabulation character. +tab=' ' +# A newline character. +nl=' +' +# Character ranges might be problematic outside the C locale. +# These definitions help. +upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ +lower=abcdefghijklmnopqrstuvwxyz +digits=0123456789 +alpha=${upper}${lower} + +if test -z "$depmode" || test -z "$source" || test -z "$object"; then + echo "depcomp: Variables source, object and depmode must be set" 1>&2 + exit 1 +fi + +# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. +depfile=${depfile-`echo "$object" | + sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} +tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} + +rm -f "$tmpdepfile" + +# Avoid interferences from the environment. +gccflag= dashmflag= + +# Some modes work just like other modes, but use different flags. We +# parameterize here, but still list the modes in the big case below, +# to make depend.m4 easier to write. Note that we *cannot* use a case +# here, because this file can only contain one case statement. +if test "$depmode" = hp; then + # HP compiler uses -M and no extra arg. + gccflag=-M + depmode=gcc +fi + +if test "$depmode" = dashXmstdout; then + # This is just like dashmstdout with a different argument. + dashmflag=-xM + depmode=dashmstdout +fi + +cygpath_u="cygpath -u -f -" +if test "$depmode" = msvcmsys; then + # This is just like msvisualcpp but w/o cygpath translation. + # Just convert the backslash-escaped backslashes to single forward + # slashes to satisfy depend.m4 + cygpath_u='sed s,\\\\,/,g' + depmode=msvisualcpp +fi + +if test "$depmode" = msvc7msys; then + # This is just like msvc7 but w/o cygpath translation. + # Just convert the backslash-escaped backslashes to single forward + # slashes to satisfy depend.m4 + cygpath_u='sed s,\\\\,/,g' + depmode=msvc7 +fi + +if test "$depmode" = xlc; then + # IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information. + gccflag=-qmakedep=gcc,-MF + depmode=gcc +fi + +case "$depmode" in +gcc3) +## gcc 3 implements dependency tracking that does exactly what +## we want. Yay! Note: for some reason libtool 1.4 doesn't like +## it if -MD -MP comes after the -MF stuff. Hmm. +## Unfortunately, FreeBSD c89 acceptance of flags depends upon +## the command line argument order; so add the flags where they +## appear in depend2.am. Note that the slowdown incurred here +## affects only configure: in makefiles, %FASTDEP% shortcuts this. + for arg + do + case $arg in + -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;; + *) set fnord "$@" "$arg" ;; + esac + shift # fnord + shift # $arg + done + "$@" + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + mv "$tmpdepfile" "$depfile" + ;; + +gcc) +## Note that this doesn't just cater to obsosete pre-3.x GCC compilers. +## but also to in-use compilers like IMB xlc/xlC and the HP C compiler. +## (see the conditional assignment to $gccflag above). +## There are various ways to get dependency output from gcc. Here's +## why we pick this rather obscure method: +## - Don't want to use -MD because we'd like the dependencies to end +## up in a subdir. Having to rename by hand is ugly. +## (We might end up doing this anyway to support other compilers.) +## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like +## -MM, not -M (despite what the docs say). Also, it might not be +## supported by the other compilers which use the 'gcc' depmode. +## - Using -M directly means running the compiler twice (even worse +## than renaming). + if test -z "$gccflag"; then + gccflag=-MD, + fi + "$@" -Wp,"$gccflag$tmpdepfile" + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + # The second -e expression handles DOS-style file names with drive + # letters. + sed -e 's/^[^:]*: / /' \ + -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" +## This next piece of magic avoids the "deleted header file" problem. +## The problem is that when a header file which appears in a .P file +## is deleted, the dependency causes make to die (because there is +## typically no way to rebuild the header). We avoid this by adding +## dummy dependencies for each header file. Too bad gcc doesn't do +## this for us directly. +## Some versions of gcc put a space before the ':'. On the theory +## that the space means something, we add a space to the output as +## well. hp depmode also adds that space, but also prefixes the VPATH +## to the object. Take care to not repeat it in the output. +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \ + | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +sgi) + if test "$libtool" = yes; then + "$@" "-Wp,-MDupdate,$tmpdepfile" + else + "$@" -MDupdate "$tmpdepfile" + fi + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + + if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files + echo "$object : \\" > "$depfile" + # Clip off the initial element (the dependent). Don't try to be + # clever and replace this with sed code, as IRIX sed won't handle + # lines with more than a fixed number of characters (4096 in + # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; + # the IRIX cc adds comments like '#:fec' to the end of the + # dependency line. + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' \ + | tr "$nl" ' ' >> "$depfile" + echo >> "$depfile" + # The second pass generates a dummy entry for each header file. + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ + >> "$depfile" + else + make_dummy_depfile + fi + rm -f "$tmpdepfile" + ;; + +xlc) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +aix) + # The C for AIX Compiler uses -M and outputs the dependencies + # in a .u file. In older versions, this file always lives in the + # current directory. Also, the AIX compiler puts '$object:' at the + # start of each line; $object doesn't have directory information. + # Version 6 uses the directory in both cases. + set_dir_from "$object" + set_base_from "$object" + if test "$libtool" = yes; then + tmpdepfile1=$dir$base.u + tmpdepfile2=$base.u + tmpdepfile3=$dir.libs/$base.u + "$@" -Wc,-M + else + tmpdepfile1=$dir$base.u + tmpdepfile2=$dir$base.u + tmpdepfile3=$dir$base.u + "$@" -M + fi + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + do + test -f "$tmpdepfile" && break + done + aix_post_process_depfile + ;; + +tcc) + # tcc (Tiny C Compiler) understand '-MD -MF file' since version 0.9.26 + # FIXME: That version still under development at the moment of writing. + # Make that this statement remains true also for stable, released + # versions. + # It will wrap lines (doesn't matter whether long or short) with a + # trailing '\', as in: + # + # foo.o : \ + # foo.c \ + # foo.h \ + # + # It will put a trailing '\' even on the last line, and will use leading + # spaces rather than leading tabs (at least since its commit 0394caf7 + # "Emit spaces for -MD"). + "$@" -MD -MF "$tmpdepfile" + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + # Each non-empty line is of the form 'foo.o : \' or ' dep.h \'. + # We have to change lines of the first kind to '$object: \'. + sed -e "s|.*:|$object :|" < "$tmpdepfile" > "$depfile" + # And for each line of the second kind, we have to emit a 'dep.h:' + # dummy dependency, to avoid the deleted-header problem. + sed -n -e 's|^ *\(.*\) *\\$|\1:|p' < "$tmpdepfile" >> "$depfile" + rm -f "$tmpdepfile" + ;; + +## The order of this option in the case statement is important, since the +## shell code in configure will try each of these formats in the order +## listed in this file. A plain '-MD' option would be understood by many +## compilers, so we must ensure this comes after the gcc and icc options. +pgcc) + # Portland's C compiler understands '-MD'. + # Will always output deps to 'file.d' where file is the root name of the + # source file under compilation, even if file resides in a subdirectory. + # The object file name does not affect the name of the '.d' file. + # pgcc 10.2 will output + # foo.o: sub/foo.c sub/foo.h + # and will wrap long lines using '\' : + # foo.o: sub/foo.c ... \ + # sub/foo.h ... \ + # ... + set_dir_from "$object" + # Use the source, not the object, to determine the base name, since + # that's sadly what pgcc will do too. + set_base_from "$source" + tmpdepfile=$base.d + + # For projects that build the same source file twice into different object + # files, the pgcc approach of using the *source* file root name can cause + # problems in parallel builds. Use a locking strategy to avoid stomping on + # the same $tmpdepfile. + lockdir=$base.d-lock + trap " + echo '$0: caught signal, cleaning up...' >&2 + rmdir '$lockdir' + exit 1 + " 1 2 13 15 + numtries=100 + i=$numtries + while test $i -gt 0; do + # mkdir is a portable test-and-set. + if mkdir "$lockdir" 2>/dev/null; then + # This process acquired the lock. + "$@" -MD + stat=$? + # Release the lock. + rmdir "$lockdir" + break + else + # If the lock is being held by a different process, wait + # until the winning process is done or we timeout. + while test -d "$lockdir" && test $i -gt 0; do + sleep 1 + i=`expr $i - 1` + done + fi + i=`expr $i - 1` + done + trap - 1 2 13 15 + if test $i -le 0; then + echo "$0: failed to acquire lock after $numtries attempts" >&2 + echo "$0: check lockdir '$lockdir'" >&2 + exit 1 + fi + + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + # Each line is of the form `foo.o: dependent.h', + # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. + # Do two passes, one to just change these to + # `$object: dependent.h' and one to simply `dependent.h:'. + sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process this invocation + # correctly. Breaking it into two sed invocations is a workaround. + sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" \ + | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp2) + # The "hp" stanza above does not work with aCC (C++) and HP's ia64 + # compilers, which have integrated preprocessors. The correct option + # to use with these is +Maked; it writes dependencies to a file named + # 'foo.d', which lands next to the object file, wherever that + # happens to be. + # Much of this is similar to the tru64 case; see comments there. + set_dir_from "$object" + set_base_from "$object" + if test "$libtool" = yes; then + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir.libs/$base.d + "$@" -Wc,+Maked + else + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir$base.d + "$@" +Maked + fi + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile1" "$tmpdepfile2" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + sed -e "s,^.*\.[$lower]*:,$object:," "$tmpdepfile" > "$depfile" + # Add 'dependent.h:' lines. + sed -ne '2,${ + s/^ *// + s/ \\*$// + s/$/:/ + p + }' "$tmpdepfile" >> "$depfile" + else + make_dummy_depfile + fi + rm -f "$tmpdepfile" "$tmpdepfile2" + ;; + +tru64) + # The Tru64 compiler uses -MD to generate dependencies as a side + # effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'. + # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put + # dependencies in 'foo.d' instead, so we check for that too. + # Subdirectories are respected. + set_dir_from "$object" + set_base_from "$object" + + if test "$libtool" = yes; then + # Libtool generates 2 separate objects for the 2 libraries. These + # two compilations output dependencies in $dir.libs/$base.o.d and + # in $dir$base.o.d. We have to check for both files, because + # one of the two compilations can be disabled. We should prefer + # $dir$base.o.d over $dir.libs/$base.o.d because the latter is + # automatically cleaned when .libs/ is deleted, while ignoring + # the former would cause a distcleancheck panic. + tmpdepfile1=$dir$base.o.d # libtool 1.5 + tmpdepfile2=$dir.libs/$base.o.d # Likewise. + tmpdepfile3=$dir.libs/$base.d # Compaq CCC V6.2-504 + "$@" -Wc,-MD + else + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir$base.d + tmpdepfile3=$dir$base.d + "$@" -MD + fi + + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + do + test -f "$tmpdepfile" && break + done + # Same post-processing that is required for AIX mode. + aix_post_process_depfile + ;; + +msvc7) + if test "$libtool" = yes; then + showIncludes=-Wc,-showIncludes + else + showIncludes=-showIncludes + fi + "$@" $showIncludes > "$tmpdepfile" + stat=$? + grep -v '^Note: including file: ' "$tmpdepfile" + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + # The first sed program below extracts the file names and escapes + # backslashes for cygpath. The second sed program outputs the file + # name when reading, but also accumulates all include files in the + # hold buffer in order to output them again at the end. This only + # works with sed implementations that can handle large buffers. + sed < "$tmpdepfile" -n ' +/^Note: including file: *\(.*\)/ { + s//\1/ + s/\\/\\\\/g + p +}' | $cygpath_u | sort -u | sed -n ' +s/ /\\ /g +s/\(.*\)/'"$tab"'\1 \\/p +s/.\(.*\) \\/\1:/ +H +$ { + s/.*/'"$tab"'/ + G + p +}' >> "$depfile" + echo >> "$depfile" # make sure the fragment doesn't end with a backslash + rm -f "$tmpdepfile" + ;; + +msvc7msys) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +#nosideeffect) + # This comment above is used by automake to tell side-effect + # dependency tracking mechanisms from slower ones. + +dashmstdout) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout, regardless of -o. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + # Remove '-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + test -z "$dashmflag" && dashmflag=-M + # Require at least two characters before searching for ':' + # in the target name. This is to cope with DOS-style filenames: + # a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise. + "$@" $dashmflag | + sed "s|^[$tab ]*[^:$tab ][^:][^:]*:[$tab ]*|$object: |" > "$tmpdepfile" + rm -f "$depfile" + cat < "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process this sed invocation + # correctly. Breaking it into two sed invocations is a workaround. + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ + | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +dashXmstdout) + # This case only exists to satisfy depend.m4. It is never actually + # run, as this mode is specially recognized in the preamble. + exit 1 + ;; + +makedepend) + "$@" || exit $? + # Remove any Libtool call + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + # X makedepend + shift + cleared=no eat=no + for arg + do + case $cleared in + no) + set ""; shift + cleared=yes ;; + esac + if test $eat = yes; then + eat=no + continue + fi + case "$arg" in + -D*|-I*) + set fnord "$@" "$arg"; shift ;; + # Strip any option that makedepend may not understand. Remove + # the object too, otherwise makedepend will parse it as a source file. + -arch) + eat=yes ;; + -*|$object) + ;; + *) + set fnord "$@" "$arg"; shift ;; + esac + done + obj_suffix=`echo "$object" | sed 's/^.*\././'` + touch "$tmpdepfile" + ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" + rm -f "$depfile" + # makedepend may prepend the VPATH from the source file name to the object. + # No need to regex-escape $object, excess matching of '.' is harmless. + sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process the last invocation + # correctly. Breaking it into two sed invocations is a workaround. + sed '1,2d' "$tmpdepfile" \ + | tr ' ' "$nl" \ + | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ + | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" "$tmpdepfile".bak + ;; + +cpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + # Remove '-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + "$@" -E \ + | sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ + -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ + | sed '$ s: \\$::' > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + cat < "$tmpdepfile" >> "$depfile" + sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvisualcpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + IFS=" " + for arg + do + case "$arg" in + -o) + shift + ;; + $object) + shift + ;; + "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") + set fnord "$@" + shift + shift + ;; + *) + set fnord "$@" "$arg" + shift + shift + ;; + esac + done + "$@" -E 2>/dev/null | + sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile" + echo "$tab" >> "$depfile" + sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvcmsys) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +none) + exec "$@" + ;; + +*) + echo "Unknown depmode $depmode" 1>&2 + exit 1 + ;; +esac + +exit 0 + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'before-save-hook 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC0" +# time-stamp-end: "; # UTC" +# End: diff --git a/external/mit/isl/dist/doc/CodingStyle b/external/mit/isl/dist/doc/CodingStyle new file mode 100644 index 000000000000..21f2e56a5712 --- /dev/null +++ b/external/mit/isl/dist/doc/CodingStyle @@ -0,0 +1,42 @@ +This document describes some aspects of the coding style of isl, +which is similar to that of the linux kernel and git. + +The general rule is to use the same style as that of the surrounding code. + +More specific rules: + - every line should have at most 80 columns + - use tabs for indentation, where a tab counts for 8 characters + - use single spaces around binary operators such as '+', '-', '=', '!=' + - no space after unary operators such as '!' + - use a single space after a comma and a semicolon + (except at the end of a line) + - no space between function name and arguments + - use a single space after control keywords such as if, for and while + - use a single space between the type of a cast and the value + that is being cast + - no whitespace at the end of a line + - opening brace of a function is placed on a new line + - opening brace of other blocks stays on the same line + - the body of a control statement is placed on the next line(s) + - an else appears on the same line as the closing brace of + the then branch, if there is such a closing brace + - if either the then or the else branch of an if has braces, + then they both have braces + - no parentheses around argument of return keyword + - use only C style comments (/* ... */) + - no comments inside function bodies; + if some part of a function deserves additional comments, then + extract it out into a separate function first + - no #ifs inside function bodies + - variables are declared at the start of a block, before any + other statements + +There are some exceptions to the general rule of using +the same style as the surrounding code, most notably +when the surrounding code is very old. +In particular, an "isl_space" used to be called "isl_dim" and +some variables of this type are still called "dim" or some variant thereof. +New variables of this type should be called "space" or a more specific name. +Some old functions do not have memory management annotations yet. +All new functions should have memory management annotations, +whenever appropriate diff --git a/external/mit/isl/dist/doc/Makefile.am b/external/mit/isl/dist/doc/Makefile.am new file mode 100644 index 000000000000..1d61dd7775a4 --- /dev/null +++ b/external/mit/isl/dist/doc/Makefile.am @@ -0,0 +1,32 @@ + +CLEANFILES = \ + manual.toc \ + manual.bbl \ + version.tex \ + user.tex \ + manual.pdf \ + manual.aux \ + manual.out \ + manual.blg \ + manual.log \ + manual.brf \ + manual.bcf \ + manual.run.xml + +if GENERATE_DOC +export TEXINPUTS := $(srcdir):$(TEXINPUTS) +export BIBINPUTS := $(srcdir):$(BIBINPUTS) +export BSTINPUTS := $(srcdir):$(BSTINPUTS) + +user.tex: user.pod + $(PERL) $(srcdir)/mypod2latex $< $@ +manual.pdf: manual.tex user.tex $(srcdir)/implementation.tex reading.tex + (cd ..; echo "@GIT_HEAD_VERSION@") > version.tex + $(PDFLATEX) $< + biber manual + $(PDFLATEX) $< + $(PDFLATEX) $< +user.html: user.pod + (cd ..; echo "@GIT_HEAD_VERSION@") > version + $(POD2HTML) --infile=$< --outfile=$@ --title="Integer Set Library: Manual [version `cat version`]" +endif diff --git a/external/mit/isl/dist/doc/Makefile.in b/external/mit/isl/dist/doc/Makefile.in new file mode 100644 index 000000000000..3152d22afa8c --- /dev/null +++ b/external/mit/isl/dist/doc/Makefile.in @@ -0,0 +1,532 @@ +# Makefile.in generated by automake 1.16.5 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2021 Free Software Foundation, Inc. + +# This Makefile.in 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. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = doc +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ax_c___attribute__.m4 \ + $(top_srcdir)/m4/ax_cc_maxopt.m4 \ + $(top_srcdir)/m4/ax_check_compile_flag.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_cxx_compile_stdcxx_11_no_override.m4 \ + $(top_srcdir)/m4/ax_cxx_compile_stdcxx_17.m4 \ + $(top_srcdir)/m4/ax_detect_git_head.m4 \ + $(top_srcdir)/m4/ax_detect_gmp.m4 \ + $(top_srcdir)/m4/ax_detect_imath.m4 \ + $(top_srcdir)/m4/ax_gcc_archflag.m4 \ + $(top_srcdir)/m4/ax_gcc_warn_unused_result.m4 \ + $(top_srcdir)/m4/ax_gcc_x86_cpuid.m4 \ + $(top_srcdir)/m4/ax_prog_cc_for_build.m4 \ + $(top_srcdir)/m4/ax_set_warning_flags.m4 \ + $(top_srcdir)/m4/ax_submodule.m4 $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/isl_config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +SOURCES = +DIST_SOURCES = +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +am__DIST_COMMON = $(srcdir)/Makefile.in +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BUILD_EXEEXT = @BUILD_EXEEXT@ +BUILD_OBJEXT = @BUILD_OBJEXT@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CCDEPMODE_FOR_BUILD = @CCDEPMODE_FOR_BUILD@ +CC_FOR_BUILD = @CC_FOR_BUILD@ +CFLAGS = @CFLAGS@ +CFLAGS_FOR_BUILD = @CFLAGS_FOR_BUILD@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CPPFLAGS_FOR_BUILD = @CPPFLAGS_FOR_BUILD@ +CPP_FOR_BUILD = @CPP_FOR_BUILD@ +CSCOPE = @CSCOPE@ +CTAGS = @CTAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH = @CYGPATH@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ETAGS = @ETAGS@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GIT_HEAD = @GIT_HEAD@ +GIT_HEAD_ID = @GIT_HEAD_ID@ +GIT_HEAD_VERSION = @GIT_HEAD_VERSION@ +GREP = @GREP@ +HAVE_CXX11 = @HAVE_CXX11@ +HAVE_CXX17 = @HAVE_CXX17@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LDFLAGS_FOR_BUILD = @LDFLAGS_FOR_BUILD@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +MP_CFLAGS = @MP_CFLAGS@ +MP_CPPFLAGS = @MP_CPPFLAGS@ +MP_LDFLAGS = @MP_LDFLAGS@ +MP_LIBS = @MP_LIBS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OS_SRCDIR = @OS_SRCDIR@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +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@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +WARNING_FLAGS = @WARNING_FLAGS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CC_FOR_BUILD = @ac_ct_CC_FOR_BUILD@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +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@ +srcdir = @srcdir@ +subdirs = @subdirs@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +versioninfo = @versioninfo@ +CLEANFILES = \ + manual.toc \ + manual.bbl \ + version.tex \ + user.tex \ + manual.pdf \ + manual.aux \ + manual.out \ + manual.blg \ + manual.log \ + manual.brf \ + manual.bcf \ + manual.run.xml + +all: all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign doc/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign doc/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +tags TAGS: + +ctags CTAGS: + +cscope cscopelist: + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: all all-am check check-am clean clean-generic clean-libtool \ + cscopelist-am ctags-am distclean distclean-generic \ + distclean-libtool distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags-am uninstall uninstall-am + +.PRECIOUS: Makefile + + +@GENERATE_DOC_TRUE@export TEXINPUTS := $(srcdir):$(TEXINPUTS) +@GENERATE_DOC_TRUE@export BIBINPUTS := $(srcdir):$(BIBINPUTS) +@GENERATE_DOC_TRUE@export BSTINPUTS := $(srcdir):$(BSTINPUTS) + +@GENERATE_DOC_TRUE@user.tex: user.pod +@GENERATE_DOC_TRUE@ $(PERL) $(srcdir)/mypod2latex $< $@ +@GENERATE_DOC_TRUE@manual.pdf: manual.tex user.tex $(srcdir)/implementation.tex reading.tex +@GENERATE_DOC_TRUE@ (cd ..; echo "@GIT_HEAD_VERSION@") > version.tex +@GENERATE_DOC_TRUE@ $(PDFLATEX) $< +@GENERATE_DOC_TRUE@ biber manual +@GENERATE_DOC_TRUE@ $(PDFLATEX) $< +@GENERATE_DOC_TRUE@ $(PDFLATEX) $< +@GENERATE_DOC_TRUE@user.html: user.pod +@GENERATE_DOC_TRUE@ (cd ..; echo "@GIT_HEAD_VERSION@") > version +@GENERATE_DOC_TRUE@ $(POD2HTML) --infile=$< --outfile=$@ --title="Integer Set Library: Manual [version `cat version`]" + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/external/mit/isl/dist/doc/SubmittingPatches b/external/mit/isl/dist/doc/SubmittingPatches new file mode 100644 index 000000000000..5a59a12956e9 --- /dev/null +++ b/external/mit/isl/dist/doc/SubmittingPatches @@ -0,0 +1,53 @@ +[Mostly copied from git's SubmittingPatches] + + Commits: + + - make commits of logical units + - check for unnecessary whitespace with "git diff --check" + before committing + - do not check in commented out code or unneeded files + - the first line of the commit message should be a short + description and should skip the full stop + - the body should provide a meaningful commit message, which + includes motivation for the change, and contrasts + its implementation with previous behaviour + - the lines of this body should have at most 76 columns + - if you want your work included in isl.git, add a + "Signed-off-by: Your Name " line to the + commit message (or just use the option "-s" when + committing) to confirm that you agree to the Developer's + Certificate of Origin + - make sure that you have tests for the bug you are fixing + - make sure that the test suite passes after your commit + + Patch: + + - use "git format-patch -M" to create the patch + - do not PGP sign your patch + - send a single patch per mail, e.g., using git-send-email(1) + - do not attach your patch, but read in the mail + body, unless you cannot teach your mailer to + leave the formatting of the patch alone. + - be careful doing cut & paste into your mailer, not to + corrupt whitespaces. + - provide additional information (which is unsuitable for + the commit message) between the "---" and the diffstat + - if you change, add, or remove a command line option or + make some other user interface change, the associated + documentation should be updated as well. + - if your name is not writable in ASCII, make sure that + you send off a message in the correct encoding. + - send the patch to the development mailing list + (isl-development@googlegroups.com). If you use + git-send-email(1), please test it first by sending email + to yourself. + + Revisions: + + - add the revision number inside square brackets to + the subject line (e.g., use --subject-prefix='PATCH v2' + when creating the patch) + - recall the major issues discovered during the previous + review and explain how you addressed them or why you + disagree. Do so either in a cover letter, between the + "---" and the diffstat or in a separate message. diff --git a/external/mit/isl/dist/doc/implementation.tex b/external/mit/isl/dist/doc/implementation.tex new file mode 100644 index 000000000000..698adb929bef --- /dev/null +++ b/external/mit/isl/dist/doc/implementation.tex @@ -0,0 +1,2049 @@ +\section{Sets and Relations} + +\begin{definition}[Polyhedral Set] +A {\em polyhedral set}\index{polyhedral set} $S$ is a finite union of basic sets +$S = \bigcup_i S_i$, each of which can be represented using affine +constraints +$$ +S_i : \Z^n \to 2^{\Z^d} : \vec s \mapsto +S_i(\vec s) = +\{\, \vec x \in \Z^d \mid \exists \vec z \in \Z^e : +A \vec x + B \vec s + D \vec z + \vec c \geq \vec 0 \,\} +, +$$ +with $A \in \Z^{m \times d}$, +$B \in \Z^{m \times n}$, +$D \in \Z^{m \times e}$ +and $\vec c \in \Z^m$. +\end{definition} + +\begin{definition}[Parameter Domain of a Set] +Let $S \in \Z^n \to 2^{\Z^d}$ be a set. +The {\em parameter domain} of $S$ is the set +$$\pdom S \coloneqq \{\, \vec s \in \Z^n \mid S(\vec s) \ne \emptyset \,\}.$$ +\end{definition} + +\begin{definition}[Polyhedral Relation] +A {\em polyhedral relation}\index{polyhedral relation} +$R$ is a finite union of basic relations +$R = \bigcup_i R_i$ of type +$\Z^n \to 2^{\Z^{d_1+d_2}}$, +each of which can be represented using affine +constraints +$$ +R_i = \vec s \mapsto +R_i(\vec s) = +\{\, \vec x_1 \to \vec x_2 \in \Z^{d_1} \times \Z^{d_2} +\mid \exists \vec z \in \Z^e : +A_1 \vec x_1 + A_2 \vec x_2 + B \vec s + D \vec z + \vec c \geq \vec 0 \,\} +, +$$ +with $A_i \in \Z^{m \times d_i}$, +$B \in \Z^{m \times n}$, +$D \in \Z^{m \times e}$ +and $\vec c \in \Z^m$. +\end{definition} + +\begin{definition}[Parameter Domain of a Relation] +Let $R \in \Z^n \to 2^{\Z^{d+d}}$ be a relation. +The {\em parameter domain} of $R$ is the set +$$\pdom R \coloneqq \{\, \vec s \in \Z^n \mid R(\vec s) \ne \emptyset \,\}.$$ +\end{definition} + +\begin{definition}[Domain of a Relation] +Let $R \in \Z^n \to 2^{\Z^{d+d}}$ be a relation. +The {\em domain} of $R$ is the polyhedral set +$$\domain R \coloneqq \vec s \mapsto +\{\, \vec x_1 \in \Z^{d_1} \mid \exists \vec x_2 \in \Z^{d_2} : +(\vec x_1, \vec x_2) \in R(\vec s) \,\} +. +$$ +\end{definition} + +\begin{definition}[Range of a Relation] +Let $R \in \Z^n \to 2^{\Z^{d+d}}$ be a relation. +The {\em range} of $R$ is the polyhedral set +$$ +\range R \coloneqq \vec s \mapsto +\{\, \vec x_2 \in \Z^{d_2} \mid \exists \vec x_1 \in \Z^{d_1} : +(\vec x_1, \vec x_2) \in R(\vec s) \,\} +. +$$ +\end{definition} + +\begin{definition}[Composition of Relations] +Let $R \in \Z^n \to 2^{\Z^{d_1+d_2}}$ and +$S \in \Z^n \to 2^{\Z^{d_2+d_3}}$ be two relations, +then the composition of +$R$ and $S$ is defined as +$$ +S \circ R \coloneqq +\vec s \mapsto +\{\, \vec x_1 \to \vec x_3 \in \Z^{d_1} \times \Z^{d_3} +\mid \exists \vec x_2 \in \Z^{d_2} : +\vec x_1 \to \vec x_2 \in R(\vec s) \wedge +\vec x_2 \to \vec x_3 \in S(\vec s) +\,\} +. +$$ +\end{definition} + +\begin{definition}[Difference Set of a Relation] +Let $R \in \Z^n \to 2^{\Z^{d+d}}$ be a relation. +The difference set ($\Delta \, R$) of $R$ is the set +of differences between image elements and the corresponding +domain elements, +$$ +\diff R \coloneqq +\vec s \mapsto +\{\, \vec \delta \in \Z^{d} \mid \exists \vec x \to \vec y \in R : +\vec \delta = \vec y - \vec x +\,\} +$$ +\end{definition} + +\section{Simple Hull}\label{s:simple hull} + +It is sometimes useful to have a single +basic set or basic relation that contains a given set or relation. +For rational sets, the obvious choice would be to compute the +(rational) convex hull. For integer sets, the obvious choice +would be the integer hull. +However, {\tt isl} currently does not support an integer hull operation +and even if it did, it would be fairly expensive to compute. +The convex hull operation is supported, but it is also fairly +expensive to compute given only an implicit representation. + +Usually, it is not required to compute the exact integer hull, +and an overapproximation of this hull is sufficient. +The ``simple hull'' of a set is such an overapproximation +and it is defined as the (inclusion-wise) smallest basic set +that is described by constraints that are translates of +the constraints in the input set. +This means that the simple hull is relatively cheap to compute +and that the number of constraints in the simple hull is no +larger than the number of constraints in the input. +\begin{definition}[Simple Hull of a Set] +The {\em simple hull} of a set +$S = \bigcup_{1 \le i \le v} S_i$, with +$$ +S : \Z^n \to 2^{\Z^d} : \vec s \mapsto +S(\vec s) = +\left\{\, \vec x \in \Z^d \mid \exists \vec z \in \Z^e : +\bigvee_{1 \le i \le v} +A_i \vec x + B_i \vec s + D_i \vec z + \vec c_i \geq \vec 0 \,\right\} +$$ +is the set +$$ +H : \Z^n \to 2^{\Z^d} : \vec s \mapsto +S(\vec s) = +\left\{\, \vec x \in \Z^d \mid \exists \vec z \in \Z^e : +\bigwedge_{1 \le i \le v} +A_i \vec x + B_i \vec s + D_i \vec z + \vec c_i + \vec K_i \geq \vec 0 +\,\right\} +, +$$ +with $\vec K_i$ the (component-wise) smallest non-negative integer vectors +such that $S \subseteq H$. +\end{definition} +The $\vec K_i$ can be obtained by solving a number of +LP problems, one for each element of each $\vec K_i$. +If any LP problem is unbounded, then the corresponding constraint +is dropped. + +\section{Parametric Integer Programming} + +\subsection{Introduction}\label{s:intro} + +Parametric integer programming \parencite{Feautrier88parametric} +is used to solve many problems within the context of the polyhedral model. +Here, we are mainly interested in dependence analysis \parencite{Fea91} +and in computing a unique representation for existentially quantified +variables. The latter operation has been used for counting elements +in sets involving such variables +\parencite{BouletRe98,Verdoolaege2005experiences} and lies at the core +of the internal representation of {\tt isl}. + +Parametric integer programming was first implemented in \texttt{PipLib}. +An alternative method for parametric integer programming +was later implemented in {\tt barvinok} \cite{barvinok-0.22}. +This method is not based on Feautrier's algorithm, but on rational +generating functions \cite{Woods2003short} and was inspired by the +``digging'' technique of \textcite{DeLoera2004Three} for solving +non-parametric integer programming problems. + +In the following sections, we briefly recall the dual simplex +method combined with Gomory cuts and describe some extensions +and optimizations. The main algorithm is applied to a matrix +data structure known as a tableau. In case of parametric problems, +there are two tableaus, one for the main problem and one for +the constraints on the parameters, known as the context tableau. +The handling of the context tableau is described in \autoref{s:context}. + +\subsection{The Dual Simplex Method} + +Tableaus can be represented in several slightly different ways. +In {\tt isl}, the dual simplex method uses the same representation +as that used by its incremental LP solver based on the \emph{primal} +simplex method. The implementation of this LP solver is based +on that of {\tt Simplify} \parencite{Detlefs2005simplify}, which, in turn, +was derived from the work of \textcite{Nelson1980phd}. +In the original \parencite{Nelson1980phd}, the tableau was implemented +as a sparse matrix, but neither {\tt Simplify} nor the current +implementation of {\tt isl} does so. + +Given some affine constraints on the variables, +$A \vec x + \vec b \ge \vec 0$, the tableau represents the relationship +between the variables $\vec x$ and non-negative variables +$\vec y = A \vec x + \vec b$ corresponding to the constraints. +The initial tableau contains $\begin{pmatrix} +\vec b & A +\end{pmatrix}$ and expresses the constraints $\vec y$ in the rows in terms +of the variables $\vec x$ in the columns. The main operation defined +on a tableau exchanges a column and a row variable and is called a pivot. +During this process, some coefficients may become rational. +As in the \texttt{PipLib} implementation, +{\tt isl} maintains a shared denominator per row. +The sample value of a tableau is one where each column variable is assigned +zero and each row variable is assigned the constant term of the row. +This sample value represents a valid solution if each constraint variable +is assigned a non-negative value, i.e., if the constant terms of +rows corresponding to constraints are all non-negative. + +The dual simplex method starts from an initial sample value that +may be invalid, but that is known to be (lexicographically) no +greater than any solution, and gradually increments this sample value +through pivoting until a valid solution is obtained. +In particular, each pivot exchanges a row variable +$r = -n + \sum_i a_i \, c_i$ with negative +sample value $-n$ with a column variable $c_j$ +such that $a_j > 0$. Since $c_j = (n + r - \sum_{i\ne j} a_i \, c_i)/a_j$, +the new row variable will have a positive sample value $n$. +If no such column can be found, then the problem is infeasible. +By always choosing the column that leads to the (lexicographically) +smallest increment in the variables $\vec x$, +the first solution found is guaranteed to be the (lexicographically) +minimal solution \cite{Feautrier88parametric}. +In order to be able to determine the smallest increment, the tableau +is (implicitly) extended with extra rows defining the original +variables in terms of the column variables. +If we assume that all variables are non-negative, then we know +that the zero vector is no greater than the minimal solution and +then the initial extended tableau looks as follows. +$$ +\begin{tikzpicture} +\matrix (m) [matrix of math nodes] +{ +& {} & 1 & \vec c \\ +\vec x && |(top)| \vec 0 & I \\ +\vec r && \vec b & |(bottom)|A \\ +}; +\begin{pgfonlayer}{background} +\node (core) [inner sep=0pt,fill=black!20,right delimiter=),left delimiter=(,fit=(top)(bottom)] {}; +\end{pgfonlayer} +\end{tikzpicture} +$$ +Each column in this extended tableau is lexicographically positive +and will remain so because of the column choice explained above. +It is then clear that the value of $\vec x$ will increase in each step. +Note that there is no need to store the extra rows explicitly. +If a given $x_i$ is a column variable, then the corresponding row +is the unit vector $e_i$. If, on the other hand, it is a row variable, +then the row already appears somewhere else in the tableau. + +In case of parametric problems, the sign of the constant term +may depend on the parameters. Each time the constant term of a constraint row +changes, we therefore need to check whether the new term can attain +negative and/or positive values over the current set of possible +parameter values, i.e., the context. +If all these terms can only attain non-negative values, the current +state of the tableau represents a solution. If one of the terms +can only attain non-positive values and is not identically zero, +the corresponding row can be pivoted. +Otherwise, we pick one of the terms that can attain both positive +and negative values and split the context into a part where +it only attains non-negative values and a part where it only attains +negative values. + +\subsection{Gomory Cuts} + +The solution found by the dual simplex method may have +non-integral coordinates. If so, some rational solutions +(including the current sample value), can be cut off by +applying a (parametric) Gomory cut. +Let $r = b(\vec p) + \sp {\vec a} {\vec c}$ be the row +corresponding to the first non-integral coordinate of $\vec x$, +with $b(\vec p)$ the constant term, an affine expression in the +parameters $\vec p$, i.e., $b(\vec p) = \sp {\vec f} {\vec p} + g$. +Note that only row variables can attain +non-integral values as the sample value of the column variables is zero. +Consider the expression +$b(\vec p) - \ceil{b(\vec p)} + \sp {\fract{\vec a}} {\vec c}$, +with $\ceil\cdot$ the ceiling function and $\fract\cdot$ the +fractional part. This expression is negative at the sample value +since $\vec c = \vec 0$ and $r = b(\vec p)$ is fractional, i.e., +$\ceil{b(\vec p)} > b(\vec p)$. On the other hand, for each integral +value of $r$ and $\vec c \ge 0$, the expression is non-negative +because $b(\vec p) - \ceil{b(\vec p)} > -1$. +Imposing this expression to be non-negative therefore does not +invalidate any integral solutions, while it does cut away the current +fractional sample value. To be able to formulate this constraint, +a new variable $q = \floor{-b(\vec p)} = - \ceil{b(\vec p)}$ is added +to the context. This integral variable is uniquely defined by the constraints +$0 \le -d \, b(\vec p) - d \, q \le d - 1$, with $d$ the common +denominator of $\vec f$ and $g$. In practice, the variable +$q' = \floor{\sp {\fract{-f}} {\vec p} + \fract{-g}}$ is used instead +and the coefficients of the new constraint are adjusted accordingly. +The sign of the constant term of this new constraint need not be determined +as it is non-positive by construction. +When several of these extra context variables are added, it is important +to avoid adding duplicates. +Recent versions of {\tt PipLib} also check for such duplicates. + +\subsection{Negative Unknowns and Maximization} + +There are two places in the above algorithm where the unknowns $\vec x$ +are assumed to be non-negative: the initial tableau starts from +sample value $\vec x = \vec 0$ and $\vec c$ is assumed to be non-negative +during the construction of Gomory cuts. +To deal with negative unknowns, \textcite[Appendix A.2]{Fea91} +proposed to use a ``big parameter'', say $M$, that is taken to be +an arbitrarily large positive number. Instead of looking for the +lexicographically minimal value of $\vec x$, we search instead +for the lexicographically minimal value of $\vec x' = \vec M + \vec x$. +The sample value $\vec x' = \vec 0$ of the initial tableau then +corresponds to $\vec x = -\vec M$, which is clearly not greater than +any potential solution. The sign of the constant term of a row +is determined lexicographically, with the coefficient of $M$ considered +first. That is, if the coefficient of $M$ is not zero, then its sign +is the sign of the entire term. Otherwise, the sign is determined +by the remaining affine expression in the parameters. +If the original problem has a bounded optimum, then the final sample +value will be of the form $\vec M + \vec v$ and the optimal value +of the original problem is then $\vec v$. +Maximization problems can be handled in a similar way by computing +the minimum of $\vec M - \vec x$. + +When the optimum is unbounded, the optimal value computed for +the original problem will involve the big parameter. +In the original implementation of {\tt PipLib}, the big parameter could +even appear in some of the extra variables $\vec q$ created during +the application of a Gomory cut. The final result could then contain +implicit conditions on the big parameter through conditions on such +$\vec q$ variables. This problem was resolved in later versions +of {\tt PipLib} by taking $M$ to be divisible by any positive number. +The big parameter can then never appear in any $\vec q$ because +$\fract {\alpha M } = 0$. It should be noted, though, that an unbounded +problem usually (but not always) +indicates an incorrect formulation of the problem. + +The original version of {\tt PipLib} required the user to ``manually'' +add a big parameter, perform the reformulation and interpret the result +\parencite{Feautrier02}. Recent versions allow the user to simply +specify that the unknowns may be negative or that the maximum should +be computed and then these transformations are performed internally. +Although there are some application, e.g., +that of \textcite{Feautrier92multi}, +where it is useful to have explicit control over the big parameter, +negative unknowns and maximization are by far the most common applications +of the big parameter and we believe that the user should not be bothered +with such implementation issues. +The current version of {\tt isl} therefore does not +provide any interface for specifying big parameters. Instead, the user +can specify whether a maximum needs to be computed and no assumptions +are made on the sign of the unknowns. Instead, the sign of the unknowns +is checked internally and a big parameter is automatically introduced when +needed. For compatibility with {\tt PipLib}, the {\tt isl\_pip} tool +does explicitly add non-negativity constraints on the unknowns unless +the \verb+Urs_unknowns+ option is specified. +Currently, there is also no way in {\tt isl} of expressing a big +parameter in the output. Even though +{\tt isl} makes the same divisibility assumption on the big parameter +as recent versions of {\tt PipLib}, it will therefore eventually +produce an error if the problem turns out to be unbounded. + +\subsection{Preprocessing} + +In this section, we describe some transformations that are +or can be applied in advance to reduce the running time +of the actual dual simplex method with Gomory cuts. + +\subsubsection{Feasibility Check and Detection of Equalities} + +Experience with the original {\tt PipLib} has shown that Gomory cuts +do not perform very well on problems that are (non-obviously) empty, +i.e., problems with rational solutions, but no integer solutions. +In {\tt isl}, we therefore first perform a feasibility check on +the original problem considered as a non-parametric problem +over the combined space of unknowns and parameters. +In fact, we do not simply check the feasibility, but we also +check for implicit equalities among the integer points by computing +the integer affine hull. The algorithm used is the same as that +described in \autoref{s:GBR} below. +Computing the affine hull is fairly expensive, but it can +bring huge benefits if any equalities can be found or if the problem +turns out to be empty. + +\subsubsection{Constraint Simplification} + +If the coefficients of the unknown and parameters in a constraint +have a common factor, then this factor should be removed, possibly +rounding down the constant term. For example, the constraint +$2 x - 5 \ge 0$ should be simplified to $x - 3 \ge 0$. +{\tt isl} performs such simplifications on all sets and relations. +Recent versions of {\tt PipLib} also perform this simplification +on the input. + +\subsubsection{Exploiting Equalities}\label{s:equalities} + +If there are any (explicit) equalities in the input description, +{\tt PipLib} converts each into a pair of inequalities. +It is also possible to write $r$ equalities as $r+1$ inequalities +\parencite{Feautrier02}, but it is even better to \emph{exploit} the +equalities to reduce the dimensionality of the problem. +Given an equality involving at least one unknown, we pivot +the row corresponding to the equality with the column corresponding +to the last unknown with non-zero coefficient. The new column variable +can then be removed completely because it is identically zero, +thereby reducing the dimensionality of the problem by one. +The last unknown is chosen to ensure that the columns of the initial +tableau remain lexicographically positive. In particular, if +the equality is of the form $b + \sum_{i \le j} a_i \, x_i = 0$ with +$a_j \ne 0$, then the (implicit) top rows of the initial tableau +are changed as follows +$$ +\begin{tikzpicture} +\matrix [matrix of math nodes] +{ + & {} & |(top)| 0 & I_1 & |(j)| & \\ +j && 0 & & 1 & \\ + && 0 & & & |(bottom)|I_2 \\ +}; +\node[overlay,above=2mm of j,anchor=south]{j}; +\begin{pgfonlayer}{background} +\node (m) [inner sep=0pt,fill=black!20,right delimiter=),left delimiter=(,fit=(top)(bottom)] {}; +\end{pgfonlayer} +\begin{scope}[xshift=4cm] +\matrix [matrix of math nodes] +{ + & {} & |(top)| 0 & I_1 & \\ +j && |(left)| -b/a_j & -a_i/a_j & \\ + && 0 & & |(bottom)|I_2 \\ +}; +\begin{pgfonlayer}{background} +\node (m2) [inner sep=0pt,fill=black!20,right delimiter=),left delimiter=(,fit=(top)(bottom)(left)] {}; +\end{pgfonlayer} +\end{scope} + \draw [shorten >=7mm,-to,thick,decorate, + decoration={snake,amplitude=.4mm,segment length=2mm, + pre=moveto,pre length=5mm,post length=8mm}] + (m) -- (m2); +\end{tikzpicture} +$$ +Currently, {\tt isl} also eliminates equalities involving only parameters +in a similar way, provided at least one of the coefficients is equal to one. +The application of parameter compression (see below) +would obviate the need for removing parametric equalities. + +\subsubsection{Offline Symmetry Detection}\label{s:offline} + +Some problems, notably those of \textcite{Bygde2010licentiate}, +have a collection of constraints, say +$b_i(\vec p) + \sp {\vec a} {\vec x} \ge 0$, +that only differ in their (parametric) constant terms. +These constant terms will be non-negative on different parts +of the context and this context may have to be split for each +of the constraints. In the worst case, the basic algorithm may +have to consider all possible orderings of the constant terms. +Instead, {\tt isl} introduces a new parameter, say $u$, and +replaces the collection of constraints by the single +constraint $u + \sp {\vec a} {\vec x} \ge 0$ along with +context constraints $u \le b_i(\vec p)$. +Any solution to the new system is also a solution +to the original system since +$\sp {\vec a} {\vec x} \ge -u \ge -b_i(\vec p)$. +Conversely, $m = \min_i b_i(\vec p)$ satisfies the constraints +on $u$ and therefore extends a solution to the new system. +It can also be plugged into a new solution. +See \autoref{s:post} for how this substitution is currently performed +in {\tt isl}. +The method described in this section can only detect symmetries +that are explicitly available in the input. +See \autoref{s:online} for the detection +and exploitation of symmetries that appear during the course of +the dual simplex method. + +Note that the replacement of the $b_i(\vec p)$ by $u$ may lose +information if the parameters that occur in $b_i(\vec p)$ also +occur in other constraints. The replacement is therefore currently +only applied when all the parameters in all of the $b_i(\vec p)$ +only occur in a single constraint, i.e., the one in which +the parameter is removed. +This is the case for the examples from \textcite{Bygde2010licentiate} +in \autoref{t:comparison}. +The version of {\tt isl} that was used during the experiments +of \autoref{s:pip:experiments} did not take into account +this single-occurrence constraint. + +\subsubsection{Parameter Compression}\label{s:compression} + +It may in some cases be apparent from the equalities in the problem +description that there can only be a solution for a sublattice +of the parameters. In such cases ``parameter compression'' +\parencite{Meister2004PhD,Meister2008} can be used to replace +the parameters by alternative ``dense'' parameters. +For example, if there is a constraint $2x = n$, then the system +will only have solutions for even values of $n$ and $n$ can be replaced +by $2n'$. Similarly, the parameters $n$ and $m$ in a system with +the constraint $2n = 3m$ can be replaced by a single parameter $n'$ +with $n=3n'$ and $m=2n'$. +It is also possible to perform a similar compression on the unknowns, +but it would be more complicated as the compression would have to +preserve the lexicographical order. Moreover, due to our handling +of equalities described above there should be +no need for such variable compression. +Although parameter compression has been implemented in {\tt isl}, +it is currently not yet used during parametric integer programming. + +\subsection{Postprocessing}\label{s:post} + +The output of {\tt PipLib} is a quast (quasi-affine selection tree). +Each internal node in this tree corresponds to a split of the context +based on a parametric constant term in the main tableau with indeterminate +sign. Each of these nodes may introduce extra variables in the context +corresponding to integer divisions. Each leaf of the tree prescribes +the solution in that part of the context that satisfies all the conditions +on the path leading to the leaf. +Such a quast is a very economical way of representing the solution, but +it would not be suitable as the (only) internal representation of +sets and relations in {\tt isl}. Instead, {\tt isl} represents +the constraints of a set or relation in disjunctive normal form. +The result of a parametric integer programming problem is then also +converted to this internal representation. Unfortunately, the conversion +to disjunctive normal form can lead to an explosion of the size +of the representation. +In some cases, this overhead would have to be paid anyway in subsequent +operations, but in other cases, especially for outside users that just +want to solve parametric integer programming problems, we would like +to avoid this overhead in future. That is, we are planning on introducing +quasts or a related representation as one of several possible internal +representations and on allowing the output of {\tt isl\_pip} to optionally +be printed as a quast. + +Currently, {\tt isl} also does not have an internal representation +for expressions such as $\min_i b_i(\vec p)$ from the offline +symmetry detection of \autoref{s:offline}. +Assume that one of these expressions has $n$ bounds $b_i(\vec p)$. +If the expression +does not appear in the affine expression describing the solution, +but only in the constraints, and if moreover, the expression +only appears with a positive coefficient, i.e., +$\min_i b_i(\vec p) \ge f_j(\vec p)$, then each of these constraints +can simply be reduplicated $n$ times, once for each of the bounds. +Otherwise, a conversion to disjunctive normal form +leads to $n$ cases, each described as $u = b_i(\vec p)$ with constraints +$b_i(\vec p) \le b_j(\vec p)$ for $j > i$ +and +$b_i(\vec p) < b_j(\vec p)$ for $j < i$. +Note that even though this conversion leads to a size increase +by a factor of $n$, not detecting the symmetry could lead to +an increase by a factor of $n!$ if all possible orderings end up being +considered. + +\subsection{Context Tableau}\label{s:context} + +The main operation that a context tableau needs to provide is a test +on the sign of an affine expression over the elements of the context. +This sign can be determined by solving two integer linear feasibility +problems, one with a constraint added to the context that enforces +the expression to be non-negative and one where the expression is +negative. As already mentioned by \textcite{Feautrier88parametric}, +any integer linear feasibility solver could be used, but the {\tt PipLib} +implementation uses a recursive call to the dual simplex with Gomory +cuts algorithm to determine the feasibility of a context. +In {\tt isl}, two ways of handling the context have been implemented, +one that performs the recursive call and one, used by default, that +uses generalized basis reduction. +We start with some optimizations that are shared between the two +implementations and then discuss additional details of each of them. + +\subsubsection{Maintaining Witnesses}\label{s:witness} + +A common feature of both integer linear feasibility solvers is that +they will not only say whether a set is empty or not, but if the set +is non-empty, they will also provide a \emph{witness} for this result, +i.e., a point that belongs to the set. By maintaining a list of such +witnesses, we can avoid many feasibility tests during the determination +of the signs of affine expressions. In particular, if the expression +evaluates to a positive number on some of these points and to a negative +number on some others, then no feasibility test needs to be performed. +If all the evaluations are non-negative, we only need to check for the +possibility of a negative value and similarly in case of all +non-positive evaluations. Finally, in the rare case that all points +evaluate to zero or at the start, when no points have been collected yet, +one or two feasibility tests need to be performed depending on the result +of the first test. + +When a new constraint is added to the context, the points that +violate the constraint are temporarily removed. They are reconsidered +when we backtrack over the addition of the constraint, as they will +satisfy the negation of the constraint. It is only when we backtrack +over the addition of the points that they are finally removed completely. +When an extra integer division is added to the context, +the new coordinates of the +witnesses can easily be computed by evaluating the integer division. +The idea of keeping track of witnesses was first used in {\tt barvinok}. + +\subsubsection{Choice of Constant Term on which to Split} + +Recall that if there are no rows with a non-positive constant term, +but there are rows with an indeterminate sign, then the context +needs to be split along the constant term of one of these rows. +If there is more than one such row, then we need to choose which row +to split on first. {\tt PipLib} uses a heuristic based on the (absolute) +sizes of the coefficients. In particular, it takes the largest coefficient +of each row and then selects the row where this largest coefficient is smaller +than those of the other rows. + +In {\tt isl}, we take that row for which non-negativity of its constant +term implies non-negativity of as many of the constant terms of the other +rows as possible. The intuition behind this heuristic is that on the +positive side, we will have fewer negative and indeterminate signs, +while on the negative side, we need to perform a pivot, which may +affect any number of rows meaning that the effect on the signs +is difficult to predict. This heuristic is of course much more +expensive to evaluate than the heuristic used by {\tt PipLib}. +More extensive tests are needed to evaluate whether the heuristic is worthwhile. + +\subsubsection{Dual Simplex + Gomory Cuts} + +When a new constraint is added to the context, the first steps +of the dual simplex method applied to this new context will be the same +or at least very similar to those taken on the original context, i.e., +before the constraint was added. In {\tt isl}, we therefore apply +the dual simplex method incrementally on the context and backtrack +to a previous state when a constraint is removed again. +An initial implementation that was never made public would also +keep the Gomory cuts, but the current implementation backtracks +to before the point where Gomory cuts are added before adding +an extra constraint to the context. +Keeping the Gomory cuts has the advantage that the sample value +is always an integer point and that this point may also satisfy +the new constraint. However, due to the technique of maintaining +witnesses explained above, +we would not perform a feasibility test in such cases and then +the previously added cuts may be redundant, possibly resulting +in an accumulation of a large number of cuts. + +If the parameters may be negative, then the same big parameter trick +used in the main tableau is applied to the context. This big parameter +is of course unrelated to the big parameter from the main tableau. +Note that it is not a requirement for this parameter to be ``big'', +but it does allow for some code reuse in {\tt isl}. +In {\tt PipLib}, the extra parameter is not ``big'', but this may be because +the big parameter of the main tableau also appears +in the context tableau. + +Finally, it was reported by \textcite{Galea2009personal}, who +worked on a parametric integer programming implementation +in {\tt PPL} \parencite{PPL}, +that it is beneficial to add cuts for \emph{all} rational coordinates +in the context tableau. Based on this report, +the initial {\tt isl} implementation was adapted accordingly. + +\subsubsection{Generalized Basis Reduction}\label{s:GBR} + +The default algorithm used in {\tt isl} for feasibility checking +is generalized basis reduction \parencite{Cook1991implementation}. +This algorithm is also used in the {\tt barvinok} implementation. +The algorithm is fairly robust, but it has some overhead. +We therefore try to avoid calling the algorithm in easy cases. +In particular, we incrementally keep track of points for which +the entire unit hypercube positioned at that point lies in the context. +This set is described by translates of the constraints of the context +and if (rationally) non-empty, any rational point +in the set can be rounded up to yield an integer point in the context. + +A restriction of the algorithm is that it only works on bounded sets. +The affine hull of the recession cone therefore needs to be projected +out first. As soon as the algorithm is invoked, we then also +incrementally keep track of this recession cone. The reduced basis +found by one call of the algorithm is also reused as initial basis +for the next call. + +Some problems lead to the +introduction of many integer divisions. Within a given context, +some of these integer divisions may be equal to each other, even +if the expressions are not identical, or they may be equal to some +affine combination of other variables. +To detect such cases, we compute the affine hull of the context +each time a new integer division is added. The algorithm used +for computing this affine hull is that of \textcite{Karr1976affine}, +while the points used in this algorithm are obtained by performing +integer feasibility checks on that part of the context outside +the current approximation of the affine hull. +The list of witnesses is used to construct an initial approximation +of the hull, while any extra points found during the construction +of the hull is added to this list. +Any equality found in this way that expresses an integer division +as an \emph{integer} affine combination of other variables is +propagated to the main tableau, where it is used to eliminate that +integer division. + +\subsection{Experiments}\label{s:pip:experiments} + +\autoref{t:comparison} compares the execution times of {\tt isl} +(with both types of context tableau) +on some more difficult instances to those of other tools, +run on an Intel Xeon W3520 @ 2.66GHz. +These instances are available in the \lstinline{testsets/pip} directory +of the {\tt isl} distribution. +Easier problems such as the +test cases distributed with {\tt Pip\-Lib} can be solved so quickly +that we would only be measuring overhead such as input/output and conversions +and not the running time of the actual algorithm. +We compare the following versions: +{\tt piplib-1.4.0-5-g0132fd9}, +{\tt barvinok-0.32.1-73-gc5d7751}, +{\tt isl-0.05.1-82-g3a37260} +and {\tt PPL} version 0.11.2. + +The first test case is the following dependence analysis problem +originating from the Phideo project \parencite{Verhaegh1995PhD} +that was communicated to us by Bart Kienhuis: +\begin{lstlisting}[flexiblecolumns=true,breaklines=true]{} +lexmax { [j1,j2] -> [i1,i2,i3,i4,i5,i6,i7,i8,i9,i10] : 1 <= i1,j1 <= 8 and 1 <= i2,i3,i4,i5,i6,i7,i8,i9,i10 <= 2 and 1 <= j2 <= 128 and i1-1 = j1-1 and i2-1+2*i3-2+4*i4-4+8*i5-8+16*i6-16+32*i7-32+64*i8-64+128*i9-128+256*i10-256=3*j2-3+66 }; +\end{lstlisting} +This problem was the main inspiration +for some of the optimizations in \autoref{s:GBR}. +The second group of test cases are projections used during counting. +The first nine of these come from \textcite{Seghir2006minimizing}. +The remaining two come from \textcite{Verdoolaege2005experiences} and +were used to drive the first, Gomory cuts based, implementation +in {\tt isl}. +The third and final group of test cases are borrowed from +\textcite{Bygde2010licentiate} and inspired the offline symmetry detection +of \autoref{s:offline}. Without symmetry detection, the running times +are 11s and 5.9s. +All running times of {\tt barvinok} and {\tt isl} include a conversion +to disjunctive normal form. Without this conversion, the final two +cases can be solved in 0.07s and 0.21s. +The {\tt PipLib} implementation has some fixed limits and will +sometimes report the problem to be too complex (TC), while on some other +problems it will run out of memory (OOM). +The {\tt barvinok} implementation does not support problems +with a non-trivial lineality space (line) nor maximization problems (max). +The Gomory cuts based {\tt isl} implementation was terminated after 1000 +minutes on the first problem. The gbr version introduces some +overhead on some of the easier problems, but is overall the clear winner. + +\begin{table} +\begin{center} +\begin{tabular}{lrrrrr} + & {\tt PipLib} & {\tt barvinok} & {\tt isl} cut & {\tt isl} gbr & {\tt PPL} \\ +\hline +\hline +% bart.pip +Phideo & TC & 793m & $>$999m & 2.7s & 372m \\ +\hline +e1 & 0.33s & 3.5s & 0.08s & 0.11s & 0.18s \\ +e3 & 0.14s & 0.13s & 0.10s & 0.10s & 0.17s \\ +e4 & 0.24s & 9.1s & 0.09s & 0.11s & 0.70s \\ +e5 & 0.12s & 6.0s & 0.06s & 0.14s & 0.17s \\ +e6 & 0.10s & 6.8s & 0.17s & 0.08s & 0.21s \\ +e7 & 0.03s & 0.27s & 0.04s & 0.04s & 0.03s \\ +e8 & 0.03s & 0.18s & 0.03s & 0.04s & 0.01s \\ +e9 & OOM & 70m & 2.6s & 0.94s & 22s \\ +vd & 0.04s & 0.10s & 0.03s & 0.03s & 0.03s \\ +bouleti & 0.25s & line & 0.06s & 0.06s & 0.15s \\ +difficult & OOM & 1.3s & 1.7s & 0.33s & 1.4s \\ +\hline +cnt/sum & TC & max & 2.2s & 2.2s & OOM \\ +jcomplex & TC & max & 3.7s & 3.9s & OOM \\ +\end{tabular} +\caption{Comparison of Execution Times} +\label{t:comparison} +\end{center} +\end{table} + +\subsection{Online Symmetry Detection}\label{s:online} + +Manual experiments on small instances of the problems of +\textcite{Bygde2010licentiate} and an analysis of the results +by the approximate MPA method developed by \textcite{Bygde2010licentiate} +have revealed that these problems contain many more symmetries +than can be detected using the offline method of \autoref{s:offline}. +In this section, we present an online detection mechanism that has +not been implemented yet, but that has shown promising results +in manual applications. + +Let us first consider what happens when we do not perform offline +symmetry detection. At some point, one of the +$b_i(\vec p) + \sp {\vec a} {\vec x} \ge 0$ constraints, +say the $j$th constraint, appears as a column +variable, say $c_1$, while the other constraints are represented +as rows of the form $b_i(\vec p) - b_j(\vec p) + c$. +The context is then split according to the relative order of +$b_j(\vec p)$ and one of the remaining $b_i(\vec p)$. +The offline method avoids this split by replacing all $b_i(\vec p)$ +by a single newly introduced parameter that represents the minimum +of these $b_i(\vec p)$. +In the online method the split is similarly avoided by the introduction +of a new parameter. In particular, a new parameter is introduced +that represents +$\left| b_j(\vec p) - b_i(\vec p) \right|_+ = +\max(b_j(\vec p) - b_i(\vec p), 0)$. + +In general, let $r = b(\vec p) + \sp {\vec a} {\vec c}$ be a row +of the tableau such that the sign of $b(\vec p)$ is indeterminate +and such that exactly one of the elements of $\vec a$ is a $1$, +while all remaining elements are non-positive. +That is, $r = b(\vec p) + c_j - f$ with $f = -\sum_{i\ne j} a_i c_i \ge 0$. +We introduce a new parameter $t$ with +context constraints $t \ge -b(\vec p)$ and $t \ge 0$ and replace +the column variable $c_j$ by $c' + t$. The row $r$ is now equal +to $b(\vec p) + t + c' - f$. The constant term of this row is always +non-negative because any negative value of $b(\vec p)$ is compensated +by $t \ge -b(\vec p)$ while and non-negative value remains non-negative +because $t \ge 0$. + +We need to show that this transformation does not eliminate any valid +solutions and that it does not introduce any spurious solutions. +Given a valid solution for the original problem, we need to find +a non-negative value of $c'$ satisfying the constraints. +If $b(\vec p) \ge 0$, we can take $t = 0$ so that +$c' = c_j - t = c_j \ge 0$. +If $b(\vec p) < 0$, we can take $t = -b(\vec p)$. +Since $r = b(\vec p) + c_j - f \ge 0$ and $f \ge 0$, we have +$c' = c_j + b(\vec p) \ge 0$. +Note that these choices amount to plugging in +$t = \left|-b(\vec p)\right|_+ = \max(-b(\vec p), 0)$. +Conversely, given a solution to the new problem, we need to find +a non-negative value of $c_j$, but this is easy since $c_j = c' + t$ +and both of these are non-negative. + +Plugging in $t = \max(-b(\vec p), 0)$ can be performed as in +\autoref{s:post}, but, as in the case of offline symmetry detection, +it may be better to provide a direct representation for such +expressions in the internal representation of sets and relations +or at least in a quast-like output format. + +\section{Coalescing}\label{s:coalescing} + +See \textcite{Verdoolaege2015impact} for details on integer set coalescing. + +\section{Transitive Closure} + +\subsection{Introduction} + +\begin{definition}[Power of a Relation] +Let $R \in \Z^n \to 2^{\Z^{d+d}}$ be a relation and +$k \in \Z_{\ge 1}$ +a positive number, then power $k$ of relation $R$ is defined as +\begin{equation} +\label{eq:transitive:power} +R^k \coloneqq +\begin{cases} +R & \text{if $k = 1$} +\\ +R \circ R^{k-1} & \text{if $k \ge 2$} +. +\end{cases} +\end{equation} +\end{definition} + +\begin{definition}[Transitive Closure of a Relation] +Let $R \in \Z^n \to 2^{\Z^{d+d}}$ be a relation, +then the transitive closure $R^+$ of $R$ is the union +of all positive powers of $R$, +$$ +R^+ \coloneqq \bigcup_{k \ge 1} R^k +. +$$ +\end{definition} +Alternatively, the transitive closure may be defined +inductively as +\begin{equation} +\label{eq:transitive:inductive} +R^+ \coloneqq R \cup \left(R \circ R^+\right) +. +\end{equation} + +Since the transitive closure of a polyhedral relation +may no longer be a polyhedral relation \parencite{Kelly1996closure}, +we can, in the general case, only compute an approximation +of the transitive closure. +Whereas \textcite{Kelly1996closure} compute underapproximations, +we, like \textcite{Beletska2009}, compute overapproximations. +That is, given a relation $R$, we will compute a relation $T$ +such that $R^+ \subseteq T$. Of course, we want this approximation +to be as close as possible to the actual transitive closure +$R^+$ and we want to detect the cases where the approximation is +exact, i.e., where $T = R^+$. + +For computing an approximation of the transitive closure of $R$, +we follow the same general strategy as \textcite{Beletska2009} +and first compute an approximation of $R^k$ for $k \ge 1$ and then project +out the parameter $k$ from the resulting relation. + +\begin{example} +As a trivial example, consider the relation +$R = \{\, x \to x + 1 \,\}$. The $k$th power of this map +for arbitrary $k$ is +$$ +R^k = k \mapsto \{\, x \to x + k \mid k \ge 1 \,\} +. +$$ +The transitive closure is then +$$ +\begin{aligned} +R^+ & = \{\, x \to y \mid \exists k \in \Z_{\ge 1} : y = x + k \,\} +\\ +& = \{\, x \to y \mid y \ge x + 1 \,\} +. +\end{aligned} +$$ +\end{example} + +\subsection{Computing an Approximation of $R^k$} +\label{s:power} + +There are some special cases where the computation of $R^k$ is very easy. +One such case is that where $R$ does not compose with itself, +i.e., $R \circ R = \emptyset$ or $\domain R \cap \range R = \emptyset$. +In this case, $R^k$ is only non-empty for $k=1$ where it is equal +to $R$ itself. + +In general, it is impossible to construct a closed form +of $R^k$ as a polyhedral relation. +We will therefore need to make some approximations. +As a first approximations, we will consider each of the basic +relations in $R$ as simply adding one or more offsets to a domain element +to arrive at an image element and ignore the fact that some of these +offsets may only be applied to some of the domain elements. +That is, we will only consider the difference set $\Delta\,R$ of the relation. +In particular, we will first construct a collection $P$ of paths +that move through +a total of $k$ offsets and then intersect domain and range of this +collection with those of $R$. +That is, +\begin{equation} +\label{eq:transitive:approx} +K = P \cap \left(\domain R \to \range R\right) +, +\end{equation} +with +\begin{equation} +\label{eq:transitive:path} +P = \vec s \mapsto \{\, \vec x \to \vec y \mid +\exists k_i \in \Z_{\ge 0}, \vec\delta_i \in k_i \, \Delta_i(\vec s) : +\vec y = \vec x + \sum_i \vec\delta_i +\wedge +\sum_i k_i = k > 0 +\,\} +\end{equation} +and with $\Delta_i$ the basic sets that compose +the difference set $\Delta\,R$. +Note that the number of basic sets $\Delta_i$ need not be +the same as the number of basic relations in $R$. +Also note that since addition is commutative, it does not +matter in which order we add the offsets and so we are allowed +to group them as we did in \eqref{eq:transitive:path}. + +If all the $\Delta_i$s are singleton sets +$\Delta_i = \{\, \vec \delta_i \,\}$ with $\vec \delta_i \in \Z^d$, +then \eqref{eq:transitive:path} simplifies to +\begin{equation} +\label{eq:transitive:singleton} +P = \{\, \vec x \to \vec y \mid +\exists k_i \in \Z_{\ge 0} : +\vec y = \vec x + \sum_i k_i \, \vec \delta_i +\wedge +\sum_i k_i = k > 0 +\,\} +\end{equation} +and then the approximation computed in \eqref{eq:transitive:approx} +is essentially the same as that of \textcite{Beletska2009}. +If some of the $\Delta_i$s are not singleton sets or if +some of $\vec \delta_i$s are parametric, then we need +to resort to further approximations. + +To ease both the exposition and the implementation, we will for +the remainder of this section work with extended offsets +$\Delta_i' = \Delta_i \times \{\, 1 \,\}$. +That is, each offset is extended with an extra coordinate that is +set equal to one. The paths constructed by summing such extended +offsets have the length encoded as the difference of their +final coordinates. The path $P'$ can then be decomposed into +paths $P_i'$, one for each $\Delta_i$, +\begin{equation} +\label{eq:transitive:decompose} +P' = \left( +(P_m' \cup \identity) \circ \cdots \circ +(P_2' \cup \identity) \circ +(P_1' \cup \identity) +\right) \cap +\{\, +\vec x' \to \vec y' \mid y_{d+1} - x_{d+1} = k > 0 +\,\} +, +\end{equation} +with +$$ +P_i' = \vec s \mapsto \{\, \vec x' \to \vec y' \mid +\exists k \in \Z_{\ge 1}, \vec \delta \in k \, \Delta_i'(\vec s) : +\vec y' = \vec x' + \vec \delta +\,\} +. +$$ +Note that each $P_i'$ contains paths of length at least one. +We therefore need to take the union with the identity relation +when composing the $P_i'$s to allow for paths that do not contain +any offsets from one or more $\Delta_i'$. +The path that consists of only identity relations is removed +by imposing the constraint $y_{d+1} - x_{d+1} > 0$. +Taking the union with the identity relation means that +that the relations we compose in \eqref{eq:transitive:decompose} +each consist of two basic relations. If there are $m$ +disjuncts in the input relation, then a direct application +of the composition operation may therefore result in a relation +with $2^m$ disjuncts, which is prohibitively expensive. +It is therefore crucial to apply coalescing (\autoref{s:coalescing}) +after each composition. + +Let us now consider how to compute an overapproximation of $P_i'$. +Those that correspond to singleton $\Delta_i$s are grouped together +and handled as in \eqref{eq:transitive:singleton}. +Note that this is just an optimization. The procedure described +below would produce results that are at least as accurate. +For simplicity, we first assume that no constraint in $\Delta_i'$ +involves any existentially quantified variables. +We will return to existentially quantified variables at the end +of this section. +Without existentially quantified variables, we can classify +the constraints of $\Delta_i'$ as follows +\begin{enumerate} +\item non-parametric constraints +\begin{equation} +\label{eq:transitive:non-parametric} +A_1 \vec x + \vec c_1 \geq \vec 0 +\end{equation} +\item purely parametric constraints +\begin{equation} +\label{eq:transitive:parametric} +B_2 \vec s + \vec c_2 \geq \vec 0 +\end{equation} +\item negative mixed constraints +\begin{equation} +\label{eq:transitive:mixed} +A_3 \vec x + B_3 \vec s + \vec c_3 \geq \vec 0 +\end{equation} +such that for each row $j$ and for all $\vec s$, +$$ +\Delta_i'(\vec s) \cap +\{\, \vec \delta' \mid B_{3,j} \vec s + c_{3,j} > 0 \,\} += \emptyset +$$ +\item positive mixed constraints +$$ +A_4 \vec x + B_4 \vec s + \vec c_4 \geq \vec 0 +$$ +such that for each row $j$, there is at least one $\vec s$ such that +$$ +\Delta_i'(\vec s) \cap +\{\, \vec \delta' \mid B_{4,j} \vec s + c_{4,j} > 0 \,\} +\ne \emptyset +$$ +\end{enumerate} +We will use the following approximation $Q_i$ for $P_i'$: +\begin{equation} +\label{eq:transitive:Q} +\begin{aligned} +Q_i = \vec s \mapsto +\{\, +\vec x' \to \vec y' +\mid {} & \exists k \in \Z_{\ge 1}, \vec f \in \Z^d : +\vec y' = \vec x' + (\vec f, k) +\wedge {} +\\ +& +A_1 \vec f + k \vec c_1 \geq \vec 0 +\wedge +B_2 \vec s + \vec c_2 \geq \vec 0 +\wedge +A_3 \vec f + B_3 \vec s + \vec c_3 \geq \vec 0 +\,\} +. +\end{aligned} +\end{equation} +To prove that $Q_i$ is indeed an overapproximation of $P_i'$, +we need to show that for every $\vec s \in \Z^n$, for every +$k \in \Z_{\ge 1}$ and for every $\vec f \in k \, \Delta_i(\vec s)$ +we have that +$(\vec f, k)$ satisfies the constraints in \eqref{eq:transitive:Q}. +If $\Delta_i(\vec s)$ is non-empty, then $\vec s$ must satisfy +the constraints in \eqref{eq:transitive:parametric}. +Each element $(\vec f, k) \in k \, \Delta_i'(\vec s)$ is a sum +of $k$ elements $(\vec f_j, 1)$ in $\Delta_i'(\vec s)$. +Each of these elements satisfies the constraints in +\eqref{eq:transitive:non-parametric}, i.e., +$$ +\left[ +\begin{matrix} +A_1 & \vec c_1 +\end{matrix} +\right] +\left[ +\begin{matrix} +\vec f_j \\ 1 +\end{matrix} +\right] +\ge \vec 0 +. +$$ +The sum of these elements therefore satisfies the same set of inequalities, +i.e., $A_1 \vec f + k \vec c_1 \geq \vec 0$. +Finally, the constraints in \eqref{eq:transitive:mixed} are such +that for any $\vec s$ in the parameter domain of $\Delta$, +we have $-\vec r(\vec s) \coloneqq B_3 \vec s + \vec c_3 \le \vec 0$, +i.e., $A_3 \vec f_j \ge \vec r(\vec s) \ge \vec 0$ +and therefore also $A_3 \vec f \ge \vec r(\vec s)$. +Note that if there are no mixed constraints and if the +rational relaxation of $\Delta_i(\vec s)$, i.e., +$\{\, \vec x \in \Q^d \mid A_1 \vec x + \vec c_1 \ge \vec 0\,\}$, +has integer vertices, then the approximation is exact, i.e., +$Q_i = P_i'$. In this case, the vertices of $\Delta'_i(\vec s)$ +generate the rational cone +$\{\, \vec x' \in \Q^{d+1} \mid \left[ +\begin{matrix} +A_1 & \vec c_1 +\end{matrix} +\right] \vec x' \,\}$ and therefore $\Delta'_i(\vec s)$ is +a Hilbert basis of this cone \parencite[Theorem~16.4]{Schrijver1986}. + +Note however that, as pointed out by \textcite{DeSmet2010personal}, +if there \emph{are} any mixed constraints, then the above procedure may +not compute the most accurate affine approximation of +$k \, \Delta_i(\vec s)$ with $k \ge 1$. +In particular, we only consider the negative mixed constraints that +happen to appear in the description of $\Delta_i(\vec s)$, while we +should instead consider \emph{all} valid such constraints. +It is also sufficient to consider those constraints because any +constraint that is valid for $k \, \Delta_i(\vec s)$ is also +valid for $1 \, \Delta_i(\vec s) = \Delta_i(\vec s)$. +Take therefore any constraint +$\spv a x + \spv b s + c \ge 0$ valid for $\Delta_i(\vec s)$. +This constraint is also valid for $k \, \Delta_i(\vec s)$ iff +$k \, \spv a x + \spv b s + c \ge 0$. +If $\spv b s + c$ can attain any positive value, then $\spv a x$ +may be negative for some elements of $\Delta_i(\vec s)$. +We then have $k \, \spv a x < \spv a x$ for $k > 1$ and so the constraint +is not valid for $k \, \Delta_i(\vec s)$. +We therefore need to impose $\spv b s + c \le 0$ for all values +of $\vec s$ such that $\Delta_i(\vec s)$ is non-empty, i.e., +$\vec b$ and $c$ need to be such that $- \spv b s - c \ge 0$ is a valid +constraint of $\Delta_i(\vec s)$. That is, $(\vec b, c)$ are the opposites +of the coefficients of a valid constraint of $\Delta_i(\vec s)$. +The approximation of $k \, \Delta_i(\vec s)$ can therefore be obtained +using three applications of Farkas' lemma. The first obtains the coefficients +of constraints valid for $\Delta_i(\vec s)$. The second obtains +the coefficients of constraints valid for the projection of $\Delta_i(\vec s)$ +onto the parameters. The opposite of the second set is then computed +and intersected with the first set. The result is the set of coefficients +of constraints valid for $k \, \Delta_i(\vec s)$. A final application +of Farkas' lemma is needed to obtain the approximation of +$k \, \Delta_i(\vec s)$ itself. + +\begin{example} +Consider the relation +$$ +n \to \{\, (x, y) \to (1 + x, 1 - n + y) \mid n \ge 2 \,\} +. +$$ +The difference set of this relation is +$$ +\Delta = n \to \{\, (1, 1 - n) \mid n \ge 2 \,\} +. +$$ +Using our approach, we would only consider the mixed constraint +$y - 1 + n \ge 0$, leading to the following approximation of the +transitive closure: +$$ +n \to \{\, (x, y) \to (o_0, o_1) \mid n \ge 2 \wedge o_1 \le 1 - n + y \wedge o_0 \ge 1 + x \,\} +. +$$ +If, instead, we apply Farkas's lemma to $\Delta$, i.e., +\begin{verbatim} +D := [n] -> { [1, 1 - n] : n >= 2 }; +CD := coefficients D; +CD; +\end{verbatim} +we obtain +\begin{verbatim} +{ rat: coefficients[[c_cst, c_n] -> [i2, i3]] : i3 <= c_n and + i3 <= c_cst + 2c_n + i2 } +\end{verbatim} +The pure-parametric constraints valid for $\Delta$, +\begin{verbatim} +P := { [a,b] -> [] }(D); +CP := coefficients P; +CP; +\end{verbatim} +are +\begin{verbatim} +{ rat: coefficients[[c_cst, c_n] -> []] : c_n >= 0 and 2c_n >= -c_cst } +\end{verbatim} +Negating these coefficients and intersecting with \verb+CD+, +\begin{verbatim} +NCP := { rat: coefficients[[a,b] -> []] + -> coefficients[[-a,-b] -> []] }(CP); +CK := wrap((unwrap CD) * (dom (unwrap NCP))); +CK; +\end{verbatim} +we obtain +\begin{verbatim} +{ rat: [[c_cst, c_n] -> [i2, i3]] : i3 <= c_n and + i3 <= c_cst + 2c_n + i2 and c_n <= 0 and 2c_n <= -c_cst } +\end{verbatim} +The approximation for $k\,\Delta$, +\begin{verbatim} +K := solutions CK; +K; +\end{verbatim} +is then +\begin{verbatim} +[n] -> { rat: [i0, i1] : i1 <= -i0 and i0 >= 1 and i1 <= 2 - n - i0 } +\end{verbatim} +Finally, the computed approximation for $R^+$, +\begin{verbatim} +T := unwrap({ [dx,dy] -> [[x,y] -> [x+dx,y+dy]] }(K)); +R := [n] -> { [x,y] -> [x+1,y+1-n] : n >= 2 }; +T := T * ((dom R) -> (ran R)); +T; +\end{verbatim} +is +\begin{verbatim} +[n] -> { [x, y] -> [o0, o1] : o1 <= x + y - o0 and + o0 >= 1 + x and o1 <= 2 - n + x + y - o0 and n >= 2 } +\end{verbatim} +\end{example} + +Existentially quantified variables can be handled by +classifying them into variables that are uniquely +determined by the parameters, variables that are independent +of the parameters and others. The first set can be treated +as parameters and the second as variables. Constraints involving +the other existentially quantified variables are removed. + +\begin{example} +Consider the relation +$$ +R = +n \to \{\, x \to y \mid \exists \, \alpha_0, \alpha_1: 7\alpha_0 = -2 + n \wedge 5\alpha_1 = -1 - x + y \wedge y \ge 6 + x \,\} +. +$$ +The difference set of this relation is +$$ +\Delta = \Delta \, R = +n \to \{\, x \mid \exists \, \alpha_0, \alpha_1: 7\alpha_0 = -2 + n \wedge 5\alpha_1 = -1 + x \wedge x \ge 6 \,\} +. +$$ +The existentially quantified variables can be defined in terms +of the parameters and variables as +$$ +\alpha_0 = \floor{\frac{-2 + n}7} +\qquad +\text{and} +\qquad +\alpha_1 = \floor{\frac{-1 + x}5} +. +$$ +$\alpha_0$ can therefore be treated as a parameter, +while $\alpha_1$ can be treated as a variable. +This in turn means that $7\alpha_0 = -2 + n$ can be treated as +a purely parametric constraint, while the other two constraints are +non-parametric. +The corresponding $Q$~\eqref{eq:transitive:Q} is therefore +$$ +\begin{aligned} +n \to \{\, (x,z) \to (y,w) \mid +\exists\, \alpha_0, \alpha_1, k, f : {} & +k \ge 1 \wedge +y = x + f \wedge +w = z + k \wedge {} \\ +& +7\alpha_0 = -2 + n \wedge +5\alpha_1 = -k + x \wedge +x \ge 6 k +\,\} +. +\end{aligned} +$$ +Projecting out the final coordinates encoding the length of the paths, +results in the exact transitive closure +$$ +R^+ = +n \to \{\, x \to y \mid \exists \, \alpha_0, \alpha_1: 7\alpha_1 = -2 + n \wedge 6\alpha_0 \ge -x + y \wedge 5\alpha_0 \le -1 - x + y \,\} +. +$$ +\end{example} + +The fact that we ignore some impure constraints clearly leads +to a loss of accuracy. In some cases, some of this loss can be recovered +by not considering the parameters in a special way. +That is, instead of considering the set +$$ +\Delta = \diff R = +\vec s \mapsto +\{\, \vec \delta \in \Z^{d} \mid \exists \vec x \to \vec y \in R : +\vec \delta = \vec y - \vec x +\,\} +$$ +we consider the set +$$ +\Delta' = \diff R' = +\{\, \vec \delta \in \Z^{n+d} \mid \exists +(\vec s, \vec x) \to (\vec s, \vec y) \in R' : +\vec \delta = (\vec s - \vec s, \vec y - \vec x) +\,\} +. +$$ +The first $n$ coordinates of every element in $\Delta'$ are zero. +Projecting out these zero coordinates from $\Delta'$ is equivalent +to projecting out the parameters in $\Delta$. +The result is obviously a superset of $\Delta$, but all its constraints +are of type \eqref{eq:transitive:non-parametric} and they can therefore +all be used in the construction of $Q_i$. + +\begin{example} +Consider the relation +$$ +% [n] -> { [x, y] -> [1 + x, 1 - n + y] | n >= 2 } +R = n \to \{\, (x, y) \to (1 + x, 1 - n + y) \mid n \ge 2 \,\} +. +$$ +We have +$$ +\diff R = n \to \{\, (1, 1 - n) \mid n \ge 2 \,\} +$$ +and so, by treating the parameters in a special way, we obtain +the following approximation for $R^+$: +$$ +n \to \{\, (x, y) \to (x', y') \mid n \ge 2 \wedge y' \le 1 - n + y \wedge x' \ge 1 + x \,\} +. +$$ +If we consider instead +$$ +R' = \{\, (n, x, y) \to (n, 1 + x, 1 - n + y) \mid n \ge 2 \,\} +$$ +then +$$ +\diff R' = \{\, (0, 1, y) \mid y \le -1 \,\} +$$ +and we obtain the approximation +$$ +n \to \{\, (x, y) \to (x', y') \mid n \ge 2 \wedge x' \ge 1 + x \wedge y' \le x + y - x' \,\} +. +$$ +If we consider both $\diff R$ and $\diff R'$, then we obtain +$$ +n \to \{\, (x, y) \to (x', y') \mid n \ge 2 \wedge y' \le 1 - n + y \wedge x' \ge 1 + x \wedge y' \le x + y - x' \,\} +. +$$ +Note, however, that this is not the most accurate affine approximation that +can be obtained. That would be +$$ +n \to \{\, (x, y) \to (x', y') \mid y' \le 2 - n + x + y - x' \wedge n \ge 2 \wedge x' \ge 1 + x \,\} +. +$$ +\end{example} + +\subsection{Checking Exactness} + +The approximation $T$ for the transitive closure $R^+$ can be obtained +by projecting out the parameter $k$ from the approximation $K$ +\eqref{eq:transitive:approx} of the power $R^k$. +Since $K$ is an overapproximation of $R^k$, $T$ will also be an +overapproximation of $R^+$. +To check whether the results are exact, we need to consider two +cases depending on whether $R$ is {\em cyclic}, where $R$ is defined +to be cyclic if $R^+$ maps any element to itself, i.e., +$R^+ \cap \identity \ne \emptyset$. +If $R$ is acyclic, then the inductive definition of +\eqref{eq:transitive:inductive} is equivalent to its completion, +i.e., +$$ +R^+ = R \cup \left(R \circ R^+\right) +$$ +is a defining property. +Since $T$ is known to be an overapproximation, we only need to check +whether +$$ +T \subseteq R \cup \left(R \circ T\right) +. +$$ +This is essentially Theorem~5 of \textcite{Kelly1996closure}. +The only difference is that they only consider lexicographically +forward relations, a special case of acyclic relations. + +If, on the other hand, $R$ is cyclic, then we have to resort +to checking whether the approximation $K$ of the power is exact. +Note that $T$ may be exact even if $K$ is not exact, so the check +is sound, but incomplete. +To check exactness of the power, we simply need to check +\eqref{eq:transitive:power}. Since again $K$ is known +to be an overapproximation, we only need to check whether +$$ +\begin{aligned} +K'|_{y_{d+1} - x_{d+1} = 1} & \subseteq R' +\\ +K'|_{y_{d+1} - x_{d+1} \ge 2} & \subseteq R' \circ K'|_{y_{d+1} - x_{d+1} \ge 1} +, +\end{aligned} +$$ +where $R' = \{\, \vec x' \to \vec y' \mid \vec x \to \vec y \in R +\wedge y_{d+1} - x_{d+1} = 1\,\}$, i.e., $R$ extended with path +lengths equal to 1. + +All that remains is to explain how to check the cyclicity of $R$. +Note that the exactness on the power is always sound, even +in the acyclic case, so we only need to be careful that we find +all cyclic cases. Now, if $R$ is cyclic, i.e., +$R^+ \cap \identity \ne \emptyset$, then, since $T$ is +an overapproximation of $R^+$, also +$T \cap \identity \ne \emptyset$. This in turn means +that $\Delta \, K'$ contains a point whose first $d$ coordinates +are zero and whose final coordinate is positive. +In the implementation we currently perform this test on $P'$ instead of $K'$. +Note that if $R^+$ is acyclic and $T$ is not, then the approximation +is clearly not exact and the approximation of the power $K$ +will not be exact either. + +\subsection{Decomposing $R$ into strongly connected components} + +If the input relation $R$ is a union of several basic relations +that can be partially ordered +then the accuracy of the approximation may be improved by computing +an approximation of each strongly connected components separately. +For example, if $R = R_1 \cup R_2$ and $R_1 \circ R_2 = \emptyset$, +then we know that any path that passes through $R_2$ cannot later +pass through $R_1$, i.e., +\begin{equation} +\label{eq:transitive:components} +R^+ = R_1^+ \cup R_2^+ \cup \left(R_2^+ \circ R_1^+\right) +. +\end{equation} +We can therefore compute (approximations of) transitive closures +of $R_1$ and $R_2$ separately. +Note, however, that the condition $R_1 \circ R_2 = \emptyset$ +is actually too strong. +If $R_1 \circ R_2$ is a subset of $R_2 \circ R_1$ +then we can reorder the segments +in any path that moves through both $R_1$ and $R_2$ to +first move through $R_1$ and then through $R_2$. + +This idea can be generalized to relations that are unions +of more than two basic relations by constructing the +strongly connected components in the graph with as vertices +the basic relations and an edge between two basic relations +$R_i$ and $R_j$ if $R_i$ needs to follow $R_j$ in some paths. +That is, there is an edge from $R_i$ to $R_j$ iff +\begin{equation} +\label{eq:transitive:edge} +R_i \circ R_j +\not\subseteq +R_j \circ R_i +. +\end{equation} +The components can be obtained from the graph by applying +Tarjan's algorithm \parencite{Tarjan1972}. + +In practice, we compute the (extended) powers $K_i'$ of each component +separately and then compose them as in \eqref{eq:transitive:decompose}. +Note, however, that in this case the order in which we apply them is +important and should correspond to a topological ordering of the +strongly connected components. Simply applying Tarjan's +algorithm will produce topologically sorted strongly connected components. +The graph on which Tarjan's algorithm is applied is constructed on-the-fly. +That is, whenever the algorithm checks if there is an edge between +two vertices, we evaluate \eqref{eq:transitive:edge}. +The exactness check is performed on each component separately. +If the approximation turns out to be inexact for any of the components, +then the entire result is marked inexact and the exactness check +is skipped on the components that still need to be handled. + +It should be noted that \eqref{eq:transitive:components} +is only valid for exact transitive closures. +If overapproximations are computed in the right hand side, then the result will +still be an overapproximation of the left hand side, but this result +may not be transitively closed. If we only separate components based +on the condition $R_i \circ R_j = \emptyset$, then there is no problem, +as this condition will still hold on the computed approximations +of the transitive closures. If, however, we have exploited +\eqref{eq:transitive:edge} during the decomposition and if the +result turns out not to be exact, then we check whether +the result is transitively closed. If not, we recompute +the transitive closure, skipping the decomposition. +Note that testing for transitive closedness on the result may +be fairly expensive, so we may want to make this check +configurable. + +\begin{figure} +\begin{center} +\begin{tikzpicture}[x=0.5cm,y=0.5cm,>=stealth,shorten >=1pt] +\foreach \x in {1,...,10}{ + \foreach \y in {1,...,10}{ + \draw[->] (\x,\y) -- (\x,\y+1); + } +} +\foreach \x in {1,...,20}{ + \foreach \y in {5,...,15}{ + \draw[->] (\x,\y) -- (\x+1,\y); + } +} +\end{tikzpicture} +\end{center} +\caption{The relation from \autoref{ex:closure4}} +\label{f:closure4} +\end{figure} +\begin{example} +\label{ex:closure4} +Consider the relation in example {\tt closure4} that comes with +the Omega calculator~\parencite{Omega_calc}, $R = R_1 \cup R_2$, +with +$$ +\begin{aligned} +R_1 & = \{\, (x,y) \to (x,y+1) \mid 1 \le x,y \le 10 \,\} +\\ +R_2 & = \{\, (x,y) \to (x+1,y) \mid 1 \le x \le 20 \wedge 5 \le y \le 15 \,\} +. +\end{aligned} +$$ +This relation is shown graphically in \autoref{f:closure4}. +We have +$$ +\begin{aligned} +R_1 \circ R_2 &= +\{\, (x,y) \to (x+1,y+1) \mid 1 \le x \le 9 \wedge 5 \le y \le 10 \,\} +\\ +R_2 \circ R_1 &= +\{\, (x,y) \to (x+1,y+1) \mid 1 \le x \le 10 \wedge 4 \le y \le 10 \,\} +. +\end{aligned} +$$ +Clearly, $R_1 \circ R_2 \subseteq R_2 \circ R_1$ and so +$$ +\left( +R_1 \cup R_2 +\right)^+ += +\left(R_2^+ \circ R_1^+\right) +\cup R_1^+ +\cup R_2^+ +. +$$ +\end{example} + +\begin{figure} +\newcounter{n} +\newcounter{t1} +\newcounter{t2} +\newcounter{t3} +\newcounter{t4} +\begin{center} +\begin{tikzpicture}[>=stealth,shorten >=1pt] +\setcounter{n}{7} +\foreach \i in {1,...,\value{n}}{ + \foreach \j in {1,...,\value{n}}{ + \setcounter{t1}{2 * \j - 4 - \i + 1} + \setcounter{t2}{\value{n} - 3 - \i + 1} + \setcounter{t3}{2 * \i - 1 - \j + 1} + \setcounter{t4}{\value{n} - \j + 1} + \ifnum\value{t1}>0\ifnum\value{t2}>0 + \ifnum\value{t3}>0\ifnum\value{t4}>0 + \draw[thick,->] (\i,\j) to[out=20] (\i+3,\j); + \fi\fi\fi\fi + \setcounter{t1}{2 * \j - 1 - \i + 1} + \setcounter{t2}{\value{n} - \i + 1} + \setcounter{t3}{2 * \i - 4 - \j + 1} + \setcounter{t4}{\value{n} - 3 - \j + 1} + \ifnum\value{t1}>0\ifnum\value{t2}>0 + \ifnum\value{t3}>0\ifnum\value{t4}>0 + \draw[thick,->] (\i,\j) to[in=-20,out=20] (\i,\j+3); + \fi\fi\fi\fi + \setcounter{t1}{2 * \j - 1 - \i + 1} + \setcounter{t2}{\value{n} - 1 - \i + 1} + \setcounter{t3}{2 * \i - 1 - \j + 1} + \setcounter{t4}{\value{n} - 1 - \j + 1} + \ifnum\value{t1}>0\ifnum\value{t2}>0 + \ifnum\value{t3}>0\ifnum\value{t4}>0 + \draw[thick,->] (\i,\j) to (\i+1,\j+1); + \fi\fi\fi\fi + } +} +\end{tikzpicture} +\end{center} +\caption{The relation from \autoref{ex:decomposition}} +\label{f:decomposition} +\end{figure} +\begin{example} +\label{ex:decomposition} +Consider the relation on the right of \textcite[Figure~2]{Beletska2009}, +reproduced in \autoref{f:decomposition}. +The relation can be described as $R = R_1 \cup R_2 \cup R_3$, +with +$$ +\begin{aligned} +R_1 &= n \mapsto \{\, (i,j) \to (i+3,j) \mid +i \le 2 j - 4 \wedge +i \le n - 3 \wedge +j \le 2 i - 1 \wedge +j \le n \,\} +\\ +R_2 &= n \mapsto \{\, (i,j) \to (i,j+3) \mid +i \le 2 j - 1 \wedge +i \le n \wedge +j \le 2 i - 4 \wedge +j \le n - 3 \,\} +\\ +R_3 &= n \mapsto \{\, (i,j) \to (i+1,j+1) \mid +i \le 2 j - 1 \wedge +i \le n - 1 \wedge +j \le 2 i - 1 \wedge +j \le n - 1\,\} +. +\end{aligned} +$$ +The figure shows this relation for $n = 7$. +Both +$R_3 \circ R_1 \subseteq R_1 \circ R_3$ +and +$R_3 \circ R_2 \subseteq R_2 \circ R_3$, +which the reader can verify using the {\tt iscc} calculator: +\begin{verbatim} +R1 := [n] -> { [i,j] -> [i+3,j] : i <= 2 j - 4 and i <= n - 3 and + j <= 2 i - 1 and j <= n }; +R2 := [n] -> { [i,j] -> [i,j+3] : i <= 2 j - 1 and i <= n and + j <= 2 i - 4 and j <= n - 3 }; +R3 := [n] -> { [i,j] -> [i+1,j+1] : i <= 2 j - 1 and i <= n - 1 and + j <= 2 i - 1 and j <= n - 1 }; +(R1 . R3) - (R3 . R1); +(R2 . R3) - (R3 . R2); +\end{verbatim} +$R_3$ can therefore be moved forward in any path. +For the other two basic relations, we have both +$R_2 \circ R_1 \not\subseteq R_1 \circ R_2$ +and +$R_1 \circ R_2 \not\subseteq R_2 \circ R_1$ +and so $R_1$ and $R_2$ form a strongly connected component. +By computing the power of $R_3$ and $R_1 \cup R_2$ separately +and composing the results, the power of $R$ can be computed exactly +using \eqref{eq:transitive:singleton}. +As explained by \textcite{Beletska2009}, applying the same formula +to $R$ directly, without a decomposition, would result in +an overapproximation of the power. +\end{example} + +\subsection{Partitioning the domains and ranges of $R$} + +The algorithm of \autoref{s:power} assumes that the input relation $R$ +can be treated as a union of translations. +This is a reasonable assumption if $R$ maps elements of a given +abstract domain to the same domain. +However, if $R$ is a union of relations that map between different +domains, then this assumption no longer holds. +In particular, when an entire dependence graph is encoded +in a single relation, as is done by, e.g., +\textcite[Section~6.1]{Barthou2000MSE}, then it does not make +sense to look at differences between iterations of different domains. +Now, arguably, a modified Floyd-Warshall algorithm should +be applied to the dependence graph, as advocated by +\textcite{Kelly1996closure}, with the transitive closure operation +only being applied to relations from a given domain to itself. +However, it is also possible to detect disjoint domains and ranges +and to apply Floyd-Warshall internally. + +\LinesNumbered +\begin{algorithm} +\caption{The modified Floyd-Warshall algorithm of +\protect\textcite{Kelly1996closure}} +\label{a:Floyd} +\SetKwInput{Input}{Input} +\SetKwInput{Output}{Output} +\Input{Relations $R_{pq}$, $0 \le p, q < n$} +\Output{Updated relations $R_{pq}$ such that each relation +$R_{pq}$ contains all indirect paths from $p$ to $q$ in the input graph} +% +\BlankLine +\SetAlgoVlined +\DontPrintSemicolon +% +\For{$r \in [0, n-1]$}{ + $R_{rr} \coloneqq R_{rr}^+$ \nllabel{l:Floyd:closure}\; + \For{$p \in [0, n-1]$}{ + \For{$q \in [0, n-1]$}{ + \If{$p \ne r$ or $q \ne r$}{ + $R_{pq} \coloneqq R_{pq} \cup \left(R_{rq} \circ R_{pr}\right) + \cup \left(R_{rq} \circ R_{rr} \circ R_{pr}\right)$ + \nllabel{l:Floyd:update} + } + } + } +} +\end{algorithm} + +Let the input relation $R$ be a union of $m$ basic relations $R_i$. +Let $D_{2i}$ be the domains of $R_i$ and $D_{2i+1}$ the ranges of $R_i$. +The first step is to group overlapping $D_j$ until a partition is +obtained. If the resulting partition consists of a single part, +then we continue with the algorithm of \autoref{s:power}. +Otherwise, we apply Floyd-Warshall on the graph with as vertices +the parts of the partition and as edges the $R_i$ attached to +the appropriate pairs of vertices. +In particular, let there be $n$ parts $P_k$ in the partition. +We construct $n^2$ relations +$$ +R_{pq} \coloneqq \bigcup_{i \text{ s.t. } \domain R_i \subseteq P_p \wedge + \range R_i \subseteq P_q} R_i +, +$$ +apply \autoref{a:Floyd} and return the union of all resulting +$R_{pq}$ as the transitive closure of $R$. +Each iteration of the $r$-loop in \autoref{a:Floyd} updates +all relations $R_{pq}$ to include paths that go from $p$ to $r$, +possibly stay there for a while, and then go from $r$ to $q$. +Note that paths that ``stay in $r$'' include all paths that +pass through earlier vertices since $R_{rr}$ itself has been updated +accordingly in previous iterations of the outer loop. +In principle, it would be sufficient to use the $R_{pr}$ +and $R_{rq}$ computed in the previous iteration of the +$r$-loop in Line~\ref{l:Floyd:update}. +However, from an implementation perspective, it is easier +to allow either or both of these to have been updated +in the same iteration of the $r$-loop. +This may result in duplicate paths, but these can usually +be removed by coalescing (\autoref{s:coalescing}) the result of the union +in Line~\ref{l:Floyd:update}, which should be done in any case. +The transitive closure in Line~\ref{l:Floyd:closure} +is performed using a recursive call. This recursive call +includes the partitioning step, but the resulting partition will +usually be a singleton. +The result of the recursive call will either be exact or an +overapproximation. The final result of Floyd-Warshall is therefore +also exact or an overapproximation. + +\begin{figure} +\begin{center} +\begin{tikzpicture}[x=1cm,y=1cm,>=stealth,shorten >=3pt] +\foreach \x/\y in {0/0,1/1,3/2} { + \fill (\x,\y) circle (2pt); +} +\foreach \x/\y in {0/1,2/2,3/3} { + \draw (\x,\y) circle (2pt); +} +\draw[->] (0,0) -- (0,1); +\draw[->] (0,1) -- (1,1); +\draw[->] (2,2) -- (3,2); +\draw[->] (3,2) -- (3,3); +\draw[->,dashed] (2,2) -- (3,3); +\draw[->,dotted] (0,0) -- (1,1); +\end{tikzpicture} +\end{center} +\caption{The relation (solid arrows) on the right of Figure~1 of +\protect\textcite{Beletska2009} and its transitive closure} +\label{f:COCOA:1} +\end{figure} +\begin{example} +Consider the relation on the right of Figure~1 of +\textcite{Beletska2009}, +reproduced in \autoref{f:COCOA:1}. +This relation can be described as +$$ +\begin{aligned} +\{\, (x, y) \to (x_2, y_2) \mid {} & (3y = 2x \wedge x_2 = x \wedge 3y_2 = 3 + 2x \wedge x \ge 0 \wedge x \le 3) \vee {} \\ +& (x_2 = 1 + x \wedge y_2 = y \wedge x \ge 0 \wedge 3y \ge 2 + 2x \wedge x \le 2 \wedge 3y \le 3 + 2x) \,\} +. +\end{aligned} +$$ +Note that the domain of the upward relation overlaps with the range +of the rightward relation and vice versa, but that the domain +of neither relation overlaps with its own range or the domain of +the other relation. +The domains and ranges can therefore be partitioned into two parts, +$P_0$ and $P_1$, shown as the white and black dots in \autoref{f:COCOA:1}, +respectively. +Initially, we have +$$ +\begin{aligned} +R_{00} & = \emptyset +\\ +R_{01} & = +\{\, (x, y) \to (x+1, y) \mid +(x \ge 0 \wedge 3y \ge 2 + 2x \wedge x \le 2 \wedge 3y \le 3 + 2x) \,\} +\\ +R_{10} & = +\{\, (x, y) \to (x_2, y_2) \mid (3y = 2x \wedge x_2 = x \wedge 3y_2 = 3 + 2x \wedge x \ge 0 \wedge x \le 3) \,\} +\\ +R_{11} & = \emptyset +. +\end{aligned} +$$ +In the first iteration, $R_{00}$ remains the same ($\emptyset^+ = \emptyset$). +$R_{01}$ and $R_{10}$ are therefore also unaffected, but +$R_{11}$ is updated to include $R_{01} \circ R_{10}$, i.e., +the dashed arrow in the figure. +This new $R_{11}$ is obviously transitively closed, so it is not +changed in the second iteration and it does not have an effect +on $R_{01}$ and $R_{10}$. However, $R_{00}$ is updated to +include $R_{10} \circ R_{01}$, i.e., the dotted arrow in the figure. +The transitive closure of the original relation is then equal to +$R_{00} \cup R_{01} \cup R_{10} \cup R_{11}$. +\end{example} + +\subsection{Incremental Computation} +\label{s:incremental} + +In some cases it is possible and useful to compute the transitive closure +of union of basic relations incrementally. In particular, +if $R$ is a union of $m$ basic maps, +$$ +R = \bigcup_j R_j +, +$$ +then we can pick some $R_i$ and compute the transitive closure of $R$ as +\begin{equation} +\label{eq:transitive:incremental} +R^+ = R_i^+ \cup +\left( +\bigcup_{j \ne i} +R_i^* \circ R_j \circ R_i^* +\right)^+ +. +\end{equation} +For this approach to be successful, it is crucial that each +of the disjuncts in the argument of the second transitive +closure in \eqref{eq:transitive:incremental} be representable +as a single basic relation, i.e., without a union. +If this condition holds, then by using \eqref{eq:transitive:incremental}, +the number of disjuncts in the argument of the transitive closure +can be reduced by one. +Now, $R_i^* = R_i^+ \cup \identity$, but in some cases it is possible +to relax the constraints of $R_i^+$ to include part of the identity relation, +say on domain $D$. We will use the notation +${\cal C}(R_i,D) = R_i^+ \cup \identity_D$ to represent +this relaxed version of $R^+$. +\textcite{Kelly1996closure} use the notation $R_i^?$. +${\cal C}(R_i,D)$ can be computed by allowing $k$ to attain +the value $0$ in \eqref{eq:transitive:Q} and by using +$$ +P \cap \left(D \to D\right) +$$ +instead of \eqref{eq:transitive:approx}. +Typically, $D$ will be a strict superset of both $\domain R_i$ +and $\range R_i$. We therefore need to check that domain +and range of the transitive closure are part of ${\cal C}(R_i,D)$, +i.e., the part that results from the paths of positive length ($k \ge 1$), +are equal to the domain and range of $R_i$. +If not, then the incremental approach cannot be applied for +the given choice of $R_i$ and $D$. + +In order to be able to replace $R^*$ by ${\cal C}(R_i,D)$ +in \eqref{eq:transitive:incremental}, $D$ should be chosen +to include both $\domain R$ and $\range R$, i.e., such +that $\identity_D \circ R_j \circ \identity_D = R_j$ for all $j\ne i$. +\textcite{Kelly1996closure} say that they use +$D = \domain R_i \cup \range R_i$, but presumably they mean that +they use $D = \domain R \cup \range R$. +Now, this expression of $D$ contains a union, so it not directly usable. +\textcite{Kelly1996closure} do not explain how they avoid this union. +Apparently, in their implementation, +they are using the convex hull of $\domain R \cup \range R$ +or at least an approximation of this convex hull. +We use the simple hull (\autoref{s:simple hull}) of $\domain R \cup \range R$. + +It is also possible to use a domain $D$ that does {\em not\/} +include $\domain R \cup \range R$, but then we have to +compose with ${\cal C}(R_i,D)$ more selectively. +In particular, if we have +\begin{equation} +\label{eq:transitive:right} +\text{for each $j \ne i$ either } +\domain R_j \subseteq D \text{ or } \domain R_j \cap \range R_i = \emptyset +\end{equation} +and, similarly, +\begin{equation} +\label{eq:transitive:left} +\text{for each $j \ne i$ either } +\range R_j \subseteq D \text{ or } \range R_j \cap \domain R_i = \emptyset +\end{equation} +then we can refine \eqref{eq:transitive:incremental} to +$$ +R_i^+ \cup +\left( +\left( +\bigcup_{\shortstack{$\scriptstyle\domain R_j \subseteq D $\\ + $\scriptstyle\range R_j \subseteq D$}} +{\cal C} \circ R_j \circ {\cal C} +\right) +\cup +\left( +\bigcup_{\shortstack{$\scriptstyle\domain R_j \cap \range R_i = \emptyset$\\ + $\scriptstyle\range R_j \subseteq D$}} +\!\!\!\!\! +{\cal C} \circ R_j +\right) +\cup +\left( +\bigcup_{\shortstack{$\scriptstyle\domain R_j \subseteq D $\\ + $\scriptstyle\range R_j \cap \domain R_i = \emptyset$}} +\!\!\!\!\! +R_j \circ {\cal C} +\right) +\cup +\left( +\bigcup_{\shortstack{$\scriptstyle\domain R_j \cap \range R_i = \emptyset$\\ + $\scriptstyle\range R_j \cap \domain R_i = \emptyset$}} +\!\!\!\!\! +R_j +\right) +\right)^+ +. +$$ +If only property~\eqref{eq:transitive:right} holds, +we can use +$$ +R_i^+ \cup +\left( +\left( +R_i^+ \cup \identity +\right) +\circ +\left( +\left( +\bigcup_{\shortstack{$\scriptstyle\domain R_j \subseteq D $}} +R_j \circ {\cal C} +\right) +\cup +\left( +\bigcup_{\shortstack{$\scriptstyle\domain R_j \cap \range R_i = \emptyset$}} +\!\!\!\!\! +R_j +\right) +\right)^+ +\right) +, +$$ +while if only property~\eqref{eq:transitive:left} holds, +we can use +$$ +R_i^+ \cup +\left( +\left( +\left( +\bigcup_{\shortstack{$\scriptstyle\range R_j \subseteq D $}} +{\cal C} \circ R_j +\right) +\cup +\left( +\bigcup_{\shortstack{$\scriptstyle\range R_j \cap \domain R_i = \emptyset$}} +\!\!\!\!\! +R_j +\right) +\right)^+ +\circ +\left( +R_i^+ \cup \identity +\right) +\right) +. +$$ + +It should be noted that if we want the result of the incremental +approach to be transitively closed, then we can only apply it +if all of the transitive closure operations involved are exact. +If, say, the second transitive closure in \eqref{eq:transitive:incremental} +contains extra elements, then the result does not necessarily contain +the composition of these extra elements with powers of $R_i$. + +\subsection{An {\tt Omega}-like implementation} + +While the main algorithm of \textcite{Kelly1996closure} is +designed to compute and underapproximation of the transitive closure, +the authors mention that they could also compute overapproximations. +In this section, we describe our implementation of an algorithm +that is based on their ideas. +Note that the {\tt Omega} library computes underapproximations +\parencite[Section 6.4]{Omega_lib}. + +The main tool is Equation~(2) of \textcite{Kelly1996closure}. +The input relation $R$ is first overapproximated by a ``d-form'' relation +$$ +\{\, \vec i \to \vec j \mid \exists \vec \alpha : +\vec L \le \vec j - \vec i \le \vec U +\wedge +(\forall p : j_p - i_p = M_p \alpha_p) +\,\} +, +$$ +where $p$ ranges over the dimensions and $\vec L$, $\vec U$ and +$\vec M$ are constant integer vectors. The elements of $\vec U$ +may be $\infty$, meaning that there is no upper bound corresponding +to that element, and similarly for $\vec L$. +Such an overapproximation can be obtained by computing strides, +lower and upper bounds on the difference set $\Delta \, R$. +The transitive closure of such a ``d-form'' relation is +\begin{equation} +\label{eq:omega} +\{\, \vec i \to \vec j \mid \exists \vec \alpha, k : +k \ge 1 \wedge +k \, \vec L \le \vec j - \vec i \le k \, \vec U +\wedge +(\forall p : j_p - i_p = M_p \alpha_p) +\,\} +. +\end{equation} +The domain and range of this transitive closure are then +intersected with those of the input relation. +This is a special case of the algorithm in \autoref{s:power}. + +In their algorithm for computing lower bounds, the authors +use the above algorithm as a substep on the disjuncts in the relation. +At the end, they say +\begin{quote} +If an upper bound is required, it can be calculated in a manner +similar to that of a single conjunct [sic] relation. +\end{quote} +Presumably, the authors mean that a ``d-form'' approximation +of the whole input relation should be used. +However, the accuracy can be improved by also trying to +apply the incremental technique from the same paper, +which is explained in more detail in \autoref{s:incremental}. +In this case, ${\cal C}(R_i,D)$ can be obtained by +allowing the value zero for $k$ in \eqref{eq:omega}, +i.e., by computing +$$ +\{\, \vec i \to \vec j \mid \exists \vec \alpha, k : +k \ge 0 \wedge +k \, \vec L \le \vec j - \vec i \le k \, \vec U +\wedge +(\forall p : j_p - i_p = M_p \alpha_p) +\,\} +. +$$ +In our implementation we take as $D$ the simple hull +(\autoref{s:simple hull}) of $\domain R \cup \range R$. +To determine whether it is safe to use ${\cal C}(R_i,D)$, +we check the following conditions, as proposed by +\textcite{Kelly1996closure}: +${\cal C}(R_i,D) - R_i^+$ is not a union and for each $j \ne i$ +the condition +$$ +\left({\cal C}(R_i,D) - R_i^+\right) +\circ +R_j +\circ +\left({\cal C}(R_i,D) - R_i^+\right) += +R_j +$$ +holds. diff --git a/external/mit/isl/dist/doc/isl.bib b/external/mit/isl/dist/doc/isl.bib new file mode 100644 index 000000000000..51fdcab21c78 --- /dev/null +++ b/external/mit/isl/dist/doc/isl.bib @@ -0,0 +1,485 @@ +@inproceedings{Kelly1996closure, + author = {Wayne Kelly and + William Pugh and + Evan Rosser and + Tatiana Shpeisman}, + title = {Transitive Closure of Infinite Graphs and Its Applications}, + pages = {126-140}, + editor = {Chua-Huang Huang and + P. Sadayappan and + Utpal Banerjee and + David Gelernter and + Alexandru Nicolau and + David A. Padua}, + booktitle = {Languages and Compilers for Parallel Computing, 8th International + Workshop, LCPC'95, Columbus, Ohio, USA, August 10-12, 1995, + Proceedings}, + publisher = {Springer}, + series = {Lecture Notes in Computer Science}, + volume = {1033}, + year = {1996}, + isbn = {3-540-60765-X}, + doi = "10.1007/BFb0014196", +} + +@inproceedings{Beletska2009, + author = {Beletska, Anna and Barthou, Denis and Bielecki, Wlodzimierz and Cohen, Albert}, + title = {Computing the Transitive Closure of a Union of Affine Integer Tuple Relations}, + booktitle = {COCOA '09: Proceedings of the 3rd International Conference on Combinatorial Optimization and Applications}, + year = {2009}, + isbn = {978-3-642-02025-4}, + pages = {98--109}, + location = {Huangshan, China}, + doi = {10.1007/978-3-642-02026-1_9}, + publisher = {Springer-Verlag}, + address = {Berlin, Heidelberg}, +} + +@book{Schrijver1986, + author = "Schrijver, Alexander", + title = "Theory of Linear and Integer Programming", + publisher = "John Wiley \& Sons", + year = 1986 +} + +@article{Tarjan1972, + author = {Tarjan, Robert}, + journal = {SIAM Journal on Computing}, + number = {2}, + pages = {146--160}, + publisher = {SIAM}, + title = {Depth-First Search and Linear Graph Algorithms}, + volume = {1}, + year = {1972}, + doi = "10.1137/0201010", +} + +@TechReport{ Omega_calc, + author = "Wayne Kelly and Vadim Maslov and William Pugh and Evan Rosser and Tatiana Shpeisman and Dave Wonnacott", + title = "The {Omega} Calculator and Library", + month = nov, + institution = "University of Maryland", + year = 1996 +} + +@TechReport{ Omega_lib, + author = "Wayne Kelly and Vadim Maslov and William Pugh and Evan Rosser and Tatiana Shpeisman and Dave Wonnacott", + title = "The {Omega} Library", + month = nov, + institution = "University of Maryland", + year = 1996 +} + +@unpublished{Verdoolaege2009isl, + author = "Verdoolaege, Sven", + title = "An integer set library for program analysis", + note = "Advances in the Theory of Integer Linear Optimization and its Extensions,AMS 2009 Spring Western Section Meeting, San Francisco, California, 25-26 April 2009", + month = Apr, + year = "2009", + url = "https://lirias.kuleuven.be/handle/123456789/228373", +} + +@article{Barthou2000MSE, + author = {Barthou, Denis and Cohen, Albert and Collard, Jean-Fran\c{c}ois}, + title = {Maximal Static Expansion}, + journal = {Int. J. Parallel Program.}, + volume = {28}, + number = {3}, + year = {2000}, + issn = {0885-7458}, + pages = {213--243}, + doi = {10.1023/A:1007500431910}, + publisher = {Kluwer Academic Publishers}, + address = {Norwell, MA, USA}, +} + +@article{ Feautrier88parametric, + author = "P. Feautrier", + title = "Parametric Integer Programming", + journal = "RAIRO Recherche Op\'erationnelle", + volume = "22", + number = "3", + pages = "243--268", + year = "1988", +} + +@Article{ Fea91, + author = {Feautrier, P.}, + title = {Dataflow analysis of array and scalar references}, + journal = {International Journal of Parallel Programming}, + year = {1991}, + OPTkey = {}, + volume = {20}, + number = {1}, + OPTmonth = {}, + pages = {23--53}, + OPTnote = {}, + OPTannote = {}, + doi = "10.1007/BF01407931", +} + +@INPROCEEDINGS{BouletRe98, + AUTHOR = {Pierre Boulet and Xavier Redon}, + TITLE = {Communication Pre-evaluation in {HPF}}, + BOOKTITLE = {EUROPAR'98}, + PAGES = {263--272}, + YEAR = 1998, + VOLUME = 1470, + series = {Lecture Notes in Computer Science}, + PUBLISHER = {Springer-Verlag, Berlin}, + ABSTRACT = { Parallel computers are difficult to program efficiently. We believe + that a good way to help programmers write efficient programs is to + provide them with tools that show them how their programs behave on + a parallel computer. Data distribution is the major performance + factor of data-parallel programs and so automatic data layout for + HPF programs has been studied by many researchers recently. The + communication volume induced by a data distribution is a good + estimator of the efficiency of this data distribution. + + We present here a symbolic method to compute the communication + volume generated by a given data distribution during the program + writing phase (before compilation). We stay machine-independent to + assure portability. Our goal is to help the programmer understand + the data movements its program generates and thus find a good data + distribution. Our method is based on parametric polyhedral + computations. It can be applied to a large class of regular codes.}, + doi = "10.1007/BFb0057861", +} + +@INPROCEEDINGS {Verdoolaege2005experiences, + AUTHOR = "Verdoolaege, Sven and Beyls, Kristof and Bruynooghe, Maurice and Catthoor, Francky", + TITLE = {{E}xperiences with enumeration of integer projections of parametric polytopes}, + BOOKTITLE = {{P}roceedings of 14th {I}nternational {C}onference on {C}ompiler {C}onstruction, {E}dinburgh, {S}cotland}, + YEAR = {2005}, + EDITOR = {Bodik, R.}, + VOLUME = 3443, + pages = "91-105", + series = "Lecture Notes in Computer Science", + publisher = "Springer-Verlag", + address = "Berlin", + doi = "10.1007/b107108", +} + +@article{Detlefs2005simplify, + author = {David Detlefs and Greg Nelson and James B. Saxe}, + title = {Simplify: a theorem prover for program checking}, + journal = {J. ACM}, + volume = {52}, + number = {3}, + year = {2005}, + issn = {0004-5411}, + pages = {365--473}, + doi = {10.1145/1066100.1066102}, + publisher = {ACM}, + address = {New York, NY, USA}, + } + +@phdthesis{Nelson1980phd, + author = {Charles Gregory Nelson}, + title = {Techniques for program verification}, + year = {1980}, + order_no = {AAI8011683}, + school = {Stanford University}, + address = {Stanford, CA, USA}, + } + +@article{Woods2003short, + year = 2003, + Journal = "J. Amer. Math. Soc.", + volume = 16, + pages = "957--979", + month = apr, + title = {{Short rational generating functions for lattice point + problems}}, + author = {Alexander Barvinok and Kevin Woods}, + doi = "10.1090/S0894-0347-03-00428-4", +} + +@misc{barvinok-0.22, + author = {Sven Verdoolaege}, + title = {{\texttt{barvinok}}, version 0.22}, + howpublished = {Available from \url{https://barvinok.sourceforge.io/}}, + year = 2006 +} + +@inproceedings{DeLoera2004Three, + title = "Three Kinds of Integer Programming Algorithms based on Barvinok's Rational Functions", + author = "De Loera, J. A. and D. Haws and R. Hemmecke and P. Huggins and R. Yoshida", + booktitle = "Integer Programming and Combinatorial Optimization: 10th International IPCO Conference", + year = "2004", + month = jan, + series = "Lecture Notes in Computer Science", + Volume = 3064, + Pages = "244-255", + doi = "10.1007/978-3-540-25960-2_19", +} + +@TechReport{Feautrier02, + author = {P. Feautrier and J. Collard and C. Bastoul}, + title = {Solving systems of affine (in)equalities}, + institution = {PRiSM, Versailles University}, + year = 2002 +} + +@article{ Feautrier92multi, + author = "Paul Feautrier", + title = "Some Efficient Solutions to the Affine Scheduling Problem. {P}art {II}. Multidimensional Time", + journal = "International Journal of Parallel Programming", + volume = "21", + number = "6", + pages = "389--420", + year = "1992", + month = dec, + url = "citeseer.nj.nec.com/article/feautrier92some.html", + doi = "10.1007/BF01379404", +} + +@misc{Bygde2010licentiate, + author = {Stefan Bygde}, + title = {Static {WCET} Analysis based on Abstract Interpretation and Counting of Elements}, + month = {March}, + year = {2010}, + howpublished = {Licentiate thesis}, + publisher = {M{\"{a}}lardalen University Press}, + url = {http://www.mrtc.mdh.se/index.php?choice=publications&id=2144}, +} + +@phdthesis{Meister2004PhD, + title = {Stating and Manipulating Periodicity in the Polytope Model. Applications to Program Analysis and Optimization}, + author= {Beno\^it Meister}, + school = {Universit\'e Louis Pasteur}, + month = Dec, + year = {2004}, +} + +@inproceedings{Meister2008, + author = {Beno\^it Meister and Sven Verdoolaege}, + title = {Polynomial Approximations in the Polytope Model: Bringing the Power + of Quasi-Polynomials to the Masses}, + year = {2008}, + booktitle = {Digest of the 6th Workshop on Optimization for DSP and Embedded Systems, ODES-6}, + editor = "Jagadeesh Sankaran and Vander Aa, Tom", + month = apr, +} + +@misc{Galea2009personal, + author = "Fran\c{c}ois Galea", + title = "personal communication", + year = 2009, + month = nov, +} + +@misc{PPL, + author = "R. Bagnara and P. M. Hill and E. Zaffanella", + title = "The {Parma Polyhedra Library}", + howpublished = {\url{http://www.cs.unipr.it/ppl/}}, +} + +@TECHREPORT{Cook1991implementation, +AUTHOR={William Cook and Thomas Rutherford and Herbert E. Scarf and David F. Shallcross}, +TITLE={An Implementation of the Generalized Basis Reduction Algorithm for Integer Programming}, +YEAR=1991, +MONTH=Aug, +INSTITUTION={Cowles Foundation, Yale University}, +TYPE={Cowles Foundation Discussion Papers}, +NOTE={available at \url{http://ideas.repec.org/p/cwl/cwldpp/990.html}}, +NUMBER={990}, +} + + @article{Karr1976affine, +author={ Michael Karr}, +title={ Affine Relationships Among Variables of a Program }, +journal={Acta Informatica}, +Volume={6}, +pages={133-151}, +year={1976}, +publisher={Springer-Verlag}, +ignore={ }, + doi = "10.1007/BF00268497", +} + +@PhdThesis{Verhaegh1995PhD, + title = "Multidimensional Periodic Scheduling", + author = "Wim F. J. Verhaegh", + school = "Technische Universiteit Eindhoven", + year = 1995, +} + +@INPROCEEDINGS{Seghir2006minimizing, + AUTHOR = "Rachid Seghir and Vincent Loechner", + TITLE = {Memory Optimization by Counting Points in Integer Transformations of Parametric Polytopes}, + BOOKTITLE = {{P}roceedings of the {I}nternational {C}onference on {C}ompilers, {A}rchitectures, and {S}ynthesis for {E}mbedded Systems, CASES 2006, {S}eoul, {K}orea}, + month = oct, + YEAR = {2006}, + doi = {10.1145/1176760.1176771}, +} + +@misc{DeSmet2010personal, + author = "De Smet, Sven", + title = "personal communication", + year = 2010, + month = apr, +} + +@inproceedings{Verdoolaege2015impact, + author = {Verdoolaege, Sven}, + title = {Integer Set Coalescing}, + booktitle = {Proceedings of the 5th International Workshop on + Polyhedral Compilation Techniques}, + year = 2015, + month = Jan, + address = {Amsterdam, The Netherlands}, + abstract = { +In polyhedral compilation, various core concepts such as the set +of statement instances, the access relations, the dependences and +the schedule are represented or approximated using sets and binary +relations of sequences of integers bounded by (quasi-)affine constraints. +When these sets and relations are represented in disjunctive normal form, +it is important to keep the number of disjuncts small, both for efficiency +and to improve the computation of transitive closure overapproximations +and AST generation. This paper describes the set coalescing operation +of isl that looks for opportunities to combine several disjuncts into +a single disjunct without affecting the elements in the set. The main +purpose of the paper is to explain the various heuristics and to prove +their correctness. + }, + doi = "10.13140/2.1.1313.6968", +} + +@misc{Verdoolaege2016tutorial, + author = "Sven Verdoolaege", + title = "Presburger Formulas and Polyhedral Compilation", + year = 2016, + doi = "10.13140/RG.2.1.1174.6323", +} + +@inproceedings{Verdoolaege2009equivalence, + author = "Sven Verdoolaege and Gerda Janssens and Maurice Bruynooghe", + title = "Equivalence checking of static affine programs using widening to handle recurrences", + booktitle = "Computer Aided Verification 21", + month = Jun, + year = 2009, + pages = "599--613", + publisher = "Springer", + doi = "10.1007/978-3-642-02658-4_44", +} + +@incollection{Verdoolaege2010isl, + author = {Verdoolaege, Sven}, + title = {isl: An Integer Set Library for the Polyhedral Model}, + booktitle = {Mathematical Software - ICMS 2010}, + series = {Lecture Notes in Computer Science}, + editor = {Fukuda, Komei and Hoeven, Joris and Joswig, Michael and Takayama, Nobuki}, + publisher = {Springer}, + isbn = {}, + pages = {299-302}, + volume = {6327}, + year = {2010}, + doi = {10.1007/978-3-642-15582-6_49}, +} + +@incollection{Verdoolaege2010networks, + author = "Verdoolaege, Sven", + title = "Polyhedral process networks", + editor = "Bhattacharrya, Shuvra and Deprettere, Ed and Leupers, Rainer and Takala, Jarmo", + publisher = "Springer", + year = "2010", + doi = "10.1007/978-1-4419-6345-1\_{}33", + pages = "931--965", + booktitle = "Handbook of Signal Processing Systems", + url = "https://lirias.kuleuven.be/handle/123456789/235370", + doi = "10.1007/978-1-4419-6345-1_33", +} + +@InProceedings{Verdoolaege2011iscc, + author = {Sven Verdoolaege}, + title = {Counting Affine Calculator and Applications}, + booktitle = { First International Workshop on Polyhedral Compilation Techniques (IMPACT'11)}, + address = { Chamonix, France}, + month = apr, + year = {2011}, + doi = "10.13140/RG.2.1.2959.5601", +} + +@inproceedings{Verdoolaege2011closure, + author = {Verdoolaege, Sven and Cohen, Albert and Beletska, Anna}, + title = {Transitive Closures of Affine Integer Tuple Relations and Their Overapproximations}, + booktitle = {Proceedings of the 18th International Conference on Static Analysis}, + series = {SAS'11}, + year = {2011}, + isbn = {978-3-642-23701-0}, + location = {Venice, Italy}, + pages = {216--232}, + numpages = {17}, + acmid = {2041570}, + publisher = {Springer-Verlag}, + address = {Berlin, Heidelberg}, + doi = "10.1007/978-3-642-23702-7_18", +} + +@article{Verdoolaege2013PPCG, + title={Polyhedral parallel code generation for {CUDA}}, + author={Verdoolaege, Sven and Juega, Juan Carlos and Cohen, Albert and G{\'o}mez, Jos{\'e} Ignacio and Tenllado, Christian and Catthoor, Francky}, + journal = {ACM Trans. Archit. Code Optim.}, + volume={9}, + number={4}, + pages={54}, + year={2013}, + publisher={ACM}, + doi = {10.1145/2400682.2400713}, +} + +@inproceedings{Verdoolaege2014impact, + author = {Verdoolaege, Sven and Guelton, Serge and + Grosser, Tobias and Cohen, Albert}, + title = {Schedule Trees}, + booktitle = {Proceedings of the 4th International Workshop on Polyhedral Compilation Techniques}, + year = 2014, + month = Jan, + address = {Vienna, Austria}, + url = {https://acohen.gitlabpages.inria.fr/impact/impact2014/papers/impact2014-verdoolaege.pdf}, + abstract = { + Schedules in the polyhedral model, both those that represent the original +execution order and those produced by scheduling algorithms, naturally have the +form of a tree. Generic schedule representations proposed in the literature +encode this tree structure such that it is only implicitly available. +Following the internal representation of isl , we propose to represent +schedules as explicit trees and further extend the concept by introducing +different kinds of nodes. We compare our schedule trees to other +representations in detail and illustrate how they have been successfully used +to simplify the implementation of a non-trivial polyhedral compiler. + }, + DOI = {10.13140/RG.2.1.4475.6001}, +} + +@article{Grosser2015AST, + author = "Tobias Grosser and Sven Verdoolaege and Albert Cohen", + title = "Polyhedral {AST} generation is more than scanning polyhedra", + journal = "ACM Transactions on Programming Languages and Systems", + issue_date = {August 2015}, + volume = {37}, + number = {4}, + month = jul, + year = {2015}, + issn = {0164-0925}, + pages = {12:1--12:50}, + articleno = {12}, + numpages = {50}, + url = {http://doi.acm.org/10.1145/2743016}, + doi = {10.1145/2743016}, + acmid = {2743016}, + publisher = {ACM}, + address = {New York, NY, USA}, + keywords = {Polyhedral compilation, Presburger relations, code generation, index set splitting, unrolling}, +} + +@inproceedings{Verdoolaege2016reordering, + author = {Sven Verdoolaege and Albert Cohen}, + title = "Live-Range Reordering", + booktitle = {Proceedings of the sixth International Workshop on + Polyhedral Compilation Techniques}, + year = 2016, + month = Jan, + address = {Prague, Czech Republic}, + doi = "10.13140/RG.2.1.3272.9680", +} diff --git a/external/mit/isl/dist/doc/manual.pdf b/external/mit/isl/dist/doc/manual.pdf new file mode 100644 index 000000000000..fc994d6fc9d8 Binary files /dev/null and b/external/mit/isl/dist/doc/manual.pdf differ diff --git a/external/mit/isl/dist/doc/manual.tex b/external/mit/isl/dist/doc/manual.tex new file mode 100644 index 000000000000..3116241490f7 --- /dev/null +++ b/external/mit/isl/dist/doc/manual.tex @@ -0,0 +1,95 @@ +\documentclass{report} +\usepackage[T1]{fontenc} +\usepackage[plainpages=false,pdfpagelabels,breaklinks]{hyperref} +\usepackage[backend=biber,isbn=false,url=false,doi=true,% +maxbibnames=99,style=authoryear,sortcites=true,sorting=nyt,backref=true,% +indexing=true,mincitenames=2,maxcitenames=2,datelabel=comp,dashed=false,% +useprefix=true]{biblatex} +\usepackage{amsmath} +\usepackage{amssymb} +\usepackage{txfonts} +\usepackage{aliascnt} +\usepackage{tikz} +\usepackage{calc} +\usepackage[ruled]{algorithm2e} +\usetikzlibrary{matrix,fit,backgrounds,decorations.pathmorphing,positioning} +\usepackage{listings} + +\addbibresource{isl.bib} + +\renewbibmacro*{finentry}{\iflistundef{pageref}{}{\renewcommand{\finentrypunct}{}}\finentry} +\renewbibmacro*{pageref}{% + \iflistundef{pageref} + {} + {\setunit{\adddot\addspace}\printtext{% + \mbox{}\penalty100\hfill\hbox{[\printlist[pageref][-\value{listtotal}]{pageref}]}}}} + +\lstset{basicstyle=\tt,flexiblecolumns=false} + +\def\vec#1{\mathchoice{\mbox{\boldmath$\displaystyle\bf#1$}} +{\mbox{\boldmath$\textstyle\bf#1$}} +{\mbox{\boldmath$\scriptstyle\bf#1$}} +{\mbox{\boldmath$\scriptscriptstyle\bf#1$}}} + +\providecommand{\fract}[1]{\left\{#1\right\}} +\providecommand{\floor}[1]{\left\lfloor#1\right\rfloor} +\providecommand{\ceil}[1]{\left\lceil#1\right\rceil} +\def\sp#1#2{\langle #1, #2 \rangle} +\def\spv#1#2{\langle\vec #1,\vec #2\rangle} + +\newtheorem{theorem}{Theorem} +\newaliascnt{example}{theorem} +\newtheorem{example}[example]{Example} +\newaliascnt{def}{theorem} +\newtheorem{definition}[def]{Definition} +\aliascntresetthe{example} +\aliascntresetthe{def} +\numberwithin{theorem}{section} +\numberwithin{def}{section} +\numberwithin{example}{section} + +\newcommand{\algocflineautorefname}{Algorithm} +\newcommand{\exampleautorefname}{Example} +\newcommand{\lstnumberautorefname}{Line} +\renewcommand{\sectionautorefname}{Section} +\renewcommand{\subsectionautorefname}{Section} +\renewcommand{\algorithmautorefname}{Algorithm} + +\DeclareFieldFormat{date}{\hypertarget{\thefield{entrykey}}{#1}} +\def\isl{\hyperlink{Verdoolaege2010isl}{\texttt{isl}}\xspace} + +\def\Z{\mathbb{Z}} +\def\Q{\mathbb{Q}} + +\def\pdom{\mathop{\rm pdom}\nolimits} +\def\domain{\mathop{\rm dom}\nolimits} +\def\range{\mathop{\rm ran}\nolimits} +\def\identity{\mathop{\rm Id}\nolimits} +\def\diff{\mathop{\Delta}\nolimits} + +\providecommand{\floor}[1]{\left\lfloor#1\right\rfloor} + +\begin{document} + +\title{Integer Set Library: Manual\\ +\small Version: \input{version} } +\author{Sven Verdoolaege} + +\maketitle +\tableofcontents + +\chapter{User Manual} + +\input{user} + +\chapter{Implementation Details} + +\input{implementation} + +\chapter{Further Reading} + +\input{reading} + +\printbibliography + +\end{document} diff --git a/external/mit/isl/dist/doc/mypod2latex b/external/mit/isl/dist/doc/mypod2latex new file mode 100755 index 000000000000..b11c0593d015 --- /dev/null +++ b/external/mit/isl/dist/doc/mypod2latex @@ -0,0 +1,14 @@ +#!/usr/bin/perl + +use strict; +use Pod::LaTeX; + +my ($in, $out) = @ARGV; + +my $parser = new Pod::LaTeX( + AddPreamble => 0, + AddPostamble => 0, + LevelNoNum => 5, + ); + +$parser->parse_from_file($in, $out); diff --git a/external/mit/isl/dist/doc/reading.tex b/external/mit/isl/dist/doc/reading.tex new file mode 100644 index 000000000000..6498000fffde --- /dev/null +++ b/external/mit/isl/dist/doc/reading.tex @@ -0,0 +1,46 @@ +\textcite{Verdoolaege2016tutorial} describes the concepts behind +\isl in some detail, mainly focusing on Presburger formulas, +but also including some information on polyhedral compilation, +especially on dependence analysis. +Individual aspects of \isl are described in the following publications. +\begin{itemize} +\item +\textcite{Verdoolaege2009equivalence} introduce \isl as a library +for manipulating sets of integers defined by linear inequalities and +integer divisions that is used in their equivalence checker. + +\item +\textcite{Verdoolaege2010isl} provides a more detailed description +of \isl at the time and still stands as the official reference for +\isl. However, many features were only added later on and one or +more of the publications below may be more appropriate as +a reference to these features. + +\item +\textcite[Section 5.1]{Verdoolaege2010networks} provides some +details on the dataflow analysis step, but also see +\textcite[Chapter 6]{Verdoolaege2016tutorial} and +\textcite{Verdoolaege2016reordering} for a more recent treatment. + +\item The concepts of structured and named spaces and the manipulation +of sets containing elements in different spaces were introduced +by \textcite{Verdoolaege2011iscc}. + +\item The transitive closure operation is described +by \textcite{Verdoolaege2011closure}. + +\item The scheduler is briefly described by +\textcite[Section 6.2]{Verdoolaege2013PPCG} and +\textcite[Section 2.4]{Verdoolaege2016reordering}. + +\item Schedule trees started out as ``trees of bands'' +\parencite[Section 6.2]{Verdoolaege2013PPCG}, were formally +introduced by \textcite{Verdoolaege2014impact}, and were +slightly refined by \textcite{Grosser2015AST}. + +\item The coalescing operation is described by +\textcite{Verdoolaege2015impact}. + +\item The AST generator is described by \textcite{Grosser2015AST}. + +\end{itemize} diff --git a/external/mit/isl/dist/doc/user.pod b/external/mit/isl/dist/doc/user.pod new file mode 100644 index 000000000000..4ce2e4268c09 --- /dev/null +++ b/external/mit/isl/dist/doc/user.pod @@ -0,0 +1,13117 @@ +=head1 Introduction + +C is a thread-safe C library for manipulating +sets and relations of integer points bounded by affine constraints. +The descriptions of the sets and relations may involve +both parameters and existentially quantified variables. +All computations are performed in exact integer arithmetic +using C or C. +The C library offers functionality that is similar +to that offered by the C and C libraries, +but the underlying algorithms are in most cases completely different. + +The library is by no means complete and some fairly basic +functionality is still missing. +Still, even in its current form, the library has been successfully +used as a backend polyhedral library for the polyhedral +scanner C and as part of an equivalence checker of +static affine programs. +For bug reports, feature requests and questions, +visit the discussion group at +L. + +=head2 Backward Incompatible Changes + +=head3 Changes since isl-0.02 + +=over + +=item * The old printing functions have been deprecated +and replaced by C functions, see L. + +=item * Most functions related to dependence analysis have acquired +an extra C argument. To obtain the old behavior, this argument +should be given the value 1. See L. + +=back + +=head3 Changes since isl-0.03 + +=over + +=item * The function C has been +renamed to C. +Similarly, C has been +renamed to C. + +=back + +=head3 Changes since isl-0.04 + +=over + +=item * All header files have been renamed from C +to C. + +=back + +=head3 Changes since isl-0.05 + +=over + +=item * The functions C and +C no longer print a newline. + +=item * The functions C +and C now return +the accesses for which no source could be found instead of +the iterations where those accesses occur. + +=item * The functions C and +C now take a B space as input. An old call +C can be rewritten to +C. + +=item * The function C no longer takes +a parameter position as input. Instead, the exponent +is now expressed as the domain of the resulting relation. + +=back + +=head3 Changes since isl-0.06 + +=over + +=item * The format of C's +C output has changed. +Use C to obtain the old output. + +=item * The C<*_fast_*> functions have been renamed to C<*_plain_*>. +Some of the old names have been kept for backward compatibility, +but they will be removed in the future. + +=back + +=head3 Changes since isl-0.07 + +=over + +=item * The function C has been renamed to +C. +Similarly, the function C has been renamed to +C. + +=item * The C type has been renamed to C +along with the associated functions. +Some of the old names have been kept for backward compatibility, +but they will be removed in the future. + +=item * Spaces of maps, sets and parameter domains are now +treated differently. The distinction between map spaces and set spaces +has always been made on a conceptual level, but proper use of such spaces +was never checked. Furthermore, up until isl-0.07 there was no way +of explicitly creating a parameter space. These can now be created +directly using C or from other spaces using +C. + +=item * The space in which C, C, C, +C, C and C +objects live is now a map space +instead of a set space. This means, for example, that the dimensions +of the domain of an C are now considered to be of type +C instead of C. Extra functions have been +added to obtain the domain space. Some of the constructors still +take a domain space and have therefore been renamed. + +=item * The functions C and C +now take an C instead of an C. +An C can be created from an C +using C. + +=item * The C type has been removed. Functions that used +to return an C now return an C. +Note that the space of an C is that of relation. +When replacing a call to C by a call to +C any C argument needs +to be replaced by C. +A call to C can be replaced by a call +to C. +A call to C call be replaced by +the nested call + + isl_qpolynomial_from_aff(isl_aff_floor(div)) + +The function C has also been renamed +to C. + +=item * The C argument has been removed from +C and similar functions. +When reading input in the original PolyLib format, +the result will have no parameters. +If parameters are expected, the caller may want to perform +dimension manipulation on the result. + +=back + +=head3 Changes since isl-0.09 + +=over + +=item * The C option has been replaced +by the C option. + +=item * The first argument of C is now +an C instead of an C. +A call C can be replaced by + + isl_pw_aff_cond(isl_set_indicator_function(a), b, c) + +=back + +=head3 Changes since isl-0.10 + +=over + +=item * The functions C and +C have been renamed to +C and +C. +The new C and +C have slightly different meanings. + +=back + +=head3 Changes since isl-0.12 + +=over + +=item * C has been replaced by C. +Some of the old functions are still available in C +but they will be removed in the future. + +=item * The functions C, +C, C +and C have been changed to return +an C instead of an C. + +=item * The function C +has been removed. Essentially the same functionality is available +through C, except that it requires +setting up coincidence constraints. +The option C has accordingly been +replaced by the option C. + +=item * The function C has been changed +to return an C instead of a rational C. +The function C has been changed to return +a regular basic set, rather than a rational basic set. + +=back + +=head3 Changes since isl-0.14 + +=over + +=item * The function C now consistently +computes the sum on the shared definition domain. +The function C has been added +to compute the sum on the union of definition domains. +The original behavior of C was +confused and is no longer available. + +=item * Band forests have been replaced by schedule trees. + +=item * The function C has been +replaced by the function C. +Note that the may dependence relation returned by +C is the union of +the two dependence relations returned by +C. Similarly for the no source relations. +The function C is still available +for backward compatibility, but it will be removed in the future. + +=item * The function C has been +deprecated. + +=item * The function C has been +renamed to C. +The original name is still available +for backward compatibility, but it will be removed in the future. + +=item * The C AST generation option has been +deprecated. + +=item * The functions C and C +have been renamed to C and +C. The original names have been +kept for backward compatibility, but they will be removed in the future. + +=item * The C option has been replaced +by the C option. The effect +of setting the C option to C +is now obtained by turning on the C option. + +=back + +=head3 Changes since isl-0.17 + +=over + +=item * The function C no longer prints +in C format by default. To print in C format, the output format +of the printer needs to have been explicitly set to C. +As a result, the function C no longer prints +the expression in C format. Use C instead. + +=item * The functions C and C +have been deprecated. The function C has an effect +that is similar to C and could in some cases +be used as an alternative. + +=back + +=head3 Changes since isl-0.19 + +=over + +=item * Zero-dimensional objects of type C or +C can now keep track of an explicit domain. +This explicit domain, if present, is taken into account +by various operations that take such objects as input. + +=back + +=head3 Changes since isl-0.20 + +=over + +=item * Several functions that used to return C +now return C. This means that these functions may +now return a negative value in case an error occurred. +The same holds for functions that used to return C, +although some of those were already returning +a negative value in case of error. + +=item * The C enumeration type has been +renamed to C. The corresponding +enumeration constants have been similarly renamed. +The old names are defined to the new names for backward +compatibility. + +=item * Several functions returning an extra boolean value +through an C argument now do so through an C +argument. The returned values are the same, only the type +of the pointer has been changed. + +=back + +=head1 License + +C is released under the MIT license. + +=over + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +=back + +Note that by default C requires C, which is released +under the GNU Lesser General Public License (LGPL). This means +that code linked against C is also linked against LGPL code. + +When configuring with C<--with-int=imath> or C<--with-int=imath-32>, C +will link against C, a library for exact integer arithmetic released +under the MIT license. + +=head1 Installation + +The source of C can be obtained either as a tarball +or from the git repository. Both are available from +L. +The installation process depends on how you obtained +the source. + +=head2 Installation from the git repository + +=over + +=item 1 Clone or update the repository + +The first time the source is obtained, you need to clone +the repository. + + git clone git://repo.or.cz/isl.git + +To obtain updates, you need to pull in the latest changes + + git pull + +=item 2 Optionally get C submodule + +To build C with C, you need to obtain the C +submodule by running in the git source tree of C + + git submodule init + git submodule update + +This will fetch the required version of C in a subdirectory of C. + +=item 2 Generate C + + ./autogen.sh + +=back + +After performing the above steps, continue +with the L. + +=head2 Common installation instructions + +=over + +=item 1 Obtain C + +By default, building C requires C, including its headers files. +Your distribution may not provide these header files by default +and you may need to install a package called C or something +similar. Alternatively, C can be built from +source, available from L. +C is not needed if you build C with C. + +=item 2 Configure + +C uses the standard C C script. +To run it, just type + + ./configure + +optionally followed by some configure options. +A complete list of options can be obtained by running + + ./configure --help + +Below we discuss some of the more common options. + +=over + +=item C<--prefix> + +Installation prefix for C + +=item C<--with-int=[gmp|imath|imath-32]> + +Select the integer library to be used by C, the default is C. +With C, C will use 32 bit integers, but fall back to C +for values out of the 32 bit range. In most applications, C will run +fastest with the C option, followed by C and C, the +slowest. + +=item C<--with-gmp-prefix=>I + +Installation prefix for C (architecture-independent files). + +=item C<--with-gmp-exec-prefix=>I + +Installation prefix for C (architecture-dependent files). + +=back + +=item 3 Compile + + make + +=item 4 Test (optional) + + make check + +=item 5 Install (optional) + + make install + +=back + +=head2 Building the foreign language bindings + +The tarball already contains the generated foreign language bindings, +but they are not included in the git repository. +Building the C++ and Python bindings relies on the LLVM/clang libraries, +see C. +The C script will not assume that these are available +on the system. +To enable building the foreign language bindings, +one of the following options needs to be specified. + +=over + +=item C<--with-clang=system> + +Use the system clang libraries (installed in a default location). + +=item C<--with-clang-prefix=>I + +Use the system clang libraries installed in I. + +=back + +It is best to use the latest release of the clang libraries (16.0), +although any release since 3.5 should work as well. +Note that if you build the clang libraries from source, +then you need to make sure they are also installed (using C). +If the compiler that was used to compile the clang libraries +is different from the default C++ compiler, then use C +to specify this non-default C++ compiler when running C's C<./configure>. + +=head1 Integer Set Library + +=head2 Memory Management + +Since a high-level operation on isl objects usually involves +several substeps and since the user is usually not interested in +the intermediate results, most functions that return a new object +will also release all the objects passed as arguments. +If the user still wants to use one or more of these arguments +after the function call, she should pass along a copy of the +object rather than the object itself. +The user is then responsible for making sure that the original +object gets used somewhere else or is explicitly freed. + +The arguments and return values of all documented functions are +annotated to make clear which arguments are released and which +arguments are preserved. In particular, the following annotations +are used + +=over + +=item C<__isl_give> + +C<__isl_give> means that a new object is returned. +The user should make sure that the returned pointer is +used exactly once as a value for an C<__isl_take> argument. +In between, it can be used as a value for as many +C<__isl_keep> arguments as the user likes. +There is one exception, and that is the case where the +pointer returned is C. In this case, the user +is free to use it as an C<__isl_take> argument or not. +When applied to a C, the returned pointer needs to be +freed using C. + +=item C<__isl_null> + +C<__isl_null> means that a C value is returned. + +=item C<__isl_take> + +C<__isl_take> means that the object the argument points to +is taken over by the function and may no longer be used +by the user as an argument to any other function. +The pointer value must be one returned by a function +returning an C<__isl_give> pointer. +If the user passes in a C value, then this will +be treated as an error in the sense that the function will +not perform its usual operation. However, it will still +make sure that all the other C<__isl_take> arguments +are released. + +=item C<__isl_keep> + +C<__isl_keep> means that the function will only use the object +temporarily. After the function has finished, the user +can still use it as an argument to other functions. +A C value will be treated in the same way as +a C value for an C<__isl_take> argument. +This annotation may also be used on return values of +type C, in which case the returned pointer should +not be freed by the user and is only valid until the object +from which it was derived is updated or freed. + +=back + +=head2 Initialization + +All manipulations of integer sets and relations occur within +the context of an C. +A given C can only be used within a single thread. +All arguments of a function are required to have been allocated +within the same context. +There are currently no functions available for moving an object +from one C to another C. This means that +there is currently no way of safely moving an object from one +thread to another, unless the whole C is moved. + +An C can be allocated using C and +freed using C. +All objects allocated within an C should be freed +before the C itself is freed. + + isl_ctx *isl_ctx_alloc(); + void isl_ctx_free(isl_ctx *ctx); + +The user can impose a bound on the number of low-level I +that can be performed by an C. This bound can be set and +retrieved using the following functions. A bound of zero means that +no bound is imposed. The number of operations performed can be +reset using C. Note that the number +of low-level operations needed to perform a high-level computation +may differ significantly across different versions +of C, but it should be the same across different platforms +for the same version of C. + +Warning: This feature is experimental. C has good support to abort and +bail out during the computation, but this feature may exercise error code paths +that are normally not used that much. Consequently, it is not unlikely that +hidden bugs will be exposed. + + void isl_ctx_set_max_operations(isl_ctx *ctx, + unsigned long max_operations); + unsigned long isl_ctx_get_max_operations(isl_ctx *ctx); + void isl_ctx_reset_operations(isl_ctx *ctx); + +In order to be able to create an object in the same context +as another object, most object types (described later in +this document) provide a function to obtain the context +in which the object was created. + + #include + isl_ctx *isl_val_get_ctx(__isl_keep isl_val *val); + isl_ctx *isl_multi_val_get_ctx( + __isl_keep isl_multi_val *mv); + + #include + isl_ctx *isl_id_get_ctx(__isl_keep isl_id *id); + isl_ctx *isl_multi_id_get_ctx( + __isl_keep isl_multi_id *mi); + + #include + isl_ctx *isl_local_space_get_ctx( + __isl_keep isl_local_space *ls); + + #include + isl_ctx *isl_set_list_get_ctx( + __isl_keep isl_set_list *list); + + #include + isl_ctx *isl_aff_get_ctx(__isl_keep isl_aff *aff); + isl_ctx *isl_multi_aff_get_ctx( + __isl_keep isl_multi_aff *maff); + isl_ctx *isl_pw_aff_get_ctx(__isl_keep isl_pw_aff *pa); + isl_ctx *isl_pw_multi_aff_get_ctx( + __isl_keep isl_pw_multi_aff *pma); + isl_ctx *isl_multi_pw_aff_get_ctx( + __isl_keep isl_multi_pw_aff *mpa); + isl_ctx *isl_union_pw_aff_get_ctx( + __isl_keep isl_union_pw_aff *upa); + isl_ctx *isl_union_pw_multi_aff_get_ctx( + __isl_keep isl_union_pw_multi_aff *upma); + isl_ctx *isl_multi_union_pw_aff_get_ctx( + __isl_keep isl_multi_union_pw_aff *mupa); + + #include + isl_ctx *isl_id_to_ast_expr_get_ctx( + __isl_keep isl_id_to_ast_expr *id2expr); + + #include + isl_ctx *isl_point_get_ctx(__isl_keep isl_point *pnt); + + #include + isl_ctx *isl_vec_get_ctx(__isl_keep isl_vec *vec); + + #include + isl_ctx *isl_mat_get_ctx(__isl_keep isl_mat *mat); + + #include + isl_ctx *isl_vertices_get_ctx( + __isl_keep isl_vertices *vertices); + isl_ctx *isl_vertex_get_ctx(__isl_keep isl_vertex *vertex); + isl_ctx *isl_cell_get_ctx(__isl_keep isl_cell *cell); + + #include + isl_ctx *isl_restriction_get_ctx( + __isl_keep isl_restriction *restr); + isl_ctx *isl_union_access_info_get_ctx( + __isl_keep isl_union_access_info *access); + isl_ctx *isl_union_flow_get_ctx( + __isl_keep isl_union_flow *flow); + + #include + isl_ctx *isl_schedule_get_ctx( + __isl_keep isl_schedule *sched); + isl_ctx *isl_schedule_constraints_get_ctx( + __isl_keep isl_schedule_constraints *sc); + + #include + isl_ctx *isl_schedule_node_get_ctx( + __isl_keep isl_schedule_node *node); + + #include + isl_ctx *isl_ast_build_get_ctx( + __isl_keep isl_ast_build *build); + + #include + isl_ctx *isl_ast_expr_get_ctx( + __isl_keep isl_ast_expr *expr); + isl_ctx *isl_ast_node_get_ctx( + __isl_keep isl_ast_node *node); + + #include + isl_ctx *isl_stride_info_get_ctx( + __isl_keep isl_stride_info *si); + + #include + isl_ctx *isl_fixed_box_get_ctx( + __isl_keep isl_fixed_box *box); + +=head2 Return Types + +C uses the special return type C for functions +that return a non-negative value, typically a number or a position. +Besides the regular non-negative return values, a special (negative) +value C may be returned, indicating that something +went wrong. + +C also uses two special return types for functions that either return +a boolean or that in principle do not return anything. +In particular, the C type has three possible values: +C (a positive integer value), indicating I or I; +C (the integer value zero), indicating I or I; and +C (a negative integer value), indicating that something +went wrong. The following operations are defined on C. The function +C can be used to negate an C, where the negation of +C is C again. The function C +converts an integer to an C. Any non-zero values yields +C and zero yields C. + + #include + isl_bool isl_bool_not(isl_bool b); + isl_bool isl_bool_ok(int b); + +The C type has two possible values: +C (the integer value zero), indicating a successful +operation; and +C (a negative integer value), indicating that something +went wrong. +The function C converts an isl object pointer +to an C, returning C if the object pointer is valid and +C if it is C. + + #include + isl_stat isl_stat_non_null(void *obj); + +See L for more information on +C, C and C. + +=head2 Values + +An C represents an integer value, a rational value +or one of three special values, infinity, negative infinity and NaN. +Some predefined values can be created using the following functions. + + #include + __isl_give isl_val *isl_val_zero(isl_ctx *ctx); + __isl_give isl_val *isl_val_one(isl_ctx *ctx); + __isl_give isl_val *isl_val_negone(isl_ctx *ctx); + __isl_give isl_val *isl_val_nan(isl_ctx *ctx); + __isl_give isl_val *isl_val_infty(isl_ctx *ctx); + __isl_give isl_val *isl_val_neginfty(isl_ctx *ctx); + +Specific integer values can be created using the following functions. + + #include + __isl_give isl_val *isl_val_int_from_si(isl_ctx *ctx, + long i); + __isl_give isl_val *isl_val_int_from_ui(isl_ctx *ctx, + unsigned long u); + __isl_give isl_val *isl_val_int_from_chunks(isl_ctx *ctx, + size_t n, size_t size, const void *chunks); + +The function C constructs an C +from the C I, each consisting of C bytes, stored at C. +The least significant digit is assumed to be stored first. + +Value objects can be copied and freed using the following functions. + + #include + __isl_give isl_val *isl_val_copy(__isl_keep isl_val *v); + __isl_null isl_val *isl_val_free(__isl_take isl_val *v); + +They can be inspected using the following functions. + + #include + long isl_val_get_num_si(__isl_keep isl_val *v); + long isl_val_get_den_si(__isl_keep isl_val *v); + __isl_give isl_val *isl_val_get_den_val( + __isl_keep isl_val *v); + double isl_val_get_d(__isl_keep isl_val *v); + isl_size isl_val_n_abs_num_chunks(__isl_keep isl_val *v, + size_t size); + isl_stat isl_val_get_abs_num_chunks(__isl_keep isl_val *v, + size_t size, void *chunks); + +C returns the number of I +of C bytes needed to store the absolute value of the +numerator of C. +C stores these digits at C, +which is assumed to have been preallocated by the caller. +The least significant digit is stored first. +Note that C, C, +C, C +and C can only be applied to rational values. + +An C can be modified using the following function. + + #include + __isl_give isl_val *isl_val_set_si(__isl_take isl_val *v, + long i); + +The following unary properties are defined on Cs. + + #include + int isl_val_sgn(__isl_keep isl_val *v); + isl_bool isl_val_is_zero(__isl_keep isl_val *v); + isl_bool isl_val_is_one(__isl_keep isl_val *v); + isl_bool isl_val_is_negone(__isl_keep isl_val *v); + isl_bool isl_val_is_nonneg(__isl_keep isl_val *v); + isl_bool isl_val_is_nonpos(__isl_keep isl_val *v); + isl_bool isl_val_is_pos(__isl_keep isl_val *v); + isl_bool isl_val_is_neg(__isl_keep isl_val *v); + isl_bool isl_val_is_int(__isl_keep isl_val *v); + isl_bool isl_val_is_rat(__isl_keep isl_val *v); + isl_bool isl_val_is_nan(__isl_keep isl_val *v); + isl_bool isl_val_is_infty(__isl_keep isl_val *v); + isl_bool isl_val_is_neginfty(__isl_keep isl_val *v); + +Note that the sign of NaN is undefined. + +The following binary properties are defined on pairs of Cs. + + #include + isl_bool isl_val_lt(__isl_keep isl_val *v1, + __isl_keep isl_val *v2); + isl_bool isl_val_le(__isl_keep isl_val *v1, + __isl_keep isl_val *v2); + isl_bool isl_val_gt(__isl_keep isl_val *v1, + __isl_keep isl_val *v2); + isl_bool isl_val_ge(__isl_keep isl_val *v1, + __isl_keep isl_val *v2); + isl_bool isl_val_eq(__isl_keep isl_val *v1, + __isl_keep isl_val *v2); + isl_bool isl_val_ne(__isl_keep isl_val *v1, + __isl_keep isl_val *v2); + isl_bool isl_val_abs_eq(__isl_keep isl_val *v1, + __isl_keep isl_val *v2); + +Comparisons to NaN always return false. +That is, a NaN is not considered to hold any relative position +with respect to any value. In particular, a NaN +is neither considered to be equal to nor to be different from +any value (including another NaN). +The function C checks whether its two arguments +are equal in absolute value. + +For integer Cs we additionally have the following binary property. + + #include + isl_bool isl_val_is_divisible_by(__isl_keep isl_val *v1, + __isl_keep isl_val *v2); + +An C can also be compared to an integer using the following +functions. The result of C is undefined for NaN. + + #include + isl_bool isl_val_gt_si(__isl_keep isl_val *v, long i); + isl_bool isl_val_eq_si(__isl_keep isl_val *v, long i); + int isl_val_cmp_si(__isl_keep isl_val *v, long i); + +The following unary operations are available on Cs. + + #include + __isl_give isl_val *isl_val_abs(__isl_take isl_val *v); + __isl_give isl_val *isl_val_neg(__isl_take isl_val *v); + __isl_give isl_val *isl_val_floor(__isl_take isl_val *v); + __isl_give isl_val *isl_val_ceil(__isl_take isl_val *v); + __isl_give isl_val *isl_val_trunc(__isl_take isl_val *v); + __isl_give isl_val *isl_val_inv(__isl_take isl_val *v); + +The following binary operations are available on Cs. + + #include + __isl_give isl_val *isl_val_min(__isl_take isl_val *v1, + __isl_take isl_val *v2); + __isl_give isl_val *isl_val_max(__isl_take isl_val *v1, + __isl_take isl_val *v2); + __isl_give isl_val *isl_val_add(__isl_take isl_val *v1, + __isl_take isl_val *v2); + __isl_give isl_val *isl_val_add_ui(__isl_take isl_val *v1, + unsigned long v2); + __isl_give isl_val *isl_val_sub(__isl_take isl_val *v1, + __isl_take isl_val *v2); + __isl_give isl_val *isl_val_sub_ui(__isl_take isl_val *v1, + unsigned long v2); + __isl_give isl_val *isl_val_mul(__isl_take isl_val *v1, + __isl_take isl_val *v2); + __isl_give isl_val *isl_val_mul_ui(__isl_take isl_val *v1, + unsigned long v2); + __isl_give isl_val *isl_val_div(__isl_take isl_val *v1, + __isl_take isl_val *v2); + __isl_give isl_val *isl_val_div_ui(__isl_take isl_val *v1, + unsigned long v2); + +On integer values, we additionally have the following operations. + + #include + __isl_give isl_val *isl_val_pow2(__isl_take isl_val *v); + __isl_give isl_val *isl_val_2exp(__isl_take isl_val *v); + __isl_give isl_val *isl_val_mod(__isl_take isl_val *v1, + __isl_take isl_val *v2); + __isl_give isl_val *isl_val_gcd(__isl_take isl_val *v1, + __isl_take isl_val *v2); + __isl_give isl_val *isl_val_gcdext(__isl_take isl_val *v1, + __isl_take isl_val *v2, __isl_give isl_val **x, + __isl_give isl_val **y); + +C is an alternative name for C. +The function C returns the greatest common divisor g +of C and C as well as two integers C<*x> and C<*y> such +that C<*x> * C + C<*y> * C = g. + +=head3 GMP specific functions + +These functions are only available if C has been compiled with C +support. + +Specific integer and rational values can be created from C values using +the following functions. + + #include + __isl_give isl_val *isl_val_int_from_gmp(isl_ctx *ctx, + mpz_t z); + __isl_give isl_val *isl_val_from_gmp(isl_ctx *ctx, + const mpz_t n, const mpz_t d); + +The numerator and denominator of a rational value can be extracted as +C values using the following functions. + + #include + int isl_val_get_num_gmp(__isl_keep isl_val *v, mpz_t z); + int isl_val_get_den_gmp(__isl_keep isl_val *v, mpz_t z); + +=head2 Sets and Relations + +C uses six types of objects for representing sets and relations, +C, C, C, C, +C and C. +C and C represent sets and relations that +can be described as a conjunction of affine constraints, while +C and C represent unions of +Cs and Cs, respectively. +However, all Cs or Cs in the union need +to live in the same space. Cs and Cs +represent unions of Cs or Cs in I spaces, +where spaces are considered different if they have a different number +of dimensions and/or different names (see L<"Spaces">). +The difference between sets and relations (maps) is that sets have +one set of variables, while relations have two sets of variables, +input variables and output variables. + +=head2 Error Handling + +C supports different ways to react in case a runtime error is triggered. +Runtime errors arise, e.g., if a function such as C is called +with two maps that have incompatible spaces. There are three possible ways +to react on error: to warn, to continue or to abort. + +The default behavior is to warn. In this mode, C prints a warning, stores +the last error in the corresponding C 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. In case of functions returning an C, C or an +C, this value is C, +C or C. +An error does not corrupt internal state, +such that isl can continue to be used. C also provides functions to +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. Hence, resetting an error is not required to +continue to use isl, but only to observe new errors. + + #include + 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, +then the functions C and +C return C. + +Another option is to continue on error. This is similar to warn on error mode, +except that C does not print any warning. This allows a program to +implement its own error reporting. + +The last option is to directly abort the execution of the program from within +the isl library. This makes it obviously impossible to recover from an error, +but it allows to directly spot the error location. By aborting on error, +debuggers break at the location the error occurred and can provide a stack +trace. Other tools that automatically provide stack traces on abort or that do +not want to continue execution after an error was triggered may also prefer to +abort on error. + +The on error behavior of isl can be specified by calling +C or by setting the command line option +C<--isl-on-error>. Valid arguments for the function call are +C, C and C. The +choices for the command line option are C, C and C. +It is also possible to query the current error mode. + + #include + isl_stat isl_options_set_on_error(isl_ctx *ctx, int val); + int isl_options_get_on_error(isl_ctx *ctx); + +=head2 Identifiers + +Identifiers are used to identify both individual dimensions +and tuples of dimensions. They consist of an optional name and an optional +user pointer. The name and the user pointer cannot both be C, however. +Identifiers with the same name but different pointer values +are considered to be distinct. +Similarly, identifiers with different names but the same pointer value +are also considered to be distinct. +Equal identifiers are represented using the same object. +Pairs of identifiers can therefore be tested for equality using the +C<==> operator. +Identifiers can be constructed, copied, freed, inspected and printed +using the following functions. + + #include + __isl_give isl_id *isl_id_alloc(isl_ctx *ctx, + __isl_keep const char *name, void *user); + __isl_give isl_id *isl_id_set_free_user( + __isl_take isl_id *id, + void (*free_user)(void *user)); + void (*isl_id_get_free_user(__isl_keep isl_id *id)) + (void *user); + __isl_give isl_id *isl_id_copy(isl_id *id); + __isl_null isl_id *isl_id_free(__isl_take isl_id *id); + + void *isl_id_get_user(__isl_keep isl_id *id); + __isl_keep const char *isl_id_get_name(__isl_keep isl_id *id); + + __isl_give isl_printer *isl_printer_print_id( + __isl_take isl_printer *p, __isl_keep isl_id *id); + +The callback set by C is called on the user +pointer when the last reference to the C is freed. +This callback can be retrieved using C. +Note that C returns a pointer to some internal +data structure, so the result can only be used while the +corresponding C is alive. + +=head2 Spaces + +Whenever a new set, relation or similar object is created from scratch, +the space in which it lives needs to be specified using an C. +Each space involves zero or more parameters and zero, one or two +tuples of set or input/output dimensions. The parameters and dimensions +are identified by an C and a position. +The type C refers to parameters, +the type C refers to set dimensions (for spaces +with a single tuple of dimensions) and the types C +and C refer to input and output dimensions +(for spaces with two tuples of dimensions). +Local spaces (see L) also contain dimensions +of type C. +Note that parameters are only identified by their position within +a given object. Across different objects, parameters are (usually) +identified by their names or identifiers. Only unnamed parameters +are identified by their positions across objects. The use of unnamed +parameters is discouraged. + + #include + __isl_give isl_space *isl_space_unit(isl_ctx *ctx); + __isl_give isl_space *isl_space_alloc(isl_ctx *ctx, + unsigned nparam, unsigned n_in, unsigned n_out); + __isl_give isl_space *isl_space_params_alloc(isl_ctx *ctx, + unsigned nparam); + __isl_give isl_space *isl_space_set_alloc(isl_ctx *ctx, + unsigned nparam, unsigned dim); + __isl_give isl_space *isl_space_copy(__isl_keep isl_space *space); + __isl_null isl_space *isl_space_free(__isl_take isl_space *space); + +The space used for creating a parameter domain +needs to be created using C or C. +For other sets, the space +needs to be created using C, while +for a relation, the space +needs to be created using C. +The use of C, +C and C is discouraged as they allow +for the introduction of unnamed parameters. + +To check whether a given space is that of a set or a map +or whether it is a parameter space, use these functions: + + #include + 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); + +Spaces can be compared using the following functions: + + #include + isl_bool isl_space_is_equal(__isl_keep isl_space *space1, + __isl_keep isl_space *space2); + isl_bool isl_space_has_equal_params( + __isl_keep isl_space *space1, + __isl_keep isl_space *space2); + isl_bool isl_space_has_equal_tuples( + __isl_keep isl_space *space1, + __isl_keep isl_space *space2); + isl_bool isl_space_is_domain(__isl_keep isl_space *space1, + __isl_keep isl_space *space2); + isl_bool isl_space_is_range(__isl_keep isl_space *space1, + __isl_keep isl_space *space2); + isl_bool isl_space_tuple_is_equal( + __isl_keep isl_space *space1, + enum isl_dim_type type1, + __isl_keep isl_space *space2, + enum isl_dim_type type2); + +C checks whether the first argument is equal +to the domain of the second argument. This requires in particular that +the first argument is a set space and that the second argument +is a map space. C checks whether the given +tuples (C, C or C) of the given +spaces are the same. That is, it checks if they have the same +identifier (if any), the same dimension and the same internal structure +(if any). +The function +C checks whether two spaces +have the same parameters in the same order. +C check whether two spaces have +the same tuples. In contrast to C below, +it does not check the +parameters. This is useful because many C functions align the +parameters before they perform their operations, such that equivalence +is not necessary. +C checks whether two spaces are identical, +meaning that they have the same parameters and the same tuples. +That is, it checks whether both C and +C hold. + +It is often useful to create objects that live in the +same space as some other object. This can be accomplished +by creating the new objects +(see L or +L) based on the space +of the original object. + + #include + __isl_give isl_space *isl_basic_set_get_space( + __isl_keep isl_basic_set *bset); + __isl_give isl_space *isl_set_get_space(__isl_keep isl_set *set); + + #include + __isl_give isl_space *isl_union_set_get_space( + __isl_keep isl_union_set *uset); + + #include + __isl_give isl_space *isl_basic_map_get_space( + __isl_keep isl_basic_map *bmap); + __isl_give isl_space *isl_map_get_space(__isl_keep isl_map *map); + + #include + __isl_give isl_space *isl_union_map_get_space( + __isl_keep isl_union_map *umap); + + #include + __isl_give isl_space *isl_constraint_get_space( + __isl_keep isl_constraint *constraint); + + #include + __isl_give isl_space *isl_qpolynomial_get_domain_space( + __isl_keep isl_qpolynomial *qp); + __isl_give isl_space *isl_qpolynomial_get_space( + __isl_keep isl_qpolynomial *qp); + __isl_give isl_space * + isl_qpolynomial_fold_get_domain_space( + __isl_keep isl_qpolynomial_fold *fold); + __isl_give isl_space *isl_qpolynomial_fold_get_space( + __isl_keep isl_qpolynomial_fold *fold); + __isl_give isl_space *isl_pw_qpolynomial_get_domain_space( + __isl_keep isl_pw_qpolynomial *pwqp); + __isl_give isl_space *isl_pw_qpolynomial_get_space( + __isl_keep isl_pw_qpolynomial *pwqp); + __isl_give isl_space *isl_pw_qpolynomial_fold_get_domain_space( + __isl_keep isl_pw_qpolynomial_fold *pwf); + __isl_give isl_space *isl_pw_qpolynomial_fold_get_space( + __isl_keep isl_pw_qpolynomial_fold *pwf); + __isl_give isl_space *isl_union_pw_qpolynomial_get_space( + __isl_keep isl_union_pw_qpolynomial *upwqp); + __isl_give isl_space *isl_union_pw_qpolynomial_fold_get_space( + __isl_keep isl_union_pw_qpolynomial_fold *upwf); + + #include + __isl_give isl_space *isl_multi_id_get_space( + __isl_keep isl_multi_id *mi); + + #include + __isl_give isl_space *isl_multi_val_get_space( + __isl_keep isl_multi_val *mv); + + #include + __isl_give isl_space *isl_aff_get_domain_space( + __isl_keep isl_aff *aff); + __isl_give isl_space *isl_aff_get_space( + __isl_keep isl_aff *aff); + __isl_give isl_space *isl_pw_aff_get_domain_space( + __isl_keep isl_pw_aff *pwaff); + __isl_give isl_space *isl_pw_aff_get_space( + __isl_keep isl_pw_aff *pwaff); + __isl_give isl_space *isl_multi_aff_get_domain_space( + __isl_keep isl_multi_aff *maff); + __isl_give isl_space *isl_multi_aff_get_space( + __isl_keep isl_multi_aff *maff); + __isl_give isl_space *isl_pw_multi_aff_get_domain_space( + __isl_keep isl_pw_multi_aff *pma); + __isl_give isl_space *isl_pw_multi_aff_get_space( + __isl_keep isl_pw_multi_aff *pma); + __isl_give isl_space *isl_union_pw_aff_get_space( + __isl_keep isl_union_pw_aff *upa); + __isl_give isl_space *isl_union_pw_multi_aff_get_space( + __isl_keep isl_union_pw_multi_aff *upma); + __isl_give isl_space *isl_multi_pw_aff_get_domain_space( + __isl_keep isl_multi_pw_aff *mpa); + __isl_give isl_space *isl_multi_pw_aff_get_space( + __isl_keep isl_multi_pw_aff *mpa); + __isl_give isl_space * + isl_multi_union_pw_aff_get_domain_space( + __isl_keep isl_multi_union_pw_aff *mupa); + __isl_give isl_space * + isl_multi_union_pw_aff_get_space( + __isl_keep isl_multi_union_pw_aff *mupa); + + #include + __isl_give isl_space *isl_point_get_space( + __isl_keep isl_point *pnt); + + #include + __isl_give isl_space *isl_fixed_box_get_space( + __isl_keep isl_fixed_box *box); + +The number of dimensions of a given type of space +may be read off from a space or an object that lives +in a space using the following functions. +In case of C, type may be +C, C (only for relations), +C (only for relations), C +(only for sets) or C. + + #include + isl_size isl_space_dim(__isl_keep isl_space *space, + enum isl_dim_type type); + + #include + isl_size isl_local_space_dim(__isl_keep isl_local_space *ls, + enum isl_dim_type type); + + #include + isl_size isl_basic_set_dim(__isl_keep isl_basic_set *bset, + enum isl_dim_type type); + isl_size isl_set_tuple_dim(__isl_keep isl_set *set); + isl_size isl_set_dim(__isl_keep isl_set *set, + enum isl_dim_type type); + + #include + isl_size isl_union_set_dim(__isl_keep isl_union_set *uset, + enum isl_dim_type type); + + #include + isl_size isl_basic_map_dim(__isl_keep isl_basic_map *bmap, + enum isl_dim_type type); + isl_size isl_map_domain_tuple_dim( + __isl_keep isl_map *map); + isl_size isl_map_range_tuple_dim( + __isl_keep isl_map *map); + isl_size isl_map_dim(__isl_keep isl_map *map, + enum isl_dim_type type); + + #include + isl_size isl_union_map_dim(__isl_keep isl_union_map *umap, + enum isl_dim_type type); + + #include + isl_size isl_multi_val_dim(__isl_keep isl_multi_val *mv, + enum isl_dim_type type); + + #include + isl_size isl_aff_dim(__isl_keep isl_aff *aff, + enum isl_dim_type type); + isl_size isl_multi_aff_dim(__isl_keep isl_multi_aff *maff, + enum isl_dim_type type); + isl_size isl_pw_aff_dim(__isl_keep isl_pw_aff *pwaff, + enum isl_dim_type type); + isl_size isl_pw_multi_aff_dim( + __isl_keep isl_pw_multi_aff *pma, + enum isl_dim_type type); + isl_size isl_multi_pw_aff_dim( + __isl_keep isl_multi_pw_aff *mpa, + enum isl_dim_type type); + isl_size isl_union_pw_aff_dim( + __isl_keep isl_union_pw_aff *upa, + enum isl_dim_type type); + isl_size isl_union_pw_multi_aff_dim( + __isl_keep isl_union_pw_multi_aff *upma, + enum isl_dim_type type); + isl_size isl_multi_union_pw_aff_dim( + __isl_keep isl_multi_union_pw_aff *mupa, + enum isl_dim_type type); + + #include + isl_size isl_union_pw_qpolynomial_dim( + __isl_keep isl_union_pw_qpolynomial *upwqp, + enum isl_dim_type type); + isl_size isl_union_pw_qpolynomial_fold_dim( + __isl_keep isl_union_pw_qpolynomial_fold *upwf, + enum isl_dim_type type); + +Note that an C, an C, +an C, +an C and +an C +only have parameters. + +Additional parameters can be added to a space using the following function. + + #include + __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. + +Conversely, all parameters can be removed from a space +using the following function. + + #include + __isl_give isl_space *isl_space_drop_all_params( + __isl_take isl_space *space); + +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. +These functions are mostly useful to obtain the identifiers, positions +or names of the parameters. Identifiers of individual dimensions are +essentially only useful for printing. They are ignored by all other +operations and may not be preserved across those operations. +To keep track of a space along with names/identifiers of +the set dimensions, use an C as described in +L. + + #include + __isl_give isl_space *isl_space_set_dim_id( + __isl_take isl_space *space, + enum isl_dim_type type, unsigned pos, + __isl_take isl_id *id); + isl_bool isl_space_has_dim_id(__isl_keep isl_space *space, + enum isl_dim_type type, unsigned pos); + __isl_give isl_id *isl_space_get_dim_id( + __isl_keep isl_space *space, + enum isl_dim_type type, unsigned pos); + __isl_give isl_space *isl_space_set_dim_name( + __isl_take isl_space *space, + enum isl_dim_type type, unsigned pos, + __isl_keep const char *name); + isl_bool isl_space_has_dim_name(__isl_keep isl_space *space, + enum isl_dim_type type, unsigned pos); + __isl_keep const char *isl_space_get_dim_name( + __isl_keep isl_space *space, + enum isl_dim_type type, unsigned pos); + + #include + __isl_give isl_local_space *isl_local_space_set_dim_id( + __isl_take isl_local_space *ls, + enum isl_dim_type type, unsigned pos, + __isl_take isl_id *id); + isl_bool isl_local_space_has_dim_id( + __isl_keep isl_local_space *ls, + enum isl_dim_type type, unsigned pos); + __isl_give isl_id *isl_local_space_get_dim_id( + __isl_keep isl_local_space *ls, + enum isl_dim_type type, unsigned pos); + __isl_give isl_local_space *isl_local_space_set_dim_name( + __isl_take isl_local_space *ls, + enum isl_dim_type type, unsigned pos, const char *s); + isl_bool isl_local_space_has_dim_name( + __isl_keep isl_local_space *ls, + enum isl_dim_type type, unsigned pos) + const char *isl_local_space_get_dim_name( + __isl_keep isl_local_space *ls, + enum isl_dim_type type, unsigned pos); + + #include + const char *isl_constraint_get_dim_name( + __isl_keep isl_constraint *constraint, + enum isl_dim_type type, unsigned pos); + + #include + __isl_give isl_id *isl_basic_set_get_dim_id( + __isl_keep isl_basic_set *bset, + enum isl_dim_type type, unsigned pos); + __isl_give isl_set *isl_set_set_dim_id( + __isl_take isl_set *set, enum isl_dim_type type, + unsigned pos, __isl_take isl_id *id); + isl_bool isl_set_has_dim_id(__isl_keep isl_set *set, + enum isl_dim_type type, unsigned pos); + __isl_give isl_id *isl_set_get_dim_id( + __isl_keep isl_set *set, enum isl_dim_type type, + unsigned pos); + const char *isl_basic_set_get_dim_name( + __isl_keep isl_basic_set *bset, + enum isl_dim_type type, unsigned pos); + isl_bool isl_set_has_dim_name(__isl_keep isl_set *set, + enum isl_dim_type type, unsigned pos); + const char *isl_set_get_dim_name( + __isl_keep isl_set *set, + enum isl_dim_type type, unsigned pos); + + #include + __isl_give isl_map *isl_map_set_dim_id( + __isl_take isl_map *map, enum isl_dim_type type, + unsigned pos, __isl_take isl_id *id); + isl_bool isl_basic_map_has_dim_id( + __isl_keep isl_basic_map *bmap, + enum isl_dim_type type, unsigned pos); + isl_bool isl_map_has_dim_id(__isl_keep isl_map *map, + enum isl_dim_type type, unsigned pos); + __isl_give isl_id *isl_map_get_dim_id( + __isl_keep isl_map *map, enum isl_dim_type type, + unsigned pos); + __isl_give isl_id *isl_union_map_get_dim_id( + __isl_keep isl_union_map *umap, + enum isl_dim_type type, unsigned pos); + const char *isl_basic_map_get_dim_name( + __isl_keep isl_basic_map *bmap, + enum isl_dim_type type, unsigned pos); + isl_bool isl_map_has_dim_name(__isl_keep isl_map *map, + enum isl_dim_type type, unsigned pos); + const char *isl_map_get_dim_name( + __isl_keep isl_map *map, + enum isl_dim_type type, unsigned pos); + + #include + __isl_give isl_multi_val *isl_multi_val_set_dim_id( + __isl_take isl_multi_val *mv, + enum isl_dim_type type, unsigned pos, + __isl_take isl_id *id); + __isl_give isl_id *isl_multi_val_get_dim_id( + __isl_keep isl_multi_val *mv, + enum isl_dim_type type, unsigned pos); + __isl_give isl_multi_val *isl_multi_val_set_dim_name( + __isl_take isl_multi_val *mv, + enum isl_dim_type type, unsigned pos, const char *s); + + #include + __isl_give isl_aff *isl_aff_set_dim_id( + __isl_take isl_aff *aff, enum isl_dim_type type, + unsigned pos, __isl_take isl_id *id); + __isl_give isl_multi_aff *isl_multi_aff_set_dim_id( + __isl_take isl_multi_aff *maff, + enum isl_dim_type type, unsigned pos, + __isl_take isl_id *id); + __isl_give isl_pw_aff *isl_pw_aff_set_dim_id( + __isl_take isl_pw_aff *pma, + enum isl_dim_type type, unsigned pos, + __isl_take isl_id *id); + __isl_give isl_multi_pw_aff * + isl_multi_pw_aff_set_dim_id( + __isl_take isl_multi_pw_aff *mpa, + enum isl_dim_type type, unsigned pos, + __isl_take isl_id *id); + __isl_give isl_multi_union_pw_aff * + isl_multi_union_pw_aff_set_dim_id( + __isl_take isl_multi_union_pw_aff *mupa, + enum isl_dim_type type, unsigned pos, + __isl_take isl_id *id); + __isl_give isl_id *isl_multi_aff_get_dim_id( + __isl_keep isl_multi_aff *ma, + enum isl_dim_type type, unsigned pos); + isl_bool isl_pw_aff_has_dim_id(__isl_keep isl_pw_aff *pa, + enum isl_dim_type type, unsigned pos); + __isl_give isl_id *isl_pw_aff_get_dim_id( + __isl_keep isl_pw_aff *pa, + enum isl_dim_type type, unsigned pos); + __isl_give isl_id *isl_pw_multi_aff_get_dim_id( + __isl_keep isl_pw_multi_aff *pma, + enum isl_dim_type type, unsigned pos); + __isl_give isl_id *isl_multi_pw_aff_get_dim_id( + __isl_keep isl_multi_pw_aff *mpa, + enum isl_dim_type type, unsigned pos); + __isl_give isl_id *isl_multi_union_pw_aff_get_dim_id( + __isl_keep isl_multi_union_pw_aff *mupa, + enum isl_dim_type type, unsigned pos); + __isl_give isl_aff *isl_aff_set_dim_name( + __isl_take isl_aff *aff, enum isl_dim_type type, + unsigned pos, const char *s); + __isl_give isl_multi_aff *isl_multi_aff_set_dim_name( + __isl_take isl_multi_aff *maff, + enum isl_dim_type type, unsigned pos, const char *s); + __isl_give isl_multi_pw_aff * + isl_multi_pw_aff_set_dim_name( + __isl_take isl_multi_pw_aff *mpa, + enum isl_dim_type type, unsigned pos, const char *s); + __isl_give isl_union_pw_aff * + isl_union_pw_aff_set_dim_name( + __isl_take isl_union_pw_aff *upa, + enum isl_dim_type type, unsigned pos, + const char *s); + __isl_give isl_union_pw_multi_aff * + isl_union_pw_multi_aff_set_dim_name( + __isl_take isl_union_pw_multi_aff *upma, + enum isl_dim_type type, unsigned pos, + const char *s); + __isl_give isl_multi_union_pw_aff * + isl_multi_union_pw_aff_set_dim_name( + __isl_take isl_multi_union_pw_aff *mupa, + enum isl_dim_type type, unsigned pos, + const char *s); + const char *isl_aff_get_dim_name(__isl_keep isl_aff *aff, + enum isl_dim_type type, unsigned pos); + const char *isl_pw_aff_get_dim_name( + __isl_keep isl_pw_aff *pa, + enum isl_dim_type type, unsigned pos); + const char *isl_pw_multi_aff_get_dim_name( + __isl_keep isl_pw_multi_aff *pma, + enum isl_dim_type type, unsigned pos); + + #include + __isl_give isl_qpolynomial *isl_qpolynomial_set_dim_name( + __isl_take isl_qpolynomial *qp, + enum isl_dim_type type, unsigned pos, + const char *s); + __isl_give isl_pw_qpolynomial * + isl_pw_qpolynomial_set_dim_name( + __isl_take isl_pw_qpolynomial *pwqp, + enum isl_dim_type type, unsigned pos, + const char *s); + __isl_give isl_pw_qpolynomial_fold * + isl_pw_qpolynomial_fold_set_dim_name( + __isl_take isl_pw_qpolynomial_fold *pwf, + enum isl_dim_type type, unsigned pos, + const char *s); + __isl_give isl_union_pw_qpolynomial * + isl_union_pw_qpolynomial_set_dim_name( + __isl_take isl_union_pw_qpolynomial *upwqp, + enum isl_dim_type type, unsigned pos, + const char *s); + __isl_give isl_union_pw_qpolynomial_fold * + isl_union_pw_qpolynomial_fold_set_dim_name( + __isl_take isl_union_pw_qpolynomial_fold *upwf, + enum isl_dim_type type, unsigned pos, + const char *s); + +Note that C returns a pointer to some internal +data structure, so the result can only be used while the +corresponding C is alive. +Also note that every function that operates on two sets or relations +requires that both arguments have the same parameters. This also +means that if one of the arguments has named parameters, then the +other needs to have named parameters too and the names need to match. +Pairs of C, C, C and/or C +arguments may have different parameters (as long as they are named), +in which case the result will have as parameters the union of the parameters of +the arguments. + +Given the identifier or name of a dimension (typically a parameter), +its position can be obtained from the following functions. + + #include + int isl_space_find_dim_by_id(__isl_keep isl_space *space, + enum isl_dim_type type, __isl_keep isl_id *id); + int isl_space_find_dim_by_name(__isl_keep isl_space *space, + enum isl_dim_type type, const char *name); + + #include + int isl_local_space_find_dim_by_name( + __isl_keep isl_local_space *ls, + enum isl_dim_type type, const char *name); + + #include + int isl_multi_val_find_dim_by_id( + __isl_keep isl_multi_val *mv, + enum isl_dim_type type, __isl_keep isl_id *id); + int isl_multi_val_find_dim_by_name( + __isl_keep isl_multi_val *mv, + enum isl_dim_type type, const char *name); + + #include + int isl_set_find_dim_by_id(__isl_keep isl_set *set, + enum isl_dim_type type, __isl_keep isl_id *id); + int isl_set_find_dim_by_name(__isl_keep isl_set *set, + enum isl_dim_type type, const char *name); + + #include + int isl_map_find_dim_by_id(__isl_keep isl_map *map, + enum isl_dim_type type, __isl_keep isl_id *id); + int isl_basic_map_find_dim_by_name( + __isl_keep isl_basic_map *bmap, + enum isl_dim_type type, const char *name); + int isl_map_find_dim_by_name(__isl_keep isl_map *map, + enum isl_dim_type type, const char *name); + int isl_union_map_find_dim_by_name( + __isl_keep isl_union_map *umap, + enum isl_dim_type type, const char *name); + + #include + int isl_multi_aff_find_dim_by_id( + __isl_keep isl_multi_aff *ma, + enum isl_dim_type type, __isl_keep isl_id *id); + int isl_multi_pw_aff_find_dim_by_id( + __isl_keep isl_multi_pw_aff *mpa, + enum isl_dim_type type, __isl_keep isl_id *id); + int isl_multi_union_pw_aff_find_dim_by_id( + __isl_keep isl_multi_union_pw_aff *mupa, + enum isl_dim_type type, __isl_keep isl_id *id); + int isl_aff_find_dim_by_name(__isl_keep isl_aff *aff, + enum isl_dim_type type, const char *name); + int isl_multi_aff_find_dim_by_name( + __isl_keep isl_multi_aff *ma, + enum isl_dim_type type, const char *name); + int isl_pw_aff_find_dim_by_name(__isl_keep isl_pw_aff *pa, + enum isl_dim_type type, const char *name); + int isl_multi_pw_aff_find_dim_by_name( + __isl_keep isl_multi_pw_aff *mpa, + enum isl_dim_type type, const char *name); + int isl_pw_multi_aff_find_dim_by_name( + __isl_keep isl_pw_multi_aff *pma, + enum isl_dim_type type, const char *name); + int isl_union_pw_aff_find_dim_by_name( + __isl_keep isl_union_pw_aff *upa, + enum isl_dim_type type, const char *name); + int isl_union_pw_multi_aff_find_dim_by_name( + __isl_keep isl_union_pw_multi_aff *upma, + enum isl_dim_type type, const char *name); + int isl_multi_union_pw_aff_find_dim_by_name( + __isl_keep isl_multi_union_pw_aff *mupa, + enum isl_dim_type type, const char *name); + + #include + int isl_pw_qpolynomial_find_dim_by_name( + __isl_keep isl_pw_qpolynomial *pwqp, + enum isl_dim_type type, const char *name); + int isl_pw_qpolynomial_fold_find_dim_by_name( + __isl_keep isl_pw_qpolynomial_fold *pwf, + enum isl_dim_type type, const char *name); + int isl_union_pw_qpolynomial_find_dim_by_name( + __isl_keep isl_union_pw_qpolynomial *upwqp, + enum isl_dim_type type, const char *name); + int isl_union_pw_qpolynomial_fold_find_dim_by_name( + __isl_keep isl_union_pw_qpolynomial_fold *upwf, + enum isl_dim_type type, const char *name); + +The identifiers or names of entire spaces may be set or read off +using the following functions. + + #include + __isl_give isl_space *isl_space_set_domain_tuple_id( + __isl_take isl_space *space, + __isl_take isl_id *id); + __isl_give isl_space *isl_space_set_range_tuple_id( + __isl_take isl_space *space, + __isl_take isl_id *id); + __isl_give isl_space *isl_space_set_tuple_id( + __isl_take isl_space *space, + enum isl_dim_type type, __isl_take isl_id *id); + __isl_give isl_space *isl_space_reset_tuple_id( + __isl_take isl_space *space, enum isl_dim_type type); + isl_bool isl_space_has_domain_tuple_id( + __isl_keep isl_space *space); + isl_bool isl_space_has_range_tuple_id( + __isl_keep isl_space *space); + isl_bool isl_space_has_tuple_id( + __isl_keep isl_space *space, + enum isl_dim_type type); + __isl_give isl_id *isl_space_get_domain_tuple_id( + __isl_keep isl_space *space); + __isl_give isl_id *isl_space_get_range_tuple_id( + __isl_keep isl_space *space); + __isl_give isl_id *isl_space_get_tuple_id( + __isl_keep isl_space *space, enum isl_dim_type type); + __isl_give isl_space *isl_space_set_tuple_name( + __isl_take isl_space *space, + enum isl_dim_type type, const char *s); + isl_bool isl_space_has_tuple_name( + __isl_keep isl_space *space, + enum isl_dim_type type); + __isl_keep const char *isl_space_get_tuple_name( + __isl_keep isl_space *space, + enum isl_dim_type type); + + #include + __isl_give isl_local_space *isl_local_space_set_tuple_id( + __isl_take isl_local_space *ls, + enum isl_dim_type type, __isl_take isl_id *id); + + #include + __isl_give isl_basic_set *isl_basic_set_set_tuple_id( + __isl_take isl_basic_set *bset, + __isl_take isl_id *id); + __isl_give isl_set *isl_set_set_tuple_id( + __isl_take isl_set *set, __isl_take isl_id *id); + __isl_give isl_set *isl_set_reset_tuple_id( + __isl_take isl_set *set); + isl_bool isl_set_has_tuple_id(__isl_keep isl_set *set); + __isl_give isl_id *isl_set_get_tuple_id( + __isl_keep isl_set *set); + __isl_give isl_basic_set *isl_basic_set_set_tuple_name( + __isl_take isl_basic_set *set, const char *s); + __isl_give isl_set *isl_set_set_tuple_name( + __isl_take isl_set *set, const char *s); + const char *isl_basic_set_get_tuple_name( + __isl_keep isl_basic_set *bset); + isl_bool isl_set_has_tuple_name(__isl_keep isl_set *set); + const char *isl_set_get_tuple_name( + __isl_keep isl_set *set); + + #include + __isl_give isl_basic_map *isl_basic_map_set_tuple_id( + __isl_take isl_basic_map *bmap, + enum isl_dim_type type, __isl_take isl_id *id); + __isl_give isl_map *isl_map_set_domain_tuple_id( + __isl_take isl_map *map, __isl_take isl_id *id); + __isl_give isl_map *isl_map_set_range_tuple_id( + __isl_take isl_map *map, __isl_take isl_id *id); + __isl_give isl_map *isl_map_set_tuple_id( + __isl_take isl_map *map, enum isl_dim_type type, + __isl_take isl_id *id); + __isl_give isl_map *isl_map_reset_tuple_id( + __isl_take isl_map *map, enum isl_dim_type type); + isl_bool isl_map_has_domain_tuple_id( + __isl_keep isl_map *map); + isl_bool isl_map_has_range_tuple_id( + __isl_keep isl_map *map); + isl_bool isl_map_has_tuple_id(__isl_keep isl_map *map, + enum isl_dim_type type); + __isl_give isl_id *isl_map_get_domain_tuple_id( + __isl_keep isl_map *map); + __isl_give isl_id *isl_map_get_range_tuple_id( + __isl_keep isl_map *map); + __isl_give isl_id *isl_map_get_tuple_id( + __isl_keep isl_map *map, enum isl_dim_type type); + __isl_give isl_map *isl_map_set_tuple_name( + __isl_take isl_map *map, + enum isl_dim_type type, const char *s); + const char *isl_basic_map_get_tuple_name( + __isl_keep isl_basic_map *bmap, + enum isl_dim_type type); + __isl_give isl_basic_map *isl_basic_map_set_tuple_name( + __isl_take isl_basic_map *bmap, + enum isl_dim_type type, const char *s); + isl_bool isl_map_has_tuple_name(__isl_keep isl_map *map, + enum isl_dim_type type); + const char *isl_map_get_tuple_name( + __isl_keep isl_map *map, + enum isl_dim_type type); + + #include + __isl_give isl_multi_val *isl_multi_val_set_range_tuple_id( + __isl_take isl_multi_val *mv, + __isl_take isl_id *id); + __isl_give isl_multi_val *isl_multi_val_set_tuple_id( + __isl_take isl_multi_val *mv, + enum isl_dim_type type, __isl_take isl_id *id); + __isl_give isl_multi_val * + isl_multi_val_reset_range_tuple_id( + __isl_take isl_multi_val *mv); + __isl_give isl_multi_val *isl_multi_val_reset_tuple_id( + __isl_take isl_multi_val *mv, + enum isl_dim_type type); + isl_bool isl_multi_val_has_range_tuple_id( + __isl_keep isl_multi_val *mv); + __isl_give isl_id *isl_multi_val_get_range_tuple_id( + __isl_keep isl_multi_val *mv); + isl_bool isl_multi_val_has_tuple_id( + __isl_keep isl_multi_val *mv, + enum isl_dim_type type); + __isl_give isl_id *isl_multi_val_get_tuple_id( + __isl_keep isl_multi_val *mv, + enum isl_dim_type type); + __isl_give isl_multi_val *isl_multi_val_set_tuple_name( + __isl_take isl_multi_val *mv, + enum isl_dim_type type, const char *s); + const char *isl_multi_val_get_tuple_name( + __isl_keep isl_multi_val *mv, + enum isl_dim_type type); + + #include + __isl_give isl_aff *isl_aff_set_tuple_id( + __isl_take isl_aff *aff, + enum isl_dim_type type, __isl_take isl_id *id); + __isl_give isl_multi_aff *isl_multi_aff_set_range_tuple_id( + __isl_take isl_multi_aff *ma, + __isl_take isl_id *id); + __isl_give isl_multi_aff *isl_multi_aff_set_tuple_id( + __isl_take isl_multi_aff *maff, + enum isl_dim_type type, __isl_take isl_id *id); + __isl_give isl_pw_aff *isl_pw_aff_set_tuple_id( + __isl_take isl_pw_aff *pwaff, + enum isl_dim_type type, __isl_take isl_id *id); + __isl_give isl_pw_multi_aff * + isl_pw_multi_aff_set_range_tuple_id( + __isl_take isl_pw_multi_aff *pma, + __isl_take isl_id *id); + __isl_give isl_pw_multi_aff *isl_pw_multi_aff_set_tuple_id( + __isl_take isl_pw_multi_aff *pma, + enum isl_dim_type type, __isl_take isl_id *id); + __isl_give isl_multi_pw_aff * + isl_multi_pw_aff_set_range_tuple_id( + __isl_take isl_multi_pw_aff *mpa, + __isl_take isl_id *id); + __isl_give isl_multi_union_pw_aff * + isl_multi_union_pw_aff_set_range_tuple_id( + __isl_take isl_multi_union_pw_aff *mupa, + __isl_take isl_id *id); + __isl_give isl_multi_union_pw_aff * + isl_multi_union_pw_aff_set_tuple_id( + __isl_take isl_multi_union_pw_aff *mupa, + enum isl_dim_type type, __isl_take isl_id *id); + __isl_give isl_multi_aff * + isl_multi_aff_reset_range_tuple_id( + __isl_take isl_multi_aff *ma); + __isl_give isl_multi_pw_aff * + isl_multi_pw_aff_reset_range_tuple_id( + __isl_take isl_multi_pw_aff *mpa); + __isl_give isl_multi_union_pw_aff * + isl_multi_union_pw_aff_reset_range_tuple_id( + __isl_take isl_multi_union_pw_aff *mupa); + __isl_give isl_multi_aff *isl_multi_aff_reset_tuple_id( + __isl_take isl_multi_aff *ma, + enum isl_dim_type type); + __isl_give isl_pw_aff *isl_pw_aff_reset_tuple_id( + __isl_take isl_pw_aff *pa, + enum isl_dim_type type); + __isl_give isl_multi_pw_aff * + isl_multi_pw_aff_reset_tuple_id( + __isl_take isl_multi_pw_aff *mpa, + enum isl_dim_type type); + __isl_give isl_pw_multi_aff * + isl_pw_multi_aff_reset_tuple_id( + __isl_take isl_pw_multi_aff *pma, + enum isl_dim_type type); + __isl_give isl_multi_union_pw_aff * + isl_multi_union_pw_aff_reset_tuple_id( + __isl_take isl_multi_union_pw_aff *mupa, + enum isl_dim_type type); + isl_bool isl_multi_aff_has_range_tuple_id( + __isl_keep isl_multi_aff *ma); + __isl_give isl_id *isl_multi_aff_get_range_tuple_id( + __isl_keep isl_multi_aff *ma); + isl_bool isl_multi_aff_has_tuple_id( + __isl_keep isl_multi_aff *ma, + enum isl_dim_type type); + __isl_give isl_id *isl_multi_aff_get_tuple_id( + __isl_keep isl_multi_aff *ma, + enum isl_dim_type type); + isl_bool isl_pw_aff_has_tuple_id(__isl_keep isl_pw_aff *pa, + enum isl_dim_type type); + __isl_give isl_id *isl_pw_aff_get_tuple_id( + __isl_keep isl_pw_aff *pa, + enum isl_dim_type type); + isl_bool isl_pw_multi_aff_has_range_tuple_id( + __isl_keep isl_pw_multi_aff *pma); + isl_bool isl_pw_multi_aff_has_tuple_id( + __isl_keep isl_pw_multi_aff *pma, + enum isl_dim_type type); + __isl_give isl_id *isl_pw_multi_aff_get_range_tuple_id( + __isl_keep isl_pw_multi_aff *pma); + __isl_give isl_id *isl_pw_multi_aff_get_tuple_id( + __isl_keep isl_pw_multi_aff *pma, + enum isl_dim_type type); + isl_bool isl_multi_pw_aff_has_range_tuple_id( + __isl_keep isl_multi_pw_aff *mpa); + __isl_give isl_id *isl_multi_pw_aff_get_range_tuple_id( + __isl_keep isl_multi_pw_aff *mpa); + isl_bool isl_multi_pw_aff_has_tuple_id( + __isl_keep isl_multi_pw_aff *mpa, + enum isl_dim_type type); + __isl_give isl_id *isl_multi_pw_aff_get_tuple_id( + __isl_keep isl_multi_pw_aff *mpa, + enum isl_dim_type type); + isl_bool isl_multi_union_pw_aff_has_range_tuple_id( + __isl_keep isl_multi_union_pw_aff *mupa); + __isl_give isl_id * + isl_multi_union_pw_aff_get_range_tuple_id( + __isl_keep isl_multi_union_pw_aff *mupa); + isl_bool isl_multi_union_pw_aff_has_tuple_id( + __isl_keep isl_multi_union_pw_aff *mupa, + enum isl_dim_type type); + __isl_give isl_id *isl_multi_union_pw_aff_get_tuple_id( + __isl_keep isl_multi_union_pw_aff *mupa, + enum isl_dim_type type); + __isl_give isl_multi_aff *isl_multi_aff_set_tuple_name( + __isl_take isl_multi_aff *maff, + enum isl_dim_type type, const char *s); + __isl_give isl_multi_pw_aff * + isl_multi_pw_aff_set_tuple_name( + __isl_take isl_multi_pw_aff *mpa, + enum isl_dim_type type, const char *s); + __isl_give isl_multi_union_pw_aff * + isl_multi_union_pw_aff_set_tuple_name( + __isl_take isl_multi_union_pw_aff *mupa, + enum isl_dim_type type, const char *s); + const char *isl_multi_aff_get_tuple_name( + __isl_keep isl_multi_aff *multi, + enum isl_dim_type type); + isl_bool isl_pw_multi_aff_has_tuple_name( + __isl_keep isl_pw_multi_aff *pma, + enum isl_dim_type type); + const char *isl_pw_multi_aff_get_tuple_name( + __isl_keep isl_pw_multi_aff *pma, + enum isl_dim_type type); + const char *isl_multi_union_pw_aff_get_tuple_name( + __isl_keep isl_multi_union_pw_aff *mupa, + enum isl_dim_type type); + +The C argument needs to be one of C, C +or C. As with C, +the C function returns a pointer to some internal +data structure. +Binary operations require the corresponding spaces of their arguments +to have the same name. + +To keep the names of all parameters and tuples, but reset the user pointers +of all the corresponding identifiers, use the following function. + + #include + __isl_give isl_space *isl_space_reset_user( + __isl_take isl_space *space); + + #include + __isl_give isl_set *isl_set_reset_user( + __isl_take isl_set *set); + + #include + __isl_give isl_map *isl_map_reset_user( + __isl_take isl_map *map); + + #include + __isl_give isl_union_set *isl_union_set_reset_user( + __isl_take isl_union_set *uset); + + #include + __isl_give isl_union_map *isl_union_map_reset_user( + __isl_take isl_union_map *umap); + + #include + __isl_give isl_multi_id *isl_multi_id_reset_user( + __isl_take isl_multi_id *mi); + + #include + __isl_give isl_multi_val *isl_multi_val_reset_user( + __isl_take isl_multi_val *mv); + + #include + __isl_give isl_multi_aff *isl_multi_aff_reset_user( + __isl_take isl_multi_aff *ma); + __isl_give isl_pw_aff *isl_pw_aff_reset_user( + __isl_take isl_pw_aff *pa); + __isl_give isl_multi_pw_aff *isl_multi_pw_aff_reset_user( + __isl_take isl_multi_pw_aff *mpa); + __isl_give isl_pw_multi_aff *isl_pw_multi_aff_reset_user( + __isl_take isl_pw_multi_aff *pma); + __isl_give isl_union_pw_aff *isl_union_pw_aff_reset_user( + __isl_take isl_union_pw_aff *upa); + __isl_give isl_multi_union_pw_aff * + isl_multi_union_pw_aff_reset_user( + __isl_take isl_multi_union_pw_aff *mupa); + __isl_give isl_union_pw_multi_aff * + isl_union_pw_multi_aff_reset_user( + __isl_take isl_union_pw_multi_aff *upma); + + #include + __isl_give isl_pw_qpolynomial * + isl_pw_qpolynomial_reset_user( + __isl_take isl_pw_qpolynomial *pwqp); + __isl_give isl_union_pw_qpolynomial * + isl_union_pw_qpolynomial_reset_user( + __isl_take isl_union_pw_qpolynomial *upwqp); + __isl_give isl_pw_qpolynomial_fold * + isl_pw_qpolynomial_fold_reset_user( + __isl_take isl_pw_qpolynomial_fold *pwf); + __isl_give isl_union_pw_qpolynomial_fold * + isl_union_pw_qpolynomial_fold_reset_user( + __isl_take isl_union_pw_qpolynomial_fold *upwf); + +Spaces can be nested. In particular, the domain of a set or +the domain or range of a relation can be a nested relation. +This process is also called I. +The functions for detecting, constructing and deconstructing +such nested spaces can be found in the wrapping properties +of L, the wrapping operations +of L and the Cartesian product operations +of L. + +Spaces can be created from other spaces +using the functions described in L +and L. + +=head2 Local Spaces + +A local space is essentially a space with +zero or more existentially quantified variables. +The local space of various objects can be obtained +using the following functions. + + #include + __isl_give isl_local_space *isl_constraint_get_local_space( + __isl_keep isl_constraint *constraint); + + #include + __isl_give isl_local_space *isl_basic_set_get_local_space( + __isl_keep isl_basic_set *bset); + + #include + __isl_give isl_local_space *isl_basic_map_get_local_space( + __isl_keep isl_basic_map *bmap); + + #include + __isl_give isl_local_space *isl_aff_get_domain_local_space( + __isl_keep isl_aff *aff); + __isl_give isl_local_space *isl_aff_get_local_space( + __isl_keep isl_aff *aff); + +A new local space can be created from a space using + + #include + __isl_give isl_local_space *isl_local_space_from_space( + __isl_take isl_space *space); + +They can be inspected, modified, copied and freed using the following functions. + + #include + isl_bool isl_local_space_is_params( + __isl_keep isl_local_space *ls); + isl_bool isl_local_space_is_set( + __isl_keep isl_local_space *ls); + __isl_give isl_space *isl_local_space_get_space( + __isl_keep isl_local_space *ls); + __isl_give isl_aff *isl_local_space_get_div( + __isl_keep isl_local_space *ls, int pos); + __isl_give isl_local_space *isl_local_space_copy( + __isl_keep isl_local_space *ls); + __isl_null isl_local_space *isl_local_space_free( + __isl_take isl_local_space *ls); + +Note that C can only be used on local spaces +of sets. + +Two local spaces can be compared using + + isl_bool isl_local_space_is_equal( + __isl_keep isl_local_space *ls1, + __isl_keep isl_local_space *ls2); + +Local spaces can be created from other local spaces +using the functions described in L +and L. + +=head2 Creating New Sets and Relations + +C has functions for creating some standard sets and relations. + +=over + +=item * Empty sets and relations + + __isl_give isl_basic_set *isl_basic_set_empty( + __isl_take isl_space *space); + __isl_give isl_basic_map *isl_basic_map_empty( + __isl_take isl_space *space); + __isl_give isl_set *isl_set_empty( + __isl_take isl_space *space); + __isl_give isl_map *isl_map_empty( + __isl_take isl_space *space); + __isl_give isl_union_set *isl_union_set_empty_ctx( + isl_ctx *ctx); + __isl_give isl_union_set *isl_union_set_empty_space( + __isl_take isl_space *space); + __isl_give isl_union_set *isl_union_set_empty( + __isl_take isl_space *space); + __isl_give isl_union_map *isl_union_map_empty_ctx( + isl_ctx *ctx); + __isl_give isl_union_map *isl_union_map_empty_space( + __isl_take isl_space *space); + __isl_give isl_union_map *isl_union_map_empty( + __isl_take isl_space *space); + +For Cs and Cs, the space +is only used to specify the parameters. +C is an alternative name for +C. +Similarly for the other pair of functions. + +=item * Universe sets and relations + + #include + __isl_give isl_basic_set *isl_basic_set_universe( + __isl_take isl_space *space); + __isl_give isl_set *isl_set_universe( + __isl_take isl_space *space); + __isl_give isl_set *isl_space_universe_set( + __isl_take isl_space *space); + + #include + __isl_give isl_basic_map *isl_basic_map_universe( + __isl_take isl_space *space); + __isl_give isl_map *isl_map_universe( + __isl_take isl_space *space); + __isl_give isl_map *isl_space_universe_map( + __isl_take isl_space *space); + + #include + __isl_give isl_union_set *isl_union_set_universe( + __isl_take isl_union_set *uset); + + #include + __isl_give isl_union_map *isl_union_map_universe( + __isl_take isl_union_map *umap); + +C and C +perform the same operation. +Similarly +for the pair C and C. + +The sets and relations constructed by the functions above +contain all integer values, while those constructed by the +functions below only contain non-negative values. + + __isl_give isl_basic_set *isl_basic_set_nat_universe( + __isl_take isl_space *space); + __isl_give isl_basic_map *isl_basic_map_nat_universe( + __isl_take isl_space *space); + __isl_give isl_set *isl_set_nat_universe( + __isl_take isl_space *space); + __isl_give isl_map *isl_map_nat_universe( + __isl_take isl_space *space); + +=item * Identity relations + + __isl_give isl_basic_map *isl_basic_map_identity( + __isl_take isl_space *space); + __isl_give isl_map *isl_map_identity( + __isl_take isl_space *space); + +The number of input and output dimensions in C needs +to be the same. + +=item * Lexicographic order + + __isl_give isl_map *isl_map_lex_lt( + __isl_take isl_space *set_space); + __isl_give isl_map *isl_map_lex_le( + __isl_take isl_space *set_space); + __isl_give isl_map *isl_map_lex_gt( + __isl_take isl_space *set_space); + __isl_give isl_map *isl_map_lex_ge( + __isl_take isl_space *set_space); + __isl_give isl_map *isl_map_lex_lt_first( + __isl_take isl_space *space, unsigned n); + __isl_give isl_map *isl_map_lex_le_first( + __isl_take isl_space *space, unsigned n); + __isl_give isl_map *isl_map_lex_gt_first( + __isl_take isl_space *space, unsigned n); + __isl_give isl_map *isl_map_lex_ge_first( + __isl_take isl_space *space, unsigned n); + +The first four functions take a space for a B +and return relations that express that the elements in the domain +are lexicographically less +(C), less or equal (C), +greater (C) or greater or equal (C) +than the elements in the range. +The last four functions take a space for a map +and return relations that express that the first C dimensions +in the domain are lexicographically less +(C), less or equal (C), +greater (C) or greater or equal (C) +than the first C dimensions in the range. + +=back + +A basic set or relation can be converted to a set or relation +using the following functions. + + __isl_give isl_set *isl_basic_set_to_set( + __isl_take isl_basic_set *bset); + __isl_give isl_set *isl_set_from_basic_set( + __isl_take isl_basic_set *bset); + __isl_give isl_map *isl_map_from_basic_map( + __isl_take isl_basic_map *bmap); + +C and C perform +the same operation. + +Sets and relations can be converted to union sets and relations +using the following functions. + + __isl_give isl_union_set *isl_union_set_from_basic_set( + __isl_take isl_basic_set *bset); + __isl_give isl_union_map *isl_union_map_from_basic_map( + __isl_take isl_basic_map *bmap); + __isl_give isl_union_set *isl_set_to_union_set( + __isl_take isl_set *set); + __isl_give isl_union_set *isl_union_set_from_set( + __isl_take isl_set *set); + __isl_give isl_union_map *isl_map_to_union_map( + __isl_take isl_map *map); + __isl_give isl_union_map *isl_union_map_from_map( + __isl_take isl_map *map); + +C and C perform +the same operation. +Similarly for C and C. + +The inverse conversions below can only be used if the input +union set or relation is known to contain elements in exactly one +space. + + #include + isl_bool isl_union_set_isa_set( + __isl_keep isl_union_set *uset); + __isl_give isl_set *isl_union_set_as_set( + __isl_take isl_union_set *uset); + __isl_give isl_set *isl_set_from_union_set( + __isl_take isl_union_set *uset); + + #include + isl_bool isl_union_map_isa_map( + __isl_keep isl_union_map *umap); + __isl_give isl_map *isl_union_map_as_map( + __isl_take isl_union_map *umap); + __isl_give isl_map *isl_map_from_union_map( + __isl_take isl_union_map *umap); + +C and C perform +the same operation. +Similarly for C and C. + +Sets and relations can be copied and freed again using the following +functions. + + __isl_give isl_basic_set *isl_basic_set_copy( + __isl_keep isl_basic_set *bset); + __isl_give isl_set *isl_set_copy(__isl_keep isl_set *set); + __isl_give isl_union_set *isl_union_set_copy( + __isl_keep isl_union_set *uset); + __isl_give isl_basic_map *isl_basic_map_copy( + __isl_keep isl_basic_map *bmap); + __isl_give isl_map *isl_map_copy(__isl_keep isl_map *map); + __isl_give isl_union_map *isl_union_map_copy( + __isl_keep isl_union_map *umap); + __isl_null isl_basic_set *isl_basic_set_free( + __isl_take isl_basic_set *bset); + __isl_null isl_set *isl_set_free(__isl_take isl_set *set); + __isl_null isl_union_set *isl_union_set_free( + __isl_take isl_union_set *uset); + __isl_null isl_basic_map *isl_basic_map_free( + __isl_take isl_basic_map *bmap); + __isl_null isl_map *isl_map_free(__isl_take isl_map *map); + __isl_null isl_union_map *isl_union_map_free( + __isl_take isl_union_map *umap); + +Other sets and relations can be constructed by starting +from a universe set or relation, adding equality and/or +inequality constraints and then projecting out the +existentially quantified variables, if any. +Constraints can be constructed, manipulated and +added to (or removed from) (basic) sets and relations +using the following functions. + + #include + __isl_give isl_constraint *isl_constraint_alloc_equality( + __isl_take isl_local_space *ls); + __isl_give isl_constraint *isl_constraint_alloc_inequality( + __isl_take isl_local_space *ls); + __isl_give isl_constraint *isl_constraint_set_constant_si( + __isl_take isl_constraint *constraint, int v); + __isl_give isl_constraint *isl_constraint_set_constant_val( + __isl_take isl_constraint *constraint, + __isl_take isl_val *v); + __isl_give isl_constraint *isl_constraint_set_coefficient_si( + __isl_take isl_constraint *constraint, + enum isl_dim_type type, int pos, int v); + __isl_give isl_constraint * + isl_constraint_set_coefficient_val( + __isl_take isl_constraint *constraint, + enum isl_dim_type type, int pos, + __isl_take isl_val *v); + __isl_give isl_basic_map *isl_basic_map_add_constraint( + __isl_take isl_basic_map *bmap, + __isl_take isl_constraint *constraint); + __isl_give isl_basic_set *isl_basic_set_add_constraint( + __isl_take isl_basic_set *bset, + __isl_take isl_constraint *constraint); + __isl_give isl_map *isl_map_add_constraint( + __isl_take isl_map *map, + __isl_take isl_constraint *constraint); + __isl_give isl_set *isl_set_add_constraint( + __isl_take isl_set *set, + __isl_take isl_constraint *constraint); + +For example, to create a set containing the even integers +between 10 and 42, you could use the following code. + + isl_space *space; + isl_local_space *ls; + isl_constraint *c; + isl_basic_set *bset; + + space = isl_space_set_alloc(ctx, 0, 2); + bset = isl_basic_set_universe(isl_space_copy(space)); + ls = isl_local_space_from_space(space); + + c = isl_constraint_alloc_equality(isl_local_space_copy(ls)); + c = isl_constraint_set_coefficient_si(c, isl_dim_set, 0, -1); + c = isl_constraint_set_coefficient_si(c, isl_dim_set, 1, 2); + bset = isl_basic_set_add_constraint(bset, c); + + c = isl_constraint_alloc_inequality(isl_local_space_copy(ls)); + c = isl_constraint_set_constant_si(c, -10); + c = isl_constraint_set_coefficient_si(c, isl_dim_set, 0, 1); + bset = isl_basic_set_add_constraint(bset, c); + + c = isl_constraint_alloc_inequality(ls); + c = isl_constraint_set_constant_si(c, 42); + c = isl_constraint_set_coefficient_si(c, isl_dim_set, 0, -1); + bset = isl_basic_set_add_constraint(bset, c); + + bset = isl_basic_set_project_out(bset, isl_dim_set, 1, 1); + +However, this is considered to be a fairly low-level approach. +It is more appropriate to construct a (basic) set by means +of affine expressions (defined below in L). +For example, the same set could be constructed as follows. + + isl_val *v, *two; + isl_space *space; + isl_multi_aff *ma; + isl_aff *var, *cst; + isl_basic_set *bset; + + space = isl_space_unit(ctx); + space = isl_space_add_unnamed_tuple_ui(space, 1); + ma = isl_multi_aff_identity_on_domain_space( + isl_space_copy(space)); + var = isl_multi_aff_get_at(ma, 0); + v = isl_val_int_from_si(ctx, 10); + cst = isl_aff_val_on_domain_space(isl_space_copy(space), v); + bset = isl_aff_ge_basic_set(isl_aff_copy(var), cst); + + v = isl_val_int_from_si(ctx, 42); + cst = isl_aff_val_on_domain_space(space, v); + bset = isl_basic_set_intersect(bset, + isl_aff_le_basic_set(var, cst)); + + two = isl_val_int_from_si(ctx, 2); + ma = isl_multi_aff_scale_val(ma, isl_val_copy(two)); + bset = isl_basic_set_preimage_multi_aff(bset, + isl_multi_aff_copy(ma)); + ma = isl_multi_aff_scale_down_val(ma, isl_val_copy(two)); + ma = isl_multi_aff_scale_down_val(ma, two); + bset = isl_basic_set_preimage_multi_aff(bset, ma); + +Alternatively, the set can be parsed from a string representation. + + isl_basic_set *bset; + bset = isl_basic_set_read_from_str(ctx, + "{[i] : exists (a : i = 2a and i >= 10 and i <= 42)}"); + +A basic set or relation can also be constructed from two matrices +describing the equalities and the inequalities. + + __isl_give isl_basic_set *isl_basic_set_from_constraint_matrices( + __isl_take isl_space *space, + __isl_take isl_mat *eq, __isl_take isl_mat *ineq, + enum isl_dim_type c1, + enum isl_dim_type c2, enum isl_dim_type c3, + enum isl_dim_type c4); + __isl_give isl_basic_map *isl_basic_map_from_constraint_matrices( + __isl_take isl_space *space, + __isl_take isl_mat *eq, __isl_take isl_mat *ineq, + enum isl_dim_type c1, + enum isl_dim_type c2, enum isl_dim_type c3, + enum isl_dim_type c4, enum isl_dim_type c5); + +The C arguments indicate the order in which +different kinds of variables appear in the input matrices +and should be a permutation of C (the constant term), +C, C and C for sets and +of C, C, +C, C and C for relations. + +A (basic or union) set or relation can also be constructed from a +(union) (piecewise) (multiple) affine expression +or a list of affine expressions +(See L), provided these affine expressions do not +involve any NaN. + + #include + __isl_give isl_basic_set *isl_basic_set_from_multi_aff( + __isl_take isl_multi_aff *ma); + __isl_give isl_set *isl_multi_aff_as_set( + __isl_take isl_multi_aff *ma); + __isl_give isl_set *isl_set_from_multi_aff( + __isl_take isl_multi_aff *ma); + + #include + __isl_give isl_basic_map *isl_basic_map_from_aff( + __isl_take isl_aff *aff); + __isl_give isl_map *isl_map_from_aff( + __isl_take isl_aff *aff); + __isl_give isl_basic_map *isl_basic_map_from_aff_list( + __isl_take isl_space *domain_space, + __isl_take isl_aff_list *list); + __isl_give isl_basic_map *isl_basic_map_from_multi_aff( + __isl_take isl_multi_aff *maff) + __isl_give isl_map *isl_multi_aff_as_map( + __isl_take isl_multi_aff *ma); + __isl_give isl_map *isl_map_from_multi_aff( + __isl_take isl_multi_aff *maff) + + #include + __isl_give isl_set *isl_set_from_pw_aff( + __isl_take isl_pw_aff *pwaff); + __isl_give isl_map *isl_pw_aff_as_map( + __isl_take isl_pw_aff *pa); + __isl_give isl_map *isl_map_from_pw_aff( + __isl_take isl_pw_aff *pwaff); + __isl_give isl_set *isl_pw_multi_aff_as_set( + __isl_take isl_pw_multi_aff *pma); + __isl_give isl_set *isl_set_from_pw_multi_aff( + __isl_take isl_pw_multi_aff *pma); + __isl_give isl_map *isl_pw_multi_aff_as_map( + __isl_take isl_pw_multi_aff *pma); + __isl_give isl_map *isl_map_from_pw_multi_aff( + __isl_take isl_pw_multi_aff *pma); + __isl_give isl_set *isl_multi_pw_aff_as_set( + __isl_take isl_multi_pw_aff *mpa); + __isl_give isl_set *isl_set_from_multi_pw_aff( + __isl_take isl_multi_pw_aff *mpa); + __isl_give isl_map *isl_multi_pw_aff_as_map( + __isl_take isl_multi_pw_aff *mpa); + __isl_give isl_map *isl_map_from_multi_pw_aff( + __isl_take isl_multi_pw_aff *mpa); + __isl_give isl_union_map *isl_union_map_from_union_pw_aff( + __isl_take isl_union_pw_aff *upa); + __isl_give isl_union_map * + isl_union_pw_multi_aff_as_union_map( + __isl_take isl_union_pw_multi_aff *upma); + __isl_give isl_union_map * + isl_union_map_from_union_pw_multi_aff( + __isl_take isl_union_pw_multi_aff *upma); + __isl_give isl_union_map * + isl_union_map_from_multi_union_pw_aff( + __isl_take isl_multi_union_pw_aff *mupa); + +The C argument describes the domain of the resulting +basic relation. It is required because the C may consist +of zero affine expressions. +The C passed to C +is not allowed to be zero-dimensional. The domain of the result +is the shared domain of the union piecewise affine elements. +C and C perform +the same operation. +Similarly for the pair C and C, +for the pair C and C, +for the pair C and C, +for the pair C and C, +the pair C and C, +the pair C and C, +and +C and +C. + +=head2 Inspecting Sets and Relations + +Usually, the user should not have to care about the actual constraints +of the sets and maps, but should instead apply the abstract operations +explained in the following sections. +Occasionally, however, it may be required to inspect the individual +coefficients of the constraints. This section explains how to do so. +In these cases, it may also be useful to have C compute +an explicit representation of the existentially quantified variables. + + __isl_give isl_set *isl_set_compute_divs( + __isl_take isl_set *set); + __isl_give isl_map *isl_map_compute_divs( + __isl_take isl_map *map); + __isl_give isl_union_set *isl_union_set_compute_divs( + __isl_take isl_union_set *uset); + __isl_give isl_union_map *isl_union_map_compute_divs( + __isl_take isl_union_map *umap); + +This explicit representation defines the existentially quantified +variables as integer divisions of the other variables, possibly +including earlier existentially quantified variables. +An explicitly represented existentially quantified variable therefore +has a unique value when the values of the other variables are known. + +Alternatively, the existentially quantified variables can be removed +using the following functions, which compute an overapproximation. + + #include + __isl_give isl_basic_set *isl_basic_set_remove_divs( + __isl_take isl_basic_set *bset); + __isl_give isl_set *isl_set_remove_divs( + __isl_take isl_set *set); + + #include + __isl_give isl_basic_map *isl_basic_map_remove_divs( + __isl_take isl_basic_map *bmap); + __isl_give isl_map *isl_map_remove_divs( + __isl_take isl_map *map); + + #include + __isl_give isl_union_set *isl_union_set_remove_divs( + __isl_take isl_union_set *bset); + + #include + __isl_give isl_union_map *isl_union_map_remove_divs( + __isl_take isl_union_map *bmap); + +It is also possible to only remove those divs that are defined +in terms of a given range of dimensions or only those for which +no explicit representation is known. + + __isl_give isl_basic_set * + isl_basic_set_remove_divs_involving_dims( + __isl_take isl_basic_set *bset, + enum isl_dim_type type, + unsigned first, unsigned n); + __isl_give isl_basic_map * + isl_basic_map_remove_divs_involving_dims( + __isl_take isl_basic_map *bmap, + enum isl_dim_type type, + unsigned first, unsigned n); + __isl_give isl_set *isl_set_remove_divs_involving_dims( + __isl_take isl_set *set, enum isl_dim_type type, + unsigned first, unsigned n); + __isl_give isl_map *isl_map_remove_divs_involving_dims( + __isl_take isl_map *map, enum isl_dim_type type, + unsigned first, unsigned n); + + __isl_give isl_basic_set * + isl_basic_set_remove_unknown_divs( + __isl_take isl_basic_set *bset); + __isl_give isl_set *isl_set_remove_unknown_divs( + __isl_take isl_set *set); + __isl_give isl_map *isl_map_remove_unknown_divs( + __isl_take isl_map *map); + +To iterate over all the sets or maps in a union set or map, use + + #include + 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); + isl_bool isl_union_set_every_set( + __isl_keep isl_union_set *uset, + isl_bool (*test)(__isl_keep isl_set *set, + void *user), + void *user); + + #include + 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 and +C variants 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 + + isl_size isl_union_set_n_set(__isl_keep isl_union_set *uset); + isl_size isl_union_map_n_map(__isl_keep isl_union_map *umap); + +To extract the set or map in a given space from a union, use + + __isl_give isl_set *isl_union_set_extract_set( + __isl_keep isl_union_set *uset, + __isl_take isl_space *space); + __isl_give isl_map *isl_union_map_extract_map( + __isl_keep isl_union_map *umap, + __isl_take isl_space *space); + +To iterate over all the basic sets or maps in a set or map, use + + isl_stat isl_set_foreach_basic_set(__isl_keep isl_set *set, + isl_stat (*fn)(__isl_take isl_basic_set *bset, + void *user), + void *user); + isl_stat isl_map_foreach_basic_map(__isl_keep isl_map *map, + isl_stat (*fn)(__isl_take isl_basic_map *bmap, + void *user), + void *user); + +The callback function C should return C if successful and +C if an error occurs. In the latter case, or if any other error +occurs, the above functions will return C. + +It should be noted that C does not guarantee that +the basic sets or maps passed to C are disjoint. +If this is required, then the user should call one of +the following functions first. + + __isl_give isl_set *isl_set_make_disjoint( + __isl_take isl_set *set); + __isl_give isl_map *isl_map_make_disjoint( + __isl_take isl_map *map); + +The number of basic sets in a set can be obtained +or the number of basic maps in a map can be obtained +from + + #include + isl_size isl_set_n_basic_set(__isl_keep isl_set *set); + + #include + isl_size isl_map_n_basic_map(__isl_keep isl_map *map); + +It is also possible to obtain a list of (basic) sets from a set +or union set, a list of basic maps from a map and a list of maps from a union +map. + + #include + __isl_give isl_basic_set_list *isl_set_get_basic_set_list( + __isl_keep isl_set *set); + + #include + __isl_give isl_basic_set_list * + isl_union_set_get_basic_set_list( + __isl_keep isl_union_set *uset); + __isl_give isl_set_list *isl_union_set_get_set_list( + __isl_keep isl_union_set *uset); + + #include + __isl_give isl_basic_map_list *isl_map_get_basic_map_list( + __isl_keep isl_map *map); + + #include + __isl_give isl_map_list *isl_union_map_get_map_list( + __isl_keep isl_union_map *umap); + +The returned list can be manipulated using the functions in L<"Lists">. + +To iterate over the constraints of a basic set or map, use + + #include + + isl_size isl_basic_set_n_constraint( + __isl_keep isl_basic_set *bset); + isl_stat isl_basic_set_foreach_constraint( + __isl_keep isl_basic_set *bset, + isl_stat (*fn)(__isl_take isl_constraint *c, + void *user), + void *user); + isl_size isl_basic_map_n_constraint( + __isl_keep isl_basic_map *bmap); + isl_stat isl_basic_map_foreach_constraint( + __isl_keep isl_basic_map *bmap, + isl_stat (*fn)(__isl_take isl_constraint *c, + void *user), + void *user); + __isl_null isl_constraint *isl_constraint_free( + __isl_take isl_constraint *c); + +Again, the callback function C should return C +if successful and +C if an error occurs. In the latter case, or if any other error +occurs, the above functions will return C. +The constraint 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. + + isl_bool isl_constraint_is_equality( + __isl_keep isl_constraint *constraint); + +It is also possible to obtain a list of constraints from a basic +map or set + + #include + __isl_give isl_constraint_list * + isl_basic_map_get_constraint_list( + __isl_keep isl_basic_map *bmap); + __isl_give isl_constraint_list * + isl_basic_set_get_constraint_list( + __isl_keep isl_basic_set *bset); + +These functions require that all existentially quantified variables +have an explicit representation. +The returned list can be manipulated using the functions in L<"Lists">. + +The coefficients of the constraints can be inspected using +the following functions. + + isl_bool isl_constraint_is_lower_bound( + __isl_keep isl_constraint *constraint, + enum isl_dim_type type, unsigned pos); + isl_bool isl_constraint_is_upper_bound( + __isl_keep isl_constraint *constraint, + enum isl_dim_type type, unsigned pos); + __isl_give isl_val *isl_constraint_get_constant_val( + __isl_keep isl_constraint *constraint); + __isl_give isl_val *isl_constraint_get_coefficient_val( + __isl_keep isl_constraint *constraint, + enum isl_dim_type type, int pos); + +The explicit representations of the existentially quantified +variables can be inspected using the following function. +Note that the user is only allowed to use this function +if the inspected set or map is the result of a call +to C or C. +The existentially quantified variable is equal to the floor +of the returned affine expression. The affine expression +itself can be inspected using the functions in +L. + + __isl_give isl_aff *isl_constraint_get_div( + __isl_keep isl_constraint *constraint, int pos); + +To obtain the constraints of a basic set or map in matrix +form, use the following functions. + + __isl_give isl_mat *isl_basic_set_equalities_matrix( + __isl_keep isl_basic_set *bset, + enum isl_dim_type c1, enum isl_dim_type c2, + enum isl_dim_type c3, enum isl_dim_type c4); + __isl_give isl_mat *isl_basic_set_inequalities_matrix( + __isl_keep isl_basic_set *bset, + enum isl_dim_type c1, enum isl_dim_type c2, + enum isl_dim_type c3, enum isl_dim_type c4); + __isl_give isl_mat *isl_basic_map_equalities_matrix( + __isl_keep isl_basic_map *bmap, + enum isl_dim_type c1, + enum isl_dim_type c2, enum isl_dim_type c3, + enum isl_dim_type c4, enum isl_dim_type c5); + __isl_give isl_mat *isl_basic_map_inequalities_matrix( + __isl_keep isl_basic_map *bmap, + enum isl_dim_type c1, + enum isl_dim_type c2, enum isl_dim_type c3, + enum isl_dim_type c4, enum isl_dim_type c5); + +The C arguments dictate the order in which +different kinds of variables appear in the resulting matrix. +For set inputs, they should be a permutation of +C (the constant term), C, C and +C. +For map inputs, they should be a permutation of +C, C, +C, C and C. + +=head2 Points + +Points are elements of a set. They can be used to construct +simple sets (boxes) or they can be used to represent the +individual elements of a set. +The zero point (the origin) can be created using + + __isl_give isl_point *isl_point_zero(__isl_take isl_space *space); + +The coordinates of a point can be inspected, set and changed +using + + #include + __isl_give isl_multi_val *isl_point_get_multi_val( + __isl_keep isl_point *pnt); + __isl_give isl_val *isl_point_get_coordinate_val( + __isl_keep isl_point *pnt, + enum isl_dim_type type, int pos); + __isl_give isl_point *isl_point_set_coordinate_val( + __isl_take isl_point *pnt, + enum isl_dim_type type, int pos, + __isl_take isl_val *v); + + __isl_give isl_point *isl_point_add_ui( + __isl_take isl_point *pnt, + enum isl_dim_type type, int pos, unsigned val); + __isl_give isl_point *isl_point_sub_ui( + __isl_take isl_point *pnt, + enum isl_dim_type type, int pos, unsigned val); + +Points can be copied or freed using + + __isl_give isl_point *isl_point_copy( + __isl_keep isl_point *pnt); + __isl_null isl_point *isl_point_free( + __isl_take isl_point *pnt); + +A singleton set can be created from a point using the following functions. + + __isl_give isl_basic_set *isl_basic_set_from_point( + __isl_take isl_point *pnt); + __isl_give isl_set *isl_point_to_set( + __isl_take isl_point *pnt); + __isl_give isl_set *isl_set_from_point( + __isl_take isl_point *pnt); + __isl_give isl_union_set *isl_union_set_from_point( + __isl_take isl_point *pnt); + +C and C perform +the same operation. + +A box can be created from two opposite extremal points using + + __isl_give isl_basic_set *isl_basic_set_box_from_points( + __isl_take isl_point *pnt1, + __isl_take isl_point *pnt2); + __isl_give isl_set *isl_set_box_from_points( + __isl_take isl_point *pnt1, + __isl_take isl_point *pnt2); + +All elements of a B (union) set can be enumerated using +the following functions. + + isl_stat isl_set_foreach_point(__isl_keep isl_set *set, + isl_stat (*fn)(__isl_take isl_point *pnt, + void *user), + void *user); + isl_stat isl_union_set_foreach_point( + __isl_keep isl_union_set *uset, + isl_stat (*fn)(__isl_take isl_point *pnt, + void *user), + void *user); + +The function C is called for each integer point in +C with as second argument the last argument of +the C call. The function C +should return C on success and C on failure. +In the latter case, C will stop +enumerating and return C as well. +If the enumeration is performed successfully and to completion, +then C returns C. + +To obtain a single point of a (basic or union) set, use + + __isl_give isl_point *isl_basic_set_sample_point( + __isl_take isl_basic_set *bset); + __isl_give isl_point *isl_set_sample_point( + __isl_take isl_set *set); + __isl_give isl_point *isl_union_set_sample_point( + __isl_take isl_union_set *uset); + +If C does not contain any (integer) points, then the +resulting point will be ``void'', a property that can be +tested using + + isl_bool isl_point_is_void(__isl_keep isl_point *pnt); + +=head2 Functions + +Besides sets and relation, C also supports various types of functions. +Each of these types is derived from the value type (see L) +or from one of two primitive function types +through the application of zero or more type constructors. +As a special case, a multiple expression can also be derived +from an identifier (see L) although the result +is not really a function. +We first describe the primitive type and then we describe +the types derived from these primitive types. + +=head3 Primitive Functions + +C support two primitive function types, quasi-affine +expressions and quasipolynomials. +A quasi-affine expression is defined either over a parameter +space or over a set and is composed of integer constants, +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)] } + +maps C to C<2*floor((4 n + x)/9>. +A quasipolynomial is a polynomial expression in quasi-affine +expression. That is, it additionally allows for multiplication. +Note, though, that it is not allowed to construct an integer +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)) } + +Note that the external representations of quasi-affine expressions +and quasipolynomials are different. Quasi-affine expressions +use a notation with square brackets just like binary relations, +while quasipolynomials do not. This might change at some point. + +If a primitive function is defined over a parameter space, +then the space of the function itself is that of a set. +If it is defined over a set, then the space of the function +is that of a relation. In both cases, the set space (or +the output space) is single-dimensional, anonymous and unstructured. +To create functions with multiple dimensions or with other kinds +of set or output spaces, use multiple expressions +(see L). + +=over + +=item * Quasi-affine Expressions + +Besides the expressions described above, a quasi-affine +expression can also be set to NaN. Such expressions +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, parameter or +a specified dimension on a given domain can be created using + + #include + __isl_give isl_aff *isl_aff_zero_on_domain_space( + __isl_take isl_space *space); + __isl_give isl_aff *isl_space_zero_aff_on_domain( + __isl_take isl_space *space); + __isl_give isl_aff *isl_aff_zero_on_domain( + __isl_take isl_local_space *ls); + __isl_give isl_aff *isl_aff_val_on_domain_space( + __isl_take isl_space *space, + __isl_take isl_val *val); + __isl_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_space_param_aff_on_domain_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_space( + __isl_take isl_space *space); + __isl_give isl_aff *isl_aff_nan_on_domain( + __isl_take isl_local_space *ls); + +The space passed to C +is required to have a parameter with the given identifier. +C and +C perform the same operation. + +C and C +perform the same operation. + +Quasi affine expressions can be copied and freed using + + #include + __isl_give isl_aff *isl_aff_copy( + __isl_keep isl_aff *aff); + __isl_null isl_aff *isl_aff_free( + __isl_take isl_aff *aff); + +A (rational) bound on a dimension can be extracted from an C +using the following function. The constraint is required to have +a non-zero coefficient for the specified dimension. + + #include + __isl_give isl_aff *isl_constraint_get_bound( + __isl_keep isl_constraint *constraint, + enum isl_dim_type type, int pos); + +The entire affine expression of the constraint can also be extracted +using the following function. + + #include + __isl_give isl_aff *isl_constraint_get_aff( + __isl_keep isl_constraint *constraint); + +Conversely, an equality constraint equating +the affine expression to zero or an inequality constraint enforcing +the affine expression to be non-negative, can be constructed using + + __isl_give isl_constraint *isl_equality_from_aff( + __isl_take isl_aff *aff); + __isl_give isl_constraint *isl_inequality_from_aff( + __isl_take isl_aff *aff); + +The coefficients and the integer divisions of an affine expression +can be inspected using the following functions. + + #include + __isl_give isl_val *isl_aff_get_constant_val( + __isl_keep isl_aff *aff); + __isl_give isl_val *isl_aff_get_coefficient_val( + __isl_keep isl_aff *aff, + enum isl_dim_type type, int pos); + int isl_aff_coefficient_sgn(__isl_keep isl_aff *aff, + enum isl_dim_type type, int pos); + __isl_give isl_val *isl_aff_get_denominator_val( + __isl_keep isl_aff *aff); + __isl_give isl_aff *isl_aff_get_div( + __isl_keep isl_aff *aff, int pos); + +They can be modified using the following functions. + + #include + __isl_give isl_aff *isl_aff_set_constant_si( + __isl_take isl_aff *aff, int v); + __isl_give isl_aff *isl_aff_set_constant_val( + __isl_take isl_aff *aff, __isl_take isl_val *v); + __isl_give isl_aff *isl_aff_set_coefficient_si( + __isl_take isl_aff *aff, + enum isl_dim_type type, int pos, int v); + __isl_give isl_aff *isl_aff_set_coefficient_val( + __isl_take isl_aff *aff, + enum isl_dim_type type, int pos, + __isl_take isl_val *v); + + __isl_give isl_aff *isl_aff_add_constant_si( + __isl_take isl_aff *aff, int v); + __isl_give isl_aff *isl_aff_add_constant_val( + __isl_take isl_aff *aff, __isl_take isl_val *v); + __isl_give isl_aff *isl_aff_add_constant_num_si( + __isl_take isl_aff *aff, int v); + __isl_give isl_aff *isl_aff_add_coefficient_si( + __isl_take isl_aff *aff, + enum isl_dim_type type, int pos, int v); + __isl_give isl_aff *isl_aff_add_coefficient_val( + __isl_take isl_aff *aff, + enum isl_dim_type type, int pos, + __isl_take isl_val *v); + +Note that C and C +set the I of the constant or coefficient, while +C and C set +the constant or coefficient as a whole. +The C and C functions add an integer +or rational value to +the possibly rational constant or coefficient. +The C functions add an integer value to +the numerator. + +=item * Quasipolynomials + +Some simple quasipolynomials can be created using the following functions. + + #include + __isl_give isl_qpolynomial *isl_qpolynomial_zero_on_domain( + __isl_take isl_space *domain); + __isl_give isl_qpolynomial *isl_qpolynomial_one_on_domain( + __isl_take isl_space *domain); + __isl_give isl_qpolynomial *isl_qpolynomial_infty_on_domain( + __isl_take isl_space *domain); + __isl_give isl_qpolynomial *isl_qpolynomial_neginfty_on_domain( + __isl_take isl_space *domain); + __isl_give isl_qpolynomial *isl_qpolynomial_nan_on_domain( + __isl_take isl_space *domain); + __isl_give isl_qpolynomial *isl_qpolynomial_val_on_domain( + __isl_take isl_space *domain, + __isl_take isl_val *val); + __isl_give isl_qpolynomial *isl_qpolynomial_var_on_domain( + __isl_take isl_space *domain, + enum isl_dim_type type, unsigned pos); + __isl_give isl_qpolynomial *isl_qpolynomial_from_aff( + __isl_take isl_aff *aff); + +Recall that the space in which a quasipolynomial lives is a map space +with a one-dimensional range. The C argument in some of +the functions above corresponds to the domain of this map space. + +Quasipolynomials can be copied and freed again using the following +functions. + + #include + __isl_give isl_qpolynomial *isl_qpolynomial_copy( + __isl_keep isl_qpolynomial *qp); + __isl_null isl_qpolynomial *isl_qpolynomial_free( + __isl_take isl_qpolynomial *qp); + +The constant term of a quasipolynomial can be extracted using + + __isl_give isl_val *isl_qpolynomial_get_constant_val( + __isl_keep isl_qpolynomial *qp); + +To iterate over all terms in a quasipolynomial, +use + + isl_stat isl_qpolynomial_foreach_term( + __isl_keep isl_qpolynomial *qp, + isl_stat (*fn)(__isl_take isl_term *term, + void *user), void *user); + +The terms themselves can be inspected and freed using +these functions + + isl_size isl_term_dim(__isl_keep isl_term *term, + enum isl_dim_type type); + __isl_give isl_val *isl_term_get_coefficient_val( + __isl_keep isl_term *term); + isl_size isl_term_get_exp(__isl_keep isl_term *term, + enum isl_dim_type type, unsigned pos); + __isl_give isl_aff *isl_term_get_div( + __isl_keep isl_term *term, unsigned pos); + __isl_null isl_term *isl_term_free( + __isl_take isl_term *term); + +Each term is a product of parameters, set variables and +integer divisions. The function C +returns the exponent of a given dimensions in the given term. + +=back + +=head3 Reductions + +A reduction represents a maximum or a minimum of its +base expressions. +The only reduction type defined by C is +C. + +There are currently no functions to directly create such +objects, but they do appear in the piecewise quasipolynomial +reductions returned by the C function. +See +L. + +Reductions can be copied and freed using +the following functions. + + #include + __isl_give isl_qpolynomial_fold * + isl_qpolynomial_fold_copy( + __isl_keep isl_qpolynomial_fold *fold); + __isl_null isl_qpolynomial_fold * + isl_qpolynomial_fold_free( + __isl_take isl_qpolynomial_fold *fold); + +The type of a (union piecewise) reduction +can be obtained using the following functions. + + #include + enum isl_fold isl_qpolynomial_fold_get_type( + __isl_keep isl_qpolynomial_fold *fold); + enum isl_fold isl_pw_qpolynomial_fold_get_type( + __isl_keep isl_pw_qpolynomial_fold *pwf); + enum isl_fold isl_union_pw_qpolynomial_fold_get_type( + __isl_keep isl_union_pw_qpolynomial_fold *upwf); + +The type may be either C or C +(or C in case of error). + +To iterate over all quasipolynomials in a reduction, use + + isl_stat isl_qpolynomial_fold_foreach_qpolynomial( + __isl_keep isl_qpolynomial_fold *fold, + isl_stat (*fn)(__isl_take isl_qpolynomial *qp, + void *user), void *user); + +=head3 Multiple Expressions + +A multiple expression represents a sequence of zero or +more base expressions, all defined on the same domain space. +The domain space of the multiple expression is the same +as that of the base expressions, but the range space +can be any space. In case the base expressions have +a set space, the corresponding multiple expression +also has a set space. +Objects of the value or identifier type do not have an associated space. +The space of a multiple value or +multiple identifier is therefore always a set space. +Similarly, the space of a multiple union piecewise +affine expression is always a set space. +If the base expressions are not total, then +a corresponding zero-dimensional multiple expression may +have an explicit domain that keeps track of the domain +outside of any base expressions. + +The multiple expression types defined by C +are C, C, C, C, +C. + +A multiple expression with the value zero for +each output (or set) dimension can be created +using the following functions. + + #include + __isl_give isl_multi_val *isl_multi_val_zero( + __isl_take isl_space *space); + __isl_give isl_multi_val *isl_space_zero_multi_val( + __isl_take isl_space *space); + + #include + __isl_give isl_multi_aff *isl_multi_aff_zero( + __isl_take isl_space *space); + __isl_give isl_multi_aff *isl_space_zero_multi_aff( + __isl_take isl_space *space); + __isl_give isl_multi_pw_aff *isl_multi_pw_aff_zero( + __isl_take isl_space *space); + __isl_give isl_multi_pw_aff *isl_space_zero_multi_pw_aff( + __isl_take isl_space *space); + __isl_give isl_multi_union_pw_aff * + isl_multi_union_pw_aff_zero( + __isl_take isl_space *space); + __isl_give isl_multi_union_pw_aff * + isl_space_zero_multi_union_pw_aff( + __isl_take isl_space *space); + +Since there is no canonical way of representing a zero +value of type C, the space passed +to C needs to be zero-dimensional. +C and C +perform the same operation. +Similarly +for the pair C and C, +for the pair C and C and +for the pair C and +C. + + +An identity function can be created using the following +functions. +For the first group of functions, the space needs to be that of a set. +For the second group, +the space needs to be that of a relation +with the same number of input and output dimensions. +For the third group, the input function needs to live in a space +with the same number of input and output dimensions and +the identity function is created in that space. + + #include + __isl_give isl_multi_aff * + isl_multi_aff_identity_on_domain_space( + __isl_take isl_space *space); + __isl_give isl_multi_aff * + isl_space_identity_multi_aff_on_domain( + __isl_take isl_space *space); + __isl_give isl_multi_pw_aff * + isl_multi_pw_aff_identity_on_domain_space( + __isl_take isl_space *space); + __isl_give isl_multi_pw_aff * + isl_space_identity_multi_pw_aff_on_domain( + __isl_take isl_space *space); + __isl_give isl_multi_aff *isl_multi_aff_identity( + __isl_take isl_space *space); + __isl_give isl_multi_pw_aff *isl_multi_pw_aff_identity( + __isl_take isl_space *space); + __isl_give isl_multi_aff * + isl_multi_aff_identity_multi_aff( + __isl_take isl_multi_aff *ma); + __isl_give isl_multi_pw_aff * + isl_multi_pw_aff_identity_multi_pw_aff( + __isl_take isl_multi_pw_aff *mpa); + +C and +C +perform the same operation. +Similarly +for the pair C and +C. + +A function that performs a projection on a universe +relation or set can be created using the following functions. +See also the corresponding +projection operations in L. + + #include + __isl_give isl_multi_aff *isl_multi_aff_domain_map( + __isl_take isl_space *space); + __isl_give isl_multi_aff *isl_space_domain_map_multi_aff( + __isl_take isl_space *space); + __isl_give isl_multi_aff *isl_multi_aff_range_map( + __isl_take isl_space *space); + __isl_give isl_multi_aff *isl_space_range_map_multi_aff( + __isl_take isl_space *space); + __isl_give isl_multi_aff *isl_multi_aff_project_out_map( + __isl_take isl_space *space, + enum isl_dim_type type, + unsigned first, unsigned n); + +C and C perform +the same operation. +Similarly +for the pair C and C. + +A multiple expression can be created from a single +base expression using the following functions. +The space of the created multiple expression is the same +as that of the base expression, except for +C where the input +lives in a parameter space and the output lives +in a single-dimensional set space. + + #include + __isl_give isl_multi_aff *isl_multi_aff_from_aff( + __isl_take isl_aff *aff); + __isl_give isl_multi_pw_aff *isl_multi_pw_aff_from_pw_aff( + __isl_take isl_pw_aff *pa); + __isl_give isl_multi_union_pw_aff * + isl_multi_union_pw_aff_from_union_pw_aff( + __isl_take isl_union_pw_aff *upa); + +A multiple expression can be created from a list +of base expression in a specified space. +The domain of this space needs to be the same +as the domains of the base expressions in the list. +If the base expressions have a set space (or no associated space), +then this space also needs to be a set space. + + #include + __isl_give isl_multi_id *isl_multi_id_from_id_list( + __isl_take isl_space *space, + __isl_take isl_id_list *list); + __isl_give isl_multi_id *isl_space_multi_id( + __isl_take isl_space *space, + __isl_take isl_id_list *list); + + #include + __isl_give isl_multi_val *isl_multi_val_from_val_list( + __isl_take isl_space *space, + __isl_take isl_val_list *list); + __isl_give isl_multi_val *isl_space_multi_val( + __isl_take isl_space *space, + __isl_take isl_val_list *list); + + #include + __isl_give isl_multi_aff *isl_multi_aff_from_aff_list( + __isl_take isl_space *space, + __isl_take isl_aff_list *list); + __isl_give isl_multi_aff *isl_space_multi_aff( + __isl_take isl_space *space, + __isl_take isl_aff_list *list); + __isl_give isl_multi_pw_aff * + isl_multi_pw_aff_from_pw_aff_list( + __isl_take isl_space *space, + __isl_take isl_pw_aff_list *list); + __isl_give isl_multi_pw_aff * + isl_space_multi_pw_aff( + __isl_take isl_space *space, + __isl_take isl_pw_aff_list *list); + __isl_give isl_multi_union_pw_aff * + isl_multi_union_pw_aff_from_union_pw_aff_list( + __isl_take isl_space *space, + __isl_take isl_union_pw_aff_list *list); + __isl_give isl_multi_union_pw_aff * + isl_space_multi_union_pw_aff( + __isl_take isl_space *space, + __isl_take isl_union_pw_aff_list *list); + +C and C perform +the same operation. +Similarly for the pair C and +C, +for the pair C and +C, +for the pair C and +C and +for the pair C and +C. + +As a convenience, a multiple piecewise expression can +also be created from a multiple expression, +or even directly from a single base expression. +Each piecewise expression in the result has a single +universe cell. + + #include + __isl_give isl_multi_pw_aff *isl_multi_pw_aff_from_aff( + __isl_take isl_aff *aff); + __isl_give isl_multi_pw_aff * + isl_multi_aff_to_multi_pw_aff( + __isl_take isl_multi_aff *ma); + __isl_give isl_multi_pw_aff * + isl_multi_pw_aff_from_multi_aff( + __isl_take isl_multi_aff *ma); + +C and +C perform the same operation. + +Similarly, a multiple union expression can be +created from a multiple expression. + + #include + __isl_give isl_multi_union_pw_aff * + isl_multi_union_pw_aff_from_multi_aff( + __isl_take isl_multi_aff *ma); + __isl_give isl_multi_union_pw_aff * + isl_multi_aff_to_multi_union_pw_aff( + __isl_take isl_multi_aff *ma); + __isl_give isl_multi_union_pw_aff * + isl_multi_union_pw_aff_from_multi_pw_aff( + __isl_take isl_multi_pw_aff *mpa); + +C and +C perform the same operation. + +A multiple quasi-affine expression can be created from +a multiple value with a given domain space using the following +function. + + #include + __isl_give isl_multi_aff * + isl_multi_aff_multi_val_on_domain_space( + __isl_take isl_space *space, + __isl_take isl_multi_val *mv); + __isl_give isl_multi_aff * + isl_space_multi_aff_on_domain_multi_val( + __isl_take isl_space *space, + __isl_take isl_multi_val *mv); + __isl_give isl_multi_aff * + isl_multi_aff_multi_val_on_space( + __isl_take isl_space *space, + __isl_take isl_multi_val *mv); + +C and +C are alternative names +for C. + +Similarly, +a multiple union piecewise affine expression can be created from +a multiple value with a given domain or +a (piecewise) multiple affine expression with a given domain +using the following functions. + + #include + __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); + +Multiple expressions can be copied and freed using +the following functions. + + #include + __isl_give isl_multi_id *isl_multi_id_copy( + __isl_keep isl_multi_id *mi); + __isl_null isl_multi_id *isl_multi_id_free( + __isl_take isl_multi_id *mi); + + #include + __isl_give isl_multi_val *isl_multi_val_copy( + __isl_keep isl_multi_val *mv); + __isl_null isl_multi_val *isl_multi_val_free( + __isl_take isl_multi_val *mv); + + #include + __isl_give isl_multi_aff *isl_multi_aff_copy( + __isl_keep isl_multi_aff *maff); + __isl_null isl_multi_aff *isl_multi_aff_free( + __isl_take isl_multi_aff *maff); + __isl_give isl_multi_pw_aff *isl_multi_pw_aff_copy( + __isl_keep isl_multi_pw_aff *mpa); + __isl_null isl_multi_pw_aff *isl_multi_pw_aff_free( + __isl_take isl_multi_pw_aff *mpa); + __isl_give isl_multi_union_pw_aff * + isl_multi_union_pw_aff_copy( + __isl_keep isl_multi_union_pw_aff *mupa); + __isl_null isl_multi_union_pw_aff * + isl_multi_union_pw_aff_free( + __isl_take isl_multi_union_pw_aff *mupa); + +The number of base expressions in a multiple +expression can be obtained using the following functions. + + #include + int isl_multi_id_size(__isl_keep isl_multi_id *mi); + + #include + isl_size isl_multi_val_size(__isl_keep isl_multi_val *mv); + + #include + isl_size isl_multi_aff_size( + __isl_keep isl_multi_aff *multi); + isl_size isl_multi_pw_aff_size( + __isl_keep isl_multi_pw_aff *mpa); + isl_size isl_multi_union_pw_aff_size( + __isl_keep isl_multi_union_pw_aff *mupa); + +The base expression at a given position of a multiple +expression can be extracted using the following functions. + + #include + __isl_give isl_id *isl_multi_id_get_at( + __isl_keep isl_multi_id *mi, int pos); + __isl_give isl_id *isl_multi_id_get_id( + __isl_keep isl_multi_id *mi, int pos); + + #include + __isl_give isl_val *isl_multi_val_get_at( + __isl_keep isl_multi_val *mv, int pos); + __isl_give isl_val *isl_multi_val_get_val( + __isl_keep isl_multi_val *mv, int pos); + + #include + __isl_give isl_aff *isl_multi_aff_get_at( + __isl_keep isl_multi_aff *ma, int pos); + __isl_give isl_aff *isl_multi_aff_get_aff( + __isl_keep isl_multi_aff *multi, int pos); + __isl_give isl_pw_aff *isl_multi_pw_aff_get_at( + __isl_keep isl_multi_pw_aff *mpa, int pos); + __isl_give isl_pw_aff *isl_multi_pw_aff_get_pw_aff( + __isl_keep isl_multi_pw_aff *mpa, int pos); + __isl_give isl_union_pw_aff * + isl_multi_union_pw_aff_get_at( + __isl_keep isl_multi_union_pw_aff *mupa, int pos); + __isl_give isl_union_pw_aff * + isl_multi_union_pw_aff_get_union_pw_aff( + __isl_keep isl_multi_union_pw_aff *mupa, int pos); + +C is an alternative name for C. +Similarly for the other pairs of functions. + +The base expression can be replaced using the following functions. + + #include + __isl_give isl_multi_id *isl_multi_id_set_at( + __isl_take isl_multi_id *mi, int pos, + __isl_take isl_id *id); + __isl_give isl_multi_id *isl_multi_id_set_id( + __isl_take isl_multi_id *mi, int pos, + __isl_take isl_id *id); + + #include + __isl_give isl_multi_val *isl_multi_val_set_at( + __isl_take isl_multi_val *mv, int pos, + __isl_take isl_val *val); + __isl_give isl_multi_val *isl_multi_val_set_val( + __isl_take isl_multi_val *mv, int pos, + __isl_take isl_val *val); + + #include + __isl_give isl_multi_aff *isl_multi_aff_set_at( + __isl_take isl_multi_aff *ma, int pos, + __isl_take isl_aff *aff); + __isl_give isl_multi_aff *isl_multi_aff_set_aff( + __isl_take isl_multi_aff *multi, int pos, + __isl_take isl_aff *aff); + __isl_give isl_multi_pw_aff *isl_multi_pw_aff_set_at( + __isl_take isl_multi_pw_aff *mpa, int pos, + __isl_take isl_pw_aff *pa); + __isl_give isl_multi_pw_aff *isl_multi_pw_aff_set_pw_aff( + __isl_take isl_multi_pw_aff *mpa, int pos, + __isl_take isl_pw_aff *pa); + __isl_give isl_multi_union_pw_aff * + isl_multi_union_pw_aff_set_at( + __isl_take isl_multi_union_pw_aff *mupa, int pos, + __isl_take isl_union_pw_aff *upa); + __isl_give isl_multi_union_pw_aff * + isl_multi_union_pw_aff_set_union_pw_aff( + __isl_take isl_multi_union_pw_aff *mupa, int pos, + __isl_take isl_union_pw_aff *upa); + +C is an alternative name for C. +Similarly for the other pairs of functions. + +A list of all base expressions of a multiple +expression can be extracted using the following functions. + + #include + __isl_give isl_id_list *isl_multi_id_get_list( + __isl_keep isl_multi_id *mi); + + #include + __isl_give isl_val_list *isl_multi_val_get_list( + __isl_keep isl_multi_val *mv); + + #include + __isl_give isl_aff_list *isl_multi_aff_get_list( + __isl_keep isl_multi_aff *multi); + __isl_give isl_pw_aff_list *isl_multi_pw_aff_get_list( + __isl_keep isl_multi_pw_aff *mpa); + __isl_give isl_union_pw_aff_list * + isl_multi_union_pw_aff_list( + __isl_keep isl_multi_union_pw_aff *mupa); + +The constant terms of the base expressions can be obtained using +the following function. + + #include + __isl_give isl_multi_val * + isl_multi_aff_get_constant_multi_val( + __isl_keep isl_multi_aff *ma); + +As a convenience, a sequence of base expressions that have +their domains in a given space can be extracted from a sequence +of union expressions using the following function. + + #include + __isl_give isl_multi_pw_aff * + isl_multi_union_pw_aff_extract_multi_pw_aff( + __isl_keep isl_multi_union_pw_aff *mupa, + __isl_take isl_space *space); + +Note that there is a difference between C +and C objects. The first is a sequence +of unions of piecewise expressions, while the second is a union +of piecewise sequences. In particular, multiple affine expressions +in an C may live in different spaces, +while there is only a single multiple expression in +an C, which can therefore only live +in a single space. This means that not every +C can be converted to +an C. Conversely, the elements +of an C may be defined over different domains, +while each multiple expression inside an C +has a single domain. The conversion of an C +of dimension greater than one may therefore not be exact. +The following functions can +be used to perform these conversions when they are possible. + + #include + __isl_give isl_multi_union_pw_aff * + isl_union_pw_multi_aff_as_multi_union_pw_aff( + __isl_take isl_union_pw_multi_aff *upma); + __isl_give isl_multi_union_pw_aff * + isl_multi_union_pw_aff_from_union_pw_multi_aff( + __isl_take isl_union_pw_multi_aff *upma); + __isl_give isl_union_pw_multi_aff * + isl_union_pw_multi_aff_from_multi_union_pw_aff( + __isl_take isl_multi_union_pw_aff *mupa); + +C and +C +perform the same operation. + +=head3 Piecewise Expressions + +A piecewise expression is an expression that is described +using zero or more base expression defined over the same +number of cells in the domain space of the base expressions. +All base expressions are defined over the same +domain space and the cells are disjoint. +The space of a piecewise expression is the same as +that of the base expressions. +If the union of the cells is a strict subset of the domain +space, then the value of the piecewise expression outside +this union is different for types derived from quasi-affine +expressions and those derived from quasipolynomials. +Piecewise expressions derived from quasi-affine expressions +are considered to be undefined outside the union of their cells. +Piecewise expressions derived from quasipolynomials +are considered to be zero outside the union of their cells. + +Piecewise quasipolynomials are mainly used by the C +library for representing the number of elements in a parametric set or map. +For example, the piecewise quasipolynomial + + [n] -> { [x] -> ((1 + n) - x) : x <= n and x >= 0 } + +represents the number of points in the map + + [n] -> { [x] -> [y] : x,y >= 0 and 0 <= x + y <= n } + +The piecewise expression types defined by C +are C, C, +C and C. + +A piecewise expression with no cells can be created using +the following functions. + + #include + __isl_give isl_pw_aff *isl_pw_aff_empty( + __isl_take isl_space *space); + __isl_give isl_pw_multi_aff *isl_pw_multi_aff_empty( + __isl_take isl_space *space); + +A piecewise expression with a single universe cell can be +created using the following functions. + + #include + __isl_give isl_pw_aff *isl_pw_aff_from_aff( + __isl_take isl_aff *aff); + __isl_give isl_pw_multi_aff * + isl_multi_aff_to_pw_multi_aff( + __isl_take isl_multi_aff *ma); + __isl_give isl_pw_multi_aff * + isl_pw_multi_aff_from_multi_aff( + __isl_take isl_multi_aff *ma); + + #include + __isl_give isl_pw_qpolynomial * + isl_pw_qpolynomial_from_qpolynomial( + __isl_take isl_qpolynomial *qp); + __isl_give isl_pw_qpolynomial_fold * + isl_pw_qpolynomial_fold_from_qpolynomial_fold( + __isl_take isl_qpolynomial_fold *fold); + +C and C perform +the same operation. + +The inverse conversions below can only be used if the input +expression is known to be defined over a single universe domain. + + #include + isl_bool isl_pw_aff_isa_aff(__isl_keep isl_pw_aff *pa); + __isl_give isl_aff *isl_pw_aff_as_aff( + __isl_take isl_pw_aff *pa); + isl_bool isl_multi_pw_aff_isa_multi_aff( + __isl_keep isl_multi_pw_aff *mpa); + __isl_give isl_multi_aff *isl_multi_pw_aff_as_multi_aff( + __isl_take isl_multi_pw_aff *mpa); + isl_bool isl_pw_multi_aff_isa_multi_aff( + __isl_keep isl_pw_multi_aff *pma); + __isl_give isl_multi_aff *isl_pw_multi_aff_as_multi_aff( + __isl_take isl_pw_multi_aff *pma); + + #include + isl_bool isl_pw_qpolynomial_isa_qpolynomial( + __isl_keep isl_pw_qpolynomial *pwqp); + __isl_give isl_qpolynomial * + isl_pw_qpolynomial_as_qpolynomial( + __isl_take isl_pw_qpolynomial *pwqp); + isl_bool isl_pw_qpolynomial_fold_isa_qpolynomial_fold( + __isl_keep isl_pw_qpolynomial_fold *pwf); + __isl_give isl_qpolynomial_fold * + isl_pw_qpolynomial_fold_as_qpolynomial_fold( + __isl_take isl_pw_qpolynomial_fold *pwf); + +A piecewise expression with a single specified cell can be +created using the following functions. + + #include + __isl_give isl_pw_aff *isl_pw_aff_alloc( + __isl_take isl_set *set, __isl_take isl_aff *aff); + __isl_give isl_pw_multi_aff *isl_pw_multi_aff_alloc( + __isl_take isl_set *set, + __isl_take isl_multi_aff *maff); + + #include + __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_alloc( + __isl_take isl_set *set, + __isl_take isl_qpolynomial *qp); + +The following convenience functions first create a base expression and +then create a piecewise expression over a universe domain. + + #include + __isl_give isl_pw_aff *isl_pw_aff_zero_on_domain( + __isl_take isl_local_space *ls); + __isl_give isl_pw_aff *isl_pw_aff_var_on_domain( + __isl_take isl_local_space *ls, + enum isl_dim_type type, unsigned pos); + __isl_give isl_pw_aff *isl_pw_aff_nan_on_domain_space( + __isl_take isl_space *space); + __isl_give isl_pw_aff *isl_pw_aff_nan_on_domain( + __isl_take isl_local_space *ls); + __isl_give isl_pw_multi_aff *isl_pw_multi_aff_zero( + __isl_take isl_space *space); + __isl_give isl_pw_multi_aff * + isl_pw_multi_aff_identity_on_domain_space( + __isl_take isl_space *space) + __isl_give isl_pw_multi_aff * + isl_space_identity_pw_multi_aff_on_domain( + __isl_take isl_space *space) + __isl_give isl_pw_multi_aff *isl_pw_multi_aff_identity( + __isl_take isl_space *space); + __isl_give isl_pw_multi_aff *isl_pw_multi_aff_domain_map( + __isl_take isl_space *space); + __isl_give isl_pw_multi_aff * + isl_space_domain_map_pw_multi_aff( + __isl_take isl_space *space); + __isl_give isl_pw_multi_aff *isl_pw_multi_aff_range_map( + __isl_take isl_space *space); + __isl_give isl_pw_multi_aff * + isl_space_range_map_pw_multi_aff( + __isl_take isl_space *space); + __isl_give isl_pw_multi_aff * + isl_pw_multi_aff_project_out_map( + __isl_take isl_space *space, + enum isl_dim_type type, + unsigned first, unsigned n); + + #include + __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_zero( + __isl_take isl_space *space); + +C and +C +perform the same operation. +Similarly +for the pair C and +C and +for the pair C and +C. + +The following convenience functions first create a base expression and +then create a piecewise expression over a given domain. + + #include + __isl_give isl_pw_aff *isl_pw_aff_val_on_domain( + __isl_take isl_set *domain, + __isl_take isl_val *v); + __isl_give isl_pw_aff *isl_set_pw_aff_on_domain_val( + __isl_take isl_set *domain, + __isl_take isl_val *v); + __isl_give isl_pw_multi_aff * + isl_pw_multi_aff_multi_val_on_domain( + __isl_take isl_set *domain, + __isl_take isl_multi_val *mv); + __isl_give isl_pw_multi_aff * + isl_set_pw_multi_aff_on_domain_multi_val( + __isl_take isl_set *domain, + __isl_take isl_multi_val *mv); + __isl_give isl_pw_aff *isl_pw_aff_param_on_domain_id( + __isl_take isl_set *domain, + __isl_take isl_id *id); + __isl_give isl_pw_aff *isl_set_param_pw_aff_on_domain_id( + __isl_take isl_set *domain, + __isl_take isl_id *id); + +C is an alternative name +for C. +Similarly for the pair +C and +C and +for the pair C and +C. + +As a convenience, a piecewise multiple expression can +also be created from a piecewise expression. +Each multiple expression in the result is derived +from the corresponding base expression. + + #include + __isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_pw_aff( + __isl_take isl_pw_aff *pa); + +Similarly, a piecewise quasipolynomial can be +created from a piecewise quasi-affine expression using +the following function. + + #include + __isl_give isl_pw_qpolynomial * + isl_pw_qpolynomial_from_pw_aff( + __isl_take isl_pw_aff *pwaff); + +Piecewise expressions can be copied and freed using the following functions. + + #include + __isl_give isl_pw_aff *isl_pw_aff_copy( + __isl_keep isl_pw_aff *pwaff); + __isl_null isl_pw_aff *isl_pw_aff_free( + __isl_take isl_pw_aff *pwaff); + __isl_give isl_pw_multi_aff *isl_pw_multi_aff_copy( + __isl_keep isl_pw_multi_aff *pma); + __isl_null isl_pw_multi_aff *isl_pw_multi_aff_free( + __isl_take isl_pw_multi_aff *pma); + + #include + __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_copy( + __isl_keep isl_pw_qpolynomial *pwqp); + __isl_null isl_pw_qpolynomial *isl_pw_qpolynomial_free( + __isl_take isl_pw_qpolynomial *pwqp); + __isl_give isl_pw_qpolynomial_fold * + isl_pw_qpolynomial_fold_copy( + __isl_keep isl_pw_qpolynomial_fold *pwf); + __isl_null isl_pw_qpolynomial_fold * + isl_pw_qpolynomial_fold_free( + __isl_take isl_pw_qpolynomial_fold *pwf); + +To iterate over the different cells of a piecewise expression, +use the following functions. + + #include + isl_bool isl_pw_aff_is_empty(__isl_keep isl_pw_aff *pwaff); + isl_size isl_pw_aff_n_piece(__isl_keep isl_pw_aff *pwaff); + isl_stat isl_pw_aff_foreach_piece( + __isl_keep isl_pw_aff *pwaff, + isl_stat (*fn)(__isl_take isl_set *set, + __isl_take isl_aff *aff, + void *user), void *user); + isl_bool isl_pw_aff_every_piece(__isl_keep isl_pw_aff *pa, + isl_bool (*test)(__isl_keep isl_set *set, + __isl_keep isl_aff *aff, void *user), + void *user); + isl_size isl_pw_multi_aff_n_piece( + __isl_keep isl_pw_multi_aff *pma); + isl_stat isl_pw_multi_aff_foreach_piece( + __isl_keep isl_pw_multi_aff *pma, + isl_stat (*fn)(__isl_take isl_set *set, + __isl_take isl_multi_aff *maff, + void *user), void *user); + isl_bool isl_pw_multi_aff_every_piece( + __isl_keep isl_pw_multi_aff *pma, + isl_bool (*test)(__isl_keep isl_set *set, + __isl_keep isl_multi_aff *ma, void *user), + void *user); + + #include + isl_size isl_pw_qpolynomial_n_piece( + __isl_keep isl_pw_qpolynomial *pwqp); + isl_stat isl_pw_qpolynomial_foreach_piece( + __isl_keep isl_pw_qpolynomial *pwqp, + isl_stat (*fn)(__isl_take isl_set *set, + __isl_take isl_qpolynomial *qp, + void *user), void *user); + isl_bool isl_pw_qpolynomial_every_piece( + __isl_keep isl_pw_qpolynomial *pwqp, + isl_bool (*test)(__isl_keep isl_set *set, + __isl_keep isl_qpolynomial *qp, + void *user), void *user); + isl_stat isl_pw_qpolynomial_foreach_lifted_piece( + __isl_keep isl_pw_qpolynomial *pwqp, + isl_stat (*fn)(__isl_take isl_set *set, + __isl_take isl_qpolynomial *qp, + void *user), void *user); + isl_size isl_pw_qpolynomial_fold_n_piece( + __isl_keep isl_pw_qpolynomial_fold *pwf); + isl_stat isl_pw_qpolynomial_fold_foreach_piece( + __isl_keep isl_pw_qpolynomial_fold *pwf, + isl_stat (*fn)(__isl_take isl_set *set, + __isl_take isl_qpolynomial_fold *fold, + void *user), void *user); + isl_bool isl_pw_qpolynomial_fold_every_piece( + __isl_keep isl_pw_qpolynomial_fold *pwf, + isl_bool (*test)(__isl_keep isl_set *set, + __isl_keep isl_qpolynomial_fold *fold, + void *user), void *user); + isl_stat isl_pw_qpolynomial_fold_foreach_lifted_piece( + __isl_keep isl_pw_qpolynomial_fold *pwf, + isl_stat (*fn)(__isl_take isl_set *set, + __isl_take isl_qpolynomial_fold *fold, + void *user), void *user); + +As usual, the function C should return C on success +and C on failure. The difference between +C and +C is that +C will first +compute unique representations for all existentially quantified +variables and then turn these existentially quantified variables +into extra set variables, adapting the associated quasipolynomial +accordingly. This means that the C passed to C +will not have any existentially quantified variables, but that +the dimensions of the sets may be different for different +invocations of C. +Similarly for C +and C. +The function C and its variants +check whether each call to the callback returns true and +stop checking as soon as one of these calls returns false (or error). + +A piecewise expression consisting of the expressions at a given +position of a piecewise multiple expression can be extracted +using the following function. + + #include + __isl_give isl_pw_aff *isl_pw_multi_aff_get_at( + __isl_keep isl_pw_multi_aff *pma, int pos); + __isl_give isl_pw_aff *isl_pw_multi_aff_get_pw_aff( + __isl_keep isl_pw_multi_aff *pma, int pos); + +C is an alternative name for +C. + +These expressions can be replaced using the following function. + + #include + __isl_give isl_pw_multi_aff *isl_pw_multi_aff_set_pw_aff( + __isl_take isl_pw_multi_aff *pma, unsigned pos, + __isl_take isl_pw_aff *pa); + +Note that there is a difference between C and +C objects. The first is a sequence of piecewise +affine expressions, while the second is a piecewise sequence +of affine expressions. In particular, each of the piecewise +affine expressions in an C may have a different +domain, while all multiple expressions associated to a cell +in an C have the same domain. +It is possible to convert between the two, but when converting +an C to an C, the domain +of the result is the intersection of the domains of the input. +The reverse conversion is exact. + + #include + __isl_give isl_pw_multi_aff * + isl_pw_multi_aff_from_multi_pw_aff( + __isl_take isl_multi_pw_aff *mpa); + __isl_give isl_multi_pw_aff * + isl_pw_multi_aff_to_multi_pw_aff( + __isl_take isl_pw_multi_aff *pma); + __isl_give isl_multi_pw_aff * + isl_multi_pw_aff_from_pw_multi_aff( + __isl_take isl_pw_multi_aff *pma); + +C and +C perform the same operation. + +=head3 Union Expressions + +A union expression collects base expressions defined +over different domains. The space of a union expression +is that of the shared parameter space. + +The union expression types defined by C +are C, C, +C and C. +In case of +C, +C and C, +there can be at most one base expression for a given domain space. +In case of +C, +there can be multiple such expressions for a given domain space, +but the domains of these expressions need to be disjoint. + +An empty union expression can be created using the following functions. + + #include + __isl_give isl_union_pw_aff * + isl_union_pw_aff_empty_ctx( + isl_ctx *ctx); + __isl_give isl_union_pw_aff * + isl_union_pw_aff_empty_space( + __isl_take isl_space *space); + __isl_give isl_union_pw_aff *isl_union_pw_aff_empty( + __isl_take isl_space *space); + __isl_give isl_union_pw_multi_aff * + isl_union_pw_multi_aff_empty_ctx( + isl_ctx *ctx); + __isl_give isl_union_pw_multi_aff * + isl_union_pw_multi_aff_empty_space( + __isl_take isl_space *space); + __isl_give isl_union_pw_multi_aff * + isl_union_pw_multi_aff_empty( + __isl_take isl_space *space); + + #include + __isl_give isl_union_pw_qpolynomial * + isl_union_pw_qpolynomial_zero_ctx( + isl_ctx *ctx); + __isl_give isl_union_pw_qpolynomial * + isl_union_pw_qpolynomial_zero_space( + __isl_take isl_space *space); + __isl_give isl_union_pw_qpolynomial * + isl_union_pw_qpolynomial_zero( + __isl_take isl_space *space); + +C is an alternative name for +C. +Similarly for the other pairs of functions. + +A union expression containing a single base expression +can be created using the following functions. + + #include + __isl_give isl_union_pw_aff * + isl_pw_aff_to_union_pw_aff( + __isl_take isl_pw_aff *pa); + __isl_give isl_union_pw_aff * + isl_union_pw_aff_from_pw_aff( + __isl_take isl_pw_aff *pa); + __isl_give isl_union_pw_multi_aff * + isl_union_pw_multi_aff_from_aff( + __isl_take isl_aff *aff); + __isl_give isl_union_pw_multi_aff * + isl_pw_multi_aff_to_union_pw_multi_aff( + __isl_take isl_pw_multi_aff *pma); + __isl_give isl_union_pw_multi_aff * + isl_union_pw_multi_aff_from_pw_multi_aff( + __isl_take isl_pw_multi_aff *pma); + + #include + __isl_give isl_union_pw_qpolynomial * + isl_pw_qpolynomial_to_union_pw_qpolynomial( + __isl_take isl_pw_qpolynomial *pwqp); + __isl_give isl_union_pw_qpolynomial * + isl_union_pw_qpolynomial_from_pw_qpolynomial( + __isl_take isl_pw_qpolynomial *pwqp); + __isl_give isl_union_pw_qpolynomial_fold * + isl_pw_qpolynomial_fold_to_union_pw_qpolynomial_fold( + __isl_take isl_pw_qpolynomial_fold *pwf); + __isl_give isl_union_pw_qpolynomial_fold * + isl_union_pw_qpolynomial_fold_from_pw_qpolynomial_fold( + __isl_take isl_pw_qpolynomial_fold *pwf); + +C and C perform +the same operation. +Similarly for C and +C, +for +C and +C, and +for +C and +C. + +The inverse conversions below can only be used if the input +expression is known to live in exactly one space. + + #include + isl_bool isl_union_pw_multi_aff_isa_pw_multi_aff( + __isl_keep isl_union_pw_multi_aff *upma); + __isl_give isl_pw_multi_aff * + isl_union_pw_multi_aff_as_pw_multi_aff( + __isl_take isl_union_pw_multi_aff *upma); + +A union piecewise expression containing a single base expression +on a universe domain can also be created directly from +a base expression using the following functions. + + #include + __isl_give isl_union_pw_aff *isl_union_pw_aff_from_aff( + __isl_take isl_aff *aff); + __isl_give isl_union_pw_multi_aff * + isl_union_pw_multi_aff_from_multi_aff( + __isl_take isl_multi_aff *ma); + +The following functions create a base expression on each +of the sets in the union set and collect the results. + + #include + __isl_give isl_union_pw_multi_aff * + isl_union_pw_multi_aff_from_union_pw_aff( + __isl_take isl_union_pw_aff *upa); + __isl_give isl_union_pw_aff * + isl_union_pw_multi_aff_get_union_pw_aff( + __isl_keep isl_union_pw_multi_aff *upma, int pos); + __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_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); + +The C argument of C +is the identifier of a parameter that may or may not already +be present in C. + +An C that is equal to a (parametric) affine +or piecewise affine +expression on a given domain can be created using the following +functions. + + #include + __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. + + #include + __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); + __isl_give isl_union_pw_multi_aff * + isl_union_pw_multi_aff_add_pw_multi_aff( + __isl_take isl_union_pw_multi_aff *upma, + __isl_take isl_pw_multi_aff *pma); + + #include + __isl_give isl_union_pw_qpolynomial * + isl_union_pw_qpolynomial_add_pw_qpolynomial( + __isl_take isl_union_pw_qpolynomial *upwqp, + __isl_take isl_pw_qpolynomial *pwqp); + +Union expressions can be copied and freed using +the following functions. + + #include + __isl_give isl_union_pw_aff *isl_union_pw_aff_copy( + __isl_keep isl_union_pw_aff *upa); + __isl_null isl_union_pw_aff *isl_union_pw_aff_free( + __isl_take isl_union_pw_aff *upa); + __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( + __isl_take isl_union_pw_multi_aff *upma); + + #include + __isl_give isl_union_pw_qpolynomial * + isl_union_pw_qpolynomial_copy( + __isl_keep isl_union_pw_qpolynomial *upwqp); + __isl_null isl_union_pw_qpolynomial * + isl_union_pw_qpolynomial_free( + __isl_take isl_union_pw_qpolynomial *upwqp); + __isl_give isl_union_pw_qpolynomial_fold * + isl_union_pw_qpolynomial_fold_copy( + __isl_keep isl_union_pw_qpolynomial_fold *upwf); + __isl_null isl_union_pw_qpolynomial_fold * + isl_union_pw_qpolynomial_fold_free( + __isl_take isl_union_pw_qpolynomial_fold *upwf); + +To iterate over the base expressions in a union expression, +use the following functions. + + #include + isl_size isl_union_pw_aff_n_pw_aff( + __isl_keep isl_union_pw_aff *upa); + isl_stat isl_union_pw_aff_foreach_pw_aff( + __isl_keep isl_union_pw_aff *upa, + isl_stat (*fn)(__isl_take isl_pw_aff *pa, + void *user), void *user); + isl_bool isl_union_pw_aff_every_pw_aff( + __isl_keep isl_union_pw_aff *upa, + isl_bool (*test)(__isl_keep isl_pw_aff *pa, + void *user), void *user); + isl_size isl_union_pw_multi_aff_n_pw_multi_aff( + __isl_keep isl_union_pw_multi_aff *upma); + isl_stat isl_union_pw_multi_aff_foreach_pw_multi_aff( + __isl_keep isl_union_pw_multi_aff *upma, + isl_stat (*fn)(__isl_take isl_pw_multi_aff *pma, + void *user), void *user); + isl_bool isl_union_pw_multi_aff_every_pw_multi_aff( + __isl_keep isl_union_pw_multi_aff *upma, + isl_bool (*test)( + __isl_keep isl_pw_multi_aff *pma, + void *user), void *user); + + #include + isl_size isl_union_pw_qpolynomial_n_pw_qpolynomial( + __isl_keep isl_union_pw_qpolynomial *upwqp); + isl_stat isl_union_pw_qpolynomial_foreach_pw_qpolynomial( + __isl_keep isl_union_pw_qpolynomial *upwqp, + isl_stat (*fn)(__isl_take isl_pw_qpolynomial *pwqp, + void *user), void *user); + isl_bool isl_union_pw_qpolynomial_every_pw_qpolynomial( + __isl_keep isl_union_pw_qpolynomial *upwqp, + isl_bool (*test)( + __isl_keep isl_pw_qpolynomial *pwqp, + void *user), void *user); + isl_size isl_union_pw_qpolynomial_fold_n_pw_qpolynomial_fold( + __isl_keep isl_union_pw_qpolynomial_fold *upwf); + isl_stat isl_union_pw_qpolynomial_fold_foreach_pw_qpolynomial_fold( + __isl_keep isl_union_pw_qpolynomial_fold *upwf, + isl_stat (*fn)(__isl_take isl_pw_qpolynomial_fold *pwf, + void *user), void *user); + isl_bool + isl_union_pw_qpolynomial_fold_every_pw_qpolynomial_fold( + __isl_keep isl_union_pw_qpolynomial_fold *upwf, + isl_bool (*test)( + __isl_keep isl_pw_qpolynomial_fold *pwf, + void *user), void *user); + +To extract the base expression in a given space from a union, use +the following functions. + + #include + __isl_give isl_pw_aff *isl_union_pw_aff_extract_pw_aff( + __isl_keep isl_union_pw_aff *upa, + __isl_take isl_space *space); + __isl_give isl_pw_multi_aff * + isl_union_pw_multi_aff_extract_pw_multi_aff( + __isl_keep isl_union_pw_multi_aff *upma, + __isl_take isl_space *space); + + #include + __isl_give isl_pw_qpolynomial * + isl_union_pw_qpolynomial_extract_pw_qpolynomial( + __isl_keep isl_union_pw_qpolynomial *upwqp, + __isl_take isl_space *space); + +It is also possible to obtain a list of the base expressions using +the following functions. + + #include + __isl_give isl_pw_aff_list * + isl_union_pw_aff_get_pw_aff_list( + __isl_keep isl_union_pw_aff *upa); + __isl_give isl_pw_multi_aff_list * + isl_union_pw_multi_aff_get_pw_multi_aff_list( + __isl_keep isl_union_pw_multi_aff *upma); + + #include + __isl_give isl_pw_qpolynomial_list * + isl_union_pw_qpolynomial_get_pw_qpolynomial_list( + __isl_keep isl_union_pw_qpolynomial *upwqp); + __isl_give isl_pw_qpolynomial_fold_list * + isl_union_pw_qpolynomial_fold_get_pw_qpolynomial_fold_list( + __isl_keep isl_union_pw_qpolynomial_fold *upwf); + +The returned list can be manipulated using the functions in L<"Lists">. + +=head2 Input and Output + +For set and relation, +C supports its own input/output format, which is similar +to the C format, but also supports the C format +in some cases. +For other object types, typically only an C format is supported. + +=head3 C format + +The C format is similar to that of C, but has a different +syntax for describing the parameters and allows for the definition +of an existentially quantified variable as the integer division +of an affine expression. +For example, the set of integers C between C<0> and C +such that C can be described as + + [n] -> { [i] : exists (a = [i/10] : 0 <= i and i <= n and + i - 10 a <= 6) } + +A set or relation can have several disjuncts, separated +by the keyword C. Each disjunct is either a conjunction +of constraints or a projection (C) of a conjunction +of constraints. The constraints are separated by the keyword +C. + +=head3 C format + +If the represented set is a union, then the first line +contains a single number representing the number of disjuncts. +Otherwise, a line containing the number C<1> is optional. + +Each disjunct is represented by a matrix of constraints. +The first line contains two numbers representing +the number of rows and columns, +where the number of rows is equal to the number of constraints +and the number of columns is equal to two plus the number of variables. +The following lines contain the actual rows of the constraint matrix. +In each row, the first column indicates whether the constraint +is an equality (C<0>) or inequality (C<1>). The final column +corresponds to the constant term. + +If the set is parametric, then the coefficients of the parameters +appear in the last columns before the constant column. +The coefficients of any existentially quantified variables appear +between those of the set variables and those of the parameters. + +=head3 Extended C format + +The extended C format is nearly identical to the +C format. The only difference is that the line +containing the number of rows and columns of a constraint matrix +also contains four additional numbers: +the number of output dimensions, the number of input dimensions, +the number of local dimensions (i.e., the number of existentially +quantified variables) and the number of parameters. +For sets, the number of ``output'' dimensions is equal +to the number of set dimensions, while the number of ``input'' +dimensions is zero. + +=head3 Input + +Objects can be read from input using the following functions. + + #include + __isl_give isl_id *isl_id_read_from_str(isl_ctx *ctx, + const char *str); + __isl_give isl_multi_id *isl_multi_id_read_from_str( + isl_ctx *ctx, const char *str); + + #include + __isl_give isl_val *isl_val_read_from_str(isl_ctx *ctx, + const char *str); + __isl_give isl_multi_val *isl_multi_val_read_from_str( + isl_ctx *ctx, const char *str); + + #include + __isl_give isl_space *isl_space_read_from_str( + isl_ctx *ctx, const char *str); + + #include + __isl_give isl_basic_set *isl_basic_set_read_from_file( + isl_ctx *ctx, FILE *input); + __isl_give isl_basic_set *isl_basic_set_read_from_str( + isl_ctx *ctx, const char *str); + __isl_give isl_set *isl_set_read_from_file(isl_ctx *ctx, + FILE *input); + __isl_give isl_set *isl_set_read_from_str(isl_ctx *ctx, + const char *str); + + #include + __isl_give isl_basic_map *isl_basic_map_read_from_file( + isl_ctx *ctx, FILE *input); + __isl_give isl_basic_map *isl_basic_map_read_from_str( + isl_ctx *ctx, const char *str); + __isl_give isl_map *isl_map_read_from_file( + isl_ctx *ctx, FILE *input); + __isl_give isl_map *isl_map_read_from_str(isl_ctx *ctx, + const char *str); + + #include + __isl_give isl_union_set *isl_union_set_read_from_file( + isl_ctx *ctx, FILE *input); + __isl_give isl_union_set *isl_union_set_read_from_str( + isl_ctx *ctx, const char *str); + + #include + __isl_give isl_union_map *isl_union_map_read_from_file( + isl_ctx *ctx, FILE *input); + __isl_give isl_union_map *isl_union_map_read_from_str( + isl_ctx *ctx, const char *str); + + #include + __isl_give isl_aff *isl_aff_read_from_str( + isl_ctx *ctx, const char *str); + __isl_give isl_multi_aff *isl_multi_aff_read_from_str( + isl_ctx *ctx, const char *str); + __isl_give isl_pw_aff *isl_pw_aff_read_from_str( + isl_ctx *ctx, const char *str); + __isl_give isl_pw_multi_aff *isl_pw_multi_aff_read_from_str( + isl_ctx *ctx, const char *str); + __isl_give isl_multi_pw_aff *isl_multi_pw_aff_read_from_str( + isl_ctx *ctx, const char *str); + __isl_give isl_union_pw_aff * + isl_union_pw_aff_read_from_str( + isl_ctx *ctx, const char *str); + __isl_give isl_union_pw_multi_aff * + isl_union_pw_multi_aff_read_from_str( + isl_ctx *ctx, const char *str); + __isl_give isl_multi_union_pw_aff * + isl_multi_union_pw_aff_read_from_str( + isl_ctx *ctx, const char *str); + + #include + __isl_give isl_union_pw_qpolynomial * + isl_union_pw_qpolynomial_read_from_str( + isl_ctx *ctx, const char *str); + + __isl_give isl_pw_qpolynomial_fold * + isl_pw_qpolynomial_fold_read_from_str( + isl_ctx *ctx, const char *str); + +For sets and relations, +the input format is autodetected and may be either the C format +or the C format. + +=head3 Output + +Before anything can be printed, an C needs to +be created. + + __isl_give isl_printer *isl_printer_to_file(isl_ctx *ctx, + FILE *file); + __isl_give isl_printer *isl_printer_to_str(isl_ctx *ctx); + __isl_null isl_printer *isl_printer_free( + __isl_take isl_printer *printer); + +C prints to the given file, while +C prints to a string that can be extracted +using the following function. + + #include + __isl_give char *isl_printer_get_str( + __isl_keep isl_printer *printer); + +The printer can be inspected using the following functions. + + FILE *isl_printer_get_file( + __isl_keep isl_printer *printer); + int isl_printer_get_output_format( + __isl_keep isl_printer *p); + int isl_printer_get_yaml_style(__isl_keep isl_printer *p); + +The behavior of the printer can be modified in various ways + + __isl_give isl_printer *isl_printer_set_output_format( + __isl_take isl_printer *p, int output_format); + __isl_give isl_printer *isl_printer_set_indent( + __isl_take isl_printer *p, int indent); + __isl_give isl_printer *isl_printer_set_indent_prefix( + __isl_take isl_printer *p, const char *prefix); + __isl_give isl_printer *isl_printer_indent( + __isl_take isl_printer *p, int indent); + __isl_give isl_printer *isl_printer_set_prefix( + __isl_take isl_printer *p, const char *prefix); + __isl_give isl_printer *isl_printer_set_suffix( + __isl_take isl_printer *p, const char *suffix); + __isl_give isl_printer *isl_printer_set_yaml_style( + __isl_take isl_printer *p, int yaml_style); + +The C may be either C, C, +C, C or C +and defaults to C. +Each line in the output is prefixed by C, +indented by C (set by C) spaces +(default: 0), prefixed by C and suffixed by C. +In the C format output, +the coefficients of the existentially quantified variables +appear between those of the set variables and those +of the parameters. +The function C increases the indentation +by the specified amount (which may be negative). +The YAML style may be either C or +C and when we are printing something +in YAML format. + +To actually print something, use + + #include + __isl_give isl_printer *isl_printer_print_double( + __isl_take isl_printer *p, double d); + + #include + __isl_give isl_printer *isl_printer_print_val( + __isl_take isl_printer *p, __isl_keep isl_val *v); + __isl_give isl_printer *isl_printer_print_multi_val( + __isl_take isl_printer *p, + __isl_keep isl_multi_val *mv); + + #include + __isl_give isl_printer *isl_printer_print_basic_set( + __isl_take isl_printer *printer, + __isl_keep isl_basic_set *bset); + __isl_give isl_printer *isl_printer_print_set( + __isl_take isl_printer *printer, + __isl_keep isl_set *set); + + #include + __isl_give isl_printer *isl_printer_print_basic_map( + __isl_take isl_printer *printer, + __isl_keep isl_basic_map *bmap); + __isl_give isl_printer *isl_printer_print_map( + __isl_take isl_printer *printer, + __isl_keep isl_map *map); + + #include + __isl_give isl_printer *isl_printer_print_union_set( + __isl_take isl_printer *p, + __isl_keep isl_union_set *uset); + + #include + __isl_give isl_printer *isl_printer_print_union_map( + __isl_take isl_printer *p, + __isl_keep isl_union_map *umap); + + #include + __isl_give isl_printer *isl_printer_print_multi_id( + __isl_take isl_printer *p, + __isl_keep isl_multi_id *mi); + + #include + __isl_give isl_printer *isl_printer_print_aff( + __isl_take isl_printer *p, __isl_keep isl_aff *aff); + __isl_give isl_printer *isl_printer_print_multi_aff( + __isl_take isl_printer *p, + __isl_keep isl_multi_aff *maff); + __isl_give isl_printer *isl_printer_print_pw_aff( + __isl_take isl_printer *p, + __isl_keep isl_pw_aff *pwaff); + __isl_give isl_printer *isl_printer_print_pw_multi_aff( + __isl_take isl_printer *p, + __isl_keep isl_pw_multi_aff *pma); + __isl_give isl_printer *isl_printer_print_multi_pw_aff( + __isl_take isl_printer *p, + __isl_keep isl_multi_pw_aff *mpa); + __isl_give isl_printer *isl_printer_print_union_pw_aff( + __isl_take isl_printer *p, + __isl_keep isl_union_pw_aff *upa); + __isl_give isl_printer *isl_printer_print_union_pw_multi_aff( + __isl_take isl_printer *p, + __isl_keep isl_union_pw_multi_aff *upma); + __isl_give isl_printer * + isl_printer_print_multi_union_pw_aff( + __isl_take isl_printer *p, + __isl_keep isl_multi_union_pw_aff *mupa); + + #include + __isl_give isl_printer *isl_printer_print_qpolynomial( + __isl_take isl_printer *p, + __isl_keep isl_qpolynomial *qp); + __isl_give isl_printer *isl_printer_print_pw_qpolynomial( + __isl_take isl_printer *p, + __isl_keep isl_pw_qpolynomial *pwqp); + __isl_give isl_printer *isl_printer_print_union_pw_qpolynomial( + __isl_take isl_printer *p, + __isl_keep isl_union_pw_qpolynomial *upwqp); + + __isl_give isl_printer * + isl_printer_print_pw_qpolynomial_fold( + __isl_take isl_printer *p, + __isl_keep isl_pw_qpolynomial_fold *pwf); + __isl_give isl_printer * + isl_printer_print_union_pw_qpolynomial_fold( + __isl_take isl_printer *p, + __isl_keep isl_union_pw_qpolynomial_fold *upwf); + +For C, +C and +C, +the output format of the printer +needs to be set to either C or C. +For C and +C, only C +is supported. +In case of printing in C, the user may want +to set the names of all dimensions first. + +C also provides limited support for printing YAML documents, +just enough for the internal use for printing such documents. + + #include + __isl_give isl_printer *isl_printer_yaml_start_mapping( + __isl_take isl_printer *p); + __isl_give isl_printer *isl_printer_yaml_end_mapping( + __isl_take isl_printer *p); + __isl_give isl_printer *isl_printer_yaml_start_sequence( + __isl_take isl_printer *p); + __isl_give isl_printer *isl_printer_yaml_end_sequence( + __isl_take isl_printer *p); + __isl_give isl_printer *isl_printer_yaml_next( + __isl_take isl_printer *p); + +A document is started by a call to either +C or C. +Anything printed to the printer after such a call belong to the +first key of the mapping or the first element in the sequence. +The function C moves to the value if +we are currently printing a mapping key, the next key if we +are printing a value or the next element if we are printing +an element in a sequence. +Nested mappings and sequences are initiated by the same +C or C. +Each call to these functions needs to have a corresponding call to +C or C. + +When called on a file printer, the following function flushes +the file. When called on a string printer, the buffer is cleared. + + __isl_give isl_printer *isl_printer_flush( + __isl_take isl_printer *p); + +The following functions allow the user to attach +notes to a printer in order to keep track of additional state. + + #include + isl_bool isl_printer_has_note(__isl_keep isl_printer *p, + __isl_keep isl_id *id); + __isl_give isl_id *isl_printer_get_note( + __isl_keep isl_printer *p, __isl_take isl_id *id); + __isl_give isl_printer *isl_printer_set_note( + __isl_take isl_printer *p, + __isl_take isl_id *id, __isl_take isl_id *note); + +C associates the given note to the given +identifier in the printer. +C retrieves a note associated to an +identifier, while +C checks if there is such a note. +C fails if the requested note does not exist. + +Alternatively, a string representation can be obtained +directly using the following functions, which always print +in isl format. + + #include + __isl_give char *isl_id_to_str( + __isl_keep isl_id *id); + __isl_give char *isl_multi_id_to_str( + __isl_keep isl_multi_id *mi); + + #include + __isl_give char *isl_space_to_str( + __isl_keep isl_space *space); + + #include + __isl_give char *isl_val_to_str(__isl_keep isl_val *v); + __isl_give char *isl_multi_val_to_str( + __isl_keep isl_multi_val *mv); + + #include + __isl_give char *isl_basic_set_to_str( + __isl_keep isl_basic_set *bset); + __isl_give char *isl_set_to_str( + __isl_keep isl_set *set); + + #include + __isl_give char *isl_union_set_to_str( + __isl_keep isl_union_set *uset); + + #include + __isl_give char *isl_basic_map_to_str( + __isl_keep isl_basic_map *bmap); + __isl_give char *isl_map_to_str( + __isl_keep isl_map *map); + + #include + __isl_give char *isl_union_map_to_str( + __isl_keep isl_union_map *umap); + + #include + __isl_give char *isl_aff_to_str(__isl_keep isl_aff *aff); + __isl_give char *isl_pw_aff_to_str( + __isl_keep isl_pw_aff *pa); + __isl_give char *isl_multi_aff_to_str( + __isl_keep isl_multi_aff *ma); + __isl_give char *isl_pw_multi_aff_to_str( + __isl_keep isl_pw_multi_aff *pma); + __isl_give char *isl_multi_pw_aff_to_str( + __isl_keep isl_multi_pw_aff *mpa); + __isl_give char *isl_union_pw_aff_to_str( + __isl_keep isl_union_pw_aff *upa); + __isl_give char *isl_union_pw_multi_aff_to_str( + __isl_keep isl_union_pw_multi_aff *upma); + __isl_give char *isl_multi_union_pw_aff_to_str( + __isl_keep isl_multi_union_pw_aff *mupa); + + #include + __isl_give char *isl_point_to_str( + __isl_keep isl_point *pnt); + + #include + __isl_give char *isl_pw_qpolynomial_to_str( + __isl_keep isl_pw_qpolynomial *pwqp); + __isl_give char *isl_union_pw_qpolynomial_to_str( + __isl_keep isl_union_pw_qpolynomial *upwqp); + +=head2 Properties + +=head3 Unary Properties + +=over + +=item * Emptiness + +The following functions test whether the given set or relation +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_bool isl_basic_set_plain_is_empty( + __isl_keep isl_basic_set *bset); + isl_bool isl_basic_set_is_empty( + __isl_keep isl_basic_set *bset); + 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_bool isl_union_set_is_empty( + __isl_keep isl_union_set *uset); + + #include + isl_bool isl_basic_map_plain_is_empty( + __isl_keep isl_basic_map *bmap); + isl_bool isl_basic_map_is_empty( + __isl_keep isl_basic_map *bmap); + 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_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); + + #include + isl_bool isl_union_pw_multi_aff_plain_is_empty( + __isl_keep isl_union_pw_multi_aff *upma); + +=item * Universality + + isl_bool isl_basic_set_plain_is_universe( + __isl_keep isl_basic_set *bset); + isl_bool isl_basic_set_is_universe( + __isl_keep isl_basic_set *bset); + isl_bool isl_basic_map_plain_is_universe( + __isl_keep isl_basic_map *bmap); + isl_bool isl_basic_map_is_universe( + __isl_keep isl_basic_map *bmap); + isl_bool isl_set_plain_is_universe( + __isl_keep isl_set *set); + isl_bool isl_map_plain_is_universe( + __isl_keep isl_map *map); + +=item * Single-valuedness + + #include + isl_bool isl_set_is_singleton(__isl_keep isl_set *set); + + #include + isl_bool isl_basic_map_is_single_valued( + __isl_keep isl_basic_map *bmap); + isl_bool isl_map_plain_is_single_valued( + __isl_keep isl_map *map); + isl_bool isl_map_is_single_valued(__isl_keep isl_map *map); + + #include + isl_bool isl_union_map_is_single_valued( + __isl_keep isl_union_map *umap); + +=item * Injectivity + + isl_bool isl_map_plain_is_injective( + __isl_keep isl_map *map); + isl_bool isl_map_is_injective( + __isl_keep isl_map *map); + isl_bool isl_union_map_plain_is_injective( + __isl_keep isl_union_map *umap); + isl_bool isl_union_map_is_injective( + __isl_keep isl_union_map *umap); + +=item * Bijectivity + + isl_bool isl_map_is_bijective( + __isl_keep isl_map *map); + isl_bool isl_union_map_is_bijective( + __isl_keep isl_union_map *umap); + +=item * Identity + +The following functions test whether the given relation +only maps elements to themselves. + + #include + isl_bool isl_map_is_identity( + __isl_keep isl_map *map); + + #include + isl_bool isl_union_map_is_identity( + __isl_keep isl_union_map *umap); + +=item * Position + + __isl_give isl_val * + isl_basic_map_plain_get_val_if_fixed( + __isl_keep isl_basic_map *bmap, + enum isl_dim_type type, unsigned pos); + __isl_give isl_val *isl_set_plain_get_val_if_fixed( + __isl_keep isl_set *set, + enum isl_dim_type type, unsigned pos); + __isl_give isl_multi_val * + isl_set_get_plain_multi_val_if_fixed( + __isl_keep isl_set *set); + __isl_give isl_val *isl_map_plain_get_val_if_fixed( + __isl_keep isl_map *map, + enum isl_dim_type type, unsigned pos); + +If the set or relation obviously lies on a hyperplane where the given dimension +has a fixed value, then return that value. +Otherwise return NaN. +C collects the results over +all set dimensions. + +=item * Stride + +Stride detection is based on heuristics. +The strides returned by the functions below are always valid, +but there may be larger valid strides that are not detected. + + 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); + +Check if the values of the given set dimension are equal to a fixed +value modulo some integer value. If so, assign the modulo to C<*modulo> +and the fixed value to C<*residue>. If the given dimension attains only +a single value, then assign C<0> to C<*modulo> and the fixed value to +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_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); + __isl_give isl_fixed_box *isl_set_get_lattice_tile( + __isl_keep isl_set *set); + + #include + __isl_give isl_stride_info * + isl_map_get_range_stride_info( + __isl_keep isl_map *map, int pos); + __isl_give isl_fixed_box * + isl_map_get_range_lattice_tile( + __isl_keep isl_map *map); + +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 or +check if the values of the given output dimensions are equal to +some affine expression of the input 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 performs the same +computation as C but only returns the stride. +The function C collects the stride +information over all output dimensions. +In particular, it returns a tile of a rectangular lattice +(possibly of size 1 in all directions) +containing the output in terms of the parameters and the input dimensions. +The size and the offset of this tile correspond to +the strides and the offsets of the stride information and +can be extracted from the returned +C using the functions described under "Box hull" in +L. Note that the C object returned by +C is always valid. +The function C collects the same stride +information over all set dimensions. +For the other functions, +the stride and offset can be extracted from the returned object +using the following functions. + + #include + __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 copied and released using the following +functions. + + #include + __isl_give isl_stride_info *isl_stride_info_copy( + __isl_keep isl_stride_info *si); + __isl_null isl_stride_info *isl_stride_info_free( + __isl_take isl_stride_info *si); + +=item * Dependence + +To check whether a function involves any local variables, +i.e., integer divisions, +the following functions can be used. + + #include + isl_bool isl_set_involves_locals( + __isl_keep isl_set *set); + + #include + isl_bool isl_aff_involves_locals( + __isl_keep isl_aff *aff); + isl_bool isl_multi_aff_involves_locals( + __isl_keep isl_multi_aff *ma); + isl_bool isl_pw_multi_aff_involves_locals( + __isl_keep isl_pw_multi_aff *pma); + isl_bool isl_union_pw_multi_aff_involves_locals( + __isl_keep isl_union_pw_multi_aff *upma); + +To check whether the description of a set, relation or function depends +on a parameter or one or more given dimensions, +the following functions can be used. + + #include + isl_bool isl_constraint_involves_dims( + __isl_keep isl_constraint *constraint, + enum isl_dim_type type, unsigned first, unsigned n); + + #include + isl_bool isl_basic_set_involves_dims( + __isl_keep isl_basic_set *bset, + enum isl_dim_type type, unsigned first, unsigned n); + isl_bool isl_set_involves_dims(__isl_keep isl_set *set, + enum isl_dim_type type, unsigned first, unsigned n); + + #include + isl_bool isl_basic_map_involves_dims( + __isl_keep isl_basic_map *bmap, + enum isl_dim_type type, unsigned first, unsigned n); + isl_bool isl_map_involves_dims(__isl_keep isl_map *map, + enum isl_dim_type type, unsigned first, unsigned n); + + #include + isl_bool isl_union_map_involves_dims( + __isl_keep isl_union_map *umap, + enum isl_dim_type type, unsigned first, unsigned n); + + #include + isl_bool isl_aff_involves_dims(__isl_keep isl_aff *aff, + enum isl_dim_type type, unsigned first, unsigned n); + isl_bool isl_pw_aff_involves_param_id( + __isl_keep isl_pw_aff *pa, + __isl_keep isl_id *id); + isl_bool isl_pw_aff_involves_dims( + __isl_keep isl_pw_aff *pwaff, + enum isl_dim_type type, unsigned first, unsigned n); + isl_bool isl_multi_aff_involves_dims( + __isl_keep isl_multi_aff *ma, + enum isl_dim_type type, unsigned first, unsigned n); + isl_bool isl_pw_multi_aff_involves_param_id( + __isl_keep isl_pw_multi_aff *pma, + __isl_keep isl_id *id); + isl_bool isl_pw_multi_aff_involves_dims( + __isl_keep isl_pw_multi_aff *pma, + enum isl_dim_type type, unsigned first, unsigned n); + isl_bool isl_multi_pw_aff_involves_dims( + __isl_keep isl_multi_pw_aff *mpa, + enum isl_dim_type type, unsigned first, unsigned n); + isl_bool isl_multi_pw_aff_involves_param_id( + __isl_keep isl_multi_pw_aff *mpa, + __isl_keep isl_id *id); + isl_bool isl_multi_pw_aff_involves_param_id_list( + __isl_keep isl_multi_pw_aff *mpa, + __isl_keep isl_id_list *list); + + #include + isl_bool isl_qpolynomial_involves_dims( + __isl_keep isl_qpolynomial *qp, + enum isl_dim_type type, unsigned first, unsigned n); + isl_bool isl_pw_qpolynomial_involves_param_id( + __isl_keep isl_pw_qpolynomial *pwqp, + __isl_keep isl_id *id); + isl_bool isl_pw_qpolynomial_fold_involves_param_id( + __isl_keep isl_pw_qpolynomial_fold *pwf, + __isl_keep isl_id *id); + +Similarly, the following functions can be used to check whether +a given dimension is involved in any lower or upper bound. + + #include + isl_bool isl_set_dim_has_any_lower_bound( + __isl_keep isl_set *set, + enum isl_dim_type type, unsigned pos); + isl_bool isl_set_dim_has_any_upper_bound( + __isl_keep isl_set *set, + enum isl_dim_type type, unsigned pos); + +Note that these functions return true even if there is a bound on +the dimension on only some of the basic sets of C. +To check if they have a bound for all of the basic sets in C, +use the following functions instead. + + #include + isl_bool isl_set_dim_has_lower_bound( + __isl_keep isl_set *set, + enum isl_dim_type type, unsigned pos); + isl_bool isl_set_dim_has_upper_bound( + __isl_keep isl_set *set, + enum isl_dim_type type, unsigned pos); + +=item * Space + +To check whether a set is a parameter domain, use this function: + + isl_bool isl_set_is_params(__isl_keep isl_set *set); + isl_bool isl_union_set_is_params( + __isl_keep isl_union_set *uset); + +=item * Wrapping + +The following functions check whether the space of the given +(basic) set or relation domain and/or range is a wrapped relation. + + #include + isl_bool isl_space_is_wrapping( + __isl_keep isl_space *space); + isl_bool isl_space_domain_is_wrapping( + __isl_keep isl_space *space); + isl_bool isl_space_range_is_wrapping( + __isl_keep isl_space *space); + isl_bool isl_space_is_product( + __isl_keep isl_space *space); + + #include + isl_bool isl_basic_set_is_wrapping( + __isl_keep isl_basic_set *bset); + isl_bool isl_set_is_wrapping(__isl_keep isl_set *set); + + #include + isl_bool isl_map_domain_is_wrapping( + __isl_keep isl_map *map); + isl_bool isl_map_range_is_wrapping( + __isl_keep isl_map *map); + isl_bool isl_map_is_product(__isl_keep isl_map *map); + + #include + isl_bool isl_multi_id_range_is_wrapping( + __isl_keep isl_multi_id *mi); + + #include + isl_bool isl_multi_val_range_is_wrapping( + __isl_keep isl_multi_val *mv); + + #include + isl_bool isl_multi_aff_range_is_wrapping( + __isl_keep isl_multi_aff *ma); + isl_bool isl_multi_pw_aff_range_is_wrapping( + __isl_keep isl_multi_pw_aff *mpa); + isl_bool isl_multi_union_pw_aff_range_is_wrapping( + __isl_keep isl_multi_union_pw_aff *mupa); + +The input to C should +be the space of a set, while that of +C and +C should be the space of a relation. +The input to C can be either the space +of a set or that of a binary relation. +In case the input is the space of a binary relation, it checks +whether both domain and range are wrapping. + +=item * Internal Product + + isl_bool isl_basic_map_can_zip( + __isl_keep isl_basic_map *bmap); + isl_bool isl_map_can_zip(__isl_keep isl_map *map); + +Check whether the product of domain and range of the given relation +can be computed, +i.e., whether both domain and range are nested relations. + +=item * Currying + + #include + isl_bool isl_space_can_curry( + __isl_keep isl_space *space); + + #include + isl_bool isl_basic_map_can_curry( + __isl_keep isl_basic_map *bmap); + isl_bool isl_map_can_curry(__isl_keep isl_map *map); + +Check whether the domain of the (basic) relation is a wrapped relation. + + #include + isl_bool isl_space_can_uncurry( + __isl_keep isl_space *space); + + #include + isl_bool isl_basic_map_can_uncurry( + __isl_keep isl_basic_map *bmap); + isl_bool isl_map_can_uncurry(__isl_keep isl_map *map); + +Check whether the range of the (basic) relation is a wrapped relation. + + #include + isl_bool isl_space_can_range_curry( + __isl_keep isl_space *space); + + #include + isl_bool isl_map_can_range_curry( + __isl_keep isl_map *map); + +Check whether the domain of the relation wrapped in the range of +the input is itself a wrapped relation. + +=item * Special Values + + #include + isl_bool isl_aff_is_cst(__isl_keep isl_aff *aff); + isl_bool isl_pw_aff_is_cst(__isl_keep isl_pw_aff *pwaff); + isl_bool isl_multi_pw_aff_is_cst( + __isl_keep isl_multi_pw_aff *mpa); + +Check whether the given expression is a constant. + + #include + isl_bool isl_multi_val_involves_nan( + __isl_keep isl_multi_val *mv); + + #include + isl_bool isl_aff_is_nan(__isl_keep isl_aff *aff); + isl_bool isl_multi_aff_involves_nan( + __isl_keep isl_multi_aff *ma); + isl_bool isl_pw_aff_involves_nan( + __isl_keep isl_pw_aff *pa); + isl_bool isl_pw_multi_aff_involves_nan( + __isl_keep isl_pw_multi_aff *pma); + isl_bool isl_multi_pw_aff_involves_nan( + __isl_keep isl_multi_pw_aff *mpa); + isl_bool isl_union_pw_aff_involves_nan( + __isl_keep isl_union_pw_aff *upa); + isl_bool isl_union_pw_multi_aff_involves_nan( + __isl_keep isl_union_pw_multi_aff *upma); + isl_bool isl_multi_union_pw_aff_involves_nan( + __isl_keep isl_multi_union_pw_aff *mupa); + + #include + isl_bool isl_qpolynomial_is_nan( + __isl_keep isl_qpolynomial *qp); + isl_bool isl_qpolynomial_fold_is_nan( + __isl_keep isl_qpolynomial_fold *fold); + isl_bool isl_pw_qpolynomial_involves_nan( + __isl_keep isl_pw_qpolynomial *pwqp); + isl_bool isl_pw_qpolynomial_fold_involves_nan( + __isl_keep isl_pw_qpolynomial_fold *pwf); + isl_bool isl_union_pw_qpolynomial_involves_nan( + __isl_keep isl_union_pw_qpolynomial *upwqp); + isl_bool isl_union_pw_qpolynomial_fold_involves_nan( + __isl_keep isl_union_pw_qpolynomial_fold *upwf); + +Check whether the given expression is equal to or involves NaN. + + #include + isl_bool isl_multi_val_is_zero( + __isl_keep isl_multi_val *mv); + +Check whether the multiple value is zero. + + #include + isl_bool isl_aff_plain_is_zero( + __isl_keep isl_aff *aff); + +Check whether the affine expression is obviously zero. + +=back + +=head3 Binary Properties + +=over + +=item * Equality + +The following functions check whether two objects +represent the same set, relation or function. +The C variants only return true if the objects +are obviously the same. That is, they may return false +even if the objects are the same, but they will never +return true if the objects are not the same. + + #include + isl_bool isl_basic_set_plain_is_equal( + __isl_keep isl_basic_set *bset1, + __isl_keep isl_basic_set *bset2); + isl_bool isl_basic_set_is_equal( + __isl_keep isl_basic_set *bset1, + __isl_keep isl_basic_set *bset2); + isl_bool isl_set_plain_is_equal( + __isl_keep isl_set *set1, + __isl_keep isl_set *set2); + isl_bool isl_set_is_equal(__isl_keep isl_set *set1, + __isl_keep isl_set *set2); + + #include + isl_bool isl_basic_map_is_equal( + __isl_keep isl_basic_map *bmap1, + __isl_keep isl_basic_map *bmap2); + isl_bool isl_map_is_equal(__isl_keep isl_map *map1, + __isl_keep isl_map *map2); + isl_bool isl_map_plain_is_equal( + __isl_keep isl_map *map1, + __isl_keep isl_map *map2); + + #include + isl_bool isl_union_set_is_equal( + __isl_keep isl_union_set *uset1, + __isl_keep isl_union_set *uset2); + + #include + isl_bool isl_union_map_is_equal( + __isl_keep isl_union_map *umap1, + __isl_keep isl_union_map *umap2); + + #include + isl_bool isl_multi_id_plain_is_equal( + __isl_keep isl_multi_id *mi1, + __isl_keep isl_multi_id *mi2); + + #include + isl_bool isl_multi_val_plain_is_equal( + __isl_keep isl_multi_val *mv1, + __isl_keep isl_multi_val *mv2); + + #include + isl_bool isl_aff_plain_is_equal( + __isl_keep isl_aff *aff1, + __isl_keep isl_aff *aff2); + isl_bool isl_multi_aff_plain_is_equal( + __isl_keep isl_multi_aff *maff1, + __isl_keep isl_multi_aff *maff2); + isl_bool isl_pw_aff_plain_is_equal( + __isl_keep isl_pw_aff *pwaff1, + __isl_keep isl_pw_aff *pwaff2); + isl_bool isl_pw_aff_is_equal( + __isl_keep isl_pw_aff *pa1, + __isl_keep isl_pw_aff *pa2); + isl_bool isl_pw_multi_aff_plain_is_equal( + __isl_keep isl_pw_multi_aff *pma1, + __isl_keep isl_pw_multi_aff *pma2); + isl_bool isl_pw_multi_aff_is_equal( + __isl_keep isl_pw_multi_aff *pma1, + __isl_keep isl_pw_multi_aff *pma2); + isl_bool isl_multi_pw_aff_plain_is_equal( + __isl_keep isl_multi_pw_aff *mpa1, + __isl_keep isl_multi_pw_aff *mpa2); + isl_bool isl_multi_pw_aff_is_equal( + __isl_keep isl_multi_pw_aff *mpa1, + __isl_keep isl_multi_pw_aff *mpa2); + isl_bool isl_union_pw_aff_plain_is_equal( + __isl_keep isl_union_pw_aff *upa1, + __isl_keep isl_union_pw_aff *upa2); + isl_bool isl_union_pw_multi_aff_plain_is_equal( + __isl_keep isl_union_pw_multi_aff *upma1, + __isl_keep isl_union_pw_multi_aff *upma2); + isl_bool isl_multi_union_pw_aff_plain_is_equal( + __isl_keep isl_multi_union_pw_aff *mupa1, + __isl_keep isl_multi_union_pw_aff *mupa2); + + #include + isl_bool isl_union_pw_qpolynomial_plain_is_equal( + __isl_keep isl_union_pw_qpolynomial *upwqp1, + __isl_keep isl_union_pw_qpolynomial *upwqp2); + isl_bool isl_union_pw_qpolynomial_fold_plain_is_equal( + __isl_keep isl_union_pw_qpolynomial_fold *upwf1, + __isl_keep isl_union_pw_qpolynomial_fold *upwf2); + +=item * Disjointness + + #include + isl_bool isl_basic_set_is_disjoint( + __isl_keep isl_basic_set *bset1, + __isl_keep isl_basic_set *bset2); + isl_bool isl_set_plain_is_disjoint( + __isl_keep isl_set *set1, + __isl_keep isl_set *set2); + isl_bool isl_set_is_disjoint(__isl_keep isl_set *set1, + __isl_keep isl_set *set2); + + #include + isl_bool isl_basic_map_is_disjoint( + __isl_keep isl_basic_map *bmap1, + __isl_keep isl_basic_map *bmap2); + isl_bool isl_map_is_disjoint(__isl_keep isl_map *map1, + __isl_keep isl_map *map2); + + #include + isl_bool isl_union_set_is_disjoint( + __isl_keep isl_union_set *uset1, + __isl_keep isl_union_set *uset2); + + #include + isl_bool isl_union_map_is_disjoint( + __isl_keep isl_union_map *umap1, + __isl_keep isl_union_map *umap2); + +=item * Subset + + isl_bool isl_basic_set_is_subset( + __isl_keep isl_basic_set *bset1, + __isl_keep isl_basic_set *bset2); + isl_bool isl_set_is_subset(__isl_keep isl_set *set1, + __isl_keep isl_set *set2); + isl_bool isl_set_is_strict_subset( + __isl_keep isl_set *set1, + __isl_keep isl_set *set2); + isl_bool isl_union_set_is_subset( + __isl_keep isl_union_set *uset1, + __isl_keep isl_union_set *uset2); + isl_bool isl_union_set_is_strict_subset( + __isl_keep isl_union_set *uset1, + __isl_keep isl_union_set *uset2); + isl_bool isl_basic_map_is_subset( + __isl_keep isl_basic_map *bmap1, + __isl_keep isl_basic_map *bmap2); + isl_bool isl_basic_map_is_strict_subset( + __isl_keep isl_basic_map *bmap1, + __isl_keep isl_basic_map *bmap2); + isl_bool isl_map_is_subset( + __isl_keep isl_map *map1, + __isl_keep isl_map *map2); + isl_bool isl_map_is_strict_subset( + __isl_keep isl_map *map1, + __isl_keep isl_map *map2); + isl_bool isl_union_map_is_subset( + __isl_keep isl_union_map *umap1, + __isl_keep isl_union_map *umap2); + isl_bool isl_union_map_is_strict_subset( + __isl_keep isl_union_map *umap1, + __isl_keep isl_union_map *umap2); + +Check whether the first argument is a (strict) subset of the +second argument. + +=item * Order + +Every comparison function returns a negative value if the first +argument is considered smaller than the second, a positive value +if the first argument is considered greater and zero if the two +constraints are considered the same by the comparison criterion. + + #include + int isl_constraint_plain_cmp( + __isl_keep isl_constraint *c1, + __isl_keep isl_constraint *c2); + +This function is useful for sorting Cs. +The order depends on the internal representation of the inputs. +The order is fixed over different calls to the function (assuming +the internal representation of the inputs has not changed), but may +change over different versions of C. + + #include + int isl_constraint_cmp_last_non_zero( + __isl_keep isl_constraint *c1, + __isl_keep isl_constraint *c2); + +This function can be used to sort constraints that live in the same +local space. Constraints that involve ``earlier'' dimensions or +that have a smaller coefficient for the shared latest dimension +are considered smaller than other constraints. +This function only defines a B order. + + #include + int isl_set_plain_cmp(__isl_keep isl_set *set1, + __isl_keep isl_set *set2); + +This function is useful for sorting Cs. +The order depends on the internal representation of the inputs. +The order is fixed over different calls to the function (assuming +the internal representation of the inputs has not changed), but may +change over different versions of C. + + #include + int isl_multi_aff_plain_cmp( + __isl_keep isl_multi_aff *ma1, + __isl_keep isl_multi_aff *ma2); + int isl_pw_aff_plain_cmp(__isl_keep isl_pw_aff *pa1, + __isl_keep isl_pw_aff *pa2); + +The functions C and +C can be used to sort Cs and +Cs. The order is not strictly defined. +The current order sorts expressions that only involve +earlier dimensions before those that involve later dimensions. + +=back + +=head2 Unary Operations + +=over + +=item * Complement + + __isl_give isl_set *isl_set_complement( + __isl_take isl_set *set); + __isl_give isl_map *isl_map_complement( + __isl_take isl_map *map); + +=item * Inverse map + + #include + __isl_give isl_space *isl_space_reverse( + __isl_take isl_space *space); + __isl_give isl_space *isl_space_wrapped_reverse( + __isl_take isl_space *space); + __isl_give isl_space *isl_space_domain_reverse( + __isl_take isl_space *space); + __isl_give isl_space *isl_space_range_reverse( + __isl_take isl_space *space); + + #include + __isl_give isl_aff *isl_aff_domain_reverse( + __isl_take isl_aff *aff); + __isl_give isl_multi_aff * + isl_multi_aff_domain_reverse( + __isl_take isl_multi_aff *ma); + __isl_give isl_pw_aff *isl_pw_aff_domain_reverse( + __isl_take isl_pw_aff *pa); + __isl_give isl_pw_multi_aff * + isl_pw_multi_aff_domain_reverse( + __isl_take isl_pw_multi_aff *pma); + __isl_give isl_multi_pw_aff * + isl_multi_pw_aff_domain_reverse( + __isl_take isl_multi_pw_aff *mpa); + + #include + __isl_give isl_set *isl_set_wrapped_reverse( + __isl_take isl_set *set); + + #include + __isl_give isl_basic_map *isl_basic_map_reverse( + __isl_take isl_basic_map *bmap); + __isl_give isl_map *isl_map_reverse( + __isl_take isl_map *map); + __isl_give isl_map *isl_map_domain_reverse( + __isl_take isl_map *map); + __isl_give isl_map *isl_map_range_reverse( + __isl_take isl_map *map); + + #include + __isl_give isl_union_map *isl_union_map_reverse( + __isl_take isl_union_map *umap); + __isl_give isl_union_map *isl_union_map_domain_reverse( + __isl_take isl_union_map *umap); + __isl_give isl_union_map *isl_union_map_range_reverse( + __isl_take isl_union_map *umap); + + #include + __isl_give isl_qpolynomial * + isl_qpolynomial_domain_reverse( + __isl_take isl_qpolynomial *qp); + __isl_give isl_pw_qpolynomial * + isl_pw_qpolynomial_domain_reverse( + __isl_take isl_pw_qpolynomial *pwqp); + __isl_give isl_union_pw_qpolynomial * + isl_union_pw_qpolynomial_domain_reverse( + __isl_take isl_union_pw_qpolynomial *upwqp); + +The function C reverses the relation +that is embedded in the range of the input map space. +The identifier of the range, if any, is only preserved +if this embedded relation has identical input and output tuples. +Similarly for C. +Along the same lines, C reverses +the relation that is embedded in a set space. + +=item * Tuple binding + +The following function binds +a tuple to a sequence of parameter identifiers, equating +the tuple dimensions to the parameters with those identifiers and +subsequently projecting out the tuple. +If the original object did not reference any such parameters, +then this means that the tuple dimensions are reinterpreted +as parameters. +The space of C needs to match that of the bound tuple. + + #include + __isl_give isl_set *isl_set_bind( + __isl_take isl_set *set, + __isl_take isl_multi_id *tuple); + + #include + __isl_give isl_set *isl_map_bind_domain( + __isl_take isl_map *map, + __isl_take isl_multi_id *tuple); + __isl_give isl_set *isl_map_bind_range( + __isl_take isl_map *map, + __isl_take isl_multi_id *tuple); + + #include + __isl_give isl_union_set *isl_union_map_bind_range( + __isl_take isl_union_map *umap, + __isl_take isl_multi_id *tuple); + + #include + __isl_give isl_pw_aff *isl_pw_aff_bind_domain( + __isl_take isl_pw_aff *pa, + __isl_take isl_multi_id *tuple); + __isl_give isl_multi_aff *isl_multi_aff_bind_domain( + __isl_take isl_multi_aff *ma, + __isl_take isl_multi_id *tuple); + __isl_give isl_pw_multi_aff * + isl_pw_multi_aff_bind_domain( + __isl_take isl_pw_multi_aff *pma, + __isl_take isl_multi_id *tuple); + __isl_give isl_multi_pw_aff * + isl_multi_pw_aff_bind_domain( + __isl_take isl_multi_pw_aff *mpa, + __isl_take isl_multi_id *tuple); + __isl_give isl_pw_aff * + isl_pw_aff_bind_domain_wrapped_domain( + __isl_take isl_pw_aff *pa, + __isl_take isl_multi_id *tuple); + __isl_give isl_multi_aff * + isl_multi_aff_bind_domain_wrapped_domain( + __isl_take isl_multi_aff *ma, + __isl_take isl_multi_id *tuple); + __isl_give isl_pw_multi_aff * + isl_pw_multi_aff_bind_domain_wrapped_domain( + __isl_take isl_pw_multi_aff *pma, + __isl_take isl_multi_id *tuple); + __isl_give isl_multi_pw_aff * + isl_multi_pw_aff_bind_domain_wrapped_domain( + __isl_take isl_multi_pw_aff *mpa, + __isl_take isl_multi_id *tuple); + __isl_give isl_basic_set *isl_aff_bind_id( + __isl_take isl_aff *aff, + __isl_take isl_id *id); + __isl_give isl_set *isl_pw_aff_bind_id( + __isl_take isl_pw_aff *pa, + __isl_take isl_id *id); + __isl_give isl_basic_set *isl_multi_aff_bind( + __isl_take isl_multi_aff *ma, + __isl_take isl_multi_id *tuple); + __isl_give isl_set *isl_multi_pw_aff_bind( + __isl_take isl_multi_pw_aff *mpa, + __isl_take isl_multi_id *tuple); + __isl_give isl_union_set *isl_union_pw_aff_bind_id( + __isl_take isl_union_pw_aff *upa, + __isl_take isl_id *id); + __isl_give isl_union_set * + isl_multi_union_pw_aff_bind( + __isl_take isl_multi_union_pw_aff *mupa, + __isl_take isl_multi_id *tuple); + +Projecting out the domain of the wrapped relation in the domain +of a function leaves the range of that wrapped relation +in the domain of the resulting function. +In the case of C, C, +C, C, +C and +C, the parameters +are bound to the function values and the result lives +in the domain of the input function. + +=item * Projection + + #include + __isl_give isl_space *isl_space_domain( + __isl_take isl_space *space); + __isl_give isl_space *isl_space_range( + __isl_take isl_space *space); + __isl_give isl_space *isl_space_params( + __isl_take isl_space *space); + __isl_give isl_space * + isl_space_domain_wrapped_domain( + __isl_take isl_space *space); + __isl_give isl_space * + isl_space_domain_wrapped_range( + __isl_take isl_space *space); + __isl_give isl_space * + isl_space_range_wrapped_domain( + __isl_take isl_space *space); + __isl_give isl_space * + isl_space_range_wrapped_range( + __isl_take isl_space *space); + + #include + __isl_give isl_local_space *isl_local_space_domain( + __isl_take isl_local_space *ls); + __isl_give isl_local_space *isl_local_space_range( + __isl_take isl_local_space *ls); + + #include + __isl_give isl_basic_set *isl_basic_set_project_out( + __isl_take isl_basic_set *bset, + enum isl_dim_type type, unsigned first, unsigned n); + __isl_give isl_set *isl_set_project_out_param_id( + __isl_take isl_set *set, + __isl_take isl_id *id); + __isl_give isl_set * + isl_set_project_out_param_id_list( + __isl_take isl_set *set, + __isl_take isl_id_list *list); + __isl_give isl_set *isl_set_project_out(__isl_take isl_set *set, + enum isl_dim_type type, unsigned first, unsigned n); + __isl_give isl_set *isl_set_project_out_all_params( + __isl_take isl_set *set); + __isl_give isl_map *isl_set_project_onto_map( + __isl_take isl_set *set, + enum isl_dim_type type, unsigned first, + unsigned n); + __isl_give isl_basic_set *isl_basic_set_params( + __isl_take isl_basic_set *bset); + __isl_give isl_set *isl_set_params(__isl_take isl_set *set); + +The function C returns the domain +of the binary relation wrapped inside the domain of the input. +The function C returns a relation +that projects the input set onto the given set dimensions. + + #include + __isl_give isl_basic_map *isl_basic_map_project_out( + __isl_take isl_basic_map *bmap, + enum isl_dim_type type, unsigned first, unsigned n); + __isl_give isl_map *isl_map_project_out_param_id( + __isl_take isl_map *map, + __isl_take isl_id *id); + __isl_give isl_map *isl_map_project_out_param_id_list( + __isl_take isl_map *map, + __isl_take isl_id_list *list); + __isl_give isl_map *isl_map_project_out(__isl_take isl_map *map, + enum isl_dim_type type, unsigned first, unsigned n); + __isl_give isl_map *isl_map_project_out_all_params( + __isl_take isl_map *map); + __isl_give isl_basic_set *isl_basic_map_domain( + __isl_take isl_basic_map *bmap); + __isl_give isl_basic_set *isl_basic_map_range( + __isl_take isl_basic_map *bmap); + __isl_give isl_set *isl_map_params(__isl_take isl_map *map); + __isl_give isl_set *isl_map_domain( + __isl_take isl_map *bmap); + __isl_give isl_set *isl_map_range( + __isl_take isl_map *map); + + #include + __isl_give isl_union_set *isl_union_set_project_out( + __isl_take isl_union_set *uset, + enum isl_dim_type type, + unsigned first, unsigned n); + __isl_give isl_union_set * + isl_union_set_project_out_all_params( + __isl_take isl_union_set *uset); + __isl_give isl_set *isl_union_set_params( + __isl_take isl_union_set *uset); + +The function C can only project out +parameters. + + #include + __isl_give isl_union_map * + isl_union_map_project_out_param_id( + __isl_take isl_union_map *umap, + __isl_take isl_id *id); + __isl_give isl_union_map * + isl_union_map_project_out_param_id_list( + __isl_take isl_union_map *umap, + __isl_take isl_id_list *list); + __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( + __isl_take isl_union_map *umap); + __isl_give isl_union_set *isl_union_map_range( + __isl_take isl_union_map *umap); + +The function C can only project out +parameters. + + #include + __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); + __isl_give isl_set *isl_pw_aff_domain( + __isl_take isl_pw_aff *pwaff); + __isl_give isl_set *isl_pw_multi_aff_domain( + __isl_take isl_pw_multi_aff *pma); + __isl_give isl_set *isl_multi_pw_aff_domain( + __isl_take isl_multi_pw_aff *mpa); + __isl_give isl_union_set *isl_union_pw_aff_domain( + __isl_take isl_union_pw_aff *upa); + __isl_give isl_union_set *isl_union_pw_multi_aff_domain( + __isl_take isl_union_pw_multi_aff *upma); + __isl_give isl_union_set * + isl_multi_union_pw_aff_domain( + __isl_take isl_multi_union_pw_aff *mupa); + __isl_give isl_set *isl_pw_aff_params( + __isl_take isl_pw_aff *pwa); + +If no explicit domain was set on a zero-dimensional input to +C, then this function will +return a parameter set. + + #include + __isl_give isl_qpolynomial * + isl_qpolynomial_project_domain_on_params( + __isl_take isl_qpolynomial *qp); + __isl_give isl_pw_qpolynomial * + isl_pw_qpolynomial_project_domain_on_params( + __isl_take isl_pw_qpolynomial *pwqp); + __isl_give isl_pw_qpolynomial_fold * + isl_pw_qpolynomial_fold_project_domain_on_params( + __isl_take isl_pw_qpolynomial_fold *pwf); + __isl_give isl_set *isl_pw_qpolynomial_domain( + __isl_take isl_pw_qpolynomial *pwqp); + __isl_give isl_union_set *isl_union_pw_qpolynomial_fold_domain( + __isl_take isl_union_pw_qpolynomial_fold *upwf); + __isl_give isl_union_set *isl_union_pw_qpolynomial_domain( + __isl_take isl_union_pw_qpolynomial *upwqp); + + #include + __isl_give isl_space *isl_space_domain_map( + __isl_take isl_space *space); + __isl_give isl_space *isl_space_range_map( + __isl_take isl_space *space); + + #include + __isl_give isl_map *isl_set_wrapped_domain_map( + __isl_take isl_set *set); + __isl_give isl_basic_map *isl_basic_map_domain_map( + __isl_take isl_basic_map *bmap); + __isl_give isl_basic_map *isl_basic_map_range_map( + __isl_take isl_basic_map *bmap); + __isl_give isl_map *isl_map_domain_map(__isl_take isl_map *map); + __isl_give isl_map *isl_map_range_map(__isl_take isl_map *map); + + #include + __isl_give isl_union_map *isl_union_map_domain_map( + __isl_take isl_union_map *umap); + __isl_give isl_union_pw_multi_aff * + isl_union_map_domain_map_union_pw_multi_aff( + __isl_take isl_union_map *umap); + __isl_give isl_union_map *isl_union_map_range_map( + __isl_take isl_union_map *umap); + __isl_give isl_union_map * + isl_union_set_wrapped_domain_map( + __isl_take isl_union_set *uset); + +The functions above construct a (basic, regular or union) relation +that maps (a wrapped version of) the input relation to its domain or range. +C maps the input set to the domain +of its wrapped relation. + +=item * Elimination + + __isl_give isl_basic_set *isl_basic_set_eliminate( + __isl_take isl_basic_set *bset, + enum isl_dim_type type, + unsigned first, unsigned n); + __isl_give isl_set *isl_set_eliminate( + __isl_take isl_set *set, enum isl_dim_type type, + unsigned first, unsigned n); + __isl_give isl_basic_map *isl_basic_map_eliminate( + __isl_take isl_basic_map *bmap, + enum isl_dim_type type, + unsigned first, unsigned n); + __isl_give isl_map *isl_map_eliminate( + __isl_take isl_map *map, enum isl_dim_type type, + unsigned first, unsigned n); + +Eliminate the coefficients for the given dimensions from the constraints, +without removing the dimensions. + +=item * Constructing a set from a parameter domain + +A set space of a given dimension and with an optional name +can be created from a parameter space using the following functions. + + #include + __isl_give isl_space *isl_space_add_unnamed_tuple_ui( + __isl_take isl_space *space, unsigned dim); + __isl_give isl_space * + isl_space_add_named_tuple_id_ui( + __isl_take isl_space *space, + __isl_take isl_id *tuple_id, unsigned dim); + +A set with a given tuple can be created from a parameter domain +using the following function. + + #include + __isl_give isl_set *isl_set_unbind_params( + __isl_take isl_set *set, + __isl_take isl_multi_id *tuple); + +Any parameters with identifiers in C are reinterpreted +as the corresponding set dimensions. + +A zero-dimensional (local) space or (basic) set can be constructed +on a given parameter domain using the following functions. + + #include + __isl_give isl_space *isl_space_set_from_params( + __isl_take isl_space *space); + + #include + __isl_give isl_local_space * + isl_local_space_set_from_params( + __isl_take isl_local_space *ls); + + #include + __isl_give isl_basic_set *isl_basic_set_from_params( + __isl_take isl_basic_set *bset); + __isl_give isl_set *isl_set_from_params( + __isl_take isl_set *set); + +=item * Constructing a relation from one or two sets + +A map space with a range of a given dimension and with an optional name +can be created from a domain space using the functions +C and C +described above. + +A relation with a given domain tuple can be created from a set +that will become the range of the relation +using the following function. + + #include + __isl_give isl_map * + isl_set_unbind_params_insert_domain( + __isl_take isl_set *set, + __isl_take isl_multi_id *domain); + +Any parameters with identifiers in C are reinterpreted +as the corresponding input dimensions. + +Similarly, a function defined over a parameter domain can +be converted into one defined over a set domain +using the following functions. + + #include + __isl_give isl_aff * + isl_aff_unbind_params_insert_domain( + __isl_take isl_aff *aff, + __isl_take isl_multi_id *domain); + __isl_give isl_multi_aff * + isl_multi_aff_unbind_params_insert_domain( + __isl_take isl_multi_aff *ma, + __isl_take isl_multi_id *domain); + __isl_give isl_multi_pw_aff * + isl_multi_pw_aff_unbind_params_insert_domain( + __isl_take isl_multi_pw_aff *mpa, + __isl_take isl_multi_id *domain); + +Again, +any parameters with identifiers in C are reinterpreted +as the corresponding input dimensions. + +Create a relation with the given set(s) as domain and/or range. +If only the domain or the range is specified, then +the range or domain of the created relation is a zero-dimensional +flat anonymous space. +If the case of C, the input space +specifies both the domain and the range of the result. + + #include + __isl_give isl_space *isl_space_from_domain( + __isl_take isl_space *space); + __isl_give isl_space *isl_space_from_range( + __isl_take isl_space *space); + __isl_give isl_space *isl_space_map_from_set( + __isl_take isl_space *space); + __isl_give isl_space *isl_space_map_from_domain_and_range( + __isl_take isl_space *domain, + __isl_take isl_space *range); + + #include + __isl_give isl_local_space *isl_local_space_from_domain( + __isl_take isl_local_space *ls); + + #include + __isl_give isl_map *isl_set_insert_domain( + __isl_take isl_set *set, + __isl_take isl_space *domain); + __isl_give isl_map *isl_map_from_domain( + __isl_take isl_set *set); + __isl_give isl_map *isl_map_from_range( + __isl_take isl_set *set); + + #include + __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, + __isl_take isl_union_set *range); + + #include + __isl_give isl_multi_id *isl_multi_id_from_range( + __isl_take isl_multi_id *mi); + + #include + __isl_give isl_multi_val *isl_multi_val_from_range( + __isl_take isl_multi_val *mv); + + #include + __isl_give isl_multi_aff * + isl_multi_aff_insert_domain( + __isl_take isl_multi_aff *ma, + __isl_take isl_space *domain); + __isl_give isl_pw_aff *isl_pw_aff_insert_domain( + __isl_take isl_pw_aff *pa, + __isl_take isl_space *domain); + __isl_give isl_pw_multi_aff * + isl_pw_multi_aff_insert_domain( + __isl_take isl_pw_multi_aff *pma, + __isl_take isl_space *domain); + __isl_give isl_multi_pw_aff * + isl_multi_pw_aff_insert_domain( + __isl_take isl_multi_pw_aff *mpa, + __isl_take isl_space *domain); + __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( + __isl_take isl_pw_aff *pwa); + __isl_give isl_multi_pw_aff *isl_multi_pw_aff_from_range( + __isl_take isl_multi_pw_aff *mpa); + __isl_give isl_multi_union_pw_aff * + isl_multi_union_pw_aff_from_range( + __isl_take isl_multi_union_pw_aff *mupa); + __isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_domain( + __isl_take isl_set *set); + __isl_give isl_union_pw_multi_aff * + isl_union_pw_multi_aff_from_domain( + __isl_take isl_union_set *uset); + + #include + __isl_give isl_pw_qpolynomial * + isl_pw_qpolynomial_from_range( + __isl_take isl_pw_qpolynomial *pwqp); + __isl_give isl_pw_qpolynomial_fold * + isl_pw_qpolynomial_fold_from_range( + __isl_take isl_pw_qpolynomial_fold *pwf); + +=item * Slicing + + #include + __isl_give isl_basic_set *isl_basic_set_fix_si( + __isl_take isl_basic_set *bset, + enum isl_dim_type type, unsigned pos, int value); + __isl_give isl_basic_set *isl_basic_set_fix_val( + __isl_take isl_basic_set *bset, + enum isl_dim_type type, unsigned pos, + __isl_take isl_val *v); + __isl_give isl_set *isl_set_fix_si(__isl_take isl_set *set, + enum isl_dim_type type, unsigned pos, int value); + __isl_give isl_set *isl_set_fix_val( + __isl_take isl_set *set, + enum isl_dim_type type, unsigned pos, + __isl_take isl_val *v); + + #include + __isl_give isl_basic_map *isl_basic_map_fix_si( + __isl_take isl_basic_map *bmap, + enum isl_dim_type type, unsigned pos, int value); + __isl_give isl_basic_map *isl_basic_map_fix_val( + __isl_take isl_basic_map *bmap, + enum isl_dim_type type, unsigned pos, + __isl_take isl_val *v); + __isl_give isl_map *isl_map_fix_si(__isl_take isl_map *map, + enum isl_dim_type type, unsigned pos, int value); + __isl_give isl_map *isl_map_fix_val( + __isl_take isl_map *map, + enum isl_dim_type type, unsigned pos, + __isl_take isl_val *v); + + #include + __isl_give isl_pw_multi_aff *isl_pw_multi_aff_fix_si( + __isl_take isl_pw_multi_aff *pma, + enum isl_dim_type type, unsigned pos, int value); + + #include + __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_fix_val( + __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 +dimension has the fixed given value. + + #include + __isl_give isl_basic_set * + isl_basic_set_lower_bound_val( + __isl_take isl_basic_set *bset, + enum isl_dim_type type, unsigned pos, + __isl_take isl_val *value); + __isl_give isl_basic_set * + isl_basic_set_upper_bound_val( + __isl_take isl_basic_set *bset, + enum isl_dim_type type, unsigned pos, + __isl_take isl_val *value); + __isl_give isl_set *isl_set_lower_bound_si( + __isl_take isl_set *set, + enum isl_dim_type type, unsigned pos, int value); + __isl_give isl_set *isl_set_lower_bound_val( + __isl_take isl_set *set, + enum isl_dim_type type, unsigned pos, + __isl_take isl_val *value); + __isl_give isl_set *isl_set_upper_bound_si( + __isl_take isl_set *set, + enum isl_dim_type type, unsigned pos, int value); + __isl_give isl_set *isl_set_upper_bound_val( + __isl_take isl_set *set, + enum isl_dim_type type, unsigned pos, + __isl_take isl_val *value); + __isl_give isl_set *isl_set_lower_bound_multi_val( + __isl_take isl_set *set, + __isl_take isl_multi_val *lower); + __isl_give isl_set *isl_set_upper_bound_multi_val( + __isl_take isl_set *set, + __isl_take isl_multi_val *upper); + __isl_give isl_set *isl_set_lower_bound_multi_pw_aff( + __isl_take isl_set *set, + __isl_take isl_multi_pw_aff *lower); + __isl_give isl_set *isl_set_upper_bound_multi_pw_aff( + __isl_take isl_set *set, + __isl_take isl_multi_pw_aff *upper); + + #include + __isl_give isl_basic_map *isl_basic_map_lower_bound_si( + __isl_take isl_basic_map *bmap, + enum isl_dim_type type, unsigned pos, int value); + __isl_give isl_basic_map *isl_basic_map_upper_bound_si( + __isl_take isl_basic_map *bmap, + enum isl_dim_type type, unsigned pos, int value); + __isl_give isl_map *isl_map_lower_bound_si( + __isl_take isl_map *map, + enum isl_dim_type type, unsigned pos, int value); + __isl_give isl_map *isl_map_upper_bound_si( + __isl_take isl_map *map, + enum isl_dim_type type, unsigned pos, int value); + __isl_give isl_map *isl_map_lower_bound_val( + __isl_take isl_map *map, + enum isl_dim_type type, unsigned pos, + __isl_take isl_val *value); + __isl_give isl_map *isl_map_upper_bound_val( + __isl_take isl_map *map, + enum isl_dim_type type, unsigned pos, + __isl_take isl_val *value); + __isl_give isl_map *isl_map_lower_bound_multi_pw_aff( + __isl_take isl_map *map, + __isl_take isl_multi_pw_aff *lower); + __isl_give isl_map *isl_map_upper_bound_multi_pw_aff( + __isl_take isl_map *map, + __isl_take isl_multi_pw_aff *upper); + +Intersect the set or relation with the half-space where the given +dimension has a value bounded by the given fixed integer value or +symbolic constant expression. +For functions taking a multi expression, +this applies to all set dimensions. +Those that bound a map, bound the range of that map. +If the multi expression is zero-dimensional but has an explicit domain, +then the (parameter) domain of the set or map is intersected +with this explicit domain. + + __isl_give isl_set *isl_set_equate(__isl_take isl_set *set, + enum isl_dim_type type1, int pos1, + enum isl_dim_type type2, int pos2); + __isl_give isl_basic_map *isl_basic_map_equate( + __isl_take isl_basic_map *bmap, + enum isl_dim_type type1, int pos1, + enum isl_dim_type type2, int pos2); + __isl_give isl_map *isl_map_equate(__isl_take isl_map *map, + enum isl_dim_type type1, int pos1, + enum isl_dim_type type2, int pos2); + +Intersect the set or relation with the hyperplane where the given +dimensions are equal to each other. + + __isl_give isl_map *isl_map_oppose(__isl_take isl_map *map, + enum isl_dim_type type1, int pos1, + enum isl_dim_type type2, int pos2); + +Intersect the relation with the hyperplane where the given +dimensions have opposite values. + + __isl_give isl_map *isl_map_order_le( + __isl_take isl_map *map, + enum isl_dim_type type1, int pos1, + enum isl_dim_type type2, int pos2); + __isl_give isl_basic_map *isl_basic_map_order_ge( + __isl_take isl_basic_map *bmap, + enum isl_dim_type type1, int pos1, + enum isl_dim_type type2, int pos2); + __isl_give isl_map *isl_map_order_ge( + __isl_take isl_map *map, + enum isl_dim_type type1, int pos1, + enum isl_dim_type type2, int pos2); + __isl_give isl_map *isl_map_order_lt(__isl_take isl_map *map, + enum isl_dim_type type1, int pos1, + enum isl_dim_type type2, int pos2); + __isl_give isl_basic_map *isl_basic_map_order_gt( + __isl_take isl_basic_map *bmap, + enum isl_dim_type type1, int pos1, + enum isl_dim_type type2, int pos2); + __isl_give isl_map *isl_map_order_gt(__isl_take isl_map *map, + enum isl_dim_type type1, int pos1, + enum isl_dim_type type2, int pos2); + +Intersect the relation with the half-space where the given +dimensions satisfy the given ordering. + + #include + __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, 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. + +=item * Locus + + #include + __isl_give isl_basic_set *isl_aff_zero_basic_set( + __isl_take isl_aff *aff); + __isl_give isl_basic_set *isl_aff_neg_basic_set( + __isl_take isl_aff *aff); + __isl_give isl_set *isl_pw_aff_pos_set( + __isl_take isl_pw_aff *pa); + __isl_give isl_set *isl_pw_aff_nonneg_set( + __isl_take isl_pw_aff *pwaff); + __isl_give isl_set *isl_pw_aff_zero_set( + __isl_take isl_pw_aff *pwaff); + __isl_give isl_set *isl_pw_aff_non_zero_set( + __isl_take isl_pw_aff *pwaff); + __isl_give isl_union_set * + isl_union_pw_aff_zero_union_set( + __isl_take isl_union_pw_aff *upa); + __isl_give isl_union_set * + isl_multi_union_pw_aff_zero_union_set( + __isl_take isl_multi_union_pw_aff *mupa); + +The function C returns a basic set +containing those elements in the domain space +of C where C is negative. +The function C returns a set +containing those elements in the domain +of C where C is non-negative. +The function C +returns a union set containing those elements +in the domains of its elements where they are all zero. + +=item * Identity + + __isl_give isl_map *isl_set_identity( + __isl_take isl_set *set); + __isl_give isl_union_map *isl_union_set_identity( + __isl_take isl_union_set *uset); + __isl_give isl_union_pw_multi_aff * + isl_union_set_identity_union_pw_multi_aff( + __isl_take isl_union_set *uset); + +Construct an identity relation on the given (union) set. + +=item * Function Extraction + +A piecewise quasi affine expression that is equal to 1 on a set +and 0 outside the set can be created using the following function. + + #include + __isl_give isl_pw_aff *isl_set_indicator_function( + __isl_take isl_set *set); + +A piecewise multiple quasi affine expression can be extracted +from an C or C, provided the C is a singleton +and the C is single-valued. +In case of a conversion from an C +to an C, these properties need to hold +in each domain space. +A conversion to a C additionally +requires that the input is non-empty and involves only a single +range space. + + #include + __isl_give isl_pw_multi_aff *isl_set_as_pw_multi_aff( + __isl_take isl_set *set); + __isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_set( + __isl_take isl_set *set); + __isl_give isl_pw_multi_aff *isl_map_as_pw_multi_aff( + __isl_take isl_map *map); + __isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_map( + __isl_take isl_map *map); + + __isl_give isl_union_pw_multi_aff * + isl_union_pw_multi_aff_from_union_set( + __isl_take isl_union_set *uset); + __isl_give isl_union_pw_multi_aff * + isl_union_map_as_union_pw_multi_aff( + __isl_take isl_union_map *umap); + __isl_give isl_union_pw_multi_aff * + isl_union_pw_multi_aff_from_union_map( + __isl_take isl_union_map *umap); + + __isl_give isl_multi_union_pw_aff * + isl_union_map_as_multi_union_pw_aff( + __isl_take isl_union_map *umap); + __isl_give isl_multi_union_pw_aff * + isl_multi_union_pw_aff_from_union_map( + __isl_take isl_union_map *umap); + +C and C perform +the same operation. +Similarly for C and +C, +for C and +C and +for C and +C. + +=item * Deltas + + __isl_give isl_basic_set *isl_basic_map_deltas( + __isl_take isl_basic_map *bmap); + __isl_give isl_set *isl_map_deltas(__isl_take isl_map *map); + __isl_give isl_union_set *isl_union_map_deltas( + __isl_take isl_union_map *umap); + +These functions return a (basic) set containing the differences +between image elements and corresponding domain elements in the input. + + __isl_give isl_basic_map *isl_basic_map_deltas_map( + __isl_take isl_basic_map *bmap); + __isl_give isl_map *isl_map_deltas_map( + __isl_take isl_map *map); + __isl_give isl_union_map *isl_union_map_deltas_map( + __isl_take isl_union_map *umap); + +The functions above construct a (basic, regular or union) relation +that maps (a wrapped version of) the input relation to its delta set. + +=item * Translation + + #include + __isl_give isl_map *isl_set_translation( + __isl_take isl_set *deltas); + +This function performs essentially the opposite operation +of C. In particular, it returns pairs +of elements in the same space that have a difference in C. + +=item * Coalescing + +Simplify the representation of a set, relation or functions by trying +to combine pairs of basic sets or relations into a single +basic set or relation. + + #include + __isl_give isl_set *isl_set_coalesce(__isl_take isl_set *set); + + #include + __isl_give isl_map *isl_map_coalesce(__isl_take isl_map *map); + + #include + __isl_give isl_union_set *isl_union_set_coalesce( + __isl_take isl_union_set *uset); + + #include + __isl_give isl_union_map *isl_union_map_coalesce( + __isl_take isl_union_map *umap); + + #include + __isl_give isl_pw_aff *isl_pw_aff_coalesce( + __isl_take isl_pw_aff *pa); + __isl_give isl_pw_multi_aff *isl_pw_multi_aff_coalesce( + __isl_take isl_pw_multi_aff *pma); + __isl_give isl_multi_pw_aff *isl_multi_pw_aff_coalesce( + __isl_take isl_multi_pw_aff *mpa); + __isl_give isl_union_pw_aff *isl_union_pw_aff_coalesce( + __isl_take isl_union_pw_aff *upa); + __isl_give isl_union_pw_multi_aff * + isl_union_pw_multi_aff_coalesce( + __isl_take isl_union_pw_multi_aff *upma); + __isl_give isl_multi_union_pw_aff * + isl_multi_union_pw_aff_coalesce( + __isl_take isl_multi_union_pw_aff *mupa); + + #include + __isl_give isl_pw_qpolynomial_fold * + isl_pw_qpolynomial_fold_coalesce( + __isl_take isl_pw_qpolynomial_fold *pwf); + __isl_give isl_union_pw_qpolynomial * + isl_union_pw_qpolynomial_coalesce( + __isl_take isl_union_pw_qpolynomial *upwqp); + __isl_give isl_union_pw_qpolynomial_fold * + isl_union_pw_qpolynomial_fold_coalesce( + __isl_take isl_union_pw_qpolynomial_fold *upwf); + +One of the methods for combining pairs of basic sets or relations +can result in coefficients that are much larger than those that appear +in the constraints of the input. By default, the coefficients are +not allowed to grow larger, but this can be changed by unsetting +the following option. + + isl_stat isl_options_set_coalesce_bounded_wrapping( + isl_ctx *ctx, int val); + int isl_options_get_coalesce_bounded_wrapping( + isl_ctx *ctx); + +One of the other methods tries to combine pairs of basic sets +with different local variables, treating them as existentially +quantified variables even if they have known (but different) +integer division expressions. The result may then also have +existentially quantified variables. Turning on the following +option prevents this from happening. + + isl_stat isl_options_set_coalesce_preserve_locals( + isl_ctx *ctx, int val); + int isl_options_get_coalesce_preserve_locals(isl_ctx *ctx); + +=item * Detecting equalities + + __isl_give isl_basic_set *isl_basic_set_detect_equalities( + __isl_take isl_basic_set *bset); + __isl_give isl_basic_map *isl_basic_map_detect_equalities( + __isl_take isl_basic_map *bmap); + __isl_give isl_set *isl_set_detect_equalities( + __isl_take isl_set *set); + __isl_give isl_map *isl_map_detect_equalities( + __isl_take isl_map *map); + __isl_give isl_union_set *isl_union_set_detect_equalities( + __isl_take isl_union_set *uset); + __isl_give isl_union_map *isl_union_map_detect_equalities( + __isl_take isl_union_map *umap); + +Simplify the representation of a set or relation by detecting implicit +equalities. + +=item * Removing redundant constraints + + #include + __isl_give isl_basic_set *isl_basic_set_remove_redundancies( + __isl_take isl_basic_set *bset); + __isl_give isl_set *isl_set_remove_redundancies( + __isl_take isl_set *set); + + #include + __isl_give isl_union_set * + isl_union_set_remove_redundancies( + __isl_take isl_union_set *uset); + + #include + __isl_give isl_basic_map *isl_basic_map_remove_redundancies( + __isl_take isl_basic_map *bmap); + __isl_give isl_map *isl_map_remove_redundancies( + __isl_take isl_map *map); + + #include + __isl_give isl_union_map * + isl_union_map_remove_redundancies( + __isl_take isl_union_map *umap); + +=item * Convex hull + + __isl_give isl_basic_set *isl_set_convex_hull( + __isl_take isl_set *set); + __isl_give isl_basic_map *isl_map_convex_hull( + __isl_take isl_map *map); + +If the input set or relation has any existentially quantified +variables, then the result of these operations is currently undefined. + +=item * Simple hull + + #include + __isl_give isl_basic_set * + isl_set_unshifted_simple_hull( + __isl_take isl_set *set); + __isl_give isl_basic_set *isl_set_simple_hull( + __isl_take isl_set *set); + __isl_give isl_basic_set * + isl_set_plain_unshifted_simple_hull( + __isl_take isl_set *set); + __isl_give isl_basic_set * + isl_set_unshifted_simple_hull_from_set_list( + __isl_take isl_set *set, + __isl_take isl_set_list *list); + + #include + __isl_give isl_basic_map * + isl_map_unshifted_simple_hull( + __isl_take isl_map *map); + __isl_give isl_basic_map *isl_map_simple_hull( + __isl_take isl_map *map); + __isl_give isl_basic_map * + isl_map_plain_unshifted_simple_hull( + __isl_take isl_map *map); + __isl_give isl_basic_map * + isl_map_unshifted_simple_hull_from_map_list( + __isl_take isl_map *map, + __isl_take isl_map_list *list); + + #include + __isl_give isl_union_map *isl_union_map_simple_hull( + __isl_take isl_union_map *umap); + +These functions compute a single basic set or relation +that contains the whole input set or relation. +In particular, the output is described by translates +of the constraints describing the basic sets or relations in the input. +In case of C, only the original +constraints are used, without any translation. +In case of C and +C, the result is described +by original constraints that are obviously satisfied +by the entire input set or relation. +In case of C and +C, the +constraints are taken from the elements of the second argument. + +=begin latex + +(See \autoref{s:simple hull}.) + +=end latex + +=item * Affine hull + + __isl_give isl_basic_set *isl_basic_set_affine_hull( + __isl_take isl_basic_set *bset); + __isl_give isl_basic_set *isl_set_affine_hull( + __isl_take isl_set *set); + __isl_give isl_union_set *isl_union_set_affine_hull( + __isl_take isl_union_set *uset); + __isl_give isl_basic_map *isl_basic_map_affine_hull( + __isl_take isl_basic_map *bmap); + __isl_give isl_basic_map *isl_map_affine_hull( + __isl_take isl_map *map); + __isl_give isl_union_map *isl_union_map_affine_hull( + __isl_take isl_union_map *umap); + +In case of union sets and relations, the affine hull is computed +per space. + +=item * Polyhedral hull + + __isl_give isl_basic_set *isl_set_polyhedral_hull( + __isl_take isl_set *set); + __isl_give isl_basic_map *isl_map_polyhedral_hull( + __isl_take isl_map *map); + __isl_give isl_union_set *isl_union_set_polyhedral_hull( + __isl_take isl_union_set *uset); + __isl_give isl_union_map *isl_union_map_polyhedral_hull( + __isl_take isl_union_map *umap); + +These functions compute a single basic set or relation +not involving any existentially quantified variables +that contains the whole input set or relation. +In case of union sets and relations, the polyhedral hull is computed +per space. + +=item * Box hull + + #include + __isl_give isl_fixed_box * + isl_set_get_simple_fixed_box_hull( + __isl_keep isl_set *set) + + #include + __isl_give isl_fixed_box * + isl_map_get_range_simple_fixed_box_hull( + __isl_keep isl_map *map); + +These functions try to approximate the set or +the range of the map by a box of fixed size. +The box is described in terms of an offset living in the same space as +the input and a size living in the set or range space. For any element +in the input map, the range value is greater than or equal to +the offset applied to the domain value and the difference with +this offset is strictly smaller than the size. +The same holds for the elements of the input set, where +the offset is a parametric constant value. +If no fixed-size approximation can be found, +an I box is returned, i.e., one for which +C below returns false. + +The validity, the offset and the size of the box can be obtained using +the following functions. + + #include + isl_bool isl_fixed_box_is_valid( + __isl_keep isl_fixed_box *box); + __isl_give isl_multi_aff *isl_fixed_box_get_offset( + __isl_keep isl_fixed_box *box); + __isl_give isl_multi_val *isl_fixed_box_get_size( + __isl_keep isl_fixed_box *box); + +The box can be copied and freed using the following functions. + + #include + __isl_give isl_fixed_box *isl_fixed_box_copy( + __isl_keep isl_fixed_box *box); + __isl_null isl_fixed_box *isl_fixed_box_free( + __isl_take isl_fixed_box *box); + +An object of type C can be read from input +using the following function. + + #include + __isl_give isl_fixed_box * + isl_fixed_box_read_from_str(isl_ctx *ctx, + const char *str); + +A representation of the information contained in an object +of type C can be obtained using + + #include + __isl_give isl_printer *isl_printer_print_fixed_box( + __isl_take isl_printer *p, + __isl_keep isl_fixed_box *box); + __isl_give char *isl_fixed_box_to_str( + __isl_keep isl_fixed_box *box); + +C prints the information in flow format. + +=item * Other approximations + + #include + __isl_give isl_basic_set * + isl_basic_set_drop_constraints_involving_dims( + __isl_take isl_basic_set *bset, + enum isl_dim_type type, + unsigned first, unsigned n); + __isl_give isl_basic_set * + isl_basic_set_drop_constraints_not_involving_dims( + __isl_take isl_basic_set *bset, + enum isl_dim_type type, + unsigned first, unsigned n); + __isl_give isl_set * + isl_set_drop_constraints_involving_dims( + __isl_take isl_set *set, + enum isl_dim_type type, + unsigned first, unsigned n); + __isl_give isl_set * + isl_set_drop_constraints_not_involving_dims( + __isl_take isl_set *set, + enum isl_dim_type type, + unsigned first, unsigned n); + + #include + __isl_give isl_basic_map * + isl_basic_map_drop_constraints_involving_dims( + __isl_take isl_basic_map *bmap, + enum isl_dim_type type, + unsigned first, unsigned n); + __isl_give isl_basic_map * + isl_basic_map_drop_constraints_not_involving_dims( + __isl_take isl_basic_map *bmap, + enum isl_dim_type type, + unsigned first, unsigned n); + __isl_give isl_map * + isl_map_drop_constraints_involving_dims( + __isl_take isl_map *map, + enum isl_dim_type type, + unsigned first, unsigned n); + __isl_give isl_map * + isl_map_drop_constraints_not_involving_dims( + __isl_take isl_map *map, + enum isl_dim_type type, + unsigned first, unsigned n); + +These functions drop any constraints (not) involving the specified dimensions. +Note that the result depends on the representation of the input. + + #include + __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_to_polynomial( + __isl_take isl_pw_qpolynomial *pwqp, int sign); + __isl_give isl_union_pw_qpolynomial * + isl_union_pw_qpolynomial_to_polynomial( + __isl_take isl_union_pw_qpolynomial *upwqp, int sign); + +Approximate each quasipolynomial by a polynomial. If C is positive, +the polynomial will be an overapproximation. If C is negative, +it will be an underapproximation. If C is zero, the approximation +will lie somewhere in between. + +=item * Feasibility + + __isl_give isl_basic_set *isl_basic_set_sample( + __isl_take isl_basic_set *bset); + __isl_give isl_basic_set *isl_set_sample( + __isl_take isl_set *set); + __isl_give isl_basic_map *isl_basic_map_sample( + __isl_take isl_basic_map *bmap); + __isl_give isl_basic_map *isl_map_sample( + __isl_take isl_map *map); + +If the input (basic) set or relation is non-empty, then return +a singleton subset of the input. Otherwise, return an empty set. + +=item * Optimization + + #include + __isl_give isl_val *isl_basic_set_max_val( + __isl_keep isl_basic_set *bset, + __isl_keep isl_aff *obj); + __isl_give isl_val *isl_set_min_val( + __isl_keep isl_set *set, + __isl_keep isl_aff *obj); + __isl_give isl_val *isl_set_max_val( + __isl_keep isl_set *set, + __isl_keep isl_aff *obj); + __isl_give isl_multi_val * + isl_union_set_min_multi_union_pw_aff( + __isl_keep isl_union_set *uset, + __isl_keep isl_multi_union_pw_aff *obj); + +Compute the minimum or maximum of the integer affine expression C +over the points in C. +The result is C 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_give isl_val *isl_pw_aff_min_val( + __isl_take isl_pw_aff *pa); + __isl_give isl_val *isl_pw_aff_max_val( + __isl_take isl_pw_aff *pa); + __isl_give isl_multi_val * + isl_pw_multi_aff_min_multi_val( + __isl_take isl_pw_multi_aff *pma); + __isl_give isl_multi_val * + isl_pw_multi_aff_max_multi_val( + __isl_take isl_pw_multi_aff *pma); + __isl_give isl_multi_val * + isl_multi_pw_aff_min_multi_val( + __isl_take isl_multi_pw_aff *mpa); + __isl_give isl_multi_val * + isl_multi_pw_aff_max_multi_val( + __isl_take isl_multi_pw_aff *mpa); + __isl_give isl_val *isl_union_pw_aff_min_val( + __isl_take isl_union_pw_aff *upa); + __isl_give isl_val *isl_union_pw_aff_max_val( + __isl_take isl_union_pw_aff *upa); + __isl_give isl_multi_val * + isl_multi_union_pw_aff_min_multi_val( + __isl_take isl_multi_union_pw_aff *mupa); + __isl_give isl_multi_val * + isl_multi_union_pw_aff_max_multi_val( + __isl_take isl_multi_union_pw_aff *mupa); + +Compute the minimum or maximum of the integer affine expression +over its definition domain. +The result is C 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_give isl_val *isl_basic_set_dim_max_val( + __isl_take isl_basic_set *bset, int pos); + __isl_give isl_val *isl_set_dim_min_val( + __isl_take isl_set *set, int pos); + __isl_give isl_val *isl_set_dim_max_val( + __isl_take isl_set *set, int pos); + +Return the minimal or maximal value attained by the given set dimension, +independently of the parameter values and of any other dimensions. +The result is C in case of an error, the optimal value in case +there is one, (negative) 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( + __isl_take isl_set *set, int pos); + __isl_give isl_pw_aff *isl_set_dim_max( + __isl_take isl_set *set, int pos); + __isl_give isl_pw_aff *isl_map_dim_min( + __isl_take isl_map *map, int pos); + __isl_give isl_pw_aff *isl_map_dim_max( + __isl_take isl_map *map, int pos); + __isl_give isl_multi_pw_aff * + isl_set_min_multi_pw_aff( + __isl_take isl_set *set); + __isl_give isl_multi_pw_aff * + isl_set_max_multi_pw_aff( + __isl_take isl_set *set); + __isl_give isl_multi_pw_aff * + isl_map_min_multi_pw_aff( + __isl_take isl_map *map); + __isl_give isl_multi_pw_aff * + isl_map_max_multi_pw_aff( + __isl_take isl_map *map); + +Compute the minimum or maximum of the (given) set or output dimension(s) +as a function of the parameters (and input dimensions), but independently +of the other set or output dimensions. +For lexicographic optimization, see L<"Lexicographic Optimization">. + +=item * Dual + +The following functions compute either the set of (rational) coefficient +values of valid constraints for the given set or the set of (rational) +values satisfying the constraints with coefficients from the given set. +Internally, these two sets of functions perform essentially the +same operations, except that the set of coefficients is assumed to +be a cone, while the set of values may be any polyhedron. +The current implementation is based on the Farkas lemma and +Fourier-Motzkin elimination, but this may change or be made optional +in future. In particular, future implementations may use different +dualization algorithms or skip the elimination step. + + #include + __isl_give isl_basic_set *isl_basic_set_coefficients( + __isl_take isl_basic_set *bset); + __isl_give isl_basic_set_list * + isl_basic_set_list_coefficients( + __isl_take isl_basic_set_list *list); + __isl_give isl_basic_set *isl_set_coefficients( + __isl_take isl_set *set); + __isl_give isl_union_set *isl_union_set_coefficients( + __isl_take isl_union_set *bset); + __isl_give isl_basic_set *isl_basic_set_solutions( + __isl_take isl_basic_set *bset); + __isl_give isl_basic_set *isl_set_solutions( + __isl_take isl_set *set); + __isl_give isl_union_set *isl_union_set_solutions( + __isl_take isl_union_set *bset); + +=item * Power + + __isl_give isl_map *isl_map_fixed_power_val( + __isl_take isl_map *map, + __isl_take isl_val *exp); + __isl_give isl_union_map * + isl_union_map_fixed_power_val( + __isl_take isl_union_map *umap, + __isl_take isl_val *exp); + +Compute the given power of C, where C is assumed to be non-zero. +If the exponent C is negative, then the -C th power of the inverse +of C is computed. + + __isl_give isl_map *isl_map_power(__isl_take isl_map *map, + isl_bool *exact); + __isl_give isl_union_map *isl_union_map_power( + __isl_take isl_union_map *umap, isl_bool *exact); + +Compute a parametric representation for all positive powers I of C. +The result maps I to a nested relation corresponding to the +Ith power of C. +The result may be an overapproximation. If the result is known to be exact, +then C<*exact> is set to C<1>. + +=item * Transitive closure + + __isl_give isl_map *isl_map_transitive_closure( + __isl_take isl_map *map, isl_bool *exact); + __isl_give isl_union_map *isl_union_map_transitive_closure( + __isl_take isl_union_map *umap, isl_bool *exact); + +Compute the transitive closure of C. +The result may be an overapproximation. If the result is known to be exact, +then C<*exact> is set to C<1>. + +=item * Reaching path lengths + + __isl_give isl_map *isl_map_reaching_path_lengths( + __isl_take isl_map *map, isl_bool *exact); + +Compute a relation that maps each element in the range of C +to the lengths of all paths composed of edges in C that +end up in the given element. +The result may be an overapproximation. If the result is known to be exact, +then C<*exact> is set to C<1>. +To compute the I path length, the resulting relation +should be postprocessed by C. +In particular, if the input relation is a dependence relation +(mapping sources to sinks), then the maximal path length corresponds +to the free schedule. +Note, however, that C expects the maximum to be +finite, so if the path lengths are unbounded (possibly due to +the overapproximation), then you will get an error message. + +=item * Wrapping + + #include + __isl_give isl_space *isl_space_wrap( + __isl_take isl_space *space); + __isl_give isl_space *isl_space_unwrap( + __isl_take isl_space *space); + + #include + __isl_give isl_local_space *isl_local_space_wrap( + __isl_take isl_local_space *ls); + + #include + __isl_give isl_basic_map *isl_basic_set_unwrap( + __isl_take isl_basic_set *bset); + __isl_give isl_map *isl_set_unwrap( + __isl_take isl_set *set); + + #include + __isl_give isl_basic_set *isl_basic_map_wrap( + __isl_take isl_basic_map *bmap); + __isl_give isl_set *isl_map_wrap( + __isl_take isl_map *map); + + #include + __isl_give isl_union_map *isl_union_set_unwrap( + __isl_take isl_union_set *uset); + + #include + __isl_give isl_union_set *isl_union_map_wrap( + __isl_take isl_union_map *umap); + +The input to C should +be the space of a set, while that of +C should be the space of a relation. +Conversely, the output of C is the space +of a relation, while that of C is the space of a set. + +=item * Flattening + +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_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_give isl_local_space * + isl_local_space_flatten_domain( + __isl_take isl_local_space *ls); + __isl_give isl_local_space * + isl_local_space_flatten_range( + __isl_take isl_local_space *ls); + + #include + __isl_give isl_basic_set *isl_basic_set_flatten( + __isl_take isl_basic_set *bset); + __isl_give isl_set *isl_set_flatten( + __isl_take isl_set *set); + + #include + __isl_give isl_basic_map *isl_basic_map_flatten_domain( + __isl_take isl_basic_map *bmap); + __isl_give isl_basic_map *isl_basic_map_flatten_range( + __isl_take isl_basic_map *bmap); + __isl_give isl_map *isl_map_flatten_range( + __isl_take isl_map *map); + __isl_give isl_map *isl_map_flatten_domain( + __isl_take isl_map *map); + __isl_give isl_basic_map *isl_basic_map_flatten( + __isl_take isl_basic_map *bmap); + __isl_give isl_map *isl_map_flatten( + __isl_take isl_map *map); + + #include + __isl_give isl_multi_id *isl_multi_id_flatten_range( + __isl_take isl_multi_id *mi); + + #include + __isl_give isl_multi_val *isl_multi_val_flatten_range( + __isl_take isl_multi_val *mv); + + #include + __isl_give isl_multi_aff *isl_multi_aff_flatten_domain( + __isl_take isl_multi_aff *ma); + __isl_give isl_multi_aff *isl_multi_aff_flatten_range( + __isl_take isl_multi_aff *ma); + __isl_give isl_multi_pw_aff * + isl_multi_pw_aff_flatten_range( + __isl_take isl_multi_pw_aff *mpa); + __isl_give isl_multi_union_pw_aff * + isl_multi_union_pw_aff_flatten_range( + __isl_take isl_multi_union_pw_aff *mupa); + + #include + __isl_give isl_map *isl_set_flatten_map( + __isl_take isl_set *set); + +The function above constructs a relation +that maps the input set to a flattened version of the set. + +=item * Lifting + +Lift the input set to a space with extra dimensions corresponding +to the existentially quantified variables in the input. +In particular, the result lives in a wrapped map where the domain +is the original space and the range corresponds to the original +existentially quantified variables. + + #include + __isl_give isl_basic_set *isl_basic_set_lift( + __isl_take isl_basic_set *bset); + __isl_give isl_set *isl_set_lift( + __isl_take isl_set *set); + __isl_give isl_union_set *isl_union_set_lift( + __isl_take isl_union_set *uset); + +Given a local space that contains the existentially quantified +variables of a set, a basic relation that, when applied to +a basic set, has essentially the same effect as C, +can be constructed using the following function. + + #include + __isl_give isl_basic_map *isl_local_space_lifting( + __isl_take isl_local_space *ls); + + #include + __isl_give isl_multi_aff *isl_multi_aff_lift( + __isl_take isl_multi_aff *maff, + __isl_give isl_local_space **ls); + +If the C argument of C is not C, +then it is assigned the local space that lies at the basis of +the lifting applied. + +=item * Internal Product + + #include + __isl_give isl_space *isl_space_zip( + __isl_take isl_space *space); + + #include + __isl_give isl_basic_map *isl_basic_map_zip( + __isl_take isl_basic_map *bmap); + __isl_give isl_map *isl_map_zip( + __isl_take isl_map *map); + + #include + __isl_give isl_union_map *isl_union_map_zip( + __isl_take isl_union_map *umap); + +Given a relation with nested relations for domain and range, +interchange the range of the domain with the domain of the range. + +=item * Currying + + #include + __isl_give isl_space *isl_space_curry( + __isl_take isl_space *space); + __isl_give isl_space *isl_space_uncurry( + __isl_take isl_space *space); + + #include + __isl_give isl_basic_map *isl_basic_map_curry( + __isl_take isl_basic_map *bmap); + __isl_give isl_basic_map *isl_basic_map_uncurry( + __isl_take isl_basic_map *bmap); + __isl_give isl_map *isl_map_curry( + __isl_take isl_map *map); + __isl_give isl_map *isl_map_uncurry( + __isl_take isl_map *map); + + #include + __isl_give isl_union_map *isl_union_map_curry( + __isl_take isl_union_map *umap); + __isl_give isl_union_map *isl_union_map_uncurry( + __isl_take isl_union_map *umap); + +Given a relation with a nested relation for domain, +the C functions +move the range of the nested relation out of the domain +and use it as the domain of a nested relation in the range, +with the original range as range of this nested relation. +The C functions perform the inverse operation. + + #include + __isl_give isl_space *isl_space_range_curry( + __isl_take isl_space *space); + + #include + __isl_give isl_map *isl_map_range_curry( + __isl_take isl_map *map); + + #include + __isl_give isl_union_map *isl_union_map_range_curry( + __isl_take isl_union_map *umap); + +These functions apply the currying to the relation that +is nested inside the range of the input. + +=item * Aligning parameters + +Change the order of the parameters of the given set, relation +or function +such that the first parameters match those of C. +This may involve the introduction of extra parameters. +All parameters need to be named. + + #include + __isl_give isl_space *isl_space_align_params( + __isl_take isl_space *space1, + __isl_take isl_space *space2) + + #include + __isl_give isl_basic_set *isl_basic_set_align_params( + __isl_take isl_basic_set *bset, + __isl_take isl_space *model); + __isl_give isl_set *isl_set_align_params( + __isl_take isl_set *set, + __isl_take isl_space *model); + + #include + __isl_give isl_basic_map *isl_basic_map_align_params( + __isl_take isl_basic_map *bmap, + __isl_take isl_space *model); + __isl_give isl_map *isl_map_align_params( + __isl_take isl_map *map, + __isl_take isl_space *model); + + #include + __isl_give isl_multi_id *isl_multi_id_align_params( + __isl_take isl_multi_id *mi, + __isl_take isl_space *model); + + #include + __isl_give isl_multi_val *isl_multi_val_align_params( + __isl_take isl_multi_val *mv, + __isl_take isl_space *model); + + #include + __isl_give isl_aff *isl_aff_align_params( + __isl_take isl_aff *aff, + __isl_take isl_space *model); + __isl_give isl_multi_aff *isl_multi_aff_align_params( + __isl_take isl_multi_aff *multi, + __isl_take isl_space *model); + __isl_give isl_pw_aff *isl_pw_aff_align_params( + __isl_take isl_pw_aff *pwaff, + __isl_take isl_space *model); + __isl_give isl_pw_multi_aff *isl_pw_multi_aff_align_params( + __isl_take isl_pw_multi_aff *pma, + __isl_take isl_space *model); + __isl_give isl_union_pw_aff * + isl_union_pw_aff_align_params( + __isl_take isl_union_pw_aff *upa, + __isl_take isl_space *model); + __isl_give isl_union_pw_multi_aff * + isl_union_pw_multi_aff_align_params( + __isl_take isl_union_pw_multi_aff *upma, + __isl_take isl_space *model); + __isl_give isl_multi_union_pw_aff * + isl_multi_union_pw_aff_align_params( + __isl_take isl_multi_union_pw_aff *mupa, + __isl_take isl_space *model); + + #include + __isl_give isl_qpolynomial *isl_qpolynomial_align_params( + __isl_take isl_qpolynomial *qp, + __isl_take isl_space *model); + +=item * Drop unused parameters + +Drop parameters that are not referenced by the isl object. +All parameters need to be named. + + #include + __isl_give isl_basic_set * + isl_basic_set_drop_unused_params( + __isl_take isl_basic_set *bset); + __isl_give isl_set *isl_set_drop_unused_params( + __isl_take isl_set *set); + + #include + __isl_give isl_basic_map * + isl_basic_map_drop_unused_params( + __isl_take isl_basic_map *bmap); + __isl_give isl_map *isl_map_drop_unused_params( + __isl_take isl_map *map); + + #include + __isl_give isl_union_set * + isl_union_set_drop_unused_params( + __isl_take isl_union_set *uset); + + #include + __isl_give isl_union_map * + isl_union_map_drop_unused_params( + __isl_take isl_union_map *umap); + + #include + __isl_give isl_pw_aff *isl_pw_aff_drop_unused_params( + __isl_take isl_pw_aff *pa); + __isl_give isl_pw_multi_aff * + isl_pw_multi_aff_drop_unused_params( + __isl_take isl_pw_multi_aff *pma); + __isl_give isl_union_pw_aff * + isl_union_pw_aff_drop_unused_params( + __isl_take isl_union_pw_aff *upa); + __isl_give isl_union_pw_multi_aff * + isl_union_pw_multi_aff_drop_unused_params( + __isl_take isl_union_pw_multi_aff *upma); + + #include + __isl_give isl_pw_qpolynomial * + isl_pw_qpolynomial_drop_unused_params( + __isl_take isl_pw_qpolynomial *pwqp); + __isl_give isl_pw_qpolynomial_fold * + isl_pw_qpolynomial_fold_drop_unused_params( + __isl_take isl_pw_qpolynomial_fold *pwf); + __isl_give isl_union_pw_qpolynomial * + isl_union_pw_qpolynomial_drop_unused_params( + __isl_take isl_union_pw_qpolynomial *upwqp); + __isl_give isl_union_pw_qpolynomial_fold * + isl_union_pw_qpolynomial_fold_drop_unused_params( + __isl_take isl_union_pw_qpolynomial_fold *upwf); + +=item * Unary Arithmetic Operations + + #include + __isl_give isl_set *isl_set_neg( + __isl_take isl_set *set); + #include + __isl_give isl_map *isl_map_neg( + __isl_take isl_map *map); + +C constructs a set containing the opposites of +the elements in its argument. +The domain of the result of C is the same +as the domain of its argument. The corresponding range +elements are the opposites of the corresponding range +elements in the argument. + + #include + __isl_give isl_multi_val *isl_multi_val_neg( + __isl_take isl_multi_val *mv); + + #include + __isl_give isl_aff *isl_aff_neg( + __isl_take isl_aff *aff); + __isl_give isl_multi_aff *isl_multi_aff_neg( + __isl_take isl_multi_aff *ma); + __isl_give isl_pw_aff *isl_pw_aff_neg( + __isl_take isl_pw_aff *pwaff); + __isl_give isl_pw_multi_aff *isl_pw_multi_aff_neg( + __isl_take isl_pw_multi_aff *pma); + __isl_give isl_multi_pw_aff *isl_multi_pw_aff_neg( + __isl_take isl_multi_pw_aff *mpa); + __isl_give isl_union_pw_aff *isl_union_pw_aff_neg( + __isl_take isl_union_pw_aff *upa); + __isl_give isl_union_pw_multi_aff * + isl_union_pw_multi_aff_neg( + __isl_take isl_union_pw_multi_aff *upma); + __isl_give isl_multi_union_pw_aff * + isl_multi_union_pw_aff_neg( + __isl_take isl_multi_union_pw_aff *mupa); + __isl_give isl_aff *isl_aff_ceil( + __isl_take isl_aff *aff); + __isl_give isl_pw_aff *isl_pw_aff_ceil( + __isl_take isl_pw_aff *pwaff); + __isl_give isl_aff *isl_aff_floor( + __isl_take isl_aff *aff); + __isl_give isl_multi_aff *isl_multi_aff_floor( + __isl_take isl_multi_aff *ma); + __isl_give isl_pw_aff *isl_pw_aff_floor( + __isl_take isl_pw_aff *pwaff); + __isl_give isl_union_pw_aff *isl_union_pw_aff_floor( + __isl_take isl_union_pw_aff *upa); + __isl_give isl_multi_union_pw_aff * + isl_multi_union_pw_aff_floor( + __isl_take isl_multi_union_pw_aff *mupa); + + #include + __isl_give isl_pw_aff *isl_pw_aff_list_min( + __isl_take isl_pw_aff_list *list); + __isl_give isl_pw_aff *isl_pw_aff_list_max( + __isl_take isl_pw_aff_list *list); + + #include + __isl_give isl_qpolynomial *isl_qpolynomial_neg( + __isl_take isl_qpolynomial *qp); + __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_neg( + __isl_take isl_pw_qpolynomial *pwqp); + __isl_give isl_union_pw_qpolynomial * + isl_union_pw_qpolynomial_neg( + __isl_take isl_union_pw_qpolynomial *upwqp); + __isl_give isl_qpolynomial *isl_qpolynomial_pow( + __isl_take isl_qpolynomial *qp, + unsigned exponent); + __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_pow( + __isl_take isl_pw_qpolynomial *pwqp, + unsigned exponent); + +=item * Evaluation + +The following functions evaluate a function in a point. + + #include + __isl_give isl_val *isl_aff_eval( + __isl_take isl_aff *aff, + __isl_take isl_point *pnt); + __isl_give isl_val *isl_pw_aff_eval( + __isl_take isl_pw_aff *pa, + __isl_take isl_point *pnt); + + #include + __isl_give isl_val *isl_pw_qpolynomial_eval( + __isl_take isl_pw_qpolynomial *pwqp, + __isl_take isl_point *pnt); + __isl_give isl_val *isl_pw_qpolynomial_fold_eval( + __isl_take isl_pw_qpolynomial_fold *pwf, + __isl_take isl_point *pnt); + __isl_give isl_val *isl_union_pw_qpolynomial_eval( + __isl_take isl_union_pw_qpolynomial *upwqp, + __isl_take isl_point *pnt); + __isl_give isl_val *isl_union_pw_qpolynomial_fold_eval( + __isl_take isl_union_pw_qpolynomial_fold *upwf, + __isl_take isl_point *pnt); + +These functions return NaN when evaluated at a void point. +Note that C returns NaN when the function is evaluated outside +its definition domain, while C returns zero +when the function is evaluated outside its explicit domain. + +=item * Dimension manipulation + +It is usually not advisable to directly change the (input or output) +space of a set or a relation as this removes the name and the internal +structure of the space. However, the functions below can be useful +to add new parameters, assuming +C and C +are not sufficient. + + #include + __isl_give isl_space *isl_space_add_dims( + __isl_take isl_space *space, + enum isl_dim_type type, unsigned n); + __isl_give isl_space *isl_space_insert_dims( + __isl_take isl_space *space, + enum isl_dim_type type, unsigned pos, unsigned n); + __isl_give isl_space *isl_space_drop_dims( + __isl_take isl_space *space, + enum isl_dim_type type, unsigned first, unsigned n); + __isl_give isl_space *isl_space_move_dims( + __isl_take isl_space *space, + enum isl_dim_type dst_type, unsigned dst_pos, + enum isl_dim_type src_type, unsigned src_pos, + unsigned n); + + #include + __isl_give isl_local_space *isl_local_space_add_dims( + __isl_take isl_local_space *ls, + enum isl_dim_type type, unsigned n); + __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_drop_dims( + __isl_take isl_local_space *ls, + enum isl_dim_type type, unsigned first, unsigned n); + + #include + __isl_give isl_basic_set *isl_basic_set_add_dims( + __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_insert_dims( + __isl_take isl_basic_set *bset, + enum isl_dim_type type, unsigned pos, + unsigned n); + __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_move_dims( + __isl_take isl_basic_set *bset, + enum isl_dim_type dst_type, unsigned dst_pos, + enum isl_dim_type src_type, unsigned src_pos, + unsigned n); + __isl_give isl_set *isl_set_move_dims( + __isl_take isl_set *set, + enum isl_dim_type dst_type, unsigned dst_pos, + enum isl_dim_type src_type, unsigned src_pos, + unsigned n); + + #include + __isl_give isl_basic_map *isl_basic_map_add_dims( + __isl_take isl_basic_map *bmap, + enum isl_dim_type type, unsigned n); + __isl_give isl_map *isl_map_add_dims( + __isl_take isl_map *map, + enum isl_dim_type type, unsigned n); + __isl_give isl_basic_map *isl_basic_map_insert_dims( + __isl_take isl_basic_map *bmap, + enum isl_dim_type type, unsigned pos, + unsigned n); + __isl_give isl_map *isl_map_insert_dims( + __isl_take isl_map *map, + enum isl_dim_type type, unsigned pos, unsigned n); + __isl_give isl_basic_map *isl_basic_map_move_dims( + __isl_take isl_basic_map *bmap, + enum isl_dim_type dst_type, unsigned dst_pos, + enum isl_dim_type src_type, unsigned src_pos, + unsigned n); + __isl_give isl_map *isl_map_move_dims( + __isl_take isl_map *map, + enum isl_dim_type dst_type, unsigned dst_pos, + enum isl_dim_type src_type, unsigned src_pos, + unsigned n); + + #include + __isl_give isl_multi_val *isl_multi_val_insert_dims( + __isl_take isl_multi_val *mv, + enum isl_dim_type type, unsigned first, unsigned n); + __isl_give isl_multi_val *isl_multi_val_add_dims( + __isl_take isl_multi_val *mv, + enum isl_dim_type type, unsigned n); + __isl_give isl_multi_val *isl_multi_val_drop_dims( + __isl_take isl_multi_val *mv, + enum isl_dim_type type, unsigned first, unsigned n); + + #include + __isl_give isl_aff *isl_aff_insert_dims( + __isl_take isl_aff *aff, + enum isl_dim_type type, unsigned first, unsigned n); + __isl_give isl_multi_aff *isl_multi_aff_insert_dims( + __isl_take isl_multi_aff *ma, + enum isl_dim_type type, unsigned first, unsigned n); + __isl_give isl_pw_aff *isl_pw_aff_insert_dims( + __isl_take isl_pw_aff *pwaff, + enum isl_dim_type type, unsigned first, unsigned n); + __isl_give isl_multi_pw_aff *isl_multi_pw_aff_insert_dims( + __isl_take isl_multi_pw_aff *mpa, + enum isl_dim_type type, unsigned first, unsigned n); + __isl_give isl_aff *isl_aff_add_dims( + __isl_take isl_aff *aff, + enum isl_dim_type type, unsigned n); + __isl_give isl_multi_aff *isl_multi_aff_add_dims( + __isl_take isl_multi_aff *ma, + enum isl_dim_type type, unsigned n); + __isl_give isl_pw_aff *isl_pw_aff_add_dims( + __isl_take isl_pw_aff *pwaff, + enum isl_dim_type type, unsigned n); + __isl_give isl_multi_pw_aff *isl_multi_pw_aff_add_dims( + __isl_take isl_multi_pw_aff *mpa, + enum isl_dim_type type, unsigned n); + __isl_give isl_aff *isl_aff_drop_dims( + __isl_take isl_aff *aff, + enum isl_dim_type type, unsigned first, unsigned n); + __isl_give isl_multi_aff *isl_multi_aff_drop_dims( + __isl_take isl_multi_aff *maff, + enum isl_dim_type type, unsigned first, unsigned n); + __isl_give isl_pw_aff *isl_pw_aff_drop_dims( + __isl_take isl_pw_aff *pwaff, + enum isl_dim_type type, unsigned first, unsigned n); + __isl_give isl_pw_multi_aff *isl_pw_multi_aff_drop_dims( + __isl_take isl_pw_multi_aff *pma, + enum isl_dim_type type, unsigned first, unsigned n); + __isl_give isl_union_pw_aff *isl_union_pw_aff_drop_dims( + __isl_take isl_union_pw_aff *upa, + enum isl_dim_type type, unsigned first, unsigned n); + __isl_give isl_union_pw_multi_aff * + isl_union_pw_multi_aff_drop_dims( + __isl_take isl_union_pw_multi_aff *upma, + enum isl_dim_type type, + unsigned first, unsigned n); + __isl_give isl_multi_union_pw_aff * + isl_multi_union_pw_aff_drop_dims( + __isl_take isl_multi_union_pw_aff *mupa, + enum isl_dim_type type, unsigned first, + unsigned n); + __isl_give isl_aff *isl_aff_move_dims( + __isl_take isl_aff *aff, + enum isl_dim_type dst_type, unsigned dst_pos, + enum isl_dim_type src_type, unsigned src_pos, + unsigned n); + __isl_give isl_multi_aff *isl_multi_aff_move_dims( + __isl_take isl_multi_aff *ma, + enum isl_dim_type dst_type, unsigned dst_pos, + enum isl_dim_type src_type, unsigned src_pos, + unsigned n); + __isl_give isl_pw_aff *isl_pw_aff_move_dims( + __isl_take isl_pw_aff *pa, + enum isl_dim_type dst_type, unsigned dst_pos, + enum isl_dim_type src_type, unsigned src_pos, + unsigned n); + __isl_give isl_multi_pw_aff *isl_multi_pw_aff_move_dims( + __isl_take isl_multi_pw_aff *pma, + enum isl_dim_type dst_type, unsigned dst_pos, + enum isl_dim_type src_type, unsigned src_pos, + unsigned n); + + #include + __isl_give isl_union_pw_qpolynomial * + isl_union_pw_qpolynomial_drop_dims( + __isl_take isl_union_pw_qpolynomial *upwqp, + enum isl_dim_type type, + unsigned first, unsigned n); + __isl_give isl_union_pw_qpolynomial_fold * + isl_union_pw_qpolynomial_fold_drop_dims( + __isl_take isl_union_pw_qpolynomial_fold *upwf, + enum isl_dim_type type, + unsigned first, unsigned n); + +The operations on union expressions can only manipulate parameters. + +=back + +=head2 Binary Operations + +The two arguments of a binary operation not only need to live +in the same C, they currently also need to have +the same (number of) parameters. + +=head3 Basic Operations + +=over + +=item * Intersection + + #include + __isl_give isl_local_space *isl_local_space_intersect( + __isl_take isl_local_space *ls1, + __isl_take isl_local_space *ls2); + + #include + __isl_give isl_basic_set *isl_basic_set_intersect_params( + __isl_take isl_basic_set *bset1, + __isl_take isl_basic_set *bset2); + __isl_give isl_basic_set *isl_basic_set_intersect( + __isl_take isl_basic_set *bset1, + __isl_take isl_basic_set *bset2); + __isl_give isl_basic_set *isl_basic_set_list_intersect( + __isl_take struct isl_basic_set_list *list); + __isl_give isl_set *isl_set_intersect_params( + __isl_take isl_set *set, + __isl_take isl_set *params); + __isl_give isl_set *isl_set_intersect( + __isl_take isl_set *set1, + __isl_take isl_set *set2); + __isl_give isl_set *isl_set_intersect_factor_domain( + __isl_take isl_set *set, + __isl_take isl_set *domain); + __isl_give isl_set *isl_set_intersect_factor_range( + __isl_take isl_set *set, + __isl_take isl_set *range); + + #include + __isl_give isl_basic_map *isl_basic_map_intersect_domain( + __isl_take isl_basic_map *bmap, + __isl_take isl_basic_set *bset); + __isl_give isl_basic_map *isl_basic_map_intersect_range( + __isl_take isl_basic_map *bmap, + __isl_take isl_basic_set *bset); + __isl_give isl_basic_map *isl_basic_map_intersect( + __isl_take isl_basic_map *bmap1, + __isl_take isl_basic_map *bmap2); + __isl_give isl_basic_map *isl_basic_map_list_intersect( + __isl_take isl_basic_map_list *list); + __isl_give isl_map *isl_map_intersect_params( + __isl_take isl_map *map, + __isl_take isl_set *params); + __isl_give isl_map *isl_map_intersect_domain( + __isl_take isl_map *map, + __isl_take isl_set *set); + __isl_give isl_map *isl_map_intersect_range( + __isl_take isl_map *map, + __isl_take isl_set *set); + __isl_give isl_map *isl_map_intersect( + __isl_take isl_map *map1, + __isl_take isl_map *map2); + __isl_give isl_map * + isl_map_intersect_domain_factor_domain( + __isl_take isl_map *map, + __isl_take isl_map *factor); + __isl_give isl_map * + isl_map_intersect_domain_factor_range( + __isl_take isl_map *map, + __isl_take isl_map *factor); + __isl_give isl_map * + isl_map_intersect_range_factor_domain( + __isl_take isl_map *map, + __isl_take isl_map *factor); + __isl_give isl_map * + isl_map_intersect_range_factor_range( + __isl_take isl_map *map, + __isl_take isl_map *factor); + __isl_give isl_map * + isl_map_intersect_domain_wrapped_domain( + __isl_take isl_map *map, + __isl_take isl_set *domain); + __isl_give isl_map * + isl_map_intersect_range_wrapped_domain( + __isl_take isl_map *map, + __isl_take isl_set *domain); + + #include + __isl_give isl_union_set *isl_union_set_intersect_params( + __isl_take isl_union_set *uset, + __isl_take isl_set *set); + __isl_give isl_union_set *isl_union_set_intersect( + __isl_take isl_union_set *uset1, + __isl_take isl_union_set *uset2); + + #include + __isl_give isl_union_map *isl_union_map_intersect_params( + __isl_take isl_union_map *umap, + __isl_take isl_set *set); + __isl_give isl_union_map * + isl_union_map_intersect_domain_union_set( + __isl_take isl_union_map *umap, + __isl_take isl_union_set *uset); + __isl_give isl_union_map * + isl_union_map_intersect_domain_space( + __isl_take isl_union_map *umap, + __isl_take isl_space *space); + __isl_give isl_union_map *isl_union_map_intersect_domain( + __isl_take isl_union_map *umap, + __isl_take isl_union_set *uset); + __isl_give isl_union_map * + isl_union_map_intersect_range_union_set( + __isl_take isl_union_map *umap, + __isl_take isl_union_set *uset); + __isl_give isl_union_map * + isl_union_map_intersect_range_space( + __isl_take isl_union_map *umap, + __isl_take isl_space *space); + __isl_give isl_union_map *isl_union_map_intersect_range( + __isl_take isl_union_map *umap, + __isl_take isl_union_set *uset); + __isl_give isl_union_map *isl_union_map_intersect( + __isl_take isl_union_map *umap1, + __isl_take isl_union_map *umap2); + __isl_give isl_union_map * + isl_union_map_intersect_domain_factor_domain( + __isl_take isl_union_map *umap, + __isl_take isl_union_map *factor); + __isl_give isl_union_map * + isl_union_map_intersect_domain_factor_range( + __isl_take isl_union_map *umap, + __isl_take isl_union_map *factor); + __isl_give isl_union_map * + isl_union_map_intersect_range_factor_domain( + __isl_take isl_union_map *umap, + __isl_take isl_union_map *factor); + __isl_give isl_union_map * + isl_union_map_intersect_range_factor_range( + __isl_take isl_union_map *umap, + __isl_take isl_union_map *factor); + __isl_give isl_union_map * + isl_union_map_intersect_domain_wrapped_domain_union_set( + __isl_take isl_union_map *umap, + __isl_take isl_union_set *domain); + __isl_give isl_union_map * + isl_union_map_intersect_range_wrapped_domain_union_set( + __isl_take isl_union_map *umap, + __isl_take isl_union_set *domain); + + #include + __isl_give isl_pw_aff *isl_pw_aff_intersect_domain( + __isl_take isl_pw_aff *pa, + __isl_take isl_set *set); + __isl_give isl_multi_pw_aff * + isl_multi_pw_aff_intersect_domain( + __isl_take isl_multi_pw_aff *mpa, + __isl_take isl_set *domain); + __isl_give isl_pw_multi_aff *isl_pw_multi_aff_intersect_domain( + __isl_take isl_pw_multi_aff *pma, + __isl_take isl_set *set); + __isl_give isl_union_pw_aff * + isl_union_pw_aff_intersect_domain_space( + __isl_take isl_union_pw_aff *upa, + __isl_take isl_space *space); + __isl_give isl_union_pw_aff * + isl_union_pw_aff_intersect_domain_union_set( + __isl_take isl_union_pw_aff *upa, + __isl_take isl_union_set *uset); + __isl_give isl_union_pw_aff *isl_union_pw_aff_intersect_domain( + __isl_take isl_union_pw_aff *upa, + __isl_take isl_union_set *uset); + __isl_give isl_union_pw_multi_aff * + isl_union_pw_multi_aff_intersect_domain_space( + __isl_take isl_union_pw_multi_aff *upma, + __isl_take isl_space *space); + __isl_give isl_union_pw_multi_aff * + isl_union_pw_multi_aff_intersect_domain_union_set( + __isl_take isl_union_pw_multi_aff *upma, + __isl_take isl_union_set *uset); + __isl_give isl_union_pw_multi_aff * + isl_union_pw_multi_aff_intersect_domain( + __isl_take isl_union_pw_multi_aff *upma, + __isl_take isl_union_set *uset); + __isl_give isl_multi_union_pw_aff * + isl_multi_union_pw_aff_intersect_domain( + __isl_take isl_multi_union_pw_aff *mupa, + __isl_take isl_union_set *uset); + __isl_give isl_pw_aff * + isl_pw_aff_intersect_domain_wrapped_domain( + __isl_take isl_pw_aff *pa, + __isl_take isl_set *set); + __isl_give isl_pw_multi_aff * + isl_pw_multi_aff_intersect_domain_wrapped_domain( + __isl_take isl_pw_multi_aff *pma, + __isl_take isl_set *set); + __isl_give isl_union_pw_aff * + isl_union_pw_aff_intersect_domain_wrapped_domain( + __isl_take isl_union_pw_aff *upa, + __isl_take isl_union_set *uset); + __isl_give isl_union_pw_multi_aff * + isl_union_pw_multi_aff_intersect_domain_wrapped_domain( + __isl_take isl_union_pw_multi_aff *upma, + __isl_take isl_union_set *uset); + __isl_give isl_pw_aff * + isl_pw_aff_intersect_domain_wrapped_range( + __isl_take isl_pw_aff *pa, + __isl_take isl_set *set); + __isl_give isl_pw_multi_aff * + isl_pw_multi_aff_intersect_domain_wrapped_range( + __isl_take isl_pw_multi_aff *pma, + __isl_take isl_set *set); + __isl_give isl_union_pw_multi_aff * + isl_union_pw_multi_aff_intersect_domain_wrapped_range( + __isl_take isl_union_pw_multi_aff *upma, + __isl_take isl_union_set *uset); + __isl_give isl_union_pw_aff * + isl_union_pw_aff_intersect_domain_wrapped_range( + __isl_take isl_union_pw_aff *upa, + __isl_take isl_union_set *uset); + __isl_give isl_pw_aff *isl_pw_aff_intersect_params( + __isl_take isl_pw_aff *pa, + __isl_take isl_set *set); + __isl_give isl_multi_pw_aff * + isl_multi_pw_aff_intersect_params( + __isl_take isl_multi_pw_aff *mpa, + __isl_take isl_set *set); + __isl_give isl_pw_multi_aff *isl_pw_multi_aff_intersect_params( + __isl_take isl_pw_multi_aff *pma, + __isl_take isl_set *set); + __isl_give isl_union_pw_aff * + isl_union_pw_aff_intersect_params( + __isl_take isl_union_pw_aff *upa, + __isl_take isl_set *set); + __isl_give isl_union_pw_multi_aff * + isl_union_pw_multi_aff_intersect_params( + __isl_take isl_union_pw_multi_aff *upma, + __isl_take isl_set *set); + __isl_give isl_multi_union_pw_aff * + isl_multi_union_pw_aff_intersect_params( + __isl_take isl_multi_union_pw_aff *mupa, + __isl_take isl_set *params); + __isl_give isl_multi_union_pw_aff * + isl_multi_union_pw_aff_intersect_range( + __isl_take isl_multi_union_pw_aff *mupa, + __isl_take isl_set *set); + + #include + __isl_give isl_pw_qpolynomial * + isl_pw_qpolynomial_intersect_domain( + __isl_take isl_pw_qpolynomial *pwpq, + __isl_take isl_set *set); + __isl_give isl_union_pw_qpolynomial * + isl_union_pw_qpolynomial_intersect_domain_space( + __isl_take isl_union_pw_qpolynomial *upwpq, + __isl_take isl_space *space); + __isl_give isl_union_pw_qpolynomial * + isl_union_pw_qpolynomial_intersect_domain_union_set( + __isl_take isl_union_pw_qpolynomial *upwpq, + __isl_take isl_union_set *uset); + __isl_give isl_union_pw_qpolynomial * + isl_union_pw_qpolynomial_intersect_domain( + __isl_take isl_union_pw_qpolynomial *upwpq, + __isl_take isl_union_set *uset); + __isl_give isl_union_pw_qpolynomial_fold * + isl_union_pw_qpolynomial_fold_intersect_domain_space( + __isl_take isl_union_pw_qpolynomial_fold *upwf, + __isl_take isl_space *space); + __isl_give isl_union_pw_qpolynomial_fold * + isl_union_pw_qpolynomial_fold_intersect_domain_union_set( + __isl_take isl_union_pw_qpolynomial_fold *upwf, + __isl_take isl_union_set *uset); + __isl_give isl_union_pw_qpolynomial_fold * + isl_union_pw_qpolynomial_fold_intersect_domain( + __isl_take isl_union_pw_qpolynomial_fold *upwf, + __isl_take isl_union_set *uset); + __isl_give isl_pw_qpolynomial * + isl_pw_qpolynomial_intersect_domain_wrapped_domain( + __isl_take isl_pw_qpolynomial *pwpq, + __isl_take isl_set *set); + __isl_give isl_pw_qpolynomial_fold * + isl_pw_qpolynomial_fold_intersect_domain_wrapped_domain( + __isl_take isl_pw_qpolynomial_fold *pwf, + __isl_take isl_set *set); + __isl_give isl_union_pw_qpolynomial * + isl_union_pw_qpolynomial_intersect_domain_wrapped_domain( + __isl_take isl_union_pw_qpolynomial *upwpq, + __isl_take isl_union_set *uset); + __isl_give isl_union_pw_qpolynomial_fold * + isl_union_pw_qpolynomial_fold_intersect_domain_wrapped_domain( + __isl_take isl_union_pw_qpolynomial_fold *upwf, + __isl_take isl_union_set *uset); + __isl_give isl_pw_qpolynomial * + isl_pw_qpolynomial_intersect_domain_wrapped_range( + __isl_take isl_pw_qpolynomial *pwpq, + __isl_take isl_set *set); + __isl_give isl_pw_qpolynomial_fold * + isl_pw_qpolynomial_fold_intersect_domain_wrapped_range( + __isl_take isl_pw_qpolynomial_fold *pwf, + __isl_take isl_set *set); + __isl_give isl_union_pw_qpolynomial * + isl_union_pw_qpolynomial_intersect_domain_wrapped_range( + __isl_take isl_union_pw_qpolynomial *upwpq, + __isl_take isl_union_set *uset); + __isl_give isl_union_pw_qpolynomial_fold * + isl_union_pw_qpolynomial_fold_intersect_domain_wrapped_range( + __isl_take isl_union_pw_qpolynomial_fold *upwf, + __isl_take isl_union_set *uset); + __isl_give isl_pw_qpolynomial * + isl_pw_qpolynomial_intersect_params( + __isl_take isl_pw_qpolynomial *pwpq, + __isl_take isl_set *set); + __isl_give isl_pw_qpolynomial_fold * + isl_pw_qpolynomial_fold_intersect_params( + __isl_take isl_pw_qpolynomial_fold *pwf, + __isl_take isl_set *set); + __isl_give isl_union_pw_qpolynomial * + isl_union_pw_qpolynomial_intersect_params( + __isl_take isl_union_pw_qpolynomial *upwpq, + __isl_take isl_set *set); + __isl_give isl_union_pw_qpolynomial_fold * + isl_union_pw_qpolynomial_fold_intersect_params( + __isl_take isl_union_pw_qpolynomial_fold *upwf, + __isl_take isl_set *set); + +The second argument to the C<_params> functions needs to be +a parametric (basic) set. For the other functions, a parametric set +for either argument is only allowed if the other argument is +a parametric set as well. +The list passed to C needs to have +at least one element and all elements need to live in the same space. +The function C +restricts the input function to those shared domain elements +that map to the specified range. +C is an alternative name for +C. +Similarly for the other pairs of functions. + +=item * Union + + #include + __isl_give isl_set *isl_basic_set_union( + __isl_take isl_basic_set *bset1, + __isl_take isl_basic_set *bset2); + __isl_give isl_set *isl_set_union( + __isl_take isl_set *set1, + __isl_take isl_set *set2); + __isl_give isl_set *isl_set_list_union( + __isl_take isl_set_list *list); + + #include + __isl_give isl_map *isl_basic_map_union( + __isl_take isl_basic_map *bmap1, + __isl_take isl_basic_map *bmap2); + __isl_give isl_map *isl_map_union( + __isl_take isl_map *map1, + __isl_take isl_map *map2); + + #include + __isl_give isl_union_set *isl_union_set_union( + __isl_take isl_union_set *uset1, + __isl_take isl_union_set *uset2); + __isl_give isl_union_set *isl_union_set_list_union( + __isl_take isl_union_set_list *list); + + #include + __isl_give isl_union_map *isl_union_map_union( + __isl_take isl_union_map *umap1, + __isl_take isl_union_map *umap2); + +The list passed to C needs to have +at least one element and all elements need to live in the same space. + +=item * Set difference + + #include + __isl_give isl_set *isl_set_subtract( + __isl_take isl_set *set1, + __isl_take isl_set *set2); + + #include + __isl_give isl_map *isl_map_subtract( + __isl_take isl_map *map1, + __isl_take isl_map *map2); + __isl_give isl_map *isl_map_subtract_domain( + __isl_take isl_map *map, + __isl_take isl_set *dom); + __isl_give isl_map *isl_map_subtract_range( + __isl_take isl_map *map, + __isl_take isl_set *dom); + + #include + __isl_give isl_union_set *isl_union_set_subtract( + __isl_take isl_union_set *uset1, + __isl_take isl_union_set *uset2); + + #include + __isl_give isl_union_map *isl_union_map_subtract( + __isl_take isl_union_map *umap1, + __isl_take isl_union_map *umap2); + __isl_give isl_union_map *isl_union_map_subtract_domain( + __isl_take isl_union_map *umap, + __isl_take isl_union_set *dom); + __isl_give isl_union_map *isl_union_map_subtract_range( + __isl_take isl_union_map *umap, + __isl_take isl_union_set *dom); + + #include + __isl_give isl_pw_aff *isl_pw_aff_subtract_domain( + __isl_take isl_pw_aff *pa, + __isl_take isl_set *set); + __isl_give isl_pw_multi_aff * + isl_pw_multi_aff_subtract_domain( + __isl_take isl_pw_multi_aff *pma, + __isl_take isl_set *set); + __isl_give isl_union_pw_aff * + isl_union_pw_aff_subtract_domain_union_set( + __isl_take isl_union_pw_aff *upa, + __isl_take isl_union_set *uset); + __isl_give isl_union_pw_aff * + isl_union_pw_aff_subtract_domain_space( + __isl_take isl_union_pw_aff *upa, + __isl_take isl_space *space); + __isl_give isl_union_pw_aff * + isl_union_pw_aff_subtract_domain( + __isl_take isl_union_pw_aff *upa, + __isl_take isl_union_set *uset); + __isl_give isl_union_pw_multi_aff * + isl_union_pw_multi_aff_subtract_domain_union_set( + __isl_take isl_union_pw_multi_aff *upma, + __isl_take isl_set *set); + __isl_give isl_union_pw_multi_aff * + isl_union_pw_multi_aff_subtract_domain_space( + __isl_take isl_union_pw_multi_aff *upma, + __isl_take isl_space *space); + __isl_give isl_union_pw_multi_aff * + isl_union_pw_multi_aff_subtract_domain( + __isl_take isl_union_pw_multi_aff *upma, + __isl_take isl_union_set *uset); + + #include + __isl_give isl_pw_qpolynomial * + isl_pw_qpolynomial_subtract_domain( + __isl_take isl_pw_qpolynomial *pwpq, + __isl_take isl_set *set); + __isl_give isl_pw_qpolynomial_fold * + isl_pw_qpolynomial_fold_subtract_domain( + __isl_take isl_pw_qpolynomial_fold *pwf, + __isl_take isl_set *set); + __isl_give isl_union_pw_qpolynomial * + isl_union_pw_qpolynomial_subtract_domain_union_set( + __isl_take isl_union_pw_qpolynomial *upwpq, + __isl_take isl_union_set *uset); + __isl_give isl_union_pw_qpolynomial * + isl_union_pw_qpolynomial_subtract_domain_space( + __isl_take isl_union_pw_qpolynomial *upwpq, + __isl_take isl_space *space); + __isl_give isl_union_pw_qpolynomial * + isl_union_pw_qpolynomial_subtract_domain( + __isl_take isl_union_pw_qpolynomial *upwpq, + __isl_take isl_union_set *uset); + __isl_give isl_union_pw_qpolynomial_fold * + isl_union_pw_qpolynomial_fold_subtract_domain_union_set( + __isl_take isl_union_pw_qpolynomial_fold *upwf, + __isl_take isl_union_set *uset); + __isl_give isl_union_pw_qpolynomial_fold * + isl_union_pw_qpolynomial_fold_subtract_domain_space( + __isl_take isl_union_pw_qpolynomial_fold *upwf, + __isl_take isl_space *space); + __isl_give isl_union_pw_qpolynomial_fold * + isl_union_pw_qpolynomial_fold_subtract_domain( + __isl_take isl_union_pw_qpolynomial_fold *upwf, + __isl_take isl_union_set *uset); + +C is an alternative name for +C. +Similarly for the other pairs of functions. + +=item * Application + + #include + __isl_give isl_space *isl_space_join( + __isl_take isl_space *left, + __isl_take isl_space *right); + + #include + __isl_give isl_basic_set *isl_basic_set_apply( + __isl_take isl_basic_set *bset, + __isl_take isl_basic_map *bmap); + __isl_give isl_set *isl_set_apply( + __isl_take isl_set *set, + __isl_take isl_map *map); + + #include + __isl_give isl_union_set *isl_union_set_apply( + __isl_take isl_union_set *uset, + __isl_take isl_union_map *umap); + + #include + __isl_give isl_basic_map *isl_basic_map_apply_domain( + __isl_take isl_basic_map *bmap1, + __isl_take isl_basic_map *bmap2); + __isl_give isl_basic_map *isl_basic_map_apply_range( + __isl_take isl_basic_map *bmap1, + __isl_take isl_basic_map *bmap2); + __isl_give isl_map *isl_map_apply_domain( + __isl_take isl_map *map1, + __isl_take isl_map *map2); + __isl_give isl_map *isl_map_apply_range( + __isl_take isl_map *map1, + __isl_take isl_map *map2); + + #include + __isl_give isl_union_map *isl_union_map_apply_domain( + __isl_take isl_union_map *umap1, + __isl_take isl_union_map *umap2); + __isl_give isl_union_map *isl_union_map_apply_range( + __isl_take isl_union_map *umap1, + __isl_take isl_union_map *umap2); + + #include + __isl_give isl_union_pw_multi_aff * + isl_union_pw_multi_aff_apply_union_pw_multi_aff( + __isl_take isl_union_pw_multi_aff *upma1, + __isl_take isl_union_pw_multi_aff *upma2); + __isl_give isl_union_pw_aff * + isl_multi_union_pw_aff_apply_aff( + __isl_take isl_multi_union_pw_aff *mupa, + __isl_take isl_aff *aff); + __isl_give isl_union_pw_aff * + isl_multi_union_pw_aff_apply_pw_aff( + __isl_take isl_multi_union_pw_aff *mupa, + __isl_take isl_pw_aff *pa); + __isl_give isl_multi_union_pw_aff * + isl_multi_union_pw_aff_apply_multi_aff( + __isl_take isl_multi_union_pw_aff *mupa, + __isl_take isl_multi_aff *ma); + __isl_give isl_multi_union_pw_aff * + isl_multi_union_pw_aff_apply_pw_multi_aff( + __isl_take isl_multi_union_pw_aff *mupa, + __isl_take isl_pw_multi_aff *pma); + +The result of C is defined +over the shared domain of the elements of the input. The dimension is +required to be greater than zero. +The C argument of +C is allowed to be zero-dimensional, +but only if the range of the C argument +is also zero-dimensional. +Similarly for C. + + #include + __isl_give isl_pw_qpolynomial_fold * + isl_set_apply_pw_qpolynomial_fold( + __isl_take isl_set *set, + __isl_take isl_pw_qpolynomial_fold *pwf, + isl_bool *tight); + __isl_give isl_pw_qpolynomial_fold * + isl_map_apply_pw_qpolynomial_fold( + __isl_take isl_map *map, + __isl_take isl_pw_qpolynomial_fold *pwf, + isl_bool *tight); + __isl_give isl_union_pw_qpolynomial_fold * + isl_union_set_apply_union_pw_qpolynomial_fold( + __isl_take isl_union_set *uset, + __isl_take isl_union_pw_qpolynomial_fold *upwf, + isl_bool *tight); + __isl_give isl_union_pw_qpolynomial_fold * + isl_union_map_apply_union_pw_qpolynomial_fold( + __isl_take isl_union_map *umap, + __isl_take isl_union_pw_qpolynomial_fold *upwf, + isl_bool *tight); + +The functions taking a map +compose the given map with the given piecewise quasipolynomial reduction. +That is, compute a bound (of the same type as C or C itself) +over all elements in the intersection of the range of the map +and the domain of the piecewise quasipolynomial reduction +as a function of an element in the domain of the map. +The functions taking a set compute a bound over all elements in the +intersection of the set and the domain of the +piecewise quasipolynomial reduction. + +=item * Preimage + + #include + __isl_give isl_basic_set * + isl_basic_set_preimage_multi_aff( + __isl_take isl_basic_set *bset, + __isl_take isl_multi_aff *ma); + __isl_give isl_set *isl_set_preimage_multi_aff( + __isl_take isl_set *set, + __isl_take isl_multi_aff *ma); + __isl_give isl_set *isl_set_preimage_pw_multi_aff( + __isl_take isl_set *set, + __isl_take isl_pw_multi_aff *pma); + __isl_give isl_set *isl_set_preimage_multi_pw_aff( + __isl_take isl_set *set, + __isl_take isl_multi_pw_aff *mpa); + + #include + __isl_give isl_union_set * + isl_union_set_preimage_multi_aff( + __isl_take isl_union_set *uset, + __isl_take isl_multi_aff *ma); + __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_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); + + #include + __isl_give isl_basic_map * + isl_basic_map_preimage_domain_multi_aff( + __isl_take isl_basic_map *bmap, + __isl_take isl_multi_aff *ma); + __isl_give isl_map *isl_map_preimage_domain_multi_aff( + __isl_take isl_map *map, + __isl_take isl_multi_aff *ma); + __isl_give isl_map *isl_map_preimage_range_multi_aff( + __isl_take isl_map *map, + __isl_take isl_multi_aff *ma); + __isl_give isl_map * + isl_map_preimage_domain_pw_multi_aff( + __isl_take isl_map *map, + __isl_take isl_pw_multi_aff *pma); + __isl_give isl_map * + isl_map_preimage_range_pw_multi_aff( + __isl_take isl_map *map, + __isl_take isl_pw_multi_aff *pma); + __isl_give isl_map * + isl_map_preimage_domain_multi_pw_aff( + __isl_take isl_map *map, + __isl_take isl_multi_pw_aff *mpa); + __isl_give isl_basic_map * + isl_basic_map_preimage_range_multi_aff( + __isl_take isl_basic_map *bmap, + __isl_take isl_multi_aff *ma); + + #include + __isl_give isl_union_map * + isl_union_map_preimage_domain_multi_aff( + __isl_take isl_union_map *umap, + __isl_take isl_multi_aff *ma); + __isl_give isl_union_map * + isl_union_map_preimage_range_multi_aff( + __isl_take isl_union_map *umap, + __isl_take isl_multi_aff *ma); + __isl_give isl_union_map * + isl_union_map_preimage_domain_pw_multi_aff( + __isl_take isl_union_map *umap, + __isl_take isl_pw_multi_aff *pma); + __isl_give isl_union_map * + isl_union_map_preimage_range_pw_multi_aff( + __isl_take isl_union_map *umap, + __isl_take isl_pw_multi_aff *pma); + __isl_give isl_union_map * + isl_union_map_preimage_domain_union_pw_multi_aff( + __isl_take isl_union_map *umap, + __isl_take isl_union_pw_multi_aff *upma); + __isl_give isl_union_map * + isl_union_map_preimage_range_union_pw_multi_aff( + __isl_take isl_union_map *umap, + __isl_take isl_union_pw_multi_aff *upma); + + #include + __isl_give isl_pw_multi_aff * + isl_pw_multi_aff_preimage_domain_wrapped_domain_pw_multi_aff( + __isl_take isl_pw_multi_aff *pma1, + __isl_take isl_pw_multi_aff *pma2); + __isl_give isl_union_pw_multi_aff * + isl_union_pw_multi_aff_preimage_domain_wrapped_domain_union_pw_multi_aff( + __isl_take isl_union_pw_multi_aff *upma1, + __isl_take isl_union_pw_multi_aff *upma2); + +These functions compute the preimage of the given set or map domain/range under +the given function. In other words, the expression is plugged +into the set description or into the domain/range of the map or function. + +=item * Pullback + + #include + __isl_give isl_aff *isl_aff_pullback_aff( + __isl_take isl_aff *aff1, + __isl_take isl_aff *aff2); + __isl_give isl_aff *isl_aff_pullback_multi_aff( + __isl_take isl_aff *aff, + __isl_take isl_multi_aff *ma); + __isl_give isl_pw_aff *isl_pw_aff_pullback_multi_aff( + __isl_take isl_pw_aff *pa, + __isl_take isl_multi_aff *ma); + __isl_give isl_pw_aff *isl_pw_aff_pullback_pw_multi_aff( + __isl_take isl_pw_aff *pa, + __isl_take isl_pw_multi_aff *pma); + __isl_give isl_pw_aff *isl_pw_aff_pullback_multi_pw_aff( + __isl_take isl_pw_aff *pa, + __isl_take isl_multi_pw_aff *mpa); + __isl_give isl_multi_aff *isl_multi_aff_pullback_multi_aff( + __isl_take isl_multi_aff *ma1, + __isl_take isl_multi_aff *ma2); + __isl_give isl_pw_multi_aff * + isl_pw_multi_aff_pullback_multi_aff( + __isl_take isl_pw_multi_aff *pma, + __isl_take isl_multi_aff *ma); + __isl_give isl_multi_pw_aff * + isl_multi_pw_aff_pullback_multi_aff( + __isl_take isl_multi_pw_aff *mpa, + __isl_take isl_multi_aff *ma); + __isl_give isl_pw_multi_aff * + isl_pw_multi_aff_pullback_pw_multi_aff( + __isl_take isl_pw_multi_aff *pma1, + __isl_take isl_pw_multi_aff *pma2); + __isl_give isl_multi_pw_aff * + isl_multi_pw_aff_pullback_pw_multi_aff( + __isl_take isl_multi_pw_aff *mpa, + __isl_take isl_pw_multi_aff *pma); + __isl_give isl_multi_pw_aff * + isl_multi_pw_aff_pullback_multi_pw_aff( + __isl_take isl_multi_pw_aff *mpa1, + __isl_take isl_multi_pw_aff *mpa2); + __isl_give isl_union_pw_aff * + isl_union_pw_aff_pullback_union_pw_multi_aff( + __isl_take isl_union_pw_aff *upa, + __isl_take isl_union_pw_multi_aff *upma); + __isl_give isl_union_pw_multi_aff * + isl_union_pw_multi_aff_pullback_union_pw_multi_aff( + __isl_take isl_union_pw_multi_aff *upma1, + __isl_take isl_union_pw_multi_aff *upma2); + __isl_give isl_multi_union_pw_aff * + isl_multi_union_pw_aff_pullback_union_pw_multi_aff( + __isl_take isl_multi_union_pw_aff *mupa, + __isl_take isl_union_pw_multi_aff *upma); + +These functions precompose the first expression by the second function. +In other words, the second function is plugged +into the first expression. + +=item * Locus + + #include + __isl_give isl_basic_set *isl_aff_eq_basic_set( + __isl_take isl_aff *aff1, + __isl_take isl_aff *aff2); + __isl_give isl_set *isl_aff_eq_set( + __isl_take isl_aff *aff1, + __isl_take isl_aff *aff2); + __isl_give isl_set *isl_aff_ne_set( + __isl_take isl_aff *aff1, + __isl_take isl_aff *aff2); + __isl_give isl_basic_set *isl_aff_le_basic_set( + __isl_take isl_aff *aff1, + __isl_take isl_aff *aff2); + __isl_give isl_set *isl_aff_le_set( + __isl_take isl_aff *aff1, + __isl_take isl_aff *aff2); + __isl_give isl_basic_set *isl_aff_lt_basic_set( + __isl_take isl_aff *aff1, + __isl_take isl_aff *aff2); + __isl_give isl_set *isl_aff_lt_set( + __isl_take isl_aff *aff1, + __isl_take isl_aff *aff2); + __isl_give isl_basic_set *isl_aff_ge_basic_set( + __isl_take isl_aff *aff1, + __isl_take isl_aff *aff2); + __isl_give isl_set *isl_aff_ge_set( + __isl_take isl_aff *aff1, + __isl_take isl_aff *aff2); + __isl_give isl_basic_set *isl_aff_gt_basic_set( + __isl_take isl_aff *aff1, + __isl_take isl_aff *aff2); + __isl_give isl_set *isl_aff_gt_set( + __isl_take isl_aff *aff1, + __isl_take isl_aff *aff2); + __isl_give isl_set *isl_pw_aff_eq_set( + __isl_take isl_pw_aff *pwaff1, + __isl_take isl_pw_aff *pwaff2); + __isl_give isl_set *isl_pw_aff_ne_set( + __isl_take isl_pw_aff *pwaff1, + __isl_take isl_pw_aff *pwaff2); + __isl_give isl_set *isl_pw_aff_le_set( + __isl_take isl_pw_aff *pwaff1, + __isl_take isl_pw_aff *pwaff2); + __isl_give isl_set *isl_pw_aff_lt_set( + __isl_take isl_pw_aff *pwaff1, + __isl_take isl_pw_aff *pwaff2); + __isl_give isl_set *isl_pw_aff_ge_set( + __isl_take isl_pw_aff *pwaff1, + __isl_take isl_pw_aff *pwaff2); + __isl_give isl_set *isl_pw_aff_gt_set( + __isl_take isl_pw_aff *pwaff1, + __isl_take isl_pw_aff *pwaff2); + + __isl_give isl_set *isl_multi_aff_lex_le_set( + __isl_take isl_multi_aff *ma1, + __isl_take isl_multi_aff *ma2); + __isl_give isl_set *isl_multi_aff_lex_lt_set( + __isl_take isl_multi_aff *ma1, + __isl_take isl_multi_aff *ma2); + __isl_give isl_set *isl_multi_aff_lex_ge_set( + __isl_take isl_multi_aff *ma1, + __isl_take isl_multi_aff *ma2); + __isl_give isl_set *isl_multi_aff_lex_gt_set( + __isl_take isl_multi_aff *ma1, + __isl_take isl_multi_aff *ma2); + + __isl_give isl_set *isl_pw_aff_list_eq_set( + __isl_take isl_pw_aff_list *list1, + __isl_take isl_pw_aff_list *list2); + __isl_give isl_set *isl_pw_aff_list_ne_set( + __isl_take isl_pw_aff_list *list1, + __isl_take isl_pw_aff_list *list2); + __isl_give isl_set *isl_pw_aff_list_le_set( + __isl_take isl_pw_aff_list *list1, + __isl_take isl_pw_aff_list *list2); + __isl_give isl_set *isl_pw_aff_list_lt_set( + __isl_take isl_pw_aff_list *list1, + __isl_take isl_pw_aff_list *list2); + __isl_give isl_set *isl_pw_aff_list_ge_set( + __isl_take isl_pw_aff_list *list1, + __isl_take isl_pw_aff_list *list2); + __isl_give isl_set *isl_pw_aff_list_gt_set( + __isl_take isl_pw_aff_list *list1, + __isl_take isl_pw_aff_list *list2); + +The function C returns a basic set +containing those elements in the shared space +of C and C where C is greater than or equal to C. +The function C returns a set +containing those elements in the shared domain +of C and C where C is +greater than or equal to C. +The function C returns a set +containing those elements in the shared domain space +where C is lexicographically smaller than or +equal to C. +The functions operating on C apply the corresponding +C function to each pair of elements in the two lists. + + #include + __isl_give isl_map *isl_pw_aff_eq_map( + __isl_take isl_pw_aff *pa1, + __isl_take isl_pw_aff *pa2); + __isl_give isl_map *isl_pw_aff_le_map( + __isl_take isl_pw_aff *pa1, + __isl_take isl_pw_aff *pa2); + __isl_give isl_map *isl_pw_aff_lt_map( + __isl_take isl_pw_aff *pa1, + __isl_take isl_pw_aff *pa2); + __isl_give isl_map *isl_pw_aff_ge_map( + __isl_take isl_pw_aff *pa1, + __isl_take isl_pw_aff *pa2); + __isl_give isl_map *isl_pw_aff_gt_map( + __isl_take isl_pw_aff *pa1, + __isl_take isl_pw_aff *pa2); + + __isl_give isl_map *isl_multi_pw_aff_eq_map( + __isl_take isl_multi_pw_aff *mpa1, + __isl_take isl_multi_pw_aff *mpa2); + __isl_give isl_map *isl_multi_pw_aff_lex_le_map( + __isl_take isl_multi_pw_aff *mpa1, + __isl_take isl_multi_pw_aff *mpa2); + __isl_give isl_map *isl_multi_pw_aff_lex_lt_map( + __isl_take isl_multi_pw_aff *mpa1, + __isl_take isl_multi_pw_aff *mpa2); + __isl_give isl_map *isl_multi_pw_aff_lex_ge_map( + __isl_take isl_multi_pw_aff *mpa1, + __isl_take isl_multi_pw_aff *mpa2); + __isl_give isl_map *isl_multi_pw_aff_lex_gt_map( + __isl_take isl_multi_pw_aff *mpa1, + __isl_take isl_multi_pw_aff *mpa2); + +These functions return a map between domain elements of the arguments +where the function values satisfy the given relation. + + #include + __isl_give isl_map *isl_map_eq_at_multi_pw_aff( + __isl_take isl_map *map, + __isl_take isl_multi_pw_aff *mpa); + __isl_give isl_map *isl_map_lex_lt_at_multi_pw_aff( + __isl_take isl_map *map, + __isl_take isl_multi_pw_aff *mpa); + __isl_give isl_map *isl_map_lex_le_at_multi_pw_aff( + __isl_take isl_map *map, + __isl_take isl_multi_pw_aff *mpa); + __isl_give isl_map *isl_map_lex_gt_at_multi_pw_aff( + __isl_take isl_map *map, + __isl_take isl_multi_pw_aff *mpa); + __isl_give isl_map *isl_map_lex_ge_at_multi_pw_aff( + __isl_take isl_map *map, + __isl_take isl_multi_pw_aff *mpa); + + #include + __isl_give isl_union_map * + isl_union_map_eq_at_multi_union_pw_aff( + __isl_take isl_union_map *umap, + __isl_take isl_multi_union_pw_aff *mupa); + __isl_give isl_union_map * + isl_union_map_lex_lt_at_multi_union_pw_aff( + __isl_take isl_union_map *umap, + __isl_take isl_multi_union_pw_aff *mupa); + __isl_give isl_union_map * + isl_union_map_lex_le_at_multi_union_pw_aff( + __isl_take isl_union_map *umap, + __isl_take isl_multi_union_pw_aff *mupa); + __isl_give isl_union_map * + isl_union_map_lex_gt_at_multi_union_pw_aff( + __isl_take isl_union_map *umap, + __isl_take isl_multi_union_pw_aff *mupa); + __isl_give isl_union_map * + isl_union_map_lex_ge_at_multi_union_pw_aff( + __isl_take isl_union_map *umap, + __isl_take isl_multi_union_pw_aff *mupa); + +These functions select the subset of elements in the union map +that have an equal or lexicographically smaller or greater function value. + +=item * Cartesian Product + + #include + __isl_give isl_space *isl_space_product( + __isl_take isl_space *space1, + __isl_take isl_space *space2); + __isl_give isl_space *isl_space_domain_product( + __isl_take isl_space *space1, + __isl_take isl_space *space2); + __isl_give isl_space *isl_space_range_product( + __isl_take isl_space *space1, + __isl_take isl_space *space2); + +The functions +C, C +and C take pairs or relation spaces and +produce a single relations space, where either the domain, the range +or both domain and range are wrapped spaces of relations between +the domains and/or ranges of the input spaces. +If the product is only constructed over the domain or the range +then the ranges or the domains of the inputs should be the same. +The function C also accepts a pair of set spaces, +in which case it returns a wrapped space of a relation between the +two input spaces. + + #include + __isl_give isl_set *isl_set_product( + __isl_take isl_set *set1, + __isl_take isl_set *set2); + + #include + __isl_give isl_basic_map *isl_basic_map_domain_product( + __isl_take isl_basic_map *bmap1, + __isl_take isl_basic_map *bmap2); + __isl_give isl_basic_map *isl_basic_map_range_product( + __isl_take isl_basic_map *bmap1, + __isl_take isl_basic_map *bmap2); + __isl_give isl_basic_map *isl_basic_map_product( + __isl_take isl_basic_map *bmap1, + __isl_take isl_basic_map *bmap2); + __isl_give isl_map *isl_map_domain_product( + __isl_take isl_map *map1, + __isl_take isl_map *map2); + __isl_give isl_map *isl_map_range_product( + __isl_take isl_map *map1, + __isl_take isl_map *map2); + __isl_give isl_map *isl_map_product( + __isl_take isl_map *map1, + __isl_take isl_map *map2); + + #include + __isl_give isl_union_set *isl_union_set_product( + __isl_take isl_union_set *uset1, + __isl_take isl_union_set *uset2); + + #include + __isl_give isl_union_map *isl_union_map_domain_product( + __isl_take isl_union_map *umap1, + __isl_take isl_union_map *umap2); + __isl_give isl_union_map *isl_union_map_range_product( + __isl_take isl_union_map *umap1, + __isl_take isl_union_map *umap2); + __isl_give isl_union_map *isl_union_map_product( + __isl_take isl_union_map *umap1, + __isl_take isl_union_map *umap2); + + #include + __isl_give isl_multi_id *isl_multi_id_range_product( + __isl_take isl_multi_id *mi1, + __isl_take isl_multi_id *mi2); + + #include + __isl_give isl_multi_val *isl_multi_val_range_product( + __isl_take isl_multi_val *mv1, + __isl_take isl_multi_val *mv2); + __isl_give isl_multi_val *isl_multi_val_product( + __isl_take isl_multi_val *mv1, + __isl_take isl_multi_val *mv2); + + #include + __isl_give isl_multi_aff *isl_multi_aff_range_product( + __isl_take isl_multi_aff *ma1, + __isl_take isl_multi_aff *ma2); + __isl_give isl_multi_aff *isl_multi_aff_product( + __isl_take isl_multi_aff *ma1, + __isl_take isl_multi_aff *ma2); + __isl_give isl_multi_pw_aff * + isl_multi_pw_aff_range_product( + __isl_take isl_multi_pw_aff *mpa1, + __isl_take isl_multi_pw_aff *mpa2); + __isl_give isl_multi_pw_aff *isl_multi_pw_aff_product( + __isl_take isl_multi_pw_aff *mpa1, + __isl_take isl_multi_pw_aff *mpa2); + __isl_give isl_pw_multi_aff * + isl_pw_multi_aff_range_product( + __isl_take isl_pw_multi_aff *pma1, + __isl_take isl_pw_multi_aff *pma2); + __isl_give isl_pw_multi_aff *isl_pw_multi_aff_product( + __isl_take isl_pw_multi_aff *pma1, + __isl_take isl_pw_multi_aff *pma2); + __isl_give isl_union_pw_multi_aff * + isl_union_pw_multi_aff_range_product( + __isl_take isl_union_pw_multi_aff *upma1, + __isl_take isl_union_pw_multi_aff *upma2); + __isl_give isl_multi_union_pw_aff * + isl_multi_union_pw_aff_range_product( + __isl_take isl_multi_union_pw_aff *mupa1, + __isl_take isl_multi_union_pw_aff *mupa2); + +The above functions compute the cross product of the given +sets, relations or functions. The domains and ranges of the results +are wrapped maps between domains and ranges of the inputs. +To obtain a ``flat'' product, use the following functions +instead. + + #include + __isl_give isl_basic_set *isl_basic_set_flat_product( + __isl_take isl_basic_set *bset1, + __isl_take isl_basic_set *bset2); + __isl_give isl_set *isl_set_flat_product( + __isl_take isl_set *set1, + __isl_take isl_set *set2); + + #include + __isl_give isl_basic_map *isl_basic_map_flat_range_product( + __isl_take isl_basic_map *bmap1, + __isl_take isl_basic_map *bmap2); + __isl_give isl_map *isl_map_flat_domain_product( + __isl_take isl_map *map1, + __isl_take isl_map *map2); + __isl_give isl_map *isl_map_flat_range_product( + __isl_take isl_map *map1, + __isl_take isl_map *map2); + __isl_give isl_basic_map *isl_basic_map_flat_product( + __isl_take isl_basic_map *bmap1, + __isl_take isl_basic_map *bmap2); + __isl_give isl_map *isl_map_flat_product( + __isl_take isl_map *map1, + __isl_take isl_map *map2); + + #include + __isl_give isl_union_map * + isl_union_map_flat_domain_product( + __isl_take isl_union_map *umap1, + __isl_take isl_union_map *umap2); + __isl_give isl_union_map * + isl_union_map_flat_range_product( + __isl_take isl_union_map *umap1, + __isl_take isl_union_map *umap2); + + #include + __isl_give isl_multi_id * + isl_multi_id_flat_range_product( + __isl_take isl_multi_id *mi1, + __isl_take isl_multi_id *mi2); + + #include + __isl_give isl_multi_val *isl_multi_val_flat_range_product( + __isl_take isl_multi_val *mv1, + __isl_take isl_multi_val *mv2); + + #include + __isl_give isl_multi_aff *isl_multi_aff_flat_range_product( + __isl_take isl_multi_aff *ma1, + __isl_take isl_multi_aff *ma2); + __isl_give isl_pw_multi_aff * + isl_pw_multi_aff_flat_range_product( + __isl_take isl_pw_multi_aff *pma1, + __isl_take isl_pw_multi_aff *pma2); + __isl_give isl_multi_pw_aff * + isl_multi_pw_aff_flat_range_product( + __isl_take isl_multi_pw_aff *mpa1, + __isl_take isl_multi_pw_aff *mpa2); + __isl_give isl_union_pw_multi_aff * + isl_union_pw_multi_aff_flat_range_product( + __isl_take isl_union_pw_multi_aff *upma1, + __isl_take isl_union_pw_multi_aff *upma2); + __isl_give isl_multi_union_pw_aff * + isl_multi_union_pw_aff_flat_range_product( + __isl_take isl_multi_union_pw_aff *mupa1, + __isl_take isl_multi_union_pw_aff *mupa2); + + #include + __isl_give isl_space *isl_space_factor_domain( + __isl_take isl_space *space); + __isl_give isl_space *isl_space_factor_range( + __isl_take isl_space *space); + __isl_give isl_space *isl_space_domain_factor_domain( + __isl_take isl_space *space); + __isl_give isl_space *isl_space_domain_factor_range( + __isl_take isl_space *space); + __isl_give isl_space *isl_space_range_factor_domain( + __isl_take isl_space *space); + __isl_give isl_space *isl_space_range_factor_range( + __isl_take isl_space *space); + +The functions C and +C extract the two arguments from +the result of a call to C. + +The arguments of a call to a product can be extracted +from the result using the following functions. + + #include + __isl_give isl_map *isl_map_factor_domain( + __isl_take isl_map *map); + __isl_give isl_map *isl_map_factor_range( + __isl_take isl_map *map); + __isl_give isl_map *isl_map_domain_factor_domain( + __isl_take isl_map *map); + __isl_give isl_map *isl_map_domain_factor_range( + __isl_take isl_map *map); + __isl_give isl_map *isl_map_range_factor_domain( + __isl_take isl_map *map); + __isl_give isl_map *isl_map_range_factor_range( + __isl_take isl_map *map); + + #include + __isl_give isl_union_map *isl_union_map_factor_domain( + __isl_take isl_union_map *umap); + __isl_give isl_union_map *isl_union_map_factor_range( + __isl_take isl_union_map *umap); + __isl_give isl_union_map * + isl_union_map_domain_factor_domain( + __isl_take isl_union_map *umap); + __isl_give isl_union_map * + isl_union_map_domain_factor_range( + __isl_take isl_union_map *umap); + __isl_give isl_union_map * + isl_union_map_range_factor_domain( + __isl_take isl_union_map *umap); + __isl_give isl_union_map * + isl_union_map_range_factor_range( + __isl_take isl_union_map *umap); + + #include + __isl_give isl_multi_id *isl_multi_id_factor_range( + __isl_take isl_multi_id *mi); + __isl_give isl_multi_id * + isl_multi_id_range_factor_domain( + __isl_take isl_multi_id *mi); + __isl_give isl_multi_id * + isl_multi_id_range_factor_range( + __isl_take isl_multi_id *mi); + + #include + __isl_give isl_multi_val *isl_multi_val_factor_range( + __isl_take isl_multi_val *mv); + __isl_give isl_multi_val * + isl_multi_val_range_factor_domain( + __isl_take isl_multi_val *mv); + __isl_give isl_multi_val * + isl_multi_val_range_factor_range( + __isl_take isl_multi_val *mv); + + #include + __isl_give isl_multi_aff *isl_multi_aff_factor_range( + __isl_take isl_multi_aff *ma); + __isl_give isl_multi_aff * + isl_multi_aff_range_factor_domain( + __isl_take isl_multi_aff *ma); + __isl_give isl_multi_aff * + isl_multi_aff_range_factor_range( + __isl_take isl_multi_aff *ma); + __isl_give isl_multi_pw_aff * + isl_multi_pw_aff_factor_range( + __isl_take isl_multi_pw_aff *mpa); + __isl_give isl_multi_pw_aff * + isl_multi_pw_aff_range_factor_domain( + __isl_take isl_multi_pw_aff *mpa); + __isl_give isl_multi_pw_aff * + isl_multi_pw_aff_range_factor_range( + __isl_take isl_multi_pw_aff *mpa); + __isl_give isl_pw_multi_aff * + isl_pw_multi_aff_range_factor_domain( + __isl_take isl_pw_multi_aff *pma); + __isl_give isl_pw_multi_aff * + isl_pw_multi_aff_range_factor_range( + __isl_take isl_pw_multi_aff *pma); + __isl_give isl_union_pw_multi_aff * + isl_union_pw_multi_aff_range_factor_domain( + __isl_take isl_union_pw_multi_aff *upma); + __isl_give isl_union_pw_multi_aff * + isl_union_pw_multi_aff_range_factor_range( + __isl_take isl_union_pw_multi_aff *upma); + __isl_give isl_multi_union_pw_aff * + isl_multi_union_pw_aff_factor_range( + __isl_take isl_multi_union_pw_aff *mupa); + __isl_give isl_multi_union_pw_aff * + isl_multi_union_pw_aff_range_factor_domain( + __isl_take isl_multi_union_pw_aff *mupa); + __isl_give isl_multi_union_pw_aff * + isl_multi_union_pw_aff_range_factor_range( + __isl_take isl_multi_union_pw_aff *mupa); + +The splice functions are a generalization of the flat product functions, +where the second argument may be inserted at any position inside +the first argument rather than being placed at the end. +The functions C, +C, +C and +C +take functions that live in a set space. + + #include + __isl_give isl_multi_id *isl_multi_id_range_splice( + __isl_take isl_multi_id *mi1, unsigned pos, + __isl_take isl_multi_id *mi2); + + #include + __isl_give isl_multi_val *isl_multi_val_range_splice( + __isl_take isl_multi_val *mv1, unsigned pos, + __isl_take isl_multi_val *mv2); + + #include + __isl_give isl_multi_aff *isl_multi_aff_range_splice( + __isl_take isl_multi_aff *ma1, unsigned pos, + __isl_take isl_multi_aff *ma2); + __isl_give isl_multi_aff *isl_multi_aff_splice( + __isl_take isl_multi_aff *ma1, + unsigned in_pos, unsigned out_pos, + __isl_take isl_multi_aff *ma2); + __isl_give isl_multi_pw_aff * + isl_multi_pw_aff_range_splice( + __isl_take isl_multi_pw_aff *mpa1, unsigned pos, + __isl_take isl_multi_pw_aff *mpa2); + __isl_give isl_multi_pw_aff *isl_multi_pw_aff_splice( + __isl_take isl_multi_pw_aff *mpa1, + unsigned in_pos, unsigned out_pos, + __isl_take isl_multi_pw_aff *mpa2); + __isl_give isl_multi_union_pw_aff * + isl_multi_union_pw_aff_range_splice( + __isl_take isl_multi_union_pw_aff *mupa1, + unsigned pos, + __isl_take isl_multi_union_pw_aff *mupa2); + +=item * Simplification + +When applied to a set or relation, +the gist operation returns a set or relation that has the +same intersection with the context as the input set or relation. +Any implicit equality in the intersection is made explicit in the result, +while all inequalities that are redundant with respect to the intersection +are removed. +In case of union sets and relations, the gist operation is performed +per space. + +When applied to a function, +the gist operation applies the set gist operation to each of +the cells in the domain of the input piecewise expression. +The context is also exploited +to simplify the expression associated to each cell. + + #include + __isl_give isl_basic_set *isl_basic_set_gist( + __isl_take isl_basic_set *bset, + __isl_take isl_basic_set *context); + __isl_give isl_set *isl_set_gist(__isl_take isl_set *set, + __isl_take isl_set *context); + __isl_give isl_set *isl_set_gist_params( + __isl_take isl_set *set, + __isl_take isl_set *context); + + #include + __isl_give isl_basic_map *isl_basic_map_gist( + __isl_take isl_basic_map *bmap, + __isl_take isl_basic_map *context); + __isl_give isl_basic_map *isl_basic_map_gist_domain( + __isl_take isl_basic_map *bmap, + __isl_take isl_basic_set *context); + __isl_give isl_map *isl_map_gist(__isl_take isl_map *map, + __isl_take isl_map *context); + __isl_give isl_map *isl_map_gist_params( + __isl_take isl_map *map, + __isl_take isl_set *context); + __isl_give isl_map *isl_map_gist_domain( + __isl_take isl_map *map, + __isl_take isl_set *context); + __isl_give isl_map *isl_map_gist_range( + __isl_take isl_map *map, + __isl_take isl_set *context); + + #include + __isl_give isl_union_set *isl_union_set_gist( + __isl_take isl_union_set *uset, + __isl_take isl_union_set *context); + __isl_give isl_union_set *isl_union_set_gist_params( + __isl_take isl_union_set *uset, + __isl_take isl_set *set); + + #include + __isl_give isl_union_map *isl_union_map_gist( + __isl_take isl_union_map *umap, + __isl_take isl_union_map *context); + __isl_give isl_union_map *isl_union_map_gist_params( + __isl_take isl_union_map *umap, + __isl_take isl_set *set); + __isl_give isl_union_map *isl_union_map_gist_domain( + __isl_take isl_union_map *umap, + __isl_take isl_union_set *uset); + __isl_give isl_union_map *isl_union_map_gist_range( + __isl_take isl_union_map *umap, + __isl_take isl_union_set *uset); + + #include + __isl_give isl_aff *isl_aff_gist_params( + __isl_take isl_aff *aff, + __isl_take isl_set *context); + __isl_give isl_aff *isl_aff_gist(__isl_take isl_aff *aff, + __isl_take isl_set *context); + __isl_give isl_multi_aff *isl_multi_aff_gist_params( + __isl_take isl_multi_aff *maff, + __isl_take isl_set *context); + __isl_give isl_multi_aff *isl_multi_aff_gist( + __isl_take isl_multi_aff *maff, + __isl_take isl_set *context); + __isl_give isl_pw_aff *isl_pw_aff_gist_params( + __isl_take isl_pw_aff *pwaff, + __isl_take isl_set *context); + __isl_give isl_pw_aff *isl_pw_aff_gist( + __isl_take isl_pw_aff *pwaff, + __isl_take isl_set *context); + __isl_give isl_pw_multi_aff *isl_pw_multi_aff_gist_params( + __isl_take isl_pw_multi_aff *pma, + __isl_take isl_set *set); + __isl_give isl_pw_multi_aff *isl_pw_multi_aff_gist( + __isl_take isl_pw_multi_aff *pma, + __isl_take isl_set *set); + __isl_give isl_multi_pw_aff *isl_multi_pw_aff_gist_params( + __isl_take isl_multi_pw_aff *mpa, + __isl_take isl_set *set); + __isl_give isl_multi_pw_aff *isl_multi_pw_aff_gist( + __isl_take isl_multi_pw_aff *mpa, + __isl_take isl_set *set); + __isl_give isl_union_pw_aff *isl_union_pw_aff_gist( + __isl_take isl_union_pw_aff *upa, + __isl_take isl_union_set *context); + __isl_give isl_union_pw_aff *isl_union_pw_aff_gist_params( + __isl_take isl_union_pw_aff *upa, + __isl_take isl_set *context); + __isl_give isl_union_pw_multi_aff * + isl_union_pw_multi_aff_gist_params( + __isl_take isl_union_pw_multi_aff *upma, + __isl_take isl_set *context); + __isl_give isl_union_pw_multi_aff * + isl_union_pw_multi_aff_gist( + __isl_take isl_union_pw_multi_aff *upma, + __isl_take isl_union_set *context); + __isl_give isl_multi_union_pw_aff * + isl_multi_union_pw_aff_gist_params( + __isl_take isl_multi_union_pw_aff *mupa, + __isl_take isl_set *context); + __isl_give isl_multi_union_pw_aff * + isl_multi_union_pw_aff_gist( + __isl_take isl_multi_union_pw_aff *mupa, + __isl_take isl_union_set *context); + + #include + __isl_give isl_qpolynomial *isl_qpolynomial_gist_params( + __isl_take isl_qpolynomial *qp, + __isl_take isl_set *context); + __isl_give isl_qpolynomial *isl_qpolynomial_gist( + __isl_take isl_qpolynomial *qp, + __isl_take isl_set *context); + __isl_give isl_qpolynomial_fold * + isl_qpolynomial_fold_gist_params( + __isl_take isl_qpolynomial_fold *fold, + __isl_take isl_set *context); + __isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_gist( + __isl_take isl_qpolynomial_fold *fold, + __isl_take isl_set *context); + __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_gist_params( + __isl_take isl_pw_qpolynomial *pwqp, + __isl_take isl_set *context); + __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_gist( + __isl_take isl_pw_qpolynomial *pwqp, + __isl_take isl_set *context); + __isl_give isl_pw_qpolynomial_fold * + isl_pw_qpolynomial_fold_gist( + __isl_take isl_pw_qpolynomial_fold *pwf, + __isl_take isl_set *context); + __isl_give isl_pw_qpolynomial_fold * + isl_pw_qpolynomial_fold_gist_params( + __isl_take isl_pw_qpolynomial_fold *pwf, + __isl_take isl_set *context); + __isl_give isl_union_pw_qpolynomial * + isl_union_pw_qpolynomial_gist_params( + __isl_take isl_union_pw_qpolynomial *upwqp, + __isl_take isl_set *context); + __isl_give isl_union_pw_qpolynomial *isl_union_pw_qpolynomial_gist( + __isl_take isl_union_pw_qpolynomial *upwqp, + __isl_take isl_union_set *context); + __isl_give isl_union_pw_qpolynomial_fold * + isl_union_pw_qpolynomial_fold_gist( + __isl_take isl_union_pw_qpolynomial_fold *upwf, + __isl_take isl_union_set *context); + __isl_give isl_union_pw_qpolynomial_fold * + isl_union_pw_qpolynomial_fold_gist_params( + __isl_take isl_union_pw_qpolynomial_fold *upwf, + __isl_take isl_set *context); + +=item * Binary Arithmetic Operations + + #include + __isl_give isl_set *isl_set_sum( + __isl_take isl_set *set1, + __isl_take isl_set *set2); + #include + __isl_give isl_map *isl_map_sum( + __isl_take isl_map *map1, + __isl_take isl_map *map2); + +C computes the Minkowski sum of its two arguments, +i.e., the set containing the sums of pairs of elements from +C and C. +The domain of the result of C is the intersection +of the domains of its two arguments. The corresponding range +elements are the sums of the corresponding range elements +in the two arguments. + + #include + __isl_give isl_multi_val *isl_multi_val_add( + __isl_take isl_multi_val *mv1, + __isl_take isl_multi_val *mv2); + __isl_give isl_multi_val *isl_multi_val_sub( + __isl_take isl_multi_val *mv1, + __isl_take isl_multi_val *mv2); + __isl_give isl_multi_val *isl_multi_val_min( + __isl_take isl_multi_val *mv1, + __isl_take isl_multi_val *mv2); + __isl_give isl_multi_val *isl_multi_val_max( + __isl_take isl_multi_val *mv1, + __isl_take isl_multi_val *mv2); + + #include + __isl_give isl_aff *isl_aff_add( + __isl_take isl_aff *aff1, + __isl_take isl_aff *aff2); + __isl_give isl_multi_aff *isl_multi_aff_add( + __isl_take isl_multi_aff *maff1, + __isl_take isl_multi_aff *maff2); + __isl_give isl_pw_aff *isl_pw_aff_add( + __isl_take isl_pw_aff *pwaff1, + __isl_take isl_pw_aff *pwaff2); + __isl_give isl_multi_pw_aff *isl_multi_pw_aff_add( + __isl_take isl_multi_pw_aff *mpa1, + __isl_take isl_multi_pw_aff *mpa2); + __isl_give isl_pw_multi_aff *isl_pw_multi_aff_add( + __isl_take isl_pw_multi_aff *pma1, + __isl_take isl_pw_multi_aff *pma2); + __isl_give isl_union_pw_aff *isl_union_pw_aff_add( + __isl_take isl_union_pw_aff *upa1, + __isl_take isl_union_pw_aff *upa2); + __isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_add( + __isl_take isl_union_pw_multi_aff *upma1, + __isl_take isl_union_pw_multi_aff *upma2); + __isl_give isl_multi_union_pw_aff * + isl_multi_union_pw_aff_add( + __isl_take isl_multi_union_pw_aff *mupa1, + __isl_take isl_multi_union_pw_aff *mupa2); + __isl_give isl_pw_aff *isl_pw_aff_add_constant_val( + __isl_take isl_pw_aff *pa, + __isl_take isl_val *v); + __isl_give isl_multi_aff * + isl_multi_aff_add_constant_val( + __isl_take isl_multi_aff *pa, + __isl_take isl_val *v); + __isl_give isl_pw_multi_aff * + isl_pw_multi_aff_add_constant_val( + __isl_take isl_pw_multi_aff *pma, + __isl_take isl_val *v); + __isl_give isl_pw_multi_aff * + isl_pw_multi_aff_add_constant_multi_val( + __isl_take isl_pw_multi_aff *pma, + __isl_take isl_multi_val *mv); + __isl_give isl_multi_pw_aff * + isl_multi_pw_aff_add_constant_val( + __isl_take isl_multi_pw_aff *mpa, + __isl_take isl_val *v); + __isl_give isl_multi_aff * + isl_multi_aff_add_constant_multi_val( + __isl_take isl_multi_aff *pa, + __isl_take isl_multi_val *mv); + __isl_give isl_multi_pw_aff * + isl_multi_pw_aff_add_constant_multi_val( + __isl_take isl_multi_pw_aff *mpa, + __isl_take isl_multi_val *mv); + __isl_give isl_pw_aff *isl_pw_aff_min( + __isl_take isl_pw_aff *pwaff1, + __isl_take isl_pw_aff *pwaff2); + __isl_give isl_pw_aff *isl_pw_aff_max( + __isl_take isl_pw_aff *pwaff1, + __isl_take isl_pw_aff *pwaff2); + __isl_give isl_multi_pw_aff *isl_multi_pw_aff_min( + __isl_take isl_multi_pw_aff *mpa1, + __isl_take isl_multi_pw_aff *mpa2); + __isl_give isl_multi_pw_aff *isl_multi_pw_aff_max( + __isl_take isl_multi_pw_aff *mpa1, + __isl_take isl_multi_pw_aff *mpa2); + __isl_give isl_aff *isl_aff_sub( + __isl_take isl_aff *aff1, + __isl_take isl_aff *aff2); + __isl_give isl_multi_aff *isl_multi_aff_sub( + __isl_take isl_multi_aff *ma1, + __isl_take isl_multi_aff *ma2); + __isl_give isl_pw_aff *isl_pw_aff_sub( + __isl_take isl_pw_aff *pwaff1, + __isl_take isl_pw_aff *pwaff2); + __isl_give isl_multi_pw_aff *isl_multi_pw_aff_sub( + __isl_take isl_multi_pw_aff *mpa1, + __isl_take isl_multi_pw_aff *mpa2); + __isl_give isl_pw_multi_aff *isl_pw_multi_aff_sub( + __isl_take isl_pw_multi_aff *pma1, + __isl_take isl_pw_multi_aff *pma2); + __isl_give isl_union_pw_aff *isl_union_pw_aff_sub( + __isl_take isl_union_pw_aff *upa1, + __isl_take isl_union_pw_aff *upa2); + __isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_sub( + __isl_take isl_union_pw_multi_aff *upma1, + __isl_take isl_union_pw_multi_aff *upma2); + __isl_give isl_multi_union_pw_aff * + isl_multi_union_pw_aff_sub( + __isl_take isl_multi_union_pw_aff *mupa1, + __isl_take isl_multi_union_pw_aff *mupa2); + +C subtracts the second argument from the first. + + #include + __isl_give isl_qpolynomial *isl_qpolynomial_add( + __isl_take isl_qpolynomial *qp1, + __isl_take isl_qpolynomial *qp2); + __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_add( + __isl_take isl_pw_qpolynomial *pwqp1, + __isl_take isl_pw_qpolynomial *pwqp2); + __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_add_disjoint( + __isl_take isl_pw_qpolynomial *pwqp1, + __isl_take isl_pw_qpolynomial *pwqp2); + __isl_give isl_pw_qpolynomial_fold *isl_pw_qpolynomial_fold_add( + __isl_take isl_pw_qpolynomial_fold *pwf1, + __isl_take isl_pw_qpolynomial_fold *pwf2); + __isl_give isl_union_pw_qpolynomial *isl_union_pw_qpolynomial_add( + __isl_take isl_union_pw_qpolynomial *upwqp1, + __isl_take isl_union_pw_qpolynomial *upwqp2); + __isl_give isl_qpolynomial *isl_qpolynomial_sub( + __isl_take isl_qpolynomial *qp1, + __isl_take isl_qpolynomial *qp2); + __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_sub( + __isl_take isl_pw_qpolynomial *pwqp1, + __isl_take isl_pw_qpolynomial *pwqp2); + __isl_give isl_union_pw_qpolynomial *isl_union_pw_qpolynomial_sub( + __isl_take isl_union_pw_qpolynomial *upwqp1, + __isl_take isl_union_pw_qpolynomial *upwqp2); + __isl_give isl_pw_qpolynomial_fold *isl_pw_qpolynomial_fold_fold( + __isl_take isl_pw_qpolynomial_fold *pwf1, + __isl_take isl_pw_qpolynomial_fold *pwf2); + __isl_give isl_union_pw_qpolynomial_fold * + isl_union_pw_qpolynomial_fold_fold( + __isl_take isl_union_pw_qpolynomial_fold *upwf1, + __isl_take isl_union_pw_qpolynomial_fold *upwf2); + + #include + __isl_give isl_pw_aff *isl_pw_aff_union_add( + __isl_take isl_pw_aff *pwaff1, + __isl_take isl_pw_aff *pwaff2); + __isl_give isl_multi_pw_aff *isl_multi_pw_aff_union_add( + __isl_take isl_multi_pw_aff *mpa1, + __isl_take isl_multi_pw_aff *mpa2); + __isl_give isl_pw_multi_aff *isl_pw_multi_aff_union_add( + __isl_take isl_pw_multi_aff *pma1, + __isl_take isl_pw_multi_aff *pma2); + __isl_give isl_union_pw_aff *isl_union_pw_aff_union_add( + __isl_take isl_union_pw_aff *upa1, + __isl_take isl_union_pw_aff *upa2); + __isl_give isl_union_pw_multi_aff * + isl_union_pw_multi_aff_union_add( + __isl_take isl_union_pw_multi_aff *upma1, + __isl_take isl_union_pw_multi_aff *upma2); + __isl_give isl_multi_union_pw_aff * + isl_multi_union_pw_aff_union_add( + __isl_take isl_multi_union_pw_aff *mupa1, + __isl_take isl_multi_union_pw_aff *mupa2); + __isl_give isl_pw_aff *isl_pw_aff_union_min( + __isl_take isl_pw_aff *pwaff1, + __isl_take isl_pw_aff *pwaff2); + __isl_give isl_pw_aff *isl_pw_aff_union_max( + __isl_take isl_pw_aff *pwaff1, + __isl_take isl_pw_aff *pwaff2); + +The function C computes a piecewise quasi-affine +expression with a domain that is the union of those of C and +C and such that on each cell, the quasi-affine expression is +the maximum of those of C and C. If only one of +C or C is defined on a given cell, then the +associated expression is the defined one. +This in contrast to the C function, which is +only defined on the shared definition domain of the arguments. + + #include + __isl_give isl_multi_val *isl_multi_val_add_val( + __isl_take isl_multi_val *mv, + __isl_take isl_val *v); + __isl_give isl_multi_val *isl_multi_val_mod_val( + __isl_take isl_multi_val *mv, + __isl_take isl_val *v); + __isl_give isl_multi_val *isl_multi_val_scale_val( + __isl_take isl_multi_val *mv, + __isl_take isl_val *v); + __isl_give isl_multi_val *isl_multi_val_scale_down_val( + __isl_take isl_multi_val *mv, + __isl_take isl_val *v); + + #include + __isl_give isl_aff *isl_aff_mod_val(__isl_take isl_aff *aff, + __isl_take isl_val *mod); + __isl_give isl_pw_aff *isl_pw_aff_mod_val( + __isl_take isl_pw_aff *pa, + __isl_take isl_val *mod); + __isl_give isl_union_pw_aff *isl_union_pw_aff_mod_val( + __isl_take isl_union_pw_aff *upa, + __isl_take isl_val *f); + __isl_give isl_aff *isl_aff_scale_val(__isl_take isl_aff *aff, + __isl_take isl_val *v); + __isl_give isl_multi_aff *isl_multi_aff_scale_val( + __isl_take isl_multi_aff *ma, + __isl_take isl_val *v); + __isl_give isl_pw_aff *isl_pw_aff_scale_val( + __isl_take isl_pw_aff *pa, __isl_take isl_val *v); + __isl_give isl_multi_pw_aff *isl_multi_pw_aff_scale_val( + __isl_take isl_multi_pw_aff *mpa, + __isl_take isl_val *v); + __isl_give isl_pw_multi_aff *isl_pw_multi_aff_scale_val( + __isl_take isl_pw_multi_aff *pma, + __isl_take isl_val *v); + __isl_give isl_union_pw_aff *isl_union_pw_aff_scale_val( + __isl_take isl_union_pw_aff *upa, + __isl_take isl_val *f); + __isl_give isl_union_pw_multi_aff * + isl_union_pw_multi_aff_scale_val( + __isl_take isl_union_pw_multi_aff *upma, + __isl_take isl_val *val); + __isl_give isl_multi_union_pw_aff * + isl_multi_union_pw_aff_scale_val( + __isl_take isl_multi_union_pw_aff *mupa, + __isl_take isl_val *v); + __isl_give isl_aff *isl_aff_scale_down_ui( + __isl_take isl_aff *aff, unsigned f); + __isl_give isl_aff *isl_aff_scale_down_val( + __isl_take isl_aff *aff, __isl_take isl_val *v); + __isl_give isl_multi_aff *isl_multi_aff_scale_down_val( + __isl_take isl_multi_aff *ma, + __isl_take isl_val *v); + __isl_give isl_pw_aff *isl_pw_aff_scale_down_val( + __isl_take isl_pw_aff *pa, + __isl_take isl_val *f); + __isl_give isl_multi_pw_aff *isl_multi_pw_aff_scale_down_val( + __isl_take isl_multi_pw_aff *mpa, + __isl_take isl_val *v); + __isl_give isl_pw_multi_aff *isl_pw_multi_aff_scale_down_val( + __isl_take isl_pw_multi_aff *pma, + __isl_take isl_val *v); + __isl_give isl_union_pw_aff *isl_union_pw_aff_scale_down_val( + __isl_take isl_union_pw_aff *upa, + __isl_take isl_val *v); + __isl_give isl_union_pw_multi_aff * + isl_union_pw_multi_aff_scale_down_val( + __isl_take isl_union_pw_multi_aff *upma, + __isl_take isl_val *val); + __isl_give isl_multi_union_pw_aff * + isl_multi_union_pw_aff_scale_down_val( + __isl_take isl_multi_union_pw_aff *mupa, + __isl_take isl_val *v); + + #include + __isl_give isl_qpolynomial *isl_qpolynomial_scale_val( + __isl_take isl_qpolynomial *qp, + __isl_take isl_val *v); + __isl_give isl_qpolynomial_fold * + isl_qpolynomial_fold_scale_val( + __isl_take isl_qpolynomial_fold *fold, + __isl_take isl_val *v); + __isl_give isl_pw_qpolynomial * + isl_pw_qpolynomial_scale_val( + __isl_take isl_pw_qpolynomial *pwqp, + __isl_take isl_val *v); + __isl_give isl_pw_qpolynomial_fold * + isl_pw_qpolynomial_fold_scale_val( + __isl_take isl_pw_qpolynomial_fold *pwf, + __isl_take isl_val *v); + __isl_give isl_union_pw_qpolynomial * + isl_union_pw_qpolynomial_scale_val( + __isl_take isl_union_pw_qpolynomial *upwqp, + __isl_take isl_val *v); + __isl_give isl_union_pw_qpolynomial_fold * + isl_union_pw_qpolynomial_fold_scale_val( + __isl_take isl_union_pw_qpolynomial_fold *upwf, + __isl_take isl_val *v); + __isl_give isl_qpolynomial * + isl_qpolynomial_scale_down_val( + __isl_take isl_qpolynomial *qp, + __isl_take isl_val *v); + __isl_give isl_qpolynomial_fold * + isl_qpolynomial_fold_scale_down_val( + __isl_take isl_qpolynomial_fold *fold, + __isl_take isl_val *v); + __isl_give isl_pw_qpolynomial * + isl_pw_qpolynomial_scale_down_val( + __isl_take isl_pw_qpolynomial *pwqp, + __isl_take isl_val *v); + __isl_give isl_pw_qpolynomial_fold * + isl_pw_qpolynomial_fold_scale_down_val( + __isl_take isl_pw_qpolynomial_fold *pwf, + __isl_take isl_val *v); + __isl_give isl_union_pw_qpolynomial * + isl_union_pw_qpolynomial_scale_down_val( + __isl_take isl_union_pw_qpolynomial *upwqp, + __isl_take isl_val *v); + __isl_give isl_union_pw_qpolynomial_fold * + isl_union_pw_qpolynomial_fold_scale_down_val( + __isl_take isl_union_pw_qpolynomial_fold *upwf, + __isl_take isl_val *v); + + #include + __isl_give isl_multi_val *isl_multi_val_mod_multi_val( + __isl_take isl_multi_val *mv1, + __isl_take isl_multi_val *mv2); + __isl_give isl_multi_val *isl_multi_val_scale_multi_val( + __isl_take isl_multi_val *mv1, + __isl_take isl_multi_val *mv2); + __isl_give isl_multi_val * + isl_multi_val_scale_down_multi_val( + __isl_take isl_multi_val *mv1, + __isl_take isl_multi_val *mv2); + + #include + __isl_give isl_multi_aff *isl_multi_aff_mod_multi_val( + __isl_take isl_multi_aff *ma, + __isl_take isl_multi_val *mv); + __isl_give isl_multi_union_pw_aff * + isl_multi_union_pw_aff_mod_multi_val( + __isl_take isl_multi_union_pw_aff *upma, + __isl_take isl_multi_val *mv); + __isl_give isl_multi_pw_aff * + isl_multi_pw_aff_mod_multi_val( + __isl_take isl_multi_pw_aff *mpa, + __isl_take isl_multi_val *mv); + __isl_give isl_multi_aff *isl_multi_aff_scale_multi_val( + __isl_take isl_multi_aff *ma, + __isl_take isl_multi_val *mv); + __isl_give isl_pw_multi_aff * + isl_pw_multi_aff_scale_multi_val( + __isl_take isl_pw_multi_aff *pma, + __isl_take isl_multi_val *mv); + __isl_give isl_multi_pw_aff * + isl_multi_pw_aff_scale_multi_val( + __isl_take isl_multi_pw_aff *mpa, + __isl_take isl_multi_val *mv); + __isl_give isl_multi_union_pw_aff * + isl_multi_union_pw_aff_scale_multi_val( + __isl_take isl_multi_union_pw_aff *mupa, + __isl_take isl_multi_val *mv); + __isl_give isl_union_pw_multi_aff * + isl_union_pw_multi_aff_scale_multi_val( + __isl_take isl_union_pw_multi_aff *upma, + __isl_take isl_multi_val *mv); + __isl_give isl_multi_aff * + isl_multi_aff_scale_down_multi_val( + __isl_take isl_multi_aff *ma, + __isl_take isl_multi_val *mv); + __isl_give isl_pw_multi_aff * + isl_pw_multi_aff_scale_down_multi_val( + __isl_take isl_pw_multi_aff *pma, + __isl_take isl_multi_val *mv); + __isl_give isl_multi_pw_aff * + isl_multi_pw_aff_scale_down_multi_val( + __isl_take isl_multi_pw_aff *mpa, + __isl_take isl_multi_val *mv); + __isl_give isl_multi_union_pw_aff * + isl_multi_union_pw_aff_scale_down_multi_val( + __isl_take isl_multi_union_pw_aff *mupa, + __isl_take isl_multi_val *mv); + +C scales the elements of C +by the corresponding elements of C. + + #include + __isl_give isl_aff *isl_aff_mul( + __isl_take isl_aff *aff1, + __isl_take isl_aff *aff2); + __isl_give isl_aff *isl_aff_div( + __isl_take isl_aff *aff1, + __isl_take isl_aff *aff2); + __isl_give isl_pw_aff *isl_pw_aff_mul( + __isl_take isl_pw_aff *pwaff1, + __isl_take isl_pw_aff *pwaff2); + __isl_give isl_pw_aff *isl_pw_aff_div( + __isl_take isl_pw_aff *pa1, + __isl_take isl_pw_aff *pa2); + __isl_give isl_pw_aff *isl_pw_aff_tdiv_q( + __isl_take isl_pw_aff *pa1, + __isl_take isl_pw_aff *pa2); + __isl_give isl_pw_aff *isl_pw_aff_tdiv_r( + __isl_take isl_pw_aff *pa1, + __isl_take isl_pw_aff *pa2); + +When multiplying two affine expressions, at least one of the two needs +to be a constant. Similarly, when dividing an affine expression by another, +the second expression needs to be a constant. +C computes the quotient of an integer division with +rounding towards zero. C computes the corresponding +remainder. + + #include + __isl_give isl_qpolynomial *isl_qpolynomial_mul( + __isl_take isl_qpolynomial *qp1, + __isl_take isl_qpolynomial *qp2); + __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_mul( + __isl_take isl_pw_qpolynomial *pwqp1, + __isl_take isl_pw_qpolynomial *pwqp2); + __isl_give isl_union_pw_qpolynomial *isl_union_pw_qpolynomial_mul( + __isl_take isl_union_pw_qpolynomial *upwqp1, + __isl_take isl_union_pw_qpolynomial *upwqp2); + +=back + +=head3 Lexicographic Optimization + +Given a (basic) set C (or C) and a zero-dimensional domain C, +the following functions +compute a set that contains the lexicographic minimum or maximum +of the elements in C (or C) for those values of the parameters +that satisfy C. +If C is not C, then C<*empty> is assigned a set +that contains the parameter values in C for which C (or C) +has no elements. +In other words, the union of the parameter values +for which the result is non-empty and of C<*empty> +is equal to C. + + #include + __isl_give isl_set *isl_basic_set_partial_lexmin( + __isl_take isl_basic_set *bset, + __isl_take isl_basic_set *dom, + __isl_give isl_set **empty); + __isl_give isl_set *isl_basic_set_partial_lexmax( + __isl_take isl_basic_set *bset, + __isl_take isl_basic_set *dom, + __isl_give isl_set **empty); + __isl_give isl_set *isl_set_partial_lexmin( + __isl_take isl_set *set, __isl_take isl_set *dom, + __isl_give isl_set **empty); + __isl_give isl_set *isl_set_partial_lexmax( + __isl_take isl_set *set, __isl_take isl_set *dom, + __isl_give isl_set **empty); + +Given a (basic) set C (or C), the following functions simply +return a set containing the lexicographic minimum or maximum +of the elements in C (or C). +In case of union sets, the optimum is computed per space. + + #include + __isl_give isl_set *isl_basic_set_lexmin( + __isl_take isl_basic_set *bset); + __isl_give isl_set *isl_basic_set_lexmax( + __isl_take isl_basic_set *bset); + __isl_give isl_set *isl_set_lexmin( + __isl_take isl_set *set); + __isl_give isl_set *isl_set_lexmax( + __isl_take isl_set *set); + __isl_give isl_union_set *isl_union_set_lexmin( + __isl_take isl_union_set *uset); + __isl_give isl_union_set *isl_union_set_lexmax( + __isl_take isl_union_set *uset); + +Given a (basic) relation C (or C) and a domain C, +the following functions +compute a relation that maps each element of C +to the single lexicographic minimum or maximum +of the elements that are associated to that same +element in C (or C). +If C is not C, then C<*empty> is assigned a set +that contains the elements in C that do not map +to any elements in C (or C). +In other words, the union of the domain of the result and of C<*empty> +is equal to C. + + #include + __isl_give isl_map *isl_basic_map_partial_lexmax( + __isl_take isl_basic_map *bmap, + __isl_take isl_basic_set *dom, + __isl_give isl_set **empty); + __isl_give isl_map *isl_basic_map_partial_lexmin( + __isl_take isl_basic_map *bmap, + __isl_take isl_basic_set *dom, + __isl_give isl_set **empty); + __isl_give isl_map *isl_map_partial_lexmax( + __isl_take isl_map *map, __isl_take isl_set *dom, + __isl_give isl_set **empty); + __isl_give isl_map *isl_map_partial_lexmin( + __isl_take isl_map *map, __isl_take isl_set *dom, + __isl_give isl_set **empty); + +Given a (basic) map C (or C), the following functions simply +return a map mapping each element in the domain of +C (or C) to the lexicographic minimum or maximum +of all elements associated to that element. +In case of union relations, the optimum is computed per space. + + #include + __isl_give isl_map *isl_basic_map_lexmin( + __isl_take isl_basic_map *bmap); + __isl_give isl_map *isl_basic_map_lexmax( + __isl_take isl_basic_map *bmap); + __isl_give isl_map *isl_map_lexmin( + __isl_take isl_map *map); + __isl_give isl_map *isl_map_lexmax( + __isl_take isl_map *map); + __isl_give isl_union_map *isl_union_map_lexmin( + __isl_take isl_union_map *umap); + __isl_give isl_union_map *isl_union_map_lexmax( + __isl_take isl_union_map *umap); + +The following functions return their result in the form of +a piecewise multi-affine expression, +but are otherwise equivalent to the corresponding functions +returning a basic set or relation. + + #include + __isl_give isl_pw_multi_aff * + isl_basic_set_partial_lexmin_pw_multi_aff( + __isl_take isl_basic_set *bset, + __isl_take isl_basic_set *dom, + __isl_give isl_set **empty); + __isl_give isl_pw_multi_aff * + isl_basic_set_partial_lexmax_pw_multi_aff( + __isl_take isl_basic_set *bset, + __isl_take isl_basic_set *dom, + __isl_give isl_set **empty); + __isl_give isl_pw_multi_aff *isl_set_lexmin_pw_multi_aff( + __isl_take isl_set *set); + __isl_give isl_pw_multi_aff *isl_set_lexmax_pw_multi_aff( + __isl_take isl_set *set); + + #include + __isl_give isl_pw_multi_aff * + isl_basic_map_lexmin_pw_multi_aff( + __isl_take isl_basic_map *bmap); + __isl_give isl_pw_multi_aff * + isl_basic_map_partial_lexmin_pw_multi_aff( + __isl_take isl_basic_map *bmap, + __isl_take isl_basic_set *dom, + __isl_give isl_set **empty); + __isl_give isl_pw_multi_aff * + isl_basic_map_partial_lexmax_pw_multi_aff( + __isl_take isl_basic_map *bmap, + __isl_take isl_basic_set *dom, + __isl_give isl_set **empty); + __isl_give isl_pw_multi_aff *isl_map_lexmin_pw_multi_aff( + __isl_take isl_map *map); + __isl_give isl_pw_multi_aff *isl_map_lexmax_pw_multi_aff( + __isl_take isl_map *map); + +The following functions return the lexicographic minimum or maximum +on the shared domain of the inputs and the single defined function +on those parts of the domain where only a single function is defined. + + #include + __isl_give isl_pw_multi_aff *isl_pw_multi_aff_union_lexmin( + __isl_take isl_pw_multi_aff *pma1, + __isl_take isl_pw_multi_aff *pma2); + __isl_give isl_pw_multi_aff *isl_pw_multi_aff_union_lexmax( + __isl_take isl_pw_multi_aff *pma1, + __isl_take isl_pw_multi_aff *pma2); + +If the input to a lexicographic optimization problem has +multiple constraints with the same coefficients for the optimized +variables, then, by default, this symmetry is exploited by +replacing those constraints by a single constraint with +an abstract bound, which is in turn bounded by the corresponding terms +in the original constraints. +Without this optimization, the solver would typically consider +all possible orderings of those original bounds, resulting in a needless +decomposition of the domain. +However, the optimization can also result in slowdowns since +an extra parameter is introduced that may get used in additional +integer divisions. +The following option determines whether symmetry detection is applied +during lexicographic optimization. + + #include + isl_stat isl_options_set_pip_symmetry(isl_ctx *ctx, + int val); + int isl_options_get_pip_symmetry(isl_ctx *ctx); + +=begin latex + +See also \autoref{s:offline}. + +=end latex + +=head2 Ternary Operations + + #include + __isl_give isl_pw_aff *isl_pw_aff_cond( + __isl_take isl_pw_aff *cond, + __isl_take isl_pw_aff *pwaff_true, + __isl_take isl_pw_aff *pwaff_false); + +The function C performs a conditional operator +and returns an expression that is equal to C +for elements where C is non-zero and equal to C for elements +where C is zero. + +=head2 Lists + +Lists are defined over several element types, including +C, C, C, C, C, +C, +C, +C, C, C, +C, +C, C, C, C, C, +C, C and C. +Here we take lists of Cs as an example. +Lists can be created, copied, modified and freed using the following functions. + + #include + __isl_give isl_set_list *isl_set_to_list( + __isl_take isl_set *el); + __isl_give isl_set_list *isl_set_list_from_set( + __isl_take isl_set *el); + __isl_give isl_set_list *isl_set_list_alloc( + isl_ctx *ctx, int n); + __isl_give isl_set_list *isl_set_list_copy( + __isl_keep isl_set_list *list); + __isl_give isl_set_list *isl_set_list_insert( + __isl_take isl_set_list *list, unsigned pos, + __isl_take isl_set *el); + __isl_give isl_set_list *isl_set_list_add( + __isl_take isl_set_list *list, + __isl_take isl_set *el); + __isl_give isl_set_list *isl_set_list_drop( + __isl_take isl_set_list *list, + unsigned first, unsigned n); + __isl_give isl_set_list *isl_set_list_clear( + __isl_take isl_set_list *list); + __isl_give isl_set_list *isl_set_list_swap( + __isl_take isl_set_list *list, + unsigned pos1, unsigned pos2); + __isl_give isl_set_list *isl_set_list_reverse( + __isl_take isl_set_list *list); + __isl_give isl_set_list *isl_set_list_set_at( + __isl_take isl_set_list *list, int index, + __isl_take isl_set *set); + __isl_give isl_set_list *isl_set_list_set_set( + __isl_take isl_set_list *list, int index, + __isl_take isl_set *set); + __isl_give isl_set_list *isl_set_list_concat( + __isl_take isl_set_list *list1, + __isl_take isl_set_list *list2); + __isl_give isl_set_list *isl_set_list_map( + __isl_take isl_set_list *list, + __isl_give isl_set *(*fn)(__isl_take isl_set *el, + void *user), + void *user); + __isl_give isl_set_list *isl_set_list_sort( + __isl_take isl_set_list *list, + int (*cmp)(__isl_keep isl_set *a, + __isl_keep isl_set *b, void *user), + void *user); + __isl_null isl_set_list *isl_set_list_free( + __isl_take isl_set_list *list); + +C creates an empty list with an initial capacity +for C elements. C and C +add elements to a list, increasing its capacity as needed. +C creates a list with a single element. +C performs the same operation. +C removes all elements from a list. +C swaps the elements at the specified locations. +C reverses the elements in the list. +C is an alternative name for C. + +Lists can be inspected using the following functions. + + #include + isl_size isl_set_list_size(__isl_keep isl_set_list *list); + isl_size isl_set_list_n_set(__isl_keep isl_set_list *list); + __isl_give isl_set *isl_set_list_get_at( + __isl_keep isl_set_list *list, int index); + __isl_give isl_set *isl_set_list_get_set( + __isl_keep isl_set_list *list, int index); + isl_stat isl_set_list_foreach(__isl_keep isl_set_list *list, + isl_stat (*fn)(__isl_take isl_set *el, void *user), + void *user); + isl_bool isl_set_list_every(__isl_keep isl_set_list *list, + isl_bool (*test)(__isl_take isl_set *el, + void *user), + void *user); + isl_stat isl_set_list_foreach_scc( + __isl_keep isl_set_list *list, + isl_bool (*follows)(__isl_keep isl_set *a, + __isl_keep isl_set *b, void *user), + void *follows_user, + isl_stat (*fn)(__isl_take isl_set_list *scc, + void *user), + void *fn_user); + +C is an alternative name for C. +Similarly, +C is an alternative name for C. +The function C calls C on each of the +strongly connected components of the graph with as vertices the elements +of C and a directed edge from vertex C to vertex C +iff C returns C. The callbacks C and +C should return C or C on error. + +Lists can be printed using + + #include + __isl_give isl_printer *isl_printer_print_set_list( + __isl_take isl_printer *p, + __isl_keep isl_set_list *list); + +Alternatively, a string representation can be obtained +directly using the following function, which always prints +in isl format. + + #include + __isl_give char *isl_set_list_to_str( + __isl_keep isl_set_list *list); + +An C, C, +C, C, C, +C, +C, C or C object +can also be read from input using the following functions. + + #include + __isl_give isl_val_list *isl_val_list_read_from_str( + isl_ctx *ctx, const char *str); + + #include + __isl_give isl_id_list *isl_id_list_read_from_str( + isl_ctx *ctx, const char *str); + + #include + __isl_give isl_aff_list * + isl_aff_list_read_from_str(isl_ctx *ctx, + const char *str); + __isl_give isl_pw_aff_list * + isl_pw_aff_list_read_from_str(isl_ctx *ctx, + const char *str); + __isl_give isl_pw_multi_aff_list * + isl_pw_multi_aff_list_read_from_str(isl_ctx *ctx, + const char *str); + __isl_give isl_union_pw_aff_list * + isl_union_pw_aff_list_read_from_str(isl_ctx *ctx, + const char *str); + + #include + __isl_give isl_set_list *isl_set_list_read_from_str( + isl_ctx *ctx, const char *str); + + #include + __isl_give isl_map_list *isl_map_list_read_from_str( + isl_ctx *ctx, const char *str); + + #include + __isl_give isl_union_set_list * + isl_union_set_list_read_from_str(isl_ctx *ctx, + const char *str); + +=head2 Associative arrays + +Associative arrays map isl objects of a specific type to isl objects +of some (other) specific type. They are defined for several pairs +of types, including (C, C), +(C, C), +(C, C) and +(C, C). +Here, we take associative arrays that map Cs to Cs +as an example. + +Associative arrays can be created, copied and freed using +the following functions. + + #include + __isl_give isl_id_to_ast_expr *isl_id_to_ast_expr_alloc( + isl_ctx *ctx, int min_size); + __isl_give isl_id_to_ast_expr *isl_id_to_ast_expr_copy( + __isl_keep isl_id_to_ast_expr *id2expr); + __isl_null isl_id_to_ast_expr *isl_id_to_ast_expr_free( + __isl_take isl_id_to_ast_expr *id2expr); + +The C argument to C can be used +to specify the expected size of the associative array. +The associative array will be grown automatically as needed. + +Associative arrays can be inspected using the following functions. + + #include + __isl_give isl_maybe_isl_ast_expr + isl_id_to_ast_expr_try_get( + __isl_keep isl_id_to_ast_expr *id2expr, + __isl_keep isl_id *key); + isl_bool isl_id_to_ast_expr_has( + __isl_keep isl_id_to_ast_expr *id2expr, + __isl_keep isl_id *key); + __isl_give isl_ast_expr *isl_id_to_ast_expr_get( + __isl_keep isl_id_to_ast_expr *id2expr, + __isl_take isl_id *key); + isl_stat isl_id_to_ast_expr_foreach( + __isl_keep isl_id_to_ast_expr *id2expr, + isl_stat (*fn)(__isl_take isl_id *key, + __isl_take isl_ast_expr *val, void *user), + void *user); + isl_bool isl_id_to_ast_expr_every( + __isl_keep isl_id_to_ast_expr *id2expr, + isl_bool (*test)(__isl_keep isl_id *key, + __isl_keep isl_ast_expr *val, void *user), + void *user); + +The function C returns a structure +containing two elements, C and C. +If there is a value associated to the key, then C +is set to C and C contains a copy of +the associated value. Otherwise C is C and +C may be C or C depending +on whether some error has occurred or there simply is no associated value. +The function C returns the C field +in the structure and +the function C returns the C field. + +Associative arrays can be modified using the following functions. + + #include + __isl_give isl_id_to_ast_expr *isl_id_to_ast_expr_set( + __isl_take isl_id_to_ast_expr *id2expr, + __isl_take isl_id *key, + __isl_take isl_ast_expr *val); + __isl_give isl_id_to_ast_expr *isl_id_to_ast_expr_drop( + __isl_take isl_id_to_ast_expr *id2expr, + __isl_take isl_id *key); + +Associative arrays can be checked for (obvious) equality +using the following function. + + #include + isl_bool isl_id_to_ast_expr_is_equal( + __isl_take isl_id_to_ast_expr *id2expr1, + __isl_take isl_id_to_ast_expr *id2expr2); + +Note that depending on how the keys and values are being compared, +for other types of keys and/or values, this function may be called +C rather than C. + +Associative arrays can be printed using the following functions. + + #include + __isl_give isl_printer *isl_printer_print_id_to_ast_expr( + __isl_take isl_printer *p, + __isl_keep isl_id_to_ast_expr *id2expr); + __isl_give char *isl_id_to_ast_expr_to_str( + __isl_keep isl_id_to_ast_expr *id2expr); + +They can be read from input using the following function. + + #include + __isl_give isl_id_to_ast_expr * + isl_id_to_ast_expr_read_from_str(isl_ctx *ctx, + const char *str); + +=head2 Vectors + +Vectors can be created, copied and freed using the following functions. + + #include + __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 vector created by C +may have arbitrary values. +A vector created by C has elements with value zero. +The elements can be changed and inspected using the following functions. + + isl_size isl_vec_size(__isl_keep isl_vec *vec); + __isl_give isl_val *isl_vec_get_element_val( + __isl_keep isl_vec *vec, int pos); + __isl_give isl_vec *isl_vec_set_element_si( + __isl_take isl_vec *vec, int pos, int v); + __isl_give isl_vec *isl_vec_set_element_val( + __isl_take isl_vec *vec, int pos, + __isl_take isl_val *v); + __isl_give isl_vec *isl_vec_set_si(__isl_take isl_vec *vec, + int v); + __isl_give isl_vec *isl_vec_set_val( + __isl_take isl_vec *vec, __isl_take isl_val *v); + int isl_vec_cmp_element(__isl_keep isl_vec *vec1, + __isl_keep isl_vec *vec2, int pos); + +C will return a negative value if anything went wrong. +In that case, the value of C<*v> is undefined. + +The following function can be used to concatenate two vectors. + + __isl_give isl_vec *isl_vec_concat(__isl_take isl_vec *vec1, + __isl_take isl_vec *vec2); + +=head2 Matrices + +Matrices can be created, copied and freed using the following functions. + + #include + __isl_give isl_mat *isl_mat_alloc(isl_ctx *ctx, + unsigned n_row, unsigned n_col); + __isl_give isl_mat *isl_mat_copy(__isl_keep isl_mat *mat); + __isl_null isl_mat *isl_mat_free(__isl_take isl_mat *mat); + +Note that the elements of a newly created matrix may have arbitrary values. +The elements can be changed and inspected using the following functions. + + isl_size isl_mat_rows(__isl_keep isl_mat *mat); + isl_size isl_mat_cols(__isl_keep isl_mat *mat); + __isl_give isl_val *isl_mat_get_element_val( + __isl_keep isl_mat *mat, int row, int col); + __isl_give isl_mat *isl_mat_set_element_si(__isl_take isl_mat *mat, + int row, int col, int v); + __isl_give isl_mat *isl_mat_set_element_val( + __isl_take isl_mat *mat, int row, int col, + __isl_take isl_val *v); + +The following function computes the rank of a matrix. +The return value may be -1 if some error occurred. + + #include + isl_size 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 +and the inverse (in that order) is a multiple of the identity matrix. +The input matrix is assumed to be of full row-rank. + + __isl_give isl_mat *isl_mat_right_inverse(__isl_take isl_mat *mat); + +The following function can be used to compute the (right) kernel +(or null space) of a matrix, i.e., a matrix such that the product of +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 +to a basis that also covers C. + + __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 +an upper or lower bound on a quasipolynomial over its domain. + + __isl_give isl_pw_qpolynomial_fold * + isl_pw_qpolynomial_bound( + __isl_take isl_pw_qpolynomial *pwqp, + enum isl_fold type, isl_bool *tight); + + __isl_give isl_union_pw_qpolynomial_fold * + isl_union_pw_qpolynomial_bound( + __isl_take isl_union_pw_qpolynomial *upwqp, + enum isl_fold type, isl_bool *tight); + +The C argument may be either C or C. +If C is not C, then C<*tight> is set to C<1> +is the returned bound is known be tight, i.e., for each value +of the parameters there is at least +one element in the domain that reaches the bound. +If the domain of C is not wrapping, then the bound is computed +over all elements in that domain and the result has a purely parametric +domain. If the domain of C is wrapping, then the bound is +computed over the range of the wrapped relation. The domain of the +wrapped relation becomes the domain of the result. + +=head2 Parametric Vertex Enumeration + +The parametric vertex enumeration described in this section +is mainly intended to be used internally and by the C +library. + + #include + __isl_give isl_vertices *isl_basic_set_compute_vertices( + __isl_keep isl_basic_set *bset); + +The function C performs the +actual computation of the parametric vertices and the chamber +decomposition and stores the result in an C object. +This information can be queried by either iterating over all +the vertices or iterating over all the chambers or cells +and then iterating over all vertices that are active on the chamber. + + isl_stat isl_vertices_foreach_vertex( + __isl_keep isl_vertices *vertices, + isl_stat (*fn)(__isl_take isl_vertex *vertex, + void *user), void *user); + + isl_stat isl_vertices_foreach_cell( + __isl_keep isl_vertices *vertices, + isl_stat (*fn)(__isl_take isl_cell *cell, + void *user), void *user); + isl_stat isl_cell_foreach_vertex(__isl_keep isl_cell *cell, + isl_stat (*fn)(__isl_take isl_vertex *vertex, + void *user), void *user); + +Other operations that can be performed on an C object are +the following. + + isl_size isl_vertices_get_n_vertices( + __isl_keep isl_vertices *vertices); + __isl_null isl_vertices *isl_vertices_free( + __isl_take isl_vertices *vertices); + +Vertices can be inspected and destroyed using the following functions. + + isl_size isl_vertex_get_id(__isl_keep isl_vertex *vertex); + __isl_give isl_basic_set *isl_vertex_get_domain( + __isl_keep isl_vertex *vertex); + __isl_give isl_multi_aff *isl_vertex_get_expr( + __isl_keep isl_vertex *vertex); + __isl_null isl_vertex *isl_vertex_free( + __isl_take isl_vertex *vertex); + +C returns a multiple quasi-affine expression +describing the vertex in terms of the parameters, +while C returns the activity domain +of the vertex. + +Chambers can be inspected and destroyed using the following functions. + + __isl_give isl_basic_set *isl_cell_get_domain( + __isl_keep isl_cell *cell); + __isl_null isl_cell *isl_cell_free( + __isl_take isl_cell *cell); + +=head1 Polyhedral Compilation Library + +This section collects functionality in C that has been specifically +designed for use during polyhedral compilation. + +=head2 Schedule Trees + +A schedule tree is a structured representation of a schedule, +assigning a relative order to a set of domain elements. +The relative order expressed by the schedule tree is +defined recursively. In particular, the order between +two domain elements is determined by the node that is closest +to the root that refers to both elements and that orders them apart. +Each node in the tree is of one of several types. +The root node is always of type C +(or C) +and it describes the (extra) domain elements to which the schedule applies. +The other types of nodes are as follows. + +=over + +=item C + +A band of schedule dimensions. Each schedule dimension is represented +by a union piecewise quasi-affine expression. If this expression +assigns a different value to two domain elements, while all previous +schedule dimensions in the same band assign them the same value, +then the two domain elements are ordered according to these two +different values. +Each expression is required to be total in the domain elements +that reach the band node. + +=item C + +An expansion node maps each of the domain elements that reach the node +to one or more domain elements. The image of this mapping forms +the set of domain elements that reach the child of the expansion node. +The function that maps each of the expanded domain elements +to the original domain element from which it was expanded +is called the contraction. + +=item C + +A filter node does not impose any ordering, but rather intersects +the set of domain elements that the current subtree refers to +with a given union set. The subtree of the filter node only +refers to domain elements in the intersection. +A filter node is typically only used as a child of a sequence or +set node. + +=item C + +A leaf of the schedule tree. Leaf nodes do not impose any ordering. + +=item C + +A mark node can be used to attach any kind of information to a subtree +of the schedule tree. + +=item C + +A sequence node has one or more children, each of which is a filter node. +The filters on these filter nodes form a partition of +the domain elements that the current subtree refers to. +If two domain elements appear in distinct filters then the sequence +node orders them according to the child positions of the corresponding +filter nodes. + +=item C + +A set node is similar to a sequence node, except that +it expresses that domain elements appearing in distinct filters +may have any order. The order of the children of a set node +is therefore also immaterial. + +=back + +The following node types are only supported by the AST generator. + +=over + +=item C + +The context describes constraints on the parameters and +the schedule dimensions of outer +bands that the AST generator may assume to hold. It is also the only +kind of node that may introduce additional parameters. +The space of the context 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. +Since a context node references the outer band nodes, any tree +containing a context node is considered to be anchored. + +=item C + +An extension node instructs the AST generator to add additional +domain elements that need to be scheduled. +The additional domain elements are described by the range of +the extension map in terms of the outer schedule dimensions, +i.e., the flat product of the outer band nodes. +Note that domain elements are added whenever the AST generator +reaches the extension node, meaning that there are still some +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 +using C or C. +In this case, the domain of the extension node should +correspond to the flat product of the outer band nodes +in this other schedule tree at the point where the extension tree +will be inserted. + +=item C + +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. +Since a guard node references the outer band nodes, any tree +containing a guard node is considered to be anchored. + +=back + +Except for the C nodes, +none of the nodes may introduce any parameters that were not +already present in the root domain node. + +A schedule tree is encapsulated in an C object. +The simplest such objects, those with a tree consisting of single domain node, +can be created using the following functions with either an empty +domain or a given domain. + + #include + __isl_give isl_schedule *isl_schedule_empty( + __isl_take isl_space *space); + __isl_give isl_schedule *isl_schedule_from_domain( + __isl_take isl_union_set *domain); + +The function C described +in L can also be used to construct schedules. + +C objects may be copied and freed using the following functions. + + #include + __isl_give isl_schedule *isl_schedule_copy( + __isl_keep isl_schedule *sched); + __isl_null isl_schedule *isl_schedule_free( + __isl_take isl_schedule *sched); + +The following functions checks whether two C objects +are obviously the same. + + #include + isl_bool isl_schedule_plain_is_equal( + __isl_keep isl_schedule *schedule1, + __isl_keep isl_schedule *schedule2); + +The domain of the schedule, i.e., the domain described by the root node, +can be obtained using the following function. + + #include + __isl_give isl_union_set *isl_schedule_get_domain( + __isl_keep isl_schedule *schedule); + +An extra top-level band node (right underneath the domain node) can +be introduced into the schedule using the following function. +The schedule tree is assumed not to have any anchored nodes. + + #include + __isl_give isl_schedule * + isl_schedule_insert_partial_schedule( + __isl_take isl_schedule *schedule, + __isl_take isl_multi_union_pw_aff *partial); + +A top-level context node (right underneath the domain node) can +be introduced into the schedule using the following function. + + #include + __isl_give isl_schedule *isl_schedule_insert_context( + __isl_take isl_schedule *schedule, + __isl_take isl_set *context) + +A top-level guard node (right underneath the domain node) can +be introduced into the schedule using the following function. + + #include + __isl_give isl_schedule *isl_schedule_insert_guard( + __isl_take isl_schedule *schedule, + __isl_take isl_set *guard) + +A schedule that combines two schedules either in the given +order or in an arbitrary order, i.e., with an C +or an C node, +can be created using the following functions. + + #include + __isl_give isl_schedule *isl_schedule_sequence( + __isl_take isl_schedule *schedule1, + __isl_take isl_schedule *schedule2); + __isl_give isl_schedule *isl_schedule_set( + __isl_take isl_schedule *schedule1, + __isl_take isl_schedule *schedule2); + +The domains of the two input schedules need to be disjoint. + +The following function can be used to restrict the domain +of a schedule with a domain node as root to be a subset of the given union set. +This operation may remove nodes in the tree that have become +redundant. + + #include + __isl_give isl_schedule *isl_schedule_intersect_domain( + __isl_take isl_schedule *schedule, + __isl_take isl_union_set *domain); + +The following function can be used to simplify the domain +of a schedule with a domain node as root with respect to the given +parameter domain. + + #include + __isl_give isl_schedule *isl_schedule_gist_domain_params( + __isl_take isl_schedule *schedule, + __isl_take isl_set *context); + +The following function resets the user pointers on all parameter +and tuple identifiers referenced by the nodes of the given schedule. + + #include + __isl_give isl_schedule *isl_schedule_reset_user( + __isl_take isl_schedule *schedule); + +The following function aligns the parameters of all nodes +in the given schedule to the given space. + + #include + __isl_give isl_schedule *isl_schedule_align_params( + __isl_take isl_schedule *schedule, + __isl_take isl_space *space); + +The following function allows the user to plug in a given function +in the iteration domains. The input schedule is not allowed to contain +any expansion nodes. + + #include + __isl_give isl_schedule * + isl_schedule_pullback_union_pw_multi_aff( + __isl_take isl_schedule *schedule, + __isl_take isl_union_pw_multi_aff *upma); + +The following function can be used to plug in the schedule C +in the leaves of C, where C describes how +the domain elements of C map to the domain elements +at the original leaves of C. +The resulting schedule will contain expansion nodes, unless +C is an identity function. + + #include + __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); + +An C representation of the schedule can be obtained +from an C using the following function. + + #include + __isl_give isl_union_map *isl_schedule_get_map( + __isl_keep isl_schedule *sched); + +The resulting relation encodes the same relative ordering as +the schedule by mapping the domain elements to a common schedule space. +If the schedule_separate_components option is set, then the order +of the children of a set node is explicitly encoded in the result. +If the tree contains any expansion nodes, then the relation +is formulated in terms of the expanded domain elements. + +Schedules can be read from input using the following functions. + + #include + __isl_give isl_schedule *isl_schedule_read_from_file( + isl_ctx *ctx, FILE *input); + __isl_give isl_schedule *isl_schedule_read_from_str( + isl_ctx *ctx, const char *str); + +A representation of the schedule can be printed using + + #include + __isl_give isl_printer *isl_printer_print_schedule( + __isl_take isl_printer *p, + __isl_keep isl_schedule *schedule); + __isl_give char *isl_schedule_to_str( + __isl_keep isl_schedule *schedule); + +C prints the schedule in flow format. + +The schedule tree can be traversed through the use of +C objects that point to a particular +position in the schedule tree. Whenever a C +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 then points to +this modified copy of the tree. + +The root of the schedule tree can be obtained using the following function. + + #include + __isl_give isl_schedule_node *isl_schedule_get_root( + __isl_keep isl_schedule *schedule); + +A pointer to a newly created schedule tree with a single domain +node can be created using the following functions. + + #include + __isl_give isl_schedule_node * + isl_schedule_node_from_domain( + __isl_take isl_union_set *domain); + __isl_give isl_schedule_node * + isl_schedule_node_from_extension( + __isl_take isl_union_map *extension); + +C creates a tree with an extension +node as root. + +Schedule nodes can be copied and freed using the following functions. + + #include + __isl_give isl_schedule_node *isl_schedule_node_copy( + __isl_keep isl_schedule_node *node); + __isl_null isl_schedule_node *isl_schedule_node_free( + __isl_take isl_schedule_node *node); + +The following functions can be used to check if two schedule +nodes point to the same position in the same schedule. + + #include + isl_bool isl_schedule_node_is_equal( + __isl_keep isl_schedule_node *node1, + __isl_keep isl_schedule_node *node2); + +The following properties can be obtained from a schedule node. + + #include + enum isl_schedule_node_type isl_schedule_node_get_type( + __isl_keep isl_schedule_node *node); + enum isl_schedule_node_type + isl_schedule_node_get_parent_type( + __isl_keep isl_schedule_node *node); + __isl_give isl_schedule *isl_schedule_node_get_schedule( + __isl_keep isl_schedule_node *node); + +The function C returns the type of +the node, while C returns +type of the parent of the node, which is required to exist. +The function C returns a copy +to the schedule to which the node belongs. + +The following functions can be used to move the schedule node +to a different position in the tree or to check if such a position +exists. + + #include + isl_bool isl_schedule_node_has_parent( + __isl_keep isl_schedule_node *node); + __isl_give isl_schedule_node *isl_schedule_node_parent( + __isl_take isl_schedule_node *node); + __isl_give isl_schedule_node * + isl_schedule_node_grandparent( + __isl_take isl_schedule_node *node); + __isl_give isl_schedule_node *isl_schedule_node_root( + __isl_take isl_schedule_node *node); + __isl_give isl_schedule_node *isl_schedule_node_ancestor( + __isl_take isl_schedule_node *node, + int generation); + isl_size isl_schedule_node_n_children( + __isl_keep isl_schedule_node *node); + __isl_give isl_schedule_node *isl_schedule_node_child( + __isl_take isl_schedule_node *node, int pos); + isl_bool isl_schedule_node_has_children( + __isl_keep isl_schedule_node *node); + __isl_give isl_schedule_node * + isl_schedule_node_grandchild( + __isl_take isl_schedule_node *node, + int pos1, int pos2); + __isl_give isl_schedule_node *isl_schedule_node_first_child( + __isl_take isl_schedule_node *node); + isl_bool isl_schedule_node_has_previous_sibling( + __isl_keep isl_schedule_node *node); + __isl_give isl_schedule_node * + isl_schedule_node_previous_sibling( + __isl_take isl_schedule_node *node); + isl_bool isl_schedule_node_has_next_sibling( + __isl_keep isl_schedule_node *node); + __isl_give isl_schedule_node * + isl_schedule_node_next_sibling( + __isl_take isl_schedule_node *node); + +For C, the ancestor of generation 0 +is the node itself, the ancestor of generation 1 is its parent and so on. + +It is also possible to query the number of ancestors of a node, +the position of the current node +within the children of its parent, the position of the subtree +containing a node within the children of an ancestor +or to obtain a copy of a given +child without destroying the current node. +Given two nodes that point to the same schedule, their closest +shared ancestor can be obtained using +C. + + #include + isl_size isl_schedule_node_get_tree_depth( + __isl_keep isl_schedule_node *node); + isl_size isl_schedule_node_get_child_position( + __isl_keep isl_schedule_node *node); + isl_size isl_schedule_node_get_ancestor_child_position( + __isl_keep isl_schedule_node *node, + __isl_keep isl_schedule_node *ancestor); + __isl_give isl_schedule_node *isl_schedule_node_get_child( + __isl_keep isl_schedule_node *node, int pos); + __isl_give isl_schedule_node * + isl_schedule_node_get_shared_ancestor( + __isl_keep isl_schedule_node *node1, + __isl_keep isl_schedule_node *node2); + +All nodes in a schedule tree or +all descendants of a specific node (including the node) can be visited +in depth-first pre-order using the following functions. + + #include + isl_stat isl_schedule_foreach_schedule_node_top_down( + __isl_keep isl_schedule *sched, + isl_bool (*fn)(__isl_keep isl_schedule_node *node, + void *user), void *user); + + #include + 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); + +The callback function is slightly different from the usual +callbacks in that it not only indicates success (non-negative result) +or failure (negative result), but also indicates whether the children +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_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. + + #include + 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), void *user); + +The following functions allows for a depth-first post-order +traversal of the nodes in a schedule tree or +of the descendants of a specific node (including the node +itself), where the user callback is allowed to modify the +visited node. + + #include + __isl_give isl_schedule * + isl_schedule_map_schedule_node_bottom_up( + __isl_take isl_schedule *schedule, + __isl_give isl_schedule_node *(*fn)( + __isl_take isl_schedule_node *node, + void *user), void *user); + + #include + __isl_give isl_schedule_node * + isl_schedule_node_map_descendant_bottom_up( + __isl_take isl_schedule_node *node, + __isl_give isl_schedule_node *(*fn)( + __isl_take isl_schedule_node *node, + void *user), void *user); + +The traversal continues from the node returned by the callback function. +It is the responsibility of the user to ensure that this does not +lead to an infinite loop. It is safest to always return a pointer +to the same position (same ancestors and child positions) as the input node. + +The following function removes a node (along with its descendants) +from a schedule tree and returns a pointer to the leaf at the +same position in the updated tree. +It is not allowed to remove the root of a schedule tree or +a child of a set or sequence node. + + #include + __isl_give isl_schedule_node *isl_schedule_node_cut( + __isl_take isl_schedule_node *node); + +The following function removes a single node +from a schedule tree and returns a pointer to the child +of the node, now located at the position of the original node +or to a leaf node at that position if there was no child. +It is not allowed to remove the root of a schedule tree, +a set or sequence node, a child of a set or sequence node or +a band node with an anchored subtree. + + #include + __isl_give isl_schedule_node *isl_schedule_node_delete( + __isl_take isl_schedule_node *node); + +Most nodes in a schedule tree only contain local information. +In some cases, however, a node may also refer to the schedule dimensions +of its outer band nodes. +This means that the position of the node within the tree should +not be changed, or at least that no changes are performed to the +outer band nodes. The following function can be used to test +whether the subtree rooted at a given node contains any such nodes. + + #include + isl_bool isl_schedule_node_is_subtree_anchored( + __isl_keep isl_schedule_node *node); + +The following function resets the user pointers on all parameter +and tuple identifiers referenced by the given schedule node. + + #include + __isl_give isl_schedule_node *isl_schedule_node_reset_user( + __isl_take isl_schedule_node *node); + +The following function aligns the parameters of the given schedule +node to the given space. + + #include + __isl_give isl_schedule_node * + isl_schedule_node_align_params( + __isl_take isl_schedule_node *node, + __isl_take isl_space *space); + +Several node types have their own functions for querying +(and in some cases setting) some node type specific properties. + + #include + __isl_give isl_space *isl_schedule_node_band_get_space( + __isl_keep isl_schedule_node *node); + __isl_give isl_multi_union_pw_aff * + isl_schedule_node_band_get_partial_schedule( + __isl_keep isl_schedule_node *node); + __isl_give isl_union_map * + isl_schedule_node_band_get_partial_schedule_union_map( + __isl_keep isl_schedule_node *node); + isl_size isl_schedule_node_band_n_member( + __isl_keep isl_schedule_node *node); + isl_bool isl_schedule_node_band_member_get_coincident( + __isl_keep isl_schedule_node *node, int pos); + __isl_give isl_schedule_node * + isl_schedule_node_band_member_set_coincident( + __isl_take isl_schedule_node *node, int pos, + int coincident); + isl_bool isl_schedule_node_band_get_permutable( + __isl_keep isl_schedule_node *node); + __isl_give isl_schedule_node * + isl_schedule_node_band_set_permutable( + __isl_take isl_schedule_node *node, int permutable); + enum isl_ast_loop_type + isl_schedule_node_band_member_get_ast_loop_type( + __isl_keep isl_schedule_node *node, int pos); + __isl_give isl_schedule_node * + isl_schedule_node_band_member_set_ast_loop_type( + __isl_take isl_schedule_node *node, int pos, + enum isl_ast_loop_type type); + enum isl_ast_loop_type + isl_schedule_node_band_member_get_isolate_ast_loop_type( + __isl_keep isl_schedule_node *node, int pos); + __isl_give isl_schedule_node * + isl_schedule_node_band_member_set_isolate_ast_loop_type( + __isl_take isl_schedule_node *node, int pos, + enum isl_ast_loop_type type); + __isl_give isl_union_set * + isl_schedule_node_band_get_ast_build_options( + __isl_keep isl_schedule_node *node); + __isl_give isl_schedule_node * + isl_schedule_node_band_set_ast_build_options( + __isl_take isl_schedule_node *node, + __isl_take isl_union_set *options); + __isl_give isl_set * + isl_schedule_node_band_get_ast_isolate_option( + __isl_keep isl_schedule_node *node); + +The function C returns the space +of the partial schedule of the band. +The function C +returns a representation of the partial schedule of the band node +in the form of an C. +The coincident and permutable properties are set by +C on the schedule tree +it produces. +A scheduling dimension is considered to be ``coincident'' +if it satisfies the coincidence constraints within its band. +That is, if the dependence distances of the coincidence +constraints are all zero in that direction (for fixed +iterations of outer bands). +A band is marked permutable if it was produced using the Pluto-like scheduler. +Note that the scheduler may have to resort to a Feautrier style scheduling +step even if the default scheduler is used. +An C is one of C, +C, C or C. +For the meaning of these loop AST generation types and the difference +between the regular loop AST generation type and the isolate +loop AST generation type, see L. +The functions C +and C +may return C if an error occurs. +The AST build options govern how an AST is generated for +the individual schedule dimensions during AST generation. +See L. +The isolate option for the given node can be extracted from these +AST build options using the function +C. + + #include + __isl_give isl_set * + isl_schedule_node_context_get_context( + __isl_keep isl_schedule_node *node); + + #include + __isl_give isl_union_set * + isl_schedule_node_domain_get_domain( + __isl_keep isl_schedule_node *node); + + #include + __isl_give isl_union_map * + isl_schedule_node_expansion_get_expansion( + __isl_keep isl_schedule_node *node); + __isl_give isl_union_pw_multi_aff * + isl_schedule_node_expansion_get_contraction( + __isl_keep isl_schedule_node *node); + + #include + __isl_give isl_union_map * + isl_schedule_node_extension_get_extension( + __isl_keep isl_schedule_node *node); + + #include + __isl_give isl_union_set * + isl_schedule_node_filter_get_filter( + __isl_keep isl_schedule_node *node); + + #include + __isl_give isl_set *isl_schedule_node_guard_get_guard( + __isl_keep isl_schedule_node *node); + + #include + __isl_give isl_id *isl_schedule_node_mark_get_id( + __isl_keep isl_schedule_node *node); + +The following functions can be used to obtain an C, +an C or C representation of +partial schedules related to the node. + + #include + __isl_give isl_multi_union_pw_aff * + isl_schedule_node_get_prefix_schedule_multi_union_pw_aff( + __isl_keep isl_schedule_node *node); + __isl_give isl_union_pw_multi_aff * + isl_schedule_node_get_prefix_schedule_union_pw_multi_aff( + __isl_keep isl_schedule_node *node); + __isl_give isl_union_map * + isl_schedule_node_get_prefix_schedule_union_map( + __isl_keep isl_schedule_node *node); + __isl_give isl_union_map * + isl_schedule_node_get_prefix_schedule_relation( + __isl_keep isl_schedule_node *node); + __isl_give isl_union_map * + isl_schedule_node_get_subtree_schedule_union_map( + __isl_keep isl_schedule_node *node); + +In particular, the functions +C, +C +and C +return a relative ordering on the domain elements that reach the given +node determined by its ancestors. +The function C +additionally includes the domain constraints in the result. +The function C +returns a representation of the partial schedule defined by the +subtree rooted at the given node. +If the tree contains any expansion nodes, then the subtree schedule +is formulated in terms of the expanded domain elements. +The tree passed to functions returning a prefix schedule +may only contain extension nodes if these would not affect +the result of these functions. That is, if one of the ancestors +is an extension node, then all of the domain elements that were +added by the extension node need to have been filtered out +by filter nodes between the extension node and the input node. +The tree passed to C +may not contain in extension nodes in the selected subtree. + +The expansion/contraction defined by an entire subtree, combining +the expansions/contractions +on the expansion nodes in the subtree, can be obtained using +the following functions. + + #include + __isl_give isl_union_map * + isl_schedule_node_get_subtree_expansion( + __isl_keep isl_schedule_node *node); + __isl_give isl_union_pw_multi_aff * + isl_schedule_node_get_subtree_contraction( + __isl_keep isl_schedule_node *node); + +The total number of outer band members of given node, i.e., +the shared output dimension of the maps in the result +of C can be obtained +using the following function. + + #include + isl_size isl_schedule_node_get_schedule_depth( + __isl_keep isl_schedule_node *node); + +The following functions return the elements that reach the given node +or the union of universes in the spaces that contain these elements. + + #include + __isl_give isl_union_set * + isl_schedule_node_get_domain( + __isl_keep isl_schedule_node *node); + __isl_give isl_union_set * + isl_schedule_node_get_universe_domain( + __isl_keep isl_schedule_node *node); + +The input tree of C +may only contain extension nodes if these would not affect +the result of this function. That is, if one of the ancestors +is an extension node, then all of the domain elements that were +added by the extension node need to have been filtered out +by filter nodes between the extension node and the input node. + +The following functions can be used to introduce additional nodes +in the schedule tree. The new node is introduced at the point +in the tree where the C points to and +the results points to the new node. + + #include + __isl_give isl_schedule_node * + isl_schedule_node_insert_partial_schedule( + __isl_take isl_schedule_node *node, + __isl_take isl_multi_union_pw_aff *schedule); + +This function inserts a new band node with (the greatest integer +part of) the given partial schedule. +The subtree rooted at the given node is assumed not to have +any anchored nodes. + + #include + __isl_give isl_schedule_node * + isl_schedule_node_insert_context( + __isl_take isl_schedule_node *node, + __isl_take isl_set *context); + +This function inserts a new context node with the given context constraints. + + #include + __isl_give isl_schedule_node * + isl_schedule_node_insert_filter( + __isl_take isl_schedule_node *node, + __isl_take isl_union_set *filter); + +This function inserts a new filter node with the given filter. +If the original node already pointed to a filter node, then the +two filter nodes are merged into one. + + #include + __isl_give isl_schedule_node * + isl_schedule_node_insert_guard( + __isl_take isl_schedule_node *node, + __isl_take isl_set *guard); + +This function inserts a new guard node with the given guard constraints. + + #include + __isl_give isl_schedule_node * + isl_schedule_node_insert_mark( + __isl_take isl_schedule_node *node, + __isl_take isl_id *mark); + +This function inserts a new mark node with the give mark identifier. + + #include + __isl_give isl_schedule_node * + isl_schedule_node_insert_sequence( + __isl_take isl_schedule_node *node, + __isl_take isl_union_set_list *filters); + __isl_give isl_schedule_node * + isl_schedule_node_insert_set( + __isl_take isl_schedule_node *node, + __isl_take isl_union_set_list *filters); + +These functions insert a new sequence or set node with the given +filters as children. + + #include + __isl_give isl_schedule_node *isl_schedule_node_group( + __isl_take isl_schedule_node *node, + __isl_take isl_id *group_id); + +This function introduces an expansion node in between the current +node and its parent that expands instances of a space with tuple +identifier C to the original domain elements that reach +the node. The group instances are identified by the prefix schedule +of those domain elements. The ancestors of the node are adjusted +to refer to the group instances instead of the original domain +elements. The return value points to the same node in the updated +schedule tree as the input node, i.e., to the child of the newly +introduced expansion node. Grouping instances of different statements +ensures that they will be treated as a single statement by the +AST generator up to the point of the expansion node. + +The following functions can be used to flatten a nested +sequence. + + #include + __isl_give isl_schedule_node * + isl_schedule_node_sequence_splice_child( + __isl_take isl_schedule_node *node, int pos); + __isl_give isl_schedule_node * + isl_schedule_node_sequence_splice_children( + __isl_take isl_schedule_node *node); + +That is, given a sequence node C that has another sequence node +in its child at position C (in particular, the child of that filter +node is a sequence node), the function +C +attaches the children of that other sequence +node as children of C, replacing the original child at position +C. +C does this for all +such children. + +The partial schedule of a band node can be scaled (down) or reduced using +the following functions. + + #include + __isl_give isl_schedule_node * + isl_schedule_node_band_scale( + __isl_take isl_schedule_node *node, + __isl_take isl_multi_val *mv); + __isl_give isl_schedule_node * + isl_schedule_node_band_scale_down( + __isl_take isl_schedule_node *node, + __isl_take isl_multi_val *mv); + __isl_give isl_schedule_node * + isl_schedule_node_band_mod( + __isl_take isl_schedule_node *node, + __isl_take isl_multi_val *mv); + +The spaces of the two arguments need to match. +After scaling, the partial schedule is replaced by its greatest +integer part to ensure that the schedule remains integral. + +The partial schedule of a band node can be shifted by an +C with a domain that is a superset +of the domain of the partial schedule using +the following function. + + #include + __isl_give isl_schedule_node * + isl_schedule_node_band_shift( + __isl_take isl_schedule_node *node, + __isl_take isl_multi_union_pw_aff *shift); + +A band node can be tiled using the following function. + + #include + __isl_give isl_schedule_node *isl_schedule_node_band_tile( + __isl_take isl_schedule_node *node, + __isl_take isl_multi_val *sizes); + + 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); + +The C function tiles +the band using the given tile sizes inside its schedule. +A new child band node is created to represent the point loops and it is +inserted between the modified band and its children. +The subtree rooted at the given node is assumed not to have +any anchored nodes. +The C option specifies whether the tile +loops iterators should be scaled by the tile sizes. +If the C option is set, then the point loops +are shifted to start at zero. + +A band node can be split into two nested band nodes +using the following function. + + #include + __isl_give isl_schedule_node *isl_schedule_node_band_split( + __isl_take isl_schedule_node *node, int pos); + +The resulting outer band node contains the first C dimensions of +the schedule of C 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 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. + + #include + __isl_give isl_schedule_node *isl_schedule_node_band_sink( + __isl_take isl_schedule_node *node); + +The subtree rooted at the given node is assumed not to have +any anchored nodes. +The result points to the node in the resulting tree that is in the same +position as the node pointed to by C in the original tree. + + #include + __isl_give isl_schedule_node * + isl_schedule_node_order_before( + __isl_take isl_schedule_node *node, + __isl_take isl_union_set *filter); + __isl_give isl_schedule_node * + isl_schedule_node_order_after( + __isl_take isl_schedule_node *node, + __isl_take isl_union_set *filter); + +These functions split the domain elements that reach C +into those that satisfy C and those that do not and +arranges for the elements that do satisfy the filter to be +executed before (in case of C) +or after (in case of C) +those that do not. The order is imposed by +a sequence node, possibly reusing the grandparent of C +on two copies of the subtree attached to the original C. +Both copies are simplified with respect to their filter. + +Return a pointer to the copy of the subtree that does not +satisfy C. If there is no such copy (because all +reaching domain elements satisfy the filter), then return +the original pointer. + + #include + __isl_give isl_schedule_node * + isl_schedule_node_graft_before( + __isl_take isl_schedule_node *node, + __isl_take isl_schedule_node *graft); + __isl_give isl_schedule_node * + isl_schedule_node_graft_after( + __isl_take isl_schedule_node *node, + __isl_take isl_schedule_node *graft); + +This function inserts the C tree into the tree containing C +such that it is executed before (in case of C) +or after (in case of C) C. +The root node of C +should be an extension node where the domain of the extension +is the flat product of all outer band nodes of C. +The root node may also be a domain node. +The elements of the domain or the range of the extension may not +intersect with the domain elements that reach "node". +The schedule tree of C may not be anchored. + +The schedule tree of C is modified to include an extension node +corresponding to the root node of C as a child of the original +parent of C. The original node that C points to and the +child of the root node of C are attached to this extension node +through a sequence, with appropriate filters and with the child +of C appearing before or after the original C. + +If C already appears inside a sequence that is the child of +an extension node and if the spaces of the new domain elements +do not overlap with those of the original domain elements, +then that extension node is extended with the new extension +rather than introducing a new segment of extension and sequence nodes. + +Return a pointer to the same node in the modified tree that +C pointed to in the original tree. + +A representation of the schedule node can be printed using + + #include + __isl_give isl_printer *isl_printer_print_schedule_node( + __isl_take isl_printer *p, + __isl_keep isl_schedule_node *node); + __isl_give char *isl_schedule_node_to_str( + __isl_keep isl_schedule_node *node); + +C prints the schedule node in block format. + +=head2 Dependence Analysis + +C contains specialized functionality for performing +array dataflow analysis. That is, given a I access relation, +a collection of possible I accesses and +a collection of I accesses, +C can compute relations that describe +for each iteration of the sink access, which iterations +of which of the source access relations may have +accessed the same data element before the given iteration +of the sink access without any intermediate kill of that data element. +The resulting dependence relations map source iterations +to either the corresponding sink iterations or +pairs of corresponding sink iterations and accessed data elements. +To compute standard flow dependences, the sink should be +a read, while the sources should be writes. +If no kills are specified, +then memory based dependence analysis is performed. +If, on the other hand, all sources are also kills, +then value based dependence analysis is performed. +If any of the source accesses are marked as being I +accesses, then they are also treated as kills. +Furthermore, the specification of must-sources results +in the computation of must-dependences. +Only dependences originating in a must access not coscheduled +with any other access to the same element and without +any may accesses between the must access and the sink access +are considered to be must dependences. + +=head3 High-level Interface + +A high-level interface to dependence analysis is provided +by the following function. + + #include + __isl_give isl_union_flow * + isl_union_access_info_compute_flow( + __isl_take isl_union_access_info *access); + +The input C object describes the sink +access relations, the source access relations and a schedule, +while the output C object describes +the resulting dependence relations and the subsets of the +sink relations for which no source was found. + +An C is created, modified, copied and freed using +the following functions. + + #include + __isl_give isl_union_access_info * + isl_union_access_info_from_sink( + __isl_take isl_union_map *sink); + __isl_give isl_union_access_info * + isl_union_access_info_set_kill( + __isl_take isl_union_access_info *access, + __isl_take isl_union_map *kill); + __isl_give isl_union_access_info * + isl_union_access_info_set_may_source( + __isl_take isl_union_access_info *access, + __isl_take isl_union_map *may_source); + __isl_give isl_union_access_info * + isl_union_access_info_set_must_source( + __isl_take isl_union_access_info *access, + __isl_take isl_union_map *must_source); + __isl_give isl_union_access_info * + isl_union_access_info_set_schedule( + __isl_take isl_union_access_info *access, + __isl_take isl_schedule *schedule); + __isl_give isl_union_access_info * + isl_union_access_info_set_schedule_map( + __isl_take isl_union_access_info *access, + __isl_take isl_union_map *schedule_map); + __isl_give isl_union_access_info * + isl_union_access_info_copy( + __isl_keep isl_union_access_info *access); + __isl_null isl_union_access_info * + isl_union_access_info_free( + __isl_take isl_union_access_info *access); + +The may sources set by C +do not need to include the must sources set by +C as a subset. +The kills set by C may overlap +with the may-sources and/or must-sources. +The user is free not to call one (or more) of these functions, +in which case the corresponding set is kept to its empty default. +Similarly, the default schedule initialized by +C is empty. +The current schedule is determined by the last call to either +C or +C. +The domain of the schedule corresponds to the domains of +the access relations. In particular, the domains of the access +relations are effectively intersected with the domain of the schedule +and only the resulting accesses are considered by the dependence analysis. + +An C object can be read from input +using the following function. + + #include + __isl_give isl_union_access_info * + isl_union_access_info_read_from_file(isl_ctx *ctx, + FILE *input); + +A representation of the information contained in an object +of type C can be obtained using + + #include + __isl_give isl_printer * + isl_printer_print_union_access_info( + __isl_take isl_printer *p, + __isl_keep isl_union_access_info *access); + __isl_give char *isl_union_access_info_to_str( + __isl_keep isl_union_access_info *access); + +C prints the information in flow format. + +The output of C can be examined, +copied, and freed using the following functions. + + #include + __isl_give isl_union_map *isl_union_flow_get_must_dependence( + __isl_keep isl_union_flow *flow); + __isl_give isl_union_map *isl_union_flow_get_may_dependence( + __isl_keep isl_union_flow *flow); + __isl_give isl_union_map * + isl_union_flow_get_full_must_dependence( + __isl_keep isl_union_flow *flow); + __isl_give isl_union_map * + isl_union_flow_get_full_may_dependence( + __isl_keep isl_union_flow *flow); + __isl_give isl_union_map *isl_union_flow_get_must_no_source( + __isl_keep isl_union_flow *flow); + __isl_give isl_union_map *isl_union_flow_get_may_no_source( + __isl_keep isl_union_flow *flow); + __isl_give isl_union_flow *isl_union_flow_copy( + __isl_keep isl_union_flow *flow); + __isl_null isl_union_flow *isl_union_flow_free( + __isl_take isl_union_flow *flow); + +The relation returned by C +relates domain elements of must sources to domain elements of the sink. +The relation returned by C +relates domain elements of must or may sources to domain elements of the sink +and includes the previous relation as a subset. +The relation returned by C +relates domain elements of must sources to pairs of domain elements of the sink +and accessed data elements. +The relation returned by C +relates domain elements of must or may sources to pairs of +domain elements of the sink and accessed data elements. +This relation includes the previous relation as a subset. +The relation returned by C is the subset +of the sink relation for which no dependences have been found. +The relation returned by C is the subset +of the sink relation for which no definite dependences have been found. +That is, it contains those sink access that do not contribute to any +of the elements in the relation returned +by C. + +A representation of the information contained in an object +of type C can be obtained using + + #include + __isl_give isl_printer *isl_printer_print_union_flow( + __isl_take isl_printer *p, + __isl_keep isl_union_flow *flow); + __isl_give char *isl_union_flow_to_str( + __isl_keep isl_union_flow *flow); + +C prints the information in flow format. + +=head3 Low-level Interface + +A lower-level interface is provided by the following functions. + + #include + + typedef int (*isl_access_level_before)(void *first, void *second); + + __isl_give isl_access_info *isl_access_info_alloc( + __isl_take isl_map *sink, + void *sink_user, isl_access_level_before fn, + int max_source); + __isl_give isl_access_info *isl_access_info_add_source( + __isl_take isl_access_info *acc, + __isl_take isl_map *source, int must, + void *source_user); + __isl_null isl_access_info *isl_access_info_free( + __isl_take isl_access_info *acc); + + __isl_give isl_flow *isl_access_info_compute_flow( + __isl_take isl_access_info *acc); + + isl_stat isl_flow_foreach(__isl_keep isl_flow *deps, + isl_stat (*fn)(__isl_take isl_map *dep, int must, + void *dep_user, void *user), + void *user); + __isl_give isl_map *isl_flow_get_no_source( + __isl_keep isl_flow *deps, int must); + __isl_null isl_flow *isl_flow_free( + __isl_take isl_flow *deps); + +The function C performs the actual +dependence analysis. The other functions are used to construct +the input for this function or to read off the output. + +The input is collected in an C, which can +be created through a call to C. +The arguments to this functions are the sink access relation +C, a token C used to identify the sink +access to the user, a callback function for specifying the +relative order of source and sink accesses, and the number +of source access relations that will be added. + +The callback function has type C. +The function is called with two user supplied tokens identifying +either a source or the sink and it should return the shared nesting +level and the relative order of the two accesses. +In particular, let I be the number of loops shared by +the two accesses. If C precedes C textually, +then the function should return I<2 * n + 1>; otherwise, +it should return I<2 * n>. +The low-level interface assumes that no sources are coscheduled. +If the information returned by the callback does not allow +the relative order to be determined, then one of the sources +is arbitrarily taken to be executed after the other(s). + +The sources can be added to the C object by performing +(at most) C calls to C. +C indicates whether the source is a I access +or a I access. Note that a multi-valued access relation +should only be marked I if every iteration in the domain +of the relation accesses I elements in its image. +The C token is again used to identify +the source access. The range of the source access relation +C should have the same dimension as the range +of the sink access relation. +The C function should usually not be +called explicitly, because it is already called implicitly by +C. + +The result of the dependence analysis is collected in an +C. There may be elements of +the sink access for which no preceding source access could be +found or for which all preceding sources are I accesses. +The relations containing these elements can be obtained through +calls to C, the first with C set +and the second with C unset. +In the case of standard flow dependence analysis, +with the sink a read and the sources I writes, +the first relation corresponds to the reads from uninitialized +array elements and the second relation is empty. +The actual flow dependences can be extracted using +C. This function will call the user-specified +callback function C for each B dependence between +a source and the sink. The callback function is called +with four arguments, the actual flow dependence relation +mapping source iterations to sink iterations, a boolean that +indicates whether it is a I or I dependence, a token +identifying the source and an additional C with value +equal to the third argument of the C call. +A dependence is marked I if it originates from a I +source and if it is not followed by any I sources. + +After finishing with an C, the user should call +C to free all associated memory. + +=head3 Interaction with the Low-level Interface + +During the dependence analysis, we frequently need to perform +the following operation. Given a relation between sink iterations +and potential source iterations from a particular source domain, +what is the last potential source iteration corresponding to each +sink iteration. It can sometimes be convenient to adjust +the set of potential source iterations before or after each such operation. +The prototypical example is fuzzy array dataflow analysis, +where we need to analyze if, based on data-dependent constraints, +the sink iteration can ever be executed without one or more of +the corresponding potential source iterations being executed. +If so, we can introduce extra parameters and select an unknown +but fixed source iteration from the potential source iterations. +To be able to perform such manipulations, C provides the following +function. + + #include + + typedef __isl_give isl_restriction *(*isl_access_restrict)( + __isl_keep isl_map *source_map, + __isl_keep isl_set *sink, void *source_user, + void *user); + __isl_give isl_access_info *isl_access_info_set_restrict( + __isl_take isl_access_info *acc, + isl_access_restrict fn, void *user); + +The function C should be called +before calling C and registers a callback function +that will be called any time C is about to compute the last +potential source. The first argument is the (reverse) proto-dependence, +mapping sink iterations to potential source iterations. +The second argument represents the sink iterations for which +we want to compute the last source iteration. +The third argument is the token corresponding to the source +and the final argument is the token passed to C. +The callback is expected to return a restriction on either the input or +the output of the operation computing the last potential source. +If the input needs to be restricted then restrictions are needed +for both the source and the sink iterations. The sink iterations +and the potential source iterations will be intersected with these sets. +If the output needs to be restricted then only a restriction on the source +iterations is required. +If any error occurs, the callback should return C. +An C object can be created, freed and inspected +using the following functions. + + #include + + __isl_give isl_restriction *isl_restriction_input( + __isl_take isl_set *source_restr, + __isl_take isl_set *sink_restr); + __isl_give isl_restriction *isl_restriction_output( + __isl_take isl_set *source_restr); + __isl_give isl_restriction *isl_restriction_none( + __isl_take isl_map *source_map); + __isl_give isl_restriction *isl_restriction_empty( + __isl_take isl_map *source_map); + __isl_null isl_restriction *isl_restriction_free( + __isl_take isl_restriction *restr); + +C and C are special +cases of C. C +is essentially equivalent to + + isl_restriction_input(isl_set_universe( + isl_space_range(isl_map_get_space(source_map))), + isl_set_universe( + isl_space_domain(isl_map_get_space(source_map)))); + +whereas C is essentially equivalent to + + isl_restriction_input(isl_set_empty( + isl_space_range(isl_map_get_space(source_map))), + isl_set_universe( + isl_space_domain(isl_map_get_space(source_map)))); + +=head2 Scheduling + + #include + __isl_give isl_schedule * + isl_schedule_constraints_compute_schedule( + __isl_take isl_schedule_constraints *sc); + +The function C can be +used to compute a schedule that satisfies the given schedule constraints. +These schedule constraints include the iteration domain for which +a schedule should be computed and dependences between pairs of +iterations. In particular, these dependences include +I dependences and I dependences. +By default, the algorithm used to construct the schedule is similar +to that of C. +Alternatively, Feautrier's multi-dimensional scheduling algorithm can +be selected. +The generated schedule respects all validity dependences. +That is, all dependence distances over these dependences in the +scheduled space are lexicographically positive. + +The default algorithm tries to ensure that the dependence distances +over coincidence constraints are zero and to minimize the +dependence distances over proximity dependences. +Moreover, it tries to obtain sequences (bands) of schedule dimensions +for groups of domains where the dependence distances over validity +dependences have only non-negative values. +Note that when minimizing the maximal dependence distance +over proximity dependences, a single affine expression in the parameters +is constructed that bounds all dependence distances. If no such expression +exists, then the algorithm will fail and resort to an alternative +scheduling algorithm. In particular, this means that adding proximity +dependences may eliminate valid solutions. A typical example where this +phenomenon may occur is when some subset of the proximity dependences +has no restriction on some parameter, forcing the coefficient of that +parameter to be zero, while some other subset forces the dependence +distance to depend on that parameter, requiring the same coefficient +to be non-zero. +When using Feautrier's algorithm, the coincidence and proximity constraints +are only taken into account during the extension to a +full-dimensional schedule. + +An C object can be constructed +and manipulated using the following functions. + + #include + __isl_give isl_schedule_constraints * + isl_schedule_constraints_copy( + __isl_keep isl_schedule_constraints *sc); + __isl_give isl_schedule_constraints * + isl_schedule_constraints_on_domain( + __isl_take isl_union_set *domain); + __isl_give isl_schedule_constraints * + isl_schedule_constraints_set_context( + __isl_take isl_schedule_constraints *sc, + __isl_take isl_set *context); + __isl_give isl_schedule_constraints * + isl_schedule_constraints_set_validity( + __isl_take isl_schedule_constraints *sc, + __isl_take isl_union_map *validity); + __isl_give isl_schedule_constraints * + isl_schedule_constraints_set_coincidence( + __isl_take isl_schedule_constraints *sc, + __isl_take isl_union_map *coincidence); + __isl_give isl_schedule_constraints * + isl_schedule_constraints_set_proximity( + __isl_take isl_schedule_constraints *sc, + __isl_take isl_union_map *proximity); + __isl_give isl_schedule_constraints * + isl_schedule_constraints_set_conditional_validity( + __isl_take isl_schedule_constraints *sc, + __isl_take isl_union_map *condition, + __isl_take isl_union_map *validity); + __isl_give isl_schedule_constraints * + isl_schedule_constraints_apply( + __isl_take isl_schedule_constraints *sc, + __isl_take isl_union_map *umap); + __isl_null isl_schedule_constraints * + isl_schedule_constraints_free( + __isl_take isl_schedule_constraints *sc); + +The initial C object created by +C does not impose any constraints. +That is, it has an empty set of dependences. +The function C allows the user +to specify additional constraints on the parameters that may +be assumed to hold during the construction of the schedule. +The function C replaces the +validity dependences, mapping domain elements I to domain +elements that should be scheduled after I. +The function C replaces the +coincidence dependences, mapping domain elements I to domain +elements that should be scheduled together with I, if possible. +The function C replaces the +proximity dependences, mapping domain elements I to domain +elements that should be scheduled either before I +or as early as possible after I. + +The function C +replaces the conditional validity constraints. +A conditional validity constraint is only imposed when any of the corresponding +conditions is satisfied, i.e., when any of them is non-zero. +That is, the scheduler ensures that within each band if the dependence +distances over the condition constraints are not all zero +then all corresponding conditional validity constraints are respected. +A conditional validity constraint corresponds to a condition +if the two are adjacent, i.e., if the domain of one relation intersect +the range of the other relation. +The typical use case of conditional validity constraints is +to allow order constraints between live ranges to be violated +as long as the live ranges themselves are local to the band. +To allow more fine-grained control over which conditions correspond +to which conditional validity constraints, the domains and ranges +of these relations may include I. That is, the domains and +ranges of those relation may themselves be wrapped relations +where the iteration domain appears in the domain of those wrapped relations +and the range of the wrapped relations can be arbitrarily chosen +by the user. Conditions and conditional validity constraints are only +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 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. + +An C object can be inspected +using the following functions. + + #include + __isl_give isl_union_set * + isl_schedule_constraints_get_domain( + __isl_keep isl_schedule_constraints *sc); + __isl_give isl_set *isl_schedule_constraints_get_context( + __isl_keep isl_schedule_constraints *sc); + __isl_give isl_union_map * + isl_schedule_constraints_get_validity( + __isl_keep isl_schedule_constraints *sc); + __isl_give isl_union_map * + isl_schedule_constraints_get_coincidence( + __isl_keep isl_schedule_constraints *sc); + __isl_give isl_union_map * + isl_schedule_constraints_get_proximity( + __isl_keep isl_schedule_constraints *sc); + __isl_give isl_union_map * + isl_schedule_constraints_get_conditional_validity( + __isl_keep isl_schedule_constraints *sc); + __isl_give isl_union_map * + isl_schedule_constraints_get_conditional_validity_condition( + __isl_keep isl_schedule_constraints *sc); + +An C object can be read from input +using the following functions. + + #include + __isl_give isl_schedule_constraints * + isl_schedule_constraints_read_from_str(isl_ctx *ctx, + const char *str); + __isl_give isl_schedule_constraints * + isl_schedule_constraints_read_from_file(isl_ctx *ctx, + FILE *input); + +The contents of an C object can be printed +using the following functions. + + #include + __isl_give isl_printer * + isl_printer_print_schedule_constraints( + __isl_take isl_printer *p, + __isl_keep isl_schedule_constraints *sc); + __isl_give char *isl_schedule_constraints_to_str( + __isl_keep isl_schedule_constraints *sc); + +The following function computes a schedule directly from +an iteration domain and validity and proximity dependences +and is implemented in terms of the functions described above. +The use of C is discouraged. + + #include + __isl_give isl_schedule *isl_union_set_compute_schedule( + __isl_take isl_union_set *domain, + __isl_take isl_union_map *validity, + __isl_take isl_union_map *proximity); + +The generated schedule represents a schedule tree. +For more information on schedule trees, see +L. + +=head3 Options + + #include + isl_stat isl_options_set_schedule_max_coefficient( + isl_ctx *ctx, int val); + int isl_options_get_schedule_max_coefficient( + isl_ctx *ctx); + isl_stat isl_options_set_schedule_max_constant_term( + isl_ctx *ctx, int val); + int isl_options_get_schedule_max_constant_term( + isl_ctx *ctx); + isl_stat isl_options_set_schedule_serialize_sccs( + isl_ctx *ctx, int val); + int isl_options_get_schedule_serialize_sccs(isl_ctx *ctx); + isl_stat isl_options_set_schedule_whole_component( + isl_ctx *ctx, int val); + int isl_options_get_schedule_whole_component( + isl_ctx *ctx); + isl_stat isl_options_set_schedule_maximize_band_depth( + isl_ctx *ctx, int val); + int isl_options_get_schedule_maximize_band_depth( + isl_ctx *ctx); + isl_stat isl_options_set_schedule_maximize_coincidence( + isl_ctx *ctx, int val); + int isl_options_get_schedule_maximize_coincidence( + isl_ctx *ctx); + isl_stat isl_options_set_schedule_outer_coincidence( + isl_ctx *ctx, int val); + int isl_options_get_schedule_outer_coincidence( + isl_ctx *ctx); + isl_stat isl_options_set_schedule_split_scaled( + isl_ctx *ctx, int val); + int isl_options_get_schedule_split_scaled( + isl_ctx *ctx); + isl_stat isl_options_set_schedule_treat_coalescing( + isl_ctx *ctx, int val); + int isl_options_get_schedule_treat_coalescing( + isl_ctx *ctx); + isl_stat isl_options_set_schedule_algorithm( + isl_ctx *ctx, int val); + int isl_options_get_schedule_algorithm( + isl_ctx *ctx); + isl_stat isl_options_set_schedule_carry_self_first( + isl_ctx *ctx, int val); + int isl_options_get_schedule_carry_self_first( + isl_ctx *ctx); + isl_stat isl_options_set_schedule_separate_components( + isl_ctx *ctx, int val); + int isl_options_get_schedule_separate_components( + isl_ctx *ctx); + +=over + +=item * schedule_max_coefficient + +This option enforces that the coefficients for variable and parameter +dimensions in the calculated schedule are not larger than the specified value. +This option can significantly increase the speed of the scheduling calculation +and may also prevent fusing of unrelated dimensions. A value of -1 means that +this option does not introduce bounds on the variable or parameter +coefficients. +This option has no effect on the Feautrier style scheduler. + +=item * schedule_max_constant_term + +This option enforces that the constant coefficients in the calculated schedule +are not larger than the maximal constant term. This option can significantly +increase the speed of the scheduling calculation and may also prevent fusing of +unrelated dimensions. A value of -1 means that this option does not introduce +bounds on the constant coefficients. + +=item * schedule_serialize_sccs + +If this option is set, then all strongly connected components +in the dependence graph are serialized as soon as they are detected. +This means in particular that instances of statements will only +appear in the same band node if these statements belong +to the same strongly connected component at the point where +the band node is constructed. + +=item * schedule_whole_component + +If this option is set, then entire (weakly) connected +components in the dependence graph are scheduled together +as a whole. +Otherwise, each strongly connected component within +such a weakly connected component is first scheduled separately +and then combined with other strongly connected components. +This option has no effect if C is set. + +=item * schedule_maximize_band_depth + +If this option is set, then the scheduler tries to maximize +the width of the bands. Wider bands give more possibilities for tiling. +In particular, if the C option is set, +then bands are split if this might result in wider bands. +Otherwise, the effect of this option is to only allow +strongly connected components to be combined if this does +not reduce the width of the bands. +Note that if the C options is set, then +the C option therefore has no effect. + +=item * schedule_maximize_coincidence + +This option is only effective if the C +option is turned off. +If the C option is set, then (clusters of) +strongly connected components are only combined with each other +if this does not reduce the number of coincident band members. + +=item * schedule_outer_coincidence + +If this option is set, then we try to construct schedules +where the outermost scheduling dimension in each band +satisfies the coincidence constraints. + +=item * schedule_algorithm + +Selects the scheduling algorithm to be used. +Available scheduling algorithms are C +and C. + +=item * schedule_split_scaled + +If this option is set, then we try to construct schedules in which the +constant term is split off from the linear part if the linear parts of +the scheduling rows for all nodes in the graph have a common non-trivial +divisor. +The constant term is then dropped and the linear +part is reduced. +This option is only effective when the Feautrier style scheduler is +being used, either as the main scheduler or as a fallback for the +Pluto-like scheduler. + +=item * schedule_treat_coalescing + +If this option is set, then the scheduler will try and avoid +producing schedules that perform loop coalescing. +In particular, for the Pluto-like scheduler, this option places +bounds on the schedule coefficients based on the sizes of the instance sets. +For the Feautrier style scheduler, this option detects potentially +coalescing schedules and then tries to adjust the schedule to avoid +the coalescing. + +=item * schedule_carry_self_first + +If this option is set, then the Feautrier style scheduler +(when used as a fallback for the Pluto-like scheduler) will +first try to only carry self-dependences. + +=item * schedule_separate_components + +If this option is set then the function C +will treat set nodes in the same way as sequence nodes. + +=back + +=head2 AST Generation + +This section describes the C functionality for generating +ASTs that visit all the elements +in a domain in an order specified by a schedule tree or +a schedule map. +In case the schedule given as a C, an AST is generated +that visits all the elements in the domain of the C +according to the lexicographic order of the corresponding image +element(s). If the range of the C consists of +elements in more than one space, then each of these spaces is handled +separately in an arbitrary order. +It should be noted that the schedule tree or the image elements +in a schedule map only specify the I +in which the corresponding domain elements should be visited. +No direct relation between the partial schedule values +or the image elements on the one hand and the loop iterators +in the generated AST on the other hand should be assumed. + +Each AST is generated within a build. The initial build +simply specifies the constraints on the parameters (if any) +and can be created, inspected, copied and freed using the following functions. + + #include + __isl_give isl_ast_build *isl_ast_build_alloc( + isl_ctx *ctx); + __isl_give isl_ast_build *isl_ast_build_from_context( + __isl_take isl_set *set); + __isl_give isl_ast_build *isl_ast_build_copy( + __isl_keep isl_ast_build *build); + __isl_null isl_ast_build *isl_ast_build_free( + __isl_take isl_ast_build *build); + +The C argument is usually a parameter set with zero or more parameters. +In fact, when creating an AST using C, +this set is required to be a parameter set. +An C created using C does not +specify any parameter constraints. +More C functions are described in L +and L. +Finally, the AST itself can be constructed using one of the following +functions. + + #include + __isl_give isl_ast_node *isl_ast_build_node_from_schedule( + __isl_keep isl_ast_build *build, + __isl_take isl_schedule *schedule); + __isl_give isl_ast_node * + isl_ast_build_node_from_schedule_map( + __isl_keep isl_ast_build *build, + __isl_take isl_union_map *schedule); + +=head3 Inspecting the AST + +The basic properties of an AST node can be obtained as follows. + + #include + enum isl_ast_node_type isl_ast_node_get_type( + __isl_keep isl_ast_node *node); + +The type of an AST node is one of +C, +C, +C, +C or +C. +An C represents a for node. +An C represents an if node. +An C represents a compound node. +An C introduces a mark in the AST. +An C represents an expression statement. +An expression statement typically corresponds to a domain element, i.e., +one of the elements that is visited by the AST. + +Each type of node has its own additional properties. + + #include + __isl_give isl_ast_expr *isl_ast_node_for_get_iterator( + __isl_keep isl_ast_node *node); + __isl_give isl_ast_expr *isl_ast_node_for_get_init( + __isl_keep isl_ast_node *node); + __isl_give isl_ast_expr *isl_ast_node_for_get_cond( + __isl_keep isl_ast_node *node); + __isl_give isl_ast_expr *isl_ast_node_for_get_inc( + __isl_keep isl_ast_node *node); + __isl_give isl_ast_node *isl_ast_node_for_get_body( + __isl_keep isl_ast_node *node); + isl_bool isl_ast_node_for_is_degenerate( + __isl_keep isl_ast_node *node); + +An C is considered degenerate if it is known to execute +exactly once. + + #include + __isl_give isl_ast_expr *isl_ast_node_if_get_cond( + __isl_keep isl_ast_node *node); + __isl_give isl_ast_node *isl_ast_node_if_get_then_node( + __isl_keep isl_ast_node *node); + __isl_give isl_ast_node *isl_ast_node_if_get_then( + __isl_keep isl_ast_node *node); + isl_bool isl_ast_node_if_has_else_node( + __isl_keep isl_ast_node *node); + isl_bool isl_ast_node_if_has_else( + __isl_keep isl_ast_node *node); + __isl_give isl_ast_node *isl_ast_node_if_get_else_node( + __isl_keep isl_ast_node *node); + __isl_give isl_ast_node *isl_ast_node_if_get_else( + __isl_keep isl_ast_node *node); + +C, +C and +C +are alternative names for +C, +C and +C, respectively. + + __isl_give isl_ast_node_list * + isl_ast_node_block_get_children( + __isl_keep isl_ast_node *node); + + __isl_give isl_id *isl_ast_node_mark_get_id( + __isl_keep isl_ast_node *node); + __isl_give isl_ast_node *isl_ast_node_mark_get_node( + __isl_keep isl_ast_node *node); + +C returns the identifier of the mark. +C returns the child node that is being marked. + + #include + __isl_give isl_ast_expr *isl_ast_node_user_get_expr( + __isl_keep isl_ast_node *node); + +All descendants of a specific node in the AST (including the node itself) +can be visited +in depth-first pre-order using the following function. + + #include + isl_stat isl_ast_node_foreach_descendant_top_down( + __isl_keep isl_ast_node *node, + isl_bool (*fn)(__isl_keep isl_ast_node *node, + void *user), void *user); + +The callback function should return C if the children +of the given node should be visited and C if they should not. +It should return C in case of failure, in which case +the entire traversal is aborted. + +Each of the returned Cs can in turn be inspected using +the following functions. + + #include + enum isl_ast_expr_type isl_ast_expr_get_type( + __isl_keep isl_ast_expr *expr); + +The type of an AST expression is one of +C, +C or +C. +An C represents the result of an operation. +An C represents an identifier. +An C represents an integer value. + +Each type of expression has its own additional properties. + + #include + enum isl_ast_expr_op_type isl_ast_expr_op_get_type( + __isl_keep isl_ast_expr *expr); + enum isl_ast_expr_op_type isl_ast_expr_get_op_type( + __isl_keep isl_ast_expr *expr); + isl_size isl_ast_expr_op_get_n_arg(__isl_keep isl_ast_expr *expr); + isl_size isl_ast_expr_get_op_n_arg(__isl_keep isl_ast_expr *expr); + __isl_give isl_ast_expr *isl_ast_expr_op_get_arg( + __isl_keep isl_ast_expr *expr, int pos); + __isl_give isl_ast_expr *isl_ast_expr_get_op_arg( + __isl_keep isl_ast_expr *expr, int pos); + isl_stat isl_ast_expr_foreach_ast_expr_op_type( + __isl_keep isl_ast_expr *expr, + isl_stat (*fn)(enum isl_ast_expr_op_type type, + void *user), void *user); + isl_stat isl_ast_expr_foreach_ast_op_type( + __isl_keep isl_ast_expr *expr, + isl_stat (*fn)(enum isl_ast_expr_op_type type, + void *user), void *user); + isl_stat isl_ast_node_foreach_ast_expr_op_type( + __isl_keep isl_ast_node *node, + isl_stat (*fn)(enum isl_ast_expr_op_type type, + void *user), void *user); + isl_stat isl_ast_node_foreach_ast_op_type( + __isl_keep isl_ast_node *node, + isl_stat (*fn)(enum isl_ast_expr_op_type type, + void *user), void *user); + +C returns the type of the operation +performed. C returns the number of +arguments. C returns the specified +argument. +C is an alternative name for +C. +Similarly, +C is an alternative name for +C and +C is an alternative name for +C. + +C calls C for each distinct +C that appears in C. +C is an alternative name for +C. +C does the same for each distinct +C that appears in C. +C is an alternative name for +C. +The operation type is one of the following. + +=over + +=item C + +Logical I of two arguments. +Both arguments can be evaluated. + +=item C + +Logical I of two arguments. +The second argument can only be evaluated if the first evaluates to true. + +=item C + +Logical I of two arguments. +Both arguments can be evaluated. + +=item C + +Logical I of two arguments. +The second argument can only be evaluated if the first evaluates to false. + +=item C + +Maximum of two or more arguments. + +=item C + +Minimum of two or more arguments. + +=item C + +Change sign. + +=item C + +Sum of two arguments. + +=item C + +Difference of two arguments. + +=item C + +Product of two arguments. + +=item C + +Exact division. That is, the result is known to be an integer. + +=item C + +Result of integer division, rounded towards negative +infinity. +The divisor is known to be positive. + +=item C + +Result of integer division, where dividend is known to be non-negative. +The divisor is known to be positive. + +=item C + +Remainder of integer division, where dividend is known to be non-negative. +The divisor is known to be positive. + +=item C + +Equal to zero iff the remainder on integer division is zero. +The divisor is known to be positive. + +=item C + +Conditional operator defined on three arguments. +If the first argument evaluates to true, then the result +is equal to the second argument. Otherwise, the result +is equal to the third argument. +The second and third argument may only be evaluated if +the first argument evaluates to true and false, respectively. +Corresponds to C in C. + +=item C + +Conditional operator defined on three arguments. +If the first argument evaluates to true, then the result +is equal to the second argument. Otherwise, the result +is equal to the third argument. +The second and third argument may be evaluated independently +of the value of the first argument. +Corresponds to C in C. + +=item C + +Equality relation. + +=item C + +Less than or equal relation. + +=item C + +Less than relation. + +=item C + +Greater than or equal relation. + +=item C + +Greater than relation. + +=item C + +A function call. +The number of arguments of the C is one more than +the number of arguments in the function call, the first argument +representing the function being called. + +=item C + +An array access. +The number of arguments of the C is one more than +the number of index expressions in the array access, the first argument +representing the array being accessed. + +=item C + +A member access. +This operation has two arguments, a structure and the name of +the member of the structure being accessed. + +=item C + +The address of its single argument, which is always an array access. + +=back + + #include + __isl_give isl_id *isl_ast_expr_id_get_id( + __isl_keep isl_ast_expr *expr); + __isl_give isl_id *isl_ast_expr_get_id( + __isl_keep isl_ast_expr *expr); + +Return the identifier represented by the AST expression. +C is an alternative name for +C. + + #include + __isl_give isl_val *isl_ast_expr_int_get_val( + __isl_keep isl_ast_expr *expr); + __isl_give isl_val *isl_ast_expr_get_val( + __isl_keep isl_ast_expr *expr); + +Return the integer represented by the AST expression. +C is an alternative name for +C. + +=head3 Properties of ASTs + + #include + isl_bool isl_ast_expr_is_equal( + __isl_keep isl_ast_expr *expr1, + __isl_keep isl_ast_expr *expr2); + +Check if two Cs are equal to each other. + +=head3 Manipulating and printing the AST + +AST nodes can be copied and freed using the following functions. + + #include + __isl_give isl_ast_node *isl_ast_node_copy( + __isl_keep isl_ast_node *node); + __isl_null isl_ast_node *isl_ast_node_free( + __isl_take isl_ast_node *node); + +AST expressions can be copied and freed using the following functions. + + #include + __isl_give isl_ast_expr *isl_ast_expr_copy( + __isl_keep isl_ast_expr *expr); + __isl_null isl_ast_expr *isl_ast_expr_free( + __isl_take isl_ast_expr *expr); + +New AST expressions can be created either directly or within +the context of an C. + + #include + __isl_give isl_ast_expr *isl_ast_expr_from_val( + __isl_take isl_val *v); + __isl_give isl_ast_expr *isl_ast_expr_from_id( + __isl_take isl_id *id); + __isl_give isl_ast_expr *isl_ast_expr_neg( + __isl_take isl_ast_expr *expr); + __isl_give isl_ast_expr *isl_ast_expr_address_of( + __isl_take isl_ast_expr *expr); + __isl_give isl_ast_expr *isl_ast_expr_add( + __isl_take isl_ast_expr *expr1, + __isl_take isl_ast_expr *expr2); + __isl_give isl_ast_expr *isl_ast_expr_sub( + __isl_take isl_ast_expr *expr1, + __isl_take isl_ast_expr *expr2); + __isl_give isl_ast_expr *isl_ast_expr_mul( + __isl_take isl_ast_expr *expr1, + __isl_take isl_ast_expr *expr2); + __isl_give isl_ast_expr *isl_ast_expr_div( + __isl_take isl_ast_expr *expr1, + __isl_take isl_ast_expr *expr2); + __isl_give isl_ast_expr *isl_ast_expr_pdiv_q( + __isl_take isl_ast_expr *expr1, + __isl_take isl_ast_expr *expr2); + __isl_give isl_ast_expr *isl_ast_expr_pdiv_r( + __isl_take isl_ast_expr *expr1, + __isl_take isl_ast_expr *expr2); + __isl_give isl_ast_expr *isl_ast_expr_and( + __isl_take isl_ast_expr *expr1, + __isl_take isl_ast_expr *expr2) + __isl_give isl_ast_expr *isl_ast_expr_and_then( + __isl_take isl_ast_expr *expr1, + __isl_take isl_ast_expr *expr2) + __isl_give isl_ast_expr *isl_ast_expr_or( + __isl_take isl_ast_expr *expr1, + __isl_take isl_ast_expr *expr2) + __isl_give isl_ast_expr *isl_ast_expr_or_else( + __isl_take isl_ast_expr *expr1, + __isl_take isl_ast_expr *expr2) + __isl_give isl_ast_expr *isl_ast_expr_eq( + __isl_take isl_ast_expr *expr1, + __isl_take isl_ast_expr *expr2); + __isl_give isl_ast_expr *isl_ast_expr_le( + __isl_take isl_ast_expr *expr1, + __isl_take isl_ast_expr *expr2); + __isl_give isl_ast_expr *isl_ast_expr_lt( + __isl_take isl_ast_expr *expr1, + __isl_take isl_ast_expr *expr2); + __isl_give isl_ast_expr *isl_ast_expr_ge( + __isl_take isl_ast_expr *expr1, + __isl_take isl_ast_expr *expr2); + __isl_give isl_ast_expr *isl_ast_expr_gt( + __isl_take isl_ast_expr *expr1, + __isl_take isl_ast_expr *expr2); + __isl_give isl_ast_expr *isl_ast_expr_access( + __isl_take isl_ast_expr *array, + __isl_take isl_ast_expr_list *indices); + __isl_give isl_ast_expr *isl_ast_expr_call( + __isl_take isl_ast_expr *function, + __isl_take isl_ast_expr_list *arguments); + +The function C can be applied to an +C of type C only. It is meant +to represent the address of the C. +The second argument of the functions C and +C should always evaluate to a positive number. +The function +C as well as C are short-circuit +versions of C and C, respectively. + + #include + __isl_give isl_ast_expr *isl_ast_build_expr_from_set( + __isl_keep isl_ast_build *build, + __isl_take isl_set *set); + __isl_give isl_ast_expr *isl_ast_build_expr_from_pw_aff( + __isl_keep isl_ast_build *build, + __isl_take isl_pw_aff *pa); + __isl_give isl_ast_expr * + isl_ast_build_access_from_pw_multi_aff( + __isl_keep isl_ast_build *build, + __isl_take isl_pw_multi_aff *pma); + __isl_give isl_ast_expr * + isl_ast_build_access_from_multi_pw_aff( + __isl_keep isl_ast_build *build, + __isl_take isl_multi_pw_aff *mpa); + __isl_give isl_ast_expr * + isl_ast_build_call_from_pw_multi_aff( + __isl_keep isl_ast_build *build, + __isl_take isl_pw_multi_aff *pma); + __isl_give isl_ast_expr * + isl_ast_build_call_from_multi_pw_aff( + __isl_keep isl_ast_build *build, + __isl_take isl_multi_pw_aff *mpa); + +The set C and +the domains of C, C and C should correspond +to the schedule space of C. +The tuple id of C or C is used as the array being accessed or +the function being called. +If the accessed space is a nested relation, then it is taken +to represent an access of the member specified by the range +of this nested relation of the structure specified by the domain +of the nested relation. + +The following functions can be used to modify an C. + + #include + __isl_give isl_ast_expr *isl_ast_expr_set_op_arg( + __isl_take isl_ast_expr *expr, int pos, + __isl_take isl_ast_expr *arg); + +Replace the argument of C at position C by C. + + #include + __isl_give isl_ast_expr *isl_ast_expr_substitute_ids( + __isl_take isl_ast_expr *expr, + __isl_take isl_id_to_ast_expr *id2expr); + +The function C replaces the +subexpressions of C of type C +by the corresponding expression in C, if there is any. + + +The following function can be used to modify the descendants +of a specific node in an AST using a depth-first post-order +traversal of those descendants (including the node itself). + + #include + __isl_give isl_ast_node * + isl_ast_node_map_descendant_bottom_up( + __isl_take isl_ast_node *node, + __isl_give isl_ast_node *(*fn)( + __isl_take isl_ast_node *node, + void *user), void *user); + +User specified data can be attached to an C and obtained +from the same C using the following functions. + + #include + __isl_give isl_ast_node *isl_ast_node_set_annotation( + __isl_take isl_ast_node *node, + __isl_take isl_id *annotation); + __isl_give isl_id *isl_ast_node_get_annotation( + __isl_keep isl_ast_node *node); + +Basic printing can be performed using the following functions. + + #include + __isl_give isl_printer *isl_printer_print_ast_expr( + __isl_take isl_printer *p, + __isl_keep isl_ast_expr *expr); + __isl_give isl_printer *isl_printer_print_ast_node( + __isl_take isl_printer *p, + __isl_keep isl_ast_node *node); + __isl_give char *isl_ast_expr_to_str( + __isl_keep isl_ast_expr *expr); + __isl_give char *isl_ast_node_to_str( + __isl_keep isl_ast_node *node); + __isl_give char *isl_ast_expr_to_C_str( + __isl_keep isl_ast_expr *expr); + __isl_give char *isl_ast_node_to_C_str( + __isl_keep isl_ast_node *node); + +The functions C and +C are convenience functions +that return a string representation of the input in C format. + +More advanced printing can be performed using the following functions. + + #include + __isl_give isl_printer * + isl_ast_expr_op_type_set_print_name( + __isl_take isl_printer *p, + enum isl_ast_expr_op_type type, + __isl_keep const char *name); + __isl_give isl_printer *isl_ast_op_type_set_print_name( + __isl_take isl_printer *p, + enum isl_ast_expr_op_type type, + __isl_keep const char *name); + isl_stat isl_options_set_ast_print_macro_once( + isl_ctx *ctx, int val); + int isl_options_get_ast_print_macro_once(isl_ctx *ctx); + __isl_give isl_printer *isl_ast_expr_op_type_print_macro( + enum isl_ast_expr_op_type type, + __isl_take isl_printer *p); + __isl_give isl_printer *isl_ast_op_type_print_macro( + enum isl_ast_expr_op_type type, + __isl_take isl_printer *p); + __isl_give isl_printer *isl_ast_expr_print_macros( + __isl_keep isl_ast_expr *expr, + __isl_take isl_printer *p); + __isl_give isl_printer *isl_ast_node_print_macros( + __isl_keep isl_ast_node *node, + __isl_take isl_printer *p); + __isl_give isl_printer *isl_ast_node_print( + __isl_keep isl_ast_node *node, + __isl_take isl_printer *p, + __isl_take isl_ast_print_options *options); + __isl_give isl_printer *isl_ast_node_for_print( + __isl_keep isl_ast_node *node, + __isl_take isl_printer *p, + __isl_take isl_ast_print_options *options); + __isl_give isl_printer *isl_ast_node_if_print( + __isl_keep isl_ast_node *node, + __isl_take isl_printer *p, + __isl_take isl_ast_print_options *options); + +While printing an C in C, +C may print out an AST that makes use of macros such +as C, C and C. +The names of these macros may be modified by a call +to C. The user-specified +names are associated to the printer object. +C is an alternative name for +C. +C prints out the macro +corresponding to a specific C. +If the print-macro-once option is set, then a given macro definition +is only printed once to any given printer object. +C is an alternative name for +C. +C scans the C +for subexpressions where these macros would be used and prints +out the required macro definitions. +Essentially, C calls +C with +C +as function argument. +C does the same +for expressions in its C argument. +C, C and +C print an C +in C, but allow for some extra control +through an C object. +This object can be created using the following functions. + + #include + __isl_give isl_ast_print_options * + isl_ast_print_options_alloc(isl_ctx *ctx); + __isl_give isl_ast_print_options * + isl_ast_print_options_copy( + __isl_keep isl_ast_print_options *options); + __isl_null isl_ast_print_options * + isl_ast_print_options_free( + __isl_take isl_ast_print_options *options); + + __isl_give isl_ast_print_options * + isl_ast_print_options_set_print_user( + __isl_take isl_ast_print_options *options, + __isl_give isl_printer *(*print_user)( + __isl_take isl_printer *p, + __isl_take isl_ast_print_options *options, + __isl_keep isl_ast_node *node, void *user), + void *user); + __isl_give isl_ast_print_options * + isl_ast_print_options_set_print_for( + __isl_take isl_ast_print_options *options, + __isl_give isl_printer *(*print_for)( + __isl_take isl_printer *p, + __isl_take isl_ast_print_options *options, + __isl_keep isl_ast_node *node, void *user), + void *user); + +The callback set by C +is called whenever a node of type C needs to +be printed. +The callback set by C +is called whenever a node of type C needs to +be printed. +Note that C will I call the +callback set by C on the node +on which C is called, but only on nested +nodes of type C. It is therefore safe to +call C from within the callback set by +C. + +The following option determines the type to be used for iterators +while printing the AST. + + isl_stat isl_options_set_ast_iterator_type( + isl_ctx *ctx, const char *val); + const char *isl_options_get_ast_iterator_type( + isl_ctx *ctx); + +The AST printer only prints body nodes of C and C nodes +as blocks if these +blocks cannot be safely omitted. +For example, a C node with one body node will not be +surrounded with braces in C. +A block will always be printed by setting the following option. + + isl_stat isl_options_set_ast_always_print_block(isl_ctx *ctx, + int val); + int isl_options_get_ast_always_print_block(isl_ctx *ctx); + +Explicit block nodes that appear inside the AST are always printed as blocks. +If the block node appears as the outermost node, +then it is only printed if the following option is set. + + isl_stat isl_options_set_ast_print_outermost_block( + isl_ctx *ctx, int val); + int isl_options_get_ast_print_outermost_block( + isl_ctx *ctx); + +=head3 Options + + #include + isl_stat isl_options_set_ast_build_atomic_upper_bound( + isl_ctx *ctx, int val); + int isl_options_get_ast_build_atomic_upper_bound( + isl_ctx *ctx); + isl_stat isl_options_set_ast_build_prefer_pdiv(isl_ctx *ctx, + int val); + int isl_options_get_ast_build_prefer_pdiv(isl_ctx *ctx); + isl_stat isl_options_set_ast_build_detect_min_max( + isl_ctx *ctx, int val); + int isl_options_get_ast_build_detect_min_max( + isl_ctx *ctx); + isl_stat isl_options_set_ast_build_exploit_nested_bounds( + isl_ctx *ctx, int val); + int isl_options_get_ast_build_exploit_nested_bounds( + isl_ctx *ctx); + isl_stat isl_options_set_ast_build_group_coscheduled( + isl_ctx *ctx, int val); + int isl_options_get_ast_build_group_coscheduled( + isl_ctx *ctx); + isl_stat isl_options_set_ast_build_separation_bounds( + isl_ctx *ctx, int val); + int isl_options_get_ast_build_separation_bounds( + isl_ctx *ctx); + isl_stat isl_options_set_ast_build_scale_strides( + isl_ctx *ctx, int val); + int isl_options_get_ast_build_scale_strides( + isl_ctx *ctx); + isl_stat isl_options_set_ast_build_allow_else(isl_ctx *ctx, + int val); + int isl_options_get_ast_build_allow_else(isl_ctx *ctx); + isl_stat isl_options_set_ast_build_allow_or(isl_ctx *ctx, + int val); + int isl_options_get_ast_build_allow_or(isl_ctx *ctx); + +=over + +=item * ast_build_atomic_upper_bound + +Generate loop upper bounds that consist of the current loop iterator, +an operator and an expression not involving the iterator. +If this option is not set, then the current loop iterator may appear +several times in the upper bound. +For example, when this option is turned off, AST generation +for the schedule + + [n] -> { A[i] -> [i] : 0 <= i <= 100, n } + +produces + + for (int c0 = 0; c0 <= 100 && n >= c0; c0 += 1) + A(c0); + +When the option is turned on, the following AST is generated + + for (int c0 = 0; c0 <= min(100, n); c0 += 1) + A(c0); + +=item * ast_build_prefer_pdiv + +If this option is turned off, then the AST generation will +produce ASTs that may only contain C +operators, but no C or +C operators. +If this option is turned on, then C will try to convert +some of the C operators to (expressions containing) +C or C operators. + +=item * ast_build_detect_min_max + +If this option is turned on, then C will try and detect +min or max-expressions when building AST expressions from +piecewise affine expressions. + +=item * ast_build_exploit_nested_bounds + +Simplify conditions based on bounds of nested for loops. +In particular, remove conditions that are implied by the fact +that one or more nested loops have at least one iteration, +meaning that the upper bound is at least as large as the lower bound. +For example, when this option is turned off, AST generation +for the schedule + + [N,M] -> { A[i,j] -> [i,j] : 0 <= i <= N and + 0 <= j <= M } + +produces + + if (M >= 0) + for (int c0 = 0; c0 <= N; c0 += 1) + for (int c1 = 0; c1 <= M; c1 += 1) + A(c0, c1); + +When the option is turned on, the following AST is generated + + for (int c0 = 0; c0 <= N; c0 += 1) + for (int c1 = 0; c1 <= M; c1 += 1) + A(c0, c1); + +=item * ast_build_group_coscheduled + +If two domain elements are assigned the same schedule point, then +they may be executed in any order and they may even appear in different +loops. If this options is set, then the AST generator will make +sure that coscheduled domain elements do not appear in separate parts +of the AST. This is useful in case of nested AST generation +if the outer AST generation is given only part of a schedule +and the inner AST generation should handle the domains that are +coscheduled by this initial part of the schedule together. +For example if an AST is generated for a schedule + + { A[i] -> [0]; B[i] -> [0] } + +then the C callback described +below may get called twice, once for each domain. +Setting this option ensures that the callback is only called once +on both domains together. + +=item * ast_build_separation_bounds + +This option specifies which bounds to use during separation. +If this option is set to C +then all (possibly implicit) bounds on the current dimension will +be used during separation. +If this option is set to C +then only those bounds that are explicitly available will +be used during separation. + +=item * ast_build_scale_strides + +This option specifies whether the AST generator is allowed +to scale down iterators of strided loops. + +=item * ast_build_allow_else + +This option specifies whether the AST generator is allowed +to construct if statements with else branches. + +=item * ast_build_allow_or + +This option specifies whether the AST generator is allowed +to construct if conditions with disjunctions. + +=back + +=head3 AST Generation Options (Schedule Tree) + +In case of AST construction from a schedule tree, the options +that control how an AST is created from the individual schedule +dimensions are stored in the band nodes of the tree +(see L). + +In particular, a schedule dimension can be handled in four +different ways, atomic, separate, unroll or the default. +This loop AST generation type can be set using +C. +Alternatively, +the first three can be selected by including a one-dimensional +element with as value the position of the schedule dimension +within the band and as name one of C, C +or C in the options +set by C. +Only one of these three may be specified for +any given schedule dimension within a band node. +If none of these is specified, then the default +is used. The meaning of the options is as follows. + +=over + +=item C + +When this option is specified, the AST generator will make +sure that a given domain space only appears in a single +loop at the specified level. + +For example, for the schedule tree + + domain: "{ a[i] : 0 <= i < 10; b[i] : 0 <= i < 10 }" + child: + schedule: "[{ a[i] -> [i]; b[i] -> [i+1] }]" + options: "{ atomic[x] }" + +the following AST will be generated + + for (int c0 = 0; c0 <= 10; c0 += 1) { + if (c0 >= 1) + b(c0 - 1); + if (c0 <= 9) + a(c0); + } + +On the other hand, for the schedule tree + + domain: "{ a[i] : 0 <= i < 10; b[i] : 0 <= i < 10 }" + child: + schedule: "[{ a[i] -> [i]; b[i] -> [i+1] }]" + options: "{ separate[x] }" + +the following AST will be generated + + { + a(0); + for (int c0 = 1; c0 <= 9; c0 += 1) { + b(c0 - 1); + a(c0); + } + b(9); + } + +If neither C nor C is specified, then the AST generator +may produce either of these two results or some intermediate form. + +=item C + +When this option is specified, the AST generator will +split the domain of the specified schedule dimension +into pieces with a fixed set of statements for which +instances need to be executed by the iterations in +the schedule domain part. This option tends to avoid +the generation of guards inside the corresponding loops. +See also the C option. + +=item C + +When this option is specified, the AST generator will +I unroll the corresponding schedule dimension. +It is the responsibility of the user to ensure that such +unrolling is possible. +To obtain a partial unrolling, the user should apply an additional +strip-mining to the schedule and fully unroll the inner schedule +dimension. + +=back + +The C option is a bit more involved. It allows the user +to isolate a range of schedule dimension values from smaller and +greater values. Additionally, the user may specify a different +atomic/separate/unroll choice for the isolated part and the remaining +parts. The typical use case of the C option is to isolate +full tiles from partial tiles. +The part that needs to be isolated may depend on outer schedule dimensions. +The option therefore needs to be able to reference those outer schedule +dimensions. In particular, the space of the C option is that +of a wrapped map with as domain the flat product of all outer band nodes +and as range the space of the current band node. +The atomic/separate/unroll choice for the isolated part is determined +by an option that lives in an unnamed wrapped space with as domain +a zero-dimensional C space and as range the regular +C, C or C space. +This option may also be set directly using +C. +The atomic/separate/unroll choice for the remaining part is determined +by the regular C, C or C option. +Since the C option references outer schedule dimensions, +its use in a band node causes any tree containing the node +to be considered anchored. + +As an example, consider the isolation of full tiles from partial tiles +in a tiling of a triangular domain. The original schedule is as follows. + + domain: "{ A[i,j] : 0 <= i,j and i + j <= 100 }" + child: + schedule: "[{ A[i,j] -> [floor(i/10)] }, \ + { A[i,j] -> [floor(j/10)] }, \ + { A[i,j] -> [i] }, { A[i,j] -> [j] }]" + +The output is + + for (int c0 = 0; c0 <= 10; c0 += 1) + for (int c1 = 0; c1 <= -c0 + 10; c1 += 1) + for (int c2 = 10 * c0; + c2 <= min(10 * c0 + 9, -10 * c1 + 100); c2 += 1) + for (int c3 = 10 * c1; + c3 <= min(10 * c1 + 9, -c2 + 100); c3 += 1) + A(c2, c3); + +Isolating the full tiles, we have the following input + + domain: "{ A[i,j] : 0 <= i,j and i + j <= 100 }" + child: + schedule: "[{ A[i,j] -> [floor(i/10)] }, \ + { A[i,j] -> [floor(j/10)] }, \ + { A[i,j] -> [i] }, { A[i,j] -> [j] }]" + options: "{ isolate[[] -> [a,b,c,d]] : 0 <= 10a,10b and \ + 10a+9+10b+9 <= 100 }" + +and output + + { + for (int c0 = 0; c0 <= 8; c0 += 1) { + for (int c1 = 0; c1 <= -c0 + 8; c1 += 1) + for (int c2 = 10 * c0; + c2 <= 10 * c0 + 9; c2 += 1) + for (int c3 = 10 * c1; + c3 <= 10 * c1 + 9; c3 += 1) + A(c2, c3); + for (int c1 = -c0 + 9; c1 <= -c0 + 10; c1 += 1) + for (int c2 = 10 * c0; + c2 <= min(10 * c0 + 9, -10 * c1 + 100); c2 += 1) + for (int c3 = 10 * c1; + c3 <= min(10 * c1 + 9, -c2 + 100); c3 += 1) + A(c2, c3); + } + for (int c0 = 9; c0 <= 10; c0 += 1) + for (int c1 = 0; c1 <= -c0 + 10; c1 += 1) + for (int c2 = 10 * c0; + c2 <= min(10 * c0 + 9, -10 * c1 + 100); c2 += 1) + for (int c3 = 10 * c1; + c3 <= min(10 * c1 + 9, -c2 + 100); c3 += 1) + A(c2, c3); + } + +We may then additionally unroll the innermost loop of the isolated part + + domain: "{ A[i,j] : 0 <= i,j and i + j <= 100 }" + child: + schedule: "[{ A[i,j] -> [floor(i/10)] }, \ + { A[i,j] -> [floor(j/10)] }, \ + { A[i,j] -> [i] }, { A[i,j] -> [j] }]" + options: "{ isolate[[] -> [a,b,c,d]] : 0 <= 10a,10b and \ + 10a+9+10b+9 <= 100; [isolate[] -> unroll[3]] }" + +to obtain + + { + for (int c0 = 0; c0 <= 8; c0 += 1) { + for (int c1 = 0; c1 <= -c0 + 8; c1 += 1) + for (int c2 = 10 * c0; c2 <= 10 * c0 + 9; c2 += 1) { + A(c2, 10 * c1); + A(c2, 10 * c1 + 1); + A(c2, 10 * c1 + 2); + A(c2, 10 * c1 + 3); + A(c2, 10 * c1 + 4); + A(c2, 10 * c1 + 5); + A(c2, 10 * c1 + 6); + A(c2, 10 * c1 + 7); + A(c2, 10 * c1 + 8); + A(c2, 10 * c1 + 9); + } + for (int c1 = -c0 + 9; c1 <= -c0 + 10; c1 += 1) + for (int c2 = 10 * c0; + c2 <= min(10 * c0 + 9, -10 * c1 + 100); c2 += 1) + for (int c3 = 10 * c1; + c3 <= min(10 * c1 + 9, -c2 + 100); c3 += 1) + A(c2, c3); + } + for (int c0 = 9; c0 <= 10; c0 += 1) + for (int c1 = 0; c1 <= -c0 + 10; c1 += 1) + for (int c2 = 10 * c0; + c2 <= min(10 * c0 + 9, -10 * c1 + 100); c2 += 1) + for (int c3 = 10 * c1; + c3 <= min(10 * c1 + 9, -c2 + 100); c3 += 1) + A(c2, c3); + } + + +=head3 AST Generation Options (Schedule Map) + +In case of AST construction using +C, the options +that control how an AST is created from the individual schedule +dimensions are stored in the C. +They can be set using the following function. + + #include + __isl_give isl_ast_build * + isl_ast_build_set_options( + __isl_take isl_ast_build *build, + __isl_take isl_union_map *options); + +The options are encoded in an C. +The domain of this union relation refers to the schedule domain, +i.e., the range of the schedule passed +to C. +In the case of nested AST generation (see L), +the domain of C should refer to the extra piece of the schedule. +That is, it should be equal to the range of the wrapped relation in the +range of the schedule. +The range of the options can consist of elements in one or more spaces, +the names of which determine the effect of the option. +The values of the range typically also refer to the schedule dimension +to which the option applies, with value C<0> representing +the outermost schedule dimension. In case of nested AST generation +(see L), these values refer to the position +of the schedule dimension within the innermost AST generation. +The constraints on the domain elements of +the option should only refer to this dimension and earlier dimensions. +We consider the following spaces. + +=over + +=item C + +B + +This space is a wrapped relation between two one dimensional spaces. +The input space represents the schedule dimension to which the option +applies and the output space represents the separation class. +While constructing a loop corresponding to the specified schedule +dimension(s), the AST generator will try to generate separate loops +for domain elements that are assigned different classes. +If only some of the elements are assigned a class, then those elements +that are not assigned any class will be treated as belonging to a class +that is separate from the explicitly assigned classes. +The typical use case for this option is to separate full tiles from +partial tiles. +The other options, described below, are applied after the separation +into classes. + +As an example, consider the separation into full and partial tiles +of a tiling of a triangular domain. +Take, for example, the domain + + { A[i,j] : 0 <= i,j and i + j <= 100 } + +and a tiling into tiles of 10 by 10. The input to the AST generator +is then the schedule + + { A[i,j] -> [([i/10]),[j/10],i,j] : 0 <= i,j and + i + j <= 100 } + +Without any options, the following AST is generated + + for (int c0 = 0; c0 <= 10; c0 += 1) + for (int c1 = 0; c1 <= -c0 + 10; c1 += 1) + for (int c2 = 10 * c0; + c2 <= min(-10 * c1 + 100, 10 * c0 + 9); + c2 += 1) + for (int c3 = 10 * c1; + c3 <= min(10 * c1 + 9, -c2 + 100); + c3 += 1) + A(c2, c3); + +Separation into full and partial tiles can be obtained by assigning +a class, say C<0>, to the full tiles. The full tiles are represented by those +values of the first and second schedule dimensions for which there are +values of the third and fourth dimensions to cover an entire tile. +That is, we need to specify the following option + + { [a,b,c,d] -> separation_class[[0]->[0]] : + exists b': 0 <= 10a,10b' and + 10a+9+10b'+9 <= 100; + [a,b,c,d] -> separation_class[[1]->[0]] : + 0 <= 10a,10b and 10a+9+10b+9 <= 100 } + +which simplifies to + + { [a, b, c, d] -> separation_class[[1] -> [0]] : + a >= 0 and b >= 0 and b <= 8 - a; + [a, b, c, d] -> separation_class[[0] -> [0]] : + a >= 0 and a <= 8 } + +With this option, the generated AST is as follows + + { + for (int c0 = 0; c0 <= 8; c0 += 1) { + for (int c1 = 0; c1 <= -c0 + 8; c1 += 1) + for (int c2 = 10 * c0; + c2 <= 10 * c0 + 9; c2 += 1) + for (int c3 = 10 * c1; + c3 <= 10 * c1 + 9; c3 += 1) + A(c2, c3); + for (int c1 = -c0 + 9; c1 <= -c0 + 10; c1 += 1) + for (int c2 = 10 * c0; + c2 <= min(-10 * c1 + 100, 10 * c0 + 9); + c2 += 1) + for (int c3 = 10 * c1; + c3 <= min(-c2 + 100, 10 * c1 + 9); + c3 += 1) + A(c2, c3); + } + for (int c0 = 9; c0 <= 10; c0 += 1) + for (int c1 = 0; c1 <= -c0 + 10; c1 += 1) + for (int c2 = 10 * c0; + c2 <= min(-10 * c1 + 100, 10 * c0 + 9); + c2 += 1) + for (int c3 = 10 * c1; + c3 <= min(10 * c1 + 9, -c2 + 100); + c3 += 1) + A(c2, c3); + } + +=item C + +This is a single-dimensional space representing the schedule dimension(s) +to which ``separation'' should be applied. Separation tries to split +a loop into several pieces if this can avoid the generation of guards +inside the loop. +See also the C option. + +=item C + +This is a single-dimensional space representing the schedule dimension(s) +for which the domains should be considered ``atomic''. That is, the +AST generator will make sure that any given domain space will only appear +in a single loop at the specified level. + +Consider the following schedule + + { a[i] -> [i] : 0 <= i < 10; + b[i] -> [i+1] : 0 <= i < 10 } + +If the following option is specified + + { [i] -> separate[x] } + +then the following AST will be generated + + { + a(0); + for (int c0 = 1; c0 <= 9; c0 += 1) { + a(c0); + b(c0 - 1); + } + b(9); + } + +If, on the other hand, the following option is specified + + { [i] -> atomic[x] } + +then the following AST will be generated + + for (int c0 = 0; c0 <= 10; c0 += 1) { + if (c0 <= 9) + a(c0); + if (c0 >= 1) + b(c0 - 1); + } + +If neither C nor C is specified, then the AST generator +may produce either of these two results or some intermediate form. + +=item C + +This is a single-dimensional space representing the schedule dimension(s) +that should be I unrolled. +To obtain a partial unrolling, the user should apply an additional +strip-mining to the schedule and fully unroll the inner loop. + +=back + +=head3 Fine-grained Control over AST Generation + +Besides specifying the constraints on the parameters, +an C object can be used to control +various aspects of the AST generation process. +In case of AST construction using +C, +the most prominent way of control is through ``options'', +as explained above. + +Additional control is available through the following functions. + + #include + __isl_give isl_ast_build * + isl_ast_build_set_iterators( + __isl_take isl_ast_build *build, + __isl_take isl_id_list *iterators); + +The function C allows the user to +specify a list of iterator Cs to be used as iterators. +If the input schedule is injective, then +the number of elements in this list should be as large as the dimension +of the schedule space, but no direct correspondence should be assumed +between dimensions and elements. +If the input schedule is not injective, then an additional number +of Cs equal to the largest dimension of the input domains +may be required. +If the number of provided Cs is insufficient, then additional +names are automatically generated. + + #include + __isl_give isl_ast_build * + isl_ast_build_set_create_leaf( + __isl_take isl_ast_build *build, + __isl_give isl_ast_node *(*fn)( + __isl_take isl_ast_build *build, + void *user), void *user); + +The +C function allows for the +specification of a callback that should be called whenever the AST +generator arrives at an element of the schedule domain. +The callback should return an AST node that should be inserted +at the corresponding position of the AST. The default action (when +the callback is not set) is to continue generating parts of the AST to scan +all the domain elements associated to the schedule domain element +and to insert user nodes, ``calling'' the domain element, for each of them. +The C argument contains the current state of the C. +To ease nested AST generation (see L), +all control information that is +specific to the current AST generation such as the options and +the callbacks has been removed from this C. +The callback would typically return the result of a nested +AST generation or a +user defined node created using the following function. + + #include + __isl_give isl_ast_node *isl_ast_node_user_from_expr( + __isl_take isl_ast_expr *expr); + __isl_give isl_ast_node *isl_ast_node_alloc_user( + __isl_take isl_ast_expr *expr); + +C is an alternative name for +C. + +In some cases, a single user defined node is not enough, +in which case the following function can be used +to create a block node from multiple AST nodes. + + #include + __isl_give isl_ast_node *isl_ast_node_block_from_children( + __isl_take isl_ast_node_list *list); + + #include + __isl_give isl_ast_build * + isl_ast_build_set_at_each_domain( + __isl_take isl_ast_build *build, + __isl_give isl_ast_node *(*fn)( + __isl_take isl_ast_node *node, + __isl_keep isl_ast_build *build, + void *user), void *user); + __isl_give isl_ast_build * + isl_ast_build_set_before_each_for( + __isl_take isl_ast_build *build, + __isl_give isl_id *(*fn)( + __isl_keep isl_ast_build *build, + void *user), void *user); + __isl_give isl_ast_build * + isl_ast_build_set_after_each_for( + __isl_take isl_ast_build *build, + __isl_give isl_ast_node *(*fn)( + __isl_take isl_ast_node *node, + __isl_keep isl_ast_build *build, + void *user), void *user); + __isl_give isl_ast_build * + isl_ast_build_set_before_each_mark( + __isl_take isl_ast_build *build, + isl_stat (*fn)(__isl_keep isl_id *mark, + __isl_keep isl_ast_build *build, + void *user), void *user); + __isl_give isl_ast_build * + isl_ast_build_set_after_each_mark( + __isl_take isl_ast_build *build, + __isl_give isl_ast_node *(*fn)( + __isl_take isl_ast_node *node, + __isl_keep isl_ast_build *build, + void *user), void *user); + +The callback set by C will +be called for each domain AST node. +The callbacks set by C +and C will be called +for each for AST node. The first will be called in depth-first +pre-order, while the second will be called in depth-first post-order. +Since C is called before the for +node is actually constructed, it is only passed an C. +The returned C will be added as an annotation (using +C) to the constructed for node. +In particular, if the user has also specified an C +callback, then the annotation can be retrieved from the node passed to +that callback using C. +The callbacks set by C +and C will be called for each +mark AST node that is created, i.e., for each mark schedule node +in the input schedule tree. The first will be called in depth-first +pre-order, while the second will be called in depth-first post-order. +Since the callback set by C +is called before the mark AST node is actually constructed, it is passed +the identifier of the mark node. +All callbacks should C (or C) on failure. +The given C can be used to create new +C objects using C +or C. + +=head3 Nested AST Generation + +C allows the user to create an AST within the context +of another AST. These nested ASTs are created using the +same C function that is used to create +the outer AST. The C argument should be an C +passed to a callback set by +C. +The space of the range of the C argument should refer +to this build. In particular, the space should be a wrapped +relation and the domain of this wrapped relation should be the +same as that of the range of the schedule returned by +C below. +In practice, the new schedule is typically +created by calling C on the old schedule +and some extra piece of the schedule. +The space of the schedule domain is also available from +the C. + + #include + __isl_give isl_union_map *isl_ast_build_get_schedule( + __isl_keep isl_ast_build *build); + __isl_give isl_space *isl_ast_build_get_schedule_space( + __isl_keep isl_ast_build *build); + __isl_give isl_ast_build *isl_ast_build_restrict( + __isl_take isl_ast_build *build, + __isl_take isl_set *set); + +The C function returns a (partial) +schedule for the domains elements for which part of the AST still needs to +be generated in the current build. +In particular, the domain elements are mapped to those iterations of the loops +enclosing the current point of the AST generation inside which +the domain elements are executed. +No direct correspondence between +the input schedule and this schedule should be assumed. +The space obtained from C can be used +to create a set for C to intersect +with the current build. In particular, the set passed to +C can have additional parameters. +The ids of the set dimensions in the space returned by +C correspond to the +iterators of the already generated loops. +The user should not rely on the ids of the output dimensions +of the relations in the union relation returned by +C having any particular value. + +=head1 Applications + +Although C is mainly meant to be used as a library, +it also contains some basic applications that use some +of the functionality of C. +For applications that take one or more polytopes or polyhedra +as input, this input may be specified in either the L +or the L. + +=head2 C + +C takes a polyhedron as input and prints +an integer element of the polyhedron, if there is any. +The first column in the output is the denominator and is always +equal to 1. If the polyhedron contains no integer points, +then a vector of length zero is printed. + +=head2 C + +C takes the same input as the C program +from the C distribution, i.e., a set of constraints +on the parameters, a line containing only -1 and finally a set +of constraints on a parametric polyhedron. +The coefficients of the parameters appear in the last columns +(but before the final constant column). +The output is the lexicographic minimum of the parametric polyhedron. +As C currently does not have its own output format, the output +is just a dump of the internal state. + +=head2 C + +C computes the minimum of some linear +or affine objective function over the integer points in a polyhedron. +If an affine objective function +is given, then the constant should appear in the last column. + +=head2 C + +Given a polytope, C prints +all integer points in the polytope. + +=head2 C + +Given an C object as input, +C prints out the corresponding dependences, +as computed by C. + +=head2 C + +Given either a schedule tree or a sequence consisting of +a schedule map, a context set and an options relation, +C prints out an AST that scans the domain elements +of the schedule in the order of their image(s) taking into account +the constraints in the context set. + +=head2 C + +Given an C object as input, +C prints out a schedule that satisfies the given +constraints. diff --git a/external/mit/isl/dist/extract_key.c b/external/mit/isl/dist/extract_key.c new file mode 100644 index 000000000000..28fbdfdd3096 --- /dev/null +++ b/external/mit/isl/dist/extract_key.c @@ -0,0 +1,62 @@ +/* + * Copyright 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 + +/* Extract a mapping key from the token "tok". + * Return KEY_ERROR on error, i.e., if "tok" does not + * correspond to any known key. + */ +static KEY KEY_EXTRACT(__isl_keep isl_stream *s, struct isl_token *tok) +{ + isl_bool has_string; + char *name; + KEY key; + isl_ctx *ctx; + + has_string = isl_token_has_str(tok); + if (has_string < 0) + return KEY_ERROR; + if (!has_string) { + isl_stream_error(s, tok, "expecting key"); + return KEY_ERROR; + } + + ctx = isl_stream_get_ctx(s); + name = isl_token_get_str(ctx, tok); + if (!name) + return KEY_ERROR; + + for (key = 0; key < KEY_END; ++key) { + if (KEY_STR[key] && !strcmp(name, KEY_STR[key])) + break; + } + free(name); + + if (key >= KEY_END) + isl_die(ctx, isl_error_invalid, "unknown key", + return KEY_ERROR); + return key; +} + +/* Read a key from "s" and return the corresponding enum. + * Return KEY_ERROR on error, i.e., if the first token + * on the stream does not correspond to any known key. + */ +static KEY KEY_GET(__isl_keep isl_stream *s) +{ + struct isl_token *tok; + KEY key; + + tok = isl_stream_next_token(s); + key = KEY_EXTRACT(s, tok); + isl_token_free(tok); + + return key; +} diff --git a/external/mit/isl/dist/flow.c b/external/mit/isl/dist/flow.c new file mode 100644 index 000000000000..9472c5bc500f --- /dev/null +++ b/external/mit/isl/dist/flow.c @@ -0,0 +1,44 @@ +/* + * Copyright 2017 Sven Verdoolaege + * + * Use of this software is governed by the MIT license + * + * Written by Sven Verdoolaege. + */ + +/* This program takes an isl_union_access_info object as input and + * prints the corresponding dependences. + */ + +#include +#include +#include +#include +#include + +int main(int argc, char **argv) +{ + isl_ctx *ctx; + isl_printer *p; + isl_union_access_info *access; + isl_union_flow *flow; + struct isl_options *options; + + options = isl_options_new_with_defaults(); + argc = isl_options_parse(options, argc, argv, ISL_ARG_ALL); + ctx = isl_ctx_alloc_with_options(&isl_options_args, options); + + access = isl_union_access_info_read_from_file(ctx, stdin); + flow = isl_union_access_info_compute_flow(access); + + p = isl_printer_to_file(ctx, stdout); + p = isl_printer_set_yaml_style(p, ISL_YAML_STYLE_BLOCK); + p = isl_printer_print_union_flow(p, flow); + isl_printer_free(p); + + isl_union_flow_free(flow); + + isl_ctx_free(ctx); + + return 0; +} diff --git a/external/mit/isl/dist/flow_cmp.c b/external/mit/isl/dist/flow_cmp.c new file mode 100644 index 000000000000..e01c0fa628c8 --- /dev/null +++ b/external/mit/isl/dist/flow_cmp.c @@ -0,0 +1,136 @@ +/* + * Copyright 2017 Sven Verdoolaege + * + * Use of this software is governed by the MIT license + * + * Written by Sven Verdoolaege. + */ + +#include + +#include +#include +#include +#include + +struct options { + struct isl_options *isl; + char *flow1; + char *flow2; +}; + +ISL_ARGS_START(struct options, options_args) +ISL_ARG_CHILD(struct options, isl, "isl", &isl_options_args, "isl options") +ISL_ARG_ARG(struct options, flow1, "flow1", NULL) +ISL_ARG_ARG(struct options, flow2, "flow2", NULL) +ISL_ARGS_END + +ISL_ARG_DEF(options, struct options, options_args) + +static void die(const char *msg) +{ + fprintf(stderr, "%s\n", msg); + exit(EXIT_FAILURE); +} + +static FILE *open_or_die(const char *filename) +{ + FILE *file; + + file = fopen(filename, "r"); + if (!file) { + fprintf(stderr, "Unable to open %s\n", filename); + exit(EXIT_FAILURE); + } + return file; +} + +#undef BASE +#define BASE union_map +#include "read_in_string_templ.c" + +/* Given two YAML descriptions of isl_union_flow objects, check whether + * they are equivalent. + * Return EXIT_SUCCESS if they are and EXIT_FAILURE if they are not + * or if anything else went wrong. + * + * The descriptions are checked field by field, meaning that the fields + * are expected to appear in the same order in both inputs. + */ +int main(int argc, char **argv) +{ + isl_bool more; + isl_ctx *ctx; + struct options *options; + FILE *input1, *input2; + isl_stream *s1, *s2; + + options = options_new_with_defaults(); + if (!options) + return EXIT_FAILURE; + + ctx = isl_ctx_alloc_with_options(&options_args, options); + argc = options_parse(options, argc, argv, ISL_ARG_ALL); + + input1 = open_or_die(options->flow1); + input2 = open_or_die(options->flow2); + s1 = isl_stream_new_file(ctx, input1); + s2 = isl_stream_new_file(ctx, input2); + + if (isl_stream_yaml_read_start_mapping(s1) < 0) + isl_die(ctx, isl_error_unknown, "arg1 not a YAML mapping", + return EXIT_FAILURE); + if (isl_stream_yaml_read_start_mapping(s2) < 0) + isl_die(ctx, isl_error_unknown, "arg2 not a YAML mapping", + return EXIT_FAILURE); + + while ((more = isl_stream_yaml_next(s1)) == isl_bool_true) { + isl_bool more2; + isl_bool equal; + isl_union_map *umap1, *umap2; + + more2 = isl_stream_yaml_next(s2); + if (more2 < 0) + return EXIT_FAILURE; + if (!more2) + isl_die(ctx, isl_error_unknown, "arg2 shorter", + return EXIT_FAILURE); + if (isl_stream_eat(s1, ISL_TOKEN_IDENT) < 0) + return EXIT_FAILURE; + if (isl_stream_eat(s2, ISL_TOKEN_IDENT) < 0) + return EXIT_FAILURE; + more = isl_stream_yaml_next(s1); + more2 = isl_stream_yaml_next(s2); + if (more < 0 || more2 < 0) + return EXIT_FAILURE; + if (!more || !more2) + isl_die(ctx, isl_error_unknown, "missing value", + return EXIT_FAILURE); + + umap1 = read_union_map(s1); + umap2 = read_union_map(s2); + equal = isl_union_map_is_equal(umap1, umap2); + isl_union_map_free(umap1); + isl_union_map_free(umap2); + if (equal < 0) + return EXIT_FAILURE; + if (!equal) + die("field not equal"); + } + if (more < 0) + return EXIT_FAILURE; + + + if (isl_stream_yaml_read_end_mapping(s1) < 0) + return EXIT_FAILURE; + if (isl_stream_yaml_read_end_mapping(s2) < 0) + return EXIT_FAILURE; + + isl_stream_free(s1); + isl_stream_free(s2); + fclose(input1); + fclose(input2); + isl_ctx_free(ctx); + + return EXIT_SUCCESS; +} diff --git a/external/mit/isl/dist/flow_test.sh.in b/external/mit/isl/dist/flow_test.sh.in new file mode 100644 index 000000000000..fa9177c0ba6a --- /dev/null +++ b/external/mit/isl/dist/flow_test.sh.in @@ -0,0 +1,18 @@ +#!/bin/sh + +EXEEXT=@EXEEXT@ +srcdir=@srcdir@ + +failed=0 + +for i in $srcdir/test_inputs/flow/*.ai; do + echo $i; + base=`basename $i .ai` + test=test-$base.flow + dir=`dirname $i` + ref=$dir/$base.flow + (./isl_flow$EXEEXT < $i > $test && + ./isl_flow_cmp$EXEEXT $ref $test && rm $test) || failed=1 +done + +test $failed -eq 0 || exit diff --git a/external/mit/isl/dist/has_single_reference_templ.c b/external/mit/isl/dist/has_single_reference_templ.c new file mode 100644 index 000000000000..332f6b22e245 --- /dev/null +++ b/external/mit/isl/dist/has_single_reference_templ.c @@ -0,0 +1,12 @@ +#define xFN(TYPE,NAME) TYPE ## _ ## NAME +#define FN(TYPE,NAME) xFN(TYPE,NAME) + +/* Does "obj" have a single reference? + * That is, can "obj" be changed inplace? + */ +isl_bool FN(TYPE,has_single_reference)(__isl_keep TYPE *obj) +{ + if (!obj) + return isl_bool_error; + return obj->ref == 1; +} diff --git a/external/mit/isl/dist/imath/gmp_compat.c b/external/mit/isl/dist/imath/gmp_compat.c new file mode 100644 index 000000000000..620c4ca9a97d --- /dev/null +++ b/external/mit/isl/dist/imath/gmp_compat.c @@ -0,0 +1,823 @@ +/* + Name: gmp_compat.c + Purpose: Provide GMP compatiable routines for imath library + Author: David Peixotto + + Copyright (c) 2012 Qualcomm Innovation Center, Inc. All rights reserved. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ +#include "gmp_compat.h" +#include +#include +#include +#include +#include + +#if defined(_MSC_VER) +#include +typedef SSIZE_T ssize_t; +#else +#include +#endif + +#ifdef NDEBUG +#define CHECK(res) (res) +#else +#define CHECK(res) assert(((res) == MP_OK) && "expected MP_OK") +#endif + +/* *(signed char *)&endian_test will thus either be: + * 0b00000001 = 1 on big-endian + * 0b11111111 = -1 on little-endian */ +static const uint16_t endian_test = 0x1FF; +#define HOST_ENDIAN (*(signed char *)&endian_test) + +/************************************************************************* + * + * Functions with direct translations + * + *************************************************************************/ +/* gmp: mpq_clear */ +void GMPQAPI(clear)(mp_rat x) { mp_rat_clear(x); } + +/* gmp: mpq_cmp */ +int GMPQAPI(cmp)(mp_rat op1, mp_rat op2) { return mp_rat_compare(op1, op2); } + +/* gmp: mpq_init */ +void GMPQAPI(init)(mp_rat x) { CHECK(mp_rat_init(x)); } + +/* gmp: mpq_mul */ +void GMPQAPI(mul)(mp_rat product, mp_rat multiplier, mp_rat multiplicand) { + CHECK(mp_rat_mul(multiplier, multiplicand, product)); +} + +/* gmp: mpq_set */ +void GMPQAPI(set)(mp_rat rop, mp_rat op) { CHECK(mp_rat_copy(op, rop)); } + +/* gmp: mpz_abs */ +void GMPZAPI(abs)(mp_int rop, mp_int op) { CHECK(mp_int_abs(op, rop)); } + +/* gmp: mpz_add */ +void GMPZAPI(add)(mp_int rop, mp_int op1, mp_int op2) { + CHECK(mp_int_add(op1, op2, rop)); +} + +/* gmp: mpz_clear */ +void GMPZAPI(clear)(mp_int x) { mp_int_clear(x); } + +/* gmp: mpz_cmp_si */ +int GMPZAPI(cmp_si)(mp_int op1, long op2) { + return mp_int_compare_value(op1, op2); +} + +/* gmp: mpz_cmpabs */ +int GMPZAPI(cmpabs)(mp_int op1, mp_int op2) { + return mp_int_compare_unsigned(op1, op2); +} + +/* gmp: mpz_cmp */ +int GMPZAPI(cmp)(mp_int op1, mp_int op2) { return mp_int_compare(op1, op2); } + +/* gmp: mpz_init */ +void GMPZAPI(init)(mp_int x) { CHECK(mp_int_init(x)); } + +/* gmp: mpz_mul */ +void GMPZAPI(mul)(mp_int rop, mp_int op1, mp_int op2) { + CHECK(mp_int_mul(op1, op2, rop)); +} + +/* gmp: mpz_neg */ +void GMPZAPI(neg)(mp_int rop, mp_int op) { CHECK(mp_int_neg(op, rop)); } + +/* gmp: mpz_set_si */ +void GMPZAPI(set_si)(mp_int rop, long op) { CHECK(mp_int_set_value(rop, op)); } + +/* gmp: mpz_set */ +void GMPZAPI(set)(mp_int rop, mp_int op) { CHECK(mp_int_copy(op, rop)); } + +/* gmp: mpz_sub */ +void GMPZAPI(sub)(mp_int rop, mp_int op1, mp_int op2) { + CHECK(mp_int_sub(op1, op2, rop)); +} + +/* gmp: mpz_swap */ +void GMPZAPI(swap)(mp_int rop1, mp_int rop2) { mp_int_swap(rop1, rop2); } + +/* gmp: mpq_sgn */ +int GMPQAPI(sgn)(mp_rat op) { return mp_rat_compare_zero(op); } + +/* gmp: mpz_sgn */ +int GMPZAPI(sgn)(mp_int op) { return mp_int_compare_zero(op); } + +/* gmp: mpq_set_ui */ +void GMPQAPI(set_ui)(mp_rat rop, unsigned long op1, unsigned long op2) { + CHECK(mp_rat_set_uvalue(rop, op1, op2)); +} + +/* gmp: mpz_set_ui */ +void GMPZAPI(set_ui)(mp_int rop, unsigned long op) { + CHECK(mp_int_set_uvalue(rop, op)); +} + +/* gmp: mpq_den_ref */ +mp_int GMPQAPI(denref)(mp_rat op) { return mp_rat_denom_ref(op); } + +/* gmp: mpq_num_ref */ +mp_int GMPQAPI(numref)(mp_rat op) { return mp_rat_numer_ref(op); } + +/* gmp: mpq_canonicalize */ +void GMPQAPI(canonicalize)(mp_rat op) { CHECK(mp_rat_reduce(op)); } + +/* + * Functions that can be implemented as a combination of imath functions + */ + +/* gmp: mpz_addmul */ +/* gmp: rop = rop + (op1 * op2) */ +void GMPZAPI(addmul)(mp_int rop, mp_int op1, mp_int op2) { + mpz_t tempz; + mp_int temp = &tempz; + mp_int_init(temp); + + CHECK(mp_int_mul(op1, op2, temp)); + CHECK(mp_int_add(rop, temp, rop)); + mp_int_clear(temp); +} + +/* gmp: mpz_divexact */ +/* gmp: only produces correct results when d divides n */ +void GMPZAPI(divexact)(mp_int q, mp_int n, mp_int d) { + CHECK(mp_int_div(n, d, q, NULL)); +} + +/* gmp: mpz_divisible_p */ +/* gmp: return 1 if d divides n, 0 otherwise */ +/* gmp: 0 is considered to divide only 0 */ +int GMPZAPI(divisible_p)(mp_int n, mp_int d) { + /* variables to hold remainder */ + mpz_t rz; + mp_int r = &rz; + int r_is_zero; + + /* check for d = 0 */ + int n_is_zero = mp_int_compare_zero(n) == 0; + int d_is_zero = mp_int_compare_zero(d) == 0; + if (d_is_zero) return n_is_zero; + + /* return true if remainder is 0 */ + CHECK(mp_int_init(r)); + CHECK(mp_int_div(n, d, NULL, r)); + r_is_zero = mp_int_compare_zero(r) == 0; + mp_int_clear(r); + + return r_is_zero; +} + +/* gmp: mpz_submul */ +/* gmp: rop = rop - (op1 * op2) */ +void GMPZAPI(submul)(mp_int rop, mp_int op1, mp_int op2) { + mpz_t tempz; + mp_int temp = &tempz; + mp_int_init(temp); + + CHECK(mp_int_mul(op1, op2, temp)); + CHECK(mp_int_sub(rop, temp, rop)); + + mp_int_clear(temp); +} + +/* gmp: mpz_add_ui */ +void GMPZAPI(add_ui)(mp_int rop, mp_int op1, unsigned long op2) { + mpz_t tempz; + mp_int temp = &tempz; + CHECK(mp_int_init_uvalue(temp, op2)); + + CHECK(mp_int_add(op1, temp, rop)); + + mp_int_clear(temp); +} + +/* gmp: mpz_divexact_ui */ +/* gmp: only produces correct results when d divides n */ +void GMPZAPI(divexact_ui)(mp_int q, mp_int n, unsigned long d) { + mpz_t tempz; + mp_int temp = &tempz; + CHECK(mp_int_init_uvalue(temp, d)); + + CHECK(mp_int_div(n, temp, q, NULL)); + + mp_int_clear(temp); +} + +/* gmp: mpz_mul_ui */ +void GMPZAPI(mul_ui)(mp_int rop, mp_int op1, unsigned long op2) { + mpz_t tempz; + mp_int temp = &tempz; + CHECK(mp_int_init_uvalue(temp, op2)); + + CHECK(mp_int_mul(op1, temp, rop)); + + mp_int_clear(temp); +} + +/* gmp: mpz_pow_ui */ +/* gmp: 0^0 = 1 */ +void GMPZAPI(pow_ui)(mp_int rop, mp_int base, unsigned long exp) { + mpz_t tempz; + mp_int temp = &tempz; + + /* check for 0^0 */ + if (exp == 0 && mp_int_compare_zero(base) == 0) { + CHECK(mp_int_set_value(rop, 1)); + return; + } + + /* rop = base^exp */ + CHECK(mp_int_init_uvalue(temp, exp)); + CHECK(mp_int_expt_full(base, temp, rop)); + mp_int_clear(temp); +} + +/* gmp: mpz_sub_ui */ +void GMPZAPI(sub_ui)(mp_int rop, mp_int op1, unsigned long op2) { + mpz_t tempz; + mp_int temp = &tempz; + CHECK(mp_int_init_uvalue(temp, op2)); + + CHECK(mp_int_sub(op1, temp, rop)); + + mp_int_clear(temp); +} + +/************************************************************************* + * + * Functions with different behavior in corner cases + * + *************************************************************************/ + +/* gmp: mpz_gcd */ +void GMPZAPI(gcd)(mp_int rop, mp_int op1, mp_int op2) { + int op1_is_zero = mp_int_compare_zero(op1) == 0; + int op2_is_zero = mp_int_compare_zero(op2) == 0; + + if (op1_is_zero && op2_is_zero) { + mp_int_zero(rop); + return; + } + + CHECK(mp_int_gcd(op1, op2, rop)); +} + +/* gmp: mpz_get_str */ +char *GMPZAPI(get_str)(char *str, int radix, mp_int op) { + int i, r, len; + + /* Support negative radix like gmp */ + r = radix; + if (r < 0) r = -r; + + /* Compute the length of the string needed to hold the int */ + len = mp_int_string_len(op, r); + if (str == NULL) { + str = malloc(len); + } + + /* Convert to string using imath function */ + CHECK(mp_int_to_string(op, r, str, len)); + + /* Change case to match gmp */ + for (i = 0; i < len - 1; i++) { + if (radix < 0) { + str[i] = toupper(str[i]); + } else { + str[i] = tolower(str[i]); + } + } + return str; +} + +/* gmp: mpq_get_str */ +char *GMPQAPI(get_str)(char *str, int radix, mp_rat op) { + int i, r, len; + + /* Only print numerator if it is a whole number */ + if (mp_int_compare_value(mp_rat_denom_ref(op), 1) == 0) + return GMPZAPI(get_str)(str, radix, mp_rat_numer_ref(op)); + + /* Support negative radix like gmp */ + r = radix; + if (r < 0) r = -r; + + /* Compute the length of the string needed to hold the int */ + len = mp_rat_string_len(op, r); + if (str == NULL) { + str = malloc(len); + } + + /* Convert to string using imath function */ + CHECK(mp_rat_to_string(op, r, str, len)); + + /* Change case to match gmp */ + for (i = 0; i < len; i++) { + if (radix < 0) { + str[i] = toupper(str[i]); + } else { + str[i] = tolower(str[i]); + } + } + + return str; +} + +/* gmp: mpz_set_str */ +int GMPZAPI(set_str)(mp_int rop, char *str, int base) { + mp_result res = mp_int_read_string(rop, base, str); + return ((res == MP_OK) ? 0 : -1); +} + +/* gmp: mpq_set_str */ +int GMPQAPI(set_str)(mp_rat rop, char *s, int base) { + char *slash; + char *str; + mp_result resN; + mp_result resD; + int res = 0; + + /* Copy string to temporary storage so we can modify it below */ + str = malloc(strlen(s) + 1); + strcpy(str, s); + + /* Properly format the string as an int by terminating at the / */ + slash = strchr(str, '/'); + if (slash) *slash = '\0'; + + /* Parse numerator */ + resN = mp_int_read_string(mp_rat_numer_ref(rop), base, str); + + /* Parse denominator if given or set to 1 if not */ + if (slash) { + resD = mp_int_read_string(mp_rat_denom_ref(rop), base, slash + 1); + } else { + resD = mp_int_set_uvalue(mp_rat_denom_ref(rop), 1); + } + + /* Return failure if either parse failed */ + if (resN != MP_OK || resD != MP_OK) { + res = -1; + } + + free(str); + return res; +} + +static unsigned long get_long_bits(mp_int op) { + /* Deal with integer that does not fit into unsigned long. We want to grab + * the least significant digits that will fit into the long. Read the digits + * into the long starting at the most significant digit that fits into a + * long. The long is shifted over by MP_DIGIT_BIT before each digit is added. + * + * The shift is decomposed into two steps (following the pattern used in the + * rest of the imath library) to accommodate architectures that don't deal + * well with 32-bit shifts. + */ + mp_size digits_to_copy = + (sizeof(unsigned long) + sizeof(mp_digit) - 1) / sizeof(mp_digit); + if (digits_to_copy > MP_USED(op)) { + digits_to_copy = MP_USED(op); + } + + mp_digit *digits = MP_DIGITS(op); + unsigned long out = 0; + + for (int i = digits_to_copy - 1; i >= 0; i--) { + out <<= (MP_DIGIT_BIT / 2); + out <<= (MP_DIGIT_BIT / 2); + out |= digits[i]; + } + + return out; +} + +/* gmp: mpz_get_ui */ +unsigned long GMPZAPI(get_ui)(mp_int op) { + unsigned long out; + + /* Try a standard conversion that fits into an unsigned long */ + mp_result res = mp_int_to_uint(op, &out); + if (res == MP_OK) return out; + + /* Abort the try if we don't have a range error in the conversion. + * The range error indicates that the value cannot fit into a long. */ + CHECK(res == MP_RANGE ? MP_OK : MP_RANGE); + if (res != MP_RANGE) return 0; + + return get_long_bits(op); +} + +/* gmp: mpz_get_si */ +long GMPZAPI(get_si)(mp_int op) { + long out; + unsigned long uout; + int long_msb; + + /* Try a standard conversion that fits into a long */ + mp_result res = mp_int_to_int(op, &out); + if (res == MP_OK) return out; + + /* Abort the try if we don't have a range error in the conversion. + * The range error indicates that the value cannot fit into a long. */ + CHECK(res == MP_RANGE ? MP_OK : MP_RANGE); + if (res != MP_RANGE) return 0; + + /* get least significant bits into an unsigned long */ + uout = get_long_bits(op); + + /* clear the top bit */ + long_msb = (sizeof(unsigned long) * 8) - 1; + uout &= (~(1UL << long_msb)); + + /* convert to negative if needed based on sign of op */ + if (MP_SIGN(op) == MP_NEG) { + uout = 0 - uout; + } + + out = (long)uout; + return out; +} + +/* gmp: mpz_lcm */ +void GMPZAPI(lcm)(mp_int rop, mp_int op1, mp_int op2) { + int op1_is_zero = mp_int_compare_zero(op1) == 0; + int op2_is_zero = mp_int_compare_zero(op2) == 0; + + if (op1_is_zero || op2_is_zero) { + mp_int_zero(rop); + return; + } + + CHECK(mp_int_lcm(op1, op2, rop)); + CHECK(mp_int_abs(rop, rop)); +} + +/* gmp: mpz_mul_2exp */ +/* gmp: allow big values for op2 when op1 == 0 */ +void GMPZAPI(mul_2exp)(mp_int rop, mp_int op1, unsigned long op2) { + if (mp_int_compare_zero(op1) == 0) + mp_int_zero(rop); + else + CHECK(mp_int_mul_pow2(op1, op2, rop)); +} + +/* + * Functions needing expanded functionality + */ +/* [Note]Overview of division implementation + + All division operations (N / D) compute q and r such that + + N = q * D + r, with 0 <= abs(r) < abs(d) + + The q and r values are not uniquely specified by N and D. To specify which q + and r values should be used, GMP implements three different rounding modes + for integer division: + + ceiling - round q twords +infinity, r has opposite sign as d + floor - round q twords -infinity, r has same sign as d + truncate - round q twords zero, r has same sign as n + + The imath library only supports truncate as a rounding mode. We need to + implement the other rounding modes in terms of truncating division. We first + perform the division in trucate mode and then adjust q accordingly. Once we + know q, we can easily compute the correct r according the the formula above + by computing: + + r = N - q * D + + The main task is to compute q. We can compute the correct q from a trucated + version as follows. + + For ceiling rounding mode, if q is less than 0 then the truncated rounding + mode is the same as the ceiling rounding mode. If q is greater than zero + then we need to round q up by one because the truncated version was rounded + down to zero. If q equals zero then check to see if the result of the + divison is positive. A positive result needs to increment q to one. + + For floor rounding mode, if q is greater than 0 then the trucated rounding + mode is the same as the floor rounding mode. If q is less than zero then we + need to round q down by one because the trucated mode rounded q up by one + twords zero. If q is zero then we need to check to see if the result of the + division is negative. A negative result needs to decrement q to negative + one. + */ + +/* gmp: mpz_cdiv_q */ +void GMPZAPI(cdiv_q)(mp_int q, mp_int n, mp_int d) { + mpz_t rz; + mp_int r = &rz; + int qsign, rsign, nsign, dsign; + CHECK(mp_int_init(r)); + + /* save signs before division because q can alias with n or d */ + nsign = mp_int_compare_zero(n); + dsign = mp_int_compare_zero(d); + + /* truncating division */ + CHECK(mp_int_div(n, d, q, r)); + + /* see: [Note]Overview of division implementation */ + qsign = mp_int_compare_zero(q); + rsign = mp_int_compare_zero(r); + if (qsign > 0) { /* q > 0 */ + if (rsign != 0) { /* r != 0 */ + CHECK(mp_int_add_value(q, 1, q)); + } + } else if (qsign == 0) { /* q == 0 */ + if (rsign != 0) { /* r != 0 */ + if ((nsign > 0 && dsign > 0) || (nsign < 0 && dsign < 0)) { + CHECK(mp_int_set_value(q, 1)); + } + } + } + mp_int_clear(r); +} + +/* gmp: mpz_fdiv_q */ +void GMPZAPI(fdiv_q)(mp_int q, mp_int n, mp_int d) { + mpz_t rz; + mp_int r = &rz; + int qsign, rsign, nsign, dsign; + CHECK(mp_int_init(r)); + + /* save signs before division because q can alias with n or d */ + nsign = mp_int_compare_zero(n); + dsign = mp_int_compare_zero(d); + + /* truncating division */ + CHECK(mp_int_div(n, d, q, r)); + + /* see: [Note]Overview of division implementation */ + qsign = mp_int_compare_zero(q); + rsign = mp_int_compare_zero(r); + if (qsign < 0) { /* q < 0 */ + if (rsign != 0) { /* r != 0 */ + CHECK(mp_int_sub_value(q, 1, q)); + } + } else if (qsign == 0) { /* q == 0 */ + if (rsign != 0) { /* r != 0 */ + if ((nsign < 0 && dsign > 0) || (nsign > 0 && dsign < 0)) { + CHECK(mp_int_set_value(q, -1)); + } + } + } + mp_int_clear(r); +} + +/* gmp: mpz_fdiv_r */ +void GMPZAPI(fdiv_r)(mp_int r, mp_int n, mp_int d) { + mpz_t qz; + mpz_t tempz; + mpz_t orig_dz; + mpz_t orig_nz; + mp_int q = &qz; + mp_int temp = &tempz; + mp_int orig_d = &orig_dz; + mp_int orig_n = &orig_nz; + CHECK(mp_int_init(q)); + CHECK(mp_int_init(temp)); + /* Make a copy of n in case n and d in case they overlap with q */ + CHECK(mp_int_init_copy(orig_d, d)); + CHECK(mp_int_init_copy(orig_n, n)); + + /* floor division */ + GMPZAPI(fdiv_q)(q, n, d); + + /* see: [Note]Overview of division implementation */ + /* n = q * d + r ==> r = n - q * d */ + mp_int_mul(q, orig_d, temp); + mp_int_sub(orig_n, temp, r); + + mp_int_clear(q); + mp_int_clear(temp); + mp_int_clear(orig_d); + mp_int_clear(orig_n); +} + +/* gmp: mpz_tdiv_q */ +void GMPZAPI(tdiv_q)(mp_int q, mp_int n, mp_int d) { + /* truncating division*/ + CHECK(mp_int_div(n, d, q, NULL)); +} + +/* gmp: mpz_fdiv_q_ui */ +unsigned long GMPZAPI(fdiv_q_ui)(mp_int q, mp_int n, unsigned long d) { + mpz_t tempz; + mp_int temp = &tempz; + mpz_t rz; + mp_int r = &rz; + mpz_t orig_nz; + mp_int orig_n = &orig_nz; + unsigned long rl; + CHECK(mp_int_init_uvalue(temp, d)); + CHECK(mp_int_init(r)); + /* Make a copy of n in case n and q overlap */ + CHECK(mp_int_init_copy(orig_n, n)); + + /* use floor division mode to compute q and r */ + GMPZAPI(fdiv_q)(q, n, temp); + GMPZAPI(fdiv_r)(r, orig_n, temp); + CHECK(mp_int_to_uint(r, &rl)); + + mp_int_clear(temp); + mp_int_clear(r); + mp_int_clear(orig_n); + + return rl; +} + +/* gmp: mpz_export */ +void *GMPZAPI(export)(void *rop, size_t *countp, int order, size_t size, + int endian, size_t nails, mp_int op) { + size_t i, j; + size_t num_used_bytes; + size_t num_words, num_missing_bytes; + ssize_t word_offset; + unsigned char *dst; + mp_digit *src; + int src_bits; + + /* We do not have a complete implementation. Assert to ensure our + * restrictions are in place. + */ + assert(nails == 0 && "Do not support non-full words"); + assert(endian == 1 || endian == 0 || endian == -1); + assert(order == 1 || order == -1); + + /* Test for zero */ + if (mp_int_compare_zero(op) == 0) { + if (countp) *countp = 0; + return rop; + } + + /* Calculate how many words we need */ + num_used_bytes = mp_int_unsigned_len(op); + num_words = (num_used_bytes + (size - 1)) / size; /* ceil division */ + assert(num_used_bytes > 0); + + /* Check to see if we will have missing bytes in the last word. + + Missing bytes can only occur when the size of words we output is + greater than the size of words used internally by imath. The number of + missing bytes is the number of bytes needed to fill out the last word. If + this number is greater than the size of a single mp_digit, then we need to + pad the word with extra zeros. Otherwise, the missing bytes can be filled + directly from the zeros in the last digit in the number. + */ + num_missing_bytes = (size * num_words) - num_used_bytes; + assert(num_missing_bytes < size); + + /* Allocate space for the result if needed */ + if (rop == NULL) { + rop = malloc(num_words * size); + } + + if (endian == 0) { + endian = HOST_ENDIAN; + } + + /* Initialize dst and src pointers */ + dst = (unsigned char *)rop + (order >= 0 ? (num_words - 1) * size : 0) + + (endian >= 0 ? size - 1 : 0); + src = MP_DIGITS(op); + src_bits = MP_DIGIT_BIT; + + word_offset = (endian >= 0 ? size : -size) + (order < 0 ? size : -size); + + for (i = 0; i < num_words; i++) { + for (j = 0; j < size && i * size + j < num_used_bytes; j++) { + if (src_bits == 0) { + ++src; + src_bits = MP_DIGIT_BIT; + } + *dst = (*src >> (MP_DIGIT_BIT - src_bits)) & 0xFF; + src_bits -= 8; + dst -= endian; + } + for (; j < size; j++) { + *dst = 0; + dst -= endian; + } + dst += word_offset; + } + + if (countp) *countp = num_words; + return rop; +} + +/* gmp: mpz_import */ +void GMPZAPI(import)(mp_int rop, size_t count, int order, size_t size, + int endian, size_t nails, const void *op) { + mpz_t tmpz; + mp_int tmp = &tmpz; + size_t total_size; + size_t num_digits; + ssize_t word_offset; + const unsigned char *src; + mp_digit *dst; + int dst_bits; + size_t i, j; + if (count == 0 || op == NULL) return; + + /* We do not have a complete implementation. Assert to ensure our + * restrictions are in place. */ + assert(nails == 0 && "Do not support non-full words"); + assert(endian == 1 || endian == 0 || endian == -1); + assert(order == 1 || order == -1); + + if (endian == 0) { + endian = HOST_ENDIAN; + } + + /* Compute number of needed digits by ceil division */ + total_size = count * size; + num_digits = (total_size + sizeof(mp_digit) - 1) / sizeof(mp_digit); + + /* Init temporary */ + mp_int_init_size(tmp, num_digits); + for (i = 0; i < num_digits; i++) tmp->digits[i] = 0; + + /* Copy bytes */ + src = (const unsigned char *)op + (order >= 0 ? (count - 1) * size : 0) + + (endian >= 0 ? size - 1 : 0); + dst = MP_DIGITS(tmp); + dst_bits = 0; + + word_offset = (endian >= 0 ? size : -size) + (order < 0 ? size : -size); + + for (i = 0; i < count; i++) { + for (j = 0; j < size; j++) { + if (dst_bits == MP_DIGIT_BIT) { + ++dst; + dst_bits = 0; + } + *dst |= ((mp_digit)*src) << dst_bits; + dst_bits += 8; + src -= endian; + } + src += word_offset; + } + + tmp->used = num_digits; + + /* Remove leading zeros from number */ + { + mp_size uz_ = tmp->used; + mp_digit *dz_ = MP_DIGITS(tmp) + uz_ - 1; + while (uz_ > 1 && (*dz_-- == 0)) --uz_; + tmp->used = uz_; + } + + /* Copy to destination */ + mp_int_copy(tmp, rop); + mp_int_clear(tmp); +} + +/* gmp: mpz_sizeinbase */ +size_t GMPZAPI(sizeinbase)(mp_int op, int base) { + mp_result res; + size_t size; + + /* If op == 0, return 1 */ + if (mp_int_compare_zero(op) == 0) return 1; + + /* Compute string length in base */ + res = mp_int_string_len(op, base); + CHECK((res > 0) == MP_OK); + + /* Now adjust the final size by getting rid of string artifacts */ + size = res; + + /* subtract one for the null terminator */ + size -= 1; + + /* subtract one for the negative sign */ + if (mp_int_compare_zero(op) < 0) size -= 1; + + return size; +} diff --git a/external/mit/isl/dist/imath/gmp_compat.h b/external/mit/isl/dist/imath/gmp_compat.h new file mode 100644 index 000000000000..949e377e9792 --- /dev/null +++ b/external/mit/isl/dist/imath/gmp_compat.h @@ -0,0 +1,229 @@ +/* + Name: gmp_compat.h + Purpose: Provide GMP compatiable routines for imath library + Author: David Peixotto + + Copyright (c) 2012 Qualcomm Innovation Center, Inc. All rights reserved. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +#ifndef IMATH_GMP_COMPAT_H_ +#define IMATH_GMP_COMPAT_H_ +#include "imath.h" +#include "imrat.h" +#include + +#define GMPZAPI(fun) impz_ ## fun +#define GMPQAPI(fun) impq_ ## fun + +#ifdef __cplusplus +extern "C" { +#endif +/************************************************************************* + * + * Functions with direct translations + * + *************************************************************************/ +/* gmp: mpq_clear */ +void GMPQAPI(clear)(mp_rat x); + +/* gmp: mpq_cmp */ +int GMPQAPI(cmp)(mp_rat op1, mp_rat op2); + +/* gmp: mpq_init */ +void GMPQAPI(init)(mp_rat x); + +/* gmp: mpq_mul */ +void GMPQAPI(mul)(mp_rat product, mp_rat multiplier, mp_rat multiplicand); + +/* gmp: mpq_set */ +void GMPQAPI(set)(mp_rat rop, mp_rat op); + +/* gmp: mpz_abs */ +void GMPZAPI(abs)(mp_int rop, mp_int op); + +/* gmp: mpz_add */ +void GMPZAPI(add)(mp_int rop, mp_int op1, mp_int op2); + +/* gmp: mpz_clear */ +void GMPZAPI(clear)(mp_int x); + +/* gmp: mpz_cmp_si */ +int GMPZAPI(cmp_si)(mp_int op1, long op2); + +/* gmp: mpz_cmpabs */ +int GMPZAPI(cmpabs)(mp_int op1, mp_int op2); + +/* gmp: mpz_cmp */ +int GMPZAPI(cmp)(mp_int op1, mp_int op2); + +/* gmp: mpz_init */ +void GMPZAPI(init)(mp_int x); + +/* gmp: mpz_mul */ +void GMPZAPI(mul)(mp_int rop, mp_int op1, mp_int op2); + +/* gmp: mpz_neg */ +void GMPZAPI(neg)(mp_int rop, mp_int op); + +/* gmp: mpz_set_si */ +void GMPZAPI(set_si)(mp_int rop, long op); + +/* gmp: mpz_set */ +void GMPZAPI(set)(mp_int rop, mp_int op); + +/* gmp: mpz_sub */ +void GMPZAPI(sub)(mp_int rop, mp_int op1, mp_int op2); + +/* gmp: mpz_swap */ +void GMPZAPI(swap)(mp_int rop1, mp_int rop2); + +/* gmp: mpq_sgn */ +int GMPQAPI(sgn)(mp_rat op); + +/* gmp: mpz_sgn */ +int GMPZAPI(sgn)(mp_int op); + +/* gmp: mpq_set_ui */ +void GMPQAPI(set_ui)(mp_rat rop, unsigned long op1, unsigned long op2); + +/* gmp: mpz_set_ui */ +void GMPZAPI(set_ui)(mp_int rop, unsigned long op); + +/* gmp: mpq_den_ref */ +mp_int GMPQAPI(denref)(mp_rat op); + +/* gmp: mpq_num_ref */ +mp_int GMPQAPI(numref)(mp_rat op); + +/* gmp: mpq_canonicalize */ +void GMPQAPI(canonicalize)(mp_rat op); + +/************************************************************************* + * + * Functions that can be implemented as a combination of imath functions + * + *************************************************************************/ +/* gmp: mpz_addmul */ +void GMPZAPI(addmul)(mp_int rop, mp_int op1, mp_int op2); + +/* gmp: mpz_divexact */ +void GMPZAPI(divexact)(mp_int q, mp_int n, mp_int d); + +/* gmp: mpz_divisible_p */ +int GMPZAPI(divisible_p)(mp_int n, mp_int d); + +/* gmp: mpz_submul */ +void GMPZAPI(submul)(mp_int rop, mp_int op1, mp_int op2); + +/* gmp: mpz_add_ui */ +void GMPZAPI(add_ui)(mp_int rop, mp_int op1, unsigned long op2); + +/* gmp: mpz_divexact_ui */ +void GMPZAPI(divexact_ui)(mp_int q, mp_int n, unsigned long d); + +/* gmp: mpz_mul_ui */ +void GMPZAPI(mul_ui)(mp_int rop, mp_int op1, unsigned long op2); + +/* gmp: mpz_pow_ui */ +void GMPZAPI(pow_ui)(mp_int rop, mp_int base, unsigned long exp); + +/* gmp: mpz_sub_ui */ +void GMPZAPI(sub_ui)(mp_int rop, mp_int op1, unsigned long op2); + +/* gmp: mpz_fdiv_q_ui */ +unsigned long GMPZAPI(fdiv_q_ui)(mp_int q, mp_int n, unsigned long d); + +/* gmp: mpz_sizeinbase */ +size_t GMPZAPI(sizeinbase)(mp_int op, int base); + +/************************************************************************* + * + * Functions with different behavior in corner cases + * + *************************************************************************/ +/* gmp: mpz_gcd */ +/* gmp: When op1 = 0 and op2 = 0, return 0.*/ +void GMPZAPI(gcd)(mp_int rop, mp_int op1, mp_int op2); + +/* gmp: mpz_get_str */ +/* gmp: If str is NULL then allocate space using the default allocator. */ +char* GMPZAPI(get_str)(char *str, int radix, mp_int op); + +/* gmp: mpq_get_str */ +/* gmp: If str is NULL then allocate space using the default allocator. */ +/* gmp: If value is a whole number do not print denomenator. */ +/* TODO: Need to handle 0 values better. GMP prints 0/4 instead of 0.*/ +char* GMPQAPI(get_str)(char *str, int radix, mp_rat op); + +/* gmp: mpz_set_str */ +/* gmp: Allow and ignore spaces in string. */ +int GMPZAPI(set_str)(mp_int rop, char *str, int base); + +/* gmp: mpq_set_str */ +int GMPQAPI(set_str)(mp_rat rop, char *str, int base); + +/* gmp: mpz_get_ui */ +/* gmp: Return least significant bits if value is too big for a long. */ +unsigned long GMPZAPI(get_ui)(mp_int op); + +/* gmp: mpz_get_si */ +/* gmp: Return least significant bits if value is too bit for a long. */ +/* gmp: If value is too big for long, return the least significant + (8*sizeof(long)-1) bits from the op and set the sign bit according to + the sign of the op. */ +long GMPZAPI(get_si)(mp_int op); + +/* gmp: mpz_lcm */ +/* gmp: When op1 = 0 or op2 = 0, return 0.*/ +/* gmp: The resutl of lcm(a,b) is always positive. */ +void GMPZAPI(lcm)(mp_int rop, mp_int op1, mp_int op2); + +/* gmp: mpz_mul_2exp */ +/* gmp: allow big values for op2 when op1 == 0 */ +void GMPZAPI(mul_2exp)(mp_int rop, mp_int op1, unsigned long op2); + +/************************************************************************* + * + * Functions needing expanded functionality + * + *************************************************************************/ +/* gmp: mpz_cdiv_q */ +void GMPZAPI(cdiv_q)(mp_int q, mp_int n, mp_int d); + +/* gmp: mpz_fdiv_q */ +void GMPZAPI(fdiv_q)(mp_int q, mp_int n, mp_int d); + +/* gmp: mpz_fdiv_r */ +void GMPZAPI(fdiv_r)(mp_int r, mp_int n, mp_int d); + +/* gmp: mpz_tdiv_q */ +void GMPZAPI(tdiv_q)(mp_int q, mp_int n, mp_int d); + +/* gmp: mpz_export */ +void* GMPZAPI(export)(void *rop, size_t *countp, int order, size_t size, int endian, size_t nails, mp_int op); + +/* gmp: mpz_import */ +void GMPZAPI(import)(mp_int rop, size_t count, int order, size_t size, int endian, size_t nails, const void* op); + +#ifdef __cplusplus +} +#endif +#endif /* end IMATH_GMP_COMPAT_H_ */ diff --git a/external/mit/isl/dist/imath/imath.c b/external/mit/isl/dist/imath/imath.c new file mode 100644 index 000000000000..26dc91f35e43 --- /dev/null +++ b/external/mit/isl/dist/imath/imath.c @@ -0,0 +1,2780 @@ +/* + Name: imath.c + Purpose: Arbitrary precision integer arithmetic routines. + Author: M. J. Fromberger + + Copyright (C) 2002-2007 Michael J. Fromberger, All Rights Reserved. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +#include "imath.h" + +#include +#include +#include +#include + +const mp_result MP_OK = 0; /* no error, all is well */ +const mp_result MP_FALSE = 0; /* boolean false */ +const mp_result MP_TRUE = -1; /* boolean true */ +const mp_result MP_MEMORY = -2; /* out of memory */ +const mp_result MP_RANGE = -3; /* argument out of range */ +const mp_result MP_UNDEF = -4; /* result undefined */ +const mp_result MP_TRUNC = -5; /* output truncated */ +const mp_result MP_BADARG = -6; /* invalid null argument */ +const mp_result MP_MINERR = -6; + +const mp_sign MP_NEG = 1; /* value is strictly negative */ +const mp_sign MP_ZPOS = 0; /* value is non-negative */ + +static const char *s_unknown_err = "unknown result code"; +static const char *s_error_msg[] = {"error code 0", "boolean true", + "out of memory", "argument out of range", + "result undefined", "output truncated", + "invalid argument", NULL}; + +/* The ith entry of this table gives the value of log_i(2). + + An integer value n requires ceil(log_i(n)) digits to be represented + in base i. Since it is easy to compute lg(n), by counting bits, we + can compute log_i(n) = lg(n) * log_i(2). + + The use of this table eliminates a dependency upon linkage against + the standard math libraries. + + If MP_MAX_RADIX is increased, this table should be expanded too. + */ +static const double s_log2[] = { + 0.000000000, 0.000000000, 1.000000000, 0.630929754, /* (D)(D) 2 3 */ + 0.500000000, 0.430676558, 0.386852807, 0.356207187, /* 4 5 6 7 */ + 0.333333333, 0.315464877, 0.301029996, 0.289064826, /* 8 9 10 11 */ + 0.278942946, 0.270238154, 0.262649535, 0.255958025, /* 12 13 14 15 */ + 0.250000000, 0.244650542, 0.239812467, 0.235408913, /* 16 17 18 19 */ + 0.231378213, 0.227670249, 0.224243824, 0.221064729, /* 20 21 22 23 */ + 0.218104292, 0.215338279, 0.212746054, 0.210309918, /* 24 25 26 27 */ + 0.208014598, 0.205846832, 0.203795047, 0.201849087, /* 28 29 30 31 */ + 0.200000000, 0.198239863, 0.196561632, 0.194959022, /* 32 33 34 35 */ + 0.193426404, /* 36 */ +}; + +/* Return the number of digits needed to represent a static value */ +#define MP_VALUE_DIGITS(V) \ + ((sizeof(V) + (sizeof(mp_digit) - 1)) / sizeof(mp_digit)) + +/* Round precision P to nearest word boundary */ +static inline mp_size s_round_prec(mp_size P) { return 2 * ((P + 1) / 2); } + +/* Set array P of S digits to zero */ +static inline void ZERO(mp_digit *P, mp_size S) { + mp_size i__ = S * sizeof(mp_digit); + mp_digit *p__ = P; + memset(p__, 0, i__); +} + +/* Copy S digits from array P to array Q */ +static inline void COPY(mp_digit *P, mp_digit *Q, mp_size S) { + mp_size i__ = S * sizeof(mp_digit); + mp_digit *p__ = P; + mp_digit *q__ = Q; + memcpy(q__, p__, i__); +} + +/* Reverse N elements of unsigned char in A. */ +static inline void REV(unsigned char *A, int N) { + unsigned char *u_ = A; + unsigned char *v_ = u_ + N - 1; + while (u_ < v_) { + unsigned char xch = *u_; + *u_++ = *v_; + *v_-- = xch; + } +} + +/* Strip leading zeroes from z_ in-place. */ +static inline void CLAMP(mp_int z_) { + mp_size uz_ = MP_USED(z_); + mp_digit *dz_ = MP_DIGITS(z_) + uz_ - 1; + while (uz_ > 1 && (*dz_-- == 0)) --uz_; + z_->used = uz_; +} + +/* Select min/max. */ +static inline int MIN(int A, int B) { return (B < A ? B : A); } +static inline mp_size MAX(mp_size A, mp_size B) { return (B > A ? B : A); } + +/* Exchange lvalues A and B of type T, e.g. + SWAP(int, x, y) where x and y are variables of type int. */ +#define SWAP(T, A, B) \ + do { \ + T t_ = (A); \ + A = (B); \ + B = t_; \ + } while (0) + +/* Declare a block of N temporary mpz_t values. + These values are initialized to zero. + You must add CLEANUP_TEMP() at the end of the function. + Use TEMP(i) to access a pointer to the ith value. + */ +#define DECLARE_TEMP(N) \ + struct { \ + mpz_t value[(N)]; \ + int len; \ + mp_result err; \ + } temp_ = { \ + .len = (N), \ + .err = MP_OK, \ + }; \ + do { \ + for (int i = 0; i < temp_.len; i++) { \ + mp_int_init(TEMP(i)); \ + } \ + } while (0) + +/* Clear all allocated temp values. */ +#define CLEANUP_TEMP() \ + CLEANUP: \ + do { \ + for (int i = 0; i < temp_.len; i++) { \ + mp_int_clear(TEMP(i)); \ + } \ + if (temp_.err != MP_OK) { \ + return temp_.err; \ + } \ + } while (0) + +/* A pointer to the kth temp value. */ +#define TEMP(K) (temp_.value + (K)) + +/* Evaluate E, an expression of type mp_result expected to return MP_OK. If + the value is not MP_OK, the error is cached and control resumes at the + cleanup handler, which returns it. +*/ +#define REQUIRE(E) \ + do { \ + temp_.err = (E); \ + if (temp_.err != MP_OK) goto CLEANUP; \ + } while (0) + +/* Compare value to zero. */ +static inline int CMPZ(mp_int Z) { + if (Z->used == 1 && Z->digits[0] == 0) return 0; + return (Z->sign == MP_NEG) ? -1 : 1; +} + +static inline mp_word UPPER_HALF(mp_word W) { return (W >> MP_DIGIT_BIT); } +static inline mp_digit LOWER_HALF(mp_word W) { return (mp_digit)(W); } + +/* Report whether the highest-order bit of W is 1. */ +static inline bool HIGH_BIT_SET(mp_word W) { + return (W >> (MP_WORD_BIT - 1)) != 0; +} + +/* Report whether adding W + V will carry out. */ +static inline bool ADD_WILL_OVERFLOW(mp_word W, mp_word V) { + return ((MP_WORD_MAX - V) < W); +} + +/* Default number of digits allocated to a new mp_int */ +static mp_size default_precision = 8; + +void mp_int_default_precision(mp_size size) { + assert(size > 0); + default_precision = size; +} + +/* Minimum number of digits to invoke recursive multiply */ +static mp_size multiply_threshold = 32; + +void mp_int_multiply_threshold(mp_size thresh) { + assert(thresh >= sizeof(mp_word)); + multiply_threshold = thresh; +} + +/* Allocate a buffer of (at least) num digits, or return + NULL if that couldn't be done. */ +static mp_digit *s_alloc(mp_size num); + +/* Release a buffer of digits allocated by s_alloc(). */ +static void s_free(void *ptr); + +/* Insure that z has at least min digits allocated, resizing if + necessary. Returns true if successful, false if out of memory. */ +static bool s_pad(mp_int z, mp_size min); + +/* Ensure Z has at least N digits allocated. */ +static inline mp_result GROW(mp_int Z, mp_size N) { + return s_pad(Z, N) ? MP_OK : MP_MEMORY; +} + +/* Fill in a "fake" mp_int on the stack with a given value */ +static void s_fake(mp_int z, mp_small value, mp_digit vbuf[]); +static void s_ufake(mp_int z, mp_usmall value, mp_digit vbuf[]); + +/* Compare two runs of digits of given length, returns <0, 0, >0 */ +static int s_cdig(mp_digit *da, mp_digit *db, mp_size len); + +/* Pack the unsigned digits of v into array t */ +static int s_uvpack(mp_usmall v, mp_digit t[]); + +/* Compare magnitudes of a and b, returns <0, 0, >0 */ +static int s_ucmp(mp_int a, mp_int b); + +/* Compare magnitudes of a and v, returns <0, 0, >0 */ +static int s_vcmp(mp_int a, mp_small v); +static int s_uvcmp(mp_int a, mp_usmall uv); + +/* Unsigned magnitude addition; assumes dc is big enough. + Carry out is returned (no memory allocated). */ +static mp_digit s_uadd(mp_digit *da, mp_digit *db, mp_digit *dc, mp_size size_a, + mp_size size_b); + +/* Unsigned magnitude subtraction. Assumes dc is big enough. */ +static void s_usub(mp_digit *da, mp_digit *db, mp_digit *dc, mp_size size_a, + mp_size size_b); + +/* Unsigned recursive multiplication. Assumes dc is big enough. */ +static int s_kmul(mp_digit *da, mp_digit *db, mp_digit *dc, mp_size size_a, + mp_size size_b); + +/* Unsigned magnitude multiplication. Assumes dc is big enough. */ +static void s_umul(mp_digit *da, mp_digit *db, mp_digit *dc, mp_size size_a, + mp_size size_b); + +/* Unsigned recursive squaring. Assumes dc is big enough. */ +static int s_ksqr(mp_digit *da, mp_digit *dc, mp_size size_a); + +/* Unsigned magnitude squaring. Assumes dc is big enough. */ +static void s_usqr(mp_digit *da, mp_digit *dc, mp_size size_a); + +/* Single digit addition. Assumes a is big enough. */ +static void s_dadd(mp_int a, mp_digit b); + +/* Single digit multiplication. Assumes a is big enough. */ +static void s_dmul(mp_int a, mp_digit b); + +/* Single digit multiplication on buffers; assumes dc is big enough. */ +static void s_dbmul(mp_digit *da, mp_digit b, mp_digit *dc, mp_size size_a); + +/* Single digit division. Replaces a with the quotient, + returns the remainder. */ +static mp_digit s_ddiv(mp_int a, mp_digit b); + +/* Quick division by a power of 2, replaces z (no allocation) */ +static void s_qdiv(mp_int z, mp_size p2); + +/* Quick remainder by a power of 2, replaces z (no allocation) */ +static void s_qmod(mp_int z, mp_size p2); + +/* Quick multiplication by a power of 2, replaces z. + Allocates if necessary; returns false in case this fails. */ +static int s_qmul(mp_int z, mp_size p2); + +/* Quick subtraction from a power of 2, replaces z. + Allocates if necessary; returns false in case this fails. */ +static int s_qsub(mp_int z, mp_size p2); + +/* Return maximum k such that 2^k divides z. */ +static int s_dp2k(mp_int z); + +/* Return k >= 0 such that z = 2^k, or -1 if there is no such k. */ +static int s_isp2(mp_int z); + +/* Set z to 2^k. May allocate; returns false in case this fails. */ +static int s_2expt(mp_int z, mp_small k); + +/* Normalize a and b for division, returns normalization constant */ +static int s_norm(mp_int a, mp_int b); + +/* Compute constant mu for Barrett reduction, given modulus m, result + replaces z, m is untouched. */ +static mp_result s_brmu(mp_int z, mp_int m); + +/* Reduce a modulo m, using Barrett's algorithm. */ +static int s_reduce(mp_int x, mp_int m, mp_int mu, mp_int q1, mp_int q2); + +/* Modular exponentiation, using Barrett reduction */ +static mp_result s_embar(mp_int a, mp_int b, mp_int m, mp_int mu, mp_int c); + +/* Unsigned magnitude division. Assumes |a| > |b|. Allocates temporaries; + overwrites a with quotient, b with remainder. */ +static mp_result s_udiv_knuth(mp_int a, mp_int b); + +/* Compute the number of digits in radix r required to represent the given + value. Does not account for sign flags, terminators, etc. */ +static int s_outlen(mp_int z, mp_size r); + +/* Guess how many digits of precision will be needed to represent a radix r + value of the specified number of digits. Returns a value guaranteed to be + no smaller than the actual number required. */ +static mp_size s_inlen(int len, mp_size r); + +/* Convert a character to a digit value in radix r, or + -1 if out of range */ +static int s_ch2val(char c, int r); + +/* Convert a digit value to a character */ +static char s_val2ch(int v, int caps); + +/* Take 2's complement of a buffer in place */ +static void s_2comp(unsigned char *buf, int len); + +/* Convert a value to binary, ignoring sign. On input, *limpos is the bound on + how many bytes should be written to buf; on output, *limpos is set to the + number of bytes actually written. */ +static mp_result s_tobin(mp_int z, unsigned char *buf, int *limpos, int pad); + +/* Multiply X by Y into Z, ignoring signs. Requires that Z have enough storage + preallocated to hold the result. */ +static inline void UMUL(mp_int X, mp_int Y, mp_int Z) { + mp_size ua_ = MP_USED(X); + mp_size ub_ = MP_USED(Y); + mp_size o_ = ua_ + ub_; + ZERO(MP_DIGITS(Z), o_); + (void)s_kmul(MP_DIGITS(X), MP_DIGITS(Y), MP_DIGITS(Z), ua_, ub_); + Z->used = o_; + CLAMP(Z); +} + +/* Square X into Z. Requires that Z have enough storage to hold the result. */ +static inline void USQR(mp_int X, mp_int Z) { + mp_size ua_ = MP_USED(X); + mp_size o_ = ua_ + ua_; + ZERO(MP_DIGITS(Z), o_); + (void)s_ksqr(MP_DIGITS(X), MP_DIGITS(Z), ua_); + Z->used = o_; + CLAMP(Z); +} + +mp_result mp_int_init(mp_int z) { + if (z == NULL) return MP_BADARG; + + z->single = 0; + z->digits = &(z->single); + z->alloc = 1; + z->used = 1; + z->sign = MP_ZPOS; + + return MP_OK; +} + +mp_int mp_int_alloc(void) { + mp_int out = malloc(sizeof(mpz_t)); + + if (out != NULL) mp_int_init(out); + + return out; +} + +mp_result mp_int_init_size(mp_int z, mp_size prec) { + assert(z != NULL); + + if (prec == 0) { + prec = default_precision; + } else if (prec == 1) { + return mp_int_init(z); + } else { + prec = s_round_prec(prec); + } + + z->digits = s_alloc(prec); + if (MP_DIGITS(z) == NULL) return MP_MEMORY; + + z->digits[0] = 0; + z->used = 1; + z->alloc = prec; + z->sign = MP_ZPOS; + + return MP_OK; +} + +mp_result mp_int_init_copy(mp_int z, mp_int old) { + assert(z != NULL && old != NULL); + + mp_size uold = MP_USED(old); + if (uold == 1) { + mp_int_init(z); + } else { + mp_size target = MAX(uold, default_precision); + mp_result res = mp_int_init_size(z, target); + if (res != MP_OK) return res; + } + + z->used = uold; + z->sign = old->sign; + COPY(MP_DIGITS(old), MP_DIGITS(z), uold); + + return MP_OK; +} + +mp_result mp_int_init_value(mp_int z, mp_small value) { + mpz_t vtmp; + mp_digit vbuf[MP_VALUE_DIGITS(value)]; + + s_fake(&vtmp, value, vbuf); + return mp_int_init_copy(z, &vtmp); +} + +mp_result mp_int_init_uvalue(mp_int z, mp_usmall uvalue) { + mpz_t vtmp; + mp_digit vbuf[MP_VALUE_DIGITS(uvalue)]; + + s_ufake(&vtmp, uvalue, vbuf); + return mp_int_init_copy(z, &vtmp); +} + +mp_result mp_int_set_value(mp_int z, mp_small value) { + mpz_t vtmp; + mp_digit vbuf[MP_VALUE_DIGITS(value)]; + + s_fake(&vtmp, value, vbuf); + return mp_int_copy(&vtmp, z); +} + +mp_result mp_int_set_uvalue(mp_int z, mp_usmall uvalue) { + mpz_t vtmp; + mp_digit vbuf[MP_VALUE_DIGITS(uvalue)]; + + s_ufake(&vtmp, uvalue, vbuf); + return mp_int_copy(&vtmp, z); +} + +void mp_int_clear(mp_int z) { + if (z == NULL) return; + + if (MP_DIGITS(z) != NULL) { + if (MP_DIGITS(z) != &(z->single)) s_free(MP_DIGITS(z)); + + z->digits = NULL; + } +} + +void mp_int_free(mp_int z) { + assert(z != NULL); + + mp_int_clear(z); + free(z); /* note: NOT s_free() */ +} + +mp_result mp_int_copy(mp_int a, mp_int c) { + assert(a != NULL && c != NULL); + + if (a != c) { + mp_size ua = MP_USED(a); + mp_digit *da, *dc; + + if (!s_pad(c, ua)) return MP_MEMORY; + + da = MP_DIGITS(a); + dc = MP_DIGITS(c); + COPY(da, dc, ua); + + c->used = ua; + c->sign = a->sign; + } + + return MP_OK; +} + +void mp_int_swap(mp_int a, mp_int c) { + if (a != c) { + mpz_t tmp = *a; + + *a = *c; + *c = tmp; + + if (MP_DIGITS(a) == &(c->single)) a->digits = &(a->single); + if (MP_DIGITS(c) == &(a->single)) c->digits = &(c->single); + } +} + +void mp_int_zero(mp_int z) { + assert(z != NULL); + + z->digits[0] = 0; + z->used = 1; + z->sign = MP_ZPOS; +} + +mp_result mp_int_abs(mp_int a, mp_int c) { + assert(a != NULL && c != NULL); + + mp_result res; + if ((res = mp_int_copy(a, c)) != MP_OK) return res; + + c->sign = MP_ZPOS; + return MP_OK; +} + +mp_result mp_int_neg(mp_int a, mp_int c) { + assert(a != NULL && c != NULL); + + mp_result res; + if ((res = mp_int_copy(a, c)) != MP_OK) return res; + + if (CMPZ(c) != 0) c->sign = 1 - MP_SIGN(a); + + return MP_OK; +} + +mp_result mp_int_add(mp_int a, mp_int b, mp_int c) { + assert(a != NULL && b != NULL && c != NULL); + + mp_size ua = MP_USED(a); + mp_size ub = MP_USED(b); + mp_size max = MAX(ua, ub); + + if (MP_SIGN(a) == MP_SIGN(b)) { + /* Same sign -- add magnitudes, preserve sign of addends */ + if (!s_pad(c, max)) return MP_MEMORY; + + mp_digit carry = s_uadd(MP_DIGITS(a), MP_DIGITS(b), MP_DIGITS(c), ua, ub); + mp_size uc = max; + + if (carry) { + if (!s_pad(c, max + 1)) return MP_MEMORY; + + c->digits[max] = carry; + ++uc; + } + + c->used = uc; + c->sign = a->sign; + + } else { + /* Different signs -- subtract magnitudes, preserve sign of greater */ + int cmp = s_ucmp(a, b); /* magnitude comparison, sign ignored */ + + /* Set x to max(a, b), y to min(a, b) to simplify later code. + A special case yields zero for equal magnitudes. + */ + mp_int x, y; + if (cmp == 0) { + mp_int_zero(c); + return MP_OK; + } else if (cmp < 0) { + x = b; + y = a; + } else { + x = a; + y = b; + } + + if (!s_pad(c, MP_USED(x))) return MP_MEMORY; + + /* Subtract smaller from larger */ + s_usub(MP_DIGITS(x), MP_DIGITS(y), MP_DIGITS(c), MP_USED(x), MP_USED(y)); + c->used = x->used; + CLAMP(c); + + /* Give result the sign of the larger */ + c->sign = x->sign; + } + + return MP_OK; +} + +mp_result mp_int_add_value(mp_int a, mp_small value, mp_int c) { + mpz_t vtmp; + mp_digit vbuf[MP_VALUE_DIGITS(value)]; + + s_fake(&vtmp, value, vbuf); + + return mp_int_add(a, &vtmp, c); +} + +mp_result mp_int_sub(mp_int a, mp_int b, mp_int c) { + assert(a != NULL && b != NULL && c != NULL); + + mp_size ua = MP_USED(a); + mp_size ub = MP_USED(b); + mp_size max = MAX(ua, ub); + + if (MP_SIGN(a) != MP_SIGN(b)) { + /* Different signs -- add magnitudes and keep sign of a */ + if (!s_pad(c, max)) return MP_MEMORY; + + mp_digit carry = s_uadd(MP_DIGITS(a), MP_DIGITS(b), MP_DIGITS(c), ua, ub); + mp_size uc = max; + + if (carry) { + if (!s_pad(c, max + 1)) return MP_MEMORY; + + c->digits[max] = carry; + ++uc; + } + + c->used = uc; + c->sign = a->sign; + + } else { + /* Same signs -- subtract magnitudes */ + if (!s_pad(c, max)) return MP_MEMORY; + mp_int x, y; + mp_sign osign; + + int cmp = s_ucmp(a, b); + if (cmp >= 0) { + x = a; + y = b; + osign = MP_ZPOS; + } else { + x = b; + y = a; + osign = MP_NEG; + } + + if (MP_SIGN(a) == MP_NEG && cmp != 0) osign = 1 - osign; + + s_usub(MP_DIGITS(x), MP_DIGITS(y), MP_DIGITS(c), MP_USED(x), MP_USED(y)); + c->used = x->used; + CLAMP(c); + + c->sign = osign; + } + + return MP_OK; +} + +mp_result mp_int_sub_value(mp_int a, mp_small value, mp_int c) { + mpz_t vtmp; + mp_digit vbuf[MP_VALUE_DIGITS(value)]; + + s_fake(&vtmp, value, vbuf); + + return mp_int_sub(a, &vtmp, c); +} + +mp_result mp_int_mul(mp_int a, mp_int b, mp_int c) { + assert(a != NULL && b != NULL && c != NULL); + + /* If either input is zero, we can shortcut multiplication */ + if (mp_int_compare_zero(a) == 0 || mp_int_compare_zero(b) == 0) { + mp_int_zero(c); + return MP_OK; + } + + /* Output is positive if inputs have same sign, otherwise negative */ + mp_sign osign = (MP_SIGN(a) == MP_SIGN(b)) ? MP_ZPOS : MP_NEG; + + /* If the output is not identical to any of the inputs, we'll write the + results directly; otherwise, allocate a temporary space. */ + mp_size ua = MP_USED(a); + mp_size ub = MP_USED(b); + mp_size osize = MAX(ua, ub); + osize = 4 * ((osize + 1) / 2); + + mp_digit *out; + mp_size p = 0; + if (c == a || c == b) { + p = MAX(s_round_prec(osize), default_precision); + + if ((out = s_alloc(p)) == NULL) return MP_MEMORY; + } else { + if (!s_pad(c, osize)) return MP_MEMORY; + + out = MP_DIGITS(c); + } + ZERO(out, osize); + + if (!s_kmul(MP_DIGITS(a), MP_DIGITS(b), out, ua, ub)) return MP_MEMORY; + + /* If we allocated a new buffer, get rid of whatever memory c was already + using, and fix up its fields to reflect that. + */ + if (out != MP_DIGITS(c)) { + if ((void *)MP_DIGITS(c) != (void *)c) s_free(MP_DIGITS(c)); + c->digits = out; + c->alloc = p; + } + + c->used = osize; /* might not be true, but we'll fix it ... */ + CLAMP(c); /* ... right here */ + c->sign = osign; + + return MP_OK; +} + +mp_result mp_int_mul_value(mp_int a, mp_small value, mp_int c) { + mpz_t vtmp; + mp_digit vbuf[MP_VALUE_DIGITS(value)]; + + s_fake(&vtmp, value, vbuf); + + return mp_int_mul(a, &vtmp, c); +} + +mp_result mp_int_mul_pow2(mp_int a, mp_small p2, mp_int c) { + assert(a != NULL && c != NULL && p2 >= 0); + + mp_result res = mp_int_copy(a, c); + if (res != MP_OK) return res; + + if (s_qmul(c, (mp_size)p2)) { + return MP_OK; + } else { + return MP_MEMORY; + } +} + +mp_result mp_int_sqr(mp_int a, mp_int c) { + assert(a != NULL && c != NULL); + + /* Get a temporary buffer big enough to hold the result */ + mp_size osize = (mp_size)4 * ((MP_USED(a) + 1) / 2); + mp_size p = 0; + mp_digit *out; + if (a == c) { + p = s_round_prec(osize); + p = MAX(p, default_precision); + + if ((out = s_alloc(p)) == NULL) return MP_MEMORY; + } else { + if (!s_pad(c, osize)) return MP_MEMORY; + + out = MP_DIGITS(c); + } + ZERO(out, osize); + + s_ksqr(MP_DIGITS(a), out, MP_USED(a)); + + /* Get rid of whatever memory c was already using, and fix up its fields to + reflect the new digit array it's using + */ + if (out != MP_DIGITS(c)) { + if ((void *)MP_DIGITS(c) != (void *)c) s_free(MP_DIGITS(c)); + c->digits = out; + c->alloc = p; + } + + c->used = osize; /* might not be true, but we'll fix it ... */ + CLAMP(c); /* ... right here */ + c->sign = MP_ZPOS; + + return MP_OK; +} + +mp_result mp_int_div(mp_int a, mp_int b, mp_int q, mp_int r) { + assert(a != NULL && b != NULL && q != r); + + int cmp; + mp_result res = MP_OK; + mp_int qout, rout; + mp_sign sa = MP_SIGN(a); + mp_sign sb = MP_SIGN(b); + if (CMPZ(b) == 0) { + return MP_UNDEF; + } else if ((cmp = s_ucmp(a, b)) < 0) { + /* If |a| < |b|, no division is required: + q = 0, r = a + */ + if (r && (res = mp_int_copy(a, r)) != MP_OK) return res; + + if (q) mp_int_zero(q); + + return MP_OK; + } else if (cmp == 0) { + /* If |a| = |b|, no division is required: + q = 1 or -1, r = 0 + */ + if (r) mp_int_zero(r); + + if (q) { + mp_int_zero(q); + q->digits[0] = 1; + + if (sa != sb) q->sign = MP_NEG; + } + + return MP_OK; + } + + /* When |a| > |b|, real division is required. We need someplace to store + quotient and remainder, but q and r are allowed to be NULL or to overlap + with the inputs. + */ + DECLARE_TEMP(2); + int lg; + if ((lg = s_isp2(b)) < 0) { + if (q && b != q) { + REQUIRE(mp_int_copy(a, q)); + qout = q; + } else { + REQUIRE(mp_int_copy(a, TEMP(0))); + qout = TEMP(0); + } + + if (r && a != r) { + REQUIRE(mp_int_copy(b, r)); + rout = r; + } else { + REQUIRE(mp_int_copy(b, TEMP(1))); + rout = TEMP(1); + } + + REQUIRE(s_udiv_knuth(qout, rout)); + } else { + if (q) REQUIRE(mp_int_copy(a, q)); + if (r) REQUIRE(mp_int_copy(a, r)); + + if (q) s_qdiv(q, (mp_size)lg); + qout = q; + if (r) s_qmod(r, (mp_size)lg); + rout = r; + } + + /* Recompute signs for output */ + if (rout) { + rout->sign = sa; + if (CMPZ(rout) == 0) rout->sign = MP_ZPOS; + } + if (qout) { + qout->sign = (sa == sb) ? MP_ZPOS : MP_NEG; + if (CMPZ(qout) == 0) qout->sign = MP_ZPOS; + } + + if (q) REQUIRE(mp_int_copy(qout, q)); + if (r) REQUIRE(mp_int_copy(rout, r)); + CLEANUP_TEMP(); + return res; +} + +mp_result mp_int_mod(mp_int a, mp_int m, mp_int c) { + DECLARE_TEMP(1); + mp_int out = (m == c) ? TEMP(0) : c; + REQUIRE(mp_int_div(a, m, NULL, out)); + if (CMPZ(out) < 0) { + REQUIRE(mp_int_add(out, m, c)); + } else { + REQUIRE(mp_int_copy(out, c)); + } + CLEANUP_TEMP(); + return MP_OK; +} + +mp_result mp_int_div_value(mp_int a, mp_small value, mp_int q, mp_small *r) { + mpz_t vtmp; + mp_digit vbuf[MP_VALUE_DIGITS(value)]; + s_fake(&vtmp, value, vbuf); + + DECLARE_TEMP(1); + REQUIRE(mp_int_div(a, &vtmp, q, TEMP(0))); + + if (r) (void)mp_int_to_int(TEMP(0), r); /* can't fail */ + + CLEANUP_TEMP(); + return MP_OK; +} + +mp_result mp_int_div_pow2(mp_int a, mp_small p2, mp_int q, mp_int r) { + assert(a != NULL && p2 >= 0 && q != r); + + mp_result res = MP_OK; + if (q != NULL && (res = mp_int_copy(a, q)) == MP_OK) { + s_qdiv(q, (mp_size)p2); + } + + if (res == MP_OK && r != NULL && (res = mp_int_copy(a, r)) == MP_OK) { + s_qmod(r, (mp_size)p2); + } + + return res; +} + +mp_result mp_int_expt(mp_int a, mp_small b, mp_int c) { + assert(c != NULL); + if (b < 0) return MP_RANGE; + + DECLARE_TEMP(1); + REQUIRE(mp_int_copy(a, TEMP(0))); + + (void)mp_int_set_value(c, 1); + unsigned int v = labs(b); + while (v != 0) { + if (v & 1) { + REQUIRE(mp_int_mul(c, TEMP(0), c)); + } + + v >>= 1; + if (v == 0) break; + + REQUIRE(mp_int_sqr(TEMP(0), TEMP(0))); + } + + CLEANUP_TEMP(); + return MP_OK; +} + +mp_result mp_int_expt_value(mp_small a, mp_small b, mp_int c) { + assert(c != NULL); + if (b < 0) return MP_RANGE; + + DECLARE_TEMP(1); + REQUIRE(mp_int_set_value(TEMP(0), a)); + + (void)mp_int_set_value(c, 1); + unsigned int v = labs(b); + while (v != 0) { + if (v & 1) { + REQUIRE(mp_int_mul(c, TEMP(0), c)); + } + + v >>= 1; + if (v == 0) break; + + REQUIRE(mp_int_sqr(TEMP(0), TEMP(0))); + } + + CLEANUP_TEMP(); + return MP_OK; +} + +mp_result mp_int_expt_full(mp_int a, mp_int b, mp_int c) { + assert(a != NULL && b != NULL && c != NULL); + if (MP_SIGN(b) == MP_NEG) return MP_RANGE; + + DECLARE_TEMP(1); + REQUIRE(mp_int_copy(a, TEMP(0))); + + (void)mp_int_set_value(c, 1); + for (unsigned ix = 0; ix < MP_USED(b); ++ix) { + mp_digit d = b->digits[ix]; + + for (unsigned jx = 0; jx < MP_DIGIT_BIT; ++jx) { + if (d & 1) { + REQUIRE(mp_int_mul(c, TEMP(0), c)); + } + + d >>= 1; + if (d == 0 && ix + 1 == MP_USED(b)) break; + REQUIRE(mp_int_sqr(TEMP(0), TEMP(0))); + } + } + + CLEANUP_TEMP(); + return MP_OK; +} + +int mp_int_compare(mp_int a, mp_int b) { + assert(a != NULL && b != NULL); + + mp_sign sa = MP_SIGN(a); + if (sa == MP_SIGN(b)) { + int cmp = s_ucmp(a, b); + + /* If they're both zero or positive, the normal comparison applies; if both + negative, the sense is reversed. */ + if (sa == MP_ZPOS) { + return cmp; + } else { + return -cmp; + } + } else if (sa == MP_ZPOS) { + return 1; + } else { + return -1; + } +} + +int mp_int_compare_unsigned(mp_int a, mp_int b) { + assert(a != NULL && b != NULL); + + return s_ucmp(a, b); +} + +int mp_int_compare_zero(mp_int z) { + assert(z != NULL); + + if (MP_USED(z) == 1 && z->digits[0] == 0) { + return 0; + } else if (MP_SIGN(z) == MP_ZPOS) { + return 1; + } else { + return -1; + } +} + +int mp_int_compare_value(mp_int z, mp_small value) { + assert(z != NULL); + + mp_sign vsign = (value < 0) ? MP_NEG : MP_ZPOS; + if (vsign == MP_SIGN(z)) { + int cmp = s_vcmp(z, value); + + return (vsign == MP_ZPOS) ? cmp : -cmp; + } else { + return (value < 0) ? 1 : -1; + } +} + +int mp_int_compare_uvalue(mp_int z, mp_usmall uv) { + assert(z != NULL); + + if (MP_SIGN(z) == MP_NEG) { + return -1; + } else { + return s_uvcmp(z, uv); + } +} + +mp_result mp_int_exptmod(mp_int a, mp_int b, mp_int m, mp_int c) { + assert(a != NULL && b != NULL && c != NULL && m != NULL); + + /* Zero moduli and negative exponents are not considered. */ + if (CMPZ(m) == 0) return MP_UNDEF; + if (CMPZ(b) < 0) return MP_RANGE; + + mp_size um = MP_USED(m); + DECLARE_TEMP(3); + REQUIRE(GROW(TEMP(0), 2 * um)); + REQUIRE(GROW(TEMP(1), 2 * um)); + + mp_int s; + if (c == b || c == m) { + REQUIRE(GROW(TEMP(2), 2 * um)); + s = TEMP(2); + } else { + s = c; + } + + REQUIRE(mp_int_mod(a, m, TEMP(0))); + REQUIRE(s_brmu(TEMP(1), m)); + REQUIRE(s_embar(TEMP(0), b, m, TEMP(1), s)); + REQUIRE(mp_int_copy(s, c)); + + CLEANUP_TEMP(); + return MP_OK; +} + +mp_result mp_int_exptmod_evalue(mp_int a, mp_small value, mp_int m, mp_int c) { + mpz_t vtmp; + mp_digit vbuf[MP_VALUE_DIGITS(value)]; + + s_fake(&vtmp, value, vbuf); + + return mp_int_exptmod(a, &vtmp, m, c); +} + +mp_result mp_int_exptmod_bvalue(mp_small value, mp_int b, mp_int m, mp_int c) { + mpz_t vtmp; + mp_digit vbuf[MP_VALUE_DIGITS(value)]; + + s_fake(&vtmp, value, vbuf); + + return mp_int_exptmod(&vtmp, b, m, c); +} + +mp_result mp_int_exptmod_known(mp_int a, mp_int b, mp_int m, mp_int mu, + mp_int c) { + assert(a && b && m && c); + + /* Zero moduli and negative exponents are not considered. */ + if (CMPZ(m) == 0) return MP_UNDEF; + if (CMPZ(b) < 0) return MP_RANGE; + + DECLARE_TEMP(2); + mp_size um = MP_USED(m); + REQUIRE(GROW(TEMP(0), 2 * um)); + + mp_int s; + if (c == b || c == m) { + REQUIRE(GROW(TEMP(1), 2 * um)); + s = TEMP(1); + } else { + s = c; + } + + REQUIRE(mp_int_mod(a, m, TEMP(0))); + REQUIRE(s_embar(TEMP(0), b, m, mu, s)); + REQUIRE(mp_int_copy(s, c)); + + CLEANUP_TEMP(); + return MP_OK; +} + +mp_result mp_int_redux_const(mp_int m, mp_int c) { + assert(m != NULL && c != NULL && m != c); + + return s_brmu(c, m); +} + +mp_result mp_int_invmod(mp_int a, mp_int m, mp_int c) { + assert(a != NULL && m != NULL && c != NULL); + + if (CMPZ(a) == 0 || CMPZ(m) <= 0) return MP_RANGE; + + DECLARE_TEMP(2); + + REQUIRE(mp_int_egcd(a, m, TEMP(0), TEMP(1), NULL)); + + if (mp_int_compare_value(TEMP(0), 1) != 0) { + REQUIRE(MP_UNDEF); + } + + /* It is first necessary to constrain the value to the proper range */ + REQUIRE(mp_int_mod(TEMP(1), m, TEMP(1))); + + /* Now, if 'a' was originally negative, the value we have is actually the + magnitude of the negative representative; to get the positive value we + have to subtract from the modulus. Otherwise, the value is okay as it + stands. + */ + if (MP_SIGN(a) == MP_NEG) { + REQUIRE(mp_int_sub(m, TEMP(1), c)); + } else { + REQUIRE(mp_int_copy(TEMP(1), c)); + } + + CLEANUP_TEMP(); + return MP_OK; +} + +/* Binary GCD algorithm due to Josef Stein, 1961 */ +mp_result mp_int_gcd(mp_int a, mp_int b, mp_int c) { + assert(a != NULL && b != NULL && c != NULL); + + int ca = CMPZ(a); + int cb = CMPZ(b); + if (ca == 0 && cb == 0) { + return MP_UNDEF; + } else if (ca == 0) { + return mp_int_abs(b, c); + } else if (cb == 0) { + return mp_int_abs(a, c); + } + + DECLARE_TEMP(3); + REQUIRE(mp_int_copy(a, TEMP(0))); + REQUIRE(mp_int_copy(b, TEMP(1))); + + TEMP(0)->sign = MP_ZPOS; + TEMP(1)->sign = MP_ZPOS; + + int k = 0; + { /* Divide out common factors of 2 from u and v */ + int div2_u = s_dp2k(TEMP(0)); + int div2_v = s_dp2k(TEMP(1)); + + k = MIN(div2_u, div2_v); + s_qdiv(TEMP(0), (mp_size)k); + s_qdiv(TEMP(1), (mp_size)k); + } + + if (mp_int_is_odd(TEMP(0))) { + REQUIRE(mp_int_neg(TEMP(1), TEMP(2))); + } else { + REQUIRE(mp_int_copy(TEMP(0), TEMP(2))); + } + + for (;;) { + s_qdiv(TEMP(2), s_dp2k(TEMP(2))); + + if (CMPZ(TEMP(2)) > 0) { + REQUIRE(mp_int_copy(TEMP(2), TEMP(0))); + } else { + REQUIRE(mp_int_neg(TEMP(2), TEMP(1))); + } + + REQUIRE(mp_int_sub(TEMP(0), TEMP(1), TEMP(2))); + + if (CMPZ(TEMP(2)) == 0) break; + } + + REQUIRE(mp_int_abs(TEMP(0), c)); + if (!s_qmul(c, (mp_size)k)) REQUIRE(MP_MEMORY); + + CLEANUP_TEMP(); + return MP_OK; +} + +/* This is the binary GCD algorithm again, but this time we keep track of the + elementary matrix operations as we go, so we can get values x and y + satisfying c = ax + by. + */ +mp_result mp_int_egcd(mp_int a, mp_int b, mp_int c, mp_int x, mp_int y) { + assert(a != NULL && b != NULL && c != NULL && (x != NULL || y != NULL)); + + mp_result res = MP_OK; + int ca = CMPZ(a); + int cb = CMPZ(b); + if (ca == 0 && cb == 0) { + return MP_UNDEF; + } else if (ca == 0) { + if ((res = mp_int_abs(b, c)) != MP_OK) return res; + mp_int_zero(x); + (void)mp_int_set_value(y, 1); + return MP_OK; + } else if (cb == 0) { + if ((res = mp_int_abs(a, c)) != MP_OK) return res; + (void)mp_int_set_value(x, 1); + mp_int_zero(y); + return MP_OK; + } + + /* Initialize temporaries: + A:0, B:1, C:2, D:3, u:4, v:5, ou:6, ov:7 */ + DECLARE_TEMP(8); + REQUIRE(mp_int_set_value(TEMP(0), 1)); + REQUIRE(mp_int_set_value(TEMP(3), 1)); + REQUIRE(mp_int_copy(a, TEMP(4))); + REQUIRE(mp_int_copy(b, TEMP(5))); + + /* We will work with absolute values here */ + TEMP(4)->sign = MP_ZPOS; + TEMP(5)->sign = MP_ZPOS; + + int k = 0; + { /* Divide out common factors of 2 from u and v */ + int div2_u = s_dp2k(TEMP(4)), div2_v = s_dp2k(TEMP(5)); + + k = MIN(div2_u, div2_v); + s_qdiv(TEMP(4), k); + s_qdiv(TEMP(5), k); + } + + REQUIRE(mp_int_copy(TEMP(4), TEMP(6))); + REQUIRE(mp_int_copy(TEMP(5), TEMP(7))); + + for (;;) { + while (mp_int_is_even(TEMP(4))) { + s_qdiv(TEMP(4), 1); + + if (mp_int_is_odd(TEMP(0)) || mp_int_is_odd(TEMP(1))) { + REQUIRE(mp_int_add(TEMP(0), TEMP(7), TEMP(0))); + REQUIRE(mp_int_sub(TEMP(1), TEMP(6), TEMP(1))); + } + + s_qdiv(TEMP(0), 1); + s_qdiv(TEMP(1), 1); + } + + while (mp_int_is_even(TEMP(5))) { + s_qdiv(TEMP(5), 1); + + if (mp_int_is_odd(TEMP(2)) || mp_int_is_odd(TEMP(3))) { + REQUIRE(mp_int_add(TEMP(2), TEMP(7), TEMP(2))); + REQUIRE(mp_int_sub(TEMP(3), TEMP(6), TEMP(3))); + } + + s_qdiv(TEMP(2), 1); + s_qdiv(TEMP(3), 1); + } + + if (mp_int_compare(TEMP(4), TEMP(5)) >= 0) { + REQUIRE(mp_int_sub(TEMP(4), TEMP(5), TEMP(4))); + REQUIRE(mp_int_sub(TEMP(0), TEMP(2), TEMP(0))); + REQUIRE(mp_int_sub(TEMP(1), TEMP(3), TEMP(1))); + } else { + REQUIRE(mp_int_sub(TEMP(5), TEMP(4), TEMP(5))); + REQUIRE(mp_int_sub(TEMP(2), TEMP(0), TEMP(2))); + REQUIRE(mp_int_sub(TEMP(3), TEMP(1), TEMP(3))); + } + + if (CMPZ(TEMP(4)) == 0) { + if (x) REQUIRE(mp_int_copy(TEMP(2), x)); + if (y) REQUIRE(mp_int_copy(TEMP(3), y)); + if (c) { + if (!s_qmul(TEMP(5), k)) { + REQUIRE(MP_MEMORY); + } + REQUIRE(mp_int_copy(TEMP(5), c)); + } + + break; + } + } + + CLEANUP_TEMP(); + return MP_OK; +} + +mp_result mp_int_lcm(mp_int a, mp_int b, mp_int c) { + assert(a != NULL && b != NULL && c != NULL); + + /* Since a * b = gcd(a, b) * lcm(a, b), we can compute + lcm(a, b) = (a / gcd(a, b)) * b. + + This formulation insures everything works even if the input + variables share space. + */ + DECLARE_TEMP(1); + REQUIRE(mp_int_gcd(a, b, TEMP(0))); + REQUIRE(mp_int_div(a, TEMP(0), TEMP(0), NULL)); + REQUIRE(mp_int_mul(TEMP(0), b, TEMP(0))); + REQUIRE(mp_int_copy(TEMP(0), c)); + + CLEANUP_TEMP(); + return MP_OK; +} + +bool mp_int_divisible_value(mp_int a, mp_small v) { + mp_small rem = 0; + + if (mp_int_div_value(a, v, NULL, &rem) != MP_OK) { + return false; + } + return rem == 0; +} + +int mp_int_is_pow2(mp_int z) { + assert(z != NULL); + + return s_isp2(z); +} + +/* Implementation of Newton's root finding method, based loosely on a patch + contributed by Hal Finkel + modified by M. J. Fromberger. + */ +mp_result mp_int_root(mp_int a, mp_small b, mp_int c) { + assert(a != NULL && c != NULL && b > 0); + + if (b == 1) { + return mp_int_copy(a, c); + } + bool flips = false; + if (MP_SIGN(a) == MP_NEG) { + if (b % 2 == 0) { + return MP_UNDEF; /* root does not exist for negative a with even b */ + } else { + flips = true; + } + } + + DECLARE_TEMP(5); + REQUIRE(mp_int_copy(a, TEMP(0))); + REQUIRE(mp_int_copy(a, TEMP(1))); + TEMP(0)->sign = MP_ZPOS; + TEMP(1)->sign = MP_ZPOS; + + for (;;) { + REQUIRE(mp_int_expt(TEMP(1), b, TEMP(2))); + + if (mp_int_compare_unsigned(TEMP(2), TEMP(0)) <= 0) break; + + REQUIRE(mp_int_sub(TEMP(2), TEMP(0), TEMP(2))); + REQUIRE(mp_int_expt(TEMP(1), b - 1, TEMP(3))); + REQUIRE(mp_int_mul_value(TEMP(3), b, TEMP(3))); + REQUIRE(mp_int_div(TEMP(2), TEMP(3), TEMP(4), NULL)); + REQUIRE(mp_int_sub(TEMP(1), TEMP(4), TEMP(4))); + + if (mp_int_compare_unsigned(TEMP(1), TEMP(4)) == 0) { + REQUIRE(mp_int_sub_value(TEMP(4), 1, TEMP(4))); + } + REQUIRE(mp_int_copy(TEMP(4), TEMP(1))); + } + + REQUIRE(mp_int_copy(TEMP(1), c)); + + /* If the original value of a was negative, flip the output sign. */ + if (flips) (void)mp_int_neg(c, c); /* cannot fail */ + + CLEANUP_TEMP(); + return MP_OK; +} + +mp_result mp_int_to_int(mp_int z, mp_small *out) { + assert(z != NULL); + + /* Make sure the value is representable as a small integer */ + mp_sign sz = MP_SIGN(z); + if ((sz == MP_ZPOS && mp_int_compare_value(z, MP_SMALL_MAX) > 0) || + mp_int_compare_value(z, MP_SMALL_MIN) < 0) { + return MP_RANGE; + } + + mp_usmall uz = MP_USED(z); + mp_digit *dz = MP_DIGITS(z) + uz - 1; + mp_small uv = 0; + while (uz > 0) { + uv <<= MP_DIGIT_BIT / 2; + uv = (uv << (MP_DIGIT_BIT / 2)) | *dz--; + --uz; + } + + if (out) *out = (mp_small)((sz == MP_NEG) ? -uv : uv); + + return MP_OK; +} + +mp_result mp_int_to_uint(mp_int z, mp_usmall *out) { + assert(z != NULL); + + /* Make sure the value is representable as an unsigned small integer */ + mp_size sz = MP_SIGN(z); + if (sz == MP_NEG || mp_int_compare_uvalue(z, MP_USMALL_MAX) > 0) { + return MP_RANGE; + } + + mp_size uz = MP_USED(z); + mp_digit *dz = MP_DIGITS(z) + uz - 1; + mp_usmall uv = 0; + + while (uz > 0) { + uv <<= MP_DIGIT_BIT / 2; + uv = (uv << (MP_DIGIT_BIT / 2)) | *dz--; + --uz; + } + + if (out) *out = uv; + + return MP_OK; +} + +mp_result mp_int_to_string(mp_int z, mp_size radix, char *str, int limit) { + assert(z != NULL && str != NULL && limit >= 2); + assert(radix >= MP_MIN_RADIX && radix <= MP_MAX_RADIX); + + int cmp = 0; + if (CMPZ(z) == 0) { + *str++ = s_val2ch(0, 1); + } else { + mp_result res; + mpz_t tmp; + char *h, *t; + + if ((res = mp_int_init_copy(&tmp, z)) != MP_OK) return res; + + if (MP_SIGN(z) == MP_NEG) { + *str++ = '-'; + --limit; + } + h = str; + + /* Generate digits in reverse order until finished or limit reached */ + for (/* */; limit > 0; --limit) { + mp_digit d; + + if ((cmp = CMPZ(&tmp)) == 0) break; + + d = s_ddiv(&tmp, (mp_digit)radix); + *str++ = s_val2ch(d, 1); + } + t = str - 1; + + /* Put digits back in correct output order */ + while (h < t) { + char tc = *h; + *h++ = *t; + *t-- = tc; + } + + mp_int_clear(&tmp); + } + + *str = '\0'; + if (cmp == 0) { + return MP_OK; + } else { + return MP_TRUNC; + } +} + +mp_result mp_int_string_len(mp_int z, mp_size radix) { + assert(z != NULL); + assert(radix >= MP_MIN_RADIX && radix <= MP_MAX_RADIX); + + int len = s_outlen(z, radix) + 1; /* for terminator */ + + /* Allow for sign marker on negatives */ + if (MP_SIGN(z) == MP_NEG) len += 1; + + return len; +} + +/* Read zero-terminated string into z */ +mp_result mp_int_read_string(mp_int z, mp_size radix, const char *str) { + return mp_int_read_cstring(z, radix, str, NULL); +} + +mp_result mp_int_read_cstring(mp_int z, mp_size radix, const char *str, + char **end) { + assert(z != NULL && str != NULL); + assert(radix >= MP_MIN_RADIX && radix <= MP_MAX_RADIX); + + /* Skip leading whitespace */ + while (isspace((unsigned char)*str)) ++str; + + /* Handle leading sign tag (+/-, positive default) */ + switch (*str) { + case '-': + z->sign = MP_NEG; + ++str; + break; + case '+': + ++str; /* fallthrough */ + default: + z->sign = MP_ZPOS; + break; + } + + /* Skip leading zeroes */ + int ch; + while ((ch = s_ch2val(*str, radix)) == 0) ++str; + + /* Make sure there is enough space for the value */ + if (!s_pad(z, s_inlen(strlen(str), radix))) return MP_MEMORY; + + z->used = 1; + z->digits[0] = 0; + + while (*str != '\0' && ((ch = s_ch2val(*str, radix)) >= 0)) { + s_dmul(z, (mp_digit)radix); + s_dadd(z, (mp_digit)ch); + ++str; + } + + CLAMP(z); + + /* Override sign for zero, even if negative specified. */ + if (CMPZ(z) == 0) z->sign = MP_ZPOS; + + if (end != NULL) *end = (char *)str; + + /* Return a truncation error if the string has unprocessed characters + remaining, so the caller can tell if the whole string was done */ + if (*str != '\0') { + return MP_TRUNC; + } else { + return MP_OK; + } +} + +mp_result mp_int_count_bits(mp_int z) { + assert(z != NULL); + + mp_size uz = MP_USED(z); + if (uz == 1 && z->digits[0] == 0) return 1; + + --uz; + mp_size nbits = uz * MP_DIGIT_BIT; + mp_digit d = z->digits[uz]; + + while (d != 0) { + d >>= 1; + ++nbits; + } + + return nbits; +} + +mp_result mp_int_to_binary(mp_int z, unsigned char *buf, int limit) { + static const int PAD_FOR_2C = 1; + + assert(z != NULL && buf != NULL); + + int limpos = limit; + mp_result res = s_tobin(z, buf, &limpos, PAD_FOR_2C); + + if (MP_SIGN(z) == MP_NEG) s_2comp(buf, limpos); + + return res; +} + +mp_result mp_int_read_binary(mp_int z, unsigned char *buf, int len) { + assert(z != NULL && buf != NULL && len > 0); + + /* Figure out how many digits are needed to represent this value */ + mp_size need = ((len * CHAR_BIT) + (MP_DIGIT_BIT - 1)) / MP_DIGIT_BIT; + if (!s_pad(z, need)) return MP_MEMORY; + + mp_int_zero(z); + + /* If the high-order bit is set, take the 2's complement before reading the + value (it will be restored afterward) */ + if (buf[0] >> (CHAR_BIT - 1)) { + z->sign = MP_NEG; + s_2comp(buf, len); + } + + mp_digit *dz = MP_DIGITS(z); + unsigned char *tmp = buf; + for (int i = len; i > 0; --i, ++tmp) { + s_qmul(z, (mp_size)CHAR_BIT); + *dz |= *tmp; + } + + /* Restore 2's complement if we took it before */ + if (MP_SIGN(z) == MP_NEG) s_2comp(buf, len); + + return MP_OK; +} + +mp_result mp_int_binary_len(mp_int z) { + mp_result res = mp_int_count_bits(z); + if (res <= 0) return res; + + int bytes = mp_int_unsigned_len(z); + + /* If the highest-order bit falls exactly on a byte boundary, we need to pad + with an extra byte so that the sign will be read correctly when reading it + back in. */ + if (bytes * CHAR_BIT == res) ++bytes; + + return bytes; +} + +mp_result mp_int_to_unsigned(mp_int z, unsigned char *buf, int limit) { + static const int NO_PADDING = 0; + + assert(z != NULL && buf != NULL); + + return s_tobin(z, buf, &limit, NO_PADDING); +} + +mp_result mp_int_read_unsigned(mp_int z, unsigned char *buf, int len) { + assert(z != NULL && buf != NULL && len > 0); + + /* Figure out how many digits are needed to represent this value */ + mp_size need = ((len * CHAR_BIT) + (MP_DIGIT_BIT - 1)) / MP_DIGIT_BIT; + if (!s_pad(z, need)) return MP_MEMORY; + + mp_int_zero(z); + + unsigned char *tmp = buf; + for (int i = len; i > 0; --i, ++tmp) { + (void)s_qmul(z, CHAR_BIT); + *MP_DIGITS(z) |= *tmp; + } + + return MP_OK; +} + +mp_result mp_int_unsigned_len(mp_int z) { + mp_result res = mp_int_count_bits(z); + if (res <= 0) return res; + + int bytes = (res + (CHAR_BIT - 1)) / CHAR_BIT; + return bytes; +} + +const char *mp_error_string(mp_result res) { + if (res > 0) return s_unknown_err; + + res = -res; + int ix; + for (ix = 0; ix < res && s_error_msg[ix] != NULL; ++ix) + ; + + if (s_error_msg[ix] != NULL) { + return s_error_msg[ix]; + } else { + return s_unknown_err; + } +} + +/*------------------------------------------------------------------------*/ +/* Private functions for internal use. These make assumptions. */ + +#if DEBUG +static const mp_digit fill = (mp_digit)0xdeadbeefabad1dea; +#endif + +static mp_digit *s_alloc(mp_size num) { + mp_digit *out = malloc(num * sizeof(mp_digit)); + assert(out != NULL); + +#if DEBUG + for (mp_size ix = 0; ix < num; ++ix) out[ix] = fill; +#endif + return out; +} + +static mp_digit *s_realloc(mp_digit *old, mp_size osize, mp_size nsize) { +#if DEBUG + mp_digit *new = s_alloc(nsize); + assert(new != NULL); + + for (mp_size ix = 0; ix < nsize; ++ix) new[ix] = fill; + memcpy(new, old, osize * sizeof(mp_digit)); +#else + mp_digit *new = realloc(old, nsize * sizeof(mp_digit)); + assert(new != NULL); +#endif + + return new; +} + +static void s_free(void *ptr) { free(ptr); } + +static bool s_pad(mp_int z, mp_size min) { + if (MP_ALLOC(z) < min) { + mp_size nsize = s_round_prec(min); + mp_digit *tmp; + + if (z->digits == &(z->single)) { + if ((tmp = s_alloc(nsize)) == NULL) return false; + tmp[0] = z->single; + } else if ((tmp = s_realloc(MP_DIGITS(z), MP_ALLOC(z), nsize)) == NULL) { + return false; + } + + z->digits = tmp; + z->alloc = nsize; + } + + return true; +} + +/* Note: This will not work correctly when value == MP_SMALL_MIN */ +static void s_fake(mp_int z, mp_small value, mp_digit vbuf[]) { + mp_usmall uv = (mp_usmall)(value < 0) ? -value : value; + s_ufake(z, uv, vbuf); + if (value < 0) z->sign = MP_NEG; +} + +static void s_ufake(mp_int z, mp_usmall value, mp_digit vbuf[]) { + mp_size ndig = (mp_size)s_uvpack(value, vbuf); + + z->used = ndig; + z->alloc = MP_VALUE_DIGITS(value); + z->sign = MP_ZPOS; + z->digits = vbuf; +} + +static int s_cdig(mp_digit *da, mp_digit *db, mp_size len) { + mp_digit *dat = da + len - 1, *dbt = db + len - 1; + + for (/* */; len != 0; --len, --dat, --dbt) { + if (*dat > *dbt) { + return 1; + } else if (*dat < *dbt) { + return -1; + } + } + + return 0; +} + +static int s_uvpack(mp_usmall uv, mp_digit t[]) { + int ndig = 0; + + if (uv == 0) + t[ndig++] = 0; + else { + while (uv != 0) { + t[ndig++] = (mp_digit)uv; + uv >>= MP_DIGIT_BIT / 2; + uv >>= MP_DIGIT_BIT / 2; + } + } + + return ndig; +} + +static int s_ucmp(mp_int a, mp_int b) { + mp_size ua = MP_USED(a), ub = MP_USED(b); + + if (ua > ub) { + return 1; + } else if (ub > ua) { + return -1; + } else { + return s_cdig(MP_DIGITS(a), MP_DIGITS(b), ua); + } +} + +static int s_vcmp(mp_int a, mp_small v) { + mp_usmall uv = (v < 0) ? -(mp_usmall)v : (mp_usmall)v; + return s_uvcmp(a, uv); +} + +static int s_uvcmp(mp_int a, mp_usmall uv) { + mpz_t vtmp; + mp_digit vdig[MP_VALUE_DIGITS(uv)]; + + s_ufake(&vtmp, uv, vdig); + return s_ucmp(a, &vtmp); +} + +static mp_digit s_uadd(mp_digit *da, mp_digit *db, mp_digit *dc, mp_size size_a, + mp_size size_b) { + mp_size pos; + mp_word w = 0; + + /* Insure that da is the longer of the two to simplify later code */ + if (size_b > size_a) { + SWAP(mp_digit *, da, db); + SWAP(mp_size, size_a, size_b); + } + + /* Add corresponding digits until the shorter number runs out */ + for (pos = 0; pos < size_b; ++pos, ++da, ++db, ++dc) { + w = w + (mp_word)*da + (mp_word)*db; + *dc = LOWER_HALF(w); + w = UPPER_HALF(w); + } + + /* Propagate carries as far as necessary */ + for (/* */; pos < size_a; ++pos, ++da, ++dc) { + w = w + *da; + + *dc = LOWER_HALF(w); + w = UPPER_HALF(w); + } + + /* Return carry out */ + return (mp_digit)w; +} + +static void s_usub(mp_digit *da, mp_digit *db, mp_digit *dc, mp_size size_a, + mp_size size_b) { + mp_size pos; + mp_word w = 0; + + /* We assume that |a| >= |b| so this should definitely hold */ + assert(size_a >= size_b); + + /* Subtract corresponding digits and propagate borrow */ + for (pos = 0; pos < size_b; ++pos, ++da, ++db, ++dc) { + w = ((mp_word)MP_DIGIT_MAX + 1 + /* MP_RADIX */ + (mp_word)*da) - + w - (mp_word)*db; + + *dc = LOWER_HALF(w); + w = (UPPER_HALF(w) == 0); + } + + /* Finish the subtraction for remaining upper digits of da */ + for (/* */; pos < size_a; ++pos, ++da, ++dc) { + w = ((mp_word)MP_DIGIT_MAX + 1 + /* MP_RADIX */ + (mp_word)*da) - + w; + + *dc = LOWER_HALF(w); + w = (UPPER_HALF(w) == 0); + } + + /* If there is a borrow out at the end, it violates the precondition */ + assert(w == 0); +} + +static int s_kmul(mp_digit *da, mp_digit *db, mp_digit *dc, mp_size size_a, + mp_size size_b) { + mp_size bot_size; + + /* Make sure b is the smaller of the two input values */ + if (size_b > size_a) { + SWAP(mp_digit *, da, db); + SWAP(mp_size, size_a, size_b); + } + + /* Insure that the bottom is the larger half in an odd-length split; the code + below relies on this being true. + */ + bot_size = (size_a + 1) / 2; + + /* If the values are big enough to bother with recursion, use the Karatsuba + algorithm to compute the product; otherwise use the normal multiplication + algorithm + */ + if (multiply_threshold && size_a >= multiply_threshold && size_b > bot_size) { + mp_digit *t1, *t2, *t3, carry; + + mp_digit *a_top = da + bot_size; + mp_digit *b_top = db + bot_size; + + mp_size at_size = size_a - bot_size; + mp_size bt_size = size_b - bot_size; + mp_size buf_size = 2 * bot_size; + + /* Do a single allocation for all three temporary buffers needed; each + buffer must be big enough to hold the product of two bottom halves, and + one buffer needs space for the completed product; twice the space is + plenty. + */ + if ((t1 = s_alloc(4 * buf_size)) == NULL) return 0; + t2 = t1 + buf_size; + t3 = t2 + buf_size; + ZERO(t1, 4 * buf_size); + + /* t1 and t2 are initially used as temporaries to compute the inner product + (a1 + a0)(b1 + b0) = a1b1 + a1b0 + a0b1 + a0b0 + */ + carry = s_uadd(da, a_top, t1, bot_size, at_size); /* t1 = a1 + a0 */ + t1[bot_size] = carry; + + carry = s_uadd(db, b_top, t2, bot_size, bt_size); /* t2 = b1 + b0 */ + t2[bot_size] = carry; + + (void)s_kmul(t1, t2, t3, bot_size + 1, bot_size + 1); /* t3 = t1 * t2 */ + + /* Now we'll get t1 = a0b0 and t2 = a1b1, and subtract them out so that + we're left with only the pieces we want: t3 = a1b0 + a0b1 + */ + ZERO(t1, buf_size); + ZERO(t2, buf_size); + (void)s_kmul(da, db, t1, bot_size, bot_size); /* t1 = a0 * b0 */ + (void)s_kmul(a_top, b_top, t2, at_size, bt_size); /* t2 = a1 * b1 */ + + /* Subtract out t1 and t2 to get the inner product */ + s_usub(t3, t1, t3, buf_size + 2, buf_size); + s_usub(t3, t2, t3, buf_size + 2, buf_size); + + /* Assemble the output value */ + COPY(t1, dc, buf_size); + carry = s_uadd(t3, dc + bot_size, dc + bot_size, buf_size + 1, buf_size); + assert(carry == 0); + + carry = + s_uadd(t2, dc + 2 * bot_size, dc + 2 * bot_size, buf_size, buf_size); + assert(carry == 0); + + s_free(t1); /* note t2 and t3 are just internal pointers to t1 */ + } else { + s_umul(da, db, dc, size_a, size_b); + } + + return 1; +} + +static void s_umul(mp_digit *da, mp_digit *db, mp_digit *dc, mp_size size_a, + mp_size size_b) { + mp_size a, b; + mp_word w; + + for (a = 0; a < size_a; ++a, ++dc, ++da) { + mp_digit *dct = dc; + mp_digit *dbt = db; + + if (*da == 0) continue; + + w = 0; + for (b = 0; b < size_b; ++b, ++dbt, ++dct) { + w = (mp_word)*da * (mp_word)*dbt + w + (mp_word)*dct; + + *dct = LOWER_HALF(w); + w = UPPER_HALF(w); + } + + *dct = (mp_digit)w; + } +} + +static int s_ksqr(mp_digit *da, mp_digit *dc, mp_size size_a) { + if (multiply_threshold && size_a > multiply_threshold) { + mp_size bot_size = (size_a + 1) / 2; + mp_digit *a_top = da + bot_size; + mp_digit *t1, *t2, *t3, carry; + mp_size at_size = size_a - bot_size; + mp_size buf_size = 2 * bot_size; + + if ((t1 = s_alloc(4 * buf_size)) == NULL) return 0; + t2 = t1 + buf_size; + t3 = t2 + buf_size; + ZERO(t1, 4 * buf_size); + + (void)s_ksqr(da, t1, bot_size); /* t1 = a0 ^ 2 */ + (void)s_ksqr(a_top, t2, at_size); /* t2 = a1 ^ 2 */ + + (void)s_kmul(da, a_top, t3, bot_size, at_size); /* t3 = a0 * a1 */ + + /* Quick multiply t3 by 2, shifting left (can't overflow) */ + { + int i, top = bot_size + at_size; + mp_word w, save = 0; + + for (i = 0; i < top; ++i) { + w = t3[i]; + w = (w << 1) | save; + t3[i] = LOWER_HALF(w); + save = UPPER_HALF(w); + } + t3[i] = LOWER_HALF(save); + } + + /* Assemble the output value */ + COPY(t1, dc, 2 * bot_size); + carry = s_uadd(t3, dc + bot_size, dc + bot_size, buf_size + 1, buf_size); + assert(carry == 0); + + carry = + s_uadd(t2, dc + 2 * bot_size, dc + 2 * bot_size, buf_size, buf_size); + assert(carry == 0); + + s_free(t1); /* note that t2 and t2 are internal pointers only */ + + } else { + s_usqr(da, dc, size_a); + } + + return 1; +} + +static void s_usqr(mp_digit *da, mp_digit *dc, mp_size size_a) { + mp_size i, j; + mp_word w; + + for (i = 0; i < size_a; ++i, dc += 2, ++da) { + mp_digit *dct = dc, *dat = da; + + if (*da == 0) continue; + + /* Take care of the first digit, no rollover */ + w = (mp_word)*dat * (mp_word)*dat + (mp_word)*dct; + *dct = LOWER_HALF(w); + w = UPPER_HALF(w); + ++dat; + ++dct; + + for (j = i + 1; j < size_a; ++j, ++dat, ++dct) { + mp_word t = (mp_word)*da * (mp_word)*dat; + mp_word u = w + (mp_word)*dct, ov = 0; + + /* Check if doubling t will overflow a word */ + if (HIGH_BIT_SET(t)) ov = 1; + + w = t + t; + + /* Check if adding u to w will overflow a word */ + if (ADD_WILL_OVERFLOW(w, u)) ov = 1; + + w += u; + + *dct = LOWER_HALF(w); + w = UPPER_HALF(w); + if (ov) { + w += MP_DIGIT_MAX; /* MP_RADIX */ + ++w; + } + } + + w = w + *dct; + *dct = (mp_digit)w; + while ((w = UPPER_HALF(w)) != 0) { + ++dct; + w = w + *dct; + *dct = LOWER_HALF(w); + } + + assert(w == 0); + } +} + +static void s_dadd(mp_int a, mp_digit b) { + mp_word w = 0; + mp_digit *da = MP_DIGITS(a); + mp_size ua = MP_USED(a); + + w = (mp_word)*da + b; + *da++ = LOWER_HALF(w); + w = UPPER_HALF(w); + + for (ua -= 1; ua > 0; --ua, ++da) { + w = (mp_word)*da + w; + + *da = LOWER_HALF(w); + w = UPPER_HALF(w); + } + + if (w) { + *da = (mp_digit)w; + a->used += 1; + } +} + +static void s_dmul(mp_int a, mp_digit b) { + mp_word w = 0; + mp_digit *da = MP_DIGITS(a); + mp_size ua = MP_USED(a); + + while (ua > 0) { + w = (mp_word)*da * b + w; + *da++ = LOWER_HALF(w); + w = UPPER_HALF(w); + --ua; + } + + if (w) { + *da = (mp_digit)w; + a->used += 1; + } +} + +static void s_dbmul(mp_digit *da, mp_digit b, mp_digit *dc, mp_size size_a) { + mp_word w = 0; + + while (size_a > 0) { + w = (mp_word)*da++ * (mp_word)b + w; + + *dc++ = LOWER_HALF(w); + w = UPPER_HALF(w); + --size_a; + } + + if (w) *dc = LOWER_HALF(w); +} + +static mp_digit s_ddiv(mp_int a, mp_digit b) { + mp_word w = 0, qdigit; + mp_size ua = MP_USED(a); + mp_digit *da = MP_DIGITS(a) + ua - 1; + + for (/* */; ua > 0; --ua, --da) { + w = (w << MP_DIGIT_BIT) | *da; + + if (w >= b) { + qdigit = w / b; + w = w % b; + } else { + qdigit = 0; + } + + *da = (mp_digit)qdigit; + } + + CLAMP(a); + return (mp_digit)w; +} + +static void s_qdiv(mp_int z, mp_size p2) { + mp_size ndig = p2 / MP_DIGIT_BIT, nbits = p2 % MP_DIGIT_BIT; + mp_size uz = MP_USED(z); + + if (ndig) { + mp_size mark; + mp_digit *to, *from; + + if (ndig >= uz) { + mp_int_zero(z); + return; + } + + to = MP_DIGITS(z); + from = to + ndig; + + for (mark = ndig; mark < uz; ++mark) { + *to++ = *from++; + } + + z->used = uz - ndig; + } + + if (nbits) { + mp_digit d = 0, *dz, save; + mp_size up = MP_DIGIT_BIT - nbits; + + uz = MP_USED(z); + dz = MP_DIGITS(z) + uz - 1; + + for (/* */; uz > 0; --uz, --dz) { + save = *dz; + + *dz = (*dz >> nbits) | (d << up); + d = save; + } + + CLAMP(z); + } + + if (MP_USED(z) == 1 && z->digits[0] == 0) z->sign = MP_ZPOS; +} + +static void s_qmod(mp_int z, mp_size p2) { + mp_size start = p2 / MP_DIGIT_BIT + 1, rest = p2 % MP_DIGIT_BIT; + mp_size uz = MP_USED(z); + mp_digit mask = (1u << rest) - 1; + + if (start <= uz) { + z->used = start; + z->digits[start - 1] &= mask; + CLAMP(z); + } +} + +static int s_qmul(mp_int z, mp_size p2) { + mp_size uz, need, rest, extra, i; + mp_digit *from, *to, d; + + if (p2 == 0) return 1; + + uz = MP_USED(z); + need = p2 / MP_DIGIT_BIT; + rest = p2 % MP_DIGIT_BIT; + + /* Figure out if we need an extra digit at the top end; this occurs if the + topmost `rest' bits of the high-order digit of z are not zero, meaning + they will be shifted off the end if not preserved */ + extra = 0; + if (rest != 0) { + mp_digit *dz = MP_DIGITS(z) + uz - 1; + + if ((*dz >> (MP_DIGIT_BIT - rest)) != 0) extra = 1; + } + + if (!s_pad(z, uz + need + extra)) return 0; + + /* If we need to shift by whole digits, do that in one pass, then + to back and shift by partial digits. + */ + if (need > 0) { + from = MP_DIGITS(z) + uz - 1; + to = from + need; + + for (i = 0; i < uz; ++i) *to-- = *from--; + + ZERO(MP_DIGITS(z), need); + uz += need; + } + + if (rest) { + d = 0; + for (i = need, from = MP_DIGITS(z) + need; i < uz; ++i, ++from) { + mp_digit save = *from; + + *from = (*from << rest) | (d >> (MP_DIGIT_BIT - rest)); + d = save; + } + + d >>= (MP_DIGIT_BIT - rest); + if (d != 0) { + *from = d; + uz += extra; + } + } + + z->used = uz; + CLAMP(z); + + return 1; +} + +/* Compute z = 2^p2 - |z|; requires that 2^p2 >= |z| + The sign of the result is always zero/positive. + */ +static int s_qsub(mp_int z, mp_size p2) { + mp_digit hi = (1u << (p2 % MP_DIGIT_BIT)), *zp; + mp_size tdig = (p2 / MP_DIGIT_BIT), pos; + mp_word w = 0; + + if (!s_pad(z, tdig + 1)) return 0; + + for (pos = 0, zp = MP_DIGITS(z); pos < tdig; ++pos, ++zp) { + w = ((mp_word)MP_DIGIT_MAX + 1) - w - (mp_word)*zp; + + *zp = LOWER_HALF(w); + w = UPPER_HALF(w) ? 0 : 1; + } + + w = ((mp_word)MP_DIGIT_MAX + 1 + hi) - w - (mp_word)*zp; + *zp = LOWER_HALF(w); + + assert(UPPER_HALF(w) != 0); /* no borrow out should be possible */ + + z->sign = MP_ZPOS; + CLAMP(z); + + return 1; +} + +static int s_dp2k(mp_int z) { + int k = 0; + mp_digit *dp = MP_DIGITS(z), d; + + if (MP_USED(z) == 1 && *dp == 0) return 1; + + while (*dp == 0) { + k += MP_DIGIT_BIT; + ++dp; + } + + d = *dp; + while ((d & 1) == 0) { + d >>= 1; + ++k; + } + + return k; +} + +static int s_isp2(mp_int z) { + mp_size uz = MP_USED(z), k = 0; + mp_digit *dz = MP_DIGITS(z), d; + + while (uz > 1) { + if (*dz++ != 0) return -1; + k += MP_DIGIT_BIT; + --uz; + } + + d = *dz; + while (d > 1) { + if (d & 1) return -1; + ++k; + d >>= 1; + } + + return (int)k; +} + +static int s_2expt(mp_int z, mp_small k) { + mp_size ndig, rest; + mp_digit *dz; + + ndig = (k + MP_DIGIT_BIT) / MP_DIGIT_BIT; + rest = k % MP_DIGIT_BIT; + + if (!s_pad(z, ndig)) return 0; + + dz = MP_DIGITS(z); + ZERO(dz, ndig); + *(dz + ndig - 1) = (1u << rest); + z->used = ndig; + + return 1; +} + +static int s_norm(mp_int a, mp_int b) { + mp_digit d = b->digits[MP_USED(b) - 1]; + int k = 0; + + while (d < (1u << (mp_digit)(MP_DIGIT_BIT - 1))) { /* d < (MP_RADIX / 2) */ + d <<= 1; + ++k; + } + + /* These multiplications can't fail */ + if (k != 0) { + (void)s_qmul(a, (mp_size)k); + (void)s_qmul(b, (mp_size)k); + } + + return k; +} + +static mp_result s_brmu(mp_int z, mp_int m) { + mp_size um = MP_USED(m) * 2; + + if (!s_pad(z, um)) return MP_MEMORY; + + s_2expt(z, MP_DIGIT_BIT * um); + return mp_int_div(z, m, z, NULL); +} + +static int s_reduce(mp_int x, mp_int m, mp_int mu, mp_int q1, mp_int q2) { + mp_size um = MP_USED(m), umb_p1, umb_m1; + + umb_p1 = (um + 1) * MP_DIGIT_BIT; + umb_m1 = (um - 1) * MP_DIGIT_BIT; + + if (mp_int_copy(x, q1) != MP_OK) return 0; + + /* Compute q2 = floor((floor(x / b^(k-1)) * mu) / b^(k+1)) */ + s_qdiv(q1, umb_m1); + UMUL(q1, mu, q2); + s_qdiv(q2, umb_p1); + + /* Set x = x mod b^(k+1) */ + s_qmod(x, umb_p1); + + /* Now, q is a guess for the quotient a / m. + Compute x - q * m mod b^(k+1), replacing x. This may be off + by a factor of 2m, but no more than that. + */ + UMUL(q2, m, q1); + s_qmod(q1, umb_p1); + (void)mp_int_sub(x, q1, x); /* can't fail */ + + /* The result may be < 0; if it is, add b^(k+1) to pin it in the proper + range. */ + if ((CMPZ(x) < 0) && !s_qsub(x, umb_p1)) return 0; + + /* If x > m, we need to back it off until it is in range. This will be + required at most twice. */ + if (mp_int_compare(x, m) >= 0) { + (void)mp_int_sub(x, m, x); + if (mp_int_compare(x, m) >= 0) { + (void)mp_int_sub(x, m, x); + } + } + + /* At this point, x has been properly reduced. */ + return 1; +} + +/* Perform modular exponentiation using Barrett's method, where mu is the + reduction constant for m. Assumes a < m, b > 0. */ +static mp_result s_embar(mp_int a, mp_int b, mp_int m, mp_int mu, mp_int c) { + mp_digit umu = MP_USED(mu); + mp_digit *db = MP_DIGITS(b); + mp_digit *dbt = db + MP_USED(b) - 1; + + DECLARE_TEMP(3); + REQUIRE(GROW(TEMP(0), 4 * umu)); + REQUIRE(GROW(TEMP(1), 4 * umu)); + REQUIRE(GROW(TEMP(2), 4 * umu)); + ZERO(TEMP(0)->digits, TEMP(0)->alloc); + ZERO(TEMP(1)->digits, TEMP(1)->alloc); + ZERO(TEMP(2)->digits, TEMP(2)->alloc); + + (void)mp_int_set_value(c, 1); + + /* Take care of low-order digits */ + while (db < dbt) { + mp_digit d = *db; + + for (int i = MP_DIGIT_BIT; i > 0; --i, d >>= 1) { + if (d & 1) { + /* The use of a second temporary avoids allocation */ + UMUL(c, a, TEMP(0)); + if (!s_reduce(TEMP(0), m, mu, TEMP(1), TEMP(2))) { + REQUIRE(MP_MEMORY); + } + mp_int_copy(TEMP(0), c); + } + + USQR(a, TEMP(0)); + assert(MP_SIGN(TEMP(0)) == MP_ZPOS); + if (!s_reduce(TEMP(0), m, mu, TEMP(1), TEMP(2))) { + REQUIRE(MP_MEMORY); + } + assert(MP_SIGN(TEMP(0)) == MP_ZPOS); + mp_int_copy(TEMP(0), a); + } + + ++db; + } + + /* Take care of highest-order digit */ + mp_digit d = *dbt; + for (;;) { + if (d & 1) { + UMUL(c, a, TEMP(0)); + if (!s_reduce(TEMP(0), m, mu, TEMP(1), TEMP(2))) { + REQUIRE(MP_MEMORY); + } + mp_int_copy(TEMP(0), c); + } + + d >>= 1; + if (!d) break; + + USQR(a, TEMP(0)); + if (!s_reduce(TEMP(0), m, mu, TEMP(1), TEMP(2))) { + REQUIRE(MP_MEMORY); + } + (void)mp_int_copy(TEMP(0), a); + } + + CLEANUP_TEMP(); + return MP_OK; +} + +/* Division of nonnegative integers + + This function implements division algorithm for unsigned multi-precision + integers. The algorithm is based on Algorithm D from Knuth's "The Art of + Computer Programming", 3rd ed. 1998, pg 272-273. + + We diverge from Knuth's algorithm in that we do not perform the subtraction + from the remainder until we have determined that we have the correct + quotient digit. This makes our algorithm less efficient that Knuth because + we might have to perform multiple multiplication and comparison steps before + the subtraction. The advantage is that it is easy to implement and ensure + correctness without worrying about underflow from the subtraction. + + inputs: u a n+m digit integer in base b (b is 2^MP_DIGIT_BIT) + v a n digit integer in base b (b is 2^MP_DIGIT_BIT) + n >= 1 + m >= 0 + outputs: u / v stored in u + u % v stored in v + */ +static mp_result s_udiv_knuth(mp_int u, mp_int v) { + /* Force signs to positive */ + u->sign = MP_ZPOS; + v->sign = MP_ZPOS; + + /* Use simple division algorithm when v is only one digit long */ + if (MP_USED(v) == 1) { + mp_digit d, rem; + d = v->digits[0]; + rem = s_ddiv(u, d); + mp_int_set_value(v, rem); + return MP_OK; + } + + /* Algorithm D + + The n and m variables are defined as used by Knuth. + u is an n digit number with digits u_{n-1}..u_0. + v is an n+m digit number with digits from v_{m+n-1}..v_0. + We require that n > 1 and m >= 0 + */ + mp_size n = MP_USED(v); + mp_size m = MP_USED(u) - n; + assert(n > 1); + /* assert(m >= 0) follows because m is unsigned. */ + + /* D1: Normalize. + The normalization step provides the necessary condition for Theorem B, + which states that the quotient estimate for q_j, call it qhat + + qhat = u_{j+n}u_{j+n-1} / v_{n-1} + + is bounded by + + qhat - 2 <= q_j <= qhat. + + That is, qhat is always greater than the actual quotient digit q, + and it is never more than two larger than the actual quotient digit. + */ + int k = s_norm(u, v); + + /* Extend size of u by one if needed. + + The algorithm begins with a value of u that has one more digit of input. + The normalization step sets u_{m+n}..u_0 = 2^k * u_{m+n-1}..u_0. If the + multiplication did not increase the number of digits of u, we need to add + a leading zero here. + */ + if (k == 0 || MP_USED(u) != m + n + 1) { + if (!s_pad(u, m + n + 1)) return MP_MEMORY; + u->digits[m + n] = 0; + u->used = m + n + 1; + } + + /* Add a leading 0 to v. + + The multiplication in step D4 multiplies qhat * 0v_{n-1}..v_0. We need to + add the leading zero to v here to ensure that the multiplication will + produce the full n+1 digit result. + */ + if (!s_pad(v, n + 1)) return MP_MEMORY; + v->digits[n] = 0; + + /* Initialize temporary variables q and t. + q allocates space for m+1 digits to store the quotient digits + t allocates space for n+1 digits to hold the result of q_j*v + */ + DECLARE_TEMP(2); + REQUIRE(GROW(TEMP(0), m + 1)); + REQUIRE(GROW(TEMP(1), n + 1)); + + /* D2: Initialize j */ + int j = m; + mpz_t r; + r.digits = MP_DIGITS(u) + j; /* The contents of r are shared with u */ + r.used = n + 1; + r.sign = MP_ZPOS; + r.alloc = MP_ALLOC(u); + ZERO(TEMP(1)->digits, TEMP(1)->alloc); + + /* Calculate the m+1 digits of the quotient result */ + for (; j >= 0; j--) { + /* D3: Calculate q' */ + /* r->digits is aligned to position j of the number u */ + mp_word pfx, qhat; + pfx = r.digits[n]; + pfx <<= MP_DIGIT_BIT / 2; + pfx <<= MP_DIGIT_BIT / 2; + pfx |= r.digits[n - 1]; /* pfx = u_{j+n}{j+n-1} */ + + qhat = pfx / v->digits[n - 1]; + /* Check to see if qhat > b, and decrease qhat if so. + Theorem B guarantess that qhat is at most 2 larger than the + actual value, so it is possible that qhat is greater than + the maximum value that will fit in a digit */ + if (qhat > MP_DIGIT_MAX) qhat = MP_DIGIT_MAX; + + /* D4,D5,D6: Multiply qhat * v and test for a correct value of q + + We proceed a bit different than the way described by Knuth. This way is + simpler but less efficent. Instead of doing the multiply and subtract + then checking for underflow, we first do the multiply of qhat * v and + see if it is larger than the current remainder r. If it is larger, we + decrease qhat by one and try again. We may need to decrease qhat one + more time before we get a value that is smaller than r. + + This way is less efficent than Knuth because we do more multiplies, but + we do not need to worry about underflow this way. + */ + /* t = qhat * v */ + s_dbmul(MP_DIGITS(v), (mp_digit)qhat, TEMP(1)->digits, n + 1); + TEMP(1)->used = n + 1; + CLAMP(TEMP(1)); + + /* Clamp r for the comparison. Comparisons do not like leading zeros. */ + CLAMP(&r); + if (s_ucmp(TEMP(1), &r) > 0) { /* would the remainder be negative? */ + qhat -= 1; /* try a smaller q */ + s_dbmul(MP_DIGITS(v), (mp_digit)qhat, TEMP(1)->digits, n + 1); + TEMP(1)->used = n + 1; + CLAMP(TEMP(1)); + if (s_ucmp(TEMP(1), &r) > 0) { /* would the remainder be negative? */ + assert(qhat > 0); + qhat -= 1; /* try a smaller q */ + s_dbmul(MP_DIGITS(v), (mp_digit)qhat, TEMP(1)->digits, n + 1); + TEMP(1)->used = n + 1; + CLAMP(TEMP(1)); + } + assert(s_ucmp(TEMP(1), &r) <= 0 && "The mathematics failed us."); + } + /* Unclamp r. The D algorithm expects r = u_{j+n}..u_j to always be n+1 + digits long. */ + r.used = n + 1; + + /* D4: Multiply and subtract + + Note: The multiply was completed above so we only need to subtract here. + */ + s_usub(r.digits, TEMP(1)->digits, r.digits, r.used, TEMP(1)->used); + + /* D5: Test remainder + + Note: Not needed because we always check that qhat is the correct value + before performing the subtract. Value cast to mp_digit to prevent + warning, qhat has been clamped to MP_DIGIT_MAX + */ + TEMP(0)->digits[j] = (mp_digit)qhat; + + /* D6: Add back + Note: Not needed because we always check that qhat is the correct value + before performing the subtract. + */ + + /* D7: Loop on j */ + r.digits--; + ZERO(TEMP(1)->digits, TEMP(1)->alloc); + } + + /* Get rid of leading zeros in q */ + TEMP(0)->used = m + 1; + CLAMP(TEMP(0)); + + /* Denormalize the remainder */ + CLAMP(u); /* use u here because the r.digits pointer is off-by-one */ + if (k != 0) s_qdiv(u, k); + + mp_int_copy(u, v); /* ok: 0 <= r < v */ + mp_int_copy(TEMP(0), u); /* ok: q <= u */ + + CLEANUP_TEMP(); + return MP_OK; +} + +static int s_outlen(mp_int z, mp_size r) { + assert(r >= MP_MIN_RADIX && r <= MP_MAX_RADIX); + + mp_result bits = mp_int_count_bits(z); + double raw = (double)bits * s_log2[r]; + + return (int)(raw + 0.999999); +} + +static mp_size s_inlen(int len, mp_size r) { + double raw = (double)len / s_log2[r]; + mp_size bits = (mp_size)(raw + 0.5); + + return (mp_size)((bits + (MP_DIGIT_BIT - 1)) / MP_DIGIT_BIT) + 1; +} + +static int s_ch2val(char c, int r) { + int out; + + /* + * In some locales, isalpha() accepts characters outside the range A-Z, + * producing out<0 or out>=36. The "out >= r" check will always catch + * out>=36. Though nothing explicitly catches out<0, our caller reacts the + * same way to every negative return value. + */ + if (isdigit((unsigned char)c)) + out = c - '0'; + else if (r > 10 && isalpha((unsigned char)c)) + out = toupper((unsigned char)c) - 'A' + 10; + else + return -1; + + return (out >= r) ? -1 : out; +} + +static char s_val2ch(int v, int caps) { + assert(v >= 0); + + if (v < 10) { + return v + '0'; + } else { + char out = (v - 10) + 'a'; + + if (caps) { + return toupper((unsigned char)out); + } else { + return out; + } + } +} + +static void s_2comp(unsigned char *buf, int len) { + unsigned short s = 1; + + for (int i = len - 1; i >= 0; --i) { + unsigned char c = ~buf[i]; + + s = c + s; + c = s & UCHAR_MAX; + s >>= CHAR_BIT; + + buf[i] = c; + } + + /* last carry out is ignored */ +} + +static mp_result s_tobin(mp_int z, unsigned char *buf, int *limpos, int pad) { + int pos = 0, limit = *limpos; + mp_size uz = MP_USED(z); + mp_digit *dz = MP_DIGITS(z); + + while (uz > 0 && pos < limit) { + mp_digit d = *dz++; + int i; + + for (i = sizeof(mp_digit); i > 0 && pos < limit; --i) { + buf[pos++] = (unsigned char)d; + d >>= CHAR_BIT; + + /* Don't write leading zeroes */ + if (d == 0 && uz == 1) i = 0; /* exit loop without signaling truncation */ + } + + /* Detect truncation (loop exited with pos >= limit) */ + if (i > 0) break; + + --uz; + } + + if (pad != 0 && (buf[pos - 1] >> (CHAR_BIT - 1))) { + if (pos < limit) { + buf[pos++] = 0; + } else { + uz = 1; + } + } + + /* Digits are in reverse order, fix that */ + REV(buf, pos); + + /* Return the number of bytes actually written */ + *limpos = pos; + + return (uz == 0) ? MP_OK : MP_TRUNC; +} + +/* Here there be dragons */ diff --git a/external/mit/isl/dist/imath/imath.h b/external/mit/isl/dist/imath/imath.h new file mode 100644 index 000000000000..7d304870cf03 --- /dev/null +++ b/external/mit/isl/dist/imath/imath.h @@ -0,0 +1,421 @@ +/* + Name: imath.h + Purpose: Arbitrary precision integer arithmetic routines. + Author: M. J. Fromberger + + Copyright (C) 2002-2007 Michael J. Fromberger, All Rights Reserved. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +#ifndef IMATH_H_ +#define IMATH_H_ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef unsigned char mp_sign; +typedef unsigned int mp_size; +typedef int mp_result; +typedef long mp_small; /* must be a signed type */ +typedef unsigned long mp_usmall; /* must be an unsigned type */ + + +/* Build with words as uint64_t by default. */ +#ifdef USE_32BIT_WORDS +typedef uint16_t mp_digit; +typedef uint32_t mp_word; +# define MP_DIGIT_MAX (UINT16_MAX * 1UL) +# define MP_WORD_MAX (UINT32_MAX * 1UL) +#else +typedef uint32_t mp_digit; +typedef uint64_t mp_word; +# define MP_DIGIT_MAX (UINT32_MAX * UINT64_C(1)) +# define MP_WORD_MAX (UINT64_MAX) +#endif + +typedef struct { + mp_digit single; + mp_digit* digits; + mp_size alloc; + mp_size used; + mp_sign sign; +} mpz_t, *mp_int; + +static inline mp_digit* MP_DIGITS(mp_int Z) { return Z->digits; } +static inline mp_size MP_ALLOC(mp_int Z) { return Z->alloc; } +static inline mp_size MP_USED(mp_int Z) { return Z->used; } +static inline mp_sign MP_SIGN(mp_int Z) { return Z->sign; } + +extern const mp_result MP_OK; +extern const mp_result MP_FALSE; +extern const mp_result MP_TRUE; +extern const mp_result MP_MEMORY; +extern const mp_result MP_RANGE; +extern const mp_result MP_UNDEF; +extern const mp_result MP_TRUNC; +extern const mp_result MP_BADARG; +extern const mp_result MP_MINERR; + +#define MP_DIGIT_BIT (sizeof(mp_digit) * CHAR_BIT) +#define MP_WORD_BIT (sizeof(mp_word) * CHAR_BIT) +#define MP_SMALL_MIN LONG_MIN +#define MP_SMALL_MAX LONG_MAX +#define MP_USMALL_MAX ULONG_MAX + +#define MP_MIN_RADIX 2 +#define MP_MAX_RADIX 36 + +/** Sets the default number of digits allocated to an `mp_int` constructed by + `mp_int_init_size()` with `prec == 0`. Allocations are rounded up to + multiples of this value. `MP_DEFAULT_PREC` is the default value. Requires + `ndigits > 0`. */ +void mp_int_default_precision(mp_size ndigits); + +/** Sets the number of digits below which multiplication will use the standard + quadratic "schoolbook" multiplication algorithm rather than Karatsuba-Ofman. + Requires `ndigits >= sizeof(mp_word)`. */ +void mp_int_multiply_threshold(mp_size ndigits); + +/** A sign indicating a (strictly) negative value. */ +extern const mp_sign MP_NEG; + +/** A sign indicating a zero or positive value. */ +extern const mp_sign MP_ZPOS; + +/** Reports whether `z` is odd, having remainder 1 when divided by 2. */ +static inline bool mp_int_is_odd(mp_int z) { return (z->digits[0] & 1) != 0; } + +/** Reports whether `z` is even, having remainder 0 when divided by 2. */ +static inline bool mp_int_is_even(mp_int z) { return (z->digits[0] & 1) == 0; } + +/** Initializes `z` with 1-digit precision and sets it to zero. This function + cannot fail unless `z == NULL`. */ +mp_result mp_int_init(mp_int z); + +/** Allocates a fresh zero-valued `mpz_t` on the heap, returning NULL in case + of error. The only possible error is out-of-memory. */ +mp_int mp_int_alloc(void); + +/** Initializes `z` with at least `prec` digits of storage, and sets it to + zero. If `prec` is zero, the default precision is used. In either case the + size is rounded up to the nearest multiple of the word size. */ +mp_result mp_int_init_size(mp_int z, mp_size prec); + +/** Initializes `z` to be a copy of an already-initialized value in `old`. The + new copy does not share storage with the original. */ +mp_result mp_int_init_copy(mp_int z, mp_int old); + +/** Initializes `z` to the specified signed `value` at default precision. */ +mp_result mp_int_init_value(mp_int z, mp_small value); + +/** Initializes `z` to the specified unsigned `value` at default precision. */ +mp_result mp_int_init_uvalue(mp_int z, mp_usmall uvalue); + +/** Sets `z` to the value of the specified signed `value`. */ +mp_result mp_int_set_value(mp_int z, mp_small value); + +/** Sets `z` to the value of the specified unsigned `value`. */ +mp_result mp_int_set_uvalue(mp_int z, mp_usmall uvalue); + +/** Releases the storage used by `z`. */ +void mp_int_clear(mp_int z); + +/** Releases the storage used by `z` and also `z` itself. + This should only be used for `z` allocated by `mp_int_alloc()`. */ +void mp_int_free(mp_int z); + +/** Replaces the value of `c` with a copy of the value of `a`. No new memory is + allocated unless `a` has more significant digits than `c` has allocated. */ +mp_result mp_int_copy(mp_int a, mp_int c); + +/** Swaps the values and storage between `a` and `c`. */ +void mp_int_swap(mp_int a, mp_int c); + +/** Sets `z` to zero. The allocated storage of `z` is not changed. */ +void mp_int_zero(mp_int z); + +/** Sets `c` to the absolute value of `a`. */ +mp_result mp_int_abs(mp_int a, mp_int c); + +/** Sets `c` to the additive inverse (negation) of `a`. */ +mp_result mp_int_neg(mp_int a, mp_int c); + +/** Sets `c` to the sum of `a` and `b`. */ +mp_result mp_int_add(mp_int a, mp_int b, mp_int c); + +/** Sets `c` to the sum of `a` and `value`. */ +mp_result mp_int_add_value(mp_int a, mp_small value, mp_int c); + +/** Sets `c` to the difference of `a` less `b`. */ +mp_result mp_int_sub(mp_int a, mp_int b, mp_int c); + +/** Sets `c` to the difference of `a` less `value`. */ +mp_result mp_int_sub_value(mp_int a, mp_small value, mp_int c); + +/** Sets `c` to the product of `a` and `b`. */ +mp_result mp_int_mul(mp_int a, mp_int b, mp_int c); + +/** Sets `c` to the product of `a` and `value`. */ +mp_result mp_int_mul_value(mp_int a, mp_small value, mp_int c); + +/** Sets `c` to the product of `a` and `2^p2`. Requires `p2 >= 0`. */ +mp_result mp_int_mul_pow2(mp_int a, mp_small p2, mp_int c); + +/** Sets `c` to the square of `a`. */ +mp_result mp_int_sqr(mp_int a, mp_int c); + +/** Sets `q` and `r` to the quotent and remainder of `a / b`. Division by + powers of 2 is detected and handled efficiently. The remainder is pinned + to `0 <= r < b`. + + Either of `q` or `r` may be NULL, but not both, and `q` and `r` may not + point to the same value. */ +mp_result mp_int_div(mp_int a, mp_int b, mp_int q, mp_int r); + +/** Sets `q` and `*r` to the quotent and remainder of `a / value`. Division by + powers of 2 is detected and handled efficiently. The remainder is pinned to + `0 <= *r < b`. Either of `q` or `r` may be NULL. */ +mp_result mp_int_div_value(mp_int a, mp_small value, mp_int q, mp_small *r); + +/** Sets `q` and `r` to the quotient and remainder of `a / 2^p2`. This is a + special case for division by powers of two that is more efficient than + using ordinary division. Note that `mp_int_div()` will automatically handle + this case, this function is for cases where you have only the exponent. */ +mp_result mp_int_div_pow2(mp_int a, mp_small p2, mp_int q, mp_int r); + +/** Sets `c` to the remainder of `a / m`. + The remainder is pinned to `0 <= c < m`. */ +mp_result mp_int_mod(mp_int a, mp_int m, mp_int c); + +/** Sets `c` to the value of `a` raised to the `b` power. + It returns `MP_RANGE` if `b < 0`. */ +mp_result mp_int_expt(mp_int a, mp_small b, mp_int c); + +/** Sets `c` to the value of `a` raised to the `b` power. + It returns `MP_RANGE` if `b < 0`. */ +mp_result mp_int_expt_value(mp_small a, mp_small b, mp_int c); + +/** Sets `c` to the value of `a` raised to the `b` power. + It returns `MP_RANGE`) if `b < 0`. */ +mp_result mp_int_expt_full(mp_int a, mp_int b, mp_int c); + +/** Sets `*r` to the remainder of `a / value`. + The remainder is pinned to `0 <= r < value`. */ +static inline +mp_result mp_int_mod_value(mp_int a, mp_small value, mp_small* r) { + return mp_int_div_value(a, value, 0, r); +} + +/** Returns the comparator of `a` and `b`. */ +int mp_int_compare(mp_int a, mp_int b); + +/** Returns the comparator of the magnitudes of `a` and `b`, disregarding their + signs. Neither `a` nor `b` is modified by the comparison. */ +int mp_int_compare_unsigned(mp_int a, mp_int b); + +/** Returns the comparator of `z` and zero. */ +int mp_int_compare_zero(mp_int z); + +/** Returns the comparator of `z` and the signed value `v`. */ +int mp_int_compare_value(mp_int z, mp_small v); + +/** Returns the comparator of `z` and the unsigned value `uv`. */ +int mp_int_compare_uvalue(mp_int z, mp_usmall uv); + +/** Reports whether `a` is divisible by `v`. */ +bool mp_int_divisible_value(mp_int a, mp_small v); + +/** Returns `k >= 0` such that `z` is `2^k`, if such a `k` exists. If no such + `k` exists, the function returns -1. */ +int mp_int_is_pow2(mp_int z); + +/** Sets `c` to the value of `a` raised to the `b` power, reduced modulo `m`. + It returns `MP_RANGE` if `b < 0` or `MP_UNDEF` if `m == 0`. */ +mp_result mp_int_exptmod(mp_int a, mp_int b, mp_int m, mp_int c); + +/** Sets `c` to the value of `a` raised to the `value` power, modulo `m`. + It returns `MP_RANGE` if `value < 0` or `MP_UNDEF` if `m == 0`. */ +mp_result mp_int_exptmod_evalue(mp_int a, mp_small value, mp_int m, mp_int c); + +/** Sets `c` to the value of `value` raised to the `b` power, modulo `m`. + It returns `MP_RANGE` if `b < 0` or `MP_UNDEF` if `m == 0`. */ +mp_result mp_int_exptmod_bvalue(mp_small value, mp_int b, mp_int m, mp_int c); + +/** Sets `c` to the value of `a` raised to the `b` power, reduced modulo `m`, + given a precomputed reduction constant `mu` defined for Barrett's modular + reduction algorithm. + + It returns `MP_RANGE` if `b < 0` or `MP_UNDEF` if `m == 0`. */ +mp_result mp_int_exptmod_known(mp_int a, mp_int b, mp_int m, mp_int mu, mp_int c); + +/** Sets `c` to the reduction constant for Barrett reduction by modulus `m`. + Requires that `c` and `m` point to distinct locations. */ +mp_result mp_int_redux_const(mp_int m, mp_int c); + +/** Sets `c` to the multiplicative inverse of `a` modulo `m`, if it exists. + The least non-negative representative of the congruence class is computed. + + It returns `MP_UNDEF` if the inverse does not exist, or `MP_RANGE` if `a == + 0` or `m <= 0`. */ +mp_result mp_int_invmod(mp_int a, mp_int m, mp_int c); + +/** Sets `c` to the greatest common divisor of `a` and `b`. + + It returns `MP_UNDEF` if the GCD is undefined, such as for example if `a` + and `b` are both zero. */ +mp_result mp_int_gcd(mp_int a, mp_int b, mp_int c); + +/** Sets `c` to the greatest common divisor of `a` and `b`, and sets `x` and + `y` to values satisfying Bezout's identity `gcd(a, b) = ax + by`. + + It returns `MP_UNDEF` if the GCD is undefined, such as for example if `a` + and `b` are both zero. */ +mp_result mp_int_egcd(mp_int a, mp_int b, mp_int c, mp_int x, mp_int y); + +/** Sets `c` to the least common multiple of `a` and `b`. + + It returns `MP_UNDEF` if the LCM is undefined, such as for example if `a` + and `b` are both zero. */ +mp_result mp_int_lcm(mp_int a, mp_int b, mp_int c); + +/** Sets `c` to the greatest integer not less than the `b`th root of `a`, + using Newton's root-finding algorithm. + It returns `MP_UNDEF` if `a < 0` and `b` is even. */ +mp_result mp_int_root(mp_int a, mp_small b, mp_int c); + +/** Sets `c` to the greatest integer not less than the square root of `a`. + This is a special case of `mp_int_root()`. */ +static inline +mp_result mp_int_sqrt(mp_int a, mp_int c) { return mp_int_root(a, 2, c); } + +/** Returns `MP_OK` if `z` is representable as `mp_small`, else `MP_RANGE`. + If `out` is not NULL, `*out` is set to the value of `z` when `MP_OK`. */ +mp_result mp_int_to_int(mp_int z, mp_small *out); + +/** Returns `MP_OK` if `z` is representable as `mp_usmall`, or `MP_RANGE`. + If `out` is not NULL, `*out` is set to the value of `z` when `MP_OK`. */ +mp_result mp_int_to_uint(mp_int z, mp_usmall *out); + +/** Converts `z` to a zero-terminated string of characters in the specified + `radix`, writing at most `limit` characters to `str` including the + terminating NUL value. A leading `-` is used to indicate a negative value. + + Returns `MP_TRUNC` if `limit` was to small to write all of `z`. + Requires `MP_MIN_RADIX <= radix <= MP_MAX_RADIX`. */ +mp_result mp_int_to_string(mp_int z, mp_size radix, char *str, int limit); + +/** Reports the minimum number of characters required to represent `z` as a + zero-terminated string in the given `radix`. + Requires `MP_MIN_RADIX <= radix <= MP_MAX_RADIX`. */ +mp_result mp_int_string_len(mp_int z, mp_size radix); + +/** Reads a string of ASCII digits in the specified `radix` from the zero + terminated `str` provided into `z`. For values of `radix > 10`, the letters + `A`..`Z` or `a`..`z` are accepted. Letters are interpreted without respect + to case. + + Leading whitespace is ignored, and a leading `+` or `-` is interpreted as a + sign flag. Processing stops when a NUL or any other character out of range + for a digit in the given radix is encountered. + + If the whole string was consumed, `MP_OK` is returned; otherwise + `MP_TRUNC`. is returned. + + Requires `MP_MIN_RADIX <= radix <= MP_MAX_RADIX`. */ +mp_result mp_int_read_string(mp_int z, mp_size radix, const char *str); + +/** Reads a string of ASCII digits in the specified `radix` from the zero + terminated `str` provided into `z`. For values of `radix > 10`, the letters + `A`..`Z` or `a`..`z` are accepted. Letters are interpreted without respect + to case. + + Leading whitespace is ignored, and a leading `+` or `-` is interpreted as a + sign flag. Processing stops when a NUL or any other character out of range + for a digit in the given radix is encountered. + + If the whole string was consumed, `MP_OK` is returned; otherwise + `MP_TRUNC`. is returned. If `end` is not NULL, `*end` is set to point to + the first unconsumed byte of the input string (the NUL byte if the whole + string was consumed). This emulates the behavior of the standard C + `strtol()` function. + + Requires `MP_MIN_RADIX <= radix <= MP_MAX_RADIX`. */ +mp_result mp_int_read_cstring(mp_int z, mp_size radix, const char *str, char **end); + +/** Returns the number of significant bits in `z`. */ +mp_result mp_int_count_bits(mp_int z); + +/** Converts `z` to 2's complement binary, writing at most `limit` bytes into + the given `buf`. Returns `MP_TRUNC` if the buffer limit was too small to + contain the whole value. If this occurs, the contents of buf will be + effectively garbage, as the function uses the buffer as scratch space. + + The binary representation of `z` is in base-256 with digits ordered from + most significant to least significant (network byte ordering). The + high-order bit of the first byte is set for negative values, clear for + non-negative values. + + As a result, non-negative values will be padded with a leading zero byte if + the high-order byte of the base-256 magnitude is set. This extra byte is + accounted for by the `mp_int_binary_len()` function. */ +mp_result mp_int_to_binary(mp_int z, unsigned char *buf, int limit); + +/** Reads a 2's complement binary value from `buf` into `z`, where `len` is the + length of the buffer. The contents of `buf` may be overwritten during + processing, although they will be restored when the function returns. */ +mp_result mp_int_read_binary(mp_int z, unsigned char *buf, int len); + +/** Returns the number of bytes to represent `z` in 2's complement binary. */ +mp_result mp_int_binary_len(mp_int z); + +/** Converts the magnitude of `z` to unsigned binary, writing at most `limit` + bytes into the given `buf`. The sign of `z` is ignored, but `z` is not + modified. Returns `MP_TRUNC` if the buffer limit was too small to contain + the whole value. If this occurs, the contents of `buf` will be effectively + garbage, as the function uses the buffer as scratch space during + conversion. + + The binary representation of `z` is in base-256 with digits ordered from + most significant to least significant (network byte ordering). */ +mp_result mp_int_to_unsigned(mp_int z, unsigned char *buf, int limit); + +/** Reads an unsigned binary value from `buf` into `z`, where `len` is the + length of the buffer. The contents of `buf` are not modified during + processing. */ +mp_result mp_int_read_unsigned(mp_int z, unsigned char *buf, int len); + +/** Returns the number of bytes required to represent `z` as an unsigned binary + value in base 256. */ +mp_result mp_int_unsigned_len(mp_int z); + +/** Returns a pointer to a brief, human-readable, zero-terminated string + describing `res`. The returned string is statically allocated and must not + be freed by the caller. */ +const char *mp_error_string(mp_result res); + +#ifdef __cplusplus +} +#endif +#endif /* end IMATH_H_ */ diff --git a/external/mit/isl/dist/imath/imrat.c b/external/mit/isl/dist/imath/imrat.c new file mode 100644 index 000000000000..afcfdaf3a78b --- /dev/null +++ b/external/mit/isl/dist/imath/imrat.c @@ -0,0 +1,940 @@ +/* + Name: imrat.c + Purpose: Arbitrary precision rational arithmetic routines. + Author: M. J. Fromberger + + Copyright (C) 2002-2007 Michael J. Fromberger, All Rights Reserved. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +#include "imrat.h" +#include +#include +#include +#include + +#define MP_NUMER_SIGN(Q) (MP_NUMER_P(Q)->sign) +#define MP_DENOM_SIGN(Q) (MP_DENOM_P(Q)->sign) + +#define TEMP(K) (temp + (K)) +#define SETUP(E, C) \ + do { \ + if ((res = (E)) != MP_OK) goto CLEANUP; \ + ++(C); \ + } while (0) + +/* Reduce the given rational, in place, to lowest terms and canonical form. + Zero is represented as 0/1, one as 1/1. Signs are adjusted so that the sign + of the numerator is definitive. */ +static mp_result s_rat_reduce(mp_rat r); + +/* Common code for addition and subtraction operations on rationals. */ +static mp_result s_rat_combine(mp_rat a, mp_rat b, mp_rat c, + mp_result (*comb_f)(mp_int, mp_int, mp_int)); + +mp_result mp_rat_init(mp_rat r) { + mp_result res; + + if ((res = mp_int_init(MP_NUMER_P(r))) != MP_OK) return res; + if ((res = mp_int_init(MP_DENOM_P(r))) != MP_OK) { + mp_int_clear(MP_NUMER_P(r)); + return res; + } + + return mp_int_set_value(MP_DENOM_P(r), 1); +} + +mp_rat mp_rat_alloc(void) { + mp_rat out = malloc(sizeof(*out)); + + if (out != NULL) { + if (mp_rat_init(out) != MP_OK) { + free(out); + return NULL; + } + } + + return out; +} + +mp_result mp_rat_reduce(mp_rat r) { return s_rat_reduce(r); } + +mp_result mp_rat_init_size(mp_rat r, mp_size n_prec, mp_size d_prec) { + mp_result res; + + if ((res = mp_int_init_size(MP_NUMER_P(r), n_prec)) != MP_OK) { + return res; + } + if ((res = mp_int_init_size(MP_DENOM_P(r), d_prec)) != MP_OK) { + mp_int_clear(MP_NUMER_P(r)); + return res; + } + + return mp_int_set_value(MP_DENOM_P(r), 1); +} + +mp_result mp_rat_init_copy(mp_rat r, mp_rat old) { + mp_result res; + + if ((res = mp_int_init_copy(MP_NUMER_P(r), MP_NUMER_P(old))) != MP_OK) { + return res; + } + if ((res = mp_int_init_copy(MP_DENOM_P(r), MP_DENOM_P(old))) != MP_OK) + mp_int_clear(MP_NUMER_P(r)); + + return res; +} + +mp_result mp_rat_set_value(mp_rat r, mp_small numer, mp_small denom) { + mp_result res; + + if (denom == 0) return MP_UNDEF; + + if ((res = mp_int_set_value(MP_NUMER_P(r), numer)) != MP_OK) { + return res; + } + if ((res = mp_int_set_value(MP_DENOM_P(r), denom)) != MP_OK) { + return res; + } + + return s_rat_reduce(r); +} + +mp_result mp_rat_set_uvalue(mp_rat r, mp_usmall numer, mp_usmall denom) { + mp_result res; + + if (denom == 0) return MP_UNDEF; + + if ((res = mp_int_set_uvalue(MP_NUMER_P(r), numer)) != MP_OK) { + return res; + } + if ((res = mp_int_set_uvalue(MP_DENOM_P(r), denom)) != MP_OK) { + return res; + } + + return s_rat_reduce(r); +} + +void mp_rat_clear(mp_rat r) { + mp_int_clear(MP_NUMER_P(r)); + mp_int_clear(MP_DENOM_P(r)); +} + +void mp_rat_free(mp_rat r) { + assert(r != NULL); + + if (r->num.digits != NULL) mp_rat_clear(r); + + free(r); +} + +mp_result mp_rat_numer(mp_rat r, mp_int z) { + return mp_int_copy(MP_NUMER_P(r), z); +} + +mp_int mp_rat_numer_ref(mp_rat r) { return MP_NUMER_P(r); } + +mp_result mp_rat_denom(mp_rat r, mp_int z) { + return mp_int_copy(MP_DENOM_P(r), z); +} + +mp_int mp_rat_denom_ref(mp_rat r) { return MP_DENOM_P(r); } + +mp_sign mp_rat_sign(mp_rat r) { return MP_NUMER_SIGN(r); } + +mp_result mp_rat_copy(mp_rat a, mp_rat c) { + mp_result res; + + if ((res = mp_int_copy(MP_NUMER_P(a), MP_NUMER_P(c))) != MP_OK) { + return res; + } + + res = mp_int_copy(MP_DENOM_P(a), MP_DENOM_P(c)); + return res; +} + +void mp_rat_zero(mp_rat r) { + mp_int_zero(MP_NUMER_P(r)); + mp_int_set_value(MP_DENOM_P(r), 1); +} + +mp_result mp_rat_abs(mp_rat a, mp_rat c) { + mp_result res; + + if ((res = mp_int_abs(MP_NUMER_P(a), MP_NUMER_P(c))) != MP_OK) { + return res; + } + + res = mp_int_abs(MP_DENOM_P(a), MP_DENOM_P(c)); + return res; +} + +mp_result mp_rat_neg(mp_rat a, mp_rat c) { + mp_result res; + + if ((res = mp_int_neg(MP_NUMER_P(a), MP_NUMER_P(c))) != MP_OK) { + return res; + } + + res = mp_int_copy(MP_DENOM_P(a), MP_DENOM_P(c)); + return res; +} + +mp_result mp_rat_recip(mp_rat a, mp_rat c) { + mp_result res; + + if (mp_rat_compare_zero(a) == 0) return MP_UNDEF; + + if ((res = mp_rat_copy(a, c)) != MP_OK) return res; + + mp_int_swap(MP_NUMER_P(c), MP_DENOM_P(c)); + + /* Restore the signs of the swapped elements */ + { + mp_sign tmp = MP_NUMER_SIGN(c); + + MP_NUMER_SIGN(c) = MP_DENOM_SIGN(c); + MP_DENOM_SIGN(c) = tmp; + } + + return MP_OK; +} + +mp_result mp_rat_add(mp_rat a, mp_rat b, mp_rat c) { + return s_rat_combine(a, b, c, mp_int_add); +} + +mp_result mp_rat_sub(mp_rat a, mp_rat b, mp_rat c) { + return s_rat_combine(a, b, c, mp_int_sub); +} + +mp_result mp_rat_mul(mp_rat a, mp_rat b, mp_rat c) { + mp_result res; + + if ((res = mp_int_mul(MP_NUMER_P(a), MP_NUMER_P(b), MP_NUMER_P(c))) != MP_OK) + return res; + + if (mp_int_compare_zero(MP_NUMER_P(c)) != 0) { + res = mp_int_mul(MP_DENOM_P(a), MP_DENOM_P(b), MP_DENOM_P(c)); + if (res != MP_OK) { + return res; + } + } + + return s_rat_reduce(c); +} + +mp_result mp_rat_div(mp_rat a, mp_rat b, mp_rat c) { + mp_result res = MP_OK; + + if (mp_rat_compare_zero(b) == 0) return MP_UNDEF; + + if (c == a || c == b) { + mpz_t tmp; + + if ((res = mp_int_init(&tmp)) != MP_OK) return res; + if ((res = mp_int_mul(MP_NUMER_P(a), MP_DENOM_P(b), &tmp)) != MP_OK) { + goto CLEANUP; + } + if ((res = mp_int_mul(MP_DENOM_P(a), MP_NUMER_P(b), MP_DENOM_P(c))) != + MP_OK) { + goto CLEANUP; + } + res = mp_int_copy(&tmp, MP_NUMER_P(c)); + + CLEANUP: + mp_int_clear(&tmp); + } else { + if ((res = mp_int_mul(MP_NUMER_P(a), MP_DENOM_P(b), MP_NUMER_P(c))) != + MP_OK) { + return res; + } + if ((res = mp_int_mul(MP_DENOM_P(a), MP_NUMER_P(b), MP_DENOM_P(c))) != + MP_OK) { + return res; + } + } + + if (res != MP_OK) { + return res; + } else { + return s_rat_reduce(c); + } +} + +mp_result mp_rat_add_int(mp_rat a, mp_int b, mp_rat c) { + mpz_t tmp; + mp_result res; + + if ((res = mp_int_init_copy(&tmp, b)) != MP_OK) { + return res; + } + if ((res = mp_int_mul(&tmp, MP_DENOM_P(a), &tmp)) != MP_OK) { + goto CLEANUP; + } + if ((res = mp_rat_copy(a, c)) != MP_OK) { + goto CLEANUP; + } + if ((res = mp_int_add(MP_NUMER_P(c), &tmp, MP_NUMER_P(c))) != MP_OK) { + goto CLEANUP; + } + + res = s_rat_reduce(c); + +CLEANUP: + mp_int_clear(&tmp); + return res; +} + +mp_result mp_rat_sub_int(mp_rat a, mp_int b, mp_rat c) { + mpz_t tmp; + mp_result res; + + if ((res = mp_int_init_copy(&tmp, b)) != MP_OK) { + return res; + } + if ((res = mp_int_mul(&tmp, MP_DENOM_P(a), &tmp)) != MP_OK) { + goto CLEANUP; + } + if ((res = mp_rat_copy(a, c)) != MP_OK) { + goto CLEANUP; + } + if ((res = mp_int_sub(MP_NUMER_P(c), &tmp, MP_NUMER_P(c))) != MP_OK) { + goto CLEANUP; + } + + res = s_rat_reduce(c); + +CLEANUP: + mp_int_clear(&tmp); + return res; +} + +mp_result mp_rat_mul_int(mp_rat a, mp_int b, mp_rat c) { + mp_result res; + + if ((res = mp_rat_copy(a, c)) != MP_OK) { + return res; + } + if ((res = mp_int_mul(MP_NUMER_P(c), b, MP_NUMER_P(c))) != MP_OK) { + return res; + } + + return s_rat_reduce(c); +} + +mp_result mp_rat_div_int(mp_rat a, mp_int b, mp_rat c) { + mp_result res; + + if (mp_int_compare_zero(b) == 0) { + return MP_UNDEF; + } + if ((res = mp_rat_copy(a, c)) != MP_OK) { + return res; + } + if ((res = mp_int_mul(MP_DENOM_P(c), b, MP_DENOM_P(c))) != MP_OK) { + return res; + } + + return s_rat_reduce(c); +} + +mp_result mp_rat_expt(mp_rat a, mp_small b, mp_rat c) { + mp_result res; + + /* Special cases for easy powers. */ + if (b == 0) { + return mp_rat_set_value(c, 1, 1); + } else if (b == 1) { + return mp_rat_copy(a, c); + } + + /* Since rationals are always stored in lowest terms, it is not necessary to + reduce again when raising to an integer power. */ + if ((res = mp_int_expt(MP_NUMER_P(a), b, MP_NUMER_P(c))) != MP_OK) { + return res; + } + + return mp_int_expt(MP_DENOM_P(a), b, MP_DENOM_P(c)); +} + +int mp_rat_compare(mp_rat a, mp_rat b) { + /* Quick check for opposite signs. Works because the sign of the numerator + is always definitive. */ + if (MP_NUMER_SIGN(a) != MP_NUMER_SIGN(b)) { + if (MP_NUMER_SIGN(a) == MP_ZPOS) { + return 1; + } else { + return -1; + } + } else { + /* Compare absolute magnitudes; if both are positive, the answer stands, + otherwise it needs to be reflected about zero. */ + int cmp = mp_rat_compare_unsigned(a, b); + + if (MP_NUMER_SIGN(a) == MP_ZPOS) { + return cmp; + } else { + return -cmp; + } + } +} + +int mp_rat_compare_unsigned(mp_rat a, mp_rat b) { + /* If the denominators are equal, we can quickly compare numerators without + multiplying. Otherwise, we actually have to do some work. */ + if (mp_int_compare_unsigned(MP_DENOM_P(a), MP_DENOM_P(b)) == 0) { + return mp_int_compare_unsigned(MP_NUMER_P(a), MP_NUMER_P(b)); + } + + else { + mpz_t temp[2]; + mp_result res; + int cmp = INT_MAX, last = 0; + + /* t0 = num(a) * den(b), t1 = num(b) * den(a) */ + SETUP(mp_int_init_copy(TEMP(last), MP_NUMER_P(a)), last); + SETUP(mp_int_init_copy(TEMP(last), MP_NUMER_P(b)), last); + + if ((res = mp_int_mul(TEMP(0), MP_DENOM_P(b), TEMP(0))) != MP_OK || + (res = mp_int_mul(TEMP(1), MP_DENOM_P(a), TEMP(1))) != MP_OK) { + goto CLEANUP; + } + + cmp = mp_int_compare_unsigned(TEMP(0), TEMP(1)); + + CLEANUP: + while (--last >= 0) { + mp_int_clear(TEMP(last)); + } + + return cmp; + } +} + +int mp_rat_compare_zero(mp_rat r) { return mp_int_compare_zero(MP_NUMER_P(r)); } + +int mp_rat_compare_value(mp_rat r, mp_small n, mp_small d) { + mpq_t tmp; + mp_result res; + int out = INT_MAX; + + if ((res = mp_rat_init(&tmp)) != MP_OK) { + return out; + } + if ((res = mp_rat_set_value(&tmp, n, d)) != MP_OK) { + goto CLEANUP; + } + + out = mp_rat_compare(r, &tmp); + +CLEANUP: + mp_rat_clear(&tmp); + return out; +} + +bool mp_rat_is_integer(mp_rat r) { + return (mp_int_compare_value(MP_DENOM_P(r), 1) == 0); +} + +mp_result mp_rat_to_ints(mp_rat r, mp_small *num, mp_small *den) { + mp_result res; + + if ((res = mp_int_to_int(MP_NUMER_P(r), num)) != MP_OK) { + return res; + } + + res = mp_int_to_int(MP_DENOM_P(r), den); + return res; +} + +mp_result mp_rat_to_string(mp_rat r, mp_size radix, char *str, int limit) { + /* Write the numerator. The sign of the rational number is written by the + underlying integer implementation. */ + mp_result res; + if ((res = mp_int_to_string(MP_NUMER_P(r), radix, str, limit)) != MP_OK) { + return res; + } + + /* If the value is zero, don't bother writing any denominator */ + if (mp_int_compare_zero(MP_NUMER_P(r)) == 0) { + return MP_OK; + } + + /* Locate the end of the numerator, and make sure we are not going to exceed + the limit by writing a slash. */ + int len = strlen(str); + char *start = str + len; + limit -= len; + if (limit == 0) return MP_TRUNC; + + *start++ = '/'; + limit -= 1; + + return mp_int_to_string(MP_DENOM_P(r), radix, start, limit); +} + +mp_result mp_rat_to_decimal(mp_rat r, mp_size radix, mp_size prec, + mp_round_mode round, char *str, int limit) { + mpz_t temp[3]; + mp_result res; + int last = 0; + + SETUP(mp_int_init_copy(TEMP(last), MP_NUMER_P(r)), last); + SETUP(mp_int_init(TEMP(last)), last); + SETUP(mp_int_init(TEMP(last)), last); + + /* Get the unsigned integer part by dividing denominator into the absolute + value of the numerator. */ + mp_int_abs(TEMP(0), TEMP(0)); + if ((res = mp_int_div(TEMP(0), MP_DENOM_P(r), TEMP(0), TEMP(1))) != MP_OK) { + goto CLEANUP; + } + + /* Now: T0 = integer portion, unsigned; + T1 = remainder, from which fractional part is computed. */ + + /* Count up leading zeroes after the radix point. */ + int zprec = (int)prec; + int lead_0; + for (lead_0 = 0; lead_0 < zprec && mp_int_compare(TEMP(1), MP_DENOM_P(r)) < 0; + ++lead_0) { + if ((res = mp_int_mul_value(TEMP(1), radix, TEMP(1))) != MP_OK) { + goto CLEANUP; + } + } + + /* Multiply remainder by a power of the radix sufficient to get the right + number of significant figures. */ + if (zprec > lead_0) { + if ((res = mp_int_expt_value(radix, zprec - lead_0, TEMP(2))) != MP_OK) { + goto CLEANUP; + } + if ((res = mp_int_mul(TEMP(1), TEMP(2), TEMP(1))) != MP_OK) { + goto CLEANUP; + } + } + if ((res = mp_int_div(TEMP(1), MP_DENOM_P(r), TEMP(1), TEMP(2))) != MP_OK) { + goto CLEANUP; + } + + /* Now: T1 = significant digits of fractional part; + T2 = leftovers, to use for rounding. + + At this point, what we do depends on the rounding mode. The default is + MP_ROUND_DOWN, for which everything is as it should be already. + */ + switch (round) { + int cmp; + + case MP_ROUND_UP: + if (mp_int_compare_zero(TEMP(2)) != 0) { + if (prec == 0) { + res = mp_int_add_value(TEMP(0), 1, TEMP(0)); + } else { + res = mp_int_add_value(TEMP(1), 1, TEMP(1)); + } + } + break; + + case MP_ROUND_HALF_UP: + case MP_ROUND_HALF_DOWN: + if ((res = mp_int_mul_pow2(TEMP(2), 1, TEMP(2))) != MP_OK) { + goto CLEANUP; + } + + cmp = mp_int_compare(TEMP(2), MP_DENOM_P(r)); + + if (round == MP_ROUND_HALF_UP) cmp += 1; + + if (cmp > 0) { + if (prec == 0) { + res = mp_int_add_value(TEMP(0), 1, TEMP(0)); + } else { + res = mp_int_add_value(TEMP(1), 1, TEMP(1)); + } + } + break; + + case MP_ROUND_DOWN: + break; /* No action required */ + + default: + return MP_BADARG; /* Invalid rounding specifier */ + } + if (res != MP_OK) { + goto CLEANUP; + } + + /* The sign of the output should be the sign of the numerator, but if all the + displayed digits will be zero due to the precision, a negative shouldn't + be shown. */ + char *start = str; + int left = limit; + if (MP_NUMER_SIGN(r) == MP_NEG && (mp_int_compare_zero(TEMP(0)) != 0 || + mp_int_compare_zero(TEMP(1)) != 0)) { + *start++ = '-'; + left -= 1; + } + + if ((res = mp_int_to_string(TEMP(0), radix, start, left)) != MP_OK) { + goto CLEANUP; + } + + int len = strlen(start); + start += len; + left -= len; + + if (prec == 0) goto CLEANUP; + + *start++ = '.'; + left -= 1; + + if (left < zprec + 1) { + res = MP_TRUNC; + goto CLEANUP; + } + + memset(start, '0', lead_0 - 1); + left -= lead_0; + start += lead_0 - 1; + + res = mp_int_to_string(TEMP(1), radix, start, left); + +CLEANUP: + while (--last >= 0) mp_int_clear(TEMP(last)); + + return res; +} + +mp_result mp_rat_string_len(mp_rat r, mp_size radix) { + mp_result d_len = 0; + mp_result n_len = mp_int_string_len(MP_NUMER_P(r), radix); + + if (mp_int_compare_zero(MP_NUMER_P(r)) != 0) { + d_len = mp_int_string_len(MP_DENOM_P(r), radix); + } + + /* Though simplistic, this formula is correct. Space for the sign flag is + included in n_len, and the space for the NUL that is counted in n_len + counts for the separator here. The space for the NUL counted in d_len + counts for the final terminator here. */ + + return n_len + d_len; +} + +mp_result mp_rat_decimal_len(mp_rat r, mp_size radix, mp_size prec) { + int f_len; + int z_len = mp_int_string_len(MP_NUMER_P(r), radix); + + if (prec == 0) { + f_len = 1; /* terminator only */ + } else { + f_len = 1 + prec + 1; /* decimal point, digits, terminator */ + } + + return z_len + f_len; +} + +mp_result mp_rat_read_string(mp_rat r, mp_size radix, const char *str) { + return mp_rat_read_cstring(r, radix, str, NULL); +} + +mp_result mp_rat_read_cstring(mp_rat r, mp_size radix, const char *str, + char **end) { + mp_result res; + char *endp; + + if ((res = mp_int_read_cstring(MP_NUMER_P(r), radix, str, &endp)) != MP_OK && + (res != MP_TRUNC)) { + return res; + } + + /* Skip whitespace between numerator and (possible) separator */ + while (isspace((unsigned char)*endp)) { + ++endp; + } + + /* If there is no separator, we will stop reading at this point. */ + if (*endp != '/') { + mp_int_set_value(MP_DENOM_P(r), 1); + if (end != NULL) *end = endp; + return res; + } + + ++endp; /* skip separator */ + if ((res = mp_int_read_cstring(MP_DENOM_P(r), radix, endp, end)) != MP_OK) { + return res; + } + + /* Make sure the value is well-defined */ + if (mp_int_compare_zero(MP_DENOM_P(r)) == 0) { + return MP_UNDEF; + } + + /* Reduce to lowest terms */ + return s_rat_reduce(r); +} + +/* Read a string and figure out what format it's in. The radix may be supplied + as zero to use "default" behaviour. + + This function will accept either a/b notation or decimal notation. + */ +mp_result mp_rat_read_ustring(mp_rat r, mp_size radix, const char *str, + char **end) { + char *endp = ""; + mp_result res; + + if (radix == 0) radix = 10; /* default to decimal input */ + + res = mp_rat_read_cstring(r, radix, str, &endp); + if (res == MP_TRUNC && *endp == '.') { + res = mp_rat_read_cdecimal(r, radix, str, &endp); + } + if (end != NULL) *end = endp; + return res; +} + +mp_result mp_rat_read_decimal(mp_rat r, mp_size radix, const char *str) { + return mp_rat_read_cdecimal(r, radix, str, NULL); +} + +mp_result mp_rat_read_cdecimal(mp_rat r, mp_size radix, const char *str, + char **end) { + mp_result res; + mp_sign osign; + char *endp; + + while (isspace((unsigned char)*str)) ++str; + + switch (*str) { + case '-': + osign = MP_NEG; + break; + default: + osign = MP_ZPOS; + } + + if ((res = mp_int_read_cstring(MP_NUMER_P(r), radix, str, &endp)) != MP_OK && + (res != MP_TRUNC)) { + return res; + } + + /* This needs to be here. */ + (void)mp_int_set_value(MP_DENOM_P(r), 1); + + if (*endp != '.') { + if (end != NULL) *end = endp; + return res; + } + + /* If the character following the decimal point is whitespace or a sign flag, + we will consider this a truncated value. This special case is because + mp_int_read_string() will consider whitespace or sign flags to be valid + starting characters for a value, and we do not want them following the + decimal point. + + Once we have done this check, it is safe to read in the value of the + fractional piece as a regular old integer. + */ + ++endp; + if (*endp == '\0') { + if (end != NULL) *end = endp; + return MP_OK; + } else if (isspace((unsigned char)*endp) || *endp == '-' || *endp == '+') { + return MP_TRUNC; + } else { + mpz_t frac; + mp_result save_res; + char *save = endp; + int num_lz = 0; + + /* Make a temporary to hold the part after the decimal point. */ + if ((res = mp_int_init(&frac)) != MP_OK) { + return res; + } + + if ((res = mp_int_read_cstring(&frac, radix, endp, &endp)) != MP_OK && + (res != MP_TRUNC)) { + goto CLEANUP; + } + + /* Save this response for later. */ + save_res = res; + + if (mp_int_compare_zero(&frac) == 0) goto FINISHED; + + /* Discard trailing zeroes (somewhat inefficiently) */ + while (mp_int_divisible_value(&frac, radix)) { + if ((res = mp_int_div_value(&frac, radix, &frac, NULL)) != MP_OK) { + goto CLEANUP; + } + } + + /* Count leading zeros after the decimal point */ + while (save[num_lz] == '0') { + ++num_lz; + } + + /* Find the least power of the radix that is at least as large as the + significant value of the fractional part, ignoring leading zeroes. */ + (void)mp_int_set_value(MP_DENOM_P(r), radix); + + while (mp_int_compare(MP_DENOM_P(r), &frac) < 0) { + if ((res = mp_int_mul_value(MP_DENOM_P(r), radix, MP_DENOM_P(r))) != + MP_OK) { + goto CLEANUP; + } + } + + /* Also shift by enough to account for leading zeroes */ + while (num_lz > 0) { + if ((res = mp_int_mul_value(MP_DENOM_P(r), radix, MP_DENOM_P(r))) != + MP_OK) { + goto CLEANUP; + } + + --num_lz; + } + + /* Having found this power, shift the numerator leftward that many, digits, + and add the nonzero significant digits of the fractional part to get the + result. */ + if ((res = mp_int_mul(MP_NUMER_P(r), MP_DENOM_P(r), MP_NUMER_P(r))) != + MP_OK) { + goto CLEANUP; + } + + { /* This addition needs to be unsigned. */ + MP_NUMER_SIGN(r) = MP_ZPOS; + if ((res = mp_int_add(MP_NUMER_P(r), &frac, MP_NUMER_P(r))) != MP_OK) { + goto CLEANUP; + } + + MP_NUMER_SIGN(r) = osign; + } + if ((res = s_rat_reduce(r)) != MP_OK) goto CLEANUP; + + /* At this point, what we return depends on whether reading the fractional + part was truncated or not. That information is saved from when we + called mp_int_read_string() above. */ + FINISHED: + res = save_res; + if (end != NULL) *end = endp; + + CLEANUP: + mp_int_clear(&frac); + + return res; + } +} + +/* Private functions for internal use. Make unchecked assumptions about format + and validity of inputs. */ + +static mp_result s_rat_reduce(mp_rat r) { + mpz_t gcd; + mp_result res = MP_OK; + + if (mp_int_compare_zero(MP_NUMER_P(r)) == 0) { + mp_int_set_value(MP_DENOM_P(r), 1); + return MP_OK; + } + + /* If the greatest common divisor of the numerator and denominator is greater + than 1, divide it out. */ + if ((res = mp_int_init(&gcd)) != MP_OK) return res; + + if ((res = mp_int_gcd(MP_NUMER_P(r), MP_DENOM_P(r), &gcd)) != MP_OK) { + goto CLEANUP; + } + + if (mp_int_compare_value(&gcd, 1) != 0) { + if ((res = mp_int_div(MP_NUMER_P(r), &gcd, MP_NUMER_P(r), NULL)) != MP_OK) { + goto CLEANUP; + } + if ((res = mp_int_div(MP_DENOM_P(r), &gcd, MP_DENOM_P(r), NULL)) != MP_OK) { + goto CLEANUP; + } + } + + /* Fix up the signs of numerator and denominator */ + if (MP_NUMER_SIGN(r) == MP_DENOM_SIGN(r)) { + MP_NUMER_SIGN(r) = MP_DENOM_SIGN(r) = MP_ZPOS; + } else { + MP_NUMER_SIGN(r) = MP_NEG; + MP_DENOM_SIGN(r) = MP_ZPOS; + } + +CLEANUP: + mp_int_clear(&gcd); + + return res; +} + +static mp_result s_rat_combine(mp_rat a, mp_rat b, mp_rat c, + mp_result (*comb_f)(mp_int, mp_int, mp_int)) { + mp_result res; + + /* Shortcut when denominators are already common */ + if (mp_int_compare(MP_DENOM_P(a), MP_DENOM_P(b)) == 0) { + if ((res = (comb_f)(MP_NUMER_P(a), MP_NUMER_P(b), MP_NUMER_P(c))) != + MP_OK) { + return res; + } + if ((res = mp_int_copy(MP_DENOM_P(a), MP_DENOM_P(c))) != MP_OK) { + return res; + } + + return s_rat_reduce(c); + } else { + mpz_t temp[2]; + int last = 0; + + SETUP(mp_int_init_copy(TEMP(last), MP_NUMER_P(a)), last); + SETUP(mp_int_init_copy(TEMP(last), MP_NUMER_P(b)), last); + + if ((res = mp_int_mul(TEMP(0), MP_DENOM_P(b), TEMP(0))) != MP_OK) { + goto CLEANUP; + } + if ((res = mp_int_mul(TEMP(1), MP_DENOM_P(a), TEMP(1))) != MP_OK) { + goto CLEANUP; + } + if ((res = (comb_f)(TEMP(0), TEMP(1), MP_NUMER_P(c))) != MP_OK) { + goto CLEANUP; + } + + res = mp_int_mul(MP_DENOM_P(a), MP_DENOM_P(b), MP_DENOM_P(c)); + + CLEANUP: + while (--last >= 0) { + mp_int_clear(TEMP(last)); + } + + if (res == MP_OK) { + return s_rat_reduce(c); + } else { + return res; + } + } +} + +/* Here there be dragons */ diff --git a/external/mit/isl/dist/imath/imrat.h b/external/mit/isl/dist/imath/imrat.h new file mode 100644 index 000000000000..87e167fe772a --- /dev/null +++ b/external/mit/isl/dist/imath/imrat.h @@ -0,0 +1,270 @@ +/* + Name: imrat.h + Purpose: Arbitrary precision rational arithmetic routines. + Author: M. J. Fromberger + + Copyright (C) 2002-2007 Michael J. Fromberger, All Rights Reserved. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +#ifndef IMRAT_H_ +#define IMRAT_H_ + +#include + +#include "imath.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + mpz_t num; /* Numerator */ + mpz_t den; /* Denominator, <> 0 */ +} mpq_t, *mp_rat; + +/* Return a pointer to the numerator. */ +static inline mp_int MP_NUMER_P(mp_rat Q) { return &(Q->num); } + +/* Return a pointer to the denominator. */ +static inline mp_int MP_DENOM_P(mp_rat Q) { return &(Q->den); } + +/* Rounding constants */ +typedef enum { + MP_ROUND_DOWN, + MP_ROUND_HALF_UP, + MP_ROUND_UP, + MP_ROUND_HALF_DOWN +} mp_round_mode; + +/** Initializes `r` with 1-digit precision and sets it to zero. This function + cannot fail unless `r` is NULL. */ +mp_result mp_rat_init(mp_rat r); + +/** Allocates a fresh zero-valued `mpq_t` on the heap, returning NULL in case + of error. The only possible error is out-of-memory. */ +mp_rat mp_rat_alloc(void); + +/** Reduces `r` in-place to lowest terms and canonical form. + + Zero is represented as 0/1, one as 1/1, and signs are adjusted so that the + sign of the value is carried by the numerator. */ +mp_result mp_rat_reduce(mp_rat r); + +/** Initializes `r` with at least `n_prec` digits of storage for the numerator + and `d_prec` digits of storage for the denominator, and value zero. + + If either precision is zero, the default precision is used, rounded up to + the nearest word size. */ +mp_result mp_rat_init_size(mp_rat r, mp_size n_prec, mp_size d_prec); + +/** Initializes `r` to be a copy of an already-initialized value in `old`. The + new copy does not share storage with the original. */ +mp_result mp_rat_init_copy(mp_rat r, mp_rat old); + +/** Sets the value of `r` to the ratio of signed `numer` to signed `denom`. It + returns `MP_UNDEF` if `denom` is zero. */ +mp_result mp_rat_set_value(mp_rat r, mp_small numer, mp_small denom); + +/** Sets the value of `r` to the ratio of unsigned `numer` to unsigned + `denom`. It returns `MP_UNDEF` if `denom` is zero. */ +mp_result mp_rat_set_uvalue(mp_rat r, mp_usmall numer, mp_usmall denom); + +/** Releases the storage used by `r`. */ +void mp_rat_clear(mp_rat r); + +/** Releases the storage used by `r` and also `r` itself. + This should only be used for `r` allocated by `mp_rat_alloc()`. */ +void mp_rat_free(mp_rat r); + +/** Sets `z` to a copy of the numerator of `r`. */ +mp_result mp_rat_numer(mp_rat r, mp_int z); + +/** Returns a pointer to the numerator of `r`. */ +mp_int mp_rat_numer_ref(mp_rat r); + +/** Sets `z` to a copy of the denominator of `r`. */ +mp_result mp_rat_denom(mp_rat r, mp_int z); + +/** Returns a pointer to the denominator of `r`. */ +mp_int mp_rat_denom_ref(mp_rat r); + +/** Reports the sign of `r`. */ +mp_sign mp_rat_sign(mp_rat r); + +/** Sets `c` to a copy of the value of `a`. No new memory is allocated unless a + term of `a` has more significant digits than the corresponding term of `c` + has allocated. */ +mp_result mp_rat_copy(mp_rat a, mp_rat c); + +/** Sets `r` to zero. The allocated storage of `r` is not changed. */ +void mp_rat_zero(mp_rat r); + +/** Sets `c` to the absolute value of `a`. */ +mp_result mp_rat_abs(mp_rat a, mp_rat c); + +/** Sets `c` to the absolute value of `a`. */ +mp_result mp_rat_neg(mp_rat a, mp_rat c); + +/** Sets `c` to the reciprocal of `a` if the reciprocal is defined. + It returns `MP_UNDEF` if `a` is zero. */ +mp_result mp_rat_recip(mp_rat a, mp_rat c); + +/** Sets `c` to the sum of `a` and `b`. */ +mp_result mp_rat_add(mp_rat a, mp_rat b, mp_rat c); + +/** Sets `c` to the difference of `a` less `b`. */ +mp_result mp_rat_sub(mp_rat a, mp_rat b, mp_rat c); + +/** Sets `c` to the product of `a` and `b`. */ +mp_result mp_rat_mul(mp_rat a, mp_rat b, mp_rat c); + +/** Sets `c` to the ratio `a / b` if that ratio is defined. + It returns `MP_UNDEF` if `b` is zero. */ +mp_result mp_rat_div(mp_rat a, mp_rat b, mp_rat c); + +/** Sets `c` to the sum of `a` and integer `b`. */ +mp_result mp_rat_add_int(mp_rat a, mp_int b, mp_rat c); + +/** Sets `c` to the difference of `a` less integer `b`. */ +mp_result mp_rat_sub_int(mp_rat a, mp_int b, mp_rat c); + +/** Sets `c` to the product of `a` and integer `b`. */ +mp_result mp_rat_mul_int(mp_rat a, mp_int b, mp_rat c); + +/** Sets `c` to the ratio `a / b` if that ratio is defined. + It returns `MP_UNDEF` if `b` is zero. */ +mp_result mp_rat_div_int(mp_rat a, mp_int b, mp_rat c); + +/** Sets `c` to the value of `a` raised to the `b` power. + It returns `MP_RANGE` if `b < 0`. */ +mp_result mp_rat_expt(mp_rat a, mp_small b, mp_rat c); + +/** Returns the comparator of `a` and `b`. */ +int mp_rat_compare(mp_rat a, mp_rat b); + +/** Returns the comparator of the magnitudes of `a` and `b`, disregarding their + signs. Neither `a` nor `b` is modified by the comparison. */ +int mp_rat_compare_unsigned(mp_rat a, mp_rat b); + +/** Returns the comparator of `r` and zero. */ +int mp_rat_compare_zero(mp_rat r); + +/** Returns the comparator of `r` and the signed ratio `n / d`. + It returns `MP_UNDEF` if `d` is zero. */ +int mp_rat_compare_value(mp_rat r, mp_small n, mp_small d); + +/** Reports whether `r` is an integer, having canonical denominator 1. */ +bool mp_rat_is_integer(mp_rat r); + +/** Reports whether the numerator and denominator of `r` can be represented as + small signed integers, and if so stores the corresponding values to `num` + and `den`. It returns `MP_RANGE` if either cannot be so represented. */ +mp_result mp_rat_to_ints(mp_rat r, mp_small *num, mp_small *den); + +/** Converts `r` to a zero-terminated string of the format `"n/d"` with `n` and + `d` in the specified radix and writing no more than `limit` bytes to the + given output buffer `str`. The output of the numerator includes a sign flag + if `r` is negative. Requires `MP_MIN_RADIX <= radix <= MP_MAX_RADIX`. */ +mp_result mp_rat_to_string(mp_rat r, mp_size radix, char *str, int limit); + +/** Converts the value of `r` to a string in decimal-point notation with the + specified radix, writing no more than `limit` bytes of data to the given + output buffer. It generates `prec` digits of precision, and requires + `MP_MIN_RADIX <= radix <= MP_MAX_RADIX`. + + Ratios usually must be rounded when they are being converted for output as + a decimal value. There are four rounding modes currently supported: + + MP_ROUND_DOWN + Truncates the value toward zero. + Example: 12.009 to 2dp becomes 12.00 + + MP_ROUND_UP + Rounds the value away from zero: + Example: 12.001 to 2dp becomes 12.01, but + 12.000 to 2dp remains 12.00 + + MP_ROUND_HALF_DOWN + Rounds the value to nearest digit, half goes toward zero. + Example: 12.005 to 2dp becomes 12.00, but + 12.006 to 2dp becomes 12.01 + + MP_ROUND_HALF_UP + Rounds the value to nearest digit, half rounds upward. + Example: 12.005 to 2dp becomes 12.01, but + 12.004 to 2dp becomes 12.00 +*/ +mp_result mp_rat_to_decimal(mp_rat r, mp_size radix, mp_size prec, + mp_round_mode round, char *str, int limit); + +/** Reports the minimum number of characters required to represent `r` as a + zero-terminated string in the given `radix`. + Requires `MP_MIN_RADIX <= radix <= MP_MAX_RADIX`. */ +mp_result mp_rat_string_len(mp_rat r, mp_size radix); + +/** Reports the length in bytes of the buffer needed to convert `r` using the + `mp_rat_to_decimal()` function with the specified `radix` and `prec`. The + buffer size estimate may slightly exceed the actual required capacity. */ +mp_result mp_rat_decimal_len(mp_rat r, mp_size radix, mp_size prec); + +/** Sets `r` to the value represented by a zero-terminated string `str` in the + format `"n/d"` including a sign flag. It returns `MP_UNDEF` if the encoded + denominator has value zero. */ +mp_result mp_rat_read_string(mp_rat r, mp_size radix, const char *str); + +/** Sets `r` to the value represented by a zero-terminated string `str` in the + format `"n/d"` including a sign flag. It returns `MP_UNDEF` if the encoded + denominator has value zero. If `end` is not NULL then `*end` is set to + point to the first unconsumed character in the string, after parsing. +*/ +mp_result mp_rat_read_cstring(mp_rat r, mp_size radix, const char *str, + char **end); + +/** Sets `r` to the value represented by a zero-terminated string `str` having + one of the following formats, each with an optional leading sign flag: + + n : integer format, e.g. "123" + n/d : ratio format, e.g., "-12/5" + z.ffff : decimal format, e.g., "1.627" + + It returns `MP_UNDEF` if the effective denominator is zero. If `end` is not + NULL then `*end` is set to point to the first unconsumed character in the + string, after parsing. +*/ +mp_result mp_rat_read_ustring(mp_rat r, mp_size radix, const char *str, + char **end); + +/** Sets `r` to the value represented by a zero-terminated string `str` in the + format `"z.ffff"` including a sign flag. It returns `MP_UNDEF` if the + effective denominator. */ +mp_result mp_rat_read_decimal(mp_rat r, mp_size radix, const char *str); + +/** Sets `r` to the value represented by a zero-terminated string `str` in the + format `"z.ffff"` including a sign flag. It returns `MP_UNDEF` if the + effective denominator. If `end` is not NULL then `*end` is set to point to + the first unconsumed character in the string, after parsing. */ +mp_result mp_rat_read_cdecimal(mp_rat r, mp_size radix, const char *str, + char **end); + +#ifdef __cplusplus +} +#endif +#endif /* IMRAT_H_ */ diff --git a/external/mit/isl/dist/imath_wrap/gmp_compat.c b/external/mit/isl/dist/imath_wrap/gmp_compat.c new file mode 100644 index 000000000000..a116913a44cb --- /dev/null +++ b/external/mit/isl/dist/imath_wrap/gmp_compat.c @@ -0,0 +1,2 @@ +#include "wrap.h" +#include "../imath/gmp_compat.c" diff --git a/external/mit/isl/dist/imath_wrap/gmp_compat.h b/external/mit/isl/dist/imath_wrap/gmp_compat.h new file mode 100644 index 000000000000..11a332daf54f --- /dev/null +++ b/external/mit/isl/dist/imath_wrap/gmp_compat.h @@ -0,0 +1,2 @@ +#include "wrap.h" +#include "../imath/gmp_compat.h" diff --git a/external/mit/isl/dist/imath_wrap/imath.c b/external/mit/isl/dist/imath_wrap/imath.c new file mode 100644 index 000000000000..c4e35c1ac8bb --- /dev/null +++ b/external/mit/isl/dist/imath_wrap/imath.c @@ -0,0 +1,2 @@ +#include "wrap.h" +#include "../imath/imath.c" diff --git a/external/mit/isl/dist/imath_wrap/imath.h b/external/mit/isl/dist/imath_wrap/imath.h new file mode 100644 index 000000000000..12029ce5b675 --- /dev/null +++ b/external/mit/isl/dist/imath_wrap/imath.h @@ -0,0 +1,2 @@ +#include "wrap.h" +#include "../imath/imath.h" diff --git a/external/mit/isl/dist/imath_wrap/imrat.c b/external/mit/isl/dist/imath_wrap/imrat.c new file mode 100644 index 000000000000..0c7feaaeadb3 --- /dev/null +++ b/external/mit/isl/dist/imath_wrap/imrat.c @@ -0,0 +1,2 @@ +#include "wrap.h" +#include "../imath/imrat.c" diff --git a/external/mit/isl/dist/imath_wrap/imrat.h b/external/mit/isl/dist/imath_wrap/imrat.h new file mode 100644 index 000000000000..c9983900a454 --- /dev/null +++ b/external/mit/isl/dist/imath_wrap/imrat.h @@ -0,0 +1,2 @@ +#include "wrap.h" +#include "../imath/imrat.h" diff --git a/external/mit/isl/dist/imath_wrap/wrap.h b/external/mit/isl/dist/imath_wrap/wrap.h new file mode 100644 index 000000000000..a2ea88f85002 --- /dev/null +++ b/external/mit/isl/dist/imath_wrap/wrap.h @@ -0,0 +1,171 @@ +#ifndef ISL_IMATH_WRAP +#define ISL_IMATH_WRAP + +#define MP_BADARG ISL_MP_BADARG +#define MP_FALSE ISL_MP_FALSE +#define MP_MEMORY ISL_MP_MEMORY +#define MP_MINERR ISL_MP_MINERR +#define MP_NEG ISL_MP_NEG +#define MP_OK ISL_MP_OK +#define MP_RANGE ISL_MP_RANGE +#define MP_TRUE ISL_MP_TRUE +#define MP_TRUNC ISL_MP_TRUNC +#define MP_UNDEF ISL_MP_UNDEF +#define MP_ZPOS ISL_MP_ZPOS + +#define impq_canonicalize isl_impq_canonicalize +#define impq_clear isl_impq_clear +#define impq_cmp isl_impq_cmp +#define impq_denref isl_impq_denref +#define impq_get_str isl_impq_get_str +#define impq_init isl_impq_init +#define impq_mul isl_impq_mul +#define impq_numref isl_impq_numref +#define impq_set isl_impq_set +#define impq_set_str isl_impq_set_str +#define impq_set_ui isl_impq_set_ui +#define impq_sgn isl_impq_sgn +#define impz_abs isl_impz_abs +#define impz_add isl_impz_add +#define impz_addmul isl_impz_addmul +#define impz_add_ui isl_impz_add_ui +#define impz_cdiv_q isl_impz_cdiv_q +#define impz_clear isl_impz_clear +#define impz_cmp isl_impz_cmp +#define impz_cmpabs isl_impz_cmpabs +#define impz_cmp_si isl_impz_cmp_si +#define impz_divexact isl_impz_divexact +#define impz_divexact_ui isl_impz_divexact_ui +#define impz_divisible_p isl_impz_divisible_p +#define impz_export isl_impz_export +#define impz_fdiv_q isl_impz_fdiv_q +#define impz_fdiv_r isl_impz_fdiv_r +#define impz_gcd isl_impz_gcd +#define impz_get_si isl_impz_get_si +#define impz_get_str isl_impz_get_str +#define impz_get_ui isl_impz_get_ui +#define impz_import isl_impz_import +#define impz_init isl_impz_init +#define impz_lcm isl_impz_lcm +#define impz_mul isl_impz_mul +#define impz_mul_2exp isl_impz_mul_2exp +#define impz_mul_ui isl_impz_mul_ui +#define impz_neg isl_impz_neg +#define impz_pow_ui isl_impz_pow_ui +#define impz_set isl_impz_set +#define impz_set_si isl_impz_set_si +#define impz_set_str isl_impz_set_str +#define impz_set_ui isl_impz_set_ui +#define impz_sgn isl_impz_sgn +#define impz_sizeinbase isl_impz_sizeinbase +#define impz_sub isl_impz_sub +#define impz_submul isl_impz_submul +#define impz_sub_ui isl_impz_sub_ui +#define impz_swap isl_impz_swap +#define impz_tdiv_q isl_impz_tdiv_q +#define mp_error_string isl_mp_error_string +#define mp_int_abs isl_mp_int_abs +#define mp_int_add isl_mp_int_add +#define mp_int_add_value isl_mp_int_add_value +#define mp_int_alloc isl_mp_int_alloc +#define mp_int_binary_len isl_mp_int_binary_len +#define mp_int_clear isl_mp_int_clear +#define mp_int_compare isl_mp_int_compare +#define mp_int_compare_unsigned isl_mp_int_compare_unsigned +#define mp_int_compare_uvalue isl_mp_int_compare_uvalue +#define mp_int_compare_value isl_mp_int_compare_value +#define mp_int_compare_zero isl_mp_int_compare_zero +#define mp_int_copy isl_mp_int_copy +#define mp_int_count_bits isl_mp_int_count_bits +#define mp_int_div isl_mp_int_div +#define mp_int_divisible_value isl_mp_int_divisible_value +#define mp_int_div_pow2 isl_mp_int_div_pow2 +#define mp_int_div_value isl_mp_int_div_value +#define mp_int_egcd isl_mp_int_egcd +#define mp_int_expt isl_mp_int_expt +#define mp_int_expt_full isl_mp_int_expt_full +#define mp_int_exptmod isl_mp_int_exptmod +#define mp_int_exptmod_bvalue isl_mp_int_exptmod_bvalue +#define mp_int_exptmod_evalue isl_mp_int_exptmod_evalue +#define mp_int_exptmod_known isl_mp_int_exptmod_known +#define mp_int_expt_value isl_mp_int_expt_value +#define mp_int_free isl_mp_int_free +#define mp_int_gcd isl_mp_int_gcd +#define mp_int_init isl_mp_int_init +#define mp_int_init_copy isl_mp_int_init_copy +#define mp_int_init_size isl_mp_int_init_size +#define mp_int_init_uvalue isl_mp_int_init_uvalue +#define mp_int_init_value isl_mp_int_init_value +#define mp_int_invmod isl_mp_int_invmod +#define mp_int_is_pow2 isl_mp_int_is_pow2 +#define mp_int_lcm isl_mp_int_lcm +#define mp_int_mod isl_mp_int_mod +#define mp_int_mul isl_mp_int_mul +#define mp_int_mul_pow2 isl_mp_int_mul_pow2 +#define mp_int_mul_value isl_mp_int_mul_value +#define mp_int_neg isl_mp_int_neg +#define mp_int_read_binary isl_mp_int_read_binary +#define mp_int_read_cstring isl_mp_int_read_cstring +#define mp_int_read_string isl_mp_int_read_string +#define mp_int_read_unsigned isl_mp_int_read_unsigned +#define mp_int_redux_const isl_mp_int_redux_const +#define mp_int_root isl_mp_int_root +#define mp_int_set_uvalue isl_mp_int_set_uvalue +#define mp_int_set_value isl_mp_int_set_value +#define mp_int_sqr isl_mp_int_sqr +#define mp_int_string_len isl_mp_int_string_len +#define mp_int_sub isl_mp_int_sub +#define mp_int_sub_value isl_mp_int_sub_value +#define mp_int_swap isl_mp_int_swap +#define mp_int_to_binary isl_mp_int_to_binary +#define mp_int_to_int isl_mp_int_to_int +#define mp_int_to_string isl_mp_int_to_string +#define mp_int_to_uint isl_mp_int_to_uint +#define mp_int_to_unsigned isl_mp_int_to_unsigned +#define mp_int_unsigned_len isl_mp_int_unsigned_len +#define mp_int_zero isl_mp_int_zero +#define mp_rat_abs isl_mp_rat_abs +#define mp_rat_add isl_mp_rat_add +#define mp_rat_add_int isl_mp_rat_add_int +#define mp_rat_alloc isl_mp_rat_alloc +#define mp_rat_clear isl_mp_rat_clear +#define mp_rat_compare isl_mp_rat_compare +#define mp_rat_compare_unsigned isl_mp_rat_compare_unsigned +#define mp_rat_compare_value isl_mp_rat_compare_value +#define mp_rat_compare_zero isl_mp_rat_compare_zero +#define mp_rat_copy isl_mp_rat_copy +#define mp_rat_decimal_len isl_mp_rat_decimal_len +#define mp_rat_denom isl_mp_rat_denom +#define mp_rat_denom_ref isl_mp_rat_denom_ref +#define mp_rat_div isl_mp_rat_div +#define mp_rat_div_int isl_mp_rat_div_int +#define mp_rat_expt isl_mp_rat_expt +#define mp_rat_free isl_mp_rat_free +#define mp_rat_init isl_mp_rat_init +#define mp_rat_init_copy isl_mp_rat_init_copy +#define mp_rat_init_size isl_mp_rat_init_size +#define mp_rat_is_integer isl_mp_rat_is_integer +#define mp_rat_mul isl_mp_rat_mul +#define mp_rat_mul_int isl_mp_rat_mul_int +#define mp_rat_neg isl_mp_rat_neg +#define mp_rat_numer isl_mp_rat_numer +#define mp_rat_numer_ref isl_mp_rat_numer_ref +#define mp_rat_read_cdecimal isl_mp_rat_read_cdecimal +#define mp_rat_read_cstring isl_mp_rat_read_cstring +#define mp_rat_read_decimal isl_mp_rat_read_decimal +#define mp_rat_read_string isl_mp_rat_read_string +#define mp_rat_read_ustring isl_mp_rat_read_ustring +#define mp_rat_recip isl_mp_rat_recip +#define mp_rat_reduce isl_mp_rat_reduce +#define mp_rat_set_uvalue isl_mp_rat_set_uvalue +#define mp_rat_set_value isl_mp_rat_set_value +#define mp_rat_sign isl_mp_rat_sign +#define mp_rat_string_len isl_mp_rat_string_len +#define mp_rat_sub isl_mp_rat_sub +#define mp_rat_sub_int isl_mp_rat_sub_int +#define mp_rat_to_decimal isl_mp_rat_to_decimal +#define mp_rat_to_ints isl_mp_rat_to_ints +#define mp_rat_to_string isl_mp_rat_to_string +#define mp_rat_zero isl_mp_rat_zero + +#endif diff --git a/external/mit/isl/dist/include/isl/aff.h b/external/mit/isl/dist/include/isl/aff.h new file mode 100644 index 000000000000..a95a8db7dd63 --- /dev/null +++ b/external/mit/isl/dist/include/isl/aff.h @@ -0,0 +1,1516 @@ +#ifndef ISL_AFF_H +#define ISL_AFF_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +__isl_overload +__isl_give isl_aff *isl_aff_zero_on_domain_space(__isl_take isl_space *space); +__isl_export +__isl_give isl_aff *isl_space_zero_aff_on_domain(__isl_take isl_space *space); +__isl_give isl_aff *isl_aff_zero_on_domain(__isl_take isl_local_space *ls); +__isl_give isl_aff *isl_aff_val_on_domain_space(__isl_take isl_space *space, + __isl_take isl_val *val); +__isl_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_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_space(__isl_take isl_space *space); +__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_overload +__isl_give isl_aff *isl_space_param_aff_on_domain_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); + +isl_ctx *isl_aff_get_ctx(__isl_keep isl_aff *aff); +uint32_t isl_aff_get_hash(__isl_keep isl_aff *aff); + +isl_bool isl_aff_involves_locals(__isl_keep isl_aff *aff); + +isl_size isl_aff_dim(__isl_keep isl_aff *aff, enum isl_dim_type type); +isl_bool isl_aff_involves_dims(__isl_keep isl_aff *aff, + enum isl_dim_type type, unsigned first, unsigned n); + +__isl_give isl_space *isl_aff_get_domain_space(__isl_keep isl_aff *aff); +__isl_give isl_space *isl_aff_get_space(__isl_keep isl_aff *aff); +__isl_give isl_local_space *isl_aff_get_domain_local_space( + __isl_keep isl_aff *aff); +__isl_give isl_local_space *isl_aff_get_local_space(__isl_keep isl_aff *aff); + +const char *isl_aff_get_dim_name(__isl_keep isl_aff *aff, + enum isl_dim_type type, unsigned pos); +__isl_export +__isl_give isl_val *isl_aff_get_constant_val(__isl_keep isl_aff *aff); +__isl_give isl_val *isl_aff_get_coefficient_val(__isl_keep isl_aff *aff, + enum isl_dim_type type, int pos); +int isl_aff_coefficient_sgn(__isl_keep isl_aff *aff, + enum isl_dim_type type, int pos); +__isl_give isl_val *isl_aff_get_denominator_val(__isl_keep isl_aff *aff); +__isl_give isl_aff *isl_aff_set_constant_si(__isl_take isl_aff *aff, int v); +__isl_give isl_aff *isl_aff_set_constant_val(__isl_take isl_aff *aff, + __isl_take isl_val *v); +__isl_give isl_aff *isl_aff_set_coefficient_si(__isl_take isl_aff *aff, + enum isl_dim_type type, int pos, int v); +__isl_give isl_aff *isl_aff_set_coefficient_val(__isl_take isl_aff *aff, + enum isl_dim_type type, int pos, __isl_take isl_val *v); +__isl_give isl_aff *isl_aff_add_constant_si(__isl_take isl_aff *aff, int v); +__isl_overload +__isl_give isl_aff *isl_aff_add_constant_val(__isl_take isl_aff *aff, + __isl_take isl_val *v); +__isl_give isl_aff *isl_aff_add_constant_num_si(__isl_take isl_aff *aff, int v); +__isl_give isl_aff *isl_aff_add_coefficient_si(__isl_take isl_aff *aff, + enum isl_dim_type type, int pos, int v); +__isl_give isl_aff *isl_aff_add_coefficient_val(__isl_take isl_aff *aff, + enum isl_dim_type type, int pos, __isl_take isl_val *v); + +__isl_export +isl_bool isl_aff_is_cst(__isl_keep isl_aff *aff); + +__isl_give isl_aff *isl_aff_set_tuple_id(__isl_take isl_aff *aff, + enum isl_dim_type type, __isl_take isl_id *id); +__isl_give isl_aff *isl_aff_set_dim_name(__isl_take isl_aff *aff, + enum isl_dim_type type, unsigned pos, const char *s); +__isl_give isl_aff *isl_aff_set_dim_id(__isl_take isl_aff *aff, + enum isl_dim_type type, unsigned pos, __isl_take isl_id *id); + +int isl_aff_find_dim_by_name(__isl_keep isl_aff *aff, enum isl_dim_type type, + const char *name); + +__isl_export +isl_bool isl_aff_plain_is_equal(__isl_keep isl_aff *aff1, + __isl_keep isl_aff *aff2); +isl_bool isl_aff_plain_is_zero(__isl_keep isl_aff *aff); +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 +__isl_give isl_aff *isl_aff_ceil(__isl_take isl_aff *aff); +__isl_export +__isl_give isl_aff *isl_aff_floor(__isl_take isl_aff *aff); +__isl_overload +__isl_give isl_aff *isl_aff_mod_val(__isl_take isl_aff *aff, + __isl_take isl_val *mod); + +__isl_export +__isl_give isl_aff *isl_aff_mul(__isl_take isl_aff *aff1, + __isl_take isl_aff *aff2); +__isl_export +__isl_give isl_aff *isl_aff_div(__isl_take isl_aff *aff1, + __isl_take isl_aff *aff2); +__isl_export +__isl_give isl_aff *isl_aff_add(__isl_take isl_aff *aff1, + __isl_take isl_aff *aff2); +__isl_export +__isl_give isl_aff *isl_aff_sub(__isl_take isl_aff *aff1, + __isl_take isl_aff *aff2); + +__isl_overload +__isl_give isl_aff *isl_aff_scale_val(__isl_take isl_aff *aff, + __isl_take isl_val *v); +__isl_give isl_aff *isl_aff_scale_down_ui(__isl_take isl_aff *aff, unsigned f); +__isl_overload +__isl_give isl_aff *isl_aff_scale_down_val(__isl_take isl_aff *aff, + __isl_take isl_val *v); + +__isl_export +__isl_give isl_aff *isl_aff_domain_reverse(__isl_take isl_aff *aff); +__isl_give isl_aff *isl_aff_insert_dims(__isl_take isl_aff *aff, + enum isl_dim_type type, unsigned first, unsigned n); +__isl_give isl_aff *isl_aff_add_dims(__isl_take isl_aff *aff, + enum isl_dim_type type, unsigned n); +__isl_give isl_aff *isl_aff_move_dims(__isl_take isl_aff *aff, + enum isl_dim_type dst_type, unsigned dst_pos, + enum isl_dim_type src_type, unsigned src_pos, unsigned n); +__isl_give isl_aff *isl_aff_drop_dims(__isl_take isl_aff *aff, + enum isl_dim_type type, unsigned first, unsigned n); +__isl_give isl_aff *isl_aff_project_domain_on_params(__isl_take isl_aff *aff); +__isl_export +__isl_give isl_aff *isl_aff_unbind_params_insert_domain( + __isl_take isl_aff *aff, __isl_take isl_multi_id *domain); + +__isl_give isl_aff *isl_aff_align_params(__isl_take isl_aff *aff, + __isl_take isl_space *model); + +__isl_export +__isl_give isl_aff *isl_aff_gist(__isl_take isl_aff *aff, + __isl_take isl_set *context); +__isl_export +__isl_give isl_aff *isl_aff_gist_params(__isl_take isl_aff *aff, + __isl_take isl_set *context); + +__isl_export +__isl_give isl_val *isl_aff_eval(__isl_take isl_aff *aff, + __isl_take isl_point *pnt); + +__isl_give isl_aff *isl_aff_pullback_aff(__isl_take isl_aff *aff1, + __isl_take isl_aff *aff2); +__isl_overload +__isl_give isl_aff *isl_aff_pullback_multi_aff(__isl_take isl_aff *aff, + __isl_take isl_multi_aff *ma); + +__isl_give isl_basic_set *isl_aff_zero_basic_set(__isl_take isl_aff *aff); +__isl_give isl_basic_set *isl_aff_neg_basic_set(__isl_take isl_aff *aff); + +__isl_give isl_basic_set *isl_aff_eq_basic_set(__isl_take isl_aff *aff1, + __isl_take isl_aff *aff2); +__isl_export +__isl_give isl_set *isl_aff_eq_set(__isl_take isl_aff *aff1, + __isl_take isl_aff *aff2); +__isl_export +__isl_give isl_set *isl_aff_ne_set(__isl_take isl_aff *aff1, + __isl_take isl_aff *aff2); +__isl_give isl_basic_set *isl_aff_le_basic_set(__isl_take isl_aff *aff1, + __isl_take isl_aff *aff2); +__isl_export +__isl_give isl_set *isl_aff_le_set(__isl_take isl_aff *aff1, + __isl_take isl_aff *aff2); +__isl_give isl_basic_set *isl_aff_lt_basic_set(__isl_take isl_aff *aff1, + __isl_take isl_aff *aff2); +__isl_export +__isl_give isl_set *isl_aff_lt_set(__isl_take isl_aff *aff1, + __isl_take isl_aff *aff2); +__isl_give isl_basic_set *isl_aff_ge_basic_set(__isl_take isl_aff *aff1, + __isl_take isl_aff *aff2); +__isl_export +__isl_give isl_set *isl_aff_ge_set(__isl_take isl_aff *aff1, + __isl_take isl_aff *aff2); +__isl_give isl_basic_set *isl_aff_gt_basic_set(__isl_take isl_aff *aff1, + __isl_take isl_aff *aff2); +__isl_export +__isl_give isl_set *isl_aff_gt_set(__isl_take isl_aff *aff1, + __isl_take isl_aff *aff2); + +__isl_overload +__isl_give isl_basic_set *isl_aff_bind_id(__isl_take isl_aff *aff, + __isl_take isl_id *id); + +__isl_constructor +__isl_give isl_aff *isl_aff_read_from_str(isl_ctx *ctx, const char *str); +__isl_give char *isl_aff_to_str(__isl_keep isl_aff *aff); +__isl_give isl_printer *isl_printer_print_aff(__isl_take isl_printer *p, + __isl_keep isl_aff *aff); +void isl_aff_dump(__isl_keep isl_aff *aff); + +isl_ctx *isl_pw_aff_get_ctx(__isl_keep isl_pw_aff *pwaff); +uint32_t isl_pw_aff_get_hash(__isl_keep isl_pw_aff *pa); +__isl_give isl_space *isl_pw_aff_get_domain_space(__isl_keep isl_pw_aff *pwaff); +__isl_export +__isl_give isl_space *isl_pw_aff_get_space(__isl_keep isl_pw_aff *pwaff); + +__isl_constructor +__isl_give isl_pw_aff *isl_pw_aff_from_aff(__isl_take isl_aff *aff); +__isl_give isl_pw_aff *isl_pw_aff_empty(__isl_take isl_space *space); +__isl_give isl_pw_aff *isl_pw_aff_alloc(__isl_take isl_set *set, + __isl_take isl_aff *aff); +__isl_give isl_pw_aff *isl_pw_aff_zero_on_domain( + __isl_take isl_local_space *ls); +__isl_give isl_pw_aff *isl_pw_aff_var_on_domain(__isl_take isl_local_space *ls, + enum isl_dim_type type, unsigned pos); +__isl_give isl_pw_aff *isl_pw_aff_nan_on_domain_space( + __isl_take isl_space *space); +__isl_give isl_pw_aff *isl_pw_aff_nan_on_domain(__isl_take isl_local_space *ls); +__isl_give isl_pw_aff *isl_pw_aff_val_on_domain(__isl_take isl_set *domain, + __isl_take isl_val *v); +__isl_overload +__isl_give isl_pw_aff *isl_set_pw_aff_on_domain_val(__isl_take isl_set *domain, + __isl_take isl_val *v); +__isl_overload +__isl_give isl_pw_aff *isl_pw_aff_param_on_domain_id( + __isl_take isl_set *domain, __isl_take isl_id *id); +__isl_overload +__isl_give isl_pw_aff *isl_set_param_pw_aff_on_domain_id( + __isl_take isl_set *domain, __isl_take isl_id *id); + +__isl_export +__isl_give isl_pw_aff *isl_set_indicator_function(__isl_take isl_set *set); + +const char *isl_pw_aff_get_dim_name(__isl_keep isl_pw_aff *pa, + enum isl_dim_type type, unsigned pos); +isl_bool isl_pw_aff_has_dim_id(__isl_keep isl_pw_aff *pa, + enum isl_dim_type type, unsigned pos); +__isl_give isl_id *isl_pw_aff_get_dim_id(__isl_keep isl_pw_aff *pa, + enum isl_dim_type type, unsigned pos); +__isl_give isl_pw_aff *isl_pw_aff_set_dim_id(__isl_take isl_pw_aff *pma, + enum isl_dim_type type, unsigned pos, __isl_take isl_id *id); + +int isl_pw_aff_find_dim_by_name(__isl_keep isl_pw_aff *pa, + enum isl_dim_type type, const char *name); + +isl_bool isl_pw_aff_is_empty(__isl_keep isl_pw_aff *pwaff); +isl_bool isl_pw_aff_involves_nan(__isl_keep isl_pw_aff *pa); +int isl_pw_aff_plain_cmp(__isl_keep isl_pw_aff *pa1, + __isl_keep isl_pw_aff *pa2); +__isl_export +isl_bool isl_pw_aff_plain_is_equal(__isl_keep isl_pw_aff *pwaff1, + __isl_keep isl_pw_aff *pwaff2); +isl_bool isl_pw_aff_is_equal(__isl_keep isl_pw_aff *pa1, + __isl_keep isl_pw_aff *pa2); + +__isl_give isl_pw_aff *isl_pw_aff_union_min(__isl_take isl_pw_aff *pwaff1, + __isl_take isl_pw_aff *pwaff2); +__isl_give isl_pw_aff *isl_pw_aff_union_max(__isl_take isl_pw_aff *pwaff1, + __isl_take isl_pw_aff *pwaff2); +__isl_export +__isl_give isl_pw_aff *isl_pw_aff_union_add(__isl_take isl_pw_aff *pwaff1, + __isl_take isl_pw_aff *pwaff2); + +__isl_give isl_pw_aff *isl_pw_aff_copy(__isl_keep isl_pw_aff *pwaff); +__isl_null isl_pw_aff *isl_pw_aff_free(__isl_take isl_pw_aff *pwaff); + +isl_size isl_pw_aff_dim(__isl_keep isl_pw_aff *pwaff, enum isl_dim_type type); +isl_bool isl_pw_aff_involves_param_id(__isl_keep isl_pw_aff *pa, + __isl_keep isl_id *id); +isl_bool isl_pw_aff_involves_dims(__isl_keep isl_pw_aff *pwaff, + enum isl_dim_type type, unsigned first, unsigned n); + +isl_bool isl_pw_aff_is_cst(__isl_keep isl_pw_aff *pwaff); + +__isl_export +__isl_give isl_pw_aff *isl_pw_aff_insert_domain(__isl_take isl_pw_aff *pa, + __isl_take isl_space *domain); +__isl_give isl_pw_aff *isl_pw_aff_project_domain_on_params( + __isl_take isl_pw_aff *pa); + +__isl_give isl_pw_aff *isl_pw_aff_align_params(__isl_take isl_pw_aff *pwaff, + __isl_take isl_space *model); +__isl_export +__isl_give isl_pw_aff *isl_pw_aff_drop_unused_params( + __isl_take isl_pw_aff *pa); + +isl_bool isl_pw_aff_has_tuple_id(__isl_keep isl_pw_aff *pa, + enum isl_dim_type type); +__isl_give isl_id *isl_pw_aff_get_tuple_id(__isl_keep isl_pw_aff *pa, + enum isl_dim_type type); +__isl_give isl_pw_aff *isl_pw_aff_set_tuple_id(__isl_take isl_pw_aff *pwaff, + enum isl_dim_type type, __isl_take isl_id *id); +__isl_give isl_pw_aff *isl_pw_aff_reset_tuple_id(__isl_take isl_pw_aff *pa, + enum isl_dim_type type); +__isl_give isl_pw_aff *isl_pw_aff_reset_user(__isl_take isl_pw_aff *pa); + +__isl_export +__isl_give isl_set *isl_pw_aff_params(__isl_take isl_pw_aff *pwa); +__isl_export +__isl_give isl_set *isl_pw_aff_domain(__isl_take isl_pw_aff *pwaff); +__isl_give isl_pw_aff *isl_pw_aff_from_range(__isl_take isl_pw_aff *pwa); + +__isl_export +__isl_give isl_pw_aff *isl_pw_aff_min(__isl_take isl_pw_aff *pwaff1, + __isl_take isl_pw_aff *pwaff2); +__isl_export +__isl_give isl_pw_aff *isl_pw_aff_max(__isl_take isl_pw_aff *pwaff1, + __isl_take isl_pw_aff *pwaff2); +__isl_export +__isl_give isl_pw_aff *isl_pw_aff_mul(__isl_take isl_pw_aff *pwaff1, + __isl_take isl_pw_aff *pwaff2); +__isl_export +__isl_give isl_pw_aff *isl_pw_aff_div(__isl_take isl_pw_aff *pa1, + __isl_take isl_pw_aff *pa2); +__isl_export +__isl_give isl_pw_aff *isl_pw_aff_add(__isl_take isl_pw_aff *pwaff1, + __isl_take isl_pw_aff *pwaff2); +__isl_export +__isl_give isl_pw_aff *isl_pw_aff_sub(__isl_take isl_pw_aff *pwaff1, + __isl_take isl_pw_aff *pwaff2); +__isl_export +__isl_give isl_pw_aff *isl_pw_aff_neg(__isl_take isl_pw_aff *pwaff); +__isl_export +__isl_give isl_pw_aff *isl_pw_aff_ceil(__isl_take isl_pw_aff *pwaff); +__isl_export +__isl_give isl_pw_aff *isl_pw_aff_floor(__isl_take isl_pw_aff *pwaff); +__isl_overload +__isl_give isl_pw_aff *isl_pw_aff_mod_val(__isl_take isl_pw_aff *pa, + __isl_take isl_val *mod); +__isl_export +__isl_give isl_pw_aff *isl_pw_aff_tdiv_q(__isl_take isl_pw_aff *pa1, + __isl_take isl_pw_aff *pa2); +__isl_export +__isl_give isl_pw_aff *isl_pw_aff_tdiv_r(__isl_take isl_pw_aff *pa1, + __isl_take isl_pw_aff *pa2); + +__isl_export +__isl_give isl_pw_aff *isl_pw_aff_intersect_params(__isl_take isl_pw_aff *pa, + __isl_take isl_set *set); +__isl_export +__isl_give isl_pw_aff *isl_pw_aff_intersect_domain(__isl_take isl_pw_aff *pa, + __isl_take isl_set *set); +__isl_give isl_pw_aff *isl_pw_aff_intersect_domain_wrapped_domain( + __isl_take isl_pw_aff *pa, __isl_take isl_set *set); +__isl_give isl_pw_aff *isl_pw_aff_intersect_domain_wrapped_range( + __isl_take isl_pw_aff *pa, __isl_take isl_set *set); +__isl_export +__isl_give isl_pw_aff *isl_pw_aff_subtract_domain(__isl_take isl_pw_aff *pa, + __isl_take isl_set *set); + +__isl_export +__isl_give isl_pw_aff *isl_pw_aff_cond(__isl_take isl_pw_aff *cond, + __isl_take isl_pw_aff *pwaff_true, __isl_take isl_pw_aff *pwaff_false); + +__isl_overload +__isl_give isl_pw_aff *isl_pw_aff_add_constant_val(__isl_take isl_pw_aff *pa, + __isl_take isl_val *v); +__isl_overload +__isl_give isl_pw_aff *isl_pw_aff_scale_val(__isl_take isl_pw_aff *pa, + __isl_take isl_val *v); +__isl_overload +__isl_give isl_pw_aff *isl_pw_aff_scale_down_val(__isl_take isl_pw_aff *pa, + __isl_take isl_val *f); + +__isl_export +__isl_give isl_pw_aff *isl_pw_aff_domain_reverse(__isl_take isl_pw_aff *pa); +__isl_give isl_pw_aff *isl_pw_aff_insert_dims(__isl_take isl_pw_aff *pwaff, + enum isl_dim_type type, unsigned first, unsigned n); +__isl_give isl_pw_aff *isl_pw_aff_add_dims(__isl_take isl_pw_aff *pwaff, + enum isl_dim_type type, unsigned n); +__isl_give isl_pw_aff *isl_pw_aff_move_dims(__isl_take isl_pw_aff *pa, + enum isl_dim_type dst_type, unsigned dst_pos, + enum isl_dim_type src_type, unsigned src_pos, unsigned n); +__isl_give isl_pw_aff *isl_pw_aff_drop_dims(__isl_take isl_pw_aff *pwaff, + enum isl_dim_type type, unsigned first, unsigned n); + +__isl_export +__isl_give isl_pw_aff *isl_pw_aff_coalesce(__isl_take isl_pw_aff *pa); +__isl_export +__isl_give isl_pw_aff *isl_pw_aff_gist(__isl_take isl_pw_aff *pwaff, + __isl_take isl_set *context); +__isl_export +__isl_give isl_pw_aff *isl_pw_aff_gist_params(__isl_take isl_pw_aff *pwaff, + __isl_take isl_set *context); + +__isl_export +__isl_give isl_val *isl_pw_aff_eval(__isl_take isl_pw_aff *pa, + __isl_take isl_point *pnt); + +__isl_overload +__isl_give isl_pw_aff *isl_pw_aff_pullback_multi_aff( + __isl_take isl_pw_aff *pa, __isl_take isl_multi_aff *ma); +__isl_overload +__isl_give isl_pw_aff *isl_pw_aff_pullback_pw_multi_aff( + __isl_take isl_pw_aff *pa, __isl_take isl_pw_multi_aff *pma); +__isl_overload +__isl_give isl_pw_aff *isl_pw_aff_pullback_multi_pw_aff( + __isl_take isl_pw_aff *pa, __isl_take isl_multi_pw_aff *mpa); + +isl_size isl_pw_aff_n_piece(__isl_keep isl_pw_aff *pwaff); +isl_stat isl_pw_aff_foreach_piece(__isl_keep isl_pw_aff *pwaff, + isl_stat (*fn)(__isl_take isl_set *set, __isl_take isl_aff *aff, + void *user), void *user); +isl_bool isl_pw_aff_every_piece(__isl_keep isl_pw_aff *pa, + isl_bool (*test)(__isl_keep isl_set *set, __isl_keep isl_aff *aff, + void *user), void *user); +__isl_export +isl_bool isl_pw_aff_isa_aff(__isl_keep isl_pw_aff *pa); +__isl_export +__isl_give isl_aff *isl_pw_aff_as_aff(__isl_take isl_pw_aff *pa); + +__isl_export +__isl_give isl_map *isl_pw_aff_as_map(__isl_take isl_pw_aff *pa); +__isl_give isl_set *isl_set_from_pw_aff(__isl_take isl_pw_aff *pwaff); +__isl_give isl_map *isl_map_from_pw_aff(__isl_take isl_pw_aff *pwaff); + +__isl_give isl_set *isl_pw_aff_pos_set(__isl_take isl_pw_aff *pa); +__isl_give isl_set *isl_pw_aff_nonneg_set(__isl_take isl_pw_aff *pwaff); +__isl_give isl_set *isl_pw_aff_zero_set(__isl_take isl_pw_aff *pwaff); +__isl_give isl_set *isl_pw_aff_non_zero_set(__isl_take isl_pw_aff *pwaff); + +__isl_export +__isl_give isl_set *isl_pw_aff_eq_set(__isl_take isl_pw_aff *pwaff1, + __isl_take isl_pw_aff *pwaff2); +__isl_export +__isl_give isl_set *isl_pw_aff_ne_set(__isl_take isl_pw_aff *pwaff1, + __isl_take isl_pw_aff *pwaff2); +__isl_export +__isl_give isl_set *isl_pw_aff_le_set(__isl_take isl_pw_aff *pwaff1, + __isl_take isl_pw_aff *pwaff2); +__isl_export +__isl_give isl_set *isl_pw_aff_lt_set(__isl_take isl_pw_aff *pwaff1, + __isl_take isl_pw_aff *pwaff2); +__isl_export +__isl_give isl_set *isl_pw_aff_ge_set(__isl_take isl_pw_aff *pwaff1, + __isl_take isl_pw_aff *pwaff2); +__isl_export +__isl_give isl_set *isl_pw_aff_gt_set(__isl_take isl_pw_aff *pwaff1, + __isl_take isl_pw_aff *pwaff2); + +__isl_give isl_map *isl_pw_aff_eq_map(__isl_take isl_pw_aff *pa1, + __isl_take isl_pw_aff *pa2); +__isl_give isl_map *isl_pw_aff_le_map(__isl_take isl_pw_aff *pa1, + __isl_take isl_pw_aff *pa2); +__isl_give isl_map *isl_pw_aff_lt_map(__isl_take isl_pw_aff *pa1, + __isl_take isl_pw_aff *pa2); +__isl_give isl_map *isl_pw_aff_ge_map(__isl_take isl_pw_aff *pa1, + __isl_take isl_pw_aff *pa2); +__isl_give isl_map *isl_pw_aff_gt_map(__isl_take isl_pw_aff *pa1, + __isl_take isl_pw_aff *pa2); + +__isl_export +__isl_give isl_pw_aff *isl_pw_aff_bind_domain(__isl_take isl_pw_aff *pa, + __isl_take isl_multi_id *tuple); +__isl_export +__isl_give isl_pw_aff *isl_pw_aff_bind_domain_wrapped_domain( + __isl_take isl_pw_aff *pa, __isl_take isl_multi_id *tuple); +__isl_overload +__isl_give isl_set *isl_pw_aff_bind_id(__isl_take isl_pw_aff *pa, + __isl_take isl_id *id); + +__isl_constructor +__isl_give isl_pw_aff *isl_pw_aff_read_from_str(isl_ctx *ctx, const char *str); +__isl_give char *isl_pw_aff_to_str(__isl_keep isl_pw_aff *pa); +__isl_give isl_printer *isl_printer_print_pw_aff(__isl_take isl_printer *p, + __isl_keep isl_pw_aff *pwaff); +void isl_pw_aff_dump(__isl_keep isl_pw_aff *pwaff); + +__isl_give isl_pw_aff *isl_pw_aff_list_min(__isl_take isl_pw_aff_list *list); +__isl_give isl_pw_aff *isl_pw_aff_list_max(__isl_take isl_pw_aff_list *list); + +__isl_give isl_set *isl_pw_aff_list_eq_set(__isl_take isl_pw_aff_list *list1, + __isl_take isl_pw_aff_list *list2); +__isl_give isl_set *isl_pw_aff_list_ne_set(__isl_take isl_pw_aff_list *list1, + __isl_take isl_pw_aff_list *list2); +__isl_give isl_set *isl_pw_aff_list_le_set(__isl_take isl_pw_aff_list *list1, + __isl_take isl_pw_aff_list *list2); +__isl_give isl_set *isl_pw_aff_list_lt_set(__isl_take isl_pw_aff_list *list1, + __isl_take isl_pw_aff_list *list2); +__isl_give isl_set *isl_pw_aff_list_ge_set(__isl_take isl_pw_aff_list *list1, + __isl_take isl_pw_aff_list *list2); +__isl_give isl_set *isl_pw_aff_list_gt_set(__isl_take isl_pw_aff_list *list1, + __isl_take isl_pw_aff_list *list2); + +ISL_DECLARE_MULTI(aff) +ISL_DECLARE_MULTI_IDENTITY(aff) +ISL_DECLARE_MULTI_CMP(aff) +ISL_DECLARE_MULTI_ARITH(aff) +ISL_DECLARE_MULTI_ADD_CONSTANT(aff) +ISL_DECLARE_MULTI_ZERO(aff) +ISL_DECLARE_MULTI_NAN(aff) +ISL_DECLARE_MULTI_DIMS(aff) +ISL_DECLARE_MULTI_INSERT_DOMAIN(aff) +ISL_DECLARE_MULTI_LOCALS(aff) +ISL_DECLARE_MULTI_DIM_ID(aff) +ISL_DECLARE_MULTI_TUPLE_ID(aff) +ISL_DECLARE_MULTI_WITH_DOMAIN(aff) +ISL_DECLARE_MULTI_BIND_DOMAIN(aff) +ISL_DECLARE_MULTI_UNBIND_PARAMS(aff) +ISL_DECLARE_MULTI_DOMAIN_REVERSE(aff) + +__isl_constructor +__isl_give isl_multi_aff *isl_multi_aff_from_aff(__isl_take isl_aff *aff); +__isl_export +__isl_give isl_multi_aff *isl_multi_aff_domain_map(__isl_take isl_space *space); +__isl_export +__isl_give isl_multi_aff *isl_space_domain_map_multi_aff( + __isl_take isl_space *space); +__isl_export +__isl_give isl_multi_aff *isl_multi_aff_range_map(__isl_take isl_space *space); +__isl_export +__isl_give isl_multi_aff *isl_space_range_map_multi_aff( + __isl_take isl_space *space); +__isl_give isl_multi_aff *isl_multi_aff_project_out_map( + __isl_take isl_space *space, enum isl_dim_type type, + unsigned first, unsigned n); + +__isl_overload +__isl_give isl_multi_aff *isl_multi_aff_multi_val_on_domain_space( + __isl_take isl_space *space, __isl_take isl_multi_val *mv); +__isl_overload +__isl_give isl_multi_aff *isl_space_multi_aff_on_domain_multi_val( + __isl_take isl_space *space, __isl_take isl_multi_val *mv); +__isl_give isl_multi_aff *isl_multi_aff_multi_val_on_space( + __isl_take isl_space *space, __isl_take isl_multi_val *mv); + +__isl_export +__isl_give isl_multi_val *isl_multi_aff_get_constant_multi_val( + __isl_keep isl_multi_aff *ma); + +__isl_export +__isl_give isl_multi_aff *isl_multi_aff_floor(__isl_take isl_multi_aff *ma); + +__isl_export +__isl_give isl_multi_aff *isl_multi_aff_gist_params( + __isl_take isl_multi_aff *maff, __isl_take isl_set *context); +__isl_export +__isl_give isl_multi_aff *isl_multi_aff_gist(__isl_take isl_multi_aff *maff, + __isl_take isl_set *context); + +__isl_give isl_multi_aff *isl_multi_aff_lift(__isl_take isl_multi_aff *maff, + __isl_give isl_local_space **ls); + +__isl_overload +__isl_give isl_multi_aff *isl_multi_aff_pullback_multi_aff( + __isl_take isl_multi_aff *ma1, __isl_take isl_multi_aff *ma2); + +__isl_give isl_multi_aff *isl_multi_aff_move_dims(__isl_take isl_multi_aff *ma, + enum isl_dim_type dst_type, unsigned dst_pos, + enum isl_dim_type src_type, unsigned src_pos, unsigned n); + +__isl_give isl_set *isl_multi_aff_lex_lt_set(__isl_take isl_multi_aff *ma1, + __isl_take isl_multi_aff *ma2); +__isl_give isl_set *isl_multi_aff_lex_le_set(__isl_take isl_multi_aff *ma1, + __isl_take isl_multi_aff *ma2); +__isl_give isl_set *isl_multi_aff_lex_gt_set(__isl_take isl_multi_aff *ma1, + __isl_take isl_multi_aff *ma2); +__isl_give isl_set *isl_multi_aff_lex_ge_set(__isl_take isl_multi_aff *ma1, + __isl_take isl_multi_aff *ma2); + +__isl_export +__isl_give isl_basic_set *isl_multi_aff_bind(__isl_take isl_multi_aff *ma, + __isl_take isl_multi_id *tuple); + +__isl_give char *isl_multi_aff_to_str(__isl_keep isl_multi_aff *ma); +__isl_give isl_printer *isl_printer_print_multi_aff(__isl_take isl_printer *p, + __isl_keep isl_multi_aff *maff); + +__isl_constructor +__isl_give isl_multi_aff *isl_multi_aff_read_from_str(isl_ctx *ctx, + const char *str); +void isl_multi_aff_dump(__isl_keep isl_multi_aff *maff); + +ISL_DECLARE_MULTI(pw_aff) +ISL_DECLARE_MULTI_IDENTITY(pw_aff) +ISL_DECLARE_MULTI_ARITH(pw_aff) +ISL_DECLARE_MULTI_MIN_MAX(pw_aff) +ISL_DECLARE_MULTI_ADD_CONSTANT(pw_aff) +ISL_DECLARE_MULTI_ZERO(pw_aff) +ISL_DECLARE_MULTI_NAN(pw_aff) +ISL_DECLARE_MULTI_DIMS(pw_aff) +ISL_DECLARE_MULTI_DIM_ID(pw_aff) +ISL_DECLARE_MULTI_INSERT_DOMAIN(pw_aff) +ISL_DECLARE_MULTI_TUPLE_ID(pw_aff) +ISL_DECLARE_MULTI_WITH_DOMAIN(pw_aff) +ISL_DECLARE_MULTI_BIND_DOMAIN(pw_aff) +ISL_DECLARE_MULTI_PARAM(pw_aff) +ISL_DECLARE_MULTI_UNBIND_PARAMS(pw_aff) +ISL_DECLARE_MULTI_DOMAIN_REVERSE(pw_aff) + +__isl_export +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_zero(__isl_take isl_space *space); +__isl_overload +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_identity_on_domain_space( + __isl_take isl_space *space); +__isl_export +__isl_give isl_pw_multi_aff *isl_space_identity_pw_multi_aff_on_domain( + __isl_take isl_space *space); +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_identity( + __isl_take isl_space *space); +__isl_export +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_domain_map( + __isl_take isl_space *space); +__isl_export +__isl_give isl_pw_multi_aff *isl_space_domain_map_pw_multi_aff( + __isl_take isl_space *space); +__isl_export +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_range_map( + __isl_take isl_space *space); +__isl_export +__isl_give isl_pw_multi_aff *isl_space_range_map_pw_multi_aff( + __isl_take isl_space *space); +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_project_out_map( + __isl_take isl_space *space, enum isl_dim_type type, + unsigned first, unsigned n); +__isl_export +__isl_give isl_pw_multi_aff *isl_multi_aff_to_pw_multi_aff( + __isl_take isl_multi_aff *ma); +__isl_constructor +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_multi_aff( + __isl_take isl_multi_aff *ma); +__isl_constructor +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_pw_aff( + __isl_take isl_pw_aff *pa); +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_alloc(__isl_take isl_set *set, + __isl_take isl_multi_aff *maff); +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_copy( + __isl_keep isl_pw_multi_aff *pma); +__isl_null isl_pw_multi_aff *isl_pw_multi_aff_free( + __isl_take isl_pw_multi_aff *pma); + +isl_size isl_pw_multi_aff_dim(__isl_keep isl_pw_multi_aff *pma, + enum isl_dim_type type); +__isl_export +isl_bool isl_pw_multi_aff_involves_locals(__isl_keep isl_pw_multi_aff *pma); +isl_bool isl_pw_multi_aff_involves_param_id(__isl_keep isl_pw_multi_aff *pma, + __isl_keep isl_id *id); +isl_bool isl_pw_multi_aff_involves_dims(__isl_keep isl_pw_multi_aff *pma, + enum isl_dim_type type, unsigned first, unsigned n); +__isl_export +__isl_give isl_pw_aff *isl_pw_multi_aff_get_at( + __isl_keep isl_pw_multi_aff *pma, int pos); +__isl_give isl_pw_aff *isl_pw_multi_aff_get_pw_aff( + __isl_keep isl_pw_multi_aff *pma, int pos); +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_set_pw_aff( + __isl_take isl_pw_multi_aff *pma, unsigned pos, + __isl_take isl_pw_aff *pa); + +isl_ctx *isl_pw_multi_aff_get_ctx(__isl_keep isl_pw_multi_aff *pma); +__isl_give isl_space *isl_pw_multi_aff_get_domain_space( + __isl_keep isl_pw_multi_aff *pma); +__isl_export +__isl_give isl_space *isl_pw_multi_aff_get_space( + __isl_keep isl_pw_multi_aff *pma); +isl_bool isl_pw_multi_aff_has_tuple_name(__isl_keep isl_pw_multi_aff *pma, + enum isl_dim_type type); +const char *isl_pw_multi_aff_get_tuple_name(__isl_keep isl_pw_multi_aff *pma, + enum isl_dim_type type); +__isl_export +__isl_give isl_id *isl_pw_multi_aff_get_range_tuple_id( + __isl_keep isl_pw_multi_aff *pma); +__isl_give isl_id *isl_pw_multi_aff_get_tuple_id( + __isl_keep isl_pw_multi_aff *pma, enum isl_dim_type type); +__isl_export +isl_bool isl_pw_multi_aff_has_range_tuple_id(__isl_keep isl_pw_multi_aff *pma); +isl_bool isl_pw_multi_aff_has_tuple_id(__isl_keep isl_pw_multi_aff *pma, + enum isl_dim_type type); +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_set_tuple_id( + __isl_take isl_pw_multi_aff *pma, + enum isl_dim_type type, __isl_take isl_id *id); +__isl_overload +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_set_range_tuple_id( + __isl_take isl_pw_multi_aff *pma, __isl_take isl_id *id); +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_reset_tuple_id( + __isl_take isl_pw_multi_aff *pma, enum isl_dim_type type); +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_reset_user( + __isl_take isl_pw_multi_aff *pma); + +int isl_pw_multi_aff_find_dim_by_name(__isl_keep isl_pw_multi_aff *pma, + enum isl_dim_type type, const char *name); + +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_drop_dims( + __isl_take isl_pw_multi_aff *pma, + enum isl_dim_type type, unsigned first, unsigned n); + +__isl_export +__isl_give isl_set *isl_pw_multi_aff_domain(__isl_take isl_pw_multi_aff *pma); + +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_empty(__isl_take isl_space *space); +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_domain( + __isl_take isl_set *set); + +__isl_export +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_multi_val_on_domain( + __isl_take isl_set *domain, __isl_take isl_multi_val *mv); +__isl_overload +__isl_give isl_pw_multi_aff *isl_set_pw_multi_aff_on_domain_multi_val( + __isl_take isl_set *domain, __isl_take isl_multi_val *mv); + +const char *isl_pw_multi_aff_get_dim_name(__isl_keep isl_pw_multi_aff *pma, + enum isl_dim_type type, unsigned pos); +__isl_give isl_id *isl_pw_multi_aff_get_dim_id( + __isl_keep isl_pw_multi_aff *pma, enum isl_dim_type type, + unsigned pos); +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_set_dim_id( + __isl_take isl_pw_multi_aff *pma, + enum isl_dim_type type, unsigned pos, __isl_take isl_id *id); + +isl_bool isl_pw_multi_aff_involves_nan(__isl_keep isl_pw_multi_aff *pma); +__isl_export +isl_bool isl_pw_multi_aff_plain_is_equal(__isl_keep isl_pw_multi_aff *pma1, + __isl_keep isl_pw_multi_aff *pma2); +isl_bool isl_pw_multi_aff_is_equal(__isl_keep isl_pw_multi_aff *pma1, + __isl_keep isl_pw_multi_aff *pma2); + +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_fix_si( + __isl_take isl_pw_multi_aff *pma, enum isl_dim_type type, + unsigned pos, int value); + +__isl_export +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_union_add( + __isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2); + +__isl_export +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_domain_reverse( + __isl_take isl_pw_multi_aff *pma); + +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_neg( + __isl_take isl_pw_multi_aff *pma); + +__isl_export +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_add( + __isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2); +__isl_export +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_sub( + __isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2); + +__isl_overload +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_add_constant_val( + __isl_take isl_pw_multi_aff *pma, __isl_take isl_val *v); +__isl_overload +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_add_constant_multi_val( + __isl_take isl_pw_multi_aff *pma, __isl_take isl_multi_val *mv); +__isl_overload +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_scale_val( + __isl_take isl_pw_multi_aff *pma, __isl_take isl_val *v); +__isl_overload +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_scale_down_val( + __isl_take isl_pw_multi_aff *pma, __isl_take isl_val *v); +__isl_overload +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_scale_multi_val( + __isl_take isl_pw_multi_aff *pma, __isl_take isl_multi_val *mv); +__isl_overload +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_scale_down_multi_val( + __isl_take isl_pw_multi_aff *pma, __isl_take isl_multi_val *mv); + +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_union_lexmin( + __isl_take isl_pw_multi_aff *pma1, + __isl_take isl_pw_multi_aff *pma2); +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_union_lexmax( + __isl_take isl_pw_multi_aff *pma1, + __isl_take isl_pw_multi_aff *pma2); + +__isl_give isl_multi_aff *isl_multi_aff_flatten_domain( + __isl_take isl_multi_aff *ma); + +__isl_export +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_range_product( + __isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2); +__isl_export +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_flat_range_product( + __isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2); +__isl_export +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_product( + __isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2); +__isl_export +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_range_factor_domain( + __isl_take isl_pw_multi_aff *pma); +__isl_export +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_range_factor_range( + __isl_take isl_pw_multi_aff *pma); + +__isl_export +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_intersect_params( + __isl_take isl_pw_multi_aff *pma, __isl_take isl_set *set); +__isl_export +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_intersect_domain( + __isl_take isl_pw_multi_aff *pma, __isl_take isl_set *set); +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_intersect_domain_wrapped_domain( + __isl_take isl_pw_multi_aff *pma, __isl_take isl_set *set); +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_intersect_domain_wrapped_range( + __isl_take isl_pw_multi_aff *pma, __isl_take isl_set *set); +__isl_export +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_subtract_domain( + __isl_take isl_pw_multi_aff *pma, __isl_take isl_set *set); + +__isl_export +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_insert_domain( + __isl_take isl_pw_multi_aff *pma, __isl_take isl_space *domain); +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_project_domain_on_params( + __isl_take isl_pw_multi_aff *pma); + +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_align_params( + __isl_take isl_pw_multi_aff *pma, __isl_take isl_space *model); +__isl_export +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_drop_unused_params( + __isl_take isl_pw_multi_aff *pma); + +__isl_export +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_coalesce( + __isl_take isl_pw_multi_aff *pma); +__isl_export +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_gist_params( + __isl_take isl_pw_multi_aff *pma, __isl_take isl_set *set); +__isl_export +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_gist( + __isl_take isl_pw_multi_aff *pma, __isl_take isl_set *set); + +__isl_overload +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_pullback_multi_aff( + __isl_take isl_pw_multi_aff *pma, __isl_take isl_multi_aff *ma); +__isl_overload +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_pullback_pw_multi_aff( + __isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2); +__isl_overload +__isl_give isl_pw_multi_aff * +isl_pw_multi_aff_preimage_domain_wrapped_domain_pw_multi_aff( + __isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2); + +__isl_export +isl_size isl_pw_multi_aff_n_piece(__isl_keep isl_pw_multi_aff *pma); +__isl_export +isl_stat isl_pw_multi_aff_foreach_piece(__isl_keep isl_pw_multi_aff *pma, + isl_stat (*fn)(__isl_take isl_set *set, __isl_take isl_multi_aff *maff, + void *user), void *user); +isl_bool isl_pw_multi_aff_every_piece(__isl_keep isl_pw_multi_aff *pma, + isl_bool (*test)(__isl_keep isl_set *set, __isl_keep isl_multi_aff *ma, + void *user), void *user); +__isl_export +isl_bool isl_pw_multi_aff_isa_multi_aff(__isl_keep isl_pw_multi_aff *pma); +__isl_export +__isl_give isl_multi_aff *isl_pw_multi_aff_as_multi_aff( + __isl_take isl_pw_multi_aff *pma); + +__isl_export +__isl_give isl_map *isl_pw_multi_aff_as_map(__isl_take isl_pw_multi_aff *pma); +__isl_give isl_map *isl_map_from_pw_multi_aff(__isl_take isl_pw_multi_aff *pma); +__isl_export +__isl_give isl_set *isl_pw_multi_aff_as_set(__isl_take isl_pw_multi_aff *pma); +__isl_give isl_set *isl_set_from_pw_multi_aff(__isl_take isl_pw_multi_aff *pma); + +__isl_give char *isl_pw_multi_aff_to_str(__isl_keep isl_pw_multi_aff *pma); +__isl_give isl_printer *isl_printer_print_pw_multi_aff(__isl_take isl_printer *p, + __isl_keep isl_pw_multi_aff *pma); + +__isl_export +__isl_give isl_pw_multi_aff *isl_set_as_pw_multi_aff(__isl_take isl_set *set); +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_set(__isl_take isl_set *set); +__isl_export +__isl_give isl_pw_multi_aff *isl_map_as_pw_multi_aff(__isl_take isl_map *map); +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_map(__isl_take isl_map *map); + +__isl_export +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_bind_domain( + __isl_take isl_pw_multi_aff *pma, __isl_take isl_multi_id *tuple); +__isl_export +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_bind_domain_wrapped_domain( + __isl_take isl_pw_multi_aff *pma, __isl_take isl_multi_id *tuple); + +__isl_constructor +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_read_from_str(isl_ctx *ctx, + const char *str); +void isl_pw_multi_aff_dump(__isl_keep isl_pw_multi_aff *pma); + + +__isl_overload +__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_empty_ctx( + isl_ctx *ctx); +__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_empty_space( + __isl_take isl_space *space); +__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_empty( + __isl_take isl_space *space); +__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_from_aff( + __isl_take isl_aff *aff); +__isl_constructor +__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_from_multi_aff( + __isl_take isl_multi_aff *ma); +__isl_export +__isl_give isl_union_pw_multi_aff *isl_pw_multi_aff_to_union_pw_multi_aff( + __isl_take isl_pw_multi_aff *pma); +__isl_constructor +__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_from_pw_multi_aff( + __isl_take isl_pw_multi_aff *pma); +__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_from_domain( + __isl_take isl_union_set *uset); +__isl_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( + __isl_take isl_union_pw_multi_aff *upma); + +__isl_give isl_union_pw_multi_aff *isl_union_set_identity_union_pw_multi_aff( + __isl_take isl_union_set *uset); + +__isl_give isl_union_pw_aff *isl_union_pw_multi_aff_get_union_pw_aff( + __isl_keep isl_union_pw_multi_aff *upma, int pos); + +__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_add_pw_multi_aff( + __isl_take isl_union_pw_multi_aff *upma, + __isl_take isl_pw_multi_aff *pma); + +isl_ctx *isl_union_pw_multi_aff_get_ctx( + __isl_keep isl_union_pw_multi_aff *upma); +__isl_export +__isl_give isl_space *isl_union_pw_multi_aff_get_space( + __isl_keep isl_union_pw_multi_aff *upma); +__isl_export +__isl_give isl_pw_multi_aff_list *isl_union_pw_multi_aff_get_pw_multi_aff_list( + __isl_keep isl_union_pw_multi_aff *upma); + +isl_size isl_union_pw_multi_aff_dim(__isl_keep isl_union_pw_multi_aff *upma, + enum isl_dim_type type); +__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_set_dim_name( + __isl_take isl_union_pw_multi_aff *upma, + enum isl_dim_type type, unsigned pos, const char *s); + +int isl_union_pw_multi_aff_find_dim_by_name( + __isl_keep isl_union_pw_multi_aff *upma, enum isl_dim_type type, + const char *name); + +__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_drop_dims( + __isl_take isl_union_pw_multi_aff *upma, + enum isl_dim_type type, unsigned first, unsigned n); +__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_reset_user( + __isl_take isl_union_pw_multi_aff *upma); + +__isl_export +__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_coalesce( + __isl_take isl_union_pw_multi_aff *upma); +__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_gist_params( + __isl_take isl_union_pw_multi_aff *upma, __isl_take isl_set *context); +__isl_export +__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_gist( + __isl_take isl_union_pw_multi_aff *upma, + __isl_take isl_union_set *context); + +__isl_overload +__isl_give isl_union_pw_multi_aff * +isl_union_pw_multi_aff_pullback_union_pw_multi_aff( + __isl_take isl_union_pw_multi_aff *upma1, + __isl_take isl_union_pw_multi_aff *upma2); +__isl_overload +__isl_give isl_union_pw_multi_aff * +isl_union_pw_multi_aff_apply_union_pw_multi_aff( + __isl_take isl_union_pw_multi_aff *upma1, + __isl_take isl_union_pw_multi_aff *upma2); +__isl_overload +__isl_give isl_union_pw_multi_aff * +isl_union_pw_multi_aff_preimage_domain_wrapped_domain_union_pw_multi_aff( + __isl_take isl_union_pw_multi_aff *upma1, + __isl_take isl_union_pw_multi_aff *upma2); + +__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_align_params( + __isl_take isl_union_pw_multi_aff *upma, __isl_take isl_space *model); +__isl_export +__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_drop_unused_params( + __isl_take isl_union_pw_multi_aff *upma); + +isl_size isl_union_pw_multi_aff_n_pw_multi_aff( + __isl_keep isl_union_pw_multi_aff *upma); + +isl_stat isl_union_pw_multi_aff_foreach_pw_multi_aff( + __isl_keep isl_union_pw_multi_aff *upma, + isl_stat (*fn)(__isl_take isl_pw_multi_aff *pma, void *user), + void *user); +isl_bool isl_union_pw_multi_aff_every_pw_multi_aff( + __isl_keep isl_union_pw_multi_aff *upma, + isl_bool (*test)(__isl_keep isl_pw_multi_aff *pma, void *user), + void *user); +__isl_export +__isl_give isl_pw_multi_aff *isl_union_pw_multi_aff_extract_pw_multi_aff( + __isl_keep isl_union_pw_multi_aff *upma, __isl_take isl_space *space); +__isl_export +isl_bool isl_union_pw_multi_aff_isa_pw_multi_aff( + __isl_keep isl_union_pw_multi_aff *upma); +__isl_export +__isl_give isl_pw_multi_aff *isl_union_pw_multi_aff_as_pw_multi_aff( + __isl_take isl_union_pw_multi_aff *upma); + +__isl_export +isl_bool isl_union_pw_multi_aff_plain_is_empty( + __isl_keep isl_union_pw_multi_aff *upma); +__isl_export +isl_bool isl_union_pw_multi_aff_involves_locals( + __isl_keep isl_union_pw_multi_aff *upma); +isl_bool isl_union_pw_multi_aff_involves_nan( + __isl_keep isl_union_pw_multi_aff *upma); +__isl_export +isl_bool isl_union_pw_multi_aff_plain_is_equal( + __isl_keep isl_union_pw_multi_aff *upma1, + __isl_keep isl_union_pw_multi_aff *upma2); + +__isl_export +__isl_give isl_union_set *isl_union_pw_multi_aff_domain( + __isl_take isl_union_pw_multi_aff *upma); + +__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_neg( + __isl_take isl_union_pw_multi_aff *upma); + +__isl_export +__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_add( + __isl_take isl_union_pw_multi_aff *upma1, + __isl_take isl_union_pw_multi_aff *upma2); +__isl_export +__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_union_add( + __isl_take isl_union_pw_multi_aff *upma1, + __isl_take isl_union_pw_multi_aff *upma2); +__isl_export +__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_sub( + __isl_take isl_union_pw_multi_aff *upma1, + __isl_take isl_union_pw_multi_aff *upma2); + +__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_scale_val( + __isl_take isl_union_pw_multi_aff *upma, __isl_take isl_val *val); +__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_scale_down_val( + __isl_take isl_union_pw_multi_aff *upma, __isl_take isl_val *val); +__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_scale_multi_val( + __isl_take isl_union_pw_multi_aff *upma, __isl_take isl_multi_val *mv); + +__isl_export +__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_range_product( + __isl_take isl_union_pw_multi_aff *upma1, + __isl_take isl_union_pw_multi_aff *upma2); +__isl_export +__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_flat_range_product( + __isl_take isl_union_pw_multi_aff *upma1, + __isl_take isl_union_pw_multi_aff *upma2); +__isl_export +__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_range_factor_domain( + __isl_take isl_union_pw_multi_aff *upma); +__isl_export +__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_range_factor_range( + __isl_take isl_union_pw_multi_aff *upma); + +__isl_export +__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_intersect_params( + __isl_take isl_union_pw_multi_aff *upma, __isl_take isl_set *set); +__isl_overload +__isl_give isl_union_pw_multi_aff * +isl_union_pw_multi_aff_intersect_domain_union_set( + __isl_take isl_union_pw_multi_aff *upma, + __isl_take isl_union_set *uset); +__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_intersect_domain( + __isl_take isl_union_pw_multi_aff *upma, + __isl_take isl_union_set *uset); +__isl_overload +__isl_give isl_union_pw_multi_aff * +isl_union_pw_multi_aff_intersect_domain_space( + __isl_take isl_union_pw_multi_aff *upma, __isl_take isl_space *space); +__isl_export +__isl_give isl_union_pw_multi_aff * +isl_union_pw_multi_aff_intersect_domain_wrapped_domain( + __isl_take isl_union_pw_multi_aff *upma, + __isl_take isl_union_set *uset); +__isl_export +__isl_give isl_union_pw_multi_aff * +isl_union_pw_multi_aff_intersect_domain_wrapped_range( + __isl_take isl_union_pw_multi_aff *upma, + __isl_take isl_union_set *uset); +__isl_overload +__isl_give isl_union_pw_multi_aff * +isl_union_pw_multi_aff_subtract_domain_union_set( + __isl_take isl_union_pw_multi_aff *upma, + __isl_take isl_union_set *uset); +__isl_overload +__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_subtract_domain_space( + __isl_take isl_union_pw_multi_aff *upma, __isl_take isl_space *space); +__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_subtract_domain( + __isl_take isl_union_pw_multi_aff *upma, + __isl_take isl_union_set *uset); + +__isl_export +__isl_give isl_union_map *isl_union_pw_multi_aff_as_union_map( + __isl_take isl_union_pw_multi_aff *upma); +__isl_overload +__isl_give isl_union_map *isl_union_map_from_union_pw_multi_aff( + __isl_take isl_union_pw_multi_aff *upma); + +__isl_give isl_printer *isl_printer_print_union_pw_multi_aff( + __isl_take isl_printer *p, __isl_keep isl_union_pw_multi_aff *upma); + +__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_from_union_set( + __isl_take isl_union_set *uset); +__isl_export +__isl_give isl_union_pw_multi_aff *isl_union_map_as_union_pw_multi_aff( + __isl_take isl_union_map *umap); +__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_from_union_map( + __isl_take isl_union_map *umap); + +__isl_constructor +__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_read_from_str( + isl_ctx *ctx, const char *str); +void isl_union_pw_multi_aff_dump(__isl_keep isl_union_pw_multi_aff *upma); +__isl_give char *isl_union_pw_multi_aff_to_str( + __isl_keep isl_union_pw_multi_aff *upma); + +uint32_t isl_multi_pw_aff_get_hash(__isl_keep isl_multi_pw_aff *mpa); + +__isl_constructor +__isl_give isl_multi_pw_aff *isl_multi_pw_aff_from_aff(__isl_take isl_aff *aff); +__isl_export +__isl_give isl_multi_pw_aff *isl_multi_aff_to_multi_pw_aff( + __isl_take isl_multi_aff *ma); +__isl_constructor +__isl_give isl_multi_pw_aff *isl_multi_pw_aff_from_multi_aff( + __isl_take isl_multi_aff *ma); +__isl_constructor +__isl_give isl_multi_pw_aff *isl_multi_pw_aff_from_pw_aff( + __isl_take isl_pw_aff *pa); +__isl_export +__isl_give isl_set *isl_multi_pw_aff_domain(__isl_take isl_multi_pw_aff *mpa); +__isl_export +__isl_give isl_multi_pw_aff *isl_multi_pw_aff_intersect_params( + __isl_take isl_multi_pw_aff *mpa, __isl_take isl_set *set); +__isl_export +__isl_give isl_multi_pw_aff *isl_multi_pw_aff_intersect_domain( + __isl_take isl_multi_pw_aff *mpa, __isl_take isl_set *domain); + +__isl_export +__isl_give isl_multi_pw_aff *isl_multi_pw_aff_coalesce( + __isl_take isl_multi_pw_aff *mpa); +__isl_export +__isl_give isl_multi_pw_aff *isl_multi_pw_aff_gist( + __isl_take isl_multi_pw_aff *mpa, __isl_take isl_set *set); +__isl_export +__isl_give isl_multi_pw_aff *isl_multi_pw_aff_gist_params( + __isl_take isl_multi_pw_aff *mpa, __isl_take isl_set *set); + +isl_bool isl_multi_pw_aff_is_cst(__isl_keep isl_multi_pw_aff *mpa); +isl_bool isl_multi_pw_aff_is_equal(__isl_keep isl_multi_pw_aff *mpa1, + __isl_keep isl_multi_pw_aff *mpa2); + +__isl_overload +__isl_give isl_multi_pw_aff *isl_multi_pw_aff_pullback_multi_aff( + __isl_take isl_multi_pw_aff *mpa, __isl_take isl_multi_aff *ma); +__isl_overload +__isl_give isl_multi_pw_aff *isl_multi_pw_aff_pullback_pw_multi_aff( + __isl_take isl_multi_pw_aff *mpa, __isl_take isl_pw_multi_aff *pma); +__isl_overload +__isl_give isl_multi_pw_aff *isl_multi_pw_aff_pullback_multi_pw_aff( + __isl_take isl_multi_pw_aff *mpa1, __isl_take isl_multi_pw_aff *mpa2); + +__isl_export +__isl_give isl_multi_pw_aff *isl_multi_pw_aff_union_add( + __isl_take isl_multi_pw_aff *mpa1, __isl_take isl_multi_pw_aff *mpa2); + +__isl_give isl_multi_pw_aff *isl_multi_pw_aff_move_dims( + __isl_take isl_multi_pw_aff *pma, + enum isl_dim_type dst_type, unsigned dst_pos, + enum isl_dim_type src_type, unsigned src_pos, unsigned n); + +__isl_export +isl_bool isl_multi_pw_aff_isa_multi_aff(__isl_keep isl_multi_pw_aff *mpa); +__isl_export +__isl_give isl_multi_aff *isl_multi_pw_aff_as_multi_aff( + __isl_take isl_multi_pw_aff *mpa); + +__isl_export +__isl_give isl_set *isl_multi_pw_aff_as_set(__isl_take isl_multi_pw_aff *mpa); +__isl_give isl_set *isl_set_from_multi_pw_aff(__isl_take isl_multi_pw_aff *mpa); +__isl_export +__isl_give isl_map *isl_multi_pw_aff_as_map(__isl_take isl_multi_pw_aff *mpa); +__isl_give isl_map *isl_map_from_multi_pw_aff(__isl_take isl_multi_pw_aff *mpa); +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_multi_pw_aff( + __isl_take isl_multi_pw_aff *mpa); +__isl_export +__isl_give isl_multi_pw_aff *isl_pw_multi_aff_to_multi_pw_aff( + __isl_take isl_pw_multi_aff *pma); +__isl_constructor +__isl_give isl_multi_pw_aff *isl_multi_pw_aff_from_pw_multi_aff( + __isl_take isl_pw_multi_aff *pma); + +__isl_give isl_map *isl_multi_pw_aff_eq_map(__isl_take isl_multi_pw_aff *mpa1, + __isl_take isl_multi_pw_aff *mpa2); +__isl_give isl_map *isl_multi_pw_aff_lex_le_map( + __isl_take isl_multi_pw_aff *mpa1, __isl_take isl_multi_pw_aff *mpa2); +__isl_give isl_map *isl_multi_pw_aff_lex_lt_map( + __isl_take isl_multi_pw_aff *mpa1, __isl_take isl_multi_pw_aff *mpa2); +__isl_give isl_map *isl_multi_pw_aff_lex_ge_map( + __isl_take isl_multi_pw_aff *mpa1, __isl_take isl_multi_pw_aff *mpa2); +__isl_give isl_map *isl_multi_pw_aff_lex_gt_map( + __isl_take isl_multi_pw_aff *mpa1, __isl_take isl_multi_pw_aff *mpa2); + +__isl_export +__isl_give isl_set *isl_multi_pw_aff_bind(__isl_take isl_multi_pw_aff *mpa, + __isl_take isl_multi_id *tuple); + +__isl_constructor +__isl_give isl_multi_pw_aff *isl_multi_pw_aff_read_from_str(isl_ctx *ctx, + const char *str); +__isl_give char *isl_multi_pw_aff_to_str(__isl_keep isl_multi_pw_aff *mpa); +__isl_give isl_printer *isl_printer_print_multi_pw_aff( + __isl_take isl_printer *p, __isl_keep isl_multi_pw_aff *mpa); +void isl_multi_pw_aff_dump(__isl_keep isl_multi_pw_aff *mpa); + +__isl_give isl_union_pw_aff *isl_union_pw_aff_copy( + __isl_keep isl_union_pw_aff *upa); +__isl_null isl_union_pw_aff *isl_union_pw_aff_free( + __isl_take isl_union_pw_aff *upa); + +isl_ctx *isl_union_pw_aff_get_ctx(__isl_keep isl_union_pw_aff *upa); +__isl_export +__isl_give isl_space *isl_union_pw_aff_get_space( + __isl_keep isl_union_pw_aff *upa); +__isl_give isl_pw_aff_list *isl_union_pw_aff_get_pw_aff_list( + __isl_keep isl_union_pw_aff *upa); + +isl_size isl_union_pw_aff_dim(__isl_keep isl_union_pw_aff *upa, + enum isl_dim_type type); +__isl_give isl_union_pw_aff *isl_union_pw_aff_set_dim_name( + __isl_take isl_union_pw_aff *upa, enum isl_dim_type type, + unsigned pos, const char *s); + +int isl_union_pw_aff_find_dim_by_name(__isl_keep isl_union_pw_aff *upa, + enum isl_dim_type type, const char *name); + +__isl_give isl_union_pw_aff *isl_union_pw_aff_drop_dims( + __isl_take isl_union_pw_aff *upa, + enum isl_dim_type type, unsigned first, unsigned n); +__isl_give isl_union_pw_aff *isl_union_pw_aff_reset_user( + __isl_take isl_union_pw_aff *upa); + +__isl_give isl_union_pw_aff *isl_union_pw_aff_empty_ctx(isl_ctx *ctx); +__isl_give isl_union_pw_aff *isl_union_pw_aff_empty_space( + __isl_take isl_space *space); +__isl_give isl_union_pw_aff *isl_union_pw_aff_empty( + __isl_take isl_space *space); +__isl_constructor +__isl_give isl_union_pw_aff *isl_union_pw_aff_from_aff(__isl_take isl_aff *aff); +__isl_export +__isl_give isl_union_pw_aff *isl_pw_aff_to_union_pw_aff( + __isl_take isl_pw_aff *pa); +__isl_constructor +__isl_give isl_union_pw_aff *isl_union_pw_aff_from_pw_aff( + __isl_take isl_pw_aff *pa); +__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); + +__isl_constructor +__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_from_union_pw_aff( + __isl_take isl_union_pw_aff *upa); + +isl_size isl_union_pw_aff_n_pw_aff(__isl_keep isl_union_pw_aff *upa); + +isl_stat isl_union_pw_aff_foreach_pw_aff(__isl_keep isl_union_pw_aff *upa, + isl_stat (*fn)(__isl_take isl_pw_aff *pa, void *user), void *user); +isl_bool isl_union_pw_aff_every_pw_aff(__isl_keep isl_union_pw_aff *upa, + isl_bool (*test)(__isl_keep isl_pw_aff *pa, void *user), void *user); +__isl_give isl_pw_aff *isl_union_pw_aff_extract_pw_aff( + __isl_keep isl_union_pw_aff *upa, __isl_take isl_space *space); + +isl_bool isl_union_pw_aff_involves_nan(__isl_keep isl_union_pw_aff *upa); +__isl_export +isl_bool isl_union_pw_aff_plain_is_equal(__isl_keep isl_union_pw_aff *upa1, + __isl_keep isl_union_pw_aff *upa2); + +__isl_export +__isl_give isl_union_set *isl_union_pw_aff_domain( + __isl_take isl_union_pw_aff *upa); + +__isl_give isl_union_pw_aff *isl_union_pw_aff_neg( + __isl_take isl_union_pw_aff *upa); + +__isl_export +__isl_give isl_union_pw_aff *isl_union_pw_aff_add( + __isl_take isl_union_pw_aff *upa1, __isl_take isl_union_pw_aff *upa2); +__isl_export +__isl_give isl_union_pw_aff *isl_union_pw_aff_union_add( + __isl_take isl_union_pw_aff *upa1, __isl_take isl_union_pw_aff *upa2); +__isl_export +__isl_give isl_union_pw_aff *isl_union_pw_aff_sub( + __isl_take isl_union_pw_aff *upa1, __isl_take isl_union_pw_aff *upa2); + +__isl_export +__isl_give isl_union_pw_aff *isl_union_pw_aff_coalesce( + __isl_take isl_union_pw_aff *upa); +__isl_export +__isl_give isl_union_pw_aff *isl_union_pw_aff_gist( + __isl_take isl_union_pw_aff *upa, __isl_take isl_union_set *context); +__isl_give isl_union_pw_aff *isl_union_pw_aff_gist_params( + __isl_take isl_union_pw_aff *upa, __isl_take isl_set *context); + +__isl_overload +__isl_give isl_union_pw_aff *isl_union_pw_aff_pullback_union_pw_multi_aff( + __isl_take isl_union_pw_aff *upa, + __isl_take isl_union_pw_multi_aff *upma); + +__isl_give isl_union_pw_aff *isl_union_pw_aff_floor( + __isl_take isl_union_pw_aff *upa); + +__isl_give isl_union_pw_aff *isl_union_pw_aff_scale_val( + __isl_take isl_union_pw_aff *upa, __isl_take isl_val *v); +__isl_give isl_union_pw_aff *isl_union_pw_aff_scale_down_val( + __isl_take isl_union_pw_aff *upa, __isl_take isl_val *v); +__isl_give isl_union_pw_aff *isl_union_pw_aff_mod_val( + __isl_take isl_union_pw_aff *upa, __isl_take isl_val *f); + +__isl_give isl_union_pw_aff *isl_union_pw_aff_align_params( + __isl_take isl_union_pw_aff *upa, __isl_take isl_space *model); +__isl_export +__isl_give isl_union_pw_aff *isl_union_pw_aff_drop_unused_params( + __isl_take isl_union_pw_aff *upa); + +__isl_export +__isl_give isl_union_pw_aff *isl_union_pw_aff_intersect_params( + __isl_take isl_union_pw_aff *upa, __isl_take isl_set *set); +__isl_overload +__isl_give isl_union_pw_aff *isl_union_pw_aff_intersect_domain_space( + __isl_take isl_union_pw_aff *upa, __isl_take isl_space *space); +__isl_overload +__isl_give isl_union_pw_aff *isl_union_pw_aff_intersect_domain_union_set( + __isl_take isl_union_pw_aff *upa, __isl_take isl_union_set *uset); +__isl_give isl_union_pw_aff *isl_union_pw_aff_intersect_domain( + __isl_take isl_union_pw_aff *upa, __isl_take isl_union_set *uset); +__isl_export +__isl_give isl_union_pw_aff *isl_union_pw_aff_intersect_domain_wrapped_domain( + __isl_take isl_union_pw_aff *upa, __isl_take isl_union_set *uset); +__isl_export +__isl_give isl_union_pw_aff *isl_union_pw_aff_intersect_domain_wrapped_range( + __isl_take isl_union_pw_aff *upa, __isl_take isl_union_set *uset); +__isl_overload +__isl_give isl_union_pw_aff *isl_union_pw_aff_subtract_domain_union_set( + __isl_take isl_union_pw_aff *upa, __isl_take isl_union_set *uset); +__isl_overload +__isl_give isl_union_pw_aff *isl_union_pw_aff_subtract_domain_space( + __isl_take isl_union_pw_aff *upa, __isl_take isl_space *space); +__isl_give isl_union_pw_aff *isl_union_pw_aff_subtract_domain( + __isl_take isl_union_pw_aff *upa, __isl_take isl_union_set *uset); + +__isl_give isl_union_pw_aff *isl_union_pw_aff_set_dim_name( + __isl_take isl_union_pw_aff *upa, + enum isl_dim_type type, unsigned pos, const char *s); + +__isl_give isl_union_set *isl_union_pw_aff_zero_union_set( + __isl_take isl_union_pw_aff *upa); + +__isl_give isl_union_map *isl_union_map_from_union_pw_aff( + __isl_take isl_union_pw_aff *upa); + +__isl_overload +__isl_give isl_union_set *isl_union_pw_aff_bind_id( + __isl_take isl_union_pw_aff *upa, __isl_take isl_id *id); + +__isl_constructor +__isl_give isl_union_pw_aff *isl_union_pw_aff_read_from_str(isl_ctx *ctx, + const char *str); +__isl_give char *isl_union_pw_aff_to_str(__isl_keep isl_union_pw_aff *upa); +__isl_give isl_printer *isl_printer_print_union_pw_aff( + __isl_take isl_printer *p, __isl_keep isl_union_pw_aff *upa); +void isl_union_pw_aff_dump(__isl_keep isl_union_pw_aff *upa); + +ISL_DECLARE_MULTI(union_pw_aff) +ISL_DECLARE_MULTI_ARITH(union_pw_aff) +ISL_DECLARE_MULTI_ZERO(union_pw_aff) +ISL_DECLARE_MULTI_NAN(union_pw_aff) +ISL_DECLARE_MULTI_DROP_DIMS(union_pw_aff) +ISL_DECLARE_MULTI_DIM_ID(union_pw_aff) +ISL_DECLARE_MULTI_TUPLE_ID(union_pw_aff) + +__isl_export +__isl_give isl_multi_union_pw_aff *isl_multi_aff_to_multi_union_pw_aff( + __isl_take isl_multi_aff *ma); +__isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_from_multi_aff( + __isl_take isl_multi_aff *ma); +__isl_constructor +__isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_from_union_pw_aff( + __isl_take isl_union_pw_aff *upa); +__isl_constructor +__isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_from_multi_pw_aff( + __isl_take isl_multi_pw_aff *mpa); +__isl_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); + +__isl_export +__isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_intersect_domain( + __isl_take isl_multi_union_pw_aff *mupa, + __isl_take isl_union_set *uset); +__isl_export +__isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_intersect_params( + __isl_take isl_multi_union_pw_aff *mupa, __isl_take isl_set *params); +__isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_intersect_range( + __isl_take isl_multi_union_pw_aff *mupa, __isl_take isl_set *set); + +__isl_export +__isl_give isl_union_set *isl_multi_union_pw_aff_domain( + __isl_take isl_multi_union_pw_aff *mupa); + +__isl_export +__isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_coalesce( + __isl_take isl_multi_union_pw_aff *mupa); +__isl_export +__isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_gist( + __isl_take isl_multi_union_pw_aff *mupa, + __isl_take isl_union_set *context); +__isl_export +__isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_gist_params( + __isl_take isl_multi_union_pw_aff *mupa, __isl_take isl_set *context); + +__isl_give isl_union_pw_aff *isl_multi_union_pw_aff_apply_aff( + __isl_take isl_multi_union_pw_aff *mupa, __isl_take isl_aff *aff); +__isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_apply_multi_aff( + __isl_take isl_multi_union_pw_aff *mupa, __isl_take isl_multi_aff *ma); +__isl_give isl_union_pw_aff *isl_multi_union_pw_aff_apply_pw_aff( + __isl_take isl_multi_union_pw_aff *mupa, __isl_take isl_pw_aff *pa); +__isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_apply_pw_multi_aff( + __isl_take isl_multi_union_pw_aff *mupa, + __isl_take isl_pw_multi_aff *pma); + +__isl_overload +__isl_give isl_multi_union_pw_aff * +isl_multi_union_pw_aff_pullback_union_pw_multi_aff( + __isl_take isl_multi_union_pw_aff *mupa, + __isl_take isl_union_pw_multi_aff *upma); + +__isl_give isl_union_pw_multi_aff * +isl_union_pw_multi_aff_from_multi_union_pw_aff( + __isl_take isl_multi_union_pw_aff *mupa); + +__isl_export +__isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_union_add( + __isl_take isl_multi_union_pw_aff *mupa1, + __isl_take isl_multi_union_pw_aff *mupa2); + +__isl_export +__isl_give isl_multi_union_pw_aff * +isl_union_pw_multi_aff_as_multi_union_pw_aff( + __isl_take isl_union_pw_multi_aff *upma); +__isl_give isl_multi_union_pw_aff * +isl_multi_union_pw_aff_from_union_pw_multi_aff( + __isl_take isl_union_pw_multi_aff *upma); + +__isl_export +__isl_give isl_multi_union_pw_aff *isl_union_map_as_multi_union_pw_aff( + __isl_take isl_union_map *umap); +__isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_from_union_map( + __isl_take isl_union_map *umap); +__isl_overload +__isl_give isl_union_map *isl_union_map_from_multi_union_pw_aff( + __isl_take isl_multi_union_pw_aff *mupa); + +__isl_give isl_union_set *isl_multi_union_pw_aff_zero_union_set( + __isl_take isl_multi_union_pw_aff *mupa); +__isl_export +__isl_give isl_union_set *isl_multi_union_pw_aff_bind( + __isl_take isl_multi_union_pw_aff *mupa, + __isl_take isl_multi_id *tuple); + +__isl_give isl_multi_pw_aff *isl_multi_union_pw_aff_extract_multi_pw_aff( + __isl_keep isl_multi_union_pw_aff *mupa, __isl_take isl_space *space); + +__isl_constructor +__isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_read_from_str( + isl_ctx *ctx, const char *str); +__isl_give char *isl_multi_union_pw_aff_to_str( + __isl_keep isl_multi_union_pw_aff *mupa); +__isl_give isl_printer *isl_printer_print_multi_union_pw_aff( + __isl_take isl_printer *p, __isl_keep isl_multi_union_pw_aff *mupa); +void isl_multi_union_pw_aff_dump(__isl_keep isl_multi_union_pw_aff *mupa); + +ISL_DECLARE_EXPORTED_LIST_FN(aff) +ISL_DECLARE_EXPORTED_LIST_FN_READ(aff) +ISL_DECLARE_EXPORTED_LIST_FN(pw_aff) +ISL_DECLARE_EXPORTED_LIST_FN_READ(pw_aff) +ISL_DECLARE_EXPORTED_LIST_FN(pw_multi_aff) +ISL_DECLARE_EXPORTED_LIST_FN_READ(pw_multi_aff) +ISL_DECLARE_EXPORTED_LIST_FN(union_pw_aff) +ISL_DECLARE_EXPORTED_LIST_FN_READ(union_pw_aff) +ISL_DECLARE_LIST_FN(union_pw_multi_aff) + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/external/mit/isl/dist/include/isl/aff_type.h b/external/mit/isl/dist/include/isl/aff_type.h new file mode 100644 index 000000000000..271f978b8ce2 --- /dev/null +++ b/external/mit/isl/dist/include/isl/aff_type.h @@ -0,0 +1,52 @@ +#ifndef ISL_AFF_TYPE_H +#define ISL_AFF_TYPE_H + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +struct __isl_subclass(isl_multi_aff) __isl_subclass(isl_pw_aff) isl_aff; +typedef struct isl_aff isl_aff; + +ISL_DECLARE_EXPORTED_LIST_TYPE(aff) + +struct __isl_subclass(isl_multi_pw_aff) __isl_subclass(isl_pw_multi_aff) + __isl_subclass(isl_union_pw_aff) isl_pw_aff; +typedef struct isl_pw_aff isl_pw_aff; + +ISL_DECLARE_EXPORTED_LIST_TYPE(pw_aff) + +struct __isl_subclass(isl_multi_union_pw_aff) + __isl_subclass(isl_union_pw_multi_aff) isl_union_pw_aff; +typedef struct isl_union_pw_aff isl_union_pw_aff; + +ISL_DECLARE_EXPORTED_LIST_TYPE(union_pw_aff) + +struct __isl_subclass(isl_multi_pw_aff) __isl_subclass(isl_pw_multi_aff) + isl_multi_aff; +typedef struct isl_multi_aff isl_multi_aff; + +struct __isl_subclass(isl_multi_pw_aff) __isl_subclass(isl_union_pw_multi_aff) + isl_pw_multi_aff; +typedef struct isl_pw_multi_aff isl_pw_multi_aff; + +ISL_DECLARE_EXPORTED_LIST_TYPE(pw_multi_aff) + +struct __isl_export isl_union_pw_multi_aff; +typedef struct isl_union_pw_multi_aff isl_union_pw_multi_aff; + +ISL_DECLARE_LIST_TYPE(union_pw_multi_aff) + +struct __isl_subclass(isl_multi_union_pw_aff) isl_multi_pw_aff; +typedef struct isl_multi_pw_aff isl_multi_pw_aff; + +struct __isl_export isl_multi_union_pw_aff; +typedef struct isl_multi_union_pw_aff isl_multi_union_pw_aff; + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/external/mit/isl/dist/include/isl/arg.h b/external/mit/isl/dist/include/isl/arg.h new file mode 100644 index 000000000000..edbd81e12dd0 --- /dev/null +++ b/external/mit/isl/dist/include/isl/arg.h @@ -0,0 +1,325 @@ +/* + * 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_ARG_H +#define ISL_ARG_H + +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +struct isl_arg_choice { + const char *name; + unsigned value; +}; + +struct isl_arg_flags { + const char *name; + unsigned mask; + unsigned value; +}; + +enum isl_arg_type { + isl_arg_end, + isl_arg_alias, + isl_arg_arg, + isl_arg_bool, + isl_arg_child, + isl_arg_choice, + isl_arg_flags, + isl_arg_footer, + isl_arg_int, + isl_arg_user, + isl_arg_long, + isl_arg_ulong, + isl_arg_str, + isl_arg_str_list, + isl_arg_version +}; + +struct isl_args; + +struct isl_arg { + enum isl_arg_type type; + char short_name; + const char *long_name; + const char *argument_name; +#define ISL_ARG_OFFSET_NONE ((size_t) -1) + size_t offset; + const char *help_msg; +#define ISL_ARG_SINGLE_DASH (1 << 0) +#define ISL_ARG_BOOL_ARG (1 << 1) +#define ISL_ARG_HIDDEN (1 << 2) + unsigned flags; + union { + struct { + struct isl_arg_choice *choice; + unsigned default_value; + unsigned default_selected; + int (*set)(void *opt, unsigned val); + } choice; + struct { + struct isl_arg_flags *flags; + unsigned default_value; + } flags; + struct { + unsigned default_value; + int (*set)(void *opt, unsigned val); + } b; + struct { + int default_value; + } i; + struct { + long default_value; + long default_selected; + int (*set)(void *opt, long val); + } l; + struct { + unsigned long default_value; + } ul; + struct { + const char *default_value; + } str; + struct { + size_t offset_n; + } str_list; + struct { + struct isl_args *child; + } child; + struct { + void (*print_version)(void); + } version; + struct { + int (*init)(void*); + void (*clear)(void*); + } user; + } u; +}; + +struct isl_args { + size_t options_size; + struct isl_arg *args; +}; + +#define ISL_ARGS_START(s,name) \ + struct isl_arg name ## LIST[]; \ + struct isl_args name = { sizeof(s), name ## LIST }; \ + struct isl_arg name ## LIST[] = { +#define ISL_ARGS_END \ + { isl_arg_end } }; + +#define ISL_ARG_ALIAS(l) { \ + .type = isl_arg_alias, \ + .long_name = l, \ +}, +#define ISL_ARG_ARG(st,f,a,d) { \ + .type = isl_arg_arg, \ + .argument_name = a, \ + .offset = offsetof(st, f), \ + .u = { .str = { .default_value = d } } \ +}, +#define ISL_ARG_FOOTER(h) { \ + .type = isl_arg_footer, \ + .help_msg = h, \ +}, +#define ISL_ARG_CHOICE(st,f,s,l,c,d,h) { \ + .type = isl_arg_choice, \ + .short_name = s, \ + .long_name = l, \ + .offset = offsetof(st, f), \ + .help_msg = h, \ + .u = { .choice = { .choice = c, .default_value = d, \ + .default_selected = d, .set = NULL } } \ +}, +#define ISL_ARG_OPT_CHOICE(st,f,s,l,c,d,ds,h) { \ + .type = isl_arg_choice, \ + .short_name = s, \ + .long_name = l, \ + .offset = offsetof(st, f), \ + .help_msg = h, \ + .u = { .choice = { .choice = c, .default_value = d, \ + .default_selected = ds, .set = NULL } } \ +}, +#define ISL_ARG_PHANTOM_USER_CHOICE_F(s,l,c,setter,d,h,fl) { \ + .type = isl_arg_choice, \ + .short_name = s, \ + .long_name = l, \ + .offset = ISL_ARG_OFFSET_NONE, \ + .help_msg = h, \ + .flags = fl, \ + .u = { .choice = { .choice = c, .default_value = d, \ + .default_selected = d, .set = setter } } \ +}, +#define ISL_ARG_USER_OPT_CHOICE(st,f,s,l,c,setter,d,ds,h) { \ + .type = isl_arg_choice, \ + .short_name = s, \ + .long_name = l, \ + .offset = offsetof(st, f), \ + .help_msg = h, \ + .u = { .choice = { .choice = c, .default_value = d, \ + .default_selected = ds, .set = setter } } \ +}, +#define _ISL_ARG_BOOL_F(o,s,l,setter,d,h,fl) { \ + .type = isl_arg_bool, \ + .short_name = s, \ + .long_name = l, \ + .offset = o, \ + .help_msg = h, \ + .flags = fl, \ + .u = { .b = { .default_value = d, .set = setter } } \ +}, +#define ISL_ARG_BOOL_F(st,f,s,l,d,h,fl) \ + _ISL_ARG_BOOL_F(offsetof(st, f),s,l,NULL,d,h,fl) +#define ISL_ARG_BOOL(st,f,s,l,d,h) \ + ISL_ARG_BOOL_F(st,f,s,l,d,h,0) +#define ISL_ARG_PHANTOM_BOOL_F(s,l,setter,h,fl) \ + _ISL_ARG_BOOL_F(ISL_ARG_OFFSET_NONE,s,l,setter,0,h,fl) +#define ISL_ARG_PHANTOM_BOOL(s,l,setter,h) \ + ISL_ARG_PHANTOM_BOOL_F(s,l,setter,h,0) +#define ISL_ARG_INT_F(st,f,s,l,a,d,h,fl) { \ + .type = isl_arg_int, \ + .short_name = s, \ + .long_name = l, \ + .argument_name = a, \ + .offset = offsetof(st, f), \ + .help_msg = h, \ + .flags = fl, \ + .u = { .i = { .default_value = d } } \ +}, +#define ISL_ARG_INT(st,f,s,l,a,d,h) \ + ISL_ARG_INT_F(st,f,s,l,a,d,h,0) +#define ISL_ARG_LONG(st,f,s,lo,d,h) { \ + .type = isl_arg_long, \ + .short_name = s, \ + .long_name = lo, \ + .offset = offsetof(st, f), \ + .help_msg = h, \ + .u = { .l = { .default_value = d, .default_selected = d, \ + .set = NULL } } \ +}, +#define ISL_ARG_USER_LONG(st,f,s,lo,setter,d,h) { \ + .type = isl_arg_long, \ + .short_name = s, \ + .long_name = lo, \ + .offset = offsetof(st, f), \ + .help_msg = h, \ + .u = { .l = { .default_value = d, .default_selected = d, \ + .set = setter } } \ +}, +#define ISL_ARG_OPT_LONG(st,f,s,lo,d,ds,h) { \ + .type = isl_arg_long, \ + .short_name = s, \ + .long_name = lo, \ + .offset = offsetof(st, f), \ + .help_msg = h, \ + .u = { .l = { .default_value = d, .default_selected = ds, \ + .set = NULL } } \ +}, +#define ISL_ARG_ULONG(st,f,s,l,d,h) { \ + .type = isl_arg_ulong, \ + .short_name = s, \ + .long_name = l, \ + .offset = offsetof(st, f), \ + .help_msg = h, \ + .u = { .ul = { .default_value = d } } \ +}, +#define ISL_ARG_STR_F(st,f,s,l,a,d,h,fl) { \ + .type = isl_arg_str, \ + .short_name = s, \ + .long_name = l, \ + .argument_name = a, \ + .offset = offsetof(st, f), \ + .help_msg = h, \ + .flags = fl, \ + .u = { .str = { .default_value = d } } \ +}, +#define ISL_ARG_STR(st,f,s,l,a,d,h) \ + ISL_ARG_STR_F(st,f,s,l,a,d,h,0) +#define ISL_ARG_STR_LIST(st,f_n,f_l,s,l,a,h) { \ + .type = isl_arg_str_list, \ + .short_name = s, \ + .long_name = l, \ + .argument_name = a, \ + .offset = offsetof(st, f_l), \ + .help_msg = h, \ + .u = { .str_list = { .offset_n = offsetof(st, f_n) } } \ +}, +#define _ISL_ARG_CHILD(o,l,c,h,fl) { \ + .type = isl_arg_child, \ + .long_name = l, \ + .offset = o, \ + .help_msg = h, \ + .flags = fl, \ + .u = { .child = { .child = c } } \ +}, +#define ISL_ARG_CHILD(st,f,l,c,h) \ + _ISL_ARG_CHILD(offsetof(st, f),l,c,h,0) +#define ISL_ARG_GROUP_F(l,c,h,fl) \ + _ISL_ARG_CHILD(ISL_ARG_OFFSET_NONE,l,c,h,fl) +#define ISL_ARG_GROUP(l,c,h) \ + ISL_ARG_GROUP_F(l,c,h,0) +#define ISL_ARG_FLAGS(st,f,s,l,c,d,h) { \ + .type = isl_arg_flags, \ + .short_name = s, \ + .long_name = l, \ + .offset = offsetof(st, f), \ + .help_msg = h, \ + .u = { .flags = { .flags = c, .default_value = d } } \ +}, +#define ISL_ARG_USER(st,f,i,c) { \ + .type = isl_arg_user, \ + .offset = offsetof(st, f), \ + .u = { .user = { .init = i, .clear = c} } \ +}, +#define ISL_ARG_VERSION(print) { \ + .type = isl_arg_version, \ + .u = { .version = { .print_version = print } } \ +}, + +#define ISL_ARG_ALL (1 << 0) +#define ISL_ARG_SKIP_HELP (1 << 1) + +void isl_args_set_defaults(struct isl_args *args, void *opt); +void isl_args_free(struct isl_args *args, void *opt); +int isl_args_parse(struct isl_args *args, int argc, char **argv, void *opt, + unsigned flags); + +#define ISL_ARG_DECL(prefix,st,args) \ +extern struct isl_args args; \ +st *prefix ## _new_with_defaults(void); \ +void prefix ## _free(st *opt); \ +int prefix ## _parse(st *opt, int argc, char **argv, unsigned flags); + +#define ISL_ARG_DEF(prefix,st,args) \ +st *prefix ## _new_with_defaults() \ +{ \ + st *opt = (st *)calloc(1, sizeof(st)); \ + if (opt) \ + isl_args_set_defaults(&(args), opt); \ + return opt; \ +} \ + \ +void prefix ## _free(st *opt) \ +{ \ + isl_args_free(&(args), opt); \ +} \ + \ +int prefix ## _parse(st *opt, int argc, char **argv, unsigned flags) \ +{ \ + return isl_args_parse(&(args), argc, argv, opt, flags); \ +} + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/external/mit/isl/dist/include/isl/ast.h b/external/mit/isl/dist/include/isl/ast.h new file mode 100644 index 000000000000..786f5b496ab6 --- /dev/null +++ b/external/mit/isl/dist/include/isl/ast.h @@ -0,0 +1,252 @@ +#ifndef ISL_AST_H +#define ISL_AST_H + +#include +#include +#include +#include +#include +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +isl_stat isl_options_set_ast_iterator_type(isl_ctx *ctx, const char *val); +const char *isl_options_get_ast_iterator_type(isl_ctx *ctx); + +isl_stat isl_options_set_ast_always_print_block(isl_ctx *ctx, int val); +int isl_options_get_ast_always_print_block(isl_ctx *ctx); + +isl_stat isl_options_set_ast_print_outermost_block(isl_ctx *ctx, int val); +int isl_options_get_ast_print_outermost_block(isl_ctx *ctx); + +__isl_give isl_ast_expr *isl_ast_expr_from_val(__isl_take isl_val *v); +__isl_give isl_ast_expr *isl_ast_expr_from_id(__isl_take isl_id *id); +__isl_give isl_ast_expr *isl_ast_expr_neg(__isl_take isl_ast_expr *expr); +__isl_give isl_ast_expr *isl_ast_expr_add(__isl_take isl_ast_expr *expr1, + __isl_take isl_ast_expr *expr2); +__isl_give isl_ast_expr *isl_ast_expr_sub(__isl_take isl_ast_expr *expr1, + __isl_take isl_ast_expr *expr2); +__isl_give isl_ast_expr *isl_ast_expr_mul(__isl_take isl_ast_expr *expr1, + __isl_take isl_ast_expr *expr2); +__isl_give isl_ast_expr *isl_ast_expr_div(__isl_take isl_ast_expr *expr1, + __isl_take isl_ast_expr *expr2); +__isl_give isl_ast_expr *isl_ast_expr_pdiv_q(__isl_take isl_ast_expr *expr1, + __isl_take isl_ast_expr *expr2); +__isl_give isl_ast_expr *isl_ast_expr_pdiv_r(__isl_take isl_ast_expr *expr1, + __isl_take isl_ast_expr *expr2); +__isl_give isl_ast_expr *isl_ast_expr_and(__isl_take isl_ast_expr *expr1, + __isl_take isl_ast_expr *expr2); +__isl_give isl_ast_expr *isl_ast_expr_and_then(__isl_take isl_ast_expr *expr1, + __isl_take isl_ast_expr *expr2); +__isl_give isl_ast_expr *isl_ast_expr_or(__isl_take isl_ast_expr *expr1, + __isl_take isl_ast_expr *expr2); +__isl_give isl_ast_expr *isl_ast_expr_or_else(__isl_take isl_ast_expr *expr1, + __isl_take isl_ast_expr *expr2); +__isl_give isl_ast_expr *isl_ast_expr_le(__isl_take isl_ast_expr *expr1, + __isl_take isl_ast_expr *expr2); +__isl_give isl_ast_expr *isl_ast_expr_lt(__isl_take isl_ast_expr *expr1, + __isl_take isl_ast_expr *expr2); +__isl_give isl_ast_expr *isl_ast_expr_ge(__isl_take isl_ast_expr *expr1, + __isl_take isl_ast_expr *expr2); +__isl_give isl_ast_expr *isl_ast_expr_gt(__isl_take isl_ast_expr *expr1, + __isl_take isl_ast_expr *expr2); +__isl_give isl_ast_expr *isl_ast_expr_eq(__isl_take isl_ast_expr *expr1, + __isl_take isl_ast_expr *expr2); +__isl_give isl_ast_expr *isl_ast_expr_access(__isl_take isl_ast_expr *array, + __isl_take isl_ast_expr_list *indices); +__isl_give isl_ast_expr *isl_ast_expr_call(__isl_take isl_ast_expr *function, + __isl_take isl_ast_expr_list *arguments); +__isl_give isl_ast_expr *isl_ast_expr_address_of(__isl_take isl_ast_expr *expr); + +__isl_give isl_ast_expr *isl_ast_expr_copy(__isl_keep isl_ast_expr *expr); +__isl_null isl_ast_expr *isl_ast_expr_free(__isl_take isl_ast_expr *expr); + +isl_ctx *isl_ast_expr_get_ctx(__isl_keep isl_ast_expr *expr); +__isl_subclass(isl_ast_expr) +enum isl_ast_expr_type isl_ast_expr_get_type(__isl_keep isl_ast_expr *expr); +__isl_export +__isl_give isl_val *isl_ast_expr_int_get_val(__isl_keep isl_ast_expr *expr); +__isl_give isl_val *isl_ast_expr_get_val(__isl_keep isl_ast_expr *expr); +__isl_export +__isl_give isl_id *isl_ast_expr_id_get_id(__isl_keep isl_ast_expr *expr); +__isl_give isl_id *isl_ast_expr_get_id(__isl_keep isl_ast_expr *expr); + +__isl_subclass(isl_ast_expr_op) +enum isl_ast_expr_op_type isl_ast_expr_op_get_type( + __isl_keep isl_ast_expr *expr); +enum isl_ast_expr_op_type isl_ast_expr_get_op_type( + __isl_keep isl_ast_expr *expr); +__isl_export +isl_size isl_ast_expr_op_get_n_arg(__isl_keep isl_ast_expr *expr); +isl_size isl_ast_expr_get_op_n_arg(__isl_keep isl_ast_expr *expr); +__isl_export +__isl_give isl_ast_expr *isl_ast_expr_op_get_arg(__isl_keep isl_ast_expr *expr, + int pos); +__isl_give isl_ast_expr *isl_ast_expr_get_op_arg(__isl_keep isl_ast_expr *expr, + int pos); +__isl_give isl_ast_expr *isl_ast_expr_set_op_arg(__isl_take isl_ast_expr *expr, + int pos, __isl_take isl_ast_expr *arg); + +isl_bool isl_ast_expr_is_equal(__isl_keep isl_ast_expr *expr1, + __isl_keep isl_ast_expr *expr2); + +__isl_give isl_ast_expr *isl_ast_expr_substitute_ids( + __isl_take isl_ast_expr *expr, __isl_take isl_id_to_ast_expr *id2expr); + +__isl_give isl_printer *isl_printer_print_ast_expr(__isl_take isl_printer *p, + __isl_keep isl_ast_expr *expr); +void isl_ast_expr_dump(__isl_keep isl_ast_expr *expr); +__isl_give char *isl_ast_expr_to_str(__isl_keep isl_ast_expr *expr); +__isl_export +__isl_give char *isl_ast_expr_to_C_str(__isl_keep isl_ast_expr *expr); + +__isl_constructor +__isl_give isl_ast_node *isl_ast_node_user_from_expr( + __isl_take isl_ast_expr *expr); +__isl_give isl_ast_node *isl_ast_node_alloc_user(__isl_take isl_ast_expr *expr); +__isl_give isl_ast_node *isl_ast_node_copy(__isl_keep isl_ast_node *node); +__isl_null isl_ast_node *isl_ast_node_free(__isl_take isl_ast_node *node); + +isl_ctx *isl_ast_node_get_ctx(__isl_keep isl_ast_node *node); +__isl_subclass(isl_ast_node) +enum isl_ast_node_type isl_ast_node_get_type(__isl_keep isl_ast_node *node); + +__isl_give isl_ast_node *isl_ast_node_set_annotation( + __isl_take isl_ast_node *node, __isl_take isl_id *annotation); +__isl_give isl_id *isl_ast_node_get_annotation(__isl_keep isl_ast_node *node); + +__isl_export +__isl_give isl_ast_expr *isl_ast_node_for_get_iterator( + __isl_keep isl_ast_node *node); +__isl_export +__isl_give isl_ast_expr *isl_ast_node_for_get_init( + __isl_keep isl_ast_node *node); +__isl_export +__isl_give isl_ast_expr *isl_ast_node_for_get_cond( + __isl_keep isl_ast_node *node); +__isl_export +__isl_give isl_ast_expr *isl_ast_node_for_get_inc( + __isl_keep isl_ast_node *node); +__isl_export +__isl_give isl_ast_node *isl_ast_node_for_get_body( + __isl_keep isl_ast_node *node); +__isl_export +isl_bool isl_ast_node_for_is_degenerate(__isl_keep isl_ast_node *node); + +__isl_export +__isl_give isl_ast_expr *isl_ast_node_if_get_cond( + __isl_keep isl_ast_node *node); +__isl_export +__isl_give isl_ast_node *isl_ast_node_if_get_then_node( + __isl_keep isl_ast_node *node); +__isl_give isl_ast_node *isl_ast_node_if_get_then( + __isl_keep isl_ast_node *node); +__isl_export +isl_bool isl_ast_node_if_has_else_node(__isl_keep isl_ast_node *node); +isl_bool isl_ast_node_if_has_else(__isl_keep isl_ast_node *node); +__isl_export +__isl_give isl_ast_node *isl_ast_node_if_get_else_node( + __isl_keep isl_ast_node *node); +__isl_give isl_ast_node *isl_ast_node_if_get_else( + __isl_keep isl_ast_node *node); + +__isl_constructor +__isl_give isl_ast_node *isl_ast_node_block_from_children( + __isl_take isl_ast_node_list *list); +__isl_export +__isl_give isl_ast_node_list *isl_ast_node_block_get_children( + __isl_keep isl_ast_node *node); + +__isl_export +__isl_give isl_id *isl_ast_node_mark_get_id(__isl_keep isl_ast_node *node); +__isl_export +__isl_give isl_ast_node *isl_ast_node_mark_get_node( + __isl_keep isl_ast_node *node); + +__isl_export +__isl_give isl_ast_expr *isl_ast_node_user_get_expr( + __isl_keep isl_ast_node *node); + +isl_stat isl_ast_node_foreach_descendant_top_down( + __isl_keep isl_ast_node *node, + isl_bool (*fn)(__isl_keep isl_ast_node *node, void *user), void *user); +__isl_export +__isl_give isl_ast_node *isl_ast_node_map_descendant_bottom_up( + __isl_take isl_ast_node *node, __isl_give isl_ast_node *(*fn)( + __isl_take isl_ast_node *node, void *user), void *user); + +__isl_give isl_printer *isl_printer_print_ast_node(__isl_take isl_printer *p, + __isl_keep isl_ast_node *node); +void isl_ast_node_dump(__isl_keep isl_ast_node *node); +__isl_give char *isl_ast_node_to_str(__isl_keep isl_ast_node *node); + +__isl_give isl_ast_print_options *isl_ast_print_options_alloc(isl_ctx *ctx); +__isl_give isl_ast_print_options *isl_ast_print_options_copy( + __isl_keep isl_ast_print_options *options); +__isl_null isl_ast_print_options *isl_ast_print_options_free( + __isl_take isl_ast_print_options *options); +isl_ctx *isl_ast_print_options_get_ctx( + __isl_keep isl_ast_print_options *options); + +__isl_give isl_ast_print_options *isl_ast_print_options_set_print_user( + __isl_take isl_ast_print_options *options, + __isl_give isl_printer *(*print_user)(__isl_take isl_printer *p, + __isl_take isl_ast_print_options *options, + __isl_keep isl_ast_node *node, void *user), + void *user); +__isl_give isl_ast_print_options *isl_ast_print_options_set_print_for( + __isl_take isl_ast_print_options *options, + __isl_give isl_printer *(*print_for)(__isl_take isl_printer *p, + __isl_take isl_ast_print_options *options, + __isl_keep isl_ast_node *node, void *user), + void *user); + +isl_stat isl_options_set_ast_print_macro_once(isl_ctx *ctx, int val); +int isl_options_get_ast_print_macro_once(isl_ctx *ctx); + +isl_stat isl_ast_expr_foreach_ast_expr_op_type(__isl_keep isl_ast_expr *expr, + isl_stat (*fn)(enum isl_ast_expr_op_type type, void *user), void *user); +isl_stat isl_ast_expr_foreach_ast_op_type(__isl_keep isl_ast_expr *expr, + isl_stat (*fn)(enum isl_ast_expr_op_type type, void *user), void *user); +isl_stat isl_ast_node_foreach_ast_expr_op_type(__isl_keep isl_ast_node *node, + isl_stat (*fn)(enum isl_ast_expr_op_type type, void *user), void *user); +isl_stat isl_ast_node_foreach_ast_op_type(__isl_keep isl_ast_node *node, + isl_stat (*fn)(enum isl_ast_expr_op_type type, void *user), void *user); +__isl_give isl_printer *isl_ast_expr_op_type_set_print_name( + __isl_take isl_printer *p, enum isl_ast_expr_op_type type, + __isl_keep const char *name); +__isl_give isl_printer *isl_ast_op_type_set_print_name( + __isl_take isl_printer *p, enum isl_ast_expr_op_type type, + __isl_keep const char *name); +__isl_give isl_printer *isl_ast_expr_op_type_print_macro( + enum isl_ast_expr_op_type type, __isl_take isl_printer *p); +__isl_give isl_printer *isl_ast_op_type_print_macro( + enum isl_ast_expr_op_type type, __isl_take isl_printer *p); +__isl_give isl_printer *isl_ast_expr_print_macros( + __isl_keep isl_ast_expr *expr, __isl_take isl_printer *p); +__isl_give isl_printer *isl_ast_node_print_macros( + __isl_keep isl_ast_node *node, __isl_take isl_printer *p); +__isl_give isl_printer *isl_ast_node_print(__isl_keep isl_ast_node *node, + __isl_take isl_printer *p, + __isl_take isl_ast_print_options *options); +__isl_give isl_printer *isl_ast_node_for_print(__isl_keep isl_ast_node *node, + __isl_take isl_printer *p, + __isl_take isl_ast_print_options *options); +__isl_give isl_printer *isl_ast_node_if_print(__isl_keep isl_ast_node *node, + __isl_take isl_printer *p, + __isl_take isl_ast_print_options *options); + +__isl_export +__isl_give char *isl_ast_node_to_C_str(__isl_keep isl_ast_node *node); + +ISL_DECLARE_LIST_FN(ast_expr) +ISL_DECLARE_EXPORTED_LIST_FN(ast_node) + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/external/mit/isl/dist/include/isl/ast_build.h b/external/mit/isl/dist/include/isl/ast_build.h new file mode 100644 index 000000000000..0029cd5bec7b --- /dev/null +++ b/external/mit/isl/dist/include/isl/ast_build.h @@ -0,0 +1,131 @@ +#ifndef ISL_AST_BUILD_H +#define ISL_AST_BUILD_H + +#include +#include +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +struct __isl_export isl_ast_build; +typedef struct isl_ast_build isl_ast_build; + + +isl_stat isl_options_set_ast_build_atomic_upper_bound(isl_ctx *ctx, int val); +int isl_options_get_ast_build_atomic_upper_bound(isl_ctx *ctx); + +isl_stat isl_options_set_ast_build_prefer_pdiv(isl_ctx *ctx, int val); +int isl_options_get_ast_build_prefer_pdiv(isl_ctx *ctx); + +isl_stat isl_options_set_ast_build_detect_min_max(isl_ctx *ctx, int val); +int isl_options_get_ast_build_detect_min_max(isl_ctx *ctx); + +isl_stat isl_options_set_ast_build_exploit_nested_bounds(isl_ctx *ctx, int val); +int isl_options_get_ast_build_exploit_nested_bounds(isl_ctx *ctx); + +isl_stat isl_options_set_ast_build_group_coscheduled(isl_ctx *ctx, int val); +int isl_options_get_ast_build_group_coscheduled(isl_ctx *ctx); + +#define ISL_AST_BUILD_SEPARATION_BOUNDS_EXPLICIT 0 +#define ISL_AST_BUILD_SEPARATION_BOUNDS_IMPLICIT 1 +isl_stat isl_options_set_ast_build_separation_bounds(isl_ctx *ctx, int val); +int isl_options_get_ast_build_separation_bounds(isl_ctx *ctx); + +isl_stat isl_options_set_ast_build_scale_strides(isl_ctx *ctx, int val); +int isl_options_get_ast_build_scale_strides(isl_ctx *ctx); + +isl_stat isl_options_set_ast_build_allow_else(isl_ctx *ctx, int val); +int isl_options_get_ast_build_allow_else(isl_ctx *ctx); + +isl_stat isl_options_set_ast_build_allow_or(isl_ctx *ctx, int val); +int isl_options_get_ast_build_allow_or(isl_ctx *ctx); + +isl_ctx *isl_ast_build_get_ctx(__isl_keep isl_ast_build *build); + +__isl_constructor +__isl_give isl_ast_build *isl_ast_build_alloc(isl_ctx *ctx); +__isl_export +__isl_give isl_ast_build *isl_ast_build_from_context(__isl_take isl_set *set); + +__isl_give isl_space *isl_ast_build_get_schedule_space( + __isl_keep isl_ast_build *build); +__isl_export +__isl_give isl_union_map *isl_ast_build_get_schedule( + __isl_keep isl_ast_build *build); + +__isl_give isl_ast_build *isl_ast_build_restrict( + __isl_take isl_ast_build *build, __isl_take isl_set *set); + +__isl_give isl_ast_build *isl_ast_build_copy( + __isl_keep isl_ast_build *build); +__isl_null isl_ast_build *isl_ast_build_free( + __isl_take isl_ast_build *build); + +__isl_give isl_ast_build *isl_ast_build_set_options( + __isl_take isl_ast_build *build, + __isl_take isl_union_map *options); +__isl_give isl_ast_build *isl_ast_build_set_iterators( + __isl_take isl_ast_build *build, + __isl_take isl_id_list *iterators); +__isl_export +__isl_give isl_ast_build *isl_ast_build_set_at_each_domain( + __isl_take isl_ast_build *build, + __isl_give isl_ast_node *(*fn)(__isl_take isl_ast_node *node, + __isl_keep isl_ast_build *build, void *user), void *user); +__isl_give isl_ast_build *isl_ast_build_set_before_each_for( + __isl_take isl_ast_build *build, + __isl_give isl_id *(*fn)(__isl_keep isl_ast_build *build, + void *user), void *user); +__isl_give isl_ast_build *isl_ast_build_set_after_each_for( + __isl_take isl_ast_build *build, + __isl_give isl_ast_node *(*fn)(__isl_take isl_ast_node *node, + __isl_keep isl_ast_build *build, void *user), void *user); +__isl_give isl_ast_build *isl_ast_build_set_before_each_mark( + __isl_take isl_ast_build *build, + isl_stat (*fn)(__isl_keep isl_id *mark, __isl_keep isl_ast_build *build, + void *user), void *user); +__isl_give isl_ast_build *isl_ast_build_set_after_each_mark( + __isl_take isl_ast_build *build, + __isl_give isl_ast_node *(*fn)(__isl_take isl_ast_node *node, + __isl_keep isl_ast_build *build, void *user), void *user); +__isl_give isl_ast_build *isl_ast_build_set_create_leaf( + __isl_take isl_ast_build *build, + __isl_give isl_ast_node *(*fn)(__isl_take isl_ast_build *build, + void *user), void *user); + +__isl_overload +__isl_give isl_ast_expr *isl_ast_build_expr_from_set( + __isl_keep isl_ast_build *build, __isl_take isl_set *set); +__isl_overload +__isl_give isl_ast_expr *isl_ast_build_expr_from_pw_aff( + __isl_keep isl_ast_build *build, __isl_take isl_pw_aff *pa); +__isl_overload +__isl_give isl_ast_expr *isl_ast_build_access_from_pw_multi_aff( + __isl_keep isl_ast_build *build, __isl_take isl_pw_multi_aff *pma); +__isl_overload +__isl_give isl_ast_expr *isl_ast_build_access_from_multi_pw_aff( + __isl_keep isl_ast_build *build, __isl_take isl_multi_pw_aff *mpa); +__isl_overload +__isl_give isl_ast_expr *isl_ast_build_call_from_pw_multi_aff( + __isl_keep isl_ast_build *build, __isl_take isl_pw_multi_aff *pma); +__isl_overload +__isl_give isl_ast_expr *isl_ast_build_call_from_multi_pw_aff( + __isl_keep isl_ast_build *build, __isl_take isl_multi_pw_aff *mpa); + +__isl_overload +__isl_give isl_ast_node *isl_ast_build_node_from_schedule( + __isl_keep isl_ast_build *build, __isl_take isl_schedule *schedule); +__isl_export +__isl_give isl_ast_node *isl_ast_build_node_from_schedule_map( + __isl_keep isl_ast_build *build, __isl_take isl_union_map *schedule); +__isl_give isl_ast_node *isl_ast_build_ast_from_schedule( + __isl_keep isl_ast_build *build, __isl_take isl_union_map *schedule); + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/external/mit/isl/dist/include/isl/ast_type.h b/external/mit/isl/dist/include/isl/ast_type.h new file mode 100644 index 000000000000..2877b8f85510 --- /dev/null +++ b/external/mit/isl/dist/include/isl/ast_type.h @@ -0,0 +1,109 @@ +#ifndef ISL_AST_TYPE_H +#define ISL_AST_TYPE_H + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +struct __isl_export isl_ast_expr; +typedef struct isl_ast_expr isl_ast_expr; + +struct __isl_export isl_ast_node; +typedef struct isl_ast_node isl_ast_node; + +enum isl_ast_expr_op_type { + isl_ast_expr_op_error = -1, + isl_ast_expr_op_and, + isl_ast_expr_op_and_then, + isl_ast_expr_op_or, + isl_ast_expr_op_or_else, + isl_ast_expr_op_max, + isl_ast_expr_op_min, + isl_ast_expr_op_minus, + isl_ast_expr_op_add, + isl_ast_expr_op_sub, + isl_ast_expr_op_mul, + isl_ast_expr_op_div, + isl_ast_expr_op_fdiv_q, /* Round towards -infty */ + isl_ast_expr_op_pdiv_q, /* Dividend is non-negative */ + isl_ast_expr_op_pdiv_r, /* Dividend is non-negative */ + isl_ast_expr_op_zdiv_r, /* Result only compared against zero */ + isl_ast_expr_op_cond, + isl_ast_expr_op_select, + isl_ast_expr_op_eq, + isl_ast_expr_op_le, + isl_ast_expr_op_lt, + isl_ast_expr_op_ge, + isl_ast_expr_op_gt, + isl_ast_expr_op_call, + isl_ast_expr_op_access, + isl_ast_expr_op_member, + isl_ast_expr_op_address_of +}; + +#define isl_ast_op_type isl_ast_expr_op_type +#define isl_ast_op_error isl_ast_expr_op_error +#define isl_ast_op_and isl_ast_expr_op_and +#define isl_ast_op_and_then isl_ast_expr_op_and_then +#define isl_ast_op_or isl_ast_expr_op_or +#define isl_ast_op_or_else isl_ast_expr_op_or_else +#define isl_ast_op_max isl_ast_expr_op_max +#define isl_ast_op_min isl_ast_expr_op_min +#define isl_ast_op_minus isl_ast_expr_op_minus +#define isl_ast_op_add isl_ast_expr_op_add +#define isl_ast_op_sub isl_ast_expr_op_sub +#define isl_ast_op_mul isl_ast_expr_op_mul +#define isl_ast_op_div isl_ast_expr_op_div +#define isl_ast_op_fdiv_q isl_ast_expr_op_fdiv_q +#define isl_ast_op_pdiv_q isl_ast_expr_op_pdiv_q +#define isl_ast_op_pdiv_r isl_ast_expr_op_pdiv_r +#define isl_ast_op_zdiv_r isl_ast_expr_op_zdiv_r +#define isl_ast_op_cond isl_ast_expr_op_cond +#define isl_ast_op_select isl_ast_expr_op_select +#define isl_ast_op_eq isl_ast_expr_op_eq +#define isl_ast_op_le isl_ast_expr_op_le +#define isl_ast_op_lt isl_ast_expr_op_lt +#define isl_ast_op_ge isl_ast_expr_op_ge +#define isl_ast_op_gt isl_ast_expr_op_gt +#define isl_ast_op_call isl_ast_expr_op_call +#define isl_ast_op_access isl_ast_expr_op_access +#define isl_ast_op_member isl_ast_expr_op_member +#define isl_ast_op_address_of isl_ast_expr_op_address_of + +enum isl_ast_expr_type { + isl_ast_expr_error = -1, + isl_ast_expr_op, + isl_ast_expr_id, + isl_ast_expr_int +}; + +enum isl_ast_node_type { + isl_ast_node_error = -1, + isl_ast_node_for = 1, + isl_ast_node_if, + isl_ast_node_block, + isl_ast_node_mark, + isl_ast_node_user +}; + +enum isl_ast_loop_type { + isl_ast_loop_error = -1, + isl_ast_loop_default = 0, + isl_ast_loop_atomic, + isl_ast_loop_unroll, + isl_ast_loop_separate +}; + +struct isl_ast_print_options; +typedef struct isl_ast_print_options isl_ast_print_options; + +ISL_DECLARE_LIST_TYPE(ast_expr) +ISL_DECLARE_EXPORTED_LIST_TYPE(ast_node) + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/external/mit/isl/dist/include/isl/constraint.h b/external/mit/isl/dist/include/isl/constraint.h new file mode 100644 index 000000000000..a8b1611220f2 --- /dev/null +++ b/external/mit/isl/dist/include/isl/constraint.h @@ -0,0 +1,148 @@ +/* + * 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_CONSTRAINT_H +#define ISL_CONSTRAINT_H + +#include +#include +#include +#include +#include +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +struct isl_constraint; +typedef struct isl_constraint isl_constraint; + +ISL_DECLARE_LIST(constraint) + +isl_ctx *isl_constraint_get_ctx(__isl_keep isl_constraint *c); + +__isl_give isl_constraint *isl_constraint_alloc_equality( + __isl_take isl_local_space *ls); +__isl_give isl_constraint *isl_constraint_alloc_inequality( + __isl_take isl_local_space *ls); +__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); + +__isl_give isl_constraint *isl_constraint_copy(__isl_keep isl_constraint *c); +__isl_null isl_constraint *isl_constraint_free(__isl_take isl_constraint *c); + +isl_size isl_basic_map_n_constraint(__isl_keep isl_basic_map *bmap); +isl_size isl_basic_set_n_constraint(__isl_keep isl_basic_set *bset); +isl_stat isl_basic_map_foreach_constraint(__isl_keep isl_basic_map *bmap, + isl_stat (*fn)(__isl_take isl_constraint *c, void *user), void *user); +isl_stat isl_basic_set_foreach_constraint(__isl_keep isl_basic_set *bset, + isl_stat (*fn)(__isl_take isl_constraint *c, void *user), void *user); +__isl_give isl_constraint_list *isl_basic_map_get_constraint_list( + __isl_keep isl_basic_map *bmap); +__isl_give isl_constraint_list *isl_basic_set_get_constraint_list( + __isl_keep isl_basic_set *bset); +int isl_constraint_is_equal(__isl_keep isl_constraint *constraint1, + __isl_keep isl_constraint *constraint2); + +isl_stat isl_basic_set_foreach_bound_pair(__isl_keep isl_basic_set *bset, + enum isl_dim_type type, unsigned pos, + isl_stat (*fn)(__isl_take isl_constraint *lower, + __isl_take isl_constraint *upper, + __isl_take isl_basic_set *bset, void *user), void *user); + +__isl_give isl_basic_map *isl_basic_map_add_constraint( + __isl_take isl_basic_map *bmap, __isl_take isl_constraint *constraint); +__isl_give isl_basic_set *isl_basic_set_add_constraint( + __isl_take isl_basic_set *bset, __isl_take isl_constraint *constraint); +__isl_give isl_map *isl_map_add_constraint(__isl_take isl_map *map, + __isl_take isl_constraint *constraint); +__isl_give isl_set *isl_set_add_constraint(__isl_take isl_set *set, + __isl_take isl_constraint *constraint); + +isl_bool isl_basic_map_has_defining_equality( + __isl_keep isl_basic_map *bmap, enum isl_dim_type type, int pos, + __isl_give isl_constraint **c); +isl_bool isl_basic_set_has_defining_equality( + struct isl_basic_set *bset, enum isl_dim_type type, int pos, + struct isl_constraint **constraint); +isl_bool isl_basic_set_has_defining_inequalities( + struct isl_basic_set *bset, enum isl_dim_type type, int pos, + struct isl_constraint **lower, + struct isl_constraint **upper); + +__isl_give isl_space *isl_constraint_get_space( + __isl_keep isl_constraint *constraint); +__isl_give isl_local_space *isl_constraint_get_local_space( + __isl_keep isl_constraint *constraint); +isl_size isl_constraint_dim(__isl_keep isl_constraint *constraint, + enum isl_dim_type type); + +isl_bool isl_constraint_involves_dims(__isl_keep isl_constraint *constraint, + enum isl_dim_type type, unsigned first, unsigned n); + +const char *isl_constraint_get_dim_name(__isl_keep isl_constraint *constraint, + enum isl_dim_type type, unsigned pos); +__isl_give isl_val *isl_constraint_get_constant_val( + __isl_keep isl_constraint *constraint); +__isl_give isl_val *isl_constraint_get_coefficient_val( + __isl_keep isl_constraint *constraint, enum isl_dim_type type, int pos); +__isl_give isl_constraint *isl_constraint_set_constant_si( + __isl_take isl_constraint *constraint, int v); +__isl_give isl_constraint *isl_constraint_set_constant_val( + __isl_take isl_constraint *constraint, __isl_take isl_val *v); +__isl_give isl_constraint *isl_constraint_set_coefficient_si( + __isl_take isl_constraint *constraint, + enum isl_dim_type type, int pos, int v); +__isl_give isl_constraint *isl_constraint_set_coefficient_val( + __isl_take isl_constraint *constraint, + enum isl_dim_type type, int pos, __isl_take isl_val *v); + +__isl_give isl_aff *isl_constraint_get_div(__isl_keep isl_constraint *constraint, + int pos); + +__isl_give isl_constraint *isl_constraint_negate( + __isl_take isl_constraint *constraint); + +isl_bool isl_constraint_is_equality(__isl_keep isl_constraint *constraint); +isl_bool isl_constraint_is_div_constraint( + __isl_keep isl_constraint *constraint); + +isl_bool isl_constraint_is_lower_bound(__isl_keep isl_constraint *constraint, + enum isl_dim_type type, unsigned pos); +isl_bool isl_constraint_is_upper_bound(__isl_keep isl_constraint *constraint, + enum isl_dim_type type, unsigned pos); + +__isl_give isl_basic_map *isl_basic_map_from_constraint( + __isl_take isl_constraint *constraint); +__isl_give isl_basic_set *isl_basic_set_from_constraint( + __isl_take isl_constraint *constraint); + +__isl_give isl_aff *isl_constraint_get_bound( + __isl_keep isl_constraint *constraint, enum isl_dim_type type, int pos); +__isl_give isl_aff *isl_constraint_get_aff( + __isl_keep isl_constraint *constraint); +__isl_give isl_constraint *isl_equality_from_aff(__isl_take isl_aff *aff); +__isl_give isl_constraint *isl_inequality_from_aff(__isl_take isl_aff *aff); + +int isl_constraint_plain_cmp(__isl_keep isl_constraint *c1, + __isl_keep isl_constraint *c2); +int isl_constraint_cmp_last_non_zero(__isl_keep isl_constraint *c1, + __isl_keep isl_constraint *c2); + +__isl_give isl_printer *isl_printer_print_constraint(__isl_take isl_printer *p, + __isl_keep isl_constraint *c); +void isl_constraint_dump(__isl_keep isl_constraint *c); + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/external/mit/isl/dist/include/isl/cpp-checked-conversion.h b/external/mit/isl/dist/include/isl/cpp-checked-conversion.h new file mode 100644 index 000000000000..4051f7808daf --- /dev/null +++ b/external/mit/isl/dist/include/isl/cpp-checked-conversion.h @@ -0,0 +1,707 @@ +/// These are automatically generated conversions between +/// the default and the checked 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_CHECKED_CONVERSION +#define ISL_CPP_CHECKED_CONVERSION + +#include +#include + +namespace isl { + +checked::aff check(aff obj) { + return checked::manage(obj.copy()); +} + +aff uncheck(checked::aff obj) { + return manage(obj.copy()); +} + +checked::aff_list check(aff_list obj) { + return checked::manage(obj.copy()); +} + +aff_list uncheck(checked::aff_list obj) { + return manage(obj.copy()); +} + +checked::ast_build check(ast_build obj) { + return checked::manage(obj.copy()); +} + +ast_build uncheck(checked::ast_build obj) { + return manage(obj.copy()); +} + +checked::ast_expr check(ast_expr obj) { + return checked::manage(obj.copy()); +} + +ast_expr uncheck(checked::ast_expr obj) { + return manage(obj.copy()); +} + +checked::ast_expr_id check(ast_expr_id obj) { + return checked::manage(obj.copy()).as(); +} + +ast_expr_id uncheck(checked::ast_expr_id obj) { + return manage(obj.copy()).as(); +} + +checked::ast_expr_int check(ast_expr_int obj) { + return checked::manage(obj.copy()).as(); +} + +ast_expr_int uncheck(checked::ast_expr_int obj) { + return manage(obj.copy()).as(); +} + +checked::ast_expr_op check(ast_expr_op obj) { + return checked::manage(obj.copy()).as(); +} + +ast_expr_op uncheck(checked::ast_expr_op obj) { + return manage(obj.copy()).as(); +} + +checked::ast_expr_op_access check(ast_expr_op_access obj) { + return checked::manage(obj.copy()).as().as(); +} + +ast_expr_op_access uncheck(checked::ast_expr_op_access obj) { + return manage(obj.copy()).as().as(); +} + +checked::ast_expr_op_add check(ast_expr_op_add obj) { + return checked::manage(obj.copy()).as().as(); +} + +ast_expr_op_add uncheck(checked::ast_expr_op_add obj) { + return manage(obj.copy()).as().as(); +} + +checked::ast_expr_op_address_of check(ast_expr_op_address_of obj) { + return checked::manage(obj.copy()).as().as(); +} + +ast_expr_op_address_of uncheck(checked::ast_expr_op_address_of obj) { + return manage(obj.copy()).as().as(); +} + +checked::ast_expr_op_and check(ast_expr_op_and obj) { + return checked::manage(obj.copy()).as().as(); +} + +ast_expr_op_and uncheck(checked::ast_expr_op_and obj) { + return manage(obj.copy()).as().as(); +} + +checked::ast_expr_op_and_then check(ast_expr_op_and_then obj) { + return checked::manage(obj.copy()).as().as(); +} + +ast_expr_op_and_then uncheck(checked::ast_expr_op_and_then obj) { + return manage(obj.copy()).as().as(); +} + +checked::ast_expr_op_call check(ast_expr_op_call obj) { + return checked::manage(obj.copy()).as().as(); +} + +ast_expr_op_call uncheck(checked::ast_expr_op_call obj) { + return manage(obj.copy()).as().as(); +} + +checked::ast_expr_op_cond check(ast_expr_op_cond obj) { + return checked::manage(obj.copy()).as().as(); +} + +ast_expr_op_cond uncheck(checked::ast_expr_op_cond obj) { + return manage(obj.copy()).as().as(); +} + +checked::ast_expr_op_div check(ast_expr_op_div obj) { + return checked::manage(obj.copy()).as().as(); +} + +ast_expr_op_div uncheck(checked::ast_expr_op_div obj) { + return manage(obj.copy()).as().as(); +} + +checked::ast_expr_op_eq check(ast_expr_op_eq obj) { + return checked::manage(obj.copy()).as().as(); +} + +ast_expr_op_eq uncheck(checked::ast_expr_op_eq obj) { + return manage(obj.copy()).as().as(); +} + +checked::ast_expr_op_fdiv_q check(ast_expr_op_fdiv_q obj) { + return checked::manage(obj.copy()).as().as(); +} + +ast_expr_op_fdiv_q uncheck(checked::ast_expr_op_fdiv_q obj) { + return manage(obj.copy()).as().as(); +} + +checked::ast_expr_op_ge check(ast_expr_op_ge obj) { + return checked::manage(obj.copy()).as().as(); +} + +ast_expr_op_ge uncheck(checked::ast_expr_op_ge obj) { + return manage(obj.copy()).as().as(); +} + +checked::ast_expr_op_gt check(ast_expr_op_gt obj) { + return checked::manage(obj.copy()).as().as(); +} + +ast_expr_op_gt uncheck(checked::ast_expr_op_gt obj) { + return manage(obj.copy()).as().as(); +} + +checked::ast_expr_op_le check(ast_expr_op_le obj) { + return checked::manage(obj.copy()).as().as(); +} + +ast_expr_op_le uncheck(checked::ast_expr_op_le obj) { + return manage(obj.copy()).as().as(); +} + +checked::ast_expr_op_lt check(ast_expr_op_lt obj) { + return checked::manage(obj.copy()).as().as(); +} + +ast_expr_op_lt uncheck(checked::ast_expr_op_lt obj) { + return manage(obj.copy()).as().as(); +} + +checked::ast_expr_op_max check(ast_expr_op_max obj) { + return checked::manage(obj.copy()).as().as(); +} + +ast_expr_op_max uncheck(checked::ast_expr_op_max obj) { + return manage(obj.copy()).as().as(); +} + +checked::ast_expr_op_member check(ast_expr_op_member obj) { + return checked::manage(obj.copy()).as().as(); +} + +ast_expr_op_member uncheck(checked::ast_expr_op_member obj) { + return manage(obj.copy()).as().as(); +} + +checked::ast_expr_op_min check(ast_expr_op_min obj) { + return checked::manage(obj.copy()).as().as(); +} + +ast_expr_op_min uncheck(checked::ast_expr_op_min obj) { + return manage(obj.copy()).as().as(); +} + +checked::ast_expr_op_minus check(ast_expr_op_minus obj) { + return checked::manage(obj.copy()).as().as(); +} + +ast_expr_op_minus uncheck(checked::ast_expr_op_minus obj) { + return manage(obj.copy()).as().as(); +} + +checked::ast_expr_op_mul check(ast_expr_op_mul obj) { + return checked::manage(obj.copy()).as().as(); +} + +ast_expr_op_mul uncheck(checked::ast_expr_op_mul obj) { + return manage(obj.copy()).as().as(); +} + +checked::ast_expr_op_or check(ast_expr_op_or obj) { + return checked::manage(obj.copy()).as().as(); +} + +ast_expr_op_or uncheck(checked::ast_expr_op_or obj) { + return manage(obj.copy()).as().as(); +} + +checked::ast_expr_op_or_else check(ast_expr_op_or_else obj) { + return checked::manage(obj.copy()).as().as(); +} + +ast_expr_op_or_else uncheck(checked::ast_expr_op_or_else obj) { + return manage(obj.copy()).as().as(); +} + +checked::ast_expr_op_pdiv_q check(ast_expr_op_pdiv_q obj) { + return checked::manage(obj.copy()).as().as(); +} + +ast_expr_op_pdiv_q uncheck(checked::ast_expr_op_pdiv_q obj) { + return manage(obj.copy()).as().as(); +} + +checked::ast_expr_op_pdiv_r check(ast_expr_op_pdiv_r obj) { + return checked::manage(obj.copy()).as().as(); +} + +ast_expr_op_pdiv_r uncheck(checked::ast_expr_op_pdiv_r obj) { + return manage(obj.copy()).as().as(); +} + +checked::ast_expr_op_select check(ast_expr_op_select obj) { + return checked::manage(obj.copy()).as().as(); +} + +ast_expr_op_select uncheck(checked::ast_expr_op_select obj) { + return manage(obj.copy()).as().as(); +} + +checked::ast_expr_op_sub check(ast_expr_op_sub obj) { + return checked::manage(obj.copy()).as().as(); +} + +ast_expr_op_sub uncheck(checked::ast_expr_op_sub obj) { + return manage(obj.copy()).as().as(); +} + +checked::ast_expr_op_zdiv_r check(ast_expr_op_zdiv_r obj) { + return checked::manage(obj.copy()).as().as(); +} + +ast_expr_op_zdiv_r uncheck(checked::ast_expr_op_zdiv_r obj) { + return manage(obj.copy()).as().as(); +} + +checked::ast_node check(ast_node obj) { + return checked::manage(obj.copy()); +} + +ast_node uncheck(checked::ast_node obj) { + return manage(obj.copy()); +} + +checked::ast_node_block check(ast_node_block obj) { + return checked::manage(obj.copy()).as(); +} + +ast_node_block uncheck(checked::ast_node_block obj) { + return manage(obj.copy()).as(); +} + +checked::ast_node_for check(ast_node_for obj) { + return checked::manage(obj.copy()).as(); +} + +ast_node_for uncheck(checked::ast_node_for obj) { + return manage(obj.copy()).as(); +} + +checked::ast_node_if check(ast_node_if obj) { + return checked::manage(obj.copy()).as(); +} + +ast_node_if uncheck(checked::ast_node_if obj) { + return manage(obj.copy()).as(); +} + +checked::ast_node_list check(ast_node_list obj) { + return checked::manage(obj.copy()); +} + +ast_node_list uncheck(checked::ast_node_list obj) { + return manage(obj.copy()); +} + +checked::ast_node_mark check(ast_node_mark obj) { + return checked::manage(obj.copy()).as(); +} + +ast_node_mark uncheck(checked::ast_node_mark obj) { + return manage(obj.copy()).as(); +} + +checked::ast_node_user check(ast_node_user obj) { + return checked::manage(obj.copy()).as(); +} + +ast_node_user uncheck(checked::ast_node_user obj) { + return manage(obj.copy()).as(); +} + +checked::basic_map check(basic_map obj) { + return checked::manage(obj.copy()); +} + +basic_map uncheck(checked::basic_map obj) { + return manage(obj.copy()); +} + +checked::basic_set check(basic_set obj) { + return checked::manage(obj.copy()); +} + +basic_set uncheck(checked::basic_set obj) { + return manage(obj.copy()); +} + +checked::fixed_box check(fixed_box obj) { + return checked::manage(obj.copy()); +} + +fixed_box uncheck(checked::fixed_box obj) { + return manage(obj.copy()); +} + +checked::id check(id obj) { + return checked::manage(obj.copy()); +} + +id uncheck(checked::id obj) { + return manage(obj.copy()); +} + +checked::id_list check(id_list obj) { + return checked::manage(obj.copy()); +} + +id_list uncheck(checked::id_list obj) { + return manage(obj.copy()); +} + +checked::id_to_ast_expr check(id_to_ast_expr obj) { + return checked::manage(obj.copy()); +} + +id_to_ast_expr uncheck(checked::id_to_ast_expr obj) { + return manage(obj.copy()); +} + +checked::id_to_id check(id_to_id obj) { + return checked::manage(obj.copy()); +} + +id_to_id uncheck(checked::id_to_id obj) { + return manage(obj.copy()); +} + +checked::map check(map obj) { + return checked::manage(obj.copy()); +} + +map uncheck(checked::map obj) { + return manage(obj.copy()); +} + +checked::map_list check(map_list obj) { + return checked::manage(obj.copy()); +} + +map_list uncheck(checked::map_list obj) { + return manage(obj.copy()); +} + +checked::multi_aff check(multi_aff obj) { + return checked::manage(obj.copy()); +} + +multi_aff uncheck(checked::multi_aff obj) { + return manage(obj.copy()); +} + +checked::multi_id check(multi_id obj) { + return checked::manage(obj.copy()); +} + +multi_id uncheck(checked::multi_id obj) { + return manage(obj.copy()); +} + +checked::multi_pw_aff check(multi_pw_aff obj) { + return checked::manage(obj.copy()); +} + +multi_pw_aff uncheck(checked::multi_pw_aff obj) { + return manage(obj.copy()); +} + +checked::multi_union_pw_aff check(multi_union_pw_aff obj) { + return checked::manage(obj.copy()); +} + +multi_union_pw_aff uncheck(checked::multi_union_pw_aff obj) { + return manage(obj.copy()); +} + +checked::multi_val check(multi_val obj) { + return checked::manage(obj.copy()); +} + +multi_val uncheck(checked::multi_val obj) { + return manage(obj.copy()); +} + +checked::point check(point obj) { + return checked::manage(obj.copy()); +} + +point uncheck(checked::point obj) { + return manage(obj.copy()); +} + +checked::pw_aff check(pw_aff obj) { + return checked::manage(obj.copy()); +} + +pw_aff uncheck(checked::pw_aff obj) { + return manage(obj.copy()); +} + +checked::pw_aff_list check(pw_aff_list obj) { + return checked::manage(obj.copy()); +} + +pw_aff_list uncheck(checked::pw_aff_list obj) { + return manage(obj.copy()); +} + +checked::pw_multi_aff check(pw_multi_aff obj) { + return checked::manage(obj.copy()); +} + +pw_multi_aff uncheck(checked::pw_multi_aff obj) { + return manage(obj.copy()); +} + +checked::pw_multi_aff_list check(pw_multi_aff_list obj) { + return checked::manage(obj.copy()); +} + +pw_multi_aff_list uncheck(checked::pw_multi_aff_list obj) { + return manage(obj.copy()); +} + +checked::schedule check(schedule obj) { + return checked::manage(obj.copy()); +} + +schedule uncheck(checked::schedule obj) { + return manage(obj.copy()); +} + +checked::schedule_constraints check(schedule_constraints obj) { + return checked::manage(obj.copy()); +} + +schedule_constraints uncheck(checked::schedule_constraints obj) { + return manage(obj.copy()); +} + +checked::schedule_node check(schedule_node obj) { + return checked::manage(obj.copy()); +} + +schedule_node uncheck(checked::schedule_node obj) { + return manage(obj.copy()); +} + +checked::schedule_node_band check(schedule_node_band obj) { + return checked::manage(obj.copy()).as(); +} + +schedule_node_band uncheck(checked::schedule_node_band obj) { + return manage(obj.copy()).as(); +} + +checked::schedule_node_context check(schedule_node_context obj) { + return checked::manage(obj.copy()).as(); +} + +schedule_node_context uncheck(checked::schedule_node_context obj) { + return manage(obj.copy()).as(); +} + +checked::schedule_node_domain check(schedule_node_domain obj) { + return checked::manage(obj.copy()).as(); +} + +schedule_node_domain uncheck(checked::schedule_node_domain obj) { + return manage(obj.copy()).as(); +} + +checked::schedule_node_expansion check(schedule_node_expansion obj) { + return checked::manage(obj.copy()).as(); +} + +schedule_node_expansion uncheck(checked::schedule_node_expansion obj) { + return manage(obj.copy()).as(); +} + +checked::schedule_node_extension check(schedule_node_extension obj) { + return checked::manage(obj.copy()).as(); +} + +schedule_node_extension uncheck(checked::schedule_node_extension obj) { + return manage(obj.copy()).as(); +} + +checked::schedule_node_filter check(schedule_node_filter obj) { + return checked::manage(obj.copy()).as(); +} + +schedule_node_filter uncheck(checked::schedule_node_filter obj) { + return manage(obj.copy()).as(); +} + +checked::schedule_node_guard check(schedule_node_guard obj) { + return checked::manage(obj.copy()).as(); +} + +schedule_node_guard uncheck(checked::schedule_node_guard obj) { + return manage(obj.copy()).as(); +} + +checked::schedule_node_leaf check(schedule_node_leaf obj) { + return checked::manage(obj.copy()).as(); +} + +schedule_node_leaf uncheck(checked::schedule_node_leaf obj) { + return manage(obj.copy()).as(); +} + +checked::schedule_node_mark check(schedule_node_mark obj) { + return checked::manage(obj.copy()).as(); +} + +schedule_node_mark uncheck(checked::schedule_node_mark obj) { + return manage(obj.copy()).as(); +} + +checked::schedule_node_sequence check(schedule_node_sequence obj) { + return checked::manage(obj.copy()).as(); +} + +schedule_node_sequence uncheck(checked::schedule_node_sequence obj) { + return manage(obj.copy()).as(); +} + +checked::schedule_node_set check(schedule_node_set obj) { + return checked::manage(obj.copy()).as(); +} + +schedule_node_set uncheck(checked::schedule_node_set obj) { + return manage(obj.copy()).as(); +} + +checked::set check(set obj) { + return checked::manage(obj.copy()); +} + +set uncheck(checked::set obj) { + return manage(obj.copy()); +} + +checked::set_list check(set_list obj) { + return checked::manage(obj.copy()); +} + +set_list uncheck(checked::set_list obj) { + return manage(obj.copy()); +} + +checked::space check(space obj) { + return checked::manage(obj.copy()); +} + +space uncheck(checked::space obj) { + return manage(obj.copy()); +} + +checked::union_access_info check(union_access_info obj) { + return checked::manage(obj.copy()); +} + +union_access_info uncheck(checked::union_access_info obj) { + return manage(obj.copy()); +} + +checked::union_flow check(union_flow obj) { + return checked::manage(obj.copy()); +} + +union_flow uncheck(checked::union_flow obj) { + return manage(obj.copy()); +} + +checked::union_map check(union_map obj) { + return checked::manage(obj.copy()); +} + +union_map uncheck(checked::union_map obj) { + return manage(obj.copy()); +} + +checked::union_pw_aff check(union_pw_aff obj) { + return checked::manage(obj.copy()); +} + +union_pw_aff uncheck(checked::union_pw_aff obj) { + return manage(obj.copy()); +} + +checked::union_pw_aff_list check(union_pw_aff_list obj) { + return checked::manage(obj.copy()); +} + +union_pw_aff_list uncheck(checked::union_pw_aff_list obj) { + return manage(obj.copy()); +} + +checked::union_pw_multi_aff check(union_pw_multi_aff obj) { + return checked::manage(obj.copy()); +} + +union_pw_multi_aff uncheck(checked::union_pw_multi_aff obj) { + return manage(obj.copy()); +} + +checked::union_set check(union_set obj) { + return checked::manage(obj.copy()); +} + +union_set uncheck(checked::union_set obj) { + return manage(obj.copy()); +} + +checked::union_set_list check(union_set_list obj) { + return checked::manage(obj.copy()); +} + +union_set_list uncheck(checked::union_set_list obj) { + return manage(obj.copy()); +} + +checked::val check(val obj) { + return checked::manage(obj.copy()); +} + +val uncheck(checked::val obj) { + return manage(obj.copy()); +} + +checked::val_list check(val_list obj) { + return checked::manage(obj.copy()); +} + +val_list uncheck(checked::val_list obj) { + return manage(obj.copy()); +} + +} // namespace isl + +#endif /* ISL_CPP_CHECKED_CONVERSION */ diff --git a/external/mit/isl/dist/include/isl/cpp-checked.h b/external/mit/isl/dist/include/isl/cpp-checked.h new file mode 100644 index 000000000000..e2fa6a7648b1 --- /dev/null +++ b/external/mit/isl/dist/include/isl/cpp-checked.h @@ -0,0 +1,21179 @@ +/// These are automatically generated checked 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_CHECKED +#define ISL_CPP_CHECKED + +#include +#include + +#include +#include +#include +#include +#include + +#if __cplusplus >= 201703L +#include +#include +#endif + +namespace isl { +namespace checked { + +#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); \ + abort(); \ + } while (0) + +/* Class used to check that isl::checked::boolean, + * isl::checked::stat and isl::checked::size values are checked for errors. + */ +struct checker { + bool checked = false; + ~checker() { + ISLPP_ASSERT(checked, "IMPLEMENTATION ERROR: Unchecked state"); + } +}; + +class boolean { +private: + mutable std::shared_ptr check = std::make_shared(); + isl_bool val; + + friend boolean manage(isl_bool val); + boolean(isl_bool val): val(val) {} +public: + static boolean error() { + return boolean(isl_bool_error); + } + boolean() + : val(isl_bool_error) {} + + /* implicit */ boolean(bool val) + : val(val ? isl_bool_true : isl_bool_false) {} + + isl_bool release() { + auto tmp = val; + val = isl_bool_error; + check->checked = true; + return tmp; + } + + bool is_error() const { check->checked = true; return val == isl_bool_error; } + bool is_false() const { check->checked = true; return val == isl_bool_false; } + bool is_true() const { check->checked = true; return val == isl_bool_true; } + + explicit operator bool() const { + ISLPP_ASSERT(check->checked, "IMPLEMENTATION ERROR: Unchecked error state"); + ISLPP_ASSERT(!is_error(), "IMPLEMENTATION ERROR: Unhandled error state"); + return is_true(); + } + + boolean negate() { + if (val == isl_bool_true) + val = isl_bool_false; + else if (val == isl_bool_false) + val = isl_bool_true; + return *this; + } + + boolean operator!() const { + return boolean(*this).negate(); + } +}; + +inline boolean manage(isl_bool val) { + return 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; + } +#if __cplusplus >= 201703L + static void free_user(void *user) { + std::any *p = static_cast(user); + delete p; + } +#endif +}; + +/* Class encapsulating an isl_stat value. + */ +class stat { +private: + mutable std::shared_ptr check = std::make_shared(); + isl_stat val; + + friend stat manage(isl_stat val); + stat(isl_stat val) : val(val) {} +public: + static stat ok() { + return stat(isl_stat_ok); + } + static stat error() { + return stat(isl_stat_error); + } + stat() : val(isl_stat_error) {} + + isl_stat release() { + check->checked = true; + return val; + } + + bool is_error() const { + check->checked = true; + return val == isl_stat_error; + } + bool is_ok() const { + check->checked = true; + return val == isl_stat_ok; + } +}; + +inline stat manage(isl_stat val) +{ + return stat(val); +} + +/* Class encapsulating an isl_size value. + */ +class size { +private: + mutable std::shared_ptr check = std::make_shared(); + isl_size val; + + friend size manage(isl_size val); + size(isl_size val) : val(val) {} +public: + size() : val(isl_size_error) {} + + isl_size release() { + auto tmp = val; + val = isl_size_error; + check->checked = true; + return tmp; + } + + bool is_error() const { + check->checked = true; + return val == isl_size_error; + } + + explicit operator unsigned() const { + ISLPP_ASSERT(check->checked, + "IMPLEMENTATION ERROR: Unchecked error state"); + ISLPP_ASSERT(!is_error(), + "IMPLEMENTATION ERROR: Unhandled error state"); + return val; + } +}; + +inline size manage(isl_size val) +{ + return size(val); +} + +} +} // namespace isl + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace isl { + +namespace checked { + +// forward declarations +class aff; +class aff_list; +class ast_build; +class ast_expr; +class ast_expr_id; +class ast_expr_int; +class ast_expr_op; +class ast_expr_op_access; +class ast_expr_op_add; +class ast_expr_op_address_of; +class ast_expr_op_and; +class ast_expr_op_and_then; +class ast_expr_op_call; +class ast_expr_op_cond; +class ast_expr_op_div; +class ast_expr_op_eq; +class ast_expr_op_fdiv_q; +class ast_expr_op_ge; +class ast_expr_op_gt; +class ast_expr_op_le; +class ast_expr_op_lt; +class ast_expr_op_max; +class ast_expr_op_member; +class ast_expr_op_min; +class ast_expr_op_minus; +class ast_expr_op_mul; +class ast_expr_op_or; +class ast_expr_op_or_else; +class ast_expr_op_pdiv_q; +class ast_expr_op_pdiv_r; +class ast_expr_op_select; +class ast_expr_op_sub; +class ast_expr_op_zdiv_r; +class ast_node; +class ast_node_block; +class ast_node_for; +class ast_node_if; +class ast_node_list; +class ast_node_mark; +class ast_node_user; +class basic_map; +class basic_set; +class fixed_box; +class id; +class id_list; +class id_to_ast_expr; +class id_to_id; +class map; +class map_list; +class multi_aff; +class multi_id; +class multi_pw_aff; +class multi_union_pw_aff; +class multi_val; +class point; +class pw_aff; +class pw_aff_list; +class pw_multi_aff; +class pw_multi_aff_list; +class schedule; +class schedule_constraints; +class schedule_node; +class schedule_node_band; +class schedule_node_context; +class schedule_node_domain; +class schedule_node_expansion; +class schedule_node_extension; +class schedule_node_filter; +class schedule_node_guard; +class schedule_node_leaf; +class schedule_node_mark; +class schedule_node_sequence; +class schedule_node_set; +class set; +class set_list; +class space; +class union_access_info; +class union_flow; +class union_map; +class union_pw_aff; +class union_pw_aff_list; +class union_pw_multi_aff; +class union_set; +class union_set_list; +class val; +class val_list; + +// declarations for isl::aff +inline aff manage(__isl_take isl_aff *ptr); +inline aff manage_copy(__isl_keep isl_aff *ptr); + +class aff { + friend inline aff manage(__isl_take isl_aff *ptr); + friend inline aff manage_copy(__isl_keep isl_aff *ptr); + +protected: + isl_aff *ptr = nullptr; + + inline explicit aff(__isl_take isl_aff *ptr); + +public: + inline /* implicit */ aff(); + inline /* implicit */ aff(const aff &obj); + inline explicit aff(isl::checked::ctx ctx, const std::string &str); + inline aff &operator=(aff obj); + inline ~aff(); + inline __isl_give isl_aff *copy() const &; + inline __isl_give isl_aff *copy() && = delete; + inline __isl_keep isl_aff *get() const; + inline __isl_give isl_aff *release(); + inline bool is_null() const; + inline isl::checked::ctx ctx() const; + + inline isl::checked::aff add(isl::checked::aff aff2) const; + inline isl::checked::multi_aff add(const isl::checked::multi_aff &multi2) const; + inline isl::checked::multi_pw_aff add(const isl::checked::multi_pw_aff &multi2) const; + inline isl::checked::multi_union_pw_aff add(const isl::checked::multi_union_pw_aff &multi2) const; + inline isl::checked::pw_aff add(const isl::checked::pw_aff &pwaff2) const; + inline isl::checked::pw_multi_aff add(const isl::checked::pw_multi_aff &pma2) const; + inline isl::checked::union_pw_aff add(const isl::checked::union_pw_aff &upa2) const; + inline isl::checked::union_pw_multi_aff add(const isl::checked::union_pw_multi_aff &upma2) const; + inline isl::checked::aff add_constant(isl::checked::val v) const; + inline isl::checked::aff add_constant(long v) const; + inline isl::checked::multi_aff add_constant(const isl::checked::multi_val &mv) const; + inline isl::checked::union_pw_multi_aff apply(const isl::checked::union_pw_multi_aff &upma2) const; + inline isl::checked::aff as_aff() const; + inline isl::checked::map as_map() const; + inline isl::checked::multi_aff as_multi_aff() const; + inline isl::checked::multi_union_pw_aff as_multi_union_pw_aff() const; + inline isl::checked::pw_multi_aff as_pw_multi_aff() const; + inline isl::checked::set as_set() const; + inline isl::checked::union_map as_union_map() const; + inline isl::checked::aff at(int pos) const; + inline isl::checked::basic_set bind(isl::checked::id id) const; + inline isl::checked::basic_set bind(const std::string &id) const; + inline isl::checked::basic_set bind(const isl::checked::multi_id &tuple) const; + inline isl::checked::pw_aff bind_domain(const isl::checked::multi_id &tuple) const; + inline isl::checked::pw_aff bind_domain_wrapped_domain(const isl::checked::multi_id &tuple) const; + inline isl::checked::aff ceil() const; + inline isl::checked::pw_aff coalesce() const; + inline isl::checked::pw_aff cond(const isl::checked::pw_aff &pwaff_true, const isl::checked::pw_aff &pwaff_false) const; + inline isl::checked::multi_val constant_multi_val() const; + inline isl::checked::val constant_val() const; + inline isl::checked::val get_constant_val() const; + inline isl::checked::aff div(isl::checked::aff aff2) const; + inline isl::checked::pw_aff div(const isl::checked::pw_aff &pa2) const; + inline isl::checked::set domain() const; + inline isl::checked::aff domain_reverse() const; + inline isl::checked::pw_aff drop_unused_params() const; + inline isl::checked::set eq_set(isl::checked::aff aff2) const; + inline isl::checked::set eq_set(const isl::checked::pw_aff &pwaff2) const; + inline isl::checked::val eval(isl::checked::point pnt) const; + inline isl::checked::pw_multi_aff extract_pw_multi_aff(const isl::checked::space &space) const; + inline isl::checked::multi_aff flat_range_product(const isl::checked::multi_aff &multi2) const; + inline isl::checked::multi_pw_aff flat_range_product(const isl::checked::multi_pw_aff &multi2) const; + inline isl::checked::multi_union_pw_aff flat_range_product(const isl::checked::multi_union_pw_aff &multi2) const; + inline isl::checked::pw_multi_aff flat_range_product(const isl::checked::pw_multi_aff &pma2) const; + inline isl::checked::union_pw_multi_aff flat_range_product(const isl::checked::union_pw_multi_aff &upma2) const; + inline isl::checked::aff floor() const; + inline stat foreach_piece(const std::function &fn) const; + inline isl::checked::set ge_set(isl::checked::aff aff2) const; + inline isl::checked::set ge_set(const isl::checked::pw_aff &pwaff2) const; + inline isl::checked::aff gist(isl::checked::set context) const; + inline isl::checked::union_pw_aff gist(const isl::checked::union_set &context) const; + inline isl::checked::aff gist(const isl::checked::basic_set &context) const; + inline isl::checked::aff gist(const isl::checked::point &context) const; + inline isl::checked::aff gist_params(isl::checked::set context) const; + inline isl::checked::set gt_set(isl::checked::aff aff2) const; + inline isl::checked::set gt_set(const isl::checked::pw_aff &pwaff2) const; + inline boolean has_range_tuple_id() const; + inline isl::checked::multi_aff identity() const; + inline isl::checked::pw_aff insert_domain(const isl::checked::space &domain) const; + inline isl::checked::pw_aff intersect_domain(const isl::checked::set &set) const; + inline isl::checked::union_pw_aff intersect_domain(const isl::checked::space &space) const; + inline isl::checked::union_pw_aff intersect_domain(const isl::checked::union_set &uset) const; + inline isl::checked::union_pw_aff intersect_domain_wrapped_domain(const isl::checked::union_set &uset) const; + inline isl::checked::union_pw_aff intersect_domain_wrapped_range(const isl::checked::union_set &uset) const; + inline isl::checked::pw_aff intersect_params(const isl::checked::set &set) const; + inline boolean involves_locals() const; + inline boolean involves_nan() const; + inline boolean involves_param(const isl::checked::id &id) const; + inline boolean involves_param(const std::string &id) const; + inline boolean involves_param(const isl::checked::id_list &list) const; + inline boolean is_cst() const; + inline boolean isa_aff() const; + inline boolean isa_multi_aff() const; + inline boolean isa_pw_multi_aff() const; + inline isl::checked::set le_set(isl::checked::aff aff2) const; + inline isl::checked::set le_set(const isl::checked::pw_aff &pwaff2) const; + inline isl::checked::aff_list list() const; + inline isl::checked::set lt_set(isl::checked::aff aff2) const; + inline isl::checked::set lt_set(const isl::checked::pw_aff &pwaff2) const; + inline isl::checked::multi_pw_aff max(const isl::checked::multi_pw_aff &multi2) const; + inline isl::checked::pw_aff max(const isl::checked::pw_aff &pwaff2) const; + inline isl::checked::multi_val max_multi_val() const; + inline isl::checked::val max_val() const; + inline isl::checked::multi_pw_aff min(const isl::checked::multi_pw_aff &multi2) const; + inline isl::checked::pw_aff min(const isl::checked::pw_aff &pwaff2) const; + inline isl::checked::multi_val min_multi_val() const; + inline isl::checked::val min_val() const; + inline isl::checked::aff mod(isl::checked::val mod) const; + inline isl::checked::aff mod(long mod) const; + inline isl::checked::aff mul(isl::checked::aff aff2) const; + inline isl::checked::pw_aff mul(const isl::checked::pw_aff &pwaff2) const; + inline class size n_piece() const; + inline isl::checked::set ne_set(isl::checked::aff aff2) const; + inline isl::checked::set ne_set(const isl::checked::pw_aff &pwaff2) const; + inline isl::checked::aff neg() const; + inline isl::checked::set params() const; + inline boolean plain_is_empty() const; + inline boolean plain_is_equal(const isl::checked::aff &aff2) const; + inline boolean plain_is_equal(const isl::checked::multi_aff &multi2) const; + inline boolean plain_is_equal(const isl::checked::multi_pw_aff &multi2) const; + inline boolean plain_is_equal(const isl::checked::multi_union_pw_aff &multi2) const; + inline boolean plain_is_equal(const isl::checked::pw_aff &pwaff2) const; + inline boolean plain_is_equal(const isl::checked::pw_multi_aff &pma2) const; + inline boolean plain_is_equal(const isl::checked::union_pw_aff &upa2) const; + inline boolean plain_is_equal(const isl::checked::union_pw_multi_aff &upma2) const; + inline isl::checked::pw_multi_aff preimage_domain_wrapped_domain(const isl::checked::pw_multi_aff &pma2) const; + inline isl::checked::union_pw_multi_aff preimage_domain_wrapped_domain(const isl::checked::union_pw_multi_aff &upma2) const; + inline isl::checked::multi_aff product(const isl::checked::multi_aff &multi2) const; + inline isl::checked::multi_pw_aff product(const isl::checked::multi_pw_aff &multi2) const; + inline isl::checked::pw_multi_aff product(const isl::checked::pw_multi_aff &pma2) const; + inline isl::checked::aff pullback(isl::checked::multi_aff ma) const; + inline isl::checked::pw_aff pullback(const isl::checked::multi_pw_aff &mpa) const; + inline isl::checked::pw_aff pullback(const isl::checked::pw_multi_aff &pma) const; + inline isl::checked::union_pw_aff pullback(const isl::checked::union_pw_multi_aff &upma) const; + inline isl::checked::aff pullback(const isl::checked::aff &ma) const; + inline isl::checked::pw_multi_aff_list pw_multi_aff_list() const; + inline isl::checked::pw_multi_aff range_factor_domain() const; + inline isl::checked::pw_multi_aff range_factor_range() const; + inline isl::checked::multi_aff range_product(const isl::checked::multi_aff &multi2) const; + inline isl::checked::multi_pw_aff range_product(const isl::checked::multi_pw_aff &multi2) const; + inline isl::checked::multi_union_pw_aff range_product(const isl::checked::multi_union_pw_aff &multi2) const; + inline isl::checked::pw_multi_aff range_product(const isl::checked::pw_multi_aff &pma2) const; + inline isl::checked::union_pw_multi_aff range_product(const isl::checked::union_pw_multi_aff &upma2) const; + inline isl::checked::id range_tuple_id() const; + inline isl::checked::multi_aff reset_range_tuple_id() const; + inline isl::checked::aff scale(isl::checked::val v) const; + inline isl::checked::aff scale(long v) const; + inline isl::checked::multi_aff scale(const isl::checked::multi_val &mv) const; + inline isl::checked::aff scale_down(isl::checked::val v) const; + inline isl::checked::aff scale_down(long v) const; + inline isl::checked::multi_aff scale_down(const isl::checked::multi_val &mv) const; + inline isl::checked::multi_aff set_at(int pos, const isl::checked::aff &el) const; + inline isl::checked::multi_pw_aff set_at(int pos, const isl::checked::pw_aff &el) const; + inline isl::checked::multi_union_pw_aff set_at(int pos, const isl::checked::union_pw_aff &el) const; + inline isl::checked::multi_aff set_range_tuple(const isl::checked::id &id) const; + inline isl::checked::multi_aff set_range_tuple(const std::string &id) const; + inline class size size() const; + inline isl::checked::space space() const; + inline isl::checked::aff sub(isl::checked::aff aff2) const; + inline isl::checked::multi_aff sub(const isl::checked::multi_aff &multi2) const; + inline isl::checked::multi_pw_aff sub(const isl::checked::multi_pw_aff &multi2) const; + inline isl::checked::multi_union_pw_aff sub(const isl::checked::multi_union_pw_aff &multi2) const; + inline isl::checked::pw_aff sub(const isl::checked::pw_aff &pwaff2) const; + inline isl::checked::pw_multi_aff sub(const isl::checked::pw_multi_aff &pma2) const; + inline isl::checked::union_pw_aff sub(const isl::checked::union_pw_aff &upa2) const; + inline isl::checked::union_pw_multi_aff sub(const isl::checked::union_pw_multi_aff &upma2) const; + inline isl::checked::pw_aff subtract_domain(const isl::checked::set &set) const; + inline isl::checked::union_pw_aff subtract_domain(const isl::checked::space &space) const; + inline isl::checked::union_pw_aff subtract_domain(const isl::checked::union_set &uset) const; + inline isl::checked::pw_aff tdiv_q(const isl::checked::pw_aff &pa2) const; + inline isl::checked::pw_aff tdiv_r(const isl::checked::pw_aff &pa2) const; + inline isl::checked::aff_list to_list() const; + inline isl::checked::multi_pw_aff to_multi_pw_aff() const; + inline isl::checked::multi_union_pw_aff to_multi_union_pw_aff() const; + inline isl::checked::pw_multi_aff to_pw_multi_aff() const; + inline isl::checked::union_pw_aff to_union_pw_aff() const; + inline isl::checked::union_pw_multi_aff to_union_pw_multi_aff() const; + inline isl::checked::aff unbind_params_insert_domain(isl::checked::multi_id domain) const; + inline isl::checked::multi_pw_aff union_add(const isl::checked::multi_pw_aff &mpa2) const; + inline isl::checked::multi_union_pw_aff union_add(const isl::checked::multi_union_pw_aff &mupa2) const; + inline isl::checked::pw_aff union_add(const isl::checked::pw_aff &pwaff2) const; + inline isl::checked::pw_multi_aff union_add(const isl::checked::pw_multi_aff &pma2) const; + inline isl::checked::union_pw_aff union_add(const isl::checked::union_pw_aff &upa2) const; + inline isl::checked::union_pw_multi_aff union_add(const isl::checked::union_pw_multi_aff &upma2) const; + static inline isl::checked::aff zero_on_domain(isl::checked::space space); +}; + +// declarations for isl::aff_list +inline aff_list manage(__isl_take isl_aff_list *ptr); +inline aff_list manage_copy(__isl_keep isl_aff_list *ptr); + +class aff_list { + friend inline aff_list manage(__isl_take isl_aff_list *ptr); + friend inline aff_list manage_copy(__isl_keep isl_aff_list *ptr); + +protected: + isl_aff_list *ptr = nullptr; + + inline explicit aff_list(__isl_take isl_aff_list *ptr); + +public: + inline /* implicit */ aff_list(); + inline /* implicit */ aff_list(const aff_list &obj); + inline explicit aff_list(isl::checked::ctx ctx, int n); + inline explicit aff_list(isl::checked::aff el); + inline explicit aff_list(isl::checked::ctx ctx, const std::string &str); + inline aff_list &operator=(aff_list obj); + inline ~aff_list(); + inline __isl_give isl_aff_list *copy() const &; + inline __isl_give isl_aff_list *copy() && = delete; + inline __isl_keep isl_aff_list *get() const; + inline __isl_give isl_aff_list *release(); + inline bool is_null() const; + inline isl::checked::ctx ctx() const; + + inline isl::checked::aff_list add(isl::checked::aff el) const; + inline isl::checked::aff at(int index) const; + inline isl::checked::aff get_at(int index) const; + inline isl::checked::aff_list clear() const; + inline isl::checked::aff_list concat(isl::checked::aff_list list2) const; + inline isl::checked::aff_list drop(unsigned int first, unsigned int n) const; + inline stat foreach(const std::function &fn) const; + inline stat foreach_scc(const std::function &follows, const std::function &fn) const; + inline isl::checked::aff_list insert(unsigned int pos, isl::checked::aff el) const; + inline isl::checked::aff_list set_at(int index, isl::checked::aff el) const; + inline class size size() const; +}; + +// declarations for isl::ast_build +inline ast_build manage(__isl_take isl_ast_build *ptr); +inline ast_build manage_copy(__isl_keep isl_ast_build *ptr); + +class ast_build { + friend inline ast_build manage(__isl_take isl_ast_build *ptr); + friend inline ast_build manage_copy(__isl_keep isl_ast_build *ptr); + +protected: + isl_ast_build *ptr = nullptr; + + inline explicit ast_build(__isl_take isl_ast_build *ptr); + +public: + inline /* implicit */ ast_build(); + inline /* implicit */ ast_build(const ast_build &obj); + inline explicit ast_build(isl::checked::ctx ctx); + inline ast_build &operator=(ast_build obj); + inline ~ast_build(); + inline __isl_give isl_ast_build *copy() const &; + inline __isl_give isl_ast_build *copy() && = delete; + inline __isl_keep isl_ast_build *get() const; + inline __isl_give isl_ast_build *release(); + inline bool is_null() const; + inline isl::checked::ctx ctx() const; + +private: + inline ast_build ©_callbacks(const ast_build &obj); + struct at_each_domain_data { + std::function func; + }; + std::shared_ptr at_each_domain_data; + static inline isl_ast_node *at_each_domain(isl_ast_node *arg_0, isl_ast_build *arg_1, void *arg_2); + inline void set_at_each_domain_data(const std::function &fn); +public: + inline isl::checked::ast_build set_at_each_domain(const std::function &fn) const; + inline isl::checked::ast_expr access_from(isl::checked::multi_pw_aff mpa) const; + inline isl::checked::ast_expr access_from(isl::checked::pw_multi_aff pma) const; + inline isl::checked::ast_expr call_from(isl::checked::multi_pw_aff mpa) const; + inline isl::checked::ast_expr call_from(isl::checked::pw_multi_aff pma) const; + inline isl::checked::ast_expr expr_from(isl::checked::pw_aff pa) const; + inline isl::checked::ast_expr expr_from(isl::checked::set set) const; + static inline isl::checked::ast_build from_context(isl::checked::set set); + inline isl::checked::ast_node node_from(isl::checked::schedule schedule) const; + inline isl::checked::ast_node node_from_schedule_map(isl::checked::union_map schedule) const; + inline isl::checked::union_map schedule() const; + inline isl::checked::union_map get_schedule() const; +}; + +// declarations for isl::ast_expr +inline ast_expr manage(__isl_take isl_ast_expr *ptr); +inline ast_expr manage_copy(__isl_keep isl_ast_expr *ptr); + +class ast_expr { + friend inline ast_expr manage(__isl_take isl_ast_expr *ptr); + friend inline ast_expr manage_copy(__isl_keep isl_ast_expr *ptr); + +protected: + isl_ast_expr *ptr = nullptr; + + inline explicit ast_expr(__isl_take isl_ast_expr *ptr); + +public: + inline /* implicit */ ast_expr(); + inline /* implicit */ ast_expr(const ast_expr &obj); + inline ast_expr &operator=(ast_expr obj); + inline ~ast_expr(); + inline __isl_give isl_ast_expr *copy() const &; + inline __isl_give isl_ast_expr *copy() && = delete; + inline __isl_keep isl_ast_expr *get() const; + inline __isl_give isl_ast_expr *release(); + inline bool is_null() const; +private: + template ::value>::type> + inline boolean isa_type(T subtype) const; +public: + template inline boolean isa() const; + template inline T as() const; + inline isl::checked::ctx ctx() const; + + inline std::string to_C_str() const; +}; + +// declarations for isl::ast_expr_id + +class ast_expr_id : public ast_expr { + template + friend boolean ast_expr::isa() const; + friend ast_expr_id ast_expr::as() const; + static const auto type = isl_ast_expr_id; + +protected: + inline explicit ast_expr_id(__isl_take isl_ast_expr *ptr); + +public: + inline /* implicit */ ast_expr_id(); + inline /* implicit */ ast_expr_id(const ast_expr_id &obj); + inline ast_expr_id &operator=(ast_expr_id obj); + inline isl::checked::ctx ctx() const; + + inline isl::checked::id id() const; + inline isl::checked::id get_id() const; +}; + +// declarations for isl::ast_expr_int + +class ast_expr_int : public ast_expr { + template + friend boolean ast_expr::isa() const; + friend ast_expr_int ast_expr::as() const; + static const auto type = isl_ast_expr_int; + +protected: + inline explicit ast_expr_int(__isl_take isl_ast_expr *ptr); + +public: + inline /* implicit */ ast_expr_int(); + inline /* implicit */ ast_expr_int(const ast_expr_int &obj); + inline ast_expr_int &operator=(ast_expr_int obj); + inline isl::checked::ctx ctx() const; + + inline isl::checked::val val() const; + inline isl::checked::val get_val() const; +}; + +// declarations for isl::ast_expr_op + +class ast_expr_op : public ast_expr { + template + friend boolean ast_expr::isa() const; + friend ast_expr_op ast_expr::as() const; + static const auto type = isl_ast_expr_op; + +protected: + inline explicit ast_expr_op(__isl_take isl_ast_expr *ptr); + +public: + inline /* implicit */ ast_expr_op(); + inline /* implicit */ ast_expr_op(const ast_expr_op &obj); + inline ast_expr_op &operator=(ast_expr_op obj); +private: + template ::value>::type> + inline boolean isa_type(T subtype) const; +public: + template inline boolean isa() const; + template inline T as() const; + inline isl::checked::ctx ctx() const; + + inline isl::checked::ast_expr arg(int pos) const; + inline isl::checked::ast_expr get_arg(int pos) const; + inline class size n_arg() const; + inline class size get_n_arg() const; +}; + +// declarations for isl::ast_expr_op_access + +class ast_expr_op_access : public ast_expr_op { + template + friend boolean ast_expr_op::isa() const; + friend ast_expr_op_access ast_expr_op::as() const; + static const auto type = isl_ast_expr_op_access; + +protected: + inline explicit ast_expr_op_access(__isl_take isl_ast_expr *ptr); + +public: + inline /* implicit */ ast_expr_op_access(); + inline /* implicit */ ast_expr_op_access(const ast_expr_op_access &obj); + inline ast_expr_op_access &operator=(ast_expr_op_access obj); + inline isl::checked::ctx ctx() const; + +}; + +// declarations for isl::ast_expr_op_add + +class ast_expr_op_add : public ast_expr_op { + template + friend boolean ast_expr_op::isa() const; + friend ast_expr_op_add ast_expr_op::as() const; + static const auto type = isl_ast_expr_op_add; + +protected: + inline explicit ast_expr_op_add(__isl_take isl_ast_expr *ptr); + +public: + inline /* implicit */ ast_expr_op_add(); + inline /* implicit */ ast_expr_op_add(const ast_expr_op_add &obj); + inline ast_expr_op_add &operator=(ast_expr_op_add obj); + inline isl::checked::ctx ctx() const; + +}; + +// declarations for isl::ast_expr_op_address_of + +class ast_expr_op_address_of : public ast_expr_op { + template + friend boolean ast_expr_op::isa() const; + friend ast_expr_op_address_of ast_expr_op::as() const; + static const auto type = isl_ast_expr_op_address_of; + +protected: + inline explicit ast_expr_op_address_of(__isl_take isl_ast_expr *ptr); + +public: + inline /* implicit */ ast_expr_op_address_of(); + inline /* implicit */ ast_expr_op_address_of(const ast_expr_op_address_of &obj); + inline ast_expr_op_address_of &operator=(ast_expr_op_address_of obj); + inline isl::checked::ctx ctx() const; + +}; + +// declarations for isl::ast_expr_op_and + +class ast_expr_op_and : public ast_expr_op { + template + friend boolean ast_expr_op::isa() const; + friend ast_expr_op_and ast_expr_op::as() const; + static const auto type = isl_ast_expr_op_and; + +protected: + inline explicit ast_expr_op_and(__isl_take isl_ast_expr *ptr); + +public: + inline /* implicit */ ast_expr_op_and(); + inline /* implicit */ ast_expr_op_and(const ast_expr_op_and &obj); + inline ast_expr_op_and &operator=(ast_expr_op_and obj); + inline isl::checked::ctx ctx() const; + +}; + +// declarations for isl::ast_expr_op_and_then + +class ast_expr_op_and_then : public ast_expr_op { + template + friend boolean ast_expr_op::isa() const; + friend ast_expr_op_and_then ast_expr_op::as() const; + static const auto type = isl_ast_expr_op_and_then; + +protected: + inline explicit ast_expr_op_and_then(__isl_take isl_ast_expr *ptr); + +public: + inline /* implicit */ ast_expr_op_and_then(); + inline /* implicit */ ast_expr_op_and_then(const ast_expr_op_and_then &obj); + inline ast_expr_op_and_then &operator=(ast_expr_op_and_then obj); + inline isl::checked::ctx ctx() const; + +}; + +// declarations for isl::ast_expr_op_call + +class ast_expr_op_call : public ast_expr_op { + template + friend boolean ast_expr_op::isa() const; + friend ast_expr_op_call ast_expr_op::as() const; + static const auto type = isl_ast_expr_op_call; + +protected: + inline explicit ast_expr_op_call(__isl_take isl_ast_expr *ptr); + +public: + inline /* implicit */ ast_expr_op_call(); + inline /* implicit */ ast_expr_op_call(const ast_expr_op_call &obj); + inline ast_expr_op_call &operator=(ast_expr_op_call obj); + inline isl::checked::ctx ctx() const; + +}; + +// declarations for isl::ast_expr_op_cond + +class ast_expr_op_cond : public ast_expr_op { + template + friend boolean ast_expr_op::isa() const; + friend ast_expr_op_cond ast_expr_op::as() const; + static const auto type = isl_ast_expr_op_cond; + +protected: + inline explicit ast_expr_op_cond(__isl_take isl_ast_expr *ptr); + +public: + inline /* implicit */ ast_expr_op_cond(); + inline /* implicit */ ast_expr_op_cond(const ast_expr_op_cond &obj); + inline ast_expr_op_cond &operator=(ast_expr_op_cond obj); + inline isl::checked::ctx ctx() const; + +}; + +// declarations for isl::ast_expr_op_div + +class ast_expr_op_div : public ast_expr_op { + template + friend boolean ast_expr_op::isa() const; + friend ast_expr_op_div ast_expr_op::as() const; + static const auto type = isl_ast_expr_op_div; + +protected: + inline explicit ast_expr_op_div(__isl_take isl_ast_expr *ptr); + +public: + inline /* implicit */ ast_expr_op_div(); + inline /* implicit */ ast_expr_op_div(const ast_expr_op_div &obj); + inline ast_expr_op_div &operator=(ast_expr_op_div obj); + inline isl::checked::ctx ctx() const; + +}; + +// declarations for isl::ast_expr_op_eq + +class ast_expr_op_eq : public ast_expr_op { + template + friend boolean ast_expr_op::isa() const; + friend ast_expr_op_eq ast_expr_op::as() const; + static const auto type = isl_ast_expr_op_eq; + +protected: + inline explicit ast_expr_op_eq(__isl_take isl_ast_expr *ptr); + +public: + inline /* implicit */ ast_expr_op_eq(); + inline /* implicit */ ast_expr_op_eq(const ast_expr_op_eq &obj); + inline ast_expr_op_eq &operator=(ast_expr_op_eq obj); + inline isl::checked::ctx ctx() const; + +}; + +// declarations for isl::ast_expr_op_fdiv_q + +class ast_expr_op_fdiv_q : public ast_expr_op { + template + friend boolean ast_expr_op::isa() const; + friend ast_expr_op_fdiv_q ast_expr_op::as() const; + static const auto type = isl_ast_expr_op_fdiv_q; + +protected: + inline explicit ast_expr_op_fdiv_q(__isl_take isl_ast_expr *ptr); + +public: + inline /* implicit */ ast_expr_op_fdiv_q(); + inline /* implicit */ ast_expr_op_fdiv_q(const ast_expr_op_fdiv_q &obj); + inline ast_expr_op_fdiv_q &operator=(ast_expr_op_fdiv_q obj); + inline isl::checked::ctx ctx() const; + +}; + +// declarations for isl::ast_expr_op_ge + +class ast_expr_op_ge : public ast_expr_op { + template + friend boolean ast_expr_op::isa() const; + friend ast_expr_op_ge ast_expr_op::as() const; + static const auto type = isl_ast_expr_op_ge; + +protected: + inline explicit ast_expr_op_ge(__isl_take isl_ast_expr *ptr); + +public: + inline /* implicit */ ast_expr_op_ge(); + inline /* implicit */ ast_expr_op_ge(const ast_expr_op_ge &obj); + inline ast_expr_op_ge &operator=(ast_expr_op_ge obj); + inline isl::checked::ctx ctx() const; + +}; + +// declarations for isl::ast_expr_op_gt + +class ast_expr_op_gt : public ast_expr_op { + template + friend boolean ast_expr_op::isa() const; + friend ast_expr_op_gt ast_expr_op::as() const; + static const auto type = isl_ast_expr_op_gt; + +protected: + inline explicit ast_expr_op_gt(__isl_take isl_ast_expr *ptr); + +public: + inline /* implicit */ ast_expr_op_gt(); + inline /* implicit */ ast_expr_op_gt(const ast_expr_op_gt &obj); + inline ast_expr_op_gt &operator=(ast_expr_op_gt obj); + inline isl::checked::ctx ctx() const; + +}; + +// declarations for isl::ast_expr_op_le + +class ast_expr_op_le : public ast_expr_op { + template + friend boolean ast_expr_op::isa() const; + friend ast_expr_op_le ast_expr_op::as() const; + static const auto type = isl_ast_expr_op_le; + +protected: + inline explicit ast_expr_op_le(__isl_take isl_ast_expr *ptr); + +public: + inline /* implicit */ ast_expr_op_le(); + inline /* implicit */ ast_expr_op_le(const ast_expr_op_le &obj); + inline ast_expr_op_le &operator=(ast_expr_op_le obj); + inline isl::checked::ctx ctx() const; + +}; + +// declarations for isl::ast_expr_op_lt + +class ast_expr_op_lt : public ast_expr_op { + template + friend boolean ast_expr_op::isa() const; + friend ast_expr_op_lt ast_expr_op::as() const; + static const auto type = isl_ast_expr_op_lt; + +protected: + inline explicit ast_expr_op_lt(__isl_take isl_ast_expr *ptr); + +public: + inline /* implicit */ ast_expr_op_lt(); + inline /* implicit */ ast_expr_op_lt(const ast_expr_op_lt &obj); + inline ast_expr_op_lt &operator=(ast_expr_op_lt obj); + inline isl::checked::ctx ctx() const; + +}; + +// declarations for isl::ast_expr_op_max + +class ast_expr_op_max : public ast_expr_op { + template + friend boolean ast_expr_op::isa() const; + friend ast_expr_op_max ast_expr_op::as() const; + static const auto type = isl_ast_expr_op_max; + +protected: + inline explicit ast_expr_op_max(__isl_take isl_ast_expr *ptr); + +public: + inline /* implicit */ ast_expr_op_max(); + inline /* implicit */ ast_expr_op_max(const ast_expr_op_max &obj); + inline ast_expr_op_max &operator=(ast_expr_op_max obj); + inline isl::checked::ctx ctx() const; + +}; + +// declarations for isl::ast_expr_op_member + +class ast_expr_op_member : public ast_expr_op { + template + friend boolean ast_expr_op::isa() const; + friend ast_expr_op_member ast_expr_op::as() const; + static const auto type = isl_ast_expr_op_member; + +protected: + inline explicit ast_expr_op_member(__isl_take isl_ast_expr *ptr); + +public: + inline /* implicit */ ast_expr_op_member(); + inline /* implicit */ ast_expr_op_member(const ast_expr_op_member &obj); + inline ast_expr_op_member &operator=(ast_expr_op_member obj); + inline isl::checked::ctx ctx() const; + +}; + +// declarations for isl::ast_expr_op_min + +class ast_expr_op_min : public ast_expr_op { + template + friend boolean ast_expr_op::isa() const; + friend ast_expr_op_min ast_expr_op::as() const; + static const auto type = isl_ast_expr_op_min; + +protected: + inline explicit ast_expr_op_min(__isl_take isl_ast_expr *ptr); + +public: + inline /* implicit */ ast_expr_op_min(); + inline /* implicit */ ast_expr_op_min(const ast_expr_op_min &obj); + inline ast_expr_op_min &operator=(ast_expr_op_min obj); + inline isl::checked::ctx ctx() const; + +}; + +// declarations for isl::ast_expr_op_minus + +class ast_expr_op_minus : public ast_expr_op { + template + friend boolean ast_expr_op::isa() const; + friend ast_expr_op_minus ast_expr_op::as() const; + static const auto type = isl_ast_expr_op_minus; + +protected: + inline explicit ast_expr_op_minus(__isl_take isl_ast_expr *ptr); + +public: + inline /* implicit */ ast_expr_op_minus(); + inline /* implicit */ ast_expr_op_minus(const ast_expr_op_minus &obj); + inline ast_expr_op_minus &operator=(ast_expr_op_minus obj); + inline isl::checked::ctx ctx() const; + +}; + +// declarations for isl::ast_expr_op_mul + +class ast_expr_op_mul : public ast_expr_op { + template + friend boolean ast_expr_op::isa() const; + friend ast_expr_op_mul ast_expr_op::as() const; + static const auto type = isl_ast_expr_op_mul; + +protected: + inline explicit ast_expr_op_mul(__isl_take isl_ast_expr *ptr); + +public: + inline /* implicit */ ast_expr_op_mul(); + inline /* implicit */ ast_expr_op_mul(const ast_expr_op_mul &obj); + inline ast_expr_op_mul &operator=(ast_expr_op_mul obj); + inline isl::checked::ctx ctx() const; + +}; + +// declarations for isl::ast_expr_op_or + +class ast_expr_op_or : public ast_expr_op { + template + friend boolean ast_expr_op::isa() const; + friend ast_expr_op_or ast_expr_op::as() const; + static const auto type = isl_ast_expr_op_or; + +protected: + inline explicit ast_expr_op_or(__isl_take isl_ast_expr *ptr); + +public: + inline /* implicit */ ast_expr_op_or(); + inline /* implicit */ ast_expr_op_or(const ast_expr_op_or &obj); + inline ast_expr_op_or &operator=(ast_expr_op_or obj); + inline isl::checked::ctx ctx() const; + +}; + +// declarations for isl::ast_expr_op_or_else + +class ast_expr_op_or_else : public ast_expr_op { + template + friend boolean ast_expr_op::isa() const; + friend ast_expr_op_or_else ast_expr_op::as() const; + static const auto type = isl_ast_expr_op_or_else; + +protected: + inline explicit ast_expr_op_or_else(__isl_take isl_ast_expr *ptr); + +public: + inline /* implicit */ ast_expr_op_or_else(); + inline /* implicit */ ast_expr_op_or_else(const ast_expr_op_or_else &obj); + inline ast_expr_op_or_else &operator=(ast_expr_op_or_else obj); + inline isl::checked::ctx ctx() const; + +}; + +// declarations for isl::ast_expr_op_pdiv_q + +class ast_expr_op_pdiv_q : public ast_expr_op { + template + friend boolean ast_expr_op::isa() const; + friend ast_expr_op_pdiv_q ast_expr_op::as() const; + static const auto type = isl_ast_expr_op_pdiv_q; + +protected: + inline explicit ast_expr_op_pdiv_q(__isl_take isl_ast_expr *ptr); + +public: + inline /* implicit */ ast_expr_op_pdiv_q(); + inline /* implicit */ ast_expr_op_pdiv_q(const ast_expr_op_pdiv_q &obj); + inline ast_expr_op_pdiv_q &operator=(ast_expr_op_pdiv_q obj); + inline isl::checked::ctx ctx() const; + +}; + +// declarations for isl::ast_expr_op_pdiv_r + +class ast_expr_op_pdiv_r : public ast_expr_op { + template + friend boolean ast_expr_op::isa() const; + friend ast_expr_op_pdiv_r ast_expr_op::as() const; + static const auto type = isl_ast_expr_op_pdiv_r; + +protected: + inline explicit ast_expr_op_pdiv_r(__isl_take isl_ast_expr *ptr); + +public: + inline /* implicit */ ast_expr_op_pdiv_r(); + inline /* implicit */ ast_expr_op_pdiv_r(const ast_expr_op_pdiv_r &obj); + inline ast_expr_op_pdiv_r &operator=(ast_expr_op_pdiv_r obj); + inline isl::checked::ctx ctx() const; + +}; + +// declarations for isl::ast_expr_op_select + +class ast_expr_op_select : public ast_expr_op { + template + friend boolean ast_expr_op::isa() const; + friend ast_expr_op_select ast_expr_op::as() const; + static const auto type = isl_ast_expr_op_select; + +protected: + inline explicit ast_expr_op_select(__isl_take isl_ast_expr *ptr); + +public: + inline /* implicit */ ast_expr_op_select(); + inline /* implicit */ ast_expr_op_select(const ast_expr_op_select &obj); + inline ast_expr_op_select &operator=(ast_expr_op_select obj); + inline isl::checked::ctx ctx() const; + +}; + +// declarations for isl::ast_expr_op_sub + +class ast_expr_op_sub : public ast_expr_op { + template + friend boolean ast_expr_op::isa() const; + friend ast_expr_op_sub ast_expr_op::as() const; + static const auto type = isl_ast_expr_op_sub; + +protected: + inline explicit ast_expr_op_sub(__isl_take isl_ast_expr *ptr); + +public: + inline /* implicit */ ast_expr_op_sub(); + inline /* implicit */ ast_expr_op_sub(const ast_expr_op_sub &obj); + inline ast_expr_op_sub &operator=(ast_expr_op_sub obj); + inline isl::checked::ctx ctx() const; + +}; + +// declarations for isl::ast_expr_op_zdiv_r + +class ast_expr_op_zdiv_r : public ast_expr_op { + template + friend boolean ast_expr_op::isa() const; + friend ast_expr_op_zdiv_r ast_expr_op::as() const; + static const auto type = isl_ast_expr_op_zdiv_r; + +protected: + inline explicit ast_expr_op_zdiv_r(__isl_take isl_ast_expr *ptr); + +public: + inline /* implicit */ ast_expr_op_zdiv_r(); + inline /* implicit */ ast_expr_op_zdiv_r(const ast_expr_op_zdiv_r &obj); + inline ast_expr_op_zdiv_r &operator=(ast_expr_op_zdiv_r obj); + inline isl::checked::ctx ctx() const; + +}; + +// declarations for isl::ast_node +inline ast_node manage(__isl_take isl_ast_node *ptr); +inline ast_node manage_copy(__isl_keep isl_ast_node *ptr); + +class ast_node { + friend inline ast_node manage(__isl_take isl_ast_node *ptr); + friend inline ast_node manage_copy(__isl_keep isl_ast_node *ptr); + +protected: + isl_ast_node *ptr = nullptr; + + inline explicit ast_node(__isl_take isl_ast_node *ptr); + +public: + inline /* implicit */ ast_node(); + inline /* implicit */ ast_node(const ast_node &obj); + inline ast_node &operator=(ast_node obj); + inline ~ast_node(); + inline __isl_give isl_ast_node *copy() const &; + inline __isl_give isl_ast_node *copy() && = delete; + inline __isl_keep isl_ast_node *get() const; + inline __isl_give isl_ast_node *release(); + inline bool is_null() const; +private: + template ::value>::type> + inline boolean isa_type(T subtype) const; +public: + template inline boolean isa() const; + template inline T as() const; + inline isl::checked::ctx ctx() const; + + inline isl::checked::ast_node map_descendant_bottom_up(const std::function &fn) const; + inline std::string to_C_str() const; + inline isl::checked::ast_node_list to_list() const; +}; + +// declarations for isl::ast_node_block + +class ast_node_block : public ast_node { + template + friend boolean ast_node::isa() const; + friend ast_node_block ast_node::as() const; + static const auto type = isl_ast_node_block; + +protected: + inline explicit ast_node_block(__isl_take isl_ast_node *ptr); + +public: + inline /* implicit */ ast_node_block(); + inline /* implicit */ ast_node_block(const ast_node_block &obj); + inline explicit ast_node_block(isl::checked::ast_node_list list); + inline ast_node_block &operator=(ast_node_block obj); + inline isl::checked::ctx ctx() const; + + inline isl::checked::ast_node_list children() const; + inline isl::checked::ast_node_list get_children() const; +}; + +// declarations for isl::ast_node_for + +class ast_node_for : public ast_node { + template + friend boolean ast_node::isa() const; + friend ast_node_for ast_node::as() const; + static const auto type = isl_ast_node_for; + +protected: + inline explicit ast_node_for(__isl_take isl_ast_node *ptr); + +public: + inline /* implicit */ ast_node_for(); + inline /* implicit */ ast_node_for(const ast_node_for &obj); + inline ast_node_for &operator=(ast_node_for obj); + inline isl::checked::ctx ctx() const; + + inline isl::checked::ast_node body() const; + inline isl::checked::ast_node get_body() const; + inline isl::checked::ast_expr cond() const; + inline isl::checked::ast_expr get_cond() const; + inline isl::checked::ast_expr inc() const; + inline isl::checked::ast_expr get_inc() const; + inline isl::checked::ast_expr init() const; + inline isl::checked::ast_expr get_init() const; + inline boolean is_degenerate() const; + inline isl::checked::ast_expr iterator() const; + inline isl::checked::ast_expr get_iterator() const; +}; + +// declarations for isl::ast_node_if + +class ast_node_if : public ast_node { + template + friend boolean ast_node::isa() const; + friend ast_node_if ast_node::as() const; + static const auto type = isl_ast_node_if; + +protected: + inline explicit ast_node_if(__isl_take isl_ast_node *ptr); + +public: + inline /* implicit */ ast_node_if(); + inline /* implicit */ ast_node_if(const ast_node_if &obj); + inline ast_node_if &operator=(ast_node_if obj); + inline isl::checked::ctx ctx() const; + + inline isl::checked::ast_expr cond() const; + inline isl::checked::ast_expr get_cond() const; + inline isl::checked::ast_node else_node() const; + inline isl::checked::ast_node get_else_node() const; + inline boolean has_else_node() const; + inline isl::checked::ast_node then_node() const; + inline isl::checked::ast_node get_then_node() const; +}; + +// declarations for isl::ast_node_list +inline ast_node_list manage(__isl_take isl_ast_node_list *ptr); +inline ast_node_list manage_copy(__isl_keep isl_ast_node_list *ptr); + +class ast_node_list { + friend inline ast_node_list manage(__isl_take isl_ast_node_list *ptr); + friend inline ast_node_list manage_copy(__isl_keep isl_ast_node_list *ptr); + +protected: + isl_ast_node_list *ptr = nullptr; + + inline explicit ast_node_list(__isl_take isl_ast_node_list *ptr); + +public: + inline /* implicit */ ast_node_list(); + inline /* implicit */ ast_node_list(const ast_node_list &obj); + inline explicit ast_node_list(isl::checked::ctx ctx, int n); + inline explicit ast_node_list(isl::checked::ast_node el); + inline ast_node_list &operator=(ast_node_list obj); + inline ~ast_node_list(); + inline __isl_give isl_ast_node_list *copy() const &; + inline __isl_give isl_ast_node_list *copy() && = delete; + inline __isl_keep isl_ast_node_list *get() const; + inline __isl_give isl_ast_node_list *release(); + inline bool is_null() const; + inline isl::checked::ctx ctx() const; + + inline isl::checked::ast_node_list add(isl::checked::ast_node el) const; + inline isl::checked::ast_node at(int index) const; + inline isl::checked::ast_node get_at(int index) const; + inline isl::checked::ast_node_list clear() const; + inline isl::checked::ast_node_list concat(isl::checked::ast_node_list list2) const; + inline isl::checked::ast_node_list drop(unsigned int first, unsigned int n) const; + inline stat foreach(const std::function &fn) const; + inline stat foreach_scc(const std::function &follows, const std::function &fn) const; + inline isl::checked::ast_node_list insert(unsigned int pos, isl::checked::ast_node el) const; + inline isl::checked::ast_node_list set_at(int index, isl::checked::ast_node el) const; + inline class size size() const; +}; + +// declarations for isl::ast_node_mark + +class ast_node_mark : public ast_node { + template + friend boolean ast_node::isa() const; + friend ast_node_mark ast_node::as() const; + static const auto type = isl_ast_node_mark; + +protected: + inline explicit ast_node_mark(__isl_take isl_ast_node *ptr); + +public: + inline /* implicit */ ast_node_mark(); + inline /* implicit */ ast_node_mark(const ast_node_mark &obj); + inline ast_node_mark &operator=(ast_node_mark obj); + inline isl::checked::ctx ctx() const; + + inline isl::checked::id id() const; + inline isl::checked::id get_id() const; + inline isl::checked::ast_node node() const; + inline isl::checked::ast_node get_node() const; +}; + +// declarations for isl::ast_node_user + +class ast_node_user : public ast_node { + template + friend boolean ast_node::isa() const; + friend ast_node_user ast_node::as() const; + static const auto type = isl_ast_node_user; + +protected: + inline explicit ast_node_user(__isl_take isl_ast_node *ptr); + +public: + inline /* implicit */ ast_node_user(); + inline /* implicit */ ast_node_user(const ast_node_user &obj); + inline explicit ast_node_user(isl::checked::ast_expr expr); + inline ast_node_user &operator=(ast_node_user obj); + inline isl::checked::ctx ctx() const; + + inline isl::checked::ast_expr expr() const; + inline isl::checked::ast_expr get_expr() const; +}; + +// declarations for isl::basic_map +inline basic_map manage(__isl_take isl_basic_map *ptr); +inline basic_map manage_copy(__isl_keep isl_basic_map *ptr); + +class basic_map { + friend inline basic_map manage(__isl_take isl_basic_map *ptr); + friend inline basic_map manage_copy(__isl_keep isl_basic_map *ptr); + +protected: + isl_basic_map *ptr = nullptr; + + inline explicit basic_map(__isl_take isl_basic_map *ptr); + +public: + inline /* implicit */ basic_map(); + inline /* implicit */ basic_map(const basic_map &obj); + inline explicit basic_map(isl::checked::ctx ctx, const std::string &str); + inline basic_map &operator=(basic_map obj); + inline ~basic_map(); + inline __isl_give isl_basic_map *copy() const &; + inline __isl_give isl_basic_map *copy() && = delete; + inline __isl_keep isl_basic_map *get() const; + inline __isl_give isl_basic_map *release(); + inline bool is_null() const; + inline isl::checked::ctx ctx() const; + + inline isl::checked::basic_map affine_hull() const; + inline isl::checked::basic_map apply_domain(isl::checked::basic_map bmap2) const; + inline isl::checked::map apply_domain(const isl::checked::map &map2) const; + inline isl::checked::union_map apply_domain(const isl::checked::union_map &umap2) const; + inline isl::checked::basic_map apply_range(isl::checked::basic_map bmap2) const; + inline isl::checked::map apply_range(const isl::checked::map &map2) const; + inline isl::checked::union_map apply_range(const isl::checked::union_map &umap2) const; + inline isl::checked::map as_map() const; + inline isl::checked::multi_union_pw_aff as_multi_union_pw_aff() const; + inline isl::checked::pw_multi_aff as_pw_multi_aff() const; + inline isl::checked::union_pw_multi_aff as_union_pw_multi_aff() const; + inline isl::checked::set bind_domain(const isl::checked::multi_id &tuple) const; + inline isl::checked::set bind_range(const isl::checked::multi_id &tuple) const; + inline isl::checked::map coalesce() const; + inline isl::checked::map complement() const; + inline isl::checked::union_map compute_divs() const; + inline isl::checked::map curry() const; + inline isl::checked::basic_set deltas() const; + inline isl::checked::basic_map detect_equalities() const; + inline isl::checked::set domain() const; + inline isl::checked::map domain_factor_domain() const; + inline isl::checked::map domain_factor_range() const; + inline isl::checked::union_map domain_map() const; + inline isl::checked::union_pw_multi_aff domain_map_union_pw_multi_aff() const; + inline isl::checked::map domain_product(const isl::checked::map &map2) const; + inline isl::checked::union_map domain_product(const isl::checked::union_map &umap2) const; + inline isl::checked::map domain_reverse() const; + inline class size domain_tuple_dim() const; + inline isl::checked::id domain_tuple_id() const; + inline isl::checked::map drop_unused_params() const; + inline isl::checked::map eq_at(const isl::checked::multi_pw_aff &mpa) const; + inline isl::checked::union_map eq_at(const isl::checked::multi_union_pw_aff &mupa) const; + inline boolean every_map(const std::function &test) const; + inline isl::checked::map extract_map(const isl::checked::space &space) const; + inline isl::checked::map factor_domain() const; + inline isl::checked::map factor_range() const; + inline isl::checked::map fixed_power(const isl::checked::val &exp) const; + inline isl::checked::map fixed_power(long exp) const; + inline isl::checked::basic_map flatten() const; + inline isl::checked::basic_map flatten_domain() const; + inline isl::checked::basic_map flatten_range() const; + inline stat foreach_basic_map(const std::function &fn) const; + inline stat foreach_map(const std::function &fn) const; + inline isl::checked::basic_map gist(isl::checked::basic_map context) const; + inline isl::checked::map gist(const isl::checked::map &context) const; + inline isl::checked::union_map gist(const isl::checked::union_map &context) const; + inline isl::checked::map gist_domain(const isl::checked::set &context) const; + inline isl::checked::union_map gist_domain(const isl::checked::union_set &uset) const; + inline isl::checked::map gist_params(const isl::checked::set &context) const; + inline isl::checked::union_map gist_range(const isl::checked::union_set &uset) const; + inline boolean has_domain_tuple_id() const; + inline boolean has_range_tuple_id() const; + inline isl::checked::basic_map intersect(isl::checked::basic_map bmap2) const; + inline isl::checked::map intersect(const isl::checked::map &map2) const; + inline isl::checked::union_map intersect(const isl::checked::union_map &umap2) const; + inline isl::checked::basic_map intersect_domain(isl::checked::basic_set bset) const; + inline isl::checked::map intersect_domain(const isl::checked::set &set) const; + inline isl::checked::union_map intersect_domain(const isl::checked::space &space) const; + inline isl::checked::union_map intersect_domain(const isl::checked::union_set &uset) const; + inline isl::checked::basic_map intersect_domain(const isl::checked::point &bset) const; + inline isl::checked::map intersect_domain_factor_domain(const isl::checked::map &factor) const; + inline isl::checked::union_map intersect_domain_factor_domain(const isl::checked::union_map &factor) const; + inline isl::checked::map intersect_domain_factor_range(const isl::checked::map &factor) const; + inline isl::checked::union_map intersect_domain_factor_range(const isl::checked::union_map &factor) const; + inline isl::checked::map intersect_domain_wrapped_domain(const isl::checked::set &domain) const; + inline isl::checked::union_map intersect_domain_wrapped_domain(const isl::checked::union_set &domain) const; + inline isl::checked::map intersect_params(const isl::checked::set ¶ms) const; + inline isl::checked::basic_map intersect_range(isl::checked::basic_set bset) const; + inline isl::checked::map intersect_range(const isl::checked::set &set) const; + inline isl::checked::union_map intersect_range(const isl::checked::space &space) const; + inline isl::checked::union_map intersect_range(const isl::checked::union_set &uset) const; + inline isl::checked::basic_map intersect_range(const isl::checked::point &bset) const; + inline isl::checked::map intersect_range_factor_domain(const isl::checked::map &factor) const; + inline isl::checked::union_map intersect_range_factor_domain(const isl::checked::union_map &factor) const; + inline isl::checked::map intersect_range_factor_range(const isl::checked::map &factor) const; + inline isl::checked::union_map intersect_range_factor_range(const isl::checked::union_map &factor) const; + inline isl::checked::map intersect_range_wrapped_domain(const isl::checked::set &domain) const; + inline isl::checked::union_map intersect_range_wrapped_domain(const isl::checked::union_set &domain) const; + inline boolean is_bijective() const; + inline boolean is_disjoint(const isl::checked::map &map2) const; + inline boolean is_disjoint(const isl::checked::union_map &umap2) const; + inline boolean is_empty() const; + inline boolean is_equal(const isl::checked::basic_map &bmap2) const; + inline boolean is_equal(const isl::checked::map &map2) const; + inline boolean is_equal(const isl::checked::union_map &umap2) const; + inline boolean is_injective() const; + inline boolean is_single_valued() const; + inline boolean is_strict_subset(const isl::checked::map &map2) const; + inline boolean is_strict_subset(const isl::checked::union_map &umap2) const; + inline boolean is_subset(const isl::checked::basic_map &bmap2) const; + inline boolean is_subset(const isl::checked::map &map2) const; + inline boolean is_subset(const isl::checked::union_map &umap2) const; + inline boolean isa_map() const; + inline isl::checked::map lex_ge_at(const isl::checked::multi_pw_aff &mpa) const; + inline isl::checked::map lex_gt_at(const isl::checked::multi_pw_aff &mpa) const; + inline isl::checked::map lex_le_at(const isl::checked::multi_pw_aff &mpa) const; + inline isl::checked::map lex_lt_at(const isl::checked::multi_pw_aff &mpa) const; + inline isl::checked::map lexmax() const; + inline isl::checked::pw_multi_aff lexmax_pw_multi_aff() const; + inline isl::checked::map lexmin() const; + inline isl::checked::pw_multi_aff lexmin_pw_multi_aff() const; + inline isl::checked::map lower_bound(const isl::checked::multi_pw_aff &lower) const; + inline isl::checked::map_list map_list() const; + inline isl::checked::multi_pw_aff max_multi_pw_aff() const; + inline isl::checked::multi_pw_aff min_multi_pw_aff() const; + inline class size n_basic_map() const; + inline isl::checked::set params() const; + inline isl::checked::basic_map polyhedral_hull() const; + inline isl::checked::map preimage_domain(const isl::checked::multi_aff &ma) const; + inline isl::checked::map preimage_domain(const isl::checked::multi_pw_aff &mpa) const; + inline isl::checked::map preimage_domain(const isl::checked::pw_multi_aff &pma) const; + inline isl::checked::union_map preimage_domain(const isl::checked::union_pw_multi_aff &upma) const; + inline isl::checked::map preimage_range(const isl::checked::multi_aff &ma) const; + inline isl::checked::map preimage_range(const isl::checked::pw_multi_aff &pma) const; + inline isl::checked::union_map preimage_range(const isl::checked::union_pw_multi_aff &upma) const; + inline isl::checked::map product(const isl::checked::map &map2) const; + inline isl::checked::union_map product(const isl::checked::union_map &umap2) const; + inline isl::checked::map project_out_all_params() const; + inline isl::checked::map project_out_param(const isl::checked::id &id) const; + inline isl::checked::map project_out_param(const std::string &id) const; + inline isl::checked::map project_out_param(const isl::checked::id_list &list) const; + inline isl::checked::set range() const; + inline isl::checked::map range_factor_domain() const; + inline isl::checked::map range_factor_range() const; + inline isl::checked::fixed_box range_lattice_tile() const; + inline isl::checked::union_map range_map() const; + inline isl::checked::map range_product(const isl::checked::map &map2) const; + inline isl::checked::union_map range_product(const isl::checked::union_map &umap2) const; + inline isl::checked::map range_reverse() const; + inline isl::checked::fixed_box range_simple_fixed_box_hull() const; + inline class size range_tuple_dim() const; + inline isl::checked::id range_tuple_id() const; + inline isl::checked::basic_map reverse() const; + inline isl::checked::basic_map sample() const; + inline isl::checked::map set_domain_tuple(const isl::checked::id &id) const; + inline isl::checked::map set_domain_tuple(const std::string &id) const; + inline isl::checked::map set_range_tuple(const isl::checked::id &id) const; + inline isl::checked::map set_range_tuple(const std::string &id) const; + inline isl::checked::space space() const; + inline isl::checked::map subtract(const isl::checked::map &map2) const; + inline isl::checked::union_map subtract(const isl::checked::union_map &umap2) const; + inline isl::checked::union_map subtract_domain(const isl::checked::union_set &dom) const; + inline isl::checked::union_map subtract_range(const isl::checked::union_set &dom) const; + inline isl::checked::map_list to_list() const; + inline isl::checked::union_map to_union_map() const; + inline isl::checked::map uncurry() const; + inline isl::checked::map unite(isl::checked::basic_map bmap2) const; + inline isl::checked::map unite(const isl::checked::map &map2) const; + inline isl::checked::union_map unite(const isl::checked::union_map &umap2) const; + inline isl::checked::basic_map unshifted_simple_hull() const; + inline isl::checked::map upper_bound(const isl::checked::multi_pw_aff &upper) const; + inline isl::checked::set wrap() const; + inline isl::checked::map zip() const; +}; + +// declarations for isl::basic_set +inline basic_set manage(__isl_take isl_basic_set *ptr); +inline basic_set manage_copy(__isl_keep isl_basic_set *ptr); + +class basic_set { + friend inline basic_set manage(__isl_take isl_basic_set *ptr); + friend inline basic_set manage_copy(__isl_keep isl_basic_set *ptr); + +protected: + isl_basic_set *ptr = nullptr; + + inline explicit basic_set(__isl_take isl_basic_set *ptr); + +public: + inline /* implicit */ basic_set(); + inline /* implicit */ basic_set(const basic_set &obj); + inline /* implicit */ basic_set(isl::checked::point pnt); + inline explicit basic_set(isl::checked::ctx ctx, const std::string &str); + inline basic_set &operator=(basic_set obj); + inline ~basic_set(); + inline __isl_give isl_basic_set *copy() const &; + inline __isl_give isl_basic_set *copy() && = delete; + inline __isl_keep isl_basic_set *get() const; + inline __isl_give isl_basic_set *release(); + inline bool is_null() const; + inline isl::checked::ctx ctx() const; + + inline isl::checked::basic_set affine_hull() const; + inline isl::checked::basic_set apply(isl::checked::basic_map bmap) const; + inline isl::checked::set apply(const isl::checked::map &map) const; + inline isl::checked::union_set apply(const isl::checked::union_map &umap) const; + inline isl::checked::pw_multi_aff as_pw_multi_aff() const; + inline isl::checked::set as_set() const; + inline isl::checked::set bind(const isl::checked::multi_id &tuple) const; + inline isl::checked::set coalesce() const; + inline isl::checked::set complement() const; + inline isl::checked::union_set compute_divs() const; + inline isl::checked::basic_set detect_equalities() const; + inline isl::checked::val dim_max_val(int pos) const; + inline isl::checked::val dim_min_val(int pos) const; + inline isl::checked::set drop_unused_params() const; + inline boolean every_set(const std::function &test) const; + inline isl::checked::set extract_set(const isl::checked::space &space) const; + inline isl::checked::basic_set flatten() const; + inline stat foreach_basic_set(const std::function &fn) const; + inline stat foreach_point(const std::function &fn) const; + inline stat foreach_set(const std::function &fn) const; + inline isl::checked::basic_set gist(isl::checked::basic_set context) const; + inline isl::checked::set gist(const isl::checked::set &context) const; + inline isl::checked::union_set gist(const isl::checked::union_set &context) const; + inline isl::checked::basic_set gist(const isl::checked::point &context) const; + inline isl::checked::set gist_params(const isl::checked::set &context) const; + inline isl::checked::map identity() const; + inline isl::checked::pw_aff indicator_function() const; + inline isl::checked::map insert_domain(const isl::checked::space &domain) const; + inline isl::checked::basic_set intersect(isl::checked::basic_set bset2) const; + inline isl::checked::set intersect(const isl::checked::set &set2) const; + inline isl::checked::union_set intersect(const isl::checked::union_set &uset2) const; + inline isl::checked::basic_set intersect(const isl::checked::point &bset2) const; + inline isl::checked::basic_set intersect_params(isl::checked::basic_set bset2) const; + inline isl::checked::set intersect_params(const isl::checked::set ¶ms) const; + inline isl::checked::basic_set intersect_params(const isl::checked::point &bset2) const; + inline boolean involves_locals() const; + inline boolean is_disjoint(const isl::checked::set &set2) const; + inline boolean is_disjoint(const isl::checked::union_set &uset2) const; + inline boolean is_empty() const; + inline boolean is_equal(const isl::checked::basic_set &bset2) const; + inline boolean is_equal(const isl::checked::set &set2) const; + inline boolean is_equal(const isl::checked::union_set &uset2) const; + inline boolean is_equal(const isl::checked::point &bset2) const; + inline boolean is_singleton() const; + inline boolean is_strict_subset(const isl::checked::set &set2) const; + inline boolean is_strict_subset(const isl::checked::union_set &uset2) const; + inline boolean is_subset(const isl::checked::basic_set &bset2) const; + inline boolean is_subset(const isl::checked::set &set2) const; + inline boolean is_subset(const isl::checked::union_set &uset2) const; + inline boolean is_subset(const isl::checked::point &bset2) const; + inline boolean is_wrapping() const; + inline boolean isa_set() const; + inline isl::checked::fixed_box lattice_tile() const; + inline isl::checked::set lexmax() const; + inline isl::checked::pw_multi_aff lexmax_pw_multi_aff() const; + inline isl::checked::set lexmin() const; + inline isl::checked::pw_multi_aff lexmin_pw_multi_aff() const; + inline isl::checked::set lower_bound(const isl::checked::multi_pw_aff &lower) const; + inline isl::checked::set lower_bound(const isl::checked::multi_val &lower) const; + inline isl::checked::multi_pw_aff max_multi_pw_aff() const; + inline isl::checked::val max_val(const isl::checked::aff &obj) const; + inline isl::checked::multi_pw_aff min_multi_pw_aff() const; + inline isl::checked::val min_val(const isl::checked::aff &obj) const; + inline class size n_basic_set() const; + inline isl::checked::pw_aff param_pw_aff_on_domain(const isl::checked::id &id) const; + inline isl::checked::pw_aff param_pw_aff_on_domain(const std::string &id) const; + inline isl::checked::basic_set params() const; + inline isl::checked::multi_val plain_multi_val_if_fixed() const; + inline isl::checked::basic_set polyhedral_hull() const; + inline isl::checked::set preimage(const isl::checked::multi_aff &ma) const; + inline isl::checked::set preimage(const isl::checked::multi_pw_aff &mpa) const; + inline isl::checked::set preimage(const isl::checked::pw_multi_aff &pma) const; + inline isl::checked::union_set preimage(const isl::checked::union_pw_multi_aff &upma) const; + inline isl::checked::set product(const isl::checked::set &set2) const; + inline isl::checked::set project_out_all_params() const; + inline isl::checked::set project_out_param(const isl::checked::id &id) const; + inline isl::checked::set project_out_param(const std::string &id) const; + inline isl::checked::set project_out_param(const isl::checked::id_list &list) const; + inline isl::checked::pw_aff pw_aff_on_domain(const isl::checked::val &v) const; + inline isl::checked::pw_aff pw_aff_on_domain(long v) const; + inline isl::checked::pw_multi_aff pw_multi_aff_on_domain(const isl::checked::multi_val &mv) const; + inline isl::checked::basic_set sample() const; + inline isl::checked::point sample_point() const; + inline isl::checked::set_list set_list() const; + inline isl::checked::fixed_box simple_fixed_box_hull() const; + inline isl::checked::space space() const; + inline isl::checked::val stride(int pos) const; + inline isl::checked::set subtract(const isl::checked::set &set2) const; + inline isl::checked::union_set subtract(const isl::checked::union_set &uset2) const; + inline isl::checked::set_list to_list() const; + inline isl::checked::set to_set() const; + inline isl::checked::union_set to_union_set() const; + inline isl::checked::map translation() const; + inline class size tuple_dim() const; + inline isl::checked::set unbind_params(const isl::checked::multi_id &tuple) const; + inline isl::checked::map unbind_params_insert_domain(const isl::checked::multi_id &domain) const; + inline isl::checked::set unite(isl::checked::basic_set bset2) const; + inline isl::checked::set unite(const isl::checked::set &set2) const; + inline isl::checked::union_set unite(const isl::checked::union_set &uset2) const; + inline isl::checked::set unite(const isl::checked::point &bset2) const; + inline isl::checked::basic_set unshifted_simple_hull() const; + inline isl::checked::map unwrap() const; + inline isl::checked::set upper_bound(const isl::checked::multi_pw_aff &upper) const; + inline isl::checked::set upper_bound(const isl::checked::multi_val &upper) const; + inline isl::checked::set wrapped_reverse() const; +}; + +// declarations for isl::fixed_box +inline fixed_box manage(__isl_take isl_fixed_box *ptr); +inline fixed_box manage_copy(__isl_keep isl_fixed_box *ptr); + +class fixed_box { + friend inline fixed_box manage(__isl_take isl_fixed_box *ptr); + friend inline fixed_box manage_copy(__isl_keep isl_fixed_box *ptr); + +protected: + isl_fixed_box *ptr = nullptr; + + inline explicit fixed_box(__isl_take isl_fixed_box *ptr); + +public: + inline /* implicit */ fixed_box(); + inline /* implicit */ fixed_box(const fixed_box &obj); + inline explicit fixed_box(isl::checked::ctx ctx, const std::string &str); + inline fixed_box &operator=(fixed_box obj); + inline ~fixed_box(); + inline __isl_give isl_fixed_box *copy() const &; + inline __isl_give isl_fixed_box *copy() && = delete; + inline __isl_keep isl_fixed_box *get() const; + inline __isl_give isl_fixed_box *release(); + inline bool is_null() const; + inline isl::checked::ctx ctx() const; + + inline boolean is_valid() const; + inline isl::checked::multi_aff offset() const; + inline isl::checked::multi_aff get_offset() const; + inline isl::checked::multi_val size() const; + inline isl::checked::multi_val get_size() const; + inline isl::checked::space space() const; + inline isl::checked::space get_space() const; +}; + +// declarations for isl::id +inline id manage(__isl_take isl_id *ptr); +inline id manage_copy(__isl_keep isl_id *ptr); + +class id { + friend inline id manage(__isl_take isl_id *ptr); + friend inline id manage_copy(__isl_keep isl_id *ptr); + +protected: + isl_id *ptr = nullptr; + + inline explicit id(__isl_take isl_id *ptr); + +public: + inline /* implicit */ id(); + inline /* implicit */ id(const id &obj); + inline explicit id(isl::checked::ctx ctx, const std::string &str); + inline id &operator=(id obj); + inline ~id(); + inline __isl_give isl_id *copy() const &; + inline __isl_give isl_id *copy() && = delete; + inline __isl_keep isl_id *get() const; + inline __isl_give isl_id *release(); + inline bool is_null() const; + inline isl::checked::ctx ctx() const; + + inline std::string name() const; + inline std::string get_name() const; + inline isl::checked::id_list to_list() const; + +#if __cplusplus >= 201703L + inline explicit id(isl::checked::ctx ctx, const std::string &str, const std::any &any); + template + std::optional try_user() const; + template + T user() const; +#endif +}; + +// declarations for isl::id_list +inline id_list manage(__isl_take isl_id_list *ptr); +inline id_list manage_copy(__isl_keep isl_id_list *ptr); + +class id_list { + friend inline id_list manage(__isl_take isl_id_list *ptr); + friend inline id_list manage_copy(__isl_keep isl_id_list *ptr); + +protected: + isl_id_list *ptr = nullptr; + + inline explicit id_list(__isl_take isl_id_list *ptr); + +public: + inline /* implicit */ id_list(); + inline /* implicit */ id_list(const id_list &obj); + inline explicit id_list(isl::checked::ctx ctx, int n); + inline explicit id_list(isl::checked::id el); + inline explicit id_list(isl::checked::ctx ctx, const std::string &str); + inline id_list &operator=(id_list obj); + inline ~id_list(); + inline __isl_give isl_id_list *copy() const &; + inline __isl_give isl_id_list *copy() && = delete; + inline __isl_keep isl_id_list *get() const; + inline __isl_give isl_id_list *release(); + inline bool is_null() const; + inline isl::checked::ctx ctx() const; + + inline isl::checked::id_list add(isl::checked::id el) const; + inline isl::checked::id_list add(const std::string &el) const; + inline isl::checked::id at(int index) const; + inline isl::checked::id get_at(int index) const; + inline isl::checked::id_list clear() const; + inline isl::checked::id_list concat(isl::checked::id_list list2) const; + inline isl::checked::id_list drop(unsigned int first, unsigned int n) const; + inline stat foreach(const std::function &fn) const; + inline stat foreach_scc(const std::function &follows, const std::function &fn) const; + inline isl::checked::id_list insert(unsigned int pos, isl::checked::id el) const; + inline isl::checked::id_list insert(unsigned int pos, const std::string &el) const; + inline isl::checked::id_list set_at(int index, isl::checked::id el) const; + inline isl::checked::id_list set_at(int index, const std::string &el) const; + inline class size size() const; +}; + +// declarations for isl::id_to_ast_expr +inline id_to_ast_expr manage(__isl_take isl_id_to_ast_expr *ptr); +inline id_to_ast_expr manage_copy(__isl_keep isl_id_to_ast_expr *ptr); + +class id_to_ast_expr { + friend inline id_to_ast_expr manage(__isl_take isl_id_to_ast_expr *ptr); + friend inline id_to_ast_expr manage_copy(__isl_keep isl_id_to_ast_expr *ptr); + +protected: + isl_id_to_ast_expr *ptr = nullptr; + + inline explicit id_to_ast_expr(__isl_take isl_id_to_ast_expr *ptr); + +public: + inline /* implicit */ id_to_ast_expr(); + inline /* implicit */ id_to_ast_expr(const id_to_ast_expr &obj); + inline explicit id_to_ast_expr(isl::checked::ctx ctx, int min_size); + inline explicit id_to_ast_expr(isl::checked::ctx ctx, const std::string &str); + inline id_to_ast_expr &operator=(id_to_ast_expr obj); + inline ~id_to_ast_expr(); + inline __isl_give isl_id_to_ast_expr *copy() const &; + inline __isl_give isl_id_to_ast_expr *copy() && = delete; + inline __isl_keep isl_id_to_ast_expr *get() const; + inline __isl_give isl_id_to_ast_expr *release(); + inline bool is_null() const; + inline isl::checked::ctx ctx() const; + + inline boolean is_equal(const isl::checked::id_to_ast_expr &hmap2) const; + inline isl::checked::id_to_ast_expr set(isl::checked::id key, isl::checked::ast_expr val) const; + inline isl::checked::id_to_ast_expr set(const std::string &key, const isl::checked::ast_expr &val) const; +}; + +// declarations for isl::id_to_id +inline id_to_id manage(__isl_take isl_id_to_id *ptr); +inline id_to_id manage_copy(__isl_keep isl_id_to_id *ptr); + +class id_to_id { + friend inline id_to_id manage(__isl_take isl_id_to_id *ptr); + friend inline id_to_id manage_copy(__isl_keep isl_id_to_id *ptr); + +protected: + isl_id_to_id *ptr = nullptr; + + inline explicit id_to_id(__isl_take isl_id_to_id *ptr); + +public: + inline /* implicit */ id_to_id(); + inline /* implicit */ id_to_id(const id_to_id &obj); + inline explicit id_to_id(isl::checked::ctx ctx, int min_size); + inline explicit id_to_id(isl::checked::ctx ctx, const std::string &str); + inline id_to_id &operator=(id_to_id obj); + inline ~id_to_id(); + inline __isl_give isl_id_to_id *copy() const &; + inline __isl_give isl_id_to_id *copy() && = delete; + inline __isl_keep isl_id_to_id *get() const; + inline __isl_give isl_id_to_id *release(); + inline bool is_null() const; + inline isl::checked::ctx ctx() const; + + inline boolean is_equal(const isl::checked::id_to_id &hmap2) const; + inline isl::checked::id_to_id set(isl::checked::id key, isl::checked::id val) const; + inline isl::checked::id_to_id set(const isl::checked::id &key, const std::string &val) const; + inline isl::checked::id_to_id set(const std::string &key, const isl::checked::id &val) const; + inline isl::checked::id_to_id set(const std::string &key, const std::string &val) const; +}; + +// declarations for isl::map +inline map manage(__isl_take isl_map *ptr); +inline map manage_copy(__isl_keep isl_map *ptr); + +class map { + friend inline map manage(__isl_take isl_map *ptr); + friend inline map manage_copy(__isl_keep isl_map *ptr); + +protected: + isl_map *ptr = nullptr; + + inline explicit map(__isl_take isl_map *ptr); + +public: + inline /* implicit */ map(); + inline /* implicit */ map(const map &obj); + inline /* implicit */ map(isl::checked::basic_map bmap); + inline explicit map(isl::checked::ctx ctx, const std::string &str); + inline map &operator=(map obj); + inline ~map(); + inline __isl_give isl_map *copy() const &; + inline __isl_give isl_map *copy() && = delete; + inline __isl_keep isl_map *get() const; + inline __isl_give isl_map *release(); + inline bool is_null() const; + inline isl::checked::ctx ctx() const; + + inline isl::checked::basic_map affine_hull() const; + inline isl::checked::map apply_domain(isl::checked::map map2) const; + inline isl::checked::union_map apply_domain(const isl::checked::union_map &umap2) const; + inline isl::checked::map apply_domain(const isl::checked::basic_map &map2) const; + inline isl::checked::map apply_range(isl::checked::map map2) const; + inline isl::checked::union_map apply_range(const isl::checked::union_map &umap2) const; + inline isl::checked::map apply_range(const isl::checked::basic_map &map2) const; + inline isl::checked::map as_map() const; + inline isl::checked::multi_union_pw_aff as_multi_union_pw_aff() const; + inline isl::checked::pw_multi_aff as_pw_multi_aff() const; + inline isl::checked::union_pw_multi_aff as_union_pw_multi_aff() const; + inline isl::checked::set bind_domain(isl::checked::multi_id tuple) const; + inline isl::checked::set bind_range(isl::checked::multi_id tuple) const; + inline isl::checked::map coalesce() const; + inline isl::checked::map complement() const; + inline isl::checked::union_map compute_divs() const; + inline isl::checked::map curry() const; + inline isl::checked::set deltas() const; + inline isl::checked::map detect_equalities() const; + inline isl::checked::set domain() const; + inline isl::checked::map domain_factor_domain() const; + inline isl::checked::map domain_factor_range() const; + inline isl::checked::union_map domain_map() const; + inline isl::checked::union_pw_multi_aff domain_map_union_pw_multi_aff() const; + inline isl::checked::map domain_product(isl::checked::map map2) const; + inline isl::checked::union_map domain_product(const isl::checked::union_map &umap2) const; + inline isl::checked::map domain_product(const isl::checked::basic_map &map2) const; + inline isl::checked::map domain_reverse() const; + inline class size domain_tuple_dim() const; + inline isl::checked::id domain_tuple_id() const; + inline isl::checked::id get_domain_tuple_id() const; + inline isl::checked::map drop_unused_params() const; + static inline isl::checked::map empty(isl::checked::space space); + inline isl::checked::map eq_at(isl::checked::multi_pw_aff mpa) const; + inline isl::checked::union_map eq_at(const isl::checked::multi_union_pw_aff &mupa) const; + inline isl::checked::map eq_at(const isl::checked::aff &mpa) const; + inline isl::checked::map eq_at(const isl::checked::multi_aff &mpa) const; + inline isl::checked::map eq_at(const isl::checked::pw_aff &mpa) const; + inline isl::checked::map eq_at(const isl::checked::pw_multi_aff &mpa) const; + inline boolean every_map(const std::function &test) const; + inline isl::checked::map extract_map(const isl::checked::space &space) const; + inline isl::checked::map factor_domain() const; + inline isl::checked::map factor_range() const; + inline isl::checked::map fixed_power(isl::checked::val exp) const; + inline isl::checked::map fixed_power(long exp) const; + inline isl::checked::map flatten() const; + inline isl::checked::map flatten_domain() const; + inline isl::checked::map flatten_range() const; + inline stat foreach_basic_map(const std::function &fn) const; + inline stat foreach_map(const std::function &fn) const; + inline isl::checked::map gist(isl::checked::map context) const; + inline isl::checked::union_map gist(const isl::checked::union_map &context) const; + inline isl::checked::map gist(const isl::checked::basic_map &context) const; + inline isl::checked::map gist_domain(isl::checked::set context) const; + inline isl::checked::union_map gist_domain(const isl::checked::union_set &uset) const; + inline isl::checked::map gist_domain(const isl::checked::basic_set &context) const; + inline isl::checked::map gist_domain(const isl::checked::point &context) const; + inline isl::checked::map gist_params(isl::checked::set context) const; + inline isl::checked::union_map gist_range(const isl::checked::union_set &uset) const; + inline boolean has_domain_tuple_id() const; + inline boolean has_range_tuple_id() const; + inline isl::checked::map intersect(isl::checked::map map2) const; + inline isl::checked::union_map intersect(const isl::checked::union_map &umap2) const; + inline isl::checked::map intersect(const isl::checked::basic_map &map2) const; + inline isl::checked::map intersect_domain(isl::checked::set set) const; + inline isl::checked::union_map intersect_domain(const isl::checked::space &space) const; + inline isl::checked::union_map intersect_domain(const isl::checked::union_set &uset) const; + inline isl::checked::map intersect_domain(const isl::checked::basic_set &set) const; + inline isl::checked::map intersect_domain(const isl::checked::point &set) const; + inline isl::checked::map intersect_domain_factor_domain(isl::checked::map factor) const; + inline isl::checked::union_map intersect_domain_factor_domain(const isl::checked::union_map &factor) const; + inline isl::checked::map intersect_domain_factor_domain(const isl::checked::basic_map &factor) const; + inline isl::checked::map intersect_domain_factor_range(isl::checked::map factor) const; + inline isl::checked::union_map intersect_domain_factor_range(const isl::checked::union_map &factor) const; + inline isl::checked::map intersect_domain_factor_range(const isl::checked::basic_map &factor) const; + inline isl::checked::map intersect_domain_wrapped_domain(isl::checked::set domain) const; + inline isl::checked::union_map intersect_domain_wrapped_domain(const isl::checked::union_set &domain) const; + inline isl::checked::map intersect_domain_wrapped_domain(const isl::checked::basic_set &domain) const; + inline isl::checked::map intersect_domain_wrapped_domain(const isl::checked::point &domain) const; + inline isl::checked::map intersect_params(isl::checked::set params) const; + inline isl::checked::map intersect_range(isl::checked::set set) const; + inline isl::checked::union_map intersect_range(const isl::checked::space &space) const; + inline isl::checked::union_map intersect_range(const isl::checked::union_set &uset) const; + inline isl::checked::map intersect_range(const isl::checked::basic_set &set) const; + inline isl::checked::map intersect_range(const isl::checked::point &set) const; + inline isl::checked::map intersect_range_factor_domain(isl::checked::map factor) const; + inline isl::checked::union_map intersect_range_factor_domain(const isl::checked::union_map &factor) const; + inline isl::checked::map intersect_range_factor_domain(const isl::checked::basic_map &factor) const; + inline isl::checked::map intersect_range_factor_range(isl::checked::map factor) const; + inline isl::checked::union_map intersect_range_factor_range(const isl::checked::union_map &factor) const; + inline isl::checked::map intersect_range_factor_range(const isl::checked::basic_map &factor) const; + inline isl::checked::map intersect_range_wrapped_domain(isl::checked::set domain) const; + inline isl::checked::union_map intersect_range_wrapped_domain(const isl::checked::union_set &domain) const; + inline isl::checked::map intersect_range_wrapped_domain(const isl::checked::basic_set &domain) const; + inline isl::checked::map intersect_range_wrapped_domain(const isl::checked::point &domain) const; + inline boolean is_bijective() const; + inline boolean is_disjoint(const isl::checked::map &map2) const; + inline boolean is_disjoint(const isl::checked::union_map &umap2) const; + inline boolean is_disjoint(const isl::checked::basic_map &map2) const; + inline boolean is_empty() const; + inline boolean is_equal(const isl::checked::map &map2) const; + inline boolean is_equal(const isl::checked::union_map &umap2) const; + inline boolean is_equal(const isl::checked::basic_map &map2) const; + inline boolean is_injective() const; + inline boolean is_single_valued() const; + inline boolean is_strict_subset(const isl::checked::map &map2) const; + inline boolean is_strict_subset(const isl::checked::union_map &umap2) const; + inline boolean is_strict_subset(const isl::checked::basic_map &map2) const; + inline boolean is_subset(const isl::checked::map &map2) const; + inline boolean is_subset(const isl::checked::union_map &umap2) const; + inline boolean is_subset(const isl::checked::basic_map &map2) const; + inline boolean isa_map() const; + inline isl::checked::map lex_ge_at(isl::checked::multi_pw_aff mpa) const; + inline isl::checked::map lex_gt_at(isl::checked::multi_pw_aff mpa) const; + inline isl::checked::map lex_le_at(isl::checked::multi_pw_aff mpa) const; + inline isl::checked::map lex_lt_at(isl::checked::multi_pw_aff mpa) const; + inline isl::checked::map lexmax() const; + inline isl::checked::pw_multi_aff lexmax_pw_multi_aff() const; + inline isl::checked::map lexmin() const; + inline isl::checked::pw_multi_aff lexmin_pw_multi_aff() const; + inline isl::checked::map lower_bound(isl::checked::multi_pw_aff lower) const; + inline isl::checked::map_list map_list() const; + inline isl::checked::multi_pw_aff max_multi_pw_aff() const; + inline isl::checked::multi_pw_aff min_multi_pw_aff() const; + inline class size n_basic_map() const; + inline isl::checked::set params() const; + inline isl::checked::basic_map polyhedral_hull() const; + inline isl::checked::map preimage_domain(isl::checked::multi_aff ma) const; + inline isl::checked::map preimage_domain(isl::checked::multi_pw_aff mpa) const; + inline isl::checked::map preimage_domain(isl::checked::pw_multi_aff pma) const; + inline isl::checked::union_map preimage_domain(const isl::checked::union_pw_multi_aff &upma) const; + inline isl::checked::map preimage_range(isl::checked::multi_aff ma) const; + inline isl::checked::map preimage_range(isl::checked::pw_multi_aff pma) const; + inline isl::checked::union_map preimage_range(const isl::checked::union_pw_multi_aff &upma) const; + inline isl::checked::map product(isl::checked::map map2) const; + inline isl::checked::union_map product(const isl::checked::union_map &umap2) const; + inline isl::checked::map product(const isl::checked::basic_map &map2) const; + inline isl::checked::map project_out_all_params() const; + inline isl::checked::map project_out_param(isl::checked::id id) const; + inline isl::checked::map project_out_param(const std::string &id) const; + inline isl::checked::map project_out_param(isl::checked::id_list list) const; + inline isl::checked::set range() const; + inline isl::checked::map range_factor_domain() const; + inline isl::checked::map range_factor_range() const; + inline isl::checked::fixed_box range_lattice_tile() const; + inline isl::checked::fixed_box get_range_lattice_tile() const; + inline isl::checked::union_map range_map() const; + inline isl::checked::map range_product(isl::checked::map map2) const; + inline isl::checked::union_map range_product(const isl::checked::union_map &umap2) const; + inline isl::checked::map range_product(const isl::checked::basic_map &map2) const; + inline isl::checked::map range_reverse() const; + inline isl::checked::fixed_box range_simple_fixed_box_hull() const; + inline isl::checked::fixed_box get_range_simple_fixed_box_hull() const; + inline class size range_tuple_dim() const; + inline isl::checked::id range_tuple_id() const; + inline isl::checked::id get_range_tuple_id() const; + inline isl::checked::map reverse() const; + inline isl::checked::basic_map sample() const; + inline isl::checked::map set_domain_tuple(isl::checked::id id) const; + inline isl::checked::map set_domain_tuple(const std::string &id) const; + inline isl::checked::map set_range_tuple(isl::checked::id id) const; + inline isl::checked::map set_range_tuple(const std::string &id) const; + inline isl::checked::space space() const; + inline isl::checked::space get_space() const; + inline isl::checked::map subtract(isl::checked::map map2) const; + inline isl::checked::union_map subtract(const isl::checked::union_map &umap2) const; + inline isl::checked::map subtract(const isl::checked::basic_map &map2) const; + inline isl::checked::union_map subtract_domain(const isl::checked::union_set &dom) const; + inline isl::checked::union_map subtract_range(const isl::checked::union_set &dom) const; + inline isl::checked::map_list to_list() const; + inline isl::checked::union_map to_union_map() const; + inline isl::checked::map uncurry() const; + inline isl::checked::map unite(isl::checked::map map2) const; + inline isl::checked::union_map unite(const isl::checked::union_map &umap2) const; + inline isl::checked::map unite(const isl::checked::basic_map &map2) const; + static inline isl::checked::map universe(isl::checked::space space); + inline isl::checked::basic_map unshifted_simple_hull() const; + inline isl::checked::map upper_bound(isl::checked::multi_pw_aff upper) const; + inline isl::checked::set wrap() const; + inline isl::checked::map zip() const; +}; + +// declarations for isl::map_list +inline map_list manage(__isl_take isl_map_list *ptr); +inline map_list manage_copy(__isl_keep isl_map_list *ptr); + +class map_list { + friend inline map_list manage(__isl_take isl_map_list *ptr); + friend inline map_list manage_copy(__isl_keep isl_map_list *ptr); + +protected: + isl_map_list *ptr = nullptr; + + inline explicit map_list(__isl_take isl_map_list *ptr); + +public: + inline /* implicit */ map_list(); + inline /* implicit */ map_list(const map_list &obj); + inline explicit map_list(isl::checked::ctx ctx, int n); + inline explicit map_list(isl::checked::map el); + inline explicit map_list(isl::checked::ctx ctx, const std::string &str); + inline map_list &operator=(map_list obj); + inline ~map_list(); + inline __isl_give isl_map_list *copy() const &; + inline __isl_give isl_map_list *copy() && = delete; + inline __isl_keep isl_map_list *get() const; + inline __isl_give isl_map_list *release(); + inline bool is_null() const; + inline isl::checked::ctx ctx() const; + + inline isl::checked::map_list add(isl::checked::map el) const; + inline isl::checked::map at(int index) const; + inline isl::checked::map get_at(int index) const; + inline isl::checked::map_list clear() const; + inline isl::checked::map_list concat(isl::checked::map_list list2) const; + inline isl::checked::map_list drop(unsigned int first, unsigned int n) const; + inline stat foreach(const std::function &fn) const; + inline stat foreach_scc(const std::function &follows, const std::function &fn) const; + inline isl::checked::map_list insert(unsigned int pos, isl::checked::map el) const; + inline isl::checked::map_list set_at(int index, isl::checked::map el) const; + inline class size size() const; +}; + +// declarations for isl::multi_aff +inline multi_aff manage(__isl_take isl_multi_aff *ptr); +inline multi_aff manage_copy(__isl_keep isl_multi_aff *ptr); + +class multi_aff { + friend inline multi_aff manage(__isl_take isl_multi_aff *ptr); + friend inline multi_aff manage_copy(__isl_keep isl_multi_aff *ptr); + +protected: + isl_multi_aff *ptr = nullptr; + + inline explicit multi_aff(__isl_take isl_multi_aff *ptr); + +public: + inline /* implicit */ multi_aff(); + inline /* implicit */ multi_aff(const multi_aff &obj); + inline /* implicit */ multi_aff(isl::checked::aff aff); + inline explicit multi_aff(isl::checked::space space, isl::checked::aff_list list); + inline explicit multi_aff(isl::checked::ctx ctx, const std::string &str); + inline multi_aff &operator=(multi_aff obj); + inline ~multi_aff(); + inline __isl_give isl_multi_aff *copy() const &; + inline __isl_give isl_multi_aff *copy() && = delete; + inline __isl_keep isl_multi_aff *get() const; + inline __isl_give isl_multi_aff *release(); + inline bool is_null() const; + inline isl::checked::ctx ctx() const; + + inline isl::checked::multi_aff add(isl::checked::multi_aff multi2) const; + inline isl::checked::multi_pw_aff add(const isl::checked::multi_pw_aff &multi2) const; + inline isl::checked::multi_union_pw_aff add(const isl::checked::multi_union_pw_aff &multi2) const; + inline isl::checked::pw_multi_aff add(const isl::checked::pw_multi_aff &pma2) const; + inline isl::checked::union_pw_multi_aff add(const isl::checked::union_pw_multi_aff &upma2) const; + inline isl::checked::multi_aff add(const isl::checked::aff &multi2) const; + inline isl::checked::multi_aff add_constant(isl::checked::multi_val mv) const; + inline isl::checked::multi_aff add_constant(isl::checked::val v) const; + inline isl::checked::multi_aff add_constant(long v) const; + inline isl::checked::union_pw_multi_aff apply(const isl::checked::union_pw_multi_aff &upma2) const; + inline isl::checked::map as_map() const; + inline isl::checked::multi_aff as_multi_aff() const; + inline isl::checked::multi_union_pw_aff as_multi_union_pw_aff() const; + inline isl::checked::pw_multi_aff as_pw_multi_aff() const; + inline isl::checked::set as_set() const; + inline isl::checked::union_map as_union_map() const; + inline isl::checked::aff at(int pos) const; + inline isl::checked::aff get_at(int pos) const; + inline isl::checked::basic_set bind(isl::checked::multi_id tuple) const; + inline isl::checked::multi_aff bind_domain(isl::checked::multi_id tuple) const; + inline isl::checked::multi_aff bind_domain_wrapped_domain(isl::checked::multi_id tuple) const; + inline isl::checked::pw_multi_aff coalesce() const; + inline isl::checked::multi_val constant_multi_val() const; + inline isl::checked::multi_val get_constant_multi_val() const; + inline isl::checked::set domain() const; + static inline isl::checked::multi_aff domain_map(isl::checked::space space); + inline isl::checked::multi_aff domain_reverse() const; + inline isl::checked::pw_multi_aff drop_unused_params() const; + inline isl::checked::pw_multi_aff extract_pw_multi_aff(const isl::checked::space &space) const; + inline isl::checked::multi_aff flat_range_product(isl::checked::multi_aff multi2) const; + inline isl::checked::multi_pw_aff flat_range_product(const isl::checked::multi_pw_aff &multi2) const; + inline isl::checked::multi_union_pw_aff flat_range_product(const isl::checked::multi_union_pw_aff &multi2) const; + inline isl::checked::pw_multi_aff flat_range_product(const isl::checked::pw_multi_aff &pma2) const; + inline isl::checked::union_pw_multi_aff flat_range_product(const isl::checked::union_pw_multi_aff &upma2) const; + inline isl::checked::multi_aff flat_range_product(const isl::checked::aff &multi2) const; + inline isl::checked::multi_aff floor() const; + inline stat foreach_piece(const std::function &fn) const; + inline isl::checked::multi_aff gist(isl::checked::set context) const; + inline isl::checked::union_pw_multi_aff gist(const isl::checked::union_set &context) const; + inline isl::checked::multi_aff gist(const isl::checked::basic_set &context) const; + inline isl::checked::multi_aff gist(const isl::checked::point &context) const; + inline isl::checked::multi_aff gist_params(isl::checked::set context) const; + inline boolean has_range_tuple_id() const; + inline isl::checked::multi_aff identity() const; + static inline isl::checked::multi_aff identity_on_domain(isl::checked::space space); + inline isl::checked::multi_aff insert_domain(isl::checked::space domain) const; + inline isl::checked::pw_multi_aff intersect_domain(const isl::checked::set &set) const; + inline isl::checked::union_pw_multi_aff intersect_domain(const isl::checked::space &space) const; + inline isl::checked::union_pw_multi_aff intersect_domain(const isl::checked::union_set &uset) const; + inline isl::checked::union_pw_multi_aff intersect_domain_wrapped_domain(const isl::checked::union_set &uset) const; + inline isl::checked::union_pw_multi_aff intersect_domain_wrapped_range(const isl::checked::union_set &uset) const; + inline isl::checked::pw_multi_aff intersect_params(const isl::checked::set &set) const; + inline boolean involves_locals() const; + inline boolean involves_nan() const; + inline boolean involves_param(const isl::checked::id &id) const; + inline boolean involves_param(const std::string &id) const; + inline boolean involves_param(const isl::checked::id_list &list) const; + inline boolean isa_multi_aff() const; + inline boolean isa_pw_multi_aff() const; + inline isl::checked::aff_list list() const; + inline isl::checked::aff_list get_list() const; + inline isl::checked::multi_pw_aff max(const isl::checked::multi_pw_aff &multi2) const; + inline isl::checked::multi_val max_multi_val() const; + inline isl::checked::multi_pw_aff min(const isl::checked::multi_pw_aff &multi2) const; + inline isl::checked::multi_val min_multi_val() const; + static inline isl::checked::multi_aff multi_val_on_domain(isl::checked::space space, isl::checked::multi_val mv); + inline class size n_piece() const; + inline isl::checked::multi_aff neg() const; + inline boolean plain_is_empty() const; + inline boolean plain_is_equal(const isl::checked::multi_aff &multi2) const; + inline boolean plain_is_equal(const isl::checked::multi_pw_aff &multi2) const; + inline boolean plain_is_equal(const isl::checked::multi_union_pw_aff &multi2) const; + inline boolean plain_is_equal(const isl::checked::pw_multi_aff &pma2) const; + inline boolean plain_is_equal(const isl::checked::union_pw_multi_aff &upma2) const; + inline boolean plain_is_equal(const isl::checked::aff &multi2) const; + inline isl::checked::pw_multi_aff preimage_domain_wrapped_domain(const isl::checked::pw_multi_aff &pma2) const; + inline isl::checked::union_pw_multi_aff preimage_domain_wrapped_domain(const isl::checked::union_pw_multi_aff &upma2) const; + inline isl::checked::multi_aff product(isl::checked::multi_aff multi2) const; + inline isl::checked::multi_pw_aff product(const isl::checked::multi_pw_aff &multi2) const; + inline isl::checked::pw_multi_aff product(const isl::checked::pw_multi_aff &pma2) const; + inline isl::checked::multi_aff product(const isl::checked::aff &multi2) const; + inline isl::checked::multi_aff pullback(isl::checked::multi_aff ma2) const; + inline isl::checked::multi_pw_aff pullback(const isl::checked::multi_pw_aff &mpa2) const; + inline isl::checked::pw_multi_aff pullback(const isl::checked::pw_multi_aff &pma2) const; + inline isl::checked::union_pw_multi_aff pullback(const isl::checked::union_pw_multi_aff &upma2) const; + inline isl::checked::multi_aff pullback(const isl::checked::aff &ma2) const; + inline isl::checked::pw_multi_aff_list pw_multi_aff_list() const; + inline isl::checked::pw_multi_aff range_factor_domain() const; + inline isl::checked::pw_multi_aff range_factor_range() const; + static inline isl::checked::multi_aff range_map(isl::checked::space space); + inline isl::checked::multi_aff range_product(isl::checked::multi_aff multi2) const; + inline isl::checked::multi_pw_aff range_product(const isl::checked::multi_pw_aff &multi2) const; + inline isl::checked::multi_union_pw_aff range_product(const isl::checked::multi_union_pw_aff &multi2) const; + inline isl::checked::pw_multi_aff range_product(const isl::checked::pw_multi_aff &pma2) const; + inline isl::checked::union_pw_multi_aff range_product(const isl::checked::union_pw_multi_aff &upma2) const; + inline isl::checked::multi_aff range_product(const isl::checked::aff &multi2) const; + inline isl::checked::id range_tuple_id() const; + inline isl::checked::id get_range_tuple_id() const; + inline isl::checked::multi_aff reset_range_tuple_id() const; + inline isl::checked::multi_aff scale(isl::checked::multi_val mv) const; + inline isl::checked::multi_aff scale(isl::checked::val v) const; + inline isl::checked::multi_aff scale(long v) const; + inline isl::checked::multi_aff scale_down(isl::checked::multi_val mv) const; + inline isl::checked::multi_aff scale_down(isl::checked::val v) const; + inline isl::checked::multi_aff scale_down(long v) const; + inline isl::checked::multi_aff set_at(int pos, isl::checked::aff el) const; + inline isl::checked::multi_pw_aff set_at(int pos, const isl::checked::pw_aff &el) const; + inline isl::checked::multi_union_pw_aff set_at(int pos, const isl::checked::union_pw_aff &el) const; + inline isl::checked::multi_aff set_range_tuple(isl::checked::id id) const; + inline isl::checked::multi_aff set_range_tuple(const std::string &id) const; + inline class size size() const; + inline isl::checked::space space() const; + inline isl::checked::space get_space() const; + inline isl::checked::multi_aff sub(isl::checked::multi_aff multi2) const; + inline isl::checked::multi_pw_aff sub(const isl::checked::multi_pw_aff &multi2) const; + inline isl::checked::multi_union_pw_aff sub(const isl::checked::multi_union_pw_aff &multi2) const; + inline isl::checked::pw_multi_aff sub(const isl::checked::pw_multi_aff &pma2) const; + inline isl::checked::union_pw_multi_aff sub(const isl::checked::union_pw_multi_aff &upma2) const; + inline isl::checked::multi_aff sub(const isl::checked::aff &multi2) const; + inline isl::checked::pw_multi_aff subtract_domain(const isl::checked::set &set) const; + inline isl::checked::union_pw_multi_aff subtract_domain(const isl::checked::space &space) const; + inline isl::checked::union_pw_multi_aff subtract_domain(const isl::checked::union_set &uset) const; + inline isl::checked::pw_multi_aff_list to_list() const; + inline isl::checked::multi_pw_aff to_multi_pw_aff() const; + inline isl::checked::multi_union_pw_aff to_multi_union_pw_aff() const; + inline isl::checked::pw_multi_aff to_pw_multi_aff() const; + inline isl::checked::union_pw_multi_aff to_union_pw_multi_aff() const; + inline isl::checked::multi_aff unbind_params_insert_domain(isl::checked::multi_id domain) const; + inline isl::checked::multi_pw_aff union_add(const isl::checked::multi_pw_aff &mpa2) const; + inline isl::checked::multi_union_pw_aff union_add(const isl::checked::multi_union_pw_aff &mupa2) const; + inline isl::checked::pw_multi_aff union_add(const isl::checked::pw_multi_aff &pma2) const; + inline isl::checked::union_pw_multi_aff union_add(const isl::checked::union_pw_multi_aff &upma2) const; + static inline isl::checked::multi_aff zero(isl::checked::space space); +}; + +// declarations for isl::multi_id +inline multi_id manage(__isl_take isl_multi_id *ptr); +inline multi_id manage_copy(__isl_keep isl_multi_id *ptr); + +class multi_id { + friend inline multi_id manage(__isl_take isl_multi_id *ptr); + friend inline multi_id manage_copy(__isl_keep isl_multi_id *ptr); + +protected: + isl_multi_id *ptr = nullptr; + + inline explicit multi_id(__isl_take isl_multi_id *ptr); + +public: + inline /* implicit */ multi_id(); + inline /* implicit */ multi_id(const multi_id &obj); + inline explicit multi_id(isl::checked::space space, isl::checked::id_list list); + inline explicit multi_id(isl::checked::ctx ctx, const std::string &str); + inline multi_id &operator=(multi_id obj); + inline ~multi_id(); + inline __isl_give isl_multi_id *copy() const &; + inline __isl_give isl_multi_id *copy() && = delete; + inline __isl_keep isl_multi_id *get() const; + inline __isl_give isl_multi_id *release(); + inline bool is_null() const; + inline isl::checked::ctx ctx() const; + + inline isl::checked::id at(int pos) const; + inline isl::checked::id get_at(int pos) const; + inline isl::checked::multi_id flat_range_product(isl::checked::multi_id multi2) const; + inline isl::checked::id_list list() const; + inline isl::checked::id_list get_list() const; + inline boolean plain_is_equal(const isl::checked::multi_id &multi2) const; + inline isl::checked::multi_id range_product(isl::checked::multi_id multi2) const; + inline isl::checked::multi_id set_at(int pos, isl::checked::id el) const; + inline isl::checked::multi_id set_at(int pos, const std::string &el) const; + inline class size size() const; + inline isl::checked::space space() const; + inline isl::checked::space get_space() const; +}; + +// declarations for isl::multi_pw_aff +inline multi_pw_aff manage(__isl_take isl_multi_pw_aff *ptr); +inline multi_pw_aff manage_copy(__isl_keep isl_multi_pw_aff *ptr); + +class multi_pw_aff { + friend inline multi_pw_aff manage(__isl_take isl_multi_pw_aff *ptr); + friend inline multi_pw_aff manage_copy(__isl_keep isl_multi_pw_aff *ptr); + +protected: + isl_multi_pw_aff *ptr = nullptr; + + inline explicit multi_pw_aff(__isl_take isl_multi_pw_aff *ptr); + +public: + inline /* implicit */ multi_pw_aff(); + inline /* implicit */ multi_pw_aff(const multi_pw_aff &obj); + inline /* implicit */ multi_pw_aff(isl::checked::aff aff); + inline /* implicit */ multi_pw_aff(isl::checked::multi_aff ma); + inline /* implicit */ multi_pw_aff(isl::checked::pw_aff pa); + inline explicit multi_pw_aff(isl::checked::space space, isl::checked::pw_aff_list list); + inline /* implicit */ multi_pw_aff(isl::checked::pw_multi_aff pma); + inline explicit multi_pw_aff(isl::checked::ctx ctx, const std::string &str); + inline multi_pw_aff &operator=(multi_pw_aff obj); + inline ~multi_pw_aff(); + inline __isl_give isl_multi_pw_aff *copy() const &; + inline __isl_give isl_multi_pw_aff *copy() && = delete; + inline __isl_keep isl_multi_pw_aff *get() const; + inline __isl_give isl_multi_pw_aff *release(); + inline bool is_null() const; + inline isl::checked::ctx ctx() const; + + inline isl::checked::multi_pw_aff add(isl::checked::multi_pw_aff multi2) const; + inline isl::checked::multi_union_pw_aff add(const isl::checked::multi_union_pw_aff &multi2) const; + inline isl::checked::multi_pw_aff add(const isl::checked::aff &multi2) const; + inline isl::checked::multi_pw_aff add(const isl::checked::multi_aff &multi2) const; + inline isl::checked::multi_pw_aff add(const isl::checked::pw_aff &multi2) const; + inline isl::checked::multi_pw_aff add(const isl::checked::pw_multi_aff &multi2) const; + inline isl::checked::multi_pw_aff add_constant(isl::checked::multi_val mv) const; + inline isl::checked::multi_pw_aff add_constant(isl::checked::val v) const; + inline isl::checked::multi_pw_aff add_constant(long v) const; + inline isl::checked::map as_map() const; + inline isl::checked::multi_aff as_multi_aff() const; + inline isl::checked::set as_set() const; + inline isl::checked::pw_aff at(int pos) const; + inline isl::checked::pw_aff get_at(int pos) const; + inline isl::checked::set bind(isl::checked::multi_id tuple) const; + inline isl::checked::multi_pw_aff bind_domain(isl::checked::multi_id tuple) const; + inline isl::checked::multi_pw_aff bind_domain_wrapped_domain(isl::checked::multi_id tuple) const; + inline isl::checked::multi_pw_aff coalesce() const; + inline isl::checked::set domain() const; + inline isl::checked::multi_pw_aff domain_reverse() const; + inline isl::checked::multi_pw_aff flat_range_product(isl::checked::multi_pw_aff multi2) const; + inline isl::checked::multi_union_pw_aff flat_range_product(const isl::checked::multi_union_pw_aff &multi2) const; + inline isl::checked::multi_pw_aff flat_range_product(const isl::checked::aff &multi2) const; + inline isl::checked::multi_pw_aff flat_range_product(const isl::checked::multi_aff &multi2) const; + inline isl::checked::multi_pw_aff flat_range_product(const isl::checked::pw_aff &multi2) const; + inline isl::checked::multi_pw_aff flat_range_product(const isl::checked::pw_multi_aff &multi2) const; + inline isl::checked::multi_pw_aff gist(isl::checked::set set) const; + inline isl::checked::multi_union_pw_aff gist(const isl::checked::union_set &context) const; + inline isl::checked::multi_pw_aff gist(const isl::checked::basic_set &set) const; + inline isl::checked::multi_pw_aff gist(const isl::checked::point &set) const; + inline isl::checked::multi_pw_aff gist_params(isl::checked::set set) const; + inline boolean has_range_tuple_id() const; + inline isl::checked::multi_pw_aff identity() const; + static inline isl::checked::multi_pw_aff identity_on_domain(isl::checked::space space); + inline isl::checked::multi_pw_aff insert_domain(isl::checked::space domain) const; + inline isl::checked::multi_pw_aff intersect_domain(isl::checked::set domain) const; + inline isl::checked::multi_union_pw_aff intersect_domain(const isl::checked::union_set &uset) const; + inline isl::checked::multi_pw_aff intersect_domain(const isl::checked::basic_set &domain) const; + inline isl::checked::multi_pw_aff intersect_domain(const isl::checked::point &domain) const; + inline isl::checked::multi_pw_aff intersect_params(isl::checked::set set) const; + inline boolean involves_nan() const; + inline boolean involves_param(const isl::checked::id &id) const; + inline boolean involves_param(const std::string &id) const; + inline boolean involves_param(const isl::checked::id_list &list) const; + inline boolean isa_multi_aff() const; + inline isl::checked::pw_aff_list list() const; + inline isl::checked::pw_aff_list get_list() const; + inline isl::checked::multi_pw_aff max(isl::checked::multi_pw_aff multi2) const; + inline isl::checked::multi_val max_multi_val() const; + inline isl::checked::multi_pw_aff min(isl::checked::multi_pw_aff multi2) const; + inline isl::checked::multi_val min_multi_val() const; + inline isl::checked::multi_pw_aff neg() const; + inline boolean plain_is_equal(const isl::checked::multi_pw_aff &multi2) const; + inline boolean plain_is_equal(const isl::checked::multi_union_pw_aff &multi2) const; + inline boolean plain_is_equal(const isl::checked::aff &multi2) const; + inline boolean plain_is_equal(const isl::checked::multi_aff &multi2) const; + inline boolean plain_is_equal(const isl::checked::pw_aff &multi2) const; + inline boolean plain_is_equal(const isl::checked::pw_multi_aff &multi2) const; + inline isl::checked::multi_pw_aff product(isl::checked::multi_pw_aff multi2) const; + inline isl::checked::multi_pw_aff pullback(isl::checked::multi_aff ma) const; + inline isl::checked::multi_pw_aff pullback(isl::checked::multi_pw_aff mpa2) const; + inline isl::checked::multi_pw_aff pullback(isl::checked::pw_multi_aff pma) const; + inline isl::checked::multi_union_pw_aff pullback(const isl::checked::union_pw_multi_aff &upma) const; + inline isl::checked::multi_pw_aff range_product(isl::checked::multi_pw_aff multi2) const; + inline isl::checked::multi_union_pw_aff range_product(const isl::checked::multi_union_pw_aff &multi2) const; + inline isl::checked::multi_pw_aff range_product(const isl::checked::aff &multi2) const; + inline isl::checked::multi_pw_aff range_product(const isl::checked::multi_aff &multi2) const; + inline isl::checked::multi_pw_aff range_product(const isl::checked::pw_aff &multi2) const; + inline isl::checked::multi_pw_aff range_product(const isl::checked::pw_multi_aff &multi2) const; + inline isl::checked::id range_tuple_id() const; + inline isl::checked::id get_range_tuple_id() const; + inline isl::checked::multi_pw_aff reset_range_tuple_id() const; + inline isl::checked::multi_pw_aff scale(isl::checked::multi_val mv) const; + inline isl::checked::multi_pw_aff scale(isl::checked::val v) const; + inline isl::checked::multi_pw_aff scale(long v) const; + inline isl::checked::multi_pw_aff scale_down(isl::checked::multi_val mv) const; + inline isl::checked::multi_pw_aff scale_down(isl::checked::val v) const; + inline isl::checked::multi_pw_aff scale_down(long v) const; + inline isl::checked::multi_pw_aff set_at(int pos, isl::checked::pw_aff el) const; + inline isl::checked::multi_union_pw_aff set_at(int pos, const isl::checked::union_pw_aff &el) const; + inline isl::checked::multi_pw_aff set_range_tuple(isl::checked::id id) const; + inline isl::checked::multi_pw_aff set_range_tuple(const std::string &id) const; + inline class size size() const; + inline isl::checked::space space() const; + inline isl::checked::space get_space() const; + inline isl::checked::multi_pw_aff sub(isl::checked::multi_pw_aff multi2) const; + inline isl::checked::multi_union_pw_aff sub(const isl::checked::multi_union_pw_aff &multi2) const; + inline isl::checked::multi_pw_aff sub(const isl::checked::aff &multi2) const; + inline isl::checked::multi_pw_aff sub(const isl::checked::multi_aff &multi2) const; + inline isl::checked::multi_pw_aff sub(const isl::checked::pw_aff &multi2) const; + inline isl::checked::multi_pw_aff sub(const isl::checked::pw_multi_aff &multi2) const; + inline isl::checked::multi_pw_aff unbind_params_insert_domain(isl::checked::multi_id domain) const; + inline isl::checked::multi_pw_aff union_add(isl::checked::multi_pw_aff mpa2) const; + inline isl::checked::multi_union_pw_aff union_add(const isl::checked::multi_union_pw_aff &mupa2) const; + inline isl::checked::multi_pw_aff union_add(const isl::checked::aff &mpa2) const; + inline isl::checked::multi_pw_aff union_add(const isl::checked::multi_aff &mpa2) const; + inline isl::checked::multi_pw_aff union_add(const isl::checked::pw_aff &mpa2) const; + inline isl::checked::multi_pw_aff union_add(const isl::checked::pw_multi_aff &mpa2) const; + static inline isl::checked::multi_pw_aff zero(isl::checked::space space); +}; + +// declarations for isl::multi_union_pw_aff +inline multi_union_pw_aff manage(__isl_take isl_multi_union_pw_aff *ptr); +inline multi_union_pw_aff manage_copy(__isl_keep isl_multi_union_pw_aff *ptr); + +class multi_union_pw_aff { + friend inline multi_union_pw_aff manage(__isl_take isl_multi_union_pw_aff *ptr); + friend inline multi_union_pw_aff manage_copy(__isl_keep isl_multi_union_pw_aff *ptr); + +protected: + isl_multi_union_pw_aff *ptr = nullptr; + + inline explicit multi_union_pw_aff(__isl_take isl_multi_union_pw_aff *ptr); + +public: + inline /* implicit */ multi_union_pw_aff(); + inline /* implicit */ multi_union_pw_aff(const multi_union_pw_aff &obj); + inline /* implicit */ multi_union_pw_aff(isl::checked::multi_pw_aff mpa); + inline /* implicit */ multi_union_pw_aff(isl::checked::union_pw_aff upa); + inline explicit multi_union_pw_aff(isl::checked::space space, isl::checked::union_pw_aff_list list); + inline explicit multi_union_pw_aff(isl::checked::ctx ctx, const std::string &str); + inline multi_union_pw_aff &operator=(multi_union_pw_aff obj); + inline ~multi_union_pw_aff(); + inline __isl_give isl_multi_union_pw_aff *copy() const &; + inline __isl_give isl_multi_union_pw_aff *copy() && = delete; + inline __isl_keep isl_multi_union_pw_aff *get() const; + inline __isl_give isl_multi_union_pw_aff *release(); + inline bool is_null() const; + inline isl::checked::ctx ctx() const; + + inline isl::checked::multi_union_pw_aff add(isl::checked::multi_union_pw_aff multi2) const; + inline isl::checked::union_pw_aff at(int pos) const; + inline isl::checked::union_pw_aff get_at(int pos) const; + inline isl::checked::union_set bind(isl::checked::multi_id tuple) const; + inline isl::checked::multi_union_pw_aff coalesce() const; + inline isl::checked::union_set domain() const; + inline isl::checked::multi_union_pw_aff flat_range_product(isl::checked::multi_union_pw_aff multi2) const; + inline isl::checked::multi_union_pw_aff gist(isl::checked::union_set context) const; + inline isl::checked::multi_union_pw_aff gist_params(isl::checked::set context) const; + inline boolean has_range_tuple_id() const; + inline isl::checked::multi_union_pw_aff intersect_domain(isl::checked::union_set uset) const; + inline isl::checked::multi_union_pw_aff intersect_params(isl::checked::set params) const; + inline boolean involves_nan() const; + inline isl::checked::union_pw_aff_list list() const; + inline isl::checked::union_pw_aff_list get_list() const; + inline isl::checked::multi_union_pw_aff neg() const; + inline boolean plain_is_equal(const isl::checked::multi_union_pw_aff &multi2) const; + inline isl::checked::multi_union_pw_aff pullback(isl::checked::union_pw_multi_aff upma) const; + inline isl::checked::multi_union_pw_aff range_product(isl::checked::multi_union_pw_aff multi2) const; + inline isl::checked::id range_tuple_id() const; + inline isl::checked::id get_range_tuple_id() const; + inline isl::checked::multi_union_pw_aff reset_range_tuple_id() const; + inline isl::checked::multi_union_pw_aff scale(isl::checked::multi_val mv) const; + inline isl::checked::multi_union_pw_aff scale(isl::checked::val v) const; + inline isl::checked::multi_union_pw_aff scale(long v) const; + inline isl::checked::multi_union_pw_aff scale_down(isl::checked::multi_val mv) const; + inline isl::checked::multi_union_pw_aff scale_down(isl::checked::val v) const; + inline isl::checked::multi_union_pw_aff scale_down(long v) const; + inline isl::checked::multi_union_pw_aff set_at(int pos, isl::checked::union_pw_aff el) const; + inline isl::checked::multi_union_pw_aff set_range_tuple(isl::checked::id id) const; + inline isl::checked::multi_union_pw_aff set_range_tuple(const std::string &id) const; + inline class size size() const; + inline isl::checked::space space() const; + inline isl::checked::space get_space() const; + inline isl::checked::multi_union_pw_aff sub(isl::checked::multi_union_pw_aff multi2) const; + inline isl::checked::multi_union_pw_aff union_add(isl::checked::multi_union_pw_aff mupa2) const; + static inline isl::checked::multi_union_pw_aff zero(isl::checked::space space); +}; + +// declarations for isl::multi_val +inline multi_val manage(__isl_take isl_multi_val *ptr); +inline multi_val manage_copy(__isl_keep isl_multi_val *ptr); + +class multi_val { + friend inline multi_val manage(__isl_take isl_multi_val *ptr); + friend inline multi_val manage_copy(__isl_keep isl_multi_val *ptr); + +protected: + isl_multi_val *ptr = nullptr; + + inline explicit multi_val(__isl_take isl_multi_val *ptr); + +public: + inline /* implicit */ multi_val(); + inline /* implicit */ multi_val(const multi_val &obj); + inline explicit multi_val(isl::checked::space space, isl::checked::val_list list); + inline explicit multi_val(isl::checked::ctx ctx, const std::string &str); + inline multi_val &operator=(multi_val obj); + inline ~multi_val(); + inline __isl_give isl_multi_val *copy() const &; + inline __isl_give isl_multi_val *copy() && = delete; + inline __isl_keep isl_multi_val *get() const; + inline __isl_give isl_multi_val *release(); + inline bool is_null() const; + inline isl::checked::ctx ctx() const; + + inline isl::checked::multi_val add(isl::checked::multi_val multi2) const; + inline isl::checked::multi_val add(isl::checked::val v) const; + inline isl::checked::multi_val add(long v) const; + inline isl::checked::val at(int pos) const; + inline isl::checked::val get_at(int pos) const; + inline isl::checked::multi_val flat_range_product(isl::checked::multi_val multi2) const; + inline boolean has_range_tuple_id() const; + inline boolean involves_nan() const; + inline isl::checked::val_list list() const; + inline isl::checked::val_list get_list() const; + inline isl::checked::multi_val max(isl::checked::multi_val multi2) const; + inline isl::checked::multi_val min(isl::checked::multi_val multi2) const; + inline isl::checked::multi_val neg() const; + inline boolean plain_is_equal(const isl::checked::multi_val &multi2) const; + inline isl::checked::multi_val product(isl::checked::multi_val multi2) const; + inline isl::checked::multi_val range_product(isl::checked::multi_val multi2) const; + inline isl::checked::id range_tuple_id() const; + inline isl::checked::id get_range_tuple_id() const; + inline isl::checked::multi_val reset_range_tuple_id() const; + inline isl::checked::multi_val scale(isl::checked::multi_val mv) const; + inline isl::checked::multi_val scale(isl::checked::val v) const; + inline isl::checked::multi_val scale(long v) const; + inline isl::checked::multi_val scale_down(isl::checked::multi_val mv) const; + inline isl::checked::multi_val scale_down(isl::checked::val v) const; + inline isl::checked::multi_val scale_down(long v) const; + inline isl::checked::multi_val set_at(int pos, isl::checked::val el) const; + inline isl::checked::multi_val set_at(int pos, long el) const; + inline isl::checked::multi_val set_range_tuple(isl::checked::id id) const; + inline isl::checked::multi_val set_range_tuple(const std::string &id) const; + inline class size size() const; + inline isl::checked::space space() const; + inline isl::checked::space get_space() const; + inline isl::checked::multi_val sub(isl::checked::multi_val multi2) const; + static inline isl::checked::multi_val zero(isl::checked::space space); +}; + +// declarations for isl::point +inline point manage(__isl_take isl_point *ptr); +inline point manage_copy(__isl_keep isl_point *ptr); + +class point { + friend inline point manage(__isl_take isl_point *ptr); + friend inline point manage_copy(__isl_keep isl_point *ptr); + +protected: + isl_point *ptr = nullptr; + + inline explicit point(__isl_take isl_point *ptr); + +public: + inline /* implicit */ point(); + inline /* implicit */ point(const point &obj); + inline point &operator=(point obj); + inline ~point(); + inline __isl_give isl_point *copy() const &; + inline __isl_give isl_point *copy() && = delete; + inline __isl_keep isl_point *get() const; + inline __isl_give isl_point *release(); + inline bool is_null() const; + inline isl::checked::ctx ctx() const; + + inline isl::checked::basic_set affine_hull() const; + inline isl::checked::basic_set apply(const isl::checked::basic_map &bmap) const; + inline isl::checked::set apply(const isl::checked::map &map) const; + inline isl::checked::union_set apply(const isl::checked::union_map &umap) const; + inline isl::checked::pw_multi_aff as_pw_multi_aff() const; + inline isl::checked::set as_set() const; + inline isl::checked::set bind(const isl::checked::multi_id &tuple) const; + inline isl::checked::set coalesce() const; + inline isl::checked::set complement() const; + inline isl::checked::union_set compute_divs() const; + inline isl::checked::basic_set detect_equalities() const; + inline isl::checked::val dim_max_val(int pos) const; + inline isl::checked::val dim_min_val(int pos) const; + inline isl::checked::set drop_unused_params() const; + inline boolean every_set(const std::function &test) const; + inline isl::checked::set extract_set(const isl::checked::space &space) const; + inline isl::checked::basic_set flatten() const; + inline stat foreach_basic_set(const std::function &fn) const; + inline stat foreach_point(const std::function &fn) const; + inline stat foreach_set(const std::function &fn) const; + inline isl::checked::basic_set gist(const isl::checked::basic_set &context) const; + inline isl::checked::set gist(const isl::checked::set &context) const; + inline isl::checked::union_set gist(const isl::checked::union_set &context) const; + inline isl::checked::set gist_params(const isl::checked::set &context) const; + inline isl::checked::map identity() const; + inline isl::checked::pw_aff indicator_function() const; + inline isl::checked::map insert_domain(const isl::checked::space &domain) const; + inline isl::checked::basic_set intersect(const isl::checked::basic_set &bset2) const; + inline isl::checked::set intersect(const isl::checked::set &set2) const; + inline isl::checked::union_set intersect(const isl::checked::union_set &uset2) const; + inline isl::checked::basic_set intersect_params(const isl::checked::basic_set &bset2) const; + inline isl::checked::set intersect_params(const isl::checked::set ¶ms) const; + inline boolean involves_locals() const; + inline boolean is_disjoint(const isl::checked::set &set2) const; + inline boolean is_disjoint(const isl::checked::union_set &uset2) const; + inline boolean is_empty() const; + inline boolean is_equal(const isl::checked::basic_set &bset2) const; + inline boolean is_equal(const isl::checked::set &set2) const; + inline boolean is_equal(const isl::checked::union_set &uset2) const; + inline boolean is_singleton() const; + inline boolean is_strict_subset(const isl::checked::set &set2) const; + inline boolean is_strict_subset(const isl::checked::union_set &uset2) const; + inline boolean is_subset(const isl::checked::basic_set &bset2) const; + inline boolean is_subset(const isl::checked::set &set2) const; + inline boolean is_subset(const isl::checked::union_set &uset2) const; + inline boolean is_wrapping() const; + inline boolean isa_set() const; + inline isl::checked::fixed_box lattice_tile() const; + inline isl::checked::set lexmax() const; + inline isl::checked::pw_multi_aff lexmax_pw_multi_aff() const; + inline isl::checked::set lexmin() const; + inline isl::checked::pw_multi_aff lexmin_pw_multi_aff() const; + inline isl::checked::set lower_bound(const isl::checked::multi_pw_aff &lower) const; + inline isl::checked::set lower_bound(const isl::checked::multi_val &lower) const; + inline isl::checked::multi_pw_aff max_multi_pw_aff() const; + inline isl::checked::val max_val(const isl::checked::aff &obj) const; + inline isl::checked::multi_pw_aff min_multi_pw_aff() const; + inline isl::checked::val min_val(const isl::checked::aff &obj) const; + inline isl::checked::multi_val multi_val() const; + inline isl::checked::multi_val get_multi_val() const; + inline class size n_basic_set() const; + inline isl::checked::pw_aff param_pw_aff_on_domain(const isl::checked::id &id) const; + inline isl::checked::pw_aff param_pw_aff_on_domain(const std::string &id) const; + inline isl::checked::basic_set params() const; + inline isl::checked::multi_val plain_multi_val_if_fixed() const; + inline isl::checked::basic_set polyhedral_hull() const; + inline isl::checked::set preimage(const isl::checked::multi_aff &ma) const; + inline isl::checked::set preimage(const isl::checked::multi_pw_aff &mpa) const; + inline isl::checked::set preimage(const isl::checked::pw_multi_aff &pma) const; + inline isl::checked::union_set preimage(const isl::checked::union_pw_multi_aff &upma) const; + inline isl::checked::set product(const isl::checked::set &set2) const; + inline isl::checked::set project_out_all_params() const; + inline isl::checked::set project_out_param(const isl::checked::id &id) const; + inline isl::checked::set project_out_param(const std::string &id) const; + inline isl::checked::set project_out_param(const isl::checked::id_list &list) const; + inline isl::checked::pw_aff pw_aff_on_domain(const isl::checked::val &v) const; + inline isl::checked::pw_aff pw_aff_on_domain(long v) const; + inline isl::checked::pw_multi_aff pw_multi_aff_on_domain(const isl::checked::multi_val &mv) const; + inline isl::checked::basic_set sample() const; + inline isl::checked::point sample_point() const; + inline isl::checked::set_list set_list() const; + inline isl::checked::fixed_box simple_fixed_box_hull() const; + inline isl::checked::space space() const; + inline isl::checked::val stride(int pos) const; + inline isl::checked::set subtract(const isl::checked::set &set2) const; + inline isl::checked::union_set subtract(const isl::checked::union_set &uset2) const; + inline isl::checked::set_list to_list() const; + inline isl::checked::set to_set() const; + inline isl::checked::union_set to_union_set() const; + inline isl::checked::map translation() const; + inline class size tuple_dim() const; + inline isl::checked::set unbind_params(const isl::checked::multi_id &tuple) const; + inline isl::checked::map unbind_params_insert_domain(const isl::checked::multi_id &domain) const; + inline isl::checked::set unite(const isl::checked::basic_set &bset2) const; + inline isl::checked::set unite(const isl::checked::set &set2) const; + inline isl::checked::union_set unite(const isl::checked::union_set &uset2) const; + inline isl::checked::basic_set unshifted_simple_hull() const; + inline isl::checked::map unwrap() const; + inline isl::checked::set upper_bound(const isl::checked::multi_pw_aff &upper) const; + inline isl::checked::set upper_bound(const isl::checked::multi_val &upper) const; + inline isl::checked::set wrapped_reverse() const; +}; + +// declarations for isl::pw_aff +inline pw_aff manage(__isl_take isl_pw_aff *ptr); +inline pw_aff manage_copy(__isl_keep isl_pw_aff *ptr); + +class pw_aff { + friend inline pw_aff manage(__isl_take isl_pw_aff *ptr); + friend inline pw_aff manage_copy(__isl_keep isl_pw_aff *ptr); + +protected: + isl_pw_aff *ptr = nullptr; + + inline explicit pw_aff(__isl_take isl_pw_aff *ptr); + +public: + inline /* implicit */ pw_aff(); + inline /* implicit */ pw_aff(const pw_aff &obj); + inline /* implicit */ pw_aff(isl::checked::aff aff); + inline explicit pw_aff(isl::checked::ctx ctx, const std::string &str); + inline pw_aff &operator=(pw_aff obj); + inline ~pw_aff(); + inline __isl_give isl_pw_aff *copy() const &; + inline __isl_give isl_pw_aff *copy() && = delete; + inline __isl_keep isl_pw_aff *get() const; + inline __isl_give isl_pw_aff *release(); + inline bool is_null() const; + inline isl::checked::ctx ctx() const; + + inline isl::checked::multi_pw_aff add(const isl::checked::multi_pw_aff &multi2) const; + inline isl::checked::multi_union_pw_aff add(const isl::checked::multi_union_pw_aff &multi2) const; + inline isl::checked::pw_aff add(isl::checked::pw_aff pwaff2) const; + inline isl::checked::pw_multi_aff add(const isl::checked::pw_multi_aff &pma2) const; + inline isl::checked::union_pw_aff add(const isl::checked::union_pw_aff &upa2) const; + inline isl::checked::union_pw_multi_aff add(const isl::checked::union_pw_multi_aff &upma2) const; + inline isl::checked::pw_aff add(const isl::checked::aff &pwaff2) const; + inline isl::checked::pw_aff add_constant(isl::checked::val v) const; + inline isl::checked::pw_aff add_constant(long v) const; + inline isl::checked::pw_multi_aff add_constant(const isl::checked::multi_val &mv) const; + inline isl::checked::union_pw_multi_aff apply(const isl::checked::union_pw_multi_aff &upma2) const; + inline isl::checked::aff as_aff() const; + inline isl::checked::map as_map() const; + inline isl::checked::multi_aff as_multi_aff() const; + inline isl::checked::multi_union_pw_aff as_multi_union_pw_aff() const; + inline isl::checked::pw_multi_aff as_pw_multi_aff() const; + inline isl::checked::set as_set() const; + inline isl::checked::union_map as_union_map() const; + inline isl::checked::pw_aff at(int pos) const; + inline isl::checked::set bind(const isl::checked::multi_id &tuple) const; + inline isl::checked::set bind(isl::checked::id id) const; + inline isl::checked::set bind(const std::string &id) const; + inline isl::checked::pw_aff bind_domain(isl::checked::multi_id tuple) const; + inline isl::checked::pw_aff bind_domain_wrapped_domain(isl::checked::multi_id tuple) const; + inline isl::checked::pw_aff ceil() const; + inline isl::checked::pw_aff coalesce() const; + inline isl::checked::pw_aff cond(isl::checked::pw_aff pwaff_true, isl::checked::pw_aff pwaff_false) const; + inline isl::checked::pw_aff div(isl::checked::pw_aff pa2) const; + inline isl::checked::set domain() const; + inline isl::checked::pw_aff domain_reverse() const; + inline isl::checked::pw_aff drop_unused_params() const; + inline isl::checked::set eq_set(isl::checked::pw_aff pwaff2) const; + inline isl::checked::val eval(isl::checked::point pnt) const; + inline isl::checked::pw_multi_aff extract_pw_multi_aff(const isl::checked::space &space) const; + inline isl::checked::multi_pw_aff flat_range_product(const isl::checked::multi_pw_aff &multi2) const; + inline isl::checked::multi_union_pw_aff flat_range_product(const isl::checked::multi_union_pw_aff &multi2) const; + inline isl::checked::pw_multi_aff flat_range_product(const isl::checked::pw_multi_aff &pma2) const; + inline isl::checked::union_pw_multi_aff flat_range_product(const isl::checked::union_pw_multi_aff &upma2) const; + inline isl::checked::pw_aff floor() const; + inline stat foreach_piece(const std::function &fn) const; + inline isl::checked::set ge_set(isl::checked::pw_aff pwaff2) const; + inline isl::checked::pw_aff gist(isl::checked::set context) const; + inline isl::checked::union_pw_aff gist(const isl::checked::union_set &context) const; + inline isl::checked::pw_aff gist(const isl::checked::basic_set &context) const; + inline isl::checked::pw_aff gist(const isl::checked::point &context) const; + inline isl::checked::pw_aff gist_params(isl::checked::set context) const; + inline isl::checked::set gt_set(isl::checked::pw_aff pwaff2) const; + inline boolean has_range_tuple_id() const; + inline isl::checked::multi_pw_aff identity() const; + inline isl::checked::pw_aff insert_domain(isl::checked::space domain) const; + inline isl::checked::pw_aff intersect_domain(isl::checked::set set) const; + inline isl::checked::union_pw_aff intersect_domain(const isl::checked::space &space) const; + inline isl::checked::union_pw_aff intersect_domain(const isl::checked::union_set &uset) const; + inline isl::checked::pw_aff intersect_domain(const isl::checked::basic_set &set) const; + inline isl::checked::pw_aff intersect_domain(const isl::checked::point &set) const; + inline isl::checked::union_pw_aff intersect_domain_wrapped_domain(const isl::checked::union_set &uset) const; + inline isl::checked::union_pw_aff intersect_domain_wrapped_range(const isl::checked::union_set &uset) const; + inline isl::checked::pw_aff intersect_params(isl::checked::set set) const; + inline boolean involves_locals() const; + inline boolean involves_nan() const; + inline boolean involves_param(const isl::checked::id &id) const; + inline boolean involves_param(const std::string &id) const; + inline boolean involves_param(const isl::checked::id_list &list) const; + inline boolean isa_aff() const; + inline boolean isa_multi_aff() const; + inline boolean isa_pw_multi_aff() const; + inline isl::checked::set le_set(isl::checked::pw_aff pwaff2) const; + inline isl::checked::pw_aff_list list() const; + inline isl::checked::set lt_set(isl::checked::pw_aff pwaff2) const; + inline isl::checked::multi_pw_aff max(const isl::checked::multi_pw_aff &multi2) const; + inline isl::checked::pw_aff max(isl::checked::pw_aff pwaff2) const; + inline isl::checked::pw_aff max(const isl::checked::aff &pwaff2) const; + inline isl::checked::multi_val max_multi_val() const; + inline isl::checked::val max_val() const; + inline isl::checked::multi_pw_aff min(const isl::checked::multi_pw_aff &multi2) const; + inline isl::checked::pw_aff min(isl::checked::pw_aff pwaff2) const; + inline isl::checked::pw_aff min(const isl::checked::aff &pwaff2) const; + inline isl::checked::multi_val min_multi_val() const; + inline isl::checked::val min_val() const; + inline isl::checked::pw_aff mod(isl::checked::val mod) const; + inline isl::checked::pw_aff mod(long mod) const; + inline isl::checked::pw_aff mul(isl::checked::pw_aff pwaff2) const; + inline class size n_piece() const; + inline isl::checked::set ne_set(isl::checked::pw_aff pwaff2) const; + inline isl::checked::pw_aff neg() const; + static inline isl::checked::pw_aff param_on_domain(isl::checked::set domain, isl::checked::id id); + inline isl::checked::set params() const; + inline boolean plain_is_empty() const; + inline boolean plain_is_equal(const isl::checked::multi_pw_aff &multi2) const; + inline boolean plain_is_equal(const isl::checked::multi_union_pw_aff &multi2) const; + inline boolean plain_is_equal(const isl::checked::pw_aff &pwaff2) const; + inline boolean plain_is_equal(const isl::checked::pw_multi_aff &pma2) const; + inline boolean plain_is_equal(const isl::checked::union_pw_aff &upa2) const; + inline boolean plain_is_equal(const isl::checked::union_pw_multi_aff &upma2) const; + inline boolean plain_is_equal(const isl::checked::aff &pwaff2) const; + inline isl::checked::pw_multi_aff preimage_domain_wrapped_domain(const isl::checked::pw_multi_aff &pma2) const; + inline isl::checked::union_pw_multi_aff preimage_domain_wrapped_domain(const isl::checked::union_pw_multi_aff &upma2) const; + inline isl::checked::multi_pw_aff product(const isl::checked::multi_pw_aff &multi2) const; + inline isl::checked::pw_multi_aff product(const isl::checked::pw_multi_aff &pma2) const; + inline isl::checked::pw_aff pullback(isl::checked::multi_aff ma) const; + inline isl::checked::pw_aff pullback(isl::checked::multi_pw_aff mpa) const; + inline isl::checked::pw_aff pullback(isl::checked::pw_multi_aff pma) const; + inline isl::checked::union_pw_aff pullback(const isl::checked::union_pw_multi_aff &upma) const; + inline isl::checked::pw_multi_aff_list pw_multi_aff_list() const; + inline isl::checked::pw_multi_aff range_factor_domain() const; + inline isl::checked::pw_multi_aff range_factor_range() const; + inline isl::checked::multi_pw_aff range_product(const isl::checked::multi_pw_aff &multi2) const; + inline isl::checked::multi_union_pw_aff range_product(const isl::checked::multi_union_pw_aff &multi2) const; + inline isl::checked::pw_multi_aff range_product(const isl::checked::pw_multi_aff &pma2) const; + inline isl::checked::union_pw_multi_aff range_product(const isl::checked::union_pw_multi_aff &upma2) const; + inline isl::checked::id range_tuple_id() const; + inline isl::checked::multi_pw_aff reset_range_tuple_id() const; + inline isl::checked::pw_aff scale(isl::checked::val v) const; + inline isl::checked::pw_aff scale(long v) const; + inline isl::checked::pw_multi_aff scale(const isl::checked::multi_val &mv) const; + inline isl::checked::pw_aff scale_down(isl::checked::val f) const; + inline isl::checked::pw_aff scale_down(long f) const; + inline isl::checked::pw_multi_aff scale_down(const isl::checked::multi_val &mv) const; + inline isl::checked::multi_pw_aff set_at(int pos, const isl::checked::pw_aff &el) const; + inline isl::checked::multi_union_pw_aff set_at(int pos, const isl::checked::union_pw_aff &el) const; + inline isl::checked::pw_multi_aff set_range_tuple(const isl::checked::id &id) const; + inline isl::checked::pw_multi_aff set_range_tuple(const std::string &id) const; + inline class size size() const; + inline isl::checked::space space() const; + inline isl::checked::space get_space() const; + inline isl::checked::multi_pw_aff sub(const isl::checked::multi_pw_aff &multi2) const; + inline isl::checked::multi_union_pw_aff sub(const isl::checked::multi_union_pw_aff &multi2) const; + inline isl::checked::pw_aff sub(isl::checked::pw_aff pwaff2) const; + inline isl::checked::pw_multi_aff sub(const isl::checked::pw_multi_aff &pma2) const; + inline isl::checked::union_pw_aff sub(const isl::checked::union_pw_aff &upa2) const; + inline isl::checked::union_pw_multi_aff sub(const isl::checked::union_pw_multi_aff &upma2) const; + inline isl::checked::pw_aff sub(const isl::checked::aff &pwaff2) const; + inline isl::checked::pw_aff subtract_domain(isl::checked::set set) const; + inline isl::checked::union_pw_aff subtract_domain(const isl::checked::space &space) const; + inline isl::checked::union_pw_aff subtract_domain(const isl::checked::union_set &uset) const; + inline isl::checked::pw_aff subtract_domain(const isl::checked::basic_set &set) const; + inline isl::checked::pw_aff subtract_domain(const isl::checked::point &set) const; + inline isl::checked::pw_aff tdiv_q(isl::checked::pw_aff pa2) const; + inline isl::checked::pw_aff tdiv_r(isl::checked::pw_aff pa2) const; + inline isl::checked::pw_aff_list to_list() const; + inline isl::checked::multi_pw_aff to_multi_pw_aff() const; + inline isl::checked::union_pw_aff to_union_pw_aff() const; + inline isl::checked::union_pw_multi_aff to_union_pw_multi_aff() const; + inline isl::checked::multi_pw_aff unbind_params_insert_domain(const isl::checked::multi_id &domain) const; + inline isl::checked::multi_pw_aff union_add(const isl::checked::multi_pw_aff &mpa2) const; + inline isl::checked::multi_union_pw_aff union_add(const isl::checked::multi_union_pw_aff &mupa2) const; + inline isl::checked::pw_aff union_add(isl::checked::pw_aff pwaff2) const; + inline isl::checked::pw_multi_aff union_add(const isl::checked::pw_multi_aff &pma2) const; + inline isl::checked::union_pw_aff union_add(const isl::checked::union_pw_aff &upa2) const; + inline isl::checked::union_pw_multi_aff union_add(const isl::checked::union_pw_multi_aff &upma2) const; + inline isl::checked::pw_aff union_add(const isl::checked::aff &pwaff2) const; +}; + +// declarations for isl::pw_aff_list +inline pw_aff_list manage(__isl_take isl_pw_aff_list *ptr); +inline pw_aff_list manage_copy(__isl_keep isl_pw_aff_list *ptr); + +class pw_aff_list { + friend inline pw_aff_list manage(__isl_take isl_pw_aff_list *ptr); + friend inline pw_aff_list manage_copy(__isl_keep isl_pw_aff_list *ptr); + +protected: + isl_pw_aff_list *ptr = nullptr; + + inline explicit pw_aff_list(__isl_take isl_pw_aff_list *ptr); + +public: + inline /* implicit */ pw_aff_list(); + inline /* implicit */ pw_aff_list(const pw_aff_list &obj); + inline explicit pw_aff_list(isl::checked::ctx ctx, int n); + inline explicit pw_aff_list(isl::checked::pw_aff el); + inline explicit pw_aff_list(isl::checked::ctx ctx, const std::string &str); + inline pw_aff_list &operator=(pw_aff_list obj); + inline ~pw_aff_list(); + inline __isl_give isl_pw_aff_list *copy() const &; + inline __isl_give isl_pw_aff_list *copy() && = delete; + inline __isl_keep isl_pw_aff_list *get() const; + inline __isl_give isl_pw_aff_list *release(); + inline bool is_null() const; + inline isl::checked::ctx ctx() const; + + inline isl::checked::pw_aff_list add(isl::checked::pw_aff el) const; + inline isl::checked::pw_aff at(int index) const; + inline isl::checked::pw_aff get_at(int index) const; + inline isl::checked::pw_aff_list clear() const; + inline isl::checked::pw_aff_list concat(isl::checked::pw_aff_list list2) const; + inline isl::checked::pw_aff_list drop(unsigned int first, unsigned int n) const; + inline stat foreach(const std::function &fn) const; + inline stat foreach_scc(const std::function &follows, const std::function &fn) const; + inline isl::checked::pw_aff_list insert(unsigned int pos, isl::checked::pw_aff el) const; + inline isl::checked::pw_aff_list set_at(int index, isl::checked::pw_aff el) const; + inline class size size() const; +}; + +// declarations for isl::pw_multi_aff +inline pw_multi_aff manage(__isl_take isl_pw_multi_aff *ptr); +inline pw_multi_aff manage_copy(__isl_keep isl_pw_multi_aff *ptr); + +class pw_multi_aff { + friend inline pw_multi_aff manage(__isl_take isl_pw_multi_aff *ptr); + friend inline pw_multi_aff manage_copy(__isl_keep isl_pw_multi_aff *ptr); + +protected: + isl_pw_multi_aff *ptr = nullptr; + + inline explicit pw_multi_aff(__isl_take isl_pw_multi_aff *ptr); + +public: + inline /* implicit */ pw_multi_aff(); + inline /* implicit */ pw_multi_aff(const pw_multi_aff &obj); + inline /* implicit */ pw_multi_aff(isl::checked::multi_aff ma); + inline /* implicit */ pw_multi_aff(isl::checked::pw_aff pa); + inline explicit pw_multi_aff(isl::checked::ctx ctx, const std::string &str); + inline pw_multi_aff &operator=(pw_multi_aff obj); + inline ~pw_multi_aff(); + inline __isl_give isl_pw_multi_aff *copy() const &; + inline __isl_give isl_pw_multi_aff *copy() && = delete; + inline __isl_keep isl_pw_multi_aff *get() const; + inline __isl_give isl_pw_multi_aff *release(); + inline bool is_null() const; + inline isl::checked::ctx ctx() const; + + inline isl::checked::multi_pw_aff add(const isl::checked::multi_pw_aff &multi2) const; + inline isl::checked::multi_union_pw_aff add(const isl::checked::multi_union_pw_aff &multi2) const; + inline isl::checked::pw_multi_aff add(isl::checked::pw_multi_aff pma2) const; + inline isl::checked::union_pw_multi_aff add(const isl::checked::union_pw_multi_aff &upma2) const; + inline isl::checked::pw_multi_aff add(const isl::checked::multi_aff &pma2) const; + inline isl::checked::pw_multi_aff add(const isl::checked::pw_aff &pma2) const; + inline isl::checked::pw_multi_aff add_constant(isl::checked::multi_val mv) const; + inline isl::checked::pw_multi_aff add_constant(isl::checked::val v) const; + inline isl::checked::pw_multi_aff add_constant(long v) const; + inline isl::checked::union_pw_multi_aff apply(const isl::checked::union_pw_multi_aff &upma2) const; + inline isl::checked::map as_map() const; + inline isl::checked::multi_aff as_multi_aff() const; + inline isl::checked::multi_union_pw_aff as_multi_union_pw_aff() const; + inline isl::checked::pw_multi_aff as_pw_multi_aff() const; + inline isl::checked::set as_set() const; + inline isl::checked::union_map as_union_map() const; + inline isl::checked::pw_aff at(int pos) const; + inline isl::checked::pw_aff get_at(int pos) const; + inline isl::checked::set bind(const isl::checked::multi_id &tuple) const; + inline isl::checked::pw_multi_aff bind_domain(isl::checked::multi_id tuple) const; + inline isl::checked::pw_multi_aff bind_domain_wrapped_domain(isl::checked::multi_id tuple) const; + inline isl::checked::pw_multi_aff coalesce() const; + inline isl::checked::set domain() const; + static inline isl::checked::pw_multi_aff domain_map(isl::checked::space space); + inline isl::checked::pw_multi_aff domain_reverse() const; + inline isl::checked::pw_multi_aff drop_unused_params() const; + inline isl::checked::pw_multi_aff extract_pw_multi_aff(const isl::checked::space &space) const; + inline isl::checked::multi_pw_aff flat_range_product(const isl::checked::multi_pw_aff &multi2) const; + inline isl::checked::multi_union_pw_aff flat_range_product(const isl::checked::multi_union_pw_aff &multi2) const; + inline isl::checked::pw_multi_aff flat_range_product(isl::checked::pw_multi_aff pma2) const; + inline isl::checked::union_pw_multi_aff flat_range_product(const isl::checked::union_pw_multi_aff &upma2) const; + inline isl::checked::pw_multi_aff flat_range_product(const isl::checked::multi_aff &pma2) const; + inline isl::checked::pw_multi_aff flat_range_product(const isl::checked::pw_aff &pma2) const; + inline stat foreach_piece(const std::function &fn) const; + inline isl::checked::pw_multi_aff gist(isl::checked::set set) const; + inline isl::checked::union_pw_multi_aff gist(const isl::checked::union_set &context) const; + inline isl::checked::pw_multi_aff gist(const isl::checked::basic_set &set) const; + inline isl::checked::pw_multi_aff gist(const isl::checked::point &set) const; + inline isl::checked::pw_multi_aff gist_params(isl::checked::set set) const; + inline boolean has_range_tuple_id() const; + inline isl::checked::multi_pw_aff identity() const; + static inline isl::checked::pw_multi_aff identity_on_domain(isl::checked::space space); + inline isl::checked::pw_multi_aff insert_domain(isl::checked::space domain) const; + inline isl::checked::pw_multi_aff intersect_domain(isl::checked::set set) const; + inline isl::checked::union_pw_multi_aff intersect_domain(const isl::checked::space &space) const; + inline isl::checked::union_pw_multi_aff intersect_domain(const isl::checked::union_set &uset) const; + inline isl::checked::pw_multi_aff intersect_domain(const isl::checked::basic_set &set) const; + inline isl::checked::pw_multi_aff intersect_domain(const isl::checked::point &set) const; + inline isl::checked::union_pw_multi_aff intersect_domain_wrapped_domain(const isl::checked::union_set &uset) const; + inline isl::checked::union_pw_multi_aff intersect_domain_wrapped_range(const isl::checked::union_set &uset) const; + inline isl::checked::pw_multi_aff intersect_params(isl::checked::set set) const; + inline boolean involves_locals() const; + inline boolean involves_nan() const; + inline boolean involves_param(const isl::checked::id &id) const; + inline boolean involves_param(const std::string &id) const; + inline boolean involves_param(const isl::checked::id_list &list) const; + inline boolean isa_multi_aff() const; + inline boolean isa_pw_multi_aff() const; + inline isl::checked::pw_aff_list list() const; + inline isl::checked::multi_pw_aff max(const isl::checked::multi_pw_aff &multi2) const; + inline isl::checked::multi_val max_multi_val() const; + inline isl::checked::multi_pw_aff min(const isl::checked::multi_pw_aff &multi2) const; + inline isl::checked::multi_val min_multi_val() const; + static inline isl::checked::pw_multi_aff multi_val_on_domain(isl::checked::set domain, isl::checked::multi_val mv); + inline class size n_piece() const; + inline isl::checked::multi_pw_aff neg() const; + inline boolean plain_is_empty() const; + inline boolean plain_is_equal(const isl::checked::multi_pw_aff &multi2) const; + inline boolean plain_is_equal(const isl::checked::multi_union_pw_aff &multi2) const; + inline boolean plain_is_equal(const isl::checked::pw_multi_aff &pma2) const; + inline boolean plain_is_equal(const isl::checked::union_pw_multi_aff &upma2) const; + inline boolean plain_is_equal(const isl::checked::multi_aff &pma2) const; + inline boolean plain_is_equal(const isl::checked::pw_aff &pma2) const; + inline isl::checked::pw_multi_aff preimage_domain_wrapped_domain(isl::checked::pw_multi_aff pma2) const; + inline isl::checked::union_pw_multi_aff preimage_domain_wrapped_domain(const isl::checked::union_pw_multi_aff &upma2) const; + inline isl::checked::pw_multi_aff preimage_domain_wrapped_domain(const isl::checked::multi_aff &pma2) const; + inline isl::checked::pw_multi_aff preimage_domain_wrapped_domain(const isl::checked::pw_aff &pma2) const; + inline isl::checked::multi_pw_aff product(const isl::checked::multi_pw_aff &multi2) const; + inline isl::checked::pw_multi_aff product(isl::checked::pw_multi_aff pma2) const; + inline isl::checked::pw_multi_aff product(const isl::checked::multi_aff &pma2) const; + inline isl::checked::pw_multi_aff product(const isl::checked::pw_aff &pma2) const; + inline isl::checked::multi_pw_aff pullback(const isl::checked::multi_pw_aff &mpa2) const; + inline isl::checked::pw_multi_aff pullback(isl::checked::multi_aff ma) const; + inline isl::checked::pw_multi_aff pullback(isl::checked::pw_multi_aff pma2) const; + inline isl::checked::union_pw_multi_aff pullback(const isl::checked::union_pw_multi_aff &upma2) const; + inline isl::checked::pw_multi_aff_list pw_multi_aff_list() const; + inline isl::checked::pw_multi_aff range_factor_domain() const; + inline isl::checked::pw_multi_aff range_factor_range() const; + static inline isl::checked::pw_multi_aff range_map(isl::checked::space space); + inline isl::checked::multi_pw_aff range_product(const isl::checked::multi_pw_aff &multi2) const; + inline isl::checked::multi_union_pw_aff range_product(const isl::checked::multi_union_pw_aff &multi2) const; + inline isl::checked::pw_multi_aff range_product(isl::checked::pw_multi_aff pma2) const; + inline isl::checked::union_pw_multi_aff range_product(const isl::checked::union_pw_multi_aff &upma2) const; + inline isl::checked::pw_multi_aff range_product(const isl::checked::multi_aff &pma2) const; + inline isl::checked::pw_multi_aff range_product(const isl::checked::pw_aff &pma2) const; + inline isl::checked::id range_tuple_id() const; + inline isl::checked::id get_range_tuple_id() const; + inline isl::checked::multi_pw_aff reset_range_tuple_id() const; + inline isl::checked::pw_multi_aff scale(isl::checked::multi_val mv) const; + inline isl::checked::pw_multi_aff scale(isl::checked::val v) const; + inline isl::checked::pw_multi_aff scale(long v) const; + inline isl::checked::pw_multi_aff scale_down(isl::checked::multi_val mv) const; + inline isl::checked::pw_multi_aff scale_down(isl::checked::val v) const; + inline isl::checked::pw_multi_aff scale_down(long v) const; + inline isl::checked::multi_pw_aff set_at(int pos, const isl::checked::pw_aff &el) const; + inline isl::checked::multi_union_pw_aff set_at(int pos, const isl::checked::union_pw_aff &el) const; + inline isl::checked::pw_multi_aff set_range_tuple(isl::checked::id id) const; + inline isl::checked::pw_multi_aff set_range_tuple(const std::string &id) const; + inline class size size() const; + inline isl::checked::space space() const; + inline isl::checked::space get_space() const; + inline isl::checked::multi_pw_aff sub(const isl::checked::multi_pw_aff &multi2) const; + inline isl::checked::multi_union_pw_aff sub(const isl::checked::multi_union_pw_aff &multi2) const; + inline isl::checked::pw_multi_aff sub(isl::checked::pw_multi_aff pma2) const; + inline isl::checked::union_pw_multi_aff sub(const isl::checked::union_pw_multi_aff &upma2) const; + inline isl::checked::pw_multi_aff sub(const isl::checked::multi_aff &pma2) const; + inline isl::checked::pw_multi_aff sub(const isl::checked::pw_aff &pma2) const; + inline isl::checked::pw_multi_aff subtract_domain(isl::checked::set set) const; + inline isl::checked::union_pw_multi_aff subtract_domain(const isl::checked::space &space) const; + inline isl::checked::union_pw_multi_aff subtract_domain(const isl::checked::union_set &uset) const; + inline isl::checked::pw_multi_aff subtract_domain(const isl::checked::basic_set &set) const; + inline isl::checked::pw_multi_aff subtract_domain(const isl::checked::point &set) const; + inline isl::checked::pw_multi_aff_list to_list() const; + inline isl::checked::multi_pw_aff to_multi_pw_aff() const; + inline isl::checked::union_pw_multi_aff to_union_pw_multi_aff() const; + inline isl::checked::multi_pw_aff unbind_params_insert_domain(const isl::checked::multi_id &domain) const; + inline isl::checked::multi_pw_aff union_add(const isl::checked::multi_pw_aff &mpa2) const; + inline isl::checked::multi_union_pw_aff union_add(const isl::checked::multi_union_pw_aff &mupa2) const; + inline isl::checked::pw_multi_aff union_add(isl::checked::pw_multi_aff pma2) const; + inline isl::checked::union_pw_multi_aff union_add(const isl::checked::union_pw_multi_aff &upma2) const; + inline isl::checked::pw_multi_aff union_add(const isl::checked::multi_aff &pma2) const; + inline isl::checked::pw_multi_aff union_add(const isl::checked::pw_aff &pma2) const; + static inline isl::checked::pw_multi_aff zero(isl::checked::space space); +}; + +// declarations for isl::pw_multi_aff_list +inline pw_multi_aff_list manage(__isl_take isl_pw_multi_aff_list *ptr); +inline pw_multi_aff_list manage_copy(__isl_keep isl_pw_multi_aff_list *ptr); + +class pw_multi_aff_list { + friend inline pw_multi_aff_list manage(__isl_take isl_pw_multi_aff_list *ptr); + friend inline pw_multi_aff_list manage_copy(__isl_keep isl_pw_multi_aff_list *ptr); + +protected: + isl_pw_multi_aff_list *ptr = nullptr; + + inline explicit pw_multi_aff_list(__isl_take isl_pw_multi_aff_list *ptr); + +public: + inline /* implicit */ pw_multi_aff_list(); + inline /* implicit */ pw_multi_aff_list(const pw_multi_aff_list &obj); + inline explicit pw_multi_aff_list(isl::checked::ctx ctx, int n); + inline explicit pw_multi_aff_list(isl::checked::pw_multi_aff el); + inline explicit pw_multi_aff_list(isl::checked::ctx ctx, const std::string &str); + inline pw_multi_aff_list &operator=(pw_multi_aff_list obj); + inline ~pw_multi_aff_list(); + inline __isl_give isl_pw_multi_aff_list *copy() const &; + inline __isl_give isl_pw_multi_aff_list *copy() && = delete; + inline __isl_keep isl_pw_multi_aff_list *get() const; + inline __isl_give isl_pw_multi_aff_list *release(); + inline bool is_null() const; + inline isl::checked::ctx ctx() const; + + inline isl::checked::pw_multi_aff_list add(isl::checked::pw_multi_aff el) const; + inline isl::checked::pw_multi_aff at(int index) const; + inline isl::checked::pw_multi_aff get_at(int index) const; + inline isl::checked::pw_multi_aff_list clear() const; + inline isl::checked::pw_multi_aff_list concat(isl::checked::pw_multi_aff_list list2) const; + inline isl::checked::pw_multi_aff_list drop(unsigned int first, unsigned int n) const; + inline stat foreach(const std::function &fn) const; + inline stat foreach_scc(const std::function &follows, const std::function &fn) const; + inline isl::checked::pw_multi_aff_list insert(unsigned int pos, isl::checked::pw_multi_aff el) const; + inline isl::checked::pw_multi_aff_list set_at(int index, isl::checked::pw_multi_aff el) const; + inline class size size() const; +}; + +// declarations for isl::schedule +inline schedule manage(__isl_take isl_schedule *ptr); +inline schedule manage_copy(__isl_keep isl_schedule *ptr); + +class schedule { + friend inline schedule manage(__isl_take isl_schedule *ptr); + friend inline schedule manage_copy(__isl_keep isl_schedule *ptr); + +protected: + isl_schedule *ptr = nullptr; + + inline explicit schedule(__isl_take isl_schedule *ptr); + +public: + inline /* implicit */ schedule(); + inline /* implicit */ schedule(const schedule &obj); + inline explicit schedule(isl::checked::ctx ctx, const std::string &str); + inline schedule &operator=(schedule obj); + inline ~schedule(); + inline __isl_give isl_schedule *copy() const &; + inline __isl_give isl_schedule *copy() && = delete; + inline __isl_keep isl_schedule *get() const; + inline __isl_give isl_schedule *release(); + inline bool is_null() const; + inline isl::checked::ctx ctx() const; + + inline isl::checked::union_set domain() const; + inline isl::checked::union_set get_domain() const; + static inline isl::checked::schedule from_domain(isl::checked::union_set domain); + inline isl::checked::union_map map() const; + inline isl::checked::union_map get_map() const; + inline isl::checked::schedule pullback(isl::checked::union_pw_multi_aff upma) const; + inline isl::checked::schedule_node root() const; + inline isl::checked::schedule_node get_root() const; +}; + +// declarations for isl::schedule_constraints +inline schedule_constraints manage(__isl_take isl_schedule_constraints *ptr); +inline schedule_constraints manage_copy(__isl_keep isl_schedule_constraints *ptr); + +class schedule_constraints { + friend inline schedule_constraints manage(__isl_take isl_schedule_constraints *ptr); + friend inline schedule_constraints manage_copy(__isl_keep isl_schedule_constraints *ptr); + +protected: + isl_schedule_constraints *ptr = nullptr; + + inline explicit schedule_constraints(__isl_take isl_schedule_constraints *ptr); + +public: + inline /* implicit */ schedule_constraints(); + inline /* implicit */ schedule_constraints(const schedule_constraints &obj); + inline explicit schedule_constraints(isl::checked::ctx ctx, const std::string &str); + inline schedule_constraints &operator=(schedule_constraints obj); + inline ~schedule_constraints(); + inline __isl_give isl_schedule_constraints *copy() const &; + inline __isl_give isl_schedule_constraints *copy() && = delete; + inline __isl_keep isl_schedule_constraints *get() const; + inline __isl_give isl_schedule_constraints *release(); + inline bool is_null() const; + inline isl::checked::ctx ctx() const; + + inline isl::checked::union_map coincidence() const; + inline isl::checked::union_map get_coincidence() const; + inline isl::checked::schedule compute_schedule() const; + inline isl::checked::union_map conditional_validity() const; + inline isl::checked::union_map get_conditional_validity() const; + inline isl::checked::union_map conditional_validity_condition() const; + inline isl::checked::union_map get_conditional_validity_condition() const; + inline isl::checked::set context() const; + inline isl::checked::set get_context() const; + inline isl::checked::union_set domain() const; + inline isl::checked::union_set get_domain() const; + static inline isl::checked::schedule_constraints on_domain(isl::checked::union_set domain); + inline isl::checked::union_map proximity() const; + inline isl::checked::union_map get_proximity() const; + inline isl::checked::schedule_constraints set_coincidence(isl::checked::union_map coincidence) const; + inline isl::checked::schedule_constraints set_conditional_validity(isl::checked::union_map condition, isl::checked::union_map validity) const; + inline isl::checked::schedule_constraints set_context(isl::checked::set context) const; + inline isl::checked::schedule_constraints set_proximity(isl::checked::union_map proximity) const; + inline isl::checked::schedule_constraints set_validity(isl::checked::union_map validity) const; + inline isl::checked::union_map validity() const; + inline isl::checked::union_map get_validity() const; +}; + +// declarations for isl::schedule_node +inline schedule_node manage(__isl_take isl_schedule_node *ptr); +inline schedule_node manage_copy(__isl_keep isl_schedule_node *ptr); + +class schedule_node { + friend inline schedule_node manage(__isl_take isl_schedule_node *ptr); + friend inline schedule_node manage_copy(__isl_keep isl_schedule_node *ptr); + +protected: + isl_schedule_node *ptr = nullptr; + + inline explicit schedule_node(__isl_take isl_schedule_node *ptr); + +public: + inline /* implicit */ schedule_node(); + inline /* implicit */ schedule_node(const schedule_node &obj); + inline schedule_node &operator=(schedule_node obj); + inline ~schedule_node(); + inline __isl_give isl_schedule_node *copy() const &; + inline __isl_give isl_schedule_node *copy() && = delete; + inline __isl_keep isl_schedule_node *get() const; + inline __isl_give isl_schedule_node *release(); + inline bool is_null() const; +private: + template ::value>::type> + inline boolean isa_type(T subtype) const; +public: + template inline boolean isa() const; + template inline T as() const; + inline isl::checked::ctx ctx() const; + + inline isl::checked::schedule_node ancestor(int generation) const; + inline class size ancestor_child_position(const isl::checked::schedule_node &ancestor) const; + inline class size get_ancestor_child_position(const isl::checked::schedule_node &ancestor) const; + inline isl::checked::schedule_node child(int pos) const; + inline class size child_position() const; + inline class size get_child_position() const; + inline boolean every_descendant(const std::function &test) const; + inline isl::checked::schedule_node first_child() const; + inline stat foreach_ancestor_top_down(const std::function &fn) const; + inline stat foreach_descendant_top_down(const std::function &fn) const; + static inline isl::checked::schedule_node from_domain(isl::checked::union_set domain); + static inline isl::checked::schedule_node from_extension(isl::checked::union_map extension); + inline isl::checked::schedule_node graft_after(isl::checked::schedule_node graft) const; + inline isl::checked::schedule_node graft_before(isl::checked::schedule_node graft) const; + inline boolean has_children() const; + inline boolean has_next_sibling() const; + inline boolean has_parent() const; + inline boolean has_previous_sibling() const; + inline isl::checked::schedule_node insert_context(isl::checked::set context) const; + inline isl::checked::schedule_node insert_filter(isl::checked::union_set filter) const; + inline isl::checked::schedule_node insert_guard(isl::checked::set context) const; + inline isl::checked::schedule_node insert_mark(isl::checked::id mark) const; + inline isl::checked::schedule_node insert_mark(const std::string &mark) const; + inline isl::checked::schedule_node insert_partial_schedule(isl::checked::multi_union_pw_aff schedule) const; + inline isl::checked::schedule_node insert_sequence(isl::checked::union_set_list filters) const; + inline isl::checked::schedule_node insert_set(isl::checked::union_set_list filters) const; + inline boolean is_equal(const isl::checked::schedule_node &node2) const; + inline boolean is_subtree_anchored() const; + inline isl::checked::schedule_node map_descendant_bottom_up(const std::function &fn) const; + inline class size n_children() const; + inline isl::checked::schedule_node next_sibling() const; + inline isl::checked::schedule_node order_after(isl::checked::union_set filter) const; + inline isl::checked::schedule_node order_before(isl::checked::union_set filter) const; + inline isl::checked::schedule_node parent() const; + inline isl::checked::multi_union_pw_aff prefix_schedule_multi_union_pw_aff() const; + inline isl::checked::multi_union_pw_aff get_prefix_schedule_multi_union_pw_aff() const; + inline isl::checked::union_map prefix_schedule_union_map() const; + inline isl::checked::union_map get_prefix_schedule_union_map() const; + inline isl::checked::union_pw_multi_aff prefix_schedule_union_pw_multi_aff() const; + inline isl::checked::union_pw_multi_aff get_prefix_schedule_union_pw_multi_aff() const; + inline isl::checked::schedule_node previous_sibling() const; + inline isl::checked::schedule_node root() const; + inline isl::checked::schedule schedule() const; + inline isl::checked::schedule get_schedule() const; + inline isl::checked::schedule_node shared_ancestor(const isl::checked::schedule_node &node2) const; + inline isl::checked::schedule_node get_shared_ancestor(const isl::checked::schedule_node &node2) const; + inline class size tree_depth() const; + inline class size get_tree_depth() const; +}; + +// declarations for isl::schedule_node_band + +class schedule_node_band : public schedule_node { + template + friend boolean schedule_node::isa() const; + friend schedule_node_band schedule_node::as() const; + static const auto type = isl_schedule_node_band; + +protected: + inline explicit schedule_node_band(__isl_take isl_schedule_node *ptr); + +public: + inline /* implicit */ schedule_node_band(); + inline /* implicit */ schedule_node_band(const schedule_node_band &obj); + inline schedule_node_band &operator=(schedule_node_band obj); + inline isl::checked::ctx ctx() const; + + inline isl::checked::union_set ast_build_options() const; + inline isl::checked::union_set get_ast_build_options() const; + inline isl::checked::set ast_isolate_option() const; + inline isl::checked::set get_ast_isolate_option() const; + inline boolean member_get_coincident(int pos) const; + inline schedule_node_band member_set_coincident(int pos, int coincident) const; + inline schedule_node_band mod(isl::checked::multi_val mv) const; + inline class size n_member() const; + inline isl::checked::multi_union_pw_aff partial_schedule() const; + inline isl::checked::multi_union_pw_aff get_partial_schedule() const; + inline boolean permutable() const; + inline boolean get_permutable() const; + inline schedule_node_band scale(isl::checked::multi_val mv) const; + inline schedule_node_band scale_down(isl::checked::multi_val mv) const; + inline schedule_node_band set_ast_build_options(isl::checked::union_set options) const; + inline schedule_node_band set_permutable(int permutable) const; + inline schedule_node_band shift(isl::checked::multi_union_pw_aff shift) const; + inline schedule_node_band split(int pos) const; + inline schedule_node_band tile(isl::checked::multi_val sizes) const; + inline schedule_node_band member_set_ast_loop_default(int pos) const; + inline schedule_node_band member_set_ast_loop_atomic(int pos) const; + inline schedule_node_band member_set_ast_loop_unroll(int pos) const; + inline schedule_node_band member_set_ast_loop_separate(int pos) const; +}; + +// declarations for isl::schedule_node_context + +class schedule_node_context : public schedule_node { + template + friend boolean schedule_node::isa() const; + friend schedule_node_context schedule_node::as() const; + static const auto type = isl_schedule_node_context; + +protected: + inline explicit schedule_node_context(__isl_take isl_schedule_node *ptr); + +public: + inline /* implicit */ schedule_node_context(); + inline /* implicit */ schedule_node_context(const schedule_node_context &obj); + inline schedule_node_context &operator=(schedule_node_context obj); + inline isl::checked::ctx ctx() const; + + inline isl::checked::set context() const; + inline isl::checked::set get_context() const; +}; + +// declarations for isl::schedule_node_domain + +class schedule_node_domain : public schedule_node { + template + friend boolean schedule_node::isa() const; + friend schedule_node_domain schedule_node::as() const; + static const auto type = isl_schedule_node_domain; + +protected: + inline explicit schedule_node_domain(__isl_take isl_schedule_node *ptr); + +public: + inline /* implicit */ schedule_node_domain(); + inline /* implicit */ schedule_node_domain(const schedule_node_domain &obj); + inline schedule_node_domain &operator=(schedule_node_domain obj); + inline isl::checked::ctx ctx() const; + + inline isl::checked::union_set domain() const; + inline isl::checked::union_set get_domain() const; +}; + +// declarations for isl::schedule_node_expansion + +class schedule_node_expansion : public schedule_node { + template + friend boolean schedule_node::isa() const; + friend schedule_node_expansion schedule_node::as() const; + static const auto type = isl_schedule_node_expansion; + +protected: + inline explicit schedule_node_expansion(__isl_take isl_schedule_node *ptr); + +public: + inline /* implicit */ schedule_node_expansion(); + inline /* implicit */ schedule_node_expansion(const schedule_node_expansion &obj); + inline schedule_node_expansion &operator=(schedule_node_expansion obj); + inline isl::checked::ctx ctx() const; + + inline isl::checked::union_pw_multi_aff contraction() const; + inline isl::checked::union_pw_multi_aff get_contraction() const; + inline isl::checked::union_map expansion() const; + inline isl::checked::union_map get_expansion() const; +}; + +// declarations for isl::schedule_node_extension + +class schedule_node_extension : public schedule_node { + template + friend boolean schedule_node::isa() const; + friend schedule_node_extension schedule_node::as() const; + static const auto type = isl_schedule_node_extension; + +protected: + inline explicit schedule_node_extension(__isl_take isl_schedule_node *ptr); + +public: + inline /* implicit */ schedule_node_extension(); + inline /* implicit */ schedule_node_extension(const schedule_node_extension &obj); + inline schedule_node_extension &operator=(schedule_node_extension obj); + inline isl::checked::ctx ctx() const; + + inline isl::checked::union_map extension() const; + inline isl::checked::union_map get_extension() const; +}; + +// declarations for isl::schedule_node_filter + +class schedule_node_filter : public schedule_node { + template + friend boolean schedule_node::isa() const; + friend schedule_node_filter schedule_node::as() const; + static const auto type = isl_schedule_node_filter; + +protected: + inline explicit schedule_node_filter(__isl_take isl_schedule_node *ptr); + +public: + inline /* implicit */ schedule_node_filter(); + inline /* implicit */ schedule_node_filter(const schedule_node_filter &obj); + inline schedule_node_filter &operator=(schedule_node_filter obj); + inline isl::checked::ctx ctx() const; + + inline isl::checked::union_set filter() const; + inline isl::checked::union_set get_filter() const; +}; + +// declarations for isl::schedule_node_guard + +class schedule_node_guard : public schedule_node { + template + friend boolean schedule_node::isa() const; + friend schedule_node_guard schedule_node::as() const; + static const auto type = isl_schedule_node_guard; + +protected: + inline explicit schedule_node_guard(__isl_take isl_schedule_node *ptr); + +public: + inline /* implicit */ schedule_node_guard(); + inline /* implicit */ schedule_node_guard(const schedule_node_guard &obj); + inline schedule_node_guard &operator=(schedule_node_guard obj); + inline isl::checked::ctx ctx() const; + + inline isl::checked::set guard() const; + inline isl::checked::set get_guard() const; +}; + +// declarations for isl::schedule_node_leaf + +class schedule_node_leaf : public schedule_node { + template + friend boolean schedule_node::isa() const; + friend schedule_node_leaf schedule_node::as() const; + static const auto type = isl_schedule_node_leaf; + +protected: + inline explicit schedule_node_leaf(__isl_take isl_schedule_node *ptr); + +public: + inline /* implicit */ schedule_node_leaf(); + inline /* implicit */ schedule_node_leaf(const schedule_node_leaf &obj); + inline schedule_node_leaf &operator=(schedule_node_leaf obj); + inline isl::checked::ctx ctx() const; + +}; + +// declarations for isl::schedule_node_mark + +class schedule_node_mark : public schedule_node { + template + friend boolean schedule_node::isa() const; + friend schedule_node_mark schedule_node::as() const; + static const auto type = isl_schedule_node_mark; + +protected: + inline explicit schedule_node_mark(__isl_take isl_schedule_node *ptr); + +public: + inline /* implicit */ schedule_node_mark(); + inline /* implicit */ schedule_node_mark(const schedule_node_mark &obj); + inline schedule_node_mark &operator=(schedule_node_mark obj); + inline isl::checked::ctx ctx() const; + +}; + +// declarations for isl::schedule_node_sequence + +class schedule_node_sequence : public schedule_node { + template + friend boolean schedule_node::isa() const; + friend schedule_node_sequence schedule_node::as() const; + static const auto type = isl_schedule_node_sequence; + +protected: + inline explicit schedule_node_sequence(__isl_take isl_schedule_node *ptr); + +public: + inline /* implicit */ schedule_node_sequence(); + inline /* implicit */ schedule_node_sequence(const schedule_node_sequence &obj); + inline schedule_node_sequence &operator=(schedule_node_sequence obj); + inline isl::checked::ctx ctx() const; + +}; + +// declarations for isl::schedule_node_set + +class schedule_node_set : public schedule_node { + template + friend boolean schedule_node::isa() const; + friend schedule_node_set schedule_node::as() const; + static const auto type = isl_schedule_node_set; + +protected: + inline explicit schedule_node_set(__isl_take isl_schedule_node *ptr); + +public: + inline /* implicit */ schedule_node_set(); + inline /* implicit */ schedule_node_set(const schedule_node_set &obj); + inline schedule_node_set &operator=(schedule_node_set obj); + inline isl::checked::ctx ctx() const; + +}; + +// declarations for isl::set +inline set manage(__isl_take isl_set *ptr); +inline set manage_copy(__isl_keep isl_set *ptr); + +class set { + friend inline set manage(__isl_take isl_set *ptr); + friend inline set manage_copy(__isl_keep isl_set *ptr); + +protected: + isl_set *ptr = nullptr; + + inline explicit set(__isl_take isl_set *ptr); + +public: + inline /* implicit */ set(); + inline /* implicit */ set(const set &obj); + inline /* implicit */ set(isl::checked::basic_set bset); + inline /* implicit */ set(isl::checked::point pnt); + inline explicit set(isl::checked::ctx ctx, const std::string &str); + inline set &operator=(set obj); + inline ~set(); + inline __isl_give isl_set *copy() const &; + inline __isl_give isl_set *copy() && = delete; + inline __isl_keep isl_set *get() const; + inline __isl_give isl_set *release(); + inline bool is_null() const; + inline isl::checked::ctx ctx() const; + + inline isl::checked::basic_set affine_hull() const; + inline isl::checked::set apply(isl::checked::map map) const; + inline isl::checked::union_set apply(const isl::checked::union_map &umap) const; + inline isl::checked::set apply(const isl::checked::basic_map &map) const; + inline isl::checked::pw_multi_aff as_pw_multi_aff() const; + inline isl::checked::set as_set() const; + inline isl::checked::set bind(isl::checked::multi_id tuple) const; + inline isl::checked::set coalesce() const; + inline isl::checked::set complement() const; + inline isl::checked::union_set compute_divs() const; + inline isl::checked::set detect_equalities() const; + inline isl::checked::val dim_max_val(int pos) const; + inline isl::checked::val dim_min_val(int pos) const; + inline isl::checked::set drop_unused_params() const; + static inline isl::checked::set empty(isl::checked::space space); + inline boolean every_set(const std::function &test) const; + inline isl::checked::set extract_set(const isl::checked::space &space) const; + inline isl::checked::set flatten() const; + inline stat foreach_basic_set(const std::function &fn) const; + inline stat foreach_point(const std::function &fn) const; + inline stat foreach_set(const std::function &fn) const; + inline isl::checked::set gist(isl::checked::set context) const; + inline isl::checked::union_set gist(const isl::checked::union_set &context) const; + inline isl::checked::set gist(const isl::checked::basic_set &context) const; + inline isl::checked::set gist(const isl::checked::point &context) const; + inline isl::checked::set gist_params(isl::checked::set context) const; + inline isl::checked::map identity() const; + inline isl::checked::pw_aff indicator_function() const; + inline isl::checked::map insert_domain(isl::checked::space domain) const; + inline isl::checked::set intersect(isl::checked::set set2) const; + inline isl::checked::union_set intersect(const isl::checked::union_set &uset2) const; + inline isl::checked::set intersect(const isl::checked::basic_set &set2) const; + inline isl::checked::set intersect(const isl::checked::point &set2) const; + inline isl::checked::set intersect_params(isl::checked::set params) const; + inline boolean involves_locals() const; + inline boolean is_disjoint(const isl::checked::set &set2) const; + inline boolean is_disjoint(const isl::checked::union_set &uset2) const; + inline boolean is_disjoint(const isl::checked::basic_set &set2) const; + inline boolean is_disjoint(const isl::checked::point &set2) const; + inline boolean is_empty() const; + inline boolean is_equal(const isl::checked::set &set2) const; + inline boolean is_equal(const isl::checked::union_set &uset2) const; + inline boolean is_equal(const isl::checked::basic_set &set2) const; + inline boolean is_equal(const isl::checked::point &set2) const; + inline boolean is_singleton() const; + inline boolean is_strict_subset(const isl::checked::set &set2) const; + inline boolean is_strict_subset(const isl::checked::union_set &uset2) const; + inline boolean is_strict_subset(const isl::checked::basic_set &set2) const; + inline boolean is_strict_subset(const isl::checked::point &set2) const; + inline boolean is_subset(const isl::checked::set &set2) const; + inline boolean is_subset(const isl::checked::union_set &uset2) const; + inline boolean is_subset(const isl::checked::basic_set &set2) const; + inline boolean is_subset(const isl::checked::point &set2) const; + inline boolean is_wrapping() const; + inline boolean isa_set() const; + inline isl::checked::fixed_box lattice_tile() const; + inline isl::checked::fixed_box get_lattice_tile() const; + inline isl::checked::set lexmax() const; + inline isl::checked::pw_multi_aff lexmax_pw_multi_aff() const; + inline isl::checked::set lexmin() const; + inline isl::checked::pw_multi_aff lexmin_pw_multi_aff() const; + inline isl::checked::set lower_bound(isl::checked::multi_pw_aff lower) const; + inline isl::checked::set lower_bound(isl::checked::multi_val lower) const; + inline isl::checked::multi_pw_aff max_multi_pw_aff() const; + inline isl::checked::val max_val(const isl::checked::aff &obj) const; + inline isl::checked::multi_pw_aff min_multi_pw_aff() const; + inline isl::checked::val min_val(const isl::checked::aff &obj) const; + inline class size n_basic_set() const; + inline isl::checked::pw_aff param_pw_aff_on_domain(isl::checked::id id) const; + inline isl::checked::pw_aff param_pw_aff_on_domain(const std::string &id) const; + inline isl::checked::set params() const; + inline isl::checked::multi_val plain_multi_val_if_fixed() const; + inline isl::checked::multi_val get_plain_multi_val_if_fixed() const; + inline isl::checked::basic_set polyhedral_hull() const; + inline isl::checked::set preimage(isl::checked::multi_aff ma) const; + inline isl::checked::set preimage(isl::checked::multi_pw_aff mpa) const; + inline isl::checked::set preimage(isl::checked::pw_multi_aff pma) const; + inline isl::checked::union_set preimage(const isl::checked::union_pw_multi_aff &upma) const; + inline isl::checked::set product(isl::checked::set set2) const; + inline isl::checked::set project_out_all_params() const; + inline isl::checked::set project_out_param(isl::checked::id id) const; + inline isl::checked::set project_out_param(const std::string &id) const; + inline isl::checked::set project_out_param(isl::checked::id_list list) const; + inline isl::checked::pw_aff pw_aff_on_domain(isl::checked::val v) const; + inline isl::checked::pw_aff pw_aff_on_domain(long v) const; + inline isl::checked::pw_multi_aff pw_multi_aff_on_domain(isl::checked::multi_val mv) const; + inline isl::checked::basic_set sample() const; + inline isl::checked::point sample_point() const; + inline isl::checked::set_list set_list() const; + inline isl::checked::fixed_box simple_fixed_box_hull() const; + inline isl::checked::fixed_box get_simple_fixed_box_hull() const; + inline isl::checked::space space() const; + inline isl::checked::space get_space() const; + inline isl::checked::val stride(int pos) const; + inline isl::checked::val get_stride(int pos) const; + inline isl::checked::set subtract(isl::checked::set set2) const; + inline isl::checked::union_set subtract(const isl::checked::union_set &uset2) const; + inline isl::checked::set subtract(const isl::checked::basic_set &set2) const; + inline isl::checked::set subtract(const isl::checked::point &set2) const; + inline isl::checked::set_list to_list() const; + inline isl::checked::union_set to_union_set() const; + inline isl::checked::map translation() const; + inline class size tuple_dim() const; + inline isl::checked::set unbind_params(isl::checked::multi_id tuple) const; + inline isl::checked::map unbind_params_insert_domain(isl::checked::multi_id domain) const; + inline isl::checked::set unite(isl::checked::set set2) const; + inline isl::checked::union_set unite(const isl::checked::union_set &uset2) const; + inline isl::checked::set unite(const isl::checked::basic_set &set2) const; + inline isl::checked::set unite(const isl::checked::point &set2) const; + static inline isl::checked::set universe(isl::checked::space space); + inline isl::checked::basic_set unshifted_simple_hull() const; + inline isl::checked::map unwrap() const; + inline isl::checked::set upper_bound(isl::checked::multi_pw_aff upper) const; + inline isl::checked::set upper_bound(isl::checked::multi_val upper) const; + inline isl::checked::set wrapped_reverse() const; +}; + +// declarations for isl::set_list +inline set_list manage(__isl_take isl_set_list *ptr); +inline set_list manage_copy(__isl_keep isl_set_list *ptr); + +class set_list { + friend inline set_list manage(__isl_take isl_set_list *ptr); + friend inline set_list manage_copy(__isl_keep isl_set_list *ptr); + +protected: + isl_set_list *ptr = nullptr; + + inline explicit set_list(__isl_take isl_set_list *ptr); + +public: + inline /* implicit */ set_list(); + inline /* implicit */ set_list(const set_list &obj); + inline explicit set_list(isl::checked::ctx ctx, int n); + inline explicit set_list(isl::checked::set el); + inline explicit set_list(isl::checked::ctx ctx, const std::string &str); + inline set_list &operator=(set_list obj); + inline ~set_list(); + inline __isl_give isl_set_list *copy() const &; + inline __isl_give isl_set_list *copy() && = delete; + inline __isl_keep isl_set_list *get() const; + inline __isl_give isl_set_list *release(); + inline bool is_null() const; + inline isl::checked::ctx ctx() const; + + inline isl::checked::set_list add(isl::checked::set el) const; + inline isl::checked::set at(int index) const; + inline isl::checked::set get_at(int index) const; + inline isl::checked::set_list clear() const; + inline isl::checked::set_list concat(isl::checked::set_list list2) const; + inline isl::checked::set_list drop(unsigned int first, unsigned int n) const; + inline stat foreach(const std::function &fn) const; + inline stat foreach_scc(const std::function &follows, const std::function &fn) const; + inline isl::checked::set_list insert(unsigned int pos, isl::checked::set el) const; + inline isl::checked::set_list set_at(int index, isl::checked::set el) const; + inline class size size() const; +}; + +// declarations for isl::space +inline space manage(__isl_take isl_space *ptr); +inline space manage_copy(__isl_keep isl_space *ptr); + +class space { + friend inline space manage(__isl_take isl_space *ptr); + friend inline space manage_copy(__isl_keep isl_space *ptr); + +protected: + isl_space *ptr = nullptr; + + inline explicit space(__isl_take isl_space *ptr); + +public: + inline /* implicit */ space(); + inline /* implicit */ space(const space &obj); + inline explicit space(isl::checked::ctx ctx, const std::string &str); + inline space &operator=(space obj); + inline ~space(); + inline __isl_give isl_space *copy() const &; + inline __isl_give isl_space *copy() && = delete; + inline __isl_keep isl_space *get() const; + inline __isl_give isl_space *release(); + inline bool is_null() const; + inline isl::checked::ctx ctx() const; + + inline isl::checked::space add_named_tuple(isl::checked::id tuple_id, unsigned int dim) const; + inline isl::checked::space add_named_tuple(const std::string &tuple_id, unsigned int dim) const; + inline isl::checked::space add_param(isl::checked::id id) const; + inline isl::checked::space add_param(const std::string &id) const; + inline isl::checked::space add_unnamed_tuple(unsigned int dim) const; + inline isl::checked::space curry() const; + inline isl::checked::space domain() const; + inline isl::checked::multi_aff domain_map_multi_aff() const; + inline isl::checked::pw_multi_aff domain_map_pw_multi_aff() const; + inline isl::checked::space domain_reverse() const; + inline isl::checked::id domain_tuple_id() const; + inline isl::checked::id get_domain_tuple_id() const; + inline isl::checked::space drop_all_params() const; + inline isl::checked::space flatten_domain() const; + inline isl::checked::space flatten_range() const; + inline boolean has_domain_tuple_id() const; + inline boolean has_range_tuple_id() const; + inline isl::checked::multi_aff identity_multi_aff_on_domain() const; + inline isl::checked::multi_pw_aff identity_multi_pw_aff_on_domain() const; + inline isl::checked::pw_multi_aff identity_pw_multi_aff_on_domain() const; + inline boolean is_equal(const isl::checked::space &space2) const; + inline boolean is_wrapping() const; + inline isl::checked::space map_from_set() const; + inline isl::checked::multi_aff multi_aff(isl::checked::aff_list list) const; + inline isl::checked::multi_aff multi_aff_on_domain(isl::checked::multi_val mv) const; + inline isl::checked::multi_id multi_id(isl::checked::id_list list) const; + inline isl::checked::multi_pw_aff multi_pw_aff(isl::checked::pw_aff_list list) const; + inline isl::checked::multi_union_pw_aff multi_union_pw_aff(isl::checked::union_pw_aff_list list) const; + inline isl::checked::multi_val multi_val(isl::checked::val_list list) const; + inline isl::checked::aff param_aff_on_domain(isl::checked::id id) const; + inline isl::checked::aff param_aff_on_domain(const std::string &id) const; + inline isl::checked::space params() const; + inline isl::checked::space product(isl::checked::space right) const; + inline isl::checked::space range() const; + inline isl::checked::multi_aff range_map_multi_aff() const; + inline isl::checked::pw_multi_aff range_map_pw_multi_aff() const; + inline isl::checked::space range_reverse() const; + inline isl::checked::id range_tuple_id() const; + inline isl::checked::id get_range_tuple_id() const; + inline isl::checked::space reverse() const; + inline isl::checked::space set_domain_tuple(isl::checked::id id) const; + inline isl::checked::space set_domain_tuple(const std::string &id) const; + inline isl::checked::space set_range_tuple(isl::checked::id id) const; + inline isl::checked::space set_range_tuple(const std::string &id) const; + inline isl::checked::space uncurry() const; + static inline isl::checked::space unit(isl::checked::ctx ctx); + inline isl::checked::map universe_map() const; + inline isl::checked::set universe_set() const; + inline isl::checked::space unwrap() const; + inline isl::checked::space wrap() const; + inline isl::checked::space wrapped_reverse() const; + inline isl::checked::aff zero_aff_on_domain() const; + inline isl::checked::multi_aff zero_multi_aff() const; + inline isl::checked::multi_pw_aff zero_multi_pw_aff() const; + inline isl::checked::multi_union_pw_aff zero_multi_union_pw_aff() const; + inline isl::checked::multi_val zero_multi_val() const; +}; + +// declarations for isl::union_access_info +inline union_access_info manage(__isl_take isl_union_access_info *ptr); +inline union_access_info manage_copy(__isl_keep isl_union_access_info *ptr); + +class union_access_info { + friend inline union_access_info manage(__isl_take isl_union_access_info *ptr); + friend inline union_access_info manage_copy(__isl_keep isl_union_access_info *ptr); + +protected: + isl_union_access_info *ptr = nullptr; + + inline explicit union_access_info(__isl_take isl_union_access_info *ptr); + +public: + inline /* implicit */ union_access_info(); + inline /* implicit */ union_access_info(const union_access_info &obj); + inline explicit union_access_info(isl::checked::union_map sink); + inline union_access_info &operator=(union_access_info obj); + inline ~union_access_info(); + inline __isl_give isl_union_access_info *copy() const &; + inline __isl_give isl_union_access_info *copy() && = delete; + inline __isl_keep isl_union_access_info *get() const; + inline __isl_give isl_union_access_info *release(); + inline bool is_null() const; + inline isl::checked::ctx ctx() const; + + inline isl::checked::union_flow compute_flow() const; + inline isl::checked::union_access_info set_kill(isl::checked::union_map kill) const; + inline isl::checked::union_access_info set_may_source(isl::checked::union_map may_source) const; + inline isl::checked::union_access_info set_must_source(isl::checked::union_map must_source) const; + inline isl::checked::union_access_info set_schedule(isl::checked::schedule schedule) const; + inline isl::checked::union_access_info set_schedule_map(isl::checked::union_map schedule_map) const; +}; + +// declarations for isl::union_flow +inline union_flow manage(__isl_take isl_union_flow *ptr); +inline union_flow manage_copy(__isl_keep isl_union_flow *ptr); + +class union_flow { + friend inline union_flow manage(__isl_take isl_union_flow *ptr); + friend inline union_flow manage_copy(__isl_keep isl_union_flow *ptr); + +protected: + isl_union_flow *ptr = nullptr; + + inline explicit union_flow(__isl_take isl_union_flow *ptr); + +public: + inline /* implicit */ union_flow(); + inline /* implicit */ union_flow(const union_flow &obj); + inline union_flow &operator=(union_flow obj); + inline ~union_flow(); + inline __isl_give isl_union_flow *copy() const &; + inline __isl_give isl_union_flow *copy() && = delete; + inline __isl_keep isl_union_flow *get() const; + inline __isl_give isl_union_flow *release(); + inline bool is_null() const; + inline isl::checked::ctx ctx() const; + + inline isl::checked::union_map full_may_dependence() const; + inline isl::checked::union_map get_full_may_dependence() const; + inline isl::checked::union_map full_must_dependence() const; + inline isl::checked::union_map get_full_must_dependence() const; + inline isl::checked::union_map may_dependence() const; + inline isl::checked::union_map get_may_dependence() const; + inline isl::checked::union_map may_no_source() const; + inline isl::checked::union_map get_may_no_source() const; + inline isl::checked::union_map must_dependence() const; + inline isl::checked::union_map get_must_dependence() const; + inline isl::checked::union_map must_no_source() const; + inline isl::checked::union_map get_must_no_source() const; +}; + +// declarations for isl::union_map +inline union_map manage(__isl_take isl_union_map *ptr); +inline union_map manage_copy(__isl_keep isl_union_map *ptr); + +class union_map { + friend inline union_map manage(__isl_take isl_union_map *ptr); + friend inline union_map manage_copy(__isl_keep isl_union_map *ptr); + +protected: + isl_union_map *ptr = nullptr; + + inline explicit union_map(__isl_take isl_union_map *ptr); + +public: + inline /* implicit */ union_map(); + inline /* implicit */ union_map(const union_map &obj); + inline /* implicit */ union_map(isl::checked::basic_map bmap); + inline /* implicit */ union_map(isl::checked::map map); + inline explicit union_map(isl::checked::ctx ctx, const std::string &str); + inline union_map &operator=(union_map obj); + inline ~union_map(); + inline __isl_give isl_union_map *copy() const &; + inline __isl_give isl_union_map *copy() && = delete; + inline __isl_keep isl_union_map *get() const; + inline __isl_give isl_union_map *release(); + inline bool is_null() const; + inline isl::checked::ctx ctx() const; + + inline isl::checked::union_map affine_hull() const; + inline isl::checked::union_map apply_domain(isl::checked::union_map umap2) const; + inline isl::checked::union_map apply_range(isl::checked::union_map umap2) const; + inline isl::checked::map as_map() const; + inline isl::checked::multi_union_pw_aff as_multi_union_pw_aff() const; + inline isl::checked::union_pw_multi_aff as_union_pw_multi_aff() const; + inline isl::checked::union_set bind_range(isl::checked::multi_id tuple) const; + inline isl::checked::union_map coalesce() const; + inline isl::checked::union_map compute_divs() const; + inline isl::checked::union_map curry() const; + inline isl::checked::union_set deltas() const; + inline isl::checked::union_map detect_equalities() const; + inline isl::checked::union_set domain() const; + inline isl::checked::union_map domain_factor_domain() const; + inline isl::checked::union_map domain_factor_range() const; + inline isl::checked::union_map domain_map() const; + inline isl::checked::union_pw_multi_aff domain_map_union_pw_multi_aff() const; + inline isl::checked::union_map domain_product(isl::checked::union_map umap2) const; + inline isl::checked::union_map domain_reverse() const; + inline isl::checked::union_map drop_unused_params() const; + static inline isl::checked::union_map empty(isl::checked::ctx ctx); + inline isl::checked::union_map eq_at(isl::checked::multi_union_pw_aff mupa) const; + inline boolean every_map(const std::function &test) const; + inline isl::checked::map extract_map(isl::checked::space space) const; + inline isl::checked::union_map factor_domain() const; + inline isl::checked::union_map factor_range() const; + inline isl::checked::union_map fixed_power(isl::checked::val exp) const; + inline isl::checked::union_map fixed_power(long exp) const; + inline stat foreach_map(const std::function &fn) const; + static inline isl::checked::union_map from(isl::checked::multi_union_pw_aff mupa); + static inline isl::checked::union_map from(isl::checked::union_pw_multi_aff upma); + static inline isl::checked::union_map from_domain(isl::checked::union_set uset); + static inline isl::checked::union_map from_domain_and_range(isl::checked::union_set domain, isl::checked::union_set range); + static inline isl::checked::union_map from_range(isl::checked::union_set uset); + inline isl::checked::union_map gist(isl::checked::union_map context) const; + inline isl::checked::union_map gist_domain(isl::checked::union_set uset) const; + inline isl::checked::union_map gist_params(isl::checked::set set) const; + inline isl::checked::union_map gist_range(isl::checked::union_set uset) const; + inline isl::checked::union_map intersect(isl::checked::union_map umap2) const; + inline isl::checked::union_map intersect_domain(isl::checked::space space) const; + inline isl::checked::union_map intersect_domain(isl::checked::union_set uset) const; + inline isl::checked::union_map intersect_domain_factor_domain(isl::checked::union_map factor) const; + inline isl::checked::union_map intersect_domain_factor_range(isl::checked::union_map factor) const; + inline isl::checked::union_map intersect_domain_wrapped_domain(isl::checked::union_set domain) const; + inline isl::checked::union_map intersect_params(isl::checked::set set) const; + inline isl::checked::union_map intersect_range(isl::checked::space space) const; + inline isl::checked::union_map intersect_range(isl::checked::union_set uset) const; + inline isl::checked::union_map intersect_range_factor_domain(isl::checked::union_map factor) const; + inline isl::checked::union_map intersect_range_factor_range(isl::checked::union_map factor) const; + inline isl::checked::union_map intersect_range_wrapped_domain(isl::checked::union_set domain) const; + inline boolean is_bijective() const; + inline boolean is_disjoint(const isl::checked::union_map &umap2) const; + inline boolean is_empty() const; + inline boolean is_equal(const isl::checked::union_map &umap2) const; + inline boolean is_injective() const; + inline boolean is_single_valued() const; + inline boolean is_strict_subset(const isl::checked::union_map &umap2) const; + inline boolean is_subset(const isl::checked::union_map &umap2) const; + inline boolean isa_map() const; + inline isl::checked::union_map lexmax() const; + inline isl::checked::union_map lexmin() const; + inline isl::checked::map_list map_list() const; + inline isl::checked::map_list get_map_list() const; + inline isl::checked::set params() const; + inline isl::checked::union_map polyhedral_hull() const; + inline isl::checked::union_map preimage_domain(isl::checked::multi_aff ma) const; + inline isl::checked::union_map preimage_domain(isl::checked::multi_pw_aff mpa) const; + inline isl::checked::union_map preimage_domain(isl::checked::pw_multi_aff pma) const; + inline isl::checked::union_map preimage_domain(isl::checked::union_pw_multi_aff upma) const; + inline isl::checked::union_map preimage_range(isl::checked::multi_aff ma) const; + inline isl::checked::union_map preimage_range(isl::checked::pw_multi_aff pma) const; + inline isl::checked::union_map preimage_range(isl::checked::union_pw_multi_aff upma) const; + inline isl::checked::union_map product(isl::checked::union_map umap2) const; + inline isl::checked::union_map project_out_all_params() const; + inline isl::checked::union_map project_out_param(isl::checked::id id) const; + inline isl::checked::union_map project_out_param(const std::string &id) const; + inline isl::checked::union_map project_out_param(isl::checked::id_list list) const; + inline isl::checked::union_set range() const; + inline isl::checked::union_map range_factor_domain() const; + inline isl::checked::union_map range_factor_range() const; + inline isl::checked::union_map range_map() const; + inline isl::checked::union_map range_product(isl::checked::union_map umap2) const; + inline isl::checked::union_map range_reverse() const; + inline isl::checked::union_map reverse() const; + inline isl::checked::space space() const; + inline isl::checked::space get_space() const; + inline isl::checked::union_map subtract(isl::checked::union_map umap2) const; + inline isl::checked::union_map subtract_domain(isl::checked::union_set dom) const; + inline isl::checked::union_map subtract_range(isl::checked::union_set dom) const; + inline isl::checked::union_map uncurry() const; + inline isl::checked::union_map unite(isl::checked::union_map umap2) const; + inline isl::checked::union_map universe() const; + inline isl::checked::union_set wrap() const; + inline isl::checked::union_map zip() const; +}; + +// declarations for isl::union_pw_aff +inline union_pw_aff manage(__isl_take isl_union_pw_aff *ptr); +inline union_pw_aff manage_copy(__isl_keep isl_union_pw_aff *ptr); + +class union_pw_aff { + friend inline union_pw_aff manage(__isl_take isl_union_pw_aff *ptr); + friend inline union_pw_aff manage_copy(__isl_keep isl_union_pw_aff *ptr); + +protected: + isl_union_pw_aff *ptr = nullptr; + + inline explicit union_pw_aff(__isl_take isl_union_pw_aff *ptr); + +public: + inline /* implicit */ union_pw_aff(); + inline /* implicit */ union_pw_aff(const union_pw_aff &obj); + inline /* implicit */ union_pw_aff(isl::checked::aff aff); + inline /* implicit */ union_pw_aff(isl::checked::pw_aff pa); + inline explicit union_pw_aff(isl::checked::ctx ctx, const std::string &str); + inline union_pw_aff &operator=(union_pw_aff obj); + inline ~union_pw_aff(); + inline __isl_give isl_union_pw_aff *copy() const &; + inline __isl_give isl_union_pw_aff *copy() && = delete; + inline __isl_keep isl_union_pw_aff *get() const; + inline __isl_give isl_union_pw_aff *release(); + inline bool is_null() const; + inline isl::checked::ctx ctx() const; + + inline isl::checked::multi_union_pw_aff add(const isl::checked::multi_union_pw_aff &multi2) const; + inline isl::checked::union_pw_aff add(isl::checked::union_pw_aff upa2) const; + inline isl::checked::union_pw_multi_aff add(const isl::checked::union_pw_multi_aff &upma2) const; + inline isl::checked::union_pw_aff add(const isl::checked::aff &upa2) const; + inline isl::checked::union_pw_aff add(const isl::checked::pw_aff &upa2) const; + inline isl::checked::union_pw_multi_aff apply(const isl::checked::union_pw_multi_aff &upma2) const; + inline isl::checked::multi_union_pw_aff as_multi_union_pw_aff() const; + inline isl::checked::pw_multi_aff as_pw_multi_aff() const; + inline isl::checked::union_map as_union_map() const; + inline isl::checked::union_pw_aff at(int pos) const; + inline isl::checked::union_set bind(const isl::checked::multi_id &tuple) const; + inline isl::checked::union_set bind(isl::checked::id id) const; + inline isl::checked::union_set bind(const std::string &id) const; + inline isl::checked::union_pw_aff coalesce() const; + inline isl::checked::union_set domain() const; + inline isl::checked::union_pw_aff drop_unused_params() const; + inline isl::checked::pw_multi_aff extract_pw_multi_aff(const isl::checked::space &space) const; + inline isl::checked::multi_union_pw_aff flat_range_product(const isl::checked::multi_union_pw_aff &multi2) const; + inline isl::checked::union_pw_multi_aff flat_range_product(const isl::checked::union_pw_multi_aff &upma2) const; + inline isl::checked::union_pw_aff gist(isl::checked::union_set context) const; + inline isl::checked::multi_union_pw_aff gist_params(const isl::checked::set &context) const; + inline boolean has_range_tuple_id() const; + inline isl::checked::union_pw_aff intersect_domain(isl::checked::space space) const; + inline isl::checked::union_pw_aff intersect_domain(isl::checked::union_set uset) const; + inline isl::checked::union_pw_aff intersect_domain_wrapped_domain(isl::checked::union_set uset) const; + inline isl::checked::union_pw_aff intersect_domain_wrapped_range(isl::checked::union_set uset) const; + inline isl::checked::union_pw_aff intersect_params(isl::checked::set set) const; + inline boolean involves_locals() const; + inline boolean involves_nan() const; + inline boolean isa_pw_multi_aff() const; + inline isl::checked::union_pw_aff_list list() const; + inline isl::checked::multi_union_pw_aff neg() const; + inline boolean plain_is_empty() const; + inline boolean plain_is_equal(const isl::checked::multi_union_pw_aff &multi2) const; + inline boolean plain_is_equal(const isl::checked::union_pw_aff &upa2) const; + inline boolean plain_is_equal(const isl::checked::union_pw_multi_aff &upma2) const; + inline boolean plain_is_equal(const isl::checked::aff &upa2) const; + inline boolean plain_is_equal(const isl::checked::pw_aff &upa2) const; + inline isl::checked::union_pw_multi_aff preimage_domain_wrapped_domain(const isl::checked::union_pw_multi_aff &upma2) const; + inline isl::checked::union_pw_aff pullback(isl::checked::union_pw_multi_aff upma) const; + inline isl::checked::pw_multi_aff_list pw_multi_aff_list() const; + inline isl::checked::union_pw_multi_aff range_factor_domain() const; + inline isl::checked::union_pw_multi_aff range_factor_range() const; + inline isl::checked::multi_union_pw_aff range_product(const isl::checked::multi_union_pw_aff &multi2) const; + inline isl::checked::union_pw_multi_aff range_product(const isl::checked::union_pw_multi_aff &upma2) const; + inline isl::checked::id range_tuple_id() const; + inline isl::checked::multi_union_pw_aff reset_range_tuple_id() const; + inline isl::checked::multi_union_pw_aff scale(const isl::checked::multi_val &mv) const; + inline isl::checked::multi_union_pw_aff scale(const isl::checked::val &v) const; + inline isl::checked::multi_union_pw_aff scale(long v) const; + inline isl::checked::multi_union_pw_aff scale_down(const isl::checked::multi_val &mv) const; + inline isl::checked::multi_union_pw_aff scale_down(const isl::checked::val &v) const; + inline isl::checked::multi_union_pw_aff scale_down(long v) const; + inline isl::checked::multi_union_pw_aff set_at(int pos, const isl::checked::union_pw_aff &el) const; + inline isl::checked::multi_union_pw_aff set_range_tuple(const isl::checked::id &id) const; + inline isl::checked::multi_union_pw_aff set_range_tuple(const std::string &id) const; + inline class size size() const; + inline isl::checked::space space() const; + inline isl::checked::space get_space() const; + inline isl::checked::multi_union_pw_aff sub(const isl::checked::multi_union_pw_aff &multi2) const; + inline isl::checked::union_pw_aff sub(isl::checked::union_pw_aff upa2) const; + inline isl::checked::union_pw_multi_aff sub(const isl::checked::union_pw_multi_aff &upma2) const; + inline isl::checked::union_pw_aff sub(const isl::checked::aff &upa2) const; + inline isl::checked::union_pw_aff sub(const isl::checked::pw_aff &upa2) const; + inline isl::checked::union_pw_aff subtract_domain(isl::checked::space space) const; + inline isl::checked::union_pw_aff subtract_domain(isl::checked::union_set uset) const; + inline isl::checked::union_pw_aff_list to_list() const; + inline isl::checked::multi_union_pw_aff union_add(const isl::checked::multi_union_pw_aff &mupa2) const; + inline isl::checked::union_pw_aff union_add(isl::checked::union_pw_aff upa2) const; + inline isl::checked::union_pw_multi_aff union_add(const isl::checked::union_pw_multi_aff &upma2) const; + inline isl::checked::union_pw_aff union_add(const isl::checked::aff &upa2) const; + inline isl::checked::union_pw_aff union_add(const isl::checked::pw_aff &upa2) const; +}; + +// declarations for isl::union_pw_aff_list +inline union_pw_aff_list manage(__isl_take isl_union_pw_aff_list *ptr); +inline union_pw_aff_list manage_copy(__isl_keep isl_union_pw_aff_list *ptr); + +class union_pw_aff_list { + friend inline union_pw_aff_list manage(__isl_take isl_union_pw_aff_list *ptr); + friend inline union_pw_aff_list manage_copy(__isl_keep isl_union_pw_aff_list *ptr); + +protected: + isl_union_pw_aff_list *ptr = nullptr; + + inline explicit union_pw_aff_list(__isl_take isl_union_pw_aff_list *ptr); + +public: + inline /* implicit */ union_pw_aff_list(); + inline /* implicit */ union_pw_aff_list(const union_pw_aff_list &obj); + inline explicit union_pw_aff_list(isl::checked::ctx ctx, int n); + inline explicit union_pw_aff_list(isl::checked::union_pw_aff el); + inline explicit union_pw_aff_list(isl::checked::ctx ctx, const std::string &str); + inline union_pw_aff_list &operator=(union_pw_aff_list obj); + inline ~union_pw_aff_list(); + inline __isl_give isl_union_pw_aff_list *copy() const &; + inline __isl_give isl_union_pw_aff_list *copy() && = delete; + inline __isl_keep isl_union_pw_aff_list *get() const; + inline __isl_give isl_union_pw_aff_list *release(); + inline bool is_null() const; + inline isl::checked::ctx ctx() const; + + inline isl::checked::union_pw_aff_list add(isl::checked::union_pw_aff el) const; + inline isl::checked::union_pw_aff at(int index) const; + inline isl::checked::union_pw_aff get_at(int index) const; + inline isl::checked::union_pw_aff_list clear() const; + inline isl::checked::union_pw_aff_list concat(isl::checked::union_pw_aff_list list2) const; + inline isl::checked::union_pw_aff_list drop(unsigned int first, unsigned int n) const; + inline stat foreach(const std::function &fn) const; + inline stat foreach_scc(const std::function &follows, const std::function &fn) const; + inline isl::checked::union_pw_aff_list insert(unsigned int pos, isl::checked::union_pw_aff el) const; + inline isl::checked::union_pw_aff_list set_at(int index, isl::checked::union_pw_aff el) const; + inline class size size() const; +}; + +// declarations for isl::union_pw_multi_aff +inline union_pw_multi_aff manage(__isl_take isl_union_pw_multi_aff *ptr); +inline union_pw_multi_aff manage_copy(__isl_keep isl_union_pw_multi_aff *ptr); + +class union_pw_multi_aff { + friend inline union_pw_multi_aff manage(__isl_take isl_union_pw_multi_aff *ptr); + friend inline union_pw_multi_aff manage_copy(__isl_keep isl_union_pw_multi_aff *ptr); + +protected: + isl_union_pw_multi_aff *ptr = nullptr; + + inline explicit union_pw_multi_aff(__isl_take isl_union_pw_multi_aff *ptr); + +public: + inline /* implicit */ union_pw_multi_aff(); + inline /* implicit */ union_pw_multi_aff(const union_pw_multi_aff &obj); + inline /* implicit */ union_pw_multi_aff(isl::checked::multi_aff ma); + inline /* implicit */ union_pw_multi_aff(isl::checked::pw_multi_aff pma); + inline /* implicit */ union_pw_multi_aff(isl::checked::union_pw_aff upa); + inline explicit union_pw_multi_aff(isl::checked::ctx ctx, const std::string &str); + inline union_pw_multi_aff &operator=(union_pw_multi_aff obj); + inline ~union_pw_multi_aff(); + inline __isl_give isl_union_pw_multi_aff *copy() const &; + inline __isl_give isl_union_pw_multi_aff *copy() && = delete; + inline __isl_keep isl_union_pw_multi_aff *get() const; + inline __isl_give isl_union_pw_multi_aff *release(); + inline bool is_null() const; + inline isl::checked::ctx ctx() const; + + inline isl::checked::union_pw_multi_aff add(isl::checked::union_pw_multi_aff upma2) const; + inline isl::checked::union_pw_multi_aff apply(isl::checked::union_pw_multi_aff upma2) const; + inline isl::checked::multi_union_pw_aff as_multi_union_pw_aff() const; + inline isl::checked::pw_multi_aff as_pw_multi_aff() const; + inline isl::checked::union_map as_union_map() const; + inline isl::checked::union_pw_multi_aff coalesce() const; + inline isl::checked::union_set domain() const; + inline isl::checked::union_pw_multi_aff drop_unused_params() const; + static inline isl::checked::union_pw_multi_aff empty(isl::checked::ctx ctx); + inline isl::checked::pw_multi_aff extract_pw_multi_aff(isl::checked::space space) const; + inline isl::checked::union_pw_multi_aff flat_range_product(isl::checked::union_pw_multi_aff upma2) const; + inline isl::checked::union_pw_multi_aff gist(isl::checked::union_set context) const; + inline isl::checked::union_pw_multi_aff intersect_domain(isl::checked::space space) const; + inline isl::checked::union_pw_multi_aff intersect_domain(isl::checked::union_set uset) const; + inline isl::checked::union_pw_multi_aff intersect_domain_wrapped_domain(isl::checked::union_set uset) const; + inline isl::checked::union_pw_multi_aff intersect_domain_wrapped_range(isl::checked::union_set uset) const; + inline isl::checked::union_pw_multi_aff intersect_params(isl::checked::set set) const; + inline boolean involves_locals() const; + inline boolean isa_pw_multi_aff() const; + inline boolean plain_is_empty() const; + inline boolean plain_is_equal(const isl::checked::union_pw_multi_aff &upma2) const; + inline isl::checked::union_pw_multi_aff preimage_domain_wrapped_domain(isl::checked::union_pw_multi_aff upma2) const; + inline isl::checked::union_pw_multi_aff pullback(isl::checked::union_pw_multi_aff upma2) const; + inline isl::checked::pw_multi_aff_list pw_multi_aff_list() const; + inline isl::checked::pw_multi_aff_list get_pw_multi_aff_list() const; + inline isl::checked::union_pw_multi_aff range_factor_domain() const; + inline isl::checked::union_pw_multi_aff range_factor_range() const; + inline isl::checked::union_pw_multi_aff range_product(isl::checked::union_pw_multi_aff upma2) const; + inline isl::checked::space space() const; + inline isl::checked::space get_space() const; + inline isl::checked::union_pw_multi_aff sub(isl::checked::union_pw_multi_aff upma2) const; + inline isl::checked::union_pw_multi_aff subtract_domain(isl::checked::space space) const; + inline isl::checked::union_pw_multi_aff subtract_domain(isl::checked::union_set uset) const; + inline isl::checked::union_pw_multi_aff union_add(isl::checked::union_pw_multi_aff upma2) const; +}; + +// declarations for isl::union_set +inline union_set manage(__isl_take isl_union_set *ptr); +inline union_set manage_copy(__isl_keep isl_union_set *ptr); + +class union_set { + friend inline union_set manage(__isl_take isl_union_set *ptr); + friend inline union_set manage_copy(__isl_keep isl_union_set *ptr); + +protected: + isl_union_set *ptr = nullptr; + + inline explicit union_set(__isl_take isl_union_set *ptr); + +public: + inline /* implicit */ union_set(); + inline /* implicit */ union_set(const union_set &obj); + inline /* implicit */ union_set(isl::checked::basic_set bset); + inline /* implicit */ union_set(isl::checked::point pnt); + inline /* implicit */ union_set(isl::checked::set set); + inline explicit union_set(isl::checked::ctx ctx, const std::string &str); + inline union_set &operator=(union_set obj); + inline ~union_set(); + inline __isl_give isl_union_set *copy() const &; + inline __isl_give isl_union_set *copy() && = delete; + inline __isl_keep isl_union_set *get() const; + inline __isl_give isl_union_set *release(); + inline bool is_null() const; + inline isl::checked::ctx ctx() const; + + inline isl::checked::union_set affine_hull() const; + inline isl::checked::union_set apply(isl::checked::union_map umap) const; + inline isl::checked::set as_set() const; + inline isl::checked::union_set coalesce() const; + inline isl::checked::union_set compute_divs() const; + inline isl::checked::union_set detect_equalities() const; + inline isl::checked::union_set drop_unused_params() const; + static inline isl::checked::union_set empty(isl::checked::ctx ctx); + inline boolean every_set(const std::function &test) const; + inline isl::checked::set extract_set(isl::checked::space space) const; + inline stat foreach_point(const std::function &fn) const; + inline stat foreach_set(const std::function &fn) const; + inline isl::checked::union_set gist(isl::checked::union_set context) const; + inline isl::checked::union_set gist_params(isl::checked::set set) const; + inline isl::checked::union_map identity() const; + inline isl::checked::union_set intersect(isl::checked::union_set uset2) const; + inline isl::checked::union_set intersect_params(isl::checked::set set) const; + inline boolean is_disjoint(const isl::checked::union_set &uset2) const; + inline boolean is_empty() const; + inline boolean is_equal(const isl::checked::union_set &uset2) const; + inline boolean is_strict_subset(const isl::checked::union_set &uset2) const; + inline boolean is_subset(const isl::checked::union_set &uset2) const; + inline boolean isa_set() const; + inline isl::checked::union_set lexmax() const; + inline isl::checked::union_set lexmin() const; + inline isl::checked::set params() const; + inline isl::checked::union_set polyhedral_hull() const; + inline isl::checked::union_set preimage(isl::checked::multi_aff ma) const; + inline isl::checked::union_set preimage(isl::checked::pw_multi_aff pma) const; + inline isl::checked::union_set preimage(isl::checked::union_pw_multi_aff upma) const; + inline isl::checked::union_set project_out_all_params() const; + inline isl::checked::point sample_point() const; + inline isl::checked::set_list set_list() const; + inline isl::checked::set_list get_set_list() const; + inline isl::checked::space space() const; + inline isl::checked::space get_space() const; + inline isl::checked::union_set subtract(isl::checked::union_set uset2) const; + inline isl::checked::union_set_list to_list() const; + inline isl::checked::union_set unite(isl::checked::union_set uset2) const; + inline isl::checked::union_set universe() const; + inline isl::checked::union_map unwrap() const; +}; + +// declarations for isl::union_set_list +inline union_set_list manage(__isl_take isl_union_set_list *ptr); +inline union_set_list manage_copy(__isl_keep isl_union_set_list *ptr); + +class union_set_list { + friend inline union_set_list manage(__isl_take isl_union_set_list *ptr); + friend inline union_set_list manage_copy(__isl_keep isl_union_set_list *ptr); + +protected: + isl_union_set_list *ptr = nullptr; + + inline explicit union_set_list(__isl_take isl_union_set_list *ptr); + +public: + inline /* implicit */ union_set_list(); + inline /* implicit */ union_set_list(const union_set_list &obj); + inline explicit union_set_list(isl::checked::ctx ctx, int n); + inline explicit union_set_list(isl::checked::union_set el); + inline explicit union_set_list(isl::checked::ctx ctx, const std::string &str); + inline union_set_list &operator=(union_set_list obj); + inline ~union_set_list(); + inline __isl_give isl_union_set_list *copy() const &; + inline __isl_give isl_union_set_list *copy() && = delete; + inline __isl_keep isl_union_set_list *get() const; + inline __isl_give isl_union_set_list *release(); + inline bool is_null() const; + inline isl::checked::ctx ctx() const; + + inline isl::checked::union_set_list add(isl::checked::union_set el) const; + inline isl::checked::union_set at(int index) const; + inline isl::checked::union_set get_at(int index) const; + inline isl::checked::union_set_list clear() const; + inline isl::checked::union_set_list concat(isl::checked::union_set_list list2) const; + inline isl::checked::union_set_list drop(unsigned int first, unsigned int n) const; + inline stat foreach(const std::function &fn) const; + inline stat foreach_scc(const std::function &follows, const std::function &fn) const; + inline isl::checked::union_set_list insert(unsigned int pos, isl::checked::union_set el) const; + inline isl::checked::union_set_list set_at(int index, isl::checked::union_set el) const; + inline class size size() const; +}; + +// declarations for isl::val +inline val manage(__isl_take isl_val *ptr); +inline val manage_copy(__isl_keep isl_val *ptr); + +class val { + friend inline val manage(__isl_take isl_val *ptr); + friend inline val manage_copy(__isl_keep isl_val *ptr); + +protected: + isl_val *ptr = nullptr; + + inline explicit val(__isl_take isl_val *ptr); + +public: + inline /* implicit */ val(); + inline /* implicit */ val(const val &obj); + inline explicit val(isl::checked::ctx ctx, long i); + inline explicit val(isl::checked::ctx ctx, const std::string &str); + inline val &operator=(val obj); + inline ~val(); + inline __isl_give isl_val *copy() const &; + inline __isl_give isl_val *copy() && = delete; + inline __isl_keep isl_val *get() const; + inline __isl_give isl_val *release(); + inline bool is_null() const; + inline isl::checked::ctx ctx() const; + + inline isl::checked::val abs() const; + inline boolean abs_eq(const isl::checked::val &v2) const; + inline boolean abs_eq(long v2) const; + inline isl::checked::val add(isl::checked::val v2) const; + inline isl::checked::val add(long v2) const; + inline isl::checked::val ceil() const; + inline int cmp_si(long i) const; + inline long den_si() const; + inline long get_den_si() const; + inline isl::checked::val div(isl::checked::val v2) const; + inline isl::checked::val div(long v2) const; + inline boolean eq(const isl::checked::val &v2) const; + inline boolean eq(long v2) const; + inline isl::checked::val floor() const; + inline isl::checked::val gcd(isl::checked::val v2) const; + inline isl::checked::val gcd(long v2) const; + inline boolean ge(const isl::checked::val &v2) const; + inline boolean ge(long v2) const; + inline boolean gt(const isl::checked::val &v2) const; + inline boolean gt(long v2) const; + static inline isl::checked::val infty(isl::checked::ctx ctx); + inline isl::checked::val inv() const; + inline boolean is_divisible_by(const isl::checked::val &v2) const; + inline boolean is_divisible_by(long v2) const; + inline boolean is_infty() const; + inline boolean is_int() const; + inline boolean is_nan() const; + inline boolean is_neg() const; + inline boolean is_neginfty() const; + inline boolean is_negone() const; + inline boolean is_nonneg() const; + inline boolean is_nonpos() const; + inline boolean is_one() const; + inline boolean is_pos() const; + inline boolean is_rat() const; + inline boolean is_zero() const; + inline boolean le(const isl::checked::val &v2) const; + inline boolean le(long v2) const; + inline boolean lt(const isl::checked::val &v2) const; + inline boolean lt(long v2) const; + inline isl::checked::val max(isl::checked::val v2) const; + inline isl::checked::val max(long v2) const; + inline isl::checked::val min(isl::checked::val v2) const; + inline isl::checked::val min(long v2) const; + inline isl::checked::val mod(isl::checked::val v2) const; + inline isl::checked::val mod(long v2) const; + inline isl::checked::val mul(isl::checked::val v2) const; + inline isl::checked::val mul(long v2) const; + static inline isl::checked::val nan(isl::checked::ctx ctx); + inline boolean ne(const isl::checked::val &v2) const; + inline boolean ne(long v2) const; + inline isl::checked::val neg() const; + static inline isl::checked::val neginfty(isl::checked::ctx ctx); + static inline isl::checked::val negone(isl::checked::ctx ctx); + inline long num_si() const; + inline long get_num_si() const; + static inline isl::checked::val one(isl::checked::ctx ctx); + inline isl::checked::val pow2() const; + inline int sgn() const; + inline isl::checked::val sub(isl::checked::val v2) const; + inline isl::checked::val sub(long v2) const; + inline isl::checked::val_list to_list() const; + inline isl::checked::val trunc() const; + static inline isl::checked::val zero(isl::checked::ctx ctx); +}; + +// declarations for isl::val_list +inline val_list manage(__isl_take isl_val_list *ptr); +inline val_list manage_copy(__isl_keep isl_val_list *ptr); + +class val_list { + friend inline val_list manage(__isl_take isl_val_list *ptr); + friend inline val_list manage_copy(__isl_keep isl_val_list *ptr); + +protected: + isl_val_list *ptr = nullptr; + + inline explicit val_list(__isl_take isl_val_list *ptr); + +public: + inline /* implicit */ val_list(); + inline /* implicit */ val_list(const val_list &obj); + inline explicit val_list(isl::checked::ctx ctx, int n); + inline explicit val_list(isl::checked::val el); + inline explicit val_list(isl::checked::ctx ctx, const std::string &str); + inline val_list &operator=(val_list obj); + inline ~val_list(); + inline __isl_give isl_val_list *copy() const &; + inline __isl_give isl_val_list *copy() && = delete; + inline __isl_keep isl_val_list *get() const; + inline __isl_give isl_val_list *release(); + inline bool is_null() const; + inline isl::checked::ctx ctx() const; + + inline isl::checked::val_list add(isl::checked::val el) const; + inline isl::checked::val_list add(long el) const; + inline isl::checked::val at(int index) const; + inline isl::checked::val get_at(int index) const; + inline isl::checked::val_list clear() const; + inline isl::checked::val_list concat(isl::checked::val_list list2) const; + inline isl::checked::val_list drop(unsigned int first, unsigned int n) const; + inline stat foreach(const std::function &fn) const; + inline stat foreach_scc(const std::function &follows, const std::function &fn) const; + inline isl::checked::val_list insert(unsigned int pos, isl::checked::val el) const; + inline isl::checked::val_list insert(unsigned int pos, long el) const; + inline isl::checked::val_list set_at(int index, isl::checked::val el) const; + inline isl::checked::val_list set_at(int index, long el) const; + inline class size size() const; +}; + +// implementations for isl::aff +aff manage(__isl_take isl_aff *ptr) { + return aff(ptr); +} +aff manage_copy(__isl_keep isl_aff *ptr) { + ptr = isl_aff_copy(ptr); + return aff(ptr); +} + +aff::aff(__isl_take isl_aff *ptr) + : ptr(ptr) {} + +aff::aff() + : ptr(nullptr) {} + +aff::aff(const aff &obj) + : ptr(nullptr) +{ + ptr = obj.copy(); +} + +aff::aff(isl::checked::ctx ctx, const std::string &str) +{ + auto res = isl_aff_read_from_str(ctx.release(), str.c_str()); + ptr = res; +} + +aff &aff::operator=(aff obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +aff::~aff() { + if (ptr) + isl_aff_free(ptr); +} + +__isl_give isl_aff *aff::copy() const & { + return isl_aff_copy(ptr); +} + +__isl_keep isl_aff *aff::get() const { + return ptr; +} + +__isl_give isl_aff *aff::release() { + isl_aff *tmp = ptr; + ptr = nullptr; + return tmp; +} + +bool aff::is_null() const { + return ptr == nullptr; +} + +isl::checked::ctx aff::ctx() const { + return isl::checked::ctx(isl_aff_get_ctx(ptr)); +} + +isl::checked::aff aff::add(isl::checked::aff aff2) const +{ + auto res = isl_aff_add(copy(), aff2.release()); + return manage(res); +} + +isl::checked::multi_aff aff::add(const isl::checked::multi_aff &multi2) const +{ + return isl::checked::multi_aff(*this).add(multi2); +} + +isl::checked::multi_pw_aff aff::add(const isl::checked::multi_pw_aff &multi2) const +{ + return isl::checked::pw_aff(*this).add(multi2); +} + +isl::checked::multi_union_pw_aff aff::add(const isl::checked::multi_union_pw_aff &multi2) const +{ + return isl::checked::pw_aff(*this).add(multi2); +} + +isl::checked::pw_aff aff::add(const isl::checked::pw_aff &pwaff2) const +{ + return isl::checked::pw_aff(*this).add(pwaff2); +} + +isl::checked::pw_multi_aff aff::add(const isl::checked::pw_multi_aff &pma2) const +{ + return isl::checked::pw_aff(*this).add(pma2); +} + +isl::checked::union_pw_aff aff::add(const isl::checked::union_pw_aff &upa2) const +{ + return isl::checked::pw_aff(*this).add(upa2); +} + +isl::checked::union_pw_multi_aff aff::add(const isl::checked::union_pw_multi_aff &upma2) const +{ + return isl::checked::pw_aff(*this).add(upma2); +} + +isl::checked::aff aff::add_constant(isl::checked::val v) const +{ + auto res = isl_aff_add_constant_val(copy(), v.release()); + return manage(res); +} + +isl::checked::aff aff::add_constant(long v) const +{ + return this->add_constant(isl::checked::val(ctx(), v)); +} + +isl::checked::multi_aff aff::add_constant(const isl::checked::multi_val &mv) const +{ + return isl::checked::multi_aff(*this).add_constant(mv); +} + +isl::checked::union_pw_multi_aff aff::apply(const isl::checked::union_pw_multi_aff &upma2) const +{ + return isl::checked::pw_aff(*this).apply(upma2); +} + +isl::checked::aff aff::as_aff() const +{ + return isl::checked::pw_aff(*this).as_aff(); +} + +isl::checked::map aff::as_map() const +{ + return isl::checked::pw_aff(*this).as_map(); +} + +isl::checked::multi_aff aff::as_multi_aff() const +{ + return isl::checked::pw_aff(*this).as_multi_aff(); +} + +isl::checked::multi_union_pw_aff aff::as_multi_union_pw_aff() const +{ + return isl::checked::pw_aff(*this).as_multi_union_pw_aff(); +} + +isl::checked::pw_multi_aff aff::as_pw_multi_aff() const +{ + return isl::checked::pw_aff(*this).as_pw_multi_aff(); +} + +isl::checked::set aff::as_set() const +{ + return isl::checked::multi_aff(*this).as_set(); +} + +isl::checked::union_map aff::as_union_map() const +{ + return isl::checked::pw_aff(*this).as_union_map(); +} + +isl::checked::aff aff::at(int pos) const +{ + return isl::checked::multi_aff(*this).at(pos); +} + +isl::checked::basic_set aff::bind(isl::checked::id id) const +{ + auto res = isl_aff_bind_id(copy(), id.release()); + return manage(res); +} + +isl::checked::basic_set aff::bind(const std::string &id) const +{ + return this->bind(isl::checked::id(ctx(), id)); +} + +isl::checked::basic_set aff::bind(const isl::checked::multi_id &tuple) const +{ + return isl::checked::multi_aff(*this).bind(tuple); +} + +isl::checked::pw_aff aff::bind_domain(const isl::checked::multi_id &tuple) const +{ + return isl::checked::pw_aff(*this).bind_domain(tuple); +} + +isl::checked::pw_aff aff::bind_domain_wrapped_domain(const isl::checked::multi_id &tuple) const +{ + return isl::checked::pw_aff(*this).bind_domain_wrapped_domain(tuple); +} + +isl::checked::aff aff::ceil() const +{ + auto res = isl_aff_ceil(copy()); + return manage(res); +} + +isl::checked::pw_aff aff::coalesce() const +{ + return isl::checked::pw_aff(*this).coalesce(); +} + +isl::checked::pw_aff aff::cond(const isl::checked::pw_aff &pwaff_true, const isl::checked::pw_aff &pwaff_false) const +{ + return isl::checked::pw_aff(*this).cond(pwaff_true, pwaff_false); +} + +isl::checked::multi_val aff::constant_multi_val() const +{ + return isl::checked::multi_aff(*this).constant_multi_val(); +} + +isl::checked::val aff::constant_val() const +{ + auto res = isl_aff_get_constant_val(get()); + return manage(res); +} + +isl::checked::val aff::get_constant_val() const +{ + return constant_val(); +} + +isl::checked::aff aff::div(isl::checked::aff aff2) const +{ + auto res = isl_aff_div(copy(), aff2.release()); + return manage(res); +} + +isl::checked::pw_aff aff::div(const isl::checked::pw_aff &pa2) const +{ + return isl::checked::pw_aff(*this).div(pa2); +} + +isl::checked::set aff::domain() const +{ + return isl::checked::pw_aff(*this).domain(); +} + +isl::checked::aff aff::domain_reverse() const +{ + auto res = isl_aff_domain_reverse(copy()); + return manage(res); +} + +isl::checked::pw_aff aff::drop_unused_params() const +{ + return isl::checked::pw_aff(*this).drop_unused_params(); +} + +isl::checked::set aff::eq_set(isl::checked::aff aff2) const +{ + auto res = isl_aff_eq_set(copy(), aff2.release()); + return manage(res); +} + +isl::checked::set aff::eq_set(const isl::checked::pw_aff &pwaff2) const +{ + return isl::checked::pw_aff(*this).eq_set(pwaff2); +} + +isl::checked::val aff::eval(isl::checked::point pnt) const +{ + auto res = isl_aff_eval(copy(), pnt.release()); + return manage(res); +} + +isl::checked::pw_multi_aff aff::extract_pw_multi_aff(const isl::checked::space &space) const +{ + return isl::checked::pw_aff(*this).extract_pw_multi_aff(space); +} + +isl::checked::multi_aff aff::flat_range_product(const isl::checked::multi_aff &multi2) const +{ + return isl::checked::multi_aff(*this).flat_range_product(multi2); +} + +isl::checked::multi_pw_aff aff::flat_range_product(const isl::checked::multi_pw_aff &multi2) const +{ + return isl::checked::pw_aff(*this).flat_range_product(multi2); +} + +isl::checked::multi_union_pw_aff aff::flat_range_product(const isl::checked::multi_union_pw_aff &multi2) const +{ + return isl::checked::pw_aff(*this).flat_range_product(multi2); +} + +isl::checked::pw_multi_aff aff::flat_range_product(const isl::checked::pw_multi_aff &pma2) const +{ + return isl::checked::pw_aff(*this).flat_range_product(pma2); +} + +isl::checked::union_pw_multi_aff aff::flat_range_product(const isl::checked::union_pw_multi_aff &upma2) const +{ + return isl::checked::pw_aff(*this).flat_range_product(upma2); +} + +isl::checked::aff aff::floor() const +{ + auto res = isl_aff_floor(copy()); + return manage(res); +} + +stat aff::foreach_piece(const std::function &fn) const +{ + return isl::checked::pw_aff(*this).foreach_piece(fn); +} + +isl::checked::set aff::ge_set(isl::checked::aff aff2) const +{ + auto res = isl_aff_ge_set(copy(), aff2.release()); + return manage(res); +} + +isl::checked::set aff::ge_set(const isl::checked::pw_aff &pwaff2) const +{ + return isl::checked::pw_aff(*this).ge_set(pwaff2); +} + +isl::checked::aff aff::gist(isl::checked::set context) const +{ + auto res = isl_aff_gist(copy(), context.release()); + return manage(res); +} + +isl::checked::union_pw_aff aff::gist(const isl::checked::union_set &context) const +{ + return isl::checked::pw_aff(*this).gist(context); +} + +isl::checked::aff aff::gist(const isl::checked::basic_set &context) const +{ + return this->gist(isl::checked::set(context)); +} + +isl::checked::aff aff::gist(const isl::checked::point &context) const +{ + return this->gist(isl::checked::set(context)); +} + +isl::checked::aff aff::gist_params(isl::checked::set context) const +{ + auto res = isl_aff_gist_params(copy(), context.release()); + return manage(res); +} + +isl::checked::set aff::gt_set(isl::checked::aff aff2) const +{ + auto res = isl_aff_gt_set(copy(), aff2.release()); + return manage(res); +} + +isl::checked::set aff::gt_set(const isl::checked::pw_aff &pwaff2) const +{ + return isl::checked::pw_aff(*this).gt_set(pwaff2); +} + +boolean aff::has_range_tuple_id() const +{ + return isl::checked::multi_aff(*this).has_range_tuple_id(); +} + +isl::checked::multi_aff aff::identity() const +{ + return isl::checked::multi_aff(*this).identity(); +} + +isl::checked::pw_aff aff::insert_domain(const isl::checked::space &domain) const +{ + return isl::checked::pw_aff(*this).insert_domain(domain); +} + +isl::checked::pw_aff aff::intersect_domain(const isl::checked::set &set) const +{ + return isl::checked::pw_aff(*this).intersect_domain(set); +} + +isl::checked::union_pw_aff aff::intersect_domain(const isl::checked::space &space) const +{ + return isl::checked::pw_aff(*this).intersect_domain(space); +} + +isl::checked::union_pw_aff aff::intersect_domain(const isl::checked::union_set &uset) const +{ + return isl::checked::pw_aff(*this).intersect_domain(uset); +} + +isl::checked::union_pw_aff aff::intersect_domain_wrapped_domain(const isl::checked::union_set &uset) const +{ + return isl::checked::pw_aff(*this).intersect_domain_wrapped_domain(uset); +} + +isl::checked::union_pw_aff aff::intersect_domain_wrapped_range(const isl::checked::union_set &uset) const +{ + return isl::checked::pw_aff(*this).intersect_domain_wrapped_range(uset); +} + +isl::checked::pw_aff aff::intersect_params(const isl::checked::set &set) const +{ + return isl::checked::pw_aff(*this).intersect_params(set); +} + +boolean aff::involves_locals() const +{ + return isl::checked::multi_aff(*this).involves_locals(); +} + +boolean aff::involves_nan() const +{ + return isl::checked::multi_aff(*this).involves_nan(); +} + +boolean aff::involves_param(const isl::checked::id &id) const +{ + return isl::checked::pw_aff(*this).involves_param(id); +} + +boolean aff::involves_param(const std::string &id) const +{ + return this->involves_param(isl::checked::id(ctx(), id)); +} + +boolean aff::involves_param(const isl::checked::id_list &list) const +{ + return isl::checked::pw_aff(*this).involves_param(list); +} + +boolean aff::is_cst() const +{ + auto res = isl_aff_is_cst(get()); + return manage(res); +} + +boolean aff::isa_aff() const +{ + return isl::checked::pw_aff(*this).isa_aff(); +} + +boolean aff::isa_multi_aff() const +{ + return isl::checked::pw_aff(*this).isa_multi_aff(); +} + +boolean aff::isa_pw_multi_aff() const +{ + return isl::checked::pw_aff(*this).isa_pw_multi_aff(); +} + +isl::checked::set aff::le_set(isl::checked::aff aff2) const +{ + auto res = isl_aff_le_set(copy(), aff2.release()); + return manage(res); +} + +isl::checked::set aff::le_set(const isl::checked::pw_aff &pwaff2) const +{ + return isl::checked::pw_aff(*this).le_set(pwaff2); +} + +isl::checked::aff_list aff::list() const +{ + return isl::checked::multi_aff(*this).list(); +} + +isl::checked::set aff::lt_set(isl::checked::aff aff2) const +{ + auto res = isl_aff_lt_set(copy(), aff2.release()); + return manage(res); +} + +isl::checked::set aff::lt_set(const isl::checked::pw_aff &pwaff2) const +{ + return isl::checked::pw_aff(*this).lt_set(pwaff2); +} + +isl::checked::multi_pw_aff aff::max(const isl::checked::multi_pw_aff &multi2) const +{ + return isl::checked::pw_aff(*this).max(multi2); +} + +isl::checked::pw_aff aff::max(const isl::checked::pw_aff &pwaff2) const +{ + return isl::checked::pw_aff(*this).max(pwaff2); +} + +isl::checked::multi_val aff::max_multi_val() const +{ + return isl::checked::pw_aff(*this).max_multi_val(); +} + +isl::checked::val aff::max_val() const +{ + return isl::checked::pw_aff(*this).max_val(); +} + +isl::checked::multi_pw_aff aff::min(const isl::checked::multi_pw_aff &multi2) const +{ + return isl::checked::pw_aff(*this).min(multi2); +} + +isl::checked::pw_aff aff::min(const isl::checked::pw_aff &pwaff2) const +{ + return isl::checked::pw_aff(*this).min(pwaff2); +} + +isl::checked::multi_val aff::min_multi_val() const +{ + return isl::checked::pw_aff(*this).min_multi_val(); +} + +isl::checked::val aff::min_val() const +{ + return isl::checked::pw_aff(*this).min_val(); +} + +isl::checked::aff aff::mod(isl::checked::val mod) const +{ + auto res = isl_aff_mod_val(copy(), mod.release()); + return manage(res); +} + +isl::checked::aff aff::mod(long mod) const +{ + return this->mod(isl::checked::val(ctx(), mod)); +} + +isl::checked::aff aff::mul(isl::checked::aff aff2) const +{ + auto res = isl_aff_mul(copy(), aff2.release()); + return manage(res); +} + +isl::checked::pw_aff aff::mul(const isl::checked::pw_aff &pwaff2) const +{ + return isl::checked::pw_aff(*this).mul(pwaff2); +} + +class size aff::n_piece() const +{ + return isl::checked::pw_aff(*this).n_piece(); +} + +isl::checked::set aff::ne_set(isl::checked::aff aff2) const +{ + auto res = isl_aff_ne_set(copy(), aff2.release()); + return manage(res); +} + +isl::checked::set aff::ne_set(const isl::checked::pw_aff &pwaff2) const +{ + return isl::checked::pw_aff(*this).ne_set(pwaff2); +} + +isl::checked::aff aff::neg() const +{ + auto res = isl_aff_neg(copy()); + return manage(res); +} + +isl::checked::set aff::params() const +{ + return isl::checked::pw_aff(*this).params(); +} + +boolean aff::plain_is_empty() const +{ + return isl::checked::pw_aff(*this).plain_is_empty(); +} + +boolean aff::plain_is_equal(const isl::checked::aff &aff2) const +{ + auto res = isl_aff_plain_is_equal(get(), aff2.get()); + return manage(res); +} + +boolean aff::plain_is_equal(const isl::checked::multi_aff &multi2) const +{ + return isl::checked::multi_aff(*this).plain_is_equal(multi2); +} + +boolean aff::plain_is_equal(const isl::checked::multi_pw_aff &multi2) const +{ + return isl::checked::pw_aff(*this).plain_is_equal(multi2); +} + +boolean aff::plain_is_equal(const isl::checked::multi_union_pw_aff &multi2) const +{ + return isl::checked::pw_aff(*this).plain_is_equal(multi2); +} + +boolean aff::plain_is_equal(const isl::checked::pw_aff &pwaff2) const +{ + return isl::checked::pw_aff(*this).plain_is_equal(pwaff2); +} + +boolean aff::plain_is_equal(const isl::checked::pw_multi_aff &pma2) const +{ + return isl::checked::pw_aff(*this).plain_is_equal(pma2); +} + +boolean aff::plain_is_equal(const isl::checked::union_pw_aff &upa2) const +{ + return isl::checked::pw_aff(*this).plain_is_equal(upa2); +} + +boolean aff::plain_is_equal(const isl::checked::union_pw_multi_aff &upma2) const +{ + return isl::checked::pw_aff(*this).plain_is_equal(upma2); +} + +isl::checked::pw_multi_aff aff::preimage_domain_wrapped_domain(const isl::checked::pw_multi_aff &pma2) const +{ + return isl::checked::pw_aff(*this).preimage_domain_wrapped_domain(pma2); +} + +isl::checked::union_pw_multi_aff aff::preimage_domain_wrapped_domain(const isl::checked::union_pw_multi_aff &upma2) const +{ + return isl::checked::pw_aff(*this).preimage_domain_wrapped_domain(upma2); +} + +isl::checked::multi_aff aff::product(const isl::checked::multi_aff &multi2) const +{ + return isl::checked::multi_aff(*this).product(multi2); +} + +isl::checked::multi_pw_aff aff::product(const isl::checked::multi_pw_aff &multi2) const +{ + return isl::checked::pw_aff(*this).product(multi2); +} + +isl::checked::pw_multi_aff aff::product(const isl::checked::pw_multi_aff &pma2) const +{ + return isl::checked::pw_aff(*this).product(pma2); +} + +isl::checked::aff aff::pullback(isl::checked::multi_aff ma) const +{ + auto res = isl_aff_pullback_multi_aff(copy(), ma.release()); + return manage(res); +} + +isl::checked::pw_aff aff::pullback(const isl::checked::multi_pw_aff &mpa) const +{ + return isl::checked::pw_aff(*this).pullback(mpa); +} + +isl::checked::pw_aff aff::pullback(const isl::checked::pw_multi_aff &pma) const +{ + return isl::checked::pw_aff(*this).pullback(pma); +} + +isl::checked::union_pw_aff aff::pullback(const isl::checked::union_pw_multi_aff &upma) const +{ + return isl::checked::pw_aff(*this).pullback(upma); +} + +isl::checked::aff aff::pullback(const isl::checked::aff &ma) const +{ + return this->pullback(isl::checked::multi_aff(ma)); +} + +isl::checked::pw_multi_aff_list aff::pw_multi_aff_list() const +{ + return isl::checked::pw_aff(*this).pw_multi_aff_list(); +} + +isl::checked::pw_multi_aff aff::range_factor_domain() const +{ + return isl::checked::pw_aff(*this).range_factor_domain(); +} + +isl::checked::pw_multi_aff aff::range_factor_range() const +{ + return isl::checked::pw_aff(*this).range_factor_range(); +} + +isl::checked::multi_aff aff::range_product(const isl::checked::multi_aff &multi2) const +{ + return isl::checked::multi_aff(*this).range_product(multi2); +} + +isl::checked::multi_pw_aff aff::range_product(const isl::checked::multi_pw_aff &multi2) const +{ + return isl::checked::pw_aff(*this).range_product(multi2); +} + +isl::checked::multi_union_pw_aff aff::range_product(const isl::checked::multi_union_pw_aff &multi2) const +{ + return isl::checked::pw_aff(*this).range_product(multi2); +} + +isl::checked::pw_multi_aff aff::range_product(const isl::checked::pw_multi_aff &pma2) const +{ + return isl::checked::pw_aff(*this).range_product(pma2); +} + +isl::checked::union_pw_multi_aff aff::range_product(const isl::checked::union_pw_multi_aff &upma2) const +{ + return isl::checked::pw_aff(*this).range_product(upma2); +} + +isl::checked::id aff::range_tuple_id() const +{ + return isl::checked::multi_aff(*this).range_tuple_id(); +} + +isl::checked::multi_aff aff::reset_range_tuple_id() const +{ + return isl::checked::multi_aff(*this).reset_range_tuple_id(); +} + +isl::checked::aff aff::scale(isl::checked::val v) const +{ + auto res = isl_aff_scale_val(copy(), v.release()); + return manage(res); +} + +isl::checked::aff aff::scale(long v) const +{ + return this->scale(isl::checked::val(ctx(), v)); +} + +isl::checked::multi_aff aff::scale(const isl::checked::multi_val &mv) const +{ + return isl::checked::multi_aff(*this).scale(mv); +} + +isl::checked::aff aff::scale_down(isl::checked::val v) const +{ + auto res = isl_aff_scale_down_val(copy(), v.release()); + return manage(res); +} + +isl::checked::aff aff::scale_down(long v) const +{ + return this->scale_down(isl::checked::val(ctx(), v)); +} + +isl::checked::multi_aff aff::scale_down(const isl::checked::multi_val &mv) const +{ + return isl::checked::multi_aff(*this).scale_down(mv); +} + +isl::checked::multi_aff aff::set_at(int pos, const isl::checked::aff &el) const +{ + return isl::checked::multi_aff(*this).set_at(pos, el); +} + +isl::checked::multi_pw_aff aff::set_at(int pos, const isl::checked::pw_aff &el) const +{ + return isl::checked::pw_aff(*this).set_at(pos, el); +} + +isl::checked::multi_union_pw_aff aff::set_at(int pos, const isl::checked::union_pw_aff &el) const +{ + return isl::checked::pw_aff(*this).set_at(pos, el); +} + +isl::checked::multi_aff aff::set_range_tuple(const isl::checked::id &id) const +{ + return isl::checked::multi_aff(*this).set_range_tuple(id); +} + +isl::checked::multi_aff aff::set_range_tuple(const std::string &id) const +{ + return this->set_range_tuple(isl::checked::id(ctx(), id)); +} + +class size aff::size() const +{ + return isl::checked::multi_aff(*this).size(); +} + +isl::checked::space aff::space() const +{ + return isl::checked::pw_aff(*this).space(); +} + +isl::checked::aff aff::sub(isl::checked::aff aff2) const +{ + auto res = isl_aff_sub(copy(), aff2.release()); + return manage(res); +} + +isl::checked::multi_aff aff::sub(const isl::checked::multi_aff &multi2) const +{ + return isl::checked::multi_aff(*this).sub(multi2); +} + +isl::checked::multi_pw_aff aff::sub(const isl::checked::multi_pw_aff &multi2) const +{ + return isl::checked::pw_aff(*this).sub(multi2); +} + +isl::checked::multi_union_pw_aff aff::sub(const isl::checked::multi_union_pw_aff &multi2) const +{ + return isl::checked::pw_aff(*this).sub(multi2); +} + +isl::checked::pw_aff aff::sub(const isl::checked::pw_aff &pwaff2) const +{ + return isl::checked::pw_aff(*this).sub(pwaff2); +} + +isl::checked::pw_multi_aff aff::sub(const isl::checked::pw_multi_aff &pma2) const +{ + return isl::checked::pw_aff(*this).sub(pma2); +} + +isl::checked::union_pw_aff aff::sub(const isl::checked::union_pw_aff &upa2) const +{ + return isl::checked::pw_aff(*this).sub(upa2); +} + +isl::checked::union_pw_multi_aff aff::sub(const isl::checked::union_pw_multi_aff &upma2) const +{ + return isl::checked::pw_aff(*this).sub(upma2); +} + +isl::checked::pw_aff aff::subtract_domain(const isl::checked::set &set) const +{ + return isl::checked::pw_aff(*this).subtract_domain(set); +} + +isl::checked::union_pw_aff aff::subtract_domain(const isl::checked::space &space) const +{ + return isl::checked::pw_aff(*this).subtract_domain(space); +} + +isl::checked::union_pw_aff aff::subtract_domain(const isl::checked::union_set &uset) const +{ + return isl::checked::pw_aff(*this).subtract_domain(uset); +} + +isl::checked::pw_aff aff::tdiv_q(const isl::checked::pw_aff &pa2) const +{ + return isl::checked::pw_aff(*this).tdiv_q(pa2); +} + +isl::checked::pw_aff aff::tdiv_r(const isl::checked::pw_aff &pa2) const +{ + return isl::checked::pw_aff(*this).tdiv_r(pa2); +} + +isl::checked::aff_list aff::to_list() const +{ + auto res = isl_aff_to_list(copy()); + return manage(res); +} + +isl::checked::multi_pw_aff aff::to_multi_pw_aff() const +{ + return isl::checked::multi_aff(*this).to_multi_pw_aff(); +} + +isl::checked::multi_union_pw_aff aff::to_multi_union_pw_aff() const +{ + return isl::checked::multi_aff(*this).to_multi_union_pw_aff(); +} + +isl::checked::pw_multi_aff aff::to_pw_multi_aff() const +{ + return isl::checked::multi_aff(*this).to_pw_multi_aff(); +} + +isl::checked::union_pw_aff aff::to_union_pw_aff() const +{ + return isl::checked::pw_aff(*this).to_union_pw_aff(); +} + +isl::checked::union_pw_multi_aff aff::to_union_pw_multi_aff() const +{ + return isl::checked::pw_aff(*this).to_union_pw_multi_aff(); +} + +isl::checked::aff aff::unbind_params_insert_domain(isl::checked::multi_id domain) const +{ + auto res = isl_aff_unbind_params_insert_domain(copy(), domain.release()); + return manage(res); +} + +isl::checked::multi_pw_aff aff::union_add(const isl::checked::multi_pw_aff &mpa2) const +{ + return isl::checked::pw_aff(*this).union_add(mpa2); +} + +isl::checked::multi_union_pw_aff aff::union_add(const isl::checked::multi_union_pw_aff &mupa2) const +{ + return isl::checked::pw_aff(*this).union_add(mupa2); +} + +isl::checked::pw_aff aff::union_add(const isl::checked::pw_aff &pwaff2) const +{ + return isl::checked::pw_aff(*this).union_add(pwaff2); +} + +isl::checked::pw_multi_aff aff::union_add(const isl::checked::pw_multi_aff &pma2) const +{ + return isl::checked::pw_aff(*this).union_add(pma2); +} + +isl::checked::union_pw_aff aff::union_add(const isl::checked::union_pw_aff &upa2) const +{ + return isl::checked::pw_aff(*this).union_add(upa2); +} + +isl::checked::union_pw_multi_aff aff::union_add(const isl::checked::union_pw_multi_aff &upma2) const +{ + return isl::checked::pw_aff(*this).union_add(upma2); +} + +isl::checked::aff aff::zero_on_domain(isl::checked::space space) +{ + auto res = isl_aff_zero_on_domain_space(space.release()); + return manage(res); +} + +inline std::ostream &operator<<(std::ostream &os, const aff &obj) +{ + char *str = isl_aff_to_str(obj.get()); + if (!str) { + os.setstate(std::ios_base::badbit); + return os; + } + os << str; + free(str); + return os; +} + +// implementations for isl::aff_list +aff_list manage(__isl_take isl_aff_list *ptr) { + return aff_list(ptr); +} +aff_list manage_copy(__isl_keep isl_aff_list *ptr) { + ptr = isl_aff_list_copy(ptr); + return aff_list(ptr); +} + +aff_list::aff_list(__isl_take isl_aff_list *ptr) + : ptr(ptr) {} + +aff_list::aff_list() + : ptr(nullptr) {} + +aff_list::aff_list(const aff_list &obj) + : ptr(nullptr) +{ + ptr = obj.copy(); +} + +aff_list::aff_list(isl::checked::ctx ctx, int n) +{ + auto res = isl_aff_list_alloc(ctx.release(), n); + ptr = res; +} + +aff_list::aff_list(isl::checked::aff el) +{ + auto res = isl_aff_list_from_aff(el.release()); + ptr = res; +} + +aff_list::aff_list(isl::checked::ctx ctx, const std::string &str) +{ + auto res = isl_aff_list_read_from_str(ctx.release(), str.c_str()); + ptr = res; +} + +aff_list &aff_list::operator=(aff_list obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +aff_list::~aff_list() { + if (ptr) + isl_aff_list_free(ptr); +} + +__isl_give isl_aff_list *aff_list::copy() const & { + return isl_aff_list_copy(ptr); +} + +__isl_keep isl_aff_list *aff_list::get() const { + return ptr; +} + +__isl_give isl_aff_list *aff_list::release() { + isl_aff_list *tmp = ptr; + ptr = nullptr; + return tmp; +} + +bool aff_list::is_null() const { + return ptr == nullptr; +} + +isl::checked::ctx aff_list::ctx() const { + return isl::checked::ctx(isl_aff_list_get_ctx(ptr)); +} + +isl::checked::aff_list aff_list::add(isl::checked::aff el) const +{ + auto res = isl_aff_list_add(copy(), el.release()); + return manage(res); +} + +isl::checked::aff aff_list::at(int index) const +{ + auto res = isl_aff_list_get_at(get(), index); + return manage(res); +} + +isl::checked::aff aff_list::get_at(int index) const +{ + return at(index); +} + +isl::checked::aff_list aff_list::clear() const +{ + auto res = isl_aff_list_clear(copy()); + return manage(res); +} + +isl::checked::aff_list aff_list::concat(isl::checked::aff_list list2) const +{ + auto res = isl_aff_list_concat(copy(), list2.release()); + return manage(res); +} + +isl::checked::aff_list aff_list::drop(unsigned int first, unsigned int n) const +{ + auto res = isl_aff_list_drop(copy(), first, n); + return manage(res); +} + +stat aff_list::foreach(const std::function &fn) const +{ + struct fn_data { + std::function func; + } fn_data = { fn }; + auto fn_lambda = [](isl_aff *arg_0, void *arg_1) -> isl_stat { + auto *data = static_cast(arg_1); + auto ret = (data->func)(manage(arg_0)); + return ret.release(); + }; + auto res = isl_aff_list_foreach(get(), fn_lambda, &fn_data); + return manage(res); +} + +stat aff_list::foreach_scc(const std::function &follows, const std::function &fn) const +{ + struct follows_data { + std::function func; + } follows_data = { follows }; + auto follows_lambda = [](isl_aff *arg_0, isl_aff *arg_1, void *arg_2) -> isl_bool { + auto *data = static_cast(arg_2); + auto ret = (data->func)(manage_copy(arg_0), manage_copy(arg_1)); + return ret.release(); + }; + struct fn_data { + std::function func; + } fn_data = { fn }; + auto fn_lambda = [](isl_aff_list *arg_0, void *arg_1) -> isl_stat { + auto *data = static_cast(arg_1); + auto ret = (data->func)(manage(arg_0)); + return ret.release(); + }; + auto res = isl_aff_list_foreach_scc(get(), follows_lambda, &follows_data, fn_lambda, &fn_data); + return manage(res); +} + +isl::checked::aff_list aff_list::insert(unsigned int pos, isl::checked::aff el) const +{ + auto res = isl_aff_list_insert(copy(), pos, el.release()); + return manage(res); +} + +isl::checked::aff_list aff_list::set_at(int index, isl::checked::aff el) const +{ + auto res = isl_aff_list_set_at(copy(), index, el.release()); + return manage(res); +} + +class size aff_list::size() const +{ + auto res = isl_aff_list_size(get()); + return manage(res); +} + +inline std::ostream &operator<<(std::ostream &os, const aff_list &obj) +{ + char *str = isl_aff_list_to_str(obj.get()); + if (!str) { + os.setstate(std::ios_base::badbit); + return os; + } + os << str; + free(str); + return os; +} + +// implementations for isl::ast_build +ast_build manage(__isl_take isl_ast_build *ptr) { + return ast_build(ptr); +} +ast_build manage_copy(__isl_keep isl_ast_build *ptr) { + ptr = isl_ast_build_copy(ptr); + return ast_build(ptr); +} + +ast_build::ast_build(__isl_take isl_ast_build *ptr) + : ptr(ptr) {} + +ast_build::ast_build() + : ptr(nullptr) {} + +ast_build::ast_build(const ast_build &obj) + : ptr(nullptr) +{ + ptr = obj.copy(); + copy_callbacks(obj); +} + +ast_build::ast_build(isl::checked::ctx ctx) +{ + auto res = isl_ast_build_alloc(ctx.release()); + ptr = res; +} + +ast_build &ast_build::operator=(ast_build obj) { + std::swap(this->ptr, obj.ptr); + copy_callbacks(obj); + return *this; +} + +ast_build::~ast_build() { + if (ptr) + isl_ast_build_free(ptr); +} + +__isl_give isl_ast_build *ast_build::copy() const & { + return isl_ast_build_copy(ptr); +} + +__isl_keep isl_ast_build *ast_build::get() const { + return ptr; +} + +__isl_give isl_ast_build *ast_build::release() { + if (at_each_domain_data) + isl_die(ctx().get(), isl_error_invalid, "cannot release object with persistent callbacks", return nullptr); + isl_ast_build *tmp = ptr; + ptr = nullptr; + return tmp; +} + +bool ast_build::is_null() const { + return ptr == nullptr; +} + +isl::checked::ctx ast_build::ctx() const { + return isl::checked::ctx(isl_ast_build_get_ctx(ptr)); +} + +ast_build &ast_build::copy_callbacks(const ast_build &obj) +{ + at_each_domain_data = obj.at_each_domain_data; + return *this; +} + +isl_ast_node *ast_build::at_each_domain(isl_ast_node *arg_0, isl_ast_build *arg_1, void *arg_2) +{ + auto *data = static_cast(arg_2); + auto ret = (data->func)(manage(arg_0), manage_copy(arg_1)); + return ret.release(); +} + +void ast_build::set_at_each_domain_data(const std::function &fn) +{ + at_each_domain_data = std::make_shared(); + at_each_domain_data->func = fn; + ptr = isl_ast_build_set_at_each_domain(ptr, &at_each_domain, at_each_domain_data.get()); +} + +isl::checked::ast_build ast_build::set_at_each_domain(const std::function &fn) const +{ + auto copy = *this; + copy.set_at_each_domain_data(fn); + return copy; +} + +isl::checked::ast_expr ast_build::access_from(isl::checked::multi_pw_aff mpa) const +{ + auto res = isl_ast_build_access_from_multi_pw_aff(get(), mpa.release()); + return manage(res); +} + +isl::checked::ast_expr ast_build::access_from(isl::checked::pw_multi_aff pma) const +{ + auto res = isl_ast_build_access_from_pw_multi_aff(get(), pma.release()); + return manage(res); +} + +isl::checked::ast_expr ast_build::call_from(isl::checked::multi_pw_aff mpa) const +{ + auto res = isl_ast_build_call_from_multi_pw_aff(get(), mpa.release()); + return manage(res); +} + +isl::checked::ast_expr ast_build::call_from(isl::checked::pw_multi_aff pma) const +{ + auto res = isl_ast_build_call_from_pw_multi_aff(get(), pma.release()); + return manage(res); +} + +isl::checked::ast_expr ast_build::expr_from(isl::checked::pw_aff pa) const +{ + auto res = isl_ast_build_expr_from_pw_aff(get(), pa.release()); + return manage(res); +} + +isl::checked::ast_expr ast_build::expr_from(isl::checked::set set) const +{ + auto res = isl_ast_build_expr_from_set(get(), set.release()); + return manage(res); +} + +isl::checked::ast_build ast_build::from_context(isl::checked::set set) +{ + auto res = isl_ast_build_from_context(set.release()); + return manage(res); +} + +isl::checked::ast_node ast_build::node_from(isl::checked::schedule schedule) const +{ + auto res = isl_ast_build_node_from_schedule(get(), schedule.release()); + return manage(res); +} + +isl::checked::ast_node ast_build::node_from_schedule_map(isl::checked::union_map schedule) const +{ + auto res = isl_ast_build_node_from_schedule_map(get(), schedule.release()); + return manage(res); +} + +isl::checked::union_map ast_build::schedule() const +{ + auto res = isl_ast_build_get_schedule(get()); + return manage(res); +} + +isl::checked::union_map ast_build::get_schedule() const +{ + return schedule(); +} + +// implementations for isl::ast_expr +ast_expr manage(__isl_take isl_ast_expr *ptr) { + return ast_expr(ptr); +} +ast_expr manage_copy(__isl_keep isl_ast_expr *ptr) { + ptr = isl_ast_expr_copy(ptr); + return ast_expr(ptr); +} + +ast_expr::ast_expr(__isl_take isl_ast_expr *ptr) + : ptr(ptr) {} + +ast_expr::ast_expr() + : ptr(nullptr) {} + +ast_expr::ast_expr(const ast_expr &obj) + : ptr(nullptr) +{ + ptr = obj.copy(); +} + +ast_expr &ast_expr::operator=(ast_expr obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +ast_expr::~ast_expr() { + if (ptr) + isl_ast_expr_free(ptr); +} + +__isl_give isl_ast_expr *ast_expr::copy() const & { + return isl_ast_expr_copy(ptr); +} + +__isl_keep isl_ast_expr *ast_expr::get() const { + return ptr; +} + +__isl_give isl_ast_expr *ast_expr::release() { + isl_ast_expr *tmp = ptr; + ptr = nullptr; + return tmp; +} + +bool ast_expr::is_null() const { + return ptr == nullptr; +} + +template +boolean ast_expr::isa_type(T subtype) const +{ + if (is_null()) + return boolean(); + return isl_ast_expr_get_type(get()) == subtype; +} +template +boolean ast_expr::isa() const +{ + return isa_type(T::type); +} +template +T ast_expr::as() const +{ + if (isa().is_false()) + isl_die(ctx().get(), isl_error_invalid, "not an object of the requested subtype", return T()); + return T(copy()); +} + +isl::checked::ctx ast_expr::ctx() const { + return isl::checked::ctx(isl_ast_expr_get_ctx(ptr)); +} + +std::string ast_expr::to_C_str() const +{ + auto res = isl_ast_expr_to_C_str(get()); + std::string tmp(res); + free(res); + return tmp; +} + +inline std::ostream &operator<<(std::ostream &os, const ast_expr &obj) +{ + char *str = isl_ast_expr_to_str(obj.get()); + if (!str) { + os.setstate(std::ios_base::badbit); + return os; + } + os << str; + free(str); + return os; +} + +// implementations for isl::ast_expr_id +ast_expr_id::ast_expr_id(__isl_take isl_ast_expr *ptr) + : ast_expr(ptr) {} + +ast_expr_id::ast_expr_id() + : ast_expr() {} + +ast_expr_id::ast_expr_id(const ast_expr_id &obj) + : ast_expr(obj) +{ +} + +ast_expr_id &ast_expr_id::operator=(ast_expr_id obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +isl::checked::ctx ast_expr_id::ctx() const { + return isl::checked::ctx(isl_ast_expr_get_ctx(ptr)); +} + +isl::checked::id ast_expr_id::id() const +{ + auto res = isl_ast_expr_id_get_id(get()); + return manage(res); +} + +isl::checked::id ast_expr_id::get_id() const +{ + return id(); +} + +inline std::ostream &operator<<(std::ostream &os, const ast_expr_id &obj) +{ + char *str = isl_ast_expr_to_str(obj.get()); + if (!str) { + os.setstate(std::ios_base::badbit); + return os; + } + os << str; + free(str); + return os; +} + +// implementations for isl::ast_expr_int +ast_expr_int::ast_expr_int(__isl_take isl_ast_expr *ptr) + : ast_expr(ptr) {} + +ast_expr_int::ast_expr_int() + : ast_expr() {} + +ast_expr_int::ast_expr_int(const ast_expr_int &obj) + : ast_expr(obj) +{ +} + +ast_expr_int &ast_expr_int::operator=(ast_expr_int obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +isl::checked::ctx ast_expr_int::ctx() const { + return isl::checked::ctx(isl_ast_expr_get_ctx(ptr)); +} + +isl::checked::val ast_expr_int::val() const +{ + auto res = isl_ast_expr_int_get_val(get()); + return manage(res); +} + +isl::checked::val ast_expr_int::get_val() const +{ + return val(); +} + +inline std::ostream &operator<<(std::ostream &os, const ast_expr_int &obj) +{ + char *str = isl_ast_expr_to_str(obj.get()); + if (!str) { + os.setstate(std::ios_base::badbit); + return os; + } + os << str; + free(str); + return os; +} + +// implementations for isl::ast_expr_op +ast_expr_op::ast_expr_op(__isl_take isl_ast_expr *ptr) + : ast_expr(ptr) {} + +ast_expr_op::ast_expr_op() + : ast_expr() {} + +ast_expr_op::ast_expr_op(const ast_expr_op &obj) + : ast_expr(obj) +{ +} + +ast_expr_op &ast_expr_op::operator=(ast_expr_op obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +template +boolean ast_expr_op::isa_type(T subtype) const +{ + if (is_null()) + return boolean(); + return isl_ast_expr_op_get_type(get()) == subtype; +} +template +boolean ast_expr_op::isa() const +{ + return isa_type(T::type); +} +template +T ast_expr_op::as() const +{ + if (isa().is_false()) + isl_die(ctx().get(), isl_error_invalid, "not an object of the requested subtype", return T()); + return T(copy()); +} + +isl::checked::ctx ast_expr_op::ctx() const { + return isl::checked::ctx(isl_ast_expr_get_ctx(ptr)); +} + +isl::checked::ast_expr ast_expr_op::arg(int pos) const +{ + auto res = isl_ast_expr_op_get_arg(get(), pos); + return manage(res); +} + +isl::checked::ast_expr ast_expr_op::get_arg(int pos) const +{ + return arg(pos); +} + +class size ast_expr_op::n_arg() const +{ + auto res = isl_ast_expr_op_get_n_arg(get()); + return manage(res); +} + +class size ast_expr_op::get_n_arg() const +{ + return n_arg(); +} + +inline std::ostream &operator<<(std::ostream &os, const ast_expr_op &obj) +{ + char *str = isl_ast_expr_to_str(obj.get()); + if (!str) { + os.setstate(std::ios_base::badbit); + return os; + } + os << str; + free(str); + return os; +} + +// implementations for isl::ast_expr_op_access +ast_expr_op_access::ast_expr_op_access(__isl_take isl_ast_expr *ptr) + : ast_expr_op(ptr) {} + +ast_expr_op_access::ast_expr_op_access() + : ast_expr_op() {} + +ast_expr_op_access::ast_expr_op_access(const ast_expr_op_access &obj) + : ast_expr_op(obj) +{ +} + +ast_expr_op_access &ast_expr_op_access::operator=(ast_expr_op_access obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +isl::checked::ctx ast_expr_op_access::ctx() const { + return isl::checked::ctx(isl_ast_expr_get_ctx(ptr)); +} + +inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_access &obj) +{ + char *str = isl_ast_expr_to_str(obj.get()); + if (!str) { + os.setstate(std::ios_base::badbit); + return os; + } + os << str; + free(str); + return os; +} + +// implementations for isl::ast_expr_op_add +ast_expr_op_add::ast_expr_op_add(__isl_take isl_ast_expr *ptr) + : ast_expr_op(ptr) {} + +ast_expr_op_add::ast_expr_op_add() + : ast_expr_op() {} + +ast_expr_op_add::ast_expr_op_add(const ast_expr_op_add &obj) + : ast_expr_op(obj) +{ +} + +ast_expr_op_add &ast_expr_op_add::operator=(ast_expr_op_add obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +isl::checked::ctx ast_expr_op_add::ctx() const { + return isl::checked::ctx(isl_ast_expr_get_ctx(ptr)); +} + +inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_add &obj) +{ + char *str = isl_ast_expr_to_str(obj.get()); + if (!str) { + os.setstate(std::ios_base::badbit); + return os; + } + os << str; + free(str); + return os; +} + +// implementations for isl::ast_expr_op_address_of +ast_expr_op_address_of::ast_expr_op_address_of(__isl_take isl_ast_expr *ptr) + : ast_expr_op(ptr) {} + +ast_expr_op_address_of::ast_expr_op_address_of() + : ast_expr_op() {} + +ast_expr_op_address_of::ast_expr_op_address_of(const ast_expr_op_address_of &obj) + : ast_expr_op(obj) +{ +} + +ast_expr_op_address_of &ast_expr_op_address_of::operator=(ast_expr_op_address_of obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +isl::checked::ctx ast_expr_op_address_of::ctx() const { + return isl::checked::ctx(isl_ast_expr_get_ctx(ptr)); +} + +inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_address_of &obj) +{ + char *str = isl_ast_expr_to_str(obj.get()); + if (!str) { + os.setstate(std::ios_base::badbit); + return os; + } + os << str; + free(str); + return os; +} + +// implementations for isl::ast_expr_op_and +ast_expr_op_and::ast_expr_op_and(__isl_take isl_ast_expr *ptr) + : ast_expr_op(ptr) {} + +ast_expr_op_and::ast_expr_op_and() + : ast_expr_op() {} + +ast_expr_op_and::ast_expr_op_and(const ast_expr_op_and &obj) + : ast_expr_op(obj) +{ +} + +ast_expr_op_and &ast_expr_op_and::operator=(ast_expr_op_and obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +isl::checked::ctx ast_expr_op_and::ctx() const { + return isl::checked::ctx(isl_ast_expr_get_ctx(ptr)); +} + +inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_and &obj) +{ + char *str = isl_ast_expr_to_str(obj.get()); + if (!str) { + os.setstate(std::ios_base::badbit); + return os; + } + os << str; + free(str); + return os; +} + +// implementations for isl::ast_expr_op_and_then +ast_expr_op_and_then::ast_expr_op_and_then(__isl_take isl_ast_expr *ptr) + : ast_expr_op(ptr) {} + +ast_expr_op_and_then::ast_expr_op_and_then() + : ast_expr_op() {} + +ast_expr_op_and_then::ast_expr_op_and_then(const ast_expr_op_and_then &obj) + : ast_expr_op(obj) +{ +} + +ast_expr_op_and_then &ast_expr_op_and_then::operator=(ast_expr_op_and_then obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +isl::checked::ctx ast_expr_op_and_then::ctx() const { + return isl::checked::ctx(isl_ast_expr_get_ctx(ptr)); +} + +inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_and_then &obj) +{ + char *str = isl_ast_expr_to_str(obj.get()); + if (!str) { + os.setstate(std::ios_base::badbit); + return os; + } + os << str; + free(str); + return os; +} + +// implementations for isl::ast_expr_op_call +ast_expr_op_call::ast_expr_op_call(__isl_take isl_ast_expr *ptr) + : ast_expr_op(ptr) {} + +ast_expr_op_call::ast_expr_op_call() + : ast_expr_op() {} + +ast_expr_op_call::ast_expr_op_call(const ast_expr_op_call &obj) + : ast_expr_op(obj) +{ +} + +ast_expr_op_call &ast_expr_op_call::operator=(ast_expr_op_call obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +isl::checked::ctx ast_expr_op_call::ctx() const { + return isl::checked::ctx(isl_ast_expr_get_ctx(ptr)); +} + +inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_call &obj) +{ + char *str = isl_ast_expr_to_str(obj.get()); + if (!str) { + os.setstate(std::ios_base::badbit); + return os; + } + os << str; + free(str); + return os; +} + +// implementations for isl::ast_expr_op_cond +ast_expr_op_cond::ast_expr_op_cond(__isl_take isl_ast_expr *ptr) + : ast_expr_op(ptr) {} + +ast_expr_op_cond::ast_expr_op_cond() + : ast_expr_op() {} + +ast_expr_op_cond::ast_expr_op_cond(const ast_expr_op_cond &obj) + : ast_expr_op(obj) +{ +} + +ast_expr_op_cond &ast_expr_op_cond::operator=(ast_expr_op_cond obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +isl::checked::ctx ast_expr_op_cond::ctx() const { + return isl::checked::ctx(isl_ast_expr_get_ctx(ptr)); +} + +inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_cond &obj) +{ + char *str = isl_ast_expr_to_str(obj.get()); + if (!str) { + os.setstate(std::ios_base::badbit); + return os; + } + os << str; + free(str); + return os; +} + +// implementations for isl::ast_expr_op_div +ast_expr_op_div::ast_expr_op_div(__isl_take isl_ast_expr *ptr) + : ast_expr_op(ptr) {} + +ast_expr_op_div::ast_expr_op_div() + : ast_expr_op() {} + +ast_expr_op_div::ast_expr_op_div(const ast_expr_op_div &obj) + : ast_expr_op(obj) +{ +} + +ast_expr_op_div &ast_expr_op_div::operator=(ast_expr_op_div obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +isl::checked::ctx ast_expr_op_div::ctx() const { + return isl::checked::ctx(isl_ast_expr_get_ctx(ptr)); +} + +inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_div &obj) +{ + char *str = isl_ast_expr_to_str(obj.get()); + if (!str) { + os.setstate(std::ios_base::badbit); + return os; + } + os << str; + free(str); + return os; +} + +// implementations for isl::ast_expr_op_eq +ast_expr_op_eq::ast_expr_op_eq(__isl_take isl_ast_expr *ptr) + : ast_expr_op(ptr) {} + +ast_expr_op_eq::ast_expr_op_eq() + : ast_expr_op() {} + +ast_expr_op_eq::ast_expr_op_eq(const ast_expr_op_eq &obj) + : ast_expr_op(obj) +{ +} + +ast_expr_op_eq &ast_expr_op_eq::operator=(ast_expr_op_eq obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +isl::checked::ctx ast_expr_op_eq::ctx() const { + return isl::checked::ctx(isl_ast_expr_get_ctx(ptr)); +} + +inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_eq &obj) +{ + char *str = isl_ast_expr_to_str(obj.get()); + if (!str) { + os.setstate(std::ios_base::badbit); + return os; + } + os << str; + free(str); + return os; +} + +// implementations for isl::ast_expr_op_fdiv_q +ast_expr_op_fdiv_q::ast_expr_op_fdiv_q(__isl_take isl_ast_expr *ptr) + : ast_expr_op(ptr) {} + +ast_expr_op_fdiv_q::ast_expr_op_fdiv_q() + : ast_expr_op() {} + +ast_expr_op_fdiv_q::ast_expr_op_fdiv_q(const ast_expr_op_fdiv_q &obj) + : ast_expr_op(obj) +{ +} + +ast_expr_op_fdiv_q &ast_expr_op_fdiv_q::operator=(ast_expr_op_fdiv_q obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +isl::checked::ctx ast_expr_op_fdiv_q::ctx() const { + return isl::checked::ctx(isl_ast_expr_get_ctx(ptr)); +} + +inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_fdiv_q &obj) +{ + char *str = isl_ast_expr_to_str(obj.get()); + if (!str) { + os.setstate(std::ios_base::badbit); + return os; + } + os << str; + free(str); + return os; +} + +// implementations for isl::ast_expr_op_ge +ast_expr_op_ge::ast_expr_op_ge(__isl_take isl_ast_expr *ptr) + : ast_expr_op(ptr) {} + +ast_expr_op_ge::ast_expr_op_ge() + : ast_expr_op() {} + +ast_expr_op_ge::ast_expr_op_ge(const ast_expr_op_ge &obj) + : ast_expr_op(obj) +{ +} + +ast_expr_op_ge &ast_expr_op_ge::operator=(ast_expr_op_ge obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +isl::checked::ctx ast_expr_op_ge::ctx() const { + return isl::checked::ctx(isl_ast_expr_get_ctx(ptr)); +} + +inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_ge &obj) +{ + char *str = isl_ast_expr_to_str(obj.get()); + if (!str) { + os.setstate(std::ios_base::badbit); + return os; + } + os << str; + free(str); + return os; +} + +// implementations for isl::ast_expr_op_gt +ast_expr_op_gt::ast_expr_op_gt(__isl_take isl_ast_expr *ptr) + : ast_expr_op(ptr) {} + +ast_expr_op_gt::ast_expr_op_gt() + : ast_expr_op() {} + +ast_expr_op_gt::ast_expr_op_gt(const ast_expr_op_gt &obj) + : ast_expr_op(obj) +{ +} + +ast_expr_op_gt &ast_expr_op_gt::operator=(ast_expr_op_gt obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +isl::checked::ctx ast_expr_op_gt::ctx() const { + return isl::checked::ctx(isl_ast_expr_get_ctx(ptr)); +} + +inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_gt &obj) +{ + char *str = isl_ast_expr_to_str(obj.get()); + if (!str) { + os.setstate(std::ios_base::badbit); + return os; + } + os << str; + free(str); + return os; +} + +// implementations for isl::ast_expr_op_le +ast_expr_op_le::ast_expr_op_le(__isl_take isl_ast_expr *ptr) + : ast_expr_op(ptr) {} + +ast_expr_op_le::ast_expr_op_le() + : ast_expr_op() {} + +ast_expr_op_le::ast_expr_op_le(const ast_expr_op_le &obj) + : ast_expr_op(obj) +{ +} + +ast_expr_op_le &ast_expr_op_le::operator=(ast_expr_op_le obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +isl::checked::ctx ast_expr_op_le::ctx() const { + return isl::checked::ctx(isl_ast_expr_get_ctx(ptr)); +} + +inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_le &obj) +{ + char *str = isl_ast_expr_to_str(obj.get()); + if (!str) { + os.setstate(std::ios_base::badbit); + return os; + } + os << str; + free(str); + return os; +} + +// implementations for isl::ast_expr_op_lt +ast_expr_op_lt::ast_expr_op_lt(__isl_take isl_ast_expr *ptr) + : ast_expr_op(ptr) {} + +ast_expr_op_lt::ast_expr_op_lt() + : ast_expr_op() {} + +ast_expr_op_lt::ast_expr_op_lt(const ast_expr_op_lt &obj) + : ast_expr_op(obj) +{ +} + +ast_expr_op_lt &ast_expr_op_lt::operator=(ast_expr_op_lt obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +isl::checked::ctx ast_expr_op_lt::ctx() const { + return isl::checked::ctx(isl_ast_expr_get_ctx(ptr)); +} + +inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_lt &obj) +{ + char *str = isl_ast_expr_to_str(obj.get()); + if (!str) { + os.setstate(std::ios_base::badbit); + return os; + } + os << str; + free(str); + return os; +} + +// implementations for isl::ast_expr_op_max +ast_expr_op_max::ast_expr_op_max(__isl_take isl_ast_expr *ptr) + : ast_expr_op(ptr) {} + +ast_expr_op_max::ast_expr_op_max() + : ast_expr_op() {} + +ast_expr_op_max::ast_expr_op_max(const ast_expr_op_max &obj) + : ast_expr_op(obj) +{ +} + +ast_expr_op_max &ast_expr_op_max::operator=(ast_expr_op_max obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +isl::checked::ctx ast_expr_op_max::ctx() const { + return isl::checked::ctx(isl_ast_expr_get_ctx(ptr)); +} + +inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_max &obj) +{ + char *str = isl_ast_expr_to_str(obj.get()); + if (!str) { + os.setstate(std::ios_base::badbit); + return os; + } + os << str; + free(str); + return os; +} + +// implementations for isl::ast_expr_op_member +ast_expr_op_member::ast_expr_op_member(__isl_take isl_ast_expr *ptr) + : ast_expr_op(ptr) {} + +ast_expr_op_member::ast_expr_op_member() + : ast_expr_op() {} + +ast_expr_op_member::ast_expr_op_member(const ast_expr_op_member &obj) + : ast_expr_op(obj) +{ +} + +ast_expr_op_member &ast_expr_op_member::operator=(ast_expr_op_member obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +isl::checked::ctx ast_expr_op_member::ctx() const { + return isl::checked::ctx(isl_ast_expr_get_ctx(ptr)); +} + +inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_member &obj) +{ + char *str = isl_ast_expr_to_str(obj.get()); + if (!str) { + os.setstate(std::ios_base::badbit); + return os; + } + os << str; + free(str); + return os; +} + +// implementations for isl::ast_expr_op_min +ast_expr_op_min::ast_expr_op_min(__isl_take isl_ast_expr *ptr) + : ast_expr_op(ptr) {} + +ast_expr_op_min::ast_expr_op_min() + : ast_expr_op() {} + +ast_expr_op_min::ast_expr_op_min(const ast_expr_op_min &obj) + : ast_expr_op(obj) +{ +} + +ast_expr_op_min &ast_expr_op_min::operator=(ast_expr_op_min obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +isl::checked::ctx ast_expr_op_min::ctx() const { + return isl::checked::ctx(isl_ast_expr_get_ctx(ptr)); +} + +inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_min &obj) +{ + char *str = isl_ast_expr_to_str(obj.get()); + if (!str) { + os.setstate(std::ios_base::badbit); + return os; + } + os << str; + free(str); + return os; +} + +// implementations for isl::ast_expr_op_minus +ast_expr_op_minus::ast_expr_op_minus(__isl_take isl_ast_expr *ptr) + : ast_expr_op(ptr) {} + +ast_expr_op_minus::ast_expr_op_minus() + : ast_expr_op() {} + +ast_expr_op_minus::ast_expr_op_minus(const ast_expr_op_minus &obj) + : ast_expr_op(obj) +{ +} + +ast_expr_op_minus &ast_expr_op_minus::operator=(ast_expr_op_minus obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +isl::checked::ctx ast_expr_op_minus::ctx() const { + return isl::checked::ctx(isl_ast_expr_get_ctx(ptr)); +} + +inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_minus &obj) +{ + char *str = isl_ast_expr_to_str(obj.get()); + if (!str) { + os.setstate(std::ios_base::badbit); + return os; + } + os << str; + free(str); + return os; +} + +// implementations for isl::ast_expr_op_mul +ast_expr_op_mul::ast_expr_op_mul(__isl_take isl_ast_expr *ptr) + : ast_expr_op(ptr) {} + +ast_expr_op_mul::ast_expr_op_mul() + : ast_expr_op() {} + +ast_expr_op_mul::ast_expr_op_mul(const ast_expr_op_mul &obj) + : ast_expr_op(obj) +{ +} + +ast_expr_op_mul &ast_expr_op_mul::operator=(ast_expr_op_mul obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +isl::checked::ctx ast_expr_op_mul::ctx() const { + return isl::checked::ctx(isl_ast_expr_get_ctx(ptr)); +} + +inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_mul &obj) +{ + char *str = isl_ast_expr_to_str(obj.get()); + if (!str) { + os.setstate(std::ios_base::badbit); + return os; + } + os << str; + free(str); + return os; +} + +// implementations for isl::ast_expr_op_or +ast_expr_op_or::ast_expr_op_or(__isl_take isl_ast_expr *ptr) + : ast_expr_op(ptr) {} + +ast_expr_op_or::ast_expr_op_or() + : ast_expr_op() {} + +ast_expr_op_or::ast_expr_op_or(const ast_expr_op_or &obj) + : ast_expr_op(obj) +{ +} + +ast_expr_op_or &ast_expr_op_or::operator=(ast_expr_op_or obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +isl::checked::ctx ast_expr_op_or::ctx() const { + return isl::checked::ctx(isl_ast_expr_get_ctx(ptr)); +} + +inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_or &obj) +{ + char *str = isl_ast_expr_to_str(obj.get()); + if (!str) { + os.setstate(std::ios_base::badbit); + return os; + } + os << str; + free(str); + return os; +} + +// implementations for isl::ast_expr_op_or_else +ast_expr_op_or_else::ast_expr_op_or_else(__isl_take isl_ast_expr *ptr) + : ast_expr_op(ptr) {} + +ast_expr_op_or_else::ast_expr_op_or_else() + : ast_expr_op() {} + +ast_expr_op_or_else::ast_expr_op_or_else(const ast_expr_op_or_else &obj) + : ast_expr_op(obj) +{ +} + +ast_expr_op_or_else &ast_expr_op_or_else::operator=(ast_expr_op_or_else obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +isl::checked::ctx ast_expr_op_or_else::ctx() const { + return isl::checked::ctx(isl_ast_expr_get_ctx(ptr)); +} + +inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_or_else &obj) +{ + char *str = isl_ast_expr_to_str(obj.get()); + if (!str) { + os.setstate(std::ios_base::badbit); + return os; + } + os << str; + free(str); + return os; +} + +// implementations for isl::ast_expr_op_pdiv_q +ast_expr_op_pdiv_q::ast_expr_op_pdiv_q(__isl_take isl_ast_expr *ptr) + : ast_expr_op(ptr) {} + +ast_expr_op_pdiv_q::ast_expr_op_pdiv_q() + : ast_expr_op() {} + +ast_expr_op_pdiv_q::ast_expr_op_pdiv_q(const ast_expr_op_pdiv_q &obj) + : ast_expr_op(obj) +{ +} + +ast_expr_op_pdiv_q &ast_expr_op_pdiv_q::operator=(ast_expr_op_pdiv_q obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +isl::checked::ctx ast_expr_op_pdiv_q::ctx() const { + return isl::checked::ctx(isl_ast_expr_get_ctx(ptr)); +} + +inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_pdiv_q &obj) +{ + char *str = isl_ast_expr_to_str(obj.get()); + if (!str) { + os.setstate(std::ios_base::badbit); + return os; + } + os << str; + free(str); + return os; +} + +// implementations for isl::ast_expr_op_pdiv_r +ast_expr_op_pdiv_r::ast_expr_op_pdiv_r(__isl_take isl_ast_expr *ptr) + : ast_expr_op(ptr) {} + +ast_expr_op_pdiv_r::ast_expr_op_pdiv_r() + : ast_expr_op() {} + +ast_expr_op_pdiv_r::ast_expr_op_pdiv_r(const ast_expr_op_pdiv_r &obj) + : ast_expr_op(obj) +{ +} + +ast_expr_op_pdiv_r &ast_expr_op_pdiv_r::operator=(ast_expr_op_pdiv_r obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +isl::checked::ctx ast_expr_op_pdiv_r::ctx() const { + return isl::checked::ctx(isl_ast_expr_get_ctx(ptr)); +} + +inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_pdiv_r &obj) +{ + char *str = isl_ast_expr_to_str(obj.get()); + if (!str) { + os.setstate(std::ios_base::badbit); + return os; + } + os << str; + free(str); + return os; +} + +// implementations for isl::ast_expr_op_select +ast_expr_op_select::ast_expr_op_select(__isl_take isl_ast_expr *ptr) + : ast_expr_op(ptr) {} + +ast_expr_op_select::ast_expr_op_select() + : ast_expr_op() {} + +ast_expr_op_select::ast_expr_op_select(const ast_expr_op_select &obj) + : ast_expr_op(obj) +{ +} + +ast_expr_op_select &ast_expr_op_select::operator=(ast_expr_op_select obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +isl::checked::ctx ast_expr_op_select::ctx() const { + return isl::checked::ctx(isl_ast_expr_get_ctx(ptr)); +} + +inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_select &obj) +{ + char *str = isl_ast_expr_to_str(obj.get()); + if (!str) { + os.setstate(std::ios_base::badbit); + return os; + } + os << str; + free(str); + return os; +} + +// implementations for isl::ast_expr_op_sub +ast_expr_op_sub::ast_expr_op_sub(__isl_take isl_ast_expr *ptr) + : ast_expr_op(ptr) {} + +ast_expr_op_sub::ast_expr_op_sub() + : ast_expr_op() {} + +ast_expr_op_sub::ast_expr_op_sub(const ast_expr_op_sub &obj) + : ast_expr_op(obj) +{ +} + +ast_expr_op_sub &ast_expr_op_sub::operator=(ast_expr_op_sub obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +isl::checked::ctx ast_expr_op_sub::ctx() const { + return isl::checked::ctx(isl_ast_expr_get_ctx(ptr)); +} + +inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_sub &obj) +{ + char *str = isl_ast_expr_to_str(obj.get()); + if (!str) { + os.setstate(std::ios_base::badbit); + return os; + } + os << str; + free(str); + return os; +} + +// implementations for isl::ast_expr_op_zdiv_r +ast_expr_op_zdiv_r::ast_expr_op_zdiv_r(__isl_take isl_ast_expr *ptr) + : ast_expr_op(ptr) {} + +ast_expr_op_zdiv_r::ast_expr_op_zdiv_r() + : ast_expr_op() {} + +ast_expr_op_zdiv_r::ast_expr_op_zdiv_r(const ast_expr_op_zdiv_r &obj) + : ast_expr_op(obj) +{ +} + +ast_expr_op_zdiv_r &ast_expr_op_zdiv_r::operator=(ast_expr_op_zdiv_r obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +isl::checked::ctx ast_expr_op_zdiv_r::ctx() const { + return isl::checked::ctx(isl_ast_expr_get_ctx(ptr)); +} + +inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_zdiv_r &obj) +{ + char *str = isl_ast_expr_to_str(obj.get()); + if (!str) { + os.setstate(std::ios_base::badbit); + return os; + } + os << str; + free(str); + return os; +} + +// implementations for isl::ast_node +ast_node manage(__isl_take isl_ast_node *ptr) { + return ast_node(ptr); +} +ast_node manage_copy(__isl_keep isl_ast_node *ptr) { + ptr = isl_ast_node_copy(ptr); + return ast_node(ptr); +} + +ast_node::ast_node(__isl_take isl_ast_node *ptr) + : ptr(ptr) {} + +ast_node::ast_node() + : ptr(nullptr) {} + +ast_node::ast_node(const ast_node &obj) + : ptr(nullptr) +{ + ptr = obj.copy(); +} + +ast_node &ast_node::operator=(ast_node obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +ast_node::~ast_node() { + if (ptr) + isl_ast_node_free(ptr); +} + +__isl_give isl_ast_node *ast_node::copy() const & { + return isl_ast_node_copy(ptr); +} + +__isl_keep isl_ast_node *ast_node::get() const { + return ptr; +} + +__isl_give isl_ast_node *ast_node::release() { + isl_ast_node *tmp = ptr; + ptr = nullptr; + return tmp; +} + +bool ast_node::is_null() const { + return ptr == nullptr; +} + +template +boolean ast_node::isa_type(T subtype) const +{ + if (is_null()) + return boolean(); + return isl_ast_node_get_type(get()) == subtype; +} +template +boolean ast_node::isa() const +{ + return isa_type(T::type); +} +template +T ast_node::as() const +{ + if (isa().is_false()) + isl_die(ctx().get(), isl_error_invalid, "not an object of the requested subtype", return T()); + return T(copy()); +} + +isl::checked::ctx ast_node::ctx() const { + return isl::checked::ctx(isl_ast_node_get_ctx(ptr)); +} + +isl::checked::ast_node ast_node::map_descendant_bottom_up(const std::function &fn) const +{ + struct fn_data { + std::function func; + } fn_data = { fn }; + auto fn_lambda = [](isl_ast_node *arg_0, void *arg_1) -> isl_ast_node * { + auto *data = static_cast(arg_1); + auto ret = (data->func)(manage(arg_0)); + return ret.release(); + }; + auto res = isl_ast_node_map_descendant_bottom_up(copy(), fn_lambda, &fn_data); + return manage(res); +} + +std::string ast_node::to_C_str() const +{ + auto res = isl_ast_node_to_C_str(get()); + std::string tmp(res); + free(res); + return tmp; +} + +isl::checked::ast_node_list ast_node::to_list() const +{ + auto res = isl_ast_node_to_list(copy()); + return manage(res); +} + +inline std::ostream &operator<<(std::ostream &os, const ast_node &obj) +{ + char *str = isl_ast_node_to_str(obj.get()); + if (!str) { + os.setstate(std::ios_base::badbit); + return os; + } + os << str; + free(str); + return os; +} + +// implementations for isl::ast_node_block +ast_node_block::ast_node_block(__isl_take isl_ast_node *ptr) + : ast_node(ptr) {} + +ast_node_block::ast_node_block() + : ast_node() {} + +ast_node_block::ast_node_block(const ast_node_block &obj) + : ast_node(obj) +{ +} + +ast_node_block::ast_node_block(isl::checked::ast_node_list list) +{ + auto res = isl_ast_node_block_from_children(list.release()); + ptr = res; +} + +ast_node_block &ast_node_block::operator=(ast_node_block obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +isl::checked::ctx ast_node_block::ctx() const { + return isl::checked::ctx(isl_ast_node_get_ctx(ptr)); +} + +isl::checked::ast_node_list ast_node_block::children() const +{ + auto res = isl_ast_node_block_get_children(get()); + return manage(res); +} + +isl::checked::ast_node_list ast_node_block::get_children() const +{ + return children(); +} + +inline std::ostream &operator<<(std::ostream &os, const ast_node_block &obj) +{ + char *str = isl_ast_node_to_str(obj.get()); + if (!str) { + os.setstate(std::ios_base::badbit); + return os; + } + os << str; + free(str); + return os; +} + +// implementations for isl::ast_node_for +ast_node_for::ast_node_for(__isl_take isl_ast_node *ptr) + : ast_node(ptr) {} + +ast_node_for::ast_node_for() + : ast_node() {} + +ast_node_for::ast_node_for(const ast_node_for &obj) + : ast_node(obj) +{ +} + +ast_node_for &ast_node_for::operator=(ast_node_for obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +isl::checked::ctx ast_node_for::ctx() const { + return isl::checked::ctx(isl_ast_node_get_ctx(ptr)); +} + +isl::checked::ast_node ast_node_for::body() const +{ + auto res = isl_ast_node_for_get_body(get()); + return manage(res); +} + +isl::checked::ast_node ast_node_for::get_body() const +{ + return body(); +} + +isl::checked::ast_expr ast_node_for::cond() const +{ + auto res = isl_ast_node_for_get_cond(get()); + return manage(res); +} + +isl::checked::ast_expr ast_node_for::get_cond() const +{ + return cond(); +} + +isl::checked::ast_expr ast_node_for::inc() const +{ + auto res = isl_ast_node_for_get_inc(get()); + return manage(res); +} + +isl::checked::ast_expr ast_node_for::get_inc() const +{ + return inc(); +} + +isl::checked::ast_expr ast_node_for::init() const +{ + auto res = isl_ast_node_for_get_init(get()); + return manage(res); +} + +isl::checked::ast_expr ast_node_for::get_init() const +{ + return init(); +} + +boolean ast_node_for::is_degenerate() const +{ + auto res = isl_ast_node_for_is_degenerate(get()); + return manage(res); +} + +isl::checked::ast_expr ast_node_for::iterator() const +{ + auto res = isl_ast_node_for_get_iterator(get()); + return manage(res); +} + +isl::checked::ast_expr ast_node_for::get_iterator() const +{ + return iterator(); +} + +inline std::ostream &operator<<(std::ostream &os, const ast_node_for &obj) +{ + char *str = isl_ast_node_to_str(obj.get()); + if (!str) { + os.setstate(std::ios_base::badbit); + return os; + } + os << str; + free(str); + return os; +} + +// implementations for isl::ast_node_if +ast_node_if::ast_node_if(__isl_take isl_ast_node *ptr) + : ast_node(ptr) {} + +ast_node_if::ast_node_if() + : ast_node() {} + +ast_node_if::ast_node_if(const ast_node_if &obj) + : ast_node(obj) +{ +} + +ast_node_if &ast_node_if::operator=(ast_node_if obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +isl::checked::ctx ast_node_if::ctx() const { + return isl::checked::ctx(isl_ast_node_get_ctx(ptr)); +} + +isl::checked::ast_expr ast_node_if::cond() const +{ + auto res = isl_ast_node_if_get_cond(get()); + return manage(res); +} + +isl::checked::ast_expr ast_node_if::get_cond() const +{ + return cond(); +} + +isl::checked::ast_node ast_node_if::else_node() const +{ + auto res = isl_ast_node_if_get_else_node(get()); + return manage(res); +} + +isl::checked::ast_node ast_node_if::get_else_node() const +{ + return else_node(); +} + +boolean ast_node_if::has_else_node() const +{ + auto res = isl_ast_node_if_has_else_node(get()); + return manage(res); +} + +isl::checked::ast_node ast_node_if::then_node() const +{ + auto res = isl_ast_node_if_get_then_node(get()); + return manage(res); +} + +isl::checked::ast_node ast_node_if::get_then_node() const +{ + return then_node(); +} + +inline std::ostream &operator<<(std::ostream &os, const ast_node_if &obj) +{ + char *str = isl_ast_node_to_str(obj.get()); + if (!str) { + os.setstate(std::ios_base::badbit); + return os; + } + os << str; + free(str); + return os; +} + +// implementations for isl::ast_node_list +ast_node_list manage(__isl_take isl_ast_node_list *ptr) { + return ast_node_list(ptr); +} +ast_node_list manage_copy(__isl_keep isl_ast_node_list *ptr) { + ptr = isl_ast_node_list_copy(ptr); + return ast_node_list(ptr); +} + +ast_node_list::ast_node_list(__isl_take isl_ast_node_list *ptr) + : ptr(ptr) {} + +ast_node_list::ast_node_list() + : ptr(nullptr) {} + +ast_node_list::ast_node_list(const ast_node_list &obj) + : ptr(nullptr) +{ + ptr = obj.copy(); +} + +ast_node_list::ast_node_list(isl::checked::ctx ctx, int n) +{ + auto res = isl_ast_node_list_alloc(ctx.release(), n); + ptr = res; +} + +ast_node_list::ast_node_list(isl::checked::ast_node el) +{ + auto res = isl_ast_node_list_from_ast_node(el.release()); + ptr = res; +} + +ast_node_list &ast_node_list::operator=(ast_node_list obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +ast_node_list::~ast_node_list() { + if (ptr) + isl_ast_node_list_free(ptr); +} + +__isl_give isl_ast_node_list *ast_node_list::copy() const & { + return isl_ast_node_list_copy(ptr); +} + +__isl_keep isl_ast_node_list *ast_node_list::get() const { + return ptr; +} + +__isl_give isl_ast_node_list *ast_node_list::release() { + isl_ast_node_list *tmp = ptr; + ptr = nullptr; + return tmp; +} + +bool ast_node_list::is_null() const { + return ptr == nullptr; +} + +isl::checked::ctx ast_node_list::ctx() const { + return isl::checked::ctx(isl_ast_node_list_get_ctx(ptr)); +} + +isl::checked::ast_node_list ast_node_list::add(isl::checked::ast_node el) const +{ + auto res = isl_ast_node_list_add(copy(), el.release()); + return manage(res); +} + +isl::checked::ast_node ast_node_list::at(int index) const +{ + auto res = isl_ast_node_list_get_at(get(), index); + return manage(res); +} + +isl::checked::ast_node ast_node_list::get_at(int index) const +{ + return at(index); +} + +isl::checked::ast_node_list ast_node_list::clear() const +{ + auto res = isl_ast_node_list_clear(copy()); + return manage(res); +} + +isl::checked::ast_node_list ast_node_list::concat(isl::checked::ast_node_list list2) const +{ + auto res = isl_ast_node_list_concat(copy(), list2.release()); + return manage(res); +} + +isl::checked::ast_node_list ast_node_list::drop(unsigned int first, unsigned int n) const +{ + auto res = isl_ast_node_list_drop(copy(), first, n); + return manage(res); +} + +stat ast_node_list::foreach(const std::function &fn) const +{ + struct fn_data { + std::function func; + } fn_data = { fn }; + auto fn_lambda = [](isl_ast_node *arg_0, void *arg_1) -> isl_stat { + auto *data = static_cast(arg_1); + auto ret = (data->func)(manage(arg_0)); + return ret.release(); + }; + auto res = isl_ast_node_list_foreach(get(), fn_lambda, &fn_data); + return manage(res); +} + +stat ast_node_list::foreach_scc(const std::function &follows, const std::function &fn) const +{ + struct follows_data { + std::function func; + } follows_data = { follows }; + auto follows_lambda = [](isl_ast_node *arg_0, isl_ast_node *arg_1, void *arg_2) -> isl_bool { + auto *data = static_cast(arg_2); + auto ret = (data->func)(manage_copy(arg_0), manage_copy(arg_1)); + return ret.release(); + }; + struct fn_data { + std::function func; + } fn_data = { fn }; + auto fn_lambda = [](isl_ast_node_list *arg_0, void *arg_1) -> isl_stat { + auto *data = static_cast(arg_1); + auto ret = (data->func)(manage(arg_0)); + return ret.release(); + }; + auto res = isl_ast_node_list_foreach_scc(get(), follows_lambda, &follows_data, fn_lambda, &fn_data); + return manage(res); +} + +isl::checked::ast_node_list ast_node_list::insert(unsigned int pos, isl::checked::ast_node el) const +{ + auto res = isl_ast_node_list_insert(copy(), pos, el.release()); + return manage(res); +} + +isl::checked::ast_node_list ast_node_list::set_at(int index, isl::checked::ast_node el) const +{ + auto res = isl_ast_node_list_set_at(copy(), index, el.release()); + return manage(res); +} + +class size ast_node_list::size() const +{ + auto res = isl_ast_node_list_size(get()); + return manage(res); +} + +inline std::ostream &operator<<(std::ostream &os, const ast_node_list &obj) +{ + char *str = isl_ast_node_list_to_str(obj.get()); + if (!str) { + os.setstate(std::ios_base::badbit); + return os; + } + os << str; + free(str); + return os; +} + +// implementations for isl::ast_node_mark +ast_node_mark::ast_node_mark(__isl_take isl_ast_node *ptr) + : ast_node(ptr) {} + +ast_node_mark::ast_node_mark() + : ast_node() {} + +ast_node_mark::ast_node_mark(const ast_node_mark &obj) + : ast_node(obj) +{ +} + +ast_node_mark &ast_node_mark::operator=(ast_node_mark obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +isl::checked::ctx ast_node_mark::ctx() const { + return isl::checked::ctx(isl_ast_node_get_ctx(ptr)); +} + +isl::checked::id ast_node_mark::id() const +{ + auto res = isl_ast_node_mark_get_id(get()); + return manage(res); +} + +isl::checked::id ast_node_mark::get_id() const +{ + return id(); +} + +isl::checked::ast_node ast_node_mark::node() const +{ + auto res = isl_ast_node_mark_get_node(get()); + return manage(res); +} + +isl::checked::ast_node ast_node_mark::get_node() const +{ + return node(); +} + +inline std::ostream &operator<<(std::ostream &os, const ast_node_mark &obj) +{ + char *str = isl_ast_node_to_str(obj.get()); + if (!str) { + os.setstate(std::ios_base::badbit); + return os; + } + os << str; + free(str); + return os; +} + +// implementations for isl::ast_node_user +ast_node_user::ast_node_user(__isl_take isl_ast_node *ptr) + : ast_node(ptr) {} + +ast_node_user::ast_node_user() + : ast_node() {} + +ast_node_user::ast_node_user(const ast_node_user &obj) + : ast_node(obj) +{ +} + +ast_node_user::ast_node_user(isl::checked::ast_expr expr) +{ + auto res = isl_ast_node_user_from_expr(expr.release()); + ptr = res; +} + +ast_node_user &ast_node_user::operator=(ast_node_user obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +isl::checked::ctx ast_node_user::ctx() const { + return isl::checked::ctx(isl_ast_node_get_ctx(ptr)); +} + +isl::checked::ast_expr ast_node_user::expr() const +{ + auto res = isl_ast_node_user_get_expr(get()); + return manage(res); +} + +isl::checked::ast_expr ast_node_user::get_expr() const +{ + return expr(); +} + +inline std::ostream &operator<<(std::ostream &os, const ast_node_user &obj) +{ + char *str = isl_ast_node_to_str(obj.get()); + if (!str) { + os.setstate(std::ios_base::badbit); + return os; + } + os << str; + free(str); + return os; +} + +// implementations for isl::basic_map +basic_map manage(__isl_take isl_basic_map *ptr) { + return basic_map(ptr); +} +basic_map manage_copy(__isl_keep isl_basic_map *ptr) { + ptr = isl_basic_map_copy(ptr); + return basic_map(ptr); +} + +basic_map::basic_map(__isl_take isl_basic_map *ptr) + : ptr(ptr) {} + +basic_map::basic_map() + : ptr(nullptr) {} + +basic_map::basic_map(const basic_map &obj) + : ptr(nullptr) +{ + ptr = obj.copy(); +} + +basic_map::basic_map(isl::checked::ctx ctx, const std::string &str) +{ + auto res = isl_basic_map_read_from_str(ctx.release(), str.c_str()); + ptr = res; +} + +basic_map &basic_map::operator=(basic_map obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +basic_map::~basic_map() { + if (ptr) + isl_basic_map_free(ptr); +} + +__isl_give isl_basic_map *basic_map::copy() const & { + return isl_basic_map_copy(ptr); +} + +__isl_keep isl_basic_map *basic_map::get() const { + return ptr; +} + +__isl_give isl_basic_map *basic_map::release() { + isl_basic_map *tmp = ptr; + ptr = nullptr; + return tmp; +} + +bool basic_map::is_null() const { + return ptr == nullptr; +} + +isl::checked::ctx basic_map::ctx() const { + return isl::checked::ctx(isl_basic_map_get_ctx(ptr)); +} + +isl::checked::basic_map basic_map::affine_hull() const +{ + auto res = isl_basic_map_affine_hull(copy()); + return manage(res); +} + +isl::checked::basic_map basic_map::apply_domain(isl::checked::basic_map bmap2) const +{ + auto res = isl_basic_map_apply_domain(copy(), bmap2.release()); + return manage(res); +} + +isl::checked::map basic_map::apply_domain(const isl::checked::map &map2) const +{ + return isl::checked::map(*this).apply_domain(map2); +} + +isl::checked::union_map basic_map::apply_domain(const isl::checked::union_map &umap2) const +{ + return isl::checked::map(*this).apply_domain(umap2); +} + +isl::checked::basic_map basic_map::apply_range(isl::checked::basic_map bmap2) const +{ + auto res = isl_basic_map_apply_range(copy(), bmap2.release()); + return manage(res); +} + +isl::checked::map basic_map::apply_range(const isl::checked::map &map2) const +{ + return isl::checked::map(*this).apply_range(map2); +} + +isl::checked::union_map basic_map::apply_range(const isl::checked::union_map &umap2) const +{ + return isl::checked::map(*this).apply_range(umap2); +} + +isl::checked::map basic_map::as_map() const +{ + return isl::checked::map(*this).as_map(); +} + +isl::checked::multi_union_pw_aff basic_map::as_multi_union_pw_aff() const +{ + return isl::checked::map(*this).as_multi_union_pw_aff(); +} + +isl::checked::pw_multi_aff basic_map::as_pw_multi_aff() const +{ + return isl::checked::map(*this).as_pw_multi_aff(); +} + +isl::checked::union_pw_multi_aff basic_map::as_union_pw_multi_aff() const +{ + return isl::checked::map(*this).as_union_pw_multi_aff(); +} + +isl::checked::set basic_map::bind_domain(const isl::checked::multi_id &tuple) const +{ + return isl::checked::map(*this).bind_domain(tuple); +} + +isl::checked::set basic_map::bind_range(const isl::checked::multi_id &tuple) const +{ + return isl::checked::map(*this).bind_range(tuple); +} + +isl::checked::map basic_map::coalesce() const +{ + return isl::checked::map(*this).coalesce(); +} + +isl::checked::map basic_map::complement() const +{ + return isl::checked::map(*this).complement(); +} + +isl::checked::union_map basic_map::compute_divs() const +{ + return isl::checked::map(*this).compute_divs(); +} + +isl::checked::map basic_map::curry() const +{ + return isl::checked::map(*this).curry(); +} + +isl::checked::basic_set basic_map::deltas() const +{ + auto res = isl_basic_map_deltas(copy()); + return manage(res); +} + +isl::checked::basic_map basic_map::detect_equalities() const +{ + auto res = isl_basic_map_detect_equalities(copy()); + return manage(res); +} + +isl::checked::set basic_map::domain() const +{ + return isl::checked::map(*this).domain(); +} + +isl::checked::map basic_map::domain_factor_domain() const +{ + return isl::checked::map(*this).domain_factor_domain(); +} + +isl::checked::map basic_map::domain_factor_range() const +{ + return isl::checked::map(*this).domain_factor_range(); +} + +isl::checked::union_map basic_map::domain_map() const +{ + return isl::checked::map(*this).domain_map(); +} + +isl::checked::union_pw_multi_aff basic_map::domain_map_union_pw_multi_aff() const +{ + return isl::checked::map(*this).domain_map_union_pw_multi_aff(); +} + +isl::checked::map basic_map::domain_product(const isl::checked::map &map2) const +{ + return isl::checked::map(*this).domain_product(map2); +} + +isl::checked::union_map basic_map::domain_product(const isl::checked::union_map &umap2) const +{ + return isl::checked::map(*this).domain_product(umap2); +} + +isl::checked::map basic_map::domain_reverse() const +{ + return isl::checked::map(*this).domain_reverse(); +} + +class size basic_map::domain_tuple_dim() const +{ + return isl::checked::map(*this).domain_tuple_dim(); +} + +isl::checked::id basic_map::domain_tuple_id() const +{ + return isl::checked::map(*this).domain_tuple_id(); +} + +isl::checked::map basic_map::drop_unused_params() const +{ + return isl::checked::map(*this).drop_unused_params(); +} + +isl::checked::map basic_map::eq_at(const isl::checked::multi_pw_aff &mpa) const +{ + return isl::checked::map(*this).eq_at(mpa); +} + +isl::checked::union_map basic_map::eq_at(const isl::checked::multi_union_pw_aff &mupa) const +{ + return isl::checked::map(*this).eq_at(mupa); +} + +boolean basic_map::every_map(const std::function &test) const +{ + return isl::checked::map(*this).every_map(test); +} + +isl::checked::map basic_map::extract_map(const isl::checked::space &space) const +{ + return isl::checked::map(*this).extract_map(space); +} + +isl::checked::map basic_map::factor_domain() const +{ + return isl::checked::map(*this).factor_domain(); +} + +isl::checked::map basic_map::factor_range() const +{ + return isl::checked::map(*this).factor_range(); +} + +isl::checked::map basic_map::fixed_power(const isl::checked::val &exp) const +{ + return isl::checked::map(*this).fixed_power(exp); +} + +isl::checked::map basic_map::fixed_power(long exp) const +{ + return this->fixed_power(isl::checked::val(ctx(), exp)); +} + +isl::checked::basic_map basic_map::flatten() const +{ + auto res = isl_basic_map_flatten(copy()); + return manage(res); +} + +isl::checked::basic_map basic_map::flatten_domain() const +{ + auto res = isl_basic_map_flatten_domain(copy()); + return manage(res); +} + +isl::checked::basic_map basic_map::flatten_range() const +{ + auto res = isl_basic_map_flatten_range(copy()); + return manage(res); +} + +stat basic_map::foreach_basic_map(const std::function &fn) const +{ + return isl::checked::map(*this).foreach_basic_map(fn); +} + +stat basic_map::foreach_map(const std::function &fn) const +{ + return isl::checked::map(*this).foreach_map(fn); +} + +isl::checked::basic_map basic_map::gist(isl::checked::basic_map context) const +{ + auto res = isl_basic_map_gist(copy(), context.release()); + return manage(res); +} + +isl::checked::map basic_map::gist(const isl::checked::map &context) const +{ + return isl::checked::map(*this).gist(context); +} + +isl::checked::union_map basic_map::gist(const isl::checked::union_map &context) const +{ + return isl::checked::map(*this).gist(context); +} + +isl::checked::map basic_map::gist_domain(const isl::checked::set &context) const +{ + return isl::checked::map(*this).gist_domain(context); +} + +isl::checked::union_map basic_map::gist_domain(const isl::checked::union_set &uset) const +{ + return isl::checked::map(*this).gist_domain(uset); +} + +isl::checked::map basic_map::gist_params(const isl::checked::set &context) const +{ + return isl::checked::map(*this).gist_params(context); +} + +isl::checked::union_map basic_map::gist_range(const isl::checked::union_set &uset) const +{ + return isl::checked::map(*this).gist_range(uset); +} + +boolean basic_map::has_domain_tuple_id() const +{ + return isl::checked::map(*this).has_domain_tuple_id(); +} + +boolean basic_map::has_range_tuple_id() const +{ + return isl::checked::map(*this).has_range_tuple_id(); +} + +isl::checked::basic_map basic_map::intersect(isl::checked::basic_map bmap2) const +{ + auto res = isl_basic_map_intersect(copy(), bmap2.release()); + return manage(res); +} + +isl::checked::map basic_map::intersect(const isl::checked::map &map2) const +{ + return isl::checked::map(*this).intersect(map2); +} + +isl::checked::union_map basic_map::intersect(const isl::checked::union_map &umap2) const +{ + return isl::checked::map(*this).intersect(umap2); +} + +isl::checked::basic_map basic_map::intersect_domain(isl::checked::basic_set bset) const +{ + auto res = isl_basic_map_intersect_domain(copy(), bset.release()); + return manage(res); +} + +isl::checked::map basic_map::intersect_domain(const isl::checked::set &set) const +{ + return isl::checked::map(*this).intersect_domain(set); +} + +isl::checked::union_map basic_map::intersect_domain(const isl::checked::space &space) const +{ + return isl::checked::map(*this).intersect_domain(space); +} + +isl::checked::union_map basic_map::intersect_domain(const isl::checked::union_set &uset) const +{ + return isl::checked::map(*this).intersect_domain(uset); +} + +isl::checked::basic_map basic_map::intersect_domain(const isl::checked::point &bset) const +{ + return this->intersect_domain(isl::checked::basic_set(bset)); +} + +isl::checked::map basic_map::intersect_domain_factor_domain(const isl::checked::map &factor) const +{ + return isl::checked::map(*this).intersect_domain_factor_domain(factor); +} + +isl::checked::union_map basic_map::intersect_domain_factor_domain(const isl::checked::union_map &factor) const +{ + return isl::checked::map(*this).intersect_domain_factor_domain(factor); +} + +isl::checked::map basic_map::intersect_domain_factor_range(const isl::checked::map &factor) const +{ + return isl::checked::map(*this).intersect_domain_factor_range(factor); +} + +isl::checked::union_map basic_map::intersect_domain_factor_range(const isl::checked::union_map &factor) const +{ + return isl::checked::map(*this).intersect_domain_factor_range(factor); +} + +isl::checked::map basic_map::intersect_domain_wrapped_domain(const isl::checked::set &domain) const +{ + return isl::checked::map(*this).intersect_domain_wrapped_domain(domain); +} + +isl::checked::union_map basic_map::intersect_domain_wrapped_domain(const isl::checked::union_set &domain) const +{ + return isl::checked::map(*this).intersect_domain_wrapped_domain(domain); +} + +isl::checked::map basic_map::intersect_params(const isl::checked::set ¶ms) const +{ + return isl::checked::map(*this).intersect_params(params); +} + +isl::checked::basic_map basic_map::intersect_range(isl::checked::basic_set bset) const +{ + auto res = isl_basic_map_intersect_range(copy(), bset.release()); + return manage(res); +} + +isl::checked::map basic_map::intersect_range(const isl::checked::set &set) const +{ + return isl::checked::map(*this).intersect_range(set); +} + +isl::checked::union_map basic_map::intersect_range(const isl::checked::space &space) const +{ + return isl::checked::map(*this).intersect_range(space); +} + +isl::checked::union_map basic_map::intersect_range(const isl::checked::union_set &uset) const +{ + return isl::checked::map(*this).intersect_range(uset); +} + +isl::checked::basic_map basic_map::intersect_range(const isl::checked::point &bset) const +{ + return this->intersect_range(isl::checked::basic_set(bset)); +} + +isl::checked::map basic_map::intersect_range_factor_domain(const isl::checked::map &factor) const +{ + return isl::checked::map(*this).intersect_range_factor_domain(factor); +} + +isl::checked::union_map basic_map::intersect_range_factor_domain(const isl::checked::union_map &factor) const +{ + return isl::checked::map(*this).intersect_range_factor_domain(factor); +} + +isl::checked::map basic_map::intersect_range_factor_range(const isl::checked::map &factor) const +{ + return isl::checked::map(*this).intersect_range_factor_range(factor); +} + +isl::checked::union_map basic_map::intersect_range_factor_range(const isl::checked::union_map &factor) const +{ + return isl::checked::map(*this).intersect_range_factor_range(factor); +} + +isl::checked::map basic_map::intersect_range_wrapped_domain(const isl::checked::set &domain) const +{ + return isl::checked::map(*this).intersect_range_wrapped_domain(domain); +} + +isl::checked::union_map basic_map::intersect_range_wrapped_domain(const isl::checked::union_set &domain) const +{ + return isl::checked::map(*this).intersect_range_wrapped_domain(domain); +} + +boolean basic_map::is_bijective() const +{ + return isl::checked::map(*this).is_bijective(); +} + +boolean basic_map::is_disjoint(const isl::checked::map &map2) const +{ + return isl::checked::map(*this).is_disjoint(map2); +} + +boolean basic_map::is_disjoint(const isl::checked::union_map &umap2) const +{ + return isl::checked::map(*this).is_disjoint(umap2); +} + +boolean basic_map::is_empty() const +{ + auto res = isl_basic_map_is_empty(get()); + return manage(res); +} + +boolean basic_map::is_equal(const isl::checked::basic_map &bmap2) const +{ + auto res = isl_basic_map_is_equal(get(), bmap2.get()); + return manage(res); +} + +boolean basic_map::is_equal(const isl::checked::map &map2) const +{ + return isl::checked::map(*this).is_equal(map2); +} + +boolean basic_map::is_equal(const isl::checked::union_map &umap2) const +{ + return isl::checked::map(*this).is_equal(umap2); +} + +boolean basic_map::is_injective() const +{ + return isl::checked::map(*this).is_injective(); +} + +boolean basic_map::is_single_valued() const +{ + return isl::checked::map(*this).is_single_valued(); +} + +boolean basic_map::is_strict_subset(const isl::checked::map &map2) const +{ + return isl::checked::map(*this).is_strict_subset(map2); +} + +boolean basic_map::is_strict_subset(const isl::checked::union_map &umap2) const +{ + return isl::checked::map(*this).is_strict_subset(umap2); +} + +boolean basic_map::is_subset(const isl::checked::basic_map &bmap2) const +{ + auto res = isl_basic_map_is_subset(get(), bmap2.get()); + return manage(res); +} + +boolean basic_map::is_subset(const isl::checked::map &map2) const +{ + return isl::checked::map(*this).is_subset(map2); +} + +boolean basic_map::is_subset(const isl::checked::union_map &umap2) const +{ + return isl::checked::map(*this).is_subset(umap2); +} + +boolean basic_map::isa_map() const +{ + return isl::checked::map(*this).isa_map(); +} + +isl::checked::map basic_map::lex_ge_at(const isl::checked::multi_pw_aff &mpa) const +{ + return isl::checked::map(*this).lex_ge_at(mpa); +} + +isl::checked::map basic_map::lex_gt_at(const isl::checked::multi_pw_aff &mpa) const +{ + return isl::checked::map(*this).lex_gt_at(mpa); +} + +isl::checked::map basic_map::lex_le_at(const isl::checked::multi_pw_aff &mpa) const +{ + return isl::checked::map(*this).lex_le_at(mpa); +} + +isl::checked::map basic_map::lex_lt_at(const isl::checked::multi_pw_aff &mpa) const +{ + return isl::checked::map(*this).lex_lt_at(mpa); +} + +isl::checked::map basic_map::lexmax() const +{ + auto res = isl_basic_map_lexmax(copy()); + return manage(res); +} + +isl::checked::pw_multi_aff basic_map::lexmax_pw_multi_aff() const +{ + return isl::checked::map(*this).lexmax_pw_multi_aff(); +} + +isl::checked::map basic_map::lexmin() const +{ + auto res = isl_basic_map_lexmin(copy()); + return manage(res); +} + +isl::checked::pw_multi_aff basic_map::lexmin_pw_multi_aff() const +{ + return isl::checked::map(*this).lexmin_pw_multi_aff(); +} + +isl::checked::map basic_map::lower_bound(const isl::checked::multi_pw_aff &lower) const +{ + return isl::checked::map(*this).lower_bound(lower); +} + +isl::checked::map_list basic_map::map_list() const +{ + return isl::checked::map(*this).map_list(); +} + +isl::checked::multi_pw_aff basic_map::max_multi_pw_aff() const +{ + return isl::checked::map(*this).max_multi_pw_aff(); +} + +isl::checked::multi_pw_aff basic_map::min_multi_pw_aff() const +{ + return isl::checked::map(*this).min_multi_pw_aff(); +} + +class size basic_map::n_basic_map() const +{ + return isl::checked::map(*this).n_basic_map(); +} + +isl::checked::set basic_map::params() const +{ + return isl::checked::map(*this).params(); +} + +isl::checked::basic_map basic_map::polyhedral_hull() const +{ + return isl::checked::map(*this).polyhedral_hull(); +} + +isl::checked::map basic_map::preimage_domain(const isl::checked::multi_aff &ma) const +{ + return isl::checked::map(*this).preimage_domain(ma); +} + +isl::checked::map basic_map::preimage_domain(const isl::checked::multi_pw_aff &mpa) const +{ + return isl::checked::map(*this).preimage_domain(mpa); +} + +isl::checked::map basic_map::preimage_domain(const isl::checked::pw_multi_aff &pma) const +{ + return isl::checked::map(*this).preimage_domain(pma); +} + +isl::checked::union_map basic_map::preimage_domain(const isl::checked::union_pw_multi_aff &upma) const +{ + return isl::checked::map(*this).preimage_domain(upma); +} + +isl::checked::map basic_map::preimage_range(const isl::checked::multi_aff &ma) const +{ + return isl::checked::map(*this).preimage_range(ma); +} + +isl::checked::map basic_map::preimage_range(const isl::checked::pw_multi_aff &pma) const +{ + return isl::checked::map(*this).preimage_range(pma); +} + +isl::checked::union_map basic_map::preimage_range(const isl::checked::union_pw_multi_aff &upma) const +{ + return isl::checked::map(*this).preimage_range(upma); +} + +isl::checked::map basic_map::product(const isl::checked::map &map2) const +{ + return isl::checked::map(*this).product(map2); +} + +isl::checked::union_map basic_map::product(const isl::checked::union_map &umap2) const +{ + return isl::checked::map(*this).product(umap2); +} + +isl::checked::map basic_map::project_out_all_params() const +{ + return isl::checked::map(*this).project_out_all_params(); +} + +isl::checked::map basic_map::project_out_param(const isl::checked::id &id) const +{ + return isl::checked::map(*this).project_out_param(id); +} + +isl::checked::map basic_map::project_out_param(const std::string &id) const +{ + return this->project_out_param(isl::checked::id(ctx(), id)); +} + +isl::checked::map basic_map::project_out_param(const isl::checked::id_list &list) const +{ + return isl::checked::map(*this).project_out_param(list); +} + +isl::checked::set basic_map::range() const +{ + return isl::checked::map(*this).range(); +} + +isl::checked::map basic_map::range_factor_domain() const +{ + return isl::checked::map(*this).range_factor_domain(); +} + +isl::checked::map basic_map::range_factor_range() const +{ + return isl::checked::map(*this).range_factor_range(); +} + +isl::checked::fixed_box basic_map::range_lattice_tile() const +{ + return isl::checked::map(*this).range_lattice_tile(); +} + +isl::checked::union_map basic_map::range_map() const +{ + return isl::checked::map(*this).range_map(); +} + +isl::checked::map basic_map::range_product(const isl::checked::map &map2) const +{ + return isl::checked::map(*this).range_product(map2); +} + +isl::checked::union_map basic_map::range_product(const isl::checked::union_map &umap2) const +{ + return isl::checked::map(*this).range_product(umap2); +} + +isl::checked::map basic_map::range_reverse() const +{ + return isl::checked::map(*this).range_reverse(); +} + +isl::checked::fixed_box basic_map::range_simple_fixed_box_hull() const +{ + return isl::checked::map(*this).range_simple_fixed_box_hull(); +} + +class size basic_map::range_tuple_dim() const +{ + return isl::checked::map(*this).range_tuple_dim(); +} + +isl::checked::id basic_map::range_tuple_id() const +{ + return isl::checked::map(*this).range_tuple_id(); +} + +isl::checked::basic_map basic_map::reverse() const +{ + auto res = isl_basic_map_reverse(copy()); + return manage(res); +} + +isl::checked::basic_map basic_map::sample() const +{ + auto res = isl_basic_map_sample(copy()); + return manage(res); +} + +isl::checked::map basic_map::set_domain_tuple(const isl::checked::id &id) const +{ + return isl::checked::map(*this).set_domain_tuple(id); +} + +isl::checked::map basic_map::set_domain_tuple(const std::string &id) const +{ + return this->set_domain_tuple(isl::checked::id(ctx(), id)); +} + +isl::checked::map basic_map::set_range_tuple(const isl::checked::id &id) const +{ + return isl::checked::map(*this).set_range_tuple(id); +} + +isl::checked::map basic_map::set_range_tuple(const std::string &id) const +{ + return this->set_range_tuple(isl::checked::id(ctx(), id)); +} + +isl::checked::space basic_map::space() const +{ + return isl::checked::map(*this).space(); +} + +isl::checked::map basic_map::subtract(const isl::checked::map &map2) const +{ + return isl::checked::map(*this).subtract(map2); +} + +isl::checked::union_map basic_map::subtract(const isl::checked::union_map &umap2) const +{ + return isl::checked::map(*this).subtract(umap2); +} + +isl::checked::union_map basic_map::subtract_domain(const isl::checked::union_set &dom) const +{ + return isl::checked::map(*this).subtract_domain(dom); +} + +isl::checked::union_map basic_map::subtract_range(const isl::checked::union_set &dom) const +{ + return isl::checked::map(*this).subtract_range(dom); +} + +isl::checked::map_list basic_map::to_list() const +{ + return isl::checked::map(*this).to_list(); +} + +isl::checked::union_map basic_map::to_union_map() const +{ + return isl::checked::map(*this).to_union_map(); +} + +isl::checked::map basic_map::uncurry() const +{ + return isl::checked::map(*this).uncurry(); +} + +isl::checked::map basic_map::unite(isl::checked::basic_map bmap2) const +{ + auto res = isl_basic_map_union(copy(), bmap2.release()); + return manage(res); +} + +isl::checked::map basic_map::unite(const isl::checked::map &map2) const +{ + return isl::checked::map(*this).unite(map2); +} + +isl::checked::union_map basic_map::unite(const isl::checked::union_map &umap2) const +{ + return isl::checked::map(*this).unite(umap2); +} + +isl::checked::basic_map basic_map::unshifted_simple_hull() const +{ + return isl::checked::map(*this).unshifted_simple_hull(); +} + +isl::checked::map basic_map::upper_bound(const isl::checked::multi_pw_aff &upper) const +{ + return isl::checked::map(*this).upper_bound(upper); +} + +isl::checked::set basic_map::wrap() const +{ + return isl::checked::map(*this).wrap(); +} + +isl::checked::map basic_map::zip() const +{ + return isl::checked::map(*this).zip(); +} + +inline std::ostream &operator<<(std::ostream &os, const basic_map &obj) +{ + char *str = isl_basic_map_to_str(obj.get()); + if (!str) { + os.setstate(std::ios_base::badbit); + return os; + } + os << str; + free(str); + return os; +} + +// implementations for isl::basic_set +basic_set manage(__isl_take isl_basic_set *ptr) { + return basic_set(ptr); +} +basic_set manage_copy(__isl_keep isl_basic_set *ptr) { + ptr = isl_basic_set_copy(ptr); + return basic_set(ptr); +} + +basic_set::basic_set(__isl_take isl_basic_set *ptr) + : ptr(ptr) {} + +basic_set::basic_set() + : ptr(nullptr) {} + +basic_set::basic_set(const basic_set &obj) + : ptr(nullptr) +{ + ptr = obj.copy(); +} + +basic_set::basic_set(isl::checked::point pnt) +{ + auto res = isl_basic_set_from_point(pnt.release()); + ptr = res; +} + +basic_set::basic_set(isl::checked::ctx ctx, const std::string &str) +{ + auto res = isl_basic_set_read_from_str(ctx.release(), str.c_str()); + ptr = res; +} + +basic_set &basic_set::operator=(basic_set obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +basic_set::~basic_set() { + if (ptr) + isl_basic_set_free(ptr); +} + +__isl_give isl_basic_set *basic_set::copy() const & { + return isl_basic_set_copy(ptr); +} + +__isl_keep isl_basic_set *basic_set::get() const { + return ptr; +} + +__isl_give isl_basic_set *basic_set::release() { + isl_basic_set *tmp = ptr; + ptr = nullptr; + return tmp; +} + +bool basic_set::is_null() const { + return ptr == nullptr; +} + +isl::checked::ctx basic_set::ctx() const { + return isl::checked::ctx(isl_basic_set_get_ctx(ptr)); +} + +isl::checked::basic_set basic_set::affine_hull() const +{ + auto res = isl_basic_set_affine_hull(copy()); + return manage(res); +} + +isl::checked::basic_set basic_set::apply(isl::checked::basic_map bmap) const +{ + auto res = isl_basic_set_apply(copy(), bmap.release()); + return manage(res); +} + +isl::checked::set basic_set::apply(const isl::checked::map &map) const +{ + return isl::checked::set(*this).apply(map); +} + +isl::checked::union_set basic_set::apply(const isl::checked::union_map &umap) const +{ + return isl::checked::set(*this).apply(umap); +} + +isl::checked::pw_multi_aff basic_set::as_pw_multi_aff() const +{ + return isl::checked::set(*this).as_pw_multi_aff(); +} + +isl::checked::set basic_set::as_set() const +{ + return isl::checked::set(*this).as_set(); +} + +isl::checked::set basic_set::bind(const isl::checked::multi_id &tuple) const +{ + return isl::checked::set(*this).bind(tuple); +} + +isl::checked::set basic_set::coalesce() const +{ + return isl::checked::set(*this).coalesce(); +} + +isl::checked::set basic_set::complement() const +{ + return isl::checked::set(*this).complement(); +} + +isl::checked::union_set basic_set::compute_divs() const +{ + return isl::checked::set(*this).compute_divs(); +} + +isl::checked::basic_set basic_set::detect_equalities() const +{ + auto res = isl_basic_set_detect_equalities(copy()); + return manage(res); +} + +isl::checked::val basic_set::dim_max_val(int pos) const +{ + auto res = isl_basic_set_dim_max_val(copy(), pos); + return manage(res); +} + +isl::checked::val basic_set::dim_min_val(int pos) const +{ + return isl::checked::set(*this).dim_min_val(pos); +} + +isl::checked::set basic_set::drop_unused_params() const +{ + return isl::checked::set(*this).drop_unused_params(); +} + +boolean basic_set::every_set(const std::function &test) const +{ + return isl::checked::set(*this).every_set(test); +} + +isl::checked::set basic_set::extract_set(const isl::checked::space &space) const +{ + return isl::checked::set(*this).extract_set(space); +} + +isl::checked::basic_set basic_set::flatten() const +{ + auto res = isl_basic_set_flatten(copy()); + return manage(res); +} + +stat basic_set::foreach_basic_set(const std::function &fn) const +{ + return isl::checked::set(*this).foreach_basic_set(fn); +} + +stat basic_set::foreach_point(const std::function &fn) const +{ + return isl::checked::set(*this).foreach_point(fn); +} + +stat basic_set::foreach_set(const std::function &fn) const +{ + return isl::checked::set(*this).foreach_set(fn); +} + +isl::checked::basic_set basic_set::gist(isl::checked::basic_set context) const +{ + auto res = isl_basic_set_gist(copy(), context.release()); + return manage(res); +} + +isl::checked::set basic_set::gist(const isl::checked::set &context) const +{ + return isl::checked::set(*this).gist(context); +} + +isl::checked::union_set basic_set::gist(const isl::checked::union_set &context) const +{ + return isl::checked::set(*this).gist(context); +} + +isl::checked::basic_set basic_set::gist(const isl::checked::point &context) const +{ + return this->gist(isl::checked::basic_set(context)); +} + +isl::checked::set basic_set::gist_params(const isl::checked::set &context) const +{ + return isl::checked::set(*this).gist_params(context); +} + +isl::checked::map basic_set::identity() const +{ + return isl::checked::set(*this).identity(); +} + +isl::checked::pw_aff basic_set::indicator_function() const +{ + return isl::checked::set(*this).indicator_function(); +} + +isl::checked::map basic_set::insert_domain(const isl::checked::space &domain) const +{ + return isl::checked::set(*this).insert_domain(domain); +} + +isl::checked::basic_set basic_set::intersect(isl::checked::basic_set bset2) const +{ + auto res = isl_basic_set_intersect(copy(), bset2.release()); + return manage(res); +} + +isl::checked::set basic_set::intersect(const isl::checked::set &set2) const +{ + return isl::checked::set(*this).intersect(set2); +} + +isl::checked::union_set basic_set::intersect(const isl::checked::union_set &uset2) const +{ + return isl::checked::set(*this).intersect(uset2); +} + +isl::checked::basic_set basic_set::intersect(const isl::checked::point &bset2) const +{ + return this->intersect(isl::checked::basic_set(bset2)); +} + +isl::checked::basic_set basic_set::intersect_params(isl::checked::basic_set bset2) const +{ + auto res = isl_basic_set_intersect_params(copy(), bset2.release()); + return manage(res); +} + +isl::checked::set basic_set::intersect_params(const isl::checked::set ¶ms) const +{ + return isl::checked::set(*this).intersect_params(params); +} + +isl::checked::basic_set basic_set::intersect_params(const isl::checked::point &bset2) const +{ + return this->intersect_params(isl::checked::basic_set(bset2)); +} + +boolean basic_set::involves_locals() const +{ + return isl::checked::set(*this).involves_locals(); +} + +boolean basic_set::is_disjoint(const isl::checked::set &set2) const +{ + return isl::checked::set(*this).is_disjoint(set2); +} + +boolean basic_set::is_disjoint(const isl::checked::union_set &uset2) const +{ + return isl::checked::set(*this).is_disjoint(uset2); +} + +boolean basic_set::is_empty() const +{ + auto res = isl_basic_set_is_empty(get()); + return manage(res); +} + +boolean basic_set::is_equal(const isl::checked::basic_set &bset2) const +{ + auto res = isl_basic_set_is_equal(get(), bset2.get()); + return manage(res); +} + +boolean basic_set::is_equal(const isl::checked::set &set2) const +{ + return isl::checked::set(*this).is_equal(set2); +} + +boolean basic_set::is_equal(const isl::checked::union_set &uset2) const +{ + return isl::checked::set(*this).is_equal(uset2); +} + +boolean basic_set::is_equal(const isl::checked::point &bset2) const +{ + return this->is_equal(isl::checked::basic_set(bset2)); +} + +boolean basic_set::is_singleton() const +{ + return isl::checked::set(*this).is_singleton(); +} + +boolean basic_set::is_strict_subset(const isl::checked::set &set2) const +{ + return isl::checked::set(*this).is_strict_subset(set2); +} + +boolean basic_set::is_strict_subset(const isl::checked::union_set &uset2) const +{ + return isl::checked::set(*this).is_strict_subset(uset2); +} + +boolean basic_set::is_subset(const isl::checked::basic_set &bset2) const +{ + auto res = isl_basic_set_is_subset(get(), bset2.get()); + return manage(res); +} + +boolean basic_set::is_subset(const isl::checked::set &set2) const +{ + return isl::checked::set(*this).is_subset(set2); +} + +boolean basic_set::is_subset(const isl::checked::union_set &uset2) const +{ + return isl::checked::set(*this).is_subset(uset2); +} + +boolean basic_set::is_subset(const isl::checked::point &bset2) const +{ + return this->is_subset(isl::checked::basic_set(bset2)); +} + +boolean basic_set::is_wrapping() const +{ + auto res = isl_basic_set_is_wrapping(get()); + return manage(res); +} + +boolean basic_set::isa_set() const +{ + return isl::checked::set(*this).isa_set(); +} + +isl::checked::fixed_box basic_set::lattice_tile() const +{ + return isl::checked::set(*this).lattice_tile(); +} + +isl::checked::set basic_set::lexmax() const +{ + auto res = isl_basic_set_lexmax(copy()); + return manage(res); +} + +isl::checked::pw_multi_aff basic_set::lexmax_pw_multi_aff() const +{ + return isl::checked::set(*this).lexmax_pw_multi_aff(); +} + +isl::checked::set basic_set::lexmin() const +{ + auto res = isl_basic_set_lexmin(copy()); + return manage(res); +} + +isl::checked::pw_multi_aff basic_set::lexmin_pw_multi_aff() const +{ + return isl::checked::set(*this).lexmin_pw_multi_aff(); +} + +isl::checked::set basic_set::lower_bound(const isl::checked::multi_pw_aff &lower) const +{ + return isl::checked::set(*this).lower_bound(lower); +} + +isl::checked::set basic_set::lower_bound(const isl::checked::multi_val &lower) const +{ + return isl::checked::set(*this).lower_bound(lower); +} + +isl::checked::multi_pw_aff basic_set::max_multi_pw_aff() const +{ + return isl::checked::set(*this).max_multi_pw_aff(); +} + +isl::checked::val basic_set::max_val(const isl::checked::aff &obj) const +{ + return isl::checked::set(*this).max_val(obj); +} + +isl::checked::multi_pw_aff basic_set::min_multi_pw_aff() const +{ + return isl::checked::set(*this).min_multi_pw_aff(); +} + +isl::checked::val basic_set::min_val(const isl::checked::aff &obj) const +{ + return isl::checked::set(*this).min_val(obj); +} + +class size basic_set::n_basic_set() const +{ + return isl::checked::set(*this).n_basic_set(); +} + +isl::checked::pw_aff basic_set::param_pw_aff_on_domain(const isl::checked::id &id) const +{ + return isl::checked::set(*this).param_pw_aff_on_domain(id); +} + +isl::checked::pw_aff basic_set::param_pw_aff_on_domain(const std::string &id) const +{ + return this->param_pw_aff_on_domain(isl::checked::id(ctx(), id)); +} + +isl::checked::basic_set basic_set::params() const +{ + auto res = isl_basic_set_params(copy()); + return manage(res); +} + +isl::checked::multi_val basic_set::plain_multi_val_if_fixed() const +{ + return isl::checked::set(*this).plain_multi_val_if_fixed(); +} + +isl::checked::basic_set basic_set::polyhedral_hull() const +{ + return isl::checked::set(*this).polyhedral_hull(); +} + +isl::checked::set basic_set::preimage(const isl::checked::multi_aff &ma) const +{ + return isl::checked::set(*this).preimage(ma); +} + +isl::checked::set basic_set::preimage(const isl::checked::multi_pw_aff &mpa) const +{ + return isl::checked::set(*this).preimage(mpa); +} + +isl::checked::set basic_set::preimage(const isl::checked::pw_multi_aff &pma) const +{ + return isl::checked::set(*this).preimage(pma); +} + +isl::checked::union_set basic_set::preimage(const isl::checked::union_pw_multi_aff &upma) const +{ + return isl::checked::set(*this).preimage(upma); +} + +isl::checked::set basic_set::product(const isl::checked::set &set2) const +{ + return isl::checked::set(*this).product(set2); +} + +isl::checked::set basic_set::project_out_all_params() const +{ + return isl::checked::set(*this).project_out_all_params(); +} + +isl::checked::set basic_set::project_out_param(const isl::checked::id &id) const +{ + return isl::checked::set(*this).project_out_param(id); +} + +isl::checked::set basic_set::project_out_param(const std::string &id) const +{ + return this->project_out_param(isl::checked::id(ctx(), id)); +} + +isl::checked::set basic_set::project_out_param(const isl::checked::id_list &list) const +{ + return isl::checked::set(*this).project_out_param(list); +} + +isl::checked::pw_aff basic_set::pw_aff_on_domain(const isl::checked::val &v) const +{ + return isl::checked::set(*this).pw_aff_on_domain(v); +} + +isl::checked::pw_aff basic_set::pw_aff_on_domain(long v) const +{ + return this->pw_aff_on_domain(isl::checked::val(ctx(), v)); +} + +isl::checked::pw_multi_aff basic_set::pw_multi_aff_on_domain(const isl::checked::multi_val &mv) const +{ + return isl::checked::set(*this).pw_multi_aff_on_domain(mv); +} + +isl::checked::basic_set basic_set::sample() const +{ + auto res = isl_basic_set_sample(copy()); + return manage(res); +} + +isl::checked::point basic_set::sample_point() const +{ + auto res = isl_basic_set_sample_point(copy()); + return manage(res); +} + +isl::checked::set_list basic_set::set_list() const +{ + return isl::checked::set(*this).set_list(); +} + +isl::checked::fixed_box basic_set::simple_fixed_box_hull() const +{ + return isl::checked::set(*this).simple_fixed_box_hull(); +} + +isl::checked::space basic_set::space() const +{ + return isl::checked::set(*this).space(); +} + +isl::checked::val basic_set::stride(int pos) const +{ + return isl::checked::set(*this).stride(pos); +} + +isl::checked::set basic_set::subtract(const isl::checked::set &set2) const +{ + return isl::checked::set(*this).subtract(set2); +} + +isl::checked::union_set basic_set::subtract(const isl::checked::union_set &uset2) const +{ + return isl::checked::set(*this).subtract(uset2); +} + +isl::checked::set_list basic_set::to_list() const +{ + return isl::checked::set(*this).to_list(); +} + +isl::checked::set basic_set::to_set() const +{ + auto res = isl_basic_set_to_set(copy()); + return manage(res); +} + +isl::checked::union_set basic_set::to_union_set() const +{ + return isl::checked::set(*this).to_union_set(); +} + +isl::checked::map basic_set::translation() const +{ + return isl::checked::set(*this).translation(); +} + +class size basic_set::tuple_dim() const +{ + return isl::checked::set(*this).tuple_dim(); +} + +isl::checked::set basic_set::unbind_params(const isl::checked::multi_id &tuple) const +{ + return isl::checked::set(*this).unbind_params(tuple); +} + +isl::checked::map basic_set::unbind_params_insert_domain(const isl::checked::multi_id &domain) const +{ + return isl::checked::set(*this).unbind_params_insert_domain(domain); +} + +isl::checked::set basic_set::unite(isl::checked::basic_set bset2) const +{ + auto res = isl_basic_set_union(copy(), bset2.release()); + return manage(res); +} + +isl::checked::set basic_set::unite(const isl::checked::set &set2) const +{ + return isl::checked::set(*this).unite(set2); +} + +isl::checked::union_set basic_set::unite(const isl::checked::union_set &uset2) const +{ + return isl::checked::set(*this).unite(uset2); +} + +isl::checked::set basic_set::unite(const isl::checked::point &bset2) const +{ + return this->unite(isl::checked::basic_set(bset2)); +} + +isl::checked::basic_set basic_set::unshifted_simple_hull() const +{ + return isl::checked::set(*this).unshifted_simple_hull(); +} + +isl::checked::map basic_set::unwrap() const +{ + return isl::checked::set(*this).unwrap(); +} + +isl::checked::set basic_set::upper_bound(const isl::checked::multi_pw_aff &upper) const +{ + return isl::checked::set(*this).upper_bound(upper); +} + +isl::checked::set basic_set::upper_bound(const isl::checked::multi_val &upper) const +{ + return isl::checked::set(*this).upper_bound(upper); +} + +isl::checked::set basic_set::wrapped_reverse() const +{ + return isl::checked::set(*this).wrapped_reverse(); +} + +inline std::ostream &operator<<(std::ostream &os, const basic_set &obj) +{ + char *str = isl_basic_set_to_str(obj.get()); + if (!str) { + os.setstate(std::ios_base::badbit); + return os; + } + os << str; + free(str); + return os; +} + +// implementations for isl::fixed_box +fixed_box manage(__isl_take isl_fixed_box *ptr) { + return fixed_box(ptr); +} +fixed_box manage_copy(__isl_keep isl_fixed_box *ptr) { + ptr = isl_fixed_box_copy(ptr); + return fixed_box(ptr); +} + +fixed_box::fixed_box(__isl_take isl_fixed_box *ptr) + : ptr(ptr) {} + +fixed_box::fixed_box() + : ptr(nullptr) {} + +fixed_box::fixed_box(const fixed_box &obj) + : ptr(nullptr) +{ + ptr = obj.copy(); +} + +fixed_box::fixed_box(isl::checked::ctx ctx, const std::string &str) +{ + auto res = isl_fixed_box_read_from_str(ctx.release(), str.c_str()); + ptr = res; +} + +fixed_box &fixed_box::operator=(fixed_box obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +fixed_box::~fixed_box() { + if (ptr) + isl_fixed_box_free(ptr); +} + +__isl_give isl_fixed_box *fixed_box::copy() const & { + return isl_fixed_box_copy(ptr); +} + +__isl_keep isl_fixed_box *fixed_box::get() const { + return ptr; +} + +__isl_give isl_fixed_box *fixed_box::release() { + isl_fixed_box *tmp = ptr; + ptr = nullptr; + return tmp; +} + +bool fixed_box::is_null() const { + return ptr == nullptr; +} + +isl::checked::ctx fixed_box::ctx() const { + return isl::checked::ctx(isl_fixed_box_get_ctx(ptr)); +} + +boolean fixed_box::is_valid() const +{ + auto res = isl_fixed_box_is_valid(get()); + return manage(res); +} + +isl::checked::multi_aff fixed_box::offset() const +{ + auto res = isl_fixed_box_get_offset(get()); + return manage(res); +} + +isl::checked::multi_aff fixed_box::get_offset() const +{ + return offset(); +} + +isl::checked::multi_val fixed_box::size() const +{ + auto res = isl_fixed_box_get_size(get()); + return manage(res); +} + +isl::checked::multi_val fixed_box::get_size() const +{ + return size(); +} + +isl::checked::space fixed_box::space() const +{ + auto res = isl_fixed_box_get_space(get()); + return manage(res); +} + +isl::checked::space fixed_box::get_space() const +{ + return space(); +} + +inline std::ostream &operator<<(std::ostream &os, const fixed_box &obj) +{ + char *str = isl_fixed_box_to_str(obj.get()); + if (!str) { + os.setstate(std::ios_base::badbit); + return os; + } + os << str; + free(str); + return os; +} + +// implementations for isl::id +id manage(__isl_take isl_id *ptr) { + return id(ptr); +} +id manage_copy(__isl_keep isl_id *ptr) { + ptr = isl_id_copy(ptr); + return id(ptr); +} + +id::id(__isl_take isl_id *ptr) + : ptr(ptr) {} + +id::id() + : ptr(nullptr) {} + +id::id(const id &obj) + : ptr(nullptr) +{ + ptr = obj.copy(); +} + +id::id(isl::checked::ctx ctx, const std::string &str) +{ + auto res = isl_id_read_from_str(ctx.release(), str.c_str()); + ptr = res; +} + +id &id::operator=(id obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +id::~id() { + if (ptr) + isl_id_free(ptr); +} + +__isl_give isl_id *id::copy() const & { + return isl_id_copy(ptr); +} + +__isl_keep isl_id *id::get() const { + return ptr; +} + +__isl_give isl_id *id::release() { + isl_id *tmp = ptr; + ptr = nullptr; + return tmp; +} + +bool id::is_null() const { + return ptr == nullptr; +} + +isl::checked::ctx id::ctx() const { + return isl::checked::ctx(isl_id_get_ctx(ptr)); +} + +std::string id::name() const +{ + auto res = isl_id_get_name(get()); + std::string tmp(res); + return tmp; +} + +std::string id::get_name() const +{ + return name(); +} + +isl::checked::id_list id::to_list() const +{ + auto res = isl_id_to_list(copy()); + return manage(res); +} + +#if __cplusplus >= 201703L +id::id(isl::checked::ctx ctx, const std::string &str, const std::any &any) +{ + std::any *p = new std::any(any); + auto res = isl_id_alloc(ctx.get(), str.c_str(), p); + res = isl_id_set_free_user(res, &ctx::free_user); + if (!res) { + delete p; + } + ptr = res; +} + +template +std::optional id::try_user() const +{ + std::any *p = (std::any *) isl_id_get_user(ptr); + if (!p) + return std::nullopt; + if (isl_id_get_free_user(ptr) != &ctx::free_user) + return std::nullopt; + T *res = std::any_cast(p); + if (!res) + return std::nullopt; + return *res; +} + +template +T id::user() const +{ + std::any *p = (std::any *) isl_id_get_user(ptr); + if (!p) + isl_die(ctx().get(), isl_error_invalid, "no user pointer", return T()); + if (isl_id_get_free_user(ptr) != &ctx::free_user) + isl_die(ctx().get(), isl_error_invalid, "user pointer not attached by C++ interface", return T()); + T *res = std::any_cast(p); + if (!res) + isl_die(ctx().get(), isl_error_invalid, "user pointer not of given type", return T()); + return *res; +} +#endif + +inline std::ostream &operator<<(std::ostream &os, const id &obj) +{ + char *str = isl_id_to_str(obj.get()); + if (!str) { + os.setstate(std::ios_base::badbit); + return os; + } + os << str; + free(str); + return os; +} + +// implementations for isl::id_list +id_list manage(__isl_take isl_id_list *ptr) { + return id_list(ptr); +} +id_list manage_copy(__isl_keep isl_id_list *ptr) { + ptr = isl_id_list_copy(ptr); + return id_list(ptr); +} + +id_list::id_list(__isl_take isl_id_list *ptr) + : ptr(ptr) {} + +id_list::id_list() + : ptr(nullptr) {} + +id_list::id_list(const id_list &obj) + : ptr(nullptr) +{ + ptr = obj.copy(); +} + +id_list::id_list(isl::checked::ctx ctx, int n) +{ + auto res = isl_id_list_alloc(ctx.release(), n); + ptr = res; +} + +id_list::id_list(isl::checked::id el) +{ + auto res = isl_id_list_from_id(el.release()); + ptr = res; +} + +id_list::id_list(isl::checked::ctx ctx, const std::string &str) +{ + auto res = isl_id_list_read_from_str(ctx.release(), str.c_str()); + ptr = res; +} + +id_list &id_list::operator=(id_list obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +id_list::~id_list() { + if (ptr) + isl_id_list_free(ptr); +} + +__isl_give isl_id_list *id_list::copy() const & { + return isl_id_list_copy(ptr); +} + +__isl_keep isl_id_list *id_list::get() const { + return ptr; +} + +__isl_give isl_id_list *id_list::release() { + isl_id_list *tmp = ptr; + ptr = nullptr; + return tmp; +} + +bool id_list::is_null() const { + return ptr == nullptr; +} + +isl::checked::ctx id_list::ctx() const { + return isl::checked::ctx(isl_id_list_get_ctx(ptr)); +} + +isl::checked::id_list id_list::add(isl::checked::id el) const +{ + auto res = isl_id_list_add(copy(), el.release()); + return manage(res); +} + +isl::checked::id_list id_list::add(const std::string &el) const +{ + return this->add(isl::checked::id(ctx(), el)); +} + +isl::checked::id id_list::at(int index) const +{ + auto res = isl_id_list_get_at(get(), index); + return manage(res); +} + +isl::checked::id id_list::get_at(int index) const +{ + return at(index); +} + +isl::checked::id_list id_list::clear() const +{ + auto res = isl_id_list_clear(copy()); + return manage(res); +} + +isl::checked::id_list id_list::concat(isl::checked::id_list list2) const +{ + auto res = isl_id_list_concat(copy(), list2.release()); + return manage(res); +} + +isl::checked::id_list id_list::drop(unsigned int first, unsigned int n) const +{ + auto res = isl_id_list_drop(copy(), first, n); + return manage(res); +} + +stat id_list::foreach(const std::function &fn) const +{ + struct fn_data { + std::function func; + } fn_data = { fn }; + auto fn_lambda = [](isl_id *arg_0, void *arg_1) -> isl_stat { + auto *data = static_cast(arg_1); + auto ret = (data->func)(manage(arg_0)); + return ret.release(); + }; + auto res = isl_id_list_foreach(get(), fn_lambda, &fn_data); + return manage(res); +} + +stat id_list::foreach_scc(const std::function &follows, const std::function &fn) const +{ + struct follows_data { + std::function func; + } follows_data = { follows }; + auto follows_lambda = [](isl_id *arg_0, isl_id *arg_1, void *arg_2) -> isl_bool { + auto *data = static_cast(arg_2); + auto ret = (data->func)(manage_copy(arg_0), manage_copy(arg_1)); + return ret.release(); + }; + struct fn_data { + std::function func; + } fn_data = { fn }; + auto fn_lambda = [](isl_id_list *arg_0, void *arg_1) -> isl_stat { + auto *data = static_cast(arg_1); + auto ret = (data->func)(manage(arg_0)); + return ret.release(); + }; + auto res = isl_id_list_foreach_scc(get(), follows_lambda, &follows_data, fn_lambda, &fn_data); + return manage(res); +} + +isl::checked::id_list id_list::insert(unsigned int pos, isl::checked::id el) const +{ + auto res = isl_id_list_insert(copy(), pos, el.release()); + return manage(res); +} + +isl::checked::id_list id_list::insert(unsigned int pos, const std::string &el) const +{ + return this->insert(pos, isl::checked::id(ctx(), el)); +} + +isl::checked::id_list id_list::set_at(int index, isl::checked::id el) const +{ + auto res = isl_id_list_set_at(copy(), index, el.release()); + return manage(res); +} + +isl::checked::id_list id_list::set_at(int index, const std::string &el) const +{ + return this->set_at(index, isl::checked::id(ctx(), el)); +} + +class size id_list::size() const +{ + auto res = isl_id_list_size(get()); + return manage(res); +} + +inline std::ostream &operator<<(std::ostream &os, const id_list &obj) +{ + char *str = isl_id_list_to_str(obj.get()); + if (!str) { + os.setstate(std::ios_base::badbit); + return os; + } + os << str; + free(str); + return os; +} + +// implementations for isl::id_to_ast_expr +id_to_ast_expr manage(__isl_take isl_id_to_ast_expr *ptr) { + return id_to_ast_expr(ptr); +} +id_to_ast_expr manage_copy(__isl_keep isl_id_to_ast_expr *ptr) { + ptr = isl_id_to_ast_expr_copy(ptr); + return id_to_ast_expr(ptr); +} + +id_to_ast_expr::id_to_ast_expr(__isl_take isl_id_to_ast_expr *ptr) + : ptr(ptr) {} + +id_to_ast_expr::id_to_ast_expr() + : ptr(nullptr) {} + +id_to_ast_expr::id_to_ast_expr(const id_to_ast_expr &obj) + : ptr(nullptr) +{ + ptr = obj.copy(); +} + +id_to_ast_expr::id_to_ast_expr(isl::checked::ctx ctx, int min_size) +{ + auto res = isl_id_to_ast_expr_alloc(ctx.release(), min_size); + ptr = res; +} + +id_to_ast_expr::id_to_ast_expr(isl::checked::ctx ctx, const std::string &str) +{ + auto res = isl_id_to_ast_expr_read_from_str(ctx.release(), str.c_str()); + ptr = res; +} + +id_to_ast_expr &id_to_ast_expr::operator=(id_to_ast_expr obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +id_to_ast_expr::~id_to_ast_expr() { + if (ptr) + isl_id_to_ast_expr_free(ptr); +} + +__isl_give isl_id_to_ast_expr *id_to_ast_expr::copy() const & { + return isl_id_to_ast_expr_copy(ptr); +} + +__isl_keep isl_id_to_ast_expr *id_to_ast_expr::get() const { + return ptr; +} + +__isl_give isl_id_to_ast_expr *id_to_ast_expr::release() { + isl_id_to_ast_expr *tmp = ptr; + ptr = nullptr; + return tmp; +} + +bool id_to_ast_expr::is_null() const { + return ptr == nullptr; +} + +isl::checked::ctx id_to_ast_expr::ctx() const { + return isl::checked::ctx(isl_id_to_ast_expr_get_ctx(ptr)); +} + +boolean id_to_ast_expr::is_equal(const isl::checked::id_to_ast_expr &hmap2) const +{ + auto res = isl_id_to_ast_expr_is_equal(get(), hmap2.get()); + return manage(res); +} + +isl::checked::id_to_ast_expr id_to_ast_expr::set(isl::checked::id key, isl::checked::ast_expr val) const +{ + auto res = isl_id_to_ast_expr_set(copy(), key.release(), val.release()); + return manage(res); +} + +isl::checked::id_to_ast_expr id_to_ast_expr::set(const std::string &key, const isl::checked::ast_expr &val) const +{ + return this->set(isl::checked::id(ctx(), key), val); +} + +inline std::ostream &operator<<(std::ostream &os, const id_to_ast_expr &obj) +{ + char *str = isl_id_to_ast_expr_to_str(obj.get()); + if (!str) { + os.setstate(std::ios_base::badbit); + return os; + } + os << str; + free(str); + return os; +} + +// implementations for isl::id_to_id +id_to_id manage(__isl_take isl_id_to_id *ptr) { + return id_to_id(ptr); +} +id_to_id manage_copy(__isl_keep isl_id_to_id *ptr) { + ptr = isl_id_to_id_copy(ptr); + return id_to_id(ptr); +} + +id_to_id::id_to_id(__isl_take isl_id_to_id *ptr) + : ptr(ptr) {} + +id_to_id::id_to_id() + : ptr(nullptr) {} + +id_to_id::id_to_id(const id_to_id &obj) + : ptr(nullptr) +{ + ptr = obj.copy(); +} + +id_to_id::id_to_id(isl::checked::ctx ctx, int min_size) +{ + auto res = isl_id_to_id_alloc(ctx.release(), min_size); + ptr = res; +} + +id_to_id::id_to_id(isl::checked::ctx ctx, const std::string &str) +{ + auto res = isl_id_to_id_read_from_str(ctx.release(), str.c_str()); + ptr = res; +} + +id_to_id &id_to_id::operator=(id_to_id obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +id_to_id::~id_to_id() { + if (ptr) + isl_id_to_id_free(ptr); +} + +__isl_give isl_id_to_id *id_to_id::copy() const & { + return isl_id_to_id_copy(ptr); +} + +__isl_keep isl_id_to_id *id_to_id::get() const { + return ptr; +} + +__isl_give isl_id_to_id *id_to_id::release() { + isl_id_to_id *tmp = ptr; + ptr = nullptr; + return tmp; +} + +bool id_to_id::is_null() const { + return ptr == nullptr; +} + +isl::checked::ctx id_to_id::ctx() const { + return isl::checked::ctx(isl_id_to_id_get_ctx(ptr)); +} + +boolean id_to_id::is_equal(const isl::checked::id_to_id &hmap2) const +{ + auto res = isl_id_to_id_is_equal(get(), hmap2.get()); + return manage(res); +} + +isl::checked::id_to_id id_to_id::set(isl::checked::id key, isl::checked::id val) const +{ + auto res = isl_id_to_id_set(copy(), key.release(), val.release()); + return manage(res); +} + +isl::checked::id_to_id id_to_id::set(const isl::checked::id &key, const std::string &val) const +{ + return this->set(key, isl::checked::id(ctx(), val)); +} + +isl::checked::id_to_id id_to_id::set(const std::string &key, const isl::checked::id &val) const +{ + return this->set(isl::checked::id(ctx(), key), val); +} + +isl::checked::id_to_id id_to_id::set(const std::string &key, const std::string &val) const +{ + return this->set(isl::checked::id(ctx(), key), isl::checked::id(ctx(), val)); +} + +inline std::ostream &operator<<(std::ostream &os, const id_to_id &obj) +{ + char *str = isl_id_to_id_to_str(obj.get()); + if (!str) { + os.setstate(std::ios_base::badbit); + return os; + } + os << str; + free(str); + return os; +} + +// implementations for isl::map +map manage(__isl_take isl_map *ptr) { + return map(ptr); +} +map manage_copy(__isl_keep isl_map *ptr) { + ptr = isl_map_copy(ptr); + return map(ptr); +} + +map::map(__isl_take isl_map *ptr) + : ptr(ptr) {} + +map::map() + : ptr(nullptr) {} + +map::map(const map &obj) + : ptr(nullptr) +{ + ptr = obj.copy(); +} + +map::map(isl::checked::basic_map bmap) +{ + auto res = isl_map_from_basic_map(bmap.release()); + ptr = res; +} + +map::map(isl::checked::ctx ctx, const std::string &str) +{ + auto res = isl_map_read_from_str(ctx.release(), str.c_str()); + ptr = res; +} + +map &map::operator=(map obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +map::~map() { + if (ptr) + isl_map_free(ptr); +} + +__isl_give isl_map *map::copy() const & { + return isl_map_copy(ptr); +} + +__isl_keep isl_map *map::get() const { + return ptr; +} + +__isl_give isl_map *map::release() { + isl_map *tmp = ptr; + ptr = nullptr; + return tmp; +} + +bool map::is_null() const { + return ptr == nullptr; +} + +isl::checked::ctx map::ctx() const { + return isl::checked::ctx(isl_map_get_ctx(ptr)); +} + +isl::checked::basic_map map::affine_hull() const +{ + auto res = isl_map_affine_hull(copy()); + return manage(res); +} + +isl::checked::map map::apply_domain(isl::checked::map map2) const +{ + auto res = isl_map_apply_domain(copy(), map2.release()); + return manage(res); +} + +isl::checked::union_map map::apply_domain(const isl::checked::union_map &umap2) const +{ + return isl::checked::union_map(*this).apply_domain(umap2); +} + +isl::checked::map map::apply_domain(const isl::checked::basic_map &map2) const +{ + return this->apply_domain(isl::checked::map(map2)); +} + +isl::checked::map map::apply_range(isl::checked::map map2) const +{ + auto res = isl_map_apply_range(copy(), map2.release()); + return manage(res); +} + +isl::checked::union_map map::apply_range(const isl::checked::union_map &umap2) const +{ + return isl::checked::union_map(*this).apply_range(umap2); +} + +isl::checked::map map::apply_range(const isl::checked::basic_map &map2) const +{ + return this->apply_range(isl::checked::map(map2)); +} + +isl::checked::map map::as_map() const +{ + return isl::checked::union_map(*this).as_map(); +} + +isl::checked::multi_union_pw_aff map::as_multi_union_pw_aff() const +{ + return isl::checked::union_map(*this).as_multi_union_pw_aff(); +} + +isl::checked::pw_multi_aff map::as_pw_multi_aff() const +{ + auto res = isl_map_as_pw_multi_aff(copy()); + return manage(res); +} + +isl::checked::union_pw_multi_aff map::as_union_pw_multi_aff() const +{ + return isl::checked::union_map(*this).as_union_pw_multi_aff(); +} + +isl::checked::set map::bind_domain(isl::checked::multi_id tuple) const +{ + auto res = isl_map_bind_domain(copy(), tuple.release()); + return manage(res); +} + +isl::checked::set map::bind_range(isl::checked::multi_id tuple) const +{ + auto res = isl_map_bind_range(copy(), tuple.release()); + return manage(res); +} + +isl::checked::map map::coalesce() const +{ + auto res = isl_map_coalesce(copy()); + return manage(res); +} + +isl::checked::map map::complement() const +{ + auto res = isl_map_complement(copy()); + return manage(res); +} + +isl::checked::union_map map::compute_divs() const +{ + return isl::checked::union_map(*this).compute_divs(); +} + +isl::checked::map map::curry() const +{ + auto res = isl_map_curry(copy()); + return manage(res); +} + +isl::checked::set map::deltas() const +{ + auto res = isl_map_deltas(copy()); + return manage(res); +} + +isl::checked::map map::detect_equalities() const +{ + auto res = isl_map_detect_equalities(copy()); + return manage(res); +} + +isl::checked::set map::domain() const +{ + auto res = isl_map_domain(copy()); + return manage(res); +} + +isl::checked::map map::domain_factor_domain() const +{ + auto res = isl_map_domain_factor_domain(copy()); + return manage(res); +} + +isl::checked::map map::domain_factor_range() const +{ + auto res = isl_map_domain_factor_range(copy()); + return manage(res); +} + +isl::checked::union_map map::domain_map() const +{ + return isl::checked::union_map(*this).domain_map(); +} + +isl::checked::union_pw_multi_aff map::domain_map_union_pw_multi_aff() const +{ + return isl::checked::union_map(*this).domain_map_union_pw_multi_aff(); +} + +isl::checked::map map::domain_product(isl::checked::map map2) const +{ + auto res = isl_map_domain_product(copy(), map2.release()); + return manage(res); +} + +isl::checked::union_map map::domain_product(const isl::checked::union_map &umap2) const +{ + return isl::checked::union_map(*this).domain_product(umap2); +} + +isl::checked::map map::domain_product(const isl::checked::basic_map &map2) const +{ + return this->domain_product(isl::checked::map(map2)); +} + +isl::checked::map map::domain_reverse() const +{ + auto res = isl_map_domain_reverse(copy()); + return manage(res); +} + +class size map::domain_tuple_dim() const +{ + auto res = isl_map_domain_tuple_dim(get()); + return manage(res); +} + +isl::checked::id map::domain_tuple_id() const +{ + auto res = isl_map_get_domain_tuple_id(get()); + return manage(res); +} + +isl::checked::id map::get_domain_tuple_id() const +{ + return domain_tuple_id(); +} + +isl::checked::map map::drop_unused_params() const +{ + auto res = isl_map_drop_unused_params(copy()); + return manage(res); +} + +isl::checked::map map::empty(isl::checked::space space) +{ + auto res = isl_map_empty(space.release()); + return manage(res); +} + +isl::checked::map map::eq_at(isl::checked::multi_pw_aff mpa) const +{ + auto res = isl_map_eq_at_multi_pw_aff(copy(), mpa.release()); + return manage(res); +} + +isl::checked::union_map map::eq_at(const isl::checked::multi_union_pw_aff &mupa) const +{ + return isl::checked::union_map(*this).eq_at(mupa); +} + +isl::checked::map map::eq_at(const isl::checked::aff &mpa) const +{ + return this->eq_at(isl::checked::multi_pw_aff(mpa)); +} + +isl::checked::map map::eq_at(const isl::checked::multi_aff &mpa) const +{ + return this->eq_at(isl::checked::multi_pw_aff(mpa)); +} + +isl::checked::map map::eq_at(const isl::checked::pw_aff &mpa) const +{ + return this->eq_at(isl::checked::multi_pw_aff(mpa)); +} + +isl::checked::map map::eq_at(const isl::checked::pw_multi_aff &mpa) const +{ + return this->eq_at(isl::checked::multi_pw_aff(mpa)); +} + +boolean map::every_map(const std::function &test) const +{ + return isl::checked::union_map(*this).every_map(test); +} + +isl::checked::map map::extract_map(const isl::checked::space &space) const +{ + return isl::checked::union_map(*this).extract_map(space); +} + +isl::checked::map map::factor_domain() const +{ + auto res = isl_map_factor_domain(copy()); + return manage(res); +} + +isl::checked::map map::factor_range() const +{ + auto res = isl_map_factor_range(copy()); + return manage(res); +} + +isl::checked::map map::fixed_power(isl::checked::val exp) const +{ + auto res = isl_map_fixed_power_val(copy(), exp.release()); + return manage(res); +} + +isl::checked::map map::fixed_power(long exp) const +{ + return this->fixed_power(isl::checked::val(ctx(), exp)); +} + +isl::checked::map map::flatten() const +{ + auto res = isl_map_flatten(copy()); + return manage(res); +} + +isl::checked::map map::flatten_domain() const +{ + auto res = isl_map_flatten_domain(copy()); + return manage(res); +} + +isl::checked::map map::flatten_range() const +{ + auto res = isl_map_flatten_range(copy()); + return manage(res); +} + +stat map::foreach_basic_map(const std::function &fn) const +{ + struct fn_data { + std::function func; + } fn_data = { fn }; + auto fn_lambda = [](isl_basic_map *arg_0, void *arg_1) -> isl_stat { + auto *data = static_cast(arg_1); + auto ret = (data->func)(manage(arg_0)); + return ret.release(); + }; + auto res = isl_map_foreach_basic_map(get(), fn_lambda, &fn_data); + return manage(res); +} + +stat map::foreach_map(const std::function &fn) const +{ + return isl::checked::union_map(*this).foreach_map(fn); +} + +isl::checked::map map::gist(isl::checked::map context) const +{ + auto res = isl_map_gist(copy(), context.release()); + return manage(res); +} + +isl::checked::union_map map::gist(const isl::checked::union_map &context) const +{ + return isl::checked::union_map(*this).gist(context); +} + +isl::checked::map map::gist(const isl::checked::basic_map &context) const +{ + return this->gist(isl::checked::map(context)); +} + +isl::checked::map map::gist_domain(isl::checked::set context) const +{ + auto res = isl_map_gist_domain(copy(), context.release()); + return manage(res); +} + +isl::checked::union_map map::gist_domain(const isl::checked::union_set &uset) const +{ + return isl::checked::union_map(*this).gist_domain(uset); +} + +isl::checked::map map::gist_domain(const isl::checked::basic_set &context) const +{ + return this->gist_domain(isl::checked::set(context)); +} + +isl::checked::map map::gist_domain(const isl::checked::point &context) const +{ + return this->gist_domain(isl::checked::set(context)); +} + +isl::checked::map map::gist_params(isl::checked::set context) const +{ + auto res = isl_map_gist_params(copy(), context.release()); + return manage(res); +} + +isl::checked::union_map map::gist_range(const isl::checked::union_set &uset) const +{ + return isl::checked::union_map(*this).gist_range(uset); +} + +boolean map::has_domain_tuple_id() const +{ + auto res = isl_map_has_domain_tuple_id(get()); + return manage(res); +} + +boolean map::has_range_tuple_id() const +{ + auto res = isl_map_has_range_tuple_id(get()); + return manage(res); +} + +isl::checked::map map::intersect(isl::checked::map map2) const +{ + auto res = isl_map_intersect(copy(), map2.release()); + return manage(res); +} + +isl::checked::union_map map::intersect(const isl::checked::union_map &umap2) const +{ + return isl::checked::union_map(*this).intersect(umap2); +} + +isl::checked::map map::intersect(const isl::checked::basic_map &map2) const +{ + return this->intersect(isl::checked::map(map2)); +} + +isl::checked::map map::intersect_domain(isl::checked::set set) const +{ + auto res = isl_map_intersect_domain(copy(), set.release()); + return manage(res); +} + +isl::checked::union_map map::intersect_domain(const isl::checked::space &space) const +{ + return isl::checked::union_map(*this).intersect_domain(space); +} + +isl::checked::union_map map::intersect_domain(const isl::checked::union_set &uset) const +{ + return isl::checked::union_map(*this).intersect_domain(uset); +} + +isl::checked::map map::intersect_domain(const isl::checked::basic_set &set) const +{ + return this->intersect_domain(isl::checked::set(set)); +} + +isl::checked::map map::intersect_domain(const isl::checked::point &set) const +{ + return this->intersect_domain(isl::checked::set(set)); +} + +isl::checked::map map::intersect_domain_factor_domain(isl::checked::map factor) const +{ + auto res = isl_map_intersect_domain_factor_domain(copy(), factor.release()); + return manage(res); +} + +isl::checked::union_map map::intersect_domain_factor_domain(const isl::checked::union_map &factor) const +{ + return isl::checked::union_map(*this).intersect_domain_factor_domain(factor); +} + +isl::checked::map map::intersect_domain_factor_domain(const isl::checked::basic_map &factor) const +{ + return this->intersect_domain_factor_domain(isl::checked::map(factor)); +} + +isl::checked::map map::intersect_domain_factor_range(isl::checked::map factor) const +{ + auto res = isl_map_intersect_domain_factor_range(copy(), factor.release()); + return manage(res); +} + +isl::checked::union_map map::intersect_domain_factor_range(const isl::checked::union_map &factor) const +{ + return isl::checked::union_map(*this).intersect_domain_factor_range(factor); +} + +isl::checked::map map::intersect_domain_factor_range(const isl::checked::basic_map &factor) const +{ + return this->intersect_domain_factor_range(isl::checked::map(factor)); +} + +isl::checked::map map::intersect_domain_wrapped_domain(isl::checked::set domain) const +{ + auto res = isl_map_intersect_domain_wrapped_domain(copy(), domain.release()); + return manage(res); +} + +isl::checked::union_map map::intersect_domain_wrapped_domain(const isl::checked::union_set &domain) const +{ + return isl::checked::union_map(*this).intersect_domain_wrapped_domain(domain); +} + +isl::checked::map map::intersect_domain_wrapped_domain(const isl::checked::basic_set &domain) const +{ + return this->intersect_domain_wrapped_domain(isl::checked::set(domain)); +} + +isl::checked::map map::intersect_domain_wrapped_domain(const isl::checked::point &domain) const +{ + return this->intersect_domain_wrapped_domain(isl::checked::set(domain)); +} + +isl::checked::map map::intersect_params(isl::checked::set params) const +{ + auto res = isl_map_intersect_params(copy(), params.release()); + return manage(res); +} + +isl::checked::map map::intersect_range(isl::checked::set set) const +{ + auto res = isl_map_intersect_range(copy(), set.release()); + return manage(res); +} + +isl::checked::union_map map::intersect_range(const isl::checked::space &space) const +{ + return isl::checked::union_map(*this).intersect_range(space); +} + +isl::checked::union_map map::intersect_range(const isl::checked::union_set &uset) const +{ + return isl::checked::union_map(*this).intersect_range(uset); +} + +isl::checked::map map::intersect_range(const isl::checked::basic_set &set) const +{ + return this->intersect_range(isl::checked::set(set)); +} + +isl::checked::map map::intersect_range(const isl::checked::point &set) const +{ + return this->intersect_range(isl::checked::set(set)); +} + +isl::checked::map map::intersect_range_factor_domain(isl::checked::map factor) const +{ + auto res = isl_map_intersect_range_factor_domain(copy(), factor.release()); + return manage(res); +} + +isl::checked::union_map map::intersect_range_factor_domain(const isl::checked::union_map &factor) const +{ + return isl::checked::union_map(*this).intersect_range_factor_domain(factor); +} + +isl::checked::map map::intersect_range_factor_domain(const isl::checked::basic_map &factor) const +{ + return this->intersect_range_factor_domain(isl::checked::map(factor)); +} + +isl::checked::map map::intersect_range_factor_range(isl::checked::map factor) const +{ + auto res = isl_map_intersect_range_factor_range(copy(), factor.release()); + return manage(res); +} + +isl::checked::union_map map::intersect_range_factor_range(const isl::checked::union_map &factor) const +{ + return isl::checked::union_map(*this).intersect_range_factor_range(factor); +} + +isl::checked::map map::intersect_range_factor_range(const isl::checked::basic_map &factor) const +{ + return this->intersect_range_factor_range(isl::checked::map(factor)); +} + +isl::checked::map map::intersect_range_wrapped_domain(isl::checked::set domain) const +{ + auto res = isl_map_intersect_range_wrapped_domain(copy(), domain.release()); + return manage(res); +} + +isl::checked::union_map map::intersect_range_wrapped_domain(const isl::checked::union_set &domain) const +{ + return isl::checked::union_map(*this).intersect_range_wrapped_domain(domain); +} + +isl::checked::map map::intersect_range_wrapped_domain(const isl::checked::basic_set &domain) const +{ + return this->intersect_range_wrapped_domain(isl::checked::set(domain)); +} + +isl::checked::map map::intersect_range_wrapped_domain(const isl::checked::point &domain) const +{ + return this->intersect_range_wrapped_domain(isl::checked::set(domain)); +} + +boolean map::is_bijective() const +{ + auto res = isl_map_is_bijective(get()); + return manage(res); +} + +boolean map::is_disjoint(const isl::checked::map &map2) const +{ + auto res = isl_map_is_disjoint(get(), map2.get()); + return manage(res); +} + +boolean map::is_disjoint(const isl::checked::union_map &umap2) const +{ + return isl::checked::union_map(*this).is_disjoint(umap2); +} + +boolean map::is_disjoint(const isl::checked::basic_map &map2) const +{ + return this->is_disjoint(isl::checked::map(map2)); +} + +boolean map::is_empty() const +{ + auto res = isl_map_is_empty(get()); + return manage(res); +} + +boolean map::is_equal(const isl::checked::map &map2) const +{ + auto res = isl_map_is_equal(get(), map2.get()); + return manage(res); +} + +boolean map::is_equal(const isl::checked::union_map &umap2) const +{ + return isl::checked::union_map(*this).is_equal(umap2); +} + +boolean map::is_equal(const isl::checked::basic_map &map2) const +{ + return this->is_equal(isl::checked::map(map2)); +} + +boolean map::is_injective() const +{ + auto res = isl_map_is_injective(get()); + return manage(res); +} + +boolean map::is_single_valued() const +{ + auto res = isl_map_is_single_valued(get()); + return manage(res); +} + +boolean map::is_strict_subset(const isl::checked::map &map2) const +{ + auto res = isl_map_is_strict_subset(get(), map2.get()); + return manage(res); +} + +boolean map::is_strict_subset(const isl::checked::union_map &umap2) const +{ + return isl::checked::union_map(*this).is_strict_subset(umap2); +} + +boolean map::is_strict_subset(const isl::checked::basic_map &map2) const +{ + return this->is_strict_subset(isl::checked::map(map2)); +} + +boolean map::is_subset(const isl::checked::map &map2) const +{ + auto res = isl_map_is_subset(get(), map2.get()); + return manage(res); +} + +boolean map::is_subset(const isl::checked::union_map &umap2) const +{ + return isl::checked::union_map(*this).is_subset(umap2); +} + +boolean map::is_subset(const isl::checked::basic_map &map2) const +{ + return this->is_subset(isl::checked::map(map2)); +} + +boolean map::isa_map() const +{ + return isl::checked::union_map(*this).isa_map(); +} + +isl::checked::map map::lex_ge_at(isl::checked::multi_pw_aff mpa) const +{ + auto res = isl_map_lex_ge_at_multi_pw_aff(copy(), mpa.release()); + return manage(res); +} + +isl::checked::map map::lex_gt_at(isl::checked::multi_pw_aff mpa) const +{ + auto res = isl_map_lex_gt_at_multi_pw_aff(copy(), mpa.release()); + return manage(res); +} + +isl::checked::map map::lex_le_at(isl::checked::multi_pw_aff mpa) const +{ + auto res = isl_map_lex_le_at_multi_pw_aff(copy(), mpa.release()); + return manage(res); +} + +isl::checked::map map::lex_lt_at(isl::checked::multi_pw_aff mpa) const +{ + auto res = isl_map_lex_lt_at_multi_pw_aff(copy(), mpa.release()); + return manage(res); +} + +isl::checked::map map::lexmax() const +{ + auto res = isl_map_lexmax(copy()); + return manage(res); +} + +isl::checked::pw_multi_aff map::lexmax_pw_multi_aff() const +{ + auto res = isl_map_lexmax_pw_multi_aff(copy()); + return manage(res); +} + +isl::checked::map map::lexmin() const +{ + auto res = isl_map_lexmin(copy()); + return manage(res); +} + +isl::checked::pw_multi_aff map::lexmin_pw_multi_aff() const +{ + auto res = isl_map_lexmin_pw_multi_aff(copy()); + return manage(res); +} + +isl::checked::map map::lower_bound(isl::checked::multi_pw_aff lower) const +{ + auto res = isl_map_lower_bound_multi_pw_aff(copy(), lower.release()); + return manage(res); +} + +isl::checked::map_list map::map_list() const +{ + return isl::checked::union_map(*this).map_list(); +} + +isl::checked::multi_pw_aff map::max_multi_pw_aff() const +{ + auto res = isl_map_max_multi_pw_aff(copy()); + return manage(res); +} + +isl::checked::multi_pw_aff map::min_multi_pw_aff() const +{ + auto res = isl_map_min_multi_pw_aff(copy()); + return manage(res); +} + +class size map::n_basic_map() const +{ + auto res = isl_map_n_basic_map(get()); + return manage(res); +} + +isl::checked::set map::params() const +{ + auto res = isl_map_params(copy()); + return manage(res); +} + +isl::checked::basic_map map::polyhedral_hull() const +{ + auto res = isl_map_polyhedral_hull(copy()); + return manage(res); +} + +isl::checked::map map::preimage_domain(isl::checked::multi_aff ma) const +{ + auto res = isl_map_preimage_domain_multi_aff(copy(), ma.release()); + return manage(res); +} + +isl::checked::map map::preimage_domain(isl::checked::multi_pw_aff mpa) const +{ + auto res = isl_map_preimage_domain_multi_pw_aff(copy(), mpa.release()); + return manage(res); +} + +isl::checked::map map::preimage_domain(isl::checked::pw_multi_aff pma) const +{ + auto res = isl_map_preimage_domain_pw_multi_aff(copy(), pma.release()); + return manage(res); +} + +isl::checked::union_map map::preimage_domain(const isl::checked::union_pw_multi_aff &upma) const +{ + return isl::checked::union_map(*this).preimage_domain(upma); +} + +isl::checked::map map::preimage_range(isl::checked::multi_aff ma) const +{ + auto res = isl_map_preimage_range_multi_aff(copy(), ma.release()); + return manage(res); +} + +isl::checked::map map::preimage_range(isl::checked::pw_multi_aff pma) const +{ + auto res = isl_map_preimage_range_pw_multi_aff(copy(), pma.release()); + return manage(res); +} + +isl::checked::union_map map::preimage_range(const isl::checked::union_pw_multi_aff &upma) const +{ + return isl::checked::union_map(*this).preimage_range(upma); +} + +isl::checked::map map::product(isl::checked::map map2) const +{ + auto res = isl_map_product(copy(), map2.release()); + return manage(res); +} + +isl::checked::union_map map::product(const isl::checked::union_map &umap2) const +{ + return isl::checked::union_map(*this).product(umap2); +} + +isl::checked::map map::product(const isl::checked::basic_map &map2) const +{ + return this->product(isl::checked::map(map2)); +} + +isl::checked::map map::project_out_all_params() const +{ + auto res = isl_map_project_out_all_params(copy()); + return manage(res); +} + +isl::checked::map map::project_out_param(isl::checked::id id) const +{ + auto res = isl_map_project_out_param_id(copy(), id.release()); + return manage(res); +} + +isl::checked::map map::project_out_param(const std::string &id) const +{ + return this->project_out_param(isl::checked::id(ctx(), id)); +} + +isl::checked::map map::project_out_param(isl::checked::id_list list) const +{ + auto res = isl_map_project_out_param_id_list(copy(), list.release()); + return manage(res); +} + +isl::checked::set map::range() const +{ + auto res = isl_map_range(copy()); + return manage(res); +} + +isl::checked::map map::range_factor_domain() const +{ + auto res = isl_map_range_factor_domain(copy()); + return manage(res); +} + +isl::checked::map map::range_factor_range() const +{ + auto res = isl_map_range_factor_range(copy()); + return manage(res); +} + +isl::checked::fixed_box map::range_lattice_tile() const +{ + auto res = isl_map_get_range_lattice_tile(get()); + return manage(res); +} + +isl::checked::fixed_box map::get_range_lattice_tile() const +{ + return range_lattice_tile(); +} + +isl::checked::union_map map::range_map() const +{ + return isl::checked::union_map(*this).range_map(); +} + +isl::checked::map map::range_product(isl::checked::map map2) const +{ + auto res = isl_map_range_product(copy(), map2.release()); + return manage(res); +} + +isl::checked::union_map map::range_product(const isl::checked::union_map &umap2) const +{ + return isl::checked::union_map(*this).range_product(umap2); +} + +isl::checked::map map::range_product(const isl::checked::basic_map &map2) const +{ + return this->range_product(isl::checked::map(map2)); +} + +isl::checked::map map::range_reverse() const +{ + auto res = isl_map_range_reverse(copy()); + return manage(res); +} + +isl::checked::fixed_box map::range_simple_fixed_box_hull() const +{ + auto res = isl_map_get_range_simple_fixed_box_hull(get()); + return manage(res); +} + +isl::checked::fixed_box map::get_range_simple_fixed_box_hull() const +{ + return range_simple_fixed_box_hull(); +} + +class size map::range_tuple_dim() const +{ + auto res = isl_map_range_tuple_dim(get()); + return manage(res); +} + +isl::checked::id map::range_tuple_id() const +{ + auto res = isl_map_get_range_tuple_id(get()); + return manage(res); +} + +isl::checked::id map::get_range_tuple_id() const +{ + return range_tuple_id(); +} + +isl::checked::map map::reverse() const +{ + auto res = isl_map_reverse(copy()); + return manage(res); +} + +isl::checked::basic_map map::sample() const +{ + auto res = isl_map_sample(copy()); + return manage(res); +} + +isl::checked::map map::set_domain_tuple(isl::checked::id id) const +{ + auto res = isl_map_set_domain_tuple_id(copy(), id.release()); + return manage(res); +} + +isl::checked::map map::set_domain_tuple(const std::string &id) const +{ + return this->set_domain_tuple(isl::checked::id(ctx(), id)); +} + +isl::checked::map map::set_range_tuple(isl::checked::id id) const +{ + auto res = isl_map_set_range_tuple_id(copy(), id.release()); + return manage(res); +} + +isl::checked::map map::set_range_tuple(const std::string &id) const +{ + return this->set_range_tuple(isl::checked::id(ctx(), id)); +} + +isl::checked::space map::space() const +{ + auto res = isl_map_get_space(get()); + return manage(res); +} + +isl::checked::space map::get_space() const +{ + return space(); +} + +isl::checked::map map::subtract(isl::checked::map map2) const +{ + auto res = isl_map_subtract(copy(), map2.release()); + return manage(res); +} + +isl::checked::union_map map::subtract(const isl::checked::union_map &umap2) const +{ + return isl::checked::union_map(*this).subtract(umap2); +} + +isl::checked::map map::subtract(const isl::checked::basic_map &map2) const +{ + return this->subtract(isl::checked::map(map2)); +} + +isl::checked::union_map map::subtract_domain(const isl::checked::union_set &dom) const +{ + return isl::checked::union_map(*this).subtract_domain(dom); +} + +isl::checked::union_map map::subtract_range(const isl::checked::union_set &dom) const +{ + return isl::checked::union_map(*this).subtract_range(dom); +} + +isl::checked::map_list map::to_list() const +{ + auto res = isl_map_to_list(copy()); + return manage(res); +} + +isl::checked::union_map map::to_union_map() const +{ + auto res = isl_map_to_union_map(copy()); + return manage(res); +} + +isl::checked::map map::uncurry() const +{ + auto res = isl_map_uncurry(copy()); + return manage(res); +} + +isl::checked::map map::unite(isl::checked::map map2) const +{ + auto res = isl_map_union(copy(), map2.release()); + return manage(res); +} + +isl::checked::union_map map::unite(const isl::checked::union_map &umap2) const +{ + return isl::checked::union_map(*this).unite(umap2); +} + +isl::checked::map map::unite(const isl::checked::basic_map &map2) const +{ + return this->unite(isl::checked::map(map2)); +} + +isl::checked::map map::universe(isl::checked::space space) +{ + auto res = isl_map_universe(space.release()); + return manage(res); +} + +isl::checked::basic_map map::unshifted_simple_hull() const +{ + auto res = isl_map_unshifted_simple_hull(copy()); + return manage(res); +} + +isl::checked::map map::upper_bound(isl::checked::multi_pw_aff upper) const +{ + auto res = isl_map_upper_bound_multi_pw_aff(copy(), upper.release()); + return manage(res); +} + +isl::checked::set map::wrap() const +{ + auto res = isl_map_wrap(copy()); + return manage(res); +} + +isl::checked::map map::zip() const +{ + auto res = isl_map_zip(copy()); + return manage(res); +} + +inline std::ostream &operator<<(std::ostream &os, const map &obj) +{ + char *str = isl_map_to_str(obj.get()); + if (!str) { + os.setstate(std::ios_base::badbit); + return os; + } + os << str; + free(str); + return os; +} + +// implementations for isl::map_list +map_list manage(__isl_take isl_map_list *ptr) { + return map_list(ptr); +} +map_list manage_copy(__isl_keep isl_map_list *ptr) { + ptr = isl_map_list_copy(ptr); + return map_list(ptr); +} + +map_list::map_list(__isl_take isl_map_list *ptr) + : ptr(ptr) {} + +map_list::map_list() + : ptr(nullptr) {} + +map_list::map_list(const map_list &obj) + : ptr(nullptr) +{ + ptr = obj.copy(); +} + +map_list::map_list(isl::checked::ctx ctx, int n) +{ + auto res = isl_map_list_alloc(ctx.release(), n); + ptr = res; +} + +map_list::map_list(isl::checked::map el) +{ + auto res = isl_map_list_from_map(el.release()); + ptr = res; +} + +map_list::map_list(isl::checked::ctx ctx, const std::string &str) +{ + auto res = isl_map_list_read_from_str(ctx.release(), str.c_str()); + ptr = res; +} + +map_list &map_list::operator=(map_list obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +map_list::~map_list() { + if (ptr) + isl_map_list_free(ptr); +} + +__isl_give isl_map_list *map_list::copy() const & { + return isl_map_list_copy(ptr); +} + +__isl_keep isl_map_list *map_list::get() const { + return ptr; +} + +__isl_give isl_map_list *map_list::release() { + isl_map_list *tmp = ptr; + ptr = nullptr; + return tmp; +} + +bool map_list::is_null() const { + return ptr == nullptr; +} + +isl::checked::ctx map_list::ctx() const { + return isl::checked::ctx(isl_map_list_get_ctx(ptr)); +} + +isl::checked::map_list map_list::add(isl::checked::map el) const +{ + auto res = isl_map_list_add(copy(), el.release()); + return manage(res); +} + +isl::checked::map map_list::at(int index) const +{ + auto res = isl_map_list_get_at(get(), index); + return manage(res); +} + +isl::checked::map map_list::get_at(int index) const +{ + return at(index); +} + +isl::checked::map_list map_list::clear() const +{ + auto res = isl_map_list_clear(copy()); + return manage(res); +} + +isl::checked::map_list map_list::concat(isl::checked::map_list list2) const +{ + auto res = isl_map_list_concat(copy(), list2.release()); + return manage(res); +} + +isl::checked::map_list map_list::drop(unsigned int first, unsigned int n) const +{ + auto res = isl_map_list_drop(copy(), first, n); + return manage(res); +} + +stat map_list::foreach(const std::function &fn) const +{ + struct fn_data { + std::function func; + } fn_data = { fn }; + auto fn_lambda = [](isl_map *arg_0, void *arg_1) -> isl_stat { + auto *data = static_cast(arg_1); + auto ret = (data->func)(manage(arg_0)); + return ret.release(); + }; + auto res = isl_map_list_foreach(get(), fn_lambda, &fn_data); + return manage(res); +} + +stat map_list::foreach_scc(const std::function &follows, const std::function &fn) const +{ + struct follows_data { + std::function func; + } follows_data = { follows }; + auto follows_lambda = [](isl_map *arg_0, isl_map *arg_1, void *arg_2) -> isl_bool { + auto *data = static_cast(arg_2); + auto ret = (data->func)(manage_copy(arg_0), manage_copy(arg_1)); + return ret.release(); + }; + struct fn_data { + std::function func; + } fn_data = { fn }; + auto fn_lambda = [](isl_map_list *arg_0, void *arg_1) -> isl_stat { + auto *data = static_cast(arg_1); + auto ret = (data->func)(manage(arg_0)); + return ret.release(); + }; + auto res = isl_map_list_foreach_scc(get(), follows_lambda, &follows_data, fn_lambda, &fn_data); + return manage(res); +} + +isl::checked::map_list map_list::insert(unsigned int pos, isl::checked::map el) const +{ + auto res = isl_map_list_insert(copy(), pos, el.release()); + return manage(res); +} + +isl::checked::map_list map_list::set_at(int index, isl::checked::map el) const +{ + auto res = isl_map_list_set_at(copy(), index, el.release()); + return manage(res); +} + +class size map_list::size() const +{ + auto res = isl_map_list_size(get()); + return manage(res); +} + +inline std::ostream &operator<<(std::ostream &os, const map_list &obj) +{ + char *str = isl_map_list_to_str(obj.get()); + if (!str) { + os.setstate(std::ios_base::badbit); + return os; + } + os << str; + free(str); + return os; +} + +// implementations for isl::multi_aff +multi_aff manage(__isl_take isl_multi_aff *ptr) { + return multi_aff(ptr); +} +multi_aff manage_copy(__isl_keep isl_multi_aff *ptr) { + ptr = isl_multi_aff_copy(ptr); + return multi_aff(ptr); +} + +multi_aff::multi_aff(__isl_take isl_multi_aff *ptr) + : ptr(ptr) {} + +multi_aff::multi_aff() + : ptr(nullptr) {} + +multi_aff::multi_aff(const multi_aff &obj) + : ptr(nullptr) +{ + ptr = obj.copy(); +} + +multi_aff::multi_aff(isl::checked::aff aff) +{ + auto res = isl_multi_aff_from_aff(aff.release()); + ptr = res; +} + +multi_aff::multi_aff(isl::checked::space space, isl::checked::aff_list list) +{ + auto res = isl_multi_aff_from_aff_list(space.release(), list.release()); + ptr = res; +} + +multi_aff::multi_aff(isl::checked::ctx ctx, const std::string &str) +{ + auto res = isl_multi_aff_read_from_str(ctx.release(), str.c_str()); + ptr = res; +} + +multi_aff &multi_aff::operator=(multi_aff obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +multi_aff::~multi_aff() { + if (ptr) + isl_multi_aff_free(ptr); +} + +__isl_give isl_multi_aff *multi_aff::copy() const & { + return isl_multi_aff_copy(ptr); +} + +__isl_keep isl_multi_aff *multi_aff::get() const { + return ptr; +} + +__isl_give isl_multi_aff *multi_aff::release() { + isl_multi_aff *tmp = ptr; + ptr = nullptr; + return tmp; +} + +bool multi_aff::is_null() const { + return ptr == nullptr; +} + +isl::checked::ctx multi_aff::ctx() const { + return isl::checked::ctx(isl_multi_aff_get_ctx(ptr)); +} + +isl::checked::multi_aff multi_aff::add(isl::checked::multi_aff multi2) const +{ + auto res = isl_multi_aff_add(copy(), multi2.release()); + return manage(res); +} + +isl::checked::multi_pw_aff multi_aff::add(const isl::checked::multi_pw_aff &multi2) const +{ + return isl::checked::pw_multi_aff(*this).add(multi2); +} + +isl::checked::multi_union_pw_aff multi_aff::add(const isl::checked::multi_union_pw_aff &multi2) const +{ + return isl::checked::pw_multi_aff(*this).add(multi2); +} + +isl::checked::pw_multi_aff multi_aff::add(const isl::checked::pw_multi_aff &pma2) const +{ + return isl::checked::pw_multi_aff(*this).add(pma2); +} + +isl::checked::union_pw_multi_aff multi_aff::add(const isl::checked::union_pw_multi_aff &upma2) const +{ + return isl::checked::pw_multi_aff(*this).add(upma2); +} + +isl::checked::multi_aff multi_aff::add(const isl::checked::aff &multi2) const +{ + return this->add(isl::checked::multi_aff(multi2)); +} + +isl::checked::multi_aff multi_aff::add_constant(isl::checked::multi_val mv) const +{ + auto res = isl_multi_aff_add_constant_multi_val(copy(), mv.release()); + return manage(res); +} + +isl::checked::multi_aff multi_aff::add_constant(isl::checked::val v) const +{ + auto res = isl_multi_aff_add_constant_val(copy(), v.release()); + return manage(res); +} + +isl::checked::multi_aff multi_aff::add_constant(long v) const +{ + return this->add_constant(isl::checked::val(ctx(), v)); +} + +isl::checked::union_pw_multi_aff multi_aff::apply(const isl::checked::union_pw_multi_aff &upma2) const +{ + return isl::checked::pw_multi_aff(*this).apply(upma2); +} + +isl::checked::map multi_aff::as_map() const +{ + auto res = isl_multi_aff_as_map(copy()); + return manage(res); +} + +isl::checked::multi_aff multi_aff::as_multi_aff() const +{ + return isl::checked::pw_multi_aff(*this).as_multi_aff(); +} + +isl::checked::multi_union_pw_aff multi_aff::as_multi_union_pw_aff() const +{ + return isl::checked::pw_multi_aff(*this).as_multi_union_pw_aff(); +} + +isl::checked::pw_multi_aff multi_aff::as_pw_multi_aff() const +{ + return isl::checked::pw_multi_aff(*this).as_pw_multi_aff(); +} + +isl::checked::set multi_aff::as_set() const +{ + auto res = isl_multi_aff_as_set(copy()); + return manage(res); +} + +isl::checked::union_map multi_aff::as_union_map() const +{ + return isl::checked::pw_multi_aff(*this).as_union_map(); +} + +isl::checked::aff multi_aff::at(int pos) const +{ + auto res = isl_multi_aff_get_at(get(), pos); + return manage(res); +} + +isl::checked::aff multi_aff::get_at(int pos) const +{ + return at(pos); +} + +isl::checked::basic_set multi_aff::bind(isl::checked::multi_id tuple) const +{ + auto res = isl_multi_aff_bind(copy(), tuple.release()); + return manage(res); +} + +isl::checked::multi_aff multi_aff::bind_domain(isl::checked::multi_id tuple) const +{ + auto res = isl_multi_aff_bind_domain(copy(), tuple.release()); + return manage(res); +} + +isl::checked::multi_aff multi_aff::bind_domain_wrapped_domain(isl::checked::multi_id tuple) const +{ + auto res = isl_multi_aff_bind_domain_wrapped_domain(copy(), tuple.release()); + return manage(res); +} + +isl::checked::pw_multi_aff multi_aff::coalesce() const +{ + return isl::checked::pw_multi_aff(*this).coalesce(); +} + +isl::checked::multi_val multi_aff::constant_multi_val() const +{ + auto res = isl_multi_aff_get_constant_multi_val(get()); + return manage(res); +} + +isl::checked::multi_val multi_aff::get_constant_multi_val() const +{ + return constant_multi_val(); +} + +isl::checked::set multi_aff::domain() const +{ + return isl::checked::pw_multi_aff(*this).domain(); +} + +isl::checked::multi_aff multi_aff::domain_map(isl::checked::space space) +{ + auto res = isl_multi_aff_domain_map(space.release()); + return manage(res); +} + +isl::checked::multi_aff multi_aff::domain_reverse() const +{ + auto res = isl_multi_aff_domain_reverse(copy()); + return manage(res); +} + +isl::checked::pw_multi_aff multi_aff::drop_unused_params() const +{ + return isl::checked::pw_multi_aff(*this).drop_unused_params(); +} + +isl::checked::pw_multi_aff multi_aff::extract_pw_multi_aff(const isl::checked::space &space) const +{ + return isl::checked::pw_multi_aff(*this).extract_pw_multi_aff(space); +} + +isl::checked::multi_aff multi_aff::flat_range_product(isl::checked::multi_aff multi2) const +{ + auto res = isl_multi_aff_flat_range_product(copy(), multi2.release()); + return manage(res); +} + +isl::checked::multi_pw_aff multi_aff::flat_range_product(const isl::checked::multi_pw_aff &multi2) const +{ + return isl::checked::pw_multi_aff(*this).flat_range_product(multi2); +} + +isl::checked::multi_union_pw_aff multi_aff::flat_range_product(const isl::checked::multi_union_pw_aff &multi2) const +{ + return isl::checked::pw_multi_aff(*this).flat_range_product(multi2); +} + +isl::checked::pw_multi_aff multi_aff::flat_range_product(const isl::checked::pw_multi_aff &pma2) const +{ + return isl::checked::pw_multi_aff(*this).flat_range_product(pma2); +} + +isl::checked::union_pw_multi_aff multi_aff::flat_range_product(const isl::checked::union_pw_multi_aff &upma2) const +{ + return isl::checked::pw_multi_aff(*this).flat_range_product(upma2); +} + +isl::checked::multi_aff multi_aff::flat_range_product(const isl::checked::aff &multi2) const +{ + return this->flat_range_product(isl::checked::multi_aff(multi2)); +} + +isl::checked::multi_aff multi_aff::floor() const +{ + auto res = isl_multi_aff_floor(copy()); + return manage(res); +} + +stat multi_aff::foreach_piece(const std::function &fn) const +{ + return isl::checked::pw_multi_aff(*this).foreach_piece(fn); +} + +isl::checked::multi_aff multi_aff::gist(isl::checked::set context) const +{ + auto res = isl_multi_aff_gist(copy(), context.release()); + return manage(res); +} + +isl::checked::union_pw_multi_aff multi_aff::gist(const isl::checked::union_set &context) const +{ + return isl::checked::pw_multi_aff(*this).gist(context); +} + +isl::checked::multi_aff multi_aff::gist(const isl::checked::basic_set &context) const +{ + return this->gist(isl::checked::set(context)); +} + +isl::checked::multi_aff multi_aff::gist(const isl::checked::point &context) const +{ + return this->gist(isl::checked::set(context)); +} + +isl::checked::multi_aff multi_aff::gist_params(isl::checked::set context) const +{ + auto res = isl_multi_aff_gist_params(copy(), context.release()); + return manage(res); +} + +boolean multi_aff::has_range_tuple_id() const +{ + auto res = isl_multi_aff_has_range_tuple_id(get()); + return manage(res); +} + +isl::checked::multi_aff multi_aff::identity() const +{ + auto res = isl_multi_aff_identity_multi_aff(copy()); + return manage(res); +} + +isl::checked::multi_aff multi_aff::identity_on_domain(isl::checked::space space) +{ + auto res = isl_multi_aff_identity_on_domain_space(space.release()); + return manage(res); +} + +isl::checked::multi_aff multi_aff::insert_domain(isl::checked::space domain) const +{ + auto res = isl_multi_aff_insert_domain(copy(), domain.release()); + return manage(res); +} + +isl::checked::pw_multi_aff multi_aff::intersect_domain(const isl::checked::set &set) const +{ + return isl::checked::pw_multi_aff(*this).intersect_domain(set); +} + +isl::checked::union_pw_multi_aff multi_aff::intersect_domain(const isl::checked::space &space) const +{ + return isl::checked::pw_multi_aff(*this).intersect_domain(space); +} + +isl::checked::union_pw_multi_aff multi_aff::intersect_domain(const isl::checked::union_set &uset) const +{ + return isl::checked::pw_multi_aff(*this).intersect_domain(uset); +} + +isl::checked::union_pw_multi_aff multi_aff::intersect_domain_wrapped_domain(const isl::checked::union_set &uset) const +{ + return isl::checked::pw_multi_aff(*this).intersect_domain_wrapped_domain(uset); +} + +isl::checked::union_pw_multi_aff multi_aff::intersect_domain_wrapped_range(const isl::checked::union_set &uset) const +{ + return isl::checked::pw_multi_aff(*this).intersect_domain_wrapped_range(uset); +} + +isl::checked::pw_multi_aff multi_aff::intersect_params(const isl::checked::set &set) const +{ + return isl::checked::pw_multi_aff(*this).intersect_params(set); +} + +boolean multi_aff::involves_locals() const +{ + auto res = isl_multi_aff_involves_locals(get()); + return manage(res); +} + +boolean multi_aff::involves_nan() const +{ + auto res = isl_multi_aff_involves_nan(get()); + return manage(res); +} + +boolean multi_aff::involves_param(const isl::checked::id &id) const +{ + return isl::checked::pw_multi_aff(*this).involves_param(id); +} + +boolean multi_aff::involves_param(const std::string &id) const +{ + return this->involves_param(isl::checked::id(ctx(), id)); +} + +boolean multi_aff::involves_param(const isl::checked::id_list &list) const +{ + return isl::checked::pw_multi_aff(*this).involves_param(list); +} + +boolean multi_aff::isa_multi_aff() const +{ + return isl::checked::pw_multi_aff(*this).isa_multi_aff(); +} + +boolean multi_aff::isa_pw_multi_aff() const +{ + return isl::checked::pw_multi_aff(*this).isa_pw_multi_aff(); +} + +isl::checked::aff_list multi_aff::list() const +{ + auto res = isl_multi_aff_get_list(get()); + return manage(res); +} + +isl::checked::aff_list multi_aff::get_list() const +{ + return list(); +} + +isl::checked::multi_pw_aff multi_aff::max(const isl::checked::multi_pw_aff &multi2) const +{ + return isl::checked::pw_multi_aff(*this).max(multi2); +} + +isl::checked::multi_val multi_aff::max_multi_val() const +{ + return isl::checked::pw_multi_aff(*this).max_multi_val(); +} + +isl::checked::multi_pw_aff multi_aff::min(const isl::checked::multi_pw_aff &multi2) const +{ + return isl::checked::pw_multi_aff(*this).min(multi2); +} + +isl::checked::multi_val multi_aff::min_multi_val() const +{ + return isl::checked::pw_multi_aff(*this).min_multi_val(); +} + +isl::checked::multi_aff multi_aff::multi_val_on_domain(isl::checked::space space, isl::checked::multi_val mv) +{ + auto res = isl_multi_aff_multi_val_on_domain_space(space.release(), mv.release()); + return manage(res); +} + +class size multi_aff::n_piece() const +{ + return isl::checked::pw_multi_aff(*this).n_piece(); +} + +isl::checked::multi_aff multi_aff::neg() const +{ + auto res = isl_multi_aff_neg(copy()); + return manage(res); +} + +boolean multi_aff::plain_is_empty() const +{ + return isl::checked::pw_multi_aff(*this).plain_is_empty(); +} + +boolean multi_aff::plain_is_equal(const isl::checked::multi_aff &multi2) const +{ + auto res = isl_multi_aff_plain_is_equal(get(), multi2.get()); + return manage(res); +} + +boolean multi_aff::plain_is_equal(const isl::checked::multi_pw_aff &multi2) const +{ + return isl::checked::pw_multi_aff(*this).plain_is_equal(multi2); +} + +boolean multi_aff::plain_is_equal(const isl::checked::multi_union_pw_aff &multi2) const +{ + return isl::checked::pw_multi_aff(*this).plain_is_equal(multi2); +} + +boolean multi_aff::plain_is_equal(const isl::checked::pw_multi_aff &pma2) const +{ + return isl::checked::pw_multi_aff(*this).plain_is_equal(pma2); +} + +boolean multi_aff::plain_is_equal(const isl::checked::union_pw_multi_aff &upma2) const +{ + return isl::checked::pw_multi_aff(*this).plain_is_equal(upma2); +} + +boolean multi_aff::plain_is_equal(const isl::checked::aff &multi2) const +{ + return this->plain_is_equal(isl::checked::multi_aff(multi2)); +} + +isl::checked::pw_multi_aff multi_aff::preimage_domain_wrapped_domain(const isl::checked::pw_multi_aff &pma2) const +{ + return isl::checked::pw_multi_aff(*this).preimage_domain_wrapped_domain(pma2); +} + +isl::checked::union_pw_multi_aff multi_aff::preimage_domain_wrapped_domain(const isl::checked::union_pw_multi_aff &upma2) const +{ + return isl::checked::pw_multi_aff(*this).preimage_domain_wrapped_domain(upma2); +} + +isl::checked::multi_aff multi_aff::product(isl::checked::multi_aff multi2) const +{ + auto res = isl_multi_aff_product(copy(), multi2.release()); + return manage(res); +} + +isl::checked::multi_pw_aff multi_aff::product(const isl::checked::multi_pw_aff &multi2) const +{ + return isl::checked::pw_multi_aff(*this).product(multi2); +} + +isl::checked::pw_multi_aff multi_aff::product(const isl::checked::pw_multi_aff &pma2) const +{ + return isl::checked::pw_multi_aff(*this).product(pma2); +} + +isl::checked::multi_aff multi_aff::product(const isl::checked::aff &multi2) const +{ + return this->product(isl::checked::multi_aff(multi2)); +} + +isl::checked::multi_aff multi_aff::pullback(isl::checked::multi_aff ma2) const +{ + auto res = isl_multi_aff_pullback_multi_aff(copy(), ma2.release()); + return manage(res); +} + +isl::checked::multi_pw_aff multi_aff::pullback(const isl::checked::multi_pw_aff &mpa2) const +{ + return isl::checked::pw_multi_aff(*this).pullback(mpa2); +} + +isl::checked::pw_multi_aff multi_aff::pullback(const isl::checked::pw_multi_aff &pma2) const +{ + return isl::checked::pw_multi_aff(*this).pullback(pma2); +} + +isl::checked::union_pw_multi_aff multi_aff::pullback(const isl::checked::union_pw_multi_aff &upma2) const +{ + return isl::checked::pw_multi_aff(*this).pullback(upma2); +} + +isl::checked::multi_aff multi_aff::pullback(const isl::checked::aff &ma2) const +{ + return this->pullback(isl::checked::multi_aff(ma2)); +} + +isl::checked::pw_multi_aff_list multi_aff::pw_multi_aff_list() const +{ + return isl::checked::pw_multi_aff(*this).pw_multi_aff_list(); +} + +isl::checked::pw_multi_aff multi_aff::range_factor_domain() const +{ + return isl::checked::pw_multi_aff(*this).range_factor_domain(); +} + +isl::checked::pw_multi_aff multi_aff::range_factor_range() const +{ + return isl::checked::pw_multi_aff(*this).range_factor_range(); +} + +isl::checked::multi_aff multi_aff::range_map(isl::checked::space space) +{ + auto res = isl_multi_aff_range_map(space.release()); + return manage(res); +} + +isl::checked::multi_aff multi_aff::range_product(isl::checked::multi_aff multi2) const +{ + auto res = isl_multi_aff_range_product(copy(), multi2.release()); + return manage(res); +} + +isl::checked::multi_pw_aff multi_aff::range_product(const isl::checked::multi_pw_aff &multi2) const +{ + return isl::checked::pw_multi_aff(*this).range_product(multi2); +} + +isl::checked::multi_union_pw_aff multi_aff::range_product(const isl::checked::multi_union_pw_aff &multi2) const +{ + return isl::checked::pw_multi_aff(*this).range_product(multi2); +} + +isl::checked::pw_multi_aff multi_aff::range_product(const isl::checked::pw_multi_aff &pma2) const +{ + return isl::checked::pw_multi_aff(*this).range_product(pma2); +} + +isl::checked::union_pw_multi_aff multi_aff::range_product(const isl::checked::union_pw_multi_aff &upma2) const +{ + return isl::checked::pw_multi_aff(*this).range_product(upma2); +} + +isl::checked::multi_aff multi_aff::range_product(const isl::checked::aff &multi2) const +{ + return this->range_product(isl::checked::multi_aff(multi2)); +} + +isl::checked::id multi_aff::range_tuple_id() const +{ + auto res = isl_multi_aff_get_range_tuple_id(get()); + return manage(res); +} + +isl::checked::id multi_aff::get_range_tuple_id() const +{ + return range_tuple_id(); +} + +isl::checked::multi_aff multi_aff::reset_range_tuple_id() const +{ + auto res = isl_multi_aff_reset_range_tuple_id(copy()); + return manage(res); +} + +isl::checked::multi_aff multi_aff::scale(isl::checked::multi_val mv) const +{ + auto res = isl_multi_aff_scale_multi_val(copy(), mv.release()); + return manage(res); +} + +isl::checked::multi_aff multi_aff::scale(isl::checked::val v) const +{ + auto res = isl_multi_aff_scale_val(copy(), v.release()); + return manage(res); +} + +isl::checked::multi_aff multi_aff::scale(long v) const +{ + return this->scale(isl::checked::val(ctx(), v)); +} + +isl::checked::multi_aff multi_aff::scale_down(isl::checked::multi_val mv) const +{ + auto res = isl_multi_aff_scale_down_multi_val(copy(), mv.release()); + return manage(res); +} + +isl::checked::multi_aff multi_aff::scale_down(isl::checked::val v) const +{ + auto res = isl_multi_aff_scale_down_val(copy(), v.release()); + return manage(res); +} + +isl::checked::multi_aff multi_aff::scale_down(long v) const +{ + return this->scale_down(isl::checked::val(ctx(), v)); +} + +isl::checked::multi_aff multi_aff::set_at(int pos, isl::checked::aff el) const +{ + auto res = isl_multi_aff_set_at(copy(), pos, el.release()); + return manage(res); +} + +isl::checked::multi_pw_aff multi_aff::set_at(int pos, const isl::checked::pw_aff &el) const +{ + return isl::checked::pw_multi_aff(*this).set_at(pos, el); +} + +isl::checked::multi_union_pw_aff multi_aff::set_at(int pos, const isl::checked::union_pw_aff &el) const +{ + return isl::checked::pw_multi_aff(*this).set_at(pos, el); +} + +isl::checked::multi_aff multi_aff::set_range_tuple(isl::checked::id id) const +{ + auto res = isl_multi_aff_set_range_tuple_id(copy(), id.release()); + return manage(res); +} + +isl::checked::multi_aff multi_aff::set_range_tuple(const std::string &id) const +{ + return this->set_range_tuple(isl::checked::id(ctx(), id)); +} + +class size multi_aff::size() const +{ + auto res = isl_multi_aff_size(get()); + return manage(res); +} + +isl::checked::space multi_aff::space() const +{ + auto res = isl_multi_aff_get_space(get()); + return manage(res); +} + +isl::checked::space multi_aff::get_space() const +{ + return space(); +} + +isl::checked::multi_aff multi_aff::sub(isl::checked::multi_aff multi2) const +{ + auto res = isl_multi_aff_sub(copy(), multi2.release()); + return manage(res); +} + +isl::checked::multi_pw_aff multi_aff::sub(const isl::checked::multi_pw_aff &multi2) const +{ + return isl::checked::pw_multi_aff(*this).sub(multi2); +} + +isl::checked::multi_union_pw_aff multi_aff::sub(const isl::checked::multi_union_pw_aff &multi2) const +{ + return isl::checked::pw_multi_aff(*this).sub(multi2); +} + +isl::checked::pw_multi_aff multi_aff::sub(const isl::checked::pw_multi_aff &pma2) const +{ + return isl::checked::pw_multi_aff(*this).sub(pma2); +} + +isl::checked::union_pw_multi_aff multi_aff::sub(const isl::checked::union_pw_multi_aff &upma2) const +{ + return isl::checked::pw_multi_aff(*this).sub(upma2); +} + +isl::checked::multi_aff multi_aff::sub(const isl::checked::aff &multi2) const +{ + return this->sub(isl::checked::multi_aff(multi2)); +} + +isl::checked::pw_multi_aff multi_aff::subtract_domain(const isl::checked::set &set) const +{ + return isl::checked::pw_multi_aff(*this).subtract_domain(set); +} + +isl::checked::union_pw_multi_aff multi_aff::subtract_domain(const isl::checked::space &space) const +{ + return isl::checked::pw_multi_aff(*this).subtract_domain(space); +} + +isl::checked::union_pw_multi_aff multi_aff::subtract_domain(const isl::checked::union_set &uset) const +{ + return isl::checked::pw_multi_aff(*this).subtract_domain(uset); +} + +isl::checked::pw_multi_aff_list multi_aff::to_list() const +{ + return isl::checked::pw_multi_aff(*this).to_list(); +} + +isl::checked::multi_pw_aff multi_aff::to_multi_pw_aff() const +{ + auto res = isl_multi_aff_to_multi_pw_aff(copy()); + return manage(res); +} + +isl::checked::multi_union_pw_aff multi_aff::to_multi_union_pw_aff() const +{ + auto res = isl_multi_aff_to_multi_union_pw_aff(copy()); + return manage(res); +} + +isl::checked::pw_multi_aff multi_aff::to_pw_multi_aff() const +{ + auto res = isl_multi_aff_to_pw_multi_aff(copy()); + return manage(res); +} + +isl::checked::union_pw_multi_aff multi_aff::to_union_pw_multi_aff() const +{ + return isl::checked::pw_multi_aff(*this).to_union_pw_multi_aff(); +} + +isl::checked::multi_aff multi_aff::unbind_params_insert_domain(isl::checked::multi_id domain) const +{ + auto res = isl_multi_aff_unbind_params_insert_domain(copy(), domain.release()); + return manage(res); +} + +isl::checked::multi_pw_aff multi_aff::union_add(const isl::checked::multi_pw_aff &mpa2) const +{ + return isl::checked::pw_multi_aff(*this).union_add(mpa2); +} + +isl::checked::multi_union_pw_aff multi_aff::union_add(const isl::checked::multi_union_pw_aff &mupa2) const +{ + return isl::checked::pw_multi_aff(*this).union_add(mupa2); +} + +isl::checked::pw_multi_aff multi_aff::union_add(const isl::checked::pw_multi_aff &pma2) const +{ + return isl::checked::pw_multi_aff(*this).union_add(pma2); +} + +isl::checked::union_pw_multi_aff multi_aff::union_add(const isl::checked::union_pw_multi_aff &upma2) const +{ + return isl::checked::pw_multi_aff(*this).union_add(upma2); +} + +isl::checked::multi_aff multi_aff::zero(isl::checked::space space) +{ + auto res = isl_multi_aff_zero(space.release()); + return manage(res); +} + +inline std::ostream &operator<<(std::ostream &os, const multi_aff &obj) +{ + char *str = isl_multi_aff_to_str(obj.get()); + if (!str) { + os.setstate(std::ios_base::badbit); + return os; + } + os << str; + free(str); + return os; +} + +// implementations for isl::multi_id +multi_id manage(__isl_take isl_multi_id *ptr) { + return multi_id(ptr); +} +multi_id manage_copy(__isl_keep isl_multi_id *ptr) { + ptr = isl_multi_id_copy(ptr); + return multi_id(ptr); +} + +multi_id::multi_id(__isl_take isl_multi_id *ptr) + : ptr(ptr) {} + +multi_id::multi_id() + : ptr(nullptr) {} + +multi_id::multi_id(const multi_id &obj) + : ptr(nullptr) +{ + ptr = obj.copy(); +} + +multi_id::multi_id(isl::checked::space space, isl::checked::id_list list) +{ + auto res = isl_multi_id_from_id_list(space.release(), list.release()); + ptr = res; +} + +multi_id::multi_id(isl::checked::ctx ctx, const std::string &str) +{ + auto res = isl_multi_id_read_from_str(ctx.release(), str.c_str()); + ptr = res; +} + +multi_id &multi_id::operator=(multi_id obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +multi_id::~multi_id() { + if (ptr) + isl_multi_id_free(ptr); +} + +__isl_give isl_multi_id *multi_id::copy() const & { + return isl_multi_id_copy(ptr); +} + +__isl_keep isl_multi_id *multi_id::get() const { + return ptr; +} + +__isl_give isl_multi_id *multi_id::release() { + isl_multi_id *tmp = ptr; + ptr = nullptr; + return tmp; +} + +bool multi_id::is_null() const { + return ptr == nullptr; +} + +isl::checked::ctx multi_id::ctx() const { + return isl::checked::ctx(isl_multi_id_get_ctx(ptr)); +} + +isl::checked::id multi_id::at(int pos) const +{ + auto res = isl_multi_id_get_at(get(), pos); + return manage(res); +} + +isl::checked::id multi_id::get_at(int pos) const +{ + return at(pos); +} + +isl::checked::multi_id multi_id::flat_range_product(isl::checked::multi_id multi2) const +{ + auto res = isl_multi_id_flat_range_product(copy(), multi2.release()); + return manage(res); +} + +isl::checked::id_list multi_id::list() const +{ + auto res = isl_multi_id_get_list(get()); + return manage(res); +} + +isl::checked::id_list multi_id::get_list() const +{ + return list(); +} + +boolean multi_id::plain_is_equal(const isl::checked::multi_id &multi2) const +{ + auto res = isl_multi_id_plain_is_equal(get(), multi2.get()); + return manage(res); +} + +isl::checked::multi_id multi_id::range_product(isl::checked::multi_id multi2) const +{ + auto res = isl_multi_id_range_product(copy(), multi2.release()); + return manage(res); +} + +isl::checked::multi_id multi_id::set_at(int pos, isl::checked::id el) const +{ + auto res = isl_multi_id_set_at(copy(), pos, el.release()); + return manage(res); +} + +isl::checked::multi_id multi_id::set_at(int pos, const std::string &el) const +{ + return this->set_at(pos, isl::checked::id(ctx(), el)); +} + +class size multi_id::size() const +{ + auto res = isl_multi_id_size(get()); + return manage(res); +} + +isl::checked::space multi_id::space() const +{ + auto res = isl_multi_id_get_space(get()); + return manage(res); +} + +isl::checked::space multi_id::get_space() const +{ + return space(); +} + +inline std::ostream &operator<<(std::ostream &os, const multi_id &obj) +{ + char *str = isl_multi_id_to_str(obj.get()); + if (!str) { + os.setstate(std::ios_base::badbit); + return os; + } + os << str; + free(str); + return os; +} + +// implementations for isl::multi_pw_aff +multi_pw_aff manage(__isl_take isl_multi_pw_aff *ptr) { + return multi_pw_aff(ptr); +} +multi_pw_aff manage_copy(__isl_keep isl_multi_pw_aff *ptr) { + ptr = isl_multi_pw_aff_copy(ptr); + return multi_pw_aff(ptr); +} + +multi_pw_aff::multi_pw_aff(__isl_take isl_multi_pw_aff *ptr) + : ptr(ptr) {} + +multi_pw_aff::multi_pw_aff() + : ptr(nullptr) {} + +multi_pw_aff::multi_pw_aff(const multi_pw_aff &obj) + : ptr(nullptr) +{ + ptr = obj.copy(); +} + +multi_pw_aff::multi_pw_aff(isl::checked::aff aff) +{ + auto res = isl_multi_pw_aff_from_aff(aff.release()); + ptr = res; +} + +multi_pw_aff::multi_pw_aff(isl::checked::multi_aff ma) +{ + auto res = isl_multi_pw_aff_from_multi_aff(ma.release()); + ptr = res; +} + +multi_pw_aff::multi_pw_aff(isl::checked::pw_aff pa) +{ + auto res = isl_multi_pw_aff_from_pw_aff(pa.release()); + ptr = res; +} + +multi_pw_aff::multi_pw_aff(isl::checked::space space, isl::checked::pw_aff_list list) +{ + auto res = isl_multi_pw_aff_from_pw_aff_list(space.release(), list.release()); + ptr = res; +} + +multi_pw_aff::multi_pw_aff(isl::checked::pw_multi_aff pma) +{ + auto res = isl_multi_pw_aff_from_pw_multi_aff(pma.release()); + ptr = res; +} + +multi_pw_aff::multi_pw_aff(isl::checked::ctx ctx, const std::string &str) +{ + auto res = isl_multi_pw_aff_read_from_str(ctx.release(), str.c_str()); + ptr = res; +} + +multi_pw_aff &multi_pw_aff::operator=(multi_pw_aff obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +multi_pw_aff::~multi_pw_aff() { + if (ptr) + isl_multi_pw_aff_free(ptr); +} + +__isl_give isl_multi_pw_aff *multi_pw_aff::copy() const & { + return isl_multi_pw_aff_copy(ptr); +} + +__isl_keep isl_multi_pw_aff *multi_pw_aff::get() const { + return ptr; +} + +__isl_give isl_multi_pw_aff *multi_pw_aff::release() { + isl_multi_pw_aff *tmp = ptr; + ptr = nullptr; + return tmp; +} + +bool multi_pw_aff::is_null() const { + return ptr == nullptr; +} + +isl::checked::ctx multi_pw_aff::ctx() const { + return isl::checked::ctx(isl_multi_pw_aff_get_ctx(ptr)); +} + +isl::checked::multi_pw_aff multi_pw_aff::add(isl::checked::multi_pw_aff multi2) const +{ + auto res = isl_multi_pw_aff_add(copy(), multi2.release()); + return manage(res); +} + +isl::checked::multi_union_pw_aff multi_pw_aff::add(const isl::checked::multi_union_pw_aff &multi2) const +{ + return isl::checked::multi_union_pw_aff(*this).add(multi2); +} + +isl::checked::multi_pw_aff multi_pw_aff::add(const isl::checked::aff &multi2) const +{ + return this->add(isl::checked::multi_pw_aff(multi2)); +} + +isl::checked::multi_pw_aff multi_pw_aff::add(const isl::checked::multi_aff &multi2) const +{ + return this->add(isl::checked::multi_pw_aff(multi2)); +} + +isl::checked::multi_pw_aff multi_pw_aff::add(const isl::checked::pw_aff &multi2) const +{ + return this->add(isl::checked::multi_pw_aff(multi2)); +} + +isl::checked::multi_pw_aff multi_pw_aff::add(const isl::checked::pw_multi_aff &multi2) const +{ + return this->add(isl::checked::multi_pw_aff(multi2)); +} + +isl::checked::multi_pw_aff multi_pw_aff::add_constant(isl::checked::multi_val mv) const +{ + auto res = isl_multi_pw_aff_add_constant_multi_val(copy(), mv.release()); + return manage(res); +} + +isl::checked::multi_pw_aff multi_pw_aff::add_constant(isl::checked::val v) const +{ + auto res = isl_multi_pw_aff_add_constant_val(copy(), v.release()); + return manage(res); +} + +isl::checked::multi_pw_aff multi_pw_aff::add_constant(long v) const +{ + return this->add_constant(isl::checked::val(ctx(), v)); +} + +isl::checked::map multi_pw_aff::as_map() const +{ + auto res = isl_multi_pw_aff_as_map(copy()); + return manage(res); +} + +isl::checked::multi_aff multi_pw_aff::as_multi_aff() const +{ + auto res = isl_multi_pw_aff_as_multi_aff(copy()); + return manage(res); +} + +isl::checked::set multi_pw_aff::as_set() const +{ + auto res = isl_multi_pw_aff_as_set(copy()); + return manage(res); +} + +isl::checked::pw_aff multi_pw_aff::at(int pos) const +{ + auto res = isl_multi_pw_aff_get_at(get(), pos); + return manage(res); +} + +isl::checked::pw_aff multi_pw_aff::get_at(int pos) const +{ + return at(pos); +} + +isl::checked::set multi_pw_aff::bind(isl::checked::multi_id tuple) const +{ + auto res = isl_multi_pw_aff_bind(copy(), tuple.release()); + return manage(res); +} + +isl::checked::multi_pw_aff multi_pw_aff::bind_domain(isl::checked::multi_id tuple) const +{ + auto res = isl_multi_pw_aff_bind_domain(copy(), tuple.release()); + return manage(res); +} + +isl::checked::multi_pw_aff multi_pw_aff::bind_domain_wrapped_domain(isl::checked::multi_id tuple) const +{ + auto res = isl_multi_pw_aff_bind_domain_wrapped_domain(copy(), tuple.release()); + return manage(res); +} + +isl::checked::multi_pw_aff multi_pw_aff::coalesce() const +{ + auto res = isl_multi_pw_aff_coalesce(copy()); + return manage(res); +} + +isl::checked::set multi_pw_aff::domain() const +{ + auto res = isl_multi_pw_aff_domain(copy()); + return manage(res); +} + +isl::checked::multi_pw_aff multi_pw_aff::domain_reverse() const +{ + auto res = isl_multi_pw_aff_domain_reverse(copy()); + return manage(res); +} + +isl::checked::multi_pw_aff multi_pw_aff::flat_range_product(isl::checked::multi_pw_aff multi2) const +{ + auto res = isl_multi_pw_aff_flat_range_product(copy(), multi2.release()); + return manage(res); +} + +isl::checked::multi_union_pw_aff multi_pw_aff::flat_range_product(const isl::checked::multi_union_pw_aff &multi2) const +{ + return isl::checked::multi_union_pw_aff(*this).flat_range_product(multi2); +} + +isl::checked::multi_pw_aff multi_pw_aff::flat_range_product(const isl::checked::aff &multi2) const +{ + return this->flat_range_product(isl::checked::multi_pw_aff(multi2)); +} + +isl::checked::multi_pw_aff multi_pw_aff::flat_range_product(const isl::checked::multi_aff &multi2) const +{ + return this->flat_range_product(isl::checked::multi_pw_aff(multi2)); +} + +isl::checked::multi_pw_aff multi_pw_aff::flat_range_product(const isl::checked::pw_aff &multi2) const +{ + return this->flat_range_product(isl::checked::multi_pw_aff(multi2)); +} + +isl::checked::multi_pw_aff multi_pw_aff::flat_range_product(const isl::checked::pw_multi_aff &multi2) const +{ + return this->flat_range_product(isl::checked::multi_pw_aff(multi2)); +} + +isl::checked::multi_pw_aff multi_pw_aff::gist(isl::checked::set set) const +{ + auto res = isl_multi_pw_aff_gist(copy(), set.release()); + return manage(res); +} + +isl::checked::multi_union_pw_aff multi_pw_aff::gist(const isl::checked::union_set &context) const +{ + return isl::checked::multi_union_pw_aff(*this).gist(context); +} + +isl::checked::multi_pw_aff multi_pw_aff::gist(const isl::checked::basic_set &set) const +{ + return this->gist(isl::checked::set(set)); +} + +isl::checked::multi_pw_aff multi_pw_aff::gist(const isl::checked::point &set) const +{ + return this->gist(isl::checked::set(set)); +} + +isl::checked::multi_pw_aff multi_pw_aff::gist_params(isl::checked::set set) const +{ + auto res = isl_multi_pw_aff_gist_params(copy(), set.release()); + return manage(res); +} + +boolean multi_pw_aff::has_range_tuple_id() const +{ + auto res = isl_multi_pw_aff_has_range_tuple_id(get()); + return manage(res); +} + +isl::checked::multi_pw_aff multi_pw_aff::identity() const +{ + auto res = isl_multi_pw_aff_identity_multi_pw_aff(copy()); + return manage(res); +} + +isl::checked::multi_pw_aff multi_pw_aff::identity_on_domain(isl::checked::space space) +{ + auto res = isl_multi_pw_aff_identity_on_domain_space(space.release()); + return manage(res); +} + +isl::checked::multi_pw_aff multi_pw_aff::insert_domain(isl::checked::space domain) const +{ + auto res = isl_multi_pw_aff_insert_domain(copy(), domain.release()); + return manage(res); +} + +isl::checked::multi_pw_aff multi_pw_aff::intersect_domain(isl::checked::set domain) const +{ + auto res = isl_multi_pw_aff_intersect_domain(copy(), domain.release()); + return manage(res); +} + +isl::checked::multi_union_pw_aff multi_pw_aff::intersect_domain(const isl::checked::union_set &uset) const +{ + return isl::checked::multi_union_pw_aff(*this).intersect_domain(uset); +} + +isl::checked::multi_pw_aff multi_pw_aff::intersect_domain(const isl::checked::basic_set &domain) const +{ + return this->intersect_domain(isl::checked::set(domain)); +} + +isl::checked::multi_pw_aff multi_pw_aff::intersect_domain(const isl::checked::point &domain) const +{ + return this->intersect_domain(isl::checked::set(domain)); +} + +isl::checked::multi_pw_aff multi_pw_aff::intersect_params(isl::checked::set set) const +{ + auto res = isl_multi_pw_aff_intersect_params(copy(), set.release()); + return manage(res); +} + +boolean multi_pw_aff::involves_nan() const +{ + auto res = isl_multi_pw_aff_involves_nan(get()); + return manage(res); +} + +boolean multi_pw_aff::involves_param(const isl::checked::id &id) const +{ + auto res = isl_multi_pw_aff_involves_param_id(get(), id.get()); + return manage(res); +} + +boolean multi_pw_aff::involves_param(const std::string &id) const +{ + return this->involves_param(isl::checked::id(ctx(), id)); +} + +boolean multi_pw_aff::involves_param(const isl::checked::id_list &list) const +{ + auto res = isl_multi_pw_aff_involves_param_id_list(get(), list.get()); + return manage(res); +} + +boolean multi_pw_aff::isa_multi_aff() const +{ + auto res = isl_multi_pw_aff_isa_multi_aff(get()); + return manage(res); +} + +isl::checked::pw_aff_list multi_pw_aff::list() const +{ + auto res = isl_multi_pw_aff_get_list(get()); + return manage(res); +} + +isl::checked::pw_aff_list multi_pw_aff::get_list() const +{ + return list(); +} + +isl::checked::multi_pw_aff multi_pw_aff::max(isl::checked::multi_pw_aff multi2) const +{ + auto res = isl_multi_pw_aff_max(copy(), multi2.release()); + return manage(res); +} + +isl::checked::multi_val multi_pw_aff::max_multi_val() const +{ + auto res = isl_multi_pw_aff_max_multi_val(copy()); + return manage(res); +} + +isl::checked::multi_pw_aff multi_pw_aff::min(isl::checked::multi_pw_aff multi2) const +{ + auto res = isl_multi_pw_aff_min(copy(), multi2.release()); + return manage(res); +} + +isl::checked::multi_val multi_pw_aff::min_multi_val() const +{ + auto res = isl_multi_pw_aff_min_multi_val(copy()); + return manage(res); +} + +isl::checked::multi_pw_aff multi_pw_aff::neg() const +{ + auto res = isl_multi_pw_aff_neg(copy()); + return manage(res); +} + +boolean multi_pw_aff::plain_is_equal(const isl::checked::multi_pw_aff &multi2) const +{ + auto res = isl_multi_pw_aff_plain_is_equal(get(), multi2.get()); + return manage(res); +} + +boolean multi_pw_aff::plain_is_equal(const isl::checked::multi_union_pw_aff &multi2) const +{ + return isl::checked::multi_union_pw_aff(*this).plain_is_equal(multi2); +} + +boolean multi_pw_aff::plain_is_equal(const isl::checked::aff &multi2) const +{ + return this->plain_is_equal(isl::checked::multi_pw_aff(multi2)); +} + +boolean multi_pw_aff::plain_is_equal(const isl::checked::multi_aff &multi2) const +{ + return this->plain_is_equal(isl::checked::multi_pw_aff(multi2)); +} + +boolean multi_pw_aff::plain_is_equal(const isl::checked::pw_aff &multi2) const +{ + return this->plain_is_equal(isl::checked::multi_pw_aff(multi2)); +} + +boolean multi_pw_aff::plain_is_equal(const isl::checked::pw_multi_aff &multi2) const +{ + return this->plain_is_equal(isl::checked::multi_pw_aff(multi2)); +} + +isl::checked::multi_pw_aff multi_pw_aff::product(isl::checked::multi_pw_aff multi2) const +{ + auto res = isl_multi_pw_aff_product(copy(), multi2.release()); + return manage(res); +} + +isl::checked::multi_pw_aff multi_pw_aff::pullback(isl::checked::multi_aff ma) const +{ + auto res = isl_multi_pw_aff_pullback_multi_aff(copy(), ma.release()); + return manage(res); +} + +isl::checked::multi_pw_aff multi_pw_aff::pullback(isl::checked::multi_pw_aff mpa2) const +{ + auto res = isl_multi_pw_aff_pullback_multi_pw_aff(copy(), mpa2.release()); + return manage(res); +} + +isl::checked::multi_pw_aff multi_pw_aff::pullback(isl::checked::pw_multi_aff pma) const +{ + auto res = isl_multi_pw_aff_pullback_pw_multi_aff(copy(), pma.release()); + return manage(res); +} + +isl::checked::multi_union_pw_aff multi_pw_aff::pullback(const isl::checked::union_pw_multi_aff &upma) const +{ + return isl::checked::multi_union_pw_aff(*this).pullback(upma); +} + +isl::checked::multi_pw_aff multi_pw_aff::range_product(isl::checked::multi_pw_aff multi2) const +{ + auto res = isl_multi_pw_aff_range_product(copy(), multi2.release()); + return manage(res); +} + +isl::checked::multi_union_pw_aff multi_pw_aff::range_product(const isl::checked::multi_union_pw_aff &multi2) const +{ + return isl::checked::multi_union_pw_aff(*this).range_product(multi2); +} + +isl::checked::multi_pw_aff multi_pw_aff::range_product(const isl::checked::aff &multi2) const +{ + return this->range_product(isl::checked::multi_pw_aff(multi2)); +} + +isl::checked::multi_pw_aff multi_pw_aff::range_product(const isl::checked::multi_aff &multi2) const +{ + return this->range_product(isl::checked::multi_pw_aff(multi2)); +} + +isl::checked::multi_pw_aff multi_pw_aff::range_product(const isl::checked::pw_aff &multi2) const +{ + return this->range_product(isl::checked::multi_pw_aff(multi2)); +} + +isl::checked::multi_pw_aff multi_pw_aff::range_product(const isl::checked::pw_multi_aff &multi2) const +{ + return this->range_product(isl::checked::multi_pw_aff(multi2)); +} + +isl::checked::id multi_pw_aff::range_tuple_id() const +{ + auto res = isl_multi_pw_aff_get_range_tuple_id(get()); + return manage(res); +} + +isl::checked::id multi_pw_aff::get_range_tuple_id() const +{ + return range_tuple_id(); +} + +isl::checked::multi_pw_aff multi_pw_aff::reset_range_tuple_id() const +{ + auto res = isl_multi_pw_aff_reset_range_tuple_id(copy()); + return manage(res); +} + +isl::checked::multi_pw_aff multi_pw_aff::scale(isl::checked::multi_val mv) const +{ + auto res = isl_multi_pw_aff_scale_multi_val(copy(), mv.release()); + return manage(res); +} + +isl::checked::multi_pw_aff multi_pw_aff::scale(isl::checked::val v) const +{ + auto res = isl_multi_pw_aff_scale_val(copy(), v.release()); + return manage(res); +} + +isl::checked::multi_pw_aff multi_pw_aff::scale(long v) const +{ + return this->scale(isl::checked::val(ctx(), v)); +} + +isl::checked::multi_pw_aff multi_pw_aff::scale_down(isl::checked::multi_val mv) const +{ + auto res = isl_multi_pw_aff_scale_down_multi_val(copy(), mv.release()); + return manage(res); +} + +isl::checked::multi_pw_aff multi_pw_aff::scale_down(isl::checked::val v) const +{ + auto res = isl_multi_pw_aff_scale_down_val(copy(), v.release()); + return manage(res); +} + +isl::checked::multi_pw_aff multi_pw_aff::scale_down(long v) const +{ + return this->scale_down(isl::checked::val(ctx(), v)); +} + +isl::checked::multi_pw_aff multi_pw_aff::set_at(int pos, isl::checked::pw_aff el) const +{ + auto res = isl_multi_pw_aff_set_at(copy(), pos, el.release()); + return manage(res); +} + +isl::checked::multi_union_pw_aff multi_pw_aff::set_at(int pos, const isl::checked::union_pw_aff &el) const +{ + return isl::checked::multi_union_pw_aff(*this).set_at(pos, el); +} + +isl::checked::multi_pw_aff multi_pw_aff::set_range_tuple(isl::checked::id id) const +{ + auto res = isl_multi_pw_aff_set_range_tuple_id(copy(), id.release()); + return manage(res); +} + +isl::checked::multi_pw_aff multi_pw_aff::set_range_tuple(const std::string &id) const +{ + return this->set_range_tuple(isl::checked::id(ctx(), id)); +} + +class size multi_pw_aff::size() const +{ + auto res = isl_multi_pw_aff_size(get()); + return manage(res); +} + +isl::checked::space multi_pw_aff::space() const +{ + auto res = isl_multi_pw_aff_get_space(get()); + return manage(res); +} + +isl::checked::space multi_pw_aff::get_space() const +{ + return space(); +} + +isl::checked::multi_pw_aff multi_pw_aff::sub(isl::checked::multi_pw_aff multi2) const +{ + auto res = isl_multi_pw_aff_sub(copy(), multi2.release()); + return manage(res); +} + +isl::checked::multi_union_pw_aff multi_pw_aff::sub(const isl::checked::multi_union_pw_aff &multi2) const +{ + return isl::checked::multi_union_pw_aff(*this).sub(multi2); +} + +isl::checked::multi_pw_aff multi_pw_aff::sub(const isl::checked::aff &multi2) const +{ + return this->sub(isl::checked::multi_pw_aff(multi2)); +} + +isl::checked::multi_pw_aff multi_pw_aff::sub(const isl::checked::multi_aff &multi2) const +{ + return this->sub(isl::checked::multi_pw_aff(multi2)); +} + +isl::checked::multi_pw_aff multi_pw_aff::sub(const isl::checked::pw_aff &multi2) const +{ + return this->sub(isl::checked::multi_pw_aff(multi2)); +} + +isl::checked::multi_pw_aff multi_pw_aff::sub(const isl::checked::pw_multi_aff &multi2) const +{ + return this->sub(isl::checked::multi_pw_aff(multi2)); +} + +isl::checked::multi_pw_aff multi_pw_aff::unbind_params_insert_domain(isl::checked::multi_id domain) const +{ + auto res = isl_multi_pw_aff_unbind_params_insert_domain(copy(), domain.release()); + return manage(res); +} + +isl::checked::multi_pw_aff multi_pw_aff::union_add(isl::checked::multi_pw_aff mpa2) const +{ + auto res = isl_multi_pw_aff_union_add(copy(), mpa2.release()); + return manage(res); +} + +isl::checked::multi_union_pw_aff multi_pw_aff::union_add(const isl::checked::multi_union_pw_aff &mupa2) const +{ + return isl::checked::multi_union_pw_aff(*this).union_add(mupa2); +} + +isl::checked::multi_pw_aff multi_pw_aff::union_add(const isl::checked::aff &mpa2) const +{ + return this->union_add(isl::checked::multi_pw_aff(mpa2)); +} + +isl::checked::multi_pw_aff multi_pw_aff::union_add(const isl::checked::multi_aff &mpa2) const +{ + return this->union_add(isl::checked::multi_pw_aff(mpa2)); +} + +isl::checked::multi_pw_aff multi_pw_aff::union_add(const isl::checked::pw_aff &mpa2) const +{ + return this->union_add(isl::checked::multi_pw_aff(mpa2)); +} + +isl::checked::multi_pw_aff multi_pw_aff::union_add(const isl::checked::pw_multi_aff &mpa2) const +{ + return this->union_add(isl::checked::multi_pw_aff(mpa2)); +} + +isl::checked::multi_pw_aff multi_pw_aff::zero(isl::checked::space space) +{ + auto res = isl_multi_pw_aff_zero(space.release()); + return manage(res); +} + +inline std::ostream &operator<<(std::ostream &os, const multi_pw_aff &obj) +{ + char *str = isl_multi_pw_aff_to_str(obj.get()); + if (!str) { + os.setstate(std::ios_base::badbit); + return os; + } + os << str; + free(str); + return os; +} + +// implementations for isl::multi_union_pw_aff +multi_union_pw_aff manage(__isl_take isl_multi_union_pw_aff *ptr) { + return multi_union_pw_aff(ptr); +} +multi_union_pw_aff manage_copy(__isl_keep isl_multi_union_pw_aff *ptr) { + ptr = isl_multi_union_pw_aff_copy(ptr); + return multi_union_pw_aff(ptr); +} + +multi_union_pw_aff::multi_union_pw_aff(__isl_take isl_multi_union_pw_aff *ptr) + : ptr(ptr) {} + +multi_union_pw_aff::multi_union_pw_aff() + : ptr(nullptr) {} + +multi_union_pw_aff::multi_union_pw_aff(const multi_union_pw_aff &obj) + : ptr(nullptr) +{ + ptr = obj.copy(); +} + +multi_union_pw_aff::multi_union_pw_aff(isl::checked::multi_pw_aff mpa) +{ + auto res = isl_multi_union_pw_aff_from_multi_pw_aff(mpa.release()); + ptr = res; +} + +multi_union_pw_aff::multi_union_pw_aff(isl::checked::union_pw_aff upa) +{ + auto res = isl_multi_union_pw_aff_from_union_pw_aff(upa.release()); + ptr = res; +} + +multi_union_pw_aff::multi_union_pw_aff(isl::checked::space space, isl::checked::union_pw_aff_list list) +{ + auto res = isl_multi_union_pw_aff_from_union_pw_aff_list(space.release(), list.release()); + ptr = res; +} + +multi_union_pw_aff::multi_union_pw_aff(isl::checked::ctx ctx, const std::string &str) +{ + auto res = isl_multi_union_pw_aff_read_from_str(ctx.release(), str.c_str()); + ptr = res; +} + +multi_union_pw_aff &multi_union_pw_aff::operator=(multi_union_pw_aff obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +multi_union_pw_aff::~multi_union_pw_aff() { + if (ptr) + isl_multi_union_pw_aff_free(ptr); +} + +__isl_give isl_multi_union_pw_aff *multi_union_pw_aff::copy() const & { + return isl_multi_union_pw_aff_copy(ptr); +} + +__isl_keep isl_multi_union_pw_aff *multi_union_pw_aff::get() const { + return ptr; +} + +__isl_give isl_multi_union_pw_aff *multi_union_pw_aff::release() { + isl_multi_union_pw_aff *tmp = ptr; + ptr = nullptr; + return tmp; +} + +bool multi_union_pw_aff::is_null() const { + return ptr == nullptr; +} + +isl::checked::ctx multi_union_pw_aff::ctx() const { + return isl::checked::ctx(isl_multi_union_pw_aff_get_ctx(ptr)); +} + +isl::checked::multi_union_pw_aff multi_union_pw_aff::add(isl::checked::multi_union_pw_aff multi2) const +{ + auto res = isl_multi_union_pw_aff_add(copy(), multi2.release()); + return manage(res); +} + +isl::checked::union_pw_aff multi_union_pw_aff::at(int pos) const +{ + auto res = isl_multi_union_pw_aff_get_at(get(), pos); + return manage(res); +} + +isl::checked::union_pw_aff multi_union_pw_aff::get_at(int pos) const +{ + return at(pos); +} + +isl::checked::union_set multi_union_pw_aff::bind(isl::checked::multi_id tuple) const +{ + auto res = isl_multi_union_pw_aff_bind(copy(), tuple.release()); + return manage(res); +} + +isl::checked::multi_union_pw_aff multi_union_pw_aff::coalesce() const +{ + auto res = isl_multi_union_pw_aff_coalesce(copy()); + return manage(res); +} + +isl::checked::union_set multi_union_pw_aff::domain() const +{ + auto res = isl_multi_union_pw_aff_domain(copy()); + return manage(res); +} + +isl::checked::multi_union_pw_aff multi_union_pw_aff::flat_range_product(isl::checked::multi_union_pw_aff multi2) const +{ + auto res = isl_multi_union_pw_aff_flat_range_product(copy(), multi2.release()); + return manage(res); +} + +isl::checked::multi_union_pw_aff multi_union_pw_aff::gist(isl::checked::union_set context) const +{ + auto res = isl_multi_union_pw_aff_gist(copy(), context.release()); + return manage(res); +} + +isl::checked::multi_union_pw_aff multi_union_pw_aff::gist_params(isl::checked::set context) const +{ + auto res = isl_multi_union_pw_aff_gist_params(copy(), context.release()); + return manage(res); +} + +boolean multi_union_pw_aff::has_range_tuple_id() const +{ + auto res = isl_multi_union_pw_aff_has_range_tuple_id(get()); + return manage(res); +} + +isl::checked::multi_union_pw_aff multi_union_pw_aff::intersect_domain(isl::checked::union_set uset) const +{ + auto res = isl_multi_union_pw_aff_intersect_domain(copy(), uset.release()); + return manage(res); +} + +isl::checked::multi_union_pw_aff multi_union_pw_aff::intersect_params(isl::checked::set params) const +{ + auto res = isl_multi_union_pw_aff_intersect_params(copy(), params.release()); + return manage(res); +} + +boolean multi_union_pw_aff::involves_nan() const +{ + auto res = isl_multi_union_pw_aff_involves_nan(get()); + return manage(res); +} + +isl::checked::union_pw_aff_list multi_union_pw_aff::list() const +{ + auto res = isl_multi_union_pw_aff_get_list(get()); + return manage(res); +} + +isl::checked::union_pw_aff_list multi_union_pw_aff::get_list() const +{ + return list(); +} + +isl::checked::multi_union_pw_aff multi_union_pw_aff::neg() const +{ + auto res = isl_multi_union_pw_aff_neg(copy()); + return manage(res); +} + +boolean multi_union_pw_aff::plain_is_equal(const isl::checked::multi_union_pw_aff &multi2) const +{ + auto res = isl_multi_union_pw_aff_plain_is_equal(get(), multi2.get()); + return manage(res); +} + +isl::checked::multi_union_pw_aff multi_union_pw_aff::pullback(isl::checked::union_pw_multi_aff upma) const +{ + auto res = isl_multi_union_pw_aff_pullback_union_pw_multi_aff(copy(), upma.release()); + return manage(res); +} + +isl::checked::multi_union_pw_aff multi_union_pw_aff::range_product(isl::checked::multi_union_pw_aff multi2) const +{ + auto res = isl_multi_union_pw_aff_range_product(copy(), multi2.release()); + return manage(res); +} + +isl::checked::id multi_union_pw_aff::range_tuple_id() const +{ + auto res = isl_multi_union_pw_aff_get_range_tuple_id(get()); + return manage(res); +} + +isl::checked::id multi_union_pw_aff::get_range_tuple_id() const +{ + return range_tuple_id(); +} + +isl::checked::multi_union_pw_aff multi_union_pw_aff::reset_range_tuple_id() const +{ + auto res = isl_multi_union_pw_aff_reset_range_tuple_id(copy()); + return manage(res); +} + +isl::checked::multi_union_pw_aff multi_union_pw_aff::scale(isl::checked::multi_val mv) const +{ + auto res = isl_multi_union_pw_aff_scale_multi_val(copy(), mv.release()); + return manage(res); +} + +isl::checked::multi_union_pw_aff multi_union_pw_aff::scale(isl::checked::val v) const +{ + auto res = isl_multi_union_pw_aff_scale_val(copy(), v.release()); + return manage(res); +} + +isl::checked::multi_union_pw_aff multi_union_pw_aff::scale(long v) const +{ + return this->scale(isl::checked::val(ctx(), v)); +} + +isl::checked::multi_union_pw_aff multi_union_pw_aff::scale_down(isl::checked::multi_val mv) const +{ + auto res = isl_multi_union_pw_aff_scale_down_multi_val(copy(), mv.release()); + return manage(res); +} + +isl::checked::multi_union_pw_aff multi_union_pw_aff::scale_down(isl::checked::val v) const +{ + auto res = isl_multi_union_pw_aff_scale_down_val(copy(), v.release()); + return manage(res); +} + +isl::checked::multi_union_pw_aff multi_union_pw_aff::scale_down(long v) const +{ + return this->scale_down(isl::checked::val(ctx(), v)); +} + +isl::checked::multi_union_pw_aff multi_union_pw_aff::set_at(int pos, isl::checked::union_pw_aff el) const +{ + auto res = isl_multi_union_pw_aff_set_at(copy(), pos, el.release()); + return manage(res); +} + +isl::checked::multi_union_pw_aff multi_union_pw_aff::set_range_tuple(isl::checked::id id) const +{ + auto res = isl_multi_union_pw_aff_set_range_tuple_id(copy(), id.release()); + return manage(res); +} + +isl::checked::multi_union_pw_aff multi_union_pw_aff::set_range_tuple(const std::string &id) const +{ + return this->set_range_tuple(isl::checked::id(ctx(), id)); +} + +class size multi_union_pw_aff::size() const +{ + auto res = isl_multi_union_pw_aff_size(get()); + return manage(res); +} + +isl::checked::space multi_union_pw_aff::space() const +{ + auto res = isl_multi_union_pw_aff_get_space(get()); + return manage(res); +} + +isl::checked::space multi_union_pw_aff::get_space() const +{ + return space(); +} + +isl::checked::multi_union_pw_aff multi_union_pw_aff::sub(isl::checked::multi_union_pw_aff multi2) const +{ + auto res = isl_multi_union_pw_aff_sub(copy(), multi2.release()); + return manage(res); +} + +isl::checked::multi_union_pw_aff multi_union_pw_aff::union_add(isl::checked::multi_union_pw_aff mupa2) const +{ + auto res = isl_multi_union_pw_aff_union_add(copy(), mupa2.release()); + return manage(res); +} + +isl::checked::multi_union_pw_aff multi_union_pw_aff::zero(isl::checked::space space) +{ + auto res = isl_multi_union_pw_aff_zero(space.release()); + return manage(res); +} + +inline std::ostream &operator<<(std::ostream &os, const multi_union_pw_aff &obj) +{ + char *str = isl_multi_union_pw_aff_to_str(obj.get()); + if (!str) { + os.setstate(std::ios_base::badbit); + return os; + } + os << str; + free(str); + return os; +} + +// implementations for isl::multi_val +multi_val manage(__isl_take isl_multi_val *ptr) { + return multi_val(ptr); +} +multi_val manage_copy(__isl_keep isl_multi_val *ptr) { + ptr = isl_multi_val_copy(ptr); + return multi_val(ptr); +} + +multi_val::multi_val(__isl_take isl_multi_val *ptr) + : ptr(ptr) {} + +multi_val::multi_val() + : ptr(nullptr) {} + +multi_val::multi_val(const multi_val &obj) + : ptr(nullptr) +{ + ptr = obj.copy(); +} + +multi_val::multi_val(isl::checked::space space, isl::checked::val_list list) +{ + auto res = isl_multi_val_from_val_list(space.release(), list.release()); + ptr = res; +} + +multi_val::multi_val(isl::checked::ctx ctx, const std::string &str) +{ + auto res = isl_multi_val_read_from_str(ctx.release(), str.c_str()); + ptr = res; +} + +multi_val &multi_val::operator=(multi_val obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +multi_val::~multi_val() { + if (ptr) + isl_multi_val_free(ptr); +} + +__isl_give isl_multi_val *multi_val::copy() const & { + return isl_multi_val_copy(ptr); +} + +__isl_keep isl_multi_val *multi_val::get() const { + return ptr; +} + +__isl_give isl_multi_val *multi_val::release() { + isl_multi_val *tmp = ptr; + ptr = nullptr; + return tmp; +} + +bool multi_val::is_null() const { + return ptr == nullptr; +} + +isl::checked::ctx multi_val::ctx() const { + return isl::checked::ctx(isl_multi_val_get_ctx(ptr)); +} + +isl::checked::multi_val multi_val::add(isl::checked::multi_val multi2) const +{ + auto res = isl_multi_val_add(copy(), multi2.release()); + return manage(res); +} + +isl::checked::multi_val multi_val::add(isl::checked::val v) const +{ + auto res = isl_multi_val_add_val(copy(), v.release()); + return manage(res); +} + +isl::checked::multi_val multi_val::add(long v) const +{ + return this->add(isl::checked::val(ctx(), v)); +} + +isl::checked::val multi_val::at(int pos) const +{ + auto res = isl_multi_val_get_at(get(), pos); + return manage(res); +} + +isl::checked::val multi_val::get_at(int pos) const +{ + return at(pos); +} + +isl::checked::multi_val multi_val::flat_range_product(isl::checked::multi_val multi2) const +{ + auto res = isl_multi_val_flat_range_product(copy(), multi2.release()); + return manage(res); +} + +boolean multi_val::has_range_tuple_id() const +{ + auto res = isl_multi_val_has_range_tuple_id(get()); + return manage(res); +} + +boolean multi_val::involves_nan() const +{ + auto res = isl_multi_val_involves_nan(get()); + return manage(res); +} + +isl::checked::val_list multi_val::list() const +{ + auto res = isl_multi_val_get_list(get()); + return manage(res); +} + +isl::checked::val_list multi_val::get_list() const +{ + return list(); +} + +isl::checked::multi_val multi_val::max(isl::checked::multi_val multi2) const +{ + auto res = isl_multi_val_max(copy(), multi2.release()); + return manage(res); +} + +isl::checked::multi_val multi_val::min(isl::checked::multi_val multi2) const +{ + auto res = isl_multi_val_min(copy(), multi2.release()); + return manage(res); +} + +isl::checked::multi_val multi_val::neg() const +{ + auto res = isl_multi_val_neg(copy()); + return manage(res); +} + +boolean multi_val::plain_is_equal(const isl::checked::multi_val &multi2) const +{ + auto res = isl_multi_val_plain_is_equal(get(), multi2.get()); + return manage(res); +} + +isl::checked::multi_val multi_val::product(isl::checked::multi_val multi2) const +{ + auto res = isl_multi_val_product(copy(), multi2.release()); + return manage(res); +} + +isl::checked::multi_val multi_val::range_product(isl::checked::multi_val multi2) const +{ + auto res = isl_multi_val_range_product(copy(), multi2.release()); + return manage(res); +} + +isl::checked::id multi_val::range_tuple_id() const +{ + auto res = isl_multi_val_get_range_tuple_id(get()); + return manage(res); +} + +isl::checked::id multi_val::get_range_tuple_id() const +{ + return range_tuple_id(); +} + +isl::checked::multi_val multi_val::reset_range_tuple_id() const +{ + auto res = isl_multi_val_reset_range_tuple_id(copy()); + return manage(res); +} + +isl::checked::multi_val multi_val::scale(isl::checked::multi_val mv) const +{ + auto res = isl_multi_val_scale_multi_val(copy(), mv.release()); + return manage(res); +} + +isl::checked::multi_val multi_val::scale(isl::checked::val v) const +{ + auto res = isl_multi_val_scale_val(copy(), v.release()); + return manage(res); +} + +isl::checked::multi_val multi_val::scale(long v) const +{ + return this->scale(isl::checked::val(ctx(), v)); +} + +isl::checked::multi_val multi_val::scale_down(isl::checked::multi_val mv) const +{ + auto res = isl_multi_val_scale_down_multi_val(copy(), mv.release()); + return manage(res); +} + +isl::checked::multi_val multi_val::scale_down(isl::checked::val v) const +{ + auto res = isl_multi_val_scale_down_val(copy(), v.release()); + return manage(res); +} + +isl::checked::multi_val multi_val::scale_down(long v) const +{ + return this->scale_down(isl::checked::val(ctx(), v)); +} + +isl::checked::multi_val multi_val::set_at(int pos, isl::checked::val el) const +{ + auto res = isl_multi_val_set_at(copy(), pos, el.release()); + return manage(res); +} + +isl::checked::multi_val multi_val::set_at(int pos, long el) const +{ + return this->set_at(pos, isl::checked::val(ctx(), el)); +} + +isl::checked::multi_val multi_val::set_range_tuple(isl::checked::id id) const +{ + auto res = isl_multi_val_set_range_tuple_id(copy(), id.release()); + return manage(res); +} + +isl::checked::multi_val multi_val::set_range_tuple(const std::string &id) const +{ + return this->set_range_tuple(isl::checked::id(ctx(), id)); +} + +class size multi_val::size() const +{ + auto res = isl_multi_val_size(get()); + return manage(res); +} + +isl::checked::space multi_val::space() const +{ + auto res = isl_multi_val_get_space(get()); + return manage(res); +} + +isl::checked::space multi_val::get_space() const +{ + return space(); +} + +isl::checked::multi_val multi_val::sub(isl::checked::multi_val multi2) const +{ + auto res = isl_multi_val_sub(copy(), multi2.release()); + return manage(res); +} + +isl::checked::multi_val multi_val::zero(isl::checked::space space) +{ + auto res = isl_multi_val_zero(space.release()); + return manage(res); +} + +inline std::ostream &operator<<(std::ostream &os, const multi_val &obj) +{ + char *str = isl_multi_val_to_str(obj.get()); + if (!str) { + os.setstate(std::ios_base::badbit); + return os; + } + os << str; + free(str); + return os; +} + +// implementations for isl::point +point manage(__isl_take isl_point *ptr) { + return point(ptr); +} +point manage_copy(__isl_keep isl_point *ptr) { + ptr = isl_point_copy(ptr); + return point(ptr); +} + +point::point(__isl_take isl_point *ptr) + : ptr(ptr) {} + +point::point() + : ptr(nullptr) {} + +point::point(const point &obj) + : ptr(nullptr) +{ + ptr = obj.copy(); +} + +point &point::operator=(point obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +point::~point() { + if (ptr) + isl_point_free(ptr); +} + +__isl_give isl_point *point::copy() const & { + return isl_point_copy(ptr); +} + +__isl_keep isl_point *point::get() const { + return ptr; +} + +__isl_give isl_point *point::release() { + isl_point *tmp = ptr; + ptr = nullptr; + return tmp; +} + +bool point::is_null() const { + return ptr == nullptr; +} + +isl::checked::ctx point::ctx() const { + return isl::checked::ctx(isl_point_get_ctx(ptr)); +} + +isl::checked::basic_set point::affine_hull() const +{ + return isl::checked::basic_set(*this).affine_hull(); +} + +isl::checked::basic_set point::apply(const isl::checked::basic_map &bmap) const +{ + return isl::checked::basic_set(*this).apply(bmap); +} + +isl::checked::set point::apply(const isl::checked::map &map) const +{ + return isl::checked::basic_set(*this).apply(map); +} + +isl::checked::union_set point::apply(const isl::checked::union_map &umap) const +{ + return isl::checked::basic_set(*this).apply(umap); +} + +isl::checked::pw_multi_aff point::as_pw_multi_aff() const +{ + return isl::checked::basic_set(*this).as_pw_multi_aff(); +} + +isl::checked::set point::as_set() const +{ + return isl::checked::basic_set(*this).as_set(); +} + +isl::checked::set point::bind(const isl::checked::multi_id &tuple) const +{ + return isl::checked::basic_set(*this).bind(tuple); +} + +isl::checked::set point::coalesce() const +{ + return isl::checked::basic_set(*this).coalesce(); +} + +isl::checked::set point::complement() const +{ + return isl::checked::basic_set(*this).complement(); +} + +isl::checked::union_set point::compute_divs() const +{ + return isl::checked::basic_set(*this).compute_divs(); +} + +isl::checked::basic_set point::detect_equalities() const +{ + return isl::checked::basic_set(*this).detect_equalities(); +} + +isl::checked::val point::dim_max_val(int pos) const +{ + return isl::checked::basic_set(*this).dim_max_val(pos); +} + +isl::checked::val point::dim_min_val(int pos) const +{ + return isl::checked::basic_set(*this).dim_min_val(pos); +} + +isl::checked::set point::drop_unused_params() const +{ + return isl::checked::basic_set(*this).drop_unused_params(); +} + +boolean point::every_set(const std::function &test) const +{ + return isl::checked::basic_set(*this).every_set(test); +} + +isl::checked::set point::extract_set(const isl::checked::space &space) const +{ + return isl::checked::basic_set(*this).extract_set(space); +} + +isl::checked::basic_set point::flatten() const +{ + return isl::checked::basic_set(*this).flatten(); +} + +stat point::foreach_basic_set(const std::function &fn) const +{ + return isl::checked::basic_set(*this).foreach_basic_set(fn); +} + +stat point::foreach_point(const std::function &fn) const +{ + return isl::checked::basic_set(*this).foreach_point(fn); +} + +stat point::foreach_set(const std::function &fn) const +{ + return isl::checked::basic_set(*this).foreach_set(fn); +} + +isl::checked::basic_set point::gist(const isl::checked::basic_set &context) const +{ + return isl::checked::basic_set(*this).gist(context); +} + +isl::checked::set point::gist(const isl::checked::set &context) const +{ + return isl::checked::basic_set(*this).gist(context); +} + +isl::checked::union_set point::gist(const isl::checked::union_set &context) const +{ + return isl::checked::basic_set(*this).gist(context); +} + +isl::checked::set point::gist_params(const isl::checked::set &context) const +{ + return isl::checked::basic_set(*this).gist_params(context); +} + +isl::checked::map point::identity() const +{ + return isl::checked::basic_set(*this).identity(); +} + +isl::checked::pw_aff point::indicator_function() const +{ + return isl::checked::basic_set(*this).indicator_function(); +} + +isl::checked::map point::insert_domain(const isl::checked::space &domain) const +{ + return isl::checked::basic_set(*this).insert_domain(domain); +} + +isl::checked::basic_set point::intersect(const isl::checked::basic_set &bset2) const +{ + return isl::checked::basic_set(*this).intersect(bset2); +} + +isl::checked::set point::intersect(const isl::checked::set &set2) const +{ + return isl::checked::basic_set(*this).intersect(set2); +} + +isl::checked::union_set point::intersect(const isl::checked::union_set &uset2) const +{ + return isl::checked::basic_set(*this).intersect(uset2); +} + +isl::checked::basic_set point::intersect_params(const isl::checked::basic_set &bset2) const +{ + return isl::checked::basic_set(*this).intersect_params(bset2); +} + +isl::checked::set point::intersect_params(const isl::checked::set ¶ms) const +{ + return isl::checked::basic_set(*this).intersect_params(params); +} + +boolean point::involves_locals() const +{ + return isl::checked::basic_set(*this).involves_locals(); +} + +boolean point::is_disjoint(const isl::checked::set &set2) const +{ + return isl::checked::basic_set(*this).is_disjoint(set2); +} + +boolean point::is_disjoint(const isl::checked::union_set &uset2) const +{ + return isl::checked::basic_set(*this).is_disjoint(uset2); +} + +boolean point::is_empty() const +{ + return isl::checked::basic_set(*this).is_empty(); +} + +boolean point::is_equal(const isl::checked::basic_set &bset2) const +{ + return isl::checked::basic_set(*this).is_equal(bset2); +} + +boolean point::is_equal(const isl::checked::set &set2) const +{ + return isl::checked::basic_set(*this).is_equal(set2); +} + +boolean point::is_equal(const isl::checked::union_set &uset2) const +{ + return isl::checked::basic_set(*this).is_equal(uset2); +} + +boolean point::is_singleton() const +{ + return isl::checked::basic_set(*this).is_singleton(); +} + +boolean point::is_strict_subset(const isl::checked::set &set2) const +{ + return isl::checked::basic_set(*this).is_strict_subset(set2); +} + +boolean point::is_strict_subset(const isl::checked::union_set &uset2) const +{ + return isl::checked::basic_set(*this).is_strict_subset(uset2); +} + +boolean point::is_subset(const isl::checked::basic_set &bset2) const +{ + return isl::checked::basic_set(*this).is_subset(bset2); +} + +boolean point::is_subset(const isl::checked::set &set2) const +{ + return isl::checked::basic_set(*this).is_subset(set2); +} + +boolean point::is_subset(const isl::checked::union_set &uset2) const +{ + return isl::checked::basic_set(*this).is_subset(uset2); +} + +boolean point::is_wrapping() const +{ + return isl::checked::basic_set(*this).is_wrapping(); +} + +boolean point::isa_set() const +{ + return isl::checked::basic_set(*this).isa_set(); +} + +isl::checked::fixed_box point::lattice_tile() const +{ + return isl::checked::basic_set(*this).lattice_tile(); +} + +isl::checked::set point::lexmax() const +{ + return isl::checked::basic_set(*this).lexmax(); +} + +isl::checked::pw_multi_aff point::lexmax_pw_multi_aff() const +{ + return isl::checked::basic_set(*this).lexmax_pw_multi_aff(); +} + +isl::checked::set point::lexmin() const +{ + return isl::checked::basic_set(*this).lexmin(); +} + +isl::checked::pw_multi_aff point::lexmin_pw_multi_aff() const +{ + return isl::checked::basic_set(*this).lexmin_pw_multi_aff(); +} + +isl::checked::set point::lower_bound(const isl::checked::multi_pw_aff &lower) const +{ + return isl::checked::basic_set(*this).lower_bound(lower); +} + +isl::checked::set point::lower_bound(const isl::checked::multi_val &lower) const +{ + return isl::checked::basic_set(*this).lower_bound(lower); +} + +isl::checked::multi_pw_aff point::max_multi_pw_aff() const +{ + return isl::checked::basic_set(*this).max_multi_pw_aff(); +} + +isl::checked::val point::max_val(const isl::checked::aff &obj) const +{ + return isl::checked::basic_set(*this).max_val(obj); +} + +isl::checked::multi_pw_aff point::min_multi_pw_aff() const +{ + return isl::checked::basic_set(*this).min_multi_pw_aff(); +} + +isl::checked::val point::min_val(const isl::checked::aff &obj) const +{ + return isl::checked::basic_set(*this).min_val(obj); +} + +isl::checked::multi_val point::multi_val() const +{ + auto res = isl_point_get_multi_val(get()); + return manage(res); +} + +isl::checked::multi_val point::get_multi_val() const +{ + return multi_val(); +} + +class size point::n_basic_set() const +{ + return isl::checked::basic_set(*this).n_basic_set(); +} + +isl::checked::pw_aff point::param_pw_aff_on_domain(const isl::checked::id &id) const +{ + return isl::checked::basic_set(*this).param_pw_aff_on_domain(id); +} + +isl::checked::pw_aff point::param_pw_aff_on_domain(const std::string &id) const +{ + return this->param_pw_aff_on_domain(isl::checked::id(ctx(), id)); +} + +isl::checked::basic_set point::params() const +{ + return isl::checked::basic_set(*this).params(); +} + +isl::checked::multi_val point::plain_multi_val_if_fixed() const +{ + return isl::checked::basic_set(*this).plain_multi_val_if_fixed(); +} + +isl::checked::basic_set point::polyhedral_hull() const +{ + return isl::checked::basic_set(*this).polyhedral_hull(); +} + +isl::checked::set point::preimage(const isl::checked::multi_aff &ma) const +{ + return isl::checked::basic_set(*this).preimage(ma); +} + +isl::checked::set point::preimage(const isl::checked::multi_pw_aff &mpa) const +{ + return isl::checked::basic_set(*this).preimage(mpa); +} + +isl::checked::set point::preimage(const isl::checked::pw_multi_aff &pma) const +{ + return isl::checked::basic_set(*this).preimage(pma); +} + +isl::checked::union_set point::preimage(const isl::checked::union_pw_multi_aff &upma) const +{ + return isl::checked::basic_set(*this).preimage(upma); +} + +isl::checked::set point::product(const isl::checked::set &set2) const +{ + return isl::checked::basic_set(*this).product(set2); +} + +isl::checked::set point::project_out_all_params() const +{ + return isl::checked::basic_set(*this).project_out_all_params(); +} + +isl::checked::set point::project_out_param(const isl::checked::id &id) const +{ + return isl::checked::basic_set(*this).project_out_param(id); +} + +isl::checked::set point::project_out_param(const std::string &id) const +{ + return this->project_out_param(isl::checked::id(ctx(), id)); +} + +isl::checked::set point::project_out_param(const isl::checked::id_list &list) const +{ + return isl::checked::basic_set(*this).project_out_param(list); +} + +isl::checked::pw_aff point::pw_aff_on_domain(const isl::checked::val &v) const +{ + return isl::checked::basic_set(*this).pw_aff_on_domain(v); +} + +isl::checked::pw_aff point::pw_aff_on_domain(long v) const +{ + return this->pw_aff_on_domain(isl::checked::val(ctx(), v)); +} + +isl::checked::pw_multi_aff point::pw_multi_aff_on_domain(const isl::checked::multi_val &mv) const +{ + return isl::checked::basic_set(*this).pw_multi_aff_on_domain(mv); +} + +isl::checked::basic_set point::sample() const +{ + return isl::checked::basic_set(*this).sample(); +} + +isl::checked::point point::sample_point() const +{ + return isl::checked::basic_set(*this).sample_point(); +} + +isl::checked::set_list point::set_list() const +{ + return isl::checked::basic_set(*this).set_list(); +} + +isl::checked::fixed_box point::simple_fixed_box_hull() const +{ + return isl::checked::basic_set(*this).simple_fixed_box_hull(); +} + +isl::checked::space point::space() const +{ + return isl::checked::basic_set(*this).space(); +} + +isl::checked::val point::stride(int pos) const +{ + return isl::checked::basic_set(*this).stride(pos); +} + +isl::checked::set point::subtract(const isl::checked::set &set2) const +{ + return isl::checked::basic_set(*this).subtract(set2); +} + +isl::checked::union_set point::subtract(const isl::checked::union_set &uset2) const +{ + return isl::checked::basic_set(*this).subtract(uset2); +} + +isl::checked::set_list point::to_list() const +{ + return isl::checked::basic_set(*this).to_list(); +} + +isl::checked::set point::to_set() const +{ + auto res = isl_point_to_set(copy()); + return manage(res); +} + +isl::checked::union_set point::to_union_set() const +{ + return isl::checked::basic_set(*this).to_union_set(); +} + +isl::checked::map point::translation() const +{ + return isl::checked::basic_set(*this).translation(); +} + +class size point::tuple_dim() const +{ + return isl::checked::basic_set(*this).tuple_dim(); +} + +isl::checked::set point::unbind_params(const isl::checked::multi_id &tuple) const +{ + return isl::checked::basic_set(*this).unbind_params(tuple); +} + +isl::checked::map point::unbind_params_insert_domain(const isl::checked::multi_id &domain) const +{ + return isl::checked::basic_set(*this).unbind_params_insert_domain(domain); +} + +isl::checked::set point::unite(const isl::checked::basic_set &bset2) const +{ + return isl::checked::basic_set(*this).unite(bset2); +} + +isl::checked::set point::unite(const isl::checked::set &set2) const +{ + return isl::checked::basic_set(*this).unite(set2); +} + +isl::checked::union_set point::unite(const isl::checked::union_set &uset2) const +{ + return isl::checked::basic_set(*this).unite(uset2); +} + +isl::checked::basic_set point::unshifted_simple_hull() const +{ + return isl::checked::basic_set(*this).unshifted_simple_hull(); +} + +isl::checked::map point::unwrap() const +{ + return isl::checked::basic_set(*this).unwrap(); +} + +isl::checked::set point::upper_bound(const isl::checked::multi_pw_aff &upper) const +{ + return isl::checked::basic_set(*this).upper_bound(upper); +} + +isl::checked::set point::upper_bound(const isl::checked::multi_val &upper) const +{ + return isl::checked::basic_set(*this).upper_bound(upper); +} + +isl::checked::set point::wrapped_reverse() const +{ + return isl::checked::basic_set(*this).wrapped_reverse(); +} + +inline std::ostream &operator<<(std::ostream &os, const point &obj) +{ + char *str = isl_point_to_str(obj.get()); + if (!str) { + os.setstate(std::ios_base::badbit); + return os; + } + os << str; + free(str); + return os; +} + +// implementations for isl::pw_aff +pw_aff manage(__isl_take isl_pw_aff *ptr) { + return pw_aff(ptr); +} +pw_aff manage_copy(__isl_keep isl_pw_aff *ptr) { + ptr = isl_pw_aff_copy(ptr); + return pw_aff(ptr); +} + +pw_aff::pw_aff(__isl_take isl_pw_aff *ptr) + : ptr(ptr) {} + +pw_aff::pw_aff() + : ptr(nullptr) {} + +pw_aff::pw_aff(const pw_aff &obj) + : ptr(nullptr) +{ + ptr = obj.copy(); +} + +pw_aff::pw_aff(isl::checked::aff aff) +{ + auto res = isl_pw_aff_from_aff(aff.release()); + ptr = res; +} + +pw_aff::pw_aff(isl::checked::ctx ctx, const std::string &str) +{ + auto res = isl_pw_aff_read_from_str(ctx.release(), str.c_str()); + ptr = res; +} + +pw_aff &pw_aff::operator=(pw_aff obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +pw_aff::~pw_aff() { + if (ptr) + isl_pw_aff_free(ptr); +} + +__isl_give isl_pw_aff *pw_aff::copy() const & { + return isl_pw_aff_copy(ptr); +} + +__isl_keep isl_pw_aff *pw_aff::get() const { + return ptr; +} + +__isl_give isl_pw_aff *pw_aff::release() { + isl_pw_aff *tmp = ptr; + ptr = nullptr; + return tmp; +} + +bool pw_aff::is_null() const { + return ptr == nullptr; +} + +isl::checked::ctx pw_aff::ctx() const { + return isl::checked::ctx(isl_pw_aff_get_ctx(ptr)); +} + +isl::checked::multi_pw_aff pw_aff::add(const isl::checked::multi_pw_aff &multi2) const +{ + return isl::checked::pw_multi_aff(*this).add(multi2); +} + +isl::checked::multi_union_pw_aff pw_aff::add(const isl::checked::multi_union_pw_aff &multi2) const +{ + return isl::checked::union_pw_aff(*this).add(multi2); +} + +isl::checked::pw_aff pw_aff::add(isl::checked::pw_aff pwaff2) const +{ + auto res = isl_pw_aff_add(copy(), pwaff2.release()); + return manage(res); +} + +isl::checked::pw_multi_aff pw_aff::add(const isl::checked::pw_multi_aff &pma2) const +{ + return isl::checked::pw_multi_aff(*this).add(pma2); +} + +isl::checked::union_pw_aff pw_aff::add(const isl::checked::union_pw_aff &upa2) const +{ + return isl::checked::union_pw_aff(*this).add(upa2); +} + +isl::checked::union_pw_multi_aff pw_aff::add(const isl::checked::union_pw_multi_aff &upma2) const +{ + return isl::checked::union_pw_aff(*this).add(upma2); +} + +isl::checked::pw_aff pw_aff::add(const isl::checked::aff &pwaff2) const +{ + return this->add(isl::checked::pw_aff(pwaff2)); +} + +isl::checked::pw_aff pw_aff::add_constant(isl::checked::val v) const +{ + auto res = isl_pw_aff_add_constant_val(copy(), v.release()); + return manage(res); +} + +isl::checked::pw_aff pw_aff::add_constant(long v) const +{ + return this->add_constant(isl::checked::val(ctx(), v)); +} + +isl::checked::pw_multi_aff pw_aff::add_constant(const isl::checked::multi_val &mv) const +{ + return isl::checked::pw_multi_aff(*this).add_constant(mv); +} + +isl::checked::union_pw_multi_aff pw_aff::apply(const isl::checked::union_pw_multi_aff &upma2) const +{ + return isl::checked::union_pw_aff(*this).apply(upma2); +} + +isl::checked::aff pw_aff::as_aff() const +{ + auto res = isl_pw_aff_as_aff(copy()); + return manage(res); +} + +isl::checked::map pw_aff::as_map() const +{ + auto res = isl_pw_aff_as_map(copy()); + return manage(res); +} + +isl::checked::multi_aff pw_aff::as_multi_aff() const +{ + return isl::checked::pw_multi_aff(*this).as_multi_aff(); +} + +isl::checked::multi_union_pw_aff pw_aff::as_multi_union_pw_aff() const +{ + return isl::checked::union_pw_aff(*this).as_multi_union_pw_aff(); +} + +isl::checked::pw_multi_aff pw_aff::as_pw_multi_aff() const +{ + return isl::checked::union_pw_aff(*this).as_pw_multi_aff(); +} + +isl::checked::set pw_aff::as_set() const +{ + return isl::checked::pw_multi_aff(*this).as_set(); +} + +isl::checked::union_map pw_aff::as_union_map() const +{ + return isl::checked::union_pw_aff(*this).as_union_map(); +} + +isl::checked::pw_aff pw_aff::at(int pos) const +{ + return isl::checked::pw_multi_aff(*this).at(pos); +} + +isl::checked::set pw_aff::bind(const isl::checked::multi_id &tuple) const +{ + return isl::checked::multi_pw_aff(*this).bind(tuple); +} + +isl::checked::set pw_aff::bind(isl::checked::id id) const +{ + auto res = isl_pw_aff_bind_id(copy(), id.release()); + return manage(res); +} + +isl::checked::set pw_aff::bind(const std::string &id) const +{ + return this->bind(isl::checked::id(ctx(), id)); +} + +isl::checked::pw_aff pw_aff::bind_domain(isl::checked::multi_id tuple) const +{ + auto res = isl_pw_aff_bind_domain(copy(), tuple.release()); + return manage(res); +} + +isl::checked::pw_aff pw_aff::bind_domain_wrapped_domain(isl::checked::multi_id tuple) const +{ + auto res = isl_pw_aff_bind_domain_wrapped_domain(copy(), tuple.release()); + return manage(res); +} + +isl::checked::pw_aff pw_aff::ceil() const +{ + auto res = isl_pw_aff_ceil(copy()); + return manage(res); +} + +isl::checked::pw_aff pw_aff::coalesce() const +{ + auto res = isl_pw_aff_coalesce(copy()); + return manage(res); +} + +isl::checked::pw_aff pw_aff::cond(isl::checked::pw_aff pwaff_true, isl::checked::pw_aff pwaff_false) const +{ + auto res = isl_pw_aff_cond(copy(), pwaff_true.release(), pwaff_false.release()); + return manage(res); +} + +isl::checked::pw_aff pw_aff::div(isl::checked::pw_aff pa2) const +{ + auto res = isl_pw_aff_div(copy(), pa2.release()); + return manage(res); +} + +isl::checked::set pw_aff::domain() const +{ + auto res = isl_pw_aff_domain(copy()); + return manage(res); +} + +isl::checked::pw_aff pw_aff::domain_reverse() const +{ + auto res = isl_pw_aff_domain_reverse(copy()); + return manage(res); +} + +isl::checked::pw_aff pw_aff::drop_unused_params() const +{ + auto res = isl_pw_aff_drop_unused_params(copy()); + return manage(res); +} + +isl::checked::set pw_aff::eq_set(isl::checked::pw_aff pwaff2) const +{ + auto res = isl_pw_aff_eq_set(copy(), pwaff2.release()); + return manage(res); +} + +isl::checked::val pw_aff::eval(isl::checked::point pnt) const +{ + auto res = isl_pw_aff_eval(copy(), pnt.release()); + return manage(res); +} + +isl::checked::pw_multi_aff pw_aff::extract_pw_multi_aff(const isl::checked::space &space) const +{ + return isl::checked::union_pw_aff(*this).extract_pw_multi_aff(space); +} + +isl::checked::multi_pw_aff pw_aff::flat_range_product(const isl::checked::multi_pw_aff &multi2) const +{ + return isl::checked::pw_multi_aff(*this).flat_range_product(multi2); +} + +isl::checked::multi_union_pw_aff pw_aff::flat_range_product(const isl::checked::multi_union_pw_aff &multi2) const +{ + return isl::checked::union_pw_aff(*this).flat_range_product(multi2); +} + +isl::checked::pw_multi_aff pw_aff::flat_range_product(const isl::checked::pw_multi_aff &pma2) const +{ + return isl::checked::pw_multi_aff(*this).flat_range_product(pma2); +} + +isl::checked::union_pw_multi_aff pw_aff::flat_range_product(const isl::checked::union_pw_multi_aff &upma2) const +{ + return isl::checked::union_pw_aff(*this).flat_range_product(upma2); +} + +isl::checked::pw_aff pw_aff::floor() const +{ + auto res = isl_pw_aff_floor(copy()); + return manage(res); +} + +stat pw_aff::foreach_piece(const std::function &fn) const +{ + return isl::checked::pw_multi_aff(*this).foreach_piece(fn); +} + +isl::checked::set pw_aff::ge_set(isl::checked::pw_aff pwaff2) const +{ + auto res = isl_pw_aff_ge_set(copy(), pwaff2.release()); + return manage(res); +} + +isl::checked::pw_aff pw_aff::gist(isl::checked::set context) const +{ + auto res = isl_pw_aff_gist(copy(), context.release()); + return manage(res); +} + +isl::checked::union_pw_aff pw_aff::gist(const isl::checked::union_set &context) const +{ + return isl::checked::union_pw_aff(*this).gist(context); +} + +isl::checked::pw_aff pw_aff::gist(const isl::checked::basic_set &context) const +{ + return this->gist(isl::checked::set(context)); +} + +isl::checked::pw_aff pw_aff::gist(const isl::checked::point &context) const +{ + return this->gist(isl::checked::set(context)); +} + +isl::checked::pw_aff pw_aff::gist_params(isl::checked::set context) const +{ + auto res = isl_pw_aff_gist_params(copy(), context.release()); + return manage(res); +} + +isl::checked::set pw_aff::gt_set(isl::checked::pw_aff pwaff2) const +{ + auto res = isl_pw_aff_gt_set(copy(), pwaff2.release()); + return manage(res); +} + +boolean pw_aff::has_range_tuple_id() const +{ + return isl::checked::pw_multi_aff(*this).has_range_tuple_id(); +} + +isl::checked::multi_pw_aff pw_aff::identity() const +{ + return isl::checked::pw_multi_aff(*this).identity(); +} + +isl::checked::pw_aff pw_aff::insert_domain(isl::checked::space domain) const +{ + auto res = isl_pw_aff_insert_domain(copy(), domain.release()); + return manage(res); +} + +isl::checked::pw_aff pw_aff::intersect_domain(isl::checked::set set) const +{ + auto res = isl_pw_aff_intersect_domain(copy(), set.release()); + return manage(res); +} + +isl::checked::union_pw_aff pw_aff::intersect_domain(const isl::checked::space &space) const +{ + return isl::checked::union_pw_aff(*this).intersect_domain(space); +} + +isl::checked::union_pw_aff pw_aff::intersect_domain(const isl::checked::union_set &uset) const +{ + return isl::checked::union_pw_aff(*this).intersect_domain(uset); +} + +isl::checked::pw_aff pw_aff::intersect_domain(const isl::checked::basic_set &set) const +{ + return this->intersect_domain(isl::checked::set(set)); +} + +isl::checked::pw_aff pw_aff::intersect_domain(const isl::checked::point &set) const +{ + return this->intersect_domain(isl::checked::set(set)); +} + +isl::checked::union_pw_aff pw_aff::intersect_domain_wrapped_domain(const isl::checked::union_set &uset) const +{ + return isl::checked::union_pw_aff(*this).intersect_domain_wrapped_domain(uset); +} + +isl::checked::union_pw_aff pw_aff::intersect_domain_wrapped_range(const isl::checked::union_set &uset) const +{ + return isl::checked::union_pw_aff(*this).intersect_domain_wrapped_range(uset); +} + +isl::checked::pw_aff pw_aff::intersect_params(isl::checked::set set) const +{ + auto res = isl_pw_aff_intersect_params(copy(), set.release()); + return manage(res); +} + +boolean pw_aff::involves_locals() const +{ + return isl::checked::pw_multi_aff(*this).involves_locals(); +} + +boolean pw_aff::involves_nan() const +{ + return isl::checked::multi_pw_aff(*this).involves_nan(); +} + +boolean pw_aff::involves_param(const isl::checked::id &id) const +{ + return isl::checked::pw_multi_aff(*this).involves_param(id); +} + +boolean pw_aff::involves_param(const std::string &id) const +{ + return this->involves_param(isl::checked::id(ctx(), id)); +} + +boolean pw_aff::involves_param(const isl::checked::id_list &list) const +{ + return isl::checked::pw_multi_aff(*this).involves_param(list); +} + +boolean pw_aff::isa_aff() const +{ + auto res = isl_pw_aff_isa_aff(get()); + return manage(res); +} + +boolean pw_aff::isa_multi_aff() const +{ + return isl::checked::pw_multi_aff(*this).isa_multi_aff(); +} + +boolean pw_aff::isa_pw_multi_aff() const +{ + return isl::checked::union_pw_aff(*this).isa_pw_multi_aff(); +} + +isl::checked::set pw_aff::le_set(isl::checked::pw_aff pwaff2) const +{ + auto res = isl_pw_aff_le_set(copy(), pwaff2.release()); + return manage(res); +} + +isl::checked::pw_aff_list pw_aff::list() const +{ + return isl::checked::multi_pw_aff(*this).list(); +} + +isl::checked::set pw_aff::lt_set(isl::checked::pw_aff pwaff2) const +{ + auto res = isl_pw_aff_lt_set(copy(), pwaff2.release()); + return manage(res); +} + +isl::checked::multi_pw_aff pw_aff::max(const isl::checked::multi_pw_aff &multi2) const +{ + return isl::checked::pw_multi_aff(*this).max(multi2); +} + +isl::checked::pw_aff pw_aff::max(isl::checked::pw_aff pwaff2) const +{ + auto res = isl_pw_aff_max(copy(), pwaff2.release()); + return manage(res); +} + +isl::checked::pw_aff pw_aff::max(const isl::checked::aff &pwaff2) const +{ + return this->max(isl::checked::pw_aff(pwaff2)); +} + +isl::checked::multi_val pw_aff::max_multi_val() const +{ + return isl::checked::pw_multi_aff(*this).max_multi_val(); +} + +isl::checked::val pw_aff::max_val() const +{ + auto res = isl_pw_aff_max_val(copy()); + return manage(res); +} + +isl::checked::multi_pw_aff pw_aff::min(const isl::checked::multi_pw_aff &multi2) const +{ + return isl::checked::pw_multi_aff(*this).min(multi2); +} + +isl::checked::pw_aff pw_aff::min(isl::checked::pw_aff pwaff2) const +{ + auto res = isl_pw_aff_min(copy(), pwaff2.release()); + return manage(res); +} + +isl::checked::pw_aff pw_aff::min(const isl::checked::aff &pwaff2) const +{ + return this->min(isl::checked::pw_aff(pwaff2)); +} + +isl::checked::multi_val pw_aff::min_multi_val() const +{ + return isl::checked::pw_multi_aff(*this).min_multi_val(); +} + +isl::checked::val pw_aff::min_val() const +{ + auto res = isl_pw_aff_min_val(copy()); + return manage(res); +} + +isl::checked::pw_aff pw_aff::mod(isl::checked::val mod) const +{ + auto res = isl_pw_aff_mod_val(copy(), mod.release()); + return manage(res); +} + +isl::checked::pw_aff pw_aff::mod(long mod) const +{ + return this->mod(isl::checked::val(ctx(), mod)); +} + +isl::checked::pw_aff pw_aff::mul(isl::checked::pw_aff pwaff2) const +{ + auto res = isl_pw_aff_mul(copy(), pwaff2.release()); + return manage(res); +} + +class size pw_aff::n_piece() const +{ + return isl::checked::pw_multi_aff(*this).n_piece(); +} + +isl::checked::set pw_aff::ne_set(isl::checked::pw_aff pwaff2) const +{ + auto res = isl_pw_aff_ne_set(copy(), pwaff2.release()); + return manage(res); +} + +isl::checked::pw_aff pw_aff::neg() const +{ + auto res = isl_pw_aff_neg(copy()); + return manage(res); +} + +isl::checked::pw_aff pw_aff::param_on_domain(isl::checked::set domain, isl::checked::id id) +{ + auto res = isl_pw_aff_param_on_domain_id(domain.release(), id.release()); + return manage(res); +} + +isl::checked::set pw_aff::params() const +{ + auto res = isl_pw_aff_params(copy()); + return manage(res); +} + +boolean pw_aff::plain_is_empty() const +{ + return isl::checked::union_pw_aff(*this).plain_is_empty(); +} + +boolean pw_aff::plain_is_equal(const isl::checked::multi_pw_aff &multi2) const +{ + return isl::checked::pw_multi_aff(*this).plain_is_equal(multi2); +} + +boolean pw_aff::plain_is_equal(const isl::checked::multi_union_pw_aff &multi2) const +{ + return isl::checked::union_pw_aff(*this).plain_is_equal(multi2); +} + +boolean pw_aff::plain_is_equal(const isl::checked::pw_aff &pwaff2) const +{ + auto res = isl_pw_aff_plain_is_equal(get(), pwaff2.get()); + return manage(res); +} + +boolean pw_aff::plain_is_equal(const isl::checked::pw_multi_aff &pma2) const +{ + return isl::checked::pw_multi_aff(*this).plain_is_equal(pma2); +} + +boolean pw_aff::plain_is_equal(const isl::checked::union_pw_aff &upa2) const +{ + return isl::checked::union_pw_aff(*this).plain_is_equal(upa2); +} + +boolean pw_aff::plain_is_equal(const isl::checked::union_pw_multi_aff &upma2) const +{ + return isl::checked::union_pw_aff(*this).plain_is_equal(upma2); +} + +boolean pw_aff::plain_is_equal(const isl::checked::aff &pwaff2) const +{ + return this->plain_is_equal(isl::checked::pw_aff(pwaff2)); +} + +isl::checked::pw_multi_aff pw_aff::preimage_domain_wrapped_domain(const isl::checked::pw_multi_aff &pma2) const +{ + return isl::checked::pw_multi_aff(*this).preimage_domain_wrapped_domain(pma2); +} + +isl::checked::union_pw_multi_aff pw_aff::preimage_domain_wrapped_domain(const isl::checked::union_pw_multi_aff &upma2) const +{ + return isl::checked::union_pw_aff(*this).preimage_domain_wrapped_domain(upma2); +} + +isl::checked::multi_pw_aff pw_aff::product(const isl::checked::multi_pw_aff &multi2) const +{ + return isl::checked::pw_multi_aff(*this).product(multi2); +} + +isl::checked::pw_multi_aff pw_aff::product(const isl::checked::pw_multi_aff &pma2) const +{ + return isl::checked::pw_multi_aff(*this).product(pma2); +} + +isl::checked::pw_aff pw_aff::pullback(isl::checked::multi_aff ma) const +{ + auto res = isl_pw_aff_pullback_multi_aff(copy(), ma.release()); + return manage(res); +} + +isl::checked::pw_aff pw_aff::pullback(isl::checked::multi_pw_aff mpa) const +{ + auto res = isl_pw_aff_pullback_multi_pw_aff(copy(), mpa.release()); + return manage(res); +} + +isl::checked::pw_aff pw_aff::pullback(isl::checked::pw_multi_aff pma) const +{ + auto res = isl_pw_aff_pullback_pw_multi_aff(copy(), pma.release()); + return manage(res); +} + +isl::checked::union_pw_aff pw_aff::pullback(const isl::checked::union_pw_multi_aff &upma) const +{ + return isl::checked::union_pw_aff(*this).pullback(upma); +} + +isl::checked::pw_multi_aff_list pw_aff::pw_multi_aff_list() const +{ + return isl::checked::union_pw_aff(*this).pw_multi_aff_list(); +} + +isl::checked::pw_multi_aff pw_aff::range_factor_domain() const +{ + return isl::checked::pw_multi_aff(*this).range_factor_domain(); +} + +isl::checked::pw_multi_aff pw_aff::range_factor_range() const +{ + return isl::checked::pw_multi_aff(*this).range_factor_range(); +} + +isl::checked::multi_pw_aff pw_aff::range_product(const isl::checked::multi_pw_aff &multi2) const +{ + return isl::checked::pw_multi_aff(*this).range_product(multi2); +} + +isl::checked::multi_union_pw_aff pw_aff::range_product(const isl::checked::multi_union_pw_aff &multi2) const +{ + return isl::checked::union_pw_aff(*this).range_product(multi2); +} + +isl::checked::pw_multi_aff pw_aff::range_product(const isl::checked::pw_multi_aff &pma2) const +{ + return isl::checked::pw_multi_aff(*this).range_product(pma2); +} + +isl::checked::union_pw_multi_aff pw_aff::range_product(const isl::checked::union_pw_multi_aff &upma2) const +{ + return isl::checked::union_pw_aff(*this).range_product(upma2); +} + +isl::checked::id pw_aff::range_tuple_id() const +{ + return isl::checked::pw_multi_aff(*this).range_tuple_id(); +} + +isl::checked::multi_pw_aff pw_aff::reset_range_tuple_id() const +{ + return isl::checked::multi_pw_aff(*this).reset_range_tuple_id(); +} + +isl::checked::pw_aff pw_aff::scale(isl::checked::val v) const +{ + auto res = isl_pw_aff_scale_val(copy(), v.release()); + return manage(res); +} + +isl::checked::pw_aff pw_aff::scale(long v) const +{ + return this->scale(isl::checked::val(ctx(), v)); +} + +isl::checked::pw_multi_aff pw_aff::scale(const isl::checked::multi_val &mv) const +{ + return isl::checked::pw_multi_aff(*this).scale(mv); +} + +isl::checked::pw_aff pw_aff::scale_down(isl::checked::val f) const +{ + auto res = isl_pw_aff_scale_down_val(copy(), f.release()); + return manage(res); +} + +isl::checked::pw_aff pw_aff::scale_down(long f) const +{ + return this->scale_down(isl::checked::val(ctx(), f)); +} + +isl::checked::pw_multi_aff pw_aff::scale_down(const isl::checked::multi_val &mv) const +{ + return isl::checked::pw_multi_aff(*this).scale_down(mv); +} + +isl::checked::multi_pw_aff pw_aff::set_at(int pos, const isl::checked::pw_aff &el) const +{ + return isl::checked::pw_multi_aff(*this).set_at(pos, el); +} + +isl::checked::multi_union_pw_aff pw_aff::set_at(int pos, const isl::checked::union_pw_aff &el) const +{ + return isl::checked::union_pw_aff(*this).set_at(pos, el); +} + +isl::checked::pw_multi_aff pw_aff::set_range_tuple(const isl::checked::id &id) const +{ + return isl::checked::pw_multi_aff(*this).set_range_tuple(id); +} + +isl::checked::pw_multi_aff pw_aff::set_range_tuple(const std::string &id) const +{ + return this->set_range_tuple(isl::checked::id(ctx(), id)); +} + +class size pw_aff::size() const +{ + return isl::checked::multi_pw_aff(*this).size(); +} + +isl::checked::space pw_aff::space() const +{ + auto res = isl_pw_aff_get_space(get()); + return manage(res); +} + +isl::checked::space pw_aff::get_space() const +{ + return space(); +} + +isl::checked::multi_pw_aff pw_aff::sub(const isl::checked::multi_pw_aff &multi2) const +{ + return isl::checked::pw_multi_aff(*this).sub(multi2); +} + +isl::checked::multi_union_pw_aff pw_aff::sub(const isl::checked::multi_union_pw_aff &multi2) const +{ + return isl::checked::union_pw_aff(*this).sub(multi2); +} + +isl::checked::pw_aff pw_aff::sub(isl::checked::pw_aff pwaff2) const +{ + auto res = isl_pw_aff_sub(copy(), pwaff2.release()); + return manage(res); +} + +isl::checked::pw_multi_aff pw_aff::sub(const isl::checked::pw_multi_aff &pma2) const +{ + return isl::checked::pw_multi_aff(*this).sub(pma2); +} + +isl::checked::union_pw_aff pw_aff::sub(const isl::checked::union_pw_aff &upa2) const +{ + return isl::checked::union_pw_aff(*this).sub(upa2); +} + +isl::checked::union_pw_multi_aff pw_aff::sub(const isl::checked::union_pw_multi_aff &upma2) const +{ + return isl::checked::union_pw_aff(*this).sub(upma2); +} + +isl::checked::pw_aff pw_aff::sub(const isl::checked::aff &pwaff2) const +{ + return this->sub(isl::checked::pw_aff(pwaff2)); +} + +isl::checked::pw_aff pw_aff::subtract_domain(isl::checked::set set) const +{ + auto res = isl_pw_aff_subtract_domain(copy(), set.release()); + return manage(res); +} + +isl::checked::union_pw_aff pw_aff::subtract_domain(const isl::checked::space &space) const +{ + return isl::checked::union_pw_aff(*this).subtract_domain(space); +} + +isl::checked::union_pw_aff pw_aff::subtract_domain(const isl::checked::union_set &uset) const +{ + return isl::checked::union_pw_aff(*this).subtract_domain(uset); +} + +isl::checked::pw_aff pw_aff::subtract_domain(const isl::checked::basic_set &set) const +{ + return this->subtract_domain(isl::checked::set(set)); +} + +isl::checked::pw_aff pw_aff::subtract_domain(const isl::checked::point &set) const +{ + return this->subtract_domain(isl::checked::set(set)); +} + +isl::checked::pw_aff pw_aff::tdiv_q(isl::checked::pw_aff pa2) const +{ + auto res = isl_pw_aff_tdiv_q(copy(), pa2.release()); + return manage(res); +} + +isl::checked::pw_aff pw_aff::tdiv_r(isl::checked::pw_aff pa2) const +{ + auto res = isl_pw_aff_tdiv_r(copy(), pa2.release()); + return manage(res); +} + +isl::checked::pw_aff_list pw_aff::to_list() const +{ + auto res = isl_pw_aff_to_list(copy()); + return manage(res); +} + +isl::checked::multi_pw_aff pw_aff::to_multi_pw_aff() const +{ + return isl::checked::pw_multi_aff(*this).to_multi_pw_aff(); +} + +isl::checked::union_pw_aff pw_aff::to_union_pw_aff() const +{ + auto res = isl_pw_aff_to_union_pw_aff(copy()); + return manage(res); +} + +isl::checked::union_pw_multi_aff pw_aff::to_union_pw_multi_aff() const +{ + return isl::checked::pw_multi_aff(*this).to_union_pw_multi_aff(); +} + +isl::checked::multi_pw_aff pw_aff::unbind_params_insert_domain(const isl::checked::multi_id &domain) const +{ + return isl::checked::pw_multi_aff(*this).unbind_params_insert_domain(domain); +} + +isl::checked::multi_pw_aff pw_aff::union_add(const isl::checked::multi_pw_aff &mpa2) const +{ + return isl::checked::pw_multi_aff(*this).union_add(mpa2); +} + +isl::checked::multi_union_pw_aff pw_aff::union_add(const isl::checked::multi_union_pw_aff &mupa2) const +{ + return isl::checked::union_pw_aff(*this).union_add(mupa2); +} + +isl::checked::pw_aff pw_aff::union_add(isl::checked::pw_aff pwaff2) const +{ + auto res = isl_pw_aff_union_add(copy(), pwaff2.release()); + return manage(res); +} + +isl::checked::pw_multi_aff pw_aff::union_add(const isl::checked::pw_multi_aff &pma2) const +{ + return isl::checked::pw_multi_aff(*this).union_add(pma2); +} + +isl::checked::union_pw_aff pw_aff::union_add(const isl::checked::union_pw_aff &upa2) const +{ + return isl::checked::union_pw_aff(*this).union_add(upa2); +} + +isl::checked::union_pw_multi_aff pw_aff::union_add(const isl::checked::union_pw_multi_aff &upma2) const +{ + return isl::checked::union_pw_aff(*this).union_add(upma2); +} + +isl::checked::pw_aff pw_aff::union_add(const isl::checked::aff &pwaff2) const +{ + return this->union_add(isl::checked::pw_aff(pwaff2)); +} + +inline std::ostream &operator<<(std::ostream &os, const pw_aff &obj) +{ + char *str = isl_pw_aff_to_str(obj.get()); + if (!str) { + os.setstate(std::ios_base::badbit); + return os; + } + os << str; + free(str); + return os; +} + +// implementations for isl::pw_aff_list +pw_aff_list manage(__isl_take isl_pw_aff_list *ptr) { + return pw_aff_list(ptr); +} +pw_aff_list manage_copy(__isl_keep isl_pw_aff_list *ptr) { + ptr = isl_pw_aff_list_copy(ptr); + return pw_aff_list(ptr); +} + +pw_aff_list::pw_aff_list(__isl_take isl_pw_aff_list *ptr) + : ptr(ptr) {} + +pw_aff_list::pw_aff_list() + : ptr(nullptr) {} + +pw_aff_list::pw_aff_list(const pw_aff_list &obj) + : ptr(nullptr) +{ + ptr = obj.copy(); +} + +pw_aff_list::pw_aff_list(isl::checked::ctx ctx, int n) +{ + auto res = isl_pw_aff_list_alloc(ctx.release(), n); + ptr = res; +} + +pw_aff_list::pw_aff_list(isl::checked::pw_aff el) +{ + auto res = isl_pw_aff_list_from_pw_aff(el.release()); + ptr = res; +} + +pw_aff_list::pw_aff_list(isl::checked::ctx ctx, const std::string &str) +{ + auto res = isl_pw_aff_list_read_from_str(ctx.release(), str.c_str()); + ptr = res; +} + +pw_aff_list &pw_aff_list::operator=(pw_aff_list obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +pw_aff_list::~pw_aff_list() { + if (ptr) + isl_pw_aff_list_free(ptr); +} + +__isl_give isl_pw_aff_list *pw_aff_list::copy() const & { + return isl_pw_aff_list_copy(ptr); +} + +__isl_keep isl_pw_aff_list *pw_aff_list::get() const { + return ptr; +} + +__isl_give isl_pw_aff_list *pw_aff_list::release() { + isl_pw_aff_list *tmp = ptr; + ptr = nullptr; + return tmp; +} + +bool pw_aff_list::is_null() const { + return ptr == nullptr; +} + +isl::checked::ctx pw_aff_list::ctx() const { + return isl::checked::ctx(isl_pw_aff_list_get_ctx(ptr)); +} + +isl::checked::pw_aff_list pw_aff_list::add(isl::checked::pw_aff el) const +{ + auto res = isl_pw_aff_list_add(copy(), el.release()); + return manage(res); +} + +isl::checked::pw_aff pw_aff_list::at(int index) const +{ + auto res = isl_pw_aff_list_get_at(get(), index); + return manage(res); +} + +isl::checked::pw_aff pw_aff_list::get_at(int index) const +{ + return at(index); +} + +isl::checked::pw_aff_list pw_aff_list::clear() const +{ + auto res = isl_pw_aff_list_clear(copy()); + return manage(res); +} + +isl::checked::pw_aff_list pw_aff_list::concat(isl::checked::pw_aff_list list2) const +{ + auto res = isl_pw_aff_list_concat(copy(), list2.release()); + return manage(res); +} + +isl::checked::pw_aff_list pw_aff_list::drop(unsigned int first, unsigned int n) const +{ + auto res = isl_pw_aff_list_drop(copy(), first, n); + return manage(res); +} + +stat pw_aff_list::foreach(const std::function &fn) const +{ + struct fn_data { + std::function func; + } fn_data = { fn }; + auto fn_lambda = [](isl_pw_aff *arg_0, void *arg_1) -> isl_stat { + auto *data = static_cast(arg_1); + auto ret = (data->func)(manage(arg_0)); + return ret.release(); + }; + auto res = isl_pw_aff_list_foreach(get(), fn_lambda, &fn_data); + return manage(res); +} + +stat pw_aff_list::foreach_scc(const std::function &follows, const std::function &fn) const +{ + struct follows_data { + std::function func; + } follows_data = { follows }; + auto follows_lambda = [](isl_pw_aff *arg_0, isl_pw_aff *arg_1, void *arg_2) -> isl_bool { + auto *data = static_cast(arg_2); + auto ret = (data->func)(manage_copy(arg_0), manage_copy(arg_1)); + return ret.release(); + }; + struct fn_data { + std::function func; + } fn_data = { fn }; + auto fn_lambda = [](isl_pw_aff_list *arg_0, void *arg_1) -> isl_stat { + auto *data = static_cast(arg_1); + auto ret = (data->func)(manage(arg_0)); + return ret.release(); + }; + auto res = isl_pw_aff_list_foreach_scc(get(), follows_lambda, &follows_data, fn_lambda, &fn_data); + return manage(res); +} + +isl::checked::pw_aff_list pw_aff_list::insert(unsigned int pos, isl::checked::pw_aff el) const +{ + auto res = isl_pw_aff_list_insert(copy(), pos, el.release()); + return manage(res); +} + +isl::checked::pw_aff_list pw_aff_list::set_at(int index, isl::checked::pw_aff el) const +{ + auto res = isl_pw_aff_list_set_at(copy(), index, el.release()); + return manage(res); +} + +class size pw_aff_list::size() const +{ + auto res = isl_pw_aff_list_size(get()); + return manage(res); +} + +inline std::ostream &operator<<(std::ostream &os, const pw_aff_list &obj) +{ + char *str = isl_pw_aff_list_to_str(obj.get()); + if (!str) { + os.setstate(std::ios_base::badbit); + return os; + } + os << str; + free(str); + return os; +} + +// implementations for isl::pw_multi_aff +pw_multi_aff manage(__isl_take isl_pw_multi_aff *ptr) { + return pw_multi_aff(ptr); +} +pw_multi_aff manage_copy(__isl_keep isl_pw_multi_aff *ptr) { + ptr = isl_pw_multi_aff_copy(ptr); + return pw_multi_aff(ptr); +} + +pw_multi_aff::pw_multi_aff(__isl_take isl_pw_multi_aff *ptr) + : ptr(ptr) {} + +pw_multi_aff::pw_multi_aff() + : ptr(nullptr) {} + +pw_multi_aff::pw_multi_aff(const pw_multi_aff &obj) + : ptr(nullptr) +{ + ptr = obj.copy(); +} + +pw_multi_aff::pw_multi_aff(isl::checked::multi_aff ma) +{ + auto res = isl_pw_multi_aff_from_multi_aff(ma.release()); + ptr = res; +} + +pw_multi_aff::pw_multi_aff(isl::checked::pw_aff pa) +{ + auto res = isl_pw_multi_aff_from_pw_aff(pa.release()); + ptr = res; +} + +pw_multi_aff::pw_multi_aff(isl::checked::ctx ctx, const std::string &str) +{ + auto res = isl_pw_multi_aff_read_from_str(ctx.release(), str.c_str()); + ptr = res; +} + +pw_multi_aff &pw_multi_aff::operator=(pw_multi_aff obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +pw_multi_aff::~pw_multi_aff() { + if (ptr) + isl_pw_multi_aff_free(ptr); +} + +__isl_give isl_pw_multi_aff *pw_multi_aff::copy() const & { + return isl_pw_multi_aff_copy(ptr); +} + +__isl_keep isl_pw_multi_aff *pw_multi_aff::get() const { + return ptr; +} + +__isl_give isl_pw_multi_aff *pw_multi_aff::release() { + isl_pw_multi_aff *tmp = ptr; + ptr = nullptr; + return tmp; +} + +bool pw_multi_aff::is_null() const { + return ptr == nullptr; +} + +isl::checked::ctx pw_multi_aff::ctx() const { + return isl::checked::ctx(isl_pw_multi_aff_get_ctx(ptr)); +} + +isl::checked::multi_pw_aff pw_multi_aff::add(const isl::checked::multi_pw_aff &multi2) const +{ + return isl::checked::multi_pw_aff(*this).add(multi2); +} + +isl::checked::multi_union_pw_aff pw_multi_aff::add(const isl::checked::multi_union_pw_aff &multi2) const +{ + return isl::checked::multi_pw_aff(*this).add(multi2); +} + +isl::checked::pw_multi_aff pw_multi_aff::add(isl::checked::pw_multi_aff pma2) const +{ + auto res = isl_pw_multi_aff_add(copy(), pma2.release()); + return manage(res); +} + +isl::checked::union_pw_multi_aff pw_multi_aff::add(const isl::checked::union_pw_multi_aff &upma2) const +{ + return isl::checked::union_pw_multi_aff(*this).add(upma2); +} + +isl::checked::pw_multi_aff pw_multi_aff::add(const isl::checked::multi_aff &pma2) const +{ + return this->add(isl::checked::pw_multi_aff(pma2)); +} + +isl::checked::pw_multi_aff pw_multi_aff::add(const isl::checked::pw_aff &pma2) const +{ + return this->add(isl::checked::pw_multi_aff(pma2)); +} + +isl::checked::pw_multi_aff pw_multi_aff::add_constant(isl::checked::multi_val mv) const +{ + auto res = isl_pw_multi_aff_add_constant_multi_val(copy(), mv.release()); + return manage(res); +} + +isl::checked::pw_multi_aff pw_multi_aff::add_constant(isl::checked::val v) const +{ + auto res = isl_pw_multi_aff_add_constant_val(copy(), v.release()); + return manage(res); +} + +isl::checked::pw_multi_aff pw_multi_aff::add_constant(long v) const +{ + return this->add_constant(isl::checked::val(ctx(), v)); +} + +isl::checked::union_pw_multi_aff pw_multi_aff::apply(const isl::checked::union_pw_multi_aff &upma2) const +{ + return isl::checked::union_pw_multi_aff(*this).apply(upma2); +} + +isl::checked::map pw_multi_aff::as_map() const +{ + auto res = isl_pw_multi_aff_as_map(copy()); + return manage(res); +} + +isl::checked::multi_aff pw_multi_aff::as_multi_aff() const +{ + auto res = isl_pw_multi_aff_as_multi_aff(copy()); + return manage(res); +} + +isl::checked::multi_union_pw_aff pw_multi_aff::as_multi_union_pw_aff() const +{ + return isl::checked::union_pw_multi_aff(*this).as_multi_union_pw_aff(); +} + +isl::checked::pw_multi_aff pw_multi_aff::as_pw_multi_aff() const +{ + return isl::checked::union_pw_multi_aff(*this).as_pw_multi_aff(); +} + +isl::checked::set pw_multi_aff::as_set() const +{ + auto res = isl_pw_multi_aff_as_set(copy()); + return manage(res); +} + +isl::checked::union_map pw_multi_aff::as_union_map() const +{ + return isl::checked::union_pw_multi_aff(*this).as_union_map(); +} + +isl::checked::pw_aff pw_multi_aff::at(int pos) const +{ + auto res = isl_pw_multi_aff_get_at(get(), pos); + return manage(res); +} + +isl::checked::pw_aff pw_multi_aff::get_at(int pos) const +{ + return at(pos); +} + +isl::checked::set pw_multi_aff::bind(const isl::checked::multi_id &tuple) const +{ + return isl::checked::multi_pw_aff(*this).bind(tuple); +} + +isl::checked::pw_multi_aff pw_multi_aff::bind_domain(isl::checked::multi_id tuple) const +{ + auto res = isl_pw_multi_aff_bind_domain(copy(), tuple.release()); + return manage(res); +} + +isl::checked::pw_multi_aff pw_multi_aff::bind_domain_wrapped_domain(isl::checked::multi_id tuple) const +{ + auto res = isl_pw_multi_aff_bind_domain_wrapped_domain(copy(), tuple.release()); + return manage(res); +} + +isl::checked::pw_multi_aff pw_multi_aff::coalesce() const +{ + auto res = isl_pw_multi_aff_coalesce(copy()); + return manage(res); +} + +isl::checked::set pw_multi_aff::domain() const +{ + auto res = isl_pw_multi_aff_domain(copy()); + return manage(res); +} + +isl::checked::pw_multi_aff pw_multi_aff::domain_map(isl::checked::space space) +{ + auto res = isl_pw_multi_aff_domain_map(space.release()); + return manage(res); +} + +isl::checked::pw_multi_aff pw_multi_aff::domain_reverse() const +{ + auto res = isl_pw_multi_aff_domain_reverse(copy()); + return manage(res); +} + +isl::checked::pw_multi_aff pw_multi_aff::drop_unused_params() const +{ + auto res = isl_pw_multi_aff_drop_unused_params(copy()); + return manage(res); +} + +isl::checked::pw_multi_aff pw_multi_aff::extract_pw_multi_aff(const isl::checked::space &space) const +{ + return isl::checked::union_pw_multi_aff(*this).extract_pw_multi_aff(space); +} + +isl::checked::multi_pw_aff pw_multi_aff::flat_range_product(const isl::checked::multi_pw_aff &multi2) const +{ + return isl::checked::multi_pw_aff(*this).flat_range_product(multi2); +} + +isl::checked::multi_union_pw_aff pw_multi_aff::flat_range_product(const isl::checked::multi_union_pw_aff &multi2) const +{ + return isl::checked::multi_pw_aff(*this).flat_range_product(multi2); +} + +isl::checked::pw_multi_aff pw_multi_aff::flat_range_product(isl::checked::pw_multi_aff pma2) const +{ + auto res = isl_pw_multi_aff_flat_range_product(copy(), pma2.release()); + return manage(res); +} + +isl::checked::union_pw_multi_aff pw_multi_aff::flat_range_product(const isl::checked::union_pw_multi_aff &upma2) const +{ + return isl::checked::union_pw_multi_aff(*this).flat_range_product(upma2); +} + +isl::checked::pw_multi_aff pw_multi_aff::flat_range_product(const isl::checked::multi_aff &pma2) const +{ + return this->flat_range_product(isl::checked::pw_multi_aff(pma2)); +} + +isl::checked::pw_multi_aff pw_multi_aff::flat_range_product(const isl::checked::pw_aff &pma2) const +{ + return this->flat_range_product(isl::checked::pw_multi_aff(pma2)); +} + +stat pw_multi_aff::foreach_piece(const std::function &fn) const +{ + struct fn_data { + std::function func; + } fn_data = { fn }; + auto fn_lambda = [](isl_set *arg_0, isl_multi_aff *arg_1, void *arg_2) -> isl_stat { + auto *data = static_cast(arg_2); + auto ret = (data->func)(manage(arg_0), manage(arg_1)); + return ret.release(); + }; + auto res = isl_pw_multi_aff_foreach_piece(get(), fn_lambda, &fn_data); + return manage(res); +} + +isl::checked::pw_multi_aff pw_multi_aff::gist(isl::checked::set set) const +{ + auto res = isl_pw_multi_aff_gist(copy(), set.release()); + return manage(res); +} + +isl::checked::union_pw_multi_aff pw_multi_aff::gist(const isl::checked::union_set &context) const +{ + return isl::checked::union_pw_multi_aff(*this).gist(context); +} + +isl::checked::pw_multi_aff pw_multi_aff::gist(const isl::checked::basic_set &set) const +{ + return this->gist(isl::checked::set(set)); +} + +isl::checked::pw_multi_aff pw_multi_aff::gist(const isl::checked::point &set) const +{ + return this->gist(isl::checked::set(set)); +} + +isl::checked::pw_multi_aff pw_multi_aff::gist_params(isl::checked::set set) const +{ + auto res = isl_pw_multi_aff_gist_params(copy(), set.release()); + return manage(res); +} + +boolean pw_multi_aff::has_range_tuple_id() const +{ + auto res = isl_pw_multi_aff_has_range_tuple_id(get()); + return manage(res); +} + +isl::checked::multi_pw_aff pw_multi_aff::identity() const +{ + return isl::checked::multi_pw_aff(*this).identity(); +} + +isl::checked::pw_multi_aff pw_multi_aff::identity_on_domain(isl::checked::space space) +{ + auto res = isl_pw_multi_aff_identity_on_domain_space(space.release()); + return manage(res); +} + +isl::checked::pw_multi_aff pw_multi_aff::insert_domain(isl::checked::space domain) const +{ + auto res = isl_pw_multi_aff_insert_domain(copy(), domain.release()); + return manage(res); +} + +isl::checked::pw_multi_aff pw_multi_aff::intersect_domain(isl::checked::set set) const +{ + auto res = isl_pw_multi_aff_intersect_domain(copy(), set.release()); + return manage(res); +} + +isl::checked::union_pw_multi_aff pw_multi_aff::intersect_domain(const isl::checked::space &space) const +{ + return isl::checked::union_pw_multi_aff(*this).intersect_domain(space); +} + +isl::checked::union_pw_multi_aff pw_multi_aff::intersect_domain(const isl::checked::union_set &uset) const +{ + return isl::checked::union_pw_multi_aff(*this).intersect_domain(uset); +} + +isl::checked::pw_multi_aff pw_multi_aff::intersect_domain(const isl::checked::basic_set &set) const +{ + return this->intersect_domain(isl::checked::set(set)); +} + +isl::checked::pw_multi_aff pw_multi_aff::intersect_domain(const isl::checked::point &set) const +{ + return this->intersect_domain(isl::checked::set(set)); +} + +isl::checked::union_pw_multi_aff pw_multi_aff::intersect_domain_wrapped_domain(const isl::checked::union_set &uset) const +{ + return isl::checked::union_pw_multi_aff(*this).intersect_domain_wrapped_domain(uset); +} + +isl::checked::union_pw_multi_aff pw_multi_aff::intersect_domain_wrapped_range(const isl::checked::union_set &uset) const +{ + return isl::checked::union_pw_multi_aff(*this).intersect_domain_wrapped_range(uset); +} + +isl::checked::pw_multi_aff pw_multi_aff::intersect_params(isl::checked::set set) const +{ + auto res = isl_pw_multi_aff_intersect_params(copy(), set.release()); + return manage(res); +} + +boolean pw_multi_aff::involves_locals() const +{ + auto res = isl_pw_multi_aff_involves_locals(get()); + return manage(res); +} + +boolean pw_multi_aff::involves_nan() const +{ + return isl::checked::multi_pw_aff(*this).involves_nan(); +} + +boolean pw_multi_aff::involves_param(const isl::checked::id &id) const +{ + return isl::checked::multi_pw_aff(*this).involves_param(id); +} + +boolean pw_multi_aff::involves_param(const std::string &id) const +{ + return this->involves_param(isl::checked::id(ctx(), id)); +} + +boolean pw_multi_aff::involves_param(const isl::checked::id_list &list) const +{ + return isl::checked::multi_pw_aff(*this).involves_param(list); +} + +boolean pw_multi_aff::isa_multi_aff() const +{ + auto res = isl_pw_multi_aff_isa_multi_aff(get()); + return manage(res); +} + +boolean pw_multi_aff::isa_pw_multi_aff() const +{ + return isl::checked::union_pw_multi_aff(*this).isa_pw_multi_aff(); +} + +isl::checked::pw_aff_list pw_multi_aff::list() const +{ + return isl::checked::multi_pw_aff(*this).list(); +} + +isl::checked::multi_pw_aff pw_multi_aff::max(const isl::checked::multi_pw_aff &multi2) const +{ + return isl::checked::multi_pw_aff(*this).max(multi2); +} + +isl::checked::multi_val pw_multi_aff::max_multi_val() const +{ + auto res = isl_pw_multi_aff_max_multi_val(copy()); + return manage(res); +} + +isl::checked::multi_pw_aff pw_multi_aff::min(const isl::checked::multi_pw_aff &multi2) const +{ + return isl::checked::multi_pw_aff(*this).min(multi2); +} + +isl::checked::multi_val pw_multi_aff::min_multi_val() const +{ + auto res = isl_pw_multi_aff_min_multi_val(copy()); + return manage(res); +} + +isl::checked::pw_multi_aff pw_multi_aff::multi_val_on_domain(isl::checked::set domain, isl::checked::multi_val mv) +{ + auto res = isl_pw_multi_aff_multi_val_on_domain(domain.release(), mv.release()); + return manage(res); +} + +class size pw_multi_aff::n_piece() const +{ + auto res = isl_pw_multi_aff_n_piece(get()); + return manage(res); +} + +isl::checked::multi_pw_aff pw_multi_aff::neg() const +{ + return isl::checked::multi_pw_aff(*this).neg(); +} + +boolean pw_multi_aff::plain_is_empty() const +{ + return isl::checked::union_pw_multi_aff(*this).plain_is_empty(); +} + +boolean pw_multi_aff::plain_is_equal(const isl::checked::multi_pw_aff &multi2) const +{ + return isl::checked::multi_pw_aff(*this).plain_is_equal(multi2); +} + +boolean pw_multi_aff::plain_is_equal(const isl::checked::multi_union_pw_aff &multi2) const +{ + return isl::checked::multi_pw_aff(*this).plain_is_equal(multi2); +} + +boolean pw_multi_aff::plain_is_equal(const isl::checked::pw_multi_aff &pma2) const +{ + auto res = isl_pw_multi_aff_plain_is_equal(get(), pma2.get()); + return manage(res); +} + +boolean pw_multi_aff::plain_is_equal(const isl::checked::union_pw_multi_aff &upma2) const +{ + return isl::checked::union_pw_multi_aff(*this).plain_is_equal(upma2); +} + +boolean pw_multi_aff::plain_is_equal(const isl::checked::multi_aff &pma2) const +{ + return this->plain_is_equal(isl::checked::pw_multi_aff(pma2)); +} + +boolean pw_multi_aff::plain_is_equal(const isl::checked::pw_aff &pma2) const +{ + return this->plain_is_equal(isl::checked::pw_multi_aff(pma2)); +} + +isl::checked::pw_multi_aff pw_multi_aff::preimage_domain_wrapped_domain(isl::checked::pw_multi_aff pma2) const +{ + auto res = isl_pw_multi_aff_preimage_domain_wrapped_domain_pw_multi_aff(copy(), pma2.release()); + return manage(res); +} + +isl::checked::union_pw_multi_aff pw_multi_aff::preimage_domain_wrapped_domain(const isl::checked::union_pw_multi_aff &upma2) const +{ + return isl::checked::union_pw_multi_aff(*this).preimage_domain_wrapped_domain(upma2); +} + +isl::checked::pw_multi_aff pw_multi_aff::preimage_domain_wrapped_domain(const isl::checked::multi_aff &pma2) const +{ + return this->preimage_domain_wrapped_domain(isl::checked::pw_multi_aff(pma2)); +} + +isl::checked::pw_multi_aff pw_multi_aff::preimage_domain_wrapped_domain(const isl::checked::pw_aff &pma2) const +{ + return this->preimage_domain_wrapped_domain(isl::checked::pw_multi_aff(pma2)); +} + +isl::checked::multi_pw_aff pw_multi_aff::product(const isl::checked::multi_pw_aff &multi2) const +{ + return isl::checked::multi_pw_aff(*this).product(multi2); +} + +isl::checked::pw_multi_aff pw_multi_aff::product(isl::checked::pw_multi_aff pma2) const +{ + auto res = isl_pw_multi_aff_product(copy(), pma2.release()); + return manage(res); +} + +isl::checked::pw_multi_aff pw_multi_aff::product(const isl::checked::multi_aff &pma2) const +{ + return this->product(isl::checked::pw_multi_aff(pma2)); +} + +isl::checked::pw_multi_aff pw_multi_aff::product(const isl::checked::pw_aff &pma2) const +{ + return this->product(isl::checked::pw_multi_aff(pma2)); +} + +isl::checked::multi_pw_aff pw_multi_aff::pullback(const isl::checked::multi_pw_aff &mpa2) const +{ + return isl::checked::multi_pw_aff(*this).pullback(mpa2); +} + +isl::checked::pw_multi_aff pw_multi_aff::pullback(isl::checked::multi_aff ma) const +{ + auto res = isl_pw_multi_aff_pullback_multi_aff(copy(), ma.release()); + return manage(res); +} + +isl::checked::pw_multi_aff pw_multi_aff::pullback(isl::checked::pw_multi_aff pma2) const +{ + auto res = isl_pw_multi_aff_pullback_pw_multi_aff(copy(), pma2.release()); + return manage(res); +} + +isl::checked::union_pw_multi_aff pw_multi_aff::pullback(const isl::checked::union_pw_multi_aff &upma2) const +{ + return isl::checked::union_pw_multi_aff(*this).pullback(upma2); +} + +isl::checked::pw_multi_aff_list pw_multi_aff::pw_multi_aff_list() const +{ + return isl::checked::union_pw_multi_aff(*this).pw_multi_aff_list(); +} + +isl::checked::pw_multi_aff pw_multi_aff::range_factor_domain() const +{ + auto res = isl_pw_multi_aff_range_factor_domain(copy()); + return manage(res); +} + +isl::checked::pw_multi_aff pw_multi_aff::range_factor_range() const +{ + auto res = isl_pw_multi_aff_range_factor_range(copy()); + return manage(res); +} + +isl::checked::pw_multi_aff pw_multi_aff::range_map(isl::checked::space space) +{ + auto res = isl_pw_multi_aff_range_map(space.release()); + return manage(res); +} + +isl::checked::multi_pw_aff pw_multi_aff::range_product(const isl::checked::multi_pw_aff &multi2) const +{ + return isl::checked::multi_pw_aff(*this).range_product(multi2); +} + +isl::checked::multi_union_pw_aff pw_multi_aff::range_product(const isl::checked::multi_union_pw_aff &multi2) const +{ + return isl::checked::multi_pw_aff(*this).range_product(multi2); +} + +isl::checked::pw_multi_aff pw_multi_aff::range_product(isl::checked::pw_multi_aff pma2) const +{ + auto res = isl_pw_multi_aff_range_product(copy(), pma2.release()); + return manage(res); +} + +isl::checked::union_pw_multi_aff pw_multi_aff::range_product(const isl::checked::union_pw_multi_aff &upma2) const +{ + return isl::checked::union_pw_multi_aff(*this).range_product(upma2); +} + +isl::checked::pw_multi_aff pw_multi_aff::range_product(const isl::checked::multi_aff &pma2) const +{ + return this->range_product(isl::checked::pw_multi_aff(pma2)); +} + +isl::checked::pw_multi_aff pw_multi_aff::range_product(const isl::checked::pw_aff &pma2) const +{ + return this->range_product(isl::checked::pw_multi_aff(pma2)); +} + +isl::checked::id pw_multi_aff::range_tuple_id() const +{ + auto res = isl_pw_multi_aff_get_range_tuple_id(get()); + return manage(res); +} + +isl::checked::id pw_multi_aff::get_range_tuple_id() const +{ + return range_tuple_id(); +} + +isl::checked::multi_pw_aff pw_multi_aff::reset_range_tuple_id() const +{ + return isl::checked::multi_pw_aff(*this).reset_range_tuple_id(); +} + +isl::checked::pw_multi_aff pw_multi_aff::scale(isl::checked::multi_val mv) const +{ + auto res = isl_pw_multi_aff_scale_multi_val(copy(), mv.release()); + return manage(res); +} + +isl::checked::pw_multi_aff pw_multi_aff::scale(isl::checked::val v) const +{ + auto res = isl_pw_multi_aff_scale_val(copy(), v.release()); + return manage(res); +} + +isl::checked::pw_multi_aff pw_multi_aff::scale(long v) const +{ + return this->scale(isl::checked::val(ctx(), v)); +} + +isl::checked::pw_multi_aff pw_multi_aff::scale_down(isl::checked::multi_val mv) const +{ + auto res = isl_pw_multi_aff_scale_down_multi_val(copy(), mv.release()); + return manage(res); +} + +isl::checked::pw_multi_aff pw_multi_aff::scale_down(isl::checked::val v) const +{ + auto res = isl_pw_multi_aff_scale_down_val(copy(), v.release()); + return manage(res); +} + +isl::checked::pw_multi_aff pw_multi_aff::scale_down(long v) const +{ + return this->scale_down(isl::checked::val(ctx(), v)); +} + +isl::checked::multi_pw_aff pw_multi_aff::set_at(int pos, const isl::checked::pw_aff &el) const +{ + return isl::checked::multi_pw_aff(*this).set_at(pos, el); +} + +isl::checked::multi_union_pw_aff pw_multi_aff::set_at(int pos, const isl::checked::union_pw_aff &el) const +{ + return isl::checked::multi_pw_aff(*this).set_at(pos, el); +} + +isl::checked::pw_multi_aff pw_multi_aff::set_range_tuple(isl::checked::id id) const +{ + auto res = isl_pw_multi_aff_set_range_tuple_id(copy(), id.release()); + return manage(res); +} + +isl::checked::pw_multi_aff pw_multi_aff::set_range_tuple(const std::string &id) const +{ + return this->set_range_tuple(isl::checked::id(ctx(), id)); +} + +class size pw_multi_aff::size() const +{ + return isl::checked::multi_pw_aff(*this).size(); +} + +isl::checked::space pw_multi_aff::space() const +{ + auto res = isl_pw_multi_aff_get_space(get()); + return manage(res); +} + +isl::checked::space pw_multi_aff::get_space() const +{ + return space(); +} + +isl::checked::multi_pw_aff pw_multi_aff::sub(const isl::checked::multi_pw_aff &multi2) const +{ + return isl::checked::multi_pw_aff(*this).sub(multi2); +} + +isl::checked::multi_union_pw_aff pw_multi_aff::sub(const isl::checked::multi_union_pw_aff &multi2) const +{ + return isl::checked::multi_pw_aff(*this).sub(multi2); +} + +isl::checked::pw_multi_aff pw_multi_aff::sub(isl::checked::pw_multi_aff pma2) const +{ + auto res = isl_pw_multi_aff_sub(copy(), pma2.release()); + return manage(res); +} + +isl::checked::union_pw_multi_aff pw_multi_aff::sub(const isl::checked::union_pw_multi_aff &upma2) const +{ + return isl::checked::union_pw_multi_aff(*this).sub(upma2); +} + +isl::checked::pw_multi_aff pw_multi_aff::sub(const isl::checked::multi_aff &pma2) const +{ + return this->sub(isl::checked::pw_multi_aff(pma2)); +} + +isl::checked::pw_multi_aff pw_multi_aff::sub(const isl::checked::pw_aff &pma2) const +{ + return this->sub(isl::checked::pw_multi_aff(pma2)); +} + +isl::checked::pw_multi_aff pw_multi_aff::subtract_domain(isl::checked::set set) const +{ + auto res = isl_pw_multi_aff_subtract_domain(copy(), set.release()); + return manage(res); +} + +isl::checked::union_pw_multi_aff pw_multi_aff::subtract_domain(const isl::checked::space &space) const +{ + return isl::checked::union_pw_multi_aff(*this).subtract_domain(space); +} + +isl::checked::union_pw_multi_aff pw_multi_aff::subtract_domain(const isl::checked::union_set &uset) const +{ + return isl::checked::union_pw_multi_aff(*this).subtract_domain(uset); +} + +isl::checked::pw_multi_aff pw_multi_aff::subtract_domain(const isl::checked::basic_set &set) const +{ + return this->subtract_domain(isl::checked::set(set)); +} + +isl::checked::pw_multi_aff pw_multi_aff::subtract_domain(const isl::checked::point &set) const +{ + return this->subtract_domain(isl::checked::set(set)); +} + +isl::checked::pw_multi_aff_list pw_multi_aff::to_list() const +{ + auto res = isl_pw_multi_aff_to_list(copy()); + return manage(res); +} + +isl::checked::multi_pw_aff pw_multi_aff::to_multi_pw_aff() const +{ + auto res = isl_pw_multi_aff_to_multi_pw_aff(copy()); + return manage(res); +} + +isl::checked::union_pw_multi_aff pw_multi_aff::to_union_pw_multi_aff() const +{ + auto res = isl_pw_multi_aff_to_union_pw_multi_aff(copy()); + return manage(res); +} + +isl::checked::multi_pw_aff pw_multi_aff::unbind_params_insert_domain(const isl::checked::multi_id &domain) const +{ + return isl::checked::multi_pw_aff(*this).unbind_params_insert_domain(domain); +} + +isl::checked::multi_pw_aff pw_multi_aff::union_add(const isl::checked::multi_pw_aff &mpa2) const +{ + return isl::checked::multi_pw_aff(*this).union_add(mpa2); +} + +isl::checked::multi_union_pw_aff pw_multi_aff::union_add(const isl::checked::multi_union_pw_aff &mupa2) const +{ + return isl::checked::multi_pw_aff(*this).union_add(mupa2); +} + +isl::checked::pw_multi_aff pw_multi_aff::union_add(isl::checked::pw_multi_aff pma2) const +{ + auto res = isl_pw_multi_aff_union_add(copy(), pma2.release()); + return manage(res); +} + +isl::checked::union_pw_multi_aff pw_multi_aff::union_add(const isl::checked::union_pw_multi_aff &upma2) const +{ + return isl::checked::union_pw_multi_aff(*this).union_add(upma2); +} + +isl::checked::pw_multi_aff pw_multi_aff::union_add(const isl::checked::multi_aff &pma2) const +{ + return this->union_add(isl::checked::pw_multi_aff(pma2)); +} + +isl::checked::pw_multi_aff pw_multi_aff::union_add(const isl::checked::pw_aff &pma2) const +{ + return this->union_add(isl::checked::pw_multi_aff(pma2)); +} + +isl::checked::pw_multi_aff pw_multi_aff::zero(isl::checked::space space) +{ + auto res = isl_pw_multi_aff_zero(space.release()); + return manage(res); +} + +inline std::ostream &operator<<(std::ostream &os, const pw_multi_aff &obj) +{ + char *str = isl_pw_multi_aff_to_str(obj.get()); + if (!str) { + os.setstate(std::ios_base::badbit); + return os; + } + os << str; + free(str); + return os; +} + +// implementations for isl::pw_multi_aff_list +pw_multi_aff_list manage(__isl_take isl_pw_multi_aff_list *ptr) { + return pw_multi_aff_list(ptr); +} +pw_multi_aff_list manage_copy(__isl_keep isl_pw_multi_aff_list *ptr) { + ptr = isl_pw_multi_aff_list_copy(ptr); + return pw_multi_aff_list(ptr); +} + +pw_multi_aff_list::pw_multi_aff_list(__isl_take isl_pw_multi_aff_list *ptr) + : ptr(ptr) {} + +pw_multi_aff_list::pw_multi_aff_list() + : ptr(nullptr) {} + +pw_multi_aff_list::pw_multi_aff_list(const pw_multi_aff_list &obj) + : ptr(nullptr) +{ + ptr = obj.copy(); +} + +pw_multi_aff_list::pw_multi_aff_list(isl::checked::ctx ctx, int n) +{ + auto res = isl_pw_multi_aff_list_alloc(ctx.release(), n); + ptr = res; +} + +pw_multi_aff_list::pw_multi_aff_list(isl::checked::pw_multi_aff el) +{ + auto res = isl_pw_multi_aff_list_from_pw_multi_aff(el.release()); + ptr = res; +} + +pw_multi_aff_list::pw_multi_aff_list(isl::checked::ctx ctx, const std::string &str) +{ + auto res = isl_pw_multi_aff_list_read_from_str(ctx.release(), str.c_str()); + ptr = res; +} + +pw_multi_aff_list &pw_multi_aff_list::operator=(pw_multi_aff_list obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +pw_multi_aff_list::~pw_multi_aff_list() { + if (ptr) + isl_pw_multi_aff_list_free(ptr); +} + +__isl_give isl_pw_multi_aff_list *pw_multi_aff_list::copy() const & { + return isl_pw_multi_aff_list_copy(ptr); +} + +__isl_keep isl_pw_multi_aff_list *pw_multi_aff_list::get() const { + return ptr; +} + +__isl_give isl_pw_multi_aff_list *pw_multi_aff_list::release() { + isl_pw_multi_aff_list *tmp = ptr; + ptr = nullptr; + return tmp; +} + +bool pw_multi_aff_list::is_null() const { + return ptr == nullptr; +} + +isl::checked::ctx pw_multi_aff_list::ctx() const { + return isl::checked::ctx(isl_pw_multi_aff_list_get_ctx(ptr)); +} + +isl::checked::pw_multi_aff_list pw_multi_aff_list::add(isl::checked::pw_multi_aff el) const +{ + auto res = isl_pw_multi_aff_list_add(copy(), el.release()); + return manage(res); +} + +isl::checked::pw_multi_aff pw_multi_aff_list::at(int index) const +{ + auto res = isl_pw_multi_aff_list_get_at(get(), index); + return manage(res); +} + +isl::checked::pw_multi_aff pw_multi_aff_list::get_at(int index) const +{ + return at(index); +} + +isl::checked::pw_multi_aff_list pw_multi_aff_list::clear() const +{ + auto res = isl_pw_multi_aff_list_clear(copy()); + return manage(res); +} + +isl::checked::pw_multi_aff_list pw_multi_aff_list::concat(isl::checked::pw_multi_aff_list list2) const +{ + auto res = isl_pw_multi_aff_list_concat(copy(), list2.release()); + return manage(res); +} + +isl::checked::pw_multi_aff_list pw_multi_aff_list::drop(unsigned int first, unsigned int n) const +{ + auto res = isl_pw_multi_aff_list_drop(copy(), first, n); + return manage(res); +} + +stat pw_multi_aff_list::foreach(const std::function &fn) const +{ + struct fn_data { + std::function func; + } fn_data = { fn }; + auto fn_lambda = [](isl_pw_multi_aff *arg_0, void *arg_1) -> isl_stat { + auto *data = static_cast(arg_1); + auto ret = (data->func)(manage(arg_0)); + return ret.release(); + }; + auto res = isl_pw_multi_aff_list_foreach(get(), fn_lambda, &fn_data); + return manage(res); +} + +stat pw_multi_aff_list::foreach_scc(const std::function &follows, const std::function &fn) const +{ + struct follows_data { + std::function func; + } follows_data = { follows }; + auto follows_lambda = [](isl_pw_multi_aff *arg_0, isl_pw_multi_aff *arg_1, void *arg_2) -> isl_bool { + auto *data = static_cast(arg_2); + auto ret = (data->func)(manage_copy(arg_0), manage_copy(arg_1)); + return ret.release(); + }; + struct fn_data { + std::function func; + } fn_data = { fn }; + auto fn_lambda = [](isl_pw_multi_aff_list *arg_0, void *arg_1) -> isl_stat { + auto *data = static_cast(arg_1); + auto ret = (data->func)(manage(arg_0)); + return ret.release(); + }; + auto res = isl_pw_multi_aff_list_foreach_scc(get(), follows_lambda, &follows_data, fn_lambda, &fn_data); + return manage(res); +} + +isl::checked::pw_multi_aff_list pw_multi_aff_list::insert(unsigned int pos, isl::checked::pw_multi_aff el) const +{ + auto res = isl_pw_multi_aff_list_insert(copy(), pos, el.release()); + return manage(res); +} + +isl::checked::pw_multi_aff_list pw_multi_aff_list::set_at(int index, isl::checked::pw_multi_aff el) const +{ + auto res = isl_pw_multi_aff_list_set_at(copy(), index, el.release()); + return manage(res); +} + +class size pw_multi_aff_list::size() const +{ + auto res = isl_pw_multi_aff_list_size(get()); + return manage(res); +} + +inline std::ostream &operator<<(std::ostream &os, const pw_multi_aff_list &obj) +{ + char *str = isl_pw_multi_aff_list_to_str(obj.get()); + if (!str) { + os.setstate(std::ios_base::badbit); + return os; + } + os << str; + free(str); + return os; +} + +// implementations for isl::schedule +schedule manage(__isl_take isl_schedule *ptr) { + return schedule(ptr); +} +schedule manage_copy(__isl_keep isl_schedule *ptr) { + ptr = isl_schedule_copy(ptr); + return schedule(ptr); +} + +schedule::schedule(__isl_take isl_schedule *ptr) + : ptr(ptr) {} + +schedule::schedule() + : ptr(nullptr) {} + +schedule::schedule(const schedule &obj) + : ptr(nullptr) +{ + ptr = obj.copy(); +} + +schedule::schedule(isl::checked::ctx ctx, const std::string &str) +{ + auto res = isl_schedule_read_from_str(ctx.release(), str.c_str()); + ptr = res; +} + +schedule &schedule::operator=(schedule obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +schedule::~schedule() { + if (ptr) + isl_schedule_free(ptr); +} + +__isl_give isl_schedule *schedule::copy() const & { + return isl_schedule_copy(ptr); +} + +__isl_keep isl_schedule *schedule::get() const { + return ptr; +} + +__isl_give isl_schedule *schedule::release() { + isl_schedule *tmp = ptr; + ptr = nullptr; + return tmp; +} + +bool schedule::is_null() const { + return ptr == nullptr; +} + +isl::checked::ctx schedule::ctx() const { + return isl::checked::ctx(isl_schedule_get_ctx(ptr)); +} + +isl::checked::union_set schedule::domain() const +{ + auto res = isl_schedule_get_domain(get()); + return manage(res); +} + +isl::checked::union_set schedule::get_domain() const +{ + return domain(); +} + +isl::checked::schedule schedule::from_domain(isl::checked::union_set domain) +{ + auto res = isl_schedule_from_domain(domain.release()); + return manage(res); +} + +isl::checked::union_map schedule::map() const +{ + auto res = isl_schedule_get_map(get()); + return manage(res); +} + +isl::checked::union_map schedule::get_map() const +{ + return map(); +} + +isl::checked::schedule schedule::pullback(isl::checked::union_pw_multi_aff upma) const +{ + auto res = isl_schedule_pullback_union_pw_multi_aff(copy(), upma.release()); + return manage(res); +} + +isl::checked::schedule_node schedule::root() const +{ + auto res = isl_schedule_get_root(get()); + return manage(res); +} + +isl::checked::schedule_node schedule::get_root() const +{ + return root(); +} + +inline std::ostream &operator<<(std::ostream &os, const schedule &obj) +{ + char *str = isl_schedule_to_str(obj.get()); + if (!str) { + os.setstate(std::ios_base::badbit); + return os; + } + os << str; + free(str); + return os; +} + +// implementations for isl::schedule_constraints +schedule_constraints manage(__isl_take isl_schedule_constraints *ptr) { + return schedule_constraints(ptr); +} +schedule_constraints manage_copy(__isl_keep isl_schedule_constraints *ptr) { + ptr = isl_schedule_constraints_copy(ptr); + return schedule_constraints(ptr); +} + +schedule_constraints::schedule_constraints(__isl_take isl_schedule_constraints *ptr) + : ptr(ptr) {} + +schedule_constraints::schedule_constraints() + : ptr(nullptr) {} + +schedule_constraints::schedule_constraints(const schedule_constraints &obj) + : ptr(nullptr) +{ + ptr = obj.copy(); +} + +schedule_constraints::schedule_constraints(isl::checked::ctx ctx, const std::string &str) +{ + auto res = isl_schedule_constraints_read_from_str(ctx.release(), str.c_str()); + ptr = res; +} + +schedule_constraints &schedule_constraints::operator=(schedule_constraints obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +schedule_constraints::~schedule_constraints() { + if (ptr) + isl_schedule_constraints_free(ptr); +} + +__isl_give isl_schedule_constraints *schedule_constraints::copy() const & { + return isl_schedule_constraints_copy(ptr); +} + +__isl_keep isl_schedule_constraints *schedule_constraints::get() const { + return ptr; +} + +__isl_give isl_schedule_constraints *schedule_constraints::release() { + isl_schedule_constraints *tmp = ptr; + ptr = nullptr; + return tmp; +} + +bool schedule_constraints::is_null() const { + return ptr == nullptr; +} + +isl::checked::ctx schedule_constraints::ctx() const { + return isl::checked::ctx(isl_schedule_constraints_get_ctx(ptr)); +} + +isl::checked::union_map schedule_constraints::coincidence() const +{ + auto res = isl_schedule_constraints_get_coincidence(get()); + return manage(res); +} + +isl::checked::union_map schedule_constraints::get_coincidence() const +{ + return coincidence(); +} + +isl::checked::schedule schedule_constraints::compute_schedule() const +{ + auto res = isl_schedule_constraints_compute_schedule(copy()); + return manage(res); +} + +isl::checked::union_map schedule_constraints::conditional_validity() const +{ + auto res = isl_schedule_constraints_get_conditional_validity(get()); + return manage(res); +} + +isl::checked::union_map schedule_constraints::get_conditional_validity() const +{ + return conditional_validity(); +} + +isl::checked::union_map schedule_constraints::conditional_validity_condition() const +{ + auto res = isl_schedule_constraints_get_conditional_validity_condition(get()); + return manage(res); +} + +isl::checked::union_map schedule_constraints::get_conditional_validity_condition() const +{ + return conditional_validity_condition(); +} + +isl::checked::set schedule_constraints::context() const +{ + auto res = isl_schedule_constraints_get_context(get()); + return manage(res); +} + +isl::checked::set schedule_constraints::get_context() const +{ + return context(); +} + +isl::checked::union_set schedule_constraints::domain() const +{ + auto res = isl_schedule_constraints_get_domain(get()); + return manage(res); +} + +isl::checked::union_set schedule_constraints::get_domain() const +{ + return domain(); +} + +isl::checked::schedule_constraints schedule_constraints::on_domain(isl::checked::union_set domain) +{ + auto res = isl_schedule_constraints_on_domain(domain.release()); + return manage(res); +} + +isl::checked::union_map schedule_constraints::proximity() const +{ + auto res = isl_schedule_constraints_get_proximity(get()); + return manage(res); +} + +isl::checked::union_map schedule_constraints::get_proximity() const +{ + return proximity(); +} + +isl::checked::schedule_constraints schedule_constraints::set_coincidence(isl::checked::union_map coincidence) const +{ + auto res = isl_schedule_constraints_set_coincidence(copy(), coincidence.release()); + return manage(res); +} + +isl::checked::schedule_constraints schedule_constraints::set_conditional_validity(isl::checked::union_map condition, isl::checked::union_map validity) const +{ + auto res = isl_schedule_constraints_set_conditional_validity(copy(), condition.release(), validity.release()); + return manage(res); +} + +isl::checked::schedule_constraints schedule_constraints::set_context(isl::checked::set context) const +{ + auto res = isl_schedule_constraints_set_context(copy(), context.release()); + return manage(res); +} + +isl::checked::schedule_constraints schedule_constraints::set_proximity(isl::checked::union_map proximity) const +{ + auto res = isl_schedule_constraints_set_proximity(copy(), proximity.release()); + return manage(res); +} + +isl::checked::schedule_constraints schedule_constraints::set_validity(isl::checked::union_map validity) const +{ + auto res = isl_schedule_constraints_set_validity(copy(), validity.release()); + return manage(res); +} + +isl::checked::union_map schedule_constraints::validity() const +{ + auto res = isl_schedule_constraints_get_validity(get()); + return manage(res); +} + +isl::checked::union_map schedule_constraints::get_validity() const +{ + return validity(); +} + +inline std::ostream &operator<<(std::ostream &os, const schedule_constraints &obj) +{ + char *str = isl_schedule_constraints_to_str(obj.get()); + if (!str) { + os.setstate(std::ios_base::badbit); + return os; + } + os << str; + free(str); + return os; +} + +// implementations for isl::schedule_node +schedule_node manage(__isl_take isl_schedule_node *ptr) { + return schedule_node(ptr); +} +schedule_node manage_copy(__isl_keep isl_schedule_node *ptr) { + ptr = isl_schedule_node_copy(ptr); + return schedule_node(ptr); +} + +schedule_node::schedule_node(__isl_take isl_schedule_node *ptr) + : ptr(ptr) {} + +schedule_node::schedule_node() + : ptr(nullptr) {} + +schedule_node::schedule_node(const schedule_node &obj) + : ptr(nullptr) +{ + ptr = obj.copy(); +} + +schedule_node &schedule_node::operator=(schedule_node obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +schedule_node::~schedule_node() { + if (ptr) + isl_schedule_node_free(ptr); +} + +__isl_give isl_schedule_node *schedule_node::copy() const & { + return isl_schedule_node_copy(ptr); +} + +__isl_keep isl_schedule_node *schedule_node::get() const { + return ptr; +} + +__isl_give isl_schedule_node *schedule_node::release() { + isl_schedule_node *tmp = ptr; + ptr = nullptr; + return tmp; +} + +bool schedule_node::is_null() const { + return ptr == nullptr; +} + +template +boolean schedule_node::isa_type(T subtype) const +{ + if (is_null()) + return boolean(); + return isl_schedule_node_get_type(get()) == subtype; +} +template +boolean schedule_node::isa() const +{ + return isa_type(T::type); +} +template +T schedule_node::as() const +{ + if (isa().is_false()) + isl_die(ctx().get(), isl_error_invalid, "not an object of the requested subtype", return T()); + return T(copy()); +} + +isl::checked::ctx schedule_node::ctx() const { + return isl::checked::ctx(isl_schedule_node_get_ctx(ptr)); +} + +isl::checked::schedule_node schedule_node::ancestor(int generation) const +{ + auto res = isl_schedule_node_ancestor(copy(), generation); + return manage(res); +} + +class size schedule_node::ancestor_child_position(const isl::checked::schedule_node &ancestor) const +{ + auto res = isl_schedule_node_get_ancestor_child_position(get(), ancestor.get()); + return manage(res); +} + +class size schedule_node::get_ancestor_child_position(const isl::checked::schedule_node &ancestor) const +{ + return ancestor_child_position(ancestor); +} + +isl::checked::schedule_node schedule_node::child(int pos) const +{ + auto res = isl_schedule_node_child(copy(), pos); + return manage(res); +} + +class size schedule_node::child_position() const +{ + auto res = isl_schedule_node_get_child_position(get()); + return manage(res); +} + +class size schedule_node::get_child_position() const +{ + return child_position(); +} + +boolean schedule_node::every_descendant(const std::function &test) const +{ + struct test_data { + std::function func; + } test_data = { test }; + auto test_lambda = [](isl_schedule_node *arg_0, void *arg_1) -> isl_bool { + auto *data = static_cast(arg_1); + auto ret = (data->func)(manage_copy(arg_0)); + return ret.release(); + }; + auto res = isl_schedule_node_every_descendant(get(), test_lambda, &test_data); + return manage(res); +} + +isl::checked::schedule_node schedule_node::first_child() const +{ + auto res = isl_schedule_node_first_child(copy()); + return manage(res); +} + +stat schedule_node::foreach_ancestor_top_down(const std::function &fn) const +{ + struct fn_data { + std::function func; + } fn_data = { fn }; + auto fn_lambda = [](isl_schedule_node *arg_0, void *arg_1) -> isl_stat { + auto *data = static_cast(arg_1); + auto ret = (data->func)(manage_copy(arg_0)); + return ret.release(); + }; + auto res = isl_schedule_node_foreach_ancestor_top_down(get(), fn_lambda, &fn_data); + return manage(res); +} + +stat schedule_node::foreach_descendant_top_down(const std::function &fn) const +{ + struct fn_data { + std::function func; + } fn_data = { fn }; + auto fn_lambda = [](isl_schedule_node *arg_0, void *arg_1) -> isl_bool { + auto *data = static_cast(arg_1); + auto ret = (data->func)(manage_copy(arg_0)); + return ret.release(); + }; + auto res = isl_schedule_node_foreach_descendant_top_down(get(), fn_lambda, &fn_data); + return manage(res); +} + +isl::checked::schedule_node schedule_node::from_domain(isl::checked::union_set domain) +{ + auto res = isl_schedule_node_from_domain(domain.release()); + return manage(res); +} + +isl::checked::schedule_node schedule_node::from_extension(isl::checked::union_map extension) +{ + auto res = isl_schedule_node_from_extension(extension.release()); + return manage(res); +} + +isl::checked::schedule_node schedule_node::graft_after(isl::checked::schedule_node graft) const +{ + auto res = isl_schedule_node_graft_after(copy(), graft.release()); + return manage(res); +} + +isl::checked::schedule_node schedule_node::graft_before(isl::checked::schedule_node graft) const +{ + auto res = isl_schedule_node_graft_before(copy(), graft.release()); + return manage(res); +} + +boolean schedule_node::has_children() const +{ + auto res = isl_schedule_node_has_children(get()); + return manage(res); +} + +boolean schedule_node::has_next_sibling() const +{ + auto res = isl_schedule_node_has_next_sibling(get()); + return manage(res); +} + +boolean schedule_node::has_parent() const +{ + auto res = isl_schedule_node_has_parent(get()); + return manage(res); +} + +boolean schedule_node::has_previous_sibling() const +{ + auto res = isl_schedule_node_has_previous_sibling(get()); + return manage(res); +} + +isl::checked::schedule_node schedule_node::insert_context(isl::checked::set context) const +{ + auto res = isl_schedule_node_insert_context(copy(), context.release()); + return manage(res); +} + +isl::checked::schedule_node schedule_node::insert_filter(isl::checked::union_set filter) const +{ + auto res = isl_schedule_node_insert_filter(copy(), filter.release()); + return manage(res); +} + +isl::checked::schedule_node schedule_node::insert_guard(isl::checked::set context) const +{ + auto res = isl_schedule_node_insert_guard(copy(), context.release()); + return manage(res); +} + +isl::checked::schedule_node schedule_node::insert_mark(isl::checked::id mark) const +{ + auto res = isl_schedule_node_insert_mark(copy(), mark.release()); + return manage(res); +} + +isl::checked::schedule_node schedule_node::insert_mark(const std::string &mark) const +{ + return this->insert_mark(isl::checked::id(ctx(), mark)); +} + +isl::checked::schedule_node schedule_node::insert_partial_schedule(isl::checked::multi_union_pw_aff schedule) const +{ + auto res = isl_schedule_node_insert_partial_schedule(copy(), schedule.release()); + return manage(res); +} + +isl::checked::schedule_node schedule_node::insert_sequence(isl::checked::union_set_list filters) const +{ + auto res = isl_schedule_node_insert_sequence(copy(), filters.release()); + return manage(res); +} + +isl::checked::schedule_node schedule_node::insert_set(isl::checked::union_set_list filters) const +{ + auto res = isl_schedule_node_insert_set(copy(), filters.release()); + return manage(res); +} + +boolean schedule_node::is_equal(const isl::checked::schedule_node &node2) const +{ + auto res = isl_schedule_node_is_equal(get(), node2.get()); + return manage(res); +} + +boolean schedule_node::is_subtree_anchored() const +{ + auto res = isl_schedule_node_is_subtree_anchored(get()); + return manage(res); +} + +isl::checked::schedule_node schedule_node::map_descendant_bottom_up(const std::function &fn) const +{ + struct fn_data { + std::function func; + } fn_data = { fn }; + auto fn_lambda = [](isl_schedule_node *arg_0, void *arg_1) -> isl_schedule_node * { + auto *data = static_cast(arg_1); + auto ret = (data->func)(manage(arg_0)); + return ret.release(); + }; + auto res = isl_schedule_node_map_descendant_bottom_up(copy(), fn_lambda, &fn_data); + return manage(res); +} + +class size schedule_node::n_children() const +{ + auto res = isl_schedule_node_n_children(get()); + return manage(res); +} + +isl::checked::schedule_node schedule_node::next_sibling() const +{ + auto res = isl_schedule_node_next_sibling(copy()); + return manage(res); +} + +isl::checked::schedule_node schedule_node::order_after(isl::checked::union_set filter) const +{ + auto res = isl_schedule_node_order_after(copy(), filter.release()); + return manage(res); +} + +isl::checked::schedule_node schedule_node::order_before(isl::checked::union_set filter) const +{ + auto res = isl_schedule_node_order_before(copy(), filter.release()); + return manage(res); +} + +isl::checked::schedule_node schedule_node::parent() const +{ + auto res = isl_schedule_node_parent(copy()); + return manage(res); +} + +isl::checked::multi_union_pw_aff schedule_node::prefix_schedule_multi_union_pw_aff() const +{ + auto res = isl_schedule_node_get_prefix_schedule_multi_union_pw_aff(get()); + return manage(res); +} + +isl::checked::multi_union_pw_aff schedule_node::get_prefix_schedule_multi_union_pw_aff() const +{ + return prefix_schedule_multi_union_pw_aff(); +} + +isl::checked::union_map schedule_node::prefix_schedule_union_map() const +{ + auto res = isl_schedule_node_get_prefix_schedule_union_map(get()); + return manage(res); +} + +isl::checked::union_map schedule_node::get_prefix_schedule_union_map() const +{ + return prefix_schedule_union_map(); +} + +isl::checked::union_pw_multi_aff schedule_node::prefix_schedule_union_pw_multi_aff() const +{ + auto res = isl_schedule_node_get_prefix_schedule_union_pw_multi_aff(get()); + return manage(res); +} + +isl::checked::union_pw_multi_aff schedule_node::get_prefix_schedule_union_pw_multi_aff() const +{ + return prefix_schedule_union_pw_multi_aff(); +} + +isl::checked::schedule_node schedule_node::previous_sibling() const +{ + auto res = isl_schedule_node_previous_sibling(copy()); + return manage(res); +} + +isl::checked::schedule_node schedule_node::root() const +{ + auto res = isl_schedule_node_root(copy()); + return manage(res); +} + +isl::checked::schedule schedule_node::schedule() const +{ + auto res = isl_schedule_node_get_schedule(get()); + return manage(res); +} + +isl::checked::schedule schedule_node::get_schedule() const +{ + return schedule(); +} + +isl::checked::schedule_node schedule_node::shared_ancestor(const isl::checked::schedule_node &node2) const +{ + auto res = isl_schedule_node_get_shared_ancestor(get(), node2.get()); + return manage(res); +} + +isl::checked::schedule_node schedule_node::get_shared_ancestor(const isl::checked::schedule_node &node2) const +{ + return shared_ancestor(node2); +} + +class size schedule_node::tree_depth() const +{ + auto res = isl_schedule_node_get_tree_depth(get()); + return manage(res); +} + +class size schedule_node::get_tree_depth() const +{ + return tree_depth(); +} + +inline std::ostream &operator<<(std::ostream &os, const schedule_node &obj) +{ + char *str = isl_schedule_node_to_str(obj.get()); + if (!str) { + os.setstate(std::ios_base::badbit); + return os; + } + os << str; + free(str); + return os; +} + +// implementations for isl::schedule_node_band +schedule_node_band::schedule_node_band(__isl_take isl_schedule_node *ptr) + : schedule_node(ptr) {} + +schedule_node_band::schedule_node_band() + : schedule_node() {} + +schedule_node_band::schedule_node_band(const schedule_node_band &obj) + : schedule_node(obj) +{ +} + +schedule_node_band &schedule_node_band::operator=(schedule_node_band obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +isl::checked::ctx schedule_node_band::ctx() const { + return isl::checked::ctx(isl_schedule_node_get_ctx(ptr)); +} + +isl::checked::union_set schedule_node_band::ast_build_options() const +{ + auto res = isl_schedule_node_band_get_ast_build_options(get()); + return manage(res); +} + +isl::checked::union_set schedule_node_band::get_ast_build_options() const +{ + return ast_build_options(); +} + +isl::checked::set schedule_node_band::ast_isolate_option() const +{ + auto res = isl_schedule_node_band_get_ast_isolate_option(get()); + return manage(res); +} + +isl::checked::set schedule_node_band::get_ast_isolate_option() const +{ + return ast_isolate_option(); +} + +boolean schedule_node_band::member_get_coincident(int pos) const +{ + auto res = isl_schedule_node_band_member_get_coincident(get(), pos); + return manage(res); +} + +schedule_node_band schedule_node_band::member_set_coincident(int pos, int coincident) const +{ + auto res = isl_schedule_node_band_member_set_coincident(copy(), pos, coincident); + return manage(res).as(); +} + +schedule_node_band schedule_node_band::mod(isl::checked::multi_val mv) const +{ + auto res = isl_schedule_node_band_mod(copy(), mv.release()); + return manage(res).as(); +} + +class size schedule_node_band::n_member() const +{ + auto res = isl_schedule_node_band_n_member(get()); + return manage(res); +} + +isl::checked::multi_union_pw_aff schedule_node_band::partial_schedule() const +{ + auto res = isl_schedule_node_band_get_partial_schedule(get()); + return manage(res); +} + +isl::checked::multi_union_pw_aff schedule_node_band::get_partial_schedule() const +{ + return partial_schedule(); +} + +boolean schedule_node_band::permutable() const +{ + auto res = isl_schedule_node_band_get_permutable(get()); + return manage(res); +} + +boolean schedule_node_band::get_permutable() const +{ + return permutable(); +} + +schedule_node_band schedule_node_band::scale(isl::checked::multi_val mv) const +{ + auto res = isl_schedule_node_band_scale(copy(), mv.release()); + return manage(res).as(); +} + +schedule_node_band schedule_node_band::scale_down(isl::checked::multi_val mv) const +{ + auto res = isl_schedule_node_band_scale_down(copy(), mv.release()); + return manage(res).as(); +} + +schedule_node_band schedule_node_band::set_ast_build_options(isl::checked::union_set options) const +{ + auto res = isl_schedule_node_band_set_ast_build_options(copy(), options.release()); + return manage(res).as(); +} + +schedule_node_band schedule_node_band::set_permutable(int permutable) const +{ + auto res = isl_schedule_node_band_set_permutable(copy(), permutable); + return manage(res).as(); +} + +schedule_node_band schedule_node_band::shift(isl::checked::multi_union_pw_aff shift) const +{ + auto res = isl_schedule_node_band_shift(copy(), shift.release()); + return manage(res).as(); +} + +schedule_node_band schedule_node_band::split(int pos) const +{ + auto res = isl_schedule_node_band_split(copy(), pos); + return manage(res).as(); +} + +schedule_node_band schedule_node_band::tile(isl::checked::multi_val sizes) const +{ + auto res = isl_schedule_node_band_tile(copy(), sizes.release()); + return manage(res).as(); +} + +schedule_node_band schedule_node_band::member_set_ast_loop_default(int pos) const +{ + auto res = isl_schedule_node_band_member_set_ast_loop_type(copy(), pos, isl_ast_loop_default); + return manage(res).as(); +} + +schedule_node_band schedule_node_band::member_set_ast_loop_atomic(int pos) const +{ + auto res = isl_schedule_node_band_member_set_ast_loop_type(copy(), pos, isl_ast_loop_atomic); + return manage(res).as(); +} + +schedule_node_band schedule_node_band::member_set_ast_loop_unroll(int pos) const +{ + auto res = isl_schedule_node_band_member_set_ast_loop_type(copy(), pos, isl_ast_loop_unroll); + return manage(res).as(); +} + +schedule_node_band schedule_node_band::member_set_ast_loop_separate(int pos) const +{ + auto res = isl_schedule_node_band_member_set_ast_loop_type(copy(), pos, isl_ast_loop_separate); + return manage(res).as(); +} + +inline std::ostream &operator<<(std::ostream &os, const schedule_node_band &obj) +{ + char *str = isl_schedule_node_to_str(obj.get()); + if (!str) { + os.setstate(std::ios_base::badbit); + return os; + } + os << str; + free(str); + return os; +} + +// implementations for isl::schedule_node_context +schedule_node_context::schedule_node_context(__isl_take isl_schedule_node *ptr) + : schedule_node(ptr) {} + +schedule_node_context::schedule_node_context() + : schedule_node() {} + +schedule_node_context::schedule_node_context(const schedule_node_context &obj) + : schedule_node(obj) +{ +} + +schedule_node_context &schedule_node_context::operator=(schedule_node_context obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +isl::checked::ctx schedule_node_context::ctx() const { + return isl::checked::ctx(isl_schedule_node_get_ctx(ptr)); +} + +isl::checked::set schedule_node_context::context() const +{ + auto res = isl_schedule_node_context_get_context(get()); + return manage(res); +} + +isl::checked::set schedule_node_context::get_context() const +{ + return context(); +} + +inline std::ostream &operator<<(std::ostream &os, const schedule_node_context &obj) +{ + char *str = isl_schedule_node_to_str(obj.get()); + if (!str) { + os.setstate(std::ios_base::badbit); + return os; + } + os << str; + free(str); + return os; +} + +// implementations for isl::schedule_node_domain +schedule_node_domain::schedule_node_domain(__isl_take isl_schedule_node *ptr) + : schedule_node(ptr) {} + +schedule_node_domain::schedule_node_domain() + : schedule_node() {} + +schedule_node_domain::schedule_node_domain(const schedule_node_domain &obj) + : schedule_node(obj) +{ +} + +schedule_node_domain &schedule_node_domain::operator=(schedule_node_domain obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +isl::checked::ctx schedule_node_domain::ctx() const { + return isl::checked::ctx(isl_schedule_node_get_ctx(ptr)); +} + +isl::checked::union_set schedule_node_domain::domain() const +{ + auto res = isl_schedule_node_domain_get_domain(get()); + return manage(res); +} + +isl::checked::union_set schedule_node_domain::get_domain() const +{ + return domain(); +} + +inline std::ostream &operator<<(std::ostream &os, const schedule_node_domain &obj) +{ + char *str = isl_schedule_node_to_str(obj.get()); + if (!str) { + os.setstate(std::ios_base::badbit); + return os; + } + os << str; + free(str); + return os; +} + +// implementations for isl::schedule_node_expansion +schedule_node_expansion::schedule_node_expansion(__isl_take isl_schedule_node *ptr) + : schedule_node(ptr) {} + +schedule_node_expansion::schedule_node_expansion() + : schedule_node() {} + +schedule_node_expansion::schedule_node_expansion(const schedule_node_expansion &obj) + : schedule_node(obj) +{ +} + +schedule_node_expansion &schedule_node_expansion::operator=(schedule_node_expansion obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +isl::checked::ctx schedule_node_expansion::ctx() const { + return isl::checked::ctx(isl_schedule_node_get_ctx(ptr)); +} + +isl::checked::union_pw_multi_aff schedule_node_expansion::contraction() const +{ + auto res = isl_schedule_node_expansion_get_contraction(get()); + return manage(res); +} + +isl::checked::union_pw_multi_aff schedule_node_expansion::get_contraction() const +{ + return contraction(); +} + +isl::checked::union_map schedule_node_expansion::expansion() const +{ + auto res = isl_schedule_node_expansion_get_expansion(get()); + return manage(res); +} + +isl::checked::union_map schedule_node_expansion::get_expansion() const +{ + return expansion(); +} + +inline std::ostream &operator<<(std::ostream &os, const schedule_node_expansion &obj) +{ + char *str = isl_schedule_node_to_str(obj.get()); + if (!str) { + os.setstate(std::ios_base::badbit); + return os; + } + os << str; + free(str); + return os; +} + +// implementations for isl::schedule_node_extension +schedule_node_extension::schedule_node_extension(__isl_take isl_schedule_node *ptr) + : schedule_node(ptr) {} + +schedule_node_extension::schedule_node_extension() + : schedule_node() {} + +schedule_node_extension::schedule_node_extension(const schedule_node_extension &obj) + : schedule_node(obj) +{ +} + +schedule_node_extension &schedule_node_extension::operator=(schedule_node_extension obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +isl::checked::ctx schedule_node_extension::ctx() const { + return isl::checked::ctx(isl_schedule_node_get_ctx(ptr)); +} + +isl::checked::union_map schedule_node_extension::extension() const +{ + auto res = isl_schedule_node_extension_get_extension(get()); + return manage(res); +} + +isl::checked::union_map schedule_node_extension::get_extension() const +{ + return extension(); +} + +inline std::ostream &operator<<(std::ostream &os, const schedule_node_extension &obj) +{ + char *str = isl_schedule_node_to_str(obj.get()); + if (!str) { + os.setstate(std::ios_base::badbit); + return os; + } + os << str; + free(str); + return os; +} + +// implementations for isl::schedule_node_filter +schedule_node_filter::schedule_node_filter(__isl_take isl_schedule_node *ptr) + : schedule_node(ptr) {} + +schedule_node_filter::schedule_node_filter() + : schedule_node() {} + +schedule_node_filter::schedule_node_filter(const schedule_node_filter &obj) + : schedule_node(obj) +{ +} + +schedule_node_filter &schedule_node_filter::operator=(schedule_node_filter obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +isl::checked::ctx schedule_node_filter::ctx() const { + return isl::checked::ctx(isl_schedule_node_get_ctx(ptr)); +} + +isl::checked::union_set schedule_node_filter::filter() const +{ + auto res = isl_schedule_node_filter_get_filter(get()); + return manage(res); +} + +isl::checked::union_set schedule_node_filter::get_filter() const +{ + return filter(); +} + +inline std::ostream &operator<<(std::ostream &os, const schedule_node_filter &obj) +{ + char *str = isl_schedule_node_to_str(obj.get()); + if (!str) { + os.setstate(std::ios_base::badbit); + return os; + } + os << str; + free(str); + return os; +} + +// implementations for isl::schedule_node_guard +schedule_node_guard::schedule_node_guard(__isl_take isl_schedule_node *ptr) + : schedule_node(ptr) {} + +schedule_node_guard::schedule_node_guard() + : schedule_node() {} + +schedule_node_guard::schedule_node_guard(const schedule_node_guard &obj) + : schedule_node(obj) +{ +} + +schedule_node_guard &schedule_node_guard::operator=(schedule_node_guard obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +isl::checked::ctx schedule_node_guard::ctx() const { + return isl::checked::ctx(isl_schedule_node_get_ctx(ptr)); +} + +isl::checked::set schedule_node_guard::guard() const +{ + auto res = isl_schedule_node_guard_get_guard(get()); + return manage(res); +} + +isl::checked::set schedule_node_guard::get_guard() const +{ + return guard(); +} + +inline std::ostream &operator<<(std::ostream &os, const schedule_node_guard &obj) +{ + char *str = isl_schedule_node_to_str(obj.get()); + if (!str) { + os.setstate(std::ios_base::badbit); + return os; + } + os << str; + free(str); + return os; +} + +// implementations for isl::schedule_node_leaf +schedule_node_leaf::schedule_node_leaf(__isl_take isl_schedule_node *ptr) + : schedule_node(ptr) {} + +schedule_node_leaf::schedule_node_leaf() + : schedule_node() {} + +schedule_node_leaf::schedule_node_leaf(const schedule_node_leaf &obj) + : schedule_node(obj) +{ +} + +schedule_node_leaf &schedule_node_leaf::operator=(schedule_node_leaf obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +isl::checked::ctx schedule_node_leaf::ctx() const { + return isl::checked::ctx(isl_schedule_node_get_ctx(ptr)); +} + +inline std::ostream &operator<<(std::ostream &os, const schedule_node_leaf &obj) +{ + char *str = isl_schedule_node_to_str(obj.get()); + if (!str) { + os.setstate(std::ios_base::badbit); + return os; + } + os << str; + free(str); + return os; +} + +// implementations for isl::schedule_node_mark +schedule_node_mark::schedule_node_mark(__isl_take isl_schedule_node *ptr) + : schedule_node(ptr) {} + +schedule_node_mark::schedule_node_mark() + : schedule_node() {} + +schedule_node_mark::schedule_node_mark(const schedule_node_mark &obj) + : schedule_node(obj) +{ +} + +schedule_node_mark &schedule_node_mark::operator=(schedule_node_mark obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +isl::checked::ctx schedule_node_mark::ctx() const { + return isl::checked::ctx(isl_schedule_node_get_ctx(ptr)); +} + +inline std::ostream &operator<<(std::ostream &os, const schedule_node_mark &obj) +{ + char *str = isl_schedule_node_to_str(obj.get()); + if (!str) { + os.setstate(std::ios_base::badbit); + return os; + } + os << str; + free(str); + return os; +} + +// implementations for isl::schedule_node_sequence +schedule_node_sequence::schedule_node_sequence(__isl_take isl_schedule_node *ptr) + : schedule_node(ptr) {} + +schedule_node_sequence::schedule_node_sequence() + : schedule_node() {} + +schedule_node_sequence::schedule_node_sequence(const schedule_node_sequence &obj) + : schedule_node(obj) +{ +} + +schedule_node_sequence &schedule_node_sequence::operator=(schedule_node_sequence obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +isl::checked::ctx schedule_node_sequence::ctx() const { + return isl::checked::ctx(isl_schedule_node_get_ctx(ptr)); +} + +inline std::ostream &operator<<(std::ostream &os, const schedule_node_sequence &obj) +{ + char *str = isl_schedule_node_to_str(obj.get()); + if (!str) { + os.setstate(std::ios_base::badbit); + return os; + } + os << str; + free(str); + return os; +} + +// implementations for isl::schedule_node_set +schedule_node_set::schedule_node_set(__isl_take isl_schedule_node *ptr) + : schedule_node(ptr) {} + +schedule_node_set::schedule_node_set() + : schedule_node() {} + +schedule_node_set::schedule_node_set(const schedule_node_set &obj) + : schedule_node(obj) +{ +} + +schedule_node_set &schedule_node_set::operator=(schedule_node_set obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +isl::checked::ctx schedule_node_set::ctx() const { + return isl::checked::ctx(isl_schedule_node_get_ctx(ptr)); +} + +inline std::ostream &operator<<(std::ostream &os, const schedule_node_set &obj) +{ + char *str = isl_schedule_node_to_str(obj.get()); + if (!str) { + os.setstate(std::ios_base::badbit); + return os; + } + os << str; + free(str); + return os; +} + +// implementations for isl::set +set manage(__isl_take isl_set *ptr) { + return set(ptr); +} +set manage_copy(__isl_keep isl_set *ptr) { + ptr = isl_set_copy(ptr); + return set(ptr); +} + +set::set(__isl_take isl_set *ptr) + : ptr(ptr) {} + +set::set() + : ptr(nullptr) {} + +set::set(const set &obj) + : ptr(nullptr) +{ + ptr = obj.copy(); +} + +set::set(isl::checked::basic_set bset) +{ + auto res = isl_set_from_basic_set(bset.release()); + ptr = res; +} + +set::set(isl::checked::point pnt) +{ + auto res = isl_set_from_point(pnt.release()); + ptr = res; +} + +set::set(isl::checked::ctx ctx, const std::string &str) +{ + auto res = isl_set_read_from_str(ctx.release(), str.c_str()); + ptr = res; +} + +set &set::operator=(set obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +set::~set() { + if (ptr) + isl_set_free(ptr); +} + +__isl_give isl_set *set::copy() const & { + return isl_set_copy(ptr); +} + +__isl_keep isl_set *set::get() const { + return ptr; +} + +__isl_give isl_set *set::release() { + isl_set *tmp = ptr; + ptr = nullptr; + return tmp; +} + +bool set::is_null() const { + return ptr == nullptr; +} + +isl::checked::ctx set::ctx() const { + return isl::checked::ctx(isl_set_get_ctx(ptr)); +} + +isl::checked::basic_set set::affine_hull() const +{ + auto res = isl_set_affine_hull(copy()); + return manage(res); +} + +isl::checked::set set::apply(isl::checked::map map) const +{ + auto res = isl_set_apply(copy(), map.release()); + return manage(res); +} + +isl::checked::union_set set::apply(const isl::checked::union_map &umap) const +{ + return isl::checked::union_set(*this).apply(umap); +} + +isl::checked::set set::apply(const isl::checked::basic_map &map) const +{ + return this->apply(isl::checked::map(map)); +} + +isl::checked::pw_multi_aff set::as_pw_multi_aff() const +{ + auto res = isl_set_as_pw_multi_aff(copy()); + return manage(res); +} + +isl::checked::set set::as_set() const +{ + return isl::checked::union_set(*this).as_set(); +} + +isl::checked::set set::bind(isl::checked::multi_id tuple) const +{ + auto res = isl_set_bind(copy(), tuple.release()); + return manage(res); +} + +isl::checked::set set::coalesce() const +{ + auto res = isl_set_coalesce(copy()); + return manage(res); +} + +isl::checked::set set::complement() const +{ + auto res = isl_set_complement(copy()); + return manage(res); +} + +isl::checked::union_set set::compute_divs() const +{ + return isl::checked::union_set(*this).compute_divs(); +} + +isl::checked::set set::detect_equalities() const +{ + auto res = isl_set_detect_equalities(copy()); + return manage(res); +} + +isl::checked::val set::dim_max_val(int pos) const +{ + auto res = isl_set_dim_max_val(copy(), pos); + return manage(res); +} + +isl::checked::val set::dim_min_val(int pos) const +{ + auto res = isl_set_dim_min_val(copy(), pos); + return manage(res); +} + +isl::checked::set set::drop_unused_params() const +{ + auto res = isl_set_drop_unused_params(copy()); + return manage(res); +} + +isl::checked::set set::empty(isl::checked::space space) +{ + auto res = isl_set_empty(space.release()); + return manage(res); +} + +boolean set::every_set(const std::function &test) const +{ + return isl::checked::union_set(*this).every_set(test); +} + +isl::checked::set set::extract_set(const isl::checked::space &space) const +{ + return isl::checked::union_set(*this).extract_set(space); +} + +isl::checked::set set::flatten() const +{ + auto res = isl_set_flatten(copy()); + return manage(res); +} + +stat set::foreach_basic_set(const std::function &fn) const +{ + struct fn_data { + std::function func; + } fn_data = { fn }; + auto fn_lambda = [](isl_basic_set *arg_0, void *arg_1) -> isl_stat { + auto *data = static_cast(arg_1); + auto ret = (data->func)(manage(arg_0)); + return ret.release(); + }; + auto res = isl_set_foreach_basic_set(get(), fn_lambda, &fn_data); + return manage(res); +} + +stat set::foreach_point(const std::function &fn) const +{ + struct fn_data { + std::function func; + } fn_data = { fn }; + auto fn_lambda = [](isl_point *arg_0, void *arg_1) -> isl_stat { + auto *data = static_cast(arg_1); + auto ret = (data->func)(manage(arg_0)); + return ret.release(); + }; + auto res = isl_set_foreach_point(get(), fn_lambda, &fn_data); + return manage(res); +} + +stat set::foreach_set(const std::function &fn) const +{ + return isl::checked::union_set(*this).foreach_set(fn); +} + +isl::checked::set set::gist(isl::checked::set context) const +{ + auto res = isl_set_gist(copy(), context.release()); + return manage(res); +} + +isl::checked::union_set set::gist(const isl::checked::union_set &context) const +{ + return isl::checked::union_set(*this).gist(context); +} + +isl::checked::set set::gist(const isl::checked::basic_set &context) const +{ + return this->gist(isl::checked::set(context)); +} + +isl::checked::set set::gist(const isl::checked::point &context) const +{ + return this->gist(isl::checked::set(context)); +} + +isl::checked::set set::gist_params(isl::checked::set context) const +{ + auto res = isl_set_gist_params(copy(), context.release()); + return manage(res); +} + +isl::checked::map set::identity() const +{ + auto res = isl_set_identity(copy()); + return manage(res); +} + +isl::checked::pw_aff set::indicator_function() const +{ + auto res = isl_set_indicator_function(copy()); + return manage(res); +} + +isl::checked::map set::insert_domain(isl::checked::space domain) const +{ + auto res = isl_set_insert_domain(copy(), domain.release()); + return manage(res); +} + +isl::checked::set set::intersect(isl::checked::set set2) const +{ + auto res = isl_set_intersect(copy(), set2.release()); + return manage(res); +} + +isl::checked::union_set set::intersect(const isl::checked::union_set &uset2) const +{ + return isl::checked::union_set(*this).intersect(uset2); +} + +isl::checked::set set::intersect(const isl::checked::basic_set &set2) const +{ + return this->intersect(isl::checked::set(set2)); +} + +isl::checked::set set::intersect(const isl::checked::point &set2) const +{ + return this->intersect(isl::checked::set(set2)); +} + +isl::checked::set set::intersect_params(isl::checked::set params) const +{ + auto res = isl_set_intersect_params(copy(), params.release()); + return manage(res); +} + +boolean set::involves_locals() const +{ + auto res = isl_set_involves_locals(get()); + return manage(res); +} + +boolean set::is_disjoint(const isl::checked::set &set2) const +{ + auto res = isl_set_is_disjoint(get(), set2.get()); + return manage(res); +} + +boolean set::is_disjoint(const isl::checked::union_set &uset2) const +{ + return isl::checked::union_set(*this).is_disjoint(uset2); +} + +boolean set::is_disjoint(const isl::checked::basic_set &set2) const +{ + return this->is_disjoint(isl::checked::set(set2)); +} + +boolean set::is_disjoint(const isl::checked::point &set2) const +{ + return this->is_disjoint(isl::checked::set(set2)); +} + +boolean set::is_empty() const +{ + auto res = isl_set_is_empty(get()); + return manage(res); +} + +boolean set::is_equal(const isl::checked::set &set2) const +{ + auto res = isl_set_is_equal(get(), set2.get()); + return manage(res); +} + +boolean set::is_equal(const isl::checked::union_set &uset2) const +{ + return isl::checked::union_set(*this).is_equal(uset2); +} + +boolean set::is_equal(const isl::checked::basic_set &set2) const +{ + return this->is_equal(isl::checked::set(set2)); +} + +boolean set::is_equal(const isl::checked::point &set2) const +{ + return this->is_equal(isl::checked::set(set2)); +} + +boolean set::is_singleton() const +{ + auto res = isl_set_is_singleton(get()); + return manage(res); +} + +boolean set::is_strict_subset(const isl::checked::set &set2) const +{ + auto res = isl_set_is_strict_subset(get(), set2.get()); + return manage(res); +} + +boolean set::is_strict_subset(const isl::checked::union_set &uset2) const +{ + return isl::checked::union_set(*this).is_strict_subset(uset2); +} + +boolean set::is_strict_subset(const isl::checked::basic_set &set2) const +{ + return this->is_strict_subset(isl::checked::set(set2)); +} + +boolean set::is_strict_subset(const isl::checked::point &set2) const +{ + return this->is_strict_subset(isl::checked::set(set2)); +} + +boolean set::is_subset(const isl::checked::set &set2) const +{ + auto res = isl_set_is_subset(get(), set2.get()); + return manage(res); +} + +boolean set::is_subset(const isl::checked::union_set &uset2) const +{ + return isl::checked::union_set(*this).is_subset(uset2); +} + +boolean set::is_subset(const isl::checked::basic_set &set2) const +{ + return this->is_subset(isl::checked::set(set2)); +} + +boolean set::is_subset(const isl::checked::point &set2) const +{ + return this->is_subset(isl::checked::set(set2)); +} + +boolean set::is_wrapping() const +{ + auto res = isl_set_is_wrapping(get()); + return manage(res); +} + +boolean set::isa_set() const +{ + return isl::checked::union_set(*this).isa_set(); +} + +isl::checked::fixed_box set::lattice_tile() const +{ + auto res = isl_set_get_lattice_tile(get()); + return manage(res); +} + +isl::checked::fixed_box set::get_lattice_tile() const +{ + return lattice_tile(); +} + +isl::checked::set set::lexmax() const +{ + auto res = isl_set_lexmax(copy()); + return manage(res); +} + +isl::checked::pw_multi_aff set::lexmax_pw_multi_aff() const +{ + auto res = isl_set_lexmax_pw_multi_aff(copy()); + return manage(res); +} + +isl::checked::set set::lexmin() const +{ + auto res = isl_set_lexmin(copy()); + return manage(res); +} + +isl::checked::pw_multi_aff set::lexmin_pw_multi_aff() const +{ + auto res = isl_set_lexmin_pw_multi_aff(copy()); + return manage(res); +} + +isl::checked::set set::lower_bound(isl::checked::multi_pw_aff lower) const +{ + auto res = isl_set_lower_bound_multi_pw_aff(copy(), lower.release()); + return manage(res); +} + +isl::checked::set set::lower_bound(isl::checked::multi_val lower) const +{ + auto res = isl_set_lower_bound_multi_val(copy(), lower.release()); + return manage(res); +} + +isl::checked::multi_pw_aff set::max_multi_pw_aff() const +{ + auto res = isl_set_max_multi_pw_aff(copy()); + return manage(res); +} + +isl::checked::val set::max_val(const isl::checked::aff &obj) const +{ + auto res = isl_set_max_val(get(), obj.get()); + return manage(res); +} + +isl::checked::multi_pw_aff set::min_multi_pw_aff() const +{ + auto res = isl_set_min_multi_pw_aff(copy()); + return manage(res); +} + +isl::checked::val set::min_val(const isl::checked::aff &obj) const +{ + auto res = isl_set_min_val(get(), obj.get()); + return manage(res); +} + +class size set::n_basic_set() const +{ + auto res = isl_set_n_basic_set(get()); + return manage(res); +} + +isl::checked::pw_aff set::param_pw_aff_on_domain(isl::checked::id id) const +{ + auto res = isl_set_param_pw_aff_on_domain_id(copy(), id.release()); + return manage(res); +} + +isl::checked::pw_aff set::param_pw_aff_on_domain(const std::string &id) const +{ + return this->param_pw_aff_on_domain(isl::checked::id(ctx(), id)); +} + +isl::checked::set set::params() const +{ + auto res = isl_set_params(copy()); + return manage(res); +} + +isl::checked::multi_val set::plain_multi_val_if_fixed() const +{ + auto res = isl_set_get_plain_multi_val_if_fixed(get()); + return manage(res); +} + +isl::checked::multi_val set::get_plain_multi_val_if_fixed() const +{ + return plain_multi_val_if_fixed(); +} + +isl::checked::basic_set set::polyhedral_hull() const +{ + auto res = isl_set_polyhedral_hull(copy()); + return manage(res); +} + +isl::checked::set set::preimage(isl::checked::multi_aff ma) const +{ + auto res = isl_set_preimage_multi_aff(copy(), ma.release()); + return manage(res); +} + +isl::checked::set set::preimage(isl::checked::multi_pw_aff mpa) const +{ + auto res = isl_set_preimage_multi_pw_aff(copy(), mpa.release()); + return manage(res); +} + +isl::checked::set set::preimage(isl::checked::pw_multi_aff pma) const +{ + auto res = isl_set_preimage_pw_multi_aff(copy(), pma.release()); + return manage(res); +} + +isl::checked::union_set set::preimage(const isl::checked::union_pw_multi_aff &upma) const +{ + return isl::checked::union_set(*this).preimage(upma); +} + +isl::checked::set set::product(isl::checked::set set2) const +{ + auto res = isl_set_product(copy(), set2.release()); + return manage(res); +} + +isl::checked::set set::project_out_all_params() const +{ + auto res = isl_set_project_out_all_params(copy()); + return manage(res); +} + +isl::checked::set set::project_out_param(isl::checked::id id) const +{ + auto res = isl_set_project_out_param_id(copy(), id.release()); + return manage(res); +} + +isl::checked::set set::project_out_param(const std::string &id) const +{ + return this->project_out_param(isl::checked::id(ctx(), id)); +} + +isl::checked::set set::project_out_param(isl::checked::id_list list) const +{ + auto res = isl_set_project_out_param_id_list(copy(), list.release()); + return manage(res); +} + +isl::checked::pw_aff set::pw_aff_on_domain(isl::checked::val v) const +{ + auto res = isl_set_pw_aff_on_domain_val(copy(), v.release()); + return manage(res); +} + +isl::checked::pw_aff set::pw_aff_on_domain(long v) const +{ + return this->pw_aff_on_domain(isl::checked::val(ctx(), v)); +} + +isl::checked::pw_multi_aff set::pw_multi_aff_on_domain(isl::checked::multi_val mv) const +{ + auto res = isl_set_pw_multi_aff_on_domain_multi_val(copy(), mv.release()); + return manage(res); +} + +isl::checked::basic_set set::sample() const +{ + auto res = isl_set_sample(copy()); + return manage(res); +} + +isl::checked::point set::sample_point() const +{ + auto res = isl_set_sample_point(copy()); + return manage(res); +} + +isl::checked::set_list set::set_list() const +{ + return isl::checked::union_set(*this).set_list(); +} + +isl::checked::fixed_box set::simple_fixed_box_hull() const +{ + auto res = isl_set_get_simple_fixed_box_hull(get()); + return manage(res); +} + +isl::checked::fixed_box set::get_simple_fixed_box_hull() const +{ + return simple_fixed_box_hull(); +} + +isl::checked::space set::space() const +{ + auto res = isl_set_get_space(get()); + return manage(res); +} + +isl::checked::space set::get_space() const +{ + return space(); +} + +isl::checked::val set::stride(int pos) const +{ + auto res = isl_set_get_stride(get(), pos); + return manage(res); +} + +isl::checked::val set::get_stride(int pos) const +{ + return stride(pos); +} + +isl::checked::set set::subtract(isl::checked::set set2) const +{ + auto res = isl_set_subtract(copy(), set2.release()); + return manage(res); +} + +isl::checked::union_set set::subtract(const isl::checked::union_set &uset2) const +{ + return isl::checked::union_set(*this).subtract(uset2); +} + +isl::checked::set set::subtract(const isl::checked::basic_set &set2) const +{ + return this->subtract(isl::checked::set(set2)); +} + +isl::checked::set set::subtract(const isl::checked::point &set2) const +{ + return this->subtract(isl::checked::set(set2)); +} + +isl::checked::set_list set::to_list() const +{ + auto res = isl_set_to_list(copy()); + return manage(res); +} + +isl::checked::union_set set::to_union_set() const +{ + auto res = isl_set_to_union_set(copy()); + return manage(res); +} + +isl::checked::map set::translation() const +{ + auto res = isl_set_translation(copy()); + return manage(res); +} + +class size set::tuple_dim() const +{ + auto res = isl_set_tuple_dim(get()); + return manage(res); +} + +isl::checked::set set::unbind_params(isl::checked::multi_id tuple) const +{ + auto res = isl_set_unbind_params(copy(), tuple.release()); + return manage(res); +} + +isl::checked::map set::unbind_params_insert_domain(isl::checked::multi_id domain) const +{ + auto res = isl_set_unbind_params_insert_domain(copy(), domain.release()); + return manage(res); +} + +isl::checked::set set::unite(isl::checked::set set2) const +{ + auto res = isl_set_union(copy(), set2.release()); + return manage(res); +} + +isl::checked::union_set set::unite(const isl::checked::union_set &uset2) const +{ + return isl::checked::union_set(*this).unite(uset2); +} + +isl::checked::set set::unite(const isl::checked::basic_set &set2) const +{ + return this->unite(isl::checked::set(set2)); +} + +isl::checked::set set::unite(const isl::checked::point &set2) const +{ + return this->unite(isl::checked::set(set2)); +} + +isl::checked::set set::universe(isl::checked::space space) +{ + auto res = isl_set_universe(space.release()); + return manage(res); +} + +isl::checked::basic_set set::unshifted_simple_hull() const +{ + auto res = isl_set_unshifted_simple_hull(copy()); + return manage(res); +} + +isl::checked::map set::unwrap() const +{ + auto res = isl_set_unwrap(copy()); + return manage(res); +} + +isl::checked::set set::upper_bound(isl::checked::multi_pw_aff upper) const +{ + auto res = isl_set_upper_bound_multi_pw_aff(copy(), upper.release()); + return manage(res); +} + +isl::checked::set set::upper_bound(isl::checked::multi_val upper) const +{ + auto res = isl_set_upper_bound_multi_val(copy(), upper.release()); + return manage(res); +} + +isl::checked::set set::wrapped_reverse() const +{ + auto res = isl_set_wrapped_reverse(copy()); + return manage(res); +} + +inline std::ostream &operator<<(std::ostream &os, const set &obj) +{ + char *str = isl_set_to_str(obj.get()); + if (!str) { + os.setstate(std::ios_base::badbit); + return os; + } + os << str; + free(str); + return os; +} + +// implementations for isl::set_list +set_list manage(__isl_take isl_set_list *ptr) { + return set_list(ptr); +} +set_list manage_copy(__isl_keep isl_set_list *ptr) { + ptr = isl_set_list_copy(ptr); + return set_list(ptr); +} + +set_list::set_list(__isl_take isl_set_list *ptr) + : ptr(ptr) {} + +set_list::set_list() + : ptr(nullptr) {} + +set_list::set_list(const set_list &obj) + : ptr(nullptr) +{ + ptr = obj.copy(); +} + +set_list::set_list(isl::checked::ctx ctx, int n) +{ + auto res = isl_set_list_alloc(ctx.release(), n); + ptr = res; +} + +set_list::set_list(isl::checked::set el) +{ + auto res = isl_set_list_from_set(el.release()); + ptr = res; +} + +set_list::set_list(isl::checked::ctx ctx, const std::string &str) +{ + auto res = isl_set_list_read_from_str(ctx.release(), str.c_str()); + ptr = res; +} + +set_list &set_list::operator=(set_list obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +set_list::~set_list() { + if (ptr) + isl_set_list_free(ptr); +} + +__isl_give isl_set_list *set_list::copy() const & { + return isl_set_list_copy(ptr); +} + +__isl_keep isl_set_list *set_list::get() const { + return ptr; +} + +__isl_give isl_set_list *set_list::release() { + isl_set_list *tmp = ptr; + ptr = nullptr; + return tmp; +} + +bool set_list::is_null() const { + return ptr == nullptr; +} + +isl::checked::ctx set_list::ctx() const { + return isl::checked::ctx(isl_set_list_get_ctx(ptr)); +} + +isl::checked::set_list set_list::add(isl::checked::set el) const +{ + auto res = isl_set_list_add(copy(), el.release()); + return manage(res); +} + +isl::checked::set set_list::at(int index) const +{ + auto res = isl_set_list_get_at(get(), index); + return manage(res); +} + +isl::checked::set set_list::get_at(int index) const +{ + return at(index); +} + +isl::checked::set_list set_list::clear() const +{ + auto res = isl_set_list_clear(copy()); + return manage(res); +} + +isl::checked::set_list set_list::concat(isl::checked::set_list list2) const +{ + auto res = isl_set_list_concat(copy(), list2.release()); + return manage(res); +} + +isl::checked::set_list set_list::drop(unsigned int first, unsigned int n) const +{ + auto res = isl_set_list_drop(copy(), first, n); + return manage(res); +} + +stat set_list::foreach(const std::function &fn) const +{ + struct fn_data { + std::function func; + } fn_data = { fn }; + auto fn_lambda = [](isl_set *arg_0, void *arg_1) -> isl_stat { + auto *data = static_cast(arg_1); + auto ret = (data->func)(manage(arg_0)); + return ret.release(); + }; + auto res = isl_set_list_foreach(get(), fn_lambda, &fn_data); + return manage(res); +} + +stat set_list::foreach_scc(const std::function &follows, const std::function &fn) const +{ + struct follows_data { + std::function func; + } follows_data = { follows }; + auto follows_lambda = [](isl_set *arg_0, isl_set *arg_1, void *arg_2) -> isl_bool { + auto *data = static_cast(arg_2); + auto ret = (data->func)(manage_copy(arg_0), manage_copy(arg_1)); + return ret.release(); + }; + struct fn_data { + std::function func; + } fn_data = { fn }; + auto fn_lambda = [](isl_set_list *arg_0, void *arg_1) -> isl_stat { + auto *data = static_cast(arg_1); + auto ret = (data->func)(manage(arg_0)); + return ret.release(); + }; + auto res = isl_set_list_foreach_scc(get(), follows_lambda, &follows_data, fn_lambda, &fn_data); + return manage(res); +} + +isl::checked::set_list set_list::insert(unsigned int pos, isl::checked::set el) const +{ + auto res = isl_set_list_insert(copy(), pos, el.release()); + return manage(res); +} + +isl::checked::set_list set_list::set_at(int index, isl::checked::set el) const +{ + auto res = isl_set_list_set_at(copy(), index, el.release()); + return manage(res); +} + +class size set_list::size() const +{ + auto res = isl_set_list_size(get()); + return manage(res); +} + +inline std::ostream &operator<<(std::ostream &os, const set_list &obj) +{ + char *str = isl_set_list_to_str(obj.get()); + if (!str) { + os.setstate(std::ios_base::badbit); + return os; + } + os << str; + free(str); + return os; +} + +// implementations for isl::space +space manage(__isl_take isl_space *ptr) { + return space(ptr); +} +space manage_copy(__isl_keep isl_space *ptr) { + ptr = isl_space_copy(ptr); + return space(ptr); +} + +space::space(__isl_take isl_space *ptr) + : ptr(ptr) {} + +space::space() + : ptr(nullptr) {} + +space::space(const space &obj) + : ptr(nullptr) +{ + ptr = obj.copy(); +} + +space::space(isl::checked::ctx ctx, const std::string &str) +{ + auto res = isl_space_read_from_str(ctx.release(), str.c_str()); + ptr = res; +} + +space &space::operator=(space obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +space::~space() { + if (ptr) + isl_space_free(ptr); +} + +__isl_give isl_space *space::copy() const & { + return isl_space_copy(ptr); +} + +__isl_keep isl_space *space::get() const { + return ptr; +} + +__isl_give isl_space *space::release() { + isl_space *tmp = ptr; + ptr = nullptr; + return tmp; +} + +bool space::is_null() const { + return ptr == nullptr; +} + +isl::checked::ctx space::ctx() const { + return isl::checked::ctx(isl_space_get_ctx(ptr)); +} + +isl::checked::space space::add_named_tuple(isl::checked::id tuple_id, unsigned int dim) const +{ + auto res = isl_space_add_named_tuple_id_ui(copy(), tuple_id.release(), dim); + return manage(res); +} + +isl::checked::space space::add_named_tuple(const std::string &tuple_id, unsigned int dim) const +{ + return this->add_named_tuple(isl::checked::id(ctx(), tuple_id), dim); +} + +isl::checked::space space::add_param(isl::checked::id id) const +{ + auto res = isl_space_add_param_id(copy(), id.release()); + return manage(res); +} + +isl::checked::space space::add_param(const std::string &id) const +{ + return this->add_param(isl::checked::id(ctx(), id)); +} + +isl::checked::space space::add_unnamed_tuple(unsigned int dim) const +{ + auto res = isl_space_add_unnamed_tuple_ui(copy(), dim); + return manage(res); +} + +isl::checked::space space::curry() const +{ + auto res = isl_space_curry(copy()); + return manage(res); +} + +isl::checked::space space::domain() const +{ + auto res = isl_space_domain(copy()); + return manage(res); +} + +isl::checked::multi_aff space::domain_map_multi_aff() const +{ + auto res = isl_space_domain_map_multi_aff(copy()); + return manage(res); +} + +isl::checked::pw_multi_aff space::domain_map_pw_multi_aff() const +{ + auto res = isl_space_domain_map_pw_multi_aff(copy()); + return manage(res); +} + +isl::checked::space space::domain_reverse() const +{ + auto res = isl_space_domain_reverse(copy()); + return manage(res); +} + +isl::checked::id space::domain_tuple_id() const +{ + auto res = isl_space_get_domain_tuple_id(get()); + return manage(res); +} + +isl::checked::id space::get_domain_tuple_id() const +{ + return domain_tuple_id(); +} + +isl::checked::space space::drop_all_params() const +{ + auto res = isl_space_drop_all_params(copy()); + return manage(res); +} + +isl::checked::space space::flatten_domain() const +{ + auto res = isl_space_flatten_domain(copy()); + return manage(res); +} + +isl::checked::space space::flatten_range() const +{ + auto res = isl_space_flatten_range(copy()); + return manage(res); +} + +boolean space::has_domain_tuple_id() const +{ + auto res = isl_space_has_domain_tuple_id(get()); + return manage(res); +} + +boolean space::has_range_tuple_id() const +{ + auto res = isl_space_has_range_tuple_id(get()); + return manage(res); +} + +isl::checked::multi_aff space::identity_multi_aff_on_domain() const +{ + auto res = isl_space_identity_multi_aff_on_domain(copy()); + return manage(res); +} + +isl::checked::multi_pw_aff space::identity_multi_pw_aff_on_domain() const +{ + auto res = isl_space_identity_multi_pw_aff_on_domain(copy()); + return manage(res); +} + +isl::checked::pw_multi_aff space::identity_pw_multi_aff_on_domain() const +{ + auto res = isl_space_identity_pw_multi_aff_on_domain(copy()); + return manage(res); +} + +boolean space::is_equal(const isl::checked::space &space2) const +{ + auto res = isl_space_is_equal(get(), space2.get()); + return manage(res); +} + +boolean space::is_wrapping() const +{ + auto res = isl_space_is_wrapping(get()); + return manage(res); +} + +isl::checked::space space::map_from_set() const +{ + auto res = isl_space_map_from_set(copy()); + return manage(res); +} + +isl::checked::multi_aff space::multi_aff(isl::checked::aff_list list) const +{ + auto res = isl_space_multi_aff(copy(), list.release()); + return manage(res); +} + +isl::checked::multi_aff space::multi_aff_on_domain(isl::checked::multi_val mv) const +{ + auto res = isl_space_multi_aff_on_domain_multi_val(copy(), mv.release()); + return manage(res); +} + +isl::checked::multi_id space::multi_id(isl::checked::id_list list) const +{ + auto res = isl_space_multi_id(copy(), list.release()); + return manage(res); +} + +isl::checked::multi_pw_aff space::multi_pw_aff(isl::checked::pw_aff_list list) const +{ + auto res = isl_space_multi_pw_aff(copy(), list.release()); + return manage(res); +} + +isl::checked::multi_union_pw_aff space::multi_union_pw_aff(isl::checked::union_pw_aff_list list) const +{ + auto res = isl_space_multi_union_pw_aff(copy(), list.release()); + return manage(res); +} + +isl::checked::multi_val space::multi_val(isl::checked::val_list list) const +{ + auto res = isl_space_multi_val(copy(), list.release()); + return manage(res); +} + +isl::checked::aff space::param_aff_on_domain(isl::checked::id id) const +{ + auto res = isl_space_param_aff_on_domain_id(copy(), id.release()); + return manage(res); +} + +isl::checked::aff space::param_aff_on_domain(const std::string &id) const +{ + return this->param_aff_on_domain(isl::checked::id(ctx(), id)); +} + +isl::checked::space space::params() const +{ + auto res = isl_space_params(copy()); + return manage(res); +} + +isl::checked::space space::product(isl::checked::space right) const +{ + auto res = isl_space_product(copy(), right.release()); + return manage(res); +} + +isl::checked::space space::range() const +{ + auto res = isl_space_range(copy()); + return manage(res); +} + +isl::checked::multi_aff space::range_map_multi_aff() const +{ + auto res = isl_space_range_map_multi_aff(copy()); + return manage(res); +} + +isl::checked::pw_multi_aff space::range_map_pw_multi_aff() const +{ + auto res = isl_space_range_map_pw_multi_aff(copy()); + return manage(res); +} + +isl::checked::space space::range_reverse() const +{ + auto res = isl_space_range_reverse(copy()); + return manage(res); +} + +isl::checked::id space::range_tuple_id() const +{ + auto res = isl_space_get_range_tuple_id(get()); + return manage(res); +} + +isl::checked::id space::get_range_tuple_id() const +{ + return range_tuple_id(); +} + +isl::checked::space space::reverse() const +{ + auto res = isl_space_reverse(copy()); + return manage(res); +} + +isl::checked::space space::set_domain_tuple(isl::checked::id id) const +{ + auto res = isl_space_set_domain_tuple_id(copy(), id.release()); + return manage(res); +} + +isl::checked::space space::set_domain_tuple(const std::string &id) const +{ + return this->set_domain_tuple(isl::checked::id(ctx(), id)); +} + +isl::checked::space space::set_range_tuple(isl::checked::id id) const +{ + auto res = isl_space_set_range_tuple_id(copy(), id.release()); + return manage(res); +} + +isl::checked::space space::set_range_tuple(const std::string &id) const +{ + return this->set_range_tuple(isl::checked::id(ctx(), id)); +} + +isl::checked::space space::uncurry() const +{ + auto res = isl_space_uncurry(copy()); + return manage(res); +} + +isl::checked::space space::unit(isl::checked::ctx ctx) +{ + auto res = isl_space_unit(ctx.release()); + return manage(res); +} + +isl::checked::map space::universe_map() const +{ + auto res = isl_space_universe_map(copy()); + return manage(res); +} + +isl::checked::set space::universe_set() const +{ + auto res = isl_space_universe_set(copy()); + return manage(res); +} + +isl::checked::space space::unwrap() const +{ + auto res = isl_space_unwrap(copy()); + return manage(res); +} + +isl::checked::space space::wrap() const +{ + auto res = isl_space_wrap(copy()); + return manage(res); +} + +isl::checked::space space::wrapped_reverse() const +{ + auto res = isl_space_wrapped_reverse(copy()); + return manage(res); +} + +isl::checked::aff space::zero_aff_on_domain() const +{ + auto res = isl_space_zero_aff_on_domain(copy()); + return manage(res); +} + +isl::checked::multi_aff space::zero_multi_aff() const +{ + auto res = isl_space_zero_multi_aff(copy()); + return manage(res); +} + +isl::checked::multi_pw_aff space::zero_multi_pw_aff() const +{ + auto res = isl_space_zero_multi_pw_aff(copy()); + return manage(res); +} + +isl::checked::multi_union_pw_aff space::zero_multi_union_pw_aff() const +{ + auto res = isl_space_zero_multi_union_pw_aff(copy()); + return manage(res); +} + +isl::checked::multi_val space::zero_multi_val() const +{ + auto res = isl_space_zero_multi_val(copy()); + return manage(res); +} + +inline std::ostream &operator<<(std::ostream &os, const space &obj) +{ + char *str = isl_space_to_str(obj.get()); + if (!str) { + os.setstate(std::ios_base::badbit); + return os; + } + os << str; + free(str); + return os; +} + +// implementations for isl::union_access_info +union_access_info manage(__isl_take isl_union_access_info *ptr) { + return union_access_info(ptr); +} +union_access_info manage_copy(__isl_keep isl_union_access_info *ptr) { + ptr = isl_union_access_info_copy(ptr); + return union_access_info(ptr); +} + +union_access_info::union_access_info(__isl_take isl_union_access_info *ptr) + : ptr(ptr) {} + +union_access_info::union_access_info() + : ptr(nullptr) {} + +union_access_info::union_access_info(const union_access_info &obj) + : ptr(nullptr) +{ + ptr = obj.copy(); +} + +union_access_info::union_access_info(isl::checked::union_map sink) +{ + auto res = isl_union_access_info_from_sink(sink.release()); + ptr = res; +} + +union_access_info &union_access_info::operator=(union_access_info obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +union_access_info::~union_access_info() { + if (ptr) + isl_union_access_info_free(ptr); +} + +__isl_give isl_union_access_info *union_access_info::copy() const & { + return isl_union_access_info_copy(ptr); +} + +__isl_keep isl_union_access_info *union_access_info::get() const { + return ptr; +} + +__isl_give isl_union_access_info *union_access_info::release() { + isl_union_access_info *tmp = ptr; + ptr = nullptr; + return tmp; +} + +bool union_access_info::is_null() const { + return ptr == nullptr; +} + +isl::checked::ctx union_access_info::ctx() const { + return isl::checked::ctx(isl_union_access_info_get_ctx(ptr)); +} + +isl::checked::union_flow union_access_info::compute_flow() const +{ + auto res = isl_union_access_info_compute_flow(copy()); + return manage(res); +} + +isl::checked::union_access_info union_access_info::set_kill(isl::checked::union_map kill) const +{ + auto res = isl_union_access_info_set_kill(copy(), kill.release()); + return manage(res); +} + +isl::checked::union_access_info union_access_info::set_may_source(isl::checked::union_map may_source) const +{ + auto res = isl_union_access_info_set_may_source(copy(), may_source.release()); + return manage(res); +} + +isl::checked::union_access_info union_access_info::set_must_source(isl::checked::union_map must_source) const +{ + auto res = isl_union_access_info_set_must_source(copy(), must_source.release()); + return manage(res); +} + +isl::checked::union_access_info union_access_info::set_schedule(isl::checked::schedule schedule) const +{ + auto res = isl_union_access_info_set_schedule(copy(), schedule.release()); + return manage(res); +} + +isl::checked::union_access_info union_access_info::set_schedule_map(isl::checked::union_map schedule_map) const +{ + auto res = isl_union_access_info_set_schedule_map(copy(), schedule_map.release()); + return manage(res); +} + +inline std::ostream &operator<<(std::ostream &os, const union_access_info &obj) +{ + char *str = isl_union_access_info_to_str(obj.get()); + if (!str) { + os.setstate(std::ios_base::badbit); + return os; + } + os << str; + free(str); + return os; +} + +// implementations for isl::union_flow +union_flow manage(__isl_take isl_union_flow *ptr) { + return union_flow(ptr); +} +union_flow manage_copy(__isl_keep isl_union_flow *ptr) { + ptr = isl_union_flow_copy(ptr); + return union_flow(ptr); +} + +union_flow::union_flow(__isl_take isl_union_flow *ptr) + : ptr(ptr) {} + +union_flow::union_flow() + : ptr(nullptr) {} + +union_flow::union_flow(const union_flow &obj) + : ptr(nullptr) +{ + ptr = obj.copy(); +} + +union_flow &union_flow::operator=(union_flow obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +union_flow::~union_flow() { + if (ptr) + isl_union_flow_free(ptr); +} + +__isl_give isl_union_flow *union_flow::copy() const & { + return isl_union_flow_copy(ptr); +} + +__isl_keep isl_union_flow *union_flow::get() const { + return ptr; +} + +__isl_give isl_union_flow *union_flow::release() { + isl_union_flow *tmp = ptr; + ptr = nullptr; + return tmp; +} + +bool union_flow::is_null() const { + return ptr == nullptr; +} + +isl::checked::ctx union_flow::ctx() const { + return isl::checked::ctx(isl_union_flow_get_ctx(ptr)); +} + +isl::checked::union_map union_flow::full_may_dependence() const +{ + auto res = isl_union_flow_get_full_may_dependence(get()); + return manage(res); +} + +isl::checked::union_map union_flow::get_full_may_dependence() const +{ + return full_may_dependence(); +} + +isl::checked::union_map union_flow::full_must_dependence() const +{ + auto res = isl_union_flow_get_full_must_dependence(get()); + return manage(res); +} + +isl::checked::union_map union_flow::get_full_must_dependence() const +{ + return full_must_dependence(); +} + +isl::checked::union_map union_flow::may_dependence() const +{ + auto res = isl_union_flow_get_may_dependence(get()); + return manage(res); +} + +isl::checked::union_map union_flow::get_may_dependence() const +{ + return may_dependence(); +} + +isl::checked::union_map union_flow::may_no_source() const +{ + auto res = isl_union_flow_get_may_no_source(get()); + return manage(res); +} + +isl::checked::union_map union_flow::get_may_no_source() const +{ + return may_no_source(); +} + +isl::checked::union_map union_flow::must_dependence() const +{ + auto res = isl_union_flow_get_must_dependence(get()); + return manage(res); +} + +isl::checked::union_map union_flow::get_must_dependence() const +{ + return must_dependence(); +} + +isl::checked::union_map union_flow::must_no_source() const +{ + auto res = isl_union_flow_get_must_no_source(get()); + return manage(res); +} + +isl::checked::union_map union_flow::get_must_no_source() const +{ + return must_no_source(); +} + +inline std::ostream &operator<<(std::ostream &os, const union_flow &obj) +{ + char *str = isl_union_flow_to_str(obj.get()); + if (!str) { + os.setstate(std::ios_base::badbit); + return os; + } + os << str; + free(str); + return os; +} + +// implementations for isl::union_map +union_map manage(__isl_take isl_union_map *ptr) { + return union_map(ptr); +} +union_map manage_copy(__isl_keep isl_union_map *ptr) { + ptr = isl_union_map_copy(ptr); + return union_map(ptr); +} + +union_map::union_map(__isl_take isl_union_map *ptr) + : ptr(ptr) {} + +union_map::union_map() + : ptr(nullptr) {} + +union_map::union_map(const union_map &obj) + : ptr(nullptr) +{ + ptr = obj.copy(); +} + +union_map::union_map(isl::checked::basic_map bmap) +{ + auto res = isl_union_map_from_basic_map(bmap.release()); + ptr = res; +} + +union_map::union_map(isl::checked::map map) +{ + auto res = isl_union_map_from_map(map.release()); + ptr = res; +} + +union_map::union_map(isl::checked::ctx ctx, const std::string &str) +{ + auto res = isl_union_map_read_from_str(ctx.release(), str.c_str()); + ptr = res; +} + +union_map &union_map::operator=(union_map obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +union_map::~union_map() { + if (ptr) + isl_union_map_free(ptr); +} + +__isl_give isl_union_map *union_map::copy() const & { + return isl_union_map_copy(ptr); +} + +__isl_keep isl_union_map *union_map::get() const { + return ptr; +} + +__isl_give isl_union_map *union_map::release() { + isl_union_map *tmp = ptr; + ptr = nullptr; + return tmp; +} + +bool union_map::is_null() const { + return ptr == nullptr; +} + +isl::checked::ctx union_map::ctx() const { + return isl::checked::ctx(isl_union_map_get_ctx(ptr)); +} + +isl::checked::union_map union_map::affine_hull() const +{ + auto res = isl_union_map_affine_hull(copy()); + return manage(res); +} + +isl::checked::union_map union_map::apply_domain(isl::checked::union_map umap2) const +{ + auto res = isl_union_map_apply_domain(copy(), umap2.release()); + return manage(res); +} + +isl::checked::union_map union_map::apply_range(isl::checked::union_map umap2) const +{ + auto res = isl_union_map_apply_range(copy(), umap2.release()); + return manage(res); +} + +isl::checked::map union_map::as_map() const +{ + auto res = isl_union_map_as_map(copy()); + return manage(res); +} + +isl::checked::multi_union_pw_aff union_map::as_multi_union_pw_aff() const +{ + auto res = isl_union_map_as_multi_union_pw_aff(copy()); + return manage(res); +} + +isl::checked::union_pw_multi_aff union_map::as_union_pw_multi_aff() const +{ + auto res = isl_union_map_as_union_pw_multi_aff(copy()); + return manage(res); +} + +isl::checked::union_set union_map::bind_range(isl::checked::multi_id tuple) const +{ + auto res = isl_union_map_bind_range(copy(), tuple.release()); + return manage(res); +} + +isl::checked::union_map union_map::coalesce() const +{ + auto res = isl_union_map_coalesce(copy()); + return manage(res); +} + +isl::checked::union_map union_map::compute_divs() const +{ + auto res = isl_union_map_compute_divs(copy()); + return manage(res); +} + +isl::checked::union_map union_map::curry() const +{ + auto res = isl_union_map_curry(copy()); + return manage(res); +} + +isl::checked::union_set union_map::deltas() const +{ + auto res = isl_union_map_deltas(copy()); + return manage(res); +} + +isl::checked::union_map union_map::detect_equalities() const +{ + auto res = isl_union_map_detect_equalities(copy()); + return manage(res); +} + +isl::checked::union_set union_map::domain() const +{ + auto res = isl_union_map_domain(copy()); + return manage(res); +} + +isl::checked::union_map union_map::domain_factor_domain() const +{ + auto res = isl_union_map_domain_factor_domain(copy()); + return manage(res); +} + +isl::checked::union_map union_map::domain_factor_range() const +{ + auto res = isl_union_map_domain_factor_range(copy()); + return manage(res); +} + +isl::checked::union_map union_map::domain_map() const +{ + auto res = isl_union_map_domain_map(copy()); + return manage(res); +} + +isl::checked::union_pw_multi_aff union_map::domain_map_union_pw_multi_aff() const +{ + auto res = isl_union_map_domain_map_union_pw_multi_aff(copy()); + return manage(res); +} + +isl::checked::union_map union_map::domain_product(isl::checked::union_map umap2) const +{ + auto res = isl_union_map_domain_product(copy(), umap2.release()); + return manage(res); +} + +isl::checked::union_map union_map::domain_reverse() const +{ + auto res = isl_union_map_domain_reverse(copy()); + return manage(res); +} + +isl::checked::union_map union_map::drop_unused_params() const +{ + auto res = isl_union_map_drop_unused_params(copy()); + return manage(res); +} + +isl::checked::union_map union_map::empty(isl::checked::ctx ctx) +{ + auto res = isl_union_map_empty_ctx(ctx.release()); + return manage(res); +} + +isl::checked::union_map union_map::eq_at(isl::checked::multi_union_pw_aff mupa) const +{ + auto res = isl_union_map_eq_at_multi_union_pw_aff(copy(), mupa.release()); + return manage(res); +} + +boolean union_map::every_map(const std::function &test) const +{ + struct test_data { + std::function func; + } test_data = { test }; + auto test_lambda = [](isl_map *arg_0, void *arg_1) -> isl_bool { + auto *data = static_cast(arg_1); + auto ret = (data->func)(manage_copy(arg_0)); + return ret.release(); + }; + auto res = isl_union_map_every_map(get(), test_lambda, &test_data); + return manage(res); +} + +isl::checked::map union_map::extract_map(isl::checked::space space) const +{ + auto res = isl_union_map_extract_map(get(), space.release()); + return manage(res); +} + +isl::checked::union_map union_map::factor_domain() const +{ + auto res = isl_union_map_factor_domain(copy()); + return manage(res); +} + +isl::checked::union_map union_map::factor_range() const +{ + auto res = isl_union_map_factor_range(copy()); + return manage(res); +} + +isl::checked::union_map union_map::fixed_power(isl::checked::val exp) const +{ + auto res = isl_union_map_fixed_power_val(copy(), exp.release()); + return manage(res); +} + +isl::checked::union_map union_map::fixed_power(long exp) const +{ + return this->fixed_power(isl::checked::val(ctx(), exp)); +} + +stat union_map::foreach_map(const std::function &fn) const +{ + struct fn_data { + std::function func; + } fn_data = { fn }; + auto fn_lambda = [](isl_map *arg_0, void *arg_1) -> isl_stat { + auto *data = static_cast(arg_1); + auto ret = (data->func)(manage(arg_0)); + return ret.release(); + }; + auto res = isl_union_map_foreach_map(get(), fn_lambda, &fn_data); + return manage(res); +} + +isl::checked::union_map union_map::from(isl::checked::multi_union_pw_aff mupa) +{ + auto res = isl_union_map_from_multi_union_pw_aff(mupa.release()); + return manage(res); +} + +isl::checked::union_map union_map::from(isl::checked::union_pw_multi_aff upma) +{ + auto res = isl_union_map_from_union_pw_multi_aff(upma.release()); + return manage(res); +} + +isl::checked::union_map union_map::from_domain(isl::checked::union_set uset) +{ + auto res = isl_union_map_from_domain(uset.release()); + return manage(res); +} + +isl::checked::union_map union_map::from_domain_and_range(isl::checked::union_set domain, isl::checked::union_set range) +{ + auto res = isl_union_map_from_domain_and_range(domain.release(), range.release()); + return manage(res); +} + +isl::checked::union_map union_map::from_range(isl::checked::union_set uset) +{ + auto res = isl_union_map_from_range(uset.release()); + return manage(res); +} + +isl::checked::union_map union_map::gist(isl::checked::union_map context) const +{ + auto res = isl_union_map_gist(copy(), context.release()); + return manage(res); +} + +isl::checked::union_map union_map::gist_domain(isl::checked::union_set uset) const +{ + auto res = isl_union_map_gist_domain(copy(), uset.release()); + return manage(res); +} + +isl::checked::union_map union_map::gist_params(isl::checked::set set) const +{ + auto res = isl_union_map_gist_params(copy(), set.release()); + return manage(res); +} + +isl::checked::union_map union_map::gist_range(isl::checked::union_set uset) const +{ + auto res = isl_union_map_gist_range(copy(), uset.release()); + return manage(res); +} + +isl::checked::union_map union_map::intersect(isl::checked::union_map umap2) const +{ + auto res = isl_union_map_intersect(copy(), umap2.release()); + return manage(res); +} + +isl::checked::union_map union_map::intersect_domain(isl::checked::space space) const +{ + auto res = isl_union_map_intersect_domain_space(copy(), space.release()); + return manage(res); +} + +isl::checked::union_map union_map::intersect_domain(isl::checked::union_set uset) const +{ + auto res = isl_union_map_intersect_domain_union_set(copy(), uset.release()); + return manage(res); +} + +isl::checked::union_map union_map::intersect_domain_factor_domain(isl::checked::union_map factor) const +{ + auto res = isl_union_map_intersect_domain_factor_domain(copy(), factor.release()); + return manage(res); +} + +isl::checked::union_map union_map::intersect_domain_factor_range(isl::checked::union_map factor) const +{ + auto res = isl_union_map_intersect_domain_factor_range(copy(), factor.release()); + return manage(res); +} + +isl::checked::union_map union_map::intersect_domain_wrapped_domain(isl::checked::union_set domain) const +{ + auto res = isl_union_map_intersect_domain_wrapped_domain_union_set(copy(), domain.release()); + return manage(res); +} + +isl::checked::union_map union_map::intersect_params(isl::checked::set set) const +{ + auto res = isl_union_map_intersect_params(copy(), set.release()); + return manage(res); +} + +isl::checked::union_map union_map::intersect_range(isl::checked::space space) const +{ + auto res = isl_union_map_intersect_range_space(copy(), space.release()); + return manage(res); +} + +isl::checked::union_map union_map::intersect_range(isl::checked::union_set uset) const +{ + auto res = isl_union_map_intersect_range_union_set(copy(), uset.release()); + return manage(res); +} + +isl::checked::union_map union_map::intersect_range_factor_domain(isl::checked::union_map factor) const +{ + auto res = isl_union_map_intersect_range_factor_domain(copy(), factor.release()); + return manage(res); +} + +isl::checked::union_map union_map::intersect_range_factor_range(isl::checked::union_map factor) const +{ + auto res = isl_union_map_intersect_range_factor_range(copy(), factor.release()); + return manage(res); +} + +isl::checked::union_map union_map::intersect_range_wrapped_domain(isl::checked::union_set domain) const +{ + auto res = isl_union_map_intersect_range_wrapped_domain_union_set(copy(), domain.release()); + return manage(res); +} + +boolean union_map::is_bijective() const +{ + auto res = isl_union_map_is_bijective(get()); + return manage(res); +} + +boolean union_map::is_disjoint(const isl::checked::union_map &umap2) const +{ + auto res = isl_union_map_is_disjoint(get(), umap2.get()); + return manage(res); +} + +boolean union_map::is_empty() const +{ + auto res = isl_union_map_is_empty(get()); + return manage(res); +} + +boolean union_map::is_equal(const isl::checked::union_map &umap2) const +{ + auto res = isl_union_map_is_equal(get(), umap2.get()); + return manage(res); +} + +boolean union_map::is_injective() const +{ + auto res = isl_union_map_is_injective(get()); + return manage(res); +} + +boolean union_map::is_single_valued() const +{ + auto res = isl_union_map_is_single_valued(get()); + return manage(res); +} + +boolean union_map::is_strict_subset(const isl::checked::union_map &umap2) const +{ + auto res = isl_union_map_is_strict_subset(get(), umap2.get()); + return manage(res); +} + +boolean union_map::is_subset(const isl::checked::union_map &umap2) const +{ + auto res = isl_union_map_is_subset(get(), umap2.get()); + return manage(res); +} + +boolean union_map::isa_map() const +{ + auto res = isl_union_map_isa_map(get()); + return manage(res); +} + +isl::checked::union_map union_map::lexmax() const +{ + auto res = isl_union_map_lexmax(copy()); + return manage(res); +} + +isl::checked::union_map union_map::lexmin() const +{ + auto res = isl_union_map_lexmin(copy()); + return manage(res); +} + +isl::checked::map_list union_map::map_list() const +{ + auto res = isl_union_map_get_map_list(get()); + return manage(res); +} + +isl::checked::map_list union_map::get_map_list() const +{ + return map_list(); +} + +isl::checked::set union_map::params() const +{ + auto res = isl_union_map_params(copy()); + return manage(res); +} + +isl::checked::union_map union_map::polyhedral_hull() const +{ + auto res = isl_union_map_polyhedral_hull(copy()); + return manage(res); +} + +isl::checked::union_map union_map::preimage_domain(isl::checked::multi_aff ma) const +{ + auto res = isl_union_map_preimage_domain_multi_aff(copy(), ma.release()); + return manage(res); +} + +isl::checked::union_map union_map::preimage_domain(isl::checked::multi_pw_aff mpa) const +{ + auto res = isl_union_map_preimage_domain_multi_pw_aff(copy(), mpa.release()); + return manage(res); +} + +isl::checked::union_map union_map::preimage_domain(isl::checked::pw_multi_aff pma) const +{ + auto res = isl_union_map_preimage_domain_pw_multi_aff(copy(), pma.release()); + return manage(res); +} + +isl::checked::union_map union_map::preimage_domain(isl::checked::union_pw_multi_aff upma) const +{ + auto res = isl_union_map_preimage_domain_union_pw_multi_aff(copy(), upma.release()); + return manage(res); +} + +isl::checked::union_map union_map::preimage_range(isl::checked::multi_aff ma) const +{ + auto res = isl_union_map_preimage_range_multi_aff(copy(), ma.release()); + return manage(res); +} + +isl::checked::union_map union_map::preimage_range(isl::checked::pw_multi_aff pma) const +{ + auto res = isl_union_map_preimage_range_pw_multi_aff(copy(), pma.release()); + return manage(res); +} + +isl::checked::union_map union_map::preimage_range(isl::checked::union_pw_multi_aff upma) const +{ + auto res = isl_union_map_preimage_range_union_pw_multi_aff(copy(), upma.release()); + return manage(res); +} + +isl::checked::union_map union_map::product(isl::checked::union_map umap2) const +{ + auto res = isl_union_map_product(copy(), umap2.release()); + return manage(res); +} + +isl::checked::union_map union_map::project_out_all_params() const +{ + auto res = isl_union_map_project_out_all_params(copy()); + return manage(res); +} + +isl::checked::union_map union_map::project_out_param(isl::checked::id id) const +{ + auto res = isl_union_map_project_out_param_id(copy(), id.release()); + return manage(res); +} + +isl::checked::union_map union_map::project_out_param(const std::string &id) const +{ + return this->project_out_param(isl::checked::id(ctx(), id)); +} + +isl::checked::union_map union_map::project_out_param(isl::checked::id_list list) const +{ + auto res = isl_union_map_project_out_param_id_list(copy(), list.release()); + return manage(res); +} + +isl::checked::union_set union_map::range() const +{ + auto res = isl_union_map_range(copy()); + return manage(res); +} + +isl::checked::union_map union_map::range_factor_domain() const +{ + auto res = isl_union_map_range_factor_domain(copy()); + return manage(res); +} + +isl::checked::union_map union_map::range_factor_range() const +{ + auto res = isl_union_map_range_factor_range(copy()); + return manage(res); +} + +isl::checked::union_map union_map::range_map() const +{ + auto res = isl_union_map_range_map(copy()); + return manage(res); +} + +isl::checked::union_map union_map::range_product(isl::checked::union_map umap2) const +{ + auto res = isl_union_map_range_product(copy(), umap2.release()); + return manage(res); +} + +isl::checked::union_map union_map::range_reverse() const +{ + auto res = isl_union_map_range_reverse(copy()); + return manage(res); +} + +isl::checked::union_map union_map::reverse() const +{ + auto res = isl_union_map_reverse(copy()); + return manage(res); +} + +isl::checked::space union_map::space() const +{ + auto res = isl_union_map_get_space(get()); + return manage(res); +} + +isl::checked::space union_map::get_space() const +{ + return space(); +} + +isl::checked::union_map union_map::subtract(isl::checked::union_map umap2) const +{ + auto res = isl_union_map_subtract(copy(), umap2.release()); + return manage(res); +} + +isl::checked::union_map union_map::subtract_domain(isl::checked::union_set dom) const +{ + auto res = isl_union_map_subtract_domain(copy(), dom.release()); + return manage(res); +} + +isl::checked::union_map union_map::subtract_range(isl::checked::union_set dom) const +{ + auto res = isl_union_map_subtract_range(copy(), dom.release()); + return manage(res); +} + +isl::checked::union_map union_map::uncurry() const +{ + auto res = isl_union_map_uncurry(copy()); + return manage(res); +} + +isl::checked::union_map union_map::unite(isl::checked::union_map umap2) const +{ + auto res = isl_union_map_union(copy(), umap2.release()); + return manage(res); +} + +isl::checked::union_map union_map::universe() const +{ + auto res = isl_union_map_universe(copy()); + return manage(res); +} + +isl::checked::union_set union_map::wrap() const +{ + auto res = isl_union_map_wrap(copy()); + return manage(res); +} + +isl::checked::union_map union_map::zip() const +{ + auto res = isl_union_map_zip(copy()); + return manage(res); +} + +inline std::ostream &operator<<(std::ostream &os, const union_map &obj) +{ + char *str = isl_union_map_to_str(obj.get()); + if (!str) { + os.setstate(std::ios_base::badbit); + return os; + } + os << str; + free(str); + return os; +} + +// implementations for isl::union_pw_aff +union_pw_aff manage(__isl_take isl_union_pw_aff *ptr) { + return union_pw_aff(ptr); +} +union_pw_aff manage_copy(__isl_keep isl_union_pw_aff *ptr) { + ptr = isl_union_pw_aff_copy(ptr); + return union_pw_aff(ptr); +} + +union_pw_aff::union_pw_aff(__isl_take isl_union_pw_aff *ptr) + : ptr(ptr) {} + +union_pw_aff::union_pw_aff() + : ptr(nullptr) {} + +union_pw_aff::union_pw_aff(const union_pw_aff &obj) + : ptr(nullptr) +{ + ptr = obj.copy(); +} + +union_pw_aff::union_pw_aff(isl::checked::aff aff) +{ + auto res = isl_union_pw_aff_from_aff(aff.release()); + ptr = res; +} + +union_pw_aff::union_pw_aff(isl::checked::pw_aff pa) +{ + auto res = isl_union_pw_aff_from_pw_aff(pa.release()); + ptr = res; +} + +union_pw_aff::union_pw_aff(isl::checked::ctx ctx, const std::string &str) +{ + auto res = isl_union_pw_aff_read_from_str(ctx.release(), str.c_str()); + ptr = res; +} + +union_pw_aff &union_pw_aff::operator=(union_pw_aff obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +union_pw_aff::~union_pw_aff() { + if (ptr) + isl_union_pw_aff_free(ptr); +} + +__isl_give isl_union_pw_aff *union_pw_aff::copy() const & { + return isl_union_pw_aff_copy(ptr); +} + +__isl_keep isl_union_pw_aff *union_pw_aff::get() const { + return ptr; +} + +__isl_give isl_union_pw_aff *union_pw_aff::release() { + isl_union_pw_aff *tmp = ptr; + ptr = nullptr; + return tmp; +} + +bool union_pw_aff::is_null() const { + return ptr == nullptr; +} + +isl::checked::ctx union_pw_aff::ctx() const { + return isl::checked::ctx(isl_union_pw_aff_get_ctx(ptr)); +} + +isl::checked::multi_union_pw_aff union_pw_aff::add(const isl::checked::multi_union_pw_aff &multi2) const +{ + return isl::checked::multi_union_pw_aff(*this).add(multi2); +} + +isl::checked::union_pw_aff union_pw_aff::add(isl::checked::union_pw_aff upa2) const +{ + auto res = isl_union_pw_aff_add(copy(), upa2.release()); + return manage(res); +} + +isl::checked::union_pw_multi_aff union_pw_aff::add(const isl::checked::union_pw_multi_aff &upma2) const +{ + return isl::checked::union_pw_multi_aff(*this).add(upma2); +} + +isl::checked::union_pw_aff union_pw_aff::add(const isl::checked::aff &upa2) const +{ + return this->add(isl::checked::union_pw_aff(upa2)); +} + +isl::checked::union_pw_aff union_pw_aff::add(const isl::checked::pw_aff &upa2) const +{ + return this->add(isl::checked::union_pw_aff(upa2)); +} + +isl::checked::union_pw_multi_aff union_pw_aff::apply(const isl::checked::union_pw_multi_aff &upma2) const +{ + return isl::checked::union_pw_multi_aff(*this).apply(upma2); +} + +isl::checked::multi_union_pw_aff union_pw_aff::as_multi_union_pw_aff() const +{ + return isl::checked::union_pw_multi_aff(*this).as_multi_union_pw_aff(); +} + +isl::checked::pw_multi_aff union_pw_aff::as_pw_multi_aff() const +{ + return isl::checked::union_pw_multi_aff(*this).as_pw_multi_aff(); +} + +isl::checked::union_map union_pw_aff::as_union_map() const +{ + return isl::checked::union_pw_multi_aff(*this).as_union_map(); +} + +isl::checked::union_pw_aff union_pw_aff::at(int pos) const +{ + return isl::checked::multi_union_pw_aff(*this).at(pos); +} + +isl::checked::union_set union_pw_aff::bind(const isl::checked::multi_id &tuple) const +{ + return isl::checked::multi_union_pw_aff(*this).bind(tuple); +} + +isl::checked::union_set union_pw_aff::bind(isl::checked::id id) const +{ + auto res = isl_union_pw_aff_bind_id(copy(), id.release()); + return manage(res); +} + +isl::checked::union_set union_pw_aff::bind(const std::string &id) const +{ + return this->bind(isl::checked::id(ctx(), id)); +} + +isl::checked::union_pw_aff union_pw_aff::coalesce() const +{ + auto res = isl_union_pw_aff_coalesce(copy()); + return manage(res); +} + +isl::checked::union_set union_pw_aff::domain() const +{ + auto res = isl_union_pw_aff_domain(copy()); + return manage(res); +} + +isl::checked::union_pw_aff union_pw_aff::drop_unused_params() const +{ + auto res = isl_union_pw_aff_drop_unused_params(copy()); + return manage(res); +} + +isl::checked::pw_multi_aff union_pw_aff::extract_pw_multi_aff(const isl::checked::space &space) const +{ + return isl::checked::union_pw_multi_aff(*this).extract_pw_multi_aff(space); +} + +isl::checked::multi_union_pw_aff union_pw_aff::flat_range_product(const isl::checked::multi_union_pw_aff &multi2) const +{ + return isl::checked::multi_union_pw_aff(*this).flat_range_product(multi2); +} + +isl::checked::union_pw_multi_aff union_pw_aff::flat_range_product(const isl::checked::union_pw_multi_aff &upma2) const +{ + return isl::checked::union_pw_multi_aff(*this).flat_range_product(upma2); +} + +isl::checked::union_pw_aff union_pw_aff::gist(isl::checked::union_set context) const +{ + auto res = isl_union_pw_aff_gist(copy(), context.release()); + return manage(res); +} + +isl::checked::multi_union_pw_aff union_pw_aff::gist_params(const isl::checked::set &context) const +{ + return isl::checked::multi_union_pw_aff(*this).gist_params(context); +} + +boolean union_pw_aff::has_range_tuple_id() const +{ + return isl::checked::multi_union_pw_aff(*this).has_range_tuple_id(); +} + +isl::checked::union_pw_aff union_pw_aff::intersect_domain(isl::checked::space space) const +{ + auto res = isl_union_pw_aff_intersect_domain_space(copy(), space.release()); + return manage(res); +} + +isl::checked::union_pw_aff union_pw_aff::intersect_domain(isl::checked::union_set uset) const +{ + auto res = isl_union_pw_aff_intersect_domain_union_set(copy(), uset.release()); + return manage(res); +} + +isl::checked::union_pw_aff union_pw_aff::intersect_domain_wrapped_domain(isl::checked::union_set uset) const +{ + auto res = isl_union_pw_aff_intersect_domain_wrapped_domain(copy(), uset.release()); + return manage(res); +} + +isl::checked::union_pw_aff union_pw_aff::intersect_domain_wrapped_range(isl::checked::union_set uset) const +{ + auto res = isl_union_pw_aff_intersect_domain_wrapped_range(copy(), uset.release()); + return manage(res); +} + +isl::checked::union_pw_aff union_pw_aff::intersect_params(isl::checked::set set) const +{ + auto res = isl_union_pw_aff_intersect_params(copy(), set.release()); + return manage(res); +} + +boolean union_pw_aff::involves_locals() const +{ + return isl::checked::union_pw_multi_aff(*this).involves_locals(); +} + +boolean union_pw_aff::involves_nan() const +{ + return isl::checked::multi_union_pw_aff(*this).involves_nan(); +} + +boolean union_pw_aff::isa_pw_multi_aff() const +{ + return isl::checked::union_pw_multi_aff(*this).isa_pw_multi_aff(); +} + +isl::checked::union_pw_aff_list union_pw_aff::list() const +{ + return isl::checked::multi_union_pw_aff(*this).list(); +} + +isl::checked::multi_union_pw_aff union_pw_aff::neg() const +{ + return isl::checked::multi_union_pw_aff(*this).neg(); +} + +boolean union_pw_aff::plain_is_empty() const +{ + return isl::checked::union_pw_multi_aff(*this).plain_is_empty(); +} + +boolean union_pw_aff::plain_is_equal(const isl::checked::multi_union_pw_aff &multi2) const +{ + return isl::checked::multi_union_pw_aff(*this).plain_is_equal(multi2); +} + +boolean union_pw_aff::plain_is_equal(const isl::checked::union_pw_aff &upa2) const +{ + auto res = isl_union_pw_aff_plain_is_equal(get(), upa2.get()); + return manage(res); +} + +boolean union_pw_aff::plain_is_equal(const isl::checked::union_pw_multi_aff &upma2) const +{ + return isl::checked::union_pw_multi_aff(*this).plain_is_equal(upma2); +} + +boolean union_pw_aff::plain_is_equal(const isl::checked::aff &upa2) const +{ + return this->plain_is_equal(isl::checked::union_pw_aff(upa2)); +} + +boolean union_pw_aff::plain_is_equal(const isl::checked::pw_aff &upa2) const +{ + return this->plain_is_equal(isl::checked::union_pw_aff(upa2)); +} + +isl::checked::union_pw_multi_aff union_pw_aff::preimage_domain_wrapped_domain(const isl::checked::union_pw_multi_aff &upma2) const +{ + return isl::checked::union_pw_multi_aff(*this).preimage_domain_wrapped_domain(upma2); +} + +isl::checked::union_pw_aff union_pw_aff::pullback(isl::checked::union_pw_multi_aff upma) const +{ + auto res = isl_union_pw_aff_pullback_union_pw_multi_aff(copy(), upma.release()); + return manage(res); +} + +isl::checked::pw_multi_aff_list union_pw_aff::pw_multi_aff_list() const +{ + return isl::checked::union_pw_multi_aff(*this).pw_multi_aff_list(); +} + +isl::checked::union_pw_multi_aff union_pw_aff::range_factor_domain() const +{ + return isl::checked::union_pw_multi_aff(*this).range_factor_domain(); +} + +isl::checked::union_pw_multi_aff union_pw_aff::range_factor_range() const +{ + return isl::checked::union_pw_multi_aff(*this).range_factor_range(); +} + +isl::checked::multi_union_pw_aff union_pw_aff::range_product(const isl::checked::multi_union_pw_aff &multi2) const +{ + return isl::checked::multi_union_pw_aff(*this).range_product(multi2); +} + +isl::checked::union_pw_multi_aff union_pw_aff::range_product(const isl::checked::union_pw_multi_aff &upma2) const +{ + return isl::checked::union_pw_multi_aff(*this).range_product(upma2); +} + +isl::checked::id union_pw_aff::range_tuple_id() const +{ + return isl::checked::multi_union_pw_aff(*this).range_tuple_id(); +} + +isl::checked::multi_union_pw_aff union_pw_aff::reset_range_tuple_id() const +{ + return isl::checked::multi_union_pw_aff(*this).reset_range_tuple_id(); +} + +isl::checked::multi_union_pw_aff union_pw_aff::scale(const isl::checked::multi_val &mv) const +{ + return isl::checked::multi_union_pw_aff(*this).scale(mv); +} + +isl::checked::multi_union_pw_aff union_pw_aff::scale(const isl::checked::val &v) const +{ + return isl::checked::multi_union_pw_aff(*this).scale(v); +} + +isl::checked::multi_union_pw_aff union_pw_aff::scale(long v) const +{ + return this->scale(isl::checked::val(ctx(), v)); +} + +isl::checked::multi_union_pw_aff union_pw_aff::scale_down(const isl::checked::multi_val &mv) const +{ + return isl::checked::multi_union_pw_aff(*this).scale_down(mv); +} + +isl::checked::multi_union_pw_aff union_pw_aff::scale_down(const isl::checked::val &v) const +{ + return isl::checked::multi_union_pw_aff(*this).scale_down(v); +} + +isl::checked::multi_union_pw_aff union_pw_aff::scale_down(long v) const +{ + return this->scale_down(isl::checked::val(ctx(), v)); +} + +isl::checked::multi_union_pw_aff union_pw_aff::set_at(int pos, const isl::checked::union_pw_aff &el) const +{ + return isl::checked::multi_union_pw_aff(*this).set_at(pos, el); +} + +isl::checked::multi_union_pw_aff union_pw_aff::set_range_tuple(const isl::checked::id &id) const +{ + return isl::checked::multi_union_pw_aff(*this).set_range_tuple(id); +} + +isl::checked::multi_union_pw_aff union_pw_aff::set_range_tuple(const std::string &id) const +{ + return this->set_range_tuple(isl::checked::id(ctx(), id)); +} + +class size union_pw_aff::size() const +{ + return isl::checked::multi_union_pw_aff(*this).size(); +} + +isl::checked::space union_pw_aff::space() const +{ + auto res = isl_union_pw_aff_get_space(get()); + return manage(res); +} + +isl::checked::space union_pw_aff::get_space() const +{ + return space(); +} + +isl::checked::multi_union_pw_aff union_pw_aff::sub(const isl::checked::multi_union_pw_aff &multi2) const +{ + return isl::checked::multi_union_pw_aff(*this).sub(multi2); +} + +isl::checked::union_pw_aff union_pw_aff::sub(isl::checked::union_pw_aff upa2) const +{ + auto res = isl_union_pw_aff_sub(copy(), upa2.release()); + return manage(res); +} + +isl::checked::union_pw_multi_aff union_pw_aff::sub(const isl::checked::union_pw_multi_aff &upma2) const +{ + return isl::checked::union_pw_multi_aff(*this).sub(upma2); +} + +isl::checked::union_pw_aff union_pw_aff::sub(const isl::checked::aff &upa2) const +{ + return this->sub(isl::checked::union_pw_aff(upa2)); +} + +isl::checked::union_pw_aff union_pw_aff::sub(const isl::checked::pw_aff &upa2) const +{ + return this->sub(isl::checked::union_pw_aff(upa2)); +} + +isl::checked::union_pw_aff union_pw_aff::subtract_domain(isl::checked::space space) const +{ + auto res = isl_union_pw_aff_subtract_domain_space(copy(), space.release()); + return manage(res); +} + +isl::checked::union_pw_aff union_pw_aff::subtract_domain(isl::checked::union_set uset) const +{ + auto res = isl_union_pw_aff_subtract_domain_union_set(copy(), uset.release()); + return manage(res); +} + +isl::checked::union_pw_aff_list union_pw_aff::to_list() const +{ + auto res = isl_union_pw_aff_to_list(copy()); + return manage(res); +} + +isl::checked::multi_union_pw_aff union_pw_aff::union_add(const isl::checked::multi_union_pw_aff &mupa2) const +{ + return isl::checked::multi_union_pw_aff(*this).union_add(mupa2); +} + +isl::checked::union_pw_aff union_pw_aff::union_add(isl::checked::union_pw_aff upa2) const +{ + auto res = isl_union_pw_aff_union_add(copy(), upa2.release()); + return manage(res); +} + +isl::checked::union_pw_multi_aff union_pw_aff::union_add(const isl::checked::union_pw_multi_aff &upma2) const +{ + return isl::checked::union_pw_multi_aff(*this).union_add(upma2); +} + +isl::checked::union_pw_aff union_pw_aff::union_add(const isl::checked::aff &upa2) const +{ + return this->union_add(isl::checked::union_pw_aff(upa2)); +} + +isl::checked::union_pw_aff union_pw_aff::union_add(const isl::checked::pw_aff &upa2) const +{ + return this->union_add(isl::checked::union_pw_aff(upa2)); +} + +inline std::ostream &operator<<(std::ostream &os, const union_pw_aff &obj) +{ + char *str = isl_union_pw_aff_to_str(obj.get()); + if (!str) { + os.setstate(std::ios_base::badbit); + return os; + } + os << str; + free(str); + return os; +} + +// implementations for isl::union_pw_aff_list +union_pw_aff_list manage(__isl_take isl_union_pw_aff_list *ptr) { + return union_pw_aff_list(ptr); +} +union_pw_aff_list manage_copy(__isl_keep isl_union_pw_aff_list *ptr) { + ptr = isl_union_pw_aff_list_copy(ptr); + return union_pw_aff_list(ptr); +} + +union_pw_aff_list::union_pw_aff_list(__isl_take isl_union_pw_aff_list *ptr) + : ptr(ptr) {} + +union_pw_aff_list::union_pw_aff_list() + : ptr(nullptr) {} + +union_pw_aff_list::union_pw_aff_list(const union_pw_aff_list &obj) + : ptr(nullptr) +{ + ptr = obj.copy(); +} + +union_pw_aff_list::union_pw_aff_list(isl::checked::ctx ctx, int n) +{ + auto res = isl_union_pw_aff_list_alloc(ctx.release(), n); + ptr = res; +} + +union_pw_aff_list::union_pw_aff_list(isl::checked::union_pw_aff el) +{ + auto res = isl_union_pw_aff_list_from_union_pw_aff(el.release()); + ptr = res; +} + +union_pw_aff_list::union_pw_aff_list(isl::checked::ctx ctx, const std::string &str) +{ + auto res = isl_union_pw_aff_list_read_from_str(ctx.release(), str.c_str()); + ptr = res; +} + +union_pw_aff_list &union_pw_aff_list::operator=(union_pw_aff_list obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +union_pw_aff_list::~union_pw_aff_list() { + if (ptr) + isl_union_pw_aff_list_free(ptr); +} + +__isl_give isl_union_pw_aff_list *union_pw_aff_list::copy() const & { + return isl_union_pw_aff_list_copy(ptr); +} + +__isl_keep isl_union_pw_aff_list *union_pw_aff_list::get() const { + return ptr; +} + +__isl_give isl_union_pw_aff_list *union_pw_aff_list::release() { + isl_union_pw_aff_list *tmp = ptr; + ptr = nullptr; + return tmp; +} + +bool union_pw_aff_list::is_null() const { + return ptr == nullptr; +} + +isl::checked::ctx union_pw_aff_list::ctx() const { + return isl::checked::ctx(isl_union_pw_aff_list_get_ctx(ptr)); +} + +isl::checked::union_pw_aff_list union_pw_aff_list::add(isl::checked::union_pw_aff el) const +{ + auto res = isl_union_pw_aff_list_add(copy(), el.release()); + return manage(res); +} + +isl::checked::union_pw_aff union_pw_aff_list::at(int index) const +{ + auto res = isl_union_pw_aff_list_get_at(get(), index); + return manage(res); +} + +isl::checked::union_pw_aff union_pw_aff_list::get_at(int index) const +{ + return at(index); +} + +isl::checked::union_pw_aff_list union_pw_aff_list::clear() const +{ + auto res = isl_union_pw_aff_list_clear(copy()); + return manage(res); +} + +isl::checked::union_pw_aff_list union_pw_aff_list::concat(isl::checked::union_pw_aff_list list2) const +{ + auto res = isl_union_pw_aff_list_concat(copy(), list2.release()); + return manage(res); +} + +isl::checked::union_pw_aff_list union_pw_aff_list::drop(unsigned int first, unsigned int n) const +{ + auto res = isl_union_pw_aff_list_drop(copy(), first, n); + return manage(res); +} + +stat union_pw_aff_list::foreach(const std::function &fn) const +{ + struct fn_data { + std::function func; + } fn_data = { fn }; + auto fn_lambda = [](isl_union_pw_aff *arg_0, void *arg_1) -> isl_stat { + auto *data = static_cast(arg_1); + auto ret = (data->func)(manage(arg_0)); + return ret.release(); + }; + auto res = isl_union_pw_aff_list_foreach(get(), fn_lambda, &fn_data); + return manage(res); +} + +stat union_pw_aff_list::foreach_scc(const std::function &follows, const std::function &fn) const +{ + struct follows_data { + std::function func; + } follows_data = { follows }; + auto follows_lambda = [](isl_union_pw_aff *arg_0, isl_union_pw_aff *arg_1, void *arg_2) -> isl_bool { + auto *data = static_cast(arg_2); + auto ret = (data->func)(manage_copy(arg_0), manage_copy(arg_1)); + return ret.release(); + }; + struct fn_data { + std::function func; + } fn_data = { fn }; + auto fn_lambda = [](isl_union_pw_aff_list *arg_0, void *arg_1) -> isl_stat { + auto *data = static_cast(arg_1); + auto ret = (data->func)(manage(arg_0)); + return ret.release(); + }; + auto res = isl_union_pw_aff_list_foreach_scc(get(), follows_lambda, &follows_data, fn_lambda, &fn_data); + return manage(res); +} + +isl::checked::union_pw_aff_list union_pw_aff_list::insert(unsigned int pos, isl::checked::union_pw_aff el) const +{ + auto res = isl_union_pw_aff_list_insert(copy(), pos, el.release()); + return manage(res); +} + +isl::checked::union_pw_aff_list union_pw_aff_list::set_at(int index, isl::checked::union_pw_aff el) const +{ + auto res = isl_union_pw_aff_list_set_at(copy(), index, el.release()); + return manage(res); +} + +class size union_pw_aff_list::size() const +{ + auto res = isl_union_pw_aff_list_size(get()); + return manage(res); +} + +inline std::ostream &operator<<(std::ostream &os, const union_pw_aff_list &obj) +{ + char *str = isl_union_pw_aff_list_to_str(obj.get()); + if (!str) { + os.setstate(std::ios_base::badbit); + return os; + } + os << str; + free(str); + return os; +} + +// implementations for isl::union_pw_multi_aff +union_pw_multi_aff manage(__isl_take isl_union_pw_multi_aff *ptr) { + return union_pw_multi_aff(ptr); +} +union_pw_multi_aff manage_copy(__isl_keep isl_union_pw_multi_aff *ptr) { + ptr = isl_union_pw_multi_aff_copy(ptr); + return union_pw_multi_aff(ptr); +} + +union_pw_multi_aff::union_pw_multi_aff(__isl_take isl_union_pw_multi_aff *ptr) + : ptr(ptr) {} + +union_pw_multi_aff::union_pw_multi_aff() + : ptr(nullptr) {} + +union_pw_multi_aff::union_pw_multi_aff(const union_pw_multi_aff &obj) + : ptr(nullptr) +{ + ptr = obj.copy(); +} + +union_pw_multi_aff::union_pw_multi_aff(isl::checked::multi_aff ma) +{ + auto res = isl_union_pw_multi_aff_from_multi_aff(ma.release()); + ptr = res; +} + +union_pw_multi_aff::union_pw_multi_aff(isl::checked::pw_multi_aff pma) +{ + auto res = isl_union_pw_multi_aff_from_pw_multi_aff(pma.release()); + ptr = res; +} + +union_pw_multi_aff::union_pw_multi_aff(isl::checked::union_pw_aff upa) +{ + auto res = isl_union_pw_multi_aff_from_union_pw_aff(upa.release()); + ptr = res; +} + +union_pw_multi_aff::union_pw_multi_aff(isl::checked::ctx ctx, const std::string &str) +{ + auto res = isl_union_pw_multi_aff_read_from_str(ctx.release(), str.c_str()); + ptr = res; +} + +union_pw_multi_aff &union_pw_multi_aff::operator=(union_pw_multi_aff obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +union_pw_multi_aff::~union_pw_multi_aff() { + if (ptr) + isl_union_pw_multi_aff_free(ptr); +} + +__isl_give isl_union_pw_multi_aff *union_pw_multi_aff::copy() const & { + return isl_union_pw_multi_aff_copy(ptr); +} + +__isl_keep isl_union_pw_multi_aff *union_pw_multi_aff::get() const { + return ptr; +} + +__isl_give isl_union_pw_multi_aff *union_pw_multi_aff::release() { + isl_union_pw_multi_aff *tmp = ptr; + ptr = nullptr; + return tmp; +} + +bool union_pw_multi_aff::is_null() const { + return ptr == nullptr; +} + +isl::checked::ctx union_pw_multi_aff::ctx() const { + return isl::checked::ctx(isl_union_pw_multi_aff_get_ctx(ptr)); +} + +isl::checked::union_pw_multi_aff union_pw_multi_aff::add(isl::checked::union_pw_multi_aff upma2) const +{ + auto res = isl_union_pw_multi_aff_add(copy(), upma2.release()); + return manage(res); +} + +isl::checked::union_pw_multi_aff union_pw_multi_aff::apply(isl::checked::union_pw_multi_aff upma2) const +{ + auto res = isl_union_pw_multi_aff_apply_union_pw_multi_aff(copy(), upma2.release()); + return manage(res); +} + +isl::checked::multi_union_pw_aff union_pw_multi_aff::as_multi_union_pw_aff() const +{ + auto res = isl_union_pw_multi_aff_as_multi_union_pw_aff(copy()); + return manage(res); +} + +isl::checked::pw_multi_aff union_pw_multi_aff::as_pw_multi_aff() const +{ + auto res = isl_union_pw_multi_aff_as_pw_multi_aff(copy()); + return manage(res); +} + +isl::checked::union_map union_pw_multi_aff::as_union_map() const +{ + auto res = isl_union_pw_multi_aff_as_union_map(copy()); + return manage(res); +} + +isl::checked::union_pw_multi_aff union_pw_multi_aff::coalesce() const +{ + auto res = isl_union_pw_multi_aff_coalesce(copy()); + return manage(res); +} + +isl::checked::union_set union_pw_multi_aff::domain() const +{ + auto res = isl_union_pw_multi_aff_domain(copy()); + return manage(res); +} + +isl::checked::union_pw_multi_aff union_pw_multi_aff::drop_unused_params() const +{ + auto res = isl_union_pw_multi_aff_drop_unused_params(copy()); + return manage(res); +} + +isl::checked::union_pw_multi_aff union_pw_multi_aff::empty(isl::checked::ctx ctx) +{ + auto res = isl_union_pw_multi_aff_empty_ctx(ctx.release()); + return manage(res); +} + +isl::checked::pw_multi_aff union_pw_multi_aff::extract_pw_multi_aff(isl::checked::space space) const +{ + auto res = isl_union_pw_multi_aff_extract_pw_multi_aff(get(), space.release()); + return manage(res); +} + +isl::checked::union_pw_multi_aff union_pw_multi_aff::flat_range_product(isl::checked::union_pw_multi_aff upma2) const +{ + auto res = isl_union_pw_multi_aff_flat_range_product(copy(), upma2.release()); + return manage(res); +} + +isl::checked::union_pw_multi_aff union_pw_multi_aff::gist(isl::checked::union_set context) const +{ + auto res = isl_union_pw_multi_aff_gist(copy(), context.release()); + return manage(res); +} + +isl::checked::union_pw_multi_aff union_pw_multi_aff::intersect_domain(isl::checked::space space) const +{ + auto res = isl_union_pw_multi_aff_intersect_domain_space(copy(), space.release()); + return manage(res); +} + +isl::checked::union_pw_multi_aff union_pw_multi_aff::intersect_domain(isl::checked::union_set uset) const +{ + auto res = isl_union_pw_multi_aff_intersect_domain_union_set(copy(), uset.release()); + return manage(res); +} + +isl::checked::union_pw_multi_aff union_pw_multi_aff::intersect_domain_wrapped_domain(isl::checked::union_set uset) const +{ + auto res = isl_union_pw_multi_aff_intersect_domain_wrapped_domain(copy(), uset.release()); + return manage(res); +} + +isl::checked::union_pw_multi_aff union_pw_multi_aff::intersect_domain_wrapped_range(isl::checked::union_set uset) const +{ + auto res = isl_union_pw_multi_aff_intersect_domain_wrapped_range(copy(), uset.release()); + return manage(res); +} + +isl::checked::union_pw_multi_aff union_pw_multi_aff::intersect_params(isl::checked::set set) const +{ + auto res = isl_union_pw_multi_aff_intersect_params(copy(), set.release()); + return manage(res); +} + +boolean union_pw_multi_aff::involves_locals() const +{ + auto res = isl_union_pw_multi_aff_involves_locals(get()); + return manage(res); +} + +boolean union_pw_multi_aff::isa_pw_multi_aff() const +{ + auto res = isl_union_pw_multi_aff_isa_pw_multi_aff(get()); + return manage(res); +} + +boolean union_pw_multi_aff::plain_is_empty() const +{ + auto res = isl_union_pw_multi_aff_plain_is_empty(get()); + return manage(res); +} + +boolean union_pw_multi_aff::plain_is_equal(const isl::checked::union_pw_multi_aff &upma2) const +{ + auto res = isl_union_pw_multi_aff_plain_is_equal(get(), upma2.get()); + return manage(res); +} + +isl::checked::union_pw_multi_aff union_pw_multi_aff::preimage_domain_wrapped_domain(isl::checked::union_pw_multi_aff upma2) const +{ + auto res = isl_union_pw_multi_aff_preimage_domain_wrapped_domain_union_pw_multi_aff(copy(), upma2.release()); + return manage(res); +} + +isl::checked::union_pw_multi_aff union_pw_multi_aff::pullback(isl::checked::union_pw_multi_aff upma2) const +{ + auto res = isl_union_pw_multi_aff_pullback_union_pw_multi_aff(copy(), upma2.release()); + return manage(res); +} + +isl::checked::pw_multi_aff_list union_pw_multi_aff::pw_multi_aff_list() const +{ + auto res = isl_union_pw_multi_aff_get_pw_multi_aff_list(get()); + return manage(res); +} + +isl::checked::pw_multi_aff_list union_pw_multi_aff::get_pw_multi_aff_list() const +{ + return pw_multi_aff_list(); +} + +isl::checked::union_pw_multi_aff union_pw_multi_aff::range_factor_domain() const +{ + auto res = isl_union_pw_multi_aff_range_factor_domain(copy()); + return manage(res); +} + +isl::checked::union_pw_multi_aff union_pw_multi_aff::range_factor_range() const +{ + auto res = isl_union_pw_multi_aff_range_factor_range(copy()); + return manage(res); +} + +isl::checked::union_pw_multi_aff union_pw_multi_aff::range_product(isl::checked::union_pw_multi_aff upma2) const +{ + auto res = isl_union_pw_multi_aff_range_product(copy(), upma2.release()); + return manage(res); +} + +isl::checked::space union_pw_multi_aff::space() const +{ + auto res = isl_union_pw_multi_aff_get_space(get()); + return manage(res); +} + +isl::checked::space union_pw_multi_aff::get_space() const +{ + return space(); +} + +isl::checked::union_pw_multi_aff union_pw_multi_aff::sub(isl::checked::union_pw_multi_aff upma2) const +{ + auto res = isl_union_pw_multi_aff_sub(copy(), upma2.release()); + return manage(res); +} + +isl::checked::union_pw_multi_aff union_pw_multi_aff::subtract_domain(isl::checked::space space) const +{ + auto res = isl_union_pw_multi_aff_subtract_domain_space(copy(), space.release()); + return manage(res); +} + +isl::checked::union_pw_multi_aff union_pw_multi_aff::subtract_domain(isl::checked::union_set uset) const +{ + auto res = isl_union_pw_multi_aff_subtract_domain_union_set(copy(), uset.release()); + return manage(res); +} + +isl::checked::union_pw_multi_aff union_pw_multi_aff::union_add(isl::checked::union_pw_multi_aff upma2) const +{ + auto res = isl_union_pw_multi_aff_union_add(copy(), upma2.release()); + return manage(res); +} + +inline std::ostream &operator<<(std::ostream &os, const union_pw_multi_aff &obj) +{ + char *str = isl_union_pw_multi_aff_to_str(obj.get()); + if (!str) { + os.setstate(std::ios_base::badbit); + return os; + } + os << str; + free(str); + return os; +} + +// implementations for isl::union_set +union_set manage(__isl_take isl_union_set *ptr) { + return union_set(ptr); +} +union_set manage_copy(__isl_keep isl_union_set *ptr) { + ptr = isl_union_set_copy(ptr); + return union_set(ptr); +} + +union_set::union_set(__isl_take isl_union_set *ptr) + : ptr(ptr) {} + +union_set::union_set() + : ptr(nullptr) {} + +union_set::union_set(const union_set &obj) + : ptr(nullptr) +{ + ptr = obj.copy(); +} + +union_set::union_set(isl::checked::basic_set bset) +{ + auto res = isl_union_set_from_basic_set(bset.release()); + ptr = res; +} + +union_set::union_set(isl::checked::point pnt) +{ + auto res = isl_union_set_from_point(pnt.release()); + ptr = res; +} + +union_set::union_set(isl::checked::set set) +{ + auto res = isl_union_set_from_set(set.release()); + ptr = res; +} + +union_set::union_set(isl::checked::ctx ctx, const std::string &str) +{ + auto res = isl_union_set_read_from_str(ctx.release(), str.c_str()); + ptr = res; +} + +union_set &union_set::operator=(union_set obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +union_set::~union_set() { + if (ptr) + isl_union_set_free(ptr); +} + +__isl_give isl_union_set *union_set::copy() const & { + return isl_union_set_copy(ptr); +} + +__isl_keep isl_union_set *union_set::get() const { + return ptr; +} + +__isl_give isl_union_set *union_set::release() { + isl_union_set *tmp = ptr; + ptr = nullptr; + return tmp; +} + +bool union_set::is_null() const { + return ptr == nullptr; +} + +isl::checked::ctx union_set::ctx() const { + return isl::checked::ctx(isl_union_set_get_ctx(ptr)); +} + +isl::checked::union_set union_set::affine_hull() const +{ + auto res = isl_union_set_affine_hull(copy()); + return manage(res); +} + +isl::checked::union_set union_set::apply(isl::checked::union_map umap) const +{ + auto res = isl_union_set_apply(copy(), umap.release()); + return manage(res); +} + +isl::checked::set union_set::as_set() const +{ + auto res = isl_union_set_as_set(copy()); + return manage(res); +} + +isl::checked::union_set union_set::coalesce() const +{ + auto res = isl_union_set_coalesce(copy()); + return manage(res); +} + +isl::checked::union_set union_set::compute_divs() const +{ + auto res = isl_union_set_compute_divs(copy()); + return manage(res); +} + +isl::checked::union_set union_set::detect_equalities() const +{ + auto res = isl_union_set_detect_equalities(copy()); + return manage(res); +} + +isl::checked::union_set union_set::drop_unused_params() const +{ + auto res = isl_union_set_drop_unused_params(copy()); + return manage(res); +} + +isl::checked::union_set union_set::empty(isl::checked::ctx ctx) +{ + auto res = isl_union_set_empty_ctx(ctx.release()); + return manage(res); +} + +boolean union_set::every_set(const std::function &test) const +{ + struct test_data { + std::function func; + } test_data = { test }; + auto test_lambda = [](isl_set *arg_0, void *arg_1) -> isl_bool { + auto *data = static_cast(arg_1); + auto ret = (data->func)(manage_copy(arg_0)); + return ret.release(); + }; + auto res = isl_union_set_every_set(get(), test_lambda, &test_data); + return manage(res); +} + +isl::checked::set union_set::extract_set(isl::checked::space space) const +{ + auto res = isl_union_set_extract_set(get(), space.release()); + return manage(res); +} + +stat union_set::foreach_point(const std::function &fn) const +{ + struct fn_data { + std::function func; + } fn_data = { fn }; + auto fn_lambda = [](isl_point *arg_0, void *arg_1) -> isl_stat { + auto *data = static_cast(arg_1); + auto ret = (data->func)(manage(arg_0)); + return ret.release(); + }; + auto res = isl_union_set_foreach_point(get(), fn_lambda, &fn_data); + return manage(res); +} + +stat union_set::foreach_set(const std::function &fn) const +{ + struct fn_data { + std::function func; + } fn_data = { fn }; + auto fn_lambda = [](isl_set *arg_0, void *arg_1) -> isl_stat { + auto *data = static_cast(arg_1); + auto ret = (data->func)(manage(arg_0)); + return ret.release(); + }; + auto res = isl_union_set_foreach_set(get(), fn_lambda, &fn_data); + return manage(res); +} + +isl::checked::union_set union_set::gist(isl::checked::union_set context) const +{ + auto res = isl_union_set_gist(copy(), context.release()); + return manage(res); +} + +isl::checked::union_set union_set::gist_params(isl::checked::set set) const +{ + auto res = isl_union_set_gist_params(copy(), set.release()); + return manage(res); +} + +isl::checked::union_map union_set::identity() const +{ + auto res = isl_union_set_identity(copy()); + return manage(res); +} + +isl::checked::union_set union_set::intersect(isl::checked::union_set uset2) const +{ + auto res = isl_union_set_intersect(copy(), uset2.release()); + return manage(res); +} + +isl::checked::union_set union_set::intersect_params(isl::checked::set set) const +{ + auto res = isl_union_set_intersect_params(copy(), set.release()); + return manage(res); +} + +boolean union_set::is_disjoint(const isl::checked::union_set &uset2) const +{ + auto res = isl_union_set_is_disjoint(get(), uset2.get()); + return manage(res); +} + +boolean union_set::is_empty() const +{ + auto res = isl_union_set_is_empty(get()); + return manage(res); +} + +boolean union_set::is_equal(const isl::checked::union_set &uset2) const +{ + auto res = isl_union_set_is_equal(get(), uset2.get()); + return manage(res); +} + +boolean union_set::is_strict_subset(const isl::checked::union_set &uset2) const +{ + auto res = isl_union_set_is_strict_subset(get(), uset2.get()); + return manage(res); +} + +boolean union_set::is_subset(const isl::checked::union_set &uset2) const +{ + auto res = isl_union_set_is_subset(get(), uset2.get()); + return manage(res); +} + +boolean union_set::isa_set() const +{ + auto res = isl_union_set_isa_set(get()); + return manage(res); +} + +isl::checked::union_set union_set::lexmax() const +{ + auto res = isl_union_set_lexmax(copy()); + return manage(res); +} + +isl::checked::union_set union_set::lexmin() const +{ + auto res = isl_union_set_lexmin(copy()); + return manage(res); +} + +isl::checked::set union_set::params() const +{ + auto res = isl_union_set_params(copy()); + return manage(res); +} + +isl::checked::union_set union_set::polyhedral_hull() const +{ + auto res = isl_union_set_polyhedral_hull(copy()); + return manage(res); +} + +isl::checked::union_set union_set::preimage(isl::checked::multi_aff ma) const +{ + auto res = isl_union_set_preimage_multi_aff(copy(), ma.release()); + return manage(res); +} + +isl::checked::union_set union_set::preimage(isl::checked::pw_multi_aff pma) const +{ + auto res = isl_union_set_preimage_pw_multi_aff(copy(), pma.release()); + return manage(res); +} + +isl::checked::union_set union_set::preimage(isl::checked::union_pw_multi_aff upma) const +{ + auto res = isl_union_set_preimage_union_pw_multi_aff(copy(), upma.release()); + return manage(res); +} + +isl::checked::union_set union_set::project_out_all_params() const +{ + auto res = isl_union_set_project_out_all_params(copy()); + return manage(res); +} + +isl::checked::point union_set::sample_point() const +{ + auto res = isl_union_set_sample_point(copy()); + return manage(res); +} + +isl::checked::set_list union_set::set_list() const +{ + auto res = isl_union_set_get_set_list(get()); + return manage(res); +} + +isl::checked::set_list union_set::get_set_list() const +{ + return set_list(); +} + +isl::checked::space union_set::space() const +{ + auto res = isl_union_set_get_space(get()); + return manage(res); +} + +isl::checked::space union_set::get_space() const +{ + return space(); +} + +isl::checked::union_set union_set::subtract(isl::checked::union_set uset2) const +{ + auto res = isl_union_set_subtract(copy(), uset2.release()); + return manage(res); +} + +isl::checked::union_set_list union_set::to_list() const +{ + auto res = isl_union_set_to_list(copy()); + return manage(res); +} + +isl::checked::union_set union_set::unite(isl::checked::union_set uset2) const +{ + auto res = isl_union_set_union(copy(), uset2.release()); + return manage(res); +} + +isl::checked::union_set union_set::universe() const +{ + auto res = isl_union_set_universe(copy()); + return manage(res); +} + +isl::checked::union_map union_set::unwrap() const +{ + auto res = isl_union_set_unwrap(copy()); + return manage(res); +} + +inline std::ostream &operator<<(std::ostream &os, const union_set &obj) +{ + char *str = isl_union_set_to_str(obj.get()); + if (!str) { + os.setstate(std::ios_base::badbit); + return os; + } + os << str; + free(str); + return os; +} + +// implementations for isl::union_set_list +union_set_list manage(__isl_take isl_union_set_list *ptr) { + return union_set_list(ptr); +} +union_set_list manage_copy(__isl_keep isl_union_set_list *ptr) { + ptr = isl_union_set_list_copy(ptr); + return union_set_list(ptr); +} + +union_set_list::union_set_list(__isl_take isl_union_set_list *ptr) + : ptr(ptr) {} + +union_set_list::union_set_list() + : ptr(nullptr) {} + +union_set_list::union_set_list(const union_set_list &obj) + : ptr(nullptr) +{ + ptr = obj.copy(); +} + +union_set_list::union_set_list(isl::checked::ctx ctx, int n) +{ + auto res = isl_union_set_list_alloc(ctx.release(), n); + ptr = res; +} + +union_set_list::union_set_list(isl::checked::union_set el) +{ + auto res = isl_union_set_list_from_union_set(el.release()); + ptr = res; +} + +union_set_list::union_set_list(isl::checked::ctx ctx, const std::string &str) +{ + auto res = isl_union_set_list_read_from_str(ctx.release(), str.c_str()); + ptr = res; +} + +union_set_list &union_set_list::operator=(union_set_list obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +union_set_list::~union_set_list() { + if (ptr) + isl_union_set_list_free(ptr); +} + +__isl_give isl_union_set_list *union_set_list::copy() const & { + return isl_union_set_list_copy(ptr); +} + +__isl_keep isl_union_set_list *union_set_list::get() const { + return ptr; +} + +__isl_give isl_union_set_list *union_set_list::release() { + isl_union_set_list *tmp = ptr; + ptr = nullptr; + return tmp; +} + +bool union_set_list::is_null() const { + return ptr == nullptr; +} + +isl::checked::ctx union_set_list::ctx() const { + return isl::checked::ctx(isl_union_set_list_get_ctx(ptr)); +} + +isl::checked::union_set_list union_set_list::add(isl::checked::union_set el) const +{ + auto res = isl_union_set_list_add(copy(), el.release()); + return manage(res); +} + +isl::checked::union_set union_set_list::at(int index) const +{ + auto res = isl_union_set_list_get_at(get(), index); + return manage(res); +} + +isl::checked::union_set union_set_list::get_at(int index) const +{ + return at(index); +} + +isl::checked::union_set_list union_set_list::clear() const +{ + auto res = isl_union_set_list_clear(copy()); + return manage(res); +} + +isl::checked::union_set_list union_set_list::concat(isl::checked::union_set_list list2) const +{ + auto res = isl_union_set_list_concat(copy(), list2.release()); + return manage(res); +} + +isl::checked::union_set_list union_set_list::drop(unsigned int first, unsigned int n) const +{ + auto res = isl_union_set_list_drop(copy(), first, n); + return manage(res); +} + +stat union_set_list::foreach(const std::function &fn) const +{ + struct fn_data { + std::function func; + } fn_data = { fn }; + auto fn_lambda = [](isl_union_set *arg_0, void *arg_1) -> isl_stat { + auto *data = static_cast(arg_1); + auto ret = (data->func)(manage(arg_0)); + return ret.release(); + }; + auto res = isl_union_set_list_foreach(get(), fn_lambda, &fn_data); + return manage(res); +} + +stat union_set_list::foreach_scc(const std::function &follows, const std::function &fn) const +{ + struct follows_data { + std::function func; + } follows_data = { follows }; + auto follows_lambda = [](isl_union_set *arg_0, isl_union_set *arg_1, void *arg_2) -> isl_bool { + auto *data = static_cast(arg_2); + auto ret = (data->func)(manage_copy(arg_0), manage_copy(arg_1)); + return ret.release(); + }; + struct fn_data { + std::function func; + } fn_data = { fn }; + auto fn_lambda = [](isl_union_set_list *arg_0, void *arg_1) -> isl_stat { + auto *data = static_cast(arg_1); + auto ret = (data->func)(manage(arg_0)); + return ret.release(); + }; + auto res = isl_union_set_list_foreach_scc(get(), follows_lambda, &follows_data, fn_lambda, &fn_data); + return manage(res); +} + +isl::checked::union_set_list union_set_list::insert(unsigned int pos, isl::checked::union_set el) const +{ + auto res = isl_union_set_list_insert(copy(), pos, el.release()); + return manage(res); +} + +isl::checked::union_set_list union_set_list::set_at(int index, isl::checked::union_set el) const +{ + auto res = isl_union_set_list_set_at(copy(), index, el.release()); + return manage(res); +} + +class size union_set_list::size() const +{ + auto res = isl_union_set_list_size(get()); + return manage(res); +} + +inline std::ostream &operator<<(std::ostream &os, const union_set_list &obj) +{ + char *str = isl_union_set_list_to_str(obj.get()); + if (!str) { + os.setstate(std::ios_base::badbit); + return os; + } + os << str; + free(str); + return os; +} + +// implementations for isl::val +val manage(__isl_take isl_val *ptr) { + return val(ptr); +} +val manage_copy(__isl_keep isl_val *ptr) { + ptr = isl_val_copy(ptr); + return val(ptr); +} + +val::val(__isl_take isl_val *ptr) + : ptr(ptr) {} + +val::val() + : ptr(nullptr) {} + +val::val(const val &obj) + : ptr(nullptr) +{ + ptr = obj.copy(); +} + +val::val(isl::checked::ctx ctx, long i) +{ + auto res = isl_val_int_from_si(ctx.release(), i); + ptr = res; +} + +val::val(isl::checked::ctx ctx, const std::string &str) +{ + auto res = isl_val_read_from_str(ctx.release(), str.c_str()); + ptr = res; +} + +val &val::operator=(val obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +val::~val() { + if (ptr) + isl_val_free(ptr); +} + +__isl_give isl_val *val::copy() const & { + return isl_val_copy(ptr); +} + +__isl_keep isl_val *val::get() const { + return ptr; +} + +__isl_give isl_val *val::release() { + isl_val *tmp = ptr; + ptr = nullptr; + return tmp; +} + +bool val::is_null() const { + return ptr == nullptr; +} + +isl::checked::ctx val::ctx() const { + return isl::checked::ctx(isl_val_get_ctx(ptr)); +} + +isl::checked::val val::abs() const +{ + auto res = isl_val_abs(copy()); + return manage(res); +} + +boolean val::abs_eq(const isl::checked::val &v2) const +{ + auto res = isl_val_abs_eq(get(), v2.get()); + return manage(res); +} + +boolean val::abs_eq(long v2) const +{ + return this->abs_eq(isl::checked::val(ctx(), v2)); +} + +isl::checked::val val::add(isl::checked::val v2) const +{ + auto res = isl_val_add(copy(), v2.release()); + return manage(res); +} + +isl::checked::val val::add(long v2) const +{ + return this->add(isl::checked::val(ctx(), v2)); +} + +isl::checked::val val::ceil() const +{ + auto res = isl_val_ceil(copy()); + return manage(res); +} + +int val::cmp_si(long i) const +{ + auto res = isl_val_cmp_si(get(), i); + return res; +} + +long val::den_si() const +{ + auto res = isl_val_get_den_si(get()); + return res; +} + +long val::get_den_si() const +{ + return den_si(); +} + +isl::checked::val val::div(isl::checked::val v2) const +{ + auto res = isl_val_div(copy(), v2.release()); + return manage(res); +} + +isl::checked::val val::div(long v2) const +{ + return this->div(isl::checked::val(ctx(), v2)); +} + +boolean val::eq(const isl::checked::val &v2) const +{ + auto res = isl_val_eq(get(), v2.get()); + return manage(res); +} + +boolean val::eq(long v2) const +{ + return this->eq(isl::checked::val(ctx(), v2)); +} + +isl::checked::val val::floor() const +{ + auto res = isl_val_floor(copy()); + return manage(res); +} + +isl::checked::val val::gcd(isl::checked::val v2) const +{ + auto res = isl_val_gcd(copy(), v2.release()); + return manage(res); +} + +isl::checked::val val::gcd(long v2) const +{ + return this->gcd(isl::checked::val(ctx(), v2)); +} + +boolean val::ge(const isl::checked::val &v2) const +{ + auto res = isl_val_ge(get(), v2.get()); + return manage(res); +} + +boolean val::ge(long v2) const +{ + return this->ge(isl::checked::val(ctx(), v2)); +} + +boolean val::gt(const isl::checked::val &v2) const +{ + auto res = isl_val_gt(get(), v2.get()); + return manage(res); +} + +boolean val::gt(long v2) const +{ + return this->gt(isl::checked::val(ctx(), v2)); +} + +isl::checked::val val::infty(isl::checked::ctx ctx) +{ + auto res = isl_val_infty(ctx.release()); + return manage(res); +} + +isl::checked::val val::inv() const +{ + auto res = isl_val_inv(copy()); + return manage(res); +} + +boolean val::is_divisible_by(const isl::checked::val &v2) const +{ + auto res = isl_val_is_divisible_by(get(), v2.get()); + return manage(res); +} + +boolean val::is_divisible_by(long v2) const +{ + return this->is_divisible_by(isl::checked::val(ctx(), v2)); +} + +boolean val::is_infty() const +{ + auto res = isl_val_is_infty(get()); + return manage(res); +} + +boolean val::is_int() const +{ + auto res = isl_val_is_int(get()); + return manage(res); +} + +boolean val::is_nan() const +{ + auto res = isl_val_is_nan(get()); + return manage(res); +} + +boolean val::is_neg() const +{ + auto res = isl_val_is_neg(get()); + return manage(res); +} + +boolean val::is_neginfty() const +{ + auto res = isl_val_is_neginfty(get()); + return manage(res); +} + +boolean val::is_negone() const +{ + auto res = isl_val_is_negone(get()); + return manage(res); +} + +boolean val::is_nonneg() const +{ + auto res = isl_val_is_nonneg(get()); + return manage(res); +} + +boolean val::is_nonpos() const +{ + auto res = isl_val_is_nonpos(get()); + return manage(res); +} + +boolean val::is_one() const +{ + auto res = isl_val_is_one(get()); + return manage(res); +} + +boolean val::is_pos() const +{ + auto res = isl_val_is_pos(get()); + return manage(res); +} + +boolean val::is_rat() const +{ + auto res = isl_val_is_rat(get()); + return manage(res); +} + +boolean val::is_zero() const +{ + auto res = isl_val_is_zero(get()); + return manage(res); +} + +boolean val::le(const isl::checked::val &v2) const +{ + auto res = isl_val_le(get(), v2.get()); + return manage(res); +} + +boolean val::le(long v2) const +{ + return this->le(isl::checked::val(ctx(), v2)); +} + +boolean val::lt(const isl::checked::val &v2) const +{ + auto res = isl_val_lt(get(), v2.get()); + return manage(res); +} + +boolean val::lt(long v2) const +{ + return this->lt(isl::checked::val(ctx(), v2)); +} + +isl::checked::val val::max(isl::checked::val v2) const +{ + auto res = isl_val_max(copy(), v2.release()); + return manage(res); +} + +isl::checked::val val::max(long v2) const +{ + return this->max(isl::checked::val(ctx(), v2)); +} + +isl::checked::val val::min(isl::checked::val v2) const +{ + auto res = isl_val_min(copy(), v2.release()); + return manage(res); +} + +isl::checked::val val::min(long v2) const +{ + return this->min(isl::checked::val(ctx(), v2)); +} + +isl::checked::val val::mod(isl::checked::val v2) const +{ + auto res = isl_val_mod(copy(), v2.release()); + return manage(res); +} + +isl::checked::val val::mod(long v2) const +{ + return this->mod(isl::checked::val(ctx(), v2)); +} + +isl::checked::val val::mul(isl::checked::val v2) const +{ + auto res = isl_val_mul(copy(), v2.release()); + return manage(res); +} + +isl::checked::val val::mul(long v2) const +{ + return this->mul(isl::checked::val(ctx(), v2)); +} + +isl::checked::val val::nan(isl::checked::ctx ctx) +{ + auto res = isl_val_nan(ctx.release()); + return manage(res); +} + +boolean val::ne(const isl::checked::val &v2) const +{ + auto res = isl_val_ne(get(), v2.get()); + return manage(res); +} + +boolean val::ne(long v2) const +{ + return this->ne(isl::checked::val(ctx(), v2)); +} + +isl::checked::val val::neg() const +{ + auto res = isl_val_neg(copy()); + return manage(res); +} + +isl::checked::val val::neginfty(isl::checked::ctx ctx) +{ + auto res = isl_val_neginfty(ctx.release()); + return manage(res); +} + +isl::checked::val val::negone(isl::checked::ctx ctx) +{ + auto res = isl_val_negone(ctx.release()); + return manage(res); +} + +long val::num_si() const +{ + auto res = isl_val_get_num_si(get()); + return res; +} + +long val::get_num_si() const +{ + return num_si(); +} + +isl::checked::val val::one(isl::checked::ctx ctx) +{ + auto res = isl_val_one(ctx.release()); + return manage(res); +} + +isl::checked::val val::pow2() const +{ + auto res = isl_val_pow2(copy()); + return manage(res); +} + +int val::sgn() const +{ + auto res = isl_val_sgn(get()); + return res; +} + +isl::checked::val val::sub(isl::checked::val v2) const +{ + auto res = isl_val_sub(copy(), v2.release()); + return manage(res); +} + +isl::checked::val val::sub(long v2) const +{ + return this->sub(isl::checked::val(ctx(), v2)); +} + +isl::checked::val_list val::to_list() const +{ + auto res = isl_val_to_list(copy()); + return manage(res); +} + +isl::checked::val val::trunc() const +{ + auto res = isl_val_trunc(copy()); + return manage(res); +} + +isl::checked::val val::zero(isl::checked::ctx ctx) +{ + auto res = isl_val_zero(ctx.release()); + return manage(res); +} + +inline std::ostream &operator<<(std::ostream &os, const val &obj) +{ + char *str = isl_val_to_str(obj.get()); + if (!str) { + os.setstate(std::ios_base::badbit); + return os; + } + os << str; + free(str); + return os; +} + +// implementations for isl::val_list +val_list manage(__isl_take isl_val_list *ptr) { + return val_list(ptr); +} +val_list manage_copy(__isl_keep isl_val_list *ptr) { + ptr = isl_val_list_copy(ptr); + return val_list(ptr); +} + +val_list::val_list(__isl_take isl_val_list *ptr) + : ptr(ptr) {} + +val_list::val_list() + : ptr(nullptr) {} + +val_list::val_list(const val_list &obj) + : ptr(nullptr) +{ + ptr = obj.copy(); +} + +val_list::val_list(isl::checked::ctx ctx, int n) +{ + auto res = isl_val_list_alloc(ctx.release(), n); + ptr = res; +} + +val_list::val_list(isl::checked::val el) +{ + auto res = isl_val_list_from_val(el.release()); + ptr = res; +} + +val_list::val_list(isl::checked::ctx ctx, const std::string &str) +{ + auto res = isl_val_list_read_from_str(ctx.release(), str.c_str()); + ptr = res; +} + +val_list &val_list::operator=(val_list obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +val_list::~val_list() { + if (ptr) + isl_val_list_free(ptr); +} + +__isl_give isl_val_list *val_list::copy() const & { + return isl_val_list_copy(ptr); +} + +__isl_keep isl_val_list *val_list::get() const { + return ptr; +} + +__isl_give isl_val_list *val_list::release() { + isl_val_list *tmp = ptr; + ptr = nullptr; + return tmp; +} + +bool val_list::is_null() const { + return ptr == nullptr; +} + +isl::checked::ctx val_list::ctx() const { + return isl::checked::ctx(isl_val_list_get_ctx(ptr)); +} + +isl::checked::val_list val_list::add(isl::checked::val el) const +{ + auto res = isl_val_list_add(copy(), el.release()); + return manage(res); +} + +isl::checked::val_list val_list::add(long el) const +{ + return this->add(isl::checked::val(ctx(), el)); +} + +isl::checked::val val_list::at(int index) const +{ + auto res = isl_val_list_get_at(get(), index); + return manage(res); +} + +isl::checked::val val_list::get_at(int index) const +{ + return at(index); +} + +isl::checked::val_list val_list::clear() const +{ + auto res = isl_val_list_clear(copy()); + return manage(res); +} + +isl::checked::val_list val_list::concat(isl::checked::val_list list2) const +{ + auto res = isl_val_list_concat(copy(), list2.release()); + return manage(res); +} + +isl::checked::val_list val_list::drop(unsigned int first, unsigned int n) const +{ + auto res = isl_val_list_drop(copy(), first, n); + return manage(res); +} + +stat val_list::foreach(const std::function &fn) const +{ + struct fn_data { + std::function func; + } fn_data = { fn }; + auto fn_lambda = [](isl_val *arg_0, void *arg_1) -> isl_stat { + auto *data = static_cast(arg_1); + auto ret = (data->func)(manage(arg_0)); + return ret.release(); + }; + auto res = isl_val_list_foreach(get(), fn_lambda, &fn_data); + return manage(res); +} + +stat val_list::foreach_scc(const std::function &follows, const std::function &fn) const +{ + struct follows_data { + std::function func; + } follows_data = { follows }; + auto follows_lambda = [](isl_val *arg_0, isl_val *arg_1, void *arg_2) -> isl_bool { + auto *data = static_cast(arg_2); + auto ret = (data->func)(manage_copy(arg_0), manage_copy(arg_1)); + return ret.release(); + }; + struct fn_data { + std::function func; + } fn_data = { fn }; + auto fn_lambda = [](isl_val_list *arg_0, void *arg_1) -> isl_stat { + auto *data = static_cast(arg_1); + auto ret = (data->func)(manage(arg_0)); + return ret.release(); + }; + auto res = isl_val_list_foreach_scc(get(), follows_lambda, &follows_data, fn_lambda, &fn_data); + return manage(res); +} + +isl::checked::val_list val_list::insert(unsigned int pos, isl::checked::val el) const +{ + auto res = isl_val_list_insert(copy(), pos, el.release()); + return manage(res); +} + +isl::checked::val_list val_list::insert(unsigned int pos, long el) const +{ + return this->insert(pos, isl::checked::val(ctx(), el)); +} + +isl::checked::val_list val_list::set_at(int index, isl::checked::val el) const +{ + auto res = isl_val_list_set_at(copy(), index, el.release()); + return manage(res); +} + +isl::checked::val_list val_list::set_at(int index, long el) const +{ + return this->set_at(index, isl::checked::val(ctx(), el)); +} + +class size val_list::size() const +{ + auto res = isl_val_list_size(get()); + return manage(res); +} + +inline std::ostream &operator<<(std::ostream &os, const val_list &obj) +{ + char *str = isl_val_list_to_str(obj.get()); + if (!str) { + os.setstate(std::ios_base::badbit); + return os; + } + os << str; + free(str); + return os; +} +} // namespace checked +} // namespace isl + +#endif /* ISL_CPP_CHECKED */ diff --git a/external/mit/isl/dist/include/isl/cpp.h b/external/mit/isl/dist/include/isl/cpp.h new file mode 100644 index 000000000000..5040183c0063 --- /dev/null +++ b/external/mit/isl/dist/include/isl/cpp.h @@ -0,0 +1,30843 @@ +/// 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 +#define ISL_CPP + +#include +#include + +#include +#include +#include +#include +#include +#include + +#if __cplusplus >= 201703L +#include +#include +#endif + +/* ISL_USE_EXCEPTIONS should be defined to 1 if exceptions are available. + * gcc and clang define __cpp_exceptions; MSVC and xlC define _CPPUNWIND. + * Older versions of gcc (e.g., 4.9) only define __EXCEPTIONS. + * If exceptions are not available, any error condition will result + * in an abort. + */ +#ifndef ISL_USE_EXCEPTIONS +#if defined(__cpp_exceptions) || defined(_CPPUNWIND) || defined(__EXCEPTIONS) +#define ISL_USE_EXCEPTIONS 1 +#else +#define ISL_USE_EXCEPTIONS 0 +#endif +#endif + +namespace isl { + +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; + } +#if __cplusplus >= 201703L + static void free_user(void *user) { + std::any *p = static_cast(user); + delete p; + } +#endif +}; + +/* Macros hiding try/catch. + * If exceptions are not available, then no exceptions will be thrown and + * there is nothing to catch. + */ +#if ISL_USE_EXCEPTIONS +#define ISL_CPP_TRY try +#define ISL_CPP_CATCH_ALL catch (...) +#else +#define ISL_CPP_TRY if (1) +#define ISL_CPP_CATCH_ALL if (0) +#endif + +#if ISL_USE_EXCEPTIONS + +/* Class capturing isl errors. + * + * The what() return value is stored in a reference counted string + * to ensure that the copy constructor and the assignment operator + * do not throw any exceptions. + */ +class exception : public std::exception { + std::shared_ptr what_str; + +protected: + inline exception(const char *what_arg, const char *msg, + const char *file, int line); +public: + exception() {} + exception(const char *what_arg) { + what_str = std::make_shared(what_arg); + } + static inline void throw_error(enum isl_error error, const char *msg, + const char *file, int line); + virtual const char *what() const noexcept { + return what_str->c_str(); + } + + /* Default behavior on error conditions that occur inside isl calls + * performed from inside the bindings. + * In the case exceptions are available, isl should continue + * without printing a warning since the warning message + * will be included in the exception thrown from inside the bindings. + */ + static constexpr auto on_error = ISL_ON_ERROR_CONTINUE; + /* Wrapper for throwing an exception with the given message. + */ + static void throw_invalid(const char *msg, const char *file, int line) { + throw_error(isl_error_invalid, msg, file, line); + } + static inline void throw_last_error(ctx ctx); +}; + +/* Create an exception of a type described by "what_arg", with + * error message "msg" in line "line" of file "file". + * + * Create a string holding the what() return value that + * corresponds to what isl would have printed. + * If no error message or no error file was set, then use "what_arg" instead. + */ +exception::exception(const char *what_arg, const char *msg, const char *file, + int line) +{ + if (!msg || !file) + what_str = std::make_shared(what_arg); + else + what_str = std::make_shared(std::string(file) + + ":" + std::to_string(line) + ": " + msg); +} + +class exception_abort : public exception { + friend exception; + exception_abort(const char *msg, const char *file, int line) : + exception("execution aborted", msg, file, line) {} +}; + +class exception_alloc : public exception { + friend exception; + exception_alloc(const char *msg, const char *file, int line) : + exception("memory allocation failure", msg, file, line) {} +}; + +class exception_unknown : public exception { + friend exception; + exception_unknown(const char *msg, const char *file, int line) : + exception("unknown failure", msg, file, line) {} +}; + +class exception_internal : public exception { + friend exception; + exception_internal(const char *msg, const char *file, int line) : + exception("internal error", msg, file, line) {} +}; + +class exception_invalid : public exception { + friend exception; + exception_invalid(const char *msg, const char *file, int line) : + exception("invalid argument", msg, file, line) {} +}; + +class exception_quota : public exception { + friend exception; + exception_quota(const char *msg, const char *file, int line) : + exception("quota exceeded", msg, file, line) {} +}; + +class exception_unsupported : public exception { + friend exception; + exception_unsupported(const char *msg, const char *file, int line) : + exception("unsupported operation", msg, file, line) {} +}; + +/* Throw an exception of the class that corresponds to "error", with + * error message "msg" in line "line" of file "file". + * + * isl_error_none is treated as an invalid error type. + */ +void exception::throw_error(enum isl_error error, const char *msg, + const char *file, int line) +{ + switch (error) { + case isl_error_none: + break; + case isl_error_abort: throw exception_abort(msg, file, line); + case isl_error_alloc: throw exception_alloc(msg, file, line); + case isl_error_unknown: throw exception_unknown(msg, file, line); + case isl_error_internal: throw exception_internal(msg, file, line); + case isl_error_invalid: throw exception_invalid(msg, file, line); + case isl_error_quota: throw exception_quota(msg, file, line); + case isl_error_unsupported: + throw exception_unsupported(msg, file, line); + } + + throw exception_invalid("invalid error type", file, line); +} + +/* Throw an exception corresponding to the last error on "ctx" and + * reset the error. + * + * If "ctx" is NULL or if it is not in an error state at the start, + * then an invalid argument exception is thrown. + */ +void exception::throw_last_error(ctx ctx) +{ + enum isl_error error; + const char *msg, *file; + int line; + + error = isl_ctx_last_error(ctx.get()); + msg = isl_ctx_last_error_msg(ctx.get()); + file = isl_ctx_last_error_file(ctx.get()); + line = isl_ctx_last_error_line(ctx.get()); + isl_ctx_reset_error(ctx.get()); + + throw_error(error, msg, file, line); +} + +#else + +#include +#include + +class exception { +public: + /* Default behavior on error conditions that occur inside isl calls + * performed from inside the bindings. + * In the case exceptions are not available, isl should abort. + */ + static constexpr auto on_error = ISL_ON_ERROR_ABORT; + /* Wrapper for throwing an exception with the given message. + * In the case exceptions are not available, print an error and abort. + */ + static void throw_invalid(const char *msg, const char *file, int line) { + fprintf(stderr, "%s:%d: %s\n", file, line, msg); + abort(); + } + /* Throw an exception corresponding to the last + * error on "ctx". + * isl should already abort when an error condition occurs, + * so this function should never be called. + */ + static void throw_last_error(ctx ctx) { + abort(); + } +}; + +#endif + +/* Helper class for setting the on_error and resetting the option + * to the original value when leaving the scope. + */ +class options_scoped_set_on_error { + isl_ctx *ctx; + int saved_on_error; +public: + options_scoped_set_on_error(class ctx ctx, int on_error) { + this->ctx = ctx.get(); + saved_on_error = isl_options_get_on_error(this->ctx); + isl_options_set_on_error(this->ctx, on_error); + } + ~options_scoped_set_on_error() { + isl_options_set_on_error(ctx, saved_on_error); + } +}; + +} // namespace isl + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace isl { + +// forward declarations +class aff; +class aff_list; +class ast_build; +class ast_expr; +class ast_expr_id; +class ast_expr_int; +class ast_expr_op; +class ast_expr_op_access; +class ast_expr_op_add; +class ast_expr_op_address_of; +class ast_expr_op_and; +class ast_expr_op_and_then; +class ast_expr_op_call; +class ast_expr_op_cond; +class ast_expr_op_div; +class ast_expr_op_eq; +class ast_expr_op_fdiv_q; +class ast_expr_op_ge; +class ast_expr_op_gt; +class ast_expr_op_le; +class ast_expr_op_lt; +class ast_expr_op_max; +class ast_expr_op_member; +class ast_expr_op_min; +class ast_expr_op_minus; +class ast_expr_op_mul; +class ast_expr_op_or; +class ast_expr_op_or_else; +class ast_expr_op_pdiv_q; +class ast_expr_op_pdiv_r; +class ast_expr_op_select; +class ast_expr_op_sub; +class ast_expr_op_zdiv_r; +class ast_node; +class ast_node_block; +class ast_node_for; +class ast_node_if; +class ast_node_list; +class ast_node_mark; +class ast_node_user; +class basic_map; +class basic_set; +class fixed_box; +class id; +class id_list; +class id_to_ast_expr; +class id_to_id; +class map; +class map_list; +class multi_aff; +class multi_id; +class multi_pw_aff; +class multi_union_pw_aff; +class multi_val; +class point; +class pw_aff; +class pw_aff_list; +class pw_multi_aff; +class pw_multi_aff_list; +class schedule; +class schedule_constraints; +class schedule_node; +class schedule_node_band; +class schedule_node_context; +class schedule_node_domain; +class schedule_node_expansion; +class schedule_node_extension; +class schedule_node_filter; +class schedule_node_guard; +class schedule_node_leaf; +class schedule_node_mark; +class schedule_node_sequence; +class schedule_node_set; +class set; +class set_list; +class space; +class union_access_info; +class union_flow; +class union_map; +class union_pw_aff; +class union_pw_aff_list; +class union_pw_multi_aff; +class union_set; +class union_set_list; +class val; +class val_list; + +// declarations for isl::aff +inline aff manage(__isl_take isl_aff *ptr); +inline aff manage_copy(__isl_keep isl_aff *ptr); + +class aff { + friend inline aff manage(__isl_take isl_aff *ptr); + friend inline aff manage_copy(__isl_keep isl_aff *ptr); + +protected: + isl_aff *ptr = nullptr; + + inline explicit aff(__isl_take isl_aff *ptr); + +public: + inline /* implicit */ aff(); + inline /* implicit */ aff(const aff &obj); + inline explicit aff(isl::ctx ctx, const std::string &str); + inline aff &operator=(aff obj); + inline ~aff(); + inline __isl_give isl_aff *copy() const &; + inline __isl_give isl_aff *copy() && = delete; + inline __isl_keep isl_aff *get() const; + inline __isl_give isl_aff *release(); + inline bool is_null() const; + inline isl::ctx ctx() const; + + inline isl::aff add(isl::aff aff2) const; + inline isl::multi_aff add(const isl::multi_aff &multi2) const; + inline isl::multi_pw_aff add(const isl::multi_pw_aff &multi2) const; + inline isl::multi_union_pw_aff add(const isl::multi_union_pw_aff &multi2) const; + inline isl::pw_aff add(const isl::pw_aff &pwaff2) const; + inline isl::pw_multi_aff add(const isl::pw_multi_aff &pma2) const; + inline isl::union_pw_aff add(const isl::union_pw_aff &upa2) const; + inline isl::union_pw_multi_aff add(const isl::union_pw_multi_aff &upma2) const; + inline isl::aff add_constant(isl::val v) const; + inline isl::aff add_constant(long v) const; + inline isl::multi_aff add_constant(const isl::multi_val &mv) const; + inline isl::union_pw_multi_aff apply(const isl::union_pw_multi_aff &upma2) const; + inline isl::aff as_aff() const; + inline isl::map as_map() const; + inline isl::multi_aff as_multi_aff() const; + inline isl::multi_union_pw_aff as_multi_union_pw_aff() const; + inline isl::pw_multi_aff as_pw_multi_aff() const; + inline isl::set as_set() const; + inline isl::union_map as_union_map() const; + inline isl::aff at(int pos) const; + inline isl::basic_set bind(isl::id id) const; + inline isl::basic_set bind(const std::string &id) const; + inline isl::basic_set bind(const isl::multi_id &tuple) const; + inline isl::pw_aff bind_domain(const isl::multi_id &tuple) const; + inline isl::pw_aff bind_domain_wrapped_domain(const isl::multi_id &tuple) const; + inline isl::aff ceil() const; + inline isl::pw_aff coalesce() const; + inline isl::pw_aff cond(const isl::pw_aff &pwaff_true, const isl::pw_aff &pwaff_false) const; + inline isl::multi_val constant_multi_val() const; + inline isl::val constant_val() const; + inline isl::val get_constant_val() const; + inline isl::aff div(isl::aff aff2) const; + inline isl::pw_aff div(const isl::pw_aff &pa2) const; + inline isl::set domain() const; + inline isl::aff domain_reverse() const; + inline isl::pw_aff drop_unused_params() const; + inline isl::set eq_set(isl::aff aff2) const; + inline isl::set eq_set(const isl::pw_aff &pwaff2) const; + inline isl::val eval(isl::point pnt) const; + inline isl::pw_multi_aff extract_pw_multi_aff(const isl::space &space) const; + inline isl::multi_aff flat_range_product(const isl::multi_aff &multi2) const; + inline isl::multi_pw_aff flat_range_product(const isl::multi_pw_aff &multi2) const; + inline isl::multi_union_pw_aff flat_range_product(const isl::multi_union_pw_aff &multi2) const; + inline isl::pw_multi_aff flat_range_product(const isl::pw_multi_aff &pma2) const; + inline isl::union_pw_multi_aff flat_range_product(const isl::union_pw_multi_aff &upma2) const; + inline isl::aff floor() const; + inline void foreach_piece(const std::function &fn) const; + inline isl::set ge_set(isl::aff aff2) const; + inline isl::set ge_set(const isl::pw_aff &pwaff2) const; + inline isl::aff gist(isl::set context) const; + inline isl::union_pw_aff gist(const isl::union_set &context) const; + inline isl::aff gist(const isl::basic_set &context) const; + inline isl::aff gist(const isl::point &context) const; + inline isl::aff gist_params(isl::set context) const; + inline isl::set gt_set(isl::aff aff2) const; + inline isl::set gt_set(const isl::pw_aff &pwaff2) const; + inline bool has_range_tuple_id() const; + inline isl::multi_aff identity() const; + inline isl::pw_aff insert_domain(const isl::space &domain) const; + inline isl::pw_aff intersect_domain(const isl::set &set) const; + inline isl::union_pw_aff intersect_domain(const isl::space &space) const; + inline isl::union_pw_aff intersect_domain(const isl::union_set &uset) const; + inline isl::union_pw_aff intersect_domain_wrapped_domain(const isl::union_set &uset) const; + inline isl::union_pw_aff intersect_domain_wrapped_range(const isl::union_set &uset) const; + inline isl::pw_aff intersect_params(const isl::set &set) const; + inline bool involves_locals() const; + inline bool involves_nan() const; + inline bool involves_param(const isl::id &id) const; + inline bool involves_param(const std::string &id) const; + inline bool involves_param(const isl::id_list &list) const; + inline bool is_cst() const; + inline bool isa_aff() const; + inline bool isa_multi_aff() const; + inline bool isa_pw_multi_aff() const; + inline isl::set le_set(isl::aff aff2) const; + inline isl::set le_set(const isl::pw_aff &pwaff2) const; + inline isl::aff_list list() const; + inline isl::set lt_set(isl::aff aff2) const; + inline isl::set lt_set(const isl::pw_aff &pwaff2) const; + inline isl::multi_pw_aff max(const isl::multi_pw_aff &multi2) const; + inline isl::pw_aff max(const isl::pw_aff &pwaff2) const; + inline isl::multi_val max_multi_val() const; + inline isl::val max_val() const; + inline isl::multi_pw_aff min(const isl::multi_pw_aff &multi2) const; + inline isl::pw_aff min(const isl::pw_aff &pwaff2) const; + inline isl::multi_val min_multi_val() const; + inline isl::val min_val() const; + inline isl::aff mod(isl::val mod) const; + inline isl::aff mod(long mod) const; + inline isl::aff mul(isl::aff aff2) const; + inline isl::pw_aff mul(const isl::pw_aff &pwaff2) const; + inline unsigned n_piece() const; + inline isl::set ne_set(isl::aff aff2) const; + inline isl::set ne_set(const isl::pw_aff &pwaff2) const; + inline isl::aff neg() const; + inline isl::set params() const; + inline bool plain_is_empty() const; + inline bool plain_is_equal(const isl::aff &aff2) const; + inline bool plain_is_equal(const isl::multi_aff &multi2) const; + inline bool plain_is_equal(const isl::multi_pw_aff &multi2) const; + inline bool plain_is_equal(const isl::multi_union_pw_aff &multi2) const; + inline bool plain_is_equal(const isl::pw_aff &pwaff2) const; + inline bool plain_is_equal(const isl::pw_multi_aff &pma2) const; + inline bool plain_is_equal(const isl::union_pw_aff &upa2) const; + inline bool plain_is_equal(const isl::union_pw_multi_aff &upma2) const; + inline isl::pw_multi_aff preimage_domain_wrapped_domain(const isl::pw_multi_aff &pma2) const; + inline isl::union_pw_multi_aff preimage_domain_wrapped_domain(const isl::union_pw_multi_aff &upma2) const; + inline isl::multi_aff product(const isl::multi_aff &multi2) const; + inline isl::multi_pw_aff product(const isl::multi_pw_aff &multi2) const; + inline isl::pw_multi_aff product(const isl::pw_multi_aff &pma2) const; + inline isl::aff pullback(isl::multi_aff ma) const; + inline isl::pw_aff pullback(const isl::multi_pw_aff &mpa) const; + inline isl::pw_aff pullback(const isl::pw_multi_aff &pma) const; + inline isl::union_pw_aff pullback(const isl::union_pw_multi_aff &upma) const; + inline isl::aff pullback(const isl::aff &ma) const; + inline isl::pw_multi_aff_list pw_multi_aff_list() const; + inline isl::pw_multi_aff range_factor_domain() const; + inline isl::pw_multi_aff range_factor_range() const; + inline isl::multi_aff range_product(const isl::multi_aff &multi2) const; + inline isl::multi_pw_aff range_product(const isl::multi_pw_aff &multi2) const; + inline isl::multi_union_pw_aff range_product(const isl::multi_union_pw_aff &multi2) const; + inline isl::pw_multi_aff range_product(const isl::pw_multi_aff &pma2) const; + inline isl::union_pw_multi_aff range_product(const isl::union_pw_multi_aff &upma2) const; + inline isl::id range_tuple_id() const; + inline isl::multi_aff reset_range_tuple_id() const; + inline isl::aff scale(isl::val v) const; + inline isl::aff scale(long v) const; + inline isl::multi_aff scale(const isl::multi_val &mv) const; + inline isl::aff scale_down(isl::val v) const; + inline isl::aff scale_down(long v) const; + inline isl::multi_aff scale_down(const isl::multi_val &mv) const; + inline isl::multi_aff set_at(int pos, const isl::aff &el) const; + inline isl::multi_pw_aff set_at(int pos, const isl::pw_aff &el) const; + inline isl::multi_union_pw_aff set_at(int pos, const isl::union_pw_aff &el) const; + inline isl::multi_aff set_range_tuple(const isl::id &id) const; + inline isl::multi_aff set_range_tuple(const std::string &id) const; + inline unsigned size() const; + inline isl::space space() const; + inline isl::aff sub(isl::aff aff2) const; + inline isl::multi_aff sub(const isl::multi_aff &multi2) const; + inline isl::multi_pw_aff sub(const isl::multi_pw_aff &multi2) const; + inline isl::multi_union_pw_aff sub(const isl::multi_union_pw_aff &multi2) const; + inline isl::pw_aff sub(const isl::pw_aff &pwaff2) const; + inline isl::pw_multi_aff sub(const isl::pw_multi_aff &pma2) const; + inline isl::union_pw_aff sub(const isl::union_pw_aff &upa2) const; + inline isl::union_pw_multi_aff sub(const isl::union_pw_multi_aff &upma2) const; + inline isl::pw_aff subtract_domain(const isl::set &set) const; + inline isl::union_pw_aff subtract_domain(const isl::space &space) const; + inline isl::union_pw_aff subtract_domain(const isl::union_set &uset) const; + inline isl::pw_aff tdiv_q(const isl::pw_aff &pa2) const; + inline isl::pw_aff tdiv_r(const isl::pw_aff &pa2) const; + inline isl::aff_list to_list() const; + inline isl::multi_pw_aff to_multi_pw_aff() const; + inline isl::multi_union_pw_aff to_multi_union_pw_aff() const; + inline isl::pw_multi_aff to_pw_multi_aff() const; + inline isl::union_pw_aff to_union_pw_aff() const; + inline isl::union_pw_multi_aff to_union_pw_multi_aff() const; + inline isl::aff unbind_params_insert_domain(isl::multi_id domain) const; + inline isl::multi_pw_aff union_add(const isl::multi_pw_aff &mpa2) const; + inline isl::multi_union_pw_aff union_add(const isl::multi_union_pw_aff &mupa2) const; + inline isl::pw_aff union_add(const isl::pw_aff &pwaff2) const; + inline isl::pw_multi_aff union_add(const isl::pw_multi_aff &pma2) const; + inline isl::union_pw_aff union_add(const isl::union_pw_aff &upa2) const; + inline isl::union_pw_multi_aff union_add(const isl::union_pw_multi_aff &upma2) const; + static inline isl::aff zero_on_domain(isl::space space); +}; + +// declarations for isl::aff_list +inline aff_list manage(__isl_take isl_aff_list *ptr); +inline aff_list manage_copy(__isl_keep isl_aff_list *ptr); + +class aff_list { + friend inline aff_list manage(__isl_take isl_aff_list *ptr); + friend inline aff_list manage_copy(__isl_keep isl_aff_list *ptr); + +protected: + isl_aff_list *ptr = nullptr; + + inline explicit aff_list(__isl_take isl_aff_list *ptr); + +public: + inline /* implicit */ aff_list(); + inline /* implicit */ aff_list(const aff_list &obj); + inline explicit aff_list(isl::ctx ctx, int n); + inline explicit aff_list(isl::aff el); + inline explicit aff_list(isl::ctx ctx, const std::string &str); + inline aff_list &operator=(aff_list obj); + inline ~aff_list(); + inline __isl_give isl_aff_list *copy() const &; + inline __isl_give isl_aff_list *copy() && = delete; + inline __isl_keep isl_aff_list *get() const; + inline __isl_give isl_aff_list *release(); + inline bool is_null() const; + inline isl::ctx ctx() const; + + inline isl::aff_list add(isl::aff el) const; + inline isl::aff at(int index) const; + inline isl::aff get_at(int index) const; + inline isl::aff_list clear() const; + inline isl::aff_list concat(isl::aff_list list2) const; + inline isl::aff_list drop(unsigned int first, unsigned int n) const; + inline void foreach(const std::function &fn) const; + inline void foreach_scc(const std::function &follows, const std::function &fn) const; + inline isl::aff_list insert(unsigned int pos, isl::aff el) const; + inline isl::aff_list set_at(int index, isl::aff el) const; + inline unsigned size() const; +}; + +// declarations for isl::ast_build +inline ast_build manage(__isl_take isl_ast_build *ptr); +inline ast_build manage_copy(__isl_keep isl_ast_build *ptr); + +class ast_build { + friend inline ast_build manage(__isl_take isl_ast_build *ptr); + friend inline ast_build manage_copy(__isl_keep isl_ast_build *ptr); + +protected: + isl_ast_build *ptr = nullptr; + + inline explicit ast_build(__isl_take isl_ast_build *ptr); + +public: + inline /* implicit */ ast_build(); + inline /* implicit */ ast_build(const ast_build &obj); + inline explicit ast_build(isl::ctx ctx); + inline ast_build &operator=(ast_build obj); + inline ~ast_build(); + inline __isl_give isl_ast_build *copy() const &; + inline __isl_give isl_ast_build *copy() && = delete; + inline __isl_keep isl_ast_build *get() const; + inline __isl_give isl_ast_build *release(); + inline bool is_null() const; + inline isl::ctx ctx() const; + +private: + inline ast_build ©_callbacks(const ast_build &obj); + struct at_each_domain_data { + std::function func; + std::exception_ptr eptr; + }; + std::shared_ptr at_each_domain_data; + static inline isl_ast_node *at_each_domain(isl_ast_node *arg_0, isl_ast_build *arg_1, void *arg_2); + inline void set_at_each_domain_data(const std::function &fn); +public: + inline isl::ast_build set_at_each_domain(const std::function &fn) const; + inline isl::ast_expr access_from(isl::multi_pw_aff mpa) const; + inline isl::ast_expr access_from(isl::pw_multi_aff pma) const; + inline isl::ast_expr call_from(isl::multi_pw_aff mpa) const; + inline isl::ast_expr call_from(isl::pw_multi_aff pma) const; + inline isl::ast_expr expr_from(isl::pw_aff pa) const; + inline isl::ast_expr expr_from(isl::set set) const; + static inline isl::ast_build from_context(isl::set set); + inline isl::ast_node node_from(isl::schedule schedule) const; + inline isl::ast_node node_from_schedule_map(isl::union_map schedule) const; + inline isl::union_map schedule() const; + inline isl::union_map get_schedule() const; +}; + +// declarations for isl::ast_expr +inline ast_expr manage(__isl_take isl_ast_expr *ptr); +inline ast_expr manage_copy(__isl_keep isl_ast_expr *ptr); + +class ast_expr { + friend inline ast_expr manage(__isl_take isl_ast_expr *ptr); + friend inline ast_expr manage_copy(__isl_keep isl_ast_expr *ptr); + +protected: + isl_ast_expr *ptr = nullptr; + + inline explicit ast_expr(__isl_take isl_ast_expr *ptr); + +public: + inline /* implicit */ ast_expr(); + inline /* implicit */ ast_expr(const ast_expr &obj); + inline ast_expr &operator=(ast_expr obj); + inline ~ast_expr(); + inline __isl_give isl_ast_expr *copy() const &; + inline __isl_give isl_ast_expr *copy() && = delete; + inline __isl_keep isl_ast_expr *get() const; + inline __isl_give isl_ast_expr *release(); + inline bool is_null() const; +private: + template ::value>::type> + inline bool isa_type(T subtype) const; +public: + template inline bool isa() const; + template inline T as() const; + inline isl::ctx ctx() const; + + inline std::string to_C_str() const; +}; + +// declarations for isl::ast_expr_id + +class ast_expr_id : public ast_expr { + template + friend bool ast_expr::isa() const; + friend ast_expr_id ast_expr::as() const; + static const auto type = isl_ast_expr_id; + +protected: + inline explicit ast_expr_id(__isl_take isl_ast_expr *ptr); + +public: + inline /* implicit */ ast_expr_id(); + inline /* implicit */ ast_expr_id(const ast_expr_id &obj); + inline ast_expr_id &operator=(ast_expr_id obj); + inline isl::ctx ctx() const; + + inline isl::id id() const; + inline isl::id get_id() const; +}; + +// declarations for isl::ast_expr_int + +class ast_expr_int : public ast_expr { + template + friend bool ast_expr::isa() const; + friend ast_expr_int ast_expr::as() const; + static const auto type = isl_ast_expr_int; + +protected: + inline explicit ast_expr_int(__isl_take isl_ast_expr *ptr); + +public: + inline /* implicit */ ast_expr_int(); + inline /* implicit */ ast_expr_int(const ast_expr_int &obj); + inline ast_expr_int &operator=(ast_expr_int obj); + inline isl::ctx ctx() const; + + inline isl::val val() const; + inline isl::val get_val() const; +}; + +// declarations for isl::ast_expr_op + +class ast_expr_op : public ast_expr { + template + friend bool ast_expr::isa() const; + friend ast_expr_op ast_expr::as() const; + static const auto type = isl_ast_expr_op; + +protected: + inline explicit ast_expr_op(__isl_take isl_ast_expr *ptr); + +public: + inline /* implicit */ ast_expr_op(); + inline /* implicit */ ast_expr_op(const ast_expr_op &obj); + inline ast_expr_op &operator=(ast_expr_op obj); +private: + template ::value>::type> + inline bool isa_type(T subtype) const; +public: + template inline bool isa() const; + template inline T as() const; + inline isl::ctx ctx() const; + + inline isl::ast_expr arg(int pos) const; + inline isl::ast_expr get_arg(int pos) const; + inline unsigned n_arg() const; + inline unsigned get_n_arg() const; +}; + +// declarations for isl::ast_expr_op_access + +class ast_expr_op_access : public ast_expr_op { + template + friend bool ast_expr_op::isa() const; + friend ast_expr_op_access ast_expr_op::as() const; + static const auto type = isl_ast_expr_op_access; + +protected: + inline explicit ast_expr_op_access(__isl_take isl_ast_expr *ptr); + +public: + inline /* implicit */ ast_expr_op_access(); + inline /* implicit */ ast_expr_op_access(const ast_expr_op_access &obj); + inline ast_expr_op_access &operator=(ast_expr_op_access obj); + inline isl::ctx ctx() const; + +}; + +// declarations for isl::ast_expr_op_add + +class ast_expr_op_add : public ast_expr_op { + template + friend bool ast_expr_op::isa() const; + friend ast_expr_op_add ast_expr_op::as() const; + static const auto type = isl_ast_expr_op_add; + +protected: + inline explicit ast_expr_op_add(__isl_take isl_ast_expr *ptr); + +public: + inline /* implicit */ ast_expr_op_add(); + inline /* implicit */ ast_expr_op_add(const ast_expr_op_add &obj); + inline ast_expr_op_add &operator=(ast_expr_op_add obj); + inline isl::ctx ctx() const; + +}; + +// declarations for isl::ast_expr_op_address_of + +class ast_expr_op_address_of : public ast_expr_op { + template + friend bool ast_expr_op::isa() const; + friend ast_expr_op_address_of ast_expr_op::as() const; + static const auto type = isl_ast_expr_op_address_of; + +protected: + inline explicit ast_expr_op_address_of(__isl_take isl_ast_expr *ptr); + +public: + inline /* implicit */ ast_expr_op_address_of(); + inline /* implicit */ ast_expr_op_address_of(const ast_expr_op_address_of &obj); + inline ast_expr_op_address_of &operator=(ast_expr_op_address_of obj); + inline isl::ctx ctx() const; + +}; + +// declarations for isl::ast_expr_op_and + +class ast_expr_op_and : public ast_expr_op { + template + friend bool ast_expr_op::isa() const; + friend ast_expr_op_and ast_expr_op::as() const; + static const auto type = isl_ast_expr_op_and; + +protected: + inline explicit ast_expr_op_and(__isl_take isl_ast_expr *ptr); + +public: + inline /* implicit */ ast_expr_op_and(); + inline /* implicit */ ast_expr_op_and(const ast_expr_op_and &obj); + inline ast_expr_op_and &operator=(ast_expr_op_and obj); + inline isl::ctx ctx() const; + +}; + +// declarations for isl::ast_expr_op_and_then + +class ast_expr_op_and_then : public ast_expr_op { + template + friend bool ast_expr_op::isa() const; + friend ast_expr_op_and_then ast_expr_op::as() const; + static const auto type = isl_ast_expr_op_and_then; + +protected: + inline explicit ast_expr_op_and_then(__isl_take isl_ast_expr *ptr); + +public: + inline /* implicit */ ast_expr_op_and_then(); + inline /* implicit */ ast_expr_op_and_then(const ast_expr_op_and_then &obj); + inline ast_expr_op_and_then &operator=(ast_expr_op_and_then obj); + inline isl::ctx ctx() const; + +}; + +// declarations for isl::ast_expr_op_call + +class ast_expr_op_call : public ast_expr_op { + template + friend bool ast_expr_op::isa() const; + friend ast_expr_op_call ast_expr_op::as() const; + static const auto type = isl_ast_expr_op_call; + +protected: + inline explicit ast_expr_op_call(__isl_take isl_ast_expr *ptr); + +public: + inline /* implicit */ ast_expr_op_call(); + inline /* implicit */ ast_expr_op_call(const ast_expr_op_call &obj); + inline ast_expr_op_call &operator=(ast_expr_op_call obj); + inline isl::ctx ctx() const; + +}; + +// declarations for isl::ast_expr_op_cond + +class ast_expr_op_cond : public ast_expr_op { + template + friend bool ast_expr_op::isa() const; + friend ast_expr_op_cond ast_expr_op::as() const; + static const auto type = isl_ast_expr_op_cond; + +protected: + inline explicit ast_expr_op_cond(__isl_take isl_ast_expr *ptr); + +public: + inline /* implicit */ ast_expr_op_cond(); + inline /* implicit */ ast_expr_op_cond(const ast_expr_op_cond &obj); + inline ast_expr_op_cond &operator=(ast_expr_op_cond obj); + inline isl::ctx ctx() const; + +}; + +// declarations for isl::ast_expr_op_div + +class ast_expr_op_div : public ast_expr_op { + template + friend bool ast_expr_op::isa() const; + friend ast_expr_op_div ast_expr_op::as() const; + static const auto type = isl_ast_expr_op_div; + +protected: + inline explicit ast_expr_op_div(__isl_take isl_ast_expr *ptr); + +public: + inline /* implicit */ ast_expr_op_div(); + inline /* implicit */ ast_expr_op_div(const ast_expr_op_div &obj); + inline ast_expr_op_div &operator=(ast_expr_op_div obj); + inline isl::ctx ctx() const; + +}; + +// declarations for isl::ast_expr_op_eq + +class ast_expr_op_eq : public ast_expr_op { + template + friend bool ast_expr_op::isa() const; + friend ast_expr_op_eq ast_expr_op::as() const; + static const auto type = isl_ast_expr_op_eq; + +protected: + inline explicit ast_expr_op_eq(__isl_take isl_ast_expr *ptr); + +public: + inline /* implicit */ ast_expr_op_eq(); + inline /* implicit */ ast_expr_op_eq(const ast_expr_op_eq &obj); + inline ast_expr_op_eq &operator=(ast_expr_op_eq obj); + inline isl::ctx ctx() const; + +}; + +// declarations for isl::ast_expr_op_fdiv_q + +class ast_expr_op_fdiv_q : public ast_expr_op { + template + friend bool ast_expr_op::isa() const; + friend ast_expr_op_fdiv_q ast_expr_op::as() const; + static const auto type = isl_ast_expr_op_fdiv_q; + +protected: + inline explicit ast_expr_op_fdiv_q(__isl_take isl_ast_expr *ptr); + +public: + inline /* implicit */ ast_expr_op_fdiv_q(); + inline /* implicit */ ast_expr_op_fdiv_q(const ast_expr_op_fdiv_q &obj); + inline ast_expr_op_fdiv_q &operator=(ast_expr_op_fdiv_q obj); + inline isl::ctx ctx() const; + +}; + +// declarations for isl::ast_expr_op_ge + +class ast_expr_op_ge : public ast_expr_op { + template + friend bool ast_expr_op::isa() const; + friend ast_expr_op_ge ast_expr_op::as() const; + static const auto type = isl_ast_expr_op_ge; + +protected: + inline explicit ast_expr_op_ge(__isl_take isl_ast_expr *ptr); + +public: + inline /* implicit */ ast_expr_op_ge(); + inline /* implicit */ ast_expr_op_ge(const ast_expr_op_ge &obj); + inline ast_expr_op_ge &operator=(ast_expr_op_ge obj); + inline isl::ctx ctx() const; + +}; + +// declarations for isl::ast_expr_op_gt + +class ast_expr_op_gt : public ast_expr_op { + template + friend bool ast_expr_op::isa() const; + friend ast_expr_op_gt ast_expr_op::as() const; + static const auto type = isl_ast_expr_op_gt; + +protected: + inline explicit ast_expr_op_gt(__isl_take isl_ast_expr *ptr); + +public: + inline /* implicit */ ast_expr_op_gt(); + inline /* implicit */ ast_expr_op_gt(const ast_expr_op_gt &obj); + inline ast_expr_op_gt &operator=(ast_expr_op_gt obj); + inline isl::ctx ctx() const; + +}; + +// declarations for isl::ast_expr_op_le + +class ast_expr_op_le : public ast_expr_op { + template + friend bool ast_expr_op::isa() const; + friend ast_expr_op_le ast_expr_op::as() const; + static const auto type = isl_ast_expr_op_le; + +protected: + inline explicit ast_expr_op_le(__isl_take isl_ast_expr *ptr); + +public: + inline /* implicit */ ast_expr_op_le(); + inline /* implicit */ ast_expr_op_le(const ast_expr_op_le &obj); + inline ast_expr_op_le &operator=(ast_expr_op_le obj); + inline isl::ctx ctx() const; + +}; + +// declarations for isl::ast_expr_op_lt + +class ast_expr_op_lt : public ast_expr_op { + template + friend bool ast_expr_op::isa() const; + friend ast_expr_op_lt ast_expr_op::as() const; + static const auto type = isl_ast_expr_op_lt; + +protected: + inline explicit ast_expr_op_lt(__isl_take isl_ast_expr *ptr); + +public: + inline /* implicit */ ast_expr_op_lt(); + inline /* implicit */ ast_expr_op_lt(const ast_expr_op_lt &obj); + inline ast_expr_op_lt &operator=(ast_expr_op_lt obj); + inline isl::ctx ctx() const; + +}; + +// declarations for isl::ast_expr_op_max + +class ast_expr_op_max : public ast_expr_op { + template + friend bool ast_expr_op::isa() const; + friend ast_expr_op_max ast_expr_op::as() const; + static const auto type = isl_ast_expr_op_max; + +protected: + inline explicit ast_expr_op_max(__isl_take isl_ast_expr *ptr); + +public: + inline /* implicit */ ast_expr_op_max(); + inline /* implicit */ ast_expr_op_max(const ast_expr_op_max &obj); + inline ast_expr_op_max &operator=(ast_expr_op_max obj); + inline isl::ctx ctx() const; + +}; + +// declarations for isl::ast_expr_op_member + +class ast_expr_op_member : public ast_expr_op { + template + friend bool ast_expr_op::isa() const; + friend ast_expr_op_member ast_expr_op::as() const; + static const auto type = isl_ast_expr_op_member; + +protected: + inline explicit ast_expr_op_member(__isl_take isl_ast_expr *ptr); + +public: + inline /* implicit */ ast_expr_op_member(); + inline /* implicit */ ast_expr_op_member(const ast_expr_op_member &obj); + inline ast_expr_op_member &operator=(ast_expr_op_member obj); + inline isl::ctx ctx() const; + +}; + +// declarations for isl::ast_expr_op_min + +class ast_expr_op_min : public ast_expr_op { + template + friend bool ast_expr_op::isa() const; + friend ast_expr_op_min ast_expr_op::as() const; + static const auto type = isl_ast_expr_op_min; + +protected: + inline explicit ast_expr_op_min(__isl_take isl_ast_expr *ptr); + +public: + inline /* implicit */ ast_expr_op_min(); + inline /* implicit */ ast_expr_op_min(const ast_expr_op_min &obj); + inline ast_expr_op_min &operator=(ast_expr_op_min obj); + inline isl::ctx ctx() const; + +}; + +// declarations for isl::ast_expr_op_minus + +class ast_expr_op_minus : public ast_expr_op { + template + friend bool ast_expr_op::isa() const; + friend ast_expr_op_minus ast_expr_op::as() const; + static const auto type = isl_ast_expr_op_minus; + +protected: + inline explicit ast_expr_op_minus(__isl_take isl_ast_expr *ptr); + +public: + inline /* implicit */ ast_expr_op_minus(); + inline /* implicit */ ast_expr_op_minus(const ast_expr_op_minus &obj); + inline ast_expr_op_minus &operator=(ast_expr_op_minus obj); + inline isl::ctx ctx() const; + +}; + +// declarations for isl::ast_expr_op_mul + +class ast_expr_op_mul : public ast_expr_op { + template + friend bool ast_expr_op::isa() const; + friend ast_expr_op_mul ast_expr_op::as() const; + static const auto type = isl_ast_expr_op_mul; + +protected: + inline explicit ast_expr_op_mul(__isl_take isl_ast_expr *ptr); + +public: + inline /* implicit */ ast_expr_op_mul(); + inline /* implicit */ ast_expr_op_mul(const ast_expr_op_mul &obj); + inline ast_expr_op_mul &operator=(ast_expr_op_mul obj); + inline isl::ctx ctx() const; + +}; + +// declarations for isl::ast_expr_op_or + +class ast_expr_op_or : public ast_expr_op { + template + friend bool ast_expr_op::isa() const; + friend ast_expr_op_or ast_expr_op::as() const; + static const auto type = isl_ast_expr_op_or; + +protected: + inline explicit ast_expr_op_or(__isl_take isl_ast_expr *ptr); + +public: + inline /* implicit */ ast_expr_op_or(); + inline /* implicit */ ast_expr_op_or(const ast_expr_op_or &obj); + inline ast_expr_op_or &operator=(ast_expr_op_or obj); + inline isl::ctx ctx() const; + +}; + +// declarations for isl::ast_expr_op_or_else + +class ast_expr_op_or_else : public ast_expr_op { + template + friend bool ast_expr_op::isa() const; + friend ast_expr_op_or_else ast_expr_op::as() const; + static const auto type = isl_ast_expr_op_or_else; + +protected: + inline explicit ast_expr_op_or_else(__isl_take isl_ast_expr *ptr); + +public: + inline /* implicit */ ast_expr_op_or_else(); + inline /* implicit */ ast_expr_op_or_else(const ast_expr_op_or_else &obj); + inline ast_expr_op_or_else &operator=(ast_expr_op_or_else obj); + inline isl::ctx ctx() const; + +}; + +// declarations for isl::ast_expr_op_pdiv_q + +class ast_expr_op_pdiv_q : public ast_expr_op { + template + friend bool ast_expr_op::isa() const; + friend ast_expr_op_pdiv_q ast_expr_op::as() const; + static const auto type = isl_ast_expr_op_pdiv_q; + +protected: + inline explicit ast_expr_op_pdiv_q(__isl_take isl_ast_expr *ptr); + +public: + inline /* implicit */ ast_expr_op_pdiv_q(); + inline /* implicit */ ast_expr_op_pdiv_q(const ast_expr_op_pdiv_q &obj); + inline ast_expr_op_pdiv_q &operator=(ast_expr_op_pdiv_q obj); + inline isl::ctx ctx() const; + +}; + +// declarations for isl::ast_expr_op_pdiv_r + +class ast_expr_op_pdiv_r : public ast_expr_op { + template + friend bool ast_expr_op::isa() const; + friend ast_expr_op_pdiv_r ast_expr_op::as() const; + static const auto type = isl_ast_expr_op_pdiv_r; + +protected: + inline explicit ast_expr_op_pdiv_r(__isl_take isl_ast_expr *ptr); + +public: + inline /* implicit */ ast_expr_op_pdiv_r(); + inline /* implicit */ ast_expr_op_pdiv_r(const ast_expr_op_pdiv_r &obj); + inline ast_expr_op_pdiv_r &operator=(ast_expr_op_pdiv_r obj); + inline isl::ctx ctx() const; + +}; + +// declarations for isl::ast_expr_op_select + +class ast_expr_op_select : public ast_expr_op { + template + friend bool ast_expr_op::isa() const; + friend ast_expr_op_select ast_expr_op::as() const; + static const auto type = isl_ast_expr_op_select; + +protected: + inline explicit ast_expr_op_select(__isl_take isl_ast_expr *ptr); + +public: + inline /* implicit */ ast_expr_op_select(); + inline /* implicit */ ast_expr_op_select(const ast_expr_op_select &obj); + inline ast_expr_op_select &operator=(ast_expr_op_select obj); + inline isl::ctx ctx() const; + +}; + +// declarations for isl::ast_expr_op_sub + +class ast_expr_op_sub : public ast_expr_op { + template + friend bool ast_expr_op::isa() const; + friend ast_expr_op_sub ast_expr_op::as() const; + static const auto type = isl_ast_expr_op_sub; + +protected: + inline explicit ast_expr_op_sub(__isl_take isl_ast_expr *ptr); + +public: + inline /* implicit */ ast_expr_op_sub(); + inline /* implicit */ ast_expr_op_sub(const ast_expr_op_sub &obj); + inline ast_expr_op_sub &operator=(ast_expr_op_sub obj); + inline isl::ctx ctx() const; + +}; + +// declarations for isl::ast_expr_op_zdiv_r + +class ast_expr_op_zdiv_r : public ast_expr_op { + template + friend bool ast_expr_op::isa() const; + friend ast_expr_op_zdiv_r ast_expr_op::as() const; + static const auto type = isl_ast_expr_op_zdiv_r; + +protected: + inline explicit ast_expr_op_zdiv_r(__isl_take isl_ast_expr *ptr); + +public: + inline /* implicit */ ast_expr_op_zdiv_r(); + inline /* implicit */ ast_expr_op_zdiv_r(const ast_expr_op_zdiv_r &obj); + inline ast_expr_op_zdiv_r &operator=(ast_expr_op_zdiv_r obj); + inline isl::ctx ctx() const; + +}; + +// declarations for isl::ast_node +inline ast_node manage(__isl_take isl_ast_node *ptr); +inline ast_node manage_copy(__isl_keep isl_ast_node *ptr); + +class ast_node { + friend inline ast_node manage(__isl_take isl_ast_node *ptr); + friend inline ast_node manage_copy(__isl_keep isl_ast_node *ptr); + +protected: + isl_ast_node *ptr = nullptr; + + inline explicit ast_node(__isl_take isl_ast_node *ptr); + +public: + inline /* implicit */ ast_node(); + inline /* implicit */ ast_node(const ast_node &obj); + inline ast_node &operator=(ast_node obj); + inline ~ast_node(); + inline __isl_give isl_ast_node *copy() const &; + inline __isl_give isl_ast_node *copy() && = delete; + inline __isl_keep isl_ast_node *get() const; + inline __isl_give isl_ast_node *release(); + inline bool is_null() const; +private: + template ::value>::type> + inline bool isa_type(T subtype) const; +public: + template inline bool isa() const; + template inline T as() const; + inline isl::ctx ctx() const; + + inline isl::ast_node map_descendant_bottom_up(const std::function &fn) const; + inline std::string to_C_str() const; + inline isl::ast_node_list to_list() const; +}; + +// declarations for isl::ast_node_block + +class ast_node_block : public ast_node { + template + friend bool ast_node::isa() const; + friend ast_node_block ast_node::as() const; + static const auto type = isl_ast_node_block; + +protected: + inline explicit ast_node_block(__isl_take isl_ast_node *ptr); + +public: + inline /* implicit */ ast_node_block(); + inline /* implicit */ ast_node_block(const ast_node_block &obj); + inline explicit ast_node_block(isl::ast_node_list list); + inline ast_node_block &operator=(ast_node_block obj); + inline isl::ctx ctx() const; + + inline isl::ast_node_list children() const; + inline isl::ast_node_list get_children() const; +}; + +// declarations for isl::ast_node_for + +class ast_node_for : public ast_node { + template + friend bool ast_node::isa() const; + friend ast_node_for ast_node::as() const; + static const auto type = isl_ast_node_for; + +protected: + inline explicit ast_node_for(__isl_take isl_ast_node *ptr); + +public: + inline /* implicit */ ast_node_for(); + inline /* implicit */ ast_node_for(const ast_node_for &obj); + inline ast_node_for &operator=(ast_node_for obj); + inline isl::ctx ctx() const; + + inline isl::ast_node body() const; + inline isl::ast_node get_body() const; + inline isl::ast_expr cond() const; + inline isl::ast_expr get_cond() const; + inline isl::ast_expr inc() const; + inline isl::ast_expr get_inc() const; + inline isl::ast_expr init() const; + inline isl::ast_expr get_init() const; + inline bool is_degenerate() const; + inline isl::ast_expr iterator() const; + inline isl::ast_expr get_iterator() const; +}; + +// declarations for isl::ast_node_if + +class ast_node_if : public ast_node { + template + friend bool ast_node::isa() const; + friend ast_node_if ast_node::as() const; + static const auto type = isl_ast_node_if; + +protected: + inline explicit ast_node_if(__isl_take isl_ast_node *ptr); + +public: + inline /* implicit */ ast_node_if(); + inline /* implicit */ ast_node_if(const ast_node_if &obj); + inline ast_node_if &operator=(ast_node_if obj); + inline isl::ctx ctx() const; + + inline isl::ast_expr cond() const; + inline isl::ast_expr get_cond() const; + inline isl::ast_node else_node() const; + inline isl::ast_node get_else_node() const; + inline bool has_else_node() const; + inline isl::ast_node then_node() const; + inline isl::ast_node get_then_node() const; +}; + +// declarations for isl::ast_node_list +inline ast_node_list manage(__isl_take isl_ast_node_list *ptr); +inline ast_node_list manage_copy(__isl_keep isl_ast_node_list *ptr); + +class ast_node_list { + friend inline ast_node_list manage(__isl_take isl_ast_node_list *ptr); + friend inline ast_node_list manage_copy(__isl_keep isl_ast_node_list *ptr); + +protected: + isl_ast_node_list *ptr = nullptr; + + inline explicit ast_node_list(__isl_take isl_ast_node_list *ptr); + +public: + inline /* implicit */ ast_node_list(); + inline /* implicit */ ast_node_list(const ast_node_list &obj); + inline explicit ast_node_list(isl::ctx ctx, int n); + inline explicit ast_node_list(isl::ast_node el); + inline ast_node_list &operator=(ast_node_list obj); + inline ~ast_node_list(); + inline __isl_give isl_ast_node_list *copy() const &; + inline __isl_give isl_ast_node_list *copy() && = delete; + inline __isl_keep isl_ast_node_list *get() const; + inline __isl_give isl_ast_node_list *release(); + inline bool is_null() const; + inline isl::ctx ctx() const; + + inline isl::ast_node_list add(isl::ast_node el) const; + inline isl::ast_node at(int index) const; + inline isl::ast_node get_at(int index) const; + inline isl::ast_node_list clear() const; + inline isl::ast_node_list concat(isl::ast_node_list list2) const; + inline isl::ast_node_list drop(unsigned int first, unsigned int n) const; + inline void foreach(const std::function &fn) const; + inline void foreach_scc(const std::function &follows, const std::function &fn) const; + inline isl::ast_node_list insert(unsigned int pos, isl::ast_node el) const; + inline isl::ast_node_list set_at(int index, isl::ast_node el) const; + inline unsigned size() const; +}; + +// declarations for isl::ast_node_mark + +class ast_node_mark : public ast_node { + template + friend bool ast_node::isa() const; + friend ast_node_mark ast_node::as() const; + static const auto type = isl_ast_node_mark; + +protected: + inline explicit ast_node_mark(__isl_take isl_ast_node *ptr); + +public: + inline /* implicit */ ast_node_mark(); + inline /* implicit */ ast_node_mark(const ast_node_mark &obj); + inline ast_node_mark &operator=(ast_node_mark obj); + inline isl::ctx ctx() const; + + inline isl::id id() const; + inline isl::id get_id() const; + inline isl::ast_node node() const; + inline isl::ast_node get_node() const; +}; + +// declarations for isl::ast_node_user + +class ast_node_user : public ast_node { + template + friend bool ast_node::isa() const; + friend ast_node_user ast_node::as() const; + static const auto type = isl_ast_node_user; + +protected: + inline explicit ast_node_user(__isl_take isl_ast_node *ptr); + +public: + inline /* implicit */ ast_node_user(); + inline /* implicit */ ast_node_user(const ast_node_user &obj); + inline explicit ast_node_user(isl::ast_expr expr); + inline ast_node_user &operator=(ast_node_user obj); + inline isl::ctx ctx() const; + + inline isl::ast_expr expr() const; + inline isl::ast_expr get_expr() const; +}; + +// declarations for isl::basic_map +inline basic_map manage(__isl_take isl_basic_map *ptr); +inline basic_map manage_copy(__isl_keep isl_basic_map *ptr); + +class basic_map { + friend inline basic_map manage(__isl_take isl_basic_map *ptr); + friend inline basic_map manage_copy(__isl_keep isl_basic_map *ptr); + +protected: + isl_basic_map *ptr = nullptr; + + inline explicit basic_map(__isl_take isl_basic_map *ptr); + +public: + inline /* implicit */ basic_map(); + inline /* implicit */ basic_map(const basic_map &obj); + inline explicit basic_map(isl::ctx ctx, const std::string &str); + inline basic_map &operator=(basic_map obj); + inline ~basic_map(); + inline __isl_give isl_basic_map *copy() const &; + inline __isl_give isl_basic_map *copy() && = delete; + inline __isl_keep isl_basic_map *get() const; + inline __isl_give isl_basic_map *release(); + inline bool is_null() const; + inline isl::ctx ctx() const; + + inline isl::basic_map affine_hull() const; + inline isl::basic_map apply_domain(isl::basic_map bmap2) const; + inline isl::map apply_domain(const isl::map &map2) const; + inline isl::union_map apply_domain(const isl::union_map &umap2) const; + inline isl::basic_map apply_range(isl::basic_map bmap2) const; + inline isl::map apply_range(const isl::map &map2) const; + inline isl::union_map apply_range(const isl::union_map &umap2) const; + inline isl::map as_map() const; + inline isl::multi_union_pw_aff as_multi_union_pw_aff() const; + inline isl::pw_multi_aff as_pw_multi_aff() const; + inline isl::union_pw_multi_aff as_union_pw_multi_aff() const; + inline isl::set bind_domain(const isl::multi_id &tuple) const; + inline isl::set bind_range(const isl::multi_id &tuple) const; + inline isl::map coalesce() const; + inline isl::map complement() const; + inline isl::union_map compute_divs() const; + inline isl::map curry() const; + inline isl::basic_set deltas() const; + inline isl::basic_map detect_equalities() const; + inline isl::set domain() const; + inline isl::map domain_factor_domain() const; + inline isl::map domain_factor_range() const; + inline isl::union_map domain_map() const; + inline isl::union_pw_multi_aff domain_map_union_pw_multi_aff() const; + inline isl::map domain_product(const isl::map &map2) const; + inline isl::union_map domain_product(const isl::union_map &umap2) const; + inline isl::map domain_reverse() const; + inline unsigned domain_tuple_dim() const; + inline isl::id domain_tuple_id() const; + inline isl::map drop_unused_params() const; + inline isl::map eq_at(const isl::multi_pw_aff &mpa) const; + inline isl::union_map eq_at(const isl::multi_union_pw_aff &mupa) const; + inline bool every_map(const std::function &test) const; + inline isl::map extract_map(const isl::space &space) const; + inline isl::map factor_domain() const; + inline isl::map factor_range() const; + inline isl::map fixed_power(const isl::val &exp) const; + inline isl::map fixed_power(long exp) const; + inline isl::basic_map flatten() const; + inline isl::basic_map flatten_domain() const; + inline isl::basic_map flatten_range() const; + inline void foreach_basic_map(const std::function &fn) const; + inline void foreach_map(const std::function &fn) const; + inline isl::basic_map gist(isl::basic_map context) const; + inline isl::map gist(const isl::map &context) const; + inline isl::union_map gist(const isl::union_map &context) const; + inline isl::map gist_domain(const isl::set &context) const; + inline isl::union_map gist_domain(const isl::union_set &uset) const; + inline isl::map gist_params(const isl::set &context) const; + inline isl::union_map gist_range(const isl::union_set &uset) const; + inline bool has_domain_tuple_id() const; + inline bool has_range_tuple_id() const; + inline isl::basic_map intersect(isl::basic_map bmap2) const; + inline isl::map intersect(const isl::map &map2) const; + inline isl::union_map intersect(const isl::union_map &umap2) const; + inline isl::basic_map intersect_domain(isl::basic_set bset) const; + inline isl::map intersect_domain(const isl::set &set) const; + inline isl::union_map intersect_domain(const isl::space &space) const; + inline isl::union_map intersect_domain(const isl::union_set &uset) const; + inline isl::basic_map intersect_domain(const isl::point &bset) const; + inline isl::map intersect_domain_factor_domain(const isl::map &factor) const; + inline isl::union_map intersect_domain_factor_domain(const isl::union_map &factor) const; + inline isl::map intersect_domain_factor_range(const isl::map &factor) const; + inline isl::union_map intersect_domain_factor_range(const isl::union_map &factor) const; + inline isl::map intersect_domain_wrapped_domain(const isl::set &domain) const; + inline isl::union_map intersect_domain_wrapped_domain(const isl::union_set &domain) const; + inline isl::map intersect_params(const isl::set ¶ms) const; + inline isl::basic_map intersect_range(isl::basic_set bset) const; + inline isl::map intersect_range(const isl::set &set) const; + inline isl::union_map intersect_range(const isl::space &space) const; + inline isl::union_map intersect_range(const isl::union_set &uset) const; + inline isl::basic_map intersect_range(const isl::point &bset) const; + inline isl::map intersect_range_factor_domain(const isl::map &factor) const; + inline isl::union_map intersect_range_factor_domain(const isl::union_map &factor) const; + inline isl::map intersect_range_factor_range(const isl::map &factor) const; + inline isl::union_map intersect_range_factor_range(const isl::union_map &factor) const; + inline isl::map intersect_range_wrapped_domain(const isl::set &domain) const; + inline isl::union_map intersect_range_wrapped_domain(const isl::union_set &domain) const; + inline bool is_bijective() const; + inline bool is_disjoint(const isl::map &map2) const; + inline bool is_disjoint(const isl::union_map &umap2) const; + inline bool is_empty() const; + inline bool is_equal(const isl::basic_map &bmap2) const; + inline bool is_equal(const isl::map &map2) const; + inline bool is_equal(const isl::union_map &umap2) const; + inline bool is_injective() const; + inline bool is_single_valued() const; + inline bool is_strict_subset(const isl::map &map2) const; + inline bool is_strict_subset(const isl::union_map &umap2) const; + inline bool is_subset(const isl::basic_map &bmap2) const; + inline bool is_subset(const isl::map &map2) const; + inline bool is_subset(const isl::union_map &umap2) const; + inline bool isa_map() const; + inline isl::map lex_ge_at(const isl::multi_pw_aff &mpa) const; + inline isl::map lex_gt_at(const isl::multi_pw_aff &mpa) const; + inline isl::map lex_le_at(const isl::multi_pw_aff &mpa) const; + inline isl::map lex_lt_at(const isl::multi_pw_aff &mpa) const; + inline isl::map lexmax() const; + inline isl::pw_multi_aff lexmax_pw_multi_aff() const; + inline isl::map lexmin() const; + inline isl::pw_multi_aff lexmin_pw_multi_aff() const; + inline isl::map lower_bound(const isl::multi_pw_aff &lower) const; + inline isl::map_list map_list() const; + inline isl::multi_pw_aff max_multi_pw_aff() const; + inline isl::multi_pw_aff min_multi_pw_aff() const; + inline unsigned n_basic_map() const; + inline isl::set params() const; + inline isl::basic_map polyhedral_hull() const; + inline isl::map preimage_domain(const isl::multi_aff &ma) const; + inline isl::map preimage_domain(const isl::multi_pw_aff &mpa) const; + inline isl::map preimage_domain(const isl::pw_multi_aff &pma) const; + inline isl::union_map preimage_domain(const isl::union_pw_multi_aff &upma) const; + inline isl::map preimage_range(const isl::multi_aff &ma) const; + inline isl::map preimage_range(const isl::pw_multi_aff &pma) const; + inline isl::union_map preimage_range(const isl::union_pw_multi_aff &upma) const; + inline isl::map product(const isl::map &map2) const; + inline isl::union_map product(const isl::union_map &umap2) const; + inline isl::map project_out_all_params() const; + inline isl::map project_out_param(const isl::id &id) const; + inline isl::map project_out_param(const std::string &id) const; + inline isl::map project_out_param(const isl::id_list &list) const; + inline isl::set range() const; + inline isl::map range_factor_domain() const; + inline isl::map range_factor_range() const; + inline isl::fixed_box range_lattice_tile() const; + inline isl::union_map range_map() const; + inline isl::map range_product(const isl::map &map2) const; + inline isl::union_map range_product(const isl::union_map &umap2) const; + inline isl::map range_reverse() const; + inline isl::fixed_box range_simple_fixed_box_hull() const; + inline unsigned range_tuple_dim() const; + inline isl::id range_tuple_id() const; + inline isl::basic_map reverse() const; + inline isl::basic_map sample() const; + inline isl::map set_domain_tuple(const isl::id &id) const; + inline isl::map set_domain_tuple(const std::string &id) const; + inline isl::map set_range_tuple(const isl::id &id) const; + inline isl::map set_range_tuple(const std::string &id) const; + inline isl::space space() const; + inline isl::map subtract(const isl::map &map2) const; + inline isl::union_map subtract(const isl::union_map &umap2) const; + inline isl::union_map subtract_domain(const isl::union_set &dom) const; + inline isl::union_map subtract_range(const isl::union_set &dom) const; + inline isl::map_list to_list() const; + inline isl::union_map to_union_map() const; + inline isl::map uncurry() const; + inline isl::map unite(isl::basic_map bmap2) const; + inline isl::map unite(const isl::map &map2) const; + inline isl::union_map unite(const isl::union_map &umap2) const; + inline isl::basic_map unshifted_simple_hull() const; + inline isl::map upper_bound(const isl::multi_pw_aff &upper) const; + inline isl::set wrap() const; + inline isl::map zip() const; +}; + +// declarations for isl::basic_set +inline basic_set manage(__isl_take isl_basic_set *ptr); +inline basic_set manage_copy(__isl_keep isl_basic_set *ptr); + +class basic_set { + friend inline basic_set manage(__isl_take isl_basic_set *ptr); + friend inline basic_set manage_copy(__isl_keep isl_basic_set *ptr); + +protected: + isl_basic_set *ptr = nullptr; + + inline explicit basic_set(__isl_take isl_basic_set *ptr); + +public: + inline /* implicit */ basic_set(); + inline /* implicit */ basic_set(const basic_set &obj); + inline /* implicit */ basic_set(isl::point pnt); + inline explicit basic_set(isl::ctx ctx, const std::string &str); + inline basic_set &operator=(basic_set obj); + inline ~basic_set(); + inline __isl_give isl_basic_set *copy() const &; + inline __isl_give isl_basic_set *copy() && = delete; + inline __isl_keep isl_basic_set *get() const; + inline __isl_give isl_basic_set *release(); + inline bool is_null() const; + inline isl::ctx ctx() const; + + inline isl::basic_set affine_hull() const; + inline isl::basic_set apply(isl::basic_map bmap) const; + inline isl::set apply(const isl::map &map) const; + inline isl::union_set apply(const isl::union_map &umap) const; + inline isl::pw_multi_aff as_pw_multi_aff() const; + inline isl::set as_set() const; + inline isl::set bind(const isl::multi_id &tuple) const; + inline isl::set coalesce() const; + inline isl::set complement() const; + inline isl::union_set compute_divs() const; + inline isl::basic_set detect_equalities() const; + inline isl::val dim_max_val(int pos) const; + inline isl::val dim_min_val(int pos) const; + inline isl::set drop_unused_params() const; + inline bool every_set(const std::function &test) const; + inline isl::set extract_set(const isl::space &space) const; + inline isl::basic_set flatten() const; + inline void foreach_basic_set(const std::function &fn) const; + inline void foreach_point(const std::function &fn) const; + inline void foreach_set(const std::function &fn) const; + inline isl::basic_set gist(isl::basic_set context) const; + inline isl::set gist(const isl::set &context) const; + inline isl::union_set gist(const isl::union_set &context) const; + inline isl::basic_set gist(const isl::point &context) const; + inline isl::set gist_params(const isl::set &context) const; + inline isl::map identity() const; + inline isl::pw_aff indicator_function() const; + inline isl::map insert_domain(const isl::space &domain) const; + inline isl::basic_set intersect(isl::basic_set bset2) const; + inline isl::set intersect(const isl::set &set2) const; + inline isl::union_set intersect(const isl::union_set &uset2) const; + inline isl::basic_set intersect(const isl::point &bset2) const; + inline isl::basic_set intersect_params(isl::basic_set bset2) const; + inline isl::set intersect_params(const isl::set ¶ms) const; + inline isl::basic_set intersect_params(const isl::point &bset2) const; + inline bool involves_locals() const; + inline bool is_disjoint(const isl::set &set2) const; + inline bool is_disjoint(const isl::union_set &uset2) const; + inline bool is_empty() const; + inline bool is_equal(const isl::basic_set &bset2) const; + inline bool is_equal(const isl::set &set2) const; + inline bool is_equal(const isl::union_set &uset2) const; + inline bool is_equal(const isl::point &bset2) const; + inline bool is_singleton() const; + inline bool is_strict_subset(const isl::set &set2) const; + inline bool is_strict_subset(const isl::union_set &uset2) const; + inline bool is_subset(const isl::basic_set &bset2) const; + inline bool is_subset(const isl::set &set2) const; + inline bool is_subset(const isl::union_set &uset2) const; + inline bool is_subset(const isl::point &bset2) const; + inline bool is_wrapping() const; + inline bool isa_set() const; + inline isl::fixed_box lattice_tile() const; + inline isl::set lexmax() const; + inline isl::pw_multi_aff lexmax_pw_multi_aff() const; + inline isl::set lexmin() const; + inline isl::pw_multi_aff lexmin_pw_multi_aff() const; + inline isl::set lower_bound(const isl::multi_pw_aff &lower) const; + inline isl::set lower_bound(const isl::multi_val &lower) const; + inline isl::multi_pw_aff max_multi_pw_aff() const; + inline isl::val max_val(const isl::aff &obj) const; + inline isl::multi_pw_aff min_multi_pw_aff() const; + inline isl::val min_val(const isl::aff &obj) const; + inline unsigned n_basic_set() const; + inline isl::pw_aff param_pw_aff_on_domain(const isl::id &id) const; + inline isl::pw_aff param_pw_aff_on_domain(const std::string &id) const; + inline isl::basic_set params() const; + inline isl::multi_val plain_multi_val_if_fixed() const; + inline isl::basic_set polyhedral_hull() const; + inline isl::set preimage(const isl::multi_aff &ma) const; + inline isl::set preimage(const isl::multi_pw_aff &mpa) const; + inline isl::set preimage(const isl::pw_multi_aff &pma) const; + inline isl::union_set preimage(const isl::union_pw_multi_aff &upma) const; + inline isl::set product(const isl::set &set2) const; + inline isl::set project_out_all_params() const; + inline isl::set project_out_param(const isl::id &id) const; + inline isl::set project_out_param(const std::string &id) const; + inline isl::set project_out_param(const isl::id_list &list) const; + inline isl::pw_aff pw_aff_on_domain(const isl::val &v) const; + inline isl::pw_aff pw_aff_on_domain(long v) const; + inline isl::pw_multi_aff pw_multi_aff_on_domain(const isl::multi_val &mv) const; + inline isl::basic_set sample() const; + inline isl::point sample_point() const; + inline isl::set_list set_list() const; + inline isl::fixed_box simple_fixed_box_hull() const; + inline isl::space space() const; + inline isl::val stride(int pos) const; + inline isl::set subtract(const isl::set &set2) const; + inline isl::union_set subtract(const isl::union_set &uset2) const; + inline isl::set_list to_list() const; + inline isl::set to_set() const; + inline isl::union_set to_union_set() const; + inline isl::map translation() const; + inline unsigned tuple_dim() const; + inline isl::set unbind_params(const isl::multi_id &tuple) const; + inline isl::map unbind_params_insert_domain(const isl::multi_id &domain) const; + inline isl::set unite(isl::basic_set bset2) const; + inline isl::set unite(const isl::set &set2) const; + inline isl::union_set unite(const isl::union_set &uset2) const; + inline isl::set unite(const isl::point &bset2) const; + inline isl::basic_set unshifted_simple_hull() const; + inline isl::map unwrap() const; + inline isl::set upper_bound(const isl::multi_pw_aff &upper) const; + inline isl::set upper_bound(const isl::multi_val &upper) const; + inline isl::set wrapped_reverse() const; +}; + +// declarations for isl::fixed_box +inline fixed_box manage(__isl_take isl_fixed_box *ptr); +inline fixed_box manage_copy(__isl_keep isl_fixed_box *ptr); + +class fixed_box { + friend inline fixed_box manage(__isl_take isl_fixed_box *ptr); + friend inline fixed_box manage_copy(__isl_keep isl_fixed_box *ptr); + +protected: + isl_fixed_box *ptr = nullptr; + + inline explicit fixed_box(__isl_take isl_fixed_box *ptr); + +public: + inline /* implicit */ fixed_box(); + inline /* implicit */ fixed_box(const fixed_box &obj); + inline explicit fixed_box(isl::ctx ctx, const std::string &str); + inline fixed_box &operator=(fixed_box obj); + inline ~fixed_box(); + inline __isl_give isl_fixed_box *copy() const &; + inline __isl_give isl_fixed_box *copy() && = delete; + inline __isl_keep isl_fixed_box *get() const; + inline __isl_give isl_fixed_box *release(); + inline bool is_null() const; + inline isl::ctx ctx() const; + + inline bool is_valid() const; + inline isl::multi_aff offset() const; + inline isl::multi_aff get_offset() const; + inline isl::multi_val size() const; + inline isl::multi_val get_size() const; + inline isl::space space() const; + inline isl::space get_space() const; +}; + +// declarations for isl::id +inline id manage(__isl_take isl_id *ptr); +inline id manage_copy(__isl_keep isl_id *ptr); + +class id { + friend inline id manage(__isl_take isl_id *ptr); + friend inline id manage_copy(__isl_keep isl_id *ptr); + +protected: + isl_id *ptr = nullptr; + + inline explicit id(__isl_take isl_id *ptr); + +public: + inline /* implicit */ id(); + inline /* implicit */ id(const id &obj); + inline explicit id(isl::ctx ctx, const std::string &str); + inline id &operator=(id obj); + inline ~id(); + inline __isl_give isl_id *copy() const &; + inline __isl_give isl_id *copy() && = delete; + inline __isl_keep isl_id *get() const; + inline __isl_give isl_id *release(); + inline bool is_null() const; + inline isl::ctx ctx() const; + + inline std::string name() const; + inline std::string get_name() const; + inline isl::id_list to_list() const; + +#if __cplusplus >= 201703L + inline explicit id(isl::ctx ctx, const std::string &str, const std::any &any); + template + std::optional try_user() const; + template + T user() const; +#endif +}; + +// declarations for isl::id_list +inline id_list manage(__isl_take isl_id_list *ptr); +inline id_list manage_copy(__isl_keep isl_id_list *ptr); + +class id_list { + friend inline id_list manage(__isl_take isl_id_list *ptr); + friend inline id_list manage_copy(__isl_keep isl_id_list *ptr); + +protected: + isl_id_list *ptr = nullptr; + + inline explicit id_list(__isl_take isl_id_list *ptr); + +public: + inline /* implicit */ id_list(); + inline /* implicit */ id_list(const id_list &obj); + inline explicit id_list(isl::ctx ctx, int n); + inline explicit id_list(isl::id el); + inline explicit id_list(isl::ctx ctx, const std::string &str); + inline id_list &operator=(id_list obj); + inline ~id_list(); + inline __isl_give isl_id_list *copy() const &; + inline __isl_give isl_id_list *copy() && = delete; + inline __isl_keep isl_id_list *get() const; + inline __isl_give isl_id_list *release(); + inline bool is_null() const; + inline isl::ctx ctx() const; + + inline isl::id_list add(isl::id el) const; + inline isl::id_list add(const std::string &el) const; + inline isl::id at(int index) const; + inline isl::id get_at(int index) const; + inline isl::id_list clear() const; + inline isl::id_list concat(isl::id_list list2) const; + inline isl::id_list drop(unsigned int first, unsigned int n) const; + inline void foreach(const std::function &fn) const; + inline void foreach_scc(const std::function &follows, const std::function &fn) const; + inline isl::id_list insert(unsigned int pos, isl::id el) const; + inline isl::id_list insert(unsigned int pos, const std::string &el) const; + inline isl::id_list set_at(int index, isl::id el) const; + inline isl::id_list set_at(int index, const std::string &el) const; + inline unsigned size() const; +}; + +// declarations for isl::id_to_ast_expr +inline id_to_ast_expr manage(__isl_take isl_id_to_ast_expr *ptr); +inline id_to_ast_expr manage_copy(__isl_keep isl_id_to_ast_expr *ptr); + +class id_to_ast_expr { + friend inline id_to_ast_expr manage(__isl_take isl_id_to_ast_expr *ptr); + friend inline id_to_ast_expr manage_copy(__isl_keep isl_id_to_ast_expr *ptr); + +protected: + isl_id_to_ast_expr *ptr = nullptr; + + inline explicit id_to_ast_expr(__isl_take isl_id_to_ast_expr *ptr); + +public: + inline /* implicit */ id_to_ast_expr(); + inline /* implicit */ id_to_ast_expr(const id_to_ast_expr &obj); + inline explicit id_to_ast_expr(isl::ctx ctx, int min_size); + inline explicit id_to_ast_expr(isl::ctx ctx, const std::string &str); + inline id_to_ast_expr &operator=(id_to_ast_expr obj); + inline ~id_to_ast_expr(); + inline __isl_give isl_id_to_ast_expr *copy() const &; + inline __isl_give isl_id_to_ast_expr *copy() && = delete; + inline __isl_keep isl_id_to_ast_expr *get() const; + inline __isl_give isl_id_to_ast_expr *release(); + inline bool is_null() const; + inline isl::ctx ctx() const; + + inline bool is_equal(const isl::id_to_ast_expr &hmap2) const; + inline isl::id_to_ast_expr set(isl::id key, isl::ast_expr val) const; + inline isl::id_to_ast_expr set(const std::string &key, const isl::ast_expr &val) const; +}; + +// declarations for isl::id_to_id +inline id_to_id manage(__isl_take isl_id_to_id *ptr); +inline id_to_id manage_copy(__isl_keep isl_id_to_id *ptr); + +class id_to_id { + friend inline id_to_id manage(__isl_take isl_id_to_id *ptr); + friend inline id_to_id manage_copy(__isl_keep isl_id_to_id *ptr); + +protected: + isl_id_to_id *ptr = nullptr; + + inline explicit id_to_id(__isl_take isl_id_to_id *ptr); + +public: + inline /* implicit */ id_to_id(); + inline /* implicit */ id_to_id(const id_to_id &obj); + inline explicit id_to_id(isl::ctx ctx, int min_size); + inline explicit id_to_id(isl::ctx ctx, const std::string &str); + inline id_to_id &operator=(id_to_id obj); + inline ~id_to_id(); + inline __isl_give isl_id_to_id *copy() const &; + inline __isl_give isl_id_to_id *copy() && = delete; + inline __isl_keep isl_id_to_id *get() const; + inline __isl_give isl_id_to_id *release(); + inline bool is_null() const; + inline isl::ctx ctx() const; + + inline bool is_equal(const isl::id_to_id &hmap2) const; + inline isl::id_to_id set(isl::id key, isl::id val) const; + inline isl::id_to_id set(const isl::id &key, const std::string &val) const; + inline isl::id_to_id set(const std::string &key, const isl::id &val) const; + inline isl::id_to_id set(const std::string &key, const std::string &val) const; +}; + +// declarations for isl::map +inline map manage(__isl_take isl_map *ptr); +inline map manage_copy(__isl_keep isl_map *ptr); + +class map { + friend inline map manage(__isl_take isl_map *ptr); + friend inline map manage_copy(__isl_keep isl_map *ptr); + +protected: + isl_map *ptr = nullptr; + + inline explicit map(__isl_take isl_map *ptr); + +public: + inline /* implicit */ map(); + inline /* implicit */ map(const map &obj); + inline /* implicit */ map(isl::basic_map bmap); + inline explicit map(isl::ctx ctx, const std::string &str); + inline map &operator=(map obj); + inline ~map(); + inline __isl_give isl_map *copy() const &; + inline __isl_give isl_map *copy() && = delete; + inline __isl_keep isl_map *get() const; + inline __isl_give isl_map *release(); + inline bool is_null() const; + inline isl::ctx ctx() const; + + inline isl::basic_map affine_hull() const; + inline isl::map apply_domain(isl::map map2) const; + inline isl::union_map apply_domain(const isl::union_map &umap2) const; + inline isl::map apply_domain(const isl::basic_map &map2) const; + inline isl::map apply_range(isl::map map2) const; + inline isl::union_map apply_range(const isl::union_map &umap2) const; + inline isl::map apply_range(const isl::basic_map &map2) const; + inline isl::map as_map() const; + inline isl::multi_union_pw_aff as_multi_union_pw_aff() const; + inline isl::pw_multi_aff as_pw_multi_aff() const; + inline isl::union_pw_multi_aff as_union_pw_multi_aff() const; + inline isl::set bind_domain(isl::multi_id tuple) const; + inline isl::set bind_range(isl::multi_id tuple) const; + inline isl::map coalesce() const; + inline isl::map complement() const; + inline isl::union_map compute_divs() const; + inline isl::map curry() const; + inline isl::set deltas() const; + inline isl::map detect_equalities() const; + inline isl::set domain() const; + inline isl::map domain_factor_domain() const; + inline isl::map domain_factor_range() const; + inline isl::union_map domain_map() const; + inline isl::union_pw_multi_aff domain_map_union_pw_multi_aff() const; + inline isl::map domain_product(isl::map map2) const; + inline isl::union_map domain_product(const isl::union_map &umap2) const; + inline isl::map domain_product(const isl::basic_map &map2) const; + inline isl::map domain_reverse() const; + inline unsigned domain_tuple_dim() const; + inline isl::id domain_tuple_id() const; + inline isl::id get_domain_tuple_id() const; + inline isl::map drop_unused_params() const; + static inline isl::map empty(isl::space space); + inline isl::map eq_at(isl::multi_pw_aff mpa) const; + inline isl::union_map eq_at(const isl::multi_union_pw_aff &mupa) const; + inline isl::map eq_at(const isl::aff &mpa) const; + inline isl::map eq_at(const isl::multi_aff &mpa) const; + inline isl::map eq_at(const isl::pw_aff &mpa) const; + inline isl::map eq_at(const isl::pw_multi_aff &mpa) const; + inline bool every_map(const std::function &test) const; + inline isl::map extract_map(const isl::space &space) const; + inline isl::map factor_domain() const; + inline isl::map factor_range() const; + inline isl::map fixed_power(isl::val exp) const; + inline isl::map fixed_power(long exp) const; + inline isl::map flatten() const; + inline isl::map flatten_domain() const; + inline isl::map flatten_range() const; + inline void foreach_basic_map(const std::function &fn) const; + inline void foreach_map(const std::function &fn) const; + inline isl::map gist(isl::map context) const; + inline isl::union_map gist(const isl::union_map &context) const; + inline isl::map gist(const isl::basic_map &context) const; + inline isl::map gist_domain(isl::set context) const; + inline isl::union_map gist_domain(const isl::union_set &uset) const; + inline isl::map gist_domain(const isl::basic_set &context) const; + inline isl::map gist_domain(const isl::point &context) const; + inline isl::map gist_params(isl::set context) const; + inline isl::union_map gist_range(const isl::union_set &uset) const; + inline bool has_domain_tuple_id() const; + inline bool has_range_tuple_id() const; + inline isl::map intersect(isl::map map2) const; + inline isl::union_map intersect(const isl::union_map &umap2) const; + inline isl::map intersect(const isl::basic_map &map2) const; + inline isl::map intersect_domain(isl::set set) const; + inline isl::union_map intersect_domain(const isl::space &space) const; + inline isl::union_map intersect_domain(const isl::union_set &uset) const; + inline isl::map intersect_domain(const isl::basic_set &set) const; + inline isl::map intersect_domain(const isl::point &set) const; + inline isl::map intersect_domain_factor_domain(isl::map factor) const; + inline isl::union_map intersect_domain_factor_domain(const isl::union_map &factor) const; + inline isl::map intersect_domain_factor_domain(const isl::basic_map &factor) const; + inline isl::map intersect_domain_factor_range(isl::map factor) const; + inline isl::union_map intersect_domain_factor_range(const isl::union_map &factor) const; + inline isl::map intersect_domain_factor_range(const isl::basic_map &factor) const; + inline isl::map intersect_domain_wrapped_domain(isl::set domain) const; + inline isl::union_map intersect_domain_wrapped_domain(const isl::union_set &domain) const; + inline isl::map intersect_domain_wrapped_domain(const isl::basic_set &domain) const; + inline isl::map intersect_domain_wrapped_domain(const isl::point &domain) const; + inline isl::map intersect_params(isl::set params) const; + inline isl::map intersect_range(isl::set set) const; + inline isl::union_map intersect_range(const isl::space &space) const; + inline isl::union_map intersect_range(const isl::union_set &uset) const; + inline isl::map intersect_range(const isl::basic_set &set) const; + inline isl::map intersect_range(const isl::point &set) const; + inline isl::map intersect_range_factor_domain(isl::map factor) const; + inline isl::union_map intersect_range_factor_domain(const isl::union_map &factor) const; + inline isl::map intersect_range_factor_domain(const isl::basic_map &factor) const; + inline isl::map intersect_range_factor_range(isl::map factor) const; + inline isl::union_map intersect_range_factor_range(const isl::union_map &factor) const; + inline isl::map intersect_range_factor_range(const isl::basic_map &factor) const; + inline isl::map intersect_range_wrapped_domain(isl::set domain) const; + inline isl::union_map intersect_range_wrapped_domain(const isl::union_set &domain) const; + inline isl::map intersect_range_wrapped_domain(const isl::basic_set &domain) const; + inline isl::map intersect_range_wrapped_domain(const isl::point &domain) const; + inline bool is_bijective() const; + inline bool is_disjoint(const isl::map &map2) const; + inline bool is_disjoint(const isl::union_map &umap2) const; + inline bool is_disjoint(const isl::basic_map &map2) const; + inline bool is_empty() const; + inline bool is_equal(const isl::map &map2) const; + inline bool is_equal(const isl::union_map &umap2) const; + inline bool is_equal(const isl::basic_map &map2) const; + inline bool is_injective() const; + inline bool is_single_valued() const; + inline bool is_strict_subset(const isl::map &map2) const; + inline bool is_strict_subset(const isl::union_map &umap2) const; + inline bool is_strict_subset(const isl::basic_map &map2) const; + inline bool is_subset(const isl::map &map2) const; + inline bool is_subset(const isl::union_map &umap2) const; + inline bool is_subset(const isl::basic_map &map2) const; + inline bool isa_map() const; + inline isl::map lex_ge_at(isl::multi_pw_aff mpa) const; + inline isl::map lex_gt_at(isl::multi_pw_aff mpa) const; + inline isl::map lex_le_at(isl::multi_pw_aff mpa) const; + inline isl::map lex_lt_at(isl::multi_pw_aff mpa) const; + inline isl::map lexmax() const; + inline isl::pw_multi_aff lexmax_pw_multi_aff() const; + inline isl::map lexmin() const; + inline isl::pw_multi_aff lexmin_pw_multi_aff() const; + inline isl::map lower_bound(isl::multi_pw_aff lower) const; + inline isl::map_list map_list() const; + inline isl::multi_pw_aff max_multi_pw_aff() const; + inline isl::multi_pw_aff min_multi_pw_aff() const; + inline unsigned n_basic_map() const; + inline isl::set params() const; + inline isl::basic_map polyhedral_hull() const; + inline isl::map preimage_domain(isl::multi_aff ma) const; + inline isl::map preimage_domain(isl::multi_pw_aff mpa) const; + inline isl::map preimage_domain(isl::pw_multi_aff pma) const; + inline isl::union_map preimage_domain(const isl::union_pw_multi_aff &upma) const; + inline isl::map preimage_range(isl::multi_aff ma) const; + inline isl::map preimage_range(isl::pw_multi_aff pma) const; + inline isl::union_map preimage_range(const isl::union_pw_multi_aff &upma) const; + inline isl::map product(isl::map map2) const; + inline isl::union_map product(const isl::union_map &umap2) const; + inline isl::map product(const isl::basic_map &map2) const; + inline isl::map project_out_all_params() const; + inline isl::map project_out_param(isl::id id) const; + inline isl::map project_out_param(const std::string &id) const; + inline isl::map project_out_param(isl::id_list list) const; + inline isl::set range() const; + inline isl::map range_factor_domain() const; + inline isl::map range_factor_range() const; + inline isl::fixed_box range_lattice_tile() const; + inline isl::fixed_box get_range_lattice_tile() const; + inline isl::union_map range_map() const; + inline isl::map range_product(isl::map map2) const; + inline isl::union_map range_product(const isl::union_map &umap2) const; + inline isl::map range_product(const isl::basic_map &map2) const; + inline isl::map range_reverse() const; + inline isl::fixed_box range_simple_fixed_box_hull() const; + inline isl::fixed_box get_range_simple_fixed_box_hull() const; + inline unsigned range_tuple_dim() const; + inline isl::id range_tuple_id() const; + inline isl::id get_range_tuple_id() const; + inline isl::map reverse() const; + inline isl::basic_map sample() const; + inline isl::map set_domain_tuple(isl::id id) const; + inline isl::map set_domain_tuple(const std::string &id) const; + inline isl::map set_range_tuple(isl::id id) const; + inline isl::map set_range_tuple(const std::string &id) const; + inline isl::space space() const; + inline isl::space get_space() const; + inline isl::map subtract(isl::map map2) const; + inline isl::union_map subtract(const isl::union_map &umap2) const; + inline isl::map subtract(const isl::basic_map &map2) const; + inline isl::union_map subtract_domain(const isl::union_set &dom) const; + inline isl::union_map subtract_range(const isl::union_set &dom) const; + inline isl::map_list to_list() const; + inline isl::union_map to_union_map() const; + inline isl::map uncurry() const; + inline isl::map unite(isl::map map2) const; + inline isl::union_map unite(const isl::union_map &umap2) const; + inline isl::map unite(const isl::basic_map &map2) const; + static inline isl::map universe(isl::space space); + inline isl::basic_map unshifted_simple_hull() const; + inline isl::map upper_bound(isl::multi_pw_aff upper) const; + inline isl::set wrap() const; + inline isl::map zip() const; +}; + +// declarations for isl::map_list +inline map_list manage(__isl_take isl_map_list *ptr); +inline map_list manage_copy(__isl_keep isl_map_list *ptr); + +class map_list { + friend inline map_list manage(__isl_take isl_map_list *ptr); + friend inline map_list manage_copy(__isl_keep isl_map_list *ptr); + +protected: + isl_map_list *ptr = nullptr; + + inline explicit map_list(__isl_take isl_map_list *ptr); + +public: + inline /* implicit */ map_list(); + inline /* implicit */ map_list(const map_list &obj); + inline explicit map_list(isl::ctx ctx, int n); + inline explicit map_list(isl::map el); + inline explicit map_list(isl::ctx ctx, const std::string &str); + inline map_list &operator=(map_list obj); + inline ~map_list(); + inline __isl_give isl_map_list *copy() const &; + inline __isl_give isl_map_list *copy() && = delete; + inline __isl_keep isl_map_list *get() const; + inline __isl_give isl_map_list *release(); + inline bool is_null() const; + inline isl::ctx ctx() const; + + inline isl::map_list add(isl::map el) const; + inline isl::map at(int index) const; + inline isl::map get_at(int index) const; + inline isl::map_list clear() const; + inline isl::map_list concat(isl::map_list list2) const; + inline isl::map_list drop(unsigned int first, unsigned int n) const; + inline void foreach(const std::function &fn) const; + inline void foreach_scc(const std::function &follows, const std::function &fn) const; + inline isl::map_list insert(unsigned int pos, isl::map el) const; + inline isl::map_list set_at(int index, isl::map el) const; + inline unsigned size() const; +}; + +// declarations for isl::multi_aff +inline multi_aff manage(__isl_take isl_multi_aff *ptr); +inline multi_aff manage_copy(__isl_keep isl_multi_aff *ptr); + +class multi_aff { + friend inline multi_aff manage(__isl_take isl_multi_aff *ptr); + friend inline multi_aff manage_copy(__isl_keep isl_multi_aff *ptr); + +protected: + isl_multi_aff *ptr = nullptr; + + inline explicit multi_aff(__isl_take isl_multi_aff *ptr); + +public: + inline /* implicit */ multi_aff(); + inline /* implicit */ multi_aff(const multi_aff &obj); + inline /* implicit */ multi_aff(isl::aff aff); + inline explicit multi_aff(isl::space space, isl::aff_list list); + inline explicit multi_aff(isl::ctx ctx, const std::string &str); + inline multi_aff &operator=(multi_aff obj); + inline ~multi_aff(); + inline __isl_give isl_multi_aff *copy() const &; + inline __isl_give isl_multi_aff *copy() && = delete; + inline __isl_keep isl_multi_aff *get() const; + inline __isl_give isl_multi_aff *release(); + inline bool is_null() const; + inline isl::ctx ctx() const; + + inline isl::multi_aff add(isl::multi_aff multi2) const; + inline isl::multi_pw_aff add(const isl::multi_pw_aff &multi2) const; + inline isl::multi_union_pw_aff add(const isl::multi_union_pw_aff &multi2) const; + inline isl::pw_multi_aff add(const isl::pw_multi_aff &pma2) const; + inline isl::union_pw_multi_aff add(const isl::union_pw_multi_aff &upma2) const; + inline isl::multi_aff add(const isl::aff &multi2) const; + inline isl::multi_aff add_constant(isl::multi_val mv) const; + inline isl::multi_aff add_constant(isl::val v) const; + inline isl::multi_aff add_constant(long v) const; + inline isl::union_pw_multi_aff apply(const isl::union_pw_multi_aff &upma2) const; + inline isl::map as_map() const; + inline isl::multi_aff as_multi_aff() const; + inline isl::multi_union_pw_aff as_multi_union_pw_aff() const; + inline isl::pw_multi_aff as_pw_multi_aff() const; + inline isl::set as_set() const; + inline isl::union_map as_union_map() const; + inline isl::aff at(int pos) const; + inline isl::aff get_at(int pos) const; + inline isl::basic_set bind(isl::multi_id tuple) const; + inline isl::multi_aff bind_domain(isl::multi_id tuple) const; + inline isl::multi_aff bind_domain_wrapped_domain(isl::multi_id tuple) const; + inline isl::pw_multi_aff coalesce() const; + inline isl::multi_val constant_multi_val() const; + inline isl::multi_val get_constant_multi_val() const; + inline isl::set domain() const; + static inline isl::multi_aff domain_map(isl::space space); + inline isl::multi_aff domain_reverse() const; + inline isl::pw_multi_aff drop_unused_params() const; + inline isl::pw_multi_aff extract_pw_multi_aff(const isl::space &space) const; + inline isl::multi_aff flat_range_product(isl::multi_aff multi2) const; + inline isl::multi_pw_aff flat_range_product(const isl::multi_pw_aff &multi2) const; + inline isl::multi_union_pw_aff flat_range_product(const isl::multi_union_pw_aff &multi2) const; + inline isl::pw_multi_aff flat_range_product(const isl::pw_multi_aff &pma2) const; + inline isl::union_pw_multi_aff flat_range_product(const isl::union_pw_multi_aff &upma2) const; + inline isl::multi_aff flat_range_product(const isl::aff &multi2) const; + inline isl::multi_aff floor() const; + inline void foreach_piece(const std::function &fn) const; + inline isl::multi_aff gist(isl::set context) const; + inline isl::union_pw_multi_aff gist(const isl::union_set &context) const; + inline isl::multi_aff gist(const isl::basic_set &context) const; + inline isl::multi_aff gist(const isl::point &context) const; + inline isl::multi_aff gist_params(isl::set context) const; + inline bool has_range_tuple_id() const; + inline isl::multi_aff identity() const; + static inline isl::multi_aff identity_on_domain(isl::space space); + inline isl::multi_aff insert_domain(isl::space domain) const; + inline isl::pw_multi_aff intersect_domain(const isl::set &set) const; + inline isl::union_pw_multi_aff intersect_domain(const isl::space &space) const; + inline isl::union_pw_multi_aff intersect_domain(const isl::union_set &uset) const; + inline isl::union_pw_multi_aff intersect_domain_wrapped_domain(const isl::union_set &uset) const; + inline isl::union_pw_multi_aff intersect_domain_wrapped_range(const isl::union_set &uset) const; + inline isl::pw_multi_aff intersect_params(const isl::set &set) const; + inline bool involves_locals() const; + inline bool involves_nan() const; + inline bool involves_param(const isl::id &id) const; + inline bool involves_param(const std::string &id) const; + inline bool involves_param(const isl::id_list &list) const; + inline bool isa_multi_aff() const; + inline bool isa_pw_multi_aff() const; + inline isl::aff_list list() const; + inline isl::aff_list get_list() const; + inline isl::multi_pw_aff max(const isl::multi_pw_aff &multi2) const; + inline isl::multi_val max_multi_val() const; + inline isl::multi_pw_aff min(const isl::multi_pw_aff &multi2) const; + inline isl::multi_val min_multi_val() const; + static inline isl::multi_aff multi_val_on_domain(isl::space space, isl::multi_val mv); + inline unsigned n_piece() const; + inline isl::multi_aff neg() const; + inline bool plain_is_empty() const; + inline bool plain_is_equal(const isl::multi_aff &multi2) const; + inline bool plain_is_equal(const isl::multi_pw_aff &multi2) const; + inline bool plain_is_equal(const isl::multi_union_pw_aff &multi2) const; + inline bool plain_is_equal(const isl::pw_multi_aff &pma2) const; + inline bool plain_is_equal(const isl::union_pw_multi_aff &upma2) const; + inline bool plain_is_equal(const isl::aff &multi2) const; + inline isl::pw_multi_aff preimage_domain_wrapped_domain(const isl::pw_multi_aff &pma2) const; + inline isl::union_pw_multi_aff preimage_domain_wrapped_domain(const isl::union_pw_multi_aff &upma2) const; + inline isl::multi_aff product(isl::multi_aff multi2) const; + inline isl::multi_pw_aff product(const isl::multi_pw_aff &multi2) const; + inline isl::pw_multi_aff product(const isl::pw_multi_aff &pma2) const; + inline isl::multi_aff product(const isl::aff &multi2) const; + inline isl::multi_aff pullback(isl::multi_aff ma2) const; + inline isl::multi_pw_aff pullback(const isl::multi_pw_aff &mpa2) const; + inline isl::pw_multi_aff pullback(const isl::pw_multi_aff &pma2) const; + inline isl::union_pw_multi_aff pullback(const isl::union_pw_multi_aff &upma2) const; + inline isl::multi_aff pullback(const isl::aff &ma2) const; + inline isl::pw_multi_aff_list pw_multi_aff_list() const; + inline isl::pw_multi_aff range_factor_domain() const; + inline isl::pw_multi_aff range_factor_range() const; + static inline isl::multi_aff range_map(isl::space space); + inline isl::multi_aff range_product(isl::multi_aff multi2) const; + inline isl::multi_pw_aff range_product(const isl::multi_pw_aff &multi2) const; + inline isl::multi_union_pw_aff range_product(const isl::multi_union_pw_aff &multi2) const; + inline isl::pw_multi_aff range_product(const isl::pw_multi_aff &pma2) const; + inline isl::union_pw_multi_aff range_product(const isl::union_pw_multi_aff &upma2) const; + inline isl::multi_aff range_product(const isl::aff &multi2) const; + inline isl::id range_tuple_id() const; + inline isl::id get_range_tuple_id() const; + inline isl::multi_aff reset_range_tuple_id() const; + inline isl::multi_aff scale(isl::multi_val mv) const; + inline isl::multi_aff scale(isl::val v) const; + inline isl::multi_aff scale(long v) const; + inline isl::multi_aff scale_down(isl::multi_val mv) const; + inline isl::multi_aff scale_down(isl::val v) const; + inline isl::multi_aff scale_down(long v) const; + inline isl::multi_aff set_at(int pos, isl::aff el) const; + inline isl::multi_pw_aff set_at(int pos, const isl::pw_aff &el) const; + inline isl::multi_union_pw_aff set_at(int pos, const isl::union_pw_aff &el) const; + inline isl::multi_aff set_range_tuple(isl::id id) const; + inline isl::multi_aff set_range_tuple(const std::string &id) const; + inline unsigned size() const; + inline isl::space space() const; + inline isl::space get_space() const; + inline isl::multi_aff sub(isl::multi_aff multi2) const; + inline isl::multi_pw_aff sub(const isl::multi_pw_aff &multi2) const; + inline isl::multi_union_pw_aff sub(const isl::multi_union_pw_aff &multi2) const; + inline isl::pw_multi_aff sub(const isl::pw_multi_aff &pma2) const; + inline isl::union_pw_multi_aff sub(const isl::union_pw_multi_aff &upma2) const; + inline isl::multi_aff sub(const isl::aff &multi2) const; + inline isl::pw_multi_aff subtract_domain(const isl::set &set) const; + inline isl::union_pw_multi_aff subtract_domain(const isl::space &space) const; + inline isl::union_pw_multi_aff subtract_domain(const isl::union_set &uset) const; + inline isl::pw_multi_aff_list to_list() const; + inline isl::multi_pw_aff to_multi_pw_aff() const; + inline isl::multi_union_pw_aff to_multi_union_pw_aff() const; + inline isl::pw_multi_aff to_pw_multi_aff() const; + inline isl::union_pw_multi_aff to_union_pw_multi_aff() const; + inline isl::multi_aff unbind_params_insert_domain(isl::multi_id domain) const; + inline isl::multi_pw_aff union_add(const isl::multi_pw_aff &mpa2) const; + inline isl::multi_union_pw_aff union_add(const isl::multi_union_pw_aff &mupa2) const; + inline isl::pw_multi_aff union_add(const isl::pw_multi_aff &pma2) const; + inline isl::union_pw_multi_aff union_add(const isl::union_pw_multi_aff &upma2) const; + static inline isl::multi_aff zero(isl::space space); +}; + +// declarations for isl::multi_id +inline multi_id manage(__isl_take isl_multi_id *ptr); +inline multi_id manage_copy(__isl_keep isl_multi_id *ptr); + +class multi_id { + friend inline multi_id manage(__isl_take isl_multi_id *ptr); + friend inline multi_id manage_copy(__isl_keep isl_multi_id *ptr); + +protected: + isl_multi_id *ptr = nullptr; + + inline explicit multi_id(__isl_take isl_multi_id *ptr); + +public: + inline /* implicit */ multi_id(); + inline /* implicit */ multi_id(const multi_id &obj); + inline explicit multi_id(isl::space space, isl::id_list list); + inline explicit multi_id(isl::ctx ctx, const std::string &str); + inline multi_id &operator=(multi_id obj); + inline ~multi_id(); + inline __isl_give isl_multi_id *copy() const &; + inline __isl_give isl_multi_id *copy() && = delete; + inline __isl_keep isl_multi_id *get() const; + inline __isl_give isl_multi_id *release(); + inline bool is_null() const; + inline isl::ctx ctx() const; + + inline isl::id at(int pos) const; + inline isl::id get_at(int pos) const; + inline isl::multi_id flat_range_product(isl::multi_id multi2) const; + inline isl::id_list list() const; + inline isl::id_list get_list() const; + inline bool plain_is_equal(const isl::multi_id &multi2) const; + inline isl::multi_id range_product(isl::multi_id multi2) const; + inline isl::multi_id set_at(int pos, isl::id el) const; + inline isl::multi_id set_at(int pos, const std::string &el) const; + inline unsigned size() const; + inline isl::space space() const; + inline isl::space get_space() const; +}; + +// declarations for isl::multi_pw_aff +inline multi_pw_aff manage(__isl_take isl_multi_pw_aff *ptr); +inline multi_pw_aff manage_copy(__isl_keep isl_multi_pw_aff *ptr); + +class multi_pw_aff { + friend inline multi_pw_aff manage(__isl_take isl_multi_pw_aff *ptr); + friend inline multi_pw_aff manage_copy(__isl_keep isl_multi_pw_aff *ptr); + +protected: + isl_multi_pw_aff *ptr = nullptr; + + inline explicit multi_pw_aff(__isl_take isl_multi_pw_aff *ptr); + +public: + inline /* implicit */ multi_pw_aff(); + inline /* implicit */ multi_pw_aff(const multi_pw_aff &obj); + inline /* implicit */ multi_pw_aff(isl::aff aff); + inline /* implicit */ multi_pw_aff(isl::multi_aff ma); + inline /* implicit */ multi_pw_aff(isl::pw_aff pa); + inline explicit multi_pw_aff(isl::space space, isl::pw_aff_list list); + inline /* implicit */ multi_pw_aff(isl::pw_multi_aff pma); + inline explicit multi_pw_aff(isl::ctx ctx, const std::string &str); + inline multi_pw_aff &operator=(multi_pw_aff obj); + inline ~multi_pw_aff(); + inline __isl_give isl_multi_pw_aff *copy() const &; + inline __isl_give isl_multi_pw_aff *copy() && = delete; + inline __isl_keep isl_multi_pw_aff *get() const; + inline __isl_give isl_multi_pw_aff *release(); + inline bool is_null() const; + inline isl::ctx ctx() const; + + inline isl::multi_pw_aff add(isl::multi_pw_aff multi2) const; + inline isl::multi_union_pw_aff add(const isl::multi_union_pw_aff &multi2) const; + inline isl::multi_pw_aff add(const isl::aff &multi2) const; + inline isl::multi_pw_aff add(const isl::multi_aff &multi2) const; + inline isl::multi_pw_aff add(const isl::pw_aff &multi2) const; + inline isl::multi_pw_aff add(const isl::pw_multi_aff &multi2) const; + inline isl::multi_pw_aff add_constant(isl::multi_val mv) const; + inline isl::multi_pw_aff add_constant(isl::val v) const; + inline isl::multi_pw_aff add_constant(long v) const; + inline isl::map as_map() const; + inline isl::multi_aff as_multi_aff() const; + inline isl::set as_set() const; + inline isl::pw_aff at(int pos) const; + inline isl::pw_aff get_at(int pos) const; + inline isl::set bind(isl::multi_id tuple) const; + inline isl::multi_pw_aff bind_domain(isl::multi_id tuple) const; + inline isl::multi_pw_aff bind_domain_wrapped_domain(isl::multi_id tuple) const; + inline isl::multi_pw_aff coalesce() const; + inline isl::set domain() const; + inline isl::multi_pw_aff domain_reverse() const; + inline isl::multi_pw_aff flat_range_product(isl::multi_pw_aff multi2) const; + inline isl::multi_union_pw_aff flat_range_product(const isl::multi_union_pw_aff &multi2) const; + inline isl::multi_pw_aff flat_range_product(const isl::aff &multi2) const; + inline isl::multi_pw_aff flat_range_product(const isl::multi_aff &multi2) const; + inline isl::multi_pw_aff flat_range_product(const isl::pw_aff &multi2) const; + inline isl::multi_pw_aff flat_range_product(const isl::pw_multi_aff &multi2) const; + inline isl::multi_pw_aff gist(isl::set set) const; + inline isl::multi_union_pw_aff gist(const isl::union_set &context) const; + inline isl::multi_pw_aff gist(const isl::basic_set &set) const; + inline isl::multi_pw_aff gist(const isl::point &set) const; + inline isl::multi_pw_aff gist_params(isl::set set) const; + inline bool has_range_tuple_id() const; + inline isl::multi_pw_aff identity() const; + static inline isl::multi_pw_aff identity_on_domain(isl::space space); + inline isl::multi_pw_aff insert_domain(isl::space domain) const; + inline isl::multi_pw_aff intersect_domain(isl::set domain) const; + inline isl::multi_union_pw_aff intersect_domain(const isl::union_set &uset) const; + inline isl::multi_pw_aff intersect_domain(const isl::basic_set &domain) const; + inline isl::multi_pw_aff intersect_domain(const isl::point &domain) const; + inline isl::multi_pw_aff intersect_params(isl::set set) const; + inline bool involves_nan() const; + inline bool involves_param(const isl::id &id) const; + inline bool involves_param(const std::string &id) const; + inline bool involves_param(const isl::id_list &list) const; + inline bool isa_multi_aff() const; + inline isl::pw_aff_list list() const; + inline isl::pw_aff_list get_list() const; + inline isl::multi_pw_aff max(isl::multi_pw_aff multi2) const; + inline isl::multi_val max_multi_val() const; + inline isl::multi_pw_aff min(isl::multi_pw_aff multi2) const; + inline isl::multi_val min_multi_val() const; + inline isl::multi_pw_aff neg() const; + inline bool plain_is_equal(const isl::multi_pw_aff &multi2) const; + inline bool plain_is_equal(const isl::multi_union_pw_aff &multi2) const; + inline bool plain_is_equal(const isl::aff &multi2) const; + inline bool plain_is_equal(const isl::multi_aff &multi2) const; + inline bool plain_is_equal(const isl::pw_aff &multi2) const; + inline bool plain_is_equal(const isl::pw_multi_aff &multi2) const; + inline isl::multi_pw_aff product(isl::multi_pw_aff multi2) const; + inline isl::multi_pw_aff pullback(isl::multi_aff ma) const; + inline isl::multi_pw_aff pullback(isl::multi_pw_aff mpa2) const; + inline isl::multi_pw_aff pullback(isl::pw_multi_aff pma) const; + inline isl::multi_union_pw_aff pullback(const isl::union_pw_multi_aff &upma) const; + inline isl::multi_pw_aff range_product(isl::multi_pw_aff multi2) const; + inline isl::multi_union_pw_aff range_product(const isl::multi_union_pw_aff &multi2) const; + inline isl::multi_pw_aff range_product(const isl::aff &multi2) const; + inline isl::multi_pw_aff range_product(const isl::multi_aff &multi2) const; + inline isl::multi_pw_aff range_product(const isl::pw_aff &multi2) const; + inline isl::multi_pw_aff range_product(const isl::pw_multi_aff &multi2) const; + inline isl::id range_tuple_id() const; + inline isl::id get_range_tuple_id() const; + inline isl::multi_pw_aff reset_range_tuple_id() const; + inline isl::multi_pw_aff scale(isl::multi_val mv) const; + inline isl::multi_pw_aff scale(isl::val v) const; + inline isl::multi_pw_aff scale(long v) const; + inline isl::multi_pw_aff scale_down(isl::multi_val mv) const; + inline isl::multi_pw_aff scale_down(isl::val v) const; + inline isl::multi_pw_aff scale_down(long v) const; + inline isl::multi_pw_aff set_at(int pos, isl::pw_aff el) const; + inline isl::multi_union_pw_aff set_at(int pos, const isl::union_pw_aff &el) const; + inline isl::multi_pw_aff set_range_tuple(isl::id id) const; + inline isl::multi_pw_aff set_range_tuple(const std::string &id) const; + inline unsigned size() const; + inline isl::space space() const; + inline isl::space get_space() const; + inline isl::multi_pw_aff sub(isl::multi_pw_aff multi2) const; + inline isl::multi_union_pw_aff sub(const isl::multi_union_pw_aff &multi2) const; + inline isl::multi_pw_aff sub(const isl::aff &multi2) const; + inline isl::multi_pw_aff sub(const isl::multi_aff &multi2) const; + inline isl::multi_pw_aff sub(const isl::pw_aff &multi2) const; + inline isl::multi_pw_aff sub(const isl::pw_multi_aff &multi2) const; + inline isl::multi_pw_aff unbind_params_insert_domain(isl::multi_id domain) const; + inline isl::multi_pw_aff union_add(isl::multi_pw_aff mpa2) const; + inline isl::multi_union_pw_aff union_add(const isl::multi_union_pw_aff &mupa2) const; + inline isl::multi_pw_aff union_add(const isl::aff &mpa2) const; + inline isl::multi_pw_aff union_add(const isl::multi_aff &mpa2) const; + inline isl::multi_pw_aff union_add(const isl::pw_aff &mpa2) const; + inline isl::multi_pw_aff union_add(const isl::pw_multi_aff &mpa2) const; + static inline isl::multi_pw_aff zero(isl::space space); +}; + +// declarations for isl::multi_union_pw_aff +inline multi_union_pw_aff manage(__isl_take isl_multi_union_pw_aff *ptr); +inline multi_union_pw_aff manage_copy(__isl_keep isl_multi_union_pw_aff *ptr); + +class multi_union_pw_aff { + friend inline multi_union_pw_aff manage(__isl_take isl_multi_union_pw_aff *ptr); + friend inline multi_union_pw_aff manage_copy(__isl_keep isl_multi_union_pw_aff *ptr); + +protected: + isl_multi_union_pw_aff *ptr = nullptr; + + inline explicit multi_union_pw_aff(__isl_take isl_multi_union_pw_aff *ptr); + +public: + inline /* implicit */ multi_union_pw_aff(); + inline /* implicit */ multi_union_pw_aff(const multi_union_pw_aff &obj); + inline /* implicit */ multi_union_pw_aff(isl::multi_pw_aff mpa); + inline /* implicit */ multi_union_pw_aff(isl::union_pw_aff upa); + inline explicit multi_union_pw_aff(isl::space space, isl::union_pw_aff_list list); + inline explicit multi_union_pw_aff(isl::ctx ctx, const std::string &str); + inline multi_union_pw_aff &operator=(multi_union_pw_aff obj); + inline ~multi_union_pw_aff(); + inline __isl_give isl_multi_union_pw_aff *copy() const &; + inline __isl_give isl_multi_union_pw_aff *copy() && = delete; + inline __isl_keep isl_multi_union_pw_aff *get() const; + inline __isl_give isl_multi_union_pw_aff *release(); + inline bool is_null() const; + inline isl::ctx ctx() const; + + inline isl::multi_union_pw_aff add(isl::multi_union_pw_aff multi2) const; + inline isl::union_pw_aff at(int pos) const; + inline isl::union_pw_aff get_at(int pos) const; + inline isl::union_set bind(isl::multi_id tuple) const; + inline isl::multi_union_pw_aff coalesce() const; + inline isl::union_set domain() const; + inline isl::multi_union_pw_aff flat_range_product(isl::multi_union_pw_aff multi2) const; + inline isl::multi_union_pw_aff gist(isl::union_set context) const; + inline isl::multi_union_pw_aff gist_params(isl::set context) const; + inline bool has_range_tuple_id() const; + inline isl::multi_union_pw_aff intersect_domain(isl::union_set uset) const; + inline isl::multi_union_pw_aff intersect_params(isl::set params) const; + inline bool involves_nan() const; + inline isl::union_pw_aff_list list() const; + inline isl::union_pw_aff_list get_list() const; + inline isl::multi_union_pw_aff neg() const; + inline bool plain_is_equal(const isl::multi_union_pw_aff &multi2) const; + inline isl::multi_union_pw_aff pullback(isl::union_pw_multi_aff upma) const; + inline isl::multi_union_pw_aff range_product(isl::multi_union_pw_aff multi2) const; + inline isl::id range_tuple_id() const; + inline isl::id get_range_tuple_id() const; + inline isl::multi_union_pw_aff reset_range_tuple_id() const; + inline isl::multi_union_pw_aff scale(isl::multi_val mv) const; + inline isl::multi_union_pw_aff scale(isl::val v) const; + inline isl::multi_union_pw_aff scale(long v) const; + inline isl::multi_union_pw_aff scale_down(isl::multi_val mv) const; + inline isl::multi_union_pw_aff scale_down(isl::val v) const; + inline isl::multi_union_pw_aff scale_down(long v) const; + inline isl::multi_union_pw_aff set_at(int pos, isl::union_pw_aff el) const; + inline isl::multi_union_pw_aff set_range_tuple(isl::id id) const; + inline isl::multi_union_pw_aff set_range_tuple(const std::string &id) const; + inline unsigned size() const; + inline isl::space space() const; + inline isl::space get_space() const; + inline isl::multi_union_pw_aff sub(isl::multi_union_pw_aff multi2) const; + inline isl::multi_union_pw_aff union_add(isl::multi_union_pw_aff mupa2) const; + static inline isl::multi_union_pw_aff zero(isl::space space); +}; + +// declarations for isl::multi_val +inline multi_val manage(__isl_take isl_multi_val *ptr); +inline multi_val manage_copy(__isl_keep isl_multi_val *ptr); + +class multi_val { + friend inline multi_val manage(__isl_take isl_multi_val *ptr); + friend inline multi_val manage_copy(__isl_keep isl_multi_val *ptr); + +protected: + isl_multi_val *ptr = nullptr; + + inline explicit multi_val(__isl_take isl_multi_val *ptr); + +public: + inline /* implicit */ multi_val(); + inline /* implicit */ multi_val(const multi_val &obj); + inline explicit multi_val(isl::space space, isl::val_list list); + inline explicit multi_val(isl::ctx ctx, const std::string &str); + inline multi_val &operator=(multi_val obj); + inline ~multi_val(); + inline __isl_give isl_multi_val *copy() const &; + inline __isl_give isl_multi_val *copy() && = delete; + inline __isl_keep isl_multi_val *get() const; + inline __isl_give isl_multi_val *release(); + inline bool is_null() const; + inline isl::ctx ctx() const; + + inline isl::multi_val add(isl::multi_val multi2) const; + inline isl::multi_val add(isl::val v) const; + inline isl::multi_val add(long v) const; + inline isl::val at(int pos) const; + inline isl::val get_at(int pos) const; + inline isl::multi_val flat_range_product(isl::multi_val multi2) const; + inline bool has_range_tuple_id() const; + inline bool involves_nan() const; + inline isl::val_list list() const; + inline isl::val_list get_list() const; + inline isl::multi_val max(isl::multi_val multi2) const; + inline isl::multi_val min(isl::multi_val multi2) const; + inline isl::multi_val neg() const; + inline bool plain_is_equal(const isl::multi_val &multi2) const; + inline isl::multi_val product(isl::multi_val multi2) const; + inline isl::multi_val range_product(isl::multi_val multi2) const; + inline isl::id range_tuple_id() const; + inline isl::id get_range_tuple_id() const; + inline isl::multi_val reset_range_tuple_id() const; + inline isl::multi_val scale(isl::multi_val mv) const; + inline isl::multi_val scale(isl::val v) const; + inline isl::multi_val scale(long v) const; + inline isl::multi_val scale_down(isl::multi_val mv) const; + inline isl::multi_val scale_down(isl::val v) const; + inline isl::multi_val scale_down(long v) const; + inline isl::multi_val set_at(int pos, isl::val el) const; + inline isl::multi_val set_at(int pos, long el) const; + inline isl::multi_val set_range_tuple(isl::id id) const; + inline isl::multi_val set_range_tuple(const std::string &id) const; + inline unsigned size() const; + inline isl::space space() const; + inline isl::space get_space() const; + inline isl::multi_val sub(isl::multi_val multi2) const; + static inline isl::multi_val zero(isl::space space); +}; + +// declarations for isl::point +inline point manage(__isl_take isl_point *ptr); +inline point manage_copy(__isl_keep isl_point *ptr); + +class point { + friend inline point manage(__isl_take isl_point *ptr); + friend inline point manage_copy(__isl_keep isl_point *ptr); + +protected: + isl_point *ptr = nullptr; + + inline explicit point(__isl_take isl_point *ptr); + +public: + inline /* implicit */ point(); + inline /* implicit */ point(const point &obj); + inline point &operator=(point obj); + inline ~point(); + inline __isl_give isl_point *copy() const &; + inline __isl_give isl_point *copy() && = delete; + inline __isl_keep isl_point *get() const; + inline __isl_give isl_point *release(); + inline bool is_null() const; + inline isl::ctx ctx() const; + + inline isl::basic_set affine_hull() const; + inline isl::basic_set apply(const isl::basic_map &bmap) const; + inline isl::set apply(const isl::map &map) const; + inline isl::union_set apply(const isl::union_map &umap) const; + inline isl::pw_multi_aff as_pw_multi_aff() const; + inline isl::set as_set() const; + inline isl::set bind(const isl::multi_id &tuple) const; + inline isl::set coalesce() const; + inline isl::set complement() const; + inline isl::union_set compute_divs() const; + inline isl::basic_set detect_equalities() const; + inline isl::val dim_max_val(int pos) const; + inline isl::val dim_min_val(int pos) const; + inline isl::set drop_unused_params() const; + inline bool every_set(const std::function &test) const; + inline isl::set extract_set(const isl::space &space) const; + inline isl::basic_set flatten() const; + inline void foreach_basic_set(const std::function &fn) const; + inline void foreach_point(const std::function &fn) const; + inline void foreach_set(const std::function &fn) const; + inline isl::basic_set gist(const isl::basic_set &context) const; + inline isl::set gist(const isl::set &context) const; + inline isl::union_set gist(const isl::union_set &context) const; + inline isl::set gist_params(const isl::set &context) const; + inline isl::map identity() const; + inline isl::pw_aff indicator_function() const; + inline isl::map insert_domain(const isl::space &domain) const; + inline isl::basic_set intersect(const isl::basic_set &bset2) const; + inline isl::set intersect(const isl::set &set2) const; + inline isl::union_set intersect(const isl::union_set &uset2) const; + inline isl::basic_set intersect_params(const isl::basic_set &bset2) const; + inline isl::set intersect_params(const isl::set ¶ms) const; + inline bool involves_locals() const; + inline bool is_disjoint(const isl::set &set2) const; + inline bool is_disjoint(const isl::union_set &uset2) const; + inline bool is_empty() const; + inline bool is_equal(const isl::basic_set &bset2) const; + inline bool is_equal(const isl::set &set2) const; + inline bool is_equal(const isl::union_set &uset2) const; + inline bool is_singleton() const; + inline bool is_strict_subset(const isl::set &set2) const; + inline bool is_strict_subset(const isl::union_set &uset2) const; + inline bool is_subset(const isl::basic_set &bset2) const; + inline bool is_subset(const isl::set &set2) const; + inline bool is_subset(const isl::union_set &uset2) const; + inline bool is_wrapping() const; + inline bool isa_set() const; + inline isl::fixed_box lattice_tile() const; + inline isl::set lexmax() const; + inline isl::pw_multi_aff lexmax_pw_multi_aff() const; + inline isl::set lexmin() const; + inline isl::pw_multi_aff lexmin_pw_multi_aff() const; + inline isl::set lower_bound(const isl::multi_pw_aff &lower) const; + inline isl::set lower_bound(const isl::multi_val &lower) const; + inline isl::multi_pw_aff max_multi_pw_aff() const; + inline isl::val max_val(const isl::aff &obj) const; + inline isl::multi_pw_aff min_multi_pw_aff() const; + inline isl::val min_val(const isl::aff &obj) const; + inline isl::multi_val multi_val() const; + inline isl::multi_val get_multi_val() const; + inline unsigned n_basic_set() const; + inline isl::pw_aff param_pw_aff_on_domain(const isl::id &id) const; + inline isl::pw_aff param_pw_aff_on_domain(const std::string &id) const; + inline isl::basic_set params() const; + inline isl::multi_val plain_multi_val_if_fixed() const; + inline isl::basic_set polyhedral_hull() const; + inline isl::set preimage(const isl::multi_aff &ma) const; + inline isl::set preimage(const isl::multi_pw_aff &mpa) const; + inline isl::set preimage(const isl::pw_multi_aff &pma) const; + inline isl::union_set preimage(const isl::union_pw_multi_aff &upma) const; + inline isl::set product(const isl::set &set2) const; + inline isl::set project_out_all_params() const; + inline isl::set project_out_param(const isl::id &id) const; + inline isl::set project_out_param(const std::string &id) const; + inline isl::set project_out_param(const isl::id_list &list) const; + inline isl::pw_aff pw_aff_on_domain(const isl::val &v) const; + inline isl::pw_aff pw_aff_on_domain(long v) const; + inline isl::pw_multi_aff pw_multi_aff_on_domain(const isl::multi_val &mv) const; + inline isl::basic_set sample() const; + inline isl::point sample_point() const; + inline isl::set_list set_list() const; + inline isl::fixed_box simple_fixed_box_hull() const; + inline isl::space space() const; + inline isl::val stride(int pos) const; + inline isl::set subtract(const isl::set &set2) const; + inline isl::union_set subtract(const isl::union_set &uset2) const; + inline isl::set_list to_list() const; + inline isl::set to_set() const; + inline isl::union_set to_union_set() const; + inline isl::map translation() const; + inline unsigned tuple_dim() const; + inline isl::set unbind_params(const isl::multi_id &tuple) const; + inline isl::map unbind_params_insert_domain(const isl::multi_id &domain) const; + inline isl::set unite(const isl::basic_set &bset2) const; + inline isl::set unite(const isl::set &set2) const; + inline isl::union_set unite(const isl::union_set &uset2) const; + inline isl::basic_set unshifted_simple_hull() const; + inline isl::map unwrap() const; + inline isl::set upper_bound(const isl::multi_pw_aff &upper) const; + inline isl::set upper_bound(const isl::multi_val &upper) const; + inline isl::set wrapped_reverse() const; +}; + +// declarations for isl::pw_aff +inline pw_aff manage(__isl_take isl_pw_aff *ptr); +inline pw_aff manage_copy(__isl_keep isl_pw_aff *ptr); + +class pw_aff { + friend inline pw_aff manage(__isl_take isl_pw_aff *ptr); + friend inline pw_aff manage_copy(__isl_keep isl_pw_aff *ptr); + +protected: + isl_pw_aff *ptr = nullptr; + + inline explicit pw_aff(__isl_take isl_pw_aff *ptr); + +public: + inline /* implicit */ pw_aff(); + inline /* implicit */ pw_aff(const pw_aff &obj); + inline /* implicit */ pw_aff(isl::aff aff); + inline explicit pw_aff(isl::ctx ctx, const std::string &str); + inline pw_aff &operator=(pw_aff obj); + inline ~pw_aff(); + inline __isl_give isl_pw_aff *copy() const &; + inline __isl_give isl_pw_aff *copy() && = delete; + inline __isl_keep isl_pw_aff *get() const; + inline __isl_give isl_pw_aff *release(); + inline bool is_null() const; + inline isl::ctx ctx() const; + + inline isl::multi_pw_aff add(const isl::multi_pw_aff &multi2) const; + inline isl::multi_union_pw_aff add(const isl::multi_union_pw_aff &multi2) const; + inline isl::pw_aff add(isl::pw_aff pwaff2) const; + inline isl::pw_multi_aff add(const isl::pw_multi_aff &pma2) const; + inline isl::union_pw_aff add(const isl::union_pw_aff &upa2) const; + inline isl::union_pw_multi_aff add(const isl::union_pw_multi_aff &upma2) const; + inline isl::pw_aff add(const isl::aff &pwaff2) const; + inline isl::pw_aff add_constant(isl::val v) const; + inline isl::pw_aff add_constant(long v) const; + inline isl::pw_multi_aff add_constant(const isl::multi_val &mv) const; + inline isl::union_pw_multi_aff apply(const isl::union_pw_multi_aff &upma2) const; + inline isl::aff as_aff() const; + inline isl::map as_map() const; + inline isl::multi_aff as_multi_aff() const; + inline isl::multi_union_pw_aff as_multi_union_pw_aff() const; + inline isl::pw_multi_aff as_pw_multi_aff() const; + inline isl::set as_set() const; + inline isl::union_map as_union_map() const; + inline isl::pw_aff at(int pos) const; + inline isl::set bind(const isl::multi_id &tuple) const; + inline isl::set bind(isl::id id) const; + inline isl::set bind(const std::string &id) const; + inline isl::pw_aff bind_domain(isl::multi_id tuple) const; + inline isl::pw_aff bind_domain_wrapped_domain(isl::multi_id tuple) const; + inline isl::pw_aff ceil() const; + inline isl::pw_aff coalesce() const; + inline isl::pw_aff cond(isl::pw_aff pwaff_true, isl::pw_aff pwaff_false) const; + inline isl::pw_aff div(isl::pw_aff pa2) const; + inline isl::set domain() const; + inline isl::pw_aff domain_reverse() const; + inline isl::pw_aff drop_unused_params() const; + inline isl::set eq_set(isl::pw_aff pwaff2) const; + inline isl::val eval(isl::point pnt) const; + inline isl::pw_multi_aff extract_pw_multi_aff(const isl::space &space) const; + inline isl::multi_pw_aff flat_range_product(const isl::multi_pw_aff &multi2) const; + inline isl::multi_union_pw_aff flat_range_product(const isl::multi_union_pw_aff &multi2) const; + inline isl::pw_multi_aff flat_range_product(const isl::pw_multi_aff &pma2) const; + inline isl::union_pw_multi_aff flat_range_product(const isl::union_pw_multi_aff &upma2) const; + inline isl::pw_aff floor() const; + inline void foreach_piece(const std::function &fn) const; + inline isl::set ge_set(isl::pw_aff pwaff2) const; + inline isl::pw_aff gist(isl::set context) const; + inline isl::union_pw_aff gist(const isl::union_set &context) const; + inline isl::pw_aff gist(const isl::basic_set &context) const; + inline isl::pw_aff gist(const isl::point &context) const; + inline isl::pw_aff gist_params(isl::set context) const; + inline isl::set gt_set(isl::pw_aff pwaff2) const; + inline bool has_range_tuple_id() const; + inline isl::multi_pw_aff identity() const; + inline isl::pw_aff insert_domain(isl::space domain) const; + inline isl::pw_aff intersect_domain(isl::set set) const; + inline isl::union_pw_aff intersect_domain(const isl::space &space) const; + inline isl::union_pw_aff intersect_domain(const isl::union_set &uset) const; + inline isl::pw_aff intersect_domain(const isl::basic_set &set) const; + inline isl::pw_aff intersect_domain(const isl::point &set) const; + inline isl::union_pw_aff intersect_domain_wrapped_domain(const isl::union_set &uset) const; + inline isl::union_pw_aff intersect_domain_wrapped_range(const isl::union_set &uset) const; + inline isl::pw_aff intersect_params(isl::set set) const; + inline bool involves_locals() const; + inline bool involves_nan() const; + inline bool involves_param(const isl::id &id) const; + inline bool involves_param(const std::string &id) const; + inline bool involves_param(const isl::id_list &list) const; + inline bool isa_aff() const; + inline bool isa_multi_aff() const; + inline bool isa_pw_multi_aff() const; + inline isl::set le_set(isl::pw_aff pwaff2) const; + inline isl::pw_aff_list list() const; + inline isl::set lt_set(isl::pw_aff pwaff2) const; + inline isl::multi_pw_aff max(const isl::multi_pw_aff &multi2) const; + inline isl::pw_aff max(isl::pw_aff pwaff2) const; + inline isl::pw_aff max(const isl::aff &pwaff2) const; + inline isl::multi_val max_multi_val() const; + inline isl::val max_val() const; + inline isl::multi_pw_aff min(const isl::multi_pw_aff &multi2) const; + inline isl::pw_aff min(isl::pw_aff pwaff2) const; + inline isl::pw_aff min(const isl::aff &pwaff2) const; + inline isl::multi_val min_multi_val() const; + inline isl::val min_val() const; + inline isl::pw_aff mod(isl::val mod) const; + inline isl::pw_aff mod(long mod) const; + inline isl::pw_aff mul(isl::pw_aff pwaff2) const; + inline unsigned n_piece() const; + inline isl::set ne_set(isl::pw_aff pwaff2) const; + inline isl::pw_aff neg() const; + static inline isl::pw_aff param_on_domain(isl::set domain, isl::id id); + inline isl::set params() const; + inline bool plain_is_empty() const; + inline bool plain_is_equal(const isl::multi_pw_aff &multi2) const; + inline bool plain_is_equal(const isl::multi_union_pw_aff &multi2) const; + inline bool plain_is_equal(const isl::pw_aff &pwaff2) const; + inline bool plain_is_equal(const isl::pw_multi_aff &pma2) const; + inline bool plain_is_equal(const isl::union_pw_aff &upa2) const; + inline bool plain_is_equal(const isl::union_pw_multi_aff &upma2) const; + inline bool plain_is_equal(const isl::aff &pwaff2) const; + inline isl::pw_multi_aff preimage_domain_wrapped_domain(const isl::pw_multi_aff &pma2) const; + inline isl::union_pw_multi_aff preimage_domain_wrapped_domain(const isl::union_pw_multi_aff &upma2) const; + inline isl::multi_pw_aff product(const isl::multi_pw_aff &multi2) const; + inline isl::pw_multi_aff product(const isl::pw_multi_aff &pma2) const; + inline isl::pw_aff pullback(isl::multi_aff ma) const; + inline isl::pw_aff pullback(isl::multi_pw_aff mpa) const; + inline isl::pw_aff pullback(isl::pw_multi_aff pma) const; + inline isl::union_pw_aff pullback(const isl::union_pw_multi_aff &upma) const; + inline isl::pw_multi_aff_list pw_multi_aff_list() const; + inline isl::pw_multi_aff range_factor_domain() const; + inline isl::pw_multi_aff range_factor_range() const; + inline isl::multi_pw_aff range_product(const isl::multi_pw_aff &multi2) const; + inline isl::multi_union_pw_aff range_product(const isl::multi_union_pw_aff &multi2) const; + inline isl::pw_multi_aff range_product(const isl::pw_multi_aff &pma2) const; + inline isl::union_pw_multi_aff range_product(const isl::union_pw_multi_aff &upma2) const; + inline isl::id range_tuple_id() const; + inline isl::multi_pw_aff reset_range_tuple_id() const; + inline isl::pw_aff scale(isl::val v) const; + inline isl::pw_aff scale(long v) const; + inline isl::pw_multi_aff scale(const isl::multi_val &mv) const; + inline isl::pw_aff scale_down(isl::val f) const; + inline isl::pw_aff scale_down(long f) const; + inline isl::pw_multi_aff scale_down(const isl::multi_val &mv) const; + inline isl::multi_pw_aff set_at(int pos, const isl::pw_aff &el) const; + inline isl::multi_union_pw_aff set_at(int pos, const isl::union_pw_aff &el) const; + inline isl::pw_multi_aff set_range_tuple(const isl::id &id) const; + inline isl::pw_multi_aff set_range_tuple(const std::string &id) const; + inline unsigned size() const; + inline isl::space space() const; + inline isl::space get_space() const; + inline isl::multi_pw_aff sub(const isl::multi_pw_aff &multi2) const; + inline isl::multi_union_pw_aff sub(const isl::multi_union_pw_aff &multi2) const; + inline isl::pw_aff sub(isl::pw_aff pwaff2) const; + inline isl::pw_multi_aff sub(const isl::pw_multi_aff &pma2) const; + inline isl::union_pw_aff sub(const isl::union_pw_aff &upa2) const; + inline isl::union_pw_multi_aff sub(const isl::union_pw_multi_aff &upma2) const; + inline isl::pw_aff sub(const isl::aff &pwaff2) const; + inline isl::pw_aff subtract_domain(isl::set set) const; + inline isl::union_pw_aff subtract_domain(const isl::space &space) const; + inline isl::union_pw_aff subtract_domain(const isl::union_set &uset) const; + inline isl::pw_aff subtract_domain(const isl::basic_set &set) const; + inline isl::pw_aff subtract_domain(const isl::point &set) const; + inline isl::pw_aff tdiv_q(isl::pw_aff pa2) const; + inline isl::pw_aff tdiv_r(isl::pw_aff pa2) const; + inline isl::pw_aff_list to_list() const; + inline isl::multi_pw_aff to_multi_pw_aff() const; + inline isl::union_pw_aff to_union_pw_aff() const; + inline isl::union_pw_multi_aff to_union_pw_multi_aff() const; + inline isl::multi_pw_aff unbind_params_insert_domain(const isl::multi_id &domain) const; + inline isl::multi_pw_aff union_add(const isl::multi_pw_aff &mpa2) const; + inline isl::multi_union_pw_aff union_add(const isl::multi_union_pw_aff &mupa2) const; + inline isl::pw_aff union_add(isl::pw_aff pwaff2) const; + inline isl::pw_multi_aff union_add(const isl::pw_multi_aff &pma2) const; + inline isl::union_pw_aff union_add(const isl::union_pw_aff &upa2) const; + inline isl::union_pw_multi_aff union_add(const isl::union_pw_multi_aff &upma2) const; + inline isl::pw_aff union_add(const isl::aff &pwaff2) const; +}; + +// declarations for isl::pw_aff_list +inline pw_aff_list manage(__isl_take isl_pw_aff_list *ptr); +inline pw_aff_list manage_copy(__isl_keep isl_pw_aff_list *ptr); + +class pw_aff_list { + friend inline pw_aff_list manage(__isl_take isl_pw_aff_list *ptr); + friend inline pw_aff_list manage_copy(__isl_keep isl_pw_aff_list *ptr); + +protected: + isl_pw_aff_list *ptr = nullptr; + + inline explicit pw_aff_list(__isl_take isl_pw_aff_list *ptr); + +public: + inline /* implicit */ pw_aff_list(); + inline /* implicit */ pw_aff_list(const pw_aff_list &obj); + inline explicit pw_aff_list(isl::ctx ctx, int n); + inline explicit pw_aff_list(isl::pw_aff el); + inline explicit pw_aff_list(isl::ctx ctx, const std::string &str); + inline pw_aff_list &operator=(pw_aff_list obj); + inline ~pw_aff_list(); + inline __isl_give isl_pw_aff_list *copy() const &; + inline __isl_give isl_pw_aff_list *copy() && = delete; + inline __isl_keep isl_pw_aff_list *get() const; + inline __isl_give isl_pw_aff_list *release(); + inline bool is_null() const; + inline isl::ctx ctx() const; + + inline isl::pw_aff_list add(isl::pw_aff el) const; + inline isl::pw_aff at(int index) const; + inline isl::pw_aff get_at(int index) const; + inline isl::pw_aff_list clear() const; + inline isl::pw_aff_list concat(isl::pw_aff_list list2) const; + inline isl::pw_aff_list drop(unsigned int first, unsigned int n) const; + inline void foreach(const std::function &fn) const; + inline void foreach_scc(const std::function &follows, const std::function &fn) const; + inline isl::pw_aff_list insert(unsigned int pos, isl::pw_aff el) const; + inline isl::pw_aff_list set_at(int index, isl::pw_aff el) const; + inline unsigned size() const; +}; + +// declarations for isl::pw_multi_aff +inline pw_multi_aff manage(__isl_take isl_pw_multi_aff *ptr); +inline pw_multi_aff manage_copy(__isl_keep isl_pw_multi_aff *ptr); + +class pw_multi_aff { + friend inline pw_multi_aff manage(__isl_take isl_pw_multi_aff *ptr); + friend inline pw_multi_aff manage_copy(__isl_keep isl_pw_multi_aff *ptr); + +protected: + isl_pw_multi_aff *ptr = nullptr; + + inline explicit pw_multi_aff(__isl_take isl_pw_multi_aff *ptr); + +public: + inline /* implicit */ pw_multi_aff(); + inline /* implicit */ pw_multi_aff(const pw_multi_aff &obj); + inline /* implicit */ pw_multi_aff(isl::multi_aff ma); + inline /* implicit */ pw_multi_aff(isl::pw_aff pa); + inline explicit pw_multi_aff(isl::ctx ctx, const std::string &str); + inline pw_multi_aff &operator=(pw_multi_aff obj); + inline ~pw_multi_aff(); + inline __isl_give isl_pw_multi_aff *copy() const &; + inline __isl_give isl_pw_multi_aff *copy() && = delete; + inline __isl_keep isl_pw_multi_aff *get() const; + inline __isl_give isl_pw_multi_aff *release(); + inline bool is_null() const; + inline isl::ctx ctx() const; + + inline isl::multi_pw_aff add(const isl::multi_pw_aff &multi2) const; + inline isl::multi_union_pw_aff add(const isl::multi_union_pw_aff &multi2) const; + inline isl::pw_multi_aff add(isl::pw_multi_aff pma2) const; + inline isl::union_pw_multi_aff add(const isl::union_pw_multi_aff &upma2) const; + inline isl::pw_multi_aff add(const isl::multi_aff &pma2) const; + inline isl::pw_multi_aff add(const isl::pw_aff &pma2) const; + inline isl::pw_multi_aff add_constant(isl::multi_val mv) const; + inline isl::pw_multi_aff add_constant(isl::val v) const; + inline isl::pw_multi_aff add_constant(long v) const; + inline isl::union_pw_multi_aff apply(const isl::union_pw_multi_aff &upma2) const; + inline isl::map as_map() const; + inline isl::multi_aff as_multi_aff() const; + inline isl::multi_union_pw_aff as_multi_union_pw_aff() const; + inline isl::pw_multi_aff as_pw_multi_aff() const; + inline isl::set as_set() const; + inline isl::union_map as_union_map() const; + inline isl::pw_aff at(int pos) const; + inline isl::pw_aff get_at(int pos) const; + inline isl::set bind(const isl::multi_id &tuple) const; + inline isl::pw_multi_aff bind_domain(isl::multi_id tuple) const; + inline isl::pw_multi_aff bind_domain_wrapped_domain(isl::multi_id tuple) const; + inline isl::pw_multi_aff coalesce() const; + inline isl::set domain() const; + static inline isl::pw_multi_aff domain_map(isl::space space); + inline isl::pw_multi_aff domain_reverse() const; + inline isl::pw_multi_aff drop_unused_params() const; + inline isl::pw_multi_aff extract_pw_multi_aff(const isl::space &space) const; + inline isl::multi_pw_aff flat_range_product(const isl::multi_pw_aff &multi2) const; + inline isl::multi_union_pw_aff flat_range_product(const isl::multi_union_pw_aff &multi2) const; + inline isl::pw_multi_aff flat_range_product(isl::pw_multi_aff pma2) const; + inline isl::union_pw_multi_aff flat_range_product(const isl::union_pw_multi_aff &upma2) const; + inline isl::pw_multi_aff flat_range_product(const isl::multi_aff &pma2) const; + inline isl::pw_multi_aff flat_range_product(const isl::pw_aff &pma2) const; + inline void foreach_piece(const std::function &fn) const; + inline isl::pw_multi_aff gist(isl::set set) const; + inline isl::union_pw_multi_aff gist(const isl::union_set &context) const; + inline isl::pw_multi_aff gist(const isl::basic_set &set) const; + inline isl::pw_multi_aff gist(const isl::point &set) const; + inline isl::pw_multi_aff gist_params(isl::set set) const; + inline bool has_range_tuple_id() const; + inline isl::multi_pw_aff identity() const; + static inline isl::pw_multi_aff identity_on_domain(isl::space space); + inline isl::pw_multi_aff insert_domain(isl::space domain) const; + inline isl::pw_multi_aff intersect_domain(isl::set set) const; + inline isl::union_pw_multi_aff intersect_domain(const isl::space &space) const; + inline isl::union_pw_multi_aff intersect_domain(const isl::union_set &uset) const; + inline isl::pw_multi_aff intersect_domain(const isl::basic_set &set) const; + inline isl::pw_multi_aff intersect_domain(const isl::point &set) const; + inline isl::union_pw_multi_aff intersect_domain_wrapped_domain(const isl::union_set &uset) const; + inline isl::union_pw_multi_aff intersect_domain_wrapped_range(const isl::union_set &uset) const; + inline isl::pw_multi_aff intersect_params(isl::set set) const; + inline bool involves_locals() const; + inline bool involves_nan() const; + inline bool involves_param(const isl::id &id) const; + inline bool involves_param(const std::string &id) const; + inline bool involves_param(const isl::id_list &list) const; + inline bool isa_multi_aff() const; + inline bool isa_pw_multi_aff() const; + inline isl::pw_aff_list list() const; + inline isl::multi_pw_aff max(const isl::multi_pw_aff &multi2) const; + inline isl::multi_val max_multi_val() const; + inline isl::multi_pw_aff min(const isl::multi_pw_aff &multi2) const; + inline isl::multi_val min_multi_val() const; + static inline isl::pw_multi_aff multi_val_on_domain(isl::set domain, isl::multi_val mv); + inline unsigned n_piece() const; + inline isl::multi_pw_aff neg() const; + inline bool plain_is_empty() const; + inline bool plain_is_equal(const isl::multi_pw_aff &multi2) const; + inline bool plain_is_equal(const isl::multi_union_pw_aff &multi2) const; + inline bool plain_is_equal(const isl::pw_multi_aff &pma2) const; + inline bool plain_is_equal(const isl::union_pw_multi_aff &upma2) const; + inline bool plain_is_equal(const isl::multi_aff &pma2) const; + inline bool plain_is_equal(const isl::pw_aff &pma2) const; + inline isl::pw_multi_aff preimage_domain_wrapped_domain(isl::pw_multi_aff pma2) const; + inline isl::union_pw_multi_aff preimage_domain_wrapped_domain(const isl::union_pw_multi_aff &upma2) const; + inline isl::pw_multi_aff preimage_domain_wrapped_domain(const isl::multi_aff &pma2) const; + inline isl::pw_multi_aff preimage_domain_wrapped_domain(const isl::pw_aff &pma2) const; + inline isl::multi_pw_aff product(const isl::multi_pw_aff &multi2) const; + inline isl::pw_multi_aff product(isl::pw_multi_aff pma2) const; + inline isl::pw_multi_aff product(const isl::multi_aff &pma2) const; + inline isl::pw_multi_aff product(const isl::pw_aff &pma2) const; + inline isl::multi_pw_aff pullback(const isl::multi_pw_aff &mpa2) const; + inline isl::pw_multi_aff pullback(isl::multi_aff ma) const; + inline isl::pw_multi_aff pullback(isl::pw_multi_aff pma2) const; + inline isl::union_pw_multi_aff pullback(const isl::union_pw_multi_aff &upma2) const; + inline isl::pw_multi_aff_list pw_multi_aff_list() const; + inline isl::pw_multi_aff range_factor_domain() const; + inline isl::pw_multi_aff range_factor_range() const; + static inline isl::pw_multi_aff range_map(isl::space space); + inline isl::multi_pw_aff range_product(const isl::multi_pw_aff &multi2) const; + inline isl::multi_union_pw_aff range_product(const isl::multi_union_pw_aff &multi2) const; + inline isl::pw_multi_aff range_product(isl::pw_multi_aff pma2) const; + inline isl::union_pw_multi_aff range_product(const isl::union_pw_multi_aff &upma2) const; + inline isl::pw_multi_aff range_product(const isl::multi_aff &pma2) const; + inline isl::pw_multi_aff range_product(const isl::pw_aff &pma2) const; + inline isl::id range_tuple_id() const; + inline isl::id get_range_tuple_id() const; + inline isl::multi_pw_aff reset_range_tuple_id() const; + inline isl::pw_multi_aff scale(isl::multi_val mv) const; + inline isl::pw_multi_aff scale(isl::val v) const; + inline isl::pw_multi_aff scale(long v) const; + inline isl::pw_multi_aff scale_down(isl::multi_val mv) const; + inline isl::pw_multi_aff scale_down(isl::val v) const; + inline isl::pw_multi_aff scale_down(long v) const; + inline isl::multi_pw_aff set_at(int pos, const isl::pw_aff &el) const; + inline isl::multi_union_pw_aff set_at(int pos, const isl::union_pw_aff &el) const; + inline isl::pw_multi_aff set_range_tuple(isl::id id) const; + inline isl::pw_multi_aff set_range_tuple(const std::string &id) const; + inline unsigned size() const; + inline isl::space space() const; + inline isl::space get_space() const; + inline isl::multi_pw_aff sub(const isl::multi_pw_aff &multi2) const; + inline isl::multi_union_pw_aff sub(const isl::multi_union_pw_aff &multi2) const; + inline isl::pw_multi_aff sub(isl::pw_multi_aff pma2) const; + inline isl::union_pw_multi_aff sub(const isl::union_pw_multi_aff &upma2) const; + inline isl::pw_multi_aff sub(const isl::multi_aff &pma2) const; + inline isl::pw_multi_aff sub(const isl::pw_aff &pma2) const; + inline isl::pw_multi_aff subtract_domain(isl::set set) const; + inline isl::union_pw_multi_aff subtract_domain(const isl::space &space) const; + inline isl::union_pw_multi_aff subtract_domain(const isl::union_set &uset) const; + inline isl::pw_multi_aff subtract_domain(const isl::basic_set &set) const; + inline isl::pw_multi_aff subtract_domain(const isl::point &set) const; + inline isl::pw_multi_aff_list to_list() const; + inline isl::multi_pw_aff to_multi_pw_aff() const; + inline isl::union_pw_multi_aff to_union_pw_multi_aff() const; + inline isl::multi_pw_aff unbind_params_insert_domain(const isl::multi_id &domain) const; + inline isl::multi_pw_aff union_add(const isl::multi_pw_aff &mpa2) const; + inline isl::multi_union_pw_aff union_add(const isl::multi_union_pw_aff &mupa2) const; + inline isl::pw_multi_aff union_add(isl::pw_multi_aff pma2) const; + inline isl::union_pw_multi_aff union_add(const isl::union_pw_multi_aff &upma2) const; + inline isl::pw_multi_aff union_add(const isl::multi_aff &pma2) const; + inline isl::pw_multi_aff union_add(const isl::pw_aff &pma2) const; + static inline isl::pw_multi_aff zero(isl::space space); +}; + +// declarations for isl::pw_multi_aff_list +inline pw_multi_aff_list manage(__isl_take isl_pw_multi_aff_list *ptr); +inline pw_multi_aff_list manage_copy(__isl_keep isl_pw_multi_aff_list *ptr); + +class pw_multi_aff_list { + friend inline pw_multi_aff_list manage(__isl_take isl_pw_multi_aff_list *ptr); + friend inline pw_multi_aff_list manage_copy(__isl_keep isl_pw_multi_aff_list *ptr); + +protected: + isl_pw_multi_aff_list *ptr = nullptr; + + inline explicit pw_multi_aff_list(__isl_take isl_pw_multi_aff_list *ptr); + +public: + inline /* implicit */ pw_multi_aff_list(); + inline /* implicit */ pw_multi_aff_list(const pw_multi_aff_list &obj); + inline explicit pw_multi_aff_list(isl::ctx ctx, int n); + inline explicit pw_multi_aff_list(isl::pw_multi_aff el); + inline explicit pw_multi_aff_list(isl::ctx ctx, const std::string &str); + inline pw_multi_aff_list &operator=(pw_multi_aff_list obj); + inline ~pw_multi_aff_list(); + inline __isl_give isl_pw_multi_aff_list *copy() const &; + inline __isl_give isl_pw_multi_aff_list *copy() && = delete; + inline __isl_keep isl_pw_multi_aff_list *get() const; + inline __isl_give isl_pw_multi_aff_list *release(); + inline bool is_null() const; + inline isl::ctx ctx() const; + + inline isl::pw_multi_aff_list add(isl::pw_multi_aff el) const; + inline isl::pw_multi_aff at(int index) const; + inline isl::pw_multi_aff get_at(int index) const; + inline isl::pw_multi_aff_list clear() const; + inline isl::pw_multi_aff_list concat(isl::pw_multi_aff_list list2) const; + inline isl::pw_multi_aff_list drop(unsigned int first, unsigned int n) const; + inline void foreach(const std::function &fn) const; + inline void foreach_scc(const std::function &follows, const std::function &fn) const; + inline isl::pw_multi_aff_list insert(unsigned int pos, isl::pw_multi_aff el) const; + inline isl::pw_multi_aff_list set_at(int index, isl::pw_multi_aff el) const; + inline unsigned size() const; +}; + +// declarations for isl::schedule +inline schedule manage(__isl_take isl_schedule *ptr); +inline schedule manage_copy(__isl_keep isl_schedule *ptr); + +class schedule { + friend inline schedule manage(__isl_take isl_schedule *ptr); + friend inline schedule manage_copy(__isl_keep isl_schedule *ptr); + +protected: + isl_schedule *ptr = nullptr; + + inline explicit schedule(__isl_take isl_schedule *ptr); + +public: + inline /* implicit */ schedule(); + inline /* implicit */ schedule(const schedule &obj); + inline explicit schedule(isl::ctx ctx, const std::string &str); + inline schedule &operator=(schedule obj); + inline ~schedule(); + inline __isl_give isl_schedule *copy() const &; + inline __isl_give isl_schedule *copy() && = delete; + inline __isl_keep isl_schedule *get() const; + inline __isl_give isl_schedule *release(); + inline bool is_null() const; + inline isl::ctx ctx() const; + + inline isl::union_set domain() const; + inline isl::union_set get_domain() const; + static inline isl::schedule from_domain(isl::union_set domain); + inline isl::union_map map() const; + inline isl::union_map get_map() const; + inline isl::schedule pullback(isl::union_pw_multi_aff upma) const; + inline isl::schedule_node root() const; + inline isl::schedule_node get_root() const; +}; + +// declarations for isl::schedule_constraints +inline schedule_constraints manage(__isl_take isl_schedule_constraints *ptr); +inline schedule_constraints manage_copy(__isl_keep isl_schedule_constraints *ptr); + +class schedule_constraints { + friend inline schedule_constraints manage(__isl_take isl_schedule_constraints *ptr); + friend inline schedule_constraints manage_copy(__isl_keep isl_schedule_constraints *ptr); + +protected: + isl_schedule_constraints *ptr = nullptr; + + inline explicit schedule_constraints(__isl_take isl_schedule_constraints *ptr); + +public: + inline /* implicit */ schedule_constraints(); + inline /* implicit */ schedule_constraints(const schedule_constraints &obj); + inline explicit schedule_constraints(isl::ctx ctx, const std::string &str); + inline schedule_constraints &operator=(schedule_constraints obj); + inline ~schedule_constraints(); + inline __isl_give isl_schedule_constraints *copy() const &; + inline __isl_give isl_schedule_constraints *copy() && = delete; + inline __isl_keep isl_schedule_constraints *get() const; + inline __isl_give isl_schedule_constraints *release(); + inline bool is_null() const; + inline isl::ctx ctx() const; + + inline isl::union_map coincidence() const; + inline isl::union_map get_coincidence() const; + inline isl::schedule compute_schedule() const; + inline isl::union_map conditional_validity() const; + inline isl::union_map get_conditional_validity() const; + inline isl::union_map conditional_validity_condition() const; + inline isl::union_map get_conditional_validity_condition() const; + inline isl::set context() const; + inline isl::set get_context() const; + inline isl::union_set domain() const; + inline isl::union_set get_domain() const; + static inline isl::schedule_constraints on_domain(isl::union_set domain); + inline isl::union_map proximity() const; + inline isl::union_map get_proximity() const; + inline isl::schedule_constraints set_coincidence(isl::union_map coincidence) const; + inline isl::schedule_constraints set_conditional_validity(isl::union_map condition, isl::union_map validity) const; + inline isl::schedule_constraints set_context(isl::set context) const; + inline isl::schedule_constraints set_proximity(isl::union_map proximity) const; + inline isl::schedule_constraints set_validity(isl::union_map validity) const; + inline isl::union_map validity() const; + inline isl::union_map get_validity() const; +}; + +// declarations for isl::schedule_node +inline schedule_node manage(__isl_take isl_schedule_node *ptr); +inline schedule_node manage_copy(__isl_keep isl_schedule_node *ptr); + +class schedule_node { + friend inline schedule_node manage(__isl_take isl_schedule_node *ptr); + friend inline schedule_node manage_copy(__isl_keep isl_schedule_node *ptr); + +protected: + isl_schedule_node *ptr = nullptr; + + inline explicit schedule_node(__isl_take isl_schedule_node *ptr); + +public: + inline /* implicit */ schedule_node(); + inline /* implicit */ schedule_node(const schedule_node &obj); + inline schedule_node &operator=(schedule_node obj); + inline ~schedule_node(); + inline __isl_give isl_schedule_node *copy() const &; + inline __isl_give isl_schedule_node *copy() && = delete; + inline __isl_keep isl_schedule_node *get() const; + inline __isl_give isl_schedule_node *release(); + inline bool is_null() const; +private: + template ::value>::type> + inline bool isa_type(T subtype) const; +public: + template inline bool isa() const; + template inline T as() const; + inline isl::ctx ctx() const; + + inline isl::schedule_node ancestor(int generation) const; + inline unsigned ancestor_child_position(const isl::schedule_node &ancestor) const; + inline unsigned get_ancestor_child_position(const isl::schedule_node &ancestor) const; + inline isl::schedule_node child(int pos) const; + inline unsigned child_position() const; + inline unsigned get_child_position() const; + inline bool every_descendant(const std::function &test) const; + inline isl::schedule_node first_child() const; + inline void foreach_ancestor_top_down(const std::function &fn) const; + inline void foreach_descendant_top_down(const std::function &fn) const; + static inline isl::schedule_node from_domain(isl::union_set domain); + static inline isl::schedule_node from_extension(isl::union_map extension); + inline isl::schedule_node graft_after(isl::schedule_node graft) const; + inline isl::schedule_node graft_before(isl::schedule_node graft) const; + inline bool has_children() const; + inline bool has_next_sibling() const; + inline bool has_parent() const; + inline bool has_previous_sibling() const; + inline isl::schedule_node insert_context(isl::set context) const; + inline isl::schedule_node insert_filter(isl::union_set filter) const; + inline isl::schedule_node insert_guard(isl::set context) const; + inline isl::schedule_node insert_mark(isl::id mark) const; + inline isl::schedule_node insert_mark(const std::string &mark) const; + inline isl::schedule_node insert_partial_schedule(isl::multi_union_pw_aff schedule) const; + inline isl::schedule_node insert_sequence(isl::union_set_list filters) const; + inline isl::schedule_node insert_set(isl::union_set_list filters) const; + inline bool is_equal(const isl::schedule_node &node2) const; + inline bool is_subtree_anchored() const; + inline isl::schedule_node map_descendant_bottom_up(const std::function &fn) const; + inline unsigned n_children() const; + inline isl::schedule_node next_sibling() const; + inline isl::schedule_node order_after(isl::union_set filter) const; + inline isl::schedule_node order_before(isl::union_set filter) const; + inline isl::schedule_node parent() const; + inline isl::multi_union_pw_aff prefix_schedule_multi_union_pw_aff() const; + inline isl::multi_union_pw_aff get_prefix_schedule_multi_union_pw_aff() const; + inline isl::union_map prefix_schedule_union_map() const; + inline isl::union_map get_prefix_schedule_union_map() const; + inline isl::union_pw_multi_aff prefix_schedule_union_pw_multi_aff() const; + inline isl::union_pw_multi_aff get_prefix_schedule_union_pw_multi_aff() const; + inline isl::schedule_node previous_sibling() const; + inline isl::schedule_node root() const; + inline isl::schedule schedule() const; + inline isl::schedule get_schedule() const; + inline isl::schedule_node shared_ancestor(const isl::schedule_node &node2) const; + inline isl::schedule_node get_shared_ancestor(const isl::schedule_node &node2) const; + inline unsigned tree_depth() const; + inline unsigned get_tree_depth() const; +}; + +// declarations for isl::schedule_node_band + +class schedule_node_band : public schedule_node { + template + friend bool schedule_node::isa() const; + friend schedule_node_band schedule_node::as() const; + static const auto type = isl_schedule_node_band; + +protected: + inline explicit schedule_node_band(__isl_take isl_schedule_node *ptr); + +public: + inline /* implicit */ schedule_node_band(); + inline /* implicit */ schedule_node_band(const schedule_node_band &obj); + inline schedule_node_band &operator=(schedule_node_band obj); + inline isl::ctx ctx() const; + + inline isl::union_set ast_build_options() const; + inline isl::union_set get_ast_build_options() const; + inline isl::set ast_isolate_option() const; + inline isl::set get_ast_isolate_option() const; + inline bool member_get_coincident(int pos) const; + inline schedule_node_band member_set_coincident(int pos, int coincident) const; + inline schedule_node_band mod(isl::multi_val mv) const; + inline unsigned n_member() const; + inline isl::multi_union_pw_aff partial_schedule() const; + inline isl::multi_union_pw_aff get_partial_schedule() const; + inline bool permutable() const; + inline bool get_permutable() const; + inline schedule_node_band scale(isl::multi_val mv) const; + inline schedule_node_band scale_down(isl::multi_val mv) const; + inline schedule_node_band set_ast_build_options(isl::union_set options) const; + inline schedule_node_band set_permutable(int permutable) const; + inline schedule_node_band shift(isl::multi_union_pw_aff shift) const; + inline schedule_node_band split(int pos) const; + inline schedule_node_band tile(isl::multi_val sizes) const; + inline schedule_node_band member_set_ast_loop_default(int pos) const; + inline schedule_node_band member_set_ast_loop_atomic(int pos) const; + inline schedule_node_band member_set_ast_loop_unroll(int pos) const; + inline schedule_node_band member_set_ast_loop_separate(int pos) const; +}; + +// declarations for isl::schedule_node_context + +class schedule_node_context : public schedule_node { + template + friend bool schedule_node::isa() const; + friend schedule_node_context schedule_node::as() const; + static const auto type = isl_schedule_node_context; + +protected: + inline explicit schedule_node_context(__isl_take isl_schedule_node *ptr); + +public: + inline /* implicit */ schedule_node_context(); + inline /* implicit */ schedule_node_context(const schedule_node_context &obj); + inline schedule_node_context &operator=(schedule_node_context obj); + inline isl::ctx ctx() const; + + inline isl::set context() const; + inline isl::set get_context() const; +}; + +// declarations for isl::schedule_node_domain + +class schedule_node_domain : public schedule_node { + template + friend bool schedule_node::isa() const; + friend schedule_node_domain schedule_node::as() const; + static const auto type = isl_schedule_node_domain; + +protected: + inline explicit schedule_node_domain(__isl_take isl_schedule_node *ptr); + +public: + inline /* implicit */ schedule_node_domain(); + inline /* implicit */ schedule_node_domain(const schedule_node_domain &obj); + inline schedule_node_domain &operator=(schedule_node_domain obj); + inline isl::ctx ctx() const; + + inline isl::union_set domain() const; + inline isl::union_set get_domain() const; +}; + +// declarations for isl::schedule_node_expansion + +class schedule_node_expansion : public schedule_node { + template + friend bool schedule_node::isa() const; + friend schedule_node_expansion schedule_node::as() const; + static const auto type = isl_schedule_node_expansion; + +protected: + inline explicit schedule_node_expansion(__isl_take isl_schedule_node *ptr); + +public: + inline /* implicit */ schedule_node_expansion(); + inline /* implicit */ schedule_node_expansion(const schedule_node_expansion &obj); + inline schedule_node_expansion &operator=(schedule_node_expansion obj); + inline isl::ctx ctx() const; + + inline isl::union_pw_multi_aff contraction() const; + inline isl::union_pw_multi_aff get_contraction() const; + inline isl::union_map expansion() const; + inline isl::union_map get_expansion() const; +}; + +// declarations for isl::schedule_node_extension + +class schedule_node_extension : public schedule_node { + template + friend bool schedule_node::isa() const; + friend schedule_node_extension schedule_node::as() const; + static const auto type = isl_schedule_node_extension; + +protected: + inline explicit schedule_node_extension(__isl_take isl_schedule_node *ptr); + +public: + inline /* implicit */ schedule_node_extension(); + inline /* implicit */ schedule_node_extension(const schedule_node_extension &obj); + inline schedule_node_extension &operator=(schedule_node_extension obj); + inline isl::ctx ctx() const; + + inline isl::union_map extension() const; + inline isl::union_map get_extension() const; +}; + +// declarations for isl::schedule_node_filter + +class schedule_node_filter : public schedule_node { + template + friend bool schedule_node::isa() const; + friend schedule_node_filter schedule_node::as() const; + static const auto type = isl_schedule_node_filter; + +protected: + inline explicit schedule_node_filter(__isl_take isl_schedule_node *ptr); + +public: + inline /* implicit */ schedule_node_filter(); + inline /* implicit */ schedule_node_filter(const schedule_node_filter &obj); + inline schedule_node_filter &operator=(schedule_node_filter obj); + inline isl::ctx ctx() const; + + inline isl::union_set filter() const; + inline isl::union_set get_filter() const; +}; + +// declarations for isl::schedule_node_guard + +class schedule_node_guard : public schedule_node { + template + friend bool schedule_node::isa() const; + friend schedule_node_guard schedule_node::as() const; + static const auto type = isl_schedule_node_guard; + +protected: + inline explicit schedule_node_guard(__isl_take isl_schedule_node *ptr); + +public: + inline /* implicit */ schedule_node_guard(); + inline /* implicit */ schedule_node_guard(const schedule_node_guard &obj); + inline schedule_node_guard &operator=(schedule_node_guard obj); + inline isl::ctx ctx() const; + + inline isl::set guard() const; + inline isl::set get_guard() const; +}; + +// declarations for isl::schedule_node_leaf + +class schedule_node_leaf : public schedule_node { + template + friend bool schedule_node::isa() const; + friend schedule_node_leaf schedule_node::as() const; + static const auto type = isl_schedule_node_leaf; + +protected: + inline explicit schedule_node_leaf(__isl_take isl_schedule_node *ptr); + +public: + inline /* implicit */ schedule_node_leaf(); + inline /* implicit */ schedule_node_leaf(const schedule_node_leaf &obj); + inline schedule_node_leaf &operator=(schedule_node_leaf obj); + inline isl::ctx ctx() const; + +}; + +// declarations for isl::schedule_node_mark + +class schedule_node_mark : public schedule_node { + template + friend bool schedule_node::isa() const; + friend schedule_node_mark schedule_node::as() const; + static const auto type = isl_schedule_node_mark; + +protected: + inline explicit schedule_node_mark(__isl_take isl_schedule_node *ptr); + +public: + inline /* implicit */ schedule_node_mark(); + inline /* implicit */ schedule_node_mark(const schedule_node_mark &obj); + inline schedule_node_mark &operator=(schedule_node_mark obj); + inline isl::ctx ctx() const; + +}; + +// declarations for isl::schedule_node_sequence + +class schedule_node_sequence : public schedule_node { + template + friend bool schedule_node::isa() const; + friend schedule_node_sequence schedule_node::as() const; + static const auto type = isl_schedule_node_sequence; + +protected: + inline explicit schedule_node_sequence(__isl_take isl_schedule_node *ptr); + +public: + inline /* implicit */ schedule_node_sequence(); + inline /* implicit */ schedule_node_sequence(const schedule_node_sequence &obj); + inline schedule_node_sequence &operator=(schedule_node_sequence obj); + inline isl::ctx ctx() const; + +}; + +// declarations for isl::schedule_node_set + +class schedule_node_set : public schedule_node { + template + friend bool schedule_node::isa() const; + friend schedule_node_set schedule_node::as() const; + static const auto type = isl_schedule_node_set; + +protected: + inline explicit schedule_node_set(__isl_take isl_schedule_node *ptr); + +public: + inline /* implicit */ schedule_node_set(); + inline /* implicit */ schedule_node_set(const schedule_node_set &obj); + inline schedule_node_set &operator=(schedule_node_set obj); + inline isl::ctx ctx() const; + +}; + +// declarations for isl::set +inline set manage(__isl_take isl_set *ptr); +inline set manage_copy(__isl_keep isl_set *ptr); + +class set { + friend inline set manage(__isl_take isl_set *ptr); + friend inline set manage_copy(__isl_keep isl_set *ptr); + +protected: + isl_set *ptr = nullptr; + + inline explicit set(__isl_take isl_set *ptr); + +public: + inline /* implicit */ set(); + inline /* implicit */ set(const set &obj); + inline /* implicit */ set(isl::basic_set bset); + inline /* implicit */ set(isl::point pnt); + inline explicit set(isl::ctx ctx, const std::string &str); + inline set &operator=(set obj); + inline ~set(); + inline __isl_give isl_set *copy() const &; + inline __isl_give isl_set *copy() && = delete; + inline __isl_keep isl_set *get() const; + inline __isl_give isl_set *release(); + inline bool is_null() const; + inline isl::ctx ctx() const; + + inline isl::basic_set affine_hull() const; + inline isl::set apply(isl::map map) const; + inline isl::union_set apply(const isl::union_map &umap) const; + inline isl::set apply(const isl::basic_map &map) const; + inline isl::pw_multi_aff as_pw_multi_aff() const; + inline isl::set as_set() const; + inline isl::set bind(isl::multi_id tuple) const; + inline isl::set coalesce() const; + inline isl::set complement() const; + inline isl::union_set compute_divs() const; + inline isl::set detect_equalities() const; + inline isl::val dim_max_val(int pos) const; + inline isl::val dim_min_val(int pos) const; + inline isl::set drop_unused_params() const; + static inline isl::set empty(isl::space space); + inline bool every_set(const std::function &test) const; + inline isl::set extract_set(const isl::space &space) const; + inline isl::set flatten() const; + inline void foreach_basic_set(const std::function &fn) const; + inline void foreach_point(const std::function &fn) const; + inline void foreach_set(const std::function &fn) const; + inline isl::set gist(isl::set context) const; + inline isl::union_set gist(const isl::union_set &context) const; + inline isl::set gist(const isl::basic_set &context) const; + inline isl::set gist(const isl::point &context) const; + inline isl::set gist_params(isl::set context) const; + inline isl::map identity() const; + inline isl::pw_aff indicator_function() const; + inline isl::map insert_domain(isl::space domain) const; + inline isl::set intersect(isl::set set2) const; + inline isl::union_set intersect(const isl::union_set &uset2) const; + inline isl::set intersect(const isl::basic_set &set2) const; + inline isl::set intersect(const isl::point &set2) const; + inline isl::set intersect_params(isl::set params) const; + inline bool involves_locals() const; + inline bool is_disjoint(const isl::set &set2) const; + inline bool is_disjoint(const isl::union_set &uset2) const; + inline bool is_disjoint(const isl::basic_set &set2) const; + inline bool is_disjoint(const isl::point &set2) const; + inline bool is_empty() const; + inline bool is_equal(const isl::set &set2) const; + inline bool is_equal(const isl::union_set &uset2) const; + inline bool is_equal(const isl::basic_set &set2) const; + inline bool is_equal(const isl::point &set2) const; + inline bool is_singleton() const; + inline bool is_strict_subset(const isl::set &set2) const; + inline bool is_strict_subset(const isl::union_set &uset2) const; + inline bool is_strict_subset(const isl::basic_set &set2) const; + inline bool is_strict_subset(const isl::point &set2) const; + inline bool is_subset(const isl::set &set2) const; + inline bool is_subset(const isl::union_set &uset2) const; + inline bool is_subset(const isl::basic_set &set2) const; + inline bool is_subset(const isl::point &set2) const; + inline bool is_wrapping() const; + inline bool isa_set() const; + inline isl::fixed_box lattice_tile() const; + inline isl::fixed_box get_lattice_tile() const; + inline isl::set lexmax() const; + inline isl::pw_multi_aff lexmax_pw_multi_aff() const; + inline isl::set lexmin() const; + inline isl::pw_multi_aff lexmin_pw_multi_aff() const; + inline isl::set lower_bound(isl::multi_pw_aff lower) const; + inline isl::set lower_bound(isl::multi_val lower) const; + inline isl::multi_pw_aff max_multi_pw_aff() const; + inline isl::val max_val(const isl::aff &obj) const; + inline isl::multi_pw_aff min_multi_pw_aff() const; + inline isl::val min_val(const isl::aff &obj) const; + inline unsigned n_basic_set() const; + inline isl::pw_aff param_pw_aff_on_domain(isl::id id) const; + inline isl::pw_aff param_pw_aff_on_domain(const std::string &id) const; + inline isl::set params() const; + inline isl::multi_val plain_multi_val_if_fixed() const; + inline isl::multi_val get_plain_multi_val_if_fixed() const; + inline isl::basic_set polyhedral_hull() const; + inline isl::set preimage(isl::multi_aff ma) const; + inline isl::set preimage(isl::multi_pw_aff mpa) const; + inline isl::set preimage(isl::pw_multi_aff pma) const; + inline isl::union_set preimage(const isl::union_pw_multi_aff &upma) const; + inline isl::set product(isl::set set2) const; + inline isl::set project_out_all_params() const; + inline isl::set project_out_param(isl::id id) const; + inline isl::set project_out_param(const std::string &id) const; + inline isl::set project_out_param(isl::id_list list) const; + inline isl::pw_aff pw_aff_on_domain(isl::val v) const; + inline isl::pw_aff pw_aff_on_domain(long v) const; + inline isl::pw_multi_aff pw_multi_aff_on_domain(isl::multi_val mv) const; + inline isl::basic_set sample() const; + inline isl::point sample_point() const; + inline isl::set_list set_list() const; + inline isl::fixed_box simple_fixed_box_hull() const; + inline isl::fixed_box get_simple_fixed_box_hull() const; + inline isl::space space() const; + inline isl::space get_space() const; + inline isl::val stride(int pos) const; + inline isl::val get_stride(int pos) const; + inline isl::set subtract(isl::set set2) const; + inline isl::union_set subtract(const isl::union_set &uset2) const; + inline isl::set subtract(const isl::basic_set &set2) const; + inline isl::set subtract(const isl::point &set2) const; + inline isl::set_list to_list() const; + inline isl::union_set to_union_set() const; + inline isl::map translation() const; + inline unsigned tuple_dim() const; + inline isl::set unbind_params(isl::multi_id tuple) const; + inline isl::map unbind_params_insert_domain(isl::multi_id domain) const; + inline isl::set unite(isl::set set2) const; + inline isl::union_set unite(const isl::union_set &uset2) const; + inline isl::set unite(const isl::basic_set &set2) const; + inline isl::set unite(const isl::point &set2) const; + static inline isl::set universe(isl::space space); + inline isl::basic_set unshifted_simple_hull() const; + inline isl::map unwrap() const; + inline isl::set upper_bound(isl::multi_pw_aff upper) const; + inline isl::set upper_bound(isl::multi_val upper) const; + inline isl::set wrapped_reverse() const; +}; + +// declarations for isl::set_list +inline set_list manage(__isl_take isl_set_list *ptr); +inline set_list manage_copy(__isl_keep isl_set_list *ptr); + +class set_list { + friend inline set_list manage(__isl_take isl_set_list *ptr); + friend inline set_list manage_copy(__isl_keep isl_set_list *ptr); + +protected: + isl_set_list *ptr = nullptr; + + inline explicit set_list(__isl_take isl_set_list *ptr); + +public: + inline /* implicit */ set_list(); + inline /* implicit */ set_list(const set_list &obj); + inline explicit set_list(isl::ctx ctx, int n); + inline explicit set_list(isl::set el); + inline explicit set_list(isl::ctx ctx, const std::string &str); + inline set_list &operator=(set_list obj); + inline ~set_list(); + inline __isl_give isl_set_list *copy() const &; + inline __isl_give isl_set_list *copy() && = delete; + inline __isl_keep isl_set_list *get() const; + inline __isl_give isl_set_list *release(); + inline bool is_null() const; + inline isl::ctx ctx() const; + + inline isl::set_list add(isl::set el) const; + inline isl::set at(int index) const; + inline isl::set get_at(int index) const; + inline isl::set_list clear() const; + inline isl::set_list concat(isl::set_list list2) const; + inline isl::set_list drop(unsigned int first, unsigned int n) const; + inline void foreach(const std::function &fn) const; + inline void foreach_scc(const std::function &follows, const std::function &fn) const; + inline isl::set_list insert(unsigned int pos, isl::set el) const; + inline isl::set_list set_at(int index, isl::set el) const; + inline unsigned size() const; +}; + +// declarations for isl::space +inline space manage(__isl_take isl_space *ptr); +inline space manage_copy(__isl_keep isl_space *ptr); + +class space { + friend inline space manage(__isl_take isl_space *ptr); + friend inline space manage_copy(__isl_keep isl_space *ptr); + +protected: + isl_space *ptr = nullptr; + + inline explicit space(__isl_take isl_space *ptr); + +public: + inline /* implicit */ space(); + inline /* implicit */ space(const space &obj); + inline explicit space(isl::ctx ctx, const std::string &str); + inline space &operator=(space obj); + inline ~space(); + inline __isl_give isl_space *copy() const &; + inline __isl_give isl_space *copy() && = delete; + inline __isl_keep isl_space *get() const; + inline __isl_give isl_space *release(); + inline bool is_null() const; + inline isl::ctx ctx() const; + + inline isl::space add_named_tuple(isl::id tuple_id, unsigned int dim) const; + inline isl::space add_named_tuple(const std::string &tuple_id, unsigned int dim) const; + inline isl::space add_param(isl::id id) const; + inline isl::space add_param(const std::string &id) const; + inline isl::space add_unnamed_tuple(unsigned int dim) const; + inline isl::space curry() const; + inline isl::space domain() const; + inline isl::multi_aff domain_map_multi_aff() const; + inline isl::pw_multi_aff domain_map_pw_multi_aff() const; + inline isl::space domain_reverse() const; + inline isl::id domain_tuple_id() const; + inline isl::id get_domain_tuple_id() const; + inline isl::space drop_all_params() const; + inline isl::space flatten_domain() const; + inline isl::space flatten_range() const; + inline bool has_domain_tuple_id() const; + inline bool has_range_tuple_id() const; + inline isl::multi_aff identity_multi_aff_on_domain() const; + inline isl::multi_pw_aff identity_multi_pw_aff_on_domain() const; + inline isl::pw_multi_aff identity_pw_multi_aff_on_domain() const; + inline bool is_equal(const isl::space &space2) const; + inline bool is_wrapping() const; + inline isl::space map_from_set() const; + inline isl::multi_aff multi_aff(isl::aff_list list) const; + inline isl::multi_aff multi_aff_on_domain(isl::multi_val mv) const; + inline isl::multi_id multi_id(isl::id_list list) const; + inline isl::multi_pw_aff multi_pw_aff(isl::pw_aff_list list) const; + inline isl::multi_union_pw_aff multi_union_pw_aff(isl::union_pw_aff_list list) const; + inline isl::multi_val multi_val(isl::val_list list) const; + inline isl::aff param_aff_on_domain(isl::id id) const; + inline isl::aff param_aff_on_domain(const std::string &id) const; + inline isl::space params() const; + inline isl::space product(isl::space right) const; + inline isl::space range() const; + inline isl::multi_aff range_map_multi_aff() const; + inline isl::pw_multi_aff range_map_pw_multi_aff() const; + inline isl::space range_reverse() const; + inline isl::id range_tuple_id() const; + inline isl::id get_range_tuple_id() const; + inline isl::space reverse() const; + inline isl::space set_domain_tuple(isl::id id) const; + inline isl::space set_domain_tuple(const std::string &id) const; + inline isl::space set_range_tuple(isl::id id) const; + inline isl::space set_range_tuple(const std::string &id) const; + inline isl::space uncurry() const; + static inline isl::space unit(isl::ctx ctx); + inline isl::map universe_map() const; + inline isl::set universe_set() const; + inline isl::space unwrap() const; + inline isl::space wrap() const; + inline isl::space wrapped_reverse() const; + inline isl::aff zero_aff_on_domain() const; + inline isl::multi_aff zero_multi_aff() const; + inline isl::multi_pw_aff zero_multi_pw_aff() const; + inline isl::multi_union_pw_aff zero_multi_union_pw_aff() const; + inline isl::multi_val zero_multi_val() const; +}; + +// declarations for isl::union_access_info +inline union_access_info manage(__isl_take isl_union_access_info *ptr); +inline union_access_info manage_copy(__isl_keep isl_union_access_info *ptr); + +class union_access_info { + friend inline union_access_info manage(__isl_take isl_union_access_info *ptr); + friend inline union_access_info manage_copy(__isl_keep isl_union_access_info *ptr); + +protected: + isl_union_access_info *ptr = nullptr; + + inline explicit union_access_info(__isl_take isl_union_access_info *ptr); + +public: + inline /* implicit */ union_access_info(); + inline /* implicit */ union_access_info(const union_access_info &obj); + inline explicit union_access_info(isl::union_map sink); + inline union_access_info &operator=(union_access_info obj); + inline ~union_access_info(); + inline __isl_give isl_union_access_info *copy() const &; + inline __isl_give isl_union_access_info *copy() && = delete; + inline __isl_keep isl_union_access_info *get() const; + inline __isl_give isl_union_access_info *release(); + inline bool is_null() const; + inline isl::ctx ctx() const; + + inline isl::union_flow compute_flow() const; + inline isl::union_access_info set_kill(isl::union_map kill) const; + inline isl::union_access_info set_may_source(isl::union_map may_source) const; + inline isl::union_access_info set_must_source(isl::union_map must_source) const; + inline isl::union_access_info set_schedule(isl::schedule schedule) const; + inline isl::union_access_info set_schedule_map(isl::union_map schedule_map) const; +}; + +// declarations for isl::union_flow +inline union_flow manage(__isl_take isl_union_flow *ptr); +inline union_flow manage_copy(__isl_keep isl_union_flow *ptr); + +class union_flow { + friend inline union_flow manage(__isl_take isl_union_flow *ptr); + friend inline union_flow manage_copy(__isl_keep isl_union_flow *ptr); + +protected: + isl_union_flow *ptr = nullptr; + + inline explicit union_flow(__isl_take isl_union_flow *ptr); + +public: + inline /* implicit */ union_flow(); + inline /* implicit */ union_flow(const union_flow &obj); + inline union_flow &operator=(union_flow obj); + inline ~union_flow(); + inline __isl_give isl_union_flow *copy() const &; + inline __isl_give isl_union_flow *copy() && = delete; + inline __isl_keep isl_union_flow *get() const; + inline __isl_give isl_union_flow *release(); + inline bool is_null() const; + inline isl::ctx ctx() const; + + inline isl::union_map full_may_dependence() const; + inline isl::union_map get_full_may_dependence() const; + inline isl::union_map full_must_dependence() const; + inline isl::union_map get_full_must_dependence() const; + inline isl::union_map may_dependence() const; + inline isl::union_map get_may_dependence() const; + inline isl::union_map may_no_source() const; + inline isl::union_map get_may_no_source() const; + inline isl::union_map must_dependence() const; + inline isl::union_map get_must_dependence() const; + inline isl::union_map must_no_source() const; + inline isl::union_map get_must_no_source() const; +}; + +// declarations for isl::union_map +inline union_map manage(__isl_take isl_union_map *ptr); +inline union_map manage_copy(__isl_keep isl_union_map *ptr); + +class union_map { + friend inline union_map manage(__isl_take isl_union_map *ptr); + friend inline union_map manage_copy(__isl_keep isl_union_map *ptr); + +protected: + isl_union_map *ptr = nullptr; + + inline explicit union_map(__isl_take isl_union_map *ptr); + +public: + inline /* implicit */ union_map(); + inline /* implicit */ union_map(const union_map &obj); + inline /* implicit */ union_map(isl::basic_map bmap); + inline /* implicit */ union_map(isl::map map); + inline explicit union_map(isl::ctx ctx, const std::string &str); + inline union_map &operator=(union_map obj); + inline ~union_map(); + inline __isl_give isl_union_map *copy() const &; + inline __isl_give isl_union_map *copy() && = delete; + inline __isl_keep isl_union_map *get() const; + inline __isl_give isl_union_map *release(); + inline bool is_null() const; + inline isl::ctx ctx() const; + + inline isl::union_map affine_hull() const; + inline isl::union_map apply_domain(isl::union_map umap2) const; + inline isl::union_map apply_range(isl::union_map umap2) const; + inline isl::map as_map() const; + inline isl::multi_union_pw_aff as_multi_union_pw_aff() const; + inline isl::union_pw_multi_aff as_union_pw_multi_aff() const; + inline isl::union_set bind_range(isl::multi_id tuple) const; + inline isl::union_map coalesce() const; + inline isl::union_map compute_divs() const; + inline isl::union_map curry() const; + inline isl::union_set deltas() const; + inline isl::union_map detect_equalities() const; + inline isl::union_set domain() const; + inline isl::union_map domain_factor_domain() const; + inline isl::union_map domain_factor_range() const; + inline isl::union_map domain_map() const; + inline isl::union_pw_multi_aff domain_map_union_pw_multi_aff() const; + inline isl::union_map domain_product(isl::union_map umap2) const; + inline isl::union_map domain_reverse() const; + inline isl::union_map drop_unused_params() const; + static inline isl::union_map empty(isl::ctx ctx); + inline isl::union_map eq_at(isl::multi_union_pw_aff mupa) const; + inline bool every_map(const std::function &test) const; + inline isl::map extract_map(isl::space space) const; + inline isl::union_map factor_domain() const; + inline isl::union_map factor_range() const; + inline isl::union_map fixed_power(isl::val exp) const; + inline isl::union_map fixed_power(long exp) const; + inline void foreach_map(const std::function &fn) const; + static inline isl::union_map from(isl::multi_union_pw_aff mupa); + static inline isl::union_map from(isl::union_pw_multi_aff upma); + static inline isl::union_map from_domain(isl::union_set uset); + static inline isl::union_map from_domain_and_range(isl::union_set domain, isl::union_set range); + static inline isl::union_map from_range(isl::union_set uset); + inline isl::union_map gist(isl::union_map context) const; + inline isl::union_map gist_domain(isl::union_set uset) const; + inline isl::union_map gist_params(isl::set set) const; + inline isl::union_map gist_range(isl::union_set uset) const; + inline isl::union_map intersect(isl::union_map umap2) const; + inline isl::union_map intersect_domain(isl::space space) const; + inline isl::union_map intersect_domain(isl::union_set uset) const; + inline isl::union_map intersect_domain_factor_domain(isl::union_map factor) const; + inline isl::union_map intersect_domain_factor_range(isl::union_map factor) const; + inline isl::union_map intersect_domain_wrapped_domain(isl::union_set domain) const; + inline isl::union_map intersect_params(isl::set set) const; + inline isl::union_map intersect_range(isl::space space) const; + inline isl::union_map intersect_range(isl::union_set uset) const; + inline isl::union_map intersect_range_factor_domain(isl::union_map factor) const; + inline isl::union_map intersect_range_factor_range(isl::union_map factor) const; + inline isl::union_map intersect_range_wrapped_domain(isl::union_set domain) const; + inline bool is_bijective() const; + inline bool is_disjoint(const isl::union_map &umap2) const; + inline bool is_empty() const; + inline bool is_equal(const isl::union_map &umap2) const; + inline bool is_injective() const; + inline bool is_single_valued() const; + inline bool is_strict_subset(const isl::union_map &umap2) const; + inline bool is_subset(const isl::union_map &umap2) const; + inline bool isa_map() const; + inline isl::union_map lexmax() const; + inline isl::union_map lexmin() const; + inline isl::map_list map_list() const; + inline isl::map_list get_map_list() const; + inline isl::set params() const; + inline isl::union_map polyhedral_hull() const; + inline isl::union_map preimage_domain(isl::multi_aff ma) const; + inline isl::union_map preimage_domain(isl::multi_pw_aff mpa) const; + inline isl::union_map preimage_domain(isl::pw_multi_aff pma) const; + inline isl::union_map preimage_domain(isl::union_pw_multi_aff upma) const; + inline isl::union_map preimage_range(isl::multi_aff ma) const; + inline isl::union_map preimage_range(isl::pw_multi_aff pma) const; + inline isl::union_map preimage_range(isl::union_pw_multi_aff upma) const; + inline isl::union_map product(isl::union_map umap2) const; + inline isl::union_map project_out_all_params() const; + inline isl::union_map project_out_param(isl::id id) const; + inline isl::union_map project_out_param(const std::string &id) const; + inline isl::union_map project_out_param(isl::id_list list) const; + inline isl::union_set range() const; + inline isl::union_map range_factor_domain() const; + inline isl::union_map range_factor_range() const; + inline isl::union_map range_map() const; + inline isl::union_map range_product(isl::union_map umap2) const; + inline isl::union_map range_reverse() const; + inline isl::union_map reverse() const; + inline isl::space space() const; + inline isl::space get_space() const; + inline isl::union_map subtract(isl::union_map umap2) const; + inline isl::union_map subtract_domain(isl::union_set dom) const; + inline isl::union_map subtract_range(isl::union_set dom) const; + inline isl::union_map uncurry() const; + inline isl::union_map unite(isl::union_map umap2) const; + inline isl::union_map universe() const; + inline isl::union_set wrap() const; + inline isl::union_map zip() const; +}; + +// declarations for isl::union_pw_aff +inline union_pw_aff manage(__isl_take isl_union_pw_aff *ptr); +inline union_pw_aff manage_copy(__isl_keep isl_union_pw_aff *ptr); + +class union_pw_aff { + friend inline union_pw_aff manage(__isl_take isl_union_pw_aff *ptr); + friend inline union_pw_aff manage_copy(__isl_keep isl_union_pw_aff *ptr); + +protected: + isl_union_pw_aff *ptr = nullptr; + + inline explicit union_pw_aff(__isl_take isl_union_pw_aff *ptr); + +public: + inline /* implicit */ union_pw_aff(); + inline /* implicit */ union_pw_aff(const union_pw_aff &obj); + inline /* implicit */ union_pw_aff(isl::aff aff); + inline /* implicit */ union_pw_aff(isl::pw_aff pa); + inline explicit union_pw_aff(isl::ctx ctx, const std::string &str); + inline union_pw_aff &operator=(union_pw_aff obj); + inline ~union_pw_aff(); + inline __isl_give isl_union_pw_aff *copy() const &; + inline __isl_give isl_union_pw_aff *copy() && = delete; + inline __isl_keep isl_union_pw_aff *get() const; + inline __isl_give isl_union_pw_aff *release(); + inline bool is_null() const; + inline isl::ctx ctx() const; + + inline isl::multi_union_pw_aff add(const isl::multi_union_pw_aff &multi2) const; + inline isl::union_pw_aff add(isl::union_pw_aff upa2) const; + inline isl::union_pw_multi_aff add(const isl::union_pw_multi_aff &upma2) const; + inline isl::union_pw_aff add(const isl::aff &upa2) const; + inline isl::union_pw_aff add(const isl::pw_aff &upa2) const; + inline isl::union_pw_multi_aff apply(const isl::union_pw_multi_aff &upma2) const; + inline isl::multi_union_pw_aff as_multi_union_pw_aff() const; + inline isl::pw_multi_aff as_pw_multi_aff() const; + inline isl::union_map as_union_map() const; + inline isl::union_pw_aff at(int pos) const; + inline isl::union_set bind(const isl::multi_id &tuple) const; + inline isl::union_set bind(isl::id id) const; + inline isl::union_set bind(const std::string &id) const; + inline isl::union_pw_aff coalesce() const; + inline isl::union_set domain() const; + inline isl::union_pw_aff drop_unused_params() const; + inline isl::pw_multi_aff extract_pw_multi_aff(const isl::space &space) const; + inline isl::multi_union_pw_aff flat_range_product(const isl::multi_union_pw_aff &multi2) const; + inline isl::union_pw_multi_aff flat_range_product(const isl::union_pw_multi_aff &upma2) const; + inline isl::union_pw_aff gist(isl::union_set context) const; + inline isl::multi_union_pw_aff gist_params(const isl::set &context) const; + inline bool has_range_tuple_id() const; + inline isl::union_pw_aff intersect_domain(isl::space space) const; + inline isl::union_pw_aff intersect_domain(isl::union_set uset) const; + inline isl::union_pw_aff intersect_domain_wrapped_domain(isl::union_set uset) const; + inline isl::union_pw_aff intersect_domain_wrapped_range(isl::union_set uset) const; + inline isl::union_pw_aff intersect_params(isl::set set) const; + inline bool involves_locals() const; + inline bool involves_nan() const; + inline bool isa_pw_multi_aff() const; + inline isl::union_pw_aff_list list() const; + inline isl::multi_union_pw_aff neg() const; + inline bool plain_is_empty() const; + inline bool plain_is_equal(const isl::multi_union_pw_aff &multi2) const; + inline bool plain_is_equal(const isl::union_pw_aff &upa2) const; + inline bool plain_is_equal(const isl::union_pw_multi_aff &upma2) const; + inline bool plain_is_equal(const isl::aff &upa2) const; + inline bool plain_is_equal(const isl::pw_aff &upa2) const; + inline isl::union_pw_multi_aff preimage_domain_wrapped_domain(const isl::union_pw_multi_aff &upma2) const; + inline isl::union_pw_aff pullback(isl::union_pw_multi_aff upma) const; + inline isl::pw_multi_aff_list pw_multi_aff_list() const; + inline isl::union_pw_multi_aff range_factor_domain() const; + inline isl::union_pw_multi_aff range_factor_range() const; + inline isl::multi_union_pw_aff range_product(const isl::multi_union_pw_aff &multi2) const; + inline isl::union_pw_multi_aff range_product(const isl::union_pw_multi_aff &upma2) const; + inline isl::id range_tuple_id() const; + inline isl::multi_union_pw_aff reset_range_tuple_id() const; + inline isl::multi_union_pw_aff scale(const isl::multi_val &mv) const; + inline isl::multi_union_pw_aff scale(const isl::val &v) const; + inline isl::multi_union_pw_aff scale(long v) const; + inline isl::multi_union_pw_aff scale_down(const isl::multi_val &mv) const; + inline isl::multi_union_pw_aff scale_down(const isl::val &v) const; + inline isl::multi_union_pw_aff scale_down(long v) const; + inline isl::multi_union_pw_aff set_at(int pos, const isl::union_pw_aff &el) const; + inline isl::multi_union_pw_aff set_range_tuple(const isl::id &id) const; + inline isl::multi_union_pw_aff set_range_tuple(const std::string &id) const; + inline unsigned size() const; + inline isl::space space() const; + inline isl::space get_space() const; + inline isl::multi_union_pw_aff sub(const isl::multi_union_pw_aff &multi2) const; + inline isl::union_pw_aff sub(isl::union_pw_aff upa2) const; + inline isl::union_pw_multi_aff sub(const isl::union_pw_multi_aff &upma2) const; + inline isl::union_pw_aff sub(const isl::aff &upa2) const; + inline isl::union_pw_aff sub(const isl::pw_aff &upa2) const; + inline isl::union_pw_aff subtract_domain(isl::space space) const; + inline isl::union_pw_aff subtract_domain(isl::union_set uset) const; + inline isl::union_pw_aff_list to_list() const; + inline isl::multi_union_pw_aff union_add(const isl::multi_union_pw_aff &mupa2) const; + inline isl::union_pw_aff union_add(isl::union_pw_aff upa2) const; + inline isl::union_pw_multi_aff union_add(const isl::union_pw_multi_aff &upma2) const; + inline isl::union_pw_aff union_add(const isl::aff &upa2) const; + inline isl::union_pw_aff union_add(const isl::pw_aff &upa2) const; +}; + +// declarations for isl::union_pw_aff_list +inline union_pw_aff_list manage(__isl_take isl_union_pw_aff_list *ptr); +inline union_pw_aff_list manage_copy(__isl_keep isl_union_pw_aff_list *ptr); + +class union_pw_aff_list { + friend inline union_pw_aff_list manage(__isl_take isl_union_pw_aff_list *ptr); + friend inline union_pw_aff_list manage_copy(__isl_keep isl_union_pw_aff_list *ptr); + +protected: + isl_union_pw_aff_list *ptr = nullptr; + + inline explicit union_pw_aff_list(__isl_take isl_union_pw_aff_list *ptr); + +public: + inline /* implicit */ union_pw_aff_list(); + inline /* implicit */ union_pw_aff_list(const union_pw_aff_list &obj); + inline explicit union_pw_aff_list(isl::ctx ctx, int n); + inline explicit union_pw_aff_list(isl::union_pw_aff el); + inline explicit union_pw_aff_list(isl::ctx ctx, const std::string &str); + inline union_pw_aff_list &operator=(union_pw_aff_list obj); + inline ~union_pw_aff_list(); + inline __isl_give isl_union_pw_aff_list *copy() const &; + inline __isl_give isl_union_pw_aff_list *copy() && = delete; + inline __isl_keep isl_union_pw_aff_list *get() const; + inline __isl_give isl_union_pw_aff_list *release(); + inline bool is_null() const; + inline isl::ctx ctx() const; + + inline isl::union_pw_aff_list add(isl::union_pw_aff el) const; + inline isl::union_pw_aff at(int index) const; + inline isl::union_pw_aff get_at(int index) const; + inline isl::union_pw_aff_list clear() const; + inline isl::union_pw_aff_list concat(isl::union_pw_aff_list list2) const; + inline isl::union_pw_aff_list drop(unsigned int first, unsigned int n) const; + inline void foreach(const std::function &fn) const; + inline void foreach_scc(const std::function &follows, const std::function &fn) const; + inline isl::union_pw_aff_list insert(unsigned int pos, isl::union_pw_aff el) const; + inline isl::union_pw_aff_list set_at(int index, isl::union_pw_aff el) const; + inline unsigned size() const; +}; + +// declarations for isl::union_pw_multi_aff +inline union_pw_multi_aff manage(__isl_take isl_union_pw_multi_aff *ptr); +inline union_pw_multi_aff manage_copy(__isl_keep isl_union_pw_multi_aff *ptr); + +class union_pw_multi_aff { + friend inline union_pw_multi_aff manage(__isl_take isl_union_pw_multi_aff *ptr); + friend inline union_pw_multi_aff manage_copy(__isl_keep isl_union_pw_multi_aff *ptr); + +protected: + isl_union_pw_multi_aff *ptr = nullptr; + + inline explicit union_pw_multi_aff(__isl_take isl_union_pw_multi_aff *ptr); + +public: + inline /* implicit */ union_pw_multi_aff(); + inline /* implicit */ union_pw_multi_aff(const union_pw_multi_aff &obj); + inline /* implicit */ union_pw_multi_aff(isl::multi_aff ma); + inline /* implicit */ union_pw_multi_aff(isl::pw_multi_aff pma); + inline /* implicit */ union_pw_multi_aff(isl::union_pw_aff upa); + inline explicit union_pw_multi_aff(isl::ctx ctx, const std::string &str); + inline union_pw_multi_aff &operator=(union_pw_multi_aff obj); + inline ~union_pw_multi_aff(); + inline __isl_give isl_union_pw_multi_aff *copy() const &; + inline __isl_give isl_union_pw_multi_aff *copy() && = delete; + inline __isl_keep isl_union_pw_multi_aff *get() const; + inline __isl_give isl_union_pw_multi_aff *release(); + inline bool is_null() const; + inline isl::ctx ctx() const; + + inline isl::union_pw_multi_aff add(isl::union_pw_multi_aff upma2) const; + inline isl::union_pw_multi_aff apply(isl::union_pw_multi_aff upma2) const; + inline isl::multi_union_pw_aff as_multi_union_pw_aff() const; + inline isl::pw_multi_aff as_pw_multi_aff() const; + inline isl::union_map as_union_map() const; + inline isl::union_pw_multi_aff coalesce() const; + inline isl::union_set domain() const; + inline isl::union_pw_multi_aff drop_unused_params() const; + static inline isl::union_pw_multi_aff empty(isl::ctx ctx); + inline isl::pw_multi_aff extract_pw_multi_aff(isl::space space) const; + inline isl::union_pw_multi_aff flat_range_product(isl::union_pw_multi_aff upma2) const; + inline isl::union_pw_multi_aff gist(isl::union_set context) const; + inline isl::union_pw_multi_aff intersect_domain(isl::space space) const; + inline isl::union_pw_multi_aff intersect_domain(isl::union_set uset) const; + inline isl::union_pw_multi_aff intersect_domain_wrapped_domain(isl::union_set uset) const; + inline isl::union_pw_multi_aff intersect_domain_wrapped_range(isl::union_set uset) const; + inline isl::union_pw_multi_aff intersect_params(isl::set set) const; + inline bool involves_locals() const; + inline bool isa_pw_multi_aff() const; + inline bool plain_is_empty() const; + inline bool plain_is_equal(const isl::union_pw_multi_aff &upma2) const; + inline isl::union_pw_multi_aff preimage_domain_wrapped_domain(isl::union_pw_multi_aff upma2) const; + inline isl::union_pw_multi_aff pullback(isl::union_pw_multi_aff upma2) const; + inline isl::pw_multi_aff_list pw_multi_aff_list() const; + inline isl::pw_multi_aff_list get_pw_multi_aff_list() const; + inline isl::union_pw_multi_aff range_factor_domain() const; + inline isl::union_pw_multi_aff range_factor_range() const; + inline isl::union_pw_multi_aff range_product(isl::union_pw_multi_aff upma2) const; + inline isl::space space() const; + inline isl::space get_space() const; + inline isl::union_pw_multi_aff sub(isl::union_pw_multi_aff upma2) const; + inline isl::union_pw_multi_aff subtract_domain(isl::space space) const; + inline isl::union_pw_multi_aff subtract_domain(isl::union_set uset) const; + inline isl::union_pw_multi_aff union_add(isl::union_pw_multi_aff upma2) const; +}; + +// declarations for isl::union_set +inline union_set manage(__isl_take isl_union_set *ptr); +inline union_set manage_copy(__isl_keep isl_union_set *ptr); + +class union_set { + friend inline union_set manage(__isl_take isl_union_set *ptr); + friend inline union_set manage_copy(__isl_keep isl_union_set *ptr); + +protected: + isl_union_set *ptr = nullptr; + + inline explicit union_set(__isl_take isl_union_set *ptr); + +public: + inline /* implicit */ union_set(); + inline /* implicit */ union_set(const union_set &obj); + inline /* implicit */ union_set(isl::basic_set bset); + inline /* implicit */ union_set(isl::point pnt); + inline /* implicit */ union_set(isl::set set); + inline explicit union_set(isl::ctx ctx, const std::string &str); + inline union_set &operator=(union_set obj); + inline ~union_set(); + inline __isl_give isl_union_set *copy() const &; + inline __isl_give isl_union_set *copy() && = delete; + inline __isl_keep isl_union_set *get() const; + inline __isl_give isl_union_set *release(); + inline bool is_null() const; + inline isl::ctx ctx() const; + + inline isl::union_set affine_hull() const; + inline isl::union_set apply(isl::union_map umap) const; + inline isl::set as_set() const; + inline isl::union_set coalesce() const; + inline isl::union_set compute_divs() const; + inline isl::union_set detect_equalities() const; + inline isl::union_set drop_unused_params() const; + static inline isl::union_set empty(isl::ctx ctx); + inline bool every_set(const std::function &test) const; + inline isl::set extract_set(isl::space space) const; + inline void foreach_point(const std::function &fn) const; + inline void foreach_set(const std::function &fn) const; + inline isl::union_set gist(isl::union_set context) const; + inline isl::union_set gist_params(isl::set set) const; + inline isl::union_map identity() const; + inline isl::union_set intersect(isl::union_set uset2) const; + inline isl::union_set intersect_params(isl::set set) const; + inline bool is_disjoint(const isl::union_set &uset2) const; + inline bool is_empty() const; + inline bool is_equal(const isl::union_set &uset2) const; + inline bool is_strict_subset(const isl::union_set &uset2) const; + inline bool is_subset(const isl::union_set &uset2) const; + inline bool isa_set() const; + inline isl::union_set lexmax() const; + inline isl::union_set lexmin() const; + inline isl::set params() const; + inline isl::union_set polyhedral_hull() const; + inline isl::union_set preimage(isl::multi_aff ma) const; + inline isl::union_set preimage(isl::pw_multi_aff pma) const; + inline isl::union_set preimage(isl::union_pw_multi_aff upma) const; + inline isl::union_set project_out_all_params() const; + inline isl::point sample_point() const; + inline isl::set_list set_list() const; + inline isl::set_list get_set_list() const; + inline isl::space space() const; + inline isl::space get_space() const; + inline isl::union_set subtract(isl::union_set uset2) const; + inline isl::union_set_list to_list() const; + inline isl::union_set unite(isl::union_set uset2) const; + inline isl::union_set universe() const; + inline isl::union_map unwrap() const; +}; + +// declarations for isl::union_set_list +inline union_set_list manage(__isl_take isl_union_set_list *ptr); +inline union_set_list manage_copy(__isl_keep isl_union_set_list *ptr); + +class union_set_list { + friend inline union_set_list manage(__isl_take isl_union_set_list *ptr); + friend inline union_set_list manage_copy(__isl_keep isl_union_set_list *ptr); + +protected: + isl_union_set_list *ptr = nullptr; + + inline explicit union_set_list(__isl_take isl_union_set_list *ptr); + +public: + inline /* implicit */ union_set_list(); + inline /* implicit */ union_set_list(const union_set_list &obj); + inline explicit union_set_list(isl::ctx ctx, int n); + inline explicit union_set_list(isl::union_set el); + inline explicit union_set_list(isl::ctx ctx, const std::string &str); + inline union_set_list &operator=(union_set_list obj); + inline ~union_set_list(); + inline __isl_give isl_union_set_list *copy() const &; + inline __isl_give isl_union_set_list *copy() && = delete; + inline __isl_keep isl_union_set_list *get() const; + inline __isl_give isl_union_set_list *release(); + inline bool is_null() const; + inline isl::ctx ctx() const; + + inline isl::union_set_list add(isl::union_set el) const; + inline isl::union_set at(int index) const; + inline isl::union_set get_at(int index) const; + inline isl::union_set_list clear() const; + inline isl::union_set_list concat(isl::union_set_list list2) const; + inline isl::union_set_list drop(unsigned int first, unsigned int n) const; + inline void foreach(const std::function &fn) const; + inline void foreach_scc(const std::function &follows, const std::function &fn) const; + inline isl::union_set_list insert(unsigned int pos, isl::union_set el) const; + inline isl::union_set_list set_at(int index, isl::union_set el) const; + inline unsigned size() const; +}; + +// declarations for isl::val +inline val manage(__isl_take isl_val *ptr); +inline val manage_copy(__isl_keep isl_val *ptr); + +class val { + friend inline val manage(__isl_take isl_val *ptr); + friend inline val manage_copy(__isl_keep isl_val *ptr); + +protected: + isl_val *ptr = nullptr; + + inline explicit val(__isl_take isl_val *ptr); + +public: + inline /* implicit */ val(); + inline /* implicit */ val(const val &obj); + inline explicit val(isl::ctx ctx, long i); + inline explicit val(isl::ctx ctx, const std::string &str); + inline val &operator=(val obj); + inline ~val(); + inline __isl_give isl_val *copy() const &; + inline __isl_give isl_val *copy() && = delete; + inline __isl_keep isl_val *get() const; + inline __isl_give isl_val *release(); + inline bool is_null() const; + inline isl::ctx ctx() const; + + inline isl::val abs() const; + inline bool abs_eq(const isl::val &v2) const; + inline bool abs_eq(long v2) const; + inline isl::val add(isl::val v2) const; + inline isl::val add(long v2) const; + inline isl::val ceil() const; + inline int cmp_si(long i) const; + inline long den_si() const; + inline long get_den_si() const; + inline isl::val div(isl::val v2) const; + inline isl::val div(long v2) const; + inline bool eq(const isl::val &v2) const; + inline bool eq(long v2) const; + inline isl::val floor() const; + inline isl::val gcd(isl::val v2) const; + inline isl::val gcd(long v2) const; + inline bool ge(const isl::val &v2) const; + inline bool ge(long v2) const; + inline bool gt(const isl::val &v2) const; + inline bool gt(long v2) const; + static inline isl::val infty(isl::ctx ctx); + inline isl::val inv() const; + inline bool is_divisible_by(const isl::val &v2) const; + inline bool is_divisible_by(long v2) const; + inline bool is_infty() const; + inline bool is_int() const; + inline bool is_nan() const; + inline bool is_neg() const; + inline bool is_neginfty() const; + inline bool is_negone() const; + inline bool is_nonneg() const; + inline bool is_nonpos() const; + inline bool is_one() const; + inline bool is_pos() const; + inline bool is_rat() const; + inline bool is_zero() const; + inline bool le(const isl::val &v2) const; + inline bool le(long v2) const; + inline bool lt(const isl::val &v2) const; + inline bool lt(long v2) const; + inline isl::val max(isl::val v2) const; + inline isl::val max(long v2) const; + inline isl::val min(isl::val v2) const; + inline isl::val min(long v2) const; + inline isl::val mod(isl::val v2) const; + inline isl::val mod(long v2) const; + inline isl::val mul(isl::val v2) const; + inline isl::val mul(long v2) const; + static inline isl::val nan(isl::ctx ctx); + inline bool ne(const isl::val &v2) const; + inline bool ne(long v2) const; + inline isl::val neg() const; + static inline isl::val neginfty(isl::ctx ctx); + static inline isl::val negone(isl::ctx ctx); + inline long num_si() const; + inline long get_num_si() const; + static inline isl::val one(isl::ctx ctx); + inline isl::val pow2() const; + inline int sgn() const; + inline isl::val sub(isl::val v2) const; + inline isl::val sub(long v2) const; + inline isl::val_list to_list() const; + inline isl::val trunc() const; + static inline isl::val zero(isl::ctx ctx); +}; + +// declarations for isl::val_list +inline val_list manage(__isl_take isl_val_list *ptr); +inline val_list manage_copy(__isl_keep isl_val_list *ptr); + +class val_list { + friend inline val_list manage(__isl_take isl_val_list *ptr); + friend inline val_list manage_copy(__isl_keep isl_val_list *ptr); + +protected: + isl_val_list *ptr = nullptr; + + inline explicit val_list(__isl_take isl_val_list *ptr); + +public: + inline /* implicit */ val_list(); + inline /* implicit */ val_list(const val_list &obj); + inline explicit val_list(isl::ctx ctx, int n); + inline explicit val_list(isl::val el); + inline explicit val_list(isl::ctx ctx, const std::string &str); + inline val_list &operator=(val_list obj); + inline ~val_list(); + inline __isl_give isl_val_list *copy() const &; + inline __isl_give isl_val_list *copy() && = delete; + inline __isl_keep isl_val_list *get() const; + inline __isl_give isl_val_list *release(); + inline bool is_null() const; + inline isl::ctx ctx() const; + + inline isl::val_list add(isl::val el) const; + inline isl::val_list add(long el) const; + inline isl::val at(int index) const; + inline isl::val get_at(int index) const; + inline isl::val_list clear() const; + inline isl::val_list concat(isl::val_list list2) const; + inline isl::val_list drop(unsigned int first, unsigned int n) const; + inline void foreach(const std::function &fn) const; + inline void foreach_scc(const std::function &follows, const std::function &fn) const; + inline isl::val_list insert(unsigned int pos, isl::val el) const; + inline isl::val_list insert(unsigned int pos, long el) const; + inline isl::val_list set_at(int index, isl::val el) const; + inline isl::val_list set_at(int index, long el) const; + inline unsigned size() const; +}; + +// implementations for isl::aff +aff manage(__isl_take isl_aff *ptr) { + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return aff(ptr); +} +aff manage_copy(__isl_keep isl_aff *ptr) { + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_aff_get_ctx(ptr); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + ptr = isl_aff_copy(ptr); + if (!ptr) + exception::throw_last_error(saved_ctx); + return aff(ptr); +} + +aff::aff(__isl_take isl_aff *ptr) + : ptr(ptr) {} + +aff::aff() + : ptr(nullptr) {} + +aff::aff(const aff &obj) + : ptr(nullptr) +{ + if (!obj.ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_aff_get_ctx(obj.ptr); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + ptr = obj.copy(); + if (!ptr) + exception::throw_last_error(saved_ctx); +} + +aff::aff(isl::ctx ctx, const std::string &str) +{ + auto saved_ctx = ctx; + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_aff_read_from_str(ctx.release(), str.c_str()); + if (!res) + exception::throw_last_error(saved_ctx); + ptr = res; +} + +aff &aff::operator=(aff obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +aff::~aff() { + if (ptr) + isl_aff_free(ptr); +} + +__isl_give isl_aff *aff::copy() const & { + return isl_aff_copy(ptr); +} + +__isl_keep isl_aff *aff::get() const { + return ptr; +} + +__isl_give isl_aff *aff::release() { + isl_aff *tmp = ptr; + ptr = nullptr; + return tmp; +} + +bool aff::is_null() const { + return ptr == nullptr; +} + +isl::ctx aff::ctx() const { + return isl::ctx(isl_aff_get_ctx(ptr)); +} + +isl::aff aff::add(isl::aff aff2) const +{ + if (!ptr || aff2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_aff_add(copy(), aff2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_aff aff::add(const isl::multi_aff &multi2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::multi_aff(*this).add(multi2); +} + +isl::multi_pw_aff aff::add(const isl::multi_pw_aff &multi2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_aff(*this).add(multi2); +} + +isl::multi_union_pw_aff aff::add(const isl::multi_union_pw_aff &multi2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_aff(*this).add(multi2); +} + +isl::pw_aff aff::add(const isl::pw_aff &pwaff2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_aff(*this).add(pwaff2); +} + +isl::pw_multi_aff aff::add(const isl::pw_multi_aff &pma2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_aff(*this).add(pma2); +} + +isl::union_pw_aff aff::add(const isl::union_pw_aff &upa2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_aff(*this).add(upa2); +} + +isl::union_pw_multi_aff aff::add(const isl::union_pw_multi_aff &upma2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_aff(*this).add(upma2); +} + +isl::aff aff::add_constant(isl::val v) const +{ + if (!ptr || v.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_aff_add_constant_val(copy(), v.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::aff aff::add_constant(long v) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->add_constant(isl::val(ctx(), v)); +} + +isl::multi_aff aff::add_constant(const isl::multi_val &mv) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::multi_aff(*this).add_constant(mv); +} + +isl::union_pw_multi_aff aff::apply(const isl::union_pw_multi_aff &upma2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_aff(*this).apply(upma2); +} + +isl::aff aff::as_aff() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_aff(*this).as_aff(); +} + +isl::map aff::as_map() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_aff(*this).as_map(); +} + +isl::multi_aff aff::as_multi_aff() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_aff(*this).as_multi_aff(); +} + +isl::multi_union_pw_aff aff::as_multi_union_pw_aff() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_aff(*this).as_multi_union_pw_aff(); +} + +isl::pw_multi_aff aff::as_pw_multi_aff() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_aff(*this).as_pw_multi_aff(); +} + +isl::set aff::as_set() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::multi_aff(*this).as_set(); +} + +isl::union_map aff::as_union_map() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_aff(*this).as_union_map(); +} + +isl::aff aff::at(int pos) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::multi_aff(*this).at(pos); +} + +isl::basic_set aff::bind(isl::id id) const +{ + if (!ptr || id.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_aff_bind_id(copy(), id.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::basic_set aff::bind(const std::string &id) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->bind(isl::id(ctx(), id)); +} + +isl::basic_set aff::bind(const isl::multi_id &tuple) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::multi_aff(*this).bind(tuple); +} + +isl::pw_aff aff::bind_domain(const isl::multi_id &tuple) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_aff(*this).bind_domain(tuple); +} + +isl::pw_aff aff::bind_domain_wrapped_domain(const isl::multi_id &tuple) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_aff(*this).bind_domain_wrapped_domain(tuple); +} + +isl::aff aff::ceil() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_aff_ceil(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::pw_aff aff::coalesce() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_aff(*this).coalesce(); +} + +isl::pw_aff aff::cond(const isl::pw_aff &pwaff_true, const isl::pw_aff &pwaff_false) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_aff(*this).cond(pwaff_true, pwaff_false); +} + +isl::multi_val aff::constant_multi_val() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::multi_aff(*this).constant_multi_val(); +} + +isl::val aff::constant_val() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_aff_get_constant_val(get()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::val aff::get_constant_val() const +{ + return constant_val(); +} + +isl::aff aff::div(isl::aff aff2) const +{ + if (!ptr || aff2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_aff_div(copy(), aff2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::pw_aff aff::div(const isl::pw_aff &pa2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_aff(*this).div(pa2); +} + +isl::set aff::domain() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_aff(*this).domain(); +} + +isl::aff aff::domain_reverse() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_aff_domain_reverse(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::pw_aff aff::drop_unused_params() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_aff(*this).drop_unused_params(); +} + +isl::set aff::eq_set(isl::aff aff2) const +{ + if (!ptr || aff2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_aff_eq_set(copy(), aff2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::set aff::eq_set(const isl::pw_aff &pwaff2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_aff(*this).eq_set(pwaff2); +} + +isl::val aff::eval(isl::point pnt) const +{ + if (!ptr || pnt.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_aff_eval(copy(), pnt.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::pw_multi_aff aff::extract_pw_multi_aff(const isl::space &space) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_aff(*this).extract_pw_multi_aff(space); +} + +isl::multi_aff aff::flat_range_product(const isl::multi_aff &multi2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::multi_aff(*this).flat_range_product(multi2); +} + +isl::multi_pw_aff aff::flat_range_product(const isl::multi_pw_aff &multi2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_aff(*this).flat_range_product(multi2); +} + +isl::multi_union_pw_aff aff::flat_range_product(const isl::multi_union_pw_aff &multi2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_aff(*this).flat_range_product(multi2); +} + +isl::pw_multi_aff aff::flat_range_product(const isl::pw_multi_aff &pma2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_aff(*this).flat_range_product(pma2); +} + +isl::union_pw_multi_aff aff::flat_range_product(const isl::union_pw_multi_aff &upma2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_aff(*this).flat_range_product(upma2); +} + +isl::aff aff::floor() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_aff_floor(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +void aff::foreach_piece(const std::function &fn) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_aff(*this).foreach_piece(fn); +} + +isl::set aff::ge_set(isl::aff aff2) const +{ + if (!ptr || aff2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_aff_ge_set(copy(), aff2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::set aff::ge_set(const isl::pw_aff &pwaff2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_aff(*this).ge_set(pwaff2); +} + +isl::aff aff::gist(isl::set context) const +{ + if (!ptr || context.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_aff_gist(copy(), context.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_pw_aff aff::gist(const isl::union_set &context) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_aff(*this).gist(context); +} + +isl::aff aff::gist(const isl::basic_set &context) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->gist(isl::set(context)); +} + +isl::aff aff::gist(const isl::point &context) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->gist(isl::set(context)); +} + +isl::aff aff::gist_params(isl::set context) const +{ + if (!ptr || context.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_aff_gist_params(copy(), context.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::set aff::gt_set(isl::aff aff2) const +{ + if (!ptr || aff2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_aff_gt_set(copy(), aff2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::set aff::gt_set(const isl::pw_aff &pwaff2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_aff(*this).gt_set(pwaff2); +} + +bool aff::has_range_tuple_id() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::multi_aff(*this).has_range_tuple_id(); +} + +isl::multi_aff aff::identity() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::multi_aff(*this).identity(); +} + +isl::pw_aff aff::insert_domain(const isl::space &domain) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_aff(*this).insert_domain(domain); +} + +isl::pw_aff aff::intersect_domain(const isl::set &set) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_aff(*this).intersect_domain(set); +} + +isl::union_pw_aff aff::intersect_domain(const isl::space &space) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_aff(*this).intersect_domain(space); +} + +isl::union_pw_aff aff::intersect_domain(const isl::union_set &uset) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_aff(*this).intersect_domain(uset); +} + +isl::union_pw_aff aff::intersect_domain_wrapped_domain(const isl::union_set &uset) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_aff(*this).intersect_domain_wrapped_domain(uset); +} + +isl::union_pw_aff aff::intersect_domain_wrapped_range(const isl::union_set &uset) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_aff(*this).intersect_domain_wrapped_range(uset); +} + +isl::pw_aff aff::intersect_params(const isl::set &set) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_aff(*this).intersect_params(set); +} + +bool aff::involves_locals() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::multi_aff(*this).involves_locals(); +} + +bool aff::involves_nan() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::multi_aff(*this).involves_nan(); +} + +bool aff::involves_param(const isl::id &id) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_aff(*this).involves_param(id); +} + +bool aff::involves_param(const std::string &id) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->involves_param(isl::id(ctx(), id)); +} + +bool aff::involves_param(const isl::id_list &list) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_aff(*this).involves_param(list); +} + +bool aff::is_cst() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_aff_is_cst(get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +bool aff::isa_aff() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_aff(*this).isa_aff(); +} + +bool aff::isa_multi_aff() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_aff(*this).isa_multi_aff(); +} + +bool aff::isa_pw_multi_aff() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_aff(*this).isa_pw_multi_aff(); +} + +isl::set aff::le_set(isl::aff aff2) const +{ + if (!ptr || aff2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_aff_le_set(copy(), aff2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::set aff::le_set(const isl::pw_aff &pwaff2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_aff(*this).le_set(pwaff2); +} + +isl::aff_list aff::list() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::multi_aff(*this).list(); +} + +isl::set aff::lt_set(isl::aff aff2) const +{ + if (!ptr || aff2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_aff_lt_set(copy(), aff2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::set aff::lt_set(const isl::pw_aff &pwaff2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_aff(*this).lt_set(pwaff2); +} + +isl::multi_pw_aff aff::max(const isl::multi_pw_aff &multi2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_aff(*this).max(multi2); +} + +isl::pw_aff aff::max(const isl::pw_aff &pwaff2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_aff(*this).max(pwaff2); +} + +isl::multi_val aff::max_multi_val() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_aff(*this).max_multi_val(); +} + +isl::val aff::max_val() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_aff(*this).max_val(); +} + +isl::multi_pw_aff aff::min(const isl::multi_pw_aff &multi2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_aff(*this).min(multi2); +} + +isl::pw_aff aff::min(const isl::pw_aff &pwaff2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_aff(*this).min(pwaff2); +} + +isl::multi_val aff::min_multi_val() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_aff(*this).min_multi_val(); +} + +isl::val aff::min_val() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_aff(*this).min_val(); +} + +isl::aff aff::mod(isl::val mod) const +{ + if (!ptr || mod.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_aff_mod_val(copy(), mod.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::aff aff::mod(long mod) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->mod(isl::val(ctx(), mod)); +} + +isl::aff aff::mul(isl::aff aff2) const +{ + if (!ptr || aff2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_aff_mul(copy(), aff2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::pw_aff aff::mul(const isl::pw_aff &pwaff2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_aff(*this).mul(pwaff2); +} + +unsigned aff::n_piece() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_aff(*this).n_piece(); +} + +isl::set aff::ne_set(isl::aff aff2) const +{ + if (!ptr || aff2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_aff_ne_set(copy(), aff2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::set aff::ne_set(const isl::pw_aff &pwaff2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_aff(*this).ne_set(pwaff2); +} + +isl::aff aff::neg() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_aff_neg(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::set aff::params() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_aff(*this).params(); +} + +bool aff::plain_is_empty() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_aff(*this).plain_is_empty(); +} + +bool aff::plain_is_equal(const isl::aff &aff2) const +{ + if (!ptr || aff2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_aff_plain_is_equal(get(), aff2.get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +bool aff::plain_is_equal(const isl::multi_aff &multi2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::multi_aff(*this).plain_is_equal(multi2); +} + +bool aff::plain_is_equal(const isl::multi_pw_aff &multi2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_aff(*this).plain_is_equal(multi2); +} + +bool aff::plain_is_equal(const isl::multi_union_pw_aff &multi2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_aff(*this).plain_is_equal(multi2); +} + +bool aff::plain_is_equal(const isl::pw_aff &pwaff2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_aff(*this).plain_is_equal(pwaff2); +} + +bool aff::plain_is_equal(const isl::pw_multi_aff &pma2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_aff(*this).plain_is_equal(pma2); +} + +bool aff::plain_is_equal(const isl::union_pw_aff &upa2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_aff(*this).plain_is_equal(upa2); +} + +bool aff::plain_is_equal(const isl::union_pw_multi_aff &upma2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_aff(*this).plain_is_equal(upma2); +} + +isl::pw_multi_aff aff::preimage_domain_wrapped_domain(const isl::pw_multi_aff &pma2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_aff(*this).preimage_domain_wrapped_domain(pma2); +} + +isl::union_pw_multi_aff aff::preimage_domain_wrapped_domain(const isl::union_pw_multi_aff &upma2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_aff(*this).preimage_domain_wrapped_domain(upma2); +} + +isl::multi_aff aff::product(const isl::multi_aff &multi2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::multi_aff(*this).product(multi2); +} + +isl::multi_pw_aff aff::product(const isl::multi_pw_aff &multi2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_aff(*this).product(multi2); +} + +isl::pw_multi_aff aff::product(const isl::pw_multi_aff &pma2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_aff(*this).product(pma2); +} + +isl::aff aff::pullback(isl::multi_aff ma) const +{ + if (!ptr || ma.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_aff_pullback_multi_aff(copy(), ma.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::pw_aff aff::pullback(const isl::multi_pw_aff &mpa) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_aff(*this).pullback(mpa); +} + +isl::pw_aff aff::pullback(const isl::pw_multi_aff &pma) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_aff(*this).pullback(pma); +} + +isl::union_pw_aff aff::pullback(const isl::union_pw_multi_aff &upma) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_aff(*this).pullback(upma); +} + +isl::aff aff::pullback(const isl::aff &ma) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->pullback(isl::multi_aff(ma)); +} + +isl::pw_multi_aff_list aff::pw_multi_aff_list() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_aff(*this).pw_multi_aff_list(); +} + +isl::pw_multi_aff aff::range_factor_domain() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_aff(*this).range_factor_domain(); +} + +isl::pw_multi_aff aff::range_factor_range() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_aff(*this).range_factor_range(); +} + +isl::multi_aff aff::range_product(const isl::multi_aff &multi2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::multi_aff(*this).range_product(multi2); +} + +isl::multi_pw_aff aff::range_product(const isl::multi_pw_aff &multi2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_aff(*this).range_product(multi2); +} + +isl::multi_union_pw_aff aff::range_product(const isl::multi_union_pw_aff &multi2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_aff(*this).range_product(multi2); +} + +isl::pw_multi_aff aff::range_product(const isl::pw_multi_aff &pma2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_aff(*this).range_product(pma2); +} + +isl::union_pw_multi_aff aff::range_product(const isl::union_pw_multi_aff &upma2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_aff(*this).range_product(upma2); +} + +isl::id aff::range_tuple_id() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::multi_aff(*this).range_tuple_id(); +} + +isl::multi_aff aff::reset_range_tuple_id() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::multi_aff(*this).reset_range_tuple_id(); +} + +isl::aff aff::scale(isl::val v) const +{ + if (!ptr || v.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_aff_scale_val(copy(), v.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::aff aff::scale(long v) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->scale(isl::val(ctx(), v)); +} + +isl::multi_aff aff::scale(const isl::multi_val &mv) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::multi_aff(*this).scale(mv); +} + +isl::aff aff::scale_down(isl::val v) const +{ + if (!ptr || v.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_aff_scale_down_val(copy(), v.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::aff aff::scale_down(long v) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->scale_down(isl::val(ctx(), v)); +} + +isl::multi_aff aff::scale_down(const isl::multi_val &mv) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::multi_aff(*this).scale_down(mv); +} + +isl::multi_aff aff::set_at(int pos, const isl::aff &el) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::multi_aff(*this).set_at(pos, el); +} + +isl::multi_pw_aff aff::set_at(int pos, const isl::pw_aff &el) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_aff(*this).set_at(pos, el); +} + +isl::multi_union_pw_aff aff::set_at(int pos, const isl::union_pw_aff &el) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_aff(*this).set_at(pos, el); +} + +isl::multi_aff aff::set_range_tuple(const isl::id &id) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::multi_aff(*this).set_range_tuple(id); +} + +isl::multi_aff aff::set_range_tuple(const std::string &id) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->set_range_tuple(isl::id(ctx(), id)); +} + +unsigned aff::size() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::multi_aff(*this).size(); +} + +isl::space aff::space() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_aff(*this).space(); +} + +isl::aff aff::sub(isl::aff aff2) const +{ + if (!ptr || aff2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_aff_sub(copy(), aff2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_aff aff::sub(const isl::multi_aff &multi2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::multi_aff(*this).sub(multi2); +} + +isl::multi_pw_aff aff::sub(const isl::multi_pw_aff &multi2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_aff(*this).sub(multi2); +} + +isl::multi_union_pw_aff aff::sub(const isl::multi_union_pw_aff &multi2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_aff(*this).sub(multi2); +} + +isl::pw_aff aff::sub(const isl::pw_aff &pwaff2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_aff(*this).sub(pwaff2); +} + +isl::pw_multi_aff aff::sub(const isl::pw_multi_aff &pma2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_aff(*this).sub(pma2); +} + +isl::union_pw_aff aff::sub(const isl::union_pw_aff &upa2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_aff(*this).sub(upa2); +} + +isl::union_pw_multi_aff aff::sub(const isl::union_pw_multi_aff &upma2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_aff(*this).sub(upma2); +} + +isl::pw_aff aff::subtract_domain(const isl::set &set) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_aff(*this).subtract_domain(set); +} + +isl::union_pw_aff aff::subtract_domain(const isl::space &space) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_aff(*this).subtract_domain(space); +} + +isl::union_pw_aff aff::subtract_domain(const isl::union_set &uset) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_aff(*this).subtract_domain(uset); +} + +isl::pw_aff aff::tdiv_q(const isl::pw_aff &pa2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_aff(*this).tdiv_q(pa2); +} + +isl::pw_aff aff::tdiv_r(const isl::pw_aff &pa2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_aff(*this).tdiv_r(pa2); +} + +isl::aff_list aff::to_list() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_aff_to_list(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_pw_aff aff::to_multi_pw_aff() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::multi_aff(*this).to_multi_pw_aff(); +} + +isl::multi_union_pw_aff aff::to_multi_union_pw_aff() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::multi_aff(*this).to_multi_union_pw_aff(); +} + +isl::pw_multi_aff aff::to_pw_multi_aff() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::multi_aff(*this).to_pw_multi_aff(); +} + +isl::union_pw_aff aff::to_union_pw_aff() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_aff(*this).to_union_pw_aff(); +} + +isl::union_pw_multi_aff aff::to_union_pw_multi_aff() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_aff(*this).to_union_pw_multi_aff(); +} + +isl::aff aff::unbind_params_insert_domain(isl::multi_id domain) const +{ + if (!ptr || domain.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_aff_unbind_params_insert_domain(copy(), domain.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_pw_aff aff::union_add(const isl::multi_pw_aff &mpa2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_aff(*this).union_add(mpa2); +} + +isl::multi_union_pw_aff aff::union_add(const isl::multi_union_pw_aff &mupa2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_aff(*this).union_add(mupa2); +} + +isl::pw_aff aff::union_add(const isl::pw_aff &pwaff2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_aff(*this).union_add(pwaff2); +} + +isl::pw_multi_aff aff::union_add(const isl::pw_multi_aff &pma2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_aff(*this).union_add(pma2); +} + +isl::union_pw_aff aff::union_add(const isl::union_pw_aff &upa2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_aff(*this).union_add(upa2); +} + +isl::union_pw_multi_aff aff::union_add(const isl::union_pw_multi_aff &upma2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_aff(*this).union_add(upma2); +} + +isl::aff aff::zero_on_domain(isl::space space) +{ + if (space.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = space.ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_aff_zero_on_domain_space(space.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +inline std::ostream &operator<<(std::ostream &os, const aff &obj) +{ + if (!obj.get()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_aff_get_ctx(obj.get()); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + char *str = isl_aff_to_str(obj.get()); + if (!str) + exception::throw_last_error(saved_ctx); + os << str; + free(str); + return os; +} + +// implementations for isl::aff_list +aff_list manage(__isl_take isl_aff_list *ptr) { + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return aff_list(ptr); +} +aff_list manage_copy(__isl_keep isl_aff_list *ptr) { + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_aff_list_get_ctx(ptr); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + ptr = isl_aff_list_copy(ptr); + if (!ptr) + exception::throw_last_error(saved_ctx); + return aff_list(ptr); +} + +aff_list::aff_list(__isl_take isl_aff_list *ptr) + : ptr(ptr) {} + +aff_list::aff_list() + : ptr(nullptr) {} + +aff_list::aff_list(const aff_list &obj) + : ptr(nullptr) +{ + if (!obj.ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_aff_list_get_ctx(obj.ptr); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + ptr = obj.copy(); + if (!ptr) + exception::throw_last_error(saved_ctx); +} + +aff_list::aff_list(isl::ctx ctx, int n) +{ + auto saved_ctx = ctx; + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_aff_list_alloc(ctx.release(), n); + if (!res) + exception::throw_last_error(saved_ctx); + ptr = res; +} + +aff_list::aff_list(isl::aff el) +{ + if (el.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = el.ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_aff_list_from_aff(el.release()); + if (!res) + exception::throw_last_error(saved_ctx); + ptr = res; +} + +aff_list::aff_list(isl::ctx ctx, const std::string &str) +{ + auto saved_ctx = ctx; + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_aff_list_read_from_str(ctx.release(), str.c_str()); + if (!res) + exception::throw_last_error(saved_ctx); + ptr = res; +} + +aff_list &aff_list::operator=(aff_list obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +aff_list::~aff_list() { + if (ptr) + isl_aff_list_free(ptr); +} + +__isl_give isl_aff_list *aff_list::copy() const & { + return isl_aff_list_copy(ptr); +} + +__isl_keep isl_aff_list *aff_list::get() const { + return ptr; +} + +__isl_give isl_aff_list *aff_list::release() { + isl_aff_list *tmp = ptr; + ptr = nullptr; + return tmp; +} + +bool aff_list::is_null() const { + return ptr == nullptr; +} + +isl::ctx aff_list::ctx() const { + return isl::ctx(isl_aff_list_get_ctx(ptr)); +} + +isl::aff_list aff_list::add(isl::aff el) const +{ + if (!ptr || el.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_aff_list_add(copy(), el.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::aff aff_list::at(int index) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_aff_list_get_at(get(), index); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::aff aff_list::get_at(int index) const +{ + return at(index); +} + +isl::aff_list aff_list::clear() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_aff_list_clear(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::aff_list aff_list::concat(isl::aff_list list2) const +{ + if (!ptr || list2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_aff_list_concat(copy(), list2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::aff_list aff_list::drop(unsigned int first, unsigned int n) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_aff_list_drop(copy(), first, n); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +void aff_list::foreach(const std::function &fn) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + struct fn_data { + std::function func; + std::exception_ptr eptr; + } fn_data = { fn }; + auto fn_lambda = [](isl_aff *arg_0, void *arg_1) -> isl_stat { + auto *data = static_cast(arg_1); + ISL_CPP_TRY { + (data->func)(manage(arg_0)); + return isl_stat_ok; + } ISL_CPP_CATCH_ALL { + data->eptr = std::current_exception(); + return isl_stat_error; + } + }; + auto res = isl_aff_list_foreach(get(), fn_lambda, &fn_data); + if (fn_data.eptr) + std::rethrow_exception(fn_data.eptr); + if (res < 0) + exception::throw_last_error(saved_ctx); + return; +} + +void aff_list::foreach_scc(const std::function &follows, const std::function &fn) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + struct follows_data { + std::function func; + std::exception_ptr eptr; + } follows_data = { follows }; + auto follows_lambda = [](isl_aff *arg_0, isl_aff *arg_1, void *arg_2) -> isl_bool { + auto *data = static_cast(arg_2); + ISL_CPP_TRY { + auto ret = (data->func)(manage_copy(arg_0), manage_copy(arg_1)); + return ret ? isl_bool_true : isl_bool_false; + } ISL_CPP_CATCH_ALL { + data->eptr = std::current_exception(); + return isl_bool_error; + } + }; + struct fn_data { + std::function func; + std::exception_ptr eptr; + } fn_data = { fn }; + auto fn_lambda = [](isl_aff_list *arg_0, void *arg_1) -> isl_stat { + auto *data = static_cast(arg_1); + ISL_CPP_TRY { + (data->func)(manage(arg_0)); + return isl_stat_ok; + } ISL_CPP_CATCH_ALL { + data->eptr = std::current_exception(); + return isl_stat_error; + } + }; + auto res = isl_aff_list_foreach_scc(get(), follows_lambda, &follows_data, fn_lambda, &fn_data); + if (follows_data.eptr) + std::rethrow_exception(follows_data.eptr); + if (fn_data.eptr) + std::rethrow_exception(fn_data.eptr); + if (res < 0) + exception::throw_last_error(saved_ctx); + return; +} + +isl::aff_list aff_list::insert(unsigned int pos, isl::aff el) const +{ + if (!ptr || el.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_aff_list_insert(copy(), pos, el.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::aff_list aff_list::set_at(int index, isl::aff el) const +{ + if (!ptr || el.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_aff_list_set_at(copy(), index, el.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +unsigned aff_list::size() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_aff_list_size(get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +inline std::ostream &operator<<(std::ostream &os, const aff_list &obj) +{ + if (!obj.get()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_aff_list_get_ctx(obj.get()); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + char *str = isl_aff_list_to_str(obj.get()); + if (!str) + exception::throw_last_error(saved_ctx); + os << str; + free(str); + return os; +} + +// implementations for isl::ast_build +ast_build manage(__isl_take isl_ast_build *ptr) { + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return ast_build(ptr); +} +ast_build manage_copy(__isl_keep isl_ast_build *ptr) { + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_ast_build_get_ctx(ptr); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + ptr = isl_ast_build_copy(ptr); + if (!ptr) + exception::throw_last_error(saved_ctx); + return ast_build(ptr); +} + +ast_build::ast_build(__isl_take isl_ast_build *ptr) + : ptr(ptr) {} + +ast_build::ast_build() + : ptr(nullptr) {} + +ast_build::ast_build(const ast_build &obj) + : ptr(nullptr) +{ + if (!obj.ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_ast_build_get_ctx(obj.ptr); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + ptr = obj.copy(); + copy_callbacks(obj); + if (!ptr) + exception::throw_last_error(saved_ctx); +} + +ast_build::ast_build(isl::ctx ctx) +{ + auto saved_ctx = ctx; + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_ast_build_alloc(ctx.release()); + if (!res) + exception::throw_last_error(saved_ctx); + ptr = res; +} + +ast_build &ast_build::operator=(ast_build obj) { + std::swap(this->ptr, obj.ptr); + copy_callbacks(obj); + return *this; +} + +ast_build::~ast_build() { + if (ptr) + isl_ast_build_free(ptr); +} + +__isl_give isl_ast_build *ast_build::copy() const & { + return isl_ast_build_copy(ptr); +} + +__isl_keep isl_ast_build *ast_build::get() const { + return ptr; +} + +__isl_give isl_ast_build *ast_build::release() { + if (at_each_domain_data) + exception::throw_invalid("cannot release object with persistent callbacks", __FILE__, __LINE__); + isl_ast_build *tmp = ptr; + ptr = nullptr; + return tmp; +} + +bool ast_build::is_null() const { + return ptr == nullptr; +} + +isl::ctx ast_build::ctx() const { + return isl::ctx(isl_ast_build_get_ctx(ptr)); +} + +ast_build &ast_build::copy_callbacks(const ast_build &obj) +{ + at_each_domain_data = obj.at_each_domain_data; + return *this; +} + +isl_ast_node *ast_build::at_each_domain(isl_ast_node *arg_0, isl_ast_build *arg_1, void *arg_2) +{ + auto *data = static_cast(arg_2); + ISL_CPP_TRY { + auto ret = (data->func)(manage(arg_0), manage_copy(arg_1)); + return ret.release(); + } ISL_CPP_CATCH_ALL { + data->eptr = std::current_exception(); + return NULL; + } +} + +void ast_build::set_at_each_domain_data(const std::function &fn) +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_ast_build_get_ctx(ptr); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + at_each_domain_data = std::make_shared(); + at_each_domain_data->func = fn; + ptr = isl_ast_build_set_at_each_domain(ptr, &at_each_domain, at_each_domain_data.get()); + if (!ptr) + exception::throw_last_error(saved_ctx); +} + +isl::ast_build ast_build::set_at_each_domain(const std::function &fn) const +{ + auto copy = *this; + copy.set_at_each_domain_data(fn); + return copy; +} + +isl::ast_expr ast_build::access_from(isl::multi_pw_aff mpa) const +{ + if (!ptr || mpa.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_ast_build_access_from_multi_pw_aff(get(), mpa.release()); + if (at_each_domain_data && at_each_domain_data->eptr) { + std::exception_ptr eptr = at_each_domain_data->eptr; + at_each_domain_data->eptr = nullptr; + std::rethrow_exception(eptr); + } + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::ast_expr ast_build::access_from(isl::pw_multi_aff pma) const +{ + if (!ptr || pma.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_ast_build_access_from_pw_multi_aff(get(), pma.release()); + if (at_each_domain_data && at_each_domain_data->eptr) { + std::exception_ptr eptr = at_each_domain_data->eptr; + at_each_domain_data->eptr = nullptr; + std::rethrow_exception(eptr); + } + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::ast_expr ast_build::call_from(isl::multi_pw_aff mpa) const +{ + if (!ptr || mpa.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_ast_build_call_from_multi_pw_aff(get(), mpa.release()); + if (at_each_domain_data && at_each_domain_data->eptr) { + std::exception_ptr eptr = at_each_domain_data->eptr; + at_each_domain_data->eptr = nullptr; + std::rethrow_exception(eptr); + } + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::ast_expr ast_build::call_from(isl::pw_multi_aff pma) const +{ + if (!ptr || pma.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_ast_build_call_from_pw_multi_aff(get(), pma.release()); + if (at_each_domain_data && at_each_domain_data->eptr) { + std::exception_ptr eptr = at_each_domain_data->eptr; + at_each_domain_data->eptr = nullptr; + std::rethrow_exception(eptr); + } + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::ast_expr ast_build::expr_from(isl::pw_aff pa) const +{ + if (!ptr || pa.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_ast_build_expr_from_pw_aff(get(), pa.release()); + if (at_each_domain_data && at_each_domain_data->eptr) { + std::exception_ptr eptr = at_each_domain_data->eptr; + at_each_domain_data->eptr = nullptr; + std::rethrow_exception(eptr); + } + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::ast_expr ast_build::expr_from(isl::set set) const +{ + if (!ptr || set.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_ast_build_expr_from_set(get(), set.release()); + if (at_each_domain_data && at_each_domain_data->eptr) { + std::exception_ptr eptr = at_each_domain_data->eptr; + at_each_domain_data->eptr = nullptr; + std::rethrow_exception(eptr); + } + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::ast_build ast_build::from_context(isl::set set) +{ + if (set.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = set.ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_ast_build_from_context(set.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::ast_node ast_build::node_from(isl::schedule schedule) const +{ + if (!ptr || schedule.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_ast_build_node_from_schedule(get(), schedule.release()); + if (at_each_domain_data && at_each_domain_data->eptr) { + std::exception_ptr eptr = at_each_domain_data->eptr; + at_each_domain_data->eptr = nullptr; + std::rethrow_exception(eptr); + } + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::ast_node ast_build::node_from_schedule_map(isl::union_map schedule) const +{ + if (!ptr || schedule.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_ast_build_node_from_schedule_map(get(), schedule.release()); + if (at_each_domain_data && at_each_domain_data->eptr) { + std::exception_ptr eptr = at_each_domain_data->eptr; + at_each_domain_data->eptr = nullptr; + std::rethrow_exception(eptr); + } + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map ast_build::schedule() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_ast_build_get_schedule(get()); + if (at_each_domain_data && at_each_domain_data->eptr) { + std::exception_ptr eptr = at_each_domain_data->eptr; + at_each_domain_data->eptr = nullptr; + std::rethrow_exception(eptr); + } + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map ast_build::get_schedule() const +{ + return schedule(); +} + +// implementations for isl::ast_expr +ast_expr manage(__isl_take isl_ast_expr *ptr) { + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return ast_expr(ptr); +} +ast_expr manage_copy(__isl_keep isl_ast_expr *ptr) { + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_ast_expr_get_ctx(ptr); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + ptr = isl_ast_expr_copy(ptr); + if (!ptr) + exception::throw_last_error(saved_ctx); + return ast_expr(ptr); +} + +ast_expr::ast_expr(__isl_take isl_ast_expr *ptr) + : ptr(ptr) {} + +ast_expr::ast_expr() + : ptr(nullptr) {} + +ast_expr::ast_expr(const ast_expr &obj) + : ptr(nullptr) +{ + if (!obj.ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_ast_expr_get_ctx(obj.ptr); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + ptr = obj.copy(); + if (!ptr) + exception::throw_last_error(saved_ctx); +} + +ast_expr &ast_expr::operator=(ast_expr obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +ast_expr::~ast_expr() { + if (ptr) + isl_ast_expr_free(ptr); +} + +__isl_give isl_ast_expr *ast_expr::copy() const & { + return isl_ast_expr_copy(ptr); +} + +__isl_keep isl_ast_expr *ast_expr::get() const { + return ptr; +} + +__isl_give isl_ast_expr *ast_expr::release() { + isl_ast_expr *tmp = ptr; + ptr = nullptr; + return tmp; +} + +bool ast_expr::is_null() const { + return ptr == nullptr; +} + +template +bool ast_expr::isa_type(T subtype) const +{ + if (is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl_ast_expr_get_type(get()) == subtype; +} +template +bool ast_expr::isa() const +{ + return isa_type(T::type); +} +template +T ast_expr::as() const +{ + if (!isa()) + exception::throw_invalid("not an object of the requested subtype", __FILE__, __LINE__); + return T(copy()); +} + +isl::ctx ast_expr::ctx() const { + return isl::ctx(isl_ast_expr_get_ctx(ptr)); +} + +std::string ast_expr::to_C_str() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_ast_expr_to_C_str(get()); + std::string tmp(res); + free(res); + return tmp; +} + +inline std::ostream &operator<<(std::ostream &os, const ast_expr &obj) +{ + if (!obj.get()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_ast_expr_get_ctx(obj.get()); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + char *str = isl_ast_expr_to_str(obj.get()); + if (!str) + exception::throw_last_error(saved_ctx); + os << str; + free(str); + return os; +} + +// implementations for isl::ast_expr_id +ast_expr_id::ast_expr_id(__isl_take isl_ast_expr *ptr) + : ast_expr(ptr) {} + +ast_expr_id::ast_expr_id() + : ast_expr() {} + +ast_expr_id::ast_expr_id(const ast_expr_id &obj) + : ast_expr(obj) +{ +} + +ast_expr_id &ast_expr_id::operator=(ast_expr_id obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +isl::ctx ast_expr_id::ctx() const { + return isl::ctx(isl_ast_expr_get_ctx(ptr)); +} + +isl::id ast_expr_id::id() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_ast_expr_id_get_id(get()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::id ast_expr_id::get_id() const +{ + return id(); +} + +inline std::ostream &operator<<(std::ostream &os, const ast_expr_id &obj) +{ + if (!obj.get()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_ast_expr_get_ctx(obj.get()); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + char *str = isl_ast_expr_to_str(obj.get()); + if (!str) + exception::throw_last_error(saved_ctx); + os << str; + free(str); + return os; +} + +// implementations for isl::ast_expr_int +ast_expr_int::ast_expr_int(__isl_take isl_ast_expr *ptr) + : ast_expr(ptr) {} + +ast_expr_int::ast_expr_int() + : ast_expr() {} + +ast_expr_int::ast_expr_int(const ast_expr_int &obj) + : ast_expr(obj) +{ +} + +ast_expr_int &ast_expr_int::operator=(ast_expr_int obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +isl::ctx ast_expr_int::ctx() const { + return isl::ctx(isl_ast_expr_get_ctx(ptr)); +} + +isl::val ast_expr_int::val() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_ast_expr_int_get_val(get()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::val ast_expr_int::get_val() const +{ + return val(); +} + +inline std::ostream &operator<<(std::ostream &os, const ast_expr_int &obj) +{ + if (!obj.get()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_ast_expr_get_ctx(obj.get()); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + char *str = isl_ast_expr_to_str(obj.get()); + if (!str) + exception::throw_last_error(saved_ctx); + os << str; + free(str); + return os; +} + +// implementations for isl::ast_expr_op +ast_expr_op::ast_expr_op(__isl_take isl_ast_expr *ptr) + : ast_expr(ptr) {} + +ast_expr_op::ast_expr_op() + : ast_expr() {} + +ast_expr_op::ast_expr_op(const ast_expr_op &obj) + : ast_expr(obj) +{ +} + +ast_expr_op &ast_expr_op::operator=(ast_expr_op obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +template +bool ast_expr_op::isa_type(T subtype) const +{ + if (is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl_ast_expr_op_get_type(get()) == subtype; +} +template +bool ast_expr_op::isa() const +{ + return isa_type(T::type); +} +template +T ast_expr_op::as() const +{ + if (!isa()) + exception::throw_invalid("not an object of the requested subtype", __FILE__, __LINE__); + return T(copy()); +} + +isl::ctx ast_expr_op::ctx() const { + return isl::ctx(isl_ast_expr_get_ctx(ptr)); +} + +isl::ast_expr ast_expr_op::arg(int pos) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_ast_expr_op_get_arg(get(), pos); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::ast_expr ast_expr_op::get_arg(int pos) const +{ + return arg(pos); +} + +unsigned ast_expr_op::n_arg() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_ast_expr_op_get_n_arg(get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +unsigned ast_expr_op::get_n_arg() const +{ + return n_arg(); +} + +inline std::ostream &operator<<(std::ostream &os, const ast_expr_op &obj) +{ + if (!obj.get()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_ast_expr_get_ctx(obj.get()); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + char *str = isl_ast_expr_to_str(obj.get()); + if (!str) + exception::throw_last_error(saved_ctx); + os << str; + free(str); + return os; +} + +// implementations for isl::ast_expr_op_access +ast_expr_op_access::ast_expr_op_access(__isl_take isl_ast_expr *ptr) + : ast_expr_op(ptr) {} + +ast_expr_op_access::ast_expr_op_access() + : ast_expr_op() {} + +ast_expr_op_access::ast_expr_op_access(const ast_expr_op_access &obj) + : ast_expr_op(obj) +{ +} + +ast_expr_op_access &ast_expr_op_access::operator=(ast_expr_op_access obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +isl::ctx ast_expr_op_access::ctx() const { + return isl::ctx(isl_ast_expr_get_ctx(ptr)); +} + +inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_access &obj) +{ + if (!obj.get()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_ast_expr_get_ctx(obj.get()); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + char *str = isl_ast_expr_to_str(obj.get()); + if (!str) + exception::throw_last_error(saved_ctx); + os << str; + free(str); + return os; +} + +// implementations for isl::ast_expr_op_add +ast_expr_op_add::ast_expr_op_add(__isl_take isl_ast_expr *ptr) + : ast_expr_op(ptr) {} + +ast_expr_op_add::ast_expr_op_add() + : ast_expr_op() {} + +ast_expr_op_add::ast_expr_op_add(const ast_expr_op_add &obj) + : ast_expr_op(obj) +{ +} + +ast_expr_op_add &ast_expr_op_add::operator=(ast_expr_op_add obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +isl::ctx ast_expr_op_add::ctx() const { + return isl::ctx(isl_ast_expr_get_ctx(ptr)); +} + +inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_add &obj) +{ + if (!obj.get()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_ast_expr_get_ctx(obj.get()); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + char *str = isl_ast_expr_to_str(obj.get()); + if (!str) + exception::throw_last_error(saved_ctx); + os << str; + free(str); + return os; +} + +// implementations for isl::ast_expr_op_address_of +ast_expr_op_address_of::ast_expr_op_address_of(__isl_take isl_ast_expr *ptr) + : ast_expr_op(ptr) {} + +ast_expr_op_address_of::ast_expr_op_address_of() + : ast_expr_op() {} + +ast_expr_op_address_of::ast_expr_op_address_of(const ast_expr_op_address_of &obj) + : ast_expr_op(obj) +{ +} + +ast_expr_op_address_of &ast_expr_op_address_of::operator=(ast_expr_op_address_of obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +isl::ctx ast_expr_op_address_of::ctx() const { + return isl::ctx(isl_ast_expr_get_ctx(ptr)); +} + +inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_address_of &obj) +{ + if (!obj.get()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_ast_expr_get_ctx(obj.get()); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + char *str = isl_ast_expr_to_str(obj.get()); + if (!str) + exception::throw_last_error(saved_ctx); + os << str; + free(str); + return os; +} + +// implementations for isl::ast_expr_op_and +ast_expr_op_and::ast_expr_op_and(__isl_take isl_ast_expr *ptr) + : ast_expr_op(ptr) {} + +ast_expr_op_and::ast_expr_op_and() + : ast_expr_op() {} + +ast_expr_op_and::ast_expr_op_and(const ast_expr_op_and &obj) + : ast_expr_op(obj) +{ +} + +ast_expr_op_and &ast_expr_op_and::operator=(ast_expr_op_and obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +isl::ctx ast_expr_op_and::ctx() const { + return isl::ctx(isl_ast_expr_get_ctx(ptr)); +} + +inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_and &obj) +{ + if (!obj.get()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_ast_expr_get_ctx(obj.get()); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + char *str = isl_ast_expr_to_str(obj.get()); + if (!str) + exception::throw_last_error(saved_ctx); + os << str; + free(str); + return os; +} + +// implementations for isl::ast_expr_op_and_then +ast_expr_op_and_then::ast_expr_op_and_then(__isl_take isl_ast_expr *ptr) + : ast_expr_op(ptr) {} + +ast_expr_op_and_then::ast_expr_op_and_then() + : ast_expr_op() {} + +ast_expr_op_and_then::ast_expr_op_and_then(const ast_expr_op_and_then &obj) + : ast_expr_op(obj) +{ +} + +ast_expr_op_and_then &ast_expr_op_and_then::operator=(ast_expr_op_and_then obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +isl::ctx ast_expr_op_and_then::ctx() const { + return isl::ctx(isl_ast_expr_get_ctx(ptr)); +} + +inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_and_then &obj) +{ + if (!obj.get()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_ast_expr_get_ctx(obj.get()); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + char *str = isl_ast_expr_to_str(obj.get()); + if (!str) + exception::throw_last_error(saved_ctx); + os << str; + free(str); + return os; +} + +// implementations for isl::ast_expr_op_call +ast_expr_op_call::ast_expr_op_call(__isl_take isl_ast_expr *ptr) + : ast_expr_op(ptr) {} + +ast_expr_op_call::ast_expr_op_call() + : ast_expr_op() {} + +ast_expr_op_call::ast_expr_op_call(const ast_expr_op_call &obj) + : ast_expr_op(obj) +{ +} + +ast_expr_op_call &ast_expr_op_call::operator=(ast_expr_op_call obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +isl::ctx ast_expr_op_call::ctx() const { + return isl::ctx(isl_ast_expr_get_ctx(ptr)); +} + +inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_call &obj) +{ + if (!obj.get()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_ast_expr_get_ctx(obj.get()); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + char *str = isl_ast_expr_to_str(obj.get()); + if (!str) + exception::throw_last_error(saved_ctx); + os << str; + free(str); + return os; +} + +// implementations for isl::ast_expr_op_cond +ast_expr_op_cond::ast_expr_op_cond(__isl_take isl_ast_expr *ptr) + : ast_expr_op(ptr) {} + +ast_expr_op_cond::ast_expr_op_cond() + : ast_expr_op() {} + +ast_expr_op_cond::ast_expr_op_cond(const ast_expr_op_cond &obj) + : ast_expr_op(obj) +{ +} + +ast_expr_op_cond &ast_expr_op_cond::operator=(ast_expr_op_cond obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +isl::ctx ast_expr_op_cond::ctx() const { + return isl::ctx(isl_ast_expr_get_ctx(ptr)); +} + +inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_cond &obj) +{ + if (!obj.get()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_ast_expr_get_ctx(obj.get()); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + char *str = isl_ast_expr_to_str(obj.get()); + if (!str) + exception::throw_last_error(saved_ctx); + os << str; + free(str); + return os; +} + +// implementations for isl::ast_expr_op_div +ast_expr_op_div::ast_expr_op_div(__isl_take isl_ast_expr *ptr) + : ast_expr_op(ptr) {} + +ast_expr_op_div::ast_expr_op_div() + : ast_expr_op() {} + +ast_expr_op_div::ast_expr_op_div(const ast_expr_op_div &obj) + : ast_expr_op(obj) +{ +} + +ast_expr_op_div &ast_expr_op_div::operator=(ast_expr_op_div obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +isl::ctx ast_expr_op_div::ctx() const { + return isl::ctx(isl_ast_expr_get_ctx(ptr)); +} + +inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_div &obj) +{ + if (!obj.get()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_ast_expr_get_ctx(obj.get()); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + char *str = isl_ast_expr_to_str(obj.get()); + if (!str) + exception::throw_last_error(saved_ctx); + os << str; + free(str); + return os; +} + +// implementations for isl::ast_expr_op_eq +ast_expr_op_eq::ast_expr_op_eq(__isl_take isl_ast_expr *ptr) + : ast_expr_op(ptr) {} + +ast_expr_op_eq::ast_expr_op_eq() + : ast_expr_op() {} + +ast_expr_op_eq::ast_expr_op_eq(const ast_expr_op_eq &obj) + : ast_expr_op(obj) +{ +} + +ast_expr_op_eq &ast_expr_op_eq::operator=(ast_expr_op_eq obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +isl::ctx ast_expr_op_eq::ctx() const { + return isl::ctx(isl_ast_expr_get_ctx(ptr)); +} + +inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_eq &obj) +{ + if (!obj.get()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_ast_expr_get_ctx(obj.get()); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + char *str = isl_ast_expr_to_str(obj.get()); + if (!str) + exception::throw_last_error(saved_ctx); + os << str; + free(str); + return os; +} + +// implementations for isl::ast_expr_op_fdiv_q +ast_expr_op_fdiv_q::ast_expr_op_fdiv_q(__isl_take isl_ast_expr *ptr) + : ast_expr_op(ptr) {} + +ast_expr_op_fdiv_q::ast_expr_op_fdiv_q() + : ast_expr_op() {} + +ast_expr_op_fdiv_q::ast_expr_op_fdiv_q(const ast_expr_op_fdiv_q &obj) + : ast_expr_op(obj) +{ +} + +ast_expr_op_fdiv_q &ast_expr_op_fdiv_q::operator=(ast_expr_op_fdiv_q obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +isl::ctx ast_expr_op_fdiv_q::ctx() const { + return isl::ctx(isl_ast_expr_get_ctx(ptr)); +} + +inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_fdiv_q &obj) +{ + if (!obj.get()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_ast_expr_get_ctx(obj.get()); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + char *str = isl_ast_expr_to_str(obj.get()); + if (!str) + exception::throw_last_error(saved_ctx); + os << str; + free(str); + return os; +} + +// implementations for isl::ast_expr_op_ge +ast_expr_op_ge::ast_expr_op_ge(__isl_take isl_ast_expr *ptr) + : ast_expr_op(ptr) {} + +ast_expr_op_ge::ast_expr_op_ge() + : ast_expr_op() {} + +ast_expr_op_ge::ast_expr_op_ge(const ast_expr_op_ge &obj) + : ast_expr_op(obj) +{ +} + +ast_expr_op_ge &ast_expr_op_ge::operator=(ast_expr_op_ge obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +isl::ctx ast_expr_op_ge::ctx() const { + return isl::ctx(isl_ast_expr_get_ctx(ptr)); +} + +inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_ge &obj) +{ + if (!obj.get()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_ast_expr_get_ctx(obj.get()); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + char *str = isl_ast_expr_to_str(obj.get()); + if (!str) + exception::throw_last_error(saved_ctx); + os << str; + free(str); + return os; +} + +// implementations for isl::ast_expr_op_gt +ast_expr_op_gt::ast_expr_op_gt(__isl_take isl_ast_expr *ptr) + : ast_expr_op(ptr) {} + +ast_expr_op_gt::ast_expr_op_gt() + : ast_expr_op() {} + +ast_expr_op_gt::ast_expr_op_gt(const ast_expr_op_gt &obj) + : ast_expr_op(obj) +{ +} + +ast_expr_op_gt &ast_expr_op_gt::operator=(ast_expr_op_gt obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +isl::ctx ast_expr_op_gt::ctx() const { + return isl::ctx(isl_ast_expr_get_ctx(ptr)); +} + +inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_gt &obj) +{ + if (!obj.get()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_ast_expr_get_ctx(obj.get()); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + char *str = isl_ast_expr_to_str(obj.get()); + if (!str) + exception::throw_last_error(saved_ctx); + os << str; + free(str); + return os; +} + +// implementations for isl::ast_expr_op_le +ast_expr_op_le::ast_expr_op_le(__isl_take isl_ast_expr *ptr) + : ast_expr_op(ptr) {} + +ast_expr_op_le::ast_expr_op_le() + : ast_expr_op() {} + +ast_expr_op_le::ast_expr_op_le(const ast_expr_op_le &obj) + : ast_expr_op(obj) +{ +} + +ast_expr_op_le &ast_expr_op_le::operator=(ast_expr_op_le obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +isl::ctx ast_expr_op_le::ctx() const { + return isl::ctx(isl_ast_expr_get_ctx(ptr)); +} + +inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_le &obj) +{ + if (!obj.get()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_ast_expr_get_ctx(obj.get()); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + char *str = isl_ast_expr_to_str(obj.get()); + if (!str) + exception::throw_last_error(saved_ctx); + os << str; + free(str); + return os; +} + +// implementations for isl::ast_expr_op_lt +ast_expr_op_lt::ast_expr_op_lt(__isl_take isl_ast_expr *ptr) + : ast_expr_op(ptr) {} + +ast_expr_op_lt::ast_expr_op_lt() + : ast_expr_op() {} + +ast_expr_op_lt::ast_expr_op_lt(const ast_expr_op_lt &obj) + : ast_expr_op(obj) +{ +} + +ast_expr_op_lt &ast_expr_op_lt::operator=(ast_expr_op_lt obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +isl::ctx ast_expr_op_lt::ctx() const { + return isl::ctx(isl_ast_expr_get_ctx(ptr)); +} + +inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_lt &obj) +{ + if (!obj.get()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_ast_expr_get_ctx(obj.get()); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + char *str = isl_ast_expr_to_str(obj.get()); + if (!str) + exception::throw_last_error(saved_ctx); + os << str; + free(str); + return os; +} + +// implementations for isl::ast_expr_op_max +ast_expr_op_max::ast_expr_op_max(__isl_take isl_ast_expr *ptr) + : ast_expr_op(ptr) {} + +ast_expr_op_max::ast_expr_op_max() + : ast_expr_op() {} + +ast_expr_op_max::ast_expr_op_max(const ast_expr_op_max &obj) + : ast_expr_op(obj) +{ +} + +ast_expr_op_max &ast_expr_op_max::operator=(ast_expr_op_max obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +isl::ctx ast_expr_op_max::ctx() const { + return isl::ctx(isl_ast_expr_get_ctx(ptr)); +} + +inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_max &obj) +{ + if (!obj.get()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_ast_expr_get_ctx(obj.get()); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + char *str = isl_ast_expr_to_str(obj.get()); + if (!str) + exception::throw_last_error(saved_ctx); + os << str; + free(str); + return os; +} + +// implementations for isl::ast_expr_op_member +ast_expr_op_member::ast_expr_op_member(__isl_take isl_ast_expr *ptr) + : ast_expr_op(ptr) {} + +ast_expr_op_member::ast_expr_op_member() + : ast_expr_op() {} + +ast_expr_op_member::ast_expr_op_member(const ast_expr_op_member &obj) + : ast_expr_op(obj) +{ +} + +ast_expr_op_member &ast_expr_op_member::operator=(ast_expr_op_member obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +isl::ctx ast_expr_op_member::ctx() const { + return isl::ctx(isl_ast_expr_get_ctx(ptr)); +} + +inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_member &obj) +{ + if (!obj.get()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_ast_expr_get_ctx(obj.get()); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + char *str = isl_ast_expr_to_str(obj.get()); + if (!str) + exception::throw_last_error(saved_ctx); + os << str; + free(str); + return os; +} + +// implementations for isl::ast_expr_op_min +ast_expr_op_min::ast_expr_op_min(__isl_take isl_ast_expr *ptr) + : ast_expr_op(ptr) {} + +ast_expr_op_min::ast_expr_op_min() + : ast_expr_op() {} + +ast_expr_op_min::ast_expr_op_min(const ast_expr_op_min &obj) + : ast_expr_op(obj) +{ +} + +ast_expr_op_min &ast_expr_op_min::operator=(ast_expr_op_min obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +isl::ctx ast_expr_op_min::ctx() const { + return isl::ctx(isl_ast_expr_get_ctx(ptr)); +} + +inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_min &obj) +{ + if (!obj.get()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_ast_expr_get_ctx(obj.get()); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + char *str = isl_ast_expr_to_str(obj.get()); + if (!str) + exception::throw_last_error(saved_ctx); + os << str; + free(str); + return os; +} + +// implementations for isl::ast_expr_op_minus +ast_expr_op_minus::ast_expr_op_minus(__isl_take isl_ast_expr *ptr) + : ast_expr_op(ptr) {} + +ast_expr_op_minus::ast_expr_op_minus() + : ast_expr_op() {} + +ast_expr_op_minus::ast_expr_op_minus(const ast_expr_op_minus &obj) + : ast_expr_op(obj) +{ +} + +ast_expr_op_minus &ast_expr_op_minus::operator=(ast_expr_op_minus obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +isl::ctx ast_expr_op_minus::ctx() const { + return isl::ctx(isl_ast_expr_get_ctx(ptr)); +} + +inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_minus &obj) +{ + if (!obj.get()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_ast_expr_get_ctx(obj.get()); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + char *str = isl_ast_expr_to_str(obj.get()); + if (!str) + exception::throw_last_error(saved_ctx); + os << str; + free(str); + return os; +} + +// implementations for isl::ast_expr_op_mul +ast_expr_op_mul::ast_expr_op_mul(__isl_take isl_ast_expr *ptr) + : ast_expr_op(ptr) {} + +ast_expr_op_mul::ast_expr_op_mul() + : ast_expr_op() {} + +ast_expr_op_mul::ast_expr_op_mul(const ast_expr_op_mul &obj) + : ast_expr_op(obj) +{ +} + +ast_expr_op_mul &ast_expr_op_mul::operator=(ast_expr_op_mul obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +isl::ctx ast_expr_op_mul::ctx() const { + return isl::ctx(isl_ast_expr_get_ctx(ptr)); +} + +inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_mul &obj) +{ + if (!obj.get()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_ast_expr_get_ctx(obj.get()); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + char *str = isl_ast_expr_to_str(obj.get()); + if (!str) + exception::throw_last_error(saved_ctx); + os << str; + free(str); + return os; +} + +// implementations for isl::ast_expr_op_or +ast_expr_op_or::ast_expr_op_or(__isl_take isl_ast_expr *ptr) + : ast_expr_op(ptr) {} + +ast_expr_op_or::ast_expr_op_or() + : ast_expr_op() {} + +ast_expr_op_or::ast_expr_op_or(const ast_expr_op_or &obj) + : ast_expr_op(obj) +{ +} + +ast_expr_op_or &ast_expr_op_or::operator=(ast_expr_op_or obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +isl::ctx ast_expr_op_or::ctx() const { + return isl::ctx(isl_ast_expr_get_ctx(ptr)); +} + +inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_or &obj) +{ + if (!obj.get()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_ast_expr_get_ctx(obj.get()); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + char *str = isl_ast_expr_to_str(obj.get()); + if (!str) + exception::throw_last_error(saved_ctx); + os << str; + free(str); + return os; +} + +// implementations for isl::ast_expr_op_or_else +ast_expr_op_or_else::ast_expr_op_or_else(__isl_take isl_ast_expr *ptr) + : ast_expr_op(ptr) {} + +ast_expr_op_or_else::ast_expr_op_or_else() + : ast_expr_op() {} + +ast_expr_op_or_else::ast_expr_op_or_else(const ast_expr_op_or_else &obj) + : ast_expr_op(obj) +{ +} + +ast_expr_op_or_else &ast_expr_op_or_else::operator=(ast_expr_op_or_else obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +isl::ctx ast_expr_op_or_else::ctx() const { + return isl::ctx(isl_ast_expr_get_ctx(ptr)); +} + +inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_or_else &obj) +{ + if (!obj.get()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_ast_expr_get_ctx(obj.get()); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + char *str = isl_ast_expr_to_str(obj.get()); + if (!str) + exception::throw_last_error(saved_ctx); + os << str; + free(str); + return os; +} + +// implementations for isl::ast_expr_op_pdiv_q +ast_expr_op_pdiv_q::ast_expr_op_pdiv_q(__isl_take isl_ast_expr *ptr) + : ast_expr_op(ptr) {} + +ast_expr_op_pdiv_q::ast_expr_op_pdiv_q() + : ast_expr_op() {} + +ast_expr_op_pdiv_q::ast_expr_op_pdiv_q(const ast_expr_op_pdiv_q &obj) + : ast_expr_op(obj) +{ +} + +ast_expr_op_pdiv_q &ast_expr_op_pdiv_q::operator=(ast_expr_op_pdiv_q obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +isl::ctx ast_expr_op_pdiv_q::ctx() const { + return isl::ctx(isl_ast_expr_get_ctx(ptr)); +} + +inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_pdiv_q &obj) +{ + if (!obj.get()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_ast_expr_get_ctx(obj.get()); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + char *str = isl_ast_expr_to_str(obj.get()); + if (!str) + exception::throw_last_error(saved_ctx); + os << str; + free(str); + return os; +} + +// implementations for isl::ast_expr_op_pdiv_r +ast_expr_op_pdiv_r::ast_expr_op_pdiv_r(__isl_take isl_ast_expr *ptr) + : ast_expr_op(ptr) {} + +ast_expr_op_pdiv_r::ast_expr_op_pdiv_r() + : ast_expr_op() {} + +ast_expr_op_pdiv_r::ast_expr_op_pdiv_r(const ast_expr_op_pdiv_r &obj) + : ast_expr_op(obj) +{ +} + +ast_expr_op_pdiv_r &ast_expr_op_pdiv_r::operator=(ast_expr_op_pdiv_r obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +isl::ctx ast_expr_op_pdiv_r::ctx() const { + return isl::ctx(isl_ast_expr_get_ctx(ptr)); +} + +inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_pdiv_r &obj) +{ + if (!obj.get()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_ast_expr_get_ctx(obj.get()); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + char *str = isl_ast_expr_to_str(obj.get()); + if (!str) + exception::throw_last_error(saved_ctx); + os << str; + free(str); + return os; +} + +// implementations for isl::ast_expr_op_select +ast_expr_op_select::ast_expr_op_select(__isl_take isl_ast_expr *ptr) + : ast_expr_op(ptr) {} + +ast_expr_op_select::ast_expr_op_select() + : ast_expr_op() {} + +ast_expr_op_select::ast_expr_op_select(const ast_expr_op_select &obj) + : ast_expr_op(obj) +{ +} + +ast_expr_op_select &ast_expr_op_select::operator=(ast_expr_op_select obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +isl::ctx ast_expr_op_select::ctx() const { + return isl::ctx(isl_ast_expr_get_ctx(ptr)); +} + +inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_select &obj) +{ + if (!obj.get()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_ast_expr_get_ctx(obj.get()); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + char *str = isl_ast_expr_to_str(obj.get()); + if (!str) + exception::throw_last_error(saved_ctx); + os << str; + free(str); + return os; +} + +// implementations for isl::ast_expr_op_sub +ast_expr_op_sub::ast_expr_op_sub(__isl_take isl_ast_expr *ptr) + : ast_expr_op(ptr) {} + +ast_expr_op_sub::ast_expr_op_sub() + : ast_expr_op() {} + +ast_expr_op_sub::ast_expr_op_sub(const ast_expr_op_sub &obj) + : ast_expr_op(obj) +{ +} + +ast_expr_op_sub &ast_expr_op_sub::operator=(ast_expr_op_sub obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +isl::ctx ast_expr_op_sub::ctx() const { + return isl::ctx(isl_ast_expr_get_ctx(ptr)); +} + +inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_sub &obj) +{ + if (!obj.get()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_ast_expr_get_ctx(obj.get()); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + char *str = isl_ast_expr_to_str(obj.get()); + if (!str) + exception::throw_last_error(saved_ctx); + os << str; + free(str); + return os; +} + +// implementations for isl::ast_expr_op_zdiv_r +ast_expr_op_zdiv_r::ast_expr_op_zdiv_r(__isl_take isl_ast_expr *ptr) + : ast_expr_op(ptr) {} + +ast_expr_op_zdiv_r::ast_expr_op_zdiv_r() + : ast_expr_op() {} + +ast_expr_op_zdiv_r::ast_expr_op_zdiv_r(const ast_expr_op_zdiv_r &obj) + : ast_expr_op(obj) +{ +} + +ast_expr_op_zdiv_r &ast_expr_op_zdiv_r::operator=(ast_expr_op_zdiv_r obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +isl::ctx ast_expr_op_zdiv_r::ctx() const { + return isl::ctx(isl_ast_expr_get_ctx(ptr)); +} + +inline std::ostream &operator<<(std::ostream &os, const ast_expr_op_zdiv_r &obj) +{ + if (!obj.get()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_ast_expr_get_ctx(obj.get()); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + char *str = isl_ast_expr_to_str(obj.get()); + if (!str) + exception::throw_last_error(saved_ctx); + os << str; + free(str); + return os; +} + +// implementations for isl::ast_node +ast_node manage(__isl_take isl_ast_node *ptr) { + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return ast_node(ptr); +} +ast_node manage_copy(__isl_keep isl_ast_node *ptr) { + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_ast_node_get_ctx(ptr); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + ptr = isl_ast_node_copy(ptr); + if (!ptr) + exception::throw_last_error(saved_ctx); + return ast_node(ptr); +} + +ast_node::ast_node(__isl_take isl_ast_node *ptr) + : ptr(ptr) {} + +ast_node::ast_node() + : ptr(nullptr) {} + +ast_node::ast_node(const ast_node &obj) + : ptr(nullptr) +{ + if (!obj.ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_ast_node_get_ctx(obj.ptr); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + ptr = obj.copy(); + if (!ptr) + exception::throw_last_error(saved_ctx); +} + +ast_node &ast_node::operator=(ast_node obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +ast_node::~ast_node() { + if (ptr) + isl_ast_node_free(ptr); +} + +__isl_give isl_ast_node *ast_node::copy() const & { + return isl_ast_node_copy(ptr); +} + +__isl_keep isl_ast_node *ast_node::get() const { + return ptr; +} + +__isl_give isl_ast_node *ast_node::release() { + isl_ast_node *tmp = ptr; + ptr = nullptr; + return tmp; +} + +bool ast_node::is_null() const { + return ptr == nullptr; +} + +template +bool ast_node::isa_type(T subtype) const +{ + if (is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl_ast_node_get_type(get()) == subtype; +} +template +bool ast_node::isa() const +{ + return isa_type(T::type); +} +template +T ast_node::as() const +{ + if (!isa()) + exception::throw_invalid("not an object of the requested subtype", __FILE__, __LINE__); + return T(copy()); +} + +isl::ctx ast_node::ctx() const { + return isl::ctx(isl_ast_node_get_ctx(ptr)); +} + +isl::ast_node ast_node::map_descendant_bottom_up(const std::function &fn) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + struct fn_data { + std::function func; + std::exception_ptr eptr; + } fn_data = { fn }; + auto fn_lambda = [](isl_ast_node *arg_0, void *arg_1) -> isl_ast_node * { + auto *data = static_cast(arg_1); + ISL_CPP_TRY { + auto ret = (data->func)(manage(arg_0)); + return ret.release(); + } ISL_CPP_CATCH_ALL { + data->eptr = std::current_exception(); + return NULL; + } + }; + auto res = isl_ast_node_map_descendant_bottom_up(copy(), fn_lambda, &fn_data); + if (fn_data.eptr) + std::rethrow_exception(fn_data.eptr); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +std::string ast_node::to_C_str() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_ast_node_to_C_str(get()); + std::string tmp(res); + free(res); + return tmp; +} + +isl::ast_node_list ast_node::to_list() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_ast_node_to_list(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +inline std::ostream &operator<<(std::ostream &os, const ast_node &obj) +{ + if (!obj.get()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_ast_node_get_ctx(obj.get()); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + char *str = isl_ast_node_to_str(obj.get()); + if (!str) + exception::throw_last_error(saved_ctx); + os << str; + free(str); + return os; +} + +// implementations for isl::ast_node_block +ast_node_block::ast_node_block(__isl_take isl_ast_node *ptr) + : ast_node(ptr) {} + +ast_node_block::ast_node_block() + : ast_node() {} + +ast_node_block::ast_node_block(const ast_node_block &obj) + : ast_node(obj) +{ +} + +ast_node_block::ast_node_block(isl::ast_node_list list) +{ + if (list.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = list.ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_ast_node_block_from_children(list.release()); + if (!res) + exception::throw_last_error(saved_ctx); + ptr = res; +} + +ast_node_block &ast_node_block::operator=(ast_node_block obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +isl::ctx ast_node_block::ctx() const { + return isl::ctx(isl_ast_node_get_ctx(ptr)); +} + +isl::ast_node_list ast_node_block::children() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_ast_node_block_get_children(get()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::ast_node_list ast_node_block::get_children() const +{ + return children(); +} + +inline std::ostream &operator<<(std::ostream &os, const ast_node_block &obj) +{ + if (!obj.get()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_ast_node_get_ctx(obj.get()); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + char *str = isl_ast_node_to_str(obj.get()); + if (!str) + exception::throw_last_error(saved_ctx); + os << str; + free(str); + return os; +} + +// implementations for isl::ast_node_for +ast_node_for::ast_node_for(__isl_take isl_ast_node *ptr) + : ast_node(ptr) {} + +ast_node_for::ast_node_for() + : ast_node() {} + +ast_node_for::ast_node_for(const ast_node_for &obj) + : ast_node(obj) +{ +} + +ast_node_for &ast_node_for::operator=(ast_node_for obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +isl::ctx ast_node_for::ctx() const { + return isl::ctx(isl_ast_node_get_ctx(ptr)); +} + +isl::ast_node ast_node_for::body() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_ast_node_for_get_body(get()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::ast_node ast_node_for::get_body() const +{ + return body(); +} + +isl::ast_expr ast_node_for::cond() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_ast_node_for_get_cond(get()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::ast_expr ast_node_for::get_cond() const +{ + return cond(); +} + +isl::ast_expr ast_node_for::inc() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_ast_node_for_get_inc(get()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::ast_expr ast_node_for::get_inc() const +{ + return inc(); +} + +isl::ast_expr ast_node_for::init() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_ast_node_for_get_init(get()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::ast_expr ast_node_for::get_init() const +{ + return init(); +} + +bool ast_node_for::is_degenerate() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_ast_node_for_is_degenerate(get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +isl::ast_expr ast_node_for::iterator() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_ast_node_for_get_iterator(get()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::ast_expr ast_node_for::get_iterator() const +{ + return iterator(); +} + +inline std::ostream &operator<<(std::ostream &os, const ast_node_for &obj) +{ + if (!obj.get()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_ast_node_get_ctx(obj.get()); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + char *str = isl_ast_node_to_str(obj.get()); + if (!str) + exception::throw_last_error(saved_ctx); + os << str; + free(str); + return os; +} + +// implementations for isl::ast_node_if +ast_node_if::ast_node_if(__isl_take isl_ast_node *ptr) + : ast_node(ptr) {} + +ast_node_if::ast_node_if() + : ast_node() {} + +ast_node_if::ast_node_if(const ast_node_if &obj) + : ast_node(obj) +{ +} + +ast_node_if &ast_node_if::operator=(ast_node_if obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +isl::ctx ast_node_if::ctx() const { + return isl::ctx(isl_ast_node_get_ctx(ptr)); +} + +isl::ast_expr ast_node_if::cond() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_ast_node_if_get_cond(get()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::ast_expr ast_node_if::get_cond() const +{ + return cond(); +} + +isl::ast_node ast_node_if::else_node() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_ast_node_if_get_else_node(get()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::ast_node ast_node_if::get_else_node() const +{ + return else_node(); +} + +bool ast_node_if::has_else_node() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_ast_node_if_has_else_node(get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +isl::ast_node ast_node_if::then_node() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_ast_node_if_get_then_node(get()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::ast_node ast_node_if::get_then_node() const +{ + return then_node(); +} + +inline std::ostream &operator<<(std::ostream &os, const ast_node_if &obj) +{ + if (!obj.get()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_ast_node_get_ctx(obj.get()); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + char *str = isl_ast_node_to_str(obj.get()); + if (!str) + exception::throw_last_error(saved_ctx); + os << str; + free(str); + return os; +} + +// implementations for isl::ast_node_list +ast_node_list manage(__isl_take isl_ast_node_list *ptr) { + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return ast_node_list(ptr); +} +ast_node_list manage_copy(__isl_keep isl_ast_node_list *ptr) { + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_ast_node_list_get_ctx(ptr); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + ptr = isl_ast_node_list_copy(ptr); + if (!ptr) + exception::throw_last_error(saved_ctx); + return ast_node_list(ptr); +} + +ast_node_list::ast_node_list(__isl_take isl_ast_node_list *ptr) + : ptr(ptr) {} + +ast_node_list::ast_node_list() + : ptr(nullptr) {} + +ast_node_list::ast_node_list(const ast_node_list &obj) + : ptr(nullptr) +{ + if (!obj.ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_ast_node_list_get_ctx(obj.ptr); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + ptr = obj.copy(); + if (!ptr) + exception::throw_last_error(saved_ctx); +} + +ast_node_list::ast_node_list(isl::ctx ctx, int n) +{ + auto saved_ctx = ctx; + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_ast_node_list_alloc(ctx.release(), n); + if (!res) + exception::throw_last_error(saved_ctx); + ptr = res; +} + +ast_node_list::ast_node_list(isl::ast_node el) +{ + if (el.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = el.ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_ast_node_list_from_ast_node(el.release()); + if (!res) + exception::throw_last_error(saved_ctx); + ptr = res; +} + +ast_node_list &ast_node_list::operator=(ast_node_list obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +ast_node_list::~ast_node_list() { + if (ptr) + isl_ast_node_list_free(ptr); +} + +__isl_give isl_ast_node_list *ast_node_list::copy() const & { + return isl_ast_node_list_copy(ptr); +} + +__isl_keep isl_ast_node_list *ast_node_list::get() const { + return ptr; +} + +__isl_give isl_ast_node_list *ast_node_list::release() { + isl_ast_node_list *tmp = ptr; + ptr = nullptr; + return tmp; +} + +bool ast_node_list::is_null() const { + return ptr == nullptr; +} + +isl::ctx ast_node_list::ctx() const { + return isl::ctx(isl_ast_node_list_get_ctx(ptr)); +} + +isl::ast_node_list ast_node_list::add(isl::ast_node el) const +{ + if (!ptr || el.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_ast_node_list_add(copy(), el.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::ast_node ast_node_list::at(int index) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_ast_node_list_get_at(get(), index); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::ast_node ast_node_list::get_at(int index) const +{ + return at(index); +} + +isl::ast_node_list ast_node_list::clear() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_ast_node_list_clear(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::ast_node_list ast_node_list::concat(isl::ast_node_list list2) const +{ + if (!ptr || list2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_ast_node_list_concat(copy(), list2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::ast_node_list ast_node_list::drop(unsigned int first, unsigned int n) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_ast_node_list_drop(copy(), first, n); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +void ast_node_list::foreach(const std::function &fn) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + struct fn_data { + std::function func; + std::exception_ptr eptr; + } fn_data = { fn }; + auto fn_lambda = [](isl_ast_node *arg_0, void *arg_1) -> isl_stat { + auto *data = static_cast(arg_1); + ISL_CPP_TRY { + (data->func)(manage(arg_0)); + return isl_stat_ok; + } ISL_CPP_CATCH_ALL { + data->eptr = std::current_exception(); + return isl_stat_error; + } + }; + auto res = isl_ast_node_list_foreach(get(), fn_lambda, &fn_data); + if (fn_data.eptr) + std::rethrow_exception(fn_data.eptr); + if (res < 0) + exception::throw_last_error(saved_ctx); + return; +} + +void ast_node_list::foreach_scc(const std::function &follows, const std::function &fn) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + struct follows_data { + std::function func; + std::exception_ptr eptr; + } follows_data = { follows }; + auto follows_lambda = [](isl_ast_node *arg_0, isl_ast_node *arg_1, void *arg_2) -> isl_bool { + auto *data = static_cast(arg_2); + ISL_CPP_TRY { + auto ret = (data->func)(manage_copy(arg_0), manage_copy(arg_1)); + return ret ? isl_bool_true : isl_bool_false; + } ISL_CPP_CATCH_ALL { + data->eptr = std::current_exception(); + return isl_bool_error; + } + }; + struct fn_data { + std::function func; + std::exception_ptr eptr; + } fn_data = { fn }; + auto fn_lambda = [](isl_ast_node_list *arg_0, void *arg_1) -> isl_stat { + auto *data = static_cast(arg_1); + ISL_CPP_TRY { + (data->func)(manage(arg_0)); + return isl_stat_ok; + } ISL_CPP_CATCH_ALL { + data->eptr = std::current_exception(); + return isl_stat_error; + } + }; + auto res = isl_ast_node_list_foreach_scc(get(), follows_lambda, &follows_data, fn_lambda, &fn_data); + if (follows_data.eptr) + std::rethrow_exception(follows_data.eptr); + if (fn_data.eptr) + std::rethrow_exception(fn_data.eptr); + if (res < 0) + exception::throw_last_error(saved_ctx); + return; +} + +isl::ast_node_list ast_node_list::insert(unsigned int pos, isl::ast_node el) const +{ + if (!ptr || el.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_ast_node_list_insert(copy(), pos, el.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::ast_node_list ast_node_list::set_at(int index, isl::ast_node el) const +{ + if (!ptr || el.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_ast_node_list_set_at(copy(), index, el.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +unsigned ast_node_list::size() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_ast_node_list_size(get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +inline std::ostream &operator<<(std::ostream &os, const ast_node_list &obj) +{ + if (!obj.get()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_ast_node_list_get_ctx(obj.get()); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + char *str = isl_ast_node_list_to_str(obj.get()); + if (!str) + exception::throw_last_error(saved_ctx); + os << str; + free(str); + return os; +} + +// implementations for isl::ast_node_mark +ast_node_mark::ast_node_mark(__isl_take isl_ast_node *ptr) + : ast_node(ptr) {} + +ast_node_mark::ast_node_mark() + : ast_node() {} + +ast_node_mark::ast_node_mark(const ast_node_mark &obj) + : ast_node(obj) +{ +} + +ast_node_mark &ast_node_mark::operator=(ast_node_mark obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +isl::ctx ast_node_mark::ctx() const { + return isl::ctx(isl_ast_node_get_ctx(ptr)); +} + +isl::id ast_node_mark::id() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_ast_node_mark_get_id(get()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::id ast_node_mark::get_id() const +{ + return id(); +} + +isl::ast_node ast_node_mark::node() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_ast_node_mark_get_node(get()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::ast_node ast_node_mark::get_node() const +{ + return node(); +} + +inline std::ostream &operator<<(std::ostream &os, const ast_node_mark &obj) +{ + if (!obj.get()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_ast_node_get_ctx(obj.get()); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + char *str = isl_ast_node_to_str(obj.get()); + if (!str) + exception::throw_last_error(saved_ctx); + os << str; + free(str); + return os; +} + +// implementations for isl::ast_node_user +ast_node_user::ast_node_user(__isl_take isl_ast_node *ptr) + : ast_node(ptr) {} + +ast_node_user::ast_node_user() + : ast_node() {} + +ast_node_user::ast_node_user(const ast_node_user &obj) + : ast_node(obj) +{ +} + +ast_node_user::ast_node_user(isl::ast_expr expr) +{ + if (expr.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = expr.ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_ast_node_user_from_expr(expr.release()); + if (!res) + exception::throw_last_error(saved_ctx); + ptr = res; +} + +ast_node_user &ast_node_user::operator=(ast_node_user obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +isl::ctx ast_node_user::ctx() const { + return isl::ctx(isl_ast_node_get_ctx(ptr)); +} + +isl::ast_expr ast_node_user::expr() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_ast_node_user_get_expr(get()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::ast_expr ast_node_user::get_expr() const +{ + return expr(); +} + +inline std::ostream &operator<<(std::ostream &os, const ast_node_user &obj) +{ + if (!obj.get()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_ast_node_get_ctx(obj.get()); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + char *str = isl_ast_node_to_str(obj.get()); + if (!str) + exception::throw_last_error(saved_ctx); + os << str; + free(str); + return os; +} + +// implementations for isl::basic_map +basic_map manage(__isl_take isl_basic_map *ptr) { + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return basic_map(ptr); +} +basic_map manage_copy(__isl_keep isl_basic_map *ptr) { + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_basic_map_get_ctx(ptr); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + ptr = isl_basic_map_copy(ptr); + if (!ptr) + exception::throw_last_error(saved_ctx); + return basic_map(ptr); +} + +basic_map::basic_map(__isl_take isl_basic_map *ptr) + : ptr(ptr) {} + +basic_map::basic_map() + : ptr(nullptr) {} + +basic_map::basic_map(const basic_map &obj) + : ptr(nullptr) +{ + if (!obj.ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_basic_map_get_ctx(obj.ptr); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + ptr = obj.copy(); + if (!ptr) + exception::throw_last_error(saved_ctx); +} + +basic_map::basic_map(isl::ctx ctx, const std::string &str) +{ + auto saved_ctx = ctx; + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_basic_map_read_from_str(ctx.release(), str.c_str()); + if (!res) + exception::throw_last_error(saved_ctx); + ptr = res; +} + +basic_map &basic_map::operator=(basic_map obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +basic_map::~basic_map() { + if (ptr) + isl_basic_map_free(ptr); +} + +__isl_give isl_basic_map *basic_map::copy() const & { + return isl_basic_map_copy(ptr); +} + +__isl_keep isl_basic_map *basic_map::get() const { + return ptr; +} + +__isl_give isl_basic_map *basic_map::release() { + isl_basic_map *tmp = ptr; + ptr = nullptr; + return tmp; +} + +bool basic_map::is_null() const { + return ptr == nullptr; +} + +isl::ctx basic_map::ctx() const { + return isl::ctx(isl_basic_map_get_ctx(ptr)); +} + +isl::basic_map basic_map::affine_hull() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_basic_map_affine_hull(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::basic_map basic_map::apply_domain(isl::basic_map bmap2) const +{ + if (!ptr || bmap2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_basic_map_apply_domain(copy(), bmap2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::map basic_map::apply_domain(const isl::map &map2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).apply_domain(map2); +} + +isl::union_map basic_map::apply_domain(const isl::union_map &umap2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).apply_domain(umap2); +} + +isl::basic_map basic_map::apply_range(isl::basic_map bmap2) const +{ + if (!ptr || bmap2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_basic_map_apply_range(copy(), bmap2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::map basic_map::apply_range(const isl::map &map2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).apply_range(map2); +} + +isl::union_map basic_map::apply_range(const isl::union_map &umap2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).apply_range(umap2); +} + +isl::map basic_map::as_map() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).as_map(); +} + +isl::multi_union_pw_aff basic_map::as_multi_union_pw_aff() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).as_multi_union_pw_aff(); +} + +isl::pw_multi_aff basic_map::as_pw_multi_aff() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).as_pw_multi_aff(); +} + +isl::union_pw_multi_aff basic_map::as_union_pw_multi_aff() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).as_union_pw_multi_aff(); +} + +isl::set basic_map::bind_domain(const isl::multi_id &tuple) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).bind_domain(tuple); +} + +isl::set basic_map::bind_range(const isl::multi_id &tuple) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).bind_range(tuple); +} + +isl::map basic_map::coalesce() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).coalesce(); +} + +isl::map basic_map::complement() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).complement(); +} + +isl::union_map basic_map::compute_divs() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).compute_divs(); +} + +isl::map basic_map::curry() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).curry(); +} + +isl::basic_set basic_map::deltas() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_basic_map_deltas(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::basic_map basic_map::detect_equalities() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_basic_map_detect_equalities(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::set basic_map::domain() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).domain(); +} + +isl::map basic_map::domain_factor_domain() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).domain_factor_domain(); +} + +isl::map basic_map::domain_factor_range() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).domain_factor_range(); +} + +isl::union_map basic_map::domain_map() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).domain_map(); +} + +isl::union_pw_multi_aff basic_map::domain_map_union_pw_multi_aff() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).domain_map_union_pw_multi_aff(); +} + +isl::map basic_map::domain_product(const isl::map &map2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).domain_product(map2); +} + +isl::union_map basic_map::domain_product(const isl::union_map &umap2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).domain_product(umap2); +} + +isl::map basic_map::domain_reverse() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).domain_reverse(); +} + +unsigned basic_map::domain_tuple_dim() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).domain_tuple_dim(); +} + +isl::id basic_map::domain_tuple_id() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).domain_tuple_id(); +} + +isl::map basic_map::drop_unused_params() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).drop_unused_params(); +} + +isl::map basic_map::eq_at(const isl::multi_pw_aff &mpa) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).eq_at(mpa); +} + +isl::union_map basic_map::eq_at(const isl::multi_union_pw_aff &mupa) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).eq_at(mupa); +} + +bool basic_map::every_map(const std::function &test) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).every_map(test); +} + +isl::map basic_map::extract_map(const isl::space &space) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).extract_map(space); +} + +isl::map basic_map::factor_domain() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).factor_domain(); +} + +isl::map basic_map::factor_range() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).factor_range(); +} + +isl::map basic_map::fixed_power(const isl::val &exp) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).fixed_power(exp); +} + +isl::map basic_map::fixed_power(long exp) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->fixed_power(isl::val(ctx(), exp)); +} + +isl::basic_map basic_map::flatten() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_basic_map_flatten(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::basic_map basic_map::flatten_domain() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_basic_map_flatten_domain(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::basic_map basic_map::flatten_range() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_basic_map_flatten_range(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +void basic_map::foreach_basic_map(const std::function &fn) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).foreach_basic_map(fn); +} + +void basic_map::foreach_map(const std::function &fn) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).foreach_map(fn); +} + +isl::basic_map basic_map::gist(isl::basic_map context) const +{ + if (!ptr || context.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_basic_map_gist(copy(), context.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::map basic_map::gist(const isl::map &context) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).gist(context); +} + +isl::union_map basic_map::gist(const isl::union_map &context) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).gist(context); +} + +isl::map basic_map::gist_domain(const isl::set &context) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).gist_domain(context); +} + +isl::union_map basic_map::gist_domain(const isl::union_set &uset) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).gist_domain(uset); +} + +isl::map basic_map::gist_params(const isl::set &context) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).gist_params(context); +} + +isl::union_map basic_map::gist_range(const isl::union_set &uset) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).gist_range(uset); +} + +bool basic_map::has_domain_tuple_id() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).has_domain_tuple_id(); +} + +bool basic_map::has_range_tuple_id() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).has_range_tuple_id(); +} + +isl::basic_map basic_map::intersect(isl::basic_map bmap2) const +{ + if (!ptr || bmap2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_basic_map_intersect(copy(), bmap2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::map basic_map::intersect(const isl::map &map2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).intersect(map2); +} + +isl::union_map basic_map::intersect(const isl::union_map &umap2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).intersect(umap2); +} + +isl::basic_map basic_map::intersect_domain(isl::basic_set bset) const +{ + if (!ptr || bset.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_basic_map_intersect_domain(copy(), bset.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::map basic_map::intersect_domain(const isl::set &set) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).intersect_domain(set); +} + +isl::union_map basic_map::intersect_domain(const isl::space &space) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).intersect_domain(space); +} + +isl::union_map basic_map::intersect_domain(const isl::union_set &uset) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).intersect_domain(uset); +} + +isl::basic_map basic_map::intersect_domain(const isl::point &bset) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->intersect_domain(isl::basic_set(bset)); +} + +isl::map basic_map::intersect_domain_factor_domain(const isl::map &factor) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).intersect_domain_factor_domain(factor); +} + +isl::union_map basic_map::intersect_domain_factor_domain(const isl::union_map &factor) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).intersect_domain_factor_domain(factor); +} + +isl::map basic_map::intersect_domain_factor_range(const isl::map &factor) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).intersect_domain_factor_range(factor); +} + +isl::union_map basic_map::intersect_domain_factor_range(const isl::union_map &factor) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).intersect_domain_factor_range(factor); +} + +isl::map basic_map::intersect_domain_wrapped_domain(const isl::set &domain) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).intersect_domain_wrapped_domain(domain); +} + +isl::union_map basic_map::intersect_domain_wrapped_domain(const isl::union_set &domain) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).intersect_domain_wrapped_domain(domain); +} + +isl::map basic_map::intersect_params(const isl::set ¶ms) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).intersect_params(params); +} + +isl::basic_map basic_map::intersect_range(isl::basic_set bset) const +{ + if (!ptr || bset.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_basic_map_intersect_range(copy(), bset.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::map basic_map::intersect_range(const isl::set &set) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).intersect_range(set); +} + +isl::union_map basic_map::intersect_range(const isl::space &space) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).intersect_range(space); +} + +isl::union_map basic_map::intersect_range(const isl::union_set &uset) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).intersect_range(uset); +} + +isl::basic_map basic_map::intersect_range(const isl::point &bset) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->intersect_range(isl::basic_set(bset)); +} + +isl::map basic_map::intersect_range_factor_domain(const isl::map &factor) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).intersect_range_factor_domain(factor); +} + +isl::union_map basic_map::intersect_range_factor_domain(const isl::union_map &factor) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).intersect_range_factor_domain(factor); +} + +isl::map basic_map::intersect_range_factor_range(const isl::map &factor) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).intersect_range_factor_range(factor); +} + +isl::union_map basic_map::intersect_range_factor_range(const isl::union_map &factor) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).intersect_range_factor_range(factor); +} + +isl::map basic_map::intersect_range_wrapped_domain(const isl::set &domain) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).intersect_range_wrapped_domain(domain); +} + +isl::union_map basic_map::intersect_range_wrapped_domain(const isl::union_set &domain) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).intersect_range_wrapped_domain(domain); +} + +bool basic_map::is_bijective() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).is_bijective(); +} + +bool basic_map::is_disjoint(const isl::map &map2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).is_disjoint(map2); +} + +bool basic_map::is_disjoint(const isl::union_map &umap2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).is_disjoint(umap2); +} + +bool basic_map::is_empty() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_basic_map_is_empty(get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +bool basic_map::is_equal(const isl::basic_map &bmap2) const +{ + if (!ptr || bmap2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_basic_map_is_equal(get(), bmap2.get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +bool basic_map::is_equal(const isl::map &map2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).is_equal(map2); +} + +bool basic_map::is_equal(const isl::union_map &umap2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).is_equal(umap2); +} + +bool basic_map::is_injective() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).is_injective(); +} + +bool basic_map::is_single_valued() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).is_single_valued(); +} + +bool basic_map::is_strict_subset(const isl::map &map2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).is_strict_subset(map2); +} + +bool basic_map::is_strict_subset(const isl::union_map &umap2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).is_strict_subset(umap2); +} + +bool basic_map::is_subset(const isl::basic_map &bmap2) const +{ + if (!ptr || bmap2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_basic_map_is_subset(get(), bmap2.get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +bool basic_map::is_subset(const isl::map &map2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).is_subset(map2); +} + +bool basic_map::is_subset(const isl::union_map &umap2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).is_subset(umap2); +} + +bool basic_map::isa_map() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).isa_map(); +} + +isl::map basic_map::lex_ge_at(const isl::multi_pw_aff &mpa) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).lex_ge_at(mpa); +} + +isl::map basic_map::lex_gt_at(const isl::multi_pw_aff &mpa) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).lex_gt_at(mpa); +} + +isl::map basic_map::lex_le_at(const isl::multi_pw_aff &mpa) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).lex_le_at(mpa); +} + +isl::map basic_map::lex_lt_at(const isl::multi_pw_aff &mpa) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).lex_lt_at(mpa); +} + +isl::map basic_map::lexmax() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_basic_map_lexmax(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::pw_multi_aff basic_map::lexmax_pw_multi_aff() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).lexmax_pw_multi_aff(); +} + +isl::map basic_map::lexmin() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_basic_map_lexmin(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::pw_multi_aff basic_map::lexmin_pw_multi_aff() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).lexmin_pw_multi_aff(); +} + +isl::map basic_map::lower_bound(const isl::multi_pw_aff &lower) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).lower_bound(lower); +} + +isl::map_list basic_map::map_list() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).map_list(); +} + +isl::multi_pw_aff basic_map::max_multi_pw_aff() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).max_multi_pw_aff(); +} + +isl::multi_pw_aff basic_map::min_multi_pw_aff() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).min_multi_pw_aff(); +} + +unsigned basic_map::n_basic_map() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).n_basic_map(); +} + +isl::set basic_map::params() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).params(); +} + +isl::basic_map basic_map::polyhedral_hull() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).polyhedral_hull(); +} + +isl::map basic_map::preimage_domain(const isl::multi_aff &ma) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).preimage_domain(ma); +} + +isl::map basic_map::preimage_domain(const isl::multi_pw_aff &mpa) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).preimage_domain(mpa); +} + +isl::map basic_map::preimage_domain(const isl::pw_multi_aff &pma) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).preimage_domain(pma); +} + +isl::union_map basic_map::preimage_domain(const isl::union_pw_multi_aff &upma) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).preimage_domain(upma); +} + +isl::map basic_map::preimage_range(const isl::multi_aff &ma) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).preimage_range(ma); +} + +isl::map basic_map::preimage_range(const isl::pw_multi_aff &pma) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).preimage_range(pma); +} + +isl::union_map basic_map::preimage_range(const isl::union_pw_multi_aff &upma) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).preimage_range(upma); +} + +isl::map basic_map::product(const isl::map &map2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).product(map2); +} + +isl::union_map basic_map::product(const isl::union_map &umap2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).product(umap2); +} + +isl::map basic_map::project_out_all_params() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).project_out_all_params(); +} + +isl::map basic_map::project_out_param(const isl::id &id) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).project_out_param(id); +} + +isl::map basic_map::project_out_param(const std::string &id) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->project_out_param(isl::id(ctx(), id)); +} + +isl::map basic_map::project_out_param(const isl::id_list &list) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).project_out_param(list); +} + +isl::set basic_map::range() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).range(); +} + +isl::map basic_map::range_factor_domain() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).range_factor_domain(); +} + +isl::map basic_map::range_factor_range() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).range_factor_range(); +} + +isl::fixed_box basic_map::range_lattice_tile() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).range_lattice_tile(); +} + +isl::union_map basic_map::range_map() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).range_map(); +} + +isl::map basic_map::range_product(const isl::map &map2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).range_product(map2); +} + +isl::union_map basic_map::range_product(const isl::union_map &umap2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).range_product(umap2); +} + +isl::map basic_map::range_reverse() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).range_reverse(); +} + +isl::fixed_box basic_map::range_simple_fixed_box_hull() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).range_simple_fixed_box_hull(); +} + +unsigned basic_map::range_tuple_dim() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).range_tuple_dim(); +} + +isl::id basic_map::range_tuple_id() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).range_tuple_id(); +} + +isl::basic_map basic_map::reverse() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_basic_map_reverse(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::basic_map basic_map::sample() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_basic_map_sample(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::map basic_map::set_domain_tuple(const isl::id &id) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).set_domain_tuple(id); +} + +isl::map basic_map::set_domain_tuple(const std::string &id) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->set_domain_tuple(isl::id(ctx(), id)); +} + +isl::map basic_map::set_range_tuple(const isl::id &id) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).set_range_tuple(id); +} + +isl::map basic_map::set_range_tuple(const std::string &id) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->set_range_tuple(isl::id(ctx(), id)); +} + +isl::space basic_map::space() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).space(); +} + +isl::map basic_map::subtract(const isl::map &map2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).subtract(map2); +} + +isl::union_map basic_map::subtract(const isl::union_map &umap2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).subtract(umap2); +} + +isl::union_map basic_map::subtract_domain(const isl::union_set &dom) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).subtract_domain(dom); +} + +isl::union_map basic_map::subtract_range(const isl::union_set &dom) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).subtract_range(dom); +} + +isl::map_list basic_map::to_list() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).to_list(); +} + +isl::union_map basic_map::to_union_map() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).to_union_map(); +} + +isl::map basic_map::uncurry() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).uncurry(); +} + +isl::map basic_map::unite(isl::basic_map bmap2) const +{ + if (!ptr || bmap2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_basic_map_union(copy(), bmap2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::map basic_map::unite(const isl::map &map2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).unite(map2); +} + +isl::union_map basic_map::unite(const isl::union_map &umap2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).unite(umap2); +} + +isl::basic_map basic_map::unshifted_simple_hull() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).unshifted_simple_hull(); +} + +isl::map basic_map::upper_bound(const isl::multi_pw_aff &upper) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).upper_bound(upper); +} + +isl::set basic_map::wrap() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).wrap(); +} + +isl::map basic_map::zip() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::map(*this).zip(); +} + +inline std::ostream &operator<<(std::ostream &os, const basic_map &obj) +{ + if (!obj.get()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_basic_map_get_ctx(obj.get()); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + char *str = isl_basic_map_to_str(obj.get()); + if (!str) + exception::throw_last_error(saved_ctx); + os << str; + free(str); + return os; +} + +// implementations for isl::basic_set +basic_set manage(__isl_take isl_basic_set *ptr) { + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return basic_set(ptr); +} +basic_set manage_copy(__isl_keep isl_basic_set *ptr) { + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_basic_set_get_ctx(ptr); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + ptr = isl_basic_set_copy(ptr); + if (!ptr) + exception::throw_last_error(saved_ctx); + return basic_set(ptr); +} + +basic_set::basic_set(__isl_take isl_basic_set *ptr) + : ptr(ptr) {} + +basic_set::basic_set() + : ptr(nullptr) {} + +basic_set::basic_set(const basic_set &obj) + : ptr(nullptr) +{ + if (!obj.ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_basic_set_get_ctx(obj.ptr); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + ptr = obj.copy(); + if (!ptr) + exception::throw_last_error(saved_ctx); +} + +basic_set::basic_set(isl::point pnt) +{ + if (pnt.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = pnt.ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_basic_set_from_point(pnt.release()); + if (!res) + exception::throw_last_error(saved_ctx); + ptr = res; +} + +basic_set::basic_set(isl::ctx ctx, const std::string &str) +{ + auto saved_ctx = ctx; + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_basic_set_read_from_str(ctx.release(), str.c_str()); + if (!res) + exception::throw_last_error(saved_ctx); + ptr = res; +} + +basic_set &basic_set::operator=(basic_set obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +basic_set::~basic_set() { + if (ptr) + isl_basic_set_free(ptr); +} + +__isl_give isl_basic_set *basic_set::copy() const & { + return isl_basic_set_copy(ptr); +} + +__isl_keep isl_basic_set *basic_set::get() const { + return ptr; +} + +__isl_give isl_basic_set *basic_set::release() { + isl_basic_set *tmp = ptr; + ptr = nullptr; + return tmp; +} + +bool basic_set::is_null() const { + return ptr == nullptr; +} + +isl::ctx basic_set::ctx() const { + return isl::ctx(isl_basic_set_get_ctx(ptr)); +} + +isl::basic_set basic_set::affine_hull() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_basic_set_affine_hull(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::basic_set basic_set::apply(isl::basic_map bmap) const +{ + if (!ptr || bmap.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_basic_set_apply(copy(), bmap.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::set basic_set::apply(const isl::map &map) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::set(*this).apply(map); +} + +isl::union_set basic_set::apply(const isl::union_map &umap) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::set(*this).apply(umap); +} + +isl::pw_multi_aff basic_set::as_pw_multi_aff() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::set(*this).as_pw_multi_aff(); +} + +isl::set basic_set::as_set() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::set(*this).as_set(); +} + +isl::set basic_set::bind(const isl::multi_id &tuple) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::set(*this).bind(tuple); +} + +isl::set basic_set::coalesce() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::set(*this).coalesce(); +} + +isl::set basic_set::complement() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::set(*this).complement(); +} + +isl::union_set basic_set::compute_divs() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::set(*this).compute_divs(); +} + +isl::basic_set basic_set::detect_equalities() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_basic_set_detect_equalities(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::val basic_set::dim_max_val(int pos) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_basic_set_dim_max_val(copy(), pos); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::val basic_set::dim_min_val(int pos) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::set(*this).dim_min_val(pos); +} + +isl::set basic_set::drop_unused_params() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::set(*this).drop_unused_params(); +} + +bool basic_set::every_set(const std::function &test) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::set(*this).every_set(test); +} + +isl::set basic_set::extract_set(const isl::space &space) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::set(*this).extract_set(space); +} + +isl::basic_set basic_set::flatten() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_basic_set_flatten(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +void basic_set::foreach_basic_set(const std::function &fn) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::set(*this).foreach_basic_set(fn); +} + +void basic_set::foreach_point(const std::function &fn) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::set(*this).foreach_point(fn); +} + +void basic_set::foreach_set(const std::function &fn) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::set(*this).foreach_set(fn); +} + +isl::basic_set basic_set::gist(isl::basic_set context) const +{ + if (!ptr || context.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_basic_set_gist(copy(), context.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::set basic_set::gist(const isl::set &context) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::set(*this).gist(context); +} + +isl::union_set basic_set::gist(const isl::union_set &context) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::set(*this).gist(context); +} + +isl::basic_set basic_set::gist(const isl::point &context) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->gist(isl::basic_set(context)); +} + +isl::set basic_set::gist_params(const isl::set &context) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::set(*this).gist_params(context); +} + +isl::map basic_set::identity() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::set(*this).identity(); +} + +isl::pw_aff basic_set::indicator_function() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::set(*this).indicator_function(); +} + +isl::map basic_set::insert_domain(const isl::space &domain) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::set(*this).insert_domain(domain); +} + +isl::basic_set basic_set::intersect(isl::basic_set bset2) const +{ + if (!ptr || bset2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_basic_set_intersect(copy(), bset2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::set basic_set::intersect(const isl::set &set2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::set(*this).intersect(set2); +} + +isl::union_set basic_set::intersect(const isl::union_set &uset2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::set(*this).intersect(uset2); +} + +isl::basic_set basic_set::intersect(const isl::point &bset2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->intersect(isl::basic_set(bset2)); +} + +isl::basic_set basic_set::intersect_params(isl::basic_set bset2) const +{ + if (!ptr || bset2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_basic_set_intersect_params(copy(), bset2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::set basic_set::intersect_params(const isl::set ¶ms) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::set(*this).intersect_params(params); +} + +isl::basic_set basic_set::intersect_params(const isl::point &bset2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->intersect_params(isl::basic_set(bset2)); +} + +bool basic_set::involves_locals() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::set(*this).involves_locals(); +} + +bool basic_set::is_disjoint(const isl::set &set2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::set(*this).is_disjoint(set2); +} + +bool basic_set::is_disjoint(const isl::union_set &uset2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::set(*this).is_disjoint(uset2); +} + +bool basic_set::is_empty() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_basic_set_is_empty(get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +bool basic_set::is_equal(const isl::basic_set &bset2) const +{ + if (!ptr || bset2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_basic_set_is_equal(get(), bset2.get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +bool basic_set::is_equal(const isl::set &set2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::set(*this).is_equal(set2); +} + +bool basic_set::is_equal(const isl::union_set &uset2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::set(*this).is_equal(uset2); +} + +bool basic_set::is_equal(const isl::point &bset2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->is_equal(isl::basic_set(bset2)); +} + +bool basic_set::is_singleton() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::set(*this).is_singleton(); +} + +bool basic_set::is_strict_subset(const isl::set &set2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::set(*this).is_strict_subset(set2); +} + +bool basic_set::is_strict_subset(const isl::union_set &uset2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::set(*this).is_strict_subset(uset2); +} + +bool basic_set::is_subset(const isl::basic_set &bset2) const +{ + if (!ptr || bset2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_basic_set_is_subset(get(), bset2.get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +bool basic_set::is_subset(const isl::set &set2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::set(*this).is_subset(set2); +} + +bool basic_set::is_subset(const isl::union_set &uset2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::set(*this).is_subset(uset2); +} + +bool basic_set::is_subset(const isl::point &bset2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->is_subset(isl::basic_set(bset2)); +} + +bool basic_set::is_wrapping() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_basic_set_is_wrapping(get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +bool basic_set::isa_set() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::set(*this).isa_set(); +} + +isl::fixed_box basic_set::lattice_tile() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::set(*this).lattice_tile(); +} + +isl::set basic_set::lexmax() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_basic_set_lexmax(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::pw_multi_aff basic_set::lexmax_pw_multi_aff() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::set(*this).lexmax_pw_multi_aff(); +} + +isl::set basic_set::lexmin() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_basic_set_lexmin(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::pw_multi_aff basic_set::lexmin_pw_multi_aff() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::set(*this).lexmin_pw_multi_aff(); +} + +isl::set basic_set::lower_bound(const isl::multi_pw_aff &lower) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::set(*this).lower_bound(lower); +} + +isl::set basic_set::lower_bound(const isl::multi_val &lower) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::set(*this).lower_bound(lower); +} + +isl::multi_pw_aff basic_set::max_multi_pw_aff() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::set(*this).max_multi_pw_aff(); +} + +isl::val basic_set::max_val(const isl::aff &obj) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::set(*this).max_val(obj); +} + +isl::multi_pw_aff basic_set::min_multi_pw_aff() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::set(*this).min_multi_pw_aff(); +} + +isl::val basic_set::min_val(const isl::aff &obj) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::set(*this).min_val(obj); +} + +unsigned basic_set::n_basic_set() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::set(*this).n_basic_set(); +} + +isl::pw_aff basic_set::param_pw_aff_on_domain(const isl::id &id) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::set(*this).param_pw_aff_on_domain(id); +} + +isl::pw_aff basic_set::param_pw_aff_on_domain(const std::string &id) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->param_pw_aff_on_domain(isl::id(ctx(), id)); +} + +isl::basic_set basic_set::params() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_basic_set_params(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_val basic_set::plain_multi_val_if_fixed() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::set(*this).plain_multi_val_if_fixed(); +} + +isl::basic_set basic_set::polyhedral_hull() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::set(*this).polyhedral_hull(); +} + +isl::set basic_set::preimage(const isl::multi_aff &ma) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::set(*this).preimage(ma); +} + +isl::set basic_set::preimage(const isl::multi_pw_aff &mpa) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::set(*this).preimage(mpa); +} + +isl::set basic_set::preimage(const isl::pw_multi_aff &pma) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::set(*this).preimage(pma); +} + +isl::union_set basic_set::preimage(const isl::union_pw_multi_aff &upma) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::set(*this).preimage(upma); +} + +isl::set basic_set::product(const isl::set &set2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::set(*this).product(set2); +} + +isl::set basic_set::project_out_all_params() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::set(*this).project_out_all_params(); +} + +isl::set basic_set::project_out_param(const isl::id &id) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::set(*this).project_out_param(id); +} + +isl::set basic_set::project_out_param(const std::string &id) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->project_out_param(isl::id(ctx(), id)); +} + +isl::set basic_set::project_out_param(const isl::id_list &list) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::set(*this).project_out_param(list); +} + +isl::pw_aff basic_set::pw_aff_on_domain(const isl::val &v) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::set(*this).pw_aff_on_domain(v); +} + +isl::pw_aff basic_set::pw_aff_on_domain(long v) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->pw_aff_on_domain(isl::val(ctx(), v)); +} + +isl::pw_multi_aff basic_set::pw_multi_aff_on_domain(const isl::multi_val &mv) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::set(*this).pw_multi_aff_on_domain(mv); +} + +isl::basic_set basic_set::sample() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_basic_set_sample(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::point basic_set::sample_point() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_basic_set_sample_point(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::set_list basic_set::set_list() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::set(*this).set_list(); +} + +isl::fixed_box basic_set::simple_fixed_box_hull() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::set(*this).simple_fixed_box_hull(); +} + +isl::space basic_set::space() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::set(*this).space(); +} + +isl::val basic_set::stride(int pos) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::set(*this).stride(pos); +} + +isl::set basic_set::subtract(const isl::set &set2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::set(*this).subtract(set2); +} + +isl::union_set basic_set::subtract(const isl::union_set &uset2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::set(*this).subtract(uset2); +} + +isl::set_list basic_set::to_list() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::set(*this).to_list(); +} + +isl::set basic_set::to_set() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_basic_set_to_set(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_set basic_set::to_union_set() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::set(*this).to_union_set(); +} + +isl::map basic_set::translation() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::set(*this).translation(); +} + +unsigned basic_set::tuple_dim() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::set(*this).tuple_dim(); +} + +isl::set basic_set::unbind_params(const isl::multi_id &tuple) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::set(*this).unbind_params(tuple); +} + +isl::map basic_set::unbind_params_insert_domain(const isl::multi_id &domain) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::set(*this).unbind_params_insert_domain(domain); +} + +isl::set basic_set::unite(isl::basic_set bset2) const +{ + if (!ptr || bset2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_basic_set_union(copy(), bset2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::set basic_set::unite(const isl::set &set2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::set(*this).unite(set2); +} + +isl::union_set basic_set::unite(const isl::union_set &uset2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::set(*this).unite(uset2); +} + +isl::set basic_set::unite(const isl::point &bset2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->unite(isl::basic_set(bset2)); +} + +isl::basic_set basic_set::unshifted_simple_hull() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::set(*this).unshifted_simple_hull(); +} + +isl::map basic_set::unwrap() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::set(*this).unwrap(); +} + +isl::set basic_set::upper_bound(const isl::multi_pw_aff &upper) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::set(*this).upper_bound(upper); +} + +isl::set basic_set::upper_bound(const isl::multi_val &upper) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::set(*this).upper_bound(upper); +} + +isl::set basic_set::wrapped_reverse() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::set(*this).wrapped_reverse(); +} + +inline std::ostream &operator<<(std::ostream &os, const basic_set &obj) +{ + if (!obj.get()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_basic_set_get_ctx(obj.get()); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + char *str = isl_basic_set_to_str(obj.get()); + if (!str) + exception::throw_last_error(saved_ctx); + os << str; + free(str); + return os; +} + +// implementations for isl::fixed_box +fixed_box manage(__isl_take isl_fixed_box *ptr) { + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return fixed_box(ptr); +} +fixed_box manage_copy(__isl_keep isl_fixed_box *ptr) { + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_fixed_box_get_ctx(ptr); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + ptr = isl_fixed_box_copy(ptr); + if (!ptr) + exception::throw_last_error(saved_ctx); + return fixed_box(ptr); +} + +fixed_box::fixed_box(__isl_take isl_fixed_box *ptr) + : ptr(ptr) {} + +fixed_box::fixed_box() + : ptr(nullptr) {} + +fixed_box::fixed_box(const fixed_box &obj) + : ptr(nullptr) +{ + if (!obj.ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_fixed_box_get_ctx(obj.ptr); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + ptr = obj.copy(); + if (!ptr) + exception::throw_last_error(saved_ctx); +} + +fixed_box::fixed_box(isl::ctx ctx, const std::string &str) +{ + auto saved_ctx = ctx; + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_fixed_box_read_from_str(ctx.release(), str.c_str()); + if (!res) + exception::throw_last_error(saved_ctx); + ptr = res; +} + +fixed_box &fixed_box::operator=(fixed_box obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +fixed_box::~fixed_box() { + if (ptr) + isl_fixed_box_free(ptr); +} + +__isl_give isl_fixed_box *fixed_box::copy() const & { + return isl_fixed_box_copy(ptr); +} + +__isl_keep isl_fixed_box *fixed_box::get() const { + return ptr; +} + +__isl_give isl_fixed_box *fixed_box::release() { + isl_fixed_box *tmp = ptr; + ptr = nullptr; + return tmp; +} + +bool fixed_box::is_null() const { + return ptr == nullptr; +} + +isl::ctx fixed_box::ctx() const { + return isl::ctx(isl_fixed_box_get_ctx(ptr)); +} + +bool fixed_box::is_valid() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_fixed_box_is_valid(get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +isl::multi_aff fixed_box::offset() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_fixed_box_get_offset(get()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_aff fixed_box::get_offset() const +{ + return offset(); +} + +isl::multi_val fixed_box::size() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_fixed_box_get_size(get()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_val fixed_box::get_size() const +{ + return size(); +} + +isl::space fixed_box::space() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_fixed_box_get_space(get()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::space fixed_box::get_space() const +{ + return space(); +} + +inline std::ostream &operator<<(std::ostream &os, const fixed_box &obj) +{ + if (!obj.get()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_fixed_box_get_ctx(obj.get()); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + char *str = isl_fixed_box_to_str(obj.get()); + if (!str) + exception::throw_last_error(saved_ctx); + os << str; + free(str); + return os; +} + +// implementations for isl::id +id manage(__isl_take isl_id *ptr) { + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return id(ptr); +} +id manage_copy(__isl_keep isl_id *ptr) { + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_id_get_ctx(ptr); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + ptr = isl_id_copy(ptr); + if (!ptr) + exception::throw_last_error(saved_ctx); + return id(ptr); +} + +id::id(__isl_take isl_id *ptr) + : ptr(ptr) {} + +id::id() + : ptr(nullptr) {} + +id::id(const id &obj) + : ptr(nullptr) +{ + if (!obj.ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_id_get_ctx(obj.ptr); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + ptr = obj.copy(); + if (!ptr) + exception::throw_last_error(saved_ctx); +} + +id::id(isl::ctx ctx, const std::string &str) +{ + auto saved_ctx = ctx; + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_id_read_from_str(ctx.release(), str.c_str()); + if (!res) + exception::throw_last_error(saved_ctx); + ptr = res; +} + +id &id::operator=(id obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +id::~id() { + if (ptr) + isl_id_free(ptr); +} + +__isl_give isl_id *id::copy() const & { + return isl_id_copy(ptr); +} + +__isl_keep isl_id *id::get() const { + return ptr; +} + +__isl_give isl_id *id::release() { + isl_id *tmp = ptr; + ptr = nullptr; + return tmp; +} + +bool id::is_null() const { + return ptr == nullptr; +} + +isl::ctx id::ctx() const { + return isl::ctx(isl_id_get_ctx(ptr)); +} + +std::string id::name() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_id_get_name(get()); + std::string tmp(res); + return tmp; +} + +std::string id::get_name() const +{ + return name(); +} + +isl::id_list id::to_list() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_id_to_list(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +#if __cplusplus >= 201703L +id::id(isl::ctx ctx, const std::string &str, const std::any &any) +{ + auto saved_ctx = ctx; + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + std::any *p = new std::any(any); + auto res = isl_id_alloc(ctx.get(), str.c_str(), p); + res = isl_id_set_free_user(res, &ctx::free_user); + if (!res) { + delete p; + exception::throw_last_error(saved_ctx); + } + ptr = res; +} + +template +std::optional id::try_user() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + std::any *p = (std::any *) isl_id_get_user(ptr); + if (!p) + return std::nullopt; + if (isl_id_get_free_user(ptr) != &ctx::free_user) + return std::nullopt; + T *res = std::any_cast(p); + if (!res) + return std::nullopt; + return *res; +} + +template +T id::user() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + std::any *p = (std::any *) isl_id_get_user(ptr); + if (!p) + exception::throw_invalid("no user pointer", __FILE__, __LINE__); + if (isl_id_get_free_user(ptr) != &ctx::free_user) + exception::throw_invalid("user pointer not attached by C++ interface", __FILE__, __LINE__); + T *res = std::any_cast(p); + if (!res) + exception::throw_invalid("user pointer not of given type", __FILE__, __LINE__); + return *res; +} +#endif + +inline std::ostream &operator<<(std::ostream &os, const id &obj) +{ + if (!obj.get()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_id_get_ctx(obj.get()); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + char *str = isl_id_to_str(obj.get()); + if (!str) + exception::throw_last_error(saved_ctx); + os << str; + free(str); + return os; +} + +// implementations for isl::id_list +id_list manage(__isl_take isl_id_list *ptr) { + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return id_list(ptr); +} +id_list manage_copy(__isl_keep isl_id_list *ptr) { + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_id_list_get_ctx(ptr); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + ptr = isl_id_list_copy(ptr); + if (!ptr) + exception::throw_last_error(saved_ctx); + return id_list(ptr); +} + +id_list::id_list(__isl_take isl_id_list *ptr) + : ptr(ptr) {} + +id_list::id_list() + : ptr(nullptr) {} + +id_list::id_list(const id_list &obj) + : ptr(nullptr) +{ + if (!obj.ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_id_list_get_ctx(obj.ptr); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + ptr = obj.copy(); + if (!ptr) + exception::throw_last_error(saved_ctx); +} + +id_list::id_list(isl::ctx ctx, int n) +{ + auto saved_ctx = ctx; + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_id_list_alloc(ctx.release(), n); + if (!res) + exception::throw_last_error(saved_ctx); + ptr = res; +} + +id_list::id_list(isl::id el) +{ + if (el.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = el.ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_id_list_from_id(el.release()); + if (!res) + exception::throw_last_error(saved_ctx); + ptr = res; +} + +id_list::id_list(isl::ctx ctx, const std::string &str) +{ + auto saved_ctx = ctx; + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_id_list_read_from_str(ctx.release(), str.c_str()); + if (!res) + exception::throw_last_error(saved_ctx); + ptr = res; +} + +id_list &id_list::operator=(id_list obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +id_list::~id_list() { + if (ptr) + isl_id_list_free(ptr); +} + +__isl_give isl_id_list *id_list::copy() const & { + return isl_id_list_copy(ptr); +} + +__isl_keep isl_id_list *id_list::get() const { + return ptr; +} + +__isl_give isl_id_list *id_list::release() { + isl_id_list *tmp = ptr; + ptr = nullptr; + return tmp; +} + +bool id_list::is_null() const { + return ptr == nullptr; +} + +isl::ctx id_list::ctx() const { + return isl::ctx(isl_id_list_get_ctx(ptr)); +} + +isl::id_list id_list::add(isl::id el) const +{ + if (!ptr || el.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_id_list_add(copy(), el.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::id_list id_list::add(const std::string &el) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->add(isl::id(ctx(), el)); +} + +isl::id id_list::at(int index) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_id_list_get_at(get(), index); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::id id_list::get_at(int index) const +{ + return at(index); +} + +isl::id_list id_list::clear() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_id_list_clear(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::id_list id_list::concat(isl::id_list list2) const +{ + if (!ptr || list2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_id_list_concat(copy(), list2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::id_list id_list::drop(unsigned int first, unsigned int n) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_id_list_drop(copy(), first, n); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +void id_list::foreach(const std::function &fn) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + struct fn_data { + std::function func; + std::exception_ptr eptr; + } fn_data = { fn }; + auto fn_lambda = [](isl_id *arg_0, void *arg_1) -> isl_stat { + auto *data = static_cast(arg_1); + ISL_CPP_TRY { + (data->func)(manage(arg_0)); + return isl_stat_ok; + } ISL_CPP_CATCH_ALL { + data->eptr = std::current_exception(); + return isl_stat_error; + } + }; + auto res = isl_id_list_foreach(get(), fn_lambda, &fn_data); + if (fn_data.eptr) + std::rethrow_exception(fn_data.eptr); + if (res < 0) + exception::throw_last_error(saved_ctx); + return; +} + +void id_list::foreach_scc(const std::function &follows, const std::function &fn) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + struct follows_data { + std::function func; + std::exception_ptr eptr; + } follows_data = { follows }; + auto follows_lambda = [](isl_id *arg_0, isl_id *arg_1, void *arg_2) -> isl_bool { + auto *data = static_cast(arg_2); + ISL_CPP_TRY { + auto ret = (data->func)(manage_copy(arg_0), manage_copy(arg_1)); + return ret ? isl_bool_true : isl_bool_false; + } ISL_CPP_CATCH_ALL { + data->eptr = std::current_exception(); + return isl_bool_error; + } + }; + struct fn_data { + std::function func; + std::exception_ptr eptr; + } fn_data = { fn }; + auto fn_lambda = [](isl_id_list *arg_0, void *arg_1) -> isl_stat { + auto *data = static_cast(arg_1); + ISL_CPP_TRY { + (data->func)(manage(arg_0)); + return isl_stat_ok; + } ISL_CPP_CATCH_ALL { + data->eptr = std::current_exception(); + return isl_stat_error; + } + }; + auto res = isl_id_list_foreach_scc(get(), follows_lambda, &follows_data, fn_lambda, &fn_data); + if (follows_data.eptr) + std::rethrow_exception(follows_data.eptr); + if (fn_data.eptr) + std::rethrow_exception(fn_data.eptr); + if (res < 0) + exception::throw_last_error(saved_ctx); + return; +} + +isl::id_list id_list::insert(unsigned int pos, isl::id el) const +{ + if (!ptr || el.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_id_list_insert(copy(), pos, el.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::id_list id_list::insert(unsigned int pos, const std::string &el) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->insert(pos, isl::id(ctx(), el)); +} + +isl::id_list id_list::set_at(int index, isl::id el) const +{ + if (!ptr || el.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_id_list_set_at(copy(), index, el.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::id_list id_list::set_at(int index, const std::string &el) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->set_at(index, isl::id(ctx(), el)); +} + +unsigned id_list::size() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_id_list_size(get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +inline std::ostream &operator<<(std::ostream &os, const id_list &obj) +{ + if (!obj.get()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_id_list_get_ctx(obj.get()); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + char *str = isl_id_list_to_str(obj.get()); + if (!str) + exception::throw_last_error(saved_ctx); + os << str; + free(str); + return os; +} + +// implementations for isl::id_to_ast_expr +id_to_ast_expr manage(__isl_take isl_id_to_ast_expr *ptr) { + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return id_to_ast_expr(ptr); +} +id_to_ast_expr manage_copy(__isl_keep isl_id_to_ast_expr *ptr) { + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_id_to_ast_expr_get_ctx(ptr); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + ptr = isl_id_to_ast_expr_copy(ptr); + if (!ptr) + exception::throw_last_error(saved_ctx); + return id_to_ast_expr(ptr); +} + +id_to_ast_expr::id_to_ast_expr(__isl_take isl_id_to_ast_expr *ptr) + : ptr(ptr) {} + +id_to_ast_expr::id_to_ast_expr() + : ptr(nullptr) {} + +id_to_ast_expr::id_to_ast_expr(const id_to_ast_expr &obj) + : ptr(nullptr) +{ + if (!obj.ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_id_to_ast_expr_get_ctx(obj.ptr); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + ptr = obj.copy(); + if (!ptr) + exception::throw_last_error(saved_ctx); +} + +id_to_ast_expr::id_to_ast_expr(isl::ctx ctx, int min_size) +{ + auto saved_ctx = ctx; + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_id_to_ast_expr_alloc(ctx.release(), min_size); + if (!res) + exception::throw_last_error(saved_ctx); + ptr = res; +} + +id_to_ast_expr::id_to_ast_expr(isl::ctx ctx, const std::string &str) +{ + auto saved_ctx = ctx; + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_id_to_ast_expr_read_from_str(ctx.release(), str.c_str()); + if (!res) + exception::throw_last_error(saved_ctx); + ptr = res; +} + +id_to_ast_expr &id_to_ast_expr::operator=(id_to_ast_expr obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +id_to_ast_expr::~id_to_ast_expr() { + if (ptr) + isl_id_to_ast_expr_free(ptr); +} + +__isl_give isl_id_to_ast_expr *id_to_ast_expr::copy() const & { + return isl_id_to_ast_expr_copy(ptr); +} + +__isl_keep isl_id_to_ast_expr *id_to_ast_expr::get() const { + return ptr; +} + +__isl_give isl_id_to_ast_expr *id_to_ast_expr::release() { + isl_id_to_ast_expr *tmp = ptr; + ptr = nullptr; + return tmp; +} + +bool id_to_ast_expr::is_null() const { + return ptr == nullptr; +} + +isl::ctx id_to_ast_expr::ctx() const { + return isl::ctx(isl_id_to_ast_expr_get_ctx(ptr)); +} + +bool id_to_ast_expr::is_equal(const isl::id_to_ast_expr &hmap2) const +{ + if (!ptr || hmap2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_id_to_ast_expr_is_equal(get(), hmap2.get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +isl::id_to_ast_expr id_to_ast_expr::set(isl::id key, isl::ast_expr val) const +{ + if (!ptr || key.is_null() || val.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_id_to_ast_expr_set(copy(), key.release(), val.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::id_to_ast_expr id_to_ast_expr::set(const std::string &key, const isl::ast_expr &val) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->set(isl::id(ctx(), key), val); +} + +inline std::ostream &operator<<(std::ostream &os, const id_to_ast_expr &obj) +{ + if (!obj.get()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_id_to_ast_expr_get_ctx(obj.get()); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + char *str = isl_id_to_ast_expr_to_str(obj.get()); + if (!str) + exception::throw_last_error(saved_ctx); + os << str; + free(str); + return os; +} + +// implementations for isl::id_to_id +id_to_id manage(__isl_take isl_id_to_id *ptr) { + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return id_to_id(ptr); +} +id_to_id manage_copy(__isl_keep isl_id_to_id *ptr) { + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_id_to_id_get_ctx(ptr); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + ptr = isl_id_to_id_copy(ptr); + if (!ptr) + exception::throw_last_error(saved_ctx); + return id_to_id(ptr); +} + +id_to_id::id_to_id(__isl_take isl_id_to_id *ptr) + : ptr(ptr) {} + +id_to_id::id_to_id() + : ptr(nullptr) {} + +id_to_id::id_to_id(const id_to_id &obj) + : ptr(nullptr) +{ + if (!obj.ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_id_to_id_get_ctx(obj.ptr); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + ptr = obj.copy(); + if (!ptr) + exception::throw_last_error(saved_ctx); +} + +id_to_id::id_to_id(isl::ctx ctx, int min_size) +{ + auto saved_ctx = ctx; + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_id_to_id_alloc(ctx.release(), min_size); + if (!res) + exception::throw_last_error(saved_ctx); + ptr = res; +} + +id_to_id::id_to_id(isl::ctx ctx, const std::string &str) +{ + auto saved_ctx = ctx; + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_id_to_id_read_from_str(ctx.release(), str.c_str()); + if (!res) + exception::throw_last_error(saved_ctx); + ptr = res; +} + +id_to_id &id_to_id::operator=(id_to_id obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +id_to_id::~id_to_id() { + if (ptr) + isl_id_to_id_free(ptr); +} + +__isl_give isl_id_to_id *id_to_id::copy() const & { + return isl_id_to_id_copy(ptr); +} + +__isl_keep isl_id_to_id *id_to_id::get() const { + return ptr; +} + +__isl_give isl_id_to_id *id_to_id::release() { + isl_id_to_id *tmp = ptr; + ptr = nullptr; + return tmp; +} + +bool id_to_id::is_null() const { + return ptr == nullptr; +} + +isl::ctx id_to_id::ctx() const { + return isl::ctx(isl_id_to_id_get_ctx(ptr)); +} + +bool id_to_id::is_equal(const isl::id_to_id &hmap2) const +{ + if (!ptr || hmap2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_id_to_id_is_equal(get(), hmap2.get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +isl::id_to_id id_to_id::set(isl::id key, isl::id val) const +{ + if (!ptr || key.is_null() || val.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_id_to_id_set(copy(), key.release(), val.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::id_to_id id_to_id::set(const isl::id &key, const std::string &val) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->set(key, isl::id(ctx(), val)); +} + +isl::id_to_id id_to_id::set(const std::string &key, const isl::id &val) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->set(isl::id(ctx(), key), val); +} + +isl::id_to_id id_to_id::set(const std::string &key, const std::string &val) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->set(isl::id(ctx(), key), isl::id(ctx(), val)); +} + +inline std::ostream &operator<<(std::ostream &os, const id_to_id &obj) +{ + if (!obj.get()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_id_to_id_get_ctx(obj.get()); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + char *str = isl_id_to_id_to_str(obj.get()); + if (!str) + exception::throw_last_error(saved_ctx); + os << str; + free(str); + return os; +} + +// implementations for isl::map +map manage(__isl_take isl_map *ptr) { + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return map(ptr); +} +map manage_copy(__isl_keep isl_map *ptr) { + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_map_get_ctx(ptr); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + ptr = isl_map_copy(ptr); + if (!ptr) + exception::throw_last_error(saved_ctx); + return map(ptr); +} + +map::map(__isl_take isl_map *ptr) + : ptr(ptr) {} + +map::map() + : ptr(nullptr) {} + +map::map(const map &obj) + : ptr(nullptr) +{ + if (!obj.ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_map_get_ctx(obj.ptr); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + ptr = obj.copy(); + if (!ptr) + exception::throw_last_error(saved_ctx); +} + +map::map(isl::basic_map bmap) +{ + if (bmap.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = bmap.ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_from_basic_map(bmap.release()); + if (!res) + exception::throw_last_error(saved_ctx); + ptr = res; +} + +map::map(isl::ctx ctx, const std::string &str) +{ + auto saved_ctx = ctx; + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_read_from_str(ctx.release(), str.c_str()); + if (!res) + exception::throw_last_error(saved_ctx); + ptr = res; +} + +map &map::operator=(map obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +map::~map() { + if (ptr) + isl_map_free(ptr); +} + +__isl_give isl_map *map::copy() const & { + return isl_map_copy(ptr); +} + +__isl_keep isl_map *map::get() const { + return ptr; +} + +__isl_give isl_map *map::release() { + isl_map *tmp = ptr; + ptr = nullptr; + return tmp; +} + +bool map::is_null() const { + return ptr == nullptr; +} + +isl::ctx map::ctx() const { + return isl::ctx(isl_map_get_ctx(ptr)); +} + +isl::basic_map map::affine_hull() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_affine_hull(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::map map::apply_domain(isl::map map2) const +{ + if (!ptr || map2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_apply_domain(copy(), map2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map map::apply_domain(const isl::union_map &umap2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_map(*this).apply_domain(umap2); +} + +isl::map map::apply_domain(const isl::basic_map &map2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->apply_domain(isl::map(map2)); +} + +isl::map map::apply_range(isl::map map2) const +{ + if (!ptr || map2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_apply_range(copy(), map2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map map::apply_range(const isl::union_map &umap2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_map(*this).apply_range(umap2); +} + +isl::map map::apply_range(const isl::basic_map &map2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->apply_range(isl::map(map2)); +} + +isl::map map::as_map() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_map(*this).as_map(); +} + +isl::multi_union_pw_aff map::as_multi_union_pw_aff() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_map(*this).as_multi_union_pw_aff(); +} + +isl::pw_multi_aff map::as_pw_multi_aff() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_as_pw_multi_aff(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_pw_multi_aff map::as_union_pw_multi_aff() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_map(*this).as_union_pw_multi_aff(); +} + +isl::set map::bind_domain(isl::multi_id tuple) const +{ + if (!ptr || tuple.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_bind_domain(copy(), tuple.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::set map::bind_range(isl::multi_id tuple) const +{ + if (!ptr || tuple.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_bind_range(copy(), tuple.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::map map::coalesce() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_coalesce(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::map map::complement() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_complement(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map map::compute_divs() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_map(*this).compute_divs(); +} + +isl::map map::curry() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_curry(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::set map::deltas() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_deltas(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::map map::detect_equalities() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_detect_equalities(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::set map::domain() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_domain(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::map map::domain_factor_domain() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_domain_factor_domain(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::map map::domain_factor_range() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_domain_factor_range(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map map::domain_map() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_map(*this).domain_map(); +} + +isl::union_pw_multi_aff map::domain_map_union_pw_multi_aff() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_map(*this).domain_map_union_pw_multi_aff(); +} + +isl::map map::domain_product(isl::map map2) const +{ + if (!ptr || map2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_domain_product(copy(), map2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map map::domain_product(const isl::union_map &umap2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_map(*this).domain_product(umap2); +} + +isl::map map::domain_product(const isl::basic_map &map2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->domain_product(isl::map(map2)); +} + +isl::map map::domain_reverse() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_domain_reverse(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +unsigned map::domain_tuple_dim() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_domain_tuple_dim(get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +isl::id map::domain_tuple_id() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_get_domain_tuple_id(get()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::id map::get_domain_tuple_id() const +{ + return domain_tuple_id(); +} + +isl::map map::drop_unused_params() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_drop_unused_params(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::map map::empty(isl::space space) +{ + if (space.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = space.ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_empty(space.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::map map::eq_at(isl::multi_pw_aff mpa) const +{ + if (!ptr || mpa.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_eq_at_multi_pw_aff(copy(), mpa.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map map::eq_at(const isl::multi_union_pw_aff &mupa) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_map(*this).eq_at(mupa); +} + +isl::map map::eq_at(const isl::aff &mpa) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->eq_at(isl::multi_pw_aff(mpa)); +} + +isl::map map::eq_at(const isl::multi_aff &mpa) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->eq_at(isl::multi_pw_aff(mpa)); +} + +isl::map map::eq_at(const isl::pw_aff &mpa) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->eq_at(isl::multi_pw_aff(mpa)); +} + +isl::map map::eq_at(const isl::pw_multi_aff &mpa) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->eq_at(isl::multi_pw_aff(mpa)); +} + +bool map::every_map(const std::function &test) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_map(*this).every_map(test); +} + +isl::map map::extract_map(const isl::space &space) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_map(*this).extract_map(space); +} + +isl::map map::factor_domain() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_factor_domain(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::map map::factor_range() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_factor_range(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::map map::fixed_power(isl::val exp) const +{ + if (!ptr || exp.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_fixed_power_val(copy(), exp.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::map map::fixed_power(long exp) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->fixed_power(isl::val(ctx(), exp)); +} + +isl::map map::flatten() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_flatten(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::map map::flatten_domain() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_flatten_domain(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::map map::flatten_range() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_flatten_range(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +void map::foreach_basic_map(const std::function &fn) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + struct fn_data { + std::function func; + std::exception_ptr eptr; + } fn_data = { fn }; + auto fn_lambda = [](isl_basic_map *arg_0, void *arg_1) -> isl_stat { + auto *data = static_cast(arg_1); + ISL_CPP_TRY { + (data->func)(manage(arg_0)); + return isl_stat_ok; + } ISL_CPP_CATCH_ALL { + data->eptr = std::current_exception(); + return isl_stat_error; + } + }; + auto res = isl_map_foreach_basic_map(get(), fn_lambda, &fn_data); + if (fn_data.eptr) + std::rethrow_exception(fn_data.eptr); + if (res < 0) + exception::throw_last_error(saved_ctx); + return; +} + +void map::foreach_map(const std::function &fn) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_map(*this).foreach_map(fn); +} + +isl::map map::gist(isl::map context) const +{ + if (!ptr || context.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_gist(copy(), context.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map map::gist(const isl::union_map &context) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_map(*this).gist(context); +} + +isl::map map::gist(const isl::basic_map &context) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->gist(isl::map(context)); +} + +isl::map map::gist_domain(isl::set context) const +{ + if (!ptr || context.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_gist_domain(copy(), context.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map map::gist_domain(const isl::union_set &uset) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_map(*this).gist_domain(uset); +} + +isl::map map::gist_domain(const isl::basic_set &context) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->gist_domain(isl::set(context)); +} + +isl::map map::gist_domain(const isl::point &context) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->gist_domain(isl::set(context)); +} + +isl::map map::gist_params(isl::set context) const +{ + if (!ptr || context.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_gist_params(copy(), context.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map map::gist_range(const isl::union_set &uset) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_map(*this).gist_range(uset); +} + +bool map::has_domain_tuple_id() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_has_domain_tuple_id(get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +bool map::has_range_tuple_id() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_has_range_tuple_id(get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +isl::map map::intersect(isl::map map2) const +{ + if (!ptr || map2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_intersect(copy(), map2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map map::intersect(const isl::union_map &umap2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_map(*this).intersect(umap2); +} + +isl::map map::intersect(const isl::basic_map &map2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->intersect(isl::map(map2)); +} + +isl::map map::intersect_domain(isl::set set) const +{ + if (!ptr || set.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_intersect_domain(copy(), set.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map map::intersect_domain(const isl::space &space) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_map(*this).intersect_domain(space); +} + +isl::union_map map::intersect_domain(const isl::union_set &uset) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_map(*this).intersect_domain(uset); +} + +isl::map map::intersect_domain(const isl::basic_set &set) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->intersect_domain(isl::set(set)); +} + +isl::map map::intersect_domain(const isl::point &set) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->intersect_domain(isl::set(set)); +} + +isl::map map::intersect_domain_factor_domain(isl::map factor) const +{ + if (!ptr || factor.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_intersect_domain_factor_domain(copy(), factor.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map map::intersect_domain_factor_domain(const isl::union_map &factor) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_map(*this).intersect_domain_factor_domain(factor); +} + +isl::map map::intersect_domain_factor_domain(const isl::basic_map &factor) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->intersect_domain_factor_domain(isl::map(factor)); +} + +isl::map map::intersect_domain_factor_range(isl::map factor) const +{ + if (!ptr || factor.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_intersect_domain_factor_range(copy(), factor.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map map::intersect_domain_factor_range(const isl::union_map &factor) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_map(*this).intersect_domain_factor_range(factor); +} + +isl::map map::intersect_domain_factor_range(const isl::basic_map &factor) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->intersect_domain_factor_range(isl::map(factor)); +} + +isl::map map::intersect_domain_wrapped_domain(isl::set domain) const +{ + if (!ptr || domain.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_intersect_domain_wrapped_domain(copy(), domain.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map map::intersect_domain_wrapped_domain(const isl::union_set &domain) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_map(*this).intersect_domain_wrapped_domain(domain); +} + +isl::map map::intersect_domain_wrapped_domain(const isl::basic_set &domain) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->intersect_domain_wrapped_domain(isl::set(domain)); +} + +isl::map map::intersect_domain_wrapped_domain(const isl::point &domain) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->intersect_domain_wrapped_domain(isl::set(domain)); +} + +isl::map map::intersect_params(isl::set params) const +{ + if (!ptr || params.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_intersect_params(copy(), params.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::map map::intersect_range(isl::set set) const +{ + if (!ptr || set.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_intersect_range(copy(), set.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map map::intersect_range(const isl::space &space) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_map(*this).intersect_range(space); +} + +isl::union_map map::intersect_range(const isl::union_set &uset) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_map(*this).intersect_range(uset); +} + +isl::map map::intersect_range(const isl::basic_set &set) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->intersect_range(isl::set(set)); +} + +isl::map map::intersect_range(const isl::point &set) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->intersect_range(isl::set(set)); +} + +isl::map map::intersect_range_factor_domain(isl::map factor) const +{ + if (!ptr || factor.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_intersect_range_factor_domain(copy(), factor.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map map::intersect_range_factor_domain(const isl::union_map &factor) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_map(*this).intersect_range_factor_domain(factor); +} + +isl::map map::intersect_range_factor_domain(const isl::basic_map &factor) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->intersect_range_factor_domain(isl::map(factor)); +} + +isl::map map::intersect_range_factor_range(isl::map factor) const +{ + if (!ptr || factor.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_intersect_range_factor_range(copy(), factor.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map map::intersect_range_factor_range(const isl::union_map &factor) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_map(*this).intersect_range_factor_range(factor); +} + +isl::map map::intersect_range_factor_range(const isl::basic_map &factor) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->intersect_range_factor_range(isl::map(factor)); +} + +isl::map map::intersect_range_wrapped_domain(isl::set domain) const +{ + if (!ptr || domain.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_intersect_range_wrapped_domain(copy(), domain.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map map::intersect_range_wrapped_domain(const isl::union_set &domain) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_map(*this).intersect_range_wrapped_domain(domain); +} + +isl::map map::intersect_range_wrapped_domain(const isl::basic_set &domain) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->intersect_range_wrapped_domain(isl::set(domain)); +} + +isl::map map::intersect_range_wrapped_domain(const isl::point &domain) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->intersect_range_wrapped_domain(isl::set(domain)); +} + +bool map::is_bijective() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_is_bijective(get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +bool map::is_disjoint(const isl::map &map2) const +{ + if (!ptr || map2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_is_disjoint(get(), map2.get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +bool map::is_disjoint(const isl::union_map &umap2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_map(*this).is_disjoint(umap2); +} + +bool map::is_disjoint(const isl::basic_map &map2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->is_disjoint(isl::map(map2)); +} + +bool map::is_empty() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_is_empty(get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +bool map::is_equal(const isl::map &map2) const +{ + if (!ptr || map2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_is_equal(get(), map2.get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +bool map::is_equal(const isl::union_map &umap2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_map(*this).is_equal(umap2); +} + +bool map::is_equal(const isl::basic_map &map2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->is_equal(isl::map(map2)); +} + +bool map::is_injective() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_is_injective(get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +bool map::is_single_valued() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_is_single_valued(get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +bool map::is_strict_subset(const isl::map &map2) const +{ + if (!ptr || map2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_is_strict_subset(get(), map2.get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +bool map::is_strict_subset(const isl::union_map &umap2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_map(*this).is_strict_subset(umap2); +} + +bool map::is_strict_subset(const isl::basic_map &map2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->is_strict_subset(isl::map(map2)); +} + +bool map::is_subset(const isl::map &map2) const +{ + if (!ptr || map2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_is_subset(get(), map2.get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +bool map::is_subset(const isl::union_map &umap2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_map(*this).is_subset(umap2); +} + +bool map::is_subset(const isl::basic_map &map2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->is_subset(isl::map(map2)); +} + +bool map::isa_map() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_map(*this).isa_map(); +} + +isl::map map::lex_ge_at(isl::multi_pw_aff mpa) const +{ + if (!ptr || mpa.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_lex_ge_at_multi_pw_aff(copy(), mpa.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::map map::lex_gt_at(isl::multi_pw_aff mpa) const +{ + if (!ptr || mpa.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_lex_gt_at_multi_pw_aff(copy(), mpa.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::map map::lex_le_at(isl::multi_pw_aff mpa) const +{ + if (!ptr || mpa.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_lex_le_at_multi_pw_aff(copy(), mpa.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::map map::lex_lt_at(isl::multi_pw_aff mpa) const +{ + if (!ptr || mpa.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_lex_lt_at_multi_pw_aff(copy(), mpa.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::map map::lexmax() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_lexmax(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::pw_multi_aff map::lexmax_pw_multi_aff() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_lexmax_pw_multi_aff(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::map map::lexmin() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_lexmin(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::pw_multi_aff map::lexmin_pw_multi_aff() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_lexmin_pw_multi_aff(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::map map::lower_bound(isl::multi_pw_aff lower) const +{ + if (!ptr || lower.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_lower_bound_multi_pw_aff(copy(), lower.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::map_list map::map_list() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_map(*this).map_list(); +} + +isl::multi_pw_aff map::max_multi_pw_aff() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_max_multi_pw_aff(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_pw_aff map::min_multi_pw_aff() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_min_multi_pw_aff(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +unsigned map::n_basic_map() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_n_basic_map(get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +isl::set map::params() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_params(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::basic_map map::polyhedral_hull() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_polyhedral_hull(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::map map::preimage_domain(isl::multi_aff ma) const +{ + if (!ptr || ma.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_preimage_domain_multi_aff(copy(), ma.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::map map::preimage_domain(isl::multi_pw_aff mpa) const +{ + if (!ptr || mpa.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_preimage_domain_multi_pw_aff(copy(), mpa.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::map map::preimage_domain(isl::pw_multi_aff pma) const +{ + if (!ptr || pma.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_preimage_domain_pw_multi_aff(copy(), pma.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map map::preimage_domain(const isl::union_pw_multi_aff &upma) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_map(*this).preimage_domain(upma); +} + +isl::map map::preimage_range(isl::multi_aff ma) const +{ + if (!ptr || ma.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_preimage_range_multi_aff(copy(), ma.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::map map::preimage_range(isl::pw_multi_aff pma) const +{ + if (!ptr || pma.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_preimage_range_pw_multi_aff(copy(), pma.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map map::preimage_range(const isl::union_pw_multi_aff &upma) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_map(*this).preimage_range(upma); +} + +isl::map map::product(isl::map map2) const +{ + if (!ptr || map2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_product(copy(), map2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map map::product(const isl::union_map &umap2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_map(*this).product(umap2); +} + +isl::map map::product(const isl::basic_map &map2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->product(isl::map(map2)); +} + +isl::map map::project_out_all_params() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_project_out_all_params(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::map map::project_out_param(isl::id id) const +{ + if (!ptr || id.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_project_out_param_id(copy(), id.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::map map::project_out_param(const std::string &id) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->project_out_param(isl::id(ctx(), id)); +} + +isl::map map::project_out_param(isl::id_list list) const +{ + if (!ptr || list.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_project_out_param_id_list(copy(), list.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::set map::range() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_range(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::map map::range_factor_domain() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_range_factor_domain(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::map map::range_factor_range() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_range_factor_range(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::fixed_box map::range_lattice_tile() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_get_range_lattice_tile(get()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::fixed_box map::get_range_lattice_tile() const +{ + return range_lattice_tile(); +} + +isl::union_map map::range_map() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_map(*this).range_map(); +} + +isl::map map::range_product(isl::map map2) const +{ + if (!ptr || map2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_range_product(copy(), map2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map map::range_product(const isl::union_map &umap2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_map(*this).range_product(umap2); +} + +isl::map map::range_product(const isl::basic_map &map2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->range_product(isl::map(map2)); +} + +isl::map map::range_reverse() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_range_reverse(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::fixed_box map::range_simple_fixed_box_hull() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_get_range_simple_fixed_box_hull(get()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::fixed_box map::get_range_simple_fixed_box_hull() const +{ + return range_simple_fixed_box_hull(); +} + +unsigned map::range_tuple_dim() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_range_tuple_dim(get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +isl::id map::range_tuple_id() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_get_range_tuple_id(get()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::id map::get_range_tuple_id() const +{ + return range_tuple_id(); +} + +isl::map map::reverse() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_reverse(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::basic_map map::sample() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_sample(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::map map::set_domain_tuple(isl::id id) const +{ + if (!ptr || id.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_set_domain_tuple_id(copy(), id.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::map map::set_domain_tuple(const std::string &id) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->set_domain_tuple(isl::id(ctx(), id)); +} + +isl::map map::set_range_tuple(isl::id id) const +{ + if (!ptr || id.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_set_range_tuple_id(copy(), id.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::map map::set_range_tuple(const std::string &id) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->set_range_tuple(isl::id(ctx(), id)); +} + +isl::space map::space() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_get_space(get()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::space map::get_space() const +{ + return space(); +} + +isl::map map::subtract(isl::map map2) const +{ + if (!ptr || map2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_subtract(copy(), map2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map map::subtract(const isl::union_map &umap2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_map(*this).subtract(umap2); +} + +isl::map map::subtract(const isl::basic_map &map2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->subtract(isl::map(map2)); +} + +isl::union_map map::subtract_domain(const isl::union_set &dom) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_map(*this).subtract_domain(dom); +} + +isl::union_map map::subtract_range(const isl::union_set &dom) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_map(*this).subtract_range(dom); +} + +isl::map_list map::to_list() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_to_list(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map map::to_union_map() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_to_union_map(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::map map::uncurry() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_uncurry(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::map map::unite(isl::map map2) const +{ + if (!ptr || map2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_union(copy(), map2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map map::unite(const isl::union_map &umap2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_map(*this).unite(umap2); +} + +isl::map map::unite(const isl::basic_map &map2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->unite(isl::map(map2)); +} + +isl::map map::universe(isl::space space) +{ + if (space.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = space.ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_universe(space.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::basic_map map::unshifted_simple_hull() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_unshifted_simple_hull(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::map map::upper_bound(isl::multi_pw_aff upper) const +{ + if (!ptr || upper.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_upper_bound_multi_pw_aff(copy(), upper.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::set map::wrap() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_wrap(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::map map::zip() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_zip(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +inline std::ostream &operator<<(std::ostream &os, const map &obj) +{ + if (!obj.get()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_map_get_ctx(obj.get()); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + char *str = isl_map_to_str(obj.get()); + if (!str) + exception::throw_last_error(saved_ctx); + os << str; + free(str); + return os; +} + +// implementations for isl::map_list +map_list manage(__isl_take isl_map_list *ptr) { + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return map_list(ptr); +} +map_list manage_copy(__isl_keep isl_map_list *ptr) { + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_map_list_get_ctx(ptr); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + ptr = isl_map_list_copy(ptr); + if (!ptr) + exception::throw_last_error(saved_ctx); + return map_list(ptr); +} + +map_list::map_list(__isl_take isl_map_list *ptr) + : ptr(ptr) {} + +map_list::map_list() + : ptr(nullptr) {} + +map_list::map_list(const map_list &obj) + : ptr(nullptr) +{ + if (!obj.ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_map_list_get_ctx(obj.ptr); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + ptr = obj.copy(); + if (!ptr) + exception::throw_last_error(saved_ctx); +} + +map_list::map_list(isl::ctx ctx, int n) +{ + auto saved_ctx = ctx; + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_list_alloc(ctx.release(), n); + if (!res) + exception::throw_last_error(saved_ctx); + ptr = res; +} + +map_list::map_list(isl::map el) +{ + if (el.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = el.ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_list_from_map(el.release()); + if (!res) + exception::throw_last_error(saved_ctx); + ptr = res; +} + +map_list::map_list(isl::ctx ctx, const std::string &str) +{ + auto saved_ctx = ctx; + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_list_read_from_str(ctx.release(), str.c_str()); + if (!res) + exception::throw_last_error(saved_ctx); + ptr = res; +} + +map_list &map_list::operator=(map_list obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +map_list::~map_list() { + if (ptr) + isl_map_list_free(ptr); +} + +__isl_give isl_map_list *map_list::copy() const & { + return isl_map_list_copy(ptr); +} + +__isl_keep isl_map_list *map_list::get() const { + return ptr; +} + +__isl_give isl_map_list *map_list::release() { + isl_map_list *tmp = ptr; + ptr = nullptr; + return tmp; +} + +bool map_list::is_null() const { + return ptr == nullptr; +} + +isl::ctx map_list::ctx() const { + return isl::ctx(isl_map_list_get_ctx(ptr)); +} + +isl::map_list map_list::add(isl::map el) const +{ + if (!ptr || el.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_list_add(copy(), el.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::map map_list::at(int index) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_list_get_at(get(), index); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::map map_list::get_at(int index) const +{ + return at(index); +} + +isl::map_list map_list::clear() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_list_clear(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::map_list map_list::concat(isl::map_list list2) const +{ + if (!ptr || list2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_list_concat(copy(), list2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::map_list map_list::drop(unsigned int first, unsigned int n) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_list_drop(copy(), first, n); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +void map_list::foreach(const std::function &fn) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + struct fn_data { + std::function func; + std::exception_ptr eptr; + } fn_data = { fn }; + auto fn_lambda = [](isl_map *arg_0, void *arg_1) -> isl_stat { + auto *data = static_cast(arg_1); + ISL_CPP_TRY { + (data->func)(manage(arg_0)); + return isl_stat_ok; + } ISL_CPP_CATCH_ALL { + data->eptr = std::current_exception(); + return isl_stat_error; + } + }; + auto res = isl_map_list_foreach(get(), fn_lambda, &fn_data); + if (fn_data.eptr) + std::rethrow_exception(fn_data.eptr); + if (res < 0) + exception::throw_last_error(saved_ctx); + return; +} + +void map_list::foreach_scc(const std::function &follows, const std::function &fn) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + struct follows_data { + std::function func; + std::exception_ptr eptr; + } follows_data = { follows }; + auto follows_lambda = [](isl_map *arg_0, isl_map *arg_1, void *arg_2) -> isl_bool { + auto *data = static_cast(arg_2); + ISL_CPP_TRY { + auto ret = (data->func)(manage_copy(arg_0), manage_copy(arg_1)); + return ret ? isl_bool_true : isl_bool_false; + } ISL_CPP_CATCH_ALL { + data->eptr = std::current_exception(); + return isl_bool_error; + } + }; + struct fn_data { + std::function func; + std::exception_ptr eptr; + } fn_data = { fn }; + auto fn_lambda = [](isl_map_list *arg_0, void *arg_1) -> isl_stat { + auto *data = static_cast(arg_1); + ISL_CPP_TRY { + (data->func)(manage(arg_0)); + return isl_stat_ok; + } ISL_CPP_CATCH_ALL { + data->eptr = std::current_exception(); + return isl_stat_error; + } + }; + auto res = isl_map_list_foreach_scc(get(), follows_lambda, &follows_data, fn_lambda, &fn_data); + if (follows_data.eptr) + std::rethrow_exception(follows_data.eptr); + if (fn_data.eptr) + std::rethrow_exception(fn_data.eptr); + if (res < 0) + exception::throw_last_error(saved_ctx); + return; +} + +isl::map_list map_list::insert(unsigned int pos, isl::map el) const +{ + if (!ptr || el.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_list_insert(copy(), pos, el.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::map_list map_list::set_at(int index, isl::map el) const +{ + if (!ptr || el.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_list_set_at(copy(), index, el.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +unsigned map_list::size() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_map_list_size(get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +inline std::ostream &operator<<(std::ostream &os, const map_list &obj) +{ + if (!obj.get()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_map_list_get_ctx(obj.get()); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + char *str = isl_map_list_to_str(obj.get()); + if (!str) + exception::throw_last_error(saved_ctx); + os << str; + free(str); + return os; +} + +// implementations for isl::multi_aff +multi_aff manage(__isl_take isl_multi_aff *ptr) { + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return multi_aff(ptr); +} +multi_aff manage_copy(__isl_keep isl_multi_aff *ptr) { + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_multi_aff_get_ctx(ptr); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + ptr = isl_multi_aff_copy(ptr); + if (!ptr) + exception::throw_last_error(saved_ctx); + return multi_aff(ptr); +} + +multi_aff::multi_aff(__isl_take isl_multi_aff *ptr) + : ptr(ptr) {} + +multi_aff::multi_aff() + : ptr(nullptr) {} + +multi_aff::multi_aff(const multi_aff &obj) + : ptr(nullptr) +{ + if (!obj.ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_multi_aff_get_ctx(obj.ptr); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + ptr = obj.copy(); + if (!ptr) + exception::throw_last_error(saved_ctx); +} + +multi_aff::multi_aff(isl::aff aff) +{ + if (aff.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = aff.ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_aff_from_aff(aff.release()); + if (!res) + exception::throw_last_error(saved_ctx); + ptr = res; +} + +multi_aff::multi_aff(isl::space space, isl::aff_list list) +{ + if (space.is_null() || list.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = space.ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_aff_from_aff_list(space.release(), list.release()); + if (!res) + exception::throw_last_error(saved_ctx); + ptr = res; +} + +multi_aff::multi_aff(isl::ctx ctx, const std::string &str) +{ + auto saved_ctx = ctx; + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_aff_read_from_str(ctx.release(), str.c_str()); + if (!res) + exception::throw_last_error(saved_ctx); + ptr = res; +} + +multi_aff &multi_aff::operator=(multi_aff obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +multi_aff::~multi_aff() { + if (ptr) + isl_multi_aff_free(ptr); +} + +__isl_give isl_multi_aff *multi_aff::copy() const & { + return isl_multi_aff_copy(ptr); +} + +__isl_keep isl_multi_aff *multi_aff::get() const { + return ptr; +} + +__isl_give isl_multi_aff *multi_aff::release() { + isl_multi_aff *tmp = ptr; + ptr = nullptr; + return tmp; +} + +bool multi_aff::is_null() const { + return ptr == nullptr; +} + +isl::ctx multi_aff::ctx() const { + return isl::ctx(isl_multi_aff_get_ctx(ptr)); +} + +isl::multi_aff multi_aff::add(isl::multi_aff multi2) const +{ + if (!ptr || multi2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_aff_add(copy(), multi2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_pw_aff multi_aff::add(const isl::multi_pw_aff &multi2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).add(multi2); +} + +isl::multi_union_pw_aff multi_aff::add(const isl::multi_union_pw_aff &multi2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).add(multi2); +} + +isl::pw_multi_aff multi_aff::add(const isl::pw_multi_aff &pma2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).add(pma2); +} + +isl::union_pw_multi_aff multi_aff::add(const isl::union_pw_multi_aff &upma2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).add(upma2); +} + +isl::multi_aff multi_aff::add(const isl::aff &multi2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->add(isl::multi_aff(multi2)); +} + +isl::multi_aff multi_aff::add_constant(isl::multi_val mv) const +{ + if (!ptr || mv.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_aff_add_constant_multi_val(copy(), mv.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_aff multi_aff::add_constant(isl::val v) const +{ + if (!ptr || v.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_aff_add_constant_val(copy(), v.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_aff multi_aff::add_constant(long v) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->add_constant(isl::val(ctx(), v)); +} + +isl::union_pw_multi_aff multi_aff::apply(const isl::union_pw_multi_aff &upma2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).apply(upma2); +} + +isl::map multi_aff::as_map() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_aff_as_map(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_aff multi_aff::as_multi_aff() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).as_multi_aff(); +} + +isl::multi_union_pw_aff multi_aff::as_multi_union_pw_aff() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).as_multi_union_pw_aff(); +} + +isl::pw_multi_aff multi_aff::as_pw_multi_aff() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).as_pw_multi_aff(); +} + +isl::set multi_aff::as_set() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_aff_as_set(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map multi_aff::as_union_map() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).as_union_map(); +} + +isl::aff multi_aff::at(int pos) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_aff_get_at(get(), pos); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::aff multi_aff::get_at(int pos) const +{ + return at(pos); +} + +isl::basic_set multi_aff::bind(isl::multi_id tuple) const +{ + if (!ptr || tuple.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_aff_bind(copy(), tuple.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_aff multi_aff::bind_domain(isl::multi_id tuple) const +{ + if (!ptr || tuple.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_aff_bind_domain(copy(), tuple.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_aff multi_aff::bind_domain_wrapped_domain(isl::multi_id tuple) const +{ + if (!ptr || tuple.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_aff_bind_domain_wrapped_domain(copy(), tuple.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::pw_multi_aff multi_aff::coalesce() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).coalesce(); +} + +isl::multi_val multi_aff::constant_multi_val() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_aff_get_constant_multi_val(get()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_val multi_aff::get_constant_multi_val() const +{ + return constant_multi_val(); +} + +isl::set multi_aff::domain() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).domain(); +} + +isl::multi_aff multi_aff::domain_map(isl::space space) +{ + if (space.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = space.ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_aff_domain_map(space.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_aff multi_aff::domain_reverse() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_aff_domain_reverse(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::pw_multi_aff multi_aff::drop_unused_params() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).drop_unused_params(); +} + +isl::pw_multi_aff multi_aff::extract_pw_multi_aff(const isl::space &space) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).extract_pw_multi_aff(space); +} + +isl::multi_aff multi_aff::flat_range_product(isl::multi_aff multi2) const +{ + if (!ptr || multi2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_aff_flat_range_product(copy(), multi2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_pw_aff multi_aff::flat_range_product(const isl::multi_pw_aff &multi2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).flat_range_product(multi2); +} + +isl::multi_union_pw_aff multi_aff::flat_range_product(const isl::multi_union_pw_aff &multi2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).flat_range_product(multi2); +} + +isl::pw_multi_aff multi_aff::flat_range_product(const isl::pw_multi_aff &pma2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).flat_range_product(pma2); +} + +isl::union_pw_multi_aff multi_aff::flat_range_product(const isl::union_pw_multi_aff &upma2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).flat_range_product(upma2); +} + +isl::multi_aff multi_aff::flat_range_product(const isl::aff &multi2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->flat_range_product(isl::multi_aff(multi2)); +} + +isl::multi_aff multi_aff::floor() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_aff_floor(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +void multi_aff::foreach_piece(const std::function &fn) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).foreach_piece(fn); +} + +isl::multi_aff multi_aff::gist(isl::set context) const +{ + if (!ptr || context.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_aff_gist(copy(), context.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_pw_multi_aff multi_aff::gist(const isl::union_set &context) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).gist(context); +} + +isl::multi_aff multi_aff::gist(const isl::basic_set &context) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->gist(isl::set(context)); +} + +isl::multi_aff multi_aff::gist(const isl::point &context) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->gist(isl::set(context)); +} + +isl::multi_aff multi_aff::gist_params(isl::set context) const +{ + if (!ptr || context.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_aff_gist_params(copy(), context.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +bool multi_aff::has_range_tuple_id() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_aff_has_range_tuple_id(get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +isl::multi_aff multi_aff::identity() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_aff_identity_multi_aff(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_aff multi_aff::identity_on_domain(isl::space space) +{ + if (space.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = space.ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_aff_identity_on_domain_space(space.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_aff multi_aff::insert_domain(isl::space domain) const +{ + if (!ptr || domain.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_aff_insert_domain(copy(), domain.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::pw_multi_aff multi_aff::intersect_domain(const isl::set &set) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).intersect_domain(set); +} + +isl::union_pw_multi_aff multi_aff::intersect_domain(const isl::space &space) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).intersect_domain(space); +} + +isl::union_pw_multi_aff multi_aff::intersect_domain(const isl::union_set &uset) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).intersect_domain(uset); +} + +isl::union_pw_multi_aff multi_aff::intersect_domain_wrapped_domain(const isl::union_set &uset) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).intersect_domain_wrapped_domain(uset); +} + +isl::union_pw_multi_aff multi_aff::intersect_domain_wrapped_range(const isl::union_set &uset) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).intersect_domain_wrapped_range(uset); +} + +isl::pw_multi_aff multi_aff::intersect_params(const isl::set &set) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).intersect_params(set); +} + +bool multi_aff::involves_locals() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_aff_involves_locals(get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +bool multi_aff::involves_nan() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_aff_involves_nan(get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +bool multi_aff::involves_param(const isl::id &id) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).involves_param(id); +} + +bool multi_aff::involves_param(const std::string &id) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->involves_param(isl::id(ctx(), id)); +} + +bool multi_aff::involves_param(const isl::id_list &list) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).involves_param(list); +} + +bool multi_aff::isa_multi_aff() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).isa_multi_aff(); +} + +bool multi_aff::isa_pw_multi_aff() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).isa_pw_multi_aff(); +} + +isl::aff_list multi_aff::list() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_aff_get_list(get()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::aff_list multi_aff::get_list() const +{ + return list(); +} + +isl::multi_pw_aff multi_aff::max(const isl::multi_pw_aff &multi2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).max(multi2); +} + +isl::multi_val multi_aff::max_multi_val() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).max_multi_val(); +} + +isl::multi_pw_aff multi_aff::min(const isl::multi_pw_aff &multi2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).min(multi2); +} + +isl::multi_val multi_aff::min_multi_val() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).min_multi_val(); +} + +isl::multi_aff multi_aff::multi_val_on_domain(isl::space space, isl::multi_val mv) +{ + if (space.is_null() || mv.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = space.ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_aff_multi_val_on_domain_space(space.release(), mv.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +unsigned multi_aff::n_piece() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).n_piece(); +} + +isl::multi_aff multi_aff::neg() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_aff_neg(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +bool multi_aff::plain_is_empty() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).plain_is_empty(); +} + +bool multi_aff::plain_is_equal(const isl::multi_aff &multi2) const +{ + if (!ptr || multi2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_aff_plain_is_equal(get(), multi2.get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +bool multi_aff::plain_is_equal(const isl::multi_pw_aff &multi2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).plain_is_equal(multi2); +} + +bool multi_aff::plain_is_equal(const isl::multi_union_pw_aff &multi2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).plain_is_equal(multi2); +} + +bool multi_aff::plain_is_equal(const isl::pw_multi_aff &pma2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).plain_is_equal(pma2); +} + +bool multi_aff::plain_is_equal(const isl::union_pw_multi_aff &upma2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).plain_is_equal(upma2); +} + +bool multi_aff::plain_is_equal(const isl::aff &multi2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->plain_is_equal(isl::multi_aff(multi2)); +} + +isl::pw_multi_aff multi_aff::preimage_domain_wrapped_domain(const isl::pw_multi_aff &pma2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).preimage_domain_wrapped_domain(pma2); +} + +isl::union_pw_multi_aff multi_aff::preimage_domain_wrapped_domain(const isl::union_pw_multi_aff &upma2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).preimage_domain_wrapped_domain(upma2); +} + +isl::multi_aff multi_aff::product(isl::multi_aff multi2) const +{ + if (!ptr || multi2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_aff_product(copy(), multi2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_pw_aff multi_aff::product(const isl::multi_pw_aff &multi2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).product(multi2); +} + +isl::pw_multi_aff multi_aff::product(const isl::pw_multi_aff &pma2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).product(pma2); +} + +isl::multi_aff multi_aff::product(const isl::aff &multi2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->product(isl::multi_aff(multi2)); +} + +isl::multi_aff multi_aff::pullback(isl::multi_aff ma2) const +{ + if (!ptr || ma2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_aff_pullback_multi_aff(copy(), ma2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_pw_aff multi_aff::pullback(const isl::multi_pw_aff &mpa2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).pullback(mpa2); +} + +isl::pw_multi_aff multi_aff::pullback(const isl::pw_multi_aff &pma2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).pullback(pma2); +} + +isl::union_pw_multi_aff multi_aff::pullback(const isl::union_pw_multi_aff &upma2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).pullback(upma2); +} + +isl::multi_aff multi_aff::pullback(const isl::aff &ma2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->pullback(isl::multi_aff(ma2)); +} + +isl::pw_multi_aff_list multi_aff::pw_multi_aff_list() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).pw_multi_aff_list(); +} + +isl::pw_multi_aff multi_aff::range_factor_domain() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).range_factor_domain(); +} + +isl::pw_multi_aff multi_aff::range_factor_range() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).range_factor_range(); +} + +isl::multi_aff multi_aff::range_map(isl::space space) +{ + if (space.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = space.ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_aff_range_map(space.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_aff multi_aff::range_product(isl::multi_aff multi2) const +{ + if (!ptr || multi2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_aff_range_product(copy(), multi2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_pw_aff multi_aff::range_product(const isl::multi_pw_aff &multi2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).range_product(multi2); +} + +isl::multi_union_pw_aff multi_aff::range_product(const isl::multi_union_pw_aff &multi2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).range_product(multi2); +} + +isl::pw_multi_aff multi_aff::range_product(const isl::pw_multi_aff &pma2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).range_product(pma2); +} + +isl::union_pw_multi_aff multi_aff::range_product(const isl::union_pw_multi_aff &upma2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).range_product(upma2); +} + +isl::multi_aff multi_aff::range_product(const isl::aff &multi2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->range_product(isl::multi_aff(multi2)); +} + +isl::id multi_aff::range_tuple_id() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_aff_get_range_tuple_id(get()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::id multi_aff::get_range_tuple_id() const +{ + return range_tuple_id(); +} + +isl::multi_aff multi_aff::reset_range_tuple_id() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_aff_reset_range_tuple_id(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_aff multi_aff::scale(isl::multi_val mv) const +{ + if (!ptr || mv.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_aff_scale_multi_val(copy(), mv.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_aff multi_aff::scale(isl::val v) const +{ + if (!ptr || v.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_aff_scale_val(copy(), v.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_aff multi_aff::scale(long v) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->scale(isl::val(ctx(), v)); +} + +isl::multi_aff multi_aff::scale_down(isl::multi_val mv) const +{ + if (!ptr || mv.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_aff_scale_down_multi_val(copy(), mv.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_aff multi_aff::scale_down(isl::val v) const +{ + if (!ptr || v.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_aff_scale_down_val(copy(), v.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_aff multi_aff::scale_down(long v) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->scale_down(isl::val(ctx(), v)); +} + +isl::multi_aff multi_aff::set_at(int pos, isl::aff el) const +{ + if (!ptr || el.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_aff_set_at(copy(), pos, el.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_pw_aff multi_aff::set_at(int pos, const isl::pw_aff &el) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).set_at(pos, el); +} + +isl::multi_union_pw_aff multi_aff::set_at(int pos, const isl::union_pw_aff &el) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).set_at(pos, el); +} + +isl::multi_aff multi_aff::set_range_tuple(isl::id id) const +{ + if (!ptr || id.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_aff_set_range_tuple_id(copy(), id.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_aff multi_aff::set_range_tuple(const std::string &id) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->set_range_tuple(isl::id(ctx(), id)); +} + +unsigned multi_aff::size() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_aff_size(get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +isl::space multi_aff::space() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_aff_get_space(get()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::space multi_aff::get_space() const +{ + return space(); +} + +isl::multi_aff multi_aff::sub(isl::multi_aff multi2) const +{ + if (!ptr || multi2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_aff_sub(copy(), multi2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_pw_aff multi_aff::sub(const isl::multi_pw_aff &multi2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).sub(multi2); +} + +isl::multi_union_pw_aff multi_aff::sub(const isl::multi_union_pw_aff &multi2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).sub(multi2); +} + +isl::pw_multi_aff multi_aff::sub(const isl::pw_multi_aff &pma2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).sub(pma2); +} + +isl::union_pw_multi_aff multi_aff::sub(const isl::union_pw_multi_aff &upma2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).sub(upma2); +} + +isl::multi_aff multi_aff::sub(const isl::aff &multi2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->sub(isl::multi_aff(multi2)); +} + +isl::pw_multi_aff multi_aff::subtract_domain(const isl::set &set) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).subtract_domain(set); +} + +isl::union_pw_multi_aff multi_aff::subtract_domain(const isl::space &space) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).subtract_domain(space); +} + +isl::union_pw_multi_aff multi_aff::subtract_domain(const isl::union_set &uset) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).subtract_domain(uset); +} + +isl::pw_multi_aff_list multi_aff::to_list() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).to_list(); +} + +isl::multi_pw_aff multi_aff::to_multi_pw_aff() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_aff_to_multi_pw_aff(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_union_pw_aff multi_aff::to_multi_union_pw_aff() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_aff_to_multi_union_pw_aff(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::pw_multi_aff multi_aff::to_pw_multi_aff() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_aff_to_pw_multi_aff(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_pw_multi_aff multi_aff::to_union_pw_multi_aff() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).to_union_pw_multi_aff(); +} + +isl::multi_aff multi_aff::unbind_params_insert_domain(isl::multi_id domain) const +{ + if (!ptr || domain.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_aff_unbind_params_insert_domain(copy(), domain.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_pw_aff multi_aff::union_add(const isl::multi_pw_aff &mpa2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).union_add(mpa2); +} + +isl::multi_union_pw_aff multi_aff::union_add(const isl::multi_union_pw_aff &mupa2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).union_add(mupa2); +} + +isl::pw_multi_aff multi_aff::union_add(const isl::pw_multi_aff &pma2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).union_add(pma2); +} + +isl::union_pw_multi_aff multi_aff::union_add(const isl::union_pw_multi_aff &upma2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).union_add(upma2); +} + +isl::multi_aff multi_aff::zero(isl::space space) +{ + if (space.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = space.ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_aff_zero(space.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +inline std::ostream &operator<<(std::ostream &os, const multi_aff &obj) +{ + if (!obj.get()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_multi_aff_get_ctx(obj.get()); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + char *str = isl_multi_aff_to_str(obj.get()); + if (!str) + exception::throw_last_error(saved_ctx); + os << str; + free(str); + return os; +} + +// implementations for isl::multi_id +multi_id manage(__isl_take isl_multi_id *ptr) { + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return multi_id(ptr); +} +multi_id manage_copy(__isl_keep isl_multi_id *ptr) { + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_multi_id_get_ctx(ptr); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + ptr = isl_multi_id_copy(ptr); + if (!ptr) + exception::throw_last_error(saved_ctx); + return multi_id(ptr); +} + +multi_id::multi_id(__isl_take isl_multi_id *ptr) + : ptr(ptr) {} + +multi_id::multi_id() + : ptr(nullptr) {} + +multi_id::multi_id(const multi_id &obj) + : ptr(nullptr) +{ + if (!obj.ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_multi_id_get_ctx(obj.ptr); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + ptr = obj.copy(); + if (!ptr) + exception::throw_last_error(saved_ctx); +} + +multi_id::multi_id(isl::space space, isl::id_list list) +{ + if (space.is_null() || list.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = space.ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_id_from_id_list(space.release(), list.release()); + if (!res) + exception::throw_last_error(saved_ctx); + ptr = res; +} + +multi_id::multi_id(isl::ctx ctx, const std::string &str) +{ + auto saved_ctx = ctx; + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_id_read_from_str(ctx.release(), str.c_str()); + if (!res) + exception::throw_last_error(saved_ctx); + ptr = res; +} + +multi_id &multi_id::operator=(multi_id obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +multi_id::~multi_id() { + if (ptr) + isl_multi_id_free(ptr); +} + +__isl_give isl_multi_id *multi_id::copy() const & { + return isl_multi_id_copy(ptr); +} + +__isl_keep isl_multi_id *multi_id::get() const { + return ptr; +} + +__isl_give isl_multi_id *multi_id::release() { + isl_multi_id *tmp = ptr; + ptr = nullptr; + return tmp; +} + +bool multi_id::is_null() const { + return ptr == nullptr; +} + +isl::ctx multi_id::ctx() const { + return isl::ctx(isl_multi_id_get_ctx(ptr)); +} + +isl::id multi_id::at(int pos) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_id_get_at(get(), pos); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::id multi_id::get_at(int pos) const +{ + return at(pos); +} + +isl::multi_id multi_id::flat_range_product(isl::multi_id multi2) const +{ + if (!ptr || multi2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_id_flat_range_product(copy(), multi2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::id_list multi_id::list() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_id_get_list(get()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::id_list multi_id::get_list() const +{ + return list(); +} + +bool multi_id::plain_is_equal(const isl::multi_id &multi2) const +{ + if (!ptr || multi2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_id_plain_is_equal(get(), multi2.get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +isl::multi_id multi_id::range_product(isl::multi_id multi2) const +{ + if (!ptr || multi2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_id_range_product(copy(), multi2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_id multi_id::set_at(int pos, isl::id el) const +{ + if (!ptr || el.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_id_set_at(copy(), pos, el.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_id multi_id::set_at(int pos, const std::string &el) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->set_at(pos, isl::id(ctx(), el)); +} + +unsigned multi_id::size() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_id_size(get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +isl::space multi_id::space() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_id_get_space(get()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::space multi_id::get_space() const +{ + return space(); +} + +inline std::ostream &operator<<(std::ostream &os, const multi_id &obj) +{ + if (!obj.get()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_multi_id_get_ctx(obj.get()); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + char *str = isl_multi_id_to_str(obj.get()); + if (!str) + exception::throw_last_error(saved_ctx); + os << str; + free(str); + return os; +} + +// implementations for isl::multi_pw_aff +multi_pw_aff manage(__isl_take isl_multi_pw_aff *ptr) { + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return multi_pw_aff(ptr); +} +multi_pw_aff manage_copy(__isl_keep isl_multi_pw_aff *ptr) { + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_multi_pw_aff_get_ctx(ptr); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + ptr = isl_multi_pw_aff_copy(ptr); + if (!ptr) + exception::throw_last_error(saved_ctx); + return multi_pw_aff(ptr); +} + +multi_pw_aff::multi_pw_aff(__isl_take isl_multi_pw_aff *ptr) + : ptr(ptr) {} + +multi_pw_aff::multi_pw_aff() + : ptr(nullptr) {} + +multi_pw_aff::multi_pw_aff(const multi_pw_aff &obj) + : ptr(nullptr) +{ + if (!obj.ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_multi_pw_aff_get_ctx(obj.ptr); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + ptr = obj.copy(); + if (!ptr) + exception::throw_last_error(saved_ctx); +} + +multi_pw_aff::multi_pw_aff(isl::aff aff) +{ + if (aff.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = aff.ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_pw_aff_from_aff(aff.release()); + if (!res) + exception::throw_last_error(saved_ctx); + ptr = res; +} + +multi_pw_aff::multi_pw_aff(isl::multi_aff ma) +{ + if (ma.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ma.ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_pw_aff_from_multi_aff(ma.release()); + if (!res) + exception::throw_last_error(saved_ctx); + ptr = res; +} + +multi_pw_aff::multi_pw_aff(isl::pw_aff pa) +{ + if (pa.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = pa.ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_pw_aff_from_pw_aff(pa.release()); + if (!res) + exception::throw_last_error(saved_ctx); + ptr = res; +} + +multi_pw_aff::multi_pw_aff(isl::space space, isl::pw_aff_list list) +{ + if (space.is_null() || list.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = space.ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_pw_aff_from_pw_aff_list(space.release(), list.release()); + if (!res) + exception::throw_last_error(saved_ctx); + ptr = res; +} + +multi_pw_aff::multi_pw_aff(isl::pw_multi_aff pma) +{ + if (pma.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = pma.ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_pw_aff_from_pw_multi_aff(pma.release()); + if (!res) + exception::throw_last_error(saved_ctx); + ptr = res; +} + +multi_pw_aff::multi_pw_aff(isl::ctx ctx, const std::string &str) +{ + auto saved_ctx = ctx; + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_pw_aff_read_from_str(ctx.release(), str.c_str()); + if (!res) + exception::throw_last_error(saved_ctx); + ptr = res; +} + +multi_pw_aff &multi_pw_aff::operator=(multi_pw_aff obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +multi_pw_aff::~multi_pw_aff() { + if (ptr) + isl_multi_pw_aff_free(ptr); +} + +__isl_give isl_multi_pw_aff *multi_pw_aff::copy() const & { + return isl_multi_pw_aff_copy(ptr); +} + +__isl_keep isl_multi_pw_aff *multi_pw_aff::get() const { + return ptr; +} + +__isl_give isl_multi_pw_aff *multi_pw_aff::release() { + isl_multi_pw_aff *tmp = ptr; + ptr = nullptr; + return tmp; +} + +bool multi_pw_aff::is_null() const { + return ptr == nullptr; +} + +isl::ctx multi_pw_aff::ctx() const { + return isl::ctx(isl_multi_pw_aff_get_ctx(ptr)); +} + +isl::multi_pw_aff multi_pw_aff::add(isl::multi_pw_aff multi2) const +{ + if (!ptr || multi2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_pw_aff_add(copy(), multi2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_union_pw_aff multi_pw_aff::add(const isl::multi_union_pw_aff &multi2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::multi_union_pw_aff(*this).add(multi2); +} + +isl::multi_pw_aff multi_pw_aff::add(const isl::aff &multi2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->add(isl::multi_pw_aff(multi2)); +} + +isl::multi_pw_aff multi_pw_aff::add(const isl::multi_aff &multi2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->add(isl::multi_pw_aff(multi2)); +} + +isl::multi_pw_aff multi_pw_aff::add(const isl::pw_aff &multi2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->add(isl::multi_pw_aff(multi2)); +} + +isl::multi_pw_aff multi_pw_aff::add(const isl::pw_multi_aff &multi2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->add(isl::multi_pw_aff(multi2)); +} + +isl::multi_pw_aff multi_pw_aff::add_constant(isl::multi_val mv) const +{ + if (!ptr || mv.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_pw_aff_add_constant_multi_val(copy(), mv.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_pw_aff multi_pw_aff::add_constant(isl::val v) const +{ + if (!ptr || v.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_pw_aff_add_constant_val(copy(), v.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_pw_aff multi_pw_aff::add_constant(long v) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->add_constant(isl::val(ctx(), v)); +} + +isl::map multi_pw_aff::as_map() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_pw_aff_as_map(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_aff multi_pw_aff::as_multi_aff() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_pw_aff_as_multi_aff(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::set multi_pw_aff::as_set() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_pw_aff_as_set(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::pw_aff multi_pw_aff::at(int pos) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_pw_aff_get_at(get(), pos); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::pw_aff multi_pw_aff::get_at(int pos) const +{ + return at(pos); +} + +isl::set multi_pw_aff::bind(isl::multi_id tuple) const +{ + if (!ptr || tuple.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_pw_aff_bind(copy(), tuple.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_pw_aff multi_pw_aff::bind_domain(isl::multi_id tuple) const +{ + if (!ptr || tuple.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_pw_aff_bind_domain(copy(), tuple.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_pw_aff multi_pw_aff::bind_domain_wrapped_domain(isl::multi_id tuple) const +{ + if (!ptr || tuple.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_pw_aff_bind_domain_wrapped_domain(copy(), tuple.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_pw_aff multi_pw_aff::coalesce() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_pw_aff_coalesce(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::set multi_pw_aff::domain() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_pw_aff_domain(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_pw_aff multi_pw_aff::domain_reverse() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_pw_aff_domain_reverse(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_pw_aff multi_pw_aff::flat_range_product(isl::multi_pw_aff multi2) const +{ + if (!ptr || multi2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_pw_aff_flat_range_product(copy(), multi2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_union_pw_aff multi_pw_aff::flat_range_product(const isl::multi_union_pw_aff &multi2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::multi_union_pw_aff(*this).flat_range_product(multi2); +} + +isl::multi_pw_aff multi_pw_aff::flat_range_product(const isl::aff &multi2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->flat_range_product(isl::multi_pw_aff(multi2)); +} + +isl::multi_pw_aff multi_pw_aff::flat_range_product(const isl::multi_aff &multi2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->flat_range_product(isl::multi_pw_aff(multi2)); +} + +isl::multi_pw_aff multi_pw_aff::flat_range_product(const isl::pw_aff &multi2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->flat_range_product(isl::multi_pw_aff(multi2)); +} + +isl::multi_pw_aff multi_pw_aff::flat_range_product(const isl::pw_multi_aff &multi2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->flat_range_product(isl::multi_pw_aff(multi2)); +} + +isl::multi_pw_aff multi_pw_aff::gist(isl::set set) const +{ + if (!ptr || set.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_pw_aff_gist(copy(), set.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_union_pw_aff multi_pw_aff::gist(const isl::union_set &context) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::multi_union_pw_aff(*this).gist(context); +} + +isl::multi_pw_aff multi_pw_aff::gist(const isl::basic_set &set) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->gist(isl::set(set)); +} + +isl::multi_pw_aff multi_pw_aff::gist(const isl::point &set) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->gist(isl::set(set)); +} + +isl::multi_pw_aff multi_pw_aff::gist_params(isl::set set) const +{ + if (!ptr || set.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_pw_aff_gist_params(copy(), set.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +bool multi_pw_aff::has_range_tuple_id() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_pw_aff_has_range_tuple_id(get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +isl::multi_pw_aff multi_pw_aff::identity() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_pw_aff_identity_multi_pw_aff(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_pw_aff multi_pw_aff::identity_on_domain(isl::space space) +{ + if (space.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = space.ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_pw_aff_identity_on_domain_space(space.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_pw_aff multi_pw_aff::insert_domain(isl::space domain) const +{ + if (!ptr || domain.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_pw_aff_insert_domain(copy(), domain.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_pw_aff multi_pw_aff::intersect_domain(isl::set domain) const +{ + if (!ptr || domain.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_pw_aff_intersect_domain(copy(), domain.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_union_pw_aff multi_pw_aff::intersect_domain(const isl::union_set &uset) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::multi_union_pw_aff(*this).intersect_domain(uset); +} + +isl::multi_pw_aff multi_pw_aff::intersect_domain(const isl::basic_set &domain) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->intersect_domain(isl::set(domain)); +} + +isl::multi_pw_aff multi_pw_aff::intersect_domain(const isl::point &domain) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->intersect_domain(isl::set(domain)); +} + +isl::multi_pw_aff multi_pw_aff::intersect_params(isl::set set) const +{ + if (!ptr || set.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_pw_aff_intersect_params(copy(), set.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +bool multi_pw_aff::involves_nan() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_pw_aff_involves_nan(get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +bool multi_pw_aff::involves_param(const isl::id &id) const +{ + if (!ptr || id.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_pw_aff_involves_param_id(get(), id.get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +bool multi_pw_aff::involves_param(const std::string &id) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->involves_param(isl::id(ctx(), id)); +} + +bool multi_pw_aff::involves_param(const isl::id_list &list) const +{ + if (!ptr || list.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_pw_aff_involves_param_id_list(get(), list.get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +bool multi_pw_aff::isa_multi_aff() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_pw_aff_isa_multi_aff(get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +isl::pw_aff_list multi_pw_aff::list() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_pw_aff_get_list(get()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::pw_aff_list multi_pw_aff::get_list() const +{ + return list(); +} + +isl::multi_pw_aff multi_pw_aff::max(isl::multi_pw_aff multi2) const +{ + if (!ptr || multi2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_pw_aff_max(copy(), multi2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_val multi_pw_aff::max_multi_val() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_pw_aff_max_multi_val(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_pw_aff multi_pw_aff::min(isl::multi_pw_aff multi2) const +{ + if (!ptr || multi2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_pw_aff_min(copy(), multi2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_val multi_pw_aff::min_multi_val() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_pw_aff_min_multi_val(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_pw_aff multi_pw_aff::neg() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_pw_aff_neg(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +bool multi_pw_aff::plain_is_equal(const isl::multi_pw_aff &multi2) const +{ + if (!ptr || multi2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_pw_aff_plain_is_equal(get(), multi2.get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +bool multi_pw_aff::plain_is_equal(const isl::multi_union_pw_aff &multi2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::multi_union_pw_aff(*this).plain_is_equal(multi2); +} + +bool multi_pw_aff::plain_is_equal(const isl::aff &multi2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->plain_is_equal(isl::multi_pw_aff(multi2)); +} + +bool multi_pw_aff::plain_is_equal(const isl::multi_aff &multi2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->plain_is_equal(isl::multi_pw_aff(multi2)); +} + +bool multi_pw_aff::plain_is_equal(const isl::pw_aff &multi2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->plain_is_equal(isl::multi_pw_aff(multi2)); +} + +bool multi_pw_aff::plain_is_equal(const isl::pw_multi_aff &multi2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->plain_is_equal(isl::multi_pw_aff(multi2)); +} + +isl::multi_pw_aff multi_pw_aff::product(isl::multi_pw_aff multi2) const +{ + if (!ptr || multi2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_pw_aff_product(copy(), multi2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_pw_aff multi_pw_aff::pullback(isl::multi_aff ma) const +{ + if (!ptr || ma.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_pw_aff_pullback_multi_aff(copy(), ma.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_pw_aff multi_pw_aff::pullback(isl::multi_pw_aff mpa2) const +{ + if (!ptr || mpa2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_pw_aff_pullback_multi_pw_aff(copy(), mpa2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_pw_aff multi_pw_aff::pullback(isl::pw_multi_aff pma) const +{ + if (!ptr || pma.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_pw_aff_pullback_pw_multi_aff(copy(), pma.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_union_pw_aff multi_pw_aff::pullback(const isl::union_pw_multi_aff &upma) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::multi_union_pw_aff(*this).pullback(upma); +} + +isl::multi_pw_aff multi_pw_aff::range_product(isl::multi_pw_aff multi2) const +{ + if (!ptr || multi2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_pw_aff_range_product(copy(), multi2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_union_pw_aff multi_pw_aff::range_product(const isl::multi_union_pw_aff &multi2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::multi_union_pw_aff(*this).range_product(multi2); +} + +isl::multi_pw_aff multi_pw_aff::range_product(const isl::aff &multi2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->range_product(isl::multi_pw_aff(multi2)); +} + +isl::multi_pw_aff multi_pw_aff::range_product(const isl::multi_aff &multi2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->range_product(isl::multi_pw_aff(multi2)); +} + +isl::multi_pw_aff multi_pw_aff::range_product(const isl::pw_aff &multi2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->range_product(isl::multi_pw_aff(multi2)); +} + +isl::multi_pw_aff multi_pw_aff::range_product(const isl::pw_multi_aff &multi2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->range_product(isl::multi_pw_aff(multi2)); +} + +isl::id multi_pw_aff::range_tuple_id() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_pw_aff_get_range_tuple_id(get()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::id multi_pw_aff::get_range_tuple_id() const +{ + return range_tuple_id(); +} + +isl::multi_pw_aff multi_pw_aff::reset_range_tuple_id() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_pw_aff_reset_range_tuple_id(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_pw_aff multi_pw_aff::scale(isl::multi_val mv) const +{ + if (!ptr || mv.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_pw_aff_scale_multi_val(copy(), mv.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_pw_aff multi_pw_aff::scale(isl::val v) const +{ + if (!ptr || v.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_pw_aff_scale_val(copy(), v.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_pw_aff multi_pw_aff::scale(long v) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->scale(isl::val(ctx(), v)); +} + +isl::multi_pw_aff multi_pw_aff::scale_down(isl::multi_val mv) const +{ + if (!ptr || mv.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_pw_aff_scale_down_multi_val(copy(), mv.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_pw_aff multi_pw_aff::scale_down(isl::val v) const +{ + if (!ptr || v.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_pw_aff_scale_down_val(copy(), v.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_pw_aff multi_pw_aff::scale_down(long v) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->scale_down(isl::val(ctx(), v)); +} + +isl::multi_pw_aff multi_pw_aff::set_at(int pos, isl::pw_aff el) const +{ + if (!ptr || el.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_pw_aff_set_at(copy(), pos, el.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_union_pw_aff multi_pw_aff::set_at(int pos, const isl::union_pw_aff &el) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::multi_union_pw_aff(*this).set_at(pos, el); +} + +isl::multi_pw_aff multi_pw_aff::set_range_tuple(isl::id id) const +{ + if (!ptr || id.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_pw_aff_set_range_tuple_id(copy(), id.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_pw_aff multi_pw_aff::set_range_tuple(const std::string &id) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->set_range_tuple(isl::id(ctx(), id)); +} + +unsigned multi_pw_aff::size() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_pw_aff_size(get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +isl::space multi_pw_aff::space() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_pw_aff_get_space(get()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::space multi_pw_aff::get_space() const +{ + return space(); +} + +isl::multi_pw_aff multi_pw_aff::sub(isl::multi_pw_aff multi2) const +{ + if (!ptr || multi2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_pw_aff_sub(copy(), multi2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_union_pw_aff multi_pw_aff::sub(const isl::multi_union_pw_aff &multi2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::multi_union_pw_aff(*this).sub(multi2); +} + +isl::multi_pw_aff multi_pw_aff::sub(const isl::aff &multi2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->sub(isl::multi_pw_aff(multi2)); +} + +isl::multi_pw_aff multi_pw_aff::sub(const isl::multi_aff &multi2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->sub(isl::multi_pw_aff(multi2)); +} + +isl::multi_pw_aff multi_pw_aff::sub(const isl::pw_aff &multi2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->sub(isl::multi_pw_aff(multi2)); +} + +isl::multi_pw_aff multi_pw_aff::sub(const isl::pw_multi_aff &multi2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->sub(isl::multi_pw_aff(multi2)); +} + +isl::multi_pw_aff multi_pw_aff::unbind_params_insert_domain(isl::multi_id domain) const +{ + if (!ptr || domain.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_pw_aff_unbind_params_insert_domain(copy(), domain.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_pw_aff multi_pw_aff::union_add(isl::multi_pw_aff mpa2) const +{ + if (!ptr || mpa2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_pw_aff_union_add(copy(), mpa2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_union_pw_aff multi_pw_aff::union_add(const isl::multi_union_pw_aff &mupa2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::multi_union_pw_aff(*this).union_add(mupa2); +} + +isl::multi_pw_aff multi_pw_aff::union_add(const isl::aff &mpa2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->union_add(isl::multi_pw_aff(mpa2)); +} + +isl::multi_pw_aff multi_pw_aff::union_add(const isl::multi_aff &mpa2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->union_add(isl::multi_pw_aff(mpa2)); +} + +isl::multi_pw_aff multi_pw_aff::union_add(const isl::pw_aff &mpa2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->union_add(isl::multi_pw_aff(mpa2)); +} + +isl::multi_pw_aff multi_pw_aff::union_add(const isl::pw_multi_aff &mpa2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->union_add(isl::multi_pw_aff(mpa2)); +} + +isl::multi_pw_aff multi_pw_aff::zero(isl::space space) +{ + if (space.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = space.ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_pw_aff_zero(space.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +inline std::ostream &operator<<(std::ostream &os, const multi_pw_aff &obj) +{ + if (!obj.get()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_multi_pw_aff_get_ctx(obj.get()); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + char *str = isl_multi_pw_aff_to_str(obj.get()); + if (!str) + exception::throw_last_error(saved_ctx); + os << str; + free(str); + return os; +} + +// implementations for isl::multi_union_pw_aff +multi_union_pw_aff manage(__isl_take isl_multi_union_pw_aff *ptr) { + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return multi_union_pw_aff(ptr); +} +multi_union_pw_aff manage_copy(__isl_keep isl_multi_union_pw_aff *ptr) { + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_multi_union_pw_aff_get_ctx(ptr); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + ptr = isl_multi_union_pw_aff_copy(ptr); + if (!ptr) + exception::throw_last_error(saved_ctx); + return multi_union_pw_aff(ptr); +} + +multi_union_pw_aff::multi_union_pw_aff(__isl_take isl_multi_union_pw_aff *ptr) + : ptr(ptr) {} + +multi_union_pw_aff::multi_union_pw_aff() + : ptr(nullptr) {} + +multi_union_pw_aff::multi_union_pw_aff(const multi_union_pw_aff &obj) + : ptr(nullptr) +{ + if (!obj.ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_multi_union_pw_aff_get_ctx(obj.ptr); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + ptr = obj.copy(); + if (!ptr) + exception::throw_last_error(saved_ctx); +} + +multi_union_pw_aff::multi_union_pw_aff(isl::multi_pw_aff mpa) +{ + if (mpa.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = mpa.ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_union_pw_aff_from_multi_pw_aff(mpa.release()); + if (!res) + exception::throw_last_error(saved_ctx); + ptr = res; +} + +multi_union_pw_aff::multi_union_pw_aff(isl::union_pw_aff upa) +{ + if (upa.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = upa.ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_union_pw_aff_from_union_pw_aff(upa.release()); + if (!res) + exception::throw_last_error(saved_ctx); + ptr = res; +} + +multi_union_pw_aff::multi_union_pw_aff(isl::space space, isl::union_pw_aff_list list) +{ + if (space.is_null() || list.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = space.ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_union_pw_aff_from_union_pw_aff_list(space.release(), list.release()); + if (!res) + exception::throw_last_error(saved_ctx); + ptr = res; +} + +multi_union_pw_aff::multi_union_pw_aff(isl::ctx ctx, const std::string &str) +{ + auto saved_ctx = ctx; + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_union_pw_aff_read_from_str(ctx.release(), str.c_str()); + if (!res) + exception::throw_last_error(saved_ctx); + ptr = res; +} + +multi_union_pw_aff &multi_union_pw_aff::operator=(multi_union_pw_aff obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +multi_union_pw_aff::~multi_union_pw_aff() { + if (ptr) + isl_multi_union_pw_aff_free(ptr); +} + +__isl_give isl_multi_union_pw_aff *multi_union_pw_aff::copy() const & { + return isl_multi_union_pw_aff_copy(ptr); +} + +__isl_keep isl_multi_union_pw_aff *multi_union_pw_aff::get() const { + return ptr; +} + +__isl_give isl_multi_union_pw_aff *multi_union_pw_aff::release() { + isl_multi_union_pw_aff *tmp = ptr; + ptr = nullptr; + return tmp; +} + +bool multi_union_pw_aff::is_null() const { + return ptr == nullptr; +} + +isl::ctx multi_union_pw_aff::ctx() const { + return isl::ctx(isl_multi_union_pw_aff_get_ctx(ptr)); +} + +isl::multi_union_pw_aff multi_union_pw_aff::add(isl::multi_union_pw_aff multi2) const +{ + if (!ptr || multi2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_union_pw_aff_add(copy(), multi2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_pw_aff multi_union_pw_aff::at(int pos) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_union_pw_aff_get_at(get(), pos); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_pw_aff multi_union_pw_aff::get_at(int pos) const +{ + return at(pos); +} + +isl::union_set multi_union_pw_aff::bind(isl::multi_id tuple) const +{ + if (!ptr || tuple.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_union_pw_aff_bind(copy(), tuple.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_union_pw_aff multi_union_pw_aff::coalesce() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_union_pw_aff_coalesce(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_set multi_union_pw_aff::domain() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_union_pw_aff_domain(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_union_pw_aff multi_union_pw_aff::flat_range_product(isl::multi_union_pw_aff multi2) const +{ + if (!ptr || multi2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_union_pw_aff_flat_range_product(copy(), multi2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_union_pw_aff multi_union_pw_aff::gist(isl::union_set context) const +{ + if (!ptr || context.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_union_pw_aff_gist(copy(), context.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_union_pw_aff multi_union_pw_aff::gist_params(isl::set context) const +{ + if (!ptr || context.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_union_pw_aff_gist_params(copy(), context.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +bool multi_union_pw_aff::has_range_tuple_id() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_union_pw_aff_has_range_tuple_id(get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +isl::multi_union_pw_aff multi_union_pw_aff::intersect_domain(isl::union_set uset) const +{ + if (!ptr || uset.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_union_pw_aff_intersect_domain(copy(), uset.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_union_pw_aff multi_union_pw_aff::intersect_params(isl::set params) const +{ + if (!ptr || params.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_union_pw_aff_intersect_params(copy(), params.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +bool multi_union_pw_aff::involves_nan() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_union_pw_aff_involves_nan(get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +isl::union_pw_aff_list multi_union_pw_aff::list() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_union_pw_aff_get_list(get()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_pw_aff_list multi_union_pw_aff::get_list() const +{ + return list(); +} + +isl::multi_union_pw_aff multi_union_pw_aff::neg() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_union_pw_aff_neg(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +bool multi_union_pw_aff::plain_is_equal(const isl::multi_union_pw_aff &multi2) const +{ + if (!ptr || multi2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_union_pw_aff_plain_is_equal(get(), multi2.get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +isl::multi_union_pw_aff multi_union_pw_aff::pullback(isl::union_pw_multi_aff upma) const +{ + if (!ptr || upma.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_union_pw_aff_pullback_union_pw_multi_aff(copy(), upma.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_union_pw_aff multi_union_pw_aff::range_product(isl::multi_union_pw_aff multi2) const +{ + if (!ptr || multi2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_union_pw_aff_range_product(copy(), multi2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::id multi_union_pw_aff::range_tuple_id() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_union_pw_aff_get_range_tuple_id(get()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::id multi_union_pw_aff::get_range_tuple_id() const +{ + return range_tuple_id(); +} + +isl::multi_union_pw_aff multi_union_pw_aff::reset_range_tuple_id() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_union_pw_aff_reset_range_tuple_id(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_union_pw_aff multi_union_pw_aff::scale(isl::multi_val mv) const +{ + if (!ptr || mv.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_union_pw_aff_scale_multi_val(copy(), mv.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_union_pw_aff multi_union_pw_aff::scale(isl::val v) const +{ + if (!ptr || v.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_union_pw_aff_scale_val(copy(), v.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_union_pw_aff multi_union_pw_aff::scale(long v) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->scale(isl::val(ctx(), v)); +} + +isl::multi_union_pw_aff multi_union_pw_aff::scale_down(isl::multi_val mv) const +{ + if (!ptr || mv.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_union_pw_aff_scale_down_multi_val(copy(), mv.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_union_pw_aff multi_union_pw_aff::scale_down(isl::val v) const +{ + if (!ptr || v.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_union_pw_aff_scale_down_val(copy(), v.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_union_pw_aff multi_union_pw_aff::scale_down(long v) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->scale_down(isl::val(ctx(), v)); +} + +isl::multi_union_pw_aff multi_union_pw_aff::set_at(int pos, isl::union_pw_aff el) const +{ + if (!ptr || el.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_union_pw_aff_set_at(copy(), pos, el.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_union_pw_aff multi_union_pw_aff::set_range_tuple(isl::id id) const +{ + if (!ptr || id.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_union_pw_aff_set_range_tuple_id(copy(), id.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_union_pw_aff multi_union_pw_aff::set_range_tuple(const std::string &id) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->set_range_tuple(isl::id(ctx(), id)); +} + +unsigned multi_union_pw_aff::size() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_union_pw_aff_size(get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +isl::space multi_union_pw_aff::space() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_union_pw_aff_get_space(get()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::space multi_union_pw_aff::get_space() const +{ + return space(); +} + +isl::multi_union_pw_aff multi_union_pw_aff::sub(isl::multi_union_pw_aff multi2) const +{ + if (!ptr || multi2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_union_pw_aff_sub(copy(), multi2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_union_pw_aff multi_union_pw_aff::union_add(isl::multi_union_pw_aff mupa2) const +{ + if (!ptr || mupa2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_union_pw_aff_union_add(copy(), mupa2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_union_pw_aff multi_union_pw_aff::zero(isl::space space) +{ + if (space.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = space.ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_union_pw_aff_zero(space.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +inline std::ostream &operator<<(std::ostream &os, const multi_union_pw_aff &obj) +{ + if (!obj.get()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_multi_union_pw_aff_get_ctx(obj.get()); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + char *str = isl_multi_union_pw_aff_to_str(obj.get()); + if (!str) + exception::throw_last_error(saved_ctx); + os << str; + free(str); + return os; +} + +// implementations for isl::multi_val +multi_val manage(__isl_take isl_multi_val *ptr) { + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return multi_val(ptr); +} +multi_val manage_copy(__isl_keep isl_multi_val *ptr) { + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_multi_val_get_ctx(ptr); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + ptr = isl_multi_val_copy(ptr); + if (!ptr) + exception::throw_last_error(saved_ctx); + return multi_val(ptr); +} + +multi_val::multi_val(__isl_take isl_multi_val *ptr) + : ptr(ptr) {} + +multi_val::multi_val() + : ptr(nullptr) {} + +multi_val::multi_val(const multi_val &obj) + : ptr(nullptr) +{ + if (!obj.ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_multi_val_get_ctx(obj.ptr); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + ptr = obj.copy(); + if (!ptr) + exception::throw_last_error(saved_ctx); +} + +multi_val::multi_val(isl::space space, isl::val_list list) +{ + if (space.is_null() || list.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = space.ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_val_from_val_list(space.release(), list.release()); + if (!res) + exception::throw_last_error(saved_ctx); + ptr = res; +} + +multi_val::multi_val(isl::ctx ctx, const std::string &str) +{ + auto saved_ctx = ctx; + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_val_read_from_str(ctx.release(), str.c_str()); + if (!res) + exception::throw_last_error(saved_ctx); + ptr = res; +} + +multi_val &multi_val::operator=(multi_val obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +multi_val::~multi_val() { + if (ptr) + isl_multi_val_free(ptr); +} + +__isl_give isl_multi_val *multi_val::copy() const & { + return isl_multi_val_copy(ptr); +} + +__isl_keep isl_multi_val *multi_val::get() const { + return ptr; +} + +__isl_give isl_multi_val *multi_val::release() { + isl_multi_val *tmp = ptr; + ptr = nullptr; + return tmp; +} + +bool multi_val::is_null() const { + return ptr == nullptr; +} + +isl::ctx multi_val::ctx() const { + return isl::ctx(isl_multi_val_get_ctx(ptr)); +} + +isl::multi_val multi_val::add(isl::multi_val multi2) const +{ + if (!ptr || multi2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_val_add(copy(), multi2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_val multi_val::add(isl::val v) const +{ + if (!ptr || v.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_val_add_val(copy(), v.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_val multi_val::add(long v) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->add(isl::val(ctx(), v)); +} + +isl::val multi_val::at(int pos) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_val_get_at(get(), pos); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::val multi_val::get_at(int pos) const +{ + return at(pos); +} + +isl::multi_val multi_val::flat_range_product(isl::multi_val multi2) const +{ + if (!ptr || multi2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_val_flat_range_product(copy(), multi2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +bool multi_val::has_range_tuple_id() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_val_has_range_tuple_id(get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +bool multi_val::involves_nan() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_val_involves_nan(get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +isl::val_list multi_val::list() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_val_get_list(get()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::val_list multi_val::get_list() const +{ + return list(); +} + +isl::multi_val multi_val::max(isl::multi_val multi2) const +{ + if (!ptr || multi2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_val_max(copy(), multi2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_val multi_val::min(isl::multi_val multi2) const +{ + if (!ptr || multi2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_val_min(copy(), multi2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_val multi_val::neg() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_val_neg(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +bool multi_val::plain_is_equal(const isl::multi_val &multi2) const +{ + if (!ptr || multi2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_val_plain_is_equal(get(), multi2.get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +isl::multi_val multi_val::product(isl::multi_val multi2) const +{ + if (!ptr || multi2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_val_product(copy(), multi2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_val multi_val::range_product(isl::multi_val multi2) const +{ + if (!ptr || multi2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_val_range_product(copy(), multi2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::id multi_val::range_tuple_id() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_val_get_range_tuple_id(get()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::id multi_val::get_range_tuple_id() const +{ + return range_tuple_id(); +} + +isl::multi_val multi_val::reset_range_tuple_id() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_val_reset_range_tuple_id(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_val multi_val::scale(isl::multi_val mv) const +{ + if (!ptr || mv.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_val_scale_multi_val(copy(), mv.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_val multi_val::scale(isl::val v) const +{ + if (!ptr || v.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_val_scale_val(copy(), v.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_val multi_val::scale(long v) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->scale(isl::val(ctx(), v)); +} + +isl::multi_val multi_val::scale_down(isl::multi_val mv) const +{ + if (!ptr || mv.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_val_scale_down_multi_val(copy(), mv.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_val multi_val::scale_down(isl::val v) const +{ + if (!ptr || v.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_val_scale_down_val(copy(), v.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_val multi_val::scale_down(long v) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->scale_down(isl::val(ctx(), v)); +} + +isl::multi_val multi_val::set_at(int pos, isl::val el) const +{ + if (!ptr || el.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_val_set_at(copy(), pos, el.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_val multi_val::set_at(int pos, long el) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->set_at(pos, isl::val(ctx(), el)); +} + +isl::multi_val multi_val::set_range_tuple(isl::id id) const +{ + if (!ptr || id.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_val_set_range_tuple_id(copy(), id.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_val multi_val::set_range_tuple(const std::string &id) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->set_range_tuple(isl::id(ctx(), id)); +} + +unsigned multi_val::size() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_val_size(get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +isl::space multi_val::space() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_val_get_space(get()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::space multi_val::get_space() const +{ + return space(); +} + +isl::multi_val multi_val::sub(isl::multi_val multi2) const +{ + if (!ptr || multi2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_val_sub(copy(), multi2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_val multi_val::zero(isl::space space) +{ + if (space.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = space.ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_multi_val_zero(space.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +inline std::ostream &operator<<(std::ostream &os, const multi_val &obj) +{ + if (!obj.get()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_multi_val_get_ctx(obj.get()); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + char *str = isl_multi_val_to_str(obj.get()); + if (!str) + exception::throw_last_error(saved_ctx); + os << str; + free(str); + return os; +} + +// implementations for isl::point +point manage(__isl_take isl_point *ptr) { + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return point(ptr); +} +point manage_copy(__isl_keep isl_point *ptr) { + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_point_get_ctx(ptr); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + ptr = isl_point_copy(ptr); + if (!ptr) + exception::throw_last_error(saved_ctx); + return point(ptr); +} + +point::point(__isl_take isl_point *ptr) + : ptr(ptr) {} + +point::point() + : ptr(nullptr) {} + +point::point(const point &obj) + : ptr(nullptr) +{ + if (!obj.ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_point_get_ctx(obj.ptr); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + ptr = obj.copy(); + if (!ptr) + exception::throw_last_error(saved_ctx); +} + +point &point::operator=(point obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +point::~point() { + if (ptr) + isl_point_free(ptr); +} + +__isl_give isl_point *point::copy() const & { + return isl_point_copy(ptr); +} + +__isl_keep isl_point *point::get() const { + return ptr; +} + +__isl_give isl_point *point::release() { + isl_point *tmp = ptr; + ptr = nullptr; + return tmp; +} + +bool point::is_null() const { + return ptr == nullptr; +} + +isl::ctx point::ctx() const { + return isl::ctx(isl_point_get_ctx(ptr)); +} + +isl::basic_set point::affine_hull() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::basic_set(*this).affine_hull(); +} + +isl::basic_set point::apply(const isl::basic_map &bmap) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::basic_set(*this).apply(bmap); +} + +isl::set point::apply(const isl::map &map) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::basic_set(*this).apply(map); +} + +isl::union_set point::apply(const isl::union_map &umap) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::basic_set(*this).apply(umap); +} + +isl::pw_multi_aff point::as_pw_multi_aff() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::basic_set(*this).as_pw_multi_aff(); +} + +isl::set point::as_set() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::basic_set(*this).as_set(); +} + +isl::set point::bind(const isl::multi_id &tuple) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::basic_set(*this).bind(tuple); +} + +isl::set point::coalesce() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::basic_set(*this).coalesce(); +} + +isl::set point::complement() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::basic_set(*this).complement(); +} + +isl::union_set point::compute_divs() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::basic_set(*this).compute_divs(); +} + +isl::basic_set point::detect_equalities() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::basic_set(*this).detect_equalities(); +} + +isl::val point::dim_max_val(int pos) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::basic_set(*this).dim_max_val(pos); +} + +isl::val point::dim_min_val(int pos) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::basic_set(*this).dim_min_val(pos); +} + +isl::set point::drop_unused_params() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::basic_set(*this).drop_unused_params(); +} + +bool point::every_set(const std::function &test) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::basic_set(*this).every_set(test); +} + +isl::set point::extract_set(const isl::space &space) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::basic_set(*this).extract_set(space); +} + +isl::basic_set point::flatten() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::basic_set(*this).flatten(); +} + +void point::foreach_basic_set(const std::function &fn) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::basic_set(*this).foreach_basic_set(fn); +} + +void point::foreach_point(const std::function &fn) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::basic_set(*this).foreach_point(fn); +} + +void point::foreach_set(const std::function &fn) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::basic_set(*this).foreach_set(fn); +} + +isl::basic_set point::gist(const isl::basic_set &context) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::basic_set(*this).gist(context); +} + +isl::set point::gist(const isl::set &context) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::basic_set(*this).gist(context); +} + +isl::union_set point::gist(const isl::union_set &context) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::basic_set(*this).gist(context); +} + +isl::set point::gist_params(const isl::set &context) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::basic_set(*this).gist_params(context); +} + +isl::map point::identity() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::basic_set(*this).identity(); +} + +isl::pw_aff point::indicator_function() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::basic_set(*this).indicator_function(); +} + +isl::map point::insert_domain(const isl::space &domain) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::basic_set(*this).insert_domain(domain); +} + +isl::basic_set point::intersect(const isl::basic_set &bset2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::basic_set(*this).intersect(bset2); +} + +isl::set point::intersect(const isl::set &set2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::basic_set(*this).intersect(set2); +} + +isl::union_set point::intersect(const isl::union_set &uset2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::basic_set(*this).intersect(uset2); +} + +isl::basic_set point::intersect_params(const isl::basic_set &bset2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::basic_set(*this).intersect_params(bset2); +} + +isl::set point::intersect_params(const isl::set ¶ms) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::basic_set(*this).intersect_params(params); +} + +bool point::involves_locals() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::basic_set(*this).involves_locals(); +} + +bool point::is_disjoint(const isl::set &set2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::basic_set(*this).is_disjoint(set2); +} + +bool point::is_disjoint(const isl::union_set &uset2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::basic_set(*this).is_disjoint(uset2); +} + +bool point::is_empty() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::basic_set(*this).is_empty(); +} + +bool point::is_equal(const isl::basic_set &bset2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::basic_set(*this).is_equal(bset2); +} + +bool point::is_equal(const isl::set &set2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::basic_set(*this).is_equal(set2); +} + +bool point::is_equal(const isl::union_set &uset2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::basic_set(*this).is_equal(uset2); +} + +bool point::is_singleton() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::basic_set(*this).is_singleton(); +} + +bool point::is_strict_subset(const isl::set &set2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::basic_set(*this).is_strict_subset(set2); +} + +bool point::is_strict_subset(const isl::union_set &uset2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::basic_set(*this).is_strict_subset(uset2); +} + +bool point::is_subset(const isl::basic_set &bset2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::basic_set(*this).is_subset(bset2); +} + +bool point::is_subset(const isl::set &set2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::basic_set(*this).is_subset(set2); +} + +bool point::is_subset(const isl::union_set &uset2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::basic_set(*this).is_subset(uset2); +} + +bool point::is_wrapping() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::basic_set(*this).is_wrapping(); +} + +bool point::isa_set() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::basic_set(*this).isa_set(); +} + +isl::fixed_box point::lattice_tile() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::basic_set(*this).lattice_tile(); +} + +isl::set point::lexmax() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::basic_set(*this).lexmax(); +} + +isl::pw_multi_aff point::lexmax_pw_multi_aff() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::basic_set(*this).lexmax_pw_multi_aff(); +} + +isl::set point::lexmin() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::basic_set(*this).lexmin(); +} + +isl::pw_multi_aff point::lexmin_pw_multi_aff() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::basic_set(*this).lexmin_pw_multi_aff(); +} + +isl::set point::lower_bound(const isl::multi_pw_aff &lower) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::basic_set(*this).lower_bound(lower); +} + +isl::set point::lower_bound(const isl::multi_val &lower) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::basic_set(*this).lower_bound(lower); +} + +isl::multi_pw_aff point::max_multi_pw_aff() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::basic_set(*this).max_multi_pw_aff(); +} + +isl::val point::max_val(const isl::aff &obj) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::basic_set(*this).max_val(obj); +} + +isl::multi_pw_aff point::min_multi_pw_aff() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::basic_set(*this).min_multi_pw_aff(); +} + +isl::val point::min_val(const isl::aff &obj) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::basic_set(*this).min_val(obj); +} + +isl::multi_val point::multi_val() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_point_get_multi_val(get()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_val point::get_multi_val() const +{ + return multi_val(); +} + +unsigned point::n_basic_set() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::basic_set(*this).n_basic_set(); +} + +isl::pw_aff point::param_pw_aff_on_domain(const isl::id &id) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::basic_set(*this).param_pw_aff_on_domain(id); +} + +isl::pw_aff point::param_pw_aff_on_domain(const std::string &id) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->param_pw_aff_on_domain(isl::id(ctx(), id)); +} + +isl::basic_set point::params() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::basic_set(*this).params(); +} + +isl::multi_val point::plain_multi_val_if_fixed() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::basic_set(*this).plain_multi_val_if_fixed(); +} + +isl::basic_set point::polyhedral_hull() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::basic_set(*this).polyhedral_hull(); +} + +isl::set point::preimage(const isl::multi_aff &ma) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::basic_set(*this).preimage(ma); +} + +isl::set point::preimage(const isl::multi_pw_aff &mpa) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::basic_set(*this).preimage(mpa); +} + +isl::set point::preimage(const isl::pw_multi_aff &pma) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::basic_set(*this).preimage(pma); +} + +isl::union_set point::preimage(const isl::union_pw_multi_aff &upma) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::basic_set(*this).preimage(upma); +} + +isl::set point::product(const isl::set &set2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::basic_set(*this).product(set2); +} + +isl::set point::project_out_all_params() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::basic_set(*this).project_out_all_params(); +} + +isl::set point::project_out_param(const isl::id &id) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::basic_set(*this).project_out_param(id); +} + +isl::set point::project_out_param(const std::string &id) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->project_out_param(isl::id(ctx(), id)); +} + +isl::set point::project_out_param(const isl::id_list &list) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::basic_set(*this).project_out_param(list); +} + +isl::pw_aff point::pw_aff_on_domain(const isl::val &v) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::basic_set(*this).pw_aff_on_domain(v); +} + +isl::pw_aff point::pw_aff_on_domain(long v) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->pw_aff_on_domain(isl::val(ctx(), v)); +} + +isl::pw_multi_aff point::pw_multi_aff_on_domain(const isl::multi_val &mv) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::basic_set(*this).pw_multi_aff_on_domain(mv); +} + +isl::basic_set point::sample() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::basic_set(*this).sample(); +} + +isl::point point::sample_point() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::basic_set(*this).sample_point(); +} + +isl::set_list point::set_list() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::basic_set(*this).set_list(); +} + +isl::fixed_box point::simple_fixed_box_hull() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::basic_set(*this).simple_fixed_box_hull(); +} + +isl::space point::space() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::basic_set(*this).space(); +} + +isl::val point::stride(int pos) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::basic_set(*this).stride(pos); +} + +isl::set point::subtract(const isl::set &set2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::basic_set(*this).subtract(set2); +} + +isl::union_set point::subtract(const isl::union_set &uset2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::basic_set(*this).subtract(uset2); +} + +isl::set_list point::to_list() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::basic_set(*this).to_list(); +} + +isl::set point::to_set() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_point_to_set(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_set point::to_union_set() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::basic_set(*this).to_union_set(); +} + +isl::map point::translation() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::basic_set(*this).translation(); +} + +unsigned point::tuple_dim() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::basic_set(*this).tuple_dim(); +} + +isl::set point::unbind_params(const isl::multi_id &tuple) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::basic_set(*this).unbind_params(tuple); +} + +isl::map point::unbind_params_insert_domain(const isl::multi_id &domain) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::basic_set(*this).unbind_params_insert_domain(domain); +} + +isl::set point::unite(const isl::basic_set &bset2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::basic_set(*this).unite(bset2); +} + +isl::set point::unite(const isl::set &set2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::basic_set(*this).unite(set2); +} + +isl::union_set point::unite(const isl::union_set &uset2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::basic_set(*this).unite(uset2); +} + +isl::basic_set point::unshifted_simple_hull() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::basic_set(*this).unshifted_simple_hull(); +} + +isl::map point::unwrap() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::basic_set(*this).unwrap(); +} + +isl::set point::upper_bound(const isl::multi_pw_aff &upper) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::basic_set(*this).upper_bound(upper); +} + +isl::set point::upper_bound(const isl::multi_val &upper) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::basic_set(*this).upper_bound(upper); +} + +isl::set point::wrapped_reverse() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::basic_set(*this).wrapped_reverse(); +} + +inline std::ostream &operator<<(std::ostream &os, const point &obj) +{ + if (!obj.get()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_point_get_ctx(obj.get()); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + char *str = isl_point_to_str(obj.get()); + if (!str) + exception::throw_last_error(saved_ctx); + os << str; + free(str); + return os; +} + +// implementations for isl::pw_aff +pw_aff manage(__isl_take isl_pw_aff *ptr) { + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return pw_aff(ptr); +} +pw_aff manage_copy(__isl_keep isl_pw_aff *ptr) { + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_pw_aff_get_ctx(ptr); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + ptr = isl_pw_aff_copy(ptr); + if (!ptr) + exception::throw_last_error(saved_ctx); + return pw_aff(ptr); +} + +pw_aff::pw_aff(__isl_take isl_pw_aff *ptr) + : ptr(ptr) {} + +pw_aff::pw_aff() + : ptr(nullptr) {} + +pw_aff::pw_aff(const pw_aff &obj) + : ptr(nullptr) +{ + if (!obj.ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_pw_aff_get_ctx(obj.ptr); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + ptr = obj.copy(); + if (!ptr) + exception::throw_last_error(saved_ctx); +} + +pw_aff::pw_aff(isl::aff aff) +{ + if (aff.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = aff.ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_aff_from_aff(aff.release()); + if (!res) + exception::throw_last_error(saved_ctx); + ptr = res; +} + +pw_aff::pw_aff(isl::ctx ctx, const std::string &str) +{ + auto saved_ctx = ctx; + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_aff_read_from_str(ctx.release(), str.c_str()); + if (!res) + exception::throw_last_error(saved_ctx); + ptr = res; +} + +pw_aff &pw_aff::operator=(pw_aff obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +pw_aff::~pw_aff() { + if (ptr) + isl_pw_aff_free(ptr); +} + +__isl_give isl_pw_aff *pw_aff::copy() const & { + return isl_pw_aff_copy(ptr); +} + +__isl_keep isl_pw_aff *pw_aff::get() const { + return ptr; +} + +__isl_give isl_pw_aff *pw_aff::release() { + isl_pw_aff *tmp = ptr; + ptr = nullptr; + return tmp; +} + +bool pw_aff::is_null() const { + return ptr == nullptr; +} + +isl::ctx pw_aff::ctx() const { + return isl::ctx(isl_pw_aff_get_ctx(ptr)); +} + +isl::multi_pw_aff pw_aff::add(const isl::multi_pw_aff &multi2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).add(multi2); +} + +isl::multi_union_pw_aff pw_aff::add(const isl::multi_union_pw_aff &multi2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_pw_aff(*this).add(multi2); +} + +isl::pw_aff pw_aff::add(isl::pw_aff pwaff2) const +{ + if (!ptr || pwaff2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_aff_add(copy(), pwaff2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::pw_multi_aff pw_aff::add(const isl::pw_multi_aff &pma2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).add(pma2); +} + +isl::union_pw_aff pw_aff::add(const isl::union_pw_aff &upa2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_pw_aff(*this).add(upa2); +} + +isl::union_pw_multi_aff pw_aff::add(const isl::union_pw_multi_aff &upma2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_pw_aff(*this).add(upma2); +} + +isl::pw_aff pw_aff::add(const isl::aff &pwaff2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->add(isl::pw_aff(pwaff2)); +} + +isl::pw_aff pw_aff::add_constant(isl::val v) const +{ + if (!ptr || v.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_aff_add_constant_val(copy(), v.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::pw_aff pw_aff::add_constant(long v) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->add_constant(isl::val(ctx(), v)); +} + +isl::pw_multi_aff pw_aff::add_constant(const isl::multi_val &mv) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).add_constant(mv); +} + +isl::union_pw_multi_aff pw_aff::apply(const isl::union_pw_multi_aff &upma2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_pw_aff(*this).apply(upma2); +} + +isl::aff pw_aff::as_aff() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_aff_as_aff(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::map pw_aff::as_map() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_aff_as_map(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_aff pw_aff::as_multi_aff() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).as_multi_aff(); +} + +isl::multi_union_pw_aff pw_aff::as_multi_union_pw_aff() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_pw_aff(*this).as_multi_union_pw_aff(); +} + +isl::pw_multi_aff pw_aff::as_pw_multi_aff() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_pw_aff(*this).as_pw_multi_aff(); +} + +isl::set pw_aff::as_set() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).as_set(); +} + +isl::union_map pw_aff::as_union_map() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_pw_aff(*this).as_union_map(); +} + +isl::pw_aff pw_aff::at(int pos) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).at(pos); +} + +isl::set pw_aff::bind(const isl::multi_id &tuple) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::multi_pw_aff(*this).bind(tuple); +} + +isl::set pw_aff::bind(isl::id id) const +{ + if (!ptr || id.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_aff_bind_id(copy(), id.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::set pw_aff::bind(const std::string &id) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->bind(isl::id(ctx(), id)); +} + +isl::pw_aff pw_aff::bind_domain(isl::multi_id tuple) const +{ + if (!ptr || tuple.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_aff_bind_domain(copy(), tuple.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::pw_aff pw_aff::bind_domain_wrapped_domain(isl::multi_id tuple) const +{ + if (!ptr || tuple.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_aff_bind_domain_wrapped_domain(copy(), tuple.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::pw_aff pw_aff::ceil() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_aff_ceil(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::pw_aff pw_aff::coalesce() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_aff_coalesce(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::pw_aff pw_aff::cond(isl::pw_aff pwaff_true, isl::pw_aff pwaff_false) const +{ + if (!ptr || pwaff_true.is_null() || pwaff_false.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_aff_cond(copy(), pwaff_true.release(), pwaff_false.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::pw_aff pw_aff::div(isl::pw_aff pa2) const +{ + if (!ptr || pa2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_aff_div(copy(), pa2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::set pw_aff::domain() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_aff_domain(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::pw_aff pw_aff::domain_reverse() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_aff_domain_reverse(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::pw_aff pw_aff::drop_unused_params() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_aff_drop_unused_params(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::set pw_aff::eq_set(isl::pw_aff pwaff2) const +{ + if (!ptr || pwaff2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_aff_eq_set(copy(), pwaff2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::val pw_aff::eval(isl::point pnt) const +{ + if (!ptr || pnt.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_aff_eval(copy(), pnt.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::pw_multi_aff pw_aff::extract_pw_multi_aff(const isl::space &space) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_pw_aff(*this).extract_pw_multi_aff(space); +} + +isl::multi_pw_aff pw_aff::flat_range_product(const isl::multi_pw_aff &multi2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).flat_range_product(multi2); +} + +isl::multi_union_pw_aff pw_aff::flat_range_product(const isl::multi_union_pw_aff &multi2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_pw_aff(*this).flat_range_product(multi2); +} + +isl::pw_multi_aff pw_aff::flat_range_product(const isl::pw_multi_aff &pma2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).flat_range_product(pma2); +} + +isl::union_pw_multi_aff pw_aff::flat_range_product(const isl::union_pw_multi_aff &upma2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_pw_aff(*this).flat_range_product(upma2); +} + +isl::pw_aff pw_aff::floor() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_aff_floor(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +void pw_aff::foreach_piece(const std::function &fn) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).foreach_piece(fn); +} + +isl::set pw_aff::ge_set(isl::pw_aff pwaff2) const +{ + if (!ptr || pwaff2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_aff_ge_set(copy(), pwaff2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::pw_aff pw_aff::gist(isl::set context) const +{ + if (!ptr || context.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_aff_gist(copy(), context.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_pw_aff pw_aff::gist(const isl::union_set &context) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_pw_aff(*this).gist(context); +} + +isl::pw_aff pw_aff::gist(const isl::basic_set &context) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->gist(isl::set(context)); +} + +isl::pw_aff pw_aff::gist(const isl::point &context) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->gist(isl::set(context)); +} + +isl::pw_aff pw_aff::gist_params(isl::set context) const +{ + if (!ptr || context.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_aff_gist_params(copy(), context.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::set pw_aff::gt_set(isl::pw_aff pwaff2) const +{ + if (!ptr || pwaff2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_aff_gt_set(copy(), pwaff2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +bool pw_aff::has_range_tuple_id() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).has_range_tuple_id(); +} + +isl::multi_pw_aff pw_aff::identity() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).identity(); +} + +isl::pw_aff pw_aff::insert_domain(isl::space domain) const +{ + if (!ptr || domain.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_aff_insert_domain(copy(), domain.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::pw_aff pw_aff::intersect_domain(isl::set set) const +{ + if (!ptr || set.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_aff_intersect_domain(copy(), set.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_pw_aff pw_aff::intersect_domain(const isl::space &space) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_pw_aff(*this).intersect_domain(space); +} + +isl::union_pw_aff pw_aff::intersect_domain(const isl::union_set &uset) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_pw_aff(*this).intersect_domain(uset); +} + +isl::pw_aff pw_aff::intersect_domain(const isl::basic_set &set) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->intersect_domain(isl::set(set)); +} + +isl::pw_aff pw_aff::intersect_domain(const isl::point &set) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->intersect_domain(isl::set(set)); +} + +isl::union_pw_aff pw_aff::intersect_domain_wrapped_domain(const isl::union_set &uset) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_pw_aff(*this).intersect_domain_wrapped_domain(uset); +} + +isl::union_pw_aff pw_aff::intersect_domain_wrapped_range(const isl::union_set &uset) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_pw_aff(*this).intersect_domain_wrapped_range(uset); +} + +isl::pw_aff pw_aff::intersect_params(isl::set set) const +{ + if (!ptr || set.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_aff_intersect_params(copy(), set.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +bool pw_aff::involves_locals() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).involves_locals(); +} + +bool pw_aff::involves_nan() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::multi_pw_aff(*this).involves_nan(); +} + +bool pw_aff::involves_param(const isl::id &id) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).involves_param(id); +} + +bool pw_aff::involves_param(const std::string &id) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->involves_param(isl::id(ctx(), id)); +} + +bool pw_aff::involves_param(const isl::id_list &list) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).involves_param(list); +} + +bool pw_aff::isa_aff() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_aff_isa_aff(get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +bool pw_aff::isa_multi_aff() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).isa_multi_aff(); +} + +bool pw_aff::isa_pw_multi_aff() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_pw_aff(*this).isa_pw_multi_aff(); +} + +isl::set pw_aff::le_set(isl::pw_aff pwaff2) const +{ + if (!ptr || pwaff2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_aff_le_set(copy(), pwaff2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::pw_aff_list pw_aff::list() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::multi_pw_aff(*this).list(); +} + +isl::set pw_aff::lt_set(isl::pw_aff pwaff2) const +{ + if (!ptr || pwaff2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_aff_lt_set(copy(), pwaff2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_pw_aff pw_aff::max(const isl::multi_pw_aff &multi2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).max(multi2); +} + +isl::pw_aff pw_aff::max(isl::pw_aff pwaff2) const +{ + if (!ptr || pwaff2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_aff_max(copy(), pwaff2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::pw_aff pw_aff::max(const isl::aff &pwaff2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->max(isl::pw_aff(pwaff2)); +} + +isl::multi_val pw_aff::max_multi_val() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).max_multi_val(); +} + +isl::val pw_aff::max_val() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_aff_max_val(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_pw_aff pw_aff::min(const isl::multi_pw_aff &multi2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).min(multi2); +} + +isl::pw_aff pw_aff::min(isl::pw_aff pwaff2) const +{ + if (!ptr || pwaff2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_aff_min(copy(), pwaff2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::pw_aff pw_aff::min(const isl::aff &pwaff2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->min(isl::pw_aff(pwaff2)); +} + +isl::multi_val pw_aff::min_multi_val() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).min_multi_val(); +} + +isl::val pw_aff::min_val() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_aff_min_val(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::pw_aff pw_aff::mod(isl::val mod) const +{ + if (!ptr || mod.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_aff_mod_val(copy(), mod.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::pw_aff pw_aff::mod(long mod) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->mod(isl::val(ctx(), mod)); +} + +isl::pw_aff pw_aff::mul(isl::pw_aff pwaff2) const +{ + if (!ptr || pwaff2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_aff_mul(copy(), pwaff2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +unsigned pw_aff::n_piece() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).n_piece(); +} + +isl::set pw_aff::ne_set(isl::pw_aff pwaff2) const +{ + if (!ptr || pwaff2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_aff_ne_set(copy(), pwaff2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::pw_aff pw_aff::neg() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_aff_neg(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::pw_aff pw_aff::param_on_domain(isl::set domain, isl::id id) +{ + if (domain.is_null() || id.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = domain.ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_aff_param_on_domain_id(domain.release(), id.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::set pw_aff::params() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_aff_params(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +bool pw_aff::plain_is_empty() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_pw_aff(*this).plain_is_empty(); +} + +bool pw_aff::plain_is_equal(const isl::multi_pw_aff &multi2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).plain_is_equal(multi2); +} + +bool pw_aff::plain_is_equal(const isl::multi_union_pw_aff &multi2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_pw_aff(*this).plain_is_equal(multi2); +} + +bool pw_aff::plain_is_equal(const isl::pw_aff &pwaff2) const +{ + if (!ptr || pwaff2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_aff_plain_is_equal(get(), pwaff2.get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +bool pw_aff::plain_is_equal(const isl::pw_multi_aff &pma2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).plain_is_equal(pma2); +} + +bool pw_aff::plain_is_equal(const isl::union_pw_aff &upa2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_pw_aff(*this).plain_is_equal(upa2); +} + +bool pw_aff::plain_is_equal(const isl::union_pw_multi_aff &upma2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_pw_aff(*this).plain_is_equal(upma2); +} + +bool pw_aff::plain_is_equal(const isl::aff &pwaff2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->plain_is_equal(isl::pw_aff(pwaff2)); +} + +isl::pw_multi_aff pw_aff::preimage_domain_wrapped_domain(const isl::pw_multi_aff &pma2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).preimage_domain_wrapped_domain(pma2); +} + +isl::union_pw_multi_aff pw_aff::preimage_domain_wrapped_domain(const isl::union_pw_multi_aff &upma2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_pw_aff(*this).preimage_domain_wrapped_domain(upma2); +} + +isl::multi_pw_aff pw_aff::product(const isl::multi_pw_aff &multi2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).product(multi2); +} + +isl::pw_multi_aff pw_aff::product(const isl::pw_multi_aff &pma2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).product(pma2); +} + +isl::pw_aff pw_aff::pullback(isl::multi_aff ma) const +{ + if (!ptr || ma.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_aff_pullback_multi_aff(copy(), ma.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::pw_aff pw_aff::pullback(isl::multi_pw_aff mpa) const +{ + if (!ptr || mpa.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_aff_pullback_multi_pw_aff(copy(), mpa.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::pw_aff pw_aff::pullback(isl::pw_multi_aff pma) const +{ + if (!ptr || pma.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_aff_pullback_pw_multi_aff(copy(), pma.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_pw_aff pw_aff::pullback(const isl::union_pw_multi_aff &upma) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_pw_aff(*this).pullback(upma); +} + +isl::pw_multi_aff_list pw_aff::pw_multi_aff_list() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_pw_aff(*this).pw_multi_aff_list(); +} + +isl::pw_multi_aff pw_aff::range_factor_domain() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).range_factor_domain(); +} + +isl::pw_multi_aff pw_aff::range_factor_range() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).range_factor_range(); +} + +isl::multi_pw_aff pw_aff::range_product(const isl::multi_pw_aff &multi2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).range_product(multi2); +} + +isl::multi_union_pw_aff pw_aff::range_product(const isl::multi_union_pw_aff &multi2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_pw_aff(*this).range_product(multi2); +} + +isl::pw_multi_aff pw_aff::range_product(const isl::pw_multi_aff &pma2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).range_product(pma2); +} + +isl::union_pw_multi_aff pw_aff::range_product(const isl::union_pw_multi_aff &upma2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_pw_aff(*this).range_product(upma2); +} + +isl::id pw_aff::range_tuple_id() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).range_tuple_id(); +} + +isl::multi_pw_aff pw_aff::reset_range_tuple_id() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::multi_pw_aff(*this).reset_range_tuple_id(); +} + +isl::pw_aff pw_aff::scale(isl::val v) const +{ + if (!ptr || v.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_aff_scale_val(copy(), v.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::pw_aff pw_aff::scale(long v) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->scale(isl::val(ctx(), v)); +} + +isl::pw_multi_aff pw_aff::scale(const isl::multi_val &mv) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).scale(mv); +} + +isl::pw_aff pw_aff::scale_down(isl::val f) const +{ + if (!ptr || f.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_aff_scale_down_val(copy(), f.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::pw_aff pw_aff::scale_down(long f) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->scale_down(isl::val(ctx(), f)); +} + +isl::pw_multi_aff pw_aff::scale_down(const isl::multi_val &mv) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).scale_down(mv); +} + +isl::multi_pw_aff pw_aff::set_at(int pos, const isl::pw_aff &el) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).set_at(pos, el); +} + +isl::multi_union_pw_aff pw_aff::set_at(int pos, const isl::union_pw_aff &el) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_pw_aff(*this).set_at(pos, el); +} + +isl::pw_multi_aff pw_aff::set_range_tuple(const isl::id &id) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).set_range_tuple(id); +} + +isl::pw_multi_aff pw_aff::set_range_tuple(const std::string &id) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->set_range_tuple(isl::id(ctx(), id)); +} + +unsigned pw_aff::size() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::multi_pw_aff(*this).size(); +} + +isl::space pw_aff::space() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_aff_get_space(get()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::space pw_aff::get_space() const +{ + return space(); +} + +isl::multi_pw_aff pw_aff::sub(const isl::multi_pw_aff &multi2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).sub(multi2); +} + +isl::multi_union_pw_aff pw_aff::sub(const isl::multi_union_pw_aff &multi2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_pw_aff(*this).sub(multi2); +} + +isl::pw_aff pw_aff::sub(isl::pw_aff pwaff2) const +{ + if (!ptr || pwaff2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_aff_sub(copy(), pwaff2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::pw_multi_aff pw_aff::sub(const isl::pw_multi_aff &pma2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).sub(pma2); +} + +isl::union_pw_aff pw_aff::sub(const isl::union_pw_aff &upa2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_pw_aff(*this).sub(upa2); +} + +isl::union_pw_multi_aff pw_aff::sub(const isl::union_pw_multi_aff &upma2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_pw_aff(*this).sub(upma2); +} + +isl::pw_aff pw_aff::sub(const isl::aff &pwaff2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->sub(isl::pw_aff(pwaff2)); +} + +isl::pw_aff pw_aff::subtract_domain(isl::set set) const +{ + if (!ptr || set.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_aff_subtract_domain(copy(), set.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_pw_aff pw_aff::subtract_domain(const isl::space &space) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_pw_aff(*this).subtract_domain(space); +} + +isl::union_pw_aff pw_aff::subtract_domain(const isl::union_set &uset) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_pw_aff(*this).subtract_domain(uset); +} + +isl::pw_aff pw_aff::subtract_domain(const isl::basic_set &set) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->subtract_domain(isl::set(set)); +} + +isl::pw_aff pw_aff::subtract_domain(const isl::point &set) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->subtract_domain(isl::set(set)); +} + +isl::pw_aff pw_aff::tdiv_q(isl::pw_aff pa2) const +{ + if (!ptr || pa2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_aff_tdiv_q(copy(), pa2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::pw_aff pw_aff::tdiv_r(isl::pw_aff pa2) const +{ + if (!ptr || pa2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_aff_tdiv_r(copy(), pa2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::pw_aff_list pw_aff::to_list() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_aff_to_list(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_pw_aff pw_aff::to_multi_pw_aff() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).to_multi_pw_aff(); +} + +isl::union_pw_aff pw_aff::to_union_pw_aff() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_aff_to_union_pw_aff(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_pw_multi_aff pw_aff::to_union_pw_multi_aff() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).to_union_pw_multi_aff(); +} + +isl::multi_pw_aff pw_aff::unbind_params_insert_domain(const isl::multi_id &domain) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).unbind_params_insert_domain(domain); +} + +isl::multi_pw_aff pw_aff::union_add(const isl::multi_pw_aff &mpa2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).union_add(mpa2); +} + +isl::multi_union_pw_aff pw_aff::union_add(const isl::multi_union_pw_aff &mupa2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_pw_aff(*this).union_add(mupa2); +} + +isl::pw_aff pw_aff::union_add(isl::pw_aff pwaff2) const +{ + if (!ptr || pwaff2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_aff_union_add(copy(), pwaff2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::pw_multi_aff pw_aff::union_add(const isl::pw_multi_aff &pma2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::pw_multi_aff(*this).union_add(pma2); +} + +isl::union_pw_aff pw_aff::union_add(const isl::union_pw_aff &upa2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_pw_aff(*this).union_add(upa2); +} + +isl::union_pw_multi_aff pw_aff::union_add(const isl::union_pw_multi_aff &upma2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_pw_aff(*this).union_add(upma2); +} + +isl::pw_aff pw_aff::union_add(const isl::aff &pwaff2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->union_add(isl::pw_aff(pwaff2)); +} + +inline std::ostream &operator<<(std::ostream &os, const pw_aff &obj) +{ + if (!obj.get()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_pw_aff_get_ctx(obj.get()); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + char *str = isl_pw_aff_to_str(obj.get()); + if (!str) + exception::throw_last_error(saved_ctx); + os << str; + free(str); + return os; +} + +// implementations for isl::pw_aff_list +pw_aff_list manage(__isl_take isl_pw_aff_list *ptr) { + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return pw_aff_list(ptr); +} +pw_aff_list manage_copy(__isl_keep isl_pw_aff_list *ptr) { + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_pw_aff_list_get_ctx(ptr); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + ptr = isl_pw_aff_list_copy(ptr); + if (!ptr) + exception::throw_last_error(saved_ctx); + return pw_aff_list(ptr); +} + +pw_aff_list::pw_aff_list(__isl_take isl_pw_aff_list *ptr) + : ptr(ptr) {} + +pw_aff_list::pw_aff_list() + : ptr(nullptr) {} + +pw_aff_list::pw_aff_list(const pw_aff_list &obj) + : ptr(nullptr) +{ + if (!obj.ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_pw_aff_list_get_ctx(obj.ptr); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + ptr = obj.copy(); + if (!ptr) + exception::throw_last_error(saved_ctx); +} + +pw_aff_list::pw_aff_list(isl::ctx ctx, int n) +{ + auto saved_ctx = ctx; + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_aff_list_alloc(ctx.release(), n); + if (!res) + exception::throw_last_error(saved_ctx); + ptr = res; +} + +pw_aff_list::pw_aff_list(isl::pw_aff el) +{ + if (el.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = el.ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_aff_list_from_pw_aff(el.release()); + if (!res) + exception::throw_last_error(saved_ctx); + ptr = res; +} + +pw_aff_list::pw_aff_list(isl::ctx ctx, const std::string &str) +{ + auto saved_ctx = ctx; + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_aff_list_read_from_str(ctx.release(), str.c_str()); + if (!res) + exception::throw_last_error(saved_ctx); + ptr = res; +} + +pw_aff_list &pw_aff_list::operator=(pw_aff_list obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +pw_aff_list::~pw_aff_list() { + if (ptr) + isl_pw_aff_list_free(ptr); +} + +__isl_give isl_pw_aff_list *pw_aff_list::copy() const & { + return isl_pw_aff_list_copy(ptr); +} + +__isl_keep isl_pw_aff_list *pw_aff_list::get() const { + return ptr; +} + +__isl_give isl_pw_aff_list *pw_aff_list::release() { + isl_pw_aff_list *tmp = ptr; + ptr = nullptr; + return tmp; +} + +bool pw_aff_list::is_null() const { + return ptr == nullptr; +} + +isl::ctx pw_aff_list::ctx() const { + return isl::ctx(isl_pw_aff_list_get_ctx(ptr)); +} + +isl::pw_aff_list pw_aff_list::add(isl::pw_aff el) const +{ + if (!ptr || el.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_aff_list_add(copy(), el.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::pw_aff pw_aff_list::at(int index) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_aff_list_get_at(get(), index); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::pw_aff pw_aff_list::get_at(int index) const +{ + return at(index); +} + +isl::pw_aff_list pw_aff_list::clear() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_aff_list_clear(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::pw_aff_list pw_aff_list::concat(isl::pw_aff_list list2) const +{ + if (!ptr || list2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_aff_list_concat(copy(), list2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::pw_aff_list pw_aff_list::drop(unsigned int first, unsigned int n) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_aff_list_drop(copy(), first, n); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +void pw_aff_list::foreach(const std::function &fn) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + struct fn_data { + std::function func; + std::exception_ptr eptr; + } fn_data = { fn }; + auto fn_lambda = [](isl_pw_aff *arg_0, void *arg_1) -> isl_stat { + auto *data = static_cast(arg_1); + ISL_CPP_TRY { + (data->func)(manage(arg_0)); + return isl_stat_ok; + } ISL_CPP_CATCH_ALL { + data->eptr = std::current_exception(); + return isl_stat_error; + } + }; + auto res = isl_pw_aff_list_foreach(get(), fn_lambda, &fn_data); + if (fn_data.eptr) + std::rethrow_exception(fn_data.eptr); + if (res < 0) + exception::throw_last_error(saved_ctx); + return; +} + +void pw_aff_list::foreach_scc(const std::function &follows, const std::function &fn) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + struct follows_data { + std::function func; + std::exception_ptr eptr; + } follows_data = { follows }; + auto follows_lambda = [](isl_pw_aff *arg_0, isl_pw_aff *arg_1, void *arg_2) -> isl_bool { + auto *data = static_cast(arg_2); + ISL_CPP_TRY { + auto ret = (data->func)(manage_copy(arg_0), manage_copy(arg_1)); + return ret ? isl_bool_true : isl_bool_false; + } ISL_CPP_CATCH_ALL { + data->eptr = std::current_exception(); + return isl_bool_error; + } + }; + struct fn_data { + std::function func; + std::exception_ptr eptr; + } fn_data = { fn }; + auto fn_lambda = [](isl_pw_aff_list *arg_0, void *arg_1) -> isl_stat { + auto *data = static_cast(arg_1); + ISL_CPP_TRY { + (data->func)(manage(arg_0)); + return isl_stat_ok; + } ISL_CPP_CATCH_ALL { + data->eptr = std::current_exception(); + return isl_stat_error; + } + }; + auto res = isl_pw_aff_list_foreach_scc(get(), follows_lambda, &follows_data, fn_lambda, &fn_data); + if (follows_data.eptr) + std::rethrow_exception(follows_data.eptr); + if (fn_data.eptr) + std::rethrow_exception(fn_data.eptr); + if (res < 0) + exception::throw_last_error(saved_ctx); + return; +} + +isl::pw_aff_list pw_aff_list::insert(unsigned int pos, isl::pw_aff el) const +{ + if (!ptr || el.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_aff_list_insert(copy(), pos, el.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::pw_aff_list pw_aff_list::set_at(int index, isl::pw_aff el) const +{ + if (!ptr || el.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_aff_list_set_at(copy(), index, el.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +unsigned pw_aff_list::size() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_aff_list_size(get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +inline std::ostream &operator<<(std::ostream &os, const pw_aff_list &obj) +{ + if (!obj.get()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_pw_aff_list_get_ctx(obj.get()); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + char *str = isl_pw_aff_list_to_str(obj.get()); + if (!str) + exception::throw_last_error(saved_ctx); + os << str; + free(str); + return os; +} + +// implementations for isl::pw_multi_aff +pw_multi_aff manage(__isl_take isl_pw_multi_aff *ptr) { + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return pw_multi_aff(ptr); +} +pw_multi_aff manage_copy(__isl_keep isl_pw_multi_aff *ptr) { + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_pw_multi_aff_get_ctx(ptr); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + ptr = isl_pw_multi_aff_copy(ptr); + if (!ptr) + exception::throw_last_error(saved_ctx); + return pw_multi_aff(ptr); +} + +pw_multi_aff::pw_multi_aff(__isl_take isl_pw_multi_aff *ptr) + : ptr(ptr) {} + +pw_multi_aff::pw_multi_aff() + : ptr(nullptr) {} + +pw_multi_aff::pw_multi_aff(const pw_multi_aff &obj) + : ptr(nullptr) +{ + if (!obj.ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_pw_multi_aff_get_ctx(obj.ptr); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + ptr = obj.copy(); + if (!ptr) + exception::throw_last_error(saved_ctx); +} + +pw_multi_aff::pw_multi_aff(isl::multi_aff ma) +{ + if (ma.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ma.ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_multi_aff_from_multi_aff(ma.release()); + if (!res) + exception::throw_last_error(saved_ctx); + ptr = res; +} + +pw_multi_aff::pw_multi_aff(isl::pw_aff pa) +{ + if (pa.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = pa.ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_multi_aff_from_pw_aff(pa.release()); + if (!res) + exception::throw_last_error(saved_ctx); + ptr = res; +} + +pw_multi_aff::pw_multi_aff(isl::ctx ctx, const std::string &str) +{ + auto saved_ctx = ctx; + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_multi_aff_read_from_str(ctx.release(), str.c_str()); + if (!res) + exception::throw_last_error(saved_ctx); + ptr = res; +} + +pw_multi_aff &pw_multi_aff::operator=(pw_multi_aff obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +pw_multi_aff::~pw_multi_aff() { + if (ptr) + isl_pw_multi_aff_free(ptr); +} + +__isl_give isl_pw_multi_aff *pw_multi_aff::copy() const & { + return isl_pw_multi_aff_copy(ptr); +} + +__isl_keep isl_pw_multi_aff *pw_multi_aff::get() const { + return ptr; +} + +__isl_give isl_pw_multi_aff *pw_multi_aff::release() { + isl_pw_multi_aff *tmp = ptr; + ptr = nullptr; + return tmp; +} + +bool pw_multi_aff::is_null() const { + return ptr == nullptr; +} + +isl::ctx pw_multi_aff::ctx() const { + return isl::ctx(isl_pw_multi_aff_get_ctx(ptr)); +} + +isl::multi_pw_aff pw_multi_aff::add(const isl::multi_pw_aff &multi2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::multi_pw_aff(*this).add(multi2); +} + +isl::multi_union_pw_aff pw_multi_aff::add(const isl::multi_union_pw_aff &multi2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::multi_pw_aff(*this).add(multi2); +} + +isl::pw_multi_aff pw_multi_aff::add(isl::pw_multi_aff pma2) const +{ + if (!ptr || pma2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_multi_aff_add(copy(), pma2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_pw_multi_aff pw_multi_aff::add(const isl::union_pw_multi_aff &upma2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_pw_multi_aff(*this).add(upma2); +} + +isl::pw_multi_aff pw_multi_aff::add(const isl::multi_aff &pma2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->add(isl::pw_multi_aff(pma2)); +} + +isl::pw_multi_aff pw_multi_aff::add(const isl::pw_aff &pma2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->add(isl::pw_multi_aff(pma2)); +} + +isl::pw_multi_aff pw_multi_aff::add_constant(isl::multi_val mv) const +{ + if (!ptr || mv.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_multi_aff_add_constant_multi_val(copy(), mv.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::pw_multi_aff pw_multi_aff::add_constant(isl::val v) const +{ + if (!ptr || v.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_multi_aff_add_constant_val(copy(), v.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::pw_multi_aff pw_multi_aff::add_constant(long v) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->add_constant(isl::val(ctx(), v)); +} + +isl::union_pw_multi_aff pw_multi_aff::apply(const isl::union_pw_multi_aff &upma2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_pw_multi_aff(*this).apply(upma2); +} + +isl::map pw_multi_aff::as_map() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_multi_aff_as_map(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_aff pw_multi_aff::as_multi_aff() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_multi_aff_as_multi_aff(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_union_pw_aff pw_multi_aff::as_multi_union_pw_aff() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_pw_multi_aff(*this).as_multi_union_pw_aff(); +} + +isl::pw_multi_aff pw_multi_aff::as_pw_multi_aff() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_pw_multi_aff(*this).as_pw_multi_aff(); +} + +isl::set pw_multi_aff::as_set() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_multi_aff_as_set(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map pw_multi_aff::as_union_map() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_pw_multi_aff(*this).as_union_map(); +} + +isl::pw_aff pw_multi_aff::at(int pos) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_multi_aff_get_at(get(), pos); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::pw_aff pw_multi_aff::get_at(int pos) const +{ + return at(pos); +} + +isl::set pw_multi_aff::bind(const isl::multi_id &tuple) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::multi_pw_aff(*this).bind(tuple); +} + +isl::pw_multi_aff pw_multi_aff::bind_domain(isl::multi_id tuple) const +{ + if (!ptr || tuple.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_multi_aff_bind_domain(copy(), tuple.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::pw_multi_aff pw_multi_aff::bind_domain_wrapped_domain(isl::multi_id tuple) const +{ + if (!ptr || tuple.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_multi_aff_bind_domain_wrapped_domain(copy(), tuple.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::pw_multi_aff pw_multi_aff::coalesce() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_multi_aff_coalesce(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::set pw_multi_aff::domain() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_multi_aff_domain(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::pw_multi_aff pw_multi_aff::domain_map(isl::space space) +{ + if (space.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = space.ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_multi_aff_domain_map(space.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::pw_multi_aff pw_multi_aff::domain_reverse() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_multi_aff_domain_reverse(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::pw_multi_aff pw_multi_aff::drop_unused_params() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_multi_aff_drop_unused_params(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::pw_multi_aff pw_multi_aff::extract_pw_multi_aff(const isl::space &space) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_pw_multi_aff(*this).extract_pw_multi_aff(space); +} + +isl::multi_pw_aff pw_multi_aff::flat_range_product(const isl::multi_pw_aff &multi2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::multi_pw_aff(*this).flat_range_product(multi2); +} + +isl::multi_union_pw_aff pw_multi_aff::flat_range_product(const isl::multi_union_pw_aff &multi2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::multi_pw_aff(*this).flat_range_product(multi2); +} + +isl::pw_multi_aff pw_multi_aff::flat_range_product(isl::pw_multi_aff pma2) const +{ + if (!ptr || pma2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_multi_aff_flat_range_product(copy(), pma2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_pw_multi_aff pw_multi_aff::flat_range_product(const isl::union_pw_multi_aff &upma2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_pw_multi_aff(*this).flat_range_product(upma2); +} + +isl::pw_multi_aff pw_multi_aff::flat_range_product(const isl::multi_aff &pma2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->flat_range_product(isl::pw_multi_aff(pma2)); +} + +isl::pw_multi_aff pw_multi_aff::flat_range_product(const isl::pw_aff &pma2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->flat_range_product(isl::pw_multi_aff(pma2)); +} + +void pw_multi_aff::foreach_piece(const std::function &fn) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + struct fn_data { + std::function func; + std::exception_ptr eptr; + } fn_data = { fn }; + auto fn_lambda = [](isl_set *arg_0, isl_multi_aff *arg_1, void *arg_2) -> isl_stat { + auto *data = static_cast(arg_2); + ISL_CPP_TRY { + (data->func)(manage(arg_0), manage(arg_1)); + return isl_stat_ok; + } ISL_CPP_CATCH_ALL { + data->eptr = std::current_exception(); + return isl_stat_error; + } + }; + auto res = isl_pw_multi_aff_foreach_piece(get(), fn_lambda, &fn_data); + if (fn_data.eptr) + std::rethrow_exception(fn_data.eptr); + if (res < 0) + exception::throw_last_error(saved_ctx); + return; +} + +isl::pw_multi_aff pw_multi_aff::gist(isl::set set) const +{ + if (!ptr || set.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_multi_aff_gist(copy(), set.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_pw_multi_aff pw_multi_aff::gist(const isl::union_set &context) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_pw_multi_aff(*this).gist(context); +} + +isl::pw_multi_aff pw_multi_aff::gist(const isl::basic_set &set) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->gist(isl::set(set)); +} + +isl::pw_multi_aff pw_multi_aff::gist(const isl::point &set) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->gist(isl::set(set)); +} + +isl::pw_multi_aff pw_multi_aff::gist_params(isl::set set) const +{ + if (!ptr || set.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_multi_aff_gist_params(copy(), set.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +bool pw_multi_aff::has_range_tuple_id() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_multi_aff_has_range_tuple_id(get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +isl::multi_pw_aff pw_multi_aff::identity() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::multi_pw_aff(*this).identity(); +} + +isl::pw_multi_aff pw_multi_aff::identity_on_domain(isl::space space) +{ + if (space.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = space.ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_multi_aff_identity_on_domain_space(space.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::pw_multi_aff pw_multi_aff::insert_domain(isl::space domain) const +{ + if (!ptr || domain.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_multi_aff_insert_domain(copy(), domain.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::pw_multi_aff pw_multi_aff::intersect_domain(isl::set set) const +{ + if (!ptr || set.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_multi_aff_intersect_domain(copy(), set.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_pw_multi_aff pw_multi_aff::intersect_domain(const isl::space &space) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_pw_multi_aff(*this).intersect_domain(space); +} + +isl::union_pw_multi_aff pw_multi_aff::intersect_domain(const isl::union_set &uset) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_pw_multi_aff(*this).intersect_domain(uset); +} + +isl::pw_multi_aff pw_multi_aff::intersect_domain(const isl::basic_set &set) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->intersect_domain(isl::set(set)); +} + +isl::pw_multi_aff pw_multi_aff::intersect_domain(const isl::point &set) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->intersect_domain(isl::set(set)); +} + +isl::union_pw_multi_aff pw_multi_aff::intersect_domain_wrapped_domain(const isl::union_set &uset) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_pw_multi_aff(*this).intersect_domain_wrapped_domain(uset); +} + +isl::union_pw_multi_aff pw_multi_aff::intersect_domain_wrapped_range(const isl::union_set &uset) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_pw_multi_aff(*this).intersect_domain_wrapped_range(uset); +} + +isl::pw_multi_aff pw_multi_aff::intersect_params(isl::set set) const +{ + if (!ptr || set.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_multi_aff_intersect_params(copy(), set.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +bool pw_multi_aff::involves_locals() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_multi_aff_involves_locals(get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +bool pw_multi_aff::involves_nan() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::multi_pw_aff(*this).involves_nan(); +} + +bool pw_multi_aff::involves_param(const isl::id &id) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::multi_pw_aff(*this).involves_param(id); +} + +bool pw_multi_aff::involves_param(const std::string &id) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->involves_param(isl::id(ctx(), id)); +} + +bool pw_multi_aff::involves_param(const isl::id_list &list) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::multi_pw_aff(*this).involves_param(list); +} + +bool pw_multi_aff::isa_multi_aff() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_multi_aff_isa_multi_aff(get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +bool pw_multi_aff::isa_pw_multi_aff() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_pw_multi_aff(*this).isa_pw_multi_aff(); +} + +isl::pw_aff_list pw_multi_aff::list() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::multi_pw_aff(*this).list(); +} + +isl::multi_pw_aff pw_multi_aff::max(const isl::multi_pw_aff &multi2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::multi_pw_aff(*this).max(multi2); +} + +isl::multi_val pw_multi_aff::max_multi_val() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_multi_aff_max_multi_val(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_pw_aff pw_multi_aff::min(const isl::multi_pw_aff &multi2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::multi_pw_aff(*this).min(multi2); +} + +isl::multi_val pw_multi_aff::min_multi_val() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_multi_aff_min_multi_val(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::pw_multi_aff pw_multi_aff::multi_val_on_domain(isl::set domain, isl::multi_val mv) +{ + if (domain.is_null() || mv.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = domain.ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_multi_aff_multi_val_on_domain(domain.release(), mv.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +unsigned pw_multi_aff::n_piece() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_multi_aff_n_piece(get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +isl::multi_pw_aff pw_multi_aff::neg() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::multi_pw_aff(*this).neg(); +} + +bool pw_multi_aff::plain_is_empty() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_pw_multi_aff(*this).plain_is_empty(); +} + +bool pw_multi_aff::plain_is_equal(const isl::multi_pw_aff &multi2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::multi_pw_aff(*this).plain_is_equal(multi2); +} + +bool pw_multi_aff::plain_is_equal(const isl::multi_union_pw_aff &multi2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::multi_pw_aff(*this).plain_is_equal(multi2); +} + +bool pw_multi_aff::plain_is_equal(const isl::pw_multi_aff &pma2) const +{ + if (!ptr || pma2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_multi_aff_plain_is_equal(get(), pma2.get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +bool pw_multi_aff::plain_is_equal(const isl::union_pw_multi_aff &upma2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_pw_multi_aff(*this).plain_is_equal(upma2); +} + +bool pw_multi_aff::plain_is_equal(const isl::multi_aff &pma2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->plain_is_equal(isl::pw_multi_aff(pma2)); +} + +bool pw_multi_aff::plain_is_equal(const isl::pw_aff &pma2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->plain_is_equal(isl::pw_multi_aff(pma2)); +} + +isl::pw_multi_aff pw_multi_aff::preimage_domain_wrapped_domain(isl::pw_multi_aff pma2) const +{ + if (!ptr || pma2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_multi_aff_preimage_domain_wrapped_domain_pw_multi_aff(copy(), pma2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_pw_multi_aff pw_multi_aff::preimage_domain_wrapped_domain(const isl::union_pw_multi_aff &upma2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_pw_multi_aff(*this).preimage_domain_wrapped_domain(upma2); +} + +isl::pw_multi_aff pw_multi_aff::preimage_domain_wrapped_domain(const isl::multi_aff &pma2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->preimage_domain_wrapped_domain(isl::pw_multi_aff(pma2)); +} + +isl::pw_multi_aff pw_multi_aff::preimage_domain_wrapped_domain(const isl::pw_aff &pma2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->preimage_domain_wrapped_domain(isl::pw_multi_aff(pma2)); +} + +isl::multi_pw_aff pw_multi_aff::product(const isl::multi_pw_aff &multi2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::multi_pw_aff(*this).product(multi2); +} + +isl::pw_multi_aff pw_multi_aff::product(isl::pw_multi_aff pma2) const +{ + if (!ptr || pma2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_multi_aff_product(copy(), pma2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::pw_multi_aff pw_multi_aff::product(const isl::multi_aff &pma2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->product(isl::pw_multi_aff(pma2)); +} + +isl::pw_multi_aff pw_multi_aff::product(const isl::pw_aff &pma2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->product(isl::pw_multi_aff(pma2)); +} + +isl::multi_pw_aff pw_multi_aff::pullback(const isl::multi_pw_aff &mpa2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::multi_pw_aff(*this).pullback(mpa2); +} + +isl::pw_multi_aff pw_multi_aff::pullback(isl::multi_aff ma) const +{ + if (!ptr || ma.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_multi_aff_pullback_multi_aff(copy(), ma.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::pw_multi_aff pw_multi_aff::pullback(isl::pw_multi_aff pma2) const +{ + if (!ptr || pma2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_multi_aff_pullback_pw_multi_aff(copy(), pma2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_pw_multi_aff pw_multi_aff::pullback(const isl::union_pw_multi_aff &upma2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_pw_multi_aff(*this).pullback(upma2); +} + +isl::pw_multi_aff_list pw_multi_aff::pw_multi_aff_list() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_pw_multi_aff(*this).pw_multi_aff_list(); +} + +isl::pw_multi_aff pw_multi_aff::range_factor_domain() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_multi_aff_range_factor_domain(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::pw_multi_aff pw_multi_aff::range_factor_range() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_multi_aff_range_factor_range(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::pw_multi_aff pw_multi_aff::range_map(isl::space space) +{ + if (space.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = space.ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_multi_aff_range_map(space.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_pw_aff pw_multi_aff::range_product(const isl::multi_pw_aff &multi2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::multi_pw_aff(*this).range_product(multi2); +} + +isl::multi_union_pw_aff pw_multi_aff::range_product(const isl::multi_union_pw_aff &multi2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::multi_pw_aff(*this).range_product(multi2); +} + +isl::pw_multi_aff pw_multi_aff::range_product(isl::pw_multi_aff pma2) const +{ + if (!ptr || pma2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_multi_aff_range_product(copy(), pma2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_pw_multi_aff pw_multi_aff::range_product(const isl::union_pw_multi_aff &upma2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_pw_multi_aff(*this).range_product(upma2); +} + +isl::pw_multi_aff pw_multi_aff::range_product(const isl::multi_aff &pma2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->range_product(isl::pw_multi_aff(pma2)); +} + +isl::pw_multi_aff pw_multi_aff::range_product(const isl::pw_aff &pma2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->range_product(isl::pw_multi_aff(pma2)); +} + +isl::id pw_multi_aff::range_tuple_id() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_multi_aff_get_range_tuple_id(get()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::id pw_multi_aff::get_range_tuple_id() const +{ + return range_tuple_id(); +} + +isl::multi_pw_aff pw_multi_aff::reset_range_tuple_id() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::multi_pw_aff(*this).reset_range_tuple_id(); +} + +isl::pw_multi_aff pw_multi_aff::scale(isl::multi_val mv) const +{ + if (!ptr || mv.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_multi_aff_scale_multi_val(copy(), mv.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::pw_multi_aff pw_multi_aff::scale(isl::val v) const +{ + if (!ptr || v.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_multi_aff_scale_val(copy(), v.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::pw_multi_aff pw_multi_aff::scale(long v) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->scale(isl::val(ctx(), v)); +} + +isl::pw_multi_aff pw_multi_aff::scale_down(isl::multi_val mv) const +{ + if (!ptr || mv.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_multi_aff_scale_down_multi_val(copy(), mv.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::pw_multi_aff pw_multi_aff::scale_down(isl::val v) const +{ + if (!ptr || v.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_multi_aff_scale_down_val(copy(), v.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::pw_multi_aff pw_multi_aff::scale_down(long v) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->scale_down(isl::val(ctx(), v)); +} + +isl::multi_pw_aff pw_multi_aff::set_at(int pos, const isl::pw_aff &el) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::multi_pw_aff(*this).set_at(pos, el); +} + +isl::multi_union_pw_aff pw_multi_aff::set_at(int pos, const isl::union_pw_aff &el) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::multi_pw_aff(*this).set_at(pos, el); +} + +isl::pw_multi_aff pw_multi_aff::set_range_tuple(isl::id id) const +{ + if (!ptr || id.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_multi_aff_set_range_tuple_id(copy(), id.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::pw_multi_aff pw_multi_aff::set_range_tuple(const std::string &id) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->set_range_tuple(isl::id(ctx(), id)); +} + +unsigned pw_multi_aff::size() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::multi_pw_aff(*this).size(); +} + +isl::space pw_multi_aff::space() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_multi_aff_get_space(get()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::space pw_multi_aff::get_space() const +{ + return space(); +} + +isl::multi_pw_aff pw_multi_aff::sub(const isl::multi_pw_aff &multi2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::multi_pw_aff(*this).sub(multi2); +} + +isl::multi_union_pw_aff pw_multi_aff::sub(const isl::multi_union_pw_aff &multi2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::multi_pw_aff(*this).sub(multi2); +} + +isl::pw_multi_aff pw_multi_aff::sub(isl::pw_multi_aff pma2) const +{ + if (!ptr || pma2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_multi_aff_sub(copy(), pma2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_pw_multi_aff pw_multi_aff::sub(const isl::union_pw_multi_aff &upma2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_pw_multi_aff(*this).sub(upma2); +} + +isl::pw_multi_aff pw_multi_aff::sub(const isl::multi_aff &pma2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->sub(isl::pw_multi_aff(pma2)); +} + +isl::pw_multi_aff pw_multi_aff::sub(const isl::pw_aff &pma2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->sub(isl::pw_multi_aff(pma2)); +} + +isl::pw_multi_aff pw_multi_aff::subtract_domain(isl::set set) const +{ + if (!ptr || set.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_multi_aff_subtract_domain(copy(), set.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_pw_multi_aff pw_multi_aff::subtract_domain(const isl::space &space) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_pw_multi_aff(*this).subtract_domain(space); +} + +isl::union_pw_multi_aff pw_multi_aff::subtract_domain(const isl::union_set &uset) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_pw_multi_aff(*this).subtract_domain(uset); +} + +isl::pw_multi_aff pw_multi_aff::subtract_domain(const isl::basic_set &set) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->subtract_domain(isl::set(set)); +} + +isl::pw_multi_aff pw_multi_aff::subtract_domain(const isl::point &set) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->subtract_domain(isl::set(set)); +} + +isl::pw_multi_aff_list pw_multi_aff::to_list() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_multi_aff_to_list(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_pw_aff pw_multi_aff::to_multi_pw_aff() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_multi_aff_to_multi_pw_aff(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_pw_multi_aff pw_multi_aff::to_union_pw_multi_aff() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_multi_aff_to_union_pw_multi_aff(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_pw_aff pw_multi_aff::unbind_params_insert_domain(const isl::multi_id &domain) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::multi_pw_aff(*this).unbind_params_insert_domain(domain); +} + +isl::multi_pw_aff pw_multi_aff::union_add(const isl::multi_pw_aff &mpa2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::multi_pw_aff(*this).union_add(mpa2); +} + +isl::multi_union_pw_aff pw_multi_aff::union_add(const isl::multi_union_pw_aff &mupa2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::multi_pw_aff(*this).union_add(mupa2); +} + +isl::pw_multi_aff pw_multi_aff::union_add(isl::pw_multi_aff pma2) const +{ + if (!ptr || pma2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_multi_aff_union_add(copy(), pma2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_pw_multi_aff pw_multi_aff::union_add(const isl::union_pw_multi_aff &upma2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_pw_multi_aff(*this).union_add(upma2); +} + +isl::pw_multi_aff pw_multi_aff::union_add(const isl::multi_aff &pma2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->union_add(isl::pw_multi_aff(pma2)); +} + +isl::pw_multi_aff pw_multi_aff::union_add(const isl::pw_aff &pma2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->union_add(isl::pw_multi_aff(pma2)); +} + +isl::pw_multi_aff pw_multi_aff::zero(isl::space space) +{ + if (space.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = space.ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_multi_aff_zero(space.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +inline std::ostream &operator<<(std::ostream &os, const pw_multi_aff &obj) +{ + if (!obj.get()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_pw_multi_aff_get_ctx(obj.get()); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + char *str = isl_pw_multi_aff_to_str(obj.get()); + if (!str) + exception::throw_last_error(saved_ctx); + os << str; + free(str); + return os; +} + +// implementations for isl::pw_multi_aff_list +pw_multi_aff_list manage(__isl_take isl_pw_multi_aff_list *ptr) { + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return pw_multi_aff_list(ptr); +} +pw_multi_aff_list manage_copy(__isl_keep isl_pw_multi_aff_list *ptr) { + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_pw_multi_aff_list_get_ctx(ptr); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + ptr = isl_pw_multi_aff_list_copy(ptr); + if (!ptr) + exception::throw_last_error(saved_ctx); + return pw_multi_aff_list(ptr); +} + +pw_multi_aff_list::pw_multi_aff_list(__isl_take isl_pw_multi_aff_list *ptr) + : ptr(ptr) {} + +pw_multi_aff_list::pw_multi_aff_list() + : ptr(nullptr) {} + +pw_multi_aff_list::pw_multi_aff_list(const pw_multi_aff_list &obj) + : ptr(nullptr) +{ + if (!obj.ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_pw_multi_aff_list_get_ctx(obj.ptr); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + ptr = obj.copy(); + if (!ptr) + exception::throw_last_error(saved_ctx); +} + +pw_multi_aff_list::pw_multi_aff_list(isl::ctx ctx, int n) +{ + auto saved_ctx = ctx; + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_multi_aff_list_alloc(ctx.release(), n); + if (!res) + exception::throw_last_error(saved_ctx); + ptr = res; +} + +pw_multi_aff_list::pw_multi_aff_list(isl::pw_multi_aff el) +{ + if (el.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = el.ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_multi_aff_list_from_pw_multi_aff(el.release()); + if (!res) + exception::throw_last_error(saved_ctx); + ptr = res; +} + +pw_multi_aff_list::pw_multi_aff_list(isl::ctx ctx, const std::string &str) +{ + auto saved_ctx = ctx; + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_multi_aff_list_read_from_str(ctx.release(), str.c_str()); + if (!res) + exception::throw_last_error(saved_ctx); + ptr = res; +} + +pw_multi_aff_list &pw_multi_aff_list::operator=(pw_multi_aff_list obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +pw_multi_aff_list::~pw_multi_aff_list() { + if (ptr) + isl_pw_multi_aff_list_free(ptr); +} + +__isl_give isl_pw_multi_aff_list *pw_multi_aff_list::copy() const & { + return isl_pw_multi_aff_list_copy(ptr); +} + +__isl_keep isl_pw_multi_aff_list *pw_multi_aff_list::get() const { + return ptr; +} + +__isl_give isl_pw_multi_aff_list *pw_multi_aff_list::release() { + isl_pw_multi_aff_list *tmp = ptr; + ptr = nullptr; + return tmp; +} + +bool pw_multi_aff_list::is_null() const { + return ptr == nullptr; +} + +isl::ctx pw_multi_aff_list::ctx() const { + return isl::ctx(isl_pw_multi_aff_list_get_ctx(ptr)); +} + +isl::pw_multi_aff_list pw_multi_aff_list::add(isl::pw_multi_aff el) const +{ + if (!ptr || el.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_multi_aff_list_add(copy(), el.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::pw_multi_aff pw_multi_aff_list::at(int index) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_multi_aff_list_get_at(get(), index); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::pw_multi_aff pw_multi_aff_list::get_at(int index) const +{ + return at(index); +} + +isl::pw_multi_aff_list pw_multi_aff_list::clear() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_multi_aff_list_clear(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::pw_multi_aff_list pw_multi_aff_list::concat(isl::pw_multi_aff_list list2) const +{ + if (!ptr || list2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_multi_aff_list_concat(copy(), list2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::pw_multi_aff_list pw_multi_aff_list::drop(unsigned int first, unsigned int n) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_multi_aff_list_drop(copy(), first, n); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +void pw_multi_aff_list::foreach(const std::function &fn) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + struct fn_data { + std::function func; + std::exception_ptr eptr; + } fn_data = { fn }; + auto fn_lambda = [](isl_pw_multi_aff *arg_0, void *arg_1) -> isl_stat { + auto *data = static_cast(arg_1); + ISL_CPP_TRY { + (data->func)(manage(arg_0)); + return isl_stat_ok; + } ISL_CPP_CATCH_ALL { + data->eptr = std::current_exception(); + return isl_stat_error; + } + }; + auto res = isl_pw_multi_aff_list_foreach(get(), fn_lambda, &fn_data); + if (fn_data.eptr) + std::rethrow_exception(fn_data.eptr); + if (res < 0) + exception::throw_last_error(saved_ctx); + return; +} + +void pw_multi_aff_list::foreach_scc(const std::function &follows, const std::function &fn) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + struct follows_data { + std::function func; + std::exception_ptr eptr; + } follows_data = { follows }; + auto follows_lambda = [](isl_pw_multi_aff *arg_0, isl_pw_multi_aff *arg_1, void *arg_2) -> isl_bool { + auto *data = static_cast(arg_2); + ISL_CPP_TRY { + auto ret = (data->func)(manage_copy(arg_0), manage_copy(arg_1)); + return ret ? isl_bool_true : isl_bool_false; + } ISL_CPP_CATCH_ALL { + data->eptr = std::current_exception(); + return isl_bool_error; + } + }; + struct fn_data { + std::function func; + std::exception_ptr eptr; + } fn_data = { fn }; + auto fn_lambda = [](isl_pw_multi_aff_list *arg_0, void *arg_1) -> isl_stat { + auto *data = static_cast(arg_1); + ISL_CPP_TRY { + (data->func)(manage(arg_0)); + return isl_stat_ok; + } ISL_CPP_CATCH_ALL { + data->eptr = std::current_exception(); + return isl_stat_error; + } + }; + auto res = isl_pw_multi_aff_list_foreach_scc(get(), follows_lambda, &follows_data, fn_lambda, &fn_data); + if (follows_data.eptr) + std::rethrow_exception(follows_data.eptr); + if (fn_data.eptr) + std::rethrow_exception(fn_data.eptr); + if (res < 0) + exception::throw_last_error(saved_ctx); + return; +} + +isl::pw_multi_aff_list pw_multi_aff_list::insert(unsigned int pos, isl::pw_multi_aff el) const +{ + if (!ptr || el.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_multi_aff_list_insert(copy(), pos, el.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::pw_multi_aff_list pw_multi_aff_list::set_at(int index, isl::pw_multi_aff el) const +{ + if (!ptr || el.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_multi_aff_list_set_at(copy(), index, el.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +unsigned pw_multi_aff_list::size() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_pw_multi_aff_list_size(get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +inline std::ostream &operator<<(std::ostream &os, const pw_multi_aff_list &obj) +{ + if (!obj.get()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_pw_multi_aff_list_get_ctx(obj.get()); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + char *str = isl_pw_multi_aff_list_to_str(obj.get()); + if (!str) + exception::throw_last_error(saved_ctx); + os << str; + free(str); + return os; +} + +// implementations for isl::schedule +schedule manage(__isl_take isl_schedule *ptr) { + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return schedule(ptr); +} +schedule manage_copy(__isl_keep isl_schedule *ptr) { + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_schedule_get_ctx(ptr); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + ptr = isl_schedule_copy(ptr); + if (!ptr) + exception::throw_last_error(saved_ctx); + return schedule(ptr); +} + +schedule::schedule(__isl_take isl_schedule *ptr) + : ptr(ptr) {} + +schedule::schedule() + : ptr(nullptr) {} + +schedule::schedule(const schedule &obj) + : ptr(nullptr) +{ + if (!obj.ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_schedule_get_ctx(obj.ptr); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + ptr = obj.copy(); + if (!ptr) + exception::throw_last_error(saved_ctx); +} + +schedule::schedule(isl::ctx ctx, const std::string &str) +{ + auto saved_ctx = ctx; + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_schedule_read_from_str(ctx.release(), str.c_str()); + if (!res) + exception::throw_last_error(saved_ctx); + ptr = res; +} + +schedule &schedule::operator=(schedule obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +schedule::~schedule() { + if (ptr) + isl_schedule_free(ptr); +} + +__isl_give isl_schedule *schedule::copy() const & { + return isl_schedule_copy(ptr); +} + +__isl_keep isl_schedule *schedule::get() const { + return ptr; +} + +__isl_give isl_schedule *schedule::release() { + isl_schedule *tmp = ptr; + ptr = nullptr; + return tmp; +} + +bool schedule::is_null() const { + return ptr == nullptr; +} + +isl::ctx schedule::ctx() const { + return isl::ctx(isl_schedule_get_ctx(ptr)); +} + +isl::union_set schedule::domain() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_schedule_get_domain(get()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_set schedule::get_domain() const +{ + return domain(); +} + +isl::schedule schedule::from_domain(isl::union_set domain) +{ + if (domain.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = domain.ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_schedule_from_domain(domain.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map schedule::map() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_schedule_get_map(get()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map schedule::get_map() const +{ + return map(); +} + +isl::schedule schedule::pullback(isl::union_pw_multi_aff upma) const +{ + if (!ptr || upma.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_schedule_pullback_union_pw_multi_aff(copy(), upma.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::schedule_node schedule::root() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_schedule_get_root(get()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::schedule_node schedule::get_root() const +{ + return root(); +} + +inline std::ostream &operator<<(std::ostream &os, const schedule &obj) +{ + if (!obj.get()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_schedule_get_ctx(obj.get()); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + char *str = isl_schedule_to_str(obj.get()); + if (!str) + exception::throw_last_error(saved_ctx); + os << str; + free(str); + return os; +} + +// implementations for isl::schedule_constraints +schedule_constraints manage(__isl_take isl_schedule_constraints *ptr) { + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return schedule_constraints(ptr); +} +schedule_constraints manage_copy(__isl_keep isl_schedule_constraints *ptr) { + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_schedule_constraints_get_ctx(ptr); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + ptr = isl_schedule_constraints_copy(ptr); + if (!ptr) + exception::throw_last_error(saved_ctx); + return schedule_constraints(ptr); +} + +schedule_constraints::schedule_constraints(__isl_take isl_schedule_constraints *ptr) + : ptr(ptr) {} + +schedule_constraints::schedule_constraints() + : ptr(nullptr) {} + +schedule_constraints::schedule_constraints(const schedule_constraints &obj) + : ptr(nullptr) +{ + if (!obj.ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_schedule_constraints_get_ctx(obj.ptr); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + ptr = obj.copy(); + if (!ptr) + exception::throw_last_error(saved_ctx); +} + +schedule_constraints::schedule_constraints(isl::ctx ctx, const std::string &str) +{ + auto saved_ctx = ctx; + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_schedule_constraints_read_from_str(ctx.release(), str.c_str()); + if (!res) + exception::throw_last_error(saved_ctx); + ptr = res; +} + +schedule_constraints &schedule_constraints::operator=(schedule_constraints obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +schedule_constraints::~schedule_constraints() { + if (ptr) + isl_schedule_constraints_free(ptr); +} + +__isl_give isl_schedule_constraints *schedule_constraints::copy() const & { + return isl_schedule_constraints_copy(ptr); +} + +__isl_keep isl_schedule_constraints *schedule_constraints::get() const { + return ptr; +} + +__isl_give isl_schedule_constraints *schedule_constraints::release() { + isl_schedule_constraints *tmp = ptr; + ptr = nullptr; + return tmp; +} + +bool schedule_constraints::is_null() const { + return ptr == nullptr; +} + +isl::ctx schedule_constraints::ctx() const { + return isl::ctx(isl_schedule_constraints_get_ctx(ptr)); +} + +isl::union_map schedule_constraints::coincidence() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_schedule_constraints_get_coincidence(get()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map schedule_constraints::get_coincidence() const +{ + return coincidence(); +} + +isl::schedule schedule_constraints::compute_schedule() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_schedule_constraints_compute_schedule(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map schedule_constraints::conditional_validity() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_schedule_constraints_get_conditional_validity(get()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map schedule_constraints::get_conditional_validity() const +{ + return conditional_validity(); +} + +isl::union_map schedule_constraints::conditional_validity_condition() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_schedule_constraints_get_conditional_validity_condition(get()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map schedule_constraints::get_conditional_validity_condition() const +{ + return conditional_validity_condition(); +} + +isl::set schedule_constraints::context() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_schedule_constraints_get_context(get()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::set schedule_constraints::get_context() const +{ + return context(); +} + +isl::union_set schedule_constraints::domain() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_schedule_constraints_get_domain(get()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_set schedule_constraints::get_domain() const +{ + return domain(); +} + +isl::schedule_constraints schedule_constraints::on_domain(isl::union_set domain) +{ + if (domain.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = domain.ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_schedule_constraints_on_domain(domain.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map schedule_constraints::proximity() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_schedule_constraints_get_proximity(get()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map schedule_constraints::get_proximity() const +{ + return proximity(); +} + +isl::schedule_constraints schedule_constraints::set_coincidence(isl::union_map coincidence) const +{ + if (!ptr || coincidence.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_schedule_constraints_set_coincidence(copy(), coincidence.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::schedule_constraints schedule_constraints::set_conditional_validity(isl::union_map condition, isl::union_map validity) const +{ + if (!ptr || condition.is_null() || validity.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_schedule_constraints_set_conditional_validity(copy(), condition.release(), validity.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::schedule_constraints schedule_constraints::set_context(isl::set context) const +{ + if (!ptr || context.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_schedule_constraints_set_context(copy(), context.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::schedule_constraints schedule_constraints::set_proximity(isl::union_map proximity) const +{ + if (!ptr || proximity.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_schedule_constraints_set_proximity(copy(), proximity.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::schedule_constraints schedule_constraints::set_validity(isl::union_map validity) const +{ + if (!ptr || validity.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_schedule_constraints_set_validity(copy(), validity.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map schedule_constraints::validity() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_schedule_constraints_get_validity(get()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map schedule_constraints::get_validity() const +{ + return validity(); +} + +inline std::ostream &operator<<(std::ostream &os, const schedule_constraints &obj) +{ + if (!obj.get()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_schedule_constraints_get_ctx(obj.get()); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + char *str = isl_schedule_constraints_to_str(obj.get()); + if (!str) + exception::throw_last_error(saved_ctx); + os << str; + free(str); + return os; +} + +// implementations for isl::schedule_node +schedule_node manage(__isl_take isl_schedule_node *ptr) { + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return schedule_node(ptr); +} +schedule_node manage_copy(__isl_keep isl_schedule_node *ptr) { + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_schedule_node_get_ctx(ptr); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + ptr = isl_schedule_node_copy(ptr); + if (!ptr) + exception::throw_last_error(saved_ctx); + return schedule_node(ptr); +} + +schedule_node::schedule_node(__isl_take isl_schedule_node *ptr) + : ptr(ptr) {} + +schedule_node::schedule_node() + : ptr(nullptr) {} + +schedule_node::schedule_node(const schedule_node &obj) + : ptr(nullptr) +{ + if (!obj.ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_schedule_node_get_ctx(obj.ptr); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + ptr = obj.copy(); + if (!ptr) + exception::throw_last_error(saved_ctx); +} + +schedule_node &schedule_node::operator=(schedule_node obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +schedule_node::~schedule_node() { + if (ptr) + isl_schedule_node_free(ptr); +} + +__isl_give isl_schedule_node *schedule_node::copy() const & { + return isl_schedule_node_copy(ptr); +} + +__isl_keep isl_schedule_node *schedule_node::get() const { + return ptr; +} + +__isl_give isl_schedule_node *schedule_node::release() { + isl_schedule_node *tmp = ptr; + ptr = nullptr; + return tmp; +} + +bool schedule_node::is_null() const { + return ptr == nullptr; +} + +template +bool schedule_node::isa_type(T subtype) const +{ + if (is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl_schedule_node_get_type(get()) == subtype; +} +template +bool schedule_node::isa() const +{ + return isa_type(T::type); +} +template +T schedule_node::as() const +{ + if (!isa()) + exception::throw_invalid("not an object of the requested subtype", __FILE__, __LINE__); + return T(copy()); +} + +isl::ctx schedule_node::ctx() const { + return isl::ctx(isl_schedule_node_get_ctx(ptr)); +} + +isl::schedule_node schedule_node::ancestor(int generation) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_schedule_node_ancestor(copy(), generation); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +unsigned schedule_node::ancestor_child_position(const isl::schedule_node &ancestor) const +{ + if (!ptr || ancestor.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_schedule_node_get_ancestor_child_position(get(), ancestor.get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +unsigned schedule_node::get_ancestor_child_position(const isl::schedule_node &ancestor) const +{ + return ancestor_child_position(ancestor); +} + +isl::schedule_node schedule_node::child(int pos) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_schedule_node_child(copy(), pos); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +unsigned schedule_node::child_position() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_schedule_node_get_child_position(get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +unsigned schedule_node::get_child_position() const +{ + return child_position(); +} + +bool schedule_node::every_descendant(const std::function &test) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + struct test_data { + std::function func; + std::exception_ptr eptr; + } test_data = { test }; + auto test_lambda = [](isl_schedule_node *arg_0, void *arg_1) -> isl_bool { + auto *data = static_cast(arg_1); + ISL_CPP_TRY { + auto ret = (data->func)(manage_copy(arg_0)); + return ret ? isl_bool_true : isl_bool_false; + } ISL_CPP_CATCH_ALL { + data->eptr = std::current_exception(); + return isl_bool_error; + } + }; + auto res = isl_schedule_node_every_descendant(get(), test_lambda, &test_data); + if (test_data.eptr) + std::rethrow_exception(test_data.eptr); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +isl::schedule_node schedule_node::first_child() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_schedule_node_first_child(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +void schedule_node::foreach_ancestor_top_down(const std::function &fn) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + struct fn_data { + std::function func; + std::exception_ptr eptr; + } fn_data = { fn }; + auto fn_lambda = [](isl_schedule_node *arg_0, void *arg_1) -> isl_stat { + auto *data = static_cast(arg_1); + ISL_CPP_TRY { + (data->func)(manage_copy(arg_0)); + return isl_stat_ok; + } ISL_CPP_CATCH_ALL { + data->eptr = std::current_exception(); + return isl_stat_error; + } + }; + auto res = isl_schedule_node_foreach_ancestor_top_down(get(), fn_lambda, &fn_data); + if (fn_data.eptr) + std::rethrow_exception(fn_data.eptr); + if (res < 0) + exception::throw_last_error(saved_ctx); + return; +} + +void schedule_node::foreach_descendant_top_down(const std::function &fn) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + struct fn_data { + std::function func; + std::exception_ptr eptr; + } fn_data = { fn }; + auto fn_lambda = [](isl_schedule_node *arg_0, void *arg_1) -> isl_bool { + auto *data = static_cast(arg_1); + ISL_CPP_TRY { + auto ret = (data->func)(manage_copy(arg_0)); + return ret ? isl_bool_true : isl_bool_false; + } ISL_CPP_CATCH_ALL { + data->eptr = std::current_exception(); + return isl_bool_error; + } + }; + auto res = isl_schedule_node_foreach_descendant_top_down(get(), fn_lambda, &fn_data); + if (fn_data.eptr) + std::rethrow_exception(fn_data.eptr); + if (res < 0) + exception::throw_last_error(saved_ctx); + return; +} + +isl::schedule_node schedule_node::from_domain(isl::union_set domain) +{ + if (domain.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = domain.ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_schedule_node_from_domain(domain.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::schedule_node schedule_node::from_extension(isl::union_map extension) +{ + if (extension.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = extension.ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_schedule_node_from_extension(extension.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::schedule_node schedule_node::graft_after(isl::schedule_node graft) const +{ + if (!ptr || graft.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_schedule_node_graft_after(copy(), graft.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::schedule_node schedule_node::graft_before(isl::schedule_node graft) const +{ + if (!ptr || graft.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_schedule_node_graft_before(copy(), graft.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +bool schedule_node::has_children() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_schedule_node_has_children(get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +bool schedule_node::has_next_sibling() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_schedule_node_has_next_sibling(get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +bool schedule_node::has_parent() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_schedule_node_has_parent(get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +bool schedule_node::has_previous_sibling() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_schedule_node_has_previous_sibling(get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +isl::schedule_node schedule_node::insert_context(isl::set context) const +{ + if (!ptr || context.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_schedule_node_insert_context(copy(), context.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::schedule_node schedule_node::insert_filter(isl::union_set filter) const +{ + if (!ptr || filter.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_schedule_node_insert_filter(copy(), filter.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::schedule_node schedule_node::insert_guard(isl::set context) const +{ + if (!ptr || context.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_schedule_node_insert_guard(copy(), context.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::schedule_node schedule_node::insert_mark(isl::id mark) const +{ + if (!ptr || mark.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_schedule_node_insert_mark(copy(), mark.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::schedule_node schedule_node::insert_mark(const std::string &mark) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->insert_mark(isl::id(ctx(), mark)); +} + +isl::schedule_node schedule_node::insert_partial_schedule(isl::multi_union_pw_aff schedule) const +{ + if (!ptr || schedule.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_schedule_node_insert_partial_schedule(copy(), schedule.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::schedule_node schedule_node::insert_sequence(isl::union_set_list filters) const +{ + if (!ptr || filters.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_schedule_node_insert_sequence(copy(), filters.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::schedule_node schedule_node::insert_set(isl::union_set_list filters) const +{ + if (!ptr || filters.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_schedule_node_insert_set(copy(), filters.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +bool schedule_node::is_equal(const isl::schedule_node &node2) const +{ + if (!ptr || node2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_schedule_node_is_equal(get(), node2.get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +bool schedule_node::is_subtree_anchored() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_schedule_node_is_subtree_anchored(get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +isl::schedule_node schedule_node::map_descendant_bottom_up(const std::function &fn) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + struct fn_data { + std::function func; + std::exception_ptr eptr; + } fn_data = { fn }; + auto fn_lambda = [](isl_schedule_node *arg_0, void *arg_1) -> isl_schedule_node * { + auto *data = static_cast(arg_1); + ISL_CPP_TRY { + auto ret = (data->func)(manage(arg_0)); + return ret.release(); + } ISL_CPP_CATCH_ALL { + data->eptr = std::current_exception(); + return NULL; + } + }; + auto res = isl_schedule_node_map_descendant_bottom_up(copy(), fn_lambda, &fn_data); + if (fn_data.eptr) + std::rethrow_exception(fn_data.eptr); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +unsigned schedule_node::n_children() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_schedule_node_n_children(get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +isl::schedule_node schedule_node::next_sibling() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_schedule_node_next_sibling(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::schedule_node schedule_node::order_after(isl::union_set filter) const +{ + if (!ptr || filter.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_schedule_node_order_after(copy(), filter.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::schedule_node schedule_node::order_before(isl::union_set filter) const +{ + if (!ptr || filter.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_schedule_node_order_before(copy(), filter.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::schedule_node schedule_node::parent() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_schedule_node_parent(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_union_pw_aff schedule_node::prefix_schedule_multi_union_pw_aff() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_schedule_node_get_prefix_schedule_multi_union_pw_aff(get()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_union_pw_aff schedule_node::get_prefix_schedule_multi_union_pw_aff() const +{ + return prefix_schedule_multi_union_pw_aff(); +} + +isl::union_map schedule_node::prefix_schedule_union_map() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_schedule_node_get_prefix_schedule_union_map(get()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map schedule_node::get_prefix_schedule_union_map() const +{ + return prefix_schedule_union_map(); +} + +isl::union_pw_multi_aff schedule_node::prefix_schedule_union_pw_multi_aff() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_schedule_node_get_prefix_schedule_union_pw_multi_aff(get()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_pw_multi_aff schedule_node::get_prefix_schedule_union_pw_multi_aff() const +{ + return prefix_schedule_union_pw_multi_aff(); +} + +isl::schedule_node schedule_node::previous_sibling() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_schedule_node_previous_sibling(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::schedule_node schedule_node::root() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_schedule_node_root(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::schedule schedule_node::schedule() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_schedule_node_get_schedule(get()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::schedule schedule_node::get_schedule() const +{ + return schedule(); +} + +isl::schedule_node schedule_node::shared_ancestor(const isl::schedule_node &node2) const +{ + if (!ptr || node2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_schedule_node_get_shared_ancestor(get(), node2.get()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::schedule_node schedule_node::get_shared_ancestor(const isl::schedule_node &node2) const +{ + return shared_ancestor(node2); +} + +unsigned schedule_node::tree_depth() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_schedule_node_get_tree_depth(get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +unsigned schedule_node::get_tree_depth() const +{ + return tree_depth(); +} + +inline std::ostream &operator<<(std::ostream &os, const schedule_node &obj) +{ + if (!obj.get()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_schedule_node_get_ctx(obj.get()); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + char *str = isl_schedule_node_to_str(obj.get()); + if (!str) + exception::throw_last_error(saved_ctx); + os << str; + free(str); + return os; +} + +// implementations for isl::schedule_node_band +schedule_node_band::schedule_node_band(__isl_take isl_schedule_node *ptr) + : schedule_node(ptr) {} + +schedule_node_band::schedule_node_band() + : schedule_node() {} + +schedule_node_band::schedule_node_band(const schedule_node_band &obj) + : schedule_node(obj) +{ +} + +schedule_node_band &schedule_node_band::operator=(schedule_node_band obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +isl::ctx schedule_node_band::ctx() const { + return isl::ctx(isl_schedule_node_get_ctx(ptr)); +} + +isl::union_set schedule_node_band::ast_build_options() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_schedule_node_band_get_ast_build_options(get()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_set schedule_node_band::get_ast_build_options() const +{ + return ast_build_options(); +} + +isl::set schedule_node_band::ast_isolate_option() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_schedule_node_band_get_ast_isolate_option(get()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::set schedule_node_band::get_ast_isolate_option() const +{ + return ast_isolate_option(); +} + +bool schedule_node_band::member_get_coincident(int pos) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_schedule_node_band_member_get_coincident(get(), pos); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +schedule_node_band schedule_node_band::member_set_coincident(int pos, int coincident) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_schedule_node_band_member_set_coincident(copy(), pos, coincident); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res).as(); +} + +schedule_node_band schedule_node_band::mod(isl::multi_val mv) const +{ + if (!ptr || mv.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_schedule_node_band_mod(copy(), mv.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res).as(); +} + +unsigned schedule_node_band::n_member() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_schedule_node_band_n_member(get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +isl::multi_union_pw_aff schedule_node_band::partial_schedule() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_schedule_node_band_get_partial_schedule(get()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_union_pw_aff schedule_node_band::get_partial_schedule() const +{ + return partial_schedule(); +} + +bool schedule_node_band::permutable() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_schedule_node_band_get_permutable(get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +bool schedule_node_band::get_permutable() const +{ + return permutable(); +} + +schedule_node_band schedule_node_band::scale(isl::multi_val mv) const +{ + if (!ptr || mv.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_schedule_node_band_scale(copy(), mv.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res).as(); +} + +schedule_node_band schedule_node_band::scale_down(isl::multi_val mv) const +{ + if (!ptr || mv.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_schedule_node_band_scale_down(copy(), mv.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res).as(); +} + +schedule_node_band schedule_node_band::set_ast_build_options(isl::union_set options) const +{ + if (!ptr || options.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_schedule_node_band_set_ast_build_options(copy(), options.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res).as(); +} + +schedule_node_band schedule_node_band::set_permutable(int permutable) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_schedule_node_band_set_permutable(copy(), permutable); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res).as(); +} + +schedule_node_band schedule_node_band::shift(isl::multi_union_pw_aff shift) const +{ + if (!ptr || shift.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_schedule_node_band_shift(copy(), shift.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res).as(); +} + +schedule_node_band schedule_node_band::split(int pos) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_schedule_node_band_split(copy(), pos); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res).as(); +} + +schedule_node_band schedule_node_band::tile(isl::multi_val sizes) const +{ + if (!ptr || sizes.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_schedule_node_band_tile(copy(), sizes.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res).as(); +} + +schedule_node_band schedule_node_band::member_set_ast_loop_default(int pos) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_schedule_node_band_member_set_ast_loop_type(copy(), pos, isl_ast_loop_default); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res).as(); +} + +schedule_node_band schedule_node_band::member_set_ast_loop_atomic(int pos) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_schedule_node_band_member_set_ast_loop_type(copy(), pos, isl_ast_loop_atomic); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res).as(); +} + +schedule_node_band schedule_node_band::member_set_ast_loop_unroll(int pos) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_schedule_node_band_member_set_ast_loop_type(copy(), pos, isl_ast_loop_unroll); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res).as(); +} + +schedule_node_band schedule_node_band::member_set_ast_loop_separate(int pos) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_schedule_node_band_member_set_ast_loop_type(copy(), pos, isl_ast_loop_separate); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res).as(); +} + +inline std::ostream &operator<<(std::ostream &os, const schedule_node_band &obj) +{ + if (!obj.get()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_schedule_node_get_ctx(obj.get()); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + char *str = isl_schedule_node_to_str(obj.get()); + if (!str) + exception::throw_last_error(saved_ctx); + os << str; + free(str); + return os; +} + +// implementations for isl::schedule_node_context +schedule_node_context::schedule_node_context(__isl_take isl_schedule_node *ptr) + : schedule_node(ptr) {} + +schedule_node_context::schedule_node_context() + : schedule_node() {} + +schedule_node_context::schedule_node_context(const schedule_node_context &obj) + : schedule_node(obj) +{ +} + +schedule_node_context &schedule_node_context::operator=(schedule_node_context obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +isl::ctx schedule_node_context::ctx() const { + return isl::ctx(isl_schedule_node_get_ctx(ptr)); +} + +isl::set schedule_node_context::context() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_schedule_node_context_get_context(get()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::set schedule_node_context::get_context() const +{ + return context(); +} + +inline std::ostream &operator<<(std::ostream &os, const schedule_node_context &obj) +{ + if (!obj.get()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_schedule_node_get_ctx(obj.get()); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + char *str = isl_schedule_node_to_str(obj.get()); + if (!str) + exception::throw_last_error(saved_ctx); + os << str; + free(str); + return os; +} + +// implementations for isl::schedule_node_domain +schedule_node_domain::schedule_node_domain(__isl_take isl_schedule_node *ptr) + : schedule_node(ptr) {} + +schedule_node_domain::schedule_node_domain() + : schedule_node() {} + +schedule_node_domain::schedule_node_domain(const schedule_node_domain &obj) + : schedule_node(obj) +{ +} + +schedule_node_domain &schedule_node_domain::operator=(schedule_node_domain obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +isl::ctx schedule_node_domain::ctx() const { + return isl::ctx(isl_schedule_node_get_ctx(ptr)); +} + +isl::union_set schedule_node_domain::domain() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_schedule_node_domain_get_domain(get()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_set schedule_node_domain::get_domain() const +{ + return domain(); +} + +inline std::ostream &operator<<(std::ostream &os, const schedule_node_domain &obj) +{ + if (!obj.get()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_schedule_node_get_ctx(obj.get()); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + char *str = isl_schedule_node_to_str(obj.get()); + if (!str) + exception::throw_last_error(saved_ctx); + os << str; + free(str); + return os; +} + +// implementations for isl::schedule_node_expansion +schedule_node_expansion::schedule_node_expansion(__isl_take isl_schedule_node *ptr) + : schedule_node(ptr) {} + +schedule_node_expansion::schedule_node_expansion() + : schedule_node() {} + +schedule_node_expansion::schedule_node_expansion(const schedule_node_expansion &obj) + : schedule_node(obj) +{ +} + +schedule_node_expansion &schedule_node_expansion::operator=(schedule_node_expansion obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +isl::ctx schedule_node_expansion::ctx() const { + return isl::ctx(isl_schedule_node_get_ctx(ptr)); +} + +isl::union_pw_multi_aff schedule_node_expansion::contraction() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_schedule_node_expansion_get_contraction(get()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_pw_multi_aff schedule_node_expansion::get_contraction() const +{ + return contraction(); +} + +isl::union_map schedule_node_expansion::expansion() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_schedule_node_expansion_get_expansion(get()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map schedule_node_expansion::get_expansion() const +{ + return expansion(); +} + +inline std::ostream &operator<<(std::ostream &os, const schedule_node_expansion &obj) +{ + if (!obj.get()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_schedule_node_get_ctx(obj.get()); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + char *str = isl_schedule_node_to_str(obj.get()); + if (!str) + exception::throw_last_error(saved_ctx); + os << str; + free(str); + return os; +} + +// implementations for isl::schedule_node_extension +schedule_node_extension::schedule_node_extension(__isl_take isl_schedule_node *ptr) + : schedule_node(ptr) {} + +schedule_node_extension::schedule_node_extension() + : schedule_node() {} + +schedule_node_extension::schedule_node_extension(const schedule_node_extension &obj) + : schedule_node(obj) +{ +} + +schedule_node_extension &schedule_node_extension::operator=(schedule_node_extension obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +isl::ctx schedule_node_extension::ctx() const { + return isl::ctx(isl_schedule_node_get_ctx(ptr)); +} + +isl::union_map schedule_node_extension::extension() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_schedule_node_extension_get_extension(get()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map schedule_node_extension::get_extension() const +{ + return extension(); +} + +inline std::ostream &operator<<(std::ostream &os, const schedule_node_extension &obj) +{ + if (!obj.get()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_schedule_node_get_ctx(obj.get()); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + char *str = isl_schedule_node_to_str(obj.get()); + if (!str) + exception::throw_last_error(saved_ctx); + os << str; + free(str); + return os; +} + +// implementations for isl::schedule_node_filter +schedule_node_filter::schedule_node_filter(__isl_take isl_schedule_node *ptr) + : schedule_node(ptr) {} + +schedule_node_filter::schedule_node_filter() + : schedule_node() {} + +schedule_node_filter::schedule_node_filter(const schedule_node_filter &obj) + : schedule_node(obj) +{ +} + +schedule_node_filter &schedule_node_filter::operator=(schedule_node_filter obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +isl::ctx schedule_node_filter::ctx() const { + return isl::ctx(isl_schedule_node_get_ctx(ptr)); +} + +isl::union_set schedule_node_filter::filter() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_schedule_node_filter_get_filter(get()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_set schedule_node_filter::get_filter() const +{ + return filter(); +} + +inline std::ostream &operator<<(std::ostream &os, const schedule_node_filter &obj) +{ + if (!obj.get()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_schedule_node_get_ctx(obj.get()); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + char *str = isl_schedule_node_to_str(obj.get()); + if (!str) + exception::throw_last_error(saved_ctx); + os << str; + free(str); + return os; +} + +// implementations for isl::schedule_node_guard +schedule_node_guard::schedule_node_guard(__isl_take isl_schedule_node *ptr) + : schedule_node(ptr) {} + +schedule_node_guard::schedule_node_guard() + : schedule_node() {} + +schedule_node_guard::schedule_node_guard(const schedule_node_guard &obj) + : schedule_node(obj) +{ +} + +schedule_node_guard &schedule_node_guard::operator=(schedule_node_guard obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +isl::ctx schedule_node_guard::ctx() const { + return isl::ctx(isl_schedule_node_get_ctx(ptr)); +} + +isl::set schedule_node_guard::guard() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_schedule_node_guard_get_guard(get()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::set schedule_node_guard::get_guard() const +{ + return guard(); +} + +inline std::ostream &operator<<(std::ostream &os, const schedule_node_guard &obj) +{ + if (!obj.get()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_schedule_node_get_ctx(obj.get()); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + char *str = isl_schedule_node_to_str(obj.get()); + if (!str) + exception::throw_last_error(saved_ctx); + os << str; + free(str); + return os; +} + +// implementations for isl::schedule_node_leaf +schedule_node_leaf::schedule_node_leaf(__isl_take isl_schedule_node *ptr) + : schedule_node(ptr) {} + +schedule_node_leaf::schedule_node_leaf() + : schedule_node() {} + +schedule_node_leaf::schedule_node_leaf(const schedule_node_leaf &obj) + : schedule_node(obj) +{ +} + +schedule_node_leaf &schedule_node_leaf::operator=(schedule_node_leaf obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +isl::ctx schedule_node_leaf::ctx() const { + return isl::ctx(isl_schedule_node_get_ctx(ptr)); +} + +inline std::ostream &operator<<(std::ostream &os, const schedule_node_leaf &obj) +{ + if (!obj.get()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_schedule_node_get_ctx(obj.get()); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + char *str = isl_schedule_node_to_str(obj.get()); + if (!str) + exception::throw_last_error(saved_ctx); + os << str; + free(str); + return os; +} + +// implementations for isl::schedule_node_mark +schedule_node_mark::schedule_node_mark(__isl_take isl_schedule_node *ptr) + : schedule_node(ptr) {} + +schedule_node_mark::schedule_node_mark() + : schedule_node() {} + +schedule_node_mark::schedule_node_mark(const schedule_node_mark &obj) + : schedule_node(obj) +{ +} + +schedule_node_mark &schedule_node_mark::operator=(schedule_node_mark obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +isl::ctx schedule_node_mark::ctx() const { + return isl::ctx(isl_schedule_node_get_ctx(ptr)); +} + +inline std::ostream &operator<<(std::ostream &os, const schedule_node_mark &obj) +{ + if (!obj.get()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_schedule_node_get_ctx(obj.get()); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + char *str = isl_schedule_node_to_str(obj.get()); + if (!str) + exception::throw_last_error(saved_ctx); + os << str; + free(str); + return os; +} + +// implementations for isl::schedule_node_sequence +schedule_node_sequence::schedule_node_sequence(__isl_take isl_schedule_node *ptr) + : schedule_node(ptr) {} + +schedule_node_sequence::schedule_node_sequence() + : schedule_node() {} + +schedule_node_sequence::schedule_node_sequence(const schedule_node_sequence &obj) + : schedule_node(obj) +{ +} + +schedule_node_sequence &schedule_node_sequence::operator=(schedule_node_sequence obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +isl::ctx schedule_node_sequence::ctx() const { + return isl::ctx(isl_schedule_node_get_ctx(ptr)); +} + +inline std::ostream &operator<<(std::ostream &os, const schedule_node_sequence &obj) +{ + if (!obj.get()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_schedule_node_get_ctx(obj.get()); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + char *str = isl_schedule_node_to_str(obj.get()); + if (!str) + exception::throw_last_error(saved_ctx); + os << str; + free(str); + return os; +} + +// implementations for isl::schedule_node_set +schedule_node_set::schedule_node_set(__isl_take isl_schedule_node *ptr) + : schedule_node(ptr) {} + +schedule_node_set::schedule_node_set() + : schedule_node() {} + +schedule_node_set::schedule_node_set(const schedule_node_set &obj) + : schedule_node(obj) +{ +} + +schedule_node_set &schedule_node_set::operator=(schedule_node_set obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +isl::ctx schedule_node_set::ctx() const { + return isl::ctx(isl_schedule_node_get_ctx(ptr)); +} + +inline std::ostream &operator<<(std::ostream &os, const schedule_node_set &obj) +{ + if (!obj.get()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_schedule_node_get_ctx(obj.get()); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + char *str = isl_schedule_node_to_str(obj.get()); + if (!str) + exception::throw_last_error(saved_ctx); + os << str; + free(str); + return os; +} + +// implementations for isl::set +set manage(__isl_take isl_set *ptr) { + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return set(ptr); +} +set manage_copy(__isl_keep isl_set *ptr) { + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_set_get_ctx(ptr); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + ptr = isl_set_copy(ptr); + if (!ptr) + exception::throw_last_error(saved_ctx); + return set(ptr); +} + +set::set(__isl_take isl_set *ptr) + : ptr(ptr) {} + +set::set() + : ptr(nullptr) {} + +set::set(const set &obj) + : ptr(nullptr) +{ + if (!obj.ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_set_get_ctx(obj.ptr); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + ptr = obj.copy(); + if (!ptr) + exception::throw_last_error(saved_ctx); +} + +set::set(isl::basic_set bset) +{ + if (bset.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = bset.ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_set_from_basic_set(bset.release()); + if (!res) + exception::throw_last_error(saved_ctx); + ptr = res; +} + +set::set(isl::point pnt) +{ + if (pnt.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = pnt.ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_set_from_point(pnt.release()); + if (!res) + exception::throw_last_error(saved_ctx); + ptr = res; +} + +set::set(isl::ctx ctx, const std::string &str) +{ + auto saved_ctx = ctx; + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_set_read_from_str(ctx.release(), str.c_str()); + if (!res) + exception::throw_last_error(saved_ctx); + ptr = res; +} + +set &set::operator=(set obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +set::~set() { + if (ptr) + isl_set_free(ptr); +} + +__isl_give isl_set *set::copy() const & { + return isl_set_copy(ptr); +} + +__isl_keep isl_set *set::get() const { + return ptr; +} + +__isl_give isl_set *set::release() { + isl_set *tmp = ptr; + ptr = nullptr; + return tmp; +} + +bool set::is_null() const { + return ptr == nullptr; +} + +isl::ctx set::ctx() const { + return isl::ctx(isl_set_get_ctx(ptr)); +} + +isl::basic_set set::affine_hull() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_set_affine_hull(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::set set::apply(isl::map map) const +{ + if (!ptr || map.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_set_apply(copy(), map.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_set set::apply(const isl::union_map &umap) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_set(*this).apply(umap); +} + +isl::set set::apply(const isl::basic_map &map) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->apply(isl::map(map)); +} + +isl::pw_multi_aff set::as_pw_multi_aff() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_set_as_pw_multi_aff(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::set set::as_set() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_set(*this).as_set(); +} + +isl::set set::bind(isl::multi_id tuple) const +{ + if (!ptr || tuple.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_set_bind(copy(), tuple.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::set set::coalesce() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_set_coalesce(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::set set::complement() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_set_complement(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_set set::compute_divs() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_set(*this).compute_divs(); +} + +isl::set set::detect_equalities() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_set_detect_equalities(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::val set::dim_max_val(int pos) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_set_dim_max_val(copy(), pos); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::val set::dim_min_val(int pos) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_set_dim_min_val(copy(), pos); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::set set::drop_unused_params() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_set_drop_unused_params(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::set set::empty(isl::space space) +{ + if (space.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = space.ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_set_empty(space.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +bool set::every_set(const std::function &test) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_set(*this).every_set(test); +} + +isl::set set::extract_set(const isl::space &space) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_set(*this).extract_set(space); +} + +isl::set set::flatten() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_set_flatten(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +void set::foreach_basic_set(const std::function &fn) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + struct fn_data { + std::function func; + std::exception_ptr eptr; + } fn_data = { fn }; + auto fn_lambda = [](isl_basic_set *arg_0, void *arg_1) -> isl_stat { + auto *data = static_cast(arg_1); + ISL_CPP_TRY { + (data->func)(manage(arg_0)); + return isl_stat_ok; + } ISL_CPP_CATCH_ALL { + data->eptr = std::current_exception(); + return isl_stat_error; + } + }; + auto res = isl_set_foreach_basic_set(get(), fn_lambda, &fn_data); + if (fn_data.eptr) + std::rethrow_exception(fn_data.eptr); + if (res < 0) + exception::throw_last_error(saved_ctx); + return; +} + +void set::foreach_point(const std::function &fn) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + struct fn_data { + std::function func; + std::exception_ptr eptr; + } fn_data = { fn }; + auto fn_lambda = [](isl_point *arg_0, void *arg_1) -> isl_stat { + auto *data = static_cast(arg_1); + ISL_CPP_TRY { + (data->func)(manage(arg_0)); + return isl_stat_ok; + } ISL_CPP_CATCH_ALL { + data->eptr = std::current_exception(); + return isl_stat_error; + } + }; + auto res = isl_set_foreach_point(get(), fn_lambda, &fn_data); + if (fn_data.eptr) + std::rethrow_exception(fn_data.eptr); + if (res < 0) + exception::throw_last_error(saved_ctx); + return; +} + +void set::foreach_set(const std::function &fn) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_set(*this).foreach_set(fn); +} + +isl::set set::gist(isl::set context) const +{ + if (!ptr || context.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_set_gist(copy(), context.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_set set::gist(const isl::union_set &context) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_set(*this).gist(context); +} + +isl::set set::gist(const isl::basic_set &context) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->gist(isl::set(context)); +} + +isl::set set::gist(const isl::point &context) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->gist(isl::set(context)); +} + +isl::set set::gist_params(isl::set context) const +{ + if (!ptr || context.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_set_gist_params(copy(), context.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::map set::identity() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_set_identity(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::pw_aff set::indicator_function() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_set_indicator_function(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::map set::insert_domain(isl::space domain) const +{ + if (!ptr || domain.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_set_insert_domain(copy(), domain.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::set set::intersect(isl::set set2) const +{ + if (!ptr || set2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_set_intersect(copy(), set2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_set set::intersect(const isl::union_set &uset2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_set(*this).intersect(uset2); +} + +isl::set set::intersect(const isl::basic_set &set2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->intersect(isl::set(set2)); +} + +isl::set set::intersect(const isl::point &set2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->intersect(isl::set(set2)); +} + +isl::set set::intersect_params(isl::set params) const +{ + if (!ptr || params.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_set_intersect_params(copy(), params.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +bool set::involves_locals() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_set_involves_locals(get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +bool set::is_disjoint(const isl::set &set2) const +{ + if (!ptr || set2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_set_is_disjoint(get(), set2.get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +bool set::is_disjoint(const isl::union_set &uset2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_set(*this).is_disjoint(uset2); +} + +bool set::is_disjoint(const isl::basic_set &set2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->is_disjoint(isl::set(set2)); +} + +bool set::is_disjoint(const isl::point &set2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->is_disjoint(isl::set(set2)); +} + +bool set::is_empty() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_set_is_empty(get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +bool set::is_equal(const isl::set &set2) const +{ + if (!ptr || set2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_set_is_equal(get(), set2.get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +bool set::is_equal(const isl::union_set &uset2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_set(*this).is_equal(uset2); +} + +bool set::is_equal(const isl::basic_set &set2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->is_equal(isl::set(set2)); +} + +bool set::is_equal(const isl::point &set2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->is_equal(isl::set(set2)); +} + +bool set::is_singleton() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_set_is_singleton(get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +bool set::is_strict_subset(const isl::set &set2) const +{ + if (!ptr || set2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_set_is_strict_subset(get(), set2.get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +bool set::is_strict_subset(const isl::union_set &uset2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_set(*this).is_strict_subset(uset2); +} + +bool set::is_strict_subset(const isl::basic_set &set2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->is_strict_subset(isl::set(set2)); +} + +bool set::is_strict_subset(const isl::point &set2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->is_strict_subset(isl::set(set2)); +} + +bool set::is_subset(const isl::set &set2) const +{ + if (!ptr || set2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_set_is_subset(get(), set2.get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +bool set::is_subset(const isl::union_set &uset2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_set(*this).is_subset(uset2); +} + +bool set::is_subset(const isl::basic_set &set2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->is_subset(isl::set(set2)); +} + +bool set::is_subset(const isl::point &set2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->is_subset(isl::set(set2)); +} + +bool set::is_wrapping() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_set_is_wrapping(get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +bool set::isa_set() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_set(*this).isa_set(); +} + +isl::fixed_box set::lattice_tile() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_set_get_lattice_tile(get()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::fixed_box set::get_lattice_tile() const +{ + return lattice_tile(); +} + +isl::set set::lexmax() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_set_lexmax(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::pw_multi_aff set::lexmax_pw_multi_aff() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_set_lexmax_pw_multi_aff(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::set set::lexmin() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_set_lexmin(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::pw_multi_aff set::lexmin_pw_multi_aff() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_set_lexmin_pw_multi_aff(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::set set::lower_bound(isl::multi_pw_aff lower) const +{ + if (!ptr || lower.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_set_lower_bound_multi_pw_aff(copy(), lower.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::set set::lower_bound(isl::multi_val lower) const +{ + if (!ptr || lower.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_set_lower_bound_multi_val(copy(), lower.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_pw_aff set::max_multi_pw_aff() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_set_max_multi_pw_aff(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::val set::max_val(const isl::aff &obj) const +{ + if (!ptr || obj.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_set_max_val(get(), obj.get()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_pw_aff set::min_multi_pw_aff() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_set_min_multi_pw_aff(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::val set::min_val(const isl::aff &obj) const +{ + if (!ptr || obj.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_set_min_val(get(), obj.get()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +unsigned set::n_basic_set() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_set_n_basic_set(get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +isl::pw_aff set::param_pw_aff_on_domain(isl::id id) const +{ + if (!ptr || id.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_set_param_pw_aff_on_domain_id(copy(), id.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::pw_aff set::param_pw_aff_on_domain(const std::string &id) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->param_pw_aff_on_domain(isl::id(ctx(), id)); +} + +isl::set set::params() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_set_params(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_val set::plain_multi_val_if_fixed() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_set_get_plain_multi_val_if_fixed(get()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_val set::get_plain_multi_val_if_fixed() const +{ + return plain_multi_val_if_fixed(); +} + +isl::basic_set set::polyhedral_hull() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_set_polyhedral_hull(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::set set::preimage(isl::multi_aff ma) const +{ + if (!ptr || ma.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_set_preimage_multi_aff(copy(), ma.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::set set::preimage(isl::multi_pw_aff mpa) const +{ + if (!ptr || mpa.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_set_preimage_multi_pw_aff(copy(), mpa.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::set set::preimage(isl::pw_multi_aff pma) const +{ + if (!ptr || pma.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_set_preimage_pw_multi_aff(copy(), pma.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_set set::preimage(const isl::union_pw_multi_aff &upma) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_set(*this).preimage(upma); +} + +isl::set set::product(isl::set set2) const +{ + if (!ptr || set2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_set_product(copy(), set2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::set set::project_out_all_params() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_set_project_out_all_params(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::set set::project_out_param(isl::id id) const +{ + if (!ptr || id.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_set_project_out_param_id(copy(), id.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::set set::project_out_param(const std::string &id) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->project_out_param(isl::id(ctx(), id)); +} + +isl::set set::project_out_param(isl::id_list list) const +{ + if (!ptr || list.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_set_project_out_param_id_list(copy(), list.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::pw_aff set::pw_aff_on_domain(isl::val v) const +{ + if (!ptr || v.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_set_pw_aff_on_domain_val(copy(), v.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::pw_aff set::pw_aff_on_domain(long v) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->pw_aff_on_domain(isl::val(ctx(), v)); +} + +isl::pw_multi_aff set::pw_multi_aff_on_domain(isl::multi_val mv) const +{ + if (!ptr || mv.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_set_pw_multi_aff_on_domain_multi_val(copy(), mv.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::basic_set set::sample() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_set_sample(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::point set::sample_point() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_set_sample_point(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::set_list set::set_list() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_set(*this).set_list(); +} + +isl::fixed_box set::simple_fixed_box_hull() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_set_get_simple_fixed_box_hull(get()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::fixed_box set::get_simple_fixed_box_hull() const +{ + return simple_fixed_box_hull(); +} + +isl::space set::space() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_set_get_space(get()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::space set::get_space() const +{ + return space(); +} + +isl::val set::stride(int pos) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_set_get_stride(get(), pos); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::val set::get_stride(int pos) const +{ + return stride(pos); +} + +isl::set set::subtract(isl::set set2) const +{ + if (!ptr || set2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_set_subtract(copy(), set2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_set set::subtract(const isl::union_set &uset2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_set(*this).subtract(uset2); +} + +isl::set set::subtract(const isl::basic_set &set2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->subtract(isl::set(set2)); +} + +isl::set set::subtract(const isl::point &set2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->subtract(isl::set(set2)); +} + +isl::set_list set::to_list() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_set_to_list(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_set set::to_union_set() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_set_to_union_set(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::map set::translation() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_set_translation(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +unsigned set::tuple_dim() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_set_tuple_dim(get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +isl::set set::unbind_params(isl::multi_id tuple) const +{ + if (!ptr || tuple.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_set_unbind_params(copy(), tuple.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::map set::unbind_params_insert_domain(isl::multi_id domain) const +{ + if (!ptr || domain.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_set_unbind_params_insert_domain(copy(), domain.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::set set::unite(isl::set set2) const +{ + if (!ptr || set2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_set_union(copy(), set2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_set set::unite(const isl::union_set &uset2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_set(*this).unite(uset2); +} + +isl::set set::unite(const isl::basic_set &set2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->unite(isl::set(set2)); +} + +isl::set set::unite(const isl::point &set2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->unite(isl::set(set2)); +} + +isl::set set::universe(isl::space space) +{ + if (space.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = space.ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_set_universe(space.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::basic_set set::unshifted_simple_hull() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_set_unshifted_simple_hull(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::map set::unwrap() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_set_unwrap(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::set set::upper_bound(isl::multi_pw_aff upper) const +{ + if (!ptr || upper.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_set_upper_bound_multi_pw_aff(copy(), upper.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::set set::upper_bound(isl::multi_val upper) const +{ + if (!ptr || upper.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_set_upper_bound_multi_val(copy(), upper.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::set set::wrapped_reverse() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_set_wrapped_reverse(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +inline std::ostream &operator<<(std::ostream &os, const set &obj) +{ + if (!obj.get()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_set_get_ctx(obj.get()); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + char *str = isl_set_to_str(obj.get()); + if (!str) + exception::throw_last_error(saved_ctx); + os << str; + free(str); + return os; +} + +// implementations for isl::set_list +set_list manage(__isl_take isl_set_list *ptr) { + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return set_list(ptr); +} +set_list manage_copy(__isl_keep isl_set_list *ptr) { + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_set_list_get_ctx(ptr); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + ptr = isl_set_list_copy(ptr); + if (!ptr) + exception::throw_last_error(saved_ctx); + return set_list(ptr); +} + +set_list::set_list(__isl_take isl_set_list *ptr) + : ptr(ptr) {} + +set_list::set_list() + : ptr(nullptr) {} + +set_list::set_list(const set_list &obj) + : ptr(nullptr) +{ + if (!obj.ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_set_list_get_ctx(obj.ptr); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + ptr = obj.copy(); + if (!ptr) + exception::throw_last_error(saved_ctx); +} + +set_list::set_list(isl::ctx ctx, int n) +{ + auto saved_ctx = ctx; + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_set_list_alloc(ctx.release(), n); + if (!res) + exception::throw_last_error(saved_ctx); + ptr = res; +} + +set_list::set_list(isl::set el) +{ + if (el.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = el.ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_set_list_from_set(el.release()); + if (!res) + exception::throw_last_error(saved_ctx); + ptr = res; +} + +set_list::set_list(isl::ctx ctx, const std::string &str) +{ + auto saved_ctx = ctx; + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_set_list_read_from_str(ctx.release(), str.c_str()); + if (!res) + exception::throw_last_error(saved_ctx); + ptr = res; +} + +set_list &set_list::operator=(set_list obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +set_list::~set_list() { + if (ptr) + isl_set_list_free(ptr); +} + +__isl_give isl_set_list *set_list::copy() const & { + return isl_set_list_copy(ptr); +} + +__isl_keep isl_set_list *set_list::get() const { + return ptr; +} + +__isl_give isl_set_list *set_list::release() { + isl_set_list *tmp = ptr; + ptr = nullptr; + return tmp; +} + +bool set_list::is_null() const { + return ptr == nullptr; +} + +isl::ctx set_list::ctx() const { + return isl::ctx(isl_set_list_get_ctx(ptr)); +} + +isl::set_list set_list::add(isl::set el) const +{ + if (!ptr || el.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_set_list_add(copy(), el.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::set set_list::at(int index) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_set_list_get_at(get(), index); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::set set_list::get_at(int index) const +{ + return at(index); +} + +isl::set_list set_list::clear() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_set_list_clear(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::set_list set_list::concat(isl::set_list list2) const +{ + if (!ptr || list2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_set_list_concat(copy(), list2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::set_list set_list::drop(unsigned int first, unsigned int n) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_set_list_drop(copy(), first, n); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +void set_list::foreach(const std::function &fn) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + struct fn_data { + std::function func; + std::exception_ptr eptr; + } fn_data = { fn }; + auto fn_lambda = [](isl_set *arg_0, void *arg_1) -> isl_stat { + auto *data = static_cast(arg_1); + ISL_CPP_TRY { + (data->func)(manage(arg_0)); + return isl_stat_ok; + } ISL_CPP_CATCH_ALL { + data->eptr = std::current_exception(); + return isl_stat_error; + } + }; + auto res = isl_set_list_foreach(get(), fn_lambda, &fn_data); + if (fn_data.eptr) + std::rethrow_exception(fn_data.eptr); + if (res < 0) + exception::throw_last_error(saved_ctx); + return; +} + +void set_list::foreach_scc(const std::function &follows, const std::function &fn) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + struct follows_data { + std::function func; + std::exception_ptr eptr; + } follows_data = { follows }; + auto follows_lambda = [](isl_set *arg_0, isl_set *arg_1, void *arg_2) -> isl_bool { + auto *data = static_cast(arg_2); + ISL_CPP_TRY { + auto ret = (data->func)(manage_copy(arg_0), manage_copy(arg_1)); + return ret ? isl_bool_true : isl_bool_false; + } ISL_CPP_CATCH_ALL { + data->eptr = std::current_exception(); + return isl_bool_error; + } + }; + struct fn_data { + std::function func; + std::exception_ptr eptr; + } fn_data = { fn }; + auto fn_lambda = [](isl_set_list *arg_0, void *arg_1) -> isl_stat { + auto *data = static_cast(arg_1); + ISL_CPP_TRY { + (data->func)(manage(arg_0)); + return isl_stat_ok; + } ISL_CPP_CATCH_ALL { + data->eptr = std::current_exception(); + return isl_stat_error; + } + }; + auto res = isl_set_list_foreach_scc(get(), follows_lambda, &follows_data, fn_lambda, &fn_data); + if (follows_data.eptr) + std::rethrow_exception(follows_data.eptr); + if (fn_data.eptr) + std::rethrow_exception(fn_data.eptr); + if (res < 0) + exception::throw_last_error(saved_ctx); + return; +} + +isl::set_list set_list::insert(unsigned int pos, isl::set el) const +{ + if (!ptr || el.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_set_list_insert(copy(), pos, el.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::set_list set_list::set_at(int index, isl::set el) const +{ + if (!ptr || el.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_set_list_set_at(copy(), index, el.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +unsigned set_list::size() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_set_list_size(get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +inline std::ostream &operator<<(std::ostream &os, const set_list &obj) +{ + if (!obj.get()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_set_list_get_ctx(obj.get()); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + char *str = isl_set_list_to_str(obj.get()); + if (!str) + exception::throw_last_error(saved_ctx); + os << str; + free(str); + return os; +} + +// implementations for isl::space +space manage(__isl_take isl_space *ptr) { + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return space(ptr); +} +space manage_copy(__isl_keep isl_space *ptr) { + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_space_get_ctx(ptr); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + ptr = isl_space_copy(ptr); + if (!ptr) + exception::throw_last_error(saved_ctx); + return space(ptr); +} + +space::space(__isl_take isl_space *ptr) + : ptr(ptr) {} + +space::space() + : ptr(nullptr) {} + +space::space(const space &obj) + : ptr(nullptr) +{ + if (!obj.ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_space_get_ctx(obj.ptr); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + ptr = obj.copy(); + if (!ptr) + exception::throw_last_error(saved_ctx); +} + +space::space(isl::ctx ctx, const std::string &str) +{ + auto saved_ctx = ctx; + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_space_read_from_str(ctx.release(), str.c_str()); + if (!res) + exception::throw_last_error(saved_ctx); + ptr = res; +} + +space &space::operator=(space obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +space::~space() { + if (ptr) + isl_space_free(ptr); +} + +__isl_give isl_space *space::copy() const & { + return isl_space_copy(ptr); +} + +__isl_keep isl_space *space::get() const { + return ptr; +} + +__isl_give isl_space *space::release() { + isl_space *tmp = ptr; + ptr = nullptr; + return tmp; +} + +bool space::is_null() const { + return ptr == nullptr; +} + +isl::ctx space::ctx() const { + return isl::ctx(isl_space_get_ctx(ptr)); +} + +isl::space space::add_named_tuple(isl::id tuple_id, unsigned int dim) const +{ + if (!ptr || tuple_id.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_space_add_named_tuple_id_ui(copy(), tuple_id.release(), dim); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::space space::add_named_tuple(const std::string &tuple_id, unsigned int dim) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->add_named_tuple(isl::id(ctx(), tuple_id), dim); +} + +isl::space space::add_param(isl::id id) const +{ + if (!ptr || id.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_space_add_param_id(copy(), id.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::space space::add_param(const std::string &id) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->add_param(isl::id(ctx(), id)); +} + +isl::space space::add_unnamed_tuple(unsigned int dim) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_space_add_unnamed_tuple_ui(copy(), dim); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::space space::curry() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_space_curry(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::space space::domain() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_space_domain(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_aff space::domain_map_multi_aff() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_space_domain_map_multi_aff(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::pw_multi_aff space::domain_map_pw_multi_aff() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_space_domain_map_pw_multi_aff(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::space space::domain_reverse() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_space_domain_reverse(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::id space::domain_tuple_id() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_space_get_domain_tuple_id(get()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::id space::get_domain_tuple_id() const +{ + return domain_tuple_id(); +} + +isl::space space::drop_all_params() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_space_drop_all_params(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::space space::flatten_domain() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_space_flatten_domain(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::space space::flatten_range() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_space_flatten_range(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +bool space::has_domain_tuple_id() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_space_has_domain_tuple_id(get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +bool space::has_range_tuple_id() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_space_has_range_tuple_id(get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +isl::multi_aff space::identity_multi_aff_on_domain() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_space_identity_multi_aff_on_domain(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_pw_aff space::identity_multi_pw_aff_on_domain() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_space_identity_multi_pw_aff_on_domain(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::pw_multi_aff space::identity_pw_multi_aff_on_domain() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_space_identity_pw_multi_aff_on_domain(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +bool space::is_equal(const isl::space &space2) const +{ + if (!ptr || space2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_space_is_equal(get(), space2.get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +bool space::is_wrapping() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_space_is_wrapping(get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +isl::space space::map_from_set() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_space_map_from_set(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_aff space::multi_aff(isl::aff_list list) const +{ + if (!ptr || list.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_space_multi_aff(copy(), list.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_aff space::multi_aff_on_domain(isl::multi_val mv) const +{ + if (!ptr || mv.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_space_multi_aff_on_domain_multi_val(copy(), mv.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_id space::multi_id(isl::id_list list) const +{ + if (!ptr || list.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_space_multi_id(copy(), list.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_pw_aff space::multi_pw_aff(isl::pw_aff_list list) const +{ + if (!ptr || list.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_space_multi_pw_aff(copy(), list.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_union_pw_aff space::multi_union_pw_aff(isl::union_pw_aff_list list) const +{ + if (!ptr || list.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_space_multi_union_pw_aff(copy(), list.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_val space::multi_val(isl::val_list list) const +{ + if (!ptr || list.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_space_multi_val(copy(), list.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::aff space::param_aff_on_domain(isl::id id) const +{ + if (!ptr || id.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_space_param_aff_on_domain_id(copy(), id.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::aff space::param_aff_on_domain(const std::string &id) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->param_aff_on_domain(isl::id(ctx(), id)); +} + +isl::space space::params() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_space_params(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::space space::product(isl::space right) const +{ + if (!ptr || right.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_space_product(copy(), right.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::space space::range() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_space_range(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_aff space::range_map_multi_aff() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_space_range_map_multi_aff(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::pw_multi_aff space::range_map_pw_multi_aff() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_space_range_map_pw_multi_aff(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::space space::range_reverse() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_space_range_reverse(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::id space::range_tuple_id() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_space_get_range_tuple_id(get()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::id space::get_range_tuple_id() const +{ + return range_tuple_id(); +} + +isl::space space::reverse() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_space_reverse(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::space space::set_domain_tuple(isl::id id) const +{ + if (!ptr || id.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_space_set_domain_tuple_id(copy(), id.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::space space::set_domain_tuple(const std::string &id) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->set_domain_tuple(isl::id(ctx(), id)); +} + +isl::space space::set_range_tuple(isl::id id) const +{ + if (!ptr || id.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_space_set_range_tuple_id(copy(), id.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::space space::set_range_tuple(const std::string &id) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->set_range_tuple(isl::id(ctx(), id)); +} + +isl::space space::uncurry() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_space_uncurry(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::space space::unit(isl::ctx ctx) +{ + auto saved_ctx = ctx; + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_space_unit(ctx.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::map space::universe_map() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_space_universe_map(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::set space::universe_set() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_space_universe_set(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::space space::unwrap() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_space_unwrap(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::space space::wrap() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_space_wrap(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::space space::wrapped_reverse() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_space_wrapped_reverse(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::aff space::zero_aff_on_domain() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_space_zero_aff_on_domain(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_aff space::zero_multi_aff() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_space_zero_multi_aff(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_pw_aff space::zero_multi_pw_aff() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_space_zero_multi_pw_aff(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_union_pw_aff space::zero_multi_union_pw_aff() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_space_zero_multi_union_pw_aff(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_val space::zero_multi_val() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_space_zero_multi_val(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +inline std::ostream &operator<<(std::ostream &os, const space &obj) +{ + if (!obj.get()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_space_get_ctx(obj.get()); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + char *str = isl_space_to_str(obj.get()); + if (!str) + exception::throw_last_error(saved_ctx); + os << str; + free(str); + return os; +} + +// implementations for isl::union_access_info +union_access_info manage(__isl_take isl_union_access_info *ptr) { + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return union_access_info(ptr); +} +union_access_info manage_copy(__isl_keep isl_union_access_info *ptr) { + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_union_access_info_get_ctx(ptr); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + ptr = isl_union_access_info_copy(ptr); + if (!ptr) + exception::throw_last_error(saved_ctx); + return union_access_info(ptr); +} + +union_access_info::union_access_info(__isl_take isl_union_access_info *ptr) + : ptr(ptr) {} + +union_access_info::union_access_info() + : ptr(nullptr) {} + +union_access_info::union_access_info(const union_access_info &obj) + : ptr(nullptr) +{ + if (!obj.ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_union_access_info_get_ctx(obj.ptr); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + ptr = obj.copy(); + if (!ptr) + exception::throw_last_error(saved_ctx); +} + +union_access_info::union_access_info(isl::union_map sink) +{ + if (sink.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = sink.ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_access_info_from_sink(sink.release()); + if (!res) + exception::throw_last_error(saved_ctx); + ptr = res; +} + +union_access_info &union_access_info::operator=(union_access_info obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +union_access_info::~union_access_info() { + if (ptr) + isl_union_access_info_free(ptr); +} + +__isl_give isl_union_access_info *union_access_info::copy() const & { + return isl_union_access_info_copy(ptr); +} + +__isl_keep isl_union_access_info *union_access_info::get() const { + return ptr; +} + +__isl_give isl_union_access_info *union_access_info::release() { + isl_union_access_info *tmp = ptr; + ptr = nullptr; + return tmp; +} + +bool union_access_info::is_null() const { + return ptr == nullptr; +} + +isl::ctx union_access_info::ctx() const { + return isl::ctx(isl_union_access_info_get_ctx(ptr)); +} + +isl::union_flow union_access_info::compute_flow() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_access_info_compute_flow(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_access_info union_access_info::set_kill(isl::union_map kill) const +{ + if (!ptr || kill.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_access_info_set_kill(copy(), kill.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_access_info union_access_info::set_may_source(isl::union_map may_source) const +{ + if (!ptr || may_source.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_access_info_set_may_source(copy(), may_source.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_access_info union_access_info::set_must_source(isl::union_map must_source) const +{ + if (!ptr || must_source.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_access_info_set_must_source(copy(), must_source.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_access_info union_access_info::set_schedule(isl::schedule schedule) const +{ + if (!ptr || schedule.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_access_info_set_schedule(copy(), schedule.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_access_info union_access_info::set_schedule_map(isl::union_map schedule_map) const +{ + if (!ptr || schedule_map.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_access_info_set_schedule_map(copy(), schedule_map.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +inline std::ostream &operator<<(std::ostream &os, const union_access_info &obj) +{ + if (!obj.get()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_union_access_info_get_ctx(obj.get()); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + char *str = isl_union_access_info_to_str(obj.get()); + if (!str) + exception::throw_last_error(saved_ctx); + os << str; + free(str); + return os; +} + +// implementations for isl::union_flow +union_flow manage(__isl_take isl_union_flow *ptr) { + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return union_flow(ptr); +} +union_flow manage_copy(__isl_keep isl_union_flow *ptr) { + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_union_flow_get_ctx(ptr); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + ptr = isl_union_flow_copy(ptr); + if (!ptr) + exception::throw_last_error(saved_ctx); + return union_flow(ptr); +} + +union_flow::union_flow(__isl_take isl_union_flow *ptr) + : ptr(ptr) {} + +union_flow::union_flow() + : ptr(nullptr) {} + +union_flow::union_flow(const union_flow &obj) + : ptr(nullptr) +{ + if (!obj.ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_union_flow_get_ctx(obj.ptr); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + ptr = obj.copy(); + if (!ptr) + exception::throw_last_error(saved_ctx); +} + +union_flow &union_flow::operator=(union_flow obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +union_flow::~union_flow() { + if (ptr) + isl_union_flow_free(ptr); +} + +__isl_give isl_union_flow *union_flow::copy() const & { + return isl_union_flow_copy(ptr); +} + +__isl_keep isl_union_flow *union_flow::get() const { + return ptr; +} + +__isl_give isl_union_flow *union_flow::release() { + isl_union_flow *tmp = ptr; + ptr = nullptr; + return tmp; +} + +bool union_flow::is_null() const { + return ptr == nullptr; +} + +isl::ctx union_flow::ctx() const { + return isl::ctx(isl_union_flow_get_ctx(ptr)); +} + +isl::union_map union_flow::full_may_dependence() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_flow_get_full_may_dependence(get()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map union_flow::get_full_may_dependence() const +{ + return full_may_dependence(); +} + +isl::union_map union_flow::full_must_dependence() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_flow_get_full_must_dependence(get()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map union_flow::get_full_must_dependence() const +{ + return full_must_dependence(); +} + +isl::union_map union_flow::may_dependence() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_flow_get_may_dependence(get()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map union_flow::get_may_dependence() const +{ + return may_dependence(); +} + +isl::union_map union_flow::may_no_source() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_flow_get_may_no_source(get()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map union_flow::get_may_no_source() const +{ + return may_no_source(); +} + +isl::union_map union_flow::must_dependence() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_flow_get_must_dependence(get()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map union_flow::get_must_dependence() const +{ + return must_dependence(); +} + +isl::union_map union_flow::must_no_source() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_flow_get_must_no_source(get()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map union_flow::get_must_no_source() const +{ + return must_no_source(); +} + +inline std::ostream &operator<<(std::ostream &os, const union_flow &obj) +{ + if (!obj.get()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_union_flow_get_ctx(obj.get()); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + char *str = isl_union_flow_to_str(obj.get()); + if (!str) + exception::throw_last_error(saved_ctx); + os << str; + free(str); + return os; +} + +// implementations for isl::union_map +union_map manage(__isl_take isl_union_map *ptr) { + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return union_map(ptr); +} +union_map manage_copy(__isl_keep isl_union_map *ptr) { + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_union_map_get_ctx(ptr); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + ptr = isl_union_map_copy(ptr); + if (!ptr) + exception::throw_last_error(saved_ctx); + return union_map(ptr); +} + +union_map::union_map(__isl_take isl_union_map *ptr) + : ptr(ptr) {} + +union_map::union_map() + : ptr(nullptr) {} + +union_map::union_map(const union_map &obj) + : ptr(nullptr) +{ + if (!obj.ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_union_map_get_ctx(obj.ptr); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + ptr = obj.copy(); + if (!ptr) + exception::throw_last_error(saved_ctx); +} + +union_map::union_map(isl::basic_map bmap) +{ + if (bmap.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = bmap.ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_map_from_basic_map(bmap.release()); + if (!res) + exception::throw_last_error(saved_ctx); + ptr = res; +} + +union_map::union_map(isl::map map) +{ + if (map.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = map.ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_map_from_map(map.release()); + if (!res) + exception::throw_last_error(saved_ctx); + ptr = res; +} + +union_map::union_map(isl::ctx ctx, const std::string &str) +{ + auto saved_ctx = ctx; + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_map_read_from_str(ctx.release(), str.c_str()); + if (!res) + exception::throw_last_error(saved_ctx); + ptr = res; +} + +union_map &union_map::operator=(union_map obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +union_map::~union_map() { + if (ptr) + isl_union_map_free(ptr); +} + +__isl_give isl_union_map *union_map::copy() const & { + return isl_union_map_copy(ptr); +} + +__isl_keep isl_union_map *union_map::get() const { + return ptr; +} + +__isl_give isl_union_map *union_map::release() { + isl_union_map *tmp = ptr; + ptr = nullptr; + return tmp; +} + +bool union_map::is_null() const { + return ptr == nullptr; +} + +isl::ctx union_map::ctx() const { + return isl::ctx(isl_union_map_get_ctx(ptr)); +} + +isl::union_map union_map::affine_hull() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_map_affine_hull(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map union_map::apply_domain(isl::union_map umap2) const +{ + if (!ptr || umap2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_map_apply_domain(copy(), umap2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map union_map::apply_range(isl::union_map umap2) const +{ + if (!ptr || umap2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_map_apply_range(copy(), umap2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::map union_map::as_map() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_map_as_map(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_union_pw_aff union_map::as_multi_union_pw_aff() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_map_as_multi_union_pw_aff(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_pw_multi_aff union_map::as_union_pw_multi_aff() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_map_as_union_pw_multi_aff(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_set union_map::bind_range(isl::multi_id tuple) const +{ + if (!ptr || tuple.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_map_bind_range(copy(), tuple.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map union_map::coalesce() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_map_coalesce(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map union_map::compute_divs() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_map_compute_divs(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map union_map::curry() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_map_curry(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_set union_map::deltas() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_map_deltas(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map union_map::detect_equalities() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_map_detect_equalities(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_set union_map::domain() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_map_domain(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map union_map::domain_factor_domain() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_map_domain_factor_domain(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map union_map::domain_factor_range() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_map_domain_factor_range(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map union_map::domain_map() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_map_domain_map(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_pw_multi_aff union_map::domain_map_union_pw_multi_aff() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_map_domain_map_union_pw_multi_aff(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map union_map::domain_product(isl::union_map umap2) const +{ + if (!ptr || umap2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_map_domain_product(copy(), umap2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map union_map::domain_reverse() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_map_domain_reverse(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map union_map::drop_unused_params() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_map_drop_unused_params(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map union_map::empty(isl::ctx ctx) +{ + auto saved_ctx = ctx; + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_map_empty_ctx(ctx.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map union_map::eq_at(isl::multi_union_pw_aff mupa) const +{ + if (!ptr || mupa.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_map_eq_at_multi_union_pw_aff(copy(), mupa.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +bool union_map::every_map(const std::function &test) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + struct test_data { + std::function func; + std::exception_ptr eptr; + } test_data = { test }; + auto test_lambda = [](isl_map *arg_0, void *arg_1) -> isl_bool { + auto *data = static_cast(arg_1); + ISL_CPP_TRY { + auto ret = (data->func)(manage_copy(arg_0)); + return ret ? isl_bool_true : isl_bool_false; + } ISL_CPP_CATCH_ALL { + data->eptr = std::current_exception(); + return isl_bool_error; + } + }; + auto res = isl_union_map_every_map(get(), test_lambda, &test_data); + if (test_data.eptr) + std::rethrow_exception(test_data.eptr); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +isl::map union_map::extract_map(isl::space space) const +{ + if (!ptr || space.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_map_extract_map(get(), space.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map union_map::factor_domain() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_map_factor_domain(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map union_map::factor_range() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_map_factor_range(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map union_map::fixed_power(isl::val exp) const +{ + if (!ptr || exp.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_map_fixed_power_val(copy(), exp.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map union_map::fixed_power(long exp) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->fixed_power(isl::val(ctx(), exp)); +} + +void union_map::foreach_map(const std::function &fn) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + struct fn_data { + std::function func; + std::exception_ptr eptr; + } fn_data = { fn }; + auto fn_lambda = [](isl_map *arg_0, void *arg_1) -> isl_stat { + auto *data = static_cast(arg_1); + ISL_CPP_TRY { + (data->func)(manage(arg_0)); + return isl_stat_ok; + } ISL_CPP_CATCH_ALL { + data->eptr = std::current_exception(); + return isl_stat_error; + } + }; + auto res = isl_union_map_foreach_map(get(), fn_lambda, &fn_data); + if (fn_data.eptr) + std::rethrow_exception(fn_data.eptr); + if (res < 0) + exception::throw_last_error(saved_ctx); + return; +} + +isl::union_map union_map::from(isl::multi_union_pw_aff mupa) +{ + if (mupa.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = mupa.ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_map_from_multi_union_pw_aff(mupa.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map union_map::from(isl::union_pw_multi_aff upma) +{ + if (upma.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = upma.ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_map_from_union_pw_multi_aff(upma.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map union_map::from_domain(isl::union_set uset) +{ + if (uset.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = uset.ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_map_from_domain(uset.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map union_map::from_domain_and_range(isl::union_set domain, isl::union_set range) +{ + if (domain.is_null() || range.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = domain.ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_map_from_domain_and_range(domain.release(), range.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map union_map::from_range(isl::union_set uset) +{ + if (uset.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = uset.ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_map_from_range(uset.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map union_map::gist(isl::union_map context) const +{ + if (!ptr || context.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_map_gist(copy(), context.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map union_map::gist_domain(isl::union_set uset) const +{ + if (!ptr || uset.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_map_gist_domain(copy(), uset.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map union_map::gist_params(isl::set set) const +{ + if (!ptr || set.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_map_gist_params(copy(), set.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map union_map::gist_range(isl::union_set uset) const +{ + if (!ptr || uset.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_map_gist_range(copy(), uset.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map union_map::intersect(isl::union_map umap2) const +{ + if (!ptr || umap2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_map_intersect(copy(), umap2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map union_map::intersect_domain(isl::space space) const +{ + if (!ptr || space.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_map_intersect_domain_space(copy(), space.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map union_map::intersect_domain(isl::union_set uset) const +{ + if (!ptr || uset.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_map_intersect_domain_union_set(copy(), uset.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map union_map::intersect_domain_factor_domain(isl::union_map factor) const +{ + if (!ptr || factor.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_map_intersect_domain_factor_domain(copy(), factor.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map union_map::intersect_domain_factor_range(isl::union_map factor) const +{ + if (!ptr || factor.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_map_intersect_domain_factor_range(copy(), factor.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map union_map::intersect_domain_wrapped_domain(isl::union_set domain) const +{ + if (!ptr || domain.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_map_intersect_domain_wrapped_domain_union_set(copy(), domain.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map union_map::intersect_params(isl::set set) const +{ + if (!ptr || set.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_map_intersect_params(copy(), set.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map union_map::intersect_range(isl::space space) const +{ + if (!ptr || space.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_map_intersect_range_space(copy(), space.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map union_map::intersect_range(isl::union_set uset) const +{ + if (!ptr || uset.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_map_intersect_range_union_set(copy(), uset.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map union_map::intersect_range_factor_domain(isl::union_map factor) const +{ + if (!ptr || factor.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_map_intersect_range_factor_domain(copy(), factor.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map union_map::intersect_range_factor_range(isl::union_map factor) const +{ + if (!ptr || factor.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_map_intersect_range_factor_range(copy(), factor.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map union_map::intersect_range_wrapped_domain(isl::union_set domain) const +{ + if (!ptr || domain.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_map_intersect_range_wrapped_domain_union_set(copy(), domain.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +bool union_map::is_bijective() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_map_is_bijective(get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +bool union_map::is_disjoint(const isl::union_map &umap2) const +{ + if (!ptr || umap2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_map_is_disjoint(get(), umap2.get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +bool union_map::is_empty() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_map_is_empty(get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +bool union_map::is_equal(const isl::union_map &umap2) const +{ + if (!ptr || umap2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_map_is_equal(get(), umap2.get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +bool union_map::is_injective() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_map_is_injective(get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +bool union_map::is_single_valued() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_map_is_single_valued(get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +bool union_map::is_strict_subset(const isl::union_map &umap2) const +{ + if (!ptr || umap2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_map_is_strict_subset(get(), umap2.get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +bool union_map::is_subset(const isl::union_map &umap2) const +{ + if (!ptr || umap2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_map_is_subset(get(), umap2.get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +bool union_map::isa_map() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_map_isa_map(get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +isl::union_map union_map::lexmax() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_map_lexmax(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map union_map::lexmin() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_map_lexmin(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::map_list union_map::map_list() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_map_get_map_list(get()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::map_list union_map::get_map_list() const +{ + return map_list(); +} + +isl::set union_map::params() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_map_params(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map union_map::polyhedral_hull() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_map_polyhedral_hull(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map union_map::preimage_domain(isl::multi_aff ma) const +{ + if (!ptr || ma.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_map_preimage_domain_multi_aff(copy(), ma.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map union_map::preimage_domain(isl::multi_pw_aff mpa) const +{ + if (!ptr || mpa.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_map_preimage_domain_multi_pw_aff(copy(), mpa.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map union_map::preimage_domain(isl::pw_multi_aff pma) const +{ + if (!ptr || pma.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_map_preimage_domain_pw_multi_aff(copy(), pma.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map union_map::preimage_domain(isl::union_pw_multi_aff upma) const +{ + if (!ptr || upma.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_map_preimage_domain_union_pw_multi_aff(copy(), upma.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map union_map::preimage_range(isl::multi_aff ma) const +{ + if (!ptr || ma.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_map_preimage_range_multi_aff(copy(), ma.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map union_map::preimage_range(isl::pw_multi_aff pma) const +{ + if (!ptr || pma.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_map_preimage_range_pw_multi_aff(copy(), pma.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map union_map::preimage_range(isl::union_pw_multi_aff upma) const +{ + if (!ptr || upma.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_map_preimage_range_union_pw_multi_aff(copy(), upma.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map union_map::product(isl::union_map umap2) const +{ + if (!ptr || umap2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_map_product(copy(), umap2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map union_map::project_out_all_params() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_map_project_out_all_params(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map union_map::project_out_param(isl::id id) const +{ + if (!ptr || id.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_map_project_out_param_id(copy(), id.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map union_map::project_out_param(const std::string &id) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->project_out_param(isl::id(ctx(), id)); +} + +isl::union_map union_map::project_out_param(isl::id_list list) const +{ + if (!ptr || list.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_map_project_out_param_id_list(copy(), list.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_set union_map::range() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_map_range(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map union_map::range_factor_domain() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_map_range_factor_domain(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map union_map::range_factor_range() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_map_range_factor_range(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map union_map::range_map() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_map_range_map(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map union_map::range_product(isl::union_map umap2) const +{ + if (!ptr || umap2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_map_range_product(copy(), umap2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map union_map::range_reverse() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_map_range_reverse(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map union_map::reverse() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_map_reverse(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::space union_map::space() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_map_get_space(get()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::space union_map::get_space() const +{ + return space(); +} + +isl::union_map union_map::subtract(isl::union_map umap2) const +{ + if (!ptr || umap2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_map_subtract(copy(), umap2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map union_map::subtract_domain(isl::union_set dom) const +{ + if (!ptr || dom.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_map_subtract_domain(copy(), dom.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map union_map::subtract_range(isl::union_set dom) const +{ + if (!ptr || dom.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_map_subtract_range(copy(), dom.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map union_map::uncurry() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_map_uncurry(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map union_map::unite(isl::union_map umap2) const +{ + if (!ptr || umap2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_map_union(copy(), umap2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map union_map::universe() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_map_universe(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_set union_map::wrap() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_map_wrap(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map union_map::zip() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_map_zip(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +inline std::ostream &operator<<(std::ostream &os, const union_map &obj) +{ + if (!obj.get()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_union_map_get_ctx(obj.get()); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + char *str = isl_union_map_to_str(obj.get()); + if (!str) + exception::throw_last_error(saved_ctx); + os << str; + free(str); + return os; +} + +// implementations for isl::union_pw_aff +union_pw_aff manage(__isl_take isl_union_pw_aff *ptr) { + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return union_pw_aff(ptr); +} +union_pw_aff manage_copy(__isl_keep isl_union_pw_aff *ptr) { + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_union_pw_aff_get_ctx(ptr); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + ptr = isl_union_pw_aff_copy(ptr); + if (!ptr) + exception::throw_last_error(saved_ctx); + return union_pw_aff(ptr); +} + +union_pw_aff::union_pw_aff(__isl_take isl_union_pw_aff *ptr) + : ptr(ptr) {} + +union_pw_aff::union_pw_aff() + : ptr(nullptr) {} + +union_pw_aff::union_pw_aff(const union_pw_aff &obj) + : ptr(nullptr) +{ + if (!obj.ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_union_pw_aff_get_ctx(obj.ptr); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + ptr = obj.copy(); + if (!ptr) + exception::throw_last_error(saved_ctx); +} + +union_pw_aff::union_pw_aff(isl::aff aff) +{ + if (aff.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = aff.ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_pw_aff_from_aff(aff.release()); + if (!res) + exception::throw_last_error(saved_ctx); + ptr = res; +} + +union_pw_aff::union_pw_aff(isl::pw_aff pa) +{ + if (pa.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = pa.ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_pw_aff_from_pw_aff(pa.release()); + if (!res) + exception::throw_last_error(saved_ctx); + ptr = res; +} + +union_pw_aff::union_pw_aff(isl::ctx ctx, const std::string &str) +{ + auto saved_ctx = ctx; + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_pw_aff_read_from_str(ctx.release(), str.c_str()); + if (!res) + exception::throw_last_error(saved_ctx); + ptr = res; +} + +union_pw_aff &union_pw_aff::operator=(union_pw_aff obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +union_pw_aff::~union_pw_aff() { + if (ptr) + isl_union_pw_aff_free(ptr); +} + +__isl_give isl_union_pw_aff *union_pw_aff::copy() const & { + return isl_union_pw_aff_copy(ptr); +} + +__isl_keep isl_union_pw_aff *union_pw_aff::get() const { + return ptr; +} + +__isl_give isl_union_pw_aff *union_pw_aff::release() { + isl_union_pw_aff *tmp = ptr; + ptr = nullptr; + return tmp; +} + +bool union_pw_aff::is_null() const { + return ptr == nullptr; +} + +isl::ctx union_pw_aff::ctx() const { + return isl::ctx(isl_union_pw_aff_get_ctx(ptr)); +} + +isl::multi_union_pw_aff union_pw_aff::add(const isl::multi_union_pw_aff &multi2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::multi_union_pw_aff(*this).add(multi2); +} + +isl::union_pw_aff union_pw_aff::add(isl::union_pw_aff upa2) const +{ + if (!ptr || upa2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_pw_aff_add(copy(), upa2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_pw_multi_aff union_pw_aff::add(const isl::union_pw_multi_aff &upma2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_pw_multi_aff(*this).add(upma2); +} + +isl::union_pw_aff union_pw_aff::add(const isl::aff &upa2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->add(isl::union_pw_aff(upa2)); +} + +isl::union_pw_aff union_pw_aff::add(const isl::pw_aff &upa2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->add(isl::union_pw_aff(upa2)); +} + +isl::union_pw_multi_aff union_pw_aff::apply(const isl::union_pw_multi_aff &upma2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_pw_multi_aff(*this).apply(upma2); +} + +isl::multi_union_pw_aff union_pw_aff::as_multi_union_pw_aff() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_pw_multi_aff(*this).as_multi_union_pw_aff(); +} + +isl::pw_multi_aff union_pw_aff::as_pw_multi_aff() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_pw_multi_aff(*this).as_pw_multi_aff(); +} + +isl::union_map union_pw_aff::as_union_map() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_pw_multi_aff(*this).as_union_map(); +} + +isl::union_pw_aff union_pw_aff::at(int pos) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::multi_union_pw_aff(*this).at(pos); +} + +isl::union_set union_pw_aff::bind(const isl::multi_id &tuple) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::multi_union_pw_aff(*this).bind(tuple); +} + +isl::union_set union_pw_aff::bind(isl::id id) const +{ + if (!ptr || id.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_pw_aff_bind_id(copy(), id.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_set union_pw_aff::bind(const std::string &id) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->bind(isl::id(ctx(), id)); +} + +isl::union_pw_aff union_pw_aff::coalesce() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_pw_aff_coalesce(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_set union_pw_aff::domain() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_pw_aff_domain(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_pw_aff union_pw_aff::drop_unused_params() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_pw_aff_drop_unused_params(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::pw_multi_aff union_pw_aff::extract_pw_multi_aff(const isl::space &space) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_pw_multi_aff(*this).extract_pw_multi_aff(space); +} + +isl::multi_union_pw_aff union_pw_aff::flat_range_product(const isl::multi_union_pw_aff &multi2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::multi_union_pw_aff(*this).flat_range_product(multi2); +} + +isl::union_pw_multi_aff union_pw_aff::flat_range_product(const isl::union_pw_multi_aff &upma2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_pw_multi_aff(*this).flat_range_product(upma2); +} + +isl::union_pw_aff union_pw_aff::gist(isl::union_set context) const +{ + if (!ptr || context.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_pw_aff_gist(copy(), context.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_union_pw_aff union_pw_aff::gist_params(const isl::set &context) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::multi_union_pw_aff(*this).gist_params(context); +} + +bool union_pw_aff::has_range_tuple_id() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::multi_union_pw_aff(*this).has_range_tuple_id(); +} + +isl::union_pw_aff union_pw_aff::intersect_domain(isl::space space) const +{ + if (!ptr || space.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_pw_aff_intersect_domain_space(copy(), space.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_pw_aff union_pw_aff::intersect_domain(isl::union_set uset) const +{ + if (!ptr || uset.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_pw_aff_intersect_domain_union_set(copy(), uset.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_pw_aff union_pw_aff::intersect_domain_wrapped_domain(isl::union_set uset) const +{ + if (!ptr || uset.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_pw_aff_intersect_domain_wrapped_domain(copy(), uset.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_pw_aff union_pw_aff::intersect_domain_wrapped_range(isl::union_set uset) const +{ + if (!ptr || uset.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_pw_aff_intersect_domain_wrapped_range(copy(), uset.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_pw_aff union_pw_aff::intersect_params(isl::set set) const +{ + if (!ptr || set.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_pw_aff_intersect_params(copy(), set.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +bool union_pw_aff::involves_locals() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_pw_multi_aff(*this).involves_locals(); +} + +bool union_pw_aff::involves_nan() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::multi_union_pw_aff(*this).involves_nan(); +} + +bool union_pw_aff::isa_pw_multi_aff() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_pw_multi_aff(*this).isa_pw_multi_aff(); +} + +isl::union_pw_aff_list union_pw_aff::list() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::multi_union_pw_aff(*this).list(); +} + +isl::multi_union_pw_aff union_pw_aff::neg() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::multi_union_pw_aff(*this).neg(); +} + +bool union_pw_aff::plain_is_empty() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_pw_multi_aff(*this).plain_is_empty(); +} + +bool union_pw_aff::plain_is_equal(const isl::multi_union_pw_aff &multi2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::multi_union_pw_aff(*this).plain_is_equal(multi2); +} + +bool union_pw_aff::plain_is_equal(const isl::union_pw_aff &upa2) const +{ + if (!ptr || upa2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_pw_aff_plain_is_equal(get(), upa2.get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +bool union_pw_aff::plain_is_equal(const isl::union_pw_multi_aff &upma2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_pw_multi_aff(*this).plain_is_equal(upma2); +} + +bool union_pw_aff::plain_is_equal(const isl::aff &upa2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->plain_is_equal(isl::union_pw_aff(upa2)); +} + +bool union_pw_aff::plain_is_equal(const isl::pw_aff &upa2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->plain_is_equal(isl::union_pw_aff(upa2)); +} + +isl::union_pw_multi_aff union_pw_aff::preimage_domain_wrapped_domain(const isl::union_pw_multi_aff &upma2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_pw_multi_aff(*this).preimage_domain_wrapped_domain(upma2); +} + +isl::union_pw_aff union_pw_aff::pullback(isl::union_pw_multi_aff upma) const +{ + if (!ptr || upma.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_pw_aff_pullback_union_pw_multi_aff(copy(), upma.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::pw_multi_aff_list union_pw_aff::pw_multi_aff_list() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_pw_multi_aff(*this).pw_multi_aff_list(); +} + +isl::union_pw_multi_aff union_pw_aff::range_factor_domain() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_pw_multi_aff(*this).range_factor_domain(); +} + +isl::union_pw_multi_aff union_pw_aff::range_factor_range() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_pw_multi_aff(*this).range_factor_range(); +} + +isl::multi_union_pw_aff union_pw_aff::range_product(const isl::multi_union_pw_aff &multi2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::multi_union_pw_aff(*this).range_product(multi2); +} + +isl::union_pw_multi_aff union_pw_aff::range_product(const isl::union_pw_multi_aff &upma2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_pw_multi_aff(*this).range_product(upma2); +} + +isl::id union_pw_aff::range_tuple_id() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::multi_union_pw_aff(*this).range_tuple_id(); +} + +isl::multi_union_pw_aff union_pw_aff::reset_range_tuple_id() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::multi_union_pw_aff(*this).reset_range_tuple_id(); +} + +isl::multi_union_pw_aff union_pw_aff::scale(const isl::multi_val &mv) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::multi_union_pw_aff(*this).scale(mv); +} + +isl::multi_union_pw_aff union_pw_aff::scale(const isl::val &v) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::multi_union_pw_aff(*this).scale(v); +} + +isl::multi_union_pw_aff union_pw_aff::scale(long v) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->scale(isl::val(ctx(), v)); +} + +isl::multi_union_pw_aff union_pw_aff::scale_down(const isl::multi_val &mv) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::multi_union_pw_aff(*this).scale_down(mv); +} + +isl::multi_union_pw_aff union_pw_aff::scale_down(const isl::val &v) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::multi_union_pw_aff(*this).scale_down(v); +} + +isl::multi_union_pw_aff union_pw_aff::scale_down(long v) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->scale_down(isl::val(ctx(), v)); +} + +isl::multi_union_pw_aff union_pw_aff::set_at(int pos, const isl::union_pw_aff &el) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::multi_union_pw_aff(*this).set_at(pos, el); +} + +isl::multi_union_pw_aff union_pw_aff::set_range_tuple(const isl::id &id) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::multi_union_pw_aff(*this).set_range_tuple(id); +} + +isl::multi_union_pw_aff union_pw_aff::set_range_tuple(const std::string &id) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->set_range_tuple(isl::id(ctx(), id)); +} + +unsigned union_pw_aff::size() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::multi_union_pw_aff(*this).size(); +} + +isl::space union_pw_aff::space() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_pw_aff_get_space(get()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::space union_pw_aff::get_space() const +{ + return space(); +} + +isl::multi_union_pw_aff union_pw_aff::sub(const isl::multi_union_pw_aff &multi2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::multi_union_pw_aff(*this).sub(multi2); +} + +isl::union_pw_aff union_pw_aff::sub(isl::union_pw_aff upa2) const +{ + if (!ptr || upa2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_pw_aff_sub(copy(), upa2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_pw_multi_aff union_pw_aff::sub(const isl::union_pw_multi_aff &upma2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_pw_multi_aff(*this).sub(upma2); +} + +isl::union_pw_aff union_pw_aff::sub(const isl::aff &upa2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->sub(isl::union_pw_aff(upa2)); +} + +isl::union_pw_aff union_pw_aff::sub(const isl::pw_aff &upa2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->sub(isl::union_pw_aff(upa2)); +} + +isl::union_pw_aff union_pw_aff::subtract_domain(isl::space space) const +{ + if (!ptr || space.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_pw_aff_subtract_domain_space(copy(), space.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_pw_aff union_pw_aff::subtract_domain(isl::union_set uset) const +{ + if (!ptr || uset.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_pw_aff_subtract_domain_union_set(copy(), uset.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_pw_aff_list union_pw_aff::to_list() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_pw_aff_to_list(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_union_pw_aff union_pw_aff::union_add(const isl::multi_union_pw_aff &mupa2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::multi_union_pw_aff(*this).union_add(mupa2); +} + +isl::union_pw_aff union_pw_aff::union_add(isl::union_pw_aff upa2) const +{ + if (!ptr || upa2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_pw_aff_union_add(copy(), upa2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_pw_multi_aff union_pw_aff::union_add(const isl::union_pw_multi_aff &upma2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return isl::union_pw_multi_aff(*this).union_add(upma2); +} + +isl::union_pw_aff union_pw_aff::union_add(const isl::aff &upa2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->union_add(isl::union_pw_aff(upa2)); +} + +isl::union_pw_aff union_pw_aff::union_add(const isl::pw_aff &upa2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->union_add(isl::union_pw_aff(upa2)); +} + +inline std::ostream &operator<<(std::ostream &os, const union_pw_aff &obj) +{ + if (!obj.get()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_union_pw_aff_get_ctx(obj.get()); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + char *str = isl_union_pw_aff_to_str(obj.get()); + if (!str) + exception::throw_last_error(saved_ctx); + os << str; + free(str); + return os; +} + +// implementations for isl::union_pw_aff_list +union_pw_aff_list manage(__isl_take isl_union_pw_aff_list *ptr) { + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return union_pw_aff_list(ptr); +} +union_pw_aff_list manage_copy(__isl_keep isl_union_pw_aff_list *ptr) { + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_union_pw_aff_list_get_ctx(ptr); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + ptr = isl_union_pw_aff_list_copy(ptr); + if (!ptr) + exception::throw_last_error(saved_ctx); + return union_pw_aff_list(ptr); +} + +union_pw_aff_list::union_pw_aff_list(__isl_take isl_union_pw_aff_list *ptr) + : ptr(ptr) {} + +union_pw_aff_list::union_pw_aff_list() + : ptr(nullptr) {} + +union_pw_aff_list::union_pw_aff_list(const union_pw_aff_list &obj) + : ptr(nullptr) +{ + if (!obj.ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_union_pw_aff_list_get_ctx(obj.ptr); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + ptr = obj.copy(); + if (!ptr) + exception::throw_last_error(saved_ctx); +} + +union_pw_aff_list::union_pw_aff_list(isl::ctx ctx, int n) +{ + auto saved_ctx = ctx; + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_pw_aff_list_alloc(ctx.release(), n); + if (!res) + exception::throw_last_error(saved_ctx); + ptr = res; +} + +union_pw_aff_list::union_pw_aff_list(isl::union_pw_aff el) +{ + if (el.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = el.ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_pw_aff_list_from_union_pw_aff(el.release()); + if (!res) + exception::throw_last_error(saved_ctx); + ptr = res; +} + +union_pw_aff_list::union_pw_aff_list(isl::ctx ctx, const std::string &str) +{ + auto saved_ctx = ctx; + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_pw_aff_list_read_from_str(ctx.release(), str.c_str()); + if (!res) + exception::throw_last_error(saved_ctx); + ptr = res; +} + +union_pw_aff_list &union_pw_aff_list::operator=(union_pw_aff_list obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +union_pw_aff_list::~union_pw_aff_list() { + if (ptr) + isl_union_pw_aff_list_free(ptr); +} + +__isl_give isl_union_pw_aff_list *union_pw_aff_list::copy() const & { + return isl_union_pw_aff_list_copy(ptr); +} + +__isl_keep isl_union_pw_aff_list *union_pw_aff_list::get() const { + return ptr; +} + +__isl_give isl_union_pw_aff_list *union_pw_aff_list::release() { + isl_union_pw_aff_list *tmp = ptr; + ptr = nullptr; + return tmp; +} + +bool union_pw_aff_list::is_null() const { + return ptr == nullptr; +} + +isl::ctx union_pw_aff_list::ctx() const { + return isl::ctx(isl_union_pw_aff_list_get_ctx(ptr)); +} + +isl::union_pw_aff_list union_pw_aff_list::add(isl::union_pw_aff el) const +{ + if (!ptr || el.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_pw_aff_list_add(copy(), el.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_pw_aff union_pw_aff_list::at(int index) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_pw_aff_list_get_at(get(), index); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_pw_aff union_pw_aff_list::get_at(int index) const +{ + return at(index); +} + +isl::union_pw_aff_list union_pw_aff_list::clear() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_pw_aff_list_clear(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_pw_aff_list union_pw_aff_list::concat(isl::union_pw_aff_list list2) const +{ + if (!ptr || list2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_pw_aff_list_concat(copy(), list2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_pw_aff_list union_pw_aff_list::drop(unsigned int first, unsigned int n) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_pw_aff_list_drop(copy(), first, n); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +void union_pw_aff_list::foreach(const std::function &fn) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + struct fn_data { + std::function func; + std::exception_ptr eptr; + } fn_data = { fn }; + auto fn_lambda = [](isl_union_pw_aff *arg_0, void *arg_1) -> isl_stat { + auto *data = static_cast(arg_1); + ISL_CPP_TRY { + (data->func)(manage(arg_0)); + return isl_stat_ok; + } ISL_CPP_CATCH_ALL { + data->eptr = std::current_exception(); + return isl_stat_error; + } + }; + auto res = isl_union_pw_aff_list_foreach(get(), fn_lambda, &fn_data); + if (fn_data.eptr) + std::rethrow_exception(fn_data.eptr); + if (res < 0) + exception::throw_last_error(saved_ctx); + return; +} + +void union_pw_aff_list::foreach_scc(const std::function &follows, const std::function &fn) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + struct follows_data { + std::function func; + std::exception_ptr eptr; + } follows_data = { follows }; + auto follows_lambda = [](isl_union_pw_aff *arg_0, isl_union_pw_aff *arg_1, void *arg_2) -> isl_bool { + auto *data = static_cast(arg_2); + ISL_CPP_TRY { + auto ret = (data->func)(manage_copy(arg_0), manage_copy(arg_1)); + return ret ? isl_bool_true : isl_bool_false; + } ISL_CPP_CATCH_ALL { + data->eptr = std::current_exception(); + return isl_bool_error; + } + }; + struct fn_data { + std::function func; + std::exception_ptr eptr; + } fn_data = { fn }; + auto fn_lambda = [](isl_union_pw_aff_list *arg_0, void *arg_1) -> isl_stat { + auto *data = static_cast(arg_1); + ISL_CPP_TRY { + (data->func)(manage(arg_0)); + return isl_stat_ok; + } ISL_CPP_CATCH_ALL { + data->eptr = std::current_exception(); + return isl_stat_error; + } + }; + auto res = isl_union_pw_aff_list_foreach_scc(get(), follows_lambda, &follows_data, fn_lambda, &fn_data); + if (follows_data.eptr) + std::rethrow_exception(follows_data.eptr); + if (fn_data.eptr) + std::rethrow_exception(fn_data.eptr); + if (res < 0) + exception::throw_last_error(saved_ctx); + return; +} + +isl::union_pw_aff_list union_pw_aff_list::insert(unsigned int pos, isl::union_pw_aff el) const +{ + if (!ptr || el.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_pw_aff_list_insert(copy(), pos, el.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_pw_aff_list union_pw_aff_list::set_at(int index, isl::union_pw_aff el) const +{ + if (!ptr || el.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_pw_aff_list_set_at(copy(), index, el.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +unsigned union_pw_aff_list::size() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_pw_aff_list_size(get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +inline std::ostream &operator<<(std::ostream &os, const union_pw_aff_list &obj) +{ + if (!obj.get()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_union_pw_aff_list_get_ctx(obj.get()); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + char *str = isl_union_pw_aff_list_to_str(obj.get()); + if (!str) + exception::throw_last_error(saved_ctx); + os << str; + free(str); + return os; +} + +// implementations for isl::union_pw_multi_aff +union_pw_multi_aff manage(__isl_take isl_union_pw_multi_aff *ptr) { + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return union_pw_multi_aff(ptr); +} +union_pw_multi_aff manage_copy(__isl_keep isl_union_pw_multi_aff *ptr) { + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_union_pw_multi_aff_get_ctx(ptr); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + ptr = isl_union_pw_multi_aff_copy(ptr); + if (!ptr) + exception::throw_last_error(saved_ctx); + return union_pw_multi_aff(ptr); +} + +union_pw_multi_aff::union_pw_multi_aff(__isl_take isl_union_pw_multi_aff *ptr) + : ptr(ptr) {} + +union_pw_multi_aff::union_pw_multi_aff() + : ptr(nullptr) {} + +union_pw_multi_aff::union_pw_multi_aff(const union_pw_multi_aff &obj) + : ptr(nullptr) +{ + if (!obj.ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_union_pw_multi_aff_get_ctx(obj.ptr); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + ptr = obj.copy(); + if (!ptr) + exception::throw_last_error(saved_ctx); +} + +union_pw_multi_aff::union_pw_multi_aff(isl::multi_aff ma) +{ + if (ma.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ma.ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_pw_multi_aff_from_multi_aff(ma.release()); + if (!res) + exception::throw_last_error(saved_ctx); + ptr = res; +} + +union_pw_multi_aff::union_pw_multi_aff(isl::pw_multi_aff pma) +{ + if (pma.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = pma.ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_pw_multi_aff_from_pw_multi_aff(pma.release()); + if (!res) + exception::throw_last_error(saved_ctx); + ptr = res; +} + +union_pw_multi_aff::union_pw_multi_aff(isl::union_pw_aff upa) +{ + if (upa.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = upa.ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_pw_multi_aff_from_union_pw_aff(upa.release()); + if (!res) + exception::throw_last_error(saved_ctx); + ptr = res; +} + +union_pw_multi_aff::union_pw_multi_aff(isl::ctx ctx, const std::string &str) +{ + auto saved_ctx = ctx; + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_pw_multi_aff_read_from_str(ctx.release(), str.c_str()); + if (!res) + exception::throw_last_error(saved_ctx); + ptr = res; +} + +union_pw_multi_aff &union_pw_multi_aff::operator=(union_pw_multi_aff obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +union_pw_multi_aff::~union_pw_multi_aff() { + if (ptr) + isl_union_pw_multi_aff_free(ptr); +} + +__isl_give isl_union_pw_multi_aff *union_pw_multi_aff::copy() const & { + return isl_union_pw_multi_aff_copy(ptr); +} + +__isl_keep isl_union_pw_multi_aff *union_pw_multi_aff::get() const { + return ptr; +} + +__isl_give isl_union_pw_multi_aff *union_pw_multi_aff::release() { + isl_union_pw_multi_aff *tmp = ptr; + ptr = nullptr; + return tmp; +} + +bool union_pw_multi_aff::is_null() const { + return ptr == nullptr; +} + +isl::ctx union_pw_multi_aff::ctx() const { + return isl::ctx(isl_union_pw_multi_aff_get_ctx(ptr)); +} + +isl::union_pw_multi_aff union_pw_multi_aff::add(isl::union_pw_multi_aff upma2) const +{ + if (!ptr || upma2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_pw_multi_aff_add(copy(), upma2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_pw_multi_aff union_pw_multi_aff::apply(isl::union_pw_multi_aff upma2) const +{ + if (!ptr || upma2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_pw_multi_aff_apply_union_pw_multi_aff(copy(), upma2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::multi_union_pw_aff union_pw_multi_aff::as_multi_union_pw_aff() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_pw_multi_aff_as_multi_union_pw_aff(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::pw_multi_aff union_pw_multi_aff::as_pw_multi_aff() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_pw_multi_aff_as_pw_multi_aff(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map union_pw_multi_aff::as_union_map() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_pw_multi_aff_as_union_map(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_pw_multi_aff union_pw_multi_aff::coalesce() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_pw_multi_aff_coalesce(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_set union_pw_multi_aff::domain() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_pw_multi_aff_domain(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_pw_multi_aff union_pw_multi_aff::drop_unused_params() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_pw_multi_aff_drop_unused_params(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_pw_multi_aff union_pw_multi_aff::empty(isl::ctx ctx) +{ + auto saved_ctx = ctx; + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_pw_multi_aff_empty_ctx(ctx.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::pw_multi_aff union_pw_multi_aff::extract_pw_multi_aff(isl::space space) const +{ + if (!ptr || space.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_pw_multi_aff_extract_pw_multi_aff(get(), space.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_pw_multi_aff union_pw_multi_aff::flat_range_product(isl::union_pw_multi_aff upma2) const +{ + if (!ptr || upma2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_pw_multi_aff_flat_range_product(copy(), upma2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_pw_multi_aff union_pw_multi_aff::gist(isl::union_set context) const +{ + if (!ptr || context.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_pw_multi_aff_gist(copy(), context.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_pw_multi_aff union_pw_multi_aff::intersect_domain(isl::space space) const +{ + if (!ptr || space.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_pw_multi_aff_intersect_domain_space(copy(), space.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_pw_multi_aff union_pw_multi_aff::intersect_domain(isl::union_set uset) const +{ + if (!ptr || uset.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_pw_multi_aff_intersect_domain_union_set(copy(), uset.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_pw_multi_aff union_pw_multi_aff::intersect_domain_wrapped_domain(isl::union_set uset) const +{ + if (!ptr || uset.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_pw_multi_aff_intersect_domain_wrapped_domain(copy(), uset.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_pw_multi_aff union_pw_multi_aff::intersect_domain_wrapped_range(isl::union_set uset) const +{ + if (!ptr || uset.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_pw_multi_aff_intersect_domain_wrapped_range(copy(), uset.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_pw_multi_aff union_pw_multi_aff::intersect_params(isl::set set) const +{ + if (!ptr || set.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_pw_multi_aff_intersect_params(copy(), set.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +bool union_pw_multi_aff::involves_locals() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_pw_multi_aff_involves_locals(get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +bool union_pw_multi_aff::isa_pw_multi_aff() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_pw_multi_aff_isa_pw_multi_aff(get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +bool union_pw_multi_aff::plain_is_empty() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_pw_multi_aff_plain_is_empty(get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +bool union_pw_multi_aff::plain_is_equal(const isl::union_pw_multi_aff &upma2) const +{ + if (!ptr || upma2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_pw_multi_aff_plain_is_equal(get(), upma2.get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +isl::union_pw_multi_aff union_pw_multi_aff::preimage_domain_wrapped_domain(isl::union_pw_multi_aff upma2) const +{ + if (!ptr || upma2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_pw_multi_aff_preimage_domain_wrapped_domain_union_pw_multi_aff(copy(), upma2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_pw_multi_aff union_pw_multi_aff::pullback(isl::union_pw_multi_aff upma2) const +{ + if (!ptr || upma2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_pw_multi_aff_pullback_union_pw_multi_aff(copy(), upma2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::pw_multi_aff_list union_pw_multi_aff::pw_multi_aff_list() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_pw_multi_aff_get_pw_multi_aff_list(get()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::pw_multi_aff_list union_pw_multi_aff::get_pw_multi_aff_list() const +{ + return pw_multi_aff_list(); +} + +isl::union_pw_multi_aff union_pw_multi_aff::range_factor_domain() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_pw_multi_aff_range_factor_domain(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_pw_multi_aff union_pw_multi_aff::range_factor_range() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_pw_multi_aff_range_factor_range(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_pw_multi_aff union_pw_multi_aff::range_product(isl::union_pw_multi_aff upma2) const +{ + if (!ptr || upma2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_pw_multi_aff_range_product(copy(), upma2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::space union_pw_multi_aff::space() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_pw_multi_aff_get_space(get()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::space union_pw_multi_aff::get_space() const +{ + return space(); +} + +isl::union_pw_multi_aff union_pw_multi_aff::sub(isl::union_pw_multi_aff upma2) const +{ + if (!ptr || upma2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_pw_multi_aff_sub(copy(), upma2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_pw_multi_aff union_pw_multi_aff::subtract_domain(isl::space space) const +{ + if (!ptr || space.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_pw_multi_aff_subtract_domain_space(copy(), space.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_pw_multi_aff union_pw_multi_aff::subtract_domain(isl::union_set uset) const +{ + if (!ptr || uset.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_pw_multi_aff_subtract_domain_union_set(copy(), uset.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_pw_multi_aff union_pw_multi_aff::union_add(isl::union_pw_multi_aff upma2) const +{ + if (!ptr || upma2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_pw_multi_aff_union_add(copy(), upma2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +inline std::ostream &operator<<(std::ostream &os, const union_pw_multi_aff &obj) +{ + if (!obj.get()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_union_pw_multi_aff_get_ctx(obj.get()); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + char *str = isl_union_pw_multi_aff_to_str(obj.get()); + if (!str) + exception::throw_last_error(saved_ctx); + os << str; + free(str); + return os; +} + +// implementations for isl::union_set +union_set manage(__isl_take isl_union_set *ptr) { + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return union_set(ptr); +} +union_set manage_copy(__isl_keep isl_union_set *ptr) { + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_union_set_get_ctx(ptr); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + ptr = isl_union_set_copy(ptr); + if (!ptr) + exception::throw_last_error(saved_ctx); + return union_set(ptr); +} + +union_set::union_set(__isl_take isl_union_set *ptr) + : ptr(ptr) {} + +union_set::union_set() + : ptr(nullptr) {} + +union_set::union_set(const union_set &obj) + : ptr(nullptr) +{ + if (!obj.ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_union_set_get_ctx(obj.ptr); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + ptr = obj.copy(); + if (!ptr) + exception::throw_last_error(saved_ctx); +} + +union_set::union_set(isl::basic_set bset) +{ + if (bset.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = bset.ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_set_from_basic_set(bset.release()); + if (!res) + exception::throw_last_error(saved_ctx); + ptr = res; +} + +union_set::union_set(isl::point pnt) +{ + if (pnt.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = pnt.ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_set_from_point(pnt.release()); + if (!res) + exception::throw_last_error(saved_ctx); + ptr = res; +} + +union_set::union_set(isl::set set) +{ + if (set.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = set.ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_set_from_set(set.release()); + if (!res) + exception::throw_last_error(saved_ctx); + ptr = res; +} + +union_set::union_set(isl::ctx ctx, const std::string &str) +{ + auto saved_ctx = ctx; + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_set_read_from_str(ctx.release(), str.c_str()); + if (!res) + exception::throw_last_error(saved_ctx); + ptr = res; +} + +union_set &union_set::operator=(union_set obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +union_set::~union_set() { + if (ptr) + isl_union_set_free(ptr); +} + +__isl_give isl_union_set *union_set::copy() const & { + return isl_union_set_copy(ptr); +} + +__isl_keep isl_union_set *union_set::get() const { + return ptr; +} + +__isl_give isl_union_set *union_set::release() { + isl_union_set *tmp = ptr; + ptr = nullptr; + return tmp; +} + +bool union_set::is_null() const { + return ptr == nullptr; +} + +isl::ctx union_set::ctx() const { + return isl::ctx(isl_union_set_get_ctx(ptr)); +} + +isl::union_set union_set::affine_hull() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_set_affine_hull(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_set union_set::apply(isl::union_map umap) const +{ + if (!ptr || umap.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_set_apply(copy(), umap.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::set union_set::as_set() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_set_as_set(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_set union_set::coalesce() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_set_coalesce(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_set union_set::compute_divs() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_set_compute_divs(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_set union_set::detect_equalities() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_set_detect_equalities(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_set union_set::drop_unused_params() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_set_drop_unused_params(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_set union_set::empty(isl::ctx ctx) +{ + auto saved_ctx = ctx; + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_set_empty_ctx(ctx.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +bool union_set::every_set(const std::function &test) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + struct test_data { + std::function func; + std::exception_ptr eptr; + } test_data = { test }; + auto test_lambda = [](isl_set *arg_0, void *arg_1) -> isl_bool { + auto *data = static_cast(arg_1); + ISL_CPP_TRY { + auto ret = (data->func)(manage_copy(arg_0)); + return ret ? isl_bool_true : isl_bool_false; + } ISL_CPP_CATCH_ALL { + data->eptr = std::current_exception(); + return isl_bool_error; + } + }; + auto res = isl_union_set_every_set(get(), test_lambda, &test_data); + if (test_data.eptr) + std::rethrow_exception(test_data.eptr); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +isl::set union_set::extract_set(isl::space space) const +{ + if (!ptr || space.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_set_extract_set(get(), space.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +void union_set::foreach_point(const std::function &fn) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + struct fn_data { + std::function func; + std::exception_ptr eptr; + } fn_data = { fn }; + auto fn_lambda = [](isl_point *arg_0, void *arg_1) -> isl_stat { + auto *data = static_cast(arg_1); + ISL_CPP_TRY { + (data->func)(manage(arg_0)); + return isl_stat_ok; + } ISL_CPP_CATCH_ALL { + data->eptr = std::current_exception(); + return isl_stat_error; + } + }; + auto res = isl_union_set_foreach_point(get(), fn_lambda, &fn_data); + if (fn_data.eptr) + std::rethrow_exception(fn_data.eptr); + if (res < 0) + exception::throw_last_error(saved_ctx); + return; +} + +void union_set::foreach_set(const std::function &fn) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + struct fn_data { + std::function func; + std::exception_ptr eptr; + } fn_data = { fn }; + auto fn_lambda = [](isl_set *arg_0, void *arg_1) -> isl_stat { + auto *data = static_cast(arg_1); + ISL_CPP_TRY { + (data->func)(manage(arg_0)); + return isl_stat_ok; + } ISL_CPP_CATCH_ALL { + data->eptr = std::current_exception(); + return isl_stat_error; + } + }; + auto res = isl_union_set_foreach_set(get(), fn_lambda, &fn_data); + if (fn_data.eptr) + std::rethrow_exception(fn_data.eptr); + if (res < 0) + exception::throw_last_error(saved_ctx); + return; +} + +isl::union_set union_set::gist(isl::union_set context) const +{ + if (!ptr || context.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_set_gist(copy(), context.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_set union_set::gist_params(isl::set set) const +{ + if (!ptr || set.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_set_gist_params(copy(), set.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map union_set::identity() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_set_identity(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_set union_set::intersect(isl::union_set uset2) const +{ + if (!ptr || uset2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_set_intersect(copy(), uset2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_set union_set::intersect_params(isl::set set) const +{ + if (!ptr || set.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_set_intersect_params(copy(), set.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +bool union_set::is_disjoint(const isl::union_set &uset2) const +{ + if (!ptr || uset2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_set_is_disjoint(get(), uset2.get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +bool union_set::is_empty() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_set_is_empty(get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +bool union_set::is_equal(const isl::union_set &uset2) const +{ + if (!ptr || uset2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_set_is_equal(get(), uset2.get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +bool union_set::is_strict_subset(const isl::union_set &uset2) const +{ + if (!ptr || uset2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_set_is_strict_subset(get(), uset2.get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +bool union_set::is_subset(const isl::union_set &uset2) const +{ + if (!ptr || uset2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_set_is_subset(get(), uset2.get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +bool union_set::isa_set() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_set_isa_set(get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +isl::union_set union_set::lexmax() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_set_lexmax(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_set union_set::lexmin() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_set_lexmin(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::set union_set::params() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_set_params(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_set union_set::polyhedral_hull() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_set_polyhedral_hull(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_set union_set::preimage(isl::multi_aff ma) const +{ + if (!ptr || ma.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_set_preimage_multi_aff(copy(), ma.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_set union_set::preimage(isl::pw_multi_aff pma) const +{ + if (!ptr || pma.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_set_preimage_pw_multi_aff(copy(), pma.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_set union_set::preimage(isl::union_pw_multi_aff upma) const +{ + if (!ptr || upma.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_set_preimage_union_pw_multi_aff(copy(), upma.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_set union_set::project_out_all_params() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_set_project_out_all_params(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::point union_set::sample_point() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_set_sample_point(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::set_list union_set::set_list() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_set_get_set_list(get()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::set_list union_set::get_set_list() const +{ + return set_list(); +} + +isl::space union_set::space() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_set_get_space(get()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::space union_set::get_space() const +{ + return space(); +} + +isl::union_set union_set::subtract(isl::union_set uset2) const +{ + if (!ptr || uset2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_set_subtract(copy(), uset2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_set_list union_set::to_list() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_set_to_list(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_set union_set::unite(isl::union_set uset2) const +{ + if (!ptr || uset2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_set_union(copy(), uset2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_set union_set::universe() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_set_universe(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_map union_set::unwrap() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_set_unwrap(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +inline std::ostream &operator<<(std::ostream &os, const union_set &obj) +{ + if (!obj.get()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_union_set_get_ctx(obj.get()); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + char *str = isl_union_set_to_str(obj.get()); + if (!str) + exception::throw_last_error(saved_ctx); + os << str; + free(str); + return os; +} + +// implementations for isl::union_set_list +union_set_list manage(__isl_take isl_union_set_list *ptr) { + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return union_set_list(ptr); +} +union_set_list manage_copy(__isl_keep isl_union_set_list *ptr) { + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_union_set_list_get_ctx(ptr); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + ptr = isl_union_set_list_copy(ptr); + if (!ptr) + exception::throw_last_error(saved_ctx); + return union_set_list(ptr); +} + +union_set_list::union_set_list(__isl_take isl_union_set_list *ptr) + : ptr(ptr) {} + +union_set_list::union_set_list() + : ptr(nullptr) {} + +union_set_list::union_set_list(const union_set_list &obj) + : ptr(nullptr) +{ + if (!obj.ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_union_set_list_get_ctx(obj.ptr); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + ptr = obj.copy(); + if (!ptr) + exception::throw_last_error(saved_ctx); +} + +union_set_list::union_set_list(isl::ctx ctx, int n) +{ + auto saved_ctx = ctx; + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_set_list_alloc(ctx.release(), n); + if (!res) + exception::throw_last_error(saved_ctx); + ptr = res; +} + +union_set_list::union_set_list(isl::union_set el) +{ + if (el.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = el.ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_set_list_from_union_set(el.release()); + if (!res) + exception::throw_last_error(saved_ctx); + ptr = res; +} + +union_set_list::union_set_list(isl::ctx ctx, const std::string &str) +{ + auto saved_ctx = ctx; + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_set_list_read_from_str(ctx.release(), str.c_str()); + if (!res) + exception::throw_last_error(saved_ctx); + ptr = res; +} + +union_set_list &union_set_list::operator=(union_set_list obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +union_set_list::~union_set_list() { + if (ptr) + isl_union_set_list_free(ptr); +} + +__isl_give isl_union_set_list *union_set_list::copy() const & { + return isl_union_set_list_copy(ptr); +} + +__isl_keep isl_union_set_list *union_set_list::get() const { + return ptr; +} + +__isl_give isl_union_set_list *union_set_list::release() { + isl_union_set_list *tmp = ptr; + ptr = nullptr; + return tmp; +} + +bool union_set_list::is_null() const { + return ptr == nullptr; +} + +isl::ctx union_set_list::ctx() const { + return isl::ctx(isl_union_set_list_get_ctx(ptr)); +} + +isl::union_set_list union_set_list::add(isl::union_set el) const +{ + if (!ptr || el.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_set_list_add(copy(), el.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_set union_set_list::at(int index) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_set_list_get_at(get(), index); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_set union_set_list::get_at(int index) const +{ + return at(index); +} + +isl::union_set_list union_set_list::clear() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_set_list_clear(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_set_list union_set_list::concat(isl::union_set_list list2) const +{ + if (!ptr || list2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_set_list_concat(copy(), list2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_set_list union_set_list::drop(unsigned int first, unsigned int n) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_set_list_drop(copy(), first, n); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +void union_set_list::foreach(const std::function &fn) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + struct fn_data { + std::function func; + std::exception_ptr eptr; + } fn_data = { fn }; + auto fn_lambda = [](isl_union_set *arg_0, void *arg_1) -> isl_stat { + auto *data = static_cast(arg_1); + ISL_CPP_TRY { + (data->func)(manage(arg_0)); + return isl_stat_ok; + } ISL_CPP_CATCH_ALL { + data->eptr = std::current_exception(); + return isl_stat_error; + } + }; + auto res = isl_union_set_list_foreach(get(), fn_lambda, &fn_data); + if (fn_data.eptr) + std::rethrow_exception(fn_data.eptr); + if (res < 0) + exception::throw_last_error(saved_ctx); + return; +} + +void union_set_list::foreach_scc(const std::function &follows, const std::function &fn) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + struct follows_data { + std::function func; + std::exception_ptr eptr; + } follows_data = { follows }; + auto follows_lambda = [](isl_union_set *arg_0, isl_union_set *arg_1, void *arg_2) -> isl_bool { + auto *data = static_cast(arg_2); + ISL_CPP_TRY { + auto ret = (data->func)(manage_copy(arg_0), manage_copy(arg_1)); + return ret ? isl_bool_true : isl_bool_false; + } ISL_CPP_CATCH_ALL { + data->eptr = std::current_exception(); + return isl_bool_error; + } + }; + struct fn_data { + std::function func; + std::exception_ptr eptr; + } fn_data = { fn }; + auto fn_lambda = [](isl_union_set_list *arg_0, void *arg_1) -> isl_stat { + auto *data = static_cast(arg_1); + ISL_CPP_TRY { + (data->func)(manage(arg_0)); + return isl_stat_ok; + } ISL_CPP_CATCH_ALL { + data->eptr = std::current_exception(); + return isl_stat_error; + } + }; + auto res = isl_union_set_list_foreach_scc(get(), follows_lambda, &follows_data, fn_lambda, &fn_data); + if (follows_data.eptr) + std::rethrow_exception(follows_data.eptr); + if (fn_data.eptr) + std::rethrow_exception(fn_data.eptr); + if (res < 0) + exception::throw_last_error(saved_ctx); + return; +} + +isl::union_set_list union_set_list::insert(unsigned int pos, isl::union_set el) const +{ + if (!ptr || el.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_set_list_insert(copy(), pos, el.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::union_set_list union_set_list::set_at(int index, isl::union_set el) const +{ + if (!ptr || el.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_set_list_set_at(copy(), index, el.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +unsigned union_set_list::size() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_union_set_list_size(get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +inline std::ostream &operator<<(std::ostream &os, const union_set_list &obj) +{ + if (!obj.get()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_union_set_list_get_ctx(obj.get()); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + char *str = isl_union_set_list_to_str(obj.get()); + if (!str) + exception::throw_last_error(saved_ctx); + os << str; + free(str); + return os; +} + +// implementations for isl::val +val manage(__isl_take isl_val *ptr) { + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return val(ptr); +} +val manage_copy(__isl_keep isl_val *ptr) { + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_val_get_ctx(ptr); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + ptr = isl_val_copy(ptr); + if (!ptr) + exception::throw_last_error(saved_ctx); + return val(ptr); +} + +val::val(__isl_take isl_val *ptr) + : ptr(ptr) {} + +val::val() + : ptr(nullptr) {} + +val::val(const val &obj) + : ptr(nullptr) +{ + if (!obj.ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_val_get_ctx(obj.ptr); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + ptr = obj.copy(); + if (!ptr) + exception::throw_last_error(saved_ctx); +} + +val::val(isl::ctx ctx, long i) +{ + auto saved_ctx = ctx; + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_val_int_from_si(ctx.release(), i); + if (!res) + exception::throw_last_error(saved_ctx); + ptr = res; +} + +val::val(isl::ctx ctx, const std::string &str) +{ + auto saved_ctx = ctx; + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_val_read_from_str(ctx.release(), str.c_str()); + if (!res) + exception::throw_last_error(saved_ctx); + ptr = res; +} + +val &val::operator=(val obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +val::~val() { + if (ptr) + isl_val_free(ptr); +} + +__isl_give isl_val *val::copy() const & { + return isl_val_copy(ptr); +} + +__isl_keep isl_val *val::get() const { + return ptr; +} + +__isl_give isl_val *val::release() { + isl_val *tmp = ptr; + ptr = nullptr; + return tmp; +} + +bool val::is_null() const { + return ptr == nullptr; +} + +isl::ctx val::ctx() const { + return isl::ctx(isl_val_get_ctx(ptr)); +} + +isl::val val::abs() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_val_abs(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +bool val::abs_eq(const isl::val &v2) const +{ + if (!ptr || v2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_val_abs_eq(get(), v2.get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +bool val::abs_eq(long v2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->abs_eq(isl::val(ctx(), v2)); +} + +isl::val val::add(isl::val v2) const +{ + if (!ptr || v2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_val_add(copy(), v2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::val val::add(long v2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->add(isl::val(ctx(), v2)); +} + +isl::val val::ceil() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_val_ceil(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +int val::cmp_si(long i) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_val_cmp_si(get(), i); + return res; +} + +long val::den_si() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_val_get_den_si(get()); + return res; +} + +long val::get_den_si() const +{ + return den_si(); +} + +isl::val val::div(isl::val v2) const +{ + if (!ptr || v2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_val_div(copy(), v2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::val val::div(long v2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->div(isl::val(ctx(), v2)); +} + +bool val::eq(const isl::val &v2) const +{ + if (!ptr || v2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_val_eq(get(), v2.get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +bool val::eq(long v2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->eq(isl::val(ctx(), v2)); +} + +isl::val val::floor() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_val_floor(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::val val::gcd(isl::val v2) const +{ + if (!ptr || v2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_val_gcd(copy(), v2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::val val::gcd(long v2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->gcd(isl::val(ctx(), v2)); +} + +bool val::ge(const isl::val &v2) const +{ + if (!ptr || v2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_val_ge(get(), v2.get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +bool val::ge(long v2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->ge(isl::val(ctx(), v2)); +} + +bool val::gt(const isl::val &v2) const +{ + if (!ptr || v2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_val_gt(get(), v2.get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +bool val::gt(long v2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->gt(isl::val(ctx(), v2)); +} + +isl::val val::infty(isl::ctx ctx) +{ + auto saved_ctx = ctx; + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_val_infty(ctx.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::val val::inv() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_val_inv(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +bool val::is_divisible_by(const isl::val &v2) const +{ + if (!ptr || v2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_val_is_divisible_by(get(), v2.get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +bool val::is_divisible_by(long v2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->is_divisible_by(isl::val(ctx(), v2)); +} + +bool val::is_infty() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_val_is_infty(get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +bool val::is_int() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_val_is_int(get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +bool val::is_nan() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_val_is_nan(get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +bool val::is_neg() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_val_is_neg(get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +bool val::is_neginfty() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_val_is_neginfty(get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +bool val::is_negone() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_val_is_negone(get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +bool val::is_nonneg() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_val_is_nonneg(get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +bool val::is_nonpos() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_val_is_nonpos(get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +bool val::is_one() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_val_is_one(get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +bool val::is_pos() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_val_is_pos(get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +bool val::is_rat() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_val_is_rat(get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +bool val::is_zero() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_val_is_zero(get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +bool val::le(const isl::val &v2) const +{ + if (!ptr || v2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_val_le(get(), v2.get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +bool val::le(long v2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->le(isl::val(ctx(), v2)); +} + +bool val::lt(const isl::val &v2) const +{ + if (!ptr || v2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_val_lt(get(), v2.get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +bool val::lt(long v2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->lt(isl::val(ctx(), v2)); +} + +isl::val val::max(isl::val v2) const +{ + if (!ptr || v2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_val_max(copy(), v2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::val val::max(long v2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->max(isl::val(ctx(), v2)); +} + +isl::val val::min(isl::val v2) const +{ + if (!ptr || v2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_val_min(copy(), v2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::val val::min(long v2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->min(isl::val(ctx(), v2)); +} + +isl::val val::mod(isl::val v2) const +{ + if (!ptr || v2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_val_mod(copy(), v2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::val val::mod(long v2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->mod(isl::val(ctx(), v2)); +} + +isl::val val::mul(isl::val v2) const +{ + if (!ptr || v2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_val_mul(copy(), v2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::val val::mul(long v2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->mul(isl::val(ctx(), v2)); +} + +isl::val val::nan(isl::ctx ctx) +{ + auto saved_ctx = ctx; + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_val_nan(ctx.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +bool val::ne(const isl::val &v2) const +{ + if (!ptr || v2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_val_ne(get(), v2.get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +bool val::ne(long v2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->ne(isl::val(ctx(), v2)); +} + +isl::val val::neg() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_val_neg(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::val val::neginfty(isl::ctx ctx) +{ + auto saved_ctx = ctx; + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_val_neginfty(ctx.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::val val::negone(isl::ctx ctx) +{ + auto saved_ctx = ctx; + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_val_negone(ctx.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +long val::num_si() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_val_get_num_si(get()); + return res; +} + +long val::get_num_si() const +{ + return num_si(); +} + +isl::val val::one(isl::ctx ctx) +{ + auto saved_ctx = ctx; + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_val_one(ctx.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::val val::pow2() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_val_pow2(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +int val::sgn() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_val_sgn(get()); + return res; +} + +isl::val val::sub(isl::val v2) const +{ + if (!ptr || v2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_val_sub(copy(), v2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::val val::sub(long v2) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->sub(isl::val(ctx(), v2)); +} + +isl::val_list val::to_list() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_val_to_list(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::val val::trunc() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_val_trunc(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::val val::zero(isl::ctx ctx) +{ + auto saved_ctx = ctx; + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_val_zero(ctx.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +inline std::ostream &operator<<(std::ostream &os, const val &obj) +{ + if (!obj.get()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_val_get_ctx(obj.get()); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + char *str = isl_val_to_str(obj.get()); + if (!str) + exception::throw_last_error(saved_ctx); + os << str; + free(str); + return os; +} + +// implementations for isl::val_list +val_list manage(__isl_take isl_val_list *ptr) { + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return val_list(ptr); +} +val_list manage_copy(__isl_keep isl_val_list *ptr) { + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_val_list_get_ctx(ptr); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + ptr = isl_val_list_copy(ptr); + if (!ptr) + exception::throw_last_error(saved_ctx); + return val_list(ptr); +} + +val_list::val_list(__isl_take isl_val_list *ptr) + : ptr(ptr) {} + +val_list::val_list() + : ptr(nullptr) {} + +val_list::val_list(const val_list &obj) + : ptr(nullptr) +{ + if (!obj.ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_val_list_get_ctx(obj.ptr); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + ptr = obj.copy(); + if (!ptr) + exception::throw_last_error(saved_ctx); +} + +val_list::val_list(isl::ctx ctx, int n) +{ + auto saved_ctx = ctx; + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_val_list_alloc(ctx.release(), n); + if (!res) + exception::throw_last_error(saved_ctx); + ptr = res; +} + +val_list::val_list(isl::val el) +{ + if (el.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = el.ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_val_list_from_val(el.release()); + if (!res) + exception::throw_last_error(saved_ctx); + ptr = res; +} + +val_list::val_list(isl::ctx ctx, const std::string &str) +{ + auto saved_ctx = ctx; + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_val_list_read_from_str(ctx.release(), str.c_str()); + if (!res) + exception::throw_last_error(saved_ctx); + ptr = res; +} + +val_list &val_list::operator=(val_list obj) { + std::swap(this->ptr, obj.ptr); + return *this; +} + +val_list::~val_list() { + if (ptr) + isl_val_list_free(ptr); +} + +__isl_give isl_val_list *val_list::copy() const & { + return isl_val_list_copy(ptr); +} + +__isl_keep isl_val_list *val_list::get() const { + return ptr; +} + +__isl_give isl_val_list *val_list::release() { + isl_val_list *tmp = ptr; + ptr = nullptr; + return tmp; +} + +bool val_list::is_null() const { + return ptr == nullptr; +} + +isl::ctx val_list::ctx() const { + return isl::ctx(isl_val_list_get_ctx(ptr)); +} + +isl::val_list val_list::add(isl::val el) const +{ + if (!ptr || el.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_val_list_add(copy(), el.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::val_list val_list::add(long el) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->add(isl::val(ctx(), el)); +} + +isl::val val_list::at(int index) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_val_list_get_at(get(), index); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::val val_list::get_at(int index) const +{ + return at(index); +} + +isl::val_list val_list::clear() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_val_list_clear(copy()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::val_list val_list::concat(isl::val_list list2) const +{ + if (!ptr || list2.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_val_list_concat(copy(), list2.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::val_list val_list::drop(unsigned int first, unsigned int n) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_val_list_drop(copy(), first, n); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +void val_list::foreach(const std::function &fn) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + struct fn_data { + std::function func; + std::exception_ptr eptr; + } fn_data = { fn }; + auto fn_lambda = [](isl_val *arg_0, void *arg_1) -> isl_stat { + auto *data = static_cast(arg_1); + ISL_CPP_TRY { + (data->func)(manage(arg_0)); + return isl_stat_ok; + } ISL_CPP_CATCH_ALL { + data->eptr = std::current_exception(); + return isl_stat_error; + } + }; + auto res = isl_val_list_foreach(get(), fn_lambda, &fn_data); + if (fn_data.eptr) + std::rethrow_exception(fn_data.eptr); + if (res < 0) + exception::throw_last_error(saved_ctx); + return; +} + +void val_list::foreach_scc(const std::function &follows, const std::function &fn) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + struct follows_data { + std::function func; + std::exception_ptr eptr; + } follows_data = { follows }; + auto follows_lambda = [](isl_val *arg_0, isl_val *arg_1, void *arg_2) -> isl_bool { + auto *data = static_cast(arg_2); + ISL_CPP_TRY { + auto ret = (data->func)(manage_copy(arg_0), manage_copy(arg_1)); + return ret ? isl_bool_true : isl_bool_false; + } ISL_CPP_CATCH_ALL { + data->eptr = std::current_exception(); + return isl_bool_error; + } + }; + struct fn_data { + std::function func; + std::exception_ptr eptr; + } fn_data = { fn }; + auto fn_lambda = [](isl_val_list *arg_0, void *arg_1) -> isl_stat { + auto *data = static_cast(arg_1); + ISL_CPP_TRY { + (data->func)(manage(arg_0)); + return isl_stat_ok; + } ISL_CPP_CATCH_ALL { + data->eptr = std::current_exception(); + return isl_stat_error; + } + }; + auto res = isl_val_list_foreach_scc(get(), follows_lambda, &follows_data, fn_lambda, &fn_data); + if (follows_data.eptr) + std::rethrow_exception(follows_data.eptr); + if (fn_data.eptr) + std::rethrow_exception(fn_data.eptr); + if (res < 0) + exception::throw_last_error(saved_ctx); + return; +} + +isl::val_list val_list::insert(unsigned int pos, isl::val el) const +{ + if (!ptr || el.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_val_list_insert(copy(), pos, el.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::val_list val_list::insert(unsigned int pos, long el) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->insert(pos, isl::val(ctx(), el)); +} + +isl::val_list val_list::set_at(int index, isl::val el) const +{ + if (!ptr || el.is_null()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_val_list_set_at(copy(), index, el.release()); + if (!res) + exception::throw_last_error(saved_ctx); + return manage(res); +} + +isl::val_list val_list::set_at(int index, long el) const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + return this->set_at(index, isl::val(ctx(), el)); +} + +unsigned val_list::size() const +{ + if (!ptr) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = ctx(); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + auto res = isl_val_list_size(get()); + if (res < 0) + exception::throw_last_error(saved_ctx); + return res; +} + +inline std::ostream &operator<<(std::ostream &os, const val_list &obj) +{ + if (!obj.get()) + exception::throw_invalid("NULL input", __FILE__, __LINE__); + auto saved_ctx = isl_val_list_get_ctx(obj.get()); + options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error); + char *str = isl_val_list_to_str(obj.get()); + if (!str) + exception::throw_last_error(saved_ctx); + os << str; + free(str); + return os; +} +} // namespace isl + +#endif /* ISL_CPP */ diff --git a/external/mit/isl/dist/include/isl/ctx.h b/external/mit/isl/dist/include/isl/ctx.h new file mode 100644 index 000000000000..ecd9272e4efa --- /dev/null +++ b/external/mit/isl/dist/include/isl/ctx.h @@ -0,0 +1,265 @@ +/* + * 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_CTX_H +#define ISL_CTX_H + +#include +#include + +#include + +#ifndef __isl_give +#define __isl_give +#endif +#ifndef __isl_take +#define __isl_take +#endif +#ifndef __isl_keep +#define __isl_keep +#endif +#ifndef __isl_null +#define __isl_null +#endif +#ifndef __isl_export +#define __isl_export +#endif +#ifndef __isl_overload +#define __isl_overload +#endif +#ifndef __isl_constructor +#define __isl_constructor +#endif +#ifndef __isl_subclass +#define __isl_subclass(super) +#endif + +#if defined(__cplusplus) +extern "C" { +#endif + +/* Nearly all isa functions require a struct isl_ctx allocated using + * isl_ctx_alloc. This ctx contains (or will contain) options that + * control the behavior of the library and some caches. + * + * An object allocated within a given ctx should never be used inside + * another ctx. Functions for moving objects from one ctx to another + * will be added as the need arises. + * + * A given context should only be used inside a single thread. + * A global context for synchronization between different threads + * as well as functions for moving a context to a different thread + * will be added as the need arises. + * + * If anything goes wrong (out of memory, failed assertion), then + * the library will currently simply abort. This will be made + * configurable in the future. + * Users of the library should expect functions that return + * a pointer to a structure, to return NULL, indicating failure. + * Any function accepting a pointer to a structure will treat + * a NULL argument as a failure, resulting in the function freeing + * the remaining structures (if any) and returning NULL itself + * (in case of pointer return type). + * The only exception is the isl_ctx argument, which should never be NULL. + */ +struct isl_stats { + long gbr_solved_lps; +}; +enum isl_error { + isl_error_none = 0, + isl_error_abort, + isl_error_alloc, + isl_error_unknown, + isl_error_internal, + isl_error_invalid, + isl_error_quota, + isl_error_unsupported +}; +typedef enum { + isl_stat_error = -1, + isl_stat_ok = 0 +} isl_stat; +isl_stat isl_stat_non_null(void *obj); +typedef enum { + isl_bool_error = -1, + isl_bool_false = 0, + isl_bool_true = 1 +} isl_bool; +isl_bool isl_bool_not(isl_bool b); +isl_bool isl_bool_ok(int b); +typedef int isl_size; +#define isl_size_error ((int) -1) +struct isl_ctx; +typedef struct isl_ctx isl_ctx; + +/* Some helper macros */ + +#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1) +#define ISL_DEPRECATED __attribute__((__deprecated__)) +#else +#define ISL_DEPRECATED +#endif + +#define ISL_FL_INIT(l, f) (l) = (f) /* Specific flags location. */ +#define ISL_FL_SET(l, f) ((l) |= (f)) +#define ISL_FL_CLR(l, f) ((l) &= ~(f)) +#define ISL_FL_ISSET(l, f) (!!((l) & (f))) + +#define ISL_F_INIT(p, f) ISL_FL_INIT((p)->flags, f) /* Structure element flags. */ +#define ISL_F_SET(p, f) ISL_FL_SET((p)->flags, f) +#define ISL_F_CLR(p, f) ISL_FL_CLR((p)->flags, f) +#define ISL_F_ISSET(p, f) ISL_FL_ISSET((p)->flags, f) + +void *isl_malloc_or_die(isl_ctx *ctx, size_t size); +void *isl_calloc_or_die(isl_ctx *ctx, size_t nmemb, size_t size); +void *isl_realloc_or_die(isl_ctx *ctx, void *ptr, size_t size); + +#define isl_alloc(ctx,type,size) ((type *)isl_malloc_or_die(ctx, size)) +#define isl_calloc(ctx,type,size) ((type *)isl_calloc_or_die(ctx,\ + 1, size)) +#define isl_realloc(ctx,ptr,type,size) ((type *)isl_realloc_or_die(ctx,\ + ptr, size)) +#define isl_alloc_type(ctx,type) isl_alloc(ctx,type,sizeof(type)) +#define isl_calloc_type(ctx,type) isl_calloc(ctx,type,sizeof(type)) +#define isl_realloc_type(ctx,ptr,type) isl_realloc(ctx,ptr,type,sizeof(type)) +#define isl_alloc_array(ctx,type,n) isl_alloc(ctx,type,(n)*sizeof(type)) +#define isl_calloc_array(ctx,type,n) ((type *)isl_calloc_or_die(ctx,\ + n, sizeof(type))) +#define isl_realloc_array(ctx,ptr,type,n) \ + isl_realloc(ctx,ptr,type,(n)*sizeof(type)) + +#define isl_die(ctx,errno,msg,code) \ + do { \ + isl_handle_error(ctx, errno, msg, __FILE__, __LINE__); \ + code; \ + } while (0) + +void isl_handle_error(isl_ctx *ctx, enum isl_error error, const char *msg, + const char *file, int line); + +#define isl_assert4(ctx,test,code,errno) \ + do { \ + if (test) \ + break; \ + isl_die(ctx, errno, "Assertion \"" #test "\" failed", code); \ + } while (0) +#define isl_assert(ctx,test,code) \ + isl_assert4(ctx,test,code,isl_error_unknown) + +#define isl_min(a,b) ((a < b) ? (a) : (b)) + +/* struct isl_ctx functions */ + +struct isl_options *isl_ctx_options(isl_ctx *ctx); + +isl_ctx *isl_ctx_alloc_with_options(struct isl_args *args, + __isl_take void *opt); +isl_ctx *isl_ctx_alloc(void); +void *isl_ctx_peek_options(isl_ctx *ctx, struct isl_args *args); +int isl_ctx_parse_options(isl_ctx *ctx, int argc, char **argv, unsigned flags); +void isl_ctx_ref(struct isl_ctx *ctx); +void isl_ctx_deref(struct isl_ctx *ctx); +void isl_ctx_free(isl_ctx *ctx); + +void isl_ctx_abort(isl_ctx *ctx); +void isl_ctx_resume(isl_ctx *ctx); +int isl_ctx_aborted(isl_ctx *ctx); + +void isl_ctx_set_max_operations(isl_ctx *ctx, unsigned long max_operations); +unsigned long isl_ctx_get_max_operations(isl_ctx *ctx); +void isl_ctx_reset_operations(isl_ctx *ctx); + +#define ISL_ARG_CTX_DECL(prefix,st,args) \ +st *isl_ctx_peek_ ## prefix(isl_ctx *ctx); + +#define ISL_ARG_CTX_DEF(prefix,st,args) \ +st *isl_ctx_peek_ ## prefix(isl_ctx *ctx) \ +{ \ + return (st *)isl_ctx_peek_options(ctx, &(args)); \ +} + +#define ISL_CTX_GET_INT_DEF(prefix,st,args,field) \ +int prefix ## _get_ ## field(isl_ctx *ctx) \ +{ \ + st *options; \ + options = isl_ctx_peek_ ## prefix(ctx); \ + if (!options) \ + isl_die(ctx, isl_error_invalid, \ + "isl_ctx does not reference " #prefix, \ + return -1); \ + return options->field; \ +} + +#define ISL_CTX_SET_INT_DEF(prefix,st,args,field) \ +isl_stat prefix ## _set_ ## field(isl_ctx *ctx, int val) \ +{ \ + st *options; \ + options = isl_ctx_peek_ ## prefix(ctx); \ + if (!options) \ + isl_die(ctx, isl_error_invalid, \ + "isl_ctx does not reference " #prefix, \ + return isl_stat_error); \ + options->field = val; \ + return isl_stat_ok; \ +} + +#define ISL_CTX_GET_STR_DEF(prefix,st,args,field) \ +const char *prefix ## _get_ ## field(isl_ctx *ctx) \ +{ \ + st *options; \ + options = isl_ctx_peek_ ## prefix(ctx); \ + if (!options) \ + isl_die(ctx, isl_error_invalid, \ + "isl_ctx does not reference " #prefix, \ + return NULL); \ + return options->field; \ +} + +#define ISL_CTX_SET_STR_DEF(prefix,st,args,field) \ +isl_stat prefix ## _set_ ## field(isl_ctx *ctx, const char *val) \ +{ \ + st *options; \ + options = isl_ctx_peek_ ## prefix(ctx); \ + if (!options) \ + isl_die(ctx, isl_error_invalid, \ + "isl_ctx does not reference " #prefix, \ + return isl_stat_error); \ + if (!val) \ + return isl_stat_error; \ + free(options->field); \ + options->field = strdup(val); \ + if (!options->field) \ + return isl_stat_error; \ + return isl_stat_ok; \ +} + +#define ISL_CTX_GET_BOOL_DEF(prefix,st,args,field) \ + ISL_CTX_GET_INT_DEF(prefix,st,args,field) + +#define ISL_CTX_SET_BOOL_DEF(prefix,st,args,field) \ + ISL_CTX_SET_INT_DEF(prefix,st,args,field) + +#define ISL_CTX_GET_CHOICE_DEF(prefix,st,args,field) \ + ISL_CTX_GET_INT_DEF(prefix,st,args,field) + +#define ISL_CTX_SET_CHOICE_DEF(prefix,st,args,field) \ + 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); + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/external/mit/isl/dist/include/isl/fixed_box.h b/external/mit/isl/dist/include/isl/fixed_box.h new file mode 100644 index 000000000000..2debfd033491 --- /dev/null +++ b/external/mit/isl/dist/include/isl/fixed_box.h @@ -0,0 +1,46 @@ +/* + * Use of this software is governed by the MIT license + */ + +#ifndef ISL_FIXED_BOX_H +#define ISL_FIXED_BOX_H + +#include +#include +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +struct __isl_export isl_fixed_box; +typedef struct isl_fixed_box isl_fixed_box; + +isl_ctx *isl_fixed_box_get_ctx(__isl_keep isl_fixed_box *box); +__isl_export +__isl_give isl_space *isl_fixed_box_get_space(__isl_keep isl_fixed_box *box); +__isl_export +isl_bool isl_fixed_box_is_valid(__isl_keep isl_fixed_box *box); +__isl_export +__isl_give isl_multi_aff *isl_fixed_box_get_offset( + __isl_keep isl_fixed_box *box); +__isl_export +__isl_give isl_multi_val *isl_fixed_box_get_size(__isl_keep isl_fixed_box *box); + +__isl_give isl_fixed_box *isl_fixed_box_copy(__isl_keep isl_fixed_box *box); +__isl_null isl_fixed_box *isl_fixed_box_free(__isl_take isl_fixed_box *box); + +__isl_constructor +__isl_give isl_fixed_box *isl_fixed_box_read_from_str(isl_ctx *ctx, + const char *str); +__isl_give isl_printer *isl_printer_print_fixed_box( + __isl_take isl_printer *p, __isl_keep isl_fixed_box *box); +__isl_give char *isl_fixed_box_to_str(__isl_keep isl_fixed_box *box); +void isl_fixed_box_dump(__isl_keep isl_fixed_box *box); + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/external/mit/isl/dist/include/isl/flow.h b/external/mit/isl/dist/include/isl/flow.h new file mode 100644 index 000000000000..be2f6c577f15 --- /dev/null +++ b/external/mit/isl/dist/include/isl/flow.h @@ -0,0 +1,156 @@ +#ifndef ISL_FLOW_H +#define ISL_FLOW_H + +#include + +#include +#include +#include +#include +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +/* Let n (>= 0) be the number of iterators shared by first and second. + * If first precedes second textually return 2 * n + 1, + * otherwise return 2 * n. + */ +typedef int (*isl_access_level_before)(void *first, void *second); + +struct isl_restriction; +typedef struct isl_restriction isl_restriction; + +__isl_null isl_restriction *isl_restriction_free( + __isl_take isl_restriction *restr); +__isl_give isl_restriction *isl_restriction_empty( + __isl_take isl_map *source_map); +__isl_give isl_restriction *isl_restriction_none( + __isl_take isl_map *source_map); +__isl_give isl_restriction *isl_restriction_input( + __isl_take isl_set *source_restr, __isl_take isl_set *sink_restr); +__isl_give isl_restriction *isl_restriction_output( + __isl_take isl_set *source_restr); + +isl_ctx *isl_restriction_get_ctx(__isl_keep isl_restriction *restr); + +typedef __isl_give isl_restriction *(*isl_access_restrict)( + __isl_keep isl_map *source_map, __isl_keep isl_set *sink, + void *source_user, void *user); + +struct isl_access_info; +typedef struct isl_access_info isl_access_info; +struct isl_flow; +typedef struct isl_flow isl_flow; + +__isl_give isl_access_info *isl_access_info_alloc(__isl_take isl_map *sink, + void *sink_user, isl_access_level_before fn, int max_source); +__isl_give isl_access_info *isl_access_info_set_restrict( + __isl_take isl_access_info *acc, isl_access_restrict fn, void *user); +__isl_give isl_access_info *isl_access_info_add_source( + __isl_take isl_access_info *acc, __isl_take isl_map *source, + int must, void *source_user); +__isl_null isl_access_info *isl_access_info_free( + __isl_take isl_access_info *acc); + +isl_ctx *isl_access_info_get_ctx(__isl_keep isl_access_info *acc); + +__isl_give isl_flow *isl_access_info_compute_flow(__isl_take isl_access_info *acc); +isl_stat isl_flow_foreach(__isl_keep isl_flow *deps, + isl_stat (*fn)(__isl_take isl_map *dep, int must, void *dep_user, + void *user), + void *user); +__isl_give isl_map *isl_flow_get_no_source(__isl_keep isl_flow *deps, int must); +__isl_null isl_flow *isl_flow_free(__isl_take isl_flow *deps); + +isl_ctx *isl_flow_get_ctx(__isl_keep isl_flow *deps); + +struct __isl_export isl_union_access_info; +typedef struct isl_union_access_info isl_union_access_info; +struct __isl_export isl_union_flow; +typedef struct isl_union_flow isl_union_flow; + +__isl_constructor +__isl_give isl_union_access_info *isl_union_access_info_from_sink( + __isl_take isl_union_map *sink); +__isl_export +__isl_give isl_union_access_info *isl_union_access_info_set_must_source( + __isl_take isl_union_access_info *access, + __isl_take isl_union_map *must_source); +__isl_export +__isl_give isl_union_access_info *isl_union_access_info_set_may_source( + __isl_take isl_union_access_info *access, + __isl_take isl_union_map *may_source); +__isl_export +__isl_give isl_union_access_info *isl_union_access_info_set_kill( + __isl_take isl_union_access_info *access, + __isl_take isl_union_map *kill); +__isl_export +__isl_give isl_union_access_info *isl_union_access_info_set_schedule( + __isl_take isl_union_access_info *access, + __isl_take isl_schedule *schedule); +__isl_export +__isl_give isl_union_access_info *isl_union_access_info_set_schedule_map( + __isl_take isl_union_access_info *access, + __isl_take isl_union_map *schedule_map); +__isl_give isl_union_access_info *isl_union_access_info_copy( + __isl_keep isl_union_access_info *access); +__isl_null isl_union_access_info *isl_union_access_info_free( + __isl_take isl_union_access_info *access); + +isl_ctx *isl_union_access_info_get_ctx( + __isl_keep isl_union_access_info *access); + +__isl_give isl_union_access_info *isl_union_access_info_read_from_file( + isl_ctx *ctx, FILE *input); +__isl_give isl_printer *isl_printer_print_union_access_info( + __isl_take isl_printer *p, __isl_keep isl_union_access_info *access); +__isl_give char *isl_union_access_info_to_str( + __isl_keep isl_union_access_info *access); + +__isl_export +__isl_give isl_union_flow *isl_union_access_info_compute_flow( + __isl_take isl_union_access_info *access); + +isl_ctx *isl_union_flow_get_ctx(__isl_keep isl_union_flow *flow); +__isl_give isl_union_flow *isl_union_flow_copy( + __isl_keep isl_union_flow *flow); +__isl_export +__isl_give isl_union_map *isl_union_flow_get_must_dependence( + __isl_keep isl_union_flow *flow); +__isl_export +__isl_give isl_union_map *isl_union_flow_get_may_dependence( + __isl_keep isl_union_flow *flow); +__isl_export +__isl_give isl_union_map *isl_union_flow_get_full_must_dependence( + __isl_keep isl_union_flow *flow); +__isl_export +__isl_give isl_union_map *isl_union_flow_get_full_may_dependence( + __isl_keep isl_union_flow *flow); +__isl_export +__isl_give isl_union_map *isl_union_flow_get_must_no_source( + __isl_keep isl_union_flow *flow); +__isl_export +__isl_give isl_union_map *isl_union_flow_get_may_no_source( + __isl_keep isl_union_flow *flow); +__isl_null isl_union_flow *isl_union_flow_free(__isl_take isl_union_flow *flow); + +__isl_give isl_printer *isl_printer_print_union_flow( + __isl_take isl_printer *p, __isl_keep isl_union_flow *flow); +__isl_give char *isl_union_flow_to_str(__isl_keep isl_union_flow *flow); + +int isl_union_map_compute_flow(__isl_take isl_union_map *sink, + __isl_take isl_union_map *must_source, + __isl_take isl_union_map *may_source, + __isl_take isl_union_map *schedule, + __isl_give isl_union_map **must_dep, __isl_give isl_union_map **may_dep, + __isl_give isl_union_map **must_no_source, + __isl_give isl_union_map **may_no_source); + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/external/mit/isl/dist/include/isl/hash.h b/external/mit/isl/dist/include/isl/hash.h new file mode 100644 index 000000000000..31cf25cf3bbe --- /dev/null +++ b/external/mit/isl/dist/include/isl/hash.h @@ -0,0 +1,80 @@ +/* + * 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_HASH_H +#define ISL_HASH_H + +#include +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +#define isl_hash_init() (2166136261u) +#define isl_hash_byte(h,b) do { \ + h *= 16777619; \ + h ^= b; \ + } while(0) +#define isl_hash_hash(h,h2) \ + do { \ + isl_hash_byte(h, (h2) & 0xFF); \ + isl_hash_byte(h, ((h2) >> 8) & 0xFF); \ + isl_hash_byte(h, ((h2) >> 16) & 0xFF); \ + isl_hash_byte(h, ((h2) >> 24) & 0xFF); \ + } while(0) +#define isl_hash_bits(h,bits) \ + ((bits) == 32) ? (h) : \ + ((bits) >= 16) ? \ + ((h) >> (bits)) ^ ((h) & (((uint32_t)1 << (bits)) - 1)) : \ + (((h) >> (bits)) ^ (h)) & (((uint32_t)1 << (bits)) - 1) + +uint32_t isl_hash_string(uint32_t hash, const char *s); +uint32_t isl_hash_mem(uint32_t hash, const void *p, size_t len); + +#define isl_hash_builtin(h,l) isl_hash_mem(h, &l, sizeof(l)) + +struct isl_hash_table_entry +{ + uint32_t hash; + void *data; +}; + +struct isl_hash_table { + int bits; + int n; + struct isl_hash_table_entry *entries; +}; + +struct isl_hash_table *isl_hash_table_alloc(struct isl_ctx *ctx, int min_size); +void isl_hash_table_free(struct isl_ctx *ctx, struct isl_hash_table *table); + +int isl_hash_table_init(struct isl_ctx *ctx, struct isl_hash_table *table, + int min_size); +void isl_hash_table_clear(struct isl_hash_table *table); +extern struct isl_hash_table_entry *isl_hash_table_entry_none; +struct isl_hash_table_entry *isl_hash_table_find(struct isl_ctx *ctx, + struct isl_hash_table *table, + uint32_t key_hash, + isl_bool (*eq)(const void *entry, const void *val), + const void *val, int reserve); +isl_stat isl_hash_table_foreach(isl_ctx *ctx, struct isl_hash_table *table, + isl_stat (*fn)(void **entry, void *user), void *user); +isl_bool isl_hash_table_every(isl_ctx *ctx, struct isl_hash_table *table, + isl_bool (*test)(void **entry, void *user), void *user); +void isl_hash_table_remove(struct isl_ctx *ctx, + struct isl_hash_table *table, + struct isl_hash_table_entry *entry); + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/external/mit/isl/dist/include/isl/hmap.h b/external/mit/isl/dist/include/isl/hmap.h new file mode 100644 index 000000000000..8d4178fe468f --- /dev/null +++ b/external/mit/isl/dist/include/isl/hmap.h @@ -0,0 +1,73 @@ +#include +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +#define ISL_xCAT(A,B) A ## B +#define ISL_CAT(A,B) ISL_xCAT(A,B) +#define ISL_xFN(TYPE,NAME) TYPE ## _ ## NAME +#define ISL_FN(TYPE,NAME) ISL_xFN(TYPE,NAME) + +struct __isl_export ISL_HMAP; +typedef struct ISL_HMAP ISL_HMAP; + +__isl_constructor +__isl_give ISL_HMAP *ISL_FN(ISL_HMAP,alloc)(isl_ctx *ctx, int min_size); +__isl_give ISL_HMAP *ISL_FN(ISL_HMAP,copy)(__isl_keep ISL_HMAP *hmap); +__isl_null ISL_HMAP *ISL_FN(ISL_HMAP,free)(__isl_take ISL_HMAP *hmap); + +isl_ctx *ISL_FN(ISL_HMAP,get_ctx)(__isl_keep ISL_HMAP *hmap); + +__isl_give ISL_MAYBE(ISL_VAL) ISL_FN(ISL_HMAP,try_get)( + __isl_keep ISL_HMAP *hmap, __isl_keep ISL_KEY *key); +isl_bool ISL_FN(ISL_HMAP,has)(__isl_keep ISL_HMAP *hmap, + __isl_keep ISL_KEY *key); +__isl_give ISL_VAL *ISL_FN(ISL_HMAP,get)(__isl_keep ISL_HMAP *hmap, + __isl_take ISL_KEY *key); +__isl_export +__isl_give ISL_HMAP *ISL_FN(ISL_HMAP,set)(__isl_take ISL_HMAP *hmap, + __isl_take ISL_KEY *key, __isl_take ISL_VAL *val); +__isl_give ISL_HMAP *ISL_FN(ISL_HMAP,drop)(__isl_take ISL_HMAP *hmap, + __isl_take ISL_KEY *key); + +isl_stat ISL_FN(ISL_HMAP,foreach)(__isl_keep ISL_HMAP *hmap, + isl_stat (*fn)(__isl_take ISL_KEY *key, __isl_take ISL_VAL *val, + void *user), + void *user); +isl_bool ISL_FN(ISL_HMAP,every)(__isl_keep ISL_HMAP *hmap, + isl_bool (*test)(__isl_keep ISL_KEY *key, __isl_keep ISL_VAL *val, + void *user), + void *user); + +#ifdef ISL_HMAP_IS_EQUAL +__isl_export +isl_bool ISL_HMAP_IS_EQUAL(__isl_keep ISL_HMAP *hmap1, + __isl_keep ISL_HMAP *hmap2); +#endif + +#ifdef ISL_HMAP_HAVE_READ_FROM_STR +__isl_constructor +__isl_give ISL_HMAP *ISL_FN(ISL_HMAP,read_from_str)(isl_ctx *ctx, + const char *str); +#endif +__isl_give char *ISL_FN(ISL_HMAP,to_str)(__isl_keep ISL_HMAP *hmap); +__isl_give isl_printer *ISL_FN(isl_printer_print,ISL_HMAP_SUFFIX)( + __isl_take isl_printer *p, __isl_keep ISL_HMAP *hmap); +void ISL_FN(ISL_HMAP,dump)(__isl_keep ISL_HMAP *hmap); + +#undef ISL_xCAT +#undef ISL_CAT +#undef ISL_KEY +#undef ISL_VAL +#undef ISL_xFN +#undef ISL_FN +#undef ISL_xHMAP +#undef ISL_yHMAP +#undef ISL_HMAP + +#if defined(__cplusplus) +} +#endif diff --git a/external/mit/isl/dist/include/isl/hmap_templ.c b/external/mit/isl/dist/include/isl/hmap_templ.c new file mode 100644 index 000000000000..ba0d7cc6e10a --- /dev/null +++ b/external/mit/isl/dist/include/isl/hmap_templ.c @@ -0,0 +1,583 @@ +/* + * Copyright 2011 INRIA Saclay + * Copyright 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 +#include +#include + +#define ISL_xCAT(A,B) A ## B +#define ISL_CAT(A,B) ISL_xCAT(A,B) +#define ISL_xFN(TYPE,NAME) TYPE ## _ ## NAME +#define ISL_FN(TYPE,NAME) ISL_xFN(TYPE,NAME) +#define ISL_xS(TYPE1,TYPE2,NAME) struct isl_ ## TYPE1 ## _ ## TYPE2 ## _ ## NAME +#define ISL_yS(TYPE1,TYPE2,NAME) ISL_xS(TYPE1,TYPE2,NAME) +#define ISL_S(NAME) ISL_yS(ISL_KEY,ISL_VAL,NAME) + +struct ISL_HMAP { + int ref; + isl_ctx *ctx; + struct isl_hash_table table; +}; + +ISL_S(pair) { + ISL_KEY *key; + ISL_VAL *val; +}; + +__isl_give ISL_HMAP *ISL_FN(ISL_HMAP,alloc)(isl_ctx *ctx, int min_size) +{ + ISL_HMAP *hmap; + + hmap = isl_calloc_type(ctx, ISL_HMAP); + if (!hmap) + return NULL; + + hmap->ctx = ctx; + isl_ctx_ref(ctx); + hmap->ref = 1; + + if (isl_hash_table_init(ctx, &hmap->table, min_size) < 0) + return ISL_FN(ISL_HMAP,free)(hmap); + + return hmap; +} + +static isl_stat free_pair(void **entry, void *user) +{ + ISL_S(pair) *pair = *entry; + ISL_FN(ISL_KEY,free)(pair->key); + ISL_FN(ISL_VAL,free)(pair->val); + free(pair); + *entry = NULL; + return isl_stat_ok; +} + +__isl_null ISL_HMAP *ISL_FN(ISL_HMAP,free)(__isl_take ISL_HMAP *hmap) +{ + if (!hmap) + return NULL; + if (--hmap->ref > 0) + return NULL; + isl_hash_table_foreach(hmap->ctx, &hmap->table, &free_pair, NULL); + isl_hash_table_clear(&hmap->table); + isl_ctx_deref(hmap->ctx); + free(hmap); + return NULL; +} + +isl_ctx *ISL_FN(ISL_HMAP,get_ctx)(__isl_keep ISL_HMAP *hmap) +{ + return hmap ? hmap->ctx : NULL; +} + +/* Add a mapping from "key" to "val" to the associative array + * pointed to by user. + */ +static isl_stat add_key_val(__isl_take ISL_KEY *key, __isl_take ISL_VAL *val, + void *user) +{ + ISL_HMAP **hmap = (ISL_HMAP **) user; + + *hmap = ISL_FN(ISL_HMAP,set)(*hmap, key, val); + + if (!*hmap) + return isl_stat_error; + + return isl_stat_ok; +} + +__isl_give ISL_HMAP *ISL_FN(ISL_HMAP,dup)(__isl_keep ISL_HMAP *hmap) +{ + ISL_HMAP *dup; + + if (!hmap) + return NULL; + + dup = ISL_FN(ISL_HMAP,alloc)(hmap->ctx, hmap->table.n); + if (ISL_FN(ISL_HMAP,foreach)(hmap, &add_key_val, &dup) < 0) + return ISL_FN(ISL_HMAP,free)(dup); + + return dup; +} + +__isl_give ISL_HMAP *ISL_FN(ISL_HMAP,cow)(__isl_take ISL_HMAP *hmap) +{ + if (!hmap) + return NULL; + + if (hmap->ref == 1) + return hmap; + hmap->ref--; + return ISL_FN(ISL_HMAP,dup)(hmap); +} + +__isl_give ISL_HMAP *ISL_FN(ISL_HMAP,copy)(__isl_keep ISL_HMAP *hmap) +{ + if (!hmap) + return NULL; + + hmap->ref++; + return hmap; +} + +static isl_bool has_key(const void *entry, const void *c_key) +{ + const ISL_S(pair) *pair = entry; + ISL_KEY *key = (ISL_KEY *) c_key; + + return ISL_KEY_IS_EQUAL(pair->key, key); +} + +/* If "hmap" contains a value associated to "key", then return + * (isl_bool_true, copy of value). + * Otherwise, return + * (isl_bool_false, NULL). + * If an error occurs, then return + * (isl_bool_error, NULL). + */ +__isl_give ISL_MAYBE(ISL_VAL) ISL_FN(ISL_HMAP,try_get)( + __isl_keep ISL_HMAP *hmap, __isl_keep ISL_KEY *key) +{ + struct isl_hash_table_entry *entry; + ISL_S(pair) *pair; + uint32_t hash; + ISL_MAYBE(ISL_VAL) res = { isl_bool_false, NULL }; + + if (!hmap || !key) + goto error; + + hash = ISL_FN(ISL_KEY,get_hash)(key); + entry = isl_hash_table_find(hmap->ctx, &hmap->table, hash, + &has_key, key, 0); + + if (!entry) + goto error; + if (entry == isl_hash_table_entry_none) + return res; + + pair = entry->data; + + res.valid = isl_bool_true; + res.value = ISL_FN(ISL_VAL,copy)(pair->val); + if (!res.value) + res.valid = isl_bool_error; + return res; +error: + res.valid = isl_bool_error; + res.value = NULL; + return res; +} + +/* If "hmap" contains a value associated to "key", then return + * isl_bool_true. Otherwise, return isl_bool_false. + * Return isl_bool_error on error. + */ +isl_bool ISL_FN(ISL_HMAP,has)(__isl_keep ISL_HMAP *hmap, + __isl_keep ISL_KEY *key) +{ + ISL_MAYBE(ISL_VAL) res; + + res = ISL_FN(ISL_HMAP,try_get)(hmap, key); + ISL_FN(ISL_VAL,free)(res.value); + + return res.valid; +} + +/* If "hmap" contains a value associated to "key", then return + * a copy of that value. Otherwise, return NULL. + * Return NULL on error. + */ +__isl_give ISL_VAL *ISL_FN(ISL_HMAP,get)(__isl_keep ISL_HMAP *hmap, + __isl_take ISL_KEY *key) +{ + ISL_VAL *res; + + res = ISL_FN(ISL_HMAP,try_get)(hmap, key).value; + ISL_FN(ISL_KEY,free)(key); + return res; +} + +/* Remove the mapping between "key" and its associated value (if any) + * from "hmap". + * + * If "key" is not mapped to anything, then we leave "hmap" untouched" + */ +__isl_give ISL_HMAP *ISL_FN(ISL_HMAP,drop)(__isl_take ISL_HMAP *hmap, + __isl_take ISL_KEY *key) +{ + struct isl_hash_table_entry *entry; + ISL_S(pair) *pair; + uint32_t hash; + + if (!hmap || !key) + goto error; + + hash = ISL_FN(ISL_KEY,get_hash)(key); + entry = isl_hash_table_find(hmap->ctx, &hmap->table, hash, + &has_key, key, 0); + if (!entry) + goto error; + if (entry == isl_hash_table_entry_none) { + ISL_FN(ISL_KEY,free)(key); + return hmap; + } + + hmap = ISL_FN(ISL_HMAP,cow)(hmap); + if (!hmap) + goto error; + entry = isl_hash_table_find(hmap->ctx, &hmap->table, hash, + &has_key, key, 0); + ISL_FN(ISL_KEY,free)(key); + + if (!entry) + return ISL_FN(ISL_HMAP,free)(hmap); + if (entry == isl_hash_table_entry_none) + isl_die(hmap->ctx, isl_error_internal, + "missing entry" , return ISL_FN(ISL_HMAP,free)(hmap)); + + pair = entry->data; + isl_hash_table_remove(hmap->ctx, &hmap->table, entry); + ISL_FN(ISL_KEY,free)(pair->key); + ISL_FN(ISL_VAL,free)(pair->val); + free(pair); + + return hmap; +error: + ISL_FN(ISL_KEY,free)(key); + ISL_FN(ISL_HMAP,free)(hmap); + return NULL; +} + +/* Add a mapping from "key" to "val" to "hmap". + * If "key" was already mapped to something else, then that mapping + * is replaced. + * If key happened to be mapped to "val" already, then we leave + * "hmap" untouched. + */ +__isl_give ISL_HMAP *ISL_FN(ISL_HMAP,set)(__isl_take ISL_HMAP *hmap, + __isl_take ISL_KEY *key, __isl_take ISL_VAL *val) +{ + struct isl_hash_table_entry *entry; + ISL_S(pair) *pair; + uint32_t hash; + + if (!hmap || !key || !val) + goto error; + + hash = ISL_FN(ISL_KEY,get_hash)(key); + entry = isl_hash_table_find(hmap->ctx, &hmap->table, hash, + &has_key, key, 0); + if (!entry) + goto error; + if (entry != isl_hash_table_entry_none) { + isl_bool equal; + pair = entry->data; + equal = ISL_VAL_IS_EQUAL(pair->val, val); + if (equal < 0) + goto error; + if (equal) { + ISL_FN(ISL_KEY,free)(key); + ISL_FN(ISL_VAL,free)(val); + return hmap; + } + } + + hmap = ISL_FN(ISL_HMAP,cow)(hmap); + if (!hmap) + goto error; + + entry = isl_hash_table_find(hmap->ctx, &hmap->table, hash, + &has_key, key, 1); + + if (!entry) + goto error; + + if (entry->data) { + pair = entry->data; + ISL_FN(ISL_VAL,free)(pair->val); + pair->val = val; + ISL_FN(ISL_KEY,free)(key); + return hmap; + } + + pair = isl_alloc_type(hmap->ctx, ISL_S(pair)); + if (!pair) + goto error; + + entry->data = pair; + pair->key = key; + pair->val = val; + return hmap; +error: + ISL_FN(ISL_KEY,free)(key); + ISL_FN(ISL_VAL,free)(val); + return ISL_FN(ISL_HMAP,free)(hmap); +} + +/* Internal data structure for isl_*_to_*_foreach. + * + * fn is the function that should be called on each entry. + * user is the user-specified final argument to fn. + */ +ISL_S(foreach_data) { + isl_stat (*fn)(__isl_take ISL_KEY *key, __isl_take ISL_VAL *val, + void *user); + void *user; +}; + +/* Call data->fn on a copy of the key and value in *entry. + */ +static isl_stat call_on_copy(void **entry, void *user) +{ + ISL_S(pair) *pair = *entry; + ISL_S(foreach_data) *data = (ISL_S(foreach_data) *) user; + + return data->fn(ISL_FN(ISL_KEY,copy)(pair->key), + ISL_FN(ISL_VAL,copy)(pair->val), data->user); +} + +/* Call "fn" on each pair of key and value in "hmap". + */ +isl_stat ISL_FN(ISL_HMAP,foreach)(__isl_keep ISL_HMAP *hmap, + isl_stat (*fn)(__isl_take ISL_KEY *key, __isl_take ISL_VAL *val, + void *user), + void *user) +{ + ISL_S(foreach_data) data = { fn, user }; + + if (!hmap) + return isl_stat_error; + + return isl_hash_table_foreach(hmap->ctx, &hmap->table, + &call_on_copy, &data); +} + +/* Internal data structure for isl_*_to_*_every. + * + * "test" is the function that should be called on each entry, + * until any invocation returns isl_bool_false. + * "test_user" is the user-specified final argument to "test". + */ +ISL_S(every_data) { + isl_bool (*test)(__isl_keep ISL_KEY *key, __isl_keep ISL_VAL *val, + void *user); + void *test_user; +}; + +/* Call data->test on the key and value in *entry. + */ +static isl_bool call_on_pair(void **entry, void *user) +{ + ISL_S(pair) *pair = *entry; + ISL_S(every_data) *data = (ISL_S(every_data) *) user; + + return data->test(pair->key, pair->val, data->test_user); +} + +/* Does "test" succeed on every entry of "hmap"? + */ +isl_bool ISL_FN(ISL_HMAP,every)(__isl_keep ISL_HMAP *hmap, + isl_bool (*test)(__isl_keep ISL_KEY *key, __isl_keep ISL_VAL *val, + void *user), + void *user) +{ + ISL_S(every_data) data = { test, user }; + + if (!hmap) + return isl_bool_error; + + return isl_hash_table_every(hmap->ctx, &hmap->table, + &call_on_pair, &data); +} + +#ifdef ISL_HMAP_IS_EQUAL + +/* Does "hmap" have an entry with key "key" and value "val"? + */ +static isl_bool has_entry(__isl_keep ISL_KEY *key, __isl_keep ISL_VAL *val, + void *user) +{ + ISL_HMAP *hmap = user; + ISL_MAYBE(ISL_VAL) maybe_val; + isl_bool equal; + + maybe_val = ISL_FN(ISL_HMAP,try_get)(hmap, key); + if (maybe_val.valid < 0 || !maybe_val.valid) + return maybe_val.valid; + equal = ISL_VAL_IS_EQUAL(maybe_val.value, val); + ISL_FN(ISL_VAL,free)(maybe_val.value); + return equal; +} + +/* Is "hmap1" (obviously) equal to "hmap2"? + * + * In particular, do the two associative arrays have + * the same number of entries and does every entry of the first + * also appear in the second? + */ +isl_bool ISL_HMAP_IS_EQUAL(__isl_keep ISL_HMAP *hmap1, + __isl_keep ISL_HMAP *hmap2) +{ + if (!hmap1 || !hmap2) + return isl_bool_error; + if (hmap1 == hmap2) + return isl_bool_true; + if (hmap1->table.n != hmap2->table.n) + return isl_bool_false; + return ISL_FN(ISL_HMAP,every)(hmap1, &has_entry, hmap2); +} + +#endif + +/* Internal data structure for print_pair. + * + * p is the printer on which the associative array is being printed. + * first is set if the current key-value pair is the first to be printed. + */ +ISL_S(print_data) { + isl_printer *p; + int first; +}; + +/* Print the given key-value pair to data->p. + */ +static isl_stat print_pair(__isl_take ISL_KEY *key, __isl_take ISL_VAL *val, + void *user) +{ + ISL_S(print_data) *data = user; + + if (!data->first) + data->p = isl_printer_print_str(data->p, ", "); + data->p = ISL_KEY_PRINT(data->p, key); + data->p = isl_printer_print_str(data->p, ": "); + data->p = ISL_VAL_PRINT(data->p, val); + data->first = 0; + + ISL_FN(ISL_KEY,free)(key); + ISL_FN(ISL_VAL,free)(val); + return isl_stat_ok; +} + +/* Print the associative array to "p". + */ +__isl_give isl_printer *ISL_FN(isl_printer_print,ISL_HMAP_SUFFIX)( + __isl_take isl_printer *p, __isl_keep ISL_HMAP *hmap) +{ + ISL_S(print_data) data; + + if (!p || !hmap) + return isl_printer_free(p); + + p = isl_printer_print_str(p, "{"); + data.p = p; + data.first = 1; + if (ISL_FN(ISL_HMAP,foreach)(hmap, &print_pair, &data) < 0) + data.p = isl_printer_free(data.p); + p = data.p; + p = isl_printer_print_str(p, "}"); + + return p; +} + +void ISL_FN(ISL_HMAP,dump)(__isl_keep ISL_HMAP *hmap) +{ + isl_printer *printer; + + if (!hmap) + return; + + printer = isl_printer_to_file(ISL_FN(ISL_HMAP,get_ctx)(hmap), stderr); + printer = ISL_FN(isl_printer_print,ISL_HMAP_SUFFIX)(printer, hmap); + printer = isl_printer_end_line(printer); + + isl_printer_free(printer); +} + +/* Return a string representation of "hmap". + */ +__isl_give char *ISL_FN(ISL_HMAP,to_str)(__isl_keep ISL_HMAP *hmap) +{ + isl_printer *p; + char *s; + + if (!hmap) + return NULL; + p = isl_printer_to_str(ISL_FN(ISL_HMAP,get_ctx)(hmap)); + p = ISL_FN(isl_printer_print,ISL_HMAP_SUFFIX)(p, hmap); + s = isl_printer_get_str(p); + isl_printer_free(p); + + return s; +} + +#ifdef ISL_HMAP_HAVE_READ_FROM_STR + +/* Read an associative array from "s". + * The input format corresponds to the way associative arrays are printed + * by isl_printer_print_*_to_*. + * In particular, each key-value pair is separated by a colon, + * the key-value pairs are separated by a comma and + * the entire associative array is surrounded by braces. + */ +__isl_give ISL_HMAP *ISL_FN(isl_stream_read,ISL_HMAP_SUFFIX)(isl_stream *s) +{ + isl_ctx *ctx; + ISL_HMAP *hmap; + + if (!s) + return NULL; + ctx = isl_stream_get_ctx(s); + hmap = ISL_FN(ISL_HMAP,alloc)(ctx, 0); + if (!hmap) + return NULL; + if (isl_stream_eat(s, '{') < 0) + return ISL_FN(ISL_HMAP,free)(hmap); + if (isl_stream_eat_if_available(s, '}')) + return hmap; + do { + ISL_KEY *key; + ISL_VAL *val = NULL; + + key = ISL_KEY_READ(s); + if (isl_stream_eat(s, ':') >= 0) + val = ISL_VAL_READ(s); + hmap = ISL_FN(ISL_HMAP,set)(hmap, key, val); + if (!hmap) + return NULL; + } while (isl_stream_eat_if_available(s, ',')); + if (isl_stream_eat(s, '}') < 0) + return ISL_FN(ISL_HMAP,free)(hmap); + return hmap; +} + +/* Read an associative array from the string "str". + * The input format corresponds to the way associative arrays are printed + * by isl_printer_print_*_to_*. + * In particular, each key-value pair is separated by a colon, + * the key-value pairs are separated by a comma and + * the entire associative array is surrounded by braces. + */ +__isl_give ISL_HMAP *ISL_FN(ISL_HMAP,read_from_str)(isl_ctx *ctx, + const char *str) +{ + ISL_HMAP *hmap; + isl_stream *s; + + s = isl_stream_new_str(ctx, str); + if (!s) + return NULL; + hmap = ISL_FN(isl_stream_read,ISL_HMAP_SUFFIX)(s); + isl_stream_free(s); + return hmap; +} + +#endif diff --git a/external/mit/isl/dist/include/isl/id.h b/external/mit/isl/dist/include/isl/id.h new file mode 100644 index 000000000000..f434d537de24 --- /dev/null +++ b/external/mit/isl/dist/include/isl/id.h @@ -0,0 +1,55 @@ +#ifndef ISL_ID_H +#define ISL_ID_H + +#include +#include +#include +#include +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +ISL_DECLARE_EXPORTED_LIST_FN(id) +ISL_DECLARE_EXPORTED_LIST_FN_READ(id) + +ISL_DECLARE_MULTI(id) + +isl_ctx *isl_id_get_ctx(__isl_keep isl_id *id); +uint32_t isl_id_get_hash(__isl_keep isl_id *id); + +__isl_give isl_id *isl_id_alloc(isl_ctx *ctx, + __isl_keep const char *name, void *user); +__isl_give isl_id *isl_id_copy(isl_id *id); +__isl_null isl_id *isl_id_free(__isl_take isl_id *id); + +void *isl_id_get_user(__isl_keep isl_id *id); +__isl_export +__isl_keep const char *isl_id_get_name(__isl_keep isl_id *id); + +__isl_give isl_id *isl_id_set_free_user(__isl_take isl_id *id, + void (*free_user)(void *user)); +void (*isl_id_get_free_user(__isl_keep isl_id *id))(void *user); + +__isl_constructor +__isl_give isl_id *isl_id_read_from_str(isl_ctx *ctx, const char *str); +__isl_give char *isl_id_to_str(__isl_keep isl_id *id); +__isl_give isl_printer *isl_printer_print_id(__isl_take isl_printer *p, + __isl_keep isl_id *id); +void isl_id_dump(__isl_keep isl_id *id); + +__isl_constructor +__isl_give isl_multi_id *isl_multi_id_read_from_str(isl_ctx *ctx, + const char *str); +__isl_give isl_printer *isl_printer_print_multi_id(__isl_take isl_printer *p, + __isl_keep isl_multi_id *mi); +void isl_multi_id_dump(__isl_keep isl_multi_id *mi); +__isl_give char *isl_multi_id_to_str(__isl_keep isl_multi_id *mi); + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/external/mit/isl/dist/include/isl/id_to_ast_expr.h b/external/mit/isl/dist/include/isl/id_to_ast_expr.h new file mode 100644 index 000000000000..ccdb1e071394 --- /dev/null +++ b/external/mit/isl/dist/include/isl/id_to_ast_expr.h @@ -0,0 +1,22 @@ +#ifndef ISL_ID_TO_AST_EXPR_H +#define ISL_ID_TO_AST_EXPR_H + +#include +#include +#include + +#define ISL_KEY isl_id +#define ISL_VAL isl_ast_expr +#define ISL_HMAP_SUFFIX id_to_ast_expr +#define ISL_HMAP isl_id_to_ast_expr +#define ISL_HMAP_HAVE_READ_FROM_STR +#define ISL_HMAP_IS_EQUAL isl_id_to_ast_expr_is_equal +#include +#undef ISL_KEY +#undef ISL_VAL +#undef ISL_HMAP_SUFFIX +#undef ISL_HMAP +#undef ISL_HMAP_HAVE_READ_FROM_STR +#undef ISL_HMAP_IS_EQUAL + +#endif diff --git a/external/mit/isl/dist/include/isl/id_to_id.h b/external/mit/isl/dist/include/isl/id_to_id.h new file mode 100644 index 000000000000..94b40ef8de7e --- /dev/null +++ b/external/mit/isl/dist/include/isl/id_to_id.h @@ -0,0 +1,21 @@ +#ifndef ISL_ID_TO_ID_H +#define ISL_ID_TO_ID_H + +#include +#include + +#define ISL_KEY isl_id +#define ISL_VAL isl_id +#define ISL_HMAP_SUFFIX id_to_id +#define ISL_HMAP isl_id_to_id +#define ISL_HMAP_HAVE_READ_FROM_STR +#define ISL_HMAP_IS_EQUAL isl_id_to_id_is_equal +#include +#undef ISL_KEY +#undef ISL_VAL +#undef ISL_HMAP_SUFFIX +#undef ISL_HMAP +#undef ISL_HMAP_HAVE_READ_FROM_STR +#undef ISL_HMAP_IS_EQUAL + +#endif diff --git a/external/mit/isl/dist/include/isl/id_to_pw_aff.h b/external/mit/isl/dist/include/isl/id_to_pw_aff.h new file mode 100644 index 000000000000..0b7a0e52cf3f --- /dev/null +++ b/external/mit/isl/dist/include/isl/id_to_pw_aff.h @@ -0,0 +1,22 @@ +#ifndef ISL_ID_TO_PW_AFF_H +#define ISL_ID_TO_PW_AFF_H + +#include +#include +#include + +#define ISL_KEY isl_id +#define ISL_VAL isl_pw_aff +#define ISL_HMAP_SUFFIX id_to_pw_aff +#define ISL_HMAP isl_id_to_pw_aff +#define ISL_HMAP_HAVE_READ_FROM_STR +#define ISL_HMAP_IS_EQUAL isl_id_to_pw_aff_plain_is_equal +#include +#undef ISL_KEY +#undef ISL_VAL +#undef ISL_HMAP_SUFFIX +#undef ISL_HMAP +#undef ISL_HMAP_HAVE_READ_FROM_STR +#undef ISL_HMAP_IS_EQUAL + +#endif diff --git a/external/mit/isl/dist/include/isl/id_type.h b/external/mit/isl/dist/include/isl/id_type.h new file mode 100644 index 000000000000..0cb3c1c43b25 --- /dev/null +++ b/external/mit/isl/dist/include/isl/id_type.h @@ -0,0 +1,22 @@ +#ifndef ISL_ID_TYPE_H +#define ISL_ID_TYPE_H + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +struct __isl_export isl_id; +typedef struct isl_id isl_id; + +ISL_DECLARE_EXPORTED_LIST_TYPE(id) + +struct __isl_export isl_multi_id; +typedef struct isl_multi_id isl_multi_id; + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/external/mit/isl/dist/include/isl/ilp.h b/external/mit/isl/dist/include/isl/ilp.h new file mode 100644 index 000000000000..5f9b8160a4a9 --- /dev/null +++ b/external/mit/isl/dist/include/isl/ilp.h @@ -0,0 +1,71 @@ +/* + * 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_ILP_H +#define ISL_ILP_H + +#include +#include +#include +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +__isl_give isl_val *isl_basic_set_max_val(__isl_keep isl_basic_set *bset, + __isl_keep isl_aff *obj); +__isl_export +__isl_give isl_val *isl_set_min_val(__isl_keep isl_set *set, + __isl_keep isl_aff *obj); +__isl_export +__isl_give isl_val *isl_set_max_val(__isl_keep isl_set *set, + __isl_keep isl_aff *obj); +__isl_give isl_multi_val *isl_union_set_min_multi_union_pw_aff( + __isl_keep isl_union_set *uset, __isl_keep isl_multi_union_pw_aff *obj); + +__isl_export +__isl_give isl_val *isl_pw_aff_min_val(__isl_take isl_pw_aff *pa); +__isl_export +__isl_give isl_val *isl_pw_aff_max_val(__isl_take isl_pw_aff *pa); +__isl_export +__isl_give isl_multi_val *isl_pw_multi_aff_min_multi_val( + __isl_take isl_pw_multi_aff *pma); +__isl_export +__isl_give isl_multi_val *isl_pw_multi_aff_max_multi_val( + __isl_take isl_pw_multi_aff *pma); +__isl_export +__isl_give isl_multi_val *isl_multi_pw_aff_min_multi_val( + __isl_take isl_multi_pw_aff *mpa); +__isl_export +__isl_give isl_multi_val *isl_multi_pw_aff_max_multi_val( + __isl_take isl_multi_pw_aff *mpa); + +__isl_give isl_val *isl_union_pw_aff_min_val(__isl_take isl_union_pw_aff *upa); +__isl_give isl_val *isl_union_pw_aff_max_val(__isl_take isl_union_pw_aff *upa); + +__isl_give isl_multi_val *isl_multi_union_pw_aff_min_multi_val( + __isl_take isl_multi_union_pw_aff *mupa); +__isl_give isl_multi_val *isl_multi_union_pw_aff_max_multi_val( + __isl_take isl_multi_union_pw_aff *mupa); + +__isl_export +__isl_give isl_val *isl_basic_set_dim_max_val(__isl_take isl_basic_set *bset, + int pos); +__isl_export +__isl_give isl_val *isl_set_dim_min_val(__isl_take isl_set *set, int pos); +__isl_export +__isl_give isl_val *isl_set_dim_max_val(__isl_take isl_set *set, int pos); + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/external/mit/isl/dist/include/isl/list.h b/external/mit/isl/dist/include/isl/list.h new file mode 100644 index 000000000000..af5d6bad99d3 --- /dev/null +++ b/external/mit/isl/dist/include/isl/list.h @@ -0,0 +1,132 @@ +/* + * 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_LIST_H +#define ISL_LIST_H + +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +#define ISL_DECLARE_LIST_TYPE2(EL,EXPORT) \ +struct isl_##EL; \ +struct EXPORT isl_##EL##_list; \ +typedef struct isl_##EL##_list isl_##EL##_list; +#define ISL_DECLARE_LIST_TYPE(EL) \ + ISL_DECLARE_LIST_TYPE2(EL,) +#define ISL_DECLARE_EXPORTED_LIST_TYPE(EL) \ + ISL_DECLARE_LIST_TYPE2(EL,__isl_export) +#define ISL_DECLARE_LIST_FN3(EL,CONSTRUCTOR,EXPORT) \ +isl_ctx *isl_##EL##_list_get_ctx(__isl_keep isl_##EL##_list *list); \ +EXPORT \ +__isl_give isl_##EL##_list *isl_##EL##_to_list(__isl_take isl_##EL *el);\ +CONSTRUCTOR \ +__isl_give isl_##EL##_list *isl_##EL##_list_from_##EL( \ + __isl_take isl_##EL *el); \ +CONSTRUCTOR \ +__isl_give isl_##EL##_list *isl_##EL##_list_alloc(isl_ctx *ctx, int n); \ +__isl_give isl_##EL##_list *isl_##EL##_list_copy( \ + __isl_keep isl_##EL##_list *list); \ +__isl_null isl_##EL##_list *isl_##EL##_list_free( \ + __isl_take isl_##EL##_list *list); \ +EXPORT \ +__isl_give isl_##EL##_list *isl_##EL##_list_add( \ + __isl_take isl_##EL##_list *list, \ + __isl_take isl_##EL *el); \ +EXPORT \ +__isl_give isl_##EL##_list *isl_##EL##_list_insert( \ + __isl_take isl_##EL##_list *list, unsigned pos, \ + __isl_take isl_##EL *el); \ +EXPORT \ +__isl_give isl_##EL##_list *isl_##EL##_list_drop( \ + __isl_take isl_##EL##_list *list, unsigned first, unsigned n); \ +EXPORT \ +__isl_give isl_##EL##_list *isl_##EL##_list_clear( \ + __isl_take isl_##EL##_list *list); \ +__isl_give isl_##EL##_list *isl_##EL##_list_swap( \ + __isl_take isl_##EL##_list *list, unsigned pos1, \ + unsigned pos2); \ +__isl_give isl_##EL##_list *isl_##EL##_list_reverse( \ + __isl_take isl_##EL##_list *list); \ +EXPORT \ +__isl_give isl_##EL##_list *isl_##EL##_list_concat( \ + __isl_take isl_##EL##_list *list1, \ + __isl_take isl_##EL##_list *list2); \ +EXPORT \ +isl_size isl_##EL##_list_size(__isl_keep isl_##EL##_list *list); \ +isl_size isl_##EL##_list_n_##EL(__isl_keep isl_##EL##_list *list); \ +EXPORT \ +__isl_give isl_##EL *isl_##EL##_list_get_at( \ + __isl_keep isl_##EL##_list *list, int index); \ +__isl_give struct isl_##EL *isl_##EL##_list_get_##EL( \ + __isl_keep isl_##EL##_list *list, int index); \ +EXPORT \ +__isl_give isl_##EL##_list *isl_##EL##_list_set_at( \ + __isl_take isl_##EL##_list *list, int index, \ + __isl_take isl_##EL *el); \ +__isl_give struct isl_##EL##_list *isl_##EL##_list_set_##EL( \ + __isl_take struct isl_##EL##_list *list, int index, \ + __isl_take struct isl_##EL *el); \ +EXPORT \ +isl_stat isl_##EL##_list_foreach(__isl_keep isl_##EL##_list *list, \ + isl_stat (*fn)(__isl_take isl_##EL *el, void *user), \ + void *user); \ +isl_bool isl_##EL##_list_every(__isl_keep isl_##EL##_list *list, \ + isl_bool (*test)(__isl_keep isl_##EL *el, void *user), \ + void *user); \ +__isl_give isl_##EL##_list *isl_##EL##_list_map( \ + __isl_take isl_##EL##_list *list, \ + __isl_give isl_##EL * (*fn)(__isl_take isl_##EL *el, \ + void *user), \ + void *user); \ +__isl_give isl_##EL##_list *isl_##EL##_list_sort( \ + __isl_take isl_##EL##_list *list, \ + int (*cmp)(__isl_keep struct isl_##EL *a, \ + __isl_keep struct isl_##EL *b, \ + void *user), void *user); \ +EXPORT \ +isl_stat isl_##EL##_list_foreach_scc(__isl_keep isl_##EL##_list *list, \ + isl_bool (*follows)(__isl_keep isl_##EL *a, \ + __isl_keep isl_##EL *b, void *user), \ + void *follows_user, \ + isl_stat (*fn)(__isl_take isl_##EL##_list *scc, void *user), \ + void *fn_user); \ +__isl_give char *isl_##EL##_list_to_str( \ + __isl_keep isl_##EL##_list *list); \ +__isl_give isl_printer *isl_printer_print_##EL##_list( \ + __isl_take isl_printer *p, __isl_keep isl_##EL##_list *list); \ +void isl_##EL##_list_dump(__isl_keep isl_##EL##_list *list); +#define ISL_DECLARE_LIST_FN(EL) \ + ISL_DECLARE_LIST_FN3(EL,,) +#define ISL_DECLARE_EXPORTED_LIST_FN(EL) \ + ISL_DECLARE_LIST_FN3(EL,__isl_constructor,__isl_export) +#define ISL_DECLARE_LIST_FN_READ2(EL,CONSTRUCTOR) \ +CONSTRUCTOR \ +__isl_give isl_##EL##_list *isl_##EL##_list_read_from_str( \ + isl_ctx *ctx, const char *str); +#define ISL_DECLARE_LIST_FN_READ(EL) \ + ISL_DECLARE_LIST_FN_READ2(EL,) +#define ISL_DECLARE_EXPORTED_LIST_FN_READ(EL) \ + ISL_DECLARE_LIST_FN_READ2(EL,__isl_constructor) + +#define ISL_DECLARE_LIST(EL) \ + ISL_DECLARE_LIST_TYPE(EL) \ + ISL_DECLARE_LIST_FN(EL) +#define ISL_DECLARE_EXPORTED_LIST(EL) \ + ISL_DECLARE_EXPORTED_LIST_TYPE(EL) \ + ISL_DECLARE_EXPORTED_LIST_FN(EL) + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/external/mit/isl/dist/include/isl/local_space.h b/external/mit/isl/dist/include/isl/local_space.h new file mode 100644 index 000000000000..51305d2ee024 --- /dev/null +++ b/external/mit/isl/dist/include/isl/local_space.h @@ -0,0 +1,98 @@ +#ifndef ISL_LOCAL_SPACE_H +#define ISL_LOCAL_SPACE_H + +#include +#include +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +struct isl_local_space; +typedef struct isl_local_space isl_local_space; + +isl_ctx *isl_local_space_get_ctx(__isl_keep isl_local_space *ls); + +__isl_give isl_local_space *isl_local_space_from_space( + __isl_take isl_space *space); + +__isl_give isl_local_space *isl_local_space_copy( + __isl_keep isl_local_space *ls); +__isl_null isl_local_space *isl_local_space_free( + __isl_take isl_local_space *ls); + +isl_bool isl_local_space_is_params(__isl_keep isl_local_space *ls); +isl_bool isl_local_space_is_set(__isl_keep isl_local_space *ls); + +__isl_give isl_local_space *isl_local_space_set_tuple_id( + __isl_take isl_local_space *ls, + enum isl_dim_type type, __isl_take isl_id *id); + +isl_size isl_local_space_dim(__isl_keep isl_local_space *ls, + enum isl_dim_type type); +isl_bool isl_local_space_has_dim_name(__isl_keep isl_local_space *ls, + enum isl_dim_type type, unsigned pos); +const char *isl_local_space_get_dim_name(__isl_keep isl_local_space *ls, + enum isl_dim_type type, unsigned pos); +__isl_give isl_local_space *isl_local_space_set_dim_name( + __isl_take isl_local_space *ls, + enum isl_dim_type type, unsigned pos, const char *s); +isl_bool isl_local_space_has_dim_id(__isl_keep isl_local_space *ls, + enum isl_dim_type type, unsigned pos); +__isl_give isl_id *isl_local_space_get_dim_id(__isl_keep isl_local_space *ls, + enum isl_dim_type type, unsigned pos); +__isl_give isl_local_space *isl_local_space_set_dim_id( + __isl_take isl_local_space *ls, + enum isl_dim_type type, unsigned pos, __isl_take isl_id *id); +__isl_give isl_space *isl_local_space_get_space(__isl_keep isl_local_space *ls); +__isl_give isl_aff *isl_local_space_get_div(__isl_keep isl_local_space *ls, + int pos); + +int isl_local_space_find_dim_by_name(__isl_keep isl_local_space *ls, + enum isl_dim_type type, const char *name); + +__isl_give isl_local_space *isl_local_space_domain( + __isl_take isl_local_space *ls); +__isl_give isl_local_space *isl_local_space_range( + __isl_take isl_local_space *ls); +__isl_give isl_local_space *isl_local_space_from_domain( + __isl_take isl_local_space *ls); +__isl_give isl_local_space *isl_local_space_add_dims( + __isl_take isl_local_space *ls, enum isl_dim_type type, unsigned n); +__isl_give isl_local_space *isl_local_space_drop_dims( + __isl_take isl_local_space *ls, + enum isl_dim_type type, unsigned first, unsigned n); +__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); + +__isl_give isl_local_space *isl_local_space_wrap( + __isl_take isl_local_space *ls); + +isl_bool isl_local_space_is_equal(__isl_keep isl_local_space *ls1, + __isl_keep isl_local_space *ls2); + +__isl_give isl_basic_map *isl_local_space_lifting( + __isl_take isl_local_space *ls); + +__isl_give isl_local_space *isl_local_space_flatten_domain( + __isl_take isl_local_space *ls); +__isl_give isl_local_space *isl_local_space_flatten_range( + __isl_take isl_local_space *ls); + +__isl_give isl_printer *isl_printer_print_local_space(__isl_take isl_printer *p, + __isl_keep isl_local_space *ls); +void isl_local_space_dump(__isl_keep isl_local_space *ls); + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/external/mit/isl/dist/include/isl/lp.h b/external/mit/isl/dist/include/isl/lp.h new file mode 100644 index 000000000000..4ca39a9fc8b0 --- /dev/null +++ b/external/mit/isl/dist/include/isl/lp.h @@ -0,0 +1,37 @@ +/* + * 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_LP_H +#define ISL_LP_H + +#include +#include +#include + +enum isl_lp_result { + isl_lp_error = -1, + isl_lp_ok = 0, + isl_lp_unbounded, + isl_lp_empty +}; + +#if defined(__cplusplus) +extern "C" { +#endif + +__isl_give isl_val *isl_basic_set_min_lp_val(__isl_keep isl_basic_set *bset, + __isl_keep isl_aff *obj); +__isl_give isl_val *isl_basic_set_max_lp_val(__isl_keep isl_basic_set *bset, + __isl_keep isl_aff *obj); + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/external/mit/isl/dist/include/isl/map.h b/external/mit/isl/dist/include/isl/map.h new file mode 100644 index 000000000000..20da7a99b9d5 --- /dev/null +++ b/external/mit/isl/dist/include/isl/map.h @@ -0,0 +1,804 @@ +/* + * 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_MAP_H +#define ISL_MAP_H + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +isl_size isl_basic_map_total_dim(__isl_keep const isl_basic_map *bmap); +isl_size isl_basic_map_dim(__isl_keep isl_basic_map *bmap, + enum isl_dim_type type); + +__isl_export +isl_size isl_map_domain_tuple_dim(__isl_keep isl_map *map); +__isl_export +isl_size isl_map_range_tuple_dim(__isl_keep isl_map *map); +isl_size isl_map_dim(__isl_keep isl_map *map, enum isl_dim_type type); + +isl_ctx *isl_basic_map_get_ctx(__isl_keep isl_basic_map *bmap); +isl_ctx *isl_map_get_ctx(__isl_keep isl_map *map); +__isl_give isl_space *isl_basic_map_get_space(__isl_keep isl_basic_map *bmap); +__isl_export +__isl_give isl_space *isl_map_get_space(__isl_keep isl_map *map); + +__isl_give isl_aff *isl_basic_map_get_div(__isl_keep isl_basic_map *bmap, + int pos); + +__isl_give isl_local_space *isl_basic_map_get_local_space( + __isl_keep isl_basic_map *bmap); + +__isl_give isl_basic_map *isl_basic_map_set_tuple_name( + __isl_take isl_basic_map *bmap, enum isl_dim_type type, const char *s); +const char *isl_basic_map_get_tuple_name(__isl_keep isl_basic_map *bmap, + enum isl_dim_type type); +isl_bool isl_map_has_tuple_name(__isl_keep isl_map *map, + enum isl_dim_type type); +const char *isl_map_get_tuple_name(__isl_keep isl_map *map, + enum isl_dim_type type); +__isl_give isl_map *isl_map_set_tuple_name(__isl_take isl_map *map, + enum isl_dim_type type, const char *s); +const char *isl_basic_map_get_dim_name(__isl_keep isl_basic_map *bmap, + enum isl_dim_type type, unsigned pos); +isl_bool isl_map_has_dim_name(__isl_keep isl_map *map, + enum isl_dim_type type, unsigned pos); +const char *isl_map_get_dim_name(__isl_keep isl_map *map, + enum isl_dim_type type, unsigned pos); +__isl_give isl_basic_map *isl_basic_map_set_dim_name( + __isl_take isl_basic_map *bmap, + enum isl_dim_type type, unsigned pos, const char *s); +__isl_give isl_map *isl_map_set_dim_name(__isl_take isl_map *map, + enum isl_dim_type type, unsigned pos, const char *s); + +__isl_give isl_basic_map *isl_basic_map_set_tuple_id( + __isl_take isl_basic_map *bmap, + enum isl_dim_type type, __isl_take isl_id *id); +__isl_give isl_map *isl_map_set_dim_id(__isl_take isl_map *map, + enum isl_dim_type type, unsigned pos, __isl_take isl_id *id); +isl_bool isl_basic_map_has_dim_id(__isl_keep isl_basic_map *bmap, + enum isl_dim_type type, unsigned pos); +isl_bool isl_map_has_dim_id(__isl_keep isl_map *map, + enum isl_dim_type type, unsigned pos); +__isl_give isl_id *isl_map_get_dim_id(__isl_keep isl_map *map, + enum isl_dim_type type, unsigned pos); +__isl_overload +__isl_give isl_map *isl_map_set_domain_tuple_id(__isl_take isl_map *map, + __isl_take isl_id *id); +__isl_overload +__isl_give isl_map *isl_map_set_range_tuple_id(__isl_take isl_map *map, + __isl_take isl_id *id); +__isl_give isl_map *isl_map_set_tuple_id(__isl_take isl_map *map, + enum isl_dim_type type, __isl_take isl_id *id); +__isl_give isl_map *isl_map_reset_tuple_id(__isl_take isl_map *map, + enum isl_dim_type type); +__isl_export +isl_bool isl_map_has_domain_tuple_id(__isl_keep isl_map *map); +__isl_export +isl_bool isl_map_has_range_tuple_id(__isl_keep isl_map *map); +isl_bool isl_map_has_tuple_id(__isl_keep isl_map *map, enum isl_dim_type type); +__isl_export +__isl_give isl_id *isl_map_get_domain_tuple_id(__isl_keep isl_map *map); +__isl_export +__isl_give isl_id *isl_map_get_range_tuple_id(__isl_keep isl_map *map); +__isl_give isl_id *isl_map_get_tuple_id(__isl_keep isl_map *map, + enum isl_dim_type type); +__isl_give isl_map *isl_map_reset_user(__isl_take isl_map *map); + +int isl_basic_map_find_dim_by_name(__isl_keep isl_basic_map *bmap, + enum isl_dim_type type, const char *name); +int isl_map_find_dim_by_id(__isl_keep isl_map *map, enum isl_dim_type type, + __isl_keep isl_id *id); +int isl_map_find_dim_by_name(__isl_keep isl_map *map, enum isl_dim_type type, + const char *name); + +isl_bool isl_basic_map_is_rational(__isl_keep isl_basic_map *bmap); + +__isl_give isl_basic_map *isl_basic_map_identity(__isl_take isl_space *space); +__isl_null isl_basic_map *isl_basic_map_free(__isl_take isl_basic_map *bmap); +__isl_give isl_basic_map *isl_basic_map_copy(__isl_keep isl_basic_map *bmap); +__isl_give isl_basic_map *isl_basic_map_equal( + __isl_take isl_space *space, unsigned n_equal); +__isl_give isl_basic_map *isl_basic_map_less_at(__isl_take isl_space *space, + unsigned pos); +__isl_give isl_basic_map *isl_basic_map_more_at(__isl_take isl_space *space, + unsigned pos); +__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 *space); +__isl_give isl_basic_map *isl_basic_map_remove_redundancies( + __isl_take isl_basic_map *bmap); +__isl_give isl_map *isl_map_remove_redundancies(__isl_take isl_map *map); +__isl_give isl_basic_map *isl_map_simple_hull(__isl_take isl_map *map); +__isl_export +__isl_give isl_basic_map *isl_map_unshifted_simple_hull( + __isl_take isl_map *map); +__isl_give isl_basic_map *isl_map_plain_unshifted_simple_hull( + __isl_take isl_map *map); +__isl_give isl_basic_map *isl_map_unshifted_simple_hull_from_map_list( + __isl_take isl_map *map, __isl_take isl_map_list *list); + +__isl_export +__isl_give isl_basic_map *isl_basic_map_intersect_domain( + __isl_take isl_basic_map *bmap, + __isl_take isl_basic_set *bset); +__isl_export +__isl_give isl_basic_map *isl_basic_map_intersect_range( + __isl_take isl_basic_map *bmap, + __isl_take isl_basic_set *bset); +__isl_export +__isl_give isl_basic_map *isl_basic_map_intersect( + __isl_take isl_basic_map *bmap1, + __isl_take isl_basic_map *bmap2); +__isl_give isl_basic_map *isl_basic_map_list_intersect( + __isl_take isl_basic_map_list *list); +__isl_export +__isl_give isl_map *isl_basic_map_union( + __isl_take isl_basic_map *bmap1, + __isl_take isl_basic_map *bmap2); +__isl_export +__isl_give isl_basic_map *isl_basic_map_apply_domain( + __isl_take isl_basic_map *bmap1, + __isl_take isl_basic_map *bmap2); +__isl_export +__isl_give isl_basic_map *isl_basic_map_apply_range( + __isl_take isl_basic_map *bmap1, + __isl_take isl_basic_map *bmap2); +__isl_export +__isl_give isl_basic_map *isl_basic_map_affine_hull( + __isl_take isl_basic_map *bmap); +__isl_give isl_basic_map *isl_basic_map_preimage_domain_multi_aff( + __isl_take isl_basic_map *bmap, __isl_take isl_multi_aff *ma); +__isl_give isl_basic_map *isl_basic_map_preimage_range_multi_aff( + __isl_take isl_basic_map *bmap, __isl_take isl_multi_aff *ma); +__isl_export +__isl_give isl_basic_map *isl_basic_map_reverse(__isl_take isl_basic_map *bmap); +__isl_give isl_basic_set *isl_basic_map_domain(__isl_take isl_basic_map *bmap); +__isl_give isl_basic_set *isl_basic_map_range(__isl_take isl_basic_map *bmap); +__isl_give isl_basic_map *isl_basic_map_domain_map( + __isl_take isl_basic_map *bmap); +__isl_give isl_basic_map *isl_basic_map_range_map( + __isl_take isl_basic_map *bmap); +__isl_give isl_basic_map *isl_basic_map_remove_dims( + __isl_take isl_basic_map *bmap, + enum isl_dim_type type, unsigned first, unsigned n); +__isl_give isl_basic_map *isl_basic_map_eliminate( + __isl_take isl_basic_map *bmap, + enum isl_dim_type type, unsigned first, unsigned n); +__isl_export +__isl_give isl_basic_map *isl_basic_map_sample(__isl_take isl_basic_map *bmap); +__isl_export +__isl_give isl_basic_map *isl_basic_map_detect_equalities( + __isl_take isl_basic_map *bmap); +__isl_give isl_basic_map *isl_basic_map_read_from_file(isl_ctx *ctx, + FILE *input); +__isl_constructor +__isl_give isl_basic_map *isl_basic_map_read_from_str(isl_ctx *ctx, + const char *str); +__isl_give isl_map *isl_map_read_from_file(isl_ctx *ctx, FILE *input); +__isl_constructor +__isl_give isl_map *isl_map_read_from_str(isl_ctx *ctx, const char *str); +void isl_basic_map_dump(__isl_keep isl_basic_map *bmap); +void isl_map_dump(__isl_keep isl_map *map); +__isl_give char *isl_basic_map_to_str(__isl_keep isl_basic_map *bmap); +__isl_give isl_printer *isl_printer_print_basic_map( + __isl_take isl_printer *printer, __isl_keep isl_basic_map *bmap); +__isl_give char *isl_map_to_str(__isl_keep isl_map *map); +__isl_give isl_printer *isl_printer_print_map(__isl_take isl_printer *printer, + __isl_keep isl_map *map); +__isl_give isl_basic_map *isl_basic_map_fix_si(__isl_take isl_basic_map *bmap, + enum isl_dim_type type, unsigned pos, int value); +__isl_give isl_basic_map *isl_basic_map_fix_val(__isl_take isl_basic_map *bmap, + enum isl_dim_type type, unsigned pos, __isl_take isl_val *v); +__isl_give isl_basic_map *isl_basic_map_lower_bound_si( + __isl_take isl_basic_map *bmap, + enum isl_dim_type type, unsigned pos, int value); +__isl_give isl_basic_map *isl_basic_map_upper_bound_si( + __isl_take isl_basic_map *bmap, + enum isl_dim_type type, unsigned pos, int value); +__isl_overload +__isl_give isl_map *isl_map_lower_bound_multi_pw_aff(__isl_take isl_map *map, + __isl_take isl_multi_pw_aff *lower); +__isl_overload +__isl_give isl_map *isl_map_upper_bound_multi_pw_aff(__isl_take isl_map *map, + __isl_take isl_multi_pw_aff *upper); + +__isl_give isl_basic_map *isl_basic_map_sum(__isl_take isl_basic_map *bmap1, + __isl_take isl_basic_map *bmap2); +__isl_give isl_basic_map *isl_basic_map_neg(__isl_take isl_basic_map *bmap); + +__isl_give isl_map *isl_map_sum(__isl_take isl_map *map1, + __isl_take isl_map *map2); +__isl_give isl_map *isl_map_neg(__isl_take isl_map *map); +__isl_give isl_map *isl_map_floordiv_val(__isl_take isl_map *map, + __isl_take isl_val *d); + +__isl_export +isl_bool isl_basic_map_is_equal(__isl_keep isl_basic_map *bmap1, + __isl_keep isl_basic_map *bmap2); +isl_bool isl_basic_map_is_disjoint(__isl_keep isl_basic_map *bmap1, + __isl_keep isl_basic_map *bmap2); + +__isl_give isl_map *isl_basic_map_partial_lexmax( + __isl_take isl_basic_map *bmap, __isl_take isl_basic_set *dom, + __isl_give isl_set **empty); +__isl_give isl_map *isl_basic_map_partial_lexmin( + __isl_take isl_basic_map *bmap, __isl_take isl_basic_set *dom, + __isl_give isl_set **empty); +__isl_give isl_map *isl_map_partial_lexmax( + __isl_take isl_map *map, __isl_take isl_set *dom, + __isl_give isl_set **empty); +__isl_give isl_map *isl_map_partial_lexmin( + __isl_take isl_map *map, __isl_take isl_set *dom, + __isl_give isl_set **empty); +__isl_export +__isl_give isl_map *isl_basic_map_lexmin(__isl_take isl_basic_map *bmap); +__isl_export +__isl_give isl_map *isl_basic_map_lexmax(__isl_take isl_basic_map *bmap); +__isl_export +__isl_give isl_map *isl_map_lexmin(__isl_take isl_map *map); +__isl_export +__isl_give isl_map *isl_map_lexmax(__isl_take isl_map *map); +__isl_give isl_pw_multi_aff *isl_basic_map_partial_lexmin_pw_multi_aff( + __isl_take isl_basic_map *bmap, __isl_take isl_basic_set *dom, + __isl_give isl_set **empty); +__isl_give isl_pw_multi_aff *isl_basic_map_partial_lexmax_pw_multi_aff( + __isl_take isl_basic_map *bmap, __isl_take isl_basic_set *dom, + __isl_give isl_set **empty); +__isl_give isl_pw_multi_aff *isl_basic_map_lexmin_pw_multi_aff( + __isl_take isl_basic_map *bmap); +__isl_export +__isl_give isl_pw_multi_aff *isl_map_lexmin_pw_multi_aff( + __isl_take isl_map *map); +__isl_export +__isl_give isl_pw_multi_aff *isl_map_lexmax_pw_multi_aff( + __isl_take isl_map *map); +__isl_export +__isl_give isl_multi_pw_aff *isl_map_min_multi_pw_aff(__isl_take isl_map *map); +__isl_export +__isl_give isl_multi_pw_aff *isl_map_max_multi_pw_aff(__isl_take isl_map *map); + +void isl_basic_map_print_internal(__isl_keep isl_basic_map *bmap, + FILE *out, int indent); + +__isl_give isl_val *isl_basic_map_plain_get_val_if_fixed( + __isl_keep isl_basic_map *bmap, + enum isl_dim_type type, unsigned pos); + +isl_bool isl_basic_map_image_is_bounded(__isl_keep isl_basic_map *bmap); +isl_bool isl_basic_map_plain_is_universe(__isl_keep isl_basic_map *bmap); +isl_bool isl_basic_map_is_universe(__isl_keep isl_basic_map *bmap); +isl_bool isl_basic_map_plain_is_empty(__isl_keep isl_basic_map *bmap); +__isl_export +isl_bool isl_basic_map_is_empty(__isl_keep isl_basic_map *bmap); +__isl_export +isl_bool isl_basic_map_is_subset(__isl_keep isl_basic_map *bmap1, + __isl_keep isl_basic_map *bmap2); +isl_bool isl_basic_map_is_strict_subset(__isl_keep isl_basic_map *bmap1, + __isl_keep isl_basic_map *bmap2); + +__isl_export +__isl_give isl_map *isl_map_universe(__isl_take isl_space *space); +__isl_export +__isl_give isl_map *isl_space_universe_map(__isl_take isl_space *space); +__isl_give isl_map *isl_map_nat_universe(__isl_take isl_space *space); +__isl_export +__isl_give isl_map *isl_map_empty(__isl_take isl_space *space); +__isl_give isl_map *isl_map_identity(__isl_take isl_space *space); +__isl_give isl_map *isl_map_lex_lt_first(__isl_take isl_space *space, + unsigned n); +__isl_give isl_map *isl_map_lex_le_first(__isl_take isl_space *space, + unsigned n); +__isl_give isl_map *isl_map_lex_lt(__isl_take isl_space *set_space); +__isl_give isl_map *isl_map_lex_le(__isl_take isl_space *set_space); +__isl_give isl_map *isl_map_lex_gt_first(__isl_take isl_space *space, + unsigned n); +__isl_give isl_map *isl_map_lex_ge_first(__isl_take isl_space *space, + unsigned n); +__isl_give isl_map *isl_map_lex_gt(__isl_take isl_space *set_space); +__isl_give isl_map *isl_map_lex_ge(__isl_take isl_space *set_space); +__isl_null isl_map *isl_map_free(__isl_take isl_map *map); +__isl_give isl_map *isl_map_copy(__isl_keep isl_map *map); +__isl_export +__isl_give isl_map *isl_map_reverse(__isl_take isl_map *map); +__isl_export +__isl_give isl_map *isl_map_domain_reverse(__isl_take isl_map *map); +__isl_export +__isl_give isl_map *isl_map_range_reverse(__isl_take isl_map *map); +__isl_export +__isl_give isl_map *isl_map_union( + __isl_take isl_map *map1, + __isl_take isl_map *map2); +__isl_give isl_map *isl_map_union_disjoint( + __isl_take isl_map *map1, __isl_take isl_map *map2); +__isl_export +__isl_give isl_map *isl_map_intersect_domain( + __isl_take isl_map *map, + __isl_take isl_set *set); +__isl_export +__isl_give isl_map *isl_map_intersect_range( + __isl_take isl_map *map, + __isl_take isl_set *set); +__isl_export +__isl_give isl_map *isl_map_intersect_domain_factor_domain( + __isl_take isl_map *map, __isl_take isl_map *factor); +__isl_export +__isl_give isl_map *isl_map_intersect_domain_factor_range( + __isl_take isl_map *map, __isl_take isl_map *factor); +__isl_export +__isl_give isl_map *isl_map_intersect_range_factor_domain( + __isl_take isl_map *map, __isl_take isl_map *factor); +__isl_export +__isl_give isl_map *isl_map_intersect_range_factor_range( + __isl_take isl_map *map, __isl_take isl_map *factor); +__isl_export +__isl_give isl_map *isl_map_intersect_domain_wrapped_domain( + __isl_take isl_map *map, __isl_take isl_set *domain); +__isl_export +__isl_give isl_map *isl_map_intersect_range_wrapped_domain( + __isl_take isl_map *map, __isl_take isl_set *domain); +__isl_export +__isl_give isl_map *isl_map_apply_domain( + __isl_take isl_map *map1, + __isl_take isl_map *map2); +__isl_export +__isl_give isl_map *isl_map_apply_range( + __isl_take isl_map *map1, + __isl_take isl_map *map2); +__isl_overload +__isl_give isl_map *isl_map_preimage_domain_multi_aff(__isl_take isl_map *map, + __isl_take isl_multi_aff *ma); +__isl_overload +__isl_give isl_map *isl_map_preimage_range_multi_aff(__isl_take isl_map *map, + __isl_take isl_multi_aff *ma); +__isl_overload +__isl_give isl_map *isl_map_preimage_domain_pw_multi_aff( + __isl_take isl_map *map, __isl_take isl_pw_multi_aff *pma); +__isl_overload +__isl_give isl_map *isl_map_preimage_range_pw_multi_aff( + __isl_take isl_map *map, __isl_take isl_pw_multi_aff *pma); +__isl_overload +__isl_give isl_map *isl_map_preimage_domain_multi_pw_aff( + __isl_take isl_map *map, __isl_take isl_multi_pw_aff *mpa); +__isl_give isl_basic_map *isl_basic_map_product( + __isl_take isl_basic_map *bmap1, __isl_take isl_basic_map *bmap2); +__isl_export +__isl_give isl_map *isl_map_product(__isl_take isl_map *map1, + __isl_take isl_map *map2); +__isl_give isl_basic_map *isl_basic_map_domain_product( + __isl_take isl_basic_map *bmap1, __isl_take isl_basic_map *bmap2); +__isl_give isl_basic_map *isl_basic_map_range_product( + __isl_take isl_basic_map *bmap1, __isl_take isl_basic_map *bmap2); +__isl_export +__isl_give isl_map *isl_map_domain_product(__isl_take isl_map *map1, + __isl_take isl_map *map2); +__isl_export +__isl_give isl_map *isl_map_range_product(__isl_take isl_map *map1, + __isl_take isl_map *map2); +__isl_give isl_basic_map *isl_basic_map_flat_product( + __isl_take isl_basic_map *bmap1, __isl_take isl_basic_map *bmap2); +__isl_give isl_map *isl_map_flat_product(__isl_take isl_map *map1, + __isl_take isl_map *map2); +__isl_give isl_basic_map *isl_basic_map_flat_range_product( + __isl_take isl_basic_map *bmap1, __isl_take isl_basic_map *bmap2); +__isl_give isl_map *isl_map_flat_domain_product(__isl_take isl_map *map1, + __isl_take isl_map *map2); +__isl_give isl_map *isl_map_flat_range_product(__isl_take isl_map *map1, + __isl_take isl_map *map2); +isl_bool isl_map_domain_is_wrapping(__isl_keep isl_map *map); +isl_bool isl_map_range_is_wrapping(__isl_keep isl_map *map); +isl_bool isl_map_is_product(__isl_keep isl_map *map); +__isl_export +__isl_give isl_map *isl_map_factor_domain(__isl_take isl_map *map); +__isl_export +__isl_give isl_map *isl_map_factor_range(__isl_take isl_map *map); +__isl_export +__isl_give isl_map *isl_map_domain_factor_domain(__isl_take isl_map *map); +__isl_export +__isl_give isl_map *isl_map_domain_factor_range(__isl_take isl_map *map); +__isl_export +__isl_give isl_map *isl_map_range_factor_domain(__isl_take isl_map *map); +__isl_export +__isl_give isl_map *isl_map_range_factor_range(__isl_take isl_map *map); +__isl_export +__isl_give isl_map *isl_map_intersect(__isl_take isl_map *map1, + __isl_take isl_map *map2); +__isl_export +__isl_give isl_map *isl_map_intersect_params(__isl_take isl_map *map, + __isl_take isl_set *params); +__isl_export +__isl_give isl_map *isl_map_subtract( + __isl_take isl_map *map1, + __isl_take isl_map *map2); +__isl_give isl_map *isl_map_subtract_domain(__isl_take isl_map *map, + __isl_take isl_set *dom); +__isl_give isl_map *isl_map_subtract_range(__isl_take isl_map *map, + __isl_take isl_set *dom); +__isl_export +__isl_give isl_map *isl_map_complement(__isl_take isl_map *map); +__isl_give isl_map *isl_map_fix_input_si(__isl_take isl_map *map, + unsigned input, int value); +__isl_give isl_map *isl_map_fix_si(__isl_take isl_map *map, + enum isl_dim_type type, unsigned pos, int value); +__isl_give isl_map *isl_map_fix_val(__isl_take isl_map *map, + enum isl_dim_type type, unsigned pos, __isl_take isl_val *v); +__isl_give isl_map *isl_map_lower_bound_si(__isl_take isl_map *map, + enum isl_dim_type type, unsigned pos, int value); +__isl_give isl_map *isl_map_lower_bound_val(__isl_take isl_map *map, + enum isl_dim_type type, unsigned pos, __isl_take isl_val *value); +__isl_give isl_map *isl_map_upper_bound_si(__isl_take isl_map *map, + enum isl_dim_type type, unsigned pos, int value); +__isl_give isl_map *isl_map_upper_bound_val(__isl_take isl_map *map, + enum isl_dim_type type, unsigned pos, __isl_take isl_val *value); +__isl_export +__isl_give isl_basic_set *isl_basic_map_deltas(__isl_take isl_basic_map *bmap); +__isl_export +__isl_give isl_set *isl_map_deltas(__isl_take isl_map *map); +__isl_give isl_basic_map *isl_basic_map_deltas_map( + __isl_take isl_basic_map *bmap); +__isl_give isl_map *isl_map_deltas_map(__isl_take isl_map *map); +__isl_export +__isl_give isl_map *isl_map_detect_equalities(__isl_take isl_map *map); +__isl_export +__isl_give isl_basic_map *isl_map_affine_hull(__isl_take isl_map *map); +__isl_give isl_basic_map *isl_map_convex_hull(__isl_take isl_map *map); +__isl_export +__isl_give isl_basic_map *isl_map_polyhedral_hull(__isl_take isl_map *map); +__isl_give isl_basic_map *isl_basic_map_add_dims(__isl_take isl_basic_map *bmap, + enum isl_dim_type type, unsigned n); +__isl_give isl_map *isl_map_add_dims(__isl_take isl_map *map, + enum isl_dim_type type, unsigned n); +__isl_give isl_basic_map *isl_basic_map_insert_dims( + __isl_take isl_basic_map *bmap, enum isl_dim_type type, + unsigned pos, unsigned n); +__isl_give isl_map *isl_map_insert_dims(__isl_take isl_map *map, + enum isl_dim_type type, unsigned pos, unsigned n); +__isl_give isl_basic_map *isl_basic_map_move_dims( + __isl_take isl_basic_map *bmap, + enum isl_dim_type dst_type, unsigned dst_pos, + enum isl_dim_type src_type, unsigned src_pos, unsigned n); +__isl_give isl_map *isl_map_move_dims(__isl_take isl_map *map, + enum isl_dim_type dst_type, unsigned dst_pos, + enum isl_dim_type src_type, unsigned src_pos, unsigned n); +__isl_give isl_basic_map *isl_basic_map_project_out( + __isl_take isl_basic_map *bmap, + enum isl_dim_type type, unsigned first, unsigned n); +__isl_overload +__isl_give isl_map *isl_map_project_out_param_id(__isl_take isl_map *map, + __isl_take isl_id *id); +__isl_overload +__isl_give isl_map *isl_map_project_out_param_id_list(__isl_take isl_map *map, + __isl_take isl_id_list *list); +__isl_give isl_map *isl_map_project_out(__isl_take isl_map *map, + enum isl_dim_type type, unsigned first, unsigned n); +__isl_export +__isl_give isl_map *isl_map_project_out_all_params(__isl_take isl_map *map); +__isl_give isl_basic_map *isl_basic_map_remove_divs( + __isl_take isl_basic_map *bmap); +__isl_give isl_map *isl_map_remove_unknown_divs(__isl_take isl_map *map); +__isl_give isl_map *isl_map_remove_divs(__isl_take isl_map *map); +__isl_give isl_map *isl_map_eliminate(__isl_take isl_map *map, + enum isl_dim_type type, unsigned first, unsigned n); +__isl_give isl_map *isl_map_remove_dims(__isl_take isl_map *map, + enum isl_dim_type type, unsigned first, unsigned n); +__isl_give isl_basic_map *isl_basic_map_remove_divs_involving_dims( + __isl_take isl_basic_map *bmap, + enum isl_dim_type type, unsigned first, unsigned n); +__isl_give isl_map *isl_map_remove_divs_involving_dims(__isl_take isl_map *map, + enum isl_dim_type type, unsigned first, unsigned n); +__isl_give isl_map *isl_map_remove_inputs(__isl_take isl_map *map, + unsigned first, unsigned n); + +__isl_give isl_basic_map *isl_basic_map_equate(__isl_take isl_basic_map *bmap, + enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2); +__isl_give isl_basic_map *isl_basic_map_order_ge(__isl_take isl_basic_map *bmap, + enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2); +__isl_give isl_map *isl_map_order_ge(__isl_take isl_map *map, + enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2); +__isl_give isl_map *isl_map_order_le(__isl_take isl_map *map, + enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2); +__isl_give isl_map *isl_map_equate(__isl_take isl_map *map, + enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2); +__isl_give isl_map *isl_map_oppose(__isl_take isl_map *map, + enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2); +__isl_give isl_map *isl_map_order_lt(__isl_take isl_map *map, + enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2); +__isl_give isl_basic_map *isl_basic_map_order_gt(__isl_take isl_basic_map *bmap, + enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2); +__isl_give isl_map *isl_map_order_gt(__isl_take isl_map *map, + enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2); + +__isl_export +__isl_give isl_map *isl_set_translation(__isl_take isl_set *deltas); +__isl_export +__isl_give isl_map *isl_set_identity(__isl_take isl_set *set); + +__isl_export +isl_bool isl_basic_set_is_wrapping(__isl_keep isl_basic_set *bset); +__isl_export +isl_bool isl_set_is_wrapping(__isl_keep isl_set *set); +__isl_give isl_basic_set *isl_basic_map_wrap(__isl_take isl_basic_map *bmap); +__isl_export +__isl_give isl_set *isl_map_wrap(__isl_take isl_map *map); +__isl_give isl_basic_map *isl_basic_set_unwrap(__isl_take isl_basic_set *bset); +__isl_export +__isl_give isl_map *isl_set_unwrap(__isl_take isl_set *set); +__isl_export +__isl_give isl_basic_map *isl_basic_map_flatten(__isl_take isl_basic_map *bmap); +__isl_export +__isl_give isl_map *isl_map_flatten(__isl_take isl_map *map); +__isl_export +__isl_give isl_basic_map *isl_basic_map_flatten_domain( + __isl_take isl_basic_map *bmap); +__isl_export +__isl_give isl_basic_map *isl_basic_map_flatten_range( + __isl_take isl_basic_map *bmap); +__isl_export +__isl_give isl_map *isl_map_flatten_domain(__isl_take isl_map *map); +__isl_export +__isl_give isl_map *isl_map_flatten_range(__isl_take isl_map *map); +__isl_export +__isl_give isl_basic_set *isl_basic_set_flatten(__isl_take isl_basic_set *bset); +__isl_export +__isl_give isl_set *isl_set_flatten(__isl_take isl_set *set); +__isl_give isl_map *isl_set_flatten_map(__isl_take isl_set *set); +__isl_export +__isl_give isl_set *isl_map_params(__isl_take isl_map *map); +__isl_export +__isl_give isl_set *isl_map_domain(__isl_take isl_map *bmap); +__isl_export +__isl_give isl_set *isl_map_range(__isl_take isl_map *map); +__isl_export +__isl_give isl_map *isl_set_insert_domain(__isl_take isl_set *set, + __isl_take isl_space *domain); +__isl_give isl_map *isl_map_domain_map(__isl_take isl_map *map); +__isl_give isl_map *isl_map_range_map(__isl_take isl_map *map); +__isl_give isl_map *isl_set_wrapped_domain_map(__isl_take isl_set *set); +__isl_constructor +__isl_give isl_map *isl_map_from_basic_map(__isl_take isl_basic_map *bmap); +__isl_give isl_map *isl_map_from_domain(__isl_take isl_set *set); +__isl_give isl_basic_map *isl_basic_map_from_domain( + __isl_take isl_basic_set *bset); +__isl_give isl_basic_map *isl_basic_map_from_range( + __isl_take isl_basic_set *bset); +__isl_give isl_map *isl_map_from_range(__isl_take isl_set *set); +__isl_give isl_basic_map *isl_basic_map_from_domain_and_range( + __isl_take isl_basic_set *domain, __isl_take isl_basic_set *range); +__isl_give isl_map *isl_map_from_domain_and_range(__isl_take isl_set *domain, + __isl_take isl_set *range); +__isl_export +__isl_give isl_basic_map *isl_map_sample(__isl_take isl_map *map); + +__isl_export +__isl_give isl_set *isl_map_bind_domain(__isl_take isl_map *map, + __isl_take isl_multi_id *tuple); +__isl_export +__isl_give isl_set *isl_map_bind_range(__isl_take isl_map *map, + __isl_take isl_multi_id *tuple); + +isl_bool isl_map_plain_is_empty(__isl_keep isl_map *map); +isl_bool isl_map_plain_is_universe(__isl_keep isl_map *map); +__isl_export +isl_bool isl_map_is_empty(__isl_keep isl_map *map); +__isl_export +isl_bool isl_map_is_subset(__isl_keep isl_map *map1, __isl_keep isl_map *map2); +__isl_export +isl_bool isl_map_is_strict_subset(__isl_keep isl_map *map1, + __isl_keep isl_map *map2); +__isl_export +isl_bool isl_map_is_equal(__isl_keep isl_map *map1, __isl_keep isl_map *map2); +__isl_export +isl_bool isl_map_is_disjoint(__isl_keep isl_map *map1, + __isl_keep isl_map *map2); +isl_bool isl_basic_map_is_single_valued(__isl_keep isl_basic_map *bmap); +isl_bool isl_map_plain_is_single_valued(__isl_keep isl_map *map); +__isl_export +isl_bool isl_map_is_single_valued(__isl_keep isl_map *map); +isl_bool isl_map_plain_is_injective(__isl_keep isl_map *map); +__isl_export +isl_bool isl_map_is_injective(__isl_keep isl_map *map); +__isl_export +isl_bool isl_map_is_bijective(__isl_keep isl_map *map); +isl_bool isl_map_is_identity(__isl_keep isl_map *map); +int isl_map_is_translation(__isl_keep isl_map *map); +isl_bool isl_map_has_equal_space(__isl_keep isl_map *map1, + __isl_keep isl_map *map2); + +isl_bool isl_basic_map_can_zip(__isl_keep isl_basic_map *bmap); +isl_bool isl_map_can_zip(__isl_keep isl_map *map); +__isl_give isl_basic_map *isl_basic_map_zip(__isl_take isl_basic_map *bmap); +__isl_export +__isl_give isl_map *isl_map_zip(__isl_take isl_map *map); + +isl_bool isl_basic_map_can_curry(__isl_keep isl_basic_map *bmap); +isl_bool isl_map_can_curry(__isl_keep isl_map *map); +__isl_give isl_basic_map *isl_basic_map_curry(__isl_take isl_basic_map *bmap); +__isl_export +__isl_give isl_map *isl_map_curry(__isl_take isl_map *map); + +isl_bool isl_map_can_range_curry(__isl_keep isl_map *map); +__isl_give isl_map *isl_map_range_curry(__isl_take isl_map *map); + +isl_bool isl_basic_map_can_uncurry(__isl_keep isl_basic_map *bmap); +isl_bool isl_map_can_uncurry(__isl_keep isl_map *map); +__isl_give isl_basic_map *isl_basic_map_uncurry(__isl_take isl_basic_map *bmap); +__isl_export +__isl_give isl_map *isl_map_uncurry(__isl_take isl_map *map); + +__isl_give isl_map *isl_map_make_disjoint(__isl_take isl_map *map); +__isl_give isl_map *isl_basic_map_compute_divs(__isl_take isl_basic_map *bmap); +__isl_give isl_map *isl_map_compute_divs(__isl_take isl_map *map); +ISL_DEPRECATED +__isl_give isl_map *isl_map_align_divs(__isl_take isl_map *map); + +__isl_give isl_basic_map *isl_basic_map_drop_constraints_involving_dims( + __isl_take isl_basic_map *bmap, + enum isl_dim_type type, unsigned first, unsigned n); +__isl_give isl_basic_map *isl_basic_map_drop_constraints_not_involving_dims( + __isl_take isl_basic_map *bmap, + enum isl_dim_type type, unsigned first, unsigned n); +__isl_give isl_map *isl_map_drop_constraints_involving_dims( + __isl_take isl_map *map, + enum isl_dim_type type, unsigned first, unsigned n); +__isl_give isl_map *isl_map_drop_constraints_not_involving_dims( + __isl_take isl_map *map, + enum isl_dim_type type, unsigned first, unsigned n); + +isl_bool isl_basic_map_involves_dims(__isl_keep isl_basic_map *bmap, + enum isl_dim_type type, unsigned first, unsigned n); +isl_bool isl_map_involves_dims(__isl_keep isl_map *map, + enum isl_dim_type type, unsigned first, unsigned n); + +void isl_map_print_internal(__isl_keep isl_map *map, FILE *out, int indent); + +__isl_give isl_val *isl_map_plain_get_val_if_fixed(__isl_keep isl_map *map, + enum isl_dim_type type, unsigned pos); + +__isl_give isl_basic_map *isl_basic_map_gist_domain( + __isl_take isl_basic_map *bmap, __isl_take isl_basic_set *context); +__isl_export +__isl_give isl_basic_map *isl_basic_map_gist(__isl_take isl_basic_map *bmap, + __isl_take isl_basic_map *context); +__isl_export +__isl_give isl_map *isl_map_gist(__isl_take isl_map *map, + __isl_take isl_map *context); +__isl_export +__isl_give isl_map *isl_map_gist_domain(__isl_take isl_map *map, + __isl_take isl_set *context); +__isl_give isl_map *isl_map_gist_range(__isl_take isl_map *map, + __isl_take isl_set *context); +__isl_export +__isl_give isl_map *isl_map_gist_params(__isl_take isl_map *map, + __isl_take isl_set *context); +__isl_give isl_map *isl_map_gist_basic_map(__isl_take isl_map *map, + __isl_take isl_basic_map *context); + +__isl_give isl_stride_info *isl_map_get_range_stride_info( + __isl_keep isl_map *map, int pos); +__isl_export +__isl_give isl_fixed_box *isl_map_get_range_lattice_tile( + __isl_keep isl_map *map); +__isl_export +__isl_give isl_fixed_box *isl_map_get_range_simple_fixed_box_hull( + __isl_keep isl_map *map); + +__isl_export +__isl_give isl_map *isl_map_coalesce(__isl_take isl_map *map); + +isl_bool isl_map_plain_is_equal(__isl_keep isl_map *map1, + __isl_keep isl_map *map2); + +uint32_t isl_map_get_hash(__isl_keep isl_map *map); + +__isl_export +isl_size isl_map_n_basic_map(__isl_keep isl_map *map); +__isl_export +isl_stat isl_map_foreach_basic_map(__isl_keep isl_map *map, + isl_stat (*fn)(__isl_take isl_basic_map *bmap, void *user), void *user); +__isl_give isl_basic_map_list *isl_map_get_basic_map_list( + __isl_keep isl_map *map); + +__isl_overload +__isl_give isl_map *isl_map_fixed_power_val(__isl_take isl_map *map, + __isl_take isl_val *exp); +__isl_give isl_map *isl_map_power(__isl_take isl_map *map, isl_bool *exact); +__isl_give isl_map *isl_map_reaching_path_lengths(__isl_take isl_map *map, + isl_bool *exact); +__isl_give isl_map *isl_map_transitive_closure(__isl_take isl_map *map, + isl_bool *exact); + +__isl_give isl_map *isl_map_lex_le_map(__isl_take isl_map *map1, + __isl_take isl_map *map2); +__isl_give isl_map *isl_map_lex_lt_map(__isl_take isl_map *map1, + __isl_take isl_map *map2); +__isl_give isl_map *isl_map_lex_ge_map(__isl_take isl_map *map1, + __isl_take isl_map *map2); +__isl_give isl_map *isl_map_lex_gt_map(__isl_take isl_map *map1, + __isl_take isl_map *map2); + +__isl_overload +__isl_give isl_map *isl_map_eq_at_multi_pw_aff(__isl_take isl_map *map, + __isl_take isl_multi_pw_aff *mpa); +__isl_overload +__isl_give isl_map *isl_map_lex_lt_at_multi_pw_aff(__isl_take isl_map *map, + __isl_take isl_multi_pw_aff *mpa); +__isl_overload +__isl_give isl_map *isl_map_lex_le_at_multi_pw_aff(__isl_take isl_map *map, + __isl_take isl_multi_pw_aff *mpa); +__isl_overload +__isl_give isl_map *isl_map_lex_gt_at_multi_pw_aff(__isl_take isl_map *map, + __isl_take isl_multi_pw_aff *mpa); +__isl_overload +__isl_give isl_map *isl_map_lex_ge_at_multi_pw_aff(__isl_take isl_map *map, + __isl_take isl_multi_pw_aff *mpa); + +__isl_give isl_basic_map *isl_basic_map_align_params( + __isl_take isl_basic_map *bmap, __isl_take isl_space *model); +__isl_give isl_map *isl_map_align_params(__isl_take isl_map *map, + __isl_take isl_space *model); +__isl_give isl_basic_map *isl_basic_map_drop_unused_params( + __isl_take isl_basic_map *bmap); +__isl_export +__isl_give isl_map *isl_map_drop_unused_params(__isl_take isl_map *map); + +__isl_give isl_mat *isl_basic_map_equalities_matrix( + __isl_keep isl_basic_map *bmap, enum isl_dim_type c1, + enum isl_dim_type c2, enum isl_dim_type c3, + enum isl_dim_type c4, enum isl_dim_type c5); +__isl_give isl_mat *isl_basic_map_inequalities_matrix( + __isl_keep isl_basic_map *bmap, enum isl_dim_type c1, + enum isl_dim_type c2, enum isl_dim_type c3, + enum isl_dim_type c4, enum isl_dim_type c5); +__isl_give isl_basic_map *isl_basic_map_from_constraint_matrices( + __isl_take isl_space *space, + __isl_take isl_mat *eq, __isl_take isl_mat *ineq, enum isl_dim_type c1, + enum isl_dim_type c2, enum isl_dim_type c3, + enum isl_dim_type c4, enum isl_dim_type c5); + +__isl_give isl_basic_map *isl_basic_map_from_aff(__isl_take isl_aff *aff); +__isl_give isl_basic_map *isl_basic_map_from_multi_aff( + __isl_take isl_multi_aff *maff); +__isl_give isl_basic_map *isl_basic_map_from_aff_list( + __isl_take isl_space *domain_space, __isl_take isl_aff_list *list); + +__isl_give isl_map *isl_map_from_aff(__isl_take isl_aff *aff); +__isl_export +__isl_give isl_map *isl_multi_aff_as_map(__isl_take isl_multi_aff *ma); +__isl_give isl_map *isl_map_from_multi_aff(__isl_take isl_multi_aff *maff); + +__isl_give isl_pw_aff *isl_map_dim_min(__isl_take isl_map *map, int pos); +__isl_give isl_pw_aff *isl_map_dim_max(__isl_take isl_map *map, int pos); + +ISL_DECLARE_LIST_FN(basic_map) +ISL_DECLARE_EXPORTED_LIST_FN(map) +ISL_DECLARE_EXPORTED_LIST_FN_READ(map) + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/external/mit/isl/dist/include/isl/map_to_basic_set.h b/external/mit/isl/dist/include/isl/map_to_basic_set.h new file mode 100644 index 000000000000..da86aacf4ac1 --- /dev/null +++ b/external/mit/isl/dist/include/isl/map_to_basic_set.h @@ -0,0 +1,22 @@ +#ifndef ISL_MAP_TO_BASIC_SET_H +#define ISL_MAP_TO_BASIC_SET_H + +#include +#include +#include + +#define ISL_KEY isl_map +#define ISL_VAL isl_basic_set +#define ISL_HMAP_SUFFIX map_to_basic_set +#define ISL_HMAP isl_map_to_basic_set +#define ISL_HMAP_HAVE_READ_FROM_STR +#define ISL_HMAP_IS_EQUAL isl_map_to_basic_set_plain_is_equal +#include +#undef ISL_KEY +#undef ISL_VAL +#undef ISL_HMAP_SUFFIX +#undef ISL_HMAP +#undef ISL_HMAP_HAVE_READ_FROM_STR +#undef ISL_HMAP_IS_EQUAL + +#endif diff --git a/external/mit/isl/dist/include/isl/map_type.h b/external/mit/isl/dist/include/isl/map_type.h new file mode 100644 index 000000000000..731dfeddda85 --- /dev/null +++ b/external/mit/isl/dist/include/isl/map_type.h @@ -0,0 +1,38 @@ +#ifndef ISL_MAP_TYPE_H +#define ISL_MAP_TYPE_H + +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +struct __isl_subclass(isl_map) isl_basic_map; +typedef struct isl_basic_map isl_basic_map; +ISL_DECLARE_LIST_TYPE(basic_map) +struct __isl_subclass(isl_union_map) isl_map; +typedef struct isl_map isl_map; +ISL_DECLARE_EXPORTED_LIST_TYPE(map) + +#ifndef isl_basic_set +struct __isl_subclass(isl_set) isl_basic_set; +typedef struct isl_basic_set isl_basic_set; +ISL_DECLARE_LIST_TYPE(basic_set) +#endif + +#ifndef isl_set +struct __isl_subclass(isl_union_set) isl_set; +typedef struct isl_set isl_set; +ISL_DECLARE_EXPORTED_LIST_TYPE(set) +#endif + +ISL_DECLARE_LIST_FN(basic_set) +ISL_DECLARE_EXPORTED_LIST_FN(set) +ISL_DECLARE_EXPORTED_LIST_FN_READ(set) + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/external/mit/isl/dist/include/isl/mat.h b/external/mit/isl/dist/include/isl/mat.h new file mode 100644 index 000000000000..0ec6b935cf45 --- /dev/null +++ b/external/mit/isl/dist/include/isl/mat.h @@ -0,0 +1,119 @@ +/* + * 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_MAT_H +#define ISL_MAT_H + +#include + +#include +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +struct isl_mat; +typedef struct isl_mat isl_mat; + +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_extend(__isl_take isl_mat *mat, + unsigned n_row, unsigned n_col); +__isl_give isl_mat *isl_mat_identity(isl_ctx *ctx, unsigned n_row); +__isl_give isl_mat *isl_mat_copy(__isl_keep isl_mat *mat); +__isl_null isl_mat *isl_mat_free(__isl_take isl_mat *mat); + +isl_size isl_mat_rows(__isl_keep isl_mat *mat); +isl_size isl_mat_cols(__isl_keep isl_mat *mat); +__isl_give isl_val *isl_mat_get_element_val(__isl_keep isl_mat *mat, + int row, int col); +__isl_give isl_mat *isl_mat_set_element_si(__isl_take isl_mat *mat, + int row, int col, int v); +__isl_give isl_mat *isl_mat_set_element_val(__isl_take isl_mat *mat, + int row, int col, __isl_take isl_val *v); + +__isl_give isl_mat *isl_mat_swap_cols(__isl_take isl_mat *mat, + unsigned i, unsigned j); +__isl_give isl_mat *isl_mat_swap_rows(__isl_take isl_mat *mat, + unsigned i, unsigned j); + +__isl_give isl_vec *isl_mat_vec_product(__isl_take isl_mat *mat, + __isl_take isl_vec *vec); +__isl_give isl_vec *isl_vec_mat_product(__isl_take isl_vec *vec, + __isl_take isl_mat *mat); +__isl_give isl_vec *isl_mat_vec_inverse_product(__isl_take isl_mat *mat, + __isl_take isl_vec *vec); +__isl_give isl_mat *isl_mat_aff_direct_sum(__isl_take isl_mat *left, + __isl_take isl_mat *right); +__isl_give isl_mat *isl_mat_diagonal(__isl_take isl_mat *mat1, + __isl_take isl_mat *mat2); +__isl_give isl_mat *isl_mat_left_hermite(__isl_take isl_mat *M, int neg, + __isl_give isl_mat **U, __isl_give isl_mat **Q); +__isl_give isl_mat *isl_mat_lin_to_aff(__isl_take isl_mat *mat); +__isl_give isl_mat *isl_mat_inverse_product(__isl_take isl_mat *left, + __isl_take isl_mat *right); +__isl_give isl_mat *isl_mat_product(__isl_take isl_mat *left, + __isl_take isl_mat *right); +__isl_give isl_mat *isl_mat_transpose(__isl_take isl_mat *mat); +__isl_give isl_mat *isl_mat_right_inverse(__isl_take isl_mat *mat); +__isl_give isl_mat *isl_mat_right_kernel(__isl_take isl_mat *mat); + +__isl_give isl_mat *isl_mat_normalize(__isl_take isl_mat *mat); +__isl_give isl_mat *isl_mat_normalize_row(__isl_take isl_mat *mat, int row); + +__isl_give isl_mat *isl_mat_drop_cols(__isl_take isl_mat *mat, + unsigned col, unsigned n); +__isl_give isl_mat *isl_mat_drop_rows(__isl_take isl_mat *mat, + unsigned row, unsigned n); +__isl_give isl_mat *isl_mat_insert_cols(__isl_take isl_mat *mat, + unsigned col, unsigned n); +__isl_give isl_mat *isl_mat_insert_rows(__isl_take isl_mat *mat, + unsigned row, unsigned n); +__isl_give isl_mat *isl_mat_move_cols(__isl_take isl_mat *mat, + unsigned dst_col, unsigned src_col, unsigned n); +__isl_give isl_mat *isl_mat_add_rows(__isl_take isl_mat *mat, unsigned n); +__isl_give isl_mat *isl_mat_insert_zero_cols(__isl_take isl_mat *mat, + unsigned first, unsigned n); +__isl_give isl_mat *isl_mat_add_zero_cols(__isl_take isl_mat *mat, unsigned n); +__isl_give isl_mat *isl_mat_insert_zero_rows(__isl_take isl_mat *mat, + unsigned row, unsigned n); +__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, + __isl_take isl_mat *bot); +__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); + +isl_size 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); +void isl_mat_dump(__isl_keep isl_mat *mat); + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/external/mit/isl/dist/include/isl/maybe.h b/external/mit/isl/dist/include/isl/maybe.h new file mode 100644 index 000000000000..1fb35737fca5 --- /dev/null +++ b/external/mit/isl/dist/include/isl/maybe.h @@ -0,0 +1,7 @@ +#ifndef ISL_MAYBE_H +#define ISL_MAYBE_H + +#define ISL_xMAYBE(TYPE) isl_maybe_ ## TYPE +#define ISL_MAYBE(TYPE) ISL_xMAYBE(TYPE) + +#endif diff --git a/external/mit/isl/dist/include/isl/maybe_ast_expr.h b/external/mit/isl/dist/include/isl/maybe_ast_expr.h new file mode 100644 index 000000000000..260fa345be25 --- /dev/null +++ b/external/mit/isl/dist/include/isl/maybe_ast_expr.h @@ -0,0 +1,8 @@ +#ifndef ISL_MAYBE_AST_EXPR_H +#define ISL_MAYBE_AST_EXPR_H + +#define ISL_TYPE isl_ast_expr +#include +#undef ISL_TYPE + +#endif diff --git a/external/mit/isl/dist/include/isl/maybe_basic_set.h b/external/mit/isl/dist/include/isl/maybe_basic_set.h new file mode 100644 index 000000000000..1dc0881e9d5f --- /dev/null +++ b/external/mit/isl/dist/include/isl/maybe_basic_set.h @@ -0,0 +1,8 @@ +#ifndef ISL_MAYBE_BASIC_SET_H +#define ISL_MAYBE_BASIC_SET_H + +#define ISL_TYPE isl_basic_set +#include +#undef ISL_TYPE + +#endif diff --git a/external/mit/isl/dist/include/isl/maybe_id.h b/external/mit/isl/dist/include/isl/maybe_id.h new file mode 100644 index 000000000000..24ea308623bf --- /dev/null +++ b/external/mit/isl/dist/include/isl/maybe_id.h @@ -0,0 +1,8 @@ +#ifndef ISL_MAYBE_ID_H +#define ISL_MAYBE_ID_H + +#define ISL_TYPE isl_id +#include +#undef ISL_TYPE + +#endif diff --git a/external/mit/isl/dist/include/isl/maybe_pw_aff.h b/external/mit/isl/dist/include/isl/maybe_pw_aff.h new file mode 100644 index 000000000000..bc0dd9ca5166 --- /dev/null +++ b/external/mit/isl/dist/include/isl/maybe_pw_aff.h @@ -0,0 +1,8 @@ +#ifndef ISL_MAYBE_PW_AFF_H +#define ISL_MAYBE_PW_AFF_H + +#define ISL_TYPE isl_pw_aff +#include +#undef ISL_TYPE + +#endif diff --git a/external/mit/isl/dist/include/isl/maybe_templ.h b/external/mit/isl/dist/include/isl/maybe_templ.h new file mode 100644 index 000000000000..4dac253f6523 --- /dev/null +++ b/external/mit/isl/dist/include/isl/maybe_templ.h @@ -0,0 +1,12 @@ +#include +#include + +/* A structure that possibly contains a pointer to an object of type ISL_TYPE. + * The pointer in "value" is only valid if "valid" is isl_bool_true. + * Otherwise, "value" is set to NULL. + */ +struct ISL_MAYBE(ISL_TYPE) { + isl_bool valid; + ISL_TYPE *value; +}; +typedef struct ISL_MAYBE(ISL_TYPE) ISL_MAYBE(ISL_TYPE); diff --git a/external/mit/isl/dist/include/isl/multi.h b/external/mit/isl/dist/include/isl/multi.h new file mode 100644 index 000000000000..185a8c2ab4d1 --- /dev/null +++ b/external/mit/isl/dist/include/isl/multi.h @@ -0,0 +1,283 @@ +#ifndef ISL_MULTI_H +#define ISL_MULTI_H + +#include +#include +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +#define ISL_DECLARE_MULTI(BASE) \ +isl_ctx *isl_multi_##BASE##_get_ctx( \ + __isl_keep isl_multi_##BASE *multi); \ +__isl_export \ +__isl_give isl_space *isl_multi_##BASE##_get_space( \ + __isl_keep isl_multi_##BASE *multi); \ +__isl_give isl_space *isl_multi_##BASE##_get_domain_space( \ + __isl_keep isl_multi_##BASE *multi); \ +__isl_export \ +__isl_give isl_##BASE##_list *isl_multi_##BASE##_get_list( \ + __isl_keep isl_multi_##BASE *multi); \ +__isl_constructor \ +__isl_give isl_multi_##BASE *isl_multi_##BASE##_from_##BASE##_list( \ + __isl_take isl_space *space, __isl_take isl_##BASE##_list *list); \ +__isl_export \ +__isl_give isl_multi_##BASE *isl_space_multi_##BASE( \ + __isl_take isl_space *space, __isl_take isl_##BASE##_list *list); \ +__isl_give isl_multi_##BASE *isl_multi_##BASE##_copy( \ + __isl_keep isl_multi_##BASE *multi); \ +__isl_null isl_multi_##BASE *isl_multi_##BASE##_free( \ + __isl_take isl_multi_##BASE *multi); \ +__isl_export \ +isl_bool isl_multi_##BASE##_plain_is_equal( \ + __isl_keep isl_multi_##BASE *multi1, \ + __isl_keep isl_multi_##BASE *multi2); \ +__isl_give isl_multi_##BASE *isl_multi_##BASE##_reset_user( \ + __isl_take isl_multi_##BASE *multi); \ +__isl_export \ +isl_size isl_multi_##BASE##_size(__isl_keep isl_multi_##BASE *multi); \ +__isl_export \ +__isl_give isl_##BASE *isl_multi_##BASE##_get_at( \ + __isl_keep isl_multi_##BASE *multi, int pos); \ +__isl_give isl_##BASE *isl_multi_##BASE##_get_##BASE( \ + __isl_keep isl_multi_##BASE *multi, int pos); \ +__isl_export \ +__isl_give isl_multi_##BASE *isl_multi_##BASE##_set_at( \ + __isl_take isl_multi_##BASE *multi, int pos, \ + __isl_take isl_##BASE *el); \ +__isl_give isl_multi_##BASE *isl_multi_##BASE##_set_##BASE( \ + __isl_take isl_multi_##BASE *multi, int pos, \ + __isl_take isl_##BASE *el); \ +__isl_give isl_multi_##BASE *isl_multi_##BASE##_range_splice( \ + __isl_take isl_multi_##BASE *multi1, unsigned pos, \ + __isl_take isl_multi_##BASE *multi2); \ +__isl_give isl_multi_##BASE *isl_multi_##BASE##_flatten_range( \ + __isl_take isl_multi_##BASE *multi); \ +__isl_export \ +__isl_give isl_multi_##BASE *isl_multi_##BASE##_flat_range_product( \ + __isl_take isl_multi_##BASE *multi1, \ + __isl_take isl_multi_##BASE *multi2); \ +__isl_export \ +__isl_give isl_multi_##BASE *isl_multi_##BASE##_range_product( \ + __isl_take isl_multi_##BASE *multi1, \ + __isl_take isl_multi_##BASE *multi2); \ +__isl_give isl_multi_##BASE *isl_multi_##BASE##_factor_range( \ + __isl_take isl_multi_##BASE *multi); \ +isl_bool isl_multi_##BASE##_range_is_wrapping( \ + __isl_keep isl_multi_##BASE *multi); \ +__isl_give isl_multi_##BASE *isl_multi_##BASE##_range_factor_domain( \ + __isl_take isl_multi_##BASE *multi); \ +__isl_give isl_multi_##BASE *isl_multi_##BASE##_range_factor_range( \ + __isl_take isl_multi_##BASE *multi); \ +__isl_give isl_multi_##BASE *isl_multi_##BASE##_align_params( \ + __isl_take isl_multi_##BASE *multi, \ + __isl_take isl_space *model); \ +__isl_give isl_multi_##BASE *isl_multi_##BASE##_from_range( \ + __isl_take isl_multi_##BASE *multi); + +#define ISL_DECLARE_MULTI_IDENTITY(BASE) \ +__isl_overload \ +__isl_give isl_multi_##BASE *isl_multi_##BASE##_identity_multi_##BASE( \ + __isl_take isl_multi_##BASE *multi); \ +__isl_give isl_multi_##BASE *isl_multi_##BASE##_identity( \ + __isl_take isl_space *space); \ +__isl_overload \ +__isl_give isl_multi_##BASE * \ +isl_multi_##BASE##_identity_on_domain_space( \ + __isl_take isl_space *space); \ +__isl_export \ +__isl_give isl_multi_##BASE * \ +isl_space_identity_multi_##BASE##_on_domain( \ + __isl_take isl_space *space); + +#define ISL_DECLARE_MULTI_CMP(BASE) \ +int isl_multi_##BASE##_plain_cmp(__isl_keep isl_multi_##BASE *multi1, \ + __isl_keep isl_multi_##BASE *multi2); + +#define ISL_DECLARE_MULTI_ARITH(BASE) \ +__isl_overload \ +__isl_give isl_multi_##BASE *isl_multi_##BASE##_scale_val( \ + __isl_take isl_multi_##BASE *multi, __isl_take isl_val *v); \ +__isl_overload \ +__isl_give isl_multi_##BASE *isl_multi_##BASE##_scale_down_val( \ + __isl_take isl_multi_##BASE *multi, __isl_take isl_val *v); \ +__isl_overload \ +__isl_give isl_multi_##BASE *isl_multi_##BASE##_scale_multi_val( \ + __isl_take isl_multi_##BASE *multi, \ + __isl_take isl_multi_val *mv); \ +__isl_overload \ +__isl_give isl_multi_##BASE *isl_multi_##BASE##_scale_down_multi_val( \ + __isl_take isl_multi_##BASE *multi, \ + __isl_take isl_multi_val *mv); \ +__isl_give isl_multi_##BASE *isl_multi_##BASE##_mod_multi_val( \ + __isl_take isl_multi_##BASE *multi, \ + __isl_take isl_multi_val *mv); \ +__isl_export \ +__isl_give isl_multi_##BASE *isl_multi_##BASE##_add( \ + __isl_take isl_multi_##BASE *multi1, \ + __isl_take isl_multi_##BASE *multi2); \ +__isl_export \ +__isl_give isl_multi_##BASE *isl_multi_##BASE##_sub( \ + __isl_take isl_multi_##BASE *multi1, \ + __isl_take isl_multi_##BASE *multi2); \ +__isl_export \ +__isl_give isl_multi_##BASE *isl_multi_##BASE##_neg( \ + __isl_take isl_multi_##BASE *multi); + +#define ISL_DECLARE_MULTI_MIN_MAX(BASE) \ +__isl_export \ +__isl_give isl_multi_##BASE *isl_multi_##BASE##_min( \ + __isl_take isl_multi_##BASE *multi1, \ + __isl_take isl_multi_##BASE *multi2); \ +__isl_export \ +__isl_give isl_multi_##BASE *isl_multi_##BASE##_max( \ + __isl_take isl_multi_##BASE *multi1, \ + __isl_take isl_multi_##BASE *multi2); + +#define ISL_DECLARE_MULTI_ADD_CONSTANT(BASE) \ +__isl_overload \ +__isl_give isl_multi_##BASE *isl_multi_##BASE##_add_constant_val( \ + __isl_take isl_multi_##BASE *mpa, __isl_take isl_val *v); \ +__isl_overload \ +__isl_give isl_multi_##BASE *isl_multi_##BASE##_add_constant_multi_val( \ + __isl_take isl_multi_##BASE *mpa, __isl_take isl_multi_val *mv); + +#define ISL_DECLARE_MULTI_ZERO(BASE) \ +__isl_export \ +__isl_give isl_multi_##BASE *isl_multi_##BASE##_zero( \ + __isl_take isl_space *space); \ +__isl_export \ +__isl_give isl_multi_##BASE *isl_space_zero_multi_##BASE( \ + __isl_take isl_space *space); + +#define ISL_DECLARE_MULTI_NAN(BASE) \ +__isl_export \ +isl_bool isl_multi_##BASE##_involves_nan( \ + __isl_keep isl_multi_##BASE *multi); + +#define ISL_DECLARE_MULTI_DROP_DIMS(BASE) \ +isl_size isl_multi_##BASE##_dim(__isl_keep isl_multi_##BASE *multi, \ + enum isl_dim_type type); \ +__isl_give isl_multi_##BASE *isl_multi_##BASE##_drop_dims( \ + __isl_take isl_multi_##BASE *multi, enum isl_dim_type type, \ + unsigned first, unsigned n); +#define ISL_DECLARE_MULTI_DIMS(BASE) \ +ISL_DECLARE_MULTI_DROP_DIMS(BASE) \ +isl_bool isl_multi_##BASE##_involves_dims( \ + __isl_keep isl_multi_##BASE *multi, enum isl_dim_type type, \ + unsigned first, unsigned n); \ +__isl_give isl_multi_##BASE *isl_multi_##BASE##_insert_dims( \ + __isl_take isl_multi_##BASE *multi, enum isl_dim_type type, \ + 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); \ +__isl_give isl_multi_##BASE * \ +isl_multi_##BASE##_project_domain_on_params( \ + __isl_take isl_multi_##BASE *multi); + +#define ISL_DECLARE_MULTI_INSERT_DOMAIN(BASE) \ +__isl_export \ +__isl_give isl_multi_##BASE * \ +isl_multi_##BASE##_insert_domain(__isl_take isl_multi_##BASE *multi, \ + __isl_take isl_space *domain); + +#define ISL_DECLARE_MULTI_LOCALS(BASE) \ +__isl_export \ +isl_bool isl_multi_##BASE##_involves_locals( \ + __isl_keep isl_multi_##BASE *multi); + +#define ISL_DECLARE_MULTI_DIM_ID(BASE) \ +int isl_multi_##BASE##_find_dim_by_name( \ + __isl_keep isl_multi_##BASE *multi, \ + enum isl_dim_type type, const char *name); \ +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_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, \ + enum isl_dim_type type, unsigned pos, const char *s); \ +__isl_give isl_multi_##BASE *isl_multi_##BASE##_set_dim_id( \ + __isl_take isl_multi_##BASE *multi, \ + enum isl_dim_type type, unsigned pos, __isl_take isl_id *id); + +#define ISL_DECLARE_MULTI_TUPLE_ID(BASE) \ +const char *isl_multi_##BASE##_get_tuple_name( \ + __isl_keep isl_multi_##BASE *multi, enum isl_dim_type type); \ +__isl_export \ +isl_bool isl_multi_##BASE##_has_range_tuple_id( \ + __isl_keep isl_multi_##BASE *multi); \ +isl_bool isl_multi_##BASE##_has_tuple_id( \ + __isl_keep isl_multi_##BASE *multi, enum isl_dim_type type); \ +__isl_export \ +__isl_give isl_id *isl_multi_##BASE##_get_range_tuple_id( \ + __isl_keep isl_multi_##BASE *multi); \ +__isl_give isl_id *isl_multi_##BASE##_get_tuple_id( \ + __isl_keep isl_multi_##BASE *multi, enum isl_dim_type type); \ +__isl_give isl_multi_##BASE *isl_multi_##BASE##_set_tuple_name( \ + __isl_take isl_multi_##BASE *multi, \ + enum isl_dim_type type, const char *s); \ +__isl_overload \ +__isl_give isl_multi_##BASE *isl_multi_##BASE##_set_range_tuple_id( \ + __isl_take isl_multi_##BASE *multi, __isl_take isl_id *id); \ +__isl_give isl_multi_##BASE *isl_multi_##BASE##_set_tuple_id( \ + __isl_take isl_multi_##BASE *multi, \ + enum isl_dim_type type, __isl_take isl_id *id); \ +__isl_export \ +__isl_give isl_multi_##BASE *isl_multi_##BASE##_reset_range_tuple_id( \ + __isl_take isl_multi_##BASE *multi); \ +__isl_give isl_multi_##BASE *isl_multi_##BASE##_reset_tuple_id( \ + __isl_take isl_multi_##BASE *multi, enum isl_dim_type type); + +#define ISL_DECLARE_MULTI_WITH_DOMAIN(BASE) \ +__isl_export \ +__isl_give isl_multi_##BASE *isl_multi_##BASE##_product( \ + __isl_take isl_multi_##BASE *multi1, \ + __isl_take isl_multi_##BASE *multi2); \ +__isl_give isl_multi_##BASE *isl_multi_##BASE##_splice( \ + __isl_take isl_multi_##BASE *multi1, unsigned in_pos, \ + unsigned out_pos, __isl_take isl_multi_##BASE *multi2); + +#define ISL_DECLARE_MULTI_BIND_DOMAIN(BASE) \ +__isl_export \ +__isl_give isl_multi_##BASE *isl_multi_##BASE##_bind_domain( \ + __isl_take isl_multi_##BASE *multi, \ + __isl_take isl_multi_id *tuple); \ +__isl_export \ +__isl_give isl_multi_##BASE * \ +isl_multi_##BASE##_bind_domain_wrapped_domain( \ + __isl_take isl_multi_##BASE *multi, \ + __isl_take isl_multi_id *tuple); + +#define ISL_DECLARE_MULTI_UNBIND_PARAMS(BASE) \ +__isl_export \ +__isl_give isl_multi_##BASE * \ +isl_multi_##BASE##_unbind_params_insert_domain( \ + __isl_take isl_multi_##BASE *multi, \ + __isl_take isl_multi_id *domain); + +#define ISL_DECLARE_MULTI_PARAM(BASE) \ +__isl_overload \ +isl_bool isl_multi_##BASE##_involves_param_id( \ + __isl_keep isl_multi_##BASE *multi, __isl_keep isl_id *id); \ +__isl_overload \ +isl_bool isl_multi_##BASE##_involves_param_id_list( \ + __isl_keep isl_multi_##BASE *multi, \ + __isl_keep isl_id_list *list); + +#define ISL_DECLARE_MULTI_DOMAIN_REVERSE(BASE) \ +__isl_export \ +__isl_give isl_multi_##BASE *isl_multi_##BASE##_domain_reverse( \ + __isl_take isl_multi_##BASE *multi); + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/external/mit/isl/dist/include/isl/obj.h b/external/mit/isl/dist/include/isl/obj.h new file mode 100644 index 000000000000..07c6bf38c664 --- /dev/null +++ b/external/mit/isl/dist/include/isl/obj.h @@ -0,0 +1,57 @@ +#ifndef ISL_OBJ_H +#define ISL_OBJ_H + +#include +#include +#include +#include +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +struct isl_obj_vtable { + void *(*copy)(void *v1); + void *(*add)(void *v1, void *v2); + __isl_give isl_printer *(*print)(__isl_take isl_printer *p, void *v); + void (*free)(void *v); +}; +typedef struct isl_obj_vtable *isl_obj_type; +extern struct isl_obj_vtable isl_obj_none_vtable; +#define isl_obj_none (&isl_obj_none_vtable) +extern struct isl_obj_vtable isl_obj_int_vtable; +#define isl_obj_int (&isl_obj_int_vtable) +extern struct isl_obj_vtable isl_obj_val_vtable; +#define isl_obj_val (&isl_obj_val_vtable) +extern struct isl_obj_vtable isl_obj_set_vtable; +#define isl_obj_set (&isl_obj_set_vtable) +extern struct isl_obj_vtable isl_obj_union_set_vtable; +#define isl_obj_union_set (&isl_obj_union_set_vtable) +extern struct isl_obj_vtable isl_obj_map_vtable; +#define isl_obj_map (&isl_obj_map_vtable) +extern struct isl_obj_vtable isl_obj_union_map_vtable; +#define isl_obj_union_map (&isl_obj_union_map_vtable) +extern struct isl_obj_vtable isl_obj_pw_multi_aff_vtable; +#define isl_obj_pw_multi_aff (&isl_obj_pw_multi_aff_vtable) +extern struct isl_obj_vtable isl_obj_pw_qpolynomial_vtable; +#define isl_obj_pw_qpolynomial (&isl_obj_pw_qpolynomial_vtable) +extern struct isl_obj_vtable isl_obj_union_pw_qpolynomial_vtable; +#define isl_obj_union_pw_qpolynomial (&isl_obj_union_pw_qpolynomial_vtable) +extern struct isl_obj_vtable isl_obj_pw_qpolynomial_fold_vtable; +#define isl_obj_pw_qpolynomial_fold (&isl_obj_pw_qpolynomial_fold_vtable) +extern struct isl_obj_vtable isl_obj_union_pw_qpolynomial_fold_vtable; +#define isl_obj_union_pw_qpolynomial_fold (&isl_obj_union_pw_qpolynomial_fold_vtable) +extern struct isl_obj_vtable isl_obj_schedule_vtable; +#define isl_obj_schedule (&isl_obj_schedule_vtable) +struct isl_obj { + isl_obj_type type; + void *v; +}; + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/external/mit/isl/dist/include/isl/options.h b/external/mit/isl/dist/include/isl/options.h new file mode 100644 index 000000000000..1738155fb9e4 --- /dev/null +++ b/external/mit/isl/dist/include/isl/options.h @@ -0,0 +1,56 @@ +/* + * 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_OPTIONS_H +#define ISL_OPTIONS_H + +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +struct isl_options; + +ISL_ARG_DECL(isl_options, struct isl_options, isl_options_args) + +#define ISL_BOUND_BERNSTEIN 0 +#define ISL_BOUND_RANGE 1 +isl_stat isl_options_set_bound(isl_ctx *ctx, int val); +int isl_options_get_bound(isl_ctx *ctx); + +#define ISL_ON_ERROR_WARN 0 +#define ISL_ON_ERROR_CONTINUE 1 +#define ISL_ON_ERROR_ABORT 2 +isl_stat isl_options_set_on_error(isl_ctx *ctx, int val); +int isl_options_get_on_error(isl_ctx *ctx); + +isl_stat isl_options_set_gbr_only_first(isl_ctx *ctx, int val); +int isl_options_get_gbr_only_first(isl_ctx *ctx); + +#define ISL_SCHEDULE_ALGORITHM_ISL 0 +#define ISL_SCHEDULE_ALGORITHM_FEAUTRIER 1 +isl_stat isl_options_set_schedule_algorithm(isl_ctx *ctx, int val); +int isl_options_get_schedule_algorithm(isl_ctx *ctx); + +isl_stat isl_options_set_pip_symmetry(isl_ctx *ctx, int val); +int isl_options_get_pip_symmetry(isl_ctx *ctx); + +isl_stat isl_options_set_coalesce_bounded_wrapping(isl_ctx *ctx, int val); +int isl_options_get_coalesce_bounded_wrapping(isl_ctx *ctx); + +isl_stat isl_options_set_coalesce_preserve_locals(isl_ctx *ctx, int val); +int isl_options_get_coalesce_preserve_locals(isl_ctx *ctx); + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/external/mit/isl/dist/include/isl/point.h b/external/mit/isl/dist/include/isl/point.h new file mode 100644 index 000000000000..0f907ed718ef --- /dev/null +++ b/external/mit/isl/dist/include/isl/point.h @@ -0,0 +1,46 @@ +#ifndef ISL_POINT_H +#define ISL_POINT_H + +#include +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +struct __isl_subclass(isl_basic_set) isl_point; +typedef struct isl_point isl_point; + +isl_ctx *isl_point_get_ctx(__isl_keep isl_point *pnt); +__isl_give isl_space *isl_point_get_space(__isl_keep isl_point *pnt); + +__isl_give isl_point *isl_point_zero(__isl_take isl_space *space); +__isl_give isl_point *isl_point_copy(__isl_keep isl_point *pnt); +__isl_null isl_point *isl_point_free(__isl_take isl_point *pnt); + +__isl_give isl_val *isl_point_get_coordinate_val(__isl_keep isl_point *pnt, + enum isl_dim_type type, int pos); +__isl_give isl_point *isl_point_set_coordinate_val(__isl_take isl_point *pnt, + enum isl_dim_type type, int pos, __isl_take isl_val *v); +__isl_export +__isl_give isl_multi_val *isl_point_get_multi_val(__isl_keep isl_point *pnt); + +__isl_give isl_point *isl_point_add_ui(__isl_take isl_point *pnt, + enum isl_dim_type type, int pos, unsigned val); +__isl_give isl_point *isl_point_sub_ui(__isl_take isl_point *pnt, + enum isl_dim_type type, int pos, unsigned val); + +__isl_give isl_point *isl_point_void(__isl_take isl_space *space); +isl_bool isl_point_is_void(__isl_keep isl_point *pnt); + +__isl_give isl_printer *isl_printer_print_point( + __isl_take isl_printer *printer, __isl_keep isl_point *pnt); +__isl_give char *isl_point_to_str(__isl_keep isl_point *pnt); +void isl_point_dump(__isl_keep isl_point *pnt); + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/external/mit/isl/dist/include/isl/polynomial.h b/external/mit/isl/dist/include/isl/polynomial.h new file mode 100644 index 000000000000..d93a75b5292a --- /dev/null +++ b/external/mit/isl/dist/include/isl/polynomial.h @@ -0,0 +1,845 @@ +#ifndef ISL_POLYNOMIAL_H +#define ISL_POLYNOMIAL_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +isl_ctx *isl_qpolynomial_get_ctx(__isl_keep isl_qpolynomial *qp); +__isl_give isl_space *isl_qpolynomial_get_domain_space( + __isl_keep isl_qpolynomial *qp); +__isl_give isl_space *isl_qpolynomial_get_space(__isl_keep isl_qpolynomial *qp); +isl_size isl_qpolynomial_dim(__isl_keep isl_qpolynomial *qp, + enum isl_dim_type type); +isl_bool isl_qpolynomial_involves_dims(__isl_keep isl_qpolynomial *qp, + enum isl_dim_type type, unsigned first, unsigned n); + +__isl_give isl_val *isl_qpolynomial_get_constant_val( + __isl_keep isl_qpolynomial *qp); + +__isl_give isl_qpolynomial *isl_qpolynomial_set_dim_name( + __isl_take isl_qpolynomial *qp, + enum isl_dim_type type, unsigned pos, const char *s); + +__isl_give isl_qpolynomial *isl_qpolynomial_zero_on_domain( + __isl_take isl_space *domain); +__isl_give isl_qpolynomial *isl_qpolynomial_one_on_domain( + __isl_take isl_space *domain); +__isl_give isl_qpolynomial *isl_qpolynomial_infty_on_domain( + __isl_take isl_space *domain); +__isl_give isl_qpolynomial *isl_qpolynomial_neginfty_on_domain( + __isl_take isl_space *domain); +__isl_give isl_qpolynomial *isl_qpolynomial_nan_on_domain( + __isl_take isl_space *domain); +__isl_give isl_qpolynomial *isl_qpolynomial_val_on_domain( + __isl_take isl_space *space, __isl_take isl_val *val); +__isl_give isl_qpolynomial *isl_qpolynomial_var_on_domain( + __isl_take isl_space *domain, + enum isl_dim_type type, unsigned pos); +__isl_give isl_qpolynomial *isl_qpolynomial_copy(__isl_keep isl_qpolynomial *qp); +__isl_null isl_qpolynomial *isl_qpolynomial_free( + __isl_take isl_qpolynomial *qp); + +isl_bool isl_qpolynomial_plain_is_equal(__isl_keep isl_qpolynomial *qp1, + __isl_keep isl_qpolynomial *qp2); +isl_bool isl_qpolynomial_is_zero(__isl_keep isl_qpolynomial *qp); +isl_bool isl_qpolynomial_is_nan(__isl_keep isl_qpolynomial *qp); +isl_bool isl_qpolynomial_is_infty(__isl_keep isl_qpolynomial *qp); +isl_bool isl_qpolynomial_is_neginfty(__isl_keep isl_qpolynomial *qp); +int isl_qpolynomial_sgn(__isl_keep isl_qpolynomial *qp); + +__isl_give isl_qpolynomial *isl_qpolynomial_neg(__isl_take isl_qpolynomial *qp); +__isl_give isl_qpolynomial *isl_qpolynomial_add(__isl_take isl_qpolynomial *qp1, + __isl_take isl_qpolynomial *qp2); +__isl_give isl_qpolynomial *isl_qpolynomial_sub(__isl_take isl_qpolynomial *qp1, + __isl_take isl_qpolynomial *qp2); +__isl_give isl_qpolynomial *isl_qpolynomial_mul(__isl_take isl_qpolynomial *qp1, + __isl_take isl_qpolynomial *qp2); +__isl_give isl_qpolynomial *isl_qpolynomial_pow(__isl_take isl_qpolynomial *qp, + unsigned power); +__isl_give isl_qpolynomial *isl_qpolynomial_scale_val( + __isl_take isl_qpolynomial *qp, __isl_take isl_val *v); +__isl_give isl_qpolynomial *isl_qpolynomial_scale_down_val( + __isl_take isl_qpolynomial *qp, __isl_take isl_val *v); + +__isl_give isl_qpolynomial *isl_qpolynomial_domain_reverse( + __isl_take isl_qpolynomial *qp); +__isl_give isl_qpolynomial *isl_qpolynomial_insert_dims( + __isl_take isl_qpolynomial *qp, enum isl_dim_type type, + unsigned first, unsigned n); +__isl_give isl_qpolynomial *isl_qpolynomial_add_dims( + __isl_take isl_qpolynomial *qp, enum isl_dim_type type, unsigned n); +__isl_give isl_qpolynomial *isl_qpolynomial_move_dims( + __isl_take isl_qpolynomial *qp, + enum isl_dim_type dst_type, unsigned dst_pos, + enum isl_dim_type src_type, unsigned src_pos, unsigned n); +__isl_give isl_qpolynomial *isl_qpolynomial_project_domain_on_params( + __isl_take isl_qpolynomial *qp); +__isl_give isl_qpolynomial *isl_qpolynomial_drop_dims( + __isl_take isl_qpolynomial *qp, + enum isl_dim_type type, unsigned first, unsigned n); + +__isl_give isl_qpolynomial *isl_qpolynomial_substitute( + __isl_take isl_qpolynomial *qp, + enum isl_dim_type type, unsigned first, unsigned n, + __isl_keep isl_qpolynomial **subs); + +isl_stat isl_qpolynomial_as_polynomial_on_domain(__isl_keep isl_qpolynomial *qp, + __isl_keep isl_basic_set *bset, + isl_stat (*fn)(__isl_take isl_basic_set *bset, + __isl_take isl_qpolynomial *poly, void *user), void *user); + +__isl_give isl_qpolynomial *isl_qpolynomial_homogenize( + __isl_take isl_qpolynomial *poly); + +__isl_give isl_qpolynomial *isl_qpolynomial_align_params( + __isl_take isl_qpolynomial *qp, __isl_take isl_space *model); + +isl_ctx *isl_term_get_ctx(__isl_keep isl_term *term); + +__isl_give isl_term *isl_term_copy(__isl_keep isl_term *term); +__isl_null isl_term *isl_term_free(__isl_take isl_term *term); + +isl_size isl_term_dim(__isl_keep isl_term *term, enum isl_dim_type type); +__isl_give isl_val *isl_term_get_coefficient_val(__isl_keep isl_term *term); +isl_size isl_term_get_exp(__isl_keep isl_term *term, + enum isl_dim_type type, unsigned pos); +__isl_give isl_aff *isl_term_get_div(__isl_keep isl_term *term, unsigned pos); + +isl_stat isl_qpolynomial_foreach_term(__isl_keep isl_qpolynomial *qp, + isl_stat (*fn)(__isl_take isl_term *term, void *user), void *user); + +__isl_give isl_val *isl_qpolynomial_eval(__isl_take isl_qpolynomial *qp, + __isl_take isl_point *pnt); + +__isl_give isl_qpolynomial *isl_qpolynomial_gist_params( + __isl_take isl_qpolynomial *qp, __isl_take isl_set *context); +__isl_give isl_qpolynomial *isl_qpolynomial_gist( + __isl_take isl_qpolynomial *qp, __isl_take isl_set *context); + +__isl_give isl_qpolynomial *isl_qpolynomial_from_constraint( + __isl_take isl_constraint *c, enum isl_dim_type type, unsigned pos); +__isl_give isl_qpolynomial *isl_qpolynomial_from_term(__isl_take isl_term *term); +__isl_give isl_qpolynomial *isl_qpolynomial_from_aff(__isl_take isl_aff *aff); +__isl_give isl_basic_map *isl_basic_map_from_qpolynomial( + __isl_take isl_qpolynomial *qp); + +__isl_give isl_printer *isl_printer_print_qpolynomial( + __isl_take isl_printer *p, __isl_keep isl_qpolynomial *qp); +void isl_qpolynomial_print(__isl_keep isl_qpolynomial *qp, FILE *out, + unsigned output_format); +void isl_qpolynomial_dump(__isl_keep isl_qpolynomial *qp); + +isl_ctx *isl_pw_qpolynomial_get_ctx(__isl_keep isl_pw_qpolynomial *pwqp); + +isl_bool isl_pw_qpolynomial_involves_nan(__isl_keep isl_pw_qpolynomial *pwqp); +isl_bool isl_pw_qpolynomial_plain_is_equal(__isl_keep isl_pw_qpolynomial *pwqp1, + __isl_keep isl_pw_qpolynomial *pwqp2); + +__isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_zero( + __isl_take isl_space *space); +__isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_alloc(__isl_take isl_set *set, + __isl_take isl_qpolynomial *qp); +__isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_from_qpolynomial( + __isl_take isl_qpolynomial *qp); +__isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_copy( + __isl_keep isl_pw_qpolynomial *pwqp); +__isl_null isl_pw_qpolynomial *isl_pw_qpolynomial_free( + __isl_take isl_pw_qpolynomial *pwqp); + +isl_bool isl_pw_qpolynomial_is_zero(__isl_keep isl_pw_qpolynomial *pwqp); + +__isl_give isl_space *isl_pw_qpolynomial_get_domain_space( + __isl_keep isl_pw_qpolynomial *pwqp); +__isl_give isl_space *isl_pw_qpolynomial_get_space( + __isl_keep isl_pw_qpolynomial *pwqp); +__isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_reset_domain_space( + __isl_take isl_pw_qpolynomial *pwqp, __isl_take isl_space *space); +isl_size isl_pw_qpolynomial_dim(__isl_keep isl_pw_qpolynomial *pwqp, + enum isl_dim_type type); +isl_bool isl_pw_qpolynomial_involves_param_id( + __isl_keep isl_pw_qpolynomial *pwqp, __isl_keep isl_id *id); +isl_bool isl_pw_qpolynomial_involves_dims(__isl_keep isl_pw_qpolynomial *pwqp, + enum isl_dim_type type, unsigned first, unsigned n); +isl_bool isl_pw_qpolynomial_has_equal_space( + __isl_keep isl_pw_qpolynomial *pwqp1, + __isl_keep isl_pw_qpolynomial *pwqp2); + +__isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_set_dim_name( + __isl_take isl_pw_qpolynomial *pwqp, + enum isl_dim_type type, unsigned pos, const char *s); + +int isl_pw_qpolynomial_find_dim_by_name(__isl_keep isl_pw_qpolynomial *pwqp, + enum isl_dim_type type, const char *name); + +__isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_reset_user( + __isl_take isl_pw_qpolynomial *pwqp); + +__isl_export +__isl_give isl_set *isl_pw_qpolynomial_domain(__isl_take isl_pw_qpolynomial *pwqp); +__isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_intersect_domain( + __isl_take isl_pw_qpolynomial *pwpq, __isl_take isl_set *set); +__isl_give isl_pw_qpolynomial * +isl_pw_qpolynomial_intersect_domain_wrapped_domain( + __isl_take isl_pw_qpolynomial *pwpq, __isl_take isl_set *set); +__isl_give isl_pw_qpolynomial * +isl_pw_qpolynomial_intersect_domain_wrapped_range( + __isl_take isl_pw_qpolynomial *pwpq, __isl_take isl_set *set); +__isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_intersect_params( + __isl_take isl_pw_qpolynomial *pwpq, __isl_take isl_set *set); +__isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_subtract_domain( + __isl_take isl_pw_qpolynomial *pwpq, __isl_take isl_set *set); + +__isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_project_domain_on_params( + __isl_take isl_pw_qpolynomial *pwqp); +__isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_from_range( + __isl_take isl_pw_qpolynomial *pwqp); +__isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_drop_dims( + __isl_take isl_pw_qpolynomial *pwqp, + enum isl_dim_type type, unsigned first, unsigned n); +__isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_split_dims( + __isl_take isl_pw_qpolynomial *pwqp, + enum isl_dim_type type, unsigned first, unsigned n); + +__isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_drop_unused_params( + __isl_take isl_pw_qpolynomial *pwqp); + +__isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_add( + __isl_take isl_pw_qpolynomial *pwqp1, + __isl_take isl_pw_qpolynomial *pwqp2); +__isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_sub( + __isl_take isl_pw_qpolynomial *pwqp1, + __isl_take isl_pw_qpolynomial *pwqp2); +__isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_add_disjoint( + __isl_take isl_pw_qpolynomial *pwqp1, + __isl_take isl_pw_qpolynomial *pwqp2); +__isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_neg( + __isl_take isl_pw_qpolynomial *pwqp); +__isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_mul( + __isl_take isl_pw_qpolynomial *pwqp1, + __isl_take isl_pw_qpolynomial *pwqp2); +__isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_scale_val( + __isl_take isl_pw_qpolynomial *pwqp, __isl_take isl_val *v); +__isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_scale_down_val( + __isl_take isl_pw_qpolynomial *pwqp, __isl_take isl_val *v); +__isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_pow( + __isl_take isl_pw_qpolynomial *pwqp, unsigned exponent); + +__isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_domain_reverse( + __isl_take isl_pw_qpolynomial *pwqp); +__isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_insert_dims( + __isl_take isl_pw_qpolynomial *pwqp, enum isl_dim_type type, + unsigned first, unsigned n); +__isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_add_dims( + __isl_take isl_pw_qpolynomial *pwqp, + enum isl_dim_type type, unsigned n); +__isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_move_dims( + __isl_take isl_pw_qpolynomial *pwqp, + enum isl_dim_type dst_type, unsigned dst_pos, + enum isl_dim_type src_type, unsigned src_pos, unsigned n); + +__isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_fix_val( + __isl_take isl_pw_qpolynomial *pwqp, + enum isl_dim_type type, unsigned n, __isl_take isl_val *v); + +__isl_export +__isl_give isl_val *isl_pw_qpolynomial_eval( + __isl_take isl_pw_qpolynomial *pwqp, __isl_take isl_point *pnt); + +__isl_give isl_val *isl_pw_qpolynomial_max(__isl_take isl_pw_qpolynomial *pwqp); +__isl_give isl_val *isl_pw_qpolynomial_min(__isl_take isl_pw_qpolynomial *pwqp); + +isl_size isl_pw_qpolynomial_n_piece(__isl_keep isl_pw_qpolynomial *pwqp); +isl_stat isl_pw_qpolynomial_foreach_piece(__isl_keep isl_pw_qpolynomial *pwqp, + isl_stat (*fn)(__isl_take isl_set *set, __isl_take isl_qpolynomial *qp, + void *user), void *user); +isl_bool isl_pw_qpolynomial_every_piece(__isl_keep isl_pw_qpolynomial *pwqp, + isl_bool (*test)(__isl_keep isl_set *set, + __isl_keep isl_qpolynomial *qp, void *user), void *user); +isl_stat isl_pw_qpolynomial_foreach_lifted_piece( + __isl_keep isl_pw_qpolynomial *pwqp, + isl_stat (*fn)(__isl_take isl_set *set, __isl_take isl_qpolynomial *qp, + void *user), void *user); +isl_bool isl_pw_qpolynomial_isa_qpolynomial( + __isl_keep isl_pw_qpolynomial *pwqp); +__isl_give isl_qpolynomial *isl_pw_qpolynomial_as_qpolynomial( + __isl_take isl_pw_qpolynomial *pwqp); + +__isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_from_pw_aff( + __isl_take isl_pw_aff *pwaff); + +__isl_constructor +__isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_read_from_str(isl_ctx *ctx, + const char *str); +__isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_read_from_file(isl_ctx *ctx, + FILE *input); +__isl_give char *isl_pw_qpolynomial_to_str(__isl_keep isl_pw_qpolynomial *pwqp); +__isl_give isl_printer *isl_printer_print_pw_qpolynomial( + __isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial *pwqp); +void isl_pw_qpolynomial_print(__isl_keep isl_pw_qpolynomial *pwqp, FILE *out, + unsigned output_format); +void isl_pw_qpolynomial_dump(__isl_keep isl_pw_qpolynomial *pwqp); + +__isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_coalesce( + __isl_take isl_pw_qpolynomial *pwqp); +__isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_gist( + __isl_take isl_pw_qpolynomial *pwqp, __isl_take isl_set *context); +__isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_gist_params( + __isl_take isl_pw_qpolynomial *pwqp, __isl_take isl_set *context); + +__isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_split_periods( + __isl_take isl_pw_qpolynomial *pwqp, int max_periods); + +__isl_give isl_pw_qpolynomial *isl_basic_set_multiplicative_call( + __isl_take isl_basic_set *bset, + __isl_give isl_pw_qpolynomial *(*fn)(__isl_take isl_basic_set *bset)); + +isl_ctx *isl_qpolynomial_fold_get_ctx(__isl_keep isl_qpolynomial_fold *fold); +enum isl_fold isl_qpolynomial_fold_get_type(__isl_keep isl_qpolynomial_fold *fold); + +__isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_empty(enum isl_fold type, + __isl_take isl_space *space); +__isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_alloc( + enum isl_fold type, __isl_take isl_qpolynomial *qp); +__isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_copy( + __isl_keep isl_qpolynomial_fold *fold); +__isl_null isl_qpolynomial_fold *isl_qpolynomial_fold_free( + __isl_take isl_qpolynomial_fold *fold); + +isl_bool isl_qpolynomial_fold_is_empty(__isl_keep isl_qpolynomial_fold *fold); +isl_bool isl_qpolynomial_fold_is_nan(__isl_keep isl_qpolynomial_fold *fold); +isl_bool isl_qpolynomial_fold_plain_is_equal( + __isl_keep isl_qpolynomial_fold *fold1, + __isl_keep isl_qpolynomial_fold *fold2); + +__isl_give isl_space *isl_qpolynomial_fold_get_domain_space( + __isl_keep isl_qpolynomial_fold *fold); +__isl_give isl_space *isl_qpolynomial_fold_get_space( + __isl_keep isl_qpolynomial_fold *fold); + +__isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_fold( + __isl_take isl_qpolynomial_fold *fold1, + __isl_take isl_qpolynomial_fold *fold2); + +__isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_scale_val( + __isl_take isl_qpolynomial_fold *fold, __isl_take isl_val *v); +__isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_scale_down_val( + __isl_take isl_qpolynomial_fold *fold, __isl_take isl_val *v); + +__isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_move_dims( + __isl_take isl_qpolynomial_fold *fold, + enum isl_dim_type dst_type, unsigned dst_pos, + enum isl_dim_type src_type, unsigned src_pos, unsigned n); + +__isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_substitute( + __isl_take isl_qpolynomial_fold *fold, + 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); + +__isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_gist_params( + __isl_take isl_qpolynomial_fold *fold, __isl_take isl_set *context); +__isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_gist( + __isl_take isl_qpolynomial_fold *fold, __isl_take isl_set *context); + +isl_stat isl_qpolynomial_fold_foreach_qpolynomial( + __isl_keep isl_qpolynomial_fold *fold, + isl_stat (*fn)(__isl_take isl_qpolynomial *qp, void *user), void *user); + +__isl_give isl_printer *isl_printer_print_qpolynomial_fold( + __isl_take isl_printer *p, __isl_keep isl_qpolynomial_fold *fold); +void isl_qpolynomial_fold_print(__isl_keep isl_qpolynomial_fold *fold, FILE *out, + unsigned output_format); +void isl_qpolynomial_fold_dump(__isl_keep isl_qpolynomial_fold *fold); + +isl_ctx *isl_pw_qpolynomial_fold_get_ctx(__isl_keep isl_pw_qpolynomial_fold *pwf); +enum isl_fold isl_pw_qpolynomial_fold_get_type( + __isl_keep isl_pw_qpolynomial_fold *pwf); + +isl_bool isl_pw_qpolynomial_fold_involves_nan( + __isl_keep isl_pw_qpolynomial_fold *pwf); +isl_bool isl_pw_qpolynomial_fold_plain_is_equal( + __isl_keep isl_pw_qpolynomial_fold *pwf1, + __isl_keep isl_pw_qpolynomial_fold *pwf2); + +__isl_give isl_pw_qpolynomial_fold *isl_pw_qpolynomial_fold_from_pw_qpolynomial( + enum isl_fold type, __isl_take isl_pw_qpolynomial *pwqp); + +__isl_give isl_pw_qpolynomial_fold *isl_pw_qpolynomial_fold_alloc( + enum isl_fold type, + __isl_take isl_set *set, __isl_take isl_qpolynomial_fold *fold); +__isl_give isl_pw_qpolynomial_fold * +isl_pw_qpolynomial_fold_from_qpolynomial_fold( + __isl_take isl_qpolynomial_fold *fold); +__isl_give isl_pw_qpolynomial_fold *isl_pw_qpolynomial_fold_copy( + __isl_keep isl_pw_qpolynomial_fold *pwf); +__isl_null isl_pw_qpolynomial_fold *isl_pw_qpolynomial_fold_free( + __isl_take isl_pw_qpolynomial_fold *pwf); + +isl_bool isl_pw_qpolynomial_fold_is_zero( + __isl_keep isl_pw_qpolynomial_fold *pwf); + +__isl_give isl_space *isl_pw_qpolynomial_fold_get_domain_space( + __isl_keep isl_pw_qpolynomial_fold *pwf); +__isl_give isl_space *isl_pw_qpolynomial_fold_get_space( + __isl_keep isl_pw_qpolynomial_fold *pwf); +__isl_give isl_pw_qpolynomial_fold *isl_pw_qpolynomial_fold_reset_space( + __isl_take isl_pw_qpolynomial_fold *pwf, __isl_take isl_space *space); +isl_size isl_pw_qpolynomial_fold_dim(__isl_keep isl_pw_qpolynomial_fold *pwf, + enum isl_dim_type type); +isl_bool isl_pw_qpolynomial_fold_involves_param_id( + __isl_keep isl_pw_qpolynomial_fold *pwf, __isl_keep isl_id *id); +isl_bool isl_pw_qpolynomial_fold_has_equal_space( + __isl_keep isl_pw_qpolynomial_fold *pwf1, + __isl_keep isl_pw_qpolynomial_fold *pwf2); + +size_t isl_pw_qpolynomial_fold_size(__isl_keep isl_pw_qpolynomial_fold *pwf); + +__isl_give isl_pw_qpolynomial_fold *isl_pw_qpolynomial_fold_zero( + __isl_take isl_space *space, enum isl_fold type); + +__isl_give isl_pw_qpolynomial_fold *isl_pw_qpolynomial_fold_set_dim_name( + __isl_take isl_pw_qpolynomial_fold *pwf, + enum isl_dim_type type, unsigned pos, const char *s); + +int isl_pw_qpolynomial_fold_find_dim_by_name( + __isl_keep isl_pw_qpolynomial_fold *pwf, + enum isl_dim_type type, const char *name); + +__isl_give isl_pw_qpolynomial_fold *isl_pw_qpolynomial_fold_reset_user( + __isl_take isl_pw_qpolynomial_fold *pwf); + +__isl_give isl_set *isl_pw_qpolynomial_fold_domain( + __isl_take isl_pw_qpolynomial_fold *pwf); +__isl_give isl_pw_qpolynomial_fold *isl_pw_qpolynomial_fold_intersect_domain( + __isl_take isl_pw_qpolynomial_fold *pwf, __isl_take isl_set *set); +__isl_give isl_pw_qpolynomial_fold * +isl_pw_qpolynomial_fold_intersect_domain_wrapped_domain( + __isl_take isl_pw_qpolynomial_fold *pwf, __isl_take isl_set *set); +__isl_give isl_pw_qpolynomial_fold * +isl_pw_qpolynomial_fold_intersect_domain_wrapped_range( + __isl_take isl_pw_qpolynomial_fold *pwf, __isl_take isl_set *set); +__isl_give isl_pw_qpolynomial_fold *isl_pw_qpolynomial_fold_intersect_params( + __isl_take isl_pw_qpolynomial_fold *pwf, __isl_take isl_set *set); +__isl_give isl_pw_qpolynomial_fold *isl_pw_qpolynomial_fold_subtract_domain( + __isl_take isl_pw_qpolynomial_fold *pwf, __isl_take isl_set *set); + +__isl_give isl_pw_qpolynomial_fold *isl_pw_qpolynomial_fold_add( + __isl_take isl_pw_qpolynomial_fold *pwf1, + __isl_take isl_pw_qpolynomial_fold *pwf2); +__isl_give isl_pw_qpolynomial_fold *isl_pw_qpolynomial_fold_fold( + __isl_take isl_pw_qpolynomial_fold *pwf1, + __isl_take isl_pw_qpolynomial_fold *pwf2); +__isl_give isl_pw_qpolynomial_fold *isl_pw_qpolynomial_fold_add_disjoint( + __isl_take isl_pw_qpolynomial_fold *pwf1, + __isl_take isl_pw_qpolynomial_fold *pwf2); +__isl_give isl_pw_qpolynomial_fold *isl_pw_qpolynomial_fold_scale_val( + __isl_take isl_pw_qpolynomial_fold *pwf, __isl_take isl_val *v); +__isl_give isl_pw_qpolynomial_fold *isl_pw_qpolynomial_fold_scale_down_val( + __isl_take isl_pw_qpolynomial_fold *pwf, __isl_take isl_val *v); + +__isl_give isl_pw_qpolynomial_fold *isl_pw_qpolynomial_fold_project_domain_on_params( + __isl_take isl_pw_qpolynomial_fold *pwf); +__isl_give isl_pw_qpolynomial_fold *isl_pw_qpolynomial_fold_from_range( + __isl_take isl_pw_qpolynomial_fold *pwf); +__isl_give isl_pw_qpolynomial_fold *isl_pw_qpolynomial_fold_drop_dims( + __isl_take isl_pw_qpolynomial_fold *pwf, + enum isl_dim_type type, unsigned first, unsigned n); +__isl_give isl_pw_qpolynomial_fold *isl_pw_qpolynomial_fold_move_dims( + __isl_take isl_pw_qpolynomial_fold *pwf, + enum isl_dim_type dst_type, unsigned dst_pos, + enum isl_dim_type src_type, unsigned src_pos, unsigned n); + +__isl_give isl_pw_qpolynomial_fold *isl_pw_qpolynomial_fold_drop_unused_params( + __isl_take isl_pw_qpolynomial_fold *pwf); + +__isl_give isl_val *isl_pw_qpolynomial_fold_eval( + __isl_take isl_pw_qpolynomial_fold *pwf, __isl_take isl_point *pnt); + +isl_size isl_pw_qpolynomial_fold_n_piece( + __isl_keep isl_pw_qpolynomial_fold *pwf); +isl_stat isl_pw_qpolynomial_fold_foreach_piece( + __isl_keep isl_pw_qpolynomial_fold *pwf, + isl_stat (*fn)(__isl_take isl_set *set, + __isl_take isl_qpolynomial_fold *fold, void *user), void *user); +isl_bool isl_pw_qpolynomial_fold_every_piece( + __isl_keep isl_pw_qpolynomial_fold *pwf, + isl_bool (*test)(__isl_keep isl_set *set, + __isl_keep isl_qpolynomial_fold *fold, void *user), void *user); +isl_stat isl_pw_qpolynomial_fold_foreach_lifted_piece( + __isl_keep isl_pw_qpolynomial_fold *pwf, + isl_stat (*fn)(__isl_take isl_set *set, + __isl_take isl_qpolynomial_fold *fold, void *user), void *user); +isl_bool isl_pw_qpolynomial_fold_isa_qpolynomial_fold( + __isl_keep isl_pw_qpolynomial_fold *pwf); +__isl_give isl_qpolynomial_fold *isl_pw_qpolynomial_fold_as_qpolynomial_fold( + __isl_take isl_pw_qpolynomial_fold *pwf); + +__isl_give isl_pw_qpolynomial_fold *isl_pw_qpolynomial_fold_read_from_str( + isl_ctx *ctx, const char *str); +__isl_give isl_printer *isl_printer_print_pw_qpolynomial_fold( + __isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial_fold *pwf); +void isl_pw_qpolynomial_fold_print(__isl_keep isl_pw_qpolynomial_fold *pwf, + FILE *out, unsigned output_format); +void isl_pw_qpolynomial_fold_dump(__isl_keep isl_pw_qpolynomial_fold *pwf); + +__isl_give isl_pw_qpolynomial_fold *isl_pw_qpolynomial_fold_coalesce( + __isl_take isl_pw_qpolynomial_fold *pwf); +__isl_give isl_pw_qpolynomial_fold *isl_pw_qpolynomial_fold_gist( + __isl_take isl_pw_qpolynomial_fold *pwf, __isl_take isl_set *context); +__isl_give isl_pw_qpolynomial_fold *isl_pw_qpolynomial_fold_gist_params( + __isl_take isl_pw_qpolynomial_fold *pwf, __isl_take isl_set *context); + +__isl_give isl_val *isl_pw_qpolynomial_fold_max( + __isl_take isl_pw_qpolynomial_fold *pwf); +__isl_give isl_val *isl_pw_qpolynomial_fold_min( + __isl_take isl_pw_qpolynomial_fold *pwf); + +__isl_give isl_pw_qpolynomial_fold *isl_pw_qpolynomial_bound( + __isl_take isl_pw_qpolynomial *pwqp, enum isl_fold type, + isl_bool *tight); +__isl_give isl_pw_qpolynomial_fold *isl_pw_qpolynomial_fold_bound( + __isl_take isl_pw_qpolynomial_fold *pwf, isl_bool *tight); +__isl_give isl_pw_qpolynomial_fold *isl_set_apply_pw_qpolynomial_fold( + __isl_take isl_set *set, __isl_take isl_pw_qpolynomial_fold *pwf, + isl_bool *tight); +__isl_give isl_pw_qpolynomial_fold *isl_map_apply_pw_qpolynomial_fold( + __isl_take isl_map *map, __isl_take isl_pw_qpolynomial_fold *pwf, + isl_bool *tight); + +__isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_to_polynomial( + __isl_take isl_pw_qpolynomial *pwqp, int sign); + +isl_ctx *isl_union_pw_qpolynomial_get_ctx( + __isl_keep isl_union_pw_qpolynomial *upwqp); + +isl_size isl_union_pw_qpolynomial_dim( + __isl_keep isl_union_pw_qpolynomial *upwqp, enum isl_dim_type type); + +isl_bool isl_union_pw_qpolynomial_involves_nan( + __isl_keep isl_union_pw_qpolynomial *upwqp); +isl_bool isl_union_pw_qpolynomial_plain_is_equal( + __isl_keep isl_union_pw_qpolynomial *upwqp1, + __isl_keep isl_union_pw_qpolynomial *upwqp2); + +__isl_give isl_union_pw_qpolynomial *isl_pw_qpolynomial_to_union_pw_qpolynomial( + __isl_take isl_pw_qpolynomial *pwqp); +__isl_give isl_union_pw_qpolynomial *isl_union_pw_qpolynomial_from_pw_qpolynomial(__isl_take isl_pw_qpolynomial *pwqp); +__isl_give isl_union_pw_qpolynomial *isl_union_pw_qpolynomial_zero_ctx( + isl_ctx *ctx); +__isl_give isl_union_pw_qpolynomial *isl_union_pw_qpolynomial_zero_space( + __isl_take isl_space *space); +__isl_give isl_union_pw_qpolynomial *isl_union_pw_qpolynomial_zero( + __isl_take isl_space *space); +__isl_give isl_union_pw_qpolynomial *isl_union_pw_qpolynomial_add_pw_qpolynomial( + __isl_take isl_union_pw_qpolynomial *upwqp, + __isl_take isl_pw_qpolynomial *pwqp); +__isl_give isl_union_pw_qpolynomial *isl_union_pw_qpolynomial_copy( + __isl_keep isl_union_pw_qpolynomial *upwqp); +__isl_null isl_union_pw_qpolynomial *isl_union_pw_qpolynomial_free( + __isl_take isl_union_pw_qpolynomial *upwqp); + +__isl_constructor +__isl_give isl_union_pw_qpolynomial *isl_union_pw_qpolynomial_read_from_str( + isl_ctx *ctx, const char *str); +__isl_give char *isl_union_pw_qpolynomial_to_str( + __isl_keep isl_union_pw_qpolynomial *upwqp); + +__isl_give isl_union_pw_qpolynomial *isl_union_pw_qpolynomial_neg( + __isl_take isl_union_pw_qpolynomial *upwqp); + +__isl_give isl_union_pw_qpolynomial *isl_union_pw_qpolynomial_add( + __isl_take isl_union_pw_qpolynomial *upwqp1, + __isl_take isl_union_pw_qpolynomial *upwqp2); +__isl_give isl_union_pw_qpolynomial *isl_union_pw_qpolynomial_sub( + __isl_take isl_union_pw_qpolynomial *upwqp1, + __isl_take isl_union_pw_qpolynomial *upwqp2); +__isl_give isl_union_pw_qpolynomial *isl_union_pw_qpolynomial_mul( + __isl_take isl_union_pw_qpolynomial *upwqp1, + __isl_take isl_union_pw_qpolynomial *upwqp2); +__isl_give isl_union_pw_qpolynomial *isl_union_pw_qpolynomial_scale_val( + __isl_take isl_union_pw_qpolynomial *upwqp, __isl_take isl_val *v); +__isl_give isl_union_pw_qpolynomial *isl_union_pw_qpolynomial_scale_down_val( + __isl_take isl_union_pw_qpolynomial *upwqp, __isl_take isl_val *v); + +__isl_export +__isl_give isl_union_set *isl_union_pw_qpolynomial_domain( + __isl_take isl_union_pw_qpolynomial *upwqp); +__isl_give isl_union_pw_qpolynomial * +isl_union_pw_qpolynomial_intersect_domain_space( + __isl_take isl_union_pw_qpolynomial *upwpq, + __isl_take isl_space *space); +__isl_give isl_union_pw_qpolynomial * +isl_union_pw_qpolynomial_intersect_domain_union_set( + __isl_take isl_union_pw_qpolynomial *upwpq, + __isl_take isl_union_set *uset); +__isl_give isl_union_pw_qpolynomial *isl_union_pw_qpolynomial_intersect_domain( + __isl_take isl_union_pw_qpolynomial *upwpq, + __isl_take isl_union_set *uset); +__isl_give isl_union_pw_qpolynomial * +isl_union_pw_qpolynomial_intersect_domain_wrapped_domain( + __isl_take isl_union_pw_qpolynomial *upwpq, + __isl_take isl_union_set *uset); +__isl_give isl_union_pw_qpolynomial * +isl_union_pw_qpolynomial_intersect_domain_wrapped_range( + __isl_take isl_union_pw_qpolynomial *upwpq, + __isl_take isl_union_set *uset); +__isl_give isl_union_pw_qpolynomial *isl_union_pw_qpolynomial_intersect_params( + __isl_take isl_union_pw_qpolynomial *upwpq, + __isl_take isl_set *set); +__isl_give isl_union_pw_qpolynomial * +isl_union_pw_qpolynomial_subtract_domain_union_set( + __isl_take isl_union_pw_qpolynomial *upwpq, + __isl_take isl_union_set *uset); +__isl_give isl_union_pw_qpolynomial * +isl_union_pw_qpolynomial_subtract_domain_space( + __isl_take isl_union_pw_qpolynomial *upwpq, + __isl_take isl_space *space); +__isl_give isl_union_pw_qpolynomial *isl_union_pw_qpolynomial_subtract_domain( + __isl_take isl_union_pw_qpolynomial *upwpq, + __isl_take isl_union_set *uset); + +__isl_give isl_space *isl_union_pw_qpolynomial_get_space( + __isl_keep isl_union_pw_qpolynomial *upwqp); +__isl_give isl_pw_qpolynomial_list * +isl_union_pw_qpolynomial_get_pw_qpolynomial_list( + __isl_keep isl_union_pw_qpolynomial *upwqp); + +__isl_give isl_union_pw_qpolynomial *isl_union_pw_qpolynomial_set_dim_name( + __isl_take isl_union_pw_qpolynomial *upwqp, + enum isl_dim_type type, unsigned pos, const char *s); + +int isl_union_pw_qpolynomial_find_dim_by_name( + __isl_keep isl_union_pw_qpolynomial *upwqp, + enum isl_dim_type type, const char *name); + +__isl_give isl_union_pw_qpolynomial *isl_union_pw_qpolynomial_domain_reverse( + __isl_take isl_union_pw_qpolynomial *upwqp); +__isl_give isl_union_pw_qpolynomial *isl_union_pw_qpolynomial_drop_dims( + __isl_take isl_union_pw_qpolynomial *upwqp, + enum isl_dim_type type, unsigned first, unsigned n); +__isl_give isl_union_pw_qpolynomial *isl_union_pw_qpolynomial_reset_user( + __isl_take isl_union_pw_qpolynomial *upwqp); + +__isl_export +__isl_give isl_val *isl_union_pw_qpolynomial_eval( + __isl_take isl_union_pw_qpolynomial *upwqp, __isl_take isl_point *pnt); + +__isl_give isl_union_pw_qpolynomial *isl_union_pw_qpolynomial_coalesce( + __isl_take isl_union_pw_qpolynomial *upwqp); +__isl_give isl_union_pw_qpolynomial *isl_union_pw_qpolynomial_gist( + __isl_take isl_union_pw_qpolynomial *upwqp, + __isl_take isl_union_set *context); +__isl_give isl_union_pw_qpolynomial *isl_union_pw_qpolynomial_gist_params( + __isl_take isl_union_pw_qpolynomial *upwqp, + __isl_take isl_set *context); + +__isl_give isl_union_pw_qpolynomial *isl_union_pw_qpolynomial_align_params( + __isl_take isl_union_pw_qpolynomial *upwqp, + __isl_take isl_space *model); +__isl_give isl_union_pw_qpolynomial * +isl_union_pw_qpolynomial_drop_unused_params( + __isl_take isl_union_pw_qpolynomial *upwqp); + +isl_size isl_union_pw_qpolynomial_n_pw_qpolynomial( + __isl_keep isl_union_pw_qpolynomial *upwqp); +isl_stat isl_union_pw_qpolynomial_foreach_pw_qpolynomial( + __isl_keep isl_union_pw_qpolynomial *upwqp, + isl_stat (*fn)(__isl_take isl_pw_qpolynomial *pwqp, void *user), + void *user); +isl_bool isl_union_pw_qpolynomial_every_pw_qpolynomial( + __isl_keep isl_union_pw_qpolynomial *upwqp, + isl_bool (*test)(__isl_keep isl_pw_qpolynomial *pwqp, void *user), + void *user); +__isl_give isl_pw_qpolynomial *isl_union_pw_qpolynomial_extract_pw_qpolynomial( + __isl_keep isl_union_pw_qpolynomial *upwqp, + __isl_take isl_space *space); + +__isl_give isl_printer *isl_printer_print_union_pw_qpolynomial( + __isl_take isl_printer *p, __isl_keep isl_union_pw_qpolynomial *upwqp); + +isl_ctx *isl_union_pw_qpolynomial_fold_get_ctx( + __isl_keep isl_union_pw_qpolynomial_fold *upwf); + +isl_size isl_union_pw_qpolynomial_fold_dim( + __isl_keep isl_union_pw_qpolynomial_fold *upwf, enum isl_dim_type type); + +isl_bool isl_union_pw_qpolynomial_fold_involves_nan( + __isl_keep isl_union_pw_qpolynomial_fold *upwf); +isl_bool isl_union_pw_qpolynomial_fold_plain_is_equal( + __isl_keep isl_union_pw_qpolynomial_fold *upwf1, + __isl_keep isl_union_pw_qpolynomial_fold *upwf2); + +__isl_give isl_union_pw_qpolynomial_fold * +isl_pw_qpolynomial_fold_to_union_pw_qpolynomial_fold( + __isl_take isl_pw_qpolynomial_fold *pwf); +__isl_give isl_union_pw_qpolynomial_fold *isl_union_pw_qpolynomial_fold_from_pw_qpolynomial_fold(__isl_take isl_pw_qpolynomial_fold *pwf); +__isl_give isl_union_pw_qpolynomial_fold * +isl_union_pw_qpolynomial_fold_zero_ctx(isl_ctx *ctx, enum isl_fold type); +__isl_give isl_union_pw_qpolynomial_fold * +isl_union_pw_qpolynomial_fold_zero_space(__isl_take isl_space *space, + enum isl_fold type); +__isl_give isl_union_pw_qpolynomial_fold *isl_union_pw_qpolynomial_fold_zero( + __isl_take isl_space *space, enum isl_fold type); +__isl_give isl_union_pw_qpolynomial_fold *isl_union_pw_qpolynomial_fold_fold_pw_qpolynomial_fold( + __isl_take isl_union_pw_qpolynomial_fold *upwqp, + __isl_take isl_pw_qpolynomial_fold *pwqp); +__isl_null isl_union_pw_qpolynomial_fold *isl_union_pw_qpolynomial_fold_free( + __isl_take isl_union_pw_qpolynomial_fold *upwf); +__isl_give isl_union_pw_qpolynomial_fold *isl_union_pw_qpolynomial_fold_copy( + __isl_keep isl_union_pw_qpolynomial_fold *upwf); + +__isl_give isl_union_pw_qpolynomial_fold *isl_union_pw_qpolynomial_fold_fold( + __isl_take isl_union_pw_qpolynomial_fold *upwf1, + __isl_take isl_union_pw_qpolynomial_fold *upwf2); +__isl_give isl_union_pw_qpolynomial_fold *isl_union_pw_qpolynomial_fold_add_union_pw_qpolynomial( + __isl_take isl_union_pw_qpolynomial_fold *upwf, + __isl_take isl_union_pw_qpolynomial *upwqp); +__isl_give isl_union_pw_qpolynomial_fold * +isl_union_pw_qpolynomial_fold_scale_val( + __isl_take isl_union_pw_qpolynomial_fold *upwf, __isl_take isl_val *v); +__isl_give isl_union_pw_qpolynomial_fold * +isl_union_pw_qpolynomial_fold_scale_down_val( + __isl_take isl_union_pw_qpolynomial_fold *upwf, __isl_take isl_val *v); + +__isl_give isl_union_set *isl_union_pw_qpolynomial_fold_domain( + __isl_take isl_union_pw_qpolynomial_fold *upwf); +__isl_give isl_union_pw_qpolynomial_fold * +isl_union_pw_qpolynomial_fold_intersect_domain_space( + __isl_take isl_union_pw_qpolynomial_fold *upwf, + __isl_take isl_space *space); +__isl_give isl_union_pw_qpolynomial_fold * +isl_union_pw_qpolynomial_fold_intersect_domain_union_set( + __isl_take isl_union_pw_qpolynomial_fold *upwf, + __isl_take isl_union_set *uset); +__isl_give isl_union_pw_qpolynomial_fold *isl_union_pw_qpolynomial_fold_intersect_domain( + __isl_take isl_union_pw_qpolynomial_fold *upwf, + __isl_take isl_union_set *uset); +__isl_give isl_union_pw_qpolynomial_fold * +isl_union_pw_qpolynomial_fold_intersect_domain_wrapped_domain( + __isl_take isl_union_pw_qpolynomial_fold *upwf, + __isl_take isl_union_set *uset); +__isl_give isl_union_pw_qpolynomial_fold * +isl_union_pw_qpolynomial_fold_intersect_domain_wrapped_range( + __isl_take isl_union_pw_qpolynomial_fold *upwf, + __isl_take isl_union_set *uset); +__isl_give isl_union_pw_qpolynomial_fold * +isl_union_pw_qpolynomial_fold_intersect_params( + __isl_take isl_union_pw_qpolynomial_fold *upwf, + __isl_take isl_set *set); +__isl_give isl_union_pw_qpolynomial_fold * +isl_union_pw_qpolynomial_fold_subtract_domain_union_set( + __isl_take isl_union_pw_qpolynomial_fold *upwf, + __isl_take isl_union_set *uset); +__isl_give isl_union_pw_qpolynomial_fold * +isl_union_pw_qpolynomial_fold_subtract_domain_space( + __isl_take isl_union_pw_qpolynomial_fold *upwf, + __isl_take isl_space *space); +__isl_give isl_union_pw_qpolynomial_fold * +isl_union_pw_qpolynomial_fold_subtract_domain( + __isl_take isl_union_pw_qpolynomial_fold *upwf, + __isl_take isl_union_set *uset); + +enum isl_fold isl_union_pw_qpolynomial_fold_get_type( + __isl_keep isl_union_pw_qpolynomial_fold *upwf); +__isl_give isl_space *isl_union_pw_qpolynomial_fold_get_space( + __isl_keep isl_union_pw_qpolynomial_fold *upwf); +__isl_give isl_pw_qpolynomial_fold_list * +isl_union_pw_qpolynomial_fold_get_pw_qpolynomial_fold_list( + __isl_keep isl_union_pw_qpolynomial_fold *upwf); + +__isl_give isl_union_pw_qpolynomial_fold * +isl_union_pw_qpolynomial_fold_set_dim_name( + __isl_take isl_union_pw_qpolynomial_fold *upwf, + enum isl_dim_type type, unsigned pos, const char *s); + +int isl_union_pw_qpolynomial_fold_find_dim_by_name( + __isl_keep isl_union_pw_qpolynomial_fold *upwf, + enum isl_dim_type type, const char *name); + +__isl_give isl_union_pw_qpolynomial_fold * + isl_union_pw_qpolynomial_fold_drop_dims( + __isl_take isl_union_pw_qpolynomial_fold *upwf, + enum isl_dim_type type, unsigned first, unsigned n); +__isl_give isl_union_pw_qpolynomial_fold * +isl_union_pw_qpolynomial_fold_reset_user( + __isl_take isl_union_pw_qpolynomial_fold *upwf); + +__isl_give isl_val *isl_union_pw_qpolynomial_fold_eval( + __isl_take isl_union_pw_qpolynomial_fold *upwf, + __isl_take isl_point *pnt); + +__isl_give isl_union_pw_qpolynomial_fold *isl_union_pw_qpolynomial_fold_coalesce( + __isl_take isl_union_pw_qpolynomial_fold *upwf); +__isl_give isl_union_pw_qpolynomial_fold *isl_union_pw_qpolynomial_fold_gist( + __isl_take isl_union_pw_qpolynomial_fold *upwf, + __isl_take isl_union_set *context); +__isl_give isl_union_pw_qpolynomial_fold * +isl_union_pw_qpolynomial_fold_gist_params( + __isl_take isl_union_pw_qpolynomial_fold *upwf, + __isl_take isl_set *context); + +__isl_give isl_union_pw_qpolynomial_fold *isl_union_pw_qpolynomial_fold_align_params( + __isl_take isl_union_pw_qpolynomial_fold *upwf, + __isl_take isl_space *model); +__isl_give isl_union_pw_qpolynomial_fold * +isl_union_pw_qpolynomial_fold_drop_unused_params( + __isl_take isl_union_pw_qpolynomial_fold *upwf); + +isl_size isl_union_pw_qpolynomial_fold_n_pw_qpolynomial_fold( + __isl_keep isl_union_pw_qpolynomial_fold *upwf); +isl_stat isl_union_pw_qpolynomial_fold_foreach_pw_qpolynomial_fold( + __isl_keep isl_union_pw_qpolynomial_fold *upwf, + isl_stat (*fn)(__isl_take isl_pw_qpolynomial_fold *pwf, + void *user), void *user); +isl_bool isl_union_pw_qpolynomial_fold_every_pw_qpolynomial_fold( + __isl_keep isl_union_pw_qpolynomial_fold *upwf, + isl_bool (*test)(__isl_keep isl_pw_qpolynomial_fold *pwf, + void *user), void *user); +__isl_give isl_pw_qpolynomial_fold *isl_union_pw_qpolynomial_fold_extract_pw_qpolynomial_fold( + __isl_keep isl_union_pw_qpolynomial_fold *upwf, + __isl_take isl_space *space); + +__isl_give isl_printer *isl_printer_print_union_pw_qpolynomial_fold( + __isl_take isl_printer *p, + __isl_keep isl_union_pw_qpolynomial_fold *upwf); + +__isl_give isl_union_pw_qpolynomial_fold *isl_union_pw_qpolynomial_bound( + __isl_take isl_union_pw_qpolynomial *upwqp, + enum isl_fold type, isl_bool *tight); +__isl_give isl_union_pw_qpolynomial_fold *isl_union_set_apply_union_pw_qpolynomial_fold( + __isl_take isl_union_set *uset, + __isl_take isl_union_pw_qpolynomial_fold *upwf, isl_bool *tight); +__isl_give isl_union_pw_qpolynomial_fold *isl_union_map_apply_union_pw_qpolynomial_fold( + __isl_take isl_union_map *umap, + __isl_take isl_union_pw_qpolynomial_fold *upwf, isl_bool *tight); + +__isl_give isl_union_pw_qpolynomial *isl_union_pw_qpolynomial_to_polynomial( + __isl_take isl_union_pw_qpolynomial *upwqp, int sign); + +ISL_DECLARE_LIST_FN(qpolynomial) +ISL_DECLARE_LIST_FN(pw_qpolynomial) +ISL_DECLARE_LIST_FN(pw_qpolynomial_fold) + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/external/mit/isl/dist/include/isl/polynomial_type.h b/external/mit/isl/dist/include/isl/polynomial_type.h new file mode 100644 index 000000000000..02bbc03b54ff --- /dev/null +++ b/external/mit/isl/dist/include/isl/polynomial_type.h @@ -0,0 +1,41 @@ +#ifndef ISL_POLYNOMIAL_TYPE_H +#define ISL_POLYNOMIAL_TYPE_H + +#include +#include + +struct isl_qpolynomial; +typedef struct isl_qpolynomial isl_qpolynomial; + +ISL_DECLARE_LIST_TYPE(qpolynomial) + +struct isl_term; +typedef struct isl_term isl_term; + +struct __isl_export isl_pw_qpolynomial; +typedef struct isl_pw_qpolynomial isl_pw_qpolynomial; + +ISL_DECLARE_LIST_TYPE(pw_qpolynomial) + +enum isl_fold { + isl_fold_error = -1, + isl_fold_min, + isl_fold_max, + isl_fold_list +}; + +struct isl_qpolynomial_fold; +typedef struct isl_qpolynomial_fold isl_qpolynomial_fold; + +struct isl_pw_qpolynomial_fold; +typedef struct isl_pw_qpolynomial_fold isl_pw_qpolynomial_fold; + +ISL_DECLARE_LIST_TYPE(pw_qpolynomial_fold) + +struct __isl_export isl_union_pw_qpolynomial; +typedef struct isl_union_pw_qpolynomial isl_union_pw_qpolynomial; + +struct isl_union_pw_qpolynomial_fold; +typedef struct isl_union_pw_qpolynomial_fold isl_union_pw_qpolynomial_fold; + +#endif diff --git a/external/mit/isl/dist/include/isl/printer.h b/external/mit/isl/dist/include/isl/printer.h new file mode 100644 index 000000000000..c31595462853 --- /dev/null +++ b/external/mit/isl/dist/include/isl/printer.h @@ -0,0 +1,84 @@ +#ifndef ISL_PRINTER_H +#define ISL_PRINTER_H + +#include +#include +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +__isl_give isl_printer *isl_printer_to_file(isl_ctx *ctx, FILE *file); +__isl_give isl_printer *isl_printer_to_str(isl_ctx *ctx); +__isl_null isl_printer *isl_printer_free(__isl_take isl_printer *printer); + +isl_ctx *isl_printer_get_ctx(__isl_keep isl_printer *printer); +FILE *isl_printer_get_file(__isl_keep isl_printer *printer); + +__isl_give char *isl_printer_get_str(__isl_keep isl_printer *printer); + +__isl_give isl_printer *isl_printer_set_indent(__isl_take isl_printer *p, + int indent); +__isl_give isl_printer *isl_printer_indent(__isl_take isl_printer *p, + int indent); + +#define ISL_FORMAT_ISL 0 +#define ISL_FORMAT_POLYLIB 1 +#define ISL_FORMAT_POLYLIB_CONSTRAINTS 2 +#define ISL_FORMAT_OMEGA 3 +#define ISL_FORMAT_C 4 +#define ISL_FORMAT_LATEX 5 +#define ISL_FORMAT_EXT_POLYLIB 6 +__isl_give isl_printer *isl_printer_set_output_format(__isl_take isl_printer *p, + int output_format); +int isl_printer_get_output_format(__isl_keep isl_printer *p); + +#define ISL_YAML_STYLE_BLOCK 0 +#define ISL_YAML_STYLE_FLOW 1 +__isl_give isl_printer *isl_printer_set_yaml_style(__isl_take isl_printer *p, + int yaml_style); +int isl_printer_get_yaml_style(__isl_keep isl_printer *p); + +__isl_give isl_printer *isl_printer_set_indent_prefix(__isl_take isl_printer *p, + const char *prefix); +__isl_give isl_printer *isl_printer_set_prefix(__isl_take isl_printer *p, + const char *prefix); +__isl_give isl_printer *isl_printer_set_suffix(__isl_take isl_printer *p, + const char *suffix); +__isl_give isl_printer *isl_printer_set_isl_int_width(__isl_take isl_printer *p, + int width); + +isl_bool isl_printer_has_note(__isl_keep isl_printer *p, + __isl_keep isl_id *id); +__isl_give isl_id *isl_printer_get_note(__isl_keep isl_printer *p, + __isl_take isl_id *id); +__isl_give isl_printer *isl_printer_set_note(__isl_take isl_printer *p, + __isl_take isl_id *id, __isl_take isl_id *note); + +__isl_give isl_printer *isl_printer_start_line(__isl_take isl_printer *p); +__isl_give isl_printer *isl_printer_end_line(__isl_take isl_printer *p); +__isl_give isl_printer *isl_printer_print_double(__isl_take isl_printer *p, + double d); +__isl_give isl_printer *isl_printer_print_int(__isl_take isl_printer *p, int i); +__isl_give isl_printer *isl_printer_print_str(__isl_take isl_printer *p, + const char *s); + +__isl_give isl_printer *isl_printer_yaml_start_mapping( + __isl_take isl_printer *p); +__isl_give isl_printer *isl_printer_yaml_end_mapping( + __isl_take isl_printer *p); +__isl_give isl_printer *isl_printer_yaml_start_sequence( + __isl_take isl_printer *p); +__isl_give isl_printer *isl_printer_yaml_end_sequence( + __isl_take isl_printer *p); +__isl_give isl_printer *isl_printer_yaml_next(__isl_take isl_printer *p); + +__isl_give isl_printer *isl_printer_flush(__isl_take isl_printer *p); + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/external/mit/isl/dist/include/isl/printer_type.h b/external/mit/isl/dist/include/isl/printer_type.h new file mode 100644 index 000000000000..985f8ca7fa44 --- /dev/null +++ b/external/mit/isl/dist/include/isl/printer_type.h @@ -0,0 +1,15 @@ +#ifndef ISL_PRINTER_TYPE_H +#define ISL_PRINTER_TYPE_H + +#if defined(__cplusplus) +extern "C" { +#endif + +struct isl_printer; +typedef struct isl_printer isl_printer; + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/external/mit/isl/dist/include/isl/schedule.h b/external/mit/isl/dist/include/isl/schedule.h new file mode 100644 index 000000000000..880a1c2826ae --- /dev/null +++ b/external/mit/isl/dist/include/isl/schedule.h @@ -0,0 +1,201 @@ +#ifndef ISL_SCHEDULE_H +#define ISL_SCHEDULE_H + +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +struct __isl_export isl_schedule_constraints; +typedef struct isl_schedule_constraints isl_schedule_constraints; + +isl_stat isl_options_set_schedule_max_coefficient(isl_ctx *ctx, int val); +int isl_options_get_schedule_max_coefficient(isl_ctx *ctx); + +isl_stat isl_options_set_schedule_max_constant_term(isl_ctx *ctx, int val); +int isl_options_get_schedule_max_constant_term(isl_ctx *ctx); + +isl_stat isl_options_set_schedule_maximize_band_depth(isl_ctx *ctx, int val); +int isl_options_get_schedule_maximize_band_depth(isl_ctx *ctx); + +isl_stat isl_options_set_schedule_maximize_coincidence(isl_ctx *ctx, int val); +int isl_options_get_schedule_maximize_coincidence(isl_ctx *ctx); + +isl_stat isl_options_set_schedule_outer_coincidence(isl_ctx *ctx, int val); +int isl_options_get_schedule_outer_coincidence(isl_ctx *ctx); + +isl_stat isl_options_set_schedule_split_scaled(isl_ctx *ctx, int val); +int isl_options_get_schedule_split_scaled(isl_ctx *ctx); + +isl_stat isl_options_set_schedule_treat_coalescing(isl_ctx *ctx, int val); +int isl_options_get_schedule_treat_coalescing(isl_ctx *ctx); + +isl_stat isl_options_set_schedule_separate_components(isl_ctx *ctx, int val); +int isl_options_get_schedule_separate_components(isl_ctx *ctx); + +isl_stat isl_options_set_schedule_serialize_sccs(isl_ctx *ctx, int val); +int isl_options_get_schedule_serialize_sccs(isl_ctx *ctx); + +isl_stat isl_options_set_schedule_whole_component(isl_ctx *ctx, int val); +int isl_options_get_schedule_whole_component(isl_ctx *ctx); + +isl_stat isl_options_set_schedule_carry_self_first(isl_ctx *ctx, int val); +int isl_options_get_schedule_carry_self_first(isl_ctx *ctx); + +__isl_give isl_schedule_constraints *isl_schedule_constraints_copy( + __isl_keep isl_schedule_constraints *sc); +__isl_export +__isl_give isl_schedule_constraints *isl_schedule_constraints_on_domain( + __isl_take isl_union_set *domain); +__isl_export +__isl_give isl_schedule_constraints *isl_schedule_constraints_set_context( + __isl_take isl_schedule_constraints *sc, __isl_take isl_set *context); +__isl_export +__isl_give isl_schedule_constraints *isl_schedule_constraints_set_validity( + __isl_take isl_schedule_constraints *sc, + __isl_take isl_union_map *validity); +__isl_export +__isl_give isl_schedule_constraints *isl_schedule_constraints_set_coincidence( + __isl_take isl_schedule_constraints *sc, + __isl_take isl_union_map *coincidence); +__isl_export +__isl_give isl_schedule_constraints *isl_schedule_constraints_set_proximity( + __isl_take isl_schedule_constraints *sc, + __isl_take isl_union_map *proximity); +__isl_export +__isl_give isl_schedule_constraints * +isl_schedule_constraints_set_conditional_validity( + __isl_take isl_schedule_constraints *sc, + __isl_take isl_union_map *condition, + __isl_take isl_union_map *validity); +__isl_null isl_schedule_constraints *isl_schedule_constraints_free( + __isl_take isl_schedule_constraints *sc); + +isl_ctx *isl_schedule_constraints_get_ctx( + __isl_keep isl_schedule_constraints *sc); +__isl_export +__isl_give isl_union_set *isl_schedule_constraints_get_domain( + __isl_keep isl_schedule_constraints *sc); +__isl_export +__isl_give isl_set *isl_schedule_constraints_get_context( + __isl_keep isl_schedule_constraints *sc); +__isl_export +__isl_give isl_union_map *isl_schedule_constraints_get_validity( + __isl_keep isl_schedule_constraints *sc); +__isl_export +__isl_give isl_union_map *isl_schedule_constraints_get_coincidence( + __isl_keep isl_schedule_constraints *sc); +__isl_export +__isl_give isl_union_map *isl_schedule_constraints_get_proximity( + __isl_keep isl_schedule_constraints *sc); +__isl_export +__isl_give isl_union_map *isl_schedule_constraints_get_conditional_validity( + __isl_keep isl_schedule_constraints *sc); +__isl_export +__isl_give isl_union_map * +isl_schedule_constraints_get_conditional_validity_condition( + __isl_keep isl_schedule_constraints *sc); + +__isl_give isl_schedule_constraints *isl_schedule_constraints_apply( + __isl_take isl_schedule_constraints *sc, + __isl_take isl_union_map *umap); + +__isl_constructor +__isl_give isl_schedule_constraints *isl_schedule_constraints_read_from_str( + isl_ctx *ctx, const char *str); +__isl_give isl_schedule_constraints *isl_schedule_constraints_read_from_file( + isl_ctx *ctx, FILE *input); +__isl_give isl_printer *isl_printer_print_schedule_constraints( + __isl_take isl_printer *p, __isl_keep isl_schedule_constraints *sc); +void isl_schedule_constraints_dump(__isl_keep isl_schedule_constraints *sc); +__isl_give char *isl_schedule_constraints_to_str( + __isl_keep isl_schedule_constraints *sc); + +__isl_export +__isl_give isl_schedule *isl_schedule_constraints_compute_schedule( + __isl_take isl_schedule_constraints *sc); + +__isl_give isl_schedule *isl_union_set_compute_schedule( + __isl_take isl_union_set *domain, + __isl_take isl_union_map *validity, + __isl_take isl_union_map *proximity); + +__isl_give isl_schedule *isl_schedule_empty(__isl_take isl_space *space); +__isl_export +__isl_give isl_schedule *isl_schedule_from_domain( + __isl_take isl_union_set *domain); +__isl_give isl_schedule *isl_schedule_copy(__isl_keep isl_schedule *sched); +__isl_null isl_schedule *isl_schedule_free(__isl_take isl_schedule *sched); +__isl_export +__isl_give isl_union_map *isl_schedule_get_map(__isl_keep isl_schedule *sched); + +isl_ctx *isl_schedule_get_ctx(__isl_keep isl_schedule *sched); +isl_bool isl_schedule_plain_is_equal(__isl_keep isl_schedule *schedule1, + __isl_keep isl_schedule *schedule2); + +__isl_export +__isl_give isl_schedule_node *isl_schedule_get_root( + __isl_keep isl_schedule *schedule); +__isl_export +__isl_give isl_union_set *isl_schedule_get_domain( + __isl_keep isl_schedule *schedule); + +isl_stat isl_schedule_foreach_schedule_node_top_down( + __isl_keep isl_schedule *sched, + isl_bool (*fn)(__isl_keep isl_schedule_node *node, void *user), + void *user); +__isl_give isl_schedule *isl_schedule_map_schedule_node_bottom_up( + __isl_take isl_schedule *schedule, + __isl_give isl_schedule_node *(*fn)( + __isl_take isl_schedule_node *node, void *user), void *user); + +__isl_give isl_schedule *isl_schedule_insert_context( + __isl_take isl_schedule *schedule, __isl_take isl_set *context); +__isl_give isl_schedule *isl_schedule_insert_partial_schedule( + __isl_take isl_schedule *schedule, + __isl_take isl_multi_union_pw_aff *partial); +__isl_give isl_schedule *isl_schedule_insert_guard( + __isl_take isl_schedule *schedule, __isl_take isl_set *guard); +__isl_give isl_schedule *isl_schedule_sequence( + __isl_take isl_schedule *schedule1, __isl_take isl_schedule *schedule2); +__isl_give isl_schedule *isl_schedule_set( + __isl_take isl_schedule *schedule1, __isl_take isl_schedule *schedule2); +__isl_give isl_schedule *isl_schedule_intersect_domain( + __isl_take isl_schedule *schedule, __isl_take isl_union_set *domain); +__isl_give isl_schedule *isl_schedule_gist_domain_params( + __isl_take isl_schedule *schedule, __isl_take isl_set *context); + +__isl_give isl_schedule *isl_schedule_reset_user( + __isl_take isl_schedule *schedule); +__isl_give isl_schedule *isl_schedule_align_params( + __isl_take isl_schedule *schedule, __isl_take isl_space *space); +__isl_overload +__isl_give isl_schedule *isl_schedule_pullback_union_pw_multi_aff( + __isl_take isl_schedule *schedule, + __isl_take isl_union_pw_multi_aff *upma); +__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_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, + const char *str); +__isl_give isl_printer *isl_printer_print_schedule(__isl_take isl_printer *p, + __isl_keep isl_schedule *schedule); +void isl_schedule_dump(__isl_keep isl_schedule *schedule); +__isl_give char *isl_schedule_to_str(__isl_keep isl_schedule *schedule); + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/external/mit/isl/dist/include/isl/schedule_node.h b/external/mit/isl/dist/include/isl/schedule_node.h new file mode 100644 index 000000000000..648bc0d75902 --- /dev/null +++ b/external/mit/isl/dist/include/isl/schedule_node.h @@ -0,0 +1,307 @@ +#ifndef ISL_SCHEDULE_NODE_H +#define ISL_SCHEDULE_NODE_H + +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +__isl_export +__isl_give isl_schedule_node *isl_schedule_node_from_domain( + __isl_take isl_union_set *domain); +__isl_export +__isl_give isl_schedule_node *isl_schedule_node_from_extension( + __isl_take isl_union_map *extension); +__isl_give isl_schedule_node *isl_schedule_node_copy( + __isl_keep isl_schedule_node *node); +__isl_null isl_schedule_node *isl_schedule_node_free( + __isl_take isl_schedule_node *node); + +__isl_export +isl_bool isl_schedule_node_is_equal(__isl_keep isl_schedule_node *node1, + __isl_keep isl_schedule_node *node2); + +isl_ctx *isl_schedule_node_get_ctx(__isl_keep isl_schedule_node *node); +__isl_subclass(isl_schedule_node) +enum isl_schedule_node_type isl_schedule_node_get_type( + __isl_keep isl_schedule_node *node); +enum isl_schedule_node_type isl_schedule_node_get_parent_type( + __isl_keep isl_schedule_node *node); +__isl_export +__isl_give isl_schedule *isl_schedule_node_get_schedule( + __isl_keep isl_schedule_node *node); + +__isl_export +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_export +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_export +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), + void *user); +__isl_export +__isl_give isl_schedule_node *isl_schedule_node_map_descendant_bottom_up( + __isl_take isl_schedule_node *node, + __isl_give isl_schedule_node *(*fn)(__isl_take isl_schedule_node *node, + void *user), void *user); + +__isl_export +isl_size isl_schedule_node_get_tree_depth(__isl_keep isl_schedule_node *node); +__isl_export +isl_bool isl_schedule_node_has_parent(__isl_keep isl_schedule_node *node); +__isl_export +isl_bool isl_schedule_node_has_children(__isl_keep isl_schedule_node *node); +__isl_export +isl_bool isl_schedule_node_has_previous_sibling( + __isl_keep isl_schedule_node *node); +__isl_export +isl_bool isl_schedule_node_has_next_sibling(__isl_keep isl_schedule_node *node); +__isl_export +isl_size isl_schedule_node_n_children(__isl_keep isl_schedule_node *node); +__isl_export +isl_size isl_schedule_node_get_child_position( + __isl_keep isl_schedule_node *node); +__isl_export +isl_size isl_schedule_node_get_ancestor_child_position( + __isl_keep isl_schedule_node *node, + __isl_keep isl_schedule_node *ancestor); +__isl_give isl_schedule_node *isl_schedule_node_get_child( + __isl_keep isl_schedule_node *node, int pos); +__isl_export +__isl_give isl_schedule_node *isl_schedule_node_get_shared_ancestor( + __isl_keep isl_schedule_node *node1, + __isl_keep isl_schedule_node *node2); + +__isl_export +__isl_give isl_schedule_node *isl_schedule_node_root( + __isl_take isl_schedule_node *node); +__isl_export +__isl_give isl_schedule_node *isl_schedule_node_parent( + __isl_take isl_schedule_node *node); +__isl_give isl_schedule_node *isl_schedule_node_grandparent( + __isl_take isl_schedule_node *node); +__isl_export +__isl_give isl_schedule_node *isl_schedule_node_ancestor( + __isl_take isl_schedule_node *node, int generation); +__isl_export +__isl_give isl_schedule_node *isl_schedule_node_child( + __isl_take isl_schedule_node *node, int pos); +__isl_give isl_schedule_node *isl_schedule_node_grandchild( + __isl_take isl_schedule_node *node, int pos1, int pos2); +__isl_export +__isl_give isl_schedule_node *isl_schedule_node_first_child( + __isl_take isl_schedule_node *node); +__isl_export +__isl_give isl_schedule_node *isl_schedule_node_previous_sibling( + __isl_take isl_schedule_node *node); +__isl_export +__isl_give isl_schedule_node *isl_schedule_node_next_sibling( + __isl_take isl_schedule_node *node); + +__isl_export +isl_bool isl_schedule_node_is_subtree_anchored( + __isl_keep isl_schedule_node *node); + +__isl_give isl_schedule_node *isl_schedule_node_group( + __isl_take isl_schedule_node *node, __isl_take isl_id *group_id); + +__isl_give isl_schedule_node *isl_schedule_node_sequence_splice_child( + __isl_take isl_schedule_node *node, int pos); +__isl_give isl_schedule_node *isl_schedule_node_sequence_splice_children( + __isl_take isl_schedule_node *node); + +__isl_give isl_space *isl_schedule_node_band_get_space( + __isl_keep isl_schedule_node *node); +__isl_export +__isl_give isl_multi_union_pw_aff *isl_schedule_node_band_get_partial_schedule( + __isl_keep isl_schedule_node *node); +__isl_give isl_union_map *isl_schedule_node_band_get_partial_schedule_union_map( + __isl_keep isl_schedule_node *node); +enum isl_ast_loop_type isl_schedule_node_band_member_get_ast_loop_type( + __isl_keep isl_schedule_node *node, int pos); +__isl_export +__isl_give isl_schedule_node *isl_schedule_node_band_member_set_ast_loop_type( + __isl_take isl_schedule_node *node, int pos, + enum isl_ast_loop_type type); +enum isl_ast_loop_type isl_schedule_node_band_member_get_isolate_ast_loop_type( + __isl_keep isl_schedule_node *node, int pos); +__isl_give isl_schedule_node * +isl_schedule_node_band_member_set_isolate_ast_loop_type( + __isl_take isl_schedule_node *node, int pos, + enum isl_ast_loop_type type); +__isl_export +__isl_give isl_union_set *isl_schedule_node_band_get_ast_build_options( + __isl_keep isl_schedule_node *node); +__isl_export +__isl_give isl_schedule_node *isl_schedule_node_band_set_ast_build_options( + __isl_take isl_schedule_node *node, __isl_take isl_union_set *options); +__isl_export +__isl_give isl_set *isl_schedule_node_band_get_ast_isolate_option( + __isl_keep isl_schedule_node *node); +__isl_export +isl_size isl_schedule_node_band_n_member(__isl_keep isl_schedule_node *node); +__isl_export +isl_bool isl_schedule_node_band_member_get_coincident( + __isl_keep isl_schedule_node *node, int pos); +__isl_export +__isl_give isl_schedule_node *isl_schedule_node_band_member_set_coincident( + __isl_take isl_schedule_node *node, int pos, int coincident); +__isl_export +isl_bool isl_schedule_node_band_get_permutable( + __isl_keep isl_schedule_node *node); +__isl_export +__isl_give isl_schedule_node *isl_schedule_node_band_set_permutable( + __isl_take isl_schedule_node *node, int permutable); + +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); + +__isl_export +__isl_give isl_schedule_node *isl_schedule_node_band_scale( + __isl_take isl_schedule_node *node, __isl_take isl_multi_val *mv); +__isl_export +__isl_give isl_schedule_node *isl_schedule_node_band_scale_down( + __isl_take isl_schedule_node *node, __isl_take isl_multi_val *mv); +__isl_export +__isl_give isl_schedule_node *isl_schedule_node_band_mod( + __isl_take isl_schedule_node *node, __isl_take isl_multi_val *mv); +__isl_export +__isl_give isl_schedule_node *isl_schedule_node_band_shift( + __isl_take isl_schedule_node *node, + __isl_take isl_multi_union_pw_aff *shift); +__isl_export +__isl_give isl_schedule_node *isl_schedule_node_band_tile( + __isl_take isl_schedule_node *node, __isl_take isl_multi_val *sizes); +__isl_give isl_schedule_node *isl_schedule_node_band_sink( + __isl_take isl_schedule_node *node); +__isl_export +__isl_give isl_schedule_node *isl_schedule_node_band_split( + __isl_take isl_schedule_node *node, int pos); + +__isl_export +__isl_give isl_set *isl_schedule_node_context_get_context( + __isl_keep isl_schedule_node *node); +__isl_export +__isl_give isl_union_set *isl_schedule_node_domain_get_domain( + __isl_keep isl_schedule_node *node); +__isl_export +__isl_give isl_union_map *isl_schedule_node_expansion_get_expansion( + __isl_keep isl_schedule_node *node); +__isl_export +__isl_give isl_union_pw_multi_aff *isl_schedule_node_expansion_get_contraction( + __isl_keep isl_schedule_node *node); +__isl_export +__isl_give isl_union_map *isl_schedule_node_extension_get_extension( + __isl_keep isl_schedule_node *node); +__isl_export +__isl_give isl_union_set *isl_schedule_node_filter_get_filter( + __isl_keep isl_schedule_node *node); +__isl_export +__isl_give isl_set *isl_schedule_node_guard_get_guard( + __isl_keep isl_schedule_node *node); +__isl_give isl_id *isl_schedule_node_mark_get_id( + __isl_keep isl_schedule_node *node); + +isl_size isl_schedule_node_get_schedule_depth( + __isl_keep isl_schedule_node *node); +__isl_give isl_union_set *isl_schedule_node_get_domain( + __isl_keep isl_schedule_node *node); +__isl_give isl_union_set *isl_schedule_node_get_universe_domain( + __isl_keep isl_schedule_node *node); +__isl_export +__isl_give isl_multi_union_pw_aff * +isl_schedule_node_get_prefix_schedule_multi_union_pw_aff( + __isl_keep isl_schedule_node *node); +__isl_export +__isl_give isl_union_pw_multi_aff * +isl_schedule_node_get_prefix_schedule_union_pw_multi_aff( + __isl_keep isl_schedule_node *node); +__isl_export +__isl_give isl_union_map *isl_schedule_node_get_prefix_schedule_union_map( + __isl_keep isl_schedule_node *node); +__isl_give isl_union_map *isl_schedule_node_get_prefix_schedule_relation( + __isl_keep isl_schedule_node *node); +__isl_give isl_union_map *isl_schedule_node_get_subtree_schedule_union_map( + __isl_keep isl_schedule_node *node); +__isl_give isl_union_map *isl_schedule_node_get_subtree_expansion( + __isl_keep isl_schedule_node *node); +__isl_give isl_union_pw_multi_aff *isl_schedule_node_get_subtree_contraction( + __isl_keep isl_schedule_node *node); + +__isl_export +__isl_give isl_schedule_node *isl_schedule_node_insert_context( + __isl_take isl_schedule_node *node, __isl_take isl_set *context); +__isl_export +__isl_give isl_schedule_node *isl_schedule_node_insert_partial_schedule( + __isl_take isl_schedule_node *node, + __isl_take isl_multi_union_pw_aff *schedule); +__isl_export +__isl_give isl_schedule_node *isl_schedule_node_insert_filter( + __isl_take isl_schedule_node *node, __isl_take isl_union_set *filter); +__isl_export +__isl_give isl_schedule_node *isl_schedule_node_insert_guard( + __isl_take isl_schedule_node *node, __isl_take isl_set *context); +__isl_export +__isl_give isl_schedule_node *isl_schedule_node_insert_mark( + __isl_take isl_schedule_node *node, __isl_take isl_id *mark); +__isl_export +__isl_give isl_schedule_node *isl_schedule_node_insert_sequence( + __isl_take isl_schedule_node *node, + __isl_take isl_union_set_list *filters); +__isl_export +__isl_give isl_schedule_node *isl_schedule_node_insert_set( + __isl_take isl_schedule_node *node, + __isl_take isl_union_set_list *filters); + +__isl_give isl_schedule_node *isl_schedule_node_cut( + __isl_take isl_schedule_node *node); +__isl_give isl_schedule_node *isl_schedule_node_delete( + __isl_take isl_schedule_node *node); + +__isl_export +__isl_give isl_schedule_node *isl_schedule_node_order_before( + __isl_take isl_schedule_node *node, __isl_take isl_union_set *filter); +__isl_export +__isl_give isl_schedule_node *isl_schedule_node_order_after( + __isl_take isl_schedule_node *node, __isl_take isl_union_set *filter); + +__isl_export +__isl_give isl_schedule_node *isl_schedule_node_graft_before( + __isl_take isl_schedule_node *node, + __isl_take isl_schedule_node *graft); +__isl_export +__isl_give isl_schedule_node *isl_schedule_node_graft_after( + __isl_take isl_schedule_node *node, + __isl_take isl_schedule_node *graft); + +__isl_give isl_schedule_node *isl_schedule_node_reset_user( + __isl_take isl_schedule_node *node); +__isl_give isl_schedule_node *isl_schedule_node_align_params( + __isl_take isl_schedule_node *node, __isl_take isl_space *space); + +__isl_give isl_printer *isl_printer_print_schedule_node( + __isl_take isl_printer *p, __isl_keep isl_schedule_node *node); +void isl_schedule_node_dump(__isl_keep isl_schedule_node *node); +__isl_give char *isl_schedule_node_to_str(__isl_keep isl_schedule_node *node); + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/external/mit/isl/dist/include/isl/schedule_type.h b/external/mit/isl/dist/include/isl/schedule_type.h new file mode 100644 index 000000000000..f5a6d4cad91f --- /dev/null +++ b/external/mit/isl/dist/include/isl/schedule_type.h @@ -0,0 +1,33 @@ +#ifndef ISL_SCHEDULE_TYPE_H +#define ISL_SCHEDULE_TYPE_H + +#if defined(__cplusplus) +extern "C" { +#endif + +enum isl_schedule_node_type { + isl_schedule_node_error = -1, + isl_schedule_node_band, + isl_schedule_node_context, + isl_schedule_node_domain, + isl_schedule_node_expansion, + isl_schedule_node_extension, + isl_schedule_node_filter, + isl_schedule_node_leaf, + isl_schedule_node_guard, + isl_schedule_node_mark, + isl_schedule_node_sequence, + isl_schedule_node_set +}; + +struct __isl_export isl_schedule_node; +typedef struct isl_schedule_node isl_schedule_node; + +struct __isl_export isl_schedule; +typedef struct isl_schedule isl_schedule; + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/external/mit/isl/dist/include/isl/set.h b/external/mit/isl/dist/include/isl/set.h new file mode 100644 index 000000000000..326267eb939c --- /dev/null +++ b/external/mit/isl/dist/include/isl/set.h @@ -0,0 +1,606 @@ +/* + * 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_SET_H +#define ISL_SET_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +isl_size isl_basic_set_n_dim(__isl_keep isl_basic_set *bset); +isl_size isl_basic_set_n_param(__isl_keep isl_basic_set *bset); +isl_size isl_basic_set_total_dim(__isl_keep const isl_basic_set *bset); +isl_size isl_basic_set_dim(__isl_keep isl_basic_set *bset, + enum isl_dim_type type); + +isl_size isl_set_n_dim(__isl_keep isl_set *set); +isl_size isl_set_n_param(__isl_keep isl_set *set); +__isl_export +isl_size isl_set_tuple_dim(__isl_keep isl_set *set); +isl_size isl_set_dim(__isl_keep isl_set *set, enum isl_dim_type type); + +isl_ctx *isl_basic_set_get_ctx(__isl_keep isl_basic_set *bset); +isl_ctx *isl_set_get_ctx(__isl_keep isl_set *set); +__isl_give isl_space *isl_basic_set_get_space(__isl_keep isl_basic_set *bset); +__isl_export +__isl_give isl_space *isl_set_get_space(__isl_keep isl_set *set); +__isl_give isl_set *isl_set_reset_space(__isl_take isl_set *set, + __isl_take isl_space *space); + +__isl_give isl_aff *isl_basic_set_get_div(__isl_keep isl_basic_set *bset, + int pos); + +__isl_give isl_local_space *isl_basic_set_get_local_space( + __isl_keep isl_basic_set *bset); + +const char *isl_basic_set_get_tuple_name(__isl_keep isl_basic_set *bset); +isl_bool isl_set_has_tuple_name(__isl_keep isl_set *set); +const char *isl_set_get_tuple_name(__isl_keep isl_set *set); +__isl_give isl_basic_set *isl_basic_set_set_tuple_name( + __isl_take isl_basic_set *set, const char *s); +__isl_give isl_set *isl_set_set_tuple_name(__isl_take isl_set *set, + const char *s); +const char *isl_basic_set_get_dim_name(__isl_keep isl_basic_set *bset, + enum isl_dim_type type, unsigned pos); +__isl_give isl_basic_set *isl_basic_set_set_dim_name( + __isl_take isl_basic_set *bset, + enum isl_dim_type type, unsigned pos, const char *s); +isl_bool isl_set_has_dim_name(__isl_keep isl_set *set, + enum isl_dim_type type, unsigned pos); +const char *isl_set_get_dim_name(__isl_keep isl_set *set, + enum isl_dim_type type, unsigned pos); +__isl_give isl_set *isl_set_set_dim_name(__isl_take isl_set *set, + enum isl_dim_type type, unsigned pos, const char *s); + +__isl_give isl_id *isl_basic_set_get_dim_id(__isl_keep isl_basic_set *bset, + enum isl_dim_type type, unsigned pos); +__isl_give isl_basic_set *isl_basic_set_set_tuple_id( + __isl_take isl_basic_set *bset, __isl_take isl_id *id); +__isl_give isl_set *isl_set_set_dim_id(__isl_take isl_set *set, + enum isl_dim_type type, unsigned pos, __isl_take isl_id *id); +isl_bool isl_set_has_dim_id(__isl_keep isl_set *set, + enum isl_dim_type type, unsigned pos); +__isl_give isl_id *isl_set_get_dim_id(__isl_keep isl_set *set, + enum isl_dim_type type, unsigned pos); +__isl_give isl_set *isl_set_set_tuple_id(__isl_take isl_set *set, + __isl_take isl_id *id); +__isl_give isl_set *isl_set_reset_tuple_id(__isl_take isl_set *set); +isl_bool isl_set_has_tuple_id(__isl_keep isl_set *set); +__isl_give isl_id *isl_set_get_tuple_id(__isl_keep isl_set *set); +__isl_give isl_set *isl_set_reset_user(__isl_take isl_set *set); + +int isl_set_find_dim_by_id(__isl_keep isl_set *set, enum isl_dim_type type, + __isl_keep isl_id *id); +int isl_set_find_dim_by_name(__isl_keep isl_set *set, enum isl_dim_type type, + const char *name); + +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 *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 *space); +__isl_give isl_basic_set *isl_basic_set_positive_orthant( + __isl_take isl_space *space); +void isl_basic_set_print_internal(__isl_keep isl_basic_set *bset, + FILE *out, int indent); +__isl_export +__isl_give isl_basic_set *isl_basic_set_intersect( + __isl_take isl_basic_set *bset1, + __isl_take isl_basic_set *bset2); +__isl_export +__isl_give isl_basic_set *isl_basic_set_intersect_params( + __isl_take isl_basic_set *bset1, __isl_take isl_basic_set *bset2); +__isl_export +__isl_give isl_basic_set *isl_basic_set_apply( + __isl_take isl_basic_set *bset, + __isl_take isl_basic_map *bmap); +__isl_give isl_basic_set *isl_basic_set_preimage_multi_aff( + __isl_take isl_basic_set *bset, __isl_take isl_multi_aff *ma); +__isl_export +__isl_give isl_basic_set *isl_basic_set_affine_hull( + __isl_take isl_basic_set *bset); +__isl_give isl_basic_set *isl_basic_set_remove_dims( + __isl_take isl_basic_set *bset, + enum isl_dim_type type, unsigned first, unsigned n); +__isl_export +__isl_give isl_basic_set *isl_basic_set_sample(__isl_take isl_basic_set *bset); +__isl_export +__isl_give isl_basic_set *isl_basic_set_detect_equalities( + __isl_take isl_basic_set *bset); +__isl_give isl_basic_set *isl_basic_set_remove_redundancies( + __isl_take isl_basic_set *bset); +__isl_give isl_set *isl_set_remove_redundancies(__isl_take isl_set *set); +__isl_give isl_basic_set *isl_basic_set_list_intersect( + __isl_take struct isl_basic_set_list *list); + +__isl_give isl_set *isl_set_list_union(__isl_take isl_set_list *list); + +__isl_give isl_basic_set *isl_basic_set_read_from_file(isl_ctx *ctx, + FILE *input); +__isl_constructor +__isl_give isl_basic_set *isl_basic_set_read_from_str(isl_ctx *ctx, + const char *str); +__isl_give isl_set *isl_set_read_from_file(isl_ctx *ctx, FILE *input); +__isl_constructor +__isl_give isl_set *isl_set_read_from_str(isl_ctx *ctx, const char *str); +void isl_basic_set_dump(__isl_keep isl_basic_set *bset); +void isl_set_dump(__isl_keep isl_set *set); +__isl_give isl_printer *isl_printer_print_basic_set( + __isl_take isl_printer *printer, __isl_keep isl_basic_set *bset); +__isl_give isl_printer *isl_printer_print_set(__isl_take isl_printer *printer, + __isl_keep isl_set *map); +__isl_give isl_basic_set *isl_basic_set_fix_si(__isl_take isl_basic_set *bset, + enum isl_dim_type type, unsigned pos, int value); +__isl_give isl_basic_set *isl_basic_set_fix_val(__isl_take isl_basic_set *bset, + enum isl_dim_type type, unsigned pos, __isl_take isl_val *v); +__isl_give isl_set *isl_set_fix_si(__isl_take isl_set *set, + enum isl_dim_type type, unsigned pos, int value); +__isl_give isl_set *isl_set_lower_bound_si(__isl_take isl_set *set, + enum isl_dim_type type, unsigned pos, int value); +__isl_give isl_basic_set *isl_basic_set_lower_bound_val( + __isl_take isl_basic_set *bset, enum isl_dim_type type, unsigned pos, + __isl_take isl_val *value); +__isl_give isl_set *isl_set_lower_bound_val(__isl_take isl_set *set, + enum isl_dim_type type, unsigned pos, __isl_take isl_val *value); +__isl_give isl_set *isl_set_upper_bound_si(__isl_take isl_set *set, + enum isl_dim_type type, unsigned pos, int value); +__isl_give isl_basic_set *isl_basic_set_upper_bound_val( + __isl_take isl_basic_set *bset, enum isl_dim_type type, unsigned pos, + __isl_take isl_val *value); +__isl_give isl_set *isl_set_upper_bound_val(__isl_take isl_set *set, + enum isl_dim_type type, unsigned pos, __isl_take isl_val *value); +__isl_overload +__isl_give isl_set *isl_set_lower_bound_multi_val(__isl_take isl_set *set, + __isl_take isl_multi_val *lower); +__isl_overload +__isl_give isl_set *isl_set_upper_bound_multi_val(__isl_take isl_set *set, + __isl_take isl_multi_val *upper); +__isl_overload +__isl_give isl_set *isl_set_lower_bound_multi_pw_aff(__isl_take isl_set *set, + __isl_take isl_multi_pw_aff *lower); +__isl_overload +__isl_give isl_set *isl_set_upper_bound_multi_pw_aff(__isl_take isl_set *set, + __isl_take isl_multi_pw_aff *upper); + +__isl_give isl_set *isl_set_equate(__isl_take isl_set *set, + enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2); + +__isl_export +isl_bool isl_basic_set_is_equal(__isl_keep isl_basic_set *bset1, + __isl_keep isl_basic_set *bset2); +isl_bool isl_basic_set_is_disjoint(__isl_keep isl_basic_set *bset1, + __isl_keep isl_basic_set *bset2); + +__isl_give isl_set *isl_basic_set_partial_lexmin( + __isl_take isl_basic_set *bset, __isl_take isl_basic_set *dom, + __isl_give isl_set **empty); +__isl_give isl_set *isl_basic_set_partial_lexmax( + __isl_take isl_basic_set *bset, __isl_take isl_basic_set *dom, + __isl_give isl_set **empty); +__isl_give isl_set *isl_set_partial_lexmin( + __isl_take isl_set *set, __isl_take isl_set *dom, + __isl_give isl_set **empty); +__isl_give isl_set *isl_set_partial_lexmax( + __isl_take isl_set *set, __isl_take isl_set *dom, + __isl_give isl_set **empty); +__isl_export +__isl_give isl_set *isl_basic_set_lexmin(__isl_take isl_basic_set *bset); +__isl_export +__isl_give isl_set *isl_basic_set_lexmax(__isl_take isl_basic_set *bset); +__isl_export +__isl_give isl_set *isl_set_lexmin(__isl_take isl_set *set); +__isl_export +__isl_give isl_set *isl_set_lexmax(__isl_take isl_set *set); +__isl_give isl_pw_multi_aff *isl_basic_set_partial_lexmin_pw_multi_aff( + __isl_take isl_basic_set *bset, __isl_take isl_basic_set *dom, + __isl_give isl_set **empty); +__isl_give isl_pw_multi_aff *isl_basic_set_partial_lexmax_pw_multi_aff( + __isl_take isl_basic_set *bset, __isl_take isl_basic_set *dom, + __isl_give isl_set **empty); +__isl_export +__isl_give isl_pw_multi_aff *isl_set_lexmin_pw_multi_aff( + __isl_take isl_set *set); +__isl_export +__isl_give isl_pw_multi_aff *isl_set_lexmax_pw_multi_aff( + __isl_take isl_set *set); +__isl_export +__isl_give isl_multi_pw_aff *isl_set_min_multi_pw_aff(__isl_take isl_set *set); +__isl_export +__isl_give isl_multi_pw_aff *isl_set_max_multi_pw_aff(__isl_take isl_set *set); + +__isl_export +__isl_give isl_set *isl_basic_set_union( + __isl_take isl_basic_set *bset1, + __isl_take isl_basic_set *bset2); + +int isl_basic_set_compare_at(__isl_keep isl_basic_set *bset1, + __isl_keep isl_basic_set *bset2, int pos); +int isl_set_follows_at(__isl_keep isl_set *set1, + __isl_keep isl_set *set2, int pos); + +__isl_export +__isl_give isl_basic_set *isl_basic_set_params(__isl_take isl_basic_set *bset); +__isl_give isl_basic_set *isl_basic_set_from_params( + __isl_take isl_basic_set *bset); +__isl_export +__isl_give isl_set *isl_set_params(__isl_take isl_set *set); +__isl_give isl_set *isl_set_from_params(__isl_take isl_set *set); + +__isl_export +__isl_give isl_set *isl_set_bind(__isl_take isl_set *set, + __isl_take isl_multi_id *tuple); +__isl_export +__isl_give isl_set *isl_set_unbind_params(__isl_take isl_set *set, + __isl_take isl_multi_id *tuple); +__isl_export +__isl_give isl_map *isl_set_unbind_params_insert_domain( + __isl_take isl_set *set, __isl_take isl_multi_id *domain); + +isl_stat isl_basic_set_dims_get_sign(__isl_keep isl_basic_set *bset, + enum isl_dim_type type, unsigned pos, unsigned n, int *signs); + +isl_bool isl_basic_set_plain_is_universe(__isl_keep isl_basic_set *bset); +isl_bool isl_basic_set_is_universe(__isl_keep isl_basic_set *bset); +isl_bool isl_basic_set_plain_is_empty(__isl_keep isl_basic_set *bset); +__isl_export +isl_bool isl_basic_set_is_empty(__isl_keep isl_basic_set *bset); +isl_bool isl_basic_set_is_bounded(__isl_keep isl_basic_set *bset); +__isl_export +isl_bool isl_basic_set_is_subset(__isl_keep isl_basic_set *bset1, + __isl_keep isl_basic_set *bset2); +isl_bool isl_basic_set_plain_is_equal(__isl_keep isl_basic_set *bset1, + __isl_keep isl_basic_set *bset2); + +__isl_export +__isl_give isl_set *isl_set_empty(__isl_take isl_space *space); +__isl_export +__isl_give isl_set *isl_set_universe(__isl_take isl_space *space); +__isl_export +__isl_give isl_set *isl_space_universe_set(__isl_take isl_space *space); +__isl_give isl_set *isl_set_nat_universe(__isl_take isl_space *space); +__isl_give isl_set *isl_set_copy(__isl_keep isl_set *set); +__isl_null isl_set *isl_set_free(__isl_take isl_set *set); +__isl_export +__isl_give isl_set *isl_basic_set_to_set(__isl_take isl_basic_set *bset); +__isl_constructor +__isl_give isl_set *isl_set_from_basic_set(__isl_take isl_basic_set *bset); +__isl_export +__isl_give isl_basic_set *isl_set_sample(__isl_take isl_set *set); +__isl_export +__isl_give isl_point *isl_basic_set_sample_point(__isl_take isl_basic_set *bset); +__isl_export +__isl_give isl_point *isl_set_sample_point(__isl_take isl_set *set); +__isl_export +__isl_give isl_set *isl_set_detect_equalities(__isl_take isl_set *set); +__isl_export +__isl_give isl_basic_set *isl_set_affine_hull(__isl_take isl_set *set); +__isl_give isl_basic_set *isl_set_convex_hull(__isl_take isl_set *set); +__isl_export +__isl_give isl_basic_set *isl_set_polyhedral_hull(__isl_take isl_set *set); +__isl_give isl_basic_set *isl_set_simple_hull(__isl_take isl_set *set); +__isl_export +__isl_give isl_basic_set *isl_set_unshifted_simple_hull( + __isl_take isl_set *set); +__isl_give isl_basic_set *isl_set_plain_unshifted_simple_hull( + __isl_take isl_set *set); +__isl_give isl_basic_set *isl_set_unshifted_simple_hull_from_set_list( + __isl_take isl_set *set, __isl_take isl_set_list *list); +__isl_give isl_basic_set *isl_set_bounded_simple_hull(__isl_take isl_set *set); + +__isl_export +__isl_give isl_set *isl_set_wrapped_reverse(__isl_take isl_set *set); +__isl_give isl_set *isl_set_union_disjoint( + __isl_take isl_set *set1, __isl_take isl_set *set2); +__isl_export +__isl_give isl_set *isl_set_union( + __isl_take isl_set *set1, + __isl_take isl_set *set2); +__isl_export +__isl_give isl_set *isl_set_product(__isl_take isl_set *set1, + __isl_take isl_set *set2); +__isl_give isl_basic_set *isl_basic_set_flat_product( + __isl_take isl_basic_set *bset1, __isl_take isl_basic_set *bset2); +__isl_give isl_set *isl_set_flat_product(__isl_take isl_set *set1, + __isl_take isl_set *set2); +__isl_export +__isl_give isl_set *isl_set_intersect( + __isl_take isl_set *set1, + __isl_take isl_set *set2); +__isl_export +__isl_give isl_set *isl_set_intersect_params(__isl_take isl_set *set, + __isl_take isl_set *params); +__isl_give isl_set *isl_set_intersect_factor_domain(__isl_take isl_set *set, + __isl_take isl_set *domain); +__isl_give isl_set *isl_set_intersect_factor_range(__isl_take isl_set *set, + __isl_take isl_set *range); +__isl_export +__isl_give isl_set *isl_set_subtract( + __isl_take isl_set *set1, + __isl_take isl_set *set2); +__isl_export +__isl_give isl_set *isl_set_complement(__isl_take isl_set *set); +__isl_export +__isl_give isl_set *isl_set_apply( + __isl_take isl_set *set, + __isl_take isl_map *map); +__isl_overload +__isl_give isl_set *isl_set_preimage_multi_aff(__isl_take isl_set *set, + __isl_take isl_multi_aff *ma); +__isl_overload +__isl_give isl_set *isl_set_preimage_pw_multi_aff(__isl_take isl_set *set, + __isl_take isl_pw_multi_aff *pma); +__isl_overload +__isl_give isl_set *isl_set_preimage_multi_pw_aff(__isl_take isl_set *set, + __isl_take isl_multi_pw_aff *mpa); +__isl_give isl_set *isl_set_fix_val(__isl_take isl_set *set, + enum isl_dim_type type, unsigned pos, __isl_take isl_val *v); +__isl_give isl_set *isl_set_fix_dim_si(__isl_take isl_set *set, + unsigned dim, int value); +__isl_give isl_basic_set *isl_basic_set_insert_dims( + __isl_take isl_basic_set *bset, + enum isl_dim_type type, unsigned pos, unsigned n); +__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_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, + enum isl_dim_type dst_type, unsigned dst_pos, + enum isl_dim_type src_type, unsigned src_pos, unsigned n); +__isl_give isl_set *isl_set_move_dims(__isl_take isl_set *set, + enum isl_dim_type dst_type, unsigned dst_pos, + enum isl_dim_type src_type, unsigned src_pos, unsigned n); +__isl_give isl_basic_set *isl_basic_set_project_out( + __isl_take isl_basic_set *bset, + enum isl_dim_type type, unsigned first, unsigned n); +__isl_overload +__isl_give isl_set *isl_set_project_out_param_id(__isl_take isl_set *set, + __isl_take isl_id *id); +__isl_overload +__isl_give isl_set *isl_set_project_out_param_id_list(__isl_take isl_set *set, + __isl_take isl_id_list *list); +__isl_give isl_set *isl_set_project_out(__isl_take isl_set *set, + enum isl_dim_type type, unsigned first, unsigned n); +__isl_export +__isl_give isl_set *isl_set_project_out_all_params(__isl_take isl_set *set); +__isl_give isl_map *isl_set_project_onto_map(__isl_take isl_set *set, + enum isl_dim_type type, unsigned first, unsigned n); +__isl_give isl_basic_set *isl_basic_set_remove_divs( + __isl_take isl_basic_set *bset); +__isl_give isl_basic_set *isl_basic_set_eliminate( + __isl_take isl_basic_set *bset, + enum isl_dim_type type, unsigned first, unsigned n); +__isl_give isl_set *isl_set_eliminate(__isl_take isl_set *set, + enum isl_dim_type type, unsigned first, unsigned n); +__isl_give isl_set *isl_set_eliminate_dims(__isl_take isl_set *set, + unsigned first, unsigned n); +__isl_give isl_set *isl_set_remove_dims(__isl_take isl_set *bset, + enum isl_dim_type type, unsigned first, unsigned n); +__isl_give isl_basic_set *isl_basic_set_remove_divs_involving_dims( + __isl_take isl_basic_set *bset, + enum isl_dim_type type, unsigned first, unsigned n); +__isl_give isl_set *isl_set_remove_divs_involving_dims(__isl_take isl_set *set, + enum isl_dim_type type, unsigned first, unsigned n); +__isl_give isl_basic_set *isl_basic_set_remove_unknown_divs( + __isl_take isl_basic_set *bset); +__isl_give isl_set *isl_set_remove_unknown_divs(__isl_take isl_set *set); +__isl_give isl_set *isl_set_remove_divs(__isl_take isl_set *set); +__isl_give isl_set *isl_set_split_dims(__isl_take isl_set *set, + enum isl_dim_type type, unsigned first, unsigned n); + +__isl_give isl_basic_set *isl_basic_set_drop_constraints_involving_dims( + __isl_take isl_basic_set *bset, + enum isl_dim_type type, unsigned first, unsigned n); +__isl_give isl_basic_set *isl_basic_set_drop_constraints_not_involving_dims( + __isl_take isl_basic_set *bset, + enum isl_dim_type type, unsigned first, unsigned n); +__isl_give isl_set *isl_set_drop_constraints_involving_dims( + __isl_take isl_set *set, + enum isl_dim_type type, unsigned first, unsigned n); +__isl_give isl_set *isl_set_drop_constraints_not_involving_dims( + __isl_take isl_set *set, + enum isl_dim_type type, unsigned first, unsigned n); + +__isl_export +isl_bool isl_set_involves_locals(__isl_keep isl_set *set); + +isl_bool isl_basic_set_involves_dims(__isl_keep isl_basic_set *bset, + enum isl_dim_type type, unsigned first, unsigned n); +isl_bool isl_set_involves_dims(__isl_keep isl_set *set, + enum isl_dim_type type, unsigned first, unsigned n); + +void isl_set_print_internal(__isl_keep isl_set *set, FILE *out, int indent); +isl_bool isl_set_plain_is_empty(__isl_keep isl_set *set); +isl_bool isl_set_plain_is_universe(__isl_keep isl_set *set); +isl_bool isl_set_is_params(__isl_keep isl_set *set); +__isl_export +isl_bool isl_set_is_empty(__isl_keep isl_set *set); +isl_bool isl_set_is_bounded(__isl_keep isl_set *set); +__isl_export +isl_bool isl_set_is_subset(__isl_keep isl_set *set1, __isl_keep isl_set *set2); +__isl_export +isl_bool isl_set_is_strict_subset(__isl_keep isl_set *set1, + __isl_keep isl_set *set2); +__isl_export +isl_bool isl_set_is_equal(__isl_keep isl_set *set1, __isl_keep isl_set *set2); +__isl_export +isl_bool isl_set_is_disjoint(__isl_keep isl_set *set1, + __isl_keep isl_set *set2); +__isl_export +isl_bool isl_set_is_singleton(__isl_keep isl_set *set); +isl_bool isl_set_is_box(__isl_keep isl_set *set); +isl_bool isl_set_has_equal_space(__isl_keep isl_set *set1, + __isl_keep isl_set *set2); + +__isl_give isl_set *isl_set_sum(__isl_take isl_set *set1, + __isl_take isl_set *set2); +__isl_give isl_basic_set *isl_basic_set_neg(__isl_take isl_basic_set *bset); +__isl_give isl_set *isl_set_neg(__isl_take isl_set *set); + +__isl_give isl_set *isl_set_make_disjoint(__isl_take isl_set *set); +__isl_give isl_set *isl_basic_set_compute_divs(__isl_take isl_basic_set *bset); +__isl_give isl_set *isl_set_compute_divs(__isl_take isl_set *set); +ISL_DEPRECATED +__isl_give isl_set *isl_set_align_divs(__isl_take isl_set *set); + +__isl_export +__isl_give isl_multi_val *isl_set_get_plain_multi_val_if_fixed( + __isl_keep isl_set *set); +__isl_give isl_val *isl_set_plain_get_val_if_fixed(__isl_keep isl_set *set, + enum isl_dim_type type, unsigned pos); +isl_bool isl_set_dim_is_bounded(__isl_keep isl_set *set, + enum isl_dim_type type, unsigned pos); +isl_bool isl_set_dim_has_lower_bound(__isl_keep isl_set *set, + enum isl_dim_type type, unsigned pos); +isl_bool isl_set_dim_has_upper_bound(__isl_keep isl_set *set, + enum isl_dim_type type, unsigned pos); +isl_bool isl_set_dim_has_any_lower_bound(__isl_keep isl_set *set, + enum isl_dim_type type, unsigned pos); +isl_bool isl_set_dim_has_any_upper_bound(__isl_keep isl_set *set, + enum isl_dim_type type, unsigned pos); + +__isl_export +__isl_give isl_basic_set *isl_basic_set_gist(__isl_take isl_basic_set *bset, + __isl_take isl_basic_set *context); +__isl_give isl_set *isl_set_gist_basic_set(__isl_take isl_set *set, + __isl_take isl_basic_set *context); +__isl_export +__isl_give isl_set *isl_set_gist(__isl_take isl_set *set, + __isl_take isl_set *context); +__isl_export +__isl_give isl_set *isl_set_gist_params(__isl_take isl_set *set, + __isl_take isl_set *context); +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); + +__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_fixed_box *isl_set_get_lattice_tile(__isl_keep isl_set *set); +__isl_export +__isl_give isl_fixed_box *isl_set_get_simple_fixed_box_hull( + __isl_keep isl_set *set); + +__isl_export +__isl_give isl_set *isl_set_coalesce(__isl_take isl_set *set); + +int isl_set_plain_cmp(__isl_keep isl_set *set1, __isl_keep isl_set *set2); +isl_bool isl_set_plain_is_equal(__isl_keep isl_set *set1, + __isl_keep isl_set *set2); +isl_bool isl_set_plain_is_disjoint(__isl_keep isl_set *set1, + __isl_keep isl_set *set2); + +uint32_t isl_set_get_hash(__isl_keep isl_set *set); + +__isl_export +isl_size isl_set_n_basic_set(__isl_keep isl_set *set); +__isl_export +isl_stat isl_set_foreach_basic_set(__isl_keep isl_set *set, + isl_stat (*fn)(__isl_take isl_basic_set *bset, void *user), void *user); +__isl_give isl_basic_set_list *isl_set_get_basic_set_list( + __isl_keep isl_set *set); + +__isl_export +isl_stat isl_set_foreach_point(__isl_keep isl_set *set, + isl_stat (*fn)(__isl_take isl_point *pnt, void *user), void *user); +__isl_give isl_val *isl_set_count_val(__isl_keep isl_set *set); + +__isl_constructor +__isl_give isl_basic_set *isl_basic_set_from_point(__isl_take isl_point *pnt); +__isl_export +__isl_give isl_set *isl_point_to_set(__isl_take isl_point *pnt); +__isl_constructor +__isl_give isl_set *isl_set_from_point(__isl_take isl_point *pnt); +__isl_give isl_basic_set *isl_basic_set_box_from_points( + __isl_take isl_point *pnt1, __isl_take isl_point *pnt2); +__isl_give isl_set *isl_set_box_from_points(__isl_take isl_point *pnt1, + __isl_take isl_point *pnt2); + +__isl_give isl_basic_set *isl_basic_set_lift(__isl_take isl_basic_set *bset); +__isl_give isl_set *isl_set_lift(__isl_take isl_set *set); + +__isl_give isl_map *isl_set_lex_le_set(__isl_take isl_set *set1, + __isl_take isl_set *set2); +__isl_give isl_map *isl_set_lex_lt_set(__isl_take isl_set *set1, + __isl_take isl_set *set2); +__isl_give isl_map *isl_set_lex_ge_set(__isl_take isl_set *set1, + __isl_take isl_set *set2); +__isl_give isl_map *isl_set_lex_gt_set(__isl_take isl_set *set1, + __isl_take isl_set *set2); + +int isl_set_size(__isl_keep isl_set *set); + +__isl_give isl_basic_set *isl_basic_set_align_params( + __isl_take isl_basic_set *bset, __isl_take isl_space *model); +__isl_give isl_set *isl_set_align_params(__isl_take isl_set *set, + __isl_take isl_space *model); +__isl_give isl_basic_set *isl_basic_set_drop_unused_params( + __isl_take isl_basic_set *bset); +__isl_export +__isl_give isl_set *isl_set_drop_unused_params(__isl_take isl_set *set); + +__isl_give isl_mat *isl_basic_set_equalities_matrix( + __isl_keep isl_basic_set *bset, enum isl_dim_type c1, + enum isl_dim_type c2, enum isl_dim_type c3, enum isl_dim_type c4); +__isl_give isl_mat *isl_basic_set_inequalities_matrix( + __isl_keep isl_basic_set *bset, enum isl_dim_type c1, + enum isl_dim_type c2, enum isl_dim_type c3, enum isl_dim_type c4); +__isl_give isl_basic_set *isl_basic_set_from_constraint_matrices( + __isl_take isl_space *space, + __isl_take isl_mat *eq, __isl_take isl_mat *ineq, enum isl_dim_type c1, + enum isl_dim_type c2, enum isl_dim_type c3, enum isl_dim_type c4); + +__isl_give isl_basic_set *isl_basic_set_from_multi_aff( + __isl_take isl_multi_aff *ma); + +__isl_export +__isl_give isl_set *isl_multi_aff_as_set(__isl_take isl_multi_aff *ma); +__isl_give isl_set *isl_set_from_multi_aff(__isl_take isl_multi_aff *ma); + +__isl_give isl_mat *isl_basic_set_reduced_basis(__isl_keep isl_basic_set *bset); + +__isl_give isl_basic_set *isl_basic_set_coefficients( + __isl_take isl_basic_set *bset); +__isl_give isl_basic_set_list *isl_basic_set_list_coefficients( + __isl_take isl_basic_set_list *list); +__isl_give isl_basic_set *isl_set_coefficients(__isl_take isl_set *set); +__isl_give isl_basic_set *isl_basic_set_solutions( + __isl_take isl_basic_set *bset); +__isl_give isl_basic_set *isl_set_solutions(__isl_take isl_set *set); + +__isl_give isl_pw_aff *isl_set_dim_max(__isl_take isl_set *set, int pos); +__isl_give isl_pw_aff *isl_set_dim_min(__isl_take isl_set *set, int pos); + +__isl_give char *isl_basic_set_to_str(__isl_keep isl_basic_set *bset); +__isl_give char *isl_set_to_str(__isl_keep isl_set *set); + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/external/mit/isl/dist/include/isl/set_type.h b/external/mit/isl/dist/include/isl/set_type.h new file mode 100644 index 000000000000..ce349e1b5d4a --- /dev/null +++ b/external/mit/isl/dist/include/isl/set_type.h @@ -0,0 +1,6 @@ +#ifndef ISL_SET_TYPE_H +#define ISL_SET_TYPE_H + +#include + +#endif diff --git a/external/mit/isl/dist/include/isl/space.h b/external/mit/isl/dist/include/isl/space.h new file mode 100644 index 000000000000..2c87a7307dab --- /dev/null +++ b/external/mit/isl/dist/include/isl/space.h @@ -0,0 +1,233 @@ +/* + * 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_SPACE_H +#define ISL_SPACE_H + +#include +#include +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +isl_ctx *isl_space_get_ctx(__isl_keep isl_space *space); +__isl_export +__isl_give isl_space *isl_space_unit(isl_ctx *ctx); +__isl_give isl_space *isl_space_alloc(isl_ctx *ctx, + unsigned nparam, unsigned n_in, unsigned n_out); +__isl_give isl_space *isl_space_set_alloc(isl_ctx *ctx, + unsigned nparam, unsigned dim); +__isl_give isl_space *isl_space_params_alloc(isl_ctx *ctx, unsigned nparam); +__isl_give isl_space *isl_space_copy(__isl_keep isl_space *space); +__isl_null isl_space *isl_space_free(__isl_take isl_space *space); + +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_overload +__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 *space, + enum isl_dim_type type, const char *s); +isl_bool isl_space_has_tuple_name(__isl_keep isl_space *space, + enum isl_dim_type type); +__isl_keep const char *isl_space_get_tuple_name(__isl_keep isl_space *space, + enum isl_dim_type type); +__isl_overload +__isl_give isl_space *isl_space_set_domain_tuple_id( + __isl_take isl_space *space, __isl_take isl_id *id); +__isl_overload +__isl_give isl_space *isl_space_set_range_tuple_id( + __isl_take isl_space *space, __isl_take isl_id *id); +__isl_give isl_space *isl_space_set_tuple_id(__isl_take isl_space *space, + enum isl_dim_type type, __isl_take isl_id *id); +__isl_give isl_space *isl_space_reset_tuple_id(__isl_take isl_space *space, + enum isl_dim_type type); +__isl_export +isl_bool isl_space_has_domain_tuple_id(__isl_keep isl_space *space); +__isl_export +isl_bool isl_space_has_range_tuple_id(__isl_keep isl_space *space); +isl_bool isl_space_has_tuple_id(__isl_keep isl_space *space, + enum isl_dim_type type); +__isl_export +__isl_give isl_id *isl_space_get_domain_tuple_id( + __isl_keep isl_space *space); +__isl_export +__isl_give isl_id *isl_space_get_range_tuple_id( + __isl_keep isl_space *space); +__isl_give isl_id *isl_space_get_tuple_id(__isl_keep isl_space *space, + enum isl_dim_type type); +__isl_give isl_space *isl_space_reset_user(__isl_take isl_space *space); + +__isl_give isl_space *isl_space_set_dim_id(__isl_take isl_space *space, + enum isl_dim_type type, unsigned pos, __isl_take isl_id *id); +isl_bool isl_space_has_dim_id(__isl_keep isl_space *space, + enum isl_dim_type type, unsigned pos); +__isl_give isl_id *isl_space_get_dim_id(__isl_keep isl_space *space, + enum isl_dim_type type, unsigned pos); + +int isl_space_find_dim_by_id(__isl_keep isl_space *space, + enum isl_dim_type type, __isl_keep isl_id *id); +int isl_space_find_dim_by_name(__isl_keep isl_space *space, + enum isl_dim_type type, const char *name); + +isl_bool isl_space_has_dim_name(__isl_keep isl_space *space, + enum isl_dim_type type, unsigned pos); +__isl_give isl_space *isl_space_set_dim_name(__isl_take isl_space *space, + enum isl_dim_type type, unsigned pos, + __isl_keep const char *name); +__isl_keep const char *isl_space_get_dim_name(__isl_keep isl_space *space, + enum isl_dim_type type, unsigned pos); + +ISL_DEPRECATED +__isl_give isl_space *isl_space_extend(__isl_take isl_space *space, + unsigned nparam, unsigned n_in, unsigned n_out); +__isl_give isl_space *isl_space_add_dims(__isl_take isl_space *space, + enum isl_dim_type type, unsigned n); +__isl_give isl_space *isl_space_move_dims(__isl_take isl_space *space, + enum isl_dim_type dst_type, unsigned dst_pos, + enum isl_dim_type src_type, unsigned src_pos, unsigned n); +__isl_give isl_space *isl_space_insert_dims(__isl_take isl_space *space, + enum isl_dim_type type, unsigned pos, unsigned n); +__isl_give isl_space *isl_space_join(__isl_take isl_space *left, + __isl_take isl_space *right); +__isl_export +__isl_give isl_space *isl_space_product(__isl_take isl_space *left, + __isl_take isl_space *right); +__isl_give isl_space *isl_space_domain_product(__isl_take isl_space *left, + __isl_take isl_space *right); +__isl_give isl_space *isl_space_range_product(__isl_take isl_space *left, + __isl_take isl_space *right); +__isl_give isl_space *isl_space_factor_domain(__isl_take isl_space *space); +__isl_give isl_space *isl_space_factor_range(__isl_take isl_space *space); +__isl_give isl_space *isl_space_domain_factor_domain( + __isl_take isl_space *space); +__isl_give isl_space *isl_space_domain_factor_range( + __isl_take isl_space *space); +__isl_give isl_space *isl_space_range_factor_domain( + __isl_take isl_space *space); +__isl_give isl_space *isl_space_range_factor_range( + __isl_take isl_space *space); +__isl_give isl_space *isl_space_domain_wrapped_domain( + __isl_take isl_space *space); +__isl_give isl_space *isl_space_domain_wrapped_range( + __isl_take isl_space *space); +__isl_give isl_space *isl_space_range_wrapped_domain( + __isl_take isl_space *space); +__isl_give isl_space *isl_space_range_wrapped_range( + __isl_take isl_space *space); +__isl_export +__isl_give isl_space *isl_space_map_from_set(__isl_take isl_space *space); +__isl_give isl_space *isl_space_map_from_domain_and_range( + __isl_take isl_space *domain, __isl_take isl_space *range); +__isl_export +__isl_give isl_space *isl_space_reverse(__isl_take isl_space *space); +__isl_export +__isl_give isl_space *isl_space_wrapped_reverse(__isl_take isl_space *space); +__isl_export +__isl_give isl_space *isl_space_domain_reverse(__isl_take isl_space *space); +__isl_export +__isl_give isl_space *isl_space_range_reverse(__isl_take isl_space *space); +__isl_give isl_space *isl_space_drop_dims(__isl_take isl_space *space, + enum isl_dim_type type, unsigned first, unsigned num); +ISL_DEPRECATED +__isl_give isl_space *isl_space_drop_inputs(__isl_take isl_space *space, + unsigned first, unsigned n); +ISL_DEPRECATED +__isl_give isl_space *isl_space_drop_outputs(__isl_take isl_space *space, + unsigned first, unsigned n); +__isl_export +__isl_give isl_space *isl_space_drop_all_params(__isl_take isl_space *space); +__isl_export +__isl_give isl_space *isl_space_domain(__isl_take isl_space *space); +__isl_give isl_space *isl_space_from_domain(__isl_take isl_space *space); +__isl_export +__isl_give isl_space *isl_space_range(__isl_take isl_space *space); +__isl_give isl_space *isl_space_from_range(__isl_take isl_space *space); +__isl_give isl_space *isl_space_domain_map(__isl_take isl_space *space); +__isl_give isl_space *isl_space_range_map(__isl_take isl_space *space); +__isl_export +__isl_give isl_space *isl_space_params(__isl_take isl_space *space); +__isl_overload +__isl_give isl_space *isl_space_add_unnamed_tuple_ui( + __isl_take isl_space *space, unsigned dim); +__isl_overload +__isl_give isl_space *isl_space_add_named_tuple_id_ui( + __isl_take isl_space *space, __isl_take isl_id *tuple_id, unsigned dim); +__isl_give isl_space *isl_space_set_from_params(__isl_take isl_space *space); + +__isl_give isl_space *isl_space_align_params(__isl_take isl_space *space1, + __isl_take isl_space *space2); + +__isl_export +isl_bool isl_space_is_wrapping(__isl_keep isl_space *space); +isl_bool isl_space_domain_is_wrapping(__isl_keep isl_space *space); +isl_bool isl_space_range_is_wrapping(__isl_keep isl_space *space); +isl_bool isl_space_is_product(__isl_keep isl_space *space); +__isl_export +__isl_give isl_space *isl_space_wrap(__isl_take isl_space *space); +__isl_export +__isl_give isl_space *isl_space_unwrap(__isl_take isl_space *space); + +isl_bool isl_space_can_zip(__isl_keep isl_space *space); +__isl_give isl_space *isl_space_zip(__isl_take isl_space *space); + +isl_bool isl_space_can_curry(__isl_keep isl_space *space); +__isl_export +__isl_give isl_space *isl_space_curry(__isl_take isl_space *space); + +isl_bool isl_space_can_range_curry(__isl_keep isl_space *space); +__isl_give isl_space *isl_space_range_curry(__isl_take isl_space *space); + +isl_bool isl_space_can_uncurry(__isl_keep isl_space *space); +__isl_export +__isl_give isl_space *isl_space_uncurry(__isl_take isl_space *space); + +isl_bool isl_space_is_domain(__isl_keep isl_space *space1, + __isl_keep isl_space *space2); +isl_bool isl_space_is_range(__isl_keep isl_space *space1, + __isl_keep isl_space *space2); +__isl_export +isl_bool isl_space_is_equal(__isl_keep isl_space *space1, + __isl_keep isl_space *space2); +isl_bool isl_space_has_equal_params(__isl_keep isl_space *space1, + __isl_keep isl_space *space2); +isl_bool isl_space_has_equal_tuples(__isl_keep isl_space *space1, + __isl_keep isl_space *space2); +isl_bool isl_space_tuple_is_equal(__isl_keep isl_space *space1, + enum isl_dim_type type1, __isl_keep isl_space *space2, + enum isl_dim_type type2); +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_size isl_space_dim(__isl_keep isl_space *space, enum isl_dim_type type); + +__isl_export +__isl_give isl_space *isl_space_flatten_domain(__isl_take isl_space *space); +__isl_export +__isl_give isl_space *isl_space_flatten_range(__isl_take isl_space *space); + +__isl_constructor +__isl_give isl_space *isl_space_read_from_str(isl_ctx *ctx, + const char *str); +__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 *space); +void isl_space_dump(__isl_keep isl_space *space); + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/external/mit/isl/dist/include/isl/space_type.h b/external/mit/isl/dist/include/isl/space_type.h new file mode 100644 index 000000000000..60c31b0d21d8 --- /dev/null +++ b/external/mit/isl/dist/include/isl/space_type.h @@ -0,0 +1,27 @@ +#ifndef ISL_SPACE_TYPE_H +#define ISL_SPACE_TYPE_H + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +struct __isl_export isl_space; +typedef struct isl_space isl_space; + +enum isl_dim_type { + isl_dim_cst, + isl_dim_param, + isl_dim_in, + isl_dim_out, + isl_dim_set = isl_dim_out, + isl_dim_div, + isl_dim_all +}; + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/external/mit/isl/dist/include/isl/stream.h b/external/mit/isl/dist/include/isl/stream.h new file mode 100644 index 000000000000..3242de2665be --- /dev/null +++ b/external/mit/isl/dist/include/isl/stream.h @@ -0,0 +1,102 @@ +/* + * 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_STREAM_H +#define ISL_STREAM_H + +#include +#include +#include +#include +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +enum isl_token_type { ISL_TOKEN_ERROR = -1, + ISL_TOKEN_UNKNOWN = 256, ISL_TOKEN_VALUE, + ISL_TOKEN_IDENT, ISL_TOKEN_GE, + ISL_TOKEN_LE, ISL_TOKEN_GT, ISL_TOKEN_LT, + ISL_TOKEN_NE, ISL_TOKEN_EQ_EQ, + ISL_TOKEN_LEX_GE, ISL_TOKEN_LEX_LE, + ISL_TOKEN_LEX_GT, ISL_TOKEN_LEX_LT, + ISL_TOKEN_TO, ISL_TOKEN_AND, + ISL_TOKEN_OR, ISL_TOKEN_EXISTS, ISL_TOKEN_NOT, + ISL_TOKEN_DEF, ISL_TOKEN_INFTY, ISL_TOKEN_NAN, + ISL_TOKEN_MIN, ISL_TOKEN_MAX, ISL_TOKEN_RAT, + ISL_TOKEN_TRUE, ISL_TOKEN_FALSE, + ISL_TOKEN_CEILD, ISL_TOKEN_FLOORD, ISL_TOKEN_MOD, + ISL_TOKEN_STRING, + ISL_TOKEN_MAP, ISL_TOKEN_AFF, + ISL_TOKEN_CEIL, ISL_TOKEN_FLOOR, + ISL_TOKEN_IMPLIES, + ISL_TOKEN_INT_DIV, + ISL_TOKEN_LAST }; + +struct isl_token; + +__isl_give isl_val *isl_token_get_val(isl_ctx *ctx, struct isl_token *tok); +isl_bool isl_token_has_str(struct isl_token *tok); +__isl_give char *isl_token_get_str(isl_ctx *ctx, struct isl_token *tok); +int isl_token_get_type(struct isl_token *tok); +void isl_token_free(struct isl_token *tok); + +struct isl_stream; +typedef struct isl_stream isl_stream; + +__isl_give isl_stream *isl_stream_new_file(isl_ctx *ctx, FILE *file); +__isl_give isl_stream *isl_stream_new_str(isl_ctx *ctx, const char *str); +void isl_stream_free(__isl_take isl_stream *s); + +isl_ctx *isl_stream_get_ctx(__isl_keep isl_stream *s); + +void isl_stream_error(__isl_keep isl_stream *s, struct isl_token *tok, + char *msg); + +struct isl_token *isl_stream_next_token(__isl_keep isl_stream *s); +struct isl_token *isl_stream_next_token_on_same_line(__isl_keep isl_stream *s); +int isl_stream_next_token_is(__isl_keep isl_stream *s, int type); +void isl_stream_push_token(__isl_keep isl_stream *s, struct isl_token *tok); +void isl_stream_flush_tokens(__isl_keep isl_stream *s); +int isl_stream_eat_if_available(__isl_keep isl_stream *s, int type); +char *isl_stream_read_ident_if_available(__isl_keep isl_stream *s); +int isl_stream_eat(__isl_keep isl_stream *s, int type); +int isl_stream_is_empty(__isl_keep isl_stream *s); +int isl_stream_skip_line(__isl_keep isl_stream *s); + +enum isl_token_type isl_stream_register_keyword(__isl_keep isl_stream *s, + const char *name); + +struct isl_obj isl_stream_read_obj(__isl_keep isl_stream *s); +__isl_give isl_id *isl_stream_read_id(__isl_keep isl_stream *s); +__isl_give isl_val *isl_stream_read_val(__isl_keep isl_stream *s); +__isl_give isl_multi_val *isl_stream_read_multi_val(__isl_keep isl_stream *s); +__isl_give isl_multi_aff *isl_stream_read_multi_aff(__isl_keep isl_stream *s); +__isl_give isl_map *isl_stream_read_map(__isl_keep isl_stream *s); +__isl_give isl_set *isl_stream_read_set(__isl_keep isl_stream *s); +__isl_give isl_basic_set *isl_stream_read_basic_set(__isl_keep isl_stream *s); +__isl_give isl_pw_qpolynomial *isl_stream_read_pw_qpolynomial( + __isl_keep isl_stream *s); +__isl_give isl_union_set *isl_stream_read_union_set(__isl_keep isl_stream *s); +__isl_give isl_union_map *isl_stream_read_union_map(__isl_keep isl_stream *s); +__isl_give isl_schedule *isl_stream_read_schedule(isl_stream *s); + +isl_stat isl_stream_yaml_read_start_mapping(__isl_keep isl_stream *s); +isl_stat isl_stream_yaml_read_end_mapping(__isl_keep isl_stream *s); +isl_stat isl_stream_yaml_read_start_sequence(__isl_keep isl_stream *s); +isl_stat isl_stream_yaml_read_end_sequence(__isl_keep isl_stream *s); +isl_bool isl_stream_yaml_next(__isl_keep isl_stream *s); + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/external/mit/isl/dist/include/isl/stride_info.h b/external/mit/isl/dist/include/isl/stride_info.h new file mode 100644 index 000000000000..533eb6850957 --- /dev/null +++ b/external/mit/isl/dist/include/isl/stride_info.h @@ -0,0 +1,30 @@ +/* + * Use of this software is governed by the MIT license + */ + +#ifndef ISL_STRIDE_INFO_H +#define ISL_STRIDE_INFO_H + +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +struct isl_stride_info; +typedef struct isl_stride_info isl_stride_info; + +isl_ctx *isl_stride_info_get_ctx(__isl_keep isl_stride_info *si); +__isl_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_stride_info_copy( + __isl_keep isl_stride_info *si); + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/external/mit/isl/dist/include/isl/typed_cpp.h b/external/mit/isl/dist/include/isl/typed_cpp.h new file mode 100644 index 000000000000..7186e41df3dd --- /dev/null +++ b/external/mit/isl/dist/include/isl/typed_cpp.h @@ -0,0 +1,52664 @@ +/// These are automatically generated templated 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_TYPED_CPP +#define ISL_TYPED_CPP + +#include + +#include + +namespace isl { +namespace typed { + +template +struct pair {}; + +struct Anonymous; + + +template +struct aff; + +template +using aff_on = aff; + +template +struct aff_list; + +template +using aff_list_on = aff_list; + +template +struct basic_map; + +template +struct basic_set; + +template +struct fixed_box; + +template +struct id; + +template +struct id_list; + +template +struct map; + +template +struct map_list; + +template +struct multi_aff; + +template +struct multi_id; + +template +struct multi_pw_aff; + +template +struct multi_union_pw_aff; + +template +struct multi_val; + +template +struct point; + +template +struct pw_aff; + +template +using pw_aff_on = pw_aff; + +template +struct pw_aff_list; + +template +using pw_aff_list_on = pw_aff_list; + +template +struct pw_multi_aff; + +template +struct pw_multi_aff_list; + +template +struct set; + +template +struct set_list; + +template +struct space; + +template +struct union_map; + +template +struct union_pw_aff; + +template +using union_pw_aff_on = union_pw_aff; + +template +struct union_pw_aff_list; + +template +using union_pw_aff_list_on = union_pw_aff_list; + +template +struct union_pw_multi_aff; + +template +struct union_set; + +template +struct union_set_list; + +template +struct val; + +template +struct val_list; + +template <> +struct aff : public isl::aff { + template + friend struct aff; + template + friend struct aff_list; + template + friend struct basic_map; + template + friend struct basic_set; + template + friend struct fixed_box; + template + friend struct id; + template + friend struct id_list; + template + friend struct map; + template + friend struct map_list; + template + friend struct multi_aff; + template + friend struct multi_id; + template + friend struct multi_pw_aff; + template + friend struct multi_union_pw_aff; + template + friend struct multi_val; + template + friend struct point; + template + friend struct pw_aff; + template + friend struct pw_aff_list; + template + friend struct pw_multi_aff; + template + friend struct pw_multi_aff_list; + template + friend struct set; + template + friend struct set_list; + template + friend struct space; + template + friend struct union_map; + template + friend struct union_pw_aff; + template + friend struct union_pw_aff_list; + template + friend struct union_pw_multi_aff; + template + friend struct union_set; + template + friend struct union_set_list; + template + friend struct val; + template + friend struct val_list; + + aff() = default; + aff(const isl::aff &obj) : isl::aff(obj) {} + static aff from(const isl::aff &obj) { + return aff(obj); + } + inline explicit aff(const isl::ctx &ctx, const std::string &str); + inline typed::aff add(const typed::aff &aff2) const; + inline typed::multi_aff add(const typed::multi_aff &multi2) const; + inline typed::multi_pw_aff add(const typed::multi_pw_aff &multi2) const; + inline typed::multi_union_pw_aff add(const typed::multi_union_pw_aff &multi2) const; + inline typed::pw_aff add(const typed::pw_aff &pwaff2) const; + inline typed::pw_multi_aff add(const typed::pw_multi_aff &pma2) const; + inline typed::union_pw_aff add(const typed::union_pw_aff &upa2) const; + inline typed::union_pw_multi_aff add(const typed::union_pw_multi_aff &upma2) const; + inline typed::aff add_constant(const typed::val &v) const; + inline typed::aff add_constant(long v) const; + inline typed::multi_aff add_constant(const typed::multi_val &mv) const; + template + inline typed::union_pw_multi_aff apply(const typed::union_pw_multi_aff &upma2) const; + inline typed::aff as_aff() const; + inline typed::map as_map() const = delete; + inline typed::multi_aff as_multi_aff() const; + inline typed::multi_union_pw_aff as_multi_union_pw_aff() const; + inline typed::pw_multi_aff as_pw_multi_aff() const; + inline typed::set as_set() const; + inline typed::union_map as_union_map() const = delete; + inline typed::aff at(int pos) const; + inline typed::basic_set<> bind(const typed::id &id) const; + inline typed::basic_set<> bind(const std::string &id) const; + inline typed::basic_set<> bind(const typed::multi_id &tuple) const; + inline typed::pw_aff bind_domain(const typed::multi_id<> &tuple) const = delete; + inline typed::pw_aff bind_domain_wrapped_domain(const typed::multi_id<> &tuple) const = delete; + inline typed::aff ceil() const; + inline typed::pw_aff coalesce() const; + inline typed::pw_aff cond(const typed::pw_aff &pwaff_true, const typed::pw_aff &pwaff_false) const; + inline typed::multi_val constant_multi_val() const; + inline typed::val constant_val() const; + inline typed::val get_constant_val() const = delete; + inline typed::set<> domain() const; + inline typed::aff domain_reverse() const = delete; + inline typed::pw_aff drop_unused_params() const; + inline typed::pw_multi_aff extract_pw_multi_aff(const typed::space &space) const; + inline typed::aff floor() const; + inline typed::set ge_set(const typed::aff<> &aff2) const = delete; + inline typed::set ge_set(const typed::pw_aff<> &pwaff2) const = delete; + inline typed::aff gist(const typed::set<> &context) const; + inline typed::union_pw_aff gist(const typed::union_set<> &context) const; + inline typed::aff gist(const typed::basic_set<> &context) const; + inline typed::aff gist(const typed::point<> &context) const; + inline typed::aff gist_params(const typed::set<> &context) const; + inline typed::aff gist_params(const typed::basic_set<> &context) const; + inline typed::aff gist_params(const typed::point<> &context) const; + inline typed::set gt_set(const typed::aff<> &aff2) const = delete; + inline typed::set gt_set(const typed::pw_aff<> &pwaff2) const = delete; + inline typed::multi_aff identity() const; + template + inline typed::pw_aff insert_domain(const typed::space &domain) const; + inline typed::pw_aff intersect_domain(const typed::set<> &set) const = delete; + inline typed::union_pw_aff intersect_domain(const typed::space<> &space) const = delete; + inline typed::union_pw_aff intersect_domain(const typed::union_set<> &uset) const = delete; + inline typed::union_pw_aff intersect_domain_wrapped_domain(const typed::union_set<> &uset) const = delete; + inline typed::pw_aff intersect_params(const typed::set<> &set) const; + inline typed::set le_set(const typed::aff<> &aff2) const = delete; + inline typed::set le_set(const typed::pw_aff<> &pwaff2) const = delete; + inline typed::aff_list list() const; + inline typed::set lt_set(const typed::aff<> &aff2) const = delete; + inline typed::set lt_set(const typed::pw_aff<> &pwaff2) const = delete; + inline typed::multi_pw_aff max(const typed::multi_pw_aff &multi2) const; + inline typed::pw_aff max(const typed::pw_aff &pwaff2) const; + inline typed::multi_val max_multi_val() const; + inline typed::val max_val() const; + inline typed::multi_pw_aff min(const typed::multi_pw_aff &multi2) const; + inline typed::pw_aff min(const typed::pw_aff &pwaff2) const; + inline typed::multi_val min_multi_val() const; + inline typed::val min_val() const; + inline typed::aff mod(const typed::val &mod) const; + inline typed::aff mod(long mod) const; + inline typed::aff neg() const; + inline typed::set<> params() const; + inline typed::pw_multi_aff preimage_domain_wrapped_domain(const typed::pw_multi_aff<> &pma2) const = delete; + inline typed::union_pw_multi_aff preimage_domain_wrapped_domain(const typed::union_pw_multi_aff<> &upma2) const = delete; + template + inline typed::multi_aff> product(const typed::multi_aff &multi2) const; + template + inline typed::multi_pw_aff> product(const typed::multi_pw_aff &multi2) const; + template + inline typed::pw_multi_aff> product(const typed::pw_multi_aff &pma2) const; + inline typed::aff pullback(const typed::multi_aff<> &ma) const = delete; + inline typed::pw_aff pullback(const typed::multi_pw_aff<> &mpa) const = delete; + inline typed::pw_aff pullback(const typed::pw_multi_aff<> &pma) const = delete; + inline typed::union_pw_aff pullback(const typed::union_pw_multi_aff<> &upma) const = delete; + inline typed::aff pullback(const typed::aff<> &ma) const = delete; + inline typed::pw_multi_aff_list pw_multi_aff_list() const; + inline typed::pw_multi_aff range_factor_domain() const = delete; + inline typed::pw_multi_aff range_factor_range() const = delete; + inline typed::multi_aff range_product(const typed::multi_aff<> &multi2) const = delete; + inline typed::multi_pw_aff range_product(const typed::multi_pw_aff<> &multi2) const = delete; + inline typed::multi_union_pw_aff range_product(const typed::multi_union_pw_aff<> &multi2) const = delete; + inline typed::pw_multi_aff range_product(const typed::pw_multi_aff<> &pma2) const = delete; + inline typed::union_pw_multi_aff range_product(const typed::union_pw_multi_aff<> &upma2) const = delete; + inline typed::aff scale(const typed::val &v) const; + inline typed::aff scale(long v) const; + inline typed::multi_aff scale(const typed::multi_val &mv) const; + inline typed::aff scale_down(const typed::val &v) const; + inline typed::aff scale_down(long v) const; + inline typed::multi_aff scale_down(const typed::multi_val &mv) const; + inline typed::multi_aff set_at(int pos, const typed::aff &el) const; + inline typed::multi_pw_aff set_at(int pos, const typed::pw_aff &el) const; + inline typed::multi_union_pw_aff set_at(int pos, const typed::union_pw_aff &el) const; + template + inline typed::multi_aff set_range_tuple(const typed::id &id) const; + template + inline typed::multi_aff set_range_tuple(const std::string &id) const; + inline typed::space space() const; + inline typed::aff sub(const typed::aff &aff2) const; + inline typed::multi_aff sub(const typed::multi_aff &multi2) const; + inline typed::multi_pw_aff sub(const typed::multi_pw_aff &multi2) const; + inline typed::multi_union_pw_aff sub(const typed::multi_union_pw_aff &multi2) const; + inline typed::pw_aff sub(const typed::pw_aff &pwaff2) const; + inline typed::pw_multi_aff sub(const typed::pw_multi_aff &pma2) const; + inline typed::union_pw_aff sub(const typed::union_pw_aff &upa2) const; + inline typed::union_pw_multi_aff sub(const typed::union_pw_multi_aff &upma2) const; + inline typed::pw_aff subtract_domain(const typed::set<> &set) const = delete; + inline typed::union_pw_aff subtract_domain(const typed::space<> &space) const = delete; + inline typed::union_pw_aff subtract_domain(const typed::union_set<> &uset) const = delete; + inline typed::multi_pw_aff to_multi_pw_aff() const; + inline typed::multi_union_pw_aff to_multi_union_pw_aff() const; + inline typed::pw_multi_aff to_pw_multi_aff() const; + inline typed::union_pw_aff to_union_pw_aff() const; + inline typed::union_pw_multi_aff to_union_pw_multi_aff() const; + template + inline typed::aff unbind_params_insert_domain(const typed::multi_id &domain) const; + inline typed::multi_pw_aff union_add(const typed::multi_pw_aff &mpa2) const; + inline typed::multi_union_pw_aff union_add(const typed::multi_union_pw_aff &mupa2) const; + inline typed::pw_aff union_add(const typed::pw_aff &pwaff2) const; + inline typed::pw_multi_aff union_add(const typed::pw_multi_aff &pma2) const; + inline typed::union_pw_aff union_add(const typed::union_pw_aff &upa2) const; + inline typed::union_pw_multi_aff union_add(const typed::union_pw_multi_aff &upma2) const; +}; + +template +struct aff : public isl::aff { + template + friend struct aff; + template + friend struct aff_list; + template + friend struct basic_map; + template + friend struct basic_set; + template + friend struct fixed_box; + template + friend struct id; + template + friend struct id_list; + template + friend struct map; + template + friend struct map_list; + template + friend struct multi_aff; + template + friend struct multi_id; + template + friend struct multi_pw_aff; + template + friend struct multi_union_pw_aff; + template + friend struct multi_val; + template + friend struct point; + template + friend struct pw_aff; + template + friend struct pw_aff_list; + template + friend struct pw_multi_aff; + template + friend struct pw_multi_aff_list; + template + friend struct set; + template + friend struct set_list; + template + friend struct space; + template + friend struct union_map; + template + friend struct union_pw_aff; + template + friend struct union_pw_aff_list; + template + friend struct union_pw_multi_aff; + template + friend struct union_set; + template + friend struct union_set_list; + template + friend struct val; + template + friend struct val_list; + + aff() = default; + template {}, + bool>::type = true> + aff(const aff &obj) : isl::aff(obj) {} + private: + template {}, bool>::type = true> + aff(const base &obj) : isl::aff(obj) {} + public: + static aff from(const isl::aff &obj) { + return aff(obj); + } + inline explicit aff(const isl::ctx &ctx, const std::string &str); + inline typed::aff add(const typed::aff &aff2) const; + inline typed::multi_aff add(const typed::multi_aff &multi2) const; + inline typed::multi_pw_aff add(const typed::multi_pw_aff &multi2) const; + inline typed::multi_union_pw_aff add(const typed::multi_union_pw_aff &multi2) const; + inline typed::pw_aff add(const typed::pw_aff &pwaff2) const; + inline typed::pw_multi_aff add(const typed::pw_multi_aff &pma2) const; + inline typed::union_pw_aff add(const typed::union_pw_aff &upa2) const; + inline typed::union_pw_multi_aff add(const typed::union_pw_multi_aff &upma2) const; + inline typed::aff add_constant(const typed::val &v) const; + inline typed::aff add_constant(long v) const; + inline typed::multi_aff add_constant(const typed::multi_val &mv) const; + template + inline typed::union_pw_multi_aff apply(const typed::union_pw_multi_aff &upma2) const; + inline typed::aff as_aff() const; + inline typed::map as_map() const; + inline typed::multi_aff as_multi_aff() const; + inline typed::multi_union_pw_aff as_multi_union_pw_aff() const; + inline typed::pw_multi_aff as_pw_multi_aff() const; + inline typed::set as_set() const = delete; + inline typed::union_map as_union_map() const; + inline typed::aff at(int pos) const; + inline typed::basic_set bind(const typed::id &id) const; + inline typed::basic_set bind(const std::string &id) const; + inline typed::basic_set bind(const typed::multi_id &tuple) const; + inline typed::pw_aff bind_domain(const typed::multi_id &tuple) const; + inline typed::pw_aff bind_domain_wrapped_domain(const typed::multi_id<> &tuple) const = delete; + inline typed::aff ceil() const; + inline typed::pw_aff coalesce() const; + inline typed::pw_aff cond(const typed::pw_aff &pwaff_true, const typed::pw_aff &pwaff_false) const; + inline typed::multi_val constant_multi_val() const; + inline typed::val constant_val() const; + inline typed::val get_constant_val() const = delete; + inline typed::set domain() const; + inline typed::aff domain_reverse() const = delete; + inline typed::pw_aff drop_unused_params() const; + inline typed::pw_multi_aff extract_pw_multi_aff(const typed::space &space) const; + inline typed::aff floor() const; + inline typed::set ge_set(const typed::aff &aff2) const; + inline typed::set ge_set(const typed::pw_aff &pwaff2) const; + inline typed::aff gist(const typed::set &context) const; + inline typed::union_pw_aff gist(const typed::union_set &context) const; + inline typed::aff gist(const typed::basic_set &context) const; + inline typed::aff gist(const typed::point &context) const; + inline typed::aff gist_params(const typed::set<> &context) const; + inline typed::aff gist_params(const typed::basic_set<> &context) const; + inline typed::aff gist_params(const typed::point<> &context) const; + inline typed::set gt_set(const typed::aff &aff2) const; + inline typed::set gt_set(const typed::pw_aff &pwaff2) const; + inline typed::multi_aff identity() const; + inline typed::pw_aff insert_domain(const typed::space<> &domain) const = delete; + inline typed::pw_aff intersect_domain(const typed::set &set) const; + inline typed::union_pw_aff intersect_domain(const typed::space &space) const; + inline typed::union_pw_aff intersect_domain(const typed::union_set &uset) const; + inline typed::union_pw_aff intersect_domain_wrapped_domain(const typed::union_set<> &uset) const = delete; + inline typed::pw_aff intersect_params(const typed::set<> &set) const; + inline typed::set le_set(const typed::aff &aff2) const; + inline typed::set le_set(const typed::pw_aff &pwaff2) const; + inline typed::aff_list list() const; + inline typed::set lt_set(const typed::aff &aff2) const; + inline typed::set lt_set(const typed::pw_aff &pwaff2) const; + inline typed::multi_pw_aff max(const typed::multi_pw_aff &multi2) const; + inline typed::pw_aff max(const typed::pw_aff &pwaff2) const; + inline typed::multi_val max_multi_val() const; + inline typed::val max_val() const; + inline typed::multi_pw_aff min(const typed::multi_pw_aff &multi2) const; + inline typed::pw_aff min(const typed::pw_aff &pwaff2) const; + inline typed::multi_val min_multi_val() const; + inline typed::val min_val() const; + inline typed::aff mod(const typed::val &mod) const; + inline typed::aff mod(long mod) const; + inline typed::aff neg() const; + inline typed::set<> params() const; + inline typed::pw_multi_aff preimage_domain_wrapped_domain(const typed::pw_multi_aff<> &pma2) const = delete; + inline typed::union_pw_multi_aff preimage_domain_wrapped_domain(const typed::union_pw_multi_aff<> &upma2) const = delete; + template + inline typed::multi_aff, pair> product(const typed::multi_aff &multi2) const; + template + inline typed::multi_pw_aff, pair> product(const typed::multi_pw_aff &multi2) const; + template + inline typed::pw_multi_aff, pair> product(const typed::pw_multi_aff &pma2) const; + template + inline typed::aff pullback(const typed::multi_aff &ma) const; + inline typed::aff pullback(const typed::multi_aff &ma) const; + template + inline typed::pw_aff pullback(const typed::multi_pw_aff &mpa) const; + inline typed::pw_aff pullback(const typed::multi_pw_aff &mpa) const; + template + inline typed::pw_aff pullback(const typed::pw_multi_aff &pma) const; + inline typed::pw_aff pullback(const typed::pw_multi_aff &pma) const; + template + inline typed::union_pw_aff pullback(const typed::union_pw_multi_aff &upma) const; + inline typed::union_pw_aff pullback(const typed::union_pw_multi_aff &upma) const; + template + inline typed::aff pullback(const typed::aff &ma) const; + inline typed::aff pullback(const typed::aff &ma) const; + inline typed::pw_multi_aff_list pw_multi_aff_list() const; + inline typed::pw_multi_aff range_factor_domain() const = delete; + inline typed::pw_multi_aff range_factor_range() const = delete; + template + inline typed::multi_aff> range_product(const typed::multi_aff &multi2) const; + template + inline typed::multi_pw_aff> range_product(const typed::multi_pw_aff &multi2) const; + template + inline typed::multi_union_pw_aff> range_product(const typed::multi_union_pw_aff &multi2) const; + template + inline typed::pw_multi_aff> range_product(const typed::pw_multi_aff &pma2) const; + template + inline typed::union_pw_multi_aff> range_product(const typed::union_pw_multi_aff &upma2) const; + inline typed::aff scale(const typed::val &v) const; + inline typed::aff scale(long v) const; + inline typed::multi_aff scale(const typed::multi_val &mv) const; + inline typed::aff scale_down(const typed::val &v) const; + inline typed::aff scale_down(long v) const; + inline typed::multi_aff scale_down(const typed::multi_val &mv) const; + inline typed::multi_aff set_at(int pos, const typed::aff &el) const; + inline typed::multi_pw_aff set_at(int pos, const typed::pw_aff &el) const; + inline typed::multi_union_pw_aff set_at(int pos, const typed::union_pw_aff &el) const; + template + inline typed::multi_aff set_range_tuple(const typed::id &id) const; + template + inline typed::multi_aff set_range_tuple(const std::string &id) const; + inline typed::space space() const; + inline typed::aff sub(const typed::aff &aff2) const; + inline typed::multi_aff sub(const typed::multi_aff &multi2) const; + inline typed::multi_pw_aff sub(const typed::multi_pw_aff &multi2) const; + inline typed::multi_union_pw_aff sub(const typed::multi_union_pw_aff &multi2) const; + inline typed::pw_aff sub(const typed::pw_aff &pwaff2) const; + inline typed::pw_multi_aff sub(const typed::pw_multi_aff &pma2) const; + inline typed::union_pw_aff sub(const typed::union_pw_aff &upa2) const; + inline typed::union_pw_multi_aff sub(const typed::union_pw_multi_aff &upma2) const; + inline typed::pw_aff subtract_domain(const typed::set &set) const; + inline typed::union_pw_aff subtract_domain(const typed::space &space) const; + inline typed::union_pw_aff subtract_domain(const typed::union_set &uset) const; + inline typed::multi_pw_aff to_multi_pw_aff() const; + inline typed::multi_union_pw_aff to_multi_union_pw_aff() const; + inline typed::pw_multi_aff to_pw_multi_aff() const; + inline typed::union_pw_aff to_union_pw_aff() const; + inline typed::union_pw_multi_aff to_union_pw_multi_aff() const; + inline typed::aff unbind_params_insert_domain(const typed::multi_id<> &domain) const = delete; + inline typed::multi_pw_aff union_add(const typed::multi_pw_aff &mpa2) const; + inline typed::multi_union_pw_aff union_add(const typed::multi_union_pw_aff &mupa2) const; + inline typed::pw_aff union_add(const typed::pw_aff &pwaff2) const; + inline typed::pw_multi_aff union_add(const typed::pw_multi_aff &pma2) const; + inline typed::union_pw_aff union_add(const typed::union_pw_aff &upa2) const; + inline typed::union_pw_multi_aff union_add(const typed::union_pw_multi_aff &upma2) const; +}; + +template +struct aff, Anonymous> : public isl::aff { + template + friend struct aff; + template + friend struct aff_list; + template + friend struct basic_map; + template + friend struct basic_set; + template + friend struct fixed_box; + template + friend struct id; + template + friend struct id_list; + template + friend struct map; + template + friend struct map_list; + template + friend struct multi_aff; + template + friend struct multi_id; + template + friend struct multi_pw_aff; + template + friend struct multi_union_pw_aff; + template + friend struct multi_val; + template + friend struct point; + template + friend struct pw_aff; + template + friend struct pw_aff_list; + template + friend struct pw_multi_aff; + template + friend struct pw_multi_aff_list; + template + friend struct set; + template + friend struct set_list; + template + friend struct space; + template + friend struct union_map; + template + friend struct union_pw_aff; + template + friend struct union_pw_aff_list; + template + friend struct union_pw_multi_aff; + template + friend struct union_set; + template + friend struct union_set_list; + template + friend struct val; + template + friend struct val_list; + + aff() = default; + template {} && + std::is_base_of{}, + bool>::type = true> + aff(const aff, Anonymous> &obj) : isl::aff(obj) {} + private: + template {}, bool>::type = true> + aff(const base &obj) : isl::aff(obj) {} + public: + static aff from(const isl::aff &obj) { + return aff(obj); + } + inline explicit aff(const isl::ctx &ctx, const std::string &str); + inline typed::aff, Anonymous> add(const typed::aff, Anonymous> &aff2) const; + inline typed::multi_aff, Anonymous> add(const typed::multi_aff, Anonymous> &multi2) const; + inline typed::multi_pw_aff, Anonymous> add(const typed::multi_pw_aff, Anonymous> &multi2) const; + inline typed::multi_union_pw_aff, Anonymous> add(const typed::multi_union_pw_aff, Anonymous> &multi2) const; + inline typed::pw_aff, Anonymous> add(const typed::pw_aff, Anonymous> &pwaff2) const; + inline typed::pw_multi_aff, Anonymous> add(const typed::pw_multi_aff, Anonymous> &pma2) const; + inline typed::union_pw_aff, Anonymous> add(const typed::union_pw_aff, Anonymous> &upa2) const; + inline typed::union_pw_multi_aff, Anonymous> add(const typed::union_pw_multi_aff, Anonymous> &upma2) const; + inline typed::aff, Anonymous> add_constant(const typed::val &v) const; + inline typed::aff, Anonymous> add_constant(long v) const; + inline typed::multi_aff, Anonymous> add_constant(const typed::multi_val &mv) const; + template + inline typed::union_pw_multi_aff, Arg1> apply(const typed::union_pw_multi_aff &upma2) const; + inline typed::aff, Anonymous> as_aff() const; + inline typed::map, Anonymous> as_map() const; + inline typed::multi_aff, Anonymous> as_multi_aff() const; + inline typed::multi_union_pw_aff, Anonymous> as_multi_union_pw_aff() const; + inline typed::pw_multi_aff, Anonymous> as_pw_multi_aff() const; + inline typed::set, Anonymous> as_set() const = delete; + inline typed::union_map, Anonymous> as_union_map() const; + inline typed::aff, Anonymous> at(int pos) const; + inline typed::basic_set> bind(const typed::id &id) const; + inline typed::basic_set> bind(const std::string &id) const; + inline typed::basic_set> bind(const typed::multi_id &tuple) const; + inline typed::pw_aff bind_domain(const typed::multi_id> &tuple) const; + inline typed::pw_aff bind_domain_wrapped_domain(const typed::multi_id &tuple) const; + inline typed::aff, Anonymous> ceil() const; + inline typed::pw_aff, Anonymous> coalesce() const; + inline typed::pw_aff, Anonymous> cond(const typed::pw_aff, Anonymous> &pwaff_true, const typed::pw_aff, Anonymous> &pwaff_false) const; + inline typed::multi_val constant_multi_val() const; + inline typed::val constant_val() const; + inline typed::val, Anonymous> get_constant_val() const = delete; + inline typed::set> domain() const; + inline typed::aff, Anonymous> domain_reverse() const; + inline typed::pw_aff, Anonymous> drop_unused_params() const; + inline typed::pw_multi_aff, Anonymous> extract_pw_multi_aff(const typed::space, Anonymous> &space) const; + inline typed::aff, Anonymous> floor() const; + inline typed::set> ge_set(const typed::aff, Anonymous> &aff2) const; + inline typed::set> ge_set(const typed::pw_aff, Anonymous> &pwaff2) const; + inline typed::aff, Anonymous> gist(const typed::set> &context) const; + inline typed::union_pw_aff, Anonymous> gist(const typed::union_set> &context) const; + inline typed::aff, Anonymous> gist(const typed::basic_set> &context) const; + inline typed::aff, Anonymous> gist(const typed::point> &context) const; + inline typed::aff, Anonymous> gist_params(const typed::set<> &context) const; + inline typed::aff, Anonymous> gist_params(const typed::basic_set<> &context) const; + inline typed::aff, Anonymous> gist_params(const typed::point<> &context) const; + inline typed::set> gt_set(const typed::aff, Anonymous> &aff2) const; + inline typed::set> gt_set(const typed::pw_aff, Anonymous> &pwaff2) const; + inline typed::multi_aff, Anonymous> identity() const; + inline typed::pw_aff, Anonymous> insert_domain(const typed::space<> &domain) const = delete; + inline typed::pw_aff, Anonymous> intersect_domain(const typed::set> &set) const; + inline typed::union_pw_aff, Anonymous> intersect_domain(const typed::space> &space) const; + inline typed::union_pw_aff, Anonymous> intersect_domain(const typed::union_set> &uset) const; + inline typed::union_pw_aff, Anonymous> intersect_domain_wrapped_domain(const typed::union_set &uset) const; + inline typed::pw_aff, Anonymous> intersect_params(const typed::set<> &set) const; + inline typed::set> le_set(const typed::aff, Anonymous> &aff2) const; + inline typed::set> le_set(const typed::pw_aff, Anonymous> &pwaff2) const; + inline typed::aff_list, Anonymous> list() const; + inline typed::set> lt_set(const typed::aff, Anonymous> &aff2) const; + inline typed::set> lt_set(const typed::pw_aff, Anonymous> &pwaff2) const; + inline typed::multi_pw_aff, Anonymous> max(const typed::multi_pw_aff, Anonymous> &multi2) const; + inline typed::pw_aff, Anonymous> max(const typed::pw_aff, Anonymous> &pwaff2) const; + inline typed::multi_val max_multi_val() const; + inline typed::val max_val() const; + inline typed::multi_pw_aff, Anonymous> min(const typed::multi_pw_aff, Anonymous> &multi2) const; + inline typed::pw_aff, Anonymous> min(const typed::pw_aff, Anonymous> &pwaff2) const; + inline typed::multi_val min_multi_val() const; + inline typed::val min_val() const; + inline typed::aff, Anonymous> mod(const typed::val &mod) const; + inline typed::aff, Anonymous> mod(long mod) const; + inline typed::aff, Anonymous> neg() const; + inline typed::set<> params() const; + template + inline typed::pw_multi_aff, Anonymous> preimage_domain_wrapped_domain(const typed::pw_multi_aff &pma2) const; + template + inline typed::union_pw_multi_aff, Anonymous> preimage_domain_wrapped_domain(const typed::union_pw_multi_aff &upma2) const; + template + inline typed::multi_aff, Arg1>, pair> product(const typed::multi_aff &multi2) const; + template + inline typed::multi_pw_aff, Arg1>, pair> product(const typed::multi_pw_aff &multi2) const; + template + inline typed::pw_multi_aff, Arg1>, pair> product(const typed::pw_multi_aff &pma2) const; + template + inline typed::aff pullback(const typed::multi_aff> &ma) const; + inline typed::aff pullback(const typed::multi_aff> &ma) const; + template + inline typed::pw_aff pullback(const typed::multi_pw_aff> &mpa) const; + inline typed::pw_aff pullback(const typed::multi_pw_aff> &mpa) const; + template + inline typed::pw_aff pullback(const typed::pw_multi_aff> &pma) const; + inline typed::pw_aff pullback(const typed::pw_multi_aff> &pma) const; + template + inline typed::union_pw_aff pullback(const typed::union_pw_multi_aff> &upma) const; + inline typed::union_pw_aff pullback(const typed::union_pw_multi_aff> &upma) const; + template + inline typed::aff pullback(const typed::aff> &ma) const; + inline typed::aff pullback(const typed::aff> &ma) const; + inline typed::pw_multi_aff_list, Anonymous> pw_multi_aff_list() const; + inline typed::pw_multi_aff, Anonymous> range_factor_domain() const = delete; + inline typed::pw_multi_aff, Anonymous> range_factor_range() const = delete; + template + inline typed::multi_aff, pair> range_product(const typed::multi_aff, Arg1> &multi2) const; + template + inline typed::multi_pw_aff, pair> range_product(const typed::multi_pw_aff, Arg1> &multi2) const; + template + inline typed::multi_union_pw_aff, pair> range_product(const typed::multi_union_pw_aff, Arg1> &multi2) const; + template + inline typed::pw_multi_aff, pair> range_product(const typed::pw_multi_aff, Arg1> &pma2) const; + template + inline typed::union_pw_multi_aff, pair> range_product(const typed::union_pw_multi_aff, Arg1> &upma2) const; + inline typed::aff, Anonymous> scale(const typed::val &v) const; + inline typed::aff, Anonymous> scale(long v) const; + inline typed::multi_aff, Anonymous> scale(const typed::multi_val &mv) const; + inline typed::aff, Anonymous> scale_down(const typed::val &v) const; + inline typed::aff, Anonymous> scale_down(long v) const; + inline typed::multi_aff, Anonymous> scale_down(const typed::multi_val &mv) const; + inline typed::multi_aff, Anonymous> set_at(int pos, const typed::aff, Anonymous> &el) const; + inline typed::multi_pw_aff, Anonymous> set_at(int pos, const typed::pw_aff, Anonymous> &el) const; + inline typed::multi_union_pw_aff, Anonymous> set_at(int pos, const typed::union_pw_aff, Anonymous> &el) const; + template + inline typed::multi_aff, Arg1> set_range_tuple(const typed::id &id) const; + template + inline typed::multi_aff, Arg1> set_range_tuple(const std::string &id) const; + inline typed::space, Anonymous> space() const; + inline typed::aff, Anonymous> sub(const typed::aff, Anonymous> &aff2) const; + inline typed::multi_aff, Anonymous> sub(const typed::multi_aff, Anonymous> &multi2) const; + inline typed::multi_pw_aff, Anonymous> sub(const typed::multi_pw_aff, Anonymous> &multi2) const; + inline typed::multi_union_pw_aff, Anonymous> sub(const typed::multi_union_pw_aff, Anonymous> &multi2) const; + inline typed::pw_aff, Anonymous> sub(const typed::pw_aff, Anonymous> &pwaff2) const; + inline typed::pw_multi_aff, Anonymous> sub(const typed::pw_multi_aff, Anonymous> &pma2) const; + inline typed::union_pw_aff, Anonymous> sub(const typed::union_pw_aff, Anonymous> &upa2) const; + inline typed::union_pw_multi_aff, Anonymous> sub(const typed::union_pw_multi_aff, Anonymous> &upma2) const; + inline typed::pw_aff, Anonymous> subtract_domain(const typed::set> &set) const; + inline typed::union_pw_aff, Anonymous> subtract_domain(const typed::space> &space) const; + inline typed::union_pw_aff, Anonymous> subtract_domain(const typed::union_set> &uset) const; + inline typed::multi_pw_aff, Anonymous> to_multi_pw_aff() const; + inline typed::multi_union_pw_aff, Anonymous> to_multi_union_pw_aff() const; + inline typed::pw_multi_aff, Anonymous> to_pw_multi_aff() const; + inline typed::union_pw_aff, Anonymous> to_union_pw_aff() const; + inline typed::union_pw_multi_aff, Anonymous> to_union_pw_multi_aff() const; + inline typed::aff, Anonymous> unbind_params_insert_domain(const typed::multi_id<> &domain) const = delete; + inline typed::multi_pw_aff, Anonymous> union_add(const typed::multi_pw_aff, Anonymous> &mpa2) const; + inline typed::multi_union_pw_aff, Anonymous> union_add(const typed::multi_union_pw_aff, Anonymous> &mupa2) const; + inline typed::pw_aff, Anonymous> union_add(const typed::pw_aff, Anonymous> &pwaff2) const; + inline typed::pw_multi_aff, Anonymous> union_add(const typed::pw_multi_aff, Anonymous> &pma2) const; + inline typed::union_pw_aff, Anonymous> union_add(const typed::union_pw_aff, Anonymous> &upa2) const; + inline typed::union_pw_multi_aff, Anonymous> union_add(const typed::union_pw_multi_aff, Anonymous> &upma2) const; +}; + +template <> +struct aff_list : public isl::aff_list { + template + friend struct aff; + template + friend struct aff_list; + template + friend struct basic_map; + template + friend struct basic_set; + template + friend struct fixed_box; + template + friend struct id; + template + friend struct id_list; + template + friend struct map; + template + friend struct map_list; + template + friend struct multi_aff; + template + friend struct multi_id; + template + friend struct multi_pw_aff; + template + friend struct multi_union_pw_aff; + template + friend struct multi_val; + template + friend struct point; + template + friend struct pw_aff; + template + friend struct pw_aff_list; + template + friend struct pw_multi_aff; + template + friend struct pw_multi_aff_list; + template + friend struct set; + template + friend struct set_list; + template + friend struct space; + template + friend struct union_map; + template + friend struct union_pw_aff; + template + friend struct union_pw_aff_list; + template + friend struct union_pw_multi_aff; + template + friend struct union_set; + template + friend struct union_set_list; + template + friend struct val; + template + friend struct val_list; + + aff_list() = default; + aff_list(const isl::aff_list &obj) : isl::aff_list(obj) {} + static aff_list from(const isl::aff_list &obj) { + return aff_list(obj); + } + inline explicit aff_list(const isl::ctx &ctx, int n); + inline explicit aff_list(const typed::aff &el); + inline explicit aff_list(const isl::ctx &ctx, const std::string &str); + inline typed::aff_list add(const typed::aff &el) const; + inline typed::aff at(int index) const; + inline typed::aff get_at(int index) const = delete; + inline typed::aff_list drop(unsigned int first, unsigned int n) const; + inline void foreach(const std::function)> &fn) const; + inline void foreach_scc(const std::function, typed::aff)> &follows, const std::function)> &fn) const; + inline typed::aff_list set_at(int index, const typed::aff &el) const; +}; + +template +struct aff_list : public isl::aff_list { + template + friend struct aff; + template + friend struct aff_list; + template + friend struct basic_map; + template + friend struct basic_set; + template + friend struct fixed_box; + template + friend struct id; + template + friend struct id_list; + template + friend struct map; + template + friend struct map_list; + template + friend struct multi_aff; + template + friend struct multi_id; + template + friend struct multi_pw_aff; + template + friend struct multi_union_pw_aff; + template + friend struct multi_val; + template + friend struct point; + template + friend struct pw_aff; + template + friend struct pw_aff_list; + template + friend struct pw_multi_aff; + template + friend struct pw_multi_aff_list; + template + friend struct set; + template + friend struct set_list; + template + friend struct space; + template + friend struct union_map; + template + friend struct union_pw_aff; + template + friend struct union_pw_aff_list; + template + friend struct union_pw_multi_aff; + template + friend struct union_set; + template + friend struct union_set_list; + template + friend struct val; + template + friend struct val_list; + + aff_list() = default; + template {}, + bool>::type = true> + aff_list(const aff_list &obj) : isl::aff_list(obj) {} + private: + template {}, bool>::type = true> + aff_list(const base &obj) : isl::aff_list(obj) {} + public: + static aff_list from(const isl::aff_list &obj) { + return aff_list(obj); + } + inline explicit aff_list(const isl::ctx &ctx, int n); + inline explicit aff_list(const typed::aff &el); + inline explicit aff_list(const isl::ctx &ctx, const std::string &str); + inline typed::aff_list add(const typed::aff &el) const; + inline typed::aff at(int index) const; + inline typed::aff get_at(int index) const = delete; + inline typed::aff_list drop(unsigned int first, unsigned int n) const; + inline void foreach(const std::function)> &fn) const; + inline void foreach_scc(const std::function, typed::aff)> &follows, const std::function)> &fn) const; + inline typed::aff_list set_at(int index, const typed::aff &el) const; +}; + +template +struct basic_map : public isl::basic_map { + template + friend struct aff; + template + friend struct aff_list; + template + friend struct basic_map; + template + friend struct basic_set; + template + friend struct fixed_box; + template + friend struct id; + template + friend struct id_list; + template + friend struct map; + template + friend struct map_list; + template + friend struct multi_aff; + template + friend struct multi_id; + template + friend struct multi_pw_aff; + template + friend struct multi_union_pw_aff; + template + friend struct multi_val; + template + friend struct point; + template + friend struct pw_aff; + template + friend struct pw_aff_list; + template + friend struct pw_multi_aff; + template + friend struct pw_multi_aff_list; + template + friend struct set; + template + friend struct set_list; + template + friend struct space; + template + friend struct union_map; + template + friend struct union_pw_aff; + template + friend struct union_pw_aff_list; + template + friend struct union_pw_multi_aff; + template + friend struct union_set; + template + friend struct union_set_list; + template + friend struct val; + template + friend struct val_list; + + basic_map() = default; + template {} && + std::is_base_of{}, + bool>::type = true> + basic_map(const basic_map &obj) : isl::basic_map(obj) {} + private: + template {}, bool>::type = true> + basic_map(const base &obj) : isl::basic_map(obj) {} + public: + static basic_map from(const isl::basic_map &obj) { + return basic_map(obj); + } + inline explicit basic_map(const isl::ctx &ctx, const std::string &str); + template + inline typed::basic_map apply_domain(const typed::basic_map &bmap2) const; + template + inline typed::map apply_domain(const typed::map &map2) const; + template + inline typed::union_map apply_domain(const typed::union_map &umap2) const; + template + inline typed::basic_map apply_range(const typed::basic_map &bmap2) const; + template + inline typed::map apply_range(const typed::map &map2) const; + template + inline typed::union_map apply_range(const typed::union_map &umap2) const; + inline typed::map as_map() const; + inline typed::multi_union_pw_aff as_multi_union_pw_aff() const; + inline typed::pw_multi_aff as_pw_multi_aff() const; + inline typed::union_pw_multi_aff as_union_pw_multi_aff() const; + inline typed::set bind_domain(const typed::multi_id &tuple) const; + inline typed::set bind_range(const typed::multi_id &tuple) const; + inline typed::map coalesce() const; + inline typed::map curry() const = delete; + inline typed::basic_set deltas() const = delete; + inline typed::basic_map detect_equalities() const; + inline typed::set domain() const; + inline typed::map domain_factor_domain() const = delete; + inline typed::map domain_factor_range() const = delete; + inline typed::union_map, Domain> domain_map() const; + inline typed::union_pw_multi_aff, Domain> domain_map_union_pw_multi_aff() const; + template + inline typed::map, Range> domain_product(const typed::map &map2) const; + template + inline typed::union_map, Range> domain_product(const typed::union_map &umap2) const; + inline typed::map domain_reverse() const = delete; + inline typed::map drop_unused_params() const; + inline typed::map eq_at(const typed::multi_pw_aff<> &mpa) const = delete; + inline typed::union_map eq_at(const typed::multi_union_pw_aff<> &mupa) const = delete; + inline bool every_map(const std::function)> &test) const; + inline typed::map extract_map(const typed::space &space) const; + inline typed::basic_map flatten_domain() const = delete; + inline typed::basic_map flatten_range() const = delete; + inline void foreach_basic_map(const std::function)> &fn) const; + inline void foreach_map(const std::function)> &fn) const; + inline typed::basic_map gist(const typed::basic_map &context) const; + inline typed::map gist(const typed::map &context) const; + inline typed::union_map gist(const typed::union_map &context) const; + inline typed::map gist_domain(const typed::set &context) const; + inline typed::union_map gist_domain(const typed::union_set &uset) const; + inline typed::map gist_params(const typed::set<> &context) const; + inline typed::basic_map intersect(const typed::basic_map &bmap2) const; + inline typed::map intersect(const typed::map &map2) const; + inline typed::union_map intersect(const typed::union_map &umap2) const; + inline typed::basic_map intersect_domain(const typed::basic_set &bset) const; + inline typed::map intersect_domain(const typed::set &set) const; + inline typed::union_map intersect_domain(const typed::space &space) const; + inline typed::union_map intersect_domain(const typed::union_set &uset) const; + inline typed::basic_map intersect_domain(const typed::point &bset) const; + inline typed::map intersect_domain_wrapped_domain(const typed::set<> &domain) const = delete; + inline typed::union_map intersect_domain_wrapped_domain(const typed::union_set<> &domain) const = delete; + inline typed::map intersect_params(const typed::set<> ¶ms) const; + inline typed::basic_map intersect_range(const typed::basic_set &bset) const; + inline typed::map intersect_range(const typed::set &set) const; + inline typed::union_map intersect_range(const typed::space &space) const; + inline typed::union_map intersect_range(const typed::union_set &uset) const; + inline typed::basic_map intersect_range(const typed::point &bset) const; + inline typed::map intersect_range_wrapped_domain(const typed::set<> &domain) const = delete; + inline typed::union_map intersect_range_wrapped_domain(const typed::union_set<> &domain) const = delete; + inline typed::map lex_ge_at(const typed::multi_pw_aff<> &mpa) const = delete; + inline typed::map lex_gt_at(const typed::multi_pw_aff<> &mpa) const = delete; + inline typed::map lex_le_at(const typed::multi_pw_aff<> &mpa) const = delete; + inline typed::map lex_lt_at(const typed::multi_pw_aff<> &mpa) const = delete; + inline typed::map lexmax() const; + inline typed::pw_multi_aff lexmax_pw_multi_aff() const; + inline typed::map lexmin() const; + inline typed::pw_multi_aff lexmin_pw_multi_aff() const; + inline typed::map lower_bound(const typed::multi_pw_aff &lower) const; + inline typed::map_list map_list() const; + inline typed::multi_pw_aff max_multi_pw_aff() const; + inline typed::multi_pw_aff min_multi_pw_aff() const; + inline typed::set<> params() const; + template + inline typed::map preimage_domain(const typed::multi_aff &ma) const; + template + inline typed::map preimage_domain(const typed::multi_pw_aff &mpa) const; + template + inline typed::map preimage_domain(const typed::pw_multi_aff &pma) const; + template + inline typed::union_map preimage_domain(const typed::union_pw_multi_aff &upma) const; + template + inline typed::map preimage_range(const typed::multi_aff &ma) const; + template + inline typed::map preimage_range(const typed::pw_multi_aff &pma) const; + template + inline typed::union_map preimage_range(const typed::union_pw_multi_aff &upma) const; + template + inline typed::map, pair> product(const typed::map &map2) const; + template + inline typed::union_map, pair> product(const typed::union_map &umap2) const; + inline typed::map project_out_all_params() const; + inline typed::map project_out_param(const typed::id &id) const; + inline typed::map project_out_param(const std::string &id) const; + inline typed::map project_out_param(const typed::id_list &list) const; + inline typed::set range() const; + inline typed::map range_factor_domain() const = delete; + inline typed::map range_factor_range() const = delete; + inline typed::fixed_box range_lattice_tile() const; + inline typed::union_map, Range> range_map() const; + template + inline typed::map> range_product(const typed::map &map2) const; + template + inline typed::union_map> range_product(const typed::union_map &umap2) const; + inline typed::map range_reverse() const = delete; + inline typed::fixed_box range_simple_fixed_box_hull() const; + inline typed::basic_map reverse() const; + template + inline typed::map set_domain_tuple(const typed::id &id) const; + template + inline typed::map set_domain_tuple(const std::string &id) const; + template + inline typed::map set_range_tuple(const typed::id &id) const; + template + inline typed::map set_range_tuple(const std::string &id) const; + inline typed::space space() const; + inline typed::map subtract(const typed::map &map2) const; + inline typed::union_map subtract(const typed::union_map &umap2) const; + inline typed::union_map subtract_domain(const typed::union_set &dom) const; + inline typed::union_map subtract_range(const typed::union_set &dom) const; + inline typed::union_map to_union_map() const; + inline typed::map uncurry() const = delete; + inline typed::map unite(const typed::basic_map &bmap2) const; + inline typed::map unite(const typed::map &map2) const; + inline typed::union_map unite(const typed::union_map &umap2) const; + inline typed::map upper_bound(const typed::multi_pw_aff &upper) const; + inline typed::set> wrap() const; +}; + +template +struct basic_map, Range2> : public isl::basic_map { + template + friend struct aff; + template + friend struct aff_list; + template + friend struct basic_map; + template + friend struct basic_set; + template + friend struct fixed_box; + template + friend struct id; + template + friend struct id_list; + template + friend struct map; + template + friend struct map_list; + template + friend struct multi_aff; + template + friend struct multi_id; + template + friend struct multi_pw_aff; + template + friend struct multi_union_pw_aff; + template + friend struct multi_val; + template + friend struct point; + template + friend struct pw_aff; + template + friend struct pw_aff_list; + template + friend struct pw_multi_aff; + template + friend struct pw_multi_aff_list; + template + friend struct set; + template + friend struct set_list; + template + friend struct space; + template + friend struct union_map; + template + friend struct union_pw_aff; + template + friend struct union_pw_aff_list; + template + friend struct union_pw_multi_aff; + template + friend struct union_set; + template + friend struct union_set_list; + template + friend struct val; + template + friend struct val_list; + + basic_map() = default; + template {} && + std::is_base_of{} && + std::is_base_of{}, + bool>::type = true> + basic_map(const basic_map, Arg3> &obj) : isl::basic_map(obj) {} + private: + template {}, bool>::type = true> + basic_map(const base &obj) : isl::basic_map(obj) {} + public: + static basic_map from(const isl::basic_map &obj) { + return basic_map(obj); + } + inline explicit basic_map(const isl::ctx &ctx, const std::string &str); + template + inline typed::basic_map apply_domain(const typed::basic_map, Domain2> &bmap2) const; + template + inline typed::map apply_domain(const typed::map, Domain2> &map2) const; + template + inline typed::union_map apply_domain(const typed::union_map, Domain2> &umap2) const; + template + inline typed::basic_map, Arg3> apply_range(const typed::basic_map &bmap2) const; + template + inline typed::map, Arg3> apply_range(const typed::map &map2) const; + template + inline typed::union_map, Arg3> apply_range(const typed::union_map &umap2) const; + inline typed::map, Range2> as_map() const; + inline typed::multi_union_pw_aff, Range2> as_multi_union_pw_aff() const; + inline typed::pw_multi_aff, Range2> as_pw_multi_aff() const; + inline typed::union_pw_multi_aff, Range2> as_union_pw_multi_aff() const; + inline typed::set bind_domain(const typed::multi_id> &tuple) const; + inline typed::set> bind_range(const typed::multi_id &tuple) const; + inline typed::map, Range2> coalesce() const; + inline typed::map> curry() const; + inline typed::basic_set, Range2> deltas() const = delete; + inline typed::basic_map, Range2> detect_equalities() const; + inline typed::set> domain() const; + inline typed::map domain_factor_domain() const; + inline typed::map domain_factor_range() const; + inline typed::union_map, Range2>, pair> domain_map() const; + inline typed::union_pw_multi_aff, Range2>, pair> domain_map_union_pw_multi_aff() const; + template + inline typed::map, Domain2>, Range2> domain_product(const typed::map &map2) const; + template + inline typed::union_map, Domain2>, Range2> domain_product(const typed::union_map &umap2) const; + inline typed::map, Range2> domain_reverse() const; + inline typed::map, Range2> drop_unused_params() const; + inline typed::map, Range2> eq_at(const typed::multi_pw_aff<> &mpa) const = delete; + inline typed::union_map, Range2> eq_at(const typed::multi_union_pw_aff<> &mupa) const = delete; + inline bool every_map(const std::function, Range2>)> &test) const; + inline typed::map, Range2> extract_map(const typed::space, Range2> &space) const; + inline typed::basic_map flatten_domain() const; + inline typed::basic_map, Range2> flatten_range() const = delete; + inline void foreach_basic_map(const std::function, Range2>)> &fn) const; + inline void foreach_map(const std::function, Range2>)> &fn) const; + inline typed::basic_map, Range2> gist(const typed::basic_map, Range2> &context) const; + inline typed::map, Range2> gist(const typed::map, Range2> &context) const; + inline typed::union_map, Range2> gist(const typed::union_map, Range2> &context) const; + inline typed::map, Range2> gist_domain(const typed::set> &context) const; + inline typed::union_map, Range2> gist_domain(const typed::union_set> &uset) const; + inline typed::map, Range2> gist_params(const typed::set<> &context) const; + inline typed::basic_map, Range2> intersect(const typed::basic_map, Range2> &bmap2) const; + inline typed::map, Range2> intersect(const typed::map, Range2> &map2) const; + inline typed::union_map, Range2> intersect(const typed::union_map, Range2> &umap2) const; + inline typed::basic_map, Range2> intersect_domain(const typed::basic_set> &bset) const; + inline typed::map, Range2> intersect_domain(const typed::set> &set) const; + inline typed::union_map, Range2> intersect_domain(const typed::space> &space) const; + inline typed::union_map, Range2> intersect_domain(const typed::union_set> &uset) const; + inline typed::basic_map, Range2> intersect_domain(const typed::point> &bset) const; + inline typed::map, Range2> intersect_domain_wrapped_domain(const typed::set &domain) const; + inline typed::union_map, Range2> intersect_domain_wrapped_domain(const typed::union_set &domain) const; + inline typed::map, Range2> intersect_params(const typed::set<> ¶ms) const; + inline typed::basic_map, Range2> intersect_range(const typed::basic_set &bset) const; + inline typed::map, Range2> intersect_range(const typed::set &set) const; + inline typed::union_map, Range2> intersect_range(const typed::space &space) const; + inline typed::union_map, Range2> intersect_range(const typed::union_set &uset) const; + inline typed::basic_map, Range2> intersect_range(const typed::point &bset) const; + inline typed::map, Range2> intersect_range_wrapped_domain(const typed::set<> &domain) const = delete; + inline typed::union_map, Range2> intersect_range_wrapped_domain(const typed::union_set<> &domain) const = delete; + inline typed::map, Range2> lex_ge_at(const typed::multi_pw_aff<> &mpa) const = delete; + inline typed::map, Range2> lex_gt_at(const typed::multi_pw_aff<> &mpa) const = delete; + inline typed::map, Range2> lex_le_at(const typed::multi_pw_aff<> &mpa) const = delete; + inline typed::map, Range2> lex_lt_at(const typed::multi_pw_aff<> &mpa) const = delete; + inline typed::map, Range2> lexmax() const; + inline typed::pw_multi_aff, Range2> lexmax_pw_multi_aff() const; + inline typed::map, Range2> lexmin() const; + inline typed::pw_multi_aff, Range2> lexmin_pw_multi_aff() const; + inline typed::map, Range2> lower_bound(const typed::multi_pw_aff, Range2> &lower) const; + inline typed::map_list, Range2> map_list() const; + inline typed::multi_pw_aff, Range2> max_multi_pw_aff() const; + inline typed::multi_pw_aff, Range2> min_multi_pw_aff() const; + inline typed::set<> params() const; + template + inline typed::map preimage_domain(const typed::multi_aff> &ma) const; + template + inline typed::map preimage_domain(const typed::multi_pw_aff> &mpa) const; + template + inline typed::map preimage_domain(const typed::pw_multi_aff> &pma) const; + template + inline typed::union_map preimage_domain(const typed::union_pw_multi_aff> &upma) const; + template + inline typed::map, Arg3> preimage_range(const typed::multi_aff &ma) const; + template + inline typed::map, Arg3> preimage_range(const typed::pw_multi_aff &pma) const; + template + inline typed::union_map, Arg3> preimage_range(const typed::union_pw_multi_aff &upma) const; + template + inline typed::map, Domain2>, pair> product(const typed::map &map2) const; + template + inline typed::union_map, Domain2>, pair> product(const typed::union_map &umap2) const; + inline typed::map, Range2> project_out_all_params() const; + inline typed::map, Range2> project_out_param(const typed::id &id) const; + inline typed::map, Range2> project_out_param(const std::string &id) const; + inline typed::map, Range2> project_out_param(const typed::id_list &list) const; + inline typed::set range() const; + inline typed::map, Range2> range_factor_domain() const = delete; + inline typed::map, Range2> range_factor_range() const = delete; + inline typed::fixed_box, Range2> range_lattice_tile() const; + inline typed::union_map, Range2>, Range2> range_map() const; + template + inline typed::map, pair> range_product(const typed::map, Arg3> &map2) const; + template + inline typed::union_map, pair> range_product(const typed::union_map, Arg3> &umap2) const; + inline typed::map, Range2> range_reverse() const = delete; + inline typed::fixed_box, Range2> range_simple_fixed_box_hull() const; + inline typed::basic_map> reverse() const; + inline typed::map, Range2> set_domain_tuple(const typed::id<> &id) const = delete; + inline typed::map, Range2> set_domain_tuple(const std::string &id) const = delete; + template + inline typed::map, Arg2> set_range_tuple(const typed::id &id) const; + template + inline typed::map, Arg2> set_range_tuple(const std::string &id) const; + inline typed::space, Range2> space() const; + inline typed::map, Range2> subtract(const typed::map, Range2> &map2) const; + inline typed::union_map, Range2> subtract(const typed::union_map, Range2> &umap2) const; + inline typed::union_map, Range2> subtract_domain(const typed::union_set> &dom) const; + inline typed::union_map, Range2> subtract_range(const typed::union_set &dom) const; + inline typed::union_map, Range2> to_union_map() const; + inline typed::map, Range2> uncurry() const = delete; + inline typed::map, Range2> unite(const typed::basic_map, Range2> &bmap2) const; + inline typed::map, Range2> unite(const typed::map, Range2> &map2) const; + inline typed::union_map, Range2> unite(const typed::union_map, Range2> &umap2) const; + inline typed::map, Range2> upper_bound(const typed::multi_pw_aff, Range2> &upper) const; + inline typed::set, Range2>> wrap() const; +}; + +template +struct basic_map : public isl::basic_map { + template + friend struct aff; + template + friend struct aff_list; + template + friend struct basic_map; + template + friend struct basic_set; + template + friend struct fixed_box; + template + friend struct id; + template + friend struct id_list; + template + friend struct map; + template + friend struct map_list; + template + friend struct multi_aff; + template + friend struct multi_id; + template + friend struct multi_pw_aff; + template + friend struct multi_union_pw_aff; + template + friend struct multi_val; + template + friend struct point; + template + friend struct pw_aff; + template + friend struct pw_aff_list; + template + friend struct pw_multi_aff; + template + friend struct pw_multi_aff_list; + template + friend struct set; + template + friend struct set_list; + template + friend struct space; + template + friend struct union_map; + template + friend struct union_pw_aff; + template + friend struct union_pw_aff_list; + template + friend struct union_pw_multi_aff; + template + friend struct union_set; + template + friend struct union_set_list; + template + friend struct val; + template + friend struct val_list; + + basic_map() = default; + template {}, + bool>::type = true> + basic_map(const basic_map &obj) : isl::basic_map(obj) {} + private: + template {}, bool>::type = true> + basic_map(const base &obj) : isl::basic_map(obj) {} + public: + static basic_map from(const isl::basic_map &obj) { + return basic_map(obj); + } + inline explicit basic_map(const isl::ctx &ctx, const std::string &str); + template + inline typed::basic_map apply_domain(const typed::basic_map &bmap2) const; + template + inline typed::map apply_domain(const typed::map &map2) const; + template + inline typed::union_map apply_domain(const typed::union_map &umap2) const; + template + inline typed::basic_map apply_range(const typed::basic_map &bmap2) const; + template + inline typed::map apply_range(const typed::map &map2) const; + template + inline typed::union_map apply_range(const typed::union_map &umap2) const; + inline typed::map as_map() const; + inline typed::multi_union_pw_aff as_multi_union_pw_aff() const; + inline typed::pw_multi_aff as_pw_multi_aff() const; + inline typed::union_pw_multi_aff as_union_pw_multi_aff() const; + inline typed::set bind_domain(const typed::multi_id &tuple) const; + inline typed::set bind_range(const typed::multi_id &tuple) const; + inline typed::map coalesce() const; + inline typed::map curry() const = delete; + inline typed::basic_set deltas() const; + inline typed::basic_map detect_equalities() const; + inline typed::set domain() const; + inline typed::map domain_factor_domain() const = delete; + inline typed::map domain_factor_range() const = delete; + inline typed::union_map, Domain> domain_map() const; + inline typed::union_pw_multi_aff, Domain> domain_map_union_pw_multi_aff() const; + template + inline typed::map, Domain> domain_product(const typed::map &map2) const; + template + inline typed::union_map, Domain> domain_product(const typed::union_map &umap2) const; + inline typed::map domain_reverse() const = delete; + inline typed::map drop_unused_params() const; + template + inline typed::map eq_at(const typed::multi_pw_aff &mpa) const; + template + inline typed::union_map eq_at(const typed::multi_union_pw_aff &mupa) const; + inline bool every_map(const std::function)> &test) const; + inline typed::map extract_map(const typed::space &space) const; + inline typed::basic_map flatten_domain() const = delete; + inline typed::basic_map flatten_range() const = delete; + inline void foreach_basic_map(const std::function)> &fn) const; + inline void foreach_map(const std::function)> &fn) const; + inline typed::basic_map gist(const typed::basic_map &context) const; + inline typed::map gist(const typed::map &context) const; + inline typed::union_map gist(const typed::union_map &context) const; + inline typed::map gist_domain(const typed::set &context) const; + inline typed::union_map gist_domain(const typed::union_set &uset) const; + inline typed::map gist_params(const typed::set<> &context) const; + inline typed::basic_map intersect(const typed::basic_map &bmap2) const; + inline typed::map intersect(const typed::map &map2) const; + inline typed::union_map intersect(const typed::union_map &umap2) const; + inline typed::basic_map intersect_domain(const typed::basic_set &bset) const; + inline typed::map intersect_domain(const typed::set &set) const; + inline typed::union_map intersect_domain(const typed::space &space) const; + inline typed::union_map intersect_domain(const typed::union_set &uset) const; + inline typed::basic_map intersect_domain(const typed::point &bset) const; + inline typed::map intersect_domain_wrapped_domain(const typed::set<> &domain) const = delete; + inline typed::union_map intersect_domain_wrapped_domain(const typed::union_set<> &domain) const = delete; + inline typed::map intersect_params(const typed::set<> ¶ms) const; + inline typed::basic_map intersect_range(const typed::basic_set &bset) const; + inline typed::map intersect_range(const typed::set &set) const; + inline typed::union_map intersect_range(const typed::space &space) const; + inline typed::union_map intersect_range(const typed::union_set &uset) const; + inline typed::basic_map intersect_range(const typed::point &bset) const; + inline typed::map intersect_range_wrapped_domain(const typed::set<> &domain) const = delete; + inline typed::union_map intersect_range_wrapped_domain(const typed::union_set<> &domain) const = delete; + template + inline typed::map lex_ge_at(const typed::multi_pw_aff &mpa) const; + template + inline typed::map lex_gt_at(const typed::multi_pw_aff &mpa) const; + template + inline typed::map lex_le_at(const typed::multi_pw_aff &mpa) const; + template + inline typed::map lex_lt_at(const typed::multi_pw_aff &mpa) const; + inline typed::map lexmax() const; + inline typed::pw_multi_aff lexmax_pw_multi_aff() const; + inline typed::map lexmin() const; + inline typed::pw_multi_aff lexmin_pw_multi_aff() const; + inline typed::map lower_bound(const typed::multi_pw_aff &lower) const; + inline typed::map_list map_list() const; + inline typed::multi_pw_aff max_multi_pw_aff() const; + inline typed::multi_pw_aff min_multi_pw_aff() const; + inline typed::set<> params() const; + template + inline typed::map preimage_domain(const typed::multi_aff &ma) const; + template + inline typed::map preimage_domain(const typed::multi_pw_aff &mpa) const; + template + inline typed::map preimage_domain(const typed::pw_multi_aff &pma) const; + template + inline typed::union_map preimage_domain(const typed::union_pw_multi_aff &upma) const; + template + inline typed::map preimage_range(const typed::multi_aff &ma) const; + template + inline typed::map preimage_range(const typed::pw_multi_aff &pma) const; + template + inline typed::union_map preimage_range(const typed::union_pw_multi_aff &upma) const; + template + inline typed::map, pair> product(const typed::map &map2) const; + template + inline typed::union_map, pair> product(const typed::union_map &umap2) const; + inline typed::map project_out_all_params() const; + inline typed::map project_out_param(const typed::id &id) const; + inline typed::map project_out_param(const std::string &id) const; + inline typed::map project_out_param(const typed::id_list &list) const; + inline typed::set range() const; + inline typed::map range_factor_domain() const = delete; + inline typed::map range_factor_range() const = delete; + inline typed::fixed_box range_lattice_tile() const; + inline typed::union_map, Domain> range_map() const; + template + inline typed::map> range_product(const typed::map &map2) const; + template + inline typed::union_map> range_product(const typed::union_map &umap2) const; + inline typed::map range_reverse() const = delete; + inline typed::fixed_box range_simple_fixed_box_hull() const; + inline typed::basic_map reverse() const; + template + inline typed::map set_domain_tuple(const typed::id &id) const; + template + inline typed::map set_domain_tuple(const std::string &id) const; + template + inline typed::map set_range_tuple(const typed::id &id) const; + template + inline typed::map set_range_tuple(const std::string &id) const; + inline typed::space space() const; + inline typed::map subtract(const typed::map &map2) const; + inline typed::union_map subtract(const typed::union_map &umap2) const; + inline typed::union_map subtract_domain(const typed::union_set &dom) const; + inline typed::union_map subtract_range(const typed::union_set &dom) const; + inline typed::union_map to_union_map() const; + inline typed::map uncurry() const = delete; + inline typed::map unite(const typed::basic_map &bmap2) const; + inline typed::map unite(const typed::map &map2) const; + inline typed::union_map unite(const typed::union_map &umap2) const; + inline typed::map upper_bound(const typed::multi_pw_aff &upper) const; + inline typed::set> wrap() const; +}; + +template +struct basic_map> : public isl::basic_map { + template + friend struct aff; + template + friend struct aff_list; + template + friend struct basic_map; + template + friend struct basic_set; + template + friend struct fixed_box; + template + friend struct id; + template + friend struct id_list; + template + friend struct map; + template + friend struct map_list; + template + friend struct multi_aff; + template + friend struct multi_id; + template + friend struct multi_pw_aff; + template + friend struct multi_union_pw_aff; + template + friend struct multi_val; + template + friend struct point; + template + friend struct pw_aff; + template + friend struct pw_aff_list; + template + friend struct pw_multi_aff; + template + friend struct pw_multi_aff_list; + template + friend struct set; + template + friend struct set_list; + template + friend struct space; + template + friend struct union_map; + template + friend struct union_pw_aff; + template + friend struct union_pw_aff_list; + template + friend struct union_pw_multi_aff; + template + friend struct union_set; + template + friend struct union_set_list; + template + friend struct val; + template + friend struct val_list; + + basic_map() = default; + template {} && + std::is_base_of{} && + std::is_base_of{}, + bool>::type = true> + basic_map(const basic_map> &obj) : isl::basic_map(obj) {} + private: + template {}, bool>::type = true> + basic_map(const base &obj) : isl::basic_map(obj) {} + public: + static basic_map from(const isl::basic_map &obj) { + return basic_map(obj); + } + inline explicit basic_map(const isl::ctx &ctx, const std::string &str); + template + inline typed::basic_map> apply_domain(const typed::basic_map &bmap2) const; + template + inline typed::map> apply_domain(const typed::map &map2) const; + template + inline typed::union_map> apply_domain(const typed::union_map &umap2) const; + template + inline typed::basic_map apply_range(const typed::basic_map, Arg3> &bmap2) const; + template + inline typed::map apply_range(const typed::map, Arg3> &map2) const; + template + inline typed::union_map apply_range(const typed::union_map, Arg3> &umap2) const; + inline typed::map> as_map() const; + inline typed::multi_union_pw_aff> as_multi_union_pw_aff() const; + inline typed::pw_multi_aff> as_pw_multi_aff() const; + inline typed::union_pw_multi_aff> as_union_pw_multi_aff() const; + inline typed::set> bind_domain(const typed::multi_id &tuple) const; + inline typed::set bind_range(const typed::multi_id> &tuple) const; + inline typed::map> coalesce() const; + inline typed::map> curry() const = delete; + inline typed::basic_set> deltas() const = delete; + inline typed::basic_map> detect_equalities() const; + inline typed::set domain() const; + inline typed::map> domain_factor_domain() const = delete; + inline typed::map> domain_factor_range() const = delete; + inline typed::union_map>, Domain> domain_map() const; + inline typed::union_pw_multi_aff>, Domain> domain_map_union_pw_multi_aff() const; + template + inline typed::map, pair> domain_product(const typed::map> &map2) const; + template + inline typed::union_map, pair> domain_product(const typed::union_map> &umap2) const; + inline typed::map> domain_reverse() const = delete; + inline typed::map> drop_unused_params() const; + inline typed::map> eq_at(const typed::multi_pw_aff<> &mpa) const = delete; + inline typed::union_map> eq_at(const typed::multi_union_pw_aff<> &mupa) const = delete; + inline bool every_map(const std::function>)> &test) const; + inline typed::map> extract_map(const typed::space> &space) const; + inline typed::basic_map> flatten_domain() const = delete; + inline typed::basic_map flatten_range() const; + inline void foreach_basic_map(const std::function>)> &fn) const; + inline void foreach_map(const std::function>)> &fn) const; + inline typed::basic_map> gist(const typed::basic_map> &context) const; + inline typed::map> gist(const typed::map> &context) const; + inline typed::union_map> gist(const typed::union_map> &context) const; + inline typed::map> gist_domain(const typed::set &context) const; + inline typed::union_map> gist_domain(const typed::union_set &uset) const; + inline typed::map> gist_params(const typed::set<> &context) const; + inline typed::basic_map> intersect(const typed::basic_map> &bmap2) const; + inline typed::map> intersect(const typed::map> &map2) const; + inline typed::union_map> intersect(const typed::union_map> &umap2) const; + inline typed::basic_map> intersect_domain(const typed::basic_set &bset) const; + inline typed::map> intersect_domain(const typed::set &set) const; + inline typed::union_map> intersect_domain(const typed::space &space) const; + inline typed::union_map> intersect_domain(const typed::union_set &uset) const; + inline typed::basic_map> intersect_domain(const typed::point &bset) const; + inline typed::map> intersect_domain_wrapped_domain(const typed::set<> &domain) const = delete; + inline typed::union_map> intersect_domain_wrapped_domain(const typed::union_set<> &domain) const = delete; + inline typed::map> intersect_params(const typed::set<> ¶ms) const; + inline typed::basic_map> intersect_range(const typed::basic_set> &bset) const; + inline typed::map> intersect_range(const typed::set> &set) const; + inline typed::union_map> intersect_range(const typed::space> &space) const; + inline typed::union_map> intersect_range(const typed::union_set> &uset) const; + inline typed::basic_map> intersect_range(const typed::point> &bset) const; + inline typed::map> intersect_range_wrapped_domain(const typed::set &domain) const; + inline typed::union_map> intersect_range_wrapped_domain(const typed::union_set &domain) const; + inline typed::map> lex_ge_at(const typed::multi_pw_aff<> &mpa) const = delete; + inline typed::map> lex_gt_at(const typed::multi_pw_aff<> &mpa) const = delete; + inline typed::map> lex_le_at(const typed::multi_pw_aff<> &mpa) const = delete; + inline typed::map> lex_lt_at(const typed::multi_pw_aff<> &mpa) const = delete; + inline typed::map> lexmax() const; + inline typed::pw_multi_aff> lexmax_pw_multi_aff() const; + inline typed::map> lexmin() const; + inline typed::pw_multi_aff> lexmin_pw_multi_aff() const; + inline typed::map> lower_bound(const typed::multi_pw_aff> &lower) const; + inline typed::map_list> map_list() const; + inline typed::multi_pw_aff> max_multi_pw_aff() const; + inline typed::multi_pw_aff> min_multi_pw_aff() const; + inline typed::set<> params() const; + template + inline typed::map> preimage_domain(const typed::multi_aff &ma) const; + template + inline typed::map> preimage_domain(const typed::multi_pw_aff &mpa) const; + template + inline typed::map> preimage_domain(const typed::pw_multi_aff &pma) const; + template + inline typed::union_map> preimage_domain(const typed::union_pw_multi_aff &upma) const; + template + inline typed::map preimage_range(const typed::multi_aff> &ma) const; + template + inline typed::map preimage_range(const typed::pw_multi_aff> &pma) const; + template + inline typed::union_map preimage_range(const typed::union_pw_multi_aff> &upma) const; + template + inline typed::map, pair, Arg3>> product(const typed::map &map2) const; + template + inline typed::union_map, pair, Arg3>> product(const typed::union_map &umap2) const; + inline typed::map> project_out_all_params() const; + inline typed::map> project_out_param(const typed::id &id) const; + inline typed::map> project_out_param(const std::string &id) const; + inline typed::map> project_out_param(const typed::id_list &list) const; + inline typed::set> range() const; + inline typed::map range_factor_domain() const; + inline typed::map range_factor_range() const; + inline typed::fixed_box> range_lattice_tile() const; + inline typed::union_map>, pair> range_map() const; + template + inline typed::map, Arg3>> range_product(const typed::map &map2) const; + template + inline typed::union_map, Arg3>> range_product(const typed::union_map &umap2) const; + inline typed::map> range_reverse() const; + inline typed::fixed_box> range_simple_fixed_box_hull() const; + inline typed::basic_map, Domain> reverse() const; + template + inline typed::map> set_domain_tuple(const typed::id &id) const; + template + inline typed::map> set_domain_tuple(const std::string &id) const; + inline typed::map> set_range_tuple(const typed::id<> &id) const = delete; + inline typed::map> set_range_tuple(const std::string &id) const = delete; + inline typed::space> space() const; + inline typed::map> subtract(const typed::map> &map2) const; + inline typed::union_map> subtract(const typed::union_map> &umap2) const; + inline typed::union_map> subtract_domain(const typed::union_set &dom) const; + inline typed::union_map> subtract_range(const typed::union_set> &dom) const; + inline typed::union_map> to_union_map() const; + inline typed::map, Range2> uncurry() const; + inline typed::map> unite(const typed::basic_map> &bmap2) const; + inline typed::map> unite(const typed::map> &map2) const; + inline typed::union_map> unite(const typed::union_map> &umap2) const; + inline typed::map> upper_bound(const typed::multi_pw_aff> &upper) const; + inline typed::set>> wrap() const; +}; + +template +struct basic_map, pair> : public isl::basic_map { + template + friend struct aff; + template + friend struct aff_list; + template + friend struct basic_map; + template + friend struct basic_set; + template + friend struct fixed_box; + template + friend struct id; + template + friend struct id_list; + template + friend struct map; + template + friend struct map_list; + template + friend struct multi_aff; + template + friend struct multi_id; + template + friend struct multi_pw_aff; + template + friend struct multi_union_pw_aff; + template + friend struct multi_val; + template + friend struct point; + template + friend struct pw_aff; + template + friend struct pw_aff_list; + template + friend struct pw_multi_aff; + template + friend struct pw_multi_aff_list; + template + friend struct set; + template + friend struct set_list; + template + friend struct space; + template + friend struct union_map; + template + friend struct union_pw_aff; + template + friend struct union_pw_aff_list; + template + friend struct union_pw_multi_aff; + template + friend struct union_set; + template + friend struct union_set_list; + template + friend struct val; + template + friend struct val_list; + + basic_map() = default; + template {} && + std::is_base_of{}, + bool>::type = true> + basic_map(const basic_map, pair> &obj) : isl::basic_map(obj) {} + private: + template {}, bool>::type = true> + basic_map(const base &obj) : isl::basic_map(obj) {} + public: + static basic_map from(const isl::basic_map &obj) { + return basic_map(obj); + } + inline explicit basic_map(const isl::ctx &ctx, const std::string &str); + template + inline typed::basic_map> apply_domain(const typed::basic_map, Domain2> &bmap2) const; + template + inline typed::map> apply_domain(const typed::map, Domain2> &map2) const; + template + inline typed::union_map> apply_domain(const typed::union_map, Domain2> &umap2) const; + template + inline typed::basic_map, Range2> apply_range(const typed::basic_map, Range2> &bmap2) const; + template + inline typed::map, Range2> apply_range(const typed::map, Range2> &map2) const; + template + inline typed::union_map, Range2> apply_range(const typed::union_map, Range2> &umap2) const; + inline typed::map, pair> as_map() const; + inline typed::multi_union_pw_aff, pair> as_multi_union_pw_aff() const; + inline typed::pw_multi_aff, pair> as_pw_multi_aff() const; + inline typed::union_pw_multi_aff, pair> as_union_pw_multi_aff() const; + inline typed::set> bind_domain(const typed::multi_id> &tuple) const; + inline typed::set> bind_range(const typed::multi_id> &tuple) const; + inline typed::map, pair> coalesce() const; + inline typed::map>> curry() const; + inline typed::basic_set> deltas() const; + inline typed::basic_map, pair> detect_equalities() const; + inline typed::set> domain() const; + inline typed::map> domain_factor_domain() const; + inline typed::map> domain_factor_range() const; + inline typed::union_map, pair>, pair> domain_map() const; + inline typed::union_pw_multi_aff, pair>, pair> domain_map_union_pw_multi_aff() const; + template + inline typed::map, Domain2>, pair> domain_product(const typed::map> &map2) const; + template + inline typed::union_map, Domain2>, pair> domain_product(const typed::union_map> &umap2) const; + inline typed::map, pair> domain_reverse() const; + inline typed::map, pair> drop_unused_params() const; + template + inline typed::map, pair> eq_at(const typed::multi_pw_aff, Range> &mpa) const; + template + inline typed::union_map, pair> eq_at(const typed::multi_union_pw_aff, Range> &mupa) const; + inline bool every_map(const std::function, pair>)> &test) const; + inline typed::map, pair> extract_map(const typed::space, pair> &space) const; + inline typed::basic_map> flatten_domain() const; + inline typed::basic_map, Anonymous> flatten_range() const; + inline void foreach_basic_map(const std::function, pair>)> &fn) const; + inline void foreach_map(const std::function, pair>)> &fn) const; + inline typed::basic_map, pair> gist(const typed::basic_map, pair> &context) const; + inline typed::map, pair> gist(const typed::map, pair> &context) const; + inline typed::union_map, pair> gist(const typed::union_map, pair> &context) const; + inline typed::map, pair> gist_domain(const typed::set> &context) const; + inline typed::union_map, pair> gist_domain(const typed::union_set> &uset) const; + inline typed::map, pair> gist_params(const typed::set<> &context) const; + inline typed::basic_map, pair> intersect(const typed::basic_map, pair> &bmap2) const; + inline typed::map, pair> intersect(const typed::map, pair> &map2) const; + inline typed::union_map, pair> intersect(const typed::union_map, pair> &umap2) const; + inline typed::basic_map, pair> intersect_domain(const typed::basic_set> &bset) const; + inline typed::map, pair> intersect_domain(const typed::set> &set) const; + inline typed::union_map, pair> intersect_domain(const typed::space> &space) const; + inline typed::union_map, pair> intersect_domain(const typed::union_set> &uset) const; + inline typed::basic_map, pair> intersect_domain(const typed::point> &bset) const; + inline typed::map, pair> intersect_domain_wrapped_domain(const typed::set &domain) const; + inline typed::union_map, pair> intersect_domain_wrapped_domain(const typed::union_set &domain) const; + inline typed::map, pair> intersect_params(const typed::set<> ¶ms) const; + inline typed::basic_map, pair> intersect_range(const typed::basic_set> &bset) const; + inline typed::map, pair> intersect_range(const typed::set> &set) const; + inline typed::union_map, pair> intersect_range(const typed::space> &space) const; + inline typed::union_map, pair> intersect_range(const typed::union_set> &uset) const; + inline typed::basic_map, pair> intersect_range(const typed::point> &bset) const; + inline typed::map, pair> intersect_range_wrapped_domain(const typed::set &domain) const; + inline typed::union_map, pair> intersect_range_wrapped_domain(const typed::union_set &domain) const; + template + inline typed::map, pair> lex_ge_at(const typed::multi_pw_aff, Range> &mpa) const; + template + inline typed::map, pair> lex_gt_at(const typed::multi_pw_aff, Range> &mpa) const; + template + inline typed::map, pair> lex_le_at(const typed::multi_pw_aff, Range> &mpa) const; + template + inline typed::map, pair> lex_lt_at(const typed::multi_pw_aff, Range> &mpa) const; + inline typed::map, pair> lexmax() const; + inline typed::pw_multi_aff, pair> lexmax_pw_multi_aff() const; + inline typed::map, pair> lexmin() const; + inline typed::pw_multi_aff, pair> lexmin_pw_multi_aff() const; + inline typed::map, pair> lower_bound(const typed::multi_pw_aff, pair> &lower) const; + inline typed::map_list, pair> map_list() const; + inline typed::multi_pw_aff, pair> max_multi_pw_aff() const; + inline typed::multi_pw_aff, pair> min_multi_pw_aff() const; + inline typed::set<> params() const; + template + inline typed::map> preimage_domain(const typed::multi_aff> &ma) const; + template + inline typed::map> preimage_domain(const typed::multi_pw_aff> &mpa) const; + template + inline typed::map> preimage_domain(const typed::pw_multi_aff> &pma) const; + template + inline typed::union_map> preimage_domain(const typed::union_pw_multi_aff> &upma) const; + template + inline typed::map, Range2> preimage_range(const typed::multi_aff> &ma) const; + template + inline typed::map, Range2> preimage_range(const typed::pw_multi_aff> &pma) const; + template + inline typed::union_map, Range2> preimage_range(const typed::union_pw_multi_aff> &upma) const; + template + inline typed::map, Domain2>, pair, Range2>> product(const typed::map &map2) const; + template + inline typed::union_map, Domain2>, pair, Range2>> product(const typed::union_map &umap2) const; + inline typed::map, pair> project_out_all_params() const; + inline typed::map, pair> project_out_param(const typed::id &id) const; + inline typed::map, pair> project_out_param(const std::string &id) const; + inline typed::map, pair> project_out_param(const typed::id_list &list) const; + inline typed::set> range() const; + inline typed::map, T1> range_factor_domain() const; + inline typed::map, T2> range_factor_range() const; + inline typed::fixed_box, pair> range_lattice_tile() const; + inline typed::union_map, pair>, pair> range_map() const; + template + inline typed::map, pair, Range2>> range_product(const typed::map, Range2> &map2) const; + template + inline typed::union_map, pair, Range2>> range_product(const typed::union_map, Range2> &umap2) const; + inline typed::map, pair> range_reverse() const; + inline typed::fixed_box, pair> range_simple_fixed_box_hull() const; + inline typed::basic_map, pair> reverse() const; + inline typed::map, pair> set_domain_tuple(const typed::id<> &id) const = delete; + inline typed::map, pair> set_domain_tuple(const std::string &id) const = delete; + inline typed::map, pair> set_range_tuple(const typed::id<> &id) const = delete; + inline typed::map, pair> set_range_tuple(const std::string &id) const = delete; + inline typed::space, pair> space() const; + inline typed::map, pair> subtract(const typed::map, pair> &map2) const; + inline typed::union_map, pair> subtract(const typed::union_map, pair> &umap2) const; + inline typed::union_map, pair> subtract_domain(const typed::union_set> &dom) const; + inline typed::union_map, pair> subtract_range(const typed::union_set> &dom) const; + inline typed::union_map, pair> to_union_map() const; + inline typed::map, T1>, T2> uncurry() const; + inline typed::map, pair> unite(const typed::basic_map, pair> &bmap2) const; + inline typed::map, pair> unite(const typed::map, pair> &map2) const; + inline typed::union_map, pair> unite(const typed::union_map, pair> &umap2) const; + inline typed::map, pair> upper_bound(const typed::multi_pw_aff, pair> &upper) const; + inline typed::set, pair>> wrap() const; +}; + +template +struct basic_map, pair> : public isl::basic_map { + template + friend struct aff; + template + friend struct aff_list; + template + friend struct basic_map; + template + friend struct basic_set; + template + friend struct fixed_box; + template + friend struct id; + template + friend struct id_list; + template + friend struct map; + template + friend struct map_list; + template + friend struct multi_aff; + template + friend struct multi_id; + template + friend struct multi_pw_aff; + template + friend struct multi_union_pw_aff; + template + friend struct multi_val; + template + friend struct point; + template + friend struct pw_aff; + template + friend struct pw_aff_list; + template + friend struct pw_multi_aff; + template + friend struct pw_multi_aff_list; + template + friend struct set; + template + friend struct set_list; + template + friend struct space; + template + friend struct union_map; + template + friend struct union_pw_aff; + template + friend struct union_pw_aff_list; + template + friend struct union_pw_multi_aff; + template + friend struct union_set; + template + friend struct union_set_list; + template + friend struct val; + template + friend struct val_list; + + basic_map() = default; + template {} && + std::is_base_of{} && + std::is_base_of{} && + std::is_base_of{}, + bool>::type = true> + basic_map(const basic_map, pair> &obj) : isl::basic_map(obj) {} + private: + template {}, bool>::type = true> + basic_map(const base &obj) : isl::basic_map(obj) {} + public: + static basic_map from(const isl::basic_map &obj) { + return basic_map(obj); + } + inline explicit basic_map(const isl::ctx &ctx, const std::string &str); + template + inline typed::basic_map> apply_domain(const typed::basic_map, Domain2> &bmap2) const; + template + inline typed::map> apply_domain(const typed::map, Domain2> &map2) const; + template + inline typed::union_map> apply_domain(const typed::union_map, Domain2> &umap2) const; + template + inline typed::basic_map, Arg2> apply_range(const typed::basic_map, Arg2> &bmap2) const; + template + inline typed::map, Arg2> apply_range(const typed::map, Arg2> &map2) const; + template + inline typed::union_map, Arg2> apply_range(const typed::union_map, Arg2> &umap2) const; + inline typed::map, pair> as_map() const; + inline typed::multi_union_pw_aff, pair> as_multi_union_pw_aff() const; + inline typed::pw_multi_aff, pair> as_pw_multi_aff() const; + inline typed::union_pw_multi_aff, pair> as_union_pw_multi_aff() const; + inline typed::set> bind_domain(const typed::multi_id> &tuple) const; + inline typed::set> bind_range(const typed::multi_id> &tuple) const; + inline typed::map, pair> coalesce() const; + inline typed::map>> curry() const; + inline typed::basic_set, pair> deltas() const = delete; + inline typed::basic_map, pair> detect_equalities() const; + inline typed::set> domain() const; + inline typed::map> domain_factor_domain() const; + inline typed::map> domain_factor_range() const; + inline typed::union_map, pair>, pair> domain_map() const; + inline typed::union_pw_multi_aff, pair>, pair> domain_map_union_pw_multi_aff() const; + template + inline typed::map, Domain2>, pair> domain_product(const typed::map> &map2) const; + template + inline typed::union_map, Domain2>, pair> domain_product(const typed::union_map> &umap2) const; + inline typed::map, pair> domain_reverse() const; + inline typed::map, pair> drop_unused_params() const; + inline typed::map, pair> eq_at(const typed::multi_pw_aff<> &mpa) const = delete; + inline typed::union_map, pair> eq_at(const typed::multi_union_pw_aff<> &mupa) const = delete; + inline bool every_map(const std::function, pair>)> &test) const; + inline typed::map, pair> extract_map(const typed::space, pair> &space) const; + inline typed::basic_map> flatten_domain() const; + inline typed::basic_map, Anonymous> flatten_range() const; + inline void foreach_basic_map(const std::function, pair>)> &fn) const; + inline void foreach_map(const std::function, pair>)> &fn) const; + inline typed::basic_map, pair> gist(const typed::basic_map, pair> &context) const; + inline typed::map, pair> gist(const typed::map, pair> &context) const; + inline typed::union_map, pair> gist(const typed::union_map, pair> &context) const; + inline typed::map, pair> gist_domain(const typed::set> &context) const; + inline typed::union_map, pair> gist_domain(const typed::union_set> &uset) const; + inline typed::map, pair> gist_params(const typed::set<> &context) const; + inline typed::basic_map, pair> intersect(const typed::basic_map, pair> &bmap2) const; + inline typed::map, pair> intersect(const typed::map, pair> &map2) const; + inline typed::union_map, pair> intersect(const typed::union_map, pair> &umap2) const; + inline typed::basic_map, pair> intersect_domain(const typed::basic_set> &bset) const; + inline typed::map, pair> intersect_domain(const typed::set> &set) const; + inline typed::union_map, pair> intersect_domain(const typed::space> &space) const; + inline typed::union_map, pair> intersect_domain(const typed::union_set> &uset) const; + inline typed::basic_map, pair> intersect_domain(const typed::point> &bset) const; + inline typed::map, pair> intersect_domain_wrapped_domain(const typed::set &domain) const; + inline typed::union_map, pair> intersect_domain_wrapped_domain(const typed::union_set &domain) const; + inline typed::map, pair> intersect_params(const typed::set<> ¶ms) const; + inline typed::basic_map, pair> intersect_range(const typed::basic_set> &bset) const; + inline typed::map, pair> intersect_range(const typed::set> &set) const; + inline typed::union_map, pair> intersect_range(const typed::space> &space) const; + inline typed::union_map, pair> intersect_range(const typed::union_set> &uset) const; + inline typed::basic_map, pair> intersect_range(const typed::point> &bset) const; + inline typed::map, pair> intersect_range_wrapped_domain(const typed::set &domain) const; + inline typed::union_map, pair> intersect_range_wrapped_domain(const typed::union_set &domain) const; + inline typed::map, pair> lex_ge_at(const typed::multi_pw_aff<> &mpa) const = delete; + inline typed::map, pair> lex_gt_at(const typed::multi_pw_aff<> &mpa) const = delete; + inline typed::map, pair> lex_le_at(const typed::multi_pw_aff<> &mpa) const = delete; + inline typed::map, pair> lex_lt_at(const typed::multi_pw_aff<> &mpa) const = delete; + inline typed::map, pair> lexmax() const; + inline typed::pw_multi_aff, pair> lexmax_pw_multi_aff() const; + inline typed::map, pair> lexmin() const; + inline typed::pw_multi_aff, pair> lexmin_pw_multi_aff() const; + inline typed::map, pair> lower_bound(const typed::multi_pw_aff, pair> &lower) const; + inline typed::map_list, pair> map_list() const; + inline typed::multi_pw_aff, pair> max_multi_pw_aff() const; + inline typed::multi_pw_aff, pair> min_multi_pw_aff() const; + inline typed::set<> params() const; + template + inline typed::map> preimage_domain(const typed::multi_aff> &ma) const; + template + inline typed::map> preimage_domain(const typed::multi_pw_aff> &mpa) const; + template + inline typed::map> preimage_domain(const typed::pw_multi_aff> &pma) const; + template + inline typed::union_map> preimage_domain(const typed::union_pw_multi_aff> &upma) const; + template + inline typed::map, Arg2> preimage_range(const typed::multi_aff> &ma) const; + template + inline typed::map, Arg2> preimage_range(const typed::pw_multi_aff> &pma) const; + template + inline typed::union_map, Arg2> preimage_range(const typed::union_pw_multi_aff> &upma) const; + template + inline typed::map, Domain2>, pair, Arg2>> product(const typed::map &map2) const; + template + inline typed::union_map, Domain2>, pair, Arg2>> product(const typed::union_map &umap2) const; + inline typed::map, pair> project_out_all_params() const; + inline typed::map, pair> project_out_param(const typed::id &id) const; + inline typed::map, pair> project_out_param(const std::string &id) const; + inline typed::map, pair> project_out_param(const typed::id_list &list) const; + inline typed::set> range() const; + inline typed::map, Range> range_factor_domain() const; + inline typed::map, Range2> range_factor_range() const; + inline typed::fixed_box, pair> range_lattice_tile() const; + inline typed::union_map, pair>, pair> range_map() const; + template + inline typed::map, pair, Arg2>> range_product(const typed::map, Arg2> &map2) const; + template + inline typed::union_map, pair, Arg2>> range_product(const typed::union_map, Arg2> &umap2) const; + inline typed::map, pair> range_reverse() const; + inline typed::fixed_box, pair> range_simple_fixed_box_hull() const; + inline typed::basic_map, pair> reverse() const; + inline typed::map, pair> set_domain_tuple(const typed::id<> &id) const = delete; + inline typed::map, pair> set_domain_tuple(const std::string &id) const = delete; + inline typed::map, pair> set_range_tuple(const typed::id<> &id) const = delete; + inline typed::map, pair> set_range_tuple(const std::string &id) const = delete; + inline typed::space, pair> space() const; + inline typed::map, pair> subtract(const typed::map, pair> &map2) const; + inline typed::union_map, pair> subtract(const typed::union_map, pair> &umap2) const; + inline typed::union_map, pair> subtract_domain(const typed::union_set> &dom) const; + inline typed::union_map, pair> subtract_range(const typed::union_set> &dom) const; + inline typed::union_map, pair> to_union_map() const; + inline typed::map, Range>, Range2> uncurry() const; + inline typed::map, pair> unite(const typed::basic_map, pair> &bmap2) const; + inline typed::map, pair> unite(const typed::map, pair> &map2) const; + inline typed::union_map, pair> unite(const typed::union_map, pair> &umap2) const; + inline typed::map, pair> upper_bound(const typed::multi_pw_aff, pair> &upper) const; + inline typed::set, pair>> wrap() const; +}; + +template <> +struct basic_set<> : public isl::basic_set { + template + friend struct aff; + template + friend struct aff_list; + template + friend struct basic_map; + template + friend struct basic_set; + template + friend struct fixed_box; + template + friend struct id; + template + friend struct id_list; + template + friend struct map; + template + friend struct map_list; + template + friend struct multi_aff; + template + friend struct multi_id; + template + friend struct multi_pw_aff; + template + friend struct multi_union_pw_aff; + template + friend struct multi_val; + template + friend struct point; + template + friend struct pw_aff; + template + friend struct pw_aff_list; + template + friend struct pw_multi_aff; + template + friend struct pw_multi_aff_list; + template + friend struct set; + template + friend struct set_list; + template + friend struct space; + template + friend struct union_map; + template + friend struct union_pw_aff; + template + friend struct union_pw_aff_list; + template + friend struct union_pw_multi_aff; + template + friend struct union_set; + template + friend struct union_set_list; + template + friend struct val; + template + friend struct val_list; + + basic_set() = default; + private: + template {}, bool>::type = true> + basic_set(const base &obj) : isl::basic_set(obj) {} + public: + static basic_set from(const isl::basic_set &obj) { + return basic_set(obj); + } + inline /* implicit */ basic_set(const typed::point<> &pnt); + inline explicit basic_set(const isl::ctx &ctx, const std::string &str); + inline typed::basic_set<> apply(const typed::basic_map<> &bmap) const = delete; + inline typed::set<> apply(const typed::map<> &map) const = delete; + inline typed::union_set<> apply(const typed::union_map<> &umap) const = delete; + inline typed::pw_multi_aff<> as_pw_multi_aff() const = delete; + inline typed::set<> as_set() const = delete; + inline typed::set<> bind(const typed::multi_id<> &tuple) const = delete; + inline typed::set<> coalesce() const; + inline typed::basic_set<> detect_equalities() const; + inline typed::set<> drop_unused_params() const; + inline bool every_set(const std::function)> &test) const; + inline typed::set<> extract_set(const typed::space<> &space) const; + inline void foreach_basic_set(const std::function)> &fn) const; + inline void foreach_point(const std::function)> &fn) const; + inline void foreach_set(const std::function)> &fn) const; + inline typed::basic_set<> gist(const typed::basic_set<> &context) const; + inline typed::set<> gist(const typed::set<> &context) const; + inline typed::union_set<> gist(const typed::union_set<> &context) const; + inline typed::basic_set<> gist(const typed::point<> &context) const; + inline typed::set<> gist_params(const typed::set<> &context) const = delete; + inline typed::map<> identity() const = delete; + inline typed::pw_aff indicator_function() const; + inline typed::map<> insert_domain(const typed::space<> &domain) const = delete; + inline typed::basic_set<> intersect(const typed::basic_set<> &bset2) const; + inline typed::set<> intersect(const typed::set<> &set2) const; + inline typed::union_set<> intersect(const typed::union_set<> &uset2) const; + inline typed::basic_set<> intersect(const typed::point<> &bset2) const; + inline typed::basic_set<> intersect_params(const typed::basic_set<> &bset2) const = delete; + inline typed::set<> intersect_params(const typed::set<> ¶ms) const = delete; + inline typed::basic_set<> intersect_params(const typed::point<> &bset2) const = delete; + inline typed::fixed_box<> lattice_tile() const = delete; + inline typed::set<> lexmax() const = delete; + inline typed::pw_multi_aff<> lexmax_pw_multi_aff() const = delete; + inline typed::set<> lexmin() const = delete; + inline typed::pw_multi_aff<> lexmin_pw_multi_aff() const = delete; + inline typed::set<> lower_bound(const typed::multi_pw_aff<> &lower) const = delete; + inline typed::set<> lower_bound(const typed::multi_val<> &lower) const = delete; + inline typed::multi_pw_aff<> max_multi_pw_aff() const = delete; + inline typed::val<> max_val(const typed::aff<> &obj) const = delete; + inline typed::multi_pw_aff<> min_multi_pw_aff() const = delete; + inline typed::val<> min_val(const typed::aff<> &obj) const = delete; + inline typed::pw_aff param_pw_aff_on_domain(const typed::id &id) const; + inline typed::pw_aff param_pw_aff_on_domain(const std::string &id) const; + inline typed::basic_set<> params() const = delete; + inline typed::multi_val<> plain_multi_val_if_fixed() const = delete; + inline typed::set<> preimage(const typed::multi_aff<> &ma) const = delete; + inline typed::set<> preimage(const typed::multi_pw_aff<> &mpa) const = delete; + inline typed::set<> preimage(const typed::pw_multi_aff<> &pma) const = delete; + inline typed::union_set<> preimage(const typed::union_pw_multi_aff<> &upma) const = delete; + inline typed::set<> product(const typed::set<> &set2) const = delete; + inline typed::set<> project_out_all_params() const; + inline typed::set<> project_out_param(const typed::id &id) const; + inline typed::set<> project_out_param(const std::string &id) const; + inline typed::set<> project_out_param(const typed::id_list &list) const; + inline typed::pw_aff pw_aff_on_domain(const typed::val &v) const; + inline typed::pw_aff pw_aff_on_domain(long v) const; + template + inline typed::pw_multi_aff pw_multi_aff_on_domain(const typed::multi_val &mv) const; + inline typed::set_list<> set_list() const; + inline typed::fixed_box<> simple_fixed_box_hull() const = delete; + inline typed::space<> space() const; + inline typed::set<> subtract(const typed::set<> &set2) const; + inline typed::union_set<> subtract(const typed::union_set<> &uset2) const; + inline typed::set<> to_set() const; + inline typed::union_set<> to_union_set() const; + inline typed::map<> translation() const = delete; + template + inline typed::set unbind_params(const typed::multi_id &tuple) const; + inline typed::map<> unbind_params_insert_domain(const typed::multi_id<> &domain) const = delete; + inline typed::set<> unite(const typed::basic_set<> &bset2) const; + inline typed::set<> unite(const typed::set<> &set2) const; + inline typed::union_set<> unite(const typed::union_set<> &uset2) const; + inline typed::set<> unite(const typed::point<> &bset2) const; + inline typed::map<> unwrap() const = delete; + inline typed::set<> upper_bound(const typed::multi_pw_aff<> &upper) const = delete; + inline typed::set<> upper_bound(const typed::multi_val<> &upper) const = delete; + inline typed::set<> wrapped_reverse() const = delete; +}; + +template +struct basic_set : public isl::basic_set { + template + friend struct aff; + template + friend struct aff_list; + template + friend struct basic_map; + template + friend struct basic_set; + template + friend struct fixed_box; + template + friend struct id; + template + friend struct id_list; + template + friend struct map; + template + friend struct map_list; + template + friend struct multi_aff; + template + friend struct multi_id; + template + friend struct multi_pw_aff; + template + friend struct multi_union_pw_aff; + template + friend struct multi_val; + template + friend struct point; + template + friend struct pw_aff; + template + friend struct pw_aff_list; + template + friend struct pw_multi_aff; + template + friend struct pw_multi_aff_list; + template + friend struct set; + template + friend struct set_list; + template + friend struct space; + template + friend struct union_map; + template + friend struct union_pw_aff; + template + friend struct union_pw_aff_list; + template + friend struct union_pw_multi_aff; + template + friend struct union_set; + template + friend struct union_set_list; + template + friend struct val; + template + friend struct val_list; + + basic_set() = default; + template {}, + bool>::type = true> + basic_set(const basic_set &obj) : isl::basic_set(obj) {} + private: + template {}, bool>::type = true> + basic_set(const base &obj) : isl::basic_set(obj) {} + public: + static basic_set from(const isl::basic_set &obj) { + return basic_set(obj); + } + inline /* implicit */ basic_set(const typed::point &pnt); + inline explicit basic_set(const isl::ctx &ctx, const std::string &str); + template + inline typed::basic_set apply(const typed::basic_map &bmap) const; + template + inline typed::set apply(const typed::map &map) const; + template + inline typed::union_set apply(const typed::union_map &umap) const; + inline typed::pw_multi_aff as_pw_multi_aff() const; + inline typed::set as_set() const; + inline typed::set<> bind(const typed::multi_id &tuple) const; + inline typed::set coalesce() const; + inline typed::basic_set detect_equalities() const; + inline typed::set drop_unused_params() const; + inline bool every_set(const std::function)> &test) const; + inline typed::set extract_set(const typed::space &space) const; + inline void foreach_basic_set(const std::function)> &fn) const; + inline void foreach_point(const std::function)> &fn) const; + inline void foreach_set(const std::function)> &fn) const; + inline typed::basic_set gist(const typed::basic_set &context) const; + inline typed::set gist(const typed::set &context) const; + inline typed::union_set gist(const typed::union_set &context) const; + inline typed::basic_set gist(const typed::point &context) const; + inline typed::set gist_params(const typed::set<> &context) const; + inline typed::map identity() const; + inline typed::pw_aff indicator_function() const; + template + inline typed::map insert_domain(const typed::space &domain) const; + inline typed::basic_set intersect(const typed::basic_set &bset2) const; + inline typed::set intersect(const typed::set &set2) const; + inline typed::union_set intersect(const typed::union_set &uset2) const; + inline typed::basic_set intersect(const typed::point &bset2) const; + inline typed::basic_set intersect_params(const typed::basic_set<> &bset2) const; + inline typed::set intersect_params(const typed::set<> ¶ms) const; + inline typed::basic_set intersect_params(const typed::point<> &bset2) const; + inline typed::fixed_box lattice_tile() const; + inline typed::set lexmax() const; + inline typed::pw_multi_aff lexmax_pw_multi_aff() const; + inline typed::set lexmin() const; + inline typed::pw_multi_aff lexmin_pw_multi_aff() const; + inline typed::set lower_bound(const typed::multi_pw_aff &lower) const; + inline typed::set lower_bound(const typed::multi_val &lower) const; + inline typed::multi_pw_aff max_multi_pw_aff() const; + inline typed::val max_val(const typed::aff<> &obj) const = delete; + inline typed::multi_pw_aff min_multi_pw_aff() const; + inline typed::val min_val(const typed::aff<> &obj) const = delete; + inline typed::pw_aff param_pw_aff_on_domain(const typed::id &id) const; + inline typed::pw_aff param_pw_aff_on_domain(const std::string &id) const; + inline typed::basic_set<> params() const; + inline typed::multi_val plain_multi_val_if_fixed() const; + template + inline typed::set preimage(const typed::multi_aff &ma) const; + template + inline typed::set preimage(const typed::multi_pw_aff &mpa) const; + template + inline typed::set preimage(const typed::pw_multi_aff &pma) const; + template + inline typed::union_set preimage(const typed::union_pw_multi_aff &upma) const; + template + inline typed::set> product(const typed::set &set2) const; + inline typed::set project_out_all_params() const; + inline typed::set project_out_param(const typed::id &id) const; + inline typed::set project_out_param(const std::string &id) const; + inline typed::set project_out_param(const typed::id_list &list) const; + inline typed::pw_aff pw_aff_on_domain(const typed::val &v) const; + inline typed::pw_aff pw_aff_on_domain(long v) const; + template + inline typed::pw_multi_aff pw_multi_aff_on_domain(const typed::multi_val &mv) const; + inline typed::set_list set_list() const; + inline typed::fixed_box simple_fixed_box_hull() const; + inline typed::space space() const; + inline typed::set subtract(const typed::set &set2) const; + inline typed::union_set subtract(const typed::union_set &uset2) const; + inline typed::set to_set() const; + inline typed::union_set to_union_set() const; + inline typed::map translation() const; + inline typed::set unbind_params(const typed::multi_id<> &tuple) const = delete; + template + inline typed::map unbind_params_insert_domain(const typed::multi_id &domain) const; + inline typed::set unite(const typed::basic_set &bset2) const; + inline typed::set unite(const typed::set &set2) const; + inline typed::union_set unite(const typed::union_set &uset2) const; + inline typed::set unite(const typed::point &bset2) const; + inline typed::map unwrap() const = delete; + inline typed::set upper_bound(const typed::multi_pw_aff &upper) const; + inline typed::set upper_bound(const typed::multi_val &upper) const; + inline typed::set wrapped_reverse() const = delete; +}; + +template +struct basic_set> : public isl::basic_set { + template + friend struct aff; + template + friend struct aff_list; + template + friend struct basic_map; + template + friend struct basic_set; + template + friend struct fixed_box; + template + friend struct id; + template + friend struct id_list; + template + friend struct map; + template + friend struct map_list; + template + friend struct multi_aff; + template + friend struct multi_id; + template + friend struct multi_pw_aff; + template + friend struct multi_union_pw_aff; + template + friend struct multi_val; + template + friend struct point; + template + friend struct pw_aff; + template + friend struct pw_aff_list; + template + friend struct pw_multi_aff; + template + friend struct pw_multi_aff_list; + template + friend struct set; + template + friend struct set_list; + template + friend struct space; + template + friend struct union_map; + template + friend struct union_pw_aff; + template + friend struct union_pw_aff_list; + template + friend struct union_pw_multi_aff; + template + friend struct union_set; + template + friend struct union_set_list; + template + friend struct val; + template + friend struct val_list; + + basic_set() = default; + template {} && + std::is_base_of{}, + bool>::type = true> + basic_set(const basic_set> &obj) : isl::basic_set(obj) {} + private: + template {}, bool>::type = true> + basic_set(const base &obj) : isl::basic_set(obj) {} + public: + static basic_set from(const isl::basic_set &obj) { + return basic_set(obj); + } + inline /* implicit */ basic_set(const typed::point> &pnt); + inline explicit basic_set(const isl::ctx &ctx, const std::string &str); + template + inline typed::basic_set apply(const typed::basic_map, Arg2> &bmap) const; + template + inline typed::set apply(const typed::map, Arg2> &map) const; + template + inline typed::union_set apply(const typed::union_map, Arg2> &umap) const; + inline typed::pw_multi_aff> as_pw_multi_aff() const; + inline typed::set> as_set() const; + inline typed::set<> bind(const typed::multi_id> &tuple) const; + inline typed::set> coalesce() const; + inline typed::basic_set> detect_equalities() const; + inline typed::set> drop_unused_params() const; + inline bool every_set(const std::function>)> &test) const; + inline typed::set> extract_set(const typed::space> &space) const; + inline void foreach_basic_set(const std::function>)> &fn) const; + inline void foreach_point(const std::function>)> &fn) const; + inline void foreach_set(const std::function>)> &fn) const; + inline typed::basic_set> gist(const typed::basic_set> &context) const; + inline typed::set> gist(const typed::set> &context) const; + inline typed::union_set> gist(const typed::union_set> &context) const; + inline typed::basic_set> gist(const typed::point> &context) const; + inline typed::set> gist_params(const typed::set<> &context) const; + inline typed::map, pair> identity() const; + inline typed::pw_aff, Anonymous> indicator_function() const; + template + inline typed::map> insert_domain(const typed::space &domain) const; + inline typed::basic_set> intersect(const typed::basic_set> &bset2) const; + inline typed::set> intersect(const typed::set> &set2) const; + inline typed::union_set> intersect(const typed::union_set> &uset2) const; + inline typed::basic_set> intersect(const typed::point> &bset2) const; + inline typed::basic_set> intersect_params(const typed::basic_set<> &bset2) const; + inline typed::set> intersect_params(const typed::set<> ¶ms) const; + inline typed::basic_set> intersect_params(const typed::point<> &bset2) const; + inline typed::fixed_box> lattice_tile() const; + inline typed::set> lexmax() const; + inline typed::pw_multi_aff> lexmax_pw_multi_aff() const; + inline typed::set> lexmin() const; + inline typed::pw_multi_aff> lexmin_pw_multi_aff() const; + inline typed::set> lower_bound(const typed::multi_pw_aff> &lower) const; + inline typed::set> lower_bound(const typed::multi_val> &lower) const; + inline typed::multi_pw_aff> max_multi_pw_aff() const; + inline typed::val> max_val(const typed::aff<> &obj) const = delete; + inline typed::multi_pw_aff> min_multi_pw_aff() const; + inline typed::val> min_val(const typed::aff<> &obj) const = delete; + inline typed::pw_aff, Anonymous> param_pw_aff_on_domain(const typed::id &id) const; + inline typed::pw_aff, Anonymous> param_pw_aff_on_domain(const std::string &id) const; + inline typed::basic_set<> params() const; + inline typed::multi_val> plain_multi_val_if_fixed() const; + template + inline typed::set preimage(const typed::multi_aff> &ma) const; + template + inline typed::set preimage(const typed::multi_pw_aff> &mpa) const; + template + inline typed::set preimage(const typed::pw_multi_aff> &pma) const; + template + inline typed::union_set preimage(const typed::union_pw_multi_aff> &upma) const; + template + inline typed::set, Arg2>> product(const typed::set &set2) const; + inline typed::set> project_out_all_params() const; + inline typed::set> project_out_param(const typed::id &id) const; + inline typed::set> project_out_param(const std::string &id) const; + inline typed::set> project_out_param(const typed::id_list &list) const; + inline typed::pw_aff, Anonymous> pw_aff_on_domain(const typed::val &v) const; + inline typed::pw_aff, Anonymous> pw_aff_on_domain(long v) const; + template + inline typed::pw_multi_aff, Arg2> pw_multi_aff_on_domain(const typed::multi_val &mv) const; + inline typed::set_list> set_list() const; + inline typed::fixed_box> simple_fixed_box_hull() const; + inline typed::space> space() const; + inline typed::set> subtract(const typed::set> &set2) const; + inline typed::union_set> subtract(const typed::union_set> &uset2) const; + inline typed::set> to_set() const; + inline typed::union_set> to_union_set() const; + inline typed::map, pair> translation() const; + inline typed::set> unbind_params(const typed::multi_id<> &tuple) const = delete; + template + inline typed::map> unbind_params_insert_domain(const typed::multi_id &domain) const; + inline typed::set> unite(const typed::basic_set> &bset2) const; + inline typed::set> unite(const typed::set> &set2) const; + inline typed::union_set> unite(const typed::union_set> &uset2) const; + inline typed::set> unite(const typed::point> &bset2) const; + inline typed::map unwrap() const; + inline typed::set> upper_bound(const typed::multi_pw_aff> &upper) const; + inline typed::set> upper_bound(const typed::multi_val> &upper) const; + inline typed::set> wrapped_reverse() const; +}; + +template +struct fixed_box : public isl::fixed_box { + template + friend struct aff; + template + friend struct aff_list; + template + friend struct basic_map; + template + friend struct basic_set; + template + friend struct fixed_box; + template + friend struct id; + template + friend struct id_list; + template + friend struct map; + template + friend struct map_list; + template + friend struct multi_aff; + template + friend struct multi_id; + template + friend struct multi_pw_aff; + template + friend struct multi_union_pw_aff; + template + friend struct multi_val; + template + friend struct point; + template + friend struct pw_aff; + template + friend struct pw_aff_list; + template + friend struct pw_multi_aff; + template + friend struct pw_multi_aff_list; + template + friend struct set; + template + friend struct set_list; + template + friend struct space; + template + friend struct union_map; + template + friend struct union_pw_aff; + template + friend struct union_pw_aff_list; + template + friend struct union_pw_multi_aff; + template + friend struct union_set; + template + friend struct union_set_list; + template + friend struct val; + template + friend struct val_list; + + fixed_box() = default; + template {}, + bool>::type = true> + fixed_box(const fixed_box &obj) : isl::fixed_box(obj) {} + private: + template {}, bool>::type = true> + fixed_box(const base &obj) : isl::fixed_box(obj) {} + public: + static fixed_box from(const isl::fixed_box &obj) { + return fixed_box(obj); + } + inline explicit fixed_box(const isl::ctx &ctx, const std::string &str); + inline typed::multi_aff offset() const; + inline typed::multi_aff get_offset() const = delete; + inline typed::multi_val size() const; + inline typed::multi_val get_size() const = delete; + inline typed::space space() const; + inline typed::space get_space() const = delete; +}; + +template +struct fixed_box : public isl::fixed_box { + template + friend struct aff; + template + friend struct aff_list; + template + friend struct basic_map; + template + friend struct basic_set; + template + friend struct fixed_box; + template + friend struct id; + template + friend struct id_list; + template + friend struct map; + template + friend struct map_list; + template + friend struct multi_aff; + template + friend struct multi_id; + template + friend struct multi_pw_aff; + template + friend struct multi_union_pw_aff; + template + friend struct multi_val; + template + friend struct point; + template + friend struct pw_aff; + template + friend struct pw_aff_list; + template + friend struct pw_multi_aff; + template + friend struct pw_multi_aff_list; + template + friend struct set; + template + friend struct set_list; + template + friend struct space; + template + friend struct union_map; + template + friend struct union_pw_aff; + template + friend struct union_pw_aff_list; + template + friend struct union_pw_multi_aff; + template + friend struct union_set; + template + friend struct union_set_list; + template + friend struct val; + template + friend struct val_list; + + fixed_box() = default; + template {} && + std::is_base_of{}, + bool>::type = true> + fixed_box(const fixed_box &obj) : isl::fixed_box(obj) {} + private: + template {}, bool>::type = true> + fixed_box(const base &obj) : isl::fixed_box(obj) {} + public: + static fixed_box from(const isl::fixed_box &obj) { + return fixed_box(obj); + } + inline explicit fixed_box(const isl::ctx &ctx, const std::string &str); + inline typed::multi_aff offset() const; + inline typed::multi_aff get_offset() const = delete; + inline typed::multi_val size() const; + inline typed::multi_val get_size() const = delete; + inline typed::space space() const; + inline typed::space get_space() const = delete; +}; + +template <> +struct id : public isl::id { + template + friend struct aff; + template + friend struct aff_list; + template + friend struct basic_map; + template + friend struct basic_set; + template + friend struct fixed_box; + template + friend struct id; + template + friend struct id_list; + template + friend struct map; + template + friend struct map_list; + template + friend struct multi_aff; + template + friend struct multi_id; + template + friend struct multi_pw_aff; + template + friend struct multi_union_pw_aff; + template + friend struct multi_val; + template + friend struct point; + template + friend struct pw_aff; + template + friend struct pw_aff_list; + template + friend struct pw_multi_aff; + template + friend struct pw_multi_aff_list; + template + friend struct set; + template + friend struct set_list; + template + friend struct space; + template + friend struct union_map; + template + friend struct union_pw_aff; + template + friend struct union_pw_aff_list; + template + friend struct union_pw_multi_aff; + template + friend struct union_set; + template + friend struct union_set_list; + template + friend struct val; + template + friend struct val_list; + + id() = default; + id(const isl::id &obj) : isl::id(obj) {} + static id from(const isl::id &obj) { + return id(obj); + } + inline explicit id(const isl::ctx &ctx, const std::string &str); + inline std::string get_name() const = delete; +}; + +template <> +struct id_list : public isl::id_list { + template + friend struct aff; + template + friend struct aff_list; + template + friend struct basic_map; + template + friend struct basic_set; + template + friend struct fixed_box; + template + friend struct id; + template + friend struct id_list; + template + friend struct map; + template + friend struct map_list; + template + friend struct multi_aff; + template + friend struct multi_id; + template + friend struct multi_pw_aff; + template + friend struct multi_union_pw_aff; + template + friend struct multi_val; + template + friend struct point; + template + friend struct pw_aff; + template + friend struct pw_aff_list; + template + friend struct pw_multi_aff; + template + friend struct pw_multi_aff_list; + template + friend struct set; + template + friend struct set_list; + template + friend struct space; + template + friend struct union_map; + template + friend struct union_pw_aff; + template + friend struct union_pw_aff_list; + template + friend struct union_pw_multi_aff; + template + friend struct union_set; + template + friend struct union_set_list; + template + friend struct val; + template + friend struct val_list; + + id_list() = default; + id_list(const isl::id_list &obj) : isl::id_list(obj) {} + static id_list from(const isl::id_list &obj) { + return id_list(obj); + } + inline explicit id_list(const isl::ctx &ctx, int n); + inline explicit id_list(const typed::id &el); + inline explicit id_list(const isl::ctx &ctx, const std::string &str); + inline typed::id_list add(const typed::id &el) const; + inline typed::id_list add(const std::string &el) const; + inline typed::id at(int index) const; + inline typed::id get_at(int index) const = delete; + inline typed::id_list drop(unsigned int first, unsigned int n) const; + inline void foreach(const std::function)> &fn) const; + inline void foreach_scc(const std::function, typed::id)> &follows, const std::function)> &fn) const; + inline typed::id_list set_at(int index, const typed::id &el) const; + inline typed::id_list set_at(int index, const std::string &el) const; +}; + +template +struct map : public isl::map { + template + friend struct aff; + template + friend struct aff_list; + template + friend struct basic_map; + template + friend struct basic_set; + template + friend struct fixed_box; + template + friend struct id; + template + friend struct id_list; + template + friend struct map; + template + friend struct map_list; + template + friend struct multi_aff; + template + friend struct multi_id; + template + friend struct multi_pw_aff; + template + friend struct multi_union_pw_aff; + template + friend struct multi_val; + template + friend struct point; + template + friend struct pw_aff; + template + friend struct pw_aff_list; + template + friend struct pw_multi_aff; + template + friend struct pw_multi_aff_list; + template + friend struct set; + template + friend struct set_list; + template + friend struct space; + template + friend struct union_map; + template + friend struct union_pw_aff; + template + friend struct union_pw_aff_list; + template + friend struct union_pw_multi_aff; + template + friend struct union_set; + template + friend struct union_set_list; + template + friend struct val; + template + friend struct val_list; + + map() = default; + template {} && + std::is_base_of{}, + bool>::type = true> + map(const map &obj) : isl::map(obj) {} + private: + template {}, bool>::type = true> + map(const base &obj) : isl::map(obj) {} + public: + static map from(const isl::map &obj) { + return map(obj); + } + inline /* implicit */ map(const typed::basic_map &bmap); + inline explicit map(const isl::ctx &ctx, const std::string &str); + template + inline typed::map apply_domain(const typed::map &map2) const; + template + inline typed::union_map apply_domain(const typed::union_map &umap2) const; + template + inline typed::map apply_domain(const typed::basic_map &map2) const; + template + inline typed::map apply_range(const typed::map &map2) const; + template + inline typed::union_map apply_range(const typed::union_map &umap2) const; + template + inline typed::map apply_range(const typed::basic_map &map2) const; + inline typed::map as_map() const; + inline typed::multi_union_pw_aff as_multi_union_pw_aff() const; + inline typed::pw_multi_aff as_pw_multi_aff() const; + inline typed::union_pw_multi_aff as_union_pw_multi_aff() const; + inline typed::set bind_domain(const typed::multi_id &tuple) const; + inline typed::set bind_range(const typed::multi_id &tuple) const; + inline typed::map coalesce() const; + inline typed::map curry() const = delete; + inline typed::set deltas() const = delete; + inline typed::map detect_equalities() const; + inline typed::set domain() const; + inline typed::map domain_factor_domain() const = delete; + inline typed::map domain_factor_range() const = delete; + inline typed::union_map, Domain> domain_map() const; + inline typed::union_pw_multi_aff, Domain> domain_map_union_pw_multi_aff() const; + template + inline typed::map, Range> domain_product(const typed::map &map2) const; + template + inline typed::union_map, Range> domain_product(const typed::union_map &umap2) const; + template + inline typed::map, Range> domain_product(const typed::basic_map &map2) const; + inline typed::map domain_reverse() const = delete; + inline typed::id get_domain_tuple_id() const = delete; + inline typed::map drop_unused_params() const; + inline typed::map eq_at(const typed::multi_pw_aff<> &mpa) const = delete; + inline typed::union_map eq_at(const typed::multi_union_pw_aff<> &mupa) const = delete; + inline typed::map eq_at(const typed::aff<> &mpa) const = delete; + inline typed::map eq_at(const typed::multi_aff<> &mpa) const = delete; + inline typed::map eq_at(const typed::pw_aff<> &mpa) const = delete; + inline typed::map eq_at(const typed::pw_multi_aff<> &mpa) const = delete; + inline bool every_map(const std::function)> &test) const; + inline typed::map extract_map(const typed::space &space) const; + inline typed::map flatten_domain() const = delete; + inline typed::map flatten_range() const = delete; + inline void foreach_basic_map(const std::function)> &fn) const; + inline void foreach_map(const std::function)> &fn) const; + inline typed::map gist(const typed::map &context) const; + inline typed::union_map gist(const typed::union_map &context) const; + inline typed::map gist(const typed::basic_map &context) const; + inline typed::map gist_domain(const typed::set &context) const; + inline typed::union_map gist_domain(const typed::union_set &uset) const; + inline typed::map gist_domain(const typed::basic_set &context) const; + inline typed::map gist_domain(const typed::point &context) const; + inline typed::map gist_params(const typed::set<> &context) const; + inline typed::map gist_params(const typed::basic_set<> &context) const; + inline typed::map gist_params(const typed::point<> &context) const; + inline typed::map intersect(const typed::map &map2) const; + inline typed::union_map intersect(const typed::union_map &umap2) const; + inline typed::map intersect(const typed::basic_map &map2) const; + inline typed::map intersect_domain(const typed::set &set) const; + inline typed::union_map intersect_domain(const typed::space &space) const; + inline typed::union_map intersect_domain(const typed::union_set &uset) const; + inline typed::map intersect_domain(const typed::basic_set &set) const; + inline typed::map intersect_domain(const typed::point &set) const; + inline typed::map intersect_domain_wrapped_domain(const typed::set<> &domain) const = delete; + inline typed::union_map intersect_domain_wrapped_domain(const typed::union_set<> &domain) const = delete; + inline typed::map intersect_domain_wrapped_domain(const typed::basic_set<> &domain) const = delete; + inline typed::map intersect_domain_wrapped_domain(const typed::point<> &domain) const = delete; + inline typed::map intersect_params(const typed::set<> ¶ms) const; + inline typed::map intersect_params(const typed::basic_set<> ¶ms) const; + inline typed::map intersect_params(const typed::point<> ¶ms) const; + inline typed::map intersect_range(const typed::set &set) const; + inline typed::union_map intersect_range(const typed::space &space) const; + inline typed::union_map intersect_range(const typed::union_set &uset) const; + inline typed::map intersect_range(const typed::basic_set &set) const; + inline typed::map intersect_range(const typed::point &set) const; + inline typed::map intersect_range_wrapped_domain(const typed::set<> &domain) const = delete; + inline typed::union_map intersect_range_wrapped_domain(const typed::union_set<> &domain) const = delete; + inline typed::map intersect_range_wrapped_domain(const typed::basic_set<> &domain) const = delete; + inline typed::map intersect_range_wrapped_domain(const typed::point<> &domain) const = delete; + inline typed::map lex_ge_at(const typed::multi_pw_aff<> &mpa) const = delete; + inline typed::map lex_ge_at(const typed::aff<> &mpa) const = delete; + inline typed::map lex_ge_at(const typed::multi_aff<> &mpa) const = delete; + inline typed::map lex_ge_at(const typed::pw_aff<> &mpa) const = delete; + inline typed::map lex_ge_at(const typed::pw_multi_aff<> &mpa) const = delete; + inline typed::map lex_gt_at(const typed::multi_pw_aff<> &mpa) const = delete; + inline typed::map lex_gt_at(const typed::aff<> &mpa) const = delete; + inline typed::map lex_gt_at(const typed::multi_aff<> &mpa) const = delete; + inline typed::map lex_gt_at(const typed::pw_aff<> &mpa) const = delete; + inline typed::map lex_gt_at(const typed::pw_multi_aff<> &mpa) const = delete; + inline typed::map lex_le_at(const typed::multi_pw_aff<> &mpa) const = delete; + inline typed::map lex_le_at(const typed::aff<> &mpa) const = delete; + inline typed::map lex_le_at(const typed::multi_aff<> &mpa) const = delete; + inline typed::map lex_le_at(const typed::pw_aff<> &mpa) const = delete; + inline typed::map lex_le_at(const typed::pw_multi_aff<> &mpa) const = delete; + inline typed::map lex_lt_at(const typed::multi_pw_aff<> &mpa) const = delete; + inline typed::map lex_lt_at(const typed::aff<> &mpa) const = delete; + inline typed::map lex_lt_at(const typed::multi_aff<> &mpa) const = delete; + inline typed::map lex_lt_at(const typed::pw_aff<> &mpa) const = delete; + inline typed::map lex_lt_at(const typed::pw_multi_aff<> &mpa) const = delete; + inline typed::map lexmax() const; + inline typed::pw_multi_aff lexmax_pw_multi_aff() const; + inline typed::map lexmin() const; + inline typed::pw_multi_aff lexmin_pw_multi_aff() const; + inline typed::map lower_bound(const typed::multi_pw_aff &lower) const; + inline typed::map lower_bound(const typed::aff &lower) const; + inline typed::map lower_bound(const typed::multi_aff &lower) const; + inline typed::map lower_bound(const typed::pw_aff &lower) const; + inline typed::map lower_bound(const typed::pw_multi_aff &lower) const; + inline typed::map_list map_list() const; + inline typed::multi_pw_aff max_multi_pw_aff() const; + inline typed::multi_pw_aff min_multi_pw_aff() const; + inline typed::set<> params() const; + template + inline typed::map preimage_domain(const typed::multi_aff &ma) const; + template + inline typed::map preimage_domain(const typed::multi_pw_aff &mpa) const; + template + inline typed::map preimage_domain(const typed::pw_multi_aff &pma) const; + template + inline typed::union_map preimage_domain(const typed::union_pw_multi_aff &upma) const; + template + inline typed::map preimage_range(const typed::multi_aff &ma) const; + template + inline typed::map preimage_range(const typed::pw_multi_aff &pma) const; + template + inline typed::union_map preimage_range(const typed::union_pw_multi_aff &upma) const; + template + inline typed::map, pair> product(const typed::map &map2) const; + template + inline typed::union_map, pair> product(const typed::union_map &umap2) const; + template + inline typed::map, pair> product(const typed::basic_map &map2) const; + inline typed::map project_out_all_params() const; + inline typed::map project_out_param(const typed::id &id) const; + inline typed::map project_out_param(const std::string &id) const; + inline typed::map project_out_param(const typed::id_list &list) const; + inline typed::set range() const; + inline typed::map range_factor_domain() const = delete; + inline typed::map range_factor_range() const = delete; + inline typed::fixed_box range_lattice_tile() const; + inline typed::fixed_box get_range_lattice_tile() const = delete; + inline typed::union_map, Range> range_map() const; + template + inline typed::map> range_product(const typed::map &map2) const; + template + inline typed::union_map> range_product(const typed::union_map &umap2) const; + template + inline typed::map> range_product(const typed::basic_map &map2) const; + inline typed::map range_reverse() const = delete; + inline typed::fixed_box range_simple_fixed_box_hull() const; + inline typed::fixed_box get_range_simple_fixed_box_hull() const = delete; + inline typed::id get_range_tuple_id() const = delete; + inline typed::map reverse() const; + template + inline typed::map set_domain_tuple(const typed::id &id) const; + template + inline typed::map set_domain_tuple(const std::string &id) const; + template + inline typed::map set_range_tuple(const typed::id &id) const; + template + inline typed::map set_range_tuple(const std::string &id) const; + inline typed::space space() const; + inline typed::space get_space() const = delete; + inline typed::map subtract(const typed::map &map2) const; + inline typed::union_map subtract(const typed::union_map &umap2) const; + inline typed::map subtract(const typed::basic_map &map2) const; + inline typed::union_map subtract_domain(const typed::union_set &dom) const; + inline typed::union_map subtract_range(const typed::union_set &dom) const; + inline typed::union_map to_union_map() const; + inline typed::map uncurry() const = delete; + inline typed::map unite(const typed::map &map2) const; + inline typed::union_map unite(const typed::union_map &umap2) const; + inline typed::map unite(const typed::basic_map &map2) const; + static inline typed::map universe(const typed::space &space); + inline typed::map upper_bound(const typed::multi_pw_aff &upper) const; + inline typed::map upper_bound(const typed::aff &upper) const; + inline typed::map upper_bound(const typed::multi_aff &upper) const; + inline typed::map upper_bound(const typed::pw_aff &upper) const; + inline typed::map upper_bound(const typed::pw_multi_aff &upper) const; + inline typed::set> wrap() const; +}; + +template +struct map, Range2> : public isl::map { + template + friend struct aff; + template + friend struct aff_list; + template + friend struct basic_map; + template + friend struct basic_set; + template + friend struct fixed_box; + template + friend struct id; + template + friend struct id_list; + template + friend struct map; + template + friend struct map_list; + template + friend struct multi_aff; + template + friend struct multi_id; + template + friend struct multi_pw_aff; + template + friend struct multi_union_pw_aff; + template + friend struct multi_val; + template + friend struct point; + template + friend struct pw_aff; + template + friend struct pw_aff_list; + template + friend struct pw_multi_aff; + template + friend struct pw_multi_aff_list; + template + friend struct set; + template + friend struct set_list; + template + friend struct space; + template + friend struct union_map; + template + friend struct union_pw_aff; + template + friend struct union_pw_aff_list; + template + friend struct union_pw_multi_aff; + template + friend struct union_set; + template + friend struct union_set_list; + template + friend struct val; + template + friend struct val_list; + + map() = default; + template {} && + std::is_base_of{} && + std::is_base_of{}, + bool>::type = true> + map(const map, Arg3> &obj) : isl::map(obj) {} + private: + template {}, bool>::type = true> + map(const base &obj) : isl::map(obj) {} + public: + static map from(const isl::map &obj) { + return map(obj); + } + inline /* implicit */ map(const typed::basic_map, Range2> &bmap); + inline explicit map(const isl::ctx &ctx, const std::string &str); + template + inline typed::map apply_domain(const typed::map, Domain2> &map2) const; + template + inline typed::union_map apply_domain(const typed::union_map, Domain2> &umap2) const; + template + inline typed::map apply_domain(const typed::basic_map, Domain2> &map2) const; + template + inline typed::map, Arg3> apply_range(const typed::map &map2) const; + template + inline typed::union_map, Arg3> apply_range(const typed::union_map &umap2) const; + template + inline typed::map, Arg3> apply_range(const typed::basic_map &map2) const; + inline typed::map, Range2> as_map() const; + inline typed::multi_union_pw_aff, Range2> as_multi_union_pw_aff() const; + inline typed::pw_multi_aff, Range2> as_pw_multi_aff() const; + inline typed::union_pw_multi_aff, Range2> as_union_pw_multi_aff() const; + inline typed::set bind_domain(const typed::multi_id> &tuple) const; + inline typed::set> bind_range(const typed::multi_id &tuple) const; + inline typed::map, Range2> coalesce() const; + inline typed::map> curry() const; + inline typed::set, Range2> deltas() const = delete; + inline typed::map, Range2> detect_equalities() const; + inline typed::set> domain() const; + inline typed::map domain_factor_domain() const; + inline typed::map domain_factor_range() const; + inline typed::union_map, Range2>, pair> domain_map() const; + inline typed::union_pw_multi_aff, Range2>, pair> domain_map_union_pw_multi_aff() const; + template + inline typed::map, Domain2>, Range2> domain_product(const typed::map &map2) const; + template + inline typed::union_map, Domain2>, Range2> domain_product(const typed::union_map &umap2) const; + template + inline typed::map, Domain2>, Range2> domain_product(const typed::basic_map &map2) const; + inline typed::map, Range2> domain_reverse() const; + inline typed::id, Range2> get_domain_tuple_id() const = delete; + inline typed::map, Range2> drop_unused_params() const; + inline typed::map, Range2> eq_at(const typed::multi_pw_aff<> &mpa) const = delete; + inline typed::union_map, Range2> eq_at(const typed::multi_union_pw_aff<> &mupa) const = delete; + inline typed::map, Range2> eq_at(const typed::aff<> &mpa) const = delete; + inline typed::map, Range2> eq_at(const typed::multi_aff<> &mpa) const = delete; + inline typed::map, Range2> eq_at(const typed::pw_aff<> &mpa) const = delete; + inline typed::map, Range2> eq_at(const typed::pw_multi_aff<> &mpa) const = delete; + inline bool every_map(const std::function, Range2>)> &test) const; + inline typed::map, Range2> extract_map(const typed::space, Range2> &space) const; + inline typed::map flatten_domain() const; + inline typed::map, Range2> flatten_range() const = delete; + inline void foreach_basic_map(const std::function, Range2>)> &fn) const; + inline void foreach_map(const std::function, Range2>)> &fn) const; + inline typed::map, Range2> gist(const typed::map, Range2> &context) const; + inline typed::union_map, Range2> gist(const typed::union_map, Range2> &context) const; + inline typed::map, Range2> gist(const typed::basic_map, Range2> &context) const; + inline typed::map, Range2> gist_domain(const typed::set> &context) const; + inline typed::union_map, Range2> gist_domain(const typed::union_set> &uset) const; + inline typed::map, Range2> gist_domain(const typed::basic_set> &context) const; + inline typed::map, Range2> gist_domain(const typed::point> &context) const; + inline typed::map, Range2> gist_params(const typed::set<> &context) const; + inline typed::map, Range2> gist_params(const typed::basic_set<> &context) const; + inline typed::map, Range2> gist_params(const typed::point<> &context) const; + inline typed::map, Range2> intersect(const typed::map, Range2> &map2) const; + inline typed::union_map, Range2> intersect(const typed::union_map, Range2> &umap2) const; + inline typed::map, Range2> intersect(const typed::basic_map, Range2> &map2) const; + inline typed::map, Range2> intersect_domain(const typed::set> &set) const; + inline typed::union_map, Range2> intersect_domain(const typed::space> &space) const; + inline typed::union_map, Range2> intersect_domain(const typed::union_set> &uset) const; + inline typed::map, Range2> intersect_domain(const typed::basic_set> &set) const; + inline typed::map, Range2> intersect_domain(const typed::point> &set) const; + inline typed::map, Range2> intersect_domain_wrapped_domain(const typed::set &domain) const; + inline typed::union_map, Range2> intersect_domain_wrapped_domain(const typed::union_set &domain) const; + inline typed::map, Range2> intersect_domain_wrapped_domain(const typed::basic_set &domain) const; + inline typed::map, Range2> intersect_domain_wrapped_domain(const typed::point &domain) const; + inline typed::map, Range2> intersect_params(const typed::set<> ¶ms) const; + inline typed::map, Range2> intersect_params(const typed::basic_set<> ¶ms) const; + inline typed::map, Range2> intersect_params(const typed::point<> ¶ms) const; + inline typed::map, Range2> intersect_range(const typed::set &set) const; + inline typed::union_map, Range2> intersect_range(const typed::space &space) const; + inline typed::union_map, Range2> intersect_range(const typed::union_set &uset) const; + inline typed::map, Range2> intersect_range(const typed::basic_set &set) const; + inline typed::map, Range2> intersect_range(const typed::point &set) const; + inline typed::map, Range2> intersect_range_wrapped_domain(const typed::set<> &domain) const = delete; + inline typed::union_map, Range2> intersect_range_wrapped_domain(const typed::union_set<> &domain) const = delete; + inline typed::map, Range2> intersect_range_wrapped_domain(const typed::basic_set<> &domain) const = delete; + inline typed::map, Range2> intersect_range_wrapped_domain(const typed::point<> &domain) const = delete; + inline typed::map, Range2> lex_ge_at(const typed::multi_pw_aff<> &mpa) const = delete; + inline typed::map, Range2> lex_ge_at(const typed::aff<> &mpa) const = delete; + inline typed::map, Range2> lex_ge_at(const typed::multi_aff<> &mpa) const = delete; + inline typed::map, Range2> lex_ge_at(const typed::pw_aff<> &mpa) const = delete; + inline typed::map, Range2> lex_ge_at(const typed::pw_multi_aff<> &mpa) const = delete; + inline typed::map, Range2> lex_gt_at(const typed::multi_pw_aff<> &mpa) const = delete; + inline typed::map, Range2> lex_gt_at(const typed::aff<> &mpa) const = delete; + inline typed::map, Range2> lex_gt_at(const typed::multi_aff<> &mpa) const = delete; + inline typed::map, Range2> lex_gt_at(const typed::pw_aff<> &mpa) const = delete; + inline typed::map, Range2> lex_gt_at(const typed::pw_multi_aff<> &mpa) const = delete; + inline typed::map, Range2> lex_le_at(const typed::multi_pw_aff<> &mpa) const = delete; + inline typed::map, Range2> lex_le_at(const typed::aff<> &mpa) const = delete; + inline typed::map, Range2> lex_le_at(const typed::multi_aff<> &mpa) const = delete; + inline typed::map, Range2> lex_le_at(const typed::pw_aff<> &mpa) const = delete; + inline typed::map, Range2> lex_le_at(const typed::pw_multi_aff<> &mpa) const = delete; + inline typed::map, Range2> lex_lt_at(const typed::multi_pw_aff<> &mpa) const = delete; + inline typed::map, Range2> lex_lt_at(const typed::aff<> &mpa) const = delete; + inline typed::map, Range2> lex_lt_at(const typed::multi_aff<> &mpa) const = delete; + inline typed::map, Range2> lex_lt_at(const typed::pw_aff<> &mpa) const = delete; + inline typed::map, Range2> lex_lt_at(const typed::pw_multi_aff<> &mpa) const = delete; + inline typed::map, Range2> lexmax() const; + inline typed::pw_multi_aff, Range2> lexmax_pw_multi_aff() const; + inline typed::map, Range2> lexmin() const; + inline typed::pw_multi_aff, Range2> lexmin_pw_multi_aff() const; + inline typed::map, Range2> lower_bound(const typed::multi_pw_aff, Range2> &lower) const; + inline typed::map, Range2> lower_bound(const typed::aff, Range2> &lower) const; + inline typed::map, Range2> lower_bound(const typed::multi_aff, Range2> &lower) const; + inline typed::map, Range2> lower_bound(const typed::pw_aff, Range2> &lower) const; + inline typed::map, Range2> lower_bound(const typed::pw_multi_aff, Range2> &lower) const; + inline typed::map_list, Range2> map_list() const; + inline typed::multi_pw_aff, Range2> max_multi_pw_aff() const; + inline typed::multi_pw_aff, Range2> min_multi_pw_aff() const; + inline typed::set<> params() const; + template + inline typed::map preimage_domain(const typed::multi_aff> &ma) const; + template + inline typed::map preimage_domain(const typed::multi_pw_aff> &mpa) const; + template + inline typed::map preimage_domain(const typed::pw_multi_aff> &pma) const; + template + inline typed::union_map preimage_domain(const typed::union_pw_multi_aff> &upma) const; + template + inline typed::map, Arg3> preimage_range(const typed::multi_aff &ma) const; + template + inline typed::map, Arg3> preimage_range(const typed::pw_multi_aff &pma) const; + template + inline typed::union_map, Arg3> preimage_range(const typed::union_pw_multi_aff &upma) const; + template + inline typed::map, Domain2>, pair> product(const typed::map &map2) const; + template + inline typed::union_map, Domain2>, pair> product(const typed::union_map &umap2) const; + template + inline typed::map, Domain2>, pair> product(const typed::basic_map &map2) const; + inline typed::map, Range2> project_out_all_params() const; + inline typed::map, Range2> project_out_param(const typed::id &id) const; + inline typed::map, Range2> project_out_param(const std::string &id) const; + inline typed::map, Range2> project_out_param(const typed::id_list &list) const; + inline typed::set range() const; + inline typed::map, Range2> range_factor_domain() const = delete; + inline typed::map, Range2> range_factor_range() const = delete; + inline typed::fixed_box, Range2> range_lattice_tile() const; + inline typed::fixed_box, Range2> get_range_lattice_tile() const = delete; + inline typed::union_map, Range2>, Range2> range_map() const; + template + inline typed::map, pair> range_product(const typed::map, Arg3> &map2) const; + template + inline typed::union_map, pair> range_product(const typed::union_map, Arg3> &umap2) const; + template + inline typed::map, pair> range_product(const typed::basic_map, Arg3> &map2) const; + inline typed::map, Range2> range_reverse() const = delete; + inline typed::fixed_box, Range2> range_simple_fixed_box_hull() const; + inline typed::fixed_box, Range2> get_range_simple_fixed_box_hull() const = delete; + inline typed::id, Range2> get_range_tuple_id() const = delete; + inline typed::map> reverse() const; + inline typed::map, Range2> set_domain_tuple(const typed::id<> &id) const = delete; + inline typed::map, Range2> set_domain_tuple(const std::string &id) const = delete; + template + inline typed::map, Arg2> set_range_tuple(const typed::id &id) const; + template + inline typed::map, Arg2> set_range_tuple(const std::string &id) const; + inline typed::space, Range2> space() const; + inline typed::space, Range2> get_space() const = delete; + inline typed::map, Range2> subtract(const typed::map, Range2> &map2) const; + inline typed::union_map, Range2> subtract(const typed::union_map, Range2> &umap2) const; + inline typed::map, Range2> subtract(const typed::basic_map, Range2> &map2) const; + inline typed::union_map, Range2> subtract_domain(const typed::union_set> &dom) const; + inline typed::union_map, Range2> subtract_range(const typed::union_set &dom) const; + inline typed::union_map, Range2> to_union_map() const; + inline typed::map, Range2> uncurry() const = delete; + inline typed::map, Range2> unite(const typed::map, Range2> &map2) const; + inline typed::union_map, Range2> unite(const typed::union_map, Range2> &umap2) const; + inline typed::map, Range2> unite(const typed::basic_map, Range2> &map2) const; + static inline typed::map, Range2> universe(const typed::space, Range2> &space); + inline typed::map, Range2> upper_bound(const typed::multi_pw_aff, Range2> &upper) const; + inline typed::map, Range2> upper_bound(const typed::aff, Range2> &upper) const; + inline typed::map, Range2> upper_bound(const typed::multi_aff, Range2> &upper) const; + inline typed::map, Range2> upper_bound(const typed::pw_aff, Range2> &upper) const; + inline typed::map, Range2> upper_bound(const typed::pw_multi_aff, Range2> &upper) const; + inline typed::set, Range2>> wrap() const; +}; + +template +struct map : public isl::map { + template + friend struct aff; + template + friend struct aff_list; + template + friend struct basic_map; + template + friend struct basic_set; + template + friend struct fixed_box; + template + friend struct id; + template + friend struct id_list; + template + friend struct map; + template + friend struct map_list; + template + friend struct multi_aff; + template + friend struct multi_id; + template + friend struct multi_pw_aff; + template + friend struct multi_union_pw_aff; + template + friend struct multi_val; + template + friend struct point; + template + friend struct pw_aff; + template + friend struct pw_aff_list; + template + friend struct pw_multi_aff; + template + friend struct pw_multi_aff_list; + template + friend struct set; + template + friend struct set_list; + template + friend struct space; + template + friend struct union_map; + template + friend struct union_pw_aff; + template + friend struct union_pw_aff_list; + template + friend struct union_pw_multi_aff; + template + friend struct union_set; + template + friend struct union_set_list; + template + friend struct val; + template + friend struct val_list; + + map() = default; + template {}, + bool>::type = true> + map(const map &obj) : isl::map(obj) {} + private: + template {}, bool>::type = true> + map(const base &obj) : isl::map(obj) {} + public: + static map from(const isl::map &obj) { + return map(obj); + } + inline /* implicit */ map(const typed::basic_map &bmap); + inline explicit map(const isl::ctx &ctx, const std::string &str); + template + inline typed::map apply_domain(const typed::map &map2) const; + template + inline typed::union_map apply_domain(const typed::union_map &umap2) const; + template + inline typed::map apply_domain(const typed::basic_map &map2) const; + template + inline typed::map apply_range(const typed::map &map2) const; + template + inline typed::union_map apply_range(const typed::union_map &umap2) const; + template + inline typed::map apply_range(const typed::basic_map &map2) const; + inline typed::map as_map() const; + inline typed::multi_union_pw_aff as_multi_union_pw_aff() const; + inline typed::pw_multi_aff as_pw_multi_aff() const; + inline typed::union_pw_multi_aff as_union_pw_multi_aff() const; + inline typed::set bind_domain(const typed::multi_id &tuple) const; + inline typed::set bind_range(const typed::multi_id &tuple) const; + inline typed::map coalesce() const; + inline typed::map curry() const = delete; + inline typed::set deltas() const; + inline typed::map detect_equalities() const; + inline typed::set domain() const; + inline typed::map domain_factor_domain() const = delete; + inline typed::map domain_factor_range() const = delete; + inline typed::union_map, Domain> domain_map() const; + inline typed::union_pw_multi_aff, Domain> domain_map_union_pw_multi_aff() const; + template + inline typed::map, Domain> domain_product(const typed::map &map2) const; + template + inline typed::union_map, Domain> domain_product(const typed::union_map &umap2) const; + template + inline typed::map, Domain> domain_product(const typed::basic_map &map2) const; + inline typed::map domain_reverse() const = delete; + inline typed::id get_domain_tuple_id() const = delete; + inline typed::map drop_unused_params() const; + template + inline typed::map eq_at(const typed::multi_pw_aff &mpa) const; + template + inline typed::union_map eq_at(const typed::multi_union_pw_aff &mupa) const; + inline typed::map eq_at(const typed::aff &mpa) const; + template + inline typed::map eq_at(const typed::multi_aff &mpa) const; + inline typed::map eq_at(const typed::pw_aff &mpa) const; + template + inline typed::map eq_at(const typed::pw_multi_aff &mpa) const; + inline bool every_map(const std::function)> &test) const; + inline typed::map extract_map(const typed::space &space) const; + inline typed::map flatten_domain() const = delete; + inline typed::map flatten_range() const = delete; + inline void foreach_basic_map(const std::function)> &fn) const; + inline void foreach_map(const std::function)> &fn) const; + inline typed::map gist(const typed::map &context) const; + inline typed::union_map gist(const typed::union_map &context) const; + inline typed::map gist(const typed::basic_map &context) const; + inline typed::map gist_domain(const typed::set &context) const; + inline typed::union_map gist_domain(const typed::union_set &uset) const; + inline typed::map gist_domain(const typed::basic_set &context) const; + inline typed::map gist_domain(const typed::point &context) const; + inline typed::map gist_params(const typed::set<> &context) const; + inline typed::map gist_params(const typed::basic_set<> &context) const; + inline typed::map gist_params(const typed::point<> &context) const; + inline typed::map intersect(const typed::map &map2) const; + inline typed::union_map intersect(const typed::union_map &umap2) const; + inline typed::map intersect(const typed::basic_map &map2) const; + inline typed::map intersect_domain(const typed::set &set) const; + inline typed::union_map intersect_domain(const typed::space &space) const; + inline typed::union_map intersect_domain(const typed::union_set &uset) const; + inline typed::map intersect_domain(const typed::basic_set &set) const; + inline typed::map intersect_domain(const typed::point &set) const; + inline typed::map intersect_domain_wrapped_domain(const typed::set<> &domain) const = delete; + inline typed::union_map intersect_domain_wrapped_domain(const typed::union_set<> &domain) const = delete; + inline typed::map intersect_domain_wrapped_domain(const typed::basic_set<> &domain) const = delete; + inline typed::map intersect_domain_wrapped_domain(const typed::point<> &domain) const = delete; + inline typed::map intersect_params(const typed::set<> ¶ms) const; + inline typed::map intersect_params(const typed::basic_set<> ¶ms) const; + inline typed::map intersect_params(const typed::point<> ¶ms) const; + inline typed::map intersect_range(const typed::set &set) const; + inline typed::union_map intersect_range(const typed::space &space) const; + inline typed::union_map intersect_range(const typed::union_set &uset) const; + inline typed::map intersect_range(const typed::basic_set &set) const; + inline typed::map intersect_range(const typed::point &set) const; + inline typed::map intersect_range_wrapped_domain(const typed::set<> &domain) const = delete; + inline typed::union_map intersect_range_wrapped_domain(const typed::union_set<> &domain) const = delete; + inline typed::map intersect_range_wrapped_domain(const typed::basic_set<> &domain) const = delete; + inline typed::map intersect_range_wrapped_domain(const typed::point<> &domain) const = delete; + template + inline typed::map lex_ge_at(const typed::multi_pw_aff &mpa) const; + inline typed::map lex_ge_at(const typed::aff &mpa) const; + template + inline typed::map lex_ge_at(const typed::multi_aff &mpa) const; + inline typed::map lex_ge_at(const typed::pw_aff &mpa) const; + template + inline typed::map lex_ge_at(const typed::pw_multi_aff &mpa) const; + template + inline typed::map lex_gt_at(const typed::multi_pw_aff &mpa) const; + inline typed::map lex_gt_at(const typed::aff &mpa) const; + template + inline typed::map lex_gt_at(const typed::multi_aff &mpa) const; + inline typed::map lex_gt_at(const typed::pw_aff &mpa) const; + template + inline typed::map lex_gt_at(const typed::pw_multi_aff &mpa) const; + template + inline typed::map lex_le_at(const typed::multi_pw_aff &mpa) const; + inline typed::map lex_le_at(const typed::aff &mpa) const; + template + inline typed::map lex_le_at(const typed::multi_aff &mpa) const; + inline typed::map lex_le_at(const typed::pw_aff &mpa) const; + template + inline typed::map lex_le_at(const typed::pw_multi_aff &mpa) const; + template + inline typed::map lex_lt_at(const typed::multi_pw_aff &mpa) const; + inline typed::map lex_lt_at(const typed::aff &mpa) const; + template + inline typed::map lex_lt_at(const typed::multi_aff &mpa) const; + inline typed::map lex_lt_at(const typed::pw_aff &mpa) const; + template + inline typed::map lex_lt_at(const typed::pw_multi_aff &mpa) const; + inline typed::map lexmax() const; + inline typed::pw_multi_aff lexmax_pw_multi_aff() const; + inline typed::map lexmin() const; + inline typed::pw_multi_aff lexmin_pw_multi_aff() const; + inline typed::map lower_bound(const typed::multi_pw_aff &lower) const; + inline typed::map lower_bound(const typed::aff &lower) const; + inline typed::map lower_bound(const typed::multi_aff &lower) const; + inline typed::map lower_bound(const typed::pw_aff &lower) const; + inline typed::map lower_bound(const typed::pw_multi_aff &lower) const; + inline typed::map_list map_list() const; + inline typed::multi_pw_aff max_multi_pw_aff() const; + inline typed::multi_pw_aff min_multi_pw_aff() const; + inline typed::set<> params() const; + template + inline typed::map preimage_domain(const typed::multi_aff &ma) const; + template + inline typed::map preimage_domain(const typed::multi_pw_aff &mpa) const; + template + inline typed::map preimage_domain(const typed::pw_multi_aff &pma) const; + template + inline typed::union_map preimage_domain(const typed::union_pw_multi_aff &upma) const; + template + inline typed::map preimage_range(const typed::multi_aff &ma) const; + template + inline typed::map preimage_range(const typed::pw_multi_aff &pma) const; + template + inline typed::union_map preimage_range(const typed::union_pw_multi_aff &upma) const; + template + inline typed::map, pair> product(const typed::map &map2) const; + template + inline typed::union_map, pair> product(const typed::union_map &umap2) const; + template + inline typed::map, pair> product(const typed::basic_map &map2) const; + inline typed::map project_out_all_params() const; + inline typed::map project_out_param(const typed::id &id) const; + inline typed::map project_out_param(const std::string &id) const; + inline typed::map project_out_param(const typed::id_list &list) const; + inline typed::set range() const; + inline typed::map range_factor_domain() const = delete; + inline typed::map range_factor_range() const = delete; + inline typed::fixed_box range_lattice_tile() const; + inline typed::fixed_box get_range_lattice_tile() const = delete; + inline typed::union_map, Domain> range_map() const; + template + inline typed::map> range_product(const typed::map &map2) const; + template + inline typed::union_map> range_product(const typed::union_map &umap2) const; + template + inline typed::map> range_product(const typed::basic_map &map2) const; + inline typed::map range_reverse() const = delete; + inline typed::fixed_box range_simple_fixed_box_hull() const; + inline typed::fixed_box get_range_simple_fixed_box_hull() const = delete; + inline typed::id get_range_tuple_id() const = delete; + inline typed::map reverse() const; + template + inline typed::map set_domain_tuple(const typed::id &id) const; + template + inline typed::map set_domain_tuple(const std::string &id) const; + template + inline typed::map set_range_tuple(const typed::id &id) const; + template + inline typed::map set_range_tuple(const std::string &id) const; + inline typed::space space() const; + inline typed::space get_space() const = delete; + inline typed::map subtract(const typed::map &map2) const; + inline typed::union_map subtract(const typed::union_map &umap2) const; + inline typed::map subtract(const typed::basic_map &map2) const; + inline typed::union_map subtract_domain(const typed::union_set &dom) const; + inline typed::union_map subtract_range(const typed::union_set &dom) const; + inline typed::union_map to_union_map() const; + inline typed::map uncurry() const = delete; + inline typed::map unite(const typed::map &map2) const; + inline typed::union_map unite(const typed::union_map &umap2) const; + inline typed::map unite(const typed::basic_map &map2) const; + static inline typed::map universe(const typed::space &space); + inline typed::map upper_bound(const typed::multi_pw_aff &upper) const; + inline typed::map upper_bound(const typed::aff &upper) const; + inline typed::map upper_bound(const typed::multi_aff &upper) const; + inline typed::map upper_bound(const typed::pw_aff &upper) const; + inline typed::map upper_bound(const typed::pw_multi_aff &upper) const; + inline typed::set> wrap() const; +}; + +template +struct map> : public isl::map { + template + friend struct aff; + template + friend struct aff_list; + template + friend struct basic_map; + template + friend struct basic_set; + template + friend struct fixed_box; + template + friend struct id; + template + friend struct id_list; + template + friend struct map; + template + friend struct map_list; + template + friend struct multi_aff; + template + friend struct multi_id; + template + friend struct multi_pw_aff; + template + friend struct multi_union_pw_aff; + template + friend struct multi_val; + template + friend struct point; + template + friend struct pw_aff; + template + friend struct pw_aff_list; + template + friend struct pw_multi_aff; + template + friend struct pw_multi_aff_list; + template + friend struct set; + template + friend struct set_list; + template + friend struct space; + template + friend struct union_map; + template + friend struct union_pw_aff; + template + friend struct union_pw_aff_list; + template + friend struct union_pw_multi_aff; + template + friend struct union_set; + template + friend struct union_set_list; + template + friend struct val; + template + friend struct val_list; + + map() = default; + template {} && + std::is_base_of{} && + std::is_base_of{}, + bool>::type = true> + map(const map> &obj) : isl::map(obj) {} + private: + template {}, bool>::type = true> + map(const base &obj) : isl::map(obj) {} + public: + static map from(const isl::map &obj) { + return map(obj); + } + inline /* implicit */ map(const typed::basic_map> &bmap); + inline explicit map(const isl::ctx &ctx, const std::string &str); + template + inline typed::map> apply_domain(const typed::map &map2) const; + template + inline typed::union_map> apply_domain(const typed::union_map &umap2) const; + template + inline typed::map> apply_domain(const typed::basic_map &map2) const; + template + inline typed::map apply_range(const typed::map, Arg3> &map2) const; + template + inline typed::union_map apply_range(const typed::union_map, Arg3> &umap2) const; + template + inline typed::map apply_range(const typed::basic_map, Arg3> &map2) const; + inline typed::map> as_map() const; + inline typed::multi_union_pw_aff> as_multi_union_pw_aff() const; + inline typed::pw_multi_aff> as_pw_multi_aff() const; + inline typed::union_pw_multi_aff> as_union_pw_multi_aff() const; + inline typed::set> bind_domain(const typed::multi_id &tuple) const; + inline typed::set bind_range(const typed::multi_id> &tuple) const; + inline typed::map> coalesce() const; + inline typed::map> curry() const = delete; + inline typed::set> deltas() const = delete; + inline typed::map> detect_equalities() const; + inline typed::set domain() const; + inline typed::map> domain_factor_domain() const = delete; + inline typed::map> domain_factor_range() const = delete; + inline typed::union_map>, Domain> domain_map() const; + inline typed::union_pw_multi_aff>, Domain> domain_map_union_pw_multi_aff() const; + template + inline typed::map, pair> domain_product(const typed::map> &map2) const; + template + inline typed::union_map, pair> domain_product(const typed::union_map> &umap2) const; + template + inline typed::map, pair> domain_product(const typed::basic_map> &map2) const; + inline typed::map> domain_reverse() const = delete; + inline typed::id> get_domain_tuple_id() const = delete; + inline typed::map> drop_unused_params() const; + inline typed::map> eq_at(const typed::multi_pw_aff<> &mpa) const = delete; + inline typed::union_map> eq_at(const typed::multi_union_pw_aff<> &mupa) const = delete; + inline typed::map> eq_at(const typed::aff<> &mpa) const = delete; + inline typed::map> eq_at(const typed::multi_aff<> &mpa) const = delete; + inline typed::map> eq_at(const typed::pw_aff<> &mpa) const = delete; + inline typed::map> eq_at(const typed::pw_multi_aff<> &mpa) const = delete; + inline bool every_map(const std::function>)> &test) const; + inline typed::map> extract_map(const typed::space> &space) const; + inline typed::map> flatten_domain() const = delete; + inline typed::map flatten_range() const; + inline void foreach_basic_map(const std::function>)> &fn) const; + inline void foreach_map(const std::function>)> &fn) const; + inline typed::map> gist(const typed::map> &context) const; + inline typed::union_map> gist(const typed::union_map> &context) const; + inline typed::map> gist(const typed::basic_map> &context) const; + inline typed::map> gist_domain(const typed::set &context) const; + inline typed::union_map> gist_domain(const typed::union_set &uset) const; + inline typed::map> gist_domain(const typed::basic_set &context) const; + inline typed::map> gist_domain(const typed::point &context) const; + inline typed::map> gist_params(const typed::set<> &context) const; + inline typed::map> gist_params(const typed::basic_set<> &context) const; + inline typed::map> gist_params(const typed::point<> &context) const; + inline typed::map> intersect(const typed::map> &map2) const; + inline typed::union_map> intersect(const typed::union_map> &umap2) const; + inline typed::map> intersect(const typed::basic_map> &map2) const; + inline typed::map> intersect_domain(const typed::set &set) const; + inline typed::union_map> intersect_domain(const typed::space &space) const; + inline typed::union_map> intersect_domain(const typed::union_set &uset) const; + inline typed::map> intersect_domain(const typed::basic_set &set) const; + inline typed::map> intersect_domain(const typed::point &set) const; + inline typed::map> intersect_domain_wrapped_domain(const typed::set<> &domain) const = delete; + inline typed::union_map> intersect_domain_wrapped_domain(const typed::union_set<> &domain) const = delete; + inline typed::map> intersect_domain_wrapped_domain(const typed::basic_set<> &domain) const = delete; + inline typed::map> intersect_domain_wrapped_domain(const typed::point<> &domain) const = delete; + inline typed::map> intersect_params(const typed::set<> ¶ms) const; + inline typed::map> intersect_params(const typed::basic_set<> ¶ms) const; + inline typed::map> intersect_params(const typed::point<> ¶ms) const; + inline typed::map> intersect_range(const typed::set> &set) const; + inline typed::union_map> intersect_range(const typed::space> &space) const; + inline typed::union_map> intersect_range(const typed::union_set> &uset) const; + inline typed::map> intersect_range(const typed::basic_set> &set) const; + inline typed::map> intersect_range(const typed::point> &set) const; + inline typed::map> intersect_range_wrapped_domain(const typed::set &domain) const; + inline typed::union_map> intersect_range_wrapped_domain(const typed::union_set &domain) const; + inline typed::map> intersect_range_wrapped_domain(const typed::basic_set &domain) const; + inline typed::map> intersect_range_wrapped_domain(const typed::point &domain) const; + inline typed::map> lex_ge_at(const typed::multi_pw_aff<> &mpa) const = delete; + inline typed::map> lex_ge_at(const typed::aff<> &mpa) const = delete; + inline typed::map> lex_ge_at(const typed::multi_aff<> &mpa) const = delete; + inline typed::map> lex_ge_at(const typed::pw_aff<> &mpa) const = delete; + inline typed::map> lex_ge_at(const typed::pw_multi_aff<> &mpa) const = delete; + inline typed::map> lex_gt_at(const typed::multi_pw_aff<> &mpa) const = delete; + inline typed::map> lex_gt_at(const typed::aff<> &mpa) const = delete; + inline typed::map> lex_gt_at(const typed::multi_aff<> &mpa) const = delete; + inline typed::map> lex_gt_at(const typed::pw_aff<> &mpa) const = delete; + inline typed::map> lex_gt_at(const typed::pw_multi_aff<> &mpa) const = delete; + inline typed::map> lex_le_at(const typed::multi_pw_aff<> &mpa) const = delete; + inline typed::map> lex_le_at(const typed::aff<> &mpa) const = delete; + inline typed::map> lex_le_at(const typed::multi_aff<> &mpa) const = delete; + inline typed::map> lex_le_at(const typed::pw_aff<> &mpa) const = delete; + inline typed::map> lex_le_at(const typed::pw_multi_aff<> &mpa) const = delete; + inline typed::map> lex_lt_at(const typed::multi_pw_aff<> &mpa) const = delete; + inline typed::map> lex_lt_at(const typed::aff<> &mpa) const = delete; + inline typed::map> lex_lt_at(const typed::multi_aff<> &mpa) const = delete; + inline typed::map> lex_lt_at(const typed::pw_aff<> &mpa) const = delete; + inline typed::map> lex_lt_at(const typed::pw_multi_aff<> &mpa) const = delete; + inline typed::map> lexmax() const; + inline typed::pw_multi_aff> lexmax_pw_multi_aff() const; + inline typed::map> lexmin() const; + inline typed::pw_multi_aff> lexmin_pw_multi_aff() const; + inline typed::map> lower_bound(const typed::multi_pw_aff> &lower) const; + inline typed::map> lower_bound(const typed::aff> &lower) const; + inline typed::map> lower_bound(const typed::multi_aff> &lower) const; + inline typed::map> lower_bound(const typed::pw_aff> &lower) const; + inline typed::map> lower_bound(const typed::pw_multi_aff> &lower) const; + inline typed::map_list> map_list() const; + inline typed::multi_pw_aff> max_multi_pw_aff() const; + inline typed::multi_pw_aff> min_multi_pw_aff() const; + inline typed::set<> params() const; + template + inline typed::map> preimage_domain(const typed::multi_aff &ma) const; + template + inline typed::map> preimage_domain(const typed::multi_pw_aff &mpa) const; + template + inline typed::map> preimage_domain(const typed::pw_multi_aff &pma) const; + template + inline typed::union_map> preimage_domain(const typed::union_pw_multi_aff &upma) const; + template + inline typed::map preimage_range(const typed::multi_aff> &ma) const; + template + inline typed::map preimage_range(const typed::pw_multi_aff> &pma) const; + template + inline typed::union_map preimage_range(const typed::union_pw_multi_aff> &upma) const; + template + inline typed::map, pair, Arg3>> product(const typed::map &map2) const; + template + inline typed::union_map, pair, Arg3>> product(const typed::union_map &umap2) const; + template + inline typed::map, pair, Arg3>> product(const typed::basic_map &map2) const; + inline typed::map> project_out_all_params() const; + inline typed::map> project_out_param(const typed::id &id) const; + inline typed::map> project_out_param(const std::string &id) const; + inline typed::map> project_out_param(const typed::id_list &list) const; + inline typed::set> range() const; + inline typed::map range_factor_domain() const; + inline typed::map range_factor_range() const; + inline typed::fixed_box> range_lattice_tile() const; + inline typed::fixed_box> get_range_lattice_tile() const = delete; + inline typed::union_map>, pair> range_map() const; + template + inline typed::map, Arg3>> range_product(const typed::map &map2) const; + template + inline typed::union_map, Arg3>> range_product(const typed::union_map &umap2) const; + template + inline typed::map, Arg3>> range_product(const typed::basic_map &map2) const; + inline typed::map> range_reverse() const; + inline typed::fixed_box> range_simple_fixed_box_hull() const; + inline typed::fixed_box> get_range_simple_fixed_box_hull() const = delete; + inline typed::id> get_range_tuple_id() const = delete; + inline typed::map, Domain> reverse() const; + template + inline typed::map> set_domain_tuple(const typed::id &id) const; + template + inline typed::map> set_domain_tuple(const std::string &id) const; + inline typed::map> set_range_tuple(const typed::id<> &id) const = delete; + inline typed::map> set_range_tuple(const std::string &id) const = delete; + inline typed::space> space() const; + inline typed::space> get_space() const = delete; + inline typed::map> subtract(const typed::map> &map2) const; + inline typed::union_map> subtract(const typed::union_map> &umap2) const; + inline typed::map> subtract(const typed::basic_map> &map2) const; + inline typed::union_map> subtract_domain(const typed::union_set &dom) const; + inline typed::union_map> subtract_range(const typed::union_set> &dom) const; + inline typed::union_map> to_union_map() const; + inline typed::map, Range2> uncurry() const; + inline typed::map> unite(const typed::map> &map2) const; + inline typed::union_map> unite(const typed::union_map> &umap2) const; + inline typed::map> unite(const typed::basic_map> &map2) const; + static inline typed::map> universe(const typed::space> &space); + inline typed::map> upper_bound(const typed::multi_pw_aff> &upper) const; + inline typed::map> upper_bound(const typed::aff> &upper) const; + inline typed::map> upper_bound(const typed::multi_aff> &upper) const; + inline typed::map> upper_bound(const typed::pw_aff> &upper) const; + inline typed::map> upper_bound(const typed::pw_multi_aff> &upper) const; + inline typed::set>> wrap() const; +}; + +template +struct map, pair> : public isl::map { + template + friend struct aff; + template + friend struct aff_list; + template + friend struct basic_map; + template + friend struct basic_set; + template + friend struct fixed_box; + template + friend struct id; + template + friend struct id_list; + template + friend struct map; + template + friend struct map_list; + template + friend struct multi_aff; + template + friend struct multi_id; + template + friend struct multi_pw_aff; + template + friend struct multi_union_pw_aff; + template + friend struct multi_val; + template + friend struct point; + template + friend struct pw_aff; + template + friend struct pw_aff_list; + template + friend struct pw_multi_aff; + template + friend struct pw_multi_aff_list; + template + friend struct set; + template + friend struct set_list; + template + friend struct space; + template + friend struct union_map; + template + friend struct union_pw_aff; + template + friend struct union_pw_aff_list; + template + friend struct union_pw_multi_aff; + template + friend struct union_set; + template + friend struct union_set_list; + template + friend struct val; + template + friend struct val_list; + + map() = default; + template {} && + std::is_base_of{}, + bool>::type = true> + map(const map, pair> &obj) : isl::map(obj) {} + private: + template {}, bool>::type = true> + map(const base &obj) : isl::map(obj) {} + public: + static map from(const isl::map &obj) { + return map(obj); + } + inline /* implicit */ map(const typed::basic_map, pair> &bmap); + inline explicit map(const isl::ctx &ctx, const std::string &str); + template + inline typed::map> apply_domain(const typed::map, Domain2> &map2) const; + template + inline typed::union_map> apply_domain(const typed::union_map, Domain2> &umap2) const; + template + inline typed::map> apply_domain(const typed::basic_map, Domain2> &map2) const; + template + inline typed::map, Range2> apply_range(const typed::map, Range2> &map2) const; + template + inline typed::union_map, Range2> apply_range(const typed::union_map, Range2> &umap2) const; + template + inline typed::map, Range2> apply_range(const typed::basic_map, Range2> &map2) const; + inline typed::map, pair> as_map() const; + inline typed::multi_union_pw_aff, pair> as_multi_union_pw_aff() const; + inline typed::pw_multi_aff, pair> as_pw_multi_aff() const; + inline typed::union_pw_multi_aff, pair> as_union_pw_multi_aff() const; + inline typed::set> bind_domain(const typed::multi_id> &tuple) const; + inline typed::set> bind_range(const typed::multi_id> &tuple) const; + inline typed::map, pair> coalesce() const; + inline typed::map>> curry() const; + inline typed::set> deltas() const; + inline typed::map, pair> detect_equalities() const; + inline typed::set> domain() const; + inline typed::map> domain_factor_domain() const; + inline typed::map> domain_factor_range() const; + inline typed::union_map, pair>, pair> domain_map() const; + inline typed::union_pw_multi_aff, pair>, pair> domain_map_union_pw_multi_aff() const; + template + inline typed::map, Domain2>, pair> domain_product(const typed::map> &map2) const; + template + inline typed::union_map, Domain2>, pair> domain_product(const typed::union_map> &umap2) const; + template + inline typed::map, Domain2>, pair> domain_product(const typed::basic_map> &map2) const; + inline typed::map, pair> domain_reverse() const; + inline typed::id, pair> get_domain_tuple_id() const = delete; + inline typed::map, pair> drop_unused_params() const; + template + inline typed::map, pair> eq_at(const typed::multi_pw_aff, Range> &mpa) const; + template + inline typed::union_map, pair> eq_at(const typed::multi_union_pw_aff, Range> &mupa) const; + inline typed::map, pair> eq_at(const typed::aff, Anonymous> &mpa) const; + template + inline typed::map, pair> eq_at(const typed::multi_aff, Range> &mpa) const; + inline typed::map, pair> eq_at(const typed::pw_aff, Anonymous> &mpa) const; + template + inline typed::map, pair> eq_at(const typed::pw_multi_aff, Range> &mpa) const; + inline bool every_map(const std::function, pair>)> &test) const; + inline typed::map, pair> extract_map(const typed::space, pair> &space) const; + inline typed::map> flatten_domain() const; + inline typed::map, Anonymous> flatten_range() const; + inline void foreach_basic_map(const std::function, pair>)> &fn) const; + inline void foreach_map(const std::function, pair>)> &fn) const; + inline typed::map, pair> gist(const typed::map, pair> &context) const; + inline typed::union_map, pair> gist(const typed::union_map, pair> &context) const; + inline typed::map, pair> gist(const typed::basic_map, pair> &context) const; + inline typed::map, pair> gist_domain(const typed::set> &context) const; + inline typed::union_map, pair> gist_domain(const typed::union_set> &uset) const; + inline typed::map, pair> gist_domain(const typed::basic_set> &context) const; + inline typed::map, pair> gist_domain(const typed::point> &context) const; + inline typed::map, pair> gist_params(const typed::set<> &context) const; + inline typed::map, pair> gist_params(const typed::basic_set<> &context) const; + inline typed::map, pair> gist_params(const typed::point<> &context) const; + inline typed::map, pair> intersect(const typed::map, pair> &map2) const; + inline typed::union_map, pair> intersect(const typed::union_map, pair> &umap2) const; + inline typed::map, pair> intersect(const typed::basic_map, pair> &map2) const; + inline typed::map, pair> intersect_domain(const typed::set> &set) const; + inline typed::union_map, pair> intersect_domain(const typed::space> &space) const; + inline typed::union_map, pair> intersect_domain(const typed::union_set> &uset) const; + inline typed::map, pair> intersect_domain(const typed::basic_set> &set) const; + inline typed::map, pair> intersect_domain(const typed::point> &set) const; + inline typed::map, pair> intersect_domain_wrapped_domain(const typed::set &domain) const; + inline typed::union_map, pair> intersect_domain_wrapped_domain(const typed::union_set &domain) const; + inline typed::map, pair> intersect_domain_wrapped_domain(const typed::basic_set &domain) const; + inline typed::map, pair> intersect_domain_wrapped_domain(const typed::point &domain) const; + inline typed::map, pair> intersect_params(const typed::set<> ¶ms) const; + inline typed::map, pair> intersect_params(const typed::basic_set<> ¶ms) const; + inline typed::map, pair> intersect_params(const typed::point<> ¶ms) const; + inline typed::map, pair> intersect_range(const typed::set> &set) const; + inline typed::union_map, pair> intersect_range(const typed::space> &space) const; + inline typed::union_map, pair> intersect_range(const typed::union_set> &uset) const; + inline typed::map, pair> intersect_range(const typed::basic_set> &set) const; + inline typed::map, pair> intersect_range(const typed::point> &set) const; + inline typed::map, pair> intersect_range_wrapped_domain(const typed::set &domain) const; + inline typed::union_map, pair> intersect_range_wrapped_domain(const typed::union_set &domain) const; + inline typed::map, pair> intersect_range_wrapped_domain(const typed::basic_set &domain) const; + inline typed::map, pair> intersect_range_wrapped_domain(const typed::point &domain) const; + template + inline typed::map, pair> lex_ge_at(const typed::multi_pw_aff, Range> &mpa) const; + inline typed::map, pair> lex_ge_at(const typed::aff, Anonymous> &mpa) const; + template + inline typed::map, pair> lex_ge_at(const typed::multi_aff, Range> &mpa) const; + inline typed::map, pair> lex_ge_at(const typed::pw_aff, Anonymous> &mpa) const; + template + inline typed::map, pair> lex_ge_at(const typed::pw_multi_aff, Range> &mpa) const; + template + inline typed::map, pair> lex_gt_at(const typed::multi_pw_aff, Range> &mpa) const; + inline typed::map, pair> lex_gt_at(const typed::aff, Anonymous> &mpa) const; + template + inline typed::map, pair> lex_gt_at(const typed::multi_aff, Range> &mpa) const; + inline typed::map, pair> lex_gt_at(const typed::pw_aff, Anonymous> &mpa) const; + template + inline typed::map, pair> lex_gt_at(const typed::pw_multi_aff, Range> &mpa) const; + template + inline typed::map, pair> lex_le_at(const typed::multi_pw_aff, Range> &mpa) const; + inline typed::map, pair> lex_le_at(const typed::aff, Anonymous> &mpa) const; + template + inline typed::map, pair> lex_le_at(const typed::multi_aff, Range> &mpa) const; + inline typed::map, pair> lex_le_at(const typed::pw_aff, Anonymous> &mpa) const; + template + inline typed::map, pair> lex_le_at(const typed::pw_multi_aff, Range> &mpa) const; + template + inline typed::map, pair> lex_lt_at(const typed::multi_pw_aff, Range> &mpa) const; + inline typed::map, pair> lex_lt_at(const typed::aff, Anonymous> &mpa) const; + template + inline typed::map, pair> lex_lt_at(const typed::multi_aff, Range> &mpa) const; + inline typed::map, pair> lex_lt_at(const typed::pw_aff, Anonymous> &mpa) const; + template + inline typed::map, pair> lex_lt_at(const typed::pw_multi_aff, Range> &mpa) const; + inline typed::map, pair> lexmax() const; + inline typed::pw_multi_aff, pair> lexmax_pw_multi_aff() const; + inline typed::map, pair> lexmin() const; + inline typed::pw_multi_aff, pair> lexmin_pw_multi_aff() const; + inline typed::map, pair> lower_bound(const typed::multi_pw_aff, pair> &lower) const; + inline typed::map, pair> lower_bound(const typed::aff, pair> &lower) const; + inline typed::map, pair> lower_bound(const typed::multi_aff, pair> &lower) const; + inline typed::map, pair> lower_bound(const typed::pw_aff, pair> &lower) const; + inline typed::map, pair> lower_bound(const typed::pw_multi_aff, pair> &lower) const; + inline typed::map_list, pair> map_list() const; + inline typed::multi_pw_aff, pair> max_multi_pw_aff() const; + inline typed::multi_pw_aff, pair> min_multi_pw_aff() const; + inline typed::set<> params() const; + template + inline typed::map> preimage_domain(const typed::multi_aff> &ma) const; + template + inline typed::map> preimage_domain(const typed::multi_pw_aff> &mpa) const; + template + inline typed::map> preimage_domain(const typed::pw_multi_aff> &pma) const; + template + inline typed::union_map> preimage_domain(const typed::union_pw_multi_aff> &upma) const; + template + inline typed::map, Range2> preimage_range(const typed::multi_aff> &ma) const; + template + inline typed::map, Range2> preimage_range(const typed::pw_multi_aff> &pma) const; + template + inline typed::union_map, Range2> preimage_range(const typed::union_pw_multi_aff> &upma) const; + template + inline typed::map, Domain2>, pair, Range2>> product(const typed::map &map2) const; + template + inline typed::union_map, Domain2>, pair, Range2>> product(const typed::union_map &umap2) const; + template + inline typed::map, Domain2>, pair, Range2>> product(const typed::basic_map &map2) const; + inline typed::map, pair> project_out_all_params() const; + inline typed::map, pair> project_out_param(const typed::id &id) const; + inline typed::map, pair> project_out_param(const std::string &id) const; + inline typed::map, pair> project_out_param(const typed::id_list &list) const; + inline typed::set> range() const; + inline typed::map, T1> range_factor_domain() const; + inline typed::map, T2> range_factor_range() const; + inline typed::fixed_box, pair> range_lattice_tile() const; + inline typed::fixed_box, pair> get_range_lattice_tile() const = delete; + inline typed::union_map, pair>, pair> range_map() const; + template + inline typed::map, pair, Range2>> range_product(const typed::map, Range2> &map2) const; + template + inline typed::union_map, pair, Range2>> range_product(const typed::union_map, Range2> &umap2) const; + template + inline typed::map, pair, Range2>> range_product(const typed::basic_map, Range2> &map2) const; + inline typed::map, pair> range_reverse() const; + inline typed::fixed_box, pair> range_simple_fixed_box_hull() const; + inline typed::fixed_box, pair> get_range_simple_fixed_box_hull() const = delete; + inline typed::id, pair> get_range_tuple_id() const = delete; + inline typed::map, pair> reverse() const; + inline typed::map, pair> set_domain_tuple(const typed::id<> &id) const = delete; + inline typed::map, pair> set_domain_tuple(const std::string &id) const = delete; + inline typed::map, pair> set_range_tuple(const typed::id<> &id) const = delete; + inline typed::map, pair> set_range_tuple(const std::string &id) const = delete; + inline typed::space, pair> space() const; + inline typed::space, pair> get_space() const = delete; + inline typed::map, pair> subtract(const typed::map, pair> &map2) const; + inline typed::union_map, pair> subtract(const typed::union_map, pair> &umap2) const; + inline typed::map, pair> subtract(const typed::basic_map, pair> &map2) const; + inline typed::union_map, pair> subtract_domain(const typed::union_set> &dom) const; + inline typed::union_map, pair> subtract_range(const typed::union_set> &dom) const; + inline typed::union_map, pair> to_union_map() const; + inline typed::map, T1>, T2> uncurry() const; + inline typed::map, pair> unite(const typed::map, pair> &map2) const; + inline typed::union_map, pair> unite(const typed::union_map, pair> &umap2) const; + inline typed::map, pair> unite(const typed::basic_map, pair> &map2) const; + static inline typed::map, pair> universe(const typed::space, pair> &space); + inline typed::map, pair> upper_bound(const typed::multi_pw_aff, pair> &upper) const; + inline typed::map, pair> upper_bound(const typed::aff, pair> &upper) const; + inline typed::map, pair> upper_bound(const typed::multi_aff, pair> &upper) const; + inline typed::map, pair> upper_bound(const typed::pw_aff, pair> &upper) const; + inline typed::map, pair> upper_bound(const typed::pw_multi_aff, pair> &upper) const; + inline typed::set, pair>> wrap() const; +}; + +template +struct map, pair> : public isl::map { + template + friend struct aff; + template + friend struct aff_list; + template + friend struct basic_map; + template + friend struct basic_set; + template + friend struct fixed_box; + template + friend struct id; + template + friend struct id_list; + template + friend struct map; + template + friend struct map_list; + template + friend struct multi_aff; + template + friend struct multi_id; + template + friend struct multi_pw_aff; + template + friend struct multi_union_pw_aff; + template + friend struct multi_val; + template + friend struct point; + template + friend struct pw_aff; + template + friend struct pw_aff_list; + template + friend struct pw_multi_aff; + template + friend struct pw_multi_aff_list; + template + friend struct set; + template + friend struct set_list; + template + friend struct space; + template + friend struct union_map; + template + friend struct union_pw_aff; + template + friend struct union_pw_aff_list; + template + friend struct union_pw_multi_aff; + template + friend struct union_set; + template + friend struct union_set_list; + template + friend struct val; + template + friend struct val_list; + + map() = default; + template {} && + std::is_base_of{} && + std::is_base_of{} && + std::is_base_of{}, + bool>::type = true> + map(const map, pair> &obj) : isl::map(obj) {} + private: + template {}, bool>::type = true> + map(const base &obj) : isl::map(obj) {} + public: + static map from(const isl::map &obj) { + return map(obj); + } + inline /* implicit */ map(const typed::basic_map, pair> &bmap); + inline explicit map(const isl::ctx &ctx, const std::string &str); + template + inline typed::map> apply_domain(const typed::map, Domain2> &map2) const; + template + inline typed::union_map> apply_domain(const typed::union_map, Domain2> &umap2) const; + template + inline typed::map> apply_domain(const typed::basic_map, Domain2> &map2) const; + template + inline typed::map, Arg2> apply_range(const typed::map, Arg2> &map2) const; + template + inline typed::union_map, Arg2> apply_range(const typed::union_map, Arg2> &umap2) const; + template + inline typed::map, Arg2> apply_range(const typed::basic_map, Arg2> &map2) const; + inline typed::map, pair> as_map() const; + inline typed::multi_union_pw_aff, pair> as_multi_union_pw_aff() const; + inline typed::pw_multi_aff, pair> as_pw_multi_aff() const; + inline typed::union_pw_multi_aff, pair> as_union_pw_multi_aff() const; + inline typed::set> bind_domain(const typed::multi_id> &tuple) const; + inline typed::set> bind_range(const typed::multi_id> &tuple) const; + inline typed::map, pair> coalesce() const; + inline typed::map>> curry() const; + inline typed::set, pair> deltas() const = delete; + inline typed::map, pair> detect_equalities() const; + inline typed::set> domain() const; + inline typed::map> domain_factor_domain() const; + inline typed::map> domain_factor_range() const; + inline typed::union_map, pair>, pair> domain_map() const; + inline typed::union_pw_multi_aff, pair>, pair> domain_map_union_pw_multi_aff() const; + template + inline typed::map, Domain2>, pair> domain_product(const typed::map> &map2) const; + template + inline typed::union_map, Domain2>, pair> domain_product(const typed::union_map> &umap2) const; + template + inline typed::map, Domain2>, pair> domain_product(const typed::basic_map> &map2) const; + inline typed::map, pair> domain_reverse() const; + inline typed::id, pair> get_domain_tuple_id() const = delete; + inline typed::map, pair> drop_unused_params() const; + inline typed::map, pair> eq_at(const typed::multi_pw_aff<> &mpa) const = delete; + inline typed::union_map, pair> eq_at(const typed::multi_union_pw_aff<> &mupa) const = delete; + inline typed::map, pair> eq_at(const typed::aff<> &mpa) const = delete; + inline typed::map, pair> eq_at(const typed::multi_aff<> &mpa) const = delete; + inline typed::map, pair> eq_at(const typed::pw_aff<> &mpa) const = delete; + inline typed::map, pair> eq_at(const typed::pw_multi_aff<> &mpa) const = delete; + inline bool every_map(const std::function, pair>)> &test) const; + inline typed::map, pair> extract_map(const typed::space, pair> &space) const; + inline typed::map> flatten_domain() const; + inline typed::map, Anonymous> flatten_range() const; + inline void foreach_basic_map(const std::function, pair>)> &fn) const; + inline void foreach_map(const std::function, pair>)> &fn) const; + inline typed::map, pair> gist(const typed::map, pair> &context) const; + inline typed::union_map, pair> gist(const typed::union_map, pair> &context) const; + inline typed::map, pair> gist(const typed::basic_map, pair> &context) const; + inline typed::map, pair> gist_domain(const typed::set> &context) const; + inline typed::union_map, pair> gist_domain(const typed::union_set> &uset) const; + inline typed::map, pair> gist_domain(const typed::basic_set> &context) const; + inline typed::map, pair> gist_domain(const typed::point> &context) const; + inline typed::map, pair> gist_params(const typed::set<> &context) const; + inline typed::map, pair> gist_params(const typed::basic_set<> &context) const; + inline typed::map, pair> gist_params(const typed::point<> &context) const; + inline typed::map, pair> intersect(const typed::map, pair> &map2) const; + inline typed::union_map, pair> intersect(const typed::union_map, pair> &umap2) const; + inline typed::map, pair> intersect(const typed::basic_map, pair> &map2) const; + inline typed::map, pair> intersect_domain(const typed::set> &set) const; + inline typed::union_map, pair> intersect_domain(const typed::space> &space) const; + inline typed::union_map, pair> intersect_domain(const typed::union_set> &uset) const; + inline typed::map, pair> intersect_domain(const typed::basic_set> &set) const; + inline typed::map, pair> intersect_domain(const typed::point> &set) const; + inline typed::map, pair> intersect_domain_wrapped_domain(const typed::set &domain) const; + inline typed::union_map, pair> intersect_domain_wrapped_domain(const typed::union_set &domain) const; + inline typed::map, pair> intersect_domain_wrapped_domain(const typed::basic_set &domain) const; + inline typed::map, pair> intersect_domain_wrapped_domain(const typed::point &domain) const; + inline typed::map, pair> intersect_params(const typed::set<> ¶ms) const; + inline typed::map, pair> intersect_params(const typed::basic_set<> ¶ms) const; + inline typed::map, pair> intersect_params(const typed::point<> ¶ms) const; + inline typed::map, pair> intersect_range(const typed::set> &set) const; + inline typed::union_map, pair> intersect_range(const typed::space> &space) const; + inline typed::union_map, pair> intersect_range(const typed::union_set> &uset) const; + inline typed::map, pair> intersect_range(const typed::basic_set> &set) const; + inline typed::map, pair> intersect_range(const typed::point> &set) const; + inline typed::map, pair> intersect_range_wrapped_domain(const typed::set &domain) const; + inline typed::union_map, pair> intersect_range_wrapped_domain(const typed::union_set &domain) const; + inline typed::map, pair> intersect_range_wrapped_domain(const typed::basic_set &domain) const; + inline typed::map, pair> intersect_range_wrapped_domain(const typed::point &domain) const; + inline typed::map, pair> lex_ge_at(const typed::multi_pw_aff<> &mpa) const = delete; + inline typed::map, pair> lex_ge_at(const typed::aff<> &mpa) const = delete; + inline typed::map, pair> lex_ge_at(const typed::multi_aff<> &mpa) const = delete; + inline typed::map, pair> lex_ge_at(const typed::pw_aff<> &mpa) const = delete; + inline typed::map, pair> lex_ge_at(const typed::pw_multi_aff<> &mpa) const = delete; + inline typed::map, pair> lex_gt_at(const typed::multi_pw_aff<> &mpa) const = delete; + inline typed::map, pair> lex_gt_at(const typed::aff<> &mpa) const = delete; + inline typed::map, pair> lex_gt_at(const typed::multi_aff<> &mpa) const = delete; + inline typed::map, pair> lex_gt_at(const typed::pw_aff<> &mpa) const = delete; + inline typed::map, pair> lex_gt_at(const typed::pw_multi_aff<> &mpa) const = delete; + inline typed::map, pair> lex_le_at(const typed::multi_pw_aff<> &mpa) const = delete; + inline typed::map, pair> lex_le_at(const typed::aff<> &mpa) const = delete; + inline typed::map, pair> lex_le_at(const typed::multi_aff<> &mpa) const = delete; + inline typed::map, pair> lex_le_at(const typed::pw_aff<> &mpa) const = delete; + inline typed::map, pair> lex_le_at(const typed::pw_multi_aff<> &mpa) const = delete; + inline typed::map, pair> lex_lt_at(const typed::multi_pw_aff<> &mpa) const = delete; + inline typed::map, pair> lex_lt_at(const typed::aff<> &mpa) const = delete; + inline typed::map, pair> lex_lt_at(const typed::multi_aff<> &mpa) const = delete; + inline typed::map, pair> lex_lt_at(const typed::pw_aff<> &mpa) const = delete; + inline typed::map, pair> lex_lt_at(const typed::pw_multi_aff<> &mpa) const = delete; + inline typed::map, pair> lexmax() const; + inline typed::pw_multi_aff, pair> lexmax_pw_multi_aff() const; + inline typed::map, pair> lexmin() const; + inline typed::pw_multi_aff, pair> lexmin_pw_multi_aff() const; + inline typed::map, pair> lower_bound(const typed::multi_pw_aff, pair> &lower) const; + inline typed::map, pair> lower_bound(const typed::aff, pair> &lower) const; + inline typed::map, pair> lower_bound(const typed::multi_aff, pair> &lower) const; + inline typed::map, pair> lower_bound(const typed::pw_aff, pair> &lower) const; + inline typed::map, pair> lower_bound(const typed::pw_multi_aff, pair> &lower) const; + inline typed::map_list, pair> map_list() const; + inline typed::multi_pw_aff, pair> max_multi_pw_aff() const; + inline typed::multi_pw_aff, pair> min_multi_pw_aff() const; + inline typed::set<> params() const; + template + inline typed::map> preimage_domain(const typed::multi_aff> &ma) const; + template + inline typed::map> preimage_domain(const typed::multi_pw_aff> &mpa) const; + template + inline typed::map> preimage_domain(const typed::pw_multi_aff> &pma) const; + template + inline typed::union_map> preimage_domain(const typed::union_pw_multi_aff> &upma) const; + template + inline typed::map, Arg2> preimage_range(const typed::multi_aff> &ma) const; + template + inline typed::map, Arg2> preimage_range(const typed::pw_multi_aff> &pma) const; + template + inline typed::union_map, Arg2> preimage_range(const typed::union_pw_multi_aff> &upma) const; + template + inline typed::map, Domain2>, pair, Arg2>> product(const typed::map &map2) const; + template + inline typed::union_map, Domain2>, pair, Arg2>> product(const typed::union_map &umap2) const; + template + inline typed::map, Domain2>, pair, Arg2>> product(const typed::basic_map &map2) const; + inline typed::map, pair> project_out_all_params() const; + inline typed::map, pair> project_out_param(const typed::id &id) const; + inline typed::map, pair> project_out_param(const std::string &id) const; + inline typed::map, pair> project_out_param(const typed::id_list &list) const; + inline typed::set> range() const; + inline typed::map, Range> range_factor_domain() const; + inline typed::map, Range2> range_factor_range() const; + inline typed::fixed_box, pair> range_lattice_tile() const; + inline typed::fixed_box, pair> get_range_lattice_tile() const = delete; + inline typed::union_map, pair>, pair> range_map() const; + template + inline typed::map, pair, Arg2>> range_product(const typed::map, Arg2> &map2) const; + template + inline typed::union_map, pair, Arg2>> range_product(const typed::union_map, Arg2> &umap2) const; + template + inline typed::map, pair, Arg2>> range_product(const typed::basic_map, Arg2> &map2) const; + inline typed::map, pair> range_reverse() const; + inline typed::fixed_box, pair> range_simple_fixed_box_hull() const; + inline typed::fixed_box, pair> get_range_simple_fixed_box_hull() const = delete; + inline typed::id, pair> get_range_tuple_id() const = delete; + inline typed::map, pair> reverse() const; + inline typed::map, pair> set_domain_tuple(const typed::id<> &id) const = delete; + inline typed::map, pair> set_domain_tuple(const std::string &id) const = delete; + inline typed::map, pair> set_range_tuple(const typed::id<> &id) const = delete; + inline typed::map, pair> set_range_tuple(const std::string &id) const = delete; + inline typed::space, pair> space() const; + inline typed::space, pair> get_space() const = delete; + inline typed::map, pair> subtract(const typed::map, pair> &map2) const; + inline typed::union_map, pair> subtract(const typed::union_map, pair> &umap2) const; + inline typed::map, pair> subtract(const typed::basic_map, pair> &map2) const; + inline typed::union_map, pair> subtract_domain(const typed::union_set> &dom) const; + inline typed::union_map, pair> subtract_range(const typed::union_set> &dom) const; + inline typed::union_map, pair> to_union_map() const; + inline typed::map, Range>, Range2> uncurry() const; + inline typed::map, pair> unite(const typed::map, pair> &map2) const; + inline typed::union_map, pair> unite(const typed::union_map, pair> &umap2) const; + inline typed::map, pair> unite(const typed::basic_map, pair> &map2) const; + static inline typed::map, pair> universe(const typed::space, pair> &space); + inline typed::map, pair> upper_bound(const typed::multi_pw_aff, pair> &upper) const; + inline typed::map, pair> upper_bound(const typed::aff, pair> &upper) const; + inline typed::map, pair> upper_bound(const typed::multi_aff, pair> &upper) const; + inline typed::map, pair> upper_bound(const typed::pw_aff, pair> &upper) const; + inline typed::map, pair> upper_bound(const typed::pw_multi_aff, pair> &upper) const; + inline typed::set, pair>> wrap() const; +}; + +template +struct map_list : public isl::map_list { + template + friend struct aff; + template + friend struct aff_list; + template + friend struct basic_map; + template + friend struct basic_set; + template + friend struct fixed_box; + template + friend struct id; + template + friend struct id_list; + template + friend struct map; + template + friend struct map_list; + template + friend struct multi_aff; + template + friend struct multi_id; + template + friend struct multi_pw_aff; + template + friend struct multi_union_pw_aff; + template + friend struct multi_val; + template + friend struct point; + template + friend struct pw_aff; + template + friend struct pw_aff_list; + template + friend struct pw_multi_aff; + template + friend struct pw_multi_aff_list; + template + friend struct set; + template + friend struct set_list; + template + friend struct space; + template + friend struct union_map; + template + friend struct union_pw_aff; + template + friend struct union_pw_aff_list; + template + friend struct union_pw_multi_aff; + template + friend struct union_set; + template + friend struct union_set_list; + template + friend struct val; + template + friend struct val_list; + + map_list() = default; + template {} && + std::is_base_of{}, + bool>::type = true> + map_list(const map_list &obj) : isl::map_list(obj) {} + private: + template {}, bool>::type = true> + map_list(const base &obj) : isl::map_list(obj) {} + public: + static map_list from(const isl::map_list &obj) { + return map_list(obj); + } + inline explicit map_list(const isl::ctx &ctx, int n); + inline explicit map_list(const typed::map &el); + inline explicit map_list(const isl::ctx &ctx, const std::string &str); + inline typed::map_list add(const typed::map &el) const; + inline typed::map_list add(const typed::basic_map &el) const; + inline typed::map at(int index) const; + inline typed::map get_at(int index) const = delete; + inline typed::map_list drop(unsigned int first, unsigned int n) const; + inline void foreach(const std::function)> &fn) const; + inline void foreach_scc(const std::function, typed::map)> &follows, const std::function)> &fn) const; + inline typed::map_list set_at(int index, const typed::map &el) const; +}; + +template +struct multi_aff : public isl::multi_aff { + template + friend struct aff; + template + friend struct aff_list; + template + friend struct basic_map; + template + friend struct basic_set; + template + friend struct fixed_box; + template + friend struct id; + template + friend struct id_list; + template + friend struct map; + template + friend struct map_list; + template + friend struct multi_aff; + template + friend struct multi_id; + template + friend struct multi_pw_aff; + template + friend struct multi_union_pw_aff; + template + friend struct multi_val; + template + friend struct point; + template + friend struct pw_aff; + template + friend struct pw_aff_list; + template + friend struct pw_multi_aff; + template + friend struct pw_multi_aff_list; + template + friend struct set; + template + friend struct set_list; + template + friend struct space; + template + friend struct union_map; + template + friend struct union_pw_aff; + template + friend struct union_pw_aff_list; + template + friend struct union_pw_multi_aff; + template + friend struct union_set; + template + friend struct union_set_list; + template + friend struct val; + template + friend struct val_list; + + multi_aff() = default; + template {}, + bool>::type = true> + multi_aff(const multi_aff &obj) : isl::multi_aff(obj) {} + private: + template {}, bool>::type = true> + multi_aff(const base &obj) : isl::multi_aff(obj) {} + public: + static multi_aff from(const isl::multi_aff &obj) { + return multi_aff(obj); + } + inline /* implicit */ multi_aff(const typed::aff &aff); + inline explicit multi_aff(const typed::space &space, const typed::aff_list &list); + inline explicit multi_aff(const isl::ctx &ctx, const std::string &str); + inline typed::multi_aff add(const typed::multi_aff &multi2) const; + inline typed::multi_pw_aff add(const typed::multi_pw_aff &multi2) const; + inline typed::multi_union_pw_aff add(const typed::multi_union_pw_aff &multi2) const; + inline typed::pw_multi_aff add(const typed::pw_multi_aff &pma2) const; + inline typed::union_pw_multi_aff add(const typed::union_pw_multi_aff &upma2) const; + inline typed::multi_aff add(const typed::aff &multi2) const; + inline typed::multi_aff add_constant(const typed::multi_val &mv) const; + inline typed::multi_aff add_constant(const typed::val &v) const; + inline typed::multi_aff add_constant(long v) const; + template + inline typed::union_pw_multi_aff apply(const typed::union_pw_multi_aff &upma2) const; + inline typed::map as_map() const = delete; + inline typed::multi_aff as_multi_aff() const; + inline typed::multi_union_pw_aff as_multi_union_pw_aff() const; + inline typed::pw_multi_aff as_pw_multi_aff() const; + inline typed::set as_set() const; + inline typed::union_map as_union_map() const = delete; + inline typed::aff at(int pos) const; + inline typed::aff get_at(int pos) const = delete; + inline typed::basic_set<> bind(const typed::multi_id &tuple) const; + inline typed::multi_aff bind_domain(const typed::multi_id<> &tuple) const = delete; + inline typed::multi_aff bind_domain_wrapped_domain(const typed::multi_id<> &tuple) const = delete; + inline typed::pw_multi_aff coalesce() const; + inline typed::multi_val constant_multi_val() const; + inline typed::multi_val get_constant_multi_val() const = delete; + inline typed::set<> domain() const; + inline typed::multi_aff domain_reverse() const = delete; + inline typed::pw_multi_aff drop_unused_params() const; + inline typed::pw_multi_aff extract_pw_multi_aff(const typed::space &space) const; + inline typed::multi_aff floor() const; + inline typed::multi_aff gist(const typed::set<> &context) const; + inline typed::union_pw_multi_aff gist(const typed::union_set<> &context) const; + inline typed::multi_aff gist(const typed::basic_set<> &context) const; + inline typed::multi_aff gist(const typed::point<> &context) const; + inline typed::multi_aff gist_params(const typed::set<> &context) const; + inline typed::multi_aff gist_params(const typed::basic_set<> &context) const; + inline typed::multi_aff gist_params(const typed::point<> &context) const; + inline typed::multi_aff identity() const; + template + inline typed::multi_aff insert_domain(const typed::space &domain) const; + inline typed::pw_multi_aff intersect_domain(const typed::set<> &set) const = delete; + inline typed::union_pw_multi_aff intersect_domain(const typed::space<> &space) const = delete; + inline typed::union_pw_multi_aff intersect_domain(const typed::union_set<> &uset) const = delete; + inline typed::union_pw_multi_aff intersect_domain_wrapped_domain(const typed::union_set<> &uset) const = delete; + inline typed::pw_multi_aff intersect_params(const typed::set<> &set) const; + inline typed::aff_list list() const; + inline typed::aff_list get_list() const = delete; + inline typed::multi_pw_aff max(const typed::multi_pw_aff &multi2) const; + inline typed::multi_val max_multi_val() const; + inline typed::multi_pw_aff min(const typed::multi_pw_aff &multi2) const; + inline typed::multi_val min_multi_val() const; + inline typed::multi_aff neg() const; + inline typed::pw_multi_aff preimage_domain_wrapped_domain(const typed::pw_multi_aff<> &pma2) const = delete; + inline typed::union_pw_multi_aff preimage_domain_wrapped_domain(const typed::union_pw_multi_aff<> &upma2) const = delete; + template + inline typed::multi_aff> product(const typed::multi_aff &multi2) const; + template + inline typed::multi_pw_aff> product(const typed::multi_pw_aff &multi2) const; + template + inline typed::pw_multi_aff> product(const typed::pw_multi_aff &pma2) const; + inline typed::multi_aff> product(const typed::aff &multi2) const; + inline typed::multi_aff pullback(const typed::multi_aff<> &ma2) const = delete; + inline typed::multi_pw_aff pullback(const typed::multi_pw_aff<> &mpa2) const = delete; + inline typed::pw_multi_aff pullback(const typed::pw_multi_aff<> &pma2) const = delete; + inline typed::union_pw_multi_aff pullback(const typed::union_pw_multi_aff<> &upma2) const = delete; + inline typed::multi_aff pullback(const typed::aff<> &ma2) const = delete; + inline typed::pw_multi_aff_list pw_multi_aff_list() const; + inline typed::pw_multi_aff range_factor_domain() const = delete; + inline typed::pw_multi_aff range_factor_range() const = delete; + inline typed::multi_aff range_product(const typed::multi_aff<> &multi2) const = delete; + inline typed::multi_pw_aff range_product(const typed::multi_pw_aff<> &multi2) const = delete; + inline typed::multi_union_pw_aff range_product(const typed::multi_union_pw_aff<> &multi2) const = delete; + inline typed::pw_multi_aff range_product(const typed::pw_multi_aff<> &pma2) const = delete; + inline typed::union_pw_multi_aff range_product(const typed::union_pw_multi_aff<> &upma2) const = delete; + inline typed::multi_aff range_product(const typed::aff<> &multi2) const = delete; + inline typed::id get_range_tuple_id() const = delete; + inline typed::multi_aff scale(const typed::multi_val &mv) const; + inline typed::multi_aff scale(const typed::val &v) const; + inline typed::multi_aff scale(long v) const; + inline typed::multi_aff scale_down(const typed::multi_val &mv) const; + inline typed::multi_aff scale_down(const typed::val &v) const; + inline typed::multi_aff scale_down(long v) const; + inline typed::multi_aff set_at(int pos, const typed::aff &el) const; + inline typed::multi_pw_aff set_at(int pos, const typed::pw_aff &el) const; + inline typed::multi_union_pw_aff set_at(int pos, const typed::union_pw_aff &el) const; + template + inline typed::multi_aff set_range_tuple(const typed::id &id) const; + template + inline typed::multi_aff set_range_tuple(const std::string &id) const; + inline typed::space space() const; + inline typed::space get_space() const = delete; + inline typed::multi_aff sub(const typed::multi_aff &multi2) const; + inline typed::multi_pw_aff sub(const typed::multi_pw_aff &multi2) const; + inline typed::multi_union_pw_aff sub(const typed::multi_union_pw_aff &multi2) const; + inline typed::pw_multi_aff sub(const typed::pw_multi_aff &pma2) const; + inline typed::union_pw_multi_aff sub(const typed::union_pw_multi_aff &upma2) const; + inline typed::multi_aff sub(const typed::aff &multi2) const; + inline typed::pw_multi_aff subtract_domain(const typed::set<> &set) const = delete; + inline typed::union_pw_multi_aff subtract_domain(const typed::space<> &space) const = delete; + inline typed::union_pw_multi_aff subtract_domain(const typed::union_set<> &uset) const = delete; + inline typed::multi_pw_aff to_multi_pw_aff() const; + inline typed::multi_union_pw_aff to_multi_union_pw_aff() const; + inline typed::pw_multi_aff to_pw_multi_aff() const; + inline typed::union_pw_multi_aff to_union_pw_multi_aff() const; + template + inline typed::multi_aff unbind_params_insert_domain(const typed::multi_id &domain) const; + inline typed::multi_pw_aff union_add(const typed::multi_pw_aff &mpa2) const; + inline typed::multi_union_pw_aff union_add(const typed::multi_union_pw_aff &mupa2) const; + inline typed::pw_multi_aff union_add(const typed::pw_multi_aff &pma2) const; + inline typed::union_pw_multi_aff union_add(const typed::union_pw_multi_aff &upma2) const; +}; + +template +struct multi_aff : public isl::multi_aff { + template + friend struct aff; + template + friend struct aff_list; + template + friend struct basic_map; + template + friend struct basic_set; + template + friend struct fixed_box; + template + friend struct id; + template + friend struct id_list; + template + friend struct map; + template + friend struct map_list; + template + friend struct multi_aff; + template + friend struct multi_id; + template + friend struct multi_pw_aff; + template + friend struct multi_union_pw_aff; + template + friend struct multi_val; + template + friend struct point; + template + friend struct pw_aff; + template + friend struct pw_aff_list; + template + friend struct pw_multi_aff; + template + friend struct pw_multi_aff_list; + template + friend struct set; + template + friend struct set_list; + template + friend struct space; + template + friend struct union_map; + template + friend struct union_pw_aff; + template + friend struct union_pw_aff_list; + template + friend struct union_pw_multi_aff; + template + friend struct union_set; + template + friend struct union_set_list; + template + friend struct val; + template + friend struct val_list; + + multi_aff() = default; + template {} && + std::is_base_of{}, + bool>::type = true> + multi_aff(const multi_aff &obj) : isl::multi_aff(obj) {} + private: + template {}, bool>::type = true> + multi_aff(const base &obj) : isl::multi_aff(obj) {} + public: + static multi_aff from(const isl::multi_aff &obj) { + return multi_aff(obj); + } + inline /* implicit */ multi_aff(const typed::aff &aff); + inline explicit multi_aff(const typed::space &space, const typed::aff_list &list); + inline explicit multi_aff(const isl::ctx &ctx, const std::string &str); + inline typed::multi_aff add(const typed::multi_aff &multi2) const; + inline typed::multi_pw_aff add(const typed::multi_pw_aff &multi2) const; + inline typed::multi_union_pw_aff add(const typed::multi_union_pw_aff &multi2) const; + inline typed::pw_multi_aff add(const typed::pw_multi_aff &pma2) const; + inline typed::union_pw_multi_aff add(const typed::union_pw_multi_aff &upma2) const; + inline typed::multi_aff add(const typed::aff &multi2) const; + inline typed::multi_aff add_constant(const typed::multi_val &mv) const; + inline typed::multi_aff add_constant(const typed::val &v) const; + inline typed::multi_aff add_constant(long v) const; + template + inline typed::union_pw_multi_aff apply(const typed::union_pw_multi_aff &upma2) const; + inline typed::map as_map() const; + inline typed::multi_aff as_multi_aff() const; + inline typed::multi_union_pw_aff as_multi_union_pw_aff() const; + inline typed::pw_multi_aff as_pw_multi_aff() const; + inline typed::set as_set() const = delete; + inline typed::union_map as_union_map() const; + inline typed::aff at(int pos) const; + inline typed::aff get_at(int pos) const = delete; + inline typed::basic_set bind(const typed::multi_id &tuple) const; + inline typed::multi_aff bind_domain(const typed::multi_id &tuple) const; + inline typed::multi_aff bind_domain_wrapped_domain(const typed::multi_id<> &tuple) const = delete; + inline typed::pw_multi_aff coalesce() const; + inline typed::multi_val constant_multi_val() const; + inline typed::multi_val get_constant_multi_val() const = delete; + inline typed::set domain() const; + inline typed::multi_aff domain_reverse() const = delete; + inline typed::pw_multi_aff drop_unused_params() const; + inline typed::pw_multi_aff extract_pw_multi_aff(const typed::space &space) const; + inline typed::multi_aff floor() const; + inline typed::multi_aff gist(const typed::set &context) const; + inline typed::union_pw_multi_aff gist(const typed::union_set &context) const; + inline typed::multi_aff gist(const typed::basic_set &context) const; + inline typed::multi_aff gist(const typed::point &context) const; + inline typed::multi_aff gist_params(const typed::set<> &context) const; + inline typed::multi_aff gist_params(const typed::basic_set<> &context) const; + inline typed::multi_aff gist_params(const typed::point<> &context) const; + inline typed::multi_aff identity() const; + inline typed::multi_aff insert_domain(const typed::space<> &domain) const = delete; + inline typed::pw_multi_aff intersect_domain(const typed::set &set) const; + inline typed::union_pw_multi_aff intersect_domain(const typed::space &space) const; + inline typed::union_pw_multi_aff intersect_domain(const typed::union_set &uset) const; + inline typed::union_pw_multi_aff intersect_domain_wrapped_domain(const typed::union_set<> &uset) const = delete; + inline typed::pw_multi_aff intersect_params(const typed::set<> &set) const; + inline typed::aff_list list() const; + inline typed::aff_list get_list() const = delete; + inline typed::multi_pw_aff max(const typed::multi_pw_aff &multi2) const; + inline typed::multi_val max_multi_val() const; + inline typed::multi_pw_aff min(const typed::multi_pw_aff &multi2) const; + inline typed::multi_val min_multi_val() const; + inline typed::multi_aff neg() const; + inline typed::pw_multi_aff preimage_domain_wrapped_domain(const typed::pw_multi_aff<> &pma2) const = delete; + inline typed::union_pw_multi_aff preimage_domain_wrapped_domain(const typed::union_pw_multi_aff<> &upma2) const = delete; + template + inline typed::multi_aff, pair> product(const typed::multi_aff &multi2) const; + template + inline typed::multi_pw_aff, pair> product(const typed::multi_pw_aff &multi2) const; + template + inline typed::pw_multi_aff, pair> product(const typed::pw_multi_aff &pma2) const; + template + inline typed::multi_aff, pair> product(const typed::aff &multi2) const; + template + inline typed::multi_aff pullback(const typed::multi_aff &ma2) const; + inline typed::multi_aff pullback(const typed::multi_aff &ma2) const; + template + inline typed::multi_pw_aff pullback(const typed::multi_pw_aff &mpa2) const; + inline typed::multi_pw_aff pullback(const typed::multi_pw_aff &mpa2) const; + template + inline typed::pw_multi_aff pullback(const typed::pw_multi_aff &pma2) const; + inline typed::pw_multi_aff pullback(const typed::pw_multi_aff &pma2) const; + template + inline typed::union_pw_multi_aff pullback(const typed::union_pw_multi_aff &upma2) const; + inline typed::union_pw_multi_aff pullback(const typed::union_pw_multi_aff &upma2) const; + template + inline typed::multi_aff pullback(const typed::aff &ma2) const; + inline typed::multi_aff pullback(const typed::aff &ma2) const; + inline typed::pw_multi_aff_list pw_multi_aff_list() const; + inline typed::pw_multi_aff range_factor_domain() const = delete; + inline typed::pw_multi_aff range_factor_range() const = delete; + template + inline typed::multi_aff> range_product(const typed::multi_aff &multi2) const; + template + inline typed::multi_pw_aff> range_product(const typed::multi_pw_aff &multi2) const; + template + inline typed::multi_union_pw_aff> range_product(const typed::multi_union_pw_aff &multi2) const; + template + inline typed::pw_multi_aff> range_product(const typed::pw_multi_aff &pma2) const; + template + inline typed::union_pw_multi_aff> range_product(const typed::union_pw_multi_aff &upma2) const; + inline typed::multi_aff> range_product(const typed::aff &multi2) const; + inline typed::id get_range_tuple_id() const = delete; + inline typed::multi_aff scale(const typed::multi_val &mv) const; + inline typed::multi_aff scale(const typed::val &v) const; + inline typed::multi_aff scale(long v) const; + inline typed::multi_aff scale_down(const typed::multi_val &mv) const; + inline typed::multi_aff scale_down(const typed::val &v) const; + inline typed::multi_aff scale_down(long v) const; + inline typed::multi_aff set_at(int pos, const typed::aff &el) const; + inline typed::multi_pw_aff set_at(int pos, const typed::pw_aff &el) const; + inline typed::multi_union_pw_aff set_at(int pos, const typed::union_pw_aff &el) const; + template + inline typed::multi_aff set_range_tuple(const typed::id &id) const; + template + inline typed::multi_aff set_range_tuple(const std::string &id) const; + inline typed::space space() const; + inline typed::space get_space() const = delete; + inline typed::multi_aff sub(const typed::multi_aff &multi2) const; + inline typed::multi_pw_aff sub(const typed::multi_pw_aff &multi2) const; + inline typed::multi_union_pw_aff sub(const typed::multi_union_pw_aff &multi2) const; + inline typed::pw_multi_aff sub(const typed::pw_multi_aff &pma2) const; + inline typed::union_pw_multi_aff sub(const typed::union_pw_multi_aff &upma2) const; + inline typed::multi_aff sub(const typed::aff &multi2) const; + inline typed::pw_multi_aff subtract_domain(const typed::set &set) const; + inline typed::union_pw_multi_aff subtract_domain(const typed::space &space) const; + inline typed::union_pw_multi_aff subtract_domain(const typed::union_set &uset) const; + inline typed::multi_pw_aff to_multi_pw_aff() const; + inline typed::multi_union_pw_aff to_multi_union_pw_aff() const; + inline typed::pw_multi_aff to_pw_multi_aff() const; + inline typed::union_pw_multi_aff to_union_pw_multi_aff() const; + inline typed::multi_aff unbind_params_insert_domain(const typed::multi_id<> &domain) const = delete; + inline typed::multi_pw_aff union_add(const typed::multi_pw_aff &mpa2) const; + inline typed::multi_union_pw_aff union_add(const typed::multi_union_pw_aff &mupa2) const; + inline typed::pw_multi_aff union_add(const typed::pw_multi_aff &pma2) const; + inline typed::union_pw_multi_aff union_add(const typed::union_pw_multi_aff &upma2) const; +}; + +template +struct multi_aff, Range> : public isl::multi_aff { + template + friend struct aff; + template + friend struct aff_list; + template + friend struct basic_map; + template + friend struct basic_set; + template + friend struct fixed_box; + template + friend struct id; + template + friend struct id_list; + template + friend struct map; + template + friend struct map_list; + template + friend struct multi_aff; + template + friend struct multi_id; + template + friend struct multi_pw_aff; + template + friend struct multi_union_pw_aff; + template + friend struct multi_val; + template + friend struct point; + template + friend struct pw_aff; + template + friend struct pw_aff_list; + template + friend struct pw_multi_aff; + template + friend struct pw_multi_aff_list; + template + friend struct set; + template + friend struct set_list; + template + friend struct space; + template + friend struct union_map; + template + friend struct union_pw_aff; + template + friend struct union_pw_aff_list; + template + friend struct union_pw_multi_aff; + template + friend struct union_set; + template + friend struct union_set_list; + template + friend struct val; + template + friend struct val_list; + + multi_aff() = default; + template {} && + std::is_base_of{} && + std::is_base_of{}, + bool>::type = true> + multi_aff(const multi_aff, Arg3> &obj) : isl::multi_aff(obj) {} + private: + template {}, bool>::type = true> + multi_aff(const base &obj) : isl::multi_aff(obj) {} + public: + static multi_aff from(const isl::multi_aff &obj) { + return multi_aff(obj); + } + inline /* implicit */ multi_aff(const typed::aff, Range> &aff); + inline explicit multi_aff(const typed::space, Range> &space, const typed::aff_list, Anonymous> &list); + inline explicit multi_aff(const isl::ctx &ctx, const std::string &str); + inline typed::multi_aff, Range> add(const typed::multi_aff, Range> &multi2) const; + inline typed::multi_pw_aff, Range> add(const typed::multi_pw_aff, Range> &multi2) const; + inline typed::multi_union_pw_aff, Range> add(const typed::multi_union_pw_aff, Range> &multi2) const; + inline typed::pw_multi_aff, Range> add(const typed::pw_multi_aff, Range> &pma2) const; + inline typed::union_pw_multi_aff, Range> add(const typed::union_pw_multi_aff, Range> &upma2) const; + inline typed::multi_aff, Range> add(const typed::aff, Range> &multi2) const; + inline typed::multi_aff, Range> add_constant(const typed::multi_val &mv) const; + inline typed::multi_aff, Range> add_constant(const typed::val &v) const; + inline typed::multi_aff, Range> add_constant(long v) const; + template + inline typed::union_pw_multi_aff, Arg2> apply(const typed::union_pw_multi_aff &upma2) const; + inline typed::map, Range> as_map() const; + inline typed::multi_aff, Range> as_multi_aff() const; + inline typed::multi_union_pw_aff, Range> as_multi_union_pw_aff() const; + inline typed::pw_multi_aff, Range> as_pw_multi_aff() const; + inline typed::set, Range> as_set() const = delete; + inline typed::union_map, Range> as_union_map() const; + inline typed::aff, Anonymous> at(int pos) const; + inline typed::aff, Range> get_at(int pos) const = delete; + inline typed::basic_set> bind(const typed::multi_id &tuple) const; + inline typed::multi_aff bind_domain(const typed::multi_id> &tuple) const; + inline typed::multi_aff bind_domain_wrapped_domain(const typed::multi_id &tuple) const; + inline typed::pw_multi_aff, Range> coalesce() const; + inline typed::multi_val constant_multi_val() const; + inline typed::multi_val, Range> get_constant_multi_val() const = delete; + inline typed::set> domain() const; + inline typed::multi_aff, Range> domain_reverse() const; + inline typed::pw_multi_aff, Range> drop_unused_params() const; + inline typed::pw_multi_aff, Range> extract_pw_multi_aff(const typed::space, Range> &space) const; + inline typed::multi_aff, Range> floor() const; + inline typed::multi_aff, Range> gist(const typed::set> &context) const; + inline typed::union_pw_multi_aff, Range> gist(const typed::union_set> &context) const; + inline typed::multi_aff, Range> gist(const typed::basic_set> &context) const; + inline typed::multi_aff, Range> gist(const typed::point> &context) const; + inline typed::multi_aff, Range> gist_params(const typed::set<> &context) const; + inline typed::multi_aff, Range> gist_params(const typed::basic_set<> &context) const; + inline typed::multi_aff, Range> gist_params(const typed::point<> &context) const; + inline typed::multi_aff, Range> identity() const; + inline typed::multi_aff, Range> insert_domain(const typed::space<> &domain) const = delete; + inline typed::pw_multi_aff, Range> intersect_domain(const typed::set> &set) const; + inline typed::union_pw_multi_aff, Range> intersect_domain(const typed::space> &space) const; + inline typed::union_pw_multi_aff, Range> intersect_domain(const typed::union_set> &uset) const; + inline typed::union_pw_multi_aff, Range> intersect_domain_wrapped_domain(const typed::union_set &uset) const; + inline typed::pw_multi_aff, Range> intersect_params(const typed::set<> &set) const; + inline typed::aff_list, Anonymous> list() const; + inline typed::aff_list, Range> get_list() const = delete; + inline typed::multi_pw_aff, Range> max(const typed::multi_pw_aff, Range> &multi2) const; + inline typed::multi_val max_multi_val() const; + inline typed::multi_pw_aff, Range> min(const typed::multi_pw_aff, Range> &multi2) const; + inline typed::multi_val min_multi_val() const; + inline typed::multi_aff, Range> neg() const; + template + inline typed::pw_multi_aff, Range> preimage_domain_wrapped_domain(const typed::pw_multi_aff &pma2) const; + template + inline typed::union_pw_multi_aff, Range> preimage_domain_wrapped_domain(const typed::union_pw_multi_aff &upma2) const; + template + inline typed::multi_aff, Arg2>, pair> product(const typed::multi_aff &multi2) const; + template + inline typed::multi_pw_aff, Arg2>, pair> product(const typed::multi_pw_aff &multi2) const; + template + inline typed::pw_multi_aff, Arg2>, pair> product(const typed::pw_multi_aff &pma2) const; + template + inline typed::multi_aff, Arg2>, pair> product(const typed::aff &multi2) const; + template + inline typed::multi_aff pullback(const typed::multi_aff> &ma2) const; + inline typed::multi_aff pullback(const typed::multi_aff> &ma2) const; + template + inline typed::multi_pw_aff pullback(const typed::multi_pw_aff> &mpa2) const; + inline typed::multi_pw_aff pullback(const typed::multi_pw_aff> &mpa2) const; + template + inline typed::pw_multi_aff pullback(const typed::pw_multi_aff> &pma2) const; + inline typed::pw_multi_aff pullback(const typed::pw_multi_aff> &pma2) const; + template + inline typed::union_pw_multi_aff pullback(const typed::union_pw_multi_aff> &upma2) const; + inline typed::union_pw_multi_aff pullback(const typed::union_pw_multi_aff> &upma2) const; + template + inline typed::multi_aff pullback(const typed::aff> &ma2) const; + inline typed::multi_aff pullback(const typed::aff> &ma2) const; + inline typed::pw_multi_aff_list, Range> pw_multi_aff_list() const; + inline typed::pw_multi_aff, Range> range_factor_domain() const = delete; + inline typed::pw_multi_aff, Range> range_factor_range() const = delete; + template + inline typed::multi_aff, pair> range_product(const typed::multi_aff, Arg2> &multi2) const; + template + inline typed::multi_pw_aff, pair> range_product(const typed::multi_pw_aff, Arg2> &multi2) const; + template + inline typed::multi_union_pw_aff, pair> range_product(const typed::multi_union_pw_aff, Arg2> &multi2) const; + template + inline typed::pw_multi_aff, pair> range_product(const typed::pw_multi_aff, Arg2> &pma2) const; + template + inline typed::union_pw_multi_aff, pair> range_product(const typed::union_pw_multi_aff, Arg2> &upma2) const; + inline typed::multi_aff, pair> range_product(const typed::aff, Anonymous> &multi2) const; + inline typed::id, Range> get_range_tuple_id() const = delete; + inline typed::multi_aff, Range> scale(const typed::multi_val &mv) const; + inline typed::multi_aff, Range> scale(const typed::val &v) const; + inline typed::multi_aff, Range> scale(long v) const; + inline typed::multi_aff, Range> scale_down(const typed::multi_val &mv) const; + inline typed::multi_aff, Range> scale_down(const typed::val &v) const; + inline typed::multi_aff, Range> scale_down(long v) const; + inline typed::multi_aff, Range> set_at(int pos, const typed::aff, Anonymous> &el) const; + inline typed::multi_pw_aff, Range> set_at(int pos, const typed::pw_aff, Anonymous> &el) const; + inline typed::multi_union_pw_aff, Range> set_at(int pos, const typed::union_pw_aff, Anonymous> &el) const; + template + inline typed::multi_aff, Arg1> set_range_tuple(const typed::id &id) const; + template + inline typed::multi_aff, Arg1> set_range_tuple(const std::string &id) const; + inline typed::space, Range> space() const; + inline typed::space, Range> get_space() const = delete; + inline typed::multi_aff, Range> sub(const typed::multi_aff, Range> &multi2) const; + inline typed::multi_pw_aff, Range> sub(const typed::multi_pw_aff, Range> &multi2) const; + inline typed::multi_union_pw_aff, Range> sub(const typed::multi_union_pw_aff, Range> &multi2) const; + inline typed::pw_multi_aff, Range> sub(const typed::pw_multi_aff, Range> &pma2) const; + inline typed::union_pw_multi_aff, Range> sub(const typed::union_pw_multi_aff, Range> &upma2) const; + inline typed::multi_aff, Range> sub(const typed::aff, Range> &multi2) const; + inline typed::pw_multi_aff, Range> subtract_domain(const typed::set> &set) const; + inline typed::union_pw_multi_aff, Range> subtract_domain(const typed::space> &space) const; + inline typed::union_pw_multi_aff, Range> subtract_domain(const typed::union_set> &uset) const; + inline typed::multi_pw_aff, Range> to_multi_pw_aff() const; + inline typed::multi_union_pw_aff, Range> to_multi_union_pw_aff() const; + inline typed::pw_multi_aff, Range> to_pw_multi_aff() const; + inline typed::union_pw_multi_aff, Range> to_union_pw_multi_aff() const; + inline typed::multi_aff, Range> unbind_params_insert_domain(const typed::multi_id<> &domain) const = delete; + inline typed::multi_pw_aff, Range> union_add(const typed::multi_pw_aff, Range> &mpa2) const; + inline typed::multi_union_pw_aff, Range> union_add(const typed::multi_union_pw_aff, Range> &mupa2) const; + inline typed::pw_multi_aff, Range> union_add(const typed::pw_multi_aff, Range> &pma2) const; + inline typed::union_pw_multi_aff, Range> union_add(const typed::union_pw_multi_aff, Range> &upma2) const; +}; + +template +struct multi_aff> : public isl::multi_aff { + template + friend struct aff; + template + friend struct aff_list; + template + friend struct basic_map; + template + friend struct basic_set; + template + friend struct fixed_box; + template + friend struct id; + template + friend struct id_list; + template + friend struct map; + template + friend struct map_list; + template + friend struct multi_aff; + template + friend struct multi_id; + template + friend struct multi_pw_aff; + template + friend struct multi_union_pw_aff; + template + friend struct multi_val; + template + friend struct point; + template + friend struct pw_aff; + template + friend struct pw_aff_list; + template + friend struct pw_multi_aff; + template + friend struct pw_multi_aff_list; + template + friend struct set; + template + friend struct set_list; + template + friend struct space; + template + friend struct union_map; + template + friend struct union_pw_aff; + template + friend struct union_pw_aff_list; + template + friend struct union_pw_multi_aff; + template + friend struct union_set; + template + friend struct union_set_list; + template + friend struct val; + template + friend struct val_list; + + multi_aff() = default; + template {} && + std::is_base_of{} && + std::is_base_of{}, + bool>::type = true> + multi_aff(const multi_aff> &obj) : isl::multi_aff(obj) {} + private: + template {}, bool>::type = true> + multi_aff(const base &obj) : isl::multi_aff(obj) {} + public: + static multi_aff from(const isl::multi_aff &obj) { + return multi_aff(obj); + } + inline /* implicit */ multi_aff(const typed::aff> &aff); + inline explicit multi_aff(const typed::space> &space, const typed::aff_list &list); + inline explicit multi_aff(const isl::ctx &ctx, const std::string &str); + inline typed::multi_aff> add(const typed::multi_aff> &multi2) const; + inline typed::multi_pw_aff> add(const typed::multi_pw_aff> &multi2) const; + inline typed::multi_union_pw_aff> add(const typed::multi_union_pw_aff> &multi2) const; + inline typed::pw_multi_aff> add(const typed::pw_multi_aff> &pma2) const; + inline typed::union_pw_multi_aff> add(const typed::union_pw_multi_aff> &upma2) const; + inline typed::multi_aff> add(const typed::aff> &multi2) const; + inline typed::multi_aff> add_constant(const typed::multi_val> &mv) const; + inline typed::multi_aff> add_constant(const typed::val> &v) const; + inline typed::multi_aff> add_constant(long v) const; + template + inline typed::union_pw_multi_aff apply(const typed::union_pw_multi_aff, Arg3> &upma2) const; + inline typed::map> as_map() const; + inline typed::multi_aff> as_multi_aff() const; + inline typed::multi_union_pw_aff> as_multi_union_pw_aff() const; + inline typed::pw_multi_aff> as_pw_multi_aff() const; + inline typed::set> as_set() const = delete; + inline typed::union_map> as_union_map() const; + inline typed::aff at(int pos) const; + inline typed::aff> get_at(int pos) const = delete; + inline typed::basic_set bind(const typed::multi_id> &tuple) const; + inline typed::multi_aff> bind_domain(const typed::multi_id &tuple) const; + inline typed::multi_aff> bind_domain_wrapped_domain(const typed::multi_id<> &tuple) const = delete; + inline typed::pw_multi_aff> coalesce() const; + inline typed::multi_val> constant_multi_val() const; + inline typed::multi_val> get_constant_multi_val() const = delete; + inline typed::set domain() const; + inline typed::multi_aff> domain_reverse() const = delete; + inline typed::pw_multi_aff> drop_unused_params() const; + inline typed::pw_multi_aff> extract_pw_multi_aff(const typed::space> &space) const; + inline typed::multi_aff> floor() const; + inline typed::multi_aff> gist(const typed::set &context) const; + inline typed::union_pw_multi_aff> gist(const typed::union_set &context) const; + inline typed::multi_aff> gist(const typed::basic_set &context) const; + inline typed::multi_aff> gist(const typed::point &context) const; + inline typed::multi_aff> gist_params(const typed::set<> &context) const; + inline typed::multi_aff> gist_params(const typed::basic_set<> &context) const; + inline typed::multi_aff> gist_params(const typed::point<> &context) const; + inline typed::multi_aff> identity() const; + inline typed::multi_aff> insert_domain(const typed::space<> &domain) const = delete; + inline typed::pw_multi_aff> intersect_domain(const typed::set &set) const; + inline typed::union_pw_multi_aff> intersect_domain(const typed::space &space) const; + inline typed::union_pw_multi_aff> intersect_domain(const typed::union_set &uset) const; + inline typed::union_pw_multi_aff> intersect_domain_wrapped_domain(const typed::union_set<> &uset) const = delete; + inline typed::pw_multi_aff> intersect_params(const typed::set<> &set) const; + inline typed::aff_list list() const; + inline typed::aff_list> get_list() const = delete; + inline typed::multi_pw_aff> max(const typed::multi_pw_aff> &multi2) const; + inline typed::multi_val> max_multi_val() const; + inline typed::multi_pw_aff> min(const typed::multi_pw_aff> &multi2) const; + inline typed::multi_val> min_multi_val() const; + inline typed::multi_aff> neg() const; + inline typed::pw_multi_aff> preimage_domain_wrapped_domain(const typed::pw_multi_aff<> &pma2) const = delete; + inline typed::union_pw_multi_aff> preimage_domain_wrapped_domain(const typed::union_pw_multi_aff<> &upma2) const = delete; + template + inline typed::multi_aff, pair, Arg3>> product(const typed::multi_aff &multi2) const; + template + inline typed::multi_pw_aff, pair, Arg3>> product(const typed::multi_pw_aff &multi2) const; + template + inline typed::pw_multi_aff, pair, Arg3>> product(const typed::pw_multi_aff &pma2) const; + template + inline typed::multi_aff, pair, Anonymous>> product(const typed::aff &multi2) const; + template + inline typed::multi_aff> pullback(const typed::multi_aff &ma2) const; + inline typed::multi_aff> pullback(const typed::multi_aff &ma2) const; + template + inline typed::multi_pw_aff> pullback(const typed::multi_pw_aff &mpa2) const; + inline typed::multi_pw_aff> pullback(const typed::multi_pw_aff &mpa2) const; + template + inline typed::pw_multi_aff> pullback(const typed::pw_multi_aff &pma2) const; + inline typed::pw_multi_aff> pullback(const typed::pw_multi_aff &pma2) const; + template + inline typed::union_pw_multi_aff> pullback(const typed::union_pw_multi_aff &upma2) const; + inline typed::union_pw_multi_aff> pullback(const typed::union_pw_multi_aff &upma2) const; + template + inline typed::multi_aff> pullback(const typed::aff &ma2) const; + inline typed::multi_aff> pullback(const typed::aff &ma2) const; + inline typed::pw_multi_aff_list> pw_multi_aff_list() const; + inline typed::pw_multi_aff range_factor_domain() const; + inline typed::pw_multi_aff range_factor_range() const; + template + inline typed::multi_aff, Arg3>> range_product(const typed::multi_aff &multi2) const; + template + inline typed::multi_pw_aff, Arg3>> range_product(const typed::multi_pw_aff &multi2) const; + template + inline typed::multi_union_pw_aff, Arg3>> range_product(const typed::multi_union_pw_aff &multi2) const; + template + inline typed::pw_multi_aff, Arg3>> range_product(const typed::pw_multi_aff &pma2) const; + template + inline typed::union_pw_multi_aff, Arg3>> range_product(const typed::union_pw_multi_aff &upma2) const; + inline typed::multi_aff, Anonymous>> range_product(const typed::aff &multi2) const; + inline typed::id> get_range_tuple_id() const = delete; + inline typed::multi_aff> scale(const typed::multi_val> &mv) const; + inline typed::multi_aff> scale(const typed::val> &v) const; + inline typed::multi_aff> scale(long v) const; + inline typed::multi_aff> scale_down(const typed::multi_val> &mv) const; + inline typed::multi_aff> scale_down(const typed::val> &v) const; + inline typed::multi_aff> scale_down(long v) const; + inline typed::multi_aff> set_at(int pos, const typed::aff &el) const; + inline typed::multi_pw_aff> set_at(int pos, const typed::pw_aff &el) const; + inline typed::multi_union_pw_aff> set_at(int pos, const typed::union_pw_aff &el) const; + inline typed::multi_aff> set_range_tuple(const typed::id<> &id) const = delete; + inline typed::multi_aff> set_range_tuple(const std::string &id) const = delete; + inline typed::space> space() const; + inline typed::space> get_space() const = delete; + inline typed::multi_aff> sub(const typed::multi_aff> &multi2) const; + inline typed::multi_pw_aff> sub(const typed::multi_pw_aff> &multi2) const; + inline typed::multi_union_pw_aff> sub(const typed::multi_union_pw_aff> &multi2) const; + inline typed::pw_multi_aff> sub(const typed::pw_multi_aff> &pma2) const; + inline typed::union_pw_multi_aff> sub(const typed::union_pw_multi_aff> &upma2) const; + inline typed::multi_aff> sub(const typed::aff> &multi2) const; + inline typed::pw_multi_aff> subtract_domain(const typed::set &set) const; + inline typed::union_pw_multi_aff> subtract_domain(const typed::space &space) const; + inline typed::union_pw_multi_aff> subtract_domain(const typed::union_set &uset) const; + inline typed::multi_pw_aff> to_multi_pw_aff() const; + inline typed::multi_union_pw_aff> to_multi_union_pw_aff() const; + inline typed::pw_multi_aff> to_pw_multi_aff() const; + inline typed::union_pw_multi_aff> to_union_pw_multi_aff() const; + inline typed::multi_aff> unbind_params_insert_domain(const typed::multi_id<> &domain) const = delete; + inline typed::multi_pw_aff> union_add(const typed::multi_pw_aff> &mpa2) const; + inline typed::multi_union_pw_aff> union_add(const typed::multi_union_pw_aff> &mupa2) const; + inline typed::pw_multi_aff> union_add(const typed::pw_multi_aff> &pma2) const; + inline typed::union_pw_multi_aff> union_add(const typed::union_pw_multi_aff> &upma2) const; +}; + +template +struct multi_aff, pair> : public isl::multi_aff { + template + friend struct aff; + template + friend struct aff_list; + template + friend struct basic_map; + template + friend struct basic_set; + template + friend struct fixed_box; + template + friend struct id; + template + friend struct id_list; + template + friend struct map; + template + friend struct map_list; + template + friend struct multi_aff; + template + friend struct multi_id; + template + friend struct multi_pw_aff; + template + friend struct multi_union_pw_aff; + template + friend struct multi_val; + template + friend struct point; + template + friend struct pw_aff; + template + friend struct pw_aff_list; + template + friend struct pw_multi_aff; + template + friend struct pw_multi_aff_list; + template + friend struct set; + template + friend struct set_list; + template + friend struct space; + template + friend struct union_map; + template + friend struct union_pw_aff; + template + friend struct union_pw_aff_list; + template + friend struct union_pw_multi_aff; + template + friend struct union_set; + template + friend struct union_set_list; + template + friend struct val; + template + friend struct val_list; + + multi_aff() = default; + template {} && + std::is_base_of{} && + std::is_base_of{} && + std::is_base_of{}, + bool>::type = true> + multi_aff(const multi_aff, pair> &obj) : isl::multi_aff(obj) {} + private: + template {}, bool>::type = true> + multi_aff(const base &obj) : isl::multi_aff(obj) {} + public: + static multi_aff from(const isl::multi_aff &obj) { + return multi_aff(obj); + } + inline /* implicit */ multi_aff(const typed::aff, pair> &aff); + inline explicit multi_aff(const typed::space, pair> &space, const typed::aff_list, Anonymous> &list); + inline explicit multi_aff(const isl::ctx &ctx, const std::string &str); + inline typed::multi_aff, pair> add(const typed::multi_aff, pair> &multi2) const; + inline typed::multi_pw_aff, pair> add(const typed::multi_pw_aff, pair> &multi2) const; + inline typed::multi_union_pw_aff, pair> add(const typed::multi_union_pw_aff, pair> &multi2) const; + inline typed::pw_multi_aff, pair> add(const typed::pw_multi_aff, pair> &pma2) const; + inline typed::union_pw_multi_aff, pair> add(const typed::union_pw_multi_aff, pair> &upma2) const; + inline typed::multi_aff, pair> add(const typed::aff, pair> &multi2) const; + inline typed::multi_aff, pair> add_constant(const typed::multi_val> &mv) const; + inline typed::multi_aff, pair> add_constant(const typed::val> &v) const; + inline typed::multi_aff, pair> add_constant(long v) const; + template + inline typed::union_pw_multi_aff, Arg2> apply(const typed::union_pw_multi_aff, Arg2> &upma2) const; + inline typed::map, pair> as_map() const; + inline typed::multi_aff, pair> as_multi_aff() const; + inline typed::multi_union_pw_aff, pair> as_multi_union_pw_aff() const; + inline typed::pw_multi_aff, pair> as_pw_multi_aff() const; + inline typed::set, pair> as_set() const = delete; + inline typed::union_map, pair> as_union_map() const; + inline typed::aff, Anonymous> at(int pos) const; + inline typed::aff, pair> get_at(int pos) const = delete; + inline typed::basic_set> bind(const typed::multi_id> &tuple) const; + inline typed::multi_aff> bind_domain(const typed::multi_id> &tuple) const; + inline typed::multi_aff> bind_domain_wrapped_domain(const typed::multi_id &tuple) const; + inline typed::pw_multi_aff, pair> coalesce() const; + inline typed::multi_val> constant_multi_val() const; + inline typed::multi_val, pair> get_constant_multi_val() const = delete; + inline typed::set> domain() const; + inline typed::multi_aff, pair> domain_reverse() const; + inline typed::pw_multi_aff, pair> drop_unused_params() const; + inline typed::pw_multi_aff, pair> extract_pw_multi_aff(const typed::space, pair> &space) const; + inline typed::multi_aff, pair> floor() const; + inline typed::multi_aff, pair> gist(const typed::set> &context) const; + inline typed::union_pw_multi_aff, pair> gist(const typed::union_set> &context) const; + inline typed::multi_aff, pair> gist(const typed::basic_set> &context) const; + inline typed::multi_aff, pair> gist(const typed::point> &context) const; + inline typed::multi_aff, pair> gist_params(const typed::set<> &context) const; + inline typed::multi_aff, pair> gist_params(const typed::basic_set<> &context) const; + inline typed::multi_aff, pair> gist_params(const typed::point<> &context) const; + inline typed::multi_aff, pair> identity() const; + inline typed::multi_aff, pair> insert_domain(const typed::space<> &domain) const = delete; + inline typed::pw_multi_aff, pair> intersect_domain(const typed::set> &set) const; + inline typed::union_pw_multi_aff, pair> intersect_domain(const typed::space> &space) const; + inline typed::union_pw_multi_aff, pair> intersect_domain(const typed::union_set> &uset) const; + inline typed::union_pw_multi_aff, pair> intersect_domain_wrapped_domain(const typed::union_set &uset) const; + inline typed::pw_multi_aff, pair> intersect_params(const typed::set<> &set) const; + inline typed::aff_list, Anonymous> list() const; + inline typed::aff_list, pair> get_list() const = delete; + inline typed::multi_pw_aff, pair> max(const typed::multi_pw_aff, pair> &multi2) const; + inline typed::multi_val> max_multi_val() const; + inline typed::multi_pw_aff, pair> min(const typed::multi_pw_aff, pair> &multi2) const; + inline typed::multi_val> min_multi_val() const; + inline typed::multi_aff, pair> neg() const; + template + inline typed::pw_multi_aff, pair> preimage_domain_wrapped_domain(const typed::pw_multi_aff &pma2) const; + template + inline typed::union_pw_multi_aff, pair> preimage_domain_wrapped_domain(const typed::union_pw_multi_aff &upma2) const; + template + inline typed::multi_aff, Domain2>, pair, Arg2>> product(const typed::multi_aff &multi2) const; + template + inline typed::multi_pw_aff, Domain2>, pair, Arg2>> product(const typed::multi_pw_aff &multi2) const; + template + inline typed::pw_multi_aff, Domain2>, pair, Arg2>> product(const typed::pw_multi_aff &pma2) const; + template + inline typed::multi_aff, Domain2>, pair, Anonymous>> product(const typed::aff &multi2) const; + template + inline typed::multi_aff> pullback(const typed::multi_aff> &ma2) const; + inline typed::multi_aff> pullback(const typed::multi_aff> &ma2) const; + template + inline typed::multi_pw_aff> pullback(const typed::multi_pw_aff> &mpa2) const; + inline typed::multi_pw_aff> pullback(const typed::multi_pw_aff> &mpa2) const; + template + inline typed::pw_multi_aff> pullback(const typed::pw_multi_aff> &pma2) const; + inline typed::pw_multi_aff> pullback(const typed::pw_multi_aff> &pma2) const; + template + inline typed::union_pw_multi_aff> pullback(const typed::union_pw_multi_aff> &upma2) const; + inline typed::union_pw_multi_aff> pullback(const typed::union_pw_multi_aff> &upma2) const; + template + inline typed::multi_aff> pullback(const typed::aff> &ma2) const; + inline typed::multi_aff> pullback(const typed::aff> &ma2) const; + inline typed::pw_multi_aff_list, pair> pw_multi_aff_list() const; + inline typed::pw_multi_aff, Range> range_factor_domain() const; + inline typed::pw_multi_aff, Range2> range_factor_range() const; + template + inline typed::multi_aff, pair, Arg2>> range_product(const typed::multi_aff, Arg2> &multi2) const; + template + inline typed::multi_pw_aff, pair, Arg2>> range_product(const typed::multi_pw_aff, Arg2> &multi2) const; + template + inline typed::multi_union_pw_aff, pair, Arg2>> range_product(const typed::multi_union_pw_aff, Arg2> &multi2) const; + template + inline typed::pw_multi_aff, pair, Arg2>> range_product(const typed::pw_multi_aff, Arg2> &pma2) const; + template + inline typed::union_pw_multi_aff, pair, Arg2>> range_product(const typed::union_pw_multi_aff, Arg2> &upma2) const; + inline typed::multi_aff, pair, Anonymous>> range_product(const typed::aff, Anonymous> &multi2) const; + inline typed::id, pair> get_range_tuple_id() const = delete; + inline typed::multi_aff, pair> scale(const typed::multi_val> &mv) const; + inline typed::multi_aff, pair> scale(const typed::val> &v) const; + inline typed::multi_aff, pair> scale(long v) const; + inline typed::multi_aff, pair> scale_down(const typed::multi_val> &mv) const; + inline typed::multi_aff, pair> scale_down(const typed::val> &v) const; + inline typed::multi_aff, pair> scale_down(long v) const; + inline typed::multi_aff, pair> set_at(int pos, const typed::aff, Anonymous> &el) const; + inline typed::multi_pw_aff, pair> set_at(int pos, const typed::pw_aff, Anonymous> &el) const; + inline typed::multi_union_pw_aff, pair> set_at(int pos, const typed::union_pw_aff, Anonymous> &el) const; + inline typed::multi_aff, pair> set_range_tuple(const typed::id<> &id) const = delete; + inline typed::multi_aff, pair> set_range_tuple(const std::string &id) const = delete; + inline typed::space, pair> space() const; + inline typed::space, pair> get_space() const = delete; + inline typed::multi_aff, pair> sub(const typed::multi_aff, pair> &multi2) const; + inline typed::multi_pw_aff, pair> sub(const typed::multi_pw_aff, pair> &multi2) const; + inline typed::multi_union_pw_aff, pair> sub(const typed::multi_union_pw_aff, pair> &multi2) const; + inline typed::pw_multi_aff, pair> sub(const typed::pw_multi_aff, pair> &pma2) const; + inline typed::union_pw_multi_aff, pair> sub(const typed::union_pw_multi_aff, pair> &upma2) const; + inline typed::multi_aff, pair> sub(const typed::aff, pair> &multi2) const; + inline typed::pw_multi_aff, pair> subtract_domain(const typed::set> &set) const; + inline typed::union_pw_multi_aff, pair> subtract_domain(const typed::space> &space) const; + inline typed::union_pw_multi_aff, pair> subtract_domain(const typed::union_set> &uset) const; + inline typed::multi_pw_aff, pair> to_multi_pw_aff() const; + inline typed::multi_union_pw_aff, pair> to_multi_union_pw_aff() const; + inline typed::pw_multi_aff, pair> to_pw_multi_aff() const; + inline typed::union_pw_multi_aff, pair> to_union_pw_multi_aff() const; + inline typed::multi_aff, pair> unbind_params_insert_domain(const typed::multi_id<> &domain) const = delete; + inline typed::multi_pw_aff, pair> union_add(const typed::multi_pw_aff, pair> &mpa2) const; + inline typed::multi_union_pw_aff, pair> union_add(const typed::multi_union_pw_aff, pair> &mupa2) const; + inline typed::pw_multi_aff, pair> union_add(const typed::pw_multi_aff, pair> &pma2) const; + inline typed::union_pw_multi_aff, pair> union_add(const typed::union_pw_multi_aff, pair> &upma2) const; +}; + +template +struct multi_id : public isl::multi_id { + template + friend struct aff; + template + friend struct aff_list; + template + friend struct basic_map; + template + friend struct basic_set; + template + friend struct fixed_box; + template + friend struct id; + template + friend struct id_list; + template + friend struct map; + template + friend struct map_list; + template + friend struct multi_aff; + template + friend struct multi_id; + template + friend struct multi_pw_aff; + template + friend struct multi_union_pw_aff; + template + friend struct multi_val; + template + friend struct point; + template + friend struct pw_aff; + template + friend struct pw_aff_list; + template + friend struct pw_multi_aff; + template + friend struct pw_multi_aff_list; + template + friend struct set; + template + friend struct set_list; + template + friend struct space; + template + friend struct union_map; + template + friend struct union_pw_aff; + template + friend struct union_pw_aff_list; + template + friend struct union_pw_multi_aff; + template + friend struct union_set; + template + friend struct union_set_list; + template + friend struct val; + template + friend struct val_list; + + multi_id() = default; + template {}, + bool>::type = true> + multi_id(const multi_id &obj) : isl::multi_id(obj) {} + private: + template {}, bool>::type = true> + multi_id(const base &obj) : isl::multi_id(obj) {} + public: + static multi_id from(const isl::multi_id &obj) { + return multi_id(obj); + } + inline explicit multi_id(const typed::space &space, const typed::id_list &list); + inline explicit multi_id(const isl::ctx &ctx, const std::string &str); + inline typed::id at(int pos) const; + inline typed::id get_at(int pos) const = delete; + inline typed::id_list list() const; + inline typed::id_list get_list() const = delete; + inline typed::multi_id range_product(const typed::multi_id<> &multi2) const = delete; + inline typed::multi_id set_at(int pos, const typed::id &el) const; + inline typed::multi_id set_at(int pos, const std::string &el) const; + inline typed::space space() const; + inline typed::space get_space() const = delete; +}; + +template +struct multi_pw_aff : public isl::multi_pw_aff { + template + friend struct aff; + template + friend struct aff_list; + template + friend struct basic_map; + template + friend struct basic_set; + template + friend struct fixed_box; + template + friend struct id; + template + friend struct id_list; + template + friend struct map; + template + friend struct map_list; + template + friend struct multi_aff; + template + friend struct multi_id; + template + friend struct multi_pw_aff; + template + friend struct multi_union_pw_aff; + template + friend struct multi_val; + template + friend struct point; + template + friend struct pw_aff; + template + friend struct pw_aff_list; + template + friend struct pw_multi_aff; + template + friend struct pw_multi_aff_list; + template + friend struct set; + template + friend struct set_list; + template + friend struct space; + template + friend struct union_map; + template + friend struct union_pw_aff; + template + friend struct union_pw_aff_list; + template + friend struct union_pw_multi_aff; + template + friend struct union_set; + template + friend struct union_set_list; + template + friend struct val; + template + friend struct val_list; + + multi_pw_aff() = default; + template {}, + bool>::type = true> + multi_pw_aff(const multi_pw_aff &obj) : isl::multi_pw_aff(obj) {} + private: + template {}, bool>::type = true> + multi_pw_aff(const base &obj) : isl::multi_pw_aff(obj) {} + public: + static multi_pw_aff from(const isl::multi_pw_aff &obj) { + return multi_pw_aff(obj); + } + inline /* implicit */ multi_pw_aff(const typed::aff &aff); + inline /* implicit */ multi_pw_aff(const typed::multi_aff &ma); + inline /* implicit */ multi_pw_aff(const typed::pw_aff &pa); + inline explicit multi_pw_aff(const typed::space &space, const typed::pw_aff_list &list); + inline /* implicit */ multi_pw_aff(const typed::pw_multi_aff &pma); + inline explicit multi_pw_aff(const isl::ctx &ctx, const std::string &str); + inline typed::multi_pw_aff add(const typed::multi_pw_aff &multi2) const; + inline typed::multi_union_pw_aff add(const typed::multi_union_pw_aff &multi2) const; + inline typed::multi_pw_aff add(const typed::aff &multi2) const; + inline typed::multi_pw_aff add(const typed::multi_aff &multi2) const; + inline typed::multi_pw_aff add(const typed::pw_aff &multi2) const; + inline typed::multi_pw_aff add(const typed::pw_multi_aff &multi2) const; + inline typed::multi_pw_aff add_constant(const typed::multi_val &mv) const; + inline typed::multi_pw_aff add_constant(const typed::val &v) const; + inline typed::multi_pw_aff add_constant(long v) const; + inline typed::map as_map() const = delete; + inline typed::multi_aff as_multi_aff() const; + inline typed::set as_set() const; + inline typed::pw_aff at(int pos) const; + inline typed::pw_aff get_at(int pos) const = delete; + inline typed::set<> bind(const typed::multi_id &tuple) const; + inline typed::multi_pw_aff bind_domain(const typed::multi_id<> &tuple) const = delete; + inline typed::multi_pw_aff bind_domain_wrapped_domain(const typed::multi_id<> &tuple) const = delete; + inline typed::multi_pw_aff coalesce() const; + inline typed::set<> domain() const; + inline typed::multi_pw_aff domain_reverse() const = delete; + inline typed::multi_pw_aff gist(const typed::set<> &set) const; + inline typed::multi_union_pw_aff gist(const typed::union_set<> &context) const; + inline typed::multi_pw_aff gist(const typed::basic_set<> &set) const; + inline typed::multi_pw_aff gist(const typed::point<> &set) const; + inline typed::multi_pw_aff gist_params(const typed::set<> &set) const; + inline typed::multi_pw_aff gist_params(const typed::basic_set<> &set) const; + inline typed::multi_pw_aff gist_params(const typed::point<> &set) const; + inline typed::multi_pw_aff identity() const; + template + inline typed::multi_pw_aff insert_domain(const typed::space &domain) const; + inline typed::multi_pw_aff intersect_domain(const typed::set<> &domain) const = delete; + inline typed::multi_union_pw_aff intersect_domain(const typed::union_set<> &uset) const = delete; + inline typed::multi_pw_aff intersect_domain(const typed::basic_set<> &domain) const = delete; + inline typed::multi_pw_aff intersect_domain(const typed::point<> &domain) const = delete; + inline typed::multi_pw_aff intersect_params(const typed::set<> &set) const; + inline typed::multi_pw_aff intersect_params(const typed::basic_set<> &set) const; + inline typed::multi_pw_aff intersect_params(const typed::point<> &set) const; + inline typed::pw_aff_list list() const; + inline typed::pw_aff_list get_list() const = delete; + inline typed::multi_pw_aff max(const typed::multi_pw_aff &multi2) const; + inline typed::multi_pw_aff max(const typed::aff &multi2) const; + inline typed::multi_pw_aff max(const typed::multi_aff &multi2) const; + inline typed::multi_pw_aff max(const typed::pw_aff &multi2) const; + inline typed::multi_pw_aff max(const typed::pw_multi_aff &multi2) const; + inline typed::multi_val max_multi_val() const; + inline typed::multi_pw_aff min(const typed::multi_pw_aff &multi2) const; + inline typed::multi_pw_aff min(const typed::aff &multi2) const; + inline typed::multi_pw_aff min(const typed::multi_aff &multi2) const; + inline typed::multi_pw_aff min(const typed::pw_aff &multi2) const; + inline typed::multi_pw_aff min(const typed::pw_multi_aff &multi2) const; + inline typed::multi_val min_multi_val() const; + inline typed::multi_pw_aff neg() const; + template + inline typed::multi_pw_aff> product(const typed::multi_pw_aff &multi2) const; + inline typed::multi_pw_aff> product(const typed::aff &multi2) const; + template + inline typed::multi_pw_aff> product(const typed::multi_aff &multi2) const; + inline typed::multi_pw_aff> product(const typed::pw_aff &multi2) const; + template + inline typed::multi_pw_aff> product(const typed::pw_multi_aff &multi2) const; + inline typed::multi_pw_aff pullback(const typed::multi_aff<> &ma) const = delete; + inline typed::multi_pw_aff pullback(const typed::multi_pw_aff<> &mpa2) const = delete; + inline typed::multi_pw_aff pullback(const typed::pw_multi_aff<> &pma) const = delete; + inline typed::multi_union_pw_aff pullback(const typed::union_pw_multi_aff<> &upma) const = delete; + inline typed::multi_pw_aff range_product(const typed::multi_pw_aff<> &multi2) const = delete; + inline typed::multi_union_pw_aff range_product(const typed::multi_union_pw_aff<> &multi2) const = delete; + inline typed::multi_pw_aff range_product(const typed::aff<> &multi2) const = delete; + inline typed::multi_pw_aff range_product(const typed::multi_aff<> &multi2) const = delete; + inline typed::multi_pw_aff range_product(const typed::pw_aff<> &multi2) const = delete; + inline typed::multi_pw_aff range_product(const typed::pw_multi_aff<> &multi2) const = delete; + inline typed::id get_range_tuple_id() const = delete; + inline typed::multi_pw_aff scale(const typed::multi_val &mv) const; + inline typed::multi_pw_aff scale(const typed::val &v) const; + inline typed::multi_pw_aff scale(long v) const; + inline typed::multi_pw_aff scale_down(const typed::multi_val &mv) const; + inline typed::multi_pw_aff scale_down(const typed::val &v) const; + inline typed::multi_pw_aff scale_down(long v) const; + inline typed::multi_pw_aff set_at(int pos, const typed::pw_aff &el) const; + inline typed::multi_union_pw_aff set_at(int pos, const typed::union_pw_aff &el) const; + template + inline typed::multi_pw_aff set_range_tuple(const typed::id &id) const; + template + inline typed::multi_pw_aff set_range_tuple(const std::string &id) const; + inline typed::space space() const; + inline typed::space get_space() const = delete; + inline typed::multi_pw_aff sub(const typed::multi_pw_aff &multi2) const; + inline typed::multi_union_pw_aff sub(const typed::multi_union_pw_aff &multi2) const; + inline typed::multi_pw_aff sub(const typed::aff &multi2) const; + inline typed::multi_pw_aff sub(const typed::multi_aff &multi2) const; + inline typed::multi_pw_aff sub(const typed::pw_aff &multi2) const; + inline typed::multi_pw_aff sub(const typed::pw_multi_aff &multi2) const; + template + inline typed::multi_pw_aff unbind_params_insert_domain(const typed::multi_id &domain) const; + inline typed::multi_pw_aff union_add(const typed::multi_pw_aff &mpa2) const; + inline typed::multi_union_pw_aff union_add(const typed::multi_union_pw_aff &mupa2) const; + inline typed::multi_pw_aff union_add(const typed::aff &mpa2) const; + inline typed::multi_pw_aff union_add(const typed::multi_aff &mpa2) const; + inline typed::multi_pw_aff union_add(const typed::pw_aff &mpa2) const; + inline typed::multi_pw_aff union_add(const typed::pw_multi_aff &mpa2) const; +}; + +template +struct multi_pw_aff : public isl::multi_pw_aff { + template + friend struct aff; + template + friend struct aff_list; + template + friend struct basic_map; + template + friend struct basic_set; + template + friend struct fixed_box; + template + friend struct id; + template + friend struct id_list; + template + friend struct map; + template + friend struct map_list; + template + friend struct multi_aff; + template + friend struct multi_id; + template + friend struct multi_pw_aff; + template + friend struct multi_union_pw_aff; + template + friend struct multi_val; + template + friend struct point; + template + friend struct pw_aff; + template + friend struct pw_aff_list; + template + friend struct pw_multi_aff; + template + friend struct pw_multi_aff_list; + template + friend struct set; + template + friend struct set_list; + template + friend struct space; + template + friend struct union_map; + template + friend struct union_pw_aff; + template + friend struct union_pw_aff_list; + template + friend struct union_pw_multi_aff; + template + friend struct union_set; + template + friend struct union_set_list; + template + friend struct val; + template + friend struct val_list; + + multi_pw_aff() = default; + template {} && + std::is_base_of{}, + bool>::type = true> + multi_pw_aff(const multi_pw_aff &obj) : isl::multi_pw_aff(obj) {} + private: + template {}, bool>::type = true> + multi_pw_aff(const base &obj) : isl::multi_pw_aff(obj) {} + public: + static multi_pw_aff from(const isl::multi_pw_aff &obj) { + return multi_pw_aff(obj); + } + inline /* implicit */ multi_pw_aff(const typed::aff &aff); + inline /* implicit */ multi_pw_aff(const typed::multi_aff &ma); + inline /* implicit */ multi_pw_aff(const typed::pw_aff &pa); + inline explicit multi_pw_aff(const typed::space &space, const typed::pw_aff_list &list); + inline /* implicit */ multi_pw_aff(const typed::pw_multi_aff &pma); + inline explicit multi_pw_aff(const isl::ctx &ctx, const std::string &str); + inline typed::multi_pw_aff add(const typed::multi_pw_aff &multi2) const; + inline typed::multi_union_pw_aff add(const typed::multi_union_pw_aff &multi2) const; + inline typed::multi_pw_aff add(const typed::aff &multi2) const; + inline typed::multi_pw_aff add(const typed::multi_aff &multi2) const; + inline typed::multi_pw_aff add(const typed::pw_aff &multi2) const; + inline typed::multi_pw_aff add(const typed::pw_multi_aff &multi2) const; + inline typed::multi_pw_aff add_constant(const typed::multi_val &mv) const; + inline typed::multi_pw_aff add_constant(const typed::val &v) const; + inline typed::multi_pw_aff add_constant(long v) const; + inline typed::map as_map() const; + inline typed::multi_aff as_multi_aff() const; + inline typed::set as_set() const = delete; + inline typed::pw_aff at(int pos) const; + inline typed::pw_aff get_at(int pos) const = delete; + inline typed::set bind(const typed::multi_id &tuple) const; + inline typed::multi_pw_aff bind_domain(const typed::multi_id &tuple) const; + inline typed::multi_pw_aff bind_domain_wrapped_domain(const typed::multi_id<> &tuple) const = delete; + inline typed::multi_pw_aff coalesce() const; + inline typed::set domain() const; + inline typed::multi_pw_aff domain_reverse() const = delete; + inline typed::multi_pw_aff gist(const typed::set &set) const; + inline typed::multi_union_pw_aff gist(const typed::union_set &context) const; + inline typed::multi_pw_aff gist(const typed::basic_set &set) const; + inline typed::multi_pw_aff gist(const typed::point &set) const; + inline typed::multi_pw_aff gist_params(const typed::set<> &set) const; + inline typed::multi_pw_aff gist_params(const typed::basic_set<> &set) const; + inline typed::multi_pw_aff gist_params(const typed::point<> &set) const; + inline typed::multi_pw_aff identity() const; + inline typed::multi_pw_aff insert_domain(const typed::space<> &domain) const = delete; + inline typed::multi_pw_aff intersect_domain(const typed::set &domain) const; + inline typed::multi_union_pw_aff intersect_domain(const typed::union_set &uset) const; + inline typed::multi_pw_aff intersect_domain(const typed::basic_set &domain) const; + inline typed::multi_pw_aff intersect_domain(const typed::point &domain) const; + inline typed::multi_pw_aff intersect_params(const typed::set<> &set) const; + inline typed::multi_pw_aff intersect_params(const typed::basic_set<> &set) const; + inline typed::multi_pw_aff intersect_params(const typed::point<> &set) const; + inline typed::pw_aff_list list() const; + inline typed::pw_aff_list get_list() const = delete; + inline typed::multi_pw_aff max(const typed::multi_pw_aff &multi2) const; + inline typed::multi_pw_aff max(const typed::aff &multi2) const; + inline typed::multi_pw_aff max(const typed::multi_aff &multi2) const; + inline typed::multi_pw_aff max(const typed::pw_aff &multi2) const; + inline typed::multi_pw_aff max(const typed::pw_multi_aff &multi2) const; + inline typed::multi_val max_multi_val() const; + inline typed::multi_pw_aff min(const typed::multi_pw_aff &multi2) const; + inline typed::multi_pw_aff min(const typed::aff &multi2) const; + inline typed::multi_pw_aff min(const typed::multi_aff &multi2) const; + inline typed::multi_pw_aff min(const typed::pw_aff &multi2) const; + inline typed::multi_pw_aff min(const typed::pw_multi_aff &multi2) const; + inline typed::multi_val min_multi_val() const; + inline typed::multi_pw_aff neg() const; + template + inline typed::multi_pw_aff, pair> product(const typed::multi_pw_aff &multi2) const; + template + inline typed::multi_pw_aff, pair> product(const typed::aff &multi2) const; + template + inline typed::multi_pw_aff, pair> product(const typed::multi_aff &multi2) const; + template + inline typed::multi_pw_aff, pair> product(const typed::pw_aff &multi2) const; + template + inline typed::multi_pw_aff, pair> product(const typed::pw_multi_aff &multi2) const; + template + inline typed::multi_pw_aff pullback(const typed::multi_aff &ma) const; + inline typed::multi_pw_aff pullback(const typed::multi_aff &ma) const; + template + inline typed::multi_pw_aff pullback(const typed::multi_pw_aff &mpa2) const; + inline typed::multi_pw_aff pullback(const typed::multi_pw_aff &mpa2) const; + template + inline typed::multi_pw_aff pullback(const typed::pw_multi_aff &pma) const; + inline typed::multi_pw_aff pullback(const typed::pw_multi_aff &pma) const; + template + inline typed::multi_union_pw_aff pullback(const typed::union_pw_multi_aff &upma) const; + inline typed::multi_union_pw_aff pullback(const typed::union_pw_multi_aff &upma) const; + template + inline typed::multi_pw_aff> range_product(const typed::multi_pw_aff &multi2) const; + template + inline typed::multi_union_pw_aff> range_product(const typed::multi_union_pw_aff &multi2) const; + inline typed::multi_pw_aff> range_product(const typed::aff &multi2) const; + template + inline typed::multi_pw_aff> range_product(const typed::multi_aff &multi2) const; + inline typed::multi_pw_aff> range_product(const typed::pw_aff &multi2) const; + template + inline typed::multi_pw_aff> range_product(const typed::pw_multi_aff &multi2) const; + inline typed::id get_range_tuple_id() const = delete; + inline typed::multi_pw_aff scale(const typed::multi_val &mv) const; + inline typed::multi_pw_aff scale(const typed::val &v) const; + inline typed::multi_pw_aff scale(long v) const; + inline typed::multi_pw_aff scale_down(const typed::multi_val &mv) const; + inline typed::multi_pw_aff scale_down(const typed::val &v) const; + inline typed::multi_pw_aff scale_down(long v) const; + inline typed::multi_pw_aff set_at(int pos, const typed::pw_aff &el) const; + inline typed::multi_union_pw_aff set_at(int pos, const typed::union_pw_aff &el) const; + template + inline typed::multi_pw_aff set_range_tuple(const typed::id &id) const; + template + inline typed::multi_pw_aff set_range_tuple(const std::string &id) const; + inline typed::space space() const; + inline typed::space get_space() const = delete; + inline typed::multi_pw_aff sub(const typed::multi_pw_aff &multi2) const; + inline typed::multi_union_pw_aff sub(const typed::multi_union_pw_aff &multi2) const; + inline typed::multi_pw_aff sub(const typed::aff &multi2) const; + inline typed::multi_pw_aff sub(const typed::multi_aff &multi2) const; + inline typed::multi_pw_aff sub(const typed::pw_aff &multi2) const; + inline typed::multi_pw_aff sub(const typed::pw_multi_aff &multi2) const; + inline typed::multi_pw_aff unbind_params_insert_domain(const typed::multi_id<> &domain) const = delete; + inline typed::multi_pw_aff union_add(const typed::multi_pw_aff &mpa2) const; + inline typed::multi_union_pw_aff union_add(const typed::multi_union_pw_aff &mupa2) const; + inline typed::multi_pw_aff union_add(const typed::aff &mpa2) const; + inline typed::multi_pw_aff union_add(const typed::multi_aff &mpa2) const; + inline typed::multi_pw_aff union_add(const typed::pw_aff &mpa2) const; + inline typed::multi_pw_aff union_add(const typed::pw_multi_aff &mpa2) const; +}; + +template +struct multi_pw_aff, Range> : public isl::multi_pw_aff { + template + friend struct aff; + template + friend struct aff_list; + template + friend struct basic_map; + template + friend struct basic_set; + template + friend struct fixed_box; + template + friend struct id; + template + friend struct id_list; + template + friend struct map; + template + friend struct map_list; + template + friend struct multi_aff; + template + friend struct multi_id; + template + friend struct multi_pw_aff; + template + friend struct multi_union_pw_aff; + template + friend struct multi_val; + template + friend struct point; + template + friend struct pw_aff; + template + friend struct pw_aff_list; + template + friend struct pw_multi_aff; + template + friend struct pw_multi_aff_list; + template + friend struct set; + template + friend struct set_list; + template + friend struct space; + template + friend struct union_map; + template + friend struct union_pw_aff; + template + friend struct union_pw_aff_list; + template + friend struct union_pw_multi_aff; + template + friend struct union_set; + template + friend struct union_set_list; + template + friend struct val; + template + friend struct val_list; + + multi_pw_aff() = default; + template {} && + std::is_base_of{} && + std::is_base_of{}, + bool>::type = true> + multi_pw_aff(const multi_pw_aff, Arg3> &obj) : isl::multi_pw_aff(obj) {} + private: + template {}, bool>::type = true> + multi_pw_aff(const base &obj) : isl::multi_pw_aff(obj) {} + public: + static multi_pw_aff from(const isl::multi_pw_aff &obj) { + return multi_pw_aff(obj); + } + inline /* implicit */ multi_pw_aff(const typed::aff, Range> &aff); + inline /* implicit */ multi_pw_aff(const typed::multi_aff, Range> &ma); + inline /* implicit */ multi_pw_aff(const typed::pw_aff, Range> &pa); + inline explicit multi_pw_aff(const typed::space, Range> &space, const typed::pw_aff_list, Anonymous> &list); + inline /* implicit */ multi_pw_aff(const typed::pw_multi_aff, Range> &pma); + inline explicit multi_pw_aff(const isl::ctx &ctx, const std::string &str); + inline typed::multi_pw_aff, Range> add(const typed::multi_pw_aff, Range> &multi2) const; + inline typed::multi_union_pw_aff, Range> add(const typed::multi_union_pw_aff, Range> &multi2) const; + inline typed::multi_pw_aff, Range> add(const typed::aff, Range> &multi2) const; + inline typed::multi_pw_aff, Range> add(const typed::multi_aff, Range> &multi2) const; + inline typed::multi_pw_aff, Range> add(const typed::pw_aff, Range> &multi2) const; + inline typed::multi_pw_aff, Range> add(const typed::pw_multi_aff, Range> &multi2) const; + inline typed::multi_pw_aff, Range> add_constant(const typed::multi_val &mv) const; + inline typed::multi_pw_aff, Range> add_constant(const typed::val &v) const; + inline typed::multi_pw_aff, Range> add_constant(long v) const; + inline typed::map, Range> as_map() const; + inline typed::multi_aff, Range> as_multi_aff() const; + inline typed::set, Range> as_set() const = delete; + inline typed::pw_aff, Anonymous> at(int pos) const; + inline typed::pw_aff, Range> get_at(int pos) const = delete; + inline typed::set> bind(const typed::multi_id &tuple) const; + inline typed::multi_pw_aff bind_domain(const typed::multi_id> &tuple) const; + inline typed::multi_pw_aff bind_domain_wrapped_domain(const typed::multi_id &tuple) const; + inline typed::multi_pw_aff, Range> coalesce() const; + inline typed::set> domain() const; + inline typed::multi_pw_aff, Range> domain_reverse() const; + inline typed::multi_pw_aff, Range> gist(const typed::set> &set) const; + inline typed::multi_union_pw_aff, Range> gist(const typed::union_set> &context) const; + inline typed::multi_pw_aff, Range> gist(const typed::basic_set> &set) const; + inline typed::multi_pw_aff, Range> gist(const typed::point> &set) const; + inline typed::multi_pw_aff, Range> gist_params(const typed::set<> &set) const; + inline typed::multi_pw_aff, Range> gist_params(const typed::basic_set<> &set) const; + inline typed::multi_pw_aff, Range> gist_params(const typed::point<> &set) const; + inline typed::multi_pw_aff, Range> identity() const; + inline typed::multi_pw_aff, Range> insert_domain(const typed::space<> &domain) const = delete; + inline typed::multi_pw_aff, Range> intersect_domain(const typed::set> &domain) const; + inline typed::multi_union_pw_aff, Range> intersect_domain(const typed::union_set> &uset) const; + inline typed::multi_pw_aff, Range> intersect_domain(const typed::basic_set> &domain) const; + inline typed::multi_pw_aff, Range> intersect_domain(const typed::point> &domain) const; + inline typed::multi_pw_aff, Range> intersect_params(const typed::set<> &set) const; + inline typed::multi_pw_aff, Range> intersect_params(const typed::basic_set<> &set) const; + inline typed::multi_pw_aff, Range> intersect_params(const typed::point<> &set) const; + inline typed::pw_aff_list, Anonymous> list() const; + inline typed::pw_aff_list, Range> get_list() const = delete; + inline typed::multi_pw_aff, Range> max(const typed::multi_pw_aff, Range> &multi2) const; + inline typed::multi_pw_aff, Range> max(const typed::aff, Range> &multi2) const; + inline typed::multi_pw_aff, Range> max(const typed::multi_aff, Range> &multi2) const; + inline typed::multi_pw_aff, Range> max(const typed::pw_aff, Range> &multi2) const; + inline typed::multi_pw_aff, Range> max(const typed::pw_multi_aff, Range> &multi2) const; + inline typed::multi_val max_multi_val() const; + inline typed::multi_pw_aff, Range> min(const typed::multi_pw_aff, Range> &multi2) const; + inline typed::multi_pw_aff, Range> min(const typed::aff, Range> &multi2) const; + inline typed::multi_pw_aff, Range> min(const typed::multi_aff, Range> &multi2) const; + inline typed::multi_pw_aff, Range> min(const typed::pw_aff, Range> &multi2) const; + inline typed::multi_pw_aff, Range> min(const typed::pw_multi_aff, Range> &multi2) const; + inline typed::multi_val min_multi_val() const; + inline typed::multi_pw_aff, Range> neg() const; + template + inline typed::multi_pw_aff, Arg2>, pair> product(const typed::multi_pw_aff &multi2) const; + template + inline typed::multi_pw_aff, Arg2>, pair> product(const typed::aff &multi2) const; + template + inline typed::multi_pw_aff, Arg2>, pair> product(const typed::multi_aff &multi2) const; + template + inline typed::multi_pw_aff, Arg2>, pair> product(const typed::pw_aff &multi2) const; + template + inline typed::multi_pw_aff, Arg2>, pair> product(const typed::pw_multi_aff &multi2) const; + template + inline typed::multi_pw_aff pullback(const typed::multi_aff> &ma) const; + inline typed::multi_pw_aff pullback(const typed::multi_aff> &ma) const; + template + inline typed::multi_pw_aff pullback(const typed::multi_pw_aff> &mpa2) const; + inline typed::multi_pw_aff pullback(const typed::multi_pw_aff> &mpa2) const; + template + inline typed::multi_pw_aff pullback(const typed::pw_multi_aff> &pma) const; + inline typed::multi_pw_aff pullback(const typed::pw_multi_aff> &pma) const; + template + inline typed::multi_union_pw_aff pullback(const typed::union_pw_multi_aff> &upma) const; + inline typed::multi_union_pw_aff pullback(const typed::union_pw_multi_aff> &upma) const; + template + inline typed::multi_pw_aff, pair> range_product(const typed::multi_pw_aff, Arg2> &multi2) const; + template + inline typed::multi_union_pw_aff, pair> range_product(const typed::multi_union_pw_aff, Arg2> &multi2) const; + inline typed::multi_pw_aff, pair> range_product(const typed::aff, Anonymous> &multi2) const; + template + inline typed::multi_pw_aff, pair> range_product(const typed::multi_aff, Arg2> &multi2) const; + inline typed::multi_pw_aff, pair> range_product(const typed::pw_aff, Anonymous> &multi2) const; + template + inline typed::multi_pw_aff, pair> range_product(const typed::pw_multi_aff, Arg2> &multi2) const; + inline typed::id, Range> get_range_tuple_id() const = delete; + inline typed::multi_pw_aff, Range> scale(const typed::multi_val &mv) const; + inline typed::multi_pw_aff, Range> scale(const typed::val &v) const; + inline typed::multi_pw_aff, Range> scale(long v) const; + inline typed::multi_pw_aff, Range> scale_down(const typed::multi_val &mv) const; + inline typed::multi_pw_aff, Range> scale_down(const typed::val &v) const; + inline typed::multi_pw_aff, Range> scale_down(long v) const; + inline typed::multi_pw_aff, Range> set_at(int pos, const typed::pw_aff, Anonymous> &el) const; + inline typed::multi_union_pw_aff, Range> set_at(int pos, const typed::union_pw_aff, Anonymous> &el) const; + template + inline typed::multi_pw_aff, Arg1> set_range_tuple(const typed::id &id) const; + template + inline typed::multi_pw_aff, Arg1> set_range_tuple(const std::string &id) const; + inline typed::space, Range> space() const; + inline typed::space, Range> get_space() const = delete; + inline typed::multi_pw_aff, Range> sub(const typed::multi_pw_aff, Range> &multi2) const; + inline typed::multi_union_pw_aff, Range> sub(const typed::multi_union_pw_aff, Range> &multi2) const; + inline typed::multi_pw_aff, Range> sub(const typed::aff, Range> &multi2) const; + inline typed::multi_pw_aff, Range> sub(const typed::multi_aff, Range> &multi2) const; + inline typed::multi_pw_aff, Range> sub(const typed::pw_aff, Range> &multi2) const; + inline typed::multi_pw_aff, Range> sub(const typed::pw_multi_aff, Range> &multi2) const; + inline typed::multi_pw_aff, Range> unbind_params_insert_domain(const typed::multi_id<> &domain) const = delete; + inline typed::multi_pw_aff, Range> union_add(const typed::multi_pw_aff, Range> &mpa2) const; + inline typed::multi_union_pw_aff, Range> union_add(const typed::multi_union_pw_aff, Range> &mupa2) const; + inline typed::multi_pw_aff, Range> union_add(const typed::aff, Range> &mpa2) const; + inline typed::multi_pw_aff, Range> union_add(const typed::multi_aff, Range> &mpa2) const; + inline typed::multi_pw_aff, Range> union_add(const typed::pw_aff, Range> &mpa2) const; + inline typed::multi_pw_aff, Range> union_add(const typed::pw_multi_aff, Range> &mpa2) const; +}; + +template +struct multi_union_pw_aff : public isl::multi_union_pw_aff { + template + friend struct aff; + template + friend struct aff_list; + template + friend struct basic_map; + template + friend struct basic_set; + template + friend struct fixed_box; + template + friend struct id; + template + friend struct id_list; + template + friend struct map; + template + friend struct map_list; + template + friend struct multi_aff; + template + friend struct multi_id; + template + friend struct multi_pw_aff; + template + friend struct multi_union_pw_aff; + template + friend struct multi_val; + template + friend struct point; + template + friend struct pw_aff; + template + friend struct pw_aff_list; + template + friend struct pw_multi_aff; + template + friend struct pw_multi_aff_list; + template + friend struct set; + template + friend struct set_list; + template + friend struct space; + template + friend struct union_map; + template + friend struct union_pw_aff; + template + friend struct union_pw_aff_list; + template + friend struct union_pw_multi_aff; + template + friend struct union_set; + template + friend struct union_set_list; + template + friend struct val; + template + friend struct val_list; + + multi_union_pw_aff() = default; + template {}, + bool>::type = true> + multi_union_pw_aff(const multi_union_pw_aff &obj) : isl::multi_union_pw_aff(obj) {} + private: + template {}, bool>::type = true> + multi_union_pw_aff(const base &obj) : isl::multi_union_pw_aff(obj) {} + public: + static multi_union_pw_aff from(const isl::multi_union_pw_aff &obj) { + return multi_union_pw_aff(obj); + } + inline /* implicit */ multi_union_pw_aff(const typed::multi_pw_aff &mpa); + inline /* implicit */ multi_union_pw_aff(const typed::union_pw_aff &upa); + inline explicit multi_union_pw_aff(const typed::space &space, const typed::union_pw_aff_list &list); + inline explicit multi_union_pw_aff(const isl::ctx &ctx, const std::string &str); + inline typed::multi_union_pw_aff add(const typed::multi_union_pw_aff &multi2) const; + inline typed::multi_union_pw_aff add(const typed::multi_pw_aff &multi2) const; + inline typed::multi_union_pw_aff add(const typed::union_pw_aff &multi2) const; + inline typed::union_pw_aff at(int pos) const; + inline typed::union_pw_aff get_at(int pos) const = delete; + inline typed::union_set<> bind(const typed::multi_id &tuple) const; + inline typed::multi_union_pw_aff coalesce() const; + inline typed::union_set<> domain() const; + inline typed::multi_union_pw_aff gist(const typed::union_set<> &context) const; + inline typed::multi_union_pw_aff gist(const typed::basic_set<> &context) const; + inline typed::multi_union_pw_aff gist(const typed::point<> &context) const; + inline typed::multi_union_pw_aff gist(const typed::set<> &context) const; + inline typed::multi_union_pw_aff gist_params(const typed::set<> &context) const; + inline typed::multi_union_pw_aff gist_params(const typed::basic_set<> &context) const; + inline typed::multi_union_pw_aff gist_params(const typed::point<> &context) const; + inline typed::multi_union_pw_aff intersect_domain(const typed::union_set<> &uset) const = delete; + inline typed::multi_union_pw_aff intersect_domain(const typed::basic_set<> &uset) const = delete; + inline typed::multi_union_pw_aff intersect_domain(const typed::point<> &uset) const = delete; + inline typed::multi_union_pw_aff intersect_domain(const typed::set<> &uset) const = delete; + inline typed::multi_union_pw_aff intersect_params(const typed::set<> ¶ms) const; + inline typed::multi_union_pw_aff intersect_params(const typed::basic_set<> ¶ms) const; + inline typed::multi_union_pw_aff intersect_params(const typed::point<> ¶ms) const; + inline typed::union_pw_aff_list list() const; + inline typed::union_pw_aff_list get_list() const = delete; + inline typed::multi_union_pw_aff neg() const; + inline typed::multi_union_pw_aff pullback(const typed::union_pw_multi_aff<> &upma) const = delete; + inline typed::multi_union_pw_aff pullback(const typed::multi_aff<> &upma) const = delete; + inline typed::multi_union_pw_aff pullback(const typed::pw_multi_aff<> &upma) const = delete; + inline typed::multi_union_pw_aff pullback(const typed::union_pw_aff<> &upma) const = delete; + inline typed::multi_union_pw_aff range_product(const typed::multi_union_pw_aff<> &multi2) const = delete; + inline typed::multi_union_pw_aff range_product(const typed::multi_pw_aff<> &multi2) const = delete; + inline typed::multi_union_pw_aff range_product(const typed::union_pw_aff<> &multi2) const = delete; + inline typed::id get_range_tuple_id() const = delete; + inline typed::multi_union_pw_aff scale(const typed::multi_val &mv) const; + inline typed::multi_union_pw_aff scale(const typed::val &v) const; + inline typed::multi_union_pw_aff scale(long v) const; + inline typed::multi_union_pw_aff scale_down(const typed::multi_val &mv) const; + inline typed::multi_union_pw_aff scale_down(const typed::val &v) const; + inline typed::multi_union_pw_aff scale_down(long v) const; + inline typed::multi_union_pw_aff set_at(int pos, const typed::union_pw_aff &el) const; + template + inline typed::multi_union_pw_aff set_range_tuple(const typed::id &id) const; + template + inline typed::multi_union_pw_aff set_range_tuple(const std::string &id) const; + inline typed::space space() const; + inline typed::space get_space() const = delete; + inline typed::multi_union_pw_aff sub(const typed::multi_union_pw_aff &multi2) const; + inline typed::multi_union_pw_aff sub(const typed::multi_pw_aff &multi2) const; + inline typed::multi_union_pw_aff sub(const typed::union_pw_aff &multi2) const; + inline typed::multi_union_pw_aff union_add(const typed::multi_union_pw_aff &mupa2) const; + inline typed::multi_union_pw_aff union_add(const typed::multi_pw_aff &mupa2) const; + inline typed::multi_union_pw_aff union_add(const typed::union_pw_aff &mupa2) const; +}; + +template +struct multi_union_pw_aff : public isl::multi_union_pw_aff { + template + friend struct aff; + template + friend struct aff_list; + template + friend struct basic_map; + template + friend struct basic_set; + template + friend struct fixed_box; + template + friend struct id; + template + friend struct id_list; + template + friend struct map; + template + friend struct map_list; + template + friend struct multi_aff; + template + friend struct multi_id; + template + friend struct multi_pw_aff; + template + friend struct multi_union_pw_aff; + template + friend struct multi_val; + template + friend struct point; + template + friend struct pw_aff; + template + friend struct pw_aff_list; + template + friend struct pw_multi_aff; + template + friend struct pw_multi_aff_list; + template + friend struct set; + template + friend struct set_list; + template + friend struct space; + template + friend struct union_map; + template + friend struct union_pw_aff; + template + friend struct union_pw_aff_list; + template + friend struct union_pw_multi_aff; + template + friend struct union_set; + template + friend struct union_set_list; + template + friend struct val; + template + friend struct val_list; + + multi_union_pw_aff() = default; + template {} && + std::is_base_of{}, + bool>::type = true> + multi_union_pw_aff(const multi_union_pw_aff &obj) : isl::multi_union_pw_aff(obj) {} + private: + template {}, bool>::type = true> + multi_union_pw_aff(const base &obj) : isl::multi_union_pw_aff(obj) {} + public: + static multi_union_pw_aff from(const isl::multi_union_pw_aff &obj) { + return multi_union_pw_aff(obj); + } + inline /* implicit */ multi_union_pw_aff(const typed::multi_pw_aff &mpa); + inline /* implicit */ multi_union_pw_aff(const typed::union_pw_aff &upa); + inline explicit multi_union_pw_aff(const typed::space &space, const typed::union_pw_aff_list &list); + inline explicit multi_union_pw_aff(const isl::ctx &ctx, const std::string &str); + inline typed::multi_union_pw_aff add(const typed::multi_union_pw_aff &multi2) const; + inline typed::multi_union_pw_aff add(const typed::multi_pw_aff &multi2) const; + inline typed::multi_union_pw_aff add(const typed::union_pw_aff &multi2) const; + inline typed::union_pw_aff at(int pos) const; + inline typed::union_pw_aff get_at(int pos) const = delete; + inline typed::union_set bind(const typed::multi_id &tuple) const; + inline typed::multi_union_pw_aff coalesce() const; + inline typed::union_set domain() const; + inline typed::multi_union_pw_aff gist(const typed::union_set &context) const; + inline typed::multi_union_pw_aff gist(const typed::basic_set &context) const; + inline typed::multi_union_pw_aff gist(const typed::point &context) const; + inline typed::multi_union_pw_aff gist(const typed::set &context) const; + inline typed::multi_union_pw_aff gist_params(const typed::set<> &context) const; + inline typed::multi_union_pw_aff gist_params(const typed::basic_set<> &context) const; + inline typed::multi_union_pw_aff gist_params(const typed::point<> &context) const; + inline typed::multi_union_pw_aff intersect_domain(const typed::union_set &uset) const; + inline typed::multi_union_pw_aff intersect_domain(const typed::basic_set &uset) const; + inline typed::multi_union_pw_aff intersect_domain(const typed::point &uset) const; + inline typed::multi_union_pw_aff intersect_domain(const typed::set &uset) const; + inline typed::multi_union_pw_aff intersect_params(const typed::set<> ¶ms) const; + inline typed::multi_union_pw_aff intersect_params(const typed::basic_set<> ¶ms) const; + inline typed::multi_union_pw_aff intersect_params(const typed::point<> ¶ms) const; + inline typed::union_pw_aff_list list() const; + inline typed::union_pw_aff_list get_list() const = delete; + inline typed::multi_union_pw_aff neg() const; + template + inline typed::multi_union_pw_aff pullback(const typed::union_pw_multi_aff &upma) const; + inline typed::multi_union_pw_aff pullback(const typed::union_pw_multi_aff &upma) const; + template + inline typed::multi_union_pw_aff pullback(const typed::multi_aff &upma) const; + inline typed::multi_union_pw_aff pullback(const typed::multi_aff &upma) const; + template + inline typed::multi_union_pw_aff pullback(const typed::pw_multi_aff &upma) const; + inline typed::multi_union_pw_aff pullback(const typed::pw_multi_aff &upma) const; + template + inline typed::multi_union_pw_aff pullback(const typed::union_pw_aff &upma) const; + inline typed::multi_union_pw_aff pullback(const typed::union_pw_aff &upma) const; + template + inline typed::multi_union_pw_aff> range_product(const typed::multi_union_pw_aff &multi2) const; + template + inline typed::multi_union_pw_aff> range_product(const typed::multi_pw_aff &multi2) const; + inline typed::multi_union_pw_aff> range_product(const typed::union_pw_aff &multi2) const; + inline typed::id get_range_tuple_id() const = delete; + inline typed::multi_union_pw_aff scale(const typed::multi_val &mv) const; + inline typed::multi_union_pw_aff scale(const typed::val &v) const; + inline typed::multi_union_pw_aff scale(long v) const; + inline typed::multi_union_pw_aff scale_down(const typed::multi_val &mv) const; + inline typed::multi_union_pw_aff scale_down(const typed::val &v) const; + inline typed::multi_union_pw_aff scale_down(long v) const; + inline typed::multi_union_pw_aff set_at(int pos, const typed::union_pw_aff &el) const; + template + inline typed::multi_union_pw_aff set_range_tuple(const typed::id &id) const; + template + inline typed::multi_union_pw_aff set_range_tuple(const std::string &id) const; + inline typed::space space() const; + inline typed::space get_space() const = delete; + inline typed::multi_union_pw_aff sub(const typed::multi_union_pw_aff &multi2) const; + inline typed::multi_union_pw_aff sub(const typed::multi_pw_aff &multi2) const; + inline typed::multi_union_pw_aff sub(const typed::union_pw_aff &multi2) const; + inline typed::multi_union_pw_aff union_add(const typed::multi_union_pw_aff &mupa2) const; + inline typed::multi_union_pw_aff union_add(const typed::multi_pw_aff &mupa2) const; + inline typed::multi_union_pw_aff union_add(const typed::union_pw_aff &mupa2) const; +}; + +template +struct multi_val : public isl::multi_val { + template + friend struct aff; + template + friend struct aff_list; + template + friend struct basic_map; + template + friend struct basic_set; + template + friend struct fixed_box; + template + friend struct id; + template + friend struct id_list; + template + friend struct map; + template + friend struct map_list; + template + friend struct multi_aff; + template + friend struct multi_id; + template + friend struct multi_pw_aff; + template + friend struct multi_union_pw_aff; + template + friend struct multi_val; + template + friend struct point; + template + friend struct pw_aff; + template + friend struct pw_aff_list; + template + friend struct pw_multi_aff; + template + friend struct pw_multi_aff_list; + template + friend struct set; + template + friend struct set_list; + template + friend struct space; + template + friend struct union_map; + template + friend struct union_pw_aff; + template + friend struct union_pw_aff_list; + template + friend struct union_pw_multi_aff; + template + friend struct union_set; + template + friend struct union_set_list; + template + friend struct val; + template + friend struct val_list; + + multi_val() = default; + template {}, + bool>::type = true> + multi_val(const multi_val &obj) : isl::multi_val(obj) {} + private: + template {}, bool>::type = true> + multi_val(const base &obj) : isl::multi_val(obj) {} + public: + static multi_val from(const isl::multi_val &obj) { + return multi_val(obj); + } + inline explicit multi_val(const typed::space &space, const typed::val_list &list); + inline explicit multi_val(const isl::ctx &ctx, const std::string &str); + inline typed::multi_val add(const typed::multi_val &multi2) const; + inline typed::multi_val add(const typed::val &v) const; + inline typed::multi_val add(long v) const; + inline typed::val at(int pos) const; + inline typed::val get_at(int pos) const = delete; + inline typed::val_list list() const; + inline typed::val_list get_list() const = delete; + inline typed::multi_val max(const typed::multi_val &multi2) const; + inline typed::multi_val min(const typed::multi_val &multi2) const; + inline typed::multi_val neg() const; + template + inline typed::multi_val> product(const typed::multi_val &multi2) const; + inline typed::multi_val range_product(const typed::multi_val<> &multi2) const = delete; + inline typed::id get_range_tuple_id() const = delete; + inline typed::multi_val scale(const typed::multi_val &mv) const; + inline typed::multi_val scale(const typed::val &v) const; + inline typed::multi_val scale(long v) const; + inline typed::multi_val scale_down(const typed::multi_val &mv) const; + inline typed::multi_val scale_down(const typed::val &v) const; + inline typed::multi_val scale_down(long v) const; + inline typed::multi_val set_at(int pos, const typed::val &el) const; + inline typed::multi_val set_at(int pos, long el) const; + template + inline typed::multi_val set_range_tuple(const typed::id &id) const; + template + inline typed::multi_val set_range_tuple(const std::string &id) const; + inline typed::space space() const; + inline typed::space get_space() const = delete; + inline typed::multi_val sub(const typed::multi_val &multi2) const; +}; + +template <> +struct point<> : public isl::point { + template + friend struct aff; + template + friend struct aff_list; + template + friend struct basic_map; + template + friend struct basic_set; + template + friend struct fixed_box; + template + friend struct id; + template + friend struct id_list; + template + friend struct map; + template + friend struct map_list; + template + friend struct multi_aff; + template + friend struct multi_id; + template + friend struct multi_pw_aff; + template + friend struct multi_union_pw_aff; + template + friend struct multi_val; + template + friend struct point; + template + friend struct pw_aff; + template + friend struct pw_aff_list; + template + friend struct pw_multi_aff; + template + friend struct pw_multi_aff_list; + template + friend struct set; + template + friend struct set_list; + template + friend struct space; + template + friend struct union_map; + template + friend struct union_pw_aff; + template + friend struct union_pw_aff_list; + template + friend struct union_pw_multi_aff; + template + friend struct union_set; + template + friend struct union_set_list; + template + friend struct val; + template + friend struct val_list; + + point() = default; + private: + template {}, bool>::type = true> + point(const base &obj) : isl::point(obj) {} + public: + static point from(const isl::point &obj) { + return point(obj); + } + inline typed::basic_set<> apply(const typed::basic_map<> &bmap) const = delete; + inline typed::set<> apply(const typed::map<> &map) const = delete; + inline typed::union_set<> apply(const typed::union_map<> &umap) const = delete; + inline typed::pw_multi_aff<> as_pw_multi_aff() const = delete; + inline typed::set<> as_set() const = delete; + inline typed::set<> bind(const typed::multi_id<> &tuple) const = delete; + inline typed::set<> coalesce() const; + inline typed::basic_set<> detect_equalities() const; + inline typed::set<> drop_unused_params() const; + inline bool every_set(const std::function)> &test) const; + inline typed::set<> extract_set(const typed::space<> &space) const; + inline void foreach_basic_set(const std::function)> &fn) const; + inline void foreach_point(const std::function)> &fn) const; + inline void foreach_set(const std::function)> &fn) const; + inline typed::basic_set<> gist(const typed::basic_set<> &context) const; + inline typed::set<> gist(const typed::set<> &context) const; + inline typed::union_set<> gist(const typed::union_set<> &context) const; + inline typed::set<> gist_params(const typed::set<> &context) const = delete; + inline typed::map<> identity() const = delete; + inline typed::pw_aff indicator_function() const; + inline typed::map<> insert_domain(const typed::space<> &domain) const = delete; + inline typed::basic_set<> intersect(const typed::basic_set<> &bset2) const; + inline typed::set<> intersect(const typed::set<> &set2) const; + inline typed::union_set<> intersect(const typed::union_set<> &uset2) const; + inline typed::basic_set<> intersect_params(const typed::basic_set<> &bset2) const = delete; + inline typed::set<> intersect_params(const typed::set<> ¶ms) const = delete; + inline typed::fixed_box<> lattice_tile() const = delete; + inline typed::set<> lexmax() const = delete; + inline typed::pw_multi_aff<> lexmax_pw_multi_aff() const = delete; + inline typed::set<> lexmin() const = delete; + inline typed::pw_multi_aff<> lexmin_pw_multi_aff() const = delete; + inline typed::set<> lower_bound(const typed::multi_pw_aff<> &lower) const = delete; + inline typed::set<> lower_bound(const typed::multi_val<> &lower) const = delete; + inline typed::multi_pw_aff<> max_multi_pw_aff() const = delete; + inline typed::val<> max_val(const typed::aff<> &obj) const = delete; + inline typed::multi_pw_aff<> min_multi_pw_aff() const = delete; + inline typed::val<> min_val(const typed::aff<> &obj) const = delete; + inline typed::multi_val<> multi_val() const = delete; + inline typed::multi_val<> get_multi_val() const = delete; + inline typed::pw_aff param_pw_aff_on_domain(const typed::id &id) const; + inline typed::pw_aff param_pw_aff_on_domain(const std::string &id) const; + inline typed::basic_set<> params() const = delete; + inline typed::multi_val<> plain_multi_val_if_fixed() const = delete; + inline typed::set<> preimage(const typed::multi_aff<> &ma) const = delete; + inline typed::set<> preimage(const typed::multi_pw_aff<> &mpa) const = delete; + inline typed::set<> preimage(const typed::pw_multi_aff<> &pma) const = delete; + inline typed::union_set<> preimage(const typed::union_pw_multi_aff<> &upma) const = delete; + inline typed::set<> product(const typed::set<> &set2) const = delete; + inline typed::set<> project_out_all_params() const; + inline typed::set<> project_out_param(const typed::id &id) const; + inline typed::set<> project_out_param(const std::string &id) const; + inline typed::set<> project_out_param(const typed::id_list &list) const; + inline typed::pw_aff pw_aff_on_domain(const typed::val &v) const; + inline typed::pw_aff pw_aff_on_domain(long v) const; + template + inline typed::pw_multi_aff pw_multi_aff_on_domain(const typed::multi_val &mv) const; + inline typed::set_list<> set_list() const; + inline typed::fixed_box<> simple_fixed_box_hull() const = delete; + inline typed::space<> space() const; + inline typed::set<> subtract(const typed::set<> &set2) const; + inline typed::union_set<> subtract(const typed::union_set<> &uset2) const; + inline typed::set<> to_set() const; + inline typed::union_set<> to_union_set() const; + inline typed::map<> translation() const = delete; + template + inline typed::set unbind_params(const typed::multi_id &tuple) const; + inline typed::map<> unbind_params_insert_domain(const typed::multi_id<> &domain) const = delete; + inline typed::set<> unite(const typed::basic_set<> &bset2) const; + inline typed::set<> unite(const typed::set<> &set2) const; + inline typed::union_set<> unite(const typed::union_set<> &uset2) const; + inline typed::map<> unwrap() const = delete; + inline typed::set<> upper_bound(const typed::multi_pw_aff<> &upper) const = delete; + inline typed::set<> upper_bound(const typed::multi_val<> &upper) const = delete; + inline typed::set<> wrapped_reverse() const = delete; +}; + +template +struct point : public isl::point { + template + friend struct aff; + template + friend struct aff_list; + template + friend struct basic_map; + template + friend struct basic_set; + template + friend struct fixed_box; + template + friend struct id; + template + friend struct id_list; + template + friend struct map; + template + friend struct map_list; + template + friend struct multi_aff; + template + friend struct multi_id; + template + friend struct multi_pw_aff; + template + friend struct multi_union_pw_aff; + template + friend struct multi_val; + template + friend struct point; + template + friend struct pw_aff; + template + friend struct pw_aff_list; + template + friend struct pw_multi_aff; + template + friend struct pw_multi_aff_list; + template + friend struct set; + template + friend struct set_list; + template + friend struct space; + template + friend struct union_map; + template + friend struct union_pw_aff; + template + friend struct union_pw_aff_list; + template + friend struct union_pw_multi_aff; + template + friend struct union_set; + template + friend struct union_set_list; + template + friend struct val; + template + friend struct val_list; + + point() = default; + template {}, + bool>::type = true> + point(const point &obj) : isl::point(obj) {} + private: + template {}, bool>::type = true> + point(const base &obj) : isl::point(obj) {} + public: + static point from(const isl::point &obj) { + return point(obj); + } + template + inline typed::basic_set apply(const typed::basic_map &bmap) const; + template + inline typed::set apply(const typed::map &map) const; + template + inline typed::union_set apply(const typed::union_map &umap) const; + inline typed::pw_multi_aff as_pw_multi_aff() const; + inline typed::set as_set() const; + inline typed::set<> bind(const typed::multi_id &tuple) const; + inline typed::set coalesce() const; + inline typed::basic_set detect_equalities() const; + inline typed::set drop_unused_params() const; + inline bool every_set(const std::function)> &test) const; + inline typed::set extract_set(const typed::space &space) const; + inline void foreach_basic_set(const std::function)> &fn) const; + inline void foreach_point(const std::function)> &fn) const; + inline void foreach_set(const std::function)> &fn) const; + inline typed::basic_set gist(const typed::basic_set &context) const; + inline typed::set gist(const typed::set &context) const; + inline typed::union_set gist(const typed::union_set &context) const; + inline typed::set gist_params(const typed::set<> &context) const; + inline typed::map identity() const; + inline typed::pw_aff indicator_function() const; + template + inline typed::map insert_domain(const typed::space &domain) const; + inline typed::basic_set intersect(const typed::basic_set &bset2) const; + inline typed::set intersect(const typed::set &set2) const; + inline typed::union_set intersect(const typed::union_set &uset2) const; + inline typed::basic_set intersect_params(const typed::basic_set<> &bset2) const; + inline typed::set intersect_params(const typed::set<> ¶ms) const; + inline typed::fixed_box lattice_tile() const; + inline typed::set lexmax() const; + inline typed::pw_multi_aff lexmax_pw_multi_aff() const; + inline typed::set lexmin() const; + inline typed::pw_multi_aff lexmin_pw_multi_aff() const; + inline typed::set lower_bound(const typed::multi_pw_aff &lower) const; + inline typed::set lower_bound(const typed::multi_val &lower) const; + inline typed::multi_pw_aff max_multi_pw_aff() const; + inline typed::val max_val(const typed::aff<> &obj) const = delete; + inline typed::multi_pw_aff min_multi_pw_aff() const; + inline typed::val min_val(const typed::aff<> &obj) const = delete; + inline typed::multi_val multi_val() const; + inline typed::multi_val get_multi_val() const = delete; + inline typed::pw_aff param_pw_aff_on_domain(const typed::id &id) const; + inline typed::pw_aff param_pw_aff_on_domain(const std::string &id) const; + inline typed::basic_set<> params() const; + inline typed::multi_val plain_multi_val_if_fixed() const; + template + inline typed::set preimage(const typed::multi_aff &ma) const; + template + inline typed::set preimage(const typed::multi_pw_aff &mpa) const; + template + inline typed::set preimage(const typed::pw_multi_aff &pma) const; + template + inline typed::union_set preimage(const typed::union_pw_multi_aff &upma) const; + template + inline typed::set> product(const typed::set &set2) const; + inline typed::set project_out_all_params() const; + inline typed::set project_out_param(const typed::id &id) const; + inline typed::set project_out_param(const std::string &id) const; + inline typed::set project_out_param(const typed::id_list &list) const; + inline typed::pw_aff pw_aff_on_domain(const typed::val &v) const; + inline typed::pw_aff pw_aff_on_domain(long v) const; + template + inline typed::pw_multi_aff pw_multi_aff_on_domain(const typed::multi_val &mv) const; + inline typed::set_list set_list() const; + inline typed::fixed_box simple_fixed_box_hull() const; + inline typed::space space() const; + inline typed::set subtract(const typed::set &set2) const; + inline typed::union_set subtract(const typed::union_set &uset2) const; + inline typed::set to_set() const; + inline typed::union_set to_union_set() const; + inline typed::map translation() const; + inline typed::set unbind_params(const typed::multi_id<> &tuple) const = delete; + template + inline typed::map unbind_params_insert_domain(const typed::multi_id &domain) const; + inline typed::set unite(const typed::basic_set &bset2) const; + inline typed::set unite(const typed::set &set2) const; + inline typed::union_set unite(const typed::union_set &uset2) const; + inline typed::map unwrap() const = delete; + inline typed::set upper_bound(const typed::multi_pw_aff &upper) const; + inline typed::set upper_bound(const typed::multi_val &upper) const; + inline typed::set wrapped_reverse() const = delete; +}; + +template +struct point> : public isl::point { + template + friend struct aff; + template + friend struct aff_list; + template + friend struct basic_map; + template + friend struct basic_set; + template + friend struct fixed_box; + template + friend struct id; + template + friend struct id_list; + template + friend struct map; + template + friend struct map_list; + template + friend struct multi_aff; + template + friend struct multi_id; + template + friend struct multi_pw_aff; + template + friend struct multi_union_pw_aff; + template + friend struct multi_val; + template + friend struct point; + template + friend struct pw_aff; + template + friend struct pw_aff_list; + template + friend struct pw_multi_aff; + template + friend struct pw_multi_aff_list; + template + friend struct set; + template + friend struct set_list; + template + friend struct space; + template + friend struct union_map; + template + friend struct union_pw_aff; + template + friend struct union_pw_aff_list; + template + friend struct union_pw_multi_aff; + template + friend struct union_set; + template + friend struct union_set_list; + template + friend struct val; + template + friend struct val_list; + + point() = default; + template {} && + std::is_base_of{}, + bool>::type = true> + point(const point> &obj) : isl::point(obj) {} + private: + template {}, bool>::type = true> + point(const base &obj) : isl::point(obj) {} + public: + static point from(const isl::point &obj) { + return point(obj); + } + template + inline typed::basic_set apply(const typed::basic_map, Arg2> &bmap) const; + template + inline typed::set apply(const typed::map, Arg2> &map) const; + template + inline typed::union_set apply(const typed::union_map, Arg2> &umap) const; + inline typed::pw_multi_aff> as_pw_multi_aff() const; + inline typed::set> as_set() const; + inline typed::set<> bind(const typed::multi_id> &tuple) const; + inline typed::set> coalesce() const; + inline typed::basic_set> detect_equalities() const; + inline typed::set> drop_unused_params() const; + inline bool every_set(const std::function>)> &test) const; + inline typed::set> extract_set(const typed::space> &space) const; + inline void foreach_basic_set(const std::function>)> &fn) const; + inline void foreach_point(const std::function>)> &fn) const; + inline void foreach_set(const std::function>)> &fn) const; + inline typed::basic_set> gist(const typed::basic_set> &context) const; + inline typed::set> gist(const typed::set> &context) const; + inline typed::union_set> gist(const typed::union_set> &context) const; + inline typed::set> gist_params(const typed::set<> &context) const; + inline typed::map, pair> identity() const; + inline typed::pw_aff, Anonymous> indicator_function() const; + template + inline typed::map> insert_domain(const typed::space &domain) const; + inline typed::basic_set> intersect(const typed::basic_set> &bset2) const; + inline typed::set> intersect(const typed::set> &set2) const; + inline typed::union_set> intersect(const typed::union_set> &uset2) const; + inline typed::basic_set> intersect_params(const typed::basic_set<> &bset2) const; + inline typed::set> intersect_params(const typed::set<> ¶ms) const; + inline typed::fixed_box> lattice_tile() const; + inline typed::set> lexmax() const; + inline typed::pw_multi_aff> lexmax_pw_multi_aff() const; + inline typed::set> lexmin() const; + inline typed::pw_multi_aff> lexmin_pw_multi_aff() const; + inline typed::set> lower_bound(const typed::multi_pw_aff> &lower) const; + inline typed::set> lower_bound(const typed::multi_val> &lower) const; + inline typed::multi_pw_aff> max_multi_pw_aff() const; + inline typed::val> max_val(const typed::aff<> &obj) const = delete; + inline typed::multi_pw_aff> min_multi_pw_aff() const; + inline typed::val> min_val(const typed::aff<> &obj) const = delete; + inline typed::multi_val> multi_val() const; + inline typed::multi_val> get_multi_val() const = delete; + inline typed::pw_aff, Anonymous> param_pw_aff_on_domain(const typed::id &id) const; + inline typed::pw_aff, Anonymous> param_pw_aff_on_domain(const std::string &id) const; + inline typed::basic_set<> params() const; + inline typed::multi_val> plain_multi_val_if_fixed() const; + template + inline typed::set preimage(const typed::multi_aff> &ma) const; + template + inline typed::set preimage(const typed::multi_pw_aff> &mpa) const; + template + inline typed::set preimage(const typed::pw_multi_aff> &pma) const; + template + inline typed::union_set preimage(const typed::union_pw_multi_aff> &upma) const; + template + inline typed::set, Arg2>> product(const typed::set &set2) const; + inline typed::set> project_out_all_params() const; + inline typed::set> project_out_param(const typed::id &id) const; + inline typed::set> project_out_param(const std::string &id) const; + inline typed::set> project_out_param(const typed::id_list &list) const; + inline typed::pw_aff, Anonymous> pw_aff_on_domain(const typed::val &v) const; + inline typed::pw_aff, Anonymous> pw_aff_on_domain(long v) const; + template + inline typed::pw_multi_aff, Arg2> pw_multi_aff_on_domain(const typed::multi_val &mv) const; + inline typed::set_list> set_list() const; + inline typed::fixed_box> simple_fixed_box_hull() const; + inline typed::space> space() const; + inline typed::set> subtract(const typed::set> &set2) const; + inline typed::union_set> subtract(const typed::union_set> &uset2) const; + inline typed::set> to_set() const; + inline typed::union_set> to_union_set() const; + inline typed::map, pair> translation() const; + inline typed::set> unbind_params(const typed::multi_id<> &tuple) const = delete; + template + inline typed::map> unbind_params_insert_domain(const typed::multi_id &domain) const; + inline typed::set> unite(const typed::basic_set> &bset2) const; + inline typed::set> unite(const typed::set> &set2) const; + inline typed::union_set> unite(const typed::union_set> &uset2) const; + inline typed::map unwrap() const; + inline typed::set> upper_bound(const typed::multi_pw_aff> &upper) const; + inline typed::set> upper_bound(const typed::multi_val> &upper) const; + inline typed::set> wrapped_reverse() const; +}; + +template <> +struct pw_aff : public isl::pw_aff { + template + friend struct aff; + template + friend struct aff_list; + template + friend struct basic_map; + template + friend struct basic_set; + template + friend struct fixed_box; + template + friend struct id; + template + friend struct id_list; + template + friend struct map; + template + friend struct map_list; + template + friend struct multi_aff; + template + friend struct multi_id; + template + friend struct multi_pw_aff; + template + friend struct multi_union_pw_aff; + template + friend struct multi_val; + template + friend struct point; + template + friend struct pw_aff; + template + friend struct pw_aff_list; + template + friend struct pw_multi_aff; + template + friend struct pw_multi_aff_list; + template + friend struct set; + template + friend struct set_list; + template + friend struct space; + template + friend struct union_map; + template + friend struct union_pw_aff; + template + friend struct union_pw_aff_list; + template + friend struct union_pw_multi_aff; + template + friend struct union_set; + template + friend struct union_set_list; + template + friend struct val; + template + friend struct val_list; + + pw_aff() = default; + pw_aff(const isl::pw_aff &obj) : isl::pw_aff(obj) {} + static pw_aff from(const isl::pw_aff &obj) { + return pw_aff(obj); + } + inline /* implicit */ pw_aff(const typed::aff &aff); + inline explicit pw_aff(const isl::ctx &ctx, const std::string &str); + inline typed::multi_pw_aff add(const typed::multi_pw_aff &multi2) const; + inline typed::multi_union_pw_aff add(const typed::multi_union_pw_aff &multi2) const; + inline typed::pw_aff add(const typed::pw_aff &pwaff2) const; + inline typed::pw_multi_aff add(const typed::pw_multi_aff &pma2) const; + inline typed::union_pw_aff add(const typed::union_pw_aff &upa2) const; + inline typed::union_pw_multi_aff add(const typed::union_pw_multi_aff &upma2) const; + inline typed::pw_aff add(const typed::aff &pwaff2) const; + inline typed::pw_aff add_constant(const typed::val &v) const; + inline typed::pw_aff add_constant(long v) const; + inline typed::pw_multi_aff add_constant(const typed::multi_val &mv) const; + template + inline typed::union_pw_multi_aff apply(const typed::union_pw_multi_aff &upma2) const; + inline typed::aff as_aff() const; + inline typed::map as_map() const = delete; + inline typed::multi_aff as_multi_aff() const; + inline typed::multi_union_pw_aff as_multi_union_pw_aff() const; + inline typed::pw_multi_aff as_pw_multi_aff() const; + inline typed::set as_set() const; + inline typed::union_map as_union_map() const = delete; + inline typed::pw_aff at(int pos) const; + inline typed::set<> bind(const typed::multi_id &tuple) const; + inline typed::set<> bind(const typed::id &id) const; + inline typed::set<> bind(const std::string &id) const; + inline typed::pw_aff bind_domain(const typed::multi_id<> &tuple) const = delete; + inline typed::pw_aff bind_domain_wrapped_domain(const typed::multi_id<> &tuple) const = delete; + inline typed::pw_aff ceil() const; + inline typed::pw_aff coalesce() const; + inline typed::pw_aff cond(const typed::pw_aff &pwaff_true, const typed::pw_aff &pwaff_false) const; + inline typed::set<> domain() const; + inline typed::pw_aff domain_reverse() const = delete; + inline typed::pw_aff drop_unused_params() const; + inline typed::pw_multi_aff extract_pw_multi_aff(const typed::space &space) const; + inline typed::pw_aff floor() const; + inline typed::set ge_set(const typed::pw_aff<> &pwaff2) const = delete; + inline typed::set ge_set(const typed::aff<> &pwaff2) const = delete; + inline typed::pw_aff gist(const typed::set<> &context) const; + inline typed::union_pw_aff gist(const typed::union_set<> &context) const; + inline typed::pw_aff gist(const typed::basic_set<> &context) const; + inline typed::pw_aff gist(const typed::point<> &context) const; + inline typed::pw_aff gist_params(const typed::set<> &context) const; + inline typed::pw_aff gist_params(const typed::basic_set<> &context) const; + inline typed::pw_aff gist_params(const typed::point<> &context) const; + inline typed::set gt_set(const typed::pw_aff<> &pwaff2) const = delete; + inline typed::set gt_set(const typed::aff<> &pwaff2) const = delete; + inline typed::multi_pw_aff identity() const; + template + inline typed::pw_aff insert_domain(const typed::space &domain) const; + inline typed::pw_aff intersect_domain(const typed::set<> &set) const = delete; + inline typed::union_pw_aff intersect_domain(const typed::space<> &space) const = delete; + inline typed::union_pw_aff intersect_domain(const typed::union_set<> &uset) const = delete; + inline typed::pw_aff intersect_domain(const typed::basic_set<> &set) const = delete; + inline typed::pw_aff intersect_domain(const typed::point<> &set) const = delete; + inline typed::union_pw_aff intersect_domain_wrapped_domain(const typed::union_set<> &uset) const = delete; + inline typed::pw_aff intersect_params(const typed::set<> &set) const; + inline typed::pw_aff intersect_params(const typed::basic_set<> &set) const; + inline typed::pw_aff intersect_params(const typed::point<> &set) const; + inline typed::set le_set(const typed::pw_aff<> &pwaff2) const = delete; + inline typed::set le_set(const typed::aff<> &pwaff2) const = delete; + inline typed::pw_aff_list list() const; + inline typed::set lt_set(const typed::pw_aff<> &pwaff2) const = delete; + inline typed::set lt_set(const typed::aff<> &pwaff2) const = delete; + inline typed::multi_pw_aff max(const typed::multi_pw_aff &multi2) const; + inline typed::pw_aff max(const typed::pw_aff &pwaff2) const; + inline typed::pw_aff max(const typed::aff &pwaff2) const; + inline typed::multi_val max_multi_val() const; + inline typed::val max_val() const; + inline typed::multi_pw_aff min(const typed::multi_pw_aff &multi2) const; + inline typed::pw_aff min(const typed::pw_aff &pwaff2) const; + inline typed::pw_aff min(const typed::aff &pwaff2) const; + inline typed::multi_val min_multi_val() const; + inline typed::val min_val() const; + inline typed::pw_aff mod(const typed::val &mod) const; + inline typed::pw_aff mod(long mod) const; + inline typed::pw_aff neg() const; + inline typed::set<> params() const; + inline typed::pw_multi_aff preimage_domain_wrapped_domain(const typed::pw_multi_aff<> &pma2) const = delete; + inline typed::union_pw_multi_aff preimage_domain_wrapped_domain(const typed::union_pw_multi_aff<> &upma2) const = delete; + template + inline typed::multi_pw_aff> product(const typed::multi_pw_aff &multi2) const; + template + inline typed::pw_multi_aff> product(const typed::pw_multi_aff &pma2) const; + inline typed::pw_aff pullback(const typed::multi_aff<> &ma) const = delete; + inline typed::pw_aff pullback(const typed::multi_pw_aff<> &mpa) const = delete; + inline typed::pw_aff pullback(const typed::pw_multi_aff<> &pma) const = delete; + inline typed::union_pw_aff pullback(const typed::union_pw_multi_aff<> &upma) const = delete; + inline typed::pw_multi_aff_list pw_multi_aff_list() const; + inline typed::pw_multi_aff range_factor_domain() const = delete; + inline typed::pw_multi_aff range_factor_range() const = delete; + inline typed::multi_pw_aff range_product(const typed::multi_pw_aff<> &multi2) const = delete; + inline typed::multi_union_pw_aff range_product(const typed::multi_union_pw_aff<> &multi2) const = delete; + inline typed::pw_multi_aff range_product(const typed::pw_multi_aff<> &pma2) const = delete; + inline typed::union_pw_multi_aff range_product(const typed::union_pw_multi_aff<> &upma2) const = delete; + inline typed::pw_aff scale(const typed::val &v) const; + inline typed::pw_aff scale(long v) const; + inline typed::pw_multi_aff scale(const typed::multi_val &mv) const; + inline typed::pw_aff scale_down(const typed::val &f) const; + inline typed::pw_aff scale_down(long f) const; + inline typed::pw_multi_aff scale_down(const typed::multi_val &mv) const; + inline typed::multi_pw_aff set_at(int pos, const typed::pw_aff &el) const; + inline typed::multi_union_pw_aff set_at(int pos, const typed::union_pw_aff &el) const; + template + inline typed::pw_multi_aff set_range_tuple(const typed::id &id) const; + template + inline typed::pw_multi_aff set_range_tuple(const std::string &id) const; + inline typed::space space() const; + inline typed::space get_space() const = delete; + inline typed::multi_pw_aff sub(const typed::multi_pw_aff &multi2) const; + inline typed::multi_union_pw_aff sub(const typed::multi_union_pw_aff &multi2) const; + inline typed::pw_aff sub(const typed::pw_aff &pwaff2) const; + inline typed::pw_multi_aff sub(const typed::pw_multi_aff &pma2) const; + inline typed::union_pw_aff sub(const typed::union_pw_aff &upa2) const; + inline typed::union_pw_multi_aff sub(const typed::union_pw_multi_aff &upma2) const; + inline typed::pw_aff sub(const typed::aff &pwaff2) const; + inline typed::pw_aff subtract_domain(const typed::set<> &set) const = delete; + inline typed::union_pw_aff subtract_domain(const typed::space<> &space) const = delete; + inline typed::union_pw_aff subtract_domain(const typed::union_set<> &uset) const = delete; + inline typed::pw_aff subtract_domain(const typed::basic_set<> &set) const = delete; + inline typed::pw_aff subtract_domain(const typed::point<> &set) const = delete; + inline typed::multi_pw_aff to_multi_pw_aff() const; + inline typed::union_pw_aff to_union_pw_aff() const; + inline typed::union_pw_multi_aff to_union_pw_multi_aff() const; + template + inline typed::multi_pw_aff unbind_params_insert_domain(const typed::multi_id &domain) const; + inline typed::multi_pw_aff union_add(const typed::multi_pw_aff &mpa2) const; + inline typed::multi_union_pw_aff union_add(const typed::multi_union_pw_aff &mupa2) const; + inline typed::pw_aff union_add(const typed::pw_aff &pwaff2) const; + inline typed::pw_multi_aff union_add(const typed::pw_multi_aff &pma2) const; + inline typed::union_pw_aff union_add(const typed::union_pw_aff &upa2) const; + inline typed::union_pw_multi_aff union_add(const typed::union_pw_multi_aff &upma2) const; + inline typed::pw_aff union_add(const typed::aff &pwaff2) const; +}; + +template +struct pw_aff : public isl::pw_aff { + template + friend struct aff; + template + friend struct aff_list; + template + friend struct basic_map; + template + friend struct basic_set; + template + friend struct fixed_box; + template + friend struct id; + template + friend struct id_list; + template + friend struct map; + template + friend struct map_list; + template + friend struct multi_aff; + template + friend struct multi_id; + template + friend struct multi_pw_aff; + template + friend struct multi_union_pw_aff; + template + friend struct multi_val; + template + friend struct point; + template + friend struct pw_aff; + template + friend struct pw_aff_list; + template + friend struct pw_multi_aff; + template + friend struct pw_multi_aff_list; + template + friend struct set; + template + friend struct set_list; + template + friend struct space; + template + friend struct union_map; + template + friend struct union_pw_aff; + template + friend struct union_pw_aff_list; + template + friend struct union_pw_multi_aff; + template + friend struct union_set; + template + friend struct union_set_list; + template + friend struct val; + template + friend struct val_list; + + pw_aff() = default; + template {}, + bool>::type = true> + pw_aff(const pw_aff &obj) : isl::pw_aff(obj) {} + private: + template {}, bool>::type = true> + pw_aff(const base &obj) : isl::pw_aff(obj) {} + public: + static pw_aff from(const isl::pw_aff &obj) { + return pw_aff(obj); + } + inline /* implicit */ pw_aff(const typed::aff &aff); + inline explicit pw_aff(const isl::ctx &ctx, const std::string &str); + inline typed::multi_pw_aff add(const typed::multi_pw_aff &multi2) const; + inline typed::multi_union_pw_aff add(const typed::multi_union_pw_aff &multi2) const; + inline typed::pw_aff add(const typed::pw_aff &pwaff2) const; + inline typed::pw_multi_aff add(const typed::pw_multi_aff &pma2) const; + inline typed::union_pw_aff add(const typed::union_pw_aff &upa2) const; + inline typed::union_pw_multi_aff add(const typed::union_pw_multi_aff &upma2) const; + inline typed::pw_aff add(const typed::aff &pwaff2) const; + inline typed::pw_aff add_constant(const typed::val &v) const; + inline typed::pw_aff add_constant(long v) const; + inline typed::pw_multi_aff add_constant(const typed::multi_val &mv) const; + template + inline typed::union_pw_multi_aff apply(const typed::union_pw_multi_aff &upma2) const; + inline typed::aff as_aff() const; + inline typed::map as_map() const; + inline typed::multi_aff as_multi_aff() const; + inline typed::multi_union_pw_aff as_multi_union_pw_aff() const; + inline typed::pw_multi_aff as_pw_multi_aff() const; + inline typed::set as_set() const = delete; + inline typed::union_map as_union_map() const; + inline typed::pw_aff at(int pos) const; + inline typed::set bind(const typed::multi_id &tuple) const; + inline typed::set bind(const typed::id &id) const; + inline typed::set bind(const std::string &id) const; + inline typed::pw_aff bind_domain(const typed::multi_id &tuple) const; + inline typed::pw_aff bind_domain_wrapped_domain(const typed::multi_id<> &tuple) const = delete; + inline typed::pw_aff ceil() const; + inline typed::pw_aff coalesce() const; + inline typed::pw_aff cond(const typed::pw_aff &pwaff_true, const typed::pw_aff &pwaff_false) const; + inline typed::set domain() const; + inline typed::pw_aff domain_reverse() const = delete; + inline typed::pw_aff drop_unused_params() const; + inline typed::pw_multi_aff extract_pw_multi_aff(const typed::space &space) const; + inline typed::pw_aff floor() const; + inline typed::set ge_set(const typed::pw_aff &pwaff2) const; + inline typed::set ge_set(const typed::aff &pwaff2) const; + inline typed::pw_aff gist(const typed::set &context) const; + inline typed::union_pw_aff gist(const typed::union_set &context) const; + inline typed::pw_aff gist(const typed::basic_set &context) const; + inline typed::pw_aff gist(const typed::point &context) const; + inline typed::pw_aff gist_params(const typed::set<> &context) const; + inline typed::pw_aff gist_params(const typed::basic_set<> &context) const; + inline typed::pw_aff gist_params(const typed::point<> &context) const; + inline typed::set gt_set(const typed::pw_aff &pwaff2) const; + inline typed::set gt_set(const typed::aff &pwaff2) const; + inline typed::multi_pw_aff identity() const; + inline typed::pw_aff insert_domain(const typed::space<> &domain) const = delete; + inline typed::pw_aff intersect_domain(const typed::set &set) const; + inline typed::union_pw_aff intersect_domain(const typed::space &space) const; + inline typed::union_pw_aff intersect_domain(const typed::union_set &uset) const; + inline typed::pw_aff intersect_domain(const typed::basic_set &set) const; + inline typed::pw_aff intersect_domain(const typed::point &set) const; + inline typed::union_pw_aff intersect_domain_wrapped_domain(const typed::union_set<> &uset) const = delete; + inline typed::pw_aff intersect_params(const typed::set<> &set) const; + inline typed::pw_aff intersect_params(const typed::basic_set<> &set) const; + inline typed::pw_aff intersect_params(const typed::point<> &set) const; + inline typed::set le_set(const typed::pw_aff &pwaff2) const; + inline typed::set le_set(const typed::aff &pwaff2) const; + inline typed::pw_aff_list list() const; + inline typed::set lt_set(const typed::pw_aff &pwaff2) const; + inline typed::set lt_set(const typed::aff &pwaff2) const; + inline typed::multi_pw_aff max(const typed::multi_pw_aff &multi2) const; + inline typed::pw_aff max(const typed::pw_aff &pwaff2) const; + inline typed::pw_aff max(const typed::aff &pwaff2) const; + inline typed::multi_val max_multi_val() const; + inline typed::val max_val() const; + inline typed::multi_pw_aff min(const typed::multi_pw_aff &multi2) const; + inline typed::pw_aff min(const typed::pw_aff &pwaff2) const; + inline typed::pw_aff min(const typed::aff &pwaff2) const; + inline typed::multi_val min_multi_val() const; + inline typed::val min_val() const; + inline typed::pw_aff mod(const typed::val &mod) const; + inline typed::pw_aff mod(long mod) const; + inline typed::pw_aff neg() const; + inline typed::set<> params() const; + inline typed::pw_multi_aff preimage_domain_wrapped_domain(const typed::pw_multi_aff<> &pma2) const = delete; + inline typed::union_pw_multi_aff preimage_domain_wrapped_domain(const typed::union_pw_multi_aff<> &upma2) const = delete; + template + inline typed::multi_pw_aff, pair> product(const typed::multi_pw_aff &multi2) const; + template + inline typed::pw_multi_aff, pair> product(const typed::pw_multi_aff &pma2) const; + template + inline typed::pw_aff pullback(const typed::multi_aff &ma) const; + inline typed::pw_aff pullback(const typed::multi_aff &ma) const; + template + inline typed::pw_aff pullback(const typed::multi_pw_aff &mpa) const; + inline typed::pw_aff pullback(const typed::multi_pw_aff &mpa) const; + template + inline typed::pw_aff pullback(const typed::pw_multi_aff &pma) const; + inline typed::pw_aff pullback(const typed::pw_multi_aff &pma) const; + template + inline typed::union_pw_aff pullback(const typed::union_pw_multi_aff &upma) const; + inline typed::union_pw_aff pullback(const typed::union_pw_multi_aff &upma) const; + inline typed::pw_multi_aff_list pw_multi_aff_list() const; + inline typed::pw_multi_aff range_factor_domain() const = delete; + inline typed::pw_multi_aff range_factor_range() const = delete; + template + inline typed::multi_pw_aff> range_product(const typed::multi_pw_aff &multi2) const; + template + inline typed::multi_union_pw_aff> range_product(const typed::multi_union_pw_aff &multi2) const; + template + inline typed::pw_multi_aff> range_product(const typed::pw_multi_aff &pma2) const; + template + inline typed::union_pw_multi_aff> range_product(const typed::union_pw_multi_aff &upma2) const; + inline typed::pw_aff scale(const typed::val &v) const; + inline typed::pw_aff scale(long v) const; + inline typed::pw_multi_aff scale(const typed::multi_val &mv) const; + inline typed::pw_aff scale_down(const typed::val &f) const; + inline typed::pw_aff scale_down(long f) const; + inline typed::pw_multi_aff scale_down(const typed::multi_val &mv) const; + inline typed::multi_pw_aff set_at(int pos, const typed::pw_aff &el) const; + inline typed::multi_union_pw_aff set_at(int pos, const typed::union_pw_aff &el) const; + template + inline typed::pw_multi_aff set_range_tuple(const typed::id &id) const; + template + inline typed::pw_multi_aff set_range_tuple(const std::string &id) const; + inline typed::space space() const; + inline typed::space get_space() const = delete; + inline typed::multi_pw_aff sub(const typed::multi_pw_aff &multi2) const; + inline typed::multi_union_pw_aff sub(const typed::multi_union_pw_aff &multi2) const; + inline typed::pw_aff sub(const typed::pw_aff &pwaff2) const; + inline typed::pw_multi_aff sub(const typed::pw_multi_aff &pma2) const; + inline typed::union_pw_aff sub(const typed::union_pw_aff &upa2) const; + inline typed::union_pw_multi_aff sub(const typed::union_pw_multi_aff &upma2) const; + inline typed::pw_aff sub(const typed::aff &pwaff2) const; + inline typed::pw_aff subtract_domain(const typed::set &set) const; + inline typed::union_pw_aff subtract_domain(const typed::space &space) const; + inline typed::union_pw_aff subtract_domain(const typed::union_set &uset) const; + inline typed::pw_aff subtract_domain(const typed::basic_set &set) const; + inline typed::pw_aff subtract_domain(const typed::point &set) const; + inline typed::multi_pw_aff to_multi_pw_aff() const; + inline typed::union_pw_aff to_union_pw_aff() const; + inline typed::union_pw_multi_aff to_union_pw_multi_aff() const; + inline typed::multi_pw_aff unbind_params_insert_domain(const typed::multi_id<> &domain) const = delete; + inline typed::multi_pw_aff union_add(const typed::multi_pw_aff &mpa2) const; + inline typed::multi_union_pw_aff union_add(const typed::multi_union_pw_aff &mupa2) const; + inline typed::pw_aff union_add(const typed::pw_aff &pwaff2) const; + inline typed::pw_multi_aff union_add(const typed::pw_multi_aff &pma2) const; + inline typed::union_pw_aff union_add(const typed::union_pw_aff &upa2) const; + inline typed::union_pw_multi_aff union_add(const typed::union_pw_multi_aff &upma2) const; + inline typed::pw_aff union_add(const typed::aff &pwaff2) const; +}; + +template +struct pw_aff, Anonymous> : public isl::pw_aff { + template + friend struct aff; + template + friend struct aff_list; + template + friend struct basic_map; + template + friend struct basic_set; + template + friend struct fixed_box; + template + friend struct id; + template + friend struct id_list; + template + friend struct map; + template + friend struct map_list; + template + friend struct multi_aff; + template + friend struct multi_id; + template + friend struct multi_pw_aff; + template + friend struct multi_union_pw_aff; + template + friend struct multi_val; + template + friend struct point; + template + friend struct pw_aff; + template + friend struct pw_aff_list; + template + friend struct pw_multi_aff; + template + friend struct pw_multi_aff_list; + template + friend struct set; + template + friend struct set_list; + template + friend struct space; + template + friend struct union_map; + template + friend struct union_pw_aff; + template + friend struct union_pw_aff_list; + template + friend struct union_pw_multi_aff; + template + friend struct union_set; + template + friend struct union_set_list; + template + friend struct val; + template + friend struct val_list; + + pw_aff() = default; + template {} && + std::is_base_of{}, + bool>::type = true> + pw_aff(const pw_aff, Anonymous> &obj) : isl::pw_aff(obj) {} + private: + template {}, bool>::type = true> + pw_aff(const base &obj) : isl::pw_aff(obj) {} + public: + static pw_aff from(const isl::pw_aff &obj) { + return pw_aff(obj); + } + inline /* implicit */ pw_aff(const typed::aff, Anonymous> &aff); + inline explicit pw_aff(const isl::ctx &ctx, const std::string &str); + inline typed::multi_pw_aff, Anonymous> add(const typed::multi_pw_aff, Anonymous> &multi2) const; + inline typed::multi_union_pw_aff, Anonymous> add(const typed::multi_union_pw_aff, Anonymous> &multi2) const; + inline typed::pw_aff, Anonymous> add(const typed::pw_aff, Anonymous> &pwaff2) const; + inline typed::pw_multi_aff, Anonymous> add(const typed::pw_multi_aff, Anonymous> &pma2) const; + inline typed::union_pw_aff, Anonymous> add(const typed::union_pw_aff, Anonymous> &upa2) const; + inline typed::union_pw_multi_aff, Anonymous> add(const typed::union_pw_multi_aff, Anonymous> &upma2) const; + inline typed::pw_aff, Anonymous> add(const typed::aff, Anonymous> &pwaff2) const; + inline typed::pw_aff, Anonymous> add_constant(const typed::val &v) const; + inline typed::pw_aff, Anonymous> add_constant(long v) const; + inline typed::pw_multi_aff, Anonymous> add_constant(const typed::multi_val &mv) const; + template + inline typed::union_pw_multi_aff, Arg1> apply(const typed::union_pw_multi_aff &upma2) const; + inline typed::aff, Anonymous> as_aff() const; + inline typed::map, Anonymous> as_map() const; + inline typed::multi_aff, Anonymous> as_multi_aff() const; + inline typed::multi_union_pw_aff, Anonymous> as_multi_union_pw_aff() const; + inline typed::pw_multi_aff, Anonymous> as_pw_multi_aff() const; + inline typed::set, Anonymous> as_set() const = delete; + inline typed::union_map, Anonymous> as_union_map() const; + inline typed::pw_aff, Anonymous> at(int pos) const; + inline typed::set> bind(const typed::multi_id &tuple) const; + inline typed::set> bind(const typed::id &id) const; + inline typed::set> bind(const std::string &id) const; + inline typed::pw_aff bind_domain(const typed::multi_id> &tuple) const; + inline typed::pw_aff bind_domain_wrapped_domain(const typed::multi_id &tuple) const; + inline typed::pw_aff, Anonymous> ceil() const; + inline typed::pw_aff, Anonymous> coalesce() const; + inline typed::pw_aff, Anonymous> cond(const typed::pw_aff, Anonymous> &pwaff_true, const typed::pw_aff, Anonymous> &pwaff_false) const; + inline typed::set> domain() const; + inline typed::pw_aff, Anonymous> domain_reverse() const; + inline typed::pw_aff, Anonymous> drop_unused_params() const; + inline typed::pw_multi_aff, Anonymous> extract_pw_multi_aff(const typed::space, Anonymous> &space) const; + inline typed::pw_aff, Anonymous> floor() const; + inline typed::set> ge_set(const typed::pw_aff, Anonymous> &pwaff2) const; + inline typed::set> ge_set(const typed::aff, Anonymous> &pwaff2) const; + inline typed::pw_aff, Anonymous> gist(const typed::set> &context) const; + inline typed::union_pw_aff, Anonymous> gist(const typed::union_set> &context) const; + inline typed::pw_aff, Anonymous> gist(const typed::basic_set> &context) const; + inline typed::pw_aff, Anonymous> gist(const typed::point> &context) const; + inline typed::pw_aff, Anonymous> gist_params(const typed::set<> &context) const; + inline typed::pw_aff, Anonymous> gist_params(const typed::basic_set<> &context) const; + inline typed::pw_aff, Anonymous> gist_params(const typed::point<> &context) const; + inline typed::set> gt_set(const typed::pw_aff, Anonymous> &pwaff2) const; + inline typed::set> gt_set(const typed::aff, Anonymous> &pwaff2) const; + inline typed::multi_pw_aff, Anonymous> identity() const; + inline typed::pw_aff, Anonymous> insert_domain(const typed::space<> &domain) const = delete; + inline typed::pw_aff, Anonymous> intersect_domain(const typed::set> &set) const; + inline typed::union_pw_aff, Anonymous> intersect_domain(const typed::space> &space) const; + inline typed::union_pw_aff, Anonymous> intersect_domain(const typed::union_set> &uset) const; + inline typed::pw_aff, Anonymous> intersect_domain(const typed::basic_set> &set) const; + inline typed::pw_aff, Anonymous> intersect_domain(const typed::point> &set) const; + inline typed::union_pw_aff, Anonymous> intersect_domain_wrapped_domain(const typed::union_set &uset) const; + inline typed::pw_aff, Anonymous> intersect_params(const typed::set<> &set) const; + inline typed::pw_aff, Anonymous> intersect_params(const typed::basic_set<> &set) const; + inline typed::pw_aff, Anonymous> intersect_params(const typed::point<> &set) const; + inline typed::set> le_set(const typed::pw_aff, Anonymous> &pwaff2) const; + inline typed::set> le_set(const typed::aff, Anonymous> &pwaff2) const; + inline typed::pw_aff_list, Anonymous> list() const; + inline typed::set> lt_set(const typed::pw_aff, Anonymous> &pwaff2) const; + inline typed::set> lt_set(const typed::aff, Anonymous> &pwaff2) const; + inline typed::multi_pw_aff, Anonymous> max(const typed::multi_pw_aff, Anonymous> &multi2) const; + inline typed::pw_aff, Anonymous> max(const typed::pw_aff, Anonymous> &pwaff2) const; + inline typed::pw_aff, Anonymous> max(const typed::aff, Anonymous> &pwaff2) const; + inline typed::multi_val max_multi_val() const; + inline typed::val max_val() const; + inline typed::multi_pw_aff, Anonymous> min(const typed::multi_pw_aff, Anonymous> &multi2) const; + inline typed::pw_aff, Anonymous> min(const typed::pw_aff, Anonymous> &pwaff2) const; + inline typed::pw_aff, Anonymous> min(const typed::aff, Anonymous> &pwaff2) const; + inline typed::multi_val min_multi_val() const; + inline typed::val min_val() const; + inline typed::pw_aff, Anonymous> mod(const typed::val &mod) const; + inline typed::pw_aff, Anonymous> mod(long mod) const; + inline typed::pw_aff, Anonymous> neg() const; + inline typed::set<> params() const; + template + inline typed::pw_multi_aff, Anonymous> preimage_domain_wrapped_domain(const typed::pw_multi_aff &pma2) const; + template + inline typed::union_pw_multi_aff, Anonymous> preimage_domain_wrapped_domain(const typed::union_pw_multi_aff &upma2) const; + template + inline typed::multi_pw_aff, Arg1>, pair> product(const typed::multi_pw_aff &multi2) const; + template + inline typed::pw_multi_aff, Arg1>, pair> product(const typed::pw_multi_aff &pma2) const; + template + inline typed::pw_aff pullback(const typed::multi_aff> &ma) const; + inline typed::pw_aff pullback(const typed::multi_aff> &ma) const; + template + inline typed::pw_aff pullback(const typed::multi_pw_aff> &mpa) const; + inline typed::pw_aff pullback(const typed::multi_pw_aff> &mpa) const; + template + inline typed::pw_aff pullback(const typed::pw_multi_aff> &pma) const; + inline typed::pw_aff pullback(const typed::pw_multi_aff> &pma) const; + template + inline typed::union_pw_aff pullback(const typed::union_pw_multi_aff> &upma) const; + inline typed::union_pw_aff pullback(const typed::union_pw_multi_aff> &upma) const; + inline typed::pw_multi_aff_list, Anonymous> pw_multi_aff_list() const; + inline typed::pw_multi_aff, Anonymous> range_factor_domain() const = delete; + inline typed::pw_multi_aff, Anonymous> range_factor_range() const = delete; + template + inline typed::multi_pw_aff, pair> range_product(const typed::multi_pw_aff, Arg1> &multi2) const; + template + inline typed::multi_union_pw_aff, pair> range_product(const typed::multi_union_pw_aff, Arg1> &multi2) const; + template + inline typed::pw_multi_aff, pair> range_product(const typed::pw_multi_aff, Arg1> &pma2) const; + template + inline typed::union_pw_multi_aff, pair> range_product(const typed::union_pw_multi_aff, Arg1> &upma2) const; + inline typed::pw_aff, Anonymous> scale(const typed::val &v) const; + inline typed::pw_aff, Anonymous> scale(long v) const; + inline typed::pw_multi_aff, Anonymous> scale(const typed::multi_val &mv) const; + inline typed::pw_aff, Anonymous> scale_down(const typed::val &f) const; + inline typed::pw_aff, Anonymous> scale_down(long f) const; + inline typed::pw_multi_aff, Anonymous> scale_down(const typed::multi_val &mv) const; + inline typed::multi_pw_aff, Anonymous> set_at(int pos, const typed::pw_aff, Anonymous> &el) const; + inline typed::multi_union_pw_aff, Anonymous> set_at(int pos, const typed::union_pw_aff, Anonymous> &el) const; + template + inline typed::pw_multi_aff, Arg1> set_range_tuple(const typed::id &id) const; + template + inline typed::pw_multi_aff, Arg1> set_range_tuple(const std::string &id) const; + inline typed::space, Anonymous> space() const; + inline typed::space, Anonymous> get_space() const = delete; + inline typed::multi_pw_aff, Anonymous> sub(const typed::multi_pw_aff, Anonymous> &multi2) const; + inline typed::multi_union_pw_aff, Anonymous> sub(const typed::multi_union_pw_aff, Anonymous> &multi2) const; + inline typed::pw_aff, Anonymous> sub(const typed::pw_aff, Anonymous> &pwaff2) const; + inline typed::pw_multi_aff, Anonymous> sub(const typed::pw_multi_aff, Anonymous> &pma2) const; + inline typed::union_pw_aff, Anonymous> sub(const typed::union_pw_aff, Anonymous> &upa2) const; + inline typed::union_pw_multi_aff, Anonymous> sub(const typed::union_pw_multi_aff, Anonymous> &upma2) const; + inline typed::pw_aff, Anonymous> sub(const typed::aff, Anonymous> &pwaff2) const; + inline typed::pw_aff, Anonymous> subtract_domain(const typed::set> &set) const; + inline typed::union_pw_aff, Anonymous> subtract_domain(const typed::space> &space) const; + inline typed::union_pw_aff, Anonymous> subtract_domain(const typed::union_set> &uset) const; + inline typed::pw_aff, Anonymous> subtract_domain(const typed::basic_set> &set) const; + inline typed::pw_aff, Anonymous> subtract_domain(const typed::point> &set) const; + inline typed::multi_pw_aff, Anonymous> to_multi_pw_aff() const; + inline typed::union_pw_aff, Anonymous> to_union_pw_aff() const; + inline typed::union_pw_multi_aff, Anonymous> to_union_pw_multi_aff() const; + inline typed::multi_pw_aff, Anonymous> unbind_params_insert_domain(const typed::multi_id<> &domain) const = delete; + inline typed::multi_pw_aff, Anonymous> union_add(const typed::multi_pw_aff, Anonymous> &mpa2) const; + inline typed::multi_union_pw_aff, Anonymous> union_add(const typed::multi_union_pw_aff, Anonymous> &mupa2) const; + inline typed::pw_aff, Anonymous> union_add(const typed::pw_aff, Anonymous> &pwaff2) const; + inline typed::pw_multi_aff, Anonymous> union_add(const typed::pw_multi_aff, Anonymous> &pma2) const; + inline typed::union_pw_aff, Anonymous> union_add(const typed::union_pw_aff, Anonymous> &upa2) const; + inline typed::union_pw_multi_aff, Anonymous> union_add(const typed::union_pw_multi_aff, Anonymous> &upma2) const; + inline typed::pw_aff, Anonymous> union_add(const typed::aff, Anonymous> &pwaff2) const; +}; + +template <> +struct pw_aff_list : public isl::pw_aff_list { + template + friend struct aff; + template + friend struct aff_list; + template + friend struct basic_map; + template + friend struct basic_set; + template + friend struct fixed_box; + template + friend struct id; + template + friend struct id_list; + template + friend struct map; + template + friend struct map_list; + template + friend struct multi_aff; + template + friend struct multi_id; + template + friend struct multi_pw_aff; + template + friend struct multi_union_pw_aff; + template + friend struct multi_val; + template + friend struct point; + template + friend struct pw_aff; + template + friend struct pw_aff_list; + template + friend struct pw_multi_aff; + template + friend struct pw_multi_aff_list; + template + friend struct set; + template + friend struct set_list; + template + friend struct space; + template + friend struct union_map; + template + friend struct union_pw_aff; + template + friend struct union_pw_aff_list; + template + friend struct union_pw_multi_aff; + template + friend struct union_set; + template + friend struct union_set_list; + template + friend struct val; + template + friend struct val_list; + + pw_aff_list() = default; + pw_aff_list(const isl::pw_aff_list &obj) : isl::pw_aff_list(obj) {} + static pw_aff_list from(const isl::pw_aff_list &obj) { + return pw_aff_list(obj); + } + inline explicit pw_aff_list(const isl::ctx &ctx, int n); + inline explicit pw_aff_list(const typed::pw_aff &el); + inline explicit pw_aff_list(const isl::ctx &ctx, const std::string &str); + inline typed::pw_aff_list add(const typed::pw_aff &el) const; + inline typed::pw_aff_list add(const typed::aff &el) const; + inline typed::pw_aff at(int index) const; + inline typed::pw_aff get_at(int index) const = delete; + inline typed::pw_aff_list drop(unsigned int first, unsigned int n) const; + inline void foreach(const std::function)> &fn) const; + inline void foreach_scc(const std::function, typed::pw_aff)> &follows, const std::function)> &fn) const; + inline typed::pw_aff_list set_at(int index, const typed::pw_aff &el) const; +}; + +template +struct pw_aff_list : public isl::pw_aff_list { + template + friend struct aff; + template + friend struct aff_list; + template + friend struct basic_map; + template + friend struct basic_set; + template + friend struct fixed_box; + template + friend struct id; + template + friend struct id_list; + template + friend struct map; + template + friend struct map_list; + template + friend struct multi_aff; + template + friend struct multi_id; + template + friend struct multi_pw_aff; + template + friend struct multi_union_pw_aff; + template + friend struct multi_val; + template + friend struct point; + template + friend struct pw_aff; + template + friend struct pw_aff_list; + template + friend struct pw_multi_aff; + template + friend struct pw_multi_aff_list; + template + friend struct set; + template + friend struct set_list; + template + friend struct space; + template + friend struct union_map; + template + friend struct union_pw_aff; + template + friend struct union_pw_aff_list; + template + friend struct union_pw_multi_aff; + template + friend struct union_set; + template + friend struct union_set_list; + template + friend struct val; + template + friend struct val_list; + + pw_aff_list() = default; + template {}, + bool>::type = true> + pw_aff_list(const pw_aff_list &obj) : isl::pw_aff_list(obj) {} + private: + template {}, bool>::type = true> + pw_aff_list(const base &obj) : isl::pw_aff_list(obj) {} + public: + static pw_aff_list from(const isl::pw_aff_list &obj) { + return pw_aff_list(obj); + } + inline explicit pw_aff_list(const isl::ctx &ctx, int n); + inline explicit pw_aff_list(const typed::pw_aff &el); + inline explicit pw_aff_list(const isl::ctx &ctx, const std::string &str); + inline typed::pw_aff_list add(const typed::pw_aff &el) const; + inline typed::pw_aff_list add(const typed::aff &el) const; + inline typed::pw_aff at(int index) const; + inline typed::pw_aff get_at(int index) const = delete; + inline typed::pw_aff_list drop(unsigned int first, unsigned int n) const; + inline void foreach(const std::function)> &fn) const; + inline void foreach_scc(const std::function, typed::pw_aff)> &follows, const std::function)> &fn) const; + inline typed::pw_aff_list set_at(int index, const typed::pw_aff &el) const; +}; + +template +struct pw_multi_aff : public isl::pw_multi_aff { + template + friend struct aff; + template + friend struct aff_list; + template + friend struct basic_map; + template + friend struct basic_set; + template + friend struct fixed_box; + template + friend struct id; + template + friend struct id_list; + template + friend struct map; + template + friend struct map_list; + template + friend struct multi_aff; + template + friend struct multi_id; + template + friend struct multi_pw_aff; + template + friend struct multi_union_pw_aff; + template + friend struct multi_val; + template + friend struct point; + template + friend struct pw_aff; + template + friend struct pw_aff_list; + template + friend struct pw_multi_aff; + template + friend struct pw_multi_aff_list; + template + friend struct set; + template + friend struct set_list; + template + friend struct space; + template + friend struct union_map; + template + friend struct union_pw_aff; + template + friend struct union_pw_aff_list; + template + friend struct union_pw_multi_aff; + template + friend struct union_set; + template + friend struct union_set_list; + template + friend struct val; + template + friend struct val_list; + + pw_multi_aff() = default; + template {}, + bool>::type = true> + pw_multi_aff(const pw_multi_aff &obj) : isl::pw_multi_aff(obj) {} + private: + template {}, bool>::type = true> + pw_multi_aff(const base &obj) : isl::pw_multi_aff(obj) {} + public: + static pw_multi_aff from(const isl::pw_multi_aff &obj) { + return pw_multi_aff(obj); + } + inline /* implicit */ pw_multi_aff(const typed::multi_aff &ma); + inline /* implicit */ pw_multi_aff(const typed::pw_aff &pa); + inline explicit pw_multi_aff(const isl::ctx &ctx, const std::string &str); + inline typed::multi_pw_aff add(const typed::multi_pw_aff &multi2) const; + inline typed::multi_union_pw_aff add(const typed::multi_union_pw_aff &multi2) const; + inline typed::pw_multi_aff add(const typed::pw_multi_aff &pma2) const; + inline typed::union_pw_multi_aff add(const typed::union_pw_multi_aff &upma2) const; + inline typed::pw_multi_aff add(const typed::multi_aff &pma2) const; + inline typed::pw_multi_aff add(const typed::pw_aff &pma2) const; + inline typed::pw_multi_aff add_constant(const typed::multi_val &mv) const; + inline typed::pw_multi_aff add_constant(const typed::val &v) const; + inline typed::pw_multi_aff add_constant(long v) const; + template + inline typed::union_pw_multi_aff apply(const typed::union_pw_multi_aff &upma2) const; + inline typed::map as_map() const = delete; + inline typed::multi_aff as_multi_aff() const; + inline typed::multi_union_pw_aff as_multi_union_pw_aff() const; + inline typed::pw_multi_aff as_pw_multi_aff() const; + inline typed::set as_set() const; + inline typed::union_map as_union_map() const = delete; + inline typed::pw_aff at(int pos) const; + inline typed::pw_aff get_at(int pos) const = delete; + inline typed::set<> bind(const typed::multi_id &tuple) const; + inline typed::pw_multi_aff bind_domain(const typed::multi_id<> &tuple) const = delete; + inline typed::pw_multi_aff bind_domain_wrapped_domain(const typed::multi_id<> &tuple) const = delete; + inline typed::pw_multi_aff coalesce() const; + inline typed::set<> domain() const; + inline typed::pw_multi_aff domain_reverse() const = delete; + inline typed::pw_multi_aff drop_unused_params() const; + inline typed::pw_multi_aff extract_pw_multi_aff(const typed::space &space) const; + inline typed::pw_multi_aff gist(const typed::set<> &set) const; + inline typed::union_pw_multi_aff gist(const typed::union_set<> &context) const; + inline typed::pw_multi_aff gist(const typed::basic_set<> &set) const; + inline typed::pw_multi_aff gist(const typed::point<> &set) const; + inline typed::pw_multi_aff gist_params(const typed::set<> &set) const; + inline typed::pw_multi_aff gist_params(const typed::basic_set<> &set) const; + inline typed::pw_multi_aff gist_params(const typed::point<> &set) const; + inline typed::multi_pw_aff identity() const; + template + inline typed::pw_multi_aff insert_domain(const typed::space &domain) const; + inline typed::pw_multi_aff intersect_domain(const typed::set<> &set) const = delete; + inline typed::union_pw_multi_aff intersect_domain(const typed::space<> &space) const = delete; + inline typed::union_pw_multi_aff intersect_domain(const typed::union_set<> &uset) const = delete; + inline typed::pw_multi_aff intersect_domain(const typed::basic_set<> &set) const = delete; + inline typed::pw_multi_aff intersect_domain(const typed::point<> &set) const = delete; + inline typed::union_pw_multi_aff intersect_domain_wrapped_domain(const typed::union_set<> &uset) const = delete; + inline typed::pw_multi_aff intersect_params(const typed::set<> &set) const; + inline typed::pw_multi_aff intersect_params(const typed::basic_set<> &set) const; + inline typed::pw_multi_aff intersect_params(const typed::point<> &set) const; + inline typed::pw_aff_list list() const; + inline typed::multi_pw_aff max(const typed::multi_pw_aff &multi2) const; + inline typed::multi_val max_multi_val() const; + inline typed::multi_pw_aff min(const typed::multi_pw_aff &multi2) const; + inline typed::multi_val min_multi_val() const; + inline typed::multi_pw_aff neg() const; + inline typed::pw_multi_aff preimage_domain_wrapped_domain(const typed::pw_multi_aff<> &pma2) const = delete; + inline typed::union_pw_multi_aff preimage_domain_wrapped_domain(const typed::union_pw_multi_aff<> &upma2) const = delete; + inline typed::pw_multi_aff preimage_domain_wrapped_domain(const typed::multi_aff<> &pma2) const = delete; + inline typed::pw_multi_aff preimage_domain_wrapped_domain(const typed::pw_aff<> &pma2) const = delete; + template + inline typed::multi_pw_aff> product(const typed::multi_pw_aff &multi2) const; + template + inline typed::pw_multi_aff> product(const typed::pw_multi_aff &pma2) const; + template + inline typed::pw_multi_aff> product(const typed::multi_aff &pma2) const; + inline typed::pw_multi_aff> product(const typed::pw_aff &pma2) const; + inline typed::multi_pw_aff pullback(const typed::multi_pw_aff<> &mpa2) const = delete; + inline typed::pw_multi_aff pullback(const typed::multi_aff<> &ma) const = delete; + inline typed::pw_multi_aff pullback(const typed::pw_multi_aff<> &pma2) const = delete; + inline typed::union_pw_multi_aff pullback(const typed::union_pw_multi_aff<> &upma2) const = delete; + inline typed::pw_multi_aff_list pw_multi_aff_list() const; + inline typed::pw_multi_aff range_factor_domain() const = delete; + inline typed::pw_multi_aff range_factor_range() const = delete; + inline typed::multi_pw_aff range_product(const typed::multi_pw_aff<> &multi2) const = delete; + inline typed::multi_union_pw_aff range_product(const typed::multi_union_pw_aff<> &multi2) const = delete; + inline typed::pw_multi_aff range_product(const typed::pw_multi_aff<> &pma2) const = delete; + inline typed::union_pw_multi_aff range_product(const typed::union_pw_multi_aff<> &upma2) const = delete; + inline typed::pw_multi_aff range_product(const typed::multi_aff<> &pma2) const = delete; + inline typed::pw_multi_aff range_product(const typed::pw_aff<> &pma2) const = delete; + inline typed::id get_range_tuple_id() const = delete; + inline typed::pw_multi_aff scale(const typed::multi_val &mv) const; + inline typed::pw_multi_aff scale(const typed::val &v) const; + inline typed::pw_multi_aff scale(long v) const; + inline typed::pw_multi_aff scale_down(const typed::multi_val &mv) const; + inline typed::pw_multi_aff scale_down(const typed::val &v) const; + inline typed::pw_multi_aff scale_down(long v) const; + inline typed::multi_pw_aff set_at(int pos, const typed::pw_aff &el) const; + inline typed::multi_union_pw_aff set_at(int pos, const typed::union_pw_aff &el) const; + template + inline typed::pw_multi_aff set_range_tuple(const typed::id &id) const; + template + inline typed::pw_multi_aff set_range_tuple(const std::string &id) const; + inline typed::space space() const; + inline typed::space get_space() const = delete; + inline typed::multi_pw_aff sub(const typed::multi_pw_aff &multi2) const; + inline typed::multi_union_pw_aff sub(const typed::multi_union_pw_aff &multi2) const; + inline typed::pw_multi_aff sub(const typed::pw_multi_aff &pma2) const; + inline typed::union_pw_multi_aff sub(const typed::union_pw_multi_aff &upma2) const; + inline typed::pw_multi_aff sub(const typed::multi_aff &pma2) const; + inline typed::pw_multi_aff sub(const typed::pw_aff &pma2) const; + inline typed::pw_multi_aff subtract_domain(const typed::set<> &set) const = delete; + inline typed::union_pw_multi_aff subtract_domain(const typed::space<> &space) const = delete; + inline typed::union_pw_multi_aff subtract_domain(const typed::union_set<> &uset) const = delete; + inline typed::pw_multi_aff subtract_domain(const typed::basic_set<> &set) const = delete; + inline typed::pw_multi_aff subtract_domain(const typed::point<> &set) const = delete; + inline typed::multi_pw_aff to_multi_pw_aff() const; + inline typed::union_pw_multi_aff to_union_pw_multi_aff() const; + template + inline typed::multi_pw_aff unbind_params_insert_domain(const typed::multi_id &domain) const; + inline typed::multi_pw_aff union_add(const typed::multi_pw_aff &mpa2) const; + inline typed::multi_union_pw_aff union_add(const typed::multi_union_pw_aff &mupa2) const; + inline typed::pw_multi_aff union_add(const typed::pw_multi_aff &pma2) const; + inline typed::union_pw_multi_aff union_add(const typed::union_pw_multi_aff &upma2) const; + inline typed::pw_multi_aff union_add(const typed::multi_aff &pma2) const; + inline typed::pw_multi_aff union_add(const typed::pw_aff &pma2) const; +}; + +template +struct pw_multi_aff : public isl::pw_multi_aff { + template + friend struct aff; + template + friend struct aff_list; + template + friend struct basic_map; + template + friend struct basic_set; + template + friend struct fixed_box; + template + friend struct id; + template + friend struct id_list; + template + friend struct map; + template + friend struct map_list; + template + friend struct multi_aff; + template + friend struct multi_id; + template + friend struct multi_pw_aff; + template + friend struct multi_union_pw_aff; + template + friend struct multi_val; + template + friend struct point; + template + friend struct pw_aff; + template + friend struct pw_aff_list; + template + friend struct pw_multi_aff; + template + friend struct pw_multi_aff_list; + template + friend struct set; + template + friend struct set_list; + template + friend struct space; + template + friend struct union_map; + template + friend struct union_pw_aff; + template + friend struct union_pw_aff_list; + template + friend struct union_pw_multi_aff; + template + friend struct union_set; + template + friend struct union_set_list; + template + friend struct val; + template + friend struct val_list; + + pw_multi_aff() = default; + template {} && + std::is_base_of{}, + bool>::type = true> + pw_multi_aff(const pw_multi_aff &obj) : isl::pw_multi_aff(obj) {} + private: + template {}, bool>::type = true> + pw_multi_aff(const base &obj) : isl::pw_multi_aff(obj) {} + public: + static pw_multi_aff from(const isl::pw_multi_aff &obj) { + return pw_multi_aff(obj); + } + inline /* implicit */ pw_multi_aff(const typed::multi_aff &ma); + inline /* implicit */ pw_multi_aff(const typed::pw_aff &pa); + inline explicit pw_multi_aff(const isl::ctx &ctx, const std::string &str); + inline typed::multi_pw_aff add(const typed::multi_pw_aff &multi2) const; + inline typed::multi_union_pw_aff add(const typed::multi_union_pw_aff &multi2) const; + inline typed::pw_multi_aff add(const typed::pw_multi_aff &pma2) const; + inline typed::union_pw_multi_aff add(const typed::union_pw_multi_aff &upma2) const; + inline typed::pw_multi_aff add(const typed::multi_aff &pma2) const; + inline typed::pw_multi_aff add(const typed::pw_aff &pma2) const; + inline typed::pw_multi_aff add_constant(const typed::multi_val &mv) const; + inline typed::pw_multi_aff add_constant(const typed::val &v) const; + inline typed::pw_multi_aff add_constant(long v) const; + template + inline typed::union_pw_multi_aff apply(const typed::union_pw_multi_aff &upma2) const; + inline typed::map as_map() const; + inline typed::multi_aff as_multi_aff() const; + inline typed::multi_union_pw_aff as_multi_union_pw_aff() const; + inline typed::pw_multi_aff as_pw_multi_aff() const; + inline typed::set as_set() const = delete; + inline typed::union_map as_union_map() const; + inline typed::pw_aff at(int pos) const; + inline typed::pw_aff get_at(int pos) const = delete; + inline typed::set bind(const typed::multi_id &tuple) const; + inline typed::pw_multi_aff bind_domain(const typed::multi_id &tuple) const; + inline typed::pw_multi_aff bind_domain_wrapped_domain(const typed::multi_id<> &tuple) const = delete; + inline typed::pw_multi_aff coalesce() const; + inline typed::set domain() const; + inline typed::pw_multi_aff domain_reverse() const = delete; + inline typed::pw_multi_aff drop_unused_params() const; + inline typed::pw_multi_aff extract_pw_multi_aff(const typed::space &space) const; + inline typed::pw_multi_aff gist(const typed::set &set) const; + inline typed::union_pw_multi_aff gist(const typed::union_set &context) const; + inline typed::pw_multi_aff gist(const typed::basic_set &set) const; + inline typed::pw_multi_aff gist(const typed::point &set) const; + inline typed::pw_multi_aff gist_params(const typed::set<> &set) const; + inline typed::pw_multi_aff gist_params(const typed::basic_set<> &set) const; + inline typed::pw_multi_aff gist_params(const typed::point<> &set) const; + inline typed::multi_pw_aff identity() const; + inline typed::pw_multi_aff insert_domain(const typed::space<> &domain) const = delete; + inline typed::pw_multi_aff intersect_domain(const typed::set &set) const; + inline typed::union_pw_multi_aff intersect_domain(const typed::space &space) const; + inline typed::union_pw_multi_aff intersect_domain(const typed::union_set &uset) const; + inline typed::pw_multi_aff intersect_domain(const typed::basic_set &set) const; + inline typed::pw_multi_aff intersect_domain(const typed::point &set) const; + inline typed::union_pw_multi_aff intersect_domain_wrapped_domain(const typed::union_set<> &uset) const = delete; + inline typed::pw_multi_aff intersect_params(const typed::set<> &set) const; + inline typed::pw_multi_aff intersect_params(const typed::basic_set<> &set) const; + inline typed::pw_multi_aff intersect_params(const typed::point<> &set) const; + inline typed::pw_aff_list list() const; + inline typed::multi_pw_aff max(const typed::multi_pw_aff &multi2) const; + inline typed::multi_val max_multi_val() const; + inline typed::multi_pw_aff min(const typed::multi_pw_aff &multi2) const; + inline typed::multi_val min_multi_val() const; + inline typed::multi_pw_aff neg() const; + inline typed::pw_multi_aff preimage_domain_wrapped_domain(const typed::pw_multi_aff<> &pma2) const = delete; + inline typed::union_pw_multi_aff preimage_domain_wrapped_domain(const typed::union_pw_multi_aff<> &upma2) const = delete; + inline typed::pw_multi_aff preimage_domain_wrapped_domain(const typed::multi_aff<> &pma2) const = delete; + inline typed::pw_multi_aff preimage_domain_wrapped_domain(const typed::pw_aff<> &pma2) const = delete; + template + inline typed::multi_pw_aff, pair> product(const typed::multi_pw_aff &multi2) const; + template + inline typed::pw_multi_aff, pair> product(const typed::pw_multi_aff &pma2) const; + template + inline typed::pw_multi_aff, pair> product(const typed::multi_aff &pma2) const; + template + inline typed::pw_multi_aff, pair> product(const typed::pw_aff &pma2) const; + template + inline typed::multi_pw_aff pullback(const typed::multi_pw_aff &mpa2) const; + inline typed::multi_pw_aff pullback(const typed::multi_pw_aff &mpa2) const; + template + inline typed::pw_multi_aff pullback(const typed::multi_aff &ma) const; + inline typed::pw_multi_aff pullback(const typed::multi_aff &ma) const; + template + inline typed::pw_multi_aff pullback(const typed::pw_multi_aff &pma2) const; + inline typed::pw_multi_aff pullback(const typed::pw_multi_aff &pma2) const; + template + inline typed::union_pw_multi_aff pullback(const typed::union_pw_multi_aff &upma2) const; + inline typed::union_pw_multi_aff pullback(const typed::union_pw_multi_aff &upma2) const; + inline typed::pw_multi_aff_list pw_multi_aff_list() const; + inline typed::pw_multi_aff range_factor_domain() const = delete; + inline typed::pw_multi_aff range_factor_range() const = delete; + template + inline typed::multi_pw_aff> range_product(const typed::multi_pw_aff &multi2) const; + template + inline typed::multi_union_pw_aff> range_product(const typed::multi_union_pw_aff &multi2) const; + template + inline typed::pw_multi_aff> range_product(const typed::pw_multi_aff &pma2) const; + template + inline typed::union_pw_multi_aff> range_product(const typed::union_pw_multi_aff &upma2) const; + template + inline typed::pw_multi_aff> range_product(const typed::multi_aff &pma2) const; + inline typed::pw_multi_aff> range_product(const typed::pw_aff &pma2) const; + inline typed::id get_range_tuple_id() const = delete; + inline typed::pw_multi_aff scale(const typed::multi_val &mv) const; + inline typed::pw_multi_aff scale(const typed::val &v) const; + inline typed::pw_multi_aff scale(long v) const; + inline typed::pw_multi_aff scale_down(const typed::multi_val &mv) const; + inline typed::pw_multi_aff scale_down(const typed::val &v) const; + inline typed::pw_multi_aff scale_down(long v) const; + inline typed::multi_pw_aff set_at(int pos, const typed::pw_aff &el) const; + inline typed::multi_union_pw_aff set_at(int pos, const typed::union_pw_aff &el) const; + template + inline typed::pw_multi_aff set_range_tuple(const typed::id &id) const; + template + inline typed::pw_multi_aff set_range_tuple(const std::string &id) const; + inline typed::space space() const; + inline typed::space get_space() const = delete; + inline typed::multi_pw_aff sub(const typed::multi_pw_aff &multi2) const; + inline typed::multi_union_pw_aff sub(const typed::multi_union_pw_aff &multi2) const; + inline typed::pw_multi_aff sub(const typed::pw_multi_aff &pma2) const; + inline typed::union_pw_multi_aff sub(const typed::union_pw_multi_aff &upma2) const; + inline typed::pw_multi_aff sub(const typed::multi_aff &pma2) const; + inline typed::pw_multi_aff sub(const typed::pw_aff &pma2) const; + inline typed::pw_multi_aff subtract_domain(const typed::set &set) const; + inline typed::union_pw_multi_aff subtract_domain(const typed::space &space) const; + inline typed::union_pw_multi_aff subtract_domain(const typed::union_set &uset) const; + inline typed::pw_multi_aff subtract_domain(const typed::basic_set &set) const; + inline typed::pw_multi_aff subtract_domain(const typed::point &set) const; + inline typed::multi_pw_aff to_multi_pw_aff() const; + inline typed::union_pw_multi_aff to_union_pw_multi_aff() const; + inline typed::multi_pw_aff unbind_params_insert_domain(const typed::multi_id<> &domain) const = delete; + inline typed::multi_pw_aff union_add(const typed::multi_pw_aff &mpa2) const; + inline typed::multi_union_pw_aff union_add(const typed::multi_union_pw_aff &mupa2) const; + inline typed::pw_multi_aff union_add(const typed::pw_multi_aff &pma2) const; + inline typed::union_pw_multi_aff union_add(const typed::union_pw_multi_aff &upma2) const; + inline typed::pw_multi_aff union_add(const typed::multi_aff &pma2) const; + inline typed::pw_multi_aff union_add(const typed::pw_aff &pma2) const; +}; + +template +struct pw_multi_aff, Range> : public isl::pw_multi_aff { + template + friend struct aff; + template + friend struct aff_list; + template + friend struct basic_map; + template + friend struct basic_set; + template + friend struct fixed_box; + template + friend struct id; + template + friend struct id_list; + template + friend struct map; + template + friend struct map_list; + template + friend struct multi_aff; + template + friend struct multi_id; + template + friend struct multi_pw_aff; + template + friend struct multi_union_pw_aff; + template + friend struct multi_val; + template + friend struct point; + template + friend struct pw_aff; + template + friend struct pw_aff_list; + template + friend struct pw_multi_aff; + template + friend struct pw_multi_aff_list; + template + friend struct set; + template + friend struct set_list; + template + friend struct space; + template + friend struct union_map; + template + friend struct union_pw_aff; + template + friend struct union_pw_aff_list; + template + friend struct union_pw_multi_aff; + template + friend struct union_set; + template + friend struct union_set_list; + template + friend struct val; + template + friend struct val_list; + + pw_multi_aff() = default; + template {} && + std::is_base_of{} && + std::is_base_of{}, + bool>::type = true> + pw_multi_aff(const pw_multi_aff, Arg3> &obj) : isl::pw_multi_aff(obj) {} + private: + template {}, bool>::type = true> + pw_multi_aff(const base &obj) : isl::pw_multi_aff(obj) {} + public: + static pw_multi_aff from(const isl::pw_multi_aff &obj) { + return pw_multi_aff(obj); + } + inline /* implicit */ pw_multi_aff(const typed::multi_aff, Range> &ma); + inline /* implicit */ pw_multi_aff(const typed::pw_aff, Range> &pa); + inline explicit pw_multi_aff(const isl::ctx &ctx, const std::string &str); + inline typed::multi_pw_aff, Range> add(const typed::multi_pw_aff, Range> &multi2) const; + inline typed::multi_union_pw_aff, Range> add(const typed::multi_union_pw_aff, Range> &multi2) const; + inline typed::pw_multi_aff, Range> add(const typed::pw_multi_aff, Range> &pma2) const; + inline typed::union_pw_multi_aff, Range> add(const typed::union_pw_multi_aff, Range> &upma2) const; + inline typed::pw_multi_aff, Range> add(const typed::multi_aff, Range> &pma2) const; + inline typed::pw_multi_aff, Range> add(const typed::pw_aff, Range> &pma2) const; + inline typed::pw_multi_aff, Range> add_constant(const typed::multi_val &mv) const; + inline typed::pw_multi_aff, Range> add_constant(const typed::val &v) const; + inline typed::pw_multi_aff, Range> add_constant(long v) const; + template + inline typed::union_pw_multi_aff, Arg2> apply(const typed::union_pw_multi_aff &upma2) const; + inline typed::map, Range> as_map() const; + inline typed::multi_aff, Range> as_multi_aff() const; + inline typed::multi_union_pw_aff, Range> as_multi_union_pw_aff() const; + inline typed::pw_multi_aff, Range> as_pw_multi_aff() const; + inline typed::set, Range> as_set() const = delete; + inline typed::union_map, Range> as_union_map() const; + inline typed::pw_aff, Anonymous> at(int pos) const; + inline typed::pw_aff, Range> get_at(int pos) const = delete; + inline typed::set> bind(const typed::multi_id &tuple) const; + inline typed::pw_multi_aff bind_domain(const typed::multi_id> &tuple) const; + inline typed::pw_multi_aff bind_domain_wrapped_domain(const typed::multi_id &tuple) const; + inline typed::pw_multi_aff, Range> coalesce() const; + inline typed::set> domain() const; + inline typed::pw_multi_aff, Range> domain_reverse() const; + inline typed::pw_multi_aff, Range> drop_unused_params() const; + inline typed::pw_multi_aff, Range> extract_pw_multi_aff(const typed::space, Range> &space) const; + inline typed::pw_multi_aff, Range> gist(const typed::set> &set) const; + inline typed::union_pw_multi_aff, Range> gist(const typed::union_set> &context) const; + inline typed::pw_multi_aff, Range> gist(const typed::basic_set> &set) const; + inline typed::pw_multi_aff, Range> gist(const typed::point> &set) const; + inline typed::pw_multi_aff, Range> gist_params(const typed::set<> &set) const; + inline typed::pw_multi_aff, Range> gist_params(const typed::basic_set<> &set) const; + inline typed::pw_multi_aff, Range> gist_params(const typed::point<> &set) const; + inline typed::multi_pw_aff, Range> identity() const; + inline typed::pw_multi_aff, Range> insert_domain(const typed::space<> &domain) const = delete; + inline typed::pw_multi_aff, Range> intersect_domain(const typed::set> &set) const; + inline typed::union_pw_multi_aff, Range> intersect_domain(const typed::space> &space) const; + inline typed::union_pw_multi_aff, Range> intersect_domain(const typed::union_set> &uset) const; + inline typed::pw_multi_aff, Range> intersect_domain(const typed::basic_set> &set) const; + inline typed::pw_multi_aff, Range> intersect_domain(const typed::point> &set) const; + inline typed::union_pw_multi_aff, Range> intersect_domain_wrapped_domain(const typed::union_set &uset) const; + inline typed::pw_multi_aff, Range> intersect_params(const typed::set<> &set) const; + inline typed::pw_multi_aff, Range> intersect_params(const typed::basic_set<> &set) const; + inline typed::pw_multi_aff, Range> intersect_params(const typed::point<> &set) const; + inline typed::pw_aff_list, Anonymous> list() const; + inline typed::multi_pw_aff, Range> max(const typed::multi_pw_aff, Range> &multi2) const; + inline typed::multi_val max_multi_val() const; + inline typed::multi_pw_aff, Range> min(const typed::multi_pw_aff, Range> &multi2) const; + inline typed::multi_val min_multi_val() const; + inline typed::multi_pw_aff, Range> neg() const; + template + inline typed::pw_multi_aff, Range> preimage_domain_wrapped_domain(const typed::pw_multi_aff &pma2) const; + template + inline typed::union_pw_multi_aff, Range> preimage_domain_wrapped_domain(const typed::union_pw_multi_aff &upma2) const; + template + inline typed::pw_multi_aff, Range> preimage_domain_wrapped_domain(const typed::multi_aff &pma2) const; + template + inline typed::pw_multi_aff, Range> preimage_domain_wrapped_domain(const typed::pw_aff &pma2) const; + template + inline typed::multi_pw_aff, Arg2>, pair> product(const typed::multi_pw_aff &multi2) const; + template + inline typed::pw_multi_aff, Arg2>, pair> product(const typed::pw_multi_aff &pma2) const; + template + inline typed::pw_multi_aff, Arg2>, pair> product(const typed::multi_aff &pma2) const; + template + inline typed::pw_multi_aff, Arg2>, pair> product(const typed::pw_aff &pma2) const; + template + inline typed::multi_pw_aff pullback(const typed::multi_pw_aff> &mpa2) const; + inline typed::multi_pw_aff pullback(const typed::multi_pw_aff> &mpa2) const; + template + inline typed::pw_multi_aff pullback(const typed::multi_aff> &ma) const; + inline typed::pw_multi_aff pullback(const typed::multi_aff> &ma) const; + template + inline typed::pw_multi_aff pullback(const typed::pw_multi_aff> &pma2) const; + inline typed::pw_multi_aff pullback(const typed::pw_multi_aff> &pma2) const; + template + inline typed::union_pw_multi_aff pullback(const typed::union_pw_multi_aff> &upma2) const; + inline typed::union_pw_multi_aff pullback(const typed::union_pw_multi_aff> &upma2) const; + inline typed::pw_multi_aff_list, Range> pw_multi_aff_list() const; + inline typed::pw_multi_aff, Range> range_factor_domain() const = delete; + inline typed::pw_multi_aff, Range> range_factor_range() const = delete; + template + inline typed::multi_pw_aff, pair> range_product(const typed::multi_pw_aff, Arg2> &multi2) const; + template + inline typed::multi_union_pw_aff, pair> range_product(const typed::multi_union_pw_aff, Arg2> &multi2) const; + template + inline typed::pw_multi_aff, pair> range_product(const typed::pw_multi_aff, Arg2> &pma2) const; + template + inline typed::union_pw_multi_aff, pair> range_product(const typed::union_pw_multi_aff, Arg2> &upma2) const; + template + inline typed::pw_multi_aff, pair> range_product(const typed::multi_aff, Arg2> &pma2) const; + inline typed::pw_multi_aff, pair> range_product(const typed::pw_aff, Anonymous> &pma2) const; + inline typed::id, Range> get_range_tuple_id() const = delete; + inline typed::pw_multi_aff, Range> scale(const typed::multi_val &mv) const; + inline typed::pw_multi_aff, Range> scale(const typed::val &v) const; + inline typed::pw_multi_aff, Range> scale(long v) const; + inline typed::pw_multi_aff, Range> scale_down(const typed::multi_val &mv) const; + inline typed::pw_multi_aff, Range> scale_down(const typed::val &v) const; + inline typed::pw_multi_aff, Range> scale_down(long v) const; + inline typed::multi_pw_aff, Range> set_at(int pos, const typed::pw_aff, Anonymous> &el) const; + inline typed::multi_union_pw_aff, Range> set_at(int pos, const typed::union_pw_aff, Anonymous> &el) const; + template + inline typed::pw_multi_aff, Arg1> set_range_tuple(const typed::id &id) const; + template + inline typed::pw_multi_aff, Arg1> set_range_tuple(const std::string &id) const; + inline typed::space, Range> space() const; + inline typed::space, Range> get_space() const = delete; + inline typed::multi_pw_aff, Range> sub(const typed::multi_pw_aff, Range> &multi2) const; + inline typed::multi_union_pw_aff, Range> sub(const typed::multi_union_pw_aff, Range> &multi2) const; + inline typed::pw_multi_aff, Range> sub(const typed::pw_multi_aff, Range> &pma2) const; + inline typed::union_pw_multi_aff, Range> sub(const typed::union_pw_multi_aff, Range> &upma2) const; + inline typed::pw_multi_aff, Range> sub(const typed::multi_aff, Range> &pma2) const; + inline typed::pw_multi_aff, Range> sub(const typed::pw_aff, Range> &pma2) const; + inline typed::pw_multi_aff, Range> subtract_domain(const typed::set> &set) const; + inline typed::union_pw_multi_aff, Range> subtract_domain(const typed::space> &space) const; + inline typed::union_pw_multi_aff, Range> subtract_domain(const typed::union_set> &uset) const; + inline typed::pw_multi_aff, Range> subtract_domain(const typed::basic_set> &set) const; + inline typed::pw_multi_aff, Range> subtract_domain(const typed::point> &set) const; + inline typed::multi_pw_aff, Range> to_multi_pw_aff() const; + inline typed::union_pw_multi_aff, Range> to_union_pw_multi_aff() const; + inline typed::multi_pw_aff, Range> unbind_params_insert_domain(const typed::multi_id<> &domain) const = delete; + inline typed::multi_pw_aff, Range> union_add(const typed::multi_pw_aff, Range> &mpa2) const; + inline typed::multi_union_pw_aff, Range> union_add(const typed::multi_union_pw_aff, Range> &mupa2) const; + inline typed::pw_multi_aff, Range> union_add(const typed::pw_multi_aff, Range> &pma2) const; + inline typed::union_pw_multi_aff, Range> union_add(const typed::union_pw_multi_aff, Range> &upma2) const; + inline typed::pw_multi_aff, Range> union_add(const typed::multi_aff, Range> &pma2) const; + inline typed::pw_multi_aff, Range> union_add(const typed::pw_aff, Range> &pma2) const; +}; + +template +struct pw_multi_aff> : public isl::pw_multi_aff { + template + friend struct aff; + template + friend struct aff_list; + template + friend struct basic_map; + template + friend struct basic_set; + template + friend struct fixed_box; + template + friend struct id; + template + friend struct id_list; + template + friend struct map; + template + friend struct map_list; + template + friend struct multi_aff; + template + friend struct multi_id; + template + friend struct multi_pw_aff; + template + friend struct multi_union_pw_aff; + template + friend struct multi_val; + template + friend struct point; + template + friend struct pw_aff; + template + friend struct pw_aff_list; + template + friend struct pw_multi_aff; + template + friend struct pw_multi_aff_list; + template + friend struct set; + template + friend struct set_list; + template + friend struct space; + template + friend struct union_map; + template + friend struct union_pw_aff; + template + friend struct union_pw_aff_list; + template + friend struct union_pw_multi_aff; + template + friend struct union_set; + template + friend struct union_set_list; + template + friend struct val; + template + friend struct val_list; + + pw_multi_aff() = default; + template {} && + std::is_base_of{} && + std::is_base_of{}, + bool>::type = true> + pw_multi_aff(const pw_multi_aff> &obj) : isl::pw_multi_aff(obj) {} + private: + template {}, bool>::type = true> + pw_multi_aff(const base &obj) : isl::pw_multi_aff(obj) {} + public: + static pw_multi_aff from(const isl::pw_multi_aff &obj) { + return pw_multi_aff(obj); + } + inline /* implicit */ pw_multi_aff(const typed::multi_aff> &ma); + inline /* implicit */ pw_multi_aff(const typed::pw_aff> &pa); + inline explicit pw_multi_aff(const isl::ctx &ctx, const std::string &str); + inline typed::multi_pw_aff> add(const typed::multi_pw_aff> &multi2) const; + inline typed::multi_union_pw_aff> add(const typed::multi_union_pw_aff> &multi2) const; + inline typed::pw_multi_aff> add(const typed::pw_multi_aff> &pma2) const; + inline typed::union_pw_multi_aff> add(const typed::union_pw_multi_aff> &upma2) const; + inline typed::pw_multi_aff> add(const typed::multi_aff> &pma2) const; + inline typed::pw_multi_aff> add(const typed::pw_aff> &pma2) const; + inline typed::pw_multi_aff> add_constant(const typed::multi_val> &mv) const; + inline typed::pw_multi_aff> add_constant(const typed::val> &v) const; + inline typed::pw_multi_aff> add_constant(long v) const; + template + inline typed::union_pw_multi_aff apply(const typed::union_pw_multi_aff, Arg3> &upma2) const; + inline typed::map> as_map() const; + inline typed::multi_aff> as_multi_aff() const; + inline typed::multi_union_pw_aff> as_multi_union_pw_aff() const; + inline typed::pw_multi_aff> as_pw_multi_aff() const; + inline typed::set> as_set() const = delete; + inline typed::union_map> as_union_map() const; + inline typed::pw_aff at(int pos) const; + inline typed::pw_aff> get_at(int pos) const = delete; + inline typed::set bind(const typed::multi_id> &tuple) const; + inline typed::pw_multi_aff> bind_domain(const typed::multi_id &tuple) const; + inline typed::pw_multi_aff> bind_domain_wrapped_domain(const typed::multi_id<> &tuple) const = delete; + inline typed::pw_multi_aff> coalesce() const; + inline typed::set domain() const; + inline typed::pw_multi_aff> domain_reverse() const = delete; + inline typed::pw_multi_aff> drop_unused_params() const; + inline typed::pw_multi_aff> extract_pw_multi_aff(const typed::space> &space) const; + inline typed::pw_multi_aff> gist(const typed::set &set) const; + inline typed::union_pw_multi_aff> gist(const typed::union_set &context) const; + inline typed::pw_multi_aff> gist(const typed::basic_set &set) const; + inline typed::pw_multi_aff> gist(const typed::point &set) const; + inline typed::pw_multi_aff> gist_params(const typed::set<> &set) const; + inline typed::pw_multi_aff> gist_params(const typed::basic_set<> &set) const; + inline typed::pw_multi_aff> gist_params(const typed::point<> &set) const; + inline typed::multi_pw_aff> identity() const; + inline typed::pw_multi_aff> insert_domain(const typed::space<> &domain) const = delete; + inline typed::pw_multi_aff> intersect_domain(const typed::set &set) const; + inline typed::union_pw_multi_aff> intersect_domain(const typed::space &space) const; + inline typed::union_pw_multi_aff> intersect_domain(const typed::union_set &uset) const; + inline typed::pw_multi_aff> intersect_domain(const typed::basic_set &set) const; + inline typed::pw_multi_aff> intersect_domain(const typed::point &set) const; + inline typed::union_pw_multi_aff> intersect_domain_wrapped_domain(const typed::union_set<> &uset) const = delete; + inline typed::pw_multi_aff> intersect_params(const typed::set<> &set) const; + inline typed::pw_multi_aff> intersect_params(const typed::basic_set<> &set) const; + inline typed::pw_multi_aff> intersect_params(const typed::point<> &set) const; + inline typed::pw_aff_list list() const; + inline typed::multi_pw_aff> max(const typed::multi_pw_aff> &multi2) const; + inline typed::multi_val> max_multi_val() const; + inline typed::multi_pw_aff> min(const typed::multi_pw_aff> &multi2) const; + inline typed::multi_val> min_multi_val() const; + inline typed::multi_pw_aff> neg() const; + inline typed::pw_multi_aff> preimage_domain_wrapped_domain(const typed::pw_multi_aff<> &pma2) const = delete; + inline typed::union_pw_multi_aff> preimage_domain_wrapped_domain(const typed::union_pw_multi_aff<> &upma2) const = delete; + inline typed::pw_multi_aff> preimage_domain_wrapped_domain(const typed::multi_aff<> &pma2) const = delete; + inline typed::pw_multi_aff> preimage_domain_wrapped_domain(const typed::pw_aff<> &pma2) const = delete; + template + inline typed::multi_pw_aff, pair, Arg3>> product(const typed::multi_pw_aff &multi2) const; + template + inline typed::pw_multi_aff, pair, Arg3>> product(const typed::pw_multi_aff &pma2) const; + template + inline typed::pw_multi_aff, pair, Arg3>> product(const typed::multi_aff &pma2) const; + template + inline typed::pw_multi_aff, pair, Anonymous>> product(const typed::pw_aff &pma2) const; + template + inline typed::multi_pw_aff> pullback(const typed::multi_pw_aff &mpa2) const; + inline typed::multi_pw_aff> pullback(const typed::multi_pw_aff &mpa2) const; + template + inline typed::pw_multi_aff> pullback(const typed::multi_aff &ma) const; + inline typed::pw_multi_aff> pullback(const typed::multi_aff &ma) const; + template + inline typed::pw_multi_aff> pullback(const typed::pw_multi_aff &pma2) const; + inline typed::pw_multi_aff> pullback(const typed::pw_multi_aff &pma2) const; + template + inline typed::union_pw_multi_aff> pullback(const typed::union_pw_multi_aff &upma2) const; + inline typed::union_pw_multi_aff> pullback(const typed::union_pw_multi_aff &upma2) const; + inline typed::pw_multi_aff_list> pw_multi_aff_list() const; + inline typed::pw_multi_aff range_factor_domain() const; + inline typed::pw_multi_aff range_factor_range() const; + template + inline typed::multi_pw_aff, Arg3>> range_product(const typed::multi_pw_aff &multi2) const; + template + inline typed::multi_union_pw_aff, Arg3>> range_product(const typed::multi_union_pw_aff &multi2) const; + template + inline typed::pw_multi_aff, Arg3>> range_product(const typed::pw_multi_aff &pma2) const; + template + inline typed::union_pw_multi_aff, Arg3>> range_product(const typed::union_pw_multi_aff &upma2) const; + template + inline typed::pw_multi_aff, Arg3>> range_product(const typed::multi_aff &pma2) const; + inline typed::pw_multi_aff, Anonymous>> range_product(const typed::pw_aff &pma2) const; + inline typed::id> get_range_tuple_id() const = delete; + inline typed::pw_multi_aff> scale(const typed::multi_val> &mv) const; + inline typed::pw_multi_aff> scale(const typed::val> &v) const; + inline typed::pw_multi_aff> scale(long v) const; + inline typed::pw_multi_aff> scale_down(const typed::multi_val> &mv) const; + inline typed::pw_multi_aff> scale_down(const typed::val> &v) const; + inline typed::pw_multi_aff> scale_down(long v) const; + inline typed::multi_pw_aff> set_at(int pos, const typed::pw_aff &el) const; + inline typed::multi_union_pw_aff> set_at(int pos, const typed::union_pw_aff &el) const; + inline typed::pw_multi_aff> set_range_tuple(const typed::id<> &id) const = delete; + inline typed::pw_multi_aff> set_range_tuple(const std::string &id) const = delete; + inline typed::space> space() const; + inline typed::space> get_space() const = delete; + inline typed::multi_pw_aff> sub(const typed::multi_pw_aff> &multi2) const; + inline typed::multi_union_pw_aff> sub(const typed::multi_union_pw_aff> &multi2) const; + inline typed::pw_multi_aff> sub(const typed::pw_multi_aff> &pma2) const; + inline typed::union_pw_multi_aff> sub(const typed::union_pw_multi_aff> &upma2) const; + inline typed::pw_multi_aff> sub(const typed::multi_aff> &pma2) const; + inline typed::pw_multi_aff> sub(const typed::pw_aff> &pma2) const; + inline typed::pw_multi_aff> subtract_domain(const typed::set &set) const; + inline typed::union_pw_multi_aff> subtract_domain(const typed::space &space) const; + inline typed::union_pw_multi_aff> subtract_domain(const typed::union_set &uset) const; + inline typed::pw_multi_aff> subtract_domain(const typed::basic_set &set) const; + inline typed::pw_multi_aff> subtract_domain(const typed::point &set) const; + inline typed::multi_pw_aff> to_multi_pw_aff() const; + inline typed::union_pw_multi_aff> to_union_pw_multi_aff() const; + inline typed::multi_pw_aff> unbind_params_insert_domain(const typed::multi_id<> &domain) const = delete; + inline typed::multi_pw_aff> union_add(const typed::multi_pw_aff> &mpa2) const; + inline typed::multi_union_pw_aff> union_add(const typed::multi_union_pw_aff> &mupa2) const; + inline typed::pw_multi_aff> union_add(const typed::pw_multi_aff> &pma2) const; + inline typed::union_pw_multi_aff> union_add(const typed::union_pw_multi_aff> &upma2) const; + inline typed::pw_multi_aff> union_add(const typed::multi_aff> &pma2) const; + inline typed::pw_multi_aff> union_add(const typed::pw_aff> &pma2) const; +}; + +template +struct pw_multi_aff, pair> : public isl::pw_multi_aff { + template + friend struct aff; + template + friend struct aff_list; + template + friend struct basic_map; + template + friend struct basic_set; + template + friend struct fixed_box; + template + friend struct id; + template + friend struct id_list; + template + friend struct map; + template + friend struct map_list; + template + friend struct multi_aff; + template + friend struct multi_id; + template + friend struct multi_pw_aff; + template + friend struct multi_union_pw_aff; + template + friend struct multi_val; + template + friend struct point; + template + friend struct pw_aff; + template + friend struct pw_aff_list; + template + friend struct pw_multi_aff; + template + friend struct pw_multi_aff_list; + template + friend struct set; + template + friend struct set_list; + template + friend struct space; + template + friend struct union_map; + template + friend struct union_pw_aff; + template + friend struct union_pw_aff_list; + template + friend struct union_pw_multi_aff; + template + friend struct union_set; + template + friend struct union_set_list; + template + friend struct val; + template + friend struct val_list; + + pw_multi_aff() = default; + template {} && + std::is_base_of{} && + std::is_base_of{} && + std::is_base_of{}, + bool>::type = true> + pw_multi_aff(const pw_multi_aff, pair> &obj) : isl::pw_multi_aff(obj) {} + private: + template {}, bool>::type = true> + pw_multi_aff(const base &obj) : isl::pw_multi_aff(obj) {} + public: + static pw_multi_aff from(const isl::pw_multi_aff &obj) { + return pw_multi_aff(obj); + } + inline /* implicit */ pw_multi_aff(const typed::multi_aff, pair> &ma); + inline /* implicit */ pw_multi_aff(const typed::pw_aff, pair> &pa); + inline explicit pw_multi_aff(const isl::ctx &ctx, const std::string &str); + inline typed::multi_pw_aff, pair> add(const typed::multi_pw_aff, pair> &multi2) const; + inline typed::multi_union_pw_aff, pair> add(const typed::multi_union_pw_aff, pair> &multi2) const; + inline typed::pw_multi_aff, pair> add(const typed::pw_multi_aff, pair> &pma2) const; + inline typed::union_pw_multi_aff, pair> add(const typed::union_pw_multi_aff, pair> &upma2) const; + inline typed::pw_multi_aff, pair> add(const typed::multi_aff, pair> &pma2) const; + inline typed::pw_multi_aff, pair> add(const typed::pw_aff, pair> &pma2) const; + inline typed::pw_multi_aff, pair> add_constant(const typed::multi_val> &mv) const; + inline typed::pw_multi_aff, pair> add_constant(const typed::val> &v) const; + inline typed::pw_multi_aff, pair> add_constant(long v) const; + template + inline typed::union_pw_multi_aff, Arg2> apply(const typed::union_pw_multi_aff, Arg2> &upma2) const; + inline typed::map, pair> as_map() const; + inline typed::multi_aff, pair> as_multi_aff() const; + inline typed::multi_union_pw_aff, pair> as_multi_union_pw_aff() const; + inline typed::pw_multi_aff, pair> as_pw_multi_aff() const; + inline typed::set, pair> as_set() const = delete; + inline typed::union_map, pair> as_union_map() const; + inline typed::pw_aff, Anonymous> at(int pos) const; + inline typed::pw_aff, pair> get_at(int pos) const = delete; + inline typed::set> bind(const typed::multi_id> &tuple) const; + inline typed::pw_multi_aff> bind_domain(const typed::multi_id> &tuple) const; + inline typed::pw_multi_aff> bind_domain_wrapped_domain(const typed::multi_id &tuple) const; + inline typed::pw_multi_aff, pair> coalesce() const; + inline typed::set> domain() const; + inline typed::pw_multi_aff, pair> domain_reverse() const; + inline typed::pw_multi_aff, pair> drop_unused_params() const; + inline typed::pw_multi_aff, pair> extract_pw_multi_aff(const typed::space, pair> &space) const; + inline typed::pw_multi_aff, pair> gist(const typed::set> &set) const; + inline typed::union_pw_multi_aff, pair> gist(const typed::union_set> &context) const; + inline typed::pw_multi_aff, pair> gist(const typed::basic_set> &set) const; + inline typed::pw_multi_aff, pair> gist(const typed::point> &set) const; + inline typed::pw_multi_aff, pair> gist_params(const typed::set<> &set) const; + inline typed::pw_multi_aff, pair> gist_params(const typed::basic_set<> &set) const; + inline typed::pw_multi_aff, pair> gist_params(const typed::point<> &set) const; + inline typed::multi_pw_aff, pair> identity() const; + inline typed::pw_multi_aff, pair> insert_domain(const typed::space<> &domain) const = delete; + inline typed::pw_multi_aff, pair> intersect_domain(const typed::set> &set) const; + inline typed::union_pw_multi_aff, pair> intersect_domain(const typed::space> &space) const; + inline typed::union_pw_multi_aff, pair> intersect_domain(const typed::union_set> &uset) const; + inline typed::pw_multi_aff, pair> intersect_domain(const typed::basic_set> &set) const; + inline typed::pw_multi_aff, pair> intersect_domain(const typed::point> &set) const; + inline typed::union_pw_multi_aff, pair> intersect_domain_wrapped_domain(const typed::union_set &uset) const; + inline typed::pw_multi_aff, pair> intersect_params(const typed::set<> &set) const; + inline typed::pw_multi_aff, pair> intersect_params(const typed::basic_set<> &set) const; + inline typed::pw_multi_aff, pair> intersect_params(const typed::point<> &set) const; + inline typed::pw_aff_list, Anonymous> list() const; + inline typed::multi_pw_aff, pair> max(const typed::multi_pw_aff, pair> &multi2) const; + inline typed::multi_val> max_multi_val() const; + inline typed::multi_pw_aff, pair> min(const typed::multi_pw_aff, pair> &multi2) const; + inline typed::multi_val> min_multi_val() const; + inline typed::multi_pw_aff, pair> neg() const; + template + inline typed::pw_multi_aff, pair> preimage_domain_wrapped_domain(const typed::pw_multi_aff &pma2) const; + template + inline typed::union_pw_multi_aff, pair> preimage_domain_wrapped_domain(const typed::union_pw_multi_aff &upma2) const; + template + inline typed::pw_multi_aff, pair> preimage_domain_wrapped_domain(const typed::multi_aff &pma2) const; + template + inline typed::pw_multi_aff, pair> preimage_domain_wrapped_domain(const typed::pw_aff &pma2) const; + template + inline typed::multi_pw_aff, Domain2>, pair, Arg2>> product(const typed::multi_pw_aff &multi2) const; + template + inline typed::pw_multi_aff, Domain2>, pair, Arg2>> product(const typed::pw_multi_aff &pma2) const; + template + inline typed::pw_multi_aff, Domain2>, pair, Arg2>> product(const typed::multi_aff &pma2) const; + template + inline typed::pw_multi_aff, Domain2>, pair, Anonymous>> product(const typed::pw_aff &pma2) const; + template + inline typed::multi_pw_aff> pullback(const typed::multi_pw_aff> &mpa2) const; + inline typed::multi_pw_aff> pullback(const typed::multi_pw_aff> &mpa2) const; + template + inline typed::pw_multi_aff> pullback(const typed::multi_aff> &ma) const; + inline typed::pw_multi_aff> pullback(const typed::multi_aff> &ma) const; + template + inline typed::pw_multi_aff> pullback(const typed::pw_multi_aff> &pma2) const; + inline typed::pw_multi_aff> pullback(const typed::pw_multi_aff> &pma2) const; + template + inline typed::union_pw_multi_aff> pullback(const typed::union_pw_multi_aff> &upma2) const; + inline typed::union_pw_multi_aff> pullback(const typed::union_pw_multi_aff> &upma2) const; + inline typed::pw_multi_aff_list, pair> pw_multi_aff_list() const; + inline typed::pw_multi_aff, Range> range_factor_domain() const; + inline typed::pw_multi_aff, Range2> range_factor_range() const; + template + inline typed::multi_pw_aff, pair, Arg2>> range_product(const typed::multi_pw_aff, Arg2> &multi2) const; + template + inline typed::multi_union_pw_aff, pair, Arg2>> range_product(const typed::multi_union_pw_aff, Arg2> &multi2) const; + template + inline typed::pw_multi_aff, pair, Arg2>> range_product(const typed::pw_multi_aff, Arg2> &pma2) const; + template + inline typed::union_pw_multi_aff, pair, Arg2>> range_product(const typed::union_pw_multi_aff, Arg2> &upma2) const; + template + inline typed::pw_multi_aff, pair, Arg2>> range_product(const typed::multi_aff, Arg2> &pma2) const; + inline typed::pw_multi_aff, pair, Anonymous>> range_product(const typed::pw_aff, Anonymous> &pma2) const; + inline typed::id, pair> get_range_tuple_id() const = delete; + inline typed::pw_multi_aff, pair> scale(const typed::multi_val> &mv) const; + inline typed::pw_multi_aff, pair> scale(const typed::val> &v) const; + inline typed::pw_multi_aff, pair> scale(long v) const; + inline typed::pw_multi_aff, pair> scale_down(const typed::multi_val> &mv) const; + inline typed::pw_multi_aff, pair> scale_down(const typed::val> &v) const; + inline typed::pw_multi_aff, pair> scale_down(long v) const; + inline typed::multi_pw_aff, pair> set_at(int pos, const typed::pw_aff, Anonymous> &el) const; + inline typed::multi_union_pw_aff, pair> set_at(int pos, const typed::union_pw_aff, Anonymous> &el) const; + inline typed::pw_multi_aff, pair> set_range_tuple(const typed::id<> &id) const = delete; + inline typed::pw_multi_aff, pair> set_range_tuple(const std::string &id) const = delete; + inline typed::space, pair> space() const; + inline typed::space, pair> get_space() const = delete; + inline typed::multi_pw_aff, pair> sub(const typed::multi_pw_aff, pair> &multi2) const; + inline typed::multi_union_pw_aff, pair> sub(const typed::multi_union_pw_aff, pair> &multi2) const; + inline typed::pw_multi_aff, pair> sub(const typed::pw_multi_aff, pair> &pma2) const; + inline typed::union_pw_multi_aff, pair> sub(const typed::union_pw_multi_aff, pair> &upma2) const; + inline typed::pw_multi_aff, pair> sub(const typed::multi_aff, pair> &pma2) const; + inline typed::pw_multi_aff, pair> sub(const typed::pw_aff, pair> &pma2) const; + inline typed::pw_multi_aff, pair> subtract_domain(const typed::set> &set) const; + inline typed::union_pw_multi_aff, pair> subtract_domain(const typed::space> &space) const; + inline typed::union_pw_multi_aff, pair> subtract_domain(const typed::union_set> &uset) const; + inline typed::pw_multi_aff, pair> subtract_domain(const typed::basic_set> &set) const; + inline typed::pw_multi_aff, pair> subtract_domain(const typed::point> &set) const; + inline typed::multi_pw_aff, pair> to_multi_pw_aff() const; + inline typed::union_pw_multi_aff, pair> to_union_pw_multi_aff() const; + inline typed::multi_pw_aff, pair> unbind_params_insert_domain(const typed::multi_id<> &domain) const = delete; + inline typed::multi_pw_aff, pair> union_add(const typed::multi_pw_aff, pair> &mpa2) const; + inline typed::multi_union_pw_aff, pair> union_add(const typed::multi_union_pw_aff, pair> &mupa2) const; + inline typed::pw_multi_aff, pair> union_add(const typed::pw_multi_aff, pair> &pma2) const; + inline typed::union_pw_multi_aff, pair> union_add(const typed::union_pw_multi_aff, pair> &upma2) const; + inline typed::pw_multi_aff, pair> union_add(const typed::multi_aff, pair> &pma2) const; + inline typed::pw_multi_aff, pair> union_add(const typed::pw_aff, pair> &pma2) const; +}; + +template +struct pw_multi_aff_list : public isl::pw_multi_aff_list { + template + friend struct aff; + template + friend struct aff_list; + template + friend struct basic_map; + template + friend struct basic_set; + template + friend struct fixed_box; + template + friend struct id; + template + friend struct id_list; + template + friend struct map; + template + friend struct map_list; + template + friend struct multi_aff; + template + friend struct multi_id; + template + friend struct multi_pw_aff; + template + friend struct multi_union_pw_aff; + template + friend struct multi_val; + template + friend struct point; + template + friend struct pw_aff; + template + friend struct pw_aff_list; + template + friend struct pw_multi_aff; + template + friend struct pw_multi_aff_list; + template + friend struct set; + template + friend struct set_list; + template + friend struct space; + template + friend struct union_map; + template + friend struct union_pw_aff; + template + friend struct union_pw_aff_list; + template + friend struct union_pw_multi_aff; + template + friend struct union_set; + template + friend struct union_set_list; + template + friend struct val; + template + friend struct val_list; + + pw_multi_aff_list() = default; + template {}, + bool>::type = true> + pw_multi_aff_list(const pw_multi_aff_list &obj) : isl::pw_multi_aff_list(obj) {} + private: + template {}, bool>::type = true> + pw_multi_aff_list(const base &obj) : isl::pw_multi_aff_list(obj) {} + public: + static pw_multi_aff_list from(const isl::pw_multi_aff_list &obj) { + return pw_multi_aff_list(obj); + } + inline explicit pw_multi_aff_list(const isl::ctx &ctx, int n); + inline explicit pw_multi_aff_list(const typed::pw_multi_aff &el); + inline explicit pw_multi_aff_list(const isl::ctx &ctx, const std::string &str); + inline typed::pw_multi_aff_list add(const typed::pw_multi_aff &el) const; + inline typed::pw_multi_aff_list add(const typed::multi_aff &el) const; + inline typed::pw_multi_aff_list add(const typed::pw_aff &el) const; + inline typed::pw_multi_aff at(int index) const; + inline typed::pw_multi_aff get_at(int index) const = delete; + inline typed::pw_multi_aff_list drop(unsigned int first, unsigned int n) const; + inline void foreach(const std::function)> &fn) const; + inline void foreach_scc(const std::function, typed::pw_multi_aff)> &follows, const std::function)> &fn) const; + inline typed::pw_multi_aff_list set_at(int index, const typed::pw_multi_aff &el) const; +}; + +template +struct pw_multi_aff_list : public isl::pw_multi_aff_list { + template + friend struct aff; + template + friend struct aff_list; + template + friend struct basic_map; + template + friend struct basic_set; + template + friend struct fixed_box; + template + friend struct id; + template + friend struct id_list; + template + friend struct map; + template + friend struct map_list; + template + friend struct multi_aff; + template + friend struct multi_id; + template + friend struct multi_pw_aff; + template + friend struct multi_union_pw_aff; + template + friend struct multi_val; + template + friend struct point; + template + friend struct pw_aff; + template + friend struct pw_aff_list; + template + friend struct pw_multi_aff; + template + friend struct pw_multi_aff_list; + template + friend struct set; + template + friend struct set_list; + template + friend struct space; + template + friend struct union_map; + template + friend struct union_pw_aff; + template + friend struct union_pw_aff_list; + template + friend struct union_pw_multi_aff; + template + friend struct union_set; + template + friend struct union_set_list; + template + friend struct val; + template + friend struct val_list; + + pw_multi_aff_list() = default; + template {} && + std::is_base_of{}, + bool>::type = true> + pw_multi_aff_list(const pw_multi_aff_list &obj) : isl::pw_multi_aff_list(obj) {} + private: + template {}, bool>::type = true> + pw_multi_aff_list(const base &obj) : isl::pw_multi_aff_list(obj) {} + public: + static pw_multi_aff_list from(const isl::pw_multi_aff_list &obj) { + return pw_multi_aff_list(obj); + } + inline explicit pw_multi_aff_list(const isl::ctx &ctx, int n); + inline explicit pw_multi_aff_list(const typed::pw_multi_aff &el); + inline explicit pw_multi_aff_list(const isl::ctx &ctx, const std::string &str); + inline typed::pw_multi_aff_list add(const typed::pw_multi_aff &el) const; + inline typed::pw_multi_aff_list add(const typed::multi_aff &el) const; + inline typed::pw_multi_aff_list add(const typed::pw_aff &el) const; + inline typed::pw_multi_aff at(int index) const; + inline typed::pw_multi_aff get_at(int index) const = delete; + inline typed::pw_multi_aff_list drop(unsigned int first, unsigned int n) const; + inline void foreach(const std::function)> &fn) const; + inline void foreach_scc(const std::function, typed::pw_multi_aff)> &follows, const std::function)> &fn) const; + inline typed::pw_multi_aff_list set_at(int index, const typed::pw_multi_aff &el) const; +}; + +template <> +struct set<> : public isl::set { + template + friend struct aff; + template + friend struct aff_list; + template + friend struct basic_map; + template + friend struct basic_set; + template + friend struct fixed_box; + template + friend struct id; + template + friend struct id_list; + template + friend struct map; + template + friend struct map_list; + template + friend struct multi_aff; + template + friend struct multi_id; + template + friend struct multi_pw_aff; + template + friend struct multi_union_pw_aff; + template + friend struct multi_val; + template + friend struct point; + template + friend struct pw_aff; + template + friend struct pw_aff_list; + template + friend struct pw_multi_aff; + template + friend struct pw_multi_aff_list; + template + friend struct set; + template + friend struct set_list; + template + friend struct space; + template + friend struct union_map; + template + friend struct union_pw_aff; + template + friend struct union_pw_aff_list; + template + friend struct union_pw_multi_aff; + template + friend struct union_set; + template + friend struct union_set_list; + template + friend struct val; + template + friend struct val_list; + + set() = default; + private: + template {}, bool>::type = true> + set(const base &obj) : isl::set(obj) {} + public: + static set from(const isl::set &obj) { + return set(obj); + } + inline /* implicit */ set(const typed::basic_set<> &bset); + inline /* implicit */ set(const typed::point<> &pnt); + inline explicit set(const isl::ctx &ctx, const std::string &str); + inline typed::set<> apply(const typed::map<> &map) const = delete; + inline typed::union_set<> apply(const typed::union_map<> &umap) const = delete; + inline typed::set<> apply(const typed::basic_map<> &map) const = delete; + inline typed::pw_multi_aff<> as_pw_multi_aff() const = delete; + inline typed::set<> as_set() const = delete; + inline typed::set<> bind(const typed::multi_id<> &tuple) const = delete; + inline typed::set<> coalesce() const; + inline typed::set<> detect_equalities() const; + inline typed::set<> drop_unused_params() const; + inline bool every_set(const std::function)> &test) const; + inline typed::set<> extract_set(const typed::space<> &space) const; + inline void foreach_basic_set(const std::function)> &fn) const; + inline void foreach_point(const std::function)> &fn) const; + inline void foreach_set(const std::function)> &fn) const; + inline typed::set<> gist(const typed::set<> &context) const; + inline typed::union_set<> gist(const typed::union_set<> &context) const; + inline typed::set<> gist(const typed::basic_set<> &context) const; + inline typed::set<> gist(const typed::point<> &context) const; + inline typed::set<> gist_params(const typed::set<> &context) const = delete; + inline typed::set<> gist_params(const typed::basic_set<> &context) const = delete; + inline typed::set<> gist_params(const typed::point<> &context) const = delete; + inline typed::map<> identity() const = delete; + inline typed::pw_aff indicator_function() const; + inline typed::map<> insert_domain(const typed::space<> &domain) const = delete; + inline typed::set<> intersect(const typed::set<> &set2) const; + inline typed::union_set<> intersect(const typed::union_set<> &uset2) const; + inline typed::set<> intersect(const typed::basic_set<> &set2) const; + inline typed::set<> intersect(const typed::point<> &set2) const; + inline typed::set<> intersect_params(const typed::set<> ¶ms) const = delete; + inline typed::set<> intersect_params(const typed::basic_set<> ¶ms) const = delete; + inline typed::set<> intersect_params(const typed::point<> ¶ms) const = delete; + inline typed::fixed_box<> lattice_tile() const = delete; + inline typed::fixed_box<> get_lattice_tile() const = delete; + inline typed::set<> lexmax() const = delete; + inline typed::pw_multi_aff<> lexmax_pw_multi_aff() const = delete; + inline typed::set<> lexmin() const = delete; + inline typed::pw_multi_aff<> lexmin_pw_multi_aff() const = delete; + inline typed::set<> lower_bound(const typed::multi_pw_aff<> &lower) const = delete; + inline typed::set<> lower_bound(const typed::multi_val<> &lower) const = delete; + inline typed::multi_pw_aff<> max_multi_pw_aff() const = delete; + inline typed::val<> max_val(const typed::aff<> &obj) const = delete; + inline typed::multi_pw_aff<> min_multi_pw_aff() const = delete; + inline typed::val<> min_val(const typed::aff<> &obj) const = delete; + inline typed::pw_aff param_pw_aff_on_domain(const typed::id &id) const; + inline typed::pw_aff param_pw_aff_on_domain(const std::string &id) const; + inline typed::set<> params() const = delete; + inline typed::multi_val<> plain_multi_val_if_fixed() const = delete; + inline typed::multi_val<> get_plain_multi_val_if_fixed() const = delete; + inline typed::set<> preimage(const typed::multi_aff<> &ma) const = delete; + inline typed::set<> preimage(const typed::multi_pw_aff<> &mpa) const = delete; + inline typed::set<> preimage(const typed::pw_multi_aff<> &pma) const = delete; + inline typed::union_set<> preimage(const typed::union_pw_multi_aff<> &upma) const = delete; + inline typed::set<> product(const typed::set<> &set2) const = delete; + inline typed::set<> product(const typed::basic_set<> &set2) const = delete; + inline typed::set<> product(const typed::point<> &set2) const = delete; + inline typed::set<> project_out_all_params() const; + inline typed::set<> project_out_param(const typed::id &id) const; + inline typed::set<> project_out_param(const std::string &id) const; + inline typed::set<> project_out_param(const typed::id_list &list) const; + inline typed::pw_aff pw_aff_on_domain(const typed::val &v) const; + inline typed::pw_aff pw_aff_on_domain(long v) const; + template + inline typed::pw_multi_aff pw_multi_aff_on_domain(const typed::multi_val &mv) const; + inline typed::set_list<> set_list() const; + inline typed::fixed_box<> simple_fixed_box_hull() const = delete; + inline typed::fixed_box<> get_simple_fixed_box_hull() const = delete; + inline typed::space<> space() const; + inline typed::space<> get_space() const = delete; + inline typed::val<> get_stride(int pos) const = delete; + inline typed::set<> subtract(const typed::set<> &set2) const; + inline typed::union_set<> subtract(const typed::union_set<> &uset2) const; + inline typed::set<> subtract(const typed::basic_set<> &set2) const; + inline typed::set<> subtract(const typed::point<> &set2) const; + inline typed::union_set<> to_union_set() const; + inline typed::map<> translation() const = delete; + template + inline typed::set unbind_params(const typed::multi_id &tuple) const; + inline typed::map<> unbind_params_insert_domain(const typed::multi_id<> &domain) const = delete; + inline typed::set<> unite(const typed::set<> &set2) const; + inline typed::union_set<> unite(const typed::union_set<> &uset2) const; + inline typed::set<> unite(const typed::basic_set<> &set2) const; + inline typed::set<> unite(const typed::point<> &set2) const; + static inline typed::set<> universe(const typed::space<> &space); + inline typed::map<> unwrap() const = delete; + inline typed::set<> upper_bound(const typed::multi_pw_aff<> &upper) const = delete; + inline typed::set<> upper_bound(const typed::multi_val<> &upper) const = delete; + inline typed::set<> wrapped_reverse() const = delete; +}; + +template +struct set : public isl::set { + template + friend struct aff; + template + friend struct aff_list; + template + friend struct basic_map; + template + friend struct basic_set; + template + friend struct fixed_box; + template + friend struct id; + template + friend struct id_list; + template + friend struct map; + template + friend struct map_list; + template + friend struct multi_aff; + template + friend struct multi_id; + template + friend struct multi_pw_aff; + template + friend struct multi_union_pw_aff; + template + friend struct multi_val; + template + friend struct point; + template + friend struct pw_aff; + template + friend struct pw_aff_list; + template + friend struct pw_multi_aff; + template + friend struct pw_multi_aff_list; + template + friend struct set; + template + friend struct set_list; + template + friend struct space; + template + friend struct union_map; + template + friend struct union_pw_aff; + template + friend struct union_pw_aff_list; + template + friend struct union_pw_multi_aff; + template + friend struct union_set; + template + friend struct union_set_list; + template + friend struct val; + template + friend struct val_list; + + set() = default; + template {}, + bool>::type = true> + set(const set &obj) : isl::set(obj) {} + private: + template {}, bool>::type = true> + set(const base &obj) : isl::set(obj) {} + public: + static set from(const isl::set &obj) { + return set(obj); + } + inline /* implicit */ set(const typed::basic_set &bset); + inline /* implicit */ set(const typed::point &pnt); + inline explicit set(const isl::ctx &ctx, const std::string &str); + template + inline typed::set apply(const typed::map &map) const; + template + inline typed::union_set apply(const typed::union_map &umap) const; + template + inline typed::set apply(const typed::basic_map &map) const; + inline typed::pw_multi_aff as_pw_multi_aff() const; + inline typed::set as_set() const; + inline typed::set<> bind(const typed::multi_id &tuple) const; + inline typed::set coalesce() const; + inline typed::set detect_equalities() const; + inline typed::set drop_unused_params() const; + inline bool every_set(const std::function)> &test) const; + inline typed::set extract_set(const typed::space &space) const; + inline void foreach_basic_set(const std::function)> &fn) const; + inline void foreach_point(const std::function)> &fn) const; + inline void foreach_set(const std::function)> &fn) const; + inline typed::set gist(const typed::set &context) const; + inline typed::union_set gist(const typed::union_set &context) const; + inline typed::set gist(const typed::basic_set &context) const; + inline typed::set gist(const typed::point &context) const; + inline typed::set gist_params(const typed::set<> &context) const; + inline typed::set gist_params(const typed::basic_set<> &context) const; + inline typed::set gist_params(const typed::point<> &context) const; + inline typed::map identity() const; + inline typed::pw_aff indicator_function() const; + template + inline typed::map insert_domain(const typed::space &domain) const; + inline typed::set intersect(const typed::set &set2) const; + inline typed::union_set intersect(const typed::union_set &uset2) const; + inline typed::set intersect(const typed::basic_set &set2) const; + inline typed::set intersect(const typed::point &set2) const; + inline typed::set intersect_params(const typed::set<> ¶ms) const; + inline typed::set intersect_params(const typed::basic_set<> ¶ms) const; + inline typed::set intersect_params(const typed::point<> ¶ms) const; + inline typed::fixed_box lattice_tile() const; + inline typed::fixed_box get_lattice_tile() const = delete; + inline typed::set lexmax() const; + inline typed::pw_multi_aff lexmax_pw_multi_aff() const; + inline typed::set lexmin() const; + inline typed::pw_multi_aff lexmin_pw_multi_aff() const; + inline typed::set lower_bound(const typed::multi_pw_aff &lower) const; + inline typed::set lower_bound(const typed::multi_val &lower) const; + inline typed::multi_pw_aff max_multi_pw_aff() const; + inline typed::val max_val(const typed::aff<> &obj) const = delete; + inline typed::multi_pw_aff min_multi_pw_aff() const; + inline typed::val min_val(const typed::aff<> &obj) const = delete; + inline typed::pw_aff param_pw_aff_on_domain(const typed::id &id) const; + inline typed::pw_aff param_pw_aff_on_domain(const std::string &id) const; + inline typed::set<> params() const; + inline typed::multi_val plain_multi_val_if_fixed() const; + inline typed::multi_val get_plain_multi_val_if_fixed() const = delete; + template + inline typed::set preimage(const typed::multi_aff &ma) const; + template + inline typed::set preimage(const typed::multi_pw_aff &mpa) const; + template + inline typed::set preimage(const typed::pw_multi_aff &pma) const; + template + inline typed::union_set preimage(const typed::union_pw_multi_aff &upma) const; + template + inline typed::set> product(const typed::set &set2) const; + template + inline typed::set> product(const typed::basic_set &set2) const; + template + inline typed::set> product(const typed::point &set2) const; + inline typed::set project_out_all_params() const; + inline typed::set project_out_param(const typed::id &id) const; + inline typed::set project_out_param(const std::string &id) const; + inline typed::set project_out_param(const typed::id_list &list) const; + inline typed::pw_aff pw_aff_on_domain(const typed::val &v) const; + inline typed::pw_aff pw_aff_on_domain(long v) const; + template + inline typed::pw_multi_aff pw_multi_aff_on_domain(const typed::multi_val &mv) const; + inline typed::set_list set_list() const; + inline typed::fixed_box simple_fixed_box_hull() const; + inline typed::fixed_box get_simple_fixed_box_hull() const = delete; + inline typed::space space() const; + inline typed::space get_space() const = delete; + inline typed::val get_stride(int pos) const = delete; + inline typed::set subtract(const typed::set &set2) const; + inline typed::union_set subtract(const typed::union_set &uset2) const; + inline typed::set subtract(const typed::basic_set &set2) const; + inline typed::set subtract(const typed::point &set2) const; + inline typed::union_set to_union_set() const; + inline typed::map translation() const; + inline typed::set unbind_params(const typed::multi_id<> &tuple) const = delete; + template + inline typed::map unbind_params_insert_domain(const typed::multi_id &domain) const; + inline typed::set unite(const typed::set &set2) const; + inline typed::union_set unite(const typed::union_set &uset2) const; + inline typed::set unite(const typed::basic_set &set2) const; + inline typed::set unite(const typed::point &set2) const; + static inline typed::set universe(const typed::space &space); + inline typed::map unwrap() const = delete; + inline typed::set upper_bound(const typed::multi_pw_aff &upper) const; + inline typed::set upper_bound(const typed::multi_val &upper) const; + inline typed::set wrapped_reverse() const = delete; +}; + +template +struct set> : public isl::set { + template + friend struct aff; + template + friend struct aff_list; + template + friend struct basic_map; + template + friend struct basic_set; + template + friend struct fixed_box; + template + friend struct id; + template + friend struct id_list; + template + friend struct map; + template + friend struct map_list; + template + friend struct multi_aff; + template + friend struct multi_id; + template + friend struct multi_pw_aff; + template + friend struct multi_union_pw_aff; + template + friend struct multi_val; + template + friend struct point; + template + friend struct pw_aff; + template + friend struct pw_aff_list; + template + friend struct pw_multi_aff; + template + friend struct pw_multi_aff_list; + template + friend struct set; + template + friend struct set_list; + template + friend struct space; + template + friend struct union_map; + template + friend struct union_pw_aff; + template + friend struct union_pw_aff_list; + template + friend struct union_pw_multi_aff; + template + friend struct union_set; + template + friend struct union_set_list; + template + friend struct val; + template + friend struct val_list; + + set() = default; + template {} && + std::is_base_of{}, + bool>::type = true> + set(const set> &obj) : isl::set(obj) {} + private: + template {}, bool>::type = true> + set(const base &obj) : isl::set(obj) {} + public: + static set from(const isl::set &obj) { + return set(obj); + } + inline /* implicit */ set(const typed::basic_set> &bset); + inline /* implicit */ set(const typed::point> &pnt); + inline explicit set(const isl::ctx &ctx, const std::string &str); + template + inline typed::set apply(const typed::map, Arg2> &map) const; + template + inline typed::union_set apply(const typed::union_map, Arg2> &umap) const; + template + inline typed::set apply(const typed::basic_map, Arg2> &map) const; + inline typed::pw_multi_aff> as_pw_multi_aff() const; + inline typed::set> as_set() const; + inline typed::set<> bind(const typed::multi_id> &tuple) const; + inline typed::set> coalesce() const; + inline typed::set> detect_equalities() const; + inline typed::set> drop_unused_params() const; + inline bool every_set(const std::function>)> &test) const; + inline typed::set> extract_set(const typed::space> &space) const; + inline void foreach_basic_set(const std::function>)> &fn) const; + inline void foreach_point(const std::function>)> &fn) const; + inline void foreach_set(const std::function>)> &fn) const; + inline typed::set> gist(const typed::set> &context) const; + inline typed::union_set> gist(const typed::union_set> &context) const; + inline typed::set> gist(const typed::basic_set> &context) const; + inline typed::set> gist(const typed::point> &context) const; + inline typed::set> gist_params(const typed::set<> &context) const; + inline typed::set> gist_params(const typed::basic_set<> &context) const; + inline typed::set> gist_params(const typed::point<> &context) const; + inline typed::map, pair> identity() const; + inline typed::pw_aff, Anonymous> indicator_function() const; + template + inline typed::map> insert_domain(const typed::space &domain) const; + inline typed::set> intersect(const typed::set> &set2) const; + inline typed::union_set> intersect(const typed::union_set> &uset2) const; + inline typed::set> intersect(const typed::basic_set> &set2) const; + inline typed::set> intersect(const typed::point> &set2) const; + inline typed::set> intersect_params(const typed::set<> ¶ms) const; + inline typed::set> intersect_params(const typed::basic_set<> ¶ms) const; + inline typed::set> intersect_params(const typed::point<> ¶ms) const; + inline typed::fixed_box> lattice_tile() const; + inline typed::fixed_box> get_lattice_tile() const = delete; + inline typed::set> lexmax() const; + inline typed::pw_multi_aff> lexmax_pw_multi_aff() const; + inline typed::set> lexmin() const; + inline typed::pw_multi_aff> lexmin_pw_multi_aff() const; + inline typed::set> lower_bound(const typed::multi_pw_aff> &lower) const; + inline typed::set> lower_bound(const typed::multi_val> &lower) const; + inline typed::multi_pw_aff> max_multi_pw_aff() const; + inline typed::val> max_val(const typed::aff<> &obj) const = delete; + inline typed::multi_pw_aff> min_multi_pw_aff() const; + inline typed::val> min_val(const typed::aff<> &obj) const = delete; + inline typed::pw_aff, Anonymous> param_pw_aff_on_domain(const typed::id &id) const; + inline typed::pw_aff, Anonymous> param_pw_aff_on_domain(const std::string &id) const; + inline typed::set<> params() const; + inline typed::multi_val> plain_multi_val_if_fixed() const; + inline typed::multi_val> get_plain_multi_val_if_fixed() const = delete; + template + inline typed::set preimage(const typed::multi_aff> &ma) const; + template + inline typed::set preimage(const typed::multi_pw_aff> &mpa) const; + template + inline typed::set preimage(const typed::pw_multi_aff> &pma) const; + template + inline typed::union_set preimage(const typed::union_pw_multi_aff> &upma) const; + template + inline typed::set, Arg2>> product(const typed::set &set2) const; + template + inline typed::set, Arg2>> product(const typed::basic_set &set2) const; + template + inline typed::set, Arg2>> product(const typed::point &set2) const; + inline typed::set> project_out_all_params() const; + inline typed::set> project_out_param(const typed::id &id) const; + inline typed::set> project_out_param(const std::string &id) const; + inline typed::set> project_out_param(const typed::id_list &list) const; + inline typed::pw_aff, Anonymous> pw_aff_on_domain(const typed::val &v) const; + inline typed::pw_aff, Anonymous> pw_aff_on_domain(long v) const; + template + inline typed::pw_multi_aff, Arg2> pw_multi_aff_on_domain(const typed::multi_val &mv) const; + inline typed::set_list> set_list() const; + inline typed::fixed_box> simple_fixed_box_hull() const; + inline typed::fixed_box> get_simple_fixed_box_hull() const = delete; + inline typed::space> space() const; + inline typed::space> get_space() const = delete; + inline typed::val> get_stride(int pos) const = delete; + inline typed::set> subtract(const typed::set> &set2) const; + inline typed::union_set> subtract(const typed::union_set> &uset2) const; + inline typed::set> subtract(const typed::basic_set> &set2) const; + inline typed::set> subtract(const typed::point> &set2) const; + inline typed::union_set> to_union_set() const; + inline typed::map, pair> translation() const; + inline typed::set> unbind_params(const typed::multi_id<> &tuple) const = delete; + template + inline typed::map> unbind_params_insert_domain(const typed::multi_id &domain) const; + inline typed::set> unite(const typed::set> &set2) const; + inline typed::union_set> unite(const typed::union_set> &uset2) const; + inline typed::set> unite(const typed::basic_set> &set2) const; + inline typed::set> unite(const typed::point> &set2) const; + static inline typed::set> universe(const typed::space> &space); + inline typed::map unwrap() const; + inline typed::set> upper_bound(const typed::multi_pw_aff> &upper) const; + inline typed::set> upper_bound(const typed::multi_val> &upper) const; + inline typed::set> wrapped_reverse() const; +}; + +template <> +struct set_list<> : public isl::set_list { + template + friend struct aff; + template + friend struct aff_list; + template + friend struct basic_map; + template + friend struct basic_set; + template + friend struct fixed_box; + template + friend struct id; + template + friend struct id_list; + template + friend struct map; + template + friend struct map_list; + template + friend struct multi_aff; + template + friend struct multi_id; + template + friend struct multi_pw_aff; + template + friend struct multi_union_pw_aff; + template + friend struct multi_val; + template + friend struct point; + template + friend struct pw_aff; + template + friend struct pw_aff_list; + template + friend struct pw_multi_aff; + template + friend struct pw_multi_aff_list; + template + friend struct set; + template + friend struct set_list; + template + friend struct space; + template + friend struct union_map; + template + friend struct union_pw_aff; + template + friend struct union_pw_aff_list; + template + friend struct union_pw_multi_aff; + template + friend struct union_set; + template + friend struct union_set_list; + template + friend struct val; + template + friend struct val_list; + + set_list() = default; + private: + template {}, bool>::type = true> + set_list(const base &obj) : isl::set_list(obj) {} + public: + static set_list from(const isl::set_list &obj) { + return set_list(obj); + } + inline explicit set_list(const isl::ctx &ctx, int n); + inline explicit set_list(const typed::set<> &el); + inline explicit set_list(const isl::ctx &ctx, const std::string &str); + inline typed::set_list<> add(const typed::set<> &el) const; + inline typed::set_list<> add(const typed::basic_set<> &el) const; + inline typed::set_list<> add(const typed::point<> &el) const; + inline typed::set<> at(int index) const = delete; + inline typed::set<> get_at(int index) const = delete; + inline typed::set_list<> drop(unsigned int first, unsigned int n) const; + inline void foreach(const std::function)> &fn) const; + inline void foreach_scc(const std::function, typed::set<>)> &follows, const std::function)> &fn) const; + inline typed::set_list<> set_at(int index, const typed::set<> &el) const = delete; +}; + +template +struct set_list : public isl::set_list { + template + friend struct aff; + template + friend struct aff_list; + template + friend struct basic_map; + template + friend struct basic_set; + template + friend struct fixed_box; + template + friend struct id; + template + friend struct id_list; + template + friend struct map; + template + friend struct map_list; + template + friend struct multi_aff; + template + friend struct multi_id; + template + friend struct multi_pw_aff; + template + friend struct multi_union_pw_aff; + template + friend struct multi_val; + template + friend struct point; + template + friend struct pw_aff; + template + friend struct pw_aff_list; + template + friend struct pw_multi_aff; + template + friend struct pw_multi_aff_list; + template + friend struct set; + template + friend struct set_list; + template + friend struct space; + template + friend struct union_map; + template + friend struct union_pw_aff; + template + friend struct union_pw_aff_list; + template + friend struct union_pw_multi_aff; + template + friend struct union_set; + template + friend struct union_set_list; + template + friend struct val; + template + friend struct val_list; + + set_list() = default; + template {}, + bool>::type = true> + set_list(const set_list &obj) : isl::set_list(obj) {} + private: + template {}, bool>::type = true> + set_list(const base &obj) : isl::set_list(obj) {} + public: + static set_list from(const isl::set_list &obj) { + return set_list(obj); + } + inline explicit set_list(const isl::ctx &ctx, int n); + inline explicit set_list(const typed::set &el); + inline explicit set_list(const isl::ctx &ctx, const std::string &str); + inline typed::set_list add(const typed::set &el) const; + inline typed::set_list add(const typed::basic_set &el) const; + inline typed::set_list add(const typed::point &el) const; + inline typed::set at(int index) const; + inline typed::set get_at(int index) const = delete; + inline typed::set_list drop(unsigned int first, unsigned int n) const; + inline void foreach(const std::function)> &fn) const; + inline void foreach_scc(const std::function, typed::set)> &follows, const std::function)> &fn) const; + inline typed::set_list set_at(int index, const typed::set &el) const; +}; + +template <> +struct space<> : public isl::space { + template + friend struct aff; + template + friend struct aff_list; + template + friend struct basic_map; + template + friend struct basic_set; + template + friend struct fixed_box; + template + friend struct id; + template + friend struct id_list; + template + friend struct map; + template + friend struct map_list; + template + friend struct multi_aff; + template + friend struct multi_id; + template + friend struct multi_pw_aff; + template + friend struct multi_union_pw_aff; + template + friend struct multi_val; + template + friend struct point; + template + friend struct pw_aff; + template + friend struct pw_aff_list; + template + friend struct pw_multi_aff; + template + friend struct pw_multi_aff_list; + template + friend struct set; + template + friend struct set_list; + template + friend struct space; + template + friend struct union_map; + template + friend struct union_pw_aff; + template + friend struct union_pw_aff_list; + template + friend struct union_pw_multi_aff; + template + friend struct union_set; + template + friend struct union_set_list; + template + friend struct val; + template + friend struct val_list; + + space() = default; + private: + template {}, bool>::type = true> + space(const base &obj) : isl::space(obj) {} + public: + static space from(const isl::space &obj) { + return space(obj); + } + inline explicit space(const isl::ctx &ctx, const std::string &str); + template + inline typed::space add_named_tuple(const typed::id &tuple_id, unsigned int dim) const; + template + inline typed::space add_named_tuple(const std::string &tuple_id, unsigned int dim) const; + inline typed::space<> add_param(const typed::id &id) const; + inline typed::space<> add_param(const std::string &id) const; + template + inline typed::space add_unnamed_tuple(unsigned int dim) const; + inline typed::space<> curry() const = delete; + inline typed::space<> domain() const = delete; + inline typed::multi_aff<> domain_map_multi_aff() const = delete; + inline typed::pw_multi_aff<> domain_map_pw_multi_aff() const = delete; + inline typed::space<> domain_reverse() const = delete; + inline typed::id<> get_domain_tuple_id() const = delete; + inline typed::space<> drop_all_params() const; + inline typed::space<> flatten_domain() const = delete; + inline typed::space<> flatten_range() const = delete; + inline typed::multi_aff<> identity_multi_aff_on_domain() const = delete; + inline typed::multi_pw_aff<> identity_multi_pw_aff_on_domain() const = delete; + inline typed::pw_multi_aff<> identity_pw_multi_aff_on_domain() const = delete; + inline typed::space<> map_from_set() const = delete; + inline typed::multi_aff<> multi_aff(const typed::aff_list<> &list) const = delete; + template + inline typed::multi_aff multi_aff_on_domain(const typed::multi_val &mv) const; + inline typed::multi_id<> multi_id(const typed::id_list<> &list) const = delete; + inline typed::multi_pw_aff<> multi_pw_aff(const typed::pw_aff_list<> &list) const = delete; + inline typed::multi_union_pw_aff<> multi_union_pw_aff(const typed::union_pw_aff_list<> &list) const = delete; + inline typed::multi_val<> multi_val(const typed::val_list<> &list) const = delete; + inline typed::aff param_aff_on_domain(const typed::id &id) const; + inline typed::aff param_aff_on_domain(const std::string &id) const; + inline typed::space<> params() const = delete; + inline typed::space<> product(const typed::space<> &right) const = delete; + inline typed::space<> range() const = delete; + inline typed::multi_aff<> range_map_multi_aff() const = delete; + inline typed::pw_multi_aff<> range_map_pw_multi_aff() const = delete; + inline typed::space<> range_reverse() const = delete; + inline typed::id<> get_range_tuple_id() const = delete; + inline typed::space<> reverse() const = delete; + inline typed::space<> set_domain_tuple(const typed::id<> &id) const = delete; + inline typed::space<> set_domain_tuple(const std::string &id) const = delete; + inline typed::space<> set_range_tuple(const typed::id<> &id) const = delete; + inline typed::space<> set_range_tuple(const std::string &id) const = delete; + inline typed::space<> uncurry() const = delete; + static inline typed::space<> unit(const isl::ctx &ctx); + inline typed::map<> universe_map() const = delete; + inline typed::set<> universe_set() const; + inline typed::space<> unwrap() const = delete; + inline typed::space<> wrap() const = delete; + inline typed::space<> wrapped_reverse() const = delete; + inline typed::aff<> zero_aff_on_domain() const = delete; + inline typed::multi_aff<> zero_multi_aff() const = delete; + inline typed::multi_pw_aff<> zero_multi_pw_aff() const = delete; + inline typed::multi_union_pw_aff<> zero_multi_union_pw_aff() const = delete; + inline typed::multi_val<> zero_multi_val() const = delete; +}; + +template +struct space : public isl::space { + template + friend struct aff; + template + friend struct aff_list; + template + friend struct basic_map; + template + friend struct basic_set; + template + friend struct fixed_box; + template + friend struct id; + template + friend struct id_list; + template + friend struct map; + template + friend struct map_list; + template + friend struct multi_aff; + template + friend struct multi_id; + template + friend struct multi_pw_aff; + template + friend struct multi_union_pw_aff; + template + friend struct multi_val; + template + friend struct point; + template + friend struct pw_aff; + template + friend struct pw_aff_list; + template + friend struct pw_multi_aff; + template + friend struct pw_multi_aff_list; + template + friend struct set; + template + friend struct set_list; + template + friend struct space; + template + friend struct union_map; + template + friend struct union_pw_aff; + template + friend struct union_pw_aff_list; + template + friend struct union_pw_multi_aff; + template + friend struct union_set; + template + friend struct union_set_list; + template + friend struct val; + template + friend struct val_list; + + space() = default; + template {}, + bool>::type = true> + space(const space &obj) : isl::space(obj) {} + private: + template {}, bool>::type = true> + space(const base &obj) : isl::space(obj) {} + public: + static space from(const isl::space &obj) { + return space(obj); + } + inline explicit space(const isl::ctx &ctx, const std::string &str); + template + inline typed::space add_named_tuple(const typed::id &tuple_id, unsigned int dim) const; + template + inline typed::space add_named_tuple(const std::string &tuple_id, unsigned int dim) const; + inline typed::space add_param(const typed::id &id) const; + inline typed::space add_param(const std::string &id) const; + template + inline typed::space add_unnamed_tuple(unsigned int dim) const; + inline typed::space curry() const = delete; + inline typed::space<> domain() const; + inline typed::multi_aff domain_map_multi_aff() const = delete; + inline typed::pw_multi_aff domain_map_pw_multi_aff() const = delete; + inline typed::space domain_reverse() const = delete; + inline typed::id get_domain_tuple_id() const = delete; + inline typed::space drop_all_params() const; + inline typed::space flatten_domain() const = delete; + inline typed::space flatten_range() const = delete; + inline typed::multi_aff identity_multi_aff_on_domain() const; + inline typed::multi_pw_aff identity_multi_pw_aff_on_domain() const; + inline typed::pw_multi_aff identity_pw_multi_aff_on_domain() const; + inline typed::space map_from_set() const; + inline typed::multi_aff multi_aff(const typed::aff_list &list) const; + template + inline typed::multi_aff multi_aff_on_domain(const typed::multi_val &mv) const; + inline typed::multi_id multi_id(const typed::id_list &list) const; + inline typed::multi_pw_aff multi_pw_aff(const typed::pw_aff_list &list) const; + inline typed::multi_union_pw_aff multi_union_pw_aff(const typed::union_pw_aff_list &list) const; + template + inline typed::multi_union_pw_aff multi_union_pw_aff(const typed::union_pw_aff_list &list) const; + inline typed::multi_val multi_val(const typed::val_list &list) const; + inline typed::aff param_aff_on_domain(const typed::id &id) const; + inline typed::aff param_aff_on_domain(const std::string &id) const; + inline typed::space<> params() const; + template + inline typed::space> product(const typed::space &right) const; + inline typed::space range() const = delete; + inline typed::multi_aff range_map_multi_aff() const = delete; + inline typed::pw_multi_aff range_map_pw_multi_aff() const = delete; + inline typed::space range_reverse() const = delete; + inline typed::id get_range_tuple_id() const = delete; + inline typed::space reverse() const = delete; + inline typed::space set_domain_tuple(const typed::id<> &id) const = delete; + inline typed::space set_domain_tuple(const std::string &id) const = delete; + template + inline typed::space set_range_tuple(const typed::id &id) const; + template + inline typed::space set_range_tuple(const std::string &id) const; + inline typed::space uncurry() const = delete; + static inline typed::space unit(const isl::ctx &ctx) = delete; + inline typed::map universe_map() const = delete; + inline typed::set universe_set() const; + inline typed::space unwrap() const = delete; + inline typed::space wrap() const = delete; + inline typed::space wrapped_reverse() const = delete; + inline typed::aff zero_aff_on_domain() const; + inline typed::multi_aff zero_multi_aff() const; + inline typed::multi_pw_aff zero_multi_pw_aff() const; + inline typed::multi_union_pw_aff zero_multi_union_pw_aff() const; + inline typed::multi_val zero_multi_val() const; +}; + +template +struct space : public isl::space { + template + friend struct aff; + template + friend struct aff_list; + template + friend struct basic_map; + template + friend struct basic_set; + template + friend struct fixed_box; + template + friend struct id; + template + friend struct id_list; + template + friend struct map; + template + friend struct map_list; + template + friend struct multi_aff; + template + friend struct multi_id; + template + friend struct multi_pw_aff; + template + friend struct multi_union_pw_aff; + template + friend struct multi_val; + template + friend struct point; + template + friend struct pw_aff; + template + friend struct pw_aff_list; + template + friend struct pw_multi_aff; + template + friend struct pw_multi_aff_list; + template + friend struct set; + template + friend struct set_list; + template + friend struct space; + template + friend struct union_map; + template + friend struct union_pw_aff; + template + friend struct union_pw_aff_list; + template + friend struct union_pw_multi_aff; + template + friend struct union_set; + template + friend struct union_set_list; + template + friend struct val; + template + friend struct val_list; + + space() = default; + template {} && + std::is_base_of{}, + bool>::type = true> + space(const space &obj) : isl::space(obj) {} + private: + template {}, bool>::type = true> + space(const base &obj) : isl::space(obj) {} + public: + static space from(const isl::space &obj) { + return space(obj); + } + inline explicit space(const isl::ctx &ctx, const std::string &str); + inline typed::space add_named_tuple(const typed::id<> &tuple_id, unsigned int dim) const = delete; + inline typed::space add_named_tuple(const std::string &tuple_id, unsigned int dim) const = delete; + inline typed::space add_param(const typed::id &id) const; + inline typed::space add_param(const std::string &id) const; + inline typed::space add_unnamed_tuple(unsigned int dim) const = delete; + inline typed::space curry() const = delete; + inline typed::space domain() const; + inline typed::multi_aff, Domain> domain_map_multi_aff() const; + inline typed::pw_multi_aff, Domain> domain_map_pw_multi_aff() const; + inline typed::space domain_reverse() const = delete; + inline typed::id get_domain_tuple_id() const = delete; + inline typed::space drop_all_params() const; + inline typed::space flatten_domain() const = delete; + inline typed::space flatten_range() const = delete; + inline typed::multi_aff identity_multi_aff_on_domain() const = delete; + inline typed::multi_pw_aff identity_multi_pw_aff_on_domain() const = delete; + inline typed::pw_multi_aff identity_pw_multi_aff_on_domain() const = delete; + inline typed::space map_from_set() const = delete; + inline typed::multi_aff multi_aff(const typed::aff_list &list) const; + inline typed::multi_aff multi_aff_on_domain(const typed::multi_val<> &mv) const = delete; + inline typed::multi_id multi_id(const typed::id_list<> &list) const = delete; + inline typed::multi_pw_aff multi_pw_aff(const typed::pw_aff_list &list) const; + inline typed::multi_union_pw_aff multi_union_pw_aff(const typed::union_pw_aff_list<> &list) const = delete; + inline typed::multi_val multi_val(const typed::val_list<> &list) const = delete; + inline typed::aff param_aff_on_domain(const typed::id<> &id) const = delete; + inline typed::aff param_aff_on_domain(const std::string &id) const = delete; + inline typed::space<> params() const; + template + inline typed::space, pair> product(const typed::space &right) const; + inline typed::space range() const; + inline typed::multi_aff, Range> range_map_multi_aff() const; + inline typed::pw_multi_aff, Range> range_map_pw_multi_aff() const; + inline typed::space range_reverse() const = delete; + inline typed::id get_range_tuple_id() const = delete; + inline typed::space reverse() const; + template + inline typed::space set_domain_tuple(const typed::id &id) const; + template + inline typed::space set_domain_tuple(const std::string &id) const; + template + inline typed::space set_range_tuple(const typed::id &id) const; + template + inline typed::space set_range_tuple(const std::string &id) const; + inline typed::space uncurry() const = delete; + static inline typed::space unit(const isl::ctx &ctx) = delete; + inline typed::map universe_map() const; + inline typed::set universe_set() const = delete; + inline typed::space unwrap() const = delete; + inline typed::space> wrap() const; + inline typed::space wrapped_reverse() const = delete; + inline typed::aff zero_aff_on_domain() const = delete; + inline typed::multi_aff zero_multi_aff() const; + inline typed::multi_pw_aff zero_multi_pw_aff() const; + inline typed::multi_union_pw_aff zero_multi_union_pw_aff() const; + inline typed::multi_val zero_multi_val() const = delete; +}; + +template +struct space> : public isl::space { + template + friend struct aff; + template + friend struct aff_list; + template + friend struct basic_map; + template + friend struct basic_set; + template + friend struct fixed_box; + template + friend struct id; + template + friend struct id_list; + template + friend struct map; + template + friend struct map_list; + template + friend struct multi_aff; + template + friend struct multi_id; + template + friend struct multi_pw_aff; + template + friend struct multi_union_pw_aff; + template + friend struct multi_val; + template + friend struct point; + template + friend struct pw_aff; + template + friend struct pw_aff_list; + template + friend struct pw_multi_aff; + template + friend struct pw_multi_aff_list; + template + friend struct set; + template + friend struct set_list; + template + friend struct space; + template + friend struct union_map; + template + friend struct union_pw_aff; + template + friend struct union_pw_aff_list; + template + friend struct union_pw_multi_aff; + template + friend struct union_set; + template + friend struct union_set_list; + template + friend struct val; + template + friend struct val_list; + + space() = default; + template {} && + std::is_base_of{}, + bool>::type = true> + space(const space> &obj) : isl::space(obj) {} + private: + template {}, bool>::type = true> + space(const base &obj) : isl::space(obj) {} + public: + static space from(const isl::space &obj) { + return space(obj); + } + inline explicit space(const isl::ctx &ctx, const std::string &str); + template + inline typed::space, Arg2> add_named_tuple(const typed::id &tuple_id, unsigned int dim) const; + template + inline typed::space, Arg2> add_named_tuple(const std::string &tuple_id, unsigned int dim) const; + inline typed::space> add_param(const typed::id &id) const; + inline typed::space> add_param(const std::string &id) const; + template + inline typed::space, Arg2> add_unnamed_tuple(unsigned int dim) const; + inline typed::space> curry() const = delete; + inline typed::space<> domain() const; + inline typed::multi_aff> domain_map_multi_aff() const = delete; + inline typed::pw_multi_aff> domain_map_pw_multi_aff() const = delete; + inline typed::space> domain_reverse() const = delete; + inline typed::id> get_domain_tuple_id() const = delete; + inline typed::space> drop_all_params() const; + inline typed::space> flatten_domain() const = delete; + inline typed::space> flatten_range() const = delete; + inline typed::multi_aff, pair> identity_multi_aff_on_domain() const; + inline typed::multi_pw_aff, pair> identity_multi_pw_aff_on_domain() const; + inline typed::pw_multi_aff, pair> identity_pw_multi_aff_on_domain() const; + inline typed::space, pair> map_from_set() const; + inline typed::multi_aff> multi_aff(const typed::aff_list &list) const; + template + inline typed::multi_aff, Arg2> multi_aff_on_domain(const typed::multi_val &mv) const; + inline typed::multi_id> multi_id(const typed::id_list &list) const; + inline typed::multi_pw_aff> multi_pw_aff(const typed::pw_aff_list &list) const; + inline typed::multi_union_pw_aff> multi_union_pw_aff(const typed::union_pw_aff_list &list) const; + template + inline typed::multi_union_pw_aff> multi_union_pw_aff(const typed::union_pw_aff_list &list) const; + inline typed::multi_val> multi_val(const typed::val_list &list) const; + inline typed::aff, Anonymous> param_aff_on_domain(const typed::id &id) const; + inline typed::aff, Anonymous> param_aff_on_domain(const std::string &id) const; + inline typed::space<> params() const; + template + inline typed::space, Arg2>> product(const typed::space &right) const; + inline typed::space> range() const = delete; + inline typed::multi_aff> range_map_multi_aff() const = delete; + inline typed::pw_multi_aff> range_map_pw_multi_aff() const = delete; + inline typed::space> range_reverse() const = delete; + inline typed::id> get_range_tuple_id() const = delete; + inline typed::space> reverse() const = delete; + inline typed::space> set_domain_tuple(const typed::id<> &id) const = delete; + inline typed::space> set_domain_tuple(const std::string &id) const = delete; + inline typed::space> set_range_tuple(const typed::id<> &id) const = delete; + inline typed::space> set_range_tuple(const std::string &id) const = delete; + inline typed::space> uncurry() const = delete; + static inline typed::space> unit(const isl::ctx &ctx) = delete; + inline typed::map> universe_map() const = delete; + inline typed::set> universe_set() const; + inline typed::space unwrap() const; + inline typed::space> wrap() const = delete; + inline typed::space> wrapped_reverse() const; + inline typed::aff, Anonymous> zero_aff_on_domain() const; + inline typed::multi_aff> zero_multi_aff() const; + inline typed::multi_pw_aff> zero_multi_pw_aff() const; + inline typed::multi_union_pw_aff> zero_multi_union_pw_aff() const; + inline typed::multi_val> zero_multi_val() const; +}; + +template +struct space, Range2> : public isl::space { + template + friend struct aff; + template + friend struct aff_list; + template + friend struct basic_map; + template + friend struct basic_set; + template + friend struct fixed_box; + template + friend struct id; + template + friend struct id_list; + template + friend struct map; + template + friend struct map_list; + template + friend struct multi_aff; + template + friend struct multi_id; + template + friend struct multi_pw_aff; + template + friend struct multi_union_pw_aff; + template + friend struct multi_val; + template + friend struct point; + template + friend struct pw_aff; + template + friend struct pw_aff_list; + template + friend struct pw_multi_aff; + template + friend struct pw_multi_aff_list; + template + friend struct set; + template + friend struct set_list; + template + friend struct space; + template + friend struct union_map; + template + friend struct union_pw_aff; + template + friend struct union_pw_aff_list; + template + friend struct union_pw_multi_aff; + template + friend struct union_set; + template + friend struct union_set_list; + template + friend struct val; + template + friend struct val_list; + + space() = default; + template {} && + std::is_base_of{} && + std::is_base_of{}, + bool>::type = true> + space(const space, Arg3> &obj) : isl::space(obj) {} + private: + template {}, bool>::type = true> + space(const base &obj) : isl::space(obj) {} + public: + static space from(const isl::space &obj) { + return space(obj); + } + inline explicit space(const isl::ctx &ctx, const std::string &str); + inline typed::space, Range2> add_named_tuple(const typed::id<> &tuple_id, unsigned int dim) const = delete; + inline typed::space, Range2> add_named_tuple(const std::string &tuple_id, unsigned int dim) const = delete; + inline typed::space, Range2> add_param(const typed::id &id) const; + inline typed::space, Range2> add_param(const std::string &id) const; + inline typed::space, Range2> add_unnamed_tuple(unsigned int dim) const = delete; + inline typed::space> curry() const; + inline typed::space> domain() const; + inline typed::multi_aff, Range2>, pair> domain_map_multi_aff() const; + inline typed::pw_multi_aff, Range2>, pair> domain_map_pw_multi_aff() const; + inline typed::space, Range2> domain_reverse() const; + inline typed::id, Range2> get_domain_tuple_id() const = delete; + inline typed::space, Range2> drop_all_params() const; + inline typed::space flatten_domain() const; + inline typed::space, Range2> flatten_range() const = delete; + inline typed::multi_aff, Range2> identity_multi_aff_on_domain() const = delete; + inline typed::multi_pw_aff, Range2> identity_multi_pw_aff_on_domain() const = delete; + inline typed::pw_multi_aff, Range2> identity_pw_multi_aff_on_domain() const = delete; + inline typed::space, Range2> map_from_set() const = delete; + inline typed::multi_aff, Range2> multi_aff(const typed::aff_list, Anonymous> &list) const; + inline typed::multi_aff, Range2> multi_aff_on_domain(const typed::multi_val<> &mv) const = delete; + inline typed::multi_id, Range2> multi_id(const typed::id_list<> &list) const = delete; + inline typed::multi_pw_aff, Range2> multi_pw_aff(const typed::pw_aff_list, Anonymous> &list) const; + inline typed::multi_union_pw_aff, Range2> multi_union_pw_aff(const typed::union_pw_aff_list<> &list) const = delete; + inline typed::multi_val, Range2> multi_val(const typed::val_list<> &list) const = delete; + inline typed::aff, Range2> param_aff_on_domain(const typed::id<> &id) const = delete; + inline typed::aff, Range2> param_aff_on_domain(const std::string &id) const = delete; + inline typed::space<> params() const; + template + inline typed::space, Domain2>, pair> product(const typed::space &right) const; + inline typed::space range() const; + inline typed::multi_aff, Range2>, Range2> range_map_multi_aff() const; + inline typed::pw_multi_aff, Range2>, Range2> range_map_pw_multi_aff() const; + inline typed::space, Range2> range_reverse() const = delete; + inline typed::id, Range2> get_range_tuple_id() const = delete; + inline typed::space> reverse() const; + inline typed::space, Range2> set_domain_tuple(const typed::id<> &id) const = delete; + inline typed::space, Range2> set_domain_tuple(const std::string &id) const = delete; + template + inline typed::space, Arg2> set_range_tuple(const typed::id &id) const; + template + inline typed::space, Arg2> set_range_tuple(const std::string &id) const; + inline typed::space, Range2> uncurry() const = delete; + static inline typed::space, Range2> unit(const isl::ctx &ctx) = delete; + inline typed::map, Range2> universe_map() const; + inline typed::set, Range2> universe_set() const = delete; + inline typed::space, Range2> unwrap() const = delete; + inline typed::space, Range2>> wrap() const; + inline typed::space, Range2> wrapped_reverse() const = delete; + inline typed::aff, Range2> zero_aff_on_domain() const = delete; + inline typed::multi_aff, Range2> zero_multi_aff() const; + inline typed::multi_pw_aff, Range2> zero_multi_pw_aff() const; + inline typed::multi_union_pw_aff, Range2> zero_multi_union_pw_aff() const; + inline typed::multi_val, Range2> zero_multi_val() const = delete; +}; + +template +struct space> : public isl::space { + template + friend struct aff; + template + friend struct aff_list; + template + friend struct basic_map; + template + friend struct basic_set; + template + friend struct fixed_box; + template + friend struct id; + template + friend struct id_list; + template + friend struct map; + template + friend struct map_list; + template + friend struct multi_aff; + template + friend struct multi_id; + template + friend struct multi_pw_aff; + template + friend struct multi_union_pw_aff; + template + friend struct multi_val; + template + friend struct point; + template + friend struct pw_aff; + template + friend struct pw_aff_list; + template + friend struct pw_multi_aff; + template + friend struct pw_multi_aff_list; + template + friend struct set; + template + friend struct set_list; + template + friend struct space; + template + friend struct union_map; + template + friend struct union_pw_aff; + template + friend struct union_pw_aff_list; + template + friend struct union_pw_multi_aff; + template + friend struct union_set; + template + friend struct union_set_list; + template + friend struct val; + template + friend struct val_list; + + space() = default; + template {} && + std::is_base_of{} && + std::is_base_of{}, + bool>::type = true> + space(const space> &obj) : isl::space(obj) {} + private: + template {}, bool>::type = true> + space(const base &obj) : isl::space(obj) {} + public: + static space from(const isl::space &obj) { + return space(obj); + } + inline explicit space(const isl::ctx &ctx, const std::string &str); + inline typed::space> add_named_tuple(const typed::id<> &tuple_id, unsigned int dim) const = delete; + inline typed::space> add_named_tuple(const std::string &tuple_id, unsigned int dim) const = delete; + inline typed::space> add_param(const typed::id &id) const; + inline typed::space> add_param(const std::string &id) const; + inline typed::space> add_unnamed_tuple(unsigned int dim) const = delete; + inline typed::space> curry() const = delete; + inline typed::space domain() const; + inline typed::multi_aff>, Domain> domain_map_multi_aff() const; + inline typed::pw_multi_aff>, Domain> domain_map_pw_multi_aff() const; + inline typed::space> domain_reverse() const = delete; + inline typed::id> get_domain_tuple_id() const = delete; + inline typed::space> drop_all_params() const; + inline typed::space> flatten_domain() const = delete; + inline typed::space flatten_range() const; + inline typed::multi_aff> identity_multi_aff_on_domain() const = delete; + inline typed::multi_pw_aff> identity_multi_pw_aff_on_domain() const = delete; + inline typed::pw_multi_aff> identity_pw_multi_aff_on_domain() const = delete; + inline typed::space> map_from_set() const = delete; + inline typed::multi_aff> multi_aff(const typed::aff_list &list) const; + inline typed::multi_aff> multi_aff_on_domain(const typed::multi_val<> &mv) const = delete; + inline typed::multi_id> multi_id(const typed::id_list<> &list) const = delete; + inline typed::multi_pw_aff> multi_pw_aff(const typed::pw_aff_list &list) const; + inline typed::multi_union_pw_aff> multi_union_pw_aff(const typed::union_pw_aff_list<> &list) const = delete; + inline typed::multi_val> multi_val(const typed::val_list<> &list) const = delete; + inline typed::aff> param_aff_on_domain(const typed::id<> &id) const = delete; + inline typed::aff> param_aff_on_domain(const std::string &id) const = delete; + inline typed::space<> params() const; + template + inline typed::space, pair, Arg3>> product(const typed::space &right) const; + inline typed::space> range() const; + inline typed::multi_aff>, pair> range_map_multi_aff() const; + inline typed::pw_multi_aff>, pair> range_map_pw_multi_aff() const; + inline typed::space> range_reverse() const; + inline typed::id> get_range_tuple_id() const = delete; + inline typed::space, Domain> reverse() const; + template + inline typed::space> set_domain_tuple(const typed::id &id) const; + template + inline typed::space> set_domain_tuple(const std::string &id) const; + inline typed::space> set_range_tuple(const typed::id<> &id) const = delete; + inline typed::space> set_range_tuple(const std::string &id) const = delete; + inline typed::space, Range2> uncurry() const; + static inline typed::space> unit(const isl::ctx &ctx) = delete; + inline typed::map> universe_map() const; + inline typed::set> universe_set() const = delete; + inline typed::space> unwrap() const = delete; + inline typed::space>> wrap() const; + inline typed::space> wrapped_reverse() const = delete; + inline typed::aff> zero_aff_on_domain() const = delete; + inline typed::multi_aff> zero_multi_aff() const; + inline typed::multi_pw_aff> zero_multi_pw_aff() const; + inline typed::multi_union_pw_aff> zero_multi_union_pw_aff() const; + inline typed::multi_val> zero_multi_val() const = delete; +}; + +template +struct space, pair> : public isl::space { + template + friend struct aff; + template + friend struct aff_list; + template + friend struct basic_map; + template + friend struct basic_set; + template + friend struct fixed_box; + template + friend struct id; + template + friend struct id_list; + template + friend struct map; + template + friend struct map_list; + template + friend struct multi_aff; + template + friend struct multi_id; + template + friend struct multi_pw_aff; + template + friend struct multi_union_pw_aff; + template + friend struct multi_val; + template + friend struct point; + template + friend struct pw_aff; + template + friend struct pw_aff_list; + template + friend struct pw_multi_aff; + template + friend struct pw_multi_aff_list; + template + friend struct set; + template + friend struct set_list; + template + friend struct space; + template + friend struct union_map; + template + friend struct union_pw_aff; + template + friend struct union_pw_aff_list; + template + friend struct union_pw_multi_aff; + template + friend struct union_set; + template + friend struct union_set_list; + template + friend struct val; + template + friend struct val_list; + + space() = default; + template {} && + std::is_base_of{} && + std::is_base_of{} && + std::is_base_of{}, + bool>::type = true> + space(const space, pair> &obj) : isl::space(obj) {} + private: + template {}, bool>::type = true> + space(const base &obj) : isl::space(obj) {} + public: + static space from(const isl::space &obj) { + return space(obj); + } + inline explicit space(const isl::ctx &ctx, const std::string &str); + inline typed::space, pair> add_named_tuple(const typed::id<> &tuple_id, unsigned int dim) const = delete; + inline typed::space, pair> add_named_tuple(const std::string &tuple_id, unsigned int dim) const = delete; + inline typed::space, pair> add_param(const typed::id &id) const; + inline typed::space, pair> add_param(const std::string &id) const; + inline typed::space, pair> add_unnamed_tuple(unsigned int dim) const = delete; + inline typed::space>> curry() const; + inline typed::space> domain() const; + inline typed::multi_aff, pair>, pair> domain_map_multi_aff() const; + inline typed::pw_multi_aff, pair>, pair> domain_map_pw_multi_aff() const; + inline typed::space, pair> domain_reverse() const; + inline typed::id, pair> get_domain_tuple_id() const = delete; + inline typed::space, pair> drop_all_params() const; + inline typed::space> flatten_domain() const; + inline typed::space, Anonymous> flatten_range() const; + inline typed::multi_aff, pair> identity_multi_aff_on_domain() const = delete; + inline typed::multi_pw_aff, pair> identity_multi_pw_aff_on_domain() const = delete; + inline typed::pw_multi_aff, pair> identity_pw_multi_aff_on_domain() const = delete; + inline typed::space, pair> map_from_set() const = delete; + inline typed::multi_aff, pair> multi_aff(const typed::aff_list, Anonymous> &list) const; + inline typed::multi_aff, pair> multi_aff_on_domain(const typed::multi_val<> &mv) const = delete; + inline typed::multi_id, pair> multi_id(const typed::id_list<> &list) const = delete; + inline typed::multi_pw_aff, pair> multi_pw_aff(const typed::pw_aff_list, Anonymous> &list) const; + inline typed::multi_union_pw_aff, pair> multi_union_pw_aff(const typed::union_pw_aff_list<> &list) const = delete; + inline typed::multi_val, pair> multi_val(const typed::val_list<> &list) const = delete; + inline typed::aff, pair> param_aff_on_domain(const typed::id<> &id) const = delete; + inline typed::aff, pair> param_aff_on_domain(const std::string &id) const = delete; + inline typed::space<> params() const; + template + inline typed::space, Domain2>, pair, Arg2>> product(const typed::space &right) const; + inline typed::space> range() const; + inline typed::multi_aff, pair>, pair> range_map_multi_aff() const; + inline typed::pw_multi_aff, pair>, pair> range_map_pw_multi_aff() const; + inline typed::space, pair> range_reverse() const; + inline typed::id, pair> get_range_tuple_id() const = delete; + inline typed::space, pair> reverse() const; + inline typed::space, pair> set_domain_tuple(const typed::id<> &id) const = delete; + inline typed::space, pair> set_domain_tuple(const std::string &id) const = delete; + inline typed::space, pair> set_range_tuple(const typed::id<> &id) const = delete; + inline typed::space, pair> set_range_tuple(const std::string &id) const = delete; + inline typed::space, Range>, Range2> uncurry() const; + static inline typed::space, pair> unit(const isl::ctx &ctx) = delete; + inline typed::map, pair> universe_map() const; + inline typed::set, pair> universe_set() const = delete; + inline typed::space, pair> unwrap() const = delete; + inline typed::space, pair>> wrap() const; + inline typed::space, pair> wrapped_reverse() const = delete; + inline typed::aff, pair> zero_aff_on_domain() const = delete; + inline typed::multi_aff, pair> zero_multi_aff() const; + inline typed::multi_pw_aff, pair> zero_multi_pw_aff() const; + inline typed::multi_union_pw_aff, pair> zero_multi_union_pw_aff() const; + inline typed::multi_val, pair> zero_multi_val() const = delete; +}; + +template +struct union_map : public isl::union_map { + template + friend struct aff; + template + friend struct aff_list; + template + friend struct basic_map; + template + friend struct basic_set; + template + friend struct fixed_box; + template + friend struct id; + template + friend struct id_list; + template + friend struct map; + template + friend struct map_list; + template + friend struct multi_aff; + template + friend struct multi_id; + template + friend struct multi_pw_aff; + template + friend struct multi_union_pw_aff; + template + friend struct multi_val; + template + friend struct point; + template + friend struct pw_aff; + template + friend struct pw_aff_list; + template + friend struct pw_multi_aff; + template + friend struct pw_multi_aff_list; + template + friend struct set; + template + friend struct set_list; + template + friend struct space; + template + friend struct union_map; + template + friend struct union_pw_aff; + template + friend struct union_pw_aff_list; + template + friend struct union_pw_multi_aff; + template + friend struct union_set; + template + friend struct union_set_list; + template + friend struct val; + template + friend struct val_list; + + union_map() = default; + template {} && + std::is_base_of{}, + bool>::type = true> + union_map(const union_map &obj) : isl::union_map(obj) {} + private: + template {}, bool>::type = true> + union_map(const base &obj) : isl::union_map(obj) {} + public: + static union_map from(const isl::union_map &obj) { + return union_map(obj); + } + inline /* implicit */ union_map(const typed::basic_map &bmap); + inline /* implicit */ union_map(const typed::map &map); + inline explicit union_map(const isl::ctx &ctx, const std::string &str); + template + inline typed::union_map apply_domain(const typed::union_map &umap2) const; + template + inline typed::union_map apply_domain(const typed::basic_map &umap2) const; + template + inline typed::union_map apply_domain(const typed::map &umap2) const; + template + inline typed::union_map apply_range(const typed::union_map &umap2) const; + template + inline typed::union_map apply_range(const typed::basic_map &umap2) const; + template + inline typed::union_map apply_range(const typed::map &umap2) const; + inline typed::map as_map() const; + inline typed::multi_union_pw_aff as_multi_union_pw_aff() const; + inline typed::union_pw_multi_aff as_union_pw_multi_aff() const; + inline typed::union_set bind_range(const typed::multi_id &tuple) const; + inline typed::union_map coalesce() const; + inline typed::union_map curry() const = delete; + inline typed::union_set deltas() const = delete; + inline typed::union_map detect_equalities() const; + inline typed::union_set domain() const; + inline typed::union_map domain_factor_domain() const = delete; + inline typed::union_map domain_factor_range() const = delete; + inline typed::union_map, Domain> domain_map() const; + inline typed::union_pw_multi_aff, Domain> domain_map_union_pw_multi_aff() const; + template + inline typed::union_map, Range> domain_product(const typed::union_map &umap2) const; + template + inline typed::union_map, Range> domain_product(const typed::basic_map &umap2) const; + template + inline typed::union_map, Range> domain_product(const typed::map &umap2) const; + inline typed::union_map domain_reverse() const = delete; + inline typed::union_map drop_unused_params() const; + static inline typed::union_map empty(const isl::ctx &ctx); + inline typed::union_map eq_at(const typed::multi_union_pw_aff<> &mupa) const = delete; + inline typed::union_map eq_at(const typed::multi_pw_aff<> &mupa) const = delete; + inline typed::union_map eq_at(const typed::union_pw_aff<> &mupa) const = delete; + inline bool every_map(const std::function)> &test) const; + inline typed::map extract_map(const typed::space &space) const; + inline void foreach_map(const std::function)> &fn) const; + inline typed::union_map gist(const typed::union_map &context) const; + inline typed::union_map gist(const typed::basic_map &context) const; + inline typed::union_map gist(const typed::map &context) const; + inline typed::union_map gist_domain(const typed::union_set &uset) const; + inline typed::union_map gist_domain(const typed::basic_set &uset) const; + inline typed::union_map gist_domain(const typed::point &uset) const; + inline typed::union_map gist_domain(const typed::set &uset) const; + inline typed::union_map gist_params(const typed::set<> &set) const; + inline typed::union_map gist_params(const typed::basic_set<> &set) const; + inline typed::union_map gist_params(const typed::point<> &set) const; + inline typed::union_map intersect(const typed::union_map &umap2) const; + inline typed::union_map intersect(const typed::basic_map &umap2) const; + inline typed::union_map intersect(const typed::map &umap2) const; + inline typed::union_map intersect_domain(const typed::space &space) const; + inline typed::union_map intersect_domain(const typed::union_set &uset) const; + inline typed::union_map intersect_domain_wrapped_domain(const typed::union_set<> &domain) const = delete; + inline typed::union_map intersect_domain_wrapped_domain(const typed::basic_set<> &domain) const = delete; + inline typed::union_map intersect_domain_wrapped_domain(const typed::point<> &domain) const = delete; + inline typed::union_map intersect_domain_wrapped_domain(const typed::set<> &domain) const = delete; + inline typed::union_map intersect_params(const typed::set<> &set) const; + inline typed::union_map intersect_params(const typed::basic_set<> &set) const; + inline typed::union_map intersect_params(const typed::point<> &set) const; + inline typed::union_map intersect_range(const typed::space &space) const; + inline typed::union_map intersect_range(const typed::union_set &uset) const; + inline typed::union_map intersect_range_wrapped_domain(const typed::union_set<> &domain) const = delete; + inline typed::union_map intersect_range_wrapped_domain(const typed::basic_set<> &domain) const = delete; + inline typed::union_map intersect_range_wrapped_domain(const typed::point<> &domain) const = delete; + inline typed::union_map intersect_range_wrapped_domain(const typed::set<> &domain) const = delete; + inline typed::union_map lexmax() const; + inline typed::union_map lexmin() const; + inline typed::map_list map_list() const; + inline typed::map_list get_map_list() const = delete; + inline typed::set<> params() const; + template + inline typed::union_map preimage_domain(const typed::multi_aff &ma) const; + template + inline typed::union_map preimage_domain(const typed::multi_pw_aff &mpa) const; + template + inline typed::union_map preimage_domain(const typed::pw_multi_aff &pma) const; + template + inline typed::union_map preimage_domain(const typed::union_pw_multi_aff &upma) const; + template + inline typed::union_map preimage_range(const typed::multi_aff &ma) const; + template + inline typed::union_map preimage_range(const typed::pw_multi_aff &pma) const; + template + inline typed::union_map preimage_range(const typed::union_pw_multi_aff &upma) const; + template + inline typed::union_map, pair> product(const typed::union_map &umap2) const; + template + inline typed::union_map, pair> product(const typed::basic_map &umap2) const; + template + inline typed::union_map, pair> product(const typed::map &umap2) const; + inline typed::union_map project_out_all_params() const; + inline typed::union_map project_out_param(const typed::id &id) const; + inline typed::union_map project_out_param(const std::string &id) const; + inline typed::union_map project_out_param(const typed::id_list &list) const; + inline typed::union_set range() const; + inline typed::union_map range_factor_domain() const = delete; + inline typed::union_map range_factor_range() const = delete; + inline typed::union_map, Range> range_map() const; + template + inline typed::union_map> range_product(const typed::union_map &umap2) const; + template + inline typed::union_map> range_product(const typed::basic_map &umap2) const; + template + inline typed::union_map> range_product(const typed::map &umap2) const; + inline typed::union_map range_reverse() const = delete; + inline typed::union_map reverse() const; + inline typed::space<> space() const; + inline typed::space get_space() const = delete; + inline typed::union_map subtract(const typed::union_map &umap2) const; + inline typed::union_map subtract(const typed::basic_map &umap2) const; + inline typed::union_map subtract(const typed::map &umap2) const; + inline typed::union_map subtract_domain(const typed::union_set &dom) const; + inline typed::union_map subtract_domain(const typed::basic_set &dom) const; + inline typed::union_map subtract_domain(const typed::point &dom) const; + inline typed::union_map subtract_domain(const typed::set &dom) const; + inline typed::union_map subtract_range(const typed::union_set &dom) const; + inline typed::union_map subtract_range(const typed::basic_set &dom) const; + inline typed::union_map subtract_range(const typed::point &dom) const; + inline typed::union_map subtract_range(const typed::set &dom) const; + inline typed::union_map uncurry() const = delete; + inline typed::union_map unite(const typed::union_map &umap2) const; + inline typed::union_map unite(const typed::basic_map &umap2) const; + inline typed::union_map unite(const typed::map &umap2) const; + inline typed::union_map universe() const; + inline typed::union_set> wrap() const; +}; + +template +struct union_map, Range2> : public isl::union_map { + template + friend struct aff; + template + friend struct aff_list; + template + friend struct basic_map; + template + friend struct basic_set; + template + friend struct fixed_box; + template + friend struct id; + template + friend struct id_list; + template + friend struct map; + template + friend struct map_list; + template + friend struct multi_aff; + template + friend struct multi_id; + template + friend struct multi_pw_aff; + template + friend struct multi_union_pw_aff; + template + friend struct multi_val; + template + friend struct point; + template + friend struct pw_aff; + template + friend struct pw_aff_list; + template + friend struct pw_multi_aff; + template + friend struct pw_multi_aff_list; + template + friend struct set; + template + friend struct set_list; + template + friend struct space; + template + friend struct union_map; + template + friend struct union_pw_aff; + template + friend struct union_pw_aff_list; + template + friend struct union_pw_multi_aff; + template + friend struct union_set; + template + friend struct union_set_list; + template + friend struct val; + template + friend struct val_list; + + union_map() = default; + template {} && + std::is_base_of{} && + std::is_base_of{}, + bool>::type = true> + union_map(const union_map, Arg3> &obj) : isl::union_map(obj) {} + private: + template {}, bool>::type = true> + union_map(const base &obj) : isl::union_map(obj) {} + public: + static union_map from(const isl::union_map &obj) { + return union_map(obj); + } + inline /* implicit */ union_map(const typed::basic_map, Range2> &bmap); + inline /* implicit */ union_map(const typed::map, Range2> &map); + inline explicit union_map(const isl::ctx &ctx, const std::string &str); + template + inline typed::union_map apply_domain(const typed::union_map, Domain2> &umap2) const; + template + inline typed::union_map apply_domain(const typed::basic_map, Domain2> &umap2) const; + template + inline typed::union_map apply_domain(const typed::map, Domain2> &umap2) const; + template + inline typed::union_map, Arg3> apply_range(const typed::union_map &umap2) const; + template + inline typed::union_map, Arg3> apply_range(const typed::basic_map &umap2) const; + template + inline typed::union_map, Arg3> apply_range(const typed::map &umap2) const; + inline typed::map, Range2> as_map() const; + inline typed::multi_union_pw_aff, Range2> as_multi_union_pw_aff() const; + inline typed::union_pw_multi_aff, Range2> as_union_pw_multi_aff() const; + inline typed::union_set> bind_range(const typed::multi_id &tuple) const; + inline typed::union_map, Range2> coalesce() const; + inline typed::union_map> curry() const; + inline typed::union_set, Range2> deltas() const = delete; + inline typed::union_map, Range2> detect_equalities() const; + inline typed::union_set> domain() const; + inline typed::union_map domain_factor_domain() const; + inline typed::union_map domain_factor_range() const; + inline typed::union_map, Range2>, pair> domain_map() const; + inline typed::union_pw_multi_aff, Range2>, pair> domain_map_union_pw_multi_aff() const; + template + inline typed::union_map, Domain2>, Range2> domain_product(const typed::union_map &umap2) const; + template + inline typed::union_map, Domain2>, Range2> domain_product(const typed::basic_map &umap2) const; + template + inline typed::union_map, Domain2>, Range2> domain_product(const typed::map &umap2) const; + inline typed::union_map, Range2> domain_reverse() const; + inline typed::union_map, Range2> drop_unused_params() const; + static inline typed::union_map, Range2> empty(const isl::ctx &ctx); + inline typed::union_map, Range2> eq_at(const typed::multi_union_pw_aff<> &mupa) const = delete; + inline typed::union_map, Range2> eq_at(const typed::multi_pw_aff<> &mupa) const = delete; + inline typed::union_map, Range2> eq_at(const typed::union_pw_aff<> &mupa) const = delete; + inline bool every_map(const std::function, Range2>)> &test) const; + inline typed::map, Range2> extract_map(const typed::space, Range2> &space) const; + inline void foreach_map(const std::function, Range2>)> &fn) const; + inline typed::union_map, Range2> gist(const typed::union_map, Range2> &context) const; + inline typed::union_map, Range2> gist(const typed::basic_map, Range2> &context) const; + inline typed::union_map, Range2> gist(const typed::map, Range2> &context) const; + inline typed::union_map, Range2> gist_domain(const typed::union_set> &uset) const; + inline typed::union_map, Range2> gist_domain(const typed::basic_set> &uset) const; + inline typed::union_map, Range2> gist_domain(const typed::point> &uset) const; + inline typed::union_map, Range2> gist_domain(const typed::set> &uset) const; + inline typed::union_map, Range2> gist_params(const typed::set<> &set) const; + inline typed::union_map, Range2> gist_params(const typed::basic_set<> &set) const; + inline typed::union_map, Range2> gist_params(const typed::point<> &set) const; + inline typed::union_map, Range2> intersect(const typed::union_map, Range2> &umap2) const; + inline typed::union_map, Range2> intersect(const typed::basic_map, Range2> &umap2) const; + inline typed::union_map, Range2> intersect(const typed::map, Range2> &umap2) const; + inline typed::union_map, Range2> intersect_domain(const typed::space> &space) const; + inline typed::union_map, Range2> intersect_domain(const typed::union_set> &uset) const; + inline typed::union_map, Range2> intersect_domain_wrapped_domain(const typed::union_set &domain) const; + inline typed::union_map, Range2> intersect_domain_wrapped_domain(const typed::basic_set &domain) const; + inline typed::union_map, Range2> intersect_domain_wrapped_domain(const typed::point &domain) const; + inline typed::union_map, Range2> intersect_domain_wrapped_domain(const typed::set &domain) const; + inline typed::union_map, Range2> intersect_params(const typed::set<> &set) const; + inline typed::union_map, Range2> intersect_params(const typed::basic_set<> &set) const; + inline typed::union_map, Range2> intersect_params(const typed::point<> &set) const; + inline typed::union_map, Range2> intersect_range(const typed::space &space) const; + inline typed::union_map, Range2> intersect_range(const typed::union_set &uset) const; + inline typed::union_map, Range2> intersect_range_wrapped_domain(const typed::union_set<> &domain) const = delete; + inline typed::union_map, Range2> intersect_range_wrapped_domain(const typed::basic_set<> &domain) const = delete; + inline typed::union_map, Range2> intersect_range_wrapped_domain(const typed::point<> &domain) const = delete; + inline typed::union_map, Range2> intersect_range_wrapped_domain(const typed::set<> &domain) const = delete; + inline typed::union_map, Range2> lexmax() const; + inline typed::union_map, Range2> lexmin() const; + inline typed::map_list, Range2> map_list() const; + inline typed::map_list, Range2> get_map_list() const = delete; + inline typed::set<> params() const; + template + inline typed::union_map preimage_domain(const typed::multi_aff> &ma) const; + template + inline typed::union_map preimage_domain(const typed::multi_pw_aff> &mpa) const; + template + inline typed::union_map preimage_domain(const typed::pw_multi_aff> &pma) const; + template + inline typed::union_map preimage_domain(const typed::union_pw_multi_aff> &upma) const; + template + inline typed::union_map, Arg3> preimage_range(const typed::multi_aff &ma) const; + template + inline typed::union_map, Arg3> preimage_range(const typed::pw_multi_aff &pma) const; + template + inline typed::union_map, Arg3> preimage_range(const typed::union_pw_multi_aff &upma) const; + template + inline typed::union_map, Domain2>, pair> product(const typed::union_map &umap2) const; + template + inline typed::union_map, Domain2>, pair> product(const typed::basic_map &umap2) const; + template + inline typed::union_map, Domain2>, pair> product(const typed::map &umap2) const; + inline typed::union_map, Range2> project_out_all_params() const; + inline typed::union_map, Range2> project_out_param(const typed::id &id) const; + inline typed::union_map, Range2> project_out_param(const std::string &id) const; + inline typed::union_map, Range2> project_out_param(const typed::id_list &list) const; + inline typed::union_set range() const; + inline typed::union_map, Range2> range_factor_domain() const = delete; + inline typed::union_map, Range2> range_factor_range() const = delete; + inline typed::union_map, Range2>, Range2> range_map() const; + template + inline typed::union_map, pair> range_product(const typed::union_map, Arg3> &umap2) const; + template + inline typed::union_map, pair> range_product(const typed::basic_map, Arg3> &umap2) const; + template + inline typed::union_map, pair> range_product(const typed::map, Arg3> &umap2) const; + inline typed::union_map, Range2> range_reverse() const = delete; + inline typed::union_map> reverse() const; + inline typed::space<> space() const; + inline typed::space, Range2> get_space() const = delete; + inline typed::union_map, Range2> subtract(const typed::union_map, Range2> &umap2) const; + inline typed::union_map, Range2> subtract(const typed::basic_map, Range2> &umap2) const; + inline typed::union_map, Range2> subtract(const typed::map, Range2> &umap2) const; + inline typed::union_map, Range2> subtract_domain(const typed::union_set> &dom) const; + inline typed::union_map, Range2> subtract_domain(const typed::basic_set> &dom) const; + inline typed::union_map, Range2> subtract_domain(const typed::point> &dom) const; + inline typed::union_map, Range2> subtract_domain(const typed::set> &dom) const; + inline typed::union_map, Range2> subtract_range(const typed::union_set &dom) const; + inline typed::union_map, Range2> subtract_range(const typed::basic_set &dom) const; + inline typed::union_map, Range2> subtract_range(const typed::point &dom) const; + inline typed::union_map, Range2> subtract_range(const typed::set &dom) const; + inline typed::union_map, Range2> uncurry() const = delete; + inline typed::union_map, Range2> unite(const typed::union_map, Range2> &umap2) const; + inline typed::union_map, Range2> unite(const typed::basic_map, Range2> &umap2) const; + inline typed::union_map, Range2> unite(const typed::map, Range2> &umap2) const; + inline typed::union_map, Range2> universe() const; + inline typed::union_set, Range2>> wrap() const; +}; + +template +struct union_map : public isl::union_map { + template + friend struct aff; + template + friend struct aff_list; + template + friend struct basic_map; + template + friend struct basic_set; + template + friend struct fixed_box; + template + friend struct id; + template + friend struct id_list; + template + friend struct map; + template + friend struct map_list; + template + friend struct multi_aff; + template + friend struct multi_id; + template + friend struct multi_pw_aff; + template + friend struct multi_union_pw_aff; + template + friend struct multi_val; + template + friend struct point; + template + friend struct pw_aff; + template + friend struct pw_aff_list; + template + friend struct pw_multi_aff; + template + friend struct pw_multi_aff_list; + template + friend struct set; + template + friend struct set_list; + template + friend struct space; + template + friend struct union_map; + template + friend struct union_pw_aff; + template + friend struct union_pw_aff_list; + template + friend struct union_pw_multi_aff; + template + friend struct union_set; + template + friend struct union_set_list; + template + friend struct val; + template + friend struct val_list; + + union_map() = default; + template {}, + bool>::type = true> + union_map(const union_map &obj) : isl::union_map(obj) {} + private: + template {}, bool>::type = true> + union_map(const base &obj) : isl::union_map(obj) {} + public: + static union_map from(const isl::union_map &obj) { + return union_map(obj); + } + inline /* implicit */ union_map(const typed::basic_map &bmap); + inline /* implicit */ union_map(const typed::map &map); + inline explicit union_map(const isl::ctx &ctx, const std::string &str); + template + inline typed::union_map apply_domain(const typed::union_map &umap2) const; + template + inline typed::union_map apply_domain(const typed::basic_map &umap2) const; + template + inline typed::union_map apply_domain(const typed::map &umap2) const; + template + inline typed::union_map apply_range(const typed::union_map &umap2) const; + template + inline typed::union_map apply_range(const typed::basic_map &umap2) const; + template + inline typed::union_map apply_range(const typed::map &umap2) const; + inline typed::map as_map() const; + inline typed::multi_union_pw_aff as_multi_union_pw_aff() const; + inline typed::union_pw_multi_aff as_union_pw_multi_aff() const; + inline typed::union_set bind_range(const typed::multi_id &tuple) const; + inline typed::union_map coalesce() const; + inline typed::union_map curry() const = delete; + inline typed::union_set deltas() const; + inline typed::union_map detect_equalities() const; + inline typed::union_set domain() const; + inline typed::union_map domain_factor_domain() const = delete; + inline typed::union_map domain_factor_range() const = delete; + inline typed::union_map, Domain> domain_map() const; + inline typed::union_pw_multi_aff, Domain> domain_map_union_pw_multi_aff() const; + template + inline typed::union_map, Domain> domain_product(const typed::union_map &umap2) const; + template + inline typed::union_map, Domain> domain_product(const typed::basic_map &umap2) const; + template + inline typed::union_map, Domain> domain_product(const typed::map &umap2) const; + inline typed::union_map domain_reverse() const = delete; + inline typed::union_map drop_unused_params() const; + static inline typed::union_map empty(const isl::ctx &ctx); + template + inline typed::union_map eq_at(const typed::multi_union_pw_aff &mupa) const; + template + inline typed::union_map eq_at(const typed::multi_pw_aff &mupa) const; + inline typed::union_map eq_at(const typed::union_pw_aff &mupa) const; + inline bool every_map(const std::function)> &test) const; + inline typed::map extract_map(const typed::space &space) const; + inline void foreach_map(const std::function)> &fn) const; + inline typed::union_map gist(const typed::union_map &context) const; + inline typed::union_map gist(const typed::basic_map &context) const; + inline typed::union_map gist(const typed::map &context) const; + inline typed::union_map gist_domain(const typed::union_set &uset) const; + inline typed::union_map gist_domain(const typed::basic_set &uset) const; + inline typed::union_map gist_domain(const typed::point &uset) const; + inline typed::union_map gist_domain(const typed::set &uset) const; + inline typed::union_map gist_params(const typed::set<> &set) const; + inline typed::union_map gist_params(const typed::basic_set<> &set) const; + inline typed::union_map gist_params(const typed::point<> &set) const; + inline typed::union_map intersect(const typed::union_map &umap2) const; + inline typed::union_map intersect(const typed::basic_map &umap2) const; + inline typed::union_map intersect(const typed::map &umap2) const; + inline typed::union_map intersect_domain(const typed::space &space) const; + inline typed::union_map intersect_domain(const typed::union_set &uset) const; + inline typed::union_map intersect_domain_wrapped_domain(const typed::union_set<> &domain) const = delete; + inline typed::union_map intersect_domain_wrapped_domain(const typed::basic_set<> &domain) const = delete; + inline typed::union_map intersect_domain_wrapped_domain(const typed::point<> &domain) const = delete; + inline typed::union_map intersect_domain_wrapped_domain(const typed::set<> &domain) const = delete; + inline typed::union_map intersect_params(const typed::set<> &set) const; + inline typed::union_map intersect_params(const typed::basic_set<> &set) const; + inline typed::union_map intersect_params(const typed::point<> &set) const; + inline typed::union_map intersect_range(const typed::space &space) const; + inline typed::union_map intersect_range(const typed::union_set &uset) const; + inline typed::union_map intersect_range_wrapped_domain(const typed::union_set<> &domain) const = delete; + inline typed::union_map intersect_range_wrapped_domain(const typed::basic_set<> &domain) const = delete; + inline typed::union_map intersect_range_wrapped_domain(const typed::point<> &domain) const = delete; + inline typed::union_map intersect_range_wrapped_domain(const typed::set<> &domain) const = delete; + inline typed::union_map lexmax() const; + inline typed::union_map lexmin() const; + inline typed::map_list map_list() const; + inline typed::map_list get_map_list() const = delete; + inline typed::set<> params() const; + template + inline typed::union_map preimage_domain(const typed::multi_aff &ma) const; + template + inline typed::union_map preimage_domain(const typed::multi_pw_aff &mpa) const; + template + inline typed::union_map preimage_domain(const typed::pw_multi_aff &pma) const; + template + inline typed::union_map preimage_domain(const typed::union_pw_multi_aff &upma) const; + template + inline typed::union_map preimage_range(const typed::multi_aff &ma) const; + template + inline typed::union_map preimage_range(const typed::pw_multi_aff &pma) const; + template + inline typed::union_map preimage_range(const typed::union_pw_multi_aff &upma) const; + template + inline typed::union_map, pair> product(const typed::union_map &umap2) const; + template + inline typed::union_map, pair> product(const typed::basic_map &umap2) const; + template + inline typed::union_map, pair> product(const typed::map &umap2) const; + inline typed::union_map project_out_all_params() const; + inline typed::union_map project_out_param(const typed::id &id) const; + inline typed::union_map project_out_param(const std::string &id) const; + inline typed::union_map project_out_param(const typed::id_list &list) const; + inline typed::union_set range() const; + inline typed::union_map range_factor_domain() const = delete; + inline typed::union_map range_factor_range() const = delete; + inline typed::union_map, Domain> range_map() const; + template + inline typed::union_map> range_product(const typed::union_map &umap2) const; + template + inline typed::union_map> range_product(const typed::basic_map &umap2) const; + template + inline typed::union_map> range_product(const typed::map &umap2) const; + inline typed::union_map range_reverse() const = delete; + inline typed::union_map reverse() const; + inline typed::space<> space() const; + inline typed::space get_space() const = delete; + inline typed::union_map subtract(const typed::union_map &umap2) const; + inline typed::union_map subtract(const typed::basic_map &umap2) const; + inline typed::union_map subtract(const typed::map &umap2) const; + inline typed::union_map subtract_domain(const typed::union_set &dom) const; + inline typed::union_map subtract_domain(const typed::basic_set &dom) const; + inline typed::union_map subtract_domain(const typed::point &dom) const; + inline typed::union_map subtract_domain(const typed::set &dom) const; + inline typed::union_map subtract_range(const typed::union_set &dom) const; + inline typed::union_map subtract_range(const typed::basic_set &dom) const; + inline typed::union_map subtract_range(const typed::point &dom) const; + inline typed::union_map subtract_range(const typed::set &dom) const; + inline typed::union_map uncurry() const = delete; + inline typed::union_map unite(const typed::union_map &umap2) const; + inline typed::union_map unite(const typed::basic_map &umap2) const; + inline typed::union_map unite(const typed::map &umap2) const; + inline typed::union_map universe() const; + inline typed::union_set> wrap() const; +}; + +template +struct union_map> : public isl::union_map { + template + friend struct aff; + template + friend struct aff_list; + template + friend struct basic_map; + template + friend struct basic_set; + template + friend struct fixed_box; + template + friend struct id; + template + friend struct id_list; + template + friend struct map; + template + friend struct map_list; + template + friend struct multi_aff; + template + friend struct multi_id; + template + friend struct multi_pw_aff; + template + friend struct multi_union_pw_aff; + template + friend struct multi_val; + template + friend struct point; + template + friend struct pw_aff; + template + friend struct pw_aff_list; + template + friend struct pw_multi_aff; + template + friend struct pw_multi_aff_list; + template + friend struct set; + template + friend struct set_list; + template + friend struct space; + template + friend struct union_map; + template + friend struct union_pw_aff; + template + friend struct union_pw_aff_list; + template + friend struct union_pw_multi_aff; + template + friend struct union_set; + template + friend struct union_set_list; + template + friend struct val; + template + friend struct val_list; + + union_map() = default; + template {} && + std::is_base_of{} && + std::is_base_of{}, + bool>::type = true> + union_map(const union_map> &obj) : isl::union_map(obj) {} + private: + template {}, bool>::type = true> + union_map(const base &obj) : isl::union_map(obj) {} + public: + static union_map from(const isl::union_map &obj) { + return union_map(obj); + } + inline /* implicit */ union_map(const typed::basic_map> &bmap); + inline /* implicit */ union_map(const typed::map> &map); + inline explicit union_map(const isl::ctx &ctx, const std::string &str); + template + inline typed::union_map> apply_domain(const typed::union_map &umap2) const; + template + inline typed::union_map> apply_domain(const typed::basic_map &umap2) const; + template + inline typed::union_map> apply_domain(const typed::map &umap2) const; + template + inline typed::union_map apply_range(const typed::union_map, Arg3> &umap2) const; + template + inline typed::union_map apply_range(const typed::basic_map, Arg3> &umap2) const; + template + inline typed::union_map apply_range(const typed::map, Arg3> &umap2) const; + inline typed::map> as_map() const; + inline typed::multi_union_pw_aff> as_multi_union_pw_aff() const; + inline typed::union_pw_multi_aff> as_union_pw_multi_aff() const; + inline typed::union_set bind_range(const typed::multi_id> &tuple) const; + inline typed::union_map> coalesce() const; + inline typed::union_map> curry() const = delete; + inline typed::union_set> deltas() const = delete; + inline typed::union_map> detect_equalities() const; + inline typed::union_set domain() const; + inline typed::union_map> domain_factor_domain() const = delete; + inline typed::union_map> domain_factor_range() const = delete; + inline typed::union_map>, Domain> domain_map() const; + inline typed::union_pw_multi_aff>, Domain> domain_map_union_pw_multi_aff() const; + template + inline typed::union_map, pair> domain_product(const typed::union_map> &umap2) const; + template + inline typed::union_map, pair> domain_product(const typed::basic_map> &umap2) const; + template + inline typed::union_map, pair> domain_product(const typed::map> &umap2) const; + inline typed::union_map> domain_reverse() const = delete; + inline typed::union_map> drop_unused_params() const; + static inline typed::union_map> empty(const isl::ctx &ctx); + inline typed::union_map> eq_at(const typed::multi_union_pw_aff<> &mupa) const = delete; + inline typed::union_map> eq_at(const typed::multi_pw_aff<> &mupa) const = delete; + inline typed::union_map> eq_at(const typed::union_pw_aff<> &mupa) const = delete; + inline bool every_map(const std::function>)> &test) const; + inline typed::map> extract_map(const typed::space> &space) const; + inline void foreach_map(const std::function>)> &fn) const; + inline typed::union_map> gist(const typed::union_map> &context) const; + inline typed::union_map> gist(const typed::basic_map> &context) const; + inline typed::union_map> gist(const typed::map> &context) const; + inline typed::union_map> gist_domain(const typed::union_set &uset) const; + inline typed::union_map> gist_domain(const typed::basic_set &uset) const; + inline typed::union_map> gist_domain(const typed::point &uset) const; + inline typed::union_map> gist_domain(const typed::set &uset) const; + inline typed::union_map> gist_params(const typed::set<> &set) const; + inline typed::union_map> gist_params(const typed::basic_set<> &set) const; + inline typed::union_map> gist_params(const typed::point<> &set) const; + inline typed::union_map> intersect(const typed::union_map> &umap2) const; + inline typed::union_map> intersect(const typed::basic_map> &umap2) const; + inline typed::union_map> intersect(const typed::map> &umap2) const; + inline typed::union_map> intersect_domain(const typed::space &space) const; + inline typed::union_map> intersect_domain(const typed::union_set &uset) const; + inline typed::union_map> intersect_domain_wrapped_domain(const typed::union_set<> &domain) const = delete; + inline typed::union_map> intersect_domain_wrapped_domain(const typed::basic_set<> &domain) const = delete; + inline typed::union_map> intersect_domain_wrapped_domain(const typed::point<> &domain) const = delete; + inline typed::union_map> intersect_domain_wrapped_domain(const typed::set<> &domain) const = delete; + inline typed::union_map> intersect_params(const typed::set<> &set) const; + inline typed::union_map> intersect_params(const typed::basic_set<> &set) const; + inline typed::union_map> intersect_params(const typed::point<> &set) const; + inline typed::union_map> intersect_range(const typed::space> &space) const; + inline typed::union_map> intersect_range(const typed::union_set> &uset) const; + inline typed::union_map> intersect_range_wrapped_domain(const typed::union_set &domain) const; + inline typed::union_map> intersect_range_wrapped_domain(const typed::basic_set &domain) const; + inline typed::union_map> intersect_range_wrapped_domain(const typed::point &domain) const; + inline typed::union_map> intersect_range_wrapped_domain(const typed::set &domain) const; + inline typed::union_map> lexmax() const; + inline typed::union_map> lexmin() const; + inline typed::map_list> map_list() const; + inline typed::map_list> get_map_list() const = delete; + inline typed::set<> params() const; + template + inline typed::union_map> preimage_domain(const typed::multi_aff &ma) const; + template + inline typed::union_map> preimage_domain(const typed::multi_pw_aff &mpa) const; + template + inline typed::union_map> preimage_domain(const typed::pw_multi_aff &pma) const; + template + inline typed::union_map> preimage_domain(const typed::union_pw_multi_aff &upma) const; + template + inline typed::union_map preimage_range(const typed::multi_aff> &ma) const; + template + inline typed::union_map preimage_range(const typed::pw_multi_aff> &pma) const; + template + inline typed::union_map preimage_range(const typed::union_pw_multi_aff> &upma) const; + template + inline typed::union_map, pair, Arg3>> product(const typed::union_map &umap2) const; + template + inline typed::union_map, pair, Arg3>> product(const typed::basic_map &umap2) const; + template + inline typed::union_map, pair, Arg3>> product(const typed::map &umap2) const; + inline typed::union_map> project_out_all_params() const; + inline typed::union_map> project_out_param(const typed::id &id) const; + inline typed::union_map> project_out_param(const std::string &id) const; + inline typed::union_map> project_out_param(const typed::id_list &list) const; + inline typed::union_set> range() const; + inline typed::union_map range_factor_domain() const; + inline typed::union_map range_factor_range() const; + inline typed::union_map>, pair> range_map() const; + template + inline typed::union_map, Arg3>> range_product(const typed::union_map &umap2) const; + template + inline typed::union_map, Arg3>> range_product(const typed::basic_map &umap2) const; + template + inline typed::union_map, Arg3>> range_product(const typed::map &umap2) const; + inline typed::union_map> range_reverse() const; + inline typed::union_map, Domain> reverse() const; + inline typed::space<> space() const; + inline typed::space> get_space() const = delete; + inline typed::union_map> subtract(const typed::union_map> &umap2) const; + inline typed::union_map> subtract(const typed::basic_map> &umap2) const; + inline typed::union_map> subtract(const typed::map> &umap2) const; + inline typed::union_map> subtract_domain(const typed::union_set &dom) const; + inline typed::union_map> subtract_domain(const typed::basic_set &dom) const; + inline typed::union_map> subtract_domain(const typed::point &dom) const; + inline typed::union_map> subtract_domain(const typed::set &dom) const; + inline typed::union_map> subtract_range(const typed::union_set> &dom) const; + inline typed::union_map> subtract_range(const typed::basic_set> &dom) const; + inline typed::union_map> subtract_range(const typed::point> &dom) const; + inline typed::union_map> subtract_range(const typed::set> &dom) const; + inline typed::union_map, Range2> uncurry() const; + inline typed::union_map> unite(const typed::union_map> &umap2) const; + inline typed::union_map> unite(const typed::basic_map> &umap2) const; + inline typed::union_map> unite(const typed::map> &umap2) const; + inline typed::union_map> universe() const; + inline typed::union_set>> wrap() const; +}; + +template +struct union_map, pair> : public isl::union_map { + template + friend struct aff; + template + friend struct aff_list; + template + friend struct basic_map; + template + friend struct basic_set; + template + friend struct fixed_box; + template + friend struct id; + template + friend struct id_list; + template + friend struct map; + template + friend struct map_list; + template + friend struct multi_aff; + template + friend struct multi_id; + template + friend struct multi_pw_aff; + template + friend struct multi_union_pw_aff; + template + friend struct multi_val; + template + friend struct point; + template + friend struct pw_aff; + template + friend struct pw_aff_list; + template + friend struct pw_multi_aff; + template + friend struct pw_multi_aff_list; + template + friend struct set; + template + friend struct set_list; + template + friend struct space; + template + friend struct union_map; + template + friend struct union_pw_aff; + template + friend struct union_pw_aff_list; + template + friend struct union_pw_multi_aff; + template + friend struct union_set; + template + friend struct union_set_list; + template + friend struct val; + template + friend struct val_list; + + union_map() = default; + template {} && + std::is_base_of{}, + bool>::type = true> + union_map(const union_map, pair> &obj) : isl::union_map(obj) {} + private: + template {}, bool>::type = true> + union_map(const base &obj) : isl::union_map(obj) {} + public: + static union_map from(const isl::union_map &obj) { + return union_map(obj); + } + inline /* implicit */ union_map(const typed::basic_map, pair> &bmap); + inline /* implicit */ union_map(const typed::map, pair> &map); + inline explicit union_map(const isl::ctx &ctx, const std::string &str); + template + inline typed::union_map> apply_domain(const typed::union_map, Domain2> &umap2) const; + template + inline typed::union_map> apply_domain(const typed::basic_map, Domain2> &umap2) const; + template + inline typed::union_map> apply_domain(const typed::map, Domain2> &umap2) const; + template + inline typed::union_map, Range2> apply_range(const typed::union_map, Range2> &umap2) const; + template + inline typed::union_map, Range2> apply_range(const typed::basic_map, Range2> &umap2) const; + template + inline typed::union_map, Range2> apply_range(const typed::map, Range2> &umap2) const; + inline typed::map, pair> as_map() const; + inline typed::multi_union_pw_aff, pair> as_multi_union_pw_aff() const; + inline typed::union_pw_multi_aff, pair> as_union_pw_multi_aff() const; + inline typed::union_set> bind_range(const typed::multi_id> &tuple) const; + inline typed::union_map, pair> coalesce() const; + inline typed::union_map>> curry() const; + inline typed::union_set> deltas() const; + inline typed::union_map, pair> detect_equalities() const; + inline typed::union_set> domain() const; + inline typed::union_map> domain_factor_domain() const; + inline typed::union_map> domain_factor_range() const; + inline typed::union_map, pair>, pair> domain_map() const; + inline typed::union_pw_multi_aff, pair>, pair> domain_map_union_pw_multi_aff() const; + template + inline typed::union_map, Domain2>, pair> domain_product(const typed::union_map> &umap2) const; + template + inline typed::union_map, Domain2>, pair> domain_product(const typed::basic_map> &umap2) const; + template + inline typed::union_map, Domain2>, pair> domain_product(const typed::map> &umap2) const; + inline typed::union_map, pair> domain_reverse() const; + inline typed::union_map, pair> drop_unused_params() const; + static inline typed::union_map, pair> empty(const isl::ctx &ctx); + template + inline typed::union_map, pair> eq_at(const typed::multi_union_pw_aff, Range> &mupa) const; + template + inline typed::union_map, pair> eq_at(const typed::multi_pw_aff, Range> &mupa) const; + inline typed::union_map, pair> eq_at(const typed::union_pw_aff, Anonymous> &mupa) const; + inline bool every_map(const std::function, pair>)> &test) const; + inline typed::map, pair> extract_map(const typed::space, pair> &space) const; + inline void foreach_map(const std::function, pair>)> &fn) const; + inline typed::union_map, pair> gist(const typed::union_map, pair> &context) const; + inline typed::union_map, pair> gist(const typed::basic_map, pair> &context) const; + inline typed::union_map, pair> gist(const typed::map, pair> &context) const; + inline typed::union_map, pair> gist_domain(const typed::union_set> &uset) const; + inline typed::union_map, pair> gist_domain(const typed::basic_set> &uset) const; + inline typed::union_map, pair> gist_domain(const typed::point> &uset) const; + inline typed::union_map, pair> gist_domain(const typed::set> &uset) const; + inline typed::union_map, pair> gist_params(const typed::set<> &set) const; + inline typed::union_map, pair> gist_params(const typed::basic_set<> &set) const; + inline typed::union_map, pair> gist_params(const typed::point<> &set) const; + inline typed::union_map, pair> intersect(const typed::union_map, pair> &umap2) const; + inline typed::union_map, pair> intersect(const typed::basic_map, pair> &umap2) const; + inline typed::union_map, pair> intersect(const typed::map, pair> &umap2) const; + inline typed::union_map, pair> intersect_domain(const typed::space> &space) const; + inline typed::union_map, pair> intersect_domain(const typed::union_set> &uset) const; + inline typed::union_map, pair> intersect_domain_wrapped_domain(const typed::union_set &domain) const; + inline typed::union_map, pair> intersect_domain_wrapped_domain(const typed::basic_set &domain) const; + inline typed::union_map, pair> intersect_domain_wrapped_domain(const typed::point &domain) const; + inline typed::union_map, pair> intersect_domain_wrapped_domain(const typed::set &domain) const; + inline typed::union_map, pair> intersect_params(const typed::set<> &set) const; + inline typed::union_map, pair> intersect_params(const typed::basic_set<> &set) const; + inline typed::union_map, pair> intersect_params(const typed::point<> &set) const; + inline typed::union_map, pair> intersect_range(const typed::space> &space) const; + inline typed::union_map, pair> intersect_range(const typed::union_set> &uset) const; + inline typed::union_map, pair> intersect_range_wrapped_domain(const typed::union_set &domain) const; + inline typed::union_map, pair> intersect_range_wrapped_domain(const typed::basic_set &domain) const; + inline typed::union_map, pair> intersect_range_wrapped_domain(const typed::point &domain) const; + inline typed::union_map, pair> intersect_range_wrapped_domain(const typed::set &domain) const; + inline typed::union_map, pair> lexmax() const; + inline typed::union_map, pair> lexmin() const; + inline typed::map_list, pair> map_list() const; + inline typed::map_list, pair> get_map_list() const = delete; + inline typed::set<> params() const; + template + inline typed::union_map> preimage_domain(const typed::multi_aff> &ma) const; + template + inline typed::union_map> preimage_domain(const typed::multi_pw_aff> &mpa) const; + template + inline typed::union_map> preimage_domain(const typed::pw_multi_aff> &pma) const; + template + inline typed::union_map> preimage_domain(const typed::union_pw_multi_aff> &upma) const; + template + inline typed::union_map, Range2> preimage_range(const typed::multi_aff> &ma) const; + template + inline typed::union_map, Range2> preimage_range(const typed::pw_multi_aff> &pma) const; + template + inline typed::union_map, Range2> preimage_range(const typed::union_pw_multi_aff> &upma) const; + template + inline typed::union_map, Domain2>, pair, Range2>> product(const typed::union_map &umap2) const; + template + inline typed::union_map, Domain2>, pair, Range2>> product(const typed::basic_map &umap2) const; + template + inline typed::union_map, Domain2>, pair, Range2>> product(const typed::map &umap2) const; + inline typed::union_map, pair> project_out_all_params() const; + inline typed::union_map, pair> project_out_param(const typed::id &id) const; + inline typed::union_map, pair> project_out_param(const std::string &id) const; + inline typed::union_map, pair> project_out_param(const typed::id_list &list) const; + inline typed::union_set> range() const; + inline typed::union_map, T1> range_factor_domain() const; + inline typed::union_map, T2> range_factor_range() const; + inline typed::union_map, pair>, pair> range_map() const; + template + inline typed::union_map, pair, Range2>> range_product(const typed::union_map, Range2> &umap2) const; + template + inline typed::union_map, pair, Range2>> range_product(const typed::basic_map, Range2> &umap2) const; + template + inline typed::union_map, pair, Range2>> range_product(const typed::map, Range2> &umap2) const; + inline typed::union_map, pair> range_reverse() const; + inline typed::union_map, pair> reverse() const; + inline typed::space<> space() const; + inline typed::space, pair> get_space() const = delete; + inline typed::union_map, pair> subtract(const typed::union_map, pair> &umap2) const; + inline typed::union_map, pair> subtract(const typed::basic_map, pair> &umap2) const; + inline typed::union_map, pair> subtract(const typed::map, pair> &umap2) const; + inline typed::union_map, pair> subtract_domain(const typed::union_set> &dom) const; + inline typed::union_map, pair> subtract_domain(const typed::basic_set> &dom) const; + inline typed::union_map, pair> subtract_domain(const typed::point> &dom) const; + inline typed::union_map, pair> subtract_domain(const typed::set> &dom) const; + inline typed::union_map, pair> subtract_range(const typed::union_set> &dom) const; + inline typed::union_map, pair> subtract_range(const typed::basic_set> &dom) const; + inline typed::union_map, pair> subtract_range(const typed::point> &dom) const; + inline typed::union_map, pair> subtract_range(const typed::set> &dom) const; + inline typed::union_map, T1>, T2> uncurry() const; + inline typed::union_map, pair> unite(const typed::union_map, pair> &umap2) const; + inline typed::union_map, pair> unite(const typed::basic_map, pair> &umap2) const; + inline typed::union_map, pair> unite(const typed::map, pair> &umap2) const; + inline typed::union_map, pair> universe() const; + inline typed::union_set, pair>> wrap() const; +}; + +template +struct union_map, pair> : public isl::union_map { + template + friend struct aff; + template + friend struct aff_list; + template + friend struct basic_map; + template + friend struct basic_set; + template + friend struct fixed_box; + template + friend struct id; + template + friend struct id_list; + template + friend struct map; + template + friend struct map_list; + template + friend struct multi_aff; + template + friend struct multi_id; + template + friend struct multi_pw_aff; + template + friend struct multi_union_pw_aff; + template + friend struct multi_val; + template + friend struct point; + template + friend struct pw_aff; + template + friend struct pw_aff_list; + template + friend struct pw_multi_aff; + template + friend struct pw_multi_aff_list; + template + friend struct set; + template + friend struct set_list; + template + friend struct space; + template + friend struct union_map; + template + friend struct union_pw_aff; + template + friend struct union_pw_aff_list; + template + friend struct union_pw_multi_aff; + template + friend struct union_set; + template + friend struct union_set_list; + template + friend struct val; + template + friend struct val_list; + + union_map() = default; + template {} && + std::is_base_of{} && + std::is_base_of{} && + std::is_base_of{}, + bool>::type = true> + union_map(const union_map, pair> &obj) : isl::union_map(obj) {} + private: + template {}, bool>::type = true> + union_map(const base &obj) : isl::union_map(obj) {} + public: + static union_map from(const isl::union_map &obj) { + return union_map(obj); + } + inline /* implicit */ union_map(const typed::basic_map, pair> &bmap); + inline /* implicit */ union_map(const typed::map, pair> &map); + inline explicit union_map(const isl::ctx &ctx, const std::string &str); + template + inline typed::union_map> apply_domain(const typed::union_map, Domain2> &umap2) const; + template + inline typed::union_map> apply_domain(const typed::basic_map, Domain2> &umap2) const; + template + inline typed::union_map> apply_domain(const typed::map, Domain2> &umap2) const; + template + inline typed::union_map, Arg2> apply_range(const typed::union_map, Arg2> &umap2) const; + template + inline typed::union_map, Arg2> apply_range(const typed::basic_map, Arg2> &umap2) const; + template + inline typed::union_map, Arg2> apply_range(const typed::map, Arg2> &umap2) const; + inline typed::map, pair> as_map() const; + inline typed::multi_union_pw_aff, pair> as_multi_union_pw_aff() const; + inline typed::union_pw_multi_aff, pair> as_union_pw_multi_aff() const; + inline typed::union_set> bind_range(const typed::multi_id> &tuple) const; + inline typed::union_map, pair> coalesce() const; + inline typed::union_map>> curry() const; + inline typed::union_set, pair> deltas() const = delete; + inline typed::union_map, pair> detect_equalities() const; + inline typed::union_set> domain() const; + inline typed::union_map> domain_factor_domain() const; + inline typed::union_map> domain_factor_range() const; + inline typed::union_map, pair>, pair> domain_map() const; + inline typed::union_pw_multi_aff, pair>, pair> domain_map_union_pw_multi_aff() const; + template + inline typed::union_map, Domain2>, pair> domain_product(const typed::union_map> &umap2) const; + template + inline typed::union_map, Domain2>, pair> domain_product(const typed::basic_map> &umap2) const; + template + inline typed::union_map, Domain2>, pair> domain_product(const typed::map> &umap2) const; + inline typed::union_map, pair> domain_reverse() const; + inline typed::union_map, pair> drop_unused_params() const; + static inline typed::union_map, pair> empty(const isl::ctx &ctx); + inline typed::union_map, pair> eq_at(const typed::multi_union_pw_aff<> &mupa) const = delete; + inline typed::union_map, pair> eq_at(const typed::multi_pw_aff<> &mupa) const = delete; + inline typed::union_map, pair> eq_at(const typed::union_pw_aff<> &mupa) const = delete; + inline bool every_map(const std::function, pair>)> &test) const; + inline typed::map, pair> extract_map(const typed::space, pair> &space) const; + inline void foreach_map(const std::function, pair>)> &fn) const; + inline typed::union_map, pair> gist(const typed::union_map, pair> &context) const; + inline typed::union_map, pair> gist(const typed::basic_map, pair> &context) const; + inline typed::union_map, pair> gist(const typed::map, pair> &context) const; + inline typed::union_map, pair> gist_domain(const typed::union_set> &uset) const; + inline typed::union_map, pair> gist_domain(const typed::basic_set> &uset) const; + inline typed::union_map, pair> gist_domain(const typed::point> &uset) const; + inline typed::union_map, pair> gist_domain(const typed::set> &uset) const; + inline typed::union_map, pair> gist_params(const typed::set<> &set) const; + inline typed::union_map, pair> gist_params(const typed::basic_set<> &set) const; + inline typed::union_map, pair> gist_params(const typed::point<> &set) const; + inline typed::union_map, pair> intersect(const typed::union_map, pair> &umap2) const; + inline typed::union_map, pair> intersect(const typed::basic_map, pair> &umap2) const; + inline typed::union_map, pair> intersect(const typed::map, pair> &umap2) const; + inline typed::union_map, pair> intersect_domain(const typed::space> &space) const; + inline typed::union_map, pair> intersect_domain(const typed::union_set> &uset) const; + inline typed::union_map, pair> intersect_domain_wrapped_domain(const typed::union_set &domain) const; + inline typed::union_map, pair> intersect_domain_wrapped_domain(const typed::basic_set &domain) const; + inline typed::union_map, pair> intersect_domain_wrapped_domain(const typed::point &domain) const; + inline typed::union_map, pair> intersect_domain_wrapped_domain(const typed::set &domain) const; + inline typed::union_map, pair> intersect_params(const typed::set<> &set) const; + inline typed::union_map, pair> intersect_params(const typed::basic_set<> &set) const; + inline typed::union_map, pair> intersect_params(const typed::point<> &set) const; + inline typed::union_map, pair> intersect_range(const typed::space> &space) const; + inline typed::union_map, pair> intersect_range(const typed::union_set> &uset) const; + inline typed::union_map, pair> intersect_range_wrapped_domain(const typed::union_set &domain) const; + inline typed::union_map, pair> intersect_range_wrapped_domain(const typed::basic_set &domain) const; + inline typed::union_map, pair> intersect_range_wrapped_domain(const typed::point &domain) const; + inline typed::union_map, pair> intersect_range_wrapped_domain(const typed::set &domain) const; + inline typed::union_map, pair> lexmax() const; + inline typed::union_map, pair> lexmin() const; + inline typed::map_list, pair> map_list() const; + inline typed::map_list, pair> get_map_list() const = delete; + inline typed::set<> params() const; + template + inline typed::union_map> preimage_domain(const typed::multi_aff> &ma) const; + template + inline typed::union_map> preimage_domain(const typed::multi_pw_aff> &mpa) const; + template + inline typed::union_map> preimage_domain(const typed::pw_multi_aff> &pma) const; + template + inline typed::union_map> preimage_domain(const typed::union_pw_multi_aff> &upma) const; + template + inline typed::union_map, Arg2> preimage_range(const typed::multi_aff> &ma) const; + template + inline typed::union_map, Arg2> preimage_range(const typed::pw_multi_aff> &pma) const; + template + inline typed::union_map, Arg2> preimage_range(const typed::union_pw_multi_aff> &upma) const; + template + inline typed::union_map, Domain2>, pair, Arg2>> product(const typed::union_map &umap2) const; + template + inline typed::union_map, Domain2>, pair, Arg2>> product(const typed::basic_map &umap2) const; + template + inline typed::union_map, Domain2>, pair, Arg2>> product(const typed::map &umap2) const; + inline typed::union_map, pair> project_out_all_params() const; + inline typed::union_map, pair> project_out_param(const typed::id &id) const; + inline typed::union_map, pair> project_out_param(const std::string &id) const; + inline typed::union_map, pair> project_out_param(const typed::id_list &list) const; + inline typed::union_set> range() const; + inline typed::union_map, Range> range_factor_domain() const; + inline typed::union_map, Range2> range_factor_range() const; + inline typed::union_map, pair>, pair> range_map() const; + template + inline typed::union_map, pair, Arg2>> range_product(const typed::union_map, Arg2> &umap2) const; + template + inline typed::union_map, pair, Arg2>> range_product(const typed::basic_map, Arg2> &umap2) const; + template + inline typed::union_map, pair, Arg2>> range_product(const typed::map, Arg2> &umap2) const; + inline typed::union_map, pair> range_reverse() const; + inline typed::union_map, pair> reverse() const; + inline typed::space<> space() const; + inline typed::space, pair> get_space() const = delete; + inline typed::union_map, pair> subtract(const typed::union_map, pair> &umap2) const; + inline typed::union_map, pair> subtract(const typed::basic_map, pair> &umap2) const; + inline typed::union_map, pair> subtract(const typed::map, pair> &umap2) const; + inline typed::union_map, pair> subtract_domain(const typed::union_set> &dom) const; + inline typed::union_map, pair> subtract_domain(const typed::basic_set> &dom) const; + inline typed::union_map, pair> subtract_domain(const typed::point> &dom) const; + inline typed::union_map, pair> subtract_domain(const typed::set> &dom) const; + inline typed::union_map, pair> subtract_range(const typed::union_set> &dom) const; + inline typed::union_map, pair> subtract_range(const typed::basic_set> &dom) const; + inline typed::union_map, pair> subtract_range(const typed::point> &dom) const; + inline typed::union_map, pair> subtract_range(const typed::set> &dom) const; + inline typed::union_map, Range>, Range2> uncurry() const; + inline typed::union_map, pair> unite(const typed::union_map, pair> &umap2) const; + inline typed::union_map, pair> unite(const typed::basic_map, pair> &umap2) const; + inline typed::union_map, pair> unite(const typed::map, pair> &umap2) const; + inline typed::union_map, pair> universe() const; + inline typed::union_set, pair>> wrap() const; +}; + +template <> +struct union_pw_aff : public isl::union_pw_aff { + template + friend struct aff; + template + friend struct aff_list; + template + friend struct basic_map; + template + friend struct basic_set; + template + friend struct fixed_box; + template + friend struct id; + template + friend struct id_list; + template + friend struct map; + template + friend struct map_list; + template + friend struct multi_aff; + template + friend struct multi_id; + template + friend struct multi_pw_aff; + template + friend struct multi_union_pw_aff; + template + friend struct multi_val; + template + friend struct point; + template + friend struct pw_aff; + template + friend struct pw_aff_list; + template + friend struct pw_multi_aff; + template + friend struct pw_multi_aff_list; + template + friend struct set; + template + friend struct set_list; + template + friend struct space; + template + friend struct union_map; + template + friend struct union_pw_aff; + template + friend struct union_pw_aff_list; + template + friend struct union_pw_multi_aff; + template + friend struct union_set; + template + friend struct union_set_list; + template + friend struct val; + template + friend struct val_list; + + union_pw_aff() = default; + union_pw_aff(const isl::union_pw_aff &obj) : isl::union_pw_aff(obj) {} + static union_pw_aff from(const isl::union_pw_aff &obj) { + return union_pw_aff(obj); + } + inline /* implicit */ union_pw_aff(const typed::aff &aff); + inline /* implicit */ union_pw_aff(const typed::pw_aff &pa); + inline explicit union_pw_aff(const isl::ctx &ctx, const std::string &str); + inline typed::multi_union_pw_aff add(const typed::multi_union_pw_aff &multi2) const; + inline typed::union_pw_aff add(const typed::union_pw_aff &upa2) const; + inline typed::union_pw_multi_aff add(const typed::union_pw_multi_aff &upma2) const; + inline typed::union_pw_aff add(const typed::aff &upa2) const; + inline typed::union_pw_aff add(const typed::pw_aff &upa2) const; + template + inline typed::union_pw_multi_aff apply(const typed::union_pw_multi_aff &upma2) const; + inline typed::multi_union_pw_aff as_multi_union_pw_aff() const; + inline typed::pw_multi_aff as_pw_multi_aff() const; + inline typed::union_map as_union_map() const = delete; + inline typed::union_pw_aff at(int pos) const; + inline typed::union_set<> bind(const typed::multi_id &tuple) const; + inline typed::union_set<> bind(const typed::id &id) const; + inline typed::union_set<> bind(const std::string &id) const; + inline typed::union_pw_aff coalesce() const; + inline typed::union_set<> domain() const; + inline typed::union_pw_aff drop_unused_params() const; + inline typed::pw_multi_aff extract_pw_multi_aff(const typed::space &space) const; + inline typed::union_pw_aff gist(const typed::union_set<> &context) const; + inline typed::union_pw_aff gist(const typed::basic_set<> &context) const; + inline typed::union_pw_aff gist(const typed::point<> &context) const; + inline typed::union_pw_aff gist(const typed::set<> &context) const; + inline typed::multi_union_pw_aff gist_params(const typed::set<> &context) const; + inline typed::union_pw_aff intersect_domain(const typed::space<> &space) const = delete; + inline typed::union_pw_aff intersect_domain(const typed::union_set<> &uset) const = delete; + inline typed::union_pw_aff intersect_domain_wrapped_domain(const typed::union_set<> &uset) const = delete; + inline typed::union_pw_aff intersect_domain_wrapped_domain(const typed::basic_set<> &uset) const = delete; + inline typed::union_pw_aff intersect_domain_wrapped_domain(const typed::point<> &uset) const = delete; + inline typed::union_pw_aff intersect_domain_wrapped_domain(const typed::set<> &uset) const = delete; + inline typed::union_pw_aff intersect_params(const typed::set<> &set) const; + inline typed::union_pw_aff intersect_params(const typed::basic_set<> &set) const; + inline typed::union_pw_aff intersect_params(const typed::point<> &set) const; + inline typed::union_pw_aff_list list() const; + inline typed::multi_union_pw_aff neg() const; + inline typed::union_pw_multi_aff preimage_domain_wrapped_domain(const typed::union_pw_multi_aff<> &upma2) const = delete; + inline typed::union_pw_aff pullback(const typed::union_pw_multi_aff<> &upma) const = delete; + inline typed::union_pw_aff pullback(const typed::multi_aff<> &upma) const = delete; + inline typed::union_pw_aff pullback(const typed::pw_multi_aff<> &upma) const = delete; + inline typed::union_pw_aff pullback(const typed::union_pw_aff<> &upma) const = delete; + inline typed::pw_multi_aff_list pw_multi_aff_list() const; + inline typed::union_pw_multi_aff range_factor_domain() const = delete; + inline typed::union_pw_multi_aff range_factor_range() const = delete; + inline typed::multi_union_pw_aff range_product(const typed::multi_union_pw_aff<> &multi2) const = delete; + inline typed::union_pw_multi_aff range_product(const typed::union_pw_multi_aff<> &upma2) const = delete; + inline typed::multi_union_pw_aff scale(const typed::multi_val &mv) const; + inline typed::multi_union_pw_aff scale(const typed::val &v) const; + inline typed::multi_union_pw_aff scale(long v) const; + inline typed::multi_union_pw_aff scale_down(const typed::multi_val &mv) const; + inline typed::multi_union_pw_aff scale_down(const typed::val &v) const; + inline typed::multi_union_pw_aff scale_down(long v) const; + inline typed::multi_union_pw_aff set_at(int pos, const typed::union_pw_aff &el) const; + template + inline typed::multi_union_pw_aff set_range_tuple(const typed::id &id) const; + template + inline typed::multi_union_pw_aff set_range_tuple(const std::string &id) const; + inline typed::space<> space() const; + inline typed::space get_space() const = delete; + inline typed::multi_union_pw_aff sub(const typed::multi_union_pw_aff &multi2) const; + inline typed::union_pw_aff sub(const typed::union_pw_aff &upa2) const; + inline typed::union_pw_multi_aff sub(const typed::union_pw_multi_aff &upma2) const; + inline typed::union_pw_aff sub(const typed::aff &upa2) const; + inline typed::union_pw_aff sub(const typed::pw_aff &upa2) const; + inline typed::union_pw_aff subtract_domain(const typed::space<> &space) const = delete; + inline typed::union_pw_aff subtract_domain(const typed::union_set<> &uset) const = delete; + inline typed::multi_union_pw_aff union_add(const typed::multi_union_pw_aff &mupa2) const; + inline typed::union_pw_aff union_add(const typed::union_pw_aff &upa2) const; + inline typed::union_pw_multi_aff union_add(const typed::union_pw_multi_aff &upma2) const; + inline typed::union_pw_aff union_add(const typed::aff &upa2) const; + inline typed::union_pw_aff union_add(const typed::pw_aff &upa2) const; +}; + +template +struct union_pw_aff : public isl::union_pw_aff { + template + friend struct aff; + template + friend struct aff_list; + template + friend struct basic_map; + template + friend struct basic_set; + template + friend struct fixed_box; + template + friend struct id; + template + friend struct id_list; + template + friend struct map; + template + friend struct map_list; + template + friend struct multi_aff; + template + friend struct multi_id; + template + friend struct multi_pw_aff; + template + friend struct multi_union_pw_aff; + template + friend struct multi_val; + template + friend struct point; + template + friend struct pw_aff; + template + friend struct pw_aff_list; + template + friend struct pw_multi_aff; + template + friend struct pw_multi_aff_list; + template + friend struct set; + template + friend struct set_list; + template + friend struct space; + template + friend struct union_map; + template + friend struct union_pw_aff; + template + friend struct union_pw_aff_list; + template + friend struct union_pw_multi_aff; + template + friend struct union_set; + template + friend struct union_set_list; + template + friend struct val; + template + friend struct val_list; + + union_pw_aff() = default; + template {}, + bool>::type = true> + union_pw_aff(const union_pw_aff &obj) : isl::union_pw_aff(obj) {} + private: + template {}, bool>::type = true> + union_pw_aff(const base &obj) : isl::union_pw_aff(obj) {} + public: + static union_pw_aff from(const isl::union_pw_aff &obj) { + return union_pw_aff(obj); + } + inline /* implicit */ union_pw_aff(const typed::aff &aff); + inline /* implicit */ union_pw_aff(const typed::pw_aff &pa); + inline explicit union_pw_aff(const isl::ctx &ctx, const std::string &str); + inline typed::multi_union_pw_aff add(const typed::multi_union_pw_aff &multi2) const; + inline typed::union_pw_aff add(const typed::union_pw_aff &upa2) const; + inline typed::union_pw_multi_aff add(const typed::union_pw_multi_aff &upma2) const; + inline typed::union_pw_aff add(const typed::aff &upa2) const; + inline typed::union_pw_aff add(const typed::pw_aff &upa2) const; + template + inline typed::union_pw_multi_aff apply(const typed::union_pw_multi_aff &upma2) const; + inline typed::multi_union_pw_aff as_multi_union_pw_aff() const; + inline typed::pw_multi_aff as_pw_multi_aff() const; + inline typed::union_map as_union_map() const; + inline typed::union_pw_aff at(int pos) const; + inline typed::union_set bind(const typed::multi_id &tuple) const; + inline typed::union_set bind(const typed::id &id) const; + inline typed::union_set bind(const std::string &id) const; + inline typed::union_pw_aff coalesce() const; + inline typed::union_set domain() const; + inline typed::union_pw_aff drop_unused_params() const; + inline typed::pw_multi_aff extract_pw_multi_aff(const typed::space &space) const; + inline typed::union_pw_aff gist(const typed::union_set &context) const; + inline typed::union_pw_aff gist(const typed::basic_set &context) const; + inline typed::union_pw_aff gist(const typed::point &context) const; + inline typed::union_pw_aff gist(const typed::set &context) const; + inline typed::multi_union_pw_aff gist_params(const typed::set<> &context) const; + inline typed::union_pw_aff intersect_domain(const typed::space &space) const; + inline typed::union_pw_aff intersect_domain(const typed::union_set &uset) const; + inline typed::union_pw_aff intersect_domain_wrapped_domain(const typed::union_set<> &uset) const = delete; + inline typed::union_pw_aff intersect_domain_wrapped_domain(const typed::basic_set<> &uset) const = delete; + inline typed::union_pw_aff intersect_domain_wrapped_domain(const typed::point<> &uset) const = delete; + inline typed::union_pw_aff intersect_domain_wrapped_domain(const typed::set<> &uset) const = delete; + inline typed::union_pw_aff intersect_params(const typed::set<> &set) const; + inline typed::union_pw_aff intersect_params(const typed::basic_set<> &set) const; + inline typed::union_pw_aff intersect_params(const typed::point<> &set) const; + inline typed::union_pw_aff_list list() const; + inline typed::multi_union_pw_aff neg() const; + inline typed::union_pw_multi_aff preimage_domain_wrapped_domain(const typed::union_pw_multi_aff<> &upma2) const = delete; + template + inline typed::union_pw_aff pullback(const typed::union_pw_multi_aff &upma) const; + inline typed::union_pw_aff pullback(const typed::union_pw_multi_aff &upma) const; + template + inline typed::union_pw_aff pullback(const typed::multi_aff &upma) const; + inline typed::union_pw_aff pullback(const typed::multi_aff &upma) const; + template + inline typed::union_pw_aff pullback(const typed::pw_multi_aff &upma) const; + inline typed::union_pw_aff pullback(const typed::pw_multi_aff &upma) const; + template + inline typed::union_pw_aff pullback(const typed::union_pw_aff &upma) const; + inline typed::union_pw_aff pullback(const typed::union_pw_aff &upma) const; + inline typed::pw_multi_aff_list pw_multi_aff_list() const; + inline typed::union_pw_multi_aff range_factor_domain() const = delete; + inline typed::union_pw_multi_aff range_factor_range() const = delete; + template + inline typed::multi_union_pw_aff> range_product(const typed::multi_union_pw_aff &multi2) const; + template + inline typed::union_pw_multi_aff> range_product(const typed::union_pw_multi_aff &upma2) const; + inline typed::multi_union_pw_aff scale(const typed::multi_val &mv) const; + inline typed::multi_union_pw_aff scale(const typed::val &v) const; + inline typed::multi_union_pw_aff scale(long v) const; + inline typed::multi_union_pw_aff scale_down(const typed::multi_val &mv) const; + inline typed::multi_union_pw_aff scale_down(const typed::val &v) const; + inline typed::multi_union_pw_aff scale_down(long v) const; + inline typed::multi_union_pw_aff set_at(int pos, const typed::union_pw_aff &el) const; + template + inline typed::multi_union_pw_aff set_range_tuple(const typed::id &id) const; + template + inline typed::multi_union_pw_aff set_range_tuple(const std::string &id) const; + inline typed::space<> space() const; + inline typed::space get_space() const = delete; + inline typed::multi_union_pw_aff sub(const typed::multi_union_pw_aff &multi2) const; + inline typed::union_pw_aff sub(const typed::union_pw_aff &upa2) const; + inline typed::union_pw_multi_aff sub(const typed::union_pw_multi_aff &upma2) const; + inline typed::union_pw_aff sub(const typed::aff &upa2) const; + inline typed::union_pw_aff sub(const typed::pw_aff &upa2) const; + inline typed::union_pw_aff subtract_domain(const typed::space &space) const; + inline typed::union_pw_aff subtract_domain(const typed::union_set &uset) const; + inline typed::multi_union_pw_aff union_add(const typed::multi_union_pw_aff &mupa2) const; + inline typed::union_pw_aff union_add(const typed::union_pw_aff &upa2) const; + inline typed::union_pw_multi_aff union_add(const typed::union_pw_multi_aff &upma2) const; + inline typed::union_pw_aff union_add(const typed::aff &upa2) const; + inline typed::union_pw_aff union_add(const typed::pw_aff &upa2) const; +}; + +template +struct union_pw_aff, Anonymous> : public isl::union_pw_aff { + template + friend struct aff; + template + friend struct aff_list; + template + friend struct basic_map; + template + friend struct basic_set; + template + friend struct fixed_box; + template + friend struct id; + template + friend struct id_list; + template + friend struct map; + template + friend struct map_list; + template + friend struct multi_aff; + template + friend struct multi_id; + template + friend struct multi_pw_aff; + template + friend struct multi_union_pw_aff; + template + friend struct multi_val; + template + friend struct point; + template + friend struct pw_aff; + template + friend struct pw_aff_list; + template + friend struct pw_multi_aff; + template + friend struct pw_multi_aff_list; + template + friend struct set; + template + friend struct set_list; + template + friend struct space; + template + friend struct union_map; + template + friend struct union_pw_aff; + template + friend struct union_pw_aff_list; + template + friend struct union_pw_multi_aff; + template + friend struct union_set; + template + friend struct union_set_list; + template + friend struct val; + template + friend struct val_list; + + union_pw_aff() = default; + template {} && + std::is_base_of{}, + bool>::type = true> + union_pw_aff(const union_pw_aff, Anonymous> &obj) : isl::union_pw_aff(obj) {} + private: + template {}, bool>::type = true> + union_pw_aff(const base &obj) : isl::union_pw_aff(obj) {} + public: + static union_pw_aff from(const isl::union_pw_aff &obj) { + return union_pw_aff(obj); + } + inline /* implicit */ union_pw_aff(const typed::aff, Anonymous> &aff); + inline /* implicit */ union_pw_aff(const typed::pw_aff, Anonymous> &pa); + inline explicit union_pw_aff(const isl::ctx &ctx, const std::string &str); + inline typed::multi_union_pw_aff, Anonymous> add(const typed::multi_union_pw_aff, Anonymous> &multi2) const; + inline typed::union_pw_aff, Anonymous> add(const typed::union_pw_aff, Anonymous> &upa2) const; + inline typed::union_pw_multi_aff, Anonymous> add(const typed::union_pw_multi_aff, Anonymous> &upma2) const; + inline typed::union_pw_aff, Anonymous> add(const typed::aff, Anonymous> &upa2) const; + inline typed::union_pw_aff, Anonymous> add(const typed::pw_aff, Anonymous> &upa2) const; + template + inline typed::union_pw_multi_aff, Range2> apply(const typed::union_pw_multi_aff &upma2) const; + inline typed::multi_union_pw_aff, Anonymous> as_multi_union_pw_aff() const; + inline typed::pw_multi_aff, Anonymous> as_pw_multi_aff() const; + inline typed::union_map, Anonymous> as_union_map() const; + inline typed::union_pw_aff, Anonymous> at(int pos) const; + inline typed::union_set> bind(const typed::multi_id &tuple) const; + inline typed::union_set> bind(const typed::id &id) const; + inline typed::union_set> bind(const std::string &id) const; + inline typed::union_pw_aff, Anonymous> coalesce() const; + inline typed::union_set> domain() const; + inline typed::union_pw_aff, Anonymous> drop_unused_params() const; + inline typed::pw_multi_aff, Anonymous> extract_pw_multi_aff(const typed::space, Anonymous> &space) const; + inline typed::union_pw_aff, Anonymous> gist(const typed::union_set> &context) const; + inline typed::union_pw_aff, Anonymous> gist(const typed::basic_set> &context) const; + inline typed::union_pw_aff, Anonymous> gist(const typed::point> &context) const; + inline typed::union_pw_aff, Anonymous> gist(const typed::set> &context) const; + inline typed::multi_union_pw_aff, Anonymous> gist_params(const typed::set<> &context) const; + inline typed::union_pw_aff, Anonymous> intersect_domain(const typed::space> &space) const; + inline typed::union_pw_aff, Anonymous> intersect_domain(const typed::union_set> &uset) const; + inline typed::union_pw_aff, Anonymous> intersect_domain_wrapped_domain(const typed::union_set &uset) const; + inline typed::union_pw_aff, Anonymous> intersect_domain_wrapped_domain(const typed::basic_set &uset) const; + inline typed::union_pw_aff, Anonymous> intersect_domain_wrapped_domain(const typed::point &uset) const; + inline typed::union_pw_aff, Anonymous> intersect_domain_wrapped_domain(const typed::set &uset) const; + inline typed::union_pw_aff, Anonymous> intersect_params(const typed::set<> &set) const; + inline typed::union_pw_aff, Anonymous> intersect_params(const typed::basic_set<> &set) const; + inline typed::union_pw_aff, Anonymous> intersect_params(const typed::point<> &set) const; + inline typed::union_pw_aff_list, Anonymous> list() const; + inline typed::multi_union_pw_aff, Anonymous> neg() const; + template + inline typed::union_pw_multi_aff, Anonymous> preimage_domain_wrapped_domain(const typed::union_pw_multi_aff &upma2) const; + template + inline typed::union_pw_aff pullback(const typed::union_pw_multi_aff> &upma) const; + inline typed::union_pw_aff pullback(const typed::union_pw_multi_aff> &upma) const; + template + inline typed::union_pw_aff pullback(const typed::multi_aff> &upma) const; + inline typed::union_pw_aff pullback(const typed::multi_aff> &upma) const; + template + inline typed::union_pw_aff pullback(const typed::pw_multi_aff> &upma) const; + inline typed::union_pw_aff pullback(const typed::pw_multi_aff> &upma) const; + template + inline typed::union_pw_aff pullback(const typed::union_pw_aff> &upma) const; + inline typed::union_pw_aff pullback(const typed::union_pw_aff> &upma) const; + inline typed::pw_multi_aff_list, Anonymous> pw_multi_aff_list() const; + inline typed::union_pw_multi_aff, Anonymous> range_factor_domain() const = delete; + inline typed::union_pw_multi_aff, Anonymous> range_factor_range() const = delete; + template + inline typed::multi_union_pw_aff, pair> range_product(const typed::multi_union_pw_aff, Range2> &multi2) const; + template + inline typed::union_pw_multi_aff, pair> range_product(const typed::union_pw_multi_aff, Range2> &upma2) const; + inline typed::multi_union_pw_aff, Anonymous> scale(const typed::multi_val &mv) const; + inline typed::multi_union_pw_aff, Anonymous> scale(const typed::val &v) const; + inline typed::multi_union_pw_aff, Anonymous> scale(long v) const; + inline typed::multi_union_pw_aff, Anonymous> scale_down(const typed::multi_val &mv) const; + inline typed::multi_union_pw_aff, Anonymous> scale_down(const typed::val &v) const; + inline typed::multi_union_pw_aff, Anonymous> scale_down(long v) const; + inline typed::multi_union_pw_aff, Anonymous> set_at(int pos, const typed::union_pw_aff, Anonymous> &el) const; + template + inline typed::multi_union_pw_aff, Range2> set_range_tuple(const typed::id &id) const; + template + inline typed::multi_union_pw_aff, Range2> set_range_tuple(const std::string &id) const; + inline typed::space<> space() const; + inline typed::space, Anonymous> get_space() const = delete; + inline typed::multi_union_pw_aff, Anonymous> sub(const typed::multi_union_pw_aff, Anonymous> &multi2) const; + inline typed::union_pw_aff, Anonymous> sub(const typed::union_pw_aff, Anonymous> &upa2) const; + inline typed::union_pw_multi_aff, Anonymous> sub(const typed::union_pw_multi_aff, Anonymous> &upma2) const; + inline typed::union_pw_aff, Anonymous> sub(const typed::aff, Anonymous> &upa2) const; + inline typed::union_pw_aff, Anonymous> sub(const typed::pw_aff, Anonymous> &upa2) const; + inline typed::union_pw_aff, Anonymous> subtract_domain(const typed::space> &space) const; + inline typed::union_pw_aff, Anonymous> subtract_domain(const typed::union_set> &uset) const; + inline typed::multi_union_pw_aff, Anonymous> union_add(const typed::multi_union_pw_aff, Anonymous> &mupa2) const; + inline typed::union_pw_aff, Anonymous> union_add(const typed::union_pw_aff, Anonymous> &upa2) const; + inline typed::union_pw_multi_aff, Anonymous> union_add(const typed::union_pw_multi_aff, Anonymous> &upma2) const; + inline typed::union_pw_aff, Anonymous> union_add(const typed::aff, Anonymous> &upa2) const; + inline typed::union_pw_aff, Anonymous> union_add(const typed::pw_aff, Anonymous> &upa2) const; +}; + +template <> +struct union_pw_aff_list : public isl::union_pw_aff_list { + template + friend struct aff; + template + friend struct aff_list; + template + friend struct basic_map; + template + friend struct basic_set; + template + friend struct fixed_box; + template + friend struct id; + template + friend struct id_list; + template + friend struct map; + template + friend struct map_list; + template + friend struct multi_aff; + template + friend struct multi_id; + template + friend struct multi_pw_aff; + template + friend struct multi_union_pw_aff; + template + friend struct multi_val; + template + friend struct point; + template + friend struct pw_aff; + template + friend struct pw_aff_list; + template + friend struct pw_multi_aff; + template + friend struct pw_multi_aff_list; + template + friend struct set; + template + friend struct set_list; + template + friend struct space; + template + friend struct union_map; + template + friend struct union_pw_aff; + template + friend struct union_pw_aff_list; + template + friend struct union_pw_multi_aff; + template + friend struct union_set; + template + friend struct union_set_list; + template + friend struct val; + template + friend struct val_list; + + union_pw_aff_list() = default; + union_pw_aff_list(const isl::union_pw_aff_list &obj) : isl::union_pw_aff_list(obj) {} + static union_pw_aff_list from(const isl::union_pw_aff_list &obj) { + return union_pw_aff_list(obj); + } + inline explicit union_pw_aff_list(const isl::ctx &ctx, int n); + inline explicit union_pw_aff_list(const typed::union_pw_aff &el); + inline explicit union_pw_aff_list(const isl::ctx &ctx, const std::string &str); + inline typed::union_pw_aff_list add(const typed::union_pw_aff &el) const; + inline typed::union_pw_aff_list add(const typed::aff &el) const; + inline typed::union_pw_aff_list add(const typed::pw_aff &el) const; + inline typed::union_pw_aff at(int index) const; + inline typed::union_pw_aff get_at(int index) const = delete; + inline typed::union_pw_aff_list drop(unsigned int first, unsigned int n) const; + inline void foreach(const std::function)> &fn) const; + inline void foreach_scc(const std::function, typed::union_pw_aff)> &follows, const std::function)> &fn) const; + inline typed::union_pw_aff_list set_at(int index, const typed::union_pw_aff &el) const; +}; + +template +struct union_pw_aff_list : public isl::union_pw_aff_list { + template + friend struct aff; + template + friend struct aff_list; + template + friend struct basic_map; + template + friend struct basic_set; + template + friend struct fixed_box; + template + friend struct id; + template + friend struct id_list; + template + friend struct map; + template + friend struct map_list; + template + friend struct multi_aff; + template + friend struct multi_id; + template + friend struct multi_pw_aff; + template + friend struct multi_union_pw_aff; + template + friend struct multi_val; + template + friend struct point; + template + friend struct pw_aff; + template + friend struct pw_aff_list; + template + friend struct pw_multi_aff; + template + friend struct pw_multi_aff_list; + template + friend struct set; + template + friend struct set_list; + template + friend struct space; + template + friend struct union_map; + template + friend struct union_pw_aff; + template + friend struct union_pw_aff_list; + template + friend struct union_pw_multi_aff; + template + friend struct union_set; + template + friend struct union_set_list; + template + friend struct val; + template + friend struct val_list; + + union_pw_aff_list() = default; + template {}, + bool>::type = true> + union_pw_aff_list(const union_pw_aff_list &obj) : isl::union_pw_aff_list(obj) {} + private: + template {}, bool>::type = true> + union_pw_aff_list(const base &obj) : isl::union_pw_aff_list(obj) {} + public: + static union_pw_aff_list from(const isl::union_pw_aff_list &obj) { + return union_pw_aff_list(obj); + } + inline explicit union_pw_aff_list(const isl::ctx &ctx, int n); + inline explicit union_pw_aff_list(const typed::union_pw_aff &el); + inline explicit union_pw_aff_list(const isl::ctx &ctx, const std::string &str); + inline typed::union_pw_aff_list add(const typed::union_pw_aff &el) const; + inline typed::union_pw_aff_list add(const typed::aff &el) const; + inline typed::union_pw_aff_list add(const typed::pw_aff &el) const; + inline typed::union_pw_aff at(int index) const; + inline typed::union_pw_aff get_at(int index) const = delete; + inline typed::union_pw_aff_list drop(unsigned int first, unsigned int n) const; + inline void foreach(const std::function)> &fn) const; + inline void foreach_scc(const std::function, typed::union_pw_aff)> &follows, const std::function)> &fn) const; + inline typed::union_pw_aff_list set_at(int index, const typed::union_pw_aff &el) const; +}; + +template +struct union_pw_multi_aff : public isl::union_pw_multi_aff { + template + friend struct aff; + template + friend struct aff_list; + template + friend struct basic_map; + template + friend struct basic_set; + template + friend struct fixed_box; + template + friend struct id; + template + friend struct id_list; + template + friend struct map; + template + friend struct map_list; + template + friend struct multi_aff; + template + friend struct multi_id; + template + friend struct multi_pw_aff; + template + friend struct multi_union_pw_aff; + template + friend struct multi_val; + template + friend struct point; + template + friend struct pw_aff; + template + friend struct pw_aff_list; + template + friend struct pw_multi_aff; + template + friend struct pw_multi_aff_list; + template + friend struct set; + template + friend struct set_list; + template + friend struct space; + template + friend struct union_map; + template + friend struct union_pw_aff; + template + friend struct union_pw_aff_list; + template + friend struct union_pw_multi_aff; + template + friend struct union_set; + template + friend struct union_set_list; + template + friend struct val; + template + friend struct val_list; + + union_pw_multi_aff() = default; + template {}, + bool>::type = true> + union_pw_multi_aff(const union_pw_multi_aff &obj) : isl::union_pw_multi_aff(obj) {} + private: + template {}, bool>::type = true> + union_pw_multi_aff(const base &obj) : isl::union_pw_multi_aff(obj) {} + public: + static union_pw_multi_aff from(const isl::union_pw_multi_aff &obj) { + return union_pw_multi_aff(obj); + } + inline /* implicit */ union_pw_multi_aff(const typed::multi_aff &ma); + inline /* implicit */ union_pw_multi_aff(const typed::pw_multi_aff &pma); + inline /* implicit */ union_pw_multi_aff(const typed::union_pw_aff &upa); + inline explicit union_pw_multi_aff(const isl::ctx &ctx, const std::string &str); + inline typed::union_pw_multi_aff add(const typed::union_pw_multi_aff &upma2) const; + inline typed::union_pw_multi_aff add(const typed::multi_aff &upma2) const; + inline typed::union_pw_multi_aff add(const typed::pw_multi_aff &upma2) const; + inline typed::union_pw_multi_aff add(const typed::union_pw_aff &upma2) const; + template + inline typed::union_pw_multi_aff apply(const typed::union_pw_multi_aff &upma2) const; + template + inline typed::union_pw_multi_aff apply(const typed::multi_aff &upma2) const; + template + inline typed::union_pw_multi_aff apply(const typed::pw_multi_aff &upma2) const; + inline typed::union_pw_multi_aff apply(const typed::union_pw_aff &upma2) const; + inline typed::multi_union_pw_aff as_multi_union_pw_aff() const; + inline typed::pw_multi_aff as_pw_multi_aff() const; + inline typed::union_map as_union_map() const = delete; + inline typed::union_pw_multi_aff coalesce() const; + inline typed::union_set<> domain() const; + inline typed::union_pw_multi_aff drop_unused_params() const; + static inline typed::union_pw_multi_aff empty(const isl::ctx &ctx); + inline typed::pw_multi_aff extract_pw_multi_aff(const typed::space &space) const; + inline typed::union_pw_multi_aff gist(const typed::union_set<> &context) const; + inline typed::union_pw_multi_aff gist(const typed::basic_set<> &context) const; + inline typed::union_pw_multi_aff gist(const typed::point<> &context) const; + inline typed::union_pw_multi_aff gist(const typed::set<> &context) const; + inline typed::union_pw_multi_aff intersect_domain(const typed::space<> &space) const = delete; + inline typed::union_pw_multi_aff intersect_domain(const typed::union_set<> &uset) const = delete; + inline typed::union_pw_multi_aff intersect_domain_wrapped_domain(const typed::union_set<> &uset) const = delete; + inline typed::union_pw_multi_aff intersect_domain_wrapped_domain(const typed::basic_set<> &uset) const = delete; + inline typed::union_pw_multi_aff intersect_domain_wrapped_domain(const typed::point<> &uset) const = delete; + inline typed::union_pw_multi_aff intersect_domain_wrapped_domain(const typed::set<> &uset) const = delete; + inline typed::union_pw_multi_aff intersect_params(const typed::set<> &set) const; + inline typed::union_pw_multi_aff intersect_params(const typed::basic_set<> &set) const; + inline typed::union_pw_multi_aff intersect_params(const typed::point<> &set) const; + inline typed::union_pw_multi_aff preimage_domain_wrapped_domain(const typed::union_pw_multi_aff<> &upma2) const = delete; + inline typed::union_pw_multi_aff preimage_domain_wrapped_domain(const typed::multi_aff<> &upma2) const = delete; + inline typed::union_pw_multi_aff preimage_domain_wrapped_domain(const typed::pw_multi_aff<> &upma2) const = delete; + inline typed::union_pw_multi_aff preimage_domain_wrapped_domain(const typed::union_pw_aff<> &upma2) const = delete; + inline typed::union_pw_multi_aff pullback(const typed::union_pw_multi_aff<> &upma2) const = delete; + inline typed::union_pw_multi_aff pullback(const typed::multi_aff<> &upma2) const = delete; + inline typed::union_pw_multi_aff pullback(const typed::pw_multi_aff<> &upma2) const = delete; + inline typed::union_pw_multi_aff pullback(const typed::union_pw_aff<> &upma2) const = delete; + inline typed::pw_multi_aff_list pw_multi_aff_list() const; + inline typed::pw_multi_aff_list get_pw_multi_aff_list() const = delete; + inline typed::union_pw_multi_aff range_factor_domain() const = delete; + inline typed::union_pw_multi_aff range_factor_range() const = delete; + inline typed::union_pw_multi_aff range_product(const typed::union_pw_multi_aff<> &upma2) const = delete; + inline typed::union_pw_multi_aff range_product(const typed::multi_aff<> &upma2) const = delete; + inline typed::union_pw_multi_aff range_product(const typed::pw_multi_aff<> &upma2) const = delete; + inline typed::union_pw_multi_aff range_product(const typed::union_pw_aff<> &upma2) const = delete; + inline typed::space<> space() const; + inline typed::space get_space() const = delete; + inline typed::union_pw_multi_aff sub(const typed::union_pw_multi_aff &upma2) const; + inline typed::union_pw_multi_aff sub(const typed::multi_aff &upma2) const; + inline typed::union_pw_multi_aff sub(const typed::pw_multi_aff &upma2) const; + inline typed::union_pw_multi_aff sub(const typed::union_pw_aff &upma2) const; + inline typed::union_pw_multi_aff subtract_domain(const typed::space<> &space) const = delete; + inline typed::union_pw_multi_aff subtract_domain(const typed::union_set<> &uset) const = delete; + inline typed::union_pw_multi_aff union_add(const typed::union_pw_multi_aff &upma2) const; + inline typed::union_pw_multi_aff union_add(const typed::multi_aff &upma2) const; + inline typed::union_pw_multi_aff union_add(const typed::pw_multi_aff &upma2) const; + inline typed::union_pw_multi_aff union_add(const typed::union_pw_aff &upma2) const; +}; + +template +struct union_pw_multi_aff : public isl::union_pw_multi_aff { + template + friend struct aff; + template + friend struct aff_list; + template + friend struct basic_map; + template + friend struct basic_set; + template + friend struct fixed_box; + template + friend struct id; + template + friend struct id_list; + template + friend struct map; + template + friend struct map_list; + template + friend struct multi_aff; + template + friend struct multi_id; + template + friend struct multi_pw_aff; + template + friend struct multi_union_pw_aff; + template + friend struct multi_val; + template + friend struct point; + template + friend struct pw_aff; + template + friend struct pw_aff_list; + template + friend struct pw_multi_aff; + template + friend struct pw_multi_aff_list; + template + friend struct set; + template + friend struct set_list; + template + friend struct space; + template + friend struct union_map; + template + friend struct union_pw_aff; + template + friend struct union_pw_aff_list; + template + friend struct union_pw_multi_aff; + template + friend struct union_set; + template + friend struct union_set_list; + template + friend struct val; + template + friend struct val_list; + + union_pw_multi_aff() = default; + template {} && + std::is_base_of{}, + bool>::type = true> + union_pw_multi_aff(const union_pw_multi_aff &obj) : isl::union_pw_multi_aff(obj) {} + private: + template {}, bool>::type = true> + union_pw_multi_aff(const base &obj) : isl::union_pw_multi_aff(obj) {} + public: + static union_pw_multi_aff from(const isl::union_pw_multi_aff &obj) { + return union_pw_multi_aff(obj); + } + inline /* implicit */ union_pw_multi_aff(const typed::multi_aff &ma); + inline /* implicit */ union_pw_multi_aff(const typed::pw_multi_aff &pma); + inline /* implicit */ union_pw_multi_aff(const typed::union_pw_aff &upa); + inline explicit union_pw_multi_aff(const isl::ctx &ctx, const std::string &str); + inline typed::union_pw_multi_aff add(const typed::union_pw_multi_aff &upma2) const; + inline typed::union_pw_multi_aff add(const typed::multi_aff &upma2) const; + inline typed::union_pw_multi_aff add(const typed::pw_multi_aff &upma2) const; + inline typed::union_pw_multi_aff add(const typed::union_pw_aff &upma2) const; + template + inline typed::union_pw_multi_aff apply(const typed::union_pw_multi_aff &upma2) const; + template + inline typed::union_pw_multi_aff apply(const typed::multi_aff &upma2) const; + template + inline typed::union_pw_multi_aff apply(const typed::pw_multi_aff &upma2) const; + inline typed::union_pw_multi_aff apply(const typed::union_pw_aff &upma2) const; + inline typed::multi_union_pw_aff as_multi_union_pw_aff() const; + inline typed::pw_multi_aff as_pw_multi_aff() const; + inline typed::union_map as_union_map() const; + inline typed::union_pw_multi_aff coalesce() const; + inline typed::union_set domain() const; + inline typed::union_pw_multi_aff drop_unused_params() const; + static inline typed::union_pw_multi_aff empty(const isl::ctx &ctx); + inline typed::pw_multi_aff extract_pw_multi_aff(const typed::space &space) const; + inline typed::union_pw_multi_aff gist(const typed::union_set &context) const; + inline typed::union_pw_multi_aff gist(const typed::basic_set &context) const; + inline typed::union_pw_multi_aff gist(const typed::point &context) const; + inline typed::union_pw_multi_aff gist(const typed::set &context) const; + inline typed::union_pw_multi_aff intersect_domain(const typed::space &space) const; + inline typed::union_pw_multi_aff intersect_domain(const typed::union_set &uset) const; + inline typed::union_pw_multi_aff intersect_domain_wrapped_domain(const typed::union_set<> &uset) const = delete; + inline typed::union_pw_multi_aff intersect_domain_wrapped_domain(const typed::basic_set<> &uset) const = delete; + inline typed::union_pw_multi_aff intersect_domain_wrapped_domain(const typed::point<> &uset) const = delete; + inline typed::union_pw_multi_aff intersect_domain_wrapped_domain(const typed::set<> &uset) const = delete; + inline typed::union_pw_multi_aff intersect_params(const typed::set<> &set) const; + inline typed::union_pw_multi_aff intersect_params(const typed::basic_set<> &set) const; + inline typed::union_pw_multi_aff intersect_params(const typed::point<> &set) const; + inline typed::union_pw_multi_aff preimage_domain_wrapped_domain(const typed::union_pw_multi_aff<> &upma2) const = delete; + inline typed::union_pw_multi_aff preimage_domain_wrapped_domain(const typed::multi_aff<> &upma2) const = delete; + inline typed::union_pw_multi_aff preimage_domain_wrapped_domain(const typed::pw_multi_aff<> &upma2) const = delete; + inline typed::union_pw_multi_aff preimage_domain_wrapped_domain(const typed::union_pw_aff<> &upma2) const = delete; + template + inline typed::union_pw_multi_aff pullback(const typed::union_pw_multi_aff &upma2) const; + inline typed::union_pw_multi_aff pullback(const typed::union_pw_multi_aff &upma2) const; + template + inline typed::union_pw_multi_aff pullback(const typed::multi_aff &upma2) const; + inline typed::union_pw_multi_aff pullback(const typed::multi_aff &upma2) const; + template + inline typed::union_pw_multi_aff pullback(const typed::pw_multi_aff &upma2) const; + inline typed::union_pw_multi_aff pullback(const typed::pw_multi_aff &upma2) const; + template + inline typed::union_pw_multi_aff pullback(const typed::union_pw_aff &upma2) const; + inline typed::union_pw_multi_aff pullback(const typed::union_pw_aff &upma2) const; + inline typed::pw_multi_aff_list pw_multi_aff_list() const; + inline typed::pw_multi_aff_list get_pw_multi_aff_list() const = delete; + inline typed::union_pw_multi_aff range_factor_domain() const = delete; + inline typed::union_pw_multi_aff range_factor_range() const = delete; + template + inline typed::union_pw_multi_aff> range_product(const typed::union_pw_multi_aff &upma2) const; + template + inline typed::union_pw_multi_aff> range_product(const typed::multi_aff &upma2) const; + template + inline typed::union_pw_multi_aff> range_product(const typed::pw_multi_aff &upma2) const; + inline typed::union_pw_multi_aff> range_product(const typed::union_pw_aff &upma2) const; + inline typed::space<> space() const; + inline typed::space get_space() const = delete; + inline typed::union_pw_multi_aff sub(const typed::union_pw_multi_aff &upma2) const; + inline typed::union_pw_multi_aff sub(const typed::multi_aff &upma2) const; + inline typed::union_pw_multi_aff sub(const typed::pw_multi_aff &upma2) const; + inline typed::union_pw_multi_aff sub(const typed::union_pw_aff &upma2) const; + inline typed::union_pw_multi_aff subtract_domain(const typed::space &space) const; + inline typed::union_pw_multi_aff subtract_domain(const typed::union_set &uset) const; + inline typed::union_pw_multi_aff union_add(const typed::union_pw_multi_aff &upma2) const; + inline typed::union_pw_multi_aff union_add(const typed::multi_aff &upma2) const; + inline typed::union_pw_multi_aff union_add(const typed::pw_multi_aff &upma2) const; + inline typed::union_pw_multi_aff union_add(const typed::union_pw_aff &upma2) const; +}; + +template +struct union_pw_multi_aff, Range> : public isl::union_pw_multi_aff { + template + friend struct aff; + template + friend struct aff_list; + template + friend struct basic_map; + template + friend struct basic_set; + template + friend struct fixed_box; + template + friend struct id; + template + friend struct id_list; + template + friend struct map; + template + friend struct map_list; + template + friend struct multi_aff; + template + friend struct multi_id; + template + friend struct multi_pw_aff; + template + friend struct multi_union_pw_aff; + template + friend struct multi_val; + template + friend struct point; + template + friend struct pw_aff; + template + friend struct pw_aff_list; + template + friend struct pw_multi_aff; + template + friend struct pw_multi_aff_list; + template + friend struct set; + template + friend struct set_list; + template + friend struct space; + template + friend struct union_map; + template + friend struct union_pw_aff; + template + friend struct union_pw_aff_list; + template + friend struct union_pw_multi_aff; + template + friend struct union_set; + template + friend struct union_set_list; + template + friend struct val; + template + friend struct val_list; + + union_pw_multi_aff() = default; + template {} && + std::is_base_of{} && + std::is_base_of{}, + bool>::type = true> + union_pw_multi_aff(const union_pw_multi_aff, Arg3> &obj) : isl::union_pw_multi_aff(obj) {} + private: + template {}, bool>::type = true> + union_pw_multi_aff(const base &obj) : isl::union_pw_multi_aff(obj) {} + public: + static union_pw_multi_aff from(const isl::union_pw_multi_aff &obj) { + return union_pw_multi_aff(obj); + } + inline /* implicit */ union_pw_multi_aff(const typed::multi_aff, Range> &ma); + inline /* implicit */ union_pw_multi_aff(const typed::pw_multi_aff, Range> &pma); + inline /* implicit */ union_pw_multi_aff(const typed::union_pw_aff, Range> &upa); + inline explicit union_pw_multi_aff(const isl::ctx &ctx, const std::string &str); + inline typed::union_pw_multi_aff, Range> add(const typed::union_pw_multi_aff, Range> &upma2) const; + inline typed::union_pw_multi_aff, Range> add(const typed::multi_aff, Range> &upma2) const; + inline typed::union_pw_multi_aff, Range> add(const typed::pw_multi_aff, Range> &upma2) const; + inline typed::union_pw_multi_aff, Range> add(const typed::union_pw_aff, Range> &upma2) const; + template + inline typed::union_pw_multi_aff, Range2> apply(const typed::union_pw_multi_aff &upma2) const; + template + inline typed::union_pw_multi_aff, Range2> apply(const typed::multi_aff &upma2) const; + template + inline typed::union_pw_multi_aff, Range2> apply(const typed::pw_multi_aff &upma2) const; + inline typed::union_pw_multi_aff, Anonymous> apply(const typed::union_pw_aff &upma2) const; + inline typed::multi_union_pw_aff, Range> as_multi_union_pw_aff() const; + inline typed::pw_multi_aff, Range> as_pw_multi_aff() const; + inline typed::union_map, Range> as_union_map() const; + inline typed::union_pw_multi_aff, Range> coalesce() const; + inline typed::union_set> domain() const; + inline typed::union_pw_multi_aff, Range> drop_unused_params() const; + static inline typed::union_pw_multi_aff, Range> empty(const isl::ctx &ctx); + inline typed::pw_multi_aff, Range> extract_pw_multi_aff(const typed::space, Range> &space) const; + inline typed::union_pw_multi_aff, Range> gist(const typed::union_set> &context) const; + inline typed::union_pw_multi_aff, Range> gist(const typed::basic_set> &context) const; + inline typed::union_pw_multi_aff, Range> gist(const typed::point> &context) const; + inline typed::union_pw_multi_aff, Range> gist(const typed::set> &context) const; + inline typed::union_pw_multi_aff, Range> intersect_domain(const typed::space> &space) const; + inline typed::union_pw_multi_aff, Range> intersect_domain(const typed::union_set> &uset) const; + inline typed::union_pw_multi_aff, Range> intersect_domain_wrapped_domain(const typed::union_set &uset) const; + inline typed::union_pw_multi_aff, Range> intersect_domain_wrapped_domain(const typed::basic_set &uset) const; + inline typed::union_pw_multi_aff, Range> intersect_domain_wrapped_domain(const typed::point &uset) const; + inline typed::union_pw_multi_aff, Range> intersect_domain_wrapped_domain(const typed::set &uset) const; + inline typed::union_pw_multi_aff, Range> intersect_params(const typed::set<> &set) const; + inline typed::union_pw_multi_aff, Range> intersect_params(const typed::basic_set<> &set) const; + inline typed::union_pw_multi_aff, Range> intersect_params(const typed::point<> &set) const; + template + inline typed::union_pw_multi_aff, Range> preimage_domain_wrapped_domain(const typed::union_pw_multi_aff &upma2) const; + template + inline typed::union_pw_multi_aff, Range> preimage_domain_wrapped_domain(const typed::multi_aff &upma2) const; + template + inline typed::union_pw_multi_aff, Range> preimage_domain_wrapped_domain(const typed::pw_multi_aff &upma2) const; + template + inline typed::union_pw_multi_aff, Range> preimage_domain_wrapped_domain(const typed::union_pw_aff &upma2) const; + template + inline typed::union_pw_multi_aff pullback(const typed::union_pw_multi_aff> &upma2) const; + inline typed::union_pw_multi_aff pullback(const typed::union_pw_multi_aff> &upma2) const; + template + inline typed::union_pw_multi_aff pullback(const typed::multi_aff> &upma2) const; + inline typed::union_pw_multi_aff pullback(const typed::multi_aff> &upma2) const; + template + inline typed::union_pw_multi_aff pullback(const typed::pw_multi_aff> &upma2) const; + inline typed::union_pw_multi_aff pullback(const typed::pw_multi_aff> &upma2) const; + template + inline typed::union_pw_multi_aff pullback(const typed::union_pw_aff> &upma2) const; + inline typed::union_pw_multi_aff pullback(const typed::union_pw_aff> &upma2) const; + inline typed::pw_multi_aff_list, Range> pw_multi_aff_list() const; + inline typed::pw_multi_aff_list, Range> get_pw_multi_aff_list() const = delete; + inline typed::union_pw_multi_aff, Range> range_factor_domain() const = delete; + inline typed::union_pw_multi_aff, Range> range_factor_range() const = delete; + template + inline typed::union_pw_multi_aff, pair> range_product(const typed::union_pw_multi_aff, Range2> &upma2) const; + template + inline typed::union_pw_multi_aff, pair> range_product(const typed::multi_aff, Range2> &upma2) const; + template + inline typed::union_pw_multi_aff, pair> range_product(const typed::pw_multi_aff, Range2> &upma2) const; + inline typed::union_pw_multi_aff, pair> range_product(const typed::union_pw_aff, Anonymous> &upma2) const; + inline typed::space<> space() const; + inline typed::space, Range> get_space() const = delete; + inline typed::union_pw_multi_aff, Range> sub(const typed::union_pw_multi_aff, Range> &upma2) const; + inline typed::union_pw_multi_aff, Range> sub(const typed::multi_aff, Range> &upma2) const; + inline typed::union_pw_multi_aff, Range> sub(const typed::pw_multi_aff, Range> &upma2) const; + inline typed::union_pw_multi_aff, Range> sub(const typed::union_pw_aff, Range> &upma2) const; + inline typed::union_pw_multi_aff, Range> subtract_domain(const typed::space> &space) const; + inline typed::union_pw_multi_aff, Range> subtract_domain(const typed::union_set> &uset) const; + inline typed::union_pw_multi_aff, Range> union_add(const typed::union_pw_multi_aff, Range> &upma2) const; + inline typed::union_pw_multi_aff, Range> union_add(const typed::multi_aff, Range> &upma2) const; + inline typed::union_pw_multi_aff, Range> union_add(const typed::pw_multi_aff, Range> &upma2) const; + inline typed::union_pw_multi_aff, Range> union_add(const typed::union_pw_aff, Range> &upma2) const; +}; + +template +struct union_pw_multi_aff> : public isl::union_pw_multi_aff { + template + friend struct aff; + template + friend struct aff_list; + template + friend struct basic_map; + template + friend struct basic_set; + template + friend struct fixed_box; + template + friend struct id; + template + friend struct id_list; + template + friend struct map; + template + friend struct map_list; + template + friend struct multi_aff; + template + friend struct multi_id; + template + friend struct multi_pw_aff; + template + friend struct multi_union_pw_aff; + template + friend struct multi_val; + template + friend struct point; + template + friend struct pw_aff; + template + friend struct pw_aff_list; + template + friend struct pw_multi_aff; + template + friend struct pw_multi_aff_list; + template + friend struct set; + template + friend struct set_list; + template + friend struct space; + template + friend struct union_map; + template + friend struct union_pw_aff; + template + friend struct union_pw_aff_list; + template + friend struct union_pw_multi_aff; + template + friend struct union_set; + template + friend struct union_set_list; + template + friend struct val; + template + friend struct val_list; + + union_pw_multi_aff() = default; + template {} && + std::is_base_of{} && + std::is_base_of{}, + bool>::type = true> + union_pw_multi_aff(const union_pw_multi_aff> &obj) : isl::union_pw_multi_aff(obj) {} + private: + template {}, bool>::type = true> + union_pw_multi_aff(const base &obj) : isl::union_pw_multi_aff(obj) {} + public: + static union_pw_multi_aff from(const isl::union_pw_multi_aff &obj) { + return union_pw_multi_aff(obj); + } + inline /* implicit */ union_pw_multi_aff(const typed::multi_aff> &ma); + inline /* implicit */ union_pw_multi_aff(const typed::pw_multi_aff> &pma); + inline /* implicit */ union_pw_multi_aff(const typed::union_pw_aff> &upa); + inline explicit union_pw_multi_aff(const isl::ctx &ctx, const std::string &str); + inline typed::union_pw_multi_aff> add(const typed::union_pw_multi_aff> &upma2) const; + inline typed::union_pw_multi_aff> add(const typed::multi_aff> &upma2) const; + inline typed::union_pw_multi_aff> add(const typed::pw_multi_aff> &upma2) const; + inline typed::union_pw_multi_aff> add(const typed::union_pw_aff> &upma2) const; + template + inline typed::union_pw_multi_aff apply(const typed::union_pw_multi_aff, Arg3> &upma2) const; + template + inline typed::union_pw_multi_aff apply(const typed::multi_aff, Arg3> &upma2) const; + template + inline typed::union_pw_multi_aff apply(const typed::pw_multi_aff, Arg3> &upma2) const; + inline typed::union_pw_multi_aff apply(const typed::union_pw_aff, Anonymous> &upma2) const; + inline typed::multi_union_pw_aff> as_multi_union_pw_aff() const; + inline typed::pw_multi_aff> as_pw_multi_aff() const; + inline typed::union_map> as_union_map() const; + inline typed::union_pw_multi_aff> coalesce() const; + inline typed::union_set domain() const; + inline typed::union_pw_multi_aff> drop_unused_params() const; + static inline typed::union_pw_multi_aff> empty(const isl::ctx &ctx); + inline typed::pw_multi_aff> extract_pw_multi_aff(const typed::space> &space) const; + inline typed::union_pw_multi_aff> gist(const typed::union_set &context) const; + inline typed::union_pw_multi_aff> gist(const typed::basic_set &context) const; + inline typed::union_pw_multi_aff> gist(const typed::point &context) const; + inline typed::union_pw_multi_aff> gist(const typed::set &context) const; + inline typed::union_pw_multi_aff> intersect_domain(const typed::space &space) const; + inline typed::union_pw_multi_aff> intersect_domain(const typed::union_set &uset) const; + inline typed::union_pw_multi_aff> intersect_domain_wrapped_domain(const typed::union_set<> &uset) const = delete; + inline typed::union_pw_multi_aff> intersect_domain_wrapped_domain(const typed::basic_set<> &uset) const = delete; + inline typed::union_pw_multi_aff> intersect_domain_wrapped_domain(const typed::point<> &uset) const = delete; + inline typed::union_pw_multi_aff> intersect_domain_wrapped_domain(const typed::set<> &uset) const = delete; + inline typed::union_pw_multi_aff> intersect_params(const typed::set<> &set) const; + inline typed::union_pw_multi_aff> intersect_params(const typed::basic_set<> &set) const; + inline typed::union_pw_multi_aff> intersect_params(const typed::point<> &set) const; + inline typed::union_pw_multi_aff> preimage_domain_wrapped_domain(const typed::union_pw_multi_aff<> &upma2) const = delete; + inline typed::union_pw_multi_aff> preimage_domain_wrapped_domain(const typed::multi_aff<> &upma2) const = delete; + inline typed::union_pw_multi_aff> preimage_domain_wrapped_domain(const typed::pw_multi_aff<> &upma2) const = delete; + inline typed::union_pw_multi_aff> preimage_domain_wrapped_domain(const typed::union_pw_aff<> &upma2) const = delete; + template + inline typed::union_pw_multi_aff> pullback(const typed::union_pw_multi_aff &upma2) const; + inline typed::union_pw_multi_aff> pullback(const typed::union_pw_multi_aff &upma2) const; + template + inline typed::union_pw_multi_aff> pullback(const typed::multi_aff &upma2) const; + inline typed::union_pw_multi_aff> pullback(const typed::multi_aff &upma2) const; + template + inline typed::union_pw_multi_aff> pullback(const typed::pw_multi_aff &upma2) const; + inline typed::union_pw_multi_aff> pullback(const typed::pw_multi_aff &upma2) const; + template + inline typed::union_pw_multi_aff> pullback(const typed::union_pw_aff &upma2) const; + inline typed::union_pw_multi_aff> pullback(const typed::union_pw_aff &upma2) const; + inline typed::pw_multi_aff_list> pw_multi_aff_list() const; + inline typed::pw_multi_aff_list> get_pw_multi_aff_list() const = delete; + inline typed::union_pw_multi_aff range_factor_domain() const; + inline typed::union_pw_multi_aff range_factor_range() const; + template + inline typed::union_pw_multi_aff, Arg3>> range_product(const typed::union_pw_multi_aff &upma2) const; + template + inline typed::union_pw_multi_aff, Arg3>> range_product(const typed::multi_aff &upma2) const; + template + inline typed::union_pw_multi_aff, Arg3>> range_product(const typed::pw_multi_aff &upma2) const; + inline typed::union_pw_multi_aff, Anonymous>> range_product(const typed::union_pw_aff &upma2) const; + inline typed::space<> space() const; + inline typed::space> get_space() const = delete; + inline typed::union_pw_multi_aff> sub(const typed::union_pw_multi_aff> &upma2) const; + inline typed::union_pw_multi_aff> sub(const typed::multi_aff> &upma2) const; + inline typed::union_pw_multi_aff> sub(const typed::pw_multi_aff> &upma2) const; + inline typed::union_pw_multi_aff> sub(const typed::union_pw_aff> &upma2) const; + inline typed::union_pw_multi_aff> subtract_domain(const typed::space &space) const; + inline typed::union_pw_multi_aff> subtract_domain(const typed::union_set &uset) const; + inline typed::union_pw_multi_aff> union_add(const typed::union_pw_multi_aff> &upma2) const; + inline typed::union_pw_multi_aff> union_add(const typed::multi_aff> &upma2) const; + inline typed::union_pw_multi_aff> union_add(const typed::pw_multi_aff> &upma2) const; + inline typed::union_pw_multi_aff> union_add(const typed::union_pw_aff> &upma2) const; +}; + +template +struct union_pw_multi_aff, pair> : public isl::union_pw_multi_aff { + template + friend struct aff; + template + friend struct aff_list; + template + friend struct basic_map; + template + friend struct basic_set; + template + friend struct fixed_box; + template + friend struct id; + template + friend struct id_list; + template + friend struct map; + template + friend struct map_list; + template + friend struct multi_aff; + template + friend struct multi_id; + template + friend struct multi_pw_aff; + template + friend struct multi_union_pw_aff; + template + friend struct multi_val; + template + friend struct point; + template + friend struct pw_aff; + template + friend struct pw_aff_list; + template + friend struct pw_multi_aff; + template + friend struct pw_multi_aff_list; + template + friend struct set; + template + friend struct set_list; + template + friend struct space; + template + friend struct union_map; + template + friend struct union_pw_aff; + template + friend struct union_pw_aff_list; + template + friend struct union_pw_multi_aff; + template + friend struct union_set; + template + friend struct union_set_list; + template + friend struct val; + template + friend struct val_list; + + union_pw_multi_aff() = default; + template {} && + std::is_base_of{} && + std::is_base_of{} && + std::is_base_of{}, + bool>::type = true> + union_pw_multi_aff(const union_pw_multi_aff, pair> &obj) : isl::union_pw_multi_aff(obj) {} + private: + template {}, bool>::type = true> + union_pw_multi_aff(const base &obj) : isl::union_pw_multi_aff(obj) {} + public: + static union_pw_multi_aff from(const isl::union_pw_multi_aff &obj) { + return union_pw_multi_aff(obj); + } + inline /* implicit */ union_pw_multi_aff(const typed::multi_aff, pair> &ma); + inline /* implicit */ union_pw_multi_aff(const typed::pw_multi_aff, pair> &pma); + inline /* implicit */ union_pw_multi_aff(const typed::union_pw_aff, pair> &upa); + inline explicit union_pw_multi_aff(const isl::ctx &ctx, const std::string &str); + inline typed::union_pw_multi_aff, pair> add(const typed::union_pw_multi_aff, pair> &upma2) const; + inline typed::union_pw_multi_aff, pair> add(const typed::multi_aff, pair> &upma2) const; + inline typed::union_pw_multi_aff, pair> add(const typed::pw_multi_aff, pair> &upma2) const; + inline typed::union_pw_multi_aff, pair> add(const typed::union_pw_aff, pair> &upma2) const; + template + inline typed::union_pw_multi_aff, Arg2> apply(const typed::union_pw_multi_aff, Arg2> &upma2) const; + template + inline typed::union_pw_multi_aff, Arg2> apply(const typed::multi_aff, Arg2> &upma2) const; + template + inline typed::union_pw_multi_aff, Arg2> apply(const typed::pw_multi_aff, Arg2> &upma2) const; + inline typed::union_pw_multi_aff, Anonymous> apply(const typed::union_pw_aff, Anonymous> &upma2) const; + inline typed::multi_union_pw_aff, pair> as_multi_union_pw_aff() const; + inline typed::pw_multi_aff, pair> as_pw_multi_aff() const; + inline typed::union_map, pair> as_union_map() const; + inline typed::union_pw_multi_aff, pair> coalesce() const; + inline typed::union_set> domain() const; + inline typed::union_pw_multi_aff, pair> drop_unused_params() const; + static inline typed::union_pw_multi_aff, pair> empty(const isl::ctx &ctx); + inline typed::pw_multi_aff, pair> extract_pw_multi_aff(const typed::space, pair> &space) const; + inline typed::union_pw_multi_aff, pair> gist(const typed::union_set> &context) const; + inline typed::union_pw_multi_aff, pair> gist(const typed::basic_set> &context) const; + inline typed::union_pw_multi_aff, pair> gist(const typed::point> &context) const; + inline typed::union_pw_multi_aff, pair> gist(const typed::set> &context) const; + inline typed::union_pw_multi_aff, pair> intersect_domain(const typed::space> &space) const; + inline typed::union_pw_multi_aff, pair> intersect_domain(const typed::union_set> &uset) const; + inline typed::union_pw_multi_aff, pair> intersect_domain_wrapped_domain(const typed::union_set &uset) const; + inline typed::union_pw_multi_aff, pair> intersect_domain_wrapped_domain(const typed::basic_set &uset) const; + inline typed::union_pw_multi_aff, pair> intersect_domain_wrapped_domain(const typed::point &uset) const; + inline typed::union_pw_multi_aff, pair> intersect_domain_wrapped_domain(const typed::set &uset) const; + inline typed::union_pw_multi_aff, pair> intersect_params(const typed::set<> &set) const; + inline typed::union_pw_multi_aff, pair> intersect_params(const typed::basic_set<> &set) const; + inline typed::union_pw_multi_aff, pair> intersect_params(const typed::point<> &set) const; + template + inline typed::union_pw_multi_aff, pair> preimage_domain_wrapped_domain(const typed::union_pw_multi_aff &upma2) const; + template + inline typed::union_pw_multi_aff, pair> preimage_domain_wrapped_domain(const typed::multi_aff &upma2) const; + template + inline typed::union_pw_multi_aff, pair> preimage_domain_wrapped_domain(const typed::pw_multi_aff &upma2) const; + template + inline typed::union_pw_multi_aff, pair> preimage_domain_wrapped_domain(const typed::union_pw_aff &upma2) const; + template + inline typed::union_pw_multi_aff> pullback(const typed::union_pw_multi_aff> &upma2) const; + inline typed::union_pw_multi_aff> pullback(const typed::union_pw_multi_aff> &upma2) const; + template + inline typed::union_pw_multi_aff> pullback(const typed::multi_aff> &upma2) const; + inline typed::union_pw_multi_aff> pullback(const typed::multi_aff> &upma2) const; + template + inline typed::union_pw_multi_aff> pullback(const typed::pw_multi_aff> &upma2) const; + inline typed::union_pw_multi_aff> pullback(const typed::pw_multi_aff> &upma2) const; + template + inline typed::union_pw_multi_aff> pullback(const typed::union_pw_aff> &upma2) const; + inline typed::union_pw_multi_aff> pullback(const typed::union_pw_aff> &upma2) const; + inline typed::pw_multi_aff_list, pair> pw_multi_aff_list() const; + inline typed::pw_multi_aff_list, pair> get_pw_multi_aff_list() const = delete; + inline typed::union_pw_multi_aff, Range> range_factor_domain() const; + inline typed::union_pw_multi_aff, Range2> range_factor_range() const; + template + inline typed::union_pw_multi_aff, pair, Arg2>> range_product(const typed::union_pw_multi_aff, Arg2> &upma2) const; + template + inline typed::union_pw_multi_aff, pair, Arg2>> range_product(const typed::multi_aff, Arg2> &upma2) const; + template + inline typed::union_pw_multi_aff, pair, Arg2>> range_product(const typed::pw_multi_aff, Arg2> &upma2) const; + inline typed::union_pw_multi_aff, pair, Anonymous>> range_product(const typed::union_pw_aff, Anonymous> &upma2) const; + inline typed::space<> space() const; + inline typed::space, pair> get_space() const = delete; + inline typed::union_pw_multi_aff, pair> sub(const typed::union_pw_multi_aff, pair> &upma2) const; + inline typed::union_pw_multi_aff, pair> sub(const typed::multi_aff, pair> &upma2) const; + inline typed::union_pw_multi_aff, pair> sub(const typed::pw_multi_aff, pair> &upma2) const; + inline typed::union_pw_multi_aff, pair> sub(const typed::union_pw_aff, pair> &upma2) const; + inline typed::union_pw_multi_aff, pair> subtract_domain(const typed::space> &space) const; + inline typed::union_pw_multi_aff, pair> subtract_domain(const typed::union_set> &uset) const; + inline typed::union_pw_multi_aff, pair> union_add(const typed::union_pw_multi_aff, pair> &upma2) const; + inline typed::union_pw_multi_aff, pair> union_add(const typed::multi_aff, pair> &upma2) const; + inline typed::union_pw_multi_aff, pair> union_add(const typed::pw_multi_aff, pair> &upma2) const; + inline typed::union_pw_multi_aff, pair> union_add(const typed::union_pw_aff, pair> &upma2) const; +}; + +template <> +struct union_set<> : public isl::union_set { + template + friend struct aff; + template + friend struct aff_list; + template + friend struct basic_map; + template + friend struct basic_set; + template + friend struct fixed_box; + template + friend struct id; + template + friend struct id_list; + template + friend struct map; + template + friend struct map_list; + template + friend struct multi_aff; + template + friend struct multi_id; + template + friend struct multi_pw_aff; + template + friend struct multi_union_pw_aff; + template + friend struct multi_val; + template + friend struct point; + template + friend struct pw_aff; + template + friend struct pw_aff_list; + template + friend struct pw_multi_aff; + template + friend struct pw_multi_aff_list; + template + friend struct set; + template + friend struct set_list; + template + friend struct space; + template + friend struct union_map; + template + friend struct union_pw_aff; + template + friend struct union_pw_aff_list; + template + friend struct union_pw_multi_aff; + template + friend struct union_set; + template + friend struct union_set_list; + template + friend struct val; + template + friend struct val_list; + + union_set() = default; + private: + template {}, bool>::type = true> + union_set(const base &obj) : isl::union_set(obj) {} + public: + static union_set from(const isl::union_set &obj) { + return union_set(obj); + } + inline /* implicit */ union_set(const typed::basic_set<> &bset); + inline /* implicit */ union_set(const typed::point<> &pnt); + inline /* implicit */ union_set(const typed::set<> &set); + inline explicit union_set(const isl::ctx &ctx, const std::string &str); + inline typed::union_set<> apply(const typed::union_map<> &umap) const = delete; + inline typed::union_set<> apply(const typed::basic_map<> &umap) const = delete; + inline typed::union_set<> apply(const typed::map<> &umap) const = delete; + inline typed::set<> as_set() const = delete; + inline typed::union_set<> coalesce() const; + inline typed::union_set<> detect_equalities() const; + inline typed::union_set<> drop_unused_params() const; + static inline typed::union_set<> empty(const isl::ctx &ctx); + inline bool every_set(const std::function)> &test) const; + inline typed::set<> extract_set(const typed::space<> &space) const; + inline void foreach_point(const std::function)> &fn) const; + inline void foreach_set(const std::function)> &fn) const; + inline typed::union_set<> gist(const typed::union_set<> &context) const; + inline typed::union_set<> gist(const typed::basic_set<> &context) const; + inline typed::union_set<> gist(const typed::point<> &context) const; + inline typed::union_set<> gist(const typed::set<> &context) const; + inline typed::union_set<> gist_params(const typed::set<> &set) const = delete; + inline typed::union_set<> gist_params(const typed::basic_set<> &set) const = delete; + inline typed::union_set<> gist_params(const typed::point<> &set) const = delete; + inline typed::union_map<> identity() const = delete; + inline typed::union_set<> intersect(const typed::union_set<> &uset2) const; + inline typed::union_set<> intersect(const typed::basic_set<> &uset2) const; + inline typed::union_set<> intersect(const typed::point<> &uset2) const; + inline typed::union_set<> intersect(const typed::set<> &uset2) const; + inline typed::union_set<> intersect_params(const typed::set<> &set) const = delete; + inline typed::union_set<> intersect_params(const typed::basic_set<> &set) const = delete; + inline typed::union_set<> intersect_params(const typed::point<> &set) const = delete; + inline typed::union_set<> lexmax() const = delete; + inline typed::union_set<> lexmin() const = delete; + inline typed::set<> params() const = delete; + inline typed::union_set<> preimage(const typed::multi_aff<> &ma) const = delete; + inline typed::union_set<> preimage(const typed::pw_multi_aff<> &pma) const = delete; + inline typed::union_set<> preimage(const typed::union_pw_multi_aff<> &upma) const = delete; + inline typed::union_set<> project_out_all_params() const; + inline typed::set_list<> set_list() const; + inline typed::set_list<> get_set_list() const = delete; + inline typed::space<> space() const; + inline typed::space<> get_space() const = delete; + inline typed::union_set<> subtract(const typed::union_set<> &uset2) const; + inline typed::union_set<> subtract(const typed::basic_set<> &uset2) const; + inline typed::union_set<> subtract(const typed::point<> &uset2) const; + inline typed::union_set<> subtract(const typed::set<> &uset2) const; + inline typed::union_set<> unite(const typed::union_set<> &uset2) const; + inline typed::union_set<> unite(const typed::basic_set<> &uset2) const; + inline typed::union_set<> unite(const typed::point<> &uset2) const; + inline typed::union_set<> unite(const typed::set<> &uset2) const; + inline typed::union_set<> universe() const; + inline typed::union_map<> unwrap() const = delete; +}; + +template +struct union_set : public isl::union_set { + template + friend struct aff; + template + friend struct aff_list; + template + friend struct basic_map; + template + friend struct basic_set; + template + friend struct fixed_box; + template + friend struct id; + template + friend struct id_list; + template + friend struct map; + template + friend struct map_list; + template + friend struct multi_aff; + template + friend struct multi_id; + template + friend struct multi_pw_aff; + template + friend struct multi_union_pw_aff; + template + friend struct multi_val; + template + friend struct point; + template + friend struct pw_aff; + template + friend struct pw_aff_list; + template + friend struct pw_multi_aff; + template + friend struct pw_multi_aff_list; + template + friend struct set; + template + friend struct set_list; + template + friend struct space; + template + friend struct union_map; + template + friend struct union_pw_aff; + template + friend struct union_pw_aff_list; + template + friend struct union_pw_multi_aff; + template + friend struct union_set; + template + friend struct union_set_list; + template + friend struct val; + template + friend struct val_list; + + union_set() = default; + template {}, + bool>::type = true> + union_set(const union_set &obj) : isl::union_set(obj) {} + private: + template {}, bool>::type = true> + union_set(const base &obj) : isl::union_set(obj) {} + public: + static union_set from(const isl::union_set &obj) { + return union_set(obj); + } + inline /* implicit */ union_set(const typed::basic_set &bset); + inline /* implicit */ union_set(const typed::point &pnt); + inline /* implicit */ union_set(const typed::set &set); + inline explicit union_set(const isl::ctx &ctx, const std::string &str); + template + inline typed::union_set apply(const typed::union_map &umap) const; + template + inline typed::union_set apply(const typed::basic_map &umap) const; + template + inline typed::union_set apply(const typed::map &umap) const; + inline typed::set as_set() const; + inline typed::union_set coalesce() const; + inline typed::union_set detect_equalities() const; + inline typed::union_set drop_unused_params() const; + static inline typed::union_set empty(const isl::ctx &ctx); + inline bool every_set(const std::function)> &test) const; + inline typed::set extract_set(const typed::space &space) const; + inline void foreach_point(const std::function)> &fn) const; + inline void foreach_set(const std::function)> &fn) const; + inline typed::union_set gist(const typed::union_set &context) const; + inline typed::union_set gist(const typed::basic_set &context) const; + inline typed::union_set gist(const typed::point &context) const; + inline typed::union_set gist(const typed::set &context) const; + inline typed::union_set gist_params(const typed::set<> &set) const; + inline typed::union_set gist_params(const typed::basic_set<> &set) const; + inline typed::union_set gist_params(const typed::point<> &set) const; + inline typed::union_map identity() const; + inline typed::union_set intersect(const typed::union_set &uset2) const; + inline typed::union_set intersect(const typed::basic_set &uset2) const; + inline typed::union_set intersect(const typed::point &uset2) const; + inline typed::union_set intersect(const typed::set &uset2) const; + inline typed::union_set intersect_params(const typed::set<> &set) const; + inline typed::union_set intersect_params(const typed::basic_set<> &set) const; + inline typed::union_set intersect_params(const typed::point<> &set) const; + inline typed::union_set lexmax() const; + inline typed::union_set lexmin() const; + inline typed::set<> params() const; + template + inline typed::union_set preimage(const typed::multi_aff &ma) const; + template + inline typed::union_set preimage(const typed::pw_multi_aff &pma) const; + template + inline typed::union_set preimage(const typed::union_pw_multi_aff &upma) const; + inline typed::union_set project_out_all_params() const; + inline typed::set_list set_list() const; + inline typed::set_list get_set_list() const = delete; + inline typed::space<> space() const; + inline typed::space get_space() const = delete; + inline typed::union_set subtract(const typed::union_set &uset2) const; + inline typed::union_set subtract(const typed::basic_set &uset2) const; + inline typed::union_set subtract(const typed::point &uset2) const; + inline typed::union_set subtract(const typed::set &uset2) const; + inline typed::union_set unite(const typed::union_set &uset2) const; + inline typed::union_set unite(const typed::basic_set &uset2) const; + inline typed::union_set unite(const typed::point &uset2) const; + inline typed::union_set unite(const typed::set &uset2) const; + inline typed::union_set universe() const; + inline typed::union_map unwrap() const = delete; +}; + +template +struct union_set> : public isl::union_set { + template + friend struct aff; + template + friend struct aff_list; + template + friend struct basic_map; + template + friend struct basic_set; + template + friend struct fixed_box; + template + friend struct id; + template + friend struct id_list; + template + friend struct map; + template + friend struct map_list; + template + friend struct multi_aff; + template + friend struct multi_id; + template + friend struct multi_pw_aff; + template + friend struct multi_union_pw_aff; + template + friend struct multi_val; + template + friend struct point; + template + friend struct pw_aff; + template + friend struct pw_aff_list; + template + friend struct pw_multi_aff; + template + friend struct pw_multi_aff_list; + template + friend struct set; + template + friend struct set_list; + template + friend struct space; + template + friend struct union_map; + template + friend struct union_pw_aff; + template + friend struct union_pw_aff_list; + template + friend struct union_pw_multi_aff; + template + friend struct union_set; + template + friend struct union_set_list; + template + friend struct val; + template + friend struct val_list; + + union_set() = default; + template {} && + std::is_base_of{}, + bool>::type = true> + union_set(const union_set> &obj) : isl::union_set(obj) {} + private: + template {}, bool>::type = true> + union_set(const base &obj) : isl::union_set(obj) {} + public: + static union_set from(const isl::union_set &obj) { + return union_set(obj); + } + inline /* implicit */ union_set(const typed::basic_set> &bset); + inline /* implicit */ union_set(const typed::point> &pnt); + inline /* implicit */ union_set(const typed::set> &set); + inline explicit union_set(const isl::ctx &ctx, const std::string &str); + template + inline typed::union_set apply(const typed::union_map, Arg2> &umap) const; + template + inline typed::union_set apply(const typed::basic_map, Arg2> &umap) const; + template + inline typed::union_set apply(const typed::map, Arg2> &umap) const; + inline typed::set> as_set() const; + inline typed::union_set> coalesce() const; + inline typed::union_set> detect_equalities() const; + inline typed::union_set> drop_unused_params() const; + static inline typed::union_set> empty(const isl::ctx &ctx); + inline bool every_set(const std::function>)> &test) const; + inline typed::set> extract_set(const typed::space> &space) const; + inline void foreach_point(const std::function>)> &fn) const; + inline void foreach_set(const std::function>)> &fn) const; + inline typed::union_set> gist(const typed::union_set> &context) const; + inline typed::union_set> gist(const typed::basic_set> &context) const; + inline typed::union_set> gist(const typed::point> &context) const; + inline typed::union_set> gist(const typed::set> &context) const; + inline typed::union_set> gist_params(const typed::set<> &set) const; + inline typed::union_set> gist_params(const typed::basic_set<> &set) const; + inline typed::union_set> gist_params(const typed::point<> &set) const; + inline typed::union_map, pair> identity() const; + inline typed::union_set> intersect(const typed::union_set> &uset2) const; + inline typed::union_set> intersect(const typed::basic_set> &uset2) const; + inline typed::union_set> intersect(const typed::point> &uset2) const; + inline typed::union_set> intersect(const typed::set> &uset2) const; + inline typed::union_set> intersect_params(const typed::set<> &set) const; + inline typed::union_set> intersect_params(const typed::basic_set<> &set) const; + inline typed::union_set> intersect_params(const typed::point<> &set) const; + inline typed::union_set> lexmax() const; + inline typed::union_set> lexmin() const; + inline typed::set<> params() const; + template + inline typed::union_set preimage(const typed::multi_aff> &ma) const; + template + inline typed::union_set preimage(const typed::pw_multi_aff> &pma) const; + template + inline typed::union_set preimage(const typed::union_pw_multi_aff> &upma) const; + inline typed::union_set> project_out_all_params() const; + inline typed::set_list> set_list() const; + inline typed::set_list> get_set_list() const = delete; + inline typed::space<> space() const; + inline typed::space> get_space() const = delete; + inline typed::union_set> subtract(const typed::union_set> &uset2) const; + inline typed::union_set> subtract(const typed::basic_set> &uset2) const; + inline typed::union_set> subtract(const typed::point> &uset2) const; + inline typed::union_set> subtract(const typed::set> &uset2) const; + inline typed::union_set> unite(const typed::union_set> &uset2) const; + inline typed::union_set> unite(const typed::basic_set> &uset2) const; + inline typed::union_set> unite(const typed::point> &uset2) const; + inline typed::union_set> unite(const typed::set> &uset2) const; + inline typed::union_set> universe() const; + inline typed::union_map unwrap() const; +}; + +template <> +struct union_set_list<> : public isl::union_set_list { + template + friend struct aff; + template + friend struct aff_list; + template + friend struct basic_map; + template + friend struct basic_set; + template + friend struct fixed_box; + template + friend struct id; + template + friend struct id_list; + template + friend struct map; + template + friend struct map_list; + template + friend struct multi_aff; + template + friend struct multi_id; + template + friend struct multi_pw_aff; + template + friend struct multi_union_pw_aff; + template + friend struct multi_val; + template + friend struct point; + template + friend struct pw_aff; + template + friend struct pw_aff_list; + template + friend struct pw_multi_aff; + template + friend struct pw_multi_aff_list; + template + friend struct set; + template + friend struct set_list; + template + friend struct space; + template + friend struct union_map; + template + friend struct union_pw_aff; + template + friend struct union_pw_aff_list; + template + friend struct union_pw_multi_aff; + template + friend struct union_set; + template + friend struct union_set_list; + template + friend struct val; + template + friend struct val_list; + + union_set_list() = default; + private: + template {}, bool>::type = true> + union_set_list(const base &obj) : isl::union_set_list(obj) {} + public: + static union_set_list from(const isl::union_set_list &obj) { + return union_set_list(obj); + } + inline explicit union_set_list(const isl::ctx &ctx, int n); + inline explicit union_set_list(const typed::union_set<> &el); + inline explicit union_set_list(const isl::ctx &ctx, const std::string &str); + inline typed::union_set_list<> add(const typed::union_set<> &el) const; + inline typed::union_set_list<> add(const typed::basic_set<> &el) const; + inline typed::union_set_list<> add(const typed::point<> &el) const; + inline typed::union_set_list<> add(const typed::set<> &el) const; + inline typed::union_set<> at(int index) const = delete; + inline typed::union_set<> get_at(int index) const = delete; + inline typed::union_set_list<> drop(unsigned int first, unsigned int n) const; + inline void foreach(const std::function)> &fn) const; + inline void foreach_scc(const std::function, typed::union_set<>)> &follows, const std::function)> &fn) const; + inline typed::union_set_list<> set_at(int index, const typed::union_set<> &el) const = delete; +}; + +template +struct union_set_list : public isl::union_set_list { + template + friend struct aff; + template + friend struct aff_list; + template + friend struct basic_map; + template + friend struct basic_set; + template + friend struct fixed_box; + template + friend struct id; + template + friend struct id_list; + template + friend struct map; + template + friend struct map_list; + template + friend struct multi_aff; + template + friend struct multi_id; + template + friend struct multi_pw_aff; + template + friend struct multi_union_pw_aff; + template + friend struct multi_val; + template + friend struct point; + template + friend struct pw_aff; + template + friend struct pw_aff_list; + template + friend struct pw_multi_aff; + template + friend struct pw_multi_aff_list; + template + friend struct set; + template + friend struct set_list; + template + friend struct space; + template + friend struct union_map; + template + friend struct union_pw_aff; + template + friend struct union_pw_aff_list; + template + friend struct union_pw_multi_aff; + template + friend struct union_set; + template + friend struct union_set_list; + template + friend struct val; + template + friend struct val_list; + + union_set_list() = default; + template {}, + bool>::type = true> + union_set_list(const union_set_list &obj) : isl::union_set_list(obj) {} + private: + template {}, bool>::type = true> + union_set_list(const base &obj) : isl::union_set_list(obj) {} + public: + static union_set_list from(const isl::union_set_list &obj) { + return union_set_list(obj); + } + inline explicit union_set_list(const isl::ctx &ctx, int n); + inline explicit union_set_list(const typed::union_set &el); + inline explicit union_set_list(const isl::ctx &ctx, const std::string &str); + inline typed::union_set_list add(const typed::union_set &el) const; + inline typed::union_set_list add(const typed::basic_set &el) const; + inline typed::union_set_list add(const typed::point &el) const; + inline typed::union_set_list add(const typed::set &el) const; + inline typed::union_set at(int index) const; + inline typed::union_set get_at(int index) const = delete; + inline typed::union_set_list drop(unsigned int first, unsigned int n) const; + inline void foreach(const std::function)> &fn) const; + inline void foreach_scc(const std::function, typed::union_set)> &follows, const std::function)> &fn) const; + inline typed::union_set_list set_at(int index, const typed::union_set &el) const; +}; + +template <> +struct val : public isl::val { + template + friend struct aff; + template + friend struct aff_list; + template + friend struct basic_map; + template + friend struct basic_set; + template + friend struct fixed_box; + template + friend struct id; + template + friend struct id_list; + template + friend struct map; + template + friend struct map_list; + template + friend struct multi_aff; + template + friend struct multi_id; + template + friend struct multi_pw_aff; + template + friend struct multi_union_pw_aff; + template + friend struct multi_val; + template + friend struct point; + template + friend struct pw_aff; + template + friend struct pw_aff_list; + template + friend struct pw_multi_aff; + template + friend struct pw_multi_aff_list; + template + friend struct set; + template + friend struct set_list; + template + friend struct space; + template + friend struct union_map; + template + friend struct union_pw_aff; + template + friend struct union_pw_aff_list; + template + friend struct union_pw_multi_aff; + template + friend struct union_set; + template + friend struct union_set_list; + template + friend struct val; + template + friend struct val_list; + + val() = default; + val(const isl::val &obj) : isl::val(obj) {} + static val from(const isl::val &obj) { + return val(obj); + } + inline explicit val(const isl::ctx &ctx, long i); + inline explicit val(const isl::ctx &ctx, const std::string &str); + inline typed::val add(const typed::val &v2) const; + inline typed::val add(long v2) const; + inline typed::val ceil() const; + inline long get_den_si() const = delete; + inline typed::val floor() const; + inline typed::val max(const typed::val &v2) const; + inline typed::val max(long v2) const; + inline typed::val min(const typed::val &v2) const; + inline typed::val min(long v2) const; + inline typed::val mod(const typed::val &v2) const; + inline typed::val mod(long v2) const; + inline typed::val neg() const; + inline long get_num_si() const = delete; + inline typed::val sub(const typed::val &v2) const; + inline typed::val sub(long v2) const; +}; + +template <> +struct val_list : public isl::val_list { + template + friend struct aff; + template + friend struct aff_list; + template + friend struct basic_map; + template + friend struct basic_set; + template + friend struct fixed_box; + template + friend struct id; + template + friend struct id_list; + template + friend struct map; + template + friend struct map_list; + template + friend struct multi_aff; + template + friend struct multi_id; + template + friend struct multi_pw_aff; + template + friend struct multi_union_pw_aff; + template + friend struct multi_val; + template + friend struct point; + template + friend struct pw_aff; + template + friend struct pw_aff_list; + template + friend struct pw_multi_aff; + template + friend struct pw_multi_aff_list; + template + friend struct set; + template + friend struct set_list; + template + friend struct space; + template + friend struct union_map; + template + friend struct union_pw_aff; + template + friend struct union_pw_aff_list; + template + friend struct union_pw_multi_aff; + template + friend struct union_set; + template + friend struct union_set_list; + template + friend struct val; + template + friend struct val_list; + + val_list() = default; + val_list(const isl::val_list &obj) : isl::val_list(obj) {} + static val_list from(const isl::val_list &obj) { + return val_list(obj); + } + inline explicit val_list(const isl::ctx &ctx, int n); + inline explicit val_list(const typed::val &el); + inline explicit val_list(const isl::ctx &ctx, const std::string &str); + inline typed::val_list add(const typed::val &el) const; + inline typed::val_list add(long el) const; + inline typed::val at(int index) const; + inline typed::val get_at(int index) const = delete; + inline typed::val_list drop(unsigned int first, unsigned int n) const; + inline void foreach(const std::function)> &fn) const; + inline void foreach_scc(const std::function, typed::val)> &follows, const std::function)> &fn) const; + inline typed::val_list set_at(int index, const typed::val &el) const; + inline typed::val_list set_at(int index, long el) const; +}; + +typed::aff::aff(const isl::ctx &ctx, const std::string &str) + : isl::aff(ctx, str) +{ +} + +typed::aff typed::aff::add(const typed::aff &aff2) const +{ + auto res = isl::aff::add(aff2); + return typed::aff(res); +} + +typed::multi_aff typed::aff::add(const typed::multi_aff &multi2) const +{ + auto res = isl::aff::add(multi2); + return typed::multi_aff(res); +} + +typed::multi_pw_aff typed::aff::add(const typed::multi_pw_aff &multi2) const +{ + auto res = isl::aff::add(multi2); + return typed::multi_pw_aff(res); +} + +typed::multi_union_pw_aff typed::aff::add(const typed::multi_union_pw_aff &multi2) const +{ + auto res = isl::aff::add(multi2); + return typed::multi_union_pw_aff(res); +} + +typed::pw_aff typed::aff::add(const typed::pw_aff &pwaff2) const +{ + auto res = isl::aff::add(pwaff2); + return typed::pw_aff(res); +} + +typed::pw_multi_aff typed::aff::add(const typed::pw_multi_aff &pma2) const +{ + auto res = isl::aff::add(pma2); + return typed::pw_multi_aff(res); +} + +typed::union_pw_aff typed::aff::add(const typed::union_pw_aff &upa2) const +{ + auto res = isl::aff::add(upa2); + return typed::union_pw_aff(res); +} + +typed::union_pw_multi_aff typed::aff::add(const typed::union_pw_multi_aff &upma2) const +{ + auto res = isl::aff::add(upma2); + return typed::union_pw_multi_aff(res); +} + +typed::aff typed::aff::add_constant(const typed::val &v) const +{ + auto res = isl::aff::add_constant(v); + return typed::aff(res); +} + +typed::aff typed::aff::add_constant(long v) const +{ + auto res = isl::aff::add_constant(v); + return typed::aff(res); +} + +typed::multi_aff typed::aff::add_constant(const typed::multi_val &mv) const +{ + auto res = isl::aff::add_constant(mv); + return typed::multi_aff(res); +} + +template +typed::union_pw_multi_aff typed::aff::apply(const typed::union_pw_multi_aff &upma2) const +{ + auto res = isl::aff::apply(upma2); + return typed::union_pw_multi_aff(res); +} + +typed::aff typed::aff::as_aff() const +{ + auto res = isl::aff::as_aff(); + return typed::aff(res); +} + +typed::multi_aff typed::aff::as_multi_aff() const +{ + auto res = isl::aff::as_multi_aff(); + return typed::multi_aff(res); +} + +typed::multi_union_pw_aff typed::aff::as_multi_union_pw_aff() const +{ + auto res = isl::aff::as_multi_union_pw_aff(); + return typed::multi_union_pw_aff(res); +} + +typed::pw_multi_aff typed::aff::as_pw_multi_aff() const +{ + auto res = isl::aff::as_pw_multi_aff(); + return typed::pw_multi_aff(res); +} + +typed::set typed::aff::as_set() const +{ + auto res = isl::aff::as_set(); + return typed::set(res); +} + +typed::aff typed::aff::at(int pos) const +{ + auto res = isl::aff::at(pos); + return typed::aff(res); +} + +typed::basic_set<> typed::aff::bind(const typed::id &id) const +{ + auto res = isl::aff::bind(id); + return typed::basic_set<>(res); +} + +typed::basic_set<> typed::aff::bind(const std::string &id) const +{ + auto res = isl::aff::bind(id); + return typed::basic_set<>(res); +} + +typed::basic_set<> typed::aff::bind(const typed::multi_id &tuple) const +{ + auto res = isl::aff::bind(tuple); + return typed::basic_set<>(res); +} + +typed::aff typed::aff::ceil() const +{ + auto res = isl::aff::ceil(); + return typed::aff(res); +} + +typed::pw_aff typed::aff::coalesce() const +{ + auto res = isl::aff::coalesce(); + return typed::pw_aff(res); +} + +typed::pw_aff typed::aff::cond(const typed::pw_aff &pwaff_true, const typed::pw_aff &pwaff_false) const +{ + auto res = isl::aff::cond(pwaff_true, pwaff_false); + return typed::pw_aff(res); +} + +typed::multi_val typed::aff::constant_multi_val() const +{ + auto res = isl::aff::constant_multi_val(); + return typed::multi_val(res); +} + +typed::val typed::aff::constant_val() const +{ + auto res = isl::aff::constant_val(); + return typed::val(res); +} + +typed::set<> typed::aff::domain() const +{ + auto res = isl::aff::domain(); + return typed::set<>(res); +} + +typed::pw_aff typed::aff::drop_unused_params() const +{ + auto res = isl::aff::drop_unused_params(); + return typed::pw_aff(res); +} + +typed::pw_multi_aff typed::aff::extract_pw_multi_aff(const typed::space &space) const +{ + auto res = isl::aff::extract_pw_multi_aff(space); + return typed::pw_multi_aff(res); +} + +typed::aff typed::aff::floor() const +{ + auto res = isl::aff::floor(); + return typed::aff(res); +} + +typed::aff typed::aff::gist(const typed::set<> &context) const +{ + auto res = isl::aff::gist(context); + return typed::aff(res); +} + +typed::union_pw_aff typed::aff::gist(const typed::union_set<> &context) const +{ + auto res = isl::aff::gist(context); + return typed::union_pw_aff(res); +} + +typed::aff typed::aff::gist(const typed::basic_set<> &context) const +{ + auto res = isl::aff::gist(context); + return typed::aff(res); +} + +typed::aff typed::aff::gist(const typed::point<> &context) const +{ + auto res = isl::aff::gist(context); + return typed::aff(res); +} + +typed::aff typed::aff::gist_params(const typed::set<> &context) const +{ + auto res = isl::aff::gist_params(context); + return typed::aff(res); +} + +typed::aff typed::aff::gist_params(const typed::basic_set<> &context) const +{ + auto res = isl::aff::gist_params(context); + return typed::aff(res); +} + +typed::aff typed::aff::gist_params(const typed::point<> &context) const +{ + auto res = isl::aff::gist_params(context); + return typed::aff(res); +} + +typed::multi_aff typed::aff::identity() const +{ + auto res = isl::aff::identity(); + return typed::multi_aff(res); +} + +template +typed::pw_aff typed::aff::insert_domain(const typed::space &domain) const +{ + auto res = isl::aff::insert_domain(domain); + return typed::pw_aff(res); +} + +typed::pw_aff typed::aff::intersect_params(const typed::set<> &set) const +{ + auto res = isl::aff::intersect_params(set); + return typed::pw_aff(res); +} + +typed::aff_list typed::aff::list() const +{ + auto res = isl::aff::list(); + return typed::aff_list(res); +} + +typed::multi_pw_aff typed::aff::max(const typed::multi_pw_aff &multi2) const +{ + auto res = isl::aff::max(multi2); + return typed::multi_pw_aff(res); +} + +typed::pw_aff typed::aff::max(const typed::pw_aff &pwaff2) const +{ + auto res = isl::aff::max(pwaff2); + return typed::pw_aff(res); +} + +typed::multi_val typed::aff::max_multi_val() const +{ + auto res = isl::aff::max_multi_val(); + return typed::multi_val(res); +} + +typed::val typed::aff::max_val() const +{ + auto res = isl::aff::max_val(); + return typed::val(res); +} + +typed::multi_pw_aff typed::aff::min(const typed::multi_pw_aff &multi2) const +{ + auto res = isl::aff::min(multi2); + return typed::multi_pw_aff(res); +} + +typed::pw_aff typed::aff::min(const typed::pw_aff &pwaff2) const +{ + auto res = isl::aff::min(pwaff2); + return typed::pw_aff(res); +} + +typed::multi_val typed::aff::min_multi_val() const +{ + auto res = isl::aff::min_multi_val(); + return typed::multi_val(res); +} + +typed::val typed::aff::min_val() const +{ + auto res = isl::aff::min_val(); + return typed::val(res); +} + +typed::aff typed::aff::mod(const typed::val &mod) const +{ + auto res = isl::aff::mod(mod); + return typed::aff(res); +} + +typed::aff typed::aff::mod(long mod) const +{ + auto res = isl::aff::mod(mod); + return typed::aff(res); +} + +typed::aff typed::aff::neg() const +{ + auto res = isl::aff::neg(); + return typed::aff(res); +} + +typed::set<> typed::aff::params() const +{ + auto res = isl::aff::params(); + return typed::set<>(res); +} + +template +typed::multi_aff> typed::aff::product(const typed::multi_aff &multi2) const +{ + auto res = isl::aff::product(multi2); + return typed::multi_aff>(res); +} + +template +typed::multi_pw_aff> typed::aff::product(const typed::multi_pw_aff &multi2) const +{ + auto res = isl::aff::product(multi2); + return typed::multi_pw_aff>(res); +} + +template +typed::pw_multi_aff> typed::aff::product(const typed::pw_multi_aff &pma2) const +{ + auto res = isl::aff::product(pma2); + return typed::pw_multi_aff>(res); +} + +typed::pw_multi_aff_list typed::aff::pw_multi_aff_list() const +{ + auto res = isl::aff::pw_multi_aff_list(); + return typed::pw_multi_aff_list(res); +} + +typed::aff typed::aff::scale(const typed::val &v) const +{ + auto res = isl::aff::scale(v); + return typed::aff(res); +} + +typed::aff typed::aff::scale(long v) const +{ + auto res = isl::aff::scale(v); + return typed::aff(res); +} + +typed::multi_aff typed::aff::scale(const typed::multi_val &mv) const +{ + auto res = isl::aff::scale(mv); + return typed::multi_aff(res); +} + +typed::aff typed::aff::scale_down(const typed::val &v) const +{ + auto res = isl::aff::scale_down(v); + return typed::aff(res); +} + +typed::aff typed::aff::scale_down(long v) const +{ + auto res = isl::aff::scale_down(v); + return typed::aff(res); +} + +typed::multi_aff typed::aff::scale_down(const typed::multi_val &mv) const +{ + auto res = isl::aff::scale_down(mv); + return typed::multi_aff(res); +} + +typed::multi_aff typed::aff::set_at(int pos, const typed::aff &el) const +{ + auto res = isl::aff::set_at(pos, el); + return typed::multi_aff(res); +} + +typed::multi_pw_aff typed::aff::set_at(int pos, const typed::pw_aff &el) const +{ + auto res = isl::aff::set_at(pos, el); + return typed::multi_pw_aff(res); +} + +typed::multi_union_pw_aff typed::aff::set_at(int pos, const typed::union_pw_aff &el) const +{ + auto res = isl::aff::set_at(pos, el); + return typed::multi_union_pw_aff(res); +} + +template +typed::multi_aff typed::aff::set_range_tuple(const typed::id &id) const +{ + auto res = isl::aff::set_range_tuple(id); + return typed::multi_aff(res); +} + +template +typed::multi_aff typed::aff::set_range_tuple(const std::string &id) const +{ + auto res = isl::aff::set_range_tuple(id); + return typed::multi_aff(res); +} + +typed::space typed::aff::space() const +{ + auto res = isl::aff::space(); + return typed::space(res); +} + +typed::aff typed::aff::sub(const typed::aff &aff2) const +{ + auto res = isl::aff::sub(aff2); + return typed::aff(res); +} + +typed::multi_aff typed::aff::sub(const typed::multi_aff &multi2) const +{ + auto res = isl::aff::sub(multi2); + return typed::multi_aff(res); +} + +typed::multi_pw_aff typed::aff::sub(const typed::multi_pw_aff &multi2) const +{ + auto res = isl::aff::sub(multi2); + return typed::multi_pw_aff(res); +} + +typed::multi_union_pw_aff typed::aff::sub(const typed::multi_union_pw_aff &multi2) const +{ + auto res = isl::aff::sub(multi2); + return typed::multi_union_pw_aff(res); +} + +typed::pw_aff typed::aff::sub(const typed::pw_aff &pwaff2) const +{ + auto res = isl::aff::sub(pwaff2); + return typed::pw_aff(res); +} + +typed::pw_multi_aff typed::aff::sub(const typed::pw_multi_aff &pma2) const +{ + auto res = isl::aff::sub(pma2); + return typed::pw_multi_aff(res); +} + +typed::union_pw_aff typed::aff::sub(const typed::union_pw_aff &upa2) const +{ + auto res = isl::aff::sub(upa2); + return typed::union_pw_aff(res); +} + +typed::union_pw_multi_aff typed::aff::sub(const typed::union_pw_multi_aff &upma2) const +{ + auto res = isl::aff::sub(upma2); + return typed::union_pw_multi_aff(res); +} + +typed::multi_pw_aff typed::aff::to_multi_pw_aff() const +{ + auto res = isl::aff::to_multi_pw_aff(); + return typed::multi_pw_aff(res); +} + +typed::multi_union_pw_aff typed::aff::to_multi_union_pw_aff() const +{ + auto res = isl::aff::to_multi_union_pw_aff(); + return typed::multi_union_pw_aff(res); +} + +typed::pw_multi_aff typed::aff::to_pw_multi_aff() const +{ + auto res = isl::aff::to_pw_multi_aff(); + return typed::pw_multi_aff(res); +} + +typed::union_pw_aff typed::aff::to_union_pw_aff() const +{ + auto res = isl::aff::to_union_pw_aff(); + return typed::union_pw_aff(res); +} + +typed::union_pw_multi_aff typed::aff::to_union_pw_multi_aff() const +{ + auto res = isl::aff::to_union_pw_multi_aff(); + return typed::union_pw_multi_aff(res); +} + +template +typed::aff typed::aff::unbind_params_insert_domain(const typed::multi_id &domain) const +{ + auto res = isl::aff::unbind_params_insert_domain(domain); + return typed::aff(res); +} + +typed::multi_pw_aff typed::aff::union_add(const typed::multi_pw_aff &mpa2) const +{ + auto res = isl::aff::union_add(mpa2); + return typed::multi_pw_aff(res); +} + +typed::multi_union_pw_aff typed::aff::union_add(const typed::multi_union_pw_aff &mupa2) const +{ + auto res = isl::aff::union_add(mupa2); + return typed::multi_union_pw_aff(res); +} + +typed::pw_aff typed::aff::union_add(const typed::pw_aff &pwaff2) const +{ + auto res = isl::aff::union_add(pwaff2); + return typed::pw_aff(res); +} + +typed::pw_multi_aff typed::aff::union_add(const typed::pw_multi_aff &pma2) const +{ + auto res = isl::aff::union_add(pma2); + return typed::pw_multi_aff(res); +} + +typed::union_pw_aff typed::aff::union_add(const typed::union_pw_aff &upa2) const +{ + auto res = isl::aff::union_add(upa2); + return typed::union_pw_aff(res); +} + +typed::union_pw_multi_aff typed::aff::union_add(const typed::union_pw_multi_aff &upma2) const +{ + auto res = isl::aff::union_add(upma2); + return typed::union_pw_multi_aff(res); +} + +template +typed::aff::aff(const isl::ctx &ctx, const std::string &str) + : isl::aff(ctx, str) +{ +} + +template +typed::aff typed::aff::add(const typed::aff &aff2) const +{ + auto res = isl::aff::add(aff2); + return typed::aff(res); +} + +template +typed::multi_aff typed::aff::add(const typed::multi_aff &multi2) const +{ + auto res = isl::aff::add(multi2); + return typed::multi_aff(res); +} + +template +typed::multi_pw_aff typed::aff::add(const typed::multi_pw_aff &multi2) const +{ + auto res = isl::aff::add(multi2); + return typed::multi_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::aff::add(const typed::multi_union_pw_aff &multi2) const +{ + auto res = isl::aff::add(multi2); + return typed::multi_union_pw_aff(res); +} + +template +typed::pw_aff typed::aff::add(const typed::pw_aff &pwaff2) const +{ + auto res = isl::aff::add(pwaff2); + return typed::pw_aff(res); +} + +template +typed::pw_multi_aff typed::aff::add(const typed::pw_multi_aff &pma2) const +{ + auto res = isl::aff::add(pma2); + return typed::pw_multi_aff(res); +} + +template +typed::union_pw_aff typed::aff::add(const typed::union_pw_aff &upa2) const +{ + auto res = isl::aff::add(upa2); + return typed::union_pw_aff(res); +} + +template +typed::union_pw_multi_aff typed::aff::add(const typed::union_pw_multi_aff &upma2) const +{ + auto res = isl::aff::add(upma2); + return typed::union_pw_multi_aff(res); +} + +template +typed::aff typed::aff::add_constant(const typed::val &v) const +{ + auto res = isl::aff::add_constant(v); + return typed::aff(res); +} + +template +typed::aff typed::aff::add_constant(long v) const +{ + auto res = isl::aff::add_constant(v); + return typed::aff(res); +} + +template +typed::multi_aff typed::aff::add_constant(const typed::multi_val &mv) const +{ + auto res = isl::aff::add_constant(mv); + return typed::multi_aff(res); +} + +template +template +typed::union_pw_multi_aff typed::aff::apply(const typed::union_pw_multi_aff &upma2) const +{ + auto res = isl::aff::apply(upma2); + return typed::union_pw_multi_aff(res); +} + +template +typed::aff typed::aff::as_aff() const +{ + auto res = isl::aff::as_aff(); + return typed::aff(res); +} + +template +typed::map typed::aff::as_map() const +{ + auto res = isl::aff::as_map(); + return typed::map(res); +} + +template +typed::multi_aff typed::aff::as_multi_aff() const +{ + auto res = isl::aff::as_multi_aff(); + return typed::multi_aff(res); +} + +template +typed::multi_union_pw_aff typed::aff::as_multi_union_pw_aff() const +{ + auto res = isl::aff::as_multi_union_pw_aff(); + return typed::multi_union_pw_aff(res); +} + +template +typed::pw_multi_aff typed::aff::as_pw_multi_aff() const +{ + auto res = isl::aff::as_pw_multi_aff(); + return typed::pw_multi_aff(res); +} + +template +typed::union_map typed::aff::as_union_map() const +{ + auto res = isl::aff::as_union_map(); + return typed::union_map(res); +} + +template +typed::aff typed::aff::at(int pos) const +{ + auto res = isl::aff::at(pos); + return typed::aff(res); +} + +template +typed::basic_set typed::aff::bind(const typed::id &id) const +{ + auto res = isl::aff::bind(id); + return typed::basic_set(res); +} + +template +typed::basic_set typed::aff::bind(const std::string &id) const +{ + auto res = isl::aff::bind(id); + return typed::basic_set(res); +} + +template +typed::basic_set typed::aff::bind(const typed::multi_id &tuple) const +{ + auto res = isl::aff::bind(tuple); + return typed::basic_set(res); +} + +template +typed::pw_aff typed::aff::bind_domain(const typed::multi_id &tuple) const +{ + auto res = isl::aff::bind_domain(tuple); + return typed::pw_aff(res); +} + +template +typed::aff typed::aff::ceil() const +{ + auto res = isl::aff::ceil(); + return typed::aff(res); +} + +template +typed::pw_aff typed::aff::coalesce() const +{ + auto res = isl::aff::coalesce(); + return typed::pw_aff(res); +} + +template +typed::pw_aff typed::aff::cond(const typed::pw_aff &pwaff_true, const typed::pw_aff &pwaff_false) const +{ + auto res = isl::aff::cond(pwaff_true, pwaff_false); + return typed::pw_aff(res); +} + +template +typed::multi_val typed::aff::constant_multi_val() const +{ + auto res = isl::aff::constant_multi_val(); + return typed::multi_val(res); +} + +template +typed::val typed::aff::constant_val() const +{ + auto res = isl::aff::constant_val(); + return typed::val(res); +} + +template +typed::set typed::aff::domain() const +{ + auto res = isl::aff::domain(); + return typed::set(res); +} + +template +typed::pw_aff typed::aff::drop_unused_params() const +{ + auto res = isl::aff::drop_unused_params(); + return typed::pw_aff(res); +} + +template +typed::pw_multi_aff typed::aff::extract_pw_multi_aff(const typed::space &space) const +{ + auto res = isl::aff::extract_pw_multi_aff(space); + return typed::pw_multi_aff(res); +} + +template +typed::aff typed::aff::floor() const +{ + auto res = isl::aff::floor(); + return typed::aff(res); +} + +template +typed::set typed::aff::ge_set(const typed::aff &aff2) const +{ + auto res = isl::aff::ge_set(aff2); + return typed::set(res); +} + +template +typed::set typed::aff::ge_set(const typed::pw_aff &pwaff2) const +{ + auto res = isl::aff::ge_set(pwaff2); + return typed::set(res); +} + +template +typed::aff typed::aff::gist(const typed::set &context) const +{ + auto res = isl::aff::gist(context); + return typed::aff(res); +} + +template +typed::union_pw_aff typed::aff::gist(const typed::union_set &context) const +{ + auto res = isl::aff::gist(context); + return typed::union_pw_aff(res); +} + +template +typed::aff typed::aff::gist(const typed::basic_set &context) const +{ + auto res = isl::aff::gist(context); + return typed::aff(res); +} + +template +typed::aff typed::aff::gist(const typed::point &context) const +{ + auto res = isl::aff::gist(context); + return typed::aff(res); +} + +template +typed::aff typed::aff::gist_params(const typed::set<> &context) const +{ + auto res = isl::aff::gist_params(context); + return typed::aff(res); +} + +template +typed::aff typed::aff::gist_params(const typed::basic_set<> &context) const +{ + auto res = isl::aff::gist_params(context); + return typed::aff(res); +} + +template +typed::aff typed::aff::gist_params(const typed::point<> &context) const +{ + auto res = isl::aff::gist_params(context); + return typed::aff(res); +} + +template +typed::set typed::aff::gt_set(const typed::aff &aff2) const +{ + auto res = isl::aff::gt_set(aff2); + return typed::set(res); +} + +template +typed::set typed::aff::gt_set(const typed::pw_aff &pwaff2) const +{ + auto res = isl::aff::gt_set(pwaff2); + return typed::set(res); +} + +template +typed::multi_aff typed::aff::identity() const +{ + auto res = isl::aff::identity(); + return typed::multi_aff(res); +} + +template +typed::pw_aff typed::aff::intersect_domain(const typed::set &set) const +{ + auto res = isl::aff::intersect_domain(set); + return typed::pw_aff(res); +} + +template +typed::union_pw_aff typed::aff::intersect_domain(const typed::space &space) const +{ + auto res = isl::aff::intersect_domain(space); + return typed::union_pw_aff(res); +} + +template +typed::union_pw_aff typed::aff::intersect_domain(const typed::union_set &uset) const +{ + auto res = isl::aff::intersect_domain(uset); + return typed::union_pw_aff(res); +} + +template +typed::pw_aff typed::aff::intersect_params(const typed::set<> &set) const +{ + auto res = isl::aff::intersect_params(set); + return typed::pw_aff(res); +} + +template +typed::set typed::aff::le_set(const typed::aff &aff2) const +{ + auto res = isl::aff::le_set(aff2); + return typed::set(res); +} + +template +typed::set typed::aff::le_set(const typed::pw_aff &pwaff2) const +{ + auto res = isl::aff::le_set(pwaff2); + return typed::set(res); +} + +template +typed::aff_list typed::aff::list() const +{ + auto res = isl::aff::list(); + return typed::aff_list(res); +} + +template +typed::set typed::aff::lt_set(const typed::aff &aff2) const +{ + auto res = isl::aff::lt_set(aff2); + return typed::set(res); +} + +template +typed::set typed::aff::lt_set(const typed::pw_aff &pwaff2) const +{ + auto res = isl::aff::lt_set(pwaff2); + return typed::set(res); +} + +template +typed::multi_pw_aff typed::aff::max(const typed::multi_pw_aff &multi2) const +{ + auto res = isl::aff::max(multi2); + return typed::multi_pw_aff(res); +} + +template +typed::pw_aff typed::aff::max(const typed::pw_aff &pwaff2) const +{ + auto res = isl::aff::max(pwaff2); + return typed::pw_aff(res); +} + +template +typed::multi_val typed::aff::max_multi_val() const +{ + auto res = isl::aff::max_multi_val(); + return typed::multi_val(res); +} + +template +typed::val typed::aff::max_val() const +{ + auto res = isl::aff::max_val(); + return typed::val(res); +} + +template +typed::multi_pw_aff typed::aff::min(const typed::multi_pw_aff &multi2) const +{ + auto res = isl::aff::min(multi2); + return typed::multi_pw_aff(res); +} + +template +typed::pw_aff typed::aff::min(const typed::pw_aff &pwaff2) const +{ + auto res = isl::aff::min(pwaff2); + return typed::pw_aff(res); +} + +template +typed::multi_val typed::aff::min_multi_val() const +{ + auto res = isl::aff::min_multi_val(); + return typed::multi_val(res); +} + +template +typed::val typed::aff::min_val() const +{ + auto res = isl::aff::min_val(); + return typed::val(res); +} + +template +typed::aff typed::aff::mod(const typed::val &mod) const +{ + auto res = isl::aff::mod(mod); + return typed::aff(res); +} + +template +typed::aff typed::aff::mod(long mod) const +{ + auto res = isl::aff::mod(mod); + return typed::aff(res); +} + +template +typed::aff typed::aff::neg() const +{ + auto res = isl::aff::neg(); + return typed::aff(res); +} + +template +typed::set<> typed::aff::params() const +{ + auto res = isl::aff::params(); + return typed::set<>(res); +} + +template +template +typed::multi_aff, pair> typed::aff::product(const typed::multi_aff &multi2) const +{ + auto res = isl::aff::product(multi2); + return typed::multi_aff, pair>(res); +} + +template +template +typed::multi_pw_aff, pair> typed::aff::product(const typed::multi_pw_aff &multi2) const +{ + auto res = isl::aff::product(multi2); + return typed::multi_pw_aff, pair>(res); +} + +template +template +typed::pw_multi_aff, pair> typed::aff::product(const typed::pw_multi_aff &pma2) const +{ + auto res = isl::aff::product(pma2); + return typed::pw_multi_aff, pair>(res); +} + +template +template +typed::aff typed::aff::pullback(const typed::multi_aff &ma) const +{ + auto res = isl::aff::pullback(ma); + return typed::aff(res); +} + +template +typed::aff typed::aff::pullback(const typed::multi_aff &ma) const +{ + auto res = isl::aff::pullback(ma); + return typed::aff(res); +} + +template +template +typed::pw_aff typed::aff::pullback(const typed::multi_pw_aff &mpa) const +{ + auto res = isl::aff::pullback(mpa); + return typed::pw_aff(res); +} + +template +typed::pw_aff typed::aff::pullback(const typed::multi_pw_aff &mpa) const +{ + auto res = isl::aff::pullback(mpa); + return typed::pw_aff(res); +} + +template +template +typed::pw_aff typed::aff::pullback(const typed::pw_multi_aff &pma) const +{ + auto res = isl::aff::pullback(pma); + return typed::pw_aff(res); +} + +template +typed::pw_aff typed::aff::pullback(const typed::pw_multi_aff &pma) const +{ + auto res = isl::aff::pullback(pma); + return typed::pw_aff(res); +} + +template +template +typed::union_pw_aff typed::aff::pullback(const typed::union_pw_multi_aff &upma) const +{ + auto res = isl::aff::pullback(upma); + return typed::union_pw_aff(res); +} + +template +typed::union_pw_aff typed::aff::pullback(const typed::union_pw_multi_aff &upma) const +{ + auto res = isl::aff::pullback(upma); + return typed::union_pw_aff(res); +} + +template +template +typed::aff typed::aff::pullback(const typed::aff &ma) const +{ + auto res = isl::aff::pullback(ma); + return typed::aff(res); +} + +template +typed::aff typed::aff::pullback(const typed::aff &ma) const +{ + auto res = isl::aff::pullback(ma); + return typed::aff(res); +} + +template +typed::pw_multi_aff_list typed::aff::pw_multi_aff_list() const +{ + auto res = isl::aff::pw_multi_aff_list(); + return typed::pw_multi_aff_list(res); +} + +template +template +typed::multi_aff> typed::aff::range_product(const typed::multi_aff &multi2) const +{ + auto res = isl::aff::range_product(multi2); + return typed::multi_aff>(res); +} + +template +template +typed::multi_pw_aff> typed::aff::range_product(const typed::multi_pw_aff &multi2) const +{ + auto res = isl::aff::range_product(multi2); + return typed::multi_pw_aff>(res); +} + +template +template +typed::multi_union_pw_aff> typed::aff::range_product(const typed::multi_union_pw_aff &multi2) const +{ + auto res = isl::aff::range_product(multi2); + return typed::multi_union_pw_aff>(res); +} + +template +template +typed::pw_multi_aff> typed::aff::range_product(const typed::pw_multi_aff &pma2) const +{ + auto res = isl::aff::range_product(pma2); + return typed::pw_multi_aff>(res); +} + +template +template +typed::union_pw_multi_aff> typed::aff::range_product(const typed::union_pw_multi_aff &upma2) const +{ + auto res = isl::aff::range_product(upma2); + return typed::union_pw_multi_aff>(res); +} + +template +typed::aff typed::aff::scale(const typed::val &v) const +{ + auto res = isl::aff::scale(v); + return typed::aff(res); +} + +template +typed::aff typed::aff::scale(long v) const +{ + auto res = isl::aff::scale(v); + return typed::aff(res); +} + +template +typed::multi_aff typed::aff::scale(const typed::multi_val &mv) const +{ + auto res = isl::aff::scale(mv); + return typed::multi_aff(res); +} + +template +typed::aff typed::aff::scale_down(const typed::val &v) const +{ + auto res = isl::aff::scale_down(v); + return typed::aff(res); +} + +template +typed::aff typed::aff::scale_down(long v) const +{ + auto res = isl::aff::scale_down(v); + return typed::aff(res); +} + +template +typed::multi_aff typed::aff::scale_down(const typed::multi_val &mv) const +{ + auto res = isl::aff::scale_down(mv); + return typed::multi_aff(res); +} + +template +typed::multi_aff typed::aff::set_at(int pos, const typed::aff &el) const +{ + auto res = isl::aff::set_at(pos, el); + return typed::multi_aff(res); +} + +template +typed::multi_pw_aff typed::aff::set_at(int pos, const typed::pw_aff &el) const +{ + auto res = isl::aff::set_at(pos, el); + return typed::multi_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::aff::set_at(int pos, const typed::union_pw_aff &el) const +{ + auto res = isl::aff::set_at(pos, el); + return typed::multi_union_pw_aff(res); +} + +template +template +typed::multi_aff typed::aff::set_range_tuple(const typed::id &id) const +{ + auto res = isl::aff::set_range_tuple(id); + return typed::multi_aff(res); +} + +template +template +typed::multi_aff typed::aff::set_range_tuple(const std::string &id) const +{ + auto res = isl::aff::set_range_tuple(id); + return typed::multi_aff(res); +} + +template +typed::space typed::aff::space() const +{ + auto res = isl::aff::space(); + return typed::space(res); +} + +template +typed::aff typed::aff::sub(const typed::aff &aff2) const +{ + auto res = isl::aff::sub(aff2); + return typed::aff(res); +} + +template +typed::multi_aff typed::aff::sub(const typed::multi_aff &multi2) const +{ + auto res = isl::aff::sub(multi2); + return typed::multi_aff(res); +} + +template +typed::multi_pw_aff typed::aff::sub(const typed::multi_pw_aff &multi2) const +{ + auto res = isl::aff::sub(multi2); + return typed::multi_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::aff::sub(const typed::multi_union_pw_aff &multi2) const +{ + auto res = isl::aff::sub(multi2); + return typed::multi_union_pw_aff(res); +} + +template +typed::pw_aff typed::aff::sub(const typed::pw_aff &pwaff2) const +{ + auto res = isl::aff::sub(pwaff2); + return typed::pw_aff(res); +} + +template +typed::pw_multi_aff typed::aff::sub(const typed::pw_multi_aff &pma2) const +{ + auto res = isl::aff::sub(pma2); + return typed::pw_multi_aff(res); +} + +template +typed::union_pw_aff typed::aff::sub(const typed::union_pw_aff &upa2) const +{ + auto res = isl::aff::sub(upa2); + return typed::union_pw_aff(res); +} + +template +typed::union_pw_multi_aff typed::aff::sub(const typed::union_pw_multi_aff &upma2) const +{ + auto res = isl::aff::sub(upma2); + return typed::union_pw_multi_aff(res); +} + +template +typed::pw_aff typed::aff::subtract_domain(const typed::set &set) const +{ + auto res = isl::aff::subtract_domain(set); + return typed::pw_aff(res); +} + +template +typed::union_pw_aff typed::aff::subtract_domain(const typed::space &space) const +{ + auto res = isl::aff::subtract_domain(space); + return typed::union_pw_aff(res); +} + +template +typed::union_pw_aff typed::aff::subtract_domain(const typed::union_set &uset) const +{ + auto res = isl::aff::subtract_domain(uset); + return typed::union_pw_aff(res); +} + +template +typed::multi_pw_aff typed::aff::to_multi_pw_aff() const +{ + auto res = isl::aff::to_multi_pw_aff(); + return typed::multi_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::aff::to_multi_union_pw_aff() const +{ + auto res = isl::aff::to_multi_union_pw_aff(); + return typed::multi_union_pw_aff(res); +} + +template +typed::pw_multi_aff typed::aff::to_pw_multi_aff() const +{ + auto res = isl::aff::to_pw_multi_aff(); + return typed::pw_multi_aff(res); +} + +template +typed::union_pw_aff typed::aff::to_union_pw_aff() const +{ + auto res = isl::aff::to_union_pw_aff(); + return typed::union_pw_aff(res); +} + +template +typed::union_pw_multi_aff typed::aff::to_union_pw_multi_aff() const +{ + auto res = isl::aff::to_union_pw_multi_aff(); + return typed::union_pw_multi_aff(res); +} + +template +typed::multi_pw_aff typed::aff::union_add(const typed::multi_pw_aff &mpa2) const +{ + auto res = isl::aff::union_add(mpa2); + return typed::multi_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::aff::union_add(const typed::multi_union_pw_aff &mupa2) const +{ + auto res = isl::aff::union_add(mupa2); + return typed::multi_union_pw_aff(res); +} + +template +typed::pw_aff typed::aff::union_add(const typed::pw_aff &pwaff2) const +{ + auto res = isl::aff::union_add(pwaff2); + return typed::pw_aff(res); +} + +template +typed::pw_multi_aff typed::aff::union_add(const typed::pw_multi_aff &pma2) const +{ + auto res = isl::aff::union_add(pma2); + return typed::pw_multi_aff(res); +} + +template +typed::union_pw_aff typed::aff::union_add(const typed::union_pw_aff &upa2) const +{ + auto res = isl::aff::union_add(upa2); + return typed::union_pw_aff(res); +} + +template +typed::union_pw_multi_aff typed::aff::union_add(const typed::union_pw_multi_aff &upma2) const +{ + auto res = isl::aff::union_add(upma2); + return typed::union_pw_multi_aff(res); +} + +template +typed::aff, Anonymous>::aff(const isl::ctx &ctx, const std::string &str) + : isl::aff(ctx, str) +{ +} + +template +typed::aff, Anonymous> typed::aff, Anonymous>::add(const typed::aff, Anonymous> &aff2) const +{ + auto res = isl::aff::add(aff2); + return typed::aff, Anonymous>(res); +} + +template +typed::multi_aff, Anonymous> typed::aff, Anonymous>::add(const typed::multi_aff, Anonymous> &multi2) const +{ + auto res = isl::aff::add(multi2); + return typed::multi_aff, Anonymous>(res); +} + +template +typed::multi_pw_aff, Anonymous> typed::aff, Anonymous>::add(const typed::multi_pw_aff, Anonymous> &multi2) const +{ + auto res = isl::aff::add(multi2); + return typed::multi_pw_aff, Anonymous>(res); +} + +template +typed::multi_union_pw_aff, Anonymous> typed::aff, Anonymous>::add(const typed::multi_union_pw_aff, Anonymous> &multi2) const +{ + auto res = isl::aff::add(multi2); + return typed::multi_union_pw_aff, Anonymous>(res); +} + +template +typed::pw_aff, Anonymous> typed::aff, Anonymous>::add(const typed::pw_aff, Anonymous> &pwaff2) const +{ + auto res = isl::aff::add(pwaff2); + return typed::pw_aff, Anonymous>(res); +} + +template +typed::pw_multi_aff, Anonymous> typed::aff, Anonymous>::add(const typed::pw_multi_aff, Anonymous> &pma2) const +{ + auto res = isl::aff::add(pma2); + return typed::pw_multi_aff, Anonymous>(res); +} + +template +typed::union_pw_aff, Anonymous> typed::aff, Anonymous>::add(const typed::union_pw_aff, Anonymous> &upa2) const +{ + auto res = isl::aff::add(upa2); + return typed::union_pw_aff, Anonymous>(res); +} + +template +typed::union_pw_multi_aff, Anonymous> typed::aff, Anonymous>::add(const typed::union_pw_multi_aff, Anonymous> &upma2) const +{ + auto res = isl::aff::add(upma2); + return typed::union_pw_multi_aff, Anonymous>(res); +} + +template +typed::aff, Anonymous> typed::aff, Anonymous>::add_constant(const typed::val &v) const +{ + auto res = isl::aff::add_constant(v); + return typed::aff, Anonymous>(res); +} + +template +typed::aff, Anonymous> typed::aff, Anonymous>::add_constant(long v) const +{ + auto res = isl::aff::add_constant(v); + return typed::aff, Anonymous>(res); +} + +template +typed::multi_aff, Anonymous> typed::aff, Anonymous>::add_constant(const typed::multi_val &mv) const +{ + auto res = isl::aff::add_constant(mv); + return typed::multi_aff, Anonymous>(res); +} + +template +template +typed::union_pw_multi_aff, Arg1> typed::aff, Anonymous>::apply(const typed::union_pw_multi_aff &upma2) const +{ + auto res = isl::aff::apply(upma2); + return typed::union_pw_multi_aff, Arg1>(res); +} + +template +typed::aff, Anonymous> typed::aff, Anonymous>::as_aff() const +{ + auto res = isl::aff::as_aff(); + return typed::aff, Anonymous>(res); +} + +template +typed::map, Anonymous> typed::aff, Anonymous>::as_map() const +{ + auto res = isl::aff::as_map(); + return typed::map, Anonymous>(res); +} + +template +typed::multi_aff, Anonymous> typed::aff, Anonymous>::as_multi_aff() const +{ + auto res = isl::aff::as_multi_aff(); + return typed::multi_aff, Anonymous>(res); +} + +template +typed::multi_union_pw_aff, Anonymous> typed::aff, Anonymous>::as_multi_union_pw_aff() const +{ + auto res = isl::aff::as_multi_union_pw_aff(); + return typed::multi_union_pw_aff, Anonymous>(res); +} + +template +typed::pw_multi_aff, Anonymous> typed::aff, Anonymous>::as_pw_multi_aff() const +{ + auto res = isl::aff::as_pw_multi_aff(); + return typed::pw_multi_aff, Anonymous>(res); +} + +template +typed::union_map, Anonymous> typed::aff, Anonymous>::as_union_map() const +{ + auto res = isl::aff::as_union_map(); + return typed::union_map, Anonymous>(res); +} + +template +typed::aff, Anonymous> typed::aff, Anonymous>::at(int pos) const +{ + auto res = isl::aff::at(pos); + return typed::aff, Anonymous>(res); +} + +template +typed::basic_set> typed::aff, Anonymous>::bind(const typed::id &id) const +{ + auto res = isl::aff::bind(id); + return typed::basic_set>(res); +} + +template +typed::basic_set> typed::aff, Anonymous>::bind(const std::string &id) const +{ + auto res = isl::aff::bind(id); + return typed::basic_set>(res); +} + +template +typed::basic_set> typed::aff, Anonymous>::bind(const typed::multi_id &tuple) const +{ + auto res = isl::aff::bind(tuple); + return typed::basic_set>(res); +} + +template +typed::pw_aff typed::aff, Anonymous>::bind_domain(const typed::multi_id> &tuple) const +{ + auto res = isl::aff::bind_domain(tuple); + return typed::pw_aff(res); +} + +template +typed::pw_aff typed::aff, Anonymous>::bind_domain_wrapped_domain(const typed::multi_id &tuple) const +{ + auto res = isl::aff::bind_domain_wrapped_domain(tuple); + return typed::pw_aff(res); +} + +template +typed::aff, Anonymous> typed::aff, Anonymous>::ceil() const +{ + auto res = isl::aff::ceil(); + return typed::aff, Anonymous>(res); +} + +template +typed::pw_aff, Anonymous> typed::aff, Anonymous>::coalesce() const +{ + auto res = isl::aff::coalesce(); + return typed::pw_aff, Anonymous>(res); +} + +template +typed::pw_aff, Anonymous> typed::aff, Anonymous>::cond(const typed::pw_aff, Anonymous> &pwaff_true, const typed::pw_aff, Anonymous> &pwaff_false) const +{ + auto res = isl::aff::cond(pwaff_true, pwaff_false); + return typed::pw_aff, Anonymous>(res); +} + +template +typed::multi_val typed::aff, Anonymous>::constant_multi_val() const +{ + auto res = isl::aff::constant_multi_val(); + return typed::multi_val(res); +} + +template +typed::val typed::aff, Anonymous>::constant_val() const +{ + auto res = isl::aff::constant_val(); + return typed::val(res); +} + +template +typed::set> typed::aff, Anonymous>::domain() const +{ + auto res = isl::aff::domain(); + return typed::set>(res); +} + +template +typed::aff, Anonymous> typed::aff, Anonymous>::domain_reverse() const +{ + auto res = isl::aff::domain_reverse(); + return typed::aff, Anonymous>(res); +} + +template +typed::pw_aff, Anonymous> typed::aff, Anonymous>::drop_unused_params() const +{ + auto res = isl::aff::drop_unused_params(); + return typed::pw_aff, Anonymous>(res); +} + +template +typed::pw_multi_aff, Anonymous> typed::aff, Anonymous>::extract_pw_multi_aff(const typed::space, Anonymous> &space) const +{ + auto res = isl::aff::extract_pw_multi_aff(space); + return typed::pw_multi_aff, Anonymous>(res); +} + +template +typed::aff, Anonymous> typed::aff, Anonymous>::floor() const +{ + auto res = isl::aff::floor(); + return typed::aff, Anonymous>(res); +} + +template +typed::set> typed::aff, Anonymous>::ge_set(const typed::aff, Anonymous> &aff2) const +{ + auto res = isl::aff::ge_set(aff2); + return typed::set>(res); +} + +template +typed::set> typed::aff, Anonymous>::ge_set(const typed::pw_aff, Anonymous> &pwaff2) const +{ + auto res = isl::aff::ge_set(pwaff2); + return typed::set>(res); +} + +template +typed::aff, Anonymous> typed::aff, Anonymous>::gist(const typed::set> &context) const +{ + auto res = isl::aff::gist(context); + return typed::aff, Anonymous>(res); +} + +template +typed::union_pw_aff, Anonymous> typed::aff, Anonymous>::gist(const typed::union_set> &context) const +{ + auto res = isl::aff::gist(context); + return typed::union_pw_aff, Anonymous>(res); +} + +template +typed::aff, Anonymous> typed::aff, Anonymous>::gist(const typed::basic_set> &context) const +{ + auto res = isl::aff::gist(context); + return typed::aff, Anonymous>(res); +} + +template +typed::aff, Anonymous> typed::aff, Anonymous>::gist(const typed::point> &context) const +{ + auto res = isl::aff::gist(context); + return typed::aff, Anonymous>(res); +} + +template +typed::aff, Anonymous> typed::aff, Anonymous>::gist_params(const typed::set<> &context) const +{ + auto res = isl::aff::gist_params(context); + return typed::aff, Anonymous>(res); +} + +template +typed::aff, Anonymous> typed::aff, Anonymous>::gist_params(const typed::basic_set<> &context) const +{ + auto res = isl::aff::gist_params(context); + return typed::aff, Anonymous>(res); +} + +template +typed::aff, Anonymous> typed::aff, Anonymous>::gist_params(const typed::point<> &context) const +{ + auto res = isl::aff::gist_params(context); + return typed::aff, Anonymous>(res); +} + +template +typed::set> typed::aff, Anonymous>::gt_set(const typed::aff, Anonymous> &aff2) const +{ + auto res = isl::aff::gt_set(aff2); + return typed::set>(res); +} + +template +typed::set> typed::aff, Anonymous>::gt_set(const typed::pw_aff, Anonymous> &pwaff2) const +{ + auto res = isl::aff::gt_set(pwaff2); + return typed::set>(res); +} + +template +typed::multi_aff, Anonymous> typed::aff, Anonymous>::identity() const +{ + auto res = isl::aff::identity(); + return typed::multi_aff, Anonymous>(res); +} + +template +typed::pw_aff, Anonymous> typed::aff, Anonymous>::intersect_domain(const typed::set> &set) const +{ + auto res = isl::aff::intersect_domain(set); + return typed::pw_aff, Anonymous>(res); +} + +template +typed::union_pw_aff, Anonymous> typed::aff, Anonymous>::intersect_domain(const typed::space> &space) const +{ + auto res = isl::aff::intersect_domain(space); + return typed::union_pw_aff, Anonymous>(res); +} + +template +typed::union_pw_aff, Anonymous> typed::aff, Anonymous>::intersect_domain(const typed::union_set> &uset) const +{ + auto res = isl::aff::intersect_domain(uset); + return typed::union_pw_aff, Anonymous>(res); +} + +template +typed::union_pw_aff, Anonymous> typed::aff, Anonymous>::intersect_domain_wrapped_domain(const typed::union_set &uset) const +{ + auto res = isl::aff::intersect_domain_wrapped_domain(uset); + return typed::union_pw_aff, Anonymous>(res); +} + +template +typed::pw_aff, Anonymous> typed::aff, Anonymous>::intersect_params(const typed::set<> &set) const +{ + auto res = isl::aff::intersect_params(set); + return typed::pw_aff, Anonymous>(res); +} + +template +typed::set> typed::aff, Anonymous>::le_set(const typed::aff, Anonymous> &aff2) const +{ + auto res = isl::aff::le_set(aff2); + return typed::set>(res); +} + +template +typed::set> typed::aff, Anonymous>::le_set(const typed::pw_aff, Anonymous> &pwaff2) const +{ + auto res = isl::aff::le_set(pwaff2); + return typed::set>(res); +} + +template +typed::aff_list, Anonymous> typed::aff, Anonymous>::list() const +{ + auto res = isl::aff::list(); + return typed::aff_list, Anonymous>(res); +} + +template +typed::set> typed::aff, Anonymous>::lt_set(const typed::aff, Anonymous> &aff2) const +{ + auto res = isl::aff::lt_set(aff2); + return typed::set>(res); +} + +template +typed::set> typed::aff, Anonymous>::lt_set(const typed::pw_aff, Anonymous> &pwaff2) const +{ + auto res = isl::aff::lt_set(pwaff2); + return typed::set>(res); +} + +template +typed::multi_pw_aff, Anonymous> typed::aff, Anonymous>::max(const typed::multi_pw_aff, Anonymous> &multi2) const +{ + auto res = isl::aff::max(multi2); + return typed::multi_pw_aff, Anonymous>(res); +} + +template +typed::pw_aff, Anonymous> typed::aff, Anonymous>::max(const typed::pw_aff, Anonymous> &pwaff2) const +{ + auto res = isl::aff::max(pwaff2); + return typed::pw_aff, Anonymous>(res); +} + +template +typed::multi_val typed::aff, Anonymous>::max_multi_val() const +{ + auto res = isl::aff::max_multi_val(); + return typed::multi_val(res); +} + +template +typed::val typed::aff, Anonymous>::max_val() const +{ + auto res = isl::aff::max_val(); + return typed::val(res); +} + +template +typed::multi_pw_aff, Anonymous> typed::aff, Anonymous>::min(const typed::multi_pw_aff, Anonymous> &multi2) const +{ + auto res = isl::aff::min(multi2); + return typed::multi_pw_aff, Anonymous>(res); +} + +template +typed::pw_aff, Anonymous> typed::aff, Anonymous>::min(const typed::pw_aff, Anonymous> &pwaff2) const +{ + auto res = isl::aff::min(pwaff2); + return typed::pw_aff, Anonymous>(res); +} + +template +typed::multi_val typed::aff, Anonymous>::min_multi_val() const +{ + auto res = isl::aff::min_multi_val(); + return typed::multi_val(res); +} + +template +typed::val typed::aff, Anonymous>::min_val() const +{ + auto res = isl::aff::min_val(); + return typed::val(res); +} + +template +typed::aff, Anonymous> typed::aff, Anonymous>::mod(const typed::val &mod) const +{ + auto res = isl::aff::mod(mod); + return typed::aff, Anonymous>(res); +} + +template +typed::aff, Anonymous> typed::aff, Anonymous>::mod(long mod) const +{ + auto res = isl::aff::mod(mod); + return typed::aff, Anonymous>(res); +} + +template +typed::aff, Anonymous> typed::aff, Anonymous>::neg() const +{ + auto res = isl::aff::neg(); + return typed::aff, Anonymous>(res); +} + +template +typed::set<> typed::aff, Anonymous>::params() const +{ + auto res = isl::aff::params(); + return typed::set<>(res); +} + +template +template +typed::pw_multi_aff, Anonymous> typed::aff, Anonymous>::preimage_domain_wrapped_domain(const typed::pw_multi_aff &pma2) const +{ + auto res = isl::aff::preimage_domain_wrapped_domain(pma2); + return typed::pw_multi_aff, Anonymous>(res); +} + +template +template +typed::union_pw_multi_aff, Anonymous> typed::aff, Anonymous>::preimage_domain_wrapped_domain(const typed::union_pw_multi_aff &upma2) const +{ + auto res = isl::aff::preimage_domain_wrapped_domain(upma2); + return typed::union_pw_multi_aff, Anonymous>(res); +} + +template +template +typed::multi_aff, Arg1>, pair> typed::aff, Anonymous>::product(const typed::multi_aff &multi2) const +{ + auto res = isl::aff::product(multi2); + return typed::multi_aff, Arg1>, pair>(res); +} + +template +template +typed::multi_pw_aff, Arg1>, pair> typed::aff, Anonymous>::product(const typed::multi_pw_aff &multi2) const +{ + auto res = isl::aff::product(multi2); + return typed::multi_pw_aff, Arg1>, pair>(res); +} + +template +template +typed::pw_multi_aff, Arg1>, pair> typed::aff, Anonymous>::product(const typed::pw_multi_aff &pma2) const +{ + auto res = isl::aff::product(pma2); + return typed::pw_multi_aff, Arg1>, pair>(res); +} + +template +template +typed::aff typed::aff, Anonymous>::pullback(const typed::multi_aff> &ma) const +{ + auto res = isl::aff::pullback(ma); + return typed::aff(res); +} + +template +typed::aff typed::aff, Anonymous>::pullback(const typed::multi_aff> &ma) const +{ + auto res = isl::aff::pullback(ma); + return typed::aff(res); +} + +template +template +typed::pw_aff typed::aff, Anonymous>::pullback(const typed::multi_pw_aff> &mpa) const +{ + auto res = isl::aff::pullback(mpa); + return typed::pw_aff(res); +} + +template +typed::pw_aff typed::aff, Anonymous>::pullback(const typed::multi_pw_aff> &mpa) const +{ + auto res = isl::aff::pullback(mpa); + return typed::pw_aff(res); +} + +template +template +typed::pw_aff typed::aff, Anonymous>::pullback(const typed::pw_multi_aff> &pma) const +{ + auto res = isl::aff::pullback(pma); + return typed::pw_aff(res); +} + +template +typed::pw_aff typed::aff, Anonymous>::pullback(const typed::pw_multi_aff> &pma) const +{ + auto res = isl::aff::pullback(pma); + return typed::pw_aff(res); +} + +template +template +typed::union_pw_aff typed::aff, Anonymous>::pullback(const typed::union_pw_multi_aff> &upma) const +{ + auto res = isl::aff::pullback(upma); + return typed::union_pw_aff(res); +} + +template +typed::union_pw_aff typed::aff, Anonymous>::pullback(const typed::union_pw_multi_aff> &upma) const +{ + auto res = isl::aff::pullback(upma); + return typed::union_pw_aff(res); +} + +template +template +typed::aff typed::aff, Anonymous>::pullback(const typed::aff> &ma) const +{ + auto res = isl::aff::pullback(ma); + return typed::aff(res); +} + +template +typed::aff typed::aff, Anonymous>::pullback(const typed::aff> &ma) const +{ + auto res = isl::aff::pullback(ma); + return typed::aff(res); +} + +template +typed::pw_multi_aff_list, Anonymous> typed::aff, Anonymous>::pw_multi_aff_list() const +{ + auto res = isl::aff::pw_multi_aff_list(); + return typed::pw_multi_aff_list, Anonymous>(res); +} + +template +template +typed::multi_aff, pair> typed::aff, Anonymous>::range_product(const typed::multi_aff, Arg1> &multi2) const +{ + auto res = isl::aff::range_product(multi2); + return typed::multi_aff, pair>(res); +} + +template +template +typed::multi_pw_aff, pair> typed::aff, Anonymous>::range_product(const typed::multi_pw_aff, Arg1> &multi2) const +{ + auto res = isl::aff::range_product(multi2); + return typed::multi_pw_aff, pair>(res); +} + +template +template +typed::multi_union_pw_aff, pair> typed::aff, Anonymous>::range_product(const typed::multi_union_pw_aff, Arg1> &multi2) const +{ + auto res = isl::aff::range_product(multi2); + return typed::multi_union_pw_aff, pair>(res); +} + +template +template +typed::pw_multi_aff, pair> typed::aff, Anonymous>::range_product(const typed::pw_multi_aff, Arg1> &pma2) const +{ + auto res = isl::aff::range_product(pma2); + return typed::pw_multi_aff, pair>(res); +} + +template +template +typed::union_pw_multi_aff, pair> typed::aff, Anonymous>::range_product(const typed::union_pw_multi_aff, Arg1> &upma2) const +{ + auto res = isl::aff::range_product(upma2); + return typed::union_pw_multi_aff, pair>(res); +} + +template +typed::aff, Anonymous> typed::aff, Anonymous>::scale(const typed::val &v) const +{ + auto res = isl::aff::scale(v); + return typed::aff, Anonymous>(res); +} + +template +typed::aff, Anonymous> typed::aff, Anonymous>::scale(long v) const +{ + auto res = isl::aff::scale(v); + return typed::aff, Anonymous>(res); +} + +template +typed::multi_aff, Anonymous> typed::aff, Anonymous>::scale(const typed::multi_val &mv) const +{ + auto res = isl::aff::scale(mv); + return typed::multi_aff, Anonymous>(res); +} + +template +typed::aff, Anonymous> typed::aff, Anonymous>::scale_down(const typed::val &v) const +{ + auto res = isl::aff::scale_down(v); + return typed::aff, Anonymous>(res); +} + +template +typed::aff, Anonymous> typed::aff, Anonymous>::scale_down(long v) const +{ + auto res = isl::aff::scale_down(v); + return typed::aff, Anonymous>(res); +} + +template +typed::multi_aff, Anonymous> typed::aff, Anonymous>::scale_down(const typed::multi_val &mv) const +{ + auto res = isl::aff::scale_down(mv); + return typed::multi_aff, Anonymous>(res); +} + +template +typed::multi_aff, Anonymous> typed::aff, Anonymous>::set_at(int pos, const typed::aff, Anonymous> &el) const +{ + auto res = isl::aff::set_at(pos, el); + return typed::multi_aff, Anonymous>(res); +} + +template +typed::multi_pw_aff, Anonymous> typed::aff, Anonymous>::set_at(int pos, const typed::pw_aff, Anonymous> &el) const +{ + auto res = isl::aff::set_at(pos, el); + return typed::multi_pw_aff, Anonymous>(res); +} + +template +typed::multi_union_pw_aff, Anonymous> typed::aff, Anonymous>::set_at(int pos, const typed::union_pw_aff, Anonymous> &el) const +{ + auto res = isl::aff::set_at(pos, el); + return typed::multi_union_pw_aff, Anonymous>(res); +} + +template +template +typed::multi_aff, Arg1> typed::aff, Anonymous>::set_range_tuple(const typed::id &id) const +{ + auto res = isl::aff::set_range_tuple(id); + return typed::multi_aff, Arg1>(res); +} + +template +template +typed::multi_aff, Arg1> typed::aff, Anonymous>::set_range_tuple(const std::string &id) const +{ + auto res = isl::aff::set_range_tuple(id); + return typed::multi_aff, Arg1>(res); +} + +template +typed::space, Anonymous> typed::aff, Anonymous>::space() const +{ + auto res = isl::aff::space(); + return typed::space, Anonymous>(res); +} + +template +typed::aff, Anonymous> typed::aff, Anonymous>::sub(const typed::aff, Anonymous> &aff2) const +{ + auto res = isl::aff::sub(aff2); + return typed::aff, Anonymous>(res); +} + +template +typed::multi_aff, Anonymous> typed::aff, Anonymous>::sub(const typed::multi_aff, Anonymous> &multi2) const +{ + auto res = isl::aff::sub(multi2); + return typed::multi_aff, Anonymous>(res); +} + +template +typed::multi_pw_aff, Anonymous> typed::aff, Anonymous>::sub(const typed::multi_pw_aff, Anonymous> &multi2) const +{ + auto res = isl::aff::sub(multi2); + return typed::multi_pw_aff, Anonymous>(res); +} + +template +typed::multi_union_pw_aff, Anonymous> typed::aff, Anonymous>::sub(const typed::multi_union_pw_aff, Anonymous> &multi2) const +{ + auto res = isl::aff::sub(multi2); + return typed::multi_union_pw_aff, Anonymous>(res); +} + +template +typed::pw_aff, Anonymous> typed::aff, Anonymous>::sub(const typed::pw_aff, Anonymous> &pwaff2) const +{ + auto res = isl::aff::sub(pwaff2); + return typed::pw_aff, Anonymous>(res); +} + +template +typed::pw_multi_aff, Anonymous> typed::aff, Anonymous>::sub(const typed::pw_multi_aff, Anonymous> &pma2) const +{ + auto res = isl::aff::sub(pma2); + return typed::pw_multi_aff, Anonymous>(res); +} + +template +typed::union_pw_aff, Anonymous> typed::aff, Anonymous>::sub(const typed::union_pw_aff, Anonymous> &upa2) const +{ + auto res = isl::aff::sub(upa2); + return typed::union_pw_aff, Anonymous>(res); +} + +template +typed::union_pw_multi_aff, Anonymous> typed::aff, Anonymous>::sub(const typed::union_pw_multi_aff, Anonymous> &upma2) const +{ + auto res = isl::aff::sub(upma2); + return typed::union_pw_multi_aff, Anonymous>(res); +} + +template +typed::pw_aff, Anonymous> typed::aff, Anonymous>::subtract_domain(const typed::set> &set) const +{ + auto res = isl::aff::subtract_domain(set); + return typed::pw_aff, Anonymous>(res); +} + +template +typed::union_pw_aff, Anonymous> typed::aff, Anonymous>::subtract_domain(const typed::space> &space) const +{ + auto res = isl::aff::subtract_domain(space); + return typed::union_pw_aff, Anonymous>(res); +} + +template +typed::union_pw_aff, Anonymous> typed::aff, Anonymous>::subtract_domain(const typed::union_set> &uset) const +{ + auto res = isl::aff::subtract_domain(uset); + return typed::union_pw_aff, Anonymous>(res); +} + +template +typed::multi_pw_aff, Anonymous> typed::aff, Anonymous>::to_multi_pw_aff() const +{ + auto res = isl::aff::to_multi_pw_aff(); + return typed::multi_pw_aff, Anonymous>(res); +} + +template +typed::multi_union_pw_aff, Anonymous> typed::aff, Anonymous>::to_multi_union_pw_aff() const +{ + auto res = isl::aff::to_multi_union_pw_aff(); + return typed::multi_union_pw_aff, Anonymous>(res); +} + +template +typed::pw_multi_aff, Anonymous> typed::aff, Anonymous>::to_pw_multi_aff() const +{ + auto res = isl::aff::to_pw_multi_aff(); + return typed::pw_multi_aff, Anonymous>(res); +} + +template +typed::union_pw_aff, Anonymous> typed::aff, Anonymous>::to_union_pw_aff() const +{ + auto res = isl::aff::to_union_pw_aff(); + return typed::union_pw_aff, Anonymous>(res); +} + +template +typed::union_pw_multi_aff, Anonymous> typed::aff, Anonymous>::to_union_pw_multi_aff() const +{ + auto res = isl::aff::to_union_pw_multi_aff(); + return typed::union_pw_multi_aff, Anonymous>(res); +} + +template +typed::multi_pw_aff, Anonymous> typed::aff, Anonymous>::union_add(const typed::multi_pw_aff, Anonymous> &mpa2) const +{ + auto res = isl::aff::union_add(mpa2); + return typed::multi_pw_aff, Anonymous>(res); +} + +template +typed::multi_union_pw_aff, Anonymous> typed::aff, Anonymous>::union_add(const typed::multi_union_pw_aff, Anonymous> &mupa2) const +{ + auto res = isl::aff::union_add(mupa2); + return typed::multi_union_pw_aff, Anonymous>(res); +} + +template +typed::pw_aff, Anonymous> typed::aff, Anonymous>::union_add(const typed::pw_aff, Anonymous> &pwaff2) const +{ + auto res = isl::aff::union_add(pwaff2); + return typed::pw_aff, Anonymous>(res); +} + +template +typed::pw_multi_aff, Anonymous> typed::aff, Anonymous>::union_add(const typed::pw_multi_aff, Anonymous> &pma2) const +{ + auto res = isl::aff::union_add(pma2); + return typed::pw_multi_aff, Anonymous>(res); +} + +template +typed::union_pw_aff, Anonymous> typed::aff, Anonymous>::union_add(const typed::union_pw_aff, Anonymous> &upa2) const +{ + auto res = isl::aff::union_add(upa2); + return typed::union_pw_aff, Anonymous>(res); +} + +template +typed::union_pw_multi_aff, Anonymous> typed::aff, Anonymous>::union_add(const typed::union_pw_multi_aff, Anonymous> &upma2) const +{ + auto res = isl::aff::union_add(upma2); + return typed::union_pw_multi_aff, Anonymous>(res); +} + +typed::aff_list::aff_list(const isl::ctx &ctx, int n) + : isl::aff_list(ctx, n) +{ +} + +typed::aff_list::aff_list(const typed::aff &el) + : isl::aff_list(el) +{ +} + +typed::aff_list::aff_list(const isl::ctx &ctx, const std::string &str) + : isl::aff_list(ctx, str) +{ +} + +typed::aff_list typed::aff_list::add(const typed::aff &el) const +{ + auto res = isl::aff_list::add(el); + return typed::aff_list(res); +} + +typed::aff typed::aff_list::at(int index) const +{ + auto res = isl::aff_list::at(index); + return typed::aff(res); +} + +typed::aff_list typed::aff_list::drop(unsigned int first, unsigned int n) const +{ + auto res = isl::aff_list::drop(first, n); + return typed::aff_list(res); +} + +void typed::aff_list::foreach(const std::function)> &fn) const +{ + auto lambda_fn = [&] (isl::aff arg0) { + return fn(typed::aff(arg0)); + }; + return isl::aff_list::foreach(lambda_fn); +} + +void typed::aff_list::foreach_scc(const std::function, typed::aff)> &follows, const std::function)> &fn) const +{ + auto lambda_follows = [&] (isl::aff arg0, isl::aff arg1) { + return follows(typed::aff(arg0), typed::aff(arg1)); + }; + auto lambda_fn = [&] (isl::aff_list arg0) { + return fn(typed::aff_list(arg0)); + }; + return isl::aff_list::foreach_scc(lambda_follows, lambda_fn); +} + +typed::aff_list typed::aff_list::set_at(int index, const typed::aff &el) const +{ + auto res = isl::aff_list::set_at(index, el); + return typed::aff_list(res); +} + +template +typed::aff_list::aff_list(const isl::ctx &ctx, int n) + : isl::aff_list(ctx, n) +{ +} + +template +typed::aff_list::aff_list(const typed::aff &el) + : isl::aff_list(el) +{ +} + +template +typed::aff_list::aff_list(const isl::ctx &ctx, const std::string &str) + : isl::aff_list(ctx, str) +{ +} + +template +typed::aff_list typed::aff_list::add(const typed::aff &el) const +{ + auto res = isl::aff_list::add(el); + return typed::aff_list(res); +} + +template +typed::aff typed::aff_list::at(int index) const +{ + auto res = isl::aff_list::at(index); + return typed::aff(res); +} + +template +typed::aff_list typed::aff_list::drop(unsigned int first, unsigned int n) const +{ + auto res = isl::aff_list::drop(first, n); + return typed::aff_list(res); +} + +template +void typed::aff_list::foreach(const std::function)> &fn) const +{ + auto lambda_fn = [&] (isl::aff arg0) { + return fn(typed::aff(arg0)); + }; + return isl::aff_list::foreach(lambda_fn); +} + +template +void typed::aff_list::foreach_scc(const std::function, typed::aff)> &follows, const std::function)> &fn) const +{ + auto lambda_follows = [&] (isl::aff arg0, isl::aff arg1) { + return follows(typed::aff(arg0), typed::aff(arg1)); + }; + auto lambda_fn = [&] (isl::aff_list arg0) { + return fn(typed::aff_list(arg0)); + }; + return isl::aff_list::foreach_scc(lambda_follows, lambda_fn); +} + +template +typed::aff_list typed::aff_list::set_at(int index, const typed::aff &el) const +{ + auto res = isl::aff_list::set_at(index, el); + return typed::aff_list(res); +} + +template +typed::basic_map::basic_map(const isl::ctx &ctx, const std::string &str) + : isl::basic_map(ctx, str) +{ +} + +template +template +typed::basic_map typed::basic_map::apply_domain(const typed::basic_map &bmap2) const +{ + auto res = isl::basic_map::apply_domain(bmap2); + return typed::basic_map(res); +} + +template +template +typed::map typed::basic_map::apply_domain(const typed::map &map2) const +{ + auto res = isl::basic_map::apply_domain(map2); + return typed::map(res); +} + +template +template +typed::union_map typed::basic_map::apply_domain(const typed::union_map &umap2) const +{ + auto res = isl::basic_map::apply_domain(umap2); + return typed::union_map(res); +} + +template +template +typed::basic_map typed::basic_map::apply_range(const typed::basic_map &bmap2) const +{ + auto res = isl::basic_map::apply_range(bmap2); + return typed::basic_map(res); +} + +template +template +typed::map typed::basic_map::apply_range(const typed::map &map2) const +{ + auto res = isl::basic_map::apply_range(map2); + return typed::map(res); +} + +template +template +typed::union_map typed::basic_map::apply_range(const typed::union_map &umap2) const +{ + auto res = isl::basic_map::apply_range(umap2); + return typed::union_map(res); +} + +template +typed::map typed::basic_map::as_map() const +{ + auto res = isl::basic_map::as_map(); + return typed::map(res); +} + +template +typed::multi_union_pw_aff typed::basic_map::as_multi_union_pw_aff() const +{ + auto res = isl::basic_map::as_multi_union_pw_aff(); + return typed::multi_union_pw_aff(res); +} + +template +typed::pw_multi_aff typed::basic_map::as_pw_multi_aff() const +{ + auto res = isl::basic_map::as_pw_multi_aff(); + return typed::pw_multi_aff(res); +} + +template +typed::union_pw_multi_aff typed::basic_map::as_union_pw_multi_aff() const +{ + auto res = isl::basic_map::as_union_pw_multi_aff(); + return typed::union_pw_multi_aff(res); +} + +template +typed::set typed::basic_map::bind_domain(const typed::multi_id &tuple) const +{ + auto res = isl::basic_map::bind_domain(tuple); + return typed::set(res); +} + +template +typed::set typed::basic_map::bind_range(const typed::multi_id &tuple) const +{ + auto res = isl::basic_map::bind_range(tuple); + return typed::set(res); +} + +template +typed::map typed::basic_map::coalesce() const +{ + auto res = isl::basic_map::coalesce(); + return typed::map(res); +} + +template +typed::basic_map typed::basic_map::detect_equalities() const +{ + auto res = isl::basic_map::detect_equalities(); + return typed::basic_map(res); +} + +template +typed::set typed::basic_map::domain() const +{ + auto res = isl::basic_map::domain(); + return typed::set(res); +} + +template +typed::union_map, Domain> typed::basic_map::domain_map() const +{ + auto res = isl::basic_map::domain_map(); + return typed::union_map, Domain>(res); +} + +template +typed::union_pw_multi_aff, Domain> typed::basic_map::domain_map_union_pw_multi_aff() const +{ + auto res = isl::basic_map::domain_map_union_pw_multi_aff(); + return typed::union_pw_multi_aff, Domain>(res); +} + +template +template +typed::map, Range> typed::basic_map::domain_product(const typed::map &map2) const +{ + auto res = isl::basic_map::domain_product(map2); + return typed::map, Range>(res); +} + +template +template +typed::union_map, Range> typed::basic_map::domain_product(const typed::union_map &umap2) const +{ + auto res = isl::basic_map::domain_product(umap2); + return typed::union_map, Range>(res); +} + +template +typed::map typed::basic_map::drop_unused_params() const +{ + auto res = isl::basic_map::drop_unused_params(); + return typed::map(res); +} + +template +bool typed::basic_map::every_map(const std::function)> &test) const +{ + auto lambda_test = [&] (isl::map arg0) { + return test(typed::map(arg0)); + }; + return isl::basic_map::every_map(lambda_test); +} + +template +typed::map typed::basic_map::extract_map(const typed::space &space) const +{ + auto res = isl::basic_map::extract_map(space); + return typed::map(res); +} + +template +void typed::basic_map::foreach_basic_map(const std::function)> &fn) const +{ + auto lambda_fn = [&] (isl::basic_map arg0) { + return fn(typed::basic_map(arg0)); + }; + return isl::basic_map::foreach_basic_map(lambda_fn); +} + +template +void typed::basic_map::foreach_map(const std::function)> &fn) const +{ + auto lambda_fn = [&] (isl::map arg0) { + return fn(typed::map(arg0)); + }; + return isl::basic_map::foreach_map(lambda_fn); +} + +template +typed::basic_map typed::basic_map::gist(const typed::basic_map &context) const +{ + auto res = isl::basic_map::gist(context); + return typed::basic_map(res); +} + +template +typed::map typed::basic_map::gist(const typed::map &context) const +{ + auto res = isl::basic_map::gist(context); + return typed::map(res); +} + +template +typed::union_map typed::basic_map::gist(const typed::union_map &context) const +{ + auto res = isl::basic_map::gist(context); + return typed::union_map(res); +} + +template +typed::map typed::basic_map::gist_domain(const typed::set &context) const +{ + auto res = isl::basic_map::gist_domain(context); + return typed::map(res); +} + +template +typed::union_map typed::basic_map::gist_domain(const typed::union_set &uset) const +{ + auto res = isl::basic_map::gist_domain(uset); + return typed::union_map(res); +} + +template +typed::map typed::basic_map::gist_params(const typed::set<> &context) const +{ + auto res = isl::basic_map::gist_params(context); + return typed::map(res); +} + +template +typed::basic_map typed::basic_map::intersect(const typed::basic_map &bmap2) const +{ + auto res = isl::basic_map::intersect(bmap2); + return typed::basic_map(res); +} + +template +typed::map typed::basic_map::intersect(const typed::map &map2) const +{ + auto res = isl::basic_map::intersect(map2); + return typed::map(res); +} + +template +typed::union_map typed::basic_map::intersect(const typed::union_map &umap2) const +{ + auto res = isl::basic_map::intersect(umap2); + return typed::union_map(res); +} + +template +typed::basic_map typed::basic_map::intersect_domain(const typed::basic_set &bset) const +{ + auto res = isl::basic_map::intersect_domain(bset); + return typed::basic_map(res); +} + +template +typed::map typed::basic_map::intersect_domain(const typed::set &set) const +{ + auto res = isl::basic_map::intersect_domain(set); + return typed::map(res); +} + +template +typed::union_map typed::basic_map::intersect_domain(const typed::space &space) const +{ + auto res = isl::basic_map::intersect_domain(space); + return typed::union_map(res); +} + +template +typed::union_map typed::basic_map::intersect_domain(const typed::union_set &uset) const +{ + auto res = isl::basic_map::intersect_domain(uset); + return typed::union_map(res); +} + +template +typed::basic_map typed::basic_map::intersect_domain(const typed::point &bset) const +{ + auto res = isl::basic_map::intersect_domain(bset); + return typed::basic_map(res); +} + +template +typed::map typed::basic_map::intersect_params(const typed::set<> ¶ms) const +{ + auto res = isl::basic_map::intersect_params(params); + return typed::map(res); +} + +template +typed::basic_map typed::basic_map::intersect_range(const typed::basic_set &bset) const +{ + auto res = isl::basic_map::intersect_range(bset); + return typed::basic_map(res); +} + +template +typed::map typed::basic_map::intersect_range(const typed::set &set) const +{ + auto res = isl::basic_map::intersect_range(set); + return typed::map(res); +} + +template +typed::union_map typed::basic_map::intersect_range(const typed::space &space) const +{ + auto res = isl::basic_map::intersect_range(space); + return typed::union_map(res); +} + +template +typed::union_map typed::basic_map::intersect_range(const typed::union_set &uset) const +{ + auto res = isl::basic_map::intersect_range(uset); + return typed::union_map(res); +} + +template +typed::basic_map typed::basic_map::intersect_range(const typed::point &bset) const +{ + auto res = isl::basic_map::intersect_range(bset); + return typed::basic_map(res); +} + +template +typed::map typed::basic_map::lexmax() const +{ + auto res = isl::basic_map::lexmax(); + return typed::map(res); +} + +template +typed::pw_multi_aff typed::basic_map::lexmax_pw_multi_aff() const +{ + auto res = isl::basic_map::lexmax_pw_multi_aff(); + return typed::pw_multi_aff(res); +} + +template +typed::map typed::basic_map::lexmin() const +{ + auto res = isl::basic_map::lexmin(); + return typed::map(res); +} + +template +typed::pw_multi_aff typed::basic_map::lexmin_pw_multi_aff() const +{ + auto res = isl::basic_map::lexmin_pw_multi_aff(); + return typed::pw_multi_aff(res); +} + +template +typed::map typed::basic_map::lower_bound(const typed::multi_pw_aff &lower) const +{ + auto res = isl::basic_map::lower_bound(lower); + return typed::map(res); +} + +template +typed::map_list typed::basic_map::map_list() const +{ + auto res = isl::basic_map::map_list(); + return typed::map_list(res); +} + +template +typed::multi_pw_aff typed::basic_map::max_multi_pw_aff() const +{ + auto res = isl::basic_map::max_multi_pw_aff(); + return typed::multi_pw_aff(res); +} + +template +typed::multi_pw_aff typed::basic_map::min_multi_pw_aff() const +{ + auto res = isl::basic_map::min_multi_pw_aff(); + return typed::multi_pw_aff(res); +} + +template +typed::set<> typed::basic_map::params() const +{ + auto res = isl::basic_map::params(); + return typed::set<>(res); +} + +template +template +typed::map typed::basic_map::preimage_domain(const typed::multi_aff &ma) const +{ + auto res = isl::basic_map::preimage_domain(ma); + return typed::map(res); +} + +template +template +typed::map typed::basic_map::preimage_domain(const typed::multi_pw_aff &mpa) const +{ + auto res = isl::basic_map::preimage_domain(mpa); + return typed::map(res); +} + +template +template +typed::map typed::basic_map::preimage_domain(const typed::pw_multi_aff &pma) const +{ + auto res = isl::basic_map::preimage_domain(pma); + return typed::map(res); +} + +template +template +typed::union_map typed::basic_map::preimage_domain(const typed::union_pw_multi_aff &upma) const +{ + auto res = isl::basic_map::preimage_domain(upma); + return typed::union_map(res); +} + +template +template +typed::map typed::basic_map::preimage_range(const typed::multi_aff &ma) const +{ + auto res = isl::basic_map::preimage_range(ma); + return typed::map(res); +} + +template +template +typed::map typed::basic_map::preimage_range(const typed::pw_multi_aff &pma) const +{ + auto res = isl::basic_map::preimage_range(pma); + return typed::map(res); +} + +template +template +typed::union_map typed::basic_map::preimage_range(const typed::union_pw_multi_aff &upma) const +{ + auto res = isl::basic_map::preimage_range(upma); + return typed::union_map(res); +} + +template +template +typed::map, pair> typed::basic_map::product(const typed::map &map2) const +{ + auto res = isl::basic_map::product(map2); + return typed::map, pair>(res); +} + +template +template +typed::union_map, pair> typed::basic_map::product(const typed::union_map &umap2) const +{ + auto res = isl::basic_map::product(umap2); + return typed::union_map, pair>(res); +} + +template +typed::map typed::basic_map::project_out_all_params() const +{ + auto res = isl::basic_map::project_out_all_params(); + return typed::map(res); +} + +template +typed::map typed::basic_map::project_out_param(const typed::id &id) const +{ + auto res = isl::basic_map::project_out_param(id); + return typed::map(res); +} + +template +typed::map typed::basic_map::project_out_param(const std::string &id) const +{ + auto res = isl::basic_map::project_out_param(id); + return typed::map(res); +} + +template +typed::map typed::basic_map::project_out_param(const typed::id_list &list) const +{ + auto res = isl::basic_map::project_out_param(list); + return typed::map(res); +} + +template +typed::set typed::basic_map::range() const +{ + auto res = isl::basic_map::range(); + return typed::set(res); +} + +template +typed::fixed_box typed::basic_map::range_lattice_tile() const +{ + auto res = isl::basic_map::range_lattice_tile(); + return typed::fixed_box(res); +} + +template +typed::union_map, Range> typed::basic_map::range_map() const +{ + auto res = isl::basic_map::range_map(); + return typed::union_map, Range>(res); +} + +template +template +typed::map> typed::basic_map::range_product(const typed::map &map2) const +{ + auto res = isl::basic_map::range_product(map2); + return typed::map>(res); +} + +template +template +typed::union_map> typed::basic_map::range_product(const typed::union_map &umap2) const +{ + auto res = isl::basic_map::range_product(umap2); + return typed::union_map>(res); +} + +template +typed::fixed_box typed::basic_map::range_simple_fixed_box_hull() const +{ + auto res = isl::basic_map::range_simple_fixed_box_hull(); + return typed::fixed_box(res); +} + +template +typed::basic_map typed::basic_map::reverse() const +{ + auto res = isl::basic_map::reverse(); + return typed::basic_map(res); +} + +template +template +typed::map typed::basic_map::set_domain_tuple(const typed::id &id) const +{ + auto res = isl::basic_map::set_domain_tuple(id); + return typed::map(res); +} + +template +template +typed::map typed::basic_map::set_domain_tuple(const std::string &id) const +{ + auto res = isl::basic_map::set_domain_tuple(id); + return typed::map(res); +} + +template +template +typed::map typed::basic_map::set_range_tuple(const typed::id &id) const +{ + auto res = isl::basic_map::set_range_tuple(id); + return typed::map(res); +} + +template +template +typed::map typed::basic_map::set_range_tuple(const std::string &id) const +{ + auto res = isl::basic_map::set_range_tuple(id); + return typed::map(res); +} + +template +typed::space typed::basic_map::space() const +{ + auto res = isl::basic_map::space(); + return typed::space(res); +} + +template +typed::map typed::basic_map::subtract(const typed::map &map2) const +{ + auto res = isl::basic_map::subtract(map2); + return typed::map(res); +} + +template +typed::union_map typed::basic_map::subtract(const typed::union_map &umap2) const +{ + auto res = isl::basic_map::subtract(umap2); + return typed::union_map(res); +} + +template +typed::union_map typed::basic_map::subtract_domain(const typed::union_set &dom) const +{ + auto res = isl::basic_map::subtract_domain(dom); + return typed::union_map(res); +} + +template +typed::union_map typed::basic_map::subtract_range(const typed::union_set &dom) const +{ + auto res = isl::basic_map::subtract_range(dom); + return typed::union_map(res); +} + +template +typed::union_map typed::basic_map::to_union_map() const +{ + auto res = isl::basic_map::to_union_map(); + return typed::union_map(res); +} + +template +typed::map typed::basic_map::unite(const typed::basic_map &bmap2) const +{ + auto res = isl::basic_map::unite(bmap2); + return typed::map(res); +} + +template +typed::map typed::basic_map::unite(const typed::map &map2) const +{ + auto res = isl::basic_map::unite(map2); + return typed::map(res); +} + +template +typed::union_map typed::basic_map::unite(const typed::union_map &umap2) const +{ + auto res = isl::basic_map::unite(umap2); + return typed::union_map(res); +} + +template +typed::map typed::basic_map::upper_bound(const typed::multi_pw_aff &upper) const +{ + auto res = isl::basic_map::upper_bound(upper); + return typed::map(res); +} + +template +typed::set> typed::basic_map::wrap() const +{ + auto res = isl::basic_map::wrap(); + return typed::set>(res); +} + +template +typed::basic_map, Range2>::basic_map(const isl::ctx &ctx, const std::string &str) + : isl::basic_map(ctx, str) +{ +} + +template +template +typed::basic_map typed::basic_map, Range2>::apply_domain(const typed::basic_map, Domain2> &bmap2) const +{ + auto res = isl::basic_map::apply_domain(bmap2); + return typed::basic_map(res); +} + +template +template +typed::map typed::basic_map, Range2>::apply_domain(const typed::map, Domain2> &map2) const +{ + auto res = isl::basic_map::apply_domain(map2); + return typed::map(res); +} + +template +template +typed::union_map typed::basic_map, Range2>::apply_domain(const typed::union_map, Domain2> &umap2) const +{ + auto res = isl::basic_map::apply_domain(umap2); + return typed::union_map(res); +} + +template +template +typed::basic_map, Arg3> typed::basic_map, Range2>::apply_range(const typed::basic_map &bmap2) const +{ + auto res = isl::basic_map::apply_range(bmap2); + return typed::basic_map, Arg3>(res); +} + +template +template +typed::map, Arg3> typed::basic_map, Range2>::apply_range(const typed::map &map2) const +{ + auto res = isl::basic_map::apply_range(map2); + return typed::map, Arg3>(res); +} + +template +template +typed::union_map, Arg3> typed::basic_map, Range2>::apply_range(const typed::union_map &umap2) const +{ + auto res = isl::basic_map::apply_range(umap2); + return typed::union_map, Arg3>(res); +} + +template +typed::map, Range2> typed::basic_map, Range2>::as_map() const +{ + auto res = isl::basic_map::as_map(); + return typed::map, Range2>(res); +} + +template +typed::multi_union_pw_aff, Range2> typed::basic_map, Range2>::as_multi_union_pw_aff() const +{ + auto res = isl::basic_map::as_multi_union_pw_aff(); + return typed::multi_union_pw_aff, Range2>(res); +} + +template +typed::pw_multi_aff, Range2> typed::basic_map, Range2>::as_pw_multi_aff() const +{ + auto res = isl::basic_map::as_pw_multi_aff(); + return typed::pw_multi_aff, Range2>(res); +} + +template +typed::union_pw_multi_aff, Range2> typed::basic_map, Range2>::as_union_pw_multi_aff() const +{ + auto res = isl::basic_map::as_union_pw_multi_aff(); + return typed::union_pw_multi_aff, Range2>(res); +} + +template +typed::set typed::basic_map, Range2>::bind_domain(const typed::multi_id> &tuple) const +{ + auto res = isl::basic_map::bind_domain(tuple); + return typed::set(res); +} + +template +typed::set> typed::basic_map, Range2>::bind_range(const typed::multi_id &tuple) const +{ + auto res = isl::basic_map::bind_range(tuple); + return typed::set>(res); +} + +template +typed::map, Range2> typed::basic_map, Range2>::coalesce() const +{ + auto res = isl::basic_map::coalesce(); + return typed::map, Range2>(res); +} + +template +typed::map> typed::basic_map, Range2>::curry() const +{ + auto res = isl::basic_map::curry(); + return typed::map>(res); +} + +template +typed::basic_map, Range2> typed::basic_map, Range2>::detect_equalities() const +{ + auto res = isl::basic_map::detect_equalities(); + return typed::basic_map, Range2>(res); +} + +template +typed::set> typed::basic_map, Range2>::domain() const +{ + auto res = isl::basic_map::domain(); + return typed::set>(res); +} + +template +typed::map typed::basic_map, Range2>::domain_factor_domain() const +{ + auto res = isl::basic_map::domain_factor_domain(); + return typed::map(res); +} + +template +typed::map typed::basic_map, Range2>::domain_factor_range() const +{ + auto res = isl::basic_map::domain_factor_range(); + return typed::map(res); +} + +template +typed::union_map, Range2>, pair> typed::basic_map, Range2>::domain_map() const +{ + auto res = isl::basic_map::domain_map(); + return typed::union_map, Range2>, pair>(res); +} + +template +typed::union_pw_multi_aff, Range2>, pair> typed::basic_map, Range2>::domain_map_union_pw_multi_aff() const +{ + auto res = isl::basic_map::domain_map_union_pw_multi_aff(); + return typed::union_pw_multi_aff, Range2>, pair>(res); +} + +template +template +typed::map, Domain2>, Range2> typed::basic_map, Range2>::domain_product(const typed::map &map2) const +{ + auto res = isl::basic_map::domain_product(map2); + return typed::map, Domain2>, Range2>(res); +} + +template +template +typed::union_map, Domain2>, Range2> typed::basic_map, Range2>::domain_product(const typed::union_map &umap2) const +{ + auto res = isl::basic_map::domain_product(umap2); + return typed::union_map, Domain2>, Range2>(res); +} + +template +typed::map, Range2> typed::basic_map, Range2>::domain_reverse() const +{ + auto res = isl::basic_map::domain_reverse(); + return typed::map, Range2>(res); +} + +template +typed::map, Range2> typed::basic_map, Range2>::drop_unused_params() const +{ + auto res = isl::basic_map::drop_unused_params(); + return typed::map, Range2>(res); +} + +template +bool typed::basic_map, Range2>::every_map(const std::function, Range2>)> &test) const +{ + auto lambda_test = [&] (isl::map arg0) { + return test(typed::map, Range2>(arg0)); + }; + return isl::basic_map::every_map(lambda_test); +} + +template +typed::map, Range2> typed::basic_map, Range2>::extract_map(const typed::space, Range2> &space) const +{ + auto res = isl::basic_map::extract_map(space); + return typed::map, Range2>(res); +} + +template +typed::basic_map typed::basic_map, Range2>::flatten_domain() const +{ + auto res = isl::basic_map::flatten_domain(); + return typed::basic_map(res); +} + +template +void typed::basic_map, Range2>::foreach_basic_map(const std::function, Range2>)> &fn) const +{ + auto lambda_fn = [&] (isl::basic_map arg0) { + return fn(typed::basic_map, Range2>(arg0)); + }; + return isl::basic_map::foreach_basic_map(lambda_fn); +} + +template +void typed::basic_map, Range2>::foreach_map(const std::function, Range2>)> &fn) const +{ + auto lambda_fn = [&] (isl::map arg0) { + return fn(typed::map, Range2>(arg0)); + }; + return isl::basic_map::foreach_map(lambda_fn); +} + +template +typed::basic_map, Range2> typed::basic_map, Range2>::gist(const typed::basic_map, Range2> &context) const +{ + auto res = isl::basic_map::gist(context); + return typed::basic_map, Range2>(res); +} + +template +typed::map, Range2> typed::basic_map, Range2>::gist(const typed::map, Range2> &context) const +{ + auto res = isl::basic_map::gist(context); + return typed::map, Range2>(res); +} + +template +typed::union_map, Range2> typed::basic_map, Range2>::gist(const typed::union_map, Range2> &context) const +{ + auto res = isl::basic_map::gist(context); + return typed::union_map, Range2>(res); +} + +template +typed::map, Range2> typed::basic_map, Range2>::gist_domain(const typed::set> &context) const +{ + auto res = isl::basic_map::gist_domain(context); + return typed::map, Range2>(res); +} + +template +typed::union_map, Range2> typed::basic_map, Range2>::gist_domain(const typed::union_set> &uset) const +{ + auto res = isl::basic_map::gist_domain(uset); + return typed::union_map, Range2>(res); +} + +template +typed::map, Range2> typed::basic_map, Range2>::gist_params(const typed::set<> &context) const +{ + auto res = isl::basic_map::gist_params(context); + return typed::map, Range2>(res); +} + +template +typed::basic_map, Range2> typed::basic_map, Range2>::intersect(const typed::basic_map, Range2> &bmap2) const +{ + auto res = isl::basic_map::intersect(bmap2); + return typed::basic_map, Range2>(res); +} + +template +typed::map, Range2> typed::basic_map, Range2>::intersect(const typed::map, Range2> &map2) const +{ + auto res = isl::basic_map::intersect(map2); + return typed::map, Range2>(res); +} + +template +typed::union_map, Range2> typed::basic_map, Range2>::intersect(const typed::union_map, Range2> &umap2) const +{ + auto res = isl::basic_map::intersect(umap2); + return typed::union_map, Range2>(res); +} + +template +typed::basic_map, Range2> typed::basic_map, Range2>::intersect_domain(const typed::basic_set> &bset) const +{ + auto res = isl::basic_map::intersect_domain(bset); + return typed::basic_map, Range2>(res); +} + +template +typed::map, Range2> typed::basic_map, Range2>::intersect_domain(const typed::set> &set) const +{ + auto res = isl::basic_map::intersect_domain(set); + return typed::map, Range2>(res); +} + +template +typed::union_map, Range2> typed::basic_map, Range2>::intersect_domain(const typed::space> &space) const +{ + auto res = isl::basic_map::intersect_domain(space); + return typed::union_map, Range2>(res); +} + +template +typed::union_map, Range2> typed::basic_map, Range2>::intersect_domain(const typed::union_set> &uset) const +{ + auto res = isl::basic_map::intersect_domain(uset); + return typed::union_map, Range2>(res); +} + +template +typed::basic_map, Range2> typed::basic_map, Range2>::intersect_domain(const typed::point> &bset) const +{ + auto res = isl::basic_map::intersect_domain(bset); + return typed::basic_map, Range2>(res); +} + +template +typed::map, Range2> typed::basic_map, Range2>::intersect_domain_wrapped_domain(const typed::set &domain) const +{ + auto res = isl::basic_map::intersect_domain_wrapped_domain(domain); + return typed::map, Range2>(res); +} + +template +typed::union_map, Range2> typed::basic_map, Range2>::intersect_domain_wrapped_domain(const typed::union_set &domain) const +{ + auto res = isl::basic_map::intersect_domain_wrapped_domain(domain); + return typed::union_map, Range2>(res); +} + +template +typed::map, Range2> typed::basic_map, Range2>::intersect_params(const typed::set<> ¶ms) const +{ + auto res = isl::basic_map::intersect_params(params); + return typed::map, Range2>(res); +} + +template +typed::basic_map, Range2> typed::basic_map, Range2>::intersect_range(const typed::basic_set &bset) const +{ + auto res = isl::basic_map::intersect_range(bset); + return typed::basic_map, Range2>(res); +} + +template +typed::map, Range2> typed::basic_map, Range2>::intersect_range(const typed::set &set) const +{ + auto res = isl::basic_map::intersect_range(set); + return typed::map, Range2>(res); +} + +template +typed::union_map, Range2> typed::basic_map, Range2>::intersect_range(const typed::space &space) const +{ + auto res = isl::basic_map::intersect_range(space); + return typed::union_map, Range2>(res); +} + +template +typed::union_map, Range2> typed::basic_map, Range2>::intersect_range(const typed::union_set &uset) const +{ + auto res = isl::basic_map::intersect_range(uset); + return typed::union_map, Range2>(res); +} + +template +typed::basic_map, Range2> typed::basic_map, Range2>::intersect_range(const typed::point &bset) const +{ + auto res = isl::basic_map::intersect_range(bset); + return typed::basic_map, Range2>(res); +} + +template +typed::map, Range2> typed::basic_map, Range2>::lexmax() const +{ + auto res = isl::basic_map::lexmax(); + return typed::map, Range2>(res); +} + +template +typed::pw_multi_aff, Range2> typed::basic_map, Range2>::lexmax_pw_multi_aff() const +{ + auto res = isl::basic_map::lexmax_pw_multi_aff(); + return typed::pw_multi_aff, Range2>(res); +} + +template +typed::map, Range2> typed::basic_map, Range2>::lexmin() const +{ + auto res = isl::basic_map::lexmin(); + return typed::map, Range2>(res); +} + +template +typed::pw_multi_aff, Range2> typed::basic_map, Range2>::lexmin_pw_multi_aff() const +{ + auto res = isl::basic_map::lexmin_pw_multi_aff(); + return typed::pw_multi_aff, Range2>(res); +} + +template +typed::map, Range2> typed::basic_map, Range2>::lower_bound(const typed::multi_pw_aff, Range2> &lower) const +{ + auto res = isl::basic_map::lower_bound(lower); + return typed::map, Range2>(res); +} + +template +typed::map_list, Range2> typed::basic_map, Range2>::map_list() const +{ + auto res = isl::basic_map::map_list(); + return typed::map_list, Range2>(res); +} + +template +typed::multi_pw_aff, Range2> typed::basic_map, Range2>::max_multi_pw_aff() const +{ + auto res = isl::basic_map::max_multi_pw_aff(); + return typed::multi_pw_aff, Range2>(res); +} + +template +typed::multi_pw_aff, Range2> typed::basic_map, Range2>::min_multi_pw_aff() const +{ + auto res = isl::basic_map::min_multi_pw_aff(); + return typed::multi_pw_aff, Range2>(res); +} + +template +typed::set<> typed::basic_map, Range2>::params() const +{ + auto res = isl::basic_map::params(); + return typed::set<>(res); +} + +template +template +typed::map typed::basic_map, Range2>::preimage_domain(const typed::multi_aff> &ma) const +{ + auto res = isl::basic_map::preimage_domain(ma); + return typed::map(res); +} + +template +template +typed::map typed::basic_map, Range2>::preimage_domain(const typed::multi_pw_aff> &mpa) const +{ + auto res = isl::basic_map::preimage_domain(mpa); + return typed::map(res); +} + +template +template +typed::map typed::basic_map, Range2>::preimage_domain(const typed::pw_multi_aff> &pma) const +{ + auto res = isl::basic_map::preimage_domain(pma); + return typed::map(res); +} + +template +template +typed::union_map typed::basic_map, Range2>::preimage_domain(const typed::union_pw_multi_aff> &upma) const +{ + auto res = isl::basic_map::preimage_domain(upma); + return typed::union_map(res); +} + +template +template +typed::map, Arg3> typed::basic_map, Range2>::preimage_range(const typed::multi_aff &ma) const +{ + auto res = isl::basic_map::preimage_range(ma); + return typed::map, Arg3>(res); +} + +template +template +typed::map, Arg3> typed::basic_map, Range2>::preimage_range(const typed::pw_multi_aff &pma) const +{ + auto res = isl::basic_map::preimage_range(pma); + return typed::map, Arg3>(res); +} + +template +template +typed::union_map, Arg3> typed::basic_map, Range2>::preimage_range(const typed::union_pw_multi_aff &upma) const +{ + auto res = isl::basic_map::preimage_range(upma); + return typed::union_map, Arg3>(res); +} + +template +template +typed::map, Domain2>, pair> typed::basic_map, Range2>::product(const typed::map &map2) const +{ + auto res = isl::basic_map::product(map2); + return typed::map, Domain2>, pair>(res); +} + +template +template +typed::union_map, Domain2>, pair> typed::basic_map, Range2>::product(const typed::union_map &umap2) const +{ + auto res = isl::basic_map::product(umap2); + return typed::union_map, Domain2>, pair>(res); +} + +template +typed::map, Range2> typed::basic_map, Range2>::project_out_all_params() const +{ + auto res = isl::basic_map::project_out_all_params(); + return typed::map, Range2>(res); +} + +template +typed::map, Range2> typed::basic_map, Range2>::project_out_param(const typed::id &id) const +{ + auto res = isl::basic_map::project_out_param(id); + return typed::map, Range2>(res); +} + +template +typed::map, Range2> typed::basic_map, Range2>::project_out_param(const std::string &id) const +{ + auto res = isl::basic_map::project_out_param(id); + return typed::map, Range2>(res); +} + +template +typed::map, Range2> typed::basic_map, Range2>::project_out_param(const typed::id_list &list) const +{ + auto res = isl::basic_map::project_out_param(list); + return typed::map, Range2>(res); +} + +template +typed::set typed::basic_map, Range2>::range() const +{ + auto res = isl::basic_map::range(); + return typed::set(res); +} + +template +typed::fixed_box, Range2> typed::basic_map, Range2>::range_lattice_tile() const +{ + auto res = isl::basic_map::range_lattice_tile(); + return typed::fixed_box, Range2>(res); +} + +template +typed::union_map, Range2>, Range2> typed::basic_map, Range2>::range_map() const +{ + auto res = isl::basic_map::range_map(); + return typed::union_map, Range2>, Range2>(res); +} + +template +template +typed::map, pair> typed::basic_map, Range2>::range_product(const typed::map, Arg3> &map2) const +{ + auto res = isl::basic_map::range_product(map2); + return typed::map, pair>(res); +} + +template +template +typed::union_map, pair> typed::basic_map, Range2>::range_product(const typed::union_map, Arg3> &umap2) const +{ + auto res = isl::basic_map::range_product(umap2); + return typed::union_map, pair>(res); +} + +template +typed::fixed_box, Range2> typed::basic_map, Range2>::range_simple_fixed_box_hull() const +{ + auto res = isl::basic_map::range_simple_fixed_box_hull(); + return typed::fixed_box, Range2>(res); +} + +template +typed::basic_map> typed::basic_map, Range2>::reverse() const +{ + auto res = isl::basic_map::reverse(); + return typed::basic_map>(res); +} + +template +template +typed::map, Arg2> typed::basic_map, Range2>::set_range_tuple(const typed::id &id) const +{ + auto res = isl::basic_map::set_range_tuple(id); + return typed::map, Arg2>(res); +} + +template +template +typed::map, Arg2> typed::basic_map, Range2>::set_range_tuple(const std::string &id) const +{ + auto res = isl::basic_map::set_range_tuple(id); + return typed::map, Arg2>(res); +} + +template +typed::space, Range2> typed::basic_map, Range2>::space() const +{ + auto res = isl::basic_map::space(); + return typed::space, Range2>(res); +} + +template +typed::map, Range2> typed::basic_map, Range2>::subtract(const typed::map, Range2> &map2) const +{ + auto res = isl::basic_map::subtract(map2); + return typed::map, Range2>(res); +} + +template +typed::union_map, Range2> typed::basic_map, Range2>::subtract(const typed::union_map, Range2> &umap2) const +{ + auto res = isl::basic_map::subtract(umap2); + return typed::union_map, Range2>(res); +} + +template +typed::union_map, Range2> typed::basic_map, Range2>::subtract_domain(const typed::union_set> &dom) const +{ + auto res = isl::basic_map::subtract_domain(dom); + return typed::union_map, Range2>(res); +} + +template +typed::union_map, Range2> typed::basic_map, Range2>::subtract_range(const typed::union_set &dom) const +{ + auto res = isl::basic_map::subtract_range(dom); + return typed::union_map, Range2>(res); +} + +template +typed::union_map, Range2> typed::basic_map, Range2>::to_union_map() const +{ + auto res = isl::basic_map::to_union_map(); + return typed::union_map, Range2>(res); +} + +template +typed::map, Range2> typed::basic_map, Range2>::unite(const typed::basic_map, Range2> &bmap2) const +{ + auto res = isl::basic_map::unite(bmap2); + return typed::map, Range2>(res); +} + +template +typed::map, Range2> typed::basic_map, Range2>::unite(const typed::map, Range2> &map2) const +{ + auto res = isl::basic_map::unite(map2); + return typed::map, Range2>(res); +} + +template +typed::union_map, Range2> typed::basic_map, Range2>::unite(const typed::union_map, Range2> &umap2) const +{ + auto res = isl::basic_map::unite(umap2); + return typed::union_map, Range2>(res); +} + +template +typed::map, Range2> typed::basic_map, Range2>::upper_bound(const typed::multi_pw_aff, Range2> &upper) const +{ + auto res = isl::basic_map::upper_bound(upper); + return typed::map, Range2>(res); +} + +template +typed::set, Range2>> typed::basic_map, Range2>::wrap() const +{ + auto res = isl::basic_map::wrap(); + return typed::set, Range2>>(res); +} + +template +typed::basic_map::basic_map(const isl::ctx &ctx, const std::string &str) + : isl::basic_map(ctx, str) +{ +} + +template +template +typed::basic_map typed::basic_map::apply_domain(const typed::basic_map &bmap2) const +{ + auto res = isl::basic_map::apply_domain(bmap2); + return typed::basic_map(res); +} + +template +template +typed::map typed::basic_map::apply_domain(const typed::map &map2) const +{ + auto res = isl::basic_map::apply_domain(map2); + return typed::map(res); +} + +template +template +typed::union_map typed::basic_map::apply_domain(const typed::union_map &umap2) const +{ + auto res = isl::basic_map::apply_domain(umap2); + return typed::union_map(res); +} + +template +template +typed::basic_map typed::basic_map::apply_range(const typed::basic_map &bmap2) const +{ + auto res = isl::basic_map::apply_range(bmap2); + return typed::basic_map(res); +} + +template +template +typed::map typed::basic_map::apply_range(const typed::map &map2) const +{ + auto res = isl::basic_map::apply_range(map2); + return typed::map(res); +} + +template +template +typed::union_map typed::basic_map::apply_range(const typed::union_map &umap2) const +{ + auto res = isl::basic_map::apply_range(umap2); + return typed::union_map(res); +} + +template +typed::map typed::basic_map::as_map() const +{ + auto res = isl::basic_map::as_map(); + return typed::map(res); +} + +template +typed::multi_union_pw_aff typed::basic_map::as_multi_union_pw_aff() const +{ + auto res = isl::basic_map::as_multi_union_pw_aff(); + return typed::multi_union_pw_aff(res); +} + +template +typed::pw_multi_aff typed::basic_map::as_pw_multi_aff() const +{ + auto res = isl::basic_map::as_pw_multi_aff(); + return typed::pw_multi_aff(res); +} + +template +typed::union_pw_multi_aff typed::basic_map::as_union_pw_multi_aff() const +{ + auto res = isl::basic_map::as_union_pw_multi_aff(); + return typed::union_pw_multi_aff(res); +} + +template +typed::set typed::basic_map::bind_domain(const typed::multi_id &tuple) const +{ + auto res = isl::basic_map::bind_domain(tuple); + return typed::set(res); +} + +template +typed::set typed::basic_map::bind_range(const typed::multi_id &tuple) const +{ + auto res = isl::basic_map::bind_range(tuple); + return typed::set(res); +} + +template +typed::map typed::basic_map::coalesce() const +{ + auto res = isl::basic_map::coalesce(); + return typed::map(res); +} + +template +typed::basic_set typed::basic_map::deltas() const +{ + auto res = isl::basic_map::deltas(); + return typed::basic_set(res); +} + +template +typed::basic_map typed::basic_map::detect_equalities() const +{ + auto res = isl::basic_map::detect_equalities(); + return typed::basic_map(res); +} + +template +typed::set typed::basic_map::domain() const +{ + auto res = isl::basic_map::domain(); + return typed::set(res); +} + +template +typed::union_map, Domain> typed::basic_map::domain_map() const +{ + auto res = isl::basic_map::domain_map(); + return typed::union_map, Domain>(res); +} + +template +typed::union_pw_multi_aff, Domain> typed::basic_map::domain_map_union_pw_multi_aff() const +{ + auto res = isl::basic_map::domain_map_union_pw_multi_aff(); + return typed::union_pw_multi_aff, Domain>(res); +} + +template +template +typed::map, Domain> typed::basic_map::domain_product(const typed::map &map2) const +{ + auto res = isl::basic_map::domain_product(map2); + return typed::map, Domain>(res); +} + +template +template +typed::union_map, Domain> typed::basic_map::domain_product(const typed::union_map &umap2) const +{ + auto res = isl::basic_map::domain_product(umap2); + return typed::union_map, Domain>(res); +} + +template +typed::map typed::basic_map::drop_unused_params() const +{ + auto res = isl::basic_map::drop_unused_params(); + return typed::map(res); +} + +template +template +typed::map typed::basic_map::eq_at(const typed::multi_pw_aff &mpa) const +{ + auto res = isl::basic_map::eq_at(mpa); + return typed::map(res); +} + +template +template +typed::union_map typed::basic_map::eq_at(const typed::multi_union_pw_aff &mupa) const +{ + auto res = isl::basic_map::eq_at(mupa); + return typed::union_map(res); +} + +template +bool typed::basic_map::every_map(const std::function)> &test) const +{ + auto lambda_test = [&] (isl::map arg0) { + return test(typed::map(arg0)); + }; + return isl::basic_map::every_map(lambda_test); +} + +template +typed::map typed::basic_map::extract_map(const typed::space &space) const +{ + auto res = isl::basic_map::extract_map(space); + return typed::map(res); +} + +template +void typed::basic_map::foreach_basic_map(const std::function)> &fn) const +{ + auto lambda_fn = [&] (isl::basic_map arg0) { + return fn(typed::basic_map(arg0)); + }; + return isl::basic_map::foreach_basic_map(lambda_fn); +} + +template +void typed::basic_map::foreach_map(const std::function)> &fn) const +{ + auto lambda_fn = [&] (isl::map arg0) { + return fn(typed::map(arg0)); + }; + return isl::basic_map::foreach_map(lambda_fn); +} + +template +typed::basic_map typed::basic_map::gist(const typed::basic_map &context) const +{ + auto res = isl::basic_map::gist(context); + return typed::basic_map(res); +} + +template +typed::map typed::basic_map::gist(const typed::map &context) const +{ + auto res = isl::basic_map::gist(context); + return typed::map(res); +} + +template +typed::union_map typed::basic_map::gist(const typed::union_map &context) const +{ + auto res = isl::basic_map::gist(context); + return typed::union_map(res); +} + +template +typed::map typed::basic_map::gist_domain(const typed::set &context) const +{ + auto res = isl::basic_map::gist_domain(context); + return typed::map(res); +} + +template +typed::union_map typed::basic_map::gist_domain(const typed::union_set &uset) const +{ + auto res = isl::basic_map::gist_domain(uset); + return typed::union_map(res); +} + +template +typed::map typed::basic_map::gist_params(const typed::set<> &context) const +{ + auto res = isl::basic_map::gist_params(context); + return typed::map(res); +} + +template +typed::basic_map typed::basic_map::intersect(const typed::basic_map &bmap2) const +{ + auto res = isl::basic_map::intersect(bmap2); + return typed::basic_map(res); +} + +template +typed::map typed::basic_map::intersect(const typed::map &map2) const +{ + auto res = isl::basic_map::intersect(map2); + return typed::map(res); +} + +template +typed::union_map typed::basic_map::intersect(const typed::union_map &umap2) const +{ + auto res = isl::basic_map::intersect(umap2); + return typed::union_map(res); +} + +template +typed::basic_map typed::basic_map::intersect_domain(const typed::basic_set &bset) const +{ + auto res = isl::basic_map::intersect_domain(bset); + return typed::basic_map(res); +} + +template +typed::map typed::basic_map::intersect_domain(const typed::set &set) const +{ + auto res = isl::basic_map::intersect_domain(set); + return typed::map(res); +} + +template +typed::union_map typed::basic_map::intersect_domain(const typed::space &space) const +{ + auto res = isl::basic_map::intersect_domain(space); + return typed::union_map(res); +} + +template +typed::union_map typed::basic_map::intersect_domain(const typed::union_set &uset) const +{ + auto res = isl::basic_map::intersect_domain(uset); + return typed::union_map(res); +} + +template +typed::basic_map typed::basic_map::intersect_domain(const typed::point &bset) const +{ + auto res = isl::basic_map::intersect_domain(bset); + return typed::basic_map(res); +} + +template +typed::map typed::basic_map::intersect_params(const typed::set<> ¶ms) const +{ + auto res = isl::basic_map::intersect_params(params); + return typed::map(res); +} + +template +typed::basic_map typed::basic_map::intersect_range(const typed::basic_set &bset) const +{ + auto res = isl::basic_map::intersect_range(bset); + return typed::basic_map(res); +} + +template +typed::map typed::basic_map::intersect_range(const typed::set &set) const +{ + auto res = isl::basic_map::intersect_range(set); + return typed::map(res); +} + +template +typed::union_map typed::basic_map::intersect_range(const typed::space &space) const +{ + auto res = isl::basic_map::intersect_range(space); + return typed::union_map(res); +} + +template +typed::union_map typed::basic_map::intersect_range(const typed::union_set &uset) const +{ + auto res = isl::basic_map::intersect_range(uset); + return typed::union_map(res); +} + +template +typed::basic_map typed::basic_map::intersect_range(const typed::point &bset) const +{ + auto res = isl::basic_map::intersect_range(bset); + return typed::basic_map(res); +} + +template +template +typed::map typed::basic_map::lex_ge_at(const typed::multi_pw_aff &mpa) const +{ + auto res = isl::basic_map::lex_ge_at(mpa); + return typed::map(res); +} + +template +template +typed::map typed::basic_map::lex_gt_at(const typed::multi_pw_aff &mpa) const +{ + auto res = isl::basic_map::lex_gt_at(mpa); + return typed::map(res); +} + +template +template +typed::map typed::basic_map::lex_le_at(const typed::multi_pw_aff &mpa) const +{ + auto res = isl::basic_map::lex_le_at(mpa); + return typed::map(res); +} + +template +template +typed::map typed::basic_map::lex_lt_at(const typed::multi_pw_aff &mpa) const +{ + auto res = isl::basic_map::lex_lt_at(mpa); + return typed::map(res); +} + +template +typed::map typed::basic_map::lexmax() const +{ + auto res = isl::basic_map::lexmax(); + return typed::map(res); +} + +template +typed::pw_multi_aff typed::basic_map::lexmax_pw_multi_aff() const +{ + auto res = isl::basic_map::lexmax_pw_multi_aff(); + return typed::pw_multi_aff(res); +} + +template +typed::map typed::basic_map::lexmin() const +{ + auto res = isl::basic_map::lexmin(); + return typed::map(res); +} + +template +typed::pw_multi_aff typed::basic_map::lexmin_pw_multi_aff() const +{ + auto res = isl::basic_map::lexmin_pw_multi_aff(); + return typed::pw_multi_aff(res); +} + +template +typed::map typed::basic_map::lower_bound(const typed::multi_pw_aff &lower) const +{ + auto res = isl::basic_map::lower_bound(lower); + return typed::map(res); +} + +template +typed::map_list typed::basic_map::map_list() const +{ + auto res = isl::basic_map::map_list(); + return typed::map_list(res); +} + +template +typed::multi_pw_aff typed::basic_map::max_multi_pw_aff() const +{ + auto res = isl::basic_map::max_multi_pw_aff(); + return typed::multi_pw_aff(res); +} + +template +typed::multi_pw_aff typed::basic_map::min_multi_pw_aff() const +{ + auto res = isl::basic_map::min_multi_pw_aff(); + return typed::multi_pw_aff(res); +} + +template +typed::set<> typed::basic_map::params() const +{ + auto res = isl::basic_map::params(); + return typed::set<>(res); +} + +template +template +typed::map typed::basic_map::preimage_domain(const typed::multi_aff &ma) const +{ + auto res = isl::basic_map::preimage_domain(ma); + return typed::map(res); +} + +template +template +typed::map typed::basic_map::preimage_domain(const typed::multi_pw_aff &mpa) const +{ + auto res = isl::basic_map::preimage_domain(mpa); + return typed::map(res); +} + +template +template +typed::map typed::basic_map::preimage_domain(const typed::pw_multi_aff &pma) const +{ + auto res = isl::basic_map::preimage_domain(pma); + return typed::map(res); +} + +template +template +typed::union_map typed::basic_map::preimage_domain(const typed::union_pw_multi_aff &upma) const +{ + auto res = isl::basic_map::preimage_domain(upma); + return typed::union_map(res); +} + +template +template +typed::map typed::basic_map::preimage_range(const typed::multi_aff &ma) const +{ + auto res = isl::basic_map::preimage_range(ma); + return typed::map(res); +} + +template +template +typed::map typed::basic_map::preimage_range(const typed::pw_multi_aff &pma) const +{ + auto res = isl::basic_map::preimage_range(pma); + return typed::map(res); +} + +template +template +typed::union_map typed::basic_map::preimage_range(const typed::union_pw_multi_aff &upma) const +{ + auto res = isl::basic_map::preimage_range(upma); + return typed::union_map(res); +} + +template +template +typed::map, pair> typed::basic_map::product(const typed::map &map2) const +{ + auto res = isl::basic_map::product(map2); + return typed::map, pair>(res); +} + +template +template +typed::union_map, pair> typed::basic_map::product(const typed::union_map &umap2) const +{ + auto res = isl::basic_map::product(umap2); + return typed::union_map, pair>(res); +} + +template +typed::map typed::basic_map::project_out_all_params() const +{ + auto res = isl::basic_map::project_out_all_params(); + return typed::map(res); +} + +template +typed::map typed::basic_map::project_out_param(const typed::id &id) const +{ + auto res = isl::basic_map::project_out_param(id); + return typed::map(res); +} + +template +typed::map typed::basic_map::project_out_param(const std::string &id) const +{ + auto res = isl::basic_map::project_out_param(id); + return typed::map(res); +} + +template +typed::map typed::basic_map::project_out_param(const typed::id_list &list) const +{ + auto res = isl::basic_map::project_out_param(list); + return typed::map(res); +} + +template +typed::set typed::basic_map::range() const +{ + auto res = isl::basic_map::range(); + return typed::set(res); +} + +template +typed::fixed_box typed::basic_map::range_lattice_tile() const +{ + auto res = isl::basic_map::range_lattice_tile(); + return typed::fixed_box(res); +} + +template +typed::union_map, Domain> typed::basic_map::range_map() const +{ + auto res = isl::basic_map::range_map(); + return typed::union_map, Domain>(res); +} + +template +template +typed::map> typed::basic_map::range_product(const typed::map &map2) const +{ + auto res = isl::basic_map::range_product(map2); + return typed::map>(res); +} + +template +template +typed::union_map> typed::basic_map::range_product(const typed::union_map &umap2) const +{ + auto res = isl::basic_map::range_product(umap2); + return typed::union_map>(res); +} + +template +typed::fixed_box typed::basic_map::range_simple_fixed_box_hull() const +{ + auto res = isl::basic_map::range_simple_fixed_box_hull(); + return typed::fixed_box(res); +} + +template +typed::basic_map typed::basic_map::reverse() const +{ + auto res = isl::basic_map::reverse(); + return typed::basic_map(res); +} + +template +template +typed::map typed::basic_map::set_domain_tuple(const typed::id &id) const +{ + auto res = isl::basic_map::set_domain_tuple(id); + return typed::map(res); +} + +template +template +typed::map typed::basic_map::set_domain_tuple(const std::string &id) const +{ + auto res = isl::basic_map::set_domain_tuple(id); + return typed::map(res); +} + +template +template +typed::map typed::basic_map::set_range_tuple(const typed::id &id) const +{ + auto res = isl::basic_map::set_range_tuple(id); + return typed::map(res); +} + +template +template +typed::map typed::basic_map::set_range_tuple(const std::string &id) const +{ + auto res = isl::basic_map::set_range_tuple(id); + return typed::map(res); +} + +template +typed::space typed::basic_map::space() const +{ + auto res = isl::basic_map::space(); + return typed::space(res); +} + +template +typed::map typed::basic_map::subtract(const typed::map &map2) const +{ + auto res = isl::basic_map::subtract(map2); + return typed::map(res); +} + +template +typed::union_map typed::basic_map::subtract(const typed::union_map &umap2) const +{ + auto res = isl::basic_map::subtract(umap2); + return typed::union_map(res); +} + +template +typed::union_map typed::basic_map::subtract_domain(const typed::union_set &dom) const +{ + auto res = isl::basic_map::subtract_domain(dom); + return typed::union_map(res); +} + +template +typed::union_map typed::basic_map::subtract_range(const typed::union_set &dom) const +{ + auto res = isl::basic_map::subtract_range(dom); + return typed::union_map(res); +} + +template +typed::union_map typed::basic_map::to_union_map() const +{ + auto res = isl::basic_map::to_union_map(); + return typed::union_map(res); +} + +template +typed::map typed::basic_map::unite(const typed::basic_map &bmap2) const +{ + auto res = isl::basic_map::unite(bmap2); + return typed::map(res); +} + +template +typed::map typed::basic_map::unite(const typed::map &map2) const +{ + auto res = isl::basic_map::unite(map2); + return typed::map(res); +} + +template +typed::union_map typed::basic_map::unite(const typed::union_map &umap2) const +{ + auto res = isl::basic_map::unite(umap2); + return typed::union_map(res); +} + +template +typed::map typed::basic_map::upper_bound(const typed::multi_pw_aff &upper) const +{ + auto res = isl::basic_map::upper_bound(upper); + return typed::map(res); +} + +template +typed::set> typed::basic_map::wrap() const +{ + auto res = isl::basic_map::wrap(); + return typed::set>(res); +} + +template +typed::basic_map>::basic_map(const isl::ctx &ctx, const std::string &str) + : isl::basic_map(ctx, str) +{ +} + +template +template +typed::basic_map> typed::basic_map>::apply_domain(const typed::basic_map &bmap2) const +{ + auto res = isl::basic_map::apply_domain(bmap2); + return typed::basic_map>(res); +} + +template +template +typed::map> typed::basic_map>::apply_domain(const typed::map &map2) const +{ + auto res = isl::basic_map::apply_domain(map2); + return typed::map>(res); +} + +template +template +typed::union_map> typed::basic_map>::apply_domain(const typed::union_map &umap2) const +{ + auto res = isl::basic_map::apply_domain(umap2); + return typed::union_map>(res); +} + +template +template +typed::basic_map typed::basic_map>::apply_range(const typed::basic_map, Arg3> &bmap2) const +{ + auto res = isl::basic_map::apply_range(bmap2); + return typed::basic_map(res); +} + +template +template +typed::map typed::basic_map>::apply_range(const typed::map, Arg3> &map2) const +{ + auto res = isl::basic_map::apply_range(map2); + return typed::map(res); +} + +template +template +typed::union_map typed::basic_map>::apply_range(const typed::union_map, Arg3> &umap2) const +{ + auto res = isl::basic_map::apply_range(umap2); + return typed::union_map(res); +} + +template +typed::map> typed::basic_map>::as_map() const +{ + auto res = isl::basic_map::as_map(); + return typed::map>(res); +} + +template +typed::multi_union_pw_aff> typed::basic_map>::as_multi_union_pw_aff() const +{ + auto res = isl::basic_map::as_multi_union_pw_aff(); + return typed::multi_union_pw_aff>(res); +} + +template +typed::pw_multi_aff> typed::basic_map>::as_pw_multi_aff() const +{ + auto res = isl::basic_map::as_pw_multi_aff(); + return typed::pw_multi_aff>(res); +} + +template +typed::union_pw_multi_aff> typed::basic_map>::as_union_pw_multi_aff() const +{ + auto res = isl::basic_map::as_union_pw_multi_aff(); + return typed::union_pw_multi_aff>(res); +} + +template +typed::set> typed::basic_map>::bind_domain(const typed::multi_id &tuple) const +{ + auto res = isl::basic_map::bind_domain(tuple); + return typed::set>(res); +} + +template +typed::set typed::basic_map>::bind_range(const typed::multi_id> &tuple) const +{ + auto res = isl::basic_map::bind_range(tuple); + return typed::set(res); +} + +template +typed::map> typed::basic_map>::coalesce() const +{ + auto res = isl::basic_map::coalesce(); + return typed::map>(res); +} + +template +typed::basic_map> typed::basic_map>::detect_equalities() const +{ + auto res = isl::basic_map::detect_equalities(); + return typed::basic_map>(res); +} + +template +typed::set typed::basic_map>::domain() const +{ + auto res = isl::basic_map::domain(); + return typed::set(res); +} + +template +typed::union_map>, Domain> typed::basic_map>::domain_map() const +{ + auto res = isl::basic_map::domain_map(); + return typed::union_map>, Domain>(res); +} + +template +typed::union_pw_multi_aff>, Domain> typed::basic_map>::domain_map_union_pw_multi_aff() const +{ + auto res = isl::basic_map::domain_map_union_pw_multi_aff(); + return typed::union_pw_multi_aff>, Domain>(res); +} + +template +template +typed::map, pair> typed::basic_map>::domain_product(const typed::map> &map2) const +{ + auto res = isl::basic_map::domain_product(map2); + return typed::map, pair>(res); +} + +template +template +typed::union_map, pair> typed::basic_map>::domain_product(const typed::union_map> &umap2) const +{ + auto res = isl::basic_map::domain_product(umap2); + return typed::union_map, pair>(res); +} + +template +typed::map> typed::basic_map>::drop_unused_params() const +{ + auto res = isl::basic_map::drop_unused_params(); + return typed::map>(res); +} + +template +bool typed::basic_map>::every_map(const std::function>)> &test) const +{ + auto lambda_test = [&] (isl::map arg0) { + return test(typed::map>(arg0)); + }; + return isl::basic_map::every_map(lambda_test); +} + +template +typed::map> typed::basic_map>::extract_map(const typed::space> &space) const +{ + auto res = isl::basic_map::extract_map(space); + return typed::map>(res); +} + +template +typed::basic_map typed::basic_map>::flatten_range() const +{ + auto res = isl::basic_map::flatten_range(); + return typed::basic_map(res); +} + +template +void typed::basic_map>::foreach_basic_map(const std::function>)> &fn) const +{ + auto lambda_fn = [&] (isl::basic_map arg0) { + return fn(typed::basic_map>(arg0)); + }; + return isl::basic_map::foreach_basic_map(lambda_fn); +} + +template +void typed::basic_map>::foreach_map(const std::function>)> &fn) const +{ + auto lambda_fn = [&] (isl::map arg0) { + return fn(typed::map>(arg0)); + }; + return isl::basic_map::foreach_map(lambda_fn); +} + +template +typed::basic_map> typed::basic_map>::gist(const typed::basic_map> &context) const +{ + auto res = isl::basic_map::gist(context); + return typed::basic_map>(res); +} + +template +typed::map> typed::basic_map>::gist(const typed::map> &context) const +{ + auto res = isl::basic_map::gist(context); + return typed::map>(res); +} + +template +typed::union_map> typed::basic_map>::gist(const typed::union_map> &context) const +{ + auto res = isl::basic_map::gist(context); + return typed::union_map>(res); +} + +template +typed::map> typed::basic_map>::gist_domain(const typed::set &context) const +{ + auto res = isl::basic_map::gist_domain(context); + return typed::map>(res); +} + +template +typed::union_map> typed::basic_map>::gist_domain(const typed::union_set &uset) const +{ + auto res = isl::basic_map::gist_domain(uset); + return typed::union_map>(res); +} + +template +typed::map> typed::basic_map>::gist_params(const typed::set<> &context) const +{ + auto res = isl::basic_map::gist_params(context); + return typed::map>(res); +} + +template +typed::basic_map> typed::basic_map>::intersect(const typed::basic_map> &bmap2) const +{ + auto res = isl::basic_map::intersect(bmap2); + return typed::basic_map>(res); +} + +template +typed::map> typed::basic_map>::intersect(const typed::map> &map2) const +{ + auto res = isl::basic_map::intersect(map2); + return typed::map>(res); +} + +template +typed::union_map> typed::basic_map>::intersect(const typed::union_map> &umap2) const +{ + auto res = isl::basic_map::intersect(umap2); + return typed::union_map>(res); +} + +template +typed::basic_map> typed::basic_map>::intersect_domain(const typed::basic_set &bset) const +{ + auto res = isl::basic_map::intersect_domain(bset); + return typed::basic_map>(res); +} + +template +typed::map> typed::basic_map>::intersect_domain(const typed::set &set) const +{ + auto res = isl::basic_map::intersect_domain(set); + return typed::map>(res); +} + +template +typed::union_map> typed::basic_map>::intersect_domain(const typed::space &space) const +{ + auto res = isl::basic_map::intersect_domain(space); + return typed::union_map>(res); +} + +template +typed::union_map> typed::basic_map>::intersect_domain(const typed::union_set &uset) const +{ + auto res = isl::basic_map::intersect_domain(uset); + return typed::union_map>(res); +} + +template +typed::basic_map> typed::basic_map>::intersect_domain(const typed::point &bset) const +{ + auto res = isl::basic_map::intersect_domain(bset); + return typed::basic_map>(res); +} + +template +typed::map> typed::basic_map>::intersect_params(const typed::set<> ¶ms) const +{ + auto res = isl::basic_map::intersect_params(params); + return typed::map>(res); +} + +template +typed::basic_map> typed::basic_map>::intersect_range(const typed::basic_set> &bset) const +{ + auto res = isl::basic_map::intersect_range(bset); + return typed::basic_map>(res); +} + +template +typed::map> typed::basic_map>::intersect_range(const typed::set> &set) const +{ + auto res = isl::basic_map::intersect_range(set); + return typed::map>(res); +} + +template +typed::union_map> typed::basic_map>::intersect_range(const typed::space> &space) const +{ + auto res = isl::basic_map::intersect_range(space); + return typed::union_map>(res); +} + +template +typed::union_map> typed::basic_map>::intersect_range(const typed::union_set> &uset) const +{ + auto res = isl::basic_map::intersect_range(uset); + return typed::union_map>(res); +} + +template +typed::basic_map> typed::basic_map>::intersect_range(const typed::point> &bset) const +{ + auto res = isl::basic_map::intersect_range(bset); + return typed::basic_map>(res); +} + +template +typed::map> typed::basic_map>::intersect_range_wrapped_domain(const typed::set &domain) const +{ + auto res = isl::basic_map::intersect_range_wrapped_domain(domain); + return typed::map>(res); +} + +template +typed::union_map> typed::basic_map>::intersect_range_wrapped_domain(const typed::union_set &domain) const +{ + auto res = isl::basic_map::intersect_range_wrapped_domain(domain); + return typed::union_map>(res); +} + +template +typed::map> typed::basic_map>::lexmax() const +{ + auto res = isl::basic_map::lexmax(); + return typed::map>(res); +} + +template +typed::pw_multi_aff> typed::basic_map>::lexmax_pw_multi_aff() const +{ + auto res = isl::basic_map::lexmax_pw_multi_aff(); + return typed::pw_multi_aff>(res); +} + +template +typed::map> typed::basic_map>::lexmin() const +{ + auto res = isl::basic_map::lexmin(); + return typed::map>(res); +} + +template +typed::pw_multi_aff> typed::basic_map>::lexmin_pw_multi_aff() const +{ + auto res = isl::basic_map::lexmin_pw_multi_aff(); + return typed::pw_multi_aff>(res); +} + +template +typed::map> typed::basic_map>::lower_bound(const typed::multi_pw_aff> &lower) const +{ + auto res = isl::basic_map::lower_bound(lower); + return typed::map>(res); +} + +template +typed::map_list> typed::basic_map>::map_list() const +{ + auto res = isl::basic_map::map_list(); + return typed::map_list>(res); +} + +template +typed::multi_pw_aff> typed::basic_map>::max_multi_pw_aff() const +{ + auto res = isl::basic_map::max_multi_pw_aff(); + return typed::multi_pw_aff>(res); +} + +template +typed::multi_pw_aff> typed::basic_map>::min_multi_pw_aff() const +{ + auto res = isl::basic_map::min_multi_pw_aff(); + return typed::multi_pw_aff>(res); +} + +template +typed::set<> typed::basic_map>::params() const +{ + auto res = isl::basic_map::params(); + return typed::set<>(res); +} + +template +template +typed::map> typed::basic_map>::preimage_domain(const typed::multi_aff &ma) const +{ + auto res = isl::basic_map::preimage_domain(ma); + return typed::map>(res); +} + +template +template +typed::map> typed::basic_map>::preimage_domain(const typed::multi_pw_aff &mpa) const +{ + auto res = isl::basic_map::preimage_domain(mpa); + return typed::map>(res); +} + +template +template +typed::map> typed::basic_map>::preimage_domain(const typed::pw_multi_aff &pma) const +{ + auto res = isl::basic_map::preimage_domain(pma); + return typed::map>(res); +} + +template +template +typed::union_map> typed::basic_map>::preimage_domain(const typed::union_pw_multi_aff &upma) const +{ + auto res = isl::basic_map::preimage_domain(upma); + return typed::union_map>(res); +} + +template +template +typed::map typed::basic_map>::preimage_range(const typed::multi_aff> &ma) const +{ + auto res = isl::basic_map::preimage_range(ma); + return typed::map(res); +} + +template +template +typed::map typed::basic_map>::preimage_range(const typed::pw_multi_aff> &pma) const +{ + auto res = isl::basic_map::preimage_range(pma); + return typed::map(res); +} + +template +template +typed::union_map typed::basic_map>::preimage_range(const typed::union_pw_multi_aff> &upma) const +{ + auto res = isl::basic_map::preimage_range(upma); + return typed::union_map(res); +} + +template +template +typed::map, pair, Arg3>> typed::basic_map>::product(const typed::map &map2) const +{ + auto res = isl::basic_map::product(map2); + return typed::map, pair, Arg3>>(res); +} + +template +template +typed::union_map, pair, Arg3>> typed::basic_map>::product(const typed::union_map &umap2) const +{ + auto res = isl::basic_map::product(umap2); + return typed::union_map, pair, Arg3>>(res); +} + +template +typed::map> typed::basic_map>::project_out_all_params() const +{ + auto res = isl::basic_map::project_out_all_params(); + return typed::map>(res); +} + +template +typed::map> typed::basic_map>::project_out_param(const typed::id &id) const +{ + auto res = isl::basic_map::project_out_param(id); + return typed::map>(res); +} + +template +typed::map> typed::basic_map>::project_out_param(const std::string &id) const +{ + auto res = isl::basic_map::project_out_param(id); + return typed::map>(res); +} + +template +typed::map> typed::basic_map>::project_out_param(const typed::id_list &list) const +{ + auto res = isl::basic_map::project_out_param(list); + return typed::map>(res); +} + +template +typed::set> typed::basic_map>::range() const +{ + auto res = isl::basic_map::range(); + return typed::set>(res); +} + +template +typed::map typed::basic_map>::range_factor_domain() const +{ + auto res = isl::basic_map::range_factor_domain(); + return typed::map(res); +} + +template +typed::map typed::basic_map>::range_factor_range() const +{ + auto res = isl::basic_map::range_factor_range(); + return typed::map(res); +} + +template +typed::fixed_box> typed::basic_map>::range_lattice_tile() const +{ + auto res = isl::basic_map::range_lattice_tile(); + return typed::fixed_box>(res); +} + +template +typed::union_map>, pair> typed::basic_map>::range_map() const +{ + auto res = isl::basic_map::range_map(); + return typed::union_map>, pair>(res); +} + +template +template +typed::map, Arg3>> typed::basic_map>::range_product(const typed::map &map2) const +{ + auto res = isl::basic_map::range_product(map2); + return typed::map, Arg3>>(res); +} + +template +template +typed::union_map, Arg3>> typed::basic_map>::range_product(const typed::union_map &umap2) const +{ + auto res = isl::basic_map::range_product(umap2); + return typed::union_map, Arg3>>(res); +} + +template +typed::map> typed::basic_map>::range_reverse() const +{ + auto res = isl::basic_map::range_reverse(); + return typed::map>(res); +} + +template +typed::fixed_box> typed::basic_map>::range_simple_fixed_box_hull() const +{ + auto res = isl::basic_map::range_simple_fixed_box_hull(); + return typed::fixed_box>(res); +} + +template +typed::basic_map, Domain> typed::basic_map>::reverse() const +{ + auto res = isl::basic_map::reverse(); + return typed::basic_map, Domain>(res); +} + +template +template +typed::map> typed::basic_map>::set_domain_tuple(const typed::id &id) const +{ + auto res = isl::basic_map::set_domain_tuple(id); + return typed::map>(res); +} + +template +template +typed::map> typed::basic_map>::set_domain_tuple(const std::string &id) const +{ + auto res = isl::basic_map::set_domain_tuple(id); + return typed::map>(res); +} + +template +typed::space> typed::basic_map>::space() const +{ + auto res = isl::basic_map::space(); + return typed::space>(res); +} + +template +typed::map> typed::basic_map>::subtract(const typed::map> &map2) const +{ + auto res = isl::basic_map::subtract(map2); + return typed::map>(res); +} + +template +typed::union_map> typed::basic_map>::subtract(const typed::union_map> &umap2) const +{ + auto res = isl::basic_map::subtract(umap2); + return typed::union_map>(res); +} + +template +typed::union_map> typed::basic_map>::subtract_domain(const typed::union_set &dom) const +{ + auto res = isl::basic_map::subtract_domain(dom); + return typed::union_map>(res); +} + +template +typed::union_map> typed::basic_map>::subtract_range(const typed::union_set> &dom) const +{ + auto res = isl::basic_map::subtract_range(dom); + return typed::union_map>(res); +} + +template +typed::union_map> typed::basic_map>::to_union_map() const +{ + auto res = isl::basic_map::to_union_map(); + return typed::union_map>(res); +} + +template +typed::map, Range2> typed::basic_map>::uncurry() const +{ + auto res = isl::basic_map::uncurry(); + return typed::map, Range2>(res); +} + +template +typed::map> typed::basic_map>::unite(const typed::basic_map> &bmap2) const +{ + auto res = isl::basic_map::unite(bmap2); + return typed::map>(res); +} + +template +typed::map> typed::basic_map>::unite(const typed::map> &map2) const +{ + auto res = isl::basic_map::unite(map2); + return typed::map>(res); +} + +template +typed::union_map> typed::basic_map>::unite(const typed::union_map> &umap2) const +{ + auto res = isl::basic_map::unite(umap2); + return typed::union_map>(res); +} + +template +typed::map> typed::basic_map>::upper_bound(const typed::multi_pw_aff> &upper) const +{ + auto res = isl::basic_map::upper_bound(upper); + return typed::map>(res); +} + +template +typed::set>> typed::basic_map>::wrap() const +{ + auto res = isl::basic_map::wrap(); + return typed::set>>(res); +} + +template +typed::basic_map, pair>::basic_map(const isl::ctx &ctx, const std::string &str) + : isl::basic_map(ctx, str) +{ +} + +template +template +typed::basic_map> typed::basic_map, pair>::apply_domain(const typed::basic_map, Domain2> &bmap2) const +{ + auto res = isl::basic_map::apply_domain(bmap2); + return typed::basic_map>(res); +} + +template +template +typed::map> typed::basic_map, pair>::apply_domain(const typed::map, Domain2> &map2) const +{ + auto res = isl::basic_map::apply_domain(map2); + return typed::map>(res); +} + +template +template +typed::union_map> typed::basic_map, pair>::apply_domain(const typed::union_map, Domain2> &umap2) const +{ + auto res = isl::basic_map::apply_domain(umap2); + return typed::union_map>(res); +} + +template +template +typed::basic_map, Range2> typed::basic_map, pair>::apply_range(const typed::basic_map, Range2> &bmap2) const +{ + auto res = isl::basic_map::apply_range(bmap2); + return typed::basic_map, Range2>(res); +} + +template +template +typed::map, Range2> typed::basic_map, pair>::apply_range(const typed::map, Range2> &map2) const +{ + auto res = isl::basic_map::apply_range(map2); + return typed::map, Range2>(res); +} + +template +template +typed::union_map, Range2> typed::basic_map, pair>::apply_range(const typed::union_map, Range2> &umap2) const +{ + auto res = isl::basic_map::apply_range(umap2); + return typed::union_map, Range2>(res); +} + +template +typed::map, pair> typed::basic_map, pair>::as_map() const +{ + auto res = isl::basic_map::as_map(); + return typed::map, pair>(res); +} + +template +typed::multi_union_pw_aff, pair> typed::basic_map, pair>::as_multi_union_pw_aff() const +{ + auto res = isl::basic_map::as_multi_union_pw_aff(); + return typed::multi_union_pw_aff, pair>(res); +} + +template +typed::pw_multi_aff, pair> typed::basic_map, pair>::as_pw_multi_aff() const +{ + auto res = isl::basic_map::as_pw_multi_aff(); + return typed::pw_multi_aff, pair>(res); +} + +template +typed::union_pw_multi_aff, pair> typed::basic_map, pair>::as_union_pw_multi_aff() const +{ + auto res = isl::basic_map::as_union_pw_multi_aff(); + return typed::union_pw_multi_aff, pair>(res); +} + +template +typed::set> typed::basic_map, pair>::bind_domain(const typed::multi_id> &tuple) const +{ + auto res = isl::basic_map::bind_domain(tuple); + return typed::set>(res); +} + +template +typed::set> typed::basic_map, pair>::bind_range(const typed::multi_id> &tuple) const +{ + auto res = isl::basic_map::bind_range(tuple); + return typed::set>(res); +} + +template +typed::map, pair> typed::basic_map, pair>::coalesce() const +{ + auto res = isl::basic_map::coalesce(); + return typed::map, pair>(res); +} + +template +typed::map>> typed::basic_map, pair>::curry() const +{ + auto res = isl::basic_map::curry(); + return typed::map>>(res); +} + +template +typed::basic_set> typed::basic_map, pair>::deltas() const +{ + auto res = isl::basic_map::deltas(); + return typed::basic_set>(res); +} + +template +typed::basic_map, pair> typed::basic_map, pair>::detect_equalities() const +{ + auto res = isl::basic_map::detect_equalities(); + return typed::basic_map, pair>(res); +} + +template +typed::set> typed::basic_map, pair>::domain() const +{ + auto res = isl::basic_map::domain(); + return typed::set>(res); +} + +template +typed::map> typed::basic_map, pair>::domain_factor_domain() const +{ + auto res = isl::basic_map::domain_factor_domain(); + return typed::map>(res); +} + +template +typed::map> typed::basic_map, pair>::domain_factor_range() const +{ + auto res = isl::basic_map::domain_factor_range(); + return typed::map>(res); +} + +template +typed::union_map, pair>, pair> typed::basic_map, pair>::domain_map() const +{ + auto res = isl::basic_map::domain_map(); + return typed::union_map, pair>, pair>(res); +} + +template +typed::union_pw_multi_aff, pair>, pair> typed::basic_map, pair>::domain_map_union_pw_multi_aff() const +{ + auto res = isl::basic_map::domain_map_union_pw_multi_aff(); + return typed::union_pw_multi_aff, pair>, pair>(res); +} + +template +template +typed::map, Domain2>, pair> typed::basic_map, pair>::domain_product(const typed::map> &map2) const +{ + auto res = isl::basic_map::domain_product(map2); + return typed::map, Domain2>, pair>(res); +} + +template +template +typed::union_map, Domain2>, pair> typed::basic_map, pair>::domain_product(const typed::union_map> &umap2) const +{ + auto res = isl::basic_map::domain_product(umap2); + return typed::union_map, Domain2>, pair>(res); +} + +template +typed::map, pair> typed::basic_map, pair>::domain_reverse() const +{ + auto res = isl::basic_map::domain_reverse(); + return typed::map, pair>(res); +} + +template +typed::map, pair> typed::basic_map, pair>::drop_unused_params() const +{ + auto res = isl::basic_map::drop_unused_params(); + return typed::map, pair>(res); +} + +template +template +typed::map, pair> typed::basic_map, pair>::eq_at(const typed::multi_pw_aff, Range> &mpa) const +{ + auto res = isl::basic_map::eq_at(mpa); + return typed::map, pair>(res); +} + +template +template +typed::union_map, pair> typed::basic_map, pair>::eq_at(const typed::multi_union_pw_aff, Range> &mupa) const +{ + auto res = isl::basic_map::eq_at(mupa); + return typed::union_map, pair>(res); +} + +template +bool typed::basic_map, pair>::every_map(const std::function, pair>)> &test) const +{ + auto lambda_test = [&] (isl::map arg0) { + return test(typed::map, pair>(arg0)); + }; + return isl::basic_map::every_map(lambda_test); +} + +template +typed::map, pair> typed::basic_map, pair>::extract_map(const typed::space, pair> &space) const +{ + auto res = isl::basic_map::extract_map(space); + return typed::map, pair>(res); +} + +template +typed::basic_map> typed::basic_map, pair>::flatten_domain() const +{ + auto res = isl::basic_map::flatten_domain(); + return typed::basic_map>(res); +} + +template +typed::basic_map, Anonymous> typed::basic_map, pair>::flatten_range() const +{ + auto res = isl::basic_map::flatten_range(); + return typed::basic_map, Anonymous>(res); +} + +template +void typed::basic_map, pair>::foreach_basic_map(const std::function, pair>)> &fn) const +{ + auto lambda_fn = [&] (isl::basic_map arg0) { + return fn(typed::basic_map, pair>(arg0)); + }; + return isl::basic_map::foreach_basic_map(lambda_fn); +} + +template +void typed::basic_map, pair>::foreach_map(const std::function, pair>)> &fn) const +{ + auto lambda_fn = [&] (isl::map arg0) { + return fn(typed::map, pair>(arg0)); + }; + return isl::basic_map::foreach_map(lambda_fn); +} + +template +typed::basic_map, pair> typed::basic_map, pair>::gist(const typed::basic_map, pair> &context) const +{ + auto res = isl::basic_map::gist(context); + return typed::basic_map, pair>(res); +} + +template +typed::map, pair> typed::basic_map, pair>::gist(const typed::map, pair> &context) const +{ + auto res = isl::basic_map::gist(context); + return typed::map, pair>(res); +} + +template +typed::union_map, pair> typed::basic_map, pair>::gist(const typed::union_map, pair> &context) const +{ + auto res = isl::basic_map::gist(context); + return typed::union_map, pair>(res); +} + +template +typed::map, pair> typed::basic_map, pair>::gist_domain(const typed::set> &context) const +{ + auto res = isl::basic_map::gist_domain(context); + return typed::map, pair>(res); +} + +template +typed::union_map, pair> typed::basic_map, pair>::gist_domain(const typed::union_set> &uset) const +{ + auto res = isl::basic_map::gist_domain(uset); + return typed::union_map, pair>(res); +} + +template +typed::map, pair> typed::basic_map, pair>::gist_params(const typed::set<> &context) const +{ + auto res = isl::basic_map::gist_params(context); + return typed::map, pair>(res); +} + +template +typed::basic_map, pair> typed::basic_map, pair>::intersect(const typed::basic_map, pair> &bmap2) const +{ + auto res = isl::basic_map::intersect(bmap2); + return typed::basic_map, pair>(res); +} + +template +typed::map, pair> typed::basic_map, pair>::intersect(const typed::map, pair> &map2) const +{ + auto res = isl::basic_map::intersect(map2); + return typed::map, pair>(res); +} + +template +typed::union_map, pair> typed::basic_map, pair>::intersect(const typed::union_map, pair> &umap2) const +{ + auto res = isl::basic_map::intersect(umap2); + return typed::union_map, pair>(res); +} + +template +typed::basic_map, pair> typed::basic_map, pair>::intersect_domain(const typed::basic_set> &bset) const +{ + auto res = isl::basic_map::intersect_domain(bset); + return typed::basic_map, pair>(res); +} + +template +typed::map, pair> typed::basic_map, pair>::intersect_domain(const typed::set> &set) const +{ + auto res = isl::basic_map::intersect_domain(set); + return typed::map, pair>(res); +} + +template +typed::union_map, pair> typed::basic_map, pair>::intersect_domain(const typed::space> &space) const +{ + auto res = isl::basic_map::intersect_domain(space); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::basic_map, pair>::intersect_domain(const typed::union_set> &uset) const +{ + auto res = isl::basic_map::intersect_domain(uset); + return typed::union_map, pair>(res); +} + +template +typed::basic_map, pair> typed::basic_map, pair>::intersect_domain(const typed::point> &bset) const +{ + auto res = isl::basic_map::intersect_domain(bset); + return typed::basic_map, pair>(res); +} + +template +typed::map, pair> typed::basic_map, pair>::intersect_domain_wrapped_domain(const typed::set &domain) const +{ + auto res = isl::basic_map::intersect_domain_wrapped_domain(domain); + return typed::map, pair>(res); +} + +template +typed::union_map, pair> typed::basic_map, pair>::intersect_domain_wrapped_domain(const typed::union_set &domain) const +{ + auto res = isl::basic_map::intersect_domain_wrapped_domain(domain); + return typed::union_map, pair>(res); +} + +template +typed::map, pair> typed::basic_map, pair>::intersect_params(const typed::set<> ¶ms) const +{ + auto res = isl::basic_map::intersect_params(params); + return typed::map, pair>(res); +} + +template +typed::basic_map, pair> typed::basic_map, pair>::intersect_range(const typed::basic_set> &bset) const +{ + auto res = isl::basic_map::intersect_range(bset); + return typed::basic_map, pair>(res); +} + +template +typed::map, pair> typed::basic_map, pair>::intersect_range(const typed::set> &set) const +{ + auto res = isl::basic_map::intersect_range(set); + return typed::map, pair>(res); +} + +template +typed::union_map, pair> typed::basic_map, pair>::intersect_range(const typed::space> &space) const +{ + auto res = isl::basic_map::intersect_range(space); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::basic_map, pair>::intersect_range(const typed::union_set> &uset) const +{ + auto res = isl::basic_map::intersect_range(uset); + return typed::union_map, pair>(res); +} + +template +typed::basic_map, pair> typed::basic_map, pair>::intersect_range(const typed::point> &bset) const +{ + auto res = isl::basic_map::intersect_range(bset); + return typed::basic_map, pair>(res); +} + +template +typed::map, pair> typed::basic_map, pair>::intersect_range_wrapped_domain(const typed::set &domain) const +{ + auto res = isl::basic_map::intersect_range_wrapped_domain(domain); + return typed::map, pair>(res); +} + +template +typed::union_map, pair> typed::basic_map, pair>::intersect_range_wrapped_domain(const typed::union_set &domain) const +{ + auto res = isl::basic_map::intersect_range_wrapped_domain(domain); + return typed::union_map, pair>(res); +} + +template +template +typed::map, pair> typed::basic_map, pair>::lex_ge_at(const typed::multi_pw_aff, Range> &mpa) const +{ + auto res = isl::basic_map::lex_ge_at(mpa); + return typed::map, pair>(res); +} + +template +template +typed::map, pair> typed::basic_map, pair>::lex_gt_at(const typed::multi_pw_aff, Range> &mpa) const +{ + auto res = isl::basic_map::lex_gt_at(mpa); + return typed::map, pair>(res); +} + +template +template +typed::map, pair> typed::basic_map, pair>::lex_le_at(const typed::multi_pw_aff, Range> &mpa) const +{ + auto res = isl::basic_map::lex_le_at(mpa); + return typed::map, pair>(res); +} + +template +template +typed::map, pair> typed::basic_map, pair>::lex_lt_at(const typed::multi_pw_aff, Range> &mpa) const +{ + auto res = isl::basic_map::lex_lt_at(mpa); + return typed::map, pair>(res); +} + +template +typed::map, pair> typed::basic_map, pair>::lexmax() const +{ + auto res = isl::basic_map::lexmax(); + return typed::map, pair>(res); +} + +template +typed::pw_multi_aff, pair> typed::basic_map, pair>::lexmax_pw_multi_aff() const +{ + auto res = isl::basic_map::lexmax_pw_multi_aff(); + return typed::pw_multi_aff, pair>(res); +} + +template +typed::map, pair> typed::basic_map, pair>::lexmin() const +{ + auto res = isl::basic_map::lexmin(); + return typed::map, pair>(res); +} + +template +typed::pw_multi_aff, pair> typed::basic_map, pair>::lexmin_pw_multi_aff() const +{ + auto res = isl::basic_map::lexmin_pw_multi_aff(); + return typed::pw_multi_aff, pair>(res); +} + +template +typed::map, pair> typed::basic_map, pair>::lower_bound(const typed::multi_pw_aff, pair> &lower) const +{ + auto res = isl::basic_map::lower_bound(lower); + return typed::map, pair>(res); +} + +template +typed::map_list, pair> typed::basic_map, pair>::map_list() const +{ + auto res = isl::basic_map::map_list(); + return typed::map_list, pair>(res); +} + +template +typed::multi_pw_aff, pair> typed::basic_map, pair>::max_multi_pw_aff() const +{ + auto res = isl::basic_map::max_multi_pw_aff(); + return typed::multi_pw_aff, pair>(res); +} + +template +typed::multi_pw_aff, pair> typed::basic_map, pair>::min_multi_pw_aff() const +{ + auto res = isl::basic_map::min_multi_pw_aff(); + return typed::multi_pw_aff, pair>(res); +} + +template +typed::set<> typed::basic_map, pair>::params() const +{ + auto res = isl::basic_map::params(); + return typed::set<>(res); +} + +template +template +typed::map> typed::basic_map, pair>::preimage_domain(const typed::multi_aff> &ma) const +{ + auto res = isl::basic_map::preimage_domain(ma); + return typed::map>(res); +} + +template +template +typed::map> typed::basic_map, pair>::preimage_domain(const typed::multi_pw_aff> &mpa) const +{ + auto res = isl::basic_map::preimage_domain(mpa); + return typed::map>(res); +} + +template +template +typed::map> typed::basic_map, pair>::preimage_domain(const typed::pw_multi_aff> &pma) const +{ + auto res = isl::basic_map::preimage_domain(pma); + return typed::map>(res); +} + +template +template +typed::union_map> typed::basic_map, pair>::preimage_domain(const typed::union_pw_multi_aff> &upma) const +{ + auto res = isl::basic_map::preimage_domain(upma); + return typed::union_map>(res); +} + +template +template +typed::map, Range2> typed::basic_map, pair>::preimage_range(const typed::multi_aff> &ma) const +{ + auto res = isl::basic_map::preimage_range(ma); + return typed::map, Range2>(res); +} + +template +template +typed::map, Range2> typed::basic_map, pair>::preimage_range(const typed::pw_multi_aff> &pma) const +{ + auto res = isl::basic_map::preimage_range(pma); + return typed::map, Range2>(res); +} + +template +template +typed::union_map, Range2> typed::basic_map, pair>::preimage_range(const typed::union_pw_multi_aff> &upma) const +{ + auto res = isl::basic_map::preimage_range(upma); + return typed::union_map, Range2>(res); +} + +template +template +typed::map, Domain2>, pair, Range2>> typed::basic_map, pair>::product(const typed::map &map2) const +{ + auto res = isl::basic_map::product(map2); + return typed::map, Domain2>, pair, Range2>>(res); +} + +template +template +typed::union_map, Domain2>, pair, Range2>> typed::basic_map, pair>::product(const typed::union_map &umap2) const +{ + auto res = isl::basic_map::product(umap2); + return typed::union_map, Domain2>, pair, Range2>>(res); +} + +template +typed::map, pair> typed::basic_map, pair>::project_out_all_params() const +{ + auto res = isl::basic_map::project_out_all_params(); + return typed::map, pair>(res); +} + +template +typed::map, pair> typed::basic_map, pair>::project_out_param(const typed::id &id) const +{ + auto res = isl::basic_map::project_out_param(id); + return typed::map, pair>(res); +} + +template +typed::map, pair> typed::basic_map, pair>::project_out_param(const std::string &id) const +{ + auto res = isl::basic_map::project_out_param(id); + return typed::map, pair>(res); +} + +template +typed::map, pair> typed::basic_map, pair>::project_out_param(const typed::id_list &list) const +{ + auto res = isl::basic_map::project_out_param(list); + return typed::map, pair>(res); +} + +template +typed::set> typed::basic_map, pair>::range() const +{ + auto res = isl::basic_map::range(); + return typed::set>(res); +} + +template +typed::map, T1> typed::basic_map, pair>::range_factor_domain() const +{ + auto res = isl::basic_map::range_factor_domain(); + return typed::map, T1>(res); +} + +template +typed::map, T2> typed::basic_map, pair>::range_factor_range() const +{ + auto res = isl::basic_map::range_factor_range(); + return typed::map, T2>(res); +} + +template +typed::fixed_box, pair> typed::basic_map, pair>::range_lattice_tile() const +{ + auto res = isl::basic_map::range_lattice_tile(); + return typed::fixed_box, pair>(res); +} + +template +typed::union_map, pair>, pair> typed::basic_map, pair>::range_map() const +{ + auto res = isl::basic_map::range_map(); + return typed::union_map, pair>, pair>(res); +} + +template +template +typed::map, pair, Range2>> typed::basic_map, pair>::range_product(const typed::map, Range2> &map2) const +{ + auto res = isl::basic_map::range_product(map2); + return typed::map, pair, Range2>>(res); +} + +template +template +typed::union_map, pair, Range2>> typed::basic_map, pair>::range_product(const typed::union_map, Range2> &umap2) const +{ + auto res = isl::basic_map::range_product(umap2); + return typed::union_map, pair, Range2>>(res); +} + +template +typed::map, pair> typed::basic_map, pair>::range_reverse() const +{ + auto res = isl::basic_map::range_reverse(); + return typed::map, pair>(res); +} + +template +typed::fixed_box, pair> typed::basic_map, pair>::range_simple_fixed_box_hull() const +{ + auto res = isl::basic_map::range_simple_fixed_box_hull(); + return typed::fixed_box, pair>(res); +} + +template +typed::basic_map, pair> typed::basic_map, pair>::reverse() const +{ + auto res = isl::basic_map::reverse(); + return typed::basic_map, pair>(res); +} + +template +typed::space, pair> typed::basic_map, pair>::space() const +{ + auto res = isl::basic_map::space(); + return typed::space, pair>(res); +} + +template +typed::map, pair> typed::basic_map, pair>::subtract(const typed::map, pair> &map2) const +{ + auto res = isl::basic_map::subtract(map2); + return typed::map, pair>(res); +} + +template +typed::union_map, pair> typed::basic_map, pair>::subtract(const typed::union_map, pair> &umap2) const +{ + auto res = isl::basic_map::subtract(umap2); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::basic_map, pair>::subtract_domain(const typed::union_set> &dom) const +{ + auto res = isl::basic_map::subtract_domain(dom); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::basic_map, pair>::subtract_range(const typed::union_set> &dom) const +{ + auto res = isl::basic_map::subtract_range(dom); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::basic_map, pair>::to_union_map() const +{ + auto res = isl::basic_map::to_union_map(); + return typed::union_map, pair>(res); +} + +template +typed::map, T1>, T2> typed::basic_map, pair>::uncurry() const +{ + auto res = isl::basic_map::uncurry(); + return typed::map, T1>, T2>(res); +} + +template +typed::map, pair> typed::basic_map, pair>::unite(const typed::basic_map, pair> &bmap2) const +{ + auto res = isl::basic_map::unite(bmap2); + return typed::map, pair>(res); +} + +template +typed::map, pair> typed::basic_map, pair>::unite(const typed::map, pair> &map2) const +{ + auto res = isl::basic_map::unite(map2); + return typed::map, pair>(res); +} + +template +typed::union_map, pair> typed::basic_map, pair>::unite(const typed::union_map, pair> &umap2) const +{ + auto res = isl::basic_map::unite(umap2); + return typed::union_map, pair>(res); +} + +template +typed::map, pair> typed::basic_map, pair>::upper_bound(const typed::multi_pw_aff, pair> &upper) const +{ + auto res = isl::basic_map::upper_bound(upper); + return typed::map, pair>(res); +} + +template +typed::set, pair>> typed::basic_map, pair>::wrap() const +{ + auto res = isl::basic_map::wrap(); + return typed::set, pair>>(res); +} + +template +typed::basic_map, pair>::basic_map(const isl::ctx &ctx, const std::string &str) + : isl::basic_map(ctx, str) +{ +} + +template +template +typed::basic_map> typed::basic_map, pair>::apply_domain(const typed::basic_map, Domain2> &bmap2) const +{ + auto res = isl::basic_map::apply_domain(bmap2); + return typed::basic_map>(res); +} + +template +template +typed::map> typed::basic_map, pair>::apply_domain(const typed::map, Domain2> &map2) const +{ + auto res = isl::basic_map::apply_domain(map2); + return typed::map>(res); +} + +template +template +typed::union_map> typed::basic_map, pair>::apply_domain(const typed::union_map, Domain2> &umap2) const +{ + auto res = isl::basic_map::apply_domain(umap2); + return typed::union_map>(res); +} + +template +template +typed::basic_map, Arg2> typed::basic_map, pair>::apply_range(const typed::basic_map, Arg2> &bmap2) const +{ + auto res = isl::basic_map::apply_range(bmap2); + return typed::basic_map, Arg2>(res); +} + +template +template +typed::map, Arg2> typed::basic_map, pair>::apply_range(const typed::map, Arg2> &map2) const +{ + auto res = isl::basic_map::apply_range(map2); + return typed::map, Arg2>(res); +} + +template +template +typed::union_map, Arg2> typed::basic_map, pair>::apply_range(const typed::union_map, Arg2> &umap2) const +{ + auto res = isl::basic_map::apply_range(umap2); + return typed::union_map, Arg2>(res); +} + +template +typed::map, pair> typed::basic_map, pair>::as_map() const +{ + auto res = isl::basic_map::as_map(); + return typed::map, pair>(res); +} + +template +typed::multi_union_pw_aff, pair> typed::basic_map, pair>::as_multi_union_pw_aff() const +{ + auto res = isl::basic_map::as_multi_union_pw_aff(); + return typed::multi_union_pw_aff, pair>(res); +} + +template +typed::pw_multi_aff, pair> typed::basic_map, pair>::as_pw_multi_aff() const +{ + auto res = isl::basic_map::as_pw_multi_aff(); + return typed::pw_multi_aff, pair>(res); +} + +template +typed::union_pw_multi_aff, pair> typed::basic_map, pair>::as_union_pw_multi_aff() const +{ + auto res = isl::basic_map::as_union_pw_multi_aff(); + return typed::union_pw_multi_aff, pair>(res); +} + +template +typed::set> typed::basic_map, pair>::bind_domain(const typed::multi_id> &tuple) const +{ + auto res = isl::basic_map::bind_domain(tuple); + return typed::set>(res); +} + +template +typed::set> typed::basic_map, pair>::bind_range(const typed::multi_id> &tuple) const +{ + auto res = isl::basic_map::bind_range(tuple); + return typed::set>(res); +} + +template +typed::map, pair> typed::basic_map, pair>::coalesce() const +{ + auto res = isl::basic_map::coalesce(); + return typed::map, pair>(res); +} + +template +typed::map>> typed::basic_map, pair>::curry() const +{ + auto res = isl::basic_map::curry(); + return typed::map>>(res); +} + +template +typed::basic_map, pair> typed::basic_map, pair>::detect_equalities() const +{ + auto res = isl::basic_map::detect_equalities(); + return typed::basic_map, pair>(res); +} + +template +typed::set> typed::basic_map, pair>::domain() const +{ + auto res = isl::basic_map::domain(); + return typed::set>(res); +} + +template +typed::map> typed::basic_map, pair>::domain_factor_domain() const +{ + auto res = isl::basic_map::domain_factor_domain(); + return typed::map>(res); +} + +template +typed::map> typed::basic_map, pair>::domain_factor_range() const +{ + auto res = isl::basic_map::domain_factor_range(); + return typed::map>(res); +} + +template +typed::union_map, pair>, pair> typed::basic_map, pair>::domain_map() const +{ + auto res = isl::basic_map::domain_map(); + return typed::union_map, pair>, pair>(res); +} + +template +typed::union_pw_multi_aff, pair>, pair> typed::basic_map, pair>::domain_map_union_pw_multi_aff() const +{ + auto res = isl::basic_map::domain_map_union_pw_multi_aff(); + return typed::union_pw_multi_aff, pair>, pair>(res); +} + +template +template +typed::map, Domain2>, pair> typed::basic_map, pair>::domain_product(const typed::map> &map2) const +{ + auto res = isl::basic_map::domain_product(map2); + return typed::map, Domain2>, pair>(res); +} + +template +template +typed::union_map, Domain2>, pair> typed::basic_map, pair>::domain_product(const typed::union_map> &umap2) const +{ + auto res = isl::basic_map::domain_product(umap2); + return typed::union_map, Domain2>, pair>(res); +} + +template +typed::map, pair> typed::basic_map, pair>::domain_reverse() const +{ + auto res = isl::basic_map::domain_reverse(); + return typed::map, pair>(res); +} + +template +typed::map, pair> typed::basic_map, pair>::drop_unused_params() const +{ + auto res = isl::basic_map::drop_unused_params(); + return typed::map, pair>(res); +} + +template +bool typed::basic_map, pair>::every_map(const std::function, pair>)> &test) const +{ + auto lambda_test = [&] (isl::map arg0) { + return test(typed::map, pair>(arg0)); + }; + return isl::basic_map::every_map(lambda_test); +} + +template +typed::map, pair> typed::basic_map, pair>::extract_map(const typed::space, pair> &space) const +{ + auto res = isl::basic_map::extract_map(space); + return typed::map, pair>(res); +} + +template +typed::basic_map> typed::basic_map, pair>::flatten_domain() const +{ + auto res = isl::basic_map::flatten_domain(); + return typed::basic_map>(res); +} + +template +typed::basic_map, Anonymous> typed::basic_map, pair>::flatten_range() const +{ + auto res = isl::basic_map::flatten_range(); + return typed::basic_map, Anonymous>(res); +} + +template +void typed::basic_map, pair>::foreach_basic_map(const std::function, pair>)> &fn) const +{ + auto lambda_fn = [&] (isl::basic_map arg0) { + return fn(typed::basic_map, pair>(arg0)); + }; + return isl::basic_map::foreach_basic_map(lambda_fn); +} + +template +void typed::basic_map, pair>::foreach_map(const std::function, pair>)> &fn) const +{ + auto lambda_fn = [&] (isl::map arg0) { + return fn(typed::map, pair>(arg0)); + }; + return isl::basic_map::foreach_map(lambda_fn); +} + +template +typed::basic_map, pair> typed::basic_map, pair>::gist(const typed::basic_map, pair> &context) const +{ + auto res = isl::basic_map::gist(context); + return typed::basic_map, pair>(res); +} + +template +typed::map, pair> typed::basic_map, pair>::gist(const typed::map, pair> &context) const +{ + auto res = isl::basic_map::gist(context); + return typed::map, pair>(res); +} + +template +typed::union_map, pair> typed::basic_map, pair>::gist(const typed::union_map, pair> &context) const +{ + auto res = isl::basic_map::gist(context); + return typed::union_map, pair>(res); +} + +template +typed::map, pair> typed::basic_map, pair>::gist_domain(const typed::set> &context) const +{ + auto res = isl::basic_map::gist_domain(context); + return typed::map, pair>(res); +} + +template +typed::union_map, pair> typed::basic_map, pair>::gist_domain(const typed::union_set> &uset) const +{ + auto res = isl::basic_map::gist_domain(uset); + return typed::union_map, pair>(res); +} + +template +typed::map, pair> typed::basic_map, pair>::gist_params(const typed::set<> &context) const +{ + auto res = isl::basic_map::gist_params(context); + return typed::map, pair>(res); +} + +template +typed::basic_map, pair> typed::basic_map, pair>::intersect(const typed::basic_map, pair> &bmap2) const +{ + auto res = isl::basic_map::intersect(bmap2); + return typed::basic_map, pair>(res); +} + +template +typed::map, pair> typed::basic_map, pair>::intersect(const typed::map, pair> &map2) const +{ + auto res = isl::basic_map::intersect(map2); + return typed::map, pair>(res); +} + +template +typed::union_map, pair> typed::basic_map, pair>::intersect(const typed::union_map, pair> &umap2) const +{ + auto res = isl::basic_map::intersect(umap2); + return typed::union_map, pair>(res); +} + +template +typed::basic_map, pair> typed::basic_map, pair>::intersect_domain(const typed::basic_set> &bset) const +{ + auto res = isl::basic_map::intersect_domain(bset); + return typed::basic_map, pair>(res); +} + +template +typed::map, pair> typed::basic_map, pair>::intersect_domain(const typed::set> &set) const +{ + auto res = isl::basic_map::intersect_domain(set); + return typed::map, pair>(res); +} + +template +typed::union_map, pair> typed::basic_map, pair>::intersect_domain(const typed::space> &space) const +{ + auto res = isl::basic_map::intersect_domain(space); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::basic_map, pair>::intersect_domain(const typed::union_set> &uset) const +{ + auto res = isl::basic_map::intersect_domain(uset); + return typed::union_map, pair>(res); +} + +template +typed::basic_map, pair> typed::basic_map, pair>::intersect_domain(const typed::point> &bset) const +{ + auto res = isl::basic_map::intersect_domain(bset); + return typed::basic_map, pair>(res); +} + +template +typed::map, pair> typed::basic_map, pair>::intersect_domain_wrapped_domain(const typed::set &domain) const +{ + auto res = isl::basic_map::intersect_domain_wrapped_domain(domain); + return typed::map, pair>(res); +} + +template +typed::union_map, pair> typed::basic_map, pair>::intersect_domain_wrapped_domain(const typed::union_set &domain) const +{ + auto res = isl::basic_map::intersect_domain_wrapped_domain(domain); + return typed::union_map, pair>(res); +} + +template +typed::map, pair> typed::basic_map, pair>::intersect_params(const typed::set<> ¶ms) const +{ + auto res = isl::basic_map::intersect_params(params); + return typed::map, pair>(res); +} + +template +typed::basic_map, pair> typed::basic_map, pair>::intersect_range(const typed::basic_set> &bset) const +{ + auto res = isl::basic_map::intersect_range(bset); + return typed::basic_map, pair>(res); +} + +template +typed::map, pair> typed::basic_map, pair>::intersect_range(const typed::set> &set) const +{ + auto res = isl::basic_map::intersect_range(set); + return typed::map, pair>(res); +} + +template +typed::union_map, pair> typed::basic_map, pair>::intersect_range(const typed::space> &space) const +{ + auto res = isl::basic_map::intersect_range(space); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::basic_map, pair>::intersect_range(const typed::union_set> &uset) const +{ + auto res = isl::basic_map::intersect_range(uset); + return typed::union_map, pair>(res); +} + +template +typed::basic_map, pair> typed::basic_map, pair>::intersect_range(const typed::point> &bset) const +{ + auto res = isl::basic_map::intersect_range(bset); + return typed::basic_map, pair>(res); +} + +template +typed::map, pair> typed::basic_map, pair>::intersect_range_wrapped_domain(const typed::set &domain) const +{ + auto res = isl::basic_map::intersect_range_wrapped_domain(domain); + return typed::map, pair>(res); +} + +template +typed::union_map, pair> typed::basic_map, pair>::intersect_range_wrapped_domain(const typed::union_set &domain) const +{ + auto res = isl::basic_map::intersect_range_wrapped_domain(domain); + return typed::union_map, pair>(res); +} + +template +typed::map, pair> typed::basic_map, pair>::lexmax() const +{ + auto res = isl::basic_map::lexmax(); + return typed::map, pair>(res); +} + +template +typed::pw_multi_aff, pair> typed::basic_map, pair>::lexmax_pw_multi_aff() const +{ + auto res = isl::basic_map::lexmax_pw_multi_aff(); + return typed::pw_multi_aff, pair>(res); +} + +template +typed::map, pair> typed::basic_map, pair>::lexmin() const +{ + auto res = isl::basic_map::lexmin(); + return typed::map, pair>(res); +} + +template +typed::pw_multi_aff, pair> typed::basic_map, pair>::lexmin_pw_multi_aff() const +{ + auto res = isl::basic_map::lexmin_pw_multi_aff(); + return typed::pw_multi_aff, pair>(res); +} + +template +typed::map, pair> typed::basic_map, pair>::lower_bound(const typed::multi_pw_aff, pair> &lower) const +{ + auto res = isl::basic_map::lower_bound(lower); + return typed::map, pair>(res); +} + +template +typed::map_list, pair> typed::basic_map, pair>::map_list() const +{ + auto res = isl::basic_map::map_list(); + return typed::map_list, pair>(res); +} + +template +typed::multi_pw_aff, pair> typed::basic_map, pair>::max_multi_pw_aff() const +{ + auto res = isl::basic_map::max_multi_pw_aff(); + return typed::multi_pw_aff, pair>(res); +} + +template +typed::multi_pw_aff, pair> typed::basic_map, pair>::min_multi_pw_aff() const +{ + auto res = isl::basic_map::min_multi_pw_aff(); + return typed::multi_pw_aff, pair>(res); +} + +template +typed::set<> typed::basic_map, pair>::params() const +{ + auto res = isl::basic_map::params(); + return typed::set<>(res); +} + +template +template +typed::map> typed::basic_map, pair>::preimage_domain(const typed::multi_aff> &ma) const +{ + auto res = isl::basic_map::preimage_domain(ma); + return typed::map>(res); +} + +template +template +typed::map> typed::basic_map, pair>::preimage_domain(const typed::multi_pw_aff> &mpa) const +{ + auto res = isl::basic_map::preimage_domain(mpa); + return typed::map>(res); +} + +template +template +typed::map> typed::basic_map, pair>::preimage_domain(const typed::pw_multi_aff> &pma) const +{ + auto res = isl::basic_map::preimage_domain(pma); + return typed::map>(res); +} + +template +template +typed::union_map> typed::basic_map, pair>::preimage_domain(const typed::union_pw_multi_aff> &upma) const +{ + auto res = isl::basic_map::preimage_domain(upma); + return typed::union_map>(res); +} + +template +template +typed::map, Arg2> typed::basic_map, pair>::preimage_range(const typed::multi_aff> &ma) const +{ + auto res = isl::basic_map::preimage_range(ma); + return typed::map, Arg2>(res); +} + +template +template +typed::map, Arg2> typed::basic_map, pair>::preimage_range(const typed::pw_multi_aff> &pma) const +{ + auto res = isl::basic_map::preimage_range(pma); + return typed::map, Arg2>(res); +} + +template +template +typed::union_map, Arg2> typed::basic_map, pair>::preimage_range(const typed::union_pw_multi_aff> &upma) const +{ + auto res = isl::basic_map::preimage_range(upma); + return typed::union_map, Arg2>(res); +} + +template +template +typed::map, Domain2>, pair, Arg2>> typed::basic_map, pair>::product(const typed::map &map2) const +{ + auto res = isl::basic_map::product(map2); + return typed::map, Domain2>, pair, Arg2>>(res); +} + +template +template +typed::union_map, Domain2>, pair, Arg2>> typed::basic_map, pair>::product(const typed::union_map &umap2) const +{ + auto res = isl::basic_map::product(umap2); + return typed::union_map, Domain2>, pair, Arg2>>(res); +} + +template +typed::map, pair> typed::basic_map, pair>::project_out_all_params() const +{ + auto res = isl::basic_map::project_out_all_params(); + return typed::map, pair>(res); +} + +template +typed::map, pair> typed::basic_map, pair>::project_out_param(const typed::id &id) const +{ + auto res = isl::basic_map::project_out_param(id); + return typed::map, pair>(res); +} + +template +typed::map, pair> typed::basic_map, pair>::project_out_param(const std::string &id) const +{ + auto res = isl::basic_map::project_out_param(id); + return typed::map, pair>(res); +} + +template +typed::map, pair> typed::basic_map, pair>::project_out_param(const typed::id_list &list) const +{ + auto res = isl::basic_map::project_out_param(list); + return typed::map, pair>(res); +} + +template +typed::set> typed::basic_map, pair>::range() const +{ + auto res = isl::basic_map::range(); + return typed::set>(res); +} + +template +typed::map, Range> typed::basic_map, pair>::range_factor_domain() const +{ + auto res = isl::basic_map::range_factor_domain(); + return typed::map, Range>(res); +} + +template +typed::map, Range2> typed::basic_map, pair>::range_factor_range() const +{ + auto res = isl::basic_map::range_factor_range(); + return typed::map, Range2>(res); +} + +template +typed::fixed_box, pair> typed::basic_map, pair>::range_lattice_tile() const +{ + auto res = isl::basic_map::range_lattice_tile(); + return typed::fixed_box, pair>(res); +} + +template +typed::union_map, pair>, pair> typed::basic_map, pair>::range_map() const +{ + auto res = isl::basic_map::range_map(); + return typed::union_map, pair>, pair>(res); +} + +template +template +typed::map, pair, Arg2>> typed::basic_map, pair>::range_product(const typed::map, Arg2> &map2) const +{ + auto res = isl::basic_map::range_product(map2); + return typed::map, pair, Arg2>>(res); +} + +template +template +typed::union_map, pair, Arg2>> typed::basic_map, pair>::range_product(const typed::union_map, Arg2> &umap2) const +{ + auto res = isl::basic_map::range_product(umap2); + return typed::union_map, pair, Arg2>>(res); +} + +template +typed::map, pair> typed::basic_map, pair>::range_reverse() const +{ + auto res = isl::basic_map::range_reverse(); + return typed::map, pair>(res); +} + +template +typed::fixed_box, pair> typed::basic_map, pair>::range_simple_fixed_box_hull() const +{ + auto res = isl::basic_map::range_simple_fixed_box_hull(); + return typed::fixed_box, pair>(res); +} + +template +typed::basic_map, pair> typed::basic_map, pair>::reverse() const +{ + auto res = isl::basic_map::reverse(); + return typed::basic_map, pair>(res); +} + +template +typed::space, pair> typed::basic_map, pair>::space() const +{ + auto res = isl::basic_map::space(); + return typed::space, pair>(res); +} + +template +typed::map, pair> typed::basic_map, pair>::subtract(const typed::map, pair> &map2) const +{ + auto res = isl::basic_map::subtract(map2); + return typed::map, pair>(res); +} + +template +typed::union_map, pair> typed::basic_map, pair>::subtract(const typed::union_map, pair> &umap2) const +{ + auto res = isl::basic_map::subtract(umap2); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::basic_map, pair>::subtract_domain(const typed::union_set> &dom) const +{ + auto res = isl::basic_map::subtract_domain(dom); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::basic_map, pair>::subtract_range(const typed::union_set> &dom) const +{ + auto res = isl::basic_map::subtract_range(dom); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::basic_map, pair>::to_union_map() const +{ + auto res = isl::basic_map::to_union_map(); + return typed::union_map, pair>(res); +} + +template +typed::map, Range>, Range2> typed::basic_map, pair>::uncurry() const +{ + auto res = isl::basic_map::uncurry(); + return typed::map, Range>, Range2>(res); +} + +template +typed::map, pair> typed::basic_map, pair>::unite(const typed::basic_map, pair> &bmap2) const +{ + auto res = isl::basic_map::unite(bmap2); + return typed::map, pair>(res); +} + +template +typed::map, pair> typed::basic_map, pair>::unite(const typed::map, pair> &map2) const +{ + auto res = isl::basic_map::unite(map2); + return typed::map, pair>(res); +} + +template +typed::union_map, pair> typed::basic_map, pair>::unite(const typed::union_map, pair> &umap2) const +{ + auto res = isl::basic_map::unite(umap2); + return typed::union_map, pair>(res); +} + +template +typed::map, pair> typed::basic_map, pair>::upper_bound(const typed::multi_pw_aff, pair> &upper) const +{ + auto res = isl::basic_map::upper_bound(upper); + return typed::map, pair>(res); +} + +template +typed::set, pair>> typed::basic_map, pair>::wrap() const +{ + auto res = isl::basic_map::wrap(); + return typed::set, pair>>(res); +} + +typed::basic_set<>::basic_set(const typed::point<> &pnt) + : isl::basic_set(pnt) +{ +} + +typed::basic_set<>::basic_set(const isl::ctx &ctx, const std::string &str) + : isl::basic_set(ctx, str) +{ +} + +typed::set<> typed::basic_set<>::coalesce() const +{ + auto res = isl::basic_set::coalesce(); + return typed::set<>(res); +} + +typed::basic_set<> typed::basic_set<>::detect_equalities() const +{ + auto res = isl::basic_set::detect_equalities(); + return typed::basic_set<>(res); +} + +typed::set<> typed::basic_set<>::drop_unused_params() const +{ + auto res = isl::basic_set::drop_unused_params(); + return typed::set<>(res); +} + +bool typed::basic_set<>::every_set(const std::function)> &test) const +{ + auto lambda_test = [&] (isl::set arg0) { + return test(typed::set<>(arg0)); + }; + return isl::basic_set::every_set(lambda_test); +} + +typed::set<> typed::basic_set<>::extract_set(const typed::space<> &space) const +{ + auto res = isl::basic_set::extract_set(space); + return typed::set<>(res); +} + +void typed::basic_set<>::foreach_basic_set(const std::function)> &fn) const +{ + auto lambda_fn = [&] (isl::basic_set arg0) { + return fn(typed::basic_set<>(arg0)); + }; + return isl::basic_set::foreach_basic_set(lambda_fn); +} + +void typed::basic_set<>::foreach_point(const std::function)> &fn) const +{ + auto lambda_fn = [&] (isl::point arg0) { + return fn(typed::point<>(arg0)); + }; + return isl::basic_set::foreach_point(lambda_fn); +} + +void typed::basic_set<>::foreach_set(const std::function)> &fn) const +{ + auto lambda_fn = [&] (isl::set arg0) { + return fn(typed::set<>(arg0)); + }; + return isl::basic_set::foreach_set(lambda_fn); +} + +typed::basic_set<> typed::basic_set<>::gist(const typed::basic_set<> &context) const +{ + auto res = isl::basic_set::gist(context); + return typed::basic_set<>(res); +} + +typed::set<> typed::basic_set<>::gist(const typed::set<> &context) const +{ + auto res = isl::basic_set::gist(context); + return typed::set<>(res); +} + +typed::union_set<> typed::basic_set<>::gist(const typed::union_set<> &context) const +{ + auto res = isl::basic_set::gist(context); + return typed::union_set<>(res); +} + +typed::basic_set<> typed::basic_set<>::gist(const typed::point<> &context) const +{ + auto res = isl::basic_set::gist(context); + return typed::basic_set<>(res); +} + +typed::pw_aff typed::basic_set<>::indicator_function() const +{ + auto res = isl::basic_set::indicator_function(); + return typed::pw_aff(res); +} + +typed::basic_set<> typed::basic_set<>::intersect(const typed::basic_set<> &bset2) const +{ + auto res = isl::basic_set::intersect(bset2); + return typed::basic_set<>(res); +} + +typed::set<> typed::basic_set<>::intersect(const typed::set<> &set2) const +{ + auto res = isl::basic_set::intersect(set2); + return typed::set<>(res); +} + +typed::union_set<> typed::basic_set<>::intersect(const typed::union_set<> &uset2) const +{ + auto res = isl::basic_set::intersect(uset2); + return typed::union_set<>(res); +} + +typed::basic_set<> typed::basic_set<>::intersect(const typed::point<> &bset2) const +{ + auto res = isl::basic_set::intersect(bset2); + return typed::basic_set<>(res); +} + +typed::pw_aff typed::basic_set<>::param_pw_aff_on_domain(const typed::id &id) const +{ + auto res = isl::basic_set::param_pw_aff_on_domain(id); + return typed::pw_aff(res); +} + +typed::pw_aff typed::basic_set<>::param_pw_aff_on_domain(const std::string &id) const +{ + auto res = isl::basic_set::param_pw_aff_on_domain(id); + return typed::pw_aff(res); +} + +typed::set<> typed::basic_set<>::project_out_all_params() const +{ + auto res = isl::basic_set::project_out_all_params(); + return typed::set<>(res); +} + +typed::set<> typed::basic_set<>::project_out_param(const typed::id &id) const +{ + auto res = isl::basic_set::project_out_param(id); + return typed::set<>(res); +} + +typed::set<> typed::basic_set<>::project_out_param(const std::string &id) const +{ + auto res = isl::basic_set::project_out_param(id); + return typed::set<>(res); +} + +typed::set<> typed::basic_set<>::project_out_param(const typed::id_list &list) const +{ + auto res = isl::basic_set::project_out_param(list); + return typed::set<>(res); +} + +typed::pw_aff typed::basic_set<>::pw_aff_on_domain(const typed::val &v) const +{ + auto res = isl::basic_set::pw_aff_on_domain(v); + return typed::pw_aff(res); +} + +typed::pw_aff typed::basic_set<>::pw_aff_on_domain(long v) const +{ + auto res = isl::basic_set::pw_aff_on_domain(v); + return typed::pw_aff(res); +} + +template +typed::pw_multi_aff typed::basic_set<>::pw_multi_aff_on_domain(const typed::multi_val &mv) const +{ + auto res = isl::basic_set::pw_multi_aff_on_domain(mv); + return typed::pw_multi_aff(res); +} + +typed::set_list<> typed::basic_set<>::set_list() const +{ + auto res = isl::basic_set::set_list(); + return typed::set_list<>(res); +} + +typed::space<> typed::basic_set<>::space() const +{ + auto res = isl::basic_set::space(); + return typed::space<>(res); +} + +typed::set<> typed::basic_set<>::subtract(const typed::set<> &set2) const +{ + auto res = isl::basic_set::subtract(set2); + return typed::set<>(res); +} + +typed::union_set<> typed::basic_set<>::subtract(const typed::union_set<> &uset2) const +{ + auto res = isl::basic_set::subtract(uset2); + return typed::union_set<>(res); +} + +typed::set<> typed::basic_set<>::to_set() const +{ + auto res = isl::basic_set::to_set(); + return typed::set<>(res); +} + +typed::union_set<> typed::basic_set<>::to_union_set() const +{ + auto res = isl::basic_set::to_union_set(); + return typed::union_set<>(res); +} + +template +typed::set typed::basic_set<>::unbind_params(const typed::multi_id &tuple) const +{ + auto res = isl::basic_set::unbind_params(tuple); + return typed::set(res); +} + +typed::set<> typed::basic_set<>::unite(const typed::basic_set<> &bset2) const +{ + auto res = isl::basic_set::unite(bset2); + return typed::set<>(res); +} + +typed::set<> typed::basic_set<>::unite(const typed::set<> &set2) const +{ + auto res = isl::basic_set::unite(set2); + return typed::set<>(res); +} + +typed::union_set<> typed::basic_set<>::unite(const typed::union_set<> &uset2) const +{ + auto res = isl::basic_set::unite(uset2); + return typed::union_set<>(res); +} + +typed::set<> typed::basic_set<>::unite(const typed::point<> &bset2) const +{ + auto res = isl::basic_set::unite(bset2); + return typed::set<>(res); +} + +template +typed::basic_set::basic_set(const typed::point &pnt) + : isl::basic_set(pnt) +{ +} + +template +typed::basic_set::basic_set(const isl::ctx &ctx, const std::string &str) + : isl::basic_set(ctx, str) +{ +} + +template +template +typed::basic_set typed::basic_set::apply(const typed::basic_map &bmap) const +{ + auto res = isl::basic_set::apply(bmap); + return typed::basic_set(res); +} + +template +template +typed::set typed::basic_set::apply(const typed::map &map) const +{ + auto res = isl::basic_set::apply(map); + return typed::set(res); +} + +template +template +typed::union_set typed::basic_set::apply(const typed::union_map &umap) const +{ + auto res = isl::basic_set::apply(umap); + return typed::union_set(res); +} + +template +typed::pw_multi_aff typed::basic_set::as_pw_multi_aff() const +{ + auto res = isl::basic_set::as_pw_multi_aff(); + return typed::pw_multi_aff(res); +} + +template +typed::set typed::basic_set::as_set() const +{ + auto res = isl::basic_set::as_set(); + return typed::set(res); +} + +template +typed::set<> typed::basic_set::bind(const typed::multi_id &tuple) const +{ + auto res = isl::basic_set::bind(tuple); + return typed::set<>(res); +} + +template +typed::set typed::basic_set::coalesce() const +{ + auto res = isl::basic_set::coalesce(); + return typed::set(res); +} + +template +typed::basic_set typed::basic_set::detect_equalities() const +{ + auto res = isl::basic_set::detect_equalities(); + return typed::basic_set(res); +} + +template +typed::set typed::basic_set::drop_unused_params() const +{ + auto res = isl::basic_set::drop_unused_params(); + return typed::set(res); +} + +template +bool typed::basic_set::every_set(const std::function)> &test) const +{ + auto lambda_test = [&] (isl::set arg0) { + return test(typed::set(arg0)); + }; + return isl::basic_set::every_set(lambda_test); +} + +template +typed::set typed::basic_set::extract_set(const typed::space &space) const +{ + auto res = isl::basic_set::extract_set(space); + return typed::set(res); +} + +template +void typed::basic_set::foreach_basic_set(const std::function)> &fn) const +{ + auto lambda_fn = [&] (isl::basic_set arg0) { + return fn(typed::basic_set(arg0)); + }; + return isl::basic_set::foreach_basic_set(lambda_fn); +} + +template +void typed::basic_set::foreach_point(const std::function)> &fn) const +{ + auto lambda_fn = [&] (isl::point arg0) { + return fn(typed::point(arg0)); + }; + return isl::basic_set::foreach_point(lambda_fn); +} + +template +void typed::basic_set::foreach_set(const std::function)> &fn) const +{ + auto lambda_fn = [&] (isl::set arg0) { + return fn(typed::set(arg0)); + }; + return isl::basic_set::foreach_set(lambda_fn); +} + +template +typed::basic_set typed::basic_set::gist(const typed::basic_set &context) const +{ + auto res = isl::basic_set::gist(context); + return typed::basic_set(res); +} + +template +typed::set typed::basic_set::gist(const typed::set &context) const +{ + auto res = isl::basic_set::gist(context); + return typed::set(res); +} + +template +typed::union_set typed::basic_set::gist(const typed::union_set &context) const +{ + auto res = isl::basic_set::gist(context); + return typed::union_set(res); +} + +template +typed::basic_set typed::basic_set::gist(const typed::point &context) const +{ + auto res = isl::basic_set::gist(context); + return typed::basic_set(res); +} + +template +typed::set typed::basic_set::gist_params(const typed::set<> &context) const +{ + auto res = isl::basic_set::gist_params(context); + return typed::set(res); +} + +template +typed::map typed::basic_set::identity() const +{ + auto res = isl::basic_set::identity(); + return typed::map(res); +} + +template +typed::pw_aff typed::basic_set::indicator_function() const +{ + auto res = isl::basic_set::indicator_function(); + return typed::pw_aff(res); +} + +template +template +typed::map typed::basic_set::insert_domain(const typed::space &domain) const +{ + auto res = isl::basic_set::insert_domain(domain); + return typed::map(res); +} + +template +typed::basic_set typed::basic_set::intersect(const typed::basic_set &bset2) const +{ + auto res = isl::basic_set::intersect(bset2); + return typed::basic_set(res); +} + +template +typed::set typed::basic_set::intersect(const typed::set &set2) const +{ + auto res = isl::basic_set::intersect(set2); + return typed::set(res); +} + +template +typed::union_set typed::basic_set::intersect(const typed::union_set &uset2) const +{ + auto res = isl::basic_set::intersect(uset2); + return typed::union_set(res); +} + +template +typed::basic_set typed::basic_set::intersect(const typed::point &bset2) const +{ + auto res = isl::basic_set::intersect(bset2); + return typed::basic_set(res); +} + +template +typed::basic_set typed::basic_set::intersect_params(const typed::basic_set<> &bset2) const +{ + auto res = isl::basic_set::intersect_params(bset2); + return typed::basic_set(res); +} + +template +typed::set typed::basic_set::intersect_params(const typed::set<> ¶ms) const +{ + auto res = isl::basic_set::intersect_params(params); + return typed::set(res); +} + +template +typed::basic_set typed::basic_set::intersect_params(const typed::point<> &bset2) const +{ + auto res = isl::basic_set::intersect_params(bset2); + return typed::basic_set(res); +} + +template +typed::fixed_box typed::basic_set::lattice_tile() const +{ + auto res = isl::basic_set::lattice_tile(); + return typed::fixed_box(res); +} + +template +typed::set typed::basic_set::lexmax() const +{ + auto res = isl::basic_set::lexmax(); + return typed::set(res); +} + +template +typed::pw_multi_aff typed::basic_set::lexmax_pw_multi_aff() const +{ + auto res = isl::basic_set::lexmax_pw_multi_aff(); + return typed::pw_multi_aff(res); +} + +template +typed::set typed::basic_set::lexmin() const +{ + auto res = isl::basic_set::lexmin(); + return typed::set(res); +} + +template +typed::pw_multi_aff typed::basic_set::lexmin_pw_multi_aff() const +{ + auto res = isl::basic_set::lexmin_pw_multi_aff(); + return typed::pw_multi_aff(res); +} + +template +typed::set typed::basic_set::lower_bound(const typed::multi_pw_aff &lower) const +{ + auto res = isl::basic_set::lower_bound(lower); + return typed::set(res); +} + +template +typed::set typed::basic_set::lower_bound(const typed::multi_val &lower) const +{ + auto res = isl::basic_set::lower_bound(lower); + return typed::set(res); +} + +template +typed::multi_pw_aff typed::basic_set::max_multi_pw_aff() const +{ + auto res = isl::basic_set::max_multi_pw_aff(); + return typed::multi_pw_aff(res); +} + +template +typed::multi_pw_aff typed::basic_set::min_multi_pw_aff() const +{ + auto res = isl::basic_set::min_multi_pw_aff(); + return typed::multi_pw_aff(res); +} + +template +typed::pw_aff typed::basic_set::param_pw_aff_on_domain(const typed::id &id) const +{ + auto res = isl::basic_set::param_pw_aff_on_domain(id); + return typed::pw_aff(res); +} + +template +typed::pw_aff typed::basic_set::param_pw_aff_on_domain(const std::string &id) const +{ + auto res = isl::basic_set::param_pw_aff_on_domain(id); + return typed::pw_aff(res); +} + +template +typed::basic_set<> typed::basic_set::params() const +{ + auto res = isl::basic_set::params(); + return typed::basic_set<>(res); +} + +template +typed::multi_val typed::basic_set::plain_multi_val_if_fixed() const +{ + auto res = isl::basic_set::plain_multi_val_if_fixed(); + return typed::multi_val(res); +} + +template +template +typed::set typed::basic_set::preimage(const typed::multi_aff &ma) const +{ + auto res = isl::basic_set::preimage(ma); + return typed::set(res); +} + +template +template +typed::set typed::basic_set::preimage(const typed::multi_pw_aff &mpa) const +{ + auto res = isl::basic_set::preimage(mpa); + return typed::set(res); +} + +template +template +typed::set typed::basic_set::preimage(const typed::pw_multi_aff &pma) const +{ + auto res = isl::basic_set::preimage(pma); + return typed::set(res); +} + +template +template +typed::union_set typed::basic_set::preimage(const typed::union_pw_multi_aff &upma) const +{ + auto res = isl::basic_set::preimage(upma); + return typed::union_set(res); +} + +template +template +typed::set> typed::basic_set::product(const typed::set &set2) const +{ + auto res = isl::basic_set::product(set2); + return typed::set>(res); +} + +template +typed::set typed::basic_set::project_out_all_params() const +{ + auto res = isl::basic_set::project_out_all_params(); + return typed::set(res); +} + +template +typed::set typed::basic_set::project_out_param(const typed::id &id) const +{ + auto res = isl::basic_set::project_out_param(id); + return typed::set(res); +} + +template +typed::set typed::basic_set::project_out_param(const std::string &id) const +{ + auto res = isl::basic_set::project_out_param(id); + return typed::set(res); +} + +template +typed::set typed::basic_set::project_out_param(const typed::id_list &list) const +{ + auto res = isl::basic_set::project_out_param(list); + return typed::set(res); +} + +template +typed::pw_aff typed::basic_set::pw_aff_on_domain(const typed::val &v) const +{ + auto res = isl::basic_set::pw_aff_on_domain(v); + return typed::pw_aff(res); +} + +template +typed::pw_aff typed::basic_set::pw_aff_on_domain(long v) const +{ + auto res = isl::basic_set::pw_aff_on_domain(v); + return typed::pw_aff(res); +} + +template +template +typed::pw_multi_aff typed::basic_set::pw_multi_aff_on_domain(const typed::multi_val &mv) const +{ + auto res = isl::basic_set::pw_multi_aff_on_domain(mv); + return typed::pw_multi_aff(res); +} + +template +typed::set_list typed::basic_set::set_list() const +{ + auto res = isl::basic_set::set_list(); + return typed::set_list(res); +} + +template +typed::fixed_box typed::basic_set::simple_fixed_box_hull() const +{ + auto res = isl::basic_set::simple_fixed_box_hull(); + return typed::fixed_box(res); +} + +template +typed::space typed::basic_set::space() const +{ + auto res = isl::basic_set::space(); + return typed::space(res); +} + +template +typed::set typed::basic_set::subtract(const typed::set &set2) const +{ + auto res = isl::basic_set::subtract(set2); + return typed::set(res); +} + +template +typed::union_set typed::basic_set::subtract(const typed::union_set &uset2) const +{ + auto res = isl::basic_set::subtract(uset2); + return typed::union_set(res); +} + +template +typed::set typed::basic_set::to_set() const +{ + auto res = isl::basic_set::to_set(); + return typed::set(res); +} + +template +typed::union_set typed::basic_set::to_union_set() const +{ + auto res = isl::basic_set::to_union_set(); + return typed::union_set(res); +} + +template +typed::map typed::basic_set::translation() const +{ + auto res = isl::basic_set::translation(); + return typed::map(res); +} + +template +template +typed::map typed::basic_set::unbind_params_insert_domain(const typed::multi_id &domain) const +{ + auto res = isl::basic_set::unbind_params_insert_domain(domain); + return typed::map(res); +} + +template +typed::set typed::basic_set::unite(const typed::basic_set &bset2) const +{ + auto res = isl::basic_set::unite(bset2); + return typed::set(res); +} + +template +typed::set typed::basic_set::unite(const typed::set &set2) const +{ + auto res = isl::basic_set::unite(set2); + return typed::set(res); +} + +template +typed::union_set typed::basic_set::unite(const typed::union_set &uset2) const +{ + auto res = isl::basic_set::unite(uset2); + return typed::union_set(res); +} + +template +typed::set typed::basic_set::unite(const typed::point &bset2) const +{ + auto res = isl::basic_set::unite(bset2); + return typed::set(res); +} + +template +typed::set typed::basic_set::upper_bound(const typed::multi_pw_aff &upper) const +{ + auto res = isl::basic_set::upper_bound(upper); + return typed::set(res); +} + +template +typed::set typed::basic_set::upper_bound(const typed::multi_val &upper) const +{ + auto res = isl::basic_set::upper_bound(upper); + return typed::set(res); +} + +template +typed::basic_set>::basic_set(const typed::point> &pnt) + : isl::basic_set(pnt) +{ +} + +template +typed::basic_set>::basic_set(const isl::ctx &ctx, const std::string &str) + : isl::basic_set(ctx, str) +{ +} + +template +template +typed::basic_set typed::basic_set>::apply(const typed::basic_map, Arg2> &bmap) const +{ + auto res = isl::basic_set::apply(bmap); + return typed::basic_set(res); +} + +template +template +typed::set typed::basic_set>::apply(const typed::map, Arg2> &map) const +{ + auto res = isl::basic_set::apply(map); + return typed::set(res); +} + +template +template +typed::union_set typed::basic_set>::apply(const typed::union_map, Arg2> &umap) const +{ + auto res = isl::basic_set::apply(umap); + return typed::union_set(res); +} + +template +typed::pw_multi_aff> typed::basic_set>::as_pw_multi_aff() const +{ + auto res = isl::basic_set::as_pw_multi_aff(); + return typed::pw_multi_aff>(res); +} + +template +typed::set> typed::basic_set>::as_set() const +{ + auto res = isl::basic_set::as_set(); + return typed::set>(res); +} + +template +typed::set<> typed::basic_set>::bind(const typed::multi_id> &tuple) const +{ + auto res = isl::basic_set::bind(tuple); + return typed::set<>(res); +} + +template +typed::set> typed::basic_set>::coalesce() const +{ + auto res = isl::basic_set::coalesce(); + return typed::set>(res); +} + +template +typed::basic_set> typed::basic_set>::detect_equalities() const +{ + auto res = isl::basic_set::detect_equalities(); + return typed::basic_set>(res); +} + +template +typed::set> typed::basic_set>::drop_unused_params() const +{ + auto res = isl::basic_set::drop_unused_params(); + return typed::set>(res); +} + +template +bool typed::basic_set>::every_set(const std::function>)> &test) const +{ + auto lambda_test = [&] (isl::set arg0) { + return test(typed::set>(arg0)); + }; + return isl::basic_set::every_set(lambda_test); +} + +template +typed::set> typed::basic_set>::extract_set(const typed::space> &space) const +{ + auto res = isl::basic_set::extract_set(space); + return typed::set>(res); +} + +template +void typed::basic_set>::foreach_basic_set(const std::function>)> &fn) const +{ + auto lambda_fn = [&] (isl::basic_set arg0) { + return fn(typed::basic_set>(arg0)); + }; + return isl::basic_set::foreach_basic_set(lambda_fn); +} + +template +void typed::basic_set>::foreach_point(const std::function>)> &fn) const +{ + auto lambda_fn = [&] (isl::point arg0) { + return fn(typed::point>(arg0)); + }; + return isl::basic_set::foreach_point(lambda_fn); +} + +template +void typed::basic_set>::foreach_set(const std::function>)> &fn) const +{ + auto lambda_fn = [&] (isl::set arg0) { + return fn(typed::set>(arg0)); + }; + return isl::basic_set::foreach_set(lambda_fn); +} + +template +typed::basic_set> typed::basic_set>::gist(const typed::basic_set> &context) const +{ + auto res = isl::basic_set::gist(context); + return typed::basic_set>(res); +} + +template +typed::set> typed::basic_set>::gist(const typed::set> &context) const +{ + auto res = isl::basic_set::gist(context); + return typed::set>(res); +} + +template +typed::union_set> typed::basic_set>::gist(const typed::union_set> &context) const +{ + auto res = isl::basic_set::gist(context); + return typed::union_set>(res); +} + +template +typed::basic_set> typed::basic_set>::gist(const typed::point> &context) const +{ + auto res = isl::basic_set::gist(context); + return typed::basic_set>(res); +} + +template +typed::set> typed::basic_set>::gist_params(const typed::set<> &context) const +{ + auto res = isl::basic_set::gist_params(context); + return typed::set>(res); +} + +template +typed::map, pair> typed::basic_set>::identity() const +{ + auto res = isl::basic_set::identity(); + return typed::map, pair>(res); +} + +template +typed::pw_aff, Anonymous> typed::basic_set>::indicator_function() const +{ + auto res = isl::basic_set::indicator_function(); + return typed::pw_aff, Anonymous>(res); +} + +template +template +typed::map> typed::basic_set>::insert_domain(const typed::space &domain) const +{ + auto res = isl::basic_set::insert_domain(domain); + return typed::map>(res); +} + +template +typed::basic_set> typed::basic_set>::intersect(const typed::basic_set> &bset2) const +{ + auto res = isl::basic_set::intersect(bset2); + return typed::basic_set>(res); +} + +template +typed::set> typed::basic_set>::intersect(const typed::set> &set2) const +{ + auto res = isl::basic_set::intersect(set2); + return typed::set>(res); +} + +template +typed::union_set> typed::basic_set>::intersect(const typed::union_set> &uset2) const +{ + auto res = isl::basic_set::intersect(uset2); + return typed::union_set>(res); +} + +template +typed::basic_set> typed::basic_set>::intersect(const typed::point> &bset2) const +{ + auto res = isl::basic_set::intersect(bset2); + return typed::basic_set>(res); +} + +template +typed::basic_set> typed::basic_set>::intersect_params(const typed::basic_set<> &bset2) const +{ + auto res = isl::basic_set::intersect_params(bset2); + return typed::basic_set>(res); +} + +template +typed::set> typed::basic_set>::intersect_params(const typed::set<> ¶ms) const +{ + auto res = isl::basic_set::intersect_params(params); + return typed::set>(res); +} + +template +typed::basic_set> typed::basic_set>::intersect_params(const typed::point<> &bset2) const +{ + auto res = isl::basic_set::intersect_params(bset2); + return typed::basic_set>(res); +} + +template +typed::fixed_box> typed::basic_set>::lattice_tile() const +{ + auto res = isl::basic_set::lattice_tile(); + return typed::fixed_box>(res); +} + +template +typed::set> typed::basic_set>::lexmax() const +{ + auto res = isl::basic_set::lexmax(); + return typed::set>(res); +} + +template +typed::pw_multi_aff> typed::basic_set>::lexmax_pw_multi_aff() const +{ + auto res = isl::basic_set::lexmax_pw_multi_aff(); + return typed::pw_multi_aff>(res); +} + +template +typed::set> typed::basic_set>::lexmin() const +{ + auto res = isl::basic_set::lexmin(); + return typed::set>(res); +} + +template +typed::pw_multi_aff> typed::basic_set>::lexmin_pw_multi_aff() const +{ + auto res = isl::basic_set::lexmin_pw_multi_aff(); + return typed::pw_multi_aff>(res); +} + +template +typed::set> typed::basic_set>::lower_bound(const typed::multi_pw_aff> &lower) const +{ + auto res = isl::basic_set::lower_bound(lower); + return typed::set>(res); +} + +template +typed::set> typed::basic_set>::lower_bound(const typed::multi_val> &lower) const +{ + auto res = isl::basic_set::lower_bound(lower); + return typed::set>(res); +} + +template +typed::multi_pw_aff> typed::basic_set>::max_multi_pw_aff() const +{ + auto res = isl::basic_set::max_multi_pw_aff(); + return typed::multi_pw_aff>(res); +} + +template +typed::multi_pw_aff> typed::basic_set>::min_multi_pw_aff() const +{ + auto res = isl::basic_set::min_multi_pw_aff(); + return typed::multi_pw_aff>(res); +} + +template +typed::pw_aff, Anonymous> typed::basic_set>::param_pw_aff_on_domain(const typed::id &id) const +{ + auto res = isl::basic_set::param_pw_aff_on_domain(id); + return typed::pw_aff, Anonymous>(res); +} + +template +typed::pw_aff, Anonymous> typed::basic_set>::param_pw_aff_on_domain(const std::string &id) const +{ + auto res = isl::basic_set::param_pw_aff_on_domain(id); + return typed::pw_aff, Anonymous>(res); +} + +template +typed::basic_set<> typed::basic_set>::params() const +{ + auto res = isl::basic_set::params(); + return typed::basic_set<>(res); +} + +template +typed::multi_val> typed::basic_set>::plain_multi_val_if_fixed() const +{ + auto res = isl::basic_set::plain_multi_val_if_fixed(); + return typed::multi_val>(res); +} + +template +template +typed::set typed::basic_set>::preimage(const typed::multi_aff> &ma) const +{ + auto res = isl::basic_set::preimage(ma); + return typed::set(res); +} + +template +template +typed::set typed::basic_set>::preimage(const typed::multi_pw_aff> &mpa) const +{ + auto res = isl::basic_set::preimage(mpa); + return typed::set(res); +} + +template +template +typed::set typed::basic_set>::preimage(const typed::pw_multi_aff> &pma) const +{ + auto res = isl::basic_set::preimage(pma); + return typed::set(res); +} + +template +template +typed::union_set typed::basic_set>::preimage(const typed::union_pw_multi_aff> &upma) const +{ + auto res = isl::basic_set::preimage(upma); + return typed::union_set(res); +} + +template +template +typed::set, Arg2>> typed::basic_set>::product(const typed::set &set2) const +{ + auto res = isl::basic_set::product(set2); + return typed::set, Arg2>>(res); +} + +template +typed::set> typed::basic_set>::project_out_all_params() const +{ + auto res = isl::basic_set::project_out_all_params(); + return typed::set>(res); +} + +template +typed::set> typed::basic_set>::project_out_param(const typed::id &id) const +{ + auto res = isl::basic_set::project_out_param(id); + return typed::set>(res); +} + +template +typed::set> typed::basic_set>::project_out_param(const std::string &id) const +{ + auto res = isl::basic_set::project_out_param(id); + return typed::set>(res); +} + +template +typed::set> typed::basic_set>::project_out_param(const typed::id_list &list) const +{ + auto res = isl::basic_set::project_out_param(list); + return typed::set>(res); +} + +template +typed::pw_aff, Anonymous> typed::basic_set>::pw_aff_on_domain(const typed::val &v) const +{ + auto res = isl::basic_set::pw_aff_on_domain(v); + return typed::pw_aff, Anonymous>(res); +} + +template +typed::pw_aff, Anonymous> typed::basic_set>::pw_aff_on_domain(long v) const +{ + auto res = isl::basic_set::pw_aff_on_domain(v); + return typed::pw_aff, Anonymous>(res); +} + +template +template +typed::pw_multi_aff, Arg2> typed::basic_set>::pw_multi_aff_on_domain(const typed::multi_val &mv) const +{ + auto res = isl::basic_set::pw_multi_aff_on_domain(mv); + return typed::pw_multi_aff, Arg2>(res); +} + +template +typed::set_list> typed::basic_set>::set_list() const +{ + auto res = isl::basic_set::set_list(); + return typed::set_list>(res); +} + +template +typed::fixed_box> typed::basic_set>::simple_fixed_box_hull() const +{ + auto res = isl::basic_set::simple_fixed_box_hull(); + return typed::fixed_box>(res); +} + +template +typed::space> typed::basic_set>::space() const +{ + auto res = isl::basic_set::space(); + return typed::space>(res); +} + +template +typed::set> typed::basic_set>::subtract(const typed::set> &set2) const +{ + auto res = isl::basic_set::subtract(set2); + return typed::set>(res); +} + +template +typed::union_set> typed::basic_set>::subtract(const typed::union_set> &uset2) const +{ + auto res = isl::basic_set::subtract(uset2); + return typed::union_set>(res); +} + +template +typed::set> typed::basic_set>::to_set() const +{ + auto res = isl::basic_set::to_set(); + return typed::set>(res); +} + +template +typed::union_set> typed::basic_set>::to_union_set() const +{ + auto res = isl::basic_set::to_union_set(); + return typed::union_set>(res); +} + +template +typed::map, pair> typed::basic_set>::translation() const +{ + auto res = isl::basic_set::translation(); + return typed::map, pair>(res); +} + +template +template +typed::map> typed::basic_set>::unbind_params_insert_domain(const typed::multi_id &domain) const +{ + auto res = isl::basic_set::unbind_params_insert_domain(domain); + return typed::map>(res); +} + +template +typed::set> typed::basic_set>::unite(const typed::basic_set> &bset2) const +{ + auto res = isl::basic_set::unite(bset2); + return typed::set>(res); +} + +template +typed::set> typed::basic_set>::unite(const typed::set> &set2) const +{ + auto res = isl::basic_set::unite(set2); + return typed::set>(res); +} + +template +typed::union_set> typed::basic_set>::unite(const typed::union_set> &uset2) const +{ + auto res = isl::basic_set::unite(uset2); + return typed::union_set>(res); +} + +template +typed::set> typed::basic_set>::unite(const typed::point> &bset2) const +{ + auto res = isl::basic_set::unite(bset2); + return typed::set>(res); +} + +template +typed::map typed::basic_set>::unwrap() const +{ + auto res = isl::basic_set::unwrap(); + return typed::map(res); +} + +template +typed::set> typed::basic_set>::upper_bound(const typed::multi_pw_aff> &upper) const +{ + auto res = isl::basic_set::upper_bound(upper); + return typed::set>(res); +} + +template +typed::set> typed::basic_set>::upper_bound(const typed::multi_val> &upper) const +{ + auto res = isl::basic_set::upper_bound(upper); + return typed::set>(res); +} + +template +typed::set> typed::basic_set>::wrapped_reverse() const +{ + auto res = isl::basic_set::wrapped_reverse(); + return typed::set>(res); +} + +template +typed::fixed_box::fixed_box(const isl::ctx &ctx, const std::string &str) + : isl::fixed_box(ctx, str) +{ +} + +template +typed::multi_aff typed::fixed_box::offset() const +{ + auto res = isl::fixed_box::offset(); + return typed::multi_aff(res); +} + +template +typed::multi_val typed::fixed_box::size() const +{ + auto res = isl::fixed_box::size(); + return typed::multi_val(res); +} + +template +typed::space typed::fixed_box::space() const +{ + auto res = isl::fixed_box::space(); + return typed::space(res); +} + +template +typed::fixed_box::fixed_box(const isl::ctx &ctx, const std::string &str) + : isl::fixed_box(ctx, str) +{ +} + +template +typed::multi_aff typed::fixed_box::offset() const +{ + auto res = isl::fixed_box::offset(); + return typed::multi_aff(res); +} + +template +typed::multi_val typed::fixed_box::size() const +{ + auto res = isl::fixed_box::size(); + return typed::multi_val(res); +} + +template +typed::space typed::fixed_box::space() const +{ + auto res = isl::fixed_box::space(); + return typed::space(res); +} + +typed::id::id(const isl::ctx &ctx, const std::string &str) + : isl::id(ctx, str) +{ +} + +typed::id_list::id_list(const isl::ctx &ctx, int n) + : isl::id_list(ctx, n) +{ +} + +typed::id_list::id_list(const typed::id &el) + : isl::id_list(el) +{ +} + +typed::id_list::id_list(const isl::ctx &ctx, const std::string &str) + : isl::id_list(ctx, str) +{ +} + +typed::id_list typed::id_list::add(const typed::id &el) const +{ + auto res = isl::id_list::add(el); + return typed::id_list(res); +} + +typed::id_list typed::id_list::add(const std::string &el) const +{ + auto res = isl::id_list::add(el); + return typed::id_list(res); +} + +typed::id typed::id_list::at(int index) const +{ + auto res = isl::id_list::at(index); + return typed::id(res); +} + +typed::id_list typed::id_list::drop(unsigned int first, unsigned int n) const +{ + auto res = isl::id_list::drop(first, n); + return typed::id_list(res); +} + +void typed::id_list::foreach(const std::function)> &fn) const +{ + auto lambda_fn = [&] (isl::id arg0) { + return fn(typed::id(arg0)); + }; + return isl::id_list::foreach(lambda_fn); +} + +void typed::id_list::foreach_scc(const std::function, typed::id)> &follows, const std::function)> &fn) const +{ + auto lambda_follows = [&] (isl::id arg0, isl::id arg1) { + return follows(typed::id(arg0), typed::id(arg1)); + }; + auto lambda_fn = [&] (isl::id_list arg0) { + return fn(typed::id_list(arg0)); + }; + return isl::id_list::foreach_scc(lambda_follows, lambda_fn); +} + +typed::id_list typed::id_list::set_at(int index, const typed::id &el) const +{ + auto res = isl::id_list::set_at(index, el); + return typed::id_list(res); +} + +typed::id_list typed::id_list::set_at(int index, const std::string &el) const +{ + auto res = isl::id_list::set_at(index, el); + return typed::id_list(res); +} + +template +typed::map::map(const typed::basic_map &bmap) + : isl::map(bmap) +{ +} + +template +typed::map::map(const isl::ctx &ctx, const std::string &str) + : isl::map(ctx, str) +{ +} + +template +template +typed::map typed::map::apply_domain(const typed::map &map2) const +{ + auto res = isl::map::apply_domain(map2); + return typed::map(res); +} + +template +template +typed::union_map typed::map::apply_domain(const typed::union_map &umap2) const +{ + auto res = isl::map::apply_domain(umap2); + return typed::union_map(res); +} + +template +template +typed::map typed::map::apply_domain(const typed::basic_map &map2) const +{ + auto res = isl::map::apply_domain(map2); + return typed::map(res); +} + +template +template +typed::map typed::map::apply_range(const typed::map &map2) const +{ + auto res = isl::map::apply_range(map2); + return typed::map(res); +} + +template +template +typed::union_map typed::map::apply_range(const typed::union_map &umap2) const +{ + auto res = isl::map::apply_range(umap2); + return typed::union_map(res); +} + +template +template +typed::map typed::map::apply_range(const typed::basic_map &map2) const +{ + auto res = isl::map::apply_range(map2); + return typed::map(res); +} + +template +typed::map typed::map::as_map() const +{ + auto res = isl::map::as_map(); + return typed::map(res); +} + +template +typed::multi_union_pw_aff typed::map::as_multi_union_pw_aff() const +{ + auto res = isl::map::as_multi_union_pw_aff(); + return typed::multi_union_pw_aff(res); +} + +template +typed::pw_multi_aff typed::map::as_pw_multi_aff() const +{ + auto res = isl::map::as_pw_multi_aff(); + return typed::pw_multi_aff(res); +} + +template +typed::union_pw_multi_aff typed::map::as_union_pw_multi_aff() const +{ + auto res = isl::map::as_union_pw_multi_aff(); + return typed::union_pw_multi_aff(res); +} + +template +typed::set typed::map::bind_domain(const typed::multi_id &tuple) const +{ + auto res = isl::map::bind_domain(tuple); + return typed::set(res); +} + +template +typed::set typed::map::bind_range(const typed::multi_id &tuple) const +{ + auto res = isl::map::bind_range(tuple); + return typed::set(res); +} + +template +typed::map typed::map::coalesce() const +{ + auto res = isl::map::coalesce(); + return typed::map(res); +} + +template +typed::map typed::map::detect_equalities() const +{ + auto res = isl::map::detect_equalities(); + return typed::map(res); +} + +template +typed::set typed::map::domain() const +{ + auto res = isl::map::domain(); + return typed::set(res); +} + +template +typed::union_map, Domain> typed::map::domain_map() const +{ + auto res = isl::map::domain_map(); + return typed::union_map, Domain>(res); +} + +template +typed::union_pw_multi_aff, Domain> typed::map::domain_map_union_pw_multi_aff() const +{ + auto res = isl::map::domain_map_union_pw_multi_aff(); + return typed::union_pw_multi_aff, Domain>(res); +} + +template +template +typed::map, Range> typed::map::domain_product(const typed::map &map2) const +{ + auto res = isl::map::domain_product(map2); + return typed::map, Range>(res); +} + +template +template +typed::union_map, Range> typed::map::domain_product(const typed::union_map &umap2) const +{ + auto res = isl::map::domain_product(umap2); + return typed::union_map, Range>(res); +} + +template +template +typed::map, Range> typed::map::domain_product(const typed::basic_map &map2) const +{ + auto res = isl::map::domain_product(map2); + return typed::map, Range>(res); +} + +template +typed::map typed::map::drop_unused_params() const +{ + auto res = isl::map::drop_unused_params(); + return typed::map(res); +} + +template +bool typed::map::every_map(const std::function)> &test) const +{ + auto lambda_test = [&] (isl::map arg0) { + return test(typed::map(arg0)); + }; + return isl::map::every_map(lambda_test); +} + +template +typed::map typed::map::extract_map(const typed::space &space) const +{ + auto res = isl::map::extract_map(space); + return typed::map(res); +} + +template +void typed::map::foreach_basic_map(const std::function)> &fn) const +{ + auto lambda_fn = [&] (isl::basic_map arg0) { + return fn(typed::basic_map(arg0)); + }; + return isl::map::foreach_basic_map(lambda_fn); +} + +template +void typed::map::foreach_map(const std::function)> &fn) const +{ + auto lambda_fn = [&] (isl::map arg0) { + return fn(typed::map(arg0)); + }; + return isl::map::foreach_map(lambda_fn); +} + +template +typed::map typed::map::gist(const typed::map &context) const +{ + auto res = isl::map::gist(context); + return typed::map(res); +} + +template +typed::union_map typed::map::gist(const typed::union_map &context) const +{ + auto res = isl::map::gist(context); + return typed::union_map(res); +} + +template +typed::map typed::map::gist(const typed::basic_map &context) const +{ + auto res = isl::map::gist(context); + return typed::map(res); +} + +template +typed::map typed::map::gist_domain(const typed::set &context) const +{ + auto res = isl::map::gist_domain(context); + return typed::map(res); +} + +template +typed::union_map typed::map::gist_domain(const typed::union_set &uset) const +{ + auto res = isl::map::gist_domain(uset); + return typed::union_map(res); +} + +template +typed::map typed::map::gist_domain(const typed::basic_set &context) const +{ + auto res = isl::map::gist_domain(context); + return typed::map(res); +} + +template +typed::map typed::map::gist_domain(const typed::point &context) const +{ + auto res = isl::map::gist_domain(context); + return typed::map(res); +} + +template +typed::map typed::map::gist_params(const typed::set<> &context) const +{ + auto res = isl::map::gist_params(context); + return typed::map(res); +} + +template +typed::map typed::map::gist_params(const typed::basic_set<> &context) const +{ + auto res = isl::map::gist_params(context); + return typed::map(res); +} + +template +typed::map typed::map::gist_params(const typed::point<> &context) const +{ + auto res = isl::map::gist_params(context); + return typed::map(res); +} + +template +typed::map typed::map::intersect(const typed::map &map2) const +{ + auto res = isl::map::intersect(map2); + return typed::map(res); +} + +template +typed::union_map typed::map::intersect(const typed::union_map &umap2) const +{ + auto res = isl::map::intersect(umap2); + return typed::union_map(res); +} + +template +typed::map typed::map::intersect(const typed::basic_map &map2) const +{ + auto res = isl::map::intersect(map2); + return typed::map(res); +} + +template +typed::map typed::map::intersect_domain(const typed::set &set) const +{ + auto res = isl::map::intersect_domain(set); + return typed::map(res); +} + +template +typed::union_map typed::map::intersect_domain(const typed::space &space) const +{ + auto res = isl::map::intersect_domain(space); + return typed::union_map(res); +} + +template +typed::union_map typed::map::intersect_domain(const typed::union_set &uset) const +{ + auto res = isl::map::intersect_domain(uset); + return typed::union_map(res); +} + +template +typed::map typed::map::intersect_domain(const typed::basic_set &set) const +{ + auto res = isl::map::intersect_domain(set); + return typed::map(res); +} + +template +typed::map typed::map::intersect_domain(const typed::point &set) const +{ + auto res = isl::map::intersect_domain(set); + return typed::map(res); +} + +template +typed::map typed::map::intersect_params(const typed::set<> ¶ms) const +{ + auto res = isl::map::intersect_params(params); + return typed::map(res); +} + +template +typed::map typed::map::intersect_params(const typed::basic_set<> ¶ms) const +{ + auto res = isl::map::intersect_params(params); + return typed::map(res); +} + +template +typed::map typed::map::intersect_params(const typed::point<> ¶ms) const +{ + auto res = isl::map::intersect_params(params); + return typed::map(res); +} + +template +typed::map typed::map::intersect_range(const typed::set &set) const +{ + auto res = isl::map::intersect_range(set); + return typed::map(res); +} + +template +typed::union_map typed::map::intersect_range(const typed::space &space) const +{ + auto res = isl::map::intersect_range(space); + return typed::union_map(res); +} + +template +typed::union_map typed::map::intersect_range(const typed::union_set &uset) const +{ + auto res = isl::map::intersect_range(uset); + return typed::union_map(res); +} + +template +typed::map typed::map::intersect_range(const typed::basic_set &set) const +{ + auto res = isl::map::intersect_range(set); + return typed::map(res); +} + +template +typed::map typed::map::intersect_range(const typed::point &set) const +{ + auto res = isl::map::intersect_range(set); + return typed::map(res); +} + +template +typed::map typed::map::lexmax() const +{ + auto res = isl::map::lexmax(); + return typed::map(res); +} + +template +typed::pw_multi_aff typed::map::lexmax_pw_multi_aff() const +{ + auto res = isl::map::lexmax_pw_multi_aff(); + return typed::pw_multi_aff(res); +} + +template +typed::map typed::map::lexmin() const +{ + auto res = isl::map::lexmin(); + return typed::map(res); +} + +template +typed::pw_multi_aff typed::map::lexmin_pw_multi_aff() const +{ + auto res = isl::map::lexmin_pw_multi_aff(); + return typed::pw_multi_aff(res); +} + +template +typed::map typed::map::lower_bound(const typed::multi_pw_aff &lower) const +{ + auto res = isl::map::lower_bound(lower); + return typed::map(res); +} + +template +typed::map typed::map::lower_bound(const typed::aff &lower) const +{ + auto res = isl::map::lower_bound(lower); + return typed::map(res); +} + +template +typed::map typed::map::lower_bound(const typed::multi_aff &lower) const +{ + auto res = isl::map::lower_bound(lower); + return typed::map(res); +} + +template +typed::map typed::map::lower_bound(const typed::pw_aff &lower) const +{ + auto res = isl::map::lower_bound(lower); + return typed::map(res); +} + +template +typed::map typed::map::lower_bound(const typed::pw_multi_aff &lower) const +{ + auto res = isl::map::lower_bound(lower); + return typed::map(res); +} + +template +typed::map_list typed::map::map_list() const +{ + auto res = isl::map::map_list(); + return typed::map_list(res); +} + +template +typed::multi_pw_aff typed::map::max_multi_pw_aff() const +{ + auto res = isl::map::max_multi_pw_aff(); + return typed::multi_pw_aff(res); +} + +template +typed::multi_pw_aff typed::map::min_multi_pw_aff() const +{ + auto res = isl::map::min_multi_pw_aff(); + return typed::multi_pw_aff(res); +} + +template +typed::set<> typed::map::params() const +{ + auto res = isl::map::params(); + return typed::set<>(res); +} + +template +template +typed::map typed::map::preimage_domain(const typed::multi_aff &ma) const +{ + auto res = isl::map::preimage_domain(ma); + return typed::map(res); +} + +template +template +typed::map typed::map::preimage_domain(const typed::multi_pw_aff &mpa) const +{ + auto res = isl::map::preimage_domain(mpa); + return typed::map(res); +} + +template +template +typed::map typed::map::preimage_domain(const typed::pw_multi_aff &pma) const +{ + auto res = isl::map::preimage_domain(pma); + return typed::map(res); +} + +template +template +typed::union_map typed::map::preimage_domain(const typed::union_pw_multi_aff &upma) const +{ + auto res = isl::map::preimage_domain(upma); + return typed::union_map(res); +} + +template +template +typed::map typed::map::preimage_range(const typed::multi_aff &ma) const +{ + auto res = isl::map::preimage_range(ma); + return typed::map(res); +} + +template +template +typed::map typed::map::preimage_range(const typed::pw_multi_aff &pma) const +{ + auto res = isl::map::preimage_range(pma); + return typed::map(res); +} + +template +template +typed::union_map typed::map::preimage_range(const typed::union_pw_multi_aff &upma) const +{ + auto res = isl::map::preimage_range(upma); + return typed::union_map(res); +} + +template +template +typed::map, pair> typed::map::product(const typed::map &map2) const +{ + auto res = isl::map::product(map2); + return typed::map, pair>(res); +} + +template +template +typed::union_map, pair> typed::map::product(const typed::union_map &umap2) const +{ + auto res = isl::map::product(umap2); + return typed::union_map, pair>(res); +} + +template +template +typed::map, pair> typed::map::product(const typed::basic_map &map2) const +{ + auto res = isl::map::product(map2); + return typed::map, pair>(res); +} + +template +typed::map typed::map::project_out_all_params() const +{ + auto res = isl::map::project_out_all_params(); + return typed::map(res); +} + +template +typed::map typed::map::project_out_param(const typed::id &id) const +{ + auto res = isl::map::project_out_param(id); + return typed::map(res); +} + +template +typed::map typed::map::project_out_param(const std::string &id) const +{ + auto res = isl::map::project_out_param(id); + return typed::map(res); +} + +template +typed::map typed::map::project_out_param(const typed::id_list &list) const +{ + auto res = isl::map::project_out_param(list); + return typed::map(res); +} + +template +typed::set typed::map::range() const +{ + auto res = isl::map::range(); + return typed::set(res); +} + +template +typed::fixed_box typed::map::range_lattice_tile() const +{ + auto res = isl::map::range_lattice_tile(); + return typed::fixed_box(res); +} + +template +typed::union_map, Range> typed::map::range_map() const +{ + auto res = isl::map::range_map(); + return typed::union_map, Range>(res); +} + +template +template +typed::map> typed::map::range_product(const typed::map &map2) const +{ + auto res = isl::map::range_product(map2); + return typed::map>(res); +} + +template +template +typed::union_map> typed::map::range_product(const typed::union_map &umap2) const +{ + auto res = isl::map::range_product(umap2); + return typed::union_map>(res); +} + +template +template +typed::map> typed::map::range_product(const typed::basic_map &map2) const +{ + auto res = isl::map::range_product(map2); + return typed::map>(res); +} + +template +typed::fixed_box typed::map::range_simple_fixed_box_hull() const +{ + auto res = isl::map::range_simple_fixed_box_hull(); + return typed::fixed_box(res); +} + +template +typed::map typed::map::reverse() const +{ + auto res = isl::map::reverse(); + return typed::map(res); +} + +template +template +typed::map typed::map::set_domain_tuple(const typed::id &id) const +{ + auto res = isl::map::set_domain_tuple(id); + return typed::map(res); +} + +template +template +typed::map typed::map::set_domain_tuple(const std::string &id) const +{ + auto res = isl::map::set_domain_tuple(id); + return typed::map(res); +} + +template +template +typed::map typed::map::set_range_tuple(const typed::id &id) const +{ + auto res = isl::map::set_range_tuple(id); + return typed::map(res); +} + +template +template +typed::map typed::map::set_range_tuple(const std::string &id) const +{ + auto res = isl::map::set_range_tuple(id); + return typed::map(res); +} + +template +typed::space typed::map::space() const +{ + auto res = isl::map::space(); + return typed::space(res); +} + +template +typed::map typed::map::subtract(const typed::map &map2) const +{ + auto res = isl::map::subtract(map2); + return typed::map(res); +} + +template +typed::union_map typed::map::subtract(const typed::union_map &umap2) const +{ + auto res = isl::map::subtract(umap2); + return typed::union_map(res); +} + +template +typed::map typed::map::subtract(const typed::basic_map &map2) const +{ + auto res = isl::map::subtract(map2); + return typed::map(res); +} + +template +typed::union_map typed::map::subtract_domain(const typed::union_set &dom) const +{ + auto res = isl::map::subtract_domain(dom); + return typed::union_map(res); +} + +template +typed::union_map typed::map::subtract_range(const typed::union_set &dom) const +{ + auto res = isl::map::subtract_range(dom); + return typed::union_map(res); +} + +template +typed::union_map typed::map::to_union_map() const +{ + auto res = isl::map::to_union_map(); + return typed::union_map(res); +} + +template +typed::map typed::map::unite(const typed::map &map2) const +{ + auto res = isl::map::unite(map2); + return typed::map(res); +} + +template +typed::union_map typed::map::unite(const typed::union_map &umap2) const +{ + auto res = isl::map::unite(umap2); + return typed::union_map(res); +} + +template +typed::map typed::map::unite(const typed::basic_map &map2) const +{ + auto res = isl::map::unite(map2); + return typed::map(res); +} + +template +typed::map typed::map::universe(const typed::space &space) +{ + auto res = isl::map::universe(space); + return typed::map(res); +} + +template +typed::map typed::map::upper_bound(const typed::multi_pw_aff &upper) const +{ + auto res = isl::map::upper_bound(upper); + return typed::map(res); +} + +template +typed::map typed::map::upper_bound(const typed::aff &upper) const +{ + auto res = isl::map::upper_bound(upper); + return typed::map(res); +} + +template +typed::map typed::map::upper_bound(const typed::multi_aff &upper) const +{ + auto res = isl::map::upper_bound(upper); + return typed::map(res); +} + +template +typed::map typed::map::upper_bound(const typed::pw_aff &upper) const +{ + auto res = isl::map::upper_bound(upper); + return typed::map(res); +} + +template +typed::map typed::map::upper_bound(const typed::pw_multi_aff &upper) const +{ + auto res = isl::map::upper_bound(upper); + return typed::map(res); +} + +template +typed::set> typed::map::wrap() const +{ + auto res = isl::map::wrap(); + return typed::set>(res); +} + +template +typed::map, Range2>::map(const typed::basic_map, Range2> &bmap) + : isl::map(bmap) +{ +} + +template +typed::map, Range2>::map(const isl::ctx &ctx, const std::string &str) + : isl::map(ctx, str) +{ +} + +template +template +typed::map typed::map, Range2>::apply_domain(const typed::map, Domain2> &map2) const +{ + auto res = isl::map::apply_domain(map2); + return typed::map(res); +} + +template +template +typed::union_map typed::map, Range2>::apply_domain(const typed::union_map, Domain2> &umap2) const +{ + auto res = isl::map::apply_domain(umap2); + return typed::union_map(res); +} + +template +template +typed::map typed::map, Range2>::apply_domain(const typed::basic_map, Domain2> &map2) const +{ + auto res = isl::map::apply_domain(map2); + return typed::map(res); +} + +template +template +typed::map, Arg3> typed::map, Range2>::apply_range(const typed::map &map2) const +{ + auto res = isl::map::apply_range(map2); + return typed::map, Arg3>(res); +} + +template +template +typed::union_map, Arg3> typed::map, Range2>::apply_range(const typed::union_map &umap2) const +{ + auto res = isl::map::apply_range(umap2); + return typed::union_map, Arg3>(res); +} + +template +template +typed::map, Arg3> typed::map, Range2>::apply_range(const typed::basic_map &map2) const +{ + auto res = isl::map::apply_range(map2); + return typed::map, Arg3>(res); +} + +template +typed::map, Range2> typed::map, Range2>::as_map() const +{ + auto res = isl::map::as_map(); + return typed::map, Range2>(res); +} + +template +typed::multi_union_pw_aff, Range2> typed::map, Range2>::as_multi_union_pw_aff() const +{ + auto res = isl::map::as_multi_union_pw_aff(); + return typed::multi_union_pw_aff, Range2>(res); +} + +template +typed::pw_multi_aff, Range2> typed::map, Range2>::as_pw_multi_aff() const +{ + auto res = isl::map::as_pw_multi_aff(); + return typed::pw_multi_aff, Range2>(res); +} + +template +typed::union_pw_multi_aff, Range2> typed::map, Range2>::as_union_pw_multi_aff() const +{ + auto res = isl::map::as_union_pw_multi_aff(); + return typed::union_pw_multi_aff, Range2>(res); +} + +template +typed::set typed::map, Range2>::bind_domain(const typed::multi_id> &tuple) const +{ + auto res = isl::map::bind_domain(tuple); + return typed::set(res); +} + +template +typed::set> typed::map, Range2>::bind_range(const typed::multi_id &tuple) const +{ + auto res = isl::map::bind_range(tuple); + return typed::set>(res); +} + +template +typed::map, Range2> typed::map, Range2>::coalesce() const +{ + auto res = isl::map::coalesce(); + return typed::map, Range2>(res); +} + +template +typed::map> typed::map, Range2>::curry() const +{ + auto res = isl::map::curry(); + return typed::map>(res); +} + +template +typed::map, Range2> typed::map, Range2>::detect_equalities() const +{ + auto res = isl::map::detect_equalities(); + return typed::map, Range2>(res); +} + +template +typed::set> typed::map, Range2>::domain() const +{ + auto res = isl::map::domain(); + return typed::set>(res); +} + +template +typed::map typed::map, Range2>::domain_factor_domain() const +{ + auto res = isl::map::domain_factor_domain(); + return typed::map(res); +} + +template +typed::map typed::map, Range2>::domain_factor_range() const +{ + auto res = isl::map::domain_factor_range(); + return typed::map(res); +} + +template +typed::union_map, Range2>, pair> typed::map, Range2>::domain_map() const +{ + auto res = isl::map::domain_map(); + return typed::union_map, Range2>, pair>(res); +} + +template +typed::union_pw_multi_aff, Range2>, pair> typed::map, Range2>::domain_map_union_pw_multi_aff() const +{ + auto res = isl::map::domain_map_union_pw_multi_aff(); + return typed::union_pw_multi_aff, Range2>, pair>(res); +} + +template +template +typed::map, Domain2>, Range2> typed::map, Range2>::domain_product(const typed::map &map2) const +{ + auto res = isl::map::domain_product(map2); + return typed::map, Domain2>, Range2>(res); +} + +template +template +typed::union_map, Domain2>, Range2> typed::map, Range2>::domain_product(const typed::union_map &umap2) const +{ + auto res = isl::map::domain_product(umap2); + return typed::union_map, Domain2>, Range2>(res); +} + +template +template +typed::map, Domain2>, Range2> typed::map, Range2>::domain_product(const typed::basic_map &map2) const +{ + auto res = isl::map::domain_product(map2); + return typed::map, Domain2>, Range2>(res); +} + +template +typed::map, Range2> typed::map, Range2>::domain_reverse() const +{ + auto res = isl::map::domain_reverse(); + return typed::map, Range2>(res); +} + +template +typed::map, Range2> typed::map, Range2>::drop_unused_params() const +{ + auto res = isl::map::drop_unused_params(); + return typed::map, Range2>(res); +} + +template +bool typed::map, Range2>::every_map(const std::function, Range2>)> &test) const +{ + auto lambda_test = [&] (isl::map arg0) { + return test(typed::map, Range2>(arg0)); + }; + return isl::map::every_map(lambda_test); +} + +template +typed::map, Range2> typed::map, Range2>::extract_map(const typed::space, Range2> &space) const +{ + auto res = isl::map::extract_map(space); + return typed::map, Range2>(res); +} + +template +typed::map typed::map, Range2>::flatten_domain() const +{ + auto res = isl::map::flatten_domain(); + return typed::map(res); +} + +template +void typed::map, Range2>::foreach_basic_map(const std::function, Range2>)> &fn) const +{ + auto lambda_fn = [&] (isl::basic_map arg0) { + return fn(typed::basic_map, Range2>(arg0)); + }; + return isl::map::foreach_basic_map(lambda_fn); +} + +template +void typed::map, Range2>::foreach_map(const std::function, Range2>)> &fn) const +{ + auto lambda_fn = [&] (isl::map arg0) { + return fn(typed::map, Range2>(arg0)); + }; + return isl::map::foreach_map(lambda_fn); +} + +template +typed::map, Range2> typed::map, Range2>::gist(const typed::map, Range2> &context) const +{ + auto res = isl::map::gist(context); + return typed::map, Range2>(res); +} + +template +typed::union_map, Range2> typed::map, Range2>::gist(const typed::union_map, Range2> &context) const +{ + auto res = isl::map::gist(context); + return typed::union_map, Range2>(res); +} + +template +typed::map, Range2> typed::map, Range2>::gist(const typed::basic_map, Range2> &context) const +{ + auto res = isl::map::gist(context); + return typed::map, Range2>(res); +} + +template +typed::map, Range2> typed::map, Range2>::gist_domain(const typed::set> &context) const +{ + auto res = isl::map::gist_domain(context); + return typed::map, Range2>(res); +} + +template +typed::union_map, Range2> typed::map, Range2>::gist_domain(const typed::union_set> &uset) const +{ + auto res = isl::map::gist_domain(uset); + return typed::union_map, Range2>(res); +} + +template +typed::map, Range2> typed::map, Range2>::gist_domain(const typed::basic_set> &context) const +{ + auto res = isl::map::gist_domain(context); + return typed::map, Range2>(res); +} + +template +typed::map, Range2> typed::map, Range2>::gist_domain(const typed::point> &context) const +{ + auto res = isl::map::gist_domain(context); + return typed::map, Range2>(res); +} + +template +typed::map, Range2> typed::map, Range2>::gist_params(const typed::set<> &context) const +{ + auto res = isl::map::gist_params(context); + return typed::map, Range2>(res); +} + +template +typed::map, Range2> typed::map, Range2>::gist_params(const typed::basic_set<> &context) const +{ + auto res = isl::map::gist_params(context); + return typed::map, Range2>(res); +} + +template +typed::map, Range2> typed::map, Range2>::gist_params(const typed::point<> &context) const +{ + auto res = isl::map::gist_params(context); + return typed::map, Range2>(res); +} + +template +typed::map, Range2> typed::map, Range2>::intersect(const typed::map, Range2> &map2) const +{ + auto res = isl::map::intersect(map2); + return typed::map, Range2>(res); +} + +template +typed::union_map, Range2> typed::map, Range2>::intersect(const typed::union_map, Range2> &umap2) const +{ + auto res = isl::map::intersect(umap2); + return typed::union_map, Range2>(res); +} + +template +typed::map, Range2> typed::map, Range2>::intersect(const typed::basic_map, Range2> &map2) const +{ + auto res = isl::map::intersect(map2); + return typed::map, Range2>(res); +} + +template +typed::map, Range2> typed::map, Range2>::intersect_domain(const typed::set> &set) const +{ + auto res = isl::map::intersect_domain(set); + return typed::map, Range2>(res); +} + +template +typed::union_map, Range2> typed::map, Range2>::intersect_domain(const typed::space> &space) const +{ + auto res = isl::map::intersect_domain(space); + return typed::union_map, Range2>(res); +} + +template +typed::union_map, Range2> typed::map, Range2>::intersect_domain(const typed::union_set> &uset) const +{ + auto res = isl::map::intersect_domain(uset); + return typed::union_map, Range2>(res); +} + +template +typed::map, Range2> typed::map, Range2>::intersect_domain(const typed::basic_set> &set) const +{ + auto res = isl::map::intersect_domain(set); + return typed::map, Range2>(res); +} + +template +typed::map, Range2> typed::map, Range2>::intersect_domain(const typed::point> &set) const +{ + auto res = isl::map::intersect_domain(set); + return typed::map, Range2>(res); +} + +template +typed::map, Range2> typed::map, Range2>::intersect_domain_wrapped_domain(const typed::set &domain) const +{ + auto res = isl::map::intersect_domain_wrapped_domain(domain); + return typed::map, Range2>(res); +} + +template +typed::union_map, Range2> typed::map, Range2>::intersect_domain_wrapped_domain(const typed::union_set &domain) const +{ + auto res = isl::map::intersect_domain_wrapped_domain(domain); + return typed::union_map, Range2>(res); +} + +template +typed::map, Range2> typed::map, Range2>::intersect_domain_wrapped_domain(const typed::basic_set &domain) const +{ + auto res = isl::map::intersect_domain_wrapped_domain(domain); + return typed::map, Range2>(res); +} + +template +typed::map, Range2> typed::map, Range2>::intersect_domain_wrapped_domain(const typed::point &domain) const +{ + auto res = isl::map::intersect_domain_wrapped_domain(domain); + return typed::map, Range2>(res); +} + +template +typed::map, Range2> typed::map, Range2>::intersect_params(const typed::set<> ¶ms) const +{ + auto res = isl::map::intersect_params(params); + return typed::map, Range2>(res); +} + +template +typed::map, Range2> typed::map, Range2>::intersect_params(const typed::basic_set<> ¶ms) const +{ + auto res = isl::map::intersect_params(params); + return typed::map, Range2>(res); +} + +template +typed::map, Range2> typed::map, Range2>::intersect_params(const typed::point<> ¶ms) const +{ + auto res = isl::map::intersect_params(params); + return typed::map, Range2>(res); +} + +template +typed::map, Range2> typed::map, Range2>::intersect_range(const typed::set &set) const +{ + auto res = isl::map::intersect_range(set); + return typed::map, Range2>(res); +} + +template +typed::union_map, Range2> typed::map, Range2>::intersect_range(const typed::space &space) const +{ + auto res = isl::map::intersect_range(space); + return typed::union_map, Range2>(res); +} + +template +typed::union_map, Range2> typed::map, Range2>::intersect_range(const typed::union_set &uset) const +{ + auto res = isl::map::intersect_range(uset); + return typed::union_map, Range2>(res); +} + +template +typed::map, Range2> typed::map, Range2>::intersect_range(const typed::basic_set &set) const +{ + auto res = isl::map::intersect_range(set); + return typed::map, Range2>(res); +} + +template +typed::map, Range2> typed::map, Range2>::intersect_range(const typed::point &set) const +{ + auto res = isl::map::intersect_range(set); + return typed::map, Range2>(res); +} + +template +typed::map, Range2> typed::map, Range2>::lexmax() const +{ + auto res = isl::map::lexmax(); + return typed::map, Range2>(res); +} + +template +typed::pw_multi_aff, Range2> typed::map, Range2>::lexmax_pw_multi_aff() const +{ + auto res = isl::map::lexmax_pw_multi_aff(); + return typed::pw_multi_aff, Range2>(res); +} + +template +typed::map, Range2> typed::map, Range2>::lexmin() const +{ + auto res = isl::map::lexmin(); + return typed::map, Range2>(res); +} + +template +typed::pw_multi_aff, Range2> typed::map, Range2>::lexmin_pw_multi_aff() const +{ + auto res = isl::map::lexmin_pw_multi_aff(); + return typed::pw_multi_aff, Range2>(res); +} + +template +typed::map, Range2> typed::map, Range2>::lower_bound(const typed::multi_pw_aff, Range2> &lower) const +{ + auto res = isl::map::lower_bound(lower); + return typed::map, Range2>(res); +} + +template +typed::map, Range2> typed::map, Range2>::lower_bound(const typed::aff, Range2> &lower) const +{ + auto res = isl::map::lower_bound(lower); + return typed::map, Range2>(res); +} + +template +typed::map, Range2> typed::map, Range2>::lower_bound(const typed::multi_aff, Range2> &lower) const +{ + auto res = isl::map::lower_bound(lower); + return typed::map, Range2>(res); +} + +template +typed::map, Range2> typed::map, Range2>::lower_bound(const typed::pw_aff, Range2> &lower) const +{ + auto res = isl::map::lower_bound(lower); + return typed::map, Range2>(res); +} + +template +typed::map, Range2> typed::map, Range2>::lower_bound(const typed::pw_multi_aff, Range2> &lower) const +{ + auto res = isl::map::lower_bound(lower); + return typed::map, Range2>(res); +} + +template +typed::map_list, Range2> typed::map, Range2>::map_list() const +{ + auto res = isl::map::map_list(); + return typed::map_list, Range2>(res); +} + +template +typed::multi_pw_aff, Range2> typed::map, Range2>::max_multi_pw_aff() const +{ + auto res = isl::map::max_multi_pw_aff(); + return typed::multi_pw_aff, Range2>(res); +} + +template +typed::multi_pw_aff, Range2> typed::map, Range2>::min_multi_pw_aff() const +{ + auto res = isl::map::min_multi_pw_aff(); + return typed::multi_pw_aff, Range2>(res); +} + +template +typed::set<> typed::map, Range2>::params() const +{ + auto res = isl::map::params(); + return typed::set<>(res); +} + +template +template +typed::map typed::map, Range2>::preimage_domain(const typed::multi_aff> &ma) const +{ + auto res = isl::map::preimage_domain(ma); + return typed::map(res); +} + +template +template +typed::map typed::map, Range2>::preimage_domain(const typed::multi_pw_aff> &mpa) const +{ + auto res = isl::map::preimage_domain(mpa); + return typed::map(res); +} + +template +template +typed::map typed::map, Range2>::preimage_domain(const typed::pw_multi_aff> &pma) const +{ + auto res = isl::map::preimage_domain(pma); + return typed::map(res); +} + +template +template +typed::union_map typed::map, Range2>::preimage_domain(const typed::union_pw_multi_aff> &upma) const +{ + auto res = isl::map::preimage_domain(upma); + return typed::union_map(res); +} + +template +template +typed::map, Arg3> typed::map, Range2>::preimage_range(const typed::multi_aff &ma) const +{ + auto res = isl::map::preimage_range(ma); + return typed::map, Arg3>(res); +} + +template +template +typed::map, Arg3> typed::map, Range2>::preimage_range(const typed::pw_multi_aff &pma) const +{ + auto res = isl::map::preimage_range(pma); + return typed::map, Arg3>(res); +} + +template +template +typed::union_map, Arg3> typed::map, Range2>::preimage_range(const typed::union_pw_multi_aff &upma) const +{ + auto res = isl::map::preimage_range(upma); + return typed::union_map, Arg3>(res); +} + +template +template +typed::map, Domain2>, pair> typed::map, Range2>::product(const typed::map &map2) const +{ + auto res = isl::map::product(map2); + return typed::map, Domain2>, pair>(res); +} + +template +template +typed::union_map, Domain2>, pair> typed::map, Range2>::product(const typed::union_map &umap2) const +{ + auto res = isl::map::product(umap2); + return typed::union_map, Domain2>, pair>(res); +} + +template +template +typed::map, Domain2>, pair> typed::map, Range2>::product(const typed::basic_map &map2) const +{ + auto res = isl::map::product(map2); + return typed::map, Domain2>, pair>(res); +} + +template +typed::map, Range2> typed::map, Range2>::project_out_all_params() const +{ + auto res = isl::map::project_out_all_params(); + return typed::map, Range2>(res); +} + +template +typed::map, Range2> typed::map, Range2>::project_out_param(const typed::id &id) const +{ + auto res = isl::map::project_out_param(id); + return typed::map, Range2>(res); +} + +template +typed::map, Range2> typed::map, Range2>::project_out_param(const std::string &id) const +{ + auto res = isl::map::project_out_param(id); + return typed::map, Range2>(res); +} + +template +typed::map, Range2> typed::map, Range2>::project_out_param(const typed::id_list &list) const +{ + auto res = isl::map::project_out_param(list); + return typed::map, Range2>(res); +} + +template +typed::set typed::map, Range2>::range() const +{ + auto res = isl::map::range(); + return typed::set(res); +} + +template +typed::fixed_box, Range2> typed::map, Range2>::range_lattice_tile() const +{ + auto res = isl::map::range_lattice_tile(); + return typed::fixed_box, Range2>(res); +} + +template +typed::union_map, Range2>, Range2> typed::map, Range2>::range_map() const +{ + auto res = isl::map::range_map(); + return typed::union_map, Range2>, Range2>(res); +} + +template +template +typed::map, pair> typed::map, Range2>::range_product(const typed::map, Arg3> &map2) const +{ + auto res = isl::map::range_product(map2); + return typed::map, pair>(res); +} + +template +template +typed::union_map, pair> typed::map, Range2>::range_product(const typed::union_map, Arg3> &umap2) const +{ + auto res = isl::map::range_product(umap2); + return typed::union_map, pair>(res); +} + +template +template +typed::map, pair> typed::map, Range2>::range_product(const typed::basic_map, Arg3> &map2) const +{ + auto res = isl::map::range_product(map2); + return typed::map, pair>(res); +} + +template +typed::fixed_box, Range2> typed::map, Range2>::range_simple_fixed_box_hull() const +{ + auto res = isl::map::range_simple_fixed_box_hull(); + return typed::fixed_box, Range2>(res); +} + +template +typed::map> typed::map, Range2>::reverse() const +{ + auto res = isl::map::reverse(); + return typed::map>(res); +} + +template +template +typed::map, Arg2> typed::map, Range2>::set_range_tuple(const typed::id &id) const +{ + auto res = isl::map::set_range_tuple(id); + return typed::map, Arg2>(res); +} + +template +template +typed::map, Arg2> typed::map, Range2>::set_range_tuple(const std::string &id) const +{ + auto res = isl::map::set_range_tuple(id); + return typed::map, Arg2>(res); +} + +template +typed::space, Range2> typed::map, Range2>::space() const +{ + auto res = isl::map::space(); + return typed::space, Range2>(res); +} + +template +typed::map, Range2> typed::map, Range2>::subtract(const typed::map, Range2> &map2) const +{ + auto res = isl::map::subtract(map2); + return typed::map, Range2>(res); +} + +template +typed::union_map, Range2> typed::map, Range2>::subtract(const typed::union_map, Range2> &umap2) const +{ + auto res = isl::map::subtract(umap2); + return typed::union_map, Range2>(res); +} + +template +typed::map, Range2> typed::map, Range2>::subtract(const typed::basic_map, Range2> &map2) const +{ + auto res = isl::map::subtract(map2); + return typed::map, Range2>(res); +} + +template +typed::union_map, Range2> typed::map, Range2>::subtract_domain(const typed::union_set> &dom) const +{ + auto res = isl::map::subtract_domain(dom); + return typed::union_map, Range2>(res); +} + +template +typed::union_map, Range2> typed::map, Range2>::subtract_range(const typed::union_set &dom) const +{ + auto res = isl::map::subtract_range(dom); + return typed::union_map, Range2>(res); +} + +template +typed::union_map, Range2> typed::map, Range2>::to_union_map() const +{ + auto res = isl::map::to_union_map(); + return typed::union_map, Range2>(res); +} + +template +typed::map, Range2> typed::map, Range2>::unite(const typed::map, Range2> &map2) const +{ + auto res = isl::map::unite(map2); + return typed::map, Range2>(res); +} + +template +typed::union_map, Range2> typed::map, Range2>::unite(const typed::union_map, Range2> &umap2) const +{ + auto res = isl::map::unite(umap2); + return typed::union_map, Range2>(res); +} + +template +typed::map, Range2> typed::map, Range2>::unite(const typed::basic_map, Range2> &map2) const +{ + auto res = isl::map::unite(map2); + return typed::map, Range2>(res); +} + +template +typed::map, Range2> typed::map, Range2>::universe(const typed::space, Range2> &space) +{ + auto res = isl::map::universe(space); + return typed::map, Range2>(res); +} + +template +typed::map, Range2> typed::map, Range2>::upper_bound(const typed::multi_pw_aff, Range2> &upper) const +{ + auto res = isl::map::upper_bound(upper); + return typed::map, Range2>(res); +} + +template +typed::map, Range2> typed::map, Range2>::upper_bound(const typed::aff, Range2> &upper) const +{ + auto res = isl::map::upper_bound(upper); + return typed::map, Range2>(res); +} + +template +typed::map, Range2> typed::map, Range2>::upper_bound(const typed::multi_aff, Range2> &upper) const +{ + auto res = isl::map::upper_bound(upper); + return typed::map, Range2>(res); +} + +template +typed::map, Range2> typed::map, Range2>::upper_bound(const typed::pw_aff, Range2> &upper) const +{ + auto res = isl::map::upper_bound(upper); + return typed::map, Range2>(res); +} + +template +typed::map, Range2> typed::map, Range2>::upper_bound(const typed::pw_multi_aff, Range2> &upper) const +{ + auto res = isl::map::upper_bound(upper); + return typed::map, Range2>(res); +} + +template +typed::set, Range2>> typed::map, Range2>::wrap() const +{ + auto res = isl::map::wrap(); + return typed::set, Range2>>(res); +} + +template +typed::map::map(const typed::basic_map &bmap) + : isl::map(bmap) +{ +} + +template +typed::map::map(const isl::ctx &ctx, const std::string &str) + : isl::map(ctx, str) +{ +} + +template +template +typed::map typed::map::apply_domain(const typed::map &map2) const +{ + auto res = isl::map::apply_domain(map2); + return typed::map(res); +} + +template +template +typed::union_map typed::map::apply_domain(const typed::union_map &umap2) const +{ + auto res = isl::map::apply_domain(umap2); + return typed::union_map(res); +} + +template +template +typed::map typed::map::apply_domain(const typed::basic_map &map2) const +{ + auto res = isl::map::apply_domain(map2); + return typed::map(res); +} + +template +template +typed::map typed::map::apply_range(const typed::map &map2) const +{ + auto res = isl::map::apply_range(map2); + return typed::map(res); +} + +template +template +typed::union_map typed::map::apply_range(const typed::union_map &umap2) const +{ + auto res = isl::map::apply_range(umap2); + return typed::union_map(res); +} + +template +template +typed::map typed::map::apply_range(const typed::basic_map &map2) const +{ + auto res = isl::map::apply_range(map2); + return typed::map(res); +} + +template +typed::map typed::map::as_map() const +{ + auto res = isl::map::as_map(); + return typed::map(res); +} + +template +typed::multi_union_pw_aff typed::map::as_multi_union_pw_aff() const +{ + auto res = isl::map::as_multi_union_pw_aff(); + return typed::multi_union_pw_aff(res); +} + +template +typed::pw_multi_aff typed::map::as_pw_multi_aff() const +{ + auto res = isl::map::as_pw_multi_aff(); + return typed::pw_multi_aff(res); +} + +template +typed::union_pw_multi_aff typed::map::as_union_pw_multi_aff() const +{ + auto res = isl::map::as_union_pw_multi_aff(); + return typed::union_pw_multi_aff(res); +} + +template +typed::set typed::map::bind_domain(const typed::multi_id &tuple) const +{ + auto res = isl::map::bind_domain(tuple); + return typed::set(res); +} + +template +typed::set typed::map::bind_range(const typed::multi_id &tuple) const +{ + auto res = isl::map::bind_range(tuple); + return typed::set(res); +} + +template +typed::map typed::map::coalesce() const +{ + auto res = isl::map::coalesce(); + return typed::map(res); +} + +template +typed::set typed::map::deltas() const +{ + auto res = isl::map::deltas(); + return typed::set(res); +} + +template +typed::map typed::map::detect_equalities() const +{ + auto res = isl::map::detect_equalities(); + return typed::map(res); +} + +template +typed::set typed::map::domain() const +{ + auto res = isl::map::domain(); + return typed::set(res); +} + +template +typed::union_map, Domain> typed::map::domain_map() const +{ + auto res = isl::map::domain_map(); + return typed::union_map, Domain>(res); +} + +template +typed::union_pw_multi_aff, Domain> typed::map::domain_map_union_pw_multi_aff() const +{ + auto res = isl::map::domain_map_union_pw_multi_aff(); + return typed::union_pw_multi_aff, Domain>(res); +} + +template +template +typed::map, Domain> typed::map::domain_product(const typed::map &map2) const +{ + auto res = isl::map::domain_product(map2); + return typed::map, Domain>(res); +} + +template +template +typed::union_map, Domain> typed::map::domain_product(const typed::union_map &umap2) const +{ + auto res = isl::map::domain_product(umap2); + return typed::union_map, Domain>(res); +} + +template +template +typed::map, Domain> typed::map::domain_product(const typed::basic_map &map2) const +{ + auto res = isl::map::domain_product(map2); + return typed::map, Domain>(res); +} + +template +typed::map typed::map::drop_unused_params() const +{ + auto res = isl::map::drop_unused_params(); + return typed::map(res); +} + +template +template +typed::map typed::map::eq_at(const typed::multi_pw_aff &mpa) const +{ + auto res = isl::map::eq_at(mpa); + return typed::map(res); +} + +template +template +typed::union_map typed::map::eq_at(const typed::multi_union_pw_aff &mupa) const +{ + auto res = isl::map::eq_at(mupa); + return typed::union_map(res); +} + +template +typed::map typed::map::eq_at(const typed::aff &mpa) const +{ + auto res = isl::map::eq_at(mpa); + return typed::map(res); +} + +template +template +typed::map typed::map::eq_at(const typed::multi_aff &mpa) const +{ + auto res = isl::map::eq_at(mpa); + return typed::map(res); +} + +template +typed::map typed::map::eq_at(const typed::pw_aff &mpa) const +{ + auto res = isl::map::eq_at(mpa); + return typed::map(res); +} + +template +template +typed::map typed::map::eq_at(const typed::pw_multi_aff &mpa) const +{ + auto res = isl::map::eq_at(mpa); + return typed::map(res); +} + +template +bool typed::map::every_map(const std::function)> &test) const +{ + auto lambda_test = [&] (isl::map arg0) { + return test(typed::map(arg0)); + }; + return isl::map::every_map(lambda_test); +} + +template +typed::map typed::map::extract_map(const typed::space &space) const +{ + auto res = isl::map::extract_map(space); + return typed::map(res); +} + +template +void typed::map::foreach_basic_map(const std::function)> &fn) const +{ + auto lambda_fn = [&] (isl::basic_map arg0) { + return fn(typed::basic_map(arg0)); + }; + return isl::map::foreach_basic_map(lambda_fn); +} + +template +void typed::map::foreach_map(const std::function)> &fn) const +{ + auto lambda_fn = [&] (isl::map arg0) { + return fn(typed::map(arg0)); + }; + return isl::map::foreach_map(lambda_fn); +} + +template +typed::map typed::map::gist(const typed::map &context) const +{ + auto res = isl::map::gist(context); + return typed::map(res); +} + +template +typed::union_map typed::map::gist(const typed::union_map &context) const +{ + auto res = isl::map::gist(context); + return typed::union_map(res); +} + +template +typed::map typed::map::gist(const typed::basic_map &context) const +{ + auto res = isl::map::gist(context); + return typed::map(res); +} + +template +typed::map typed::map::gist_domain(const typed::set &context) const +{ + auto res = isl::map::gist_domain(context); + return typed::map(res); +} + +template +typed::union_map typed::map::gist_domain(const typed::union_set &uset) const +{ + auto res = isl::map::gist_domain(uset); + return typed::union_map(res); +} + +template +typed::map typed::map::gist_domain(const typed::basic_set &context) const +{ + auto res = isl::map::gist_domain(context); + return typed::map(res); +} + +template +typed::map typed::map::gist_domain(const typed::point &context) const +{ + auto res = isl::map::gist_domain(context); + return typed::map(res); +} + +template +typed::map typed::map::gist_params(const typed::set<> &context) const +{ + auto res = isl::map::gist_params(context); + return typed::map(res); +} + +template +typed::map typed::map::gist_params(const typed::basic_set<> &context) const +{ + auto res = isl::map::gist_params(context); + return typed::map(res); +} + +template +typed::map typed::map::gist_params(const typed::point<> &context) const +{ + auto res = isl::map::gist_params(context); + return typed::map(res); +} + +template +typed::map typed::map::intersect(const typed::map &map2) const +{ + auto res = isl::map::intersect(map2); + return typed::map(res); +} + +template +typed::union_map typed::map::intersect(const typed::union_map &umap2) const +{ + auto res = isl::map::intersect(umap2); + return typed::union_map(res); +} + +template +typed::map typed::map::intersect(const typed::basic_map &map2) const +{ + auto res = isl::map::intersect(map2); + return typed::map(res); +} + +template +typed::map typed::map::intersect_domain(const typed::set &set) const +{ + auto res = isl::map::intersect_domain(set); + return typed::map(res); +} + +template +typed::union_map typed::map::intersect_domain(const typed::space &space) const +{ + auto res = isl::map::intersect_domain(space); + return typed::union_map(res); +} + +template +typed::union_map typed::map::intersect_domain(const typed::union_set &uset) const +{ + auto res = isl::map::intersect_domain(uset); + return typed::union_map(res); +} + +template +typed::map typed::map::intersect_domain(const typed::basic_set &set) const +{ + auto res = isl::map::intersect_domain(set); + return typed::map(res); +} + +template +typed::map typed::map::intersect_domain(const typed::point &set) const +{ + auto res = isl::map::intersect_domain(set); + return typed::map(res); +} + +template +typed::map typed::map::intersect_params(const typed::set<> ¶ms) const +{ + auto res = isl::map::intersect_params(params); + return typed::map(res); +} + +template +typed::map typed::map::intersect_params(const typed::basic_set<> ¶ms) const +{ + auto res = isl::map::intersect_params(params); + return typed::map(res); +} + +template +typed::map typed::map::intersect_params(const typed::point<> ¶ms) const +{ + auto res = isl::map::intersect_params(params); + return typed::map(res); +} + +template +typed::map typed::map::intersect_range(const typed::set &set) const +{ + auto res = isl::map::intersect_range(set); + return typed::map(res); +} + +template +typed::union_map typed::map::intersect_range(const typed::space &space) const +{ + auto res = isl::map::intersect_range(space); + return typed::union_map(res); +} + +template +typed::union_map typed::map::intersect_range(const typed::union_set &uset) const +{ + auto res = isl::map::intersect_range(uset); + return typed::union_map(res); +} + +template +typed::map typed::map::intersect_range(const typed::basic_set &set) const +{ + auto res = isl::map::intersect_range(set); + return typed::map(res); +} + +template +typed::map typed::map::intersect_range(const typed::point &set) const +{ + auto res = isl::map::intersect_range(set); + return typed::map(res); +} + +template +template +typed::map typed::map::lex_ge_at(const typed::multi_pw_aff &mpa) const +{ + auto res = isl::map::lex_ge_at(mpa); + return typed::map(res); +} + +template +typed::map typed::map::lex_ge_at(const typed::aff &mpa) const +{ + auto res = isl::map::lex_ge_at(mpa); + return typed::map(res); +} + +template +template +typed::map typed::map::lex_ge_at(const typed::multi_aff &mpa) const +{ + auto res = isl::map::lex_ge_at(mpa); + return typed::map(res); +} + +template +typed::map typed::map::lex_ge_at(const typed::pw_aff &mpa) const +{ + auto res = isl::map::lex_ge_at(mpa); + return typed::map(res); +} + +template +template +typed::map typed::map::lex_ge_at(const typed::pw_multi_aff &mpa) const +{ + auto res = isl::map::lex_ge_at(mpa); + return typed::map(res); +} + +template +template +typed::map typed::map::lex_gt_at(const typed::multi_pw_aff &mpa) const +{ + auto res = isl::map::lex_gt_at(mpa); + return typed::map(res); +} + +template +typed::map typed::map::lex_gt_at(const typed::aff &mpa) const +{ + auto res = isl::map::lex_gt_at(mpa); + return typed::map(res); +} + +template +template +typed::map typed::map::lex_gt_at(const typed::multi_aff &mpa) const +{ + auto res = isl::map::lex_gt_at(mpa); + return typed::map(res); +} + +template +typed::map typed::map::lex_gt_at(const typed::pw_aff &mpa) const +{ + auto res = isl::map::lex_gt_at(mpa); + return typed::map(res); +} + +template +template +typed::map typed::map::lex_gt_at(const typed::pw_multi_aff &mpa) const +{ + auto res = isl::map::lex_gt_at(mpa); + return typed::map(res); +} + +template +template +typed::map typed::map::lex_le_at(const typed::multi_pw_aff &mpa) const +{ + auto res = isl::map::lex_le_at(mpa); + return typed::map(res); +} + +template +typed::map typed::map::lex_le_at(const typed::aff &mpa) const +{ + auto res = isl::map::lex_le_at(mpa); + return typed::map(res); +} + +template +template +typed::map typed::map::lex_le_at(const typed::multi_aff &mpa) const +{ + auto res = isl::map::lex_le_at(mpa); + return typed::map(res); +} + +template +typed::map typed::map::lex_le_at(const typed::pw_aff &mpa) const +{ + auto res = isl::map::lex_le_at(mpa); + return typed::map(res); +} + +template +template +typed::map typed::map::lex_le_at(const typed::pw_multi_aff &mpa) const +{ + auto res = isl::map::lex_le_at(mpa); + return typed::map(res); +} + +template +template +typed::map typed::map::lex_lt_at(const typed::multi_pw_aff &mpa) const +{ + auto res = isl::map::lex_lt_at(mpa); + return typed::map(res); +} + +template +typed::map typed::map::lex_lt_at(const typed::aff &mpa) const +{ + auto res = isl::map::lex_lt_at(mpa); + return typed::map(res); +} + +template +template +typed::map typed::map::lex_lt_at(const typed::multi_aff &mpa) const +{ + auto res = isl::map::lex_lt_at(mpa); + return typed::map(res); +} + +template +typed::map typed::map::lex_lt_at(const typed::pw_aff &mpa) const +{ + auto res = isl::map::lex_lt_at(mpa); + return typed::map(res); +} + +template +template +typed::map typed::map::lex_lt_at(const typed::pw_multi_aff &mpa) const +{ + auto res = isl::map::lex_lt_at(mpa); + return typed::map(res); +} + +template +typed::map typed::map::lexmax() const +{ + auto res = isl::map::lexmax(); + return typed::map(res); +} + +template +typed::pw_multi_aff typed::map::lexmax_pw_multi_aff() const +{ + auto res = isl::map::lexmax_pw_multi_aff(); + return typed::pw_multi_aff(res); +} + +template +typed::map typed::map::lexmin() const +{ + auto res = isl::map::lexmin(); + return typed::map(res); +} + +template +typed::pw_multi_aff typed::map::lexmin_pw_multi_aff() const +{ + auto res = isl::map::lexmin_pw_multi_aff(); + return typed::pw_multi_aff(res); +} + +template +typed::map typed::map::lower_bound(const typed::multi_pw_aff &lower) const +{ + auto res = isl::map::lower_bound(lower); + return typed::map(res); +} + +template +typed::map typed::map::lower_bound(const typed::aff &lower) const +{ + auto res = isl::map::lower_bound(lower); + return typed::map(res); +} + +template +typed::map typed::map::lower_bound(const typed::multi_aff &lower) const +{ + auto res = isl::map::lower_bound(lower); + return typed::map(res); +} + +template +typed::map typed::map::lower_bound(const typed::pw_aff &lower) const +{ + auto res = isl::map::lower_bound(lower); + return typed::map(res); +} + +template +typed::map typed::map::lower_bound(const typed::pw_multi_aff &lower) const +{ + auto res = isl::map::lower_bound(lower); + return typed::map(res); +} + +template +typed::map_list typed::map::map_list() const +{ + auto res = isl::map::map_list(); + return typed::map_list(res); +} + +template +typed::multi_pw_aff typed::map::max_multi_pw_aff() const +{ + auto res = isl::map::max_multi_pw_aff(); + return typed::multi_pw_aff(res); +} + +template +typed::multi_pw_aff typed::map::min_multi_pw_aff() const +{ + auto res = isl::map::min_multi_pw_aff(); + return typed::multi_pw_aff(res); +} + +template +typed::set<> typed::map::params() const +{ + auto res = isl::map::params(); + return typed::set<>(res); +} + +template +template +typed::map typed::map::preimage_domain(const typed::multi_aff &ma) const +{ + auto res = isl::map::preimage_domain(ma); + return typed::map(res); +} + +template +template +typed::map typed::map::preimage_domain(const typed::multi_pw_aff &mpa) const +{ + auto res = isl::map::preimage_domain(mpa); + return typed::map(res); +} + +template +template +typed::map typed::map::preimage_domain(const typed::pw_multi_aff &pma) const +{ + auto res = isl::map::preimage_domain(pma); + return typed::map(res); +} + +template +template +typed::union_map typed::map::preimage_domain(const typed::union_pw_multi_aff &upma) const +{ + auto res = isl::map::preimage_domain(upma); + return typed::union_map(res); +} + +template +template +typed::map typed::map::preimage_range(const typed::multi_aff &ma) const +{ + auto res = isl::map::preimage_range(ma); + return typed::map(res); +} + +template +template +typed::map typed::map::preimage_range(const typed::pw_multi_aff &pma) const +{ + auto res = isl::map::preimage_range(pma); + return typed::map(res); +} + +template +template +typed::union_map typed::map::preimage_range(const typed::union_pw_multi_aff &upma) const +{ + auto res = isl::map::preimage_range(upma); + return typed::union_map(res); +} + +template +template +typed::map, pair> typed::map::product(const typed::map &map2) const +{ + auto res = isl::map::product(map2); + return typed::map, pair>(res); +} + +template +template +typed::union_map, pair> typed::map::product(const typed::union_map &umap2) const +{ + auto res = isl::map::product(umap2); + return typed::union_map, pair>(res); +} + +template +template +typed::map, pair> typed::map::product(const typed::basic_map &map2) const +{ + auto res = isl::map::product(map2); + return typed::map, pair>(res); +} + +template +typed::map typed::map::project_out_all_params() const +{ + auto res = isl::map::project_out_all_params(); + return typed::map(res); +} + +template +typed::map typed::map::project_out_param(const typed::id &id) const +{ + auto res = isl::map::project_out_param(id); + return typed::map(res); +} + +template +typed::map typed::map::project_out_param(const std::string &id) const +{ + auto res = isl::map::project_out_param(id); + return typed::map(res); +} + +template +typed::map typed::map::project_out_param(const typed::id_list &list) const +{ + auto res = isl::map::project_out_param(list); + return typed::map(res); +} + +template +typed::set typed::map::range() const +{ + auto res = isl::map::range(); + return typed::set(res); +} + +template +typed::fixed_box typed::map::range_lattice_tile() const +{ + auto res = isl::map::range_lattice_tile(); + return typed::fixed_box(res); +} + +template +typed::union_map, Domain> typed::map::range_map() const +{ + auto res = isl::map::range_map(); + return typed::union_map, Domain>(res); +} + +template +template +typed::map> typed::map::range_product(const typed::map &map2) const +{ + auto res = isl::map::range_product(map2); + return typed::map>(res); +} + +template +template +typed::union_map> typed::map::range_product(const typed::union_map &umap2) const +{ + auto res = isl::map::range_product(umap2); + return typed::union_map>(res); +} + +template +template +typed::map> typed::map::range_product(const typed::basic_map &map2) const +{ + auto res = isl::map::range_product(map2); + return typed::map>(res); +} + +template +typed::fixed_box typed::map::range_simple_fixed_box_hull() const +{ + auto res = isl::map::range_simple_fixed_box_hull(); + return typed::fixed_box(res); +} + +template +typed::map typed::map::reverse() const +{ + auto res = isl::map::reverse(); + return typed::map(res); +} + +template +template +typed::map typed::map::set_domain_tuple(const typed::id &id) const +{ + auto res = isl::map::set_domain_tuple(id); + return typed::map(res); +} + +template +template +typed::map typed::map::set_domain_tuple(const std::string &id) const +{ + auto res = isl::map::set_domain_tuple(id); + return typed::map(res); +} + +template +template +typed::map typed::map::set_range_tuple(const typed::id &id) const +{ + auto res = isl::map::set_range_tuple(id); + return typed::map(res); +} + +template +template +typed::map typed::map::set_range_tuple(const std::string &id) const +{ + auto res = isl::map::set_range_tuple(id); + return typed::map(res); +} + +template +typed::space typed::map::space() const +{ + auto res = isl::map::space(); + return typed::space(res); +} + +template +typed::map typed::map::subtract(const typed::map &map2) const +{ + auto res = isl::map::subtract(map2); + return typed::map(res); +} + +template +typed::union_map typed::map::subtract(const typed::union_map &umap2) const +{ + auto res = isl::map::subtract(umap2); + return typed::union_map(res); +} + +template +typed::map typed::map::subtract(const typed::basic_map &map2) const +{ + auto res = isl::map::subtract(map2); + return typed::map(res); +} + +template +typed::union_map typed::map::subtract_domain(const typed::union_set &dom) const +{ + auto res = isl::map::subtract_domain(dom); + return typed::union_map(res); +} + +template +typed::union_map typed::map::subtract_range(const typed::union_set &dom) const +{ + auto res = isl::map::subtract_range(dom); + return typed::union_map(res); +} + +template +typed::union_map typed::map::to_union_map() const +{ + auto res = isl::map::to_union_map(); + return typed::union_map(res); +} + +template +typed::map typed::map::unite(const typed::map &map2) const +{ + auto res = isl::map::unite(map2); + return typed::map(res); +} + +template +typed::union_map typed::map::unite(const typed::union_map &umap2) const +{ + auto res = isl::map::unite(umap2); + return typed::union_map(res); +} + +template +typed::map typed::map::unite(const typed::basic_map &map2) const +{ + auto res = isl::map::unite(map2); + return typed::map(res); +} + +template +typed::map typed::map::universe(const typed::space &space) +{ + auto res = isl::map::universe(space); + return typed::map(res); +} + +template +typed::map typed::map::upper_bound(const typed::multi_pw_aff &upper) const +{ + auto res = isl::map::upper_bound(upper); + return typed::map(res); +} + +template +typed::map typed::map::upper_bound(const typed::aff &upper) const +{ + auto res = isl::map::upper_bound(upper); + return typed::map(res); +} + +template +typed::map typed::map::upper_bound(const typed::multi_aff &upper) const +{ + auto res = isl::map::upper_bound(upper); + return typed::map(res); +} + +template +typed::map typed::map::upper_bound(const typed::pw_aff &upper) const +{ + auto res = isl::map::upper_bound(upper); + return typed::map(res); +} + +template +typed::map typed::map::upper_bound(const typed::pw_multi_aff &upper) const +{ + auto res = isl::map::upper_bound(upper); + return typed::map(res); +} + +template +typed::set> typed::map::wrap() const +{ + auto res = isl::map::wrap(); + return typed::set>(res); +} + +template +typed::map>::map(const typed::basic_map> &bmap) + : isl::map(bmap) +{ +} + +template +typed::map>::map(const isl::ctx &ctx, const std::string &str) + : isl::map(ctx, str) +{ +} + +template +template +typed::map> typed::map>::apply_domain(const typed::map &map2) const +{ + auto res = isl::map::apply_domain(map2); + return typed::map>(res); +} + +template +template +typed::union_map> typed::map>::apply_domain(const typed::union_map &umap2) const +{ + auto res = isl::map::apply_domain(umap2); + return typed::union_map>(res); +} + +template +template +typed::map> typed::map>::apply_domain(const typed::basic_map &map2) const +{ + auto res = isl::map::apply_domain(map2); + return typed::map>(res); +} + +template +template +typed::map typed::map>::apply_range(const typed::map, Arg3> &map2) const +{ + auto res = isl::map::apply_range(map2); + return typed::map(res); +} + +template +template +typed::union_map typed::map>::apply_range(const typed::union_map, Arg3> &umap2) const +{ + auto res = isl::map::apply_range(umap2); + return typed::union_map(res); +} + +template +template +typed::map typed::map>::apply_range(const typed::basic_map, Arg3> &map2) const +{ + auto res = isl::map::apply_range(map2); + return typed::map(res); +} + +template +typed::map> typed::map>::as_map() const +{ + auto res = isl::map::as_map(); + return typed::map>(res); +} + +template +typed::multi_union_pw_aff> typed::map>::as_multi_union_pw_aff() const +{ + auto res = isl::map::as_multi_union_pw_aff(); + return typed::multi_union_pw_aff>(res); +} + +template +typed::pw_multi_aff> typed::map>::as_pw_multi_aff() const +{ + auto res = isl::map::as_pw_multi_aff(); + return typed::pw_multi_aff>(res); +} + +template +typed::union_pw_multi_aff> typed::map>::as_union_pw_multi_aff() const +{ + auto res = isl::map::as_union_pw_multi_aff(); + return typed::union_pw_multi_aff>(res); +} + +template +typed::set> typed::map>::bind_domain(const typed::multi_id &tuple) const +{ + auto res = isl::map::bind_domain(tuple); + return typed::set>(res); +} + +template +typed::set typed::map>::bind_range(const typed::multi_id> &tuple) const +{ + auto res = isl::map::bind_range(tuple); + return typed::set(res); +} + +template +typed::map> typed::map>::coalesce() const +{ + auto res = isl::map::coalesce(); + return typed::map>(res); +} + +template +typed::map> typed::map>::detect_equalities() const +{ + auto res = isl::map::detect_equalities(); + return typed::map>(res); +} + +template +typed::set typed::map>::domain() const +{ + auto res = isl::map::domain(); + return typed::set(res); +} + +template +typed::union_map>, Domain> typed::map>::domain_map() const +{ + auto res = isl::map::domain_map(); + return typed::union_map>, Domain>(res); +} + +template +typed::union_pw_multi_aff>, Domain> typed::map>::domain_map_union_pw_multi_aff() const +{ + auto res = isl::map::domain_map_union_pw_multi_aff(); + return typed::union_pw_multi_aff>, Domain>(res); +} + +template +template +typed::map, pair> typed::map>::domain_product(const typed::map> &map2) const +{ + auto res = isl::map::domain_product(map2); + return typed::map, pair>(res); +} + +template +template +typed::union_map, pair> typed::map>::domain_product(const typed::union_map> &umap2) const +{ + auto res = isl::map::domain_product(umap2); + return typed::union_map, pair>(res); +} + +template +template +typed::map, pair> typed::map>::domain_product(const typed::basic_map> &map2) const +{ + auto res = isl::map::domain_product(map2); + return typed::map, pair>(res); +} + +template +typed::map> typed::map>::drop_unused_params() const +{ + auto res = isl::map::drop_unused_params(); + return typed::map>(res); +} + +template +bool typed::map>::every_map(const std::function>)> &test) const +{ + auto lambda_test = [&] (isl::map arg0) { + return test(typed::map>(arg0)); + }; + return isl::map::every_map(lambda_test); +} + +template +typed::map> typed::map>::extract_map(const typed::space> &space) const +{ + auto res = isl::map::extract_map(space); + return typed::map>(res); +} + +template +typed::map typed::map>::flatten_range() const +{ + auto res = isl::map::flatten_range(); + return typed::map(res); +} + +template +void typed::map>::foreach_basic_map(const std::function>)> &fn) const +{ + auto lambda_fn = [&] (isl::basic_map arg0) { + return fn(typed::basic_map>(arg0)); + }; + return isl::map::foreach_basic_map(lambda_fn); +} + +template +void typed::map>::foreach_map(const std::function>)> &fn) const +{ + auto lambda_fn = [&] (isl::map arg0) { + return fn(typed::map>(arg0)); + }; + return isl::map::foreach_map(lambda_fn); +} + +template +typed::map> typed::map>::gist(const typed::map> &context) const +{ + auto res = isl::map::gist(context); + return typed::map>(res); +} + +template +typed::union_map> typed::map>::gist(const typed::union_map> &context) const +{ + auto res = isl::map::gist(context); + return typed::union_map>(res); +} + +template +typed::map> typed::map>::gist(const typed::basic_map> &context) const +{ + auto res = isl::map::gist(context); + return typed::map>(res); +} + +template +typed::map> typed::map>::gist_domain(const typed::set &context) const +{ + auto res = isl::map::gist_domain(context); + return typed::map>(res); +} + +template +typed::union_map> typed::map>::gist_domain(const typed::union_set &uset) const +{ + auto res = isl::map::gist_domain(uset); + return typed::union_map>(res); +} + +template +typed::map> typed::map>::gist_domain(const typed::basic_set &context) const +{ + auto res = isl::map::gist_domain(context); + return typed::map>(res); +} + +template +typed::map> typed::map>::gist_domain(const typed::point &context) const +{ + auto res = isl::map::gist_domain(context); + return typed::map>(res); +} + +template +typed::map> typed::map>::gist_params(const typed::set<> &context) const +{ + auto res = isl::map::gist_params(context); + return typed::map>(res); +} + +template +typed::map> typed::map>::gist_params(const typed::basic_set<> &context) const +{ + auto res = isl::map::gist_params(context); + return typed::map>(res); +} + +template +typed::map> typed::map>::gist_params(const typed::point<> &context) const +{ + auto res = isl::map::gist_params(context); + return typed::map>(res); +} + +template +typed::map> typed::map>::intersect(const typed::map> &map2) const +{ + auto res = isl::map::intersect(map2); + return typed::map>(res); +} + +template +typed::union_map> typed::map>::intersect(const typed::union_map> &umap2) const +{ + auto res = isl::map::intersect(umap2); + return typed::union_map>(res); +} + +template +typed::map> typed::map>::intersect(const typed::basic_map> &map2) const +{ + auto res = isl::map::intersect(map2); + return typed::map>(res); +} + +template +typed::map> typed::map>::intersect_domain(const typed::set &set) const +{ + auto res = isl::map::intersect_domain(set); + return typed::map>(res); +} + +template +typed::union_map> typed::map>::intersect_domain(const typed::space &space) const +{ + auto res = isl::map::intersect_domain(space); + return typed::union_map>(res); +} + +template +typed::union_map> typed::map>::intersect_domain(const typed::union_set &uset) const +{ + auto res = isl::map::intersect_domain(uset); + return typed::union_map>(res); +} + +template +typed::map> typed::map>::intersect_domain(const typed::basic_set &set) const +{ + auto res = isl::map::intersect_domain(set); + return typed::map>(res); +} + +template +typed::map> typed::map>::intersect_domain(const typed::point &set) const +{ + auto res = isl::map::intersect_domain(set); + return typed::map>(res); +} + +template +typed::map> typed::map>::intersect_params(const typed::set<> ¶ms) const +{ + auto res = isl::map::intersect_params(params); + return typed::map>(res); +} + +template +typed::map> typed::map>::intersect_params(const typed::basic_set<> ¶ms) const +{ + auto res = isl::map::intersect_params(params); + return typed::map>(res); +} + +template +typed::map> typed::map>::intersect_params(const typed::point<> ¶ms) const +{ + auto res = isl::map::intersect_params(params); + return typed::map>(res); +} + +template +typed::map> typed::map>::intersect_range(const typed::set> &set) const +{ + auto res = isl::map::intersect_range(set); + return typed::map>(res); +} + +template +typed::union_map> typed::map>::intersect_range(const typed::space> &space) const +{ + auto res = isl::map::intersect_range(space); + return typed::union_map>(res); +} + +template +typed::union_map> typed::map>::intersect_range(const typed::union_set> &uset) const +{ + auto res = isl::map::intersect_range(uset); + return typed::union_map>(res); +} + +template +typed::map> typed::map>::intersect_range(const typed::basic_set> &set) const +{ + auto res = isl::map::intersect_range(set); + return typed::map>(res); +} + +template +typed::map> typed::map>::intersect_range(const typed::point> &set) const +{ + auto res = isl::map::intersect_range(set); + return typed::map>(res); +} + +template +typed::map> typed::map>::intersect_range_wrapped_domain(const typed::set &domain) const +{ + auto res = isl::map::intersect_range_wrapped_domain(domain); + return typed::map>(res); +} + +template +typed::union_map> typed::map>::intersect_range_wrapped_domain(const typed::union_set &domain) const +{ + auto res = isl::map::intersect_range_wrapped_domain(domain); + return typed::union_map>(res); +} + +template +typed::map> typed::map>::intersect_range_wrapped_domain(const typed::basic_set &domain) const +{ + auto res = isl::map::intersect_range_wrapped_domain(domain); + return typed::map>(res); +} + +template +typed::map> typed::map>::intersect_range_wrapped_domain(const typed::point &domain) const +{ + auto res = isl::map::intersect_range_wrapped_domain(domain); + return typed::map>(res); +} + +template +typed::map> typed::map>::lexmax() const +{ + auto res = isl::map::lexmax(); + return typed::map>(res); +} + +template +typed::pw_multi_aff> typed::map>::lexmax_pw_multi_aff() const +{ + auto res = isl::map::lexmax_pw_multi_aff(); + return typed::pw_multi_aff>(res); +} + +template +typed::map> typed::map>::lexmin() const +{ + auto res = isl::map::lexmin(); + return typed::map>(res); +} + +template +typed::pw_multi_aff> typed::map>::lexmin_pw_multi_aff() const +{ + auto res = isl::map::lexmin_pw_multi_aff(); + return typed::pw_multi_aff>(res); +} + +template +typed::map> typed::map>::lower_bound(const typed::multi_pw_aff> &lower) const +{ + auto res = isl::map::lower_bound(lower); + return typed::map>(res); +} + +template +typed::map> typed::map>::lower_bound(const typed::aff> &lower) const +{ + auto res = isl::map::lower_bound(lower); + return typed::map>(res); +} + +template +typed::map> typed::map>::lower_bound(const typed::multi_aff> &lower) const +{ + auto res = isl::map::lower_bound(lower); + return typed::map>(res); +} + +template +typed::map> typed::map>::lower_bound(const typed::pw_aff> &lower) const +{ + auto res = isl::map::lower_bound(lower); + return typed::map>(res); +} + +template +typed::map> typed::map>::lower_bound(const typed::pw_multi_aff> &lower) const +{ + auto res = isl::map::lower_bound(lower); + return typed::map>(res); +} + +template +typed::map_list> typed::map>::map_list() const +{ + auto res = isl::map::map_list(); + return typed::map_list>(res); +} + +template +typed::multi_pw_aff> typed::map>::max_multi_pw_aff() const +{ + auto res = isl::map::max_multi_pw_aff(); + return typed::multi_pw_aff>(res); +} + +template +typed::multi_pw_aff> typed::map>::min_multi_pw_aff() const +{ + auto res = isl::map::min_multi_pw_aff(); + return typed::multi_pw_aff>(res); +} + +template +typed::set<> typed::map>::params() const +{ + auto res = isl::map::params(); + return typed::set<>(res); +} + +template +template +typed::map> typed::map>::preimage_domain(const typed::multi_aff &ma) const +{ + auto res = isl::map::preimage_domain(ma); + return typed::map>(res); +} + +template +template +typed::map> typed::map>::preimage_domain(const typed::multi_pw_aff &mpa) const +{ + auto res = isl::map::preimage_domain(mpa); + return typed::map>(res); +} + +template +template +typed::map> typed::map>::preimage_domain(const typed::pw_multi_aff &pma) const +{ + auto res = isl::map::preimage_domain(pma); + return typed::map>(res); +} + +template +template +typed::union_map> typed::map>::preimage_domain(const typed::union_pw_multi_aff &upma) const +{ + auto res = isl::map::preimage_domain(upma); + return typed::union_map>(res); +} + +template +template +typed::map typed::map>::preimage_range(const typed::multi_aff> &ma) const +{ + auto res = isl::map::preimage_range(ma); + return typed::map(res); +} + +template +template +typed::map typed::map>::preimage_range(const typed::pw_multi_aff> &pma) const +{ + auto res = isl::map::preimage_range(pma); + return typed::map(res); +} + +template +template +typed::union_map typed::map>::preimage_range(const typed::union_pw_multi_aff> &upma) const +{ + auto res = isl::map::preimage_range(upma); + return typed::union_map(res); +} + +template +template +typed::map, pair, Arg3>> typed::map>::product(const typed::map &map2) const +{ + auto res = isl::map::product(map2); + return typed::map, pair, Arg3>>(res); +} + +template +template +typed::union_map, pair, Arg3>> typed::map>::product(const typed::union_map &umap2) const +{ + auto res = isl::map::product(umap2); + return typed::union_map, pair, Arg3>>(res); +} + +template +template +typed::map, pair, Arg3>> typed::map>::product(const typed::basic_map &map2) const +{ + auto res = isl::map::product(map2); + return typed::map, pair, Arg3>>(res); +} + +template +typed::map> typed::map>::project_out_all_params() const +{ + auto res = isl::map::project_out_all_params(); + return typed::map>(res); +} + +template +typed::map> typed::map>::project_out_param(const typed::id &id) const +{ + auto res = isl::map::project_out_param(id); + return typed::map>(res); +} + +template +typed::map> typed::map>::project_out_param(const std::string &id) const +{ + auto res = isl::map::project_out_param(id); + return typed::map>(res); +} + +template +typed::map> typed::map>::project_out_param(const typed::id_list &list) const +{ + auto res = isl::map::project_out_param(list); + return typed::map>(res); +} + +template +typed::set> typed::map>::range() const +{ + auto res = isl::map::range(); + return typed::set>(res); +} + +template +typed::map typed::map>::range_factor_domain() const +{ + auto res = isl::map::range_factor_domain(); + return typed::map(res); +} + +template +typed::map typed::map>::range_factor_range() const +{ + auto res = isl::map::range_factor_range(); + return typed::map(res); +} + +template +typed::fixed_box> typed::map>::range_lattice_tile() const +{ + auto res = isl::map::range_lattice_tile(); + return typed::fixed_box>(res); +} + +template +typed::union_map>, pair> typed::map>::range_map() const +{ + auto res = isl::map::range_map(); + return typed::union_map>, pair>(res); +} + +template +template +typed::map, Arg3>> typed::map>::range_product(const typed::map &map2) const +{ + auto res = isl::map::range_product(map2); + return typed::map, Arg3>>(res); +} + +template +template +typed::union_map, Arg3>> typed::map>::range_product(const typed::union_map &umap2) const +{ + auto res = isl::map::range_product(umap2); + return typed::union_map, Arg3>>(res); +} + +template +template +typed::map, Arg3>> typed::map>::range_product(const typed::basic_map &map2) const +{ + auto res = isl::map::range_product(map2); + return typed::map, Arg3>>(res); +} + +template +typed::map> typed::map>::range_reverse() const +{ + auto res = isl::map::range_reverse(); + return typed::map>(res); +} + +template +typed::fixed_box> typed::map>::range_simple_fixed_box_hull() const +{ + auto res = isl::map::range_simple_fixed_box_hull(); + return typed::fixed_box>(res); +} + +template +typed::map, Domain> typed::map>::reverse() const +{ + auto res = isl::map::reverse(); + return typed::map, Domain>(res); +} + +template +template +typed::map> typed::map>::set_domain_tuple(const typed::id &id) const +{ + auto res = isl::map::set_domain_tuple(id); + return typed::map>(res); +} + +template +template +typed::map> typed::map>::set_domain_tuple(const std::string &id) const +{ + auto res = isl::map::set_domain_tuple(id); + return typed::map>(res); +} + +template +typed::space> typed::map>::space() const +{ + auto res = isl::map::space(); + return typed::space>(res); +} + +template +typed::map> typed::map>::subtract(const typed::map> &map2) const +{ + auto res = isl::map::subtract(map2); + return typed::map>(res); +} + +template +typed::union_map> typed::map>::subtract(const typed::union_map> &umap2) const +{ + auto res = isl::map::subtract(umap2); + return typed::union_map>(res); +} + +template +typed::map> typed::map>::subtract(const typed::basic_map> &map2) const +{ + auto res = isl::map::subtract(map2); + return typed::map>(res); +} + +template +typed::union_map> typed::map>::subtract_domain(const typed::union_set &dom) const +{ + auto res = isl::map::subtract_domain(dom); + return typed::union_map>(res); +} + +template +typed::union_map> typed::map>::subtract_range(const typed::union_set> &dom) const +{ + auto res = isl::map::subtract_range(dom); + return typed::union_map>(res); +} + +template +typed::union_map> typed::map>::to_union_map() const +{ + auto res = isl::map::to_union_map(); + return typed::union_map>(res); +} + +template +typed::map, Range2> typed::map>::uncurry() const +{ + auto res = isl::map::uncurry(); + return typed::map, Range2>(res); +} + +template +typed::map> typed::map>::unite(const typed::map> &map2) const +{ + auto res = isl::map::unite(map2); + return typed::map>(res); +} + +template +typed::union_map> typed::map>::unite(const typed::union_map> &umap2) const +{ + auto res = isl::map::unite(umap2); + return typed::union_map>(res); +} + +template +typed::map> typed::map>::unite(const typed::basic_map> &map2) const +{ + auto res = isl::map::unite(map2); + return typed::map>(res); +} + +template +typed::map> typed::map>::universe(const typed::space> &space) +{ + auto res = isl::map::universe(space); + return typed::map>(res); +} + +template +typed::map> typed::map>::upper_bound(const typed::multi_pw_aff> &upper) const +{ + auto res = isl::map::upper_bound(upper); + return typed::map>(res); +} + +template +typed::map> typed::map>::upper_bound(const typed::aff> &upper) const +{ + auto res = isl::map::upper_bound(upper); + return typed::map>(res); +} + +template +typed::map> typed::map>::upper_bound(const typed::multi_aff> &upper) const +{ + auto res = isl::map::upper_bound(upper); + return typed::map>(res); +} + +template +typed::map> typed::map>::upper_bound(const typed::pw_aff> &upper) const +{ + auto res = isl::map::upper_bound(upper); + return typed::map>(res); +} + +template +typed::map> typed::map>::upper_bound(const typed::pw_multi_aff> &upper) const +{ + auto res = isl::map::upper_bound(upper); + return typed::map>(res); +} + +template +typed::set>> typed::map>::wrap() const +{ + auto res = isl::map::wrap(); + return typed::set>>(res); +} + +template +typed::map, pair>::map(const typed::basic_map, pair> &bmap) + : isl::map(bmap) +{ +} + +template +typed::map, pair>::map(const isl::ctx &ctx, const std::string &str) + : isl::map(ctx, str) +{ +} + +template +template +typed::map> typed::map, pair>::apply_domain(const typed::map, Domain2> &map2) const +{ + auto res = isl::map::apply_domain(map2); + return typed::map>(res); +} + +template +template +typed::union_map> typed::map, pair>::apply_domain(const typed::union_map, Domain2> &umap2) const +{ + auto res = isl::map::apply_domain(umap2); + return typed::union_map>(res); +} + +template +template +typed::map> typed::map, pair>::apply_domain(const typed::basic_map, Domain2> &map2) const +{ + auto res = isl::map::apply_domain(map2); + return typed::map>(res); +} + +template +template +typed::map, Range2> typed::map, pair>::apply_range(const typed::map, Range2> &map2) const +{ + auto res = isl::map::apply_range(map2); + return typed::map, Range2>(res); +} + +template +template +typed::union_map, Range2> typed::map, pair>::apply_range(const typed::union_map, Range2> &umap2) const +{ + auto res = isl::map::apply_range(umap2); + return typed::union_map, Range2>(res); +} + +template +template +typed::map, Range2> typed::map, pair>::apply_range(const typed::basic_map, Range2> &map2) const +{ + auto res = isl::map::apply_range(map2); + return typed::map, Range2>(res); +} + +template +typed::map, pair> typed::map, pair>::as_map() const +{ + auto res = isl::map::as_map(); + return typed::map, pair>(res); +} + +template +typed::multi_union_pw_aff, pair> typed::map, pair>::as_multi_union_pw_aff() const +{ + auto res = isl::map::as_multi_union_pw_aff(); + return typed::multi_union_pw_aff, pair>(res); +} + +template +typed::pw_multi_aff, pair> typed::map, pair>::as_pw_multi_aff() const +{ + auto res = isl::map::as_pw_multi_aff(); + return typed::pw_multi_aff, pair>(res); +} + +template +typed::union_pw_multi_aff, pair> typed::map, pair>::as_union_pw_multi_aff() const +{ + auto res = isl::map::as_union_pw_multi_aff(); + return typed::union_pw_multi_aff, pair>(res); +} + +template +typed::set> typed::map, pair>::bind_domain(const typed::multi_id> &tuple) const +{ + auto res = isl::map::bind_domain(tuple); + return typed::set>(res); +} + +template +typed::set> typed::map, pair>::bind_range(const typed::multi_id> &tuple) const +{ + auto res = isl::map::bind_range(tuple); + return typed::set>(res); +} + +template +typed::map, pair> typed::map, pair>::coalesce() const +{ + auto res = isl::map::coalesce(); + return typed::map, pair>(res); +} + +template +typed::map>> typed::map, pair>::curry() const +{ + auto res = isl::map::curry(); + return typed::map>>(res); +} + +template +typed::set> typed::map, pair>::deltas() const +{ + auto res = isl::map::deltas(); + return typed::set>(res); +} + +template +typed::map, pair> typed::map, pair>::detect_equalities() const +{ + auto res = isl::map::detect_equalities(); + return typed::map, pair>(res); +} + +template +typed::set> typed::map, pair>::domain() const +{ + auto res = isl::map::domain(); + return typed::set>(res); +} + +template +typed::map> typed::map, pair>::domain_factor_domain() const +{ + auto res = isl::map::domain_factor_domain(); + return typed::map>(res); +} + +template +typed::map> typed::map, pair>::domain_factor_range() const +{ + auto res = isl::map::domain_factor_range(); + return typed::map>(res); +} + +template +typed::union_map, pair>, pair> typed::map, pair>::domain_map() const +{ + auto res = isl::map::domain_map(); + return typed::union_map, pair>, pair>(res); +} + +template +typed::union_pw_multi_aff, pair>, pair> typed::map, pair>::domain_map_union_pw_multi_aff() const +{ + auto res = isl::map::domain_map_union_pw_multi_aff(); + return typed::union_pw_multi_aff, pair>, pair>(res); +} + +template +template +typed::map, Domain2>, pair> typed::map, pair>::domain_product(const typed::map> &map2) const +{ + auto res = isl::map::domain_product(map2); + return typed::map, Domain2>, pair>(res); +} + +template +template +typed::union_map, Domain2>, pair> typed::map, pair>::domain_product(const typed::union_map> &umap2) const +{ + auto res = isl::map::domain_product(umap2); + return typed::union_map, Domain2>, pair>(res); +} + +template +template +typed::map, Domain2>, pair> typed::map, pair>::domain_product(const typed::basic_map> &map2) const +{ + auto res = isl::map::domain_product(map2); + return typed::map, Domain2>, pair>(res); +} + +template +typed::map, pair> typed::map, pair>::domain_reverse() const +{ + auto res = isl::map::domain_reverse(); + return typed::map, pair>(res); +} + +template +typed::map, pair> typed::map, pair>::drop_unused_params() const +{ + auto res = isl::map::drop_unused_params(); + return typed::map, pair>(res); +} + +template +template +typed::map, pair> typed::map, pair>::eq_at(const typed::multi_pw_aff, Range> &mpa) const +{ + auto res = isl::map::eq_at(mpa); + return typed::map, pair>(res); +} + +template +template +typed::union_map, pair> typed::map, pair>::eq_at(const typed::multi_union_pw_aff, Range> &mupa) const +{ + auto res = isl::map::eq_at(mupa); + return typed::union_map, pair>(res); +} + +template +typed::map, pair> typed::map, pair>::eq_at(const typed::aff, Anonymous> &mpa) const +{ + auto res = isl::map::eq_at(mpa); + return typed::map, pair>(res); +} + +template +template +typed::map, pair> typed::map, pair>::eq_at(const typed::multi_aff, Range> &mpa) const +{ + auto res = isl::map::eq_at(mpa); + return typed::map, pair>(res); +} + +template +typed::map, pair> typed::map, pair>::eq_at(const typed::pw_aff, Anonymous> &mpa) const +{ + auto res = isl::map::eq_at(mpa); + return typed::map, pair>(res); +} + +template +template +typed::map, pair> typed::map, pair>::eq_at(const typed::pw_multi_aff, Range> &mpa) const +{ + auto res = isl::map::eq_at(mpa); + return typed::map, pair>(res); +} + +template +bool typed::map, pair>::every_map(const std::function, pair>)> &test) const +{ + auto lambda_test = [&] (isl::map arg0) { + return test(typed::map, pair>(arg0)); + }; + return isl::map::every_map(lambda_test); +} + +template +typed::map, pair> typed::map, pair>::extract_map(const typed::space, pair> &space) const +{ + auto res = isl::map::extract_map(space); + return typed::map, pair>(res); +} + +template +typed::map> typed::map, pair>::flatten_domain() const +{ + auto res = isl::map::flatten_domain(); + return typed::map>(res); +} + +template +typed::map, Anonymous> typed::map, pair>::flatten_range() const +{ + auto res = isl::map::flatten_range(); + return typed::map, Anonymous>(res); +} + +template +void typed::map, pair>::foreach_basic_map(const std::function, pair>)> &fn) const +{ + auto lambda_fn = [&] (isl::basic_map arg0) { + return fn(typed::basic_map, pair>(arg0)); + }; + return isl::map::foreach_basic_map(lambda_fn); +} + +template +void typed::map, pair>::foreach_map(const std::function, pair>)> &fn) const +{ + auto lambda_fn = [&] (isl::map arg0) { + return fn(typed::map, pair>(arg0)); + }; + return isl::map::foreach_map(lambda_fn); +} + +template +typed::map, pair> typed::map, pair>::gist(const typed::map, pair> &context) const +{ + auto res = isl::map::gist(context); + return typed::map, pair>(res); +} + +template +typed::union_map, pair> typed::map, pair>::gist(const typed::union_map, pair> &context) const +{ + auto res = isl::map::gist(context); + return typed::union_map, pair>(res); +} + +template +typed::map, pair> typed::map, pair>::gist(const typed::basic_map, pair> &context) const +{ + auto res = isl::map::gist(context); + return typed::map, pair>(res); +} + +template +typed::map, pair> typed::map, pair>::gist_domain(const typed::set> &context) const +{ + auto res = isl::map::gist_domain(context); + return typed::map, pair>(res); +} + +template +typed::union_map, pair> typed::map, pair>::gist_domain(const typed::union_set> &uset) const +{ + auto res = isl::map::gist_domain(uset); + return typed::union_map, pair>(res); +} + +template +typed::map, pair> typed::map, pair>::gist_domain(const typed::basic_set> &context) const +{ + auto res = isl::map::gist_domain(context); + return typed::map, pair>(res); +} + +template +typed::map, pair> typed::map, pair>::gist_domain(const typed::point> &context) const +{ + auto res = isl::map::gist_domain(context); + return typed::map, pair>(res); +} + +template +typed::map, pair> typed::map, pair>::gist_params(const typed::set<> &context) const +{ + auto res = isl::map::gist_params(context); + return typed::map, pair>(res); +} + +template +typed::map, pair> typed::map, pair>::gist_params(const typed::basic_set<> &context) const +{ + auto res = isl::map::gist_params(context); + return typed::map, pair>(res); +} + +template +typed::map, pair> typed::map, pair>::gist_params(const typed::point<> &context) const +{ + auto res = isl::map::gist_params(context); + return typed::map, pair>(res); +} + +template +typed::map, pair> typed::map, pair>::intersect(const typed::map, pair> &map2) const +{ + auto res = isl::map::intersect(map2); + return typed::map, pair>(res); +} + +template +typed::union_map, pair> typed::map, pair>::intersect(const typed::union_map, pair> &umap2) const +{ + auto res = isl::map::intersect(umap2); + return typed::union_map, pair>(res); +} + +template +typed::map, pair> typed::map, pair>::intersect(const typed::basic_map, pair> &map2) const +{ + auto res = isl::map::intersect(map2); + return typed::map, pair>(res); +} + +template +typed::map, pair> typed::map, pair>::intersect_domain(const typed::set> &set) const +{ + auto res = isl::map::intersect_domain(set); + return typed::map, pair>(res); +} + +template +typed::union_map, pair> typed::map, pair>::intersect_domain(const typed::space> &space) const +{ + auto res = isl::map::intersect_domain(space); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::map, pair>::intersect_domain(const typed::union_set> &uset) const +{ + auto res = isl::map::intersect_domain(uset); + return typed::union_map, pair>(res); +} + +template +typed::map, pair> typed::map, pair>::intersect_domain(const typed::basic_set> &set) const +{ + auto res = isl::map::intersect_domain(set); + return typed::map, pair>(res); +} + +template +typed::map, pair> typed::map, pair>::intersect_domain(const typed::point> &set) const +{ + auto res = isl::map::intersect_domain(set); + return typed::map, pair>(res); +} + +template +typed::map, pair> typed::map, pair>::intersect_domain_wrapped_domain(const typed::set &domain) const +{ + auto res = isl::map::intersect_domain_wrapped_domain(domain); + return typed::map, pair>(res); +} + +template +typed::union_map, pair> typed::map, pair>::intersect_domain_wrapped_domain(const typed::union_set &domain) const +{ + auto res = isl::map::intersect_domain_wrapped_domain(domain); + return typed::union_map, pair>(res); +} + +template +typed::map, pair> typed::map, pair>::intersect_domain_wrapped_domain(const typed::basic_set &domain) const +{ + auto res = isl::map::intersect_domain_wrapped_domain(domain); + return typed::map, pair>(res); +} + +template +typed::map, pair> typed::map, pair>::intersect_domain_wrapped_domain(const typed::point &domain) const +{ + auto res = isl::map::intersect_domain_wrapped_domain(domain); + return typed::map, pair>(res); +} + +template +typed::map, pair> typed::map, pair>::intersect_params(const typed::set<> ¶ms) const +{ + auto res = isl::map::intersect_params(params); + return typed::map, pair>(res); +} + +template +typed::map, pair> typed::map, pair>::intersect_params(const typed::basic_set<> ¶ms) const +{ + auto res = isl::map::intersect_params(params); + return typed::map, pair>(res); +} + +template +typed::map, pair> typed::map, pair>::intersect_params(const typed::point<> ¶ms) const +{ + auto res = isl::map::intersect_params(params); + return typed::map, pair>(res); +} + +template +typed::map, pair> typed::map, pair>::intersect_range(const typed::set> &set) const +{ + auto res = isl::map::intersect_range(set); + return typed::map, pair>(res); +} + +template +typed::union_map, pair> typed::map, pair>::intersect_range(const typed::space> &space) const +{ + auto res = isl::map::intersect_range(space); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::map, pair>::intersect_range(const typed::union_set> &uset) const +{ + auto res = isl::map::intersect_range(uset); + return typed::union_map, pair>(res); +} + +template +typed::map, pair> typed::map, pair>::intersect_range(const typed::basic_set> &set) const +{ + auto res = isl::map::intersect_range(set); + return typed::map, pair>(res); +} + +template +typed::map, pair> typed::map, pair>::intersect_range(const typed::point> &set) const +{ + auto res = isl::map::intersect_range(set); + return typed::map, pair>(res); +} + +template +typed::map, pair> typed::map, pair>::intersect_range_wrapped_domain(const typed::set &domain) const +{ + auto res = isl::map::intersect_range_wrapped_domain(domain); + return typed::map, pair>(res); +} + +template +typed::union_map, pair> typed::map, pair>::intersect_range_wrapped_domain(const typed::union_set &domain) const +{ + auto res = isl::map::intersect_range_wrapped_domain(domain); + return typed::union_map, pair>(res); +} + +template +typed::map, pair> typed::map, pair>::intersect_range_wrapped_domain(const typed::basic_set &domain) const +{ + auto res = isl::map::intersect_range_wrapped_domain(domain); + return typed::map, pair>(res); +} + +template +typed::map, pair> typed::map, pair>::intersect_range_wrapped_domain(const typed::point &domain) const +{ + auto res = isl::map::intersect_range_wrapped_domain(domain); + return typed::map, pair>(res); +} + +template +template +typed::map, pair> typed::map, pair>::lex_ge_at(const typed::multi_pw_aff, Range> &mpa) const +{ + auto res = isl::map::lex_ge_at(mpa); + return typed::map, pair>(res); +} + +template +typed::map, pair> typed::map, pair>::lex_ge_at(const typed::aff, Anonymous> &mpa) const +{ + auto res = isl::map::lex_ge_at(mpa); + return typed::map, pair>(res); +} + +template +template +typed::map, pair> typed::map, pair>::lex_ge_at(const typed::multi_aff, Range> &mpa) const +{ + auto res = isl::map::lex_ge_at(mpa); + return typed::map, pair>(res); +} + +template +typed::map, pair> typed::map, pair>::lex_ge_at(const typed::pw_aff, Anonymous> &mpa) const +{ + auto res = isl::map::lex_ge_at(mpa); + return typed::map, pair>(res); +} + +template +template +typed::map, pair> typed::map, pair>::lex_ge_at(const typed::pw_multi_aff, Range> &mpa) const +{ + auto res = isl::map::lex_ge_at(mpa); + return typed::map, pair>(res); +} + +template +template +typed::map, pair> typed::map, pair>::lex_gt_at(const typed::multi_pw_aff, Range> &mpa) const +{ + auto res = isl::map::lex_gt_at(mpa); + return typed::map, pair>(res); +} + +template +typed::map, pair> typed::map, pair>::lex_gt_at(const typed::aff, Anonymous> &mpa) const +{ + auto res = isl::map::lex_gt_at(mpa); + return typed::map, pair>(res); +} + +template +template +typed::map, pair> typed::map, pair>::lex_gt_at(const typed::multi_aff, Range> &mpa) const +{ + auto res = isl::map::lex_gt_at(mpa); + return typed::map, pair>(res); +} + +template +typed::map, pair> typed::map, pair>::lex_gt_at(const typed::pw_aff, Anonymous> &mpa) const +{ + auto res = isl::map::lex_gt_at(mpa); + return typed::map, pair>(res); +} + +template +template +typed::map, pair> typed::map, pair>::lex_gt_at(const typed::pw_multi_aff, Range> &mpa) const +{ + auto res = isl::map::lex_gt_at(mpa); + return typed::map, pair>(res); +} + +template +template +typed::map, pair> typed::map, pair>::lex_le_at(const typed::multi_pw_aff, Range> &mpa) const +{ + auto res = isl::map::lex_le_at(mpa); + return typed::map, pair>(res); +} + +template +typed::map, pair> typed::map, pair>::lex_le_at(const typed::aff, Anonymous> &mpa) const +{ + auto res = isl::map::lex_le_at(mpa); + return typed::map, pair>(res); +} + +template +template +typed::map, pair> typed::map, pair>::lex_le_at(const typed::multi_aff, Range> &mpa) const +{ + auto res = isl::map::lex_le_at(mpa); + return typed::map, pair>(res); +} + +template +typed::map, pair> typed::map, pair>::lex_le_at(const typed::pw_aff, Anonymous> &mpa) const +{ + auto res = isl::map::lex_le_at(mpa); + return typed::map, pair>(res); +} + +template +template +typed::map, pair> typed::map, pair>::lex_le_at(const typed::pw_multi_aff, Range> &mpa) const +{ + auto res = isl::map::lex_le_at(mpa); + return typed::map, pair>(res); +} + +template +template +typed::map, pair> typed::map, pair>::lex_lt_at(const typed::multi_pw_aff, Range> &mpa) const +{ + auto res = isl::map::lex_lt_at(mpa); + return typed::map, pair>(res); +} + +template +typed::map, pair> typed::map, pair>::lex_lt_at(const typed::aff, Anonymous> &mpa) const +{ + auto res = isl::map::lex_lt_at(mpa); + return typed::map, pair>(res); +} + +template +template +typed::map, pair> typed::map, pair>::lex_lt_at(const typed::multi_aff, Range> &mpa) const +{ + auto res = isl::map::lex_lt_at(mpa); + return typed::map, pair>(res); +} + +template +typed::map, pair> typed::map, pair>::lex_lt_at(const typed::pw_aff, Anonymous> &mpa) const +{ + auto res = isl::map::lex_lt_at(mpa); + return typed::map, pair>(res); +} + +template +template +typed::map, pair> typed::map, pair>::lex_lt_at(const typed::pw_multi_aff, Range> &mpa) const +{ + auto res = isl::map::lex_lt_at(mpa); + return typed::map, pair>(res); +} + +template +typed::map, pair> typed::map, pair>::lexmax() const +{ + auto res = isl::map::lexmax(); + return typed::map, pair>(res); +} + +template +typed::pw_multi_aff, pair> typed::map, pair>::lexmax_pw_multi_aff() const +{ + auto res = isl::map::lexmax_pw_multi_aff(); + return typed::pw_multi_aff, pair>(res); +} + +template +typed::map, pair> typed::map, pair>::lexmin() const +{ + auto res = isl::map::lexmin(); + return typed::map, pair>(res); +} + +template +typed::pw_multi_aff, pair> typed::map, pair>::lexmin_pw_multi_aff() const +{ + auto res = isl::map::lexmin_pw_multi_aff(); + return typed::pw_multi_aff, pair>(res); +} + +template +typed::map, pair> typed::map, pair>::lower_bound(const typed::multi_pw_aff, pair> &lower) const +{ + auto res = isl::map::lower_bound(lower); + return typed::map, pair>(res); +} + +template +typed::map, pair> typed::map, pair>::lower_bound(const typed::aff, pair> &lower) const +{ + auto res = isl::map::lower_bound(lower); + return typed::map, pair>(res); +} + +template +typed::map, pair> typed::map, pair>::lower_bound(const typed::multi_aff, pair> &lower) const +{ + auto res = isl::map::lower_bound(lower); + return typed::map, pair>(res); +} + +template +typed::map, pair> typed::map, pair>::lower_bound(const typed::pw_aff, pair> &lower) const +{ + auto res = isl::map::lower_bound(lower); + return typed::map, pair>(res); +} + +template +typed::map, pair> typed::map, pair>::lower_bound(const typed::pw_multi_aff, pair> &lower) const +{ + auto res = isl::map::lower_bound(lower); + return typed::map, pair>(res); +} + +template +typed::map_list, pair> typed::map, pair>::map_list() const +{ + auto res = isl::map::map_list(); + return typed::map_list, pair>(res); +} + +template +typed::multi_pw_aff, pair> typed::map, pair>::max_multi_pw_aff() const +{ + auto res = isl::map::max_multi_pw_aff(); + return typed::multi_pw_aff, pair>(res); +} + +template +typed::multi_pw_aff, pair> typed::map, pair>::min_multi_pw_aff() const +{ + auto res = isl::map::min_multi_pw_aff(); + return typed::multi_pw_aff, pair>(res); +} + +template +typed::set<> typed::map, pair>::params() const +{ + auto res = isl::map::params(); + return typed::set<>(res); +} + +template +template +typed::map> typed::map, pair>::preimage_domain(const typed::multi_aff> &ma) const +{ + auto res = isl::map::preimage_domain(ma); + return typed::map>(res); +} + +template +template +typed::map> typed::map, pair>::preimage_domain(const typed::multi_pw_aff> &mpa) const +{ + auto res = isl::map::preimage_domain(mpa); + return typed::map>(res); +} + +template +template +typed::map> typed::map, pair>::preimage_domain(const typed::pw_multi_aff> &pma) const +{ + auto res = isl::map::preimage_domain(pma); + return typed::map>(res); +} + +template +template +typed::union_map> typed::map, pair>::preimage_domain(const typed::union_pw_multi_aff> &upma) const +{ + auto res = isl::map::preimage_domain(upma); + return typed::union_map>(res); +} + +template +template +typed::map, Range2> typed::map, pair>::preimage_range(const typed::multi_aff> &ma) const +{ + auto res = isl::map::preimage_range(ma); + return typed::map, Range2>(res); +} + +template +template +typed::map, Range2> typed::map, pair>::preimage_range(const typed::pw_multi_aff> &pma) const +{ + auto res = isl::map::preimage_range(pma); + return typed::map, Range2>(res); +} + +template +template +typed::union_map, Range2> typed::map, pair>::preimage_range(const typed::union_pw_multi_aff> &upma) const +{ + auto res = isl::map::preimage_range(upma); + return typed::union_map, Range2>(res); +} + +template +template +typed::map, Domain2>, pair, Range2>> typed::map, pair>::product(const typed::map &map2) const +{ + auto res = isl::map::product(map2); + return typed::map, Domain2>, pair, Range2>>(res); +} + +template +template +typed::union_map, Domain2>, pair, Range2>> typed::map, pair>::product(const typed::union_map &umap2) const +{ + auto res = isl::map::product(umap2); + return typed::union_map, Domain2>, pair, Range2>>(res); +} + +template +template +typed::map, Domain2>, pair, Range2>> typed::map, pair>::product(const typed::basic_map &map2) const +{ + auto res = isl::map::product(map2); + return typed::map, Domain2>, pair, Range2>>(res); +} + +template +typed::map, pair> typed::map, pair>::project_out_all_params() const +{ + auto res = isl::map::project_out_all_params(); + return typed::map, pair>(res); +} + +template +typed::map, pair> typed::map, pair>::project_out_param(const typed::id &id) const +{ + auto res = isl::map::project_out_param(id); + return typed::map, pair>(res); +} + +template +typed::map, pair> typed::map, pair>::project_out_param(const std::string &id) const +{ + auto res = isl::map::project_out_param(id); + return typed::map, pair>(res); +} + +template +typed::map, pair> typed::map, pair>::project_out_param(const typed::id_list &list) const +{ + auto res = isl::map::project_out_param(list); + return typed::map, pair>(res); +} + +template +typed::set> typed::map, pair>::range() const +{ + auto res = isl::map::range(); + return typed::set>(res); +} + +template +typed::map, T1> typed::map, pair>::range_factor_domain() const +{ + auto res = isl::map::range_factor_domain(); + return typed::map, T1>(res); +} + +template +typed::map, T2> typed::map, pair>::range_factor_range() const +{ + auto res = isl::map::range_factor_range(); + return typed::map, T2>(res); +} + +template +typed::fixed_box, pair> typed::map, pair>::range_lattice_tile() const +{ + auto res = isl::map::range_lattice_tile(); + return typed::fixed_box, pair>(res); +} + +template +typed::union_map, pair>, pair> typed::map, pair>::range_map() const +{ + auto res = isl::map::range_map(); + return typed::union_map, pair>, pair>(res); +} + +template +template +typed::map, pair, Range2>> typed::map, pair>::range_product(const typed::map, Range2> &map2) const +{ + auto res = isl::map::range_product(map2); + return typed::map, pair, Range2>>(res); +} + +template +template +typed::union_map, pair, Range2>> typed::map, pair>::range_product(const typed::union_map, Range2> &umap2) const +{ + auto res = isl::map::range_product(umap2); + return typed::union_map, pair, Range2>>(res); +} + +template +template +typed::map, pair, Range2>> typed::map, pair>::range_product(const typed::basic_map, Range2> &map2) const +{ + auto res = isl::map::range_product(map2); + return typed::map, pair, Range2>>(res); +} + +template +typed::map, pair> typed::map, pair>::range_reverse() const +{ + auto res = isl::map::range_reverse(); + return typed::map, pair>(res); +} + +template +typed::fixed_box, pair> typed::map, pair>::range_simple_fixed_box_hull() const +{ + auto res = isl::map::range_simple_fixed_box_hull(); + return typed::fixed_box, pair>(res); +} + +template +typed::map, pair> typed::map, pair>::reverse() const +{ + auto res = isl::map::reverse(); + return typed::map, pair>(res); +} + +template +typed::space, pair> typed::map, pair>::space() const +{ + auto res = isl::map::space(); + return typed::space, pair>(res); +} + +template +typed::map, pair> typed::map, pair>::subtract(const typed::map, pair> &map2) const +{ + auto res = isl::map::subtract(map2); + return typed::map, pair>(res); +} + +template +typed::union_map, pair> typed::map, pair>::subtract(const typed::union_map, pair> &umap2) const +{ + auto res = isl::map::subtract(umap2); + return typed::union_map, pair>(res); +} + +template +typed::map, pair> typed::map, pair>::subtract(const typed::basic_map, pair> &map2) const +{ + auto res = isl::map::subtract(map2); + return typed::map, pair>(res); +} + +template +typed::union_map, pair> typed::map, pair>::subtract_domain(const typed::union_set> &dom) const +{ + auto res = isl::map::subtract_domain(dom); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::map, pair>::subtract_range(const typed::union_set> &dom) const +{ + auto res = isl::map::subtract_range(dom); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::map, pair>::to_union_map() const +{ + auto res = isl::map::to_union_map(); + return typed::union_map, pair>(res); +} + +template +typed::map, T1>, T2> typed::map, pair>::uncurry() const +{ + auto res = isl::map::uncurry(); + return typed::map, T1>, T2>(res); +} + +template +typed::map, pair> typed::map, pair>::unite(const typed::map, pair> &map2) const +{ + auto res = isl::map::unite(map2); + return typed::map, pair>(res); +} + +template +typed::union_map, pair> typed::map, pair>::unite(const typed::union_map, pair> &umap2) const +{ + auto res = isl::map::unite(umap2); + return typed::union_map, pair>(res); +} + +template +typed::map, pair> typed::map, pair>::unite(const typed::basic_map, pair> &map2) const +{ + auto res = isl::map::unite(map2); + return typed::map, pair>(res); +} + +template +typed::map, pair> typed::map, pair>::universe(const typed::space, pair> &space) +{ + auto res = isl::map::universe(space); + return typed::map, pair>(res); +} + +template +typed::map, pair> typed::map, pair>::upper_bound(const typed::multi_pw_aff, pair> &upper) const +{ + auto res = isl::map::upper_bound(upper); + return typed::map, pair>(res); +} + +template +typed::map, pair> typed::map, pair>::upper_bound(const typed::aff, pair> &upper) const +{ + auto res = isl::map::upper_bound(upper); + return typed::map, pair>(res); +} + +template +typed::map, pair> typed::map, pair>::upper_bound(const typed::multi_aff, pair> &upper) const +{ + auto res = isl::map::upper_bound(upper); + return typed::map, pair>(res); +} + +template +typed::map, pair> typed::map, pair>::upper_bound(const typed::pw_aff, pair> &upper) const +{ + auto res = isl::map::upper_bound(upper); + return typed::map, pair>(res); +} + +template +typed::map, pair> typed::map, pair>::upper_bound(const typed::pw_multi_aff, pair> &upper) const +{ + auto res = isl::map::upper_bound(upper); + return typed::map, pair>(res); +} + +template +typed::set, pair>> typed::map, pair>::wrap() const +{ + auto res = isl::map::wrap(); + return typed::set, pair>>(res); +} + +template +typed::map, pair>::map(const typed::basic_map, pair> &bmap) + : isl::map(bmap) +{ +} + +template +typed::map, pair>::map(const isl::ctx &ctx, const std::string &str) + : isl::map(ctx, str) +{ +} + +template +template +typed::map> typed::map, pair>::apply_domain(const typed::map, Domain2> &map2) const +{ + auto res = isl::map::apply_domain(map2); + return typed::map>(res); +} + +template +template +typed::union_map> typed::map, pair>::apply_domain(const typed::union_map, Domain2> &umap2) const +{ + auto res = isl::map::apply_domain(umap2); + return typed::union_map>(res); +} + +template +template +typed::map> typed::map, pair>::apply_domain(const typed::basic_map, Domain2> &map2) const +{ + auto res = isl::map::apply_domain(map2); + return typed::map>(res); +} + +template +template +typed::map, Arg2> typed::map, pair>::apply_range(const typed::map, Arg2> &map2) const +{ + auto res = isl::map::apply_range(map2); + return typed::map, Arg2>(res); +} + +template +template +typed::union_map, Arg2> typed::map, pair>::apply_range(const typed::union_map, Arg2> &umap2) const +{ + auto res = isl::map::apply_range(umap2); + return typed::union_map, Arg2>(res); +} + +template +template +typed::map, Arg2> typed::map, pair>::apply_range(const typed::basic_map, Arg2> &map2) const +{ + auto res = isl::map::apply_range(map2); + return typed::map, Arg2>(res); +} + +template +typed::map, pair> typed::map, pair>::as_map() const +{ + auto res = isl::map::as_map(); + return typed::map, pair>(res); +} + +template +typed::multi_union_pw_aff, pair> typed::map, pair>::as_multi_union_pw_aff() const +{ + auto res = isl::map::as_multi_union_pw_aff(); + return typed::multi_union_pw_aff, pair>(res); +} + +template +typed::pw_multi_aff, pair> typed::map, pair>::as_pw_multi_aff() const +{ + auto res = isl::map::as_pw_multi_aff(); + return typed::pw_multi_aff, pair>(res); +} + +template +typed::union_pw_multi_aff, pair> typed::map, pair>::as_union_pw_multi_aff() const +{ + auto res = isl::map::as_union_pw_multi_aff(); + return typed::union_pw_multi_aff, pair>(res); +} + +template +typed::set> typed::map, pair>::bind_domain(const typed::multi_id> &tuple) const +{ + auto res = isl::map::bind_domain(tuple); + return typed::set>(res); +} + +template +typed::set> typed::map, pair>::bind_range(const typed::multi_id> &tuple) const +{ + auto res = isl::map::bind_range(tuple); + return typed::set>(res); +} + +template +typed::map, pair> typed::map, pair>::coalesce() const +{ + auto res = isl::map::coalesce(); + return typed::map, pair>(res); +} + +template +typed::map>> typed::map, pair>::curry() const +{ + auto res = isl::map::curry(); + return typed::map>>(res); +} + +template +typed::map, pair> typed::map, pair>::detect_equalities() const +{ + auto res = isl::map::detect_equalities(); + return typed::map, pair>(res); +} + +template +typed::set> typed::map, pair>::domain() const +{ + auto res = isl::map::domain(); + return typed::set>(res); +} + +template +typed::map> typed::map, pair>::domain_factor_domain() const +{ + auto res = isl::map::domain_factor_domain(); + return typed::map>(res); +} + +template +typed::map> typed::map, pair>::domain_factor_range() const +{ + auto res = isl::map::domain_factor_range(); + return typed::map>(res); +} + +template +typed::union_map, pair>, pair> typed::map, pair>::domain_map() const +{ + auto res = isl::map::domain_map(); + return typed::union_map, pair>, pair>(res); +} + +template +typed::union_pw_multi_aff, pair>, pair> typed::map, pair>::domain_map_union_pw_multi_aff() const +{ + auto res = isl::map::domain_map_union_pw_multi_aff(); + return typed::union_pw_multi_aff, pair>, pair>(res); +} + +template +template +typed::map, Domain2>, pair> typed::map, pair>::domain_product(const typed::map> &map2) const +{ + auto res = isl::map::domain_product(map2); + return typed::map, Domain2>, pair>(res); +} + +template +template +typed::union_map, Domain2>, pair> typed::map, pair>::domain_product(const typed::union_map> &umap2) const +{ + auto res = isl::map::domain_product(umap2); + return typed::union_map, Domain2>, pair>(res); +} + +template +template +typed::map, Domain2>, pair> typed::map, pair>::domain_product(const typed::basic_map> &map2) const +{ + auto res = isl::map::domain_product(map2); + return typed::map, Domain2>, pair>(res); +} + +template +typed::map, pair> typed::map, pair>::domain_reverse() const +{ + auto res = isl::map::domain_reverse(); + return typed::map, pair>(res); +} + +template +typed::map, pair> typed::map, pair>::drop_unused_params() const +{ + auto res = isl::map::drop_unused_params(); + return typed::map, pair>(res); +} + +template +bool typed::map, pair>::every_map(const std::function, pair>)> &test) const +{ + auto lambda_test = [&] (isl::map arg0) { + return test(typed::map, pair>(arg0)); + }; + return isl::map::every_map(lambda_test); +} + +template +typed::map, pair> typed::map, pair>::extract_map(const typed::space, pair> &space) const +{ + auto res = isl::map::extract_map(space); + return typed::map, pair>(res); +} + +template +typed::map> typed::map, pair>::flatten_domain() const +{ + auto res = isl::map::flatten_domain(); + return typed::map>(res); +} + +template +typed::map, Anonymous> typed::map, pair>::flatten_range() const +{ + auto res = isl::map::flatten_range(); + return typed::map, Anonymous>(res); +} + +template +void typed::map, pair>::foreach_basic_map(const std::function, pair>)> &fn) const +{ + auto lambda_fn = [&] (isl::basic_map arg0) { + return fn(typed::basic_map, pair>(arg0)); + }; + return isl::map::foreach_basic_map(lambda_fn); +} + +template +void typed::map, pair>::foreach_map(const std::function, pair>)> &fn) const +{ + auto lambda_fn = [&] (isl::map arg0) { + return fn(typed::map, pair>(arg0)); + }; + return isl::map::foreach_map(lambda_fn); +} + +template +typed::map, pair> typed::map, pair>::gist(const typed::map, pair> &context) const +{ + auto res = isl::map::gist(context); + return typed::map, pair>(res); +} + +template +typed::union_map, pair> typed::map, pair>::gist(const typed::union_map, pair> &context) const +{ + auto res = isl::map::gist(context); + return typed::union_map, pair>(res); +} + +template +typed::map, pair> typed::map, pair>::gist(const typed::basic_map, pair> &context) const +{ + auto res = isl::map::gist(context); + return typed::map, pair>(res); +} + +template +typed::map, pair> typed::map, pair>::gist_domain(const typed::set> &context) const +{ + auto res = isl::map::gist_domain(context); + return typed::map, pair>(res); +} + +template +typed::union_map, pair> typed::map, pair>::gist_domain(const typed::union_set> &uset) const +{ + auto res = isl::map::gist_domain(uset); + return typed::union_map, pair>(res); +} + +template +typed::map, pair> typed::map, pair>::gist_domain(const typed::basic_set> &context) const +{ + auto res = isl::map::gist_domain(context); + return typed::map, pair>(res); +} + +template +typed::map, pair> typed::map, pair>::gist_domain(const typed::point> &context) const +{ + auto res = isl::map::gist_domain(context); + return typed::map, pair>(res); +} + +template +typed::map, pair> typed::map, pair>::gist_params(const typed::set<> &context) const +{ + auto res = isl::map::gist_params(context); + return typed::map, pair>(res); +} + +template +typed::map, pair> typed::map, pair>::gist_params(const typed::basic_set<> &context) const +{ + auto res = isl::map::gist_params(context); + return typed::map, pair>(res); +} + +template +typed::map, pair> typed::map, pair>::gist_params(const typed::point<> &context) const +{ + auto res = isl::map::gist_params(context); + return typed::map, pair>(res); +} + +template +typed::map, pair> typed::map, pair>::intersect(const typed::map, pair> &map2) const +{ + auto res = isl::map::intersect(map2); + return typed::map, pair>(res); +} + +template +typed::union_map, pair> typed::map, pair>::intersect(const typed::union_map, pair> &umap2) const +{ + auto res = isl::map::intersect(umap2); + return typed::union_map, pair>(res); +} + +template +typed::map, pair> typed::map, pair>::intersect(const typed::basic_map, pair> &map2) const +{ + auto res = isl::map::intersect(map2); + return typed::map, pair>(res); +} + +template +typed::map, pair> typed::map, pair>::intersect_domain(const typed::set> &set) const +{ + auto res = isl::map::intersect_domain(set); + return typed::map, pair>(res); +} + +template +typed::union_map, pair> typed::map, pair>::intersect_domain(const typed::space> &space) const +{ + auto res = isl::map::intersect_domain(space); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::map, pair>::intersect_domain(const typed::union_set> &uset) const +{ + auto res = isl::map::intersect_domain(uset); + return typed::union_map, pair>(res); +} + +template +typed::map, pair> typed::map, pair>::intersect_domain(const typed::basic_set> &set) const +{ + auto res = isl::map::intersect_domain(set); + return typed::map, pair>(res); +} + +template +typed::map, pair> typed::map, pair>::intersect_domain(const typed::point> &set) const +{ + auto res = isl::map::intersect_domain(set); + return typed::map, pair>(res); +} + +template +typed::map, pair> typed::map, pair>::intersect_domain_wrapped_domain(const typed::set &domain) const +{ + auto res = isl::map::intersect_domain_wrapped_domain(domain); + return typed::map, pair>(res); +} + +template +typed::union_map, pair> typed::map, pair>::intersect_domain_wrapped_domain(const typed::union_set &domain) const +{ + auto res = isl::map::intersect_domain_wrapped_domain(domain); + return typed::union_map, pair>(res); +} + +template +typed::map, pair> typed::map, pair>::intersect_domain_wrapped_domain(const typed::basic_set &domain) const +{ + auto res = isl::map::intersect_domain_wrapped_domain(domain); + return typed::map, pair>(res); +} + +template +typed::map, pair> typed::map, pair>::intersect_domain_wrapped_domain(const typed::point &domain) const +{ + auto res = isl::map::intersect_domain_wrapped_domain(domain); + return typed::map, pair>(res); +} + +template +typed::map, pair> typed::map, pair>::intersect_params(const typed::set<> ¶ms) const +{ + auto res = isl::map::intersect_params(params); + return typed::map, pair>(res); +} + +template +typed::map, pair> typed::map, pair>::intersect_params(const typed::basic_set<> ¶ms) const +{ + auto res = isl::map::intersect_params(params); + return typed::map, pair>(res); +} + +template +typed::map, pair> typed::map, pair>::intersect_params(const typed::point<> ¶ms) const +{ + auto res = isl::map::intersect_params(params); + return typed::map, pair>(res); +} + +template +typed::map, pair> typed::map, pair>::intersect_range(const typed::set> &set) const +{ + auto res = isl::map::intersect_range(set); + return typed::map, pair>(res); +} + +template +typed::union_map, pair> typed::map, pair>::intersect_range(const typed::space> &space) const +{ + auto res = isl::map::intersect_range(space); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::map, pair>::intersect_range(const typed::union_set> &uset) const +{ + auto res = isl::map::intersect_range(uset); + return typed::union_map, pair>(res); +} + +template +typed::map, pair> typed::map, pair>::intersect_range(const typed::basic_set> &set) const +{ + auto res = isl::map::intersect_range(set); + return typed::map, pair>(res); +} + +template +typed::map, pair> typed::map, pair>::intersect_range(const typed::point> &set) const +{ + auto res = isl::map::intersect_range(set); + return typed::map, pair>(res); +} + +template +typed::map, pair> typed::map, pair>::intersect_range_wrapped_domain(const typed::set &domain) const +{ + auto res = isl::map::intersect_range_wrapped_domain(domain); + return typed::map, pair>(res); +} + +template +typed::union_map, pair> typed::map, pair>::intersect_range_wrapped_domain(const typed::union_set &domain) const +{ + auto res = isl::map::intersect_range_wrapped_domain(domain); + return typed::union_map, pair>(res); +} + +template +typed::map, pair> typed::map, pair>::intersect_range_wrapped_domain(const typed::basic_set &domain) const +{ + auto res = isl::map::intersect_range_wrapped_domain(domain); + return typed::map, pair>(res); +} + +template +typed::map, pair> typed::map, pair>::intersect_range_wrapped_domain(const typed::point &domain) const +{ + auto res = isl::map::intersect_range_wrapped_domain(domain); + return typed::map, pair>(res); +} + +template +typed::map, pair> typed::map, pair>::lexmax() const +{ + auto res = isl::map::lexmax(); + return typed::map, pair>(res); +} + +template +typed::pw_multi_aff, pair> typed::map, pair>::lexmax_pw_multi_aff() const +{ + auto res = isl::map::lexmax_pw_multi_aff(); + return typed::pw_multi_aff, pair>(res); +} + +template +typed::map, pair> typed::map, pair>::lexmin() const +{ + auto res = isl::map::lexmin(); + return typed::map, pair>(res); +} + +template +typed::pw_multi_aff, pair> typed::map, pair>::lexmin_pw_multi_aff() const +{ + auto res = isl::map::lexmin_pw_multi_aff(); + return typed::pw_multi_aff, pair>(res); +} + +template +typed::map, pair> typed::map, pair>::lower_bound(const typed::multi_pw_aff, pair> &lower) const +{ + auto res = isl::map::lower_bound(lower); + return typed::map, pair>(res); +} + +template +typed::map, pair> typed::map, pair>::lower_bound(const typed::aff, pair> &lower) const +{ + auto res = isl::map::lower_bound(lower); + return typed::map, pair>(res); +} + +template +typed::map, pair> typed::map, pair>::lower_bound(const typed::multi_aff, pair> &lower) const +{ + auto res = isl::map::lower_bound(lower); + return typed::map, pair>(res); +} + +template +typed::map, pair> typed::map, pair>::lower_bound(const typed::pw_aff, pair> &lower) const +{ + auto res = isl::map::lower_bound(lower); + return typed::map, pair>(res); +} + +template +typed::map, pair> typed::map, pair>::lower_bound(const typed::pw_multi_aff, pair> &lower) const +{ + auto res = isl::map::lower_bound(lower); + return typed::map, pair>(res); +} + +template +typed::map_list, pair> typed::map, pair>::map_list() const +{ + auto res = isl::map::map_list(); + return typed::map_list, pair>(res); +} + +template +typed::multi_pw_aff, pair> typed::map, pair>::max_multi_pw_aff() const +{ + auto res = isl::map::max_multi_pw_aff(); + return typed::multi_pw_aff, pair>(res); +} + +template +typed::multi_pw_aff, pair> typed::map, pair>::min_multi_pw_aff() const +{ + auto res = isl::map::min_multi_pw_aff(); + return typed::multi_pw_aff, pair>(res); +} + +template +typed::set<> typed::map, pair>::params() const +{ + auto res = isl::map::params(); + return typed::set<>(res); +} + +template +template +typed::map> typed::map, pair>::preimage_domain(const typed::multi_aff> &ma) const +{ + auto res = isl::map::preimage_domain(ma); + return typed::map>(res); +} + +template +template +typed::map> typed::map, pair>::preimage_domain(const typed::multi_pw_aff> &mpa) const +{ + auto res = isl::map::preimage_domain(mpa); + return typed::map>(res); +} + +template +template +typed::map> typed::map, pair>::preimage_domain(const typed::pw_multi_aff> &pma) const +{ + auto res = isl::map::preimage_domain(pma); + return typed::map>(res); +} + +template +template +typed::union_map> typed::map, pair>::preimage_domain(const typed::union_pw_multi_aff> &upma) const +{ + auto res = isl::map::preimage_domain(upma); + return typed::union_map>(res); +} + +template +template +typed::map, Arg2> typed::map, pair>::preimage_range(const typed::multi_aff> &ma) const +{ + auto res = isl::map::preimage_range(ma); + return typed::map, Arg2>(res); +} + +template +template +typed::map, Arg2> typed::map, pair>::preimage_range(const typed::pw_multi_aff> &pma) const +{ + auto res = isl::map::preimage_range(pma); + return typed::map, Arg2>(res); +} + +template +template +typed::union_map, Arg2> typed::map, pair>::preimage_range(const typed::union_pw_multi_aff> &upma) const +{ + auto res = isl::map::preimage_range(upma); + return typed::union_map, Arg2>(res); +} + +template +template +typed::map, Domain2>, pair, Arg2>> typed::map, pair>::product(const typed::map &map2) const +{ + auto res = isl::map::product(map2); + return typed::map, Domain2>, pair, Arg2>>(res); +} + +template +template +typed::union_map, Domain2>, pair, Arg2>> typed::map, pair>::product(const typed::union_map &umap2) const +{ + auto res = isl::map::product(umap2); + return typed::union_map, Domain2>, pair, Arg2>>(res); +} + +template +template +typed::map, Domain2>, pair, Arg2>> typed::map, pair>::product(const typed::basic_map &map2) const +{ + auto res = isl::map::product(map2); + return typed::map, Domain2>, pair, Arg2>>(res); +} + +template +typed::map, pair> typed::map, pair>::project_out_all_params() const +{ + auto res = isl::map::project_out_all_params(); + return typed::map, pair>(res); +} + +template +typed::map, pair> typed::map, pair>::project_out_param(const typed::id &id) const +{ + auto res = isl::map::project_out_param(id); + return typed::map, pair>(res); +} + +template +typed::map, pair> typed::map, pair>::project_out_param(const std::string &id) const +{ + auto res = isl::map::project_out_param(id); + return typed::map, pair>(res); +} + +template +typed::map, pair> typed::map, pair>::project_out_param(const typed::id_list &list) const +{ + auto res = isl::map::project_out_param(list); + return typed::map, pair>(res); +} + +template +typed::set> typed::map, pair>::range() const +{ + auto res = isl::map::range(); + return typed::set>(res); +} + +template +typed::map, Range> typed::map, pair>::range_factor_domain() const +{ + auto res = isl::map::range_factor_domain(); + return typed::map, Range>(res); +} + +template +typed::map, Range2> typed::map, pair>::range_factor_range() const +{ + auto res = isl::map::range_factor_range(); + return typed::map, Range2>(res); +} + +template +typed::fixed_box, pair> typed::map, pair>::range_lattice_tile() const +{ + auto res = isl::map::range_lattice_tile(); + return typed::fixed_box, pair>(res); +} + +template +typed::union_map, pair>, pair> typed::map, pair>::range_map() const +{ + auto res = isl::map::range_map(); + return typed::union_map, pair>, pair>(res); +} + +template +template +typed::map, pair, Arg2>> typed::map, pair>::range_product(const typed::map, Arg2> &map2) const +{ + auto res = isl::map::range_product(map2); + return typed::map, pair, Arg2>>(res); +} + +template +template +typed::union_map, pair, Arg2>> typed::map, pair>::range_product(const typed::union_map, Arg2> &umap2) const +{ + auto res = isl::map::range_product(umap2); + return typed::union_map, pair, Arg2>>(res); +} + +template +template +typed::map, pair, Arg2>> typed::map, pair>::range_product(const typed::basic_map, Arg2> &map2) const +{ + auto res = isl::map::range_product(map2); + return typed::map, pair, Arg2>>(res); +} + +template +typed::map, pair> typed::map, pair>::range_reverse() const +{ + auto res = isl::map::range_reverse(); + return typed::map, pair>(res); +} + +template +typed::fixed_box, pair> typed::map, pair>::range_simple_fixed_box_hull() const +{ + auto res = isl::map::range_simple_fixed_box_hull(); + return typed::fixed_box, pair>(res); +} + +template +typed::map, pair> typed::map, pair>::reverse() const +{ + auto res = isl::map::reverse(); + return typed::map, pair>(res); +} + +template +typed::space, pair> typed::map, pair>::space() const +{ + auto res = isl::map::space(); + return typed::space, pair>(res); +} + +template +typed::map, pair> typed::map, pair>::subtract(const typed::map, pair> &map2) const +{ + auto res = isl::map::subtract(map2); + return typed::map, pair>(res); +} + +template +typed::union_map, pair> typed::map, pair>::subtract(const typed::union_map, pair> &umap2) const +{ + auto res = isl::map::subtract(umap2); + return typed::union_map, pair>(res); +} + +template +typed::map, pair> typed::map, pair>::subtract(const typed::basic_map, pair> &map2) const +{ + auto res = isl::map::subtract(map2); + return typed::map, pair>(res); +} + +template +typed::union_map, pair> typed::map, pair>::subtract_domain(const typed::union_set> &dom) const +{ + auto res = isl::map::subtract_domain(dom); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::map, pair>::subtract_range(const typed::union_set> &dom) const +{ + auto res = isl::map::subtract_range(dom); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::map, pair>::to_union_map() const +{ + auto res = isl::map::to_union_map(); + return typed::union_map, pair>(res); +} + +template +typed::map, Range>, Range2> typed::map, pair>::uncurry() const +{ + auto res = isl::map::uncurry(); + return typed::map, Range>, Range2>(res); +} + +template +typed::map, pair> typed::map, pair>::unite(const typed::map, pair> &map2) const +{ + auto res = isl::map::unite(map2); + return typed::map, pair>(res); +} + +template +typed::union_map, pair> typed::map, pair>::unite(const typed::union_map, pair> &umap2) const +{ + auto res = isl::map::unite(umap2); + return typed::union_map, pair>(res); +} + +template +typed::map, pair> typed::map, pair>::unite(const typed::basic_map, pair> &map2) const +{ + auto res = isl::map::unite(map2); + return typed::map, pair>(res); +} + +template +typed::map, pair> typed::map, pair>::universe(const typed::space, pair> &space) +{ + auto res = isl::map::universe(space); + return typed::map, pair>(res); +} + +template +typed::map, pair> typed::map, pair>::upper_bound(const typed::multi_pw_aff, pair> &upper) const +{ + auto res = isl::map::upper_bound(upper); + return typed::map, pair>(res); +} + +template +typed::map, pair> typed::map, pair>::upper_bound(const typed::aff, pair> &upper) const +{ + auto res = isl::map::upper_bound(upper); + return typed::map, pair>(res); +} + +template +typed::map, pair> typed::map, pair>::upper_bound(const typed::multi_aff, pair> &upper) const +{ + auto res = isl::map::upper_bound(upper); + return typed::map, pair>(res); +} + +template +typed::map, pair> typed::map, pair>::upper_bound(const typed::pw_aff, pair> &upper) const +{ + auto res = isl::map::upper_bound(upper); + return typed::map, pair>(res); +} + +template +typed::map, pair> typed::map, pair>::upper_bound(const typed::pw_multi_aff, pair> &upper) const +{ + auto res = isl::map::upper_bound(upper); + return typed::map, pair>(res); +} + +template +typed::set, pair>> typed::map, pair>::wrap() const +{ + auto res = isl::map::wrap(); + return typed::set, pair>>(res); +} + +template +typed::map_list::map_list(const isl::ctx &ctx, int n) + : isl::map_list(ctx, n) +{ +} + +template +typed::map_list::map_list(const typed::map &el) + : isl::map_list(el) +{ +} + +template +typed::map_list::map_list(const isl::ctx &ctx, const std::string &str) + : isl::map_list(ctx, str) +{ +} + +template +typed::map_list typed::map_list::add(const typed::map &el) const +{ + auto res = isl::map_list::add(el); + return typed::map_list(res); +} + +template +typed::map_list typed::map_list::add(const typed::basic_map &el) const +{ + auto res = isl::map_list::add(el); + return typed::map_list(res); +} + +template +typed::map typed::map_list::at(int index) const +{ + auto res = isl::map_list::at(index); + return typed::map(res); +} + +template +typed::map_list typed::map_list::drop(unsigned int first, unsigned int n) const +{ + auto res = isl::map_list::drop(first, n); + return typed::map_list(res); +} + +template +void typed::map_list::foreach(const std::function)> &fn) const +{ + auto lambda_fn = [&] (isl::map arg0) { + return fn(typed::map(arg0)); + }; + return isl::map_list::foreach(lambda_fn); +} + +template +void typed::map_list::foreach_scc(const std::function, typed::map)> &follows, const std::function)> &fn) const +{ + auto lambda_follows = [&] (isl::map arg0, isl::map arg1) { + return follows(typed::map(arg0), typed::map(arg1)); + }; + auto lambda_fn = [&] (isl::map_list arg0) { + return fn(typed::map_list(arg0)); + }; + return isl::map_list::foreach_scc(lambda_follows, lambda_fn); +} + +template +typed::map_list typed::map_list::set_at(int index, const typed::map &el) const +{ + auto res = isl::map_list::set_at(index, el); + return typed::map_list(res); +} + +template +typed::multi_aff::multi_aff(const typed::aff &aff) + : isl::multi_aff(aff) +{ +} + +template +typed::multi_aff::multi_aff(const typed::space &space, const typed::aff_list &list) + : isl::multi_aff(space, list) +{ +} + +template +typed::multi_aff::multi_aff(const isl::ctx &ctx, const std::string &str) + : isl::multi_aff(ctx, str) +{ +} + +template +typed::multi_aff typed::multi_aff::add(const typed::multi_aff &multi2) const +{ + auto res = isl::multi_aff::add(multi2); + return typed::multi_aff(res); +} + +template +typed::multi_pw_aff typed::multi_aff::add(const typed::multi_pw_aff &multi2) const +{ + auto res = isl::multi_aff::add(multi2); + return typed::multi_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::multi_aff::add(const typed::multi_union_pw_aff &multi2) const +{ + auto res = isl::multi_aff::add(multi2); + return typed::multi_union_pw_aff(res); +} + +template +typed::pw_multi_aff typed::multi_aff::add(const typed::pw_multi_aff &pma2) const +{ + auto res = isl::multi_aff::add(pma2); + return typed::pw_multi_aff(res); +} + +template +typed::union_pw_multi_aff typed::multi_aff::add(const typed::union_pw_multi_aff &upma2) const +{ + auto res = isl::multi_aff::add(upma2); + return typed::union_pw_multi_aff(res); +} + +template +typed::multi_aff typed::multi_aff::add(const typed::aff &multi2) const +{ + auto res = isl::multi_aff::add(multi2); + return typed::multi_aff(res); +} + +template +typed::multi_aff typed::multi_aff::add_constant(const typed::multi_val &mv) const +{ + auto res = isl::multi_aff::add_constant(mv); + return typed::multi_aff(res); +} + +template +typed::multi_aff typed::multi_aff::add_constant(const typed::val &v) const +{ + auto res = isl::multi_aff::add_constant(v); + return typed::multi_aff(res); +} + +template +typed::multi_aff typed::multi_aff::add_constant(long v) const +{ + auto res = isl::multi_aff::add_constant(v); + return typed::multi_aff(res); +} + +template +template +typed::union_pw_multi_aff typed::multi_aff::apply(const typed::union_pw_multi_aff &upma2) const +{ + auto res = isl::multi_aff::apply(upma2); + return typed::union_pw_multi_aff(res); +} + +template +typed::multi_aff typed::multi_aff::as_multi_aff() const +{ + auto res = isl::multi_aff::as_multi_aff(); + return typed::multi_aff(res); +} + +template +typed::multi_union_pw_aff typed::multi_aff::as_multi_union_pw_aff() const +{ + auto res = isl::multi_aff::as_multi_union_pw_aff(); + return typed::multi_union_pw_aff(res); +} + +template +typed::pw_multi_aff typed::multi_aff::as_pw_multi_aff() const +{ + auto res = isl::multi_aff::as_pw_multi_aff(); + return typed::pw_multi_aff(res); +} + +template +typed::set typed::multi_aff::as_set() const +{ + auto res = isl::multi_aff::as_set(); + return typed::set(res); +} + +template +typed::aff typed::multi_aff::at(int pos) const +{ + auto res = isl::multi_aff::at(pos); + return typed::aff(res); +} + +template +typed::basic_set<> typed::multi_aff::bind(const typed::multi_id &tuple) const +{ + auto res = isl::multi_aff::bind(tuple); + return typed::basic_set<>(res); +} + +template +typed::pw_multi_aff typed::multi_aff::coalesce() const +{ + auto res = isl::multi_aff::coalesce(); + return typed::pw_multi_aff(res); +} + +template +typed::multi_val typed::multi_aff::constant_multi_val() const +{ + auto res = isl::multi_aff::constant_multi_val(); + return typed::multi_val(res); +} + +template +typed::set<> typed::multi_aff::domain() const +{ + auto res = isl::multi_aff::domain(); + return typed::set<>(res); +} + +template +typed::pw_multi_aff typed::multi_aff::drop_unused_params() const +{ + auto res = isl::multi_aff::drop_unused_params(); + return typed::pw_multi_aff(res); +} + +template +typed::pw_multi_aff typed::multi_aff::extract_pw_multi_aff(const typed::space &space) const +{ + auto res = isl::multi_aff::extract_pw_multi_aff(space); + return typed::pw_multi_aff(res); +} + +template +typed::multi_aff typed::multi_aff::floor() const +{ + auto res = isl::multi_aff::floor(); + return typed::multi_aff(res); +} + +template +typed::multi_aff typed::multi_aff::gist(const typed::set<> &context) const +{ + auto res = isl::multi_aff::gist(context); + return typed::multi_aff(res); +} + +template +typed::union_pw_multi_aff typed::multi_aff::gist(const typed::union_set<> &context) const +{ + auto res = isl::multi_aff::gist(context); + return typed::union_pw_multi_aff(res); +} + +template +typed::multi_aff typed::multi_aff::gist(const typed::basic_set<> &context) const +{ + auto res = isl::multi_aff::gist(context); + return typed::multi_aff(res); +} + +template +typed::multi_aff typed::multi_aff::gist(const typed::point<> &context) const +{ + auto res = isl::multi_aff::gist(context); + return typed::multi_aff(res); +} + +template +typed::multi_aff typed::multi_aff::gist_params(const typed::set<> &context) const +{ + auto res = isl::multi_aff::gist_params(context); + return typed::multi_aff(res); +} + +template +typed::multi_aff typed::multi_aff::gist_params(const typed::basic_set<> &context) const +{ + auto res = isl::multi_aff::gist_params(context); + return typed::multi_aff(res); +} + +template +typed::multi_aff typed::multi_aff::gist_params(const typed::point<> &context) const +{ + auto res = isl::multi_aff::gist_params(context); + return typed::multi_aff(res); +} + +template +typed::multi_aff typed::multi_aff::identity() const +{ + auto res = isl::multi_aff::identity(); + return typed::multi_aff(res); +} + +template +template +typed::multi_aff typed::multi_aff::insert_domain(const typed::space &domain) const +{ + auto res = isl::multi_aff::insert_domain(domain); + return typed::multi_aff(res); +} + +template +typed::pw_multi_aff typed::multi_aff::intersect_params(const typed::set<> &set) const +{ + auto res = isl::multi_aff::intersect_params(set); + return typed::pw_multi_aff(res); +} + +template +typed::aff_list typed::multi_aff::list() const +{ + auto res = isl::multi_aff::list(); + return typed::aff_list(res); +} + +template +typed::multi_pw_aff typed::multi_aff::max(const typed::multi_pw_aff &multi2) const +{ + auto res = isl::multi_aff::max(multi2); + return typed::multi_pw_aff(res); +} + +template +typed::multi_val typed::multi_aff::max_multi_val() const +{ + auto res = isl::multi_aff::max_multi_val(); + return typed::multi_val(res); +} + +template +typed::multi_pw_aff typed::multi_aff::min(const typed::multi_pw_aff &multi2) const +{ + auto res = isl::multi_aff::min(multi2); + return typed::multi_pw_aff(res); +} + +template +typed::multi_val typed::multi_aff::min_multi_val() const +{ + auto res = isl::multi_aff::min_multi_val(); + return typed::multi_val(res); +} + +template +typed::multi_aff typed::multi_aff::neg() const +{ + auto res = isl::multi_aff::neg(); + return typed::multi_aff(res); +} + +template +template +typed::multi_aff> typed::multi_aff::product(const typed::multi_aff &multi2) const +{ + auto res = isl::multi_aff::product(multi2); + return typed::multi_aff>(res); +} + +template +template +typed::multi_pw_aff> typed::multi_aff::product(const typed::multi_pw_aff &multi2) const +{ + auto res = isl::multi_aff::product(multi2); + return typed::multi_pw_aff>(res); +} + +template +template +typed::pw_multi_aff> typed::multi_aff::product(const typed::pw_multi_aff &pma2) const +{ + auto res = isl::multi_aff::product(pma2); + return typed::pw_multi_aff>(res); +} + +template +typed::multi_aff> typed::multi_aff::product(const typed::aff &multi2) const +{ + auto res = isl::multi_aff::product(multi2); + return typed::multi_aff>(res); +} + +template +typed::pw_multi_aff_list typed::multi_aff::pw_multi_aff_list() const +{ + auto res = isl::multi_aff::pw_multi_aff_list(); + return typed::pw_multi_aff_list(res); +} + +template +typed::multi_aff typed::multi_aff::scale(const typed::multi_val &mv) const +{ + auto res = isl::multi_aff::scale(mv); + return typed::multi_aff(res); +} + +template +typed::multi_aff typed::multi_aff::scale(const typed::val &v) const +{ + auto res = isl::multi_aff::scale(v); + return typed::multi_aff(res); +} + +template +typed::multi_aff typed::multi_aff::scale(long v) const +{ + auto res = isl::multi_aff::scale(v); + return typed::multi_aff(res); +} + +template +typed::multi_aff typed::multi_aff::scale_down(const typed::multi_val &mv) const +{ + auto res = isl::multi_aff::scale_down(mv); + return typed::multi_aff(res); +} + +template +typed::multi_aff typed::multi_aff::scale_down(const typed::val &v) const +{ + auto res = isl::multi_aff::scale_down(v); + return typed::multi_aff(res); +} + +template +typed::multi_aff typed::multi_aff::scale_down(long v) const +{ + auto res = isl::multi_aff::scale_down(v); + return typed::multi_aff(res); +} + +template +typed::multi_aff typed::multi_aff::set_at(int pos, const typed::aff &el) const +{ + auto res = isl::multi_aff::set_at(pos, el); + return typed::multi_aff(res); +} + +template +typed::multi_pw_aff typed::multi_aff::set_at(int pos, const typed::pw_aff &el) const +{ + auto res = isl::multi_aff::set_at(pos, el); + return typed::multi_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::multi_aff::set_at(int pos, const typed::union_pw_aff &el) const +{ + auto res = isl::multi_aff::set_at(pos, el); + return typed::multi_union_pw_aff(res); +} + +template +template +typed::multi_aff typed::multi_aff::set_range_tuple(const typed::id &id) const +{ + auto res = isl::multi_aff::set_range_tuple(id); + return typed::multi_aff(res); +} + +template +template +typed::multi_aff typed::multi_aff::set_range_tuple(const std::string &id) const +{ + auto res = isl::multi_aff::set_range_tuple(id); + return typed::multi_aff(res); +} + +template +typed::space typed::multi_aff::space() const +{ + auto res = isl::multi_aff::space(); + return typed::space(res); +} + +template +typed::multi_aff typed::multi_aff::sub(const typed::multi_aff &multi2) const +{ + auto res = isl::multi_aff::sub(multi2); + return typed::multi_aff(res); +} + +template +typed::multi_pw_aff typed::multi_aff::sub(const typed::multi_pw_aff &multi2) const +{ + auto res = isl::multi_aff::sub(multi2); + return typed::multi_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::multi_aff::sub(const typed::multi_union_pw_aff &multi2) const +{ + auto res = isl::multi_aff::sub(multi2); + return typed::multi_union_pw_aff(res); +} + +template +typed::pw_multi_aff typed::multi_aff::sub(const typed::pw_multi_aff &pma2) const +{ + auto res = isl::multi_aff::sub(pma2); + return typed::pw_multi_aff(res); +} + +template +typed::union_pw_multi_aff typed::multi_aff::sub(const typed::union_pw_multi_aff &upma2) const +{ + auto res = isl::multi_aff::sub(upma2); + return typed::union_pw_multi_aff(res); +} + +template +typed::multi_aff typed::multi_aff::sub(const typed::aff &multi2) const +{ + auto res = isl::multi_aff::sub(multi2); + return typed::multi_aff(res); +} + +template +typed::multi_pw_aff typed::multi_aff::to_multi_pw_aff() const +{ + auto res = isl::multi_aff::to_multi_pw_aff(); + return typed::multi_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::multi_aff::to_multi_union_pw_aff() const +{ + auto res = isl::multi_aff::to_multi_union_pw_aff(); + return typed::multi_union_pw_aff(res); +} + +template +typed::pw_multi_aff typed::multi_aff::to_pw_multi_aff() const +{ + auto res = isl::multi_aff::to_pw_multi_aff(); + return typed::pw_multi_aff(res); +} + +template +typed::union_pw_multi_aff typed::multi_aff::to_union_pw_multi_aff() const +{ + auto res = isl::multi_aff::to_union_pw_multi_aff(); + return typed::union_pw_multi_aff(res); +} + +template +template +typed::multi_aff typed::multi_aff::unbind_params_insert_domain(const typed::multi_id &domain) const +{ + auto res = isl::multi_aff::unbind_params_insert_domain(domain); + return typed::multi_aff(res); +} + +template +typed::multi_pw_aff typed::multi_aff::union_add(const typed::multi_pw_aff &mpa2) const +{ + auto res = isl::multi_aff::union_add(mpa2); + return typed::multi_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::multi_aff::union_add(const typed::multi_union_pw_aff &mupa2) const +{ + auto res = isl::multi_aff::union_add(mupa2); + return typed::multi_union_pw_aff(res); +} + +template +typed::pw_multi_aff typed::multi_aff::union_add(const typed::pw_multi_aff &pma2) const +{ + auto res = isl::multi_aff::union_add(pma2); + return typed::pw_multi_aff(res); +} + +template +typed::union_pw_multi_aff typed::multi_aff::union_add(const typed::union_pw_multi_aff &upma2) const +{ + auto res = isl::multi_aff::union_add(upma2); + return typed::union_pw_multi_aff(res); +} + +template +typed::multi_aff::multi_aff(const typed::aff &aff) + : isl::multi_aff(aff) +{ +} + +template +typed::multi_aff::multi_aff(const typed::space &space, const typed::aff_list &list) + : isl::multi_aff(space, list) +{ +} + +template +typed::multi_aff::multi_aff(const isl::ctx &ctx, const std::string &str) + : isl::multi_aff(ctx, str) +{ +} + +template +typed::multi_aff typed::multi_aff::add(const typed::multi_aff &multi2) const +{ + auto res = isl::multi_aff::add(multi2); + return typed::multi_aff(res); +} + +template +typed::multi_pw_aff typed::multi_aff::add(const typed::multi_pw_aff &multi2) const +{ + auto res = isl::multi_aff::add(multi2); + return typed::multi_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::multi_aff::add(const typed::multi_union_pw_aff &multi2) const +{ + auto res = isl::multi_aff::add(multi2); + return typed::multi_union_pw_aff(res); +} + +template +typed::pw_multi_aff typed::multi_aff::add(const typed::pw_multi_aff &pma2) const +{ + auto res = isl::multi_aff::add(pma2); + return typed::pw_multi_aff(res); +} + +template +typed::union_pw_multi_aff typed::multi_aff::add(const typed::union_pw_multi_aff &upma2) const +{ + auto res = isl::multi_aff::add(upma2); + return typed::union_pw_multi_aff(res); +} + +template +typed::multi_aff typed::multi_aff::add(const typed::aff &multi2) const +{ + auto res = isl::multi_aff::add(multi2); + return typed::multi_aff(res); +} + +template +typed::multi_aff typed::multi_aff::add_constant(const typed::multi_val &mv) const +{ + auto res = isl::multi_aff::add_constant(mv); + return typed::multi_aff(res); +} + +template +typed::multi_aff typed::multi_aff::add_constant(const typed::val &v) const +{ + auto res = isl::multi_aff::add_constant(v); + return typed::multi_aff(res); +} + +template +typed::multi_aff typed::multi_aff::add_constant(long v) const +{ + auto res = isl::multi_aff::add_constant(v); + return typed::multi_aff(res); +} + +template +template +typed::union_pw_multi_aff typed::multi_aff::apply(const typed::union_pw_multi_aff &upma2) const +{ + auto res = isl::multi_aff::apply(upma2); + return typed::union_pw_multi_aff(res); +} + +template +typed::map typed::multi_aff::as_map() const +{ + auto res = isl::multi_aff::as_map(); + return typed::map(res); +} + +template +typed::multi_aff typed::multi_aff::as_multi_aff() const +{ + auto res = isl::multi_aff::as_multi_aff(); + return typed::multi_aff(res); +} + +template +typed::multi_union_pw_aff typed::multi_aff::as_multi_union_pw_aff() const +{ + auto res = isl::multi_aff::as_multi_union_pw_aff(); + return typed::multi_union_pw_aff(res); +} + +template +typed::pw_multi_aff typed::multi_aff::as_pw_multi_aff() const +{ + auto res = isl::multi_aff::as_pw_multi_aff(); + return typed::pw_multi_aff(res); +} + +template +typed::union_map typed::multi_aff::as_union_map() const +{ + auto res = isl::multi_aff::as_union_map(); + return typed::union_map(res); +} + +template +typed::aff typed::multi_aff::at(int pos) const +{ + auto res = isl::multi_aff::at(pos); + return typed::aff(res); +} + +template +typed::basic_set typed::multi_aff::bind(const typed::multi_id &tuple) const +{ + auto res = isl::multi_aff::bind(tuple); + return typed::basic_set(res); +} + +template +typed::multi_aff typed::multi_aff::bind_domain(const typed::multi_id &tuple) const +{ + auto res = isl::multi_aff::bind_domain(tuple); + return typed::multi_aff(res); +} + +template +typed::pw_multi_aff typed::multi_aff::coalesce() const +{ + auto res = isl::multi_aff::coalesce(); + return typed::pw_multi_aff(res); +} + +template +typed::multi_val typed::multi_aff::constant_multi_val() const +{ + auto res = isl::multi_aff::constant_multi_val(); + return typed::multi_val(res); +} + +template +typed::set typed::multi_aff::domain() const +{ + auto res = isl::multi_aff::domain(); + return typed::set(res); +} + +template +typed::pw_multi_aff typed::multi_aff::drop_unused_params() const +{ + auto res = isl::multi_aff::drop_unused_params(); + return typed::pw_multi_aff(res); +} + +template +typed::pw_multi_aff typed::multi_aff::extract_pw_multi_aff(const typed::space &space) const +{ + auto res = isl::multi_aff::extract_pw_multi_aff(space); + return typed::pw_multi_aff(res); +} + +template +typed::multi_aff typed::multi_aff::floor() const +{ + auto res = isl::multi_aff::floor(); + return typed::multi_aff(res); +} + +template +typed::multi_aff typed::multi_aff::gist(const typed::set &context) const +{ + auto res = isl::multi_aff::gist(context); + return typed::multi_aff(res); +} + +template +typed::union_pw_multi_aff typed::multi_aff::gist(const typed::union_set &context) const +{ + auto res = isl::multi_aff::gist(context); + return typed::union_pw_multi_aff(res); +} + +template +typed::multi_aff typed::multi_aff::gist(const typed::basic_set &context) const +{ + auto res = isl::multi_aff::gist(context); + return typed::multi_aff(res); +} + +template +typed::multi_aff typed::multi_aff::gist(const typed::point &context) const +{ + auto res = isl::multi_aff::gist(context); + return typed::multi_aff(res); +} + +template +typed::multi_aff typed::multi_aff::gist_params(const typed::set<> &context) const +{ + auto res = isl::multi_aff::gist_params(context); + return typed::multi_aff(res); +} + +template +typed::multi_aff typed::multi_aff::gist_params(const typed::basic_set<> &context) const +{ + auto res = isl::multi_aff::gist_params(context); + return typed::multi_aff(res); +} + +template +typed::multi_aff typed::multi_aff::gist_params(const typed::point<> &context) const +{ + auto res = isl::multi_aff::gist_params(context); + return typed::multi_aff(res); +} + +template +typed::multi_aff typed::multi_aff::identity() const +{ + auto res = isl::multi_aff::identity(); + return typed::multi_aff(res); +} + +template +typed::pw_multi_aff typed::multi_aff::intersect_domain(const typed::set &set) const +{ + auto res = isl::multi_aff::intersect_domain(set); + return typed::pw_multi_aff(res); +} + +template +typed::union_pw_multi_aff typed::multi_aff::intersect_domain(const typed::space &space) const +{ + auto res = isl::multi_aff::intersect_domain(space); + return typed::union_pw_multi_aff(res); +} + +template +typed::union_pw_multi_aff typed::multi_aff::intersect_domain(const typed::union_set &uset) const +{ + auto res = isl::multi_aff::intersect_domain(uset); + return typed::union_pw_multi_aff(res); +} + +template +typed::pw_multi_aff typed::multi_aff::intersect_params(const typed::set<> &set) const +{ + auto res = isl::multi_aff::intersect_params(set); + return typed::pw_multi_aff(res); +} + +template +typed::aff_list typed::multi_aff::list() const +{ + auto res = isl::multi_aff::list(); + return typed::aff_list(res); +} + +template +typed::multi_pw_aff typed::multi_aff::max(const typed::multi_pw_aff &multi2) const +{ + auto res = isl::multi_aff::max(multi2); + return typed::multi_pw_aff(res); +} + +template +typed::multi_val typed::multi_aff::max_multi_val() const +{ + auto res = isl::multi_aff::max_multi_val(); + return typed::multi_val(res); +} + +template +typed::multi_pw_aff typed::multi_aff::min(const typed::multi_pw_aff &multi2) const +{ + auto res = isl::multi_aff::min(multi2); + return typed::multi_pw_aff(res); +} + +template +typed::multi_val typed::multi_aff::min_multi_val() const +{ + auto res = isl::multi_aff::min_multi_val(); + return typed::multi_val(res); +} + +template +typed::multi_aff typed::multi_aff::neg() const +{ + auto res = isl::multi_aff::neg(); + return typed::multi_aff(res); +} + +template +template +typed::multi_aff, pair> typed::multi_aff::product(const typed::multi_aff &multi2) const +{ + auto res = isl::multi_aff::product(multi2); + return typed::multi_aff, pair>(res); +} + +template +template +typed::multi_pw_aff, pair> typed::multi_aff::product(const typed::multi_pw_aff &multi2) const +{ + auto res = isl::multi_aff::product(multi2); + return typed::multi_pw_aff, pair>(res); +} + +template +template +typed::pw_multi_aff, pair> typed::multi_aff::product(const typed::pw_multi_aff &pma2) const +{ + auto res = isl::multi_aff::product(pma2); + return typed::pw_multi_aff, pair>(res); +} + +template +template +typed::multi_aff, pair> typed::multi_aff::product(const typed::aff &multi2) const +{ + auto res = isl::multi_aff::product(multi2); + return typed::multi_aff, pair>(res); +} + +template +template +typed::multi_aff typed::multi_aff::pullback(const typed::multi_aff &ma2) const +{ + auto res = isl::multi_aff::pullback(ma2); + return typed::multi_aff(res); +} + +template +typed::multi_aff typed::multi_aff::pullback(const typed::multi_aff &ma2) const +{ + auto res = isl::multi_aff::pullback(ma2); + return typed::multi_aff(res); +} + +template +template +typed::multi_pw_aff typed::multi_aff::pullback(const typed::multi_pw_aff &mpa2) const +{ + auto res = isl::multi_aff::pullback(mpa2); + return typed::multi_pw_aff(res); +} + +template +typed::multi_pw_aff typed::multi_aff::pullback(const typed::multi_pw_aff &mpa2) const +{ + auto res = isl::multi_aff::pullback(mpa2); + return typed::multi_pw_aff(res); +} + +template +template +typed::pw_multi_aff typed::multi_aff::pullback(const typed::pw_multi_aff &pma2) const +{ + auto res = isl::multi_aff::pullback(pma2); + return typed::pw_multi_aff(res); +} + +template +typed::pw_multi_aff typed::multi_aff::pullback(const typed::pw_multi_aff &pma2) const +{ + auto res = isl::multi_aff::pullback(pma2); + return typed::pw_multi_aff(res); +} + +template +template +typed::union_pw_multi_aff typed::multi_aff::pullback(const typed::union_pw_multi_aff &upma2) const +{ + auto res = isl::multi_aff::pullback(upma2); + return typed::union_pw_multi_aff(res); +} + +template +typed::union_pw_multi_aff typed::multi_aff::pullback(const typed::union_pw_multi_aff &upma2) const +{ + auto res = isl::multi_aff::pullback(upma2); + return typed::union_pw_multi_aff(res); +} + +template +template +typed::multi_aff typed::multi_aff::pullback(const typed::aff &ma2) const +{ + auto res = isl::multi_aff::pullback(ma2); + return typed::multi_aff(res); +} + +template +typed::multi_aff typed::multi_aff::pullback(const typed::aff &ma2) const +{ + auto res = isl::multi_aff::pullback(ma2); + return typed::multi_aff(res); +} + +template +typed::pw_multi_aff_list typed::multi_aff::pw_multi_aff_list() const +{ + auto res = isl::multi_aff::pw_multi_aff_list(); + return typed::pw_multi_aff_list(res); +} + +template +template +typed::multi_aff> typed::multi_aff::range_product(const typed::multi_aff &multi2) const +{ + auto res = isl::multi_aff::range_product(multi2); + return typed::multi_aff>(res); +} + +template +template +typed::multi_pw_aff> typed::multi_aff::range_product(const typed::multi_pw_aff &multi2) const +{ + auto res = isl::multi_aff::range_product(multi2); + return typed::multi_pw_aff>(res); +} + +template +template +typed::multi_union_pw_aff> typed::multi_aff::range_product(const typed::multi_union_pw_aff &multi2) const +{ + auto res = isl::multi_aff::range_product(multi2); + return typed::multi_union_pw_aff>(res); +} + +template +template +typed::pw_multi_aff> typed::multi_aff::range_product(const typed::pw_multi_aff &pma2) const +{ + auto res = isl::multi_aff::range_product(pma2); + return typed::pw_multi_aff>(res); +} + +template +template +typed::union_pw_multi_aff> typed::multi_aff::range_product(const typed::union_pw_multi_aff &upma2) const +{ + auto res = isl::multi_aff::range_product(upma2); + return typed::union_pw_multi_aff>(res); +} + +template +typed::multi_aff> typed::multi_aff::range_product(const typed::aff &multi2) const +{ + auto res = isl::multi_aff::range_product(multi2); + return typed::multi_aff>(res); +} + +template +typed::multi_aff typed::multi_aff::scale(const typed::multi_val &mv) const +{ + auto res = isl::multi_aff::scale(mv); + return typed::multi_aff(res); +} + +template +typed::multi_aff typed::multi_aff::scale(const typed::val &v) const +{ + auto res = isl::multi_aff::scale(v); + return typed::multi_aff(res); +} + +template +typed::multi_aff typed::multi_aff::scale(long v) const +{ + auto res = isl::multi_aff::scale(v); + return typed::multi_aff(res); +} + +template +typed::multi_aff typed::multi_aff::scale_down(const typed::multi_val &mv) const +{ + auto res = isl::multi_aff::scale_down(mv); + return typed::multi_aff(res); +} + +template +typed::multi_aff typed::multi_aff::scale_down(const typed::val &v) const +{ + auto res = isl::multi_aff::scale_down(v); + return typed::multi_aff(res); +} + +template +typed::multi_aff typed::multi_aff::scale_down(long v) const +{ + auto res = isl::multi_aff::scale_down(v); + return typed::multi_aff(res); +} + +template +typed::multi_aff typed::multi_aff::set_at(int pos, const typed::aff &el) const +{ + auto res = isl::multi_aff::set_at(pos, el); + return typed::multi_aff(res); +} + +template +typed::multi_pw_aff typed::multi_aff::set_at(int pos, const typed::pw_aff &el) const +{ + auto res = isl::multi_aff::set_at(pos, el); + return typed::multi_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::multi_aff::set_at(int pos, const typed::union_pw_aff &el) const +{ + auto res = isl::multi_aff::set_at(pos, el); + return typed::multi_union_pw_aff(res); +} + +template +template +typed::multi_aff typed::multi_aff::set_range_tuple(const typed::id &id) const +{ + auto res = isl::multi_aff::set_range_tuple(id); + return typed::multi_aff(res); +} + +template +template +typed::multi_aff typed::multi_aff::set_range_tuple(const std::string &id) const +{ + auto res = isl::multi_aff::set_range_tuple(id); + return typed::multi_aff(res); +} + +template +typed::space typed::multi_aff::space() const +{ + auto res = isl::multi_aff::space(); + return typed::space(res); +} + +template +typed::multi_aff typed::multi_aff::sub(const typed::multi_aff &multi2) const +{ + auto res = isl::multi_aff::sub(multi2); + return typed::multi_aff(res); +} + +template +typed::multi_pw_aff typed::multi_aff::sub(const typed::multi_pw_aff &multi2) const +{ + auto res = isl::multi_aff::sub(multi2); + return typed::multi_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::multi_aff::sub(const typed::multi_union_pw_aff &multi2) const +{ + auto res = isl::multi_aff::sub(multi2); + return typed::multi_union_pw_aff(res); +} + +template +typed::pw_multi_aff typed::multi_aff::sub(const typed::pw_multi_aff &pma2) const +{ + auto res = isl::multi_aff::sub(pma2); + return typed::pw_multi_aff(res); +} + +template +typed::union_pw_multi_aff typed::multi_aff::sub(const typed::union_pw_multi_aff &upma2) const +{ + auto res = isl::multi_aff::sub(upma2); + return typed::union_pw_multi_aff(res); +} + +template +typed::multi_aff typed::multi_aff::sub(const typed::aff &multi2) const +{ + auto res = isl::multi_aff::sub(multi2); + return typed::multi_aff(res); +} + +template +typed::pw_multi_aff typed::multi_aff::subtract_domain(const typed::set &set) const +{ + auto res = isl::multi_aff::subtract_domain(set); + return typed::pw_multi_aff(res); +} + +template +typed::union_pw_multi_aff typed::multi_aff::subtract_domain(const typed::space &space) const +{ + auto res = isl::multi_aff::subtract_domain(space); + return typed::union_pw_multi_aff(res); +} + +template +typed::union_pw_multi_aff typed::multi_aff::subtract_domain(const typed::union_set &uset) const +{ + auto res = isl::multi_aff::subtract_domain(uset); + return typed::union_pw_multi_aff(res); +} + +template +typed::multi_pw_aff typed::multi_aff::to_multi_pw_aff() const +{ + auto res = isl::multi_aff::to_multi_pw_aff(); + return typed::multi_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::multi_aff::to_multi_union_pw_aff() const +{ + auto res = isl::multi_aff::to_multi_union_pw_aff(); + return typed::multi_union_pw_aff(res); +} + +template +typed::pw_multi_aff typed::multi_aff::to_pw_multi_aff() const +{ + auto res = isl::multi_aff::to_pw_multi_aff(); + return typed::pw_multi_aff(res); +} + +template +typed::union_pw_multi_aff typed::multi_aff::to_union_pw_multi_aff() const +{ + auto res = isl::multi_aff::to_union_pw_multi_aff(); + return typed::union_pw_multi_aff(res); +} + +template +typed::multi_pw_aff typed::multi_aff::union_add(const typed::multi_pw_aff &mpa2) const +{ + auto res = isl::multi_aff::union_add(mpa2); + return typed::multi_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::multi_aff::union_add(const typed::multi_union_pw_aff &mupa2) const +{ + auto res = isl::multi_aff::union_add(mupa2); + return typed::multi_union_pw_aff(res); +} + +template +typed::pw_multi_aff typed::multi_aff::union_add(const typed::pw_multi_aff &pma2) const +{ + auto res = isl::multi_aff::union_add(pma2); + return typed::pw_multi_aff(res); +} + +template +typed::union_pw_multi_aff typed::multi_aff::union_add(const typed::union_pw_multi_aff &upma2) const +{ + auto res = isl::multi_aff::union_add(upma2); + return typed::union_pw_multi_aff(res); +} + +template +typed::multi_aff, Range>::multi_aff(const typed::aff, Range> &aff) + : isl::multi_aff(aff) +{ +} + +template +typed::multi_aff, Range>::multi_aff(const typed::space, Range> &space, const typed::aff_list, Anonymous> &list) + : isl::multi_aff(space, list) +{ +} + +template +typed::multi_aff, Range>::multi_aff(const isl::ctx &ctx, const std::string &str) + : isl::multi_aff(ctx, str) +{ +} + +template +typed::multi_aff, Range> typed::multi_aff, Range>::add(const typed::multi_aff, Range> &multi2) const +{ + auto res = isl::multi_aff::add(multi2); + return typed::multi_aff, Range>(res); +} + +template +typed::multi_pw_aff, Range> typed::multi_aff, Range>::add(const typed::multi_pw_aff, Range> &multi2) const +{ + auto res = isl::multi_aff::add(multi2); + return typed::multi_pw_aff, Range>(res); +} + +template +typed::multi_union_pw_aff, Range> typed::multi_aff, Range>::add(const typed::multi_union_pw_aff, Range> &multi2) const +{ + auto res = isl::multi_aff::add(multi2); + return typed::multi_union_pw_aff, Range>(res); +} + +template +typed::pw_multi_aff, Range> typed::multi_aff, Range>::add(const typed::pw_multi_aff, Range> &pma2) const +{ + auto res = isl::multi_aff::add(pma2); + return typed::pw_multi_aff, Range>(res); +} + +template +typed::union_pw_multi_aff, Range> typed::multi_aff, Range>::add(const typed::union_pw_multi_aff, Range> &upma2) const +{ + auto res = isl::multi_aff::add(upma2); + return typed::union_pw_multi_aff, Range>(res); +} + +template +typed::multi_aff, Range> typed::multi_aff, Range>::add(const typed::aff, Range> &multi2) const +{ + auto res = isl::multi_aff::add(multi2); + return typed::multi_aff, Range>(res); +} + +template +typed::multi_aff, Range> typed::multi_aff, Range>::add_constant(const typed::multi_val &mv) const +{ + auto res = isl::multi_aff::add_constant(mv); + return typed::multi_aff, Range>(res); +} + +template +typed::multi_aff, Range> typed::multi_aff, Range>::add_constant(const typed::val &v) const +{ + auto res = isl::multi_aff::add_constant(v); + return typed::multi_aff, Range>(res); +} + +template +typed::multi_aff, Range> typed::multi_aff, Range>::add_constant(long v) const +{ + auto res = isl::multi_aff::add_constant(v); + return typed::multi_aff, Range>(res); +} + +template +template +typed::union_pw_multi_aff, Arg2> typed::multi_aff, Range>::apply(const typed::union_pw_multi_aff &upma2) const +{ + auto res = isl::multi_aff::apply(upma2); + return typed::union_pw_multi_aff, Arg2>(res); +} + +template +typed::map, Range> typed::multi_aff, Range>::as_map() const +{ + auto res = isl::multi_aff::as_map(); + return typed::map, Range>(res); +} + +template +typed::multi_aff, Range> typed::multi_aff, Range>::as_multi_aff() const +{ + auto res = isl::multi_aff::as_multi_aff(); + return typed::multi_aff, Range>(res); +} + +template +typed::multi_union_pw_aff, Range> typed::multi_aff, Range>::as_multi_union_pw_aff() const +{ + auto res = isl::multi_aff::as_multi_union_pw_aff(); + return typed::multi_union_pw_aff, Range>(res); +} + +template +typed::pw_multi_aff, Range> typed::multi_aff, Range>::as_pw_multi_aff() const +{ + auto res = isl::multi_aff::as_pw_multi_aff(); + return typed::pw_multi_aff, Range>(res); +} + +template +typed::union_map, Range> typed::multi_aff, Range>::as_union_map() const +{ + auto res = isl::multi_aff::as_union_map(); + return typed::union_map, Range>(res); +} + +template +typed::aff, Anonymous> typed::multi_aff, Range>::at(int pos) const +{ + auto res = isl::multi_aff::at(pos); + return typed::aff, Anonymous>(res); +} + +template +typed::basic_set> typed::multi_aff, Range>::bind(const typed::multi_id &tuple) const +{ + auto res = isl::multi_aff::bind(tuple); + return typed::basic_set>(res); +} + +template +typed::multi_aff typed::multi_aff, Range>::bind_domain(const typed::multi_id> &tuple) const +{ + auto res = isl::multi_aff::bind_domain(tuple); + return typed::multi_aff(res); +} + +template +typed::multi_aff typed::multi_aff, Range>::bind_domain_wrapped_domain(const typed::multi_id &tuple) const +{ + auto res = isl::multi_aff::bind_domain_wrapped_domain(tuple); + return typed::multi_aff(res); +} + +template +typed::pw_multi_aff, Range> typed::multi_aff, Range>::coalesce() const +{ + auto res = isl::multi_aff::coalesce(); + return typed::pw_multi_aff, Range>(res); +} + +template +typed::multi_val typed::multi_aff, Range>::constant_multi_val() const +{ + auto res = isl::multi_aff::constant_multi_val(); + return typed::multi_val(res); +} + +template +typed::set> typed::multi_aff, Range>::domain() const +{ + auto res = isl::multi_aff::domain(); + return typed::set>(res); +} + +template +typed::multi_aff, Range> typed::multi_aff, Range>::domain_reverse() const +{ + auto res = isl::multi_aff::domain_reverse(); + return typed::multi_aff, Range>(res); +} + +template +typed::pw_multi_aff, Range> typed::multi_aff, Range>::drop_unused_params() const +{ + auto res = isl::multi_aff::drop_unused_params(); + return typed::pw_multi_aff, Range>(res); +} + +template +typed::pw_multi_aff, Range> typed::multi_aff, Range>::extract_pw_multi_aff(const typed::space, Range> &space) const +{ + auto res = isl::multi_aff::extract_pw_multi_aff(space); + return typed::pw_multi_aff, Range>(res); +} + +template +typed::multi_aff, Range> typed::multi_aff, Range>::floor() const +{ + auto res = isl::multi_aff::floor(); + return typed::multi_aff, Range>(res); +} + +template +typed::multi_aff, Range> typed::multi_aff, Range>::gist(const typed::set> &context) const +{ + auto res = isl::multi_aff::gist(context); + return typed::multi_aff, Range>(res); +} + +template +typed::union_pw_multi_aff, Range> typed::multi_aff, Range>::gist(const typed::union_set> &context) const +{ + auto res = isl::multi_aff::gist(context); + return typed::union_pw_multi_aff, Range>(res); +} + +template +typed::multi_aff, Range> typed::multi_aff, Range>::gist(const typed::basic_set> &context) const +{ + auto res = isl::multi_aff::gist(context); + return typed::multi_aff, Range>(res); +} + +template +typed::multi_aff, Range> typed::multi_aff, Range>::gist(const typed::point> &context) const +{ + auto res = isl::multi_aff::gist(context); + return typed::multi_aff, Range>(res); +} + +template +typed::multi_aff, Range> typed::multi_aff, Range>::gist_params(const typed::set<> &context) const +{ + auto res = isl::multi_aff::gist_params(context); + return typed::multi_aff, Range>(res); +} + +template +typed::multi_aff, Range> typed::multi_aff, Range>::gist_params(const typed::basic_set<> &context) const +{ + auto res = isl::multi_aff::gist_params(context); + return typed::multi_aff, Range>(res); +} + +template +typed::multi_aff, Range> typed::multi_aff, Range>::gist_params(const typed::point<> &context) const +{ + auto res = isl::multi_aff::gist_params(context); + return typed::multi_aff, Range>(res); +} + +template +typed::multi_aff, Range> typed::multi_aff, Range>::identity() const +{ + auto res = isl::multi_aff::identity(); + return typed::multi_aff, Range>(res); +} + +template +typed::pw_multi_aff, Range> typed::multi_aff, Range>::intersect_domain(const typed::set> &set) const +{ + auto res = isl::multi_aff::intersect_domain(set); + return typed::pw_multi_aff, Range>(res); +} + +template +typed::union_pw_multi_aff, Range> typed::multi_aff, Range>::intersect_domain(const typed::space> &space) const +{ + auto res = isl::multi_aff::intersect_domain(space); + return typed::union_pw_multi_aff, Range>(res); +} + +template +typed::union_pw_multi_aff, Range> typed::multi_aff, Range>::intersect_domain(const typed::union_set> &uset) const +{ + auto res = isl::multi_aff::intersect_domain(uset); + return typed::union_pw_multi_aff, Range>(res); +} + +template +typed::union_pw_multi_aff, Range> typed::multi_aff, Range>::intersect_domain_wrapped_domain(const typed::union_set &uset) const +{ + auto res = isl::multi_aff::intersect_domain_wrapped_domain(uset); + return typed::union_pw_multi_aff, Range>(res); +} + +template +typed::pw_multi_aff, Range> typed::multi_aff, Range>::intersect_params(const typed::set<> &set) const +{ + auto res = isl::multi_aff::intersect_params(set); + return typed::pw_multi_aff, Range>(res); +} + +template +typed::aff_list, Anonymous> typed::multi_aff, Range>::list() const +{ + auto res = isl::multi_aff::list(); + return typed::aff_list, Anonymous>(res); +} + +template +typed::multi_pw_aff, Range> typed::multi_aff, Range>::max(const typed::multi_pw_aff, Range> &multi2) const +{ + auto res = isl::multi_aff::max(multi2); + return typed::multi_pw_aff, Range>(res); +} + +template +typed::multi_val typed::multi_aff, Range>::max_multi_val() const +{ + auto res = isl::multi_aff::max_multi_val(); + return typed::multi_val(res); +} + +template +typed::multi_pw_aff, Range> typed::multi_aff, Range>::min(const typed::multi_pw_aff, Range> &multi2) const +{ + auto res = isl::multi_aff::min(multi2); + return typed::multi_pw_aff, Range>(res); +} + +template +typed::multi_val typed::multi_aff, Range>::min_multi_val() const +{ + auto res = isl::multi_aff::min_multi_val(); + return typed::multi_val(res); +} + +template +typed::multi_aff, Range> typed::multi_aff, Range>::neg() const +{ + auto res = isl::multi_aff::neg(); + return typed::multi_aff, Range>(res); +} + +template +template +typed::pw_multi_aff, Range> typed::multi_aff, Range>::preimage_domain_wrapped_domain(const typed::pw_multi_aff &pma2) const +{ + auto res = isl::multi_aff::preimage_domain_wrapped_domain(pma2); + return typed::pw_multi_aff, Range>(res); +} + +template +template +typed::union_pw_multi_aff, Range> typed::multi_aff, Range>::preimage_domain_wrapped_domain(const typed::union_pw_multi_aff &upma2) const +{ + auto res = isl::multi_aff::preimage_domain_wrapped_domain(upma2); + return typed::union_pw_multi_aff, Range>(res); +} + +template +template +typed::multi_aff, Arg2>, pair> typed::multi_aff, Range>::product(const typed::multi_aff &multi2) const +{ + auto res = isl::multi_aff::product(multi2); + return typed::multi_aff, Arg2>, pair>(res); +} + +template +template +typed::multi_pw_aff, Arg2>, pair> typed::multi_aff, Range>::product(const typed::multi_pw_aff &multi2) const +{ + auto res = isl::multi_aff::product(multi2); + return typed::multi_pw_aff, Arg2>, pair>(res); +} + +template +template +typed::pw_multi_aff, Arg2>, pair> typed::multi_aff, Range>::product(const typed::pw_multi_aff &pma2) const +{ + auto res = isl::multi_aff::product(pma2); + return typed::pw_multi_aff, Arg2>, pair>(res); +} + +template +template +typed::multi_aff, Arg2>, pair> typed::multi_aff, Range>::product(const typed::aff &multi2) const +{ + auto res = isl::multi_aff::product(multi2); + return typed::multi_aff, Arg2>, pair>(res); +} + +template +template +typed::multi_aff typed::multi_aff, Range>::pullback(const typed::multi_aff> &ma2) const +{ + auto res = isl::multi_aff::pullback(ma2); + return typed::multi_aff(res); +} + +template +typed::multi_aff typed::multi_aff, Range>::pullback(const typed::multi_aff> &ma2) const +{ + auto res = isl::multi_aff::pullback(ma2); + return typed::multi_aff(res); +} + +template +template +typed::multi_pw_aff typed::multi_aff, Range>::pullback(const typed::multi_pw_aff> &mpa2) const +{ + auto res = isl::multi_aff::pullback(mpa2); + return typed::multi_pw_aff(res); +} + +template +typed::multi_pw_aff typed::multi_aff, Range>::pullback(const typed::multi_pw_aff> &mpa2) const +{ + auto res = isl::multi_aff::pullback(mpa2); + return typed::multi_pw_aff(res); +} + +template +template +typed::pw_multi_aff typed::multi_aff, Range>::pullback(const typed::pw_multi_aff> &pma2) const +{ + auto res = isl::multi_aff::pullback(pma2); + return typed::pw_multi_aff(res); +} + +template +typed::pw_multi_aff typed::multi_aff, Range>::pullback(const typed::pw_multi_aff> &pma2) const +{ + auto res = isl::multi_aff::pullback(pma2); + return typed::pw_multi_aff(res); +} + +template +template +typed::union_pw_multi_aff typed::multi_aff, Range>::pullback(const typed::union_pw_multi_aff> &upma2) const +{ + auto res = isl::multi_aff::pullback(upma2); + return typed::union_pw_multi_aff(res); +} + +template +typed::union_pw_multi_aff typed::multi_aff, Range>::pullback(const typed::union_pw_multi_aff> &upma2) const +{ + auto res = isl::multi_aff::pullback(upma2); + return typed::union_pw_multi_aff(res); +} + +template +template +typed::multi_aff typed::multi_aff, Range>::pullback(const typed::aff> &ma2) const +{ + auto res = isl::multi_aff::pullback(ma2); + return typed::multi_aff(res); +} + +template +typed::multi_aff typed::multi_aff, Range>::pullback(const typed::aff> &ma2) const +{ + auto res = isl::multi_aff::pullback(ma2); + return typed::multi_aff(res); +} + +template +typed::pw_multi_aff_list, Range> typed::multi_aff, Range>::pw_multi_aff_list() const +{ + auto res = isl::multi_aff::pw_multi_aff_list(); + return typed::pw_multi_aff_list, Range>(res); +} + +template +template +typed::multi_aff, pair> typed::multi_aff, Range>::range_product(const typed::multi_aff, Arg2> &multi2) const +{ + auto res = isl::multi_aff::range_product(multi2); + return typed::multi_aff, pair>(res); +} + +template +template +typed::multi_pw_aff, pair> typed::multi_aff, Range>::range_product(const typed::multi_pw_aff, Arg2> &multi2) const +{ + auto res = isl::multi_aff::range_product(multi2); + return typed::multi_pw_aff, pair>(res); +} + +template +template +typed::multi_union_pw_aff, pair> typed::multi_aff, Range>::range_product(const typed::multi_union_pw_aff, Arg2> &multi2) const +{ + auto res = isl::multi_aff::range_product(multi2); + return typed::multi_union_pw_aff, pair>(res); +} + +template +template +typed::pw_multi_aff, pair> typed::multi_aff, Range>::range_product(const typed::pw_multi_aff, Arg2> &pma2) const +{ + auto res = isl::multi_aff::range_product(pma2); + return typed::pw_multi_aff, pair>(res); +} + +template +template +typed::union_pw_multi_aff, pair> typed::multi_aff, Range>::range_product(const typed::union_pw_multi_aff, Arg2> &upma2) const +{ + auto res = isl::multi_aff::range_product(upma2); + return typed::union_pw_multi_aff, pair>(res); +} + +template +typed::multi_aff, pair> typed::multi_aff, Range>::range_product(const typed::aff, Anonymous> &multi2) const +{ + auto res = isl::multi_aff::range_product(multi2); + return typed::multi_aff, pair>(res); +} + +template +typed::multi_aff, Range> typed::multi_aff, Range>::scale(const typed::multi_val &mv) const +{ + auto res = isl::multi_aff::scale(mv); + return typed::multi_aff, Range>(res); +} + +template +typed::multi_aff, Range> typed::multi_aff, Range>::scale(const typed::val &v) const +{ + auto res = isl::multi_aff::scale(v); + return typed::multi_aff, Range>(res); +} + +template +typed::multi_aff, Range> typed::multi_aff, Range>::scale(long v) const +{ + auto res = isl::multi_aff::scale(v); + return typed::multi_aff, Range>(res); +} + +template +typed::multi_aff, Range> typed::multi_aff, Range>::scale_down(const typed::multi_val &mv) const +{ + auto res = isl::multi_aff::scale_down(mv); + return typed::multi_aff, Range>(res); +} + +template +typed::multi_aff, Range> typed::multi_aff, Range>::scale_down(const typed::val &v) const +{ + auto res = isl::multi_aff::scale_down(v); + return typed::multi_aff, Range>(res); +} + +template +typed::multi_aff, Range> typed::multi_aff, Range>::scale_down(long v) const +{ + auto res = isl::multi_aff::scale_down(v); + return typed::multi_aff, Range>(res); +} + +template +typed::multi_aff, Range> typed::multi_aff, Range>::set_at(int pos, const typed::aff, Anonymous> &el) const +{ + auto res = isl::multi_aff::set_at(pos, el); + return typed::multi_aff, Range>(res); +} + +template +typed::multi_pw_aff, Range> typed::multi_aff, Range>::set_at(int pos, const typed::pw_aff, Anonymous> &el) const +{ + auto res = isl::multi_aff::set_at(pos, el); + return typed::multi_pw_aff, Range>(res); +} + +template +typed::multi_union_pw_aff, Range> typed::multi_aff, Range>::set_at(int pos, const typed::union_pw_aff, Anonymous> &el) const +{ + auto res = isl::multi_aff::set_at(pos, el); + return typed::multi_union_pw_aff, Range>(res); +} + +template +template +typed::multi_aff, Arg1> typed::multi_aff, Range>::set_range_tuple(const typed::id &id) const +{ + auto res = isl::multi_aff::set_range_tuple(id); + return typed::multi_aff, Arg1>(res); +} + +template +template +typed::multi_aff, Arg1> typed::multi_aff, Range>::set_range_tuple(const std::string &id) const +{ + auto res = isl::multi_aff::set_range_tuple(id); + return typed::multi_aff, Arg1>(res); +} + +template +typed::space, Range> typed::multi_aff, Range>::space() const +{ + auto res = isl::multi_aff::space(); + return typed::space, Range>(res); +} + +template +typed::multi_aff, Range> typed::multi_aff, Range>::sub(const typed::multi_aff, Range> &multi2) const +{ + auto res = isl::multi_aff::sub(multi2); + return typed::multi_aff, Range>(res); +} + +template +typed::multi_pw_aff, Range> typed::multi_aff, Range>::sub(const typed::multi_pw_aff, Range> &multi2) const +{ + auto res = isl::multi_aff::sub(multi2); + return typed::multi_pw_aff, Range>(res); +} + +template +typed::multi_union_pw_aff, Range> typed::multi_aff, Range>::sub(const typed::multi_union_pw_aff, Range> &multi2) const +{ + auto res = isl::multi_aff::sub(multi2); + return typed::multi_union_pw_aff, Range>(res); +} + +template +typed::pw_multi_aff, Range> typed::multi_aff, Range>::sub(const typed::pw_multi_aff, Range> &pma2) const +{ + auto res = isl::multi_aff::sub(pma2); + return typed::pw_multi_aff, Range>(res); +} + +template +typed::union_pw_multi_aff, Range> typed::multi_aff, Range>::sub(const typed::union_pw_multi_aff, Range> &upma2) const +{ + auto res = isl::multi_aff::sub(upma2); + return typed::union_pw_multi_aff, Range>(res); +} + +template +typed::multi_aff, Range> typed::multi_aff, Range>::sub(const typed::aff, Range> &multi2) const +{ + auto res = isl::multi_aff::sub(multi2); + return typed::multi_aff, Range>(res); +} + +template +typed::pw_multi_aff, Range> typed::multi_aff, Range>::subtract_domain(const typed::set> &set) const +{ + auto res = isl::multi_aff::subtract_domain(set); + return typed::pw_multi_aff, Range>(res); +} + +template +typed::union_pw_multi_aff, Range> typed::multi_aff, Range>::subtract_domain(const typed::space> &space) const +{ + auto res = isl::multi_aff::subtract_domain(space); + return typed::union_pw_multi_aff, Range>(res); +} + +template +typed::union_pw_multi_aff, Range> typed::multi_aff, Range>::subtract_domain(const typed::union_set> &uset) const +{ + auto res = isl::multi_aff::subtract_domain(uset); + return typed::union_pw_multi_aff, Range>(res); +} + +template +typed::multi_pw_aff, Range> typed::multi_aff, Range>::to_multi_pw_aff() const +{ + auto res = isl::multi_aff::to_multi_pw_aff(); + return typed::multi_pw_aff, Range>(res); +} + +template +typed::multi_union_pw_aff, Range> typed::multi_aff, Range>::to_multi_union_pw_aff() const +{ + auto res = isl::multi_aff::to_multi_union_pw_aff(); + return typed::multi_union_pw_aff, Range>(res); +} + +template +typed::pw_multi_aff, Range> typed::multi_aff, Range>::to_pw_multi_aff() const +{ + auto res = isl::multi_aff::to_pw_multi_aff(); + return typed::pw_multi_aff, Range>(res); +} + +template +typed::union_pw_multi_aff, Range> typed::multi_aff, Range>::to_union_pw_multi_aff() const +{ + auto res = isl::multi_aff::to_union_pw_multi_aff(); + return typed::union_pw_multi_aff, Range>(res); +} + +template +typed::multi_pw_aff, Range> typed::multi_aff, Range>::union_add(const typed::multi_pw_aff, Range> &mpa2) const +{ + auto res = isl::multi_aff::union_add(mpa2); + return typed::multi_pw_aff, Range>(res); +} + +template +typed::multi_union_pw_aff, Range> typed::multi_aff, Range>::union_add(const typed::multi_union_pw_aff, Range> &mupa2) const +{ + auto res = isl::multi_aff::union_add(mupa2); + return typed::multi_union_pw_aff, Range>(res); +} + +template +typed::pw_multi_aff, Range> typed::multi_aff, Range>::union_add(const typed::pw_multi_aff, Range> &pma2) const +{ + auto res = isl::multi_aff::union_add(pma2); + return typed::pw_multi_aff, Range>(res); +} + +template +typed::union_pw_multi_aff, Range> typed::multi_aff, Range>::union_add(const typed::union_pw_multi_aff, Range> &upma2) const +{ + auto res = isl::multi_aff::union_add(upma2); + return typed::union_pw_multi_aff, Range>(res); +} + +template +typed::multi_aff>::multi_aff(const typed::aff> &aff) + : isl::multi_aff(aff) +{ +} + +template +typed::multi_aff>::multi_aff(const typed::space> &space, const typed::aff_list &list) + : isl::multi_aff(space, list) +{ +} + +template +typed::multi_aff>::multi_aff(const isl::ctx &ctx, const std::string &str) + : isl::multi_aff(ctx, str) +{ +} + +template +typed::multi_aff> typed::multi_aff>::add(const typed::multi_aff> &multi2) const +{ + auto res = isl::multi_aff::add(multi2); + return typed::multi_aff>(res); +} + +template +typed::multi_pw_aff> typed::multi_aff>::add(const typed::multi_pw_aff> &multi2) const +{ + auto res = isl::multi_aff::add(multi2); + return typed::multi_pw_aff>(res); +} + +template +typed::multi_union_pw_aff> typed::multi_aff>::add(const typed::multi_union_pw_aff> &multi2) const +{ + auto res = isl::multi_aff::add(multi2); + return typed::multi_union_pw_aff>(res); +} + +template +typed::pw_multi_aff> typed::multi_aff>::add(const typed::pw_multi_aff> &pma2) const +{ + auto res = isl::multi_aff::add(pma2); + return typed::pw_multi_aff>(res); +} + +template +typed::union_pw_multi_aff> typed::multi_aff>::add(const typed::union_pw_multi_aff> &upma2) const +{ + auto res = isl::multi_aff::add(upma2); + return typed::union_pw_multi_aff>(res); +} + +template +typed::multi_aff> typed::multi_aff>::add(const typed::aff> &multi2) const +{ + auto res = isl::multi_aff::add(multi2); + return typed::multi_aff>(res); +} + +template +typed::multi_aff> typed::multi_aff>::add_constant(const typed::multi_val> &mv) const +{ + auto res = isl::multi_aff::add_constant(mv); + return typed::multi_aff>(res); +} + +template +typed::multi_aff> typed::multi_aff>::add_constant(const typed::val> &v) const +{ + auto res = isl::multi_aff::add_constant(v); + return typed::multi_aff>(res); +} + +template +typed::multi_aff> typed::multi_aff>::add_constant(long v) const +{ + auto res = isl::multi_aff::add_constant(v); + return typed::multi_aff>(res); +} + +template +template +typed::union_pw_multi_aff typed::multi_aff>::apply(const typed::union_pw_multi_aff, Arg3> &upma2) const +{ + auto res = isl::multi_aff::apply(upma2); + return typed::union_pw_multi_aff(res); +} + +template +typed::map> typed::multi_aff>::as_map() const +{ + auto res = isl::multi_aff::as_map(); + return typed::map>(res); +} + +template +typed::multi_aff> typed::multi_aff>::as_multi_aff() const +{ + auto res = isl::multi_aff::as_multi_aff(); + return typed::multi_aff>(res); +} + +template +typed::multi_union_pw_aff> typed::multi_aff>::as_multi_union_pw_aff() const +{ + auto res = isl::multi_aff::as_multi_union_pw_aff(); + return typed::multi_union_pw_aff>(res); +} + +template +typed::pw_multi_aff> typed::multi_aff>::as_pw_multi_aff() const +{ + auto res = isl::multi_aff::as_pw_multi_aff(); + return typed::pw_multi_aff>(res); +} + +template +typed::union_map> typed::multi_aff>::as_union_map() const +{ + auto res = isl::multi_aff::as_union_map(); + return typed::union_map>(res); +} + +template +typed::aff typed::multi_aff>::at(int pos) const +{ + auto res = isl::multi_aff::at(pos); + return typed::aff(res); +} + +template +typed::basic_set typed::multi_aff>::bind(const typed::multi_id> &tuple) const +{ + auto res = isl::multi_aff::bind(tuple); + return typed::basic_set(res); +} + +template +typed::multi_aff> typed::multi_aff>::bind_domain(const typed::multi_id &tuple) const +{ + auto res = isl::multi_aff::bind_domain(tuple); + return typed::multi_aff>(res); +} + +template +typed::pw_multi_aff> typed::multi_aff>::coalesce() const +{ + auto res = isl::multi_aff::coalesce(); + return typed::pw_multi_aff>(res); +} + +template +typed::multi_val> typed::multi_aff>::constant_multi_val() const +{ + auto res = isl::multi_aff::constant_multi_val(); + return typed::multi_val>(res); +} + +template +typed::set typed::multi_aff>::domain() const +{ + auto res = isl::multi_aff::domain(); + return typed::set(res); +} + +template +typed::pw_multi_aff> typed::multi_aff>::drop_unused_params() const +{ + auto res = isl::multi_aff::drop_unused_params(); + return typed::pw_multi_aff>(res); +} + +template +typed::pw_multi_aff> typed::multi_aff>::extract_pw_multi_aff(const typed::space> &space) const +{ + auto res = isl::multi_aff::extract_pw_multi_aff(space); + return typed::pw_multi_aff>(res); +} + +template +typed::multi_aff> typed::multi_aff>::floor() const +{ + auto res = isl::multi_aff::floor(); + return typed::multi_aff>(res); +} + +template +typed::multi_aff> typed::multi_aff>::gist(const typed::set &context) const +{ + auto res = isl::multi_aff::gist(context); + return typed::multi_aff>(res); +} + +template +typed::union_pw_multi_aff> typed::multi_aff>::gist(const typed::union_set &context) const +{ + auto res = isl::multi_aff::gist(context); + return typed::union_pw_multi_aff>(res); +} + +template +typed::multi_aff> typed::multi_aff>::gist(const typed::basic_set &context) const +{ + auto res = isl::multi_aff::gist(context); + return typed::multi_aff>(res); +} + +template +typed::multi_aff> typed::multi_aff>::gist(const typed::point &context) const +{ + auto res = isl::multi_aff::gist(context); + return typed::multi_aff>(res); +} + +template +typed::multi_aff> typed::multi_aff>::gist_params(const typed::set<> &context) const +{ + auto res = isl::multi_aff::gist_params(context); + return typed::multi_aff>(res); +} + +template +typed::multi_aff> typed::multi_aff>::gist_params(const typed::basic_set<> &context) const +{ + auto res = isl::multi_aff::gist_params(context); + return typed::multi_aff>(res); +} + +template +typed::multi_aff> typed::multi_aff>::gist_params(const typed::point<> &context) const +{ + auto res = isl::multi_aff::gist_params(context); + return typed::multi_aff>(res); +} + +template +typed::multi_aff> typed::multi_aff>::identity() const +{ + auto res = isl::multi_aff::identity(); + return typed::multi_aff>(res); +} + +template +typed::pw_multi_aff> typed::multi_aff>::intersect_domain(const typed::set &set) const +{ + auto res = isl::multi_aff::intersect_domain(set); + return typed::pw_multi_aff>(res); +} + +template +typed::union_pw_multi_aff> typed::multi_aff>::intersect_domain(const typed::space &space) const +{ + auto res = isl::multi_aff::intersect_domain(space); + return typed::union_pw_multi_aff>(res); +} + +template +typed::union_pw_multi_aff> typed::multi_aff>::intersect_domain(const typed::union_set &uset) const +{ + auto res = isl::multi_aff::intersect_domain(uset); + return typed::union_pw_multi_aff>(res); +} + +template +typed::pw_multi_aff> typed::multi_aff>::intersect_params(const typed::set<> &set) const +{ + auto res = isl::multi_aff::intersect_params(set); + return typed::pw_multi_aff>(res); +} + +template +typed::aff_list typed::multi_aff>::list() const +{ + auto res = isl::multi_aff::list(); + return typed::aff_list(res); +} + +template +typed::multi_pw_aff> typed::multi_aff>::max(const typed::multi_pw_aff> &multi2) const +{ + auto res = isl::multi_aff::max(multi2); + return typed::multi_pw_aff>(res); +} + +template +typed::multi_val> typed::multi_aff>::max_multi_val() const +{ + auto res = isl::multi_aff::max_multi_val(); + return typed::multi_val>(res); +} + +template +typed::multi_pw_aff> typed::multi_aff>::min(const typed::multi_pw_aff> &multi2) const +{ + auto res = isl::multi_aff::min(multi2); + return typed::multi_pw_aff>(res); +} + +template +typed::multi_val> typed::multi_aff>::min_multi_val() const +{ + auto res = isl::multi_aff::min_multi_val(); + return typed::multi_val>(res); +} + +template +typed::multi_aff> typed::multi_aff>::neg() const +{ + auto res = isl::multi_aff::neg(); + return typed::multi_aff>(res); +} + +template +template +typed::multi_aff, pair, Arg3>> typed::multi_aff>::product(const typed::multi_aff &multi2) const +{ + auto res = isl::multi_aff::product(multi2); + return typed::multi_aff, pair, Arg3>>(res); +} + +template +template +typed::multi_pw_aff, pair, Arg3>> typed::multi_aff>::product(const typed::multi_pw_aff &multi2) const +{ + auto res = isl::multi_aff::product(multi2); + return typed::multi_pw_aff, pair, Arg3>>(res); +} + +template +template +typed::pw_multi_aff, pair, Arg3>> typed::multi_aff>::product(const typed::pw_multi_aff &pma2) const +{ + auto res = isl::multi_aff::product(pma2); + return typed::pw_multi_aff, pair, Arg3>>(res); +} + +template +template +typed::multi_aff, pair, Anonymous>> typed::multi_aff>::product(const typed::aff &multi2) const +{ + auto res = isl::multi_aff::product(multi2); + return typed::multi_aff, pair, Anonymous>>(res); +} + +template +template +typed::multi_aff> typed::multi_aff>::pullback(const typed::multi_aff &ma2) const +{ + auto res = isl::multi_aff::pullback(ma2); + return typed::multi_aff>(res); +} + +template +typed::multi_aff> typed::multi_aff>::pullback(const typed::multi_aff &ma2) const +{ + auto res = isl::multi_aff::pullback(ma2); + return typed::multi_aff>(res); +} + +template +template +typed::multi_pw_aff> typed::multi_aff>::pullback(const typed::multi_pw_aff &mpa2) const +{ + auto res = isl::multi_aff::pullback(mpa2); + return typed::multi_pw_aff>(res); +} + +template +typed::multi_pw_aff> typed::multi_aff>::pullback(const typed::multi_pw_aff &mpa2) const +{ + auto res = isl::multi_aff::pullback(mpa2); + return typed::multi_pw_aff>(res); +} + +template +template +typed::pw_multi_aff> typed::multi_aff>::pullback(const typed::pw_multi_aff &pma2) const +{ + auto res = isl::multi_aff::pullback(pma2); + return typed::pw_multi_aff>(res); +} + +template +typed::pw_multi_aff> typed::multi_aff>::pullback(const typed::pw_multi_aff &pma2) const +{ + auto res = isl::multi_aff::pullback(pma2); + return typed::pw_multi_aff>(res); +} + +template +template +typed::union_pw_multi_aff> typed::multi_aff>::pullback(const typed::union_pw_multi_aff &upma2) const +{ + auto res = isl::multi_aff::pullback(upma2); + return typed::union_pw_multi_aff>(res); +} + +template +typed::union_pw_multi_aff> typed::multi_aff>::pullback(const typed::union_pw_multi_aff &upma2) const +{ + auto res = isl::multi_aff::pullback(upma2); + return typed::union_pw_multi_aff>(res); +} + +template +template +typed::multi_aff> typed::multi_aff>::pullback(const typed::aff &ma2) const +{ + auto res = isl::multi_aff::pullback(ma2); + return typed::multi_aff>(res); +} + +template +typed::multi_aff> typed::multi_aff>::pullback(const typed::aff &ma2) const +{ + auto res = isl::multi_aff::pullback(ma2); + return typed::multi_aff>(res); +} + +template +typed::pw_multi_aff_list> typed::multi_aff>::pw_multi_aff_list() const +{ + auto res = isl::multi_aff::pw_multi_aff_list(); + return typed::pw_multi_aff_list>(res); +} + +template +typed::pw_multi_aff typed::multi_aff>::range_factor_domain() const +{ + auto res = isl::multi_aff::range_factor_domain(); + return typed::pw_multi_aff(res); +} + +template +typed::pw_multi_aff typed::multi_aff>::range_factor_range() const +{ + auto res = isl::multi_aff::range_factor_range(); + return typed::pw_multi_aff(res); +} + +template +template +typed::multi_aff, Arg3>> typed::multi_aff>::range_product(const typed::multi_aff &multi2) const +{ + auto res = isl::multi_aff::range_product(multi2); + return typed::multi_aff, Arg3>>(res); +} + +template +template +typed::multi_pw_aff, Arg3>> typed::multi_aff>::range_product(const typed::multi_pw_aff &multi2) const +{ + auto res = isl::multi_aff::range_product(multi2); + return typed::multi_pw_aff, Arg3>>(res); +} + +template +template +typed::multi_union_pw_aff, Arg3>> typed::multi_aff>::range_product(const typed::multi_union_pw_aff &multi2) const +{ + auto res = isl::multi_aff::range_product(multi2); + return typed::multi_union_pw_aff, Arg3>>(res); +} + +template +template +typed::pw_multi_aff, Arg3>> typed::multi_aff>::range_product(const typed::pw_multi_aff &pma2) const +{ + auto res = isl::multi_aff::range_product(pma2); + return typed::pw_multi_aff, Arg3>>(res); +} + +template +template +typed::union_pw_multi_aff, Arg3>> typed::multi_aff>::range_product(const typed::union_pw_multi_aff &upma2) const +{ + auto res = isl::multi_aff::range_product(upma2); + return typed::union_pw_multi_aff, Arg3>>(res); +} + +template +typed::multi_aff, Anonymous>> typed::multi_aff>::range_product(const typed::aff &multi2) const +{ + auto res = isl::multi_aff::range_product(multi2); + return typed::multi_aff, Anonymous>>(res); +} + +template +typed::multi_aff> typed::multi_aff>::scale(const typed::multi_val> &mv) const +{ + auto res = isl::multi_aff::scale(mv); + return typed::multi_aff>(res); +} + +template +typed::multi_aff> typed::multi_aff>::scale(const typed::val> &v) const +{ + auto res = isl::multi_aff::scale(v); + return typed::multi_aff>(res); +} + +template +typed::multi_aff> typed::multi_aff>::scale(long v) const +{ + auto res = isl::multi_aff::scale(v); + return typed::multi_aff>(res); +} + +template +typed::multi_aff> typed::multi_aff>::scale_down(const typed::multi_val> &mv) const +{ + auto res = isl::multi_aff::scale_down(mv); + return typed::multi_aff>(res); +} + +template +typed::multi_aff> typed::multi_aff>::scale_down(const typed::val> &v) const +{ + auto res = isl::multi_aff::scale_down(v); + return typed::multi_aff>(res); +} + +template +typed::multi_aff> typed::multi_aff>::scale_down(long v) const +{ + auto res = isl::multi_aff::scale_down(v); + return typed::multi_aff>(res); +} + +template +typed::multi_aff> typed::multi_aff>::set_at(int pos, const typed::aff &el) const +{ + auto res = isl::multi_aff::set_at(pos, el); + return typed::multi_aff>(res); +} + +template +typed::multi_pw_aff> typed::multi_aff>::set_at(int pos, const typed::pw_aff &el) const +{ + auto res = isl::multi_aff::set_at(pos, el); + return typed::multi_pw_aff>(res); +} + +template +typed::multi_union_pw_aff> typed::multi_aff>::set_at(int pos, const typed::union_pw_aff &el) const +{ + auto res = isl::multi_aff::set_at(pos, el); + return typed::multi_union_pw_aff>(res); +} + +template +typed::space> typed::multi_aff>::space() const +{ + auto res = isl::multi_aff::space(); + return typed::space>(res); +} + +template +typed::multi_aff> typed::multi_aff>::sub(const typed::multi_aff> &multi2) const +{ + auto res = isl::multi_aff::sub(multi2); + return typed::multi_aff>(res); +} + +template +typed::multi_pw_aff> typed::multi_aff>::sub(const typed::multi_pw_aff> &multi2) const +{ + auto res = isl::multi_aff::sub(multi2); + return typed::multi_pw_aff>(res); +} + +template +typed::multi_union_pw_aff> typed::multi_aff>::sub(const typed::multi_union_pw_aff> &multi2) const +{ + auto res = isl::multi_aff::sub(multi2); + return typed::multi_union_pw_aff>(res); +} + +template +typed::pw_multi_aff> typed::multi_aff>::sub(const typed::pw_multi_aff> &pma2) const +{ + auto res = isl::multi_aff::sub(pma2); + return typed::pw_multi_aff>(res); +} + +template +typed::union_pw_multi_aff> typed::multi_aff>::sub(const typed::union_pw_multi_aff> &upma2) const +{ + auto res = isl::multi_aff::sub(upma2); + return typed::union_pw_multi_aff>(res); +} + +template +typed::multi_aff> typed::multi_aff>::sub(const typed::aff> &multi2) const +{ + auto res = isl::multi_aff::sub(multi2); + return typed::multi_aff>(res); +} + +template +typed::pw_multi_aff> typed::multi_aff>::subtract_domain(const typed::set &set) const +{ + auto res = isl::multi_aff::subtract_domain(set); + return typed::pw_multi_aff>(res); +} + +template +typed::union_pw_multi_aff> typed::multi_aff>::subtract_domain(const typed::space &space) const +{ + auto res = isl::multi_aff::subtract_domain(space); + return typed::union_pw_multi_aff>(res); +} + +template +typed::union_pw_multi_aff> typed::multi_aff>::subtract_domain(const typed::union_set &uset) const +{ + auto res = isl::multi_aff::subtract_domain(uset); + return typed::union_pw_multi_aff>(res); +} + +template +typed::multi_pw_aff> typed::multi_aff>::to_multi_pw_aff() const +{ + auto res = isl::multi_aff::to_multi_pw_aff(); + return typed::multi_pw_aff>(res); +} + +template +typed::multi_union_pw_aff> typed::multi_aff>::to_multi_union_pw_aff() const +{ + auto res = isl::multi_aff::to_multi_union_pw_aff(); + return typed::multi_union_pw_aff>(res); +} + +template +typed::pw_multi_aff> typed::multi_aff>::to_pw_multi_aff() const +{ + auto res = isl::multi_aff::to_pw_multi_aff(); + return typed::pw_multi_aff>(res); +} + +template +typed::union_pw_multi_aff> typed::multi_aff>::to_union_pw_multi_aff() const +{ + auto res = isl::multi_aff::to_union_pw_multi_aff(); + return typed::union_pw_multi_aff>(res); +} + +template +typed::multi_pw_aff> typed::multi_aff>::union_add(const typed::multi_pw_aff> &mpa2) const +{ + auto res = isl::multi_aff::union_add(mpa2); + return typed::multi_pw_aff>(res); +} + +template +typed::multi_union_pw_aff> typed::multi_aff>::union_add(const typed::multi_union_pw_aff> &mupa2) const +{ + auto res = isl::multi_aff::union_add(mupa2); + return typed::multi_union_pw_aff>(res); +} + +template +typed::pw_multi_aff> typed::multi_aff>::union_add(const typed::pw_multi_aff> &pma2) const +{ + auto res = isl::multi_aff::union_add(pma2); + return typed::pw_multi_aff>(res); +} + +template +typed::union_pw_multi_aff> typed::multi_aff>::union_add(const typed::union_pw_multi_aff> &upma2) const +{ + auto res = isl::multi_aff::union_add(upma2); + return typed::union_pw_multi_aff>(res); +} + +template +typed::multi_aff, pair>::multi_aff(const typed::aff, pair> &aff) + : isl::multi_aff(aff) +{ +} + +template +typed::multi_aff, pair>::multi_aff(const typed::space, pair> &space, const typed::aff_list, Anonymous> &list) + : isl::multi_aff(space, list) +{ +} + +template +typed::multi_aff, pair>::multi_aff(const isl::ctx &ctx, const std::string &str) + : isl::multi_aff(ctx, str) +{ +} + +template +typed::multi_aff, pair> typed::multi_aff, pair>::add(const typed::multi_aff, pair> &multi2) const +{ + auto res = isl::multi_aff::add(multi2); + return typed::multi_aff, pair>(res); +} + +template +typed::multi_pw_aff, pair> typed::multi_aff, pair>::add(const typed::multi_pw_aff, pair> &multi2) const +{ + auto res = isl::multi_aff::add(multi2); + return typed::multi_pw_aff, pair>(res); +} + +template +typed::multi_union_pw_aff, pair> typed::multi_aff, pair>::add(const typed::multi_union_pw_aff, pair> &multi2) const +{ + auto res = isl::multi_aff::add(multi2); + return typed::multi_union_pw_aff, pair>(res); +} + +template +typed::pw_multi_aff, pair> typed::multi_aff, pair>::add(const typed::pw_multi_aff, pair> &pma2) const +{ + auto res = isl::multi_aff::add(pma2); + return typed::pw_multi_aff, pair>(res); +} + +template +typed::union_pw_multi_aff, pair> typed::multi_aff, pair>::add(const typed::union_pw_multi_aff, pair> &upma2) const +{ + auto res = isl::multi_aff::add(upma2); + return typed::union_pw_multi_aff, pair>(res); +} + +template +typed::multi_aff, pair> typed::multi_aff, pair>::add(const typed::aff, pair> &multi2) const +{ + auto res = isl::multi_aff::add(multi2); + return typed::multi_aff, pair>(res); +} + +template +typed::multi_aff, pair> typed::multi_aff, pair>::add_constant(const typed::multi_val> &mv) const +{ + auto res = isl::multi_aff::add_constant(mv); + return typed::multi_aff, pair>(res); +} + +template +typed::multi_aff, pair> typed::multi_aff, pair>::add_constant(const typed::val> &v) const +{ + auto res = isl::multi_aff::add_constant(v); + return typed::multi_aff, pair>(res); +} + +template +typed::multi_aff, pair> typed::multi_aff, pair>::add_constant(long v) const +{ + auto res = isl::multi_aff::add_constant(v); + return typed::multi_aff, pair>(res); +} + +template +template +typed::union_pw_multi_aff, Arg2> typed::multi_aff, pair>::apply(const typed::union_pw_multi_aff, Arg2> &upma2) const +{ + auto res = isl::multi_aff::apply(upma2); + return typed::union_pw_multi_aff, Arg2>(res); +} + +template +typed::map, pair> typed::multi_aff, pair>::as_map() const +{ + auto res = isl::multi_aff::as_map(); + return typed::map, pair>(res); +} + +template +typed::multi_aff, pair> typed::multi_aff, pair>::as_multi_aff() const +{ + auto res = isl::multi_aff::as_multi_aff(); + return typed::multi_aff, pair>(res); +} + +template +typed::multi_union_pw_aff, pair> typed::multi_aff, pair>::as_multi_union_pw_aff() const +{ + auto res = isl::multi_aff::as_multi_union_pw_aff(); + return typed::multi_union_pw_aff, pair>(res); +} + +template +typed::pw_multi_aff, pair> typed::multi_aff, pair>::as_pw_multi_aff() const +{ + auto res = isl::multi_aff::as_pw_multi_aff(); + return typed::pw_multi_aff, pair>(res); +} + +template +typed::union_map, pair> typed::multi_aff, pair>::as_union_map() const +{ + auto res = isl::multi_aff::as_union_map(); + return typed::union_map, pair>(res); +} + +template +typed::aff, Anonymous> typed::multi_aff, pair>::at(int pos) const +{ + auto res = isl::multi_aff::at(pos); + return typed::aff, Anonymous>(res); +} + +template +typed::basic_set> typed::multi_aff, pair>::bind(const typed::multi_id> &tuple) const +{ + auto res = isl::multi_aff::bind(tuple); + return typed::basic_set>(res); +} + +template +typed::multi_aff> typed::multi_aff, pair>::bind_domain(const typed::multi_id> &tuple) const +{ + auto res = isl::multi_aff::bind_domain(tuple); + return typed::multi_aff>(res); +} + +template +typed::multi_aff> typed::multi_aff, pair>::bind_domain_wrapped_domain(const typed::multi_id &tuple) const +{ + auto res = isl::multi_aff::bind_domain_wrapped_domain(tuple); + return typed::multi_aff>(res); +} + +template +typed::pw_multi_aff, pair> typed::multi_aff, pair>::coalesce() const +{ + auto res = isl::multi_aff::coalesce(); + return typed::pw_multi_aff, pair>(res); +} + +template +typed::multi_val> typed::multi_aff, pair>::constant_multi_val() const +{ + auto res = isl::multi_aff::constant_multi_val(); + return typed::multi_val>(res); +} + +template +typed::set> typed::multi_aff, pair>::domain() const +{ + auto res = isl::multi_aff::domain(); + return typed::set>(res); +} + +template +typed::multi_aff, pair> typed::multi_aff, pair>::domain_reverse() const +{ + auto res = isl::multi_aff::domain_reverse(); + return typed::multi_aff, pair>(res); +} + +template +typed::pw_multi_aff, pair> typed::multi_aff, pair>::drop_unused_params() const +{ + auto res = isl::multi_aff::drop_unused_params(); + return typed::pw_multi_aff, pair>(res); +} + +template +typed::pw_multi_aff, pair> typed::multi_aff, pair>::extract_pw_multi_aff(const typed::space, pair> &space) const +{ + auto res = isl::multi_aff::extract_pw_multi_aff(space); + return typed::pw_multi_aff, pair>(res); +} + +template +typed::multi_aff, pair> typed::multi_aff, pair>::floor() const +{ + auto res = isl::multi_aff::floor(); + return typed::multi_aff, pair>(res); +} + +template +typed::multi_aff, pair> typed::multi_aff, pair>::gist(const typed::set> &context) const +{ + auto res = isl::multi_aff::gist(context); + return typed::multi_aff, pair>(res); +} + +template +typed::union_pw_multi_aff, pair> typed::multi_aff, pair>::gist(const typed::union_set> &context) const +{ + auto res = isl::multi_aff::gist(context); + return typed::union_pw_multi_aff, pair>(res); +} + +template +typed::multi_aff, pair> typed::multi_aff, pair>::gist(const typed::basic_set> &context) const +{ + auto res = isl::multi_aff::gist(context); + return typed::multi_aff, pair>(res); +} + +template +typed::multi_aff, pair> typed::multi_aff, pair>::gist(const typed::point> &context) const +{ + auto res = isl::multi_aff::gist(context); + return typed::multi_aff, pair>(res); +} + +template +typed::multi_aff, pair> typed::multi_aff, pair>::gist_params(const typed::set<> &context) const +{ + auto res = isl::multi_aff::gist_params(context); + return typed::multi_aff, pair>(res); +} + +template +typed::multi_aff, pair> typed::multi_aff, pair>::gist_params(const typed::basic_set<> &context) const +{ + auto res = isl::multi_aff::gist_params(context); + return typed::multi_aff, pair>(res); +} + +template +typed::multi_aff, pair> typed::multi_aff, pair>::gist_params(const typed::point<> &context) const +{ + auto res = isl::multi_aff::gist_params(context); + return typed::multi_aff, pair>(res); +} + +template +typed::multi_aff, pair> typed::multi_aff, pair>::identity() const +{ + auto res = isl::multi_aff::identity(); + return typed::multi_aff, pair>(res); +} + +template +typed::pw_multi_aff, pair> typed::multi_aff, pair>::intersect_domain(const typed::set> &set) const +{ + auto res = isl::multi_aff::intersect_domain(set); + return typed::pw_multi_aff, pair>(res); +} + +template +typed::union_pw_multi_aff, pair> typed::multi_aff, pair>::intersect_domain(const typed::space> &space) const +{ + auto res = isl::multi_aff::intersect_domain(space); + return typed::union_pw_multi_aff, pair>(res); +} + +template +typed::union_pw_multi_aff, pair> typed::multi_aff, pair>::intersect_domain(const typed::union_set> &uset) const +{ + auto res = isl::multi_aff::intersect_domain(uset); + return typed::union_pw_multi_aff, pair>(res); +} + +template +typed::union_pw_multi_aff, pair> typed::multi_aff, pair>::intersect_domain_wrapped_domain(const typed::union_set &uset) const +{ + auto res = isl::multi_aff::intersect_domain_wrapped_domain(uset); + return typed::union_pw_multi_aff, pair>(res); +} + +template +typed::pw_multi_aff, pair> typed::multi_aff, pair>::intersect_params(const typed::set<> &set) const +{ + auto res = isl::multi_aff::intersect_params(set); + return typed::pw_multi_aff, pair>(res); +} + +template +typed::aff_list, Anonymous> typed::multi_aff, pair>::list() const +{ + auto res = isl::multi_aff::list(); + return typed::aff_list, Anonymous>(res); +} + +template +typed::multi_pw_aff, pair> typed::multi_aff, pair>::max(const typed::multi_pw_aff, pair> &multi2) const +{ + auto res = isl::multi_aff::max(multi2); + return typed::multi_pw_aff, pair>(res); +} + +template +typed::multi_val> typed::multi_aff, pair>::max_multi_val() const +{ + auto res = isl::multi_aff::max_multi_val(); + return typed::multi_val>(res); +} + +template +typed::multi_pw_aff, pair> typed::multi_aff, pair>::min(const typed::multi_pw_aff, pair> &multi2) const +{ + auto res = isl::multi_aff::min(multi2); + return typed::multi_pw_aff, pair>(res); +} + +template +typed::multi_val> typed::multi_aff, pair>::min_multi_val() const +{ + auto res = isl::multi_aff::min_multi_val(); + return typed::multi_val>(res); +} + +template +typed::multi_aff, pair> typed::multi_aff, pair>::neg() const +{ + auto res = isl::multi_aff::neg(); + return typed::multi_aff, pair>(res); +} + +template +template +typed::pw_multi_aff, pair> typed::multi_aff, pair>::preimage_domain_wrapped_domain(const typed::pw_multi_aff &pma2) const +{ + auto res = isl::multi_aff::preimage_domain_wrapped_domain(pma2); + return typed::pw_multi_aff, pair>(res); +} + +template +template +typed::union_pw_multi_aff, pair> typed::multi_aff, pair>::preimage_domain_wrapped_domain(const typed::union_pw_multi_aff &upma2) const +{ + auto res = isl::multi_aff::preimage_domain_wrapped_domain(upma2); + return typed::union_pw_multi_aff, pair>(res); +} + +template +template +typed::multi_aff, Domain2>, pair, Arg2>> typed::multi_aff, pair>::product(const typed::multi_aff &multi2) const +{ + auto res = isl::multi_aff::product(multi2); + return typed::multi_aff, Domain2>, pair, Arg2>>(res); +} + +template +template +typed::multi_pw_aff, Domain2>, pair, Arg2>> typed::multi_aff, pair>::product(const typed::multi_pw_aff &multi2) const +{ + auto res = isl::multi_aff::product(multi2); + return typed::multi_pw_aff, Domain2>, pair, Arg2>>(res); +} + +template +template +typed::pw_multi_aff, Domain2>, pair, Arg2>> typed::multi_aff, pair>::product(const typed::pw_multi_aff &pma2) const +{ + auto res = isl::multi_aff::product(pma2); + return typed::pw_multi_aff, Domain2>, pair, Arg2>>(res); +} + +template +template +typed::multi_aff, Domain2>, pair, Anonymous>> typed::multi_aff, pair>::product(const typed::aff &multi2) const +{ + auto res = isl::multi_aff::product(multi2); + return typed::multi_aff, Domain2>, pair, Anonymous>>(res); +} + +template +template +typed::multi_aff> typed::multi_aff, pair>::pullback(const typed::multi_aff> &ma2) const +{ + auto res = isl::multi_aff::pullback(ma2); + return typed::multi_aff>(res); +} + +template +typed::multi_aff> typed::multi_aff, pair>::pullback(const typed::multi_aff> &ma2) const +{ + auto res = isl::multi_aff::pullback(ma2); + return typed::multi_aff>(res); +} + +template +template +typed::multi_pw_aff> typed::multi_aff, pair>::pullback(const typed::multi_pw_aff> &mpa2) const +{ + auto res = isl::multi_aff::pullback(mpa2); + return typed::multi_pw_aff>(res); +} + +template +typed::multi_pw_aff> typed::multi_aff, pair>::pullback(const typed::multi_pw_aff> &mpa2) const +{ + auto res = isl::multi_aff::pullback(mpa2); + return typed::multi_pw_aff>(res); +} + +template +template +typed::pw_multi_aff> typed::multi_aff, pair>::pullback(const typed::pw_multi_aff> &pma2) const +{ + auto res = isl::multi_aff::pullback(pma2); + return typed::pw_multi_aff>(res); +} + +template +typed::pw_multi_aff> typed::multi_aff, pair>::pullback(const typed::pw_multi_aff> &pma2) const +{ + auto res = isl::multi_aff::pullback(pma2); + return typed::pw_multi_aff>(res); +} + +template +template +typed::union_pw_multi_aff> typed::multi_aff, pair>::pullback(const typed::union_pw_multi_aff> &upma2) const +{ + auto res = isl::multi_aff::pullback(upma2); + return typed::union_pw_multi_aff>(res); +} + +template +typed::union_pw_multi_aff> typed::multi_aff, pair>::pullback(const typed::union_pw_multi_aff> &upma2) const +{ + auto res = isl::multi_aff::pullback(upma2); + return typed::union_pw_multi_aff>(res); +} + +template +template +typed::multi_aff> typed::multi_aff, pair>::pullback(const typed::aff> &ma2) const +{ + auto res = isl::multi_aff::pullback(ma2); + return typed::multi_aff>(res); +} + +template +typed::multi_aff> typed::multi_aff, pair>::pullback(const typed::aff> &ma2) const +{ + auto res = isl::multi_aff::pullback(ma2); + return typed::multi_aff>(res); +} + +template +typed::pw_multi_aff_list, pair> typed::multi_aff, pair>::pw_multi_aff_list() const +{ + auto res = isl::multi_aff::pw_multi_aff_list(); + return typed::pw_multi_aff_list, pair>(res); +} + +template +typed::pw_multi_aff, Range> typed::multi_aff, pair>::range_factor_domain() const +{ + auto res = isl::multi_aff::range_factor_domain(); + return typed::pw_multi_aff, Range>(res); +} + +template +typed::pw_multi_aff, Range2> typed::multi_aff, pair>::range_factor_range() const +{ + auto res = isl::multi_aff::range_factor_range(); + return typed::pw_multi_aff, Range2>(res); +} + +template +template +typed::multi_aff, pair, Arg2>> typed::multi_aff, pair>::range_product(const typed::multi_aff, Arg2> &multi2) const +{ + auto res = isl::multi_aff::range_product(multi2); + return typed::multi_aff, pair, Arg2>>(res); +} + +template +template +typed::multi_pw_aff, pair, Arg2>> typed::multi_aff, pair>::range_product(const typed::multi_pw_aff, Arg2> &multi2) const +{ + auto res = isl::multi_aff::range_product(multi2); + return typed::multi_pw_aff, pair, Arg2>>(res); +} + +template +template +typed::multi_union_pw_aff, pair, Arg2>> typed::multi_aff, pair>::range_product(const typed::multi_union_pw_aff, Arg2> &multi2) const +{ + auto res = isl::multi_aff::range_product(multi2); + return typed::multi_union_pw_aff, pair, Arg2>>(res); +} + +template +template +typed::pw_multi_aff, pair, Arg2>> typed::multi_aff, pair>::range_product(const typed::pw_multi_aff, Arg2> &pma2) const +{ + auto res = isl::multi_aff::range_product(pma2); + return typed::pw_multi_aff, pair, Arg2>>(res); +} + +template +template +typed::union_pw_multi_aff, pair, Arg2>> typed::multi_aff, pair>::range_product(const typed::union_pw_multi_aff, Arg2> &upma2) const +{ + auto res = isl::multi_aff::range_product(upma2); + return typed::union_pw_multi_aff, pair, Arg2>>(res); +} + +template +typed::multi_aff, pair, Anonymous>> typed::multi_aff, pair>::range_product(const typed::aff, Anonymous> &multi2) const +{ + auto res = isl::multi_aff::range_product(multi2); + return typed::multi_aff, pair, Anonymous>>(res); +} + +template +typed::multi_aff, pair> typed::multi_aff, pair>::scale(const typed::multi_val> &mv) const +{ + auto res = isl::multi_aff::scale(mv); + return typed::multi_aff, pair>(res); +} + +template +typed::multi_aff, pair> typed::multi_aff, pair>::scale(const typed::val> &v) const +{ + auto res = isl::multi_aff::scale(v); + return typed::multi_aff, pair>(res); +} + +template +typed::multi_aff, pair> typed::multi_aff, pair>::scale(long v) const +{ + auto res = isl::multi_aff::scale(v); + return typed::multi_aff, pair>(res); +} + +template +typed::multi_aff, pair> typed::multi_aff, pair>::scale_down(const typed::multi_val> &mv) const +{ + auto res = isl::multi_aff::scale_down(mv); + return typed::multi_aff, pair>(res); +} + +template +typed::multi_aff, pair> typed::multi_aff, pair>::scale_down(const typed::val> &v) const +{ + auto res = isl::multi_aff::scale_down(v); + return typed::multi_aff, pair>(res); +} + +template +typed::multi_aff, pair> typed::multi_aff, pair>::scale_down(long v) const +{ + auto res = isl::multi_aff::scale_down(v); + return typed::multi_aff, pair>(res); +} + +template +typed::multi_aff, pair> typed::multi_aff, pair>::set_at(int pos, const typed::aff, Anonymous> &el) const +{ + auto res = isl::multi_aff::set_at(pos, el); + return typed::multi_aff, pair>(res); +} + +template +typed::multi_pw_aff, pair> typed::multi_aff, pair>::set_at(int pos, const typed::pw_aff, Anonymous> &el) const +{ + auto res = isl::multi_aff::set_at(pos, el); + return typed::multi_pw_aff, pair>(res); +} + +template +typed::multi_union_pw_aff, pair> typed::multi_aff, pair>::set_at(int pos, const typed::union_pw_aff, Anonymous> &el) const +{ + auto res = isl::multi_aff::set_at(pos, el); + return typed::multi_union_pw_aff, pair>(res); +} + +template +typed::space, pair> typed::multi_aff, pair>::space() const +{ + auto res = isl::multi_aff::space(); + return typed::space, pair>(res); +} + +template +typed::multi_aff, pair> typed::multi_aff, pair>::sub(const typed::multi_aff, pair> &multi2) const +{ + auto res = isl::multi_aff::sub(multi2); + return typed::multi_aff, pair>(res); +} + +template +typed::multi_pw_aff, pair> typed::multi_aff, pair>::sub(const typed::multi_pw_aff, pair> &multi2) const +{ + auto res = isl::multi_aff::sub(multi2); + return typed::multi_pw_aff, pair>(res); +} + +template +typed::multi_union_pw_aff, pair> typed::multi_aff, pair>::sub(const typed::multi_union_pw_aff, pair> &multi2) const +{ + auto res = isl::multi_aff::sub(multi2); + return typed::multi_union_pw_aff, pair>(res); +} + +template +typed::pw_multi_aff, pair> typed::multi_aff, pair>::sub(const typed::pw_multi_aff, pair> &pma2) const +{ + auto res = isl::multi_aff::sub(pma2); + return typed::pw_multi_aff, pair>(res); +} + +template +typed::union_pw_multi_aff, pair> typed::multi_aff, pair>::sub(const typed::union_pw_multi_aff, pair> &upma2) const +{ + auto res = isl::multi_aff::sub(upma2); + return typed::union_pw_multi_aff, pair>(res); +} + +template +typed::multi_aff, pair> typed::multi_aff, pair>::sub(const typed::aff, pair> &multi2) const +{ + auto res = isl::multi_aff::sub(multi2); + return typed::multi_aff, pair>(res); +} + +template +typed::pw_multi_aff, pair> typed::multi_aff, pair>::subtract_domain(const typed::set> &set) const +{ + auto res = isl::multi_aff::subtract_domain(set); + return typed::pw_multi_aff, pair>(res); +} + +template +typed::union_pw_multi_aff, pair> typed::multi_aff, pair>::subtract_domain(const typed::space> &space) const +{ + auto res = isl::multi_aff::subtract_domain(space); + return typed::union_pw_multi_aff, pair>(res); +} + +template +typed::union_pw_multi_aff, pair> typed::multi_aff, pair>::subtract_domain(const typed::union_set> &uset) const +{ + auto res = isl::multi_aff::subtract_domain(uset); + return typed::union_pw_multi_aff, pair>(res); +} + +template +typed::multi_pw_aff, pair> typed::multi_aff, pair>::to_multi_pw_aff() const +{ + auto res = isl::multi_aff::to_multi_pw_aff(); + return typed::multi_pw_aff, pair>(res); +} + +template +typed::multi_union_pw_aff, pair> typed::multi_aff, pair>::to_multi_union_pw_aff() const +{ + auto res = isl::multi_aff::to_multi_union_pw_aff(); + return typed::multi_union_pw_aff, pair>(res); +} + +template +typed::pw_multi_aff, pair> typed::multi_aff, pair>::to_pw_multi_aff() const +{ + auto res = isl::multi_aff::to_pw_multi_aff(); + return typed::pw_multi_aff, pair>(res); +} + +template +typed::union_pw_multi_aff, pair> typed::multi_aff, pair>::to_union_pw_multi_aff() const +{ + auto res = isl::multi_aff::to_union_pw_multi_aff(); + return typed::union_pw_multi_aff, pair>(res); +} + +template +typed::multi_pw_aff, pair> typed::multi_aff, pair>::union_add(const typed::multi_pw_aff, pair> &mpa2) const +{ + auto res = isl::multi_aff::union_add(mpa2); + return typed::multi_pw_aff, pair>(res); +} + +template +typed::multi_union_pw_aff, pair> typed::multi_aff, pair>::union_add(const typed::multi_union_pw_aff, pair> &mupa2) const +{ + auto res = isl::multi_aff::union_add(mupa2); + return typed::multi_union_pw_aff, pair>(res); +} + +template +typed::pw_multi_aff, pair> typed::multi_aff, pair>::union_add(const typed::pw_multi_aff, pair> &pma2) const +{ + auto res = isl::multi_aff::union_add(pma2); + return typed::pw_multi_aff, pair>(res); +} + +template +typed::union_pw_multi_aff, pair> typed::multi_aff, pair>::union_add(const typed::union_pw_multi_aff, pair> &upma2) const +{ + auto res = isl::multi_aff::union_add(upma2); + return typed::union_pw_multi_aff, pair>(res); +} + +template +typed::multi_id::multi_id(const typed::space &space, const typed::id_list &list) + : isl::multi_id(space, list) +{ +} + +template +typed::multi_id::multi_id(const isl::ctx &ctx, const std::string &str) + : isl::multi_id(ctx, str) +{ +} + +template +typed::id typed::multi_id::at(int pos) const +{ + auto res = isl::multi_id::at(pos); + return typed::id(res); +} + +template +typed::id_list typed::multi_id::list() const +{ + auto res = isl::multi_id::list(); + return typed::id_list(res); +} + +template +typed::multi_id typed::multi_id::set_at(int pos, const typed::id &el) const +{ + auto res = isl::multi_id::set_at(pos, el); + return typed::multi_id(res); +} + +template +typed::multi_id typed::multi_id::set_at(int pos, const std::string &el) const +{ + auto res = isl::multi_id::set_at(pos, el); + return typed::multi_id(res); +} + +template +typed::space typed::multi_id::space() const +{ + auto res = isl::multi_id::space(); + return typed::space(res); +} + +template +typed::multi_pw_aff::multi_pw_aff(const typed::aff &aff) + : isl::multi_pw_aff(aff) +{ +} + +template +typed::multi_pw_aff::multi_pw_aff(const typed::multi_aff &ma) + : isl::multi_pw_aff(ma) +{ +} + +template +typed::multi_pw_aff::multi_pw_aff(const typed::pw_aff &pa) + : isl::multi_pw_aff(pa) +{ +} + +template +typed::multi_pw_aff::multi_pw_aff(const typed::space &space, const typed::pw_aff_list &list) + : isl::multi_pw_aff(space, list) +{ +} + +template +typed::multi_pw_aff::multi_pw_aff(const typed::pw_multi_aff &pma) + : isl::multi_pw_aff(pma) +{ +} + +template +typed::multi_pw_aff::multi_pw_aff(const isl::ctx &ctx, const std::string &str) + : isl::multi_pw_aff(ctx, str) +{ +} + +template +typed::multi_pw_aff typed::multi_pw_aff::add(const typed::multi_pw_aff &multi2) const +{ + auto res = isl::multi_pw_aff::add(multi2); + return typed::multi_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::multi_pw_aff::add(const typed::multi_union_pw_aff &multi2) const +{ + auto res = isl::multi_pw_aff::add(multi2); + return typed::multi_union_pw_aff(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff::add(const typed::aff &multi2) const +{ + auto res = isl::multi_pw_aff::add(multi2); + return typed::multi_pw_aff(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff::add(const typed::multi_aff &multi2) const +{ + auto res = isl::multi_pw_aff::add(multi2); + return typed::multi_pw_aff(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff::add(const typed::pw_aff &multi2) const +{ + auto res = isl::multi_pw_aff::add(multi2); + return typed::multi_pw_aff(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff::add(const typed::pw_multi_aff &multi2) const +{ + auto res = isl::multi_pw_aff::add(multi2); + return typed::multi_pw_aff(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff::add_constant(const typed::multi_val &mv) const +{ + auto res = isl::multi_pw_aff::add_constant(mv); + return typed::multi_pw_aff(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff::add_constant(const typed::val &v) const +{ + auto res = isl::multi_pw_aff::add_constant(v); + return typed::multi_pw_aff(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff::add_constant(long v) const +{ + auto res = isl::multi_pw_aff::add_constant(v); + return typed::multi_pw_aff(res); +} + +template +typed::multi_aff typed::multi_pw_aff::as_multi_aff() const +{ + auto res = isl::multi_pw_aff::as_multi_aff(); + return typed::multi_aff(res); +} + +template +typed::set typed::multi_pw_aff::as_set() const +{ + auto res = isl::multi_pw_aff::as_set(); + return typed::set(res); +} + +template +typed::pw_aff typed::multi_pw_aff::at(int pos) const +{ + auto res = isl::multi_pw_aff::at(pos); + return typed::pw_aff(res); +} + +template +typed::set<> typed::multi_pw_aff::bind(const typed::multi_id &tuple) const +{ + auto res = isl::multi_pw_aff::bind(tuple); + return typed::set<>(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff::coalesce() const +{ + auto res = isl::multi_pw_aff::coalesce(); + return typed::multi_pw_aff(res); +} + +template +typed::set<> typed::multi_pw_aff::domain() const +{ + auto res = isl::multi_pw_aff::domain(); + return typed::set<>(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff::gist(const typed::set<> &set) const +{ + auto res = isl::multi_pw_aff::gist(set); + return typed::multi_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::multi_pw_aff::gist(const typed::union_set<> &context) const +{ + auto res = isl::multi_pw_aff::gist(context); + return typed::multi_union_pw_aff(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff::gist(const typed::basic_set<> &set) const +{ + auto res = isl::multi_pw_aff::gist(set); + return typed::multi_pw_aff(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff::gist(const typed::point<> &set) const +{ + auto res = isl::multi_pw_aff::gist(set); + return typed::multi_pw_aff(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff::gist_params(const typed::set<> &set) const +{ + auto res = isl::multi_pw_aff::gist_params(set); + return typed::multi_pw_aff(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff::gist_params(const typed::basic_set<> &set) const +{ + auto res = isl::multi_pw_aff::gist_params(set); + return typed::multi_pw_aff(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff::gist_params(const typed::point<> &set) const +{ + auto res = isl::multi_pw_aff::gist_params(set); + return typed::multi_pw_aff(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff::identity() const +{ + auto res = isl::multi_pw_aff::identity(); + return typed::multi_pw_aff(res); +} + +template +template +typed::multi_pw_aff typed::multi_pw_aff::insert_domain(const typed::space &domain) const +{ + auto res = isl::multi_pw_aff::insert_domain(domain); + return typed::multi_pw_aff(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff::intersect_params(const typed::set<> &set) const +{ + auto res = isl::multi_pw_aff::intersect_params(set); + return typed::multi_pw_aff(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff::intersect_params(const typed::basic_set<> &set) const +{ + auto res = isl::multi_pw_aff::intersect_params(set); + return typed::multi_pw_aff(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff::intersect_params(const typed::point<> &set) const +{ + auto res = isl::multi_pw_aff::intersect_params(set); + return typed::multi_pw_aff(res); +} + +template +typed::pw_aff_list typed::multi_pw_aff::list() const +{ + auto res = isl::multi_pw_aff::list(); + return typed::pw_aff_list(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff::max(const typed::multi_pw_aff &multi2) const +{ + auto res = isl::multi_pw_aff::max(multi2); + return typed::multi_pw_aff(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff::max(const typed::aff &multi2) const +{ + auto res = isl::multi_pw_aff::max(multi2); + return typed::multi_pw_aff(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff::max(const typed::multi_aff &multi2) const +{ + auto res = isl::multi_pw_aff::max(multi2); + return typed::multi_pw_aff(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff::max(const typed::pw_aff &multi2) const +{ + auto res = isl::multi_pw_aff::max(multi2); + return typed::multi_pw_aff(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff::max(const typed::pw_multi_aff &multi2) const +{ + auto res = isl::multi_pw_aff::max(multi2); + return typed::multi_pw_aff(res); +} + +template +typed::multi_val typed::multi_pw_aff::max_multi_val() const +{ + auto res = isl::multi_pw_aff::max_multi_val(); + return typed::multi_val(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff::min(const typed::multi_pw_aff &multi2) const +{ + auto res = isl::multi_pw_aff::min(multi2); + return typed::multi_pw_aff(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff::min(const typed::aff &multi2) const +{ + auto res = isl::multi_pw_aff::min(multi2); + return typed::multi_pw_aff(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff::min(const typed::multi_aff &multi2) const +{ + auto res = isl::multi_pw_aff::min(multi2); + return typed::multi_pw_aff(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff::min(const typed::pw_aff &multi2) const +{ + auto res = isl::multi_pw_aff::min(multi2); + return typed::multi_pw_aff(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff::min(const typed::pw_multi_aff &multi2) const +{ + auto res = isl::multi_pw_aff::min(multi2); + return typed::multi_pw_aff(res); +} + +template +typed::multi_val typed::multi_pw_aff::min_multi_val() const +{ + auto res = isl::multi_pw_aff::min_multi_val(); + return typed::multi_val(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff::neg() const +{ + auto res = isl::multi_pw_aff::neg(); + return typed::multi_pw_aff(res); +} + +template +template +typed::multi_pw_aff> typed::multi_pw_aff::product(const typed::multi_pw_aff &multi2) const +{ + auto res = isl::multi_pw_aff::product(multi2); + return typed::multi_pw_aff>(res); +} + +template +typed::multi_pw_aff> typed::multi_pw_aff::product(const typed::aff &multi2) const +{ + auto res = isl::multi_pw_aff::product(multi2); + return typed::multi_pw_aff>(res); +} + +template +template +typed::multi_pw_aff> typed::multi_pw_aff::product(const typed::multi_aff &multi2) const +{ + auto res = isl::multi_pw_aff::product(multi2); + return typed::multi_pw_aff>(res); +} + +template +typed::multi_pw_aff> typed::multi_pw_aff::product(const typed::pw_aff &multi2) const +{ + auto res = isl::multi_pw_aff::product(multi2); + return typed::multi_pw_aff>(res); +} + +template +template +typed::multi_pw_aff> typed::multi_pw_aff::product(const typed::pw_multi_aff &multi2) const +{ + auto res = isl::multi_pw_aff::product(multi2); + return typed::multi_pw_aff>(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff::scale(const typed::multi_val &mv) const +{ + auto res = isl::multi_pw_aff::scale(mv); + return typed::multi_pw_aff(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff::scale(const typed::val &v) const +{ + auto res = isl::multi_pw_aff::scale(v); + return typed::multi_pw_aff(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff::scale(long v) const +{ + auto res = isl::multi_pw_aff::scale(v); + return typed::multi_pw_aff(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff::scale_down(const typed::multi_val &mv) const +{ + auto res = isl::multi_pw_aff::scale_down(mv); + return typed::multi_pw_aff(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff::scale_down(const typed::val &v) const +{ + auto res = isl::multi_pw_aff::scale_down(v); + return typed::multi_pw_aff(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff::scale_down(long v) const +{ + auto res = isl::multi_pw_aff::scale_down(v); + return typed::multi_pw_aff(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff::set_at(int pos, const typed::pw_aff &el) const +{ + auto res = isl::multi_pw_aff::set_at(pos, el); + return typed::multi_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::multi_pw_aff::set_at(int pos, const typed::union_pw_aff &el) const +{ + auto res = isl::multi_pw_aff::set_at(pos, el); + return typed::multi_union_pw_aff(res); +} + +template +template +typed::multi_pw_aff typed::multi_pw_aff::set_range_tuple(const typed::id &id) const +{ + auto res = isl::multi_pw_aff::set_range_tuple(id); + return typed::multi_pw_aff(res); +} + +template +template +typed::multi_pw_aff typed::multi_pw_aff::set_range_tuple(const std::string &id) const +{ + auto res = isl::multi_pw_aff::set_range_tuple(id); + return typed::multi_pw_aff(res); +} + +template +typed::space typed::multi_pw_aff::space() const +{ + auto res = isl::multi_pw_aff::space(); + return typed::space(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff::sub(const typed::multi_pw_aff &multi2) const +{ + auto res = isl::multi_pw_aff::sub(multi2); + return typed::multi_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::multi_pw_aff::sub(const typed::multi_union_pw_aff &multi2) const +{ + auto res = isl::multi_pw_aff::sub(multi2); + return typed::multi_union_pw_aff(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff::sub(const typed::aff &multi2) const +{ + auto res = isl::multi_pw_aff::sub(multi2); + return typed::multi_pw_aff(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff::sub(const typed::multi_aff &multi2) const +{ + auto res = isl::multi_pw_aff::sub(multi2); + return typed::multi_pw_aff(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff::sub(const typed::pw_aff &multi2) const +{ + auto res = isl::multi_pw_aff::sub(multi2); + return typed::multi_pw_aff(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff::sub(const typed::pw_multi_aff &multi2) const +{ + auto res = isl::multi_pw_aff::sub(multi2); + return typed::multi_pw_aff(res); +} + +template +template +typed::multi_pw_aff typed::multi_pw_aff::unbind_params_insert_domain(const typed::multi_id &domain) const +{ + auto res = isl::multi_pw_aff::unbind_params_insert_domain(domain); + return typed::multi_pw_aff(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff::union_add(const typed::multi_pw_aff &mpa2) const +{ + auto res = isl::multi_pw_aff::union_add(mpa2); + return typed::multi_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::multi_pw_aff::union_add(const typed::multi_union_pw_aff &mupa2) const +{ + auto res = isl::multi_pw_aff::union_add(mupa2); + return typed::multi_union_pw_aff(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff::union_add(const typed::aff &mpa2) const +{ + auto res = isl::multi_pw_aff::union_add(mpa2); + return typed::multi_pw_aff(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff::union_add(const typed::multi_aff &mpa2) const +{ + auto res = isl::multi_pw_aff::union_add(mpa2); + return typed::multi_pw_aff(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff::union_add(const typed::pw_aff &mpa2) const +{ + auto res = isl::multi_pw_aff::union_add(mpa2); + return typed::multi_pw_aff(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff::union_add(const typed::pw_multi_aff &mpa2) const +{ + auto res = isl::multi_pw_aff::union_add(mpa2); + return typed::multi_pw_aff(res); +} + +template +typed::multi_pw_aff::multi_pw_aff(const typed::aff &aff) + : isl::multi_pw_aff(aff) +{ +} + +template +typed::multi_pw_aff::multi_pw_aff(const typed::multi_aff &ma) + : isl::multi_pw_aff(ma) +{ +} + +template +typed::multi_pw_aff::multi_pw_aff(const typed::pw_aff &pa) + : isl::multi_pw_aff(pa) +{ +} + +template +typed::multi_pw_aff::multi_pw_aff(const typed::space &space, const typed::pw_aff_list &list) + : isl::multi_pw_aff(space, list) +{ +} + +template +typed::multi_pw_aff::multi_pw_aff(const typed::pw_multi_aff &pma) + : isl::multi_pw_aff(pma) +{ +} + +template +typed::multi_pw_aff::multi_pw_aff(const isl::ctx &ctx, const std::string &str) + : isl::multi_pw_aff(ctx, str) +{ +} + +template +typed::multi_pw_aff typed::multi_pw_aff::add(const typed::multi_pw_aff &multi2) const +{ + auto res = isl::multi_pw_aff::add(multi2); + return typed::multi_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::multi_pw_aff::add(const typed::multi_union_pw_aff &multi2) const +{ + auto res = isl::multi_pw_aff::add(multi2); + return typed::multi_union_pw_aff(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff::add(const typed::aff &multi2) const +{ + auto res = isl::multi_pw_aff::add(multi2); + return typed::multi_pw_aff(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff::add(const typed::multi_aff &multi2) const +{ + auto res = isl::multi_pw_aff::add(multi2); + return typed::multi_pw_aff(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff::add(const typed::pw_aff &multi2) const +{ + auto res = isl::multi_pw_aff::add(multi2); + return typed::multi_pw_aff(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff::add(const typed::pw_multi_aff &multi2) const +{ + auto res = isl::multi_pw_aff::add(multi2); + return typed::multi_pw_aff(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff::add_constant(const typed::multi_val &mv) const +{ + auto res = isl::multi_pw_aff::add_constant(mv); + return typed::multi_pw_aff(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff::add_constant(const typed::val &v) const +{ + auto res = isl::multi_pw_aff::add_constant(v); + return typed::multi_pw_aff(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff::add_constant(long v) const +{ + auto res = isl::multi_pw_aff::add_constant(v); + return typed::multi_pw_aff(res); +} + +template +typed::map typed::multi_pw_aff::as_map() const +{ + auto res = isl::multi_pw_aff::as_map(); + return typed::map(res); +} + +template +typed::multi_aff typed::multi_pw_aff::as_multi_aff() const +{ + auto res = isl::multi_pw_aff::as_multi_aff(); + return typed::multi_aff(res); +} + +template +typed::pw_aff typed::multi_pw_aff::at(int pos) const +{ + auto res = isl::multi_pw_aff::at(pos); + return typed::pw_aff(res); +} + +template +typed::set typed::multi_pw_aff::bind(const typed::multi_id &tuple) const +{ + auto res = isl::multi_pw_aff::bind(tuple); + return typed::set(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff::bind_domain(const typed::multi_id &tuple) const +{ + auto res = isl::multi_pw_aff::bind_domain(tuple); + return typed::multi_pw_aff(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff::coalesce() const +{ + auto res = isl::multi_pw_aff::coalesce(); + return typed::multi_pw_aff(res); +} + +template +typed::set typed::multi_pw_aff::domain() const +{ + auto res = isl::multi_pw_aff::domain(); + return typed::set(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff::gist(const typed::set &set) const +{ + auto res = isl::multi_pw_aff::gist(set); + return typed::multi_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::multi_pw_aff::gist(const typed::union_set &context) const +{ + auto res = isl::multi_pw_aff::gist(context); + return typed::multi_union_pw_aff(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff::gist(const typed::basic_set &set) const +{ + auto res = isl::multi_pw_aff::gist(set); + return typed::multi_pw_aff(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff::gist(const typed::point &set) const +{ + auto res = isl::multi_pw_aff::gist(set); + return typed::multi_pw_aff(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff::gist_params(const typed::set<> &set) const +{ + auto res = isl::multi_pw_aff::gist_params(set); + return typed::multi_pw_aff(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff::gist_params(const typed::basic_set<> &set) const +{ + auto res = isl::multi_pw_aff::gist_params(set); + return typed::multi_pw_aff(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff::gist_params(const typed::point<> &set) const +{ + auto res = isl::multi_pw_aff::gist_params(set); + return typed::multi_pw_aff(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff::identity() const +{ + auto res = isl::multi_pw_aff::identity(); + return typed::multi_pw_aff(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff::intersect_domain(const typed::set &domain) const +{ + auto res = isl::multi_pw_aff::intersect_domain(domain); + return typed::multi_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::multi_pw_aff::intersect_domain(const typed::union_set &uset) const +{ + auto res = isl::multi_pw_aff::intersect_domain(uset); + return typed::multi_union_pw_aff(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff::intersect_domain(const typed::basic_set &domain) const +{ + auto res = isl::multi_pw_aff::intersect_domain(domain); + return typed::multi_pw_aff(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff::intersect_domain(const typed::point &domain) const +{ + auto res = isl::multi_pw_aff::intersect_domain(domain); + return typed::multi_pw_aff(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff::intersect_params(const typed::set<> &set) const +{ + auto res = isl::multi_pw_aff::intersect_params(set); + return typed::multi_pw_aff(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff::intersect_params(const typed::basic_set<> &set) const +{ + auto res = isl::multi_pw_aff::intersect_params(set); + return typed::multi_pw_aff(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff::intersect_params(const typed::point<> &set) const +{ + auto res = isl::multi_pw_aff::intersect_params(set); + return typed::multi_pw_aff(res); +} + +template +typed::pw_aff_list typed::multi_pw_aff::list() const +{ + auto res = isl::multi_pw_aff::list(); + return typed::pw_aff_list(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff::max(const typed::multi_pw_aff &multi2) const +{ + auto res = isl::multi_pw_aff::max(multi2); + return typed::multi_pw_aff(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff::max(const typed::aff &multi2) const +{ + auto res = isl::multi_pw_aff::max(multi2); + return typed::multi_pw_aff(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff::max(const typed::multi_aff &multi2) const +{ + auto res = isl::multi_pw_aff::max(multi2); + return typed::multi_pw_aff(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff::max(const typed::pw_aff &multi2) const +{ + auto res = isl::multi_pw_aff::max(multi2); + return typed::multi_pw_aff(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff::max(const typed::pw_multi_aff &multi2) const +{ + auto res = isl::multi_pw_aff::max(multi2); + return typed::multi_pw_aff(res); +} + +template +typed::multi_val typed::multi_pw_aff::max_multi_val() const +{ + auto res = isl::multi_pw_aff::max_multi_val(); + return typed::multi_val(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff::min(const typed::multi_pw_aff &multi2) const +{ + auto res = isl::multi_pw_aff::min(multi2); + return typed::multi_pw_aff(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff::min(const typed::aff &multi2) const +{ + auto res = isl::multi_pw_aff::min(multi2); + return typed::multi_pw_aff(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff::min(const typed::multi_aff &multi2) const +{ + auto res = isl::multi_pw_aff::min(multi2); + return typed::multi_pw_aff(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff::min(const typed::pw_aff &multi2) const +{ + auto res = isl::multi_pw_aff::min(multi2); + return typed::multi_pw_aff(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff::min(const typed::pw_multi_aff &multi2) const +{ + auto res = isl::multi_pw_aff::min(multi2); + return typed::multi_pw_aff(res); +} + +template +typed::multi_val typed::multi_pw_aff::min_multi_val() const +{ + auto res = isl::multi_pw_aff::min_multi_val(); + return typed::multi_val(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff::neg() const +{ + auto res = isl::multi_pw_aff::neg(); + return typed::multi_pw_aff(res); +} + +template +template +typed::multi_pw_aff, pair> typed::multi_pw_aff::product(const typed::multi_pw_aff &multi2) const +{ + auto res = isl::multi_pw_aff::product(multi2); + return typed::multi_pw_aff, pair>(res); +} + +template +template +typed::multi_pw_aff, pair> typed::multi_pw_aff::product(const typed::aff &multi2) const +{ + auto res = isl::multi_pw_aff::product(multi2); + return typed::multi_pw_aff, pair>(res); +} + +template +template +typed::multi_pw_aff, pair> typed::multi_pw_aff::product(const typed::multi_aff &multi2) const +{ + auto res = isl::multi_pw_aff::product(multi2); + return typed::multi_pw_aff, pair>(res); +} + +template +template +typed::multi_pw_aff, pair> typed::multi_pw_aff::product(const typed::pw_aff &multi2) const +{ + auto res = isl::multi_pw_aff::product(multi2); + return typed::multi_pw_aff, pair>(res); +} + +template +template +typed::multi_pw_aff, pair> typed::multi_pw_aff::product(const typed::pw_multi_aff &multi2) const +{ + auto res = isl::multi_pw_aff::product(multi2); + return typed::multi_pw_aff, pair>(res); +} + +template +template +typed::multi_pw_aff typed::multi_pw_aff::pullback(const typed::multi_aff &ma) const +{ + auto res = isl::multi_pw_aff::pullback(ma); + return typed::multi_pw_aff(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff::pullback(const typed::multi_aff &ma) const +{ + auto res = isl::multi_pw_aff::pullback(ma); + return typed::multi_pw_aff(res); +} + +template +template +typed::multi_pw_aff typed::multi_pw_aff::pullback(const typed::multi_pw_aff &mpa2) const +{ + auto res = isl::multi_pw_aff::pullback(mpa2); + return typed::multi_pw_aff(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff::pullback(const typed::multi_pw_aff &mpa2) const +{ + auto res = isl::multi_pw_aff::pullback(mpa2); + return typed::multi_pw_aff(res); +} + +template +template +typed::multi_pw_aff typed::multi_pw_aff::pullback(const typed::pw_multi_aff &pma) const +{ + auto res = isl::multi_pw_aff::pullback(pma); + return typed::multi_pw_aff(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff::pullback(const typed::pw_multi_aff &pma) const +{ + auto res = isl::multi_pw_aff::pullback(pma); + return typed::multi_pw_aff(res); +} + +template +template +typed::multi_union_pw_aff typed::multi_pw_aff::pullback(const typed::union_pw_multi_aff &upma) const +{ + auto res = isl::multi_pw_aff::pullback(upma); + return typed::multi_union_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::multi_pw_aff::pullback(const typed::union_pw_multi_aff &upma) const +{ + auto res = isl::multi_pw_aff::pullback(upma); + return typed::multi_union_pw_aff(res); +} + +template +template +typed::multi_pw_aff> typed::multi_pw_aff::range_product(const typed::multi_pw_aff &multi2) const +{ + auto res = isl::multi_pw_aff::range_product(multi2); + return typed::multi_pw_aff>(res); +} + +template +template +typed::multi_union_pw_aff> typed::multi_pw_aff::range_product(const typed::multi_union_pw_aff &multi2) const +{ + auto res = isl::multi_pw_aff::range_product(multi2); + return typed::multi_union_pw_aff>(res); +} + +template +typed::multi_pw_aff> typed::multi_pw_aff::range_product(const typed::aff &multi2) const +{ + auto res = isl::multi_pw_aff::range_product(multi2); + return typed::multi_pw_aff>(res); +} + +template +template +typed::multi_pw_aff> typed::multi_pw_aff::range_product(const typed::multi_aff &multi2) const +{ + auto res = isl::multi_pw_aff::range_product(multi2); + return typed::multi_pw_aff>(res); +} + +template +typed::multi_pw_aff> typed::multi_pw_aff::range_product(const typed::pw_aff &multi2) const +{ + auto res = isl::multi_pw_aff::range_product(multi2); + return typed::multi_pw_aff>(res); +} + +template +template +typed::multi_pw_aff> typed::multi_pw_aff::range_product(const typed::pw_multi_aff &multi2) const +{ + auto res = isl::multi_pw_aff::range_product(multi2); + return typed::multi_pw_aff>(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff::scale(const typed::multi_val &mv) const +{ + auto res = isl::multi_pw_aff::scale(mv); + return typed::multi_pw_aff(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff::scale(const typed::val &v) const +{ + auto res = isl::multi_pw_aff::scale(v); + return typed::multi_pw_aff(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff::scale(long v) const +{ + auto res = isl::multi_pw_aff::scale(v); + return typed::multi_pw_aff(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff::scale_down(const typed::multi_val &mv) const +{ + auto res = isl::multi_pw_aff::scale_down(mv); + return typed::multi_pw_aff(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff::scale_down(const typed::val &v) const +{ + auto res = isl::multi_pw_aff::scale_down(v); + return typed::multi_pw_aff(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff::scale_down(long v) const +{ + auto res = isl::multi_pw_aff::scale_down(v); + return typed::multi_pw_aff(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff::set_at(int pos, const typed::pw_aff &el) const +{ + auto res = isl::multi_pw_aff::set_at(pos, el); + return typed::multi_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::multi_pw_aff::set_at(int pos, const typed::union_pw_aff &el) const +{ + auto res = isl::multi_pw_aff::set_at(pos, el); + return typed::multi_union_pw_aff(res); +} + +template +template +typed::multi_pw_aff typed::multi_pw_aff::set_range_tuple(const typed::id &id) const +{ + auto res = isl::multi_pw_aff::set_range_tuple(id); + return typed::multi_pw_aff(res); +} + +template +template +typed::multi_pw_aff typed::multi_pw_aff::set_range_tuple(const std::string &id) const +{ + auto res = isl::multi_pw_aff::set_range_tuple(id); + return typed::multi_pw_aff(res); +} + +template +typed::space typed::multi_pw_aff::space() const +{ + auto res = isl::multi_pw_aff::space(); + return typed::space(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff::sub(const typed::multi_pw_aff &multi2) const +{ + auto res = isl::multi_pw_aff::sub(multi2); + return typed::multi_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::multi_pw_aff::sub(const typed::multi_union_pw_aff &multi2) const +{ + auto res = isl::multi_pw_aff::sub(multi2); + return typed::multi_union_pw_aff(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff::sub(const typed::aff &multi2) const +{ + auto res = isl::multi_pw_aff::sub(multi2); + return typed::multi_pw_aff(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff::sub(const typed::multi_aff &multi2) const +{ + auto res = isl::multi_pw_aff::sub(multi2); + return typed::multi_pw_aff(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff::sub(const typed::pw_aff &multi2) const +{ + auto res = isl::multi_pw_aff::sub(multi2); + return typed::multi_pw_aff(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff::sub(const typed::pw_multi_aff &multi2) const +{ + auto res = isl::multi_pw_aff::sub(multi2); + return typed::multi_pw_aff(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff::union_add(const typed::multi_pw_aff &mpa2) const +{ + auto res = isl::multi_pw_aff::union_add(mpa2); + return typed::multi_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::multi_pw_aff::union_add(const typed::multi_union_pw_aff &mupa2) const +{ + auto res = isl::multi_pw_aff::union_add(mupa2); + return typed::multi_union_pw_aff(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff::union_add(const typed::aff &mpa2) const +{ + auto res = isl::multi_pw_aff::union_add(mpa2); + return typed::multi_pw_aff(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff::union_add(const typed::multi_aff &mpa2) const +{ + auto res = isl::multi_pw_aff::union_add(mpa2); + return typed::multi_pw_aff(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff::union_add(const typed::pw_aff &mpa2) const +{ + auto res = isl::multi_pw_aff::union_add(mpa2); + return typed::multi_pw_aff(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff::union_add(const typed::pw_multi_aff &mpa2) const +{ + auto res = isl::multi_pw_aff::union_add(mpa2); + return typed::multi_pw_aff(res); +} + +template +typed::multi_pw_aff, Range>::multi_pw_aff(const typed::aff, Range> &aff) + : isl::multi_pw_aff(aff) +{ +} + +template +typed::multi_pw_aff, Range>::multi_pw_aff(const typed::multi_aff, Range> &ma) + : isl::multi_pw_aff(ma) +{ +} + +template +typed::multi_pw_aff, Range>::multi_pw_aff(const typed::pw_aff, Range> &pa) + : isl::multi_pw_aff(pa) +{ +} + +template +typed::multi_pw_aff, Range>::multi_pw_aff(const typed::space, Range> &space, const typed::pw_aff_list, Anonymous> &list) + : isl::multi_pw_aff(space, list) +{ +} + +template +typed::multi_pw_aff, Range>::multi_pw_aff(const typed::pw_multi_aff, Range> &pma) + : isl::multi_pw_aff(pma) +{ +} + +template +typed::multi_pw_aff, Range>::multi_pw_aff(const isl::ctx &ctx, const std::string &str) + : isl::multi_pw_aff(ctx, str) +{ +} + +template +typed::multi_pw_aff, Range> typed::multi_pw_aff, Range>::add(const typed::multi_pw_aff, Range> &multi2) const +{ + auto res = isl::multi_pw_aff::add(multi2); + return typed::multi_pw_aff, Range>(res); +} + +template +typed::multi_union_pw_aff, Range> typed::multi_pw_aff, Range>::add(const typed::multi_union_pw_aff, Range> &multi2) const +{ + auto res = isl::multi_pw_aff::add(multi2); + return typed::multi_union_pw_aff, Range>(res); +} + +template +typed::multi_pw_aff, Range> typed::multi_pw_aff, Range>::add(const typed::aff, Range> &multi2) const +{ + auto res = isl::multi_pw_aff::add(multi2); + return typed::multi_pw_aff, Range>(res); +} + +template +typed::multi_pw_aff, Range> typed::multi_pw_aff, Range>::add(const typed::multi_aff, Range> &multi2) const +{ + auto res = isl::multi_pw_aff::add(multi2); + return typed::multi_pw_aff, Range>(res); +} + +template +typed::multi_pw_aff, Range> typed::multi_pw_aff, Range>::add(const typed::pw_aff, Range> &multi2) const +{ + auto res = isl::multi_pw_aff::add(multi2); + return typed::multi_pw_aff, Range>(res); +} + +template +typed::multi_pw_aff, Range> typed::multi_pw_aff, Range>::add(const typed::pw_multi_aff, Range> &multi2) const +{ + auto res = isl::multi_pw_aff::add(multi2); + return typed::multi_pw_aff, Range>(res); +} + +template +typed::multi_pw_aff, Range> typed::multi_pw_aff, Range>::add_constant(const typed::multi_val &mv) const +{ + auto res = isl::multi_pw_aff::add_constant(mv); + return typed::multi_pw_aff, Range>(res); +} + +template +typed::multi_pw_aff, Range> typed::multi_pw_aff, Range>::add_constant(const typed::val &v) const +{ + auto res = isl::multi_pw_aff::add_constant(v); + return typed::multi_pw_aff, Range>(res); +} + +template +typed::multi_pw_aff, Range> typed::multi_pw_aff, Range>::add_constant(long v) const +{ + auto res = isl::multi_pw_aff::add_constant(v); + return typed::multi_pw_aff, Range>(res); +} + +template +typed::map, Range> typed::multi_pw_aff, Range>::as_map() const +{ + auto res = isl::multi_pw_aff::as_map(); + return typed::map, Range>(res); +} + +template +typed::multi_aff, Range> typed::multi_pw_aff, Range>::as_multi_aff() const +{ + auto res = isl::multi_pw_aff::as_multi_aff(); + return typed::multi_aff, Range>(res); +} + +template +typed::pw_aff, Anonymous> typed::multi_pw_aff, Range>::at(int pos) const +{ + auto res = isl::multi_pw_aff::at(pos); + return typed::pw_aff, Anonymous>(res); +} + +template +typed::set> typed::multi_pw_aff, Range>::bind(const typed::multi_id &tuple) const +{ + auto res = isl::multi_pw_aff::bind(tuple); + return typed::set>(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff, Range>::bind_domain(const typed::multi_id> &tuple) const +{ + auto res = isl::multi_pw_aff::bind_domain(tuple); + return typed::multi_pw_aff(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff, Range>::bind_domain_wrapped_domain(const typed::multi_id &tuple) const +{ + auto res = isl::multi_pw_aff::bind_domain_wrapped_domain(tuple); + return typed::multi_pw_aff(res); +} + +template +typed::multi_pw_aff, Range> typed::multi_pw_aff, Range>::coalesce() const +{ + auto res = isl::multi_pw_aff::coalesce(); + return typed::multi_pw_aff, Range>(res); +} + +template +typed::set> typed::multi_pw_aff, Range>::domain() const +{ + auto res = isl::multi_pw_aff::domain(); + return typed::set>(res); +} + +template +typed::multi_pw_aff, Range> typed::multi_pw_aff, Range>::domain_reverse() const +{ + auto res = isl::multi_pw_aff::domain_reverse(); + return typed::multi_pw_aff, Range>(res); +} + +template +typed::multi_pw_aff, Range> typed::multi_pw_aff, Range>::gist(const typed::set> &set) const +{ + auto res = isl::multi_pw_aff::gist(set); + return typed::multi_pw_aff, Range>(res); +} + +template +typed::multi_union_pw_aff, Range> typed::multi_pw_aff, Range>::gist(const typed::union_set> &context) const +{ + auto res = isl::multi_pw_aff::gist(context); + return typed::multi_union_pw_aff, Range>(res); +} + +template +typed::multi_pw_aff, Range> typed::multi_pw_aff, Range>::gist(const typed::basic_set> &set) const +{ + auto res = isl::multi_pw_aff::gist(set); + return typed::multi_pw_aff, Range>(res); +} + +template +typed::multi_pw_aff, Range> typed::multi_pw_aff, Range>::gist(const typed::point> &set) const +{ + auto res = isl::multi_pw_aff::gist(set); + return typed::multi_pw_aff, Range>(res); +} + +template +typed::multi_pw_aff, Range> typed::multi_pw_aff, Range>::gist_params(const typed::set<> &set) const +{ + auto res = isl::multi_pw_aff::gist_params(set); + return typed::multi_pw_aff, Range>(res); +} + +template +typed::multi_pw_aff, Range> typed::multi_pw_aff, Range>::gist_params(const typed::basic_set<> &set) const +{ + auto res = isl::multi_pw_aff::gist_params(set); + return typed::multi_pw_aff, Range>(res); +} + +template +typed::multi_pw_aff, Range> typed::multi_pw_aff, Range>::gist_params(const typed::point<> &set) const +{ + auto res = isl::multi_pw_aff::gist_params(set); + return typed::multi_pw_aff, Range>(res); +} + +template +typed::multi_pw_aff, Range> typed::multi_pw_aff, Range>::identity() const +{ + auto res = isl::multi_pw_aff::identity(); + return typed::multi_pw_aff, Range>(res); +} + +template +typed::multi_pw_aff, Range> typed::multi_pw_aff, Range>::intersect_domain(const typed::set> &domain) const +{ + auto res = isl::multi_pw_aff::intersect_domain(domain); + return typed::multi_pw_aff, Range>(res); +} + +template +typed::multi_union_pw_aff, Range> typed::multi_pw_aff, Range>::intersect_domain(const typed::union_set> &uset) const +{ + auto res = isl::multi_pw_aff::intersect_domain(uset); + return typed::multi_union_pw_aff, Range>(res); +} + +template +typed::multi_pw_aff, Range> typed::multi_pw_aff, Range>::intersect_domain(const typed::basic_set> &domain) const +{ + auto res = isl::multi_pw_aff::intersect_domain(domain); + return typed::multi_pw_aff, Range>(res); +} + +template +typed::multi_pw_aff, Range> typed::multi_pw_aff, Range>::intersect_domain(const typed::point> &domain) const +{ + auto res = isl::multi_pw_aff::intersect_domain(domain); + return typed::multi_pw_aff, Range>(res); +} + +template +typed::multi_pw_aff, Range> typed::multi_pw_aff, Range>::intersect_params(const typed::set<> &set) const +{ + auto res = isl::multi_pw_aff::intersect_params(set); + return typed::multi_pw_aff, Range>(res); +} + +template +typed::multi_pw_aff, Range> typed::multi_pw_aff, Range>::intersect_params(const typed::basic_set<> &set) const +{ + auto res = isl::multi_pw_aff::intersect_params(set); + return typed::multi_pw_aff, Range>(res); +} + +template +typed::multi_pw_aff, Range> typed::multi_pw_aff, Range>::intersect_params(const typed::point<> &set) const +{ + auto res = isl::multi_pw_aff::intersect_params(set); + return typed::multi_pw_aff, Range>(res); +} + +template +typed::pw_aff_list, Anonymous> typed::multi_pw_aff, Range>::list() const +{ + auto res = isl::multi_pw_aff::list(); + return typed::pw_aff_list, Anonymous>(res); +} + +template +typed::multi_pw_aff, Range> typed::multi_pw_aff, Range>::max(const typed::multi_pw_aff, Range> &multi2) const +{ + auto res = isl::multi_pw_aff::max(multi2); + return typed::multi_pw_aff, Range>(res); +} + +template +typed::multi_pw_aff, Range> typed::multi_pw_aff, Range>::max(const typed::aff, Range> &multi2) const +{ + auto res = isl::multi_pw_aff::max(multi2); + return typed::multi_pw_aff, Range>(res); +} + +template +typed::multi_pw_aff, Range> typed::multi_pw_aff, Range>::max(const typed::multi_aff, Range> &multi2) const +{ + auto res = isl::multi_pw_aff::max(multi2); + return typed::multi_pw_aff, Range>(res); +} + +template +typed::multi_pw_aff, Range> typed::multi_pw_aff, Range>::max(const typed::pw_aff, Range> &multi2) const +{ + auto res = isl::multi_pw_aff::max(multi2); + return typed::multi_pw_aff, Range>(res); +} + +template +typed::multi_pw_aff, Range> typed::multi_pw_aff, Range>::max(const typed::pw_multi_aff, Range> &multi2) const +{ + auto res = isl::multi_pw_aff::max(multi2); + return typed::multi_pw_aff, Range>(res); +} + +template +typed::multi_val typed::multi_pw_aff, Range>::max_multi_val() const +{ + auto res = isl::multi_pw_aff::max_multi_val(); + return typed::multi_val(res); +} + +template +typed::multi_pw_aff, Range> typed::multi_pw_aff, Range>::min(const typed::multi_pw_aff, Range> &multi2) const +{ + auto res = isl::multi_pw_aff::min(multi2); + return typed::multi_pw_aff, Range>(res); +} + +template +typed::multi_pw_aff, Range> typed::multi_pw_aff, Range>::min(const typed::aff, Range> &multi2) const +{ + auto res = isl::multi_pw_aff::min(multi2); + return typed::multi_pw_aff, Range>(res); +} + +template +typed::multi_pw_aff, Range> typed::multi_pw_aff, Range>::min(const typed::multi_aff, Range> &multi2) const +{ + auto res = isl::multi_pw_aff::min(multi2); + return typed::multi_pw_aff, Range>(res); +} + +template +typed::multi_pw_aff, Range> typed::multi_pw_aff, Range>::min(const typed::pw_aff, Range> &multi2) const +{ + auto res = isl::multi_pw_aff::min(multi2); + return typed::multi_pw_aff, Range>(res); +} + +template +typed::multi_pw_aff, Range> typed::multi_pw_aff, Range>::min(const typed::pw_multi_aff, Range> &multi2) const +{ + auto res = isl::multi_pw_aff::min(multi2); + return typed::multi_pw_aff, Range>(res); +} + +template +typed::multi_val typed::multi_pw_aff, Range>::min_multi_val() const +{ + auto res = isl::multi_pw_aff::min_multi_val(); + return typed::multi_val(res); +} + +template +typed::multi_pw_aff, Range> typed::multi_pw_aff, Range>::neg() const +{ + auto res = isl::multi_pw_aff::neg(); + return typed::multi_pw_aff, Range>(res); +} + +template +template +typed::multi_pw_aff, Arg2>, pair> typed::multi_pw_aff, Range>::product(const typed::multi_pw_aff &multi2) const +{ + auto res = isl::multi_pw_aff::product(multi2); + return typed::multi_pw_aff, Arg2>, pair>(res); +} + +template +template +typed::multi_pw_aff, Arg2>, pair> typed::multi_pw_aff, Range>::product(const typed::aff &multi2) const +{ + auto res = isl::multi_pw_aff::product(multi2); + return typed::multi_pw_aff, Arg2>, pair>(res); +} + +template +template +typed::multi_pw_aff, Arg2>, pair> typed::multi_pw_aff, Range>::product(const typed::multi_aff &multi2) const +{ + auto res = isl::multi_pw_aff::product(multi2); + return typed::multi_pw_aff, Arg2>, pair>(res); +} + +template +template +typed::multi_pw_aff, Arg2>, pair> typed::multi_pw_aff, Range>::product(const typed::pw_aff &multi2) const +{ + auto res = isl::multi_pw_aff::product(multi2); + return typed::multi_pw_aff, Arg2>, pair>(res); +} + +template +template +typed::multi_pw_aff, Arg2>, pair> typed::multi_pw_aff, Range>::product(const typed::pw_multi_aff &multi2) const +{ + auto res = isl::multi_pw_aff::product(multi2); + return typed::multi_pw_aff, Arg2>, pair>(res); +} + +template +template +typed::multi_pw_aff typed::multi_pw_aff, Range>::pullback(const typed::multi_aff> &ma) const +{ + auto res = isl::multi_pw_aff::pullback(ma); + return typed::multi_pw_aff(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff, Range>::pullback(const typed::multi_aff> &ma) const +{ + auto res = isl::multi_pw_aff::pullback(ma); + return typed::multi_pw_aff(res); +} + +template +template +typed::multi_pw_aff typed::multi_pw_aff, Range>::pullback(const typed::multi_pw_aff> &mpa2) const +{ + auto res = isl::multi_pw_aff::pullback(mpa2); + return typed::multi_pw_aff(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff, Range>::pullback(const typed::multi_pw_aff> &mpa2) const +{ + auto res = isl::multi_pw_aff::pullback(mpa2); + return typed::multi_pw_aff(res); +} + +template +template +typed::multi_pw_aff typed::multi_pw_aff, Range>::pullback(const typed::pw_multi_aff> &pma) const +{ + auto res = isl::multi_pw_aff::pullback(pma); + return typed::multi_pw_aff(res); +} + +template +typed::multi_pw_aff typed::multi_pw_aff, Range>::pullback(const typed::pw_multi_aff> &pma) const +{ + auto res = isl::multi_pw_aff::pullback(pma); + return typed::multi_pw_aff(res); +} + +template +template +typed::multi_union_pw_aff typed::multi_pw_aff, Range>::pullback(const typed::union_pw_multi_aff> &upma) const +{ + auto res = isl::multi_pw_aff::pullback(upma); + return typed::multi_union_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::multi_pw_aff, Range>::pullback(const typed::union_pw_multi_aff> &upma) const +{ + auto res = isl::multi_pw_aff::pullback(upma); + return typed::multi_union_pw_aff(res); +} + +template +template +typed::multi_pw_aff, pair> typed::multi_pw_aff, Range>::range_product(const typed::multi_pw_aff, Arg2> &multi2) const +{ + auto res = isl::multi_pw_aff::range_product(multi2); + return typed::multi_pw_aff, pair>(res); +} + +template +template +typed::multi_union_pw_aff, pair> typed::multi_pw_aff, Range>::range_product(const typed::multi_union_pw_aff, Arg2> &multi2) const +{ + auto res = isl::multi_pw_aff::range_product(multi2); + return typed::multi_union_pw_aff, pair>(res); +} + +template +typed::multi_pw_aff, pair> typed::multi_pw_aff, Range>::range_product(const typed::aff, Anonymous> &multi2) const +{ + auto res = isl::multi_pw_aff::range_product(multi2); + return typed::multi_pw_aff, pair>(res); +} + +template +template +typed::multi_pw_aff, pair> typed::multi_pw_aff, Range>::range_product(const typed::multi_aff, Arg2> &multi2) const +{ + auto res = isl::multi_pw_aff::range_product(multi2); + return typed::multi_pw_aff, pair>(res); +} + +template +typed::multi_pw_aff, pair> typed::multi_pw_aff, Range>::range_product(const typed::pw_aff, Anonymous> &multi2) const +{ + auto res = isl::multi_pw_aff::range_product(multi2); + return typed::multi_pw_aff, pair>(res); +} + +template +template +typed::multi_pw_aff, pair> typed::multi_pw_aff, Range>::range_product(const typed::pw_multi_aff, Arg2> &multi2) const +{ + auto res = isl::multi_pw_aff::range_product(multi2); + return typed::multi_pw_aff, pair>(res); +} + +template +typed::multi_pw_aff, Range> typed::multi_pw_aff, Range>::scale(const typed::multi_val &mv) const +{ + auto res = isl::multi_pw_aff::scale(mv); + return typed::multi_pw_aff, Range>(res); +} + +template +typed::multi_pw_aff, Range> typed::multi_pw_aff, Range>::scale(const typed::val &v) const +{ + auto res = isl::multi_pw_aff::scale(v); + return typed::multi_pw_aff, Range>(res); +} + +template +typed::multi_pw_aff, Range> typed::multi_pw_aff, Range>::scale(long v) const +{ + auto res = isl::multi_pw_aff::scale(v); + return typed::multi_pw_aff, Range>(res); +} + +template +typed::multi_pw_aff, Range> typed::multi_pw_aff, Range>::scale_down(const typed::multi_val &mv) const +{ + auto res = isl::multi_pw_aff::scale_down(mv); + return typed::multi_pw_aff, Range>(res); +} + +template +typed::multi_pw_aff, Range> typed::multi_pw_aff, Range>::scale_down(const typed::val &v) const +{ + auto res = isl::multi_pw_aff::scale_down(v); + return typed::multi_pw_aff, Range>(res); +} + +template +typed::multi_pw_aff, Range> typed::multi_pw_aff, Range>::scale_down(long v) const +{ + auto res = isl::multi_pw_aff::scale_down(v); + return typed::multi_pw_aff, Range>(res); +} + +template +typed::multi_pw_aff, Range> typed::multi_pw_aff, Range>::set_at(int pos, const typed::pw_aff, Anonymous> &el) const +{ + auto res = isl::multi_pw_aff::set_at(pos, el); + return typed::multi_pw_aff, Range>(res); +} + +template +typed::multi_union_pw_aff, Range> typed::multi_pw_aff, Range>::set_at(int pos, const typed::union_pw_aff, Anonymous> &el) const +{ + auto res = isl::multi_pw_aff::set_at(pos, el); + return typed::multi_union_pw_aff, Range>(res); +} + +template +template +typed::multi_pw_aff, Arg1> typed::multi_pw_aff, Range>::set_range_tuple(const typed::id &id) const +{ + auto res = isl::multi_pw_aff::set_range_tuple(id); + return typed::multi_pw_aff, Arg1>(res); +} + +template +template +typed::multi_pw_aff, Arg1> typed::multi_pw_aff, Range>::set_range_tuple(const std::string &id) const +{ + auto res = isl::multi_pw_aff::set_range_tuple(id); + return typed::multi_pw_aff, Arg1>(res); +} + +template +typed::space, Range> typed::multi_pw_aff, Range>::space() const +{ + auto res = isl::multi_pw_aff::space(); + return typed::space, Range>(res); +} + +template +typed::multi_pw_aff, Range> typed::multi_pw_aff, Range>::sub(const typed::multi_pw_aff, Range> &multi2) const +{ + auto res = isl::multi_pw_aff::sub(multi2); + return typed::multi_pw_aff, Range>(res); +} + +template +typed::multi_union_pw_aff, Range> typed::multi_pw_aff, Range>::sub(const typed::multi_union_pw_aff, Range> &multi2) const +{ + auto res = isl::multi_pw_aff::sub(multi2); + return typed::multi_union_pw_aff, Range>(res); +} + +template +typed::multi_pw_aff, Range> typed::multi_pw_aff, Range>::sub(const typed::aff, Range> &multi2) const +{ + auto res = isl::multi_pw_aff::sub(multi2); + return typed::multi_pw_aff, Range>(res); +} + +template +typed::multi_pw_aff, Range> typed::multi_pw_aff, Range>::sub(const typed::multi_aff, Range> &multi2) const +{ + auto res = isl::multi_pw_aff::sub(multi2); + return typed::multi_pw_aff, Range>(res); +} + +template +typed::multi_pw_aff, Range> typed::multi_pw_aff, Range>::sub(const typed::pw_aff, Range> &multi2) const +{ + auto res = isl::multi_pw_aff::sub(multi2); + return typed::multi_pw_aff, Range>(res); +} + +template +typed::multi_pw_aff, Range> typed::multi_pw_aff, Range>::sub(const typed::pw_multi_aff, Range> &multi2) const +{ + auto res = isl::multi_pw_aff::sub(multi2); + return typed::multi_pw_aff, Range>(res); +} + +template +typed::multi_pw_aff, Range> typed::multi_pw_aff, Range>::union_add(const typed::multi_pw_aff, Range> &mpa2) const +{ + auto res = isl::multi_pw_aff::union_add(mpa2); + return typed::multi_pw_aff, Range>(res); +} + +template +typed::multi_union_pw_aff, Range> typed::multi_pw_aff, Range>::union_add(const typed::multi_union_pw_aff, Range> &mupa2) const +{ + auto res = isl::multi_pw_aff::union_add(mupa2); + return typed::multi_union_pw_aff, Range>(res); +} + +template +typed::multi_pw_aff, Range> typed::multi_pw_aff, Range>::union_add(const typed::aff, Range> &mpa2) const +{ + auto res = isl::multi_pw_aff::union_add(mpa2); + return typed::multi_pw_aff, Range>(res); +} + +template +typed::multi_pw_aff, Range> typed::multi_pw_aff, Range>::union_add(const typed::multi_aff, Range> &mpa2) const +{ + auto res = isl::multi_pw_aff::union_add(mpa2); + return typed::multi_pw_aff, Range>(res); +} + +template +typed::multi_pw_aff, Range> typed::multi_pw_aff, Range>::union_add(const typed::pw_aff, Range> &mpa2) const +{ + auto res = isl::multi_pw_aff::union_add(mpa2); + return typed::multi_pw_aff, Range>(res); +} + +template +typed::multi_pw_aff, Range> typed::multi_pw_aff, Range>::union_add(const typed::pw_multi_aff, Range> &mpa2) const +{ + auto res = isl::multi_pw_aff::union_add(mpa2); + return typed::multi_pw_aff, Range>(res); +} + +template +typed::multi_union_pw_aff::multi_union_pw_aff(const typed::multi_pw_aff &mpa) + : isl::multi_union_pw_aff(mpa) +{ +} + +template +typed::multi_union_pw_aff::multi_union_pw_aff(const typed::union_pw_aff &upa) + : isl::multi_union_pw_aff(upa) +{ +} + +template +typed::multi_union_pw_aff::multi_union_pw_aff(const typed::space &space, const typed::union_pw_aff_list &list) + : isl::multi_union_pw_aff(space, list) +{ +} + +template +typed::multi_union_pw_aff::multi_union_pw_aff(const isl::ctx &ctx, const std::string &str) + : isl::multi_union_pw_aff(ctx, str) +{ +} + +template +typed::multi_union_pw_aff typed::multi_union_pw_aff::add(const typed::multi_union_pw_aff &multi2) const +{ + auto res = isl::multi_union_pw_aff::add(multi2); + return typed::multi_union_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::multi_union_pw_aff::add(const typed::multi_pw_aff &multi2) const +{ + auto res = isl::multi_union_pw_aff::add(multi2); + return typed::multi_union_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::multi_union_pw_aff::add(const typed::union_pw_aff &multi2) const +{ + auto res = isl::multi_union_pw_aff::add(multi2); + return typed::multi_union_pw_aff(res); +} + +template +typed::union_pw_aff typed::multi_union_pw_aff::at(int pos) const +{ + auto res = isl::multi_union_pw_aff::at(pos); + return typed::union_pw_aff(res); +} + +template +typed::union_set<> typed::multi_union_pw_aff::bind(const typed::multi_id &tuple) const +{ + auto res = isl::multi_union_pw_aff::bind(tuple); + return typed::union_set<>(res); +} + +template +typed::multi_union_pw_aff typed::multi_union_pw_aff::coalesce() const +{ + auto res = isl::multi_union_pw_aff::coalesce(); + return typed::multi_union_pw_aff(res); +} + +template +typed::union_set<> typed::multi_union_pw_aff::domain() const +{ + auto res = isl::multi_union_pw_aff::domain(); + return typed::union_set<>(res); +} + +template +typed::multi_union_pw_aff typed::multi_union_pw_aff::gist(const typed::union_set<> &context) const +{ + auto res = isl::multi_union_pw_aff::gist(context); + return typed::multi_union_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::multi_union_pw_aff::gist(const typed::basic_set<> &context) const +{ + auto res = isl::multi_union_pw_aff::gist(context); + return typed::multi_union_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::multi_union_pw_aff::gist(const typed::point<> &context) const +{ + auto res = isl::multi_union_pw_aff::gist(context); + return typed::multi_union_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::multi_union_pw_aff::gist(const typed::set<> &context) const +{ + auto res = isl::multi_union_pw_aff::gist(context); + return typed::multi_union_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::multi_union_pw_aff::gist_params(const typed::set<> &context) const +{ + auto res = isl::multi_union_pw_aff::gist_params(context); + return typed::multi_union_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::multi_union_pw_aff::gist_params(const typed::basic_set<> &context) const +{ + auto res = isl::multi_union_pw_aff::gist_params(context); + return typed::multi_union_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::multi_union_pw_aff::gist_params(const typed::point<> &context) const +{ + auto res = isl::multi_union_pw_aff::gist_params(context); + return typed::multi_union_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::multi_union_pw_aff::intersect_params(const typed::set<> ¶ms) const +{ + auto res = isl::multi_union_pw_aff::intersect_params(params); + return typed::multi_union_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::multi_union_pw_aff::intersect_params(const typed::basic_set<> ¶ms) const +{ + auto res = isl::multi_union_pw_aff::intersect_params(params); + return typed::multi_union_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::multi_union_pw_aff::intersect_params(const typed::point<> ¶ms) const +{ + auto res = isl::multi_union_pw_aff::intersect_params(params); + return typed::multi_union_pw_aff(res); +} + +template +typed::union_pw_aff_list typed::multi_union_pw_aff::list() const +{ + auto res = isl::multi_union_pw_aff::list(); + return typed::union_pw_aff_list(res); +} + +template +typed::multi_union_pw_aff typed::multi_union_pw_aff::neg() const +{ + auto res = isl::multi_union_pw_aff::neg(); + return typed::multi_union_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::multi_union_pw_aff::scale(const typed::multi_val &mv) const +{ + auto res = isl::multi_union_pw_aff::scale(mv); + return typed::multi_union_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::multi_union_pw_aff::scale(const typed::val &v) const +{ + auto res = isl::multi_union_pw_aff::scale(v); + return typed::multi_union_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::multi_union_pw_aff::scale(long v) const +{ + auto res = isl::multi_union_pw_aff::scale(v); + return typed::multi_union_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::multi_union_pw_aff::scale_down(const typed::multi_val &mv) const +{ + auto res = isl::multi_union_pw_aff::scale_down(mv); + return typed::multi_union_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::multi_union_pw_aff::scale_down(const typed::val &v) const +{ + auto res = isl::multi_union_pw_aff::scale_down(v); + return typed::multi_union_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::multi_union_pw_aff::scale_down(long v) const +{ + auto res = isl::multi_union_pw_aff::scale_down(v); + return typed::multi_union_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::multi_union_pw_aff::set_at(int pos, const typed::union_pw_aff &el) const +{ + auto res = isl::multi_union_pw_aff::set_at(pos, el); + return typed::multi_union_pw_aff(res); +} + +template +template +typed::multi_union_pw_aff typed::multi_union_pw_aff::set_range_tuple(const typed::id &id) const +{ + auto res = isl::multi_union_pw_aff::set_range_tuple(id); + return typed::multi_union_pw_aff(res); +} + +template +template +typed::multi_union_pw_aff typed::multi_union_pw_aff::set_range_tuple(const std::string &id) const +{ + auto res = isl::multi_union_pw_aff::set_range_tuple(id); + return typed::multi_union_pw_aff(res); +} + +template +typed::space typed::multi_union_pw_aff::space() const +{ + auto res = isl::multi_union_pw_aff::space(); + return typed::space(res); +} + +template +typed::multi_union_pw_aff typed::multi_union_pw_aff::sub(const typed::multi_union_pw_aff &multi2) const +{ + auto res = isl::multi_union_pw_aff::sub(multi2); + return typed::multi_union_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::multi_union_pw_aff::sub(const typed::multi_pw_aff &multi2) const +{ + auto res = isl::multi_union_pw_aff::sub(multi2); + return typed::multi_union_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::multi_union_pw_aff::sub(const typed::union_pw_aff &multi2) const +{ + auto res = isl::multi_union_pw_aff::sub(multi2); + return typed::multi_union_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::multi_union_pw_aff::union_add(const typed::multi_union_pw_aff &mupa2) const +{ + auto res = isl::multi_union_pw_aff::union_add(mupa2); + return typed::multi_union_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::multi_union_pw_aff::union_add(const typed::multi_pw_aff &mupa2) const +{ + auto res = isl::multi_union_pw_aff::union_add(mupa2); + return typed::multi_union_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::multi_union_pw_aff::union_add(const typed::union_pw_aff &mupa2) const +{ + auto res = isl::multi_union_pw_aff::union_add(mupa2); + return typed::multi_union_pw_aff(res); +} + +template +typed::multi_union_pw_aff::multi_union_pw_aff(const typed::multi_pw_aff &mpa) + : isl::multi_union_pw_aff(mpa) +{ +} + +template +typed::multi_union_pw_aff::multi_union_pw_aff(const typed::union_pw_aff &upa) + : isl::multi_union_pw_aff(upa) +{ +} + +template +typed::multi_union_pw_aff::multi_union_pw_aff(const typed::space &space, const typed::union_pw_aff_list &list) + : isl::multi_union_pw_aff(space, list) +{ +} + +template +typed::multi_union_pw_aff::multi_union_pw_aff(const isl::ctx &ctx, const std::string &str) + : isl::multi_union_pw_aff(ctx, str) +{ +} + +template +typed::multi_union_pw_aff typed::multi_union_pw_aff::add(const typed::multi_union_pw_aff &multi2) const +{ + auto res = isl::multi_union_pw_aff::add(multi2); + return typed::multi_union_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::multi_union_pw_aff::add(const typed::multi_pw_aff &multi2) const +{ + auto res = isl::multi_union_pw_aff::add(multi2); + return typed::multi_union_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::multi_union_pw_aff::add(const typed::union_pw_aff &multi2) const +{ + auto res = isl::multi_union_pw_aff::add(multi2); + return typed::multi_union_pw_aff(res); +} + +template +typed::union_pw_aff typed::multi_union_pw_aff::at(int pos) const +{ + auto res = isl::multi_union_pw_aff::at(pos); + return typed::union_pw_aff(res); +} + +template +typed::union_set typed::multi_union_pw_aff::bind(const typed::multi_id &tuple) const +{ + auto res = isl::multi_union_pw_aff::bind(tuple); + return typed::union_set(res); +} + +template +typed::multi_union_pw_aff typed::multi_union_pw_aff::coalesce() const +{ + auto res = isl::multi_union_pw_aff::coalesce(); + return typed::multi_union_pw_aff(res); +} + +template +typed::union_set typed::multi_union_pw_aff::domain() const +{ + auto res = isl::multi_union_pw_aff::domain(); + return typed::union_set(res); +} + +template +typed::multi_union_pw_aff typed::multi_union_pw_aff::gist(const typed::union_set &context) const +{ + auto res = isl::multi_union_pw_aff::gist(context); + return typed::multi_union_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::multi_union_pw_aff::gist(const typed::basic_set &context) const +{ + auto res = isl::multi_union_pw_aff::gist(context); + return typed::multi_union_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::multi_union_pw_aff::gist(const typed::point &context) const +{ + auto res = isl::multi_union_pw_aff::gist(context); + return typed::multi_union_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::multi_union_pw_aff::gist(const typed::set &context) const +{ + auto res = isl::multi_union_pw_aff::gist(context); + return typed::multi_union_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::multi_union_pw_aff::gist_params(const typed::set<> &context) const +{ + auto res = isl::multi_union_pw_aff::gist_params(context); + return typed::multi_union_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::multi_union_pw_aff::gist_params(const typed::basic_set<> &context) const +{ + auto res = isl::multi_union_pw_aff::gist_params(context); + return typed::multi_union_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::multi_union_pw_aff::gist_params(const typed::point<> &context) const +{ + auto res = isl::multi_union_pw_aff::gist_params(context); + return typed::multi_union_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::multi_union_pw_aff::intersect_domain(const typed::union_set &uset) const +{ + auto res = isl::multi_union_pw_aff::intersect_domain(uset); + return typed::multi_union_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::multi_union_pw_aff::intersect_domain(const typed::basic_set &uset) const +{ + auto res = isl::multi_union_pw_aff::intersect_domain(uset); + return typed::multi_union_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::multi_union_pw_aff::intersect_domain(const typed::point &uset) const +{ + auto res = isl::multi_union_pw_aff::intersect_domain(uset); + return typed::multi_union_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::multi_union_pw_aff::intersect_domain(const typed::set &uset) const +{ + auto res = isl::multi_union_pw_aff::intersect_domain(uset); + return typed::multi_union_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::multi_union_pw_aff::intersect_params(const typed::set<> ¶ms) const +{ + auto res = isl::multi_union_pw_aff::intersect_params(params); + return typed::multi_union_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::multi_union_pw_aff::intersect_params(const typed::basic_set<> ¶ms) const +{ + auto res = isl::multi_union_pw_aff::intersect_params(params); + return typed::multi_union_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::multi_union_pw_aff::intersect_params(const typed::point<> ¶ms) const +{ + auto res = isl::multi_union_pw_aff::intersect_params(params); + return typed::multi_union_pw_aff(res); +} + +template +typed::union_pw_aff_list typed::multi_union_pw_aff::list() const +{ + auto res = isl::multi_union_pw_aff::list(); + return typed::union_pw_aff_list(res); +} + +template +typed::multi_union_pw_aff typed::multi_union_pw_aff::neg() const +{ + auto res = isl::multi_union_pw_aff::neg(); + return typed::multi_union_pw_aff(res); +} + +template +template +typed::multi_union_pw_aff typed::multi_union_pw_aff::pullback(const typed::union_pw_multi_aff &upma) const +{ + auto res = isl::multi_union_pw_aff::pullback(upma); + return typed::multi_union_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::multi_union_pw_aff::pullback(const typed::union_pw_multi_aff &upma) const +{ + auto res = isl::multi_union_pw_aff::pullback(upma); + return typed::multi_union_pw_aff(res); +} + +template +template +typed::multi_union_pw_aff typed::multi_union_pw_aff::pullback(const typed::multi_aff &upma) const +{ + auto res = isl::multi_union_pw_aff::pullback(upma); + return typed::multi_union_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::multi_union_pw_aff::pullback(const typed::multi_aff &upma) const +{ + auto res = isl::multi_union_pw_aff::pullback(upma); + return typed::multi_union_pw_aff(res); +} + +template +template +typed::multi_union_pw_aff typed::multi_union_pw_aff::pullback(const typed::pw_multi_aff &upma) const +{ + auto res = isl::multi_union_pw_aff::pullback(upma); + return typed::multi_union_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::multi_union_pw_aff::pullback(const typed::pw_multi_aff &upma) const +{ + auto res = isl::multi_union_pw_aff::pullback(upma); + return typed::multi_union_pw_aff(res); +} + +template +template +typed::multi_union_pw_aff typed::multi_union_pw_aff::pullback(const typed::union_pw_aff &upma) const +{ + auto res = isl::multi_union_pw_aff::pullback(upma); + return typed::multi_union_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::multi_union_pw_aff::pullback(const typed::union_pw_aff &upma) const +{ + auto res = isl::multi_union_pw_aff::pullback(upma); + return typed::multi_union_pw_aff(res); +} + +template +template +typed::multi_union_pw_aff> typed::multi_union_pw_aff::range_product(const typed::multi_union_pw_aff &multi2) const +{ + auto res = isl::multi_union_pw_aff::range_product(multi2); + return typed::multi_union_pw_aff>(res); +} + +template +template +typed::multi_union_pw_aff> typed::multi_union_pw_aff::range_product(const typed::multi_pw_aff &multi2) const +{ + auto res = isl::multi_union_pw_aff::range_product(multi2); + return typed::multi_union_pw_aff>(res); +} + +template +typed::multi_union_pw_aff> typed::multi_union_pw_aff::range_product(const typed::union_pw_aff &multi2) const +{ + auto res = isl::multi_union_pw_aff::range_product(multi2); + return typed::multi_union_pw_aff>(res); +} + +template +typed::multi_union_pw_aff typed::multi_union_pw_aff::scale(const typed::multi_val &mv) const +{ + auto res = isl::multi_union_pw_aff::scale(mv); + return typed::multi_union_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::multi_union_pw_aff::scale(const typed::val &v) const +{ + auto res = isl::multi_union_pw_aff::scale(v); + return typed::multi_union_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::multi_union_pw_aff::scale(long v) const +{ + auto res = isl::multi_union_pw_aff::scale(v); + return typed::multi_union_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::multi_union_pw_aff::scale_down(const typed::multi_val &mv) const +{ + auto res = isl::multi_union_pw_aff::scale_down(mv); + return typed::multi_union_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::multi_union_pw_aff::scale_down(const typed::val &v) const +{ + auto res = isl::multi_union_pw_aff::scale_down(v); + return typed::multi_union_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::multi_union_pw_aff::scale_down(long v) const +{ + auto res = isl::multi_union_pw_aff::scale_down(v); + return typed::multi_union_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::multi_union_pw_aff::set_at(int pos, const typed::union_pw_aff &el) const +{ + auto res = isl::multi_union_pw_aff::set_at(pos, el); + return typed::multi_union_pw_aff(res); +} + +template +template +typed::multi_union_pw_aff typed::multi_union_pw_aff::set_range_tuple(const typed::id &id) const +{ + auto res = isl::multi_union_pw_aff::set_range_tuple(id); + return typed::multi_union_pw_aff(res); +} + +template +template +typed::multi_union_pw_aff typed::multi_union_pw_aff::set_range_tuple(const std::string &id) const +{ + auto res = isl::multi_union_pw_aff::set_range_tuple(id); + return typed::multi_union_pw_aff(res); +} + +template +typed::space typed::multi_union_pw_aff::space() const +{ + auto res = isl::multi_union_pw_aff::space(); + return typed::space(res); +} + +template +typed::multi_union_pw_aff typed::multi_union_pw_aff::sub(const typed::multi_union_pw_aff &multi2) const +{ + auto res = isl::multi_union_pw_aff::sub(multi2); + return typed::multi_union_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::multi_union_pw_aff::sub(const typed::multi_pw_aff &multi2) const +{ + auto res = isl::multi_union_pw_aff::sub(multi2); + return typed::multi_union_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::multi_union_pw_aff::sub(const typed::union_pw_aff &multi2) const +{ + auto res = isl::multi_union_pw_aff::sub(multi2); + return typed::multi_union_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::multi_union_pw_aff::union_add(const typed::multi_union_pw_aff &mupa2) const +{ + auto res = isl::multi_union_pw_aff::union_add(mupa2); + return typed::multi_union_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::multi_union_pw_aff::union_add(const typed::multi_pw_aff &mupa2) const +{ + auto res = isl::multi_union_pw_aff::union_add(mupa2); + return typed::multi_union_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::multi_union_pw_aff::union_add(const typed::union_pw_aff &mupa2) const +{ + auto res = isl::multi_union_pw_aff::union_add(mupa2); + return typed::multi_union_pw_aff(res); +} + +template +typed::multi_val::multi_val(const typed::space &space, const typed::val_list &list) + : isl::multi_val(space, list) +{ +} + +template +typed::multi_val::multi_val(const isl::ctx &ctx, const std::string &str) + : isl::multi_val(ctx, str) +{ +} + +template +typed::multi_val typed::multi_val::add(const typed::multi_val &multi2) const +{ + auto res = isl::multi_val::add(multi2); + return typed::multi_val(res); +} + +template +typed::multi_val typed::multi_val::add(const typed::val &v) const +{ + auto res = isl::multi_val::add(v); + return typed::multi_val(res); +} + +template +typed::multi_val typed::multi_val::add(long v) const +{ + auto res = isl::multi_val::add(v); + return typed::multi_val(res); +} + +template +typed::val typed::multi_val::at(int pos) const +{ + auto res = isl::multi_val::at(pos); + return typed::val(res); +} + +template +typed::val_list typed::multi_val::list() const +{ + auto res = isl::multi_val::list(); + return typed::val_list(res); +} + +template +typed::multi_val typed::multi_val::max(const typed::multi_val &multi2) const +{ + auto res = isl::multi_val::max(multi2); + return typed::multi_val(res); +} + +template +typed::multi_val typed::multi_val::min(const typed::multi_val &multi2) const +{ + auto res = isl::multi_val::min(multi2); + return typed::multi_val(res); +} + +template +typed::multi_val typed::multi_val::neg() const +{ + auto res = isl::multi_val::neg(); + return typed::multi_val(res); +} + +template +template +typed::multi_val> typed::multi_val::product(const typed::multi_val &multi2) const +{ + auto res = isl::multi_val::product(multi2); + return typed::multi_val>(res); +} + +template +typed::multi_val typed::multi_val::scale(const typed::multi_val &mv) const +{ + auto res = isl::multi_val::scale(mv); + return typed::multi_val(res); +} + +template +typed::multi_val typed::multi_val::scale(const typed::val &v) const +{ + auto res = isl::multi_val::scale(v); + return typed::multi_val(res); +} + +template +typed::multi_val typed::multi_val::scale(long v) const +{ + auto res = isl::multi_val::scale(v); + return typed::multi_val(res); +} + +template +typed::multi_val typed::multi_val::scale_down(const typed::multi_val &mv) const +{ + auto res = isl::multi_val::scale_down(mv); + return typed::multi_val(res); +} + +template +typed::multi_val typed::multi_val::scale_down(const typed::val &v) const +{ + auto res = isl::multi_val::scale_down(v); + return typed::multi_val(res); +} + +template +typed::multi_val typed::multi_val::scale_down(long v) const +{ + auto res = isl::multi_val::scale_down(v); + return typed::multi_val(res); +} + +template +typed::multi_val typed::multi_val::set_at(int pos, const typed::val &el) const +{ + auto res = isl::multi_val::set_at(pos, el); + return typed::multi_val(res); +} + +template +typed::multi_val typed::multi_val::set_at(int pos, long el) const +{ + auto res = isl::multi_val::set_at(pos, el); + return typed::multi_val(res); +} + +template +template +typed::multi_val typed::multi_val::set_range_tuple(const typed::id &id) const +{ + auto res = isl::multi_val::set_range_tuple(id); + return typed::multi_val(res); +} + +template +template +typed::multi_val typed::multi_val::set_range_tuple(const std::string &id) const +{ + auto res = isl::multi_val::set_range_tuple(id); + return typed::multi_val(res); +} + +template +typed::space typed::multi_val::space() const +{ + auto res = isl::multi_val::space(); + return typed::space(res); +} + +template +typed::multi_val typed::multi_val::sub(const typed::multi_val &multi2) const +{ + auto res = isl::multi_val::sub(multi2); + return typed::multi_val(res); +} + +typed::set<> typed::point<>::coalesce() const +{ + auto res = isl::point::coalesce(); + return typed::set<>(res); +} + +typed::basic_set<> typed::point<>::detect_equalities() const +{ + auto res = isl::point::detect_equalities(); + return typed::basic_set<>(res); +} + +typed::set<> typed::point<>::drop_unused_params() const +{ + auto res = isl::point::drop_unused_params(); + return typed::set<>(res); +} + +bool typed::point<>::every_set(const std::function)> &test) const +{ + auto lambda_test = [&] (isl::set arg0) { + return test(typed::set<>(arg0)); + }; + return isl::point::every_set(lambda_test); +} + +typed::set<> typed::point<>::extract_set(const typed::space<> &space) const +{ + auto res = isl::point::extract_set(space); + return typed::set<>(res); +} + +void typed::point<>::foreach_basic_set(const std::function)> &fn) const +{ + auto lambda_fn = [&] (isl::basic_set arg0) { + return fn(typed::basic_set<>(arg0)); + }; + return isl::point::foreach_basic_set(lambda_fn); +} + +void typed::point<>::foreach_point(const std::function)> &fn) const +{ + auto lambda_fn = [&] (isl::point arg0) { + return fn(typed::point<>(arg0)); + }; + return isl::point::foreach_point(lambda_fn); +} + +void typed::point<>::foreach_set(const std::function)> &fn) const +{ + auto lambda_fn = [&] (isl::set arg0) { + return fn(typed::set<>(arg0)); + }; + return isl::point::foreach_set(lambda_fn); +} + +typed::basic_set<> typed::point<>::gist(const typed::basic_set<> &context) const +{ + auto res = isl::point::gist(context); + return typed::basic_set<>(res); +} + +typed::set<> typed::point<>::gist(const typed::set<> &context) const +{ + auto res = isl::point::gist(context); + return typed::set<>(res); +} + +typed::union_set<> typed::point<>::gist(const typed::union_set<> &context) const +{ + auto res = isl::point::gist(context); + return typed::union_set<>(res); +} + +typed::pw_aff typed::point<>::indicator_function() const +{ + auto res = isl::point::indicator_function(); + return typed::pw_aff(res); +} + +typed::basic_set<> typed::point<>::intersect(const typed::basic_set<> &bset2) const +{ + auto res = isl::point::intersect(bset2); + return typed::basic_set<>(res); +} + +typed::set<> typed::point<>::intersect(const typed::set<> &set2) const +{ + auto res = isl::point::intersect(set2); + return typed::set<>(res); +} + +typed::union_set<> typed::point<>::intersect(const typed::union_set<> &uset2) const +{ + auto res = isl::point::intersect(uset2); + return typed::union_set<>(res); +} + +typed::pw_aff typed::point<>::param_pw_aff_on_domain(const typed::id &id) const +{ + auto res = isl::point::param_pw_aff_on_domain(id); + return typed::pw_aff(res); +} + +typed::pw_aff typed::point<>::param_pw_aff_on_domain(const std::string &id) const +{ + auto res = isl::point::param_pw_aff_on_domain(id); + return typed::pw_aff(res); +} + +typed::set<> typed::point<>::project_out_all_params() const +{ + auto res = isl::point::project_out_all_params(); + return typed::set<>(res); +} + +typed::set<> typed::point<>::project_out_param(const typed::id &id) const +{ + auto res = isl::point::project_out_param(id); + return typed::set<>(res); +} + +typed::set<> typed::point<>::project_out_param(const std::string &id) const +{ + auto res = isl::point::project_out_param(id); + return typed::set<>(res); +} + +typed::set<> typed::point<>::project_out_param(const typed::id_list &list) const +{ + auto res = isl::point::project_out_param(list); + return typed::set<>(res); +} + +typed::pw_aff typed::point<>::pw_aff_on_domain(const typed::val &v) const +{ + auto res = isl::point::pw_aff_on_domain(v); + return typed::pw_aff(res); +} + +typed::pw_aff typed::point<>::pw_aff_on_domain(long v) const +{ + auto res = isl::point::pw_aff_on_domain(v); + return typed::pw_aff(res); +} + +template +typed::pw_multi_aff typed::point<>::pw_multi_aff_on_domain(const typed::multi_val &mv) const +{ + auto res = isl::point::pw_multi_aff_on_domain(mv); + return typed::pw_multi_aff(res); +} + +typed::set_list<> typed::point<>::set_list() const +{ + auto res = isl::point::set_list(); + return typed::set_list<>(res); +} + +typed::space<> typed::point<>::space() const +{ + auto res = isl::point::space(); + return typed::space<>(res); +} + +typed::set<> typed::point<>::subtract(const typed::set<> &set2) const +{ + auto res = isl::point::subtract(set2); + return typed::set<>(res); +} + +typed::union_set<> typed::point<>::subtract(const typed::union_set<> &uset2) const +{ + auto res = isl::point::subtract(uset2); + return typed::union_set<>(res); +} + +typed::set<> typed::point<>::to_set() const +{ + auto res = isl::point::to_set(); + return typed::set<>(res); +} + +typed::union_set<> typed::point<>::to_union_set() const +{ + auto res = isl::point::to_union_set(); + return typed::union_set<>(res); +} + +template +typed::set typed::point<>::unbind_params(const typed::multi_id &tuple) const +{ + auto res = isl::point::unbind_params(tuple); + return typed::set(res); +} + +typed::set<> typed::point<>::unite(const typed::basic_set<> &bset2) const +{ + auto res = isl::point::unite(bset2); + return typed::set<>(res); +} + +typed::set<> typed::point<>::unite(const typed::set<> &set2) const +{ + auto res = isl::point::unite(set2); + return typed::set<>(res); +} + +typed::union_set<> typed::point<>::unite(const typed::union_set<> &uset2) const +{ + auto res = isl::point::unite(uset2); + return typed::union_set<>(res); +} + +template +template +typed::basic_set typed::point::apply(const typed::basic_map &bmap) const +{ + auto res = isl::point::apply(bmap); + return typed::basic_set(res); +} + +template +template +typed::set typed::point::apply(const typed::map &map) const +{ + auto res = isl::point::apply(map); + return typed::set(res); +} + +template +template +typed::union_set typed::point::apply(const typed::union_map &umap) const +{ + auto res = isl::point::apply(umap); + return typed::union_set(res); +} + +template +typed::pw_multi_aff typed::point::as_pw_multi_aff() const +{ + auto res = isl::point::as_pw_multi_aff(); + return typed::pw_multi_aff(res); +} + +template +typed::set typed::point::as_set() const +{ + auto res = isl::point::as_set(); + return typed::set(res); +} + +template +typed::set<> typed::point::bind(const typed::multi_id &tuple) const +{ + auto res = isl::point::bind(tuple); + return typed::set<>(res); +} + +template +typed::set typed::point::coalesce() const +{ + auto res = isl::point::coalesce(); + return typed::set(res); +} + +template +typed::basic_set typed::point::detect_equalities() const +{ + auto res = isl::point::detect_equalities(); + return typed::basic_set(res); +} + +template +typed::set typed::point::drop_unused_params() const +{ + auto res = isl::point::drop_unused_params(); + return typed::set(res); +} + +template +bool typed::point::every_set(const std::function)> &test) const +{ + auto lambda_test = [&] (isl::set arg0) { + return test(typed::set(arg0)); + }; + return isl::point::every_set(lambda_test); +} + +template +typed::set typed::point::extract_set(const typed::space &space) const +{ + auto res = isl::point::extract_set(space); + return typed::set(res); +} + +template +void typed::point::foreach_basic_set(const std::function)> &fn) const +{ + auto lambda_fn = [&] (isl::basic_set arg0) { + return fn(typed::basic_set(arg0)); + }; + return isl::point::foreach_basic_set(lambda_fn); +} + +template +void typed::point::foreach_point(const std::function)> &fn) const +{ + auto lambda_fn = [&] (isl::point arg0) { + return fn(typed::point(arg0)); + }; + return isl::point::foreach_point(lambda_fn); +} + +template +void typed::point::foreach_set(const std::function)> &fn) const +{ + auto lambda_fn = [&] (isl::set arg0) { + return fn(typed::set(arg0)); + }; + return isl::point::foreach_set(lambda_fn); +} + +template +typed::basic_set typed::point::gist(const typed::basic_set &context) const +{ + auto res = isl::point::gist(context); + return typed::basic_set(res); +} + +template +typed::set typed::point::gist(const typed::set &context) const +{ + auto res = isl::point::gist(context); + return typed::set(res); +} + +template +typed::union_set typed::point::gist(const typed::union_set &context) const +{ + auto res = isl::point::gist(context); + return typed::union_set(res); +} + +template +typed::set typed::point::gist_params(const typed::set<> &context) const +{ + auto res = isl::point::gist_params(context); + return typed::set(res); +} + +template +typed::map typed::point::identity() const +{ + auto res = isl::point::identity(); + return typed::map(res); +} + +template +typed::pw_aff typed::point::indicator_function() const +{ + auto res = isl::point::indicator_function(); + return typed::pw_aff(res); +} + +template +template +typed::map typed::point::insert_domain(const typed::space &domain) const +{ + auto res = isl::point::insert_domain(domain); + return typed::map(res); +} + +template +typed::basic_set typed::point::intersect(const typed::basic_set &bset2) const +{ + auto res = isl::point::intersect(bset2); + return typed::basic_set(res); +} + +template +typed::set typed::point::intersect(const typed::set &set2) const +{ + auto res = isl::point::intersect(set2); + return typed::set(res); +} + +template +typed::union_set typed::point::intersect(const typed::union_set &uset2) const +{ + auto res = isl::point::intersect(uset2); + return typed::union_set(res); +} + +template +typed::basic_set typed::point::intersect_params(const typed::basic_set<> &bset2) const +{ + auto res = isl::point::intersect_params(bset2); + return typed::basic_set(res); +} + +template +typed::set typed::point::intersect_params(const typed::set<> ¶ms) const +{ + auto res = isl::point::intersect_params(params); + return typed::set(res); +} + +template +typed::fixed_box typed::point::lattice_tile() const +{ + auto res = isl::point::lattice_tile(); + return typed::fixed_box(res); +} + +template +typed::set typed::point::lexmax() const +{ + auto res = isl::point::lexmax(); + return typed::set(res); +} + +template +typed::pw_multi_aff typed::point::lexmax_pw_multi_aff() const +{ + auto res = isl::point::lexmax_pw_multi_aff(); + return typed::pw_multi_aff(res); +} + +template +typed::set typed::point::lexmin() const +{ + auto res = isl::point::lexmin(); + return typed::set(res); +} + +template +typed::pw_multi_aff typed::point::lexmin_pw_multi_aff() const +{ + auto res = isl::point::lexmin_pw_multi_aff(); + return typed::pw_multi_aff(res); +} + +template +typed::set typed::point::lower_bound(const typed::multi_pw_aff &lower) const +{ + auto res = isl::point::lower_bound(lower); + return typed::set(res); +} + +template +typed::set typed::point::lower_bound(const typed::multi_val &lower) const +{ + auto res = isl::point::lower_bound(lower); + return typed::set(res); +} + +template +typed::multi_pw_aff typed::point::max_multi_pw_aff() const +{ + auto res = isl::point::max_multi_pw_aff(); + return typed::multi_pw_aff(res); +} + +template +typed::multi_pw_aff typed::point::min_multi_pw_aff() const +{ + auto res = isl::point::min_multi_pw_aff(); + return typed::multi_pw_aff(res); +} + +template +typed::multi_val typed::point::multi_val() const +{ + auto res = isl::point::multi_val(); + return typed::multi_val(res); +} + +template +typed::pw_aff typed::point::param_pw_aff_on_domain(const typed::id &id) const +{ + auto res = isl::point::param_pw_aff_on_domain(id); + return typed::pw_aff(res); +} + +template +typed::pw_aff typed::point::param_pw_aff_on_domain(const std::string &id) const +{ + auto res = isl::point::param_pw_aff_on_domain(id); + return typed::pw_aff(res); +} + +template +typed::basic_set<> typed::point::params() const +{ + auto res = isl::point::params(); + return typed::basic_set<>(res); +} + +template +typed::multi_val typed::point::plain_multi_val_if_fixed() const +{ + auto res = isl::point::plain_multi_val_if_fixed(); + return typed::multi_val(res); +} + +template +template +typed::set typed::point::preimage(const typed::multi_aff &ma) const +{ + auto res = isl::point::preimage(ma); + return typed::set(res); +} + +template +template +typed::set typed::point::preimage(const typed::multi_pw_aff &mpa) const +{ + auto res = isl::point::preimage(mpa); + return typed::set(res); +} + +template +template +typed::set typed::point::preimage(const typed::pw_multi_aff &pma) const +{ + auto res = isl::point::preimage(pma); + return typed::set(res); +} + +template +template +typed::union_set typed::point::preimage(const typed::union_pw_multi_aff &upma) const +{ + auto res = isl::point::preimage(upma); + return typed::union_set(res); +} + +template +template +typed::set> typed::point::product(const typed::set &set2) const +{ + auto res = isl::point::product(set2); + return typed::set>(res); +} + +template +typed::set typed::point::project_out_all_params() const +{ + auto res = isl::point::project_out_all_params(); + return typed::set(res); +} + +template +typed::set typed::point::project_out_param(const typed::id &id) const +{ + auto res = isl::point::project_out_param(id); + return typed::set(res); +} + +template +typed::set typed::point::project_out_param(const std::string &id) const +{ + auto res = isl::point::project_out_param(id); + return typed::set(res); +} + +template +typed::set typed::point::project_out_param(const typed::id_list &list) const +{ + auto res = isl::point::project_out_param(list); + return typed::set(res); +} + +template +typed::pw_aff typed::point::pw_aff_on_domain(const typed::val &v) const +{ + auto res = isl::point::pw_aff_on_domain(v); + return typed::pw_aff(res); +} + +template +typed::pw_aff typed::point::pw_aff_on_domain(long v) const +{ + auto res = isl::point::pw_aff_on_domain(v); + return typed::pw_aff(res); +} + +template +template +typed::pw_multi_aff typed::point::pw_multi_aff_on_domain(const typed::multi_val &mv) const +{ + auto res = isl::point::pw_multi_aff_on_domain(mv); + return typed::pw_multi_aff(res); +} + +template +typed::set_list typed::point::set_list() const +{ + auto res = isl::point::set_list(); + return typed::set_list(res); +} + +template +typed::fixed_box typed::point::simple_fixed_box_hull() const +{ + auto res = isl::point::simple_fixed_box_hull(); + return typed::fixed_box(res); +} + +template +typed::space typed::point::space() const +{ + auto res = isl::point::space(); + return typed::space(res); +} + +template +typed::set typed::point::subtract(const typed::set &set2) const +{ + auto res = isl::point::subtract(set2); + return typed::set(res); +} + +template +typed::union_set typed::point::subtract(const typed::union_set &uset2) const +{ + auto res = isl::point::subtract(uset2); + return typed::union_set(res); +} + +template +typed::set typed::point::to_set() const +{ + auto res = isl::point::to_set(); + return typed::set(res); +} + +template +typed::union_set typed::point::to_union_set() const +{ + auto res = isl::point::to_union_set(); + return typed::union_set(res); +} + +template +typed::map typed::point::translation() const +{ + auto res = isl::point::translation(); + return typed::map(res); +} + +template +template +typed::map typed::point::unbind_params_insert_domain(const typed::multi_id &domain) const +{ + auto res = isl::point::unbind_params_insert_domain(domain); + return typed::map(res); +} + +template +typed::set typed::point::unite(const typed::basic_set &bset2) const +{ + auto res = isl::point::unite(bset2); + return typed::set(res); +} + +template +typed::set typed::point::unite(const typed::set &set2) const +{ + auto res = isl::point::unite(set2); + return typed::set(res); +} + +template +typed::union_set typed::point::unite(const typed::union_set &uset2) const +{ + auto res = isl::point::unite(uset2); + return typed::union_set(res); +} + +template +typed::set typed::point::upper_bound(const typed::multi_pw_aff &upper) const +{ + auto res = isl::point::upper_bound(upper); + return typed::set(res); +} + +template +typed::set typed::point::upper_bound(const typed::multi_val &upper) const +{ + auto res = isl::point::upper_bound(upper); + return typed::set(res); +} + +template +template +typed::basic_set typed::point>::apply(const typed::basic_map, Arg2> &bmap) const +{ + auto res = isl::point::apply(bmap); + return typed::basic_set(res); +} + +template +template +typed::set typed::point>::apply(const typed::map, Arg2> &map) const +{ + auto res = isl::point::apply(map); + return typed::set(res); +} + +template +template +typed::union_set typed::point>::apply(const typed::union_map, Arg2> &umap) const +{ + auto res = isl::point::apply(umap); + return typed::union_set(res); +} + +template +typed::pw_multi_aff> typed::point>::as_pw_multi_aff() const +{ + auto res = isl::point::as_pw_multi_aff(); + return typed::pw_multi_aff>(res); +} + +template +typed::set> typed::point>::as_set() const +{ + auto res = isl::point::as_set(); + return typed::set>(res); +} + +template +typed::set<> typed::point>::bind(const typed::multi_id> &tuple) const +{ + auto res = isl::point::bind(tuple); + return typed::set<>(res); +} + +template +typed::set> typed::point>::coalesce() const +{ + auto res = isl::point::coalesce(); + return typed::set>(res); +} + +template +typed::basic_set> typed::point>::detect_equalities() const +{ + auto res = isl::point::detect_equalities(); + return typed::basic_set>(res); +} + +template +typed::set> typed::point>::drop_unused_params() const +{ + auto res = isl::point::drop_unused_params(); + return typed::set>(res); +} + +template +bool typed::point>::every_set(const std::function>)> &test) const +{ + auto lambda_test = [&] (isl::set arg0) { + return test(typed::set>(arg0)); + }; + return isl::point::every_set(lambda_test); +} + +template +typed::set> typed::point>::extract_set(const typed::space> &space) const +{ + auto res = isl::point::extract_set(space); + return typed::set>(res); +} + +template +void typed::point>::foreach_basic_set(const std::function>)> &fn) const +{ + auto lambda_fn = [&] (isl::basic_set arg0) { + return fn(typed::basic_set>(arg0)); + }; + return isl::point::foreach_basic_set(lambda_fn); +} + +template +void typed::point>::foreach_point(const std::function>)> &fn) const +{ + auto lambda_fn = [&] (isl::point arg0) { + return fn(typed::point>(arg0)); + }; + return isl::point::foreach_point(lambda_fn); +} + +template +void typed::point>::foreach_set(const std::function>)> &fn) const +{ + auto lambda_fn = [&] (isl::set arg0) { + return fn(typed::set>(arg0)); + }; + return isl::point::foreach_set(lambda_fn); +} + +template +typed::basic_set> typed::point>::gist(const typed::basic_set> &context) const +{ + auto res = isl::point::gist(context); + return typed::basic_set>(res); +} + +template +typed::set> typed::point>::gist(const typed::set> &context) const +{ + auto res = isl::point::gist(context); + return typed::set>(res); +} + +template +typed::union_set> typed::point>::gist(const typed::union_set> &context) const +{ + auto res = isl::point::gist(context); + return typed::union_set>(res); +} + +template +typed::set> typed::point>::gist_params(const typed::set<> &context) const +{ + auto res = isl::point::gist_params(context); + return typed::set>(res); +} + +template +typed::map, pair> typed::point>::identity() const +{ + auto res = isl::point::identity(); + return typed::map, pair>(res); +} + +template +typed::pw_aff, Anonymous> typed::point>::indicator_function() const +{ + auto res = isl::point::indicator_function(); + return typed::pw_aff, Anonymous>(res); +} + +template +template +typed::map> typed::point>::insert_domain(const typed::space &domain) const +{ + auto res = isl::point::insert_domain(domain); + return typed::map>(res); +} + +template +typed::basic_set> typed::point>::intersect(const typed::basic_set> &bset2) const +{ + auto res = isl::point::intersect(bset2); + return typed::basic_set>(res); +} + +template +typed::set> typed::point>::intersect(const typed::set> &set2) const +{ + auto res = isl::point::intersect(set2); + return typed::set>(res); +} + +template +typed::union_set> typed::point>::intersect(const typed::union_set> &uset2) const +{ + auto res = isl::point::intersect(uset2); + return typed::union_set>(res); +} + +template +typed::basic_set> typed::point>::intersect_params(const typed::basic_set<> &bset2) const +{ + auto res = isl::point::intersect_params(bset2); + return typed::basic_set>(res); +} + +template +typed::set> typed::point>::intersect_params(const typed::set<> ¶ms) const +{ + auto res = isl::point::intersect_params(params); + return typed::set>(res); +} + +template +typed::fixed_box> typed::point>::lattice_tile() const +{ + auto res = isl::point::lattice_tile(); + return typed::fixed_box>(res); +} + +template +typed::set> typed::point>::lexmax() const +{ + auto res = isl::point::lexmax(); + return typed::set>(res); +} + +template +typed::pw_multi_aff> typed::point>::lexmax_pw_multi_aff() const +{ + auto res = isl::point::lexmax_pw_multi_aff(); + return typed::pw_multi_aff>(res); +} + +template +typed::set> typed::point>::lexmin() const +{ + auto res = isl::point::lexmin(); + return typed::set>(res); +} + +template +typed::pw_multi_aff> typed::point>::lexmin_pw_multi_aff() const +{ + auto res = isl::point::lexmin_pw_multi_aff(); + return typed::pw_multi_aff>(res); +} + +template +typed::set> typed::point>::lower_bound(const typed::multi_pw_aff> &lower) const +{ + auto res = isl::point::lower_bound(lower); + return typed::set>(res); +} + +template +typed::set> typed::point>::lower_bound(const typed::multi_val> &lower) const +{ + auto res = isl::point::lower_bound(lower); + return typed::set>(res); +} + +template +typed::multi_pw_aff> typed::point>::max_multi_pw_aff() const +{ + auto res = isl::point::max_multi_pw_aff(); + return typed::multi_pw_aff>(res); +} + +template +typed::multi_pw_aff> typed::point>::min_multi_pw_aff() const +{ + auto res = isl::point::min_multi_pw_aff(); + return typed::multi_pw_aff>(res); +} + +template +typed::multi_val> typed::point>::multi_val() const +{ + auto res = isl::point::multi_val(); + return typed::multi_val>(res); +} + +template +typed::pw_aff, Anonymous> typed::point>::param_pw_aff_on_domain(const typed::id &id) const +{ + auto res = isl::point::param_pw_aff_on_domain(id); + return typed::pw_aff, Anonymous>(res); +} + +template +typed::pw_aff, Anonymous> typed::point>::param_pw_aff_on_domain(const std::string &id) const +{ + auto res = isl::point::param_pw_aff_on_domain(id); + return typed::pw_aff, Anonymous>(res); +} + +template +typed::basic_set<> typed::point>::params() const +{ + auto res = isl::point::params(); + return typed::basic_set<>(res); +} + +template +typed::multi_val> typed::point>::plain_multi_val_if_fixed() const +{ + auto res = isl::point::plain_multi_val_if_fixed(); + return typed::multi_val>(res); +} + +template +template +typed::set typed::point>::preimage(const typed::multi_aff> &ma) const +{ + auto res = isl::point::preimage(ma); + return typed::set(res); +} + +template +template +typed::set typed::point>::preimage(const typed::multi_pw_aff> &mpa) const +{ + auto res = isl::point::preimage(mpa); + return typed::set(res); +} + +template +template +typed::set typed::point>::preimage(const typed::pw_multi_aff> &pma) const +{ + auto res = isl::point::preimage(pma); + return typed::set(res); +} + +template +template +typed::union_set typed::point>::preimage(const typed::union_pw_multi_aff> &upma) const +{ + auto res = isl::point::preimage(upma); + return typed::union_set(res); +} + +template +template +typed::set, Arg2>> typed::point>::product(const typed::set &set2) const +{ + auto res = isl::point::product(set2); + return typed::set, Arg2>>(res); +} + +template +typed::set> typed::point>::project_out_all_params() const +{ + auto res = isl::point::project_out_all_params(); + return typed::set>(res); +} + +template +typed::set> typed::point>::project_out_param(const typed::id &id) const +{ + auto res = isl::point::project_out_param(id); + return typed::set>(res); +} + +template +typed::set> typed::point>::project_out_param(const std::string &id) const +{ + auto res = isl::point::project_out_param(id); + return typed::set>(res); +} + +template +typed::set> typed::point>::project_out_param(const typed::id_list &list) const +{ + auto res = isl::point::project_out_param(list); + return typed::set>(res); +} + +template +typed::pw_aff, Anonymous> typed::point>::pw_aff_on_domain(const typed::val &v) const +{ + auto res = isl::point::pw_aff_on_domain(v); + return typed::pw_aff, Anonymous>(res); +} + +template +typed::pw_aff, Anonymous> typed::point>::pw_aff_on_domain(long v) const +{ + auto res = isl::point::pw_aff_on_domain(v); + return typed::pw_aff, Anonymous>(res); +} + +template +template +typed::pw_multi_aff, Arg2> typed::point>::pw_multi_aff_on_domain(const typed::multi_val &mv) const +{ + auto res = isl::point::pw_multi_aff_on_domain(mv); + return typed::pw_multi_aff, Arg2>(res); +} + +template +typed::set_list> typed::point>::set_list() const +{ + auto res = isl::point::set_list(); + return typed::set_list>(res); +} + +template +typed::fixed_box> typed::point>::simple_fixed_box_hull() const +{ + auto res = isl::point::simple_fixed_box_hull(); + return typed::fixed_box>(res); +} + +template +typed::space> typed::point>::space() const +{ + auto res = isl::point::space(); + return typed::space>(res); +} + +template +typed::set> typed::point>::subtract(const typed::set> &set2) const +{ + auto res = isl::point::subtract(set2); + return typed::set>(res); +} + +template +typed::union_set> typed::point>::subtract(const typed::union_set> &uset2) const +{ + auto res = isl::point::subtract(uset2); + return typed::union_set>(res); +} + +template +typed::set> typed::point>::to_set() const +{ + auto res = isl::point::to_set(); + return typed::set>(res); +} + +template +typed::union_set> typed::point>::to_union_set() const +{ + auto res = isl::point::to_union_set(); + return typed::union_set>(res); +} + +template +typed::map, pair> typed::point>::translation() const +{ + auto res = isl::point::translation(); + return typed::map, pair>(res); +} + +template +template +typed::map> typed::point>::unbind_params_insert_domain(const typed::multi_id &domain) const +{ + auto res = isl::point::unbind_params_insert_domain(domain); + return typed::map>(res); +} + +template +typed::set> typed::point>::unite(const typed::basic_set> &bset2) const +{ + auto res = isl::point::unite(bset2); + return typed::set>(res); +} + +template +typed::set> typed::point>::unite(const typed::set> &set2) const +{ + auto res = isl::point::unite(set2); + return typed::set>(res); +} + +template +typed::union_set> typed::point>::unite(const typed::union_set> &uset2) const +{ + auto res = isl::point::unite(uset2); + return typed::union_set>(res); +} + +template +typed::map typed::point>::unwrap() const +{ + auto res = isl::point::unwrap(); + return typed::map(res); +} + +template +typed::set> typed::point>::upper_bound(const typed::multi_pw_aff> &upper) const +{ + auto res = isl::point::upper_bound(upper); + return typed::set>(res); +} + +template +typed::set> typed::point>::upper_bound(const typed::multi_val> &upper) const +{ + auto res = isl::point::upper_bound(upper); + return typed::set>(res); +} + +template +typed::set> typed::point>::wrapped_reverse() const +{ + auto res = isl::point::wrapped_reverse(); + return typed::set>(res); +} + +typed::pw_aff::pw_aff(const typed::aff &aff) + : isl::pw_aff(aff) +{ +} + +typed::pw_aff::pw_aff(const isl::ctx &ctx, const std::string &str) + : isl::pw_aff(ctx, str) +{ +} + +typed::multi_pw_aff typed::pw_aff::add(const typed::multi_pw_aff &multi2) const +{ + auto res = isl::pw_aff::add(multi2); + return typed::multi_pw_aff(res); +} + +typed::multi_union_pw_aff typed::pw_aff::add(const typed::multi_union_pw_aff &multi2) const +{ + auto res = isl::pw_aff::add(multi2); + return typed::multi_union_pw_aff(res); +} + +typed::pw_aff typed::pw_aff::add(const typed::pw_aff &pwaff2) const +{ + auto res = isl::pw_aff::add(pwaff2); + return typed::pw_aff(res); +} + +typed::pw_multi_aff typed::pw_aff::add(const typed::pw_multi_aff &pma2) const +{ + auto res = isl::pw_aff::add(pma2); + return typed::pw_multi_aff(res); +} + +typed::union_pw_aff typed::pw_aff::add(const typed::union_pw_aff &upa2) const +{ + auto res = isl::pw_aff::add(upa2); + return typed::union_pw_aff(res); +} + +typed::union_pw_multi_aff typed::pw_aff::add(const typed::union_pw_multi_aff &upma2) const +{ + auto res = isl::pw_aff::add(upma2); + return typed::union_pw_multi_aff(res); +} + +typed::pw_aff typed::pw_aff::add(const typed::aff &pwaff2) const +{ + auto res = isl::pw_aff::add(pwaff2); + return typed::pw_aff(res); +} + +typed::pw_aff typed::pw_aff::add_constant(const typed::val &v) const +{ + auto res = isl::pw_aff::add_constant(v); + return typed::pw_aff(res); +} + +typed::pw_aff typed::pw_aff::add_constant(long v) const +{ + auto res = isl::pw_aff::add_constant(v); + return typed::pw_aff(res); +} + +typed::pw_multi_aff typed::pw_aff::add_constant(const typed::multi_val &mv) const +{ + auto res = isl::pw_aff::add_constant(mv); + return typed::pw_multi_aff(res); +} + +template +typed::union_pw_multi_aff typed::pw_aff::apply(const typed::union_pw_multi_aff &upma2) const +{ + auto res = isl::pw_aff::apply(upma2); + return typed::union_pw_multi_aff(res); +} + +typed::aff typed::pw_aff::as_aff() const +{ + auto res = isl::pw_aff::as_aff(); + return typed::aff(res); +} + +typed::multi_aff typed::pw_aff::as_multi_aff() const +{ + auto res = isl::pw_aff::as_multi_aff(); + return typed::multi_aff(res); +} + +typed::multi_union_pw_aff typed::pw_aff::as_multi_union_pw_aff() const +{ + auto res = isl::pw_aff::as_multi_union_pw_aff(); + return typed::multi_union_pw_aff(res); +} + +typed::pw_multi_aff typed::pw_aff::as_pw_multi_aff() const +{ + auto res = isl::pw_aff::as_pw_multi_aff(); + return typed::pw_multi_aff(res); +} + +typed::set typed::pw_aff::as_set() const +{ + auto res = isl::pw_aff::as_set(); + return typed::set(res); +} + +typed::pw_aff typed::pw_aff::at(int pos) const +{ + auto res = isl::pw_aff::at(pos); + return typed::pw_aff(res); +} + +typed::set<> typed::pw_aff::bind(const typed::multi_id &tuple) const +{ + auto res = isl::pw_aff::bind(tuple); + return typed::set<>(res); +} + +typed::set<> typed::pw_aff::bind(const typed::id &id) const +{ + auto res = isl::pw_aff::bind(id); + return typed::set<>(res); +} + +typed::set<> typed::pw_aff::bind(const std::string &id) const +{ + auto res = isl::pw_aff::bind(id); + return typed::set<>(res); +} + +typed::pw_aff typed::pw_aff::ceil() const +{ + auto res = isl::pw_aff::ceil(); + return typed::pw_aff(res); +} + +typed::pw_aff typed::pw_aff::coalesce() const +{ + auto res = isl::pw_aff::coalesce(); + return typed::pw_aff(res); +} + +typed::pw_aff typed::pw_aff::cond(const typed::pw_aff &pwaff_true, const typed::pw_aff &pwaff_false) const +{ + auto res = isl::pw_aff::cond(pwaff_true, pwaff_false); + return typed::pw_aff(res); +} + +typed::set<> typed::pw_aff::domain() const +{ + auto res = isl::pw_aff::domain(); + return typed::set<>(res); +} + +typed::pw_aff typed::pw_aff::drop_unused_params() const +{ + auto res = isl::pw_aff::drop_unused_params(); + return typed::pw_aff(res); +} + +typed::pw_multi_aff typed::pw_aff::extract_pw_multi_aff(const typed::space &space) const +{ + auto res = isl::pw_aff::extract_pw_multi_aff(space); + return typed::pw_multi_aff(res); +} + +typed::pw_aff typed::pw_aff::floor() const +{ + auto res = isl::pw_aff::floor(); + return typed::pw_aff(res); +} + +typed::pw_aff typed::pw_aff::gist(const typed::set<> &context) const +{ + auto res = isl::pw_aff::gist(context); + return typed::pw_aff(res); +} + +typed::union_pw_aff typed::pw_aff::gist(const typed::union_set<> &context) const +{ + auto res = isl::pw_aff::gist(context); + return typed::union_pw_aff(res); +} + +typed::pw_aff typed::pw_aff::gist(const typed::basic_set<> &context) const +{ + auto res = isl::pw_aff::gist(context); + return typed::pw_aff(res); +} + +typed::pw_aff typed::pw_aff::gist(const typed::point<> &context) const +{ + auto res = isl::pw_aff::gist(context); + return typed::pw_aff(res); +} + +typed::pw_aff typed::pw_aff::gist_params(const typed::set<> &context) const +{ + auto res = isl::pw_aff::gist_params(context); + return typed::pw_aff(res); +} + +typed::pw_aff typed::pw_aff::gist_params(const typed::basic_set<> &context) const +{ + auto res = isl::pw_aff::gist_params(context); + return typed::pw_aff(res); +} + +typed::pw_aff typed::pw_aff::gist_params(const typed::point<> &context) const +{ + auto res = isl::pw_aff::gist_params(context); + return typed::pw_aff(res); +} + +typed::multi_pw_aff typed::pw_aff::identity() const +{ + auto res = isl::pw_aff::identity(); + return typed::multi_pw_aff(res); +} + +template +typed::pw_aff typed::pw_aff::insert_domain(const typed::space &domain) const +{ + auto res = isl::pw_aff::insert_domain(domain); + return typed::pw_aff(res); +} + +typed::pw_aff typed::pw_aff::intersect_params(const typed::set<> &set) const +{ + auto res = isl::pw_aff::intersect_params(set); + return typed::pw_aff(res); +} + +typed::pw_aff typed::pw_aff::intersect_params(const typed::basic_set<> &set) const +{ + auto res = isl::pw_aff::intersect_params(set); + return typed::pw_aff(res); +} + +typed::pw_aff typed::pw_aff::intersect_params(const typed::point<> &set) const +{ + auto res = isl::pw_aff::intersect_params(set); + return typed::pw_aff(res); +} + +typed::pw_aff_list typed::pw_aff::list() const +{ + auto res = isl::pw_aff::list(); + return typed::pw_aff_list(res); +} + +typed::multi_pw_aff typed::pw_aff::max(const typed::multi_pw_aff &multi2) const +{ + auto res = isl::pw_aff::max(multi2); + return typed::multi_pw_aff(res); +} + +typed::pw_aff typed::pw_aff::max(const typed::pw_aff &pwaff2) const +{ + auto res = isl::pw_aff::max(pwaff2); + return typed::pw_aff(res); +} + +typed::pw_aff typed::pw_aff::max(const typed::aff &pwaff2) const +{ + auto res = isl::pw_aff::max(pwaff2); + return typed::pw_aff(res); +} + +typed::multi_val typed::pw_aff::max_multi_val() const +{ + auto res = isl::pw_aff::max_multi_val(); + return typed::multi_val(res); +} + +typed::val typed::pw_aff::max_val() const +{ + auto res = isl::pw_aff::max_val(); + return typed::val(res); +} + +typed::multi_pw_aff typed::pw_aff::min(const typed::multi_pw_aff &multi2) const +{ + auto res = isl::pw_aff::min(multi2); + return typed::multi_pw_aff(res); +} + +typed::pw_aff typed::pw_aff::min(const typed::pw_aff &pwaff2) const +{ + auto res = isl::pw_aff::min(pwaff2); + return typed::pw_aff(res); +} + +typed::pw_aff typed::pw_aff::min(const typed::aff &pwaff2) const +{ + auto res = isl::pw_aff::min(pwaff2); + return typed::pw_aff(res); +} + +typed::multi_val typed::pw_aff::min_multi_val() const +{ + auto res = isl::pw_aff::min_multi_val(); + return typed::multi_val(res); +} + +typed::val typed::pw_aff::min_val() const +{ + auto res = isl::pw_aff::min_val(); + return typed::val(res); +} + +typed::pw_aff typed::pw_aff::mod(const typed::val &mod) const +{ + auto res = isl::pw_aff::mod(mod); + return typed::pw_aff(res); +} + +typed::pw_aff typed::pw_aff::mod(long mod) const +{ + auto res = isl::pw_aff::mod(mod); + return typed::pw_aff(res); +} + +typed::pw_aff typed::pw_aff::neg() const +{ + auto res = isl::pw_aff::neg(); + return typed::pw_aff(res); +} + +typed::set<> typed::pw_aff::params() const +{ + auto res = isl::pw_aff::params(); + return typed::set<>(res); +} + +template +typed::multi_pw_aff> typed::pw_aff::product(const typed::multi_pw_aff &multi2) const +{ + auto res = isl::pw_aff::product(multi2); + return typed::multi_pw_aff>(res); +} + +template +typed::pw_multi_aff> typed::pw_aff::product(const typed::pw_multi_aff &pma2) const +{ + auto res = isl::pw_aff::product(pma2); + return typed::pw_multi_aff>(res); +} + +typed::pw_multi_aff_list typed::pw_aff::pw_multi_aff_list() const +{ + auto res = isl::pw_aff::pw_multi_aff_list(); + return typed::pw_multi_aff_list(res); +} + +typed::pw_aff typed::pw_aff::scale(const typed::val &v) const +{ + auto res = isl::pw_aff::scale(v); + return typed::pw_aff(res); +} + +typed::pw_aff typed::pw_aff::scale(long v) const +{ + auto res = isl::pw_aff::scale(v); + return typed::pw_aff(res); +} + +typed::pw_multi_aff typed::pw_aff::scale(const typed::multi_val &mv) const +{ + auto res = isl::pw_aff::scale(mv); + return typed::pw_multi_aff(res); +} + +typed::pw_aff typed::pw_aff::scale_down(const typed::val &f) const +{ + auto res = isl::pw_aff::scale_down(f); + return typed::pw_aff(res); +} + +typed::pw_aff typed::pw_aff::scale_down(long f) const +{ + auto res = isl::pw_aff::scale_down(f); + return typed::pw_aff(res); +} + +typed::pw_multi_aff typed::pw_aff::scale_down(const typed::multi_val &mv) const +{ + auto res = isl::pw_aff::scale_down(mv); + return typed::pw_multi_aff(res); +} + +typed::multi_pw_aff typed::pw_aff::set_at(int pos, const typed::pw_aff &el) const +{ + auto res = isl::pw_aff::set_at(pos, el); + return typed::multi_pw_aff(res); +} + +typed::multi_union_pw_aff typed::pw_aff::set_at(int pos, const typed::union_pw_aff &el) const +{ + auto res = isl::pw_aff::set_at(pos, el); + return typed::multi_union_pw_aff(res); +} + +template +typed::pw_multi_aff typed::pw_aff::set_range_tuple(const typed::id &id) const +{ + auto res = isl::pw_aff::set_range_tuple(id); + return typed::pw_multi_aff(res); +} + +template +typed::pw_multi_aff typed::pw_aff::set_range_tuple(const std::string &id) const +{ + auto res = isl::pw_aff::set_range_tuple(id); + return typed::pw_multi_aff(res); +} + +typed::space typed::pw_aff::space() const +{ + auto res = isl::pw_aff::space(); + return typed::space(res); +} + +typed::multi_pw_aff typed::pw_aff::sub(const typed::multi_pw_aff &multi2) const +{ + auto res = isl::pw_aff::sub(multi2); + return typed::multi_pw_aff(res); +} + +typed::multi_union_pw_aff typed::pw_aff::sub(const typed::multi_union_pw_aff &multi2) const +{ + auto res = isl::pw_aff::sub(multi2); + return typed::multi_union_pw_aff(res); +} + +typed::pw_aff typed::pw_aff::sub(const typed::pw_aff &pwaff2) const +{ + auto res = isl::pw_aff::sub(pwaff2); + return typed::pw_aff(res); +} + +typed::pw_multi_aff typed::pw_aff::sub(const typed::pw_multi_aff &pma2) const +{ + auto res = isl::pw_aff::sub(pma2); + return typed::pw_multi_aff(res); +} + +typed::union_pw_aff typed::pw_aff::sub(const typed::union_pw_aff &upa2) const +{ + auto res = isl::pw_aff::sub(upa2); + return typed::union_pw_aff(res); +} + +typed::union_pw_multi_aff typed::pw_aff::sub(const typed::union_pw_multi_aff &upma2) const +{ + auto res = isl::pw_aff::sub(upma2); + return typed::union_pw_multi_aff(res); +} + +typed::pw_aff typed::pw_aff::sub(const typed::aff &pwaff2) const +{ + auto res = isl::pw_aff::sub(pwaff2); + return typed::pw_aff(res); +} + +typed::multi_pw_aff typed::pw_aff::to_multi_pw_aff() const +{ + auto res = isl::pw_aff::to_multi_pw_aff(); + return typed::multi_pw_aff(res); +} + +typed::union_pw_aff typed::pw_aff::to_union_pw_aff() const +{ + auto res = isl::pw_aff::to_union_pw_aff(); + return typed::union_pw_aff(res); +} + +typed::union_pw_multi_aff typed::pw_aff::to_union_pw_multi_aff() const +{ + auto res = isl::pw_aff::to_union_pw_multi_aff(); + return typed::union_pw_multi_aff(res); +} + +template +typed::multi_pw_aff typed::pw_aff::unbind_params_insert_domain(const typed::multi_id &domain) const +{ + auto res = isl::pw_aff::unbind_params_insert_domain(domain); + return typed::multi_pw_aff(res); +} + +typed::multi_pw_aff typed::pw_aff::union_add(const typed::multi_pw_aff &mpa2) const +{ + auto res = isl::pw_aff::union_add(mpa2); + return typed::multi_pw_aff(res); +} + +typed::multi_union_pw_aff typed::pw_aff::union_add(const typed::multi_union_pw_aff &mupa2) const +{ + auto res = isl::pw_aff::union_add(mupa2); + return typed::multi_union_pw_aff(res); +} + +typed::pw_aff typed::pw_aff::union_add(const typed::pw_aff &pwaff2) const +{ + auto res = isl::pw_aff::union_add(pwaff2); + return typed::pw_aff(res); +} + +typed::pw_multi_aff typed::pw_aff::union_add(const typed::pw_multi_aff &pma2) const +{ + auto res = isl::pw_aff::union_add(pma2); + return typed::pw_multi_aff(res); +} + +typed::union_pw_aff typed::pw_aff::union_add(const typed::union_pw_aff &upa2) const +{ + auto res = isl::pw_aff::union_add(upa2); + return typed::union_pw_aff(res); +} + +typed::union_pw_multi_aff typed::pw_aff::union_add(const typed::union_pw_multi_aff &upma2) const +{ + auto res = isl::pw_aff::union_add(upma2); + return typed::union_pw_multi_aff(res); +} + +typed::pw_aff typed::pw_aff::union_add(const typed::aff &pwaff2) const +{ + auto res = isl::pw_aff::union_add(pwaff2); + return typed::pw_aff(res); +} + +template +typed::pw_aff::pw_aff(const typed::aff &aff) + : isl::pw_aff(aff) +{ +} + +template +typed::pw_aff::pw_aff(const isl::ctx &ctx, const std::string &str) + : isl::pw_aff(ctx, str) +{ +} + +template +typed::multi_pw_aff typed::pw_aff::add(const typed::multi_pw_aff &multi2) const +{ + auto res = isl::pw_aff::add(multi2); + return typed::multi_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::pw_aff::add(const typed::multi_union_pw_aff &multi2) const +{ + auto res = isl::pw_aff::add(multi2); + return typed::multi_union_pw_aff(res); +} + +template +typed::pw_aff typed::pw_aff::add(const typed::pw_aff &pwaff2) const +{ + auto res = isl::pw_aff::add(pwaff2); + return typed::pw_aff(res); +} + +template +typed::pw_multi_aff typed::pw_aff::add(const typed::pw_multi_aff &pma2) const +{ + auto res = isl::pw_aff::add(pma2); + return typed::pw_multi_aff(res); +} + +template +typed::union_pw_aff typed::pw_aff::add(const typed::union_pw_aff &upa2) const +{ + auto res = isl::pw_aff::add(upa2); + return typed::union_pw_aff(res); +} + +template +typed::union_pw_multi_aff typed::pw_aff::add(const typed::union_pw_multi_aff &upma2) const +{ + auto res = isl::pw_aff::add(upma2); + return typed::union_pw_multi_aff(res); +} + +template +typed::pw_aff typed::pw_aff::add(const typed::aff &pwaff2) const +{ + auto res = isl::pw_aff::add(pwaff2); + return typed::pw_aff(res); +} + +template +typed::pw_aff typed::pw_aff::add_constant(const typed::val &v) const +{ + auto res = isl::pw_aff::add_constant(v); + return typed::pw_aff(res); +} + +template +typed::pw_aff typed::pw_aff::add_constant(long v) const +{ + auto res = isl::pw_aff::add_constant(v); + return typed::pw_aff(res); +} + +template +typed::pw_multi_aff typed::pw_aff::add_constant(const typed::multi_val &mv) const +{ + auto res = isl::pw_aff::add_constant(mv); + return typed::pw_multi_aff(res); +} + +template +template +typed::union_pw_multi_aff typed::pw_aff::apply(const typed::union_pw_multi_aff &upma2) const +{ + auto res = isl::pw_aff::apply(upma2); + return typed::union_pw_multi_aff(res); +} + +template +typed::aff typed::pw_aff::as_aff() const +{ + auto res = isl::pw_aff::as_aff(); + return typed::aff(res); +} + +template +typed::map typed::pw_aff::as_map() const +{ + auto res = isl::pw_aff::as_map(); + return typed::map(res); +} + +template +typed::multi_aff typed::pw_aff::as_multi_aff() const +{ + auto res = isl::pw_aff::as_multi_aff(); + return typed::multi_aff(res); +} + +template +typed::multi_union_pw_aff typed::pw_aff::as_multi_union_pw_aff() const +{ + auto res = isl::pw_aff::as_multi_union_pw_aff(); + return typed::multi_union_pw_aff(res); +} + +template +typed::pw_multi_aff typed::pw_aff::as_pw_multi_aff() const +{ + auto res = isl::pw_aff::as_pw_multi_aff(); + return typed::pw_multi_aff(res); +} + +template +typed::union_map typed::pw_aff::as_union_map() const +{ + auto res = isl::pw_aff::as_union_map(); + return typed::union_map(res); +} + +template +typed::pw_aff typed::pw_aff::at(int pos) const +{ + auto res = isl::pw_aff::at(pos); + return typed::pw_aff(res); +} + +template +typed::set typed::pw_aff::bind(const typed::multi_id &tuple) const +{ + auto res = isl::pw_aff::bind(tuple); + return typed::set(res); +} + +template +typed::set typed::pw_aff::bind(const typed::id &id) const +{ + auto res = isl::pw_aff::bind(id); + return typed::set(res); +} + +template +typed::set typed::pw_aff::bind(const std::string &id) const +{ + auto res = isl::pw_aff::bind(id); + return typed::set(res); +} + +template +typed::pw_aff typed::pw_aff::bind_domain(const typed::multi_id &tuple) const +{ + auto res = isl::pw_aff::bind_domain(tuple); + return typed::pw_aff(res); +} + +template +typed::pw_aff typed::pw_aff::ceil() const +{ + auto res = isl::pw_aff::ceil(); + return typed::pw_aff(res); +} + +template +typed::pw_aff typed::pw_aff::coalesce() const +{ + auto res = isl::pw_aff::coalesce(); + return typed::pw_aff(res); +} + +template +typed::pw_aff typed::pw_aff::cond(const typed::pw_aff &pwaff_true, const typed::pw_aff &pwaff_false) const +{ + auto res = isl::pw_aff::cond(pwaff_true, pwaff_false); + return typed::pw_aff(res); +} + +template +typed::set typed::pw_aff::domain() const +{ + auto res = isl::pw_aff::domain(); + return typed::set(res); +} + +template +typed::pw_aff typed::pw_aff::drop_unused_params() const +{ + auto res = isl::pw_aff::drop_unused_params(); + return typed::pw_aff(res); +} + +template +typed::pw_multi_aff typed::pw_aff::extract_pw_multi_aff(const typed::space &space) const +{ + auto res = isl::pw_aff::extract_pw_multi_aff(space); + return typed::pw_multi_aff(res); +} + +template +typed::pw_aff typed::pw_aff::floor() const +{ + auto res = isl::pw_aff::floor(); + return typed::pw_aff(res); +} + +template +typed::set typed::pw_aff::ge_set(const typed::pw_aff &pwaff2) const +{ + auto res = isl::pw_aff::ge_set(pwaff2); + return typed::set(res); +} + +template +typed::set typed::pw_aff::ge_set(const typed::aff &pwaff2) const +{ + auto res = isl::pw_aff::ge_set(pwaff2); + return typed::set(res); +} + +template +typed::pw_aff typed::pw_aff::gist(const typed::set &context) const +{ + auto res = isl::pw_aff::gist(context); + return typed::pw_aff(res); +} + +template +typed::union_pw_aff typed::pw_aff::gist(const typed::union_set &context) const +{ + auto res = isl::pw_aff::gist(context); + return typed::union_pw_aff(res); +} + +template +typed::pw_aff typed::pw_aff::gist(const typed::basic_set &context) const +{ + auto res = isl::pw_aff::gist(context); + return typed::pw_aff(res); +} + +template +typed::pw_aff typed::pw_aff::gist(const typed::point &context) const +{ + auto res = isl::pw_aff::gist(context); + return typed::pw_aff(res); +} + +template +typed::pw_aff typed::pw_aff::gist_params(const typed::set<> &context) const +{ + auto res = isl::pw_aff::gist_params(context); + return typed::pw_aff(res); +} + +template +typed::pw_aff typed::pw_aff::gist_params(const typed::basic_set<> &context) const +{ + auto res = isl::pw_aff::gist_params(context); + return typed::pw_aff(res); +} + +template +typed::pw_aff typed::pw_aff::gist_params(const typed::point<> &context) const +{ + auto res = isl::pw_aff::gist_params(context); + return typed::pw_aff(res); +} + +template +typed::set typed::pw_aff::gt_set(const typed::pw_aff &pwaff2) const +{ + auto res = isl::pw_aff::gt_set(pwaff2); + return typed::set(res); +} + +template +typed::set typed::pw_aff::gt_set(const typed::aff &pwaff2) const +{ + auto res = isl::pw_aff::gt_set(pwaff2); + return typed::set(res); +} + +template +typed::multi_pw_aff typed::pw_aff::identity() const +{ + auto res = isl::pw_aff::identity(); + return typed::multi_pw_aff(res); +} + +template +typed::pw_aff typed::pw_aff::intersect_domain(const typed::set &set) const +{ + auto res = isl::pw_aff::intersect_domain(set); + return typed::pw_aff(res); +} + +template +typed::union_pw_aff typed::pw_aff::intersect_domain(const typed::space &space) const +{ + auto res = isl::pw_aff::intersect_domain(space); + return typed::union_pw_aff(res); +} + +template +typed::union_pw_aff typed::pw_aff::intersect_domain(const typed::union_set &uset) const +{ + auto res = isl::pw_aff::intersect_domain(uset); + return typed::union_pw_aff(res); +} + +template +typed::pw_aff typed::pw_aff::intersect_domain(const typed::basic_set &set) const +{ + auto res = isl::pw_aff::intersect_domain(set); + return typed::pw_aff(res); +} + +template +typed::pw_aff typed::pw_aff::intersect_domain(const typed::point &set) const +{ + auto res = isl::pw_aff::intersect_domain(set); + return typed::pw_aff(res); +} + +template +typed::pw_aff typed::pw_aff::intersect_params(const typed::set<> &set) const +{ + auto res = isl::pw_aff::intersect_params(set); + return typed::pw_aff(res); +} + +template +typed::pw_aff typed::pw_aff::intersect_params(const typed::basic_set<> &set) const +{ + auto res = isl::pw_aff::intersect_params(set); + return typed::pw_aff(res); +} + +template +typed::pw_aff typed::pw_aff::intersect_params(const typed::point<> &set) const +{ + auto res = isl::pw_aff::intersect_params(set); + return typed::pw_aff(res); +} + +template +typed::set typed::pw_aff::le_set(const typed::pw_aff &pwaff2) const +{ + auto res = isl::pw_aff::le_set(pwaff2); + return typed::set(res); +} + +template +typed::set typed::pw_aff::le_set(const typed::aff &pwaff2) const +{ + auto res = isl::pw_aff::le_set(pwaff2); + return typed::set(res); +} + +template +typed::pw_aff_list typed::pw_aff::list() const +{ + auto res = isl::pw_aff::list(); + return typed::pw_aff_list(res); +} + +template +typed::set typed::pw_aff::lt_set(const typed::pw_aff &pwaff2) const +{ + auto res = isl::pw_aff::lt_set(pwaff2); + return typed::set(res); +} + +template +typed::set typed::pw_aff::lt_set(const typed::aff &pwaff2) const +{ + auto res = isl::pw_aff::lt_set(pwaff2); + return typed::set(res); +} + +template +typed::multi_pw_aff typed::pw_aff::max(const typed::multi_pw_aff &multi2) const +{ + auto res = isl::pw_aff::max(multi2); + return typed::multi_pw_aff(res); +} + +template +typed::pw_aff typed::pw_aff::max(const typed::pw_aff &pwaff2) const +{ + auto res = isl::pw_aff::max(pwaff2); + return typed::pw_aff(res); +} + +template +typed::pw_aff typed::pw_aff::max(const typed::aff &pwaff2) const +{ + auto res = isl::pw_aff::max(pwaff2); + return typed::pw_aff(res); +} + +template +typed::multi_val typed::pw_aff::max_multi_val() const +{ + auto res = isl::pw_aff::max_multi_val(); + return typed::multi_val(res); +} + +template +typed::val typed::pw_aff::max_val() const +{ + auto res = isl::pw_aff::max_val(); + return typed::val(res); +} + +template +typed::multi_pw_aff typed::pw_aff::min(const typed::multi_pw_aff &multi2) const +{ + auto res = isl::pw_aff::min(multi2); + return typed::multi_pw_aff(res); +} + +template +typed::pw_aff typed::pw_aff::min(const typed::pw_aff &pwaff2) const +{ + auto res = isl::pw_aff::min(pwaff2); + return typed::pw_aff(res); +} + +template +typed::pw_aff typed::pw_aff::min(const typed::aff &pwaff2) const +{ + auto res = isl::pw_aff::min(pwaff2); + return typed::pw_aff(res); +} + +template +typed::multi_val typed::pw_aff::min_multi_val() const +{ + auto res = isl::pw_aff::min_multi_val(); + return typed::multi_val(res); +} + +template +typed::val typed::pw_aff::min_val() const +{ + auto res = isl::pw_aff::min_val(); + return typed::val(res); +} + +template +typed::pw_aff typed::pw_aff::mod(const typed::val &mod) const +{ + auto res = isl::pw_aff::mod(mod); + return typed::pw_aff(res); +} + +template +typed::pw_aff typed::pw_aff::mod(long mod) const +{ + auto res = isl::pw_aff::mod(mod); + return typed::pw_aff(res); +} + +template +typed::pw_aff typed::pw_aff::neg() const +{ + auto res = isl::pw_aff::neg(); + return typed::pw_aff(res); +} + +template +typed::set<> typed::pw_aff::params() const +{ + auto res = isl::pw_aff::params(); + return typed::set<>(res); +} + +template +template +typed::multi_pw_aff, pair> typed::pw_aff::product(const typed::multi_pw_aff &multi2) const +{ + auto res = isl::pw_aff::product(multi2); + return typed::multi_pw_aff, pair>(res); +} + +template +template +typed::pw_multi_aff, pair> typed::pw_aff::product(const typed::pw_multi_aff &pma2) const +{ + auto res = isl::pw_aff::product(pma2); + return typed::pw_multi_aff, pair>(res); +} + +template +template +typed::pw_aff typed::pw_aff::pullback(const typed::multi_aff &ma) const +{ + auto res = isl::pw_aff::pullback(ma); + return typed::pw_aff(res); +} + +template +typed::pw_aff typed::pw_aff::pullback(const typed::multi_aff &ma) const +{ + auto res = isl::pw_aff::pullback(ma); + return typed::pw_aff(res); +} + +template +template +typed::pw_aff typed::pw_aff::pullback(const typed::multi_pw_aff &mpa) const +{ + auto res = isl::pw_aff::pullback(mpa); + return typed::pw_aff(res); +} + +template +typed::pw_aff typed::pw_aff::pullback(const typed::multi_pw_aff &mpa) const +{ + auto res = isl::pw_aff::pullback(mpa); + return typed::pw_aff(res); +} + +template +template +typed::pw_aff typed::pw_aff::pullback(const typed::pw_multi_aff &pma) const +{ + auto res = isl::pw_aff::pullback(pma); + return typed::pw_aff(res); +} + +template +typed::pw_aff typed::pw_aff::pullback(const typed::pw_multi_aff &pma) const +{ + auto res = isl::pw_aff::pullback(pma); + return typed::pw_aff(res); +} + +template +template +typed::union_pw_aff typed::pw_aff::pullback(const typed::union_pw_multi_aff &upma) const +{ + auto res = isl::pw_aff::pullback(upma); + return typed::union_pw_aff(res); +} + +template +typed::union_pw_aff typed::pw_aff::pullback(const typed::union_pw_multi_aff &upma) const +{ + auto res = isl::pw_aff::pullback(upma); + return typed::union_pw_aff(res); +} + +template +typed::pw_multi_aff_list typed::pw_aff::pw_multi_aff_list() const +{ + auto res = isl::pw_aff::pw_multi_aff_list(); + return typed::pw_multi_aff_list(res); +} + +template +template +typed::multi_pw_aff> typed::pw_aff::range_product(const typed::multi_pw_aff &multi2) const +{ + auto res = isl::pw_aff::range_product(multi2); + return typed::multi_pw_aff>(res); +} + +template +template +typed::multi_union_pw_aff> typed::pw_aff::range_product(const typed::multi_union_pw_aff &multi2) const +{ + auto res = isl::pw_aff::range_product(multi2); + return typed::multi_union_pw_aff>(res); +} + +template +template +typed::pw_multi_aff> typed::pw_aff::range_product(const typed::pw_multi_aff &pma2) const +{ + auto res = isl::pw_aff::range_product(pma2); + return typed::pw_multi_aff>(res); +} + +template +template +typed::union_pw_multi_aff> typed::pw_aff::range_product(const typed::union_pw_multi_aff &upma2) const +{ + auto res = isl::pw_aff::range_product(upma2); + return typed::union_pw_multi_aff>(res); +} + +template +typed::pw_aff typed::pw_aff::scale(const typed::val &v) const +{ + auto res = isl::pw_aff::scale(v); + return typed::pw_aff(res); +} + +template +typed::pw_aff typed::pw_aff::scale(long v) const +{ + auto res = isl::pw_aff::scale(v); + return typed::pw_aff(res); +} + +template +typed::pw_multi_aff typed::pw_aff::scale(const typed::multi_val &mv) const +{ + auto res = isl::pw_aff::scale(mv); + return typed::pw_multi_aff(res); +} + +template +typed::pw_aff typed::pw_aff::scale_down(const typed::val &f) const +{ + auto res = isl::pw_aff::scale_down(f); + return typed::pw_aff(res); +} + +template +typed::pw_aff typed::pw_aff::scale_down(long f) const +{ + auto res = isl::pw_aff::scale_down(f); + return typed::pw_aff(res); +} + +template +typed::pw_multi_aff typed::pw_aff::scale_down(const typed::multi_val &mv) const +{ + auto res = isl::pw_aff::scale_down(mv); + return typed::pw_multi_aff(res); +} + +template +typed::multi_pw_aff typed::pw_aff::set_at(int pos, const typed::pw_aff &el) const +{ + auto res = isl::pw_aff::set_at(pos, el); + return typed::multi_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::pw_aff::set_at(int pos, const typed::union_pw_aff &el) const +{ + auto res = isl::pw_aff::set_at(pos, el); + return typed::multi_union_pw_aff(res); +} + +template +template +typed::pw_multi_aff typed::pw_aff::set_range_tuple(const typed::id &id) const +{ + auto res = isl::pw_aff::set_range_tuple(id); + return typed::pw_multi_aff(res); +} + +template +template +typed::pw_multi_aff typed::pw_aff::set_range_tuple(const std::string &id) const +{ + auto res = isl::pw_aff::set_range_tuple(id); + return typed::pw_multi_aff(res); +} + +template +typed::space typed::pw_aff::space() const +{ + auto res = isl::pw_aff::space(); + return typed::space(res); +} + +template +typed::multi_pw_aff typed::pw_aff::sub(const typed::multi_pw_aff &multi2) const +{ + auto res = isl::pw_aff::sub(multi2); + return typed::multi_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::pw_aff::sub(const typed::multi_union_pw_aff &multi2) const +{ + auto res = isl::pw_aff::sub(multi2); + return typed::multi_union_pw_aff(res); +} + +template +typed::pw_aff typed::pw_aff::sub(const typed::pw_aff &pwaff2) const +{ + auto res = isl::pw_aff::sub(pwaff2); + return typed::pw_aff(res); +} + +template +typed::pw_multi_aff typed::pw_aff::sub(const typed::pw_multi_aff &pma2) const +{ + auto res = isl::pw_aff::sub(pma2); + return typed::pw_multi_aff(res); +} + +template +typed::union_pw_aff typed::pw_aff::sub(const typed::union_pw_aff &upa2) const +{ + auto res = isl::pw_aff::sub(upa2); + return typed::union_pw_aff(res); +} + +template +typed::union_pw_multi_aff typed::pw_aff::sub(const typed::union_pw_multi_aff &upma2) const +{ + auto res = isl::pw_aff::sub(upma2); + return typed::union_pw_multi_aff(res); +} + +template +typed::pw_aff typed::pw_aff::sub(const typed::aff &pwaff2) const +{ + auto res = isl::pw_aff::sub(pwaff2); + return typed::pw_aff(res); +} + +template +typed::pw_aff typed::pw_aff::subtract_domain(const typed::set &set) const +{ + auto res = isl::pw_aff::subtract_domain(set); + return typed::pw_aff(res); +} + +template +typed::union_pw_aff typed::pw_aff::subtract_domain(const typed::space &space) const +{ + auto res = isl::pw_aff::subtract_domain(space); + return typed::union_pw_aff(res); +} + +template +typed::union_pw_aff typed::pw_aff::subtract_domain(const typed::union_set &uset) const +{ + auto res = isl::pw_aff::subtract_domain(uset); + return typed::union_pw_aff(res); +} + +template +typed::pw_aff typed::pw_aff::subtract_domain(const typed::basic_set &set) const +{ + auto res = isl::pw_aff::subtract_domain(set); + return typed::pw_aff(res); +} + +template +typed::pw_aff typed::pw_aff::subtract_domain(const typed::point &set) const +{ + auto res = isl::pw_aff::subtract_domain(set); + return typed::pw_aff(res); +} + +template +typed::multi_pw_aff typed::pw_aff::to_multi_pw_aff() const +{ + auto res = isl::pw_aff::to_multi_pw_aff(); + return typed::multi_pw_aff(res); +} + +template +typed::union_pw_aff typed::pw_aff::to_union_pw_aff() const +{ + auto res = isl::pw_aff::to_union_pw_aff(); + return typed::union_pw_aff(res); +} + +template +typed::union_pw_multi_aff typed::pw_aff::to_union_pw_multi_aff() const +{ + auto res = isl::pw_aff::to_union_pw_multi_aff(); + return typed::union_pw_multi_aff(res); +} + +template +typed::multi_pw_aff typed::pw_aff::union_add(const typed::multi_pw_aff &mpa2) const +{ + auto res = isl::pw_aff::union_add(mpa2); + return typed::multi_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::pw_aff::union_add(const typed::multi_union_pw_aff &mupa2) const +{ + auto res = isl::pw_aff::union_add(mupa2); + return typed::multi_union_pw_aff(res); +} + +template +typed::pw_aff typed::pw_aff::union_add(const typed::pw_aff &pwaff2) const +{ + auto res = isl::pw_aff::union_add(pwaff2); + return typed::pw_aff(res); +} + +template +typed::pw_multi_aff typed::pw_aff::union_add(const typed::pw_multi_aff &pma2) const +{ + auto res = isl::pw_aff::union_add(pma2); + return typed::pw_multi_aff(res); +} + +template +typed::union_pw_aff typed::pw_aff::union_add(const typed::union_pw_aff &upa2) const +{ + auto res = isl::pw_aff::union_add(upa2); + return typed::union_pw_aff(res); +} + +template +typed::union_pw_multi_aff typed::pw_aff::union_add(const typed::union_pw_multi_aff &upma2) const +{ + auto res = isl::pw_aff::union_add(upma2); + return typed::union_pw_multi_aff(res); +} + +template +typed::pw_aff typed::pw_aff::union_add(const typed::aff &pwaff2) const +{ + auto res = isl::pw_aff::union_add(pwaff2); + return typed::pw_aff(res); +} + +template +typed::pw_aff, Anonymous>::pw_aff(const typed::aff, Anonymous> &aff) + : isl::pw_aff(aff) +{ +} + +template +typed::pw_aff, Anonymous>::pw_aff(const isl::ctx &ctx, const std::string &str) + : isl::pw_aff(ctx, str) +{ +} + +template +typed::multi_pw_aff, Anonymous> typed::pw_aff, Anonymous>::add(const typed::multi_pw_aff, Anonymous> &multi2) const +{ + auto res = isl::pw_aff::add(multi2); + return typed::multi_pw_aff, Anonymous>(res); +} + +template +typed::multi_union_pw_aff, Anonymous> typed::pw_aff, Anonymous>::add(const typed::multi_union_pw_aff, Anonymous> &multi2) const +{ + auto res = isl::pw_aff::add(multi2); + return typed::multi_union_pw_aff, Anonymous>(res); +} + +template +typed::pw_aff, Anonymous> typed::pw_aff, Anonymous>::add(const typed::pw_aff, Anonymous> &pwaff2) const +{ + auto res = isl::pw_aff::add(pwaff2); + return typed::pw_aff, Anonymous>(res); +} + +template +typed::pw_multi_aff, Anonymous> typed::pw_aff, Anonymous>::add(const typed::pw_multi_aff, Anonymous> &pma2) const +{ + auto res = isl::pw_aff::add(pma2); + return typed::pw_multi_aff, Anonymous>(res); +} + +template +typed::union_pw_aff, Anonymous> typed::pw_aff, Anonymous>::add(const typed::union_pw_aff, Anonymous> &upa2) const +{ + auto res = isl::pw_aff::add(upa2); + return typed::union_pw_aff, Anonymous>(res); +} + +template +typed::union_pw_multi_aff, Anonymous> typed::pw_aff, Anonymous>::add(const typed::union_pw_multi_aff, Anonymous> &upma2) const +{ + auto res = isl::pw_aff::add(upma2); + return typed::union_pw_multi_aff, Anonymous>(res); +} + +template +typed::pw_aff, Anonymous> typed::pw_aff, Anonymous>::add(const typed::aff, Anonymous> &pwaff2) const +{ + auto res = isl::pw_aff::add(pwaff2); + return typed::pw_aff, Anonymous>(res); +} + +template +typed::pw_aff, Anonymous> typed::pw_aff, Anonymous>::add_constant(const typed::val &v) const +{ + auto res = isl::pw_aff::add_constant(v); + return typed::pw_aff, Anonymous>(res); +} + +template +typed::pw_aff, Anonymous> typed::pw_aff, Anonymous>::add_constant(long v) const +{ + auto res = isl::pw_aff::add_constant(v); + return typed::pw_aff, Anonymous>(res); +} + +template +typed::pw_multi_aff, Anonymous> typed::pw_aff, Anonymous>::add_constant(const typed::multi_val &mv) const +{ + auto res = isl::pw_aff::add_constant(mv); + return typed::pw_multi_aff, Anonymous>(res); +} + +template +template +typed::union_pw_multi_aff, Arg1> typed::pw_aff, Anonymous>::apply(const typed::union_pw_multi_aff &upma2) const +{ + auto res = isl::pw_aff::apply(upma2); + return typed::union_pw_multi_aff, Arg1>(res); +} + +template +typed::aff, Anonymous> typed::pw_aff, Anonymous>::as_aff() const +{ + auto res = isl::pw_aff::as_aff(); + return typed::aff, Anonymous>(res); +} + +template +typed::map, Anonymous> typed::pw_aff, Anonymous>::as_map() const +{ + auto res = isl::pw_aff::as_map(); + return typed::map, Anonymous>(res); +} + +template +typed::multi_aff, Anonymous> typed::pw_aff, Anonymous>::as_multi_aff() const +{ + auto res = isl::pw_aff::as_multi_aff(); + return typed::multi_aff, Anonymous>(res); +} + +template +typed::multi_union_pw_aff, Anonymous> typed::pw_aff, Anonymous>::as_multi_union_pw_aff() const +{ + auto res = isl::pw_aff::as_multi_union_pw_aff(); + return typed::multi_union_pw_aff, Anonymous>(res); +} + +template +typed::pw_multi_aff, Anonymous> typed::pw_aff, Anonymous>::as_pw_multi_aff() const +{ + auto res = isl::pw_aff::as_pw_multi_aff(); + return typed::pw_multi_aff, Anonymous>(res); +} + +template +typed::union_map, Anonymous> typed::pw_aff, Anonymous>::as_union_map() const +{ + auto res = isl::pw_aff::as_union_map(); + return typed::union_map, Anonymous>(res); +} + +template +typed::pw_aff, Anonymous> typed::pw_aff, Anonymous>::at(int pos) const +{ + auto res = isl::pw_aff::at(pos); + return typed::pw_aff, Anonymous>(res); +} + +template +typed::set> typed::pw_aff, Anonymous>::bind(const typed::multi_id &tuple) const +{ + auto res = isl::pw_aff::bind(tuple); + return typed::set>(res); +} + +template +typed::set> typed::pw_aff, Anonymous>::bind(const typed::id &id) const +{ + auto res = isl::pw_aff::bind(id); + return typed::set>(res); +} + +template +typed::set> typed::pw_aff, Anonymous>::bind(const std::string &id) const +{ + auto res = isl::pw_aff::bind(id); + return typed::set>(res); +} + +template +typed::pw_aff typed::pw_aff, Anonymous>::bind_domain(const typed::multi_id> &tuple) const +{ + auto res = isl::pw_aff::bind_domain(tuple); + return typed::pw_aff(res); +} + +template +typed::pw_aff typed::pw_aff, Anonymous>::bind_domain_wrapped_domain(const typed::multi_id &tuple) const +{ + auto res = isl::pw_aff::bind_domain_wrapped_domain(tuple); + return typed::pw_aff(res); +} + +template +typed::pw_aff, Anonymous> typed::pw_aff, Anonymous>::ceil() const +{ + auto res = isl::pw_aff::ceil(); + return typed::pw_aff, Anonymous>(res); +} + +template +typed::pw_aff, Anonymous> typed::pw_aff, Anonymous>::coalesce() const +{ + auto res = isl::pw_aff::coalesce(); + return typed::pw_aff, Anonymous>(res); +} + +template +typed::pw_aff, Anonymous> typed::pw_aff, Anonymous>::cond(const typed::pw_aff, Anonymous> &pwaff_true, const typed::pw_aff, Anonymous> &pwaff_false) const +{ + auto res = isl::pw_aff::cond(pwaff_true, pwaff_false); + return typed::pw_aff, Anonymous>(res); +} + +template +typed::set> typed::pw_aff, Anonymous>::domain() const +{ + auto res = isl::pw_aff::domain(); + return typed::set>(res); +} + +template +typed::pw_aff, Anonymous> typed::pw_aff, Anonymous>::domain_reverse() const +{ + auto res = isl::pw_aff::domain_reverse(); + return typed::pw_aff, Anonymous>(res); +} + +template +typed::pw_aff, Anonymous> typed::pw_aff, Anonymous>::drop_unused_params() const +{ + auto res = isl::pw_aff::drop_unused_params(); + return typed::pw_aff, Anonymous>(res); +} + +template +typed::pw_multi_aff, Anonymous> typed::pw_aff, Anonymous>::extract_pw_multi_aff(const typed::space, Anonymous> &space) const +{ + auto res = isl::pw_aff::extract_pw_multi_aff(space); + return typed::pw_multi_aff, Anonymous>(res); +} + +template +typed::pw_aff, Anonymous> typed::pw_aff, Anonymous>::floor() const +{ + auto res = isl::pw_aff::floor(); + return typed::pw_aff, Anonymous>(res); +} + +template +typed::set> typed::pw_aff, Anonymous>::ge_set(const typed::pw_aff, Anonymous> &pwaff2) const +{ + auto res = isl::pw_aff::ge_set(pwaff2); + return typed::set>(res); +} + +template +typed::set> typed::pw_aff, Anonymous>::ge_set(const typed::aff, Anonymous> &pwaff2) const +{ + auto res = isl::pw_aff::ge_set(pwaff2); + return typed::set>(res); +} + +template +typed::pw_aff, Anonymous> typed::pw_aff, Anonymous>::gist(const typed::set> &context) const +{ + auto res = isl::pw_aff::gist(context); + return typed::pw_aff, Anonymous>(res); +} + +template +typed::union_pw_aff, Anonymous> typed::pw_aff, Anonymous>::gist(const typed::union_set> &context) const +{ + auto res = isl::pw_aff::gist(context); + return typed::union_pw_aff, Anonymous>(res); +} + +template +typed::pw_aff, Anonymous> typed::pw_aff, Anonymous>::gist(const typed::basic_set> &context) const +{ + auto res = isl::pw_aff::gist(context); + return typed::pw_aff, Anonymous>(res); +} + +template +typed::pw_aff, Anonymous> typed::pw_aff, Anonymous>::gist(const typed::point> &context) const +{ + auto res = isl::pw_aff::gist(context); + return typed::pw_aff, Anonymous>(res); +} + +template +typed::pw_aff, Anonymous> typed::pw_aff, Anonymous>::gist_params(const typed::set<> &context) const +{ + auto res = isl::pw_aff::gist_params(context); + return typed::pw_aff, Anonymous>(res); +} + +template +typed::pw_aff, Anonymous> typed::pw_aff, Anonymous>::gist_params(const typed::basic_set<> &context) const +{ + auto res = isl::pw_aff::gist_params(context); + return typed::pw_aff, Anonymous>(res); +} + +template +typed::pw_aff, Anonymous> typed::pw_aff, Anonymous>::gist_params(const typed::point<> &context) const +{ + auto res = isl::pw_aff::gist_params(context); + return typed::pw_aff, Anonymous>(res); +} + +template +typed::set> typed::pw_aff, Anonymous>::gt_set(const typed::pw_aff, Anonymous> &pwaff2) const +{ + auto res = isl::pw_aff::gt_set(pwaff2); + return typed::set>(res); +} + +template +typed::set> typed::pw_aff, Anonymous>::gt_set(const typed::aff, Anonymous> &pwaff2) const +{ + auto res = isl::pw_aff::gt_set(pwaff2); + return typed::set>(res); +} + +template +typed::multi_pw_aff, Anonymous> typed::pw_aff, Anonymous>::identity() const +{ + auto res = isl::pw_aff::identity(); + return typed::multi_pw_aff, Anonymous>(res); +} + +template +typed::pw_aff, Anonymous> typed::pw_aff, Anonymous>::intersect_domain(const typed::set> &set) const +{ + auto res = isl::pw_aff::intersect_domain(set); + return typed::pw_aff, Anonymous>(res); +} + +template +typed::union_pw_aff, Anonymous> typed::pw_aff, Anonymous>::intersect_domain(const typed::space> &space) const +{ + auto res = isl::pw_aff::intersect_domain(space); + return typed::union_pw_aff, Anonymous>(res); +} + +template +typed::union_pw_aff, Anonymous> typed::pw_aff, Anonymous>::intersect_domain(const typed::union_set> &uset) const +{ + auto res = isl::pw_aff::intersect_domain(uset); + return typed::union_pw_aff, Anonymous>(res); +} + +template +typed::pw_aff, Anonymous> typed::pw_aff, Anonymous>::intersect_domain(const typed::basic_set> &set) const +{ + auto res = isl::pw_aff::intersect_domain(set); + return typed::pw_aff, Anonymous>(res); +} + +template +typed::pw_aff, Anonymous> typed::pw_aff, Anonymous>::intersect_domain(const typed::point> &set) const +{ + auto res = isl::pw_aff::intersect_domain(set); + return typed::pw_aff, Anonymous>(res); +} + +template +typed::union_pw_aff, Anonymous> typed::pw_aff, Anonymous>::intersect_domain_wrapped_domain(const typed::union_set &uset) const +{ + auto res = isl::pw_aff::intersect_domain_wrapped_domain(uset); + return typed::union_pw_aff, Anonymous>(res); +} + +template +typed::pw_aff, Anonymous> typed::pw_aff, Anonymous>::intersect_params(const typed::set<> &set) const +{ + auto res = isl::pw_aff::intersect_params(set); + return typed::pw_aff, Anonymous>(res); +} + +template +typed::pw_aff, Anonymous> typed::pw_aff, Anonymous>::intersect_params(const typed::basic_set<> &set) const +{ + auto res = isl::pw_aff::intersect_params(set); + return typed::pw_aff, Anonymous>(res); +} + +template +typed::pw_aff, Anonymous> typed::pw_aff, Anonymous>::intersect_params(const typed::point<> &set) const +{ + auto res = isl::pw_aff::intersect_params(set); + return typed::pw_aff, Anonymous>(res); +} + +template +typed::set> typed::pw_aff, Anonymous>::le_set(const typed::pw_aff, Anonymous> &pwaff2) const +{ + auto res = isl::pw_aff::le_set(pwaff2); + return typed::set>(res); +} + +template +typed::set> typed::pw_aff, Anonymous>::le_set(const typed::aff, Anonymous> &pwaff2) const +{ + auto res = isl::pw_aff::le_set(pwaff2); + return typed::set>(res); +} + +template +typed::pw_aff_list, Anonymous> typed::pw_aff, Anonymous>::list() const +{ + auto res = isl::pw_aff::list(); + return typed::pw_aff_list, Anonymous>(res); +} + +template +typed::set> typed::pw_aff, Anonymous>::lt_set(const typed::pw_aff, Anonymous> &pwaff2) const +{ + auto res = isl::pw_aff::lt_set(pwaff2); + return typed::set>(res); +} + +template +typed::set> typed::pw_aff, Anonymous>::lt_set(const typed::aff, Anonymous> &pwaff2) const +{ + auto res = isl::pw_aff::lt_set(pwaff2); + return typed::set>(res); +} + +template +typed::multi_pw_aff, Anonymous> typed::pw_aff, Anonymous>::max(const typed::multi_pw_aff, Anonymous> &multi2) const +{ + auto res = isl::pw_aff::max(multi2); + return typed::multi_pw_aff, Anonymous>(res); +} + +template +typed::pw_aff, Anonymous> typed::pw_aff, Anonymous>::max(const typed::pw_aff, Anonymous> &pwaff2) const +{ + auto res = isl::pw_aff::max(pwaff2); + return typed::pw_aff, Anonymous>(res); +} + +template +typed::pw_aff, Anonymous> typed::pw_aff, Anonymous>::max(const typed::aff, Anonymous> &pwaff2) const +{ + auto res = isl::pw_aff::max(pwaff2); + return typed::pw_aff, Anonymous>(res); +} + +template +typed::multi_val typed::pw_aff, Anonymous>::max_multi_val() const +{ + auto res = isl::pw_aff::max_multi_val(); + return typed::multi_val(res); +} + +template +typed::val typed::pw_aff, Anonymous>::max_val() const +{ + auto res = isl::pw_aff::max_val(); + return typed::val(res); +} + +template +typed::multi_pw_aff, Anonymous> typed::pw_aff, Anonymous>::min(const typed::multi_pw_aff, Anonymous> &multi2) const +{ + auto res = isl::pw_aff::min(multi2); + return typed::multi_pw_aff, Anonymous>(res); +} + +template +typed::pw_aff, Anonymous> typed::pw_aff, Anonymous>::min(const typed::pw_aff, Anonymous> &pwaff2) const +{ + auto res = isl::pw_aff::min(pwaff2); + return typed::pw_aff, Anonymous>(res); +} + +template +typed::pw_aff, Anonymous> typed::pw_aff, Anonymous>::min(const typed::aff, Anonymous> &pwaff2) const +{ + auto res = isl::pw_aff::min(pwaff2); + return typed::pw_aff, Anonymous>(res); +} + +template +typed::multi_val typed::pw_aff, Anonymous>::min_multi_val() const +{ + auto res = isl::pw_aff::min_multi_val(); + return typed::multi_val(res); +} + +template +typed::val typed::pw_aff, Anonymous>::min_val() const +{ + auto res = isl::pw_aff::min_val(); + return typed::val(res); +} + +template +typed::pw_aff, Anonymous> typed::pw_aff, Anonymous>::mod(const typed::val &mod) const +{ + auto res = isl::pw_aff::mod(mod); + return typed::pw_aff, Anonymous>(res); +} + +template +typed::pw_aff, Anonymous> typed::pw_aff, Anonymous>::mod(long mod) const +{ + auto res = isl::pw_aff::mod(mod); + return typed::pw_aff, Anonymous>(res); +} + +template +typed::pw_aff, Anonymous> typed::pw_aff, Anonymous>::neg() const +{ + auto res = isl::pw_aff::neg(); + return typed::pw_aff, Anonymous>(res); +} + +template +typed::set<> typed::pw_aff, Anonymous>::params() const +{ + auto res = isl::pw_aff::params(); + return typed::set<>(res); +} + +template +template +typed::pw_multi_aff, Anonymous> typed::pw_aff, Anonymous>::preimage_domain_wrapped_domain(const typed::pw_multi_aff &pma2) const +{ + auto res = isl::pw_aff::preimage_domain_wrapped_domain(pma2); + return typed::pw_multi_aff, Anonymous>(res); +} + +template +template +typed::union_pw_multi_aff, Anonymous> typed::pw_aff, Anonymous>::preimage_domain_wrapped_domain(const typed::union_pw_multi_aff &upma2) const +{ + auto res = isl::pw_aff::preimage_domain_wrapped_domain(upma2); + return typed::union_pw_multi_aff, Anonymous>(res); +} + +template +template +typed::multi_pw_aff, Arg1>, pair> typed::pw_aff, Anonymous>::product(const typed::multi_pw_aff &multi2) const +{ + auto res = isl::pw_aff::product(multi2); + return typed::multi_pw_aff, Arg1>, pair>(res); +} + +template +template +typed::pw_multi_aff, Arg1>, pair> typed::pw_aff, Anonymous>::product(const typed::pw_multi_aff &pma2) const +{ + auto res = isl::pw_aff::product(pma2); + return typed::pw_multi_aff, Arg1>, pair>(res); +} + +template +template +typed::pw_aff typed::pw_aff, Anonymous>::pullback(const typed::multi_aff> &ma) const +{ + auto res = isl::pw_aff::pullback(ma); + return typed::pw_aff(res); +} + +template +typed::pw_aff typed::pw_aff, Anonymous>::pullback(const typed::multi_aff> &ma) const +{ + auto res = isl::pw_aff::pullback(ma); + return typed::pw_aff(res); +} + +template +template +typed::pw_aff typed::pw_aff, Anonymous>::pullback(const typed::multi_pw_aff> &mpa) const +{ + auto res = isl::pw_aff::pullback(mpa); + return typed::pw_aff(res); +} + +template +typed::pw_aff typed::pw_aff, Anonymous>::pullback(const typed::multi_pw_aff> &mpa) const +{ + auto res = isl::pw_aff::pullback(mpa); + return typed::pw_aff(res); +} + +template +template +typed::pw_aff typed::pw_aff, Anonymous>::pullback(const typed::pw_multi_aff> &pma) const +{ + auto res = isl::pw_aff::pullback(pma); + return typed::pw_aff(res); +} + +template +typed::pw_aff typed::pw_aff, Anonymous>::pullback(const typed::pw_multi_aff> &pma) const +{ + auto res = isl::pw_aff::pullback(pma); + return typed::pw_aff(res); +} + +template +template +typed::union_pw_aff typed::pw_aff, Anonymous>::pullback(const typed::union_pw_multi_aff> &upma) const +{ + auto res = isl::pw_aff::pullback(upma); + return typed::union_pw_aff(res); +} + +template +typed::union_pw_aff typed::pw_aff, Anonymous>::pullback(const typed::union_pw_multi_aff> &upma) const +{ + auto res = isl::pw_aff::pullback(upma); + return typed::union_pw_aff(res); +} + +template +typed::pw_multi_aff_list, Anonymous> typed::pw_aff, Anonymous>::pw_multi_aff_list() const +{ + auto res = isl::pw_aff::pw_multi_aff_list(); + return typed::pw_multi_aff_list, Anonymous>(res); +} + +template +template +typed::multi_pw_aff, pair> typed::pw_aff, Anonymous>::range_product(const typed::multi_pw_aff, Arg1> &multi2) const +{ + auto res = isl::pw_aff::range_product(multi2); + return typed::multi_pw_aff, pair>(res); +} + +template +template +typed::multi_union_pw_aff, pair> typed::pw_aff, Anonymous>::range_product(const typed::multi_union_pw_aff, Arg1> &multi2) const +{ + auto res = isl::pw_aff::range_product(multi2); + return typed::multi_union_pw_aff, pair>(res); +} + +template +template +typed::pw_multi_aff, pair> typed::pw_aff, Anonymous>::range_product(const typed::pw_multi_aff, Arg1> &pma2) const +{ + auto res = isl::pw_aff::range_product(pma2); + return typed::pw_multi_aff, pair>(res); +} + +template +template +typed::union_pw_multi_aff, pair> typed::pw_aff, Anonymous>::range_product(const typed::union_pw_multi_aff, Arg1> &upma2) const +{ + auto res = isl::pw_aff::range_product(upma2); + return typed::union_pw_multi_aff, pair>(res); +} + +template +typed::pw_aff, Anonymous> typed::pw_aff, Anonymous>::scale(const typed::val &v) const +{ + auto res = isl::pw_aff::scale(v); + return typed::pw_aff, Anonymous>(res); +} + +template +typed::pw_aff, Anonymous> typed::pw_aff, Anonymous>::scale(long v) const +{ + auto res = isl::pw_aff::scale(v); + return typed::pw_aff, Anonymous>(res); +} + +template +typed::pw_multi_aff, Anonymous> typed::pw_aff, Anonymous>::scale(const typed::multi_val &mv) const +{ + auto res = isl::pw_aff::scale(mv); + return typed::pw_multi_aff, Anonymous>(res); +} + +template +typed::pw_aff, Anonymous> typed::pw_aff, Anonymous>::scale_down(const typed::val &f) const +{ + auto res = isl::pw_aff::scale_down(f); + return typed::pw_aff, Anonymous>(res); +} + +template +typed::pw_aff, Anonymous> typed::pw_aff, Anonymous>::scale_down(long f) const +{ + auto res = isl::pw_aff::scale_down(f); + return typed::pw_aff, Anonymous>(res); +} + +template +typed::pw_multi_aff, Anonymous> typed::pw_aff, Anonymous>::scale_down(const typed::multi_val &mv) const +{ + auto res = isl::pw_aff::scale_down(mv); + return typed::pw_multi_aff, Anonymous>(res); +} + +template +typed::multi_pw_aff, Anonymous> typed::pw_aff, Anonymous>::set_at(int pos, const typed::pw_aff, Anonymous> &el) const +{ + auto res = isl::pw_aff::set_at(pos, el); + return typed::multi_pw_aff, Anonymous>(res); +} + +template +typed::multi_union_pw_aff, Anonymous> typed::pw_aff, Anonymous>::set_at(int pos, const typed::union_pw_aff, Anonymous> &el) const +{ + auto res = isl::pw_aff::set_at(pos, el); + return typed::multi_union_pw_aff, Anonymous>(res); +} + +template +template +typed::pw_multi_aff, Arg1> typed::pw_aff, Anonymous>::set_range_tuple(const typed::id &id) const +{ + auto res = isl::pw_aff::set_range_tuple(id); + return typed::pw_multi_aff, Arg1>(res); +} + +template +template +typed::pw_multi_aff, Arg1> typed::pw_aff, Anonymous>::set_range_tuple(const std::string &id) const +{ + auto res = isl::pw_aff::set_range_tuple(id); + return typed::pw_multi_aff, Arg1>(res); +} + +template +typed::space, Anonymous> typed::pw_aff, Anonymous>::space() const +{ + auto res = isl::pw_aff::space(); + return typed::space, Anonymous>(res); +} + +template +typed::multi_pw_aff, Anonymous> typed::pw_aff, Anonymous>::sub(const typed::multi_pw_aff, Anonymous> &multi2) const +{ + auto res = isl::pw_aff::sub(multi2); + return typed::multi_pw_aff, Anonymous>(res); +} + +template +typed::multi_union_pw_aff, Anonymous> typed::pw_aff, Anonymous>::sub(const typed::multi_union_pw_aff, Anonymous> &multi2) const +{ + auto res = isl::pw_aff::sub(multi2); + return typed::multi_union_pw_aff, Anonymous>(res); +} + +template +typed::pw_aff, Anonymous> typed::pw_aff, Anonymous>::sub(const typed::pw_aff, Anonymous> &pwaff2) const +{ + auto res = isl::pw_aff::sub(pwaff2); + return typed::pw_aff, Anonymous>(res); +} + +template +typed::pw_multi_aff, Anonymous> typed::pw_aff, Anonymous>::sub(const typed::pw_multi_aff, Anonymous> &pma2) const +{ + auto res = isl::pw_aff::sub(pma2); + return typed::pw_multi_aff, Anonymous>(res); +} + +template +typed::union_pw_aff, Anonymous> typed::pw_aff, Anonymous>::sub(const typed::union_pw_aff, Anonymous> &upa2) const +{ + auto res = isl::pw_aff::sub(upa2); + return typed::union_pw_aff, Anonymous>(res); +} + +template +typed::union_pw_multi_aff, Anonymous> typed::pw_aff, Anonymous>::sub(const typed::union_pw_multi_aff, Anonymous> &upma2) const +{ + auto res = isl::pw_aff::sub(upma2); + return typed::union_pw_multi_aff, Anonymous>(res); +} + +template +typed::pw_aff, Anonymous> typed::pw_aff, Anonymous>::sub(const typed::aff, Anonymous> &pwaff2) const +{ + auto res = isl::pw_aff::sub(pwaff2); + return typed::pw_aff, Anonymous>(res); +} + +template +typed::pw_aff, Anonymous> typed::pw_aff, Anonymous>::subtract_domain(const typed::set> &set) const +{ + auto res = isl::pw_aff::subtract_domain(set); + return typed::pw_aff, Anonymous>(res); +} + +template +typed::union_pw_aff, Anonymous> typed::pw_aff, Anonymous>::subtract_domain(const typed::space> &space) const +{ + auto res = isl::pw_aff::subtract_domain(space); + return typed::union_pw_aff, Anonymous>(res); +} + +template +typed::union_pw_aff, Anonymous> typed::pw_aff, Anonymous>::subtract_domain(const typed::union_set> &uset) const +{ + auto res = isl::pw_aff::subtract_domain(uset); + return typed::union_pw_aff, Anonymous>(res); +} + +template +typed::pw_aff, Anonymous> typed::pw_aff, Anonymous>::subtract_domain(const typed::basic_set> &set) const +{ + auto res = isl::pw_aff::subtract_domain(set); + return typed::pw_aff, Anonymous>(res); +} + +template +typed::pw_aff, Anonymous> typed::pw_aff, Anonymous>::subtract_domain(const typed::point> &set) const +{ + auto res = isl::pw_aff::subtract_domain(set); + return typed::pw_aff, Anonymous>(res); +} + +template +typed::multi_pw_aff, Anonymous> typed::pw_aff, Anonymous>::to_multi_pw_aff() const +{ + auto res = isl::pw_aff::to_multi_pw_aff(); + return typed::multi_pw_aff, Anonymous>(res); +} + +template +typed::union_pw_aff, Anonymous> typed::pw_aff, Anonymous>::to_union_pw_aff() const +{ + auto res = isl::pw_aff::to_union_pw_aff(); + return typed::union_pw_aff, Anonymous>(res); +} + +template +typed::union_pw_multi_aff, Anonymous> typed::pw_aff, Anonymous>::to_union_pw_multi_aff() const +{ + auto res = isl::pw_aff::to_union_pw_multi_aff(); + return typed::union_pw_multi_aff, Anonymous>(res); +} + +template +typed::multi_pw_aff, Anonymous> typed::pw_aff, Anonymous>::union_add(const typed::multi_pw_aff, Anonymous> &mpa2) const +{ + auto res = isl::pw_aff::union_add(mpa2); + return typed::multi_pw_aff, Anonymous>(res); +} + +template +typed::multi_union_pw_aff, Anonymous> typed::pw_aff, Anonymous>::union_add(const typed::multi_union_pw_aff, Anonymous> &mupa2) const +{ + auto res = isl::pw_aff::union_add(mupa2); + return typed::multi_union_pw_aff, Anonymous>(res); +} + +template +typed::pw_aff, Anonymous> typed::pw_aff, Anonymous>::union_add(const typed::pw_aff, Anonymous> &pwaff2) const +{ + auto res = isl::pw_aff::union_add(pwaff2); + return typed::pw_aff, Anonymous>(res); +} + +template +typed::pw_multi_aff, Anonymous> typed::pw_aff, Anonymous>::union_add(const typed::pw_multi_aff, Anonymous> &pma2) const +{ + auto res = isl::pw_aff::union_add(pma2); + return typed::pw_multi_aff, Anonymous>(res); +} + +template +typed::union_pw_aff, Anonymous> typed::pw_aff, Anonymous>::union_add(const typed::union_pw_aff, Anonymous> &upa2) const +{ + auto res = isl::pw_aff::union_add(upa2); + return typed::union_pw_aff, Anonymous>(res); +} + +template +typed::union_pw_multi_aff, Anonymous> typed::pw_aff, Anonymous>::union_add(const typed::union_pw_multi_aff, Anonymous> &upma2) const +{ + auto res = isl::pw_aff::union_add(upma2); + return typed::union_pw_multi_aff, Anonymous>(res); +} + +template +typed::pw_aff, Anonymous> typed::pw_aff, Anonymous>::union_add(const typed::aff, Anonymous> &pwaff2) const +{ + auto res = isl::pw_aff::union_add(pwaff2); + return typed::pw_aff, Anonymous>(res); +} + +typed::pw_aff_list::pw_aff_list(const isl::ctx &ctx, int n) + : isl::pw_aff_list(ctx, n) +{ +} + +typed::pw_aff_list::pw_aff_list(const typed::pw_aff &el) + : isl::pw_aff_list(el) +{ +} + +typed::pw_aff_list::pw_aff_list(const isl::ctx &ctx, const std::string &str) + : isl::pw_aff_list(ctx, str) +{ +} + +typed::pw_aff_list typed::pw_aff_list::add(const typed::pw_aff &el) const +{ + auto res = isl::pw_aff_list::add(el); + return typed::pw_aff_list(res); +} + +typed::pw_aff_list typed::pw_aff_list::add(const typed::aff &el) const +{ + auto res = isl::pw_aff_list::add(el); + return typed::pw_aff_list(res); +} + +typed::pw_aff typed::pw_aff_list::at(int index) const +{ + auto res = isl::pw_aff_list::at(index); + return typed::pw_aff(res); +} + +typed::pw_aff_list typed::pw_aff_list::drop(unsigned int first, unsigned int n) const +{ + auto res = isl::pw_aff_list::drop(first, n); + return typed::pw_aff_list(res); +} + +void typed::pw_aff_list::foreach(const std::function)> &fn) const +{ + auto lambda_fn = [&] (isl::pw_aff arg0) { + return fn(typed::pw_aff(arg0)); + }; + return isl::pw_aff_list::foreach(lambda_fn); +} + +void typed::pw_aff_list::foreach_scc(const std::function, typed::pw_aff)> &follows, const std::function)> &fn) const +{ + auto lambda_follows = [&] (isl::pw_aff arg0, isl::pw_aff arg1) { + return follows(typed::pw_aff(arg0), typed::pw_aff(arg1)); + }; + auto lambda_fn = [&] (isl::pw_aff_list arg0) { + return fn(typed::pw_aff_list(arg0)); + }; + return isl::pw_aff_list::foreach_scc(lambda_follows, lambda_fn); +} + +typed::pw_aff_list typed::pw_aff_list::set_at(int index, const typed::pw_aff &el) const +{ + auto res = isl::pw_aff_list::set_at(index, el); + return typed::pw_aff_list(res); +} + +template +typed::pw_aff_list::pw_aff_list(const isl::ctx &ctx, int n) + : isl::pw_aff_list(ctx, n) +{ +} + +template +typed::pw_aff_list::pw_aff_list(const typed::pw_aff &el) + : isl::pw_aff_list(el) +{ +} + +template +typed::pw_aff_list::pw_aff_list(const isl::ctx &ctx, const std::string &str) + : isl::pw_aff_list(ctx, str) +{ +} + +template +typed::pw_aff_list typed::pw_aff_list::add(const typed::pw_aff &el) const +{ + auto res = isl::pw_aff_list::add(el); + return typed::pw_aff_list(res); +} + +template +typed::pw_aff_list typed::pw_aff_list::add(const typed::aff &el) const +{ + auto res = isl::pw_aff_list::add(el); + return typed::pw_aff_list(res); +} + +template +typed::pw_aff typed::pw_aff_list::at(int index) const +{ + auto res = isl::pw_aff_list::at(index); + return typed::pw_aff(res); +} + +template +typed::pw_aff_list typed::pw_aff_list::drop(unsigned int first, unsigned int n) const +{ + auto res = isl::pw_aff_list::drop(first, n); + return typed::pw_aff_list(res); +} + +template +void typed::pw_aff_list::foreach(const std::function)> &fn) const +{ + auto lambda_fn = [&] (isl::pw_aff arg0) { + return fn(typed::pw_aff(arg0)); + }; + return isl::pw_aff_list::foreach(lambda_fn); +} + +template +void typed::pw_aff_list::foreach_scc(const std::function, typed::pw_aff)> &follows, const std::function)> &fn) const +{ + auto lambda_follows = [&] (isl::pw_aff arg0, isl::pw_aff arg1) { + return follows(typed::pw_aff(arg0), typed::pw_aff(arg1)); + }; + auto lambda_fn = [&] (isl::pw_aff_list arg0) { + return fn(typed::pw_aff_list(arg0)); + }; + return isl::pw_aff_list::foreach_scc(lambda_follows, lambda_fn); +} + +template +typed::pw_aff_list typed::pw_aff_list::set_at(int index, const typed::pw_aff &el) const +{ + auto res = isl::pw_aff_list::set_at(index, el); + return typed::pw_aff_list(res); +} + +template +typed::pw_multi_aff::pw_multi_aff(const typed::multi_aff &ma) + : isl::pw_multi_aff(ma) +{ +} + +template +typed::pw_multi_aff::pw_multi_aff(const typed::pw_aff &pa) + : isl::pw_multi_aff(pa) +{ +} + +template +typed::pw_multi_aff::pw_multi_aff(const isl::ctx &ctx, const std::string &str) + : isl::pw_multi_aff(ctx, str) +{ +} + +template +typed::multi_pw_aff typed::pw_multi_aff::add(const typed::multi_pw_aff &multi2) const +{ + auto res = isl::pw_multi_aff::add(multi2); + return typed::multi_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::pw_multi_aff::add(const typed::multi_union_pw_aff &multi2) const +{ + auto res = isl::pw_multi_aff::add(multi2); + return typed::multi_union_pw_aff(res); +} + +template +typed::pw_multi_aff typed::pw_multi_aff::add(const typed::pw_multi_aff &pma2) const +{ + auto res = isl::pw_multi_aff::add(pma2); + return typed::pw_multi_aff(res); +} + +template +typed::union_pw_multi_aff typed::pw_multi_aff::add(const typed::union_pw_multi_aff &upma2) const +{ + auto res = isl::pw_multi_aff::add(upma2); + return typed::union_pw_multi_aff(res); +} + +template +typed::pw_multi_aff typed::pw_multi_aff::add(const typed::multi_aff &pma2) const +{ + auto res = isl::pw_multi_aff::add(pma2); + return typed::pw_multi_aff(res); +} + +template +typed::pw_multi_aff typed::pw_multi_aff::add(const typed::pw_aff &pma2) const +{ + auto res = isl::pw_multi_aff::add(pma2); + return typed::pw_multi_aff(res); +} + +template +typed::pw_multi_aff typed::pw_multi_aff::add_constant(const typed::multi_val &mv) const +{ + auto res = isl::pw_multi_aff::add_constant(mv); + return typed::pw_multi_aff(res); +} + +template +typed::pw_multi_aff typed::pw_multi_aff::add_constant(const typed::val &v) const +{ + auto res = isl::pw_multi_aff::add_constant(v); + return typed::pw_multi_aff(res); +} + +template +typed::pw_multi_aff typed::pw_multi_aff::add_constant(long v) const +{ + auto res = isl::pw_multi_aff::add_constant(v); + return typed::pw_multi_aff(res); +} + +template +template +typed::union_pw_multi_aff typed::pw_multi_aff::apply(const typed::union_pw_multi_aff &upma2) const +{ + auto res = isl::pw_multi_aff::apply(upma2); + return typed::union_pw_multi_aff(res); +} + +template +typed::multi_aff typed::pw_multi_aff::as_multi_aff() const +{ + auto res = isl::pw_multi_aff::as_multi_aff(); + return typed::multi_aff(res); +} + +template +typed::multi_union_pw_aff typed::pw_multi_aff::as_multi_union_pw_aff() const +{ + auto res = isl::pw_multi_aff::as_multi_union_pw_aff(); + return typed::multi_union_pw_aff(res); +} + +template +typed::pw_multi_aff typed::pw_multi_aff::as_pw_multi_aff() const +{ + auto res = isl::pw_multi_aff::as_pw_multi_aff(); + return typed::pw_multi_aff(res); +} + +template +typed::set typed::pw_multi_aff::as_set() const +{ + auto res = isl::pw_multi_aff::as_set(); + return typed::set(res); +} + +template +typed::pw_aff typed::pw_multi_aff::at(int pos) const +{ + auto res = isl::pw_multi_aff::at(pos); + return typed::pw_aff(res); +} + +template +typed::set<> typed::pw_multi_aff::bind(const typed::multi_id &tuple) const +{ + auto res = isl::pw_multi_aff::bind(tuple); + return typed::set<>(res); +} + +template +typed::pw_multi_aff typed::pw_multi_aff::coalesce() const +{ + auto res = isl::pw_multi_aff::coalesce(); + return typed::pw_multi_aff(res); +} + +template +typed::set<> typed::pw_multi_aff::domain() const +{ + auto res = isl::pw_multi_aff::domain(); + return typed::set<>(res); +} + +template +typed::pw_multi_aff typed::pw_multi_aff::drop_unused_params() const +{ + auto res = isl::pw_multi_aff::drop_unused_params(); + return typed::pw_multi_aff(res); +} + +template +typed::pw_multi_aff typed::pw_multi_aff::extract_pw_multi_aff(const typed::space &space) const +{ + auto res = isl::pw_multi_aff::extract_pw_multi_aff(space); + return typed::pw_multi_aff(res); +} + +template +typed::pw_multi_aff typed::pw_multi_aff::gist(const typed::set<> &set) const +{ + auto res = isl::pw_multi_aff::gist(set); + return typed::pw_multi_aff(res); +} + +template +typed::union_pw_multi_aff typed::pw_multi_aff::gist(const typed::union_set<> &context) const +{ + auto res = isl::pw_multi_aff::gist(context); + return typed::union_pw_multi_aff(res); +} + +template +typed::pw_multi_aff typed::pw_multi_aff::gist(const typed::basic_set<> &set) const +{ + auto res = isl::pw_multi_aff::gist(set); + return typed::pw_multi_aff(res); +} + +template +typed::pw_multi_aff typed::pw_multi_aff::gist(const typed::point<> &set) const +{ + auto res = isl::pw_multi_aff::gist(set); + return typed::pw_multi_aff(res); +} + +template +typed::pw_multi_aff typed::pw_multi_aff::gist_params(const typed::set<> &set) const +{ + auto res = isl::pw_multi_aff::gist_params(set); + return typed::pw_multi_aff(res); +} + +template +typed::pw_multi_aff typed::pw_multi_aff::gist_params(const typed::basic_set<> &set) const +{ + auto res = isl::pw_multi_aff::gist_params(set); + return typed::pw_multi_aff(res); +} + +template +typed::pw_multi_aff typed::pw_multi_aff::gist_params(const typed::point<> &set) const +{ + auto res = isl::pw_multi_aff::gist_params(set); + return typed::pw_multi_aff(res); +} + +template +typed::multi_pw_aff typed::pw_multi_aff::identity() const +{ + auto res = isl::pw_multi_aff::identity(); + return typed::multi_pw_aff(res); +} + +template +template +typed::pw_multi_aff typed::pw_multi_aff::insert_domain(const typed::space &domain) const +{ + auto res = isl::pw_multi_aff::insert_domain(domain); + return typed::pw_multi_aff(res); +} + +template +typed::pw_multi_aff typed::pw_multi_aff::intersect_params(const typed::set<> &set) const +{ + auto res = isl::pw_multi_aff::intersect_params(set); + return typed::pw_multi_aff(res); +} + +template +typed::pw_multi_aff typed::pw_multi_aff::intersect_params(const typed::basic_set<> &set) const +{ + auto res = isl::pw_multi_aff::intersect_params(set); + return typed::pw_multi_aff(res); +} + +template +typed::pw_multi_aff typed::pw_multi_aff::intersect_params(const typed::point<> &set) const +{ + auto res = isl::pw_multi_aff::intersect_params(set); + return typed::pw_multi_aff(res); +} + +template +typed::pw_aff_list typed::pw_multi_aff::list() const +{ + auto res = isl::pw_multi_aff::list(); + return typed::pw_aff_list(res); +} + +template +typed::multi_pw_aff typed::pw_multi_aff::max(const typed::multi_pw_aff &multi2) const +{ + auto res = isl::pw_multi_aff::max(multi2); + return typed::multi_pw_aff(res); +} + +template +typed::multi_val typed::pw_multi_aff::max_multi_val() const +{ + auto res = isl::pw_multi_aff::max_multi_val(); + return typed::multi_val(res); +} + +template +typed::multi_pw_aff typed::pw_multi_aff::min(const typed::multi_pw_aff &multi2) const +{ + auto res = isl::pw_multi_aff::min(multi2); + return typed::multi_pw_aff(res); +} + +template +typed::multi_val typed::pw_multi_aff::min_multi_val() const +{ + auto res = isl::pw_multi_aff::min_multi_val(); + return typed::multi_val(res); +} + +template +typed::multi_pw_aff typed::pw_multi_aff::neg() const +{ + auto res = isl::pw_multi_aff::neg(); + return typed::multi_pw_aff(res); +} + +template +template +typed::multi_pw_aff> typed::pw_multi_aff::product(const typed::multi_pw_aff &multi2) const +{ + auto res = isl::pw_multi_aff::product(multi2); + return typed::multi_pw_aff>(res); +} + +template +template +typed::pw_multi_aff> typed::pw_multi_aff::product(const typed::pw_multi_aff &pma2) const +{ + auto res = isl::pw_multi_aff::product(pma2); + return typed::pw_multi_aff>(res); +} + +template +template +typed::pw_multi_aff> typed::pw_multi_aff::product(const typed::multi_aff &pma2) const +{ + auto res = isl::pw_multi_aff::product(pma2); + return typed::pw_multi_aff>(res); +} + +template +typed::pw_multi_aff> typed::pw_multi_aff::product(const typed::pw_aff &pma2) const +{ + auto res = isl::pw_multi_aff::product(pma2); + return typed::pw_multi_aff>(res); +} + +template +typed::pw_multi_aff_list typed::pw_multi_aff::pw_multi_aff_list() const +{ + auto res = isl::pw_multi_aff::pw_multi_aff_list(); + return typed::pw_multi_aff_list(res); +} + +template +typed::pw_multi_aff typed::pw_multi_aff::scale(const typed::multi_val &mv) const +{ + auto res = isl::pw_multi_aff::scale(mv); + return typed::pw_multi_aff(res); +} + +template +typed::pw_multi_aff typed::pw_multi_aff::scale(const typed::val &v) const +{ + auto res = isl::pw_multi_aff::scale(v); + return typed::pw_multi_aff(res); +} + +template +typed::pw_multi_aff typed::pw_multi_aff::scale(long v) const +{ + auto res = isl::pw_multi_aff::scale(v); + return typed::pw_multi_aff(res); +} + +template +typed::pw_multi_aff typed::pw_multi_aff::scale_down(const typed::multi_val &mv) const +{ + auto res = isl::pw_multi_aff::scale_down(mv); + return typed::pw_multi_aff(res); +} + +template +typed::pw_multi_aff typed::pw_multi_aff::scale_down(const typed::val &v) const +{ + auto res = isl::pw_multi_aff::scale_down(v); + return typed::pw_multi_aff(res); +} + +template +typed::pw_multi_aff typed::pw_multi_aff::scale_down(long v) const +{ + auto res = isl::pw_multi_aff::scale_down(v); + return typed::pw_multi_aff(res); +} + +template +typed::multi_pw_aff typed::pw_multi_aff::set_at(int pos, const typed::pw_aff &el) const +{ + auto res = isl::pw_multi_aff::set_at(pos, el); + return typed::multi_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::pw_multi_aff::set_at(int pos, const typed::union_pw_aff &el) const +{ + auto res = isl::pw_multi_aff::set_at(pos, el); + return typed::multi_union_pw_aff(res); +} + +template +template +typed::pw_multi_aff typed::pw_multi_aff::set_range_tuple(const typed::id &id) const +{ + auto res = isl::pw_multi_aff::set_range_tuple(id); + return typed::pw_multi_aff(res); +} + +template +template +typed::pw_multi_aff typed::pw_multi_aff::set_range_tuple(const std::string &id) const +{ + auto res = isl::pw_multi_aff::set_range_tuple(id); + return typed::pw_multi_aff(res); +} + +template +typed::space typed::pw_multi_aff::space() const +{ + auto res = isl::pw_multi_aff::space(); + return typed::space(res); +} + +template +typed::multi_pw_aff typed::pw_multi_aff::sub(const typed::multi_pw_aff &multi2) const +{ + auto res = isl::pw_multi_aff::sub(multi2); + return typed::multi_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::pw_multi_aff::sub(const typed::multi_union_pw_aff &multi2) const +{ + auto res = isl::pw_multi_aff::sub(multi2); + return typed::multi_union_pw_aff(res); +} + +template +typed::pw_multi_aff typed::pw_multi_aff::sub(const typed::pw_multi_aff &pma2) const +{ + auto res = isl::pw_multi_aff::sub(pma2); + return typed::pw_multi_aff(res); +} + +template +typed::union_pw_multi_aff typed::pw_multi_aff::sub(const typed::union_pw_multi_aff &upma2) const +{ + auto res = isl::pw_multi_aff::sub(upma2); + return typed::union_pw_multi_aff(res); +} + +template +typed::pw_multi_aff typed::pw_multi_aff::sub(const typed::multi_aff &pma2) const +{ + auto res = isl::pw_multi_aff::sub(pma2); + return typed::pw_multi_aff(res); +} + +template +typed::pw_multi_aff typed::pw_multi_aff::sub(const typed::pw_aff &pma2) const +{ + auto res = isl::pw_multi_aff::sub(pma2); + return typed::pw_multi_aff(res); +} + +template +typed::multi_pw_aff typed::pw_multi_aff::to_multi_pw_aff() const +{ + auto res = isl::pw_multi_aff::to_multi_pw_aff(); + return typed::multi_pw_aff(res); +} + +template +typed::union_pw_multi_aff typed::pw_multi_aff::to_union_pw_multi_aff() const +{ + auto res = isl::pw_multi_aff::to_union_pw_multi_aff(); + return typed::union_pw_multi_aff(res); +} + +template +template +typed::multi_pw_aff typed::pw_multi_aff::unbind_params_insert_domain(const typed::multi_id &domain) const +{ + auto res = isl::pw_multi_aff::unbind_params_insert_domain(domain); + return typed::multi_pw_aff(res); +} + +template +typed::multi_pw_aff typed::pw_multi_aff::union_add(const typed::multi_pw_aff &mpa2) const +{ + auto res = isl::pw_multi_aff::union_add(mpa2); + return typed::multi_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::pw_multi_aff::union_add(const typed::multi_union_pw_aff &mupa2) const +{ + auto res = isl::pw_multi_aff::union_add(mupa2); + return typed::multi_union_pw_aff(res); +} + +template +typed::pw_multi_aff typed::pw_multi_aff::union_add(const typed::pw_multi_aff &pma2) const +{ + auto res = isl::pw_multi_aff::union_add(pma2); + return typed::pw_multi_aff(res); +} + +template +typed::union_pw_multi_aff typed::pw_multi_aff::union_add(const typed::union_pw_multi_aff &upma2) const +{ + auto res = isl::pw_multi_aff::union_add(upma2); + return typed::union_pw_multi_aff(res); +} + +template +typed::pw_multi_aff typed::pw_multi_aff::union_add(const typed::multi_aff &pma2) const +{ + auto res = isl::pw_multi_aff::union_add(pma2); + return typed::pw_multi_aff(res); +} + +template +typed::pw_multi_aff typed::pw_multi_aff::union_add(const typed::pw_aff &pma2) const +{ + auto res = isl::pw_multi_aff::union_add(pma2); + return typed::pw_multi_aff(res); +} + +template +typed::pw_multi_aff::pw_multi_aff(const typed::multi_aff &ma) + : isl::pw_multi_aff(ma) +{ +} + +template +typed::pw_multi_aff::pw_multi_aff(const typed::pw_aff &pa) + : isl::pw_multi_aff(pa) +{ +} + +template +typed::pw_multi_aff::pw_multi_aff(const isl::ctx &ctx, const std::string &str) + : isl::pw_multi_aff(ctx, str) +{ +} + +template +typed::multi_pw_aff typed::pw_multi_aff::add(const typed::multi_pw_aff &multi2) const +{ + auto res = isl::pw_multi_aff::add(multi2); + return typed::multi_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::pw_multi_aff::add(const typed::multi_union_pw_aff &multi2) const +{ + auto res = isl::pw_multi_aff::add(multi2); + return typed::multi_union_pw_aff(res); +} + +template +typed::pw_multi_aff typed::pw_multi_aff::add(const typed::pw_multi_aff &pma2) const +{ + auto res = isl::pw_multi_aff::add(pma2); + return typed::pw_multi_aff(res); +} + +template +typed::union_pw_multi_aff typed::pw_multi_aff::add(const typed::union_pw_multi_aff &upma2) const +{ + auto res = isl::pw_multi_aff::add(upma2); + return typed::union_pw_multi_aff(res); +} + +template +typed::pw_multi_aff typed::pw_multi_aff::add(const typed::multi_aff &pma2) const +{ + auto res = isl::pw_multi_aff::add(pma2); + return typed::pw_multi_aff(res); +} + +template +typed::pw_multi_aff typed::pw_multi_aff::add(const typed::pw_aff &pma2) const +{ + auto res = isl::pw_multi_aff::add(pma2); + return typed::pw_multi_aff(res); +} + +template +typed::pw_multi_aff typed::pw_multi_aff::add_constant(const typed::multi_val &mv) const +{ + auto res = isl::pw_multi_aff::add_constant(mv); + return typed::pw_multi_aff(res); +} + +template +typed::pw_multi_aff typed::pw_multi_aff::add_constant(const typed::val &v) const +{ + auto res = isl::pw_multi_aff::add_constant(v); + return typed::pw_multi_aff(res); +} + +template +typed::pw_multi_aff typed::pw_multi_aff::add_constant(long v) const +{ + auto res = isl::pw_multi_aff::add_constant(v); + return typed::pw_multi_aff(res); +} + +template +template +typed::union_pw_multi_aff typed::pw_multi_aff::apply(const typed::union_pw_multi_aff &upma2) const +{ + auto res = isl::pw_multi_aff::apply(upma2); + return typed::union_pw_multi_aff(res); +} + +template +typed::map typed::pw_multi_aff::as_map() const +{ + auto res = isl::pw_multi_aff::as_map(); + return typed::map(res); +} + +template +typed::multi_aff typed::pw_multi_aff::as_multi_aff() const +{ + auto res = isl::pw_multi_aff::as_multi_aff(); + return typed::multi_aff(res); +} + +template +typed::multi_union_pw_aff typed::pw_multi_aff::as_multi_union_pw_aff() const +{ + auto res = isl::pw_multi_aff::as_multi_union_pw_aff(); + return typed::multi_union_pw_aff(res); +} + +template +typed::pw_multi_aff typed::pw_multi_aff::as_pw_multi_aff() const +{ + auto res = isl::pw_multi_aff::as_pw_multi_aff(); + return typed::pw_multi_aff(res); +} + +template +typed::union_map typed::pw_multi_aff::as_union_map() const +{ + auto res = isl::pw_multi_aff::as_union_map(); + return typed::union_map(res); +} + +template +typed::pw_aff typed::pw_multi_aff::at(int pos) const +{ + auto res = isl::pw_multi_aff::at(pos); + return typed::pw_aff(res); +} + +template +typed::set typed::pw_multi_aff::bind(const typed::multi_id &tuple) const +{ + auto res = isl::pw_multi_aff::bind(tuple); + return typed::set(res); +} + +template +typed::pw_multi_aff typed::pw_multi_aff::bind_domain(const typed::multi_id &tuple) const +{ + auto res = isl::pw_multi_aff::bind_domain(tuple); + return typed::pw_multi_aff(res); +} + +template +typed::pw_multi_aff typed::pw_multi_aff::coalesce() const +{ + auto res = isl::pw_multi_aff::coalesce(); + return typed::pw_multi_aff(res); +} + +template +typed::set typed::pw_multi_aff::domain() const +{ + auto res = isl::pw_multi_aff::domain(); + return typed::set(res); +} + +template +typed::pw_multi_aff typed::pw_multi_aff::drop_unused_params() const +{ + auto res = isl::pw_multi_aff::drop_unused_params(); + return typed::pw_multi_aff(res); +} + +template +typed::pw_multi_aff typed::pw_multi_aff::extract_pw_multi_aff(const typed::space &space) const +{ + auto res = isl::pw_multi_aff::extract_pw_multi_aff(space); + return typed::pw_multi_aff(res); +} + +template +typed::pw_multi_aff typed::pw_multi_aff::gist(const typed::set &set) const +{ + auto res = isl::pw_multi_aff::gist(set); + return typed::pw_multi_aff(res); +} + +template +typed::union_pw_multi_aff typed::pw_multi_aff::gist(const typed::union_set &context) const +{ + auto res = isl::pw_multi_aff::gist(context); + return typed::union_pw_multi_aff(res); +} + +template +typed::pw_multi_aff typed::pw_multi_aff::gist(const typed::basic_set &set) const +{ + auto res = isl::pw_multi_aff::gist(set); + return typed::pw_multi_aff(res); +} + +template +typed::pw_multi_aff typed::pw_multi_aff::gist(const typed::point &set) const +{ + auto res = isl::pw_multi_aff::gist(set); + return typed::pw_multi_aff(res); +} + +template +typed::pw_multi_aff typed::pw_multi_aff::gist_params(const typed::set<> &set) const +{ + auto res = isl::pw_multi_aff::gist_params(set); + return typed::pw_multi_aff(res); +} + +template +typed::pw_multi_aff typed::pw_multi_aff::gist_params(const typed::basic_set<> &set) const +{ + auto res = isl::pw_multi_aff::gist_params(set); + return typed::pw_multi_aff(res); +} + +template +typed::pw_multi_aff typed::pw_multi_aff::gist_params(const typed::point<> &set) const +{ + auto res = isl::pw_multi_aff::gist_params(set); + return typed::pw_multi_aff(res); +} + +template +typed::multi_pw_aff typed::pw_multi_aff::identity() const +{ + auto res = isl::pw_multi_aff::identity(); + return typed::multi_pw_aff(res); +} + +template +typed::pw_multi_aff typed::pw_multi_aff::intersect_domain(const typed::set &set) const +{ + auto res = isl::pw_multi_aff::intersect_domain(set); + return typed::pw_multi_aff(res); +} + +template +typed::union_pw_multi_aff typed::pw_multi_aff::intersect_domain(const typed::space &space) const +{ + auto res = isl::pw_multi_aff::intersect_domain(space); + return typed::union_pw_multi_aff(res); +} + +template +typed::union_pw_multi_aff typed::pw_multi_aff::intersect_domain(const typed::union_set &uset) const +{ + auto res = isl::pw_multi_aff::intersect_domain(uset); + return typed::union_pw_multi_aff(res); +} + +template +typed::pw_multi_aff typed::pw_multi_aff::intersect_domain(const typed::basic_set &set) const +{ + auto res = isl::pw_multi_aff::intersect_domain(set); + return typed::pw_multi_aff(res); +} + +template +typed::pw_multi_aff typed::pw_multi_aff::intersect_domain(const typed::point &set) const +{ + auto res = isl::pw_multi_aff::intersect_domain(set); + return typed::pw_multi_aff(res); +} + +template +typed::pw_multi_aff typed::pw_multi_aff::intersect_params(const typed::set<> &set) const +{ + auto res = isl::pw_multi_aff::intersect_params(set); + return typed::pw_multi_aff(res); +} + +template +typed::pw_multi_aff typed::pw_multi_aff::intersect_params(const typed::basic_set<> &set) const +{ + auto res = isl::pw_multi_aff::intersect_params(set); + return typed::pw_multi_aff(res); +} + +template +typed::pw_multi_aff typed::pw_multi_aff::intersect_params(const typed::point<> &set) const +{ + auto res = isl::pw_multi_aff::intersect_params(set); + return typed::pw_multi_aff(res); +} + +template +typed::pw_aff_list typed::pw_multi_aff::list() const +{ + auto res = isl::pw_multi_aff::list(); + return typed::pw_aff_list(res); +} + +template +typed::multi_pw_aff typed::pw_multi_aff::max(const typed::multi_pw_aff &multi2) const +{ + auto res = isl::pw_multi_aff::max(multi2); + return typed::multi_pw_aff(res); +} + +template +typed::multi_val typed::pw_multi_aff::max_multi_val() const +{ + auto res = isl::pw_multi_aff::max_multi_val(); + return typed::multi_val(res); +} + +template +typed::multi_pw_aff typed::pw_multi_aff::min(const typed::multi_pw_aff &multi2) const +{ + auto res = isl::pw_multi_aff::min(multi2); + return typed::multi_pw_aff(res); +} + +template +typed::multi_val typed::pw_multi_aff::min_multi_val() const +{ + auto res = isl::pw_multi_aff::min_multi_val(); + return typed::multi_val(res); +} + +template +typed::multi_pw_aff typed::pw_multi_aff::neg() const +{ + auto res = isl::pw_multi_aff::neg(); + return typed::multi_pw_aff(res); +} + +template +template +typed::multi_pw_aff, pair> typed::pw_multi_aff::product(const typed::multi_pw_aff &multi2) const +{ + auto res = isl::pw_multi_aff::product(multi2); + return typed::multi_pw_aff, pair>(res); +} + +template +template +typed::pw_multi_aff, pair> typed::pw_multi_aff::product(const typed::pw_multi_aff &pma2) const +{ + auto res = isl::pw_multi_aff::product(pma2); + return typed::pw_multi_aff, pair>(res); +} + +template +template +typed::pw_multi_aff, pair> typed::pw_multi_aff::product(const typed::multi_aff &pma2) const +{ + auto res = isl::pw_multi_aff::product(pma2); + return typed::pw_multi_aff, pair>(res); +} + +template +template +typed::pw_multi_aff, pair> typed::pw_multi_aff::product(const typed::pw_aff &pma2) const +{ + auto res = isl::pw_multi_aff::product(pma2); + return typed::pw_multi_aff, pair>(res); +} + +template +template +typed::multi_pw_aff typed::pw_multi_aff::pullback(const typed::multi_pw_aff &mpa2) const +{ + auto res = isl::pw_multi_aff::pullback(mpa2); + return typed::multi_pw_aff(res); +} + +template +typed::multi_pw_aff typed::pw_multi_aff::pullback(const typed::multi_pw_aff &mpa2) const +{ + auto res = isl::pw_multi_aff::pullback(mpa2); + return typed::multi_pw_aff(res); +} + +template +template +typed::pw_multi_aff typed::pw_multi_aff::pullback(const typed::multi_aff &ma) const +{ + auto res = isl::pw_multi_aff::pullback(ma); + return typed::pw_multi_aff(res); +} + +template +typed::pw_multi_aff typed::pw_multi_aff::pullback(const typed::multi_aff &ma) const +{ + auto res = isl::pw_multi_aff::pullback(ma); + return typed::pw_multi_aff(res); +} + +template +template +typed::pw_multi_aff typed::pw_multi_aff::pullback(const typed::pw_multi_aff &pma2) const +{ + auto res = isl::pw_multi_aff::pullback(pma2); + return typed::pw_multi_aff(res); +} + +template +typed::pw_multi_aff typed::pw_multi_aff::pullback(const typed::pw_multi_aff &pma2) const +{ + auto res = isl::pw_multi_aff::pullback(pma2); + return typed::pw_multi_aff(res); +} + +template +template +typed::union_pw_multi_aff typed::pw_multi_aff::pullback(const typed::union_pw_multi_aff &upma2) const +{ + auto res = isl::pw_multi_aff::pullback(upma2); + return typed::union_pw_multi_aff(res); +} + +template +typed::union_pw_multi_aff typed::pw_multi_aff::pullback(const typed::union_pw_multi_aff &upma2) const +{ + auto res = isl::pw_multi_aff::pullback(upma2); + return typed::union_pw_multi_aff(res); +} + +template +typed::pw_multi_aff_list typed::pw_multi_aff::pw_multi_aff_list() const +{ + auto res = isl::pw_multi_aff::pw_multi_aff_list(); + return typed::pw_multi_aff_list(res); +} + +template +template +typed::multi_pw_aff> typed::pw_multi_aff::range_product(const typed::multi_pw_aff &multi2) const +{ + auto res = isl::pw_multi_aff::range_product(multi2); + return typed::multi_pw_aff>(res); +} + +template +template +typed::multi_union_pw_aff> typed::pw_multi_aff::range_product(const typed::multi_union_pw_aff &multi2) const +{ + auto res = isl::pw_multi_aff::range_product(multi2); + return typed::multi_union_pw_aff>(res); +} + +template +template +typed::pw_multi_aff> typed::pw_multi_aff::range_product(const typed::pw_multi_aff &pma2) const +{ + auto res = isl::pw_multi_aff::range_product(pma2); + return typed::pw_multi_aff>(res); +} + +template +template +typed::union_pw_multi_aff> typed::pw_multi_aff::range_product(const typed::union_pw_multi_aff &upma2) const +{ + auto res = isl::pw_multi_aff::range_product(upma2); + return typed::union_pw_multi_aff>(res); +} + +template +template +typed::pw_multi_aff> typed::pw_multi_aff::range_product(const typed::multi_aff &pma2) const +{ + auto res = isl::pw_multi_aff::range_product(pma2); + return typed::pw_multi_aff>(res); +} + +template +typed::pw_multi_aff> typed::pw_multi_aff::range_product(const typed::pw_aff &pma2) const +{ + auto res = isl::pw_multi_aff::range_product(pma2); + return typed::pw_multi_aff>(res); +} + +template +typed::pw_multi_aff typed::pw_multi_aff::scale(const typed::multi_val &mv) const +{ + auto res = isl::pw_multi_aff::scale(mv); + return typed::pw_multi_aff(res); +} + +template +typed::pw_multi_aff typed::pw_multi_aff::scale(const typed::val &v) const +{ + auto res = isl::pw_multi_aff::scale(v); + return typed::pw_multi_aff(res); +} + +template +typed::pw_multi_aff typed::pw_multi_aff::scale(long v) const +{ + auto res = isl::pw_multi_aff::scale(v); + return typed::pw_multi_aff(res); +} + +template +typed::pw_multi_aff typed::pw_multi_aff::scale_down(const typed::multi_val &mv) const +{ + auto res = isl::pw_multi_aff::scale_down(mv); + return typed::pw_multi_aff(res); +} + +template +typed::pw_multi_aff typed::pw_multi_aff::scale_down(const typed::val &v) const +{ + auto res = isl::pw_multi_aff::scale_down(v); + return typed::pw_multi_aff(res); +} + +template +typed::pw_multi_aff typed::pw_multi_aff::scale_down(long v) const +{ + auto res = isl::pw_multi_aff::scale_down(v); + return typed::pw_multi_aff(res); +} + +template +typed::multi_pw_aff typed::pw_multi_aff::set_at(int pos, const typed::pw_aff &el) const +{ + auto res = isl::pw_multi_aff::set_at(pos, el); + return typed::multi_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::pw_multi_aff::set_at(int pos, const typed::union_pw_aff &el) const +{ + auto res = isl::pw_multi_aff::set_at(pos, el); + return typed::multi_union_pw_aff(res); +} + +template +template +typed::pw_multi_aff typed::pw_multi_aff::set_range_tuple(const typed::id &id) const +{ + auto res = isl::pw_multi_aff::set_range_tuple(id); + return typed::pw_multi_aff(res); +} + +template +template +typed::pw_multi_aff typed::pw_multi_aff::set_range_tuple(const std::string &id) const +{ + auto res = isl::pw_multi_aff::set_range_tuple(id); + return typed::pw_multi_aff(res); +} + +template +typed::space typed::pw_multi_aff::space() const +{ + auto res = isl::pw_multi_aff::space(); + return typed::space(res); +} + +template +typed::multi_pw_aff typed::pw_multi_aff::sub(const typed::multi_pw_aff &multi2) const +{ + auto res = isl::pw_multi_aff::sub(multi2); + return typed::multi_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::pw_multi_aff::sub(const typed::multi_union_pw_aff &multi2) const +{ + auto res = isl::pw_multi_aff::sub(multi2); + return typed::multi_union_pw_aff(res); +} + +template +typed::pw_multi_aff typed::pw_multi_aff::sub(const typed::pw_multi_aff &pma2) const +{ + auto res = isl::pw_multi_aff::sub(pma2); + return typed::pw_multi_aff(res); +} + +template +typed::union_pw_multi_aff typed::pw_multi_aff::sub(const typed::union_pw_multi_aff &upma2) const +{ + auto res = isl::pw_multi_aff::sub(upma2); + return typed::union_pw_multi_aff(res); +} + +template +typed::pw_multi_aff typed::pw_multi_aff::sub(const typed::multi_aff &pma2) const +{ + auto res = isl::pw_multi_aff::sub(pma2); + return typed::pw_multi_aff(res); +} + +template +typed::pw_multi_aff typed::pw_multi_aff::sub(const typed::pw_aff &pma2) const +{ + auto res = isl::pw_multi_aff::sub(pma2); + return typed::pw_multi_aff(res); +} + +template +typed::pw_multi_aff typed::pw_multi_aff::subtract_domain(const typed::set &set) const +{ + auto res = isl::pw_multi_aff::subtract_domain(set); + return typed::pw_multi_aff(res); +} + +template +typed::union_pw_multi_aff typed::pw_multi_aff::subtract_domain(const typed::space &space) const +{ + auto res = isl::pw_multi_aff::subtract_domain(space); + return typed::union_pw_multi_aff(res); +} + +template +typed::union_pw_multi_aff typed::pw_multi_aff::subtract_domain(const typed::union_set &uset) const +{ + auto res = isl::pw_multi_aff::subtract_domain(uset); + return typed::union_pw_multi_aff(res); +} + +template +typed::pw_multi_aff typed::pw_multi_aff::subtract_domain(const typed::basic_set &set) const +{ + auto res = isl::pw_multi_aff::subtract_domain(set); + return typed::pw_multi_aff(res); +} + +template +typed::pw_multi_aff typed::pw_multi_aff::subtract_domain(const typed::point &set) const +{ + auto res = isl::pw_multi_aff::subtract_domain(set); + return typed::pw_multi_aff(res); +} + +template +typed::multi_pw_aff typed::pw_multi_aff::to_multi_pw_aff() const +{ + auto res = isl::pw_multi_aff::to_multi_pw_aff(); + return typed::multi_pw_aff(res); +} + +template +typed::union_pw_multi_aff typed::pw_multi_aff::to_union_pw_multi_aff() const +{ + auto res = isl::pw_multi_aff::to_union_pw_multi_aff(); + return typed::union_pw_multi_aff(res); +} + +template +typed::multi_pw_aff typed::pw_multi_aff::union_add(const typed::multi_pw_aff &mpa2) const +{ + auto res = isl::pw_multi_aff::union_add(mpa2); + return typed::multi_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::pw_multi_aff::union_add(const typed::multi_union_pw_aff &mupa2) const +{ + auto res = isl::pw_multi_aff::union_add(mupa2); + return typed::multi_union_pw_aff(res); +} + +template +typed::pw_multi_aff typed::pw_multi_aff::union_add(const typed::pw_multi_aff &pma2) const +{ + auto res = isl::pw_multi_aff::union_add(pma2); + return typed::pw_multi_aff(res); +} + +template +typed::union_pw_multi_aff typed::pw_multi_aff::union_add(const typed::union_pw_multi_aff &upma2) const +{ + auto res = isl::pw_multi_aff::union_add(upma2); + return typed::union_pw_multi_aff(res); +} + +template +typed::pw_multi_aff typed::pw_multi_aff::union_add(const typed::multi_aff &pma2) const +{ + auto res = isl::pw_multi_aff::union_add(pma2); + return typed::pw_multi_aff(res); +} + +template +typed::pw_multi_aff typed::pw_multi_aff::union_add(const typed::pw_aff &pma2) const +{ + auto res = isl::pw_multi_aff::union_add(pma2); + return typed::pw_multi_aff(res); +} + +template +typed::pw_multi_aff, Range>::pw_multi_aff(const typed::multi_aff, Range> &ma) + : isl::pw_multi_aff(ma) +{ +} + +template +typed::pw_multi_aff, Range>::pw_multi_aff(const typed::pw_aff, Range> &pa) + : isl::pw_multi_aff(pa) +{ +} + +template +typed::pw_multi_aff, Range>::pw_multi_aff(const isl::ctx &ctx, const std::string &str) + : isl::pw_multi_aff(ctx, str) +{ +} + +template +typed::multi_pw_aff, Range> typed::pw_multi_aff, Range>::add(const typed::multi_pw_aff, Range> &multi2) const +{ + auto res = isl::pw_multi_aff::add(multi2); + return typed::multi_pw_aff, Range>(res); +} + +template +typed::multi_union_pw_aff, Range> typed::pw_multi_aff, Range>::add(const typed::multi_union_pw_aff, Range> &multi2) const +{ + auto res = isl::pw_multi_aff::add(multi2); + return typed::multi_union_pw_aff, Range>(res); +} + +template +typed::pw_multi_aff, Range> typed::pw_multi_aff, Range>::add(const typed::pw_multi_aff, Range> &pma2) const +{ + auto res = isl::pw_multi_aff::add(pma2); + return typed::pw_multi_aff, Range>(res); +} + +template +typed::union_pw_multi_aff, Range> typed::pw_multi_aff, Range>::add(const typed::union_pw_multi_aff, Range> &upma2) const +{ + auto res = isl::pw_multi_aff::add(upma2); + return typed::union_pw_multi_aff, Range>(res); +} + +template +typed::pw_multi_aff, Range> typed::pw_multi_aff, Range>::add(const typed::multi_aff, Range> &pma2) const +{ + auto res = isl::pw_multi_aff::add(pma2); + return typed::pw_multi_aff, Range>(res); +} + +template +typed::pw_multi_aff, Range> typed::pw_multi_aff, Range>::add(const typed::pw_aff, Range> &pma2) const +{ + auto res = isl::pw_multi_aff::add(pma2); + return typed::pw_multi_aff, Range>(res); +} + +template +typed::pw_multi_aff, Range> typed::pw_multi_aff, Range>::add_constant(const typed::multi_val &mv) const +{ + auto res = isl::pw_multi_aff::add_constant(mv); + return typed::pw_multi_aff, Range>(res); +} + +template +typed::pw_multi_aff, Range> typed::pw_multi_aff, Range>::add_constant(const typed::val &v) const +{ + auto res = isl::pw_multi_aff::add_constant(v); + return typed::pw_multi_aff, Range>(res); +} + +template +typed::pw_multi_aff, Range> typed::pw_multi_aff, Range>::add_constant(long v) const +{ + auto res = isl::pw_multi_aff::add_constant(v); + return typed::pw_multi_aff, Range>(res); +} + +template +template +typed::union_pw_multi_aff, Arg2> typed::pw_multi_aff, Range>::apply(const typed::union_pw_multi_aff &upma2) const +{ + auto res = isl::pw_multi_aff::apply(upma2); + return typed::union_pw_multi_aff, Arg2>(res); +} + +template +typed::map, Range> typed::pw_multi_aff, Range>::as_map() const +{ + auto res = isl::pw_multi_aff::as_map(); + return typed::map, Range>(res); +} + +template +typed::multi_aff, Range> typed::pw_multi_aff, Range>::as_multi_aff() const +{ + auto res = isl::pw_multi_aff::as_multi_aff(); + return typed::multi_aff, Range>(res); +} + +template +typed::multi_union_pw_aff, Range> typed::pw_multi_aff, Range>::as_multi_union_pw_aff() const +{ + auto res = isl::pw_multi_aff::as_multi_union_pw_aff(); + return typed::multi_union_pw_aff, Range>(res); +} + +template +typed::pw_multi_aff, Range> typed::pw_multi_aff, Range>::as_pw_multi_aff() const +{ + auto res = isl::pw_multi_aff::as_pw_multi_aff(); + return typed::pw_multi_aff, Range>(res); +} + +template +typed::union_map, Range> typed::pw_multi_aff, Range>::as_union_map() const +{ + auto res = isl::pw_multi_aff::as_union_map(); + return typed::union_map, Range>(res); +} + +template +typed::pw_aff, Anonymous> typed::pw_multi_aff, Range>::at(int pos) const +{ + auto res = isl::pw_multi_aff::at(pos); + return typed::pw_aff, Anonymous>(res); +} + +template +typed::set> typed::pw_multi_aff, Range>::bind(const typed::multi_id &tuple) const +{ + auto res = isl::pw_multi_aff::bind(tuple); + return typed::set>(res); +} + +template +typed::pw_multi_aff typed::pw_multi_aff, Range>::bind_domain(const typed::multi_id> &tuple) const +{ + auto res = isl::pw_multi_aff::bind_domain(tuple); + return typed::pw_multi_aff(res); +} + +template +typed::pw_multi_aff typed::pw_multi_aff, Range>::bind_domain_wrapped_domain(const typed::multi_id &tuple) const +{ + auto res = isl::pw_multi_aff::bind_domain_wrapped_domain(tuple); + return typed::pw_multi_aff(res); +} + +template +typed::pw_multi_aff, Range> typed::pw_multi_aff, Range>::coalesce() const +{ + auto res = isl::pw_multi_aff::coalesce(); + return typed::pw_multi_aff, Range>(res); +} + +template +typed::set> typed::pw_multi_aff, Range>::domain() const +{ + auto res = isl::pw_multi_aff::domain(); + return typed::set>(res); +} + +template +typed::pw_multi_aff, Range> typed::pw_multi_aff, Range>::domain_reverse() const +{ + auto res = isl::pw_multi_aff::domain_reverse(); + return typed::pw_multi_aff, Range>(res); +} + +template +typed::pw_multi_aff, Range> typed::pw_multi_aff, Range>::drop_unused_params() const +{ + auto res = isl::pw_multi_aff::drop_unused_params(); + return typed::pw_multi_aff, Range>(res); +} + +template +typed::pw_multi_aff, Range> typed::pw_multi_aff, Range>::extract_pw_multi_aff(const typed::space, Range> &space) const +{ + auto res = isl::pw_multi_aff::extract_pw_multi_aff(space); + return typed::pw_multi_aff, Range>(res); +} + +template +typed::pw_multi_aff, Range> typed::pw_multi_aff, Range>::gist(const typed::set> &set) const +{ + auto res = isl::pw_multi_aff::gist(set); + return typed::pw_multi_aff, Range>(res); +} + +template +typed::union_pw_multi_aff, Range> typed::pw_multi_aff, Range>::gist(const typed::union_set> &context) const +{ + auto res = isl::pw_multi_aff::gist(context); + return typed::union_pw_multi_aff, Range>(res); +} + +template +typed::pw_multi_aff, Range> typed::pw_multi_aff, Range>::gist(const typed::basic_set> &set) const +{ + auto res = isl::pw_multi_aff::gist(set); + return typed::pw_multi_aff, Range>(res); +} + +template +typed::pw_multi_aff, Range> typed::pw_multi_aff, Range>::gist(const typed::point> &set) const +{ + auto res = isl::pw_multi_aff::gist(set); + return typed::pw_multi_aff, Range>(res); +} + +template +typed::pw_multi_aff, Range> typed::pw_multi_aff, Range>::gist_params(const typed::set<> &set) const +{ + auto res = isl::pw_multi_aff::gist_params(set); + return typed::pw_multi_aff, Range>(res); +} + +template +typed::pw_multi_aff, Range> typed::pw_multi_aff, Range>::gist_params(const typed::basic_set<> &set) const +{ + auto res = isl::pw_multi_aff::gist_params(set); + return typed::pw_multi_aff, Range>(res); +} + +template +typed::pw_multi_aff, Range> typed::pw_multi_aff, Range>::gist_params(const typed::point<> &set) const +{ + auto res = isl::pw_multi_aff::gist_params(set); + return typed::pw_multi_aff, Range>(res); +} + +template +typed::multi_pw_aff, Range> typed::pw_multi_aff, Range>::identity() const +{ + auto res = isl::pw_multi_aff::identity(); + return typed::multi_pw_aff, Range>(res); +} + +template +typed::pw_multi_aff, Range> typed::pw_multi_aff, Range>::intersect_domain(const typed::set> &set) const +{ + auto res = isl::pw_multi_aff::intersect_domain(set); + return typed::pw_multi_aff, Range>(res); +} + +template +typed::union_pw_multi_aff, Range> typed::pw_multi_aff, Range>::intersect_domain(const typed::space> &space) const +{ + auto res = isl::pw_multi_aff::intersect_domain(space); + return typed::union_pw_multi_aff, Range>(res); +} + +template +typed::union_pw_multi_aff, Range> typed::pw_multi_aff, Range>::intersect_domain(const typed::union_set> &uset) const +{ + auto res = isl::pw_multi_aff::intersect_domain(uset); + return typed::union_pw_multi_aff, Range>(res); +} + +template +typed::pw_multi_aff, Range> typed::pw_multi_aff, Range>::intersect_domain(const typed::basic_set> &set) const +{ + auto res = isl::pw_multi_aff::intersect_domain(set); + return typed::pw_multi_aff, Range>(res); +} + +template +typed::pw_multi_aff, Range> typed::pw_multi_aff, Range>::intersect_domain(const typed::point> &set) const +{ + auto res = isl::pw_multi_aff::intersect_domain(set); + return typed::pw_multi_aff, Range>(res); +} + +template +typed::union_pw_multi_aff, Range> typed::pw_multi_aff, Range>::intersect_domain_wrapped_domain(const typed::union_set &uset) const +{ + auto res = isl::pw_multi_aff::intersect_domain_wrapped_domain(uset); + return typed::union_pw_multi_aff, Range>(res); +} + +template +typed::pw_multi_aff, Range> typed::pw_multi_aff, Range>::intersect_params(const typed::set<> &set) const +{ + auto res = isl::pw_multi_aff::intersect_params(set); + return typed::pw_multi_aff, Range>(res); +} + +template +typed::pw_multi_aff, Range> typed::pw_multi_aff, Range>::intersect_params(const typed::basic_set<> &set) const +{ + auto res = isl::pw_multi_aff::intersect_params(set); + return typed::pw_multi_aff, Range>(res); +} + +template +typed::pw_multi_aff, Range> typed::pw_multi_aff, Range>::intersect_params(const typed::point<> &set) const +{ + auto res = isl::pw_multi_aff::intersect_params(set); + return typed::pw_multi_aff, Range>(res); +} + +template +typed::pw_aff_list, Anonymous> typed::pw_multi_aff, Range>::list() const +{ + auto res = isl::pw_multi_aff::list(); + return typed::pw_aff_list, Anonymous>(res); +} + +template +typed::multi_pw_aff, Range> typed::pw_multi_aff, Range>::max(const typed::multi_pw_aff, Range> &multi2) const +{ + auto res = isl::pw_multi_aff::max(multi2); + return typed::multi_pw_aff, Range>(res); +} + +template +typed::multi_val typed::pw_multi_aff, Range>::max_multi_val() const +{ + auto res = isl::pw_multi_aff::max_multi_val(); + return typed::multi_val(res); +} + +template +typed::multi_pw_aff, Range> typed::pw_multi_aff, Range>::min(const typed::multi_pw_aff, Range> &multi2) const +{ + auto res = isl::pw_multi_aff::min(multi2); + return typed::multi_pw_aff, Range>(res); +} + +template +typed::multi_val typed::pw_multi_aff, Range>::min_multi_val() const +{ + auto res = isl::pw_multi_aff::min_multi_val(); + return typed::multi_val(res); +} + +template +typed::multi_pw_aff, Range> typed::pw_multi_aff, Range>::neg() const +{ + auto res = isl::pw_multi_aff::neg(); + return typed::multi_pw_aff, Range>(res); +} + +template +template +typed::pw_multi_aff, Range> typed::pw_multi_aff, Range>::preimage_domain_wrapped_domain(const typed::pw_multi_aff &pma2) const +{ + auto res = isl::pw_multi_aff::preimage_domain_wrapped_domain(pma2); + return typed::pw_multi_aff, Range>(res); +} + +template +template +typed::union_pw_multi_aff, Range> typed::pw_multi_aff, Range>::preimage_domain_wrapped_domain(const typed::union_pw_multi_aff &upma2) const +{ + auto res = isl::pw_multi_aff::preimage_domain_wrapped_domain(upma2); + return typed::union_pw_multi_aff, Range>(res); +} + +template +template +typed::pw_multi_aff, Range> typed::pw_multi_aff, Range>::preimage_domain_wrapped_domain(const typed::multi_aff &pma2) const +{ + auto res = isl::pw_multi_aff::preimage_domain_wrapped_domain(pma2); + return typed::pw_multi_aff, Range>(res); +} + +template +template +typed::pw_multi_aff, Range> typed::pw_multi_aff, Range>::preimage_domain_wrapped_domain(const typed::pw_aff &pma2) const +{ + auto res = isl::pw_multi_aff::preimage_domain_wrapped_domain(pma2); + return typed::pw_multi_aff, Range>(res); +} + +template +template +typed::multi_pw_aff, Arg2>, pair> typed::pw_multi_aff, Range>::product(const typed::multi_pw_aff &multi2) const +{ + auto res = isl::pw_multi_aff::product(multi2); + return typed::multi_pw_aff, Arg2>, pair>(res); +} + +template +template +typed::pw_multi_aff, Arg2>, pair> typed::pw_multi_aff, Range>::product(const typed::pw_multi_aff &pma2) const +{ + auto res = isl::pw_multi_aff::product(pma2); + return typed::pw_multi_aff, Arg2>, pair>(res); +} + +template +template +typed::pw_multi_aff, Arg2>, pair> typed::pw_multi_aff, Range>::product(const typed::multi_aff &pma2) const +{ + auto res = isl::pw_multi_aff::product(pma2); + return typed::pw_multi_aff, Arg2>, pair>(res); +} + +template +template +typed::pw_multi_aff, Arg2>, pair> typed::pw_multi_aff, Range>::product(const typed::pw_aff &pma2) const +{ + auto res = isl::pw_multi_aff::product(pma2); + return typed::pw_multi_aff, Arg2>, pair>(res); +} + +template +template +typed::multi_pw_aff typed::pw_multi_aff, Range>::pullback(const typed::multi_pw_aff> &mpa2) const +{ + auto res = isl::pw_multi_aff::pullback(mpa2); + return typed::multi_pw_aff(res); +} + +template +typed::multi_pw_aff typed::pw_multi_aff, Range>::pullback(const typed::multi_pw_aff> &mpa2) const +{ + auto res = isl::pw_multi_aff::pullback(mpa2); + return typed::multi_pw_aff(res); +} + +template +template +typed::pw_multi_aff typed::pw_multi_aff, Range>::pullback(const typed::multi_aff> &ma) const +{ + auto res = isl::pw_multi_aff::pullback(ma); + return typed::pw_multi_aff(res); +} + +template +typed::pw_multi_aff typed::pw_multi_aff, Range>::pullback(const typed::multi_aff> &ma) const +{ + auto res = isl::pw_multi_aff::pullback(ma); + return typed::pw_multi_aff(res); +} + +template +template +typed::pw_multi_aff typed::pw_multi_aff, Range>::pullback(const typed::pw_multi_aff> &pma2) const +{ + auto res = isl::pw_multi_aff::pullback(pma2); + return typed::pw_multi_aff(res); +} + +template +typed::pw_multi_aff typed::pw_multi_aff, Range>::pullback(const typed::pw_multi_aff> &pma2) const +{ + auto res = isl::pw_multi_aff::pullback(pma2); + return typed::pw_multi_aff(res); +} + +template +template +typed::union_pw_multi_aff typed::pw_multi_aff, Range>::pullback(const typed::union_pw_multi_aff> &upma2) const +{ + auto res = isl::pw_multi_aff::pullback(upma2); + return typed::union_pw_multi_aff(res); +} + +template +typed::union_pw_multi_aff typed::pw_multi_aff, Range>::pullback(const typed::union_pw_multi_aff> &upma2) const +{ + auto res = isl::pw_multi_aff::pullback(upma2); + return typed::union_pw_multi_aff(res); +} + +template +typed::pw_multi_aff_list, Range> typed::pw_multi_aff, Range>::pw_multi_aff_list() const +{ + auto res = isl::pw_multi_aff::pw_multi_aff_list(); + return typed::pw_multi_aff_list, Range>(res); +} + +template +template +typed::multi_pw_aff, pair> typed::pw_multi_aff, Range>::range_product(const typed::multi_pw_aff, Arg2> &multi2) const +{ + auto res = isl::pw_multi_aff::range_product(multi2); + return typed::multi_pw_aff, pair>(res); +} + +template +template +typed::multi_union_pw_aff, pair> typed::pw_multi_aff, Range>::range_product(const typed::multi_union_pw_aff, Arg2> &multi2) const +{ + auto res = isl::pw_multi_aff::range_product(multi2); + return typed::multi_union_pw_aff, pair>(res); +} + +template +template +typed::pw_multi_aff, pair> typed::pw_multi_aff, Range>::range_product(const typed::pw_multi_aff, Arg2> &pma2) const +{ + auto res = isl::pw_multi_aff::range_product(pma2); + return typed::pw_multi_aff, pair>(res); +} + +template +template +typed::union_pw_multi_aff, pair> typed::pw_multi_aff, Range>::range_product(const typed::union_pw_multi_aff, Arg2> &upma2) const +{ + auto res = isl::pw_multi_aff::range_product(upma2); + return typed::union_pw_multi_aff, pair>(res); +} + +template +template +typed::pw_multi_aff, pair> typed::pw_multi_aff, Range>::range_product(const typed::multi_aff, Arg2> &pma2) const +{ + auto res = isl::pw_multi_aff::range_product(pma2); + return typed::pw_multi_aff, pair>(res); +} + +template +typed::pw_multi_aff, pair> typed::pw_multi_aff, Range>::range_product(const typed::pw_aff, Anonymous> &pma2) const +{ + auto res = isl::pw_multi_aff::range_product(pma2); + return typed::pw_multi_aff, pair>(res); +} + +template +typed::pw_multi_aff, Range> typed::pw_multi_aff, Range>::scale(const typed::multi_val &mv) const +{ + auto res = isl::pw_multi_aff::scale(mv); + return typed::pw_multi_aff, Range>(res); +} + +template +typed::pw_multi_aff, Range> typed::pw_multi_aff, Range>::scale(const typed::val &v) const +{ + auto res = isl::pw_multi_aff::scale(v); + return typed::pw_multi_aff, Range>(res); +} + +template +typed::pw_multi_aff, Range> typed::pw_multi_aff, Range>::scale(long v) const +{ + auto res = isl::pw_multi_aff::scale(v); + return typed::pw_multi_aff, Range>(res); +} + +template +typed::pw_multi_aff, Range> typed::pw_multi_aff, Range>::scale_down(const typed::multi_val &mv) const +{ + auto res = isl::pw_multi_aff::scale_down(mv); + return typed::pw_multi_aff, Range>(res); +} + +template +typed::pw_multi_aff, Range> typed::pw_multi_aff, Range>::scale_down(const typed::val &v) const +{ + auto res = isl::pw_multi_aff::scale_down(v); + return typed::pw_multi_aff, Range>(res); +} + +template +typed::pw_multi_aff, Range> typed::pw_multi_aff, Range>::scale_down(long v) const +{ + auto res = isl::pw_multi_aff::scale_down(v); + return typed::pw_multi_aff, Range>(res); +} + +template +typed::multi_pw_aff, Range> typed::pw_multi_aff, Range>::set_at(int pos, const typed::pw_aff, Anonymous> &el) const +{ + auto res = isl::pw_multi_aff::set_at(pos, el); + return typed::multi_pw_aff, Range>(res); +} + +template +typed::multi_union_pw_aff, Range> typed::pw_multi_aff, Range>::set_at(int pos, const typed::union_pw_aff, Anonymous> &el) const +{ + auto res = isl::pw_multi_aff::set_at(pos, el); + return typed::multi_union_pw_aff, Range>(res); +} + +template +template +typed::pw_multi_aff, Arg1> typed::pw_multi_aff, Range>::set_range_tuple(const typed::id &id) const +{ + auto res = isl::pw_multi_aff::set_range_tuple(id); + return typed::pw_multi_aff, Arg1>(res); +} + +template +template +typed::pw_multi_aff, Arg1> typed::pw_multi_aff, Range>::set_range_tuple(const std::string &id) const +{ + auto res = isl::pw_multi_aff::set_range_tuple(id); + return typed::pw_multi_aff, Arg1>(res); +} + +template +typed::space, Range> typed::pw_multi_aff, Range>::space() const +{ + auto res = isl::pw_multi_aff::space(); + return typed::space, Range>(res); +} + +template +typed::multi_pw_aff, Range> typed::pw_multi_aff, Range>::sub(const typed::multi_pw_aff, Range> &multi2) const +{ + auto res = isl::pw_multi_aff::sub(multi2); + return typed::multi_pw_aff, Range>(res); +} + +template +typed::multi_union_pw_aff, Range> typed::pw_multi_aff, Range>::sub(const typed::multi_union_pw_aff, Range> &multi2) const +{ + auto res = isl::pw_multi_aff::sub(multi2); + return typed::multi_union_pw_aff, Range>(res); +} + +template +typed::pw_multi_aff, Range> typed::pw_multi_aff, Range>::sub(const typed::pw_multi_aff, Range> &pma2) const +{ + auto res = isl::pw_multi_aff::sub(pma2); + return typed::pw_multi_aff, Range>(res); +} + +template +typed::union_pw_multi_aff, Range> typed::pw_multi_aff, Range>::sub(const typed::union_pw_multi_aff, Range> &upma2) const +{ + auto res = isl::pw_multi_aff::sub(upma2); + return typed::union_pw_multi_aff, Range>(res); +} + +template +typed::pw_multi_aff, Range> typed::pw_multi_aff, Range>::sub(const typed::multi_aff, Range> &pma2) const +{ + auto res = isl::pw_multi_aff::sub(pma2); + return typed::pw_multi_aff, Range>(res); +} + +template +typed::pw_multi_aff, Range> typed::pw_multi_aff, Range>::sub(const typed::pw_aff, Range> &pma2) const +{ + auto res = isl::pw_multi_aff::sub(pma2); + return typed::pw_multi_aff, Range>(res); +} + +template +typed::pw_multi_aff, Range> typed::pw_multi_aff, Range>::subtract_domain(const typed::set> &set) const +{ + auto res = isl::pw_multi_aff::subtract_domain(set); + return typed::pw_multi_aff, Range>(res); +} + +template +typed::union_pw_multi_aff, Range> typed::pw_multi_aff, Range>::subtract_domain(const typed::space> &space) const +{ + auto res = isl::pw_multi_aff::subtract_domain(space); + return typed::union_pw_multi_aff, Range>(res); +} + +template +typed::union_pw_multi_aff, Range> typed::pw_multi_aff, Range>::subtract_domain(const typed::union_set> &uset) const +{ + auto res = isl::pw_multi_aff::subtract_domain(uset); + return typed::union_pw_multi_aff, Range>(res); +} + +template +typed::pw_multi_aff, Range> typed::pw_multi_aff, Range>::subtract_domain(const typed::basic_set> &set) const +{ + auto res = isl::pw_multi_aff::subtract_domain(set); + return typed::pw_multi_aff, Range>(res); +} + +template +typed::pw_multi_aff, Range> typed::pw_multi_aff, Range>::subtract_domain(const typed::point> &set) const +{ + auto res = isl::pw_multi_aff::subtract_domain(set); + return typed::pw_multi_aff, Range>(res); +} + +template +typed::multi_pw_aff, Range> typed::pw_multi_aff, Range>::to_multi_pw_aff() const +{ + auto res = isl::pw_multi_aff::to_multi_pw_aff(); + return typed::multi_pw_aff, Range>(res); +} + +template +typed::union_pw_multi_aff, Range> typed::pw_multi_aff, Range>::to_union_pw_multi_aff() const +{ + auto res = isl::pw_multi_aff::to_union_pw_multi_aff(); + return typed::union_pw_multi_aff, Range>(res); +} + +template +typed::multi_pw_aff, Range> typed::pw_multi_aff, Range>::union_add(const typed::multi_pw_aff, Range> &mpa2) const +{ + auto res = isl::pw_multi_aff::union_add(mpa2); + return typed::multi_pw_aff, Range>(res); +} + +template +typed::multi_union_pw_aff, Range> typed::pw_multi_aff, Range>::union_add(const typed::multi_union_pw_aff, Range> &mupa2) const +{ + auto res = isl::pw_multi_aff::union_add(mupa2); + return typed::multi_union_pw_aff, Range>(res); +} + +template +typed::pw_multi_aff, Range> typed::pw_multi_aff, Range>::union_add(const typed::pw_multi_aff, Range> &pma2) const +{ + auto res = isl::pw_multi_aff::union_add(pma2); + return typed::pw_multi_aff, Range>(res); +} + +template +typed::union_pw_multi_aff, Range> typed::pw_multi_aff, Range>::union_add(const typed::union_pw_multi_aff, Range> &upma2) const +{ + auto res = isl::pw_multi_aff::union_add(upma2); + return typed::union_pw_multi_aff, Range>(res); +} + +template +typed::pw_multi_aff, Range> typed::pw_multi_aff, Range>::union_add(const typed::multi_aff, Range> &pma2) const +{ + auto res = isl::pw_multi_aff::union_add(pma2); + return typed::pw_multi_aff, Range>(res); +} + +template +typed::pw_multi_aff, Range> typed::pw_multi_aff, Range>::union_add(const typed::pw_aff, Range> &pma2) const +{ + auto res = isl::pw_multi_aff::union_add(pma2); + return typed::pw_multi_aff, Range>(res); +} + +template +typed::pw_multi_aff>::pw_multi_aff(const typed::multi_aff> &ma) + : isl::pw_multi_aff(ma) +{ +} + +template +typed::pw_multi_aff>::pw_multi_aff(const typed::pw_aff> &pa) + : isl::pw_multi_aff(pa) +{ +} + +template +typed::pw_multi_aff>::pw_multi_aff(const isl::ctx &ctx, const std::string &str) + : isl::pw_multi_aff(ctx, str) +{ +} + +template +typed::multi_pw_aff> typed::pw_multi_aff>::add(const typed::multi_pw_aff> &multi2) const +{ + auto res = isl::pw_multi_aff::add(multi2); + return typed::multi_pw_aff>(res); +} + +template +typed::multi_union_pw_aff> typed::pw_multi_aff>::add(const typed::multi_union_pw_aff> &multi2) const +{ + auto res = isl::pw_multi_aff::add(multi2); + return typed::multi_union_pw_aff>(res); +} + +template +typed::pw_multi_aff> typed::pw_multi_aff>::add(const typed::pw_multi_aff> &pma2) const +{ + auto res = isl::pw_multi_aff::add(pma2); + return typed::pw_multi_aff>(res); +} + +template +typed::union_pw_multi_aff> typed::pw_multi_aff>::add(const typed::union_pw_multi_aff> &upma2) const +{ + auto res = isl::pw_multi_aff::add(upma2); + return typed::union_pw_multi_aff>(res); +} + +template +typed::pw_multi_aff> typed::pw_multi_aff>::add(const typed::multi_aff> &pma2) const +{ + auto res = isl::pw_multi_aff::add(pma2); + return typed::pw_multi_aff>(res); +} + +template +typed::pw_multi_aff> typed::pw_multi_aff>::add(const typed::pw_aff> &pma2) const +{ + auto res = isl::pw_multi_aff::add(pma2); + return typed::pw_multi_aff>(res); +} + +template +typed::pw_multi_aff> typed::pw_multi_aff>::add_constant(const typed::multi_val> &mv) const +{ + auto res = isl::pw_multi_aff::add_constant(mv); + return typed::pw_multi_aff>(res); +} + +template +typed::pw_multi_aff> typed::pw_multi_aff>::add_constant(const typed::val> &v) const +{ + auto res = isl::pw_multi_aff::add_constant(v); + return typed::pw_multi_aff>(res); +} + +template +typed::pw_multi_aff> typed::pw_multi_aff>::add_constant(long v) const +{ + auto res = isl::pw_multi_aff::add_constant(v); + return typed::pw_multi_aff>(res); +} + +template +template +typed::union_pw_multi_aff typed::pw_multi_aff>::apply(const typed::union_pw_multi_aff, Arg3> &upma2) const +{ + auto res = isl::pw_multi_aff::apply(upma2); + return typed::union_pw_multi_aff(res); +} + +template +typed::map> typed::pw_multi_aff>::as_map() const +{ + auto res = isl::pw_multi_aff::as_map(); + return typed::map>(res); +} + +template +typed::multi_aff> typed::pw_multi_aff>::as_multi_aff() const +{ + auto res = isl::pw_multi_aff::as_multi_aff(); + return typed::multi_aff>(res); +} + +template +typed::multi_union_pw_aff> typed::pw_multi_aff>::as_multi_union_pw_aff() const +{ + auto res = isl::pw_multi_aff::as_multi_union_pw_aff(); + return typed::multi_union_pw_aff>(res); +} + +template +typed::pw_multi_aff> typed::pw_multi_aff>::as_pw_multi_aff() const +{ + auto res = isl::pw_multi_aff::as_pw_multi_aff(); + return typed::pw_multi_aff>(res); +} + +template +typed::union_map> typed::pw_multi_aff>::as_union_map() const +{ + auto res = isl::pw_multi_aff::as_union_map(); + return typed::union_map>(res); +} + +template +typed::pw_aff typed::pw_multi_aff>::at(int pos) const +{ + auto res = isl::pw_multi_aff::at(pos); + return typed::pw_aff(res); +} + +template +typed::set typed::pw_multi_aff>::bind(const typed::multi_id> &tuple) const +{ + auto res = isl::pw_multi_aff::bind(tuple); + return typed::set(res); +} + +template +typed::pw_multi_aff> typed::pw_multi_aff>::bind_domain(const typed::multi_id &tuple) const +{ + auto res = isl::pw_multi_aff::bind_domain(tuple); + return typed::pw_multi_aff>(res); +} + +template +typed::pw_multi_aff> typed::pw_multi_aff>::coalesce() const +{ + auto res = isl::pw_multi_aff::coalesce(); + return typed::pw_multi_aff>(res); +} + +template +typed::set typed::pw_multi_aff>::domain() const +{ + auto res = isl::pw_multi_aff::domain(); + return typed::set(res); +} + +template +typed::pw_multi_aff> typed::pw_multi_aff>::drop_unused_params() const +{ + auto res = isl::pw_multi_aff::drop_unused_params(); + return typed::pw_multi_aff>(res); +} + +template +typed::pw_multi_aff> typed::pw_multi_aff>::extract_pw_multi_aff(const typed::space> &space) const +{ + auto res = isl::pw_multi_aff::extract_pw_multi_aff(space); + return typed::pw_multi_aff>(res); +} + +template +typed::pw_multi_aff> typed::pw_multi_aff>::gist(const typed::set &set) const +{ + auto res = isl::pw_multi_aff::gist(set); + return typed::pw_multi_aff>(res); +} + +template +typed::union_pw_multi_aff> typed::pw_multi_aff>::gist(const typed::union_set &context) const +{ + auto res = isl::pw_multi_aff::gist(context); + return typed::union_pw_multi_aff>(res); +} + +template +typed::pw_multi_aff> typed::pw_multi_aff>::gist(const typed::basic_set &set) const +{ + auto res = isl::pw_multi_aff::gist(set); + return typed::pw_multi_aff>(res); +} + +template +typed::pw_multi_aff> typed::pw_multi_aff>::gist(const typed::point &set) const +{ + auto res = isl::pw_multi_aff::gist(set); + return typed::pw_multi_aff>(res); +} + +template +typed::pw_multi_aff> typed::pw_multi_aff>::gist_params(const typed::set<> &set) const +{ + auto res = isl::pw_multi_aff::gist_params(set); + return typed::pw_multi_aff>(res); +} + +template +typed::pw_multi_aff> typed::pw_multi_aff>::gist_params(const typed::basic_set<> &set) const +{ + auto res = isl::pw_multi_aff::gist_params(set); + return typed::pw_multi_aff>(res); +} + +template +typed::pw_multi_aff> typed::pw_multi_aff>::gist_params(const typed::point<> &set) const +{ + auto res = isl::pw_multi_aff::gist_params(set); + return typed::pw_multi_aff>(res); +} + +template +typed::multi_pw_aff> typed::pw_multi_aff>::identity() const +{ + auto res = isl::pw_multi_aff::identity(); + return typed::multi_pw_aff>(res); +} + +template +typed::pw_multi_aff> typed::pw_multi_aff>::intersect_domain(const typed::set &set) const +{ + auto res = isl::pw_multi_aff::intersect_domain(set); + return typed::pw_multi_aff>(res); +} + +template +typed::union_pw_multi_aff> typed::pw_multi_aff>::intersect_domain(const typed::space &space) const +{ + auto res = isl::pw_multi_aff::intersect_domain(space); + return typed::union_pw_multi_aff>(res); +} + +template +typed::union_pw_multi_aff> typed::pw_multi_aff>::intersect_domain(const typed::union_set &uset) const +{ + auto res = isl::pw_multi_aff::intersect_domain(uset); + return typed::union_pw_multi_aff>(res); +} + +template +typed::pw_multi_aff> typed::pw_multi_aff>::intersect_domain(const typed::basic_set &set) const +{ + auto res = isl::pw_multi_aff::intersect_domain(set); + return typed::pw_multi_aff>(res); +} + +template +typed::pw_multi_aff> typed::pw_multi_aff>::intersect_domain(const typed::point &set) const +{ + auto res = isl::pw_multi_aff::intersect_domain(set); + return typed::pw_multi_aff>(res); +} + +template +typed::pw_multi_aff> typed::pw_multi_aff>::intersect_params(const typed::set<> &set) const +{ + auto res = isl::pw_multi_aff::intersect_params(set); + return typed::pw_multi_aff>(res); +} + +template +typed::pw_multi_aff> typed::pw_multi_aff>::intersect_params(const typed::basic_set<> &set) const +{ + auto res = isl::pw_multi_aff::intersect_params(set); + return typed::pw_multi_aff>(res); +} + +template +typed::pw_multi_aff> typed::pw_multi_aff>::intersect_params(const typed::point<> &set) const +{ + auto res = isl::pw_multi_aff::intersect_params(set); + return typed::pw_multi_aff>(res); +} + +template +typed::pw_aff_list typed::pw_multi_aff>::list() const +{ + auto res = isl::pw_multi_aff::list(); + return typed::pw_aff_list(res); +} + +template +typed::multi_pw_aff> typed::pw_multi_aff>::max(const typed::multi_pw_aff> &multi2) const +{ + auto res = isl::pw_multi_aff::max(multi2); + return typed::multi_pw_aff>(res); +} + +template +typed::multi_val> typed::pw_multi_aff>::max_multi_val() const +{ + auto res = isl::pw_multi_aff::max_multi_val(); + return typed::multi_val>(res); +} + +template +typed::multi_pw_aff> typed::pw_multi_aff>::min(const typed::multi_pw_aff> &multi2) const +{ + auto res = isl::pw_multi_aff::min(multi2); + return typed::multi_pw_aff>(res); +} + +template +typed::multi_val> typed::pw_multi_aff>::min_multi_val() const +{ + auto res = isl::pw_multi_aff::min_multi_val(); + return typed::multi_val>(res); +} + +template +typed::multi_pw_aff> typed::pw_multi_aff>::neg() const +{ + auto res = isl::pw_multi_aff::neg(); + return typed::multi_pw_aff>(res); +} + +template +template +typed::multi_pw_aff, pair, Arg3>> typed::pw_multi_aff>::product(const typed::multi_pw_aff &multi2) const +{ + auto res = isl::pw_multi_aff::product(multi2); + return typed::multi_pw_aff, pair, Arg3>>(res); +} + +template +template +typed::pw_multi_aff, pair, Arg3>> typed::pw_multi_aff>::product(const typed::pw_multi_aff &pma2) const +{ + auto res = isl::pw_multi_aff::product(pma2); + return typed::pw_multi_aff, pair, Arg3>>(res); +} + +template +template +typed::pw_multi_aff, pair, Arg3>> typed::pw_multi_aff>::product(const typed::multi_aff &pma2) const +{ + auto res = isl::pw_multi_aff::product(pma2); + return typed::pw_multi_aff, pair, Arg3>>(res); +} + +template +template +typed::pw_multi_aff, pair, Anonymous>> typed::pw_multi_aff>::product(const typed::pw_aff &pma2) const +{ + auto res = isl::pw_multi_aff::product(pma2); + return typed::pw_multi_aff, pair, Anonymous>>(res); +} + +template +template +typed::multi_pw_aff> typed::pw_multi_aff>::pullback(const typed::multi_pw_aff &mpa2) const +{ + auto res = isl::pw_multi_aff::pullback(mpa2); + return typed::multi_pw_aff>(res); +} + +template +typed::multi_pw_aff> typed::pw_multi_aff>::pullback(const typed::multi_pw_aff &mpa2) const +{ + auto res = isl::pw_multi_aff::pullback(mpa2); + return typed::multi_pw_aff>(res); +} + +template +template +typed::pw_multi_aff> typed::pw_multi_aff>::pullback(const typed::multi_aff &ma) const +{ + auto res = isl::pw_multi_aff::pullback(ma); + return typed::pw_multi_aff>(res); +} + +template +typed::pw_multi_aff> typed::pw_multi_aff>::pullback(const typed::multi_aff &ma) const +{ + auto res = isl::pw_multi_aff::pullback(ma); + return typed::pw_multi_aff>(res); +} + +template +template +typed::pw_multi_aff> typed::pw_multi_aff>::pullback(const typed::pw_multi_aff &pma2) const +{ + auto res = isl::pw_multi_aff::pullback(pma2); + return typed::pw_multi_aff>(res); +} + +template +typed::pw_multi_aff> typed::pw_multi_aff>::pullback(const typed::pw_multi_aff &pma2) const +{ + auto res = isl::pw_multi_aff::pullback(pma2); + return typed::pw_multi_aff>(res); +} + +template +template +typed::union_pw_multi_aff> typed::pw_multi_aff>::pullback(const typed::union_pw_multi_aff &upma2) const +{ + auto res = isl::pw_multi_aff::pullback(upma2); + return typed::union_pw_multi_aff>(res); +} + +template +typed::union_pw_multi_aff> typed::pw_multi_aff>::pullback(const typed::union_pw_multi_aff &upma2) const +{ + auto res = isl::pw_multi_aff::pullback(upma2); + return typed::union_pw_multi_aff>(res); +} + +template +typed::pw_multi_aff_list> typed::pw_multi_aff>::pw_multi_aff_list() const +{ + auto res = isl::pw_multi_aff::pw_multi_aff_list(); + return typed::pw_multi_aff_list>(res); +} + +template +typed::pw_multi_aff typed::pw_multi_aff>::range_factor_domain() const +{ + auto res = isl::pw_multi_aff::range_factor_domain(); + return typed::pw_multi_aff(res); +} + +template +typed::pw_multi_aff typed::pw_multi_aff>::range_factor_range() const +{ + auto res = isl::pw_multi_aff::range_factor_range(); + return typed::pw_multi_aff(res); +} + +template +template +typed::multi_pw_aff, Arg3>> typed::pw_multi_aff>::range_product(const typed::multi_pw_aff &multi2) const +{ + auto res = isl::pw_multi_aff::range_product(multi2); + return typed::multi_pw_aff, Arg3>>(res); +} + +template +template +typed::multi_union_pw_aff, Arg3>> typed::pw_multi_aff>::range_product(const typed::multi_union_pw_aff &multi2) const +{ + auto res = isl::pw_multi_aff::range_product(multi2); + return typed::multi_union_pw_aff, Arg3>>(res); +} + +template +template +typed::pw_multi_aff, Arg3>> typed::pw_multi_aff>::range_product(const typed::pw_multi_aff &pma2) const +{ + auto res = isl::pw_multi_aff::range_product(pma2); + return typed::pw_multi_aff, Arg3>>(res); +} + +template +template +typed::union_pw_multi_aff, Arg3>> typed::pw_multi_aff>::range_product(const typed::union_pw_multi_aff &upma2) const +{ + auto res = isl::pw_multi_aff::range_product(upma2); + return typed::union_pw_multi_aff, Arg3>>(res); +} + +template +template +typed::pw_multi_aff, Arg3>> typed::pw_multi_aff>::range_product(const typed::multi_aff &pma2) const +{ + auto res = isl::pw_multi_aff::range_product(pma2); + return typed::pw_multi_aff, Arg3>>(res); +} + +template +typed::pw_multi_aff, Anonymous>> typed::pw_multi_aff>::range_product(const typed::pw_aff &pma2) const +{ + auto res = isl::pw_multi_aff::range_product(pma2); + return typed::pw_multi_aff, Anonymous>>(res); +} + +template +typed::pw_multi_aff> typed::pw_multi_aff>::scale(const typed::multi_val> &mv) const +{ + auto res = isl::pw_multi_aff::scale(mv); + return typed::pw_multi_aff>(res); +} + +template +typed::pw_multi_aff> typed::pw_multi_aff>::scale(const typed::val> &v) const +{ + auto res = isl::pw_multi_aff::scale(v); + return typed::pw_multi_aff>(res); +} + +template +typed::pw_multi_aff> typed::pw_multi_aff>::scale(long v) const +{ + auto res = isl::pw_multi_aff::scale(v); + return typed::pw_multi_aff>(res); +} + +template +typed::pw_multi_aff> typed::pw_multi_aff>::scale_down(const typed::multi_val> &mv) const +{ + auto res = isl::pw_multi_aff::scale_down(mv); + return typed::pw_multi_aff>(res); +} + +template +typed::pw_multi_aff> typed::pw_multi_aff>::scale_down(const typed::val> &v) const +{ + auto res = isl::pw_multi_aff::scale_down(v); + return typed::pw_multi_aff>(res); +} + +template +typed::pw_multi_aff> typed::pw_multi_aff>::scale_down(long v) const +{ + auto res = isl::pw_multi_aff::scale_down(v); + return typed::pw_multi_aff>(res); +} + +template +typed::multi_pw_aff> typed::pw_multi_aff>::set_at(int pos, const typed::pw_aff &el) const +{ + auto res = isl::pw_multi_aff::set_at(pos, el); + return typed::multi_pw_aff>(res); +} + +template +typed::multi_union_pw_aff> typed::pw_multi_aff>::set_at(int pos, const typed::union_pw_aff &el) const +{ + auto res = isl::pw_multi_aff::set_at(pos, el); + return typed::multi_union_pw_aff>(res); +} + +template +typed::space> typed::pw_multi_aff>::space() const +{ + auto res = isl::pw_multi_aff::space(); + return typed::space>(res); +} + +template +typed::multi_pw_aff> typed::pw_multi_aff>::sub(const typed::multi_pw_aff> &multi2) const +{ + auto res = isl::pw_multi_aff::sub(multi2); + return typed::multi_pw_aff>(res); +} + +template +typed::multi_union_pw_aff> typed::pw_multi_aff>::sub(const typed::multi_union_pw_aff> &multi2) const +{ + auto res = isl::pw_multi_aff::sub(multi2); + return typed::multi_union_pw_aff>(res); +} + +template +typed::pw_multi_aff> typed::pw_multi_aff>::sub(const typed::pw_multi_aff> &pma2) const +{ + auto res = isl::pw_multi_aff::sub(pma2); + return typed::pw_multi_aff>(res); +} + +template +typed::union_pw_multi_aff> typed::pw_multi_aff>::sub(const typed::union_pw_multi_aff> &upma2) const +{ + auto res = isl::pw_multi_aff::sub(upma2); + return typed::union_pw_multi_aff>(res); +} + +template +typed::pw_multi_aff> typed::pw_multi_aff>::sub(const typed::multi_aff> &pma2) const +{ + auto res = isl::pw_multi_aff::sub(pma2); + return typed::pw_multi_aff>(res); +} + +template +typed::pw_multi_aff> typed::pw_multi_aff>::sub(const typed::pw_aff> &pma2) const +{ + auto res = isl::pw_multi_aff::sub(pma2); + return typed::pw_multi_aff>(res); +} + +template +typed::pw_multi_aff> typed::pw_multi_aff>::subtract_domain(const typed::set &set) const +{ + auto res = isl::pw_multi_aff::subtract_domain(set); + return typed::pw_multi_aff>(res); +} + +template +typed::union_pw_multi_aff> typed::pw_multi_aff>::subtract_domain(const typed::space &space) const +{ + auto res = isl::pw_multi_aff::subtract_domain(space); + return typed::union_pw_multi_aff>(res); +} + +template +typed::union_pw_multi_aff> typed::pw_multi_aff>::subtract_domain(const typed::union_set &uset) const +{ + auto res = isl::pw_multi_aff::subtract_domain(uset); + return typed::union_pw_multi_aff>(res); +} + +template +typed::pw_multi_aff> typed::pw_multi_aff>::subtract_domain(const typed::basic_set &set) const +{ + auto res = isl::pw_multi_aff::subtract_domain(set); + return typed::pw_multi_aff>(res); +} + +template +typed::pw_multi_aff> typed::pw_multi_aff>::subtract_domain(const typed::point &set) const +{ + auto res = isl::pw_multi_aff::subtract_domain(set); + return typed::pw_multi_aff>(res); +} + +template +typed::multi_pw_aff> typed::pw_multi_aff>::to_multi_pw_aff() const +{ + auto res = isl::pw_multi_aff::to_multi_pw_aff(); + return typed::multi_pw_aff>(res); +} + +template +typed::union_pw_multi_aff> typed::pw_multi_aff>::to_union_pw_multi_aff() const +{ + auto res = isl::pw_multi_aff::to_union_pw_multi_aff(); + return typed::union_pw_multi_aff>(res); +} + +template +typed::multi_pw_aff> typed::pw_multi_aff>::union_add(const typed::multi_pw_aff> &mpa2) const +{ + auto res = isl::pw_multi_aff::union_add(mpa2); + return typed::multi_pw_aff>(res); +} + +template +typed::multi_union_pw_aff> typed::pw_multi_aff>::union_add(const typed::multi_union_pw_aff> &mupa2) const +{ + auto res = isl::pw_multi_aff::union_add(mupa2); + return typed::multi_union_pw_aff>(res); +} + +template +typed::pw_multi_aff> typed::pw_multi_aff>::union_add(const typed::pw_multi_aff> &pma2) const +{ + auto res = isl::pw_multi_aff::union_add(pma2); + return typed::pw_multi_aff>(res); +} + +template +typed::union_pw_multi_aff> typed::pw_multi_aff>::union_add(const typed::union_pw_multi_aff> &upma2) const +{ + auto res = isl::pw_multi_aff::union_add(upma2); + return typed::union_pw_multi_aff>(res); +} + +template +typed::pw_multi_aff> typed::pw_multi_aff>::union_add(const typed::multi_aff> &pma2) const +{ + auto res = isl::pw_multi_aff::union_add(pma2); + return typed::pw_multi_aff>(res); +} + +template +typed::pw_multi_aff> typed::pw_multi_aff>::union_add(const typed::pw_aff> &pma2) const +{ + auto res = isl::pw_multi_aff::union_add(pma2); + return typed::pw_multi_aff>(res); +} + +template +typed::pw_multi_aff, pair>::pw_multi_aff(const typed::multi_aff, pair> &ma) + : isl::pw_multi_aff(ma) +{ +} + +template +typed::pw_multi_aff, pair>::pw_multi_aff(const typed::pw_aff, pair> &pa) + : isl::pw_multi_aff(pa) +{ +} + +template +typed::pw_multi_aff, pair>::pw_multi_aff(const isl::ctx &ctx, const std::string &str) + : isl::pw_multi_aff(ctx, str) +{ +} + +template +typed::multi_pw_aff, pair> typed::pw_multi_aff, pair>::add(const typed::multi_pw_aff, pair> &multi2) const +{ + auto res = isl::pw_multi_aff::add(multi2); + return typed::multi_pw_aff, pair>(res); +} + +template +typed::multi_union_pw_aff, pair> typed::pw_multi_aff, pair>::add(const typed::multi_union_pw_aff, pair> &multi2) const +{ + auto res = isl::pw_multi_aff::add(multi2); + return typed::multi_union_pw_aff, pair>(res); +} + +template +typed::pw_multi_aff, pair> typed::pw_multi_aff, pair>::add(const typed::pw_multi_aff, pair> &pma2) const +{ + auto res = isl::pw_multi_aff::add(pma2); + return typed::pw_multi_aff, pair>(res); +} + +template +typed::union_pw_multi_aff, pair> typed::pw_multi_aff, pair>::add(const typed::union_pw_multi_aff, pair> &upma2) const +{ + auto res = isl::pw_multi_aff::add(upma2); + return typed::union_pw_multi_aff, pair>(res); +} + +template +typed::pw_multi_aff, pair> typed::pw_multi_aff, pair>::add(const typed::multi_aff, pair> &pma2) const +{ + auto res = isl::pw_multi_aff::add(pma2); + return typed::pw_multi_aff, pair>(res); +} + +template +typed::pw_multi_aff, pair> typed::pw_multi_aff, pair>::add(const typed::pw_aff, pair> &pma2) const +{ + auto res = isl::pw_multi_aff::add(pma2); + return typed::pw_multi_aff, pair>(res); +} + +template +typed::pw_multi_aff, pair> typed::pw_multi_aff, pair>::add_constant(const typed::multi_val> &mv) const +{ + auto res = isl::pw_multi_aff::add_constant(mv); + return typed::pw_multi_aff, pair>(res); +} + +template +typed::pw_multi_aff, pair> typed::pw_multi_aff, pair>::add_constant(const typed::val> &v) const +{ + auto res = isl::pw_multi_aff::add_constant(v); + return typed::pw_multi_aff, pair>(res); +} + +template +typed::pw_multi_aff, pair> typed::pw_multi_aff, pair>::add_constant(long v) const +{ + auto res = isl::pw_multi_aff::add_constant(v); + return typed::pw_multi_aff, pair>(res); +} + +template +template +typed::union_pw_multi_aff, Arg2> typed::pw_multi_aff, pair>::apply(const typed::union_pw_multi_aff, Arg2> &upma2) const +{ + auto res = isl::pw_multi_aff::apply(upma2); + return typed::union_pw_multi_aff, Arg2>(res); +} + +template +typed::map, pair> typed::pw_multi_aff, pair>::as_map() const +{ + auto res = isl::pw_multi_aff::as_map(); + return typed::map, pair>(res); +} + +template +typed::multi_aff, pair> typed::pw_multi_aff, pair>::as_multi_aff() const +{ + auto res = isl::pw_multi_aff::as_multi_aff(); + return typed::multi_aff, pair>(res); +} + +template +typed::multi_union_pw_aff, pair> typed::pw_multi_aff, pair>::as_multi_union_pw_aff() const +{ + auto res = isl::pw_multi_aff::as_multi_union_pw_aff(); + return typed::multi_union_pw_aff, pair>(res); +} + +template +typed::pw_multi_aff, pair> typed::pw_multi_aff, pair>::as_pw_multi_aff() const +{ + auto res = isl::pw_multi_aff::as_pw_multi_aff(); + return typed::pw_multi_aff, pair>(res); +} + +template +typed::union_map, pair> typed::pw_multi_aff, pair>::as_union_map() const +{ + auto res = isl::pw_multi_aff::as_union_map(); + return typed::union_map, pair>(res); +} + +template +typed::pw_aff, Anonymous> typed::pw_multi_aff, pair>::at(int pos) const +{ + auto res = isl::pw_multi_aff::at(pos); + return typed::pw_aff, Anonymous>(res); +} + +template +typed::set> typed::pw_multi_aff, pair>::bind(const typed::multi_id> &tuple) const +{ + auto res = isl::pw_multi_aff::bind(tuple); + return typed::set>(res); +} + +template +typed::pw_multi_aff> typed::pw_multi_aff, pair>::bind_domain(const typed::multi_id> &tuple) const +{ + auto res = isl::pw_multi_aff::bind_domain(tuple); + return typed::pw_multi_aff>(res); +} + +template +typed::pw_multi_aff> typed::pw_multi_aff, pair>::bind_domain_wrapped_domain(const typed::multi_id &tuple) const +{ + auto res = isl::pw_multi_aff::bind_domain_wrapped_domain(tuple); + return typed::pw_multi_aff>(res); +} + +template +typed::pw_multi_aff, pair> typed::pw_multi_aff, pair>::coalesce() const +{ + auto res = isl::pw_multi_aff::coalesce(); + return typed::pw_multi_aff, pair>(res); +} + +template +typed::set> typed::pw_multi_aff, pair>::domain() const +{ + auto res = isl::pw_multi_aff::domain(); + return typed::set>(res); +} + +template +typed::pw_multi_aff, pair> typed::pw_multi_aff, pair>::domain_reverse() const +{ + auto res = isl::pw_multi_aff::domain_reverse(); + return typed::pw_multi_aff, pair>(res); +} + +template +typed::pw_multi_aff, pair> typed::pw_multi_aff, pair>::drop_unused_params() const +{ + auto res = isl::pw_multi_aff::drop_unused_params(); + return typed::pw_multi_aff, pair>(res); +} + +template +typed::pw_multi_aff, pair> typed::pw_multi_aff, pair>::extract_pw_multi_aff(const typed::space, pair> &space) const +{ + auto res = isl::pw_multi_aff::extract_pw_multi_aff(space); + return typed::pw_multi_aff, pair>(res); +} + +template +typed::pw_multi_aff, pair> typed::pw_multi_aff, pair>::gist(const typed::set> &set) const +{ + auto res = isl::pw_multi_aff::gist(set); + return typed::pw_multi_aff, pair>(res); +} + +template +typed::union_pw_multi_aff, pair> typed::pw_multi_aff, pair>::gist(const typed::union_set> &context) const +{ + auto res = isl::pw_multi_aff::gist(context); + return typed::union_pw_multi_aff, pair>(res); +} + +template +typed::pw_multi_aff, pair> typed::pw_multi_aff, pair>::gist(const typed::basic_set> &set) const +{ + auto res = isl::pw_multi_aff::gist(set); + return typed::pw_multi_aff, pair>(res); +} + +template +typed::pw_multi_aff, pair> typed::pw_multi_aff, pair>::gist(const typed::point> &set) const +{ + auto res = isl::pw_multi_aff::gist(set); + return typed::pw_multi_aff, pair>(res); +} + +template +typed::pw_multi_aff, pair> typed::pw_multi_aff, pair>::gist_params(const typed::set<> &set) const +{ + auto res = isl::pw_multi_aff::gist_params(set); + return typed::pw_multi_aff, pair>(res); +} + +template +typed::pw_multi_aff, pair> typed::pw_multi_aff, pair>::gist_params(const typed::basic_set<> &set) const +{ + auto res = isl::pw_multi_aff::gist_params(set); + return typed::pw_multi_aff, pair>(res); +} + +template +typed::pw_multi_aff, pair> typed::pw_multi_aff, pair>::gist_params(const typed::point<> &set) const +{ + auto res = isl::pw_multi_aff::gist_params(set); + return typed::pw_multi_aff, pair>(res); +} + +template +typed::multi_pw_aff, pair> typed::pw_multi_aff, pair>::identity() const +{ + auto res = isl::pw_multi_aff::identity(); + return typed::multi_pw_aff, pair>(res); +} + +template +typed::pw_multi_aff, pair> typed::pw_multi_aff, pair>::intersect_domain(const typed::set> &set) const +{ + auto res = isl::pw_multi_aff::intersect_domain(set); + return typed::pw_multi_aff, pair>(res); +} + +template +typed::union_pw_multi_aff, pair> typed::pw_multi_aff, pair>::intersect_domain(const typed::space> &space) const +{ + auto res = isl::pw_multi_aff::intersect_domain(space); + return typed::union_pw_multi_aff, pair>(res); +} + +template +typed::union_pw_multi_aff, pair> typed::pw_multi_aff, pair>::intersect_domain(const typed::union_set> &uset) const +{ + auto res = isl::pw_multi_aff::intersect_domain(uset); + return typed::union_pw_multi_aff, pair>(res); +} + +template +typed::pw_multi_aff, pair> typed::pw_multi_aff, pair>::intersect_domain(const typed::basic_set> &set) const +{ + auto res = isl::pw_multi_aff::intersect_domain(set); + return typed::pw_multi_aff, pair>(res); +} + +template +typed::pw_multi_aff, pair> typed::pw_multi_aff, pair>::intersect_domain(const typed::point> &set) const +{ + auto res = isl::pw_multi_aff::intersect_domain(set); + return typed::pw_multi_aff, pair>(res); +} + +template +typed::union_pw_multi_aff, pair> typed::pw_multi_aff, pair>::intersect_domain_wrapped_domain(const typed::union_set &uset) const +{ + auto res = isl::pw_multi_aff::intersect_domain_wrapped_domain(uset); + return typed::union_pw_multi_aff, pair>(res); +} + +template +typed::pw_multi_aff, pair> typed::pw_multi_aff, pair>::intersect_params(const typed::set<> &set) const +{ + auto res = isl::pw_multi_aff::intersect_params(set); + return typed::pw_multi_aff, pair>(res); +} + +template +typed::pw_multi_aff, pair> typed::pw_multi_aff, pair>::intersect_params(const typed::basic_set<> &set) const +{ + auto res = isl::pw_multi_aff::intersect_params(set); + return typed::pw_multi_aff, pair>(res); +} + +template +typed::pw_multi_aff, pair> typed::pw_multi_aff, pair>::intersect_params(const typed::point<> &set) const +{ + auto res = isl::pw_multi_aff::intersect_params(set); + return typed::pw_multi_aff, pair>(res); +} + +template +typed::pw_aff_list, Anonymous> typed::pw_multi_aff, pair>::list() const +{ + auto res = isl::pw_multi_aff::list(); + return typed::pw_aff_list, Anonymous>(res); +} + +template +typed::multi_pw_aff, pair> typed::pw_multi_aff, pair>::max(const typed::multi_pw_aff, pair> &multi2) const +{ + auto res = isl::pw_multi_aff::max(multi2); + return typed::multi_pw_aff, pair>(res); +} + +template +typed::multi_val> typed::pw_multi_aff, pair>::max_multi_val() const +{ + auto res = isl::pw_multi_aff::max_multi_val(); + return typed::multi_val>(res); +} + +template +typed::multi_pw_aff, pair> typed::pw_multi_aff, pair>::min(const typed::multi_pw_aff, pair> &multi2) const +{ + auto res = isl::pw_multi_aff::min(multi2); + return typed::multi_pw_aff, pair>(res); +} + +template +typed::multi_val> typed::pw_multi_aff, pair>::min_multi_val() const +{ + auto res = isl::pw_multi_aff::min_multi_val(); + return typed::multi_val>(res); +} + +template +typed::multi_pw_aff, pair> typed::pw_multi_aff, pair>::neg() const +{ + auto res = isl::pw_multi_aff::neg(); + return typed::multi_pw_aff, pair>(res); +} + +template +template +typed::pw_multi_aff, pair> typed::pw_multi_aff, pair>::preimage_domain_wrapped_domain(const typed::pw_multi_aff &pma2) const +{ + auto res = isl::pw_multi_aff::preimage_domain_wrapped_domain(pma2); + return typed::pw_multi_aff, pair>(res); +} + +template +template +typed::union_pw_multi_aff, pair> typed::pw_multi_aff, pair>::preimage_domain_wrapped_domain(const typed::union_pw_multi_aff &upma2) const +{ + auto res = isl::pw_multi_aff::preimage_domain_wrapped_domain(upma2); + return typed::union_pw_multi_aff, pair>(res); +} + +template +template +typed::pw_multi_aff, pair> typed::pw_multi_aff, pair>::preimage_domain_wrapped_domain(const typed::multi_aff &pma2) const +{ + auto res = isl::pw_multi_aff::preimage_domain_wrapped_domain(pma2); + return typed::pw_multi_aff, pair>(res); +} + +template +template +typed::pw_multi_aff, pair> typed::pw_multi_aff, pair>::preimage_domain_wrapped_domain(const typed::pw_aff &pma2) const +{ + auto res = isl::pw_multi_aff::preimage_domain_wrapped_domain(pma2); + return typed::pw_multi_aff, pair>(res); +} + +template +template +typed::multi_pw_aff, Domain2>, pair, Arg2>> typed::pw_multi_aff, pair>::product(const typed::multi_pw_aff &multi2) const +{ + auto res = isl::pw_multi_aff::product(multi2); + return typed::multi_pw_aff, Domain2>, pair, Arg2>>(res); +} + +template +template +typed::pw_multi_aff, Domain2>, pair, Arg2>> typed::pw_multi_aff, pair>::product(const typed::pw_multi_aff &pma2) const +{ + auto res = isl::pw_multi_aff::product(pma2); + return typed::pw_multi_aff, Domain2>, pair, Arg2>>(res); +} + +template +template +typed::pw_multi_aff, Domain2>, pair, Arg2>> typed::pw_multi_aff, pair>::product(const typed::multi_aff &pma2) const +{ + auto res = isl::pw_multi_aff::product(pma2); + return typed::pw_multi_aff, Domain2>, pair, Arg2>>(res); +} + +template +template +typed::pw_multi_aff, Domain2>, pair, Anonymous>> typed::pw_multi_aff, pair>::product(const typed::pw_aff &pma2) const +{ + auto res = isl::pw_multi_aff::product(pma2); + return typed::pw_multi_aff, Domain2>, pair, Anonymous>>(res); +} + +template +template +typed::multi_pw_aff> typed::pw_multi_aff, pair>::pullback(const typed::multi_pw_aff> &mpa2) const +{ + auto res = isl::pw_multi_aff::pullback(mpa2); + return typed::multi_pw_aff>(res); +} + +template +typed::multi_pw_aff> typed::pw_multi_aff, pair>::pullback(const typed::multi_pw_aff> &mpa2) const +{ + auto res = isl::pw_multi_aff::pullback(mpa2); + return typed::multi_pw_aff>(res); +} + +template +template +typed::pw_multi_aff> typed::pw_multi_aff, pair>::pullback(const typed::multi_aff> &ma) const +{ + auto res = isl::pw_multi_aff::pullback(ma); + return typed::pw_multi_aff>(res); +} + +template +typed::pw_multi_aff> typed::pw_multi_aff, pair>::pullback(const typed::multi_aff> &ma) const +{ + auto res = isl::pw_multi_aff::pullback(ma); + return typed::pw_multi_aff>(res); +} + +template +template +typed::pw_multi_aff> typed::pw_multi_aff, pair>::pullback(const typed::pw_multi_aff> &pma2) const +{ + auto res = isl::pw_multi_aff::pullback(pma2); + return typed::pw_multi_aff>(res); +} + +template +typed::pw_multi_aff> typed::pw_multi_aff, pair>::pullback(const typed::pw_multi_aff> &pma2) const +{ + auto res = isl::pw_multi_aff::pullback(pma2); + return typed::pw_multi_aff>(res); +} + +template +template +typed::union_pw_multi_aff> typed::pw_multi_aff, pair>::pullback(const typed::union_pw_multi_aff> &upma2) const +{ + auto res = isl::pw_multi_aff::pullback(upma2); + return typed::union_pw_multi_aff>(res); +} + +template +typed::union_pw_multi_aff> typed::pw_multi_aff, pair>::pullback(const typed::union_pw_multi_aff> &upma2) const +{ + auto res = isl::pw_multi_aff::pullback(upma2); + return typed::union_pw_multi_aff>(res); +} + +template +typed::pw_multi_aff_list, pair> typed::pw_multi_aff, pair>::pw_multi_aff_list() const +{ + auto res = isl::pw_multi_aff::pw_multi_aff_list(); + return typed::pw_multi_aff_list, pair>(res); +} + +template +typed::pw_multi_aff, Range> typed::pw_multi_aff, pair>::range_factor_domain() const +{ + auto res = isl::pw_multi_aff::range_factor_domain(); + return typed::pw_multi_aff, Range>(res); +} + +template +typed::pw_multi_aff, Range2> typed::pw_multi_aff, pair>::range_factor_range() const +{ + auto res = isl::pw_multi_aff::range_factor_range(); + return typed::pw_multi_aff, Range2>(res); +} + +template +template +typed::multi_pw_aff, pair, Arg2>> typed::pw_multi_aff, pair>::range_product(const typed::multi_pw_aff, Arg2> &multi2) const +{ + auto res = isl::pw_multi_aff::range_product(multi2); + return typed::multi_pw_aff, pair, Arg2>>(res); +} + +template +template +typed::multi_union_pw_aff, pair, Arg2>> typed::pw_multi_aff, pair>::range_product(const typed::multi_union_pw_aff, Arg2> &multi2) const +{ + auto res = isl::pw_multi_aff::range_product(multi2); + return typed::multi_union_pw_aff, pair, Arg2>>(res); +} + +template +template +typed::pw_multi_aff, pair, Arg2>> typed::pw_multi_aff, pair>::range_product(const typed::pw_multi_aff, Arg2> &pma2) const +{ + auto res = isl::pw_multi_aff::range_product(pma2); + return typed::pw_multi_aff, pair, Arg2>>(res); +} + +template +template +typed::union_pw_multi_aff, pair, Arg2>> typed::pw_multi_aff, pair>::range_product(const typed::union_pw_multi_aff, Arg2> &upma2) const +{ + auto res = isl::pw_multi_aff::range_product(upma2); + return typed::union_pw_multi_aff, pair, Arg2>>(res); +} + +template +template +typed::pw_multi_aff, pair, Arg2>> typed::pw_multi_aff, pair>::range_product(const typed::multi_aff, Arg2> &pma2) const +{ + auto res = isl::pw_multi_aff::range_product(pma2); + return typed::pw_multi_aff, pair, Arg2>>(res); +} + +template +typed::pw_multi_aff, pair, Anonymous>> typed::pw_multi_aff, pair>::range_product(const typed::pw_aff, Anonymous> &pma2) const +{ + auto res = isl::pw_multi_aff::range_product(pma2); + return typed::pw_multi_aff, pair, Anonymous>>(res); +} + +template +typed::pw_multi_aff, pair> typed::pw_multi_aff, pair>::scale(const typed::multi_val> &mv) const +{ + auto res = isl::pw_multi_aff::scale(mv); + return typed::pw_multi_aff, pair>(res); +} + +template +typed::pw_multi_aff, pair> typed::pw_multi_aff, pair>::scale(const typed::val> &v) const +{ + auto res = isl::pw_multi_aff::scale(v); + return typed::pw_multi_aff, pair>(res); +} + +template +typed::pw_multi_aff, pair> typed::pw_multi_aff, pair>::scale(long v) const +{ + auto res = isl::pw_multi_aff::scale(v); + return typed::pw_multi_aff, pair>(res); +} + +template +typed::pw_multi_aff, pair> typed::pw_multi_aff, pair>::scale_down(const typed::multi_val> &mv) const +{ + auto res = isl::pw_multi_aff::scale_down(mv); + return typed::pw_multi_aff, pair>(res); +} + +template +typed::pw_multi_aff, pair> typed::pw_multi_aff, pair>::scale_down(const typed::val> &v) const +{ + auto res = isl::pw_multi_aff::scale_down(v); + return typed::pw_multi_aff, pair>(res); +} + +template +typed::pw_multi_aff, pair> typed::pw_multi_aff, pair>::scale_down(long v) const +{ + auto res = isl::pw_multi_aff::scale_down(v); + return typed::pw_multi_aff, pair>(res); +} + +template +typed::multi_pw_aff, pair> typed::pw_multi_aff, pair>::set_at(int pos, const typed::pw_aff, Anonymous> &el) const +{ + auto res = isl::pw_multi_aff::set_at(pos, el); + return typed::multi_pw_aff, pair>(res); +} + +template +typed::multi_union_pw_aff, pair> typed::pw_multi_aff, pair>::set_at(int pos, const typed::union_pw_aff, Anonymous> &el) const +{ + auto res = isl::pw_multi_aff::set_at(pos, el); + return typed::multi_union_pw_aff, pair>(res); +} + +template +typed::space, pair> typed::pw_multi_aff, pair>::space() const +{ + auto res = isl::pw_multi_aff::space(); + return typed::space, pair>(res); +} + +template +typed::multi_pw_aff, pair> typed::pw_multi_aff, pair>::sub(const typed::multi_pw_aff, pair> &multi2) const +{ + auto res = isl::pw_multi_aff::sub(multi2); + return typed::multi_pw_aff, pair>(res); +} + +template +typed::multi_union_pw_aff, pair> typed::pw_multi_aff, pair>::sub(const typed::multi_union_pw_aff, pair> &multi2) const +{ + auto res = isl::pw_multi_aff::sub(multi2); + return typed::multi_union_pw_aff, pair>(res); +} + +template +typed::pw_multi_aff, pair> typed::pw_multi_aff, pair>::sub(const typed::pw_multi_aff, pair> &pma2) const +{ + auto res = isl::pw_multi_aff::sub(pma2); + return typed::pw_multi_aff, pair>(res); +} + +template +typed::union_pw_multi_aff, pair> typed::pw_multi_aff, pair>::sub(const typed::union_pw_multi_aff, pair> &upma2) const +{ + auto res = isl::pw_multi_aff::sub(upma2); + return typed::union_pw_multi_aff, pair>(res); +} + +template +typed::pw_multi_aff, pair> typed::pw_multi_aff, pair>::sub(const typed::multi_aff, pair> &pma2) const +{ + auto res = isl::pw_multi_aff::sub(pma2); + return typed::pw_multi_aff, pair>(res); +} + +template +typed::pw_multi_aff, pair> typed::pw_multi_aff, pair>::sub(const typed::pw_aff, pair> &pma2) const +{ + auto res = isl::pw_multi_aff::sub(pma2); + return typed::pw_multi_aff, pair>(res); +} + +template +typed::pw_multi_aff, pair> typed::pw_multi_aff, pair>::subtract_domain(const typed::set> &set) const +{ + auto res = isl::pw_multi_aff::subtract_domain(set); + return typed::pw_multi_aff, pair>(res); +} + +template +typed::union_pw_multi_aff, pair> typed::pw_multi_aff, pair>::subtract_domain(const typed::space> &space) const +{ + auto res = isl::pw_multi_aff::subtract_domain(space); + return typed::union_pw_multi_aff, pair>(res); +} + +template +typed::union_pw_multi_aff, pair> typed::pw_multi_aff, pair>::subtract_domain(const typed::union_set> &uset) const +{ + auto res = isl::pw_multi_aff::subtract_domain(uset); + return typed::union_pw_multi_aff, pair>(res); +} + +template +typed::pw_multi_aff, pair> typed::pw_multi_aff, pair>::subtract_domain(const typed::basic_set> &set) const +{ + auto res = isl::pw_multi_aff::subtract_domain(set); + return typed::pw_multi_aff, pair>(res); +} + +template +typed::pw_multi_aff, pair> typed::pw_multi_aff, pair>::subtract_domain(const typed::point> &set) const +{ + auto res = isl::pw_multi_aff::subtract_domain(set); + return typed::pw_multi_aff, pair>(res); +} + +template +typed::multi_pw_aff, pair> typed::pw_multi_aff, pair>::to_multi_pw_aff() const +{ + auto res = isl::pw_multi_aff::to_multi_pw_aff(); + return typed::multi_pw_aff, pair>(res); +} + +template +typed::union_pw_multi_aff, pair> typed::pw_multi_aff, pair>::to_union_pw_multi_aff() const +{ + auto res = isl::pw_multi_aff::to_union_pw_multi_aff(); + return typed::union_pw_multi_aff, pair>(res); +} + +template +typed::multi_pw_aff, pair> typed::pw_multi_aff, pair>::union_add(const typed::multi_pw_aff, pair> &mpa2) const +{ + auto res = isl::pw_multi_aff::union_add(mpa2); + return typed::multi_pw_aff, pair>(res); +} + +template +typed::multi_union_pw_aff, pair> typed::pw_multi_aff, pair>::union_add(const typed::multi_union_pw_aff, pair> &mupa2) const +{ + auto res = isl::pw_multi_aff::union_add(mupa2); + return typed::multi_union_pw_aff, pair>(res); +} + +template +typed::pw_multi_aff, pair> typed::pw_multi_aff, pair>::union_add(const typed::pw_multi_aff, pair> &pma2) const +{ + auto res = isl::pw_multi_aff::union_add(pma2); + return typed::pw_multi_aff, pair>(res); +} + +template +typed::union_pw_multi_aff, pair> typed::pw_multi_aff, pair>::union_add(const typed::union_pw_multi_aff, pair> &upma2) const +{ + auto res = isl::pw_multi_aff::union_add(upma2); + return typed::union_pw_multi_aff, pair>(res); +} + +template +typed::pw_multi_aff, pair> typed::pw_multi_aff, pair>::union_add(const typed::multi_aff, pair> &pma2) const +{ + auto res = isl::pw_multi_aff::union_add(pma2); + return typed::pw_multi_aff, pair>(res); +} + +template +typed::pw_multi_aff, pair> typed::pw_multi_aff, pair>::union_add(const typed::pw_aff, pair> &pma2) const +{ + auto res = isl::pw_multi_aff::union_add(pma2); + return typed::pw_multi_aff, pair>(res); +} + +template +typed::pw_multi_aff_list::pw_multi_aff_list(const isl::ctx &ctx, int n) + : isl::pw_multi_aff_list(ctx, n) +{ +} + +template +typed::pw_multi_aff_list::pw_multi_aff_list(const typed::pw_multi_aff &el) + : isl::pw_multi_aff_list(el) +{ +} + +template +typed::pw_multi_aff_list::pw_multi_aff_list(const isl::ctx &ctx, const std::string &str) + : isl::pw_multi_aff_list(ctx, str) +{ +} + +template +typed::pw_multi_aff_list typed::pw_multi_aff_list::add(const typed::pw_multi_aff &el) const +{ + auto res = isl::pw_multi_aff_list::add(el); + return typed::pw_multi_aff_list(res); +} + +template +typed::pw_multi_aff_list typed::pw_multi_aff_list::add(const typed::multi_aff &el) const +{ + auto res = isl::pw_multi_aff_list::add(el); + return typed::pw_multi_aff_list(res); +} + +template +typed::pw_multi_aff_list typed::pw_multi_aff_list::add(const typed::pw_aff &el) const +{ + auto res = isl::pw_multi_aff_list::add(el); + return typed::pw_multi_aff_list(res); +} + +template +typed::pw_multi_aff typed::pw_multi_aff_list::at(int index) const +{ + auto res = isl::pw_multi_aff_list::at(index); + return typed::pw_multi_aff(res); +} + +template +typed::pw_multi_aff_list typed::pw_multi_aff_list::drop(unsigned int first, unsigned int n) const +{ + auto res = isl::pw_multi_aff_list::drop(first, n); + return typed::pw_multi_aff_list(res); +} + +template +void typed::pw_multi_aff_list::foreach(const std::function)> &fn) const +{ + auto lambda_fn = [&] (isl::pw_multi_aff arg0) { + return fn(typed::pw_multi_aff(arg0)); + }; + return isl::pw_multi_aff_list::foreach(lambda_fn); +} + +template +void typed::pw_multi_aff_list::foreach_scc(const std::function, typed::pw_multi_aff)> &follows, const std::function)> &fn) const +{ + auto lambda_follows = [&] (isl::pw_multi_aff arg0, isl::pw_multi_aff arg1) { + return follows(typed::pw_multi_aff(arg0), typed::pw_multi_aff(arg1)); + }; + auto lambda_fn = [&] (isl::pw_multi_aff_list arg0) { + return fn(typed::pw_multi_aff_list(arg0)); + }; + return isl::pw_multi_aff_list::foreach_scc(lambda_follows, lambda_fn); +} + +template +typed::pw_multi_aff_list typed::pw_multi_aff_list::set_at(int index, const typed::pw_multi_aff &el) const +{ + auto res = isl::pw_multi_aff_list::set_at(index, el); + return typed::pw_multi_aff_list(res); +} + +template +typed::pw_multi_aff_list::pw_multi_aff_list(const isl::ctx &ctx, int n) + : isl::pw_multi_aff_list(ctx, n) +{ +} + +template +typed::pw_multi_aff_list::pw_multi_aff_list(const typed::pw_multi_aff &el) + : isl::pw_multi_aff_list(el) +{ +} + +template +typed::pw_multi_aff_list::pw_multi_aff_list(const isl::ctx &ctx, const std::string &str) + : isl::pw_multi_aff_list(ctx, str) +{ +} + +template +typed::pw_multi_aff_list typed::pw_multi_aff_list::add(const typed::pw_multi_aff &el) const +{ + auto res = isl::pw_multi_aff_list::add(el); + return typed::pw_multi_aff_list(res); +} + +template +typed::pw_multi_aff_list typed::pw_multi_aff_list::add(const typed::multi_aff &el) const +{ + auto res = isl::pw_multi_aff_list::add(el); + return typed::pw_multi_aff_list(res); +} + +template +typed::pw_multi_aff_list typed::pw_multi_aff_list::add(const typed::pw_aff &el) const +{ + auto res = isl::pw_multi_aff_list::add(el); + return typed::pw_multi_aff_list(res); +} + +template +typed::pw_multi_aff typed::pw_multi_aff_list::at(int index) const +{ + auto res = isl::pw_multi_aff_list::at(index); + return typed::pw_multi_aff(res); +} + +template +typed::pw_multi_aff_list typed::pw_multi_aff_list::drop(unsigned int first, unsigned int n) const +{ + auto res = isl::pw_multi_aff_list::drop(first, n); + return typed::pw_multi_aff_list(res); +} + +template +void typed::pw_multi_aff_list::foreach(const std::function)> &fn) const +{ + auto lambda_fn = [&] (isl::pw_multi_aff arg0) { + return fn(typed::pw_multi_aff(arg0)); + }; + return isl::pw_multi_aff_list::foreach(lambda_fn); +} + +template +void typed::pw_multi_aff_list::foreach_scc(const std::function, typed::pw_multi_aff)> &follows, const std::function)> &fn) const +{ + auto lambda_follows = [&] (isl::pw_multi_aff arg0, isl::pw_multi_aff arg1) { + return follows(typed::pw_multi_aff(arg0), typed::pw_multi_aff(arg1)); + }; + auto lambda_fn = [&] (isl::pw_multi_aff_list arg0) { + return fn(typed::pw_multi_aff_list(arg0)); + }; + return isl::pw_multi_aff_list::foreach_scc(lambda_follows, lambda_fn); +} + +template +typed::pw_multi_aff_list typed::pw_multi_aff_list::set_at(int index, const typed::pw_multi_aff &el) const +{ + auto res = isl::pw_multi_aff_list::set_at(index, el); + return typed::pw_multi_aff_list(res); +} + +typed::set<>::set(const typed::basic_set<> &bset) + : isl::set(bset) +{ +} + +typed::set<>::set(const typed::point<> &pnt) + : isl::set(pnt) +{ +} + +typed::set<>::set(const isl::ctx &ctx, const std::string &str) + : isl::set(ctx, str) +{ +} + +typed::set<> typed::set<>::coalesce() const +{ + auto res = isl::set::coalesce(); + return typed::set<>(res); +} + +typed::set<> typed::set<>::detect_equalities() const +{ + auto res = isl::set::detect_equalities(); + return typed::set<>(res); +} + +typed::set<> typed::set<>::drop_unused_params() const +{ + auto res = isl::set::drop_unused_params(); + return typed::set<>(res); +} + +bool typed::set<>::every_set(const std::function)> &test) const +{ + auto lambda_test = [&] (isl::set arg0) { + return test(typed::set<>(arg0)); + }; + return isl::set::every_set(lambda_test); +} + +typed::set<> typed::set<>::extract_set(const typed::space<> &space) const +{ + auto res = isl::set::extract_set(space); + return typed::set<>(res); +} + +void typed::set<>::foreach_basic_set(const std::function)> &fn) const +{ + auto lambda_fn = [&] (isl::basic_set arg0) { + return fn(typed::basic_set<>(arg0)); + }; + return isl::set::foreach_basic_set(lambda_fn); +} + +void typed::set<>::foreach_point(const std::function)> &fn) const +{ + auto lambda_fn = [&] (isl::point arg0) { + return fn(typed::point<>(arg0)); + }; + return isl::set::foreach_point(lambda_fn); +} + +void typed::set<>::foreach_set(const std::function)> &fn) const +{ + auto lambda_fn = [&] (isl::set arg0) { + return fn(typed::set<>(arg0)); + }; + return isl::set::foreach_set(lambda_fn); +} + +typed::set<> typed::set<>::gist(const typed::set<> &context) const +{ + auto res = isl::set::gist(context); + return typed::set<>(res); +} + +typed::union_set<> typed::set<>::gist(const typed::union_set<> &context) const +{ + auto res = isl::set::gist(context); + return typed::union_set<>(res); +} + +typed::set<> typed::set<>::gist(const typed::basic_set<> &context) const +{ + auto res = isl::set::gist(context); + return typed::set<>(res); +} + +typed::set<> typed::set<>::gist(const typed::point<> &context) const +{ + auto res = isl::set::gist(context); + return typed::set<>(res); +} + +typed::pw_aff typed::set<>::indicator_function() const +{ + auto res = isl::set::indicator_function(); + return typed::pw_aff(res); +} + +typed::set<> typed::set<>::intersect(const typed::set<> &set2) const +{ + auto res = isl::set::intersect(set2); + return typed::set<>(res); +} + +typed::union_set<> typed::set<>::intersect(const typed::union_set<> &uset2) const +{ + auto res = isl::set::intersect(uset2); + return typed::union_set<>(res); +} + +typed::set<> typed::set<>::intersect(const typed::basic_set<> &set2) const +{ + auto res = isl::set::intersect(set2); + return typed::set<>(res); +} + +typed::set<> typed::set<>::intersect(const typed::point<> &set2) const +{ + auto res = isl::set::intersect(set2); + return typed::set<>(res); +} + +typed::pw_aff typed::set<>::param_pw_aff_on_domain(const typed::id &id) const +{ + auto res = isl::set::param_pw_aff_on_domain(id); + return typed::pw_aff(res); +} + +typed::pw_aff typed::set<>::param_pw_aff_on_domain(const std::string &id) const +{ + auto res = isl::set::param_pw_aff_on_domain(id); + return typed::pw_aff(res); +} + +typed::set<> typed::set<>::project_out_all_params() const +{ + auto res = isl::set::project_out_all_params(); + return typed::set<>(res); +} + +typed::set<> typed::set<>::project_out_param(const typed::id &id) const +{ + auto res = isl::set::project_out_param(id); + return typed::set<>(res); +} + +typed::set<> typed::set<>::project_out_param(const std::string &id) const +{ + auto res = isl::set::project_out_param(id); + return typed::set<>(res); +} + +typed::set<> typed::set<>::project_out_param(const typed::id_list &list) const +{ + auto res = isl::set::project_out_param(list); + return typed::set<>(res); +} + +typed::pw_aff typed::set<>::pw_aff_on_domain(const typed::val &v) const +{ + auto res = isl::set::pw_aff_on_domain(v); + return typed::pw_aff(res); +} + +typed::pw_aff typed::set<>::pw_aff_on_domain(long v) const +{ + auto res = isl::set::pw_aff_on_domain(v); + return typed::pw_aff(res); +} + +template +typed::pw_multi_aff typed::set<>::pw_multi_aff_on_domain(const typed::multi_val &mv) const +{ + auto res = isl::set::pw_multi_aff_on_domain(mv); + return typed::pw_multi_aff(res); +} + +typed::set_list<> typed::set<>::set_list() const +{ + auto res = isl::set::set_list(); + return typed::set_list<>(res); +} + +typed::space<> typed::set<>::space() const +{ + auto res = isl::set::space(); + return typed::space<>(res); +} + +typed::set<> typed::set<>::subtract(const typed::set<> &set2) const +{ + auto res = isl::set::subtract(set2); + return typed::set<>(res); +} + +typed::union_set<> typed::set<>::subtract(const typed::union_set<> &uset2) const +{ + auto res = isl::set::subtract(uset2); + return typed::union_set<>(res); +} + +typed::set<> typed::set<>::subtract(const typed::basic_set<> &set2) const +{ + auto res = isl::set::subtract(set2); + return typed::set<>(res); +} + +typed::set<> typed::set<>::subtract(const typed::point<> &set2) const +{ + auto res = isl::set::subtract(set2); + return typed::set<>(res); +} + +typed::union_set<> typed::set<>::to_union_set() const +{ + auto res = isl::set::to_union_set(); + return typed::union_set<>(res); +} + +template +typed::set typed::set<>::unbind_params(const typed::multi_id &tuple) const +{ + auto res = isl::set::unbind_params(tuple); + return typed::set(res); +} + +typed::set<> typed::set<>::unite(const typed::set<> &set2) const +{ + auto res = isl::set::unite(set2); + return typed::set<>(res); +} + +typed::union_set<> typed::set<>::unite(const typed::union_set<> &uset2) const +{ + auto res = isl::set::unite(uset2); + return typed::union_set<>(res); +} + +typed::set<> typed::set<>::unite(const typed::basic_set<> &set2) const +{ + auto res = isl::set::unite(set2); + return typed::set<>(res); +} + +typed::set<> typed::set<>::unite(const typed::point<> &set2) const +{ + auto res = isl::set::unite(set2); + return typed::set<>(res); +} + +typed::set<> typed::set<>::universe(const typed::space<> &space) +{ + auto res = isl::set::universe(space); + return typed::set<>(res); +} + +template +typed::set::set(const typed::basic_set &bset) + : isl::set(bset) +{ +} + +template +typed::set::set(const typed::point &pnt) + : isl::set(pnt) +{ +} + +template +typed::set::set(const isl::ctx &ctx, const std::string &str) + : isl::set(ctx, str) +{ +} + +template +template +typed::set typed::set::apply(const typed::map &map) const +{ + auto res = isl::set::apply(map); + return typed::set(res); +} + +template +template +typed::union_set typed::set::apply(const typed::union_map &umap) const +{ + auto res = isl::set::apply(umap); + return typed::union_set(res); +} + +template +template +typed::set typed::set::apply(const typed::basic_map &map) const +{ + auto res = isl::set::apply(map); + return typed::set(res); +} + +template +typed::pw_multi_aff typed::set::as_pw_multi_aff() const +{ + auto res = isl::set::as_pw_multi_aff(); + return typed::pw_multi_aff(res); +} + +template +typed::set typed::set::as_set() const +{ + auto res = isl::set::as_set(); + return typed::set(res); +} + +template +typed::set<> typed::set::bind(const typed::multi_id &tuple) const +{ + auto res = isl::set::bind(tuple); + return typed::set<>(res); +} + +template +typed::set typed::set::coalesce() const +{ + auto res = isl::set::coalesce(); + return typed::set(res); +} + +template +typed::set typed::set::detect_equalities() const +{ + auto res = isl::set::detect_equalities(); + return typed::set(res); +} + +template +typed::set typed::set::drop_unused_params() const +{ + auto res = isl::set::drop_unused_params(); + return typed::set(res); +} + +template +bool typed::set::every_set(const std::function)> &test) const +{ + auto lambda_test = [&] (isl::set arg0) { + return test(typed::set(arg0)); + }; + return isl::set::every_set(lambda_test); +} + +template +typed::set typed::set::extract_set(const typed::space &space) const +{ + auto res = isl::set::extract_set(space); + return typed::set(res); +} + +template +void typed::set::foreach_basic_set(const std::function)> &fn) const +{ + auto lambda_fn = [&] (isl::basic_set arg0) { + return fn(typed::basic_set(arg0)); + }; + return isl::set::foreach_basic_set(lambda_fn); +} + +template +void typed::set::foreach_point(const std::function)> &fn) const +{ + auto lambda_fn = [&] (isl::point arg0) { + return fn(typed::point(arg0)); + }; + return isl::set::foreach_point(lambda_fn); +} + +template +void typed::set::foreach_set(const std::function)> &fn) const +{ + auto lambda_fn = [&] (isl::set arg0) { + return fn(typed::set(arg0)); + }; + return isl::set::foreach_set(lambda_fn); +} + +template +typed::set typed::set::gist(const typed::set &context) const +{ + auto res = isl::set::gist(context); + return typed::set(res); +} + +template +typed::union_set typed::set::gist(const typed::union_set &context) const +{ + auto res = isl::set::gist(context); + return typed::union_set(res); +} + +template +typed::set typed::set::gist(const typed::basic_set &context) const +{ + auto res = isl::set::gist(context); + return typed::set(res); +} + +template +typed::set typed::set::gist(const typed::point &context) const +{ + auto res = isl::set::gist(context); + return typed::set(res); +} + +template +typed::set typed::set::gist_params(const typed::set<> &context) const +{ + auto res = isl::set::gist_params(context); + return typed::set(res); +} + +template +typed::set typed::set::gist_params(const typed::basic_set<> &context) const +{ + auto res = isl::set::gist_params(context); + return typed::set(res); +} + +template +typed::set typed::set::gist_params(const typed::point<> &context) const +{ + auto res = isl::set::gist_params(context); + return typed::set(res); +} + +template +typed::map typed::set::identity() const +{ + auto res = isl::set::identity(); + return typed::map(res); +} + +template +typed::pw_aff typed::set::indicator_function() const +{ + auto res = isl::set::indicator_function(); + return typed::pw_aff(res); +} + +template +template +typed::map typed::set::insert_domain(const typed::space &domain) const +{ + auto res = isl::set::insert_domain(domain); + return typed::map(res); +} + +template +typed::set typed::set::intersect(const typed::set &set2) const +{ + auto res = isl::set::intersect(set2); + return typed::set(res); +} + +template +typed::union_set typed::set::intersect(const typed::union_set &uset2) const +{ + auto res = isl::set::intersect(uset2); + return typed::union_set(res); +} + +template +typed::set typed::set::intersect(const typed::basic_set &set2) const +{ + auto res = isl::set::intersect(set2); + return typed::set(res); +} + +template +typed::set typed::set::intersect(const typed::point &set2) const +{ + auto res = isl::set::intersect(set2); + return typed::set(res); +} + +template +typed::set typed::set::intersect_params(const typed::set<> ¶ms) const +{ + auto res = isl::set::intersect_params(params); + return typed::set(res); +} + +template +typed::set typed::set::intersect_params(const typed::basic_set<> ¶ms) const +{ + auto res = isl::set::intersect_params(params); + return typed::set(res); +} + +template +typed::set typed::set::intersect_params(const typed::point<> ¶ms) const +{ + auto res = isl::set::intersect_params(params); + return typed::set(res); +} + +template +typed::fixed_box typed::set::lattice_tile() const +{ + auto res = isl::set::lattice_tile(); + return typed::fixed_box(res); +} + +template +typed::set typed::set::lexmax() const +{ + auto res = isl::set::lexmax(); + return typed::set(res); +} + +template +typed::pw_multi_aff typed::set::lexmax_pw_multi_aff() const +{ + auto res = isl::set::lexmax_pw_multi_aff(); + return typed::pw_multi_aff(res); +} + +template +typed::set typed::set::lexmin() const +{ + auto res = isl::set::lexmin(); + return typed::set(res); +} + +template +typed::pw_multi_aff typed::set::lexmin_pw_multi_aff() const +{ + auto res = isl::set::lexmin_pw_multi_aff(); + return typed::pw_multi_aff(res); +} + +template +typed::set typed::set::lower_bound(const typed::multi_pw_aff &lower) const +{ + auto res = isl::set::lower_bound(lower); + return typed::set(res); +} + +template +typed::set typed::set::lower_bound(const typed::multi_val &lower) const +{ + auto res = isl::set::lower_bound(lower); + return typed::set(res); +} + +template +typed::multi_pw_aff typed::set::max_multi_pw_aff() const +{ + auto res = isl::set::max_multi_pw_aff(); + return typed::multi_pw_aff(res); +} + +template +typed::multi_pw_aff typed::set::min_multi_pw_aff() const +{ + auto res = isl::set::min_multi_pw_aff(); + return typed::multi_pw_aff(res); +} + +template +typed::pw_aff typed::set::param_pw_aff_on_domain(const typed::id &id) const +{ + auto res = isl::set::param_pw_aff_on_domain(id); + return typed::pw_aff(res); +} + +template +typed::pw_aff typed::set::param_pw_aff_on_domain(const std::string &id) const +{ + auto res = isl::set::param_pw_aff_on_domain(id); + return typed::pw_aff(res); +} + +template +typed::set<> typed::set::params() const +{ + auto res = isl::set::params(); + return typed::set<>(res); +} + +template +typed::multi_val typed::set::plain_multi_val_if_fixed() const +{ + auto res = isl::set::plain_multi_val_if_fixed(); + return typed::multi_val(res); +} + +template +template +typed::set typed::set::preimage(const typed::multi_aff &ma) const +{ + auto res = isl::set::preimage(ma); + return typed::set(res); +} + +template +template +typed::set typed::set::preimage(const typed::multi_pw_aff &mpa) const +{ + auto res = isl::set::preimage(mpa); + return typed::set(res); +} + +template +template +typed::set typed::set::preimage(const typed::pw_multi_aff &pma) const +{ + auto res = isl::set::preimage(pma); + return typed::set(res); +} + +template +template +typed::union_set typed::set::preimage(const typed::union_pw_multi_aff &upma) const +{ + auto res = isl::set::preimage(upma); + return typed::union_set(res); +} + +template +template +typed::set> typed::set::product(const typed::set &set2) const +{ + auto res = isl::set::product(set2); + return typed::set>(res); +} + +template +template +typed::set> typed::set::product(const typed::basic_set &set2) const +{ + auto res = isl::set::product(set2); + return typed::set>(res); +} + +template +template +typed::set> typed::set::product(const typed::point &set2) const +{ + auto res = isl::set::product(set2); + return typed::set>(res); +} + +template +typed::set typed::set::project_out_all_params() const +{ + auto res = isl::set::project_out_all_params(); + return typed::set(res); +} + +template +typed::set typed::set::project_out_param(const typed::id &id) const +{ + auto res = isl::set::project_out_param(id); + return typed::set(res); +} + +template +typed::set typed::set::project_out_param(const std::string &id) const +{ + auto res = isl::set::project_out_param(id); + return typed::set(res); +} + +template +typed::set typed::set::project_out_param(const typed::id_list &list) const +{ + auto res = isl::set::project_out_param(list); + return typed::set(res); +} + +template +typed::pw_aff typed::set::pw_aff_on_domain(const typed::val &v) const +{ + auto res = isl::set::pw_aff_on_domain(v); + return typed::pw_aff(res); +} + +template +typed::pw_aff typed::set::pw_aff_on_domain(long v) const +{ + auto res = isl::set::pw_aff_on_domain(v); + return typed::pw_aff(res); +} + +template +template +typed::pw_multi_aff typed::set::pw_multi_aff_on_domain(const typed::multi_val &mv) const +{ + auto res = isl::set::pw_multi_aff_on_domain(mv); + return typed::pw_multi_aff(res); +} + +template +typed::set_list typed::set::set_list() const +{ + auto res = isl::set::set_list(); + return typed::set_list(res); +} + +template +typed::fixed_box typed::set::simple_fixed_box_hull() const +{ + auto res = isl::set::simple_fixed_box_hull(); + return typed::fixed_box(res); +} + +template +typed::space typed::set::space() const +{ + auto res = isl::set::space(); + return typed::space(res); +} + +template +typed::set typed::set::subtract(const typed::set &set2) const +{ + auto res = isl::set::subtract(set2); + return typed::set(res); +} + +template +typed::union_set typed::set::subtract(const typed::union_set &uset2) const +{ + auto res = isl::set::subtract(uset2); + return typed::union_set(res); +} + +template +typed::set typed::set::subtract(const typed::basic_set &set2) const +{ + auto res = isl::set::subtract(set2); + return typed::set(res); +} + +template +typed::set typed::set::subtract(const typed::point &set2) const +{ + auto res = isl::set::subtract(set2); + return typed::set(res); +} + +template +typed::union_set typed::set::to_union_set() const +{ + auto res = isl::set::to_union_set(); + return typed::union_set(res); +} + +template +typed::map typed::set::translation() const +{ + auto res = isl::set::translation(); + return typed::map(res); +} + +template +template +typed::map typed::set::unbind_params_insert_domain(const typed::multi_id &domain) const +{ + auto res = isl::set::unbind_params_insert_domain(domain); + return typed::map(res); +} + +template +typed::set typed::set::unite(const typed::set &set2) const +{ + auto res = isl::set::unite(set2); + return typed::set(res); +} + +template +typed::union_set typed::set::unite(const typed::union_set &uset2) const +{ + auto res = isl::set::unite(uset2); + return typed::union_set(res); +} + +template +typed::set typed::set::unite(const typed::basic_set &set2) const +{ + auto res = isl::set::unite(set2); + return typed::set(res); +} + +template +typed::set typed::set::unite(const typed::point &set2) const +{ + auto res = isl::set::unite(set2); + return typed::set(res); +} + +template +typed::set typed::set::universe(const typed::space &space) +{ + auto res = isl::set::universe(space); + return typed::set(res); +} + +template +typed::set typed::set::upper_bound(const typed::multi_pw_aff &upper) const +{ + auto res = isl::set::upper_bound(upper); + return typed::set(res); +} + +template +typed::set typed::set::upper_bound(const typed::multi_val &upper) const +{ + auto res = isl::set::upper_bound(upper); + return typed::set(res); +} + +template +typed::set>::set(const typed::basic_set> &bset) + : isl::set(bset) +{ +} + +template +typed::set>::set(const typed::point> &pnt) + : isl::set(pnt) +{ +} + +template +typed::set>::set(const isl::ctx &ctx, const std::string &str) + : isl::set(ctx, str) +{ +} + +template +template +typed::set typed::set>::apply(const typed::map, Arg2> &map) const +{ + auto res = isl::set::apply(map); + return typed::set(res); +} + +template +template +typed::union_set typed::set>::apply(const typed::union_map, Arg2> &umap) const +{ + auto res = isl::set::apply(umap); + return typed::union_set(res); +} + +template +template +typed::set typed::set>::apply(const typed::basic_map, Arg2> &map) const +{ + auto res = isl::set::apply(map); + return typed::set(res); +} + +template +typed::pw_multi_aff> typed::set>::as_pw_multi_aff() const +{ + auto res = isl::set::as_pw_multi_aff(); + return typed::pw_multi_aff>(res); +} + +template +typed::set> typed::set>::as_set() const +{ + auto res = isl::set::as_set(); + return typed::set>(res); +} + +template +typed::set<> typed::set>::bind(const typed::multi_id> &tuple) const +{ + auto res = isl::set::bind(tuple); + return typed::set<>(res); +} + +template +typed::set> typed::set>::coalesce() const +{ + auto res = isl::set::coalesce(); + return typed::set>(res); +} + +template +typed::set> typed::set>::detect_equalities() const +{ + auto res = isl::set::detect_equalities(); + return typed::set>(res); +} + +template +typed::set> typed::set>::drop_unused_params() const +{ + auto res = isl::set::drop_unused_params(); + return typed::set>(res); +} + +template +bool typed::set>::every_set(const std::function>)> &test) const +{ + auto lambda_test = [&] (isl::set arg0) { + return test(typed::set>(arg0)); + }; + return isl::set::every_set(lambda_test); +} + +template +typed::set> typed::set>::extract_set(const typed::space> &space) const +{ + auto res = isl::set::extract_set(space); + return typed::set>(res); +} + +template +void typed::set>::foreach_basic_set(const std::function>)> &fn) const +{ + auto lambda_fn = [&] (isl::basic_set arg0) { + return fn(typed::basic_set>(arg0)); + }; + return isl::set::foreach_basic_set(lambda_fn); +} + +template +void typed::set>::foreach_point(const std::function>)> &fn) const +{ + auto lambda_fn = [&] (isl::point arg0) { + return fn(typed::point>(arg0)); + }; + return isl::set::foreach_point(lambda_fn); +} + +template +void typed::set>::foreach_set(const std::function>)> &fn) const +{ + auto lambda_fn = [&] (isl::set arg0) { + return fn(typed::set>(arg0)); + }; + return isl::set::foreach_set(lambda_fn); +} + +template +typed::set> typed::set>::gist(const typed::set> &context) const +{ + auto res = isl::set::gist(context); + return typed::set>(res); +} + +template +typed::union_set> typed::set>::gist(const typed::union_set> &context) const +{ + auto res = isl::set::gist(context); + return typed::union_set>(res); +} + +template +typed::set> typed::set>::gist(const typed::basic_set> &context) const +{ + auto res = isl::set::gist(context); + return typed::set>(res); +} + +template +typed::set> typed::set>::gist(const typed::point> &context) const +{ + auto res = isl::set::gist(context); + return typed::set>(res); +} + +template +typed::set> typed::set>::gist_params(const typed::set<> &context) const +{ + auto res = isl::set::gist_params(context); + return typed::set>(res); +} + +template +typed::set> typed::set>::gist_params(const typed::basic_set<> &context) const +{ + auto res = isl::set::gist_params(context); + return typed::set>(res); +} + +template +typed::set> typed::set>::gist_params(const typed::point<> &context) const +{ + auto res = isl::set::gist_params(context); + return typed::set>(res); +} + +template +typed::map, pair> typed::set>::identity() const +{ + auto res = isl::set::identity(); + return typed::map, pair>(res); +} + +template +typed::pw_aff, Anonymous> typed::set>::indicator_function() const +{ + auto res = isl::set::indicator_function(); + return typed::pw_aff, Anonymous>(res); +} + +template +template +typed::map> typed::set>::insert_domain(const typed::space &domain) const +{ + auto res = isl::set::insert_domain(domain); + return typed::map>(res); +} + +template +typed::set> typed::set>::intersect(const typed::set> &set2) const +{ + auto res = isl::set::intersect(set2); + return typed::set>(res); +} + +template +typed::union_set> typed::set>::intersect(const typed::union_set> &uset2) const +{ + auto res = isl::set::intersect(uset2); + return typed::union_set>(res); +} + +template +typed::set> typed::set>::intersect(const typed::basic_set> &set2) const +{ + auto res = isl::set::intersect(set2); + return typed::set>(res); +} + +template +typed::set> typed::set>::intersect(const typed::point> &set2) const +{ + auto res = isl::set::intersect(set2); + return typed::set>(res); +} + +template +typed::set> typed::set>::intersect_params(const typed::set<> ¶ms) const +{ + auto res = isl::set::intersect_params(params); + return typed::set>(res); +} + +template +typed::set> typed::set>::intersect_params(const typed::basic_set<> ¶ms) const +{ + auto res = isl::set::intersect_params(params); + return typed::set>(res); +} + +template +typed::set> typed::set>::intersect_params(const typed::point<> ¶ms) const +{ + auto res = isl::set::intersect_params(params); + return typed::set>(res); +} + +template +typed::fixed_box> typed::set>::lattice_tile() const +{ + auto res = isl::set::lattice_tile(); + return typed::fixed_box>(res); +} + +template +typed::set> typed::set>::lexmax() const +{ + auto res = isl::set::lexmax(); + return typed::set>(res); +} + +template +typed::pw_multi_aff> typed::set>::lexmax_pw_multi_aff() const +{ + auto res = isl::set::lexmax_pw_multi_aff(); + return typed::pw_multi_aff>(res); +} + +template +typed::set> typed::set>::lexmin() const +{ + auto res = isl::set::lexmin(); + return typed::set>(res); +} + +template +typed::pw_multi_aff> typed::set>::lexmin_pw_multi_aff() const +{ + auto res = isl::set::lexmin_pw_multi_aff(); + return typed::pw_multi_aff>(res); +} + +template +typed::set> typed::set>::lower_bound(const typed::multi_pw_aff> &lower) const +{ + auto res = isl::set::lower_bound(lower); + return typed::set>(res); +} + +template +typed::set> typed::set>::lower_bound(const typed::multi_val> &lower) const +{ + auto res = isl::set::lower_bound(lower); + return typed::set>(res); +} + +template +typed::multi_pw_aff> typed::set>::max_multi_pw_aff() const +{ + auto res = isl::set::max_multi_pw_aff(); + return typed::multi_pw_aff>(res); +} + +template +typed::multi_pw_aff> typed::set>::min_multi_pw_aff() const +{ + auto res = isl::set::min_multi_pw_aff(); + return typed::multi_pw_aff>(res); +} + +template +typed::pw_aff, Anonymous> typed::set>::param_pw_aff_on_domain(const typed::id &id) const +{ + auto res = isl::set::param_pw_aff_on_domain(id); + return typed::pw_aff, Anonymous>(res); +} + +template +typed::pw_aff, Anonymous> typed::set>::param_pw_aff_on_domain(const std::string &id) const +{ + auto res = isl::set::param_pw_aff_on_domain(id); + return typed::pw_aff, Anonymous>(res); +} + +template +typed::set<> typed::set>::params() const +{ + auto res = isl::set::params(); + return typed::set<>(res); +} + +template +typed::multi_val> typed::set>::plain_multi_val_if_fixed() const +{ + auto res = isl::set::plain_multi_val_if_fixed(); + return typed::multi_val>(res); +} + +template +template +typed::set typed::set>::preimage(const typed::multi_aff> &ma) const +{ + auto res = isl::set::preimage(ma); + return typed::set(res); +} + +template +template +typed::set typed::set>::preimage(const typed::multi_pw_aff> &mpa) const +{ + auto res = isl::set::preimage(mpa); + return typed::set(res); +} + +template +template +typed::set typed::set>::preimage(const typed::pw_multi_aff> &pma) const +{ + auto res = isl::set::preimage(pma); + return typed::set(res); +} + +template +template +typed::union_set typed::set>::preimage(const typed::union_pw_multi_aff> &upma) const +{ + auto res = isl::set::preimage(upma); + return typed::union_set(res); +} + +template +template +typed::set, Arg2>> typed::set>::product(const typed::set &set2) const +{ + auto res = isl::set::product(set2); + return typed::set, Arg2>>(res); +} + +template +template +typed::set, Arg2>> typed::set>::product(const typed::basic_set &set2) const +{ + auto res = isl::set::product(set2); + return typed::set, Arg2>>(res); +} + +template +template +typed::set, Arg2>> typed::set>::product(const typed::point &set2) const +{ + auto res = isl::set::product(set2); + return typed::set, Arg2>>(res); +} + +template +typed::set> typed::set>::project_out_all_params() const +{ + auto res = isl::set::project_out_all_params(); + return typed::set>(res); +} + +template +typed::set> typed::set>::project_out_param(const typed::id &id) const +{ + auto res = isl::set::project_out_param(id); + return typed::set>(res); +} + +template +typed::set> typed::set>::project_out_param(const std::string &id) const +{ + auto res = isl::set::project_out_param(id); + return typed::set>(res); +} + +template +typed::set> typed::set>::project_out_param(const typed::id_list &list) const +{ + auto res = isl::set::project_out_param(list); + return typed::set>(res); +} + +template +typed::pw_aff, Anonymous> typed::set>::pw_aff_on_domain(const typed::val &v) const +{ + auto res = isl::set::pw_aff_on_domain(v); + return typed::pw_aff, Anonymous>(res); +} + +template +typed::pw_aff, Anonymous> typed::set>::pw_aff_on_domain(long v) const +{ + auto res = isl::set::pw_aff_on_domain(v); + return typed::pw_aff, Anonymous>(res); +} + +template +template +typed::pw_multi_aff, Arg2> typed::set>::pw_multi_aff_on_domain(const typed::multi_val &mv) const +{ + auto res = isl::set::pw_multi_aff_on_domain(mv); + return typed::pw_multi_aff, Arg2>(res); +} + +template +typed::set_list> typed::set>::set_list() const +{ + auto res = isl::set::set_list(); + return typed::set_list>(res); +} + +template +typed::fixed_box> typed::set>::simple_fixed_box_hull() const +{ + auto res = isl::set::simple_fixed_box_hull(); + return typed::fixed_box>(res); +} + +template +typed::space> typed::set>::space() const +{ + auto res = isl::set::space(); + return typed::space>(res); +} + +template +typed::set> typed::set>::subtract(const typed::set> &set2) const +{ + auto res = isl::set::subtract(set2); + return typed::set>(res); +} + +template +typed::union_set> typed::set>::subtract(const typed::union_set> &uset2) const +{ + auto res = isl::set::subtract(uset2); + return typed::union_set>(res); +} + +template +typed::set> typed::set>::subtract(const typed::basic_set> &set2) const +{ + auto res = isl::set::subtract(set2); + return typed::set>(res); +} + +template +typed::set> typed::set>::subtract(const typed::point> &set2) const +{ + auto res = isl::set::subtract(set2); + return typed::set>(res); +} + +template +typed::union_set> typed::set>::to_union_set() const +{ + auto res = isl::set::to_union_set(); + return typed::union_set>(res); +} + +template +typed::map, pair> typed::set>::translation() const +{ + auto res = isl::set::translation(); + return typed::map, pair>(res); +} + +template +template +typed::map> typed::set>::unbind_params_insert_domain(const typed::multi_id &domain) const +{ + auto res = isl::set::unbind_params_insert_domain(domain); + return typed::map>(res); +} + +template +typed::set> typed::set>::unite(const typed::set> &set2) const +{ + auto res = isl::set::unite(set2); + return typed::set>(res); +} + +template +typed::union_set> typed::set>::unite(const typed::union_set> &uset2) const +{ + auto res = isl::set::unite(uset2); + return typed::union_set>(res); +} + +template +typed::set> typed::set>::unite(const typed::basic_set> &set2) const +{ + auto res = isl::set::unite(set2); + return typed::set>(res); +} + +template +typed::set> typed::set>::unite(const typed::point> &set2) const +{ + auto res = isl::set::unite(set2); + return typed::set>(res); +} + +template +typed::set> typed::set>::universe(const typed::space> &space) +{ + auto res = isl::set::universe(space); + return typed::set>(res); +} + +template +typed::map typed::set>::unwrap() const +{ + auto res = isl::set::unwrap(); + return typed::map(res); +} + +template +typed::set> typed::set>::upper_bound(const typed::multi_pw_aff> &upper) const +{ + auto res = isl::set::upper_bound(upper); + return typed::set>(res); +} + +template +typed::set> typed::set>::upper_bound(const typed::multi_val> &upper) const +{ + auto res = isl::set::upper_bound(upper); + return typed::set>(res); +} + +template +typed::set> typed::set>::wrapped_reverse() const +{ + auto res = isl::set::wrapped_reverse(); + return typed::set>(res); +} + +typed::set_list<>::set_list(const isl::ctx &ctx, int n) + : isl::set_list(ctx, n) +{ +} + +typed::set_list<>::set_list(const typed::set<> &el) + : isl::set_list(el) +{ +} + +typed::set_list<>::set_list(const isl::ctx &ctx, const std::string &str) + : isl::set_list(ctx, str) +{ +} + +typed::set_list<> typed::set_list<>::add(const typed::set<> &el) const +{ + auto res = isl::set_list::add(el); + return typed::set_list<>(res); +} + +typed::set_list<> typed::set_list<>::add(const typed::basic_set<> &el) const +{ + auto res = isl::set_list::add(el); + return typed::set_list<>(res); +} + +typed::set_list<> typed::set_list<>::add(const typed::point<> &el) const +{ + auto res = isl::set_list::add(el); + return typed::set_list<>(res); +} + +typed::set_list<> typed::set_list<>::drop(unsigned int first, unsigned int n) const +{ + auto res = isl::set_list::drop(first, n); + return typed::set_list<>(res); +} + +void typed::set_list<>::foreach(const std::function)> &fn) const +{ + auto lambda_fn = [&] (isl::set arg0) { + return fn(typed::set<>(arg0)); + }; + return isl::set_list::foreach(lambda_fn); +} + +void typed::set_list<>::foreach_scc(const std::function, typed::set<>)> &follows, const std::function)> &fn) const +{ + auto lambda_follows = [&] (isl::set arg0, isl::set arg1) { + return follows(typed::set<>(arg0), typed::set<>(arg1)); + }; + auto lambda_fn = [&] (isl::set_list arg0) { + return fn(typed::set_list<>(arg0)); + }; + return isl::set_list::foreach_scc(lambda_follows, lambda_fn); +} + +template +typed::set_list::set_list(const isl::ctx &ctx, int n) + : isl::set_list(ctx, n) +{ +} + +template +typed::set_list::set_list(const typed::set &el) + : isl::set_list(el) +{ +} + +template +typed::set_list::set_list(const isl::ctx &ctx, const std::string &str) + : isl::set_list(ctx, str) +{ +} + +template +typed::set_list typed::set_list::add(const typed::set &el) const +{ + auto res = isl::set_list::add(el); + return typed::set_list(res); +} + +template +typed::set_list typed::set_list::add(const typed::basic_set &el) const +{ + auto res = isl::set_list::add(el); + return typed::set_list(res); +} + +template +typed::set_list typed::set_list::add(const typed::point &el) const +{ + auto res = isl::set_list::add(el); + return typed::set_list(res); +} + +template +typed::set typed::set_list::at(int index) const +{ + auto res = isl::set_list::at(index); + return typed::set(res); +} + +template +typed::set_list typed::set_list::drop(unsigned int first, unsigned int n) const +{ + auto res = isl::set_list::drop(first, n); + return typed::set_list(res); +} + +template +void typed::set_list::foreach(const std::function)> &fn) const +{ + auto lambda_fn = [&] (isl::set arg0) { + return fn(typed::set(arg0)); + }; + return isl::set_list::foreach(lambda_fn); +} + +template +void typed::set_list::foreach_scc(const std::function, typed::set)> &follows, const std::function)> &fn) const +{ + auto lambda_follows = [&] (isl::set arg0, isl::set arg1) { + return follows(typed::set(arg0), typed::set(arg1)); + }; + auto lambda_fn = [&] (isl::set_list arg0) { + return fn(typed::set_list(arg0)); + }; + return isl::set_list::foreach_scc(lambda_follows, lambda_fn); +} + +template +typed::set_list typed::set_list::set_at(int index, const typed::set &el) const +{ + auto res = isl::set_list::set_at(index, el); + return typed::set_list(res); +} + +typed::space<>::space(const isl::ctx &ctx, const std::string &str) + : isl::space(ctx, str) +{ +} + +template +typed::space typed::space<>::add_named_tuple(const typed::id &tuple_id, unsigned int dim) const +{ + auto res = isl::space::add_named_tuple(tuple_id, dim); + return typed::space(res); +} + +template +typed::space typed::space<>::add_named_tuple(const std::string &tuple_id, unsigned int dim) const +{ + auto res = isl::space::add_named_tuple(tuple_id, dim); + return typed::space(res); +} + +typed::space<> typed::space<>::add_param(const typed::id &id) const +{ + auto res = isl::space::add_param(id); + return typed::space<>(res); +} + +typed::space<> typed::space<>::add_param(const std::string &id) const +{ + auto res = isl::space::add_param(id); + return typed::space<>(res); +} + +template +typed::space typed::space<>::add_unnamed_tuple(unsigned int dim) const +{ + auto res = isl::space::add_unnamed_tuple(dim); + return typed::space(res); +} + +typed::space<> typed::space<>::drop_all_params() const +{ + auto res = isl::space::drop_all_params(); + return typed::space<>(res); +} + +template +typed::multi_aff typed::space<>::multi_aff_on_domain(const typed::multi_val &mv) const +{ + auto res = isl::space::multi_aff_on_domain(mv); + return typed::multi_aff(res); +} + +typed::aff typed::space<>::param_aff_on_domain(const typed::id &id) const +{ + auto res = isl::space::param_aff_on_domain(id); + return typed::aff(res); +} + +typed::aff typed::space<>::param_aff_on_domain(const std::string &id) const +{ + auto res = isl::space::param_aff_on_domain(id); + return typed::aff(res); +} + +typed::space<> typed::space<>::unit(const isl::ctx &ctx) +{ + auto res = isl::space::unit(ctx); + return typed::space<>(res); +} + +typed::set<> typed::space<>::universe_set() const +{ + auto res = isl::space::universe_set(); + return typed::set<>(res); +} + +template +typed::space::space(const isl::ctx &ctx, const std::string &str) + : isl::space(ctx, str) +{ +} + +template +template +typed::space typed::space::add_named_tuple(const typed::id &tuple_id, unsigned int dim) const +{ + auto res = isl::space::add_named_tuple(tuple_id, dim); + return typed::space(res); +} + +template +template +typed::space typed::space::add_named_tuple(const std::string &tuple_id, unsigned int dim) const +{ + auto res = isl::space::add_named_tuple(tuple_id, dim); + return typed::space(res); +} + +template +typed::space typed::space::add_param(const typed::id &id) const +{ + auto res = isl::space::add_param(id); + return typed::space(res); +} + +template +typed::space typed::space::add_param(const std::string &id) const +{ + auto res = isl::space::add_param(id); + return typed::space(res); +} + +template +template +typed::space typed::space::add_unnamed_tuple(unsigned int dim) const +{ + auto res = isl::space::add_unnamed_tuple(dim); + return typed::space(res); +} + +template +typed::space<> typed::space::domain() const +{ + auto res = isl::space::domain(); + return typed::space<>(res); +} + +template +typed::space typed::space::drop_all_params() const +{ + auto res = isl::space::drop_all_params(); + return typed::space(res); +} + +template +typed::multi_aff typed::space::identity_multi_aff_on_domain() const +{ + auto res = isl::space::identity_multi_aff_on_domain(); + return typed::multi_aff(res); +} + +template +typed::multi_pw_aff typed::space::identity_multi_pw_aff_on_domain() const +{ + auto res = isl::space::identity_multi_pw_aff_on_domain(); + return typed::multi_pw_aff(res); +} + +template +typed::pw_multi_aff typed::space::identity_pw_multi_aff_on_domain() const +{ + auto res = isl::space::identity_pw_multi_aff_on_domain(); + return typed::pw_multi_aff(res); +} + +template +typed::space typed::space::map_from_set() const +{ + auto res = isl::space::map_from_set(); + return typed::space(res); +} + +template +typed::multi_aff typed::space::multi_aff(const typed::aff_list &list) const +{ + auto res = isl::space::multi_aff(list); + return typed::multi_aff(res); +} + +template +template +typed::multi_aff typed::space::multi_aff_on_domain(const typed::multi_val &mv) const +{ + auto res = isl::space::multi_aff_on_domain(mv); + return typed::multi_aff(res); +} + +template +typed::multi_id typed::space::multi_id(const typed::id_list &list) const +{ + auto res = isl::space::multi_id(list); + return typed::multi_id(res); +} + +template +typed::multi_pw_aff typed::space::multi_pw_aff(const typed::pw_aff_list &list) const +{ + auto res = isl::space::multi_pw_aff(list); + return typed::multi_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::space::multi_union_pw_aff(const typed::union_pw_aff_list &list) const +{ + auto res = isl::space::multi_union_pw_aff(list); + return typed::multi_union_pw_aff(res); +} + +template +template +typed::multi_union_pw_aff typed::space::multi_union_pw_aff(const typed::union_pw_aff_list &list) const +{ + auto res = isl::space::multi_union_pw_aff(list); + return typed::multi_union_pw_aff(res); +} + +template +typed::multi_val typed::space::multi_val(const typed::val_list &list) const +{ + auto res = isl::space::multi_val(list); + return typed::multi_val(res); +} + +template +typed::aff typed::space::param_aff_on_domain(const typed::id &id) const +{ + auto res = isl::space::param_aff_on_domain(id); + return typed::aff(res); +} + +template +typed::aff typed::space::param_aff_on_domain(const std::string &id) const +{ + auto res = isl::space::param_aff_on_domain(id); + return typed::aff(res); +} + +template +typed::space<> typed::space::params() const +{ + auto res = isl::space::params(); + return typed::space<>(res); +} + +template +template +typed::space> typed::space::product(const typed::space &right) const +{ + auto res = isl::space::product(right); + return typed::space>(res); +} + +template +template +typed::space typed::space::set_range_tuple(const typed::id &id) const +{ + auto res = isl::space::set_range_tuple(id); + return typed::space(res); +} + +template +template +typed::space typed::space::set_range_tuple(const std::string &id) const +{ + auto res = isl::space::set_range_tuple(id); + return typed::space(res); +} + +template +typed::set typed::space::universe_set() const +{ + auto res = isl::space::universe_set(); + return typed::set(res); +} + +template +typed::aff typed::space::zero_aff_on_domain() const +{ + auto res = isl::space::zero_aff_on_domain(); + return typed::aff(res); +} + +template +typed::multi_aff typed::space::zero_multi_aff() const +{ + auto res = isl::space::zero_multi_aff(); + return typed::multi_aff(res); +} + +template +typed::multi_pw_aff typed::space::zero_multi_pw_aff() const +{ + auto res = isl::space::zero_multi_pw_aff(); + return typed::multi_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::space::zero_multi_union_pw_aff() const +{ + auto res = isl::space::zero_multi_union_pw_aff(); + return typed::multi_union_pw_aff(res); +} + +template +typed::multi_val typed::space::zero_multi_val() const +{ + auto res = isl::space::zero_multi_val(); + return typed::multi_val(res); +} + +template +typed::space::space(const isl::ctx &ctx, const std::string &str) + : isl::space(ctx, str) +{ +} + +template +typed::space typed::space::add_param(const typed::id &id) const +{ + auto res = isl::space::add_param(id); + return typed::space(res); +} + +template +typed::space typed::space::add_param(const std::string &id) const +{ + auto res = isl::space::add_param(id); + return typed::space(res); +} + +template +typed::space typed::space::domain() const +{ + auto res = isl::space::domain(); + return typed::space(res); +} + +template +typed::multi_aff, Domain> typed::space::domain_map_multi_aff() const +{ + auto res = isl::space::domain_map_multi_aff(); + return typed::multi_aff, Domain>(res); +} + +template +typed::pw_multi_aff, Domain> typed::space::domain_map_pw_multi_aff() const +{ + auto res = isl::space::domain_map_pw_multi_aff(); + return typed::pw_multi_aff, Domain>(res); +} + +template +typed::space typed::space::drop_all_params() const +{ + auto res = isl::space::drop_all_params(); + return typed::space(res); +} + +template +typed::multi_aff typed::space::multi_aff(const typed::aff_list &list) const +{ + auto res = isl::space::multi_aff(list); + return typed::multi_aff(res); +} + +template +typed::multi_pw_aff typed::space::multi_pw_aff(const typed::pw_aff_list &list) const +{ + auto res = isl::space::multi_pw_aff(list); + return typed::multi_pw_aff(res); +} + +template +typed::space<> typed::space::params() const +{ + auto res = isl::space::params(); + return typed::space<>(res); +} + +template +template +typed::space, pair> typed::space::product(const typed::space &right) const +{ + auto res = isl::space::product(right); + return typed::space, pair>(res); +} + +template +typed::space typed::space::range() const +{ + auto res = isl::space::range(); + return typed::space(res); +} + +template +typed::multi_aff, Range> typed::space::range_map_multi_aff() const +{ + auto res = isl::space::range_map_multi_aff(); + return typed::multi_aff, Range>(res); +} + +template +typed::pw_multi_aff, Range> typed::space::range_map_pw_multi_aff() const +{ + auto res = isl::space::range_map_pw_multi_aff(); + return typed::pw_multi_aff, Range>(res); +} + +template +typed::space typed::space::reverse() const +{ + auto res = isl::space::reverse(); + return typed::space(res); +} + +template +template +typed::space typed::space::set_domain_tuple(const typed::id &id) const +{ + auto res = isl::space::set_domain_tuple(id); + return typed::space(res); +} + +template +template +typed::space typed::space::set_domain_tuple(const std::string &id) const +{ + auto res = isl::space::set_domain_tuple(id); + return typed::space(res); +} + +template +template +typed::space typed::space::set_range_tuple(const typed::id &id) const +{ + auto res = isl::space::set_range_tuple(id); + return typed::space(res); +} + +template +template +typed::space typed::space::set_range_tuple(const std::string &id) const +{ + auto res = isl::space::set_range_tuple(id); + return typed::space(res); +} + +template +typed::map typed::space::universe_map() const +{ + auto res = isl::space::universe_map(); + return typed::map(res); +} + +template +typed::space> typed::space::wrap() const +{ + auto res = isl::space::wrap(); + return typed::space>(res); +} + +template +typed::multi_aff typed::space::zero_multi_aff() const +{ + auto res = isl::space::zero_multi_aff(); + return typed::multi_aff(res); +} + +template +typed::multi_pw_aff typed::space::zero_multi_pw_aff() const +{ + auto res = isl::space::zero_multi_pw_aff(); + return typed::multi_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::space::zero_multi_union_pw_aff() const +{ + auto res = isl::space::zero_multi_union_pw_aff(); + return typed::multi_union_pw_aff(res); +} + +template +typed::space>::space(const isl::ctx &ctx, const std::string &str) + : isl::space(ctx, str) +{ +} + +template +template +typed::space, Arg2> typed::space>::add_named_tuple(const typed::id &tuple_id, unsigned int dim) const +{ + auto res = isl::space::add_named_tuple(tuple_id, dim); + return typed::space, Arg2>(res); +} + +template +template +typed::space, Arg2> typed::space>::add_named_tuple(const std::string &tuple_id, unsigned int dim) const +{ + auto res = isl::space::add_named_tuple(tuple_id, dim); + return typed::space, Arg2>(res); +} + +template +typed::space> typed::space>::add_param(const typed::id &id) const +{ + auto res = isl::space::add_param(id); + return typed::space>(res); +} + +template +typed::space> typed::space>::add_param(const std::string &id) const +{ + auto res = isl::space::add_param(id); + return typed::space>(res); +} + +template +template +typed::space, Arg2> typed::space>::add_unnamed_tuple(unsigned int dim) const +{ + auto res = isl::space::add_unnamed_tuple(dim); + return typed::space, Arg2>(res); +} + +template +typed::space<> typed::space>::domain() const +{ + auto res = isl::space::domain(); + return typed::space<>(res); +} + +template +typed::space> typed::space>::drop_all_params() const +{ + auto res = isl::space::drop_all_params(); + return typed::space>(res); +} + +template +typed::multi_aff, pair> typed::space>::identity_multi_aff_on_domain() const +{ + auto res = isl::space::identity_multi_aff_on_domain(); + return typed::multi_aff, pair>(res); +} + +template +typed::multi_pw_aff, pair> typed::space>::identity_multi_pw_aff_on_domain() const +{ + auto res = isl::space::identity_multi_pw_aff_on_domain(); + return typed::multi_pw_aff, pair>(res); +} + +template +typed::pw_multi_aff, pair> typed::space>::identity_pw_multi_aff_on_domain() const +{ + auto res = isl::space::identity_pw_multi_aff_on_domain(); + return typed::pw_multi_aff, pair>(res); +} + +template +typed::space, pair> typed::space>::map_from_set() const +{ + auto res = isl::space::map_from_set(); + return typed::space, pair>(res); +} + +template +typed::multi_aff> typed::space>::multi_aff(const typed::aff_list &list) const +{ + auto res = isl::space::multi_aff(list); + return typed::multi_aff>(res); +} + +template +template +typed::multi_aff, Arg2> typed::space>::multi_aff_on_domain(const typed::multi_val &mv) const +{ + auto res = isl::space::multi_aff_on_domain(mv); + return typed::multi_aff, Arg2>(res); +} + +template +typed::multi_id> typed::space>::multi_id(const typed::id_list &list) const +{ + auto res = isl::space::multi_id(list); + return typed::multi_id>(res); +} + +template +typed::multi_pw_aff> typed::space>::multi_pw_aff(const typed::pw_aff_list &list) const +{ + auto res = isl::space::multi_pw_aff(list); + return typed::multi_pw_aff>(res); +} + +template +typed::multi_union_pw_aff> typed::space>::multi_union_pw_aff(const typed::union_pw_aff_list &list) const +{ + auto res = isl::space::multi_union_pw_aff(list); + return typed::multi_union_pw_aff>(res); +} + +template +template +typed::multi_union_pw_aff> typed::space>::multi_union_pw_aff(const typed::union_pw_aff_list &list) const +{ + auto res = isl::space::multi_union_pw_aff(list); + return typed::multi_union_pw_aff>(res); +} + +template +typed::multi_val> typed::space>::multi_val(const typed::val_list &list) const +{ + auto res = isl::space::multi_val(list); + return typed::multi_val>(res); +} + +template +typed::aff, Anonymous> typed::space>::param_aff_on_domain(const typed::id &id) const +{ + auto res = isl::space::param_aff_on_domain(id); + return typed::aff, Anonymous>(res); +} + +template +typed::aff, Anonymous> typed::space>::param_aff_on_domain(const std::string &id) const +{ + auto res = isl::space::param_aff_on_domain(id); + return typed::aff, Anonymous>(res); +} + +template +typed::space<> typed::space>::params() const +{ + auto res = isl::space::params(); + return typed::space<>(res); +} + +template +template +typed::space, Arg2>> typed::space>::product(const typed::space &right) const +{ + auto res = isl::space::product(right); + return typed::space, Arg2>>(res); +} + +template +typed::set> typed::space>::universe_set() const +{ + auto res = isl::space::universe_set(); + return typed::set>(res); +} + +template +typed::space typed::space>::unwrap() const +{ + auto res = isl::space::unwrap(); + return typed::space(res); +} + +template +typed::space> typed::space>::wrapped_reverse() const +{ + auto res = isl::space::wrapped_reverse(); + return typed::space>(res); +} + +template +typed::aff, Anonymous> typed::space>::zero_aff_on_domain() const +{ + auto res = isl::space::zero_aff_on_domain(); + return typed::aff, Anonymous>(res); +} + +template +typed::multi_aff> typed::space>::zero_multi_aff() const +{ + auto res = isl::space::zero_multi_aff(); + return typed::multi_aff>(res); +} + +template +typed::multi_pw_aff> typed::space>::zero_multi_pw_aff() const +{ + auto res = isl::space::zero_multi_pw_aff(); + return typed::multi_pw_aff>(res); +} + +template +typed::multi_union_pw_aff> typed::space>::zero_multi_union_pw_aff() const +{ + auto res = isl::space::zero_multi_union_pw_aff(); + return typed::multi_union_pw_aff>(res); +} + +template +typed::multi_val> typed::space>::zero_multi_val() const +{ + auto res = isl::space::zero_multi_val(); + return typed::multi_val>(res); +} + +template +typed::space, Range2>::space(const isl::ctx &ctx, const std::string &str) + : isl::space(ctx, str) +{ +} + +template +typed::space, Range2> typed::space, Range2>::add_param(const typed::id &id) const +{ + auto res = isl::space::add_param(id); + return typed::space, Range2>(res); +} + +template +typed::space, Range2> typed::space, Range2>::add_param(const std::string &id) const +{ + auto res = isl::space::add_param(id); + return typed::space, Range2>(res); +} + +template +typed::space> typed::space, Range2>::curry() const +{ + auto res = isl::space::curry(); + return typed::space>(res); +} + +template +typed::space> typed::space, Range2>::domain() const +{ + auto res = isl::space::domain(); + return typed::space>(res); +} + +template +typed::multi_aff, Range2>, pair> typed::space, Range2>::domain_map_multi_aff() const +{ + auto res = isl::space::domain_map_multi_aff(); + return typed::multi_aff, Range2>, pair>(res); +} + +template +typed::pw_multi_aff, Range2>, pair> typed::space, Range2>::domain_map_pw_multi_aff() const +{ + auto res = isl::space::domain_map_pw_multi_aff(); + return typed::pw_multi_aff, Range2>, pair>(res); +} + +template +typed::space, Range2> typed::space, Range2>::domain_reverse() const +{ + auto res = isl::space::domain_reverse(); + return typed::space, Range2>(res); +} + +template +typed::space, Range2> typed::space, Range2>::drop_all_params() const +{ + auto res = isl::space::drop_all_params(); + return typed::space, Range2>(res); +} + +template +typed::space typed::space, Range2>::flatten_domain() const +{ + auto res = isl::space::flatten_domain(); + return typed::space(res); +} + +template +typed::multi_aff, Range2> typed::space, Range2>::multi_aff(const typed::aff_list, Anonymous> &list) const +{ + auto res = isl::space::multi_aff(list); + return typed::multi_aff, Range2>(res); +} + +template +typed::multi_pw_aff, Range2> typed::space, Range2>::multi_pw_aff(const typed::pw_aff_list, Anonymous> &list) const +{ + auto res = isl::space::multi_pw_aff(list); + return typed::multi_pw_aff, Range2>(res); +} + +template +typed::space<> typed::space, Range2>::params() const +{ + auto res = isl::space::params(); + return typed::space<>(res); +} + +template +template +typed::space, Domain2>, pair> typed::space, Range2>::product(const typed::space &right) const +{ + auto res = isl::space::product(right); + return typed::space, Domain2>, pair>(res); +} + +template +typed::space typed::space, Range2>::range() const +{ + auto res = isl::space::range(); + return typed::space(res); +} + +template +typed::multi_aff, Range2>, Range2> typed::space, Range2>::range_map_multi_aff() const +{ + auto res = isl::space::range_map_multi_aff(); + return typed::multi_aff, Range2>, Range2>(res); +} + +template +typed::pw_multi_aff, Range2>, Range2> typed::space, Range2>::range_map_pw_multi_aff() const +{ + auto res = isl::space::range_map_pw_multi_aff(); + return typed::pw_multi_aff, Range2>, Range2>(res); +} + +template +typed::space> typed::space, Range2>::reverse() const +{ + auto res = isl::space::reverse(); + return typed::space>(res); +} + +template +template +typed::space, Arg2> typed::space, Range2>::set_range_tuple(const typed::id &id) const +{ + auto res = isl::space::set_range_tuple(id); + return typed::space, Arg2>(res); +} + +template +template +typed::space, Arg2> typed::space, Range2>::set_range_tuple(const std::string &id) const +{ + auto res = isl::space::set_range_tuple(id); + return typed::space, Arg2>(res); +} + +template +typed::map, Range2> typed::space, Range2>::universe_map() const +{ + auto res = isl::space::universe_map(); + return typed::map, Range2>(res); +} + +template +typed::space, Range2>> typed::space, Range2>::wrap() const +{ + auto res = isl::space::wrap(); + return typed::space, Range2>>(res); +} + +template +typed::multi_aff, Range2> typed::space, Range2>::zero_multi_aff() const +{ + auto res = isl::space::zero_multi_aff(); + return typed::multi_aff, Range2>(res); +} + +template +typed::multi_pw_aff, Range2> typed::space, Range2>::zero_multi_pw_aff() const +{ + auto res = isl::space::zero_multi_pw_aff(); + return typed::multi_pw_aff, Range2>(res); +} + +template +typed::multi_union_pw_aff, Range2> typed::space, Range2>::zero_multi_union_pw_aff() const +{ + auto res = isl::space::zero_multi_union_pw_aff(); + return typed::multi_union_pw_aff, Range2>(res); +} + +template +typed::space>::space(const isl::ctx &ctx, const std::string &str) + : isl::space(ctx, str) +{ +} + +template +typed::space> typed::space>::add_param(const typed::id &id) const +{ + auto res = isl::space::add_param(id); + return typed::space>(res); +} + +template +typed::space> typed::space>::add_param(const std::string &id) const +{ + auto res = isl::space::add_param(id); + return typed::space>(res); +} + +template +typed::space typed::space>::domain() const +{ + auto res = isl::space::domain(); + return typed::space(res); +} + +template +typed::multi_aff>, Domain> typed::space>::domain_map_multi_aff() const +{ + auto res = isl::space::domain_map_multi_aff(); + return typed::multi_aff>, Domain>(res); +} + +template +typed::pw_multi_aff>, Domain> typed::space>::domain_map_pw_multi_aff() const +{ + auto res = isl::space::domain_map_pw_multi_aff(); + return typed::pw_multi_aff>, Domain>(res); +} + +template +typed::space> typed::space>::drop_all_params() const +{ + auto res = isl::space::drop_all_params(); + return typed::space>(res); +} + +template +typed::space typed::space>::flatten_range() const +{ + auto res = isl::space::flatten_range(); + return typed::space(res); +} + +template +typed::multi_aff> typed::space>::multi_aff(const typed::aff_list &list) const +{ + auto res = isl::space::multi_aff(list); + return typed::multi_aff>(res); +} + +template +typed::multi_pw_aff> typed::space>::multi_pw_aff(const typed::pw_aff_list &list) const +{ + auto res = isl::space::multi_pw_aff(list); + return typed::multi_pw_aff>(res); +} + +template +typed::space<> typed::space>::params() const +{ + auto res = isl::space::params(); + return typed::space<>(res); +} + +template +template +typed::space, pair, Arg3>> typed::space>::product(const typed::space &right) const +{ + auto res = isl::space::product(right); + return typed::space, pair, Arg3>>(res); +} + +template +typed::space> typed::space>::range() const +{ + auto res = isl::space::range(); + return typed::space>(res); +} + +template +typed::multi_aff>, pair> typed::space>::range_map_multi_aff() const +{ + auto res = isl::space::range_map_multi_aff(); + return typed::multi_aff>, pair>(res); +} + +template +typed::pw_multi_aff>, pair> typed::space>::range_map_pw_multi_aff() const +{ + auto res = isl::space::range_map_pw_multi_aff(); + return typed::pw_multi_aff>, pair>(res); +} + +template +typed::space> typed::space>::range_reverse() const +{ + auto res = isl::space::range_reverse(); + return typed::space>(res); +} + +template +typed::space, Domain> typed::space>::reverse() const +{ + auto res = isl::space::reverse(); + return typed::space, Domain>(res); +} + +template +template +typed::space> typed::space>::set_domain_tuple(const typed::id &id) const +{ + auto res = isl::space::set_domain_tuple(id); + return typed::space>(res); +} + +template +template +typed::space> typed::space>::set_domain_tuple(const std::string &id) const +{ + auto res = isl::space::set_domain_tuple(id); + return typed::space>(res); +} + +template +typed::space, Range2> typed::space>::uncurry() const +{ + auto res = isl::space::uncurry(); + return typed::space, Range2>(res); +} + +template +typed::map> typed::space>::universe_map() const +{ + auto res = isl::space::universe_map(); + return typed::map>(res); +} + +template +typed::space>> typed::space>::wrap() const +{ + auto res = isl::space::wrap(); + return typed::space>>(res); +} + +template +typed::multi_aff> typed::space>::zero_multi_aff() const +{ + auto res = isl::space::zero_multi_aff(); + return typed::multi_aff>(res); +} + +template +typed::multi_pw_aff> typed::space>::zero_multi_pw_aff() const +{ + auto res = isl::space::zero_multi_pw_aff(); + return typed::multi_pw_aff>(res); +} + +template +typed::multi_union_pw_aff> typed::space>::zero_multi_union_pw_aff() const +{ + auto res = isl::space::zero_multi_union_pw_aff(); + return typed::multi_union_pw_aff>(res); +} + +template +typed::space, pair>::space(const isl::ctx &ctx, const std::string &str) + : isl::space(ctx, str) +{ +} + +template +typed::space, pair> typed::space, pair>::add_param(const typed::id &id) const +{ + auto res = isl::space::add_param(id); + return typed::space, pair>(res); +} + +template +typed::space, pair> typed::space, pair>::add_param(const std::string &id) const +{ + auto res = isl::space::add_param(id); + return typed::space, pair>(res); +} + +template +typed::space>> typed::space, pair>::curry() const +{ + auto res = isl::space::curry(); + return typed::space>>(res); +} + +template +typed::space> typed::space, pair>::domain() const +{ + auto res = isl::space::domain(); + return typed::space>(res); +} + +template +typed::multi_aff, pair>, pair> typed::space, pair>::domain_map_multi_aff() const +{ + auto res = isl::space::domain_map_multi_aff(); + return typed::multi_aff, pair>, pair>(res); +} + +template +typed::pw_multi_aff, pair>, pair> typed::space, pair>::domain_map_pw_multi_aff() const +{ + auto res = isl::space::domain_map_pw_multi_aff(); + return typed::pw_multi_aff, pair>, pair>(res); +} + +template +typed::space, pair> typed::space, pair>::domain_reverse() const +{ + auto res = isl::space::domain_reverse(); + return typed::space, pair>(res); +} + +template +typed::space, pair> typed::space, pair>::drop_all_params() const +{ + auto res = isl::space::drop_all_params(); + return typed::space, pair>(res); +} + +template +typed::space> typed::space, pair>::flatten_domain() const +{ + auto res = isl::space::flatten_domain(); + return typed::space>(res); +} + +template +typed::space, Anonymous> typed::space, pair>::flatten_range() const +{ + auto res = isl::space::flatten_range(); + return typed::space, Anonymous>(res); +} + +template +typed::multi_aff, pair> typed::space, pair>::multi_aff(const typed::aff_list, Anonymous> &list) const +{ + auto res = isl::space::multi_aff(list); + return typed::multi_aff, pair>(res); +} + +template +typed::multi_pw_aff, pair> typed::space, pair>::multi_pw_aff(const typed::pw_aff_list, Anonymous> &list) const +{ + auto res = isl::space::multi_pw_aff(list); + return typed::multi_pw_aff, pair>(res); +} + +template +typed::space<> typed::space, pair>::params() const +{ + auto res = isl::space::params(); + return typed::space<>(res); +} + +template +template +typed::space, Domain2>, pair, Arg2>> typed::space, pair>::product(const typed::space &right) const +{ + auto res = isl::space::product(right); + return typed::space, Domain2>, pair, Arg2>>(res); +} + +template +typed::space> typed::space, pair>::range() const +{ + auto res = isl::space::range(); + return typed::space>(res); +} + +template +typed::multi_aff, pair>, pair> typed::space, pair>::range_map_multi_aff() const +{ + auto res = isl::space::range_map_multi_aff(); + return typed::multi_aff, pair>, pair>(res); +} + +template +typed::pw_multi_aff, pair>, pair> typed::space, pair>::range_map_pw_multi_aff() const +{ + auto res = isl::space::range_map_pw_multi_aff(); + return typed::pw_multi_aff, pair>, pair>(res); +} + +template +typed::space, pair> typed::space, pair>::range_reverse() const +{ + auto res = isl::space::range_reverse(); + return typed::space, pair>(res); +} + +template +typed::space, pair> typed::space, pair>::reverse() const +{ + auto res = isl::space::reverse(); + return typed::space, pair>(res); +} + +template +typed::space, Range>, Range2> typed::space, pair>::uncurry() const +{ + auto res = isl::space::uncurry(); + return typed::space, Range>, Range2>(res); +} + +template +typed::map, pair> typed::space, pair>::universe_map() const +{ + auto res = isl::space::universe_map(); + return typed::map, pair>(res); +} + +template +typed::space, pair>> typed::space, pair>::wrap() const +{ + auto res = isl::space::wrap(); + return typed::space, pair>>(res); +} + +template +typed::multi_aff, pair> typed::space, pair>::zero_multi_aff() const +{ + auto res = isl::space::zero_multi_aff(); + return typed::multi_aff, pair>(res); +} + +template +typed::multi_pw_aff, pair> typed::space, pair>::zero_multi_pw_aff() const +{ + auto res = isl::space::zero_multi_pw_aff(); + return typed::multi_pw_aff, pair>(res); +} + +template +typed::multi_union_pw_aff, pair> typed::space, pair>::zero_multi_union_pw_aff() const +{ + auto res = isl::space::zero_multi_union_pw_aff(); + return typed::multi_union_pw_aff, pair>(res); +} + +template +typed::union_map::union_map(const typed::basic_map &bmap) + : isl::union_map(bmap) +{ +} + +template +typed::union_map::union_map(const typed::map &map) + : isl::union_map(map) +{ +} + +template +typed::union_map::union_map(const isl::ctx &ctx, const std::string &str) + : isl::union_map(ctx, str) +{ +} + +template +template +typed::union_map typed::union_map::apply_domain(const typed::union_map &umap2) const +{ + auto res = isl::union_map::apply_domain(umap2); + return typed::union_map(res); +} + +template +template +typed::union_map typed::union_map::apply_domain(const typed::basic_map &umap2) const +{ + auto res = isl::union_map::apply_domain(umap2); + return typed::union_map(res); +} + +template +template +typed::union_map typed::union_map::apply_domain(const typed::map &umap2) const +{ + auto res = isl::union_map::apply_domain(umap2); + return typed::union_map(res); +} + +template +template +typed::union_map typed::union_map::apply_range(const typed::union_map &umap2) const +{ + auto res = isl::union_map::apply_range(umap2); + return typed::union_map(res); +} + +template +template +typed::union_map typed::union_map::apply_range(const typed::basic_map &umap2) const +{ + auto res = isl::union_map::apply_range(umap2); + return typed::union_map(res); +} + +template +template +typed::union_map typed::union_map::apply_range(const typed::map &umap2) const +{ + auto res = isl::union_map::apply_range(umap2); + return typed::union_map(res); +} + +template +typed::map typed::union_map::as_map() const +{ + auto res = isl::union_map::as_map(); + return typed::map(res); +} + +template +typed::multi_union_pw_aff typed::union_map::as_multi_union_pw_aff() const +{ + auto res = isl::union_map::as_multi_union_pw_aff(); + return typed::multi_union_pw_aff(res); +} + +template +typed::union_pw_multi_aff typed::union_map::as_union_pw_multi_aff() const +{ + auto res = isl::union_map::as_union_pw_multi_aff(); + return typed::union_pw_multi_aff(res); +} + +template +typed::union_set typed::union_map::bind_range(const typed::multi_id &tuple) const +{ + auto res = isl::union_map::bind_range(tuple); + return typed::union_set(res); +} + +template +typed::union_map typed::union_map::coalesce() const +{ + auto res = isl::union_map::coalesce(); + return typed::union_map(res); +} + +template +typed::union_map typed::union_map::detect_equalities() const +{ + auto res = isl::union_map::detect_equalities(); + return typed::union_map(res); +} + +template +typed::union_set typed::union_map::domain() const +{ + auto res = isl::union_map::domain(); + return typed::union_set(res); +} + +template +typed::union_map, Domain> typed::union_map::domain_map() const +{ + auto res = isl::union_map::domain_map(); + return typed::union_map, Domain>(res); +} + +template +typed::union_pw_multi_aff, Domain> typed::union_map::domain_map_union_pw_multi_aff() const +{ + auto res = isl::union_map::domain_map_union_pw_multi_aff(); + return typed::union_pw_multi_aff, Domain>(res); +} + +template +template +typed::union_map, Range> typed::union_map::domain_product(const typed::union_map &umap2) const +{ + auto res = isl::union_map::domain_product(umap2); + return typed::union_map, Range>(res); +} + +template +template +typed::union_map, Range> typed::union_map::domain_product(const typed::basic_map &umap2) const +{ + auto res = isl::union_map::domain_product(umap2); + return typed::union_map, Range>(res); +} + +template +template +typed::union_map, Range> typed::union_map::domain_product(const typed::map &umap2) const +{ + auto res = isl::union_map::domain_product(umap2); + return typed::union_map, Range>(res); +} + +template +typed::union_map typed::union_map::drop_unused_params() const +{ + auto res = isl::union_map::drop_unused_params(); + return typed::union_map(res); +} + +template +typed::union_map typed::union_map::empty(const isl::ctx &ctx) +{ + auto res = isl::union_map::empty(ctx); + return typed::union_map(res); +} + +template +bool typed::union_map::every_map(const std::function)> &test) const +{ + auto lambda_test = [&] (isl::map arg0) { + return test(typed::map(arg0)); + }; + return isl::union_map::every_map(lambda_test); +} + +template +typed::map typed::union_map::extract_map(const typed::space &space) const +{ + auto res = isl::union_map::extract_map(space); + return typed::map(res); +} + +template +void typed::union_map::foreach_map(const std::function)> &fn) const +{ + auto lambda_fn = [&] (isl::map arg0) { + return fn(typed::map(arg0)); + }; + return isl::union_map::foreach_map(lambda_fn); +} + +template +typed::union_map typed::union_map::gist(const typed::union_map &context) const +{ + auto res = isl::union_map::gist(context); + return typed::union_map(res); +} + +template +typed::union_map typed::union_map::gist(const typed::basic_map &context) const +{ + auto res = isl::union_map::gist(context); + return typed::union_map(res); +} + +template +typed::union_map typed::union_map::gist(const typed::map &context) const +{ + auto res = isl::union_map::gist(context); + return typed::union_map(res); +} + +template +typed::union_map typed::union_map::gist_domain(const typed::union_set &uset) const +{ + auto res = isl::union_map::gist_domain(uset); + return typed::union_map(res); +} + +template +typed::union_map typed::union_map::gist_domain(const typed::basic_set &uset) const +{ + auto res = isl::union_map::gist_domain(uset); + return typed::union_map(res); +} + +template +typed::union_map typed::union_map::gist_domain(const typed::point &uset) const +{ + auto res = isl::union_map::gist_domain(uset); + return typed::union_map(res); +} + +template +typed::union_map typed::union_map::gist_domain(const typed::set &uset) const +{ + auto res = isl::union_map::gist_domain(uset); + return typed::union_map(res); +} + +template +typed::union_map typed::union_map::gist_params(const typed::set<> &set) const +{ + auto res = isl::union_map::gist_params(set); + return typed::union_map(res); +} + +template +typed::union_map typed::union_map::gist_params(const typed::basic_set<> &set) const +{ + auto res = isl::union_map::gist_params(set); + return typed::union_map(res); +} + +template +typed::union_map typed::union_map::gist_params(const typed::point<> &set) const +{ + auto res = isl::union_map::gist_params(set); + return typed::union_map(res); +} + +template +typed::union_map typed::union_map::intersect(const typed::union_map &umap2) const +{ + auto res = isl::union_map::intersect(umap2); + return typed::union_map(res); +} + +template +typed::union_map typed::union_map::intersect(const typed::basic_map &umap2) const +{ + auto res = isl::union_map::intersect(umap2); + return typed::union_map(res); +} + +template +typed::union_map typed::union_map::intersect(const typed::map &umap2) const +{ + auto res = isl::union_map::intersect(umap2); + return typed::union_map(res); +} + +template +typed::union_map typed::union_map::intersect_domain(const typed::space &space) const +{ + auto res = isl::union_map::intersect_domain(space); + return typed::union_map(res); +} + +template +typed::union_map typed::union_map::intersect_domain(const typed::union_set &uset) const +{ + auto res = isl::union_map::intersect_domain(uset); + return typed::union_map(res); +} + +template +typed::union_map typed::union_map::intersect_params(const typed::set<> &set) const +{ + auto res = isl::union_map::intersect_params(set); + return typed::union_map(res); +} + +template +typed::union_map typed::union_map::intersect_params(const typed::basic_set<> &set) const +{ + auto res = isl::union_map::intersect_params(set); + return typed::union_map(res); +} + +template +typed::union_map typed::union_map::intersect_params(const typed::point<> &set) const +{ + auto res = isl::union_map::intersect_params(set); + return typed::union_map(res); +} + +template +typed::union_map typed::union_map::intersect_range(const typed::space &space) const +{ + auto res = isl::union_map::intersect_range(space); + return typed::union_map(res); +} + +template +typed::union_map typed::union_map::intersect_range(const typed::union_set &uset) const +{ + auto res = isl::union_map::intersect_range(uset); + return typed::union_map(res); +} + +template +typed::union_map typed::union_map::lexmax() const +{ + auto res = isl::union_map::lexmax(); + return typed::union_map(res); +} + +template +typed::union_map typed::union_map::lexmin() const +{ + auto res = isl::union_map::lexmin(); + return typed::union_map(res); +} + +template +typed::map_list typed::union_map::map_list() const +{ + auto res = isl::union_map::map_list(); + return typed::map_list(res); +} + +template +typed::set<> typed::union_map::params() const +{ + auto res = isl::union_map::params(); + return typed::set<>(res); +} + +template +template +typed::union_map typed::union_map::preimage_domain(const typed::multi_aff &ma) const +{ + auto res = isl::union_map::preimage_domain(ma); + return typed::union_map(res); +} + +template +template +typed::union_map typed::union_map::preimage_domain(const typed::multi_pw_aff &mpa) const +{ + auto res = isl::union_map::preimage_domain(mpa); + return typed::union_map(res); +} + +template +template +typed::union_map typed::union_map::preimage_domain(const typed::pw_multi_aff &pma) const +{ + auto res = isl::union_map::preimage_domain(pma); + return typed::union_map(res); +} + +template +template +typed::union_map typed::union_map::preimage_domain(const typed::union_pw_multi_aff &upma) const +{ + auto res = isl::union_map::preimage_domain(upma); + return typed::union_map(res); +} + +template +template +typed::union_map typed::union_map::preimage_range(const typed::multi_aff &ma) const +{ + auto res = isl::union_map::preimage_range(ma); + return typed::union_map(res); +} + +template +template +typed::union_map typed::union_map::preimage_range(const typed::pw_multi_aff &pma) const +{ + auto res = isl::union_map::preimage_range(pma); + return typed::union_map(res); +} + +template +template +typed::union_map typed::union_map::preimage_range(const typed::union_pw_multi_aff &upma) const +{ + auto res = isl::union_map::preimage_range(upma); + return typed::union_map(res); +} + +template +template +typed::union_map, pair> typed::union_map::product(const typed::union_map &umap2) const +{ + auto res = isl::union_map::product(umap2); + return typed::union_map, pair>(res); +} + +template +template +typed::union_map, pair> typed::union_map::product(const typed::basic_map &umap2) const +{ + auto res = isl::union_map::product(umap2); + return typed::union_map, pair>(res); +} + +template +template +typed::union_map, pair> typed::union_map::product(const typed::map &umap2) const +{ + auto res = isl::union_map::product(umap2); + return typed::union_map, pair>(res); +} + +template +typed::union_map typed::union_map::project_out_all_params() const +{ + auto res = isl::union_map::project_out_all_params(); + return typed::union_map(res); +} + +template +typed::union_map typed::union_map::project_out_param(const typed::id &id) const +{ + auto res = isl::union_map::project_out_param(id); + return typed::union_map(res); +} + +template +typed::union_map typed::union_map::project_out_param(const std::string &id) const +{ + auto res = isl::union_map::project_out_param(id); + return typed::union_map(res); +} + +template +typed::union_map typed::union_map::project_out_param(const typed::id_list &list) const +{ + auto res = isl::union_map::project_out_param(list); + return typed::union_map(res); +} + +template +typed::union_set typed::union_map::range() const +{ + auto res = isl::union_map::range(); + return typed::union_set(res); +} + +template +typed::union_map, Range> typed::union_map::range_map() const +{ + auto res = isl::union_map::range_map(); + return typed::union_map, Range>(res); +} + +template +template +typed::union_map> typed::union_map::range_product(const typed::union_map &umap2) const +{ + auto res = isl::union_map::range_product(umap2); + return typed::union_map>(res); +} + +template +template +typed::union_map> typed::union_map::range_product(const typed::basic_map &umap2) const +{ + auto res = isl::union_map::range_product(umap2); + return typed::union_map>(res); +} + +template +template +typed::union_map> typed::union_map::range_product(const typed::map &umap2) const +{ + auto res = isl::union_map::range_product(umap2); + return typed::union_map>(res); +} + +template +typed::union_map typed::union_map::reverse() const +{ + auto res = isl::union_map::reverse(); + return typed::union_map(res); +} + +template +typed::space<> typed::union_map::space() const +{ + auto res = isl::union_map::space(); + return typed::space<>(res); +} + +template +typed::union_map typed::union_map::subtract(const typed::union_map &umap2) const +{ + auto res = isl::union_map::subtract(umap2); + return typed::union_map(res); +} + +template +typed::union_map typed::union_map::subtract(const typed::basic_map &umap2) const +{ + auto res = isl::union_map::subtract(umap2); + return typed::union_map(res); +} + +template +typed::union_map typed::union_map::subtract(const typed::map &umap2) const +{ + auto res = isl::union_map::subtract(umap2); + return typed::union_map(res); +} + +template +typed::union_map typed::union_map::subtract_domain(const typed::union_set &dom) const +{ + auto res = isl::union_map::subtract_domain(dom); + return typed::union_map(res); +} + +template +typed::union_map typed::union_map::subtract_domain(const typed::basic_set &dom) const +{ + auto res = isl::union_map::subtract_domain(dom); + return typed::union_map(res); +} + +template +typed::union_map typed::union_map::subtract_domain(const typed::point &dom) const +{ + auto res = isl::union_map::subtract_domain(dom); + return typed::union_map(res); +} + +template +typed::union_map typed::union_map::subtract_domain(const typed::set &dom) const +{ + auto res = isl::union_map::subtract_domain(dom); + return typed::union_map(res); +} + +template +typed::union_map typed::union_map::subtract_range(const typed::union_set &dom) const +{ + auto res = isl::union_map::subtract_range(dom); + return typed::union_map(res); +} + +template +typed::union_map typed::union_map::subtract_range(const typed::basic_set &dom) const +{ + auto res = isl::union_map::subtract_range(dom); + return typed::union_map(res); +} + +template +typed::union_map typed::union_map::subtract_range(const typed::point &dom) const +{ + auto res = isl::union_map::subtract_range(dom); + return typed::union_map(res); +} + +template +typed::union_map typed::union_map::subtract_range(const typed::set &dom) const +{ + auto res = isl::union_map::subtract_range(dom); + return typed::union_map(res); +} + +template +typed::union_map typed::union_map::unite(const typed::union_map &umap2) const +{ + auto res = isl::union_map::unite(umap2); + return typed::union_map(res); +} + +template +typed::union_map typed::union_map::unite(const typed::basic_map &umap2) const +{ + auto res = isl::union_map::unite(umap2); + return typed::union_map(res); +} + +template +typed::union_map typed::union_map::unite(const typed::map &umap2) const +{ + auto res = isl::union_map::unite(umap2); + return typed::union_map(res); +} + +template +typed::union_map typed::union_map::universe() const +{ + auto res = isl::union_map::universe(); + return typed::union_map(res); +} + +template +typed::union_set> typed::union_map::wrap() const +{ + auto res = isl::union_map::wrap(); + return typed::union_set>(res); +} + +template +typed::union_map, Range2>::union_map(const typed::basic_map, Range2> &bmap) + : isl::union_map(bmap) +{ +} + +template +typed::union_map, Range2>::union_map(const typed::map, Range2> &map) + : isl::union_map(map) +{ +} + +template +typed::union_map, Range2>::union_map(const isl::ctx &ctx, const std::string &str) + : isl::union_map(ctx, str) +{ +} + +template +template +typed::union_map typed::union_map, Range2>::apply_domain(const typed::union_map, Domain2> &umap2) const +{ + auto res = isl::union_map::apply_domain(umap2); + return typed::union_map(res); +} + +template +template +typed::union_map typed::union_map, Range2>::apply_domain(const typed::basic_map, Domain2> &umap2) const +{ + auto res = isl::union_map::apply_domain(umap2); + return typed::union_map(res); +} + +template +template +typed::union_map typed::union_map, Range2>::apply_domain(const typed::map, Domain2> &umap2) const +{ + auto res = isl::union_map::apply_domain(umap2); + return typed::union_map(res); +} + +template +template +typed::union_map, Arg3> typed::union_map, Range2>::apply_range(const typed::union_map &umap2) const +{ + auto res = isl::union_map::apply_range(umap2); + return typed::union_map, Arg3>(res); +} + +template +template +typed::union_map, Arg3> typed::union_map, Range2>::apply_range(const typed::basic_map &umap2) const +{ + auto res = isl::union_map::apply_range(umap2); + return typed::union_map, Arg3>(res); +} + +template +template +typed::union_map, Arg3> typed::union_map, Range2>::apply_range(const typed::map &umap2) const +{ + auto res = isl::union_map::apply_range(umap2); + return typed::union_map, Arg3>(res); +} + +template +typed::map, Range2> typed::union_map, Range2>::as_map() const +{ + auto res = isl::union_map::as_map(); + return typed::map, Range2>(res); +} + +template +typed::multi_union_pw_aff, Range2> typed::union_map, Range2>::as_multi_union_pw_aff() const +{ + auto res = isl::union_map::as_multi_union_pw_aff(); + return typed::multi_union_pw_aff, Range2>(res); +} + +template +typed::union_pw_multi_aff, Range2> typed::union_map, Range2>::as_union_pw_multi_aff() const +{ + auto res = isl::union_map::as_union_pw_multi_aff(); + return typed::union_pw_multi_aff, Range2>(res); +} + +template +typed::union_set> typed::union_map, Range2>::bind_range(const typed::multi_id &tuple) const +{ + auto res = isl::union_map::bind_range(tuple); + return typed::union_set>(res); +} + +template +typed::union_map, Range2> typed::union_map, Range2>::coalesce() const +{ + auto res = isl::union_map::coalesce(); + return typed::union_map, Range2>(res); +} + +template +typed::union_map> typed::union_map, Range2>::curry() const +{ + auto res = isl::union_map::curry(); + return typed::union_map>(res); +} + +template +typed::union_map, Range2> typed::union_map, Range2>::detect_equalities() const +{ + auto res = isl::union_map::detect_equalities(); + return typed::union_map, Range2>(res); +} + +template +typed::union_set> typed::union_map, Range2>::domain() const +{ + auto res = isl::union_map::domain(); + return typed::union_set>(res); +} + +template +typed::union_map typed::union_map, Range2>::domain_factor_domain() const +{ + auto res = isl::union_map::domain_factor_domain(); + return typed::union_map(res); +} + +template +typed::union_map typed::union_map, Range2>::domain_factor_range() const +{ + auto res = isl::union_map::domain_factor_range(); + return typed::union_map(res); +} + +template +typed::union_map, Range2>, pair> typed::union_map, Range2>::domain_map() const +{ + auto res = isl::union_map::domain_map(); + return typed::union_map, Range2>, pair>(res); +} + +template +typed::union_pw_multi_aff, Range2>, pair> typed::union_map, Range2>::domain_map_union_pw_multi_aff() const +{ + auto res = isl::union_map::domain_map_union_pw_multi_aff(); + return typed::union_pw_multi_aff, Range2>, pair>(res); +} + +template +template +typed::union_map, Domain2>, Range2> typed::union_map, Range2>::domain_product(const typed::union_map &umap2) const +{ + auto res = isl::union_map::domain_product(umap2); + return typed::union_map, Domain2>, Range2>(res); +} + +template +template +typed::union_map, Domain2>, Range2> typed::union_map, Range2>::domain_product(const typed::basic_map &umap2) const +{ + auto res = isl::union_map::domain_product(umap2); + return typed::union_map, Domain2>, Range2>(res); +} + +template +template +typed::union_map, Domain2>, Range2> typed::union_map, Range2>::domain_product(const typed::map &umap2) const +{ + auto res = isl::union_map::domain_product(umap2); + return typed::union_map, Domain2>, Range2>(res); +} + +template +typed::union_map, Range2> typed::union_map, Range2>::domain_reverse() const +{ + auto res = isl::union_map::domain_reverse(); + return typed::union_map, Range2>(res); +} + +template +typed::union_map, Range2> typed::union_map, Range2>::drop_unused_params() const +{ + auto res = isl::union_map::drop_unused_params(); + return typed::union_map, Range2>(res); +} + +template +typed::union_map, Range2> typed::union_map, Range2>::empty(const isl::ctx &ctx) +{ + auto res = isl::union_map::empty(ctx); + return typed::union_map, Range2>(res); +} + +template +bool typed::union_map, Range2>::every_map(const std::function, Range2>)> &test) const +{ + auto lambda_test = [&] (isl::map arg0) { + return test(typed::map, Range2>(arg0)); + }; + return isl::union_map::every_map(lambda_test); +} + +template +typed::map, Range2> typed::union_map, Range2>::extract_map(const typed::space, Range2> &space) const +{ + auto res = isl::union_map::extract_map(space); + return typed::map, Range2>(res); +} + +template +void typed::union_map, Range2>::foreach_map(const std::function, Range2>)> &fn) const +{ + auto lambda_fn = [&] (isl::map arg0) { + return fn(typed::map, Range2>(arg0)); + }; + return isl::union_map::foreach_map(lambda_fn); +} + +template +typed::union_map, Range2> typed::union_map, Range2>::gist(const typed::union_map, Range2> &context) const +{ + auto res = isl::union_map::gist(context); + return typed::union_map, Range2>(res); +} + +template +typed::union_map, Range2> typed::union_map, Range2>::gist(const typed::basic_map, Range2> &context) const +{ + auto res = isl::union_map::gist(context); + return typed::union_map, Range2>(res); +} + +template +typed::union_map, Range2> typed::union_map, Range2>::gist(const typed::map, Range2> &context) const +{ + auto res = isl::union_map::gist(context); + return typed::union_map, Range2>(res); +} + +template +typed::union_map, Range2> typed::union_map, Range2>::gist_domain(const typed::union_set> &uset) const +{ + auto res = isl::union_map::gist_domain(uset); + return typed::union_map, Range2>(res); +} + +template +typed::union_map, Range2> typed::union_map, Range2>::gist_domain(const typed::basic_set> &uset) const +{ + auto res = isl::union_map::gist_domain(uset); + return typed::union_map, Range2>(res); +} + +template +typed::union_map, Range2> typed::union_map, Range2>::gist_domain(const typed::point> &uset) const +{ + auto res = isl::union_map::gist_domain(uset); + return typed::union_map, Range2>(res); +} + +template +typed::union_map, Range2> typed::union_map, Range2>::gist_domain(const typed::set> &uset) const +{ + auto res = isl::union_map::gist_domain(uset); + return typed::union_map, Range2>(res); +} + +template +typed::union_map, Range2> typed::union_map, Range2>::gist_params(const typed::set<> &set) const +{ + auto res = isl::union_map::gist_params(set); + return typed::union_map, Range2>(res); +} + +template +typed::union_map, Range2> typed::union_map, Range2>::gist_params(const typed::basic_set<> &set) const +{ + auto res = isl::union_map::gist_params(set); + return typed::union_map, Range2>(res); +} + +template +typed::union_map, Range2> typed::union_map, Range2>::gist_params(const typed::point<> &set) const +{ + auto res = isl::union_map::gist_params(set); + return typed::union_map, Range2>(res); +} + +template +typed::union_map, Range2> typed::union_map, Range2>::intersect(const typed::union_map, Range2> &umap2) const +{ + auto res = isl::union_map::intersect(umap2); + return typed::union_map, Range2>(res); +} + +template +typed::union_map, Range2> typed::union_map, Range2>::intersect(const typed::basic_map, Range2> &umap2) const +{ + auto res = isl::union_map::intersect(umap2); + return typed::union_map, Range2>(res); +} + +template +typed::union_map, Range2> typed::union_map, Range2>::intersect(const typed::map, Range2> &umap2) const +{ + auto res = isl::union_map::intersect(umap2); + return typed::union_map, Range2>(res); +} + +template +typed::union_map, Range2> typed::union_map, Range2>::intersect_domain(const typed::space> &space) const +{ + auto res = isl::union_map::intersect_domain(space); + return typed::union_map, Range2>(res); +} + +template +typed::union_map, Range2> typed::union_map, Range2>::intersect_domain(const typed::union_set> &uset) const +{ + auto res = isl::union_map::intersect_domain(uset); + return typed::union_map, Range2>(res); +} + +template +typed::union_map, Range2> typed::union_map, Range2>::intersect_domain_wrapped_domain(const typed::union_set &domain) const +{ + auto res = isl::union_map::intersect_domain_wrapped_domain(domain); + return typed::union_map, Range2>(res); +} + +template +typed::union_map, Range2> typed::union_map, Range2>::intersect_domain_wrapped_domain(const typed::basic_set &domain) const +{ + auto res = isl::union_map::intersect_domain_wrapped_domain(domain); + return typed::union_map, Range2>(res); +} + +template +typed::union_map, Range2> typed::union_map, Range2>::intersect_domain_wrapped_domain(const typed::point &domain) const +{ + auto res = isl::union_map::intersect_domain_wrapped_domain(domain); + return typed::union_map, Range2>(res); +} + +template +typed::union_map, Range2> typed::union_map, Range2>::intersect_domain_wrapped_domain(const typed::set &domain) const +{ + auto res = isl::union_map::intersect_domain_wrapped_domain(domain); + return typed::union_map, Range2>(res); +} + +template +typed::union_map, Range2> typed::union_map, Range2>::intersect_params(const typed::set<> &set) const +{ + auto res = isl::union_map::intersect_params(set); + return typed::union_map, Range2>(res); +} + +template +typed::union_map, Range2> typed::union_map, Range2>::intersect_params(const typed::basic_set<> &set) const +{ + auto res = isl::union_map::intersect_params(set); + return typed::union_map, Range2>(res); +} + +template +typed::union_map, Range2> typed::union_map, Range2>::intersect_params(const typed::point<> &set) const +{ + auto res = isl::union_map::intersect_params(set); + return typed::union_map, Range2>(res); +} + +template +typed::union_map, Range2> typed::union_map, Range2>::intersect_range(const typed::space &space) const +{ + auto res = isl::union_map::intersect_range(space); + return typed::union_map, Range2>(res); +} + +template +typed::union_map, Range2> typed::union_map, Range2>::intersect_range(const typed::union_set &uset) const +{ + auto res = isl::union_map::intersect_range(uset); + return typed::union_map, Range2>(res); +} + +template +typed::union_map, Range2> typed::union_map, Range2>::lexmax() const +{ + auto res = isl::union_map::lexmax(); + return typed::union_map, Range2>(res); +} + +template +typed::union_map, Range2> typed::union_map, Range2>::lexmin() const +{ + auto res = isl::union_map::lexmin(); + return typed::union_map, Range2>(res); +} + +template +typed::map_list, Range2> typed::union_map, Range2>::map_list() const +{ + auto res = isl::union_map::map_list(); + return typed::map_list, Range2>(res); +} + +template +typed::set<> typed::union_map, Range2>::params() const +{ + auto res = isl::union_map::params(); + return typed::set<>(res); +} + +template +template +typed::union_map typed::union_map, Range2>::preimage_domain(const typed::multi_aff> &ma) const +{ + auto res = isl::union_map::preimage_domain(ma); + return typed::union_map(res); +} + +template +template +typed::union_map typed::union_map, Range2>::preimage_domain(const typed::multi_pw_aff> &mpa) const +{ + auto res = isl::union_map::preimage_domain(mpa); + return typed::union_map(res); +} + +template +template +typed::union_map typed::union_map, Range2>::preimage_domain(const typed::pw_multi_aff> &pma) const +{ + auto res = isl::union_map::preimage_domain(pma); + return typed::union_map(res); +} + +template +template +typed::union_map typed::union_map, Range2>::preimage_domain(const typed::union_pw_multi_aff> &upma) const +{ + auto res = isl::union_map::preimage_domain(upma); + return typed::union_map(res); +} + +template +template +typed::union_map, Arg3> typed::union_map, Range2>::preimage_range(const typed::multi_aff &ma) const +{ + auto res = isl::union_map::preimage_range(ma); + return typed::union_map, Arg3>(res); +} + +template +template +typed::union_map, Arg3> typed::union_map, Range2>::preimage_range(const typed::pw_multi_aff &pma) const +{ + auto res = isl::union_map::preimage_range(pma); + return typed::union_map, Arg3>(res); +} + +template +template +typed::union_map, Arg3> typed::union_map, Range2>::preimage_range(const typed::union_pw_multi_aff &upma) const +{ + auto res = isl::union_map::preimage_range(upma); + return typed::union_map, Arg3>(res); +} + +template +template +typed::union_map, Domain2>, pair> typed::union_map, Range2>::product(const typed::union_map &umap2) const +{ + auto res = isl::union_map::product(umap2); + return typed::union_map, Domain2>, pair>(res); +} + +template +template +typed::union_map, Domain2>, pair> typed::union_map, Range2>::product(const typed::basic_map &umap2) const +{ + auto res = isl::union_map::product(umap2); + return typed::union_map, Domain2>, pair>(res); +} + +template +template +typed::union_map, Domain2>, pair> typed::union_map, Range2>::product(const typed::map &umap2) const +{ + auto res = isl::union_map::product(umap2); + return typed::union_map, Domain2>, pair>(res); +} + +template +typed::union_map, Range2> typed::union_map, Range2>::project_out_all_params() const +{ + auto res = isl::union_map::project_out_all_params(); + return typed::union_map, Range2>(res); +} + +template +typed::union_map, Range2> typed::union_map, Range2>::project_out_param(const typed::id &id) const +{ + auto res = isl::union_map::project_out_param(id); + return typed::union_map, Range2>(res); +} + +template +typed::union_map, Range2> typed::union_map, Range2>::project_out_param(const std::string &id) const +{ + auto res = isl::union_map::project_out_param(id); + return typed::union_map, Range2>(res); +} + +template +typed::union_map, Range2> typed::union_map, Range2>::project_out_param(const typed::id_list &list) const +{ + auto res = isl::union_map::project_out_param(list); + return typed::union_map, Range2>(res); +} + +template +typed::union_set typed::union_map, Range2>::range() const +{ + auto res = isl::union_map::range(); + return typed::union_set(res); +} + +template +typed::union_map, Range2>, Range2> typed::union_map, Range2>::range_map() const +{ + auto res = isl::union_map::range_map(); + return typed::union_map, Range2>, Range2>(res); +} + +template +template +typed::union_map, pair> typed::union_map, Range2>::range_product(const typed::union_map, Arg3> &umap2) const +{ + auto res = isl::union_map::range_product(umap2); + return typed::union_map, pair>(res); +} + +template +template +typed::union_map, pair> typed::union_map, Range2>::range_product(const typed::basic_map, Arg3> &umap2) const +{ + auto res = isl::union_map::range_product(umap2); + return typed::union_map, pair>(res); +} + +template +template +typed::union_map, pair> typed::union_map, Range2>::range_product(const typed::map, Arg3> &umap2) const +{ + auto res = isl::union_map::range_product(umap2); + return typed::union_map, pair>(res); +} + +template +typed::union_map> typed::union_map, Range2>::reverse() const +{ + auto res = isl::union_map::reverse(); + return typed::union_map>(res); +} + +template +typed::space<> typed::union_map, Range2>::space() const +{ + auto res = isl::union_map::space(); + return typed::space<>(res); +} + +template +typed::union_map, Range2> typed::union_map, Range2>::subtract(const typed::union_map, Range2> &umap2) const +{ + auto res = isl::union_map::subtract(umap2); + return typed::union_map, Range2>(res); +} + +template +typed::union_map, Range2> typed::union_map, Range2>::subtract(const typed::basic_map, Range2> &umap2) const +{ + auto res = isl::union_map::subtract(umap2); + return typed::union_map, Range2>(res); +} + +template +typed::union_map, Range2> typed::union_map, Range2>::subtract(const typed::map, Range2> &umap2) const +{ + auto res = isl::union_map::subtract(umap2); + return typed::union_map, Range2>(res); +} + +template +typed::union_map, Range2> typed::union_map, Range2>::subtract_domain(const typed::union_set> &dom) const +{ + auto res = isl::union_map::subtract_domain(dom); + return typed::union_map, Range2>(res); +} + +template +typed::union_map, Range2> typed::union_map, Range2>::subtract_domain(const typed::basic_set> &dom) const +{ + auto res = isl::union_map::subtract_domain(dom); + return typed::union_map, Range2>(res); +} + +template +typed::union_map, Range2> typed::union_map, Range2>::subtract_domain(const typed::point> &dom) const +{ + auto res = isl::union_map::subtract_domain(dom); + return typed::union_map, Range2>(res); +} + +template +typed::union_map, Range2> typed::union_map, Range2>::subtract_domain(const typed::set> &dom) const +{ + auto res = isl::union_map::subtract_domain(dom); + return typed::union_map, Range2>(res); +} + +template +typed::union_map, Range2> typed::union_map, Range2>::subtract_range(const typed::union_set &dom) const +{ + auto res = isl::union_map::subtract_range(dom); + return typed::union_map, Range2>(res); +} + +template +typed::union_map, Range2> typed::union_map, Range2>::subtract_range(const typed::basic_set &dom) const +{ + auto res = isl::union_map::subtract_range(dom); + return typed::union_map, Range2>(res); +} + +template +typed::union_map, Range2> typed::union_map, Range2>::subtract_range(const typed::point &dom) const +{ + auto res = isl::union_map::subtract_range(dom); + return typed::union_map, Range2>(res); +} + +template +typed::union_map, Range2> typed::union_map, Range2>::subtract_range(const typed::set &dom) const +{ + auto res = isl::union_map::subtract_range(dom); + return typed::union_map, Range2>(res); +} + +template +typed::union_map, Range2> typed::union_map, Range2>::unite(const typed::union_map, Range2> &umap2) const +{ + auto res = isl::union_map::unite(umap2); + return typed::union_map, Range2>(res); +} + +template +typed::union_map, Range2> typed::union_map, Range2>::unite(const typed::basic_map, Range2> &umap2) const +{ + auto res = isl::union_map::unite(umap2); + return typed::union_map, Range2>(res); +} + +template +typed::union_map, Range2> typed::union_map, Range2>::unite(const typed::map, Range2> &umap2) const +{ + auto res = isl::union_map::unite(umap2); + return typed::union_map, Range2>(res); +} + +template +typed::union_map, Range2> typed::union_map, Range2>::universe() const +{ + auto res = isl::union_map::universe(); + return typed::union_map, Range2>(res); +} + +template +typed::union_set, Range2>> typed::union_map, Range2>::wrap() const +{ + auto res = isl::union_map::wrap(); + return typed::union_set, Range2>>(res); +} + +template +typed::union_map::union_map(const typed::basic_map &bmap) + : isl::union_map(bmap) +{ +} + +template +typed::union_map::union_map(const typed::map &map) + : isl::union_map(map) +{ +} + +template +typed::union_map::union_map(const isl::ctx &ctx, const std::string &str) + : isl::union_map(ctx, str) +{ +} + +template +template +typed::union_map typed::union_map::apply_domain(const typed::union_map &umap2) const +{ + auto res = isl::union_map::apply_domain(umap2); + return typed::union_map(res); +} + +template +template +typed::union_map typed::union_map::apply_domain(const typed::basic_map &umap2) const +{ + auto res = isl::union_map::apply_domain(umap2); + return typed::union_map(res); +} + +template +template +typed::union_map typed::union_map::apply_domain(const typed::map &umap2) const +{ + auto res = isl::union_map::apply_domain(umap2); + return typed::union_map(res); +} + +template +template +typed::union_map typed::union_map::apply_range(const typed::union_map &umap2) const +{ + auto res = isl::union_map::apply_range(umap2); + return typed::union_map(res); +} + +template +template +typed::union_map typed::union_map::apply_range(const typed::basic_map &umap2) const +{ + auto res = isl::union_map::apply_range(umap2); + return typed::union_map(res); +} + +template +template +typed::union_map typed::union_map::apply_range(const typed::map &umap2) const +{ + auto res = isl::union_map::apply_range(umap2); + return typed::union_map(res); +} + +template +typed::map typed::union_map::as_map() const +{ + auto res = isl::union_map::as_map(); + return typed::map(res); +} + +template +typed::multi_union_pw_aff typed::union_map::as_multi_union_pw_aff() const +{ + auto res = isl::union_map::as_multi_union_pw_aff(); + return typed::multi_union_pw_aff(res); +} + +template +typed::union_pw_multi_aff typed::union_map::as_union_pw_multi_aff() const +{ + auto res = isl::union_map::as_union_pw_multi_aff(); + return typed::union_pw_multi_aff(res); +} + +template +typed::union_set typed::union_map::bind_range(const typed::multi_id &tuple) const +{ + auto res = isl::union_map::bind_range(tuple); + return typed::union_set(res); +} + +template +typed::union_map typed::union_map::coalesce() const +{ + auto res = isl::union_map::coalesce(); + return typed::union_map(res); +} + +template +typed::union_set typed::union_map::deltas() const +{ + auto res = isl::union_map::deltas(); + return typed::union_set(res); +} + +template +typed::union_map typed::union_map::detect_equalities() const +{ + auto res = isl::union_map::detect_equalities(); + return typed::union_map(res); +} + +template +typed::union_set typed::union_map::domain() const +{ + auto res = isl::union_map::domain(); + return typed::union_set(res); +} + +template +typed::union_map, Domain> typed::union_map::domain_map() const +{ + auto res = isl::union_map::domain_map(); + return typed::union_map, Domain>(res); +} + +template +typed::union_pw_multi_aff, Domain> typed::union_map::domain_map_union_pw_multi_aff() const +{ + auto res = isl::union_map::domain_map_union_pw_multi_aff(); + return typed::union_pw_multi_aff, Domain>(res); +} + +template +template +typed::union_map, Domain> typed::union_map::domain_product(const typed::union_map &umap2) const +{ + auto res = isl::union_map::domain_product(umap2); + return typed::union_map, Domain>(res); +} + +template +template +typed::union_map, Domain> typed::union_map::domain_product(const typed::basic_map &umap2) const +{ + auto res = isl::union_map::domain_product(umap2); + return typed::union_map, Domain>(res); +} + +template +template +typed::union_map, Domain> typed::union_map::domain_product(const typed::map &umap2) const +{ + auto res = isl::union_map::domain_product(umap2); + return typed::union_map, Domain>(res); +} + +template +typed::union_map typed::union_map::drop_unused_params() const +{ + auto res = isl::union_map::drop_unused_params(); + return typed::union_map(res); +} + +template +typed::union_map typed::union_map::empty(const isl::ctx &ctx) +{ + auto res = isl::union_map::empty(ctx); + return typed::union_map(res); +} + +template +template +typed::union_map typed::union_map::eq_at(const typed::multi_union_pw_aff &mupa) const +{ + auto res = isl::union_map::eq_at(mupa); + return typed::union_map(res); +} + +template +template +typed::union_map typed::union_map::eq_at(const typed::multi_pw_aff &mupa) const +{ + auto res = isl::union_map::eq_at(mupa); + return typed::union_map(res); +} + +template +typed::union_map typed::union_map::eq_at(const typed::union_pw_aff &mupa) const +{ + auto res = isl::union_map::eq_at(mupa); + return typed::union_map(res); +} + +template +bool typed::union_map::every_map(const std::function)> &test) const +{ + auto lambda_test = [&] (isl::map arg0) { + return test(typed::map(arg0)); + }; + return isl::union_map::every_map(lambda_test); +} + +template +typed::map typed::union_map::extract_map(const typed::space &space) const +{ + auto res = isl::union_map::extract_map(space); + return typed::map(res); +} + +template +void typed::union_map::foreach_map(const std::function)> &fn) const +{ + auto lambda_fn = [&] (isl::map arg0) { + return fn(typed::map(arg0)); + }; + return isl::union_map::foreach_map(lambda_fn); +} + +template +typed::union_map typed::union_map::gist(const typed::union_map &context) const +{ + auto res = isl::union_map::gist(context); + return typed::union_map(res); +} + +template +typed::union_map typed::union_map::gist(const typed::basic_map &context) const +{ + auto res = isl::union_map::gist(context); + return typed::union_map(res); +} + +template +typed::union_map typed::union_map::gist(const typed::map &context) const +{ + auto res = isl::union_map::gist(context); + return typed::union_map(res); +} + +template +typed::union_map typed::union_map::gist_domain(const typed::union_set &uset) const +{ + auto res = isl::union_map::gist_domain(uset); + return typed::union_map(res); +} + +template +typed::union_map typed::union_map::gist_domain(const typed::basic_set &uset) const +{ + auto res = isl::union_map::gist_domain(uset); + return typed::union_map(res); +} + +template +typed::union_map typed::union_map::gist_domain(const typed::point &uset) const +{ + auto res = isl::union_map::gist_domain(uset); + return typed::union_map(res); +} + +template +typed::union_map typed::union_map::gist_domain(const typed::set &uset) const +{ + auto res = isl::union_map::gist_domain(uset); + return typed::union_map(res); +} + +template +typed::union_map typed::union_map::gist_params(const typed::set<> &set) const +{ + auto res = isl::union_map::gist_params(set); + return typed::union_map(res); +} + +template +typed::union_map typed::union_map::gist_params(const typed::basic_set<> &set) const +{ + auto res = isl::union_map::gist_params(set); + return typed::union_map(res); +} + +template +typed::union_map typed::union_map::gist_params(const typed::point<> &set) const +{ + auto res = isl::union_map::gist_params(set); + return typed::union_map(res); +} + +template +typed::union_map typed::union_map::intersect(const typed::union_map &umap2) const +{ + auto res = isl::union_map::intersect(umap2); + return typed::union_map(res); +} + +template +typed::union_map typed::union_map::intersect(const typed::basic_map &umap2) const +{ + auto res = isl::union_map::intersect(umap2); + return typed::union_map(res); +} + +template +typed::union_map typed::union_map::intersect(const typed::map &umap2) const +{ + auto res = isl::union_map::intersect(umap2); + return typed::union_map(res); +} + +template +typed::union_map typed::union_map::intersect_domain(const typed::space &space) const +{ + auto res = isl::union_map::intersect_domain(space); + return typed::union_map(res); +} + +template +typed::union_map typed::union_map::intersect_domain(const typed::union_set &uset) const +{ + auto res = isl::union_map::intersect_domain(uset); + return typed::union_map(res); +} + +template +typed::union_map typed::union_map::intersect_params(const typed::set<> &set) const +{ + auto res = isl::union_map::intersect_params(set); + return typed::union_map(res); +} + +template +typed::union_map typed::union_map::intersect_params(const typed::basic_set<> &set) const +{ + auto res = isl::union_map::intersect_params(set); + return typed::union_map(res); +} + +template +typed::union_map typed::union_map::intersect_params(const typed::point<> &set) const +{ + auto res = isl::union_map::intersect_params(set); + return typed::union_map(res); +} + +template +typed::union_map typed::union_map::intersect_range(const typed::space &space) const +{ + auto res = isl::union_map::intersect_range(space); + return typed::union_map(res); +} + +template +typed::union_map typed::union_map::intersect_range(const typed::union_set &uset) const +{ + auto res = isl::union_map::intersect_range(uset); + return typed::union_map(res); +} + +template +typed::union_map typed::union_map::lexmax() const +{ + auto res = isl::union_map::lexmax(); + return typed::union_map(res); +} + +template +typed::union_map typed::union_map::lexmin() const +{ + auto res = isl::union_map::lexmin(); + return typed::union_map(res); +} + +template +typed::map_list typed::union_map::map_list() const +{ + auto res = isl::union_map::map_list(); + return typed::map_list(res); +} + +template +typed::set<> typed::union_map::params() const +{ + auto res = isl::union_map::params(); + return typed::set<>(res); +} + +template +template +typed::union_map typed::union_map::preimage_domain(const typed::multi_aff &ma) const +{ + auto res = isl::union_map::preimage_domain(ma); + return typed::union_map(res); +} + +template +template +typed::union_map typed::union_map::preimage_domain(const typed::multi_pw_aff &mpa) const +{ + auto res = isl::union_map::preimage_domain(mpa); + return typed::union_map(res); +} + +template +template +typed::union_map typed::union_map::preimage_domain(const typed::pw_multi_aff &pma) const +{ + auto res = isl::union_map::preimage_domain(pma); + return typed::union_map(res); +} + +template +template +typed::union_map typed::union_map::preimage_domain(const typed::union_pw_multi_aff &upma) const +{ + auto res = isl::union_map::preimage_domain(upma); + return typed::union_map(res); +} + +template +template +typed::union_map typed::union_map::preimage_range(const typed::multi_aff &ma) const +{ + auto res = isl::union_map::preimage_range(ma); + return typed::union_map(res); +} + +template +template +typed::union_map typed::union_map::preimage_range(const typed::pw_multi_aff &pma) const +{ + auto res = isl::union_map::preimage_range(pma); + return typed::union_map(res); +} + +template +template +typed::union_map typed::union_map::preimage_range(const typed::union_pw_multi_aff &upma) const +{ + auto res = isl::union_map::preimage_range(upma); + return typed::union_map(res); +} + +template +template +typed::union_map, pair> typed::union_map::product(const typed::union_map &umap2) const +{ + auto res = isl::union_map::product(umap2); + return typed::union_map, pair>(res); +} + +template +template +typed::union_map, pair> typed::union_map::product(const typed::basic_map &umap2) const +{ + auto res = isl::union_map::product(umap2); + return typed::union_map, pair>(res); +} + +template +template +typed::union_map, pair> typed::union_map::product(const typed::map &umap2) const +{ + auto res = isl::union_map::product(umap2); + return typed::union_map, pair>(res); +} + +template +typed::union_map typed::union_map::project_out_all_params() const +{ + auto res = isl::union_map::project_out_all_params(); + return typed::union_map(res); +} + +template +typed::union_map typed::union_map::project_out_param(const typed::id &id) const +{ + auto res = isl::union_map::project_out_param(id); + return typed::union_map(res); +} + +template +typed::union_map typed::union_map::project_out_param(const std::string &id) const +{ + auto res = isl::union_map::project_out_param(id); + return typed::union_map(res); +} + +template +typed::union_map typed::union_map::project_out_param(const typed::id_list &list) const +{ + auto res = isl::union_map::project_out_param(list); + return typed::union_map(res); +} + +template +typed::union_set typed::union_map::range() const +{ + auto res = isl::union_map::range(); + return typed::union_set(res); +} + +template +typed::union_map, Domain> typed::union_map::range_map() const +{ + auto res = isl::union_map::range_map(); + return typed::union_map, Domain>(res); +} + +template +template +typed::union_map> typed::union_map::range_product(const typed::union_map &umap2) const +{ + auto res = isl::union_map::range_product(umap2); + return typed::union_map>(res); +} + +template +template +typed::union_map> typed::union_map::range_product(const typed::basic_map &umap2) const +{ + auto res = isl::union_map::range_product(umap2); + return typed::union_map>(res); +} + +template +template +typed::union_map> typed::union_map::range_product(const typed::map &umap2) const +{ + auto res = isl::union_map::range_product(umap2); + return typed::union_map>(res); +} + +template +typed::union_map typed::union_map::reverse() const +{ + auto res = isl::union_map::reverse(); + return typed::union_map(res); +} + +template +typed::space<> typed::union_map::space() const +{ + auto res = isl::union_map::space(); + return typed::space<>(res); +} + +template +typed::union_map typed::union_map::subtract(const typed::union_map &umap2) const +{ + auto res = isl::union_map::subtract(umap2); + return typed::union_map(res); +} + +template +typed::union_map typed::union_map::subtract(const typed::basic_map &umap2) const +{ + auto res = isl::union_map::subtract(umap2); + return typed::union_map(res); +} + +template +typed::union_map typed::union_map::subtract(const typed::map &umap2) const +{ + auto res = isl::union_map::subtract(umap2); + return typed::union_map(res); +} + +template +typed::union_map typed::union_map::subtract_domain(const typed::union_set &dom) const +{ + auto res = isl::union_map::subtract_domain(dom); + return typed::union_map(res); +} + +template +typed::union_map typed::union_map::subtract_domain(const typed::basic_set &dom) const +{ + auto res = isl::union_map::subtract_domain(dom); + return typed::union_map(res); +} + +template +typed::union_map typed::union_map::subtract_domain(const typed::point &dom) const +{ + auto res = isl::union_map::subtract_domain(dom); + return typed::union_map(res); +} + +template +typed::union_map typed::union_map::subtract_domain(const typed::set &dom) const +{ + auto res = isl::union_map::subtract_domain(dom); + return typed::union_map(res); +} + +template +typed::union_map typed::union_map::subtract_range(const typed::union_set &dom) const +{ + auto res = isl::union_map::subtract_range(dom); + return typed::union_map(res); +} + +template +typed::union_map typed::union_map::subtract_range(const typed::basic_set &dom) const +{ + auto res = isl::union_map::subtract_range(dom); + return typed::union_map(res); +} + +template +typed::union_map typed::union_map::subtract_range(const typed::point &dom) const +{ + auto res = isl::union_map::subtract_range(dom); + return typed::union_map(res); +} + +template +typed::union_map typed::union_map::subtract_range(const typed::set &dom) const +{ + auto res = isl::union_map::subtract_range(dom); + return typed::union_map(res); +} + +template +typed::union_map typed::union_map::unite(const typed::union_map &umap2) const +{ + auto res = isl::union_map::unite(umap2); + return typed::union_map(res); +} + +template +typed::union_map typed::union_map::unite(const typed::basic_map &umap2) const +{ + auto res = isl::union_map::unite(umap2); + return typed::union_map(res); +} + +template +typed::union_map typed::union_map::unite(const typed::map &umap2) const +{ + auto res = isl::union_map::unite(umap2); + return typed::union_map(res); +} + +template +typed::union_map typed::union_map::universe() const +{ + auto res = isl::union_map::universe(); + return typed::union_map(res); +} + +template +typed::union_set> typed::union_map::wrap() const +{ + auto res = isl::union_map::wrap(); + return typed::union_set>(res); +} + +template +typed::union_map>::union_map(const typed::basic_map> &bmap) + : isl::union_map(bmap) +{ +} + +template +typed::union_map>::union_map(const typed::map> &map) + : isl::union_map(map) +{ +} + +template +typed::union_map>::union_map(const isl::ctx &ctx, const std::string &str) + : isl::union_map(ctx, str) +{ +} + +template +template +typed::union_map> typed::union_map>::apply_domain(const typed::union_map &umap2) const +{ + auto res = isl::union_map::apply_domain(umap2); + return typed::union_map>(res); +} + +template +template +typed::union_map> typed::union_map>::apply_domain(const typed::basic_map &umap2) const +{ + auto res = isl::union_map::apply_domain(umap2); + return typed::union_map>(res); +} + +template +template +typed::union_map> typed::union_map>::apply_domain(const typed::map &umap2) const +{ + auto res = isl::union_map::apply_domain(umap2); + return typed::union_map>(res); +} + +template +template +typed::union_map typed::union_map>::apply_range(const typed::union_map, Arg3> &umap2) const +{ + auto res = isl::union_map::apply_range(umap2); + return typed::union_map(res); +} + +template +template +typed::union_map typed::union_map>::apply_range(const typed::basic_map, Arg3> &umap2) const +{ + auto res = isl::union_map::apply_range(umap2); + return typed::union_map(res); +} + +template +template +typed::union_map typed::union_map>::apply_range(const typed::map, Arg3> &umap2) const +{ + auto res = isl::union_map::apply_range(umap2); + return typed::union_map(res); +} + +template +typed::map> typed::union_map>::as_map() const +{ + auto res = isl::union_map::as_map(); + return typed::map>(res); +} + +template +typed::multi_union_pw_aff> typed::union_map>::as_multi_union_pw_aff() const +{ + auto res = isl::union_map::as_multi_union_pw_aff(); + return typed::multi_union_pw_aff>(res); +} + +template +typed::union_pw_multi_aff> typed::union_map>::as_union_pw_multi_aff() const +{ + auto res = isl::union_map::as_union_pw_multi_aff(); + return typed::union_pw_multi_aff>(res); +} + +template +typed::union_set typed::union_map>::bind_range(const typed::multi_id> &tuple) const +{ + auto res = isl::union_map::bind_range(tuple); + return typed::union_set(res); +} + +template +typed::union_map> typed::union_map>::coalesce() const +{ + auto res = isl::union_map::coalesce(); + return typed::union_map>(res); +} + +template +typed::union_map> typed::union_map>::detect_equalities() const +{ + auto res = isl::union_map::detect_equalities(); + return typed::union_map>(res); +} + +template +typed::union_set typed::union_map>::domain() const +{ + auto res = isl::union_map::domain(); + return typed::union_set(res); +} + +template +typed::union_map>, Domain> typed::union_map>::domain_map() const +{ + auto res = isl::union_map::domain_map(); + return typed::union_map>, Domain>(res); +} + +template +typed::union_pw_multi_aff>, Domain> typed::union_map>::domain_map_union_pw_multi_aff() const +{ + auto res = isl::union_map::domain_map_union_pw_multi_aff(); + return typed::union_pw_multi_aff>, Domain>(res); +} + +template +template +typed::union_map, pair> typed::union_map>::domain_product(const typed::union_map> &umap2) const +{ + auto res = isl::union_map::domain_product(umap2); + return typed::union_map, pair>(res); +} + +template +template +typed::union_map, pair> typed::union_map>::domain_product(const typed::basic_map> &umap2) const +{ + auto res = isl::union_map::domain_product(umap2); + return typed::union_map, pair>(res); +} + +template +template +typed::union_map, pair> typed::union_map>::domain_product(const typed::map> &umap2) const +{ + auto res = isl::union_map::domain_product(umap2); + return typed::union_map, pair>(res); +} + +template +typed::union_map> typed::union_map>::drop_unused_params() const +{ + auto res = isl::union_map::drop_unused_params(); + return typed::union_map>(res); +} + +template +typed::union_map> typed::union_map>::empty(const isl::ctx &ctx) +{ + auto res = isl::union_map::empty(ctx); + return typed::union_map>(res); +} + +template +bool typed::union_map>::every_map(const std::function>)> &test) const +{ + auto lambda_test = [&] (isl::map arg0) { + return test(typed::map>(arg0)); + }; + return isl::union_map::every_map(lambda_test); +} + +template +typed::map> typed::union_map>::extract_map(const typed::space> &space) const +{ + auto res = isl::union_map::extract_map(space); + return typed::map>(res); +} + +template +void typed::union_map>::foreach_map(const std::function>)> &fn) const +{ + auto lambda_fn = [&] (isl::map arg0) { + return fn(typed::map>(arg0)); + }; + return isl::union_map::foreach_map(lambda_fn); +} + +template +typed::union_map> typed::union_map>::gist(const typed::union_map> &context) const +{ + auto res = isl::union_map::gist(context); + return typed::union_map>(res); +} + +template +typed::union_map> typed::union_map>::gist(const typed::basic_map> &context) const +{ + auto res = isl::union_map::gist(context); + return typed::union_map>(res); +} + +template +typed::union_map> typed::union_map>::gist(const typed::map> &context) const +{ + auto res = isl::union_map::gist(context); + return typed::union_map>(res); +} + +template +typed::union_map> typed::union_map>::gist_domain(const typed::union_set &uset) const +{ + auto res = isl::union_map::gist_domain(uset); + return typed::union_map>(res); +} + +template +typed::union_map> typed::union_map>::gist_domain(const typed::basic_set &uset) const +{ + auto res = isl::union_map::gist_domain(uset); + return typed::union_map>(res); +} + +template +typed::union_map> typed::union_map>::gist_domain(const typed::point &uset) const +{ + auto res = isl::union_map::gist_domain(uset); + return typed::union_map>(res); +} + +template +typed::union_map> typed::union_map>::gist_domain(const typed::set &uset) const +{ + auto res = isl::union_map::gist_domain(uset); + return typed::union_map>(res); +} + +template +typed::union_map> typed::union_map>::gist_params(const typed::set<> &set) const +{ + auto res = isl::union_map::gist_params(set); + return typed::union_map>(res); +} + +template +typed::union_map> typed::union_map>::gist_params(const typed::basic_set<> &set) const +{ + auto res = isl::union_map::gist_params(set); + return typed::union_map>(res); +} + +template +typed::union_map> typed::union_map>::gist_params(const typed::point<> &set) const +{ + auto res = isl::union_map::gist_params(set); + return typed::union_map>(res); +} + +template +typed::union_map> typed::union_map>::intersect(const typed::union_map> &umap2) const +{ + auto res = isl::union_map::intersect(umap2); + return typed::union_map>(res); +} + +template +typed::union_map> typed::union_map>::intersect(const typed::basic_map> &umap2) const +{ + auto res = isl::union_map::intersect(umap2); + return typed::union_map>(res); +} + +template +typed::union_map> typed::union_map>::intersect(const typed::map> &umap2) const +{ + auto res = isl::union_map::intersect(umap2); + return typed::union_map>(res); +} + +template +typed::union_map> typed::union_map>::intersect_domain(const typed::space &space) const +{ + auto res = isl::union_map::intersect_domain(space); + return typed::union_map>(res); +} + +template +typed::union_map> typed::union_map>::intersect_domain(const typed::union_set &uset) const +{ + auto res = isl::union_map::intersect_domain(uset); + return typed::union_map>(res); +} + +template +typed::union_map> typed::union_map>::intersect_params(const typed::set<> &set) const +{ + auto res = isl::union_map::intersect_params(set); + return typed::union_map>(res); +} + +template +typed::union_map> typed::union_map>::intersect_params(const typed::basic_set<> &set) const +{ + auto res = isl::union_map::intersect_params(set); + return typed::union_map>(res); +} + +template +typed::union_map> typed::union_map>::intersect_params(const typed::point<> &set) const +{ + auto res = isl::union_map::intersect_params(set); + return typed::union_map>(res); +} + +template +typed::union_map> typed::union_map>::intersect_range(const typed::space> &space) const +{ + auto res = isl::union_map::intersect_range(space); + return typed::union_map>(res); +} + +template +typed::union_map> typed::union_map>::intersect_range(const typed::union_set> &uset) const +{ + auto res = isl::union_map::intersect_range(uset); + return typed::union_map>(res); +} + +template +typed::union_map> typed::union_map>::intersect_range_wrapped_domain(const typed::union_set &domain) const +{ + auto res = isl::union_map::intersect_range_wrapped_domain(domain); + return typed::union_map>(res); +} + +template +typed::union_map> typed::union_map>::intersect_range_wrapped_domain(const typed::basic_set &domain) const +{ + auto res = isl::union_map::intersect_range_wrapped_domain(domain); + return typed::union_map>(res); +} + +template +typed::union_map> typed::union_map>::intersect_range_wrapped_domain(const typed::point &domain) const +{ + auto res = isl::union_map::intersect_range_wrapped_domain(domain); + return typed::union_map>(res); +} + +template +typed::union_map> typed::union_map>::intersect_range_wrapped_domain(const typed::set &domain) const +{ + auto res = isl::union_map::intersect_range_wrapped_domain(domain); + return typed::union_map>(res); +} + +template +typed::union_map> typed::union_map>::lexmax() const +{ + auto res = isl::union_map::lexmax(); + return typed::union_map>(res); +} + +template +typed::union_map> typed::union_map>::lexmin() const +{ + auto res = isl::union_map::lexmin(); + return typed::union_map>(res); +} + +template +typed::map_list> typed::union_map>::map_list() const +{ + auto res = isl::union_map::map_list(); + return typed::map_list>(res); +} + +template +typed::set<> typed::union_map>::params() const +{ + auto res = isl::union_map::params(); + return typed::set<>(res); +} + +template +template +typed::union_map> typed::union_map>::preimage_domain(const typed::multi_aff &ma) const +{ + auto res = isl::union_map::preimage_domain(ma); + return typed::union_map>(res); +} + +template +template +typed::union_map> typed::union_map>::preimage_domain(const typed::multi_pw_aff &mpa) const +{ + auto res = isl::union_map::preimage_domain(mpa); + return typed::union_map>(res); +} + +template +template +typed::union_map> typed::union_map>::preimage_domain(const typed::pw_multi_aff &pma) const +{ + auto res = isl::union_map::preimage_domain(pma); + return typed::union_map>(res); +} + +template +template +typed::union_map> typed::union_map>::preimage_domain(const typed::union_pw_multi_aff &upma) const +{ + auto res = isl::union_map::preimage_domain(upma); + return typed::union_map>(res); +} + +template +template +typed::union_map typed::union_map>::preimage_range(const typed::multi_aff> &ma) const +{ + auto res = isl::union_map::preimage_range(ma); + return typed::union_map(res); +} + +template +template +typed::union_map typed::union_map>::preimage_range(const typed::pw_multi_aff> &pma) const +{ + auto res = isl::union_map::preimage_range(pma); + return typed::union_map(res); +} + +template +template +typed::union_map typed::union_map>::preimage_range(const typed::union_pw_multi_aff> &upma) const +{ + auto res = isl::union_map::preimage_range(upma); + return typed::union_map(res); +} + +template +template +typed::union_map, pair, Arg3>> typed::union_map>::product(const typed::union_map &umap2) const +{ + auto res = isl::union_map::product(umap2); + return typed::union_map, pair, Arg3>>(res); +} + +template +template +typed::union_map, pair, Arg3>> typed::union_map>::product(const typed::basic_map &umap2) const +{ + auto res = isl::union_map::product(umap2); + return typed::union_map, pair, Arg3>>(res); +} + +template +template +typed::union_map, pair, Arg3>> typed::union_map>::product(const typed::map &umap2) const +{ + auto res = isl::union_map::product(umap2); + return typed::union_map, pair, Arg3>>(res); +} + +template +typed::union_map> typed::union_map>::project_out_all_params() const +{ + auto res = isl::union_map::project_out_all_params(); + return typed::union_map>(res); +} + +template +typed::union_map> typed::union_map>::project_out_param(const typed::id &id) const +{ + auto res = isl::union_map::project_out_param(id); + return typed::union_map>(res); +} + +template +typed::union_map> typed::union_map>::project_out_param(const std::string &id) const +{ + auto res = isl::union_map::project_out_param(id); + return typed::union_map>(res); +} + +template +typed::union_map> typed::union_map>::project_out_param(const typed::id_list &list) const +{ + auto res = isl::union_map::project_out_param(list); + return typed::union_map>(res); +} + +template +typed::union_set> typed::union_map>::range() const +{ + auto res = isl::union_map::range(); + return typed::union_set>(res); +} + +template +typed::union_map typed::union_map>::range_factor_domain() const +{ + auto res = isl::union_map::range_factor_domain(); + return typed::union_map(res); +} + +template +typed::union_map typed::union_map>::range_factor_range() const +{ + auto res = isl::union_map::range_factor_range(); + return typed::union_map(res); +} + +template +typed::union_map>, pair> typed::union_map>::range_map() const +{ + auto res = isl::union_map::range_map(); + return typed::union_map>, pair>(res); +} + +template +template +typed::union_map, Arg3>> typed::union_map>::range_product(const typed::union_map &umap2) const +{ + auto res = isl::union_map::range_product(umap2); + return typed::union_map, Arg3>>(res); +} + +template +template +typed::union_map, Arg3>> typed::union_map>::range_product(const typed::basic_map &umap2) const +{ + auto res = isl::union_map::range_product(umap2); + return typed::union_map, Arg3>>(res); +} + +template +template +typed::union_map, Arg3>> typed::union_map>::range_product(const typed::map &umap2) const +{ + auto res = isl::union_map::range_product(umap2); + return typed::union_map, Arg3>>(res); +} + +template +typed::union_map> typed::union_map>::range_reverse() const +{ + auto res = isl::union_map::range_reverse(); + return typed::union_map>(res); +} + +template +typed::union_map, Domain> typed::union_map>::reverse() const +{ + auto res = isl::union_map::reverse(); + return typed::union_map, Domain>(res); +} + +template +typed::space<> typed::union_map>::space() const +{ + auto res = isl::union_map::space(); + return typed::space<>(res); +} + +template +typed::union_map> typed::union_map>::subtract(const typed::union_map> &umap2) const +{ + auto res = isl::union_map::subtract(umap2); + return typed::union_map>(res); +} + +template +typed::union_map> typed::union_map>::subtract(const typed::basic_map> &umap2) const +{ + auto res = isl::union_map::subtract(umap2); + return typed::union_map>(res); +} + +template +typed::union_map> typed::union_map>::subtract(const typed::map> &umap2) const +{ + auto res = isl::union_map::subtract(umap2); + return typed::union_map>(res); +} + +template +typed::union_map> typed::union_map>::subtract_domain(const typed::union_set &dom) const +{ + auto res = isl::union_map::subtract_domain(dom); + return typed::union_map>(res); +} + +template +typed::union_map> typed::union_map>::subtract_domain(const typed::basic_set &dom) const +{ + auto res = isl::union_map::subtract_domain(dom); + return typed::union_map>(res); +} + +template +typed::union_map> typed::union_map>::subtract_domain(const typed::point &dom) const +{ + auto res = isl::union_map::subtract_domain(dom); + return typed::union_map>(res); +} + +template +typed::union_map> typed::union_map>::subtract_domain(const typed::set &dom) const +{ + auto res = isl::union_map::subtract_domain(dom); + return typed::union_map>(res); +} + +template +typed::union_map> typed::union_map>::subtract_range(const typed::union_set> &dom) const +{ + auto res = isl::union_map::subtract_range(dom); + return typed::union_map>(res); +} + +template +typed::union_map> typed::union_map>::subtract_range(const typed::basic_set> &dom) const +{ + auto res = isl::union_map::subtract_range(dom); + return typed::union_map>(res); +} + +template +typed::union_map> typed::union_map>::subtract_range(const typed::point> &dom) const +{ + auto res = isl::union_map::subtract_range(dom); + return typed::union_map>(res); +} + +template +typed::union_map> typed::union_map>::subtract_range(const typed::set> &dom) const +{ + auto res = isl::union_map::subtract_range(dom); + return typed::union_map>(res); +} + +template +typed::union_map, Range2> typed::union_map>::uncurry() const +{ + auto res = isl::union_map::uncurry(); + return typed::union_map, Range2>(res); +} + +template +typed::union_map> typed::union_map>::unite(const typed::union_map> &umap2) const +{ + auto res = isl::union_map::unite(umap2); + return typed::union_map>(res); +} + +template +typed::union_map> typed::union_map>::unite(const typed::basic_map> &umap2) const +{ + auto res = isl::union_map::unite(umap2); + return typed::union_map>(res); +} + +template +typed::union_map> typed::union_map>::unite(const typed::map> &umap2) const +{ + auto res = isl::union_map::unite(umap2); + return typed::union_map>(res); +} + +template +typed::union_map> typed::union_map>::universe() const +{ + auto res = isl::union_map::universe(); + return typed::union_map>(res); +} + +template +typed::union_set>> typed::union_map>::wrap() const +{ + auto res = isl::union_map::wrap(); + return typed::union_set>>(res); +} + +template +typed::union_map, pair>::union_map(const typed::basic_map, pair> &bmap) + : isl::union_map(bmap) +{ +} + +template +typed::union_map, pair>::union_map(const typed::map, pair> &map) + : isl::union_map(map) +{ +} + +template +typed::union_map, pair>::union_map(const isl::ctx &ctx, const std::string &str) + : isl::union_map(ctx, str) +{ +} + +template +template +typed::union_map> typed::union_map, pair>::apply_domain(const typed::union_map, Domain2> &umap2) const +{ + auto res = isl::union_map::apply_domain(umap2); + return typed::union_map>(res); +} + +template +template +typed::union_map> typed::union_map, pair>::apply_domain(const typed::basic_map, Domain2> &umap2) const +{ + auto res = isl::union_map::apply_domain(umap2); + return typed::union_map>(res); +} + +template +template +typed::union_map> typed::union_map, pair>::apply_domain(const typed::map, Domain2> &umap2) const +{ + auto res = isl::union_map::apply_domain(umap2); + return typed::union_map>(res); +} + +template +template +typed::union_map, Range2> typed::union_map, pair>::apply_range(const typed::union_map, Range2> &umap2) const +{ + auto res = isl::union_map::apply_range(umap2); + return typed::union_map, Range2>(res); +} + +template +template +typed::union_map, Range2> typed::union_map, pair>::apply_range(const typed::basic_map, Range2> &umap2) const +{ + auto res = isl::union_map::apply_range(umap2); + return typed::union_map, Range2>(res); +} + +template +template +typed::union_map, Range2> typed::union_map, pair>::apply_range(const typed::map, Range2> &umap2) const +{ + auto res = isl::union_map::apply_range(umap2); + return typed::union_map, Range2>(res); +} + +template +typed::map, pair> typed::union_map, pair>::as_map() const +{ + auto res = isl::union_map::as_map(); + return typed::map, pair>(res); +} + +template +typed::multi_union_pw_aff, pair> typed::union_map, pair>::as_multi_union_pw_aff() const +{ + auto res = isl::union_map::as_multi_union_pw_aff(); + return typed::multi_union_pw_aff, pair>(res); +} + +template +typed::union_pw_multi_aff, pair> typed::union_map, pair>::as_union_pw_multi_aff() const +{ + auto res = isl::union_map::as_union_pw_multi_aff(); + return typed::union_pw_multi_aff, pair>(res); +} + +template +typed::union_set> typed::union_map, pair>::bind_range(const typed::multi_id> &tuple) const +{ + auto res = isl::union_map::bind_range(tuple); + return typed::union_set>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::coalesce() const +{ + auto res = isl::union_map::coalesce(); + return typed::union_map, pair>(res); +} + +template +typed::union_map>> typed::union_map, pair>::curry() const +{ + auto res = isl::union_map::curry(); + return typed::union_map>>(res); +} + +template +typed::union_set> typed::union_map, pair>::deltas() const +{ + auto res = isl::union_map::deltas(); + return typed::union_set>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::detect_equalities() const +{ + auto res = isl::union_map::detect_equalities(); + return typed::union_map, pair>(res); +} + +template +typed::union_set> typed::union_map, pair>::domain() const +{ + auto res = isl::union_map::domain(); + return typed::union_set>(res); +} + +template +typed::union_map> typed::union_map, pair>::domain_factor_domain() const +{ + auto res = isl::union_map::domain_factor_domain(); + return typed::union_map>(res); +} + +template +typed::union_map> typed::union_map, pair>::domain_factor_range() const +{ + auto res = isl::union_map::domain_factor_range(); + return typed::union_map>(res); +} + +template +typed::union_map, pair>, pair> typed::union_map, pair>::domain_map() const +{ + auto res = isl::union_map::domain_map(); + return typed::union_map, pair>, pair>(res); +} + +template +typed::union_pw_multi_aff, pair>, pair> typed::union_map, pair>::domain_map_union_pw_multi_aff() const +{ + auto res = isl::union_map::domain_map_union_pw_multi_aff(); + return typed::union_pw_multi_aff, pair>, pair>(res); +} + +template +template +typed::union_map, Domain2>, pair> typed::union_map, pair>::domain_product(const typed::union_map> &umap2) const +{ + auto res = isl::union_map::domain_product(umap2); + return typed::union_map, Domain2>, pair>(res); +} + +template +template +typed::union_map, Domain2>, pair> typed::union_map, pair>::domain_product(const typed::basic_map> &umap2) const +{ + auto res = isl::union_map::domain_product(umap2); + return typed::union_map, Domain2>, pair>(res); +} + +template +template +typed::union_map, Domain2>, pair> typed::union_map, pair>::domain_product(const typed::map> &umap2) const +{ + auto res = isl::union_map::domain_product(umap2); + return typed::union_map, Domain2>, pair>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::domain_reverse() const +{ + auto res = isl::union_map::domain_reverse(); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::drop_unused_params() const +{ + auto res = isl::union_map::drop_unused_params(); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::empty(const isl::ctx &ctx) +{ + auto res = isl::union_map::empty(ctx); + return typed::union_map, pair>(res); +} + +template +template +typed::union_map, pair> typed::union_map, pair>::eq_at(const typed::multi_union_pw_aff, Range> &mupa) const +{ + auto res = isl::union_map::eq_at(mupa); + return typed::union_map, pair>(res); +} + +template +template +typed::union_map, pair> typed::union_map, pair>::eq_at(const typed::multi_pw_aff, Range> &mupa) const +{ + auto res = isl::union_map::eq_at(mupa); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::eq_at(const typed::union_pw_aff, Anonymous> &mupa) const +{ + auto res = isl::union_map::eq_at(mupa); + return typed::union_map, pair>(res); +} + +template +bool typed::union_map, pair>::every_map(const std::function, pair>)> &test) const +{ + auto lambda_test = [&] (isl::map arg0) { + return test(typed::map, pair>(arg0)); + }; + return isl::union_map::every_map(lambda_test); +} + +template +typed::map, pair> typed::union_map, pair>::extract_map(const typed::space, pair> &space) const +{ + auto res = isl::union_map::extract_map(space); + return typed::map, pair>(res); +} + +template +void typed::union_map, pair>::foreach_map(const std::function, pair>)> &fn) const +{ + auto lambda_fn = [&] (isl::map arg0) { + return fn(typed::map, pair>(arg0)); + }; + return isl::union_map::foreach_map(lambda_fn); +} + +template +typed::union_map, pair> typed::union_map, pair>::gist(const typed::union_map, pair> &context) const +{ + auto res = isl::union_map::gist(context); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::gist(const typed::basic_map, pair> &context) const +{ + auto res = isl::union_map::gist(context); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::gist(const typed::map, pair> &context) const +{ + auto res = isl::union_map::gist(context); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::gist_domain(const typed::union_set> &uset) const +{ + auto res = isl::union_map::gist_domain(uset); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::gist_domain(const typed::basic_set> &uset) const +{ + auto res = isl::union_map::gist_domain(uset); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::gist_domain(const typed::point> &uset) const +{ + auto res = isl::union_map::gist_domain(uset); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::gist_domain(const typed::set> &uset) const +{ + auto res = isl::union_map::gist_domain(uset); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::gist_params(const typed::set<> &set) const +{ + auto res = isl::union_map::gist_params(set); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::gist_params(const typed::basic_set<> &set) const +{ + auto res = isl::union_map::gist_params(set); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::gist_params(const typed::point<> &set) const +{ + auto res = isl::union_map::gist_params(set); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::intersect(const typed::union_map, pair> &umap2) const +{ + auto res = isl::union_map::intersect(umap2); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::intersect(const typed::basic_map, pair> &umap2) const +{ + auto res = isl::union_map::intersect(umap2); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::intersect(const typed::map, pair> &umap2) const +{ + auto res = isl::union_map::intersect(umap2); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::intersect_domain(const typed::space> &space) const +{ + auto res = isl::union_map::intersect_domain(space); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::intersect_domain(const typed::union_set> &uset) const +{ + auto res = isl::union_map::intersect_domain(uset); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::intersect_domain_wrapped_domain(const typed::union_set &domain) const +{ + auto res = isl::union_map::intersect_domain_wrapped_domain(domain); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::intersect_domain_wrapped_domain(const typed::basic_set &domain) const +{ + auto res = isl::union_map::intersect_domain_wrapped_domain(domain); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::intersect_domain_wrapped_domain(const typed::point &domain) const +{ + auto res = isl::union_map::intersect_domain_wrapped_domain(domain); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::intersect_domain_wrapped_domain(const typed::set &domain) const +{ + auto res = isl::union_map::intersect_domain_wrapped_domain(domain); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::intersect_params(const typed::set<> &set) const +{ + auto res = isl::union_map::intersect_params(set); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::intersect_params(const typed::basic_set<> &set) const +{ + auto res = isl::union_map::intersect_params(set); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::intersect_params(const typed::point<> &set) const +{ + auto res = isl::union_map::intersect_params(set); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::intersect_range(const typed::space> &space) const +{ + auto res = isl::union_map::intersect_range(space); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::intersect_range(const typed::union_set> &uset) const +{ + auto res = isl::union_map::intersect_range(uset); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::intersect_range_wrapped_domain(const typed::union_set &domain) const +{ + auto res = isl::union_map::intersect_range_wrapped_domain(domain); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::intersect_range_wrapped_domain(const typed::basic_set &domain) const +{ + auto res = isl::union_map::intersect_range_wrapped_domain(domain); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::intersect_range_wrapped_domain(const typed::point &domain) const +{ + auto res = isl::union_map::intersect_range_wrapped_domain(domain); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::intersect_range_wrapped_domain(const typed::set &domain) const +{ + auto res = isl::union_map::intersect_range_wrapped_domain(domain); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::lexmax() const +{ + auto res = isl::union_map::lexmax(); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::lexmin() const +{ + auto res = isl::union_map::lexmin(); + return typed::union_map, pair>(res); +} + +template +typed::map_list, pair> typed::union_map, pair>::map_list() const +{ + auto res = isl::union_map::map_list(); + return typed::map_list, pair>(res); +} + +template +typed::set<> typed::union_map, pair>::params() const +{ + auto res = isl::union_map::params(); + return typed::set<>(res); +} + +template +template +typed::union_map> typed::union_map, pair>::preimage_domain(const typed::multi_aff> &ma) const +{ + auto res = isl::union_map::preimage_domain(ma); + return typed::union_map>(res); +} + +template +template +typed::union_map> typed::union_map, pair>::preimage_domain(const typed::multi_pw_aff> &mpa) const +{ + auto res = isl::union_map::preimage_domain(mpa); + return typed::union_map>(res); +} + +template +template +typed::union_map> typed::union_map, pair>::preimage_domain(const typed::pw_multi_aff> &pma) const +{ + auto res = isl::union_map::preimage_domain(pma); + return typed::union_map>(res); +} + +template +template +typed::union_map> typed::union_map, pair>::preimage_domain(const typed::union_pw_multi_aff> &upma) const +{ + auto res = isl::union_map::preimage_domain(upma); + return typed::union_map>(res); +} + +template +template +typed::union_map, Range2> typed::union_map, pair>::preimage_range(const typed::multi_aff> &ma) const +{ + auto res = isl::union_map::preimage_range(ma); + return typed::union_map, Range2>(res); +} + +template +template +typed::union_map, Range2> typed::union_map, pair>::preimage_range(const typed::pw_multi_aff> &pma) const +{ + auto res = isl::union_map::preimage_range(pma); + return typed::union_map, Range2>(res); +} + +template +template +typed::union_map, Range2> typed::union_map, pair>::preimage_range(const typed::union_pw_multi_aff> &upma) const +{ + auto res = isl::union_map::preimage_range(upma); + return typed::union_map, Range2>(res); +} + +template +template +typed::union_map, Domain2>, pair, Range2>> typed::union_map, pair>::product(const typed::union_map &umap2) const +{ + auto res = isl::union_map::product(umap2); + return typed::union_map, Domain2>, pair, Range2>>(res); +} + +template +template +typed::union_map, Domain2>, pair, Range2>> typed::union_map, pair>::product(const typed::basic_map &umap2) const +{ + auto res = isl::union_map::product(umap2); + return typed::union_map, Domain2>, pair, Range2>>(res); +} + +template +template +typed::union_map, Domain2>, pair, Range2>> typed::union_map, pair>::product(const typed::map &umap2) const +{ + auto res = isl::union_map::product(umap2); + return typed::union_map, Domain2>, pair, Range2>>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::project_out_all_params() const +{ + auto res = isl::union_map::project_out_all_params(); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::project_out_param(const typed::id &id) const +{ + auto res = isl::union_map::project_out_param(id); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::project_out_param(const std::string &id) const +{ + auto res = isl::union_map::project_out_param(id); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::project_out_param(const typed::id_list &list) const +{ + auto res = isl::union_map::project_out_param(list); + return typed::union_map, pair>(res); +} + +template +typed::union_set> typed::union_map, pair>::range() const +{ + auto res = isl::union_map::range(); + return typed::union_set>(res); +} + +template +typed::union_map, T1> typed::union_map, pair>::range_factor_domain() const +{ + auto res = isl::union_map::range_factor_domain(); + return typed::union_map, T1>(res); +} + +template +typed::union_map, T2> typed::union_map, pair>::range_factor_range() const +{ + auto res = isl::union_map::range_factor_range(); + return typed::union_map, T2>(res); +} + +template +typed::union_map, pair>, pair> typed::union_map, pair>::range_map() const +{ + auto res = isl::union_map::range_map(); + return typed::union_map, pair>, pair>(res); +} + +template +template +typed::union_map, pair, Range2>> typed::union_map, pair>::range_product(const typed::union_map, Range2> &umap2) const +{ + auto res = isl::union_map::range_product(umap2); + return typed::union_map, pair, Range2>>(res); +} + +template +template +typed::union_map, pair, Range2>> typed::union_map, pair>::range_product(const typed::basic_map, Range2> &umap2) const +{ + auto res = isl::union_map::range_product(umap2); + return typed::union_map, pair, Range2>>(res); +} + +template +template +typed::union_map, pair, Range2>> typed::union_map, pair>::range_product(const typed::map, Range2> &umap2) const +{ + auto res = isl::union_map::range_product(umap2); + return typed::union_map, pair, Range2>>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::range_reverse() const +{ + auto res = isl::union_map::range_reverse(); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::reverse() const +{ + auto res = isl::union_map::reverse(); + return typed::union_map, pair>(res); +} + +template +typed::space<> typed::union_map, pair>::space() const +{ + auto res = isl::union_map::space(); + return typed::space<>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::subtract(const typed::union_map, pair> &umap2) const +{ + auto res = isl::union_map::subtract(umap2); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::subtract(const typed::basic_map, pair> &umap2) const +{ + auto res = isl::union_map::subtract(umap2); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::subtract(const typed::map, pair> &umap2) const +{ + auto res = isl::union_map::subtract(umap2); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::subtract_domain(const typed::union_set> &dom) const +{ + auto res = isl::union_map::subtract_domain(dom); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::subtract_domain(const typed::basic_set> &dom) const +{ + auto res = isl::union_map::subtract_domain(dom); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::subtract_domain(const typed::point> &dom) const +{ + auto res = isl::union_map::subtract_domain(dom); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::subtract_domain(const typed::set> &dom) const +{ + auto res = isl::union_map::subtract_domain(dom); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::subtract_range(const typed::union_set> &dom) const +{ + auto res = isl::union_map::subtract_range(dom); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::subtract_range(const typed::basic_set> &dom) const +{ + auto res = isl::union_map::subtract_range(dom); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::subtract_range(const typed::point> &dom) const +{ + auto res = isl::union_map::subtract_range(dom); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::subtract_range(const typed::set> &dom) const +{ + auto res = isl::union_map::subtract_range(dom); + return typed::union_map, pair>(res); +} + +template +typed::union_map, T1>, T2> typed::union_map, pair>::uncurry() const +{ + auto res = isl::union_map::uncurry(); + return typed::union_map, T1>, T2>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::unite(const typed::union_map, pair> &umap2) const +{ + auto res = isl::union_map::unite(umap2); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::unite(const typed::basic_map, pair> &umap2) const +{ + auto res = isl::union_map::unite(umap2); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::unite(const typed::map, pair> &umap2) const +{ + auto res = isl::union_map::unite(umap2); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::universe() const +{ + auto res = isl::union_map::universe(); + return typed::union_map, pair>(res); +} + +template +typed::union_set, pair>> typed::union_map, pair>::wrap() const +{ + auto res = isl::union_map::wrap(); + return typed::union_set, pair>>(res); +} + +template +typed::union_map, pair>::union_map(const typed::basic_map, pair> &bmap) + : isl::union_map(bmap) +{ +} + +template +typed::union_map, pair>::union_map(const typed::map, pair> &map) + : isl::union_map(map) +{ +} + +template +typed::union_map, pair>::union_map(const isl::ctx &ctx, const std::string &str) + : isl::union_map(ctx, str) +{ +} + +template +template +typed::union_map> typed::union_map, pair>::apply_domain(const typed::union_map, Domain2> &umap2) const +{ + auto res = isl::union_map::apply_domain(umap2); + return typed::union_map>(res); +} + +template +template +typed::union_map> typed::union_map, pair>::apply_domain(const typed::basic_map, Domain2> &umap2) const +{ + auto res = isl::union_map::apply_domain(umap2); + return typed::union_map>(res); +} + +template +template +typed::union_map> typed::union_map, pair>::apply_domain(const typed::map, Domain2> &umap2) const +{ + auto res = isl::union_map::apply_domain(umap2); + return typed::union_map>(res); +} + +template +template +typed::union_map, Arg2> typed::union_map, pair>::apply_range(const typed::union_map, Arg2> &umap2) const +{ + auto res = isl::union_map::apply_range(umap2); + return typed::union_map, Arg2>(res); +} + +template +template +typed::union_map, Arg2> typed::union_map, pair>::apply_range(const typed::basic_map, Arg2> &umap2) const +{ + auto res = isl::union_map::apply_range(umap2); + return typed::union_map, Arg2>(res); +} + +template +template +typed::union_map, Arg2> typed::union_map, pair>::apply_range(const typed::map, Arg2> &umap2) const +{ + auto res = isl::union_map::apply_range(umap2); + return typed::union_map, Arg2>(res); +} + +template +typed::map, pair> typed::union_map, pair>::as_map() const +{ + auto res = isl::union_map::as_map(); + return typed::map, pair>(res); +} + +template +typed::multi_union_pw_aff, pair> typed::union_map, pair>::as_multi_union_pw_aff() const +{ + auto res = isl::union_map::as_multi_union_pw_aff(); + return typed::multi_union_pw_aff, pair>(res); +} + +template +typed::union_pw_multi_aff, pair> typed::union_map, pair>::as_union_pw_multi_aff() const +{ + auto res = isl::union_map::as_union_pw_multi_aff(); + return typed::union_pw_multi_aff, pair>(res); +} + +template +typed::union_set> typed::union_map, pair>::bind_range(const typed::multi_id> &tuple) const +{ + auto res = isl::union_map::bind_range(tuple); + return typed::union_set>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::coalesce() const +{ + auto res = isl::union_map::coalesce(); + return typed::union_map, pair>(res); +} + +template +typed::union_map>> typed::union_map, pair>::curry() const +{ + auto res = isl::union_map::curry(); + return typed::union_map>>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::detect_equalities() const +{ + auto res = isl::union_map::detect_equalities(); + return typed::union_map, pair>(res); +} + +template +typed::union_set> typed::union_map, pair>::domain() const +{ + auto res = isl::union_map::domain(); + return typed::union_set>(res); +} + +template +typed::union_map> typed::union_map, pair>::domain_factor_domain() const +{ + auto res = isl::union_map::domain_factor_domain(); + return typed::union_map>(res); +} + +template +typed::union_map> typed::union_map, pair>::domain_factor_range() const +{ + auto res = isl::union_map::domain_factor_range(); + return typed::union_map>(res); +} + +template +typed::union_map, pair>, pair> typed::union_map, pair>::domain_map() const +{ + auto res = isl::union_map::domain_map(); + return typed::union_map, pair>, pair>(res); +} + +template +typed::union_pw_multi_aff, pair>, pair> typed::union_map, pair>::domain_map_union_pw_multi_aff() const +{ + auto res = isl::union_map::domain_map_union_pw_multi_aff(); + return typed::union_pw_multi_aff, pair>, pair>(res); +} + +template +template +typed::union_map, Domain2>, pair> typed::union_map, pair>::domain_product(const typed::union_map> &umap2) const +{ + auto res = isl::union_map::domain_product(umap2); + return typed::union_map, Domain2>, pair>(res); +} + +template +template +typed::union_map, Domain2>, pair> typed::union_map, pair>::domain_product(const typed::basic_map> &umap2) const +{ + auto res = isl::union_map::domain_product(umap2); + return typed::union_map, Domain2>, pair>(res); +} + +template +template +typed::union_map, Domain2>, pair> typed::union_map, pair>::domain_product(const typed::map> &umap2) const +{ + auto res = isl::union_map::domain_product(umap2); + return typed::union_map, Domain2>, pair>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::domain_reverse() const +{ + auto res = isl::union_map::domain_reverse(); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::drop_unused_params() const +{ + auto res = isl::union_map::drop_unused_params(); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::empty(const isl::ctx &ctx) +{ + auto res = isl::union_map::empty(ctx); + return typed::union_map, pair>(res); +} + +template +bool typed::union_map, pair>::every_map(const std::function, pair>)> &test) const +{ + auto lambda_test = [&] (isl::map arg0) { + return test(typed::map, pair>(arg0)); + }; + return isl::union_map::every_map(lambda_test); +} + +template +typed::map, pair> typed::union_map, pair>::extract_map(const typed::space, pair> &space) const +{ + auto res = isl::union_map::extract_map(space); + return typed::map, pair>(res); +} + +template +void typed::union_map, pair>::foreach_map(const std::function, pair>)> &fn) const +{ + auto lambda_fn = [&] (isl::map arg0) { + return fn(typed::map, pair>(arg0)); + }; + return isl::union_map::foreach_map(lambda_fn); +} + +template +typed::union_map, pair> typed::union_map, pair>::gist(const typed::union_map, pair> &context) const +{ + auto res = isl::union_map::gist(context); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::gist(const typed::basic_map, pair> &context) const +{ + auto res = isl::union_map::gist(context); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::gist(const typed::map, pair> &context) const +{ + auto res = isl::union_map::gist(context); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::gist_domain(const typed::union_set> &uset) const +{ + auto res = isl::union_map::gist_domain(uset); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::gist_domain(const typed::basic_set> &uset) const +{ + auto res = isl::union_map::gist_domain(uset); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::gist_domain(const typed::point> &uset) const +{ + auto res = isl::union_map::gist_domain(uset); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::gist_domain(const typed::set> &uset) const +{ + auto res = isl::union_map::gist_domain(uset); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::gist_params(const typed::set<> &set) const +{ + auto res = isl::union_map::gist_params(set); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::gist_params(const typed::basic_set<> &set) const +{ + auto res = isl::union_map::gist_params(set); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::gist_params(const typed::point<> &set) const +{ + auto res = isl::union_map::gist_params(set); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::intersect(const typed::union_map, pair> &umap2) const +{ + auto res = isl::union_map::intersect(umap2); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::intersect(const typed::basic_map, pair> &umap2) const +{ + auto res = isl::union_map::intersect(umap2); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::intersect(const typed::map, pair> &umap2) const +{ + auto res = isl::union_map::intersect(umap2); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::intersect_domain(const typed::space> &space) const +{ + auto res = isl::union_map::intersect_domain(space); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::intersect_domain(const typed::union_set> &uset) const +{ + auto res = isl::union_map::intersect_domain(uset); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::intersect_domain_wrapped_domain(const typed::union_set &domain) const +{ + auto res = isl::union_map::intersect_domain_wrapped_domain(domain); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::intersect_domain_wrapped_domain(const typed::basic_set &domain) const +{ + auto res = isl::union_map::intersect_domain_wrapped_domain(domain); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::intersect_domain_wrapped_domain(const typed::point &domain) const +{ + auto res = isl::union_map::intersect_domain_wrapped_domain(domain); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::intersect_domain_wrapped_domain(const typed::set &domain) const +{ + auto res = isl::union_map::intersect_domain_wrapped_domain(domain); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::intersect_params(const typed::set<> &set) const +{ + auto res = isl::union_map::intersect_params(set); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::intersect_params(const typed::basic_set<> &set) const +{ + auto res = isl::union_map::intersect_params(set); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::intersect_params(const typed::point<> &set) const +{ + auto res = isl::union_map::intersect_params(set); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::intersect_range(const typed::space> &space) const +{ + auto res = isl::union_map::intersect_range(space); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::intersect_range(const typed::union_set> &uset) const +{ + auto res = isl::union_map::intersect_range(uset); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::intersect_range_wrapped_domain(const typed::union_set &domain) const +{ + auto res = isl::union_map::intersect_range_wrapped_domain(domain); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::intersect_range_wrapped_domain(const typed::basic_set &domain) const +{ + auto res = isl::union_map::intersect_range_wrapped_domain(domain); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::intersect_range_wrapped_domain(const typed::point &domain) const +{ + auto res = isl::union_map::intersect_range_wrapped_domain(domain); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::intersect_range_wrapped_domain(const typed::set &domain) const +{ + auto res = isl::union_map::intersect_range_wrapped_domain(domain); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::lexmax() const +{ + auto res = isl::union_map::lexmax(); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::lexmin() const +{ + auto res = isl::union_map::lexmin(); + return typed::union_map, pair>(res); +} + +template +typed::map_list, pair> typed::union_map, pair>::map_list() const +{ + auto res = isl::union_map::map_list(); + return typed::map_list, pair>(res); +} + +template +typed::set<> typed::union_map, pair>::params() const +{ + auto res = isl::union_map::params(); + return typed::set<>(res); +} + +template +template +typed::union_map> typed::union_map, pair>::preimage_domain(const typed::multi_aff> &ma) const +{ + auto res = isl::union_map::preimage_domain(ma); + return typed::union_map>(res); +} + +template +template +typed::union_map> typed::union_map, pair>::preimage_domain(const typed::multi_pw_aff> &mpa) const +{ + auto res = isl::union_map::preimage_domain(mpa); + return typed::union_map>(res); +} + +template +template +typed::union_map> typed::union_map, pair>::preimage_domain(const typed::pw_multi_aff> &pma) const +{ + auto res = isl::union_map::preimage_domain(pma); + return typed::union_map>(res); +} + +template +template +typed::union_map> typed::union_map, pair>::preimage_domain(const typed::union_pw_multi_aff> &upma) const +{ + auto res = isl::union_map::preimage_domain(upma); + return typed::union_map>(res); +} + +template +template +typed::union_map, Arg2> typed::union_map, pair>::preimage_range(const typed::multi_aff> &ma) const +{ + auto res = isl::union_map::preimage_range(ma); + return typed::union_map, Arg2>(res); +} + +template +template +typed::union_map, Arg2> typed::union_map, pair>::preimage_range(const typed::pw_multi_aff> &pma) const +{ + auto res = isl::union_map::preimage_range(pma); + return typed::union_map, Arg2>(res); +} + +template +template +typed::union_map, Arg2> typed::union_map, pair>::preimage_range(const typed::union_pw_multi_aff> &upma) const +{ + auto res = isl::union_map::preimage_range(upma); + return typed::union_map, Arg2>(res); +} + +template +template +typed::union_map, Domain2>, pair, Arg2>> typed::union_map, pair>::product(const typed::union_map &umap2) const +{ + auto res = isl::union_map::product(umap2); + return typed::union_map, Domain2>, pair, Arg2>>(res); +} + +template +template +typed::union_map, Domain2>, pair, Arg2>> typed::union_map, pair>::product(const typed::basic_map &umap2) const +{ + auto res = isl::union_map::product(umap2); + return typed::union_map, Domain2>, pair, Arg2>>(res); +} + +template +template +typed::union_map, Domain2>, pair, Arg2>> typed::union_map, pair>::product(const typed::map &umap2) const +{ + auto res = isl::union_map::product(umap2); + return typed::union_map, Domain2>, pair, Arg2>>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::project_out_all_params() const +{ + auto res = isl::union_map::project_out_all_params(); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::project_out_param(const typed::id &id) const +{ + auto res = isl::union_map::project_out_param(id); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::project_out_param(const std::string &id) const +{ + auto res = isl::union_map::project_out_param(id); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::project_out_param(const typed::id_list &list) const +{ + auto res = isl::union_map::project_out_param(list); + return typed::union_map, pair>(res); +} + +template +typed::union_set> typed::union_map, pair>::range() const +{ + auto res = isl::union_map::range(); + return typed::union_set>(res); +} + +template +typed::union_map, Range> typed::union_map, pair>::range_factor_domain() const +{ + auto res = isl::union_map::range_factor_domain(); + return typed::union_map, Range>(res); +} + +template +typed::union_map, Range2> typed::union_map, pair>::range_factor_range() const +{ + auto res = isl::union_map::range_factor_range(); + return typed::union_map, Range2>(res); +} + +template +typed::union_map, pair>, pair> typed::union_map, pair>::range_map() const +{ + auto res = isl::union_map::range_map(); + return typed::union_map, pair>, pair>(res); +} + +template +template +typed::union_map, pair, Arg2>> typed::union_map, pair>::range_product(const typed::union_map, Arg2> &umap2) const +{ + auto res = isl::union_map::range_product(umap2); + return typed::union_map, pair, Arg2>>(res); +} + +template +template +typed::union_map, pair, Arg2>> typed::union_map, pair>::range_product(const typed::basic_map, Arg2> &umap2) const +{ + auto res = isl::union_map::range_product(umap2); + return typed::union_map, pair, Arg2>>(res); +} + +template +template +typed::union_map, pair, Arg2>> typed::union_map, pair>::range_product(const typed::map, Arg2> &umap2) const +{ + auto res = isl::union_map::range_product(umap2); + return typed::union_map, pair, Arg2>>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::range_reverse() const +{ + auto res = isl::union_map::range_reverse(); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::reverse() const +{ + auto res = isl::union_map::reverse(); + return typed::union_map, pair>(res); +} + +template +typed::space<> typed::union_map, pair>::space() const +{ + auto res = isl::union_map::space(); + return typed::space<>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::subtract(const typed::union_map, pair> &umap2) const +{ + auto res = isl::union_map::subtract(umap2); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::subtract(const typed::basic_map, pair> &umap2) const +{ + auto res = isl::union_map::subtract(umap2); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::subtract(const typed::map, pair> &umap2) const +{ + auto res = isl::union_map::subtract(umap2); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::subtract_domain(const typed::union_set> &dom) const +{ + auto res = isl::union_map::subtract_domain(dom); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::subtract_domain(const typed::basic_set> &dom) const +{ + auto res = isl::union_map::subtract_domain(dom); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::subtract_domain(const typed::point> &dom) const +{ + auto res = isl::union_map::subtract_domain(dom); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::subtract_domain(const typed::set> &dom) const +{ + auto res = isl::union_map::subtract_domain(dom); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::subtract_range(const typed::union_set> &dom) const +{ + auto res = isl::union_map::subtract_range(dom); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::subtract_range(const typed::basic_set> &dom) const +{ + auto res = isl::union_map::subtract_range(dom); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::subtract_range(const typed::point> &dom) const +{ + auto res = isl::union_map::subtract_range(dom); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::subtract_range(const typed::set> &dom) const +{ + auto res = isl::union_map::subtract_range(dom); + return typed::union_map, pair>(res); +} + +template +typed::union_map, Range>, Range2> typed::union_map, pair>::uncurry() const +{ + auto res = isl::union_map::uncurry(); + return typed::union_map, Range>, Range2>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::unite(const typed::union_map, pair> &umap2) const +{ + auto res = isl::union_map::unite(umap2); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::unite(const typed::basic_map, pair> &umap2) const +{ + auto res = isl::union_map::unite(umap2); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::unite(const typed::map, pair> &umap2) const +{ + auto res = isl::union_map::unite(umap2); + return typed::union_map, pair>(res); +} + +template +typed::union_map, pair> typed::union_map, pair>::universe() const +{ + auto res = isl::union_map::universe(); + return typed::union_map, pair>(res); +} + +template +typed::union_set, pair>> typed::union_map, pair>::wrap() const +{ + auto res = isl::union_map::wrap(); + return typed::union_set, pair>>(res); +} + +typed::union_pw_aff::union_pw_aff(const typed::aff &aff) + : isl::union_pw_aff(aff) +{ +} + +typed::union_pw_aff::union_pw_aff(const typed::pw_aff &pa) + : isl::union_pw_aff(pa) +{ +} + +typed::union_pw_aff::union_pw_aff(const isl::ctx &ctx, const std::string &str) + : isl::union_pw_aff(ctx, str) +{ +} + +typed::multi_union_pw_aff typed::union_pw_aff::add(const typed::multi_union_pw_aff &multi2) const +{ + auto res = isl::union_pw_aff::add(multi2); + return typed::multi_union_pw_aff(res); +} + +typed::union_pw_aff typed::union_pw_aff::add(const typed::union_pw_aff &upa2) const +{ + auto res = isl::union_pw_aff::add(upa2); + return typed::union_pw_aff(res); +} + +typed::union_pw_multi_aff typed::union_pw_aff::add(const typed::union_pw_multi_aff &upma2) const +{ + auto res = isl::union_pw_aff::add(upma2); + return typed::union_pw_multi_aff(res); +} + +typed::union_pw_aff typed::union_pw_aff::add(const typed::aff &upa2) const +{ + auto res = isl::union_pw_aff::add(upa2); + return typed::union_pw_aff(res); +} + +typed::union_pw_aff typed::union_pw_aff::add(const typed::pw_aff &upa2) const +{ + auto res = isl::union_pw_aff::add(upa2); + return typed::union_pw_aff(res); +} + +template +typed::union_pw_multi_aff typed::union_pw_aff::apply(const typed::union_pw_multi_aff &upma2) const +{ + auto res = isl::union_pw_aff::apply(upma2); + return typed::union_pw_multi_aff(res); +} + +typed::multi_union_pw_aff typed::union_pw_aff::as_multi_union_pw_aff() const +{ + auto res = isl::union_pw_aff::as_multi_union_pw_aff(); + return typed::multi_union_pw_aff(res); +} + +typed::pw_multi_aff typed::union_pw_aff::as_pw_multi_aff() const +{ + auto res = isl::union_pw_aff::as_pw_multi_aff(); + return typed::pw_multi_aff(res); +} + +typed::union_pw_aff typed::union_pw_aff::at(int pos) const +{ + auto res = isl::union_pw_aff::at(pos); + return typed::union_pw_aff(res); +} + +typed::union_set<> typed::union_pw_aff::bind(const typed::multi_id &tuple) const +{ + auto res = isl::union_pw_aff::bind(tuple); + return typed::union_set<>(res); +} + +typed::union_set<> typed::union_pw_aff::bind(const typed::id &id) const +{ + auto res = isl::union_pw_aff::bind(id); + return typed::union_set<>(res); +} + +typed::union_set<> typed::union_pw_aff::bind(const std::string &id) const +{ + auto res = isl::union_pw_aff::bind(id); + return typed::union_set<>(res); +} + +typed::union_pw_aff typed::union_pw_aff::coalesce() const +{ + auto res = isl::union_pw_aff::coalesce(); + return typed::union_pw_aff(res); +} + +typed::union_set<> typed::union_pw_aff::domain() const +{ + auto res = isl::union_pw_aff::domain(); + return typed::union_set<>(res); +} + +typed::union_pw_aff typed::union_pw_aff::drop_unused_params() const +{ + auto res = isl::union_pw_aff::drop_unused_params(); + return typed::union_pw_aff(res); +} + +typed::pw_multi_aff typed::union_pw_aff::extract_pw_multi_aff(const typed::space &space) const +{ + auto res = isl::union_pw_aff::extract_pw_multi_aff(space); + return typed::pw_multi_aff(res); +} + +typed::union_pw_aff typed::union_pw_aff::gist(const typed::union_set<> &context) const +{ + auto res = isl::union_pw_aff::gist(context); + return typed::union_pw_aff(res); +} + +typed::union_pw_aff typed::union_pw_aff::gist(const typed::basic_set<> &context) const +{ + auto res = isl::union_pw_aff::gist(context); + return typed::union_pw_aff(res); +} + +typed::union_pw_aff typed::union_pw_aff::gist(const typed::point<> &context) const +{ + auto res = isl::union_pw_aff::gist(context); + return typed::union_pw_aff(res); +} + +typed::union_pw_aff typed::union_pw_aff::gist(const typed::set<> &context) const +{ + auto res = isl::union_pw_aff::gist(context); + return typed::union_pw_aff(res); +} + +typed::multi_union_pw_aff typed::union_pw_aff::gist_params(const typed::set<> &context) const +{ + auto res = isl::union_pw_aff::gist_params(context); + return typed::multi_union_pw_aff(res); +} + +typed::union_pw_aff typed::union_pw_aff::intersect_params(const typed::set<> &set) const +{ + auto res = isl::union_pw_aff::intersect_params(set); + return typed::union_pw_aff(res); +} + +typed::union_pw_aff typed::union_pw_aff::intersect_params(const typed::basic_set<> &set) const +{ + auto res = isl::union_pw_aff::intersect_params(set); + return typed::union_pw_aff(res); +} + +typed::union_pw_aff typed::union_pw_aff::intersect_params(const typed::point<> &set) const +{ + auto res = isl::union_pw_aff::intersect_params(set); + return typed::union_pw_aff(res); +} + +typed::union_pw_aff_list typed::union_pw_aff::list() const +{ + auto res = isl::union_pw_aff::list(); + return typed::union_pw_aff_list(res); +} + +typed::multi_union_pw_aff typed::union_pw_aff::neg() const +{ + auto res = isl::union_pw_aff::neg(); + return typed::multi_union_pw_aff(res); +} + +typed::pw_multi_aff_list typed::union_pw_aff::pw_multi_aff_list() const +{ + auto res = isl::union_pw_aff::pw_multi_aff_list(); + return typed::pw_multi_aff_list(res); +} + +typed::multi_union_pw_aff typed::union_pw_aff::scale(const typed::multi_val &mv) const +{ + auto res = isl::union_pw_aff::scale(mv); + return typed::multi_union_pw_aff(res); +} + +typed::multi_union_pw_aff typed::union_pw_aff::scale(const typed::val &v) const +{ + auto res = isl::union_pw_aff::scale(v); + return typed::multi_union_pw_aff(res); +} + +typed::multi_union_pw_aff typed::union_pw_aff::scale(long v) const +{ + auto res = isl::union_pw_aff::scale(v); + return typed::multi_union_pw_aff(res); +} + +typed::multi_union_pw_aff typed::union_pw_aff::scale_down(const typed::multi_val &mv) const +{ + auto res = isl::union_pw_aff::scale_down(mv); + return typed::multi_union_pw_aff(res); +} + +typed::multi_union_pw_aff typed::union_pw_aff::scale_down(const typed::val &v) const +{ + auto res = isl::union_pw_aff::scale_down(v); + return typed::multi_union_pw_aff(res); +} + +typed::multi_union_pw_aff typed::union_pw_aff::scale_down(long v) const +{ + auto res = isl::union_pw_aff::scale_down(v); + return typed::multi_union_pw_aff(res); +} + +typed::multi_union_pw_aff typed::union_pw_aff::set_at(int pos, const typed::union_pw_aff &el) const +{ + auto res = isl::union_pw_aff::set_at(pos, el); + return typed::multi_union_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::union_pw_aff::set_range_tuple(const typed::id &id) const +{ + auto res = isl::union_pw_aff::set_range_tuple(id); + return typed::multi_union_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::union_pw_aff::set_range_tuple(const std::string &id) const +{ + auto res = isl::union_pw_aff::set_range_tuple(id); + return typed::multi_union_pw_aff(res); +} + +typed::space<> typed::union_pw_aff::space() const +{ + auto res = isl::union_pw_aff::space(); + return typed::space<>(res); +} + +typed::multi_union_pw_aff typed::union_pw_aff::sub(const typed::multi_union_pw_aff &multi2) const +{ + auto res = isl::union_pw_aff::sub(multi2); + return typed::multi_union_pw_aff(res); +} + +typed::union_pw_aff typed::union_pw_aff::sub(const typed::union_pw_aff &upa2) const +{ + auto res = isl::union_pw_aff::sub(upa2); + return typed::union_pw_aff(res); +} + +typed::union_pw_multi_aff typed::union_pw_aff::sub(const typed::union_pw_multi_aff &upma2) const +{ + auto res = isl::union_pw_aff::sub(upma2); + return typed::union_pw_multi_aff(res); +} + +typed::union_pw_aff typed::union_pw_aff::sub(const typed::aff &upa2) const +{ + auto res = isl::union_pw_aff::sub(upa2); + return typed::union_pw_aff(res); +} + +typed::union_pw_aff typed::union_pw_aff::sub(const typed::pw_aff &upa2) const +{ + auto res = isl::union_pw_aff::sub(upa2); + return typed::union_pw_aff(res); +} + +typed::multi_union_pw_aff typed::union_pw_aff::union_add(const typed::multi_union_pw_aff &mupa2) const +{ + auto res = isl::union_pw_aff::union_add(mupa2); + return typed::multi_union_pw_aff(res); +} + +typed::union_pw_aff typed::union_pw_aff::union_add(const typed::union_pw_aff &upa2) const +{ + auto res = isl::union_pw_aff::union_add(upa2); + return typed::union_pw_aff(res); +} + +typed::union_pw_multi_aff typed::union_pw_aff::union_add(const typed::union_pw_multi_aff &upma2) const +{ + auto res = isl::union_pw_aff::union_add(upma2); + return typed::union_pw_multi_aff(res); +} + +typed::union_pw_aff typed::union_pw_aff::union_add(const typed::aff &upa2) const +{ + auto res = isl::union_pw_aff::union_add(upa2); + return typed::union_pw_aff(res); +} + +typed::union_pw_aff typed::union_pw_aff::union_add(const typed::pw_aff &upa2) const +{ + auto res = isl::union_pw_aff::union_add(upa2); + return typed::union_pw_aff(res); +} + +template +typed::union_pw_aff::union_pw_aff(const typed::aff &aff) + : isl::union_pw_aff(aff) +{ +} + +template +typed::union_pw_aff::union_pw_aff(const typed::pw_aff &pa) + : isl::union_pw_aff(pa) +{ +} + +template +typed::union_pw_aff::union_pw_aff(const isl::ctx &ctx, const std::string &str) + : isl::union_pw_aff(ctx, str) +{ +} + +template +typed::multi_union_pw_aff typed::union_pw_aff::add(const typed::multi_union_pw_aff &multi2) const +{ + auto res = isl::union_pw_aff::add(multi2); + return typed::multi_union_pw_aff(res); +} + +template +typed::union_pw_aff typed::union_pw_aff::add(const typed::union_pw_aff &upa2) const +{ + auto res = isl::union_pw_aff::add(upa2); + return typed::union_pw_aff(res); +} + +template +typed::union_pw_multi_aff typed::union_pw_aff::add(const typed::union_pw_multi_aff &upma2) const +{ + auto res = isl::union_pw_aff::add(upma2); + return typed::union_pw_multi_aff(res); +} + +template +typed::union_pw_aff typed::union_pw_aff::add(const typed::aff &upa2) const +{ + auto res = isl::union_pw_aff::add(upa2); + return typed::union_pw_aff(res); +} + +template +typed::union_pw_aff typed::union_pw_aff::add(const typed::pw_aff &upa2) const +{ + auto res = isl::union_pw_aff::add(upa2); + return typed::union_pw_aff(res); +} + +template +template +typed::union_pw_multi_aff typed::union_pw_aff::apply(const typed::union_pw_multi_aff &upma2) const +{ + auto res = isl::union_pw_aff::apply(upma2); + return typed::union_pw_multi_aff(res); +} + +template +typed::multi_union_pw_aff typed::union_pw_aff::as_multi_union_pw_aff() const +{ + auto res = isl::union_pw_aff::as_multi_union_pw_aff(); + return typed::multi_union_pw_aff(res); +} + +template +typed::pw_multi_aff typed::union_pw_aff::as_pw_multi_aff() const +{ + auto res = isl::union_pw_aff::as_pw_multi_aff(); + return typed::pw_multi_aff(res); +} + +template +typed::union_map typed::union_pw_aff::as_union_map() const +{ + auto res = isl::union_pw_aff::as_union_map(); + return typed::union_map(res); +} + +template +typed::union_pw_aff typed::union_pw_aff::at(int pos) const +{ + auto res = isl::union_pw_aff::at(pos); + return typed::union_pw_aff(res); +} + +template +typed::union_set typed::union_pw_aff::bind(const typed::multi_id &tuple) const +{ + auto res = isl::union_pw_aff::bind(tuple); + return typed::union_set(res); +} + +template +typed::union_set typed::union_pw_aff::bind(const typed::id &id) const +{ + auto res = isl::union_pw_aff::bind(id); + return typed::union_set(res); +} + +template +typed::union_set typed::union_pw_aff::bind(const std::string &id) const +{ + auto res = isl::union_pw_aff::bind(id); + return typed::union_set(res); +} + +template +typed::union_pw_aff typed::union_pw_aff::coalesce() const +{ + auto res = isl::union_pw_aff::coalesce(); + return typed::union_pw_aff(res); +} + +template +typed::union_set typed::union_pw_aff::domain() const +{ + auto res = isl::union_pw_aff::domain(); + return typed::union_set(res); +} + +template +typed::union_pw_aff typed::union_pw_aff::drop_unused_params() const +{ + auto res = isl::union_pw_aff::drop_unused_params(); + return typed::union_pw_aff(res); +} + +template +typed::pw_multi_aff typed::union_pw_aff::extract_pw_multi_aff(const typed::space &space) const +{ + auto res = isl::union_pw_aff::extract_pw_multi_aff(space); + return typed::pw_multi_aff(res); +} + +template +typed::union_pw_aff typed::union_pw_aff::gist(const typed::union_set &context) const +{ + auto res = isl::union_pw_aff::gist(context); + return typed::union_pw_aff(res); +} + +template +typed::union_pw_aff typed::union_pw_aff::gist(const typed::basic_set &context) const +{ + auto res = isl::union_pw_aff::gist(context); + return typed::union_pw_aff(res); +} + +template +typed::union_pw_aff typed::union_pw_aff::gist(const typed::point &context) const +{ + auto res = isl::union_pw_aff::gist(context); + return typed::union_pw_aff(res); +} + +template +typed::union_pw_aff typed::union_pw_aff::gist(const typed::set &context) const +{ + auto res = isl::union_pw_aff::gist(context); + return typed::union_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::union_pw_aff::gist_params(const typed::set<> &context) const +{ + auto res = isl::union_pw_aff::gist_params(context); + return typed::multi_union_pw_aff(res); +} + +template +typed::union_pw_aff typed::union_pw_aff::intersect_domain(const typed::space &space) const +{ + auto res = isl::union_pw_aff::intersect_domain(space); + return typed::union_pw_aff(res); +} + +template +typed::union_pw_aff typed::union_pw_aff::intersect_domain(const typed::union_set &uset) const +{ + auto res = isl::union_pw_aff::intersect_domain(uset); + return typed::union_pw_aff(res); +} + +template +typed::union_pw_aff typed::union_pw_aff::intersect_params(const typed::set<> &set) const +{ + auto res = isl::union_pw_aff::intersect_params(set); + return typed::union_pw_aff(res); +} + +template +typed::union_pw_aff typed::union_pw_aff::intersect_params(const typed::basic_set<> &set) const +{ + auto res = isl::union_pw_aff::intersect_params(set); + return typed::union_pw_aff(res); +} + +template +typed::union_pw_aff typed::union_pw_aff::intersect_params(const typed::point<> &set) const +{ + auto res = isl::union_pw_aff::intersect_params(set); + return typed::union_pw_aff(res); +} + +template +typed::union_pw_aff_list typed::union_pw_aff::list() const +{ + auto res = isl::union_pw_aff::list(); + return typed::union_pw_aff_list(res); +} + +template +typed::multi_union_pw_aff typed::union_pw_aff::neg() const +{ + auto res = isl::union_pw_aff::neg(); + return typed::multi_union_pw_aff(res); +} + +template +template +typed::union_pw_aff typed::union_pw_aff::pullback(const typed::union_pw_multi_aff &upma) const +{ + auto res = isl::union_pw_aff::pullback(upma); + return typed::union_pw_aff(res); +} + +template +typed::union_pw_aff typed::union_pw_aff::pullback(const typed::union_pw_multi_aff &upma) const +{ + auto res = isl::union_pw_aff::pullback(upma); + return typed::union_pw_aff(res); +} + +template +template +typed::union_pw_aff typed::union_pw_aff::pullback(const typed::multi_aff &upma) const +{ + auto res = isl::union_pw_aff::pullback(upma); + return typed::union_pw_aff(res); +} + +template +typed::union_pw_aff typed::union_pw_aff::pullback(const typed::multi_aff &upma) const +{ + auto res = isl::union_pw_aff::pullback(upma); + return typed::union_pw_aff(res); +} + +template +template +typed::union_pw_aff typed::union_pw_aff::pullback(const typed::pw_multi_aff &upma) const +{ + auto res = isl::union_pw_aff::pullback(upma); + return typed::union_pw_aff(res); +} + +template +typed::union_pw_aff typed::union_pw_aff::pullback(const typed::pw_multi_aff &upma) const +{ + auto res = isl::union_pw_aff::pullback(upma); + return typed::union_pw_aff(res); +} + +template +template +typed::union_pw_aff typed::union_pw_aff::pullback(const typed::union_pw_aff &upma) const +{ + auto res = isl::union_pw_aff::pullback(upma); + return typed::union_pw_aff(res); +} + +template +typed::union_pw_aff typed::union_pw_aff::pullback(const typed::union_pw_aff &upma) const +{ + auto res = isl::union_pw_aff::pullback(upma); + return typed::union_pw_aff(res); +} + +template +typed::pw_multi_aff_list typed::union_pw_aff::pw_multi_aff_list() const +{ + auto res = isl::union_pw_aff::pw_multi_aff_list(); + return typed::pw_multi_aff_list(res); +} + +template +template +typed::multi_union_pw_aff> typed::union_pw_aff::range_product(const typed::multi_union_pw_aff &multi2) const +{ + auto res = isl::union_pw_aff::range_product(multi2); + return typed::multi_union_pw_aff>(res); +} + +template +template +typed::union_pw_multi_aff> typed::union_pw_aff::range_product(const typed::union_pw_multi_aff &upma2) const +{ + auto res = isl::union_pw_aff::range_product(upma2); + return typed::union_pw_multi_aff>(res); +} + +template +typed::multi_union_pw_aff typed::union_pw_aff::scale(const typed::multi_val &mv) const +{ + auto res = isl::union_pw_aff::scale(mv); + return typed::multi_union_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::union_pw_aff::scale(const typed::val &v) const +{ + auto res = isl::union_pw_aff::scale(v); + return typed::multi_union_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::union_pw_aff::scale(long v) const +{ + auto res = isl::union_pw_aff::scale(v); + return typed::multi_union_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::union_pw_aff::scale_down(const typed::multi_val &mv) const +{ + auto res = isl::union_pw_aff::scale_down(mv); + return typed::multi_union_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::union_pw_aff::scale_down(const typed::val &v) const +{ + auto res = isl::union_pw_aff::scale_down(v); + return typed::multi_union_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::union_pw_aff::scale_down(long v) const +{ + auto res = isl::union_pw_aff::scale_down(v); + return typed::multi_union_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::union_pw_aff::set_at(int pos, const typed::union_pw_aff &el) const +{ + auto res = isl::union_pw_aff::set_at(pos, el); + return typed::multi_union_pw_aff(res); +} + +template +template +typed::multi_union_pw_aff typed::union_pw_aff::set_range_tuple(const typed::id &id) const +{ + auto res = isl::union_pw_aff::set_range_tuple(id); + return typed::multi_union_pw_aff(res); +} + +template +template +typed::multi_union_pw_aff typed::union_pw_aff::set_range_tuple(const std::string &id) const +{ + auto res = isl::union_pw_aff::set_range_tuple(id); + return typed::multi_union_pw_aff(res); +} + +template +typed::space<> typed::union_pw_aff::space() const +{ + auto res = isl::union_pw_aff::space(); + return typed::space<>(res); +} + +template +typed::multi_union_pw_aff typed::union_pw_aff::sub(const typed::multi_union_pw_aff &multi2) const +{ + auto res = isl::union_pw_aff::sub(multi2); + return typed::multi_union_pw_aff(res); +} + +template +typed::union_pw_aff typed::union_pw_aff::sub(const typed::union_pw_aff &upa2) const +{ + auto res = isl::union_pw_aff::sub(upa2); + return typed::union_pw_aff(res); +} + +template +typed::union_pw_multi_aff typed::union_pw_aff::sub(const typed::union_pw_multi_aff &upma2) const +{ + auto res = isl::union_pw_aff::sub(upma2); + return typed::union_pw_multi_aff(res); +} + +template +typed::union_pw_aff typed::union_pw_aff::sub(const typed::aff &upa2) const +{ + auto res = isl::union_pw_aff::sub(upa2); + return typed::union_pw_aff(res); +} + +template +typed::union_pw_aff typed::union_pw_aff::sub(const typed::pw_aff &upa2) const +{ + auto res = isl::union_pw_aff::sub(upa2); + return typed::union_pw_aff(res); +} + +template +typed::union_pw_aff typed::union_pw_aff::subtract_domain(const typed::space &space) const +{ + auto res = isl::union_pw_aff::subtract_domain(space); + return typed::union_pw_aff(res); +} + +template +typed::union_pw_aff typed::union_pw_aff::subtract_domain(const typed::union_set &uset) const +{ + auto res = isl::union_pw_aff::subtract_domain(uset); + return typed::union_pw_aff(res); +} + +template +typed::multi_union_pw_aff typed::union_pw_aff::union_add(const typed::multi_union_pw_aff &mupa2) const +{ + auto res = isl::union_pw_aff::union_add(mupa2); + return typed::multi_union_pw_aff(res); +} + +template +typed::union_pw_aff typed::union_pw_aff::union_add(const typed::union_pw_aff &upa2) const +{ + auto res = isl::union_pw_aff::union_add(upa2); + return typed::union_pw_aff(res); +} + +template +typed::union_pw_multi_aff typed::union_pw_aff::union_add(const typed::union_pw_multi_aff &upma2) const +{ + auto res = isl::union_pw_aff::union_add(upma2); + return typed::union_pw_multi_aff(res); +} + +template +typed::union_pw_aff typed::union_pw_aff::union_add(const typed::aff &upa2) const +{ + auto res = isl::union_pw_aff::union_add(upa2); + return typed::union_pw_aff(res); +} + +template +typed::union_pw_aff typed::union_pw_aff::union_add(const typed::pw_aff &upa2) const +{ + auto res = isl::union_pw_aff::union_add(upa2); + return typed::union_pw_aff(res); +} + +template +typed::union_pw_aff, Anonymous>::union_pw_aff(const typed::aff, Anonymous> &aff) + : isl::union_pw_aff(aff) +{ +} + +template +typed::union_pw_aff, Anonymous>::union_pw_aff(const typed::pw_aff, Anonymous> &pa) + : isl::union_pw_aff(pa) +{ +} + +template +typed::union_pw_aff, Anonymous>::union_pw_aff(const isl::ctx &ctx, const std::string &str) + : isl::union_pw_aff(ctx, str) +{ +} + +template +typed::multi_union_pw_aff, Anonymous> typed::union_pw_aff, Anonymous>::add(const typed::multi_union_pw_aff, Anonymous> &multi2) const +{ + auto res = isl::union_pw_aff::add(multi2); + return typed::multi_union_pw_aff, Anonymous>(res); +} + +template +typed::union_pw_aff, Anonymous> typed::union_pw_aff, Anonymous>::add(const typed::union_pw_aff, Anonymous> &upa2) const +{ + auto res = isl::union_pw_aff::add(upa2); + return typed::union_pw_aff, Anonymous>(res); +} + +template +typed::union_pw_multi_aff, Anonymous> typed::union_pw_aff, Anonymous>::add(const typed::union_pw_multi_aff, Anonymous> &upma2) const +{ + auto res = isl::union_pw_aff::add(upma2); + return typed::union_pw_multi_aff, Anonymous>(res); +} + +template +typed::union_pw_aff, Anonymous> typed::union_pw_aff, Anonymous>::add(const typed::aff, Anonymous> &upa2) const +{ + auto res = isl::union_pw_aff::add(upa2); + return typed::union_pw_aff, Anonymous>(res); +} + +template +typed::union_pw_aff, Anonymous> typed::union_pw_aff, Anonymous>::add(const typed::pw_aff, Anonymous> &upa2) const +{ + auto res = isl::union_pw_aff::add(upa2); + return typed::union_pw_aff, Anonymous>(res); +} + +template +template +typed::union_pw_multi_aff, Range2> typed::union_pw_aff, Anonymous>::apply(const typed::union_pw_multi_aff &upma2) const +{ + auto res = isl::union_pw_aff::apply(upma2); + return typed::union_pw_multi_aff, Range2>(res); +} + +template +typed::multi_union_pw_aff, Anonymous> typed::union_pw_aff, Anonymous>::as_multi_union_pw_aff() const +{ + auto res = isl::union_pw_aff::as_multi_union_pw_aff(); + return typed::multi_union_pw_aff, Anonymous>(res); +} + +template +typed::pw_multi_aff, Anonymous> typed::union_pw_aff, Anonymous>::as_pw_multi_aff() const +{ + auto res = isl::union_pw_aff::as_pw_multi_aff(); + return typed::pw_multi_aff, Anonymous>(res); +} + +template +typed::union_map, Anonymous> typed::union_pw_aff, Anonymous>::as_union_map() const +{ + auto res = isl::union_pw_aff::as_union_map(); + return typed::union_map, Anonymous>(res); +} + +template +typed::union_pw_aff, Anonymous> typed::union_pw_aff, Anonymous>::at(int pos) const +{ + auto res = isl::union_pw_aff::at(pos); + return typed::union_pw_aff, Anonymous>(res); +} + +template +typed::union_set> typed::union_pw_aff, Anonymous>::bind(const typed::multi_id &tuple) const +{ + auto res = isl::union_pw_aff::bind(tuple); + return typed::union_set>(res); +} + +template +typed::union_set> typed::union_pw_aff, Anonymous>::bind(const typed::id &id) const +{ + auto res = isl::union_pw_aff::bind(id); + return typed::union_set>(res); +} + +template +typed::union_set> typed::union_pw_aff, Anonymous>::bind(const std::string &id) const +{ + auto res = isl::union_pw_aff::bind(id); + return typed::union_set>(res); +} + +template +typed::union_pw_aff, Anonymous> typed::union_pw_aff, Anonymous>::coalesce() const +{ + auto res = isl::union_pw_aff::coalesce(); + return typed::union_pw_aff, Anonymous>(res); +} + +template +typed::union_set> typed::union_pw_aff, Anonymous>::domain() const +{ + auto res = isl::union_pw_aff::domain(); + return typed::union_set>(res); +} + +template +typed::union_pw_aff, Anonymous> typed::union_pw_aff, Anonymous>::drop_unused_params() const +{ + auto res = isl::union_pw_aff::drop_unused_params(); + return typed::union_pw_aff, Anonymous>(res); +} + +template +typed::pw_multi_aff, Anonymous> typed::union_pw_aff, Anonymous>::extract_pw_multi_aff(const typed::space, Anonymous> &space) const +{ + auto res = isl::union_pw_aff::extract_pw_multi_aff(space); + return typed::pw_multi_aff, Anonymous>(res); +} + +template +typed::union_pw_aff, Anonymous> typed::union_pw_aff, Anonymous>::gist(const typed::union_set> &context) const +{ + auto res = isl::union_pw_aff::gist(context); + return typed::union_pw_aff, Anonymous>(res); +} + +template +typed::union_pw_aff, Anonymous> typed::union_pw_aff, Anonymous>::gist(const typed::basic_set> &context) const +{ + auto res = isl::union_pw_aff::gist(context); + return typed::union_pw_aff, Anonymous>(res); +} + +template +typed::union_pw_aff, Anonymous> typed::union_pw_aff, Anonymous>::gist(const typed::point> &context) const +{ + auto res = isl::union_pw_aff::gist(context); + return typed::union_pw_aff, Anonymous>(res); +} + +template +typed::union_pw_aff, Anonymous> typed::union_pw_aff, Anonymous>::gist(const typed::set> &context) const +{ + auto res = isl::union_pw_aff::gist(context); + return typed::union_pw_aff, Anonymous>(res); +} + +template +typed::multi_union_pw_aff, Anonymous> typed::union_pw_aff, Anonymous>::gist_params(const typed::set<> &context) const +{ + auto res = isl::union_pw_aff::gist_params(context); + return typed::multi_union_pw_aff, Anonymous>(res); +} + +template +typed::union_pw_aff, Anonymous> typed::union_pw_aff, Anonymous>::intersect_domain(const typed::space> &space) const +{ + auto res = isl::union_pw_aff::intersect_domain(space); + return typed::union_pw_aff, Anonymous>(res); +} + +template +typed::union_pw_aff, Anonymous> typed::union_pw_aff, Anonymous>::intersect_domain(const typed::union_set> &uset) const +{ + auto res = isl::union_pw_aff::intersect_domain(uset); + return typed::union_pw_aff, Anonymous>(res); +} + +template +typed::union_pw_aff, Anonymous> typed::union_pw_aff, Anonymous>::intersect_domain_wrapped_domain(const typed::union_set &uset) const +{ + auto res = isl::union_pw_aff::intersect_domain_wrapped_domain(uset); + return typed::union_pw_aff, Anonymous>(res); +} + +template +typed::union_pw_aff, Anonymous> typed::union_pw_aff, Anonymous>::intersect_domain_wrapped_domain(const typed::basic_set &uset) const +{ + auto res = isl::union_pw_aff::intersect_domain_wrapped_domain(uset); + return typed::union_pw_aff, Anonymous>(res); +} + +template +typed::union_pw_aff, Anonymous> typed::union_pw_aff, Anonymous>::intersect_domain_wrapped_domain(const typed::point &uset) const +{ + auto res = isl::union_pw_aff::intersect_domain_wrapped_domain(uset); + return typed::union_pw_aff, Anonymous>(res); +} + +template +typed::union_pw_aff, Anonymous> typed::union_pw_aff, Anonymous>::intersect_domain_wrapped_domain(const typed::set &uset) const +{ + auto res = isl::union_pw_aff::intersect_domain_wrapped_domain(uset); + return typed::union_pw_aff, Anonymous>(res); +} + +template +typed::union_pw_aff, Anonymous> typed::union_pw_aff, Anonymous>::intersect_params(const typed::set<> &set) const +{ + auto res = isl::union_pw_aff::intersect_params(set); + return typed::union_pw_aff, Anonymous>(res); +} + +template +typed::union_pw_aff, Anonymous> typed::union_pw_aff, Anonymous>::intersect_params(const typed::basic_set<> &set) const +{ + auto res = isl::union_pw_aff::intersect_params(set); + return typed::union_pw_aff, Anonymous>(res); +} + +template +typed::union_pw_aff, Anonymous> typed::union_pw_aff, Anonymous>::intersect_params(const typed::point<> &set) const +{ + auto res = isl::union_pw_aff::intersect_params(set); + return typed::union_pw_aff, Anonymous>(res); +} + +template +typed::union_pw_aff_list, Anonymous> typed::union_pw_aff, Anonymous>::list() const +{ + auto res = isl::union_pw_aff::list(); + return typed::union_pw_aff_list, Anonymous>(res); +} + +template +typed::multi_union_pw_aff, Anonymous> typed::union_pw_aff, Anonymous>::neg() const +{ + auto res = isl::union_pw_aff::neg(); + return typed::multi_union_pw_aff, Anonymous>(res); +} + +template +template +typed::union_pw_multi_aff, Anonymous> typed::union_pw_aff, Anonymous>::preimage_domain_wrapped_domain(const typed::union_pw_multi_aff &upma2) const +{ + auto res = isl::union_pw_aff::preimage_domain_wrapped_domain(upma2); + return typed::union_pw_multi_aff, Anonymous>(res); +} + +template +template +typed::union_pw_aff typed::union_pw_aff, Anonymous>::pullback(const typed::union_pw_multi_aff> &upma) const +{ + auto res = isl::union_pw_aff::pullback(upma); + return typed::union_pw_aff(res); +} + +template +typed::union_pw_aff typed::union_pw_aff, Anonymous>::pullback(const typed::union_pw_multi_aff> &upma) const +{ + auto res = isl::union_pw_aff::pullback(upma); + return typed::union_pw_aff(res); +} + +template +template +typed::union_pw_aff typed::union_pw_aff, Anonymous>::pullback(const typed::multi_aff> &upma) const +{ + auto res = isl::union_pw_aff::pullback(upma); + return typed::union_pw_aff(res); +} + +template +typed::union_pw_aff typed::union_pw_aff, Anonymous>::pullback(const typed::multi_aff> &upma) const +{ + auto res = isl::union_pw_aff::pullback(upma); + return typed::union_pw_aff(res); +} + +template +template +typed::union_pw_aff typed::union_pw_aff, Anonymous>::pullback(const typed::pw_multi_aff> &upma) const +{ + auto res = isl::union_pw_aff::pullback(upma); + return typed::union_pw_aff(res); +} + +template +typed::union_pw_aff typed::union_pw_aff, Anonymous>::pullback(const typed::pw_multi_aff> &upma) const +{ + auto res = isl::union_pw_aff::pullback(upma); + return typed::union_pw_aff(res); +} + +template +template +typed::union_pw_aff typed::union_pw_aff, Anonymous>::pullback(const typed::union_pw_aff> &upma) const +{ + auto res = isl::union_pw_aff::pullback(upma); + return typed::union_pw_aff(res); +} + +template +typed::union_pw_aff typed::union_pw_aff, Anonymous>::pullback(const typed::union_pw_aff> &upma) const +{ + auto res = isl::union_pw_aff::pullback(upma); + return typed::union_pw_aff(res); +} + +template +typed::pw_multi_aff_list, Anonymous> typed::union_pw_aff, Anonymous>::pw_multi_aff_list() const +{ + auto res = isl::union_pw_aff::pw_multi_aff_list(); + return typed::pw_multi_aff_list, Anonymous>(res); +} + +template +template +typed::multi_union_pw_aff, pair> typed::union_pw_aff, Anonymous>::range_product(const typed::multi_union_pw_aff, Range2> &multi2) const +{ + auto res = isl::union_pw_aff::range_product(multi2); + return typed::multi_union_pw_aff, pair>(res); +} + +template +template +typed::union_pw_multi_aff, pair> typed::union_pw_aff, Anonymous>::range_product(const typed::union_pw_multi_aff, Range2> &upma2) const +{ + auto res = isl::union_pw_aff::range_product(upma2); + return typed::union_pw_multi_aff, pair>(res); +} + +template +typed::multi_union_pw_aff, Anonymous> typed::union_pw_aff, Anonymous>::scale(const typed::multi_val &mv) const +{ + auto res = isl::union_pw_aff::scale(mv); + return typed::multi_union_pw_aff, Anonymous>(res); +} + +template +typed::multi_union_pw_aff, Anonymous> typed::union_pw_aff, Anonymous>::scale(const typed::val &v) const +{ + auto res = isl::union_pw_aff::scale(v); + return typed::multi_union_pw_aff, Anonymous>(res); +} + +template +typed::multi_union_pw_aff, Anonymous> typed::union_pw_aff, Anonymous>::scale(long v) const +{ + auto res = isl::union_pw_aff::scale(v); + return typed::multi_union_pw_aff, Anonymous>(res); +} + +template +typed::multi_union_pw_aff, Anonymous> typed::union_pw_aff, Anonymous>::scale_down(const typed::multi_val &mv) const +{ + auto res = isl::union_pw_aff::scale_down(mv); + return typed::multi_union_pw_aff, Anonymous>(res); +} + +template +typed::multi_union_pw_aff, Anonymous> typed::union_pw_aff, Anonymous>::scale_down(const typed::val &v) const +{ + auto res = isl::union_pw_aff::scale_down(v); + return typed::multi_union_pw_aff, Anonymous>(res); +} + +template +typed::multi_union_pw_aff, Anonymous> typed::union_pw_aff, Anonymous>::scale_down(long v) const +{ + auto res = isl::union_pw_aff::scale_down(v); + return typed::multi_union_pw_aff, Anonymous>(res); +} + +template +typed::multi_union_pw_aff, Anonymous> typed::union_pw_aff, Anonymous>::set_at(int pos, const typed::union_pw_aff, Anonymous> &el) const +{ + auto res = isl::union_pw_aff::set_at(pos, el); + return typed::multi_union_pw_aff, Anonymous>(res); +} + +template +template +typed::multi_union_pw_aff, Range2> typed::union_pw_aff, Anonymous>::set_range_tuple(const typed::id &id) const +{ + auto res = isl::union_pw_aff::set_range_tuple(id); + return typed::multi_union_pw_aff, Range2>(res); +} + +template +template +typed::multi_union_pw_aff, Range2> typed::union_pw_aff, Anonymous>::set_range_tuple(const std::string &id) const +{ + auto res = isl::union_pw_aff::set_range_tuple(id); + return typed::multi_union_pw_aff, Range2>(res); +} + +template +typed::space<> typed::union_pw_aff, Anonymous>::space() const +{ + auto res = isl::union_pw_aff::space(); + return typed::space<>(res); +} + +template +typed::multi_union_pw_aff, Anonymous> typed::union_pw_aff, Anonymous>::sub(const typed::multi_union_pw_aff, Anonymous> &multi2) const +{ + auto res = isl::union_pw_aff::sub(multi2); + return typed::multi_union_pw_aff, Anonymous>(res); +} + +template +typed::union_pw_aff, Anonymous> typed::union_pw_aff, Anonymous>::sub(const typed::union_pw_aff, Anonymous> &upa2) const +{ + auto res = isl::union_pw_aff::sub(upa2); + return typed::union_pw_aff, Anonymous>(res); +} + +template +typed::union_pw_multi_aff, Anonymous> typed::union_pw_aff, Anonymous>::sub(const typed::union_pw_multi_aff, Anonymous> &upma2) const +{ + auto res = isl::union_pw_aff::sub(upma2); + return typed::union_pw_multi_aff, Anonymous>(res); +} + +template +typed::union_pw_aff, Anonymous> typed::union_pw_aff, Anonymous>::sub(const typed::aff, Anonymous> &upa2) const +{ + auto res = isl::union_pw_aff::sub(upa2); + return typed::union_pw_aff, Anonymous>(res); +} + +template +typed::union_pw_aff, Anonymous> typed::union_pw_aff, Anonymous>::sub(const typed::pw_aff, Anonymous> &upa2) const +{ + auto res = isl::union_pw_aff::sub(upa2); + return typed::union_pw_aff, Anonymous>(res); +} + +template +typed::union_pw_aff, Anonymous> typed::union_pw_aff, Anonymous>::subtract_domain(const typed::space> &space) const +{ + auto res = isl::union_pw_aff::subtract_domain(space); + return typed::union_pw_aff, Anonymous>(res); +} + +template +typed::union_pw_aff, Anonymous> typed::union_pw_aff, Anonymous>::subtract_domain(const typed::union_set> &uset) const +{ + auto res = isl::union_pw_aff::subtract_domain(uset); + return typed::union_pw_aff, Anonymous>(res); +} + +template +typed::multi_union_pw_aff, Anonymous> typed::union_pw_aff, Anonymous>::union_add(const typed::multi_union_pw_aff, Anonymous> &mupa2) const +{ + auto res = isl::union_pw_aff::union_add(mupa2); + return typed::multi_union_pw_aff, Anonymous>(res); +} + +template +typed::union_pw_aff, Anonymous> typed::union_pw_aff, Anonymous>::union_add(const typed::union_pw_aff, Anonymous> &upa2) const +{ + auto res = isl::union_pw_aff::union_add(upa2); + return typed::union_pw_aff, Anonymous>(res); +} + +template +typed::union_pw_multi_aff, Anonymous> typed::union_pw_aff, Anonymous>::union_add(const typed::union_pw_multi_aff, Anonymous> &upma2) const +{ + auto res = isl::union_pw_aff::union_add(upma2); + return typed::union_pw_multi_aff, Anonymous>(res); +} + +template +typed::union_pw_aff, Anonymous> typed::union_pw_aff, Anonymous>::union_add(const typed::aff, Anonymous> &upa2) const +{ + auto res = isl::union_pw_aff::union_add(upa2); + return typed::union_pw_aff, Anonymous>(res); +} + +template +typed::union_pw_aff, Anonymous> typed::union_pw_aff, Anonymous>::union_add(const typed::pw_aff, Anonymous> &upa2) const +{ + auto res = isl::union_pw_aff::union_add(upa2); + return typed::union_pw_aff, Anonymous>(res); +} + +typed::union_pw_aff_list::union_pw_aff_list(const isl::ctx &ctx, int n) + : isl::union_pw_aff_list(ctx, n) +{ +} + +typed::union_pw_aff_list::union_pw_aff_list(const typed::union_pw_aff &el) + : isl::union_pw_aff_list(el) +{ +} + +typed::union_pw_aff_list::union_pw_aff_list(const isl::ctx &ctx, const std::string &str) + : isl::union_pw_aff_list(ctx, str) +{ +} + +typed::union_pw_aff_list typed::union_pw_aff_list::add(const typed::union_pw_aff &el) const +{ + auto res = isl::union_pw_aff_list::add(el); + return typed::union_pw_aff_list(res); +} + +typed::union_pw_aff_list typed::union_pw_aff_list::add(const typed::aff &el) const +{ + auto res = isl::union_pw_aff_list::add(el); + return typed::union_pw_aff_list(res); +} + +typed::union_pw_aff_list typed::union_pw_aff_list::add(const typed::pw_aff &el) const +{ + auto res = isl::union_pw_aff_list::add(el); + return typed::union_pw_aff_list(res); +} + +typed::union_pw_aff typed::union_pw_aff_list::at(int index) const +{ + auto res = isl::union_pw_aff_list::at(index); + return typed::union_pw_aff(res); +} + +typed::union_pw_aff_list typed::union_pw_aff_list::drop(unsigned int first, unsigned int n) const +{ + auto res = isl::union_pw_aff_list::drop(first, n); + return typed::union_pw_aff_list(res); +} + +void typed::union_pw_aff_list::foreach(const std::function)> &fn) const +{ + auto lambda_fn = [&] (isl::union_pw_aff arg0) { + return fn(typed::union_pw_aff(arg0)); + }; + return isl::union_pw_aff_list::foreach(lambda_fn); +} + +void typed::union_pw_aff_list::foreach_scc(const std::function, typed::union_pw_aff)> &follows, const std::function)> &fn) const +{ + auto lambda_follows = [&] (isl::union_pw_aff arg0, isl::union_pw_aff arg1) { + return follows(typed::union_pw_aff(arg0), typed::union_pw_aff(arg1)); + }; + auto lambda_fn = [&] (isl::union_pw_aff_list arg0) { + return fn(typed::union_pw_aff_list(arg0)); + }; + return isl::union_pw_aff_list::foreach_scc(lambda_follows, lambda_fn); +} + +typed::union_pw_aff_list typed::union_pw_aff_list::set_at(int index, const typed::union_pw_aff &el) const +{ + auto res = isl::union_pw_aff_list::set_at(index, el); + return typed::union_pw_aff_list(res); +} + +template +typed::union_pw_aff_list::union_pw_aff_list(const isl::ctx &ctx, int n) + : isl::union_pw_aff_list(ctx, n) +{ +} + +template +typed::union_pw_aff_list::union_pw_aff_list(const typed::union_pw_aff &el) + : isl::union_pw_aff_list(el) +{ +} + +template +typed::union_pw_aff_list::union_pw_aff_list(const isl::ctx &ctx, const std::string &str) + : isl::union_pw_aff_list(ctx, str) +{ +} + +template +typed::union_pw_aff_list typed::union_pw_aff_list::add(const typed::union_pw_aff &el) const +{ + auto res = isl::union_pw_aff_list::add(el); + return typed::union_pw_aff_list(res); +} + +template +typed::union_pw_aff_list typed::union_pw_aff_list::add(const typed::aff &el) const +{ + auto res = isl::union_pw_aff_list::add(el); + return typed::union_pw_aff_list(res); +} + +template +typed::union_pw_aff_list typed::union_pw_aff_list::add(const typed::pw_aff &el) const +{ + auto res = isl::union_pw_aff_list::add(el); + return typed::union_pw_aff_list(res); +} + +template +typed::union_pw_aff typed::union_pw_aff_list::at(int index) const +{ + auto res = isl::union_pw_aff_list::at(index); + return typed::union_pw_aff(res); +} + +template +typed::union_pw_aff_list typed::union_pw_aff_list::drop(unsigned int first, unsigned int n) const +{ + auto res = isl::union_pw_aff_list::drop(first, n); + return typed::union_pw_aff_list(res); +} + +template +void typed::union_pw_aff_list::foreach(const std::function)> &fn) const +{ + auto lambda_fn = [&] (isl::union_pw_aff arg0) { + return fn(typed::union_pw_aff(arg0)); + }; + return isl::union_pw_aff_list::foreach(lambda_fn); +} + +template +void typed::union_pw_aff_list::foreach_scc(const std::function, typed::union_pw_aff)> &follows, const std::function)> &fn) const +{ + auto lambda_follows = [&] (isl::union_pw_aff arg0, isl::union_pw_aff arg1) { + return follows(typed::union_pw_aff(arg0), typed::union_pw_aff(arg1)); + }; + auto lambda_fn = [&] (isl::union_pw_aff_list arg0) { + return fn(typed::union_pw_aff_list(arg0)); + }; + return isl::union_pw_aff_list::foreach_scc(lambda_follows, lambda_fn); +} + +template +typed::union_pw_aff_list typed::union_pw_aff_list::set_at(int index, const typed::union_pw_aff &el) const +{ + auto res = isl::union_pw_aff_list::set_at(index, el); + return typed::union_pw_aff_list(res); +} + +template +typed::union_pw_multi_aff::union_pw_multi_aff(const typed::multi_aff &ma) + : isl::union_pw_multi_aff(ma) +{ +} + +template +typed::union_pw_multi_aff::union_pw_multi_aff(const typed::pw_multi_aff &pma) + : isl::union_pw_multi_aff(pma) +{ +} + +template +typed::union_pw_multi_aff::union_pw_multi_aff(const typed::union_pw_aff &upa) + : isl::union_pw_multi_aff(upa) +{ +} + +template +typed::union_pw_multi_aff::union_pw_multi_aff(const isl::ctx &ctx, const std::string &str) + : isl::union_pw_multi_aff(ctx, str) +{ +} + +template +typed::union_pw_multi_aff typed::union_pw_multi_aff::add(const typed::union_pw_multi_aff &upma2) const +{ + auto res = isl::union_pw_multi_aff::add(upma2); + return typed::union_pw_multi_aff(res); +} + +template +typed::union_pw_multi_aff typed::union_pw_multi_aff::add(const typed::multi_aff &upma2) const +{ + auto res = isl::union_pw_multi_aff::add(upma2); + return typed::union_pw_multi_aff(res); +} + +template +typed::union_pw_multi_aff typed::union_pw_multi_aff::add(const typed::pw_multi_aff &upma2) const +{ + auto res = isl::union_pw_multi_aff::add(upma2); + return typed::union_pw_multi_aff(res); +} + +template +typed::union_pw_multi_aff typed::union_pw_multi_aff::add(const typed::union_pw_aff &upma2) const +{ + auto res = isl::union_pw_multi_aff::add(upma2); + return typed::union_pw_multi_aff(res); +} + +template +template +typed::union_pw_multi_aff typed::union_pw_multi_aff::apply(const typed::union_pw_multi_aff &upma2) const +{ + auto res = isl::union_pw_multi_aff::apply(upma2); + return typed::union_pw_multi_aff(res); +} + +template +template +typed::union_pw_multi_aff typed::union_pw_multi_aff::apply(const typed::multi_aff &upma2) const +{ + auto res = isl::union_pw_multi_aff::apply(upma2); + return typed::union_pw_multi_aff(res); +} + +template +template +typed::union_pw_multi_aff typed::union_pw_multi_aff::apply(const typed::pw_multi_aff &upma2) const +{ + auto res = isl::union_pw_multi_aff::apply(upma2); + return typed::union_pw_multi_aff(res); +} + +template +typed::union_pw_multi_aff typed::union_pw_multi_aff::apply(const typed::union_pw_aff &upma2) const +{ + auto res = isl::union_pw_multi_aff::apply(upma2); + return typed::union_pw_multi_aff(res); +} + +template +typed::multi_union_pw_aff typed::union_pw_multi_aff::as_multi_union_pw_aff() const +{ + auto res = isl::union_pw_multi_aff::as_multi_union_pw_aff(); + return typed::multi_union_pw_aff(res); +} + +template +typed::pw_multi_aff typed::union_pw_multi_aff::as_pw_multi_aff() const +{ + auto res = isl::union_pw_multi_aff::as_pw_multi_aff(); + return typed::pw_multi_aff(res); +} + +template +typed::union_pw_multi_aff typed::union_pw_multi_aff::coalesce() const +{ + auto res = isl::union_pw_multi_aff::coalesce(); + return typed::union_pw_multi_aff(res); +} + +template +typed::union_set<> typed::union_pw_multi_aff::domain() const +{ + auto res = isl::union_pw_multi_aff::domain(); + return typed::union_set<>(res); +} + +template +typed::union_pw_multi_aff typed::union_pw_multi_aff::drop_unused_params() const +{ + auto res = isl::union_pw_multi_aff::drop_unused_params(); + return typed::union_pw_multi_aff(res); +} + +template +typed::union_pw_multi_aff typed::union_pw_multi_aff::empty(const isl::ctx &ctx) +{ + auto res = isl::union_pw_multi_aff::empty(ctx); + return typed::union_pw_multi_aff(res); +} + +template +typed::pw_multi_aff typed::union_pw_multi_aff::extract_pw_multi_aff(const typed::space &space) const +{ + auto res = isl::union_pw_multi_aff::extract_pw_multi_aff(space); + return typed::pw_multi_aff(res); +} + +template +typed::union_pw_multi_aff typed::union_pw_multi_aff::gist(const typed::union_set<> &context) const +{ + auto res = isl::union_pw_multi_aff::gist(context); + return typed::union_pw_multi_aff(res); +} + +template +typed::union_pw_multi_aff typed::union_pw_multi_aff::gist(const typed::basic_set<> &context) const +{ + auto res = isl::union_pw_multi_aff::gist(context); + return typed::union_pw_multi_aff(res); +} + +template +typed::union_pw_multi_aff typed::union_pw_multi_aff::gist(const typed::point<> &context) const +{ + auto res = isl::union_pw_multi_aff::gist(context); + return typed::union_pw_multi_aff(res); +} + +template +typed::union_pw_multi_aff typed::union_pw_multi_aff::gist(const typed::set<> &context) const +{ + auto res = isl::union_pw_multi_aff::gist(context); + return typed::union_pw_multi_aff(res); +} + +template +typed::union_pw_multi_aff typed::union_pw_multi_aff::intersect_params(const typed::set<> &set) const +{ + auto res = isl::union_pw_multi_aff::intersect_params(set); + return typed::union_pw_multi_aff(res); +} + +template +typed::union_pw_multi_aff typed::union_pw_multi_aff::intersect_params(const typed::basic_set<> &set) const +{ + auto res = isl::union_pw_multi_aff::intersect_params(set); + return typed::union_pw_multi_aff(res); +} + +template +typed::union_pw_multi_aff typed::union_pw_multi_aff::intersect_params(const typed::point<> &set) const +{ + auto res = isl::union_pw_multi_aff::intersect_params(set); + return typed::union_pw_multi_aff(res); +} + +template +typed::pw_multi_aff_list typed::union_pw_multi_aff::pw_multi_aff_list() const +{ + auto res = isl::union_pw_multi_aff::pw_multi_aff_list(); + return typed::pw_multi_aff_list(res); +} + +template +typed::space<> typed::union_pw_multi_aff::space() const +{ + auto res = isl::union_pw_multi_aff::space(); + return typed::space<>(res); +} + +template +typed::union_pw_multi_aff typed::union_pw_multi_aff::sub(const typed::union_pw_multi_aff &upma2) const +{ + auto res = isl::union_pw_multi_aff::sub(upma2); + return typed::union_pw_multi_aff(res); +} + +template +typed::union_pw_multi_aff typed::union_pw_multi_aff::sub(const typed::multi_aff &upma2) const +{ + auto res = isl::union_pw_multi_aff::sub(upma2); + return typed::union_pw_multi_aff(res); +} + +template +typed::union_pw_multi_aff typed::union_pw_multi_aff::sub(const typed::pw_multi_aff &upma2) const +{ + auto res = isl::union_pw_multi_aff::sub(upma2); + return typed::union_pw_multi_aff(res); +} + +template +typed::union_pw_multi_aff typed::union_pw_multi_aff::sub(const typed::union_pw_aff &upma2) const +{ + auto res = isl::union_pw_multi_aff::sub(upma2); + return typed::union_pw_multi_aff(res); +} + +template +typed::union_pw_multi_aff typed::union_pw_multi_aff::union_add(const typed::union_pw_multi_aff &upma2) const +{ + auto res = isl::union_pw_multi_aff::union_add(upma2); + return typed::union_pw_multi_aff(res); +} + +template +typed::union_pw_multi_aff typed::union_pw_multi_aff::union_add(const typed::multi_aff &upma2) const +{ + auto res = isl::union_pw_multi_aff::union_add(upma2); + return typed::union_pw_multi_aff(res); +} + +template +typed::union_pw_multi_aff typed::union_pw_multi_aff::union_add(const typed::pw_multi_aff &upma2) const +{ + auto res = isl::union_pw_multi_aff::union_add(upma2); + return typed::union_pw_multi_aff(res); +} + +template +typed::union_pw_multi_aff typed::union_pw_multi_aff::union_add(const typed::union_pw_aff &upma2) const +{ + auto res = isl::union_pw_multi_aff::union_add(upma2); + return typed::union_pw_multi_aff(res); +} + +template +typed::union_pw_multi_aff::union_pw_multi_aff(const typed::multi_aff &ma) + : isl::union_pw_multi_aff(ma) +{ +} + +template +typed::union_pw_multi_aff::union_pw_multi_aff(const typed::pw_multi_aff &pma) + : isl::union_pw_multi_aff(pma) +{ +} + +template +typed::union_pw_multi_aff::union_pw_multi_aff(const typed::union_pw_aff &upa) + : isl::union_pw_multi_aff(upa) +{ +} + +template +typed::union_pw_multi_aff::union_pw_multi_aff(const isl::ctx &ctx, const std::string &str) + : isl::union_pw_multi_aff(ctx, str) +{ +} + +template +typed::union_pw_multi_aff typed::union_pw_multi_aff::add(const typed::union_pw_multi_aff &upma2) const +{ + auto res = isl::union_pw_multi_aff::add(upma2); + return typed::union_pw_multi_aff(res); +} + +template +typed::union_pw_multi_aff typed::union_pw_multi_aff::add(const typed::multi_aff &upma2) const +{ + auto res = isl::union_pw_multi_aff::add(upma2); + return typed::union_pw_multi_aff(res); +} + +template +typed::union_pw_multi_aff typed::union_pw_multi_aff::add(const typed::pw_multi_aff &upma2) const +{ + auto res = isl::union_pw_multi_aff::add(upma2); + return typed::union_pw_multi_aff(res); +} + +template +typed::union_pw_multi_aff typed::union_pw_multi_aff::add(const typed::union_pw_aff &upma2) const +{ + auto res = isl::union_pw_multi_aff::add(upma2); + return typed::union_pw_multi_aff(res); +} + +template +template +typed::union_pw_multi_aff typed::union_pw_multi_aff::apply(const typed::union_pw_multi_aff &upma2) const +{ + auto res = isl::union_pw_multi_aff::apply(upma2); + return typed::union_pw_multi_aff(res); +} + +template +template +typed::union_pw_multi_aff typed::union_pw_multi_aff::apply(const typed::multi_aff &upma2) const +{ + auto res = isl::union_pw_multi_aff::apply(upma2); + return typed::union_pw_multi_aff(res); +} + +template +template +typed::union_pw_multi_aff typed::union_pw_multi_aff::apply(const typed::pw_multi_aff &upma2) const +{ + auto res = isl::union_pw_multi_aff::apply(upma2); + return typed::union_pw_multi_aff(res); +} + +template +typed::union_pw_multi_aff typed::union_pw_multi_aff::apply(const typed::union_pw_aff &upma2) const +{ + auto res = isl::union_pw_multi_aff::apply(upma2); + return typed::union_pw_multi_aff(res); +} + +template +typed::multi_union_pw_aff typed::union_pw_multi_aff::as_multi_union_pw_aff() const +{ + auto res = isl::union_pw_multi_aff::as_multi_union_pw_aff(); + return typed::multi_union_pw_aff(res); +} + +template +typed::pw_multi_aff typed::union_pw_multi_aff::as_pw_multi_aff() const +{ + auto res = isl::union_pw_multi_aff::as_pw_multi_aff(); + return typed::pw_multi_aff(res); +} + +template +typed::union_map typed::union_pw_multi_aff::as_union_map() const +{ + auto res = isl::union_pw_multi_aff::as_union_map(); + return typed::union_map(res); +} + +template +typed::union_pw_multi_aff typed::union_pw_multi_aff::coalesce() const +{ + auto res = isl::union_pw_multi_aff::coalesce(); + return typed::union_pw_multi_aff(res); +} + +template +typed::union_set typed::union_pw_multi_aff::domain() const +{ + auto res = isl::union_pw_multi_aff::domain(); + return typed::union_set(res); +} + +template +typed::union_pw_multi_aff typed::union_pw_multi_aff::drop_unused_params() const +{ + auto res = isl::union_pw_multi_aff::drop_unused_params(); + return typed::union_pw_multi_aff(res); +} + +template +typed::union_pw_multi_aff typed::union_pw_multi_aff::empty(const isl::ctx &ctx) +{ + auto res = isl::union_pw_multi_aff::empty(ctx); + return typed::union_pw_multi_aff(res); +} + +template +typed::pw_multi_aff typed::union_pw_multi_aff::extract_pw_multi_aff(const typed::space &space) const +{ + auto res = isl::union_pw_multi_aff::extract_pw_multi_aff(space); + return typed::pw_multi_aff(res); +} + +template +typed::union_pw_multi_aff typed::union_pw_multi_aff::gist(const typed::union_set &context) const +{ + auto res = isl::union_pw_multi_aff::gist(context); + return typed::union_pw_multi_aff(res); +} + +template +typed::union_pw_multi_aff typed::union_pw_multi_aff::gist(const typed::basic_set &context) const +{ + auto res = isl::union_pw_multi_aff::gist(context); + return typed::union_pw_multi_aff(res); +} + +template +typed::union_pw_multi_aff typed::union_pw_multi_aff::gist(const typed::point &context) const +{ + auto res = isl::union_pw_multi_aff::gist(context); + return typed::union_pw_multi_aff(res); +} + +template +typed::union_pw_multi_aff typed::union_pw_multi_aff::gist(const typed::set &context) const +{ + auto res = isl::union_pw_multi_aff::gist(context); + return typed::union_pw_multi_aff(res); +} + +template +typed::union_pw_multi_aff typed::union_pw_multi_aff::intersect_domain(const typed::space &space) const +{ + auto res = isl::union_pw_multi_aff::intersect_domain(space); + return typed::union_pw_multi_aff(res); +} + +template +typed::union_pw_multi_aff typed::union_pw_multi_aff::intersect_domain(const typed::union_set &uset) const +{ + auto res = isl::union_pw_multi_aff::intersect_domain(uset); + return typed::union_pw_multi_aff(res); +} + +template +typed::union_pw_multi_aff typed::union_pw_multi_aff::intersect_params(const typed::set<> &set) const +{ + auto res = isl::union_pw_multi_aff::intersect_params(set); + return typed::union_pw_multi_aff(res); +} + +template +typed::union_pw_multi_aff typed::union_pw_multi_aff::intersect_params(const typed::basic_set<> &set) const +{ + auto res = isl::union_pw_multi_aff::intersect_params(set); + return typed::union_pw_multi_aff(res); +} + +template +typed::union_pw_multi_aff typed::union_pw_multi_aff::intersect_params(const typed::point<> &set) const +{ + auto res = isl::union_pw_multi_aff::intersect_params(set); + return typed::union_pw_multi_aff(res); +} + +template +template +typed::union_pw_multi_aff typed::union_pw_multi_aff::pullback(const typed::union_pw_multi_aff &upma2) const +{ + auto res = isl::union_pw_multi_aff::pullback(upma2); + return typed::union_pw_multi_aff(res); +} + +template +typed::union_pw_multi_aff typed::union_pw_multi_aff::pullback(const typed::union_pw_multi_aff &upma2) const +{ + auto res = isl::union_pw_multi_aff::pullback(upma2); + return typed::union_pw_multi_aff(res); +} + +template +template +typed::union_pw_multi_aff typed::union_pw_multi_aff::pullback(const typed::multi_aff &upma2) const +{ + auto res = isl::union_pw_multi_aff::pullback(upma2); + return typed::union_pw_multi_aff(res); +} + +template +typed::union_pw_multi_aff typed::union_pw_multi_aff::pullback(const typed::multi_aff &upma2) const +{ + auto res = isl::union_pw_multi_aff::pullback(upma2); + return typed::union_pw_multi_aff(res); +} + +template +template +typed::union_pw_multi_aff typed::union_pw_multi_aff::pullback(const typed::pw_multi_aff &upma2) const +{ + auto res = isl::union_pw_multi_aff::pullback(upma2); + return typed::union_pw_multi_aff(res); +} + +template +typed::union_pw_multi_aff typed::union_pw_multi_aff::pullback(const typed::pw_multi_aff &upma2) const +{ + auto res = isl::union_pw_multi_aff::pullback(upma2); + return typed::union_pw_multi_aff(res); +} + +template +template +typed::union_pw_multi_aff typed::union_pw_multi_aff::pullback(const typed::union_pw_aff &upma2) const +{ + auto res = isl::union_pw_multi_aff::pullback(upma2); + return typed::union_pw_multi_aff(res); +} + +template +typed::union_pw_multi_aff typed::union_pw_multi_aff::pullback(const typed::union_pw_aff &upma2) const +{ + auto res = isl::union_pw_multi_aff::pullback(upma2); + return typed::union_pw_multi_aff(res); +} + +template +typed::pw_multi_aff_list typed::union_pw_multi_aff::pw_multi_aff_list() const +{ + auto res = isl::union_pw_multi_aff::pw_multi_aff_list(); + return typed::pw_multi_aff_list(res); +} + +template +template +typed::union_pw_multi_aff> typed::union_pw_multi_aff::range_product(const typed::union_pw_multi_aff &upma2) const +{ + auto res = isl::union_pw_multi_aff::range_product(upma2); + return typed::union_pw_multi_aff>(res); +} + +template +template +typed::union_pw_multi_aff> typed::union_pw_multi_aff::range_product(const typed::multi_aff &upma2) const +{ + auto res = isl::union_pw_multi_aff::range_product(upma2); + return typed::union_pw_multi_aff>(res); +} + +template +template +typed::union_pw_multi_aff> typed::union_pw_multi_aff::range_product(const typed::pw_multi_aff &upma2) const +{ + auto res = isl::union_pw_multi_aff::range_product(upma2); + return typed::union_pw_multi_aff>(res); +} + +template +typed::union_pw_multi_aff> typed::union_pw_multi_aff::range_product(const typed::union_pw_aff &upma2) const +{ + auto res = isl::union_pw_multi_aff::range_product(upma2); + return typed::union_pw_multi_aff>(res); +} + +template +typed::space<> typed::union_pw_multi_aff::space() const +{ + auto res = isl::union_pw_multi_aff::space(); + return typed::space<>(res); +} + +template +typed::union_pw_multi_aff typed::union_pw_multi_aff::sub(const typed::union_pw_multi_aff &upma2) const +{ + auto res = isl::union_pw_multi_aff::sub(upma2); + return typed::union_pw_multi_aff(res); +} + +template +typed::union_pw_multi_aff typed::union_pw_multi_aff::sub(const typed::multi_aff &upma2) const +{ + auto res = isl::union_pw_multi_aff::sub(upma2); + return typed::union_pw_multi_aff(res); +} + +template +typed::union_pw_multi_aff typed::union_pw_multi_aff::sub(const typed::pw_multi_aff &upma2) const +{ + auto res = isl::union_pw_multi_aff::sub(upma2); + return typed::union_pw_multi_aff(res); +} + +template +typed::union_pw_multi_aff typed::union_pw_multi_aff::sub(const typed::union_pw_aff &upma2) const +{ + auto res = isl::union_pw_multi_aff::sub(upma2); + return typed::union_pw_multi_aff(res); +} + +template +typed::union_pw_multi_aff typed::union_pw_multi_aff::subtract_domain(const typed::space &space) const +{ + auto res = isl::union_pw_multi_aff::subtract_domain(space); + return typed::union_pw_multi_aff(res); +} + +template +typed::union_pw_multi_aff typed::union_pw_multi_aff::subtract_domain(const typed::union_set &uset) const +{ + auto res = isl::union_pw_multi_aff::subtract_domain(uset); + return typed::union_pw_multi_aff(res); +} + +template +typed::union_pw_multi_aff typed::union_pw_multi_aff::union_add(const typed::union_pw_multi_aff &upma2) const +{ + auto res = isl::union_pw_multi_aff::union_add(upma2); + return typed::union_pw_multi_aff(res); +} + +template +typed::union_pw_multi_aff typed::union_pw_multi_aff::union_add(const typed::multi_aff &upma2) const +{ + auto res = isl::union_pw_multi_aff::union_add(upma2); + return typed::union_pw_multi_aff(res); +} + +template +typed::union_pw_multi_aff typed::union_pw_multi_aff::union_add(const typed::pw_multi_aff &upma2) const +{ + auto res = isl::union_pw_multi_aff::union_add(upma2); + return typed::union_pw_multi_aff(res); +} + +template +typed::union_pw_multi_aff typed::union_pw_multi_aff::union_add(const typed::union_pw_aff &upma2) const +{ + auto res = isl::union_pw_multi_aff::union_add(upma2); + return typed::union_pw_multi_aff(res); +} + +template +typed::union_pw_multi_aff, Range>::union_pw_multi_aff(const typed::multi_aff, Range> &ma) + : isl::union_pw_multi_aff(ma) +{ +} + +template +typed::union_pw_multi_aff, Range>::union_pw_multi_aff(const typed::pw_multi_aff, Range> &pma) + : isl::union_pw_multi_aff(pma) +{ +} + +template +typed::union_pw_multi_aff, Range>::union_pw_multi_aff(const typed::union_pw_aff, Range> &upa) + : isl::union_pw_multi_aff(upa) +{ +} + +template +typed::union_pw_multi_aff, Range>::union_pw_multi_aff(const isl::ctx &ctx, const std::string &str) + : isl::union_pw_multi_aff(ctx, str) +{ +} + +template +typed::union_pw_multi_aff, Range> typed::union_pw_multi_aff, Range>::add(const typed::union_pw_multi_aff, Range> &upma2) const +{ + auto res = isl::union_pw_multi_aff::add(upma2); + return typed::union_pw_multi_aff, Range>(res); +} + +template +typed::union_pw_multi_aff, Range> typed::union_pw_multi_aff, Range>::add(const typed::multi_aff, Range> &upma2) const +{ + auto res = isl::union_pw_multi_aff::add(upma2); + return typed::union_pw_multi_aff, Range>(res); +} + +template +typed::union_pw_multi_aff, Range> typed::union_pw_multi_aff, Range>::add(const typed::pw_multi_aff, Range> &upma2) const +{ + auto res = isl::union_pw_multi_aff::add(upma2); + return typed::union_pw_multi_aff, Range>(res); +} + +template +typed::union_pw_multi_aff, Range> typed::union_pw_multi_aff, Range>::add(const typed::union_pw_aff, Range> &upma2) const +{ + auto res = isl::union_pw_multi_aff::add(upma2); + return typed::union_pw_multi_aff, Range>(res); +} + +template +template +typed::union_pw_multi_aff, Range2> typed::union_pw_multi_aff, Range>::apply(const typed::union_pw_multi_aff &upma2) const +{ + auto res = isl::union_pw_multi_aff::apply(upma2); + return typed::union_pw_multi_aff, Range2>(res); +} + +template +template +typed::union_pw_multi_aff, Range2> typed::union_pw_multi_aff, Range>::apply(const typed::multi_aff &upma2) const +{ + auto res = isl::union_pw_multi_aff::apply(upma2); + return typed::union_pw_multi_aff, Range2>(res); +} + +template +template +typed::union_pw_multi_aff, Range2> typed::union_pw_multi_aff, Range>::apply(const typed::pw_multi_aff &upma2) const +{ + auto res = isl::union_pw_multi_aff::apply(upma2); + return typed::union_pw_multi_aff, Range2>(res); +} + +template +typed::union_pw_multi_aff, Anonymous> typed::union_pw_multi_aff, Range>::apply(const typed::union_pw_aff &upma2) const +{ + auto res = isl::union_pw_multi_aff::apply(upma2); + return typed::union_pw_multi_aff, Anonymous>(res); +} + +template +typed::multi_union_pw_aff, Range> typed::union_pw_multi_aff, Range>::as_multi_union_pw_aff() const +{ + auto res = isl::union_pw_multi_aff::as_multi_union_pw_aff(); + return typed::multi_union_pw_aff, Range>(res); +} + +template +typed::pw_multi_aff, Range> typed::union_pw_multi_aff, Range>::as_pw_multi_aff() const +{ + auto res = isl::union_pw_multi_aff::as_pw_multi_aff(); + return typed::pw_multi_aff, Range>(res); +} + +template +typed::union_map, Range> typed::union_pw_multi_aff, Range>::as_union_map() const +{ + auto res = isl::union_pw_multi_aff::as_union_map(); + return typed::union_map, Range>(res); +} + +template +typed::union_pw_multi_aff, Range> typed::union_pw_multi_aff, Range>::coalesce() const +{ + auto res = isl::union_pw_multi_aff::coalesce(); + return typed::union_pw_multi_aff, Range>(res); +} + +template +typed::union_set> typed::union_pw_multi_aff, Range>::domain() const +{ + auto res = isl::union_pw_multi_aff::domain(); + return typed::union_set>(res); +} + +template +typed::union_pw_multi_aff, Range> typed::union_pw_multi_aff, Range>::drop_unused_params() const +{ + auto res = isl::union_pw_multi_aff::drop_unused_params(); + return typed::union_pw_multi_aff, Range>(res); +} + +template +typed::union_pw_multi_aff, Range> typed::union_pw_multi_aff, Range>::empty(const isl::ctx &ctx) +{ + auto res = isl::union_pw_multi_aff::empty(ctx); + return typed::union_pw_multi_aff, Range>(res); +} + +template +typed::pw_multi_aff, Range> typed::union_pw_multi_aff, Range>::extract_pw_multi_aff(const typed::space, Range> &space) const +{ + auto res = isl::union_pw_multi_aff::extract_pw_multi_aff(space); + return typed::pw_multi_aff, Range>(res); +} + +template +typed::union_pw_multi_aff, Range> typed::union_pw_multi_aff, Range>::gist(const typed::union_set> &context) const +{ + auto res = isl::union_pw_multi_aff::gist(context); + return typed::union_pw_multi_aff, Range>(res); +} + +template +typed::union_pw_multi_aff, Range> typed::union_pw_multi_aff, Range>::gist(const typed::basic_set> &context) const +{ + auto res = isl::union_pw_multi_aff::gist(context); + return typed::union_pw_multi_aff, Range>(res); +} + +template +typed::union_pw_multi_aff, Range> typed::union_pw_multi_aff, Range>::gist(const typed::point> &context) const +{ + auto res = isl::union_pw_multi_aff::gist(context); + return typed::union_pw_multi_aff, Range>(res); +} + +template +typed::union_pw_multi_aff, Range> typed::union_pw_multi_aff, Range>::gist(const typed::set> &context) const +{ + auto res = isl::union_pw_multi_aff::gist(context); + return typed::union_pw_multi_aff, Range>(res); +} + +template +typed::union_pw_multi_aff, Range> typed::union_pw_multi_aff, Range>::intersect_domain(const typed::space> &space) const +{ + auto res = isl::union_pw_multi_aff::intersect_domain(space); + return typed::union_pw_multi_aff, Range>(res); +} + +template +typed::union_pw_multi_aff, Range> typed::union_pw_multi_aff, Range>::intersect_domain(const typed::union_set> &uset) const +{ + auto res = isl::union_pw_multi_aff::intersect_domain(uset); + return typed::union_pw_multi_aff, Range>(res); +} + +template +typed::union_pw_multi_aff, Range> typed::union_pw_multi_aff, Range>::intersect_domain_wrapped_domain(const typed::union_set &uset) const +{ + auto res = isl::union_pw_multi_aff::intersect_domain_wrapped_domain(uset); + return typed::union_pw_multi_aff, Range>(res); +} + +template +typed::union_pw_multi_aff, Range> typed::union_pw_multi_aff, Range>::intersect_domain_wrapped_domain(const typed::basic_set &uset) const +{ + auto res = isl::union_pw_multi_aff::intersect_domain_wrapped_domain(uset); + return typed::union_pw_multi_aff, Range>(res); +} + +template +typed::union_pw_multi_aff, Range> typed::union_pw_multi_aff, Range>::intersect_domain_wrapped_domain(const typed::point &uset) const +{ + auto res = isl::union_pw_multi_aff::intersect_domain_wrapped_domain(uset); + return typed::union_pw_multi_aff, Range>(res); +} + +template +typed::union_pw_multi_aff, Range> typed::union_pw_multi_aff, Range>::intersect_domain_wrapped_domain(const typed::set &uset) const +{ + auto res = isl::union_pw_multi_aff::intersect_domain_wrapped_domain(uset); + return typed::union_pw_multi_aff, Range>(res); +} + +template +typed::union_pw_multi_aff, Range> typed::union_pw_multi_aff, Range>::intersect_params(const typed::set<> &set) const +{ + auto res = isl::union_pw_multi_aff::intersect_params(set); + return typed::union_pw_multi_aff, Range>(res); +} + +template +typed::union_pw_multi_aff, Range> typed::union_pw_multi_aff, Range>::intersect_params(const typed::basic_set<> &set) const +{ + auto res = isl::union_pw_multi_aff::intersect_params(set); + return typed::union_pw_multi_aff, Range>(res); +} + +template +typed::union_pw_multi_aff, Range> typed::union_pw_multi_aff, Range>::intersect_params(const typed::point<> &set) const +{ + auto res = isl::union_pw_multi_aff::intersect_params(set); + return typed::union_pw_multi_aff, Range>(res); +} + +template +template +typed::union_pw_multi_aff, Range> typed::union_pw_multi_aff, Range>::preimage_domain_wrapped_domain(const typed::union_pw_multi_aff &upma2) const +{ + auto res = isl::union_pw_multi_aff::preimage_domain_wrapped_domain(upma2); + return typed::union_pw_multi_aff, Range>(res); +} + +template +template +typed::union_pw_multi_aff, Range> typed::union_pw_multi_aff, Range>::preimage_domain_wrapped_domain(const typed::multi_aff &upma2) const +{ + auto res = isl::union_pw_multi_aff::preimage_domain_wrapped_domain(upma2); + return typed::union_pw_multi_aff, Range>(res); +} + +template +template +typed::union_pw_multi_aff, Range> typed::union_pw_multi_aff, Range>::preimage_domain_wrapped_domain(const typed::pw_multi_aff &upma2) const +{ + auto res = isl::union_pw_multi_aff::preimage_domain_wrapped_domain(upma2); + return typed::union_pw_multi_aff, Range>(res); +} + +template +template +typed::union_pw_multi_aff, Range> typed::union_pw_multi_aff, Range>::preimage_domain_wrapped_domain(const typed::union_pw_aff &upma2) const +{ + auto res = isl::union_pw_multi_aff::preimage_domain_wrapped_domain(upma2); + return typed::union_pw_multi_aff, Range>(res); +} + +template +template +typed::union_pw_multi_aff typed::union_pw_multi_aff, Range>::pullback(const typed::union_pw_multi_aff> &upma2) const +{ + auto res = isl::union_pw_multi_aff::pullback(upma2); + return typed::union_pw_multi_aff(res); +} + +template +typed::union_pw_multi_aff typed::union_pw_multi_aff, Range>::pullback(const typed::union_pw_multi_aff> &upma2) const +{ + auto res = isl::union_pw_multi_aff::pullback(upma2); + return typed::union_pw_multi_aff(res); +} + +template +template +typed::union_pw_multi_aff typed::union_pw_multi_aff, Range>::pullback(const typed::multi_aff> &upma2) const +{ + auto res = isl::union_pw_multi_aff::pullback(upma2); + return typed::union_pw_multi_aff(res); +} + +template +typed::union_pw_multi_aff typed::union_pw_multi_aff, Range>::pullback(const typed::multi_aff> &upma2) const +{ + auto res = isl::union_pw_multi_aff::pullback(upma2); + return typed::union_pw_multi_aff(res); +} + +template +template +typed::union_pw_multi_aff typed::union_pw_multi_aff, Range>::pullback(const typed::pw_multi_aff> &upma2) const +{ + auto res = isl::union_pw_multi_aff::pullback(upma2); + return typed::union_pw_multi_aff(res); +} + +template +typed::union_pw_multi_aff typed::union_pw_multi_aff, Range>::pullback(const typed::pw_multi_aff> &upma2) const +{ + auto res = isl::union_pw_multi_aff::pullback(upma2); + return typed::union_pw_multi_aff(res); +} + +template +template +typed::union_pw_multi_aff typed::union_pw_multi_aff, Range>::pullback(const typed::union_pw_aff> &upma2) const +{ + auto res = isl::union_pw_multi_aff::pullback(upma2); + return typed::union_pw_multi_aff(res); +} + +template +typed::union_pw_multi_aff typed::union_pw_multi_aff, Range>::pullback(const typed::union_pw_aff> &upma2) const +{ + auto res = isl::union_pw_multi_aff::pullback(upma2); + return typed::union_pw_multi_aff(res); +} + +template +typed::pw_multi_aff_list, Range> typed::union_pw_multi_aff, Range>::pw_multi_aff_list() const +{ + auto res = isl::union_pw_multi_aff::pw_multi_aff_list(); + return typed::pw_multi_aff_list, Range>(res); +} + +template +template +typed::union_pw_multi_aff, pair> typed::union_pw_multi_aff, Range>::range_product(const typed::union_pw_multi_aff, Range2> &upma2) const +{ + auto res = isl::union_pw_multi_aff::range_product(upma2); + return typed::union_pw_multi_aff, pair>(res); +} + +template +template +typed::union_pw_multi_aff, pair> typed::union_pw_multi_aff, Range>::range_product(const typed::multi_aff, Range2> &upma2) const +{ + auto res = isl::union_pw_multi_aff::range_product(upma2); + return typed::union_pw_multi_aff, pair>(res); +} + +template +template +typed::union_pw_multi_aff, pair> typed::union_pw_multi_aff, Range>::range_product(const typed::pw_multi_aff, Range2> &upma2) const +{ + auto res = isl::union_pw_multi_aff::range_product(upma2); + return typed::union_pw_multi_aff, pair>(res); +} + +template +typed::union_pw_multi_aff, pair> typed::union_pw_multi_aff, Range>::range_product(const typed::union_pw_aff, Anonymous> &upma2) const +{ + auto res = isl::union_pw_multi_aff::range_product(upma2); + return typed::union_pw_multi_aff, pair>(res); +} + +template +typed::space<> typed::union_pw_multi_aff, Range>::space() const +{ + auto res = isl::union_pw_multi_aff::space(); + return typed::space<>(res); +} + +template +typed::union_pw_multi_aff, Range> typed::union_pw_multi_aff, Range>::sub(const typed::union_pw_multi_aff, Range> &upma2) const +{ + auto res = isl::union_pw_multi_aff::sub(upma2); + return typed::union_pw_multi_aff, Range>(res); +} + +template +typed::union_pw_multi_aff, Range> typed::union_pw_multi_aff, Range>::sub(const typed::multi_aff, Range> &upma2) const +{ + auto res = isl::union_pw_multi_aff::sub(upma2); + return typed::union_pw_multi_aff, Range>(res); +} + +template +typed::union_pw_multi_aff, Range> typed::union_pw_multi_aff, Range>::sub(const typed::pw_multi_aff, Range> &upma2) const +{ + auto res = isl::union_pw_multi_aff::sub(upma2); + return typed::union_pw_multi_aff, Range>(res); +} + +template +typed::union_pw_multi_aff, Range> typed::union_pw_multi_aff, Range>::sub(const typed::union_pw_aff, Range> &upma2) const +{ + auto res = isl::union_pw_multi_aff::sub(upma2); + return typed::union_pw_multi_aff, Range>(res); +} + +template +typed::union_pw_multi_aff, Range> typed::union_pw_multi_aff, Range>::subtract_domain(const typed::space> &space) const +{ + auto res = isl::union_pw_multi_aff::subtract_domain(space); + return typed::union_pw_multi_aff, Range>(res); +} + +template +typed::union_pw_multi_aff, Range> typed::union_pw_multi_aff, Range>::subtract_domain(const typed::union_set> &uset) const +{ + auto res = isl::union_pw_multi_aff::subtract_domain(uset); + return typed::union_pw_multi_aff, Range>(res); +} + +template +typed::union_pw_multi_aff, Range> typed::union_pw_multi_aff, Range>::union_add(const typed::union_pw_multi_aff, Range> &upma2) const +{ + auto res = isl::union_pw_multi_aff::union_add(upma2); + return typed::union_pw_multi_aff, Range>(res); +} + +template +typed::union_pw_multi_aff, Range> typed::union_pw_multi_aff, Range>::union_add(const typed::multi_aff, Range> &upma2) const +{ + auto res = isl::union_pw_multi_aff::union_add(upma2); + return typed::union_pw_multi_aff, Range>(res); +} + +template +typed::union_pw_multi_aff, Range> typed::union_pw_multi_aff, Range>::union_add(const typed::pw_multi_aff, Range> &upma2) const +{ + auto res = isl::union_pw_multi_aff::union_add(upma2); + return typed::union_pw_multi_aff, Range>(res); +} + +template +typed::union_pw_multi_aff, Range> typed::union_pw_multi_aff, Range>::union_add(const typed::union_pw_aff, Range> &upma2) const +{ + auto res = isl::union_pw_multi_aff::union_add(upma2); + return typed::union_pw_multi_aff, Range>(res); +} + +template +typed::union_pw_multi_aff>::union_pw_multi_aff(const typed::multi_aff> &ma) + : isl::union_pw_multi_aff(ma) +{ +} + +template +typed::union_pw_multi_aff>::union_pw_multi_aff(const typed::pw_multi_aff> &pma) + : isl::union_pw_multi_aff(pma) +{ +} + +template +typed::union_pw_multi_aff>::union_pw_multi_aff(const typed::union_pw_aff> &upa) + : isl::union_pw_multi_aff(upa) +{ +} + +template +typed::union_pw_multi_aff>::union_pw_multi_aff(const isl::ctx &ctx, const std::string &str) + : isl::union_pw_multi_aff(ctx, str) +{ +} + +template +typed::union_pw_multi_aff> typed::union_pw_multi_aff>::add(const typed::union_pw_multi_aff> &upma2) const +{ + auto res = isl::union_pw_multi_aff::add(upma2); + return typed::union_pw_multi_aff>(res); +} + +template +typed::union_pw_multi_aff> typed::union_pw_multi_aff>::add(const typed::multi_aff> &upma2) const +{ + auto res = isl::union_pw_multi_aff::add(upma2); + return typed::union_pw_multi_aff>(res); +} + +template +typed::union_pw_multi_aff> typed::union_pw_multi_aff>::add(const typed::pw_multi_aff> &upma2) const +{ + auto res = isl::union_pw_multi_aff::add(upma2); + return typed::union_pw_multi_aff>(res); +} + +template +typed::union_pw_multi_aff> typed::union_pw_multi_aff>::add(const typed::union_pw_aff> &upma2) const +{ + auto res = isl::union_pw_multi_aff::add(upma2); + return typed::union_pw_multi_aff>(res); +} + +template +template +typed::union_pw_multi_aff typed::union_pw_multi_aff>::apply(const typed::union_pw_multi_aff, Arg3> &upma2) const +{ + auto res = isl::union_pw_multi_aff::apply(upma2); + return typed::union_pw_multi_aff(res); +} + +template +template +typed::union_pw_multi_aff typed::union_pw_multi_aff>::apply(const typed::multi_aff, Arg3> &upma2) const +{ + auto res = isl::union_pw_multi_aff::apply(upma2); + return typed::union_pw_multi_aff(res); +} + +template +template +typed::union_pw_multi_aff typed::union_pw_multi_aff>::apply(const typed::pw_multi_aff, Arg3> &upma2) const +{ + auto res = isl::union_pw_multi_aff::apply(upma2); + return typed::union_pw_multi_aff(res); +} + +template +typed::union_pw_multi_aff typed::union_pw_multi_aff>::apply(const typed::union_pw_aff, Anonymous> &upma2) const +{ + auto res = isl::union_pw_multi_aff::apply(upma2); + return typed::union_pw_multi_aff(res); +} + +template +typed::multi_union_pw_aff> typed::union_pw_multi_aff>::as_multi_union_pw_aff() const +{ + auto res = isl::union_pw_multi_aff::as_multi_union_pw_aff(); + return typed::multi_union_pw_aff>(res); +} + +template +typed::pw_multi_aff> typed::union_pw_multi_aff>::as_pw_multi_aff() const +{ + auto res = isl::union_pw_multi_aff::as_pw_multi_aff(); + return typed::pw_multi_aff>(res); +} + +template +typed::union_map> typed::union_pw_multi_aff>::as_union_map() const +{ + auto res = isl::union_pw_multi_aff::as_union_map(); + return typed::union_map>(res); +} + +template +typed::union_pw_multi_aff> typed::union_pw_multi_aff>::coalesce() const +{ + auto res = isl::union_pw_multi_aff::coalesce(); + return typed::union_pw_multi_aff>(res); +} + +template +typed::union_set typed::union_pw_multi_aff>::domain() const +{ + auto res = isl::union_pw_multi_aff::domain(); + return typed::union_set(res); +} + +template +typed::union_pw_multi_aff> typed::union_pw_multi_aff>::drop_unused_params() const +{ + auto res = isl::union_pw_multi_aff::drop_unused_params(); + return typed::union_pw_multi_aff>(res); +} + +template +typed::union_pw_multi_aff> typed::union_pw_multi_aff>::empty(const isl::ctx &ctx) +{ + auto res = isl::union_pw_multi_aff::empty(ctx); + return typed::union_pw_multi_aff>(res); +} + +template +typed::pw_multi_aff> typed::union_pw_multi_aff>::extract_pw_multi_aff(const typed::space> &space) const +{ + auto res = isl::union_pw_multi_aff::extract_pw_multi_aff(space); + return typed::pw_multi_aff>(res); +} + +template +typed::union_pw_multi_aff> typed::union_pw_multi_aff>::gist(const typed::union_set &context) const +{ + auto res = isl::union_pw_multi_aff::gist(context); + return typed::union_pw_multi_aff>(res); +} + +template +typed::union_pw_multi_aff> typed::union_pw_multi_aff>::gist(const typed::basic_set &context) const +{ + auto res = isl::union_pw_multi_aff::gist(context); + return typed::union_pw_multi_aff>(res); +} + +template +typed::union_pw_multi_aff> typed::union_pw_multi_aff>::gist(const typed::point &context) const +{ + auto res = isl::union_pw_multi_aff::gist(context); + return typed::union_pw_multi_aff>(res); +} + +template +typed::union_pw_multi_aff> typed::union_pw_multi_aff>::gist(const typed::set &context) const +{ + auto res = isl::union_pw_multi_aff::gist(context); + return typed::union_pw_multi_aff>(res); +} + +template +typed::union_pw_multi_aff> typed::union_pw_multi_aff>::intersect_domain(const typed::space &space) const +{ + auto res = isl::union_pw_multi_aff::intersect_domain(space); + return typed::union_pw_multi_aff>(res); +} + +template +typed::union_pw_multi_aff> typed::union_pw_multi_aff>::intersect_domain(const typed::union_set &uset) const +{ + auto res = isl::union_pw_multi_aff::intersect_domain(uset); + return typed::union_pw_multi_aff>(res); +} + +template +typed::union_pw_multi_aff> typed::union_pw_multi_aff>::intersect_params(const typed::set<> &set) const +{ + auto res = isl::union_pw_multi_aff::intersect_params(set); + return typed::union_pw_multi_aff>(res); +} + +template +typed::union_pw_multi_aff> typed::union_pw_multi_aff>::intersect_params(const typed::basic_set<> &set) const +{ + auto res = isl::union_pw_multi_aff::intersect_params(set); + return typed::union_pw_multi_aff>(res); +} + +template +typed::union_pw_multi_aff> typed::union_pw_multi_aff>::intersect_params(const typed::point<> &set) const +{ + auto res = isl::union_pw_multi_aff::intersect_params(set); + return typed::union_pw_multi_aff>(res); +} + +template +template +typed::union_pw_multi_aff> typed::union_pw_multi_aff>::pullback(const typed::union_pw_multi_aff &upma2) const +{ + auto res = isl::union_pw_multi_aff::pullback(upma2); + return typed::union_pw_multi_aff>(res); +} + +template +typed::union_pw_multi_aff> typed::union_pw_multi_aff>::pullback(const typed::union_pw_multi_aff &upma2) const +{ + auto res = isl::union_pw_multi_aff::pullback(upma2); + return typed::union_pw_multi_aff>(res); +} + +template +template +typed::union_pw_multi_aff> typed::union_pw_multi_aff>::pullback(const typed::multi_aff &upma2) const +{ + auto res = isl::union_pw_multi_aff::pullback(upma2); + return typed::union_pw_multi_aff>(res); +} + +template +typed::union_pw_multi_aff> typed::union_pw_multi_aff>::pullback(const typed::multi_aff &upma2) const +{ + auto res = isl::union_pw_multi_aff::pullback(upma2); + return typed::union_pw_multi_aff>(res); +} + +template +template +typed::union_pw_multi_aff> typed::union_pw_multi_aff>::pullback(const typed::pw_multi_aff &upma2) const +{ + auto res = isl::union_pw_multi_aff::pullback(upma2); + return typed::union_pw_multi_aff>(res); +} + +template +typed::union_pw_multi_aff> typed::union_pw_multi_aff>::pullback(const typed::pw_multi_aff &upma2) const +{ + auto res = isl::union_pw_multi_aff::pullback(upma2); + return typed::union_pw_multi_aff>(res); +} + +template +template +typed::union_pw_multi_aff> typed::union_pw_multi_aff>::pullback(const typed::union_pw_aff &upma2) const +{ + auto res = isl::union_pw_multi_aff::pullback(upma2); + return typed::union_pw_multi_aff>(res); +} + +template +typed::union_pw_multi_aff> typed::union_pw_multi_aff>::pullback(const typed::union_pw_aff &upma2) const +{ + auto res = isl::union_pw_multi_aff::pullback(upma2); + return typed::union_pw_multi_aff>(res); +} + +template +typed::pw_multi_aff_list> typed::union_pw_multi_aff>::pw_multi_aff_list() const +{ + auto res = isl::union_pw_multi_aff::pw_multi_aff_list(); + return typed::pw_multi_aff_list>(res); +} + +template +typed::union_pw_multi_aff typed::union_pw_multi_aff>::range_factor_domain() const +{ + auto res = isl::union_pw_multi_aff::range_factor_domain(); + return typed::union_pw_multi_aff(res); +} + +template +typed::union_pw_multi_aff typed::union_pw_multi_aff>::range_factor_range() const +{ + auto res = isl::union_pw_multi_aff::range_factor_range(); + return typed::union_pw_multi_aff(res); +} + +template +template +typed::union_pw_multi_aff, Arg3>> typed::union_pw_multi_aff>::range_product(const typed::union_pw_multi_aff &upma2) const +{ + auto res = isl::union_pw_multi_aff::range_product(upma2); + return typed::union_pw_multi_aff, Arg3>>(res); +} + +template +template +typed::union_pw_multi_aff, Arg3>> typed::union_pw_multi_aff>::range_product(const typed::multi_aff &upma2) const +{ + auto res = isl::union_pw_multi_aff::range_product(upma2); + return typed::union_pw_multi_aff, Arg3>>(res); +} + +template +template +typed::union_pw_multi_aff, Arg3>> typed::union_pw_multi_aff>::range_product(const typed::pw_multi_aff &upma2) const +{ + auto res = isl::union_pw_multi_aff::range_product(upma2); + return typed::union_pw_multi_aff, Arg3>>(res); +} + +template +typed::union_pw_multi_aff, Anonymous>> typed::union_pw_multi_aff>::range_product(const typed::union_pw_aff &upma2) const +{ + auto res = isl::union_pw_multi_aff::range_product(upma2); + return typed::union_pw_multi_aff, Anonymous>>(res); +} + +template +typed::space<> typed::union_pw_multi_aff>::space() const +{ + auto res = isl::union_pw_multi_aff::space(); + return typed::space<>(res); +} + +template +typed::union_pw_multi_aff> typed::union_pw_multi_aff>::sub(const typed::union_pw_multi_aff> &upma2) const +{ + auto res = isl::union_pw_multi_aff::sub(upma2); + return typed::union_pw_multi_aff>(res); +} + +template +typed::union_pw_multi_aff> typed::union_pw_multi_aff>::sub(const typed::multi_aff> &upma2) const +{ + auto res = isl::union_pw_multi_aff::sub(upma2); + return typed::union_pw_multi_aff>(res); +} + +template +typed::union_pw_multi_aff> typed::union_pw_multi_aff>::sub(const typed::pw_multi_aff> &upma2) const +{ + auto res = isl::union_pw_multi_aff::sub(upma2); + return typed::union_pw_multi_aff>(res); +} + +template +typed::union_pw_multi_aff> typed::union_pw_multi_aff>::sub(const typed::union_pw_aff> &upma2) const +{ + auto res = isl::union_pw_multi_aff::sub(upma2); + return typed::union_pw_multi_aff>(res); +} + +template +typed::union_pw_multi_aff> typed::union_pw_multi_aff>::subtract_domain(const typed::space &space) const +{ + auto res = isl::union_pw_multi_aff::subtract_domain(space); + return typed::union_pw_multi_aff>(res); +} + +template +typed::union_pw_multi_aff> typed::union_pw_multi_aff>::subtract_domain(const typed::union_set &uset) const +{ + auto res = isl::union_pw_multi_aff::subtract_domain(uset); + return typed::union_pw_multi_aff>(res); +} + +template +typed::union_pw_multi_aff> typed::union_pw_multi_aff>::union_add(const typed::union_pw_multi_aff> &upma2) const +{ + auto res = isl::union_pw_multi_aff::union_add(upma2); + return typed::union_pw_multi_aff>(res); +} + +template +typed::union_pw_multi_aff> typed::union_pw_multi_aff>::union_add(const typed::multi_aff> &upma2) const +{ + auto res = isl::union_pw_multi_aff::union_add(upma2); + return typed::union_pw_multi_aff>(res); +} + +template +typed::union_pw_multi_aff> typed::union_pw_multi_aff>::union_add(const typed::pw_multi_aff> &upma2) const +{ + auto res = isl::union_pw_multi_aff::union_add(upma2); + return typed::union_pw_multi_aff>(res); +} + +template +typed::union_pw_multi_aff> typed::union_pw_multi_aff>::union_add(const typed::union_pw_aff> &upma2) const +{ + auto res = isl::union_pw_multi_aff::union_add(upma2); + return typed::union_pw_multi_aff>(res); +} + +template +typed::union_pw_multi_aff, pair>::union_pw_multi_aff(const typed::multi_aff, pair> &ma) + : isl::union_pw_multi_aff(ma) +{ +} + +template +typed::union_pw_multi_aff, pair>::union_pw_multi_aff(const typed::pw_multi_aff, pair> &pma) + : isl::union_pw_multi_aff(pma) +{ +} + +template +typed::union_pw_multi_aff, pair>::union_pw_multi_aff(const typed::union_pw_aff, pair> &upa) + : isl::union_pw_multi_aff(upa) +{ +} + +template +typed::union_pw_multi_aff, pair>::union_pw_multi_aff(const isl::ctx &ctx, const std::string &str) + : isl::union_pw_multi_aff(ctx, str) +{ +} + +template +typed::union_pw_multi_aff, pair> typed::union_pw_multi_aff, pair>::add(const typed::union_pw_multi_aff, pair> &upma2) const +{ + auto res = isl::union_pw_multi_aff::add(upma2); + return typed::union_pw_multi_aff, pair>(res); +} + +template +typed::union_pw_multi_aff, pair> typed::union_pw_multi_aff, pair>::add(const typed::multi_aff, pair> &upma2) const +{ + auto res = isl::union_pw_multi_aff::add(upma2); + return typed::union_pw_multi_aff, pair>(res); +} + +template +typed::union_pw_multi_aff, pair> typed::union_pw_multi_aff, pair>::add(const typed::pw_multi_aff, pair> &upma2) const +{ + auto res = isl::union_pw_multi_aff::add(upma2); + return typed::union_pw_multi_aff, pair>(res); +} + +template +typed::union_pw_multi_aff, pair> typed::union_pw_multi_aff, pair>::add(const typed::union_pw_aff, pair> &upma2) const +{ + auto res = isl::union_pw_multi_aff::add(upma2); + return typed::union_pw_multi_aff, pair>(res); +} + +template +template +typed::union_pw_multi_aff, Arg2> typed::union_pw_multi_aff, pair>::apply(const typed::union_pw_multi_aff, Arg2> &upma2) const +{ + auto res = isl::union_pw_multi_aff::apply(upma2); + return typed::union_pw_multi_aff, Arg2>(res); +} + +template +template +typed::union_pw_multi_aff, Arg2> typed::union_pw_multi_aff, pair>::apply(const typed::multi_aff, Arg2> &upma2) const +{ + auto res = isl::union_pw_multi_aff::apply(upma2); + return typed::union_pw_multi_aff, Arg2>(res); +} + +template +template +typed::union_pw_multi_aff, Arg2> typed::union_pw_multi_aff, pair>::apply(const typed::pw_multi_aff, Arg2> &upma2) const +{ + auto res = isl::union_pw_multi_aff::apply(upma2); + return typed::union_pw_multi_aff, Arg2>(res); +} + +template +typed::union_pw_multi_aff, Anonymous> typed::union_pw_multi_aff, pair>::apply(const typed::union_pw_aff, Anonymous> &upma2) const +{ + auto res = isl::union_pw_multi_aff::apply(upma2); + return typed::union_pw_multi_aff, Anonymous>(res); +} + +template +typed::multi_union_pw_aff, pair> typed::union_pw_multi_aff, pair>::as_multi_union_pw_aff() const +{ + auto res = isl::union_pw_multi_aff::as_multi_union_pw_aff(); + return typed::multi_union_pw_aff, pair>(res); +} + +template +typed::pw_multi_aff, pair> typed::union_pw_multi_aff, pair>::as_pw_multi_aff() const +{ + auto res = isl::union_pw_multi_aff::as_pw_multi_aff(); + return typed::pw_multi_aff, pair>(res); +} + +template +typed::union_map, pair> typed::union_pw_multi_aff, pair>::as_union_map() const +{ + auto res = isl::union_pw_multi_aff::as_union_map(); + return typed::union_map, pair>(res); +} + +template +typed::union_pw_multi_aff, pair> typed::union_pw_multi_aff, pair>::coalesce() const +{ + auto res = isl::union_pw_multi_aff::coalesce(); + return typed::union_pw_multi_aff, pair>(res); +} + +template +typed::union_set> typed::union_pw_multi_aff, pair>::domain() const +{ + auto res = isl::union_pw_multi_aff::domain(); + return typed::union_set>(res); +} + +template +typed::union_pw_multi_aff, pair> typed::union_pw_multi_aff, pair>::drop_unused_params() const +{ + auto res = isl::union_pw_multi_aff::drop_unused_params(); + return typed::union_pw_multi_aff, pair>(res); +} + +template +typed::union_pw_multi_aff, pair> typed::union_pw_multi_aff, pair>::empty(const isl::ctx &ctx) +{ + auto res = isl::union_pw_multi_aff::empty(ctx); + return typed::union_pw_multi_aff, pair>(res); +} + +template +typed::pw_multi_aff, pair> typed::union_pw_multi_aff, pair>::extract_pw_multi_aff(const typed::space, pair> &space) const +{ + auto res = isl::union_pw_multi_aff::extract_pw_multi_aff(space); + return typed::pw_multi_aff, pair>(res); +} + +template +typed::union_pw_multi_aff, pair> typed::union_pw_multi_aff, pair>::gist(const typed::union_set> &context) const +{ + auto res = isl::union_pw_multi_aff::gist(context); + return typed::union_pw_multi_aff, pair>(res); +} + +template +typed::union_pw_multi_aff, pair> typed::union_pw_multi_aff, pair>::gist(const typed::basic_set> &context) const +{ + auto res = isl::union_pw_multi_aff::gist(context); + return typed::union_pw_multi_aff, pair>(res); +} + +template +typed::union_pw_multi_aff, pair> typed::union_pw_multi_aff, pair>::gist(const typed::point> &context) const +{ + auto res = isl::union_pw_multi_aff::gist(context); + return typed::union_pw_multi_aff, pair>(res); +} + +template +typed::union_pw_multi_aff, pair> typed::union_pw_multi_aff, pair>::gist(const typed::set> &context) const +{ + auto res = isl::union_pw_multi_aff::gist(context); + return typed::union_pw_multi_aff, pair>(res); +} + +template +typed::union_pw_multi_aff, pair> typed::union_pw_multi_aff, pair>::intersect_domain(const typed::space> &space) const +{ + auto res = isl::union_pw_multi_aff::intersect_domain(space); + return typed::union_pw_multi_aff, pair>(res); +} + +template +typed::union_pw_multi_aff, pair> typed::union_pw_multi_aff, pair>::intersect_domain(const typed::union_set> &uset) const +{ + auto res = isl::union_pw_multi_aff::intersect_domain(uset); + return typed::union_pw_multi_aff, pair>(res); +} + +template +typed::union_pw_multi_aff, pair> typed::union_pw_multi_aff, pair>::intersect_domain_wrapped_domain(const typed::union_set &uset) const +{ + auto res = isl::union_pw_multi_aff::intersect_domain_wrapped_domain(uset); + return typed::union_pw_multi_aff, pair>(res); +} + +template +typed::union_pw_multi_aff, pair> typed::union_pw_multi_aff, pair>::intersect_domain_wrapped_domain(const typed::basic_set &uset) const +{ + auto res = isl::union_pw_multi_aff::intersect_domain_wrapped_domain(uset); + return typed::union_pw_multi_aff, pair>(res); +} + +template +typed::union_pw_multi_aff, pair> typed::union_pw_multi_aff, pair>::intersect_domain_wrapped_domain(const typed::point &uset) const +{ + auto res = isl::union_pw_multi_aff::intersect_domain_wrapped_domain(uset); + return typed::union_pw_multi_aff, pair>(res); +} + +template +typed::union_pw_multi_aff, pair> typed::union_pw_multi_aff, pair>::intersect_domain_wrapped_domain(const typed::set &uset) const +{ + auto res = isl::union_pw_multi_aff::intersect_domain_wrapped_domain(uset); + return typed::union_pw_multi_aff, pair>(res); +} + +template +typed::union_pw_multi_aff, pair> typed::union_pw_multi_aff, pair>::intersect_params(const typed::set<> &set) const +{ + auto res = isl::union_pw_multi_aff::intersect_params(set); + return typed::union_pw_multi_aff, pair>(res); +} + +template +typed::union_pw_multi_aff, pair> typed::union_pw_multi_aff, pair>::intersect_params(const typed::basic_set<> &set) const +{ + auto res = isl::union_pw_multi_aff::intersect_params(set); + return typed::union_pw_multi_aff, pair>(res); +} + +template +typed::union_pw_multi_aff, pair> typed::union_pw_multi_aff, pair>::intersect_params(const typed::point<> &set) const +{ + auto res = isl::union_pw_multi_aff::intersect_params(set); + return typed::union_pw_multi_aff, pair>(res); +} + +template +template +typed::union_pw_multi_aff, pair> typed::union_pw_multi_aff, pair>::preimage_domain_wrapped_domain(const typed::union_pw_multi_aff &upma2) const +{ + auto res = isl::union_pw_multi_aff::preimage_domain_wrapped_domain(upma2); + return typed::union_pw_multi_aff, pair>(res); +} + +template +template +typed::union_pw_multi_aff, pair> typed::union_pw_multi_aff, pair>::preimage_domain_wrapped_domain(const typed::multi_aff &upma2) const +{ + auto res = isl::union_pw_multi_aff::preimage_domain_wrapped_domain(upma2); + return typed::union_pw_multi_aff, pair>(res); +} + +template +template +typed::union_pw_multi_aff, pair> typed::union_pw_multi_aff, pair>::preimage_domain_wrapped_domain(const typed::pw_multi_aff &upma2) const +{ + auto res = isl::union_pw_multi_aff::preimage_domain_wrapped_domain(upma2); + return typed::union_pw_multi_aff, pair>(res); +} + +template +template +typed::union_pw_multi_aff, pair> typed::union_pw_multi_aff, pair>::preimage_domain_wrapped_domain(const typed::union_pw_aff &upma2) const +{ + auto res = isl::union_pw_multi_aff::preimage_domain_wrapped_domain(upma2); + return typed::union_pw_multi_aff, pair>(res); +} + +template +template +typed::union_pw_multi_aff> typed::union_pw_multi_aff, pair>::pullback(const typed::union_pw_multi_aff> &upma2) const +{ + auto res = isl::union_pw_multi_aff::pullback(upma2); + return typed::union_pw_multi_aff>(res); +} + +template +typed::union_pw_multi_aff> typed::union_pw_multi_aff, pair>::pullback(const typed::union_pw_multi_aff> &upma2) const +{ + auto res = isl::union_pw_multi_aff::pullback(upma2); + return typed::union_pw_multi_aff>(res); +} + +template +template +typed::union_pw_multi_aff> typed::union_pw_multi_aff, pair>::pullback(const typed::multi_aff> &upma2) const +{ + auto res = isl::union_pw_multi_aff::pullback(upma2); + return typed::union_pw_multi_aff>(res); +} + +template +typed::union_pw_multi_aff> typed::union_pw_multi_aff, pair>::pullback(const typed::multi_aff> &upma2) const +{ + auto res = isl::union_pw_multi_aff::pullback(upma2); + return typed::union_pw_multi_aff>(res); +} + +template +template +typed::union_pw_multi_aff> typed::union_pw_multi_aff, pair>::pullback(const typed::pw_multi_aff> &upma2) const +{ + auto res = isl::union_pw_multi_aff::pullback(upma2); + return typed::union_pw_multi_aff>(res); +} + +template +typed::union_pw_multi_aff> typed::union_pw_multi_aff, pair>::pullback(const typed::pw_multi_aff> &upma2) const +{ + auto res = isl::union_pw_multi_aff::pullback(upma2); + return typed::union_pw_multi_aff>(res); +} + +template +template +typed::union_pw_multi_aff> typed::union_pw_multi_aff, pair>::pullback(const typed::union_pw_aff> &upma2) const +{ + auto res = isl::union_pw_multi_aff::pullback(upma2); + return typed::union_pw_multi_aff>(res); +} + +template +typed::union_pw_multi_aff> typed::union_pw_multi_aff, pair>::pullback(const typed::union_pw_aff> &upma2) const +{ + auto res = isl::union_pw_multi_aff::pullback(upma2); + return typed::union_pw_multi_aff>(res); +} + +template +typed::pw_multi_aff_list, pair> typed::union_pw_multi_aff, pair>::pw_multi_aff_list() const +{ + auto res = isl::union_pw_multi_aff::pw_multi_aff_list(); + return typed::pw_multi_aff_list, pair>(res); +} + +template +typed::union_pw_multi_aff, Range> typed::union_pw_multi_aff, pair>::range_factor_domain() const +{ + auto res = isl::union_pw_multi_aff::range_factor_domain(); + return typed::union_pw_multi_aff, Range>(res); +} + +template +typed::union_pw_multi_aff, Range2> typed::union_pw_multi_aff, pair>::range_factor_range() const +{ + auto res = isl::union_pw_multi_aff::range_factor_range(); + return typed::union_pw_multi_aff, Range2>(res); +} + +template +template +typed::union_pw_multi_aff, pair, Arg2>> typed::union_pw_multi_aff, pair>::range_product(const typed::union_pw_multi_aff, Arg2> &upma2) const +{ + auto res = isl::union_pw_multi_aff::range_product(upma2); + return typed::union_pw_multi_aff, pair, Arg2>>(res); +} + +template +template +typed::union_pw_multi_aff, pair, Arg2>> typed::union_pw_multi_aff, pair>::range_product(const typed::multi_aff, Arg2> &upma2) const +{ + auto res = isl::union_pw_multi_aff::range_product(upma2); + return typed::union_pw_multi_aff, pair, Arg2>>(res); +} + +template +template +typed::union_pw_multi_aff, pair, Arg2>> typed::union_pw_multi_aff, pair>::range_product(const typed::pw_multi_aff, Arg2> &upma2) const +{ + auto res = isl::union_pw_multi_aff::range_product(upma2); + return typed::union_pw_multi_aff, pair, Arg2>>(res); +} + +template +typed::union_pw_multi_aff, pair, Anonymous>> typed::union_pw_multi_aff, pair>::range_product(const typed::union_pw_aff, Anonymous> &upma2) const +{ + auto res = isl::union_pw_multi_aff::range_product(upma2); + return typed::union_pw_multi_aff, pair, Anonymous>>(res); +} + +template +typed::space<> typed::union_pw_multi_aff, pair>::space() const +{ + auto res = isl::union_pw_multi_aff::space(); + return typed::space<>(res); +} + +template +typed::union_pw_multi_aff, pair> typed::union_pw_multi_aff, pair>::sub(const typed::union_pw_multi_aff, pair> &upma2) const +{ + auto res = isl::union_pw_multi_aff::sub(upma2); + return typed::union_pw_multi_aff, pair>(res); +} + +template +typed::union_pw_multi_aff, pair> typed::union_pw_multi_aff, pair>::sub(const typed::multi_aff, pair> &upma2) const +{ + auto res = isl::union_pw_multi_aff::sub(upma2); + return typed::union_pw_multi_aff, pair>(res); +} + +template +typed::union_pw_multi_aff, pair> typed::union_pw_multi_aff, pair>::sub(const typed::pw_multi_aff, pair> &upma2) const +{ + auto res = isl::union_pw_multi_aff::sub(upma2); + return typed::union_pw_multi_aff, pair>(res); +} + +template +typed::union_pw_multi_aff, pair> typed::union_pw_multi_aff, pair>::sub(const typed::union_pw_aff, pair> &upma2) const +{ + auto res = isl::union_pw_multi_aff::sub(upma2); + return typed::union_pw_multi_aff, pair>(res); +} + +template +typed::union_pw_multi_aff, pair> typed::union_pw_multi_aff, pair>::subtract_domain(const typed::space> &space) const +{ + auto res = isl::union_pw_multi_aff::subtract_domain(space); + return typed::union_pw_multi_aff, pair>(res); +} + +template +typed::union_pw_multi_aff, pair> typed::union_pw_multi_aff, pair>::subtract_domain(const typed::union_set> &uset) const +{ + auto res = isl::union_pw_multi_aff::subtract_domain(uset); + return typed::union_pw_multi_aff, pair>(res); +} + +template +typed::union_pw_multi_aff, pair> typed::union_pw_multi_aff, pair>::union_add(const typed::union_pw_multi_aff, pair> &upma2) const +{ + auto res = isl::union_pw_multi_aff::union_add(upma2); + return typed::union_pw_multi_aff, pair>(res); +} + +template +typed::union_pw_multi_aff, pair> typed::union_pw_multi_aff, pair>::union_add(const typed::multi_aff, pair> &upma2) const +{ + auto res = isl::union_pw_multi_aff::union_add(upma2); + return typed::union_pw_multi_aff, pair>(res); +} + +template +typed::union_pw_multi_aff, pair> typed::union_pw_multi_aff, pair>::union_add(const typed::pw_multi_aff, pair> &upma2) const +{ + auto res = isl::union_pw_multi_aff::union_add(upma2); + return typed::union_pw_multi_aff, pair>(res); +} + +template +typed::union_pw_multi_aff, pair> typed::union_pw_multi_aff, pair>::union_add(const typed::union_pw_aff, pair> &upma2) const +{ + auto res = isl::union_pw_multi_aff::union_add(upma2); + return typed::union_pw_multi_aff, pair>(res); +} + +typed::union_set<>::union_set(const typed::basic_set<> &bset) + : isl::union_set(bset) +{ +} + +typed::union_set<>::union_set(const typed::point<> &pnt) + : isl::union_set(pnt) +{ +} + +typed::union_set<>::union_set(const typed::set<> &set) + : isl::union_set(set) +{ +} + +typed::union_set<>::union_set(const isl::ctx &ctx, const std::string &str) + : isl::union_set(ctx, str) +{ +} + +typed::union_set<> typed::union_set<>::coalesce() const +{ + auto res = isl::union_set::coalesce(); + return typed::union_set<>(res); +} + +typed::union_set<> typed::union_set<>::detect_equalities() const +{ + auto res = isl::union_set::detect_equalities(); + return typed::union_set<>(res); +} + +typed::union_set<> typed::union_set<>::drop_unused_params() const +{ + auto res = isl::union_set::drop_unused_params(); + return typed::union_set<>(res); +} + +typed::union_set<> typed::union_set<>::empty(const isl::ctx &ctx) +{ + auto res = isl::union_set::empty(ctx); + return typed::union_set<>(res); +} + +bool typed::union_set<>::every_set(const std::function)> &test) const +{ + auto lambda_test = [&] (isl::set arg0) { + return test(typed::set<>(arg0)); + }; + return isl::union_set::every_set(lambda_test); +} + +typed::set<> typed::union_set<>::extract_set(const typed::space<> &space) const +{ + auto res = isl::union_set::extract_set(space); + return typed::set<>(res); +} + +void typed::union_set<>::foreach_point(const std::function)> &fn) const +{ + auto lambda_fn = [&] (isl::point arg0) { + return fn(typed::point<>(arg0)); + }; + return isl::union_set::foreach_point(lambda_fn); +} + +void typed::union_set<>::foreach_set(const std::function)> &fn) const +{ + auto lambda_fn = [&] (isl::set arg0) { + return fn(typed::set<>(arg0)); + }; + return isl::union_set::foreach_set(lambda_fn); +} + +typed::union_set<> typed::union_set<>::gist(const typed::union_set<> &context) const +{ + auto res = isl::union_set::gist(context); + return typed::union_set<>(res); +} + +typed::union_set<> typed::union_set<>::gist(const typed::basic_set<> &context) const +{ + auto res = isl::union_set::gist(context); + return typed::union_set<>(res); +} + +typed::union_set<> typed::union_set<>::gist(const typed::point<> &context) const +{ + auto res = isl::union_set::gist(context); + return typed::union_set<>(res); +} + +typed::union_set<> typed::union_set<>::gist(const typed::set<> &context) const +{ + auto res = isl::union_set::gist(context); + return typed::union_set<>(res); +} + +typed::union_set<> typed::union_set<>::intersect(const typed::union_set<> &uset2) const +{ + auto res = isl::union_set::intersect(uset2); + return typed::union_set<>(res); +} + +typed::union_set<> typed::union_set<>::intersect(const typed::basic_set<> &uset2) const +{ + auto res = isl::union_set::intersect(uset2); + return typed::union_set<>(res); +} + +typed::union_set<> typed::union_set<>::intersect(const typed::point<> &uset2) const +{ + auto res = isl::union_set::intersect(uset2); + return typed::union_set<>(res); +} + +typed::union_set<> typed::union_set<>::intersect(const typed::set<> &uset2) const +{ + auto res = isl::union_set::intersect(uset2); + return typed::union_set<>(res); +} + +typed::union_set<> typed::union_set<>::project_out_all_params() const +{ + auto res = isl::union_set::project_out_all_params(); + return typed::union_set<>(res); +} + +typed::set_list<> typed::union_set<>::set_list() const +{ + auto res = isl::union_set::set_list(); + return typed::set_list<>(res); +} + +typed::space<> typed::union_set<>::space() const +{ + auto res = isl::union_set::space(); + return typed::space<>(res); +} + +typed::union_set<> typed::union_set<>::subtract(const typed::union_set<> &uset2) const +{ + auto res = isl::union_set::subtract(uset2); + return typed::union_set<>(res); +} + +typed::union_set<> typed::union_set<>::subtract(const typed::basic_set<> &uset2) const +{ + auto res = isl::union_set::subtract(uset2); + return typed::union_set<>(res); +} + +typed::union_set<> typed::union_set<>::subtract(const typed::point<> &uset2) const +{ + auto res = isl::union_set::subtract(uset2); + return typed::union_set<>(res); +} + +typed::union_set<> typed::union_set<>::subtract(const typed::set<> &uset2) const +{ + auto res = isl::union_set::subtract(uset2); + return typed::union_set<>(res); +} + +typed::union_set<> typed::union_set<>::unite(const typed::union_set<> &uset2) const +{ + auto res = isl::union_set::unite(uset2); + return typed::union_set<>(res); +} + +typed::union_set<> typed::union_set<>::unite(const typed::basic_set<> &uset2) const +{ + auto res = isl::union_set::unite(uset2); + return typed::union_set<>(res); +} + +typed::union_set<> typed::union_set<>::unite(const typed::point<> &uset2) const +{ + auto res = isl::union_set::unite(uset2); + return typed::union_set<>(res); +} + +typed::union_set<> typed::union_set<>::unite(const typed::set<> &uset2) const +{ + auto res = isl::union_set::unite(uset2); + return typed::union_set<>(res); +} + +typed::union_set<> typed::union_set<>::universe() const +{ + auto res = isl::union_set::universe(); + return typed::union_set<>(res); +} + +template +typed::union_set::union_set(const typed::basic_set &bset) + : isl::union_set(bset) +{ +} + +template +typed::union_set::union_set(const typed::point &pnt) + : isl::union_set(pnt) +{ +} + +template +typed::union_set::union_set(const typed::set &set) + : isl::union_set(set) +{ +} + +template +typed::union_set::union_set(const isl::ctx &ctx, const std::string &str) + : isl::union_set(ctx, str) +{ +} + +template +template +typed::union_set typed::union_set::apply(const typed::union_map &umap) const +{ + auto res = isl::union_set::apply(umap); + return typed::union_set(res); +} + +template +template +typed::union_set typed::union_set::apply(const typed::basic_map &umap) const +{ + auto res = isl::union_set::apply(umap); + return typed::union_set(res); +} + +template +template +typed::union_set typed::union_set::apply(const typed::map &umap) const +{ + auto res = isl::union_set::apply(umap); + return typed::union_set(res); +} + +template +typed::set typed::union_set::as_set() const +{ + auto res = isl::union_set::as_set(); + return typed::set(res); +} + +template +typed::union_set typed::union_set::coalesce() const +{ + auto res = isl::union_set::coalesce(); + return typed::union_set(res); +} + +template +typed::union_set typed::union_set::detect_equalities() const +{ + auto res = isl::union_set::detect_equalities(); + return typed::union_set(res); +} + +template +typed::union_set typed::union_set::drop_unused_params() const +{ + auto res = isl::union_set::drop_unused_params(); + return typed::union_set(res); +} + +template +typed::union_set typed::union_set::empty(const isl::ctx &ctx) +{ + auto res = isl::union_set::empty(ctx); + return typed::union_set(res); +} + +template +bool typed::union_set::every_set(const std::function)> &test) const +{ + auto lambda_test = [&] (isl::set arg0) { + return test(typed::set(arg0)); + }; + return isl::union_set::every_set(lambda_test); +} + +template +typed::set typed::union_set::extract_set(const typed::space &space) const +{ + auto res = isl::union_set::extract_set(space); + return typed::set(res); +} + +template +void typed::union_set::foreach_point(const std::function)> &fn) const +{ + auto lambda_fn = [&] (isl::point arg0) { + return fn(typed::point(arg0)); + }; + return isl::union_set::foreach_point(lambda_fn); +} + +template +void typed::union_set::foreach_set(const std::function)> &fn) const +{ + auto lambda_fn = [&] (isl::set arg0) { + return fn(typed::set(arg0)); + }; + return isl::union_set::foreach_set(lambda_fn); +} + +template +typed::union_set typed::union_set::gist(const typed::union_set &context) const +{ + auto res = isl::union_set::gist(context); + return typed::union_set(res); +} + +template +typed::union_set typed::union_set::gist(const typed::basic_set &context) const +{ + auto res = isl::union_set::gist(context); + return typed::union_set(res); +} + +template +typed::union_set typed::union_set::gist(const typed::point &context) const +{ + auto res = isl::union_set::gist(context); + return typed::union_set(res); +} + +template +typed::union_set typed::union_set::gist(const typed::set &context) const +{ + auto res = isl::union_set::gist(context); + return typed::union_set(res); +} + +template +typed::union_set typed::union_set::gist_params(const typed::set<> &set) const +{ + auto res = isl::union_set::gist_params(set); + return typed::union_set(res); +} + +template +typed::union_set typed::union_set::gist_params(const typed::basic_set<> &set) const +{ + auto res = isl::union_set::gist_params(set); + return typed::union_set(res); +} + +template +typed::union_set typed::union_set::gist_params(const typed::point<> &set) const +{ + auto res = isl::union_set::gist_params(set); + return typed::union_set(res); +} + +template +typed::union_map typed::union_set::identity() const +{ + auto res = isl::union_set::identity(); + return typed::union_map(res); +} + +template +typed::union_set typed::union_set::intersect(const typed::union_set &uset2) const +{ + auto res = isl::union_set::intersect(uset2); + return typed::union_set(res); +} + +template +typed::union_set typed::union_set::intersect(const typed::basic_set &uset2) const +{ + auto res = isl::union_set::intersect(uset2); + return typed::union_set(res); +} + +template +typed::union_set typed::union_set::intersect(const typed::point &uset2) const +{ + auto res = isl::union_set::intersect(uset2); + return typed::union_set(res); +} + +template +typed::union_set typed::union_set::intersect(const typed::set &uset2) const +{ + auto res = isl::union_set::intersect(uset2); + return typed::union_set(res); +} + +template +typed::union_set typed::union_set::intersect_params(const typed::set<> &set) const +{ + auto res = isl::union_set::intersect_params(set); + return typed::union_set(res); +} + +template +typed::union_set typed::union_set::intersect_params(const typed::basic_set<> &set) const +{ + auto res = isl::union_set::intersect_params(set); + return typed::union_set(res); +} + +template +typed::union_set typed::union_set::intersect_params(const typed::point<> &set) const +{ + auto res = isl::union_set::intersect_params(set); + return typed::union_set(res); +} + +template +typed::union_set typed::union_set::lexmax() const +{ + auto res = isl::union_set::lexmax(); + return typed::union_set(res); +} + +template +typed::union_set typed::union_set::lexmin() const +{ + auto res = isl::union_set::lexmin(); + return typed::union_set(res); +} + +template +typed::set<> typed::union_set::params() const +{ + auto res = isl::union_set::params(); + return typed::set<>(res); +} + +template +template +typed::union_set typed::union_set::preimage(const typed::multi_aff &ma) const +{ + auto res = isl::union_set::preimage(ma); + return typed::union_set(res); +} + +template +template +typed::union_set typed::union_set::preimage(const typed::pw_multi_aff &pma) const +{ + auto res = isl::union_set::preimage(pma); + return typed::union_set(res); +} + +template +template +typed::union_set typed::union_set::preimage(const typed::union_pw_multi_aff &upma) const +{ + auto res = isl::union_set::preimage(upma); + return typed::union_set(res); +} + +template +typed::union_set typed::union_set::project_out_all_params() const +{ + auto res = isl::union_set::project_out_all_params(); + return typed::union_set(res); +} + +template +typed::set_list typed::union_set::set_list() const +{ + auto res = isl::union_set::set_list(); + return typed::set_list(res); +} + +template +typed::space<> typed::union_set::space() const +{ + auto res = isl::union_set::space(); + return typed::space<>(res); +} + +template +typed::union_set typed::union_set::subtract(const typed::union_set &uset2) const +{ + auto res = isl::union_set::subtract(uset2); + return typed::union_set(res); +} + +template +typed::union_set typed::union_set::subtract(const typed::basic_set &uset2) const +{ + auto res = isl::union_set::subtract(uset2); + return typed::union_set(res); +} + +template +typed::union_set typed::union_set::subtract(const typed::point &uset2) const +{ + auto res = isl::union_set::subtract(uset2); + return typed::union_set(res); +} + +template +typed::union_set typed::union_set::subtract(const typed::set &uset2) const +{ + auto res = isl::union_set::subtract(uset2); + return typed::union_set(res); +} + +template +typed::union_set typed::union_set::unite(const typed::union_set &uset2) const +{ + auto res = isl::union_set::unite(uset2); + return typed::union_set(res); +} + +template +typed::union_set typed::union_set::unite(const typed::basic_set &uset2) const +{ + auto res = isl::union_set::unite(uset2); + return typed::union_set(res); +} + +template +typed::union_set typed::union_set::unite(const typed::point &uset2) const +{ + auto res = isl::union_set::unite(uset2); + return typed::union_set(res); +} + +template +typed::union_set typed::union_set::unite(const typed::set &uset2) const +{ + auto res = isl::union_set::unite(uset2); + return typed::union_set(res); +} + +template +typed::union_set typed::union_set::universe() const +{ + auto res = isl::union_set::universe(); + return typed::union_set(res); +} + +template +typed::union_set>::union_set(const typed::basic_set> &bset) + : isl::union_set(bset) +{ +} + +template +typed::union_set>::union_set(const typed::point> &pnt) + : isl::union_set(pnt) +{ +} + +template +typed::union_set>::union_set(const typed::set> &set) + : isl::union_set(set) +{ +} + +template +typed::union_set>::union_set(const isl::ctx &ctx, const std::string &str) + : isl::union_set(ctx, str) +{ +} + +template +template +typed::union_set typed::union_set>::apply(const typed::union_map, Arg2> &umap) const +{ + auto res = isl::union_set::apply(umap); + return typed::union_set(res); +} + +template +template +typed::union_set typed::union_set>::apply(const typed::basic_map, Arg2> &umap) const +{ + auto res = isl::union_set::apply(umap); + return typed::union_set(res); +} + +template +template +typed::union_set typed::union_set>::apply(const typed::map, Arg2> &umap) const +{ + auto res = isl::union_set::apply(umap); + return typed::union_set(res); +} + +template +typed::set> typed::union_set>::as_set() const +{ + auto res = isl::union_set::as_set(); + return typed::set>(res); +} + +template +typed::union_set> typed::union_set>::coalesce() const +{ + auto res = isl::union_set::coalesce(); + return typed::union_set>(res); +} + +template +typed::union_set> typed::union_set>::detect_equalities() const +{ + auto res = isl::union_set::detect_equalities(); + return typed::union_set>(res); +} + +template +typed::union_set> typed::union_set>::drop_unused_params() const +{ + auto res = isl::union_set::drop_unused_params(); + return typed::union_set>(res); +} + +template +typed::union_set> typed::union_set>::empty(const isl::ctx &ctx) +{ + auto res = isl::union_set::empty(ctx); + return typed::union_set>(res); +} + +template +bool typed::union_set>::every_set(const std::function>)> &test) const +{ + auto lambda_test = [&] (isl::set arg0) { + return test(typed::set>(arg0)); + }; + return isl::union_set::every_set(lambda_test); +} + +template +typed::set> typed::union_set>::extract_set(const typed::space> &space) const +{ + auto res = isl::union_set::extract_set(space); + return typed::set>(res); +} + +template +void typed::union_set>::foreach_point(const std::function>)> &fn) const +{ + auto lambda_fn = [&] (isl::point arg0) { + return fn(typed::point>(arg0)); + }; + return isl::union_set::foreach_point(lambda_fn); +} + +template +void typed::union_set>::foreach_set(const std::function>)> &fn) const +{ + auto lambda_fn = [&] (isl::set arg0) { + return fn(typed::set>(arg0)); + }; + return isl::union_set::foreach_set(lambda_fn); +} + +template +typed::union_set> typed::union_set>::gist(const typed::union_set> &context) const +{ + auto res = isl::union_set::gist(context); + return typed::union_set>(res); +} + +template +typed::union_set> typed::union_set>::gist(const typed::basic_set> &context) const +{ + auto res = isl::union_set::gist(context); + return typed::union_set>(res); +} + +template +typed::union_set> typed::union_set>::gist(const typed::point> &context) const +{ + auto res = isl::union_set::gist(context); + return typed::union_set>(res); +} + +template +typed::union_set> typed::union_set>::gist(const typed::set> &context) const +{ + auto res = isl::union_set::gist(context); + return typed::union_set>(res); +} + +template +typed::union_set> typed::union_set>::gist_params(const typed::set<> &set) const +{ + auto res = isl::union_set::gist_params(set); + return typed::union_set>(res); +} + +template +typed::union_set> typed::union_set>::gist_params(const typed::basic_set<> &set) const +{ + auto res = isl::union_set::gist_params(set); + return typed::union_set>(res); +} + +template +typed::union_set> typed::union_set>::gist_params(const typed::point<> &set) const +{ + auto res = isl::union_set::gist_params(set); + return typed::union_set>(res); +} + +template +typed::union_map, pair> typed::union_set>::identity() const +{ + auto res = isl::union_set::identity(); + return typed::union_map, pair>(res); +} + +template +typed::union_set> typed::union_set>::intersect(const typed::union_set> &uset2) const +{ + auto res = isl::union_set::intersect(uset2); + return typed::union_set>(res); +} + +template +typed::union_set> typed::union_set>::intersect(const typed::basic_set> &uset2) const +{ + auto res = isl::union_set::intersect(uset2); + return typed::union_set>(res); +} + +template +typed::union_set> typed::union_set>::intersect(const typed::point> &uset2) const +{ + auto res = isl::union_set::intersect(uset2); + return typed::union_set>(res); +} + +template +typed::union_set> typed::union_set>::intersect(const typed::set> &uset2) const +{ + auto res = isl::union_set::intersect(uset2); + return typed::union_set>(res); +} + +template +typed::union_set> typed::union_set>::intersect_params(const typed::set<> &set) const +{ + auto res = isl::union_set::intersect_params(set); + return typed::union_set>(res); +} + +template +typed::union_set> typed::union_set>::intersect_params(const typed::basic_set<> &set) const +{ + auto res = isl::union_set::intersect_params(set); + return typed::union_set>(res); +} + +template +typed::union_set> typed::union_set>::intersect_params(const typed::point<> &set) const +{ + auto res = isl::union_set::intersect_params(set); + return typed::union_set>(res); +} + +template +typed::union_set> typed::union_set>::lexmax() const +{ + auto res = isl::union_set::lexmax(); + return typed::union_set>(res); +} + +template +typed::union_set> typed::union_set>::lexmin() const +{ + auto res = isl::union_set::lexmin(); + return typed::union_set>(res); +} + +template +typed::set<> typed::union_set>::params() const +{ + auto res = isl::union_set::params(); + return typed::set<>(res); +} + +template +template +typed::union_set typed::union_set>::preimage(const typed::multi_aff> &ma) const +{ + auto res = isl::union_set::preimage(ma); + return typed::union_set(res); +} + +template +template +typed::union_set typed::union_set>::preimage(const typed::pw_multi_aff> &pma) const +{ + auto res = isl::union_set::preimage(pma); + return typed::union_set(res); +} + +template +template +typed::union_set typed::union_set>::preimage(const typed::union_pw_multi_aff> &upma) const +{ + auto res = isl::union_set::preimage(upma); + return typed::union_set(res); +} + +template +typed::union_set> typed::union_set>::project_out_all_params() const +{ + auto res = isl::union_set::project_out_all_params(); + return typed::union_set>(res); +} + +template +typed::set_list> typed::union_set>::set_list() const +{ + auto res = isl::union_set::set_list(); + return typed::set_list>(res); +} + +template +typed::space<> typed::union_set>::space() const +{ + auto res = isl::union_set::space(); + return typed::space<>(res); +} + +template +typed::union_set> typed::union_set>::subtract(const typed::union_set> &uset2) const +{ + auto res = isl::union_set::subtract(uset2); + return typed::union_set>(res); +} + +template +typed::union_set> typed::union_set>::subtract(const typed::basic_set> &uset2) const +{ + auto res = isl::union_set::subtract(uset2); + return typed::union_set>(res); +} + +template +typed::union_set> typed::union_set>::subtract(const typed::point> &uset2) const +{ + auto res = isl::union_set::subtract(uset2); + return typed::union_set>(res); +} + +template +typed::union_set> typed::union_set>::subtract(const typed::set> &uset2) const +{ + auto res = isl::union_set::subtract(uset2); + return typed::union_set>(res); +} + +template +typed::union_set> typed::union_set>::unite(const typed::union_set> &uset2) const +{ + auto res = isl::union_set::unite(uset2); + return typed::union_set>(res); +} + +template +typed::union_set> typed::union_set>::unite(const typed::basic_set> &uset2) const +{ + auto res = isl::union_set::unite(uset2); + return typed::union_set>(res); +} + +template +typed::union_set> typed::union_set>::unite(const typed::point> &uset2) const +{ + auto res = isl::union_set::unite(uset2); + return typed::union_set>(res); +} + +template +typed::union_set> typed::union_set>::unite(const typed::set> &uset2) const +{ + auto res = isl::union_set::unite(uset2); + return typed::union_set>(res); +} + +template +typed::union_set> typed::union_set>::universe() const +{ + auto res = isl::union_set::universe(); + return typed::union_set>(res); +} + +template +typed::union_map typed::union_set>::unwrap() const +{ + auto res = isl::union_set::unwrap(); + return typed::union_map(res); +} + +typed::union_set_list<>::union_set_list(const isl::ctx &ctx, int n) + : isl::union_set_list(ctx, n) +{ +} + +typed::union_set_list<>::union_set_list(const typed::union_set<> &el) + : isl::union_set_list(el) +{ +} + +typed::union_set_list<>::union_set_list(const isl::ctx &ctx, const std::string &str) + : isl::union_set_list(ctx, str) +{ +} + +typed::union_set_list<> typed::union_set_list<>::add(const typed::union_set<> &el) const +{ + auto res = isl::union_set_list::add(el); + return typed::union_set_list<>(res); +} + +typed::union_set_list<> typed::union_set_list<>::add(const typed::basic_set<> &el) const +{ + auto res = isl::union_set_list::add(el); + return typed::union_set_list<>(res); +} + +typed::union_set_list<> typed::union_set_list<>::add(const typed::point<> &el) const +{ + auto res = isl::union_set_list::add(el); + return typed::union_set_list<>(res); +} + +typed::union_set_list<> typed::union_set_list<>::add(const typed::set<> &el) const +{ + auto res = isl::union_set_list::add(el); + return typed::union_set_list<>(res); +} + +typed::union_set_list<> typed::union_set_list<>::drop(unsigned int first, unsigned int n) const +{ + auto res = isl::union_set_list::drop(first, n); + return typed::union_set_list<>(res); +} + +void typed::union_set_list<>::foreach(const std::function)> &fn) const +{ + auto lambda_fn = [&] (isl::union_set arg0) { + return fn(typed::union_set<>(arg0)); + }; + return isl::union_set_list::foreach(lambda_fn); +} + +void typed::union_set_list<>::foreach_scc(const std::function, typed::union_set<>)> &follows, const std::function)> &fn) const +{ + auto lambda_follows = [&] (isl::union_set arg0, isl::union_set arg1) { + return follows(typed::union_set<>(arg0), typed::union_set<>(arg1)); + }; + auto lambda_fn = [&] (isl::union_set_list arg0) { + return fn(typed::union_set_list<>(arg0)); + }; + return isl::union_set_list::foreach_scc(lambda_follows, lambda_fn); +} + +template +typed::union_set_list::union_set_list(const isl::ctx &ctx, int n) + : isl::union_set_list(ctx, n) +{ +} + +template +typed::union_set_list::union_set_list(const typed::union_set &el) + : isl::union_set_list(el) +{ +} + +template +typed::union_set_list::union_set_list(const isl::ctx &ctx, const std::string &str) + : isl::union_set_list(ctx, str) +{ +} + +template +typed::union_set_list typed::union_set_list::add(const typed::union_set &el) const +{ + auto res = isl::union_set_list::add(el); + return typed::union_set_list(res); +} + +template +typed::union_set_list typed::union_set_list::add(const typed::basic_set &el) const +{ + auto res = isl::union_set_list::add(el); + return typed::union_set_list(res); +} + +template +typed::union_set_list typed::union_set_list::add(const typed::point &el) const +{ + auto res = isl::union_set_list::add(el); + return typed::union_set_list(res); +} + +template +typed::union_set_list typed::union_set_list::add(const typed::set &el) const +{ + auto res = isl::union_set_list::add(el); + return typed::union_set_list(res); +} + +template +typed::union_set typed::union_set_list::at(int index) const +{ + auto res = isl::union_set_list::at(index); + return typed::union_set(res); +} + +template +typed::union_set_list typed::union_set_list::drop(unsigned int first, unsigned int n) const +{ + auto res = isl::union_set_list::drop(first, n); + return typed::union_set_list(res); +} + +template +void typed::union_set_list::foreach(const std::function)> &fn) const +{ + auto lambda_fn = [&] (isl::union_set arg0) { + return fn(typed::union_set(arg0)); + }; + return isl::union_set_list::foreach(lambda_fn); +} + +template +void typed::union_set_list::foreach_scc(const std::function, typed::union_set)> &follows, const std::function)> &fn) const +{ + auto lambda_follows = [&] (isl::union_set arg0, isl::union_set arg1) { + return follows(typed::union_set(arg0), typed::union_set(arg1)); + }; + auto lambda_fn = [&] (isl::union_set_list arg0) { + return fn(typed::union_set_list(arg0)); + }; + return isl::union_set_list::foreach_scc(lambda_follows, lambda_fn); +} + +template +typed::union_set_list typed::union_set_list::set_at(int index, const typed::union_set &el) const +{ + auto res = isl::union_set_list::set_at(index, el); + return typed::union_set_list(res); +} + +typed::val::val(const isl::ctx &ctx, long i) + : isl::val(ctx, i) +{ +} + +typed::val::val(const isl::ctx &ctx, const std::string &str) + : isl::val(ctx, str) +{ +} + +typed::val typed::val::add(const typed::val &v2) const +{ + auto res = isl::val::add(v2); + return typed::val(res); +} + +typed::val typed::val::add(long v2) const +{ + auto res = isl::val::add(v2); + return typed::val(res); +} + +typed::val typed::val::ceil() const +{ + auto res = isl::val::ceil(); + return typed::val(res); +} + +typed::val typed::val::floor() const +{ + auto res = isl::val::floor(); + return typed::val(res); +} + +typed::val typed::val::max(const typed::val &v2) const +{ + auto res = isl::val::max(v2); + return typed::val(res); +} + +typed::val typed::val::max(long v2) const +{ + auto res = isl::val::max(v2); + return typed::val(res); +} + +typed::val typed::val::min(const typed::val &v2) const +{ + auto res = isl::val::min(v2); + return typed::val(res); +} + +typed::val typed::val::min(long v2) const +{ + auto res = isl::val::min(v2); + return typed::val(res); +} + +typed::val typed::val::mod(const typed::val &v2) const +{ + auto res = isl::val::mod(v2); + return typed::val(res); +} + +typed::val typed::val::mod(long v2) const +{ + auto res = isl::val::mod(v2); + return typed::val(res); +} + +typed::val typed::val::neg() const +{ + auto res = isl::val::neg(); + return typed::val(res); +} + +typed::val typed::val::sub(const typed::val &v2) const +{ + auto res = isl::val::sub(v2); + return typed::val(res); +} + +typed::val typed::val::sub(long v2) const +{ + auto res = isl::val::sub(v2); + return typed::val(res); +} + +typed::val_list::val_list(const isl::ctx &ctx, int n) + : isl::val_list(ctx, n) +{ +} + +typed::val_list::val_list(const typed::val &el) + : isl::val_list(el) +{ +} + +typed::val_list::val_list(const isl::ctx &ctx, const std::string &str) + : isl::val_list(ctx, str) +{ +} + +typed::val_list typed::val_list::add(const typed::val &el) const +{ + auto res = isl::val_list::add(el); + return typed::val_list(res); +} + +typed::val_list typed::val_list::add(long el) const +{ + auto res = isl::val_list::add(el); + return typed::val_list(res); +} + +typed::val typed::val_list::at(int index) const +{ + auto res = isl::val_list::at(index); + return typed::val(res); +} + +typed::val_list typed::val_list::drop(unsigned int first, unsigned int n) const +{ + auto res = isl::val_list::drop(first, n); + return typed::val_list(res); +} + +void typed::val_list::foreach(const std::function)> &fn) const +{ + auto lambda_fn = [&] (isl::val arg0) { + return fn(typed::val(arg0)); + }; + return isl::val_list::foreach(lambda_fn); +} + +void typed::val_list::foreach_scc(const std::function, typed::val)> &follows, const std::function)> &fn) const +{ + auto lambda_follows = [&] (isl::val arg0, isl::val arg1) { + return follows(typed::val(arg0), typed::val(arg1)); + }; + auto lambda_fn = [&] (isl::val_list arg0) { + return fn(typed::val_list(arg0)); + }; + return isl::val_list::foreach_scc(lambda_follows, lambda_fn); +} + +typed::val_list typed::val_list::set_at(int index, const typed::val &el) const +{ + auto res = isl::val_list::set_at(index, el); + return typed::val_list(res); +} + +typed::val_list typed::val_list::set_at(int index, long el) const +{ + auto res = isl::val_list::set_at(index, el); + return typed::val_list(res); +} + +} // namespace typed +} // namespace isl + +#endif /* ISL_TYPED_CPP */ diff --git a/external/mit/isl/dist/include/isl/union_map.h b/external/mit/isl/dist/include/isl/union_map.h new file mode 100644 index 000000000000..c17c27d74e2e --- /dev/null +++ b/external/mit/isl/dist/include/isl/union_map.h @@ -0,0 +1,393 @@ +#ifndef ISL_UNION_MAP_H +#define ISL_UNION_MAP_H + +#include +#include +#include +#include +#include +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +isl_size isl_union_map_dim(__isl_keep isl_union_map *umap, + enum isl_dim_type type); +isl_bool isl_union_map_involves_dims(__isl_keep isl_union_map *umap, + enum isl_dim_type type, unsigned first, unsigned n); +__isl_give isl_id *isl_union_map_get_dim_id(__isl_keep isl_union_map *umap, + enum isl_dim_type type, unsigned pos); + +__isl_constructor +__isl_give isl_union_map *isl_union_map_from_basic_map( + __isl_take isl_basic_map *bmap); +__isl_export +__isl_give isl_union_map *isl_map_to_union_map(__isl_take isl_map *map); +__isl_constructor +__isl_give isl_union_map *isl_union_map_from_map(__isl_take isl_map *map); +__isl_overload +__isl_give isl_union_map *isl_union_map_empty_ctx(isl_ctx *ctx); +__isl_give isl_union_map *isl_union_map_empty_space( + __isl_take isl_space *space); +__isl_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); + +isl_ctx *isl_union_map_get_ctx(__isl_keep isl_union_map *umap); +__isl_export +__isl_give isl_space *isl_union_map_get_space(__isl_keep isl_union_map *umap); + +__isl_give isl_union_map *isl_union_map_reset_user( + __isl_take isl_union_map *umap); + +int isl_union_map_find_dim_by_name(__isl_keep isl_union_map *umap, + enum isl_dim_type type, const char *name); + +__isl_export +__isl_give isl_union_map *isl_union_map_universe( + __isl_take isl_union_map *umap); +__isl_export +__isl_give isl_set *isl_union_map_params(__isl_take isl_union_map *umap); +__isl_export +__isl_give isl_union_set *isl_union_map_domain(__isl_take isl_union_map *umap); +__isl_export +__isl_give isl_union_set *isl_union_map_range(__isl_take isl_union_map *umap); +__isl_export +__isl_give isl_union_map *isl_union_map_domain_map( + __isl_take isl_union_map *umap); +__isl_export +__isl_give isl_union_pw_multi_aff *isl_union_map_domain_map_union_pw_multi_aff( + __isl_take isl_union_map *umap); +__isl_export +__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); + +__isl_export +__isl_give isl_union_map *isl_union_map_affine_hull( + __isl_take isl_union_map *umap); +__isl_export +__isl_give isl_union_map *isl_union_map_polyhedral_hull( + __isl_take isl_union_map *umap); +__isl_give isl_union_map *isl_union_map_remove_redundancies( + __isl_take isl_union_map *umap); +__isl_give isl_union_map *isl_union_map_simple_hull( + __isl_take isl_union_map *umap); +__isl_export +__isl_give isl_union_map *isl_union_map_coalesce( + __isl_take isl_union_map *umap); +__isl_export +__isl_give isl_union_map *isl_union_map_compute_divs( + __isl_take isl_union_map *umap); +__isl_export +__isl_give isl_union_map *isl_union_map_lexmin(__isl_take isl_union_map *umap); +__isl_export +__isl_give isl_union_map *isl_union_map_lexmax(__isl_take isl_union_map *umap); + +__isl_give isl_union_map *isl_union_map_add_map(__isl_take isl_union_map *umap, + __isl_take isl_map *map); +__isl_export +__isl_give isl_union_map *isl_union_map_union(__isl_take isl_union_map *umap1, + __isl_take isl_union_map *umap2); +__isl_export +__isl_give isl_union_map *isl_union_map_subtract( + __isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2); +__isl_export +__isl_give isl_union_map *isl_union_map_intersect( + __isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2); +__isl_export +__isl_give isl_union_map *isl_union_map_intersect_params( + __isl_take isl_union_map *umap, __isl_take isl_set *set); +__isl_export +__isl_give isl_union_map *isl_union_map_product(__isl_take isl_union_map *umap1, + __isl_take isl_union_map *umap2); +__isl_export +__isl_give isl_union_map *isl_union_map_domain_product( + __isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2); +__isl_give isl_union_map *isl_union_map_flat_domain_product( + __isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2); +__isl_export +__isl_give isl_union_map *isl_union_map_range_product( + __isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2); +__isl_give isl_union_map *isl_union_map_flat_range_product( + __isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2); +__isl_export +__isl_give isl_union_map *isl_union_map_domain_factor_domain( + __isl_take isl_union_map *umap); +__isl_export +__isl_give isl_union_map *isl_union_map_domain_factor_range( + __isl_take isl_union_map *umap); +__isl_export +__isl_give isl_union_map *isl_union_map_range_factor_domain( + __isl_take isl_union_map *umap); +__isl_export +__isl_give isl_union_map *isl_union_map_range_factor_range( + __isl_take isl_union_map *umap); +__isl_export +__isl_give isl_union_map *isl_union_map_factor_domain( + __isl_take isl_union_map *umap); +__isl_export +__isl_give isl_union_map *isl_union_map_factor_range( + __isl_take isl_union_map *umap); +__isl_export +__isl_give isl_union_map *isl_union_map_gist(__isl_take isl_union_map *umap, + __isl_take isl_union_map *context); +__isl_export +__isl_give isl_union_map *isl_union_map_gist_params( + __isl_take isl_union_map *umap, __isl_take isl_set *set); +__isl_export +__isl_give isl_union_map *isl_union_map_gist_domain( + __isl_take isl_union_map *umap, __isl_take isl_union_set *uset); +__isl_export +__isl_give isl_union_map *isl_union_map_gist_range( + __isl_take isl_union_map *umap, __isl_take isl_union_set *uset); + +__isl_overload +__isl_give isl_union_map *isl_union_map_intersect_domain_union_set( + __isl_take isl_union_map *umap, __isl_take isl_union_set *uset); +__isl_overload +__isl_give isl_union_map *isl_union_map_intersect_domain_space( + __isl_take isl_union_map *umap, __isl_take isl_space *space); +__isl_give isl_union_map *isl_union_map_intersect_domain( + __isl_take isl_union_map *umap, __isl_take isl_union_set *uset); +__isl_overload +__isl_give isl_union_map *isl_union_map_intersect_range_union_set( + __isl_take isl_union_map *umap, __isl_take isl_union_set *uset); +__isl_overload +__isl_give isl_union_map *isl_union_map_intersect_range_space( + __isl_take isl_union_map *umap, __isl_take isl_space *space); +__isl_give isl_union_map *isl_union_map_intersect_range( + __isl_take isl_union_map *umap, __isl_take isl_union_set *uset); +__isl_export +__isl_give isl_union_map *isl_union_map_intersect_domain_factor_domain( + __isl_take isl_union_map *umap, __isl_take isl_union_map *factor); +__isl_export +__isl_give isl_union_map *isl_union_map_intersect_domain_factor_range( + __isl_take isl_union_map *umap, __isl_take isl_union_map *factor); +__isl_export +__isl_give isl_union_map *isl_union_map_intersect_range_factor_domain( + __isl_take isl_union_map *umap, __isl_take isl_union_map *factor); +__isl_export +__isl_give isl_union_map *isl_union_map_intersect_range_factor_range( + __isl_take isl_union_map *umap, __isl_take isl_union_map *factor); +__isl_overload +__isl_give isl_union_map * +isl_union_map_intersect_domain_wrapped_domain_union_set( + __isl_take isl_union_map *umap, __isl_take isl_union_set *domain); +__isl_overload +__isl_give isl_union_map * +isl_union_map_intersect_range_wrapped_domain_union_set( + __isl_take isl_union_map *umap, __isl_take isl_union_set *domain); + +__isl_export +__isl_give isl_union_map *isl_union_map_subtract_domain( + __isl_take isl_union_map *umap, __isl_take isl_union_set *dom); +__isl_export +__isl_give isl_union_map *isl_union_map_subtract_range( + __isl_take isl_union_map *umap, __isl_take isl_union_set *dom); + +__isl_export +__isl_give isl_union_map *isl_union_map_apply_domain( + __isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2); +__isl_export +__isl_give isl_union_map *isl_union_map_apply_range( + __isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2); +__isl_overload +__isl_give isl_union_map *isl_union_map_preimage_domain_multi_aff( + __isl_take isl_union_map *umap, __isl_take isl_multi_aff *ma); +__isl_overload +__isl_give isl_union_map *isl_union_map_preimage_range_multi_aff( + __isl_take isl_union_map *umap, __isl_take isl_multi_aff *ma); +__isl_overload +__isl_give isl_union_map *isl_union_map_preimage_domain_pw_multi_aff( + __isl_take isl_union_map *umap, __isl_take isl_pw_multi_aff *pma); +__isl_overload +__isl_give isl_union_map *isl_union_map_preimage_range_pw_multi_aff( + __isl_take isl_union_map *umap, __isl_take isl_pw_multi_aff *pma); +__isl_overload +__isl_give isl_union_map *isl_union_map_preimage_domain_multi_pw_aff( + __isl_take isl_union_map *umap, __isl_take isl_multi_pw_aff *mpa); +__isl_overload +__isl_give isl_union_map *isl_union_map_preimage_domain_union_pw_multi_aff( + __isl_take isl_union_map *umap, + __isl_take isl_union_pw_multi_aff *upma); +__isl_overload +__isl_give isl_union_map *isl_union_map_preimage_range_union_pw_multi_aff( + __isl_take isl_union_map *umap, + __isl_take isl_union_pw_multi_aff *upma); +__isl_export +__isl_give isl_union_map *isl_union_map_reverse(__isl_take isl_union_map *umap); +__isl_export +__isl_give isl_union_map *isl_union_map_domain_reverse( + __isl_take isl_union_map *umap); +__isl_export +__isl_give isl_union_map *isl_union_map_range_reverse( + __isl_take isl_union_map *umap); +__isl_export +__isl_give isl_union_map *isl_union_map_from_domain_and_range( + __isl_take isl_union_set *domain, __isl_take isl_union_set *range); + +__isl_export +__isl_give isl_union_map *isl_union_map_detect_equalities( + __isl_take isl_union_map *umap); +__isl_export +__isl_give isl_union_set *isl_union_map_deltas(__isl_take isl_union_map *umap); +__isl_give isl_union_map *isl_union_map_deltas_map( + __isl_take isl_union_map *umap); +__isl_export +__isl_give isl_union_map *isl_union_set_identity(__isl_take isl_union_set *uset); + +__isl_overload +__isl_give isl_union_map *isl_union_map_project_out_param_id( + __isl_take isl_union_map *umap, __isl_take isl_id *id); +__isl_overload +__isl_give isl_union_map *isl_union_map_project_out_param_id_list( + __isl_take isl_union_map *umap, __isl_take isl_id_list *list); +__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_export +__isl_give isl_union_map *isl_union_map_drop_unused_params( + __isl_take isl_union_map *umap); +__isl_give isl_union_map *isl_union_map_remove_divs( + __isl_take isl_union_map *bmap); + +__isl_export +__isl_give isl_union_set *isl_union_map_bind_range( + __isl_take isl_union_map *umap, __isl_take isl_multi_id *tuple); + +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 +isl_bool isl_union_map_is_single_valued(__isl_keep isl_union_map *umap); +isl_bool isl_union_map_plain_is_injective(__isl_keep isl_union_map *umap); +__isl_export +isl_bool isl_union_map_is_injective(__isl_keep isl_union_map *umap); +__isl_export +isl_bool isl_union_map_is_bijective(__isl_keep isl_union_map *umap); +isl_bool isl_union_map_is_identity(__isl_keep isl_union_map *umap); + +__isl_export +isl_bool isl_union_map_is_subset(__isl_keep isl_union_map *umap1, + __isl_keep isl_union_map *umap2); +__isl_export +isl_bool isl_union_map_is_equal(__isl_keep isl_union_map *umap1, + __isl_keep isl_union_map *umap2); +__isl_export +isl_bool isl_union_map_is_disjoint(__isl_keep isl_union_map *umap1, + __isl_keep isl_union_map *umap2); +__isl_export +isl_bool isl_union_map_is_strict_subset(__isl_keep isl_union_map *umap1, + __isl_keep isl_union_map *umap2); + +uint32_t isl_union_map_get_hash(__isl_keep isl_union_map *umap); + +isl_size isl_union_map_n_map(__isl_keep isl_union_map *umap); +__isl_export +isl_stat isl_union_map_foreach_map(__isl_keep isl_union_map *umap, + isl_stat (*fn)(__isl_take isl_map *map, void *user), void *user); +__isl_export +__isl_give isl_map_list *isl_union_map_get_map_list( + __isl_keep isl_union_map *umap); +__isl_export +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_export +__isl_give isl_map *isl_union_map_extract_map(__isl_keep isl_union_map *umap, + __isl_take isl_space *space); +__isl_export +isl_bool isl_union_map_isa_map(__isl_keep isl_union_map *umap); +__isl_export +__isl_give isl_map *isl_union_map_as_map(__isl_take isl_union_map *umap); +__isl_give isl_map *isl_map_from_union_map(__isl_take isl_union_map *umap); + +__isl_give isl_basic_map *isl_union_map_sample(__isl_take isl_union_map *umap); + +__isl_overload +__isl_give isl_union_map *isl_union_map_fixed_power_val( + __isl_take isl_union_map *umap, __isl_take isl_val *exp); +__isl_give isl_union_map *isl_union_map_power(__isl_take isl_union_map *umap, + isl_bool *exact); +__isl_give isl_union_map *isl_union_map_transitive_closure( + __isl_take isl_union_map *umap, isl_bool *exact); + +__isl_give isl_union_map *isl_union_map_lex_lt_union_map( + __isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2); +__isl_give isl_union_map *isl_union_map_lex_le_union_map( + __isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2); +__isl_give isl_union_map *isl_union_map_lex_gt_union_map( + __isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2); +__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); +__isl_give isl_union_map *isl_union_map_lex_le_at_multi_union_pw_aff( + __isl_take isl_union_map *umap, + __isl_take isl_multi_union_pw_aff *mupa); +__isl_give isl_union_map *isl_union_map_lex_lt_at_multi_union_pw_aff( + __isl_take isl_union_map *umap, + __isl_take isl_multi_union_pw_aff *mupa); +__isl_give isl_union_map *isl_union_map_lex_ge_at_multi_union_pw_aff( + __isl_take isl_union_map *umap, + __isl_take isl_multi_union_pw_aff *mupa); +__isl_give isl_union_map *isl_union_map_lex_gt_at_multi_union_pw_aff( + __isl_take isl_union_map *umap, + __isl_take isl_multi_union_pw_aff *mupa); + +__isl_give isl_union_map *isl_union_map_read_from_file(isl_ctx *ctx, + FILE *input); +__isl_constructor +__isl_give isl_union_map *isl_union_map_read_from_str(isl_ctx *ctx, + const char *str); +__isl_give char *isl_union_map_to_str(__isl_keep isl_union_map *umap); +__isl_give isl_printer *isl_printer_print_union_map(__isl_take isl_printer *p, + __isl_keep isl_union_map *umap); +void isl_union_map_dump(__isl_keep isl_union_map *umap); + +__isl_export +__isl_give isl_union_set *isl_union_map_wrap(__isl_take isl_union_map *umap); +__isl_export +__isl_give isl_union_map *isl_union_set_unwrap(__isl_take isl_union_set *uset); + +__isl_export +__isl_give isl_union_map *isl_union_map_zip(__isl_take isl_union_map *umap); +__isl_export +__isl_give isl_union_map *isl_union_map_curry(__isl_take isl_union_map *umap); +__isl_give isl_union_map *isl_union_map_range_curry( + __isl_take isl_union_map *umap); +__isl_export +__isl_give isl_union_map *isl_union_map_uncurry(__isl_take isl_union_map *umap); + +__isl_give isl_union_map *isl_union_map_align_params( + __isl_take isl_union_map *umap, __isl_take isl_space *model); +__isl_give isl_union_set *isl_union_set_align_params( + __isl_take isl_union_set *uset, __isl_take isl_space *model); + +ISL_DECLARE_LIST_FN(union_map) + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/external/mit/isl/dist/include/isl/union_map_type.h b/external/mit/isl/dist/include/isl/union_map_type.h new file mode 100644 index 000000000000..7b6e69f573e6 --- /dev/null +++ b/external/mit/isl/dist/include/isl/union_map_type.h @@ -0,0 +1,24 @@ +#ifndef ISL_UNION_MAP_TYPE_H +#define ISL_UNION_MAP_TYPE_H + +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +struct __isl_export isl_union_map; +typedef struct isl_union_map isl_union_map; +ISL_DECLARE_LIST_TYPE(union_map) +#ifndef isl_union_set +struct __isl_export isl_union_set; +typedef struct isl_union_set isl_union_set; +ISL_DECLARE_EXPORTED_LIST_TYPE(union_set) +#endif + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/external/mit/isl/dist/include/isl/union_set.h b/external/mit/isl/dist/include/isl/union_set.h new file mode 100644 index 000000000000..b86196de41e9 --- /dev/null +++ b/external/mit/isl/dist/include/isl/union_set.h @@ -0,0 +1,204 @@ +#ifndef ISL_UNION_SET_H +#define ISL_UNION_SET_H + +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +isl_size isl_union_set_dim(__isl_keep isl_union_set *uset, + enum isl_dim_type type); + +__isl_constructor +__isl_give isl_union_set *isl_union_set_from_basic_set( + __isl_take isl_basic_set *bset); +__isl_export +__isl_give isl_union_set *isl_set_to_union_set(__isl_take isl_set *set); +__isl_constructor +__isl_give isl_union_set *isl_union_set_from_set(__isl_take isl_set *set); +__isl_overload +__isl_give isl_union_set *isl_union_set_empty_ctx(isl_ctx *ctx); +__isl_give isl_union_set *isl_union_set_empty_space( + __isl_take isl_space *space); +__isl_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); + +isl_ctx *isl_union_set_get_ctx(__isl_keep isl_union_set *uset); +__isl_export +__isl_give isl_space *isl_union_set_get_space(__isl_keep isl_union_set *uset); + +__isl_give isl_union_set *isl_union_set_reset_user( + __isl_take isl_union_set *uset); + +__isl_export +__isl_give isl_union_set *isl_union_set_universe( + __isl_take isl_union_set *uset); +__isl_export +__isl_give isl_set *isl_union_set_params(__isl_take isl_union_set *uset); + +__isl_export +__isl_give isl_union_set *isl_union_set_detect_equalities( + __isl_take isl_union_set *uset); +__isl_export +__isl_give isl_union_set *isl_union_set_affine_hull( + __isl_take isl_union_set *uset); +__isl_export +__isl_give isl_union_set *isl_union_set_polyhedral_hull( + __isl_take isl_union_set *uset); +__isl_give isl_union_set *isl_union_set_remove_redundancies( + __isl_take isl_union_set *uset); +__isl_give isl_union_set *isl_union_set_simple_hull( + __isl_take isl_union_set *uset); +__isl_export +__isl_give isl_union_set *isl_union_set_coalesce( + __isl_take isl_union_set *uset); +__isl_export +__isl_give isl_union_set *isl_union_set_compute_divs( + __isl_take isl_union_set *uset); +__isl_export +__isl_give isl_union_set *isl_union_set_lexmin(__isl_take isl_union_set *uset); +__isl_export +__isl_give isl_union_set *isl_union_set_lexmax(__isl_take isl_union_set *uset); + +__isl_give isl_union_set *isl_union_set_add_set(__isl_take isl_union_set *uset, + __isl_take isl_set *set); +__isl_export +__isl_give isl_union_set *isl_union_set_union(__isl_take isl_union_set *uset1, + __isl_take isl_union_set *uset2); +__isl_export +__isl_give isl_union_set *isl_union_set_subtract( + __isl_take isl_union_set *uset1, __isl_take isl_union_set *uset2); +__isl_export +__isl_give isl_union_set *isl_union_set_intersect( + __isl_take isl_union_set *uset1, __isl_take isl_union_set *uset2); +__isl_export +__isl_give isl_union_set *isl_union_set_intersect_params( + __isl_take isl_union_set *uset, __isl_take isl_set *set); +__isl_give isl_union_set *isl_union_set_product(__isl_take isl_union_set *uset1, + __isl_take isl_union_set *uset2); +__isl_export +__isl_give isl_union_set *isl_union_set_gist(__isl_take isl_union_set *uset, + __isl_take isl_union_set *context); +__isl_export +__isl_give isl_union_set *isl_union_set_gist_params( + __isl_take isl_union_set *uset, __isl_take isl_set *set); + +__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); + +__isl_give isl_union_set *isl_union_set_project_out( + __isl_take isl_union_set *uset, + enum isl_dim_type type, unsigned first, unsigned n); +__isl_export +__isl_give isl_union_set *isl_union_set_project_out_all_params( + __isl_take isl_union_set *uset); +__isl_export +__isl_give isl_union_set *isl_union_set_drop_unused_params( + __isl_take isl_union_set *uset); +__isl_give isl_union_set *isl_union_set_remove_divs( + __isl_take isl_union_set *bset); + +isl_bool isl_union_set_is_params(__isl_keep isl_union_set *uset); +__isl_export +isl_bool isl_union_set_is_empty(__isl_keep isl_union_set *uset); + +__isl_export +isl_bool isl_union_set_is_subset(__isl_keep isl_union_set *uset1, + __isl_keep isl_union_set *uset2); +__isl_export +isl_bool isl_union_set_is_equal(__isl_keep isl_union_set *uset1, + __isl_keep isl_union_set *uset2); +__isl_export +isl_bool isl_union_set_is_disjoint(__isl_keep isl_union_set *uset1, + __isl_keep isl_union_set *uset2); +__isl_export +isl_bool isl_union_set_is_strict_subset(__isl_keep isl_union_set *uset1, + __isl_keep isl_union_set *uset2); + +uint32_t isl_union_set_get_hash(__isl_keep isl_union_set *uset); + +isl_size isl_union_set_n_set(__isl_keep isl_union_set *uset); +__isl_export +isl_stat isl_union_set_foreach_set(__isl_keep isl_union_set *uset, + isl_stat (*fn)(__isl_take isl_set *set, void *user), void *user); +__isl_export +isl_bool isl_union_set_every_set(__isl_keep isl_union_set *uset, + isl_bool (*test)(__isl_keep isl_set *set, void *user), void *user); +__isl_give isl_basic_set_list *isl_union_set_get_basic_set_list( + __isl_keep isl_union_set *uset); +__isl_export +__isl_give isl_set_list *isl_union_set_get_set_list( + __isl_keep isl_union_set *uset); +isl_bool isl_union_set_contains(__isl_keep isl_union_set *uset, + __isl_keep isl_space *space); +__isl_export +__isl_give isl_set *isl_union_set_extract_set(__isl_keep isl_union_set *uset, + __isl_take isl_space *space); +__isl_export +isl_bool isl_union_set_isa_set(__isl_keep isl_union_set *uset); +__isl_export +__isl_give isl_set *isl_union_set_as_set(__isl_take isl_union_set *uset); +__isl_give isl_set *isl_set_from_union_set(__isl_take isl_union_set *uset); +__isl_export +isl_stat isl_union_set_foreach_point(__isl_keep isl_union_set *uset, + isl_stat (*fn)(__isl_take isl_point *pnt, void *user), void *user); + +__isl_give isl_basic_set *isl_union_set_sample(__isl_take isl_union_set *uset); +__isl_export +__isl_give isl_point *isl_union_set_sample_point( + __isl_take isl_union_set *uset); + +__isl_constructor +__isl_give isl_union_set *isl_union_set_from_point(__isl_take isl_point *pnt); + +__isl_give isl_union_set *isl_union_set_lift(__isl_take isl_union_set *uset); + +__isl_give isl_union_map *isl_union_set_lex_lt_union_set( + __isl_take isl_union_set *uset1, __isl_take isl_union_set *uset2); +__isl_give isl_union_map *isl_union_set_lex_le_union_set( + __isl_take isl_union_set *uset1, __isl_take isl_union_set *uset2); +__isl_give isl_union_map *isl_union_set_lex_gt_union_set( + __isl_take isl_union_set *uset1, __isl_take isl_union_set *uset2); +__isl_give isl_union_map *isl_union_set_lex_ge_union_set( + __isl_take isl_union_set *uset1, __isl_take isl_union_set *uset2); + +__isl_give isl_union_set *isl_union_set_coefficients( + __isl_take isl_union_set *bset); +__isl_give isl_union_set *isl_union_set_solutions( + __isl_take isl_union_set *bset); + +__isl_give isl_union_set *isl_union_set_read_from_file(isl_ctx *ctx, + FILE *input); +__isl_constructor +__isl_give isl_union_set *isl_union_set_read_from_str(isl_ctx *ctx, + const char *str); +__isl_give char *isl_union_set_to_str(__isl_keep isl_union_set *uset); +__isl_give isl_printer *isl_printer_print_union_set(__isl_take isl_printer *p, + __isl_keep isl_union_set *uset); +void isl_union_set_dump(__isl_keep isl_union_set *uset); + +ISL_DECLARE_EXPORTED_LIST_FN(union_set) +ISL_DECLARE_EXPORTED_LIST_FN_READ(union_set) + +__isl_give isl_union_set *isl_union_set_list_union( + __isl_take isl_union_set_list *list); + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/external/mit/isl/dist/include/isl/union_set_type.h b/external/mit/isl/dist/include/isl/union_set_type.h new file mode 100644 index 000000000000..86b2c317fa1a --- /dev/null +++ b/external/mit/isl/dist/include/isl/union_set_type.h @@ -0,0 +1,6 @@ +#ifndef ISL_UNION_SET_TYPE_H +#define ISL_UNION_SET_TYPE_H + +#include + +#endif diff --git a/external/mit/isl/dist/include/isl/val.h b/external/mit/isl/dist/include/isl/val.h new file mode 100644 index 000000000000..942207db9167 --- /dev/null +++ b/external/mit/isl/dist/include/isl/val.h @@ -0,0 +1,179 @@ +#ifndef ISL_VAL_H +#define ISL_VAL_H + +#include +#include +#include +#include +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +ISL_DECLARE_MULTI(val) +ISL_DECLARE_MULTI_ARITH(val) +ISL_DECLARE_MULTI_MIN_MAX(val) +ISL_DECLARE_MULTI_ZERO(val) +ISL_DECLARE_MULTI_NAN(val) +ISL_DECLARE_MULTI_DIMS(val) +ISL_DECLARE_MULTI_DIM_ID(val) +ISL_DECLARE_MULTI_TUPLE_ID(val) +ISL_DECLARE_MULTI_WITH_DOMAIN(val) + +__isl_export +__isl_give isl_val *isl_val_zero(isl_ctx *ctx); +__isl_export +__isl_give isl_val *isl_val_one(isl_ctx *ctx); +__isl_export +__isl_give isl_val *isl_val_negone(isl_ctx *ctx); +__isl_export +__isl_give isl_val *isl_val_nan(isl_ctx *ctx); +__isl_export +__isl_give isl_val *isl_val_infty(isl_ctx *ctx); +__isl_export +__isl_give isl_val *isl_val_neginfty(isl_ctx *ctx); +__isl_constructor +__isl_give isl_val *isl_val_int_from_si(isl_ctx *ctx, long i); +__isl_give isl_val *isl_val_int_from_ui(isl_ctx *ctx, unsigned long u); +__isl_give isl_val *isl_val_int_from_chunks(isl_ctx *ctx, size_t n, + size_t size, const void *chunks); + +__isl_give isl_val *isl_val_copy(__isl_keep isl_val *v); +__isl_null isl_val *isl_val_free(__isl_take isl_val *v); + +isl_ctx *isl_val_get_ctx(__isl_keep isl_val *val); +uint32_t isl_val_get_hash(__isl_keep isl_val *val); +__isl_export +long isl_val_get_num_si(__isl_keep isl_val *v); +__isl_export +long isl_val_get_den_si(__isl_keep isl_val *v); +__isl_give isl_val *isl_val_get_den_val(__isl_keep isl_val *v); +double isl_val_get_d(__isl_keep isl_val *v); +isl_size isl_val_n_abs_num_chunks(__isl_keep isl_val *v, size_t size); +isl_stat isl_val_get_abs_num_chunks(__isl_keep isl_val *v, size_t size, + void *chunks); + +__isl_give isl_val *isl_val_set_si(__isl_take isl_val *v, long i); + +__isl_export +__isl_give isl_val *isl_val_abs(__isl_take isl_val *v); +__isl_export +__isl_give isl_val *isl_val_neg(__isl_take isl_val *v); +__isl_export +__isl_give isl_val *isl_val_inv(__isl_take isl_val *v); +__isl_export +__isl_give isl_val *isl_val_floor(__isl_take isl_val *v); +__isl_export +__isl_give isl_val *isl_val_ceil(__isl_take isl_val *v); +__isl_export +__isl_give isl_val *isl_val_trunc(__isl_take isl_val *v); +__isl_give isl_val *isl_val_2exp(__isl_take isl_val *v); +__isl_export +__isl_give isl_val *isl_val_pow2(__isl_take isl_val *v); +__isl_export +__isl_give isl_val *isl_val_min(__isl_take isl_val *v1, __isl_take isl_val *v2); +__isl_export +__isl_give isl_val *isl_val_max(__isl_take isl_val *v1, __isl_take isl_val *v2); +__isl_export +__isl_give isl_val *isl_val_add(__isl_take isl_val *v1, __isl_take isl_val *v2); +__isl_give isl_val *isl_val_add_ui(__isl_take isl_val *v1, unsigned long v2); +__isl_export +__isl_give isl_val *isl_val_sub(__isl_take isl_val *v1, __isl_take isl_val *v2); +__isl_give isl_val *isl_val_sub_ui(__isl_take isl_val *v1, unsigned long v2); +__isl_export +__isl_give isl_val *isl_val_mul(__isl_take isl_val *v1, __isl_take isl_val *v2); +__isl_give isl_val *isl_val_mul_ui(__isl_take isl_val *v1, unsigned long v2); +__isl_export +__isl_give isl_val *isl_val_div(__isl_take isl_val *v1, __isl_take isl_val *v2); +__isl_give isl_val *isl_val_div_ui(__isl_take isl_val *v1, unsigned long v2); +__isl_export +__isl_give isl_val *isl_val_mod(__isl_take isl_val *v1, __isl_take isl_val *v2); +__isl_export +__isl_give isl_val *isl_val_gcd(__isl_take isl_val *v1, __isl_take isl_val *v2); +__isl_give isl_val *isl_val_gcdext(__isl_take isl_val *v1, + __isl_take isl_val *v2, __isl_give isl_val **x, __isl_give isl_val **y); + +__isl_export +int isl_val_sgn(__isl_keep isl_val *v); +__isl_export +isl_bool isl_val_is_zero(__isl_keep isl_val *v); +__isl_export +isl_bool isl_val_is_one(__isl_keep isl_val *v); +__isl_export +isl_bool isl_val_is_negone(__isl_keep isl_val *v); +__isl_export +isl_bool isl_val_is_nonneg(__isl_keep isl_val *v); +__isl_export +isl_bool isl_val_is_nonpos(__isl_keep isl_val *v); +__isl_export +isl_bool isl_val_is_pos(__isl_keep isl_val *v); +__isl_export +isl_bool isl_val_is_neg(__isl_keep isl_val *v); +__isl_export +isl_bool isl_val_is_int(__isl_keep isl_val *v); +__isl_export +isl_bool isl_val_is_rat(__isl_keep isl_val *v); +__isl_export +isl_bool isl_val_is_nan(__isl_keep isl_val *v); +__isl_export +isl_bool isl_val_is_infty(__isl_keep isl_val *v); +__isl_export +isl_bool isl_val_is_neginfty(__isl_keep isl_val *v); + +__isl_export +int isl_val_cmp_si(__isl_keep isl_val *v, long i); + +__isl_export +isl_bool isl_val_lt(__isl_keep isl_val *v1, __isl_keep isl_val *v2); +__isl_export +isl_bool isl_val_le(__isl_keep isl_val *v1, __isl_keep isl_val *v2); +__isl_export +isl_bool isl_val_gt(__isl_keep isl_val *v1, __isl_keep isl_val *v2); +isl_bool isl_val_gt_si(__isl_keep isl_val *v, long i); +__isl_export +isl_bool isl_val_ge(__isl_keep isl_val *v1, __isl_keep isl_val *v2); +__isl_export +isl_bool isl_val_eq(__isl_keep isl_val *v1, __isl_keep isl_val *v2); +isl_bool isl_val_eq_si(__isl_keep isl_val *v, long i); +__isl_export +isl_bool isl_val_ne(__isl_keep isl_val *v1, __isl_keep isl_val *v2); +__isl_export +isl_bool isl_val_abs_eq(__isl_keep isl_val *v1, __isl_keep isl_val *v2); + +__isl_export +isl_bool isl_val_is_divisible_by(__isl_keep isl_val *v1, + __isl_keep isl_val *v2); + +__isl_constructor +__isl_give isl_val *isl_val_read_from_str(isl_ctx *ctx, const char *str); +__isl_give isl_printer *isl_printer_print_val(__isl_take isl_printer *p, + __isl_keep isl_val *v); +void isl_val_dump(__isl_keep isl_val *v); +__isl_give char *isl_val_to_str(__isl_keep isl_val *v); + +isl_bool isl_multi_val_is_zero(__isl_keep isl_multi_val *mv); + +__isl_overload +__isl_give isl_multi_val *isl_multi_val_add_val(__isl_take isl_multi_val *mv, + __isl_take isl_val *v); +__isl_give isl_multi_val *isl_multi_val_mod_val(__isl_take isl_multi_val *mv, + __isl_take isl_val *v); + +__isl_constructor +__isl_give isl_multi_val *isl_multi_val_read_from_str(isl_ctx *ctx, + const char *str); +__isl_give isl_printer *isl_printer_print_multi_val(__isl_take isl_printer *p, + __isl_keep isl_multi_val *mv); +void isl_multi_val_dump(__isl_keep isl_multi_val *mv); +__isl_give char *isl_multi_val_to_str(__isl_keep isl_multi_val *mv); + +ISL_DECLARE_EXPORTED_LIST_FN(val) +ISL_DECLARE_EXPORTED_LIST_FN_READ(val) + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/external/mit/isl/dist/include/isl/val_gmp.h b/external/mit/isl/dist/include/isl/val_gmp.h new file mode 100644 index 000000000000..dbc1501630f2 --- /dev/null +++ b/external/mit/isl/dist/include/isl/val_gmp.h @@ -0,0 +1,21 @@ +#ifndef ISL_VAL_GMP_H +#define ISL_VAL_GMP_H + +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +__isl_give isl_val *isl_val_int_from_gmp(isl_ctx *ctx, mpz_t z); +__isl_give isl_val *isl_val_from_gmp(isl_ctx *ctx, + const mpz_t n, const mpz_t d); +int isl_val_get_num_gmp(__isl_keep isl_val *v, mpz_t z); +int isl_val_get_den_gmp(__isl_keep isl_val *v, mpz_t z); + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/external/mit/isl/dist/include/isl/val_type.h b/external/mit/isl/dist/include/isl/val_type.h new file mode 100644 index 000000000000..ede64013c6ba --- /dev/null +++ b/external/mit/isl/dist/include/isl/val_type.h @@ -0,0 +1,22 @@ +#ifndef ISL_VAL_TYPE_H +#define ISL_VAL_TYPE_H + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +struct __isl_export isl_val; +typedef struct isl_val isl_val; + +ISL_DECLARE_EXPORTED_LIST_TYPE(val) + +struct __isl_export isl_multi_val; +typedef struct isl_multi_val isl_multi_val; + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/external/mit/isl/dist/include/isl/vec.h b/external/mit/isl/dist/include/isl/vec.h new file mode 100644 index 000000000000..71f7d64217aa --- /dev/null +++ b/external/mit/isl/dist/include/isl/vec.h @@ -0,0 +1,80 @@ +/* + * 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_VEC_H +#define ISL_VEC_H + +#include + +#include +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +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); + +isl_ctx *isl_vec_get_ctx(__isl_keep isl_vec *vec); + +isl_size isl_vec_size(__isl_keep isl_vec *vec); +__isl_give isl_val *isl_vec_get_element_val(__isl_keep isl_vec *vec, int pos); +__isl_give isl_vec *isl_vec_set_element_si(__isl_take isl_vec *vec, + int pos, int v); +__isl_give isl_vec *isl_vec_set_element_val(__isl_take isl_vec *vec, + int pos, __isl_take isl_val *v); + +isl_bool isl_vec_is_equal(__isl_keep isl_vec *vec1, __isl_keep isl_vec *vec2); +int isl_vec_cmp_element(__isl_keep isl_vec *vec1, __isl_keep isl_vec *vec2, + int pos); + +void isl_vec_dump(__isl_keep isl_vec *vec); +__isl_give isl_printer *isl_printer_print_vec(__isl_take isl_printer *printer, + __isl_keep isl_vec *vec); + +__isl_give isl_vec *isl_vec_ceil(__isl_take isl_vec *vec); +__isl_give isl_vec *isl_vec_normalize(__isl_take isl_vec *vec); +__isl_give isl_vec *isl_vec_set_si(__isl_take isl_vec *vec, int v); +__isl_give isl_vec *isl_vec_set_val(__isl_take isl_vec *vec, + __isl_take isl_val *v); +__isl_give isl_vec *isl_vec_clr(__isl_take isl_vec *vec); +__isl_give isl_vec *isl_vec_neg(__isl_take isl_vec *vec); +__isl_give isl_vec *isl_vec_add(__isl_take isl_vec *vec1, + __isl_take isl_vec *vec2); +__isl_give isl_vec *isl_vec_extend(__isl_take isl_vec *vec, unsigned size); +__isl_give isl_vec *isl_vec_zero_extend(__isl_take isl_vec *vec, unsigned size); +__isl_give isl_vec *isl_vec_concat(__isl_take isl_vec *vec1, + __isl_take isl_vec *vec2); + +__isl_give isl_vec *isl_vec_sort(__isl_take isl_vec *vec); + +__isl_give isl_vec *isl_vec_read_from_file(isl_ctx *ctx, FILE *input); + +__isl_give isl_vec *isl_vec_drop_els(__isl_take isl_vec *vec, + unsigned pos, unsigned n); +__isl_give isl_vec *isl_vec_add_els(__isl_take isl_vec *vec, unsigned n); +__isl_give isl_vec *isl_vec_insert_els(__isl_take isl_vec *vec, + unsigned pos, unsigned n); +__isl_give isl_vec *isl_vec_insert_zero_els(__isl_take isl_vec *vec, + unsigned pos, unsigned n); +__isl_give isl_vec *isl_vec_move_els(__isl_take isl_vec *vec, + unsigned dst_col, unsigned src_col, unsigned n); + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/external/mit/isl/dist/include/isl/version.h b/external/mit/isl/dist/include/isl/version.h new file mode 100644 index 000000000000..7f8f23d69451 --- /dev/null +++ b/external/mit/isl/dist/include/isl/version.h @@ -0,0 +1,14 @@ +#ifndef ISL_VERSION_H +#define ISL_VERSION_H + +#if defined(__cplusplus) +extern "C" { +#endif + +const char *isl_version(void); + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/external/mit/isl/dist/include/isl/vertices.h b/external/mit/isl/dist/include/isl/vertices.h new file mode 100644 index 000000000000..9a7ac508c56c --- /dev/null +++ b/external/mit/isl/dist/include/isl/vertices.h @@ -0,0 +1,47 @@ +#ifndef ISL_VERTICES_H +#define ISL_VERTICES_H + +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +struct isl_external_vertex; +typedef struct isl_external_vertex isl_vertex; + +struct isl_cell; +typedef struct isl_cell isl_cell; + +struct isl_vertices; +typedef struct isl_vertices isl_vertices; + +isl_ctx *isl_vertex_get_ctx(__isl_keep isl_vertex *vertex); +isl_size isl_vertex_get_id(__isl_keep isl_vertex *vertex); +__isl_give isl_basic_set *isl_vertex_get_domain(__isl_keep isl_vertex *vertex); +__isl_give isl_multi_aff *isl_vertex_get_expr(__isl_keep isl_vertex *vertex); +__isl_null isl_vertex *isl_vertex_free(__isl_take isl_vertex *vertex); + +__isl_give isl_vertices *isl_basic_set_compute_vertices( + __isl_keep isl_basic_set *bset); +isl_ctx *isl_vertices_get_ctx(__isl_keep isl_vertices *vertices); +isl_size isl_vertices_get_n_vertices(__isl_keep isl_vertices *vertices); +isl_stat isl_vertices_foreach_vertex(__isl_keep isl_vertices *vertices, + isl_stat (*fn)(__isl_take isl_vertex *vertex, void *user), void *user); +__isl_null isl_vertices *isl_vertices_free(__isl_take isl_vertices *vertices); + +isl_ctx *isl_cell_get_ctx(__isl_keep isl_cell *cell); +__isl_give isl_basic_set *isl_cell_get_domain(__isl_keep isl_cell *cell); +isl_stat isl_cell_foreach_vertex(__isl_keep isl_cell *cell, + isl_stat (*fn)(__isl_take isl_vertex *vertex, void *user), void *user); +__isl_null isl_cell *isl_cell_free(__isl_take isl_cell *cell); + +isl_stat isl_vertices_foreach_cell(__isl_keep isl_vertices *vertices, + isl_stat (*fn)(__isl_take isl_cell *cell, void *user), void *user); + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/external/mit/isl/dist/install-sh b/external/mit/isl/dist/install-sh new file mode 100755 index 000000000000..ec298b537402 --- /dev/null +++ b/external/mit/isl/dist/install-sh @@ -0,0 +1,541 @@ +#!/bin/sh +# install - install a program, script, or datafile + +scriptversion=2020-11-14.01; # UTC + +# This originates from X11R5 (mit/util/scripts/install.sh), which was +# later released in X11R6 (xc/config/util/install.sh) with the +# following copyright and license. +# +# Copyright (C) 1994 X Consortium +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- +# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# Except as contained in this notice, the name of the X Consortium shall not +# be used in advertising or otherwise to promote the sale, use or other deal- +# ings in this Software without prior written authorization from the X Consor- +# tium. +# +# +# FSF changes to this file are in the public domain. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# 'make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. + +tab=' ' +nl=' +' +IFS=" $tab$nl" + +# Set DOITPROG to "echo" to test this script. + +doit=${DOITPROG-} +doit_exec=${doit:-exec} + +# Put in absolute file names if you don't have them in your path; +# or use environment vars. + +chgrpprog=${CHGRPPROG-chgrp} +chmodprog=${CHMODPROG-chmod} +chownprog=${CHOWNPROG-chown} +cmpprog=${CMPPROG-cmp} +cpprog=${CPPROG-cp} +mkdirprog=${MKDIRPROG-mkdir} +mvprog=${MVPROG-mv} +rmprog=${RMPROG-rm} +stripprog=${STRIPPROG-strip} + +posix_mkdir= + +# Desired mode of installed file. +mode=0755 + +# Create dirs (including intermediate dirs) using mode 755. +# This is like GNU 'install' as of coreutils 8.32 (2020). +mkdir_umask=22 + +backupsuffix= +chgrpcmd= +chmodcmd=$chmodprog +chowncmd= +mvcmd=$mvprog +rmcmd="$rmprog -f" +stripcmd= + +src= +dst= +dir_arg= +dst_arg= + +copy_on_change=false +is_target_a_directory=possibly + +usage="\ +Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE + or: $0 [OPTION]... SRCFILES... DIRECTORY + or: $0 [OPTION]... -t DIRECTORY SRCFILES... + or: $0 [OPTION]... -d DIRECTORIES... + +In the 1st form, copy SRCFILE to DSTFILE. +In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. +In the 4th, create DIRECTORIES. + +Options: + --help display this help and exit. + --version display version info and exit. + + -c (ignored) + -C install only if different (preserve data modification time) + -d create directories instead of installing files. + -g GROUP $chgrpprog installed files to GROUP. + -m MODE $chmodprog installed files to MODE. + -o USER $chownprog installed files to USER. + -p pass -p to $cpprog. + -s $stripprog installed files. + -S SUFFIX attempt to back up existing files, with suffix SUFFIX. + -t DIRECTORY install into DIRECTORY. + -T report an error if DSTFILE is a directory. + +Environment variables override the default commands: + CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG + RMPROG STRIPPROG + +By default, rm is invoked with -f; when overridden with RMPROG, +it's up to you to specify -f if you want it. + +If -S is not specified, no backups are attempted. + +Email bug reports to bug-automake@gnu.org. +Automake home page: https://www.gnu.org/software/automake/ +" + +while test $# -ne 0; do + case $1 in + -c) ;; + + -C) copy_on_change=true;; + + -d) dir_arg=true;; + + -g) chgrpcmd="$chgrpprog $2" + shift;; + + --help) echo "$usage"; exit $?;; + + -m) mode=$2 + case $mode in + *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) + echo "$0: invalid mode: $mode" >&2 + exit 1;; + esac + shift;; + + -o) chowncmd="$chownprog $2" + shift;; + + -p) cpprog="$cpprog -p";; + + -s) stripcmd=$stripprog;; + + -S) backupsuffix="$2" + shift;; + + -t) + is_target_a_directory=always + dst_arg=$2 + # Protect names problematic for 'test' and other utilities. + case $dst_arg in + -* | [=\(\)!]) dst_arg=./$dst_arg;; + esac + shift;; + + -T) is_target_a_directory=never;; + + --version) echo "$0 $scriptversion"; exit $?;; + + --) shift + break;; + + -*) echo "$0: invalid option: $1" >&2 + exit 1;; + + *) break;; + esac + shift +done + +# We allow the use of options -d and -T together, by making -d +# take the precedence; this is for compatibility with GNU install. + +if test -n "$dir_arg"; then + if test -n "$dst_arg"; then + echo "$0: target directory not allowed when installing a directory." >&2 + exit 1 + fi +fi + +if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then + # When -d is used, all remaining arguments are directories to create. + # When -t is used, the destination is already specified. + # Otherwise, the last argument is the destination. Remove it from $@. + for arg + do + if test -n "$dst_arg"; then + # $@ is not empty: it contains at least $arg. + set fnord "$@" "$dst_arg" + shift # fnord + fi + shift # arg + dst_arg=$arg + # Protect names problematic for 'test' and other utilities. + case $dst_arg in + -* | [=\(\)!]) dst_arg=./$dst_arg;; + esac + done +fi + +if test $# -eq 0; then + if test -z "$dir_arg"; then + echo "$0: no input file specified." >&2 + exit 1 + fi + # It's OK to call 'install-sh -d' without argument. + # This can happen when creating conditional directories. + exit 0 +fi + +if test -z "$dir_arg"; then + if test $# -gt 1 || test "$is_target_a_directory" = always; then + if test ! -d "$dst_arg"; then + echo "$0: $dst_arg: Is not a directory." >&2 + exit 1 + fi + fi +fi + +if test -z "$dir_arg"; then + do_exit='(exit $ret); exit $ret' + trap "ret=129; $do_exit" 1 + trap "ret=130; $do_exit" 2 + trap "ret=141; $do_exit" 13 + trap "ret=143; $do_exit" 15 + + # Set umask so as not to create temps with too-generous modes. + # However, 'strip' requires both read and write access to temps. + case $mode in + # Optimize common cases. + *644) cp_umask=133;; + *755) cp_umask=22;; + + *[0-7]) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw='% 200' + fi + cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; + *) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw=,u+rw + fi + cp_umask=$mode$u_plus_rw;; + esac +fi + +for src +do + # Protect names problematic for 'test' and other utilities. + case $src in + -* | [=\(\)!]) src=./$src;; + esac + + if test -n "$dir_arg"; then + dst=$src + dstdir=$dst + test -d "$dstdir" + dstdir_status=$? + # Don't chown directories that already exist. + if test $dstdir_status = 0; then + chowncmd="" + fi + else + + # Waiting for this to be detected by the "$cpprog $src $dsttmp" command + # might cause directories to be created, which would be especially bad + # if $src (and thus $dsttmp) contains '*'. + if test ! -f "$src" && test ! -d "$src"; then + echo "$0: $src does not exist." >&2 + exit 1 + fi + + if test -z "$dst_arg"; then + echo "$0: no destination specified." >&2 + exit 1 + fi + dst=$dst_arg + + # If destination is a directory, append the input filename. + if test -d "$dst"; then + if test "$is_target_a_directory" = never; then + echo "$0: $dst_arg: Is a directory" >&2 + exit 1 + fi + dstdir=$dst + dstbase=`basename "$src"` + case $dst in + */) dst=$dst$dstbase;; + *) dst=$dst/$dstbase;; + esac + dstdir_status=0 + else + dstdir=`dirname "$dst"` + test -d "$dstdir" + dstdir_status=$? + fi + fi + + case $dstdir in + */) dstdirslash=$dstdir;; + *) dstdirslash=$dstdir/;; + esac + + obsolete_mkdir_used=false + + if test $dstdir_status != 0; then + case $posix_mkdir in + '') + # With -d, create the new directory with the user-specified mode. + # Otherwise, rely on $mkdir_umask. + if test -n "$dir_arg"; then + mkdir_mode=-m$mode + else + mkdir_mode= + fi + + posix_mkdir=false + # The $RANDOM variable is not portable (e.g., dash). Use it + # here however when possible just to lower collision chance. + tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ + + trap ' + ret=$? + rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null + exit $ret + ' 0 + + # Because "mkdir -p" follows existing symlinks and we likely work + # directly in world-writeable /tmp, make sure that the '$tmpdir' + # directory is successfully created first before we actually test + # 'mkdir -p'. + if (umask $mkdir_umask && + $mkdirprog $mkdir_mode "$tmpdir" && + exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1 + then + if test -z "$dir_arg" || { + # Check for POSIX incompatibilities with -m. + # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or + # other-writable bit of parent directory when it shouldn't. + # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. + test_tmpdir="$tmpdir/a" + ls_ld_tmpdir=`ls -ld "$test_tmpdir"` + case $ls_ld_tmpdir in + d????-?r-*) different_mode=700;; + d????-?--*) different_mode=755;; + *) false;; + esac && + $mkdirprog -m$different_mode -p -- "$test_tmpdir" && { + ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"` + test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" + } + } + then posix_mkdir=: + fi + rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" + else + # Remove any dirs left behind by ancient mkdir implementations. + rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null + fi + trap '' 0;; + esac + + if + $posix_mkdir && ( + umask $mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" + ) + then : + else + + # mkdir does not conform to POSIX, + # or it failed possibly due to a race condition. Create the + # directory the slow way, step by step, checking for races as we go. + + case $dstdir in + /*) prefix='/';; + [-=\(\)!]*) prefix='./';; + *) prefix='';; + esac + + oIFS=$IFS + IFS=/ + set -f + set fnord $dstdir + shift + set +f + IFS=$oIFS + + prefixes= + + for d + do + test X"$d" = X && continue + + prefix=$prefix$d + if test -d "$prefix"; then + prefixes= + else + if $posix_mkdir; then + (umask $mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break + # Don't fail if two instances are running concurrently. + test -d "$prefix" || exit 1 + else + case $prefix in + *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; + *) qprefix=$prefix;; + esac + prefixes="$prefixes '$qprefix'" + fi + fi + prefix=$prefix/ + done + + if test -n "$prefixes"; then + # Don't fail if two instances are running concurrently. + (umask $mkdir_umask && + eval "\$doit_exec \$mkdirprog $prefixes") || + test -d "$dstdir" || exit 1 + obsolete_mkdir_used=true + fi + fi + fi + + if test -n "$dir_arg"; then + { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && + { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || + test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 + else + + # Make a couple of temp file names in the proper directory. + dsttmp=${dstdirslash}_inst.$$_ + rmtmp=${dstdirslash}_rm.$$_ + + # Trap to clean up those temp files at exit. + trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 + + # Copy the file name to the temp name. + (umask $cp_umask && + { test -z "$stripcmd" || { + # Create $dsttmp read-write so that cp doesn't create it read-only, + # which would cause strip to fail. + if test -z "$doit"; then + : >"$dsttmp" # No need to fork-exec 'touch'. + else + $doit touch "$dsttmp" + fi + } + } && + $doit_exec $cpprog "$src" "$dsttmp") && + + # and set any options; do chmod last to preserve setuid bits. + # + # If any of these fail, we abort the whole thing. If we want to + # ignore errors from any of these, just make sure not to ignore + # errors from the above "$doit $cpprog $src $dsttmp" command. + # + { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && + { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && + { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && + + # If -C, don't bother to copy if it wouldn't change the file. + if $copy_on_change && + old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && + new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && + set -f && + set X $old && old=:$2:$4:$5:$6 && + set X $new && new=:$2:$4:$5:$6 && + set +f && + test "$old" = "$new" && + $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 + then + rm -f "$dsttmp" + else + # If $backupsuffix is set, and the file being installed + # already exists, attempt a backup. Don't worry if it fails, + # e.g., if mv doesn't support -f. + if test -n "$backupsuffix" && test -f "$dst"; then + $doit $mvcmd -f "$dst" "$dst$backupsuffix" 2>/dev/null + fi + + # Rename the file to the real destination. + $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || + + # The rename failed, perhaps because mv can't rename something else + # to itself, or perhaps because mv is so ancient that it does not + # support -f. + { + # Now remove or move aside any old file at destination location. + # We try this two ways since rm can't unlink itself on some + # systems and the destination file might be busy for other + # reasons. In this case, the final cleanup might fail but the new + # file should still install successfully. + { + test ! -f "$dst" || + $doit $rmcmd "$dst" 2>/dev/null || + { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && + { $doit $rmcmd "$rmtmp" 2>/dev/null; :; } + } || + { echo "$0: cannot unlink or rename $dst" >&2 + (exit 1); exit 1 + } + } && + + # Now rename the file to the real destination. + $doit $mvcmd "$dsttmp" "$dst" + } + fi || exit 1 + + trap '' 0 + fi +done + +# Local variables: +# eval: (add-hook 'before-save-hook 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC0" +# time-stamp-end: "; # UTC" +# End: diff --git a/external/mit/isl/dist/interface/Makefile.am b/external/mit/isl/dist/interface/Makefile.am new file mode 100644 index 000000000000..702f9a4854f2 --- /dev/null +++ b/external/mit/isl/dist/interface/Makefile.am @@ -0,0 +1,28 @@ +ACLOCAL_AMFLAGS = -I ../m4 +AUTOMAKE_OPTIONS = nostdinc + +noinst_PROGRAMS = extract_interface + +includes = -I$(top_builddir) -I$(top_srcdir) \ + -I$(top_builddir)/include -I$(top_srcdir)/include + +extract_interface_CPPFLAGS = $(includes) +extract_interface_CXXFLAGS = $(CLANG_CXXFLAGS) +extract_interface_SOURCES = \ + generator.h \ + generator.cc \ + python.h \ + python.cc \ + cpp.h \ + cpp.cc \ + cpp_conversion.h \ + cpp_conversion.cc \ + plain_cpp.h \ + plain_cpp.cc \ + set_lang_defaults_arg4.h \ + template_cpp.h \ + template_cpp.cc \ + extract_interface.h \ + extract_interface.cc +extract_interface_LDFLAGS = $(CLANG_LDFLAGS) $(CLANG_RFLAG) +extract_interface_LDADD = $(CLANG_LIBS) $(CLANG_LDFLAGS) diff --git a/external/mit/isl/dist/interface/Makefile.in b/external/mit/isl/dist/interface/Makefile.in new file mode 100644 index 000000000000..16b68bf5b085 --- /dev/null +++ b/external/mit/isl/dist/interface/Makefile.in @@ -0,0 +1,1003 @@ +# Makefile.in generated by automake 1.16.5 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2021 Free Software Foundation, Inc. + +# This Makefile.in 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. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +noinst_PROGRAMS = extract_interface$(EXEEXT) +subdir = . +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/../m4/ax_cxx_compile_stdcxx.m4 \ + $(top_srcdir)/../m4/ax_cxx_compile_stdcxx_11.m4 \ + $(top_srcdir)/../m4/ax_cxx_compile_stdcxx_11_no_override.m4 \ + $(top_srcdir)/../m4/ax_detect_clang.m4 \ + $(top_srcdir)/../m4/ax_prog_cc_for_build.m4 \ + $(top_srcdir)/../m4/ax_prog_cxx_for_build.m4 \ + $(top_srcdir)/../m4/libtool.m4 \ + $(top_srcdir)/../m4/ltoptions.m4 \ + $(top_srcdir)/../m4/ltsugar.m4 \ + $(top_srcdir)/../m4/ltversion.m4 \ + $(top_srcdir)/../m4/lt~obsolete.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \ + $(am__configure_deps) $(am__DIST_COMMON) +am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ + configure.lineno config.status.lineno +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = isl_config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +PROGRAMS = $(noinst_PROGRAMS) +am_extract_interface_OBJECTS = extract_interface-generator.$(OBJEXT) \ + extract_interface-python.$(OBJEXT) \ + extract_interface-cpp.$(OBJEXT) \ + extract_interface-cpp_conversion.$(OBJEXT) \ + extract_interface-plain_cpp.$(OBJEXT) \ + extract_interface-template_cpp.$(OBJEXT) \ + extract_interface-extract_interface.$(OBJEXT) +extract_interface_OBJECTS = $(am_extract_interface_OBJECTS) +am__DEPENDENCIES_1 = +extract_interface_DEPENDENCIES = $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +extract_interface_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \ + $(extract_interface_CXXFLAGS) $(CXXFLAGS) \ + $(extract_interface_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/extract_interface-cpp.Po \ + ./$(DEPDIR)/extract_interface-cpp_conversion.Po \ + ./$(DEPDIR)/extract_interface-extract_interface.Po \ + ./$(DEPDIR)/extract_interface-generator.Po \ + ./$(DEPDIR)/extract_interface-plain_cpp.Po \ + ./$(DEPDIR)/extract_interface-python.Po \ + ./$(DEPDIR)/extract_interface-template_cpp.Po +am__mv = mv -f +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CXXFLAGS) $(CXXFLAGS) +AM_V_CXX = $(am__v_CXX_@AM_V@) +am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) +am__v_CXX_0 = @echo " CXX " $@; +am__v_CXX_1 = +CXXLD = $(CXX) +CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ + $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) +am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) +am__v_CXXLD_0 = @echo " CXXLD " $@; +am__v_CXXLD_1 = +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(extract_interface_SOURCES) +DIST_SOURCES = $(extract_interface_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) \ + isl_config.h.in +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +AM_RECURSIVE_TARGETS = cscope +am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/isl_config.h.in \ + compile config.guess config.sub depcomp install-sh ltmain.sh \ + missing +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +distdir = $(PACKAGE)-$(VERSION) +top_distdir = $(distdir) +am__remove_distdir = \ + if test -d "$(distdir)"; then \ + find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ + && rm -rf "$(distdir)" \ + || { sleep 5 && rm -rf "$(distdir)"; }; \ + else :; fi +am__post_remove_distdir = $(am__remove_distdir) +DIST_ARCHIVES = $(distdir).tar.gz +GZIP_ENV = --best +DIST_TARGETS = dist-gzip +# Exists only to be overridden by the user if desired. +AM_DISTCHECK_DVI_TARGET = dvi +distuninstallcheck_listfiles = find . -type f -print +am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ + | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' +distcleancheck_listfiles = find . -type f -print +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BUILD_EXEEXT = @BUILD_EXEEXT@ +BUILD_OBJEXT = @BUILD_OBJEXT@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CCDEPMODE_FOR_BUILD = @CCDEPMODE_FOR_BUILD@ +CC_FOR_BUILD = @CC_FOR_BUILD@ +CFLAGS = @CFLAGS@ +CFLAGS_FOR_BUILD = @CFLAGS_FOR_BUILD@ +CLANG_CXXFLAGS = @CLANG_CXXFLAGS@ +CLANG_LDFLAGS = @CLANG_LDFLAGS@ +CLANG_LIBS = @CLANG_LIBS@ +CLANG_RFLAG = @CLANG_RFLAG@ +CONFIG_STATUS_DEPENDENCIES = @CONFIG_STATUS_DEPENDENCIES@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CPPFLAGS_FOR_BUILD = @CPPFLAGS_FOR_BUILD@ +CPP_FOR_BUILD = @CPP_FOR_BUILD@ +CSCOPE = @CSCOPE@ +CTAGS = @CTAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXCPPFLAGS_FOR_BUILD = @CXXCPPFLAGS_FOR_BUILD@ +CXXCPP_FOR_BUILD = @CXXCPP_FOR_BUILD@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CXXFLAGS_FOR_BUILD = @CXXFLAGS_FOR_BUILD@ +CXX_FOR_BUILD = @CXX_FOR_BUILD@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ETAGS = @ETAGS@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +HAVE_CXX11 = @HAVE_CXX11@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LDFLAGS_FOR_BUILD = @LDFLAGS_FOR_BUILD@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LLVM_CONFIG = @LLVM_CONFIG@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +XCODE_SELECT = @XCODE_SELECT@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CC_FOR_BUILD = @ac_ct_CC_FOR_BUILD@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_CXX_FOR_BUILD = @ac_ct_CXX_FOR_BUILD@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +ACLOCAL_AMFLAGS = -I ../m4 +AUTOMAKE_OPTIONS = nostdinc +includes = -I$(top_builddir) -I$(top_srcdir) \ + -I$(top_builddir)/include -I$(top_srcdir)/include + +extract_interface_CPPFLAGS = $(includes) +extract_interface_CXXFLAGS = $(CLANG_CXXFLAGS) +extract_interface_SOURCES = \ + generator.h \ + generator.cc \ + python.h \ + python.cc \ + cpp.h \ + cpp.cc \ + cpp_conversion.h \ + cpp_conversion.cc \ + plain_cpp.h \ + plain_cpp.cc \ + set_lang_defaults_arg4.h \ + template_cpp.h \ + template_cpp.cc \ + extract_interface.h \ + extract_interface.cc + +extract_interface_LDFLAGS = $(CLANG_LDFLAGS) $(CLANG_RFLAG) +extract_interface_LDADD = $(CLANG_LIBS) $(CLANG_LDFLAGS) +all: isl_config.h + $(MAKE) $(AM_MAKEFLAGS) all-am + +.SUFFIXES: +.SUFFIXES: .cc .lo .o .obj +am--refresh: Makefile + @: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \ + $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + echo ' $(SHELL) ./config.status'; \ + $(SHELL) ./config.status;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + $(SHELL) ./config.status --recheck + +$(top_srcdir)/configure: $(am__configure_deps) + $(am__cd) $(srcdir) && $(AUTOCONF) +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) +$(am__aclocal_m4_deps): + +isl_config.h: stamp-h1 + @test -f $@ || rm -f stamp-h1 + @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1 + +stamp-h1: $(srcdir)/isl_config.h.in $(top_builddir)/config.status + @rm -f stamp-h1 + cd $(top_builddir) && $(SHELL) ./config.status isl_config.h +$(srcdir)/isl_config.h.in: $(am__configure_deps) + ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) + rm -f stamp-h1 + touch $@ + +distclean-hdr: + -rm -f isl_config.h stamp-h1 + +clean-noinstPROGRAMS: + @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list + +extract_interface$(EXEEXT): $(extract_interface_OBJECTS) $(extract_interface_DEPENDENCIES) $(EXTRA_extract_interface_DEPENDENCIES) + @rm -f extract_interface$(EXEEXT) + $(AM_V_CXXLD)$(extract_interface_LINK) $(extract_interface_OBJECTS) $(extract_interface_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/extract_interface-cpp.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/extract_interface-cpp_conversion.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/extract_interface-extract_interface.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/extract_interface-generator.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/extract_interface-plain_cpp.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/extract_interface-python.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/extract_interface-template_cpp.Po@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.cc.o: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< + +.cc.obj: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.cc.lo: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $< + +extract_interface-generator.o: generator.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(extract_interface_CPPFLAGS) $(CPPFLAGS) $(extract_interface_CXXFLAGS) $(CXXFLAGS) -MT extract_interface-generator.o -MD -MP -MF $(DEPDIR)/extract_interface-generator.Tpo -c -o extract_interface-generator.o `test -f 'generator.cc' || echo '$(srcdir)/'`generator.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/extract_interface-generator.Tpo $(DEPDIR)/extract_interface-generator.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='generator.cc' object='extract_interface-generator.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(extract_interface_CPPFLAGS) $(CPPFLAGS) $(extract_interface_CXXFLAGS) $(CXXFLAGS) -c -o extract_interface-generator.o `test -f 'generator.cc' || echo '$(srcdir)/'`generator.cc + +extract_interface-generator.obj: generator.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(extract_interface_CPPFLAGS) $(CPPFLAGS) $(extract_interface_CXXFLAGS) $(CXXFLAGS) -MT extract_interface-generator.obj -MD -MP -MF $(DEPDIR)/extract_interface-generator.Tpo -c -o extract_interface-generator.obj `if test -f 'generator.cc'; then $(CYGPATH_W) 'generator.cc'; else $(CYGPATH_W) '$(srcdir)/generator.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/extract_interface-generator.Tpo $(DEPDIR)/extract_interface-generator.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='generator.cc' object='extract_interface-generator.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(extract_interface_CPPFLAGS) $(CPPFLAGS) $(extract_interface_CXXFLAGS) $(CXXFLAGS) -c -o extract_interface-generator.obj `if test -f 'generator.cc'; then $(CYGPATH_W) 'generator.cc'; else $(CYGPATH_W) '$(srcdir)/generator.cc'; fi` + +extract_interface-python.o: python.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(extract_interface_CPPFLAGS) $(CPPFLAGS) $(extract_interface_CXXFLAGS) $(CXXFLAGS) -MT extract_interface-python.o -MD -MP -MF $(DEPDIR)/extract_interface-python.Tpo -c -o extract_interface-python.o `test -f 'python.cc' || echo '$(srcdir)/'`python.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/extract_interface-python.Tpo $(DEPDIR)/extract_interface-python.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='python.cc' object='extract_interface-python.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(extract_interface_CPPFLAGS) $(CPPFLAGS) $(extract_interface_CXXFLAGS) $(CXXFLAGS) -c -o extract_interface-python.o `test -f 'python.cc' || echo '$(srcdir)/'`python.cc + +extract_interface-python.obj: python.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(extract_interface_CPPFLAGS) $(CPPFLAGS) $(extract_interface_CXXFLAGS) $(CXXFLAGS) -MT extract_interface-python.obj -MD -MP -MF $(DEPDIR)/extract_interface-python.Tpo -c -o extract_interface-python.obj `if test -f 'python.cc'; then $(CYGPATH_W) 'python.cc'; else $(CYGPATH_W) '$(srcdir)/python.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/extract_interface-python.Tpo $(DEPDIR)/extract_interface-python.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='python.cc' object='extract_interface-python.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(extract_interface_CPPFLAGS) $(CPPFLAGS) $(extract_interface_CXXFLAGS) $(CXXFLAGS) -c -o extract_interface-python.obj `if test -f 'python.cc'; then $(CYGPATH_W) 'python.cc'; else $(CYGPATH_W) '$(srcdir)/python.cc'; fi` + +extract_interface-cpp.o: cpp.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(extract_interface_CPPFLAGS) $(CPPFLAGS) $(extract_interface_CXXFLAGS) $(CXXFLAGS) -MT extract_interface-cpp.o -MD -MP -MF $(DEPDIR)/extract_interface-cpp.Tpo -c -o extract_interface-cpp.o `test -f 'cpp.cc' || echo '$(srcdir)/'`cpp.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/extract_interface-cpp.Tpo $(DEPDIR)/extract_interface-cpp.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='cpp.cc' object='extract_interface-cpp.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(extract_interface_CPPFLAGS) $(CPPFLAGS) $(extract_interface_CXXFLAGS) $(CXXFLAGS) -c -o extract_interface-cpp.o `test -f 'cpp.cc' || echo '$(srcdir)/'`cpp.cc + +extract_interface-cpp.obj: cpp.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(extract_interface_CPPFLAGS) $(CPPFLAGS) $(extract_interface_CXXFLAGS) $(CXXFLAGS) -MT extract_interface-cpp.obj -MD -MP -MF $(DEPDIR)/extract_interface-cpp.Tpo -c -o extract_interface-cpp.obj `if test -f 'cpp.cc'; then $(CYGPATH_W) 'cpp.cc'; else $(CYGPATH_W) '$(srcdir)/cpp.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/extract_interface-cpp.Tpo $(DEPDIR)/extract_interface-cpp.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='cpp.cc' object='extract_interface-cpp.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(extract_interface_CPPFLAGS) $(CPPFLAGS) $(extract_interface_CXXFLAGS) $(CXXFLAGS) -c -o extract_interface-cpp.obj `if test -f 'cpp.cc'; then $(CYGPATH_W) 'cpp.cc'; else $(CYGPATH_W) '$(srcdir)/cpp.cc'; fi` + +extract_interface-cpp_conversion.o: cpp_conversion.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(extract_interface_CPPFLAGS) $(CPPFLAGS) $(extract_interface_CXXFLAGS) $(CXXFLAGS) -MT extract_interface-cpp_conversion.o -MD -MP -MF $(DEPDIR)/extract_interface-cpp_conversion.Tpo -c -o extract_interface-cpp_conversion.o `test -f 'cpp_conversion.cc' || echo '$(srcdir)/'`cpp_conversion.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/extract_interface-cpp_conversion.Tpo $(DEPDIR)/extract_interface-cpp_conversion.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='cpp_conversion.cc' object='extract_interface-cpp_conversion.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(extract_interface_CPPFLAGS) $(CPPFLAGS) $(extract_interface_CXXFLAGS) $(CXXFLAGS) -c -o extract_interface-cpp_conversion.o `test -f 'cpp_conversion.cc' || echo '$(srcdir)/'`cpp_conversion.cc + +extract_interface-cpp_conversion.obj: cpp_conversion.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(extract_interface_CPPFLAGS) $(CPPFLAGS) $(extract_interface_CXXFLAGS) $(CXXFLAGS) -MT extract_interface-cpp_conversion.obj -MD -MP -MF $(DEPDIR)/extract_interface-cpp_conversion.Tpo -c -o extract_interface-cpp_conversion.obj `if test -f 'cpp_conversion.cc'; then $(CYGPATH_W) 'cpp_conversion.cc'; else $(CYGPATH_W) '$(srcdir)/cpp_conversion.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/extract_interface-cpp_conversion.Tpo $(DEPDIR)/extract_interface-cpp_conversion.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='cpp_conversion.cc' object='extract_interface-cpp_conversion.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(extract_interface_CPPFLAGS) $(CPPFLAGS) $(extract_interface_CXXFLAGS) $(CXXFLAGS) -c -o extract_interface-cpp_conversion.obj `if test -f 'cpp_conversion.cc'; then $(CYGPATH_W) 'cpp_conversion.cc'; else $(CYGPATH_W) '$(srcdir)/cpp_conversion.cc'; fi` + +extract_interface-plain_cpp.o: plain_cpp.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(extract_interface_CPPFLAGS) $(CPPFLAGS) $(extract_interface_CXXFLAGS) $(CXXFLAGS) -MT extract_interface-plain_cpp.o -MD -MP -MF $(DEPDIR)/extract_interface-plain_cpp.Tpo -c -o extract_interface-plain_cpp.o `test -f 'plain_cpp.cc' || echo '$(srcdir)/'`plain_cpp.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/extract_interface-plain_cpp.Tpo $(DEPDIR)/extract_interface-plain_cpp.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='plain_cpp.cc' object='extract_interface-plain_cpp.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(extract_interface_CPPFLAGS) $(CPPFLAGS) $(extract_interface_CXXFLAGS) $(CXXFLAGS) -c -o extract_interface-plain_cpp.o `test -f 'plain_cpp.cc' || echo '$(srcdir)/'`plain_cpp.cc + +extract_interface-plain_cpp.obj: plain_cpp.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(extract_interface_CPPFLAGS) $(CPPFLAGS) $(extract_interface_CXXFLAGS) $(CXXFLAGS) -MT extract_interface-plain_cpp.obj -MD -MP -MF $(DEPDIR)/extract_interface-plain_cpp.Tpo -c -o extract_interface-plain_cpp.obj `if test -f 'plain_cpp.cc'; then $(CYGPATH_W) 'plain_cpp.cc'; else $(CYGPATH_W) '$(srcdir)/plain_cpp.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/extract_interface-plain_cpp.Tpo $(DEPDIR)/extract_interface-plain_cpp.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='plain_cpp.cc' object='extract_interface-plain_cpp.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(extract_interface_CPPFLAGS) $(CPPFLAGS) $(extract_interface_CXXFLAGS) $(CXXFLAGS) -c -o extract_interface-plain_cpp.obj `if test -f 'plain_cpp.cc'; then $(CYGPATH_W) 'plain_cpp.cc'; else $(CYGPATH_W) '$(srcdir)/plain_cpp.cc'; fi` + +extract_interface-template_cpp.o: template_cpp.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(extract_interface_CPPFLAGS) $(CPPFLAGS) $(extract_interface_CXXFLAGS) $(CXXFLAGS) -MT extract_interface-template_cpp.o -MD -MP -MF $(DEPDIR)/extract_interface-template_cpp.Tpo -c -o extract_interface-template_cpp.o `test -f 'template_cpp.cc' || echo '$(srcdir)/'`template_cpp.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/extract_interface-template_cpp.Tpo $(DEPDIR)/extract_interface-template_cpp.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='template_cpp.cc' object='extract_interface-template_cpp.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(extract_interface_CPPFLAGS) $(CPPFLAGS) $(extract_interface_CXXFLAGS) $(CXXFLAGS) -c -o extract_interface-template_cpp.o `test -f 'template_cpp.cc' || echo '$(srcdir)/'`template_cpp.cc + +extract_interface-template_cpp.obj: template_cpp.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(extract_interface_CPPFLAGS) $(CPPFLAGS) $(extract_interface_CXXFLAGS) $(CXXFLAGS) -MT extract_interface-template_cpp.obj -MD -MP -MF $(DEPDIR)/extract_interface-template_cpp.Tpo -c -o extract_interface-template_cpp.obj `if test -f 'template_cpp.cc'; then $(CYGPATH_W) 'template_cpp.cc'; else $(CYGPATH_W) '$(srcdir)/template_cpp.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/extract_interface-template_cpp.Tpo $(DEPDIR)/extract_interface-template_cpp.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='template_cpp.cc' object='extract_interface-template_cpp.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(extract_interface_CPPFLAGS) $(CPPFLAGS) $(extract_interface_CXXFLAGS) $(CXXFLAGS) -c -o extract_interface-template_cpp.obj `if test -f 'template_cpp.cc'; then $(CYGPATH_W) 'template_cpp.cc'; else $(CYGPATH_W) '$(srcdir)/template_cpp.cc'; fi` + +extract_interface-extract_interface.o: extract_interface.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(extract_interface_CPPFLAGS) $(CPPFLAGS) $(extract_interface_CXXFLAGS) $(CXXFLAGS) -MT extract_interface-extract_interface.o -MD -MP -MF $(DEPDIR)/extract_interface-extract_interface.Tpo -c -o extract_interface-extract_interface.o `test -f 'extract_interface.cc' || echo '$(srcdir)/'`extract_interface.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/extract_interface-extract_interface.Tpo $(DEPDIR)/extract_interface-extract_interface.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='extract_interface.cc' object='extract_interface-extract_interface.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(extract_interface_CPPFLAGS) $(CPPFLAGS) $(extract_interface_CXXFLAGS) $(CXXFLAGS) -c -o extract_interface-extract_interface.o `test -f 'extract_interface.cc' || echo '$(srcdir)/'`extract_interface.cc + +extract_interface-extract_interface.obj: extract_interface.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(extract_interface_CPPFLAGS) $(CPPFLAGS) $(extract_interface_CXXFLAGS) $(CXXFLAGS) -MT extract_interface-extract_interface.obj -MD -MP -MF $(DEPDIR)/extract_interface-extract_interface.Tpo -c -o extract_interface-extract_interface.obj `if test -f 'extract_interface.cc'; then $(CYGPATH_W) 'extract_interface.cc'; else $(CYGPATH_W) '$(srcdir)/extract_interface.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/extract_interface-extract_interface.Tpo $(DEPDIR)/extract_interface-extract_interface.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='extract_interface.cc' object='extract_interface-extract_interface.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(extract_interface_CPPFLAGS) $(CPPFLAGS) $(extract_interface_CXXFLAGS) $(CXXFLAGS) -c -o extract_interface-extract_interface.obj `if test -f 'extract_interface.cc'; then $(CYGPATH_W) 'extract_interface.cc'; else $(CYGPATH_W) '$(srcdir)/extract_interface.cc'; fi` + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool config.lt + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscope: cscope.files + test ! -s cscope.files \ + || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS) +clean-cscope: + -rm -f cscope.files +cscope.files: clean-cscope cscopelist +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + -rm -f cscope.out cscope.in.out cscope.po.out cscope.files +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + $(am__remove_distdir) + test -d "$(distdir)" || mkdir "$(distdir)" + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + -test -n "$(am__skip_mode_fix)" \ + || find "$(distdir)" -type d ! -perm -755 \ + -exec chmod u+rwx,go+rx {} \; -o \ + ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ + || chmod -R a+r "$(distdir)" +dist-gzip: distdir + tardir=$(distdir) && $(am__tar) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).tar.gz + $(am__post_remove_distdir) + +dist-bzip2: distdir + tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 + $(am__post_remove_distdir) + +dist-lzip: distdir + tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz + $(am__post_remove_distdir) + +dist-xz: distdir + tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz + $(am__post_remove_distdir) + +dist-zstd: distdir + tardir=$(distdir) && $(am__tar) | zstd -c $${ZSTD_CLEVEL-$${ZSTD_OPT--19}} >$(distdir).tar.zst + $(am__post_remove_distdir) + +dist-tarZ: distdir + @echo WARNING: "Support for distribution archives compressed with" \ + "legacy program 'compress' is deprecated." >&2 + @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 + tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z + $(am__post_remove_distdir) + +dist-shar: distdir + @echo WARNING: "Support for shar distribution archives is" \ + "deprecated." >&2 + @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 + shar $(distdir) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).shar.gz + $(am__post_remove_distdir) + +dist-zip: distdir + -rm -f $(distdir).zip + zip -rq $(distdir).zip $(distdir) + $(am__post_remove_distdir) + +dist dist-all: + $(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:' + $(am__post_remove_distdir) + +# This target untars the dist file and tries a VPATH configuration. Then +# it guarantees that the distribution is self-contained by making another +# tarfile. +distcheck: dist + case '$(DIST_ARCHIVES)' in \ + *.tar.gz*) \ + eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).tar.gz | $(am__untar) ;;\ + *.tar.bz2*) \ + bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ + *.tar.lz*) \ + lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ + *.tar.xz*) \ + xz -dc $(distdir).tar.xz | $(am__untar) ;;\ + *.tar.Z*) \ + uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ + *.shar.gz*) \ + eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).shar.gz | unshar ;;\ + *.zip*) \ + unzip $(distdir).zip ;;\ + *.tar.zst*) \ + zstd -dc $(distdir).tar.zst | $(am__untar) ;;\ + esac + chmod -R a-w $(distdir) + chmod u+w $(distdir) + mkdir $(distdir)/_build $(distdir)/_build/sub $(distdir)/_inst + chmod a-w $(distdir) + test -d $(distdir)/_build || exit 0; \ + dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ + && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ + && am__cwd=`pwd` \ + && $(am__cd) $(distdir)/_build/sub \ + && ../../configure \ + $(AM_DISTCHECK_CONFIGURE_FLAGS) \ + $(DISTCHECK_CONFIGURE_FLAGS) \ + --srcdir=../.. --prefix="$$dc_install_base" \ + && $(MAKE) $(AM_MAKEFLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) $(AM_DISTCHECK_DVI_TARGET) \ + && $(MAKE) $(AM_MAKEFLAGS) check \ + && $(MAKE) $(AM_MAKEFLAGS) install \ + && $(MAKE) $(AM_MAKEFLAGS) installcheck \ + && $(MAKE) $(AM_MAKEFLAGS) uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ + distuninstallcheck \ + && chmod -R a-w "$$dc_install_base" \ + && ({ \ + (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ + distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ + } || { rm -rf "$$dc_destdir"; exit 1; }) \ + && rm -rf "$$dc_destdir" \ + && $(MAKE) $(AM_MAKEFLAGS) dist \ + && rm -rf $(DIST_ARCHIVES) \ + && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ + && cd "$$am__cwd" \ + || exit 1 + $(am__post_remove_distdir) + @(echo "$(distdir) archives ready for distribution: "; \ + list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ + sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' +distuninstallcheck: + @test -n '$(distuninstallcheck_dir)' || { \ + echo 'ERROR: trying to run $@ with an empty' \ + '$$(distuninstallcheck_dir)' >&2; \ + exit 1; \ + }; \ + $(am__cd) '$(distuninstallcheck_dir)' || { \ + echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \ + exit 1; \ + }; \ + test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left after uninstall:" ; \ + if test -n "$(DESTDIR)"; then \ + echo " (check DESTDIR support)"; \ + fi ; \ + $(distuninstallcheck_listfiles) ; \ + exit 1; } >&2 +distcleancheck: distclean + @if test '$(srcdir)' = . ; then \ + echo "ERROR: distcleancheck can only run from a VPATH build" ; \ + exit 1 ; \ + fi + @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left in build directory after distclean:" ; \ + $(distcleancheck_listfiles) ; \ + exit 1; } >&2 +check-am: all-am +check: check-am +all-am: Makefile $(PROGRAMS) isl_config.h +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstPROGRAMS \ + mostlyclean-am + +distclean: distclean-am + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -f ./$(DEPDIR)/extract_interface-cpp.Po + -rm -f ./$(DEPDIR)/extract_interface-cpp_conversion.Po + -rm -f ./$(DEPDIR)/extract_interface-extract_interface.Po + -rm -f ./$(DEPDIR)/extract_interface-generator.Po + -rm -f ./$(DEPDIR)/extract_interface-plain_cpp.Po + -rm -f ./$(DEPDIR)/extract_interface-python.Po + -rm -f ./$(DEPDIR)/extract_interface-template_cpp.Po + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-hdr distclean-libtool distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -rf $(top_srcdir)/autom4te.cache + -rm -f ./$(DEPDIR)/extract_interface-cpp.Po + -rm -f ./$(DEPDIR)/extract_interface-cpp_conversion.Po + -rm -f ./$(DEPDIR)/extract_interface-extract_interface.Po + -rm -f ./$(DEPDIR)/extract_interface-generator.Po + -rm -f ./$(DEPDIR)/extract_interface-plain_cpp.Po + -rm -f ./$(DEPDIR)/extract_interface-python.Po + -rm -f ./$(DEPDIR)/extract_interface-template_cpp.Po + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: all install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles am--refresh check \ + check-am clean clean-cscope clean-generic clean-libtool \ + clean-noinstPROGRAMS cscope cscopelist-am ctags ctags-am dist \ + dist-all dist-bzip2 dist-gzip dist-lzip dist-shar dist-tarZ \ + dist-xz dist-zip dist-zstd distcheck distclean \ + distclean-compile distclean-generic distclean-hdr \ + 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-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am tags tags-am uninstall uninstall-am + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/external/mit/isl/dist/interface/aclocal.m4 b/external/mit/isl/dist/interface/aclocal.m4 new file mode 100644 index 000000000000..ed0e8003c525 --- /dev/null +++ b/external/mit/isl/dist/interface/aclocal.m4 @@ -0,0 +1,1161 @@ +# generated automatically by aclocal 1.16.5 -*- Autoconf -*- + +# Copyright (C) 1996-2021 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. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) +m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.71],, +[m4_warning([this file was generated for autoconf 2.71. +You have another version of autoconf. It may work, but is not guaranteed to. +If you have problems, you may need to regenerate the build system entirely. +To do so, use the procedure documented by the package, typically 'autoreconf'.])]) + +# Copyright (C) 2002-2021 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_AUTOMAKE_VERSION(VERSION) +# ---------------------------- +# Automake X.Y traces this macro to ensure aclocal.m4 has been +# generated from the m4 files accompanying Automake X.Y. +# (This private macro should not be called outside this file.) +AC_DEFUN([AM_AUTOMAKE_VERSION], +[am__api_version='1.16' +dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to +dnl require some minimum version. Point them to the right macro. +m4_if([$1], [1.16.5], [], + [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl +]) + +# _AM_AUTOCONF_VERSION(VERSION) +# ----------------------------- +# aclocal traces this macro to find the Autoconf version. +# This is a private macro too. Using m4_define simplifies +# the logic in aclocal, which can simply ignore this definition. +m4_define([_AM_AUTOCONF_VERSION], []) + +# AM_SET_CURRENT_AUTOMAKE_VERSION +# ------------------------------- +# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. +# This function is AC_REQUIREd by AM_INIT_AUTOMAKE. +AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], +[AM_AUTOMAKE_VERSION([1.16.5])dnl +m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) + +# AM_AUX_DIR_EXPAND -*- Autoconf -*- + +# Copyright (C) 2001-2021 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. + +# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets +# $ac_aux_dir to '$srcdir/foo'. In other projects, it is set to +# '$srcdir', '$srcdir/..', or '$srcdir/../..'. +# +# Of course, Automake must honor this variable whenever it calls a +# tool from the auxiliary directory. The problem is that $srcdir (and +# therefore $ac_aux_dir as well) can be either absolute or relative, +# depending on how configure is run. This is pretty annoying, since +# it makes $ac_aux_dir quite unusable in subdirectories: in the top +# source directory, any form will work fine, but in subdirectories a +# relative path needs to be adjusted first. +# +# $ac_aux_dir/missing +# fails when called from a subdirectory if $ac_aux_dir is relative +# $top_srcdir/$ac_aux_dir/missing +# fails if $ac_aux_dir is absolute, +# fails when called from a subdirectory in a VPATH build with +# a relative $ac_aux_dir +# +# The reason of the latter failure is that $top_srcdir and $ac_aux_dir +# are both prefixed by $srcdir. In an in-source build this is usually +# harmless because $srcdir is '.', but things will broke when you +# start a VPATH build or use an absolute $srcdir. +# +# So we could use something similar to $top_srcdir/$ac_aux_dir/missing, +# iff we strip the leading $srcdir from $ac_aux_dir. That would be: +# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` +# and then we would define $MISSING as +# MISSING="\${SHELL} $am_aux_dir/missing" +# This will work as long as MISSING is not called from configure, because +# unfortunately $(top_srcdir) has no meaning in configure. +# However there are other variables, like CC, which are often used in +# configure, and could therefore not use this "fixed" $ac_aux_dir. +# +# Another solution, used here, is to always expand $ac_aux_dir to an +# absolute PATH. The drawback is that using absolute paths prevent a +# configured tree to be moved without reconfiguration. + +AC_DEFUN([AM_AUX_DIR_EXPAND], +[AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl +# Expand $ac_aux_dir to an absolute path. +am_aux_dir=`cd "$ac_aux_dir" && pwd` +]) + +# AM_CONDITIONAL -*- Autoconf -*- + +# Copyright (C) 1997-2021 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_CONDITIONAL(NAME, SHELL-CONDITION) +# ------------------------------------- +# Define a conditional. +AC_DEFUN([AM_CONDITIONAL], +[AC_PREREQ([2.52])dnl + m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], + [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl +AC_SUBST([$1_TRUE])dnl +AC_SUBST([$1_FALSE])dnl +_AM_SUBST_NOTMAKE([$1_TRUE])dnl +_AM_SUBST_NOTMAKE([$1_FALSE])dnl +m4_define([_AM_COND_VALUE_$1], [$2])dnl +if $2; then + $1_TRUE= + $1_FALSE='#' +else + $1_TRUE='#' + $1_FALSE= +fi +AC_CONFIG_COMMANDS_PRE( +[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then + AC_MSG_ERROR([[conditional "$1" was never defined. +Usually this means the macro was only invoked conditionally.]]) +fi])]) + +# Copyright (C) 1999-2021 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. + + +# There are a few dirty hacks below to avoid letting 'AC_PROG_CC' be +# written in clear, in which case automake, when reading aclocal.m4, +# will think it sees a *use*, and therefore will trigger all it's +# C support machinery. Also note that it means that autoscan, seeing +# CC etc. in the Makefile, will ask for an AC_PROG_CC use... + + +# _AM_DEPENDENCIES(NAME) +# ---------------------- +# See how the compiler implements dependency checking. +# NAME is "CC", "CXX", "OBJC", "OBJCXX", "UPC", or "GJC". +# We try a few techniques and use that to set a single cache variable. +# +# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was +# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular +# dependency, and given that the user is not expected to run this macro, +# just rely on AC_PROG_CC. +AC_DEFUN([_AM_DEPENDENCIES], +[AC_REQUIRE([AM_SET_DEPDIR])dnl +AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl +AC_REQUIRE([AM_MAKE_INCLUDE])dnl +AC_REQUIRE([AM_DEP_TRACK])dnl + +m4_if([$1], [CC], [depcc="$CC" am_compiler_list=], + [$1], [CXX], [depcc="$CXX" am_compiler_list=], + [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'], + [$1], [OBJCXX], [depcc="$OBJCXX" am_compiler_list='gcc3 gcc'], + [$1], [UPC], [depcc="$UPC" am_compiler_list=], + [$1], [GCJ], [depcc="$GCJ" am_compiler_list='gcc3 gcc'], + [depcc="$$1" am_compiler_list=]) + +AC_CACHE_CHECK([dependency style of $depcc], + [am_cv_$1_dependencies_compiler_type], +[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named 'D' -- because '-MD' means "put the output + # in D". + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_$1_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` + fi + am__universal=false + m4_case([$1], [CC], + [case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac], + [CXX], + [case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac]) + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with + # Solaris 10 /bin/sh. + echo '/* dummy */' > sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with '-c' and '-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle '-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs. + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # After this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested. + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok '-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_$1_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_$1_dependencies_compiler_type=none +fi +]) +AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) +AM_CONDITIONAL([am__fastdep$1], [ + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) +]) + + +# AM_SET_DEPDIR +# ------------- +# Choose a directory name for dependency files. +# This macro is AC_REQUIREd in _AM_DEPENDENCIES. +AC_DEFUN([AM_SET_DEPDIR], +[AC_REQUIRE([AM_SET_LEADING_DOT])dnl +AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl +]) + + +# AM_DEP_TRACK +# ------------ +AC_DEFUN([AM_DEP_TRACK], +[AC_ARG_ENABLE([dependency-tracking], [dnl +AS_HELP_STRING( + [--enable-dependency-tracking], + [do not reject slow dependency extractors]) +AS_HELP_STRING( + [--disable-dependency-tracking], + [speeds up one-time build])]) +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' + am__nodep='_no' +fi +AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) +AC_SUBST([AMDEPBACKSLASH])dnl +_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl +AC_SUBST([am__nodep])dnl +_AM_SUBST_NOTMAKE([am__nodep])dnl +]) + +# Generate code to set up dependency tracking. -*- Autoconf -*- + +# Copyright (C) 1999-2021 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_OUTPUT_DEPENDENCY_COMMANDS +# ------------------------------ +AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], +[{ + # Older Autoconf quotes --file arguments for eval, but not when files + # are listed without --file. Let's play safe and only enable the eval + # if we detect the quoting. + # TODO: see whether this extra hack can be removed once we start + # requiring Autoconf 2.70 or later. + AS_CASE([$CONFIG_FILES], + [*\'*], [eval set x "$CONFIG_FILES"], + [*], [set x $CONFIG_FILES]) + shift + # Used to flag and report bootstrapping failures. + am_rc=0 + for am_mf + do + # Strip MF so we end up with the name of the file. + am_mf=`AS_ECHO(["$am_mf"]) | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile which includes + # dependency-tracking related rules and includes. + # Grep'ing the whole file directly is not great: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + sed -n 's,^am--depfiles:.*,X,p' "$am_mf" | grep X >/dev/null 2>&1 \ + || continue + am_dirpart=`AS_DIRNAME(["$am_mf"])` + am_filepart=`AS_BASENAME(["$am_mf"])` + AM_RUN_LOG([cd "$am_dirpart" \ + && sed -e '/# am--include-marker/d' "$am_filepart" \ + | $MAKE -f - am--depfiles]) || am_rc=$? + done + if test $am_rc -ne 0; then + AC_MSG_FAILURE([Something went wrong bootstrapping makefile fragments + for automatic dependency tracking. If GNU make was not used, consider + re-running the configure script with MAKE="gmake" (or whatever is + necessary). You can also try re-running configure with the + '--disable-dependency-tracking' option to at least be able to build + the package (albeit without support for automatic dependency tracking).]) + fi + AS_UNSET([am_dirpart]) + AS_UNSET([am_filepart]) + AS_UNSET([am_mf]) + AS_UNSET([am_rc]) + rm -f conftest-deps.mk +} +])# _AM_OUTPUT_DEPENDENCY_COMMANDS + + +# AM_OUTPUT_DEPENDENCY_COMMANDS +# ----------------------------- +# This macro should only be invoked once -- use via AC_REQUIRE. +# +# This code is only required when automatic dependency tracking is enabled. +# This creates each '.Po' and '.Plo' makefile fragment that we'll need in +# order to bootstrap the dependency handling code. +AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], +[AC_CONFIG_COMMANDS([depfiles], + [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], + [AMDEP_TRUE="$AMDEP_TRUE" MAKE="${MAKE-make}"])]) + +# Do all the work for Automake. -*- Autoconf -*- + +# Copyright (C) 1996-2021 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. + +# This macro actually does too much. Some checks are only needed if +# your package does certain things. But this isn't really a big deal. + +dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O. +m4_define([AC_PROG_CC], +m4_defn([AC_PROG_CC]) +[_AM_PROG_CC_C_O +]) + +# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) +# AM_INIT_AUTOMAKE([OPTIONS]) +# ----------------------------------------------- +# The call with PACKAGE and VERSION arguments is the old style +# call (pre autoconf-2.50), which is being phased out. PACKAGE +# and VERSION should now be passed to AC_INIT and removed from +# the call to AM_INIT_AUTOMAKE. +# We support both call styles for the transition. After +# the next Automake release, Autoconf can make the AC_INIT +# arguments mandatory, and then we can depend on a new Autoconf +# release and drop the old call support. +AC_DEFUN([AM_INIT_AUTOMAKE], +[AC_PREREQ([2.65])dnl +m4_ifdef([_$0_ALREADY_INIT], + [m4_fatal([$0 expanded multiple times +]m4_defn([_$0_ALREADY_INIT]))], + [m4_define([_$0_ALREADY_INIT], m4_expansion_stack)])dnl +dnl Autoconf wants to disallow AM_ names. We explicitly allow +dnl the ones we care about. +m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl +AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl +AC_REQUIRE([AC_PROG_INSTALL])dnl +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi +AC_SUBST([CYGPATH_W]) + +# Define the identity of the package. +dnl Distinguish between old-style and new-style calls. +m4_ifval([$2], +[AC_DIAGNOSE([obsolete], + [$0: two- and three-arguments forms are deprecated.]) +m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl + AC_SUBST([PACKAGE], [$1])dnl + AC_SUBST([VERSION], [$2])], +[_AM_SET_OPTIONS([$1])dnl +dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. +m4_if( + m4_ifset([AC_PACKAGE_NAME], [ok]):m4_ifset([AC_PACKAGE_VERSION], [ok]), + [ok:ok],, + [m4_fatal([AC_INIT should be called with package and version arguments])])dnl + AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl + AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl + +_AM_IF_OPTION([no-define],, +[AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package]) + AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl + +# Some tools Automake needs. +AC_REQUIRE([AM_SANITY_CHECK])dnl +AC_REQUIRE([AC_ARG_PROGRAM])dnl +AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}]) +AM_MISSING_PROG([AUTOCONF], [autoconf]) +AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}]) +AM_MISSING_PROG([AUTOHEADER], [autoheader]) +AM_MISSING_PROG([MAKEINFO], [makeinfo]) +AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl +AC_REQUIRE([AC_PROG_MKDIR_P])dnl +# For better backward compatibility. To be removed once Automake 1.9.x +# dies out for good. For more background, see: +# +# +AC_SUBST([mkdir_p], ['$(MKDIR_P)']) +# We need awk for the "check" target (and possibly the TAP driver). The +# system "awk" is bad on some platforms. +AC_REQUIRE([AC_PROG_AWK])dnl +AC_REQUIRE([AC_PROG_MAKE_SET])dnl +AC_REQUIRE([AM_SET_LEADING_DOT])dnl +_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], + [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], + [_AM_PROG_TAR([v7])])]) +_AM_IF_OPTION([no-dependencies],, +[AC_PROVIDE_IFELSE([AC_PROG_CC], + [_AM_DEPENDENCIES([CC])], + [m4_define([AC_PROG_CC], + m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl +AC_PROVIDE_IFELSE([AC_PROG_CXX], + [_AM_DEPENDENCIES([CXX])], + [m4_define([AC_PROG_CXX], + m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl +AC_PROVIDE_IFELSE([AC_PROG_OBJC], + [_AM_DEPENDENCIES([OBJC])], + [m4_define([AC_PROG_OBJC], + m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl +AC_PROVIDE_IFELSE([AC_PROG_OBJCXX], + [_AM_DEPENDENCIES([OBJCXX])], + [m4_define([AC_PROG_OBJCXX], + m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl +]) +# Variables for tags utilities; see am/tags.am +if test -z "$CTAGS"; then + CTAGS=ctags +fi +AC_SUBST([CTAGS]) +if test -z "$ETAGS"; then + ETAGS=etags +fi +AC_SUBST([ETAGS]) +if test -z "$CSCOPE"; then + CSCOPE=cscope +fi +AC_SUBST([CSCOPE]) + +AC_REQUIRE([AM_SILENT_RULES])dnl +dnl The testsuite driver may need to know about EXEEXT, so add the +dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This +dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below. +AC_CONFIG_COMMANDS_PRE(dnl +[m4_provide_if([_AM_COMPILER_EXEEXT], + [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl + +# POSIX will say in a future version that running "rm -f" with no argument +# is OK; and we want to be able to make that assumption in our Makefile +# recipes. So use an aggressive probe to check that the usage we want is +# actually supported "in the wild" to an acceptable degree. +# See automake bug#10828. +# To make any issue more visible, cause the running configure to be aborted +# by default if the 'rm' program in use doesn't match our expectations; the +# user can still override this though. +if rm -f && rm -fr && rm -rf; then : OK; else + cat >&2 <<'END' +Oops! + +Your 'rm' program seems unable to run without file operands specified +on the command line, even when the '-f' option is present. This is contrary +to the behaviour of most rm programs out there, and not conforming with +the upcoming POSIX standard: + +Please tell bug-automake@gnu.org about your system, including the value +of your $PATH and any error possibly output before this message. This +can help us improve future automake versions. + +END + if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then + echo 'Configuration will proceed anyway, since you have set the' >&2 + echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 + echo >&2 + else + cat >&2 <<'END' +Aborting the configuration process, to ensure you take notice of the issue. + +You can download and install GNU coreutils to get an 'rm' implementation +that behaves properly: . + +If you want to complete the configuration process using your problematic +'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM +to "yes", and re-run configure. + +END + AC_MSG_ERROR([Your 'rm' program is bad, sorry.]) + fi +fi +dnl The trailing newline in this macro's definition is deliberate, for +dnl backward compatibility and to allow trailing 'dnl'-style comments +dnl after the AM_INIT_AUTOMAKE invocation. See automake bug#16841. +]) + +dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not +dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further +dnl mangled by Autoconf and run in a shell conditional statement. +m4_define([_AC_COMPILER_EXEEXT], +m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) + +# When config.status generates a header, we must update the stamp-h file. +# This file resides in the same directory as the config header +# that is generated. The stamp files are numbered to have different names. + +# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the +# loop where config.status creates the headers, so we can generate +# our stamp files there. +AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], +[# Compute $1's index in $config_headers. +_am_arg=$1 +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $_am_arg | $_am_arg:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) + +# Copyright (C) 2001-2021 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_PROG_INSTALL_SH +# ------------------ +# Define $install_sh. +AC_DEFUN([AM_PROG_INSTALL_SH], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +if test x"${install_sh+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; + *) + install_sh="\${SHELL} $am_aux_dir/install-sh" + esac +fi +AC_SUBST([install_sh])]) + +# Copyright (C) 2003-2021 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. + +# Check whether the underlying file-system supports filenames +# with a leading dot. For instance MS-DOS doesn't. +AC_DEFUN([AM_SET_LEADING_DOT], +[rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null +AC_SUBST([am__leading_dot])]) + +# Check to see how 'make' treats includes. -*- Autoconf -*- + +# Copyright (C) 2001-2021 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_MAKE_INCLUDE() +# ----------------- +# Check whether make has an 'include' directive that can support all +# the idioms we need for our automatic dependency tracking code. +AC_DEFUN([AM_MAKE_INCLUDE], +[AC_MSG_CHECKING([whether ${MAKE-make} supports the include directive]) +cat > confinc.mk << 'END' +am__doit: + @echo this is the am__doit target >confinc.out +.PHONY: am__doit +END +am__include="#" +am__quote= +# BSD make does it like this. +echo '.include "confinc.mk" # ignored' > confmf.BSD +# Other make implementations (GNU, Solaris 10, AIX) do it like this. +echo 'include confinc.mk # ignored' > confmf.GNU +_am_result=no +for s in GNU BSD; do + AM_RUN_LOG([${MAKE-make} -f confmf.$s && cat confinc.out]) + AS_CASE([$?:`cat confinc.out 2>/dev/null`], + ['0:this is the am__doit target'], + [AS_CASE([$s], + [BSD], [am__include='.include' am__quote='"'], + [am__include='include' am__quote=''])]) + if test "$am__include" != "#"; then + _am_result="yes ($s style)" + break + fi +done +rm -f confinc.* confmf.* +AC_MSG_RESULT([${_am_result}]) +AC_SUBST([am__include])]) +AC_SUBST([am__quote])]) + +# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- + +# Copyright (C) 1997-2021 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_MISSING_PROG(NAME, PROGRAM) +# ------------------------------ +AC_DEFUN([AM_MISSING_PROG], +[AC_REQUIRE([AM_MISSING_HAS_RUN]) +$1=${$1-"${am_missing_run}$2"} +AC_SUBST($1)]) + +# AM_MISSING_HAS_RUN +# ------------------ +# Define MISSING if not defined so far and test if it is modern enough. +# If it is, set am_missing_run to use it, otherwise, to nothing. +AC_DEFUN([AM_MISSING_HAS_RUN], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +AC_REQUIRE_AUX_FILE([missing])dnl +if test x"${MISSING+set}" != xset; then + MISSING="\${SHELL} '$am_aux_dir/missing'" +fi +# Use eval to expand $SHELL +if eval "$MISSING --is-lightweight"; then + am_missing_run="$MISSING " +else + am_missing_run= + AC_MSG_WARN(['missing' script is too old or missing]) +fi +]) + +# Helper functions for option handling. -*- Autoconf -*- + +# Copyright (C) 2001-2021 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_MANGLE_OPTION(NAME) +# ----------------------- +AC_DEFUN([_AM_MANGLE_OPTION], +[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) + +# _AM_SET_OPTION(NAME) +# -------------------- +# Set option NAME. Presently that only means defining a flag for this option. +AC_DEFUN([_AM_SET_OPTION], +[m4_define(_AM_MANGLE_OPTION([$1]), [1])]) + +# _AM_SET_OPTIONS(OPTIONS) +# ------------------------ +# OPTIONS is a space-separated list of Automake options. +AC_DEFUN([_AM_SET_OPTIONS], +[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) + +# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) +# ------------------------------------------- +# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. +AC_DEFUN([_AM_IF_OPTION], +[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) + +# Copyright (C) 1999-2021 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_PROG_CC_C_O +# --------------- +# Like AC_PROG_CC_C_O, but changed for automake. We rewrite AC_PROG_CC +# to automatically call this. +AC_DEFUN([_AM_PROG_CC_C_O], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +AC_REQUIRE_AUX_FILE([compile])dnl +AC_LANG_PUSH([C])dnl +AC_CACHE_CHECK( + [whether $CC understands -c and -o together], + [am_cv_prog_cc_c_o], + [AC_LANG_CONFTEST([AC_LANG_PROGRAM([])]) + # Make sure it works both with $CC and with simple cc. + # Following AC_PROG_CC_C_O, we do the test twice because some + # compilers refuse to overwrite an existing .o file with -o, + # though they will create one. + am_cv_prog_cc_c_o=yes + for am_i in 1 2; do + if AM_RUN_LOG([$CC -c conftest.$ac_ext -o conftest2.$ac_objext]) \ + && test -f conftest2.$ac_objext; then + : OK + else + am_cv_prog_cc_c_o=no + break + fi + done + rm -f core conftest* + unset am_i]) +if test "$am_cv_prog_cc_c_o" != yes; then + # Losing compiler, so override with the script. + # FIXME: It is wrong to rewrite CC. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__CC in this case, + # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" + CC="$am_aux_dir/compile $CC" +fi +AC_LANG_POP([C])]) + +# For backward compatibility. +AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) + +# Copyright (C) 2001-2021 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_RUN_LOG(COMMAND) +# ------------------- +# Run COMMAND, save the exit status in ac_status, and log it. +# (This has been adapted from Autoconf's _AC_RUN_LOG macro.) +AC_DEFUN([AM_RUN_LOG], +[{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD + ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + (exit $ac_status); }]) + +# Check to make sure that the build environment is sane. -*- Autoconf -*- + +# Copyright (C) 1996-2021 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_SANITY_CHECK +# --------------- +AC_DEFUN([AM_SANITY_CHECK], +[AC_MSG_CHECKING([whether build environment is sane]) +# Reject unsafe characters in $srcdir or the absolute working directory +# name. Accept space and tab only in the latter. +am_lf=' +' +case `pwd` in + *[[\\\"\#\$\&\'\`$am_lf]]*) + AC_MSG_ERROR([unsafe absolute working directory name]);; +esac +case $srcdir in + *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) + AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);; +esac + +# Do 'set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + am_has_slept=no + for am_try in 1 2; do + echo "timestamp, slept: $am_has_slept" > conftest.file + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$[*]" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + if test "$[*]" != "X $srcdir/configure conftest.file" \ + && test "$[*]" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken + alias in your environment]) + fi + if test "$[2]" = conftest.file || test $am_try -eq 2; then + break + fi + # Just in case. + sleep 1 + am_has_slept=yes + done + test "$[2]" = conftest.file + ) +then + # Ok. + : +else + AC_MSG_ERROR([newly created file is older than distributed files! +Check your system clock]) +fi +AC_MSG_RESULT([yes]) +# If we didn't sleep, we still need to ensure time stamps of config.status and +# generated files are strictly newer. +am_sleep_pid= +if grep 'slept: no' conftest.file >/dev/null 2>&1; then + ( sleep 1 ) & + am_sleep_pid=$! +fi +AC_CONFIG_COMMANDS_PRE( + [AC_MSG_CHECKING([that generated files are newer than configure]) + if test -n "$am_sleep_pid"; then + # Hide warnings about reused PIDs. + wait $am_sleep_pid 2>/dev/null + fi + AC_MSG_RESULT([done])]) +rm -f conftest.file +]) + +# Copyright (C) 2009-2021 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_SILENT_RULES([DEFAULT]) +# -------------------------- +# Enable less verbose build rules; with the default set to DEFAULT +# ("yes" being less verbose, "no" or empty being verbose). +AC_DEFUN([AM_SILENT_RULES], +[AC_ARG_ENABLE([silent-rules], [dnl +AS_HELP_STRING( + [--enable-silent-rules], + [less verbose build output (undo: "make V=1")]) +AS_HELP_STRING( + [--disable-silent-rules], + [verbose build output (undo: "make V=0")])dnl +]) +case $enable_silent_rules in @%:@ ((( + yes) AM_DEFAULT_VERBOSITY=0;; + no) AM_DEFAULT_VERBOSITY=1;; + *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);; +esac +dnl +dnl A few 'make' implementations (e.g., NonStop OS and NextStep) +dnl do not support nested variable expansions. +dnl See automake bug#9928 and bug#10237. +am_make=${MAKE-make} +AC_CACHE_CHECK([whether $am_make supports nested variables], + [am_cv_make_support_nested_variables], + [if AS_ECHO([['TRUE=$(BAR$(V)) +BAR0=false +BAR1=true +V=1 +am__doit: + @$(TRUE) +.PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then + am_cv_make_support_nested_variables=yes +else + am_cv_make_support_nested_variables=no +fi]) +if test $am_cv_make_support_nested_variables = yes; then + dnl Using '$V' instead of '$(V)' breaks IRIX make. + AM_V='$(V)' + AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' +else + AM_V=$AM_DEFAULT_VERBOSITY + AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY +fi +AC_SUBST([AM_V])dnl +AM_SUBST_NOTMAKE([AM_V])dnl +AC_SUBST([AM_DEFAULT_V])dnl +AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl +AC_SUBST([AM_DEFAULT_VERBOSITY])dnl +AM_BACKSLASH='\' +AC_SUBST([AM_BACKSLASH])dnl +_AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl +]) + +# Copyright (C) 2001-2021 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_PROG_INSTALL_STRIP +# --------------------- +# One issue with vendor 'install' (even GNU) is that you can't +# specify the program used to strip binaries. This is especially +# annoying in cross-compiling environments, where the build's strip +# is unlikely to handle the host's binaries. +# Fortunately install-sh will honor a STRIPPROG variable, so we +# always use install-sh in "make install-strip", and initialize +# STRIPPROG with the value of the STRIP variable (set by the user). +AC_DEFUN([AM_PROG_INSTALL_STRIP], +[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +# Installed binaries are usually stripped using 'strip' when the user +# run "make install-strip". However 'strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the 'STRIP' environment variable to overrule this program. +dnl Don't test for $cross_compiling = yes, because it might be 'maybe'. +if test "$cross_compiling" != no; then + AC_CHECK_TOOL([STRIP], [strip], :) +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" +AC_SUBST([INSTALL_STRIP_PROGRAM])]) + +# Copyright (C) 2006-2021 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_SUBST_NOTMAKE(VARIABLE) +# --------------------------- +# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. +# This macro is traced by Automake. +AC_DEFUN([_AM_SUBST_NOTMAKE]) + +# AM_SUBST_NOTMAKE(VARIABLE) +# -------------------------- +# Public sister of _AM_SUBST_NOTMAKE. +AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) + +# Check how to create a tarball. -*- Autoconf -*- + +# Copyright (C) 2004-2021 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_PROG_TAR(FORMAT) +# -------------------- +# Check how to create a tarball in format FORMAT. +# FORMAT should be one of 'v7', 'ustar', or 'pax'. +# +# Substitute a variable $(am__tar) that is a command +# writing to stdout a FORMAT-tarball containing the directory +# $tardir. +# tardir=directory && $(am__tar) > result.tar +# +# Substitute a variable $(am__untar) that extract such +# a tarball read from stdin. +# $(am__untar) < result.tar +# +AC_DEFUN([_AM_PROG_TAR], +[# Always define AMTAR for backward compatibility. Yes, it's still used +# in the wild :-( We should find a proper way to deprecate it ... +AC_SUBST([AMTAR], ['$${TAR-tar}']) + +# We'll loop over all known methods to create a tar archive until one works. +_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' + +m4_if([$1], [v7], + [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], + + [m4_case([$1], + [ustar], + [# The POSIX 1988 'ustar' format is defined with fixed-size fields. + # There is notably a 21 bits limit for the UID and the GID. In fact, + # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343 + # and bug#13588). + am_max_uid=2097151 # 2^21 - 1 + am_max_gid=$am_max_uid + # The $UID and $GID variables are not portable, so we need to resort + # to the POSIX-mandated id(1) utility. Errors in the 'id' calls + # below are definitely unexpected, so allow the users to see them + # (that is, avoid stderr redirection). + am_uid=`id -u || echo unknown` + am_gid=`id -g || echo unknown` + AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format]) + if test $am_uid -le $am_max_uid; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + _am_tools=none + fi + AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format]) + if test $am_gid -le $am_max_gid; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + _am_tools=none + fi], + + [pax], + [], + + [m4_fatal([Unknown tar format])]) + + AC_MSG_CHECKING([how to create a $1 tar archive]) + + # Go ahead even if we have the value already cached. We do so because we + # need to set the values for the 'am__tar' and 'am__untar' variables. + _am_tools=${am_cv_prog_tar_$1-$_am_tools} + + for _am_tool in $_am_tools; do + case $_am_tool in + gnutar) + for _am_tar in tar gnutar gtar; do + AM_RUN_LOG([$_am_tar --version]) && break + done + am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' + am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' + am__untar="$_am_tar -xf -" + ;; + plaintar) + # Must skip GNU tar: if it does not support --format= it doesn't create + # ustar tarball either. + (tar --version) >/dev/null 2>&1 && continue + am__tar='tar chf - "$$tardir"' + am__tar_='tar chf - "$tardir"' + am__untar='tar xf -' + ;; + pax) + am__tar='pax -L -x $1 -w "$$tardir"' + am__tar_='pax -L -x $1 -w "$tardir"' + am__untar='pax -r' + ;; + cpio) + am__tar='find "$$tardir" -print | cpio -o -H $1 -L' + am__tar_='find "$tardir" -print | cpio -o -H $1 -L' + am__untar='cpio -i -H $1 -d' + ;; + none) + am__tar=false + am__tar_=false + am__untar=false + ;; + esac + + # If the value was cached, stop now. We just wanted to have am__tar + # and am__untar set. + test -n "${am_cv_prog_tar_$1}" && break + + # tar/untar a dummy directory, and stop if the command works. + rm -rf conftest.dir + mkdir conftest.dir + echo GrepMe > conftest.dir/file + AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) + rm -rf conftest.dir + if test -s conftest.tar; then + AM_RUN_LOG([$am__untar /dev/null 2>&1 && break + fi + done + rm -rf conftest.dir + + AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) + AC_MSG_RESULT([$am_cv_prog_tar_$1])]) + +AC_SUBST([am__tar]) +AC_SUBST([am__untar]) +]) # _AM_PROG_TAR + +m4_include([../m4/ax_cxx_compile_stdcxx.m4]) +m4_include([../m4/ax_cxx_compile_stdcxx_11.m4]) +m4_include([../m4/ax_cxx_compile_stdcxx_11_no_override.m4]) +m4_include([../m4/ax_detect_clang.m4]) +m4_include([../m4/ax_prog_cc_for_build.m4]) +m4_include([../m4/ax_prog_cxx_for_build.m4]) +m4_include([../m4/libtool.m4]) +m4_include([../m4/ltoptions.m4]) +m4_include([../m4/ltsugar.m4]) +m4_include([../m4/ltversion.m4]) +m4_include([../m4/lt~obsolete.m4]) diff --git a/external/mit/isl/dist/interface/compile b/external/mit/isl/dist/interface/compile new file mode 100755 index 000000000000..df363c8fbfbc --- /dev/null +++ b/external/mit/isl/dist/interface/compile @@ -0,0 +1,348 @@ +#! /bin/sh +# Wrapper for compilers which do not understand '-c -o'. + +scriptversion=2018-03-07.03; # UTC + +# Copyright (C) 1999-2021 Free Software Foundation, Inc. +# Written by Tom Tromey . +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# This file is maintained in Automake, please report +# bugs to or send patches to +# . + +nl=' +' + +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent tools from complaining about whitespace usage. +IFS=" "" $nl" + +file_conv= + +# func_file_conv build_file lazy +# Convert a $build file to $host form and store it in $file +# Currently only supports Windows hosts. If the determined conversion +# type is listed in (the comma separated) LAZY, no conversion will +# take place. +func_file_conv () +{ + file=$1 + case $file in + / | /[!/]*) # absolute file, and not a UNC file + if test -z "$file_conv"; then + # lazily determine how to convert abs files + case `uname -s` in + MINGW*) + file_conv=mingw + ;; + CYGWIN* | MSYS*) + file_conv=cygwin + ;; + *) + file_conv=wine + ;; + esac + fi + case $file_conv/,$2, in + *,$file_conv,*) + ;; + mingw/*) + file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` + ;; + cygwin/* | msys/*) + file=`cygpath -m "$file" || echo "$file"` + ;; + wine/*) + file=`winepath -w "$file" || echo "$file"` + ;; + esac + ;; + esac +} + +# func_cl_dashL linkdir +# Make cl look for libraries in LINKDIR +func_cl_dashL () +{ + func_file_conv "$1" + if test -z "$lib_path"; then + lib_path=$file + else + lib_path="$lib_path;$file" + fi + linker_opts="$linker_opts -LIBPATH:$file" +} + +# func_cl_dashl library +# Do a library search-path lookup for cl +func_cl_dashl () +{ + lib=$1 + found=no + save_IFS=$IFS + IFS=';' + for dir in $lib_path $LIB + do + IFS=$save_IFS + if $shared && test -f "$dir/$lib.dll.lib"; then + found=yes + lib=$dir/$lib.dll.lib + break + fi + if test -f "$dir/$lib.lib"; then + found=yes + lib=$dir/$lib.lib + break + fi + if test -f "$dir/lib$lib.a"; then + found=yes + lib=$dir/lib$lib.a + break + fi + done + IFS=$save_IFS + + if test "$found" != yes; then + lib=$lib.lib + fi +} + +# func_cl_wrapper cl arg... +# Adjust compile command to suit cl +func_cl_wrapper () +{ + # Assume a capable shell + lib_path= + shared=: + linker_opts= + for arg + do + if test -n "$eat"; then + eat= + else + case $1 in + -o) + # configure might choose to run compile as 'compile cc -o foo foo.c'. + eat=1 + case $2 in + *.o | *.[oO][bB][jJ]) + func_file_conv "$2" + set x "$@" -Fo"$file" + shift + ;; + *) + func_file_conv "$2" + set x "$@" -Fe"$file" + shift + ;; + esac + ;; + -I) + eat=1 + func_file_conv "$2" mingw + set x "$@" -I"$file" + shift + ;; + -I*) + func_file_conv "${1#-I}" mingw + set x "$@" -I"$file" + shift + ;; + -l) + eat=1 + func_cl_dashl "$2" + set x "$@" "$lib" + shift + ;; + -l*) + func_cl_dashl "${1#-l}" + set x "$@" "$lib" + shift + ;; + -L) + eat=1 + func_cl_dashL "$2" + ;; + -L*) + func_cl_dashL "${1#-L}" + ;; + -static) + shared=false + ;; + -Wl,*) + arg=${1#-Wl,} + save_ifs="$IFS"; IFS=',' + for flag in $arg; do + IFS="$save_ifs" + linker_opts="$linker_opts $flag" + done + IFS="$save_ifs" + ;; + -Xlinker) + eat=1 + linker_opts="$linker_opts $2" + ;; + -*) + set x "$@" "$1" + shift + ;; + *.cc | *.CC | *.cxx | *.CXX | *.[cC]++) + func_file_conv "$1" + set x "$@" -Tp"$file" + shift + ;; + *.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO]) + func_file_conv "$1" mingw + set x "$@" "$file" + shift + ;; + *) + set x "$@" "$1" + shift + ;; + esac + fi + shift + done + if test -n "$linker_opts"; then + linker_opts="-link$linker_opts" + fi + exec "$@" $linker_opts + exit 1 +} + +eat= + +case $1 in + '') + echo "$0: No command. Try '$0 --help' for more information." 1>&2 + exit 1; + ;; + -h | --h*) + cat <<\EOF +Usage: compile [--help] [--version] PROGRAM [ARGS] + +Wrapper for compilers which do not understand '-c -o'. +Remove '-o dest.o' from ARGS, run PROGRAM with the remaining +arguments, and rename the output as expected. + +If you are trying to build a whole package this is not the +right script to run: please start by reading the file 'INSTALL'. + +Report bugs to . +EOF + exit $? + ;; + -v | --v*) + echo "compile $scriptversion" + exit $? + ;; + cl | *[/\\]cl | cl.exe | *[/\\]cl.exe | \ + icl | *[/\\]icl | icl.exe | *[/\\]icl.exe ) + func_cl_wrapper "$@" # Doesn't return... + ;; +esac + +ofile= +cfile= + +for arg +do + if test -n "$eat"; then + eat= + else + case $1 in + -o) + # configure might choose to run compile as 'compile cc -o foo foo.c'. + # So we strip '-o arg' only if arg is an object. + eat=1 + case $2 in + *.o | *.obj) + ofile=$2 + ;; + *) + set x "$@" -o "$2" + shift + ;; + esac + ;; + *.c) + cfile=$1 + set x "$@" "$1" + shift + ;; + *) + set x "$@" "$1" + shift + ;; + esac + fi + shift +done + +if test -z "$ofile" || test -z "$cfile"; then + # If no '-o' option was seen then we might have been invoked from a + # pattern rule where we don't need one. That is ok -- this is a + # normal compilation that the losing compiler can handle. If no + # '.c' file was seen then we are probably linking. That is also + # ok. + exec "$@" +fi + +# Name of file we expect compiler to create. +cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'` + +# Create the lock directory. +# Note: use '[/\\:.-]' here to ensure that we don't use the same name +# that we are using for the .o file. Also, base the name on the expected +# object file name, since that is what matters with a parallel build. +lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d +while true; do + if mkdir "$lockdir" >/dev/null 2>&1; then + break + fi + sleep 1 +done +# FIXME: race condition here if user kills between mkdir and trap. +trap "rmdir '$lockdir'; exit 1" 1 2 15 + +# Run the compile. +"$@" +ret=$? + +if test -f "$cofile"; then + test "$cofile" = "$ofile" || mv "$cofile" "$ofile" +elif test -f "${cofile}bj"; then + test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile" +fi + +rmdir "$lockdir" +exit $ret + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'before-save-hook 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC0" +# time-stamp-end: "; # UTC" +# End: diff --git a/external/mit/isl/dist/interface/config.guess b/external/mit/isl/dist/interface/config.guess new file mode 100755 index 000000000000..7f76b6228f73 --- /dev/null +++ b/external/mit/isl/dist/interface/config.guess @@ -0,0 +1,1754 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright 1992-2022 Free Software Foundation, Inc. + +# shellcheck disable=SC2006,SC2268 # see below for rationale + +timestamp='2022-01-09' + +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that +# program. This Exception is an additional permission under section 7 +# of the GNU General Public License, version 3 ("GPLv3"). +# +# Originally written by Per Bothner; maintained since 2000 by Ben Elliston. +# +# You can get the latest version of this script from: +# https://git.savannah.gnu.org/cgit/config.git/plain/config.guess +# +# Please send patches to . + + +# The "shellcheck disable" line above the timestamp inhibits complaints +# about features and limitations of the classic Bourne shell that were +# superseded or lifted in POSIX. However, this script identifies a wide +# variety of pre-POSIX systems that do not have POSIX shells at all, and +# even some reasonably current systems (Solaris 10 as case-in-point) still +# have a pre-POSIX /bin/sh. + + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Options: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright 1992-2022 Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + +# Just in case it came from the environment. +GUESS= + +# CC_FOR_BUILD -- compiler used by this script. Note that the use of a +# compiler to aid in system detection is discouraged as it requires +# temporary files to be created and, as you can see below, it is a +# headache to deal with in a portable fashion. + +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +# Portable tmp directory creation inspired by the Autoconf team. + +tmp= +# shellcheck disable=SC2172 +trap 'test -z "$tmp" || rm -fr "$tmp"' 0 1 2 13 15 + +set_cc_for_build() { + # prevent multiple calls if $tmp is already set + test "$tmp" && return 0 + : "${TMPDIR=/tmp}" + # shellcheck disable=SC2039,SC3028 + { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir "$tmp" 2>/dev/null) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir "$tmp" 2>/dev/null) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } + dummy=$tmp/dummy + case ${CC_FOR_BUILD-},${HOST_CC-},${CC-} in + ,,) echo "int x;" > "$dummy.c" + for driver in cc gcc c89 c99 ; do + if ($driver -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then + CC_FOR_BUILD=$driver + break + fi + done + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; + esac +} + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 1994-08-24) +if test -f /.attbin/uname ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +case $UNAME_SYSTEM in +Linux|GNU|GNU/*) + LIBC=unknown + + set_cc_for_build + cat <<-EOF > "$dummy.c" + #include + #if defined(__UCLIBC__) + LIBC=uclibc + #elif defined(__dietlibc__) + LIBC=dietlibc + #elif defined(__GLIBC__) + LIBC=gnu + #else + #include + /* First heuristic to detect musl libc. */ + #ifdef __DEFINED_va_list + LIBC=musl + #endif + #endif + EOF + cc_set_libc=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'` + eval "$cc_set_libc" + + # Second heuristic to detect musl libc. + if [ "$LIBC" = unknown ] && + command -v ldd >/dev/null && + ldd --version 2>&1 | grep -q ^musl; then + LIBC=musl + fi + + # If the system lacks a compiler, then just pick glibc. + # We could probably try harder. + if [ "$LIBC" = unknown ]; then + LIBC=gnu + fi + ;; +esac + +# Note: order is significant - the case branches are not exclusive. + +case $UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION in + *:NetBSD:*:*) + # NetBSD (nbsd) targets should (where applicable) match one or + # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \ + /sbin/sysctl -n hw.machine_arch 2>/dev/null || \ + /usr/sbin/sysctl -n hw.machine_arch 2>/dev/null || \ + echo unknown)` + case $UNAME_MACHINE_ARCH in + aarch64eb) machine=aarch64_be-unknown ;; + armeb) machine=armeb-unknown ;; + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + sh5el) machine=sh5le-unknown ;; + earmv*) + arch=`echo "$UNAME_MACHINE_ARCH" | sed -e 's,^e\(armv[0-9]\).*$,\1,'` + endian=`echo "$UNAME_MACHINE_ARCH" | sed -ne 's,^.*\(eb\)$,\1,p'` + machine=${arch}${endian}-unknown + ;; + *) machine=$UNAME_MACHINE_ARCH-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently (or will in the future) and ABI. + case $UNAME_MACHINE_ARCH in + earm*) + os=netbsdelf + ;; + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + set_cc_for_build + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ELF__ + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # Determine ABI tags. + case $UNAME_MACHINE_ARCH in + earm*) + expr='s/^earmv[0-9]/-eabi/;s/eb$//' + abi=`echo "$UNAME_MACHINE_ARCH" | sed -e "$expr"` + ;; + esac + # The OS release + # Debian GNU/NetBSD machines have a different userland, and + # thus, need a distinct triplet. However, they do not need + # kernel version information, so it can be replaced with a + # suitable tag, in the style of linux-gnu. + case $UNAME_VERSION in + Debian*) + release='-gnu' + ;; + *) + release=`echo "$UNAME_RELEASE" | sed -e 's/[-_].*//' | cut -d. -f1,2` + ;; + esac + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + GUESS=$machine-${os}${release}${abi-} + ;; + *:Bitrig:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` + GUESS=$UNAME_MACHINE_ARCH-unknown-bitrig$UNAME_RELEASE + ;; + *:OpenBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` + GUESS=$UNAME_MACHINE_ARCH-unknown-openbsd$UNAME_RELEASE + ;; + *:SecBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/SecBSD.//'` + GUESS=$UNAME_MACHINE_ARCH-unknown-secbsd$UNAME_RELEASE + ;; + *:LibertyBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'` + GUESS=$UNAME_MACHINE_ARCH-unknown-libertybsd$UNAME_RELEASE + ;; + *:MidnightBSD:*:*) + GUESS=$UNAME_MACHINE-unknown-midnightbsd$UNAME_RELEASE + ;; + *:ekkoBSD:*:*) + GUESS=$UNAME_MACHINE-unknown-ekkobsd$UNAME_RELEASE + ;; + *:SolidBSD:*:*) + GUESS=$UNAME_MACHINE-unknown-solidbsd$UNAME_RELEASE + ;; + *:OS108:*:*) + GUESS=$UNAME_MACHINE-unknown-os108_$UNAME_RELEASE + ;; + macppc:MirBSD:*:*) + GUESS=powerpc-unknown-mirbsd$UNAME_RELEASE + ;; + *:MirBSD:*:*) + GUESS=$UNAME_MACHINE-unknown-mirbsd$UNAME_RELEASE + ;; + *:Sortix:*:*) + GUESS=$UNAME_MACHINE-unknown-sortix + ;; + *:Twizzler:*:*) + GUESS=$UNAME_MACHINE-unknown-twizzler + ;; + *:Redox:*:*) + GUESS=$UNAME_MACHINE-unknown-redox + ;; + mips:OSF1:*.*) + GUESS=mips-dec-osf1 + ;; + alpha:OSF1:*:*) + # Reset EXIT trap before exiting to avoid spurious non-zero exit code. + trap '' 0 + case $UNAME_RELEASE in + *4.0) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + ;; + *5.*) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` + ;; + esac + # According to Compaq, /usr/sbin/psrinfo has been available on + # OSF/1 and Tru64 systems produced since 1995. I hope that + # covers most systems running today. This code pipes the CPU + # types through head -n 1, so we only detect the type of CPU 0. + ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` + case $ALPHA_CPU_TYPE in + "EV4 (21064)") + UNAME_MACHINE=alpha ;; + "EV4.5 (21064)") + UNAME_MACHINE=alpha ;; + "LCA4 (21066/21068)") + UNAME_MACHINE=alpha ;; + "EV5 (21164)") + UNAME_MACHINE=alphaev5 ;; + "EV5.6 (21164A)") + UNAME_MACHINE=alphaev56 ;; + "EV5.6 (21164PC)") + UNAME_MACHINE=alphapca56 ;; + "EV5.7 (21164PC)") + UNAME_MACHINE=alphapca57 ;; + "EV6 (21264)") + UNAME_MACHINE=alphaev6 ;; + "EV6.7 (21264A)") + UNAME_MACHINE=alphaev67 ;; + "EV6.8CB (21264C)") + UNAME_MACHINE=alphaev68 ;; + "EV6.8AL (21264B)") + UNAME_MACHINE=alphaev68 ;; + "EV6.8CX (21264D)") + UNAME_MACHINE=alphaev68 ;; + "EV6.9A (21264/EV69A)") + UNAME_MACHINE=alphaev69 ;; + "EV7 (21364)") + UNAME_MACHINE=alphaev7 ;; + "EV7.9 (21364A)") + UNAME_MACHINE=alphaev79 ;; + esac + # A Pn.n version is a patched version. + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + OSF_REL=`echo "$UNAME_RELEASE" | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` + GUESS=$UNAME_MACHINE-dec-osf$OSF_REL + ;; + Amiga*:UNIX_System_V:4.0:*) + GUESS=m68k-unknown-sysv4 + ;; + *:[Aa]miga[Oo][Ss]:*:*) + GUESS=$UNAME_MACHINE-unknown-amigaos + ;; + *:[Mm]orph[Oo][Ss]:*:*) + GUESS=$UNAME_MACHINE-unknown-morphos + ;; + *:OS/390:*:*) + GUESS=i370-ibm-openedition + ;; + *:z/VM:*:*) + GUESS=s390-ibm-zvmoe + ;; + *:OS400:*:*) + GUESS=powerpc-ibm-os400 + ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + GUESS=arm-acorn-riscix$UNAME_RELEASE + ;; + arm*:riscos:*:*|arm*:RISCOS:*:*) + GUESS=arm-unknown-riscos + ;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + GUESS=hppa1.1-hitachi-hiuxmpp + ;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + case `(/bin/universe) 2>/dev/null` in + att) GUESS=pyramid-pyramid-sysv3 ;; + *) GUESS=pyramid-pyramid-bsd ;; + esac + ;; + NILE*:*:*:dcosx) + GUESS=pyramid-pyramid-svr4 + ;; + DRS?6000:unix:4.0:6*) + GUESS=sparc-icl-nx6 + ;; + DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) + case `/usr/bin/uname -p` in + sparc) GUESS=sparc-icl-nx7 ;; + esac + ;; + s390x:SunOS:*:*) + SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` + GUESS=$UNAME_MACHINE-ibm-solaris2$SUN_REL + ;; + sun4H:SunOS:5.*:*) + SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` + GUESS=sparc-hal-solaris2$SUN_REL + ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` + GUESS=sparc-sun-solaris2$SUN_REL + ;; + i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) + GUESS=i386-pc-auroraux$UNAME_RELEASE + ;; + i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) + set_cc_for_build + SUN_ARCH=i386 + # If there is a compiler, see if it is configured for 64-bit objects. + # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. + # This test works for both compilers. + if test "$CC_FOR_BUILD" != no_compiler_found; then + if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS="" $CC_FOR_BUILD -m64 -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + SUN_ARCH=x86_64 + fi + fi + SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` + GUESS=$SUN_ARCH-pc-solaris2$SUN_REL + ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` + GUESS=sparc-sun-solaris3$SUN_REL + ;; + sun4*:SunOS:*:*) + case `/usr/bin/arch -k` in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/-/_/'` + GUESS=sparc-sun-sunos$SUN_REL + ;; + sun3*:SunOS:*:*) + GUESS=m68k-sun-sunos$UNAME_RELEASE + ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x$UNAME_RELEASE" = x && UNAME_RELEASE=3 + case `/bin/arch` in + sun3) + GUESS=m68k-sun-sunos$UNAME_RELEASE + ;; + sun4) + GUESS=sparc-sun-sunos$UNAME_RELEASE + ;; + esac + ;; + aushp:SunOS:*:*) + GUESS=sparc-auspex-sunos$UNAME_RELEASE + ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + GUESS=m68k-atari-mint$UNAME_RELEASE + ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + GUESS=m68k-atari-mint$UNAME_RELEASE + ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + GUESS=m68k-atari-mint$UNAME_RELEASE + ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + GUESS=m68k-milan-mint$UNAME_RELEASE + ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + GUESS=m68k-hades-mint$UNAME_RELEASE + ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + GUESS=m68k-unknown-mint$UNAME_RELEASE + ;; + m68k:machten:*:*) + GUESS=m68k-apple-machten$UNAME_RELEASE + ;; + powerpc:machten:*:*) + GUESS=powerpc-apple-machten$UNAME_RELEASE + ;; + RISC*:Mach:*:*) + GUESS=mips-dec-mach_bsd4.3 + ;; + RISC*:ULTRIX:*:*) + GUESS=mips-dec-ultrix$UNAME_RELEASE + ;; + VAX*:ULTRIX*:*:*) + GUESS=vax-dec-ultrix$UNAME_RELEASE + ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + GUESS=clipper-intergraph-clix$UNAME_RELEASE + ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + set_cc_for_build + sed 's/^ //' << EOF > "$dummy.c" +#ifdef __cplusplus +#include /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD -o "$dummy" "$dummy.c" && + dummyarg=`echo "$UNAME_RELEASE" | sed -n 's/\([0-9]*\).*/\1/p'` && + SYSTEM_NAME=`"$dummy" "$dummyarg"` && + { echo "$SYSTEM_NAME"; exit; } + GUESS=mips-mips-riscos$UNAME_RELEASE + ;; + Motorola:PowerMAX_OS:*:*) + GUESS=powerpc-motorola-powermax + ;; + Motorola:*:4.3:PL8-*) + GUESS=powerpc-harris-powermax + ;; + Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) + GUESS=powerpc-harris-powermax + ;; + Night_Hawk:Power_UNIX:*:*) + GUESS=powerpc-harris-powerunix + ;; + m88k:CX/UX:7*:*) + GUESS=m88k-harris-cxux7 + ;; + m88k:*:4*:R4*) + GUESS=m88k-motorola-sysv4 + ;; + m88k:*:3*:R3*) + GUESS=m88k-motorola-sysv3 + ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if test "$UNAME_PROCESSOR" = mc88100 || test "$UNAME_PROCESSOR" = mc88110 + then + if test "$TARGET_BINARY_INTERFACE"x = m88kdguxelfx || \ + test "$TARGET_BINARY_INTERFACE"x = x + then + GUESS=m88k-dg-dgux$UNAME_RELEASE + else + GUESS=m88k-dg-dguxbcs$UNAME_RELEASE + fi + else + GUESS=i586-dg-dgux$UNAME_RELEASE + fi + ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + GUESS=m88k-dolphin-sysv3 + ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + GUESS=m88k-motorola-sysv3 + ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + GUESS=m88k-tektronix-sysv3 + ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + GUESS=m68k-tektronix-bsd + ;; + *:IRIX*:*:*) + IRIX_REL=`echo "$UNAME_RELEASE" | sed -e 's/-/_/g'` + GUESS=mips-sgi-irix$IRIX_REL + ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + GUESS=romp-ibm-aix # uname -m gives an 8 hex-code CPU id + ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + GUESS=i386-ibm-aix + ;; + ia64:AIX:*:*) + if test -x /usr/bin/oslevel ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=$UNAME_VERSION.$UNAME_RELEASE + fi + GUESS=$UNAME_MACHINE-ibm-aix$IBM_REV + ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + set_cc_for_build + sed 's/^ //' << EOF > "$dummy.c" + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + if $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` + then + GUESS=$SYSTEM_NAME + else + GUESS=rs6000-ibm-aix3.2.5 + fi + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + GUESS=rs6000-ibm-aix3.2.4 + else + GUESS=rs6000-ibm-aix3.2 + fi + ;; + *:AIX:*:[4567]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + if /usr/sbin/lsattr -El "$IBM_CPU_ID" | grep ' POWER' >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if test -x /usr/bin/lslpp ; then + IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc | \ + awk -F: '{ print $3 }' | sed s/[0-9]*$/0/` + else + IBM_REV=$UNAME_VERSION.$UNAME_RELEASE + fi + GUESS=$IBM_ARCH-ibm-aix$IBM_REV + ;; + *:AIX:*:*) + GUESS=rs6000-ibm-aix + ;; + ibmrt:4.4BSD:*|romp-ibm:4.4BSD:*) + GUESS=romp-ibm-bsd4.4 + ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + GUESS=romp-ibm-bsd$UNAME_RELEASE # 4.3 with uname added to + ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + GUESS=rs6000-bull-bosx + ;; + DPX/2?00:B.O.S.:*:*) + GUESS=m68k-bull-sysv3 + ;; + 9000/[34]??:4.3bsd:1.*:*) + GUESS=m68k-hp-bsd + ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + GUESS=m68k-hp-bsd4.4 + ;; + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*.[0B]*//'` + case $UNAME_MACHINE in + 9000/31?) HP_ARCH=m68000 ;; + 9000/[34]??) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + if test -x /usr/bin/getconf; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case $sc_cpu_version in + 523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0 + 528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case $sc_kernel_bits in + 32) HP_ARCH=hppa2.0n ;; + 64) HP_ARCH=hppa2.0w ;; + '') HP_ARCH=hppa2.0 ;; # HP-UX 10.20 + esac ;; + esac + fi + if test "$HP_ARCH" = ""; then + set_cc_for_build + sed 's/^ //' << EOF > "$dummy.c" + + #define _HPUX_SOURCE + #include + #include + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS="" $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null) && HP_ARCH=`"$dummy"` + test -z "$HP_ARCH" && HP_ARCH=hppa + fi ;; + esac + if test "$HP_ARCH" = hppa2.0w + then + set_cc_for_build + + # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating + # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler + # generating 64-bit code. GNU and HP use different nomenclature: + # + # $ CC_FOR_BUILD=cc ./config.guess + # => hppa2.0w-hp-hpux11.23 + # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess + # => hppa64-hp-hpux11.23 + + if echo __LP64__ | (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | + grep -q __LP64__ + then + HP_ARCH=hppa2.0w + else + HP_ARCH=hppa64 + fi + fi + GUESS=$HP_ARCH-hp-hpux$HPUX_REV + ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*.[0B]*//'` + GUESS=ia64-hp-hpux$HPUX_REV + ;; + 3050*:HI-UX:*:*) + set_cc_for_build + sed 's/^ //' << EOF > "$dummy.c" + #include + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` && + { echo "$SYSTEM_NAME"; exit; } + GUESS=unknown-hitachi-hiuxwe2 + ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:*) + GUESS=hppa1.1-hp-bsd + ;; + 9000/8??:4.3bsd:*:*) + GUESS=hppa1.0-hp-bsd + ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + GUESS=hppa1.0-hp-mpeix + ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:*) + GUESS=hppa1.1-hp-osf + ;; + hp8??:OSF1:*:*) + GUESS=hppa1.0-hp-osf + ;; + i*86:OSF1:*:*) + if test -x /usr/sbin/sysversion ; then + GUESS=$UNAME_MACHINE-unknown-osf1mk + else + GUESS=$UNAME_MACHINE-unknown-osf1 + fi + ;; + parisc*:Lites*:*:*) + GUESS=hppa1.1-hp-lites + ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + GUESS=c1-convex-bsd + ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + GUESS=c34-convex-bsd + ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + GUESS=c38-convex-bsd + ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + GUESS=c4-convex-bsd + ;; + CRAY*Y-MP:*:*:*) + CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` + GUESS=ymp-cray-unicos$CRAY_REL + ;; + CRAY*[A-Z]90:*:*:*) + echo "$UNAME_MACHINE"-cray-unicos"$UNAME_RELEASE" \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ + -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*TS:*:*:*) + CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` + GUESS=t90-cray-unicos$CRAY_REL + ;; + CRAY*T3E:*:*:*) + CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` + GUESS=alphaev5-cray-unicosmk$CRAY_REL + ;; + CRAY*SV1:*:*:*) + CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` + GUESS=sv1-cray-unicos$CRAY_REL + ;; + *:UNICOS/mp:*:*) + CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` + GUESS=craynv-cray-unicosmp$CRAY_REL + ;; + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` + FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` + FUJITSU_REL=`echo "$UNAME_RELEASE" | sed -e 's/ /_/'` + GUESS=${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL} + ;; + 5000:UNIX_System_V:4.*:*) + FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` + FUJITSU_REL=`echo "$UNAME_RELEASE" | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'` + GUESS=sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL} + ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + GUESS=$UNAME_MACHINE-pc-bsdi$UNAME_RELEASE + ;; + sparc*:BSD/OS:*:*) + GUESS=sparc-unknown-bsdi$UNAME_RELEASE + ;; + *:BSD/OS:*:*) + GUESS=$UNAME_MACHINE-unknown-bsdi$UNAME_RELEASE + ;; + arm:FreeBSD:*:*) + UNAME_PROCESSOR=`uname -p` + set_cc_for_build + if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_PCS_VFP + then + FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` + GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL-gnueabi + else + FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` + GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL-gnueabihf + fi + ;; + *:FreeBSD:*:*) + UNAME_PROCESSOR=`/usr/bin/uname -p` + case $UNAME_PROCESSOR in + amd64) + UNAME_PROCESSOR=x86_64 ;; + i386) + UNAME_PROCESSOR=i586 ;; + esac + FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` + GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL + ;; + i*:CYGWIN*:*) + GUESS=$UNAME_MACHINE-pc-cygwin + ;; + *:MINGW64*:*) + GUESS=$UNAME_MACHINE-pc-mingw64 + ;; + *:MINGW*:*) + GUESS=$UNAME_MACHINE-pc-mingw32 + ;; + *:MSYS*:*) + GUESS=$UNAME_MACHINE-pc-msys + ;; + i*:PW*:*) + GUESS=$UNAME_MACHINE-pc-pw32 + ;; + *:SerenityOS:*:*) + GUESS=$UNAME_MACHINE-pc-serenity + ;; + *:Interix*:*) + case $UNAME_MACHINE in + x86) + GUESS=i586-pc-interix$UNAME_RELEASE + ;; + authenticamd | genuineintel | EM64T) + GUESS=x86_64-unknown-interix$UNAME_RELEASE + ;; + IA64) + GUESS=ia64-unknown-interix$UNAME_RELEASE + ;; + esac ;; + i*:UWIN*:*) + GUESS=$UNAME_MACHINE-pc-uwin + ;; + amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) + GUESS=x86_64-pc-cygwin + ;; + prep*:SunOS:5.*:*) + SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` + GUESS=powerpcle-unknown-solaris2$SUN_REL + ;; + *:GNU:*:*) + # the GNU system + GNU_ARCH=`echo "$UNAME_MACHINE" | sed -e 's,[-/].*$,,'` + GNU_REL=`echo "$UNAME_RELEASE" | sed -e 's,/.*$,,'` + GUESS=$GNU_ARCH-unknown-$LIBC$GNU_REL + ;; + *:GNU/*:*:*) + # other systems with GNU libc and userland + GNU_SYS=`echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"` + GNU_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` + GUESS=$UNAME_MACHINE-unknown-$GNU_SYS$GNU_REL-$LIBC + ;; + *:Minix:*:*) + GUESS=$UNAME_MACHINE-unknown-minix + ;; + aarch64:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + aarch64_be:Linux:*:*) + UNAME_MACHINE=aarch64_be + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' /proc/cpuinfo 2>/dev/null` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep -q ld.so.1 + if test "$?" = 0 ; then LIBC=gnulibc1 ; fi + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + arc:Linux:*:* | arceb:Linux:*:* | arc32:Linux:*:* | arc64:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + arm*:Linux:*:*) + set_cc_for_build + if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_EABI__ + then + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + else + if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_PCS_VFP + then + GUESS=$UNAME_MACHINE-unknown-linux-${LIBC}eabi + else + GUESS=$UNAME_MACHINE-unknown-linux-${LIBC}eabihf + fi + fi + ;; + avr32*:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + cris:Linux:*:*) + GUESS=$UNAME_MACHINE-axis-linux-$LIBC + ;; + crisv32:Linux:*:*) + GUESS=$UNAME_MACHINE-axis-linux-$LIBC + ;; + e2k:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + frv:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + hexagon:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + i*86:Linux:*:*) + GUESS=$UNAME_MACHINE-pc-linux-$LIBC + ;; + ia64:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + k1om:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + loongarch32:Linux:*:* | loongarch64:Linux:*:* | loongarchx32:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + m32r*:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + m68*:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + mips:Linux:*:* | mips64:Linux:*:*) + set_cc_for_build + IS_GLIBC=0 + test x"${LIBC}" = xgnu && IS_GLIBC=1 + sed 's/^ //' << EOF > "$dummy.c" + #undef CPU + #undef mips + #undef mipsel + #undef mips64 + #undef mips64el + #if ${IS_GLIBC} && defined(_ABI64) + LIBCABI=gnuabi64 + #else + #if ${IS_GLIBC} && defined(_ABIN32) + LIBCABI=gnuabin32 + #else + LIBCABI=${LIBC} + #endif + #endif + + #if ${IS_GLIBC} && defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6 + CPU=mipsisa64r6 + #else + #if ${IS_GLIBC} && !defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6 + CPU=mipsisa32r6 + #else + #if defined(__mips64) + CPU=mips64 + #else + CPU=mips + #endif + #endif + #endif + + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + MIPS_ENDIAN=el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + MIPS_ENDIAN= + #else + MIPS_ENDIAN= + #endif + #endif +EOF + cc_set_vars=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU\|^MIPS_ENDIAN\|^LIBCABI'` + eval "$cc_set_vars" + test "x$CPU" != x && { echo "$CPU${MIPS_ENDIAN}-unknown-linux-$LIBCABI"; exit; } + ;; + mips64el:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + openrisc*:Linux:*:*) + GUESS=or1k-unknown-linux-$LIBC + ;; + or32:Linux:*:* | or1k*:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + padre:Linux:*:*) + GUESS=sparc-unknown-linux-$LIBC + ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + GUESS=hppa64-unknown-linux-$LIBC + ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) GUESS=hppa1.1-unknown-linux-$LIBC ;; + PA8*) GUESS=hppa2.0-unknown-linux-$LIBC ;; + *) GUESS=hppa-unknown-linux-$LIBC ;; + esac + ;; + ppc64:Linux:*:*) + GUESS=powerpc64-unknown-linux-$LIBC + ;; + ppc:Linux:*:*) + GUESS=powerpc-unknown-linux-$LIBC + ;; + ppc64le:Linux:*:*) + GUESS=powerpc64le-unknown-linux-$LIBC + ;; + ppcle:Linux:*:*) + GUESS=powerpcle-unknown-linux-$LIBC + ;; + riscv32:Linux:*:* | riscv32be:Linux:*:* | riscv64:Linux:*:* | riscv64be:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + s390:Linux:*:* | s390x:Linux:*:*) + GUESS=$UNAME_MACHINE-ibm-linux-$LIBC + ;; + sh64*:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + sh*:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + tile*:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + vax:Linux:*:*) + GUESS=$UNAME_MACHINE-dec-linux-$LIBC + ;; + x86_64:Linux:*:*) + set_cc_for_build + LIBCABI=$LIBC + if test "$CC_FOR_BUILD" != no_compiler_found; then + if (echo '#ifdef __ILP32__'; echo IS_X32; echo '#endif') | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_X32 >/dev/null + then + LIBCABI=${LIBC}x32 + fi + fi + GUESS=$UNAME_MACHINE-pc-linux-$LIBCABI + ;; + xtensa*:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + i*86:DYNIX/ptx:4*:*) + # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. + # earlier versions are messed up and put the nodename in both + # sysname and nodename. + GUESS=i386-sequent-sysv4 + ;; + i*86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + GUESS=$UNAME_MACHINE-pc-sysv4.2uw$UNAME_VERSION + ;; + i*86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + GUESS=$UNAME_MACHINE-pc-os2-emx + ;; + i*86:XTS-300:*:STOP) + GUESS=$UNAME_MACHINE-unknown-stop + ;; + i*86:atheos:*:*) + GUESS=$UNAME_MACHINE-unknown-atheos + ;; + i*86:syllable:*:*) + GUESS=$UNAME_MACHINE-pc-syllable + ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) + GUESS=i386-unknown-lynxos$UNAME_RELEASE + ;; + i*86:*DOS:*:*) + GUESS=$UNAME_MACHINE-pc-msdosdjgpp + ;; + i*86:*:4.*:*) + UNAME_REL=`echo "$UNAME_RELEASE" | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + GUESS=$UNAME_MACHINE-univel-sysv$UNAME_REL + else + GUESS=$UNAME_MACHINE-pc-sysv$UNAME_REL + fi + ;; + i*86:*:5:[678]*) + # UnixWare 7.x, OpenUNIX and OpenServer 6. + case `/bin/uname -X | grep "^Machine"` in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + GUESS=$UNAME_MACHINE-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` + (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + GUESS=$UNAME_MACHINE-pc-sco$UNAME_REL + else + GUESS=$UNAME_MACHINE-pc-sysv32 + fi + ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i586. + # Note: whatever this is, it MUST be the same as what config.sub + # prints for the "djgpp" host, or else GDB configure will decide that + # this is a cross-build. + GUESS=i586-pc-msdosdjgpp + ;; + Intel:Mach:3*:*) + GUESS=i386-pc-mach3 + ;; + paragon:*:*:*) + GUESS=i860-intel-osf1 + ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + GUESS=i860-stardent-sysv$UNAME_RELEASE # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + GUESS=i860-unknown-sysv$UNAME_RELEASE # Unknown i860-SVR4 + fi + ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + GUESS=m68010-convergent-sysv + ;; + mc68k:UNIX:SYSTEM5:3.51m) + GUESS=m68k-convergent-sysv + ;; + M680?0:D-NIX:5.3:*) + GUESS=m68k-diab-dnix + ;; + M68*:*:R3V[5678]*:*) + test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; + 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4; exit; } ;; + NCR*:*:4.2:* | MPRAS*:*:4.2:*) + OS_REL='.3' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } + /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ + && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + GUESS=m68k-unknown-lynxos$UNAME_RELEASE + ;; + mc68030:UNIX_System_V:4.*:*) + GUESS=m68k-atari-sysv4 + ;; + TSUNAMI:LynxOS:2.*:*) + GUESS=sparc-unknown-lynxos$UNAME_RELEASE + ;; + rs6000:LynxOS:2.*:*) + GUESS=rs6000-unknown-lynxos$UNAME_RELEASE + ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) + GUESS=powerpc-unknown-lynxos$UNAME_RELEASE + ;; + SM[BE]S:UNIX_SV:*:*) + GUESS=mips-dde-sysv$UNAME_RELEASE + ;; + RM*:ReliantUNIX-*:*:*) + GUESS=mips-sni-sysv4 + ;; + RM*:SINIX-*:*:*) + GUESS=mips-sni-sysv4 + ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + GUESS=$UNAME_MACHINE-sni-sysv4 + else + GUESS=ns32k-sni-sysv + fi + ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + GUESS=i586-unisys-sysv4 + ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + GUESS=hppa1.1-stratus-sysv4 + ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + GUESS=i860-stratus-sysv4 + ;; + i*86:VOS:*:*) + # From Paul.Green@stratus.com. + GUESS=$UNAME_MACHINE-stratus-vos + ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + GUESS=hppa1.1-stratus-vos + ;; + mc68*:A/UX:*:*) + GUESS=m68k-apple-aux$UNAME_RELEASE + ;; + news*:NEWS-OS:6*:*) + GUESS=mips-sony-newsos6 + ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if test -d /usr/nec; then + GUESS=mips-nec-sysv$UNAME_RELEASE + else + GUESS=mips-unknown-sysv$UNAME_RELEASE + fi + ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + GUESS=powerpc-be-beos + ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + GUESS=powerpc-apple-beos + ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + GUESS=i586-pc-beos + ;; + BePC:Haiku:*:*) # Haiku running on Intel PC compatible. + GUESS=i586-pc-haiku + ;; + x86_64:Haiku:*:*) + GUESS=x86_64-unknown-haiku + ;; + SX-4:SUPER-UX:*:*) + GUESS=sx4-nec-superux$UNAME_RELEASE + ;; + SX-5:SUPER-UX:*:*) + GUESS=sx5-nec-superux$UNAME_RELEASE + ;; + SX-6:SUPER-UX:*:*) + GUESS=sx6-nec-superux$UNAME_RELEASE + ;; + SX-7:SUPER-UX:*:*) + GUESS=sx7-nec-superux$UNAME_RELEASE + ;; + SX-8:SUPER-UX:*:*) + GUESS=sx8-nec-superux$UNAME_RELEASE + ;; + SX-8R:SUPER-UX:*:*) + GUESS=sx8r-nec-superux$UNAME_RELEASE + ;; + SX-ACE:SUPER-UX:*:*) + GUESS=sxace-nec-superux$UNAME_RELEASE + ;; + Power*:Rhapsody:*:*) + GUESS=powerpc-apple-rhapsody$UNAME_RELEASE + ;; + *:Rhapsody:*:*) + GUESS=$UNAME_MACHINE-apple-rhapsody$UNAME_RELEASE + ;; + arm64:Darwin:*:*) + GUESS=aarch64-apple-darwin$UNAME_RELEASE + ;; + *:Darwin:*:*) + UNAME_PROCESSOR=`uname -p` + case $UNAME_PROCESSOR in + unknown) UNAME_PROCESSOR=powerpc ;; + esac + if command -v xcode-select > /dev/null 2> /dev/null && \ + ! xcode-select --print-path > /dev/null 2> /dev/null ; then + # Avoid executing cc if there is no toolchain installed as + # cc will be a stub that puts up a graphical alert + # prompting the user to install developer tools. + CC_FOR_BUILD=no_compiler_found + else + set_cc_for_build + fi + if test "$CC_FOR_BUILD" != no_compiler_found; then + if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + case $UNAME_PROCESSOR in + i386) UNAME_PROCESSOR=x86_64 ;; + powerpc) UNAME_PROCESSOR=powerpc64 ;; + esac + fi + # On 10.4-10.6 one might compile for PowerPC via gcc -arch ppc + if (echo '#ifdef __POWERPC__'; echo IS_PPC; echo '#endif') | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_PPC >/dev/null + then + UNAME_PROCESSOR=powerpc + fi + elif test "$UNAME_PROCESSOR" = i386 ; then + # uname -m returns i386 or x86_64 + UNAME_PROCESSOR=$UNAME_MACHINE + fi + GUESS=$UNAME_PROCESSOR-apple-darwin$UNAME_RELEASE + ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = x86; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + GUESS=$UNAME_PROCESSOR-$UNAME_MACHINE-nto-qnx$UNAME_RELEASE + ;; + *:QNX:*:4*) + GUESS=i386-pc-qnx + ;; + NEO-*:NONSTOP_KERNEL:*:*) + GUESS=neo-tandem-nsk$UNAME_RELEASE + ;; + NSE-*:NONSTOP_KERNEL:*:*) + GUESS=nse-tandem-nsk$UNAME_RELEASE + ;; + NSR-*:NONSTOP_KERNEL:*:*) + GUESS=nsr-tandem-nsk$UNAME_RELEASE + ;; + NSV-*:NONSTOP_KERNEL:*:*) + GUESS=nsv-tandem-nsk$UNAME_RELEASE + ;; + NSX-*:NONSTOP_KERNEL:*:*) + GUESS=nsx-tandem-nsk$UNAME_RELEASE + ;; + *:NonStop-UX:*:*) + GUESS=mips-compaq-nonstopux + ;; + BS2000:POSIX*:*:*) + GUESS=bs2000-siemens-sysv + ;; + DS/*:UNIX_System_V:*:*) + GUESS=$UNAME_MACHINE-$UNAME_SYSTEM-$UNAME_RELEASE + ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + if test "${cputype-}" = 386; then + UNAME_MACHINE=i386 + elif test "x${cputype-}" != x; then + UNAME_MACHINE=$cputype + fi + GUESS=$UNAME_MACHINE-unknown-plan9 + ;; + *:TOPS-10:*:*) + GUESS=pdp10-unknown-tops10 + ;; + *:TENEX:*:*) + GUESS=pdp10-unknown-tenex + ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + GUESS=pdp10-dec-tops20 + ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + GUESS=pdp10-xkl-tops20 + ;; + *:TOPS-20:*:*) + GUESS=pdp10-unknown-tops20 + ;; + *:ITS:*:*) + GUESS=pdp10-unknown-its + ;; + SEI:*:*:SEIUX) + GUESS=mips-sei-seiux$UNAME_RELEASE + ;; + *:DragonFly:*:*) + DRAGONFLY_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` + GUESS=$UNAME_MACHINE-unknown-dragonfly$DRAGONFLY_REL + ;; + *:*VMS:*:*) + UNAME_MACHINE=`(uname -p) 2>/dev/null` + case $UNAME_MACHINE in + A*) GUESS=alpha-dec-vms ;; + I*) GUESS=ia64-dec-vms ;; + V*) GUESS=vax-dec-vms ;; + esac ;; + *:XENIX:*:SysV) + GUESS=i386-pc-xenix + ;; + i*86:skyos:*:*) + SKYOS_REL=`echo "$UNAME_RELEASE" | sed -e 's/ .*$//'` + GUESS=$UNAME_MACHINE-pc-skyos$SKYOS_REL + ;; + i*86:rdos:*:*) + GUESS=$UNAME_MACHINE-pc-rdos + ;; + i*86:Fiwix:*:*) + GUESS=$UNAME_MACHINE-pc-fiwix + ;; + *:AROS:*:*) + GUESS=$UNAME_MACHINE-unknown-aros + ;; + x86_64:VMkernel:*:*) + GUESS=$UNAME_MACHINE-unknown-esx + ;; + amd64:Isilon\ OneFS:*:*) + GUESS=x86_64-unknown-onefs + ;; + *:Unleashed:*:*) + GUESS=$UNAME_MACHINE-unknown-unleashed$UNAME_RELEASE + ;; +esac + +# Do we have a guess based on uname results? +if test "x$GUESS" != x; then + echo "$GUESS" + exit +fi + +# No uname command or uname output not recognized. +set_cc_for_build +cat > "$dummy.c" < +#include +#endif +#if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__) +#if defined (vax) || defined (__vax) || defined (__vax__) || defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__) +#include +#if defined(_SIZE_T_) || defined(SIGLOST) +#include +#endif +#endif +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); +#endif + +#if defined (vax) +#if !defined (ultrix) +#include +#if defined (BSD) +#if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +#else +#if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +#else + printf ("vax-dec-bsd\n"); exit (0); +#endif +#endif +#else + printf ("vax-dec-bsd\n"); exit (0); +#endif +#else +#if defined(_SIZE_T_) || defined(SIGLOST) + struct utsname un; + uname (&un); + printf ("vax-dec-ultrix%s\n", un.release); exit (0); +#else + printf ("vax-dec-ultrix\n"); exit (0); +#endif +#endif +#endif +#if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__) +#if defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__) +#if defined(_SIZE_T_) || defined(SIGLOST) + struct utsname *un; + uname (&un); + printf ("mips-dec-ultrix%s\n", un.release); exit (0); +#else + printf ("mips-dec-ultrix\n"); exit (0); +#endif +#endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null && SYSTEM_NAME=`"$dummy"` && + { echo "$SYSTEM_NAME"; exit; } + +# Apollos put the system type in the environment. +test -d /usr/apollo && { echo "$ISP-apollo-$SYSTYPE"; exit; } + +echo "$0: unable to guess system type" >&2 + +case $UNAME_MACHINE:$UNAME_SYSTEM in + mips:Linux | mips64:Linux) + # If we got here on MIPS GNU/Linux, output extra information. + cat >&2 <&2 <&2 </dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = "$UNAME_MACHINE" +UNAME_RELEASE = "$UNAME_RELEASE" +UNAME_SYSTEM = "$UNAME_SYSTEM" +UNAME_VERSION = "$UNAME_VERSION" +EOF +fi + +exit 1 + +# Local variables: +# eval: (add-hook 'before-save-hook 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/external/mit/isl/dist/interface/config.sub b/external/mit/isl/dist/interface/config.sub new file mode 100755 index 000000000000..dba16e84c77c --- /dev/null +++ b/external/mit/isl/dist/interface/config.sub @@ -0,0 +1,1890 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright 1992-2022 Free Software Foundation, Inc. + +# shellcheck disable=SC2006,SC2268 # see below for rationale + +timestamp='2022-01-03' + +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that +# program. This Exception is an additional permission under section 7 +# of the GNU General Public License, version 3 ("GPLv3"). + + +# Please send patches to . +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# You can get the latest version of this script from: +# https://git.savannah.gnu.org/cgit/config.git/plain/config.sub + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +# The "shellcheck disable" line above the timestamp inhibits complaints +# about features and limitations of the classic Bourne shell that were +# superseded or lifted in POSIX. However, this script identifies a wide +# variety of pre-POSIX systems that do not have POSIX shells at all, and +# even some reasonably current systems (Solaris 10 as case-in-point) still +# have a pre-POSIX /bin/sh. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS + +Canonicalize a configuration name. + +Options: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.sub ($timestamp) + +Copyright 1992-2022 Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo "$1" + exit ;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +esac + +# Split fields of configuration type +# shellcheck disable=SC2162 +saved_IFS=$IFS +IFS="-" read field1 field2 field3 field4 <&2 + exit 1 + ;; + *-*-*-*) + basic_machine=$field1-$field2 + basic_os=$field3-$field4 + ;; + *-*-*) + # Ambiguous whether COMPANY is present, or skipped and KERNEL-OS is two + # parts + maybe_os=$field2-$field3 + case $maybe_os in + nto-qnx* | linux-* | uclinux-uclibc* \ + | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* \ + | netbsd*-eabi* | kopensolaris*-gnu* | cloudabi*-eabi* \ + | storm-chaos* | os2-emx* | rtmk-nova*) + basic_machine=$field1 + basic_os=$maybe_os + ;; + android-linux) + basic_machine=$field1-unknown + basic_os=linux-android + ;; + *) + basic_machine=$field1-$field2 + basic_os=$field3 + ;; + esac + ;; + *-*) + # A lone config we happen to match not fitting any pattern + case $field1-$field2 in + decstation-3100) + basic_machine=mips-dec + basic_os= + ;; + *-*) + # Second component is usually, but not always the OS + case $field2 in + # Prevent following clause from handling this valid os + sun*os*) + basic_machine=$field1 + basic_os=$field2 + ;; + zephyr*) + basic_machine=$field1-unknown + basic_os=$field2 + ;; + # Manufacturers + dec* | mips* | sequent* | encore* | pc533* | sgi* | sony* \ + | att* | 7300* | 3300* | delta* | motorola* | sun[234]* \ + | unicom* | ibm* | next | hp | isi* | apollo | altos* \ + | convergent* | ncr* | news | 32* | 3600* | 3100* \ + | hitachi* | c[123]* | convex* | sun | crds | omron* | dg \ + | ultra | tti* | harris | dolphin | highlevel | gould \ + | cbm | ns | masscomp | apple | axis | knuth | cray \ + | microblaze* | sim | cisco \ + | oki | wec | wrs | winbond) + basic_machine=$field1-$field2 + basic_os= + ;; + *) + basic_machine=$field1 + basic_os=$field2 + ;; + esac + ;; + esac + ;; + *) + # Convert single-component short-hands not valid as part of + # multi-component configurations. + case $field1 in + 386bsd) + basic_machine=i386-pc + basic_os=bsd + ;; + a29khif) + basic_machine=a29k-amd + basic_os=udi + ;; + adobe68k) + basic_machine=m68010-adobe + basic_os=scout + ;; + alliant) + basic_machine=fx80-alliant + basic_os= + ;; + altos | altos3068) + basic_machine=m68k-altos + basic_os= + ;; + am29k) + basic_machine=a29k-none + basic_os=bsd + ;; + amdahl) + basic_machine=580-amdahl + basic_os=sysv + ;; + amiga) + basic_machine=m68k-unknown + basic_os= + ;; + amigaos | amigados) + basic_machine=m68k-unknown + basic_os=amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + basic_os=sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + basic_os=sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + basic_os=bsd + ;; + aros) + basic_machine=i386-pc + basic_os=aros + ;; + aux) + basic_machine=m68k-apple + basic_os=aux + ;; + balance) + basic_machine=ns32k-sequent + basic_os=dynix + ;; + blackfin) + basic_machine=bfin-unknown + basic_os=linux + ;; + cegcc) + basic_machine=arm-unknown + basic_os=cegcc + ;; + convex-c1) + basic_machine=c1-convex + basic_os=bsd + ;; + convex-c2) + basic_machine=c2-convex + basic_os=bsd + ;; + convex-c32) + basic_machine=c32-convex + basic_os=bsd + ;; + convex-c34) + basic_machine=c34-convex + basic_os=bsd + ;; + convex-c38) + basic_machine=c38-convex + basic_os=bsd + ;; + cray) + basic_machine=j90-cray + basic_os=unicos + ;; + crds | unos) + basic_machine=m68k-crds + basic_os= + ;; + da30) + basic_machine=m68k-da30 + basic_os= + ;; + decstation | pmax | pmin | dec3100 | decstatn) + basic_machine=mips-dec + basic_os= + ;; + delta88) + basic_machine=m88k-motorola + basic_os=sysv3 + ;; + dicos) + basic_machine=i686-pc + basic_os=dicos + ;; + djgpp) + basic_machine=i586-pc + basic_os=msdosdjgpp + ;; + ebmon29k) + basic_machine=a29k-amd + basic_os=ebmon + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + basic_os=ose + ;; + gmicro) + basic_machine=tron-gmicro + basic_os=sysv + ;; + go32) + basic_machine=i386-pc + basic_os=go32 + ;; + h8300hms) + basic_machine=h8300-hitachi + basic_os=hms + ;; + h8300xray) + basic_machine=h8300-hitachi + basic_os=xray + ;; + h8500hms) + basic_machine=h8500-hitachi + basic_os=hms + ;; + harris) + basic_machine=m88k-harris + basic_os=sysv3 + ;; + hp300 | hp300hpux) + basic_machine=m68k-hp + basic_os=hpux + ;; + hp300bsd) + basic_machine=m68k-hp + basic_os=bsd + ;; + hppaosf) + basic_machine=hppa1.1-hp + basic_os=osf + ;; + hppro) + basic_machine=hppa1.1-hp + basic_os=proelf + ;; + i386mach) + basic_machine=i386-mach + basic_os=mach + ;; + isi68 | isi) + basic_machine=m68k-isi + basic_os=sysv + ;; + m68knommu) + basic_machine=m68k-unknown + basic_os=linux + ;; + magnum | m3230) + basic_machine=mips-mips + basic_os=sysv + ;; + merlin) + basic_machine=ns32k-utek + basic_os=sysv + ;; + mingw64) + basic_machine=x86_64-pc + basic_os=mingw64 + ;; + mingw32) + basic_machine=i686-pc + basic_os=mingw32 + ;; + mingw32ce) + basic_machine=arm-unknown + basic_os=mingw32ce + ;; + monitor) + basic_machine=m68k-rom68k + basic_os=coff + ;; + morphos) + basic_machine=powerpc-unknown + basic_os=morphos + ;; + moxiebox) + basic_machine=moxie-unknown + basic_os=moxiebox + ;; + msdos) + basic_machine=i386-pc + basic_os=msdos + ;; + msys) + basic_machine=i686-pc + basic_os=msys + ;; + mvs) + basic_machine=i370-ibm + basic_os=mvs + ;; + nacl) + basic_machine=le32-unknown + basic_os=nacl + ;; + ncr3000) + basic_machine=i486-ncr + basic_os=sysv4 + ;; + netbsd386) + basic_machine=i386-pc + basic_os=netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + basic_os=linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + basic_os=newsos + ;; + news1000) + basic_machine=m68030-sony + basic_os=newsos + ;; + necv70) + basic_machine=v70-nec + basic_os=sysv + ;; + nh3000) + basic_machine=m68k-harris + basic_os=cxux + ;; + nh[45]000) + basic_machine=m88k-harris + basic_os=cxux + ;; + nindy960) + basic_machine=i960-intel + basic_os=nindy + ;; + mon960) + basic_machine=i960-intel + basic_os=mon960 + ;; + nonstopux) + basic_machine=mips-compaq + basic_os=nonstopux + ;; + os400) + basic_machine=powerpc-ibm + basic_os=os400 + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + basic_os=ose + ;; + os68k) + basic_machine=m68k-none + basic_os=os68k + ;; + paragon) + basic_machine=i860-intel + basic_os=osf + ;; + parisc) + basic_machine=hppa-unknown + basic_os=linux + ;; + psp) + basic_machine=mipsallegrexel-sony + basic_os=psp + ;; + pw32) + basic_machine=i586-unknown + basic_os=pw32 + ;; + rdos | rdos64) + basic_machine=x86_64-pc + basic_os=rdos + ;; + rdos32) + basic_machine=i386-pc + basic_os=rdos + ;; + rom68k) + basic_machine=m68k-rom68k + basic_os=coff + ;; + sa29200) + basic_machine=a29k-amd + basic_os=udi + ;; + sei) + basic_machine=mips-sei + basic_os=seiux + ;; + sequent) + basic_machine=i386-sequent + basic_os= + ;; + sps7) + basic_machine=m68k-bull + basic_os=sysv2 + ;; + st2000) + basic_machine=m68k-tandem + basic_os= + ;; + stratus) + basic_machine=i860-stratus + basic_os=sysv4 + ;; + sun2) + basic_machine=m68000-sun + basic_os= + ;; + sun2os3) + basic_machine=m68000-sun + basic_os=sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + basic_os=sunos4 + ;; + sun3) + basic_machine=m68k-sun + basic_os= + ;; + sun3os3) + basic_machine=m68k-sun + basic_os=sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + basic_os=sunos4 + ;; + sun4) + basic_machine=sparc-sun + basic_os= + ;; + sun4os3) + basic_machine=sparc-sun + basic_os=sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + basic_os=sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + basic_os=solaris2 + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + basic_os= + ;; + sv1) + basic_machine=sv1-cray + basic_os=unicos + ;; + symmetry) + basic_machine=i386-sequent + basic_os=dynix + ;; + t3e) + basic_machine=alphaev5-cray + basic_os=unicos + ;; + t90) + basic_machine=t90-cray + basic_os=unicos + ;; + toad1) + basic_machine=pdp10-xkl + basic_os=tops20 + ;; + tpf) + basic_machine=s390x-ibm + basic_os=tpf + ;; + udi29k) + basic_machine=a29k-amd + basic_os=udi + ;; + ultra3) + basic_machine=a29k-nyu + basic_os=sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + basic_os=none + ;; + vaxv) + basic_machine=vax-dec + basic_os=sysv + ;; + vms) + basic_machine=vax-dec + basic_os=vms + ;; + vsta) + basic_machine=i386-pc + basic_os=vsta + ;; + vxworks960) + basic_machine=i960-wrs + basic_os=vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + basic_os=vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + basic_os=vxworks + ;; + xbox) + basic_machine=i686-pc + basic_os=mingw32 + ;; + ymp) + basic_machine=ymp-cray + basic_os=unicos + ;; + *) + basic_machine=$1 + basic_os= + ;; + esac + ;; +esac + +# Decode 1-component or ad-hoc basic machines +case $basic_machine in + # Here we handle the default manufacturer of certain CPU types. It is in + # some cases the only manufacturer, in others, it is the most popular. + w89k) + cpu=hppa1.1 + vendor=winbond + ;; + op50n) + cpu=hppa1.1 + vendor=oki + ;; + op60c) + cpu=hppa1.1 + vendor=oki + ;; + ibm*) + cpu=i370 + vendor=ibm + ;; + orion105) + cpu=clipper + vendor=highlevel + ;; + mac | mpw | mac-mpw) + cpu=m68k + vendor=apple + ;; + pmac | pmac-mpw) + cpu=powerpc + vendor=apple + ;; + + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + cpu=m68000 + vendor=att + ;; + 3b*) + cpu=we32k + vendor=att + ;; + bluegene*) + cpu=powerpc + vendor=ibm + basic_os=cnk + ;; + decsystem10* | dec10*) + cpu=pdp10 + vendor=dec + basic_os=tops10 + ;; + decsystem20* | dec20*) + cpu=pdp10 + vendor=dec + basic_os=tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + cpu=m68k + vendor=motorola + ;; + dpx2*) + cpu=m68k + vendor=bull + basic_os=sysv3 + ;; + encore | umax | mmax) + cpu=ns32k + vendor=encore + ;; + elxsi) + cpu=elxsi + vendor=elxsi + basic_os=${basic_os:-bsd} + ;; + fx2800) + cpu=i860 + vendor=alliant + ;; + genix) + cpu=ns32k + vendor=ns + ;; + h3050r* | hiux*) + cpu=hppa1.1 + vendor=hitachi + basic_os=hiuxwe2 + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + cpu=hppa1.0 + vendor=hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + cpu=m68000 + vendor=hp + ;; + hp9k3[2-9][0-9]) + cpu=m68k + vendor=hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + cpu=hppa1.0 + vendor=hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + cpu=hppa1.1 + vendor=hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + cpu=hppa1.1 + vendor=hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + cpu=hppa1.1 + vendor=hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + cpu=hppa1.1 + vendor=hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + cpu=hppa1.0 + vendor=hp + ;; + i*86v32) + cpu=`echo "$1" | sed -e 's/86.*/86/'` + vendor=pc + basic_os=sysv32 + ;; + i*86v4*) + cpu=`echo "$1" | sed -e 's/86.*/86/'` + vendor=pc + basic_os=sysv4 + ;; + i*86v) + cpu=`echo "$1" | sed -e 's/86.*/86/'` + vendor=pc + basic_os=sysv + ;; + i*86sol2) + cpu=`echo "$1" | sed -e 's/86.*/86/'` + vendor=pc + basic_os=solaris2 + ;; + j90 | j90-cray) + cpu=j90 + vendor=cray + basic_os=${basic_os:-unicos} + ;; + iris | iris4d) + cpu=mips + vendor=sgi + case $basic_os in + irix*) + ;; + *) + basic_os=irix4 + ;; + esac + ;; + miniframe) + cpu=m68000 + vendor=convergent + ;; + *mint | mint[0-9]* | *MiNT | *MiNT[0-9]*) + cpu=m68k + vendor=atari + basic_os=mint + ;; + news-3600 | risc-news) + cpu=mips + vendor=sony + basic_os=newsos + ;; + next | m*-next) + cpu=m68k + vendor=next + case $basic_os in + openstep*) + ;; + nextstep*) + ;; + ns2*) + basic_os=nextstep2 + ;; + *) + basic_os=nextstep3 + ;; + esac + ;; + np1) + cpu=np1 + vendor=gould + ;; + op50n-* | op60c-*) + cpu=hppa1.1 + vendor=oki + basic_os=proelf + ;; + pa-hitachi) + cpu=hppa1.1 + vendor=hitachi + basic_os=hiuxwe2 + ;; + pbd) + cpu=sparc + vendor=tti + ;; + pbb) + cpu=m68k + vendor=tti + ;; + pc532) + cpu=ns32k + vendor=pc532 + ;; + pn) + cpu=pn + vendor=gould + ;; + power) + cpu=power + vendor=ibm + ;; + ps2) + cpu=i386 + vendor=ibm + ;; + rm[46]00) + cpu=mips + vendor=siemens + ;; + rtpc | rtpc-*) + cpu=romp + vendor=ibm + ;; + sde) + cpu=mipsisa32 + vendor=sde + basic_os=${basic_os:-elf} + ;; + simso-wrs) + cpu=sparclite + vendor=wrs + basic_os=vxworks + ;; + tower | tower-32) + cpu=m68k + vendor=ncr + ;; + vpp*|vx|vx-*) + cpu=f301 + vendor=fujitsu + ;; + w65) + cpu=w65 + vendor=wdc + ;; + w89k-*) + cpu=hppa1.1 + vendor=winbond + basic_os=proelf + ;; + none) + cpu=none + vendor=none + ;; + leon|leon[3-9]) + cpu=sparc + vendor=$basic_machine + ;; + leon-*|leon[3-9]-*) + cpu=sparc + vendor=`echo "$basic_machine" | sed 's/-.*//'` + ;; + + *-*) + # shellcheck disable=SC2162 + saved_IFS=$IFS + IFS="-" read cpu vendor <&2 + exit 1 + ;; + esac + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $vendor in + digital*) + vendor=dec + ;; + commodore*) + vendor=cbm + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if test x$basic_os != x +then + +# First recognize some ad-hoc cases, or perhaps split kernel-os, or else just +# set os. +case $basic_os in + gnu/linux*) + kernel=linux + os=`echo "$basic_os" | sed -e 's|gnu/linux|gnu|'` + ;; + os2-emx) + kernel=os2 + os=`echo "$basic_os" | sed -e 's|os2-emx|emx|'` + ;; + nto-qnx*) + kernel=nto + os=`echo "$basic_os" | sed -e 's|nto-qnx|qnx|'` + ;; + *-*) + # shellcheck disable=SC2162 + saved_IFS=$IFS + IFS="-" read kernel os <&2 + exit 1 + ;; +esac + +# As a final step for OS-related things, validate the OS-kernel combination +# (given a valid OS), if there is a kernel. +case $kernel-$os in + linux-gnu* | linux-dietlibc* | linux-android* | linux-newlib* \ + | linux-musl* | linux-relibc* | linux-uclibc* ) + ;; + uclinux-uclibc* ) + ;; + -dietlibc* | -newlib* | -musl* | -relibc* | -uclibc* ) + # These are just libc implementations, not actual OSes, and thus + # require a kernel. + echo "Invalid configuration \`$1': libc \`$os' needs explicit kernel." 1>&2 + exit 1 + ;; + kfreebsd*-gnu* | kopensolaris*-gnu*) + ;; + vxworks-simlinux | vxworks-simwindows | vxworks-spe) + ;; + nto-qnx*) + ;; + os2-emx) + ;; + *-eabi* | *-gnueabi*) + ;; + -*) + # Blank kernel with real OS is always fine. + ;; + *-*) + echo "Invalid configuration \`$1': Kernel \`$kernel' not known to work with OS \`$os'." 1>&2 + exit 1 + ;; +esac + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +case $vendor in + unknown) + case $cpu-$os in + *-riscix*) + vendor=acorn + ;; + *-sunos*) + vendor=sun + ;; + *-cnk* | *-aix*) + vendor=ibm + ;; + *-beos*) + vendor=be + ;; + *-hpux*) + vendor=hp + ;; + *-mpeix*) + vendor=hp + ;; + *-hiux*) + vendor=hitachi + ;; + *-unos*) + vendor=crds + ;; + *-dgux*) + vendor=dg + ;; + *-luna*) + vendor=omron + ;; + *-genix*) + vendor=ns + ;; + *-clix*) + vendor=intergraph + ;; + *-mvs* | *-opened*) + vendor=ibm + ;; + *-os400*) + vendor=ibm + ;; + s390-* | s390x-*) + vendor=ibm + ;; + *-ptx*) + vendor=sequent + ;; + *-tpf*) + vendor=ibm + ;; + *-vxsim* | *-vxworks* | *-windiss*) + vendor=wrs + ;; + *-aux*) + vendor=apple + ;; + *-hms*) + vendor=hitachi + ;; + *-mpw* | *-macos*) + vendor=apple + ;; + *-*mint | *-mint[0-9]* | *-*MiNT | *-MiNT[0-9]*) + vendor=atari + ;; + *-vos*) + vendor=stratus + ;; + esac + ;; +esac + +echo "$cpu-$vendor-${kernel:+$kernel-}$os" +exit + +# Local variables: +# eval: (add-hook 'before-save-hook 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/external/mit/isl/dist/interface/configure b/external/mit/isl/dist/interface/configure new file mode 100755 index 000000000000..31eb669132d7 --- /dev/null +++ b/external/mit/isl/dist/interface/configure @@ -0,0 +1,23323 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.71 for isl-interface 0. +# +# Report bugs to . +# +# +# Copyright (C) 1992-1996, 1998-2017, 2020-2021 Free Software Foundation, +# Inc. +# +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +as_nop=: +if test ${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1 +then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else $as_nop + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + + +# Reset variables that may have inherited troublesome values from +# the environment. + +# IFS needs to be set, to space, tab, and newline, in precisely that order. +# (If _AS_PATH_WALK were called with IFS unset, it would have the +# side effect of setting IFS to empty, thus disabling word splitting.) +# Quoting is to prevent editors from complaining about space-tab. +as_nl=' +' +export as_nl +IFS=" "" $as_nl" + +PS1='$ ' +PS2='> ' +PS4='+ ' + +# Ensure predictable behavior from utilities with locale-dependent output. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# We cannot yet rely on "unset" to work, but we need these variables +# to be unset--not just set to an empty or harmless value--now, to +# avoid bugs in old shells (e.g. pre-3.0 UWIN ksh). This construct +# also avoids known problems related to "unset" and subshell syntax +# in other old shells (e.g. bash 2.01 and pdksh 5.2.14). +for as_var in BASH_ENV ENV MAIL MAILPATH CDPATH +do eval test \${$as_var+y} \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done + +# Ensure that fds 0, 1, and 2 are open. +if (exec 3>&0) 2>/dev/null; then :; else exec 0&1) 2>/dev/null; then :; else exec 1>/dev/null; fi +if (exec 3>&2) ; then :; else exec 2>/dev/null; fi + +# The user is always right. +if ${PATH_SEPARATOR+false} :; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + test -r "$as_dir$0" && as_myself=$as_dir$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + printf "%s\n" "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + + +# Use a proper internal environment variable to ensure we don't fall + # into an infinite loop, continuously re-executing ourselves. + if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then + _as_can_reexec=no; export _as_can_reexec; + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +printf "%s\n" "$0: could not re-execute with $CONFIG_SHELL" >&2 +exit 255 + fi + # We don't want this to propagate to other subprocesses. + { _as_can_reexec=; unset _as_can_reexec;} +if test "x$CONFIG_SHELL" = x; then + as_bourne_compatible="as_nop=: +if test \${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1 +then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else \$as_nop + case \`(set -o) 2>/dev/null\` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi +" + as_required="as_fn_return () { (exit \$1); } +as_fn_success () { as_fn_return 0; } +as_fn_failure () { as_fn_return 1; } +as_fn_ret_success () { return 0; } +as_fn_ret_failure () { return 1; } + +exitcode=0 +as_fn_success || { exitcode=1; echo as_fn_success failed.; } +as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } +as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } +as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } +if ( set x; as_fn_ret_success y && test x = \"\$1\" ) +then : + +else \$as_nop + exitcode=1; echo positional parameters were not saved. +fi +test x\$exitcode = x0 || exit 1 +blah=\$(echo \$(echo blah)) +test x\"\$blah\" = xblah || exit 1 +test -x / || exit 1" + as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO + as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO + eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && + test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 +test \$(( 1 + 1 )) = 2 || exit 1 + + test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || ( + ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' + ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO + ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO + PATH=/empty FPATH=/empty; export PATH FPATH + test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\ + || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1" + if (eval "$as_required") 2>/dev/null +then : + as_have_required=yes +else $as_nop + as_have_required=no +fi + if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null +then : + +else $as_nop + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_found=false +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + as_found=: + case $as_dir in #( + /*) + for as_base in sh bash ksh sh5; do + # Try only shells that exist, to save several forks. + as_shell=$as_dir$as_base + if { test -f "$as_shell" || test -f "$as_shell.exe"; } && + as_run=a "$as_shell" -c "$as_bourne_compatible""$as_required" 2>/dev/null +then : + CONFIG_SHELL=$as_shell as_have_required=yes + if as_run=a "$as_shell" -c "$as_bourne_compatible""$as_suggested" 2>/dev/null +then : + break 2 +fi +fi + done;; + esac + as_found=false +done +IFS=$as_save_IFS +if $as_found +then : + +else $as_nop + if { test -f "$SHELL" || test -f "$SHELL.exe"; } && + as_run=a "$SHELL" -c "$as_bourne_compatible""$as_required" 2>/dev/null +then : + CONFIG_SHELL=$SHELL as_have_required=yes +fi +fi + + + if test "x$CONFIG_SHELL" != x +then : + export CONFIG_SHELL + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +printf "%s\n" "$0: could not re-execute with $CONFIG_SHELL" >&2 +exit 255 +fi + + if test x$as_have_required = xno +then : + printf "%s\n" "$0: This script requires a shell more modern than all" + printf "%s\n" "$0: the shells that I found on your system." + if test ${ZSH_VERSION+y} ; then + printf "%s\n" "$0: In particular, zsh $ZSH_VERSION has bugs and should" + printf "%s\n" "$0: be upgraded to zsh 4.3.4 or later." + else + printf "%s\n" "$0: Please tell bug-autoconf@gnu.org and +$0: isl-development@googlegroups.com about your system, +$0: including any error possibly output before this +$0: message. Then install a modern shell, or manually run +$0: the script under such a shell if you do have one." + fi + exit 1 +fi +fi +fi +SHELL=${CONFIG_SHELL-/bin/sh} +export SHELL +# Unset more variables known to interfere with behavior of common tools. +CLICOLOR_FORCE= GREP_OPTIONS= +unset CLICOLOR_FORCE GREP_OPTIONS + +## --------------------- ## +## M4sh Shell Functions. ## +## --------------------- ## +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset + + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit +# as_fn_nop +# --------- +# Do nothing but, unlike ":", preserve the value of $?. +as_fn_nop () +{ + return $? +} +as_nop=as_fn_nop + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`printf "%s\n" "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +printf "%s\n" X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null +then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else $as_nop + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null +then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else $as_nop + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + +# as_fn_nop +# --------- +# Do nothing but, unlike ":", preserve the value of $?. +as_fn_nop () +{ + return $? +} +as_nop=as_fn_nop + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + printf "%s\n" "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +printf "%s\n" X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + + + as_lineno_1=$LINENO as_lineno_1a=$LINENO + as_lineno_2=$LINENO as_lineno_2a=$LINENO + eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && + test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { + # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { printf "%s\n" "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } + + # If we had to re-execute with $CONFIG_SHELL, we're ensured to have + # already done that, so ensure we don't try to do so again and fall + # in an infinite loop. This has already happened in practice. + _as_can_reexec=no; export _as_can_reexec + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + + +# Determine whether it's possible to make 'echo' print without a newline. +# These variables are no longer used directly by Autoconf, but are AC_SUBSTed +# for compatibility with existing Makefiles. +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +# For backward compatibility with old third-party macros, we provide +# the shell variables $as_echo and $as_echo_n. New code should use +# AS_ECHO(["message"]) and AS_ECHO_N(["message"]), respectively. +as_echo='printf %s\n' +as_echo_n='printf %s' + + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -pR'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -pR' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -pR' + fi +else + as_ln_s='cp -pR' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +as_test_x='test -x' +as_executable_p=as_fn_executable_p + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + +SHELL=${CONFIG_SHELL-/bin/sh} + + +test -n "$DJDIR" || exec 7<&0 &1 + +# Name of the host. +# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_clean_files= +ac_config_libobj_dir=. +LIBOBJS= +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= + +# Identity of this package. +PACKAGE_NAME='isl-interface' +PACKAGE_TARNAME='isl-interface' +PACKAGE_VERSION='0' +PACKAGE_STRING='isl-interface 0' +PACKAGE_BUGREPORT='isl-development@googlegroups.com' +PACKAGE_URL='' + +# Factoring default headers for most tests. +ac_includes_default="\ +#include +#ifdef HAVE_STDIO_H +# include +#endif +#ifdef HAVE_STDLIB_H +# include +#endif +#ifdef HAVE_STRING_H +# include +#endif +#ifdef HAVE_INTTYPES_H +# include +#endif +#ifdef HAVE_STDINT_H +# include +#endif +#ifdef HAVE_STRINGS_H +# include +#endif +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_SYS_STAT_H +# include +#endif +#ifdef HAVE_UNISTD_H +# include +#endif" + +ac_header_c_list= +ac_subst_vars='am__EXEEXT_FALSE +am__EXEEXT_TRUE +LTLIBOBJS +LIBOBJS +CONFIG_STATUS_DEPENDENCIES +XCODE_SELECT +LLVM_CONFIG +CLANG_LIBS +CLANG_RFLAG +CLANG_LDFLAGS +CLANG_CXXFLAGS +LT_SYS_LIBRARY_PATH +OTOOL64 +OTOOL +LIPO +NMEDIT +DSYMUTIL +MANIFEST_TOOL +RANLIB +ac_ct_AR +AR +DLLTOOL +OBJDUMP +LN_S +NM +ac_ct_DUMPBIN +DUMPBIN +LD +FGREP +EGREP +SED +LIBTOOL +HAVE_CXX11 +GREP +CXXCPPFLAGS_FOR_BUILD +CXXFLAGS_FOR_BUILD +CXXCPP_FOR_BUILD +ac_ct_CXX_FOR_BUILD +CXX_FOR_BUILD +host_os +host_vendor +host_cpu +host +CXXCPP +LDFLAGS_FOR_BUILD +CPPFLAGS_FOR_BUILD +CFLAGS_FOR_BUILD +CCDEPMODE_FOR_BUILD +BUILD_OBJEXT +BUILD_EXEEXT +CPP_FOR_BUILD +ac_ct_CC_FOR_BUILD +CC_FOR_BUILD +build_os +build_vendor +build_cpu +build +CPP +am__fastdepCC_FALSE +am__fastdepCC_TRUE +CCDEPMODE +ac_ct_CC +CFLAGS +CC +am__fastdepCXX_FALSE +am__fastdepCXX_TRUE +CXXDEPMODE +am__nodep +AMDEPBACKSLASH +AMDEP_FALSE +AMDEP_TRUE +am__include +DEPDIR +OBJEXT +EXEEXT +ac_ct_CXX +CPPFLAGS +LDFLAGS +CXXFLAGS +CXX +AM_BACKSLASH +AM_DEFAULT_VERBOSITY +AM_DEFAULT_V +AM_V +CSCOPE +ETAGS +CTAGS +am__untar +am__tar +AMTAR +am__leading_dot +SET_MAKE +AWK +mkdir_p +MKDIR_P +INSTALL_STRIP_PROGRAM +STRIP +install_sh +MAKEINFO +AUTOHEADER +AUTOMAKE +AUTOCONF +ACLOCAL +VERSION +PACKAGE +CYGPATH_W +am__isrc +INSTALL_DATA +INSTALL_SCRIPT +INSTALL_PROGRAM +target_alias +host_alias +build_alias +LIBS +ECHO_T +ECHO_N +ECHO_C +DEFS +mandir +localedir +libdir +psdir +pdfdir +dvidir +htmldir +infodir +docdir +oldincludedir +includedir +runstatedir +localstatedir +sharedstatedir +sysconfdir +datadir +datarootdir +libexecdir +sbindir +bindir +program_transform_name +prefix +exec_prefix +PACKAGE_URL +PACKAGE_BUGREPORT +PACKAGE_STRING +PACKAGE_VERSION +PACKAGE_TARNAME +PACKAGE_NAME +PATH_SEPARATOR +SHELL +am__quote' +ac_subst_files='' +ac_user_opts=' +enable_option_checking +enable_silent_rules +enable_dependency_tracking +enable_shared +enable_static +with_pic +enable_fast_install +with_aix_soname +with_gnu_ld +with_sysroot +enable_libtool_lock +' + ac_precious_vars='build_alias +host_alias +target_alias +CXX +CXXFLAGS +LDFLAGS +LIBS +CPPFLAGS +CCC +CC +CFLAGS +CPP +CXXCPP +LT_SYS_LIBRARY_PATH' + + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +ac_unrecognized_opts= +ac_unrecognized_sep= +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +# (The list follows the same order as the GNU Coding Standards.) +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datarootdir='${prefix}/share' +datadir='${datarootdir}' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +runstatedir='${localstatedir}/run' +includedir='${prefix}/include' +oldincludedir='/usr/include' +docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' +infodir='${datarootdir}/info' +htmldir='${docdir}' +dvidir='${docdir}' +pdfdir='${docdir}' +psdir='${docdir}' +libdir='${exec_prefix}/lib' +localedir='${datarootdir}/locale' +mandir='${datarootdir}/man' + +ac_prev= +ac_dashdash= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval $ac_prev=\$ac_option + ac_prev= + continue + fi + + case $ac_option in + *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *=) ac_optarg= ;; + *) ac_optarg=yes ;; + esac + + case $ac_dashdash$ac_option in + --) + ac_dashdash=yes ;; + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=*) + datadir=$ac_optarg ;; + + -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ + | --dataroo | --dataro | --datar) + ac_prev=datarootdir ;; + -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ + | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) + datarootdir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: \`$ac_useropt'" + ac_useropt_orig=$ac_useropt + ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=no ;; + + -docdir | --docdir | --docdi | --doc | --do) + ac_prev=docdir ;; + -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) + docdir=$ac_optarg ;; + + -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) + ac_prev=dvidir ;; + -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) + dvidir=$ac_optarg ;; + + -enable-* | --enable-*) + ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: \`$ac_useropt'" + ac_useropt_orig=$ac_useropt + ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=\$ac_optarg ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) + ac_prev=htmldir ;; + -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ + | --ht=*) + htmldir=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localedir | --localedir | --localedi | --localed | --locale) + ac_prev=localedir ;; + -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) + localedir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst | --locals) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) + ac_prev=pdfdir ;; + -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) + pdfdir=$ac_optarg ;; + + -psdir | --psdir | --psdi | --psd | --ps) + ac_prev=psdir ;; + -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) + psdir=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -runstatedir | --runstatedir | --runstatedi | --runstated \ + | --runstate | --runstat | --runsta | --runst | --runs \ + | --run | --ru | --r) + ac_prev=runstatedir ;; + -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ + | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ + | --run=* | --ru=* | --r=*) + runstatedir=$ac_optarg ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: \`$ac_useropt'" + ac_useropt_orig=$ac_useropt + ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=\$ac_optarg ;; + + -without-* | --without-*) + ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: \`$ac_useropt'" + ac_useropt_orig=$ac_useropt + ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=no ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) as_fn_error $? "unrecognized option: \`$ac_option' +Try \`$0 --help' for more information" + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + case $ac_envvar in #( + '' | [0-9]* | *[!_$as_cr_alnum]* ) + as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; + esac + eval $ac_envvar=\$ac_optarg + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + printf "%s\n" "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + printf "%s\n" "$as_me: WARNING: invalid host type: $ac_option" >&2 + : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + as_fn_error $? "missing argument to $ac_option" +fi + +if test -n "$ac_unrecognized_opts"; then + case $enable_option_checking in + no) ;; + fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; + *) printf "%s\n" "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; + esac +fi + +# Check all directory arguments for consistency. +for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ + datadir sysconfdir sharedstatedir localstatedir includedir \ + oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ + libdir localedir mandir runstatedir +do + eval ac_val=\$$ac_var + # Remove trailing slashes. + case $ac_val in + */ ) + ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` + eval $ac_var=\$ac_val;; + esac + # Be sure to have absolute directory names. + case $ac_val in + [\\/$]* | ?:[\\/]* ) continue;; + NONE | '' ) case $ac_var in *prefix ) continue;; esac;; + esac + as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +ac_pwd=`pwd` && test -n "$ac_pwd" && +ac_ls_di=`ls -di .` && +ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || + as_fn_error $? "working directory cannot be determined" +test "X$ac_ls_di" = "X$ac_pwd_ls_di" || + as_fn_error $? "pwd does not report name of working directory" + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then the parent directory. + ac_confdir=`$as_dirname -- "$as_myself" || +$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_myself" : 'X\(//\)[^/]' \| \ + X"$as_myself" : 'X\(//\)$' \| \ + X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || +printf "%s\n" X"$as_myself" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r "$srcdir/$ac_unique_file"; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r "$srcdir/$ac_unique_file"; then + test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." + as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" +fi +ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" +ac_abs_confdir=`( + cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" + pwd)` +# When building in place, set srcdir=. +if test "$ac_abs_confdir" = "$ac_pwd"; then + srcdir=. +fi +# Remove unnecessary trailing slashes from srcdir. +# Double slashes in file names in object file debugging info +# mess up M-x gdb in Emacs. +case $srcdir in +*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; +esac +for ac_var in $ac_precious_vars; do + eval ac_env_${ac_var}_set=\${${ac_var}+set} + eval ac_env_${ac_var}_value=\$${ac_var} + eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} + eval ac_cv_env_${ac_var}_value=\$${ac_var} +done + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures isl-interface 0 to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking ...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] + --datadir=DIR read-only architecture-independent data [DATAROOTDIR] + --infodir=DIR info documentation [DATAROOTDIR/info] + --localedir=DIR locale-dependent data [DATAROOTDIR/locale] + --mandir=DIR man documentation [DATAROOTDIR/man] + --docdir=DIR documentation root [DATAROOTDIR/doc/isl-interface] + --htmldir=DIR html documentation [DOCDIR] + --dvidir=DIR dvi documentation [DOCDIR] + --pdfdir=DIR pdf documentation [DOCDIR] + --psdir=DIR ps documentation [DOCDIR] +_ACEOF + + cat <<\_ACEOF + +Program names: + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM run sed PROGRAM on installed program names + +System types: + --build=BUILD configure for building on BUILD [guessed] + --host=HOST cross-compile to build programs to run on HOST [BUILD] +_ACEOF +fi + +if test -n "$ac_init_help"; then + case $ac_init_help in + short | recursive ) echo "Configuration of isl-interface 0:";; + esac + cat <<\_ACEOF + +Optional Features: + --disable-option-checking ignore unrecognized --enable/--with options + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --enable-silent-rules less verbose build output (undo: "make V=1") + --disable-silent-rules verbose build output (undo: "make V=0") + --enable-dependency-tracking + do not reject slow dependency extractors + --disable-dependency-tracking + speeds up one-time build + --enable-shared[=PKGS] build shared libraries [default=no] + --enable-static[=PKGS] build static libraries [default=yes] + --enable-fast-install[=PKGS] + optimize for fast installation [default=yes] + --disable-libtool-lock avoid locking (might break parallel builds) + +Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --with-pic[=PKGS] try to use only PIC/non-PIC objects [default=use + both] + --with-aix-soname=aix|svr4|both + shared library versioning (aka "SONAME") variant to + provide on AIX, [default=aix]. + --with-gnu-ld assume the C compiler uses GNU ld [default=no] + --with-sysroot[=DIR] Search for dependent libraries within DIR (or the + compiler's sysroot if not specified). + +Some influential environment variables: + CXX C++ compiler command + CXXFLAGS C++ compiler flags + LDFLAGS linker flags, e.g. -L if you have libraries in a + nonstandard directory + LIBS libraries to pass to the linker, e.g. -l + CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if + you have headers in a nonstandard directory + CC C compiler command + CFLAGS C compiler flags + CPP C preprocessor + CXXCPP C++ preprocessor + LT_SYS_LIBRARY_PATH + User-defined run-time library search path. + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +Report bugs to . +_ACEOF +ac_status=$? +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d "$ac_dir" || + { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || + continue + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`printf "%s\n" "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`printf "%s\n" "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + cd "$ac_dir" || { ac_status=$?; continue; } + # Check for configure.gnu first; this name is used for a wrapper for + # Metaconfig's "Configure" on case-insensitive file systems. + if test -f "$ac_srcdir/configure.gnu"; then + echo && + $SHELL "$ac_srcdir/configure.gnu" --help=recursive + elif test -f "$ac_srcdir/configure"; then + echo && + $SHELL "$ac_srcdir/configure" --help=recursive + else + printf "%s\n" "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi || ac_status=$? + cd "$ac_pwd" || { ac_status=$?; break; } + done +fi + +test -n "$ac_init_help" && exit $ac_status +if $ac_init_version; then + cat <<\_ACEOF +isl-interface configure 0 +generated by GNU Autoconf 2.71 + +Copyright (C) 2021 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit +fi + +## ------------------------ ## +## Autoconf initialization. ## +## ------------------------ ## + +# ac_fn_cxx_try_compile LINENO +# ---------------------------- +# Try to compile conftest.$ac_ext, and return whether this succeeded. +ac_fn_cxx_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest.beam + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +printf "%s\n" "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext +then : + ac_retval=0 +else $as_nop + printf "%s\n" "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_cxx_try_compile + +# ac_fn_c_try_compile LINENO +# -------------------------- +# Try to compile conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest.beam + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +printf "%s\n" "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext +then : + ac_retval=0 +else $as_nop + printf "%s\n" "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_compile + +# ac_fn_c_try_cpp LINENO +# ---------------------- +# Try to preprocess conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_cpp () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +printf "%s\n" "$ac_try_echo"; } >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } > conftest.i && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + } +then : + ac_retval=0 +else $as_nop + printf "%s\n" "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_cpp + +# ac_fn_cxx_try_cpp LINENO +# ------------------------ +# Try to preprocess conftest.$ac_ext, and return whether this succeeded. +ac_fn_cxx_try_cpp () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +printf "%s\n" "$ac_try_echo"; } >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } > conftest.i && { + test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || + test ! -s conftest.err + } +then : + ac_retval=0 +else $as_nop + printf "%s\n" "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_cxx_try_cpp + +# ac_fn_c_try_link LINENO +# ----------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_link () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest.beam conftest$ac_exeext + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +printf "%s\n" "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + test -x conftest$ac_exeext + } +then : + ac_retval=0 +else $as_nop + printf "%s\n" "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information + # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would + # interfere with the next link command; also delete a directory that is + # left behind by Apple's compiler. We do this before executing the actions. + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_link + +# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists and can be compiled using the include files in +# INCLUDES, setting the cache variable VAR accordingly. +ac_fn_c_check_header_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +printf %s "checking for $2... " >&6; } +if eval test \${$3+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + eval "$3=yes" +else $as_nop + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +fi +eval ac_res=\$$3 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_header_compile + +# ac_fn_c_check_func LINENO FUNC VAR +# ---------------------------------- +# Tests whether FUNC exists, setting the cache variable VAR accordingly +ac_fn_c_check_func () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +printf %s "checking for $2... " >&6; } +if eval test \${$3+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +/* Define $2 to an innocuous variant, in case declares $2. + For example, HP-UX 11i declares gettimeofday. */ +#define $2 innocuous_$2 + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $2 (); below. */ + +#include +#undef $2 + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $2 (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$2 || defined __stub___$2 +choke me +#endif + +int +main (void) +{ +return $2 (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + eval "$3=yes" +else $as_nop + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +fi +eval ac_res=\$$3 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_func + +# ac_fn_cxx_try_link LINENO +# ------------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. +ac_fn_cxx_try_link () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest.beam conftest$ac_exeext + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +printf "%s\n" "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + test -x conftest$ac_exeext + } +then : + ac_retval=0 +else $as_nop + printf "%s\n" "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information + # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would + # interfere with the next link command; also delete a directory that is + # left behind by Apple's compiler. We do this before executing the actions. + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_cxx_try_link + +# ac_fn_cxx_check_header_compile LINENO HEADER VAR INCLUDES +# --------------------------------------------------------- +# Tests whether HEADER exists and can be compiled using the include files in +# INCLUDES, setting the cache variable VAR accordingly. +ac_fn_cxx_check_header_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +printf %s "checking for $2... " >&6; } +if eval test \${$3+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_cxx_try_compile "$LINENO" +then : + eval "$3=yes" +else $as_nop + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +fi +eval ac_res=\$$3 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_cxx_check_header_compile +ac_configure_args_raw= +for ac_arg +do + case $ac_arg in + *\'*) + ac_arg=`printf "%s\n" "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + as_fn_append ac_configure_args_raw " '$ac_arg'" +done + +case $ac_configure_args_raw in + *$as_nl*) + ac_safe_unquote= ;; + *) + ac_unsafe_z='|&;<>()$`\\"*?[ '' ' # This string ends in space, tab. + ac_unsafe_a="$ac_unsafe_z#~" + ac_safe_unquote="s/ '\\([^$ac_unsafe_a][^$ac_unsafe_z]*\\)'/ \\1/g" + ac_configure_args_raw=` printf "%s\n" "$ac_configure_args_raw" | sed "$ac_safe_unquote"`;; +esac + +cat >config.log <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by isl-interface $as_me 0, which was +generated by GNU Autoconf 2.71. Invocation command line was + + $ $0$ac_configure_args_raw + +_ACEOF +exec 5>>config.log +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + printf "%s\n" "PATH: $as_dir" + done +IFS=$as_save_IFS + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *\'*) + ac_arg=`printf "%s\n" "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; + 2) + as_fn_append ac_configure_args1 " '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + as_fn_append ac_configure_args " '$ac_arg'" + ;; + esac + done +done +{ ac_configure_args0=; unset ac_configure_args0;} +{ ac_configure_args1=; unset ac_configure_args1;} + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Use '\'' to represent an apostrophe within the trap. +# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. +trap 'exit_status=$? + # Sanitize IFS. + IFS=" "" $as_nl" + # Save into config.log some information that might help in debugging. + { + echo + + printf "%s\n" "## ---------------- ## +## Cache variables. ## +## ---------------- ##" + echo + # The following way of writing the cache mishandles newlines in values, +( + for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +printf "%s\n" "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + (set) 2>&1 | + case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + sed -n \ + "s/'\''/'\''\\\\'\'''\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" + ;; #( + *) + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) + echo + + printf "%s\n" "## ----------------- ## +## Output variables. ## +## ----------------- ##" + echo + for ac_var in $ac_subst_vars + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`printf "%s\n" "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + printf "%s\n" "$ac_var='\''$ac_val'\''" + done | sort + echo + + if test -n "$ac_subst_files"; then + printf "%s\n" "## ------------------- ## +## File substitutions. ## +## ------------------- ##" + echo + for ac_var in $ac_subst_files + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`printf "%s\n" "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + printf "%s\n" "$ac_var='\''$ac_val'\''" + done | sort + echo + fi + + if test -s confdefs.h; then + printf "%s\n" "## ----------- ## +## confdefs.h. ## +## ----------- ##" + echo + cat confdefs.h + echo + fi + test "$ac_signal" != 0 && + printf "%s\n" "$as_me: caught signal $ac_signal" + printf "%s\n" "$as_me: exit $exit_status" + } >&5 + rm -f core *.core core.conftest.* && + rm -f -r conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status +' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -f -r conftest* confdefs.h + +printf "%s\n" "/* confdefs.h */" > confdefs.h + +# Predefined preprocessor variables. + +printf "%s\n" "#define PACKAGE_NAME \"$PACKAGE_NAME\"" >>confdefs.h + +printf "%s\n" "#define PACKAGE_TARNAME \"$PACKAGE_TARNAME\"" >>confdefs.h + +printf "%s\n" "#define PACKAGE_VERSION \"$PACKAGE_VERSION\"" >>confdefs.h + +printf "%s\n" "#define PACKAGE_STRING \"$PACKAGE_STRING\"" >>confdefs.h + +printf "%s\n" "#define PACKAGE_BUGREPORT \"$PACKAGE_BUGREPORT\"" >>confdefs.h + +printf "%s\n" "#define PACKAGE_URL \"$PACKAGE_URL\"" >>confdefs.h + + +# Let the site file select an alternate cache file if it wants to. +# Prefer an explicitly selected file to automatically selected ones. +if test -n "$CONFIG_SITE"; then + ac_site_files="$CONFIG_SITE" +elif test "x$prefix" != xNONE; then + ac_site_files="$prefix/share/config.site $prefix/etc/config.site" +else + ac_site_files="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" +fi + +for ac_site_file in $ac_site_files +do + case $ac_site_file in #( + */*) : + ;; #( + *) : + ac_site_file=./$ac_site_file ;; +esac + if test -f "$ac_site_file" && test -r "$ac_site_file"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 +printf "%s\n" "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" \ + || { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "failed to load site script $ac_site_file +See \`config.log' for more details" "$LINENO" 5; } + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special files + # actually), so we avoid doing that. DJGPP emulates it as a regular file. + if test /dev/null != "$cache_file" && test -f "$cache_file"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 +printf "%s\n" "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . "$cache_file";; + *) . "./$cache_file";; + esac + fi +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 +printf "%s\n" "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Test code for whether the C++ compiler supports C++98 (global declarations) +ac_cxx_conftest_cxx98_globals=' +// Does the compiler advertise C++98 conformance? +#if !defined __cplusplus || __cplusplus < 199711L +# error "Compiler does not advertise C++98 conformance" +#endif + +// These inclusions are to reject old compilers that +// lack the unsuffixed header files. +#include +#include + +// and are *not* freestanding headers in C++98. +extern void assert (int); +namespace std { + extern int strcmp (const char *, const char *); +} + +// Namespaces, exceptions, and templates were all added after "C++ 2.0". +using std::exception; +using std::strcmp; + +namespace { + +void test_exception_syntax() +{ + try { + throw "test"; + } catch (const char *s) { + // Extra parentheses suppress a warning when building autoconf itself, + // due to lint rules shared with more typical C programs. + assert (!(strcmp) (s, "test")); + } +} + +template struct test_template +{ + T const val; + explicit test_template(T t) : val(t) {} + template T add(U u) { return static_cast(u) + val; } +}; + +} // anonymous namespace +' + +# Test code for whether the C++ compiler supports C++98 (body of main) +ac_cxx_conftest_cxx98_main=' + assert (argc); + assert (! argv[0]); +{ + test_exception_syntax (); + test_template tt (2.0); + assert (tt.add (4) == 6.0); + assert (true && !false); +} +' + +# Test code for whether the C++ compiler supports C++11 (global declarations) +ac_cxx_conftest_cxx11_globals=' +// Does the compiler advertise C++ 2011 conformance? +#if !defined __cplusplus || __cplusplus < 201103L +# error "Compiler does not advertise C++11 conformance" +#endif + +namespace cxx11test +{ + constexpr int get_val() { return 20; } + + struct testinit + { + int i; + double d; + }; + + class delegate + { + public: + delegate(int n) : n(n) {} + delegate(): delegate(2354) {} + + virtual int getval() { return this->n; }; + protected: + int n; + }; + + class overridden : public delegate + { + public: + overridden(int n): delegate(n) {} + virtual int getval() override final { return this->n * 2; } + }; + + class nocopy + { + public: + nocopy(int i): i(i) {} + nocopy() = default; + nocopy(const nocopy&) = delete; + nocopy & operator=(const nocopy&) = delete; + private: + int i; + }; + + // for testing lambda expressions + template Ret eval(Fn f, Ret v) + { + return f(v); + } + + // for testing variadic templates and trailing return types + template auto sum(V first) -> V + { + return first; + } + template auto sum(V first, Args... rest) -> V + { + return first + sum(rest...); + } +} +' + +# Test code for whether the C++ compiler supports C++11 (body of main) +ac_cxx_conftest_cxx11_main=' +{ + // Test auto and decltype + auto a1 = 6538; + auto a2 = 48573953.4; + auto a3 = "String literal"; + + int total = 0; + for (auto i = a3; *i; ++i) { total += *i; } + + decltype(a2) a4 = 34895.034; +} +{ + // Test constexpr + short sa[cxx11test::get_val()] = { 0 }; +} +{ + // Test initializer lists + cxx11test::testinit il = { 4323, 435234.23544 }; +} +{ + // Test range-based for + int array[] = {9, 7, 13, 15, 4, 18, 12, 10, 5, 3, + 14, 19, 17, 8, 6, 20, 16, 2, 11, 1}; + for (auto &x : array) { x += 23; } +} +{ + // Test lambda expressions + using cxx11test::eval; + assert (eval ([](int x) { return x*2; }, 21) == 42); + double d = 2.0; + assert (eval ([&](double x) { return d += x; }, 3.0) == 5.0); + assert (d == 5.0); + assert (eval ([=](double x) mutable { return d += x; }, 4.0) == 9.0); + assert (d == 5.0); +} +{ + // Test use of variadic templates + using cxx11test::sum; + auto a = sum(1); + auto b = sum(1, 2); + auto c = sum(1.0, 2.0, 3.0); +} +{ + // Test constructor delegation + cxx11test::delegate d1; + cxx11test::delegate d2(); + cxx11test::delegate d3(45); +} +{ + // Test override and final + cxx11test::overridden o1(55464); +} +{ + // Test nullptr + char *c = nullptr; +} +{ + // Test template brackets + test_template<::test_template> v(test_template(12)); +} +{ + // Unicode literals + char const *utf8 = u8"UTF-8 string \u2500"; + char16_t const *utf16 = u"UTF-8 string \u2500"; + char32_t const *utf32 = U"UTF-32 string \u2500"; +} +' + +# Test code for whether the C compiler supports C++11 (complete). +ac_cxx_conftest_cxx11_program="${ac_cxx_conftest_cxx98_globals} +${ac_cxx_conftest_cxx11_globals} + +int +main (int argc, char **argv) +{ + int ok = 0; + ${ac_cxx_conftest_cxx98_main} + ${ac_cxx_conftest_cxx11_main} + return ok; +} +" + +# Test code for whether the C compiler supports C++98 (complete). +ac_cxx_conftest_cxx98_program="${ac_cxx_conftest_cxx98_globals} +int +main (int argc, char **argv) +{ + int ok = 0; + ${ac_cxx_conftest_cxx98_main} + return ok; +} +" + +# Test code for whether the C compiler supports C89 (global declarations) +ac_c_conftest_c89_globals=' +/* Does the compiler advertise C89 conformance? + Do not test the value of __STDC__, because some compilers set it to 0 + while being otherwise adequately conformant. */ +#if !defined __STDC__ +# error "Compiler does not advertise C89 conformance" +#endif + +#include +#include +struct stat; +/* Most of the following tests are stolen from RCS 5.7 src/conf.sh. */ +struct buf { int x; }; +struct buf * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not \xHH hex character constants. + These do not provoke an error unfortunately, instead are silently treated + as an "x". The following induces an error, until -std is added to get + proper ANSI mode. Curiously \x00 != x always comes out true, for an + array size at least. It is necessary to write \x00 == 0 to get something + that is true only with -std. */ +int osf4_cc_array ['\''\x00'\'' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) '\''x'\'' +int xlc6_cc_array[FOO(a) == '\''x'\'' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, int *(*)(struct buf *, struct stat *, int), + int, int);' + +# Test code for whether the C compiler supports C89 (body of main). +ac_c_conftest_c89_main=' +ok |= (argc == 0 || f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]); +' + +# Test code for whether the C compiler supports C99 (global declarations) +ac_c_conftest_c99_globals=' +// Does the compiler advertise C99 conformance? +#if !defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L +# error "Compiler does not advertise C99 conformance" +#endif + +#include +extern int puts (const char *); +extern int printf (const char *, ...); +extern int dprintf (int, const char *, ...); +extern void *malloc (size_t); + +// Check varargs macros. These examples are taken from C99 6.10.3.5. +// dprintf is used instead of fprintf to avoid needing to declare +// FILE and stderr. +#define debug(...) dprintf (2, __VA_ARGS__) +#define showlist(...) puts (#__VA_ARGS__) +#define report(test,...) ((test) ? puts (#test) : printf (__VA_ARGS__)) +static void +test_varargs_macros (void) +{ + int x = 1234; + int y = 5678; + debug ("Flag"); + debug ("X = %d\n", x); + showlist (The first, second, and third items.); + report (x>y, "x is %d but y is %d", x, y); +} + +// Check long long types. +#define BIG64 18446744073709551615ull +#define BIG32 4294967295ul +#define BIG_OK (BIG64 / BIG32 == 4294967297ull && BIG64 % BIG32 == 0) +#if !BIG_OK + #error "your preprocessor is broken" +#endif +#if BIG_OK +#else + #error "your preprocessor is broken" +#endif +static long long int bignum = -9223372036854775807LL; +static unsigned long long int ubignum = BIG64; + +struct incomplete_array +{ + int datasize; + double data[]; +}; + +struct named_init { + int number; + const wchar_t *name; + double average; +}; + +typedef const char *ccp; + +static inline int +test_restrict (ccp restrict text) +{ + // See if C++-style comments work. + // Iterate through items via the restricted pointer. + // Also check for declarations in for loops. + for (unsigned int i = 0; *(text+i) != '\''\0'\''; ++i) + continue; + return 0; +} + +// Check varargs and va_copy. +static bool +test_varargs (const char *format, ...) +{ + va_list args; + va_start (args, format); + va_list args_copy; + va_copy (args_copy, args); + + const char *str = ""; + int number = 0; + float fnumber = 0; + + while (*format) + { + switch (*format++) + { + case '\''s'\'': // string + str = va_arg (args_copy, const char *); + break; + case '\''d'\'': // int + number = va_arg (args_copy, int); + break; + case '\''f'\'': // float + fnumber = va_arg (args_copy, double); + break; + default: + break; + } + } + va_end (args_copy); + va_end (args); + + return *str && number && fnumber; +} +' + +# Test code for whether the C compiler supports C99 (body of main). +ac_c_conftest_c99_main=' + // Check bool. + _Bool success = false; + success |= (argc != 0); + + // Check restrict. + if (test_restrict ("String literal") == 0) + success = true; + char *restrict newvar = "Another string"; + + // Check varargs. + success &= test_varargs ("s, d'\'' f .", "string", 65, 34.234); + test_varargs_macros (); + + // Check flexible array members. + struct incomplete_array *ia = + malloc (sizeof (struct incomplete_array) + (sizeof (double) * 10)); + ia->datasize = 10; + for (int i = 0; i < ia->datasize; ++i) + ia->data[i] = i * 1.234; + + // Check named initializers. + struct named_init ni = { + .number = 34, + .name = L"Test wide string", + .average = 543.34343, + }; + + ni.number = 58; + + int dynamic_array[ni.number]; + dynamic_array[0] = argv[0][0]; + dynamic_array[ni.number - 1] = 543; + + // work around unused variable warnings + ok |= (!success || bignum == 0LL || ubignum == 0uLL || newvar[0] == '\''x'\'' + || dynamic_array[ni.number - 1] != 543); +' + +# Test code for whether the C compiler supports C11 (global declarations) +ac_c_conftest_c11_globals=' +// Does the compiler advertise C11 conformance? +#if !defined __STDC_VERSION__ || __STDC_VERSION__ < 201112L +# error "Compiler does not advertise C11 conformance" +#endif + +// Check _Alignas. +char _Alignas (double) aligned_as_double; +char _Alignas (0) no_special_alignment; +extern char aligned_as_int; +char _Alignas (0) _Alignas (int) aligned_as_int; + +// Check _Alignof. +enum +{ + int_alignment = _Alignof (int), + int_array_alignment = _Alignof (int[100]), + char_alignment = _Alignof (char) +}; +_Static_assert (0 < -_Alignof (int), "_Alignof is signed"); + +// Check _Noreturn. +int _Noreturn does_not_return (void) { for (;;) continue; } + +// Check _Static_assert. +struct test_static_assert +{ + int x; + _Static_assert (sizeof (int) <= sizeof (long int), + "_Static_assert does not work in struct"); + long int y; +}; + +// Check UTF-8 literals. +#define u8 syntax error! +char const utf8_literal[] = u8"happens to be ASCII" "another string"; + +// Check duplicate typedefs. +typedef long *long_ptr; +typedef long int *long_ptr; +typedef long_ptr long_ptr; + +// Anonymous structures and unions -- taken from C11 6.7.2.1 Example 1. +struct anonymous +{ + union { + struct { int i; int j; }; + struct { int k; long int l; } w; + }; + int m; +} v1; +' + +# Test code for whether the C compiler supports C11 (body of main). +ac_c_conftest_c11_main=' + _Static_assert ((offsetof (struct anonymous, i) + == offsetof (struct anonymous, w.k)), + "Anonymous union alignment botch"); + v1.i = 2; + v1.w.k = 5; + ok |= v1.i != 5; +' + +# Test code for whether the C compiler supports C11 (complete). +ac_c_conftest_c11_program="${ac_c_conftest_c89_globals} +${ac_c_conftest_c99_globals} +${ac_c_conftest_c11_globals} + +int +main (int argc, char **argv) +{ + int ok = 0; + ${ac_c_conftest_c89_main} + ${ac_c_conftest_c99_main} + ${ac_c_conftest_c11_main} + return ok; +} +" + +# Test code for whether the C compiler supports C99 (complete). +ac_c_conftest_c99_program="${ac_c_conftest_c89_globals} +${ac_c_conftest_c99_globals} + +int +main (int argc, char **argv) +{ + int ok = 0; + ${ac_c_conftest_c89_main} + ${ac_c_conftest_c99_main} + return ok; +} +" + +# Test code for whether the C compiler supports C89 (complete). +ac_c_conftest_c89_program="${ac_c_conftest_c89_globals} + +int +main (int argc, char **argv) +{ + int ok = 0; + ${ac_c_conftest_c89_main} + return ok; +} +" + +as_fn_append ac_header_c_list " stdio.h stdio_h HAVE_STDIO_H" +as_fn_append ac_header_c_list " stdlib.h stdlib_h HAVE_STDLIB_H" +as_fn_append ac_header_c_list " string.h string_h HAVE_STRING_H" +as_fn_append ac_header_c_list " inttypes.h inttypes_h HAVE_INTTYPES_H" +as_fn_append ac_header_c_list " stdint.h stdint_h HAVE_STDINT_H" +as_fn_append ac_header_c_list " strings.h strings_h HAVE_STRINGS_H" +as_fn_append ac_header_c_list " sys/stat.h sys_stat_h HAVE_SYS_STAT_H" +as_fn_append ac_header_c_list " sys/types.h sys_types_h HAVE_SYS_TYPES_H" +as_fn_append ac_header_c_list " unistd.h unistd_h HAVE_UNISTD_H" + +# Auxiliary files required by this configure script. +ac_aux_files="ltmain.sh config.guess config.sub compile missing install-sh" + +# Locations in which to look for auxiliary files. +ac_aux_dir_candidates="${srcdir}/." + +# Search for a directory containing all of the required auxiliary files, +# $ac_aux_files, from the $PATH-style list $ac_aux_dir_candidates. +# If we don't find one directory that contains all the files we need, +# we report the set of missing files from the *first* directory in +# $ac_aux_dir_candidates and give up. +ac_missing_aux_files="" +ac_first_candidate=: +printf "%s\n" "$as_me:${as_lineno-$LINENO}: looking for aux files: $ac_aux_files" >&5 +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_found=false +for as_dir in $ac_aux_dir_candidates +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + as_found=: + + printf "%s\n" "$as_me:${as_lineno-$LINENO}: trying $as_dir" >&5 + ac_aux_dir_found=yes + ac_install_sh= + for ac_aux in $ac_aux_files + do + # As a special case, if "install-sh" is required, that requirement + # can be satisfied by any of "install-sh", "install.sh", or "shtool", + # and $ac_install_sh is set appropriately for whichever one is found. + if test x"$ac_aux" = x"install-sh" + then + if test -f "${as_dir}install-sh"; then + printf "%s\n" "$as_me:${as_lineno-$LINENO}: ${as_dir}install-sh found" >&5 + ac_install_sh="${as_dir}install-sh -c" + elif test -f "${as_dir}install.sh"; then + printf "%s\n" "$as_me:${as_lineno-$LINENO}: ${as_dir}install.sh found" >&5 + ac_install_sh="${as_dir}install.sh -c" + elif test -f "${as_dir}shtool"; then + printf "%s\n" "$as_me:${as_lineno-$LINENO}: ${as_dir}shtool found" >&5 + ac_install_sh="${as_dir}shtool install -c" + else + ac_aux_dir_found=no + if $ac_first_candidate; then + ac_missing_aux_files="${ac_missing_aux_files} install-sh" + else + break + fi + fi + else + if test -f "${as_dir}${ac_aux}"; then + printf "%s\n" "$as_me:${as_lineno-$LINENO}: ${as_dir}${ac_aux} found" >&5 + else + ac_aux_dir_found=no + if $ac_first_candidate; then + ac_missing_aux_files="${ac_missing_aux_files} ${ac_aux}" + else + break + fi + fi + fi + done + if test "$ac_aux_dir_found" = yes; then + ac_aux_dir="$as_dir" + break + fi + ac_first_candidate=false + + as_found=false +done +IFS=$as_save_IFS +if $as_found +then : + +else $as_nop + as_fn_error $? "cannot find required auxiliary files:$ac_missing_aux_files" "$LINENO" 5 +fi + + +# These three variables are undocumented and unsupported, +# and are intended to be withdrawn in a future Autoconf release. +# They can cause serious problems if a builder's source tree is in a directory +# whose full name contains unusual characters. +if test -f "${ac_aux_dir}config.guess"; then + ac_config_guess="$SHELL ${ac_aux_dir}config.guess" +fi +if test -f "${ac_aux_dir}config.sub"; then + ac_config_sub="$SHELL ${ac_aux_dir}config.sub" +fi +if test -f "$ac_aux_dir/configure"; then + ac_configure="$SHELL ${ac_aux_dir}configure" +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in $ac_precious_vars; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val=\$ac_cv_env_${ac_var}_value + eval ac_new_val=\$ac_env_${ac_var}_value + case $ac_old_set,$ac_new_set in + set,) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +printf "%s\n" "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 +printf "%s\n" "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + # differences in whitespace do not lead to failure. + ac_old_val_w=`echo x $ac_old_val` + ac_new_val_w=`echo x $ac_new_val` + if test "$ac_old_val_w" != "$ac_new_val_w"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 +printf "%s\n" "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + ac_cache_corrupted=: + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 +printf "%s\n" "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} + eval $ac_var=\$ac_old_val + fi + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 +printf "%s\n" "$as_me: former value: \`$ac_old_val'" >&2;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 +printf "%s\n" "$as_me: current value: \`$ac_new_val'" >&2;} + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *\'*) ac_arg=$ac_var=`printf "%s\n" "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) as_fn_append ac_configure_args " '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 +printf "%s\n" "$as_me: error: changes in the environment can compromise the build" >&2;} + as_fn_error $? "run \`${MAKE-make} distclean' and/or \`rm $cache_file' + and start over" "$LINENO" 5 +fi +## -------------------- ## +## Main body of script. ## +## -------------------- ## + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + + +am__api_version='1.16' + + + + # Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +# Reject install programs that cannot install multiple files. +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 +printf %s "checking for a BSD-compatible install... " >&6; } +if test -z "$INSTALL"; then +if test ${ac_cv_path_install+y} +then : + printf %s "(cached) " >&6 +else $as_nop + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + # Account for fact that we put trailing slashes in our PATH walk. +case $as_dir in #(( + ./ | /[cC]/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_prog$ac_exec_ext"; then + if test $ac_prog = install && + grep dspmsg "$as_dir$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + rm -rf conftest.one conftest.two conftest.dir + echo one > conftest.one + echo two > conftest.two + mkdir conftest.dir + if "$as_dir$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir/" && + test -s conftest.one && test -s conftest.two && + test -s conftest.dir/conftest.one && + test -s conftest.dir/conftest.two + then + ac_cv_path_install="$as_dir$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + fi + done + done + ;; +esac + + done +IFS=$as_save_IFS + +rm -rf conftest.one conftest.two conftest.dir + +fi + if test ${ac_cv_path_install+y}; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. Don't cache a + # value for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + INSTALL=$ac_install_sh + fi +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 +printf "%s\n" "$INSTALL" >&6; } + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 +printf %s "checking whether build environment is sane... " >&6; } +# Reject unsafe characters in $srcdir or the absolute working directory +# name. Accept space and tab only in the latter. +am_lf=' +' +case `pwd` in + *[\\\"\#\$\&\'\`$am_lf]*) + as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; +esac +case $srcdir in + *[\\\"\#\$\&\'\`$am_lf\ \ ]*) + as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;; +esac + +# Do 'set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + am_has_slept=no + for am_try in 1 2; do + echo "timestamp, slept: $am_has_slept" > conftest.file + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$*" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + if test "$*" != "X $srcdir/configure conftest.file" \ + && test "$*" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + as_fn_error $? "ls -t appears to fail. Make sure there is not a broken + alias in your environment" "$LINENO" 5 + fi + if test "$2" = conftest.file || test $am_try -eq 2; then + break + fi + # Just in case. + sleep 1 + am_has_slept=yes + done + test "$2" = conftest.file + ) +then + # Ok. + : +else + as_fn_error $? "newly created file is older than distributed files! +Check your system clock" "$LINENO" 5 +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } +# If we didn't sleep, we still need to ensure time stamps of config.status and +# generated files are strictly newer. +am_sleep_pid= +if grep 'slept: no' conftest.file >/dev/null 2>&1; then + ( sleep 1 ) & + am_sleep_pid=$! +fi + +rm -f conftest.file + +test "$program_prefix" != NONE && + program_transform_name="s&^&$program_prefix&;$program_transform_name" +# Use a double $ so make ignores it. +test "$program_suffix" != NONE && + program_transform_name="s&\$&$program_suffix&;$program_transform_name" +# Double any \ or $. +# By default was `s,x,x', remove it if useless. +ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' +program_transform_name=`printf "%s\n" "$program_transform_name" | sed "$ac_script"` + + +# Expand $ac_aux_dir to an absolute path. +am_aux_dir=`cd "$ac_aux_dir" && pwd` + + + if test x"${MISSING+set}" != xset; then + MISSING="\${SHELL} '$am_aux_dir/missing'" +fi +# Use eval to expand $SHELL +if eval "$MISSING --is-lightweight"; then + am_missing_run="$MISSING " +else + am_missing_run= + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5 +printf "%s\n" "$as_me: WARNING: 'missing' script is too old or missing" >&2;} +fi + +if test x"${install_sh+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; + *) + install_sh="\${SHELL} $am_aux_dir/install-sh" + esac +fi + +# Installed binaries are usually stripped using 'strip' when the user +# run "make install-strip". However 'strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the 'STRIP' environment variable to overrule this program. +if test "$cross_compiling" != no; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_STRIP+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 +printf "%s\n" "$STRIP" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_STRIP+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_STRIP="strip" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 +printf "%s\n" "$ac_ct_STRIP" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a race-free mkdir -p" >&5 +printf %s "checking for a race-free mkdir -p... " >&6; } +if test -z "$MKDIR_P"; then + if test ${ac_cv_path_mkdir+y} +then : + printf %s "(cached) " >&6 +else $as_nop + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_prog in mkdir gmkdir; do + for ac_exec_ext in '' $ac_executable_extensions; do + as_fn_executable_p "$as_dir$ac_prog$ac_exec_ext" || continue + case `"$as_dir$ac_prog$ac_exec_ext" --version 2>&1` in #( + 'mkdir ('*'coreutils) '* | \ + 'BusyBox '* | \ + 'mkdir (fileutils) '4.1*) + ac_cv_path_mkdir=$as_dir$ac_prog$ac_exec_ext + break 3;; + esac + done + done + done +IFS=$as_save_IFS + +fi + + test -d ./--version && rmdir ./--version + if test ${ac_cv_path_mkdir+y}; then + MKDIR_P="$ac_cv_path_mkdir -p" + else + # As a last resort, use the slow shell script. Don't cache a + # value for MKDIR_P within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + MKDIR_P="$ac_install_sh -d" + fi +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 +printf "%s\n" "$MKDIR_P" >&6; } + +for ac_prog in gawk mawk nawk awk +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_AWK+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$AWK"; then + ac_cv_prog_AWK="$AWK" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_AWK="$ac_prog" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AWK=$ac_cv_prog_AWK +if test -n "$AWK"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 +printf "%s\n" "$AWK" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + + test -n "$AWK" && break +done + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +printf %s "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } +set x ${MAKE-make} +ac_make=`printf "%s\n" "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` +if eval test \${ac_cv_prog_make_${ac_make}_set+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat >conftest.make <<\_ACEOF +SHELL = /bin/sh +all: + @echo '@@@%%%=$(MAKE)=@@@%%%' +_ACEOF +# GNU make sometimes prints "make[1]: Entering ...", which would confuse us. +case `${MAKE-make} -f conftest.make 2>/dev/null` in + *@@@%%%=?*=@@@%%%*) + eval ac_cv_prog_make_${ac_make}_set=yes;; + *) + eval ac_cv_prog_make_${ac_make}_set=no;; +esac +rm -f conftest.make +fi +if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + SET_MAKE= +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + SET_MAKE="MAKE=${MAKE-make}" +fi + +rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null + +# Check whether --enable-silent-rules was given. +if test ${enable_silent_rules+y} +then : + enableval=$enable_silent_rules; +fi + +case $enable_silent_rules in # ((( + yes) AM_DEFAULT_VERBOSITY=0;; + no) AM_DEFAULT_VERBOSITY=1;; + *) AM_DEFAULT_VERBOSITY=1;; +esac +am_make=${MAKE-make} +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 +printf %s "checking whether $am_make supports nested variables... " >&6; } +if test ${am_cv_make_support_nested_variables+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if printf "%s\n" 'TRUE=$(BAR$(V)) +BAR0=false +BAR1=true +V=1 +am__doit: + @$(TRUE) +.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then + am_cv_make_support_nested_variables=yes +else + am_cv_make_support_nested_variables=no +fi +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 +printf "%s\n" "$am_cv_make_support_nested_variables" >&6; } +if test $am_cv_make_support_nested_variables = yes; then + AM_V='$(V)' + AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' +else + AM_V=$AM_DEFAULT_VERBOSITY + AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY +fi +AM_BACKSLASH='\' + +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + am__isrc=' -I$(srcdir)' + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi + + +# Define the identity of the package. + PACKAGE='isl-interface' + VERSION='0' + + +printf "%s\n" "#define PACKAGE \"$PACKAGE\"" >>confdefs.h + + +printf "%s\n" "#define VERSION \"$VERSION\"" >>confdefs.h + +# Some tools Automake needs. + +ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} + + +AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} + + +AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} + + +AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} + + +MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} + +# For better backward compatibility. To be removed once Automake 1.9.x +# dies out for good. For more background, see: +# +# +mkdir_p='$(MKDIR_P)' + +# We need awk for the "check" target (and possibly the TAP driver). The +# system "awk" is bad on some platforms. +# Always define AMTAR for backward compatibility. Yes, it's still used +# in the wild :-( We should find a proper way to deprecate it ... +AMTAR='$${TAR-tar}' + + +# We'll loop over all known methods to create a tar archive until one works. +_am_tools='gnutar pax cpio none' + +am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' + + + + + +# Variables for tags utilities; see am/tags.am +if test -z "$CTAGS"; then + CTAGS=ctags +fi + +if test -z "$ETAGS"; then + ETAGS=etags +fi + +if test -z "$CSCOPE"; then + CSCOPE=cscope +fi + + + +# POSIX will say in a future version that running "rm -f" with no argument +# is OK; and we want to be able to make that assumption in our Makefile +# recipes. So use an aggressive probe to check that the usage we want is +# actually supported "in the wild" to an acceptable degree. +# See automake bug#10828. +# To make any issue more visible, cause the running configure to be aborted +# by default if the 'rm' program in use doesn't match our expectations; the +# user can still override this though. +if rm -f && rm -fr && rm -rf; then : OK; else + cat >&2 <<'END' +Oops! + +Your 'rm' program seems unable to run without file operands specified +on the command line, even when the '-f' option is present. This is contrary +to the behaviour of most rm programs out there, and not conforming with +the upcoming POSIX standard: + +Please tell bug-automake@gnu.org about your system, including the value +of your $PATH and any error possibly output before this message. This +can help us improve future automake versions. + +END + if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then + echo 'Configuration will proceed anyway, since you have set the' >&2 + echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 + echo >&2 + else + cat >&2 <<'END' +Aborting the configuration process, to ensure you take notice of the issue. + +You can download and install GNU coreutils to get an 'rm' implementation +that behaves properly: . + +If you want to complete the configuration process using your problematic +'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM +to "yes", and re-run configure. + +END + as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5 + fi +fi + +# Check whether --enable-silent-rules was given. +if test ${enable_silent_rules+y} +then : + enableval=$enable_silent_rules; +fi + +case $enable_silent_rules in # ((( + yes) AM_DEFAULT_VERBOSITY=0;; + no) AM_DEFAULT_VERBOSITY=1;; + *) AM_DEFAULT_VERBOSITY=0;; +esac +am_make=${MAKE-make} +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 +printf %s "checking whether $am_make supports nested variables... " >&6; } +if test ${am_cv_make_support_nested_variables+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if printf "%s\n" 'TRUE=$(BAR$(V)) +BAR0=false +BAR1=true +V=1 +am__doit: + @$(TRUE) +.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then + am_cv_make_support_nested_variables=yes +else + am_cv_make_support_nested_variables=no +fi +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 +printf "%s\n" "$am_cv_make_support_nested_variables" >&6; } +if test $am_cv_make_support_nested_variables = yes; then + AM_V='$(V)' + AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' +else + AM_V=$AM_DEFAULT_VERBOSITY + AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY +fi +AM_BACKSLASH='\' + + + + + + + + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +if test -z "$CXX"; then + if test -n "$CCC"; then + CXX=$CCC + else + if test -n "$ac_tool_prefix"; then + for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC clang++ + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_CXX+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$CXX"; then + ac_cv_prog_CXX="$CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CXX=$ac_cv_prog_CXX +if test -n "$CXX"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 +printf "%s\n" "$CXX" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + + test -n "$CXX" && break + done +fi +if test -z "$CXX"; then + ac_ct_CXX=$CXX + for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC clang++ +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_CXX+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$ac_ct_CXX"; then + ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CXX="$ac_prog" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CXX=$ac_cv_prog_ac_ct_CXX +if test -n "$ac_ct_CXX"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5 +printf "%s\n" "$ac_ct_CXX" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + + test -n "$ac_ct_CXX" && break +done + + if test "x$ac_ct_CXX" = x; then + CXX="g++" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CXX=$ac_ct_CXX + fi +fi + + fi +fi +# Provide some information about the compiler. +printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +printf "%s\n" "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the C++ compiler works" >&5 +printf %s "checking whether the C++ compiler works... " >&6; } +ac_link_default=`printf "%s\n" "$ac_link" | sed 's/ -o *conftest[^ ]*//'` + +# The possible output files: +ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" + +ac_rmfiles= +for ac_file in $ac_files +do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + * ) ac_rmfiles="$ac_rmfiles $ac_file";; + esac +done +rm -f $ac_rmfiles + +if { { ac_try="$ac_link_default" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +printf "%s\n" "$ac_try_echo"; } >&5 + (eval "$ac_link_default") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +then : + # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. +# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' +# in a Makefile. We should not override ac_cv_exeext if it was cached, +# so that the user can short-circuit this test for compilers unknown to +# Autoconf. +for ac_file in $ac_files '' +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + if test ${ac_cv_exeext+y} && test "$ac_cv_exeext" != no; + then :; else + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + fi + # We set ac_cv_exeext here because the later test for it is not + # safe: cross compilers may not add the suffix if given an `-o' + # argument, so we may need to know it at that point already. + # Even if this section looks crufty: it has the advantage of + # actually working. + break;; + * ) + break;; + esac +done +test "$ac_cv_exeext" = no && ac_cv_exeext= + +else $as_nop + ac_file='' +fi +if test -z "$ac_file" +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +printf "%s\n" "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "C++ compiler cannot create executables +See \`config.log' for more details" "$LINENO" 5; } +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C++ compiler default output file name" >&5 +printf %s "checking for C++ compiler default output file name... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 +printf "%s\n" "$ac_file" >&6; } +ac_exeext=$ac_cv_exeext + +rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 +printf %s "checking for suffix of executables... " >&6; } +if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +printf "%s\n" "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +then : + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + break;; + * ) break;; + esac +done +else $as_nop + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest conftest$ac_cv_exeext +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 +printf "%s\n" "$ac_cv_exeext" >&6; } + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main (void) +{ +FILE *f = fopen ("conftest.out", "w"); + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +ac_clean_files="$ac_clean_files conftest.out" +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 +printf %s "checking whether we are cross compiling... " >&6; } +if test "$cross_compiling" != yes; then + { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +printf "%s\n" "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if { ac_try='./conftest$ac_cv_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +printf "%s\n" "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot run C++ compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details" "$LINENO" 5; } + fi + fi +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 +printf "%s\n" "$cross_compiling" >&6; } + +rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out +ac_clean_files=$ac_clean_files_save +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 +printf %s "checking for suffix of object files... " >&6; } +if test ${ac_cv_objext+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +printf "%s\n" "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +then : + for ac_file in conftest.o conftest.obj conftest.*; do + test -f "$ac_file" || continue; + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else $as_nop + printf "%s\n" "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of object files: cannot compile +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 +printf "%s\n" "$ac_cv_objext" >&6; } +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports GNU C++" >&5 +printf %s "checking whether the compiler supports GNU C++... " >&6; } +if test ${ac_cv_cxx_compiler_gnu+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO" +then : + ac_compiler_gnu=yes +else $as_nop + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +ac_cv_cxx_compiler_gnu=$ac_compiler_gnu + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5 +printf "%s\n" "$ac_cv_cxx_compiler_gnu" >&6; } +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + +if test $ac_compiler_gnu = yes; then + GXX=yes +else + GXX= +fi +ac_test_CXXFLAGS=${CXXFLAGS+y} +ac_save_CXXFLAGS=$CXXFLAGS +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5 +printf %s "checking whether $CXX accepts -g... " >&6; } +if test ${ac_cv_prog_cxx_g+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_save_cxx_werror_flag=$ac_cxx_werror_flag + ac_cxx_werror_flag=yes + ac_cv_prog_cxx_g=no + CXXFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO" +then : + ac_cv_prog_cxx_g=yes +else $as_nop + CXXFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO" +then : + +else $as_nop + ac_cxx_werror_flag=$ac_save_cxx_werror_flag + CXXFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO" +then : + ac_cv_prog_cxx_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ac_cxx_werror_flag=$ac_save_cxx_werror_flag +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5 +printf "%s\n" "$ac_cv_prog_cxx_g" >&6; } +if test $ac_test_CXXFLAGS; then + CXXFLAGS=$ac_save_CXXFLAGS +elif test $ac_cv_prog_cxx_g = yes; then + if test "$GXX" = yes; then + CXXFLAGS="-g -O2" + else + CXXFLAGS="-g" + fi +else + if test "$GXX" = yes; then + CXXFLAGS="-O2" + else + CXXFLAGS= + fi +fi +ac_prog_cxx_stdcxx=no +if test x$ac_prog_cxx_stdcxx = xno +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CXX option to enable C++11 features" >&5 +printf %s "checking for $CXX option to enable C++11 features... " >&6; } +if test ${ac_cv_prog_cxx_11+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_cv_prog_cxx_11=no +ac_save_CXX=$CXX +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_cxx_conftest_cxx11_program +_ACEOF +for ac_arg in '' -std=gnu++11 -std=gnu++0x -std=c++11 -std=c++0x -qlanglvl=extended0x -AA +do + CXX="$ac_save_CXX $ac_arg" + if ac_fn_cxx_try_compile "$LINENO" +then : + ac_cv_prog_cxx_cxx11=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam + test "x$ac_cv_prog_cxx_cxx11" != "xno" && break +done +rm -f conftest.$ac_ext +CXX=$ac_save_CXX +fi + +if test "x$ac_cv_prog_cxx_cxx11" = xno +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +printf "%s\n" "unsupported" >&6; } +else $as_nop + if test "x$ac_cv_prog_cxx_cxx11" = x +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +printf "%s\n" "none needed" >&6; } +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_cxx11" >&5 +printf "%s\n" "$ac_cv_prog_cxx_cxx11" >&6; } + CXX="$CXX $ac_cv_prog_cxx_cxx11" +fi + ac_cv_prog_cxx_stdcxx=$ac_cv_prog_cxx_cxx11 + ac_prog_cxx_stdcxx=cxx11 +fi +fi +if test x$ac_prog_cxx_stdcxx = xno +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CXX option to enable C++98 features" >&5 +printf %s "checking for $CXX option to enable C++98 features... " >&6; } +if test ${ac_cv_prog_cxx_98+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_cv_prog_cxx_98=no +ac_save_CXX=$CXX +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_cxx_conftest_cxx98_program +_ACEOF +for ac_arg in '' -std=gnu++98 -std=c++98 -qlanglvl=extended -AA +do + CXX="$ac_save_CXX $ac_arg" + if ac_fn_cxx_try_compile "$LINENO" +then : + ac_cv_prog_cxx_cxx98=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam + test "x$ac_cv_prog_cxx_cxx98" != "xno" && break +done +rm -f conftest.$ac_ext +CXX=$ac_save_CXX +fi + +if test "x$ac_cv_prog_cxx_cxx98" = xno +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +printf "%s\n" "unsupported" >&6; } +else $as_nop + if test "x$ac_cv_prog_cxx_cxx98" = x +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +printf "%s\n" "none needed" >&6; } +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_cxx98" >&5 +printf "%s\n" "$ac_cv_prog_cxx_cxx98" >&6; } + CXX="$CXX $ac_cv_prog_cxx_cxx98" +fi + ac_cv_prog_cxx_stdcxx=$ac_cv_prog_cxx_cxx98 + ac_prog_cxx_stdcxx=cxx98 +fi +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +DEPDIR="${am__leading_dot}deps" + +ac_config_commands="$ac_config_commands depfiles" + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} supports the include directive" >&5 +printf %s "checking whether ${MAKE-make} supports the include directive... " >&6; } +cat > confinc.mk << 'END' +am__doit: + @echo this is the am__doit target >confinc.out +.PHONY: am__doit +END +am__include="#" +am__quote= +# BSD make does it like this. +echo '.include "confinc.mk" # ignored' > confmf.BSD +# Other make implementations (GNU, Solaris 10, AIX) do it like this. +echo 'include confinc.mk # ignored' > confmf.GNU +_am_result=no +for s in GNU BSD; do + { echo "$as_me:$LINENO: ${MAKE-make} -f confmf.$s && cat confinc.out" >&5 + (${MAKE-make} -f confmf.$s && cat confinc.out) >&5 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + case $?:`cat confinc.out 2>/dev/null` in #( + '0:this is the am__doit target') : + case $s in #( + BSD) : + am__include='.include' am__quote='"' ;; #( + *) : + am__include='include' am__quote='' ;; +esac ;; #( + *) : + ;; +esac + if test "$am__include" != "#"; then + _am_result="yes ($s style)" + break + fi +done +rm -f confinc.* confmf.* +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: ${_am_result}" >&5 +printf "%s\n" "${_am_result}" >&6; } + +# Check whether --enable-dependency-tracking was given. +if test ${enable_dependency_tracking+y} +then : + enableval=$enable_dependency_tracking; +fi + +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' + am__nodep='_no' +fi + if test "x$enable_dependency_tracking" != xno; then + AMDEP_TRUE= + AMDEP_FALSE='#' +else + AMDEP_TRUE='#' + AMDEP_FALSE= +fi + + + +depcc="$CXX" am_compiler_list= + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 +printf %s "checking dependency style of $depcc... " >&6; } +if test ${am_cv_CXX_dependencies_compiler_type+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named 'D' -- because '-MD' means "put the output + # in D". + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CXX_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + am__universal=false + case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with + # Solaris 10 /bin/sh. + echo '/* dummy */' > sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with '-c' and '-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle '-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs. + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # After this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested. + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok '-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CXX_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CXX_dependencies_compiler_type=none +fi + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_CXX_dependencies_compiler_type" >&5 +printf "%s\n" "$am_cv_CXX_dependencies_compiler_type" >&6; } +CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type + + if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then + am__fastdepCXX_TRUE= + am__fastdepCXX_FALSE='#' +else + am__fastdepCXX_TRUE='#' + am__fastdepCXX_FALSE= +fi + + + + + + + + + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_CC+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +printf "%s\n" "$CC" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_CC+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="gcc" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +printf "%s\n" "$ac_ct_CC" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_CC+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +printf "%s\n" "$CC" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + + fi +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_CC+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + if test "$as_dir$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +printf "%s\n" "$CC" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl.exe + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_CC+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +printf "%s\n" "$CC" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl.exe +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_CC+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="$ac_prog" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +printf "%s\n" "$ac_ct_CC" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}clang", so it can be a program name with args. +set dummy ${ac_tool_prefix}clang; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_CC+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}clang" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +printf "%s\n" "$CC" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "clang", so it can be a program name with args. +set dummy clang; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_CC+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="clang" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +printf "%s\n" "$ac_ct_CC" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +fi + + +test -z "$CC" && { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "no acceptable C compiler found in \$PATH +See \`config.log' for more details" "$LINENO" 5; } + +# Provide some information about the compiler. +printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion -version; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +printf "%s\n" "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports GNU C" >&5 +printf %s "checking whether the compiler supports GNU C... " >&6; } +if test ${ac_cv_c_compiler_gnu+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_compiler_gnu=yes +else $as_nop + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 +printf "%s\n" "$ac_cv_c_compiler_gnu" >&6; } +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +if test $ac_compiler_gnu = yes; then + GCC=yes +else + GCC= +fi +ac_test_CFLAGS=${CFLAGS+y} +ac_save_CFLAGS=$CFLAGS +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 +printf %s "checking whether $CC accepts -g... " >&6; } +if test ${ac_cv_prog_cc_g+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_prog_cc_g=yes +else $as_nop + CFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + +else $as_nop + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_prog_cc_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 +printf "%s\n" "$ac_cv_prog_cc_g" >&6; } +if test $ac_test_CFLAGS; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +ac_prog_cc_stdc=no +if test x$ac_prog_cc_stdc = xno +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C11 features" >&5 +printf %s "checking for $CC option to enable C11 features... " >&6; } +if test ${ac_cv_prog_cc_c11+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_cv_prog_cc_c11=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_c_conftest_c11_program +_ACEOF +for ac_arg in '' -std=gnu11 +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_prog_cc_c11=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam + test "x$ac_cv_prog_cc_c11" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC +fi + +if test "x$ac_cv_prog_cc_c11" = xno +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +printf "%s\n" "unsupported" >&6; } +else $as_nop + if test "x$ac_cv_prog_cc_c11" = x +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +printf "%s\n" "none needed" >&6; } +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c11" >&5 +printf "%s\n" "$ac_cv_prog_cc_c11" >&6; } + CC="$CC $ac_cv_prog_cc_c11" +fi + ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c11 + ac_prog_cc_stdc=c11 +fi +fi +if test x$ac_prog_cc_stdc = xno +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C99 features" >&5 +printf %s "checking for $CC option to enable C99 features... " >&6; } +if test ${ac_cv_prog_cc_c99+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_cv_prog_cc_c99=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_c_conftest_c99_program +_ACEOF +for ac_arg in '' -std=gnu99 -std=c99 -c99 -qlanglvl=extc1x -qlanglvl=extc99 -AC99 -D_STDC_C99= +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_prog_cc_c99=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam + test "x$ac_cv_prog_cc_c99" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC +fi + +if test "x$ac_cv_prog_cc_c99" = xno +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +printf "%s\n" "unsupported" >&6; } +else $as_nop + if test "x$ac_cv_prog_cc_c99" = x +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +printf "%s\n" "none needed" >&6; } +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c99" >&5 +printf "%s\n" "$ac_cv_prog_cc_c99" >&6; } + CC="$CC $ac_cv_prog_cc_c99" +fi + ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c99 + ac_prog_cc_stdc=c99 +fi +fi +if test x$ac_prog_cc_stdc = xno +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C89 features" >&5 +printf %s "checking for $CC option to enable C89 features... " >&6; } +if test ${ac_cv_prog_cc_c89+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_c_conftest_c89_program +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_prog_cc_c89=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC +fi + +if test "x$ac_cv_prog_cc_c89" = xno +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +printf "%s\n" "unsupported" >&6; } +else $as_nop + if test "x$ac_cv_prog_cc_c89" = x +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +printf "%s\n" "none needed" >&6; } +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 +printf "%s\n" "$ac_cv_prog_cc_c89" >&6; } + CC="$CC $ac_cv_prog_cc_c89" +fi + ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c89 + ac_prog_cc_stdc=c89 +fi +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5 +printf %s "checking whether $CC understands -c and -o together... " >&6; } +if test ${am_cv_prog_cc_c_o+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF + # Make sure it works both with $CC and with simple cc. + # Following AC_PROG_CC_C_O, we do the test twice because some + # compilers refuse to overwrite an existing .o file with -o, + # though they will create one. + am_cv_prog_cc_c_o=yes + for am_i in 1 2; do + if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5 + ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } \ + && test -f conftest2.$ac_objext; then + : OK + else + am_cv_prog_cc_c_o=no + break + fi + done + rm -f core conftest* + unset am_i +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5 +printf "%s\n" "$am_cv_prog_cc_c_o" >&6; } +if test "$am_cv_prog_cc_c_o" != yes; then + # Losing compiler, so override with the script. + # FIXME: It is wrong to rewrite CC. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__CC in this case, + # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" + CC="$am_aux_dir/compile $CC" +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +depcc="$CC" am_compiler_list= + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 +printf %s "checking dependency style of $depcc... " >&6; } +if test ${am_cv_CC_dependencies_compiler_type+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named 'D' -- because '-MD' means "put the output + # in D". + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CC_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + am__universal=false + case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with + # Solaris 10 /bin/sh. + echo '/* dummy */' > sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with '-c' and '-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle '-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs. + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # After this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested. + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok '-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CC_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CC_dependencies_compiler_type=none +fi + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 +printf "%s\n" "$am_cv_CC_dependencies_compiler_type" >&6; } +CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type + + if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then + am__fastdepCC_TRUE= + am__fastdepCC_FALSE='#' +else + am__fastdepCC_TRUE='#' + am__fastdepCC_FALSE= +fi + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 +printf %s "checking how to run the C preprocessor... " >&6; } +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if test ${ac_cv_prog_CPP+y} +then : + printf %s "(cached) " >&6 +else $as_nop + # Double quotes because $CC needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" cpp /lib/cpp + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO" +then : + +else $as_nop + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO" +then : + # Broken: success on invalid input. +continue +else $as_nop + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok +then : + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 +printf "%s\n" "$CPP" >&6; } +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO" +then : + +else $as_nop + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO" +then : + # Broken: success on invalid input. +continue +else $as_nop + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok +then : + +else $as_nop + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details" "$LINENO" 5; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + + # Make sure we can run config.sub. +$SHELL "${ac_aux_dir}config.sub" sun4 >/dev/null 2>&1 || + as_fn_error $? "cannot run $SHELL ${ac_aux_dir}config.sub" "$LINENO" 5 + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 +printf %s "checking build system type... " >&6; } +if test ${ac_cv_build+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_build_alias=$build_alias +test "x$ac_build_alias" = x && + ac_build_alias=`$SHELL "${ac_aux_dir}config.guess"` +test "x$ac_build_alias" = x && + as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 +ac_cv_build=`$SHELL "${ac_aux_dir}config.sub" $ac_build_alias` || + as_fn_error $? "$SHELL ${ac_aux_dir}config.sub $ac_build_alias failed" "$LINENO" 5 + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 +printf "%s\n" "$ac_cv_build" >&6; } +case $ac_cv_build in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; +esac +build=$ac_cv_build +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_build +shift +build_cpu=$1 +build_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +build_os=$* +IFS=$ac_save_IFS +case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac + + + + +cross_compiling_build=no + +ac_build_tool_prefix= +if test -n "$build" +then : + ac_build_tool_prefix="$build-" +elif test -n "$build_alias" +then : + ac_build_tool_prefix="$build_alias-" +fi + +ac_ext=c +ac_cpp='$CPP_FOR_BUILD $CPPFLAGS_FOR_BUILD' +ac_compile='$CC_FOR_BUILD -c $CFLAGS_FOR_BUILD $CPPFLAGS_FOR_BUILD conftest.$ac_ext >&5' +ac_link='$CC_FOR_BUILD -o conftest$ac_build_exeext $CFLAGS_FOR_BUILD $CPPFLAGS_FOR_BUILD $LDFLAGS_FOR_BUILD conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_build_c_compiler_gnu + + +was_set_c_compiler_gnu=${ac_cv_c_compiler_gnu+y} +if test ${was_set_c_compiler_gnu} +then : + saved_c_compiler_gnu=$ac_cv_c_compiler_gnu + { ac_cv_c_compiler_gnu=; unset ac_cv_c_compiler_gnu;} +fi + +ac_ext=c +ac_cpp='$CPP_FOR_BUILD $CPPFLAGS_FOR_BUILD' +ac_compile='$CC_FOR_BUILD -c $CFLAGS_FOR_BUILD $CPPFLAGS_FOR_BUILD conftest.$ac_ext >&5' +ac_link='$CC_FOR_BUILD -o conftest$ac_build_exeext $CFLAGS_FOR_BUILD $CPPFLAGS_FOR_BUILD $LDFLAGS_FOR_BUILD conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_build_c_compiler_gnu +if test -n "$ac_build_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_build_tool_prefix}gcc; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_CC_FOR_BUILD+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$CC_FOR_BUILD"; then + ac_cv_prog_CC_FOR_BUILD="$CC_FOR_BUILD" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_CC_FOR_BUILD="${ac_build_tool_prefix}gcc" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC_FOR_BUILD=$ac_cv_prog_CC_FOR_BUILD +if test -n "$CC_FOR_BUILD"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC_FOR_BUILD" >&5 +printf "%s\n" "$CC_FOR_BUILD" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC_FOR_BUILD"; then + ac_ct_CC_FOR_BUILD=$CC_FOR_BUILD + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_CC_FOR_BUILD+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$ac_ct_CC_FOR_BUILD"; then + ac_cv_prog_ac_ct_CC_FOR_BUILD="$ac_ct_CC_FOR_BUILD" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC_FOR_BUILD="gcc" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC_FOR_BUILD=$ac_cv_prog_ac_ct_CC_FOR_BUILD +if test -n "$ac_ct_CC_FOR_BUILD"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC_FOR_BUILD" >&5 +printf "%s\n" "$ac_ct_CC_FOR_BUILD" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + if test "x$ac_ct_CC_FOR_BUILD" = x; then + CC_FOR_BUILD="" + else + case $cross_compiling_build:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with build triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with build triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC_FOR_BUILD=$ac_ct_CC_FOR_BUILD + fi +else + CC_FOR_BUILD="$ac_cv_prog_CC_FOR_BUILD" +fi + +if test -z "$CC_FOR_BUILD"; then + if test -n "$ac_build_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_build_tool_prefix}cc; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_CC_FOR_BUILD+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$CC_FOR_BUILD"; then + ac_cv_prog_CC_FOR_BUILD="$CC_FOR_BUILD" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_CC_FOR_BUILD="${ac_build_tool_prefix}cc" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC_FOR_BUILD=$ac_cv_prog_CC_FOR_BUILD +if test -n "$CC_FOR_BUILD"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC_FOR_BUILD" >&5 +printf "%s\n" "$CC_FOR_BUILD" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + + fi +fi +if test -z "$CC_FOR_BUILD"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_CC_FOR_BUILD+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$CC_FOR_BUILD"; then + ac_cv_prog_CC_FOR_BUILD="$CC_FOR_BUILD" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + if test "$as_dir$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC_FOR_BUILD="cc" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC_FOR_BUILD + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC_FOR_BUILD to just the basename; use the full file name. + shift + ac_cv_prog_CC_FOR_BUILD="$as_dir$ac_word${1+' '}$@" + fi +fi +fi +fi +CC_FOR_BUILD=$ac_cv_prog_CC_FOR_BUILD +if test -n "$CC_FOR_BUILD"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC_FOR_BUILD" >&5 +printf "%s\n" "$CC_FOR_BUILD" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + +fi +if test -z "$CC_FOR_BUILD"; then + if test -n "$ac_build_tool_prefix"; then + for ac_prog in cl.exe + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_build_tool_prefix$ac_prog; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_CC_FOR_BUILD+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$CC_FOR_BUILD"; then + ac_cv_prog_CC_FOR_BUILD="$CC_FOR_BUILD" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_CC_FOR_BUILD="$ac_build_tool_prefix$ac_prog" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC_FOR_BUILD=$ac_cv_prog_CC_FOR_BUILD +if test -n "$CC_FOR_BUILD"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC_FOR_BUILD" >&5 +printf "%s\n" "$CC_FOR_BUILD" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + + test -n "$CC_FOR_BUILD" && break + done +fi +if test -z "$CC_FOR_BUILD"; then + ac_ct_CC_FOR_BUILD=$CC_FOR_BUILD + for ac_prog in cl.exe +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_CC_FOR_BUILD+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$ac_ct_CC_FOR_BUILD"; then + ac_cv_prog_ac_ct_CC_FOR_BUILD="$ac_ct_CC_FOR_BUILD" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC_FOR_BUILD="$ac_prog" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC_FOR_BUILD=$ac_cv_prog_ac_ct_CC_FOR_BUILD +if test -n "$ac_ct_CC_FOR_BUILD"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC_FOR_BUILD" >&5 +printf "%s\n" "$ac_ct_CC_FOR_BUILD" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + + test -n "$ac_ct_CC_FOR_BUILD" && break +done + + if test "x$ac_ct_CC_FOR_BUILD" = x; then + CC_FOR_BUILD="" + else + case $cross_compiling_build:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with build triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with build triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC_FOR_BUILD=$ac_ct_CC_FOR_BUILD + fi +fi + +fi +if test -z "$CC_FOR_BUILD"; then + if test -n "$ac_build_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}clang", so it can be a program name with args. +set dummy ${ac_build_tool_prefix}clang; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_CC_FOR_BUILD+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$CC_FOR_BUILD"; then + ac_cv_prog_CC_FOR_BUILD="$CC_FOR_BUILD" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_CC_FOR_BUILD="${ac_build_tool_prefix}clang" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC_FOR_BUILD=$ac_cv_prog_CC_FOR_BUILD +if test -n "$CC_FOR_BUILD"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC_FOR_BUILD" >&5 +printf "%s\n" "$CC_FOR_BUILD" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC_FOR_BUILD"; then + ac_ct_CC_FOR_BUILD=$CC_FOR_BUILD + # Extract the first word of "clang", so it can be a program name with args. +set dummy clang; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_CC_FOR_BUILD+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$ac_ct_CC_FOR_BUILD"; then + ac_cv_prog_ac_ct_CC_FOR_BUILD="$ac_ct_CC_FOR_BUILD" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC_FOR_BUILD="clang" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC_FOR_BUILD=$ac_cv_prog_ac_ct_CC_FOR_BUILD +if test -n "$ac_ct_CC_FOR_BUILD"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC_FOR_BUILD" >&5 +printf "%s\n" "$ac_ct_CC_FOR_BUILD" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + if test "x$ac_ct_CC_FOR_BUILD" = x; then + CC_FOR_BUILD="" + else + case $cross_compiling_build:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with build triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with build triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC_FOR_BUILD=$ac_ct_CC_FOR_BUILD + fi +else + CC_FOR_BUILD="$ac_cv_prog_CC_FOR_BUILD" +fi + +fi + + +test -z "$CC_FOR_BUILD" && { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "no acceptable C compiler found in \$PATH +See \`config.log' for more details" "$LINENO" 5; } + +# Provide some information about the compiler. +printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion -version; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +printf "%s\n" "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports GNU C" >&5 +printf %s "checking whether the compiler supports GNU C... " >&6; } +if test ${ac_cv_c_compiler_gnu+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_compiler_gnu=yes +else $as_nop + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_build_objext conftest.beam conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 +printf "%s\n" "$ac_cv_c_compiler_gnu" >&6; } +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +if test $ac_compiler_gnu = yes; then + GCC_FOR_BUILD=yes +else + GCC_FOR_BUILD= +fi +ac_test_CFLAGS=${CFLAGS_FOR_BUILD+y} +ac_save_CFLAGS=$CFLAGS_FOR_BUILD +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC_FOR_BUILD accepts -g" >&5 +printf %s "checking whether $CC_FOR_BUILD accepts -g... " >&6; } +if test ${ac_cv_build_prog_cc_g+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_build_prog_cc_g=no + CFLAGS_FOR_BUILD="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_build_prog_cc_g=yes +else $as_nop + CFLAGS_FOR_BUILD="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + +else $as_nop + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS_FOR_BUILD="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_build_prog_cc_g=yes +fi +rm -f core conftest.err conftest.$ac_build_objext conftest.beam conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_build_objext conftest.beam conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_build_objext conftest.beam conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build_prog_cc_g" >&5 +printf "%s\n" "$ac_cv_build_prog_cc_g" >&6; } +if test $ac_test_CFLAGS; then + CFLAGS_FOR_BUILD=$ac_save_CFLAGS +elif test $ac_cv_build_prog_cc_g = yes; then + if test "$GCC_FOR_BUILD" = yes; then + CFLAGS_FOR_BUILD="-g -O2" + else + CFLAGS_FOR_BUILD="-g" + fi +else + if test "$GCC_FOR_BUILD" = yes; then + CFLAGS_FOR_BUILD="-O2" + else + CFLAGS_FOR_BUILD= + fi +fi +ac_prog_cc_stdc=no +if test x$ac_prog_cc_stdc = xno +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC_FOR_BUILD option to enable C11 features" >&5 +printf %s "checking for $CC_FOR_BUILD option to enable C11 features... " >&6; } +if test ${ac_cv_build_prog_cc_c11+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_cv_build_prog_cc_c11=no +ac_save_CC=$CC_FOR_BUILD +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_c_conftest_c11_program +_ACEOF +for ac_arg in '' -std=gnu11 +do + CC_FOR_BUILD="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_build_prog_cc_c11=$ac_arg +fi +rm -f core conftest.err conftest.$ac_build_objext conftest.beam + test "x$ac_cv_build_prog_cc_c11" != "xno" && break +done +rm -f conftest.$ac_ext +CC_FOR_BUILD=$ac_save_CC +fi + +if test "x$ac_cv_build_prog_cc_c11" = xno +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +printf "%s\n" "unsupported" >&6; } +else $as_nop + if test "x$ac_cv_build_prog_cc_c11" = x +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +printf "%s\n" "none needed" >&6; } +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build_prog_cc_c11" >&5 +printf "%s\n" "$ac_cv_build_prog_cc_c11" >&6; } + CC_FOR_BUILD="$CC_FOR_BUILD $ac_cv_build_prog_cc_c11" +fi + ac_cv_prog_cc_stdc=$ac_cv_build_prog_cc_c11 + ac_prog_cc_stdc=c11 +fi +fi +if test x$ac_prog_cc_stdc = xno +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC_FOR_BUILD option to enable C99 features" >&5 +printf %s "checking for $CC_FOR_BUILD option to enable C99 features... " >&6; } +if test ${ac_cv_build_prog_cc_c99+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_cv_build_prog_cc_c99=no +ac_save_CC=$CC_FOR_BUILD +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_c_conftest_c99_program +_ACEOF +for ac_arg in '' -std=gnu99 -std=c99 -c99 -qlanglvl=extc1x -qlanglvl=extc99 -AC99 -D_STDC_C99= +do + CC_FOR_BUILD="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_build_prog_cc_c99=$ac_arg +fi +rm -f core conftest.err conftest.$ac_build_objext conftest.beam + test "x$ac_cv_build_prog_cc_c99" != "xno" && break +done +rm -f conftest.$ac_ext +CC_FOR_BUILD=$ac_save_CC +fi + +if test "x$ac_cv_build_prog_cc_c99" = xno +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +printf "%s\n" "unsupported" >&6; } +else $as_nop + if test "x$ac_cv_build_prog_cc_c99" = x +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +printf "%s\n" "none needed" >&6; } +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build_prog_cc_c99" >&5 +printf "%s\n" "$ac_cv_build_prog_cc_c99" >&6; } + CC_FOR_BUILD="$CC_FOR_BUILD $ac_cv_build_prog_cc_c99" +fi + ac_cv_prog_cc_stdc=$ac_cv_build_prog_cc_c99 + ac_prog_cc_stdc=c99 +fi +fi +if test x$ac_prog_cc_stdc = xno +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC_FOR_BUILD option to enable C89 features" >&5 +printf %s "checking for $CC_FOR_BUILD option to enable C89 features... " >&6; } +if test ${ac_cv_build_prog_cc_c89+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_cv_build_prog_cc_c89=no +ac_save_CC=$CC_FOR_BUILD +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_c_conftest_c89_program +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC_FOR_BUILD="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_build_prog_cc_c89=$ac_arg +fi +rm -f core conftest.err conftest.$ac_build_objext conftest.beam + test "x$ac_cv_build_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC_FOR_BUILD=$ac_save_CC +fi + +if test "x$ac_cv_build_prog_cc_c89" = xno +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +printf "%s\n" "unsupported" >&6; } +else $as_nop + if test "x$ac_cv_build_prog_cc_c89" = x +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +printf "%s\n" "none needed" >&6; } +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build_prog_cc_c89" >&5 +printf "%s\n" "$ac_cv_build_prog_cc_c89" >&6; } + CC_FOR_BUILD="$CC_FOR_BUILD $ac_cv_build_prog_cc_c89" +fi + ac_cv_prog_cc_stdc=$ac_cv_build_prog_cc_c89 + ac_prog_cc_stdc=c89 +fi +fi + +ac_ext=c +ac_cpp='$CPP_FOR_BUILD $CPPFLAGS_FOR_BUILD' +ac_compile='$CC_FOR_BUILD -c $CFLAGS_FOR_BUILD $CPPFLAGS_FOR_BUILD conftest.$ac_ext >&5' +ac_link='$CC_FOR_BUILD -o conftest$ac_build_exeext $CFLAGS_FOR_BUILD $CPPFLAGS_FOR_BUILD $LDFLAGS_FOR_BUILD conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_build_c_compiler_gnu + + + ac_ext=c +ac_cpp='$CPP_FOR_BUILD $CPPFLAGS_FOR_BUILD' +ac_compile='$CC_FOR_BUILD -c $CFLAGS_FOR_BUILD $CPPFLAGS_FOR_BUILD conftest.$ac_ext >&5' +ac_link='$CC_FOR_BUILD -o conftest$ac_build_exeext $CFLAGS_FOR_BUILD $CPPFLAGS_FOR_BUILD $LDFLAGS_FOR_BUILD conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_build_c_compiler_gnu +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC_FOR_BUILD understands -c and -o together" >&5 +printf %s "checking whether $CC_FOR_BUILD understands -c and -o together... " >&6; } +if test ${am_cv_build_prog_cc_c_o+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF + # Make sure it works both with $CC and with simple cc. + # Following AC_PROG_CC_C_O, we do the test twice because some + # compilers refuse to overwrite an existing .o file with -o, + # though they will create one. + am_cv_build_prog_cc_c_o=yes + for am_i in 1 2; do + if { echo "$as_me:$LINENO: $CC_FOR_BUILD -c conftest.$ac_ext -o conftest2.$ac_build_objext" >&5 + ($CC_FOR_BUILD -c conftest.$ac_ext -o conftest2.$ac_build_objext) >&5 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } \ + && test -f conftest2.$ac_build_objext; then + : OK + else + am_cv_build_prog_cc_c_o=no + break + fi + done + rm -f core conftest* + unset am_i +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_build_prog_cc_c_o" >&5 +printf "%s\n" "$am_cv_build_prog_cc_c_o" >&6; } +if test "$am_cv_build_prog_cc_c_o" != yes; then + # Losing compiler, so override with the script. + # FIXME: It is wrong to rewrite CC. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__CC in this case, + # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" + CC_FOR_BUILD="$am_aux_dir/compile $CC_FOR_BUILD" +fi +ac_ext=c +ac_cpp='$CPP_FOR_BUILD $CPPFLAGS_FOR_BUILD' +ac_compile='$CC_FOR_BUILD -c $CFLAGS_FOR_BUILD $CPPFLAGS_FOR_BUILD conftest.$ac_ext >&5' +ac_link='$CC_FOR_BUILD -o conftest$ac_build_exeext $CFLAGS_FOR_BUILD $CPPFLAGS_FOR_BUILD $LDFLAGS_FOR_BUILD conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_build_c_compiler_gnu + + +depcc="$CC_FOR_BUILD" am_compiler_list= + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 +printf %s "checking dependency style of $depcc... " >&6; } +if test ${am_cv_build_CC_dependencies_compiler_type+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named 'D' -- because '-MD' means "put the output + # in D". + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_build_CC_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + am__universal=false + case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with + # Solaris 10 /bin/sh. + echo '/* dummy */' > sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with '-c' and '-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle '-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs. + am__obj=sub/conftest.${BUILD_OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # After this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested. + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok '-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${BUILD_OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_build_CC_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_build_CC_dependencies_compiler_type=none +fi + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_build_CC_dependencies_compiler_type" >&5 +printf "%s\n" "$am_cv_build_CC_dependencies_compiler_type" >&6; } +CCDEPMODE=depmode=$am_cv_build_CC_dependencies_compiler_type + + if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_build_CC_dependencies_compiler_type" = gcc3; then + am__fastdepCC_build_TRUE= + am__fastdepCC_build_FALSE='#' +else + am__fastdepCC_build_TRUE='#' + am__fastdepCC_build_FALSE= +fi + + + +if test ${was_set_c_compiler_gnu} +then : + ac_cv_c_compiler_gnu=$saved_c_compiler_gnu +fi + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 +printf %s "checking whether the C compiler works... " >&6; } +ac_link_default=`printf "%s\n" "$ac_link" | sed 's/ -o *conftest[^ ]*//'` + +# The possible output files: +ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" + +ac_rmfiles= +for ac_file in $ac_files +do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + * ) ac_rmfiles="$ac_rmfiles $ac_file";; + esac +done +rm -f $ac_rmfiles + +if { { ac_try="$ac_link_default" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +printf "%s\n" "$ac_try_echo"; } >&5 + (eval "$ac_link_default") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +then : + # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. +# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' +# in a Makefile. We should not override ac_cv_exeext if it was cached, +# so that the user can short-circuit this test for compilers unknown to +# Autoconf. +for ac_file in $ac_files '' +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + if test ${ac_cv_build_exeext+y} && test "$ac_cv_build_exeext" != no; + then :; else + ac_cv_build_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + fi + # We set ac_cv_exeext here because the later test for it is not + # safe: cross compilers may not add the suffix if given an `-o' + # argument, so we may need to know it at that point already. + # Even if this section looks crufty: it has the advantage of + # actually working. + break;; + * ) + break;; + esac +done +test "$ac_cv_build_exeext" = no && ac_cv_build_exeext= + +else $as_nop + ac_file='' +fi +if test -z "$ac_file" +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +printf "%s\n" "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "C compiler cannot create executables +See \`config.log' for more details" "$LINENO" 5; } +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 +printf %s "checking for C compiler default output file name... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 +printf "%s\n" "$ac_file" >&6; } +ac_build_exeext=$ac_cv_build_exeext + +rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_build_exeext b.out +ac_clean_files=$ac_clean_files_save +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 +printf %s "checking for suffix of executables... " >&6; } +if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +printf "%s\n" "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +then : + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + *.* ) ac_cv_build_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + break;; + * ) break;; + esac +done +else $as_nop + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest conftest$ac_cv_build_exeext +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build_exeext" >&5 +printf "%s\n" "$ac_cv_build_exeext" >&6; } + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_build_exeext +ac_build_exeext=$BUILD_EXEEXT +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main (void) +{ +FILE *f = fopen ("conftest.out", "w"); + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +ac_clean_files="$ac_clean_files conftest.out" +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 +printf %s "checking whether we are cross compiling... " >&6; } +if test "$cross_compiling_build" != yes; then + { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +printf "%s\n" "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if { ac_try='./conftest$ac_cv_build_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +printf "%s\n" "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then + cross_compiling_build=no + else + if test "$cross_compiling_build" = maybe; then + cross_compiling_build=yes + else + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot run C compiled programs. +If you meant to cross compile, use \`--build'. +See \`config.log' for more details" "$LINENO" 5; } + fi + fi +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $cross_compiling_build" >&5 +printf "%s\n" "$cross_compiling_build" >&6; } + +rm -f conftest.$ac_ext conftest$ac_cv_build_exeext conftest.out +ac_clean_files=$ac_clean_files_save + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 +printf %s "checking for suffix of object files... " >&6; } +if test ${ac_cv_build_objext+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +printf "%s\n" "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +then : + for ac_file in conftest.o conftest.obj conftest.*; do + test -f "$ac_file" || continue; + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; + *) ac_cv_build_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else $as_nop + printf "%s\n" "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of object files: cannot compile +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest.$ac_cv_build_objext conftest.$ac_ext +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build_objext" >&5 +printf "%s\n" "$ac_cv_build_objext" >&6; } +OBJEXT=$ac_cv_build_objext +ac_build_objext=$BUILD_OBJEXT + +ac_ext=c +ac_cpp='$CPP_FOR_BUILD $CPPFLAGS_FOR_BUILD' +ac_compile='$CC_FOR_BUILD -c $CFLAGS_FOR_BUILD $CPPFLAGS_FOR_BUILD conftest.$ac_ext >&5' +ac_link='$CC_FOR_BUILD -o conftest$ac_build_exeext $CFLAGS_FOR_BUILD $CPPFLAGS_FOR_BUILD $LDFLAGS_FOR_BUILD conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_build_c_compiler_gnu +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 +printf %s "checking how to run the C preprocessor... " >&6; } +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP_FOR_BUILD" && test -d "$CPP_FOR_BUILD"; then + CPP_FOR_BUILD= +fi +if test -z "$CPP_FOR_BUILD"; then + if test ${ac_cv_build_prog_CPP+y} +then : + printf %s "(cached) " >&6 +else $as_nop + # Double quotes because $CC needs to be expanded + for CPP_FOR_BUILD in "$CC_FOR_BUILD -E" "$CC_FOR_BUILD -E -traditional-cpp" cpp /lib/cpp + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO" +then : + +else $as_nop + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO" +then : + # Broken: success on invalid input. +continue +else $as_nop + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok +then : + break +fi + + done + ac_cv_build_prog_CPP=$CPP_FOR_BUILD + +fi + CPP_FOR_BUILD=$ac_cv_build_prog_CPP +else + ac_cv_build_prog_CPP=$CPP_FOR_BUILD +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CPP_FOR_BUILD" >&5 +printf "%s\n" "$CPP_FOR_BUILD" >&6; } +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO" +then : + +else $as_nop + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO" +then : + # Broken: success on invalid input. +continue +else $as_nop + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok +then : + +else $as_nop + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "C preprocessor \"$CPP_FOR_BUILD\" fails sanity check +See \`config.log' for more details" "$LINENO" 5; } +fi + +ac_ext=c +ac_cpp='$CPP_FOR_BUILD $CPPFLAGS_FOR_BUILD' +ac_compile='$CC_FOR_BUILD -c $CFLAGS_FOR_BUILD $CPPFLAGS_FOR_BUILD conftest.$ac_ext >&5' +ac_link='$CC_FOR_BUILD -o conftest$ac_build_exeext $CFLAGS_FOR_BUILD $CPPFLAGS_FOR_BUILD $LDFLAGS_FOR_BUILD conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_build_c_compiler_gnu + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +EXEEXT=$ac_cv_exeext +BUILD_EXEEXT=$ac_cv_build_exeext; ac_build_exeext=$ac_cv_build_exeext +OBJEXT=$ac_cv_objext +BUILD_OBJEXT=$ac_cv_build_objext; ac_build_objext=$ac_cv_build_objext +CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type +CCDEPMODE_FOR_BUILD=depmode=$am_cv_build_CC_dependencies_compiler_type + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to run the C++ preprocessor" >&5 +printf %s "checking how to run the C++ preprocessor... " >&6; } +if test -z "$CXXCPP"; then + if test ${ac_cv_prog_CXXCPP+y} +then : + printf %s "(cached) " >&6 +else $as_nop + # Double quotes because $CXX needs to be expanded + for CXXCPP in "$CXX -E" cpp /lib/cpp + do + ac_preproc_ok=false +for ac_cxx_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + Syntax error +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO" +then : + +else $as_nop + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO" +then : + # Broken: success on invalid input. +continue +else $as_nop + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok +then : + break +fi + + done + ac_cv_prog_CXXCPP=$CXXCPP + +fi + CXXCPP=$ac_cv_prog_CXXCPP +else + ac_cv_prog_CXXCPP=$CXXCPP +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CXXCPP" >&5 +printf "%s\n" "$CXXCPP" >&6; } +ac_preproc_ok=false +for ac_cxx_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + Syntax error +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO" +then : + +else $as_nop + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO" +then : + # Broken: success on invalid input. +continue +else $as_nop + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok +then : + +else $as_nop + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "C++ preprocessor \"$CXXCPP\" fails sanity check +See \`config.log' for more details" "$LINENO" 5; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 +printf %s "checking host system type... " >&6; } +if test ${ac_cv_host+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test "x$host_alias" = x; then + ac_cv_host=$ac_cv_build +else + ac_cv_host=`$SHELL "${ac_aux_dir}config.sub" $host_alias` || + as_fn_error $? "$SHELL ${ac_aux_dir}config.sub $host_alias failed" "$LINENO" 5 +fi + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 +printf "%s\n" "$ac_cv_host" >&6; } +case $ac_cv_host in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; +esac +host=$ac_cv_host +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_host +shift +host_cpu=$1 +host_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +host_os=$* +IFS=$ac_save_IFS +case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac + + + + +save_cross_compiling=$cross_compiling +save_ac_tool_prefix=$ac_tool_prefix +cross_compiling=no +ac_tool_prefix= + +ac_ext=cpp +ac_cpp='$CXXCPP_FOR_BUILD $CPPFLAGS_FOR_BUILD' +ac_build_compile='$CXX_FOR_BUILD -c $CXXFLAGS_FOR_BUILD $CPPFLAGS_FOR_BUILD conftest.$ac_ext >&5' +ac_build_link='$CXX_FOR_BUILD -o conftest$ac_exeext $CXXFLAGS_FOR_BUILD $CPPFLAGS_FOR_BUILD $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +if test -z "$CXX_FOR_BUILD"; then + if test -n "$CCC"; then + CXX_FOR_BUILD=$CCC + else + if test -n "$ac_tool_prefix"; then + for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC clang++ + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_CXX_FOR_BUILD+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$CXX_FOR_BUILD"; then + ac_cv_prog_CXX_FOR_BUILD="$CXX_FOR_BUILD" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_CXX_FOR_BUILD="$ac_tool_prefix$ac_prog" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CXX_FOR_BUILD=$ac_cv_prog_CXX_FOR_BUILD +if test -n "$CXX_FOR_BUILD"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CXX_FOR_BUILD" >&5 +printf "%s\n" "$CXX_FOR_BUILD" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + + test -n "$CXX_FOR_BUILD" && break + done +fi +if test -z "$CXX_FOR_BUILD"; then + ac_ct_CXX_FOR_BUILD=$CXX_FOR_BUILD + for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC clang++ +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_CXX_FOR_BUILD+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$ac_ct_CXX_FOR_BUILD"; then + ac_cv_prog_ac_ct_CXX_FOR_BUILD="$ac_ct_CXX_FOR_BUILD" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CXX_FOR_BUILD="$ac_prog" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CXX_FOR_BUILD=$ac_cv_prog_ac_ct_CXX_FOR_BUILD +if test -n "$ac_ct_CXX_FOR_BUILD"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX_FOR_BUILD" >&5 +printf "%s\n" "$ac_ct_CXX_FOR_BUILD" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + + test -n "$ac_ct_CXX_FOR_BUILD" && break +done + + if test "x$ac_ct_CXX_FOR_BUILD" = x; then + CXX_FOR_BUILD="g++" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with build triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with build triplet" >&2;} +ac_tool_warned=yes ;; +esac + CXX_FOR_BUILD=$ac_ct_CXX_FOR_BUILD + fi +fi + + fi +fi +# Provide some information about the compiler. +printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5 +set X $ac_build_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +printf "%s\n" "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports GNU C++" >&5 +printf %s "checking whether the compiler supports GNU C++... " >&6; } +if test ${ac_cv_cxx_compiler_gnu+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO" +then : + ac_compiler_gnu=yes +else $as_nop + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +ac_cv_cxx_compiler_gnu=$ac_compiler_gnu + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5 +printf "%s\n" "$ac_cv_cxx_compiler_gnu" >&6; } +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + +if test $ac_compiler_gnu = yes; then + GXX=yes +else + GXX= +fi +ac_test_CXXFLAGS=${CXXFLAGS_FOR_BUILD+y} +ac_save_CXXFLAGS=$CXXFLAGS_FOR_BUILD +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CXX_FOR_BUILD accepts -g" >&5 +printf %s "checking whether $CXX_FOR_BUILD accepts -g... " >&6; } +if test ${ac_cv_build_prog_cxx_g+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_save_cxx_werror_flag=$ac_cxx_werror_flag + ac_cxx_werror_flag=yes + ac_cv_build_prog_cxx_g=no + CXXFLAGS_FOR_BUILD="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO" +then : + ac_cv_build_prog_cxx_g=yes +else $as_nop + CXXFLAGS_FOR_BUILD="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO" +then : + +else $as_nop + ac_cxx_werror_flag=$ac_save_cxx_werror_flag + CXXFLAGS_FOR_BUILD="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO" +then : + ac_cv_build_prog_cxx_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ac_cxx_werror_flag=$ac_save_cxx_werror_flag +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build_prog_cxx_g" >&5 +printf "%s\n" "$ac_cv_build_prog_cxx_g" >&6; } +if test $ac_test_CXXFLAGS; then + CXXFLAGS_FOR_BUILD=$ac_save_CXXFLAGS +elif test $ac_cv_build_prog_cxx_g = yes; then + if test "$GXX" = yes; then + CXXFLAGS_FOR_BUILD="-g -O2" + else + CXXFLAGS_FOR_BUILD="-g" + fi +else + if test "$GXX" = yes; then + CXXFLAGS_FOR_BUILD="-O2" + else + CXXFLAGS_FOR_BUILD= + fi +fi +ac_prog_cxx_stdcxx=no +if test x$ac_prog_cxx_stdcxx = xno +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CXX_FOR_BUILD option to enable C++11 features" >&5 +printf %s "checking for $CXX_FOR_BUILD option to enable C++11 features... " >&6; } +if test ${ac_cv_prog_cxx_11+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_cv_prog_cxx_11=no +ac_save_CXX=$CXX_FOR_BUILD +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_cxx_conftest_cxx11_program +_ACEOF +for ac_arg in '' -std=gnu++11 -std=gnu++0x -std=c++11 -std=c++0x -qlanglvl=extended0x -AA +do + CXX_FOR_BUILD="$ac_save_CXX $ac_arg" + if ac_fn_cxx_try_compile "$LINENO" +then : + ac_cv_prog_cxx_cxx11=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam + test "x$ac_cv_prog_cxx_cxx11" != "xno" && break +done +rm -f conftest.$ac_ext +CXX_FOR_BUILD=$ac_save_CXX +fi + +if test "x$ac_cv_prog_cxx_cxx11" = xno +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +printf "%s\n" "unsupported" >&6; } +else $as_nop + if test "x$ac_cv_prog_cxx_cxx11" = x +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +printf "%s\n" "none needed" >&6; } +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_cxx11" >&5 +printf "%s\n" "$ac_cv_prog_cxx_cxx11" >&6; } + CXX_FOR_BUILD="$CXX_FOR_BUILD $ac_cv_prog_cxx_cxx11" +fi + ac_cv_prog_cxx_stdcxx=$ac_cv_prog_cxx_cxx11 + ac_prog_cxx_stdcxx=cxx11 +fi +fi +if test x$ac_prog_cxx_stdcxx = xno +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CXX_FOR_BUILD option to enable C++98 features" >&5 +printf %s "checking for $CXX_FOR_BUILD option to enable C++98 features... " >&6; } +if test ${ac_cv_prog_cxx_98+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_cv_prog_cxx_98=no +ac_save_CXX=$CXX_FOR_BUILD +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_cxx_conftest_cxx98_program +_ACEOF +for ac_arg in '' -std=gnu++98 -std=c++98 -qlanglvl=extended -AA +do + CXX_FOR_BUILD="$ac_save_CXX $ac_arg" + if ac_fn_cxx_try_compile "$LINENO" +then : + ac_cv_prog_cxx_cxx98=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam + test "x$ac_cv_prog_cxx_cxx98" != "xno" && break +done +rm -f conftest.$ac_ext +CXX_FOR_BUILD=$ac_save_CXX +fi + +if test "x$ac_cv_prog_cxx_cxx98" = xno +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +printf "%s\n" "unsupported" >&6; } +else $as_nop + if test "x$ac_cv_prog_cxx_cxx98" = x +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +printf "%s\n" "none needed" >&6; } +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_cxx98" >&5 +printf "%s\n" "$ac_cv_prog_cxx_cxx98" >&6; } + CXX_FOR_BUILD="$CXX_FOR_BUILD $ac_cv_prog_cxx_cxx98" +fi + ac_cv_prog_cxx_stdcxx=$ac_cv_prog_cxx_cxx98 + ac_prog_cxx_stdcxx=cxx98 +fi +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS_FOR_BUILD' +ac_build_compile='$CC -c $CFLAGS $CPPFLAGS_FOR_BUILD conftest.$ac_ext >&5' +ac_build_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS_FOR_BUILD $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +depcc="$CXX_FOR_BUILD" am_compiler_list= + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 +printf %s "checking dependency style of $depcc... " >&6; } +if test ${am_cv_CXX_dependencies_compiler_type+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named 'D' -- because '-MD' means "put the output + # in D". + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CXX_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + am__universal=false + case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with + # Solaris 10 /bin/sh. + echo '/* dummy */' > sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with '-c' and '-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle '-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs. + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # After this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested. + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok '-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CXX_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CXX_dependencies_compiler_type=none +fi + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_CXX_dependencies_compiler_type" >&5 +printf "%s\n" "$am_cv_CXX_dependencies_compiler_type" >&6; } +CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type + + if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then + am__fastdepCXX_TRUE= + am__fastdepCXX_FALSE='#' +else + am__fastdepCXX_TRUE='#' + am__fastdepCXX_FALSE= +fi + + +ac_ext=cpp +ac_cpp='$CXXCPP_FOR_BUILD $CPPFLAGS_FOR_BUILD' +ac_build_compile='$CXX_FOR_BUILD -c $CXXFLAGS_FOR_BUILD $CPPFLAGS_FOR_BUILD conftest.$ac_ext >&5' +ac_build_link='$CXX_FOR_BUILD -o conftest$ac_exeext $CXXFLAGS_FOR_BUILD $CPPFLAGS_FOR_BUILD $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to run the C++ preprocessor" >&5 +printf %s "checking how to run the C++ preprocessor... " >&6; } +if test -z "$CXXCPP_FOR_BUILD"; then + if test ${ac_cv_build_prog_CXXCPP+y} +then : + printf %s "(cached) " >&6 +else $as_nop + # Double quotes because $CXX needs to be expanded + for CXXCPP_FOR_BUILD in "$CXX_FOR_BUILD -E" cpp /lib/cpp + do + ac_preproc_ok=false +for ac_cxx_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + Syntax error +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO" +then : + +else $as_nop + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO" +then : + # Broken: success on invalid input. +continue +else $as_nop + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok +then : + break +fi + + done + ac_cv_build_prog_CXXCPP=$CXXCPP_FOR_BUILD + +fi + CXXCPP_FOR_BUILD=$ac_cv_build_prog_CXXCPP +else + ac_cv_build_prog_CXXCPP=$CXXCPP_FOR_BUILD +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CXXCPP_FOR_BUILD" >&5 +printf "%s\n" "$CXXCPP_FOR_BUILD" >&6; } +ac_preproc_ok=false +for ac_cxx_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + Syntax error +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO" +then : + +else $as_nop + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO" +then : + # Broken: success on invalid input. +continue +else $as_nop + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok +then : + +else $as_nop + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "C++ preprocessor \"$CXXCPP_FOR_BUILD\" fails sanity check +See \`config.log' for more details" "$LINENO" 5; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS_FOR_BUILD' +ac_build_compile='$CC -c $CFLAGS $CPPFLAGS_FOR_BUILD conftest.$ac_ext >&5' +ac_build_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS_FOR_BUILD $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +ac_tool_prefix=$save_ac_tool_prefix +cross_compiling=$save_cross_compiling + + + + +# extract_interface needs to be run on the build system. +# Since this is the only target that is being built, +# simply use the build compiler throughout. +# This ensures that the clang configure checks are +# performed using the right compiler. +CXX="$CXX_FOR_BUILD" +CXXCPP="$CXXCPP_FOR_BUILD" +EXEEXT="$BUILD_EXEEXT" +OBJEXT="$BUILD_OBJEXT" + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 +printf %s "checking for grep that handles long lines and -e... " >&6; } +if test ${ac_cv_path_GREP+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -z "$GREP"; then + ac_path_GREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_prog in grep ggrep + do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_GREP="$as_dir$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_GREP" || continue +# Check for GNU ac_path_GREP and select it if it is found. + # Check for GNU $ac_path_GREP +case `"$ac_path_GREP" --version 2>&1` in +*GNU*) + ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; +*) + ac_count=0 + printf %s 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + printf "%s\n" 'GREP' >> "conftest.nl" + "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_GREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_GREP="$ac_path_GREP" + ac_path_GREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_GREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_GREP"; then + as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_GREP=$GREP +fi + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 +printf "%s\n" "$ac_cv_path_GREP" >&6; } + GREP="$ac_cv_path_GREP" + + + echo $CXX | $GREP -e "-std=" > /dev/null 2> /dev/null + if test $? -eq 0; then + ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + ac_success=no + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CXX supports C++11 features by default" >&5 +printf %s "checking whether $CXX supports C++11 features by default... " >&6; } +if test ${ax_cv_cxx_compile_cxx11+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +// If the compiler admits that it is not ready for C++11, why torture it? +// Hopefully, this will speed up the test. + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 201103L + +#error "This is not a C++11 compiler" + +#else + +namespace cxx11 +{ + + namespace test_static_assert + { + + template + struct check + { + static_assert(sizeof(int) <= sizeof(T), "not big enough"); + }; + + } + + namespace test_final_override + { + + struct Base + { + virtual ~Base() {} + virtual void f() {} + }; + + struct Derived : public Base + { + virtual ~Derived() override {} + virtual void f() override {} + }; + + } + + namespace test_double_right_angle_brackets + { + + template < typename T > + struct check {}; + + typedef check single_type; + typedef check> double_type; + typedef check>> triple_type; + typedef check>>> quadruple_type; + + } + + namespace test_decltype + { + + int + f() + { + int a = 1; + decltype(a) b = 2; + return a + b; + } + + } + + namespace test_type_deduction + { + + template < typename T1, typename T2 > + struct is_same + { + static const bool value = false; + }; + + template < typename T > + struct is_same + { + static const bool value = true; + }; + + template < typename T1, typename T2 > + auto + add(T1 a1, T2 a2) -> decltype(a1 + a2) + { + return a1 + a2; + } + + int + test(const int c, volatile int v) + { + static_assert(is_same::value == true, ""); + static_assert(is_same::value == false, ""); + static_assert(is_same::value == false, ""); + auto ac = c; + auto av = v; + auto sumi = ac + av + 'x'; + auto sumf = ac + av + 1.0; + static_assert(is_same::value == true, ""); + static_assert(is_same::value == true, ""); + static_assert(is_same::value == true, ""); + static_assert(is_same::value == false, ""); + static_assert(is_same::value == true, ""); + return (sumf > 0.0) ? sumi : add(c, v); + } + + } + + namespace test_noexcept + { + + int f() { return 0; } + int g() noexcept { return 0; } + + static_assert(noexcept(f()) == false, ""); + static_assert(noexcept(g()) == true, ""); + + } + + namespace test_constexpr + { + + template < typename CharT > + unsigned long constexpr + strlen_c_r(const CharT *const s, const unsigned long acc) noexcept + { + return *s ? strlen_c_r(s + 1, acc + 1) : acc; + } + + template < typename CharT > + unsigned long constexpr + strlen_c(const CharT *const s) noexcept + { + return strlen_c_r(s, 0UL); + } + + static_assert(strlen_c("") == 0UL, ""); + static_assert(strlen_c("1") == 1UL, ""); + static_assert(strlen_c("example") == 7UL, ""); + static_assert(strlen_c("another\0example") == 7UL, ""); + + } + + namespace test_rvalue_references + { + + template < int N > + struct answer + { + static constexpr int value = N; + }; + + answer<1> f(int&) { return answer<1>(); } + answer<2> f(const int&) { return answer<2>(); } + answer<3> f(int&&) { return answer<3>(); } + + void + test() + { + int i = 0; + const int c = 0; + static_assert(decltype(f(i))::value == 1, ""); + static_assert(decltype(f(c))::value == 2, ""); + static_assert(decltype(f(0))::value == 3, ""); + } + + } + + namespace test_uniform_initialization + { + + struct test + { + static const int zero {}; + static const int one {1}; + }; + + static_assert(test::zero == 0, ""); + static_assert(test::one == 1, ""); + + } + + namespace test_lambdas + { + + void + test1() + { + auto lambda1 = [](){}; + auto lambda2 = lambda1; + lambda1(); + lambda2(); + } + + int + test2() + { + auto a = [](int i, int j){ return i + j; }(1, 2); + auto b = []() -> int { return '0'; }(); + auto c = [=](){ return a + b; }(); + auto d = [&](){ return c; }(); + auto e = [a, &b](int x) mutable { + const auto identity = [](int y){ return y; }; + for (auto i = 0; i < a; ++i) + a += b--; + return x + identity(a + b); + }(0); + return a + b + c + d + e; + } + + int + test3() + { + const auto nullary = [](){ return 0; }; + const auto unary = [](int x){ return x; }; + using nullary_t = decltype(nullary); + using unary_t = decltype(unary); + const auto higher1st = [](nullary_t f){ return f(); }; + const auto higher2nd = [unary](nullary_t f1){ + return [unary, f1](unary_t f2){ return f2(unary(f1())); }; + }; + return higher1st(nullary) + higher2nd(nullary)(unary); + } + + } + + namespace test_variadic_templates + { + + template + struct sum; + + template + struct sum + { + static constexpr auto value = N0 + sum::value; + }; + + template <> + struct sum<> + { + static constexpr auto value = 0; + }; + + static_assert(sum<>::value == 0, ""); + static_assert(sum<1>::value == 1, ""); + static_assert(sum<23>::value == 23, ""); + static_assert(sum<1, 2>::value == 3, ""); + static_assert(sum<5, 5, 11>::value == 21, ""); + static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, ""); + + } + + // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae + // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function + // because of this. + namespace test_template_alias_sfinae + { + + struct foo {}; + + template + using member = typename T::member_type; + + template + void func(...) {} + + template + void func(member*) {} + + void test(); + + void test() { func(0); } + + } + +} // namespace cxx11 + +#endif // __cplusplus >= 201103L + + + +_ACEOF +if ac_fn_cxx_try_compile "$LINENO" +then : + ax_cv_cxx_compile_cxx11=yes +else $as_nop + ax_cv_cxx_compile_cxx11=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_cxx_compile_cxx11" >&5 +printf "%s\n" "$ax_cv_cxx_compile_cxx11" >&6; } + if test x$ax_cv_cxx_compile_cxx11 = xyes; then + ac_success=yes + fi + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + if test x$ac_success = xno; then + HAVE_CXX11=0 + else + HAVE_CXX11=1 + +printf "%s\n" "#define HAVE_CXX11 1" >>confdefs.h + + fi + + + else + ax_cxx_compile_alternatives="11 0x" ax_cxx_compile_cxx11_required=false + ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + ac_success=no + + + + + + if test x$ac_success = xno; then + for alternative in ${ax_cxx_compile_alternatives}; do + for switch in -std=c++${alternative} +std=c++${alternative} "-h std=c++${alternative}"; do + cachevar=`printf "%s\n" "ax_cv_cxx_compile_cxx11_$switch" | $as_tr_sh` + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CXX supports C++11 features with $switch" >&5 +printf %s "checking whether $CXX supports C++11 features with $switch... " >&6; } +if eval test \${$cachevar+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_save_CXX="$CXX" + CXX="$CXX $switch" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +// If the compiler admits that it is not ready for C++11, why torture it? +// Hopefully, this will speed up the test. + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 201103L + +#error "This is not a C++11 compiler" + +#else + +namespace cxx11 +{ + + namespace test_static_assert + { + + template + struct check + { + static_assert(sizeof(int) <= sizeof(T), "not big enough"); + }; + + } + + namespace test_final_override + { + + struct Base + { + virtual ~Base() {} + virtual void f() {} + }; + + struct Derived : public Base + { + virtual ~Derived() override {} + virtual void f() override {} + }; + + } + + namespace test_double_right_angle_brackets + { + + template < typename T > + struct check {}; + + typedef check single_type; + typedef check> double_type; + typedef check>> triple_type; + typedef check>>> quadruple_type; + + } + + namespace test_decltype + { + + int + f() + { + int a = 1; + decltype(a) b = 2; + return a + b; + } + + } + + namespace test_type_deduction + { + + template < typename T1, typename T2 > + struct is_same + { + static const bool value = false; + }; + + template < typename T > + struct is_same + { + static const bool value = true; + }; + + template < typename T1, typename T2 > + auto + add(T1 a1, T2 a2) -> decltype(a1 + a2) + { + return a1 + a2; + } + + int + test(const int c, volatile int v) + { + static_assert(is_same::value == true, ""); + static_assert(is_same::value == false, ""); + static_assert(is_same::value == false, ""); + auto ac = c; + auto av = v; + auto sumi = ac + av + 'x'; + auto sumf = ac + av + 1.0; + static_assert(is_same::value == true, ""); + static_assert(is_same::value == true, ""); + static_assert(is_same::value == true, ""); + static_assert(is_same::value == false, ""); + static_assert(is_same::value == true, ""); + return (sumf > 0.0) ? sumi : add(c, v); + } + + } + + namespace test_noexcept + { + + int f() { return 0; } + int g() noexcept { return 0; } + + static_assert(noexcept(f()) == false, ""); + static_assert(noexcept(g()) == true, ""); + + } + + namespace test_constexpr + { + + template < typename CharT > + unsigned long constexpr + strlen_c_r(const CharT *const s, const unsigned long acc) noexcept + { + return *s ? strlen_c_r(s + 1, acc + 1) : acc; + } + + template < typename CharT > + unsigned long constexpr + strlen_c(const CharT *const s) noexcept + { + return strlen_c_r(s, 0UL); + } + + static_assert(strlen_c("") == 0UL, ""); + static_assert(strlen_c("1") == 1UL, ""); + static_assert(strlen_c("example") == 7UL, ""); + static_assert(strlen_c("another\0example") == 7UL, ""); + + } + + namespace test_rvalue_references + { + + template < int N > + struct answer + { + static constexpr int value = N; + }; + + answer<1> f(int&) { return answer<1>(); } + answer<2> f(const int&) { return answer<2>(); } + answer<3> f(int&&) { return answer<3>(); } + + void + test() + { + int i = 0; + const int c = 0; + static_assert(decltype(f(i))::value == 1, ""); + static_assert(decltype(f(c))::value == 2, ""); + static_assert(decltype(f(0))::value == 3, ""); + } + + } + + namespace test_uniform_initialization + { + + struct test + { + static const int zero {}; + static const int one {1}; + }; + + static_assert(test::zero == 0, ""); + static_assert(test::one == 1, ""); + + } + + namespace test_lambdas + { + + void + test1() + { + auto lambda1 = [](){}; + auto lambda2 = lambda1; + lambda1(); + lambda2(); + } + + int + test2() + { + auto a = [](int i, int j){ return i + j; }(1, 2); + auto b = []() -> int { return '0'; }(); + auto c = [=](){ return a + b; }(); + auto d = [&](){ return c; }(); + auto e = [a, &b](int x) mutable { + const auto identity = [](int y){ return y; }; + for (auto i = 0; i < a; ++i) + a += b--; + return x + identity(a + b); + }(0); + return a + b + c + d + e; + } + + int + test3() + { + const auto nullary = [](){ return 0; }; + const auto unary = [](int x){ return x; }; + using nullary_t = decltype(nullary); + using unary_t = decltype(unary); + const auto higher1st = [](nullary_t f){ return f(); }; + const auto higher2nd = [unary](nullary_t f1){ + return [unary, f1](unary_t f2){ return f2(unary(f1())); }; + }; + return higher1st(nullary) + higher2nd(nullary)(unary); + } + + } + + namespace test_variadic_templates + { + + template + struct sum; + + template + struct sum + { + static constexpr auto value = N0 + sum::value; + }; + + template <> + struct sum<> + { + static constexpr auto value = 0; + }; + + static_assert(sum<>::value == 0, ""); + static_assert(sum<1>::value == 1, ""); + static_assert(sum<23>::value == 23, ""); + static_assert(sum<1, 2>::value == 3, ""); + static_assert(sum<5, 5, 11>::value == 21, ""); + static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, ""); + + } + + // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae + // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function + // because of this. + namespace test_template_alias_sfinae + { + + struct foo {}; + + template + using member = typename T::member_type; + + template + void func(...) {} + + template + void func(member*) {} + + void test(); + + void test() { func(0); } + + } + +} // namespace cxx11 + +#endif // __cplusplus >= 201103L + + + +_ACEOF +if ac_fn_cxx_try_compile "$LINENO" +then : + eval $cachevar=yes +else $as_nop + eval $cachevar=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + CXX="$ac_save_CXX" +fi +eval ac_res=\$$cachevar + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } + if eval test x\$$cachevar = xyes; then + CXX="$CXX $switch" + if test -n "$CXXCPP" ; then + CXXCPP="$CXXCPP $switch" + fi + ac_success=yes + break + fi + done + if test x$ac_success = xyes; then + break + fi + done + fi + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + if test x$ax_cxx_compile_cxx11_required = xtrue; then + if test x$ac_success = xno; then + as_fn_error $? "*** A compiler with support for C++11 language features is required." "$LINENO" 5 + fi + fi + if test x$ac_success = xno; then + HAVE_CXX11=0 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: No compiler with C++11 support was found" >&5 +printf "%s\n" "$as_me: No compiler with C++11 support was found" >&6;} + else + HAVE_CXX11=1 + +printf "%s\n" "#define HAVE_CXX11 1" >>confdefs.h + + fi + + + fi + + +# Check whether --enable-shared was given. +if test ${enable_shared+y} +then : + enableval=$enable_shared; p=${PACKAGE-default} + case $enableval in + yes) enable_shared=yes ;; + no) enable_shared=no ;; + *) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for pkg in $enableval; do + IFS=$lt_save_ifs + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS=$lt_save_ifs + ;; + esac +else $as_nop + enable_shared=no +fi + + + + + + + + + +case `pwd` in + *\ * | *\ *) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5 +printf "%s\n" "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;; +esac + + + +macro_version='2.4.6' +macro_revision='2.4.6' + + + + + + + + + + + + + + +ltmain=$ac_aux_dir/ltmain.sh + +# Backslashify metacharacters that are still active within +# double-quoted strings. +sed_quote_subst='s/\(["`$\\]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\(["`\\]\)/\\\1/g' + +# Sed substitution to delay expansion of an escaped shell variable in a +# double_quote_subst'ed string. +delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' + +# Sed substitution to delay expansion of an escaped single quote. +delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' + +# Sed substitution to avoid accidental globbing in evaled expressions +no_glob_subst='s/\*/\\\*/g' + +ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5 +printf %s "checking how to print strings... " >&6; } +# Test print first, because it will be a builtin if present. +if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ + test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='print -r --' +elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='printf %s\n' +else + # Use this function as a fallback that always works. + func_fallback_echo () + { + eval 'cat <<_LTECHO_EOF +$1 +_LTECHO_EOF' + } + ECHO='func_fallback_echo' +fi + +# func_echo_all arg... +# Invoke $ECHO with all args, space-separated. +func_echo_all () +{ + $ECHO "" +} + +case $ECHO in + printf*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: printf" >&5 +printf "%s\n" "printf" >&6; } ;; + print*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: print -r" >&5 +printf "%s\n" "print -r" >&6; } ;; + *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: cat" >&5 +printf "%s\n" "cat" >&6; } ;; +esac + + + + + + + + + + + + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 +printf %s "checking for a sed that does not truncate output... " >&6; } +if test ${ac_cv_path_SED+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ + for ac_i in 1 2 3 4 5 6 7; do + ac_script="$ac_script$as_nl$ac_script" + done + echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed + { ac_script=; unset ac_script;} + if test -z "$SED"; then + ac_path_SED_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_prog in sed gsed + do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_SED="$as_dir$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_SED" || continue +# Check for GNU ac_path_SED and select it if it is found. + # Check for GNU $ac_path_SED +case `"$ac_path_SED" --version 2>&1` in +*GNU*) + ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; +*) + ac_count=0 + printf %s 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + printf "%s\n" '' >> "conftest.nl" + "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_SED_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_SED="$ac_path_SED" + ac_path_SED_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_SED_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_SED"; then + as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 + fi +else + ac_cv_path_SED=$SED +fi + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 +printf "%s\n" "$ac_cv_path_SED" >&6; } + SED="$ac_cv_path_SED" + rm -f conftest.sed + +test -z "$SED" && SED=sed +Xsed="$SED -e 1s/^X//" + + + + + + + + + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 +printf %s "checking for egrep... " >&6; } +if test ${ac_cv_path_EGREP+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 + then ac_cv_path_EGREP="$GREP -E" + else + if test -z "$EGREP"; then + ac_path_EGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_prog in egrep + do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_EGREP="$as_dir$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_EGREP" || continue +# Check for GNU ac_path_EGREP and select it if it is found. + # Check for GNU $ac_path_EGREP +case `"$ac_path_EGREP" --version 2>&1` in +*GNU*) + ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; +*) + ac_count=0 + printf %s 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + printf "%s\n" 'EGREP' >> "conftest.nl" + "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_EGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_EGREP="$ac_path_EGREP" + ac_path_EGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_EGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_EGREP"; then + as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_EGREP=$EGREP +fi + + fi +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 +printf "%s\n" "$ac_cv_path_EGREP" >&6; } + EGREP="$ac_cv_path_EGREP" + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5 +printf %s "checking for fgrep... " >&6; } +if test ${ac_cv_path_FGREP+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1 + then ac_cv_path_FGREP="$GREP -F" + else + if test -z "$FGREP"; then + ac_path_FGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_prog in fgrep + do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_FGREP="$as_dir$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_FGREP" || continue +# Check for GNU ac_path_FGREP and select it if it is found. + # Check for GNU $ac_path_FGREP +case `"$ac_path_FGREP" --version 2>&1` in +*GNU*) + ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;; +*) + ac_count=0 + printf %s 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + printf "%s\n" 'FGREP' >> "conftest.nl" + "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_FGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_FGREP="$ac_path_FGREP" + ac_path_FGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_FGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_FGREP"; then + as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_FGREP=$FGREP +fi + + fi +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5 +printf "%s\n" "$ac_cv_path_FGREP" >&6; } + FGREP="$ac_cv_path_FGREP" + + +test -z "$GREP" && GREP=grep + + + + + + + + + + + + + + + + + + + +# Check whether --with-gnu-ld was given. +if test ${with_gnu_ld+y} +then : + withval=$with_gnu_ld; test no = "$withval" || with_gnu_ld=yes +else $as_nop + with_gnu_ld=no +fi + +ac_prog=ld +if test yes = "$GCC"; then + # Check if gcc -print-prog-name=ld gives a path. + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 +printf %s "checking for ld used by $CC... " >&6; } + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return, which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [\\/]* | ?:[\\/]*) + re_direlt='/[^/][^/]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` + while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do + ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD=$ac_prog + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test yes = "$with_gnu_ld"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 +printf %s "checking for GNU ld... " >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 +printf %s "checking for non-GNU ld... " >&6; } +fi +if test ${lt_cv_path_LD+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -z "$LD"; then + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS=$lt_save_ifs + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD=$ac_dir/$ac_prog + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 &5 +printf "%s\n" "$LD" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi +test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 +printf %s "checking if the linker ($LD) is GNU ld... " >&6; } +if test ${lt_cv_prog_gnu_ld+y} +then : + printf %s "(cached) " >&6 +else $as_nop + # I'd rather use --version here, but apparently some GNU lds only accept -v. +case `$LD -v 2>&1 &5 +printf "%s\n" "$lt_cv_prog_gnu_ld" >&6; } +with_gnu_ld=$lt_cv_prog_gnu_ld + + + + + + + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5 +printf %s "checking for BSD- or MS-compatible name lister (nm)... " >&6; } +if test ${lt_cv_path_NM+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$NM"; then + # Let the user override the test. + lt_cv_path_NM=$NM +else + lt_nm_to_check=${ac_tool_prefix}nm + if test -n "$ac_tool_prefix" && test "$build" = "$host"; then + lt_nm_to_check="$lt_nm_to_check nm" + fi + for lt_tmp_nm in $lt_nm_to_check; do + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR + for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do + IFS=$lt_save_ifs + test -z "$ac_dir" && ac_dir=. + tmp_nm=$ac_dir/$lt_tmp_nm + if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext"; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the 'sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + # Tru64's nm complains that /dev/null is an invalid object file + # MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty + case $build_os in + mingw*) lt_bad_file=conftest.nm/nofile ;; + *) lt_bad_file=/dev/null ;; + esac + case `"$tmp_nm" -B $lt_bad_file 2>&1 | sed '1q'` in + *$lt_bad_file* | *'Invalid file or object type'*) + lt_cv_path_NM="$tmp_nm -B" + break 2 + ;; + *) + case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in + */dev/null*) + lt_cv_path_NM="$tmp_nm -p" + break 2 + ;; + *) + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + ;; + esac + ;; + esac + fi + done + IFS=$lt_save_ifs + done + : ${lt_cv_path_NM=no} +fi +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5 +printf "%s\n" "$lt_cv_path_NM" >&6; } +if test no != "$lt_cv_path_NM"; then + NM=$lt_cv_path_NM +else + # Didn't find any BSD compatible name lister, look for dumpbin. + if test -n "$DUMPBIN"; then : + # Let the user override the test. + else + if test -n "$ac_tool_prefix"; then + for ac_prog in dumpbin "link -dump" + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_DUMPBIN+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$DUMPBIN"; then + ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DUMPBIN=$ac_cv_prog_DUMPBIN +if test -n "$DUMPBIN"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5 +printf "%s\n" "$DUMPBIN" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + + test -n "$DUMPBIN" && break + done +fi +if test -z "$DUMPBIN"; then + ac_ct_DUMPBIN=$DUMPBIN + for ac_prog in dumpbin "link -dump" +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_DUMPBIN+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$ac_ct_DUMPBIN"; then + ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_DUMPBIN="$ac_prog" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN +if test -n "$ac_ct_DUMPBIN"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5 +printf "%s\n" "$ac_ct_DUMPBIN" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + + test -n "$ac_ct_DUMPBIN" && break +done + + if test "x$ac_ct_DUMPBIN" = x; then + DUMPBIN=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DUMPBIN=$ac_ct_DUMPBIN + fi +fi + + case `$DUMPBIN -symbols -headers /dev/null 2>&1 | sed '1q'` in + *COFF*) + DUMPBIN="$DUMPBIN -symbols -headers" + ;; + *) + DUMPBIN=: + ;; + esac + fi + + if test : != "$DUMPBIN"; then + NM=$DUMPBIN + fi +fi +test -z "$NM" && NM=nm + + + + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5 +printf %s "checking the name lister ($NM) interface... " >&6; } +if test ${lt_cv_nm_interface+y} +then : + printf %s "(cached) " >&6 +else $as_nop + lt_cv_nm_interface="BSD nm" + echo "int some_variable = 0;" > conftest.$ac_ext + (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5) + (eval "$ac_compile" 2>conftest.err) + cat conftest.err >&5 + (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5) + (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) + cat conftest.err >&5 + (eval echo "\"\$as_me:$LINENO: output\"" >&5) + cat conftest.out >&5 + if $GREP 'External.*some_variable' conftest.out > /dev/null; then + lt_cv_nm_interface="MS dumpbin" + fi + rm -f conftest* +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5 +printf "%s\n" "$lt_cv_nm_interface" >&6; } + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 +printf %s "checking whether ln -s works... " >&6; } +LN_S=$as_ln_s +if test "$LN_S" = "ln -s"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 +printf "%s\n" "no, using $LN_S" >&6; } +fi + +# find the maximum length of command line arguments +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5 +printf %s "checking the maximum length of command line arguments... " >&6; } +if test ${lt_cv_sys_max_cmd_len+y} +then : + printf %s "(cached) " >&6 +else $as_nop + i=0 + teststring=ABCD + + case $build_os in + msdosdjgpp*) + # On DJGPP, this test can blow up pretty badly due to problems in libc + # (any single argument exceeding 2000 bytes causes a buffer overrun + # during glob expansion). Even if it were fixed, the result of this + # check would be larger than it should be. + lt_cv_sys_max_cmd_len=12288; # 12K is about right + ;; + + gnu*) + # Under GNU Hurd, this test is not required because there is + # no limit to the length of command line arguments. + # Libtool will interpret -1 as no limit whatsoever + lt_cv_sys_max_cmd_len=-1; + ;; + + cygwin* | mingw* | cegcc*) + # On Win9x/ME, this test blows up -- it succeeds, but takes + # about 5 minutes as the teststring grows exponentially. + # Worse, since 9x/ME are not pre-emptively multitasking, + # you end up with a "frozen" computer, even though with patience + # the test eventually succeeds (with a max line length of 256k). + # Instead, let's just punt: use the minimum linelength reported by + # all of the supported platforms: 8192 (on NT/2K/XP). + lt_cv_sys_max_cmd_len=8192; + ;; + + mint*) + # On MiNT this can take a long time and run out of memory. + lt_cv_sys_max_cmd_len=8192; + ;; + + amigaos*) + # On AmigaOS with pdksh, this test takes hours, literally. + # So we just punt and use a minimum line length of 8192. + lt_cv_sys_max_cmd_len=8192; + ;; + + bitrig* | darwin* | dragonfly* | freebsd* | netbsd* | openbsd*) + # This has been around since 386BSD, at least. Likely further. + if test -x /sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` + elif test -x /usr/sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` + else + lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs + fi + # And add a safety zone + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + ;; + + interix*) + # We know the value 262144 and hardcode it with a safety zone (like BSD) + lt_cv_sys_max_cmd_len=196608 + ;; + + os2*) + # The test takes a long time on OS/2. + lt_cv_sys_max_cmd_len=8192 + ;; + + osf*) + # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure + # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not + # nice to cause kernel panics so lets avoid the loop below. + # First set a reasonable default. + lt_cv_sys_max_cmd_len=16384 + # + if test -x /sbin/sysconfig; then + case `/sbin/sysconfig -q proc exec_disable_arg_limit` in + *1*) lt_cv_sys_max_cmd_len=-1 ;; + esac + fi + ;; + sco3.2v5*) + lt_cv_sys_max_cmd_len=102400 + ;; + sysv5* | sco5v6* | sysv4.2uw2*) + kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` + if test -n "$kargmax"; then + lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'` + else + lt_cv_sys_max_cmd_len=32768 + fi + ;; + *) + lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` + if test -n "$lt_cv_sys_max_cmd_len" && \ + test undefined != "$lt_cv_sys_max_cmd_len"; then + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + else + # Make teststring a little bigger before we do anything with it. + # a 1K string should be a reasonable start. + for i in 1 2 3 4 5 6 7 8; do + teststring=$teststring$teststring + done + SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} + # If test is not a shell built-in, we'll probably end up computing a + # maximum length that is only half of the actual maximum length, but + # we can't tell. + while { test X`env echo "$teststring$teststring" 2>/dev/null` \ + = "X$teststring$teststring"; } >/dev/null 2>&1 && + test 17 != "$i" # 1/2 MB should be enough + do + i=`expr $i + 1` + teststring=$teststring$teststring + done + # Only check the string length outside the loop. + lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` + teststring= + # Add a significant safety factor because C++ compilers can tack on + # massive amounts of additional arguments before passing them to the + # linker. It appears as though 1/2 is a usable value. + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` + fi + ;; + esac + +fi + +if test -n "$lt_cv_sys_max_cmd_len"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5 +printf "%s\n" "$lt_cv_sys_max_cmd_len" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none" >&5 +printf "%s\n" "none" >&6; } +fi +max_cmd_len=$lt_cv_sys_max_cmd_len + + + + + + +: ${CP="cp -f"} +: ${MV="mv -f"} +: ${RM="rm -f"} + +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + lt_unset=unset +else + lt_unset=false +fi + + + + + +# test EBCDIC or ASCII +case `echo X|tr X '\101'` in + A) # ASCII based system + # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr + lt_SP2NL='tr \040 \012' + lt_NL2SP='tr \015\012 \040\040' + ;; + *) # EBCDIC based system + lt_SP2NL='tr \100 \n' + lt_NL2SP='tr \r\n \100\100' + ;; +esac + + + + + + + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to $host format" >&5 +printf %s "checking how to convert $build file names to $host format... " >&6; } +if test ${lt_cv_to_host_file_cmd+y} +then : + printf %s "(cached) " >&6 +else $as_nop + case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 + ;; + esac + ;; + *-*-cygwin* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin + ;; + esac + ;; + * ) # unhandled hosts (and "normal" native builds) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; +esac + +fi + +to_host_file_cmd=$lt_cv_to_host_file_cmd +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5 +printf "%s\n" "$lt_cv_to_host_file_cmd" >&6; } + + + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5 +printf %s "checking how to convert $build file names to toolchain format... " >&6; } +if test ${lt_cv_to_tool_file_cmd+y} +then : + printf %s "(cached) " >&6 +else $as_nop + #assume ordinary cross tools, or native build. +lt_cv_to_tool_file_cmd=func_convert_file_noop +case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 + ;; + esac + ;; +esac + +fi + +to_tool_file_cmd=$lt_cv_to_tool_file_cmd +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5 +printf "%s\n" "$lt_cv_to_tool_file_cmd" >&6; } + + + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5 +printf %s "checking for $LD option to reload object files... " >&6; } +if test ${lt_cv_ld_reload_flag+y} +then : + printf %s "(cached) " >&6 +else $as_nop + lt_cv_ld_reload_flag='-r' +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5 +printf "%s\n" "$lt_cv_ld_reload_flag" >&6; } +reload_flag=$lt_cv_ld_reload_flag +case $reload_flag in +"" | " "*) ;; +*) reload_flag=" $reload_flag" ;; +esac +reload_cmds='$LD$reload_flag -o $output$reload_objs' +case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + if test yes != "$GCC"; then + reload_cmds=false + fi + ;; + darwin*) + if test yes = "$GCC"; then + reload_cmds='$LTCC $LTCFLAGS -nostdlib $wl-r -o $output$reload_objs' + else + reload_cmds='$LD$reload_flag -o $output$reload_objs' + fi + ;; +esac + + + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. +set dummy ${ac_tool_prefix}objdump; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_OBJDUMP+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$OBJDUMP"; then + ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OBJDUMP=$ac_cv_prog_OBJDUMP +if test -n "$OBJDUMP"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 +printf "%s\n" "$OBJDUMP" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OBJDUMP"; then + ac_ct_OBJDUMP=$OBJDUMP + # Extract the first word of "objdump", so it can be a program name with args. +set dummy objdump; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_OBJDUMP+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$ac_ct_OBJDUMP"; then + ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_OBJDUMP="objdump" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP +if test -n "$ac_ct_OBJDUMP"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 +printf "%s\n" "$ac_ct_OBJDUMP" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + if test "x$ac_ct_OBJDUMP" = x; then + OBJDUMP="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OBJDUMP=$ac_ct_OBJDUMP + fi +else + OBJDUMP="$ac_cv_prog_OBJDUMP" +fi + +test -z "$OBJDUMP" && OBJDUMP=objdump + + + + + + + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5 +printf %s "checking how to recognize dependent libraries... " >&6; } +if test ${lt_cv_deplibs_check_method+y} +then : + printf %s "(cached) " >&6 +else $as_nop + lt_cv_file_magic_cmd='$MAGIC_CMD' +lt_cv_file_magic_test_file= +lt_cv_deplibs_check_method='unknown' +# Need to set the preceding variable on all platforms that support +# interlibrary dependencies. +# 'none' -- dependencies not supported. +# 'unknown' -- same as none, but documents that we really don't know. +# 'pass_all' -- all dependencies passed with no checks. +# 'test_compile' -- check by making test program. +# 'file_magic [[regex]]' -- check by looking for files in library path +# that responds to the $file_magic_cmd with a given extended regex. +# If you have 'file' or equivalent on your system and you're not sure +# whether 'pass_all' will *always* work, you probably want this one. + +case $host_os in +aix[4-9]*) + lt_cv_deplibs_check_method=pass_all + ;; + +beos*) + lt_cv_deplibs_check_method=pass_all + ;; + +bsdi[45]*) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' + lt_cv_file_magic_cmd='/usr/bin/file -L' + lt_cv_file_magic_test_file=/shlib/libc.so + ;; + +cygwin*) + # func_win32_libid is a shell function defined in ltmain.sh + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + ;; + +mingw* | pw32*) + # Base MSYS/MinGW do not provide the 'file' command needed by + # func_win32_libid shell function, so use a weaker test based on 'objdump', + # unless we find 'file', for example because we are cross-compiling. + if ( file / ) >/dev/null 2>&1; then + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + else + # Keep this pattern in sync with the one in func_win32_libid. + lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' + lt_cv_file_magic_cmd='$OBJDUMP -f' + fi + ;; + +cegcc*) + # use the weaker test based on 'objdump'. See mingw*. + lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + ;; + +darwin* | rhapsody*) + lt_cv_deplibs_check_method=pass_all + ;; + +freebsd* | dragonfly*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + case $host_cpu in + i*86 ) + # Not sure whether the presence of OpenBSD here was a mistake. + # Let's accept both of them until this is cleared up. + lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + ;; + esac + else + lt_cv_deplibs_check_method=pass_all + fi + ;; + +haiku*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20* | hpux11*) + lt_cv_file_magic_cmd=/usr/bin/file + case $host_cpu in + ia64*) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64' + lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so + ;; + hppa*64*) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]' + lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl + ;; + *) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library' + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + esac + ;; + +interix[3-9]*) + # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$' + ;; + +irix5* | irix6* | nonstopux*) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$' + fi + ;; + +newos6*) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +*nto* | *qnx*) + lt_cv_deplibs_check_method=pass_all + ;; + +openbsd* | bitrig*) + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' + fi + ;; + +osf3* | osf4* | osf5*) + lt_cv_deplibs_check_method=pass_all + ;; + +rdos*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv4 | sysv4.3*) + case $host_vendor in + motorola) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + ncr) + lt_cv_deplibs_check_method=pass_all + ;; + sequent) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' + ;; + sni) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib" + lt_cv_file_magic_test_file=/lib/libc.so + ;; + siemens) + lt_cv_deplibs_check_method=pass_all + ;; + pc) + lt_cv_deplibs_check_method=pass_all + ;; + esac + ;; + +tpf*) + lt_cv_deplibs_check_method=pass_all + ;; +os2*) + lt_cv_deplibs_check_method=pass_all + ;; +esac + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5 +printf "%s\n" "$lt_cv_deplibs_check_method" >&6; } + +file_magic_glob= +want_nocaseglob=no +if test "$build" = "$host"; then + case $host_os in + mingw* | pw32*) + if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then + want_nocaseglob=yes + else + file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[\1]\/[\1]\/g;/g"` + fi + ;; + esac +fi + +file_magic_cmd=$lt_cv_file_magic_cmd +deplibs_check_method=$lt_cv_deplibs_check_method +test -z "$deplibs_check_method" && deplibs_check_method=unknown + + + + + + + + + + + + + + + + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args. +set dummy ${ac_tool_prefix}dlltool; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_DLLTOOL+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$DLLTOOL"; then + ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DLLTOOL=$ac_cv_prog_DLLTOOL +if test -n "$DLLTOOL"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5 +printf "%s\n" "$DLLTOOL" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_DLLTOOL"; then + ac_ct_DLLTOOL=$DLLTOOL + # Extract the first word of "dlltool", so it can be a program name with args. +set dummy dlltool; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_DLLTOOL+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$ac_ct_DLLTOOL"; then + ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_DLLTOOL="dlltool" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL +if test -n "$ac_ct_DLLTOOL"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5 +printf "%s\n" "$ac_ct_DLLTOOL" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + if test "x$ac_ct_DLLTOOL" = x; then + DLLTOOL="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DLLTOOL=$ac_ct_DLLTOOL + fi +else + DLLTOOL="$ac_cv_prog_DLLTOOL" +fi + +test -z "$DLLTOOL" && DLLTOOL=dlltool + + + + + + + + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5 +printf %s "checking how to associate runtime and link libraries... " >&6; } +if test ${lt_cv_sharedlib_from_linklib_cmd+y} +then : + printf %s "(cached) " >&6 +else $as_nop + lt_cv_sharedlib_from_linklib_cmd='unknown' + +case $host_os in +cygwin* | mingw* | pw32* | cegcc*) + # two different shell functions defined in ltmain.sh; + # decide which one to use based on capabilities of $DLLTOOL + case `$DLLTOOL --help 2>&1` in + *--identify-strict*) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib + ;; + *) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback + ;; + esac + ;; +*) + # fallback: assume linklib IS sharedlib + lt_cv_sharedlib_from_linklib_cmd=$ECHO + ;; +esac + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5 +printf "%s\n" "$lt_cv_sharedlib_from_linklib_cmd" >&6; } +sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd +test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO + + + + + + + + +if test -n "$ac_tool_prefix"; then + for ac_prog in ar + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_AR+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$AR"; then + ac_cv_prog_AR="$AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_AR="$ac_tool_prefix$ac_prog" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AR=$ac_cv_prog_AR +if test -n "$AR"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 +printf "%s\n" "$AR" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + + test -n "$AR" && break + done +fi +if test -z "$AR"; then + ac_ct_AR=$AR + for ac_prog in ar +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_AR+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$ac_ct_AR"; then + ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_AR="$ac_prog" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_AR=$ac_cv_prog_ac_ct_AR +if test -n "$ac_ct_AR"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 +printf "%s\n" "$ac_ct_AR" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + + test -n "$ac_ct_AR" && break +done + + if test "x$ac_ct_AR" = x; then + AR="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + AR=$ac_ct_AR + fi +fi + +: ${AR=ar} +: ${AR_FLAGS=cr} + + + + + + + + + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5 +printf %s "checking for archiver @FILE support... " >&6; } +if test ${lt_cv_ar_at_file+y} +then : + printf %s "(cached) " >&6 +else $as_nop + lt_cv_ar_at_file=no + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + echo conftest.$ac_objext > conftest.lst + lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5' + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 + (eval $lt_ar_try) 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if test 0 -eq "$ac_status"; then + # Ensure the archiver fails upon bogus file names. + rm -f conftest.$ac_objext libconftest.a + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 + (eval $lt_ar_try) 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if test 0 -ne "$ac_status"; then + lt_cv_ar_at_file=@ + fi + fi + rm -f conftest.* libconftest.a + +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5 +printf "%s\n" "$lt_cv_ar_at_file" >&6; } + +if test no = "$lt_cv_ar_at_file"; then + archiver_list_spec= +else + archiver_list_spec=$lt_cv_ar_at_file +fi + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_STRIP+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 +printf "%s\n" "$STRIP" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_STRIP+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_STRIP="strip" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 +printf "%s\n" "$ac_ct_STRIP" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + +test -z "$STRIP" && STRIP=: + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_RANLIB+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +RANLIB=$ac_cv_prog_RANLIB +if test -n "$RANLIB"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 +printf "%s\n" "$RANLIB" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_RANLIB"; then + ac_ct_RANLIB=$RANLIB + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_RANLIB+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$ac_ct_RANLIB"; then + ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_RANLIB="ranlib" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB +if test -n "$ac_ct_RANLIB"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 +printf "%s\n" "$ac_ct_RANLIB" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + if test "x$ac_ct_RANLIB" = x; then + RANLIB=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + RANLIB=$ac_ct_RANLIB + fi +else + RANLIB="$ac_cv_prog_RANLIB" +fi + +test -z "$RANLIB" && RANLIB=: + + + + + + +# Determine commands to create old-style static archives. +old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' +old_postinstall_cmds='chmod 644 $oldlib' +old_postuninstall_cmds= + +if test -n "$RANLIB"; then + case $host_os in + bitrig* | openbsd*) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" + ;; + *) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" + ;; + esac + old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" +fi + +case $host_os in + darwin*) + lock_old_archive_extraction=yes ;; + *) + lock_old_archive_extraction=no ;; +esac + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + + +# Check for command to grab the raw symbol name followed by C symbol from nm. +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5 +printf %s "checking command to parse $NM output from $compiler object... " >&6; } +if test ${lt_cv_sys_global_symbol_pipe+y} +then : + printf %s "(cached) " >&6 +else $as_nop + +# These are sane defaults that work on at least a few old systems. +# [They come from Ultrix. What could be older than Ultrix?!! ;)] + +# Character class describing NM global symbol codes. +symcode='[BCDEGRST]' + +# Regexp to match symbols that can be accessed directly from C. +sympat='\([_A-Za-z][_A-Za-z0-9]*\)' + +# Define system-specific variables. +case $host_os in +aix*) + symcode='[BCDT]' + ;; +cygwin* | mingw* | pw32* | cegcc*) + symcode='[ABCDGISTW]' + ;; +hpux*) + if test ia64 = "$host_cpu"; then + symcode='[ABCDEGRST]' + fi + ;; +irix* | nonstopux*) + symcode='[BCDEGRST]' + ;; +osf*) + symcode='[BCDEGQRST]' + ;; +solaris*) + symcode='[BDRT]' + ;; +sco3.2v5*) + symcode='[DT]' + ;; +sysv4.2uw2*) + symcode='[DT]' + ;; +sysv5* | sco5v6* | unixware* | OpenUNIX*) + symcode='[ABDT]' + ;; +sysv4) + symcode='[DFNSTU]' + ;; +esac + +# If we're using GNU nm, then use its standard symbol codes. +case `$NM -V 2>&1` in +*GNU* | *'with BFD'*) + symcode='[ABCDGIRSTW]' ;; +esac + +if test "$lt_cv_nm_interface" = "MS dumpbin"; then + # Gets list of data symbols to import. + lt_cv_sys_global_symbol_to_import="sed -n -e 's/^I .* \(.*\)$/\1/p'" + # Adjust the below global symbol transforms to fixup imported variables. + lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'" + lt_c_name_hook=" -e 's/^I .* \(.*\)$/ {\"\1\", (void *) 0},/p'" + lt_c_name_lib_hook="\ + -e 's/^I .* \(lib.*\)$/ {\"\1\", (void *) 0},/p'\ + -e 's/^I .* \(.*\)$/ {\"lib\1\", (void *) 0},/p'" +else + # Disable hooks by default. + lt_cv_sys_global_symbol_to_import= + lt_cdecl_hook= + lt_c_name_hook= + lt_c_name_lib_hook= +fi + +# Transform an extracted symbol line into a proper C declaration. +# Some systems (esp. on ia64) link data and code symbols differently, +# so use this general approach. +lt_cv_sys_global_symbol_to_cdecl="sed -n"\ +$lt_cdecl_hook\ +" -e 's/^T .* \(.*\)$/extern int \1();/p'"\ +" -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'" + +# Transform an extracted symbol line into symbol name and symbol address +lt_cv_sys_global_symbol_to_c_name_address="sed -n"\ +$lt_c_name_hook\ +" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ +" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/p'" + +# Transform an extracted symbol line into symbol name with lib prefix and +# symbol address. +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n"\ +$lt_c_name_lib_hook\ +" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ +" -e 's/^$symcode$symcode* .* \(lib.*\)$/ {\"\1\", (void *) \&\1},/p'"\ +" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"lib\1\", (void *) \&\1},/p'" + +# Handle CRLF in mingw tool chain +opt_cr= +case $build_os in +mingw*) + opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp + ;; +esac + +# Try without a prefix underscore, then with it. +for ac_symprfx in "" "_"; do + + # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. + symxfrm="\\1 $ac_symprfx\\2 \\2" + + # Write the raw and C identifiers. + if test "$lt_cv_nm_interface" = "MS dumpbin"; then + # Fake it for dumpbin and say T for any non-static function, + # D for any global variable and I for any imported variable. + # Also find C++ and __fastcall symbols from MSVC++, + # which start with @ or ?. + lt_cv_sys_global_symbol_pipe="$AWK '"\ +" {last_section=section; section=\$ 3};"\ +" /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ +" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ +" /^ *Symbol name *: /{split(\$ 0,sn,\":\"); si=substr(sn[2],2)};"\ +" /^ *Type *: code/{print \"T\",si,substr(si,length(prfx))};"\ +" /^ *Type *: data/{print \"I\",si,substr(si,length(prfx))};"\ +" \$ 0!~/External *\|/{next};"\ +" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ +" {if(hide[section]) next};"\ +" {f=\"D\"}; \$ 0~/\(\).*\|/{f=\"T\"};"\ +" {split(\$ 0,a,/\||\r/); split(a[2],s)};"\ +" s[1]~/^[@?]/{print f,s[1],s[1]; next};"\ +" s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\ +" ' prfx=^$ac_symprfx" + else + lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" + fi + lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" + + # Check to see that the pipe works correctly. + pipe_works=no + + rm -f conftest* + cat > conftest.$ac_ext <<_LT_EOF +#ifdef __cplusplus +extern "C" { +#endif +char nm_test_var; +void nm_test_func(void); +void nm_test_func(void){} +#ifdef __cplusplus +} +#endif +int main(){nm_test_var='a';nm_test_func();return(0);} +_LT_EOF + + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + # Now try to grab the symbols. + nlist=conftest.nm + $ECHO "$as_me:$LINENO: $NM conftest.$ac_objext | $lt_cv_sys_global_symbol_pipe > $nlist" >&5 + if eval "$NM" conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist 2>&5 && test -s "$nlist"; then + # Try sorting and uniquifying the output. + if sort "$nlist" | uniq > "$nlist"T; then + mv -f "$nlist"T "$nlist" + else + rm -f "$nlist"T + fi + + # Make sure that we snagged all the symbols we need. + if $GREP ' nm_test_var$' "$nlist" >/dev/null; then + if $GREP ' nm_test_func$' "$nlist" >/dev/null; then + cat <<_LT_EOF > conftest.$ac_ext +/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ +#if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE +/* DATA imports from DLLs on WIN32 can't be const, because runtime + relocations are performed -- see ld's documentation on pseudo-relocs. */ +# define LT_DLSYM_CONST +#elif defined __osf__ +/* This system does not cope well with relocations in const data. */ +# define LT_DLSYM_CONST +#else +# define LT_DLSYM_CONST const +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +_LT_EOF + # Now generate the symbol file. + eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' + + cat <<_LT_EOF >> conftest.$ac_ext + +/* The mapping between symbol names and symbols. */ +LT_DLSYM_CONST struct { + const char *name; + void *address; +} +lt__PROGRAM__LTX_preloaded_symbols[] = +{ + { "@PROGRAM@", (void *) 0 }, +_LT_EOF + $SED "s/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext + cat <<\_LT_EOF >> conftest.$ac_ext + {0, (void *) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt__PROGRAM__LTX_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif +_LT_EOF + # Now try linking the two files. + mv conftest.$ac_objext conftstm.$ac_objext + lt_globsym_save_LIBS=$LIBS + lt_globsym_save_CFLAGS=$CFLAGS + LIBS=conftstm.$ac_objext + CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s conftest$ac_exeext; then + pipe_works=yes + fi + LIBS=$lt_globsym_save_LIBS + CFLAGS=$lt_globsym_save_CFLAGS + else + echo "cannot find nm_test_func in $nlist" >&5 + fi + else + echo "cannot find nm_test_var in $nlist" >&5 + fi + else + echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5 + fi + else + echo "$progname: failed program was:" >&5 + cat conftest.$ac_ext >&5 + fi + rm -rf conftest* conftst* + + # Do not use the global_symbol_pipe unless it works. + if test yes = "$pipe_works"; then + break + else + lt_cv_sys_global_symbol_pipe= + fi +done + +fi + +if test -z "$lt_cv_sys_global_symbol_pipe"; then + lt_cv_sys_global_symbol_to_cdecl= +fi +if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: failed" >&5 +printf "%s\n" "failed" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: ok" >&5 +printf "%s\n" "ok" >&6; } +fi + +# Response file support. +if test "$lt_cv_nm_interface" = "MS dumpbin"; then + nm_file_list_spec='@' +elif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then + nm_file_list_spec='@' +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5 +printf %s "checking for sysroot... " >&6; } + +# Check whether --with-sysroot was given. +if test ${with_sysroot+y} +then : + withval=$with_sysroot; +else $as_nop + with_sysroot=no +fi + + +lt_sysroot= +case $with_sysroot in #( + yes) + if test yes = "$GCC"; then + lt_sysroot=`$CC --print-sysroot 2>/dev/null` + fi + ;; #( + /*) + lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` + ;; #( + no|'') + ;; #( + *) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $with_sysroot" >&5 +printf "%s\n" "$with_sysroot" >&6; } + as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5 + ;; +esac + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5 +printf "%s\n" "${lt_sysroot:-no}" >&6; } + + + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a working dd" >&5 +printf %s "checking for a working dd... " >&6; } +if test ${ac_cv_path_lt_DD+y} +then : + printf %s "(cached) " >&6 +else $as_nop + printf 0123456789abcdef0123456789abcdef >conftest.i +cat conftest.i conftest.i >conftest2.i +: ${lt_DD:=$DD} +if test -z "$lt_DD"; then + ac_path_lt_DD_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_prog in dd + do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_lt_DD="$as_dir$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_lt_DD" || continue +if "$ac_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then + cmp -s conftest.i conftest.out \ + && ac_cv_path_lt_DD="$ac_path_lt_DD" ac_path_lt_DD_found=: +fi + $ac_path_lt_DD_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_lt_DD"; then + : + fi +else + ac_cv_path_lt_DD=$lt_DD +fi + +rm -f conftest.i conftest2.i conftest.out +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_lt_DD" >&5 +printf "%s\n" "$ac_cv_path_lt_DD" >&6; } + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to truncate binary pipes" >&5 +printf %s "checking how to truncate binary pipes... " >&6; } +if test ${lt_cv_truncate_bin+y} +then : + printf %s "(cached) " >&6 +else $as_nop + printf 0123456789abcdef0123456789abcdef >conftest.i +cat conftest.i conftest.i >conftest2.i +lt_cv_truncate_bin= +if "$ac_cv_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then + cmp -s conftest.i conftest.out \ + && lt_cv_truncate_bin="$ac_cv_path_lt_DD bs=4096 count=1" +fi +rm -f conftest.i conftest2.i conftest.out +test -z "$lt_cv_truncate_bin" && lt_cv_truncate_bin="$SED -e 4q" +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_truncate_bin" >&5 +printf "%s\n" "$lt_cv_truncate_bin" >&6; } + + + + + + + +# Calculate cc_basename. Skip known compiler wrappers and cross-prefix. +func_cc_basename () +{ + for cc_temp in $*""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac + done + func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` +} + +# Check whether --enable-libtool-lock was given. +if test ${enable_libtool_lock+y} +then : + enableval=$enable_libtool_lock; +fi + +test no = "$enable_libtool_lock" || enable_libtool_lock=yes + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case $host in +ia64-*-hpux*) + # Find out what ABI is being produced by ac_compile, and set mode + # options accordingly. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.$ac_objext` in + *ELF-32*) + HPUX_IA64_MODE=32 + ;; + *ELF-64*) + HPUX_IA64_MODE=64 + ;; + esac + fi + rm -rf conftest* + ;; +*-*-irix6*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. + echo '#line '$LINENO' "configure"' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + if test yes = "$lt_cv_prog_gnu_ld"; then + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -melf32bsmip" + ;; + *N32*) + LD="${LD-ld} -melf32bmipn32" + ;; + *64-bit*) + LD="${LD-ld} -melf64bmip" + ;; + esac + else + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + fi + rm -rf conftest* + ;; + +mips64*-*linux*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. + echo '#line '$LINENO' "configure"' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + emul=elf + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + emul="${emul}32" + ;; + *64-bit*) + emul="${emul}64" + ;; + esac + case `/usr/bin/file conftest.$ac_objext` in + *MSB*) + emul="${emul}btsmip" + ;; + *LSB*) + emul="${emul}ltsmip" + ;; + esac + case `/usr/bin/file conftest.$ac_objext` in + *N32*) + emul="${emul}n32" + ;; + esac + LD="${LD-ld} -m $emul" + fi + rm -rf conftest* + ;; + +x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ +s390*-*linux*|s390*-*tpf*|sparc*-*linux*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. Note that the listed cases only cover the + # situations where additional linker options are needed (such as when + # doing 32-bit compilation for a host where ld defaults to 64-bit, or + # vice versa); the common cases where no linker options are needed do + # not appear in the list. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.o` in + *32-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_i386_fbsd" + ;; + x86_64-*linux*) + case `/usr/bin/file conftest.o` in + *x86-64*) + LD="${LD-ld} -m elf32_x86_64" + ;; + *) + LD="${LD-ld} -m elf_i386" + ;; + esac + ;; + powerpc64le-*linux*) + LD="${LD-ld} -m elf32lppclinux" + ;; + powerpc64-*linux*) + LD="${LD-ld} -m elf32ppclinux" + ;; + s390x-*linux*) + LD="${LD-ld} -m elf_s390" + ;; + sparc64-*linux*) + LD="${LD-ld} -m elf32_sparc" + ;; + esac + ;; + *64-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_x86_64_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_x86_64" + ;; + powerpcle-*linux*) + LD="${LD-ld} -m elf64lppc" + ;; + powerpc-*linux*) + LD="${LD-ld} -m elf64ppc" + ;; + s390*-*linux*|s390*-*tpf*) + LD="${LD-ld} -m elf64_s390" + ;; + sparc*-*linux*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS=$CFLAGS + CFLAGS="$CFLAGS -belf" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5 +printf %s "checking whether the C compiler needs -belf... " >&6; } +if test ${lt_cv_cc_needs_belf+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + lt_cv_cc_needs_belf=yes +else $as_nop + lt_cv_cc_needs_belf=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5 +printf "%s\n" "$lt_cv_cc_needs_belf" >&6; } + if test yes != "$lt_cv_cc_needs_belf"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS=$SAVE_CFLAGS + fi + ;; +*-*solaris*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.o` in + *64-bit*) + case $lt_cv_prog_gnu_ld in + yes*) + case $host in + i?86-*-solaris*|x86_64-*-solaris*) + LD="${LD-ld} -m elf_x86_64" + ;; + sparc*-*-solaris*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + # GNU ld 2.21 introduced _sol2 emulations. Use them if available. + if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then + LD=${LD-ld}_sol2 + fi + ;; + *) + if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then + LD="${LD-ld} -64" + fi + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; +esac + +need_locks=$enable_libtool_lock + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args. +set dummy ${ac_tool_prefix}mt; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_MANIFEST_TOOL+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$MANIFEST_TOOL"; then + ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL +if test -n "$MANIFEST_TOOL"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5 +printf "%s\n" "$MANIFEST_TOOL" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_MANIFEST_TOOL"; then + ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL + # Extract the first word of "mt", so it can be a program name with args. +set dummy mt; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_MANIFEST_TOOL+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$ac_ct_MANIFEST_TOOL"; then + ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_MANIFEST_TOOL="mt" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL +if test -n "$ac_ct_MANIFEST_TOOL"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5 +printf "%s\n" "$ac_ct_MANIFEST_TOOL" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + if test "x$ac_ct_MANIFEST_TOOL" = x; then + MANIFEST_TOOL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL + fi +else + MANIFEST_TOOL="$ac_cv_prog_MANIFEST_TOOL" +fi + +test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5 +printf %s "checking if $MANIFEST_TOOL is a manifest tool... " >&6; } +if test ${lt_cv_path_mainfest_tool+y} +then : + printf %s "(cached) " >&6 +else $as_nop + lt_cv_path_mainfest_tool=no + echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5 + $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out + cat conftest.err >&5 + if $GREP 'Manifest Tool' conftest.out > /dev/null; then + lt_cv_path_mainfest_tool=yes + fi + rm -f conftest* +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5 +printf "%s\n" "$lt_cv_path_mainfest_tool" >&6; } +if test yes != "$lt_cv_path_mainfest_tool"; then + MANIFEST_TOOL=: +fi + + + + + + + case $host_os in + rhapsody* | darwin*) + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args. +set dummy ${ac_tool_prefix}dsymutil; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_DSYMUTIL+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$DSYMUTIL"; then + ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DSYMUTIL=$ac_cv_prog_DSYMUTIL +if test -n "$DSYMUTIL"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5 +printf "%s\n" "$DSYMUTIL" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_DSYMUTIL"; then + ac_ct_DSYMUTIL=$DSYMUTIL + # Extract the first word of "dsymutil", so it can be a program name with args. +set dummy dsymutil; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_DSYMUTIL+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$ac_ct_DSYMUTIL"; then + ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_DSYMUTIL="dsymutil" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL +if test -n "$ac_ct_DSYMUTIL"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5 +printf "%s\n" "$ac_ct_DSYMUTIL" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + if test "x$ac_ct_DSYMUTIL" = x; then + DSYMUTIL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DSYMUTIL=$ac_ct_DSYMUTIL + fi +else + DSYMUTIL="$ac_cv_prog_DSYMUTIL" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args. +set dummy ${ac_tool_prefix}nmedit; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_NMEDIT+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$NMEDIT"; then + ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +NMEDIT=$ac_cv_prog_NMEDIT +if test -n "$NMEDIT"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5 +printf "%s\n" "$NMEDIT" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_NMEDIT"; then + ac_ct_NMEDIT=$NMEDIT + # Extract the first word of "nmedit", so it can be a program name with args. +set dummy nmedit; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_NMEDIT+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$ac_ct_NMEDIT"; then + ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_NMEDIT="nmedit" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT +if test -n "$ac_ct_NMEDIT"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5 +printf "%s\n" "$ac_ct_NMEDIT" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + if test "x$ac_ct_NMEDIT" = x; then + NMEDIT=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + NMEDIT=$ac_ct_NMEDIT + fi +else + NMEDIT="$ac_cv_prog_NMEDIT" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args. +set dummy ${ac_tool_prefix}lipo; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_LIPO+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$LIPO"; then + ac_cv_prog_LIPO="$LIPO" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_LIPO="${ac_tool_prefix}lipo" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +LIPO=$ac_cv_prog_LIPO +if test -n "$LIPO"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5 +printf "%s\n" "$LIPO" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_LIPO"; then + ac_ct_LIPO=$LIPO + # Extract the first word of "lipo", so it can be a program name with args. +set dummy lipo; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_LIPO+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$ac_ct_LIPO"; then + ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_LIPO="lipo" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO +if test -n "$ac_ct_LIPO"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5 +printf "%s\n" "$ac_ct_LIPO" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + if test "x$ac_ct_LIPO" = x; then + LIPO=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + LIPO=$ac_ct_LIPO + fi +else + LIPO="$ac_cv_prog_LIPO" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args. +set dummy ${ac_tool_prefix}otool; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_OTOOL+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$OTOOL"; then + ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_OTOOL="${ac_tool_prefix}otool" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OTOOL=$ac_cv_prog_OTOOL +if test -n "$OTOOL"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5 +printf "%s\n" "$OTOOL" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OTOOL"; then + ac_ct_OTOOL=$OTOOL + # Extract the first word of "otool", so it can be a program name with args. +set dummy otool; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_OTOOL+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$ac_ct_OTOOL"; then + ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_OTOOL="otool" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL +if test -n "$ac_ct_OTOOL"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5 +printf "%s\n" "$ac_ct_OTOOL" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + if test "x$ac_ct_OTOOL" = x; then + OTOOL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OTOOL=$ac_ct_OTOOL + fi +else + OTOOL="$ac_cv_prog_OTOOL" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args. +set dummy ${ac_tool_prefix}otool64; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_OTOOL64+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$OTOOL64"; then + ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OTOOL64=$ac_cv_prog_OTOOL64 +if test -n "$OTOOL64"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5 +printf "%s\n" "$OTOOL64" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OTOOL64"; then + ac_ct_OTOOL64=$OTOOL64 + # Extract the first word of "otool64", so it can be a program name with args. +set dummy otool64; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_OTOOL64+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$ac_ct_OTOOL64"; then + ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_OTOOL64="otool64" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64 +if test -n "$ac_ct_OTOOL64"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5 +printf "%s\n" "$ac_ct_OTOOL64" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + if test "x$ac_ct_OTOOL64" = x; then + OTOOL64=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OTOOL64=$ac_ct_OTOOL64 + fi +else + OTOOL64="$ac_cv_prog_OTOOL64" +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5 +printf %s "checking for -single_module linker flag... " >&6; } +if test ${lt_cv_apple_cc_single_mod+y} +then : + printf %s "(cached) " >&6 +else $as_nop + lt_cv_apple_cc_single_mod=no + if test -z "$LT_MULTI_MODULE"; then + # By default we will add the -single_module flag. You can override + # by either setting the environment variable LT_MULTI_MODULE + # non-empty at configure time, or by adding -multi_module to the + # link flags. + rm -rf libconftest.dylib* + echo "int foo(void){return 1;}" > conftest.c + echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ +-dynamiclib -Wl,-single_module conftest.c" >&5 + $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ + -dynamiclib -Wl,-single_module conftest.c 2>conftest.err + _lt_result=$? + # If there is a non-empty error log, and "single_module" + # appears in it, assume the flag caused a linker warning + if test -s conftest.err && $GREP single_module conftest.err; then + cat conftest.err >&5 + # Otherwise, if the output was created with a 0 exit code from + # the compiler, it worked. + elif test -f libconftest.dylib && test 0 = "$_lt_result"; then + lt_cv_apple_cc_single_mod=yes + else + cat conftest.err >&5 + fi + rm -rf libconftest.dylib* + rm -f conftest.* + fi +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5 +printf "%s\n" "$lt_cv_apple_cc_single_mod" >&6; } + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5 +printf %s "checking for -exported_symbols_list linker flag... " >&6; } +if test ${lt_cv_ld_exported_symbols_list+y} +then : + printf %s "(cached) " >&6 +else $as_nop + lt_cv_ld_exported_symbols_list=no + save_LDFLAGS=$LDFLAGS + echo "_main" > conftest.sym + LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + lt_cv_ld_exported_symbols_list=yes +else $as_nop + lt_cv_ld_exported_symbols_list=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS=$save_LDFLAGS + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5 +printf "%s\n" "$lt_cv_ld_exported_symbols_list" >&6; } + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5 +printf %s "checking for -force_load linker flag... " >&6; } +if test ${lt_cv_ld_force_load+y} +then : + printf %s "(cached) " >&6 +else $as_nop + lt_cv_ld_force_load=no + cat > conftest.c << _LT_EOF +int forced_loaded() { return 2;} +_LT_EOF + echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5 + $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5 + echo "$AR cr libconftest.a conftest.o" >&5 + $AR cr libconftest.a conftest.o 2>&5 + echo "$RANLIB libconftest.a" >&5 + $RANLIB libconftest.a 2>&5 + cat > conftest.c << _LT_EOF +int main() { return 0;} +_LT_EOF + echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5 + $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err + _lt_result=$? + if test -s conftest.err && $GREP force_load conftest.err; then + cat conftest.err >&5 + elif test -f conftest && test 0 = "$_lt_result" && $GREP forced_load conftest >/dev/null 2>&1; then + lt_cv_ld_force_load=yes + else + cat conftest.err >&5 + fi + rm -f conftest.err libconftest.a conftest conftest.c + rm -rf conftest.dSYM + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5 +printf "%s\n" "$lt_cv_ld_force_load" >&6; } + case $host_os in + rhapsody* | darwin1.[012]) + _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;; + darwin1.*) + _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; + darwin*) # darwin 5.x on + # if running on 10.5 or later, the deployment target defaults + # to the OS version, if on x86, and 10.4, the deployment + # target defaults to 10.4. Don't you love it? + case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in + 10.0,*86*-darwin8*|10.0,*-darwin[912]*) + _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; + 10.[012][,.]*) + _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; + 10.*|11.*) + _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; + esac + ;; + esac + if test yes = "$lt_cv_apple_cc_single_mod"; then + _lt_dar_single_mod='$single_module' + fi + if test yes = "$lt_cv_ld_exported_symbols_list"; then + _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym' + else + _lt_dar_export_syms='~$NMEDIT -s $output_objdir/$libname-symbols.expsym $lib' + fi + if test : != "$DSYMUTIL" && test no = "$lt_cv_ld_force_load"; then + _lt_dsymutil='~$DSYMUTIL $lib || :' + else + _lt_dsymutil= + fi + ;; + esac + +# func_munge_path_list VARIABLE PATH +# ----------------------------------- +# VARIABLE is name of variable containing _space_ separated list of +# directories to be munged by the contents of PATH, which is string +# having a format: +# "DIR[:DIR]:" +# string "DIR[ DIR]" will be prepended to VARIABLE +# ":DIR[:DIR]" +# string "DIR[ DIR]" will be appended to VARIABLE +# "DIRP[:DIRP]::[DIRA:]DIRA" +# string "DIRP[ DIRP]" will be prepended to VARIABLE and string +# "DIRA[ DIRA]" will be appended to VARIABLE +# "DIR[:DIR]" +# VARIABLE will be replaced by "DIR[ DIR]" +func_munge_path_list () +{ + case x$2 in + x) + ;; + *:) + eval $1=\"`$ECHO $2 | $SED 's/:/ /g'` \$$1\" + ;; + x:*) + eval $1=\"\$$1 `$ECHO $2 | $SED 's/:/ /g'`\" + ;; + *::*) + eval $1=\"\$$1\ `$ECHO $2 | $SED -e 's/.*:://' -e 's/:/ /g'`\" + eval $1=\"`$ECHO $2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \$$1\" + ;; + *) + eval $1=\"`$ECHO $2 | $SED 's/:/ /g'`\" + ;; + esac +} + +ac_header= ac_cache= +for ac_item in $ac_header_c_list +do + if test $ac_cache; then + ac_fn_c_check_header_compile "$LINENO" $ac_header ac_cv_header_$ac_cache "$ac_includes_default" + if eval test \"x\$ac_cv_header_$ac_cache\" = xyes; then + printf "%s\n" "#define $ac_item 1" >> confdefs.h + fi + ac_header= ac_cache= + elif test $ac_header; then + ac_cache=$ac_item + else + ac_header=$ac_item + fi +done + + + + + + + + +if test $ac_cv_header_stdlib_h = yes && test $ac_cv_header_string_h = yes +then : + +printf "%s\n" "#define STDC_HEADERS 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default +" +if test "x$ac_cv_header_dlfcn_h" = xyes +then : + printf "%s\n" "#define HAVE_DLFCN_H 1" >>confdefs.h + +fi + + + +func_stripname_cnf () +{ + case $2 in + .*) func_stripname_result=`$ECHO "$3" | $SED "s%^$1%%; s%\\\\$2\$%%"`;; + *) func_stripname_result=`$ECHO "$3" | $SED "s%^$1%%; s%$2\$%%"`;; + esac +} # func_stripname_cnf + + + + + +# Set options + + + + enable_dlopen=no + + + enable_win32_dll=no + + + + # Check whether --enable-static was given. +if test ${enable_static+y} +then : + enableval=$enable_static; p=${PACKAGE-default} + case $enableval in + yes) enable_static=yes ;; + no) enable_static=no ;; + *) + enable_static=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for pkg in $enableval; do + IFS=$lt_save_ifs + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS=$lt_save_ifs + ;; + esac +else $as_nop + enable_static=yes +fi + + + + + + + + + + +# Check whether --with-pic was given. +if test ${with_pic+y} +then : + withval=$with_pic; lt_p=${PACKAGE-default} + case $withval in + yes|no) pic_mode=$withval ;; + *) + pic_mode=default + # Look at the argument we got. We use all the common list separators. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for lt_pkg in $withval; do + IFS=$lt_save_ifs + if test "X$lt_pkg" = "X$lt_p"; then + pic_mode=yes + fi + done + IFS=$lt_save_ifs + ;; + esac +else $as_nop + pic_mode=default +fi + + + + + + + + + # Check whether --enable-fast-install was given. +if test ${enable_fast_install+y} +then : + enableval=$enable_fast_install; p=${PACKAGE-default} + case $enableval in + yes) enable_fast_install=yes ;; + no) enable_fast_install=no ;; + *) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for pkg in $enableval; do + IFS=$lt_save_ifs + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS=$lt_save_ifs + ;; + esac +else $as_nop + enable_fast_install=yes +fi + + + + + + + + + shared_archive_member_spec= +case $host,$enable_shared in +power*-*-aix[5-9]*,yes) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking which variant of shared library versioning to provide" >&5 +printf %s "checking which variant of shared library versioning to provide... " >&6; } + +# Check whether --with-aix-soname was given. +if test ${with_aix_soname+y} +then : + withval=$with_aix_soname; case $withval in + aix|svr4|both) + ;; + *) + as_fn_error $? "Unknown argument to --with-aix-soname" "$LINENO" 5 + ;; + esac + lt_cv_with_aix_soname=$with_aix_soname +else $as_nop + if test ${lt_cv_with_aix_soname+y} +then : + printf %s "(cached) " >&6 +else $as_nop + lt_cv_with_aix_soname=aix +fi + + with_aix_soname=$lt_cv_with_aix_soname +fi + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $with_aix_soname" >&5 +printf "%s\n" "$with_aix_soname" >&6; } + if test aix != "$with_aix_soname"; then + # For the AIX way of multilib, we name the shared archive member + # based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o', + # and 'shr.imp' or 'shr_64.imp', respectively, for the Import File. + # Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag, + # the AIX toolchain works better with OBJECT_MODE set (default 32). + if test 64 = "${OBJECT_MODE-32}"; then + shared_archive_member_spec=shr_64 + else + shared_archive_member_spec=shr + fi + fi + ;; +*) + with_aix_soname=aix + ;; +esac + + + + + + + + + + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS=$ltmain + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +test -z "$LN_S" && LN_S="ln -s" + + + + + + + + + + + + + + +if test -n "${ZSH_VERSION+set}"; then + setopt NO_GLOB_SUBST +fi + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5 +printf %s "checking for objdir... " >&6; } +if test ${lt_cv_objdir+y} +then : + printf %s "(cached) " >&6 +else $as_nop + rm -f .libs 2>/dev/null +mkdir .libs 2>/dev/null +if test -d .libs; then + lt_cv_objdir=.libs +else + # MS-DOS does not allow filenames that begin with a dot. + lt_cv_objdir=_libs +fi +rmdir .libs 2>/dev/null +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5 +printf "%s\n" "$lt_cv_objdir" >&6; } +objdir=$lt_cv_objdir + + + + + +printf "%s\n" "#define LT_OBJDIR \"$lt_cv_objdir/\"" >>confdefs.h + + + + +case $host_os in +aix3*) + # AIX sometimes has problems with the GCC collect2 program. For some + # reason, if we set the COLLECT_NAMES environment variable, the problems + # vanish in a puff of smoke. + if test set != "${COLLECT_NAMES+set}"; then + COLLECT_NAMES= + export COLLECT_NAMES + fi + ;; +esac + +# Global variables: +ofile=libtool +can_build_shared=yes + +# All known linkers require a '.a' archive for static linking (except MSVC, +# which needs '.lib'). +libext=a + +with_gnu_ld=$lt_cv_prog_gnu_ld + +old_CC=$CC +old_CFLAGS=$CFLAGS + +# Set sane defaults for various variables +test -z "$CC" && CC=cc +test -z "$LTCC" && LTCC=$CC +test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS +test -z "$LD" && LD=ld +test -z "$ac_objext" && ac_objext=o + +func_cc_basename $compiler +cc_basename=$func_cc_basename_result + + +# Only perform the check for file, if the check method requires it +test -z "$MAGIC_CMD" && MAGIC_CMD=file +case $deplibs_check_method in +file_magic*) + if test "$file_magic_cmd" = '$MAGIC_CMD'; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5 +printf %s "checking for ${ac_tool_prefix}file... " >&6; } +if test ${lt_cv_path_MAGIC_CMD+y} +then : + printf %s "(cached) " >&6 +else $as_nop + case $MAGIC_CMD in +[\\/*] | ?:[\\/]*) + lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD=$MAGIC_CMD + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR + ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" + for ac_dir in $ac_dummy; do + IFS=$lt_save_ifs + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/${ac_tool_prefix}file"; then + lt_cv_path_MAGIC_CMD=$ac_dir/"${ac_tool_prefix}file" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD=$lt_cv_path_MAGIC_CMD + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS=$lt_save_ifs + MAGIC_CMD=$lt_save_MAGIC_CMD + ;; +esac +fi + +MAGIC_CMD=$lt_cv_path_MAGIC_CMD +if test -n "$MAGIC_CMD"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 +printf "%s\n" "$MAGIC_CMD" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + + + + +if test -z "$lt_cv_path_MAGIC_CMD"; then + if test -n "$ac_tool_prefix"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for file" >&5 +printf %s "checking for file... " >&6; } +if test ${lt_cv_path_MAGIC_CMD+y} +then : + printf %s "(cached) " >&6 +else $as_nop + case $MAGIC_CMD in +[\\/*] | ?:[\\/]*) + lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD=$MAGIC_CMD + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR + ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" + for ac_dir in $ac_dummy; do + IFS=$lt_save_ifs + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/file"; then + lt_cv_path_MAGIC_CMD=$ac_dir/"file" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD=$lt_cv_path_MAGIC_CMD + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS=$lt_save_ifs + MAGIC_CMD=$lt_save_MAGIC_CMD + ;; +esac +fi + +MAGIC_CMD=$lt_cv_path_MAGIC_CMD +if test -n "$MAGIC_CMD"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 +printf "%s\n" "$MAGIC_CMD" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + + else + MAGIC_CMD=: + fi +fi + + fi + ;; +esac + +# Use C for the default configuration in the libtool script + +lt_save_CC=$CC +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +# Source file extension for C test sources. +ac_ext=c + +# Object file extension for compiled C test sources. +objext=o +objext=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(){return(0);}' + + + + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + +# Save the default compiler, since it gets overwritten when the other +# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. +compiler_DEFAULT=$CC + +# save warnings/boilerplate of simple test code +ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$RM conftest* + +ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$RM -r conftest* + + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... +if test -n "$compiler"; then + +lt_prog_compiler_no_builtin_flag= + +if test yes = "$GCC"; then + case $cc_basename in + nvcc*) + lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;; + *) + lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;; + esac + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 +printf %s "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; } +if test ${lt_cv_prog_compiler_rtti_exceptions+y} +then : + printf %s "(cached) " >&6 +else $as_nop + lt_cv_prog_compiler_rtti_exceptions=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="-fno-rtti -fno-exceptions" ## exclude from sc_useless_quotes_in_assignment + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_rtti_exceptions=yes + fi + fi + $RM conftest* + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 +printf "%s\n" "$lt_cv_prog_compiler_rtti_exceptions" >&6; } + +if test yes = "$lt_cv_prog_compiler_rtti_exceptions"; then + lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions" +else + : +fi + +fi + + + + + + + lt_prog_compiler_wl= +lt_prog_compiler_pic= +lt_prog_compiler_static= + + + if test yes = "$GCC"; then + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_static='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test ia64 = "$host_cpu"; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static='-Bstatic' + fi + lt_prog_compiler_pic='-fPIC' + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + lt_prog_compiler_pic='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the '-m68020' flag to GCC prevents building anything better, + # like '-m68040'. + lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + lt_prog_compiler_pic='-DDLL_EXPORT' + case $host_os in + os2*) + lt_prog_compiler_static='$wl-static' + ;; + esac + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic='-fno-common' + ;; + + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + lt_prog_compiler_static= + ;; + + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic='-fPIC' + ;; + esac + ;; + + interix[3-9]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + + msdosdjgpp*) + # Just because we use GCC doesn't mean we suddenly get shared libraries + # on systems that don't support them. + lt_prog_compiler_can_build_shared=no + enable_shared=no + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic='-fPIC -shared' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic=-Kconform_pic + fi + ;; + + *) + lt_prog_compiler_pic='-fPIC' + ;; + esac + + case $cc_basename in + nvcc*) # Cuda Compiler Driver 2.2 + lt_prog_compiler_wl='-Xlinker ' + if test -n "$lt_prog_compiler_pic"; then + lt_prog_compiler_pic="-Xcompiler $lt_prog_compiler_pic" + fi + ;; + esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in + aix*) + lt_prog_compiler_wl='-Wl,' + if test ia64 = "$host_cpu"; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static='-Bstatic' + else + lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp' + fi + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic='-fno-common' + case $cc_basename in + nagfor*) + # NAG Fortran compiler + lt_prog_compiler_wl='-Wl,-Wl,,' + lt_prog_compiler_pic='-PIC' + lt_prog_compiler_static='-Bstatic' + ;; + esac + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_prog_compiler_pic='-DDLL_EXPORT' + case $host_os in + os2*) + lt_prog_compiler_static='$wl-static' + ;; + esac + ;; + + hpux9* | hpux10* | hpux11*) + lt_prog_compiler_wl='-Wl,' + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic='+Z' + ;; + esac + # Is there a better lt_prog_compiler_static that works with the bundled CC? + lt_prog_compiler_static='$wl-a ${wl}archive' + ;; + + irix5* | irix6* | nonstopux*) + lt_prog_compiler_wl='-Wl,' + # PIC (with -KPIC) is the default. + lt_prog_compiler_static='-non_shared' + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + case $cc_basename in + # old Intel for x86_64, which still supported -KPIC. + ecc*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-static' + ;; + # flang / f18. f95 an alias for gfortran or flang on Debian + flang* | f18* | f95*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; + # icc used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + icc* | ifort*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; + # Lahey Fortran 8.1. + lf95*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='--shared' + lt_prog_compiler_static='--static' + ;; + nagfor*) + # NAG Fortran compiler + lt_prog_compiler_wl='-Wl,-Wl,,' + lt_prog_compiler_pic='-PIC' + lt_prog_compiler_static='-Bstatic' + ;; + tcc*) + # Fabrice Bellard et al's Tiny C Compiler + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; + pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group compilers (*not* the Pentium gcc compiler, + # which looks to be a dead project) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fpic' + lt_prog_compiler_static='-Bstatic' + ;; + ccc*) + lt_prog_compiler_wl='-Wl,' + # All Alpha code is PIC. + lt_prog_compiler_static='-non_shared' + ;; + xl* | bgxl* | bgf* | mpixl*) + # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-qpic' + lt_prog_compiler_static='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [1-7].* | *Sun*Fortran*\ 8.[0-3]*) + # Sun Fortran 8.3 passes all unrecognized flags to the linker + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='' + ;; + *Sun\ F* | *Sun*Fortran*) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='-Qoption ld ' + ;; + *Sun\ C*) + # Sun C 5.9 + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='-Wl,' + ;; + *Intel*\ [CF]*Compiler*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; + *Portland\ Group*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fpic' + lt_prog_compiler_static='-Bstatic' + ;; + esac + ;; + esac + ;; + + newsos6) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic='-fPIC -shared' + ;; + + osf3* | osf4* | osf5*) + lt_prog_compiler_wl='-Wl,' + # All OSF/1 code is PIC. + lt_prog_compiler_static='-non_shared' + ;; + + rdos*) + lt_prog_compiler_static='-non_shared' + ;; + + solaris*) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + case $cc_basename in + f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) + lt_prog_compiler_wl='-Qoption ld ';; + *) + lt_prog_compiler_wl='-Wl,';; + esac + ;; + + sunos4*) + lt_prog_compiler_wl='-Qoption ld ' + lt_prog_compiler_pic='-PIC' + lt_prog_compiler_static='-Bstatic' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic='-Kconform_pic' + lt_prog_compiler_static='-Bstatic' + fi + ;; + + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + unicos*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_can_build_shared=no + ;; + + uts4*) + lt_prog_compiler_pic='-pic' + lt_prog_compiler_static='-Bstatic' + ;; + + *) + lt_prog_compiler_can_build_shared=no + ;; + esac + fi + +case $host_os in + # For platforms that do not support PIC, -DPIC is meaningless: + *djgpp*) + lt_prog_compiler_pic= + ;; + *) + lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC" + ;; +esac + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 +printf %s "checking for $compiler option to produce PIC... " >&6; } +if test ${lt_cv_prog_compiler_pic+y} +then : + printf %s "(cached) " >&6 +else $as_nop + lt_cv_prog_compiler_pic=$lt_prog_compiler_pic +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5 +printf "%s\n" "$lt_cv_prog_compiler_pic" >&6; } +lt_prog_compiler_pic=$lt_cv_prog_compiler_pic + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$lt_prog_compiler_pic"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 +printf %s "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; } +if test ${lt_cv_prog_compiler_pic_works+y} +then : + printf %s "(cached) " >&6 +else $as_nop + lt_cv_prog_compiler_pic_works=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$lt_prog_compiler_pic -DPIC" ## exclude from sc_useless_quotes_in_assignment + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_pic_works=yes + fi + fi + $RM conftest* + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5 +printf "%s\n" "$lt_cv_prog_compiler_pic_works" >&6; } + +if test yes = "$lt_cv_prog_compiler_pic_works"; then + case $lt_prog_compiler_pic in + "" | " "*) ;; + *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;; + esac +else + lt_prog_compiler_pic= + lt_prog_compiler_can_build_shared=no +fi + +fi + + + + + + + + + + + +# +# Check to make sure the static flag actually works. +# +wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\" +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 +printf %s "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } +if test ${lt_cv_prog_compiler_static_works+y} +then : + printf %s "(cached) " >&6 +else $as_nop + lt_cv_prog_compiler_static_works=no + save_LDFLAGS=$LDFLAGS + LDFLAGS="$LDFLAGS $lt_tmp_static_flag" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_static_works=yes + fi + else + lt_cv_prog_compiler_static_works=yes + fi + fi + $RM -r conftest* + LDFLAGS=$save_LDFLAGS + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5 +printf "%s\n" "$lt_cv_prog_compiler_static_works" >&6; } + +if test yes = "$lt_cv_prog_compiler_static_works"; then + : +else + lt_prog_compiler_static= +fi + + + + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +printf %s "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if test ${lt_cv_prog_compiler_c_o+y} +then : + printf %s "(cached) " >&6 +else $as_nop + lt_cv_prog_compiler_c_o=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 +printf "%s\n" "$lt_cv_prog_compiler_c_o" >&6; } + + + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +printf %s "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if test ${lt_cv_prog_compiler_c_o+y} +then : + printf %s "(cached) " >&6 +else $as_nop + lt_cv_prog_compiler_c_o=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 +printf "%s\n" "$lt_cv_prog_compiler_c_o" >&6; } + + + + +hard_links=nottested +if test no = "$lt_cv_prog_compiler_c_o" && test no != "$need_locks"; then + # do not overwrite the value of need_locks provided by the user + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 +printf %s "checking if we can lock with hard links... " >&6; } + hard_links=yes + $RM conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 +printf "%s\n" "$hard_links" >&6; } + if test no = "$hard_links"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&5 +printf "%s\n" "$as_me: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&2;} + need_locks=warn + fi +else + need_locks=no +fi + + + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +printf %s "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } + + runpath_var= + allow_undefined_flag= + always_export_symbols=no + archive_cmds= + archive_expsym_cmds= + compiler_needs_object=no + enable_shared_with_static_runtimes=no + export_dynamic_flag_spec= + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + hardcode_automatic=no + hardcode_direct=no + hardcode_direct_absolute=no + hardcode_libdir_flag_spec= + hardcode_libdir_separator= + hardcode_minus_L=no + hardcode_shlibpath_var=unsupported + inherit_rpath=no + link_all_deplibs=unknown + module_cmds= + module_expsym_cmds= + old_archive_from_new_cmds= + old_archive_from_expsyms_cmds= + thread_safe_flag_spec= + whole_archive_flag_spec= + # include_expsyms should be a list of space-separated symbols to be *always* + # included in the symbol list + include_expsyms= + # exclude_expsyms can be an extended regexp of symbols to exclude + # it will be wrapped by ' (' and ')$', so one must not match beginning or + # end of line. Example: 'a|bc|.*d.*' will exclude the symbols 'a' and 'bc', + # as well as any symbol that contains 'd'. + exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' + # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out + # platforms (ab)use it in PIC code, but their linkers get confused if + # the symbol is explicitly referenced. Since portable code cannot + # rely on this symbol name, it's probably fine to never include it in + # preloaded symbol tables. + # Exclude shared library initialization/finalization symbols. + extract_expsyms_cmds= + + case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test yes != "$GCC"; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd* | bitrig*) + with_gnu_ld=no + ;; + linux* | k*bsd*-gnu | gnu*) + link_all_deplibs=no + ;; + esac + + ld_shlibs=yes + + # On some targets, GNU ld is compatible enough with the native linker + # that we're better off using the native interface for both. + lt_use_gnu_ld_interface=no + if test yes = "$with_gnu_ld"; then + case $host_os in + aix*) + # The AIX port of GNU ld has always aspired to compatibility + # with the native linker. However, as the warning in the GNU ld + # block says, versions before 2.19.5* couldn't really create working + # shared libraries, regardless of the interface used. + case `$LD -v 2>&1` in + *\ \(GNU\ Binutils\)\ 2.19.5*) ;; + *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;; + *\ \(GNU\ Binutils\)\ [3-9]*) ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + fi + + if test yes = "$lt_use_gnu_ld_interface"; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='$wl' + + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + runpath_var=LD_RUN_PATH + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + export_dynamic_flag_spec='$wl--export-dynamic' + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then + whole_archive_flag_spec=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' + else + whole_archive_flag_spec= + fi + supports_anon_versioning=no + case `$LD -v | $SED -e 's/(^)\+)\s\+//' 2>&1` in + *GNU\ gold*) supports_anon_versioning=yes ;; + *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 + *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... + *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... + *\ 2.11.*) ;; # other 2.11 versions + *) supports_anon_versioning=yes ;; + esac + + # See if GNU ld supports shared libraries. + case $host_os in + aix[3-9]*) + # On AIX/PPC, the GNU linker is very broken + if test ia64 != "$host_cpu"; then + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: the GNU linker, at least up to release 2.19, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to install binutils +*** 2.20 or above, or modify your PATH so that a non-GNU linker is found. +*** You will then need to restart the configuration process. + +_LT_EOF + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds='' + ;; + m68k) + archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + ;; + esac + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + allow_undefined_flag=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + else + ld_shlibs=no + fi + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, + # as there is no search path for DLLs. + hardcode_libdir_flag_spec='-L$libdir' + export_dynamic_flag_spec='$wl--export-all-symbols' + allow_undefined_flag=unsupported + always_export_symbols=no + enable_shared_with_static_runtimes=yes + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' + exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file, use it as + # is; otherwise, prepend EXPORTS... + archive_expsym_cmds='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + ld_shlibs=no + fi + ;; + + haiku*) + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + link_all_deplibs=yes + ;; + + os2*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + allow_undefined_flag=unsupported + shrext_cmds=.dll + archive_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + archive_expsym_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + prefix_cmds="$SED"~ + if test EXPORTS = "`$SED 1q $export_symbols`"; then + prefix_cmds="$prefix_cmds -e 1d"; + fi~ + prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ + cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' + enable_shared_with_static_runtimes=yes + ;; + + interix[3-9]*) + hardcode_direct=no + hardcode_shlibpath_var=no + hardcode_libdir_flag_spec='$wl-rpath,$libdir' + export_dynamic_flag_spec='$wl-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + archive_expsym_cmds='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + + gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) + tmp_diet=no + if test linux-dietlibc = "$host_os"; then + case $cc_basename in + diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) + esac + fi + if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ + && test no = "$tmp_diet" + then + tmp_addflag=' $pic_flag' + tmp_sharedflag='-shared' + case $cc_basename,$host_cpu in + pgcc*) # Portland Group C compiler + whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + tmp_addflag=' $pic_flag' + ;; + pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group f77 and f90 compilers + whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; + efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 + tmp_addflag=' -i_dynamic -nofor_main' ;; + ifc* | ifort*) # Intel Fortran compiler + tmp_addflag=' -nofor_main' ;; + lf95*) # Lahey Fortran 8.1 + whole_archive_flag_spec= + tmp_sharedflag='--shared' ;; + nagfor*) # NAGFOR 5.3 + tmp_sharedflag='-Wl,-shared' ;; + xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below) + tmp_sharedflag='-qmkshrobj' + tmp_addflag= ;; + nvcc*) # Cuda Compiler Driver 2.2 + whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + compiler_needs_object=yes + ;; + esac + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) # Sun C 5.9 + whole_archive_flag_spec='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + compiler_needs_object=yes + tmp_sharedflag='-G' ;; + *Sun\ F*) # Sun Fortran 8.3 + tmp_sharedflag='-G' ;; + esac + archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + + if test yes = "$supports_anon_versioning"; then + archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' + fi + + case $cc_basename in + tcc*) + export_dynamic_flag_spec='-rdynamic' + ;; + xlf* | bgf* | bgxlf* | mpixlf*) + # IBM XL Fortran 10.1 on PPC cannot create shared libs itself + whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive' + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' + if test yes = "$supports_anon_versioning"; then + archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' + fi + ;; + esac + else + ld_shlibs=no + fi + ;; + + netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris*) + if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 cannot +*** reliably create shared libraries on SCO systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.16.91.0.3 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + ;; + *) + # For security reasons, it is highly recommended that you always + # use absolute paths for naming shared libraries, and exclude the + # DT_RUNPATH tag from executables and libraries. But doing so + # requires that you compile everything twice, which is a pain. + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + esac + ;; + + sunos4*) + archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + *) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + esac + + if test no = "$ld_shlibs"; then + runpath_var= + hardcode_libdir_flag_spec= + export_dynamic_flag_spec= + whole_archive_flag_spec= + fi + else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + allow_undefined_flag=unsupported + always_export_symbols=yes + archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + hardcode_minus_L=yes + if test yes = "$GCC" && test -z "$lt_prog_compiler_static"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + hardcode_direct=unsupported + fi + ;; + + aix[4-9]*) + if test ia64 = "$host_cpu"; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag= + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to GNU nm, but means don't demangle to AIX nm. + # Without the "-l" option, or with the "-B" option, AIX nm treats + # weak defined symbols like other global defined symbols, whereas + # GNU nm marks them as "W". + # While the 'weak' keyword is ignored in the Export File, we need + # it in the Import File for the 'aix-soname' feature, so we have + # to replace the "-B" option with "-P" for AIX nm. + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' + else + export_symbols_cmds='`func_echo_all $NM | $SED -e '\''s/B\([^B]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && (substr(\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' + fi + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # have runtime linking enabled, and use it for executables. + # For shared libraries, we enable/disable runtime linking + # depending on the kind of the shared library created - + # when "with_aix_soname,aix_use_runtimelinking" is: + # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables + # "aix,yes" lib.so shared, rtl:yes, for executables + # lib.a static archive + # "both,no" lib.so.V(shr.o) shared, rtl:yes + # lib.a(lib.so.V) shared, rtl:no, for executables + # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables + # lib.a(lib.so.V) shared, rtl:no + # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables + # lib.a static archive + case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) + for ld_flag in $LDFLAGS; do + if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then + aix_use_runtimelinking=yes + break + fi + done + if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then + # With aix-soname=svr4, we create the lib.so.V shared archives only, + # so we don't have lib.a shared libs to link our executables. + # We have to force runtime linking in this case. + aix_use_runtimelinking=yes + LDFLAGS="$LDFLAGS -Wl,-brtl" + fi + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + archive_cmds='' + hardcode_direct=yes + hardcode_direct_absolute=yes + hardcode_libdir_separator=':' + link_all_deplibs=yes + file_list_spec='$wl-f,' + case $with_aix_soname,$aix_use_runtimelinking in + aix,*) ;; # traditional, no import file + svr4,* | *,yes) # use import file + # The Import File defines what to hardcode. + hardcode_direct=no + hardcode_direct_absolute=no + ;; + esac + + if test yes = "$GCC"; then + case $host_os in aix4.[012]|aix4.[012].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`$CC -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + hardcode_direct=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + hardcode_minus_L=yes + hardcode_libdir_flag_spec='-L$libdir' + hardcode_libdir_separator= + fi + ;; + esac + shared_flag='-shared' + if test yes = "$aix_use_runtimelinking"; then + shared_flag="$shared_flag "'$wl-G' + fi + # Need to ensure runtime linking is disabled for the traditional + # shared library, or the linker may eventually find shared libraries + # /with/ Import File - we do not want to mix them. + shared_flag_aix='-shared' + shared_flag_svr4='-shared $wl-G' + else + # not using gcc + if test ia64 = "$host_cpu"; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test yes = "$aix_use_runtimelinking"; then + shared_flag='$wl-G' + else + shared_flag='$wl-bM:SRE' + fi + shared_flag_aix='$wl-bM:SRE' + shared_flag_svr4='$wl-G' + fi + fi + + export_dynamic_flag_spec='$wl-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + always_export_symbols=yes + if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + allow_undefined_flag='-berok' + # Determine the default libpath from the value encoded in an + # empty executable. + if test set = "${lt_cv_aix_libpath+set}"; then + aix_libpath=$lt_cv_aix_libpath +else + if test ${lt_cv_aix_libpath_+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + + lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }' + lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_=/usr/lib:/lib + fi + +fi + + aix_libpath=$lt_cv_aix_libpath_ +fi + + hardcode_libdir_flag_spec='$wl-blibpath:$libdir:'"$aix_libpath" + archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag + else + if test ia64 = "$host_cpu"; then + hardcode_libdir_flag_spec='$wl-R $libdir:/usr/lib:/lib' + allow_undefined_flag="-z nodefs" + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + if test set = "${lt_cv_aix_libpath+set}"; then + aix_libpath=$lt_cv_aix_libpath +else + if test ${lt_cv_aix_libpath_+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + + lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }' + lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_=/usr/lib:/lib + fi + +fi + + aix_libpath=$lt_cv_aix_libpath_ +fi + + hardcode_libdir_flag_spec='$wl-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + no_undefined_flag=' $wl-bernotok' + allow_undefined_flag=' $wl-berok' + if test yes = "$with_gnu_ld"; then + # We only use this code for GNU lds that support --whole-archive. + whole_archive_flag_spec='$wl--whole-archive$convenience $wl--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + whole_archive_flag_spec='$convenience' + fi + archive_cmds_need_lc=yes + archive_expsym_cmds='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' + # -brtl affects multiple linker settings, -berok does not and is overridden later + compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([, ]\\)%-berok\\1%g"`' + if test svr4 != "$with_aix_soname"; then + # This is similar to how AIX traditionally builds its shared libraries. + archive_expsym_cmds="$archive_expsym_cmds"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' + fi + if test aix != "$with_aix_soname"; then + archive_expsym_cmds="$archive_expsym_cmds"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' + else + # used by -dlpreopen to get the symbols + archive_expsym_cmds="$archive_expsym_cmds"'~$MV $output_objdir/$realname.d/$soname $output_objdir' + fi + archive_expsym_cmds="$archive_expsym_cmds"'~$RM -r $output_objdir/$realname.d' + fi + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds='' + ;; + m68k) + archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + ;; + esac + ;; + + bsdi[45]*) + export_dynamic_flag_spec=-rdynamic + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + case $cc_basename in + cl*) + # Native MSVC + hardcode_libdir_flag_spec=' ' + allow_undefined_flag=unsupported + always_export_symbols=yes + file_list_spec='@' + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=.dll + # FIXME: Setting linknames here is a bad hack. + archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' + archive_expsym_cmds='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then + cp "$export_symbols" "$output_objdir/$soname.def"; + echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; + else + $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' + # The linker will not automatically build a static lib if we build a DLL. + # _LT_TAGVAR(old_archive_from_new_cmds, )='true' + enable_shared_with_static_runtimes=yes + exclude_expsyms='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols' + # Don't use ranlib + old_postinstall_cmds='chmod 644 $oldlib' + postlink_cmds='lt_outputfile="@OUTPUT@"~ + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile=$lt_outputfile.exe + lt_tool_outputfile=$lt_tool_outputfile.exe + ;; + esac~ + if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' + ;; + *) + # Assume MSVC wrapper + hardcode_libdir_flag_spec=' ' + allow_undefined_flag=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=.dll + # FIXME: Setting linknames here is a bad hack. + archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + old_archive_from_new_cmds='true' + # FIXME: Should let the user specify the lib program. + old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs' + enable_shared_with_static_runtimes=yes + ;; + esac + ;; + + darwin* | rhapsody*) + + + archive_cmds_need_lc=no + hardcode_direct=no + hardcode_automatic=yes + hardcode_shlibpath_var=unsupported + if test yes = "$lt_cv_ld_force_load"; then + whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' + + else + whole_archive_flag_spec='' + fi + link_all_deplibs=yes + allow_undefined_flag=$_lt_dar_allow_undefined + case $cc_basename in + ifort*|nagfor*) _lt_dar_can_shared=yes ;; + *) _lt_dar_can_shared=$GCC ;; + esac + if test yes = "$_lt_dar_can_shared"; then + output_verbose_link_cmd=func_echo_all + archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil" + module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil" + archive_expsym_cmds="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" + module_expsym_cmds="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" + + else + ld_shlibs=no + fi + + ;; + + dgux*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2.*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd* | dragonfly*) + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + hpux9*) + if test yes = "$GCC"; then + archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' + else + archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' + fi + hardcode_libdir_flag_spec='$wl+b $wl$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + export_dynamic_flag_spec='$wl-E' + ;; + + hpux10*) + if test yes,no = "$GCC,$with_gnu_ld"; then + archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + fi + if test no = "$with_gnu_ld"; then + hardcode_libdir_flag_spec='$wl+b $wl$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + hardcode_direct_absolute=yes + export_dynamic_flag_spec='$wl-E' + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + fi + ;; + + hpux11*) + if test yes,no = "$GCC,$with_gnu_ld"; then + case $host_cpu in + hppa*64*) + archive_cmds='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + else + case $host_cpu in + hppa*64*) + archive_cmds='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + + # Older versions of the 11.00 compiler do not understand -b yet + # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5 +printf %s "checking if $CC understands -b... " >&6; } +if test ${lt_cv_prog_compiler__b+y} +then : + printf %s "(cached) " >&6 +else $as_nop + lt_cv_prog_compiler__b=no + save_LDFLAGS=$LDFLAGS + LDFLAGS="$LDFLAGS -b" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler__b=yes + fi + else + lt_cv_prog_compiler__b=yes + fi + fi + $RM -r conftest* + LDFLAGS=$save_LDFLAGS + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5 +printf "%s\n" "$lt_cv_prog_compiler__b" >&6; } + +if test yes = "$lt_cv_prog_compiler__b"; then + archive_cmds='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' +else + archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' +fi + + ;; + esac + fi + if test no = "$with_gnu_ld"; then + hardcode_libdir_flag_spec='$wl+b $wl$libdir' + hardcode_libdir_separator=: + + case $host_cpu in + hppa*64*|ia64*) + hardcode_direct=no + hardcode_shlibpath_var=no + ;; + *) + hardcode_direct=yes + hardcode_direct_absolute=yes + export_dynamic_flag_spec='$wl-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + ;; + esac + fi + ;; + + irix5* | irix6* | nonstopux*) + if test yes = "$GCC"; then + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + # Try to use the -exported_symbol ld option, if it does not + # work, assume that -exports_file does not work either and + # implicitly export all symbols. + # This should be the same for all languages, so no per-tag cache variable. + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5 +printf %s "checking whether the $host_os linker accepts -exported_symbol... " >&6; } +if test ${lt_cv_irix_exported_symbol+y} +then : + printf %s "(cached) " >&6 +else $as_nop + save_LDFLAGS=$LDFLAGS + LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +int foo (void) { return 0; } +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + lt_cv_irix_exported_symbol=yes +else $as_nop + lt_cv_irix_exported_symbol=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS=$save_LDFLAGS +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5 +printf "%s\n" "$lt_cv_irix_exported_symbol" >&6; } + if test yes = "$lt_cv_irix_exported_symbol"; then + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib' + fi + link_all_deplibs=no + else + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib' + fi + archive_cmds_need_lc='no' + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + hardcode_libdir_separator=: + inherit_rpath=yes + link_all_deplibs=yes + ;; + + linux*) + case $cc_basename in + tcc*) + # Fabrice Bellard et al's Tiny C Compiler + ld_shlibs=yes + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + newsos6) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + hardcode_libdir_separator=: + hardcode_shlibpath_var=no + ;; + + *nto* | *qnx*) + ;; + + openbsd* | bitrig*) + if test -f /usr/libexec/ld.so; then + hardcode_direct=yes + hardcode_shlibpath_var=no + hardcode_direct_absolute=yes + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $wl-retain-symbols-file,$export_symbols' + hardcode_libdir_flag_spec='$wl-rpath,$libdir' + export_dynamic_flag_spec='$wl-E' + else + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='$wl-rpath,$libdir' + fi + else + ld_shlibs=no + fi + ;; + + os2*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + allow_undefined_flag=unsupported + shrext_cmds=.dll + archive_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + archive_expsym_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + prefix_cmds="$SED"~ + if test EXPORTS = "`$SED 1q $export_symbols`"; then + prefix_cmds="$prefix_cmds -e 1d"; + fi~ + prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ + cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' + enable_shared_with_static_runtimes=yes + ;; + + osf3*) + if test yes = "$GCC"; then + allow_undefined_flag=' $wl-expect_unresolved $wl\*' + archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + fi + archive_cmds_need_lc='no' + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + hardcode_libdir_separator=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test yes = "$GCC"; then + allow_undefined_flag=' $wl-expect_unresolved $wl\*' + archive_cmds='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $wl-input $wl$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~$RM $lib.exp' + + # Both c and cxx compiler support -rpath directly + hardcode_libdir_flag_spec='-rpath $libdir' + fi + archive_cmds_need_lc='no' + hardcode_libdir_separator=: + ;; + + solaris*) + no_undefined_flag=' -z defs' + if test yes = "$GCC"; then + wlarc='$wl' + archive_cmds='$CC -shared $pic_flag $wl-z ${wl}text $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared $pic_flag $wl-z ${wl}text $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + else + case `$CC -V 2>&1` in + *"Compilers 5.0"*) + wlarc='' + archive_cmds='$LD -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $linker_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $LD -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' + ;; + *) + wlarc='$wl' + archive_cmds='$CC -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + ;; + esac + fi + hardcode_libdir_flag_spec='-R$libdir' + hardcode_shlibpath_var=no + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands '-z linker_flag'. GCC discards it without '$wl', + # but is careful enough not to reorder. + # Supported since Solaris 2.6 (maybe 2.5.1?) + if test yes = "$GCC"; then + whole_archive_flag_spec='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' + else + whole_archive_flag_spec='-z allextract$convenience -z defaultextract' + fi + ;; + esac + link_all_deplibs=yes + ;; + + sunos4*) + if test sequent = "$host_vendor"; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + archive_cmds='$CC -G $wl-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + hardcode_libdir_flag_spec='-L$libdir' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + sysv4) + case $host_vendor in + sni) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' + reload_cmds='$CC -r -o $output$reload_objs' + hardcode_direct=no + ;; + motorola) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + hardcode_shlibpath_var=no + ;; + + sysv4.3*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + export_dynamic_flag_spec='-Bexport' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + ld_shlibs=yes + fi + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) + no_undefined_flag='$wl-z,text' + archive_cmds_need_lc=no + hardcode_shlibpath_var=no + runpath_var='LD_RUN_PATH' + + if test yes = "$GCC"; then + archive_cmds='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We CANNOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + no_undefined_flag='$wl-z,text' + allow_undefined_flag='$wl-z,nodefs' + archive_cmds_need_lc=no + hardcode_shlibpath_var=no + hardcode_libdir_flag_spec='$wl-R,$libdir' + hardcode_libdir_separator=':' + link_all_deplibs=yes + export_dynamic_flag_spec='$wl-Bexport' + runpath_var='LD_RUN_PATH' + + if test yes = "$GCC"; then + archive_cmds='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + uts4*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + *) + ld_shlibs=no + ;; + esac + + if test sni = "$host_vendor"; then + case $host in + sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + export_dynamic_flag_spec='$wl-Blargedynsym' + ;; + esac + fi + fi + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5 +printf "%s\n" "$ld_shlibs" >&6; } +test no = "$ld_shlibs" && can_build_shared=no + +with_gnu_ld=$with_gnu_ld + + + + + + + + + + + + + + + +# +# Do we need to explicitly link libc? +# +case "x$archive_cmds_need_lc" in +x|xyes) + # Assume -lc should be added + archive_cmds_need_lc=yes + + if test yes,yes = "$GCC,$enable_shared"; then + case $archive_cmds in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 +printf %s "checking whether -lc should be explicitly linked in... " >&6; } +if test ${lt_cv_archive_cmds_need_lc+y} +then : + printf %s "(cached) " >&6 +else $as_nop + $RM conftest* + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$lt_prog_compiler_wl + pic_flag=$lt_prog_compiler_pic + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$allow_undefined_flag + allow_undefined_flag= + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 + (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + then + lt_cv_archive_cmds_need_lc=no + else + lt_cv_archive_cmds_need_lc=yes + fi + allow_undefined_flag=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $RM conftest* + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5 +printf "%s\n" "$lt_cv_archive_cmds_need_lc" >&6; } + archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc + ;; + esac + fi + ;; +esac + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 +printf %s "checking dynamic linker characteristics... " >&6; } + +if test yes = "$GCC"; then + case $host_os in + darwin*) lt_awk_arg='/^libraries:/,/LR/' ;; + *) lt_awk_arg='/^libraries:/' ;; + esac + case $host_os in + mingw* | cegcc*) lt_sed_strip_eq='s|=\([A-Za-z]:\)|\1|g' ;; + *) lt_sed_strip_eq='s|=/|/|g' ;; + esac + lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` + case $lt_search_path_spec in + *\;*) + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` + ;; + *) + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` + ;; + esac + # Ok, now we have the path, separated by spaces, we can step through it + # and add multilib dir if necessary... + lt_tmp_lt_search_path_spec= + lt_multi_os_dir=/`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` + # ...but if some path component already ends with the multilib dir we assume + # that all is fine and trust -print-search-dirs as is (GCC 4.2? or newer). + case "$lt_multi_os_dir; $lt_search_path_spec " in + "/; "* | "/.; "* | "/./; "* | *"$lt_multi_os_dir "* | *"$lt_multi_os_dir/ "*) + lt_multi_os_dir= + ;; + esac + for lt_sys_path in $lt_search_path_spec; do + if test -d "$lt_sys_path$lt_multi_os_dir"; then + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path$lt_multi_os_dir" + elif test -n "$lt_multi_os_dir"; then + test -d "$lt_sys_path" && \ + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" + fi + done + lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' +BEGIN {RS = " "; FS = "/|\n";} { + lt_foo = ""; + lt_count = 0; + for (lt_i = NF; lt_i > 0; lt_i--) { + if ($lt_i != "" && $lt_i != ".") { + if ($lt_i == "..") { + lt_count++; + } else { + if (lt_count == 0) { + lt_foo = "/" $lt_i lt_foo; + } else { + lt_count--; + } + } + } + } + if (lt_foo != "") { lt_freq[lt_foo]++; } + if (lt_freq[lt_foo] == 1) { print lt_foo; } +}'` + # AWK program above erroneously prepends '/' to C:/dos/paths + # for these hosts. + case $host_os in + mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ + $SED 's|/\([A-Za-z]:\)|\1|g'` ;; + esac + sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` +else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" +fi +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=.so +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + + + +case $host_os in +aix3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='$libname$release$shared_ext$major' + ;; + +aix[4-9]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test ia64 = "$host_cpu"; then + # AIX 5 supports IA64 + library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line '#! .'. This would cause the generated library to + # depend on '.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[01] | aix4.[01].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # Using Import Files as archive members, it is possible to support + # filename-based versioning of shared library archives on AIX. While + # this would work for both with and without runtime linking, it will + # prevent static linking of such archives. So we do filename-based + # shared library versioning with .so extension only, which is used + # when both runtime linking and shared linking is enabled. + # Unfortunately, runtime linking may impact performance, so we do + # not want this to be the default eventually. Also, we use the + # versioned .so libs for executables only if there is the -brtl + # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only. + # To allow for filename-based versioning support, we need to create + # libNAME.so.V as an archive file, containing: + # *) an Import File, referring to the versioned filename of the + # archive as well as the shared archive member, telling the + # bitwidth (32 or 64) of that shared object, and providing the + # list of exported symbols of that shared object, eventually + # decorated with the 'weak' keyword + # *) the shared object with the F_LOADONLY flag set, to really avoid + # it being seen by the linker. + # At run time we better use the real file rather than another symlink, + # but for link time we create the symlink libNAME.so -> libNAME.so.V + + case $with_aix_soname,$aix_use_runtimelinking in + # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + aix,yes) # traditional libtool + dynamic_linker='AIX unversionable lib.so' + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + ;; + aix,no) # traditional AIX only + dynamic_linker='AIX lib.a(lib.so.V)' + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='$libname$release.a $libname.a' + soname_spec='$libname$release$shared_ext$major' + ;; + svr4,*) # full svr4 only + dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o)" + library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' + # We do not specify a path in Import Files, so LIBPATH fires. + shlibpath_overrides_runpath=yes + ;; + *,yes) # both, prefer svr4 + dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o), lib.a(lib.so.V)" + library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' + # unpreferred sharedlib libNAME.a needs extra handling + postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"' + postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"' + # We do not specify a path in Import Files, so LIBPATH fires. + shlibpath_overrides_runpath=yes + ;; + *,no) # both, prefer aix + dynamic_linker="AIX lib.a(lib.so.V), lib.so.V($shared_archive_member_spec.o)" + library_names_spec='$libname$release.a $libname.a' + soname_spec='$libname$release$shared_ext$major' + # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling + postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)' + postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"' + ;; + esac + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + case $host_cpu in + powerpc) + # Since July 2007 AmigaOS4 officially supports .so libraries. + # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + ;; + m68k) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + esac + ;; + +beos*) + library_names_spec='$libname$shared_ext' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[45]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32* | cegcc*) + version_type=windows + shrext_cmds=.dll + need_version=no + need_lib_prefix=no + + case $GCC,$cc_basename in + yes,*) + # gcc + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api" + ;; + mingw* | cegcc*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + ;; + esac + dynamic_linker='Win32 ld.exe' + ;; + + *,cl*) + # Native MSVC + libname_spec='$name' + soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + library_names_spec='$libname.dll.lib' + + case $build_os in + mingw*) + sys_lib_search_path_spec= + lt_save_ifs=$IFS + IFS=';' + for lt_path in $LIB + do + IFS=$lt_save_ifs + # Let DOS variable expansion print the short 8.3 style file name. + lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` + sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" + done + IFS=$lt_save_ifs + # Convert to MSYS style. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` + ;; + cygwin*) + # Convert to unix form, then to dos form, then back to unix form + # but this time dos style (no spaces!) so that the unix form looks + # like /cygdrive/c/PROGRA~1:/cygdr... + sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` + sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` + sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + ;; + *) + sys_lib_search_path_spec=$LIB + if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then + # It is most probably a Windows format PATH. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + # FIXME: find the short name or the path components, as spaces are + # common. (e.g. "Program Files" -> "PROGRA~1") + ;; + esac + + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + dynamic_linker='Win32 link.exe' + ;; + + *) + # Assume MSVC wrapper + library_names_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext $libname.lib' + dynamic_linker='Win32 ld.exe' + ;; + esac + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$major$shared_ext $libname$shared_ext' + soname_spec='$libname$release$major$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' + + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib" + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[23].*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2.*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[01]* | freebsdelf3.[01]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ + freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +haiku*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + dynamic_linker="$host_os runtime_loader" + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LIBRARY_PATH + shlibpath_overrides_runpath=no + sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + if test 32 = "$HPUX_IA64_MODE"; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + sys_lib_dlsearch_path_spec=/usr/lib/hpux32 + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + sys_lib_dlsearch_path_spec=/usr/lib/hpux64 + fi + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555, ... + postinstall_cmds='chmod 555 $lib' + # or fails outright, so override atomically: + install_override_mode=555 + ;; + +interix[3-9]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test yes = "$lt_cv_prog_gnu_ld"; then + version_type=linux # correct to gnu/linux during the next big refactor + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='$libname$release$shared_ext$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff" + sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +linux*android*) + version_type=none # Android doesn't support versioned libraries. + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext' + soname_spec='$libname$release$shared_ext' + finish_cmds= + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + dynamic_linker='Android linker' + # Don't embed -rpath directories since the linker doesn't support them. + hardcode_libdir_flag_spec='-L$libdir' + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + + # Some binutils ld are patched to set DT_RUNPATH + if test ${lt_cv_shlibpath_overrides_runpath+y} +then : + printf %s "(cached) " >&6 +else $as_nop + lt_cv_shlibpath_overrides_runpath=no + save_LDFLAGS=$LDFLAGS + save_libdir=$libdir + eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \ + LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\"" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null +then : + lt_cv_shlibpath_overrides_runpath=yes +fi +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS=$save_LDFLAGS + libdir=$save_libdir + +fi + + shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Ideally, we could use ldconfig to report *all* directores which are + # searched for libraries, however this is still not possible. Aside from not + # being certain /sbin/ldconfig is available, command + # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64, + # even though it is searched at run-time. Try to do the best guess by + # appending ld.so.conf contents (and includes) to the search path. + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsdelf*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='NetBSD ld.elf_so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +*nto* | *qnx*) + version_type=qnx + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='ldqnx.so' + ;; + +openbsd* | bitrig*) + version_type=sunos + sys_lib_dlsearch_path_spec=/usr/lib + need_lib_prefix=no + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then + need_version=no + else + need_version=yes + fi + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +os2*) + libname_spec='$name' + version_type=windows + shrext_cmds=.dll + need_version=no + need_lib_prefix=no + # OS/2 can only load a DLL with a base name of 8 characters or less. + soname_spec='`test -n "$os2dllname" && libname="$os2dllname"; + v=$($ECHO $release$versuffix | tr -d .-); + n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _); + $ECHO $n$v`$shared_ext' + library_names_spec='${libname}_dll.$libext' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=BEGINLIBPATH + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='$libname$release$shared_ext$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + +rdos*) + dynamic_linker=no + ;; + +solaris*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test yes = "$with_gnu_ld"; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec; then + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext' + soname_spec='$libname$shared_ext.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=sco + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + if test yes = "$with_gnu_ld"; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +tpf*) + # TPF is a cross-target only. Preferred cross-host = GNU/Linux. + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +uts4*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 +printf "%s\n" "$dynamic_linker" >&6; } +test no = "$dynamic_linker" && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test yes = "$GCC"; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then + sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec +fi + +if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then + sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec +fi + +# remember unaugmented sys_lib_dlsearch_path content for libtool script decls... +configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec + +# ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code +func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH" + +# to be used as default LT_SYS_LIBRARY_PATH value in generated libtool +configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 +printf %s "checking how to hardcode library paths into programs... " >&6; } +hardcode_action= +if test -n "$hardcode_libdir_flag_spec" || + test -n "$runpath_var" || + test yes = "$hardcode_automatic"; then + + # We can hardcode non-existent directories. + if test no != "$hardcode_direct" && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, )" && + test no != "$hardcode_minus_L"; then + # Linking always hardcodes the temporary library directory. + hardcode_action=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + hardcode_action=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + hardcode_action=unsupported +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5 +printf "%s\n" "$hardcode_action" >&6; } + +if test relink = "$hardcode_action" || + test yes = "$inherit_rpath"; then + # Fast installation is not supported + enable_fast_install=no +elif test yes = "$shlibpath_overrides_runpath" || + test no = "$enable_shared"; then + # Fast installation is not necessary + enable_fast_install=needless +fi + + + + + + + if test yes != "$enable_dlopen"; then + enable_dlopen=unknown + enable_dlopen_self=unknown + enable_dlopen_self_static=unknown +else + lt_cv_dlopen=no + lt_cv_dlopen_libs= + + case $host_os in + beos*) + lt_cv_dlopen=load_add_on + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ;; + + mingw* | pw32* | cegcc*) + lt_cv_dlopen=LoadLibrary + lt_cv_dlopen_libs= + ;; + + cygwin*) + lt_cv_dlopen=dlopen + lt_cv_dlopen_libs= + ;; + + darwin*) + # if libdl is installed we need to link against it + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 +printf %s "checking for dlopen in -ldl... " >&6; } +if test ${ac_cv_lib_dl_dlopen+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +char dlopen (); +int +main (void) +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_dl_dlopen=yes +else $as_nop + ac_cv_lib_dl_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 +printf "%s\n" "$ac_cv_lib_dl_dlopen" >&6; } +if test "x$ac_cv_lib_dl_dlopen" = xyes +then : + lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl +else $as_nop + + lt_cv_dlopen=dyld + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + +fi + + ;; + + tpf*) + # Don't try to run any link tests for TPF. We know it's impossible + # because TPF is a cross-compiler, and we know how we open DSOs. + lt_cv_dlopen=dlopen + lt_cv_dlopen_libs= + lt_cv_dlopen_self=no + ;; + + *) + ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load" +if test "x$ac_cv_func_shl_load" = xyes +then : + lt_cv_dlopen=shl_load +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5 +printf %s "checking for shl_load in -ldld... " >&6; } +if test ${ac_cv_lib_dld_shl_load+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +char shl_load (); +int +main (void) +{ +return shl_load (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_dld_shl_load=yes +else $as_nop + ac_cv_lib_dld_shl_load=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5 +printf "%s\n" "$ac_cv_lib_dld_shl_load" >&6; } +if test "x$ac_cv_lib_dld_shl_load" = xyes +then : + lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld +else $as_nop + ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen" +if test "x$ac_cv_func_dlopen" = xyes +then : + lt_cv_dlopen=dlopen +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 +printf %s "checking for dlopen in -ldl... " >&6; } +if test ${ac_cv_lib_dl_dlopen+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +char dlopen (); +int +main (void) +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_dl_dlopen=yes +else $as_nop + ac_cv_lib_dl_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 +printf "%s\n" "$ac_cv_lib_dl_dlopen" >&6; } +if test "x$ac_cv_lib_dl_dlopen" = xyes +then : + lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5 +printf %s "checking for dlopen in -lsvld... " >&6; } +if test ${ac_cv_lib_svld_dlopen+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsvld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +char dlopen (); +int +main (void) +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_svld_dlopen=yes +else $as_nop + ac_cv_lib_svld_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5 +printf "%s\n" "$ac_cv_lib_svld_dlopen" >&6; } +if test "x$ac_cv_lib_svld_dlopen" = xyes +then : + lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5 +printf %s "checking for dld_link in -ldld... " >&6; } +if test ${ac_cv_lib_dld_dld_link+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +char dld_link (); +int +main (void) +{ +return dld_link (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_dld_dld_link=yes +else $as_nop + ac_cv_lib_dld_dld_link=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5 +printf "%s\n" "$ac_cv_lib_dld_dld_link" >&6; } +if test "x$ac_cv_lib_dld_dld_link" = xyes +then : + lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld +fi + + +fi + + +fi + + +fi + + +fi + + +fi + + ;; + esac + + if test no = "$lt_cv_dlopen"; then + enable_dlopen=no + else + enable_dlopen=yes + fi + + case $lt_cv_dlopen in + dlopen) + save_CPPFLAGS=$CPPFLAGS + test yes = "$ac_cv_header_dlfcn_h" && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + + save_LDFLAGS=$LDFLAGS + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + + save_LIBS=$LIBS + LIBS="$lt_cv_dlopen_libs $LIBS" + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5 +printf %s "checking whether a program can dlopen itself... " >&6; } +if test ${lt_cv_dlopen_self+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test yes = "$cross_compiling"; then : + lt_cv_dlopen_self=cross +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +#line $LINENO "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +/* When -fvisibility=hidden is used, assume the code has been annotated + correspondingly for the symbols needed. */ +#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +int fnord () __attribute__((visibility("default"))); +#endif + +int fnord () { return 42; } +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else + { + if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + else puts (dlerror ()); + } + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +} +_LT_EOF + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s "conftest$ac_exeext" 2>/dev/null; then + (./conftest; exit; ) >&5 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; + x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; + x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;; + esac + else : + # compilation failed + lt_cv_dlopen_self=no + fi +fi +rm -fr conftest* + + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5 +printf "%s\n" "$lt_cv_dlopen_self" >&6; } + + if test yes = "$lt_cv_dlopen_self"; then + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5 +printf %s "checking whether a statically linked program can dlopen itself... " >&6; } +if test ${lt_cv_dlopen_self_static+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test yes = "$cross_compiling"; then : + lt_cv_dlopen_self_static=cross +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +#line $LINENO "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +/* When -fvisibility=hidden is used, assume the code has been annotated + correspondingly for the symbols needed. */ +#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +int fnord () __attribute__((visibility("default"))); +#endif + +int fnord () { return 42; } +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else + { + if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + else puts (dlerror ()); + } + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +} +_LT_EOF + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s "conftest$ac_exeext" 2>/dev/null; then + (./conftest; exit; ) >&5 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; + x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; + x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;; + esac + else : + # compilation failed + lt_cv_dlopen_self_static=no + fi +fi +rm -fr conftest* + + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5 +printf "%s\n" "$lt_cv_dlopen_self_static" >&6; } + fi + + CPPFLAGS=$save_CPPFLAGS + LDFLAGS=$save_LDFLAGS + LIBS=$save_LIBS + ;; + esac + + case $lt_cv_dlopen_self in + yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; + *) enable_dlopen_self=unknown ;; + esac + + case $lt_cv_dlopen_self_static in + yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; + *) enable_dlopen_self_static=unknown ;; + esac +fi + + + + + + + + + + + + + + + + + +striplib= +old_striplib= +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5 +printf %s "checking whether stripping libraries is possible... " >&6; } +if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then + test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" + test -z "$striplib" && striplib="$STRIP --strip-unneeded" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } +else +# FIXME - insert some real tests, host_os isn't really good enough + case $host_os in + darwin*) + if test -n "$STRIP"; then + striplib="$STRIP -x" + old_striplib="$STRIP -S" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + fi + ;; + *) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + ;; + esac +fi + + + + + + + + + + + + + # Report what library types will actually be built + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5 +printf %s "checking if libtool supports shared libraries... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5 +printf "%s\n" "$can_build_shared" >&6; } + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5 +printf %s "checking whether to build shared libraries... " >&6; } + test no = "$can_build_shared" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test yes = "$enable_shared" && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + + aix[4-9]*) + if test ia64 != "$host_cpu"; then + case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in + yes,aix,yes) ;; # shared object as lib.so file only + yes,svr4,*) ;; # shared object as lib.so archive member only + yes,*) enable_static=no ;; # shared object in lib.a archive as well + esac + fi + ;; + esac + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5 +printf "%s\n" "$enable_shared" >&6; } + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5 +printf %s "checking whether to build static libraries... " >&6; } + # Make sure either enable_shared or enable_static is yes. + test yes = "$enable_shared" || enable_static=yes + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5 +printf "%s\n" "$enable_static" >&6; } + + + + +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +CC=$lt_save_CC + + if test -n "$CXX" && ( test no != "$CXX" && + ( (test g++ = "$CXX" && `g++ -v >/dev/null 2>&1` ) || + (test g++ != "$CXX"))); then + ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to run the C++ preprocessor" >&5 +printf %s "checking how to run the C++ preprocessor... " >&6; } +if test -z "$CXXCPP"; then + if test ${ac_cv_prog_CXXCPP+y} +then : + printf %s "(cached) " >&6 +else $as_nop + # Double quotes because $CXX needs to be expanded + for CXXCPP in "$CXX -E" cpp /lib/cpp + do + ac_preproc_ok=false +for ac_cxx_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + Syntax error +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO" +then : + +else $as_nop + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO" +then : + # Broken: success on invalid input. +continue +else $as_nop + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok +then : + break +fi + + done + ac_cv_prog_CXXCPP=$CXXCPP + +fi + CXXCPP=$ac_cv_prog_CXXCPP +else + ac_cv_prog_CXXCPP=$CXXCPP +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CXXCPP" >&5 +printf "%s\n" "$CXXCPP" >&6; } +ac_preproc_ok=false +for ac_cxx_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + Syntax error +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO" +then : + +else $as_nop + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO" +then : + # Broken: success on invalid input. +continue +else $as_nop + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok +then : + +else $as_nop + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "C++ preprocessor \"$CXXCPP\" fails sanity check +See \`config.log' for more details" "$LINENO" 5; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +else + _lt_caught_CXX_error=yes +fi + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + +archive_cmds_need_lc_CXX=no +allow_undefined_flag_CXX= +always_export_symbols_CXX=no +archive_expsym_cmds_CXX= +compiler_needs_object_CXX=no +export_dynamic_flag_spec_CXX= +hardcode_direct_CXX=no +hardcode_direct_absolute_CXX=no +hardcode_libdir_flag_spec_CXX= +hardcode_libdir_separator_CXX= +hardcode_minus_L_CXX=no +hardcode_shlibpath_var_CXX=unsupported +hardcode_automatic_CXX=no +inherit_rpath_CXX=no +module_cmds_CXX= +module_expsym_cmds_CXX= +link_all_deplibs_CXX=unknown +old_archive_cmds_CXX=$old_archive_cmds +reload_flag_CXX=$reload_flag +reload_cmds_CXX=$reload_cmds +no_undefined_flag_CXX= +whole_archive_flag_spec_CXX= +enable_shared_with_static_runtimes_CXX=no + +# Source file extension for C++ test sources. +ac_ext=cpp + +# Object file extension for compiled C++ test sources. +objext=o +objext_CXX=$objext + +# No sense in running all these tests if we already determined that +# the CXX compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test yes != "$_lt_caught_CXX_error"; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="int some_variable = 0;" + + # Code to be used in simple link tests + lt_simple_link_test_code='int main(int, char *[]) { return(0); }' + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + + + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + + + # save warnings/boilerplate of simple test code + ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$RM conftest* + + ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$RM -r conftest* + + + # Allow CC to be a program name with arguments. + lt_save_CC=$CC + lt_save_CFLAGS=$CFLAGS + lt_save_LD=$LD + lt_save_GCC=$GCC + GCC=$GXX + lt_save_with_gnu_ld=$with_gnu_ld + lt_save_path_LD=$lt_cv_path_LD + if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then + lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx + else + $as_unset lt_cv_prog_gnu_ld + fi + if test -n "${lt_cv_path_LDCXX+set}"; then + lt_cv_path_LD=$lt_cv_path_LDCXX + else + $as_unset lt_cv_path_LD + fi + test -z "${LDCXX+set}" || LD=$LDCXX + CC=${CXX-"c++"} + CFLAGS=$CXXFLAGS + compiler=$CC + compiler_CXX=$CC + func_cc_basename $compiler +cc_basename=$func_cc_basename_result + + + if test -n "$compiler"; then + # We don't want -fno-exception when compiling C++ code, so set the + # no_builtin_flag separately + if test yes = "$GXX"; then + lt_prog_compiler_no_builtin_flag_CXX=' -fno-builtin' + else + lt_prog_compiler_no_builtin_flag_CXX= + fi + + if test yes = "$GXX"; then + # Set up default GNU C++ configuration + + + +# Check whether --with-gnu-ld was given. +if test ${with_gnu_ld+y} +then : + withval=$with_gnu_ld; test no = "$withval" || with_gnu_ld=yes +else $as_nop + with_gnu_ld=no +fi + +ac_prog=ld +if test yes = "$GCC"; then + # Check if gcc -print-prog-name=ld gives a path. + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 +printf %s "checking for ld used by $CC... " >&6; } + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return, which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [\\/]* | ?:[\\/]*) + re_direlt='/[^/][^/]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` + while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do + ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD=$ac_prog + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test yes = "$with_gnu_ld"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 +printf %s "checking for GNU ld... " >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 +printf %s "checking for non-GNU ld... " >&6; } +fi +if test ${lt_cv_path_LD+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -z "$LD"; then + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS=$lt_save_ifs + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD=$ac_dir/$ac_prog + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 &5 +printf "%s\n" "$LD" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi +test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 +printf %s "checking if the linker ($LD) is GNU ld... " >&6; } +if test ${lt_cv_prog_gnu_ld+y} +then : + printf %s "(cached) " >&6 +else $as_nop + # I'd rather use --version here, but apparently some GNU lds only accept -v. +case `$LD -v 2>&1 &5 +printf "%s\n" "$lt_cv_prog_gnu_ld" >&6; } +with_gnu_ld=$lt_cv_prog_gnu_ld + + + + + + + + # Check if GNU C++ uses GNU ld as the underlying linker, since the + # archiving commands below assume that GNU ld is being used. + if test yes = "$with_gnu_ld"; then + archive_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + + hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir' + export_dynamic_flag_spec_CXX='$wl--export-dynamic' + + # If archive_cmds runs LD, not CC, wlarc should be empty + # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to + # investigate it a little bit more. (MM) + wlarc='$wl' + + # ancient GNU ld didn't support --whole-archive et. al. + if eval "`$CC -print-prog-name=ld` --help 2>&1" | + $GREP 'no-whole-archive' > /dev/null; then + whole_archive_flag_spec_CXX=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' + else + whole_archive_flag_spec_CXX= + fi + else + with_gnu_ld=no + wlarc= + + # A generic and very simple default shared library creation + # command for GNU C++ for the case where it uses the native + # linker, instead of GNU ld. If possible, this setting should + # overridden to take advantage of the native linker features on + # the platform it is being used on. + archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + fi + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' + + else + GXX=no + with_gnu_ld=no + wlarc= + fi + + # PORTME: fill in a description of your system's C++ link characteristics + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +printf %s "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } + ld_shlibs_CXX=yes + case $host_os in + aix3*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + aix[4-9]*) + if test ia64 = "$host_cpu"; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag= + else + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # have runtime linking enabled, and use it for executables. + # For shared libraries, we enable/disable runtime linking + # depending on the kind of the shared library created - + # when "with_aix_soname,aix_use_runtimelinking" is: + # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables + # "aix,yes" lib.so shared, rtl:yes, for executables + # lib.a static archive + # "both,no" lib.so.V(shr.o) shared, rtl:yes + # lib.a(lib.so.V) shared, rtl:no, for executables + # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables + # lib.a(lib.so.V) shared, rtl:no + # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables + # lib.a static archive + case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) + for ld_flag in $LDFLAGS; do + case $ld_flag in + *-brtl*) + aix_use_runtimelinking=yes + break + ;; + esac + done + if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then + # With aix-soname=svr4, we create the lib.so.V shared archives only, + # so we don't have lib.a shared libs to link our executables. + # We have to force runtime linking in this case. + aix_use_runtimelinking=yes + LDFLAGS="$LDFLAGS -Wl,-brtl" + fi + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + archive_cmds_CXX='' + hardcode_direct_CXX=yes + hardcode_direct_absolute_CXX=yes + hardcode_libdir_separator_CXX=':' + link_all_deplibs_CXX=yes + file_list_spec_CXX='$wl-f,' + case $with_aix_soname,$aix_use_runtimelinking in + aix,*) ;; # no import file + svr4,* | *,yes) # use import file + # The Import File defines what to hardcode. + hardcode_direct_CXX=no + hardcode_direct_absolute_CXX=no + ;; + esac + + if test yes = "$GXX"; then + case $host_os in aix4.[012]|aix4.[012].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`$CC -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + hardcode_direct_CXX=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + hardcode_minus_L_CXX=yes + hardcode_libdir_flag_spec_CXX='-L$libdir' + hardcode_libdir_separator_CXX= + fi + esac + shared_flag='-shared' + if test yes = "$aix_use_runtimelinking"; then + shared_flag=$shared_flag' $wl-G' + fi + # Need to ensure runtime linking is disabled for the traditional + # shared library, or the linker may eventually find shared libraries + # /with/ Import File - we do not want to mix them. + shared_flag_aix='-shared' + shared_flag_svr4='-shared $wl-G' + else + # not using gcc + if test ia64 = "$host_cpu"; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test yes = "$aix_use_runtimelinking"; then + shared_flag='$wl-G' + else + shared_flag='$wl-bM:SRE' + fi + shared_flag_aix='$wl-bM:SRE' + shared_flag_svr4='$wl-G' + fi + fi + + export_dynamic_flag_spec_CXX='$wl-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to + # export. + always_export_symbols_CXX=yes + if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + # The "-G" linker flag allows undefined symbols. + no_undefined_flag_CXX='-bernotok' + # Determine the default libpath from the value encoded in an empty + # executable. + if test set = "${lt_cv_aix_libpath+set}"; then + aix_libpath=$lt_cv_aix_libpath +else + if test ${lt_cv_aix_libpath__CXX+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO" +then : + + lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }' + lt_cv_aix_libpath__CXX=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$lt_cv_aix_libpath__CXX"; then + lt_cv_aix_libpath__CXX=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + if test -z "$lt_cv_aix_libpath__CXX"; then + lt_cv_aix_libpath__CXX=/usr/lib:/lib + fi + +fi + + aix_libpath=$lt_cv_aix_libpath__CXX +fi + + hardcode_libdir_flag_spec_CXX='$wl-blibpath:$libdir:'"$aix_libpath" + + archive_expsym_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag + else + if test ia64 = "$host_cpu"; then + hardcode_libdir_flag_spec_CXX='$wl-R $libdir:/usr/lib:/lib' + allow_undefined_flag_CXX="-z nodefs" + archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + if test set = "${lt_cv_aix_libpath+set}"; then + aix_libpath=$lt_cv_aix_libpath +else + if test ${lt_cv_aix_libpath__CXX+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO" +then : + + lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }' + lt_cv_aix_libpath__CXX=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$lt_cv_aix_libpath__CXX"; then + lt_cv_aix_libpath__CXX=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + if test -z "$lt_cv_aix_libpath__CXX"; then + lt_cv_aix_libpath__CXX=/usr/lib:/lib + fi + +fi + + aix_libpath=$lt_cv_aix_libpath__CXX +fi + + hardcode_libdir_flag_spec_CXX='$wl-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + no_undefined_flag_CXX=' $wl-bernotok' + allow_undefined_flag_CXX=' $wl-berok' + if test yes = "$with_gnu_ld"; then + # We only use this code for GNU lds that support --whole-archive. + whole_archive_flag_spec_CXX='$wl--whole-archive$convenience $wl--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + whole_archive_flag_spec_CXX='$convenience' + fi + archive_cmds_need_lc_CXX=yes + archive_expsym_cmds_CXX='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' + # -brtl affects multiple linker settings, -berok does not and is overridden later + compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([, ]\\)%-berok\\1%g"`' + if test svr4 != "$with_aix_soname"; then + # This is similar to how AIX traditionally builds its shared + # libraries. Need -bnortl late, we may have -brtl in LDFLAGS. + archive_expsym_cmds_CXX="$archive_expsym_cmds_CXX"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' + fi + if test aix != "$with_aix_soname"; then + archive_expsym_cmds_CXX="$archive_expsym_cmds_CXX"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' + else + # used by -dlpreopen to get the symbols + archive_expsym_cmds_CXX="$archive_expsym_cmds_CXX"'~$MV $output_objdir/$realname.d/$soname $output_objdir' + fi + archive_expsym_cmds_CXX="$archive_expsym_cmds_CXX"'~$RM -r $output_objdir/$realname.d' + fi + fi + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + allow_undefined_flag_CXX=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + archive_cmds_CXX='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + else + ld_shlibs_CXX=no + fi + ;; + + chorus*) + case $cc_basename in + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + cygwin* | mingw* | pw32* | cegcc*) + case $GXX,$cc_basename in + ,cl* | no,cl*) + # Native MSVC + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + hardcode_libdir_flag_spec_CXX=' ' + allow_undefined_flag_CXX=unsupported + always_export_symbols_CXX=yes + file_list_spec_CXX='@' + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=.dll + # FIXME: Setting linknames here is a bad hack. + archive_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' + archive_expsym_cmds_CXX='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then + cp "$export_symbols" "$output_objdir/$soname.def"; + echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; + else + $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' + # The linker will not automatically build a static lib if we build a DLL. + # _LT_TAGVAR(old_archive_from_new_cmds, CXX)='true' + enable_shared_with_static_runtimes_CXX=yes + # Don't use ranlib + old_postinstall_cmds_CXX='chmod 644 $oldlib' + postlink_cmds_CXX='lt_outputfile="@OUTPUT@"~ + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile=$lt_outputfile.exe + lt_tool_outputfile=$lt_tool_outputfile.exe + ;; + esac~ + func_to_tool_file "$lt_outputfile"~ + if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' + ;; + *) + # g++ + # _LT_TAGVAR(hardcode_libdir_flag_spec, CXX) is actually meaningless, + # as there is no search path for DLLs. + hardcode_libdir_flag_spec_CXX='-L$libdir' + export_dynamic_flag_spec_CXX='$wl--export-all-symbols' + allow_undefined_flag_CXX=unsupported + always_export_symbols_CXX=no + enable_shared_with_static_runtimes_CXX=yes + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file, use it as + # is; otherwise, prepend EXPORTS... + archive_expsym_cmds_CXX='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + ld_shlibs_CXX=no + fi + ;; + esac + ;; + darwin* | rhapsody*) + + + archive_cmds_need_lc_CXX=no + hardcode_direct_CXX=no + hardcode_automatic_CXX=yes + hardcode_shlibpath_var_CXX=unsupported + if test yes = "$lt_cv_ld_force_load"; then + whole_archive_flag_spec_CXX='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' + + else + whole_archive_flag_spec_CXX='' + fi + link_all_deplibs_CXX=yes + allow_undefined_flag_CXX=$_lt_dar_allow_undefined + case $cc_basename in + ifort*|nagfor*) _lt_dar_can_shared=yes ;; + *) _lt_dar_can_shared=$GCC ;; + esac + if test yes = "$_lt_dar_can_shared"; then + output_verbose_link_cmd=func_echo_all + archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil" + module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil" + archive_expsym_cmds_CXX="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" + module_expsym_cmds_CXX="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" + if test yes != "$lt_cv_apple_cc_single_mod"; then + archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dsymutil" + archive_expsym_cmds_CXX="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dar_export_syms$_lt_dsymutil" + fi + + else + ld_shlibs_CXX=no + fi + + ;; + + os2*) + hardcode_libdir_flag_spec_CXX='-L$libdir' + hardcode_minus_L_CXX=yes + allow_undefined_flag_CXX=unsupported + shrext_cmds=.dll + archive_cmds_CXX='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + archive_expsym_cmds_CXX='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + prefix_cmds="$SED"~ + if test EXPORTS = "`$SED 1q $export_symbols`"; then + prefix_cmds="$prefix_cmds -e 1d"; + fi~ + prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ + cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + old_archive_From_new_cmds_CXX='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' + enable_shared_with_static_runtimes_CXX=yes + ;; + + dgux*) + case $cc_basename in + ec++*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + ghcx*) + # Green Hills C++ Compiler + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + freebsd2.*) + # C++ shared libraries reported to be fairly broken before + # switch to ELF + ld_shlibs_CXX=no + ;; + + freebsd-elf*) + archive_cmds_need_lc_CXX=no + ;; + + freebsd* | dragonfly*) + # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF + # conventions + ld_shlibs_CXX=yes + ;; + + haiku*) + archive_cmds_CXX='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + link_all_deplibs_CXX=yes + ;; + + hpux9*) + hardcode_libdir_flag_spec_CXX='$wl+b $wl$libdir' + hardcode_libdir_separator_CXX=: + export_dynamic_flag_spec_CXX='$wl-E' + hardcode_direct_CXX=yes + hardcode_minus_L_CXX=yes # Not in the search PATH, + # but as the default + # location of the library. + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + aCC*) + archive_cmds_CXX='$RM $output_objdir/$soname~$CC -b $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP " \-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test yes = "$GXX"; then + archive_cmds_CXX='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' + else + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + fi + ;; + esac + ;; + + hpux10*|hpux11*) + if test no = "$with_gnu_ld"; then + hardcode_libdir_flag_spec_CXX='$wl+b $wl$libdir' + hardcode_libdir_separator_CXX=: + + case $host_cpu in + hppa*64*|ia64*) + ;; + *) + export_dynamic_flag_spec_CXX='$wl-E' + ;; + esac + fi + case $host_cpu in + hppa*64*|ia64*) + hardcode_direct_CXX=no + hardcode_shlibpath_var_CXX=no + ;; + *) + hardcode_direct_CXX=yes + hardcode_direct_absolute_CXX=yes + hardcode_minus_L_CXX=yes # Not in the search PATH, + # but as the default + # location of the library. + ;; + esac + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + aCC*) + case $host_cpu in + hppa*64*) + archive_cmds_CXX='$CC -b $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + archive_cmds_CXX='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + archive_cmds_CXX='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP " \-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test yes = "$GXX"; then + if test no = "$with_gnu_ld"; then + case $host_cpu in + hppa*64*) + archive_cmds_CXX='$CC -shared -nostdlib -fPIC $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + archive_cmds_CXX='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + archive_cmds_CXX='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + fi + else + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + fi + ;; + esac + ;; + + interix[3-9]*) + hardcode_direct_CXX=no + hardcode_shlibpath_var_CXX=no + hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir' + export_dynamic_flag_spec_CXX='$wl-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + archive_cmds_CXX='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + archive_expsym_cmds_CXX='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + irix5* | irix6*) + case $cc_basename in + CC*) + # SGI C++ + archive_cmds_CXX='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + + # Archives containing C++ object files must be created using + # "CC -ar", where "CC" is the IRIX C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + old_archive_cmds_CXX='$CC -ar -WR,-u -o $oldlib $oldobjs' + ;; + *) + if test yes = "$GXX"; then + if test no = "$with_gnu_ld"; then + archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + else + archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` -o $lib' + fi + fi + link_all_deplibs_CXX=yes + ;; + esac + hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir' + hardcode_libdir_separator_CXX=: + inherit_rpath_CXX=yes + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + archive_expsym_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib $wl-retain-symbols-file,$export_symbols; mv \$templib $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + + hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir' + export_dynamic_flag_spec_CXX='$wl--export-dynamic' + + # Archives containing C++ object files must be created using + # "CC -Bstatic", where "CC" is the KAI C++ compiler. + old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' + ;; + icpc* | ecpc* ) + # Intel C++ + with_gnu_ld=yes + # version 8.0 and above of icpc choke on multiply defined symbols + # if we add $predep_objects and $postdep_objects, however 7.1 and + # earlier do not add the objects themselves. + case `$CC -V 2>&1` in + *"Version 7."*) + archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + ;; + *) # Version 8.0 or newer + tmp_idyn= + case $host_cpu in + ia64*) tmp_idyn=' -i_dynamic';; + esac + archive_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + ;; + esac + archive_cmds_need_lc_CXX=no + hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir' + export_dynamic_flag_spec_CXX='$wl--export-dynamic' + whole_archive_flag_spec_CXX='$wl--whole-archive$convenience $wl--no-whole-archive' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + case `$CC -V` in + *pgCC\ [1-5].* | *pgcpp\ [1-5].*) + prelink_cmds_CXX='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ + compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' + old_archive_cmds_CXX='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ + $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ + $RANLIB $oldlib' + archive_cmds_CXX='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + ;; + *) # Version 6 and above use weak symbols + archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + ;; + esac + + hardcode_libdir_flag_spec_CXX='$wl--rpath $wl$libdir' + export_dynamic_flag_spec_CXX='$wl--export-dynamic' + whole_archive_flag_spec_CXX='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + ;; + cxx*) + # Compaq C++ + archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib $wl-retain-symbols-file $wl$export_symbols' + + runpath_var=LD_RUN_PATH + hardcode_libdir_flag_spec_CXX='-rpath $libdir' + hardcode_libdir_separator_CXX=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' + ;; + xl* | mpixl* | bgxl*) + # IBM XL 8.0 on PPC, with GNU ld + hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir' + export_dynamic_flag_spec_CXX='$wl--export-dynamic' + archive_cmds_CXX='$CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + if test yes = "$supports_anon_versioning"; then + archive_expsym_cmds_CXX='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' + fi + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + no_undefined_flag_CXX=' -zdefs' + archive_cmds_CXX='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + archive_expsym_cmds_CXX='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file $wl$export_symbols' + hardcode_libdir_flag_spec_CXX='-R$libdir' + whole_archive_flag_spec_CXX='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + compiler_needs_object_CXX=yes + + # Not sure whether something based on + # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 + # would be better. + output_verbose_link_cmd='func_echo_all' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs' + ;; + esac + ;; + esac + ;; + + lynxos*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + + m88k*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + + mvs*) + case $cc_basename in + cxx*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds_CXX='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' + wlarc= + hardcode_libdir_flag_spec_CXX='-R$libdir' + hardcode_direct_CXX=yes + hardcode_shlibpath_var_CXX=no + fi + # Workaround some broken pre-1.5 toolchains + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' + ;; + + *nto* | *qnx*) + ld_shlibs_CXX=yes + ;; + + openbsd* | bitrig*) + if test -f /usr/libexec/ld.so; then + hardcode_direct_CXX=yes + hardcode_shlibpath_var_CXX=no + hardcode_direct_absolute_CXX=yes + archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir' + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`"; then + archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file,$export_symbols -o $lib' + export_dynamic_flag_spec_CXX='$wl-E' + whole_archive_flag_spec_CXX=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' + fi + output_verbose_link_cmd=func_echo_all + else + ld_shlibs_CXX=no + fi + ;; + + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + + hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir' + hardcode_libdir_separator_CXX=: + + # Archives containing C++ object files must be created using + # the KAI C++ compiler. + case $host in + osf3*) old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' ;; + *) old_archive_cmds_CXX='$CC -o $oldlib $oldobjs' ;; + esac + ;; + RCC*) + # Rational C++ 2.4.1 + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + cxx*) + case $host in + osf3*) + allow_undefined_flag_CXX=' $wl-expect_unresolved $wl\*' + archive_cmds_CXX='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $soname `test -n "$verstring" && func_echo_all "$wl-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir' + ;; + *) + allow_undefined_flag_CXX=' -expect_unresolved \*' + archive_cmds_CXX='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + archive_expsym_cmds_CXX='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ + echo "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname $wl-input $wl$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~ + $RM $lib.exp' + hardcode_libdir_flag_spec_CXX='-rpath $libdir' + ;; + esac + + hardcode_libdir_separator_CXX=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test yes,no = "$GXX,$with_gnu_ld"; then + allow_undefined_flag_CXX=' $wl-expect_unresolved $wl\*' + case $host in + osf3*) + archive_cmds_CXX='$CC -shared -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + ;; + *) + archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + ;; + esac + + hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir' + hardcode_libdir_separator_CXX=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' + + else + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + fi + ;; + esac + ;; + + psos*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + lcc*) + # Lucid + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + solaris*) + case $cc_basename in + CC* | sunCC*) + # Sun C++ 4.2, 5.x and Centerline C++ + archive_cmds_need_lc_CXX=yes + no_undefined_flag_CXX=' -zdefs' + archive_cmds_CXX='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G$allow_undefined_flag $wl-M $wl$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + hardcode_libdir_flag_spec_CXX='-R$libdir' + hardcode_shlibpath_var_CXX=no + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands '-z linker_flag'. + # Supported since Solaris 2.6 (maybe 2.5.1?) + whole_archive_flag_spec_CXX='-z allextract$convenience -z defaultextract' + ;; + esac + link_all_deplibs_CXX=yes + + output_verbose_link_cmd='func_echo_all' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs' + ;; + gcx*) + # Green Hills C++ Compiler + archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' + + # The C++ compiler must be used to create the archive. + old_archive_cmds_CXX='$CC $LDFLAGS -archive -o $oldlib $oldobjs' + ;; + *) + # GNU C++ compiler with Solaris linker + if test yes,no = "$GXX,$with_gnu_ld"; then + no_undefined_flag_CXX=' $wl-z ${wl}defs' + if $CC --version | $GREP -v '^2\.7' > /dev/null; then + archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' + archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared $pic_flag -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' + else + # g++ 2.7 appears to require '-G' NOT '-shared' on this + # platform. + archive_cmds_CXX='$CC -G -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' + archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' + fi + + hardcode_libdir_flag_spec_CXX='$wl-R $wl$libdir' + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + whole_archive_flag_spec_CXX='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' + ;; + esac + fi + ;; + esac + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) + no_undefined_flag_CXX='$wl-z,text' + archive_cmds_need_lc_CXX=no + hardcode_shlibpath_var_CXX=no + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + archive_cmds_CXX='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds_CXX='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We CANNOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + no_undefined_flag_CXX='$wl-z,text' + allow_undefined_flag_CXX='$wl-z,nodefs' + archive_cmds_need_lc_CXX=no + hardcode_shlibpath_var_CXX=no + hardcode_libdir_flag_spec_CXX='$wl-R,$libdir' + hardcode_libdir_separator_CXX=':' + link_all_deplibs_CXX=yes + export_dynamic_flag_spec_CXX='$wl-Bexport' + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + archive_cmds_CXX='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + old_archive_cmds_CXX='$CC -Tprelink_objects $oldobjs~ + '"$old_archive_cmds_CXX" + reload_cmds_CXX='$CC -Tprelink_objects $reload_objs~ + '"$reload_cmds_CXX" + ;; + *) + archive_cmds_CXX='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + vxworks*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5 +printf "%s\n" "$ld_shlibs_CXX" >&6; } + test no = "$ld_shlibs_CXX" && can_build_shared=no + + GCC_CXX=$GXX + LD_CXX=$LD + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + # Dependencies to place before and after the object being linked: +predep_objects_CXX= +postdep_objects_CXX= +predeps_CXX= +postdeps_CXX= +compiler_lib_search_path_CXX= + +cat > conftest.$ac_ext <<_LT_EOF +class Foo +{ +public: + Foo (void) { a = 0; } +private: + int a; +}; +_LT_EOF + + +_lt_libdeps_save_CFLAGS=$CFLAGS +case "$CC $CFLAGS " in #( +*\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; +*\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; +*\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;; +esac + +if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + # Parse the compiler output and extract the necessary + # objects, libraries and library flags. + + # Sentinel used to keep track of whether or not we are before + # the conftest object file. + pre_test_object_deps_done=no + + for p in `eval "$output_verbose_link_cmd"`; do + case $prev$p in + + -L* | -R* | -l*) + # Some compilers place space between "-{L,R}" and the path. + # Remove the space. + if test x-L = "$p" || + test x-R = "$p"; then + prev=$p + continue + fi + + # Expand the sysroot to ease extracting the directories later. + if test -z "$prev"; then + case $p in + -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;; + -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;; + -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;; + esac + fi + case $p in + =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; + esac + if test no = "$pre_test_object_deps_done"; then + case $prev in + -L | -R) + # Internal compiler library paths should come after those + # provided the user. The postdeps already come after the + # user supplied libs so there is no need to process them. + if test -z "$compiler_lib_search_path_CXX"; then + compiler_lib_search_path_CXX=$prev$p + else + compiler_lib_search_path_CXX="${compiler_lib_search_path_CXX} $prev$p" + fi + ;; + # The "-l" case would never come before the object being + # linked, so don't bother handling this case. + esac + else + if test -z "$postdeps_CXX"; then + postdeps_CXX=$prev$p + else + postdeps_CXX="${postdeps_CXX} $prev$p" + fi + fi + prev= + ;; + + *.lto.$objext) ;; # Ignore GCC LTO objects + *.$objext) + # This assumes that the test object file only shows up + # once in the compiler output. + if test "$p" = "conftest.$objext"; then + pre_test_object_deps_done=yes + continue + fi + + if test no = "$pre_test_object_deps_done"; then + if test -z "$predep_objects_CXX"; then + predep_objects_CXX=$p + else + predep_objects_CXX="$predep_objects_CXX $p" + fi + else + if test -z "$postdep_objects_CXX"; then + postdep_objects_CXX=$p + else + postdep_objects_CXX="$postdep_objects_CXX $p" + fi + fi + ;; + + *) ;; # Ignore the rest. + + esac + done + + # Clean up. + rm -f a.out a.exe +else + echo "libtool.m4: error: problem compiling CXX test program" +fi + +$RM -f confest.$objext +CFLAGS=$_lt_libdeps_save_CFLAGS + +# PORTME: override above test on systems where it is broken +case $host_os in +interix[3-9]*) + # Interix 3.5 installs completely hosed .la files for C++, so rather than + # hack all around it, let's just trust "g++" to DTRT. + predep_objects_CXX= + postdep_objects_CXX= + postdeps_CXX= + ;; +esac + + +case " $postdeps_CXX " in +*" -lc "*) archive_cmds_need_lc_CXX=no ;; +esac + compiler_lib_search_dirs_CXX= +if test -n "${compiler_lib_search_path_CXX}"; then + compiler_lib_search_dirs_CXX=`echo " ${compiler_lib_search_path_CXX}" | $SED -e 's! -L! !g' -e 's!^ !!'` +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + lt_prog_compiler_wl_CXX= +lt_prog_compiler_pic_CXX= +lt_prog_compiler_static_CXX= + + + # C++ specific cases for pic, static, wl, etc. + if test yes = "$GXX"; then + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test ia64 = "$host_cpu"; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static_CXX='-Bstatic' + fi + lt_prog_compiler_pic_CXX='-fPIC' + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + lt_prog_compiler_pic_CXX='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the '-m68020' flag to GCC prevents building anything better, + # like '-m68040'. + lt_prog_compiler_pic_CXX='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + mingw* | cygwin* | os2* | pw32* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + lt_prog_compiler_pic_CXX='-DDLL_EXPORT' + case $host_os in + os2*) + lt_prog_compiler_static_CXX='$wl-static' + ;; + esac + ;; + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic_CXX='-fno-common' + ;; + *djgpp*) + # DJGPP does not support shared libraries at all + lt_prog_compiler_pic_CXX= + ;; + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + lt_prog_compiler_static_CXX= + ;; + interix[3-9]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic_CXX=-Kconform_pic + fi + ;; + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + ;; + *) + lt_prog_compiler_pic_CXX='-fPIC' + ;; + esac + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic_CXX='-fPIC -shared' + ;; + *) + lt_prog_compiler_pic_CXX='-fPIC' + ;; + esac + else + case $host_os in + aix[4-9]*) + # All AIX code is PIC. + if test ia64 = "$host_cpu"; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static_CXX='-Bstatic' + else + lt_prog_compiler_static_CXX='-bnso -bI:/lib/syscalls.exp' + fi + ;; + chorus*) + case $cc_basename in + cxch68*) + # Green Hills C++ Compiler + # _LT_TAGVAR(lt_prog_compiler_static, CXX)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" + ;; + esac + ;; + mingw* | cygwin* | os2* | pw32* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_prog_compiler_pic_CXX='-DDLL_EXPORT' + ;; + dgux*) + case $cc_basename in + ec++*) + lt_prog_compiler_pic_CXX='-KPIC' + ;; + ghcx*) + # Green Hills C++ Compiler + lt_prog_compiler_pic_CXX='-pic' + ;; + *) + ;; + esac + ;; + freebsd* | dragonfly*) + # FreeBSD uses GNU C++ + ;; + hpux9* | hpux10* | hpux11*) + case $cc_basename in + CC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='$wl-a ${wl}archive' + if test ia64 != "$host_cpu"; then + lt_prog_compiler_pic_CXX='+Z' + fi + ;; + aCC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='$wl-a ${wl}archive' + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic_CXX='+Z' + ;; + esac + ;; + *) + ;; + esac + ;; + interix*) + # This is c89, which is MS Visual C++ (no shared libs) + # Anyone wants to do a port? + ;; + irix5* | irix6* | nonstopux*) + case $cc_basename in + CC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='-non_shared' + # CC pic flag -KPIC is the default. + ;; + *) + ;; + esac + ;; + linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + case $cc_basename in + KCC*) + # KAI C++ Compiler + lt_prog_compiler_wl_CXX='--backend -Wl,' + lt_prog_compiler_pic_CXX='-fPIC' + ;; + ecpc* ) + # old Intel C++ for x86_64, which still supported -KPIC. + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-static' + ;; + icpc* ) + # Intel C++, used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-fPIC' + lt_prog_compiler_static_CXX='-static' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-fpic' + lt_prog_compiler_static_CXX='-Bstatic' + ;; + cxx*) + # Compaq C++ + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + lt_prog_compiler_pic_CXX= + lt_prog_compiler_static_CXX='-non_shared' + ;; + xlc* | xlC* | bgxl[cC]* | mpixl[cC]*) + # IBM XL 8.0, 9.0 on PPC and BlueGene + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-qpic' + lt_prog_compiler_static_CXX='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-Bstatic' + lt_prog_compiler_wl_CXX='-Qoption ld ' + ;; + esac + ;; + esac + ;; + lynxos*) + ;; + m88k*) + ;; + mvs*) + case $cc_basename in + cxx*) + lt_prog_compiler_pic_CXX='-W c,exportall' + ;; + *) + ;; + esac + ;; + netbsd* | netbsdelf*-gnu) + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic_CXX='-fPIC -shared' + ;; + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + lt_prog_compiler_wl_CXX='--backend -Wl,' + ;; + RCC*) + # Rational C++ 2.4.1 + lt_prog_compiler_pic_CXX='-pic' + ;; + cxx*) + # Digital/Compaq C++ + lt_prog_compiler_wl_CXX='-Wl,' + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + lt_prog_compiler_pic_CXX= + lt_prog_compiler_static_CXX='-non_shared' + ;; + *) + ;; + esac + ;; + psos*) + ;; + solaris*) + case $cc_basename in + CC* | sunCC*) + # Sun C++ 4.2, 5.x and Centerline C++ + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-Bstatic' + lt_prog_compiler_wl_CXX='-Qoption ld ' + ;; + gcx*) + # Green Hills C++ Compiler + lt_prog_compiler_pic_CXX='-PIC' + ;; + *) + ;; + esac + ;; + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + lt_prog_compiler_pic_CXX='-pic' + lt_prog_compiler_static_CXX='-Bstatic' + ;; + lcc*) + # Lucid + lt_prog_compiler_pic_CXX='-pic' + ;; + *) + ;; + esac + ;; + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + case $cc_basename in + CC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-Bstatic' + ;; + esac + ;; + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + lt_prog_compiler_pic_CXX='-KPIC' + ;; + *) + ;; + esac + ;; + vxworks*) + ;; + *) + lt_prog_compiler_can_build_shared_CXX=no + ;; + esac + fi + +case $host_os in + # For platforms that do not support PIC, -DPIC is meaningless: + *djgpp*) + lt_prog_compiler_pic_CXX= + ;; + *) + lt_prog_compiler_pic_CXX="$lt_prog_compiler_pic_CXX -DPIC" + ;; +esac + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 +printf %s "checking for $compiler option to produce PIC... " >&6; } +if test ${lt_cv_prog_compiler_pic_CXX+y} +then : + printf %s "(cached) " >&6 +else $as_nop + lt_cv_prog_compiler_pic_CXX=$lt_prog_compiler_pic_CXX +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_CXX" >&5 +printf "%s\n" "$lt_cv_prog_compiler_pic_CXX" >&6; } +lt_prog_compiler_pic_CXX=$lt_cv_prog_compiler_pic_CXX + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$lt_prog_compiler_pic_CXX"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works" >&5 +printf %s "checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works... " >&6; } +if test ${lt_cv_prog_compiler_pic_works_CXX+y} +then : + printf %s "(cached) " >&6 +else $as_nop + lt_cv_prog_compiler_pic_works_CXX=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$lt_prog_compiler_pic_CXX -DPIC" ## exclude from sc_useless_quotes_in_assignment + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_pic_works_CXX=yes + fi + fi + $RM conftest* + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works_CXX" >&5 +printf "%s\n" "$lt_cv_prog_compiler_pic_works_CXX" >&6; } + +if test yes = "$lt_cv_prog_compiler_pic_works_CXX"; then + case $lt_prog_compiler_pic_CXX in + "" | " "*) ;; + *) lt_prog_compiler_pic_CXX=" $lt_prog_compiler_pic_CXX" ;; + esac +else + lt_prog_compiler_pic_CXX= + lt_prog_compiler_can_build_shared_CXX=no +fi + +fi + + + + + +# +# Check to make sure the static flag actually works. +# +wl=$lt_prog_compiler_wl_CXX eval lt_tmp_static_flag=\"$lt_prog_compiler_static_CXX\" +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 +printf %s "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } +if test ${lt_cv_prog_compiler_static_works_CXX+y} +then : + printf %s "(cached) " >&6 +else $as_nop + lt_cv_prog_compiler_static_works_CXX=no + save_LDFLAGS=$LDFLAGS + LDFLAGS="$LDFLAGS $lt_tmp_static_flag" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_static_works_CXX=yes + fi + else + lt_cv_prog_compiler_static_works_CXX=yes + fi + fi + $RM -r conftest* + LDFLAGS=$save_LDFLAGS + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works_CXX" >&5 +printf "%s\n" "$lt_cv_prog_compiler_static_works_CXX" >&6; } + +if test yes = "$lt_cv_prog_compiler_static_works_CXX"; then + : +else + lt_prog_compiler_static_CXX= +fi + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +printf %s "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if test ${lt_cv_prog_compiler_c_o_CXX+y} +then : + printf %s "(cached) " >&6 +else $as_nop + lt_cv_prog_compiler_c_o_CXX=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o_CXX=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5 +printf "%s\n" "$lt_cv_prog_compiler_c_o_CXX" >&6; } + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +printf %s "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if test ${lt_cv_prog_compiler_c_o_CXX+y} +then : + printf %s "(cached) " >&6 +else $as_nop + lt_cv_prog_compiler_c_o_CXX=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o_CXX=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5 +printf "%s\n" "$lt_cv_prog_compiler_c_o_CXX" >&6; } + + + + +hard_links=nottested +if test no = "$lt_cv_prog_compiler_c_o_CXX" && test no != "$need_locks"; then + # do not overwrite the value of need_locks provided by the user + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 +printf %s "checking if we can lock with hard links... " >&6; } + hard_links=yes + $RM conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 +printf "%s\n" "$hard_links" >&6; } + if test no = "$hard_links"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&5 +printf "%s\n" "$as_me: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&2;} + need_locks=warn + fi +else + need_locks=no +fi + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +printf %s "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } + + export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + exclude_expsyms_CXX='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' + case $host_os in + aix[4-9]*) + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to GNU nm, but means don't demangle to AIX nm. + # Without the "-l" option, or with the "-B" option, AIX nm treats + # weak defined symbols like other global defined symbols, whereas + # GNU nm marks them as "W". + # While the 'weak' keyword is ignored in the Export File, we need + # it in the Import File for the 'aix-soname' feature, so we have + # to replace the "-B" option with "-P" for AIX nm. + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + export_symbols_cmds_CXX='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' + else + export_symbols_cmds_CXX='`func_echo_all $NM | $SED -e '\''s/B\([^B]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && (substr(\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' + fi + ;; + pw32*) + export_symbols_cmds_CXX=$ltdll_cmds + ;; + cygwin* | mingw* | cegcc*) + case $cc_basename in + cl*) + exclude_expsyms_CXX='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' + ;; + *) + export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' + exclude_expsyms_CXX='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' + ;; + esac + ;; + linux* | k*bsd*-gnu | gnu*) + link_all_deplibs_CXX=no + ;; + *) + export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + ;; + esac + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5 +printf "%s\n" "$ld_shlibs_CXX" >&6; } +test no = "$ld_shlibs_CXX" && can_build_shared=no + +with_gnu_ld_CXX=$with_gnu_ld + + + + + + +# +# Do we need to explicitly link libc? +# +case "x$archive_cmds_need_lc_CXX" in +x|xyes) + # Assume -lc should be added + archive_cmds_need_lc_CXX=yes + + if test yes,yes = "$GCC,$enable_shared"; then + case $archive_cmds_CXX in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 +printf %s "checking whether -lc should be explicitly linked in... " >&6; } +if test ${lt_cv_archive_cmds_need_lc_CXX+y} +then : + printf %s "(cached) " >&6 +else $as_nop + $RM conftest* + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$lt_prog_compiler_wl_CXX + pic_flag=$lt_prog_compiler_pic_CXX + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$allow_undefined_flag_CXX + allow_undefined_flag_CXX= + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 + (eval $archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + then + lt_cv_archive_cmds_need_lc_CXX=no + else + lt_cv_archive_cmds_need_lc_CXX=yes + fi + allow_undefined_flag_CXX=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $RM conftest* + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc_CXX" >&5 +printf "%s\n" "$lt_cv_archive_cmds_need_lc_CXX" >&6; } + archive_cmds_need_lc_CXX=$lt_cv_archive_cmds_need_lc_CXX + ;; + esac + fi + ;; +esac + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 +printf %s "checking dynamic linker characteristics... " >&6; } + +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=.so +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + + + +case $host_os in +aix3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='$libname$release$shared_ext$major' + ;; + +aix[4-9]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test ia64 = "$host_cpu"; then + # AIX 5 supports IA64 + library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line '#! .'. This would cause the generated library to + # depend on '.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[01] | aix4.[01].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # Using Import Files as archive members, it is possible to support + # filename-based versioning of shared library archives on AIX. While + # this would work for both with and without runtime linking, it will + # prevent static linking of such archives. So we do filename-based + # shared library versioning with .so extension only, which is used + # when both runtime linking and shared linking is enabled. + # Unfortunately, runtime linking may impact performance, so we do + # not want this to be the default eventually. Also, we use the + # versioned .so libs for executables only if there is the -brtl + # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only. + # To allow for filename-based versioning support, we need to create + # libNAME.so.V as an archive file, containing: + # *) an Import File, referring to the versioned filename of the + # archive as well as the shared archive member, telling the + # bitwidth (32 or 64) of that shared object, and providing the + # list of exported symbols of that shared object, eventually + # decorated with the 'weak' keyword + # *) the shared object with the F_LOADONLY flag set, to really avoid + # it being seen by the linker. + # At run time we better use the real file rather than another symlink, + # but for link time we create the symlink libNAME.so -> libNAME.so.V + + case $with_aix_soname,$aix_use_runtimelinking in + # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + aix,yes) # traditional libtool + dynamic_linker='AIX unversionable lib.so' + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + ;; + aix,no) # traditional AIX only + dynamic_linker='AIX lib.a(lib.so.V)' + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='$libname$release.a $libname.a' + soname_spec='$libname$release$shared_ext$major' + ;; + svr4,*) # full svr4 only + dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o)" + library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' + # We do not specify a path in Import Files, so LIBPATH fires. + shlibpath_overrides_runpath=yes + ;; + *,yes) # both, prefer svr4 + dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o), lib.a(lib.so.V)" + library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' + # unpreferred sharedlib libNAME.a needs extra handling + postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"' + postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"' + # We do not specify a path in Import Files, so LIBPATH fires. + shlibpath_overrides_runpath=yes + ;; + *,no) # both, prefer aix + dynamic_linker="AIX lib.a(lib.so.V), lib.so.V($shared_archive_member_spec.o)" + library_names_spec='$libname$release.a $libname.a' + soname_spec='$libname$release$shared_ext$major' + # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling + postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)' + postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"' + ;; + esac + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + case $host_cpu in + powerpc) + # Since July 2007 AmigaOS4 officially supports .so libraries. + # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + ;; + m68k) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + esac + ;; + +beos*) + library_names_spec='$libname$shared_ext' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[45]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32* | cegcc*) + version_type=windows + shrext_cmds=.dll + need_version=no + need_lib_prefix=no + + case $GCC,$cc_basename in + yes,*) + # gcc + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + + ;; + mingw* | cegcc*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + ;; + esac + dynamic_linker='Win32 ld.exe' + ;; + + *,cl*) + # Native MSVC + libname_spec='$name' + soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + library_names_spec='$libname.dll.lib' + + case $build_os in + mingw*) + sys_lib_search_path_spec= + lt_save_ifs=$IFS + IFS=';' + for lt_path in $LIB + do + IFS=$lt_save_ifs + # Let DOS variable expansion print the short 8.3 style file name. + lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` + sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" + done + IFS=$lt_save_ifs + # Convert to MSYS style. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` + ;; + cygwin*) + # Convert to unix form, then to dos form, then back to unix form + # but this time dos style (no spaces!) so that the unix form looks + # like /cygdrive/c/PROGRA~1:/cygdr... + sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` + sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` + sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + ;; + *) + sys_lib_search_path_spec=$LIB + if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then + # It is most probably a Windows format PATH. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + # FIXME: find the short name or the path components, as spaces are + # common. (e.g. "Program Files" -> "PROGRA~1") + ;; + esac + + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + dynamic_linker='Win32 link.exe' + ;; + + *) + # Assume MSVC wrapper + library_names_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext $libname.lib' + dynamic_linker='Win32 ld.exe' + ;; + esac + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$major$shared_ext $libname$shared_ext' + soname_spec='$libname$release$major$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' + + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[23].*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2.*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[01]* | freebsdelf3.[01]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ + freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +haiku*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + dynamic_linker="$host_os runtime_loader" + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LIBRARY_PATH + shlibpath_overrides_runpath=no + sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + if test 32 = "$HPUX_IA64_MODE"; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + sys_lib_dlsearch_path_spec=/usr/lib/hpux32 + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + sys_lib_dlsearch_path_spec=/usr/lib/hpux64 + fi + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555, ... + postinstall_cmds='chmod 555 $lib' + # or fails outright, so override atomically: + install_override_mode=555 + ;; + +interix[3-9]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test yes = "$lt_cv_prog_gnu_ld"; then + version_type=linux # correct to gnu/linux during the next big refactor + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='$libname$release$shared_ext$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff" + sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +linux*android*) + version_type=none # Android doesn't support versioned libraries. + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext' + soname_spec='$libname$release$shared_ext' + finish_cmds= + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + dynamic_linker='Android linker' + # Don't embed -rpath directories since the linker doesn't support them. + hardcode_libdir_flag_spec_CXX='-L$libdir' + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + + # Some binutils ld are patched to set DT_RUNPATH + if test ${lt_cv_shlibpath_overrides_runpath+y} +then : + printf %s "(cached) " >&6 +else $as_nop + lt_cv_shlibpath_overrides_runpath=no + save_LDFLAGS=$LDFLAGS + save_libdir=$libdir + eval "libdir=/foo; wl=\"$lt_prog_compiler_wl_CXX\"; \ + LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec_CXX\"" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO" +then : + if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null +then : + lt_cv_shlibpath_overrides_runpath=yes +fi +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS=$save_LDFLAGS + libdir=$save_libdir + +fi + + shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Ideally, we could use ldconfig to report *all* directores which are + # searched for libraries, however this is still not possible. Aside from not + # being certain /sbin/ldconfig is available, command + # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64, + # even though it is searched at run-time. Try to do the best guess by + # appending ld.so.conf contents (and includes) to the search path. + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsdelf*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='NetBSD ld.elf_so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +*nto* | *qnx*) + version_type=qnx + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='ldqnx.so' + ;; + +openbsd* | bitrig*) + version_type=sunos + sys_lib_dlsearch_path_spec=/usr/lib + need_lib_prefix=no + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then + need_version=no + else + need_version=yes + fi + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +os2*) + libname_spec='$name' + version_type=windows + shrext_cmds=.dll + need_version=no + need_lib_prefix=no + # OS/2 can only load a DLL with a base name of 8 characters or less. + soname_spec='`test -n "$os2dllname" && libname="$os2dllname"; + v=$($ECHO $release$versuffix | tr -d .-); + n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _); + $ECHO $n$v`$shared_ext' + library_names_spec='${libname}_dll.$libext' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=BEGINLIBPATH + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='$libname$release$shared_ext$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + +rdos*) + dynamic_linker=no + ;; + +solaris*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test yes = "$with_gnu_ld"; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec; then + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext' + soname_spec='$libname$shared_ext.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=sco + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + if test yes = "$with_gnu_ld"; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +tpf*) + # TPF is a cross-target only. Preferred cross-host = GNU/Linux. + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +uts4*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 +printf "%s\n" "$dynamic_linker" >&6; } +test no = "$dynamic_linker" && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test yes = "$GCC"; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then + sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec +fi + +if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then + sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec +fi + +# remember unaugmented sys_lib_dlsearch_path content for libtool script decls... +configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec + +# ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code +func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH" + +# to be used as default LT_SYS_LIBRARY_PATH value in generated libtool +configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 +printf %s "checking how to hardcode library paths into programs... " >&6; } +hardcode_action_CXX= +if test -n "$hardcode_libdir_flag_spec_CXX" || + test -n "$runpath_var_CXX" || + test yes = "$hardcode_automatic_CXX"; then + + # We can hardcode non-existent directories. + if test no != "$hardcode_direct_CXX" && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, CXX)" && + test no != "$hardcode_minus_L_CXX"; then + # Linking always hardcodes the temporary library directory. + hardcode_action_CXX=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + hardcode_action_CXX=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + hardcode_action_CXX=unsupported +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $hardcode_action_CXX" >&5 +printf "%s\n" "$hardcode_action_CXX" >&6; } + +if test relink = "$hardcode_action_CXX" || + test yes = "$inherit_rpath_CXX"; then + # Fast installation is not supported + enable_fast_install=no +elif test yes = "$shlibpath_overrides_runpath" || + test no = "$enable_shared"; then + # Fast installation is not necessary + enable_fast_install=needless +fi + + + + + + + + fi # test -n "$compiler" + + CC=$lt_save_CC + CFLAGS=$lt_save_CFLAGS + LDCXX=$LD + LD=$lt_save_LD + GCC=$lt_save_GCC + with_gnu_ld=$lt_save_with_gnu_ld + lt_cv_path_LDCXX=$lt_cv_path_LD + lt_cv_path_LD=$lt_save_path_LD + lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld + lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld +fi # test yes != "$_lt_caught_CXX_error" + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + + + + + + + + + + + + + + ac_config_commands="$ac_config_commands libtool" + + + + +# Only expand once: + + + + + + + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 +printf %s "checking for grep that handles long lines and -e... " >&6; } +if test ${ac_cv_path_GREP+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -z "$GREP"; then + ac_path_GREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_prog in grep ggrep + do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_GREP="$as_dir$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_GREP" || continue +# Check for GNU ac_path_GREP and select it if it is found. + # Check for GNU $ac_path_GREP +case `"$ac_path_GREP" --version 2>&1` in +*GNU*) + ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; +*) + ac_count=0 + printf %s 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + printf "%s\n" 'GREP' >> "conftest.nl" + "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_GREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_GREP="$ac_path_GREP" + ac_path_GREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_GREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_GREP"; then + as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_GREP=$GREP +fi + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 +printf "%s\n" "$ac_cv_path_GREP" >&6; } + GREP="$ac_cv_path_GREP" + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 +printf %s "checking for a sed that does not truncate output... " >&6; } +if test ${ac_cv_path_SED+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ + for ac_i in 1 2 3 4 5 6 7; do + ac_script="$ac_script$as_nl$ac_script" + done + echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed + { ac_script=; unset ac_script;} + if test -z "$SED"; then + ac_path_SED_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_prog in sed gsed + do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_SED="$as_dir$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_SED" || continue +# Check for GNU ac_path_SED and select it if it is found. + # Check for GNU $ac_path_SED +case `"$ac_path_SED" --version 2>&1` in +*GNU*) + ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; +*) + ac_count=0 + printf %s 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + printf "%s\n" '' >> "conftest.nl" + "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_SED_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_SED="$ac_path_SED" + ac_path_SED_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_SED_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_SED"; then + as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 + fi +else + ac_cv_path_SED=$SED +fi + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 +printf "%s\n" "$ac_cv_path_SED" >&6; } + SED="$ac_cv_path_SED" + rm -f conftest.sed + +if test "x$with_clang_prefix" != "x"; then + LLVM_CONFIG="$with_clang_prefix/bin/llvm-config" +fi +# Extract the first word of ""llvm-config"", so it can be a program name with args. +set dummy "llvm-config"; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_path_LLVM_CONFIG+y} +then : + printf %s "(cached) " >&6 +else $as_nop + case $LLVM_CONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_LLVM_CONFIG="$LLVM_CONFIG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_path_LLVM_CONFIG="$as_dir$ac_word$ac_exec_ext" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +LLVM_CONFIG=$ac_cv_path_LLVM_CONFIG +if test -n "$LLVM_CONFIG"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $LLVM_CONFIG" >&5 +printf "%s\n" "$LLVM_CONFIG" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + +if test -z "$LLVM_CONFIG" || test ! -x "$LLVM_CONFIG"; then + as_fn_error $? "llvm-config not found" "$LINENO" 5 +fi +CLANG_CXXFLAGS=`$LLVM_CONFIG --cxxflags | \ + $SED -e 's/-Wcovered-switch-default//;s/-gsplit-dwarf//'` +CLANG_LDFLAGS=`$LLVM_CONFIG --ldflags` +# Construct a -R argument for libtool. +# This is needed in case some of the clang libraries are shared libraries. +CLANG_RFLAG=`echo "$CLANG_LDFLAGS" | $SED -e 's/-L/-R/g'` +targets=`$LLVM_CONFIG --targets-built` +components="$targets asmparser bitreader support mc" +# Link in option and frontendopenmp components when available +# since they may be used by the clang libraries. +for c in option frontendopenmp; do + $LLVM_CONFIG --components | $GREP $c > /dev/null 2> /dev/null + if test $? -eq 0; then + components="$components $c" + fi +done +CLANG_LIBS=`$LLVM_CONFIG --libs $components` +systemlibs=`$LLVM_CONFIG --system-libs 2> /dev/null | tail -1` +if test $? -eq 0; then + CLANG_LIBS="$CLANG_LIBS $systemlibs" +fi +CLANG_PREFIX=`$LLVM_CONFIG --prefix` + +printf "%s\n" "#define CLANG_PREFIX \"$CLANG_PREFIX\"" >>confdefs.h + + +# If $CLANG_PREFIX/bin/clang cannot find the standard include files, +# then see if setting sysroot to `xcode-select -p`/SDKs/MacOSX.sdk helps. +# This may be required on some versions of OS X since they lack /usr/include. +# If so, set CLANG_SYSROOT accordingly. +SAVE_CC="$CC" +CC="$CLANG_PREFIX/bin/clang" +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CLANG_PREFIX/bin/clang can find standard include files" >&5 +printf %s "checking whether $CLANG_PREFIX/bin/clang can find standard include files... " >&6; } +found_header=no +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + found_header=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $found_header" >&5 +printf "%s\n" "$found_header" >&6; } +if test "x$found_header" != "xyes"; then + # Extract the first word of "xcode-select", so it can be a program name with args. +set dummy xcode-select; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_XCODE_SELECT+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$XCODE_SELECT"; then + ac_cv_prog_XCODE_SELECT="$XCODE_SELECT" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_XCODE_SELECT="xcode-select" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +XCODE_SELECT=$ac_cv_prog_XCODE_SELECT +if test -n "$XCODE_SELECT"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $XCODE_SELECT" >&5 +printf "%s\n" "$XCODE_SELECT" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + + if test -z "$XCODE_SELECT"; then + as_fn_error $? "Cannot find xcode-select" "$LINENO" 5 + fi + sysroot=`$XCODE_SELECT -p`/SDKs/MacOSX.sdk + SAVE_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS -isysroot $sysroot" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether standard include files can be found with sysroot set" >&5 +printf %s "checking whether standard include files can be found with sysroot set... " >&6; } + found_header=no + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + found_header=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $found_header" >&5 +printf "%s\n" "$found_header" >&6; } + CPPFLAGS="$SAVE_CPPFLAGS" + if test "x$found_header" != "xyes"; then + as_fn_error $? "Cannot find standard include files" "$LINENO" 5 + else + +printf "%s\n" "#define CLANG_SYSROOT \"$sysroot\"" >>confdefs.h + + fi +fi +CC="$SAVE_CC" + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + + +SAVE_CPPFLAGS="$CPPFLAGS" +SAVE_LDFLAGS="$LDFLAGS" +SAVE_LIBS="$LIBS" + +CPPFLAGS="$CLANG_CXXFLAGS -I$srcdir $CPPFLAGS" +ac_fn_cxx_check_header_compile "$LINENO" "clang/Basic/SourceLocation.h" "ac_cv_header_clang_Basic_SourceLocation_h" "$ac_includes_default" +if test "x$ac_cv_header_clang_Basic_SourceLocation_h" = xyes +then : + +else $as_nop + as_fn_error $? "clang header file not found" "$LINENO" 5 +fi + +ac_fn_cxx_check_header_compile "$LINENO" "llvm/TargetParser/Host.h" "ac_cv_header_llvm_TargetParser_Host_h" "$ac_includes_default" +if test "x$ac_cv_header_llvm_TargetParser_Host_h" = xyes +then : + +printf "%s\n" "#define HAVE_TARGETPARSER_HOST_H /**/" >>confdefs.h + +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "getDefaultTargetTriple" >/dev/null 2>&1 +then : + +else $as_nop + +printf "%s\n" "#define getDefaultTargetTriple getHostTriple" >>confdefs.h + +fi +rm -rf conftest* + + +fi + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "getExpansionLineNumber" >/dev/null 2>&1 +then : + +else $as_nop + +printf "%s\n" "#define getExpansionLineNumber getInstantiationLineNumber" >>confdefs.h + +fi +rm -rf conftest* + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "getImmediateExpansionRange" >/dev/null 2>&1 +then : + +else $as_nop + +printf "%s\n" "#define getImmediateExpansionRange getImmediateInstantiationRange" >>confdefs.h + + +fi +rm -rf conftest* + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "DiagnosticsEngine" >/dev/null 2>&1 +then : + +else $as_nop + +printf "%s\n" "#define DiagnosticsEngine Diagnostic" >>confdefs.h + +fi +rm -rf conftest* + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "ArrayRef" >/dev/null 2>&1 +then : + +printf "%s\n" "#define USE_ARRAYREF /**/" >>confdefs.h + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "ArrayRef.*CommandLineArgs" >/dev/null 2>&1 +then : + +printf "%s\n" "#define CREATE_FROM_ARGS_TAKES_ARRAYREF /**/" >>confdefs.h + + +fi +rm -rf conftest* + + +fi +rm -rf conftest* + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "CXXIsProduction" >/dev/null 2>&1 +then : + +printf "%s\n" "#define HAVE_CXXISPRODUCTION /**/" >>confdefs.h + +fi +rm -rf conftest* + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP " IsProduction" >/dev/null 2>&1 +then : + +printf "%s\n" "#define HAVE_ISPRODUCTION /**/" >>confdefs.h + +fi +rm -rf conftest* + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main (void) +{ + + using namespace clang; + DiagnosticsEngine *Diags; + new driver::Driver("", "", "", *Diags); + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO" +then : + +printf "%s\n" "#define DRIVER_CTOR_TAKES_DEFAULTIMAGENAME /**/" >>confdefs.h + +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "void HandleTopLevelDecl\(" >/dev/null 2>&1 +then : + +printf "%s\n" "#define HandleTopLevelDeclReturn void" >>confdefs.h + + +printf "%s\n" "#define HandleTopLevelDeclContinue /**/" >>confdefs.h + +else $as_nop + +printf "%s\n" "#define HandleTopLevelDeclReturn bool" >>confdefs.h + + +printf "%s\n" "#define HandleTopLevelDeclContinue true" >>confdefs.h + +fi +rm -rf conftest* + +ac_fn_cxx_check_header_compile "$LINENO" "clang/Basic/DiagnosticOptions.h" "ac_cv_header_clang_Basic_DiagnosticOptions_h" "$ac_includes_default" +if test "x$ac_cv_header_clang_Basic_DiagnosticOptions_h" = xyes +then : + +printf "%s\n" "#define HAVE_BASIC_DIAGNOSTICOPTIONS_H /**/" >>confdefs.h + +fi + +ac_fn_cxx_check_header_compile "$LINENO" "clang/Lex/PreprocessorOptions.h" "ac_cv_header_clang_Lex_PreprocessorOptions_h" "#include +" +if test "x$ac_cv_header_clang_Lex_PreprocessorOptions_h" = xyes +then : + +printf "%s\n" "#define HAVE_LEX_PREPROCESSOROPTIONS_H /**/" >>confdefs.h + +fi + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main (void) +{ + + using namespace clang; + std::shared_ptr TO; + DiagnosticsEngine *Diags; + TargetInfo::CreateTargetInfo(*Diags, TO); + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO" +then : + +printf "%s\n" "#define CREATETARGETINFO_TAKES_SHARED_PTR /**/" >>confdefs.h + +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main (void) +{ + + using namespace clang; + TargetOptions *TO; + DiagnosticsEngine *Diags; + TargetInfo::CreateTargetInfo(*Diags, TO); + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO" +then : + +printf "%s\n" "#define CREATETARGETINFO_TAKES_POINTER /**/" >>confdefs.h + +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main (void) +{ + + using namespace clang; + DiagnosticConsumer *client; + CompilerInstance *Clang; + Clang->createDiagnostics(client); + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO" +then : + +else $as_nop + +printf "%s\n" "#define CREATEDIAGNOSTICS_TAKES_ARG /**/" >>confdefs.h + +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main (void) +{ + + using namespace clang; + HeaderSearchOptions HSO; + HSO.AddPath("", frontend::Angled, false, false); + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO" +then : + +printf "%s\n" "#define ADDPATH_TAKES_4_ARGUMENTS /**/" >>confdefs.h + +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "getNumParams" >/dev/null 2>&1 +then : + +printf "%s\n" "#define getNumArgs getNumParams" >>confdefs.h + + +printf "%s\n" "#define getArgType getParamType" >>confdefs.h + +fi +rm -rf conftest* + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "getReturnType" >/dev/null 2>&1 +then : + +else $as_nop + +printf "%s\n" "#define getReturnType getResultType" >>confdefs.h + +fi +rm -rf conftest* + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main (void) +{ + + using namespace clang; + CompilerInstance *Clang; + Clang->createPreprocessor(TU_Complete); + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO" +then : + +printf "%s\n" "#define CREATEPREPROCESSOR_TAKES_TUKIND /**/" >>confdefs.h + +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "setMainFileID" >/dev/null 2>&1 +then : + +printf "%s\n" "#define HAVE_SETMAINFILEID /**/" >>confdefs.h + +fi +rm -rf conftest* + +ac_fn_cxx_check_header_compile "$LINENO" "llvm/ADT/OwningPtr.h" "ac_cv_header_llvm_ADT_OwningPtr_h" "$ac_includes_default" +if test "x$ac_cv_header_llvm_ADT_OwningPtr_h" = xyes +then : + +printf "%s\n" "#define HAVE_ADT_OWNINGPTR_H /**/" >>confdefs.h + +fi + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "initializeBuiltins" >/dev/null 2>&1 +then : + +else $as_nop + +printf "%s\n" "#define initializeBuiltins InitializeBuiltins" >>confdefs.h + +fi +rm -rf conftest* + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "IK_C" >/dev/null 2>&1 +then : + +else $as_nop + ac_fn_cxx_check_header_compile "$LINENO" "clang/Basic/LangStandard.h" "ac_cv_header_clang_Basic_LangStandard_h" "$ac_includes_default" +if test "x$ac_cv_header_clang_Basic_LangStandard_h" = xyes +then : + IK_C=Language::C +else $as_nop + IK_C=InputKind::C +fi + + +printf "%s\n" "#define IK_C $IK_C" >>confdefs.h + + +fi +rm -rf conftest* + +# llvmorg-15-init-7544-g93471e65df48 +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "setLangDefaults" >/dev/null 2>&1 +then : + SETLANGDEFAULTS=LangOptions +else $as_nop + SETLANGDEFAULTS=CompilerInvocation +fi +rm -rf conftest* + + +printf "%s\n" "#define SETLANGDEFAULTS $SETLANGDEFAULTS" >>confdefs.h + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #include + #include + #include + + #include "set_lang_defaults_arg4.h" + +int +main (void) +{ + + using namespace clang; + CompilerInstance *Clang; + TargetOptions TO; + llvm::Triple T(TO.Triple); + PreprocessorOptions PO; + SETLANGDEFAULTS::setLangDefaults(Clang->getLangOpts(), IK_C, + T, setLangDefaultsArg4(PO), + LangStandard::lang_unspecified); + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO" +then : + +printf "%s\n" "#define SETLANGDEFAULTS_TAKES_5_ARGUMENTS /**/" >>confdefs.h + +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #include + #include + +int +main (void) +{ + + using namespace clang; + CompilerInvocation *invocation; + CompilerInstance *Clang; + Clang->setInvocation(std::make_shared(*invocation)); + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO" +then : + +printf "%s\n" "#define SETINVOCATION_TAKES_SHARED_PTR /**/" >>confdefs.h + +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +ac_fn_cxx_check_header_compile "$LINENO" "llvm/Option/Arg.h" "ac_cv_header_llvm_Option_Arg_h" "$ac_includes_default" +if test "x$ac_cv_header_llvm_Option_Arg_h" = xyes +then : + +printf "%s\n" "#define HAVE_LLVM_OPTION_ARG_H /**/" >>confdefs.h + +fi + + +LDFLAGS="$CLANG_LDFLAGS $LDFLAGS" + +# A test program for checking whether linking against libclang-cpp works. + + +# Use single libclang-cpp shared library when available. +# Otherwise, use a selection of clang libraries that appears to work. +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for main in -lclang-cpp" >&5 +printf %s "checking for main in -lclang-cpp... " >&6; } +if test ${ac_cv_lib_clang_cpp_main+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_check_lib_save_LIBS=$LIBS +LIBS="-lclang-cpp $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +namespace conftest { + extern "C" int main (); +} +int +main (void) +{ +return conftest::main (); + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO" +then : + ac_cv_lib_clang_cpp_main=yes +else $as_nop + ac_cv_lib_clang_cpp_main=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_clang_cpp_main" >&5 +printf "%s\n" "$ac_cv_lib_clang_cpp_main" >&6; } +if test "x$ac_cv_lib_clang_cpp_main" = xyes +then : + have_lib_clang=yes +else $as_nop + have_lib_clang=no +fi + +if test "$have_lib_clang" = yes; then + # The LLVM libraries may be linked into libclang-cpp already. + # Linking against them again can cause errors about options + # being registered more than once. + # Check whether linking against libclang-cpp requires + # linking against the LLVM libraries as well. + # Fail if linking fails with or without the LLVM libraries. + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether libclang-cpp needs LLVM libraries" >&5 +printf %s "checking whether libclang-cpp needs LLVM libraries... " >&6; } + LIBS="-lclang-cpp $SAVE_LIBS" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main (void) +{ + + new clang::CompilerInstance(); + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO" +then : + clangcpp_needs_llvm=no +else $as_nop + + LIBS="-lclang-cpp $CLANG_LIBS $SAVE_LIBS" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main (void) +{ + + new clang::CompilerInstance(); + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO" +then : + clangcpp_needs_llvm=yes +else $as_nop + clangcpp_needs_llvm=unknown +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $clangcpp_needs_llvm" >&5 +printf "%s\n" "$clangcpp_needs_llvm" >&6; } + if test "$clangcpp_needs_llvm" = "no" +then : + CLANG_LIBS="-lclang-cpp" +elif test "$clangcpp_needs_llvm" = "yes" +then : + CLANG_LIBS="-lclang-cpp $CLANG_LIBS" +else $as_nop + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "unable to link against libclang-cpp +See \`config.log' for more details" "$LINENO" 5; } +fi +else + CLANG_LIBS="-lclangBasic -lclangDriver $CLANG_LIBS" + CLANG_LIBS="-lclangAnalysis -lclangAST -lclangLex $CLANG_LIBS" + LDFLAGS="$CLANG_LDFLAGS $CLANG_LIBS $SAVE_LDFLAGS" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for main in -lclangEdit" >&5 +printf %s "checking for main in -lclangEdit... " >&6; } +if test ${ac_cv_lib_clangEdit_main+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_check_lib_save_LIBS=$LIBS +LIBS="-lclangEdit $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +namespace conftest { + extern "C" int main (); +} +int +main (void) +{ +return conftest::main (); + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO" +then : + ac_cv_lib_clangEdit_main=yes +else $as_nop + ac_cv_lib_clangEdit_main=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_clangEdit_main" >&5 +printf "%s\n" "$ac_cv_lib_clangEdit_main" >&6; } +if test "x$ac_cv_lib_clangEdit_main" = xyes +then : + LIB_CLANG_EDIT=-lclangEdit +fi + + CLANG_LIBS="$LIB_CLANG_EDIT $CLANG_LIBS" + CLANG_LIBS="-lclangParse -lclangSema $CLANG_LIBS" + CLANG_LIBS="-lclangFrontend -lclangSerialization $CLANG_LIBS" +fi + +CPPFLAGS="$SAVE_CPPFLAGS" +LDFLAGS="$SAVE_LDFLAGS" +LIBS="$SAVE_LIBS" + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + +CONFIG_STATUS_DEPENDENCIES=$LLVM_CONFIG + +ac_config_headers="$ac_config_headers isl_config.h" + +ac_config_files="$ac_config_files Makefile" + + +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, we kill variables containing newlines. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +( + for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +printf "%s\n" "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + + (set) 2>&1 | + case $as_nl`(ac_space=' '; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + # `set' does not quote correctly, so add quotes: double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \. + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; #( + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) | + sed ' + /^ac_cv_env_/b end + t clear + :clear + s/^\([^=]*\)=\(.*[{}].*\)$/test ${\1+y} || &/ + t end + s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + :end' >>confcache +if diff "$cache_file" confcache >/dev/null 2>&1; then :; else + if test -w "$cache_file"; then + if test "x$cache_file" != "x/dev/null"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 +printf "%s\n" "$as_me: updating cache $cache_file" >&6;} + if test ! -f "$cache_file" || test -h "$cache_file"; then + cat confcache >"$cache_file" + else + case $cache_file in #( + */* | ?:*) + mv -f confcache "$cache_file"$$ && + mv -f "$cache_file"$$ "$cache_file" ;; #( + *) + mv -f confcache "$cache_file" ;; + esac + fi + fi + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 +printf "%s\n" "$as_me: not updating unwritable cache $cache_file" >&6;} + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +DEFS=-DHAVE_CONFIG_H + +ac_libobjs= +ac_ltlibobjs= +U= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' + ac_i=`printf "%s\n" "$ac_i" | sed "$ac_script"` + # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR + # will be set to the directory where LIBOBJS objects are built. + as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" + as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5 +printf %s "checking that generated files are newer than configure... " >&6; } + if test -n "$am_sleep_pid"; then + # Hide warnings about reused PIDs. + wait $am_sleep_pid 2>/dev/null + fi + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: done" >&5 +printf "%s\n" "done" >&6; } + if test -n "$EXEEXT"; then + am__EXEEXT_TRUE= + am__EXEEXT_FALSE='#' +else + am__EXEEXT_TRUE='#' + am__EXEEXT_FALSE= +fi + +if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then + as_fn_error $? "conditional \"AMDEP\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then + as_fn_error $? "conditional \"am__fastdepCXX\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then + as_fn_error $? "conditional \"am__fastdepCC\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then + as_fn_error $? "conditional \"am__fastdepCC\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then + as_fn_error $? "conditional \"am__fastdepCXX\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi + +: "${CONFIG_STATUS=./config.status}" +ac_write_fail=0 +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 +printf "%s\n" "$as_me: creating $CONFIG_STATUS" >&6;} +as_write_fail=0 +cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false + +SHELL=\${CONFIG_SHELL-$SHELL} +export SHELL +_ASEOF +cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +as_nop=: +if test ${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1 +then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else $as_nop + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + + +# Reset variables that may have inherited troublesome values from +# the environment. + +# IFS needs to be set, to space, tab, and newline, in precisely that order. +# (If _AS_PATH_WALK were called with IFS unset, it would have the +# side effect of setting IFS to empty, thus disabling word splitting.) +# Quoting is to prevent editors from complaining about space-tab. +as_nl=' +' +export as_nl +IFS=" "" $as_nl" + +PS1='$ ' +PS2='> ' +PS4='+ ' + +# Ensure predictable behavior from utilities with locale-dependent output. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# We cannot yet rely on "unset" to work, but we need these variables +# to be unset--not just set to an empty or harmless value--now, to +# avoid bugs in old shells (e.g. pre-3.0 UWIN ksh). This construct +# also avoids known problems related to "unset" and subshell syntax +# in other old shells (e.g. bash 2.01 and pdksh 5.2.14). +for as_var in BASH_ENV ENV MAIL MAILPATH CDPATH +do eval test \${$as_var+y} \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done + +# Ensure that fds 0, 1, and 2 are open. +if (exec 3>&0) 2>/dev/null; then :; else exec 0&1) 2>/dev/null; then :; else exec 1>/dev/null; fi +if (exec 3>&2) ; then :; else exec 2>/dev/null; fi + +# The user is always right. +if ${PATH_SEPARATOR+false} :; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + test -r "$as_dir$0" && as_myself=$as_dir$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + printf "%s\n" "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + printf "%s\n" "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + + + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset + +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null +then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else $as_nop + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null +then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else $as_nop + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +printf "%s\n" X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + + +# Determine whether it's possible to make 'echo' print without a newline. +# These variables are no longer used directly by Autoconf, but are AC_SUBSTed +# for compatibility with existing Makefiles. +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +# For backward compatibility with old third-party macros, we provide +# the shell variables $as_echo and $as_echo_n. New code should use +# AS_ECHO(["message"]) and AS_ECHO_N(["message"]), respectively. +as_echo='printf %s\n' +as_echo_n='printf %s' + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -pR'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -pR' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -pR' + fi +else + as_ln_s='cp -pR' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`printf "%s\n" "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +printf "%s\n" X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +as_test_x='test -x' +as_executable_p=as_fn_executable_p + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +exec 6>&1 +## ----------------------------------- ## +## Main body of $CONFIG_STATUS script. ## +## ----------------------------------- ## +_ASEOF +test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# Save the log message, to keep $0 and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. +ac_log=" +This file was extended by isl-interface $as_me 0, which was +generated by GNU Autoconf 2.71. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + +_ACEOF + +case $ac_config_files in *" +"*) set x $ac_config_files; shift; ac_config_files=$*;; +esac + +case $ac_config_headers in *" +"*) set x $ac_config_headers; shift; ac_config_headers=$*;; +esac + + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# Files that config.status was made for. +config_files="$ac_config_files" +config_headers="$ac_config_headers" +config_commands="$ac_config_commands" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +ac_cs_usage="\ +\`$as_me' instantiates files and other configuration actions +from templates according to the current configuration. Unless the files +and actions are specified as TAGs, all are instantiated by default. + +Usage: $0 [OPTION]... [TAG]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit + --config print configuration, then exit + -q, --quiet, --silent + do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE + +Configuration files: +$config_files + +Configuration headers: +$config_headers + +Configuration commands: +$config_commands + +Report bugs to ." + +_ACEOF +ac_cs_config=`printf "%s\n" "$ac_configure_args" | sed "$ac_safe_unquote"` +ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\''/g"` +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_cs_config='$ac_cs_config_escaped' +ac_cs_version="\\ +isl-interface config.status 0 +configured by $0, generated by GNU Autoconf 2.71, + with options \\"\$ac_cs_config\\" + +Copyright (C) 2021 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." + +ac_pwd='$ac_pwd' +srcdir='$srcdir' +INSTALL='$INSTALL' +MKDIR_P='$MKDIR_P' +AWK='$AWK' +test -n "\$AWK" || AWK=awk +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# The default lists apply if the user does not specify any file. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=?*) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` + ac_shift=: + ;; + --*=) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg= + ac_shift=: + ;; + *) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + printf "%s\n" "$ac_cs_version"; exit ;; + --config | --confi | --conf | --con | --co | --c ) + printf "%s\n" "$ac_cs_config"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`printf "%s\n" "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + '') as_fn_error $? "missing file argument" ;; + esac + as_fn_append CONFIG_FILES " '$ac_optarg'" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`printf "%s\n" "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + as_fn_append CONFIG_HEADERS " '$ac_optarg'" + ac_need_defaults=false;; + --he | --h) + # Conflict between --help and --header + as_fn_error $? "ambiguous option: \`$1' +Try \`$0 --help' for more information.";; + --help | --hel | -h ) + printf "%s\n" "$ac_cs_usage"; exit ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) as_fn_error $? "unrecognized option: \`$1' +Try \`$0 --help' for more information." ;; + + *) as_fn_append ac_config_targets " $1" + ac_need_defaults=false ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +if \$ac_cs_recheck; then + set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion + shift + \printf "%s\n" "running CONFIG_SHELL=$SHELL \$*" >&6 + CONFIG_SHELL='$SHELL' + export CONFIG_SHELL + exec "\$@" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + printf "%s\n" "$ac_log" +} >&5 + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# +# INIT-COMMANDS +# +AMDEP_TRUE="$AMDEP_TRUE" MAKE="${MAKE-make}" + + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +sed_quote_subst='$sed_quote_subst' +double_quote_subst='$double_quote_subst' +delay_variable_subst='$delay_variable_subst' +enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`' +macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`' +macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`' +enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`' +pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`' +enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`' +shared_archive_member_spec='`$ECHO "$shared_archive_member_spec" | $SED "$delay_single_quote_subst"`' +SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`' +ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`' +PATH_SEPARATOR='`$ECHO "$PATH_SEPARATOR" | $SED "$delay_single_quote_subst"`' +host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`' +host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`' +host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`' +build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`' +build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`' +build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`' +SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`' +Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`' +GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`' +EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`' +FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`' +LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`' +NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`' +LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`' +max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`' +ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`' +exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`' +lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`' +lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`' +lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`' +lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`' +lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`' +reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`' +reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`' +OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`' +deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`' +file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`' +file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`' +want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`' +DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`' +sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`' +AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`' +AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`' +archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`' +STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`' +RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`' +old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`' +old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`' +old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`' +lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`' +CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`' +CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`' +compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`' +GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_import='`$ECHO "$lt_cv_sys_global_symbol_to_import" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`' +lt_cv_nm_interface='`$ECHO "$lt_cv_nm_interface" | $SED "$delay_single_quote_subst"`' +nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`' +lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`' +lt_cv_truncate_bin='`$ECHO "$lt_cv_truncate_bin" | $SED "$delay_single_quote_subst"`' +objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`' +MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`' +lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`' +need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`' +MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`' +DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`' +NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`' +LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`' +OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`' +OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`' +libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`' +shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`' +extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`' +archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`' +enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`' +export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`' +whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`' +compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`' +old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`' +old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`' +archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`' +archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`' +module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`' +module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`' +with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`' +allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`' +no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`' +hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`' +hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`' +hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`' +hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`' +hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`' +inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`' +link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`' +always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`' +export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`' +exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`' +include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`' +prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`' +postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`' +file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`' +variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`' +need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`' +need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`' +version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`' +runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`' +shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`' +shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`' +libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`' +library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`' +soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`' +install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`' +postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`' +postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`' +finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`' +finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`' +hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`' +sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`' +configure_time_dlsearch_path='`$ECHO "$configure_time_dlsearch_path" | $SED "$delay_single_quote_subst"`' +configure_time_lt_sys_library_path='`$ECHO "$configure_time_lt_sys_library_path" | $SED "$delay_single_quote_subst"`' +hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`' +enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`' +enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`' +enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`' +old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`' +striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`' +compiler_lib_search_dirs='`$ECHO "$compiler_lib_search_dirs" | $SED "$delay_single_quote_subst"`' +predep_objects='`$ECHO "$predep_objects" | $SED "$delay_single_quote_subst"`' +postdep_objects='`$ECHO "$postdep_objects" | $SED "$delay_single_quote_subst"`' +predeps='`$ECHO "$predeps" | $SED "$delay_single_quote_subst"`' +postdeps='`$ECHO "$postdeps" | $SED "$delay_single_quote_subst"`' +compiler_lib_search_path='`$ECHO "$compiler_lib_search_path" | $SED "$delay_single_quote_subst"`' +LD_CXX='`$ECHO "$LD_CXX" | $SED "$delay_single_quote_subst"`' +reload_flag_CXX='`$ECHO "$reload_flag_CXX" | $SED "$delay_single_quote_subst"`' +reload_cmds_CXX='`$ECHO "$reload_cmds_CXX" | $SED "$delay_single_quote_subst"`' +old_archive_cmds_CXX='`$ECHO "$old_archive_cmds_CXX" | $SED "$delay_single_quote_subst"`' +compiler_CXX='`$ECHO "$compiler_CXX" | $SED "$delay_single_quote_subst"`' +GCC_CXX='`$ECHO "$GCC_CXX" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_no_builtin_flag_CXX='`$ECHO "$lt_prog_compiler_no_builtin_flag_CXX" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_pic_CXX='`$ECHO "$lt_prog_compiler_pic_CXX" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_wl_CXX='`$ECHO "$lt_prog_compiler_wl_CXX" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_static_CXX='`$ECHO "$lt_prog_compiler_static_CXX" | $SED "$delay_single_quote_subst"`' +lt_cv_prog_compiler_c_o_CXX='`$ECHO "$lt_cv_prog_compiler_c_o_CXX" | $SED "$delay_single_quote_subst"`' +archive_cmds_need_lc_CXX='`$ECHO "$archive_cmds_need_lc_CXX" | $SED "$delay_single_quote_subst"`' +enable_shared_with_static_runtimes_CXX='`$ECHO "$enable_shared_with_static_runtimes_CXX" | $SED "$delay_single_quote_subst"`' +export_dynamic_flag_spec_CXX='`$ECHO "$export_dynamic_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' +whole_archive_flag_spec_CXX='`$ECHO "$whole_archive_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' +compiler_needs_object_CXX='`$ECHO "$compiler_needs_object_CXX" | $SED "$delay_single_quote_subst"`' +old_archive_from_new_cmds_CXX='`$ECHO "$old_archive_from_new_cmds_CXX" | $SED "$delay_single_quote_subst"`' +old_archive_from_expsyms_cmds_CXX='`$ECHO "$old_archive_from_expsyms_cmds_CXX" | $SED "$delay_single_quote_subst"`' +archive_cmds_CXX='`$ECHO "$archive_cmds_CXX" | $SED "$delay_single_quote_subst"`' +archive_expsym_cmds_CXX='`$ECHO "$archive_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`' +module_cmds_CXX='`$ECHO "$module_cmds_CXX" | $SED "$delay_single_quote_subst"`' +module_expsym_cmds_CXX='`$ECHO "$module_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`' +with_gnu_ld_CXX='`$ECHO "$with_gnu_ld_CXX" | $SED "$delay_single_quote_subst"`' +allow_undefined_flag_CXX='`$ECHO "$allow_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`' +no_undefined_flag_CXX='`$ECHO "$no_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_flag_spec_CXX='`$ECHO "$hardcode_libdir_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_separator_CXX='`$ECHO "$hardcode_libdir_separator_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_direct_CXX='`$ECHO "$hardcode_direct_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_direct_absolute_CXX='`$ECHO "$hardcode_direct_absolute_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_minus_L_CXX='`$ECHO "$hardcode_minus_L_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_shlibpath_var_CXX='`$ECHO "$hardcode_shlibpath_var_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_automatic_CXX='`$ECHO "$hardcode_automatic_CXX" | $SED "$delay_single_quote_subst"`' +inherit_rpath_CXX='`$ECHO "$inherit_rpath_CXX" | $SED "$delay_single_quote_subst"`' +link_all_deplibs_CXX='`$ECHO "$link_all_deplibs_CXX" | $SED "$delay_single_quote_subst"`' +always_export_symbols_CXX='`$ECHO "$always_export_symbols_CXX" | $SED "$delay_single_quote_subst"`' +export_symbols_cmds_CXX='`$ECHO "$export_symbols_cmds_CXX" | $SED "$delay_single_quote_subst"`' +exclude_expsyms_CXX='`$ECHO "$exclude_expsyms_CXX" | $SED "$delay_single_quote_subst"`' +include_expsyms_CXX='`$ECHO "$include_expsyms_CXX" | $SED "$delay_single_quote_subst"`' +prelink_cmds_CXX='`$ECHO "$prelink_cmds_CXX" | $SED "$delay_single_quote_subst"`' +postlink_cmds_CXX='`$ECHO "$postlink_cmds_CXX" | $SED "$delay_single_quote_subst"`' +file_list_spec_CXX='`$ECHO "$file_list_spec_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_action_CXX='`$ECHO "$hardcode_action_CXX" | $SED "$delay_single_quote_subst"`' +compiler_lib_search_dirs_CXX='`$ECHO "$compiler_lib_search_dirs_CXX" | $SED "$delay_single_quote_subst"`' +predep_objects_CXX='`$ECHO "$predep_objects_CXX" | $SED "$delay_single_quote_subst"`' +postdep_objects_CXX='`$ECHO "$postdep_objects_CXX" | $SED "$delay_single_quote_subst"`' +predeps_CXX='`$ECHO "$predeps_CXX" | $SED "$delay_single_quote_subst"`' +postdeps_CXX='`$ECHO "$postdeps_CXX" | $SED "$delay_single_quote_subst"`' +compiler_lib_search_path_CXX='`$ECHO "$compiler_lib_search_path_CXX" | $SED "$delay_single_quote_subst"`' + +LTCC='$LTCC' +LTCFLAGS='$LTCFLAGS' +compiler='$compiler_DEFAULT' + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +\$1 +_LTECHO_EOF' +} + +# Quote evaled strings. +for var in SHELL \ +ECHO \ +PATH_SEPARATOR \ +SED \ +GREP \ +EGREP \ +FGREP \ +LD \ +NM \ +LN_S \ +lt_SP2NL \ +lt_NL2SP \ +reload_flag \ +OBJDUMP \ +deplibs_check_method \ +file_magic_cmd \ +file_magic_glob \ +want_nocaseglob \ +DLLTOOL \ +sharedlib_from_linklib_cmd \ +AR \ +AR_FLAGS \ +archiver_list_spec \ +STRIP \ +RANLIB \ +CC \ +CFLAGS \ +compiler \ +lt_cv_sys_global_symbol_pipe \ +lt_cv_sys_global_symbol_to_cdecl \ +lt_cv_sys_global_symbol_to_import \ +lt_cv_sys_global_symbol_to_c_name_address \ +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \ +lt_cv_nm_interface \ +nm_file_list_spec \ +lt_cv_truncate_bin \ +lt_prog_compiler_no_builtin_flag \ +lt_prog_compiler_pic \ +lt_prog_compiler_wl \ +lt_prog_compiler_static \ +lt_cv_prog_compiler_c_o \ +need_locks \ +MANIFEST_TOOL \ +DSYMUTIL \ +NMEDIT \ +LIPO \ +OTOOL \ +OTOOL64 \ +shrext_cmds \ +export_dynamic_flag_spec \ +whole_archive_flag_spec \ +compiler_needs_object \ +with_gnu_ld \ +allow_undefined_flag \ +no_undefined_flag \ +hardcode_libdir_flag_spec \ +hardcode_libdir_separator \ +exclude_expsyms \ +include_expsyms \ +file_list_spec \ +variables_saved_for_relink \ +libname_spec \ +library_names_spec \ +soname_spec \ +install_override_mode \ +finish_eval \ +old_striplib \ +striplib \ +compiler_lib_search_dirs \ +predep_objects \ +postdep_objects \ +predeps \ +postdeps \ +compiler_lib_search_path \ +LD_CXX \ +reload_flag_CXX \ +compiler_CXX \ +lt_prog_compiler_no_builtin_flag_CXX \ +lt_prog_compiler_pic_CXX \ +lt_prog_compiler_wl_CXX \ +lt_prog_compiler_static_CXX \ +lt_cv_prog_compiler_c_o_CXX \ +export_dynamic_flag_spec_CXX \ +whole_archive_flag_spec_CXX \ +compiler_needs_object_CXX \ +with_gnu_ld_CXX \ +allow_undefined_flag_CXX \ +no_undefined_flag_CXX \ +hardcode_libdir_flag_spec_CXX \ +hardcode_libdir_separator_CXX \ +exclude_expsyms_CXX \ +include_expsyms_CXX \ +file_list_spec_CXX \ +compiler_lib_search_dirs_CXX \ +predep_objects_CXX \ +postdep_objects_CXX \ +predeps_CXX \ +postdeps_CXX \ +compiler_lib_search_path_CXX; do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[\\\\\\\`\\"\\\$]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +# Double-quote double-evaled strings. +for var in reload_cmds \ +old_postinstall_cmds \ +old_postuninstall_cmds \ +old_archive_cmds \ +extract_expsyms_cmds \ +old_archive_from_new_cmds \ +old_archive_from_expsyms_cmds \ +archive_cmds \ +archive_expsym_cmds \ +module_cmds \ +module_expsym_cmds \ +export_symbols_cmds \ +prelink_cmds \ +postlink_cmds \ +postinstall_cmds \ +postuninstall_cmds \ +finish_cmds \ +sys_lib_search_path_spec \ +configure_time_dlsearch_path \ +configure_time_lt_sys_library_path \ +reload_cmds_CXX \ +old_archive_cmds_CXX \ +old_archive_from_new_cmds_CXX \ +old_archive_from_expsyms_cmds_CXX \ +archive_cmds_CXX \ +archive_expsym_cmds_CXX \ +module_cmds_CXX \ +module_expsym_cmds_CXX \ +export_symbols_cmds_CXX \ +prelink_cmds_CXX \ +postlink_cmds_CXX; do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[\\\\\\\`\\"\\\$]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +ac_aux_dir='$ac_aux_dir' + +# See if we are running on zsh, and set the options that allow our +# commands through without removal of \ escapes INIT. +if test -n "\${ZSH_VERSION+set}"; then + setopt NO_GLOB_SUBST +fi + + + PACKAGE='$PACKAGE' + VERSION='$VERSION' + RM='$RM' + ofile='$ofile' + + + + + + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + +# Handling of arguments. +for ac_config_target in $ac_config_targets +do + case $ac_config_target in + "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; + "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;; + "isl_config.h") CONFIG_HEADERS="$CONFIG_HEADERS isl_config.h" ;; + "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; + + *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; + esac +done + + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test ${CONFIG_FILES+y} || CONFIG_FILES=$config_files + test ${CONFIG_HEADERS+y} || CONFIG_HEADERS=$config_headers + test ${CONFIG_COMMANDS+y} || CONFIG_COMMANDS=$config_commands +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason against having it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to `$tmp'. +$debug || +{ + tmp= ac_tmp= + trap 'exit_status=$? + : "${ac_tmp:=$tmp}" + { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status +' 0 + trap 'as_fn_exit 1' 1 2 13 15 +} +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && + test -d "$tmp" +} || +{ + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") +} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 +ac_tmp=$tmp + +# Set up the scripts for CONFIG_FILES section. +# No need to generate them if there are no CONFIG_FILES. +# This happens for instance with `./config.status config.h'. +if test -n "$CONFIG_FILES"; then + + +ac_cr=`echo X | tr X '\015'` +# On cygwin, bash can eat \r inside `` if the user requested igncr. +# But we know of no other shell where ac_cr would be empty at this +# point, so we can use a bashism as a fallback. +if test "x$ac_cr" = x; then + eval ac_cr=\$\'\\r\' +fi +ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` +if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then + ac_cs_awk_cr='\\r' +else + ac_cs_awk_cr=$ac_cr +fi + +echo 'BEGIN {' >"$ac_tmp/subs1.awk" && +_ACEOF + + +{ + echo "cat >conf$$subs.awk <<_ACEOF" && + echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && + echo "_ACEOF" +} >conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 +ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + . ./conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + + ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` + if test $ac_delim_n = $ac_delim_num; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done +rm -f conf$$subs.sh + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && +_ACEOF +sed -n ' +h +s/^/S["/; s/!.*/"]=/ +p +g +s/^[^!]*!// +:repl +t repl +s/'"$ac_delim"'$// +t delim +:nl +h +s/\(.\{148\}\)..*/\1/ +t more1 +s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ +p +n +b repl +:more1 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t nl +:delim +h +s/\(.\{148\}\)..*/\1/ +t more2 +s/["\\]/\\&/g; s/^/"/; s/$/"/ +p +b +:more2 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t delim +' >$CONFIG_STATUS || ac_write_fail=1 +rm -f conf$$subs.awk +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +_ACAWK +cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && + for (key in S) S_is_set[key] = 1 + FS = "" + +} +{ + line = $ 0 + nfields = split(line, field, "@") + substed = 0 + len = length(field[1]) + for (i = 2; i < nfields; i++) { + key = field[i] + keylen = length(key) + if (S_is_set[key]) { + value = S[key] + line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) + len += length(value) + length(field[++i]) + substed = 1 + } else + len += 1 + keylen + } + + print line +} + +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then + sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" +else + cat +fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ + || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 +_ACEOF + +# VPATH may cause trouble with some makes, so we remove sole $(srcdir), +# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ +h +s/// +s/^/:/ +s/[ ]*$/:/ +s/:\$(srcdir):/:/g +s/:\${srcdir}:/:/g +s/:@srcdir@:/:/g +s/^:*// +s/:*$// +x +s/\(=[ ]*\).*/\1/ +G +s/\n// +s/^[^=]*=[ ]*$// +}' +fi + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +fi # test -n "$CONFIG_FILES" + +# Set up the scripts for CONFIG_HEADERS section. +# No need to generate them if there are no CONFIG_HEADERS. +# This happens for instance with `./config.status Makefile'. +if test -n "$CONFIG_HEADERS"; then +cat >"$ac_tmp/defines.awk" <<\_ACAWK || +BEGIN { +_ACEOF + +# Transform confdefs.h into an awk script `defines.awk', embedded as +# here-document in config.status, that substitutes the proper values into +# config.h.in to produce config.h. + +# Create a delimiter string that does not exist in confdefs.h, to ease +# handling of long lines. +ac_delim='%!_!# ' +for ac_last_try in false false :; do + ac_tt=`sed -n "/$ac_delim/p" confdefs.h` + if test -z "$ac_tt"; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done + +# For the awk script, D is an array of macro values keyed by name, +# likewise P contains macro parameters if any. Preserve backslash +# newline sequences. + +ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* +sed -n ' +s/.\{148\}/&'"$ac_delim"'/g +t rset +:rset +s/^[ ]*#[ ]*define[ ][ ]*/ / +t def +d +:def +s/\\$// +t bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3"/p +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p +d +:bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3\\\\\\n"\\/p +t cont +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p +t cont +d +:cont +n +s/.\{148\}/&'"$ac_delim"'/g +t clear +:clear +s/\\$// +t bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/"/p +d +:bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p +b cont +' >$CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + for (key in D) D_is_set[key] = 1 + FS = "" +} +/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { + line = \$ 0 + split(line, arg, " ") + if (arg[1] == "#") { + defundef = arg[2] + mac1 = arg[3] + } else { + defundef = substr(arg[1], 2) + mac1 = arg[2] + } + split(mac1, mac2, "(") #) + macro = mac2[1] + prefix = substr(line, 1, index(line, defundef) - 1) + if (D_is_set[macro]) { + # Preserve the white space surrounding the "#". + print prefix "define", macro P[macro] D[macro] + next + } else { + # Replace #undef with comments. This is necessary, for example, + # in the case of _POSIX_SOURCE, which is predefined and required + # on some systems where configure will not decide to define it. + if (defundef == "undef") { + print "/*", prefix defundef, macro, "*/" + next + } + } +} +{ print } +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 +fi # test -n "$CONFIG_HEADERS" + + +eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" +shift +for ac_tag +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift + + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$ac_tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain `:'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; + esac + case $ac_f in *\'*) ac_f=`printf "%s\n" "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac + as_fn_append ac_file_inputs " '$ac_f'" + done + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input='Generated from '` + printf "%s\n" "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' + `' by configure.' + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 +printf "%s\n" "$as_me: creating $ac_file" >&6;} + fi + # Neutralize special characters interpreted by sed in replacement strings. + case $configure_input in #( + *\&* | *\|* | *\\* ) + ac_sed_conf_input=`printf "%s\n" "$configure_input" | + sed 's/[\\\\&|]/\\\\&/g'`;; #( + *) ac_sed_conf_input=$configure_input;; + esac + + case $ac_tag in + *:-:* | *:-) cat >"$ac_tmp/stdin" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; + esac + ;; + esac + + ac_dir=`$as_dirname -- "$ac_file" || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +printf "%s\n" X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir="$ac_dir"; as_fn_mkdir_p + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`printf "%s\n" "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`printf "%s\n" "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + case $ac_mode in + :F) + # + # CONFIG_FILE + # + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; + esac + ac_MKDIR_P=$MKDIR_P + case $MKDIR_P in + [\\/$]* | ?:[\\/]* ) ;; + */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; + esac +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= +ac_sed_dataroot=' +/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p' +case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +printf "%s\n" "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + ac_datarootdir_hack=' + s&@datadir@&$datadir&g + s&@docdir@&$docdir&g + s&@infodir@&$infodir&g + s&@localedir@&$localedir&g + s&@mandir@&$mandir&g + s&\\\${datarootdir}&$datarootdir&g' ;; +esac +_ACEOF + +# Neutralize VPATH when `$srcdir' = `.'. +# Shell code in configure.ac might set extrasub. +# FIXME: do we really want to maintain this feature? +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_sed_extra="$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s|@configure_input@|$ac_sed_conf_input|;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@top_build_prefix@&$ac_top_build_prefix&;t t +s&@srcdir@&$ac_srcdir&;t t +s&@abs_srcdir@&$ac_abs_srcdir&;t t +s&@top_srcdir@&$ac_top_srcdir&;t t +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +s&@builddir@&$ac_builddir&;t t +s&@abs_builddir@&$ac_abs_builddir&;t t +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +s&@INSTALL@&$ac_INSTALL&;t t +s&@MKDIR_P@&$ac_MKDIR_P&;t t +$ac_datarootdir_hack +" +eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ + >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ + "$ac_tmp/out"`; test -z "$ac_out"; } && + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&5 +printf "%s\n" "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&2;} + + rm -f "$ac_tmp/stdin" + case $ac_file in + -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; + *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; + esac \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + ;; + :H) + # + # CONFIG_HEADER + # + if test x"$ac_file" != x-; then + { + printf "%s\n" "/* $configure_input */" >&1 \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" + } >"$ac_tmp/config.h" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 +printf "%s\n" "$as_me: $ac_file is unchanged" >&6;} + else + rm -f "$ac_file" + mv "$ac_tmp/config.h" "$ac_file" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + fi + else + printf "%s\n" "/* $configure_input */" >&1 \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ + || as_fn_error $? "could not create -" "$LINENO" 5 + fi +# Compute "$ac_file"'s index in $config_headers. +_am_arg="$ac_file" +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $_am_arg | $_am_arg:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || +$as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$_am_arg" : 'X\(//\)[^/]' \| \ + X"$_am_arg" : 'X\(//\)$' \| \ + X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || +printf "%s\n" X"$_am_arg" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'`/stamp-h$_am_stamp_count + ;; + + :C) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 +printf "%s\n" "$as_me: executing $ac_file commands" >&6;} + ;; + esac + + + case $ac_file$ac_mode in + "depfiles":C) test x"$AMDEP_TRUE" != x"" || { + # Older Autoconf quotes --file arguments for eval, but not when files + # are listed without --file. Let's play safe and only enable the eval + # if we detect the quoting. + # TODO: see whether this extra hack can be removed once we start + # requiring Autoconf 2.70 or later. + case $CONFIG_FILES in #( + *\'*) : + eval set x "$CONFIG_FILES" ;; #( + *) : + set x $CONFIG_FILES ;; #( + *) : + ;; +esac + shift + # Used to flag and report bootstrapping failures. + am_rc=0 + for am_mf + do + # Strip MF so we end up with the name of the file. + am_mf=`printf "%s\n" "$am_mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile which includes + # dependency-tracking related rules and includes. + # Grep'ing the whole file directly is not great: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + sed -n 's,^am--depfiles:.*,X,p' "$am_mf" | grep X >/dev/null 2>&1 \ + || continue + am_dirpart=`$as_dirname -- "$am_mf" || +$as_expr X"$am_mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$am_mf" : 'X\(//\)[^/]' \| \ + X"$am_mf" : 'X\(//\)$' \| \ + X"$am_mf" : 'X\(/\)' \| . 2>/dev/null || +printf "%s\n" X"$am_mf" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + am_filepart=`$as_basename -- "$am_mf" || +$as_expr X/"$am_mf" : '.*/\([^/][^/]*\)/*$' \| \ + X"$am_mf" : 'X\(//\)$' \| \ + X"$am_mf" : 'X\(/\)' \| . 2>/dev/null || +printf "%s\n" X/"$am_mf" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + { echo "$as_me:$LINENO: cd "$am_dirpart" \ + && sed -e '/# am--include-marker/d' "$am_filepart" \ + | $MAKE -f - am--depfiles" >&5 + (cd "$am_dirpart" \ + && sed -e '/# am--include-marker/d' "$am_filepart" \ + | $MAKE -f - am--depfiles) >&5 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } || am_rc=$? + done + if test $am_rc -ne 0; then + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "Something went wrong bootstrapping makefile fragments + for automatic dependency tracking. If GNU make was not used, consider + re-running the configure script with MAKE=\"gmake\" (or whatever is + necessary). You can also try re-running configure with the + '--disable-dependency-tracking' option to at least be able to build + the package (albeit without support for automatic dependency tracking). +See \`config.log' for more details" "$LINENO" 5; } + fi + { am_dirpart=; unset am_dirpart;} + { am_filepart=; unset am_filepart;} + { am_mf=; unset am_mf;} + { am_rc=; unset am_rc;} + rm -f conftest-deps.mk +} + ;; + "libtool":C) + + # See if we are running on zsh, and set the options that allow our + # commands through without removal of \ escapes. + if test -n "${ZSH_VERSION+set}"; then + setopt NO_GLOB_SUBST + fi + + cfgfile=${ofile}T + trap "$RM \"$cfgfile\"; exit 1" 1 2 15 + $RM "$cfgfile" + + cat <<_LT_EOF >> "$cfgfile" +#! $SHELL +# Generated automatically by $as_me ($PACKAGE) $VERSION +# NOTE: Changes made to this file will be lost: look at ltmain.sh. + +# Provide generalized library-building support services. +# Written by Gordon Matzigkeit, 1996 + +# Copyright (C) 2014 Free Software Foundation, Inc. +# This is free software; see the source for copying conditions. There is NO +# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +# GNU Libtool is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of of the License, or +# (at your option) any later version. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program or library that is built +# using GNU Libtool, you may include this file under the same +# distribution terms that you use for the rest of that program. +# +# GNU Libtool is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + + +# The names of the tagged configurations supported by this script. +available_tags='CXX ' + +# Configured defaults for sys_lib_dlsearch_path munging. +: \${LT_SYS_LIBRARY_PATH="$configure_time_lt_sys_library_path"} + +# ### BEGIN LIBTOOL CONFIG + +# Whether or not to build shared libraries. +build_libtool_libs=$enable_shared + +# Which release of libtool.m4 was used? +macro_version=$macro_version +macro_revision=$macro_revision + +# Whether or not to build static libraries. +build_old_libs=$enable_static + +# What type of objects to build. +pic_mode=$pic_mode + +# Whether or not to optimize for fast installation. +fast_install=$enable_fast_install + +# Shared archive member basename,for filename based shared library versioning on AIX. +shared_archive_member_spec=$shared_archive_member_spec + +# Shell to use when invoking shell scripts. +SHELL=$lt_SHELL + +# An echo program that protects backslashes. +ECHO=$lt_ECHO + +# The PATH separator for the build system. +PATH_SEPARATOR=$lt_PATH_SEPARATOR + +# The host system. +host_alias=$host_alias +host=$host +host_os=$host_os + +# The build system. +build_alias=$build_alias +build=$build +build_os=$build_os + +# A sed program that does not truncate output. +SED=$lt_SED + +# Sed that helps us avoid accidentally triggering echo(1) options like -n. +Xsed="\$SED -e 1s/^X//" + +# A grep program that handles long lines. +GREP=$lt_GREP + +# An ERE matcher. +EGREP=$lt_EGREP + +# A literal string matcher. +FGREP=$lt_FGREP + +# A BSD- or MS-compatible name lister. +NM=$lt_NM + +# Whether we need soft or hard links. +LN_S=$lt_LN_S + +# What is the maximum length of a command? +max_cmd_len=$max_cmd_len + +# Object file suffix (normally "o"). +objext=$ac_objext + +# Executable file suffix (normally ""). +exeext=$exeext + +# whether the shell understands "unset". +lt_unset=$lt_unset + +# turn spaces into newlines. +SP2NL=$lt_lt_SP2NL + +# turn newlines into spaces. +NL2SP=$lt_lt_NL2SP + +# convert \$build file names to \$host format. +to_host_file_cmd=$lt_cv_to_host_file_cmd + +# convert \$build files to toolchain format. +to_tool_file_cmd=$lt_cv_to_tool_file_cmd + +# An object symbol dumper. +OBJDUMP=$lt_OBJDUMP + +# Method to check whether dependent libraries are shared objects. +deplibs_check_method=$lt_deplibs_check_method + +# Command to use when deplibs_check_method = "file_magic". +file_magic_cmd=$lt_file_magic_cmd + +# How to find potential files when deplibs_check_method = "file_magic". +file_magic_glob=$lt_file_magic_glob + +# Find potential files using nocaseglob when deplibs_check_method = "file_magic". +want_nocaseglob=$lt_want_nocaseglob + +# DLL creation program. +DLLTOOL=$lt_DLLTOOL + +# Command to associate shared and link libraries. +sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd + +# The archiver. +AR=$lt_AR + +# Flags to create an archive. +AR_FLAGS=$lt_AR_FLAGS + +# How to feed a file listing to the archiver. +archiver_list_spec=$lt_archiver_list_spec + +# A symbol stripping program. +STRIP=$lt_STRIP + +# Commands used to install an old-style archive. +RANLIB=$lt_RANLIB +old_postinstall_cmds=$lt_old_postinstall_cmds +old_postuninstall_cmds=$lt_old_postuninstall_cmds + +# Whether to use a lock for old archive extraction. +lock_old_archive_extraction=$lock_old_archive_extraction + +# A C compiler. +LTCC=$lt_CC + +# LTCC compiler flags. +LTCFLAGS=$lt_CFLAGS + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe + +# Transform the output of nm in a proper C declaration. +global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl + +# Transform the output of nm into a list of symbols to manually relocate. +global_symbol_to_import=$lt_lt_cv_sys_global_symbol_to_import + +# Transform the output of nm in a C name address pair. +global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address + +# Transform the output of nm in a C name address pair when lib prefix is needed. +global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix + +# The name lister interface. +nm_interface=$lt_lt_cv_nm_interface + +# Specify filename containing input files for \$NM. +nm_file_list_spec=$lt_nm_file_list_spec + +# The root where to search for dependent libraries,and where our libraries should be installed. +lt_sysroot=$lt_sysroot + +# Command to truncate a binary pipe. +lt_truncate_bin=$lt_lt_cv_truncate_bin + +# The name of the directory that contains temporary libtool files. +objdir=$objdir + +# Used to examine libraries when file_magic_cmd begins with "file". +MAGIC_CMD=$MAGIC_CMD + +# Must we lock files when doing compilation? +need_locks=$lt_need_locks + +# Manifest tool. +MANIFEST_TOOL=$lt_MANIFEST_TOOL + +# Tool to manipulate archived DWARF debug symbol files on Mac OS X. +DSYMUTIL=$lt_DSYMUTIL + +# Tool to change global to local symbols on Mac OS X. +NMEDIT=$lt_NMEDIT + +# Tool to manipulate fat objects and archives on Mac OS X. +LIPO=$lt_LIPO + +# ldd/readelf like tool for Mach-O binaries on Mac OS X. +OTOOL=$lt_OTOOL + +# ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4. +OTOOL64=$lt_OTOOL64 + +# Old archive suffix (normally "a"). +libext=$libext + +# Shared library suffix (normally ".so"). +shrext_cmds=$lt_shrext_cmds + +# The commands to extract the exported symbol list from a shared archive. +extract_expsyms_cmds=$lt_extract_expsyms_cmds + +# Variables whose values should be saved in libtool wrapper scripts and +# restored at link time. +variables_saved_for_relink=$lt_variables_saved_for_relink + +# Do we need the "lib" prefix for modules? +need_lib_prefix=$need_lib_prefix + +# Do we need a version for libraries? +need_version=$need_version + +# Library versioning type. +version_type=$version_type + +# Shared library runtime path variable. +runpath_var=$runpath_var + +# Shared library path variable. +shlibpath_var=$shlibpath_var + +# Is shlibpath searched before the hard-coded library search path? +shlibpath_overrides_runpath=$shlibpath_overrides_runpath + +# Format of library name prefix. +libname_spec=$lt_libname_spec + +# List of archive names. First name is the real one, the rest are links. +# The last name is the one that the linker finds with -lNAME +library_names_spec=$lt_library_names_spec + +# The coded name of the library, if different from the real name. +soname_spec=$lt_soname_spec + +# Permission mode override for installation of shared libraries. +install_override_mode=$lt_install_override_mode + +# Command to use after installation of a shared archive. +postinstall_cmds=$lt_postinstall_cmds + +# Command to use after uninstallation of a shared archive. +postuninstall_cmds=$lt_postuninstall_cmds + +# Commands used to finish a libtool library installation in a directory. +finish_cmds=$lt_finish_cmds + +# As "finish_cmds", except a single script fragment to be evaled but +# not shown. +finish_eval=$lt_finish_eval + +# Whether we should hardcode library paths into libraries. +hardcode_into_libs=$hardcode_into_libs + +# Compile-time system search path for libraries. +sys_lib_search_path_spec=$lt_sys_lib_search_path_spec + +# Detected run-time system search path for libraries. +sys_lib_dlsearch_path_spec=$lt_configure_time_dlsearch_path + +# Explicit LT_SYS_LIBRARY_PATH set during ./configure time. +configure_time_lt_sys_library_path=$lt_configure_time_lt_sys_library_path + +# Whether dlopen is supported. +dlopen_support=$enable_dlopen + +# Whether dlopen of programs is supported. +dlopen_self=$enable_dlopen_self + +# Whether dlopen of statically linked programs is supported. +dlopen_self_static=$enable_dlopen_self_static + +# Commands to strip libraries. +old_striplib=$lt_old_striplib +striplib=$lt_striplib + + +# The linker used to build libraries. +LD=$lt_LD + +# How to create reloadable object files. +reload_flag=$lt_reload_flag +reload_cmds=$lt_reload_cmds + +# Commands used to build an old-style archive. +old_archive_cmds=$lt_old_archive_cmds + +# A language specific compiler. +CC=$lt_compiler + +# Is the compiler the GNU compiler? +with_gcc=$GCC + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag + +# Additional compiler flags for building library objects. +pic_flag=$lt_lt_prog_compiler_pic + +# How to pass a linker flag through the compiler. +wl=$lt_lt_prog_compiler_wl + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_lt_prog_compiler_static + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_lt_cv_prog_compiler_c_o + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$archive_cmds_need_lc + +# Whether or not to disallow shared libs when runtime libs are static. +allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec + +# Whether the compiler copes with passing no objects directly. +compiler_needs_object=$lt_compiler_needs_object + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds + +# Commands used to build a shared archive. +archive_cmds=$lt_archive_cmds +archive_expsym_cmds=$lt_archive_expsym_cmds + +# Commands used to build a loadable module if different from building +# a shared archive. +module_cmds=$lt_module_cmds +module_expsym_cmds=$lt_module_expsym_cmds + +# Whether we are building with GNU ld or not. +with_gnu_ld=$lt_with_gnu_ld + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag + +# Flag that enforces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec + +# Whether we need a single "-rpath" flag with a separated argument. +hardcode_libdir_separator=$lt_hardcode_libdir_separator + +# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes +# DIR into the resulting binary. +hardcode_direct=$hardcode_direct + +# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes +# DIR into the resulting binary and the resulting library dependency is +# "absolute",i.e impossible to change by setting \$shlibpath_var if the +# library is relocated. +hardcode_direct_absolute=$hardcode_direct_absolute + +# Set to "yes" if using the -LDIR flag during linking hardcodes DIR +# into the resulting binary. +hardcode_minus_L=$hardcode_minus_L + +# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR +# into the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var + +# Set to "yes" if building a shared library automatically hardcodes DIR +# into the library and all subsequent libraries and executables linked +# against it. +hardcode_automatic=$hardcode_automatic + +# Set to yes if linker adds runtime paths of dependent libraries +# to runtime path list. +inherit_rpath=$inherit_rpath + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs + +# Set to "yes" if exported symbols are required. +always_export_symbols=$always_export_symbols + +# The commands to list exported symbols. +export_symbols_cmds=$lt_export_symbols_cmds + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms + +# Commands necessary for linking programs (against libraries) with templates. +prelink_cmds=$lt_prelink_cmds + +# Commands necessary for finishing linking programs. +postlink_cmds=$lt_postlink_cmds + +# Specify filename containing input files. +file_list_spec=$lt_file_list_spec + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action + +# The directories searched by this compiler when creating a shared library. +compiler_lib_search_dirs=$lt_compiler_lib_search_dirs + +# Dependencies to place before and after the objects being linked to +# create a shared library. +predep_objects=$lt_predep_objects +postdep_objects=$lt_postdep_objects +predeps=$lt_predeps +postdeps=$lt_postdeps + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path=$lt_compiler_lib_search_path + +# ### END LIBTOOL CONFIG + +_LT_EOF + + cat <<'_LT_EOF' >> "$cfgfile" + +# ### BEGIN FUNCTIONS SHARED WITH CONFIGURE + +# func_munge_path_list VARIABLE PATH +# ----------------------------------- +# VARIABLE is name of variable containing _space_ separated list of +# directories to be munged by the contents of PATH, which is string +# having a format: +# "DIR[:DIR]:" +# string "DIR[ DIR]" will be prepended to VARIABLE +# ":DIR[:DIR]" +# string "DIR[ DIR]" will be appended to VARIABLE +# "DIRP[:DIRP]::[DIRA:]DIRA" +# string "DIRP[ DIRP]" will be prepended to VARIABLE and string +# "DIRA[ DIRA]" will be appended to VARIABLE +# "DIR[:DIR]" +# VARIABLE will be replaced by "DIR[ DIR]" +func_munge_path_list () +{ + case x$2 in + x) + ;; + *:) + eval $1=\"`$ECHO $2 | $SED 's/:/ /g'` \$$1\" + ;; + x:*) + eval $1=\"\$$1 `$ECHO $2 | $SED 's/:/ /g'`\" + ;; + *::*) + eval $1=\"\$$1\ `$ECHO $2 | $SED -e 's/.*:://' -e 's/:/ /g'`\" + eval $1=\"`$ECHO $2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \$$1\" + ;; + *) + eval $1=\"`$ECHO $2 | $SED 's/:/ /g'`\" + ;; + esac +} + + +# Calculate cc_basename. Skip known compiler wrappers and cross-prefix. +func_cc_basename () +{ + for cc_temp in $*""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac + done + func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` +} + + +# ### END FUNCTIONS SHARED WITH CONFIGURE + +_LT_EOF + + case $host_os in + aix3*) + cat <<\_LT_EOF >> "$cfgfile" +# AIX sometimes has problems with the GCC collect2 program. For some +# reason, if we set the COLLECT_NAMES environment variable, the problems +# vanish in a puff of smoke. +if test set != "${COLLECT_NAMES+set}"; then + COLLECT_NAMES= + export COLLECT_NAMES +fi +_LT_EOF + ;; + esac + + + +ltmain=$ac_aux_dir/ltmain.sh + + + # We use sed instead of cat because bash on DJGPP gets confused if + # if finds mixed CR/LF and LF-only lines. Since sed operates in + # text mode, it properly converts lines to CR/LF. This bash problem + # is reportedly fixed, but why not run on old versions too? + sed '$q' "$ltmain" >> "$cfgfile" \ + || (rm -f "$cfgfile"; exit 1) + + mv -f "$cfgfile" "$ofile" || + (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") + chmod +x "$ofile" + + + cat <<_LT_EOF >> "$ofile" + +# ### BEGIN LIBTOOL TAG CONFIG: CXX + +# The linker used to build libraries. +LD=$lt_LD_CXX + +# How to create reloadable object files. +reload_flag=$lt_reload_flag_CXX +reload_cmds=$lt_reload_cmds_CXX + +# Commands used to build an old-style archive. +old_archive_cmds=$lt_old_archive_cmds_CXX + +# A language specific compiler. +CC=$lt_compiler_CXX + +# Is the compiler the GNU compiler? +with_gcc=$GCC_CXX + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_CXX + +# Additional compiler flags for building library objects. +pic_flag=$lt_lt_prog_compiler_pic_CXX + +# How to pass a linker flag through the compiler. +wl=$lt_lt_prog_compiler_wl_CXX + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_lt_prog_compiler_static_CXX + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_lt_cv_prog_compiler_c_o_CXX + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$archive_cmds_need_lc_CXX + +# Whether or not to disallow shared libs when runtime libs are static. +allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_CXX + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_CXX + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec_CXX + +# Whether the compiler copes with passing no objects directly. +compiler_needs_object=$lt_compiler_needs_object_CXX + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_CXX + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_CXX + +# Commands used to build a shared archive. +archive_cmds=$lt_archive_cmds_CXX +archive_expsym_cmds=$lt_archive_expsym_cmds_CXX + +# Commands used to build a loadable module if different from building +# a shared archive. +module_cmds=$lt_module_cmds_CXX +module_expsym_cmds=$lt_module_expsym_cmds_CXX + +# Whether we are building with GNU ld or not. +with_gnu_ld=$lt_with_gnu_ld_CXX + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag_CXX + +# Flag that enforces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag_CXX + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_CXX + +# Whether we need a single "-rpath" flag with a separated argument. +hardcode_libdir_separator=$lt_hardcode_libdir_separator_CXX + +# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes +# DIR into the resulting binary. +hardcode_direct=$hardcode_direct_CXX + +# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes +# DIR into the resulting binary and the resulting library dependency is +# "absolute",i.e impossible to change by setting \$shlibpath_var if the +# library is relocated. +hardcode_direct_absolute=$hardcode_direct_absolute_CXX + +# Set to "yes" if using the -LDIR flag during linking hardcodes DIR +# into the resulting binary. +hardcode_minus_L=$hardcode_minus_L_CXX + +# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR +# into the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var_CXX + +# Set to "yes" if building a shared library automatically hardcodes DIR +# into the library and all subsequent libraries and executables linked +# against it. +hardcode_automatic=$hardcode_automatic_CXX + +# Set to yes if linker adds runtime paths of dependent libraries +# to runtime path list. +inherit_rpath=$inherit_rpath_CXX + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs_CXX + +# Set to "yes" if exported symbols are required. +always_export_symbols=$always_export_symbols_CXX + +# The commands to list exported symbols. +export_symbols_cmds=$lt_export_symbols_cmds_CXX + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms_CXX + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms_CXX + +# Commands necessary for linking programs (against libraries) with templates. +prelink_cmds=$lt_prelink_cmds_CXX + +# Commands necessary for finishing linking programs. +postlink_cmds=$lt_postlink_cmds_CXX + +# Specify filename containing input files. +file_list_spec=$lt_file_list_spec_CXX + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action_CXX + +# The directories searched by this compiler when creating a shared library. +compiler_lib_search_dirs=$lt_compiler_lib_search_dirs_CXX + +# Dependencies to place before and after the objects being linked to +# create a shared library. +predep_objects=$lt_predep_objects_CXX +postdep_objects=$lt_postdep_objects_CXX +predeps=$lt_predeps_CXX +postdeps=$lt_postdeps_CXX + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path=$lt_compiler_lib_search_path_CXX + +# ### END LIBTOOL TAG CONFIG: CXX +_LT_EOF + + ;; + + esac +done # for ac_tag + + +as_fn_exit 0 +_ACEOF +ac_clean_files=$ac_clean_files_save + +test $ac_write_fail = 0 || + as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || as_fn_exit 1 +fi +if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 +printf "%s\n" "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} +fi + + diff --git a/external/mit/isl/dist/interface/configure.ac b/external/mit/isl/dist/interface/configure.ac new file mode 100644 index 000000000000..b61822bad802 --- /dev/null +++ b/external/mit/isl/dist/interface/configure.ac @@ -0,0 +1,31 @@ +AC_INIT([isl-interface], [0], [isl-development@googlegroups.com]) +AC_CONFIG_AUX_DIR([.]) +AC_CONFIG_MACRO_DIR([../m4]) +AM_INIT_AUTOMAKE([foreign]) +m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])]) + +AC_PROG_CXX +AX_PROG_CXX_FOR_BUILD + +# extract_interface needs to be run on the build system. +# Since this is the only target that is being built, +# simply use the build compiler throughout. +# This ensures that the clang configure checks are +# performed using the right compiler. +CXX="$CXX_FOR_BUILD" +CXXCPP="$CXXCPP_FOR_BUILD" +EXEEXT="$BUILD_EXEEXT" +OBJEXT="$BUILD_OBJEXT" + +AX_CXX_COMPILE_STDCXX_11_NO_OVERRIDE + +AC_DISABLE_SHARED +LT_INIT + +AX_DETECT_CLANG + +AC_SUBST([CONFIG_STATUS_DEPENDENCIES], [$LLVM_CONFIG]) +AC_CONFIG_HEADERS(isl_config.h) +AC_CONFIG_FILES(Makefile) + +AC_OUTPUT diff --git a/external/mit/isl/dist/interface/cpp.cc b/external/mit/isl/dist/interface/cpp.cc new file mode 100644 index 000000000000..d5c08ebf25f0 --- /dev/null +++ b/external/mit/isl/dist/interface/cpp.cc @@ -0,0 +1,1311 @@ +/* + * Copyright 2016, 2017 Tobias Grosser. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY TOBIAS GROSSER ''AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL TOBIAS GROSSER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation + * are those of the authors and should not be interpreted as + * representing official policies, either expressed or implied, of + * Tobias Grosser. + */ + +#include +#include +#include + +#include "cpp.h" +#include "isl_config.h" + +/* Determine the isl types from which the given class can be implicitly + * constructed using a unary constructor. + * + * Look through all constructors for implicit conversion constructors that take + * an isl type and add those types, along with the corresponding + * constructor argument. + */ +void cpp_generator::set_class_construction_types(isl_class &clazz) +{ + for (const auto &cons : clazz.constructors) { + ParmVarDecl *param; + QualType type; + std::string arg_type; + + if (!is_implicit_conversion(Method(clazz, cons))) + continue; + + param = cons->getParamDecl(0); + type = param->getOriginalType(); + arg_type = extract_type(type); + clazz.construction_types.emplace(arg_type, param); + } +} + +/* Determine the isl types from which any (proper) class can be constructed + * using a unary constructor. + */ +void cpp_generator::set_construction_types() +{ + for (auto &kvp : classes) { + auto &clazz = kvp.second; + set_class_construction_types(clazz); + } +} + +/* Construct a generator for C++ bindings. + * + * The classes and methods are extracted by the constructor + * of the generator superclass. + * + * Additionally extract information about types + * that can be converted to a class and copy all methods + * from superclasses that can be converted to a given class + * to that class. + */ +cpp_generator::cpp_generator(SourceManager &SM, + set &exported_types, + set exported_functions, set functions) : + generator(SM, exported_types, exported_functions, functions) +{ + set_construction_types(); + copy_super_methods(); +} + +/* Copy the method called "name" described by "fd" from "super" to "clazz" + * with the distance to the original ancestor given by "depth". + * + * In particular, keep track of "fd" as well as the superclass + * from which it was copied and the distance to the original ancestor. + */ +static void copy_method(isl_class &clazz, const isl_class &super, + const std::string &name, FunctionDecl *fd, int depth) +{ + clazz.methods[name].insert(fd); + clazz.copied_from.emplace(fd, super); + clazz.copy_depth.emplace(fd, depth); +} + +/* Do "fd1" and "fd2" have the same signature (ignoring the first argument + * which represents the object class on which the corresponding method + * gets called). + */ +static bool same_signature(FunctionDecl *fd1, FunctionDecl *fd2) +{ + int n1 = fd1->getNumParams(); + int n2 = fd2->getNumParams(); + + if (n1 != n2) + return false; + + for (int i = 1; i < n1; ++i) { + ParmVarDecl *p1 = fd1->getParamDecl(i); + ParmVarDecl *p2 = fd2->getParamDecl(i); + + if (p1->getOriginalType() != p2->getOriginalType()) + return false; + } + + return true; +} + +/* Return the distance between "clazz" and the ancestor + * from which "fd" got copied. + * If no distance was recorded, then the method has not been copied + * but appears in "clazz" itself and so the distance is zero. + */ +static int copy_depth(const isl_class &clazz, FunctionDecl *fd) +{ + if (clazz.copy_depth.count(fd) == 0) + return 0; + return clazz.copy_depth.at(fd); +} + +/* Is the method derived from "fd", with method name "name" and + * with distance to the original ancestor "depth", + * overridden by a method already in "clazz"? + * + * A method is considered to have been overridden if there + * is a method with the same name in "clazz" that has the same signature and + * that comes from an ancestor closer to "clazz", + * where an ancestor is closer if the distance in the class hierarchy + * is smaller or the distance is the same and the ancestor appears + * closer in the declaration of the type (in which case it gets added first). + * + * If a method with the same signature has already been added, + * but it does not override the method derived from "fd", + * then this method is removed since it is overridden by "fd". + */ +static bool is_overridden(FunctionDecl *fd, isl_class &clazz, + const std::string &name, int depth) +{ + if (clazz.methods.count(name) == 0) + return false; + + for (const auto &m : clazz.methods.at(name)) { + if (!same_signature(fd, m)) + continue; + if (copy_depth(clazz, m) <= depth) + return true; + clazz.methods[name].erase(m); + return false; + } + return false; +} + +/* Add the methods "methods" with method name "name" from "super" to "clazz" + * provided they have not been overridden by a method already in "clazz". + * + * Methods that are static in their original class are not copied. + */ +void cpp_generator::copy_methods(isl_class &clazz, const std::string &name, + const isl_class &super, const function_set &methods) +{ + for (auto fd : methods) { + int depth; + + if (method2class(fd)->is_static(fd)) + continue; + depth = copy_depth(super, fd) + 1; + if (is_overridden(fd, clazz, name, depth)) + continue; + copy_method(clazz, super, name, fd, depth); + } +} + +/* Add all methods from "super" to "clazz" that have not been overridden + * by a method already in "clazz". + * + * Look through all groups of methods with the same name. + */ +void cpp_generator::copy_super_methods(isl_class &clazz, const isl_class &super) +{ + for (const auto &kvp : super.methods) { + const auto &name = kvp.first; + const auto &methods = kvp.second; + + copy_methods(clazz, name, super, methods); + } +} + +/* Copy methods from the superclasses of "clazz" + * if an object of this class can be implicitly converted to an object + * from the superclass, keeping track + * of the classes that have already been handled in "done". + * + * Make sure the superclasses have copied methods from their superclasses first + * since those methods could be copied further down to this class. + * + * Consider the superclass that appears closest to the subclass first. + */ +void cpp_generator::copy_super_methods(isl_class &clazz, set &done) +{ + auto supers = find_superclasses(clazz.type); + + for (const auto &super : supers) + if (done.count(super) == 0) + copy_super_methods(classes[super], done); + done.insert(clazz.name); + + for (const auto &super_name : supers) { + const auto &super = classes[super_name]; + + if (super.construction_types.count(clazz.name) == 0) + continue; + copy_super_methods(clazz, super); + } +} + +/* For each (proper) class, copy methods from its superclasses, + * if an object from the class can be converted to an object + * from the superclass. + * + * Type based subclasses are not considered for now since + * they do not have any explicit superclasses. + * + * Iterate through all (proper) classes and copy methods + * from their superclasses, + * unless they have already been determined by a recursive call. + */ +void cpp_generator::copy_super_methods() +{ + set done; + + for (auto &kvp : classes) { + auto &clazz = kvp.second; + + if (clazz.is_type_subclass()) + continue; + if (done.count(clazz.name) != 0) + continue; + copy_super_methods(clazz, done); + } +} + +/* Print declarations or implementations of constructors. + * + * For each isl function that is marked as __isl_constructor, + * add a corresponding C++ constructor. + * + * Example of declarations: + * + * inline /\* implicit *\/ union_set(basic_set bset); + * inline /\* implicit *\/ union_set(set set); + * inline explicit val(ctx ctx, long i); + * inline explicit val(ctx ctx, const std::string &str); + */ +void cpp_generator::class_printer::print_constructors() +{ + for (const auto &cons : clazz.constructors) + print_method(Method(clazz, cons)); +} + +/* Print declarations or definitions for methods in the class. + */ +void cpp_generator::class_printer::print_methods() +{ + for (const auto &kvp : clazz.methods) + print_method_group(kvp.second, kvp.first); +} + +/* Print declarations or implementations for the methods derived from "fd", + * which sets an enum. + * + * A method is generated for each value in the enum, setting + * the enum to that value. + */ +void cpp_generator::class_printer::print_set_enums(FunctionDecl *fd) +{ + for (const auto &set : clazz.set_enums.at(fd)) { + EnumMethod method(clazz, fd, set.method_name, set.name); + + print_method(method); + } +} + +/* Print declarations or implementations for methods derived from functions + * that set an enum. + */ +void cpp_generator::class_printer::print_set_enums() +{ + for (const auto &kvp : clazz.set_enums) + print_set_enums(kvp.first); +} + +/* Update "convert" to reflect the next combination of automatic conversions + * for the arguments of "fd", + * returning false if there are no more combinations. + * + * In particular, find the last argument for which an automatic + * conversion function is available mapping to the type of this argument and + * that is not already marked for conversion. + * Mark this argument, if any, for conversion and clear the markings + * of all subsequent arguments. + * Repeated calls to this method therefore run through + * all possible combinations. + * + * Note that the first function argument is never considered + * for automatic conversion since this is the argument + * from which the isl_ctx used in the conversion is extracted. + */ +bool cpp_generator::class_printer::next_variant(FunctionDecl *fd, + std::vector &convert) +{ + size_t n = convert.size(); + + for (int i = n - 1; i >= 1; --i) { + ParmVarDecl *param = fd->getParamDecl(i); + const Type *type = param->getOriginalType().getTypePtr(); + + if (generator.conversions.count(type) == 0) + continue; + if (convert[i]) + continue; + convert[i] = true; + for (size_t j = i + 1; j < n; ++j) + convert[j] = false; + return true; + } + + return false; +} + +/* Print a declaration or definition for a method called "name" + * derived from "fd". + * + * If the method was copied from a superclass, then print a definition + * that calls the corresponding method in the superclass. + * Otherwise, for methods that are identified as "get" methods, also + * print a declaration or definition for the method + * using a name that includes the "get_" prefix. + * + * If the generated method is an object method, then check + * whether any of its arguments can be automatically converted + * from something else, and, if so, generate a method + * for each combination of converted arguments. + * Do so by constructing a ConversionMethod that changes the converted arguments + * to those of the sources of the conversions. + * + * Note that a method may be both copied from a superclass and + * have arguments that can be automatically converted. + * In this case, the conversion methods for the arguments + * call the corresponding method in this class, which + * in turn will call the method in the superclass. + */ +void cpp_generator::class_printer::print_method_variants(FunctionDecl *fd, + const std::string &name) +{ + Method method(clazz, fd, name); + std::vector convert(method.num_params()); + + if (method.clazz.copied_from.count(method.fd) == 0) { + print_method(method); + if (clazz.is_get_method(fd)) + print_get_method(fd); + } else { + auto super = method.clazz.copied_from.at(method.fd); + print_method(ConversionMethod(method, super.name)); + } + if (method.kind != Method::Kind::member_method) + return; + while (next_variant(fd, convert)) { + print_method(ConversionMethod(method, [&] (int pos) { + return get_param(fd, pos, convert); + })); + } +} + +/* Given a function declaration representing a method, + * does this method have a single argument (beyond the object + * on which the method is called) that corresponds to + * an isl object? + */ +static bool has_single_isl_argument(FunctionDecl *fd) +{ + ParmVarDecl *param; + + if (fd->getNumParams() != 2) + return false; + + param = fd->getParamDecl(1); + return generator::is_isl_type(param->getOriginalType()); +} + +/* Does the set "methods" contain exactly one function declaration + * that corresponds to a method of "clazz" itself (i.e., that + * was not copied from an ancestor)? + */ +static FunctionDecl *single_local(const isl_class &clazz, + const function_set &methods) +{ + int count = 0; + FunctionDecl *local; + + for (const auto &fn : methods) { + if (!clazz.first_arg_matches_class(fn)) + continue; + ++count; + local = fn; + } + + return count == 1 ? local : NULL; +} + +/* Given a function declaration "fd" for a method called "name" + * with a single argument representing an isl object, + * generate declarations or definitions for methods with the same name, + * but with as argument an isl object of a class that can be implicitly + * converted to that of the original argument. + * In particular, generate methods for converting this argument. + */ +void cpp_generator::class_printer::print_descendent_overloads( + FunctionDecl *fd, const std::string &name) +{ + Method method(clazz, fd, name); + ParmVarDecl *param = fd->getParamDecl(1); + QualType type = param->getOriginalType(); + std::string arg = type->getPointeeType().getAsString(); + + for (const auto &kvp : generator.classes[arg].construction_types) { + const auto sub = kvp.second; + print_method(ConversionMethod(method, [&] (int pos) { + return sub; + })); + } +} + +/* Print declarations or definitions for methods called "name" + * derived from "methods". + * + * If want_descendent_overloads signals that variants should be added that take + * as arguments those types that can be converted to the original argument type + * through a unary constructor and if only one of the methods in the group + * was originally defined in "clazz", then effectively add those variants. + * Only do this for methods with a single (isl object) argument. + */ +void cpp_generator::class_printer::print_method_group( + const function_set &methods, const std::string &name) +{ + FunctionDecl *local; + + for (const auto &fd : methods) + print_method_variants(fd, name); + if (!want_descendent_overloads(methods)) + return; + local = single_local(clazz, methods); + if (!local) + return; + if (!has_single_isl_argument(local)) + return; + print_descendent_overloads(local, name); +} + +/* Print the use of the argument at position "pos" to "os". + * + * Member methods pass the isl object corresponding to "this" + * as first argument (at position 0). + * Any other arguments are passed along from the method arguments. + * + * If the argument value is loaded from a this pointer, the original + * value must be preserved and must consequently be copied. Values that are + * loaded from method parameters do not need to be preserved, as such values + * will already be copies of the actual parameters. It is consequently possible + * to directly take the pointer from these values, which saves + * an unnecessary copy. + * + * In case the parameter is a callback function, two parameters get printed, + * a wrapper for the callback function and a pointer to the actual + * callback function. The wrapper is expected to be available + * in a previously declared variable _lambda, while + * the actual callback function is expected to be stored + * in a structure called _data. + * The caller of this function must ensure that these variables exist. + */ +void Method::print_param_use(ostream &os, int pos) const +{ + ParmVarDecl *param = fd->getParamDecl(pos); + bool load_from_this_ptr = pos == 0 && kind == member_method; + string name = param->getName().str(); + QualType type = param->getOriginalType(); + + if (type->isIntegerType()) { + os << name; + return; + } + + if (generator::is_string(type)) { + os << name << ".c_str()"; + return; + } + + if (generator::is_callback(type)) { + os << name << "_lambda, "; + os << "&" << name << "_data"; + return; + } + + if (!load_from_this_ptr) + os << name << "."; + + if (generator::keeps(param)) { + os << "get()"; + } else { + if (load_from_this_ptr) + os << "copy()"; + else + os << "release()"; + } +} + +/* Does the isl function from which this method is derived + * modify an object of a subclass based on a type function? + */ +bool Method::is_subclass_mutator() const +{ + return clazz.is_type_subclass() && generator::is_mutator(clazz, fd); +} + +/* Return the C++ return type of the method "method". + * + * If the corresponding function modifies an object of a subclass, then return + * the type of this subclass. + * Otherwise, return the C++ counterpart of the actual return type. + */ +std::string cpp_type_printer::return_type(const Method &method) const +{ + if (method.is_subclass_mutator()) + return cpp_generator::type2cpp(method.clazz); + else + return param(-1, method.fd->getReturnType()); +} + +/* Return the formal parameter at position "pos" of "fd". + * However, if this parameter should be converted, as indicated + * by "convert", then return the second formal parameter + * of the conversion function instead. + */ +ParmVarDecl *cpp_generator::class_printer::get_param(FunctionDecl *fd, + int pos, const std::vector &convert) +{ + ParmVarDecl *param = fd->getParamDecl(pos); + + if (!convert[pos]) + return param; + return generator.conversions[param->getOriginalType().getTypePtr()]; +} + +/* Print the header for "method", without newline or semicolon, + * using "type_printer" to print argument and return types. + * + * Print the header of a declaration if this->declarations is set, + * otherwise print the header of a method definition. + * + * This function prints headers for member methods, static methods, and + * constructors, either for their declaration or definition. + * + * Member functions are declared as "const", as they do not change the current + * object, but instead create a new object. They always retrieve the first + * parameter of the original isl function from the this-pointer of the object, + * such that only starting at the second parameter the parameters of the + * original function become part of the method's interface. + * + * A function + * + * __isl_give isl_set *isl_set_intersect(__isl_take isl_set *s1, + * __isl_take isl_set *s2); + * + * is translated into: + * + * inline set intersect(set set2) const + * + * For static functions and constructors all parameters of the original isl + * function are exposed. + * + * Parameters of which no copy is required, are passed + * as const reference, which allows the compiler to optimize the parameter + * transfer. + * + * Constructors are marked as explicit using the C++ keyword 'explicit' or as + * implicit using a comment in place of the explicit keyword. By annotating + * implicit constructors with a comment, users of the interface are made + * aware of the potential danger that implicit construction is possible + * for these constructors, whereas without a comment not every user would + * know that implicit construction is allowed in absence of an explicit keyword. + * + * Note that in case "method" is a ConversionMethod, the argument returned + * by Method::get_param may be different from the original argument. + * The name of the argument is, however, derived from the original + * function argument. + */ +void cpp_generator::class_printer::print_method_header( + const Method &method, const cpp_type_printer &type_printer) +{ + string rettype_str = type_printer.return_type(method); + + if (declarations) { + os << " "; + + if (method.kind == Method::Kind::static_method) + os << "static "; + + os << "inline "; + + if (method.kind == Method::Kind::constructor) { + if (generator.is_implicit_conversion(method)) + os << "/* implicit */ "; + else + os << "explicit "; + } + } + + if (method.kind != Method::Kind::constructor) + os << rettype_str << " "; + + if (!declarations) + os << type_printer.class_type(cppstring) << "::"; + + if (method.kind != Method::Kind::constructor) + os << method.name; + else + os << cppstring; + + method.print_cpp_arg_list(os, [&] (int i, int arg) { + std::string name = method.fd->getParamDecl(i)->getName().str(); + ParmVarDecl *param = method.get_param(i); + QualType type = param->getOriginalType(); + string cpptype = type_printer.param(arg, type); + + if (!method.param_needs_copy(i)) + os << "const " << cpptype << " &" << name; + else + os << cpptype << " " << name; + }); + + if (method.kind == Method::Kind::member_method) + os << " const"; +} + +/* Generate the list of argument types for a callback function of + * type "type", appearing in argument position "arg". + * If "cpp" is set, then generate the C++ type list, otherwise + * the C type list. + * + * For a callback of type + * + * isl_stat (*)(__isl_take isl_map *map, void *user) + * + * the following C++ argument list is generated: + * + * map + * + * The arguments of the callback are considered to appear + * after the position of the callback itself. + */ +std::string cpp_type_printer::generate_callback_args(int arg, QualType type, + bool cpp) const +{ + std::string type_str; + const FunctionProtoType *callback; + int num_params; + + callback = generator::extract_prototype(type); + num_params = callback->getNumArgs(); + if (cpp) + num_params--; + + for (long i = 0; i < num_params; i++) { + QualType type = callback->getArgType(i); + + if (cpp) + type_str += param(arg + 1 + i, type); + else + type_str += type.getAsString(); + + if (!cpp) + type_str += "arg_" + ::to_string(i); + + if (i != num_params - 1) + type_str += ", "; + } + + return type_str; +} + +/* Generate the full cpp type of a callback function of type "type", + * appearing in argument position "arg". + * + * For a callback of type + * + * isl_stat (*)(__isl_take isl_map *map, void *user) + * + * the following type is generated: + * + * std::function + */ +std::string cpp_type_printer::generate_callback_type(int arg, QualType type) + const +{ + std::string type_str; + const FunctionProtoType *callback = generator::extract_prototype(type); + QualType return_type = callback->getReturnType(); + string rettype_str = param(arg, return_type); + + type_str = "std::function<"; + type_str += rettype_str; + type_str += "("; + type_str += generate_callback_args(arg, type, true); + type_str += ")>"; + + return type_str; +} + +/* An array listing functions that must be renamed and the function name they + * should be renamed to. We currently rename functions in case their name would + * match a reserved C++ keyword, which is not allowed in C++. + */ +static const char *rename_map[][2] = { + { "union", "unite" }, +}; + +/* Rename method "name" in case the method name in the C++ bindings should not + * match the name in the C bindings. We do this for example to avoid + * C++ keywords. + */ +static std::string rename_method(std::string name) +{ + for (size_t i = 0; i < sizeof(rename_map) / sizeof(rename_map[0]); i++) + if (name.compare(rename_map[i][0]) == 0) + return rename_map[i][1]; + + return name; +} + +/* Translate isl class "clazz" to its corresponding C++ type. + * Use the name of the type based subclass, if any. + */ +string cpp_generator::type2cpp(const isl_class &clazz) +{ + return type2cpp(clazz.subclass_name); +} + +/* Translate type string "type_str" to its C++ name counterpart. +*/ +string cpp_generator::type2cpp(string type_str) +{ + return type_str.substr(4); +} + +/* Return the C++ counterpart to the isl_bool type. + * + * By default, this is simply "bool" since + * the exceptional case is handled through exceptions. + */ +std::string cpp_type_printer::isl_bool() const +{ + return "bool"; +} + +/* Return the C++ counterpart to the isl_stat type. + * + * By default, this is simply "void" since + * the exceptional case is handled through exceptions. + */ +string cpp_type_printer::isl_stat() const +{ + return "void"; +} + +/* Return the C++ counterpart to the isl_size type. + * + * By default, this is simply "unsigned" since + * the exceptional case is handled through exceptions. + */ +string cpp_type_printer::isl_size() const +{ + return "unsigned"; +} + +/* Return the namespace of the generated C++ bindings. + * + * By default, this is "isl::". + */ +std::string cpp_type_printer::isl_namespace() const +{ + return "isl::"; +} + +/* Return the class type given the C++ name. + * + * By default, directly use the C++ name. + */ +std::string cpp_type_printer::class_type(const std::string &cpp_name) const +{ + return cpp_name; +} + +/* Return the qualified form of the given C++ isl type name appearing + * in argument position "arg" (-1 for return type). + * + * By default, the argument position is ignored. + */ +std::string cpp_type_printer::qualified(int arg, const std::string &cpp_type) + const +{ + return isl_namespace() + cpp_type; +} + +/* Return the C++ counterpart to the given isl type appearing + * in argument position "arg" (-1 for return type). + */ +std::string cpp_type_printer::isl_type(int arg, QualType type) const +{ + auto name = type->getPointeeType().getAsString(); + return qualified(arg, cpp_generator::type2cpp(name)); +} + +/* Translate parameter or return type "type" to its C++ name counterpart. + * "arg" is the position of the argument, or -1 in case of the return type. + * If any callback is involved, then the return type and arguments types + * of the callback are considered to start at the position of the callback. + */ +std::string cpp_type_printer::param(int arg, QualType type) const +{ + if (cpp_generator::is_isl_type(type)) + return isl_type(arg, type); + + if (cpp_generator::is_isl_bool(type)) + return isl_bool(); + + if (cpp_generator::is_isl_stat(type)) + return isl_stat(); + + if (cpp_generator::is_isl_size(type)) + return isl_size(); + + if (type->isIntegerType()) + return type.getAsString(); + + if (cpp_generator::is_string(type)) + return "std::string"; + + if (cpp_generator::is_callback(type)) + return generate_callback_type(arg, type); + + generator::die("Cannot convert type to C++ type"); +} + +/* Check if "subclass_type" is a subclass of "class_type". + */ +bool cpp_generator::is_subclass(QualType subclass_type, + const isl_class &class_type) +{ + std::string type_str = subclass_type->getPointeeType().getAsString(); + std::vector superclasses; + std::vector parents; + std::vector::iterator ci; + + superclasses = generator::find_superclasses(classes[type_str].type); + + for (ci = superclasses.begin(); ci < superclasses.end(); ci++) + parents.push_back(&classes[*ci]); + + while (!parents.empty()) { + const isl_class *candidate = parents.back(); + + parents.pop_back(); + + if (&class_type == candidate) + return true; + + superclasses = generator::find_superclasses(candidate->type); + + for (ci = superclasses.begin(); ci < superclasses.end(); ci++) + parents.push_back(&classes[*ci]); + } + + return false; +} + +/* Check if "cons" is an implicit conversion constructor of class "clazz". + * + * An implicit conversion constructor is generated in case "cons" has a single + * parameter, where the parameter type is a subclass of the class that is + * currently being generated. + */ +bool cpp_generator::is_implicit_conversion(const Method &cons) +{ + const auto &clazz = cons.clazz; + ParmVarDecl *param = cons.fd->getParamDecl(0); + QualType type = param->getOriginalType(); + + int num_params = cons.fd->getNumParams(); + if (num_params != 1) + return false; + + if (is_isl_type(type) && !is_isl_ctx(type) && is_subclass(type, clazz)) + return true; + + return false; +} + +/* Construct a list combiner for printing a list. + */ +Method::list_combiner Method::print_combiner(std::ostream &os) +{ + return { + [&] () { os << "("; }, + [&] () { os << ", "; }, + [&] () { os << ")"; } + }; +} + +/* Construct a list combiner for simply iterating over a list. + */ +Method::list_combiner Method::empty_combiner() +{ + return { [&] () { }, [&] () { }, [&] () { } }; +} + +/* Get kind of "method" in "clazz". + * + * Given the declaration of a static or member method, returns its kind. + */ +static Method::Kind get_kind(const isl_class &clazz, FunctionDecl *method) +{ + if (generator::is_constructor(method)) + return Method::Kind::constructor; + else if (generator::is_static(clazz, method)) + return Method::Kind::static_method; + else + return Method::Kind::member_method; +} + +/* Return the callback arguments of "fd". + */ +static std::vector find_callback_args(FunctionDecl *fd) +{ + std::vector callbacks; + int num_params = fd->getNumParams(); + + for (int i = 0; i < num_params; ++i) { + ParmVarDecl *param = fd->getParamDecl(i); + if (generator::is_callback(param->getType())) + callbacks.emplace_back(param); + } + + return callbacks; +} + +/* Construct a C++ method object from the class to which is belongs, + * the isl function from which it is derived and the method name. + * + * Perform any renaming of the method that may be required and + * determine the type of the method. + */ +Method::Method(const isl_class &clazz, FunctionDecl *fd, + const std::string &name) : + clazz(clazz), fd(fd), name(rename_method(name)), + kind(get_kind(clazz, fd)), + callbacks(find_callback_args(fd)) +{ +} + +/* Construct a C++ method object from the class to which is belongs and + * the isl function from which it is derived. + * + * Obtain the default method name and continue + * with the generic constructor. + */ +Method::Method(const isl_class &clazz, FunctionDecl *fd) : + Method(clazz, fd, clazz.method_name(fd)) +{ +} + +/* Return the number of parameters of the corresponding C function. + * + * This number includes any possible user pointers that follow callback + * arguments. These are skipped by Method::print_fd_arg_list + * during the actual argument printing. + */ +int Method::c_num_params() const +{ + return fd->getNumParams(); +} + +/* Return the number of parameters of the method + * (including the implicit "this"). + * + * By default, it is the same as the number of parameters + * of the corresponding C function. + */ +int Method::num_params() const +{ + return c_num_params(); +} + +/* Call "on_arg_skip_next" on the arguments from "start" (inclusive) + * to "end" (exclusive), calling the methods of "combiner" + * before, between and after the arguments. + * If "on_arg_skip_next" returns true then the next argument is skipped. + */ +void Method::on_arg_list(int start, int end, + const Method::list_combiner &combiner, + const std::function &on_arg_skip_next) +{ + combiner.before(); + for (int i = start; i < end; ++i) { + if (i != start) + combiner.between(); + if (on_arg_skip_next(i)) + ++i; + } + combiner.after(); +} + +/* Print the arguments from "start" (inclusive) to "end" (exclusive) + * as arguments to a method of C function call, using "print_arg_skip_next" + * to print each individual argument. If this callback return true + * then the next argument is skipped. + */ +void Method::print_arg_list(std::ostream &os, int start, int end, + const std::function &print_arg_skip_next) +{ + on_arg_list(start, end, print_combiner(os), [&] (int i) { + return print_arg_skip_next(i); + }); +} + +/* Call "on_arg" on the arguments from "start" (inclusive) to "end" (exclusive), + * calling the methods of "combiner" before, between and after the arguments. + * The first argument to "on_arg" is the position of the argument + * in this->fd. + * The second argument is the (first) position in the list of arguments + * with all callback arguments spliced in. + * + * Call on_arg_list to do the actual iteration over the arguments, skipping + * the user argument that comes after every callback argument. + * On the C++ side no user pointer is needed, as arguments can be forwarded + * as part of the std::function argument which specifies the callback function. + * The user pointer is also removed from the number of parameters + * of the C function because the pair of callback and user pointer + * is considered as a single argument that is printed as a whole + * by Method::print_param_use. + * + * In case of a callback argument, the second argument to "print_arg" + * is also adjusted to account for the spliced-in arguments of the callback. + * The return value takes the place of the callback itself, + * while the arguments (excluding the final user pointer) + * take the following positions. + */ +void Method::on_fd_arg_list(int start, int end, + const Method::list_combiner &combiner, + const std::function &on_arg) const +{ + int arg = start; + + on_arg_list(start, end, combiner, [this, &on_arg, &arg] (int i) { + auto type = fd->getParamDecl(i)->getType(); + + on_arg(i, arg++); + if (!generator::is_callback(type)) + return false; + arg += generator::prototype_n_args(type) - 1; + return true; + }); +} + +/* Print the arguments from "start" (inclusive) to "end" (exclusive) + * as arguments to a method of C function call, using "print_arg" + * to print each individual argument. + * The first argument to this callback is the position of the argument + * in this->fd. + * The second argument is the (first) position in the list of arguments + * with all callback arguments spliced in. + */ +void Method::print_fd_arg_list(std::ostream &os, int start, int end, + const std::function &print_arg) const +{ + on_fd_arg_list(start, end, print_combiner(os), print_arg); +} + +/* Call "on_arg" on the arguments to the method call, + * calling the methods of "combiner" before, between and after the arguments. + * The first argument to "on_arg" is the position of the argument + * in this->fd. + * The second argument is the (first) position in the list of arguments + * with all callback arguments spliced in. + */ +void Method::on_cpp_arg_list(const Method::list_combiner &combiner, + const std::function &on_arg) const +{ + int first_param = kind == member_method ? 1 : 0; + on_fd_arg_list(first_param, num_params(), combiner, on_arg); +} + +/* Call "on_arg" on the arguments to the method call. + * The first argument to "on_arg" is the position of the argument + * in this->fd. + * The second argument is the (first) position in the list of arguments + * with all callback arguments spliced in. + */ +void Method::on_cpp_arg_list( + const std::function &on_arg) const +{ + on_cpp_arg_list(empty_combiner(), on_arg); +} + +/* Print the arguments to the method call, using "print_arg" + * to print each individual argument. + * The first argument to this callback is the position of the argument + * in this->fd. + * The second argument is the (first) position in the list of arguments + * with all callback arguments spliced in. + */ +void Method::print_cpp_arg_list(std::ostream &os, + const std::function &print_arg) const +{ + on_cpp_arg_list(print_combiner(os), print_arg); +} + +/* Should the parameter at position "pos" be a copy (rather than + * a const reference)? + * + * Strictly speaking, a copy is only needed on isl types that are + * not marked __isl_keep, since those will be release()'d + * by code printed by Method::print_param_use. + * + * However, there may be other arguments such as integer types + * that are more naturally passed as a copy. + * The default is therefore to require a copy, except for + * arguments marked __isl_keep, string arguments or callback arguments. + */ +bool Method::param_needs_copy(int pos) const +{ + ParmVarDecl *param = get_param(pos); + QualType type = param->getOriginalType(); + + if (generator::keeps(param)) + return false; + if (generator::is_string(type) || generator::is_callback(type)) + return false; + return true; +} + +/* Return the method argument at position "pos". + */ +clang::ParmVarDecl *Method::get_param(int pos) const +{ + return fd->getParamDecl(pos); +} + +/* Construct a method that performs one or more conversions + * from the original Method (without conversions), + * the name of the type to which "this" should be converted and + * a function for determining the arguments of the constructed method. + */ +ConversionMethod::ConversionMethod(const Method &method, + const std::string &this_type, + const std::function &get_param) : + NoCopyMethod(method), this_type(this_type), + get_param_fn(get_param) +{ +} + +/* Construct a method that only performs a conversion on "this" + * from the original Method (without conversions) and + * the name of the type to which "this" should be converted. + * + * Call the generic constructor with + * a function for determining the arguments of the constructed method + * that performs no conversion. + */ +ConversionMethod::ConversionMethod(const Method &method, + const std::string &this_type) : + ConversionMethod(method, this_type, [this] (int pos) { + return Method::get_param(pos); + }) +{ +} + +/* Construct a method that performs one or more argument conversions + * from the original Method (without conversions) and + * a function for determining the arguments of the constructed method. + * + * Call the generic constructor with method.clazz.name as "this" type, + * indicating that "this" should not be converted. + */ +ConversionMethod::ConversionMethod(const Method &method, + const std::function &get_param) : + ConversionMethod(method, method.clazz.name, get_param) +{ +} + +/* Should the parameter at position "pos" be a copy (rather than + * a const reference)? + * + * Parameters of isl type do not need to be a copy. + * For other types, use the same defaults as Method. + */ +bool NoCopyMethod::param_needs_copy(int pos) const +{ + ParmVarDecl *param = get_param(pos); + QualType type = param->getOriginalType(); + + if (generator::is_isl_type(type)) + return false; + + return Method::param_needs_copy(pos); +} + +/* Return the method argument at position "pos". + * + * Call get_param_fn to determine this argument. + */ +clang::ParmVarDecl *ConversionMethod::get_param(int pos) const +{ + return get_param_fn(pos); +} + +/* Print a call to the method (without the arguments), + * with "ns" the namespace of the generated C++ bindings. + * + * If "this_type" is different from the name of the class of the method, + * then "this" needs to be converted to that type before + * the call is performed. + */ +void ConversionMethod::print_call(std::ostream &os, const std::string &ns) const +{ + if (clazz.name == this_type) { + os << "this->"; + } else { + auto cpp_type = ns + cpp_generator::type2cpp(this_type); + os << cpp_type << "(*this)."; + } + os << name; +} + +/* Construct an object representing a C++ method for setting an enum + * from the class to which is belongs, + * the isl function from which it is derived and the method and enum names. + */ +EnumMethod::EnumMethod(const isl_class &clazz, FunctionDecl *fd, + const std::string &method_name, const std::string &enum_name) : + Method(clazz, fd, method_name), enum_name(enum_name) +{ +} + +/* Print the use of the argument at position "pos" to "os". + * + * If the position is beyond the number of method arguments, + * then it corresponds to the enum value corresponding to this EnumMethod. + * Otherwise, delegate to Method::print_param_use. + */ +void EnumMethod::print_param_use(ostream &os, int pos) const +{ + if (pos == num_params()) + os << enum_name; + else + Method::print_param_use(os, pos); +} + +/* Return the number of parameters of the method + * (including the implicit "this"). + * + * The last argument of the C function does not appear in the method call, + * because it is replaced by a break-up into several methods. + */ +int EnumMethod::num_params() const +{ + return Method::num_params() - 1; +} + +/* Initialize a class method printer from the stream onto which the methods + * are printed, the class method description and the C++ interface generator. + */ +cpp_generator::class_printer::class_printer(std::ostream &os, + const isl_class &clazz, cpp_generator &generator, + bool declarations) : + os(os), clazz(clazz), cppstring(type2cpp(clazz)), generator(generator), + declarations(declarations) +{ +} diff --git a/external/mit/isl/dist/interface/cpp.h b/external/mit/isl/dist/interface/cpp.h new file mode 100644 index 000000000000..55a8fb42eef2 --- /dev/null +++ b/external/mit/isl/dist/interface/cpp.h @@ -0,0 +1,212 @@ +#ifndef ISL_INTERFACE_CPP_H +#define ISL_INTERFACE_CPP_H + +#include +#include +#include + +#include "generator.h" + +/* A generated C++ method derived from an isl function. + * + * "clazz" is the class to which the method belongs. + * "fd" is the original isl function. + * "name" is the name of the method, which may be different + * from the default name derived from "fd". + * "kind" is the type of the method. + * "callbacks" stores the callback arguments. + */ +struct Method { + enum Kind { + static_method, + member_method, + constructor, + }; + + struct list_combiner; + static list_combiner print_combiner(std::ostream &os); + static list_combiner empty_combiner(); + + Method(const isl_class &clazz, FunctionDecl *fd, + const std::string &name); + Method(const isl_class &clazz, FunctionDecl *fd); + + int c_num_params() const; + virtual int num_params() const; + virtual bool param_needs_copy(int pos) const; + virtual clang::ParmVarDecl *get_param(int pos) const; + virtual void print_param_use(ostream &os, int pos) const; + bool is_subclass_mutator() const; + static void on_arg_list(int start, int end, + const list_combiner &combiner, + const std::function &on_arg_skip_next); + static void print_arg_list(std::ostream &os, int start, int end, + const std::function &print_arg_skip_next); + void on_fd_arg_list(int start, int end, + const list_combiner &combiner, + const std::function &on_arg) const; + void print_fd_arg_list(std::ostream &os, int start, int end, + const std::function &print_arg) const; + void on_cpp_arg_list(const list_combiner &combiner, + const std::function &on_arg) const; + void on_cpp_arg_list( + const std::function &on_arg) const; + void print_cpp_arg_list(std::ostream &os, + const std::function &print_arg) const; + + const isl_class &clazz; + FunctionDecl *const fd; + const std::string name; + const enum Kind kind; + const std::vector callbacks; +}; + +/* A data structure expressing how Method::on_arg_list should combine + * the arguments. + * + * In particular, "before" is called before any argument is handled; + * "between" is called between two arguments and + * "after" is called after all arguments have been handled. + */ +struct Method::list_combiner { + const std::function before; + const std::function between; + const std::function after; +}; + +/* A method that does not require its isl type parameters to be a copy. + */ +struct NoCopyMethod : Method { + NoCopyMethod(const Method &method) : Method(method) {} + + virtual bool param_needs_copy(int pos) const override; +}; + +/* A generated method that performs one or more argument conversions and + * then calls the original method. + * + * A ConversionMethod inherits from a NoCopyMethod, because + * unlike methods that call an isl C function, + * a conversion method never calls release() on an isl type argument, + * so they can all be passed as const references. + * + * "this_type" is the name of the type to which "this" should be converted + * (if different from clazz.name). + * "get_param_fn" returns the method argument at position "pos". + */ +struct ConversionMethod : NoCopyMethod { + ConversionMethod(const Method &method, const std::string &this_type, + const std::function &get_param); + ConversionMethod(const Method &method, const std::string &this_type); + ConversionMethod(const Method &method, + const std::function &get_param); + virtual clang::ParmVarDecl *get_param(int pos) const override; + + void print_call(std::ostream &os, const std::string &ns) const; + + const std::string this_type; + const std::function get_param_fn; +}; + +/* A specialized generated C++ method for setting an enum. + * + * "enum_name" is a string representation of the enum value + * set by this method. + */ +struct EnumMethod : public Method { + EnumMethod(const isl_class &clazz, FunctionDecl *fd, + const std::string &method_name, const std::string &enum_name); + + virtual int num_params() const override; + virtual void print_param_use(ostream &os, int pos) const override; + + std::string enum_name; +}; + +/* A type printer for converting argument and return types, + * as well as the class type, + * to string representations of the corresponding types + * in the C++ interface. + */ +struct cpp_type_printer { + cpp_type_printer() {} + + virtual std::string isl_bool() const; + virtual std::string isl_stat() const; + virtual std::string isl_size() const; + virtual std::string isl_namespace() const; + virtual std::string class_type(const std::string &cpp_name) const; + virtual std::string qualified(int arg, const std::string &cpp_type) + const; + std::string isl_type(int arg, QualType type) const; + std::string generate_callback_args(int arg, QualType type, bool cpp) + const; + std::string generate_callback_type(int arg, QualType type) const; + std::string param(int arg, QualType type) const; + std::string return_type(const Method &method) const; +}; + +/* Generator for C++ bindings. + */ +class cpp_generator : public generator { +protected: + struct class_printer; +public: + cpp_generator(SourceManager &SM, set &exported_types, + set exported_functions, + set functions); +private: + void set_class_construction_types(isl_class &clazz); + void set_construction_types(); + void copy_methods(isl_class &clazz, const std::string &name, + const isl_class &super, const function_set &methods); + void copy_super_methods(isl_class &clazz, const isl_class &super); + void copy_super_methods(isl_class &clazz, set &done); + void copy_super_methods(); + bool is_implicit_conversion(const Method &cons); + bool is_subclass(QualType subclass_type, const isl_class &class_type); +public: + static string type2cpp(const isl_class &clazz); + static string type2cpp(string type_string); +}; + +/* A helper class for printing method declarations and definitions + * of a class. + * + * "os" is the stream onto which the methods are printed. + * "clazz" describes the methods of the class. + * "cppstring" is the C++ name of the class. + * "generator" is the C++ interface generator printing the classes. + * "declarations" is set if this object is used to print declarations. + */ +struct cpp_generator::class_printer { + std::ostream &os; + const isl_class &clazz; + const std::string cppstring; + cpp_generator &generator; + const bool declarations; + + class_printer(std::ostream &os, const isl_class &clazz, + cpp_generator &generator, bool declarations); + + void print_constructors(); + void print_methods(); + bool next_variant(FunctionDecl *fd, std::vector &convert); + void print_method_variants(FunctionDecl *fd, const std::string &name); + virtual bool want_descendent_overloads(const function_set &methods) = 0; + void print_descendent_overloads(FunctionDecl *fd, + const std::string &name); + void print_method_group(const function_set &methods, + const std::string &name); + virtual void print_method(const Method &method) = 0; + virtual void print_method(const ConversionMethod &method) = 0; + virtual void print_get_method(FunctionDecl *fd) = 0; + void print_set_enums(FunctionDecl *fd); + void print_set_enums(); + ParmVarDecl *get_param(FunctionDecl *fd, int pos, + const std::vector &convert); + void print_method_header(const Method &method, + const cpp_type_printer &type_printer); +}; + +#endif diff --git a/external/mit/isl/dist/interface/cpp_conversion.cc b/external/mit/isl/dist/interface/cpp_conversion.cc new file mode 100644 index 000000000000..58294d54800b --- /dev/null +++ b/external/mit/isl/dist/interface/cpp_conversion.cc @@ -0,0 +1,86 @@ +/* + * Copyright 2018 Sven Verdoolaege + * + * Use of this software is governed by the MIT license + * + * Written by Sven Verdoolaege. + */ + +#include +#include +#include + +#include "cpp.h" +#include "cpp_conversion.h" + +/* If "clazz" describes a subclass of a C type, then print code + * for converting an object of the class derived from the C type + * to the subclass. Do this by first converting this class + * to the immediate superclass of the subclass and then converting + * from this superclass to the subclass. + */ +void cpp_conversion_generator::cast(const isl_class &clazz, const char *to) +{ + string name = cpp_generator::type2cpp(clazz); + + if (!clazz.is_type_subclass()) + return; + + cast(classes[clazz.superclass_name], to); + printf(".as<%s%s>()", to, name.c_str()); +} + +/* Print a function called "function" for converting objects of + * "clazz" from the "from" bindings to the "to" bindings. + * If "clazz" describes a subclass of a C type, then the result + * of the conversion between bindings is derived from the C type and + * needs to be converted back to the subclass. + */ +void cpp_conversion_generator::convert(const isl_class &clazz, + const char *from, const char *to, const char *function) +{ + string name = cpp_generator::type2cpp(clazz); + + printf("%s%s %s(%s%s obj) {\n", + to, name.c_str(), function, from, name.c_str()); + printf("\t""return %s""manage(obj.copy())", to); + cast(clazz, to); + printf(";\n"); + printf("}\n"); + printf("\n"); +} + +/* Print functions for converting objects of "clazz" + * between the default and the checked C++ bindings. + * + * The conversion from default to checked is called "check". + * The inverse conversion is called "uncheck". + * For example, to "set", the following two functions are generated: + * + * checked::set check(set obj) { + * return checked::manage(obj.copy()); + * } + * + * set uncheck(checked::set obj) { + * return manage(obj.copy()); + * } + */ +void cpp_conversion_generator::print(const isl_class &clazz) +{ + convert(clazz, "", "checked::", "check"); + convert(clazz, "checked::", "", "uncheck"); +} + +/* Generate conversion functions for converting objects between + * the default and the checked C++ bindings. + * Do this for each exported class. + */ +void cpp_conversion_generator::generate() +{ + map::iterator ci; + + printf("namespace isl {\n\n"); + for (ci = classes.begin(); ci != classes.end(); ++ci) + print(ci->second); + printf("} // namespace isl\n"); +} diff --git a/external/mit/isl/dist/interface/cpp_conversion.h b/external/mit/isl/dist/interface/cpp_conversion.h new file mode 100644 index 000000000000..57856b2c6a5d --- /dev/null +++ b/external/mit/isl/dist/interface/cpp_conversion.h @@ -0,0 +1,15 @@ +#include "generator.h" + +class cpp_conversion_generator : public generator { + void cast(const isl_class &clazz, const char *to); + void convert(const isl_class &clazz, const char *from, const char *to, + const char *function); + void print(const isl_class &clazz); +public: + cpp_conversion_generator(SourceManager &SM, + set &exported_types, + set exported_functions, + set functions) : + generator(SM, exported_types, exported_functions, functions) {} + virtual void generate(); +}; diff --git a/external/mit/isl/dist/interface/depcomp b/external/mit/isl/dist/interface/depcomp new file mode 100755 index 000000000000..715e34311ed2 --- /dev/null +++ b/external/mit/isl/dist/interface/depcomp @@ -0,0 +1,791 @@ +#! /bin/sh +# depcomp - compile a program generating dependencies as side-effects + +scriptversion=2018-03-07.03; # UTC + +# Copyright (C) 1999-2021 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Originally written by Alexandre Oliva . + +case $1 in + '') + echo "$0: No command. Try '$0 --help' for more information." 1>&2 + exit 1; + ;; + -h | --h*) + cat <<\EOF +Usage: depcomp [--help] [--version] PROGRAM [ARGS] + +Run PROGRAMS ARGS to compile a file, generating dependencies +as side-effects. + +Environment variables: + depmode Dependency tracking mode. + source Source file read by 'PROGRAMS ARGS'. + object Object file output by 'PROGRAMS ARGS'. + DEPDIR directory where to store dependencies. + depfile Dependency file to output. + tmpdepfile Temporary file to use when outputting dependencies. + libtool Whether libtool is used (yes/no). + +Report bugs to . +EOF + exit $? + ;; + -v | --v*) + echo "depcomp $scriptversion" + exit $? + ;; +esac + +# Get the directory component of the given path, and save it in the +# global variables '$dir'. Note that this directory component will +# be either empty or ending with a '/' character. This is deliberate. +set_dir_from () +{ + case $1 in + */*) dir=`echo "$1" | sed -e 's|/[^/]*$|/|'`;; + *) dir=;; + esac +} + +# Get the suffix-stripped basename of the given path, and save it the +# global variable '$base'. +set_base_from () +{ + base=`echo "$1" | sed -e 's|^.*/||' -e 's/\.[^.]*$//'` +} + +# If no dependency file was actually created by the compiler invocation, +# we still have to create a dummy depfile, to avoid errors with the +# Makefile "include basename.Plo" scheme. +make_dummy_depfile () +{ + echo "#dummy" > "$depfile" +} + +# Factor out some common post-processing of the generated depfile. +# Requires the auxiliary global variable '$tmpdepfile' to be set. +aix_post_process_depfile () +{ + # If the compiler actually managed to produce a dependency file, + # post-process it. + if test -f "$tmpdepfile"; then + # Each line is of the form 'foo.o: dependency.h'. + # Do two passes, one to just change these to + # $object: dependency.h + # and one to simply output + # dependency.h: + # which is needed to avoid the deleted-header problem. + { sed -e "s,^.*\.[$lower]*:,$object:," < "$tmpdepfile" + sed -e "s,^.*\.[$lower]*:[$tab ]*,," -e 's,$,:,' < "$tmpdepfile" + } > "$depfile" + rm -f "$tmpdepfile" + else + make_dummy_depfile + fi +} + +# A tabulation character. +tab=' ' +# A newline character. +nl=' +' +# Character ranges might be problematic outside the C locale. +# These definitions help. +upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ +lower=abcdefghijklmnopqrstuvwxyz +digits=0123456789 +alpha=${upper}${lower} + +if test -z "$depmode" || test -z "$source" || test -z "$object"; then + echo "depcomp: Variables source, object and depmode must be set" 1>&2 + exit 1 +fi + +# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. +depfile=${depfile-`echo "$object" | + sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} +tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} + +rm -f "$tmpdepfile" + +# Avoid interferences from the environment. +gccflag= dashmflag= + +# Some modes work just like other modes, but use different flags. We +# parameterize here, but still list the modes in the big case below, +# to make depend.m4 easier to write. Note that we *cannot* use a case +# here, because this file can only contain one case statement. +if test "$depmode" = hp; then + # HP compiler uses -M and no extra arg. + gccflag=-M + depmode=gcc +fi + +if test "$depmode" = dashXmstdout; then + # This is just like dashmstdout with a different argument. + dashmflag=-xM + depmode=dashmstdout +fi + +cygpath_u="cygpath -u -f -" +if test "$depmode" = msvcmsys; then + # This is just like msvisualcpp but w/o cygpath translation. + # Just convert the backslash-escaped backslashes to single forward + # slashes to satisfy depend.m4 + cygpath_u='sed s,\\\\,/,g' + depmode=msvisualcpp +fi + +if test "$depmode" = msvc7msys; then + # This is just like msvc7 but w/o cygpath translation. + # Just convert the backslash-escaped backslashes to single forward + # slashes to satisfy depend.m4 + cygpath_u='sed s,\\\\,/,g' + depmode=msvc7 +fi + +if test "$depmode" = xlc; then + # IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information. + gccflag=-qmakedep=gcc,-MF + depmode=gcc +fi + +case "$depmode" in +gcc3) +## gcc 3 implements dependency tracking that does exactly what +## we want. Yay! Note: for some reason libtool 1.4 doesn't like +## it if -MD -MP comes after the -MF stuff. Hmm. +## Unfortunately, FreeBSD c89 acceptance of flags depends upon +## the command line argument order; so add the flags where they +## appear in depend2.am. Note that the slowdown incurred here +## affects only configure: in makefiles, %FASTDEP% shortcuts this. + for arg + do + case $arg in + -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;; + *) set fnord "$@" "$arg" ;; + esac + shift # fnord + shift # $arg + done + "$@" + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + mv "$tmpdepfile" "$depfile" + ;; + +gcc) +## Note that this doesn't just cater to obsosete pre-3.x GCC compilers. +## but also to in-use compilers like IMB xlc/xlC and the HP C compiler. +## (see the conditional assignment to $gccflag above). +## There are various ways to get dependency output from gcc. Here's +## why we pick this rather obscure method: +## - Don't want to use -MD because we'd like the dependencies to end +## up in a subdir. Having to rename by hand is ugly. +## (We might end up doing this anyway to support other compilers.) +## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like +## -MM, not -M (despite what the docs say). Also, it might not be +## supported by the other compilers which use the 'gcc' depmode. +## - Using -M directly means running the compiler twice (even worse +## than renaming). + if test -z "$gccflag"; then + gccflag=-MD, + fi + "$@" -Wp,"$gccflag$tmpdepfile" + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + # The second -e expression handles DOS-style file names with drive + # letters. + sed -e 's/^[^:]*: / /' \ + -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" +## This next piece of magic avoids the "deleted header file" problem. +## The problem is that when a header file which appears in a .P file +## is deleted, the dependency causes make to die (because there is +## typically no way to rebuild the header). We avoid this by adding +## dummy dependencies for each header file. Too bad gcc doesn't do +## this for us directly. +## Some versions of gcc put a space before the ':'. On the theory +## that the space means something, we add a space to the output as +## well. hp depmode also adds that space, but also prefixes the VPATH +## to the object. Take care to not repeat it in the output. +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \ + | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +sgi) + if test "$libtool" = yes; then + "$@" "-Wp,-MDupdate,$tmpdepfile" + else + "$@" -MDupdate "$tmpdepfile" + fi + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + + if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files + echo "$object : \\" > "$depfile" + # Clip off the initial element (the dependent). Don't try to be + # clever and replace this with sed code, as IRIX sed won't handle + # lines with more than a fixed number of characters (4096 in + # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; + # the IRIX cc adds comments like '#:fec' to the end of the + # dependency line. + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' \ + | tr "$nl" ' ' >> "$depfile" + echo >> "$depfile" + # The second pass generates a dummy entry for each header file. + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ + >> "$depfile" + else + make_dummy_depfile + fi + rm -f "$tmpdepfile" + ;; + +xlc) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +aix) + # The C for AIX Compiler uses -M and outputs the dependencies + # in a .u file. In older versions, this file always lives in the + # current directory. Also, the AIX compiler puts '$object:' at the + # start of each line; $object doesn't have directory information. + # Version 6 uses the directory in both cases. + set_dir_from "$object" + set_base_from "$object" + if test "$libtool" = yes; then + tmpdepfile1=$dir$base.u + tmpdepfile2=$base.u + tmpdepfile3=$dir.libs/$base.u + "$@" -Wc,-M + else + tmpdepfile1=$dir$base.u + tmpdepfile2=$dir$base.u + tmpdepfile3=$dir$base.u + "$@" -M + fi + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + do + test -f "$tmpdepfile" && break + done + aix_post_process_depfile + ;; + +tcc) + # tcc (Tiny C Compiler) understand '-MD -MF file' since version 0.9.26 + # FIXME: That version still under development at the moment of writing. + # Make that this statement remains true also for stable, released + # versions. + # It will wrap lines (doesn't matter whether long or short) with a + # trailing '\', as in: + # + # foo.o : \ + # foo.c \ + # foo.h \ + # + # It will put a trailing '\' even on the last line, and will use leading + # spaces rather than leading tabs (at least since its commit 0394caf7 + # "Emit spaces for -MD"). + "$@" -MD -MF "$tmpdepfile" + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + # Each non-empty line is of the form 'foo.o : \' or ' dep.h \'. + # We have to change lines of the first kind to '$object: \'. + sed -e "s|.*:|$object :|" < "$tmpdepfile" > "$depfile" + # And for each line of the second kind, we have to emit a 'dep.h:' + # dummy dependency, to avoid the deleted-header problem. + sed -n -e 's|^ *\(.*\) *\\$|\1:|p' < "$tmpdepfile" >> "$depfile" + rm -f "$tmpdepfile" + ;; + +## The order of this option in the case statement is important, since the +## shell code in configure will try each of these formats in the order +## listed in this file. A plain '-MD' option would be understood by many +## compilers, so we must ensure this comes after the gcc and icc options. +pgcc) + # Portland's C compiler understands '-MD'. + # Will always output deps to 'file.d' where file is the root name of the + # source file under compilation, even if file resides in a subdirectory. + # The object file name does not affect the name of the '.d' file. + # pgcc 10.2 will output + # foo.o: sub/foo.c sub/foo.h + # and will wrap long lines using '\' : + # foo.o: sub/foo.c ... \ + # sub/foo.h ... \ + # ... + set_dir_from "$object" + # Use the source, not the object, to determine the base name, since + # that's sadly what pgcc will do too. + set_base_from "$source" + tmpdepfile=$base.d + + # For projects that build the same source file twice into different object + # files, the pgcc approach of using the *source* file root name can cause + # problems in parallel builds. Use a locking strategy to avoid stomping on + # the same $tmpdepfile. + lockdir=$base.d-lock + trap " + echo '$0: caught signal, cleaning up...' >&2 + rmdir '$lockdir' + exit 1 + " 1 2 13 15 + numtries=100 + i=$numtries + while test $i -gt 0; do + # mkdir is a portable test-and-set. + if mkdir "$lockdir" 2>/dev/null; then + # This process acquired the lock. + "$@" -MD + stat=$? + # Release the lock. + rmdir "$lockdir" + break + else + # If the lock is being held by a different process, wait + # until the winning process is done or we timeout. + while test -d "$lockdir" && test $i -gt 0; do + sleep 1 + i=`expr $i - 1` + done + fi + i=`expr $i - 1` + done + trap - 1 2 13 15 + if test $i -le 0; then + echo "$0: failed to acquire lock after $numtries attempts" >&2 + echo "$0: check lockdir '$lockdir'" >&2 + exit 1 + fi + + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + # Each line is of the form `foo.o: dependent.h', + # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. + # Do two passes, one to just change these to + # `$object: dependent.h' and one to simply `dependent.h:'. + sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process this invocation + # correctly. Breaking it into two sed invocations is a workaround. + sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" \ + | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp2) + # The "hp" stanza above does not work with aCC (C++) and HP's ia64 + # compilers, which have integrated preprocessors. The correct option + # to use with these is +Maked; it writes dependencies to a file named + # 'foo.d', which lands next to the object file, wherever that + # happens to be. + # Much of this is similar to the tru64 case; see comments there. + set_dir_from "$object" + set_base_from "$object" + if test "$libtool" = yes; then + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir.libs/$base.d + "$@" -Wc,+Maked + else + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir$base.d + "$@" +Maked + fi + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile1" "$tmpdepfile2" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + sed -e "s,^.*\.[$lower]*:,$object:," "$tmpdepfile" > "$depfile" + # Add 'dependent.h:' lines. + sed -ne '2,${ + s/^ *// + s/ \\*$// + s/$/:/ + p + }' "$tmpdepfile" >> "$depfile" + else + make_dummy_depfile + fi + rm -f "$tmpdepfile" "$tmpdepfile2" + ;; + +tru64) + # The Tru64 compiler uses -MD to generate dependencies as a side + # effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'. + # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put + # dependencies in 'foo.d' instead, so we check for that too. + # Subdirectories are respected. + set_dir_from "$object" + set_base_from "$object" + + if test "$libtool" = yes; then + # Libtool generates 2 separate objects for the 2 libraries. These + # two compilations output dependencies in $dir.libs/$base.o.d and + # in $dir$base.o.d. We have to check for both files, because + # one of the two compilations can be disabled. We should prefer + # $dir$base.o.d over $dir.libs/$base.o.d because the latter is + # automatically cleaned when .libs/ is deleted, while ignoring + # the former would cause a distcleancheck panic. + tmpdepfile1=$dir$base.o.d # libtool 1.5 + tmpdepfile2=$dir.libs/$base.o.d # Likewise. + tmpdepfile3=$dir.libs/$base.d # Compaq CCC V6.2-504 + "$@" -Wc,-MD + else + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir$base.d + tmpdepfile3=$dir$base.d + "$@" -MD + fi + + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + do + test -f "$tmpdepfile" && break + done + # Same post-processing that is required for AIX mode. + aix_post_process_depfile + ;; + +msvc7) + if test "$libtool" = yes; then + showIncludes=-Wc,-showIncludes + else + showIncludes=-showIncludes + fi + "$@" $showIncludes > "$tmpdepfile" + stat=$? + grep -v '^Note: including file: ' "$tmpdepfile" + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + # The first sed program below extracts the file names and escapes + # backslashes for cygpath. The second sed program outputs the file + # name when reading, but also accumulates all include files in the + # hold buffer in order to output them again at the end. This only + # works with sed implementations that can handle large buffers. + sed < "$tmpdepfile" -n ' +/^Note: including file: *\(.*\)/ { + s//\1/ + s/\\/\\\\/g + p +}' | $cygpath_u | sort -u | sed -n ' +s/ /\\ /g +s/\(.*\)/'"$tab"'\1 \\/p +s/.\(.*\) \\/\1:/ +H +$ { + s/.*/'"$tab"'/ + G + p +}' >> "$depfile" + echo >> "$depfile" # make sure the fragment doesn't end with a backslash + rm -f "$tmpdepfile" + ;; + +msvc7msys) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +#nosideeffect) + # This comment above is used by automake to tell side-effect + # dependency tracking mechanisms from slower ones. + +dashmstdout) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout, regardless of -o. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + # Remove '-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + test -z "$dashmflag" && dashmflag=-M + # Require at least two characters before searching for ':' + # in the target name. This is to cope with DOS-style filenames: + # a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise. + "$@" $dashmflag | + sed "s|^[$tab ]*[^:$tab ][^:][^:]*:[$tab ]*|$object: |" > "$tmpdepfile" + rm -f "$depfile" + cat < "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process this sed invocation + # correctly. Breaking it into two sed invocations is a workaround. + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ + | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +dashXmstdout) + # This case only exists to satisfy depend.m4. It is never actually + # run, as this mode is specially recognized in the preamble. + exit 1 + ;; + +makedepend) + "$@" || exit $? + # Remove any Libtool call + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + # X makedepend + shift + cleared=no eat=no + for arg + do + case $cleared in + no) + set ""; shift + cleared=yes ;; + esac + if test $eat = yes; then + eat=no + continue + fi + case "$arg" in + -D*|-I*) + set fnord "$@" "$arg"; shift ;; + # Strip any option that makedepend may not understand. Remove + # the object too, otherwise makedepend will parse it as a source file. + -arch) + eat=yes ;; + -*|$object) + ;; + *) + set fnord "$@" "$arg"; shift ;; + esac + done + obj_suffix=`echo "$object" | sed 's/^.*\././'` + touch "$tmpdepfile" + ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" + rm -f "$depfile" + # makedepend may prepend the VPATH from the source file name to the object. + # No need to regex-escape $object, excess matching of '.' is harmless. + sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process the last invocation + # correctly. Breaking it into two sed invocations is a workaround. + sed '1,2d' "$tmpdepfile" \ + | tr ' ' "$nl" \ + | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ + | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" "$tmpdepfile".bak + ;; + +cpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + # Remove '-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + "$@" -E \ + | sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ + -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ + | sed '$ s: \\$::' > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + cat < "$tmpdepfile" >> "$depfile" + sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvisualcpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + IFS=" " + for arg + do + case "$arg" in + -o) + shift + ;; + $object) + shift + ;; + "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") + set fnord "$@" + shift + shift + ;; + *) + set fnord "$@" "$arg" + shift + shift + ;; + esac + done + "$@" -E 2>/dev/null | + sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile" + echo "$tab" >> "$depfile" + sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvcmsys) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +none) + exec "$@" + ;; + +*) + echo "Unknown depmode $depmode" 1>&2 + exit 1 + ;; +esac + +exit 0 + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'before-save-hook 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC0" +# time-stamp-end: "; # UTC" +# End: diff --git a/external/mit/isl/dist/interface/extract_interface.cc b/external/mit/isl/dist/interface/extract_interface.cc new file mode 100644 index 000000000000..aebb049eca4d --- /dev/null +++ b/external/mit/isl/dist/interface/extract_interface.cc @@ -0,0 +1,599 @@ +/* + * Copyright 2011 Sven Verdoolaege. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY SVEN VERDOOLAEGE ''AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SVEN VERDOOLAEGE OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation + * are those of the authors and should not be interpreted as + * representing official policies, either expressed or implied, of + * Sven Verdoolaege. + */ + +#include "isl_config.h" +#undef PACKAGE + +#include +#include +#include +#ifdef HAVE_ADT_OWNINGPTR_H +#include +#else +#include +#endif +#ifdef HAVE_LLVM_OPTION_ARG_H +#include +#endif +#include +#include +#ifdef HAVE_TARGETPARSER_HOST_H +#include +#else +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef HAVE_BASIC_DIAGNOSTICOPTIONS_H +#include +#else +#include +#endif +#include +#include +#include +#ifdef HAVE_LEX_PREPROCESSOROPTIONS_H +#include +#else +#include +#endif +#include +#include +#include + +#include "extract_interface.h" +#include "generator.h" +#include "python.h" +#include "plain_cpp.h" +#include "cpp_conversion.h" +#include "template_cpp.h" + +using namespace std; +using namespace clang; +using namespace clang::driver; +#ifdef HAVE_LLVM_OPTION_ARG_H +using namespace llvm::opt; +#endif + +#ifdef HAVE_ADT_OWNINGPTR_H +#define unique_ptr llvm::OwningPtr +#endif + +static llvm::cl::opt InputFilename(llvm::cl::Positional, + llvm::cl::Required, llvm::cl::desc("")); +static llvm::cl::list Includes("I", + llvm::cl::desc("Header search path"), + llvm::cl::value_desc("path"), llvm::cl::Prefix); + +static llvm::cl::opt OutputLanguage(llvm::cl::Required, + llvm::cl::ValueRequired, "language", + llvm::cl::desc("Bindings to generate"), + llvm::cl::value_desc("name")); + +static const char *ResourceDir = + CLANG_PREFIX "/lib/clang/" CLANG_VERSION_STRING; + +/* Does decl have an attribute of the following form? + * + * __attribute__((annotate("name"))) + */ +bool has_annotation(Decl *decl, const char *name) +{ + if (!decl->hasAttrs()) + return false; + + AttrVec attrs = decl->getAttrs(); + for (AttrVec::const_iterator i = attrs.begin() ; i != attrs.end(); ++i) { + const AnnotateAttr *ann = dyn_cast(*i); + if (!ann) + continue; + if (ann->getAnnotation().str() == name) + return true; + } + + return false; +} + +/* Is decl marked as exported? + */ +static bool is_exported(Decl *decl) +{ + return has_annotation(decl, "isl_export"); +} + +/* Collect all types and functions that are annotated "isl_export" + * in "exported_types" and "exported_function". Collect all function + * declarations in "functions". + * + * We currently only consider single declarations. + */ +struct MyASTConsumer : public ASTConsumer { + set exported_types; + set exported_functions; + set functions; + + virtual HandleTopLevelDeclReturn HandleTopLevelDecl(DeclGroupRef D) { + Decl *decl; + + if (!D.isSingleDecl()) + return HandleTopLevelDeclContinue; + decl = D.getSingleDecl(); + if (isa(decl)) + functions.insert(cast(decl)); + if (!is_exported(decl)) + return HandleTopLevelDeclContinue; + switch (decl->getKind()) { + case Decl::Record: + exported_types.insert(cast(decl)); + break; + case Decl::Function: + exported_functions.insert(cast(decl)); + break; + default: + break; + } + return HandleTopLevelDeclContinue; + } +}; + +#ifdef USE_ARRAYREF + +#ifdef HAVE_CXXISPRODUCTION +static Driver *construct_driver(const char *binary, DiagnosticsEngine &Diags) +{ + return new Driver(binary, llvm::sys::getDefaultTargetTriple(), + "", false, false, Diags); +} +#elif defined(HAVE_ISPRODUCTION) +static Driver *construct_driver(const char *binary, DiagnosticsEngine &Diags) +{ + return new Driver(binary, llvm::sys::getDefaultTargetTriple(), + "", false, Diags); +} +#elif defined(DRIVER_CTOR_TAKES_DEFAULTIMAGENAME) +static Driver *construct_driver(const char *binary, DiagnosticsEngine &Diags) +{ + return new Driver(binary, llvm::sys::getDefaultTargetTriple(), + "", Diags); +} +#else +static Driver *construct_driver(const char *binary, DiagnosticsEngine &Diags) +{ + return new Driver(binary, llvm::sys::getDefaultTargetTriple(), Diags); +} +#endif + +namespace clang { namespace driver { class Job; } } + +/* Clang changed its API from 3.5 to 3.6 and once more in 3.7. + * We fix this with a simple overloaded function here. + */ +struct ClangAPI { + static Job *command(Job *J) { return J; } + static Job *command(Job &J) { return &J; } + static Command *command(Command &C) { return &C; } +}; + +#ifdef CREATE_FROM_ARGS_TAKES_ARRAYREF + +/* Call CompilerInvocation::CreateFromArgs with the right arguments. + * In this case, an ArrayRef. + */ +static void create_from_args(CompilerInvocation &invocation, + const ArgStringList *args, DiagnosticsEngine &Diags) +{ + CompilerInvocation::CreateFromArgs(invocation, *args, Diags); +} + +#else + +/* Call CompilerInvocation::CreateFromArgs with the right arguments. + * In this case, two "const char *" pointers. + */ +static void create_from_args(CompilerInvocation &invocation, + const ArgStringList *args, DiagnosticsEngine &Diags) +{ + CompilerInvocation::CreateFromArgs(invocation, args->data() + 1, + args->data() + args->size(), + Diags); +} + +#endif + +#ifdef CLANG_SYSROOT +/* Set sysroot if required. + * + * If CLANG_SYSROOT is defined, then set it to this value. + */ +static void set_sysroot(ArgStringList &args) +{ + args.push_back("-isysroot"); + args.push_back(CLANG_SYSROOT); +} +#else +/* Set sysroot if required. + * + * If CLANG_SYSROOT is not defined, then it does not need to be set. + */ +static void set_sysroot(ArgStringList &args) +{ +} +#endif + +/* Create a CompilerInvocation object that stores the command line + * arguments constructed by the driver. + * The arguments are mainly useful for setting up the system include + * paths on newer clangs and on some platforms. + */ +static CompilerInvocation *construct_invocation(const char *filename, + DiagnosticsEngine &Diags) +{ + const char *binary = CLANG_PREFIX"/bin/clang"; + const unique_ptr driver(construct_driver(binary, Diags)); + std::vector Argv; + Argv.push_back(binary); + Argv.push_back(filename); + const unique_ptr compilation( + driver->BuildCompilation(llvm::ArrayRef(Argv))); + JobList &Jobs = compilation->getJobs(); + + Command *cmd = cast(ClangAPI::command(*Jobs.begin())); + if (strcmp(cmd->getCreator().getName(), "clang")) + return NULL; + + ArgStringList args = cmd->getArguments(); + set_sysroot(args); + + CompilerInvocation *invocation = new CompilerInvocation; + create_from_args(*invocation, &args, Diags); + return invocation; +} + +#else + +static CompilerInvocation *construct_invocation(const char *filename, + DiagnosticsEngine &Diags) +{ + return NULL; +} + +#endif + +#ifdef HAVE_BASIC_DIAGNOSTICOPTIONS_H + +static TextDiagnosticPrinter *construct_printer(void) +{ + return new TextDiagnosticPrinter(llvm::errs(), new DiagnosticOptions()); +} + +#else + +static TextDiagnosticPrinter *construct_printer(void) +{ + DiagnosticOptions DO; + return new TextDiagnosticPrinter(llvm::errs(), DO); +} + +#endif + +#ifdef CREATETARGETINFO_TAKES_SHARED_PTR + +static TargetInfo *create_target_info(CompilerInstance *Clang, + DiagnosticsEngine &Diags) +{ + shared_ptr TO = Clang->getInvocation().TargetOpts; + TO->Triple = llvm::sys::getDefaultTargetTriple(); + return TargetInfo::CreateTargetInfo(Diags, TO); +} + +#elif defined(CREATETARGETINFO_TAKES_POINTER) + +static TargetInfo *create_target_info(CompilerInstance *Clang, + DiagnosticsEngine &Diags) +{ + TargetOptions &TO = Clang->getTargetOpts(); + TO.Triple = llvm::sys::getDefaultTargetTriple(); + return TargetInfo::CreateTargetInfo(Diags, &TO); +} + +#else + +static TargetInfo *create_target_info(CompilerInstance *Clang, + DiagnosticsEngine &Diags) +{ + TargetOptions &TO = Clang->getTargetOpts(); + TO.Triple = llvm::sys::getDefaultTargetTriple(); + return TargetInfo::CreateTargetInfo(Diags, TO); +} + +#endif + +#ifdef CREATEDIAGNOSTICS_TAKES_ARG + +static void create_diagnostics(CompilerInstance *Clang) +{ + Clang->createDiagnostics(0, NULL, construct_printer()); +} + +#else + +static void create_diagnostics(CompilerInstance *Clang) +{ + Clang->createDiagnostics(construct_printer()); +} + +#endif + +#ifdef CREATEPREPROCESSOR_TAKES_TUKIND + +static void create_preprocessor(CompilerInstance *Clang) +{ + Clang->createPreprocessor(TU_Complete); +} + +#else + +static void create_preprocessor(CompilerInstance *Clang) +{ + Clang->createPreprocessor(); +} + +#endif + +#ifdef ADDPATH_TAKES_4_ARGUMENTS + +/* Add "Path" to the header search options. + * + * Do not take into account sysroot, i.e., set ignoreSysRoot to true. + */ +void add_path(HeaderSearchOptions &HSO, string Path) +{ + HSO.AddPath(Path, frontend::Angled, false, true); +} + +#else + +/* Add "Path" to the header search options. + * + * Do not take into account sysroot, i.e., set IsSysRootRelative to false. + */ +void add_path(HeaderSearchOptions &HSO, string Path) +{ + HSO.AddPath(Path, frontend::Angled, true, false, false); +} + +#endif + +#ifdef HAVE_SETMAINFILEID + +static void create_main_file_id(SourceManager &SM, const FileEntry *file) +{ + SM.setMainFileID(SM.createFileID(file, SourceLocation(), + SrcMgr::C_User)); +} + +#else + +static void create_main_file_id(SourceManager &SM, const FileEntry *file) +{ + SM.createMainFileID(file); +} + +#endif + +#ifdef SETLANGDEFAULTS_TAKES_5_ARGUMENTS + +#include "set_lang_defaults_arg4.h" + +static void set_lang_defaults(CompilerInstance *Clang) +{ + PreprocessorOptions &PO = Clang->getPreprocessorOpts(); + TargetOptions &TO = Clang->getTargetOpts(); + llvm::Triple T(TO.Triple); + SETLANGDEFAULTS::setLangDefaults(Clang->getLangOpts(), IK_C, T, + setLangDefaultsArg4(PO), + LangStandard::lang_unspecified); +} + +#else + +static void set_lang_defaults(CompilerInstance *Clang) +{ + CompilerInvocation::setLangDefaults(Clang->getLangOpts(), IK_C, + LangStandard::lang_unspecified); +} + +#endif + +#ifdef SETINVOCATION_TAKES_SHARED_PTR + +static void set_invocation(CompilerInstance *Clang, + CompilerInvocation *invocation) +{ + Clang->setInvocation(std::make_shared(*invocation)); +} + +#else + +static void set_invocation(CompilerInstance *Clang, + CompilerInvocation *invocation) +{ + Clang->setInvocation(invocation); +} + +#endif + +/* Helper function for ignore_error that only gets enabled if T + * (which is either const FileEntry * or llvm::ErrorOr) + * has getError method, i.e., if it is llvm::ErrorOr. + */ +template +static const FileEntry *ignore_error_helper(const T obj, int, + int[1][sizeof(obj.getError())]) +{ + return *obj; +} + +/* Helper function for ignore_error that is always enabled, + * but that only gets selected if the variant above is not enabled, + * i.e., if T is const FileEntry *. + */ +template +static const FileEntry *ignore_error_helper(const T obj, long, void *) +{ + return obj; +} + +/* Given either a const FileEntry * or a llvm::ErrorOr, + * extract out the const FileEntry *. + */ +template +static const FileEntry *ignore_error(const T obj) +{ + return ignore_error_helper(obj, 0, NULL); +} + +/* Return the FileEntry corresponding to the given file name + * in the given compiler instances, ignoring any error. + */ +static const FileEntry *getFile(CompilerInstance *Clang, std::string Filename) +{ + return ignore_error(Clang->getFileManager().getFile(Filename)); +} + +/* Create an interface generator for the selected language and + * then use it to generate the interface. + */ +static void generate(MyASTConsumer &consumer, SourceManager &SM) +{ + generator *gen; + + if (OutputLanguage.compare("python") == 0) { + gen = new python_generator(SM, consumer.exported_types, + consumer.exported_functions, consumer.functions); + } else if (OutputLanguage.compare("cpp") == 0) { + gen = new plain_cpp_generator(SM, consumer.exported_types, + consumer.exported_functions, consumer.functions); + } else if (OutputLanguage.compare("cpp-checked") == 0) { + gen = new plain_cpp_generator(SM, consumer.exported_types, + consumer.exported_functions, consumer.functions, true); + } else if (OutputLanguage.compare("cpp-checked-conversion") == 0) { + gen = new cpp_conversion_generator(SM, consumer.exported_types, + consumer.exported_functions, consumer.functions); + } else if (OutputLanguage.compare("template-cpp") == 0) { + gen = new template_cpp_generator(SM, consumer.exported_types, + consumer.exported_functions, consumer.functions); + } else { + cerr << "Language '" << OutputLanguage + << "' not recognized." << endl + << "Not generating bindings." << endl; + exit(EXIT_FAILURE); + } + + gen->generate(); +} + +int main(int argc, char *argv[]) +{ + llvm::cl::ParseCommandLineOptions(argc, argv); + + CompilerInstance *Clang = new CompilerInstance(); + create_diagnostics(Clang); + DiagnosticsEngine &Diags = Clang->getDiagnostics(); + Diags.setSuppressSystemWarnings(true); + TargetInfo *target = create_target_info(Clang, Diags); + Clang->setTarget(target); + set_lang_defaults(Clang); + CompilerInvocation *invocation = + construct_invocation(InputFilename.c_str(), Diags); + if (invocation) + set_invocation(Clang, invocation); + Clang->createFileManager(); + Clang->createSourceManager(Clang->getFileManager()); + HeaderSearchOptions &HSO = Clang->getHeaderSearchOpts(); + LangOptions &LO = Clang->getLangOpts(); + PreprocessorOptions &PO = Clang->getPreprocessorOpts(); + HSO.ResourceDir = ResourceDir; + + for (llvm::cl::list::size_type i = 0; i < Includes.size(); ++i) + add_path(HSO, Includes[i]); + + PO.addMacroDef("__isl_give=__attribute__((annotate(\"isl_give\")))"); + PO.addMacroDef("__isl_keep=__attribute__((annotate(\"isl_keep\")))"); + PO.addMacroDef("__isl_take=__attribute__((annotate(\"isl_take\")))"); + PO.addMacroDef("__isl_export=__attribute__((annotate(\"isl_export\")))"); + PO.addMacroDef("__isl_overload=" + "__attribute__((annotate(\"isl_overload\"))) " + "__attribute__((annotate(\"isl_export\")))"); + PO.addMacroDef("__isl_constructor=__attribute__((annotate(\"isl_constructor\"))) __attribute__((annotate(\"isl_export\")))"); + PO.addMacroDef("__isl_subclass(super)=__attribute__((annotate(\"isl_subclass(\" #super \")\"))) __attribute__((annotate(\"isl_export\")))"); + + create_preprocessor(Clang); + Preprocessor &PP = Clang->getPreprocessor(); + + PP.getBuiltinInfo().initializeBuiltins(PP.getIdentifierTable(), LO); + + const FileEntry *file = getFile(Clang, InputFilename); + assert(file); + create_main_file_id(Clang->getSourceManager(), file); + + Clang->createASTContext(); + MyASTConsumer consumer; + Sema *sema = new Sema(PP, Clang->getASTContext(), consumer); + + Diags.getClient()->BeginSourceFile(LO, &PP); + ParseAST(*sema); + Diags.getClient()->EndSourceFile(); + + generate(consumer, Clang->getSourceManager()); + + delete sema; + delete Clang; + llvm::llvm_shutdown(); + + if (Diags.hasErrorOccurred()) + return EXIT_FAILURE; + return EXIT_SUCCESS; +} diff --git a/external/mit/isl/dist/interface/extract_interface.h b/external/mit/isl/dist/interface/extract_interface.h new file mode 100644 index 000000000000..b6788f1343df --- /dev/null +++ b/external/mit/isl/dist/interface/extract_interface.h @@ -0,0 +1,3 @@ +#include + +bool has_annotation(clang::Decl *decl, const char *name); diff --git a/external/mit/isl/dist/interface/generator.cc b/external/mit/isl/dist/interface/generator.cc new file mode 100644 index 000000000000..4b9890325ccb --- /dev/null +++ b/external/mit/isl/dist/interface/generator.cc @@ -0,0 +1,889 @@ +/* + * Copyright 2011,2015 Sven Verdoolaege. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY SVEN VERDOOLAEGE ''AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SVEN VERDOOLAEGE OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation + * are those of the authors and should not be interpreted as + * representing official policies, either expressed or implied, of + * Sven Verdoolaege. + */ + +#include +#include +#include +#include + +#include +#include + +#include "isl_config.h" +#include "extract_interface.h" +#include "generator.h" + +const char *isl_class::get_prefix = "get_"; +const char *isl_class::set_callback_prefix = "set_"; + +/* Is the first argument an instance of the class? + */ +bool isl_class::first_arg_matches_class(FunctionDecl *method) const +{ + ParmVarDecl *param; + QualType type; + + if (method->getNumParams() < 1) + return false; + + param = method->getParamDecl(0); + type = param->getOriginalType(); + if (!generator::is_isl_type(type)) + return false; + return generator::extract_type(type) == name; +} + +/* Should "method" be considered to be a static method? + * That is, is the first argument something other than + * an instance of the class? + * + * If this method was copied from a superclass, then check + * whether the method is static with respect to this superclass. + */ +bool isl_class::is_static(FunctionDecl *method) const +{ + if (copied_from.count(method) != 0) + return copied_from.at(method).is_static(method); + return !first_arg_matches_class(method); +} + +/* Should "method" be considered to be a static method? + * That is, is the first argument something other than + * an instance of the class? + */ +bool generator::is_static(const isl_class &clazz, FunctionDecl *method) +{ + return clazz.is_static(method); +} + +/* Does "fd" modify an object of "clazz"? + * That is, is it an object method that takes the object and + * returns (gives) an object of the same type? + */ +bool generator::is_mutator(const isl_class &clazz, FunctionDecl *fd) +{ + ParmVarDecl *param; + QualType type, return_type; + + if (fd->getNumParams() < 1) + return false; + if (is_static(clazz, fd)) + return false; + + if (!gives(fd)) + return false; + param = fd->getParamDecl(0); + if (!takes(param)) + return false; + type = param->getOriginalType(); + return_type = fd->getReturnType(); + return return_type == type; +} + +/* Find the FunctionDecl with name "name", + * returning NULL if there is no such FunctionDecl. + * If "required" is set, then error out if no FunctionDecl can be found. + */ +FunctionDecl *generator::find_by_name(const string &name, bool required) +{ + map::iterator i; + + i = functions_by_name.find(name); + if (i != functions_by_name.end()) + return i->second; + if (required) + die("No " + name + " function found"); + return NULL; +} + +/* List of conversion functions that are used to automatically convert + * the second argument of the conversion function to its function result. + */ +const std::set generator::automatic_conversion_functions = { + "isl_id_read_from_str", + "isl_val_int_from_si", +}; + +/* Extract information about the automatic conversion function "fd", + * storing the results in this->conversions. + * + * A function used for automatic conversion has exactly two arguments, + * an isl_ctx and a non-isl object, and it returns an isl object. + * Store a mapping from the isl object return type + * to the non-isl object source type. + */ +void generator::extract_automatic_conversion(FunctionDecl *fd) +{ + QualType return_type = fd->getReturnType(); + const Type *type = return_type.getTypePtr(); + + if (fd->getNumParams() != 2) + die("Expecting two arguments"); + if (!is_isl_ctx(fd->getParamDecl(0)->getOriginalType())) + die("Expecting isl_ctx first argument"); + if (!is_isl_type(return_type)) + die("Expecting isl object return type"); + conversions[type] = fd->getParamDecl(1); +} + +/* Extract information about all automatic conversion functions + * for the given class, storing the results in this->conversions. + * + * In particular, look through all exported constructors for the class and + * check if any of them is explicitly marked as a conversion function. + */ +void generator::extract_class_automatic_conversions(const isl_class &clazz) +{ + const function_set &constructors = clazz.constructors; + function_set::iterator fi; + + for (fi = constructors.begin(); fi != constructors.end(); ++fi) { + FunctionDecl *fd = *fi; + string name = fd->getName().str(); + if (automatic_conversion_functions.count(name) != 0) + extract_automatic_conversion(fd); + } +} + +/* Extract information about all automatic conversion functions, + * storing the results in this->conversions. + */ +void generator::extract_automatic_conversions() +{ + map::iterator ci; + + for (ci = classes.begin(); ci != classes.end(); ++ci) + extract_class_automatic_conversions(ci->second); +} + +/* Add a subclass derived from "decl" called "sub_name" to the set of classes, + * keeping track of the _to_str, _copy and _free functions, if any, separately. + * "sub_name" is either the name of the class itself or + * the name of a type based subclass. + * If the class is a proper subclass, then "super_name" is the name + * of its immediate superclass. + */ +void generator::add_subclass(RecordDecl *decl, const string &super_name, + const string &sub_name) +{ + string name = decl->getName().str(); + + classes[sub_name].name = name; + classes[sub_name].superclass_name = super_name; + classes[sub_name].subclass_name = sub_name; + classes[sub_name].type = decl; + classes[sub_name].fn_to_str = find_by_name(name + "_to_str", false); + classes[sub_name].fn_copy = find_by_name(name + "_copy", true); + classes[sub_name].fn_free = find_by_name(name + "_free", true); +} + +/* Add a class derived from "decl" to the set of classes, + * keeping track of the _to_str, _copy and _free functions, if any, separately. + */ +void generator::add_class(RecordDecl *decl) +{ + return add_subclass(decl, "", decl->getName().str()); +} + +/* Given a function "fn_type" that returns the subclass type + * of a C object, create subclasses for each of the (non-negative) + * return values. + * + * The function "fn_type" is also stored in the superclass, + * along with all pairs of type values and subclass names. + */ +void generator::add_type_subclasses(FunctionDecl *fn_type) +{ + QualType return_type = fn_type->getReturnType(); + const EnumType *enum_type = return_type->getAs(); + EnumDecl *decl = enum_type->getDecl(); + isl_class *c = method2class(fn_type); + DeclContext::decl_iterator i; + + c->fn_type = fn_type; + for (i = decl->decls_begin(); i != decl->decls_end(); ++i) { + EnumConstantDecl *ecd = dyn_cast(*i); + int val = (int) ecd->getInitVal().getSExtValue(); + string name = ecd->getNameAsString(); + + if (val < 0) + continue; + c->type_subclasses[val] = name; + add_subclass(c->type, c->subclass_name, name); + } +} + +/* Add information about the enum values in "decl", set by "fd", + * to c->set_enums. "prefix" is the prefix of the generated method names. + * In particular, it has the name of the enum type removed. + * + * In particular, for each non-negative enum value, keep track of + * the value, the name and the corresponding method name. + */ +static void add_set_enum(isl_class *c, const string &prefix, EnumDecl *decl, + FunctionDecl *fd) +{ + DeclContext::decl_iterator i; + + for (i = decl->decls_begin(); i != decl->decls_end(); ++i) { + EnumConstantDecl *ecd = dyn_cast(*i); + int val = (int) ecd->getInitVal().getSExtValue(); + string name = ecd->getNameAsString(); + string method_name; + + if (val < 0) + continue; + method_name = prefix + name.substr(4); + c->set_enums[fd].push_back(set_enum(val, name, method_name)); + } +} + +/* Check if "fd" sets an enum value and, if so, add information + * about the enum values to c->set_enums. + * + * A function is considered to set an enum value if: + * - the function returns an object of the same type + * - the last argument is of type enum + * - the name of the function ends with the name of the enum + */ +static bool handled_sets_enum(isl_class *c, FunctionDecl *fd) +{ + unsigned n; + ParmVarDecl *param; + const EnumType *enum_type; + EnumDecl *decl; + string enum_name; + string fd_name; + string prefix; + size_t pos; + + if (!generator::is_mutator(*c, fd)) + return false; + n = fd->getNumParams(); + if (n < 2) + return false; + param = fd->getParamDecl(n - 1); + enum_type = param->getType()->getAs(); + if (!enum_type) + return false; + decl = enum_type->getDecl(); + enum_name = decl->getName().str(); + enum_name = enum_name.substr(4); + fd_name = c->method_name(fd); + pos = fd_name.find(enum_name); + if (pos == std::string::npos) + return false; + prefix = fd_name.substr(0, pos); + + add_set_enum(c, prefix, decl, fd); + + return true; +} + +/* Return the callback argument of a function setting + * a persistent callback. + * This callback is in the second argument (position 1). + */ +ParmVarDecl *generator::persistent_callback_arg(FunctionDecl *fd) +{ + return fd->getParamDecl(1); +} + +/* Does the given function set a persistent callback? + * The following heuristics are used to determine this property: + * - the function returns an object of the same type + * - its name starts with "set_" + * - it has exactly three arguments + * - the second (position 1) of which is a callback + */ +static bool sets_persistent_callback(isl_class *c, FunctionDecl *fd) +{ + ParmVarDecl *param; + + if (!generator::is_mutator(*c, fd)) + return false; + if (fd->getNumParams() != 3) + return false; + param = generator::persistent_callback_arg(fd); + if (!generator::is_callback(param->getType())) + return false; + return prefixcmp(c->method_name(fd).c_str(), + c->set_callback_prefix) == 0; +} + +/* Does this function take any enum arguments? + */ +static bool takes_enums(FunctionDecl *fd) +{ + unsigned n; + + n = fd->getNumParams(); + for (unsigned i = 0; i < n; ++i) { + ParmVarDecl *param = fd->getParamDecl(i); + if (param->getType()->getAs()) + return true; + } + return false; +} + +/* Sorting function that places declaration of functions + * with a shorter name first. + */ +static bool less_name(const FunctionDecl *a, const FunctionDecl *b) +{ + return a->getName().size() < b->getName().size(); +} + +/* Collect all functions that belong to a certain type, separating + * constructors from methods that set an enum value, + * methods that set a persistent callback and + * from regular methods, while keeping track of the _to_str, + * _copy and _free functions, if any, separately. + * Methods that accept any enum arguments that are not specifically handled + * are not supported. + * If there are any overloaded + * functions, then they are grouped based on their name after removing the + * argument type suffix. + * Check for functions that describe subclasses before considering + * any other functions in order to be able to detect those other + * functions as belonging to the subclasses. + * Sort the names of the functions based on their lengths + * to ensure that nested subclasses are handled later. + * + * Also extract information about automatic conversion functions. + */ +generator::generator(SourceManager &SM, set &exported_types, + set exported_functions, set functions) : + SM(SM) +{ + set::iterator in; + set::iterator it; + vector type_subclasses; + vector::iterator iv; + + for (in = functions.begin(); in != functions.end(); ++in) { + FunctionDecl *decl = *in; + functions_by_name[decl->getName().str()] = decl; + } + + for (it = exported_types.begin(); it != exported_types.end(); ++it) + add_class(*it); + + for (in = exported_functions.begin(); in != exported_functions.end(); + ++in) { + if (is_subclass(*in)) + type_subclasses.push_back(*in); + } + std::sort(type_subclasses.begin(), type_subclasses.end(), &less_name); + for (iv = type_subclasses.begin(); iv != type_subclasses.end(); ++iv) { + add_type_subclasses(*iv); + } + + for (in = exported_functions.begin(); in != exported_functions.end(); + ++in) { + FunctionDecl *method = *in; + isl_class *c; + + if (is_subclass(method)) + continue; + + c = method2class(method); + if (!c) + continue; + if (is_constructor(method)) { + c->constructors.insert(method); + } else if (handled_sets_enum(c, method)) { + } else if (sets_persistent_callback(c, method)) { + c->persistent_callbacks.insert(method); + } else if (takes_enums(method)) { + std::string name = method->getName().str(); + die(name + " has unhandled enum argument"); + } else { + string name = c->method_name(method); + c->methods[name].insert(method); + } + } + + extract_automatic_conversions(); +} + +/* Print error message "msg" and abort. + */ +void generator::die(const char *msg) +{ + fprintf(stderr, "%s\n", msg); + abort(); +} + +/* Print error message "msg" and abort. + */ +void generator::die(string msg) +{ + die(msg.c_str()); +} + +/* Return a sequence of the types of which the given type declaration is + * marked as being a subtype. + * The order of the types is the opposite of the order in which they + * appear in the source. In particular, the first annotation + * is the one that is closest to the annotated type and the corresponding + * type is then also the first that will appear in the sequence of types. + * This is also the order in which the annotations appear + * in the AttrVec returned by Decl::getAttrs() in older versions of clang. + * In newer versions of clang, the order is that in which + * the attribute appears in the source. + * Use the position of the "isl_export" attribute to determine + * whether this is an old (with reversed order) or a new version. + * The "isl_export" attribute is automatically added + * after each "isl_subclass" attribute. If it appears in the list before + * any "isl_subclass" is encountered, then this must be a reversed list. + */ +std::vector generator::find_superclasses(Decl *decl) +{ + vector super; + bool reversed = false; + + if (!decl->hasAttrs()) + return super; + + string sub = "isl_subclass"; + size_t len = sub.length(); + AttrVec attrs = decl->getAttrs(); + for (AttrVec::const_iterator i = attrs.begin(); i != attrs.end(); ++i) { + const AnnotateAttr *ann = dyn_cast(*i); + if (!ann) + continue; + string s = ann->getAnnotation().str(); + if (s == "isl_export" && super.size() == 0) + reversed = true; + if (s.substr(0, len) == sub) { + s = s.substr(len + 1, s.length() - len - 2); + if (reversed) + super.push_back(s); + else + super.insert(super.begin(), s); + } + } + + return super; +} + +/* Is "decl" marked as describing subclasses? + */ +bool generator::is_subclass(FunctionDecl *decl) +{ + return find_superclasses(decl).size() > 0; +} + +/* Is decl marked as being part of an overloaded method? + */ +bool generator::is_overload(Decl *decl) +{ + return has_annotation(decl, "isl_overload"); +} + +/* Is decl marked as a constructor? + */ +bool generator::is_constructor(Decl *decl) +{ + return has_annotation(decl, "isl_constructor"); +} + +/* Is decl marked as consuming a reference? + */ +bool generator::takes(Decl *decl) +{ + return has_annotation(decl, "isl_take"); +} + +/* Is decl marked as preserving a reference? + */ +bool generator::keeps(Decl *decl) +{ + return has_annotation(decl, "isl_keep"); +} + +/* Is decl marked as returning a reference that is required to be freed. + */ +bool generator::gives(Decl *decl) +{ + return has_annotation(decl, "isl_give"); +} + +/* Return the class that has a name that best matches the initial part + * of the name of function "fd" or NULL if no such class could be found. + */ +isl_class *generator::method2class(FunctionDecl *fd) +{ + string best; + map::iterator ci; + string name = fd->getNameAsString(); + + for (ci = classes.begin(); ci != classes.end(); ++ci) { + size_t len = ci->first.length(); + if (len > best.length() && name.substr(0, len) == ci->first && + name[len] == '_') + best = ci->first; + } + + if (classes.find(best) == classes.end()) { + cerr << "Unable to find class of " << name << endl; + return NULL; + } + + return &classes[best]; +} + +/* Is "type" the type "isl_ctx *"? + */ +bool generator::is_isl_ctx(QualType type) +{ + if (!type->isPointerType()) + return false; + type = type->getPointeeType(); + if (type.getAsString() != "isl_ctx") + return false; + + return true; +} + +/* Is the first argument of "fd" of type "isl_ctx *"? + */ +bool generator::first_arg_is_isl_ctx(FunctionDecl *fd) +{ + ParmVarDecl *param; + + if (fd->getNumParams() < 1) + return false; + + param = fd->getParamDecl(0); + return is_isl_ctx(param->getOriginalType()); +} + +namespace { + +struct ClangAPI { + /* Return the first location in the range returned by + * clang::SourceManager::getImmediateExpansionRange. + * Older versions of clang return a pair of SourceLocation objects. + * More recent versions return a CharSourceRange. + */ + static SourceLocation range_begin( + const std::pair &p) { + return p.first; + } + static SourceLocation range_begin(const CharSourceRange &range) { + return range.getBegin(); + } +}; + +} + +/* Does the callback argument "param" take its argument at position "pos"? + * + * The memory management annotations of arguments to function pointers + * are not recorded by clang, so the information cannot be extracted + * from the type of "param". + * Instead, go to the location in the source where the callback argument + * is declared, look for the right argument of the callback itself and + * then check if it has an "__isl_take" memory management annotation. + * + * If the return value of the function has a memory management annotation, + * then the spelling of "param" will point to the spelling + * of this memory management annotation. Since the macro is defined + * on the command line (in main), this location does not have a file entry. + * In this case, move up one level in the macro expansion to the location + * where the memory management annotation is used. + */ +bool generator::callback_takes_argument(ParmVarDecl *param, + int pos) +{ + SourceLocation loc; + const char *s, *end, *next; + bool takes, keeps; + + loc = param->getSourceRange().getBegin(); + if (!SM.getFileEntryForID(SM.getFileID(SM.getSpellingLoc(loc)))) + loc = ClangAPI::range_begin(SM.getImmediateExpansionRange(loc)); + s = SM.getCharacterData(loc); + if (!s) + die("No character data"); + s = strchr(s, '('); + if (!s) + die("Cannot find function pointer"); + s = strchr(s + 1, '('); + if (!s) + die("Cannot find function pointer arguments"); + end = strchr(s + 1, ')'); + if (!end) + die("Cannot find end of function pointer arguments"); + while (pos-- > 0) { + s = strchr(s + 1, ','); + if (!s || s > end) + die("Cannot find function pointer argument"); + } + next = strchr(s + 1, ','); + if (next && next < end) + end = next; + s = strchr(s + 1, '_'); + if (!s || s > end) + die("Cannot find function pointer argument annotation"); + takes = prefixcmp(s, "__isl_take") == 0; + keeps = prefixcmp(s, "__isl_keep") == 0; + if (!takes && !keeps) + die("Cannot find function pointer argument annotation"); + + return takes; +} + +/* Is "type" that of a pointer to an isl_* structure? + */ +bool generator::is_isl_type(QualType type) +{ + if (type->isPointerType()) { + string s; + + type = type->getPointeeType(); + if (type->isFunctionType()) + return false; + s = type.getAsString(); + return s.substr(0, 4) == "isl_"; + } + + return false; +} + +/* Is "type" one of the integral types with a negative value + * indicating an error condition? + */ +bool generator::is_isl_neg_error(QualType type) +{ + return is_isl_bool(type) || is_isl_stat(type) || is_isl_size(type); +} + +/* Is "type" the primitive type with the given name? + */ +static bool is_isl_primitive(QualType type, const char *name) +{ + string s; + + if (type->isPointerType()) + return false; + + s = type.getAsString(); + return s == name; +} + +/* Is "type" the type isl_bool? + */ +bool generator::is_isl_bool(QualType type) +{ + return is_isl_primitive(type, "isl_bool"); +} + +/* Is "type" the type isl_stat? + */ +bool generator::is_isl_stat(QualType type) +{ + return is_isl_primitive(type, "isl_stat"); +} + +/* Is "type" the type isl_size? + */ +bool generator::is_isl_size(QualType type) +{ + return is_isl_primitive(type, "isl_size"); +} + +/* Is "type" that of a pointer to a function? + */ +bool generator::is_callback(QualType type) +{ + if (!type->isPointerType()) + return false; + type = type->getPointeeType(); + return type->isFunctionType(); +} + +/* Is the parameter at position "i" of "fd" a pointer to a function? + */ +bool generator::is_callback_arg(FunctionDecl *fd, int i) +{ + ParmVarDecl *param = fd->getParamDecl(i); + QualType type = param->getOriginalType(); + + return is_callback(type); +} + +/* Is "type" that of "char *" of "const char *"? + */ +bool generator::is_string(QualType type) +{ + if (type->isPointerType()) { + string s = type->getPointeeType().getAsString(); + return s == "const char" || s == "char"; + } + + return false; +} + +/* Is "type" that of "long"? + */ +bool generator::is_long(QualType type) +{ + const BuiltinType *builtin = type->getAs(); + return builtin && builtin->getKind() == BuiltinType::Long; +} + +/* Is "type" that of "unsigned int"? + */ +static bool is_unsigned_int(QualType type) +{ + const BuiltinType *builtin = type->getAs(); + return builtin && builtin->getKind() == BuiltinType::UInt; +} + +/* Return the name of the type that "type" points to. + * The input "type" is assumed to be a pointer type. + */ +string generator::extract_type(QualType type) +{ + if (type->isPointerType()) + return type->getPointeeType().getAsString(); + die("Cannot extract type from non-pointer type"); +} + +/* Given the type of a function pointer, return the corresponding + * function prototype. + */ +const FunctionProtoType *generator::extract_prototype(QualType type) +{ + return type->getPointeeType()->getAs(); +} + +/* Given the type of a function pointer, return the number of arguments + * of the corresponding function prototype. + */ +int generator::prototype_n_args(QualType type) +{ + return extract_prototype(type)->getNumArgs(); +} + +/* Return the function name suffix for the type of "param". + * + * If the type of "param" is an isl object type, + * then the suffix is the name of the type with the "isl" prefix removed, + * but keeping the "_". + * If the type is an unsigned integer, then the type suffix is "_ui". + */ +static std::string type_suffix(ParmVarDecl *param) +{ + QualType type; + + type = param->getOriginalType(); + if (generator::is_isl_type(type)) + return generator::extract_type(type).substr(3); + else if (is_unsigned_int(type)) + return "_ui"; + generator::die("Unsupported type suffix"); +} + +/* If "suffix" is a suffix of "s", then return "s" with the suffix removed. + * Otherwise, simply return "s". + */ +std::string generator::drop_suffix(const std::string &s, + const std::string &suffix) +{ + size_t len, suffix_len; + + len = s.length(); + suffix_len = suffix.length(); + + if (len >= suffix_len && s.substr(len - suffix_len) == suffix) + return s.substr(0, len - suffix_len); + else + return s; +} + +/* If "method" is overloaded, then return its name with the suffixes + * corresponding to the types of the final arguments removed. + * Otherwise, simply return the name of the function. + * Start from the final argument and keep removing suffixes + * matching arguments, independently of whether previously considered + * arguments matched. + */ +string isl_class::name_without_type_suffixes(FunctionDecl *method) +{ + int num_params; + string name; + + name = method->getName().str(); + if (!generator::is_overload(method)) + return name; + + num_params = method->getNumParams(); + for (int i = num_params - 1; i >= 0; --i) { + ParmVarDecl *param; + string type; + + param = method->getParamDecl(i); + type = type_suffix(param); + + name = generator::drop_suffix(name, type); + } + + return name; +} + +/* Is function "fd" with the given name a "get" method? + * + * A "get" method is an instance method + * with a name that starts with the get method prefix. + */ +bool isl_class::is_get_method_name(FunctionDecl *fd, const string &name) const +{ + return !is_static(fd) && prefixcmp(name.c_str(), get_prefix) == 0; +} + +/* Extract the method name corresponding to "fd". + * + * If "fd" is a "get" method, then drop the "get" method prefix. + */ +string isl_class::method_name(FunctionDecl *fd) const +{ + string base = base_method_name(fd); + + if (is_get_method_name(fd, base)) + return base.substr(strlen(get_prefix)); + return base; +} diff --git a/external/mit/isl/dist/interface/generator.h b/external/mit/isl/dist/interface/generator.h new file mode 100644 index 000000000000..90eae8266a73 --- /dev/null +++ b/external/mit/isl/dist/interface/generator.h @@ -0,0 +1,203 @@ +#ifndef ISL_INTERFACE_GENERATOR_H +#define ISL_INTERFACE_GENERATOR_H + +#include +#include +#include +#include + +#include + +using namespace std; +using namespace clang; + +/* Compare the prefix of "s" to "prefix" up to the length of "prefix". + */ +inline int prefixcmp(const char *s, const char *prefix) +{ + return strncmp(s, prefix, strlen(prefix)); +} + +/* Information about a single enum value of an enum set by a function. + * "value" is the enum value. + * "name" is the corresponding name. + * "method_name" is the the name of the method that sets this value. + */ +struct set_enum { + int value; + string name; + string method_name; + set_enum(int value, string name, string method_name) : + value(value), name(name), method_name(method_name) {} +}; + +/* Helper structure for sorting FunctionDecl pointers + * on the corresponding function names. + */ +struct function_name_less { + bool operator()(FunctionDecl *x, FunctionDecl *y) const { + return x->getName() < y->getName(); + } +}; + +/* Set of FunctionDecl pointers sorted on function name. + */ +typedef std::set function_set; + +/* isl_class collects all constructors and methods for an isl "class". + * "name" is the name of the class. + * If this object describes a subclass of a C type, then + * "subclass_name" is the name of that subclass and "superclass_name" + * is the name of the immediate superclass of that subclass. Otherwise, + * "subclass_name" is equal to "name" and "superclass_name" is undefined. + * "type" is the declaration that introduces the type. + * "persistent_callbacks" contains the set of functions that + * set a persistent callback. + * "set_enums" maps the set of functions that set an enum value + * to information associated to each value. + * A function is considered to set an enum value if it returns + * an object of the same type and if its last argument is of an enum type. + * "methods" contains the set of methods, grouped by method name. + * "fn_to_str" is a reference to the *_to_str method of this class, if any. + * "fn_copy" is a reference to the *_copy method of this class, if any. + * "fn_free" is a reference to the *_free method of this class, if any. + * "fn_type" is a reference to a function that described subclasses, if any. + * If "fn_type" is set, then "type_subclasses" maps the values returned + * by that function to the names of the corresponding subclasses. + * + * The following fields are only used for the C++ bindings. + * For methods that are not derived from a function that applies + * directly to this class, but are rather copied from some ancestor, + * "copied_from" records the direct superclass from which the method + * was copied (where it may have been copied from a further ancestor) and + * "copy_depth" records the distance to the ancestor to which + * the function applies. + * "construction_types" contains the set of isl classes that can be + * implicitly converted to this class through a unary constructor, + * mapped to the single argument + * of this unary constructor. + */ +struct isl_class { + string name; + string superclass_name; + string subclass_name; + RecordDecl *type; + function_set constructors; + set persistent_callbacks; + map > set_enums; + map methods; + map type_subclasses; + FunctionDecl *fn_type; + FunctionDecl *fn_to_str; + FunctionDecl *fn_copy; + FunctionDecl *fn_free; + + std::map copied_from; + std::map copy_depth; + std::map construction_types; + + /* Is the first argument an instance of the class? */ + bool first_arg_matches_class(FunctionDecl *method) const; + /* Does "method" correspond to a static method? */ + bool is_static(FunctionDecl *method) const; + /* Is this class a subclass based on a type function? */ + bool is_type_subclass() const { return name != subclass_name; } + /* Return name of "fd" without type suffixes, if any. */ + static string name_without_type_suffixes(FunctionDecl *fd); + /* Extract the method name corresponding to "fd" + * (including "get" method prefix if any). + */ + string base_method_name(FunctionDecl *fd) const { + string m_name = name_without_type_suffixes(fd); + return m_name.substr(subclass_name.length() + 1); + } + /* The prefix of a "get" method. */ + static const char *get_prefix; + /* Is function "fd" with the given name a "get" method? */ + bool is_get_method_name(FunctionDecl *fd, const string &name) const; + /* Is function "fd" a "get" method? */ + bool is_get_method(FunctionDecl *fd) const { + return is_get_method_name(fd, base_method_name(fd)); + } + /* Extract the method name corresponding to "fd". */ + string method_name(FunctionDecl *fd) const; + /* The prefix of any method that may set a (persistent) callback. */ + static const char *set_callback_prefix; + /* Given a function that sets a persistent callback, + * return the name of the callback. + */ + string persistent_callback_name(FunctionDecl *fd) const { + return method_name(fd).substr(strlen(set_callback_prefix)); + } + /* Does this class have any functions that set a persistent callback? + */ + bool has_persistent_callbacks() const { + return persistent_callbacks.size() != 0; + } +}; + +/* Base class for interface generators. + * + * "conversions" maps the target type of automatic conversion + * to the second input argument of the conversion function. + */ +class generator { +protected: + SourceManager &SM; + map classes; + map functions_by_name; + +public: + generator(SourceManager &SM, set &exported_types, + set exported_functions, + set functions); + + virtual void generate() = 0; + virtual ~generator() {}; + +protected: + void add_subclass(RecordDecl *decl, const string &name, + const string &sub_name); + void add_class(RecordDecl *decl); + void add_type_subclasses(FunctionDecl *method); + isl_class *method2class(FunctionDecl *fd); + bool callback_takes_argument(ParmVarDecl *param, int pos); + FunctionDecl *find_by_name(const string &name, bool required); + std::map conversions; +private: + static const std::set automatic_conversion_functions; + void extract_automatic_conversion(FunctionDecl *fd); + void extract_class_automatic_conversions(const isl_class &clazz); + void extract_automatic_conversions(); +public: + static std::string drop_suffix(const std::string &s, + const std::string &suffix); + static void die(const char *msg) __attribute__((noreturn)); + static void die(string msg) __attribute__((noreturn)); + static vector find_superclasses(Decl *decl); + static bool is_subclass(FunctionDecl *decl); + static bool is_overload(Decl *decl); + static bool is_constructor(Decl *decl); + static bool takes(Decl *decl); + static bool keeps(Decl *decl); + static bool gives(Decl *decl); + static bool is_isl_ctx(QualType type); + static bool first_arg_is_isl_ctx(FunctionDecl *fd); + static bool is_isl_type(QualType type); + static bool is_isl_neg_error(QualType type); + static bool is_isl_bool(QualType type); + static bool is_isl_stat(QualType type); + static bool is_isl_size(QualType type); + static bool is_long(QualType type); + static bool is_callback(QualType type); + static bool is_callback_arg(FunctionDecl *fd, int i); + static bool is_string(QualType type); + static bool is_static(const isl_class &clazz, FunctionDecl *method); + static bool is_mutator(const isl_class &clazz, FunctionDecl *fd); + static string extract_type(QualType type); + static const FunctionProtoType *extract_prototype(QualType type); + static int prototype_n_args(QualType type); + static ParmVarDecl *persistent_callback_arg(FunctionDecl *fd); +}; + +#endif /* ISL_INTERFACE_GENERATOR_H */ diff --git a/external/mit/isl/dist/interface/install-sh b/external/mit/isl/dist/interface/install-sh new file mode 100755 index 000000000000..ec298b537402 --- /dev/null +++ b/external/mit/isl/dist/interface/install-sh @@ -0,0 +1,541 @@ +#!/bin/sh +# install - install a program, script, or datafile + +scriptversion=2020-11-14.01; # UTC + +# This originates from X11R5 (mit/util/scripts/install.sh), which was +# later released in X11R6 (xc/config/util/install.sh) with the +# following copyright and license. +# +# Copyright (C) 1994 X Consortium +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- +# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# Except as contained in this notice, the name of the X Consortium shall not +# be used in advertising or otherwise to promote the sale, use or other deal- +# ings in this Software without prior written authorization from the X Consor- +# tium. +# +# +# FSF changes to this file are in the public domain. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# 'make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. + +tab=' ' +nl=' +' +IFS=" $tab$nl" + +# Set DOITPROG to "echo" to test this script. + +doit=${DOITPROG-} +doit_exec=${doit:-exec} + +# Put in absolute file names if you don't have them in your path; +# or use environment vars. + +chgrpprog=${CHGRPPROG-chgrp} +chmodprog=${CHMODPROG-chmod} +chownprog=${CHOWNPROG-chown} +cmpprog=${CMPPROG-cmp} +cpprog=${CPPROG-cp} +mkdirprog=${MKDIRPROG-mkdir} +mvprog=${MVPROG-mv} +rmprog=${RMPROG-rm} +stripprog=${STRIPPROG-strip} + +posix_mkdir= + +# Desired mode of installed file. +mode=0755 + +# Create dirs (including intermediate dirs) using mode 755. +# This is like GNU 'install' as of coreutils 8.32 (2020). +mkdir_umask=22 + +backupsuffix= +chgrpcmd= +chmodcmd=$chmodprog +chowncmd= +mvcmd=$mvprog +rmcmd="$rmprog -f" +stripcmd= + +src= +dst= +dir_arg= +dst_arg= + +copy_on_change=false +is_target_a_directory=possibly + +usage="\ +Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE + or: $0 [OPTION]... SRCFILES... DIRECTORY + or: $0 [OPTION]... -t DIRECTORY SRCFILES... + or: $0 [OPTION]... -d DIRECTORIES... + +In the 1st form, copy SRCFILE to DSTFILE. +In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. +In the 4th, create DIRECTORIES. + +Options: + --help display this help and exit. + --version display version info and exit. + + -c (ignored) + -C install only if different (preserve data modification time) + -d create directories instead of installing files. + -g GROUP $chgrpprog installed files to GROUP. + -m MODE $chmodprog installed files to MODE. + -o USER $chownprog installed files to USER. + -p pass -p to $cpprog. + -s $stripprog installed files. + -S SUFFIX attempt to back up existing files, with suffix SUFFIX. + -t DIRECTORY install into DIRECTORY. + -T report an error if DSTFILE is a directory. + +Environment variables override the default commands: + CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG + RMPROG STRIPPROG + +By default, rm is invoked with -f; when overridden with RMPROG, +it's up to you to specify -f if you want it. + +If -S is not specified, no backups are attempted. + +Email bug reports to bug-automake@gnu.org. +Automake home page: https://www.gnu.org/software/automake/ +" + +while test $# -ne 0; do + case $1 in + -c) ;; + + -C) copy_on_change=true;; + + -d) dir_arg=true;; + + -g) chgrpcmd="$chgrpprog $2" + shift;; + + --help) echo "$usage"; exit $?;; + + -m) mode=$2 + case $mode in + *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) + echo "$0: invalid mode: $mode" >&2 + exit 1;; + esac + shift;; + + -o) chowncmd="$chownprog $2" + shift;; + + -p) cpprog="$cpprog -p";; + + -s) stripcmd=$stripprog;; + + -S) backupsuffix="$2" + shift;; + + -t) + is_target_a_directory=always + dst_arg=$2 + # Protect names problematic for 'test' and other utilities. + case $dst_arg in + -* | [=\(\)!]) dst_arg=./$dst_arg;; + esac + shift;; + + -T) is_target_a_directory=never;; + + --version) echo "$0 $scriptversion"; exit $?;; + + --) shift + break;; + + -*) echo "$0: invalid option: $1" >&2 + exit 1;; + + *) break;; + esac + shift +done + +# We allow the use of options -d and -T together, by making -d +# take the precedence; this is for compatibility with GNU install. + +if test -n "$dir_arg"; then + if test -n "$dst_arg"; then + echo "$0: target directory not allowed when installing a directory." >&2 + exit 1 + fi +fi + +if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then + # When -d is used, all remaining arguments are directories to create. + # When -t is used, the destination is already specified. + # Otherwise, the last argument is the destination. Remove it from $@. + for arg + do + if test -n "$dst_arg"; then + # $@ is not empty: it contains at least $arg. + set fnord "$@" "$dst_arg" + shift # fnord + fi + shift # arg + dst_arg=$arg + # Protect names problematic for 'test' and other utilities. + case $dst_arg in + -* | [=\(\)!]) dst_arg=./$dst_arg;; + esac + done +fi + +if test $# -eq 0; then + if test -z "$dir_arg"; then + echo "$0: no input file specified." >&2 + exit 1 + fi + # It's OK to call 'install-sh -d' without argument. + # This can happen when creating conditional directories. + exit 0 +fi + +if test -z "$dir_arg"; then + if test $# -gt 1 || test "$is_target_a_directory" = always; then + if test ! -d "$dst_arg"; then + echo "$0: $dst_arg: Is not a directory." >&2 + exit 1 + fi + fi +fi + +if test -z "$dir_arg"; then + do_exit='(exit $ret); exit $ret' + trap "ret=129; $do_exit" 1 + trap "ret=130; $do_exit" 2 + trap "ret=141; $do_exit" 13 + trap "ret=143; $do_exit" 15 + + # Set umask so as not to create temps with too-generous modes. + # However, 'strip' requires both read and write access to temps. + case $mode in + # Optimize common cases. + *644) cp_umask=133;; + *755) cp_umask=22;; + + *[0-7]) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw='% 200' + fi + cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; + *) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw=,u+rw + fi + cp_umask=$mode$u_plus_rw;; + esac +fi + +for src +do + # Protect names problematic for 'test' and other utilities. + case $src in + -* | [=\(\)!]) src=./$src;; + esac + + if test -n "$dir_arg"; then + dst=$src + dstdir=$dst + test -d "$dstdir" + dstdir_status=$? + # Don't chown directories that already exist. + if test $dstdir_status = 0; then + chowncmd="" + fi + else + + # Waiting for this to be detected by the "$cpprog $src $dsttmp" command + # might cause directories to be created, which would be especially bad + # if $src (and thus $dsttmp) contains '*'. + if test ! -f "$src" && test ! -d "$src"; then + echo "$0: $src does not exist." >&2 + exit 1 + fi + + if test -z "$dst_arg"; then + echo "$0: no destination specified." >&2 + exit 1 + fi + dst=$dst_arg + + # If destination is a directory, append the input filename. + if test -d "$dst"; then + if test "$is_target_a_directory" = never; then + echo "$0: $dst_arg: Is a directory" >&2 + exit 1 + fi + dstdir=$dst + dstbase=`basename "$src"` + case $dst in + */) dst=$dst$dstbase;; + *) dst=$dst/$dstbase;; + esac + dstdir_status=0 + else + dstdir=`dirname "$dst"` + test -d "$dstdir" + dstdir_status=$? + fi + fi + + case $dstdir in + */) dstdirslash=$dstdir;; + *) dstdirslash=$dstdir/;; + esac + + obsolete_mkdir_used=false + + if test $dstdir_status != 0; then + case $posix_mkdir in + '') + # With -d, create the new directory with the user-specified mode. + # Otherwise, rely on $mkdir_umask. + if test -n "$dir_arg"; then + mkdir_mode=-m$mode + else + mkdir_mode= + fi + + posix_mkdir=false + # The $RANDOM variable is not portable (e.g., dash). Use it + # here however when possible just to lower collision chance. + tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ + + trap ' + ret=$? + rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null + exit $ret + ' 0 + + # Because "mkdir -p" follows existing symlinks and we likely work + # directly in world-writeable /tmp, make sure that the '$tmpdir' + # directory is successfully created first before we actually test + # 'mkdir -p'. + if (umask $mkdir_umask && + $mkdirprog $mkdir_mode "$tmpdir" && + exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1 + then + if test -z "$dir_arg" || { + # Check for POSIX incompatibilities with -m. + # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or + # other-writable bit of parent directory when it shouldn't. + # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. + test_tmpdir="$tmpdir/a" + ls_ld_tmpdir=`ls -ld "$test_tmpdir"` + case $ls_ld_tmpdir in + d????-?r-*) different_mode=700;; + d????-?--*) different_mode=755;; + *) false;; + esac && + $mkdirprog -m$different_mode -p -- "$test_tmpdir" && { + ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"` + test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" + } + } + then posix_mkdir=: + fi + rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" + else + # Remove any dirs left behind by ancient mkdir implementations. + rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null + fi + trap '' 0;; + esac + + if + $posix_mkdir && ( + umask $mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" + ) + then : + else + + # mkdir does not conform to POSIX, + # or it failed possibly due to a race condition. Create the + # directory the slow way, step by step, checking for races as we go. + + case $dstdir in + /*) prefix='/';; + [-=\(\)!]*) prefix='./';; + *) prefix='';; + esac + + oIFS=$IFS + IFS=/ + set -f + set fnord $dstdir + shift + set +f + IFS=$oIFS + + prefixes= + + for d + do + test X"$d" = X && continue + + prefix=$prefix$d + if test -d "$prefix"; then + prefixes= + else + if $posix_mkdir; then + (umask $mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break + # Don't fail if two instances are running concurrently. + test -d "$prefix" || exit 1 + else + case $prefix in + *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; + *) qprefix=$prefix;; + esac + prefixes="$prefixes '$qprefix'" + fi + fi + prefix=$prefix/ + done + + if test -n "$prefixes"; then + # Don't fail if two instances are running concurrently. + (umask $mkdir_umask && + eval "\$doit_exec \$mkdirprog $prefixes") || + test -d "$dstdir" || exit 1 + obsolete_mkdir_used=true + fi + fi + fi + + if test -n "$dir_arg"; then + { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && + { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || + test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 + else + + # Make a couple of temp file names in the proper directory. + dsttmp=${dstdirslash}_inst.$$_ + rmtmp=${dstdirslash}_rm.$$_ + + # Trap to clean up those temp files at exit. + trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 + + # Copy the file name to the temp name. + (umask $cp_umask && + { test -z "$stripcmd" || { + # Create $dsttmp read-write so that cp doesn't create it read-only, + # which would cause strip to fail. + if test -z "$doit"; then + : >"$dsttmp" # No need to fork-exec 'touch'. + else + $doit touch "$dsttmp" + fi + } + } && + $doit_exec $cpprog "$src" "$dsttmp") && + + # and set any options; do chmod last to preserve setuid bits. + # + # If any of these fail, we abort the whole thing. If we want to + # ignore errors from any of these, just make sure not to ignore + # errors from the above "$doit $cpprog $src $dsttmp" command. + # + { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && + { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && + { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && + + # If -C, don't bother to copy if it wouldn't change the file. + if $copy_on_change && + old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && + new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && + set -f && + set X $old && old=:$2:$4:$5:$6 && + set X $new && new=:$2:$4:$5:$6 && + set +f && + test "$old" = "$new" && + $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 + then + rm -f "$dsttmp" + else + # If $backupsuffix is set, and the file being installed + # already exists, attempt a backup. Don't worry if it fails, + # e.g., if mv doesn't support -f. + if test -n "$backupsuffix" && test -f "$dst"; then + $doit $mvcmd -f "$dst" "$dst$backupsuffix" 2>/dev/null + fi + + # Rename the file to the real destination. + $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || + + # The rename failed, perhaps because mv can't rename something else + # to itself, or perhaps because mv is so ancient that it does not + # support -f. + { + # Now remove or move aside any old file at destination location. + # We try this two ways since rm can't unlink itself on some + # systems and the destination file might be busy for other + # reasons. In this case, the final cleanup might fail but the new + # file should still install successfully. + { + test ! -f "$dst" || + $doit $rmcmd "$dst" 2>/dev/null || + { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && + { $doit $rmcmd "$rmtmp" 2>/dev/null; :; } + } || + { echo "$0: cannot unlink or rename $dst" >&2 + (exit 1); exit 1 + } + } && + + # Now rename the file to the real destination. + $doit $mvcmd "$dsttmp" "$dst" + } + fi || exit 1 + + trap '' 0 + fi +done + +# Local variables: +# eval: (add-hook 'before-save-hook 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC0" +# time-stamp-end: "; # UTC" +# End: diff --git a/external/mit/isl/dist/interface/isl.py b/external/mit/isl/dist/interface/isl.py new file mode 100644 index 000000000000..0c3397f7c95e --- /dev/null +++ b/external/mit/isl/dist/interface/isl.py @@ -0,0 +1,19130 @@ +isl_dlname='libisl.so.23' +import os +from ctypes import * +from ctypes.util import find_library + +isl_dyld_library_path = os.environ.get('ISL_DYLD_LIBRARY_PATH') +if isl_dyld_library_path != None: + os.environ['DYLD_LIBRARY_PATH'] = isl_dyld_library_path +try: + isl = cdll.LoadLibrary(isl_dlname) +except: + isl = cdll.LoadLibrary(find_library("isl")) +libc = cdll.LoadLibrary(find_library("c")) + +class Error(Exception): + pass + +class Context: + defaultInstance = None + + def __init__(self): + ptr = isl.isl_ctx_alloc() + self.ptr = ptr + + def __del__(self): + isl.isl_ctx_free(self) + + def from_param(self): + return c_void_p(self.ptr) + + @staticmethod + def getDefaultInstance(): + if Context.defaultInstance == None: + Context.defaultInstance = Context() + return Context.defaultInstance + + @CFUNCTYPE(None, py_object) + def free_user(user): + pythonapi.Py_DecRef(py_object(user)) + +isl.isl_ctx_alloc.restype = c_void_p +isl.isl_ctx_free.argtypes = [Context] +isl.isl_id_alloc.restype = c_void_p +isl.isl_id_alloc.argtypes = [Context, c_char_p, py_object] +isl.isl_id_set_free_user.restype = c_void_p +isl.isl_id_set_free_user.argtypes = [c_void_p, c_void_p] +isl.isl_id_get_free_user.restype = c_void_p +isl.isl_id_get_free_user.argtypes = [c_void_p] +isl.isl_id_get_user.restype = py_object +isl.isl_id_get_user.argtypes = [c_void_p] + +class union_pw_multi_aff(object): + def __init__(self, *args, **keywords): + if "ptr" in keywords: + self.ctx = keywords["ctx"] + self.ptr = keywords["ptr"] + return + if len(args) == 1 and args[0].__class__ is multi_aff: + self.ctx = Context.getDefaultInstance() + self.ptr = isl.isl_union_pw_multi_aff_from_multi_aff(isl.isl_multi_aff_copy(args[0].ptr)) + return + if len(args) == 1 and args[0].__class__ is pw_multi_aff: + self.ctx = Context.getDefaultInstance() + self.ptr = isl.isl_union_pw_multi_aff_from_pw_multi_aff(isl.isl_pw_multi_aff_copy(args[0].ptr)) + return + if len(args) == 1 and args[0].__class__ is union_pw_aff: + self.ctx = Context.getDefaultInstance() + self.ptr = isl.isl_union_pw_multi_aff_from_union_pw_aff(isl.isl_union_pw_aff_copy(args[0].ptr)) + return + if len(args) == 1 and type(args[0]) == str: + self.ctx = Context.getDefaultInstance() + self.ptr = isl.isl_union_pw_multi_aff_read_from_str(self.ctx, args[0].encode('ascii')) + return + raise Error + def __del__(self): + if hasattr(self, 'ptr'): + isl.isl_union_pw_multi_aff_free(self.ptr) + def __str__(arg0): + try: + if not arg0.__class__ is union_pw_multi_aff: + arg0 = union_pw_multi_aff(arg0) + except: + raise + ptr = isl.isl_union_pw_multi_aff_to_str(arg0.ptr) + res = cast(ptr, c_char_p).value.decode('ascii') + libc.free(ptr) + return res + def __repr__(self): + s = str(self) + if '"' in s: + return 'isl.union_pw_multi_aff("""%s""")' % s + else: + return 'isl.union_pw_multi_aff("%s")' % s + def add(arg0, arg1): + try: + if not arg0.__class__ is union_pw_multi_aff: + arg0 = union_pw_multi_aff(arg0) + except: + raise + try: + if not arg1.__class__ is union_pw_multi_aff: + arg1 = union_pw_multi_aff(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_pw_multi_aff_add(isl.isl_union_pw_multi_aff_copy(arg0.ptr), isl.isl_union_pw_multi_aff_copy(arg1.ptr)) + obj = union_pw_multi_aff(ctx=ctx, ptr=res) + return obj + def apply(*args): + if len(args) == 2 and args[1].__class__ is union_pw_multi_aff: + args = list(args) + try: + if not args[0].__class__ is union_pw_multi_aff: + args[0] = union_pw_multi_aff(args[0]) + except: + raise + ctx = args[0].ctx + res = isl.isl_union_pw_multi_aff_apply_union_pw_multi_aff(isl.isl_union_pw_multi_aff_copy(args[0].ptr), isl.isl_union_pw_multi_aff_copy(args[1].ptr)) + obj = union_pw_multi_aff(ctx=ctx, ptr=res) + return obj + raise Error + def as_multi_union_pw_aff(arg0): + try: + if not arg0.__class__ is union_pw_multi_aff: + arg0 = union_pw_multi_aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_pw_multi_aff_as_multi_union_pw_aff(isl.isl_union_pw_multi_aff_copy(arg0.ptr)) + obj = multi_union_pw_aff(ctx=ctx, ptr=res) + return obj + def as_pw_multi_aff(arg0): + try: + if not arg0.__class__ is union_pw_multi_aff: + arg0 = union_pw_multi_aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_pw_multi_aff_as_pw_multi_aff(isl.isl_union_pw_multi_aff_copy(arg0.ptr)) + obj = pw_multi_aff(ctx=ctx, ptr=res) + return obj + def as_union_map(arg0): + try: + if not arg0.__class__ is union_pw_multi_aff: + arg0 = union_pw_multi_aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_pw_multi_aff_as_union_map(isl.isl_union_pw_multi_aff_copy(arg0.ptr)) + obj = union_map(ctx=ctx, ptr=res) + return obj + def coalesce(arg0): + try: + if not arg0.__class__ is union_pw_multi_aff: + arg0 = union_pw_multi_aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_pw_multi_aff_coalesce(isl.isl_union_pw_multi_aff_copy(arg0.ptr)) + obj = union_pw_multi_aff(ctx=ctx, ptr=res) + return obj + def domain(arg0): + try: + if not arg0.__class__ is union_pw_multi_aff: + arg0 = union_pw_multi_aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_pw_multi_aff_domain(isl.isl_union_pw_multi_aff_copy(arg0.ptr)) + obj = union_set(ctx=ctx, ptr=res) + return obj + def drop_unused_params(arg0): + try: + if not arg0.__class__ is union_pw_multi_aff: + arg0 = union_pw_multi_aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_pw_multi_aff_drop_unused_params(isl.isl_union_pw_multi_aff_copy(arg0.ptr)) + obj = union_pw_multi_aff(ctx=ctx, ptr=res) + return obj + @staticmethod + def empty(*args): + if len(args) == 0: + ctx = Context.getDefaultInstance() + res = isl.isl_union_pw_multi_aff_empty_ctx(ctx) + obj = union_pw_multi_aff(ctx=ctx, ptr=res) + return obj + raise Error + def extract_pw_multi_aff(arg0, arg1): + try: + if not arg0.__class__ is union_pw_multi_aff: + arg0 = union_pw_multi_aff(arg0) + except: + raise + try: + if not arg1.__class__ is space: + arg1 = space(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_pw_multi_aff_extract_pw_multi_aff(arg0.ptr, isl.isl_space_copy(arg1.ptr)) + obj = pw_multi_aff(ctx=ctx, ptr=res) + return obj + def flat_range_product(arg0, arg1): + try: + if not arg0.__class__ is union_pw_multi_aff: + arg0 = union_pw_multi_aff(arg0) + except: + raise + try: + if not arg1.__class__ is union_pw_multi_aff: + arg1 = union_pw_multi_aff(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_pw_multi_aff_flat_range_product(isl.isl_union_pw_multi_aff_copy(arg0.ptr), isl.isl_union_pw_multi_aff_copy(arg1.ptr)) + obj = union_pw_multi_aff(ctx=ctx, ptr=res) + return obj + def gist(arg0, arg1): + try: + if not arg0.__class__ is union_pw_multi_aff: + arg0 = union_pw_multi_aff(arg0) + except: + raise + try: + if not arg1.__class__ is union_set: + arg1 = union_set(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_pw_multi_aff_gist(isl.isl_union_pw_multi_aff_copy(arg0.ptr), isl.isl_union_set_copy(arg1.ptr)) + obj = union_pw_multi_aff(ctx=ctx, ptr=res) + return obj + def intersect_domain(*args): + if len(args) == 2 and args[1].__class__ is space: + args = list(args) + try: + if not args[0].__class__ is union_pw_multi_aff: + args[0] = union_pw_multi_aff(args[0]) + except: + raise + ctx = args[0].ctx + res = isl.isl_union_pw_multi_aff_intersect_domain_space(isl.isl_union_pw_multi_aff_copy(args[0].ptr), isl.isl_space_copy(args[1].ptr)) + obj = union_pw_multi_aff(ctx=ctx, ptr=res) + return obj + if len(args) == 2 and args[1].__class__ is union_set: + args = list(args) + try: + if not args[0].__class__ is union_pw_multi_aff: + args[0] = union_pw_multi_aff(args[0]) + except: + raise + ctx = args[0].ctx + res = isl.isl_union_pw_multi_aff_intersect_domain_union_set(isl.isl_union_pw_multi_aff_copy(args[0].ptr), isl.isl_union_set_copy(args[1].ptr)) + obj = union_pw_multi_aff(ctx=ctx, ptr=res) + return obj + raise Error + def intersect_domain_wrapped_domain(arg0, arg1): + try: + if not arg0.__class__ is union_pw_multi_aff: + arg0 = union_pw_multi_aff(arg0) + except: + raise + try: + if not arg1.__class__ is union_set: + arg1 = union_set(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_pw_multi_aff_intersect_domain_wrapped_domain(isl.isl_union_pw_multi_aff_copy(arg0.ptr), isl.isl_union_set_copy(arg1.ptr)) + obj = union_pw_multi_aff(ctx=ctx, ptr=res) + return obj + def intersect_domain_wrapped_range(arg0, arg1): + try: + if not arg0.__class__ is union_pw_multi_aff: + arg0 = union_pw_multi_aff(arg0) + except: + raise + try: + if not arg1.__class__ is union_set: + arg1 = union_set(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_pw_multi_aff_intersect_domain_wrapped_range(isl.isl_union_pw_multi_aff_copy(arg0.ptr), isl.isl_union_set_copy(arg1.ptr)) + obj = union_pw_multi_aff(ctx=ctx, ptr=res) + return obj + def intersect_params(arg0, arg1): + try: + if not arg0.__class__ is union_pw_multi_aff: + arg0 = union_pw_multi_aff(arg0) + except: + raise + try: + if not arg1.__class__ is set: + arg1 = set(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_pw_multi_aff_intersect_params(isl.isl_union_pw_multi_aff_copy(arg0.ptr), isl.isl_set_copy(arg1.ptr)) + obj = union_pw_multi_aff(ctx=ctx, ptr=res) + return obj + def involves_locals(arg0): + try: + if not arg0.__class__ is union_pw_multi_aff: + arg0 = union_pw_multi_aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_pw_multi_aff_involves_locals(arg0.ptr) + if res < 0: + raise Error + return bool(res) + def isa_pw_multi_aff(arg0): + try: + if not arg0.__class__ is union_pw_multi_aff: + arg0 = union_pw_multi_aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_pw_multi_aff_isa_pw_multi_aff(arg0.ptr) + if res < 0: + raise Error + return bool(res) + def plain_is_empty(arg0): + try: + if not arg0.__class__ is union_pw_multi_aff: + arg0 = union_pw_multi_aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_pw_multi_aff_plain_is_empty(arg0.ptr) + if res < 0: + raise Error + return bool(res) + def plain_is_equal(arg0, arg1): + try: + if not arg0.__class__ is union_pw_multi_aff: + arg0 = union_pw_multi_aff(arg0) + except: + raise + try: + if not arg1.__class__ is union_pw_multi_aff: + arg1 = union_pw_multi_aff(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_pw_multi_aff_plain_is_equal(arg0.ptr, arg1.ptr) + if res < 0: + raise Error + return bool(res) + def preimage_domain_wrapped_domain(*args): + if len(args) == 2 and args[1].__class__ is union_pw_multi_aff: + args = list(args) + try: + if not args[0].__class__ is union_pw_multi_aff: + args[0] = union_pw_multi_aff(args[0]) + except: + raise + ctx = args[0].ctx + res = isl.isl_union_pw_multi_aff_preimage_domain_wrapped_domain_union_pw_multi_aff(isl.isl_union_pw_multi_aff_copy(args[0].ptr), isl.isl_union_pw_multi_aff_copy(args[1].ptr)) + obj = union_pw_multi_aff(ctx=ctx, ptr=res) + return obj + raise Error + def pullback(*args): + if len(args) == 2 and args[1].__class__ is union_pw_multi_aff: + args = list(args) + try: + if not args[0].__class__ is union_pw_multi_aff: + args[0] = union_pw_multi_aff(args[0]) + except: + raise + ctx = args[0].ctx + res = isl.isl_union_pw_multi_aff_pullback_union_pw_multi_aff(isl.isl_union_pw_multi_aff_copy(args[0].ptr), isl.isl_union_pw_multi_aff_copy(args[1].ptr)) + obj = union_pw_multi_aff(ctx=ctx, ptr=res) + return obj + raise Error + def pw_multi_aff_list(arg0): + try: + if not arg0.__class__ is union_pw_multi_aff: + arg0 = union_pw_multi_aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_pw_multi_aff_get_pw_multi_aff_list(arg0.ptr) + obj = pw_multi_aff_list(ctx=ctx, ptr=res) + return obj + def get_pw_multi_aff_list(arg0): + return arg0.pw_multi_aff_list() + def range_factor_domain(arg0): + try: + if not arg0.__class__ is union_pw_multi_aff: + arg0 = union_pw_multi_aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_pw_multi_aff_range_factor_domain(isl.isl_union_pw_multi_aff_copy(arg0.ptr)) + obj = union_pw_multi_aff(ctx=ctx, ptr=res) + return obj + def range_factor_range(arg0): + try: + if not arg0.__class__ is union_pw_multi_aff: + arg0 = union_pw_multi_aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_pw_multi_aff_range_factor_range(isl.isl_union_pw_multi_aff_copy(arg0.ptr)) + obj = union_pw_multi_aff(ctx=ctx, ptr=res) + return obj + def range_product(arg0, arg1): + try: + if not arg0.__class__ is union_pw_multi_aff: + arg0 = union_pw_multi_aff(arg0) + except: + raise + try: + if not arg1.__class__ is union_pw_multi_aff: + arg1 = union_pw_multi_aff(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_pw_multi_aff_range_product(isl.isl_union_pw_multi_aff_copy(arg0.ptr), isl.isl_union_pw_multi_aff_copy(arg1.ptr)) + obj = union_pw_multi_aff(ctx=ctx, ptr=res) + return obj + def space(arg0): + try: + if not arg0.__class__ is union_pw_multi_aff: + arg0 = union_pw_multi_aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_pw_multi_aff_get_space(arg0.ptr) + obj = space(ctx=ctx, ptr=res) + return obj + def get_space(arg0): + return arg0.space() + def sub(arg0, arg1): + try: + if not arg0.__class__ is union_pw_multi_aff: + arg0 = union_pw_multi_aff(arg0) + except: + raise + try: + if not arg1.__class__ is union_pw_multi_aff: + arg1 = union_pw_multi_aff(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_pw_multi_aff_sub(isl.isl_union_pw_multi_aff_copy(arg0.ptr), isl.isl_union_pw_multi_aff_copy(arg1.ptr)) + obj = union_pw_multi_aff(ctx=ctx, ptr=res) + return obj + def subtract_domain(*args): + if len(args) == 2 and args[1].__class__ is space: + args = list(args) + try: + if not args[0].__class__ is union_pw_multi_aff: + args[0] = union_pw_multi_aff(args[0]) + except: + raise + ctx = args[0].ctx + res = isl.isl_union_pw_multi_aff_subtract_domain_space(isl.isl_union_pw_multi_aff_copy(args[0].ptr), isl.isl_space_copy(args[1].ptr)) + obj = union_pw_multi_aff(ctx=ctx, ptr=res) + return obj + if len(args) == 2 and args[1].__class__ is union_set: + args = list(args) + try: + if not args[0].__class__ is union_pw_multi_aff: + args[0] = union_pw_multi_aff(args[0]) + except: + raise + ctx = args[0].ctx + res = isl.isl_union_pw_multi_aff_subtract_domain_union_set(isl.isl_union_pw_multi_aff_copy(args[0].ptr), isl.isl_union_set_copy(args[1].ptr)) + obj = union_pw_multi_aff(ctx=ctx, ptr=res) + return obj + raise Error + def union_add(arg0, arg1): + try: + if not arg0.__class__ is union_pw_multi_aff: + arg0 = union_pw_multi_aff(arg0) + except: + raise + try: + if not arg1.__class__ is union_pw_multi_aff: + arg1 = union_pw_multi_aff(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_pw_multi_aff_union_add(isl.isl_union_pw_multi_aff_copy(arg0.ptr), isl.isl_union_pw_multi_aff_copy(arg1.ptr)) + obj = union_pw_multi_aff(ctx=ctx, ptr=res) + return obj + +isl.isl_union_pw_multi_aff_from_multi_aff.restype = c_void_p +isl.isl_union_pw_multi_aff_from_multi_aff.argtypes = [c_void_p] +isl.isl_union_pw_multi_aff_from_pw_multi_aff.restype = c_void_p +isl.isl_union_pw_multi_aff_from_pw_multi_aff.argtypes = [c_void_p] +isl.isl_union_pw_multi_aff_from_union_pw_aff.restype = c_void_p +isl.isl_union_pw_multi_aff_from_union_pw_aff.argtypes = [c_void_p] +isl.isl_union_pw_multi_aff_read_from_str.restype = c_void_p +isl.isl_union_pw_multi_aff_read_from_str.argtypes = [Context, c_char_p] +isl.isl_union_pw_multi_aff_add.restype = c_void_p +isl.isl_union_pw_multi_aff_add.argtypes = [c_void_p, c_void_p] +isl.isl_union_pw_multi_aff_apply_union_pw_multi_aff.restype = c_void_p +isl.isl_union_pw_multi_aff_apply_union_pw_multi_aff.argtypes = [c_void_p, c_void_p] +isl.isl_union_pw_multi_aff_as_multi_union_pw_aff.restype = c_void_p +isl.isl_union_pw_multi_aff_as_multi_union_pw_aff.argtypes = [c_void_p] +isl.isl_union_pw_multi_aff_as_pw_multi_aff.restype = c_void_p +isl.isl_union_pw_multi_aff_as_pw_multi_aff.argtypes = [c_void_p] +isl.isl_union_pw_multi_aff_as_union_map.restype = c_void_p +isl.isl_union_pw_multi_aff_as_union_map.argtypes = [c_void_p] +isl.isl_union_pw_multi_aff_coalesce.restype = c_void_p +isl.isl_union_pw_multi_aff_coalesce.argtypes = [c_void_p] +isl.isl_union_pw_multi_aff_domain.restype = c_void_p +isl.isl_union_pw_multi_aff_domain.argtypes = [c_void_p] +isl.isl_union_pw_multi_aff_drop_unused_params.restype = c_void_p +isl.isl_union_pw_multi_aff_drop_unused_params.argtypes = [c_void_p] +isl.isl_union_pw_multi_aff_empty_ctx.restype = c_void_p +isl.isl_union_pw_multi_aff_empty_ctx.argtypes = [Context] +isl.isl_union_pw_multi_aff_extract_pw_multi_aff.restype = c_void_p +isl.isl_union_pw_multi_aff_extract_pw_multi_aff.argtypes = [c_void_p, c_void_p] +isl.isl_union_pw_multi_aff_flat_range_product.restype = c_void_p +isl.isl_union_pw_multi_aff_flat_range_product.argtypes = [c_void_p, c_void_p] +isl.isl_union_pw_multi_aff_gist.restype = c_void_p +isl.isl_union_pw_multi_aff_gist.argtypes = [c_void_p, c_void_p] +isl.isl_union_pw_multi_aff_intersect_domain_space.restype = c_void_p +isl.isl_union_pw_multi_aff_intersect_domain_space.argtypes = [c_void_p, c_void_p] +isl.isl_union_pw_multi_aff_intersect_domain_union_set.restype = c_void_p +isl.isl_union_pw_multi_aff_intersect_domain_union_set.argtypes = [c_void_p, c_void_p] +isl.isl_union_pw_multi_aff_intersect_domain_wrapped_domain.restype = c_void_p +isl.isl_union_pw_multi_aff_intersect_domain_wrapped_domain.argtypes = [c_void_p, c_void_p] +isl.isl_union_pw_multi_aff_intersect_domain_wrapped_range.restype = c_void_p +isl.isl_union_pw_multi_aff_intersect_domain_wrapped_range.argtypes = [c_void_p, c_void_p] +isl.isl_union_pw_multi_aff_intersect_params.restype = c_void_p +isl.isl_union_pw_multi_aff_intersect_params.argtypes = [c_void_p, c_void_p] +isl.isl_union_pw_multi_aff_involves_locals.argtypes = [c_void_p] +isl.isl_union_pw_multi_aff_isa_pw_multi_aff.argtypes = [c_void_p] +isl.isl_union_pw_multi_aff_plain_is_empty.argtypes = [c_void_p] +isl.isl_union_pw_multi_aff_plain_is_equal.argtypes = [c_void_p, c_void_p] +isl.isl_union_pw_multi_aff_preimage_domain_wrapped_domain_union_pw_multi_aff.restype = c_void_p +isl.isl_union_pw_multi_aff_preimage_domain_wrapped_domain_union_pw_multi_aff.argtypes = [c_void_p, c_void_p] +isl.isl_union_pw_multi_aff_pullback_union_pw_multi_aff.restype = c_void_p +isl.isl_union_pw_multi_aff_pullback_union_pw_multi_aff.argtypes = [c_void_p, c_void_p] +isl.isl_union_pw_multi_aff_get_pw_multi_aff_list.restype = c_void_p +isl.isl_union_pw_multi_aff_get_pw_multi_aff_list.argtypes = [c_void_p] +isl.isl_union_pw_multi_aff_range_factor_domain.restype = c_void_p +isl.isl_union_pw_multi_aff_range_factor_domain.argtypes = [c_void_p] +isl.isl_union_pw_multi_aff_range_factor_range.restype = c_void_p +isl.isl_union_pw_multi_aff_range_factor_range.argtypes = [c_void_p] +isl.isl_union_pw_multi_aff_range_product.restype = c_void_p +isl.isl_union_pw_multi_aff_range_product.argtypes = [c_void_p, c_void_p] +isl.isl_union_pw_multi_aff_get_space.restype = c_void_p +isl.isl_union_pw_multi_aff_get_space.argtypes = [c_void_p] +isl.isl_union_pw_multi_aff_sub.restype = c_void_p +isl.isl_union_pw_multi_aff_sub.argtypes = [c_void_p, c_void_p] +isl.isl_union_pw_multi_aff_subtract_domain_space.restype = c_void_p +isl.isl_union_pw_multi_aff_subtract_domain_space.argtypes = [c_void_p, c_void_p] +isl.isl_union_pw_multi_aff_subtract_domain_union_set.restype = c_void_p +isl.isl_union_pw_multi_aff_subtract_domain_union_set.argtypes = [c_void_p, c_void_p] +isl.isl_union_pw_multi_aff_union_add.restype = c_void_p +isl.isl_union_pw_multi_aff_union_add.argtypes = [c_void_p, c_void_p] +isl.isl_union_pw_multi_aff_copy.restype = c_void_p +isl.isl_union_pw_multi_aff_copy.argtypes = [c_void_p] +isl.isl_union_pw_multi_aff_free.restype = c_void_p +isl.isl_union_pw_multi_aff_free.argtypes = [c_void_p] +isl.isl_union_pw_multi_aff_to_str.restype = POINTER(c_char) +isl.isl_union_pw_multi_aff_to_str.argtypes = [c_void_p] + +class multi_union_pw_aff(object): + def __init__(self, *args, **keywords): + if "ptr" in keywords: + self.ctx = keywords["ctx"] + self.ptr = keywords["ptr"] + return + if len(args) == 1 and args[0].__class__ is multi_pw_aff: + self.ctx = Context.getDefaultInstance() + self.ptr = isl.isl_multi_union_pw_aff_from_multi_pw_aff(isl.isl_multi_pw_aff_copy(args[0].ptr)) + return + if len(args) == 1 and args[0].__class__ is union_pw_aff: + self.ctx = Context.getDefaultInstance() + self.ptr = isl.isl_multi_union_pw_aff_from_union_pw_aff(isl.isl_union_pw_aff_copy(args[0].ptr)) + return + if len(args) == 2 and args[0].__class__ is space and args[1].__class__ is union_pw_aff_list: + self.ctx = Context.getDefaultInstance() + self.ptr = isl.isl_multi_union_pw_aff_from_union_pw_aff_list(isl.isl_space_copy(args[0].ptr), isl.isl_union_pw_aff_list_copy(args[1].ptr)) + return + if len(args) == 1 and type(args[0]) == str: + self.ctx = Context.getDefaultInstance() + self.ptr = isl.isl_multi_union_pw_aff_read_from_str(self.ctx, args[0].encode('ascii')) + return + raise Error + def __del__(self): + if hasattr(self, 'ptr'): + isl.isl_multi_union_pw_aff_free(self.ptr) + def __str__(arg0): + try: + if not arg0.__class__ is multi_union_pw_aff: + arg0 = multi_union_pw_aff(arg0) + except: + raise + ptr = isl.isl_multi_union_pw_aff_to_str(arg0.ptr) + res = cast(ptr, c_char_p).value.decode('ascii') + libc.free(ptr) + return res + def __repr__(self): + s = str(self) + if '"' in s: + return 'isl.multi_union_pw_aff("""%s""")' % s + else: + return 'isl.multi_union_pw_aff("%s")' % s + def add(arg0, arg1): + try: + if not arg0.__class__ is multi_union_pw_aff: + arg0 = multi_union_pw_aff(arg0) + except: + raise + try: + if not arg1.__class__ is multi_union_pw_aff: + arg1 = multi_union_pw_aff(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_multi_union_pw_aff_add(isl.isl_multi_union_pw_aff_copy(arg0.ptr), isl.isl_multi_union_pw_aff_copy(arg1.ptr)) + obj = multi_union_pw_aff(ctx=ctx, ptr=res) + return obj + def at(arg0, arg1): + try: + if not arg0.__class__ is multi_union_pw_aff: + arg0 = multi_union_pw_aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_multi_union_pw_aff_get_at(arg0.ptr, arg1) + obj = union_pw_aff(ctx=ctx, ptr=res) + return obj + def get_at(arg0, arg1): + return arg0.at(arg1) + def bind(arg0, arg1): + try: + if not arg0.__class__ is multi_union_pw_aff: + arg0 = multi_union_pw_aff(arg0) + except: + raise + try: + if not arg1.__class__ is multi_id: + arg1 = multi_id(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_multi_union_pw_aff_bind(isl.isl_multi_union_pw_aff_copy(arg0.ptr), isl.isl_multi_id_copy(arg1.ptr)) + obj = union_set(ctx=ctx, ptr=res) + return obj + def coalesce(arg0): + try: + if not arg0.__class__ is multi_union_pw_aff: + arg0 = multi_union_pw_aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_multi_union_pw_aff_coalesce(isl.isl_multi_union_pw_aff_copy(arg0.ptr)) + obj = multi_union_pw_aff(ctx=ctx, ptr=res) + return obj + def domain(arg0): + try: + if not arg0.__class__ is multi_union_pw_aff: + arg0 = multi_union_pw_aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_multi_union_pw_aff_domain(isl.isl_multi_union_pw_aff_copy(arg0.ptr)) + obj = union_set(ctx=ctx, ptr=res) + return obj + def flat_range_product(arg0, arg1): + try: + if not arg0.__class__ is multi_union_pw_aff: + arg0 = multi_union_pw_aff(arg0) + except: + raise + try: + if not arg1.__class__ is multi_union_pw_aff: + arg1 = multi_union_pw_aff(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_multi_union_pw_aff_flat_range_product(isl.isl_multi_union_pw_aff_copy(arg0.ptr), isl.isl_multi_union_pw_aff_copy(arg1.ptr)) + obj = multi_union_pw_aff(ctx=ctx, ptr=res) + return obj + def gist(arg0, arg1): + try: + if not arg0.__class__ is multi_union_pw_aff: + arg0 = multi_union_pw_aff(arg0) + except: + raise + try: + if not arg1.__class__ is union_set: + arg1 = union_set(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_multi_union_pw_aff_gist(isl.isl_multi_union_pw_aff_copy(arg0.ptr), isl.isl_union_set_copy(arg1.ptr)) + obj = multi_union_pw_aff(ctx=ctx, ptr=res) + return obj + def gist_params(arg0, arg1): + try: + if not arg0.__class__ is multi_union_pw_aff: + arg0 = multi_union_pw_aff(arg0) + except: + raise + try: + if not arg1.__class__ is set: + arg1 = set(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_multi_union_pw_aff_gist_params(isl.isl_multi_union_pw_aff_copy(arg0.ptr), isl.isl_set_copy(arg1.ptr)) + obj = multi_union_pw_aff(ctx=ctx, ptr=res) + return obj + def has_range_tuple_id(arg0): + try: + if not arg0.__class__ is multi_union_pw_aff: + arg0 = multi_union_pw_aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_multi_union_pw_aff_has_range_tuple_id(arg0.ptr) + if res < 0: + raise Error + return bool(res) + def intersect_domain(arg0, arg1): + try: + if not arg0.__class__ is multi_union_pw_aff: + arg0 = multi_union_pw_aff(arg0) + except: + raise + try: + if not arg1.__class__ is union_set: + arg1 = union_set(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_multi_union_pw_aff_intersect_domain(isl.isl_multi_union_pw_aff_copy(arg0.ptr), isl.isl_union_set_copy(arg1.ptr)) + obj = multi_union_pw_aff(ctx=ctx, ptr=res) + return obj + def intersect_params(arg0, arg1): + try: + if not arg0.__class__ is multi_union_pw_aff: + arg0 = multi_union_pw_aff(arg0) + except: + raise + try: + if not arg1.__class__ is set: + arg1 = set(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_multi_union_pw_aff_intersect_params(isl.isl_multi_union_pw_aff_copy(arg0.ptr), isl.isl_set_copy(arg1.ptr)) + obj = multi_union_pw_aff(ctx=ctx, ptr=res) + return obj + def involves_nan(arg0): + try: + if not arg0.__class__ is multi_union_pw_aff: + arg0 = multi_union_pw_aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_multi_union_pw_aff_involves_nan(arg0.ptr) + if res < 0: + raise Error + return bool(res) + def list(arg0): + try: + if not arg0.__class__ is multi_union_pw_aff: + arg0 = multi_union_pw_aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_multi_union_pw_aff_get_list(arg0.ptr) + obj = union_pw_aff_list(ctx=ctx, ptr=res) + return obj + def get_list(arg0): + return arg0.list() + def neg(arg0): + try: + if not arg0.__class__ is multi_union_pw_aff: + arg0 = multi_union_pw_aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_multi_union_pw_aff_neg(isl.isl_multi_union_pw_aff_copy(arg0.ptr)) + obj = multi_union_pw_aff(ctx=ctx, ptr=res) + return obj + def plain_is_equal(arg0, arg1): + try: + if not arg0.__class__ is multi_union_pw_aff: + arg0 = multi_union_pw_aff(arg0) + except: + raise + try: + if not arg1.__class__ is multi_union_pw_aff: + arg1 = multi_union_pw_aff(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_multi_union_pw_aff_plain_is_equal(arg0.ptr, arg1.ptr) + if res < 0: + raise Error + return bool(res) + def pullback(*args): + if len(args) == 2 and args[1].__class__ is union_pw_multi_aff: + args = list(args) + try: + if not args[0].__class__ is multi_union_pw_aff: + args[0] = multi_union_pw_aff(args[0]) + except: + raise + ctx = args[0].ctx + res = isl.isl_multi_union_pw_aff_pullback_union_pw_multi_aff(isl.isl_multi_union_pw_aff_copy(args[0].ptr), isl.isl_union_pw_multi_aff_copy(args[1].ptr)) + obj = multi_union_pw_aff(ctx=ctx, ptr=res) + return obj + raise Error + def range_product(arg0, arg1): + try: + if not arg0.__class__ is multi_union_pw_aff: + arg0 = multi_union_pw_aff(arg0) + except: + raise + try: + if not arg1.__class__ is multi_union_pw_aff: + arg1 = multi_union_pw_aff(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_multi_union_pw_aff_range_product(isl.isl_multi_union_pw_aff_copy(arg0.ptr), isl.isl_multi_union_pw_aff_copy(arg1.ptr)) + obj = multi_union_pw_aff(ctx=ctx, ptr=res) + return obj + def range_tuple_id(arg0): + try: + if not arg0.__class__ is multi_union_pw_aff: + arg0 = multi_union_pw_aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_multi_union_pw_aff_get_range_tuple_id(arg0.ptr) + obj = id(ctx=ctx, ptr=res) + return obj + def get_range_tuple_id(arg0): + return arg0.range_tuple_id() + def reset_range_tuple_id(arg0): + try: + if not arg0.__class__ is multi_union_pw_aff: + arg0 = multi_union_pw_aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_multi_union_pw_aff_reset_range_tuple_id(isl.isl_multi_union_pw_aff_copy(arg0.ptr)) + obj = multi_union_pw_aff(ctx=ctx, ptr=res) + return obj + def scale(*args): + if len(args) == 2 and args[1].__class__ is multi_val: + args = list(args) + try: + if not args[0].__class__ is multi_union_pw_aff: + args[0] = multi_union_pw_aff(args[0]) + except: + raise + ctx = args[0].ctx + res = isl.isl_multi_union_pw_aff_scale_multi_val(isl.isl_multi_union_pw_aff_copy(args[0].ptr), isl.isl_multi_val_copy(args[1].ptr)) + obj = multi_union_pw_aff(ctx=ctx, ptr=res) + return obj + if len(args) == 2 and (args[1].__class__ is val or type(args[1]) == int): + args = list(args) + try: + if not args[0].__class__ is multi_union_pw_aff: + args[0] = multi_union_pw_aff(args[0]) + except: + raise + try: + if not args[1].__class__ is val: + args[1] = val(args[1]) + except: + raise + ctx = args[0].ctx + res = isl.isl_multi_union_pw_aff_scale_val(isl.isl_multi_union_pw_aff_copy(args[0].ptr), isl.isl_val_copy(args[1].ptr)) + obj = multi_union_pw_aff(ctx=ctx, ptr=res) + return obj + raise Error + def scale_down(*args): + if len(args) == 2 and args[1].__class__ is multi_val: + args = list(args) + try: + if not args[0].__class__ is multi_union_pw_aff: + args[0] = multi_union_pw_aff(args[0]) + except: + raise + ctx = args[0].ctx + res = isl.isl_multi_union_pw_aff_scale_down_multi_val(isl.isl_multi_union_pw_aff_copy(args[0].ptr), isl.isl_multi_val_copy(args[1].ptr)) + obj = multi_union_pw_aff(ctx=ctx, ptr=res) + return obj + if len(args) == 2 and (args[1].__class__ is val or type(args[1]) == int): + args = list(args) + try: + if not args[0].__class__ is multi_union_pw_aff: + args[0] = multi_union_pw_aff(args[0]) + except: + raise + try: + if not args[1].__class__ is val: + args[1] = val(args[1]) + except: + raise + ctx = args[0].ctx + res = isl.isl_multi_union_pw_aff_scale_down_val(isl.isl_multi_union_pw_aff_copy(args[0].ptr), isl.isl_val_copy(args[1].ptr)) + obj = multi_union_pw_aff(ctx=ctx, ptr=res) + return obj + raise Error + def set_at(arg0, arg1, arg2): + try: + if not arg0.__class__ is multi_union_pw_aff: + arg0 = multi_union_pw_aff(arg0) + except: + raise + try: + if not arg2.__class__ is union_pw_aff: + arg2 = union_pw_aff(arg2) + except: + raise + ctx = arg0.ctx + res = isl.isl_multi_union_pw_aff_set_at(isl.isl_multi_union_pw_aff_copy(arg0.ptr), arg1, isl.isl_union_pw_aff_copy(arg2.ptr)) + obj = multi_union_pw_aff(ctx=ctx, ptr=res) + return obj + def set_range_tuple(*args): + if len(args) == 2 and (args[1].__class__ is id or type(args[1]) == str): + args = list(args) + try: + if not args[0].__class__ is multi_union_pw_aff: + args[0] = multi_union_pw_aff(args[0]) + except: + raise + try: + if not args[1].__class__ is id: + args[1] = id(args[1]) + except: + raise + ctx = args[0].ctx + res = isl.isl_multi_union_pw_aff_set_range_tuple_id(isl.isl_multi_union_pw_aff_copy(args[0].ptr), isl.isl_id_copy(args[1].ptr)) + obj = multi_union_pw_aff(ctx=ctx, ptr=res) + return obj + raise Error + def size(arg0): + try: + if not arg0.__class__ is multi_union_pw_aff: + arg0 = multi_union_pw_aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_multi_union_pw_aff_size(arg0.ptr) + if res < 0: + raise Error + return int(res) + def space(arg0): + try: + if not arg0.__class__ is multi_union_pw_aff: + arg0 = multi_union_pw_aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_multi_union_pw_aff_get_space(arg0.ptr) + obj = space(ctx=ctx, ptr=res) + return obj + def get_space(arg0): + return arg0.space() + def sub(arg0, arg1): + try: + if not arg0.__class__ is multi_union_pw_aff: + arg0 = multi_union_pw_aff(arg0) + except: + raise + try: + if not arg1.__class__ is multi_union_pw_aff: + arg1 = multi_union_pw_aff(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_multi_union_pw_aff_sub(isl.isl_multi_union_pw_aff_copy(arg0.ptr), isl.isl_multi_union_pw_aff_copy(arg1.ptr)) + obj = multi_union_pw_aff(ctx=ctx, ptr=res) + return obj + def union_add(arg0, arg1): + try: + if not arg0.__class__ is multi_union_pw_aff: + arg0 = multi_union_pw_aff(arg0) + except: + raise + try: + if not arg1.__class__ is multi_union_pw_aff: + arg1 = multi_union_pw_aff(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_multi_union_pw_aff_union_add(isl.isl_multi_union_pw_aff_copy(arg0.ptr), isl.isl_multi_union_pw_aff_copy(arg1.ptr)) + obj = multi_union_pw_aff(ctx=ctx, ptr=res) + return obj + @staticmethod + def zero(arg0): + try: + if not arg0.__class__ is space: + arg0 = space(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_multi_union_pw_aff_zero(isl.isl_space_copy(arg0.ptr)) + obj = multi_union_pw_aff(ctx=ctx, ptr=res) + return obj + +isl.isl_multi_union_pw_aff_from_multi_pw_aff.restype = c_void_p +isl.isl_multi_union_pw_aff_from_multi_pw_aff.argtypes = [c_void_p] +isl.isl_multi_union_pw_aff_from_union_pw_aff.restype = c_void_p +isl.isl_multi_union_pw_aff_from_union_pw_aff.argtypes = [c_void_p] +isl.isl_multi_union_pw_aff_from_union_pw_aff_list.restype = c_void_p +isl.isl_multi_union_pw_aff_from_union_pw_aff_list.argtypes = [c_void_p, c_void_p] +isl.isl_multi_union_pw_aff_read_from_str.restype = c_void_p +isl.isl_multi_union_pw_aff_read_from_str.argtypes = [Context, c_char_p] +isl.isl_multi_union_pw_aff_add.restype = c_void_p +isl.isl_multi_union_pw_aff_add.argtypes = [c_void_p, c_void_p] +isl.isl_multi_union_pw_aff_get_at.restype = c_void_p +isl.isl_multi_union_pw_aff_get_at.argtypes = [c_void_p, c_int] +isl.isl_multi_union_pw_aff_bind.restype = c_void_p +isl.isl_multi_union_pw_aff_bind.argtypes = [c_void_p, c_void_p] +isl.isl_multi_union_pw_aff_coalesce.restype = c_void_p +isl.isl_multi_union_pw_aff_coalesce.argtypes = [c_void_p] +isl.isl_multi_union_pw_aff_domain.restype = c_void_p +isl.isl_multi_union_pw_aff_domain.argtypes = [c_void_p] +isl.isl_multi_union_pw_aff_flat_range_product.restype = c_void_p +isl.isl_multi_union_pw_aff_flat_range_product.argtypes = [c_void_p, c_void_p] +isl.isl_multi_union_pw_aff_gist.restype = c_void_p +isl.isl_multi_union_pw_aff_gist.argtypes = [c_void_p, c_void_p] +isl.isl_multi_union_pw_aff_gist_params.restype = c_void_p +isl.isl_multi_union_pw_aff_gist_params.argtypes = [c_void_p, c_void_p] +isl.isl_multi_union_pw_aff_has_range_tuple_id.argtypes = [c_void_p] +isl.isl_multi_union_pw_aff_intersect_domain.restype = c_void_p +isl.isl_multi_union_pw_aff_intersect_domain.argtypes = [c_void_p, c_void_p] +isl.isl_multi_union_pw_aff_intersect_params.restype = c_void_p +isl.isl_multi_union_pw_aff_intersect_params.argtypes = [c_void_p, c_void_p] +isl.isl_multi_union_pw_aff_involves_nan.argtypes = [c_void_p] +isl.isl_multi_union_pw_aff_get_list.restype = c_void_p +isl.isl_multi_union_pw_aff_get_list.argtypes = [c_void_p] +isl.isl_multi_union_pw_aff_neg.restype = c_void_p +isl.isl_multi_union_pw_aff_neg.argtypes = [c_void_p] +isl.isl_multi_union_pw_aff_plain_is_equal.argtypes = [c_void_p, c_void_p] +isl.isl_multi_union_pw_aff_pullback_union_pw_multi_aff.restype = c_void_p +isl.isl_multi_union_pw_aff_pullback_union_pw_multi_aff.argtypes = [c_void_p, c_void_p] +isl.isl_multi_union_pw_aff_range_product.restype = c_void_p +isl.isl_multi_union_pw_aff_range_product.argtypes = [c_void_p, c_void_p] +isl.isl_multi_union_pw_aff_get_range_tuple_id.restype = c_void_p +isl.isl_multi_union_pw_aff_get_range_tuple_id.argtypes = [c_void_p] +isl.isl_multi_union_pw_aff_reset_range_tuple_id.restype = c_void_p +isl.isl_multi_union_pw_aff_reset_range_tuple_id.argtypes = [c_void_p] +isl.isl_multi_union_pw_aff_scale_multi_val.restype = c_void_p +isl.isl_multi_union_pw_aff_scale_multi_val.argtypes = [c_void_p, c_void_p] +isl.isl_multi_union_pw_aff_scale_val.restype = c_void_p +isl.isl_multi_union_pw_aff_scale_val.argtypes = [c_void_p, c_void_p] +isl.isl_multi_union_pw_aff_scale_down_multi_val.restype = c_void_p +isl.isl_multi_union_pw_aff_scale_down_multi_val.argtypes = [c_void_p, c_void_p] +isl.isl_multi_union_pw_aff_scale_down_val.restype = c_void_p +isl.isl_multi_union_pw_aff_scale_down_val.argtypes = [c_void_p, c_void_p] +isl.isl_multi_union_pw_aff_set_at.restype = c_void_p +isl.isl_multi_union_pw_aff_set_at.argtypes = [c_void_p, c_int, c_void_p] +isl.isl_multi_union_pw_aff_set_range_tuple_id.restype = c_void_p +isl.isl_multi_union_pw_aff_set_range_tuple_id.argtypes = [c_void_p, c_void_p] +isl.isl_multi_union_pw_aff_size.argtypes = [c_void_p] +isl.isl_multi_union_pw_aff_get_space.restype = c_void_p +isl.isl_multi_union_pw_aff_get_space.argtypes = [c_void_p] +isl.isl_multi_union_pw_aff_sub.restype = c_void_p +isl.isl_multi_union_pw_aff_sub.argtypes = [c_void_p, c_void_p] +isl.isl_multi_union_pw_aff_union_add.restype = c_void_p +isl.isl_multi_union_pw_aff_union_add.argtypes = [c_void_p, c_void_p] +isl.isl_multi_union_pw_aff_zero.restype = c_void_p +isl.isl_multi_union_pw_aff_zero.argtypes = [c_void_p] +isl.isl_multi_union_pw_aff_copy.restype = c_void_p +isl.isl_multi_union_pw_aff_copy.argtypes = [c_void_p] +isl.isl_multi_union_pw_aff_free.restype = c_void_p +isl.isl_multi_union_pw_aff_free.argtypes = [c_void_p] +isl.isl_multi_union_pw_aff_to_str.restype = POINTER(c_char) +isl.isl_multi_union_pw_aff_to_str.argtypes = [c_void_p] + +class union_pw_aff(union_pw_multi_aff, multi_union_pw_aff): + def __init__(self, *args, **keywords): + if "ptr" in keywords: + self.ctx = keywords["ctx"] + self.ptr = keywords["ptr"] + return + if len(args) == 1 and args[0].__class__ is aff: + self.ctx = Context.getDefaultInstance() + self.ptr = isl.isl_union_pw_aff_from_aff(isl.isl_aff_copy(args[0].ptr)) + return + if len(args) == 1 and args[0].__class__ is pw_aff: + self.ctx = Context.getDefaultInstance() + self.ptr = isl.isl_union_pw_aff_from_pw_aff(isl.isl_pw_aff_copy(args[0].ptr)) + return + if len(args) == 1 and type(args[0]) == str: + self.ctx = Context.getDefaultInstance() + self.ptr = isl.isl_union_pw_aff_read_from_str(self.ctx, args[0].encode('ascii')) + return + raise Error + def __del__(self): + if hasattr(self, 'ptr'): + isl.isl_union_pw_aff_free(self.ptr) + def __str__(arg0): + try: + if not arg0.__class__ is union_pw_aff: + arg0 = union_pw_aff(arg0) + except: + raise + ptr = isl.isl_union_pw_aff_to_str(arg0.ptr) + res = cast(ptr, c_char_p).value.decode('ascii') + libc.free(ptr) + return res + def __repr__(self): + s = str(self) + if '"' in s: + return 'isl.union_pw_aff("""%s""")' % s + else: + return 'isl.union_pw_aff("%s")' % s + def add(arg0, arg1): + try: + if not arg0.__class__ is union_pw_aff: + arg0 = union_pw_aff(arg0) + except: + raise + try: + if not arg1.__class__ is union_pw_aff: + arg1 = union_pw_aff(arg1) + except: + return union_pw_multi_aff(arg0).add(arg1) + ctx = arg0.ctx + res = isl.isl_union_pw_aff_add(isl.isl_union_pw_aff_copy(arg0.ptr), isl.isl_union_pw_aff_copy(arg1.ptr)) + obj = union_pw_aff(ctx=ctx, ptr=res) + return obj + def bind(*args): + if len(args) == 2 and (args[1].__class__ is id or type(args[1]) == str): + args = list(args) + try: + if not args[0].__class__ is union_pw_aff: + args[0] = union_pw_aff(args[0]) + except: + raise + try: + if not args[1].__class__ is id: + args[1] = id(args[1]) + except: + raise + ctx = args[0].ctx + res = isl.isl_union_pw_aff_bind_id(isl.isl_union_pw_aff_copy(args[0].ptr), isl.isl_id_copy(args[1].ptr)) + obj = union_set(ctx=ctx, ptr=res) + return obj + raise Error + def coalesce(arg0): + try: + if not arg0.__class__ is union_pw_aff: + arg0 = union_pw_aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_pw_aff_coalesce(isl.isl_union_pw_aff_copy(arg0.ptr)) + obj = union_pw_aff(ctx=ctx, ptr=res) + return obj + def domain(arg0): + try: + if not arg0.__class__ is union_pw_aff: + arg0 = union_pw_aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_pw_aff_domain(isl.isl_union_pw_aff_copy(arg0.ptr)) + obj = union_set(ctx=ctx, ptr=res) + return obj + def drop_unused_params(arg0): + try: + if not arg0.__class__ is union_pw_aff: + arg0 = union_pw_aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_pw_aff_drop_unused_params(isl.isl_union_pw_aff_copy(arg0.ptr)) + obj = union_pw_aff(ctx=ctx, ptr=res) + return obj + def gist(arg0, arg1): + try: + if not arg0.__class__ is union_pw_aff: + arg0 = union_pw_aff(arg0) + except: + raise + try: + if not arg1.__class__ is union_set: + arg1 = union_set(arg1) + except: + return union_pw_multi_aff(arg0).gist(arg1) + ctx = arg0.ctx + res = isl.isl_union_pw_aff_gist(isl.isl_union_pw_aff_copy(arg0.ptr), isl.isl_union_set_copy(arg1.ptr)) + obj = union_pw_aff(ctx=ctx, ptr=res) + return obj + def intersect_domain(*args): + if len(args) == 2 and args[1].__class__ is space: + args = list(args) + try: + if not args[0].__class__ is union_pw_aff: + args[0] = union_pw_aff(args[0]) + except: + raise + ctx = args[0].ctx + res = isl.isl_union_pw_aff_intersect_domain_space(isl.isl_union_pw_aff_copy(args[0].ptr), isl.isl_space_copy(args[1].ptr)) + obj = union_pw_aff(ctx=ctx, ptr=res) + return obj + if len(args) == 2 and args[1].__class__ is union_set: + args = list(args) + try: + if not args[0].__class__ is union_pw_aff: + args[0] = union_pw_aff(args[0]) + except: + raise + ctx = args[0].ctx + res = isl.isl_union_pw_aff_intersect_domain_union_set(isl.isl_union_pw_aff_copy(args[0].ptr), isl.isl_union_set_copy(args[1].ptr)) + obj = union_pw_aff(ctx=ctx, ptr=res) + return obj + raise Error + def intersect_domain_wrapped_domain(arg0, arg1): + try: + if not arg0.__class__ is union_pw_aff: + arg0 = union_pw_aff(arg0) + except: + raise + try: + if not arg1.__class__ is union_set: + arg1 = union_set(arg1) + except: + return union_pw_multi_aff(arg0).intersect_domain_wrapped_domain(arg1) + ctx = arg0.ctx + res = isl.isl_union_pw_aff_intersect_domain_wrapped_domain(isl.isl_union_pw_aff_copy(arg0.ptr), isl.isl_union_set_copy(arg1.ptr)) + obj = union_pw_aff(ctx=ctx, ptr=res) + return obj + def intersect_domain_wrapped_range(arg0, arg1): + try: + if not arg0.__class__ is union_pw_aff: + arg0 = union_pw_aff(arg0) + except: + raise + try: + if not arg1.__class__ is union_set: + arg1 = union_set(arg1) + except: + return union_pw_multi_aff(arg0).intersect_domain_wrapped_range(arg1) + ctx = arg0.ctx + res = isl.isl_union_pw_aff_intersect_domain_wrapped_range(isl.isl_union_pw_aff_copy(arg0.ptr), isl.isl_union_set_copy(arg1.ptr)) + obj = union_pw_aff(ctx=ctx, ptr=res) + return obj + def intersect_params(arg0, arg1): + try: + if not arg0.__class__ is union_pw_aff: + arg0 = union_pw_aff(arg0) + except: + raise + try: + if not arg1.__class__ is set: + arg1 = set(arg1) + except: + return union_pw_multi_aff(arg0).intersect_params(arg1) + ctx = arg0.ctx + res = isl.isl_union_pw_aff_intersect_params(isl.isl_union_pw_aff_copy(arg0.ptr), isl.isl_set_copy(arg1.ptr)) + obj = union_pw_aff(ctx=ctx, ptr=res) + return obj + def plain_is_equal(arg0, arg1): + try: + if not arg0.__class__ is union_pw_aff: + arg0 = union_pw_aff(arg0) + except: + raise + try: + if not arg1.__class__ is union_pw_aff: + arg1 = union_pw_aff(arg1) + except: + return union_pw_multi_aff(arg0).plain_is_equal(arg1) + ctx = arg0.ctx + res = isl.isl_union_pw_aff_plain_is_equal(arg0.ptr, arg1.ptr) + if res < 0: + raise Error + return bool(res) + def pullback(*args): + if len(args) == 2 and args[1].__class__ is union_pw_multi_aff: + args = list(args) + try: + if not args[0].__class__ is union_pw_aff: + args[0] = union_pw_aff(args[0]) + except: + raise + ctx = args[0].ctx + res = isl.isl_union_pw_aff_pullback_union_pw_multi_aff(isl.isl_union_pw_aff_copy(args[0].ptr), isl.isl_union_pw_multi_aff_copy(args[1].ptr)) + obj = union_pw_aff(ctx=ctx, ptr=res) + return obj + raise Error + def space(arg0): + try: + if not arg0.__class__ is union_pw_aff: + arg0 = union_pw_aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_pw_aff_get_space(arg0.ptr) + obj = space(ctx=ctx, ptr=res) + return obj + def get_space(arg0): + return arg0.space() + def sub(arg0, arg1): + try: + if not arg0.__class__ is union_pw_aff: + arg0 = union_pw_aff(arg0) + except: + raise + try: + if not arg1.__class__ is union_pw_aff: + arg1 = union_pw_aff(arg1) + except: + return union_pw_multi_aff(arg0).sub(arg1) + ctx = arg0.ctx + res = isl.isl_union_pw_aff_sub(isl.isl_union_pw_aff_copy(arg0.ptr), isl.isl_union_pw_aff_copy(arg1.ptr)) + obj = union_pw_aff(ctx=ctx, ptr=res) + return obj + def subtract_domain(*args): + if len(args) == 2 and args[1].__class__ is space: + args = list(args) + try: + if not args[0].__class__ is union_pw_aff: + args[0] = union_pw_aff(args[0]) + except: + raise + ctx = args[0].ctx + res = isl.isl_union_pw_aff_subtract_domain_space(isl.isl_union_pw_aff_copy(args[0].ptr), isl.isl_space_copy(args[1].ptr)) + obj = union_pw_aff(ctx=ctx, ptr=res) + return obj + if len(args) == 2 and args[1].__class__ is union_set: + args = list(args) + try: + if not args[0].__class__ is union_pw_aff: + args[0] = union_pw_aff(args[0]) + except: + raise + ctx = args[0].ctx + res = isl.isl_union_pw_aff_subtract_domain_union_set(isl.isl_union_pw_aff_copy(args[0].ptr), isl.isl_union_set_copy(args[1].ptr)) + obj = union_pw_aff(ctx=ctx, ptr=res) + return obj + raise Error + def to_list(arg0): + try: + if not arg0.__class__ is union_pw_aff: + arg0 = union_pw_aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_pw_aff_to_list(isl.isl_union_pw_aff_copy(arg0.ptr)) + obj = union_pw_aff_list(ctx=ctx, ptr=res) + return obj + def union_add(arg0, arg1): + try: + if not arg0.__class__ is union_pw_aff: + arg0 = union_pw_aff(arg0) + except: + raise + try: + if not arg1.__class__ is union_pw_aff: + arg1 = union_pw_aff(arg1) + except: + return union_pw_multi_aff(arg0).union_add(arg1) + ctx = arg0.ctx + res = isl.isl_union_pw_aff_union_add(isl.isl_union_pw_aff_copy(arg0.ptr), isl.isl_union_pw_aff_copy(arg1.ptr)) + obj = union_pw_aff(ctx=ctx, ptr=res) + return obj + +isl.isl_union_pw_aff_from_aff.restype = c_void_p +isl.isl_union_pw_aff_from_aff.argtypes = [c_void_p] +isl.isl_union_pw_aff_from_pw_aff.restype = c_void_p +isl.isl_union_pw_aff_from_pw_aff.argtypes = [c_void_p] +isl.isl_union_pw_aff_read_from_str.restype = c_void_p +isl.isl_union_pw_aff_read_from_str.argtypes = [Context, c_char_p] +isl.isl_union_pw_aff_add.restype = c_void_p +isl.isl_union_pw_aff_add.argtypes = [c_void_p, c_void_p] +isl.isl_union_pw_aff_bind_id.restype = c_void_p +isl.isl_union_pw_aff_bind_id.argtypes = [c_void_p, c_void_p] +isl.isl_union_pw_aff_coalesce.restype = c_void_p +isl.isl_union_pw_aff_coalesce.argtypes = [c_void_p] +isl.isl_union_pw_aff_domain.restype = c_void_p +isl.isl_union_pw_aff_domain.argtypes = [c_void_p] +isl.isl_union_pw_aff_drop_unused_params.restype = c_void_p +isl.isl_union_pw_aff_drop_unused_params.argtypes = [c_void_p] +isl.isl_union_pw_aff_gist.restype = c_void_p +isl.isl_union_pw_aff_gist.argtypes = [c_void_p, c_void_p] +isl.isl_union_pw_aff_intersect_domain_space.restype = c_void_p +isl.isl_union_pw_aff_intersect_domain_space.argtypes = [c_void_p, c_void_p] +isl.isl_union_pw_aff_intersect_domain_union_set.restype = c_void_p +isl.isl_union_pw_aff_intersect_domain_union_set.argtypes = [c_void_p, c_void_p] +isl.isl_union_pw_aff_intersect_domain_wrapped_domain.restype = c_void_p +isl.isl_union_pw_aff_intersect_domain_wrapped_domain.argtypes = [c_void_p, c_void_p] +isl.isl_union_pw_aff_intersect_domain_wrapped_range.restype = c_void_p +isl.isl_union_pw_aff_intersect_domain_wrapped_range.argtypes = [c_void_p, c_void_p] +isl.isl_union_pw_aff_intersect_params.restype = c_void_p +isl.isl_union_pw_aff_intersect_params.argtypes = [c_void_p, c_void_p] +isl.isl_union_pw_aff_plain_is_equal.argtypes = [c_void_p, c_void_p] +isl.isl_union_pw_aff_pullback_union_pw_multi_aff.restype = c_void_p +isl.isl_union_pw_aff_pullback_union_pw_multi_aff.argtypes = [c_void_p, c_void_p] +isl.isl_union_pw_aff_get_space.restype = c_void_p +isl.isl_union_pw_aff_get_space.argtypes = [c_void_p] +isl.isl_union_pw_aff_sub.restype = c_void_p +isl.isl_union_pw_aff_sub.argtypes = [c_void_p, c_void_p] +isl.isl_union_pw_aff_subtract_domain_space.restype = c_void_p +isl.isl_union_pw_aff_subtract_domain_space.argtypes = [c_void_p, c_void_p] +isl.isl_union_pw_aff_subtract_domain_union_set.restype = c_void_p +isl.isl_union_pw_aff_subtract_domain_union_set.argtypes = [c_void_p, c_void_p] +isl.isl_union_pw_aff_to_list.restype = c_void_p +isl.isl_union_pw_aff_to_list.argtypes = [c_void_p] +isl.isl_union_pw_aff_union_add.restype = c_void_p +isl.isl_union_pw_aff_union_add.argtypes = [c_void_p, c_void_p] +isl.isl_union_pw_aff_copy.restype = c_void_p +isl.isl_union_pw_aff_copy.argtypes = [c_void_p] +isl.isl_union_pw_aff_free.restype = c_void_p +isl.isl_union_pw_aff_free.argtypes = [c_void_p] +isl.isl_union_pw_aff_to_str.restype = POINTER(c_char) +isl.isl_union_pw_aff_to_str.argtypes = [c_void_p] + +class multi_pw_aff(multi_union_pw_aff): + def __init__(self, *args, **keywords): + if "ptr" in keywords: + self.ctx = keywords["ctx"] + self.ptr = keywords["ptr"] + return + if len(args) == 1 and args[0].__class__ is aff: + self.ctx = Context.getDefaultInstance() + self.ptr = isl.isl_multi_pw_aff_from_aff(isl.isl_aff_copy(args[0].ptr)) + return + if len(args) == 1 and args[0].__class__ is multi_aff: + self.ctx = Context.getDefaultInstance() + self.ptr = isl.isl_multi_pw_aff_from_multi_aff(isl.isl_multi_aff_copy(args[0].ptr)) + return + if len(args) == 1 and args[0].__class__ is pw_aff: + self.ctx = Context.getDefaultInstance() + self.ptr = isl.isl_multi_pw_aff_from_pw_aff(isl.isl_pw_aff_copy(args[0].ptr)) + return + if len(args) == 2 and args[0].__class__ is space and args[1].__class__ is pw_aff_list: + self.ctx = Context.getDefaultInstance() + self.ptr = isl.isl_multi_pw_aff_from_pw_aff_list(isl.isl_space_copy(args[0].ptr), isl.isl_pw_aff_list_copy(args[1].ptr)) + return + if len(args) == 1 and args[0].__class__ is pw_multi_aff: + self.ctx = Context.getDefaultInstance() + self.ptr = isl.isl_multi_pw_aff_from_pw_multi_aff(isl.isl_pw_multi_aff_copy(args[0].ptr)) + return + if len(args) == 1 and type(args[0]) == str: + self.ctx = Context.getDefaultInstance() + self.ptr = isl.isl_multi_pw_aff_read_from_str(self.ctx, args[0].encode('ascii')) + return + raise Error + def __del__(self): + if hasattr(self, 'ptr'): + isl.isl_multi_pw_aff_free(self.ptr) + def __str__(arg0): + try: + if not arg0.__class__ is multi_pw_aff: + arg0 = multi_pw_aff(arg0) + except: + raise + ptr = isl.isl_multi_pw_aff_to_str(arg0.ptr) + res = cast(ptr, c_char_p).value.decode('ascii') + libc.free(ptr) + return res + def __repr__(self): + s = str(self) + if '"' in s: + return 'isl.multi_pw_aff("""%s""")' % s + else: + return 'isl.multi_pw_aff("%s")' % s + def add(arg0, arg1): + try: + if not arg0.__class__ is multi_pw_aff: + arg0 = multi_pw_aff(arg0) + except: + raise + try: + if not arg1.__class__ is multi_pw_aff: + arg1 = multi_pw_aff(arg1) + except: + return multi_union_pw_aff(arg0).add(arg1) + ctx = arg0.ctx + res = isl.isl_multi_pw_aff_add(isl.isl_multi_pw_aff_copy(arg0.ptr), isl.isl_multi_pw_aff_copy(arg1.ptr)) + obj = multi_pw_aff(ctx=ctx, ptr=res) + return obj + def add_constant(*args): + if len(args) == 2 and args[1].__class__ is multi_val: + args = list(args) + try: + if not args[0].__class__ is multi_pw_aff: + args[0] = multi_pw_aff(args[0]) + except: + raise + ctx = args[0].ctx + res = isl.isl_multi_pw_aff_add_constant_multi_val(isl.isl_multi_pw_aff_copy(args[0].ptr), isl.isl_multi_val_copy(args[1].ptr)) + obj = multi_pw_aff(ctx=ctx, ptr=res) + return obj + if len(args) == 2 and (args[1].__class__ is val or type(args[1]) == int): + args = list(args) + try: + if not args[0].__class__ is multi_pw_aff: + args[0] = multi_pw_aff(args[0]) + except: + raise + try: + if not args[1].__class__ is val: + args[1] = val(args[1]) + except: + raise + ctx = args[0].ctx + res = isl.isl_multi_pw_aff_add_constant_val(isl.isl_multi_pw_aff_copy(args[0].ptr), isl.isl_val_copy(args[1].ptr)) + obj = multi_pw_aff(ctx=ctx, ptr=res) + return obj + raise Error + def as_map(arg0): + try: + if not arg0.__class__ is multi_pw_aff: + arg0 = multi_pw_aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_multi_pw_aff_as_map(isl.isl_multi_pw_aff_copy(arg0.ptr)) + obj = map(ctx=ctx, ptr=res) + return obj + def as_multi_aff(arg0): + try: + if not arg0.__class__ is multi_pw_aff: + arg0 = multi_pw_aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_multi_pw_aff_as_multi_aff(isl.isl_multi_pw_aff_copy(arg0.ptr)) + obj = multi_aff(ctx=ctx, ptr=res) + return obj + def as_set(arg0): + try: + if not arg0.__class__ is multi_pw_aff: + arg0 = multi_pw_aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_multi_pw_aff_as_set(isl.isl_multi_pw_aff_copy(arg0.ptr)) + obj = set(ctx=ctx, ptr=res) + return obj + def at(arg0, arg1): + try: + if not arg0.__class__ is multi_pw_aff: + arg0 = multi_pw_aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_multi_pw_aff_get_at(arg0.ptr, arg1) + obj = pw_aff(ctx=ctx, ptr=res) + return obj + def get_at(arg0, arg1): + return arg0.at(arg1) + def bind(arg0, arg1): + try: + if not arg0.__class__ is multi_pw_aff: + arg0 = multi_pw_aff(arg0) + except: + raise + try: + if not arg1.__class__ is multi_id: + arg1 = multi_id(arg1) + except: + return multi_union_pw_aff(arg0).bind(arg1) + ctx = arg0.ctx + res = isl.isl_multi_pw_aff_bind(isl.isl_multi_pw_aff_copy(arg0.ptr), isl.isl_multi_id_copy(arg1.ptr)) + obj = set(ctx=ctx, ptr=res) + return obj + def bind_domain(arg0, arg1): + try: + if not arg0.__class__ is multi_pw_aff: + arg0 = multi_pw_aff(arg0) + except: + raise + try: + if not arg1.__class__ is multi_id: + arg1 = multi_id(arg1) + except: + return multi_union_pw_aff(arg0).bind_domain(arg1) + ctx = arg0.ctx + res = isl.isl_multi_pw_aff_bind_domain(isl.isl_multi_pw_aff_copy(arg0.ptr), isl.isl_multi_id_copy(arg1.ptr)) + obj = multi_pw_aff(ctx=ctx, ptr=res) + return obj + def bind_domain_wrapped_domain(arg0, arg1): + try: + if not arg0.__class__ is multi_pw_aff: + arg0 = multi_pw_aff(arg0) + except: + raise + try: + if not arg1.__class__ is multi_id: + arg1 = multi_id(arg1) + except: + return multi_union_pw_aff(arg0).bind_domain_wrapped_domain(arg1) + ctx = arg0.ctx + res = isl.isl_multi_pw_aff_bind_domain_wrapped_domain(isl.isl_multi_pw_aff_copy(arg0.ptr), isl.isl_multi_id_copy(arg1.ptr)) + obj = multi_pw_aff(ctx=ctx, ptr=res) + return obj + def coalesce(arg0): + try: + if not arg0.__class__ is multi_pw_aff: + arg0 = multi_pw_aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_multi_pw_aff_coalesce(isl.isl_multi_pw_aff_copy(arg0.ptr)) + obj = multi_pw_aff(ctx=ctx, ptr=res) + return obj + def domain(arg0): + try: + if not arg0.__class__ is multi_pw_aff: + arg0 = multi_pw_aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_multi_pw_aff_domain(isl.isl_multi_pw_aff_copy(arg0.ptr)) + obj = set(ctx=ctx, ptr=res) + return obj + def domain_reverse(arg0): + try: + if not arg0.__class__ is multi_pw_aff: + arg0 = multi_pw_aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_multi_pw_aff_domain_reverse(isl.isl_multi_pw_aff_copy(arg0.ptr)) + obj = multi_pw_aff(ctx=ctx, ptr=res) + return obj + def flat_range_product(arg0, arg1): + try: + if not arg0.__class__ is multi_pw_aff: + arg0 = multi_pw_aff(arg0) + except: + raise + try: + if not arg1.__class__ is multi_pw_aff: + arg1 = multi_pw_aff(arg1) + except: + return multi_union_pw_aff(arg0).flat_range_product(arg1) + ctx = arg0.ctx + res = isl.isl_multi_pw_aff_flat_range_product(isl.isl_multi_pw_aff_copy(arg0.ptr), isl.isl_multi_pw_aff_copy(arg1.ptr)) + obj = multi_pw_aff(ctx=ctx, ptr=res) + return obj + def gist(arg0, arg1): + try: + if not arg0.__class__ is multi_pw_aff: + arg0 = multi_pw_aff(arg0) + except: + raise + try: + if not arg1.__class__ is set: + arg1 = set(arg1) + except: + return multi_union_pw_aff(arg0).gist(arg1) + ctx = arg0.ctx + res = isl.isl_multi_pw_aff_gist(isl.isl_multi_pw_aff_copy(arg0.ptr), isl.isl_set_copy(arg1.ptr)) + obj = multi_pw_aff(ctx=ctx, ptr=res) + return obj + def gist_params(arg0, arg1): + try: + if not arg0.__class__ is multi_pw_aff: + arg0 = multi_pw_aff(arg0) + except: + raise + try: + if not arg1.__class__ is set: + arg1 = set(arg1) + except: + return multi_union_pw_aff(arg0).gist_params(arg1) + ctx = arg0.ctx + res = isl.isl_multi_pw_aff_gist_params(isl.isl_multi_pw_aff_copy(arg0.ptr), isl.isl_set_copy(arg1.ptr)) + obj = multi_pw_aff(ctx=ctx, ptr=res) + return obj + def has_range_tuple_id(arg0): + try: + if not arg0.__class__ is multi_pw_aff: + arg0 = multi_pw_aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_multi_pw_aff_has_range_tuple_id(arg0.ptr) + if res < 0: + raise Error + return bool(res) + def identity(*args): + if len(args) == 1: + args = list(args) + try: + if not args[0].__class__ is multi_pw_aff: + args[0] = multi_pw_aff(args[0]) + except: + raise + ctx = args[0].ctx + res = isl.isl_multi_pw_aff_identity_multi_pw_aff(isl.isl_multi_pw_aff_copy(args[0].ptr)) + obj = multi_pw_aff(ctx=ctx, ptr=res) + return obj + raise Error + @staticmethod + def identity_on_domain(*args): + if len(args) == 1 and args[0].__class__ is space: + ctx = args[0].ctx + res = isl.isl_multi_pw_aff_identity_on_domain_space(isl.isl_space_copy(args[0].ptr)) + obj = multi_pw_aff(ctx=ctx, ptr=res) + return obj + raise Error + def insert_domain(arg0, arg1): + try: + if not arg0.__class__ is multi_pw_aff: + arg0 = multi_pw_aff(arg0) + except: + raise + try: + if not arg1.__class__ is space: + arg1 = space(arg1) + except: + return multi_union_pw_aff(arg0).insert_domain(arg1) + ctx = arg0.ctx + res = isl.isl_multi_pw_aff_insert_domain(isl.isl_multi_pw_aff_copy(arg0.ptr), isl.isl_space_copy(arg1.ptr)) + obj = multi_pw_aff(ctx=ctx, ptr=res) + return obj + def intersect_domain(arg0, arg1): + try: + if not arg0.__class__ is multi_pw_aff: + arg0 = multi_pw_aff(arg0) + except: + raise + try: + if not arg1.__class__ is set: + arg1 = set(arg1) + except: + return multi_union_pw_aff(arg0).intersect_domain(arg1) + ctx = arg0.ctx + res = isl.isl_multi_pw_aff_intersect_domain(isl.isl_multi_pw_aff_copy(arg0.ptr), isl.isl_set_copy(arg1.ptr)) + obj = multi_pw_aff(ctx=ctx, ptr=res) + return obj + def intersect_params(arg0, arg1): + try: + if not arg0.__class__ is multi_pw_aff: + arg0 = multi_pw_aff(arg0) + except: + raise + try: + if not arg1.__class__ is set: + arg1 = set(arg1) + except: + return multi_union_pw_aff(arg0).intersect_params(arg1) + ctx = arg0.ctx + res = isl.isl_multi_pw_aff_intersect_params(isl.isl_multi_pw_aff_copy(arg0.ptr), isl.isl_set_copy(arg1.ptr)) + obj = multi_pw_aff(ctx=ctx, ptr=res) + return obj + def involves_nan(arg0): + try: + if not arg0.__class__ is multi_pw_aff: + arg0 = multi_pw_aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_multi_pw_aff_involves_nan(arg0.ptr) + if res < 0: + raise Error + return bool(res) + def involves_param(*args): + if len(args) == 2 and (args[1].__class__ is id or type(args[1]) == str): + args = list(args) + try: + if not args[0].__class__ is multi_pw_aff: + args[0] = multi_pw_aff(args[0]) + except: + raise + try: + if not args[1].__class__ is id: + args[1] = id(args[1]) + except: + raise + ctx = args[0].ctx + res = isl.isl_multi_pw_aff_involves_param_id(args[0].ptr, args[1].ptr) + if res < 0: + raise Error + return bool(res) + if len(args) == 2 and args[1].__class__ is id_list: + args = list(args) + try: + if not args[0].__class__ is multi_pw_aff: + args[0] = multi_pw_aff(args[0]) + except: + raise + ctx = args[0].ctx + res = isl.isl_multi_pw_aff_involves_param_id_list(args[0].ptr, args[1].ptr) + if res < 0: + raise Error + return bool(res) + raise Error + def isa_multi_aff(arg0): + try: + if not arg0.__class__ is multi_pw_aff: + arg0 = multi_pw_aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_multi_pw_aff_isa_multi_aff(arg0.ptr) + if res < 0: + raise Error + return bool(res) + def list(arg0): + try: + if not arg0.__class__ is multi_pw_aff: + arg0 = multi_pw_aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_multi_pw_aff_get_list(arg0.ptr) + obj = pw_aff_list(ctx=ctx, ptr=res) + return obj + def get_list(arg0): + return arg0.list() + def max(arg0, arg1): + try: + if not arg0.__class__ is multi_pw_aff: + arg0 = multi_pw_aff(arg0) + except: + raise + try: + if not arg1.__class__ is multi_pw_aff: + arg1 = multi_pw_aff(arg1) + except: + return multi_union_pw_aff(arg0).max(arg1) + ctx = arg0.ctx + res = isl.isl_multi_pw_aff_max(isl.isl_multi_pw_aff_copy(arg0.ptr), isl.isl_multi_pw_aff_copy(arg1.ptr)) + obj = multi_pw_aff(ctx=ctx, ptr=res) + return obj + def max_multi_val(arg0): + try: + if not arg0.__class__ is multi_pw_aff: + arg0 = multi_pw_aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_multi_pw_aff_max_multi_val(isl.isl_multi_pw_aff_copy(arg0.ptr)) + obj = multi_val(ctx=ctx, ptr=res) + return obj + def min(arg0, arg1): + try: + if not arg0.__class__ is multi_pw_aff: + arg0 = multi_pw_aff(arg0) + except: + raise + try: + if not arg1.__class__ is multi_pw_aff: + arg1 = multi_pw_aff(arg1) + except: + return multi_union_pw_aff(arg0).min(arg1) + ctx = arg0.ctx + res = isl.isl_multi_pw_aff_min(isl.isl_multi_pw_aff_copy(arg0.ptr), isl.isl_multi_pw_aff_copy(arg1.ptr)) + obj = multi_pw_aff(ctx=ctx, ptr=res) + return obj + def min_multi_val(arg0): + try: + if not arg0.__class__ is multi_pw_aff: + arg0 = multi_pw_aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_multi_pw_aff_min_multi_val(isl.isl_multi_pw_aff_copy(arg0.ptr)) + obj = multi_val(ctx=ctx, ptr=res) + return obj + def neg(arg0): + try: + if not arg0.__class__ is multi_pw_aff: + arg0 = multi_pw_aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_multi_pw_aff_neg(isl.isl_multi_pw_aff_copy(arg0.ptr)) + obj = multi_pw_aff(ctx=ctx, ptr=res) + return obj + def plain_is_equal(arg0, arg1): + try: + if not arg0.__class__ is multi_pw_aff: + arg0 = multi_pw_aff(arg0) + except: + raise + try: + if not arg1.__class__ is multi_pw_aff: + arg1 = multi_pw_aff(arg1) + except: + return multi_union_pw_aff(arg0).plain_is_equal(arg1) + ctx = arg0.ctx + res = isl.isl_multi_pw_aff_plain_is_equal(arg0.ptr, arg1.ptr) + if res < 0: + raise Error + return bool(res) + def product(arg0, arg1): + try: + if not arg0.__class__ is multi_pw_aff: + arg0 = multi_pw_aff(arg0) + except: + raise + try: + if not arg1.__class__ is multi_pw_aff: + arg1 = multi_pw_aff(arg1) + except: + return multi_union_pw_aff(arg0).product(arg1) + ctx = arg0.ctx + res = isl.isl_multi_pw_aff_product(isl.isl_multi_pw_aff_copy(arg0.ptr), isl.isl_multi_pw_aff_copy(arg1.ptr)) + obj = multi_pw_aff(ctx=ctx, ptr=res) + return obj + def pullback(*args): + if len(args) == 2 and args[1].__class__ is multi_aff: + args = list(args) + try: + if not args[0].__class__ is multi_pw_aff: + args[0] = multi_pw_aff(args[0]) + except: + raise + ctx = args[0].ctx + res = isl.isl_multi_pw_aff_pullback_multi_aff(isl.isl_multi_pw_aff_copy(args[0].ptr), isl.isl_multi_aff_copy(args[1].ptr)) + obj = multi_pw_aff(ctx=ctx, ptr=res) + return obj + if len(args) == 2 and args[1].__class__ is multi_pw_aff: + args = list(args) + try: + if not args[0].__class__ is multi_pw_aff: + args[0] = multi_pw_aff(args[0]) + except: + raise + ctx = args[0].ctx + res = isl.isl_multi_pw_aff_pullback_multi_pw_aff(isl.isl_multi_pw_aff_copy(args[0].ptr), isl.isl_multi_pw_aff_copy(args[1].ptr)) + obj = multi_pw_aff(ctx=ctx, ptr=res) + return obj + if len(args) == 2 and args[1].__class__ is pw_multi_aff: + args = list(args) + try: + if not args[0].__class__ is multi_pw_aff: + args[0] = multi_pw_aff(args[0]) + except: + raise + ctx = args[0].ctx + res = isl.isl_multi_pw_aff_pullback_pw_multi_aff(isl.isl_multi_pw_aff_copy(args[0].ptr), isl.isl_pw_multi_aff_copy(args[1].ptr)) + obj = multi_pw_aff(ctx=ctx, ptr=res) + return obj + raise Error + def range_product(arg0, arg1): + try: + if not arg0.__class__ is multi_pw_aff: + arg0 = multi_pw_aff(arg0) + except: + raise + try: + if not arg1.__class__ is multi_pw_aff: + arg1 = multi_pw_aff(arg1) + except: + return multi_union_pw_aff(arg0).range_product(arg1) + ctx = arg0.ctx + res = isl.isl_multi_pw_aff_range_product(isl.isl_multi_pw_aff_copy(arg0.ptr), isl.isl_multi_pw_aff_copy(arg1.ptr)) + obj = multi_pw_aff(ctx=ctx, ptr=res) + return obj + def range_tuple_id(arg0): + try: + if not arg0.__class__ is multi_pw_aff: + arg0 = multi_pw_aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_multi_pw_aff_get_range_tuple_id(arg0.ptr) + obj = id(ctx=ctx, ptr=res) + return obj + def get_range_tuple_id(arg0): + return arg0.range_tuple_id() + def reset_range_tuple_id(arg0): + try: + if not arg0.__class__ is multi_pw_aff: + arg0 = multi_pw_aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_multi_pw_aff_reset_range_tuple_id(isl.isl_multi_pw_aff_copy(arg0.ptr)) + obj = multi_pw_aff(ctx=ctx, ptr=res) + return obj + def scale(*args): + if len(args) == 2 and args[1].__class__ is multi_val: + args = list(args) + try: + if not args[0].__class__ is multi_pw_aff: + args[0] = multi_pw_aff(args[0]) + except: + raise + ctx = args[0].ctx + res = isl.isl_multi_pw_aff_scale_multi_val(isl.isl_multi_pw_aff_copy(args[0].ptr), isl.isl_multi_val_copy(args[1].ptr)) + obj = multi_pw_aff(ctx=ctx, ptr=res) + return obj + if len(args) == 2 and (args[1].__class__ is val or type(args[1]) == int): + args = list(args) + try: + if not args[0].__class__ is multi_pw_aff: + args[0] = multi_pw_aff(args[0]) + except: + raise + try: + if not args[1].__class__ is val: + args[1] = val(args[1]) + except: + raise + ctx = args[0].ctx + res = isl.isl_multi_pw_aff_scale_val(isl.isl_multi_pw_aff_copy(args[0].ptr), isl.isl_val_copy(args[1].ptr)) + obj = multi_pw_aff(ctx=ctx, ptr=res) + return obj + raise Error + def scale_down(*args): + if len(args) == 2 and args[1].__class__ is multi_val: + args = list(args) + try: + if not args[0].__class__ is multi_pw_aff: + args[0] = multi_pw_aff(args[0]) + except: + raise + ctx = args[0].ctx + res = isl.isl_multi_pw_aff_scale_down_multi_val(isl.isl_multi_pw_aff_copy(args[0].ptr), isl.isl_multi_val_copy(args[1].ptr)) + obj = multi_pw_aff(ctx=ctx, ptr=res) + return obj + if len(args) == 2 and (args[1].__class__ is val or type(args[1]) == int): + args = list(args) + try: + if not args[0].__class__ is multi_pw_aff: + args[0] = multi_pw_aff(args[0]) + except: + raise + try: + if not args[1].__class__ is val: + args[1] = val(args[1]) + except: + raise + ctx = args[0].ctx + res = isl.isl_multi_pw_aff_scale_down_val(isl.isl_multi_pw_aff_copy(args[0].ptr), isl.isl_val_copy(args[1].ptr)) + obj = multi_pw_aff(ctx=ctx, ptr=res) + return obj + raise Error + def set_at(arg0, arg1, arg2): + try: + if not arg0.__class__ is multi_pw_aff: + arg0 = multi_pw_aff(arg0) + except: + raise + try: + if not arg2.__class__ is pw_aff: + arg2 = pw_aff(arg2) + except: + return multi_union_pw_aff(arg0).set_at(arg1, arg2) + ctx = arg0.ctx + res = isl.isl_multi_pw_aff_set_at(isl.isl_multi_pw_aff_copy(arg0.ptr), arg1, isl.isl_pw_aff_copy(arg2.ptr)) + obj = multi_pw_aff(ctx=ctx, ptr=res) + return obj + def set_range_tuple(*args): + if len(args) == 2 and (args[1].__class__ is id or type(args[1]) == str): + args = list(args) + try: + if not args[0].__class__ is multi_pw_aff: + args[0] = multi_pw_aff(args[0]) + except: + raise + try: + if not args[1].__class__ is id: + args[1] = id(args[1]) + except: + raise + ctx = args[0].ctx + res = isl.isl_multi_pw_aff_set_range_tuple_id(isl.isl_multi_pw_aff_copy(args[0].ptr), isl.isl_id_copy(args[1].ptr)) + obj = multi_pw_aff(ctx=ctx, ptr=res) + return obj + raise Error + def size(arg0): + try: + if not arg0.__class__ is multi_pw_aff: + arg0 = multi_pw_aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_multi_pw_aff_size(arg0.ptr) + if res < 0: + raise Error + return int(res) + def space(arg0): + try: + if not arg0.__class__ is multi_pw_aff: + arg0 = multi_pw_aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_multi_pw_aff_get_space(arg0.ptr) + obj = space(ctx=ctx, ptr=res) + return obj + def get_space(arg0): + return arg0.space() + def sub(arg0, arg1): + try: + if not arg0.__class__ is multi_pw_aff: + arg0 = multi_pw_aff(arg0) + except: + raise + try: + if not arg1.__class__ is multi_pw_aff: + arg1 = multi_pw_aff(arg1) + except: + return multi_union_pw_aff(arg0).sub(arg1) + ctx = arg0.ctx + res = isl.isl_multi_pw_aff_sub(isl.isl_multi_pw_aff_copy(arg0.ptr), isl.isl_multi_pw_aff_copy(arg1.ptr)) + obj = multi_pw_aff(ctx=ctx, ptr=res) + return obj + def unbind_params_insert_domain(arg0, arg1): + try: + if not arg0.__class__ is multi_pw_aff: + arg0 = multi_pw_aff(arg0) + except: + raise + try: + if not arg1.__class__ is multi_id: + arg1 = multi_id(arg1) + except: + return multi_union_pw_aff(arg0).unbind_params_insert_domain(arg1) + ctx = arg0.ctx + res = isl.isl_multi_pw_aff_unbind_params_insert_domain(isl.isl_multi_pw_aff_copy(arg0.ptr), isl.isl_multi_id_copy(arg1.ptr)) + obj = multi_pw_aff(ctx=ctx, ptr=res) + return obj + def union_add(arg0, arg1): + try: + if not arg0.__class__ is multi_pw_aff: + arg0 = multi_pw_aff(arg0) + except: + raise + try: + if not arg1.__class__ is multi_pw_aff: + arg1 = multi_pw_aff(arg1) + except: + return multi_union_pw_aff(arg0).union_add(arg1) + ctx = arg0.ctx + res = isl.isl_multi_pw_aff_union_add(isl.isl_multi_pw_aff_copy(arg0.ptr), isl.isl_multi_pw_aff_copy(arg1.ptr)) + obj = multi_pw_aff(ctx=ctx, ptr=res) + return obj + @staticmethod + def zero(arg0): + try: + if not arg0.__class__ is space: + arg0 = space(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_multi_pw_aff_zero(isl.isl_space_copy(arg0.ptr)) + obj = multi_pw_aff(ctx=ctx, ptr=res) + return obj + +isl.isl_multi_pw_aff_from_aff.restype = c_void_p +isl.isl_multi_pw_aff_from_aff.argtypes = [c_void_p] +isl.isl_multi_pw_aff_from_multi_aff.restype = c_void_p +isl.isl_multi_pw_aff_from_multi_aff.argtypes = [c_void_p] +isl.isl_multi_pw_aff_from_pw_aff.restype = c_void_p +isl.isl_multi_pw_aff_from_pw_aff.argtypes = [c_void_p] +isl.isl_multi_pw_aff_from_pw_aff_list.restype = c_void_p +isl.isl_multi_pw_aff_from_pw_aff_list.argtypes = [c_void_p, c_void_p] +isl.isl_multi_pw_aff_from_pw_multi_aff.restype = c_void_p +isl.isl_multi_pw_aff_from_pw_multi_aff.argtypes = [c_void_p] +isl.isl_multi_pw_aff_read_from_str.restype = c_void_p +isl.isl_multi_pw_aff_read_from_str.argtypes = [Context, c_char_p] +isl.isl_multi_pw_aff_add.restype = c_void_p +isl.isl_multi_pw_aff_add.argtypes = [c_void_p, c_void_p] +isl.isl_multi_pw_aff_add_constant_multi_val.restype = c_void_p +isl.isl_multi_pw_aff_add_constant_multi_val.argtypes = [c_void_p, c_void_p] +isl.isl_multi_pw_aff_add_constant_val.restype = c_void_p +isl.isl_multi_pw_aff_add_constant_val.argtypes = [c_void_p, c_void_p] +isl.isl_multi_pw_aff_as_map.restype = c_void_p +isl.isl_multi_pw_aff_as_map.argtypes = [c_void_p] +isl.isl_multi_pw_aff_as_multi_aff.restype = c_void_p +isl.isl_multi_pw_aff_as_multi_aff.argtypes = [c_void_p] +isl.isl_multi_pw_aff_as_set.restype = c_void_p +isl.isl_multi_pw_aff_as_set.argtypes = [c_void_p] +isl.isl_multi_pw_aff_get_at.restype = c_void_p +isl.isl_multi_pw_aff_get_at.argtypes = [c_void_p, c_int] +isl.isl_multi_pw_aff_bind.restype = c_void_p +isl.isl_multi_pw_aff_bind.argtypes = [c_void_p, c_void_p] +isl.isl_multi_pw_aff_bind_domain.restype = c_void_p +isl.isl_multi_pw_aff_bind_domain.argtypes = [c_void_p, c_void_p] +isl.isl_multi_pw_aff_bind_domain_wrapped_domain.restype = c_void_p +isl.isl_multi_pw_aff_bind_domain_wrapped_domain.argtypes = [c_void_p, c_void_p] +isl.isl_multi_pw_aff_coalesce.restype = c_void_p +isl.isl_multi_pw_aff_coalesce.argtypes = [c_void_p] +isl.isl_multi_pw_aff_domain.restype = c_void_p +isl.isl_multi_pw_aff_domain.argtypes = [c_void_p] +isl.isl_multi_pw_aff_domain_reverse.restype = c_void_p +isl.isl_multi_pw_aff_domain_reverse.argtypes = [c_void_p] +isl.isl_multi_pw_aff_flat_range_product.restype = c_void_p +isl.isl_multi_pw_aff_flat_range_product.argtypes = [c_void_p, c_void_p] +isl.isl_multi_pw_aff_gist.restype = c_void_p +isl.isl_multi_pw_aff_gist.argtypes = [c_void_p, c_void_p] +isl.isl_multi_pw_aff_gist_params.restype = c_void_p +isl.isl_multi_pw_aff_gist_params.argtypes = [c_void_p, c_void_p] +isl.isl_multi_pw_aff_has_range_tuple_id.argtypes = [c_void_p] +isl.isl_multi_pw_aff_identity_multi_pw_aff.restype = c_void_p +isl.isl_multi_pw_aff_identity_multi_pw_aff.argtypes = [c_void_p] +isl.isl_multi_pw_aff_identity_on_domain_space.restype = c_void_p +isl.isl_multi_pw_aff_identity_on_domain_space.argtypes = [c_void_p] +isl.isl_multi_pw_aff_insert_domain.restype = c_void_p +isl.isl_multi_pw_aff_insert_domain.argtypes = [c_void_p, c_void_p] +isl.isl_multi_pw_aff_intersect_domain.restype = c_void_p +isl.isl_multi_pw_aff_intersect_domain.argtypes = [c_void_p, c_void_p] +isl.isl_multi_pw_aff_intersect_params.restype = c_void_p +isl.isl_multi_pw_aff_intersect_params.argtypes = [c_void_p, c_void_p] +isl.isl_multi_pw_aff_involves_nan.argtypes = [c_void_p] +isl.isl_multi_pw_aff_involves_param_id.argtypes = [c_void_p, c_void_p] +isl.isl_multi_pw_aff_involves_param_id_list.argtypes = [c_void_p, c_void_p] +isl.isl_multi_pw_aff_isa_multi_aff.argtypes = [c_void_p] +isl.isl_multi_pw_aff_get_list.restype = c_void_p +isl.isl_multi_pw_aff_get_list.argtypes = [c_void_p] +isl.isl_multi_pw_aff_max.restype = c_void_p +isl.isl_multi_pw_aff_max.argtypes = [c_void_p, c_void_p] +isl.isl_multi_pw_aff_max_multi_val.restype = c_void_p +isl.isl_multi_pw_aff_max_multi_val.argtypes = [c_void_p] +isl.isl_multi_pw_aff_min.restype = c_void_p +isl.isl_multi_pw_aff_min.argtypes = [c_void_p, c_void_p] +isl.isl_multi_pw_aff_min_multi_val.restype = c_void_p +isl.isl_multi_pw_aff_min_multi_val.argtypes = [c_void_p] +isl.isl_multi_pw_aff_neg.restype = c_void_p +isl.isl_multi_pw_aff_neg.argtypes = [c_void_p] +isl.isl_multi_pw_aff_plain_is_equal.argtypes = [c_void_p, c_void_p] +isl.isl_multi_pw_aff_product.restype = c_void_p +isl.isl_multi_pw_aff_product.argtypes = [c_void_p, c_void_p] +isl.isl_multi_pw_aff_pullback_multi_aff.restype = c_void_p +isl.isl_multi_pw_aff_pullback_multi_aff.argtypes = [c_void_p, c_void_p] +isl.isl_multi_pw_aff_pullback_multi_pw_aff.restype = c_void_p +isl.isl_multi_pw_aff_pullback_multi_pw_aff.argtypes = [c_void_p, c_void_p] +isl.isl_multi_pw_aff_pullback_pw_multi_aff.restype = c_void_p +isl.isl_multi_pw_aff_pullback_pw_multi_aff.argtypes = [c_void_p, c_void_p] +isl.isl_multi_pw_aff_range_product.restype = c_void_p +isl.isl_multi_pw_aff_range_product.argtypes = [c_void_p, c_void_p] +isl.isl_multi_pw_aff_get_range_tuple_id.restype = c_void_p +isl.isl_multi_pw_aff_get_range_tuple_id.argtypes = [c_void_p] +isl.isl_multi_pw_aff_reset_range_tuple_id.restype = c_void_p +isl.isl_multi_pw_aff_reset_range_tuple_id.argtypes = [c_void_p] +isl.isl_multi_pw_aff_scale_multi_val.restype = c_void_p +isl.isl_multi_pw_aff_scale_multi_val.argtypes = [c_void_p, c_void_p] +isl.isl_multi_pw_aff_scale_val.restype = c_void_p +isl.isl_multi_pw_aff_scale_val.argtypes = [c_void_p, c_void_p] +isl.isl_multi_pw_aff_scale_down_multi_val.restype = c_void_p +isl.isl_multi_pw_aff_scale_down_multi_val.argtypes = [c_void_p, c_void_p] +isl.isl_multi_pw_aff_scale_down_val.restype = c_void_p +isl.isl_multi_pw_aff_scale_down_val.argtypes = [c_void_p, c_void_p] +isl.isl_multi_pw_aff_set_at.restype = c_void_p +isl.isl_multi_pw_aff_set_at.argtypes = [c_void_p, c_int, c_void_p] +isl.isl_multi_pw_aff_set_range_tuple_id.restype = c_void_p +isl.isl_multi_pw_aff_set_range_tuple_id.argtypes = [c_void_p, c_void_p] +isl.isl_multi_pw_aff_size.argtypes = [c_void_p] +isl.isl_multi_pw_aff_get_space.restype = c_void_p +isl.isl_multi_pw_aff_get_space.argtypes = [c_void_p] +isl.isl_multi_pw_aff_sub.restype = c_void_p +isl.isl_multi_pw_aff_sub.argtypes = [c_void_p, c_void_p] +isl.isl_multi_pw_aff_unbind_params_insert_domain.restype = c_void_p +isl.isl_multi_pw_aff_unbind_params_insert_domain.argtypes = [c_void_p, c_void_p] +isl.isl_multi_pw_aff_union_add.restype = c_void_p +isl.isl_multi_pw_aff_union_add.argtypes = [c_void_p, c_void_p] +isl.isl_multi_pw_aff_zero.restype = c_void_p +isl.isl_multi_pw_aff_zero.argtypes = [c_void_p] +isl.isl_multi_pw_aff_copy.restype = c_void_p +isl.isl_multi_pw_aff_copy.argtypes = [c_void_p] +isl.isl_multi_pw_aff_free.restype = c_void_p +isl.isl_multi_pw_aff_free.argtypes = [c_void_p] +isl.isl_multi_pw_aff_to_str.restype = POINTER(c_char) +isl.isl_multi_pw_aff_to_str.argtypes = [c_void_p] + +class pw_multi_aff(union_pw_multi_aff, multi_pw_aff): + def __init__(self, *args, **keywords): + if "ptr" in keywords: + self.ctx = keywords["ctx"] + self.ptr = keywords["ptr"] + return + if len(args) == 1 and args[0].__class__ is multi_aff: + self.ctx = Context.getDefaultInstance() + self.ptr = isl.isl_pw_multi_aff_from_multi_aff(isl.isl_multi_aff_copy(args[0].ptr)) + return + if len(args) == 1 and args[0].__class__ is pw_aff: + self.ctx = Context.getDefaultInstance() + self.ptr = isl.isl_pw_multi_aff_from_pw_aff(isl.isl_pw_aff_copy(args[0].ptr)) + return + if len(args) == 1 and type(args[0]) == str: + self.ctx = Context.getDefaultInstance() + self.ptr = isl.isl_pw_multi_aff_read_from_str(self.ctx, args[0].encode('ascii')) + return + raise Error + def __del__(self): + if hasattr(self, 'ptr'): + isl.isl_pw_multi_aff_free(self.ptr) + def __str__(arg0): + try: + if not arg0.__class__ is pw_multi_aff: + arg0 = pw_multi_aff(arg0) + except: + raise + ptr = isl.isl_pw_multi_aff_to_str(arg0.ptr) + res = cast(ptr, c_char_p).value.decode('ascii') + libc.free(ptr) + return res + def __repr__(self): + s = str(self) + if '"' in s: + return 'isl.pw_multi_aff("""%s""")' % s + else: + return 'isl.pw_multi_aff("%s")' % s + def add(arg0, arg1): + try: + if not arg0.__class__ is pw_multi_aff: + arg0 = pw_multi_aff(arg0) + except: + raise + try: + if not arg1.__class__ is pw_multi_aff: + arg1 = pw_multi_aff(arg1) + except: + return union_pw_multi_aff(arg0).add(arg1) + ctx = arg0.ctx + res = isl.isl_pw_multi_aff_add(isl.isl_pw_multi_aff_copy(arg0.ptr), isl.isl_pw_multi_aff_copy(arg1.ptr)) + obj = pw_multi_aff(ctx=ctx, ptr=res) + return obj + def add_constant(*args): + if len(args) == 2 and args[1].__class__ is multi_val: + args = list(args) + try: + if not args[0].__class__ is pw_multi_aff: + args[0] = pw_multi_aff(args[0]) + except: + raise + ctx = args[0].ctx + res = isl.isl_pw_multi_aff_add_constant_multi_val(isl.isl_pw_multi_aff_copy(args[0].ptr), isl.isl_multi_val_copy(args[1].ptr)) + obj = pw_multi_aff(ctx=ctx, ptr=res) + return obj + if len(args) == 2 and (args[1].__class__ is val or type(args[1]) == int): + args = list(args) + try: + if not args[0].__class__ is pw_multi_aff: + args[0] = pw_multi_aff(args[0]) + except: + raise + try: + if not args[1].__class__ is val: + args[1] = val(args[1]) + except: + raise + ctx = args[0].ctx + res = isl.isl_pw_multi_aff_add_constant_val(isl.isl_pw_multi_aff_copy(args[0].ptr), isl.isl_val_copy(args[1].ptr)) + obj = pw_multi_aff(ctx=ctx, ptr=res) + return obj + raise Error + def as_map(arg0): + try: + if not arg0.__class__ is pw_multi_aff: + arg0 = pw_multi_aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_pw_multi_aff_as_map(isl.isl_pw_multi_aff_copy(arg0.ptr)) + obj = map(ctx=ctx, ptr=res) + return obj + def as_multi_aff(arg0): + try: + if not arg0.__class__ is pw_multi_aff: + arg0 = pw_multi_aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_pw_multi_aff_as_multi_aff(isl.isl_pw_multi_aff_copy(arg0.ptr)) + obj = multi_aff(ctx=ctx, ptr=res) + return obj + def as_set(arg0): + try: + if not arg0.__class__ is pw_multi_aff: + arg0 = pw_multi_aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_pw_multi_aff_as_set(isl.isl_pw_multi_aff_copy(arg0.ptr)) + obj = set(ctx=ctx, ptr=res) + return obj + def at(arg0, arg1): + try: + if not arg0.__class__ is pw_multi_aff: + arg0 = pw_multi_aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_pw_multi_aff_get_at(arg0.ptr, arg1) + obj = pw_aff(ctx=ctx, ptr=res) + return obj + def get_at(arg0, arg1): + return arg0.at(arg1) + def bind_domain(arg0, arg1): + try: + if not arg0.__class__ is pw_multi_aff: + arg0 = pw_multi_aff(arg0) + except: + raise + try: + if not arg1.__class__ is multi_id: + arg1 = multi_id(arg1) + except: + return union_pw_multi_aff(arg0).bind_domain(arg1) + ctx = arg0.ctx + res = isl.isl_pw_multi_aff_bind_domain(isl.isl_pw_multi_aff_copy(arg0.ptr), isl.isl_multi_id_copy(arg1.ptr)) + obj = pw_multi_aff(ctx=ctx, ptr=res) + return obj + def bind_domain_wrapped_domain(arg0, arg1): + try: + if not arg0.__class__ is pw_multi_aff: + arg0 = pw_multi_aff(arg0) + except: + raise + try: + if not arg1.__class__ is multi_id: + arg1 = multi_id(arg1) + except: + return union_pw_multi_aff(arg0).bind_domain_wrapped_domain(arg1) + ctx = arg0.ctx + res = isl.isl_pw_multi_aff_bind_domain_wrapped_domain(isl.isl_pw_multi_aff_copy(arg0.ptr), isl.isl_multi_id_copy(arg1.ptr)) + obj = pw_multi_aff(ctx=ctx, ptr=res) + return obj + def coalesce(arg0): + try: + if not arg0.__class__ is pw_multi_aff: + arg0 = pw_multi_aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_pw_multi_aff_coalesce(isl.isl_pw_multi_aff_copy(arg0.ptr)) + obj = pw_multi_aff(ctx=ctx, ptr=res) + return obj + def domain(arg0): + try: + if not arg0.__class__ is pw_multi_aff: + arg0 = pw_multi_aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_pw_multi_aff_domain(isl.isl_pw_multi_aff_copy(arg0.ptr)) + obj = set(ctx=ctx, ptr=res) + return obj + @staticmethod + def domain_map(arg0): + try: + if not arg0.__class__ is space: + arg0 = space(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_pw_multi_aff_domain_map(isl.isl_space_copy(arg0.ptr)) + obj = pw_multi_aff(ctx=ctx, ptr=res) + return obj + def domain_reverse(arg0): + try: + if not arg0.__class__ is pw_multi_aff: + arg0 = pw_multi_aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_pw_multi_aff_domain_reverse(isl.isl_pw_multi_aff_copy(arg0.ptr)) + obj = pw_multi_aff(ctx=ctx, ptr=res) + return obj + def drop_unused_params(arg0): + try: + if not arg0.__class__ is pw_multi_aff: + arg0 = pw_multi_aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_pw_multi_aff_drop_unused_params(isl.isl_pw_multi_aff_copy(arg0.ptr)) + obj = pw_multi_aff(ctx=ctx, ptr=res) + return obj + def flat_range_product(arg0, arg1): + try: + if not arg0.__class__ is pw_multi_aff: + arg0 = pw_multi_aff(arg0) + except: + raise + try: + if not arg1.__class__ is pw_multi_aff: + arg1 = pw_multi_aff(arg1) + except: + return union_pw_multi_aff(arg0).flat_range_product(arg1) + ctx = arg0.ctx + res = isl.isl_pw_multi_aff_flat_range_product(isl.isl_pw_multi_aff_copy(arg0.ptr), isl.isl_pw_multi_aff_copy(arg1.ptr)) + obj = pw_multi_aff(ctx=ctx, ptr=res) + return obj + def foreach_piece(arg0, arg1): + try: + if not arg0.__class__ is pw_multi_aff: + arg0 = pw_multi_aff(arg0) + except: + raise + exc_info = [None] + fn = CFUNCTYPE(c_int, c_void_p, c_void_p, c_void_p) + def cb_func(cb_arg0, cb_arg1, cb_arg2): + cb_arg0 = set(ctx=arg0.ctx, ptr=(cb_arg0)) + cb_arg1 = multi_aff(ctx=arg0.ctx, ptr=(cb_arg1)) + try: + arg1(cb_arg0, cb_arg1) + except BaseException as e: + exc_info[0] = e + return -1 + return 0 + cb1 = fn(cb_func) + ctx = arg0.ctx + res = isl.isl_pw_multi_aff_foreach_piece(arg0.ptr, cb1, None) + if exc_info[0] is not None: + raise exc_info[0] + if res < 0: + raise Error + def gist(arg0, arg1): + try: + if not arg0.__class__ is pw_multi_aff: + arg0 = pw_multi_aff(arg0) + except: + raise + try: + if not arg1.__class__ is set: + arg1 = set(arg1) + except: + return union_pw_multi_aff(arg0).gist(arg1) + ctx = arg0.ctx + res = isl.isl_pw_multi_aff_gist(isl.isl_pw_multi_aff_copy(arg0.ptr), isl.isl_set_copy(arg1.ptr)) + obj = pw_multi_aff(ctx=ctx, ptr=res) + return obj + def gist_params(arg0, arg1): + try: + if not arg0.__class__ is pw_multi_aff: + arg0 = pw_multi_aff(arg0) + except: + raise + try: + if not arg1.__class__ is set: + arg1 = set(arg1) + except: + return union_pw_multi_aff(arg0).gist_params(arg1) + ctx = arg0.ctx + res = isl.isl_pw_multi_aff_gist_params(isl.isl_pw_multi_aff_copy(arg0.ptr), isl.isl_set_copy(arg1.ptr)) + obj = pw_multi_aff(ctx=ctx, ptr=res) + return obj + def has_range_tuple_id(arg0): + try: + if not arg0.__class__ is pw_multi_aff: + arg0 = pw_multi_aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_pw_multi_aff_has_range_tuple_id(arg0.ptr) + if res < 0: + raise Error + return bool(res) + @staticmethod + def identity_on_domain(*args): + if len(args) == 1 and args[0].__class__ is space: + ctx = args[0].ctx + res = isl.isl_pw_multi_aff_identity_on_domain_space(isl.isl_space_copy(args[0].ptr)) + obj = pw_multi_aff(ctx=ctx, ptr=res) + return obj + raise Error + def insert_domain(arg0, arg1): + try: + if not arg0.__class__ is pw_multi_aff: + arg0 = pw_multi_aff(arg0) + except: + raise + try: + if not arg1.__class__ is space: + arg1 = space(arg1) + except: + return union_pw_multi_aff(arg0).insert_domain(arg1) + ctx = arg0.ctx + res = isl.isl_pw_multi_aff_insert_domain(isl.isl_pw_multi_aff_copy(arg0.ptr), isl.isl_space_copy(arg1.ptr)) + obj = pw_multi_aff(ctx=ctx, ptr=res) + return obj + def intersect_domain(arg0, arg1): + try: + if not arg0.__class__ is pw_multi_aff: + arg0 = pw_multi_aff(arg0) + except: + raise + try: + if not arg1.__class__ is set: + arg1 = set(arg1) + except: + return union_pw_multi_aff(arg0).intersect_domain(arg1) + ctx = arg0.ctx + res = isl.isl_pw_multi_aff_intersect_domain(isl.isl_pw_multi_aff_copy(arg0.ptr), isl.isl_set_copy(arg1.ptr)) + obj = pw_multi_aff(ctx=ctx, ptr=res) + return obj + def intersect_params(arg0, arg1): + try: + if not arg0.__class__ is pw_multi_aff: + arg0 = pw_multi_aff(arg0) + except: + raise + try: + if not arg1.__class__ is set: + arg1 = set(arg1) + except: + return union_pw_multi_aff(arg0).intersect_params(arg1) + ctx = arg0.ctx + res = isl.isl_pw_multi_aff_intersect_params(isl.isl_pw_multi_aff_copy(arg0.ptr), isl.isl_set_copy(arg1.ptr)) + obj = pw_multi_aff(ctx=ctx, ptr=res) + return obj + def involves_locals(arg0): + try: + if not arg0.__class__ is pw_multi_aff: + arg0 = pw_multi_aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_pw_multi_aff_involves_locals(arg0.ptr) + if res < 0: + raise Error + return bool(res) + def isa_multi_aff(arg0): + try: + if not arg0.__class__ is pw_multi_aff: + arg0 = pw_multi_aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_pw_multi_aff_isa_multi_aff(arg0.ptr) + if res < 0: + raise Error + return bool(res) + def max_multi_val(arg0): + try: + if not arg0.__class__ is pw_multi_aff: + arg0 = pw_multi_aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_pw_multi_aff_max_multi_val(isl.isl_pw_multi_aff_copy(arg0.ptr)) + obj = multi_val(ctx=ctx, ptr=res) + return obj + def min_multi_val(arg0): + try: + if not arg0.__class__ is pw_multi_aff: + arg0 = pw_multi_aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_pw_multi_aff_min_multi_val(isl.isl_pw_multi_aff_copy(arg0.ptr)) + obj = multi_val(ctx=ctx, ptr=res) + return obj + @staticmethod + def multi_val_on_domain(arg0, arg1): + try: + if not arg0.__class__ is set: + arg0 = set(arg0) + except: + raise + try: + if not arg1.__class__ is multi_val: + arg1 = multi_val(arg1) + except: + return union_pw_multi_aff(arg0).multi_val_on_domain(arg1) + ctx = arg0.ctx + res = isl.isl_pw_multi_aff_multi_val_on_domain(isl.isl_set_copy(arg0.ptr), isl.isl_multi_val_copy(arg1.ptr)) + obj = pw_multi_aff(ctx=ctx, ptr=res) + return obj + def n_piece(arg0): + try: + if not arg0.__class__ is pw_multi_aff: + arg0 = pw_multi_aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_pw_multi_aff_n_piece(arg0.ptr) + if res < 0: + raise Error + return int(res) + def plain_is_equal(arg0, arg1): + try: + if not arg0.__class__ is pw_multi_aff: + arg0 = pw_multi_aff(arg0) + except: + raise + try: + if not arg1.__class__ is pw_multi_aff: + arg1 = pw_multi_aff(arg1) + except: + return union_pw_multi_aff(arg0).plain_is_equal(arg1) + ctx = arg0.ctx + res = isl.isl_pw_multi_aff_plain_is_equal(arg0.ptr, arg1.ptr) + if res < 0: + raise Error + return bool(res) + def preimage_domain_wrapped_domain(*args): + if len(args) == 2 and args[1].__class__ is pw_multi_aff: + args = list(args) + try: + if not args[0].__class__ is pw_multi_aff: + args[0] = pw_multi_aff(args[0]) + except: + raise + ctx = args[0].ctx + res = isl.isl_pw_multi_aff_preimage_domain_wrapped_domain_pw_multi_aff(isl.isl_pw_multi_aff_copy(args[0].ptr), isl.isl_pw_multi_aff_copy(args[1].ptr)) + obj = pw_multi_aff(ctx=ctx, ptr=res) + return obj + raise Error + def product(arg0, arg1): + try: + if not arg0.__class__ is pw_multi_aff: + arg0 = pw_multi_aff(arg0) + except: + raise + try: + if not arg1.__class__ is pw_multi_aff: + arg1 = pw_multi_aff(arg1) + except: + return union_pw_multi_aff(arg0).product(arg1) + ctx = arg0.ctx + res = isl.isl_pw_multi_aff_product(isl.isl_pw_multi_aff_copy(arg0.ptr), isl.isl_pw_multi_aff_copy(arg1.ptr)) + obj = pw_multi_aff(ctx=ctx, ptr=res) + return obj + def pullback(*args): + if len(args) == 2 and args[1].__class__ is multi_aff: + args = list(args) + try: + if not args[0].__class__ is pw_multi_aff: + args[0] = pw_multi_aff(args[0]) + except: + raise + ctx = args[0].ctx + res = isl.isl_pw_multi_aff_pullback_multi_aff(isl.isl_pw_multi_aff_copy(args[0].ptr), isl.isl_multi_aff_copy(args[1].ptr)) + obj = pw_multi_aff(ctx=ctx, ptr=res) + return obj + if len(args) == 2 and args[1].__class__ is pw_multi_aff: + args = list(args) + try: + if not args[0].__class__ is pw_multi_aff: + args[0] = pw_multi_aff(args[0]) + except: + raise + ctx = args[0].ctx + res = isl.isl_pw_multi_aff_pullback_pw_multi_aff(isl.isl_pw_multi_aff_copy(args[0].ptr), isl.isl_pw_multi_aff_copy(args[1].ptr)) + obj = pw_multi_aff(ctx=ctx, ptr=res) + return obj + raise Error + def range_factor_domain(arg0): + try: + if not arg0.__class__ is pw_multi_aff: + arg0 = pw_multi_aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_pw_multi_aff_range_factor_domain(isl.isl_pw_multi_aff_copy(arg0.ptr)) + obj = pw_multi_aff(ctx=ctx, ptr=res) + return obj + def range_factor_range(arg0): + try: + if not arg0.__class__ is pw_multi_aff: + arg0 = pw_multi_aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_pw_multi_aff_range_factor_range(isl.isl_pw_multi_aff_copy(arg0.ptr)) + obj = pw_multi_aff(ctx=ctx, ptr=res) + return obj + @staticmethod + def range_map(arg0): + try: + if not arg0.__class__ is space: + arg0 = space(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_pw_multi_aff_range_map(isl.isl_space_copy(arg0.ptr)) + obj = pw_multi_aff(ctx=ctx, ptr=res) + return obj + def range_product(arg0, arg1): + try: + if not arg0.__class__ is pw_multi_aff: + arg0 = pw_multi_aff(arg0) + except: + raise + try: + if not arg1.__class__ is pw_multi_aff: + arg1 = pw_multi_aff(arg1) + except: + return union_pw_multi_aff(arg0).range_product(arg1) + ctx = arg0.ctx + res = isl.isl_pw_multi_aff_range_product(isl.isl_pw_multi_aff_copy(arg0.ptr), isl.isl_pw_multi_aff_copy(arg1.ptr)) + obj = pw_multi_aff(ctx=ctx, ptr=res) + return obj + def range_tuple_id(arg0): + try: + if not arg0.__class__ is pw_multi_aff: + arg0 = pw_multi_aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_pw_multi_aff_get_range_tuple_id(arg0.ptr) + obj = id(ctx=ctx, ptr=res) + return obj + def get_range_tuple_id(arg0): + return arg0.range_tuple_id() + def scale(*args): + if len(args) == 2 and args[1].__class__ is multi_val: + args = list(args) + try: + if not args[0].__class__ is pw_multi_aff: + args[0] = pw_multi_aff(args[0]) + except: + raise + ctx = args[0].ctx + res = isl.isl_pw_multi_aff_scale_multi_val(isl.isl_pw_multi_aff_copy(args[0].ptr), isl.isl_multi_val_copy(args[1].ptr)) + obj = pw_multi_aff(ctx=ctx, ptr=res) + return obj + if len(args) == 2 and (args[1].__class__ is val or type(args[1]) == int): + args = list(args) + try: + if not args[0].__class__ is pw_multi_aff: + args[0] = pw_multi_aff(args[0]) + except: + raise + try: + if not args[1].__class__ is val: + args[1] = val(args[1]) + except: + raise + ctx = args[0].ctx + res = isl.isl_pw_multi_aff_scale_val(isl.isl_pw_multi_aff_copy(args[0].ptr), isl.isl_val_copy(args[1].ptr)) + obj = pw_multi_aff(ctx=ctx, ptr=res) + return obj + raise Error + def scale_down(*args): + if len(args) == 2 and args[1].__class__ is multi_val: + args = list(args) + try: + if not args[0].__class__ is pw_multi_aff: + args[0] = pw_multi_aff(args[0]) + except: + raise + ctx = args[0].ctx + res = isl.isl_pw_multi_aff_scale_down_multi_val(isl.isl_pw_multi_aff_copy(args[0].ptr), isl.isl_multi_val_copy(args[1].ptr)) + obj = pw_multi_aff(ctx=ctx, ptr=res) + return obj + if len(args) == 2 and (args[1].__class__ is val or type(args[1]) == int): + args = list(args) + try: + if not args[0].__class__ is pw_multi_aff: + args[0] = pw_multi_aff(args[0]) + except: + raise + try: + if not args[1].__class__ is val: + args[1] = val(args[1]) + except: + raise + ctx = args[0].ctx + res = isl.isl_pw_multi_aff_scale_down_val(isl.isl_pw_multi_aff_copy(args[0].ptr), isl.isl_val_copy(args[1].ptr)) + obj = pw_multi_aff(ctx=ctx, ptr=res) + return obj + raise Error + def set_range_tuple(*args): + if len(args) == 2 and (args[1].__class__ is id or type(args[1]) == str): + args = list(args) + try: + if not args[0].__class__ is pw_multi_aff: + args[0] = pw_multi_aff(args[0]) + except: + raise + try: + if not args[1].__class__ is id: + args[1] = id(args[1]) + except: + raise + ctx = args[0].ctx + res = isl.isl_pw_multi_aff_set_range_tuple_id(isl.isl_pw_multi_aff_copy(args[0].ptr), isl.isl_id_copy(args[1].ptr)) + obj = pw_multi_aff(ctx=ctx, ptr=res) + return obj + raise Error + def space(arg0): + try: + if not arg0.__class__ is pw_multi_aff: + arg0 = pw_multi_aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_pw_multi_aff_get_space(arg0.ptr) + obj = space(ctx=ctx, ptr=res) + return obj + def get_space(arg0): + return arg0.space() + def sub(arg0, arg1): + try: + if not arg0.__class__ is pw_multi_aff: + arg0 = pw_multi_aff(arg0) + except: + raise + try: + if not arg1.__class__ is pw_multi_aff: + arg1 = pw_multi_aff(arg1) + except: + return union_pw_multi_aff(arg0).sub(arg1) + ctx = arg0.ctx + res = isl.isl_pw_multi_aff_sub(isl.isl_pw_multi_aff_copy(arg0.ptr), isl.isl_pw_multi_aff_copy(arg1.ptr)) + obj = pw_multi_aff(ctx=ctx, ptr=res) + return obj + def subtract_domain(arg0, arg1): + try: + if not arg0.__class__ is pw_multi_aff: + arg0 = pw_multi_aff(arg0) + except: + raise + try: + if not arg1.__class__ is set: + arg1 = set(arg1) + except: + return union_pw_multi_aff(arg0).subtract_domain(arg1) + ctx = arg0.ctx + res = isl.isl_pw_multi_aff_subtract_domain(isl.isl_pw_multi_aff_copy(arg0.ptr), isl.isl_set_copy(arg1.ptr)) + obj = pw_multi_aff(ctx=ctx, ptr=res) + return obj + def to_list(arg0): + try: + if not arg0.__class__ is pw_multi_aff: + arg0 = pw_multi_aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_pw_multi_aff_to_list(isl.isl_pw_multi_aff_copy(arg0.ptr)) + obj = pw_multi_aff_list(ctx=ctx, ptr=res) + return obj + def to_multi_pw_aff(arg0): + try: + if not arg0.__class__ is pw_multi_aff: + arg0 = pw_multi_aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_pw_multi_aff_to_multi_pw_aff(isl.isl_pw_multi_aff_copy(arg0.ptr)) + obj = multi_pw_aff(ctx=ctx, ptr=res) + return obj + def to_union_pw_multi_aff(arg0): + try: + if not arg0.__class__ is pw_multi_aff: + arg0 = pw_multi_aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_pw_multi_aff_to_union_pw_multi_aff(isl.isl_pw_multi_aff_copy(arg0.ptr)) + obj = union_pw_multi_aff(ctx=ctx, ptr=res) + return obj + def union_add(arg0, arg1): + try: + if not arg0.__class__ is pw_multi_aff: + arg0 = pw_multi_aff(arg0) + except: + raise + try: + if not arg1.__class__ is pw_multi_aff: + arg1 = pw_multi_aff(arg1) + except: + return union_pw_multi_aff(arg0).union_add(arg1) + ctx = arg0.ctx + res = isl.isl_pw_multi_aff_union_add(isl.isl_pw_multi_aff_copy(arg0.ptr), isl.isl_pw_multi_aff_copy(arg1.ptr)) + obj = pw_multi_aff(ctx=ctx, ptr=res) + return obj + @staticmethod + def zero(arg0): + try: + if not arg0.__class__ is space: + arg0 = space(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_pw_multi_aff_zero(isl.isl_space_copy(arg0.ptr)) + obj = pw_multi_aff(ctx=ctx, ptr=res) + return obj + +isl.isl_pw_multi_aff_from_multi_aff.restype = c_void_p +isl.isl_pw_multi_aff_from_multi_aff.argtypes = [c_void_p] +isl.isl_pw_multi_aff_from_pw_aff.restype = c_void_p +isl.isl_pw_multi_aff_from_pw_aff.argtypes = [c_void_p] +isl.isl_pw_multi_aff_read_from_str.restype = c_void_p +isl.isl_pw_multi_aff_read_from_str.argtypes = [Context, c_char_p] +isl.isl_pw_multi_aff_add.restype = c_void_p +isl.isl_pw_multi_aff_add.argtypes = [c_void_p, c_void_p] +isl.isl_pw_multi_aff_add_constant_multi_val.restype = c_void_p +isl.isl_pw_multi_aff_add_constant_multi_val.argtypes = [c_void_p, c_void_p] +isl.isl_pw_multi_aff_add_constant_val.restype = c_void_p +isl.isl_pw_multi_aff_add_constant_val.argtypes = [c_void_p, c_void_p] +isl.isl_pw_multi_aff_as_map.restype = c_void_p +isl.isl_pw_multi_aff_as_map.argtypes = [c_void_p] +isl.isl_pw_multi_aff_as_multi_aff.restype = c_void_p +isl.isl_pw_multi_aff_as_multi_aff.argtypes = [c_void_p] +isl.isl_pw_multi_aff_as_set.restype = c_void_p +isl.isl_pw_multi_aff_as_set.argtypes = [c_void_p] +isl.isl_pw_multi_aff_get_at.restype = c_void_p +isl.isl_pw_multi_aff_get_at.argtypes = [c_void_p, c_int] +isl.isl_pw_multi_aff_bind_domain.restype = c_void_p +isl.isl_pw_multi_aff_bind_domain.argtypes = [c_void_p, c_void_p] +isl.isl_pw_multi_aff_bind_domain_wrapped_domain.restype = c_void_p +isl.isl_pw_multi_aff_bind_domain_wrapped_domain.argtypes = [c_void_p, c_void_p] +isl.isl_pw_multi_aff_coalesce.restype = c_void_p +isl.isl_pw_multi_aff_coalesce.argtypes = [c_void_p] +isl.isl_pw_multi_aff_domain.restype = c_void_p +isl.isl_pw_multi_aff_domain.argtypes = [c_void_p] +isl.isl_pw_multi_aff_domain_map.restype = c_void_p +isl.isl_pw_multi_aff_domain_map.argtypes = [c_void_p] +isl.isl_pw_multi_aff_domain_reverse.restype = c_void_p +isl.isl_pw_multi_aff_domain_reverse.argtypes = [c_void_p] +isl.isl_pw_multi_aff_drop_unused_params.restype = c_void_p +isl.isl_pw_multi_aff_drop_unused_params.argtypes = [c_void_p] +isl.isl_pw_multi_aff_flat_range_product.restype = c_void_p +isl.isl_pw_multi_aff_flat_range_product.argtypes = [c_void_p, c_void_p] +isl.isl_pw_multi_aff_foreach_piece.argtypes = [c_void_p, c_void_p, c_void_p] +isl.isl_pw_multi_aff_gist.restype = c_void_p +isl.isl_pw_multi_aff_gist.argtypes = [c_void_p, c_void_p] +isl.isl_pw_multi_aff_gist_params.restype = c_void_p +isl.isl_pw_multi_aff_gist_params.argtypes = [c_void_p, c_void_p] +isl.isl_pw_multi_aff_has_range_tuple_id.argtypes = [c_void_p] +isl.isl_pw_multi_aff_identity_on_domain_space.restype = c_void_p +isl.isl_pw_multi_aff_identity_on_domain_space.argtypes = [c_void_p] +isl.isl_pw_multi_aff_insert_domain.restype = c_void_p +isl.isl_pw_multi_aff_insert_domain.argtypes = [c_void_p, c_void_p] +isl.isl_pw_multi_aff_intersect_domain.restype = c_void_p +isl.isl_pw_multi_aff_intersect_domain.argtypes = [c_void_p, c_void_p] +isl.isl_pw_multi_aff_intersect_params.restype = c_void_p +isl.isl_pw_multi_aff_intersect_params.argtypes = [c_void_p, c_void_p] +isl.isl_pw_multi_aff_involves_locals.argtypes = [c_void_p] +isl.isl_pw_multi_aff_isa_multi_aff.argtypes = [c_void_p] +isl.isl_pw_multi_aff_max_multi_val.restype = c_void_p +isl.isl_pw_multi_aff_max_multi_val.argtypes = [c_void_p] +isl.isl_pw_multi_aff_min_multi_val.restype = c_void_p +isl.isl_pw_multi_aff_min_multi_val.argtypes = [c_void_p] +isl.isl_pw_multi_aff_multi_val_on_domain.restype = c_void_p +isl.isl_pw_multi_aff_multi_val_on_domain.argtypes = [c_void_p, c_void_p] +isl.isl_pw_multi_aff_n_piece.argtypes = [c_void_p] +isl.isl_pw_multi_aff_plain_is_equal.argtypes = [c_void_p, c_void_p] +isl.isl_pw_multi_aff_preimage_domain_wrapped_domain_pw_multi_aff.restype = c_void_p +isl.isl_pw_multi_aff_preimage_domain_wrapped_domain_pw_multi_aff.argtypes = [c_void_p, c_void_p] +isl.isl_pw_multi_aff_product.restype = c_void_p +isl.isl_pw_multi_aff_product.argtypes = [c_void_p, c_void_p] +isl.isl_pw_multi_aff_pullback_multi_aff.restype = c_void_p +isl.isl_pw_multi_aff_pullback_multi_aff.argtypes = [c_void_p, c_void_p] +isl.isl_pw_multi_aff_pullback_pw_multi_aff.restype = c_void_p +isl.isl_pw_multi_aff_pullback_pw_multi_aff.argtypes = [c_void_p, c_void_p] +isl.isl_pw_multi_aff_range_factor_domain.restype = c_void_p +isl.isl_pw_multi_aff_range_factor_domain.argtypes = [c_void_p] +isl.isl_pw_multi_aff_range_factor_range.restype = c_void_p +isl.isl_pw_multi_aff_range_factor_range.argtypes = [c_void_p] +isl.isl_pw_multi_aff_range_map.restype = c_void_p +isl.isl_pw_multi_aff_range_map.argtypes = [c_void_p] +isl.isl_pw_multi_aff_range_product.restype = c_void_p +isl.isl_pw_multi_aff_range_product.argtypes = [c_void_p, c_void_p] +isl.isl_pw_multi_aff_get_range_tuple_id.restype = c_void_p +isl.isl_pw_multi_aff_get_range_tuple_id.argtypes = [c_void_p] +isl.isl_pw_multi_aff_scale_multi_val.restype = c_void_p +isl.isl_pw_multi_aff_scale_multi_val.argtypes = [c_void_p, c_void_p] +isl.isl_pw_multi_aff_scale_val.restype = c_void_p +isl.isl_pw_multi_aff_scale_val.argtypes = [c_void_p, c_void_p] +isl.isl_pw_multi_aff_scale_down_multi_val.restype = c_void_p +isl.isl_pw_multi_aff_scale_down_multi_val.argtypes = [c_void_p, c_void_p] +isl.isl_pw_multi_aff_scale_down_val.restype = c_void_p +isl.isl_pw_multi_aff_scale_down_val.argtypes = [c_void_p, c_void_p] +isl.isl_pw_multi_aff_set_range_tuple_id.restype = c_void_p +isl.isl_pw_multi_aff_set_range_tuple_id.argtypes = [c_void_p, c_void_p] +isl.isl_pw_multi_aff_get_space.restype = c_void_p +isl.isl_pw_multi_aff_get_space.argtypes = [c_void_p] +isl.isl_pw_multi_aff_sub.restype = c_void_p +isl.isl_pw_multi_aff_sub.argtypes = [c_void_p, c_void_p] +isl.isl_pw_multi_aff_subtract_domain.restype = c_void_p +isl.isl_pw_multi_aff_subtract_domain.argtypes = [c_void_p, c_void_p] +isl.isl_pw_multi_aff_to_list.restype = c_void_p +isl.isl_pw_multi_aff_to_list.argtypes = [c_void_p] +isl.isl_pw_multi_aff_to_multi_pw_aff.restype = c_void_p +isl.isl_pw_multi_aff_to_multi_pw_aff.argtypes = [c_void_p] +isl.isl_pw_multi_aff_to_union_pw_multi_aff.restype = c_void_p +isl.isl_pw_multi_aff_to_union_pw_multi_aff.argtypes = [c_void_p] +isl.isl_pw_multi_aff_union_add.restype = c_void_p +isl.isl_pw_multi_aff_union_add.argtypes = [c_void_p, c_void_p] +isl.isl_pw_multi_aff_zero.restype = c_void_p +isl.isl_pw_multi_aff_zero.argtypes = [c_void_p] +isl.isl_pw_multi_aff_copy.restype = c_void_p +isl.isl_pw_multi_aff_copy.argtypes = [c_void_p] +isl.isl_pw_multi_aff_free.restype = c_void_p +isl.isl_pw_multi_aff_free.argtypes = [c_void_p] +isl.isl_pw_multi_aff_to_str.restype = POINTER(c_char) +isl.isl_pw_multi_aff_to_str.argtypes = [c_void_p] + +class pw_aff(union_pw_aff, pw_multi_aff, multi_pw_aff): + def __init__(self, *args, **keywords): + if "ptr" in keywords: + self.ctx = keywords["ctx"] + self.ptr = keywords["ptr"] + return + if len(args) == 1 and args[0].__class__ is aff: + self.ctx = Context.getDefaultInstance() + self.ptr = isl.isl_pw_aff_from_aff(isl.isl_aff_copy(args[0].ptr)) + return + if len(args) == 1 and type(args[0]) == str: + self.ctx = Context.getDefaultInstance() + self.ptr = isl.isl_pw_aff_read_from_str(self.ctx, args[0].encode('ascii')) + return + raise Error + def __del__(self): + if hasattr(self, 'ptr'): + isl.isl_pw_aff_free(self.ptr) + def __str__(arg0): + try: + if not arg0.__class__ is pw_aff: + arg0 = pw_aff(arg0) + except: + raise + ptr = isl.isl_pw_aff_to_str(arg0.ptr) + res = cast(ptr, c_char_p).value.decode('ascii') + libc.free(ptr) + return res + def __repr__(self): + s = str(self) + if '"' in s: + return 'isl.pw_aff("""%s""")' % s + else: + return 'isl.pw_aff("%s")' % s + def add(arg0, arg1): + try: + if not arg0.__class__ is pw_aff: + arg0 = pw_aff(arg0) + except: + raise + try: + if not arg1.__class__ is pw_aff: + arg1 = pw_aff(arg1) + except: + return union_pw_aff(arg0).add(arg1) + ctx = arg0.ctx + res = isl.isl_pw_aff_add(isl.isl_pw_aff_copy(arg0.ptr), isl.isl_pw_aff_copy(arg1.ptr)) + obj = pw_aff(ctx=ctx, ptr=res) + return obj + def add_constant(*args): + if len(args) == 2 and (args[1].__class__ is val or type(args[1]) == int): + args = list(args) + try: + if not args[0].__class__ is pw_aff: + args[0] = pw_aff(args[0]) + except: + raise + try: + if not args[1].__class__ is val: + args[1] = val(args[1]) + except: + raise + ctx = args[0].ctx + res = isl.isl_pw_aff_add_constant_val(isl.isl_pw_aff_copy(args[0].ptr), isl.isl_val_copy(args[1].ptr)) + obj = pw_aff(ctx=ctx, ptr=res) + return obj + raise Error + def as_aff(arg0): + try: + if not arg0.__class__ is pw_aff: + arg0 = pw_aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_pw_aff_as_aff(isl.isl_pw_aff_copy(arg0.ptr)) + obj = aff(ctx=ctx, ptr=res) + return obj + def as_map(arg0): + try: + if not arg0.__class__ is pw_aff: + arg0 = pw_aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_pw_aff_as_map(isl.isl_pw_aff_copy(arg0.ptr)) + obj = map(ctx=ctx, ptr=res) + return obj + def bind(*args): + if len(args) == 2 and (args[1].__class__ is id or type(args[1]) == str): + args = list(args) + try: + if not args[0].__class__ is pw_aff: + args[0] = pw_aff(args[0]) + except: + raise + try: + if not args[1].__class__ is id: + args[1] = id(args[1]) + except: + raise + ctx = args[0].ctx + res = isl.isl_pw_aff_bind_id(isl.isl_pw_aff_copy(args[0].ptr), isl.isl_id_copy(args[1].ptr)) + obj = set(ctx=ctx, ptr=res) + return obj + raise Error + def bind_domain(arg0, arg1): + try: + if not arg0.__class__ is pw_aff: + arg0 = pw_aff(arg0) + except: + raise + try: + if not arg1.__class__ is multi_id: + arg1 = multi_id(arg1) + except: + return union_pw_aff(arg0).bind_domain(arg1) + ctx = arg0.ctx + res = isl.isl_pw_aff_bind_domain(isl.isl_pw_aff_copy(arg0.ptr), isl.isl_multi_id_copy(arg1.ptr)) + obj = pw_aff(ctx=ctx, ptr=res) + return obj + def bind_domain_wrapped_domain(arg0, arg1): + try: + if not arg0.__class__ is pw_aff: + arg0 = pw_aff(arg0) + except: + raise + try: + if not arg1.__class__ is multi_id: + arg1 = multi_id(arg1) + except: + return union_pw_aff(arg0).bind_domain_wrapped_domain(arg1) + ctx = arg0.ctx + res = isl.isl_pw_aff_bind_domain_wrapped_domain(isl.isl_pw_aff_copy(arg0.ptr), isl.isl_multi_id_copy(arg1.ptr)) + obj = pw_aff(ctx=ctx, ptr=res) + return obj + def ceil(arg0): + try: + if not arg0.__class__ is pw_aff: + arg0 = pw_aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_pw_aff_ceil(isl.isl_pw_aff_copy(arg0.ptr)) + obj = pw_aff(ctx=ctx, ptr=res) + return obj + def coalesce(arg0): + try: + if not arg0.__class__ is pw_aff: + arg0 = pw_aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_pw_aff_coalesce(isl.isl_pw_aff_copy(arg0.ptr)) + obj = pw_aff(ctx=ctx, ptr=res) + return obj + def cond(arg0, arg1, arg2): + try: + if not arg0.__class__ is pw_aff: + arg0 = pw_aff(arg0) + except: + raise + try: + if not arg1.__class__ is pw_aff: + arg1 = pw_aff(arg1) + except: + return union_pw_aff(arg0).cond(arg1, arg2) + try: + if not arg2.__class__ is pw_aff: + arg2 = pw_aff(arg2) + except: + return union_pw_aff(arg0).cond(arg1, arg2) + ctx = arg0.ctx + res = isl.isl_pw_aff_cond(isl.isl_pw_aff_copy(arg0.ptr), isl.isl_pw_aff_copy(arg1.ptr), isl.isl_pw_aff_copy(arg2.ptr)) + obj = pw_aff(ctx=ctx, ptr=res) + return obj + def div(arg0, arg1): + try: + if not arg0.__class__ is pw_aff: + arg0 = pw_aff(arg0) + except: + raise + try: + if not arg1.__class__ is pw_aff: + arg1 = pw_aff(arg1) + except: + return union_pw_aff(arg0).div(arg1) + ctx = arg0.ctx + res = isl.isl_pw_aff_div(isl.isl_pw_aff_copy(arg0.ptr), isl.isl_pw_aff_copy(arg1.ptr)) + obj = pw_aff(ctx=ctx, ptr=res) + return obj + def domain(arg0): + try: + if not arg0.__class__ is pw_aff: + arg0 = pw_aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_pw_aff_domain(isl.isl_pw_aff_copy(arg0.ptr)) + obj = set(ctx=ctx, ptr=res) + return obj + def domain_reverse(arg0): + try: + if not arg0.__class__ is pw_aff: + arg0 = pw_aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_pw_aff_domain_reverse(isl.isl_pw_aff_copy(arg0.ptr)) + obj = pw_aff(ctx=ctx, ptr=res) + return obj + def drop_unused_params(arg0): + try: + if not arg0.__class__ is pw_aff: + arg0 = pw_aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_pw_aff_drop_unused_params(isl.isl_pw_aff_copy(arg0.ptr)) + obj = pw_aff(ctx=ctx, ptr=res) + return obj + def eq_set(arg0, arg1): + try: + if not arg0.__class__ is pw_aff: + arg0 = pw_aff(arg0) + except: + raise + try: + if not arg1.__class__ is pw_aff: + arg1 = pw_aff(arg1) + except: + return union_pw_aff(arg0).eq_set(arg1) + ctx = arg0.ctx + res = isl.isl_pw_aff_eq_set(isl.isl_pw_aff_copy(arg0.ptr), isl.isl_pw_aff_copy(arg1.ptr)) + obj = set(ctx=ctx, ptr=res) + return obj + def eval(arg0, arg1): + try: + if not arg0.__class__ is pw_aff: + arg0 = pw_aff(arg0) + except: + raise + try: + if not arg1.__class__ is point: + arg1 = point(arg1) + except: + return union_pw_aff(arg0).eval(arg1) + ctx = arg0.ctx + res = isl.isl_pw_aff_eval(isl.isl_pw_aff_copy(arg0.ptr), isl.isl_point_copy(arg1.ptr)) + obj = val(ctx=ctx, ptr=res) + return obj + def floor(arg0): + try: + if not arg0.__class__ is pw_aff: + arg0 = pw_aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_pw_aff_floor(isl.isl_pw_aff_copy(arg0.ptr)) + obj = pw_aff(ctx=ctx, ptr=res) + return obj + def ge_set(arg0, arg1): + try: + if not arg0.__class__ is pw_aff: + arg0 = pw_aff(arg0) + except: + raise + try: + if not arg1.__class__ is pw_aff: + arg1 = pw_aff(arg1) + except: + return union_pw_aff(arg0).ge_set(arg1) + ctx = arg0.ctx + res = isl.isl_pw_aff_ge_set(isl.isl_pw_aff_copy(arg0.ptr), isl.isl_pw_aff_copy(arg1.ptr)) + obj = set(ctx=ctx, ptr=res) + return obj + def gist(arg0, arg1): + try: + if not arg0.__class__ is pw_aff: + arg0 = pw_aff(arg0) + except: + raise + try: + if not arg1.__class__ is set: + arg1 = set(arg1) + except: + return union_pw_aff(arg0).gist(arg1) + ctx = arg0.ctx + res = isl.isl_pw_aff_gist(isl.isl_pw_aff_copy(arg0.ptr), isl.isl_set_copy(arg1.ptr)) + obj = pw_aff(ctx=ctx, ptr=res) + return obj + def gist_params(arg0, arg1): + try: + if not arg0.__class__ is pw_aff: + arg0 = pw_aff(arg0) + except: + raise + try: + if not arg1.__class__ is set: + arg1 = set(arg1) + except: + return union_pw_aff(arg0).gist_params(arg1) + ctx = arg0.ctx + res = isl.isl_pw_aff_gist_params(isl.isl_pw_aff_copy(arg0.ptr), isl.isl_set_copy(arg1.ptr)) + obj = pw_aff(ctx=ctx, ptr=res) + return obj + def gt_set(arg0, arg1): + try: + if not arg0.__class__ is pw_aff: + arg0 = pw_aff(arg0) + except: + raise + try: + if not arg1.__class__ is pw_aff: + arg1 = pw_aff(arg1) + except: + return union_pw_aff(arg0).gt_set(arg1) + ctx = arg0.ctx + res = isl.isl_pw_aff_gt_set(isl.isl_pw_aff_copy(arg0.ptr), isl.isl_pw_aff_copy(arg1.ptr)) + obj = set(ctx=ctx, ptr=res) + return obj + def insert_domain(arg0, arg1): + try: + if not arg0.__class__ is pw_aff: + arg0 = pw_aff(arg0) + except: + raise + try: + if not arg1.__class__ is space: + arg1 = space(arg1) + except: + return union_pw_aff(arg0).insert_domain(arg1) + ctx = arg0.ctx + res = isl.isl_pw_aff_insert_domain(isl.isl_pw_aff_copy(arg0.ptr), isl.isl_space_copy(arg1.ptr)) + obj = pw_aff(ctx=ctx, ptr=res) + return obj + def intersect_domain(arg0, arg1): + try: + if not arg0.__class__ is pw_aff: + arg0 = pw_aff(arg0) + except: + raise + try: + if not arg1.__class__ is set: + arg1 = set(arg1) + except: + return union_pw_aff(arg0).intersect_domain(arg1) + ctx = arg0.ctx + res = isl.isl_pw_aff_intersect_domain(isl.isl_pw_aff_copy(arg0.ptr), isl.isl_set_copy(arg1.ptr)) + obj = pw_aff(ctx=ctx, ptr=res) + return obj + def intersect_params(arg0, arg1): + try: + if not arg0.__class__ is pw_aff: + arg0 = pw_aff(arg0) + except: + raise + try: + if not arg1.__class__ is set: + arg1 = set(arg1) + except: + return union_pw_aff(arg0).intersect_params(arg1) + ctx = arg0.ctx + res = isl.isl_pw_aff_intersect_params(isl.isl_pw_aff_copy(arg0.ptr), isl.isl_set_copy(arg1.ptr)) + obj = pw_aff(ctx=ctx, ptr=res) + return obj + def isa_aff(arg0): + try: + if not arg0.__class__ is pw_aff: + arg0 = pw_aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_pw_aff_isa_aff(arg0.ptr) + if res < 0: + raise Error + return bool(res) + def le_set(arg0, arg1): + try: + if not arg0.__class__ is pw_aff: + arg0 = pw_aff(arg0) + except: + raise + try: + if not arg1.__class__ is pw_aff: + arg1 = pw_aff(arg1) + except: + return union_pw_aff(arg0).le_set(arg1) + ctx = arg0.ctx + res = isl.isl_pw_aff_le_set(isl.isl_pw_aff_copy(arg0.ptr), isl.isl_pw_aff_copy(arg1.ptr)) + obj = set(ctx=ctx, ptr=res) + return obj + def lt_set(arg0, arg1): + try: + if not arg0.__class__ is pw_aff: + arg0 = pw_aff(arg0) + except: + raise + try: + if not arg1.__class__ is pw_aff: + arg1 = pw_aff(arg1) + except: + return union_pw_aff(arg0).lt_set(arg1) + ctx = arg0.ctx + res = isl.isl_pw_aff_lt_set(isl.isl_pw_aff_copy(arg0.ptr), isl.isl_pw_aff_copy(arg1.ptr)) + obj = set(ctx=ctx, ptr=res) + return obj + def max(arg0, arg1): + try: + if not arg0.__class__ is pw_aff: + arg0 = pw_aff(arg0) + except: + raise + try: + if not arg1.__class__ is pw_aff: + arg1 = pw_aff(arg1) + except: + return union_pw_aff(arg0).max(arg1) + ctx = arg0.ctx + res = isl.isl_pw_aff_max(isl.isl_pw_aff_copy(arg0.ptr), isl.isl_pw_aff_copy(arg1.ptr)) + obj = pw_aff(ctx=ctx, ptr=res) + return obj + def max_val(arg0): + try: + if not arg0.__class__ is pw_aff: + arg0 = pw_aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_pw_aff_max_val(isl.isl_pw_aff_copy(arg0.ptr)) + obj = val(ctx=ctx, ptr=res) + return obj + def min(arg0, arg1): + try: + if not arg0.__class__ is pw_aff: + arg0 = pw_aff(arg0) + except: + raise + try: + if not arg1.__class__ is pw_aff: + arg1 = pw_aff(arg1) + except: + return union_pw_aff(arg0).min(arg1) + ctx = arg0.ctx + res = isl.isl_pw_aff_min(isl.isl_pw_aff_copy(arg0.ptr), isl.isl_pw_aff_copy(arg1.ptr)) + obj = pw_aff(ctx=ctx, ptr=res) + return obj + def min_val(arg0): + try: + if not arg0.__class__ is pw_aff: + arg0 = pw_aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_pw_aff_min_val(isl.isl_pw_aff_copy(arg0.ptr)) + obj = val(ctx=ctx, ptr=res) + return obj + def mod(*args): + if len(args) == 2 and (args[1].__class__ is val or type(args[1]) == int): + args = list(args) + try: + if not args[0].__class__ is pw_aff: + args[0] = pw_aff(args[0]) + except: + raise + try: + if not args[1].__class__ is val: + args[1] = val(args[1]) + except: + raise + ctx = args[0].ctx + res = isl.isl_pw_aff_mod_val(isl.isl_pw_aff_copy(args[0].ptr), isl.isl_val_copy(args[1].ptr)) + obj = pw_aff(ctx=ctx, ptr=res) + return obj + raise Error + def mul(arg0, arg1): + try: + if not arg0.__class__ is pw_aff: + arg0 = pw_aff(arg0) + except: + raise + try: + if not arg1.__class__ is pw_aff: + arg1 = pw_aff(arg1) + except: + return union_pw_aff(arg0).mul(arg1) + ctx = arg0.ctx + res = isl.isl_pw_aff_mul(isl.isl_pw_aff_copy(arg0.ptr), isl.isl_pw_aff_copy(arg1.ptr)) + obj = pw_aff(ctx=ctx, ptr=res) + return obj + def ne_set(arg0, arg1): + try: + if not arg0.__class__ is pw_aff: + arg0 = pw_aff(arg0) + except: + raise + try: + if not arg1.__class__ is pw_aff: + arg1 = pw_aff(arg1) + except: + return union_pw_aff(arg0).ne_set(arg1) + ctx = arg0.ctx + res = isl.isl_pw_aff_ne_set(isl.isl_pw_aff_copy(arg0.ptr), isl.isl_pw_aff_copy(arg1.ptr)) + obj = set(ctx=ctx, ptr=res) + return obj + def neg(arg0): + try: + if not arg0.__class__ is pw_aff: + arg0 = pw_aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_pw_aff_neg(isl.isl_pw_aff_copy(arg0.ptr)) + obj = pw_aff(ctx=ctx, ptr=res) + return obj + @staticmethod + def param_on_domain(*args): + if len(args) == 2 and args[0].__class__ is set and (args[1].__class__ is id or type(args[1]) == str): + args = list(args) + try: + if not args[1].__class__ is id: + args[1] = id(args[1]) + except: + raise + ctx = args[0].ctx + res = isl.isl_pw_aff_param_on_domain_id(isl.isl_set_copy(args[0].ptr), isl.isl_id_copy(args[1].ptr)) + obj = pw_aff(ctx=ctx, ptr=res) + return obj + raise Error + def params(arg0): + try: + if not arg0.__class__ is pw_aff: + arg0 = pw_aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_pw_aff_params(isl.isl_pw_aff_copy(arg0.ptr)) + obj = set(ctx=ctx, ptr=res) + return obj + def plain_is_equal(arg0, arg1): + try: + if not arg0.__class__ is pw_aff: + arg0 = pw_aff(arg0) + except: + raise + try: + if not arg1.__class__ is pw_aff: + arg1 = pw_aff(arg1) + except: + return union_pw_aff(arg0).plain_is_equal(arg1) + ctx = arg0.ctx + res = isl.isl_pw_aff_plain_is_equal(arg0.ptr, arg1.ptr) + if res < 0: + raise Error + return bool(res) + def pullback(*args): + if len(args) == 2 and args[1].__class__ is multi_aff: + args = list(args) + try: + if not args[0].__class__ is pw_aff: + args[0] = pw_aff(args[0]) + except: + raise + ctx = args[0].ctx + res = isl.isl_pw_aff_pullback_multi_aff(isl.isl_pw_aff_copy(args[0].ptr), isl.isl_multi_aff_copy(args[1].ptr)) + obj = pw_aff(ctx=ctx, ptr=res) + return obj + if len(args) == 2 and args[1].__class__ is multi_pw_aff: + args = list(args) + try: + if not args[0].__class__ is pw_aff: + args[0] = pw_aff(args[0]) + except: + raise + ctx = args[0].ctx + res = isl.isl_pw_aff_pullback_multi_pw_aff(isl.isl_pw_aff_copy(args[0].ptr), isl.isl_multi_pw_aff_copy(args[1].ptr)) + obj = pw_aff(ctx=ctx, ptr=res) + return obj + if len(args) == 2 and args[1].__class__ is pw_multi_aff: + args = list(args) + try: + if not args[0].__class__ is pw_aff: + args[0] = pw_aff(args[0]) + except: + raise + ctx = args[0].ctx + res = isl.isl_pw_aff_pullback_pw_multi_aff(isl.isl_pw_aff_copy(args[0].ptr), isl.isl_pw_multi_aff_copy(args[1].ptr)) + obj = pw_aff(ctx=ctx, ptr=res) + return obj + raise Error + def scale(*args): + if len(args) == 2 and (args[1].__class__ is val or type(args[1]) == int): + args = list(args) + try: + if not args[0].__class__ is pw_aff: + args[0] = pw_aff(args[0]) + except: + raise + try: + if not args[1].__class__ is val: + args[1] = val(args[1]) + except: + raise + ctx = args[0].ctx + res = isl.isl_pw_aff_scale_val(isl.isl_pw_aff_copy(args[0].ptr), isl.isl_val_copy(args[1].ptr)) + obj = pw_aff(ctx=ctx, ptr=res) + return obj + raise Error + def scale_down(*args): + if len(args) == 2 and (args[1].__class__ is val or type(args[1]) == int): + args = list(args) + try: + if not args[0].__class__ is pw_aff: + args[0] = pw_aff(args[0]) + except: + raise + try: + if not args[1].__class__ is val: + args[1] = val(args[1]) + except: + raise + ctx = args[0].ctx + res = isl.isl_pw_aff_scale_down_val(isl.isl_pw_aff_copy(args[0].ptr), isl.isl_val_copy(args[1].ptr)) + obj = pw_aff(ctx=ctx, ptr=res) + return obj + raise Error + def space(arg0): + try: + if not arg0.__class__ is pw_aff: + arg0 = pw_aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_pw_aff_get_space(arg0.ptr) + obj = space(ctx=ctx, ptr=res) + return obj + def get_space(arg0): + return arg0.space() + def sub(arg0, arg1): + try: + if not arg0.__class__ is pw_aff: + arg0 = pw_aff(arg0) + except: + raise + try: + if not arg1.__class__ is pw_aff: + arg1 = pw_aff(arg1) + except: + return union_pw_aff(arg0).sub(arg1) + ctx = arg0.ctx + res = isl.isl_pw_aff_sub(isl.isl_pw_aff_copy(arg0.ptr), isl.isl_pw_aff_copy(arg1.ptr)) + obj = pw_aff(ctx=ctx, ptr=res) + return obj + def subtract_domain(arg0, arg1): + try: + if not arg0.__class__ is pw_aff: + arg0 = pw_aff(arg0) + except: + raise + try: + if not arg1.__class__ is set: + arg1 = set(arg1) + except: + return union_pw_aff(arg0).subtract_domain(arg1) + ctx = arg0.ctx + res = isl.isl_pw_aff_subtract_domain(isl.isl_pw_aff_copy(arg0.ptr), isl.isl_set_copy(arg1.ptr)) + obj = pw_aff(ctx=ctx, ptr=res) + return obj + def tdiv_q(arg0, arg1): + try: + if not arg0.__class__ is pw_aff: + arg0 = pw_aff(arg0) + except: + raise + try: + if not arg1.__class__ is pw_aff: + arg1 = pw_aff(arg1) + except: + return union_pw_aff(arg0).tdiv_q(arg1) + ctx = arg0.ctx + res = isl.isl_pw_aff_tdiv_q(isl.isl_pw_aff_copy(arg0.ptr), isl.isl_pw_aff_copy(arg1.ptr)) + obj = pw_aff(ctx=ctx, ptr=res) + return obj + def tdiv_r(arg0, arg1): + try: + if not arg0.__class__ is pw_aff: + arg0 = pw_aff(arg0) + except: + raise + try: + if not arg1.__class__ is pw_aff: + arg1 = pw_aff(arg1) + except: + return union_pw_aff(arg0).tdiv_r(arg1) + ctx = arg0.ctx + res = isl.isl_pw_aff_tdiv_r(isl.isl_pw_aff_copy(arg0.ptr), isl.isl_pw_aff_copy(arg1.ptr)) + obj = pw_aff(ctx=ctx, ptr=res) + return obj + def to_list(arg0): + try: + if not arg0.__class__ is pw_aff: + arg0 = pw_aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_pw_aff_to_list(isl.isl_pw_aff_copy(arg0.ptr)) + obj = pw_aff_list(ctx=ctx, ptr=res) + return obj + def to_union_pw_aff(arg0): + try: + if not arg0.__class__ is pw_aff: + arg0 = pw_aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_pw_aff_to_union_pw_aff(isl.isl_pw_aff_copy(arg0.ptr)) + obj = union_pw_aff(ctx=ctx, ptr=res) + return obj + def union_add(arg0, arg1): + try: + if not arg0.__class__ is pw_aff: + arg0 = pw_aff(arg0) + except: + raise + try: + if not arg1.__class__ is pw_aff: + arg1 = pw_aff(arg1) + except: + return union_pw_aff(arg0).union_add(arg1) + ctx = arg0.ctx + res = isl.isl_pw_aff_union_add(isl.isl_pw_aff_copy(arg0.ptr), isl.isl_pw_aff_copy(arg1.ptr)) + obj = pw_aff(ctx=ctx, ptr=res) + return obj + +isl.isl_pw_aff_from_aff.restype = c_void_p +isl.isl_pw_aff_from_aff.argtypes = [c_void_p] +isl.isl_pw_aff_read_from_str.restype = c_void_p +isl.isl_pw_aff_read_from_str.argtypes = [Context, c_char_p] +isl.isl_pw_aff_add.restype = c_void_p +isl.isl_pw_aff_add.argtypes = [c_void_p, c_void_p] +isl.isl_pw_aff_add_constant_val.restype = c_void_p +isl.isl_pw_aff_add_constant_val.argtypes = [c_void_p, c_void_p] +isl.isl_pw_aff_as_aff.restype = c_void_p +isl.isl_pw_aff_as_aff.argtypes = [c_void_p] +isl.isl_pw_aff_as_map.restype = c_void_p +isl.isl_pw_aff_as_map.argtypes = [c_void_p] +isl.isl_pw_aff_bind_id.restype = c_void_p +isl.isl_pw_aff_bind_id.argtypes = [c_void_p, c_void_p] +isl.isl_pw_aff_bind_domain.restype = c_void_p +isl.isl_pw_aff_bind_domain.argtypes = [c_void_p, c_void_p] +isl.isl_pw_aff_bind_domain_wrapped_domain.restype = c_void_p +isl.isl_pw_aff_bind_domain_wrapped_domain.argtypes = [c_void_p, c_void_p] +isl.isl_pw_aff_ceil.restype = c_void_p +isl.isl_pw_aff_ceil.argtypes = [c_void_p] +isl.isl_pw_aff_coalesce.restype = c_void_p +isl.isl_pw_aff_coalesce.argtypes = [c_void_p] +isl.isl_pw_aff_cond.restype = c_void_p +isl.isl_pw_aff_cond.argtypes = [c_void_p, c_void_p, c_void_p] +isl.isl_pw_aff_div.restype = c_void_p +isl.isl_pw_aff_div.argtypes = [c_void_p, c_void_p] +isl.isl_pw_aff_domain.restype = c_void_p +isl.isl_pw_aff_domain.argtypes = [c_void_p] +isl.isl_pw_aff_domain_reverse.restype = c_void_p +isl.isl_pw_aff_domain_reverse.argtypes = [c_void_p] +isl.isl_pw_aff_drop_unused_params.restype = c_void_p +isl.isl_pw_aff_drop_unused_params.argtypes = [c_void_p] +isl.isl_pw_aff_eq_set.restype = c_void_p +isl.isl_pw_aff_eq_set.argtypes = [c_void_p, c_void_p] +isl.isl_pw_aff_eval.restype = c_void_p +isl.isl_pw_aff_eval.argtypes = [c_void_p, c_void_p] +isl.isl_pw_aff_floor.restype = c_void_p +isl.isl_pw_aff_floor.argtypes = [c_void_p] +isl.isl_pw_aff_ge_set.restype = c_void_p +isl.isl_pw_aff_ge_set.argtypes = [c_void_p, c_void_p] +isl.isl_pw_aff_gist.restype = c_void_p +isl.isl_pw_aff_gist.argtypes = [c_void_p, c_void_p] +isl.isl_pw_aff_gist_params.restype = c_void_p +isl.isl_pw_aff_gist_params.argtypes = [c_void_p, c_void_p] +isl.isl_pw_aff_gt_set.restype = c_void_p +isl.isl_pw_aff_gt_set.argtypes = [c_void_p, c_void_p] +isl.isl_pw_aff_insert_domain.restype = c_void_p +isl.isl_pw_aff_insert_domain.argtypes = [c_void_p, c_void_p] +isl.isl_pw_aff_intersect_domain.restype = c_void_p +isl.isl_pw_aff_intersect_domain.argtypes = [c_void_p, c_void_p] +isl.isl_pw_aff_intersect_params.restype = c_void_p +isl.isl_pw_aff_intersect_params.argtypes = [c_void_p, c_void_p] +isl.isl_pw_aff_isa_aff.argtypes = [c_void_p] +isl.isl_pw_aff_le_set.restype = c_void_p +isl.isl_pw_aff_le_set.argtypes = [c_void_p, c_void_p] +isl.isl_pw_aff_lt_set.restype = c_void_p +isl.isl_pw_aff_lt_set.argtypes = [c_void_p, c_void_p] +isl.isl_pw_aff_max.restype = c_void_p +isl.isl_pw_aff_max.argtypes = [c_void_p, c_void_p] +isl.isl_pw_aff_max_val.restype = c_void_p +isl.isl_pw_aff_max_val.argtypes = [c_void_p] +isl.isl_pw_aff_min.restype = c_void_p +isl.isl_pw_aff_min.argtypes = [c_void_p, c_void_p] +isl.isl_pw_aff_min_val.restype = c_void_p +isl.isl_pw_aff_min_val.argtypes = [c_void_p] +isl.isl_pw_aff_mod_val.restype = c_void_p +isl.isl_pw_aff_mod_val.argtypes = [c_void_p, c_void_p] +isl.isl_pw_aff_mul.restype = c_void_p +isl.isl_pw_aff_mul.argtypes = [c_void_p, c_void_p] +isl.isl_pw_aff_ne_set.restype = c_void_p +isl.isl_pw_aff_ne_set.argtypes = [c_void_p, c_void_p] +isl.isl_pw_aff_neg.restype = c_void_p +isl.isl_pw_aff_neg.argtypes = [c_void_p] +isl.isl_pw_aff_param_on_domain_id.restype = c_void_p +isl.isl_pw_aff_param_on_domain_id.argtypes = [c_void_p, c_void_p] +isl.isl_pw_aff_params.restype = c_void_p +isl.isl_pw_aff_params.argtypes = [c_void_p] +isl.isl_pw_aff_plain_is_equal.argtypes = [c_void_p, c_void_p] +isl.isl_pw_aff_pullback_multi_aff.restype = c_void_p +isl.isl_pw_aff_pullback_multi_aff.argtypes = [c_void_p, c_void_p] +isl.isl_pw_aff_pullback_multi_pw_aff.restype = c_void_p +isl.isl_pw_aff_pullback_multi_pw_aff.argtypes = [c_void_p, c_void_p] +isl.isl_pw_aff_pullback_pw_multi_aff.restype = c_void_p +isl.isl_pw_aff_pullback_pw_multi_aff.argtypes = [c_void_p, c_void_p] +isl.isl_pw_aff_scale_val.restype = c_void_p +isl.isl_pw_aff_scale_val.argtypes = [c_void_p, c_void_p] +isl.isl_pw_aff_scale_down_val.restype = c_void_p +isl.isl_pw_aff_scale_down_val.argtypes = [c_void_p, c_void_p] +isl.isl_pw_aff_get_space.restype = c_void_p +isl.isl_pw_aff_get_space.argtypes = [c_void_p] +isl.isl_pw_aff_sub.restype = c_void_p +isl.isl_pw_aff_sub.argtypes = [c_void_p, c_void_p] +isl.isl_pw_aff_subtract_domain.restype = c_void_p +isl.isl_pw_aff_subtract_domain.argtypes = [c_void_p, c_void_p] +isl.isl_pw_aff_tdiv_q.restype = c_void_p +isl.isl_pw_aff_tdiv_q.argtypes = [c_void_p, c_void_p] +isl.isl_pw_aff_tdiv_r.restype = c_void_p +isl.isl_pw_aff_tdiv_r.argtypes = [c_void_p, c_void_p] +isl.isl_pw_aff_to_list.restype = c_void_p +isl.isl_pw_aff_to_list.argtypes = [c_void_p] +isl.isl_pw_aff_to_union_pw_aff.restype = c_void_p +isl.isl_pw_aff_to_union_pw_aff.argtypes = [c_void_p] +isl.isl_pw_aff_union_add.restype = c_void_p +isl.isl_pw_aff_union_add.argtypes = [c_void_p, c_void_p] +isl.isl_pw_aff_copy.restype = c_void_p +isl.isl_pw_aff_copy.argtypes = [c_void_p] +isl.isl_pw_aff_free.restype = c_void_p +isl.isl_pw_aff_free.argtypes = [c_void_p] +isl.isl_pw_aff_to_str.restype = POINTER(c_char) +isl.isl_pw_aff_to_str.argtypes = [c_void_p] + +class multi_aff(pw_multi_aff, multi_pw_aff): + def __init__(self, *args, **keywords): + if "ptr" in keywords: + self.ctx = keywords["ctx"] + self.ptr = keywords["ptr"] + return + if len(args) == 1 and args[0].__class__ is aff: + self.ctx = Context.getDefaultInstance() + self.ptr = isl.isl_multi_aff_from_aff(isl.isl_aff_copy(args[0].ptr)) + return + if len(args) == 2 and args[0].__class__ is space and args[1].__class__ is aff_list: + self.ctx = Context.getDefaultInstance() + self.ptr = isl.isl_multi_aff_from_aff_list(isl.isl_space_copy(args[0].ptr), isl.isl_aff_list_copy(args[1].ptr)) + return + if len(args) == 1 and type(args[0]) == str: + self.ctx = Context.getDefaultInstance() + self.ptr = isl.isl_multi_aff_read_from_str(self.ctx, args[0].encode('ascii')) + return + raise Error + def __del__(self): + if hasattr(self, 'ptr'): + isl.isl_multi_aff_free(self.ptr) + def __str__(arg0): + try: + if not arg0.__class__ is multi_aff: + arg0 = multi_aff(arg0) + except: + raise + ptr = isl.isl_multi_aff_to_str(arg0.ptr) + res = cast(ptr, c_char_p).value.decode('ascii') + libc.free(ptr) + return res + def __repr__(self): + s = str(self) + if '"' in s: + return 'isl.multi_aff("""%s""")' % s + else: + return 'isl.multi_aff("%s")' % s + def add(arg0, arg1): + try: + if not arg0.__class__ is multi_aff: + arg0 = multi_aff(arg0) + except: + raise + try: + if not arg1.__class__ is multi_aff: + arg1 = multi_aff(arg1) + except: + return pw_multi_aff(arg0).add(arg1) + ctx = arg0.ctx + res = isl.isl_multi_aff_add(isl.isl_multi_aff_copy(arg0.ptr), isl.isl_multi_aff_copy(arg1.ptr)) + obj = multi_aff(ctx=ctx, ptr=res) + return obj + def add_constant(*args): + if len(args) == 2 and args[1].__class__ is multi_val: + args = list(args) + try: + if not args[0].__class__ is multi_aff: + args[0] = multi_aff(args[0]) + except: + raise + ctx = args[0].ctx + res = isl.isl_multi_aff_add_constant_multi_val(isl.isl_multi_aff_copy(args[0].ptr), isl.isl_multi_val_copy(args[1].ptr)) + obj = multi_aff(ctx=ctx, ptr=res) + return obj + if len(args) == 2 and (args[1].__class__ is val or type(args[1]) == int): + args = list(args) + try: + if not args[0].__class__ is multi_aff: + args[0] = multi_aff(args[0]) + except: + raise + try: + if not args[1].__class__ is val: + args[1] = val(args[1]) + except: + raise + ctx = args[0].ctx + res = isl.isl_multi_aff_add_constant_val(isl.isl_multi_aff_copy(args[0].ptr), isl.isl_val_copy(args[1].ptr)) + obj = multi_aff(ctx=ctx, ptr=res) + return obj + raise Error + def as_map(arg0): + try: + if not arg0.__class__ is multi_aff: + arg0 = multi_aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_multi_aff_as_map(isl.isl_multi_aff_copy(arg0.ptr)) + obj = map(ctx=ctx, ptr=res) + return obj + def as_set(arg0): + try: + if not arg0.__class__ is multi_aff: + arg0 = multi_aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_multi_aff_as_set(isl.isl_multi_aff_copy(arg0.ptr)) + obj = set(ctx=ctx, ptr=res) + return obj + def at(arg0, arg1): + try: + if not arg0.__class__ is multi_aff: + arg0 = multi_aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_multi_aff_get_at(arg0.ptr, arg1) + obj = aff(ctx=ctx, ptr=res) + return obj + def get_at(arg0, arg1): + return arg0.at(arg1) + def bind(arg0, arg1): + try: + if not arg0.__class__ is multi_aff: + arg0 = multi_aff(arg0) + except: + raise + try: + if not arg1.__class__ is multi_id: + arg1 = multi_id(arg1) + except: + return pw_multi_aff(arg0).bind(arg1) + ctx = arg0.ctx + res = isl.isl_multi_aff_bind(isl.isl_multi_aff_copy(arg0.ptr), isl.isl_multi_id_copy(arg1.ptr)) + obj = basic_set(ctx=ctx, ptr=res) + return obj + def bind_domain(arg0, arg1): + try: + if not arg0.__class__ is multi_aff: + arg0 = multi_aff(arg0) + except: + raise + try: + if not arg1.__class__ is multi_id: + arg1 = multi_id(arg1) + except: + return pw_multi_aff(arg0).bind_domain(arg1) + ctx = arg0.ctx + res = isl.isl_multi_aff_bind_domain(isl.isl_multi_aff_copy(arg0.ptr), isl.isl_multi_id_copy(arg1.ptr)) + obj = multi_aff(ctx=ctx, ptr=res) + return obj + def bind_domain_wrapped_domain(arg0, arg1): + try: + if not arg0.__class__ is multi_aff: + arg0 = multi_aff(arg0) + except: + raise + try: + if not arg1.__class__ is multi_id: + arg1 = multi_id(arg1) + except: + return pw_multi_aff(arg0).bind_domain_wrapped_domain(arg1) + ctx = arg0.ctx + res = isl.isl_multi_aff_bind_domain_wrapped_domain(isl.isl_multi_aff_copy(arg0.ptr), isl.isl_multi_id_copy(arg1.ptr)) + obj = multi_aff(ctx=ctx, ptr=res) + return obj + def constant_multi_val(arg0): + try: + if not arg0.__class__ is multi_aff: + arg0 = multi_aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_multi_aff_get_constant_multi_val(arg0.ptr) + obj = multi_val(ctx=ctx, ptr=res) + return obj + def get_constant_multi_val(arg0): + return arg0.constant_multi_val() + @staticmethod + def domain_map(arg0): + try: + if not arg0.__class__ is space: + arg0 = space(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_multi_aff_domain_map(isl.isl_space_copy(arg0.ptr)) + obj = multi_aff(ctx=ctx, ptr=res) + return obj + def domain_reverse(arg0): + try: + if not arg0.__class__ is multi_aff: + arg0 = multi_aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_multi_aff_domain_reverse(isl.isl_multi_aff_copy(arg0.ptr)) + obj = multi_aff(ctx=ctx, ptr=res) + return obj + def flat_range_product(arg0, arg1): + try: + if not arg0.__class__ is multi_aff: + arg0 = multi_aff(arg0) + except: + raise + try: + if not arg1.__class__ is multi_aff: + arg1 = multi_aff(arg1) + except: + return pw_multi_aff(arg0).flat_range_product(arg1) + ctx = arg0.ctx + res = isl.isl_multi_aff_flat_range_product(isl.isl_multi_aff_copy(arg0.ptr), isl.isl_multi_aff_copy(arg1.ptr)) + obj = multi_aff(ctx=ctx, ptr=res) + return obj + def floor(arg0): + try: + if not arg0.__class__ is multi_aff: + arg0 = multi_aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_multi_aff_floor(isl.isl_multi_aff_copy(arg0.ptr)) + obj = multi_aff(ctx=ctx, ptr=res) + return obj + def gist(arg0, arg1): + try: + if not arg0.__class__ is multi_aff: + arg0 = multi_aff(arg0) + except: + raise + try: + if not arg1.__class__ is set: + arg1 = set(arg1) + except: + return pw_multi_aff(arg0).gist(arg1) + ctx = arg0.ctx + res = isl.isl_multi_aff_gist(isl.isl_multi_aff_copy(arg0.ptr), isl.isl_set_copy(arg1.ptr)) + obj = multi_aff(ctx=ctx, ptr=res) + return obj + def gist_params(arg0, arg1): + try: + if not arg0.__class__ is multi_aff: + arg0 = multi_aff(arg0) + except: + raise + try: + if not arg1.__class__ is set: + arg1 = set(arg1) + except: + return pw_multi_aff(arg0).gist_params(arg1) + ctx = arg0.ctx + res = isl.isl_multi_aff_gist_params(isl.isl_multi_aff_copy(arg0.ptr), isl.isl_set_copy(arg1.ptr)) + obj = multi_aff(ctx=ctx, ptr=res) + return obj + def has_range_tuple_id(arg0): + try: + if not arg0.__class__ is multi_aff: + arg0 = multi_aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_multi_aff_has_range_tuple_id(arg0.ptr) + if res < 0: + raise Error + return bool(res) + def identity(*args): + if len(args) == 1: + args = list(args) + try: + if not args[0].__class__ is multi_aff: + args[0] = multi_aff(args[0]) + except: + raise + ctx = args[0].ctx + res = isl.isl_multi_aff_identity_multi_aff(isl.isl_multi_aff_copy(args[0].ptr)) + obj = multi_aff(ctx=ctx, ptr=res) + return obj + raise Error + @staticmethod + def identity_on_domain(*args): + if len(args) == 1 and args[0].__class__ is space: + ctx = args[0].ctx + res = isl.isl_multi_aff_identity_on_domain_space(isl.isl_space_copy(args[0].ptr)) + obj = multi_aff(ctx=ctx, ptr=res) + return obj + raise Error + def insert_domain(arg0, arg1): + try: + if not arg0.__class__ is multi_aff: + arg0 = multi_aff(arg0) + except: + raise + try: + if not arg1.__class__ is space: + arg1 = space(arg1) + except: + return pw_multi_aff(arg0).insert_domain(arg1) + ctx = arg0.ctx + res = isl.isl_multi_aff_insert_domain(isl.isl_multi_aff_copy(arg0.ptr), isl.isl_space_copy(arg1.ptr)) + obj = multi_aff(ctx=ctx, ptr=res) + return obj + def involves_locals(arg0): + try: + if not arg0.__class__ is multi_aff: + arg0 = multi_aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_multi_aff_involves_locals(arg0.ptr) + if res < 0: + raise Error + return bool(res) + def involves_nan(arg0): + try: + if not arg0.__class__ is multi_aff: + arg0 = multi_aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_multi_aff_involves_nan(arg0.ptr) + if res < 0: + raise Error + return bool(res) + def list(arg0): + try: + if not arg0.__class__ is multi_aff: + arg0 = multi_aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_multi_aff_get_list(arg0.ptr) + obj = aff_list(ctx=ctx, ptr=res) + return obj + def get_list(arg0): + return arg0.list() + @staticmethod + def multi_val_on_domain(*args): + if len(args) == 2 and args[0].__class__ is space and args[1].__class__ is multi_val: + ctx = args[0].ctx + res = isl.isl_multi_aff_multi_val_on_domain_space(isl.isl_space_copy(args[0].ptr), isl.isl_multi_val_copy(args[1].ptr)) + obj = multi_aff(ctx=ctx, ptr=res) + return obj + raise Error + def neg(arg0): + try: + if not arg0.__class__ is multi_aff: + arg0 = multi_aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_multi_aff_neg(isl.isl_multi_aff_copy(arg0.ptr)) + obj = multi_aff(ctx=ctx, ptr=res) + return obj + def plain_is_equal(arg0, arg1): + try: + if not arg0.__class__ is multi_aff: + arg0 = multi_aff(arg0) + except: + raise + try: + if not arg1.__class__ is multi_aff: + arg1 = multi_aff(arg1) + except: + return pw_multi_aff(arg0).plain_is_equal(arg1) + ctx = arg0.ctx + res = isl.isl_multi_aff_plain_is_equal(arg0.ptr, arg1.ptr) + if res < 0: + raise Error + return bool(res) + def product(arg0, arg1): + try: + if not arg0.__class__ is multi_aff: + arg0 = multi_aff(arg0) + except: + raise + try: + if not arg1.__class__ is multi_aff: + arg1 = multi_aff(arg1) + except: + return pw_multi_aff(arg0).product(arg1) + ctx = arg0.ctx + res = isl.isl_multi_aff_product(isl.isl_multi_aff_copy(arg0.ptr), isl.isl_multi_aff_copy(arg1.ptr)) + obj = multi_aff(ctx=ctx, ptr=res) + return obj + def pullback(*args): + if len(args) == 2 and args[1].__class__ is multi_aff: + args = list(args) + try: + if not args[0].__class__ is multi_aff: + args[0] = multi_aff(args[0]) + except: + raise + ctx = args[0].ctx + res = isl.isl_multi_aff_pullback_multi_aff(isl.isl_multi_aff_copy(args[0].ptr), isl.isl_multi_aff_copy(args[1].ptr)) + obj = multi_aff(ctx=ctx, ptr=res) + return obj + raise Error + @staticmethod + def range_map(arg0): + try: + if not arg0.__class__ is space: + arg0 = space(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_multi_aff_range_map(isl.isl_space_copy(arg0.ptr)) + obj = multi_aff(ctx=ctx, ptr=res) + return obj + def range_product(arg0, arg1): + try: + if not arg0.__class__ is multi_aff: + arg0 = multi_aff(arg0) + except: + raise + try: + if not arg1.__class__ is multi_aff: + arg1 = multi_aff(arg1) + except: + return pw_multi_aff(arg0).range_product(arg1) + ctx = arg0.ctx + res = isl.isl_multi_aff_range_product(isl.isl_multi_aff_copy(arg0.ptr), isl.isl_multi_aff_copy(arg1.ptr)) + obj = multi_aff(ctx=ctx, ptr=res) + return obj + def range_tuple_id(arg0): + try: + if not arg0.__class__ is multi_aff: + arg0 = multi_aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_multi_aff_get_range_tuple_id(arg0.ptr) + obj = id(ctx=ctx, ptr=res) + return obj + def get_range_tuple_id(arg0): + return arg0.range_tuple_id() + def reset_range_tuple_id(arg0): + try: + if not arg0.__class__ is multi_aff: + arg0 = multi_aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_multi_aff_reset_range_tuple_id(isl.isl_multi_aff_copy(arg0.ptr)) + obj = multi_aff(ctx=ctx, ptr=res) + return obj + def scale(*args): + if len(args) == 2 and args[1].__class__ is multi_val: + args = list(args) + try: + if not args[0].__class__ is multi_aff: + args[0] = multi_aff(args[0]) + except: + raise + ctx = args[0].ctx + res = isl.isl_multi_aff_scale_multi_val(isl.isl_multi_aff_copy(args[0].ptr), isl.isl_multi_val_copy(args[1].ptr)) + obj = multi_aff(ctx=ctx, ptr=res) + return obj + if len(args) == 2 and (args[1].__class__ is val or type(args[1]) == int): + args = list(args) + try: + if not args[0].__class__ is multi_aff: + args[0] = multi_aff(args[0]) + except: + raise + try: + if not args[1].__class__ is val: + args[1] = val(args[1]) + except: + raise + ctx = args[0].ctx + res = isl.isl_multi_aff_scale_val(isl.isl_multi_aff_copy(args[0].ptr), isl.isl_val_copy(args[1].ptr)) + obj = multi_aff(ctx=ctx, ptr=res) + return obj + raise Error + def scale_down(*args): + if len(args) == 2 and args[1].__class__ is multi_val: + args = list(args) + try: + if not args[0].__class__ is multi_aff: + args[0] = multi_aff(args[0]) + except: + raise + ctx = args[0].ctx + res = isl.isl_multi_aff_scale_down_multi_val(isl.isl_multi_aff_copy(args[0].ptr), isl.isl_multi_val_copy(args[1].ptr)) + obj = multi_aff(ctx=ctx, ptr=res) + return obj + if len(args) == 2 and (args[1].__class__ is val or type(args[1]) == int): + args = list(args) + try: + if not args[0].__class__ is multi_aff: + args[0] = multi_aff(args[0]) + except: + raise + try: + if not args[1].__class__ is val: + args[1] = val(args[1]) + except: + raise + ctx = args[0].ctx + res = isl.isl_multi_aff_scale_down_val(isl.isl_multi_aff_copy(args[0].ptr), isl.isl_val_copy(args[1].ptr)) + obj = multi_aff(ctx=ctx, ptr=res) + return obj + raise Error + def set_at(arg0, arg1, arg2): + try: + if not arg0.__class__ is multi_aff: + arg0 = multi_aff(arg0) + except: + raise + try: + if not arg2.__class__ is aff: + arg2 = aff(arg2) + except: + return pw_multi_aff(arg0).set_at(arg1, arg2) + ctx = arg0.ctx + res = isl.isl_multi_aff_set_at(isl.isl_multi_aff_copy(arg0.ptr), arg1, isl.isl_aff_copy(arg2.ptr)) + obj = multi_aff(ctx=ctx, ptr=res) + return obj + def set_range_tuple(*args): + if len(args) == 2 and (args[1].__class__ is id or type(args[1]) == str): + args = list(args) + try: + if not args[0].__class__ is multi_aff: + args[0] = multi_aff(args[0]) + except: + raise + try: + if not args[1].__class__ is id: + args[1] = id(args[1]) + except: + raise + ctx = args[0].ctx + res = isl.isl_multi_aff_set_range_tuple_id(isl.isl_multi_aff_copy(args[0].ptr), isl.isl_id_copy(args[1].ptr)) + obj = multi_aff(ctx=ctx, ptr=res) + return obj + raise Error + def size(arg0): + try: + if not arg0.__class__ is multi_aff: + arg0 = multi_aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_multi_aff_size(arg0.ptr) + if res < 0: + raise Error + return int(res) + def space(arg0): + try: + if not arg0.__class__ is multi_aff: + arg0 = multi_aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_multi_aff_get_space(arg0.ptr) + obj = space(ctx=ctx, ptr=res) + return obj + def get_space(arg0): + return arg0.space() + def sub(arg0, arg1): + try: + if not arg0.__class__ is multi_aff: + arg0 = multi_aff(arg0) + except: + raise + try: + if not arg1.__class__ is multi_aff: + arg1 = multi_aff(arg1) + except: + return pw_multi_aff(arg0).sub(arg1) + ctx = arg0.ctx + res = isl.isl_multi_aff_sub(isl.isl_multi_aff_copy(arg0.ptr), isl.isl_multi_aff_copy(arg1.ptr)) + obj = multi_aff(ctx=ctx, ptr=res) + return obj + def to_multi_pw_aff(arg0): + try: + if not arg0.__class__ is multi_aff: + arg0 = multi_aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_multi_aff_to_multi_pw_aff(isl.isl_multi_aff_copy(arg0.ptr)) + obj = multi_pw_aff(ctx=ctx, ptr=res) + return obj + def to_multi_union_pw_aff(arg0): + try: + if not arg0.__class__ is multi_aff: + arg0 = multi_aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_multi_aff_to_multi_union_pw_aff(isl.isl_multi_aff_copy(arg0.ptr)) + obj = multi_union_pw_aff(ctx=ctx, ptr=res) + return obj + def to_pw_multi_aff(arg0): + try: + if not arg0.__class__ is multi_aff: + arg0 = multi_aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_multi_aff_to_pw_multi_aff(isl.isl_multi_aff_copy(arg0.ptr)) + obj = pw_multi_aff(ctx=ctx, ptr=res) + return obj + def unbind_params_insert_domain(arg0, arg1): + try: + if not arg0.__class__ is multi_aff: + arg0 = multi_aff(arg0) + except: + raise + try: + if not arg1.__class__ is multi_id: + arg1 = multi_id(arg1) + except: + return pw_multi_aff(arg0).unbind_params_insert_domain(arg1) + ctx = arg0.ctx + res = isl.isl_multi_aff_unbind_params_insert_domain(isl.isl_multi_aff_copy(arg0.ptr), isl.isl_multi_id_copy(arg1.ptr)) + obj = multi_aff(ctx=ctx, ptr=res) + return obj + @staticmethod + def zero(arg0): + try: + if not arg0.__class__ is space: + arg0 = space(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_multi_aff_zero(isl.isl_space_copy(arg0.ptr)) + obj = multi_aff(ctx=ctx, ptr=res) + return obj + +isl.isl_multi_aff_from_aff.restype = c_void_p +isl.isl_multi_aff_from_aff.argtypes = [c_void_p] +isl.isl_multi_aff_from_aff_list.restype = c_void_p +isl.isl_multi_aff_from_aff_list.argtypes = [c_void_p, c_void_p] +isl.isl_multi_aff_read_from_str.restype = c_void_p +isl.isl_multi_aff_read_from_str.argtypes = [Context, c_char_p] +isl.isl_multi_aff_add.restype = c_void_p +isl.isl_multi_aff_add.argtypes = [c_void_p, c_void_p] +isl.isl_multi_aff_add_constant_multi_val.restype = c_void_p +isl.isl_multi_aff_add_constant_multi_val.argtypes = [c_void_p, c_void_p] +isl.isl_multi_aff_add_constant_val.restype = c_void_p +isl.isl_multi_aff_add_constant_val.argtypes = [c_void_p, c_void_p] +isl.isl_multi_aff_as_map.restype = c_void_p +isl.isl_multi_aff_as_map.argtypes = [c_void_p] +isl.isl_multi_aff_as_set.restype = c_void_p +isl.isl_multi_aff_as_set.argtypes = [c_void_p] +isl.isl_multi_aff_get_at.restype = c_void_p +isl.isl_multi_aff_get_at.argtypes = [c_void_p, c_int] +isl.isl_multi_aff_bind.restype = c_void_p +isl.isl_multi_aff_bind.argtypes = [c_void_p, c_void_p] +isl.isl_multi_aff_bind_domain.restype = c_void_p +isl.isl_multi_aff_bind_domain.argtypes = [c_void_p, c_void_p] +isl.isl_multi_aff_bind_domain_wrapped_domain.restype = c_void_p +isl.isl_multi_aff_bind_domain_wrapped_domain.argtypes = [c_void_p, c_void_p] +isl.isl_multi_aff_get_constant_multi_val.restype = c_void_p +isl.isl_multi_aff_get_constant_multi_val.argtypes = [c_void_p] +isl.isl_multi_aff_domain_map.restype = c_void_p +isl.isl_multi_aff_domain_map.argtypes = [c_void_p] +isl.isl_multi_aff_domain_reverse.restype = c_void_p +isl.isl_multi_aff_domain_reverse.argtypes = [c_void_p] +isl.isl_multi_aff_flat_range_product.restype = c_void_p +isl.isl_multi_aff_flat_range_product.argtypes = [c_void_p, c_void_p] +isl.isl_multi_aff_floor.restype = c_void_p +isl.isl_multi_aff_floor.argtypes = [c_void_p] +isl.isl_multi_aff_gist.restype = c_void_p +isl.isl_multi_aff_gist.argtypes = [c_void_p, c_void_p] +isl.isl_multi_aff_gist_params.restype = c_void_p +isl.isl_multi_aff_gist_params.argtypes = [c_void_p, c_void_p] +isl.isl_multi_aff_has_range_tuple_id.argtypes = [c_void_p] +isl.isl_multi_aff_identity_multi_aff.restype = c_void_p +isl.isl_multi_aff_identity_multi_aff.argtypes = [c_void_p] +isl.isl_multi_aff_identity_on_domain_space.restype = c_void_p +isl.isl_multi_aff_identity_on_domain_space.argtypes = [c_void_p] +isl.isl_multi_aff_insert_domain.restype = c_void_p +isl.isl_multi_aff_insert_domain.argtypes = [c_void_p, c_void_p] +isl.isl_multi_aff_involves_locals.argtypes = [c_void_p] +isl.isl_multi_aff_involves_nan.argtypes = [c_void_p] +isl.isl_multi_aff_get_list.restype = c_void_p +isl.isl_multi_aff_get_list.argtypes = [c_void_p] +isl.isl_multi_aff_multi_val_on_domain_space.restype = c_void_p +isl.isl_multi_aff_multi_val_on_domain_space.argtypes = [c_void_p, c_void_p] +isl.isl_multi_aff_neg.restype = c_void_p +isl.isl_multi_aff_neg.argtypes = [c_void_p] +isl.isl_multi_aff_plain_is_equal.argtypes = [c_void_p, c_void_p] +isl.isl_multi_aff_product.restype = c_void_p +isl.isl_multi_aff_product.argtypes = [c_void_p, c_void_p] +isl.isl_multi_aff_pullback_multi_aff.restype = c_void_p +isl.isl_multi_aff_pullback_multi_aff.argtypes = [c_void_p, c_void_p] +isl.isl_multi_aff_range_map.restype = c_void_p +isl.isl_multi_aff_range_map.argtypes = [c_void_p] +isl.isl_multi_aff_range_product.restype = c_void_p +isl.isl_multi_aff_range_product.argtypes = [c_void_p, c_void_p] +isl.isl_multi_aff_get_range_tuple_id.restype = c_void_p +isl.isl_multi_aff_get_range_tuple_id.argtypes = [c_void_p] +isl.isl_multi_aff_reset_range_tuple_id.restype = c_void_p +isl.isl_multi_aff_reset_range_tuple_id.argtypes = [c_void_p] +isl.isl_multi_aff_scale_multi_val.restype = c_void_p +isl.isl_multi_aff_scale_multi_val.argtypes = [c_void_p, c_void_p] +isl.isl_multi_aff_scale_val.restype = c_void_p +isl.isl_multi_aff_scale_val.argtypes = [c_void_p, c_void_p] +isl.isl_multi_aff_scale_down_multi_val.restype = c_void_p +isl.isl_multi_aff_scale_down_multi_val.argtypes = [c_void_p, c_void_p] +isl.isl_multi_aff_scale_down_val.restype = c_void_p +isl.isl_multi_aff_scale_down_val.argtypes = [c_void_p, c_void_p] +isl.isl_multi_aff_set_at.restype = c_void_p +isl.isl_multi_aff_set_at.argtypes = [c_void_p, c_int, c_void_p] +isl.isl_multi_aff_set_range_tuple_id.restype = c_void_p +isl.isl_multi_aff_set_range_tuple_id.argtypes = [c_void_p, c_void_p] +isl.isl_multi_aff_size.argtypes = [c_void_p] +isl.isl_multi_aff_get_space.restype = c_void_p +isl.isl_multi_aff_get_space.argtypes = [c_void_p] +isl.isl_multi_aff_sub.restype = c_void_p +isl.isl_multi_aff_sub.argtypes = [c_void_p, c_void_p] +isl.isl_multi_aff_to_multi_pw_aff.restype = c_void_p +isl.isl_multi_aff_to_multi_pw_aff.argtypes = [c_void_p] +isl.isl_multi_aff_to_multi_union_pw_aff.restype = c_void_p +isl.isl_multi_aff_to_multi_union_pw_aff.argtypes = [c_void_p] +isl.isl_multi_aff_to_pw_multi_aff.restype = c_void_p +isl.isl_multi_aff_to_pw_multi_aff.argtypes = [c_void_p] +isl.isl_multi_aff_unbind_params_insert_domain.restype = c_void_p +isl.isl_multi_aff_unbind_params_insert_domain.argtypes = [c_void_p, c_void_p] +isl.isl_multi_aff_zero.restype = c_void_p +isl.isl_multi_aff_zero.argtypes = [c_void_p] +isl.isl_multi_aff_copy.restype = c_void_p +isl.isl_multi_aff_copy.argtypes = [c_void_p] +isl.isl_multi_aff_free.restype = c_void_p +isl.isl_multi_aff_free.argtypes = [c_void_p] +isl.isl_multi_aff_to_str.restype = POINTER(c_char) +isl.isl_multi_aff_to_str.argtypes = [c_void_p] + +class aff(pw_aff, multi_aff): + def __init__(self, *args, **keywords): + if "ptr" in keywords: + self.ctx = keywords["ctx"] + self.ptr = keywords["ptr"] + return + if len(args) == 1 and type(args[0]) == str: + self.ctx = Context.getDefaultInstance() + self.ptr = isl.isl_aff_read_from_str(self.ctx, args[0].encode('ascii')) + return + raise Error + def __del__(self): + if hasattr(self, 'ptr'): + isl.isl_aff_free(self.ptr) + def __str__(arg0): + try: + if not arg0.__class__ is aff: + arg0 = aff(arg0) + except: + raise + ptr = isl.isl_aff_to_str(arg0.ptr) + res = cast(ptr, c_char_p).value.decode('ascii') + libc.free(ptr) + return res + def __repr__(self): + s = str(self) + if '"' in s: + return 'isl.aff("""%s""")' % s + else: + return 'isl.aff("%s")' % s + def add(arg0, arg1): + try: + if not arg0.__class__ is aff: + arg0 = aff(arg0) + except: + raise + try: + if not arg1.__class__ is aff: + arg1 = aff(arg1) + except: + return pw_aff(arg0).add(arg1) + ctx = arg0.ctx + res = isl.isl_aff_add(isl.isl_aff_copy(arg0.ptr), isl.isl_aff_copy(arg1.ptr)) + obj = aff(ctx=ctx, ptr=res) + return obj + def add_constant(*args): + if len(args) == 2 and (args[1].__class__ is val or type(args[1]) == int): + args = list(args) + try: + if not args[0].__class__ is aff: + args[0] = aff(args[0]) + except: + raise + try: + if not args[1].__class__ is val: + args[1] = val(args[1]) + except: + raise + ctx = args[0].ctx + res = isl.isl_aff_add_constant_val(isl.isl_aff_copy(args[0].ptr), isl.isl_val_copy(args[1].ptr)) + obj = aff(ctx=ctx, ptr=res) + return obj + raise Error + def bind(*args): + if len(args) == 2 and (args[1].__class__ is id or type(args[1]) == str): + args = list(args) + try: + if not args[0].__class__ is aff: + args[0] = aff(args[0]) + except: + raise + try: + if not args[1].__class__ is id: + args[1] = id(args[1]) + except: + raise + ctx = args[0].ctx + res = isl.isl_aff_bind_id(isl.isl_aff_copy(args[0].ptr), isl.isl_id_copy(args[1].ptr)) + obj = basic_set(ctx=ctx, ptr=res) + return obj + raise Error + def ceil(arg0): + try: + if not arg0.__class__ is aff: + arg0 = aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_aff_ceil(isl.isl_aff_copy(arg0.ptr)) + obj = aff(ctx=ctx, ptr=res) + return obj + def constant_val(arg0): + try: + if not arg0.__class__ is aff: + arg0 = aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_aff_get_constant_val(arg0.ptr) + obj = val(ctx=ctx, ptr=res) + return obj + def get_constant_val(arg0): + return arg0.constant_val() + def div(arg0, arg1): + try: + if not arg0.__class__ is aff: + arg0 = aff(arg0) + except: + raise + try: + if not arg1.__class__ is aff: + arg1 = aff(arg1) + except: + return pw_aff(arg0).div(arg1) + ctx = arg0.ctx + res = isl.isl_aff_div(isl.isl_aff_copy(arg0.ptr), isl.isl_aff_copy(arg1.ptr)) + obj = aff(ctx=ctx, ptr=res) + return obj + def domain_reverse(arg0): + try: + if not arg0.__class__ is aff: + arg0 = aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_aff_domain_reverse(isl.isl_aff_copy(arg0.ptr)) + obj = aff(ctx=ctx, ptr=res) + return obj + def eq_set(arg0, arg1): + try: + if not arg0.__class__ is aff: + arg0 = aff(arg0) + except: + raise + try: + if not arg1.__class__ is aff: + arg1 = aff(arg1) + except: + return pw_aff(arg0).eq_set(arg1) + ctx = arg0.ctx + res = isl.isl_aff_eq_set(isl.isl_aff_copy(arg0.ptr), isl.isl_aff_copy(arg1.ptr)) + obj = set(ctx=ctx, ptr=res) + return obj + def eval(arg0, arg1): + try: + if not arg0.__class__ is aff: + arg0 = aff(arg0) + except: + raise + try: + if not arg1.__class__ is point: + arg1 = point(arg1) + except: + return pw_aff(arg0).eval(arg1) + ctx = arg0.ctx + res = isl.isl_aff_eval(isl.isl_aff_copy(arg0.ptr), isl.isl_point_copy(arg1.ptr)) + obj = val(ctx=ctx, ptr=res) + return obj + def floor(arg0): + try: + if not arg0.__class__ is aff: + arg0 = aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_aff_floor(isl.isl_aff_copy(arg0.ptr)) + obj = aff(ctx=ctx, ptr=res) + return obj + def ge_set(arg0, arg1): + try: + if not arg0.__class__ is aff: + arg0 = aff(arg0) + except: + raise + try: + if not arg1.__class__ is aff: + arg1 = aff(arg1) + except: + return pw_aff(arg0).ge_set(arg1) + ctx = arg0.ctx + res = isl.isl_aff_ge_set(isl.isl_aff_copy(arg0.ptr), isl.isl_aff_copy(arg1.ptr)) + obj = set(ctx=ctx, ptr=res) + return obj + def gist(arg0, arg1): + try: + if not arg0.__class__ is aff: + arg0 = aff(arg0) + except: + raise + try: + if not arg1.__class__ is set: + arg1 = set(arg1) + except: + return pw_aff(arg0).gist(arg1) + ctx = arg0.ctx + res = isl.isl_aff_gist(isl.isl_aff_copy(arg0.ptr), isl.isl_set_copy(arg1.ptr)) + obj = aff(ctx=ctx, ptr=res) + return obj + def gist_params(arg0, arg1): + try: + if not arg0.__class__ is aff: + arg0 = aff(arg0) + except: + raise + try: + if not arg1.__class__ is set: + arg1 = set(arg1) + except: + return pw_aff(arg0).gist_params(arg1) + ctx = arg0.ctx + res = isl.isl_aff_gist_params(isl.isl_aff_copy(arg0.ptr), isl.isl_set_copy(arg1.ptr)) + obj = aff(ctx=ctx, ptr=res) + return obj + def gt_set(arg0, arg1): + try: + if not arg0.__class__ is aff: + arg0 = aff(arg0) + except: + raise + try: + if not arg1.__class__ is aff: + arg1 = aff(arg1) + except: + return pw_aff(arg0).gt_set(arg1) + ctx = arg0.ctx + res = isl.isl_aff_gt_set(isl.isl_aff_copy(arg0.ptr), isl.isl_aff_copy(arg1.ptr)) + obj = set(ctx=ctx, ptr=res) + return obj + def is_cst(arg0): + try: + if not arg0.__class__ is aff: + arg0 = aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_aff_is_cst(arg0.ptr) + if res < 0: + raise Error + return bool(res) + def le_set(arg0, arg1): + try: + if not arg0.__class__ is aff: + arg0 = aff(arg0) + except: + raise + try: + if not arg1.__class__ is aff: + arg1 = aff(arg1) + except: + return pw_aff(arg0).le_set(arg1) + ctx = arg0.ctx + res = isl.isl_aff_le_set(isl.isl_aff_copy(arg0.ptr), isl.isl_aff_copy(arg1.ptr)) + obj = set(ctx=ctx, ptr=res) + return obj + def lt_set(arg0, arg1): + try: + if not arg0.__class__ is aff: + arg0 = aff(arg0) + except: + raise + try: + if not arg1.__class__ is aff: + arg1 = aff(arg1) + except: + return pw_aff(arg0).lt_set(arg1) + ctx = arg0.ctx + res = isl.isl_aff_lt_set(isl.isl_aff_copy(arg0.ptr), isl.isl_aff_copy(arg1.ptr)) + obj = set(ctx=ctx, ptr=res) + return obj + def mod(*args): + if len(args) == 2 and (args[1].__class__ is val or type(args[1]) == int): + args = list(args) + try: + if not args[0].__class__ is aff: + args[0] = aff(args[0]) + except: + raise + try: + if not args[1].__class__ is val: + args[1] = val(args[1]) + except: + raise + ctx = args[0].ctx + res = isl.isl_aff_mod_val(isl.isl_aff_copy(args[0].ptr), isl.isl_val_copy(args[1].ptr)) + obj = aff(ctx=ctx, ptr=res) + return obj + raise Error + def mul(arg0, arg1): + try: + if not arg0.__class__ is aff: + arg0 = aff(arg0) + except: + raise + try: + if not arg1.__class__ is aff: + arg1 = aff(arg1) + except: + return pw_aff(arg0).mul(arg1) + ctx = arg0.ctx + res = isl.isl_aff_mul(isl.isl_aff_copy(arg0.ptr), isl.isl_aff_copy(arg1.ptr)) + obj = aff(ctx=ctx, ptr=res) + return obj + def ne_set(arg0, arg1): + try: + if not arg0.__class__ is aff: + arg0 = aff(arg0) + except: + raise + try: + if not arg1.__class__ is aff: + arg1 = aff(arg1) + except: + return pw_aff(arg0).ne_set(arg1) + ctx = arg0.ctx + res = isl.isl_aff_ne_set(isl.isl_aff_copy(arg0.ptr), isl.isl_aff_copy(arg1.ptr)) + obj = set(ctx=ctx, ptr=res) + return obj + def neg(arg0): + try: + if not arg0.__class__ is aff: + arg0 = aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_aff_neg(isl.isl_aff_copy(arg0.ptr)) + obj = aff(ctx=ctx, ptr=res) + return obj + def plain_is_equal(arg0, arg1): + try: + if not arg0.__class__ is aff: + arg0 = aff(arg0) + except: + raise + try: + if not arg1.__class__ is aff: + arg1 = aff(arg1) + except: + return pw_aff(arg0).plain_is_equal(arg1) + ctx = arg0.ctx + res = isl.isl_aff_plain_is_equal(arg0.ptr, arg1.ptr) + if res < 0: + raise Error + return bool(res) + def pullback(*args): + if len(args) == 2 and args[1].__class__ is multi_aff: + args = list(args) + try: + if not args[0].__class__ is aff: + args[0] = aff(args[0]) + except: + raise + ctx = args[0].ctx + res = isl.isl_aff_pullback_multi_aff(isl.isl_aff_copy(args[0].ptr), isl.isl_multi_aff_copy(args[1].ptr)) + obj = aff(ctx=ctx, ptr=res) + return obj + raise Error + def scale(*args): + if len(args) == 2 and (args[1].__class__ is val or type(args[1]) == int): + args = list(args) + try: + if not args[0].__class__ is aff: + args[0] = aff(args[0]) + except: + raise + try: + if not args[1].__class__ is val: + args[1] = val(args[1]) + except: + raise + ctx = args[0].ctx + res = isl.isl_aff_scale_val(isl.isl_aff_copy(args[0].ptr), isl.isl_val_copy(args[1].ptr)) + obj = aff(ctx=ctx, ptr=res) + return obj + raise Error + def scale_down(*args): + if len(args) == 2 and (args[1].__class__ is val or type(args[1]) == int): + args = list(args) + try: + if not args[0].__class__ is aff: + args[0] = aff(args[0]) + except: + raise + try: + if not args[1].__class__ is val: + args[1] = val(args[1]) + except: + raise + ctx = args[0].ctx + res = isl.isl_aff_scale_down_val(isl.isl_aff_copy(args[0].ptr), isl.isl_val_copy(args[1].ptr)) + obj = aff(ctx=ctx, ptr=res) + return obj + raise Error + def sub(arg0, arg1): + try: + if not arg0.__class__ is aff: + arg0 = aff(arg0) + except: + raise + try: + if not arg1.__class__ is aff: + arg1 = aff(arg1) + except: + return pw_aff(arg0).sub(arg1) + ctx = arg0.ctx + res = isl.isl_aff_sub(isl.isl_aff_copy(arg0.ptr), isl.isl_aff_copy(arg1.ptr)) + obj = aff(ctx=ctx, ptr=res) + return obj + def to_list(arg0): + try: + if not arg0.__class__ is aff: + arg0 = aff(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_aff_to_list(isl.isl_aff_copy(arg0.ptr)) + obj = aff_list(ctx=ctx, ptr=res) + return obj + def unbind_params_insert_domain(arg0, arg1): + try: + if not arg0.__class__ is aff: + arg0 = aff(arg0) + except: + raise + try: + if not arg1.__class__ is multi_id: + arg1 = multi_id(arg1) + except: + return pw_aff(arg0).unbind_params_insert_domain(arg1) + ctx = arg0.ctx + res = isl.isl_aff_unbind_params_insert_domain(isl.isl_aff_copy(arg0.ptr), isl.isl_multi_id_copy(arg1.ptr)) + obj = aff(ctx=ctx, ptr=res) + return obj + @staticmethod + def zero_on_domain(*args): + if len(args) == 1 and args[0].__class__ is space: + ctx = args[0].ctx + res = isl.isl_aff_zero_on_domain_space(isl.isl_space_copy(args[0].ptr)) + obj = aff(ctx=ctx, ptr=res) + return obj + raise Error + +isl.isl_aff_read_from_str.restype = c_void_p +isl.isl_aff_read_from_str.argtypes = [Context, c_char_p] +isl.isl_aff_add.restype = c_void_p +isl.isl_aff_add.argtypes = [c_void_p, c_void_p] +isl.isl_aff_add_constant_val.restype = c_void_p +isl.isl_aff_add_constant_val.argtypes = [c_void_p, c_void_p] +isl.isl_aff_bind_id.restype = c_void_p +isl.isl_aff_bind_id.argtypes = [c_void_p, c_void_p] +isl.isl_aff_ceil.restype = c_void_p +isl.isl_aff_ceil.argtypes = [c_void_p] +isl.isl_aff_get_constant_val.restype = c_void_p +isl.isl_aff_get_constant_val.argtypes = [c_void_p] +isl.isl_aff_div.restype = c_void_p +isl.isl_aff_div.argtypes = [c_void_p, c_void_p] +isl.isl_aff_domain_reverse.restype = c_void_p +isl.isl_aff_domain_reverse.argtypes = [c_void_p] +isl.isl_aff_eq_set.restype = c_void_p +isl.isl_aff_eq_set.argtypes = [c_void_p, c_void_p] +isl.isl_aff_eval.restype = c_void_p +isl.isl_aff_eval.argtypes = [c_void_p, c_void_p] +isl.isl_aff_floor.restype = c_void_p +isl.isl_aff_floor.argtypes = [c_void_p] +isl.isl_aff_ge_set.restype = c_void_p +isl.isl_aff_ge_set.argtypes = [c_void_p, c_void_p] +isl.isl_aff_gist.restype = c_void_p +isl.isl_aff_gist.argtypes = [c_void_p, c_void_p] +isl.isl_aff_gist_params.restype = c_void_p +isl.isl_aff_gist_params.argtypes = [c_void_p, c_void_p] +isl.isl_aff_gt_set.restype = c_void_p +isl.isl_aff_gt_set.argtypes = [c_void_p, c_void_p] +isl.isl_aff_is_cst.argtypes = [c_void_p] +isl.isl_aff_le_set.restype = c_void_p +isl.isl_aff_le_set.argtypes = [c_void_p, c_void_p] +isl.isl_aff_lt_set.restype = c_void_p +isl.isl_aff_lt_set.argtypes = [c_void_p, c_void_p] +isl.isl_aff_mod_val.restype = c_void_p +isl.isl_aff_mod_val.argtypes = [c_void_p, c_void_p] +isl.isl_aff_mul.restype = c_void_p +isl.isl_aff_mul.argtypes = [c_void_p, c_void_p] +isl.isl_aff_ne_set.restype = c_void_p +isl.isl_aff_ne_set.argtypes = [c_void_p, c_void_p] +isl.isl_aff_neg.restype = c_void_p +isl.isl_aff_neg.argtypes = [c_void_p] +isl.isl_aff_plain_is_equal.argtypes = [c_void_p, c_void_p] +isl.isl_aff_pullback_multi_aff.restype = c_void_p +isl.isl_aff_pullback_multi_aff.argtypes = [c_void_p, c_void_p] +isl.isl_aff_scale_val.restype = c_void_p +isl.isl_aff_scale_val.argtypes = [c_void_p, c_void_p] +isl.isl_aff_scale_down_val.restype = c_void_p +isl.isl_aff_scale_down_val.argtypes = [c_void_p, c_void_p] +isl.isl_aff_sub.restype = c_void_p +isl.isl_aff_sub.argtypes = [c_void_p, c_void_p] +isl.isl_aff_to_list.restype = c_void_p +isl.isl_aff_to_list.argtypes = [c_void_p] +isl.isl_aff_unbind_params_insert_domain.restype = c_void_p +isl.isl_aff_unbind_params_insert_domain.argtypes = [c_void_p, c_void_p] +isl.isl_aff_zero_on_domain_space.restype = c_void_p +isl.isl_aff_zero_on_domain_space.argtypes = [c_void_p] +isl.isl_aff_copy.restype = c_void_p +isl.isl_aff_copy.argtypes = [c_void_p] +isl.isl_aff_free.restype = c_void_p +isl.isl_aff_free.argtypes = [c_void_p] +isl.isl_aff_to_str.restype = POINTER(c_char) +isl.isl_aff_to_str.argtypes = [c_void_p] + +class aff_list(object): + def __init__(self, *args, **keywords): + if "ptr" in keywords: + self.ctx = keywords["ctx"] + self.ptr = keywords["ptr"] + return + if len(args) == 1 and type(args[0]) == int: + self.ctx = Context.getDefaultInstance() + self.ptr = isl.isl_aff_list_alloc(self.ctx, args[0]) + return + if len(args) == 1 and args[0].__class__ is aff: + self.ctx = Context.getDefaultInstance() + self.ptr = isl.isl_aff_list_from_aff(isl.isl_aff_copy(args[0].ptr)) + return + if len(args) == 1 and type(args[0]) == str: + self.ctx = Context.getDefaultInstance() + self.ptr = isl.isl_aff_list_read_from_str(self.ctx, args[0].encode('ascii')) + return + raise Error + def __del__(self): + if hasattr(self, 'ptr'): + isl.isl_aff_list_free(self.ptr) + def __str__(arg0): + try: + if not arg0.__class__ is aff_list: + arg0 = aff_list(arg0) + except: + raise + ptr = isl.isl_aff_list_to_str(arg0.ptr) + res = cast(ptr, c_char_p).value.decode('ascii') + libc.free(ptr) + return res + def __repr__(self): + s = str(self) + if '"' in s: + return 'isl.aff_list("""%s""")' % s + else: + return 'isl.aff_list("%s")' % s + def add(arg0, arg1): + try: + if not arg0.__class__ is aff_list: + arg0 = aff_list(arg0) + except: + raise + try: + if not arg1.__class__ is aff: + arg1 = aff(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_aff_list_add(isl.isl_aff_list_copy(arg0.ptr), isl.isl_aff_copy(arg1.ptr)) + obj = aff_list(ctx=ctx, ptr=res) + return obj + def at(arg0, arg1): + try: + if not arg0.__class__ is aff_list: + arg0 = aff_list(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_aff_list_get_at(arg0.ptr, arg1) + obj = aff(ctx=ctx, ptr=res) + return obj + def get_at(arg0, arg1): + return arg0.at(arg1) + def clear(arg0): + try: + if not arg0.__class__ is aff_list: + arg0 = aff_list(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_aff_list_clear(isl.isl_aff_list_copy(arg0.ptr)) + obj = aff_list(ctx=ctx, ptr=res) + return obj + def concat(arg0, arg1): + try: + if not arg0.__class__ is aff_list: + arg0 = aff_list(arg0) + except: + raise + try: + if not arg1.__class__ is aff_list: + arg1 = aff_list(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_aff_list_concat(isl.isl_aff_list_copy(arg0.ptr), isl.isl_aff_list_copy(arg1.ptr)) + obj = aff_list(ctx=ctx, ptr=res) + return obj + def drop(arg0, arg1, arg2): + try: + if not arg0.__class__ is aff_list: + arg0 = aff_list(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_aff_list_drop(isl.isl_aff_list_copy(arg0.ptr), arg1, arg2) + obj = aff_list(ctx=ctx, ptr=res) + return obj + def foreach(arg0, arg1): + try: + if not arg0.__class__ is aff_list: + arg0 = aff_list(arg0) + except: + raise + exc_info = [None] + fn = CFUNCTYPE(c_int, c_void_p, c_void_p) + def cb_func(cb_arg0, cb_arg1): + cb_arg0 = aff(ctx=arg0.ctx, ptr=(cb_arg0)) + try: + arg1(cb_arg0) + except BaseException as e: + exc_info[0] = e + return -1 + return 0 + cb1 = fn(cb_func) + ctx = arg0.ctx + res = isl.isl_aff_list_foreach(arg0.ptr, cb1, None) + if exc_info[0] is not None: + raise exc_info[0] + if res < 0: + raise Error + def foreach_scc(arg0, arg1, arg2): + try: + if not arg0.__class__ is aff_list: + arg0 = aff_list(arg0) + except: + raise + exc_info = [None] + fn = CFUNCTYPE(c_int, c_void_p, c_void_p, c_void_p) + def cb_func(cb_arg0, cb_arg1, cb_arg2): + cb_arg0 = aff(ctx=arg0.ctx, ptr=isl.isl_aff_copy(cb_arg0)) + cb_arg1 = aff(ctx=arg0.ctx, ptr=isl.isl_aff_copy(cb_arg1)) + try: + res = arg1(cb_arg0, cb_arg1) + except BaseException as e: + exc_info[0] = e + return -1 + return 1 if res else 0 + cb1 = fn(cb_func) + exc_info = [None] + fn = CFUNCTYPE(c_int, c_void_p, c_void_p) + def cb_func(cb_arg0, cb_arg1): + cb_arg0 = aff_list(ctx=arg0.ctx, ptr=(cb_arg0)) + try: + arg2(cb_arg0) + except BaseException as e: + exc_info[0] = e + return -1 + return 0 + cb2 = fn(cb_func) + ctx = arg0.ctx + res = isl.isl_aff_list_foreach_scc(arg0.ptr, cb1, None, cb2, None) + if exc_info[0] is not None: + raise exc_info[0] + if res < 0: + raise Error + def insert(arg0, arg1, arg2): + try: + if not arg0.__class__ is aff_list: + arg0 = aff_list(arg0) + except: + raise + try: + if not arg2.__class__ is aff: + arg2 = aff(arg2) + except: + raise + ctx = arg0.ctx + res = isl.isl_aff_list_insert(isl.isl_aff_list_copy(arg0.ptr), arg1, isl.isl_aff_copy(arg2.ptr)) + obj = aff_list(ctx=ctx, ptr=res) + return obj + def set_at(arg0, arg1, arg2): + try: + if not arg0.__class__ is aff_list: + arg0 = aff_list(arg0) + except: + raise + try: + if not arg2.__class__ is aff: + arg2 = aff(arg2) + except: + raise + ctx = arg0.ctx + res = isl.isl_aff_list_set_at(isl.isl_aff_list_copy(arg0.ptr), arg1, isl.isl_aff_copy(arg2.ptr)) + obj = aff_list(ctx=ctx, ptr=res) + return obj + def size(arg0): + try: + if not arg0.__class__ is aff_list: + arg0 = aff_list(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_aff_list_size(arg0.ptr) + if res < 0: + raise Error + return int(res) + +isl.isl_aff_list_alloc.restype = c_void_p +isl.isl_aff_list_alloc.argtypes = [Context, c_int] +isl.isl_aff_list_from_aff.restype = c_void_p +isl.isl_aff_list_from_aff.argtypes = [c_void_p] +isl.isl_aff_list_read_from_str.restype = c_void_p +isl.isl_aff_list_read_from_str.argtypes = [Context, c_char_p] +isl.isl_aff_list_add.restype = c_void_p +isl.isl_aff_list_add.argtypes = [c_void_p, c_void_p] +isl.isl_aff_list_get_at.restype = c_void_p +isl.isl_aff_list_get_at.argtypes = [c_void_p, c_int] +isl.isl_aff_list_clear.restype = c_void_p +isl.isl_aff_list_clear.argtypes = [c_void_p] +isl.isl_aff_list_concat.restype = c_void_p +isl.isl_aff_list_concat.argtypes = [c_void_p, c_void_p] +isl.isl_aff_list_drop.restype = c_void_p +isl.isl_aff_list_drop.argtypes = [c_void_p, c_int, c_int] +isl.isl_aff_list_foreach.argtypes = [c_void_p, c_void_p, c_void_p] +isl.isl_aff_list_foreach_scc.argtypes = [c_void_p, c_void_p, c_void_p, c_void_p, c_void_p] +isl.isl_aff_list_insert.restype = c_void_p +isl.isl_aff_list_insert.argtypes = [c_void_p, c_int, c_void_p] +isl.isl_aff_list_set_at.restype = c_void_p +isl.isl_aff_list_set_at.argtypes = [c_void_p, c_int, c_void_p] +isl.isl_aff_list_size.argtypes = [c_void_p] +isl.isl_aff_list_copy.restype = c_void_p +isl.isl_aff_list_copy.argtypes = [c_void_p] +isl.isl_aff_list_free.restype = c_void_p +isl.isl_aff_list_free.argtypes = [c_void_p] +isl.isl_aff_list_to_str.restype = POINTER(c_char) +isl.isl_aff_list_to_str.argtypes = [c_void_p] + +class ast_build(object): + def __init__(self, *args, **keywords): + if "ptr" in keywords: + self.ctx = keywords["ctx"] + self.ptr = keywords["ptr"] + return + if len(args) == 0: + self.ctx = Context.getDefaultInstance() + self.ptr = isl.isl_ast_build_alloc(self.ctx) + return + raise Error + def __del__(self): + if hasattr(self, 'ptr'): + isl.isl_ast_build_free(self.ptr) + def copy_callbacks(self, obj): + if hasattr(obj, 'at_each_domain'): + self.at_each_domain = obj.at_each_domain + def set_at_each_domain(arg0, arg1): + try: + if not arg0.__class__ is ast_build: + arg0 = ast_build(arg0) + except: + raise + exc_info = [None] + fn = CFUNCTYPE(c_void_p, c_void_p, c_void_p, c_void_p) + def cb_func(cb_arg0, cb_arg1, cb_arg2): + cb_arg0 = ast_node(ctx=arg0.ctx, ptr=(cb_arg0)) + cb_arg1 = ast_build(ctx=arg0.ctx, ptr=isl.isl_ast_build_copy(cb_arg1)) + try: + res = arg1(cb_arg0, cb_arg1) + except BaseException as e: + exc_info[0] = e + return None + return isl.isl_ast_node_copy(res.ptr) + cb1 = fn(cb_func) + ctx = arg0.ctx + res = isl.isl_ast_build_set_at_each_domain(isl.isl_ast_build_copy(arg0.ptr), cb1, None) + if exc_info[0] is not None: + raise exc_info[0] + if hasattr(arg0, 'at_each_domain') and arg0.at_each_domain['exc_info'] != None: + exc_info = arg0.at_each_domain['exc_info'][0] + arg0.at_each_domain['exc_info'][0] = None + if exc_info is not None: + raise exc_info + obj = ast_build(ctx=ctx, ptr=res) + obj.copy_callbacks(arg0) + obj.at_each_domain = { 'func': cb1, 'exc_info': exc_info } + return obj + def access_from(*args): + if len(args) == 2 and args[1].__class__ is multi_pw_aff: + args = list(args) + try: + if not args[0].__class__ is ast_build: + args[0] = ast_build(args[0]) + except: + raise + ctx = args[0].ctx + res = isl.isl_ast_build_access_from_multi_pw_aff(args[0].ptr, isl.isl_multi_pw_aff_copy(args[1].ptr)) + if hasattr(args[0], 'at_each_domain') and args[0].at_each_domain['exc_info'] != None: + exc_info = args[0].at_each_domain['exc_info'][0] + args[0].at_each_domain['exc_info'][0] = None + if exc_info is not None: + raise exc_info + obj = ast_expr(ctx=ctx, ptr=res) + return obj + if len(args) == 2 and args[1].__class__ is pw_multi_aff: + args = list(args) + try: + if not args[0].__class__ is ast_build: + args[0] = ast_build(args[0]) + except: + raise + ctx = args[0].ctx + res = isl.isl_ast_build_access_from_pw_multi_aff(args[0].ptr, isl.isl_pw_multi_aff_copy(args[1].ptr)) + if hasattr(args[0], 'at_each_domain') and args[0].at_each_domain['exc_info'] != None: + exc_info = args[0].at_each_domain['exc_info'][0] + args[0].at_each_domain['exc_info'][0] = None + if exc_info is not None: + raise exc_info + obj = ast_expr(ctx=ctx, ptr=res) + return obj + raise Error + def call_from(*args): + if len(args) == 2 and args[1].__class__ is multi_pw_aff: + args = list(args) + try: + if not args[0].__class__ is ast_build: + args[0] = ast_build(args[0]) + except: + raise + ctx = args[0].ctx + res = isl.isl_ast_build_call_from_multi_pw_aff(args[0].ptr, isl.isl_multi_pw_aff_copy(args[1].ptr)) + if hasattr(args[0], 'at_each_domain') and args[0].at_each_domain['exc_info'] != None: + exc_info = args[0].at_each_domain['exc_info'][0] + args[0].at_each_domain['exc_info'][0] = None + if exc_info is not None: + raise exc_info + obj = ast_expr(ctx=ctx, ptr=res) + return obj + if len(args) == 2 and args[1].__class__ is pw_multi_aff: + args = list(args) + try: + if not args[0].__class__ is ast_build: + args[0] = ast_build(args[0]) + except: + raise + ctx = args[0].ctx + res = isl.isl_ast_build_call_from_pw_multi_aff(args[0].ptr, isl.isl_pw_multi_aff_copy(args[1].ptr)) + if hasattr(args[0], 'at_each_domain') and args[0].at_each_domain['exc_info'] != None: + exc_info = args[0].at_each_domain['exc_info'][0] + args[0].at_each_domain['exc_info'][0] = None + if exc_info is not None: + raise exc_info + obj = ast_expr(ctx=ctx, ptr=res) + return obj + raise Error + def expr_from(*args): + if len(args) == 2 and args[1].__class__ is pw_aff: + args = list(args) + try: + if not args[0].__class__ is ast_build: + args[0] = ast_build(args[0]) + except: + raise + ctx = args[0].ctx + res = isl.isl_ast_build_expr_from_pw_aff(args[0].ptr, isl.isl_pw_aff_copy(args[1].ptr)) + if hasattr(args[0], 'at_each_domain') and args[0].at_each_domain['exc_info'] != None: + exc_info = args[0].at_each_domain['exc_info'][0] + args[0].at_each_domain['exc_info'][0] = None + if exc_info is not None: + raise exc_info + obj = ast_expr(ctx=ctx, ptr=res) + return obj + if len(args) == 2 and args[1].__class__ is set: + args = list(args) + try: + if not args[0].__class__ is ast_build: + args[0] = ast_build(args[0]) + except: + raise + ctx = args[0].ctx + res = isl.isl_ast_build_expr_from_set(args[0].ptr, isl.isl_set_copy(args[1].ptr)) + if hasattr(args[0], 'at_each_domain') and args[0].at_each_domain['exc_info'] != None: + exc_info = args[0].at_each_domain['exc_info'][0] + args[0].at_each_domain['exc_info'][0] = None + if exc_info is not None: + raise exc_info + obj = ast_expr(ctx=ctx, ptr=res) + return obj + raise Error + @staticmethod + def from_context(arg0): + try: + if not arg0.__class__ is set: + arg0 = set(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_ast_build_from_context(isl.isl_set_copy(arg0.ptr)) + obj = ast_build(ctx=ctx, ptr=res) + return obj + def node_from(*args): + if len(args) == 2 and args[1].__class__ is schedule: + args = list(args) + try: + if not args[0].__class__ is ast_build: + args[0] = ast_build(args[0]) + except: + raise + ctx = args[0].ctx + res = isl.isl_ast_build_node_from_schedule(args[0].ptr, isl.isl_schedule_copy(args[1].ptr)) + if hasattr(args[0], 'at_each_domain') and args[0].at_each_domain['exc_info'] != None: + exc_info = args[0].at_each_domain['exc_info'][0] + args[0].at_each_domain['exc_info'][0] = None + if exc_info is not None: + raise exc_info + obj = ast_node(ctx=ctx, ptr=res) + return obj + raise Error + def node_from_schedule_map(arg0, arg1): + try: + if not arg0.__class__ is ast_build: + arg0 = ast_build(arg0) + except: + raise + try: + if not arg1.__class__ is union_map: + arg1 = union_map(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_ast_build_node_from_schedule_map(arg0.ptr, isl.isl_union_map_copy(arg1.ptr)) + if hasattr(arg0, 'at_each_domain') and arg0.at_each_domain['exc_info'] != None: + exc_info = arg0.at_each_domain['exc_info'][0] + arg0.at_each_domain['exc_info'][0] = None + if exc_info is not None: + raise exc_info + obj = ast_node(ctx=ctx, ptr=res) + return obj + def schedule(arg0): + try: + if not arg0.__class__ is ast_build: + arg0 = ast_build(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_ast_build_get_schedule(arg0.ptr) + if hasattr(arg0, 'at_each_domain') and arg0.at_each_domain['exc_info'] != None: + exc_info = arg0.at_each_domain['exc_info'][0] + arg0.at_each_domain['exc_info'][0] = None + if exc_info is not None: + raise exc_info + obj = union_map(ctx=ctx, ptr=res) + return obj + def get_schedule(arg0): + return arg0.schedule() + +isl.isl_ast_build_alloc.restype = c_void_p +isl.isl_ast_build_alloc.argtypes = [Context] +isl.isl_ast_build_set_at_each_domain.restype = c_void_p +isl.isl_ast_build_set_at_each_domain.argtypes = [c_void_p, c_void_p, c_void_p] +isl.isl_ast_build_access_from_multi_pw_aff.restype = c_void_p +isl.isl_ast_build_access_from_multi_pw_aff.argtypes = [c_void_p, c_void_p] +isl.isl_ast_build_access_from_pw_multi_aff.restype = c_void_p +isl.isl_ast_build_access_from_pw_multi_aff.argtypes = [c_void_p, c_void_p] +isl.isl_ast_build_call_from_multi_pw_aff.restype = c_void_p +isl.isl_ast_build_call_from_multi_pw_aff.argtypes = [c_void_p, c_void_p] +isl.isl_ast_build_call_from_pw_multi_aff.restype = c_void_p +isl.isl_ast_build_call_from_pw_multi_aff.argtypes = [c_void_p, c_void_p] +isl.isl_ast_build_expr_from_pw_aff.restype = c_void_p +isl.isl_ast_build_expr_from_pw_aff.argtypes = [c_void_p, c_void_p] +isl.isl_ast_build_expr_from_set.restype = c_void_p +isl.isl_ast_build_expr_from_set.argtypes = [c_void_p, c_void_p] +isl.isl_ast_build_from_context.restype = c_void_p +isl.isl_ast_build_from_context.argtypes = [c_void_p] +isl.isl_ast_build_node_from_schedule.restype = c_void_p +isl.isl_ast_build_node_from_schedule.argtypes = [c_void_p, c_void_p] +isl.isl_ast_build_node_from_schedule_map.restype = c_void_p +isl.isl_ast_build_node_from_schedule_map.argtypes = [c_void_p, c_void_p] +isl.isl_ast_build_get_schedule.restype = c_void_p +isl.isl_ast_build_get_schedule.argtypes = [c_void_p] +isl.isl_ast_build_copy.restype = c_void_p +isl.isl_ast_build_copy.argtypes = [c_void_p] +isl.isl_ast_build_free.restype = c_void_p +isl.isl_ast_build_free.argtypes = [c_void_p] + +class ast_expr(object): + def __init__(self, *args, **keywords): + if "ptr" in keywords: + self.ctx = keywords["ctx"] + self.ptr = keywords["ptr"] + return + if len(args) == 1 and isinstance(args[0], ast_expr_op): + self.ctx = args[0].ctx + self.ptr = isl.isl_ast_expr_copy(args[0].ptr) + return + if len(args) == 1 and isinstance(args[0], ast_expr_id): + self.ctx = args[0].ctx + self.ptr = isl.isl_ast_expr_copy(args[0].ptr) + return + if len(args) == 1 and isinstance(args[0], ast_expr_int): + self.ctx = args[0].ctx + self.ptr = isl.isl_ast_expr_copy(args[0].ptr) + return + raise Error + def __del__(self): + if hasattr(self, 'ptr'): + isl.isl_ast_expr_free(self.ptr) + def __new__(cls, *args, **keywords): + if "ptr" in keywords: + type = isl.isl_ast_expr_get_type(keywords["ptr"]) + if type == 0: + return ast_expr_op(**keywords) + if type == 1: + return ast_expr_id(**keywords) + if type == 2: + return ast_expr_int(**keywords) + raise Error + return super(ast_expr, cls).__new__(cls) + def __str__(arg0): + try: + if not arg0.__class__ is ast_expr: + arg0 = ast_expr(arg0) + except: + raise + ptr = isl.isl_ast_expr_to_str(arg0.ptr) + res = cast(ptr, c_char_p).value.decode('ascii') + libc.free(ptr) + return res + def __repr__(self): + s = str(self) + if '"' in s: + return 'isl.ast_expr("""%s""")' % s + else: + return 'isl.ast_expr("%s")' % s + def to_C_str(arg0): + try: + if not arg0.__class__ is ast_expr: + arg0 = ast_expr(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_ast_expr_to_C_str(arg0.ptr) + if res == 0: + raise Error + string = cast(res, c_char_p).value.decode('ascii') + libc.free(res) + return string + +isl.isl_ast_expr_to_C_str.restype = POINTER(c_char) +isl.isl_ast_expr_to_C_str.argtypes = [c_void_p] +isl.isl_ast_expr_copy.restype = c_void_p +isl.isl_ast_expr_copy.argtypes = [c_void_p] +isl.isl_ast_expr_free.restype = c_void_p +isl.isl_ast_expr_free.argtypes = [c_void_p] +isl.isl_ast_expr_to_str.restype = POINTER(c_char) +isl.isl_ast_expr_to_str.argtypes = [c_void_p] +isl.isl_ast_expr_get_type.argtypes = [c_void_p] + +class ast_expr_id(ast_expr): + def __init__(self, *args, **keywords): + if "ptr" in keywords: + self.ctx = keywords["ctx"] + self.ptr = keywords["ptr"] + return + raise Error + def __del__(self): + if hasattr(self, 'ptr'): + isl.isl_ast_expr_free(self.ptr) + def __new__(cls, *args, **keywords): + return super(ast_expr_id, cls).__new__(cls) + def __str__(arg0): + try: + if not arg0.__class__ is ast_expr_id: + arg0 = ast_expr_id(arg0) + except: + raise + ptr = isl.isl_ast_expr_to_str(arg0.ptr) + res = cast(ptr, c_char_p).value.decode('ascii') + libc.free(ptr) + return res + def __repr__(self): + s = str(self) + if '"' in s: + return 'isl.ast_expr_id("""%s""")' % s + else: + return 'isl.ast_expr_id("%s")' % s + def id(arg0): + try: + if not arg0.__class__ is ast_expr: + arg0 = ast_expr(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_ast_expr_id_get_id(arg0.ptr) + obj = id(ctx=ctx, ptr=res) + return obj + def get_id(arg0): + return arg0.id() + +isl.isl_ast_expr_id_get_id.restype = c_void_p +isl.isl_ast_expr_id_get_id.argtypes = [c_void_p] +isl.isl_ast_expr_copy.restype = c_void_p +isl.isl_ast_expr_copy.argtypes = [c_void_p] +isl.isl_ast_expr_free.restype = c_void_p +isl.isl_ast_expr_free.argtypes = [c_void_p] +isl.isl_ast_expr_to_str.restype = POINTER(c_char) +isl.isl_ast_expr_to_str.argtypes = [c_void_p] + +class ast_expr_int(ast_expr): + def __init__(self, *args, **keywords): + if "ptr" in keywords: + self.ctx = keywords["ctx"] + self.ptr = keywords["ptr"] + return + raise Error + def __del__(self): + if hasattr(self, 'ptr'): + isl.isl_ast_expr_free(self.ptr) + def __new__(cls, *args, **keywords): + return super(ast_expr_int, cls).__new__(cls) + def __str__(arg0): + try: + if not arg0.__class__ is ast_expr_int: + arg0 = ast_expr_int(arg0) + except: + raise + ptr = isl.isl_ast_expr_to_str(arg0.ptr) + res = cast(ptr, c_char_p).value.decode('ascii') + libc.free(ptr) + return res + def __repr__(self): + s = str(self) + if '"' in s: + return 'isl.ast_expr_int("""%s""")' % s + else: + return 'isl.ast_expr_int("%s")' % s + def val(arg0): + try: + if not arg0.__class__ is ast_expr: + arg0 = ast_expr(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_ast_expr_int_get_val(arg0.ptr) + obj = val(ctx=ctx, ptr=res) + return obj + def get_val(arg0): + return arg0.val() + +isl.isl_ast_expr_int_get_val.restype = c_void_p +isl.isl_ast_expr_int_get_val.argtypes = [c_void_p] +isl.isl_ast_expr_copy.restype = c_void_p +isl.isl_ast_expr_copy.argtypes = [c_void_p] +isl.isl_ast_expr_free.restype = c_void_p +isl.isl_ast_expr_free.argtypes = [c_void_p] +isl.isl_ast_expr_to_str.restype = POINTER(c_char) +isl.isl_ast_expr_to_str.argtypes = [c_void_p] + +class ast_expr_op(ast_expr): + def __init__(self, *args, **keywords): + if "ptr" in keywords: + self.ctx = keywords["ctx"] + self.ptr = keywords["ptr"] + return + if len(args) == 1 and isinstance(args[0], ast_expr_op_and): + self.ctx = args[0].ctx + self.ptr = isl.isl_ast_expr_copy(args[0].ptr) + return + if len(args) == 1 and isinstance(args[0], ast_expr_op_and_then): + self.ctx = args[0].ctx + self.ptr = isl.isl_ast_expr_copy(args[0].ptr) + return + if len(args) == 1 and isinstance(args[0], ast_expr_op_or): + self.ctx = args[0].ctx + self.ptr = isl.isl_ast_expr_copy(args[0].ptr) + return + if len(args) == 1 and isinstance(args[0], ast_expr_op_or_else): + self.ctx = args[0].ctx + self.ptr = isl.isl_ast_expr_copy(args[0].ptr) + return + if len(args) == 1 and isinstance(args[0], ast_expr_op_max): + self.ctx = args[0].ctx + self.ptr = isl.isl_ast_expr_copy(args[0].ptr) + return + if len(args) == 1 and isinstance(args[0], ast_expr_op_min): + self.ctx = args[0].ctx + self.ptr = isl.isl_ast_expr_copy(args[0].ptr) + return + if len(args) == 1 and isinstance(args[0], ast_expr_op_minus): + self.ctx = args[0].ctx + self.ptr = isl.isl_ast_expr_copy(args[0].ptr) + return + if len(args) == 1 and isinstance(args[0], ast_expr_op_add): + self.ctx = args[0].ctx + self.ptr = isl.isl_ast_expr_copy(args[0].ptr) + return + if len(args) == 1 and isinstance(args[0], ast_expr_op_sub): + self.ctx = args[0].ctx + self.ptr = isl.isl_ast_expr_copy(args[0].ptr) + return + if len(args) == 1 and isinstance(args[0], ast_expr_op_mul): + self.ctx = args[0].ctx + self.ptr = isl.isl_ast_expr_copy(args[0].ptr) + return + if len(args) == 1 and isinstance(args[0], ast_expr_op_div): + self.ctx = args[0].ctx + self.ptr = isl.isl_ast_expr_copy(args[0].ptr) + return + if len(args) == 1 and isinstance(args[0], ast_expr_op_fdiv_q): + self.ctx = args[0].ctx + self.ptr = isl.isl_ast_expr_copy(args[0].ptr) + return + if len(args) == 1 and isinstance(args[0], ast_expr_op_pdiv_q): + self.ctx = args[0].ctx + self.ptr = isl.isl_ast_expr_copy(args[0].ptr) + return + if len(args) == 1 and isinstance(args[0], ast_expr_op_pdiv_r): + self.ctx = args[0].ctx + self.ptr = isl.isl_ast_expr_copy(args[0].ptr) + return + if len(args) == 1 and isinstance(args[0], ast_expr_op_zdiv_r): + self.ctx = args[0].ctx + self.ptr = isl.isl_ast_expr_copy(args[0].ptr) + return + if len(args) == 1 and isinstance(args[0], ast_expr_op_cond): + self.ctx = args[0].ctx + self.ptr = isl.isl_ast_expr_copy(args[0].ptr) + return + if len(args) == 1 and isinstance(args[0], ast_expr_op_select): + self.ctx = args[0].ctx + self.ptr = isl.isl_ast_expr_copy(args[0].ptr) + return + if len(args) == 1 and isinstance(args[0], ast_expr_op_eq): + self.ctx = args[0].ctx + self.ptr = isl.isl_ast_expr_copy(args[0].ptr) + return + if len(args) == 1 and isinstance(args[0], ast_expr_op_le): + self.ctx = args[0].ctx + self.ptr = isl.isl_ast_expr_copy(args[0].ptr) + return + if len(args) == 1 and isinstance(args[0], ast_expr_op_lt): + self.ctx = args[0].ctx + self.ptr = isl.isl_ast_expr_copy(args[0].ptr) + return + if len(args) == 1 and isinstance(args[0], ast_expr_op_ge): + self.ctx = args[0].ctx + self.ptr = isl.isl_ast_expr_copy(args[0].ptr) + return + if len(args) == 1 and isinstance(args[0], ast_expr_op_gt): + self.ctx = args[0].ctx + self.ptr = isl.isl_ast_expr_copy(args[0].ptr) + return + if len(args) == 1 and isinstance(args[0], ast_expr_op_call): + self.ctx = args[0].ctx + self.ptr = isl.isl_ast_expr_copy(args[0].ptr) + return + if len(args) == 1 and isinstance(args[0], ast_expr_op_access): + self.ctx = args[0].ctx + self.ptr = isl.isl_ast_expr_copy(args[0].ptr) + return + if len(args) == 1 and isinstance(args[0], ast_expr_op_member): + self.ctx = args[0].ctx + self.ptr = isl.isl_ast_expr_copy(args[0].ptr) + return + if len(args) == 1 and isinstance(args[0], ast_expr_op_address_of): + self.ctx = args[0].ctx + self.ptr = isl.isl_ast_expr_copy(args[0].ptr) + return + raise Error + def __del__(self): + if hasattr(self, 'ptr'): + isl.isl_ast_expr_free(self.ptr) + def __new__(cls, *args, **keywords): + if "ptr" in keywords: + type = isl.isl_ast_expr_op_get_type(keywords["ptr"]) + if type == 0: + return ast_expr_op_and(**keywords) + if type == 1: + return ast_expr_op_and_then(**keywords) + if type == 2: + return ast_expr_op_or(**keywords) + if type == 3: + return ast_expr_op_or_else(**keywords) + if type == 4: + return ast_expr_op_max(**keywords) + if type == 5: + return ast_expr_op_min(**keywords) + if type == 6: + return ast_expr_op_minus(**keywords) + if type == 7: + return ast_expr_op_add(**keywords) + if type == 8: + return ast_expr_op_sub(**keywords) + if type == 9: + return ast_expr_op_mul(**keywords) + if type == 10: + return ast_expr_op_div(**keywords) + if type == 11: + return ast_expr_op_fdiv_q(**keywords) + if type == 12: + return ast_expr_op_pdiv_q(**keywords) + if type == 13: + return ast_expr_op_pdiv_r(**keywords) + if type == 14: + return ast_expr_op_zdiv_r(**keywords) + if type == 15: + return ast_expr_op_cond(**keywords) + if type == 16: + return ast_expr_op_select(**keywords) + if type == 17: + return ast_expr_op_eq(**keywords) + if type == 18: + return ast_expr_op_le(**keywords) + if type == 19: + return ast_expr_op_lt(**keywords) + if type == 20: + return ast_expr_op_ge(**keywords) + if type == 21: + return ast_expr_op_gt(**keywords) + if type == 22: + return ast_expr_op_call(**keywords) + if type == 23: + return ast_expr_op_access(**keywords) + if type == 24: + return ast_expr_op_member(**keywords) + if type == 25: + return ast_expr_op_address_of(**keywords) + raise Error + return super(ast_expr_op, cls).__new__(cls) + def __str__(arg0): + try: + if not arg0.__class__ is ast_expr_op: + arg0 = ast_expr_op(arg0) + except: + raise + ptr = isl.isl_ast_expr_to_str(arg0.ptr) + res = cast(ptr, c_char_p).value.decode('ascii') + libc.free(ptr) + return res + def __repr__(self): + s = str(self) + if '"' in s: + return 'isl.ast_expr_op("""%s""")' % s + else: + return 'isl.ast_expr_op("%s")' % s + def arg(arg0, arg1): + try: + if not arg0.__class__ is ast_expr: + arg0 = ast_expr(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_ast_expr_op_get_arg(arg0.ptr, arg1) + obj = ast_expr(ctx=ctx, ptr=res) + return obj + def get_arg(arg0, arg1): + return arg0.arg(arg1) + def n_arg(arg0): + try: + if not arg0.__class__ is ast_expr: + arg0 = ast_expr(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_ast_expr_op_get_n_arg(arg0.ptr) + if res < 0: + raise Error + return int(res) + def get_n_arg(arg0): + return arg0.n_arg() + +isl.isl_ast_expr_op_get_arg.restype = c_void_p +isl.isl_ast_expr_op_get_arg.argtypes = [c_void_p, c_int] +isl.isl_ast_expr_op_get_n_arg.argtypes = [c_void_p] +isl.isl_ast_expr_copy.restype = c_void_p +isl.isl_ast_expr_copy.argtypes = [c_void_p] +isl.isl_ast_expr_free.restype = c_void_p +isl.isl_ast_expr_free.argtypes = [c_void_p] +isl.isl_ast_expr_to_str.restype = POINTER(c_char) +isl.isl_ast_expr_to_str.argtypes = [c_void_p] +isl.isl_ast_expr_op_get_type.argtypes = [c_void_p] + +class ast_expr_op_access(ast_expr_op): + def __init__(self, *args, **keywords): + if "ptr" in keywords: + self.ctx = keywords["ctx"] + self.ptr = keywords["ptr"] + return + raise Error + def __del__(self): + if hasattr(self, 'ptr'): + isl.isl_ast_expr_free(self.ptr) + def __new__(cls, *args, **keywords): + return super(ast_expr_op_access, cls).__new__(cls) + def __str__(arg0): + try: + if not arg0.__class__ is ast_expr_op_access: + arg0 = ast_expr_op_access(arg0) + except: + raise + ptr = isl.isl_ast_expr_to_str(arg0.ptr) + res = cast(ptr, c_char_p).value.decode('ascii') + libc.free(ptr) + return res + def __repr__(self): + s = str(self) + if '"' in s: + return 'isl.ast_expr_op_access("""%s""")' % s + else: + return 'isl.ast_expr_op_access("%s")' % s + +isl.isl_ast_expr_copy.restype = c_void_p +isl.isl_ast_expr_copy.argtypes = [c_void_p] +isl.isl_ast_expr_free.restype = c_void_p +isl.isl_ast_expr_free.argtypes = [c_void_p] +isl.isl_ast_expr_to_str.restype = POINTER(c_char) +isl.isl_ast_expr_to_str.argtypes = [c_void_p] + +class ast_expr_op_add(ast_expr_op): + def __init__(self, *args, **keywords): + if "ptr" in keywords: + self.ctx = keywords["ctx"] + self.ptr = keywords["ptr"] + return + raise Error + def __del__(self): + if hasattr(self, 'ptr'): + isl.isl_ast_expr_free(self.ptr) + def __new__(cls, *args, **keywords): + return super(ast_expr_op_add, cls).__new__(cls) + def __str__(arg0): + try: + if not arg0.__class__ is ast_expr_op_add: + arg0 = ast_expr_op_add(arg0) + except: + raise + ptr = isl.isl_ast_expr_to_str(arg0.ptr) + res = cast(ptr, c_char_p).value.decode('ascii') + libc.free(ptr) + return res + def __repr__(self): + s = str(self) + if '"' in s: + return 'isl.ast_expr_op_add("""%s""")' % s + else: + return 'isl.ast_expr_op_add("%s")' % s + +isl.isl_ast_expr_copy.restype = c_void_p +isl.isl_ast_expr_copy.argtypes = [c_void_p] +isl.isl_ast_expr_free.restype = c_void_p +isl.isl_ast_expr_free.argtypes = [c_void_p] +isl.isl_ast_expr_to_str.restype = POINTER(c_char) +isl.isl_ast_expr_to_str.argtypes = [c_void_p] + +class ast_expr_op_address_of(ast_expr_op): + def __init__(self, *args, **keywords): + if "ptr" in keywords: + self.ctx = keywords["ctx"] + self.ptr = keywords["ptr"] + return + raise Error + def __del__(self): + if hasattr(self, 'ptr'): + isl.isl_ast_expr_free(self.ptr) + def __new__(cls, *args, **keywords): + return super(ast_expr_op_address_of, cls).__new__(cls) + def __str__(arg0): + try: + if not arg0.__class__ is ast_expr_op_address_of: + arg0 = ast_expr_op_address_of(arg0) + except: + raise + ptr = isl.isl_ast_expr_to_str(arg0.ptr) + res = cast(ptr, c_char_p).value.decode('ascii') + libc.free(ptr) + return res + def __repr__(self): + s = str(self) + if '"' in s: + return 'isl.ast_expr_op_address_of("""%s""")' % s + else: + return 'isl.ast_expr_op_address_of("%s")' % s + +isl.isl_ast_expr_copy.restype = c_void_p +isl.isl_ast_expr_copy.argtypes = [c_void_p] +isl.isl_ast_expr_free.restype = c_void_p +isl.isl_ast_expr_free.argtypes = [c_void_p] +isl.isl_ast_expr_to_str.restype = POINTER(c_char) +isl.isl_ast_expr_to_str.argtypes = [c_void_p] + +class ast_expr_op_and(ast_expr_op): + def __init__(self, *args, **keywords): + if "ptr" in keywords: + self.ctx = keywords["ctx"] + self.ptr = keywords["ptr"] + return + raise Error + def __del__(self): + if hasattr(self, 'ptr'): + isl.isl_ast_expr_free(self.ptr) + def __new__(cls, *args, **keywords): + return super(ast_expr_op_and, cls).__new__(cls) + def __str__(arg0): + try: + if not arg0.__class__ is ast_expr_op_and: + arg0 = ast_expr_op_and(arg0) + except: + raise + ptr = isl.isl_ast_expr_to_str(arg0.ptr) + res = cast(ptr, c_char_p).value.decode('ascii') + libc.free(ptr) + return res + def __repr__(self): + s = str(self) + if '"' in s: + return 'isl.ast_expr_op_and("""%s""")' % s + else: + return 'isl.ast_expr_op_and("%s")' % s + +isl.isl_ast_expr_copy.restype = c_void_p +isl.isl_ast_expr_copy.argtypes = [c_void_p] +isl.isl_ast_expr_free.restype = c_void_p +isl.isl_ast_expr_free.argtypes = [c_void_p] +isl.isl_ast_expr_to_str.restype = POINTER(c_char) +isl.isl_ast_expr_to_str.argtypes = [c_void_p] + +class ast_expr_op_and_then(ast_expr_op): + def __init__(self, *args, **keywords): + if "ptr" in keywords: + self.ctx = keywords["ctx"] + self.ptr = keywords["ptr"] + return + raise Error + def __del__(self): + if hasattr(self, 'ptr'): + isl.isl_ast_expr_free(self.ptr) + def __new__(cls, *args, **keywords): + return super(ast_expr_op_and_then, cls).__new__(cls) + def __str__(arg0): + try: + if not arg0.__class__ is ast_expr_op_and_then: + arg0 = ast_expr_op_and_then(arg0) + except: + raise + ptr = isl.isl_ast_expr_to_str(arg0.ptr) + res = cast(ptr, c_char_p).value.decode('ascii') + libc.free(ptr) + return res + def __repr__(self): + s = str(self) + if '"' in s: + return 'isl.ast_expr_op_and_then("""%s""")' % s + else: + return 'isl.ast_expr_op_and_then("%s")' % s + +isl.isl_ast_expr_copy.restype = c_void_p +isl.isl_ast_expr_copy.argtypes = [c_void_p] +isl.isl_ast_expr_free.restype = c_void_p +isl.isl_ast_expr_free.argtypes = [c_void_p] +isl.isl_ast_expr_to_str.restype = POINTER(c_char) +isl.isl_ast_expr_to_str.argtypes = [c_void_p] + +class ast_expr_op_call(ast_expr_op): + def __init__(self, *args, **keywords): + if "ptr" in keywords: + self.ctx = keywords["ctx"] + self.ptr = keywords["ptr"] + return + raise Error + def __del__(self): + if hasattr(self, 'ptr'): + isl.isl_ast_expr_free(self.ptr) + def __new__(cls, *args, **keywords): + return super(ast_expr_op_call, cls).__new__(cls) + def __str__(arg0): + try: + if not arg0.__class__ is ast_expr_op_call: + arg0 = ast_expr_op_call(arg0) + except: + raise + ptr = isl.isl_ast_expr_to_str(arg0.ptr) + res = cast(ptr, c_char_p).value.decode('ascii') + libc.free(ptr) + return res + def __repr__(self): + s = str(self) + if '"' in s: + return 'isl.ast_expr_op_call("""%s""")' % s + else: + return 'isl.ast_expr_op_call("%s")' % s + +isl.isl_ast_expr_copy.restype = c_void_p +isl.isl_ast_expr_copy.argtypes = [c_void_p] +isl.isl_ast_expr_free.restype = c_void_p +isl.isl_ast_expr_free.argtypes = [c_void_p] +isl.isl_ast_expr_to_str.restype = POINTER(c_char) +isl.isl_ast_expr_to_str.argtypes = [c_void_p] + +class ast_expr_op_cond(ast_expr_op): + def __init__(self, *args, **keywords): + if "ptr" in keywords: + self.ctx = keywords["ctx"] + self.ptr = keywords["ptr"] + return + raise Error + def __del__(self): + if hasattr(self, 'ptr'): + isl.isl_ast_expr_free(self.ptr) + def __new__(cls, *args, **keywords): + return super(ast_expr_op_cond, cls).__new__(cls) + def __str__(arg0): + try: + if not arg0.__class__ is ast_expr_op_cond: + arg0 = ast_expr_op_cond(arg0) + except: + raise + ptr = isl.isl_ast_expr_to_str(arg0.ptr) + res = cast(ptr, c_char_p).value.decode('ascii') + libc.free(ptr) + return res + def __repr__(self): + s = str(self) + if '"' in s: + return 'isl.ast_expr_op_cond("""%s""")' % s + else: + return 'isl.ast_expr_op_cond("%s")' % s + +isl.isl_ast_expr_copy.restype = c_void_p +isl.isl_ast_expr_copy.argtypes = [c_void_p] +isl.isl_ast_expr_free.restype = c_void_p +isl.isl_ast_expr_free.argtypes = [c_void_p] +isl.isl_ast_expr_to_str.restype = POINTER(c_char) +isl.isl_ast_expr_to_str.argtypes = [c_void_p] + +class ast_expr_op_div(ast_expr_op): + def __init__(self, *args, **keywords): + if "ptr" in keywords: + self.ctx = keywords["ctx"] + self.ptr = keywords["ptr"] + return + raise Error + def __del__(self): + if hasattr(self, 'ptr'): + isl.isl_ast_expr_free(self.ptr) + def __new__(cls, *args, **keywords): + return super(ast_expr_op_div, cls).__new__(cls) + def __str__(arg0): + try: + if not arg0.__class__ is ast_expr_op_div: + arg0 = ast_expr_op_div(arg0) + except: + raise + ptr = isl.isl_ast_expr_to_str(arg0.ptr) + res = cast(ptr, c_char_p).value.decode('ascii') + libc.free(ptr) + return res + def __repr__(self): + s = str(self) + if '"' in s: + return 'isl.ast_expr_op_div("""%s""")' % s + else: + return 'isl.ast_expr_op_div("%s")' % s + +isl.isl_ast_expr_copy.restype = c_void_p +isl.isl_ast_expr_copy.argtypes = [c_void_p] +isl.isl_ast_expr_free.restype = c_void_p +isl.isl_ast_expr_free.argtypes = [c_void_p] +isl.isl_ast_expr_to_str.restype = POINTER(c_char) +isl.isl_ast_expr_to_str.argtypes = [c_void_p] + +class ast_expr_op_eq(ast_expr_op): + def __init__(self, *args, **keywords): + if "ptr" in keywords: + self.ctx = keywords["ctx"] + self.ptr = keywords["ptr"] + return + raise Error + def __del__(self): + if hasattr(self, 'ptr'): + isl.isl_ast_expr_free(self.ptr) + def __new__(cls, *args, **keywords): + return super(ast_expr_op_eq, cls).__new__(cls) + def __str__(arg0): + try: + if not arg0.__class__ is ast_expr_op_eq: + arg0 = ast_expr_op_eq(arg0) + except: + raise + ptr = isl.isl_ast_expr_to_str(arg0.ptr) + res = cast(ptr, c_char_p).value.decode('ascii') + libc.free(ptr) + return res + def __repr__(self): + s = str(self) + if '"' in s: + return 'isl.ast_expr_op_eq("""%s""")' % s + else: + return 'isl.ast_expr_op_eq("%s")' % s + +isl.isl_ast_expr_copy.restype = c_void_p +isl.isl_ast_expr_copy.argtypes = [c_void_p] +isl.isl_ast_expr_free.restype = c_void_p +isl.isl_ast_expr_free.argtypes = [c_void_p] +isl.isl_ast_expr_to_str.restype = POINTER(c_char) +isl.isl_ast_expr_to_str.argtypes = [c_void_p] + +class ast_expr_op_fdiv_q(ast_expr_op): + def __init__(self, *args, **keywords): + if "ptr" in keywords: + self.ctx = keywords["ctx"] + self.ptr = keywords["ptr"] + return + raise Error + def __del__(self): + if hasattr(self, 'ptr'): + isl.isl_ast_expr_free(self.ptr) + def __new__(cls, *args, **keywords): + return super(ast_expr_op_fdiv_q, cls).__new__(cls) + def __str__(arg0): + try: + if not arg0.__class__ is ast_expr_op_fdiv_q: + arg0 = ast_expr_op_fdiv_q(arg0) + except: + raise + ptr = isl.isl_ast_expr_to_str(arg0.ptr) + res = cast(ptr, c_char_p).value.decode('ascii') + libc.free(ptr) + return res + def __repr__(self): + s = str(self) + if '"' in s: + return 'isl.ast_expr_op_fdiv_q("""%s""")' % s + else: + return 'isl.ast_expr_op_fdiv_q("%s")' % s + +isl.isl_ast_expr_copy.restype = c_void_p +isl.isl_ast_expr_copy.argtypes = [c_void_p] +isl.isl_ast_expr_free.restype = c_void_p +isl.isl_ast_expr_free.argtypes = [c_void_p] +isl.isl_ast_expr_to_str.restype = POINTER(c_char) +isl.isl_ast_expr_to_str.argtypes = [c_void_p] + +class ast_expr_op_ge(ast_expr_op): + def __init__(self, *args, **keywords): + if "ptr" in keywords: + self.ctx = keywords["ctx"] + self.ptr = keywords["ptr"] + return + raise Error + def __del__(self): + if hasattr(self, 'ptr'): + isl.isl_ast_expr_free(self.ptr) + def __new__(cls, *args, **keywords): + return super(ast_expr_op_ge, cls).__new__(cls) + def __str__(arg0): + try: + if not arg0.__class__ is ast_expr_op_ge: + arg0 = ast_expr_op_ge(arg0) + except: + raise + ptr = isl.isl_ast_expr_to_str(arg0.ptr) + res = cast(ptr, c_char_p).value.decode('ascii') + libc.free(ptr) + return res + def __repr__(self): + s = str(self) + if '"' in s: + return 'isl.ast_expr_op_ge("""%s""")' % s + else: + return 'isl.ast_expr_op_ge("%s")' % s + +isl.isl_ast_expr_copy.restype = c_void_p +isl.isl_ast_expr_copy.argtypes = [c_void_p] +isl.isl_ast_expr_free.restype = c_void_p +isl.isl_ast_expr_free.argtypes = [c_void_p] +isl.isl_ast_expr_to_str.restype = POINTER(c_char) +isl.isl_ast_expr_to_str.argtypes = [c_void_p] + +class ast_expr_op_gt(ast_expr_op): + def __init__(self, *args, **keywords): + if "ptr" in keywords: + self.ctx = keywords["ctx"] + self.ptr = keywords["ptr"] + return + raise Error + def __del__(self): + if hasattr(self, 'ptr'): + isl.isl_ast_expr_free(self.ptr) + def __new__(cls, *args, **keywords): + return super(ast_expr_op_gt, cls).__new__(cls) + def __str__(arg0): + try: + if not arg0.__class__ is ast_expr_op_gt: + arg0 = ast_expr_op_gt(arg0) + except: + raise + ptr = isl.isl_ast_expr_to_str(arg0.ptr) + res = cast(ptr, c_char_p).value.decode('ascii') + libc.free(ptr) + return res + def __repr__(self): + s = str(self) + if '"' in s: + return 'isl.ast_expr_op_gt("""%s""")' % s + else: + return 'isl.ast_expr_op_gt("%s")' % s + +isl.isl_ast_expr_copy.restype = c_void_p +isl.isl_ast_expr_copy.argtypes = [c_void_p] +isl.isl_ast_expr_free.restype = c_void_p +isl.isl_ast_expr_free.argtypes = [c_void_p] +isl.isl_ast_expr_to_str.restype = POINTER(c_char) +isl.isl_ast_expr_to_str.argtypes = [c_void_p] + +class ast_expr_op_le(ast_expr_op): + def __init__(self, *args, **keywords): + if "ptr" in keywords: + self.ctx = keywords["ctx"] + self.ptr = keywords["ptr"] + return + raise Error + def __del__(self): + if hasattr(self, 'ptr'): + isl.isl_ast_expr_free(self.ptr) + def __new__(cls, *args, **keywords): + return super(ast_expr_op_le, cls).__new__(cls) + def __str__(arg0): + try: + if not arg0.__class__ is ast_expr_op_le: + arg0 = ast_expr_op_le(arg0) + except: + raise + ptr = isl.isl_ast_expr_to_str(arg0.ptr) + res = cast(ptr, c_char_p).value.decode('ascii') + libc.free(ptr) + return res + def __repr__(self): + s = str(self) + if '"' in s: + return 'isl.ast_expr_op_le("""%s""")' % s + else: + return 'isl.ast_expr_op_le("%s")' % s + +isl.isl_ast_expr_copy.restype = c_void_p +isl.isl_ast_expr_copy.argtypes = [c_void_p] +isl.isl_ast_expr_free.restype = c_void_p +isl.isl_ast_expr_free.argtypes = [c_void_p] +isl.isl_ast_expr_to_str.restype = POINTER(c_char) +isl.isl_ast_expr_to_str.argtypes = [c_void_p] + +class ast_expr_op_lt(ast_expr_op): + def __init__(self, *args, **keywords): + if "ptr" in keywords: + self.ctx = keywords["ctx"] + self.ptr = keywords["ptr"] + return + raise Error + def __del__(self): + if hasattr(self, 'ptr'): + isl.isl_ast_expr_free(self.ptr) + def __new__(cls, *args, **keywords): + return super(ast_expr_op_lt, cls).__new__(cls) + def __str__(arg0): + try: + if not arg0.__class__ is ast_expr_op_lt: + arg0 = ast_expr_op_lt(arg0) + except: + raise + ptr = isl.isl_ast_expr_to_str(arg0.ptr) + res = cast(ptr, c_char_p).value.decode('ascii') + libc.free(ptr) + return res + def __repr__(self): + s = str(self) + if '"' in s: + return 'isl.ast_expr_op_lt("""%s""")' % s + else: + return 'isl.ast_expr_op_lt("%s")' % s + +isl.isl_ast_expr_copy.restype = c_void_p +isl.isl_ast_expr_copy.argtypes = [c_void_p] +isl.isl_ast_expr_free.restype = c_void_p +isl.isl_ast_expr_free.argtypes = [c_void_p] +isl.isl_ast_expr_to_str.restype = POINTER(c_char) +isl.isl_ast_expr_to_str.argtypes = [c_void_p] + +class ast_expr_op_max(ast_expr_op): + def __init__(self, *args, **keywords): + if "ptr" in keywords: + self.ctx = keywords["ctx"] + self.ptr = keywords["ptr"] + return + raise Error + def __del__(self): + if hasattr(self, 'ptr'): + isl.isl_ast_expr_free(self.ptr) + def __new__(cls, *args, **keywords): + return super(ast_expr_op_max, cls).__new__(cls) + def __str__(arg0): + try: + if not arg0.__class__ is ast_expr_op_max: + arg0 = ast_expr_op_max(arg0) + except: + raise + ptr = isl.isl_ast_expr_to_str(arg0.ptr) + res = cast(ptr, c_char_p).value.decode('ascii') + libc.free(ptr) + return res + def __repr__(self): + s = str(self) + if '"' in s: + return 'isl.ast_expr_op_max("""%s""")' % s + else: + return 'isl.ast_expr_op_max("%s")' % s + +isl.isl_ast_expr_copy.restype = c_void_p +isl.isl_ast_expr_copy.argtypes = [c_void_p] +isl.isl_ast_expr_free.restype = c_void_p +isl.isl_ast_expr_free.argtypes = [c_void_p] +isl.isl_ast_expr_to_str.restype = POINTER(c_char) +isl.isl_ast_expr_to_str.argtypes = [c_void_p] + +class ast_expr_op_member(ast_expr_op): + def __init__(self, *args, **keywords): + if "ptr" in keywords: + self.ctx = keywords["ctx"] + self.ptr = keywords["ptr"] + return + raise Error + def __del__(self): + if hasattr(self, 'ptr'): + isl.isl_ast_expr_free(self.ptr) + def __new__(cls, *args, **keywords): + return super(ast_expr_op_member, cls).__new__(cls) + def __str__(arg0): + try: + if not arg0.__class__ is ast_expr_op_member: + arg0 = ast_expr_op_member(arg0) + except: + raise + ptr = isl.isl_ast_expr_to_str(arg0.ptr) + res = cast(ptr, c_char_p).value.decode('ascii') + libc.free(ptr) + return res + def __repr__(self): + s = str(self) + if '"' in s: + return 'isl.ast_expr_op_member("""%s""")' % s + else: + return 'isl.ast_expr_op_member("%s")' % s + +isl.isl_ast_expr_copy.restype = c_void_p +isl.isl_ast_expr_copy.argtypes = [c_void_p] +isl.isl_ast_expr_free.restype = c_void_p +isl.isl_ast_expr_free.argtypes = [c_void_p] +isl.isl_ast_expr_to_str.restype = POINTER(c_char) +isl.isl_ast_expr_to_str.argtypes = [c_void_p] + +class ast_expr_op_min(ast_expr_op): + def __init__(self, *args, **keywords): + if "ptr" in keywords: + self.ctx = keywords["ctx"] + self.ptr = keywords["ptr"] + return + raise Error + def __del__(self): + if hasattr(self, 'ptr'): + isl.isl_ast_expr_free(self.ptr) + def __new__(cls, *args, **keywords): + return super(ast_expr_op_min, cls).__new__(cls) + def __str__(arg0): + try: + if not arg0.__class__ is ast_expr_op_min: + arg0 = ast_expr_op_min(arg0) + except: + raise + ptr = isl.isl_ast_expr_to_str(arg0.ptr) + res = cast(ptr, c_char_p).value.decode('ascii') + libc.free(ptr) + return res + def __repr__(self): + s = str(self) + if '"' in s: + return 'isl.ast_expr_op_min("""%s""")' % s + else: + return 'isl.ast_expr_op_min("%s")' % s + +isl.isl_ast_expr_copy.restype = c_void_p +isl.isl_ast_expr_copy.argtypes = [c_void_p] +isl.isl_ast_expr_free.restype = c_void_p +isl.isl_ast_expr_free.argtypes = [c_void_p] +isl.isl_ast_expr_to_str.restype = POINTER(c_char) +isl.isl_ast_expr_to_str.argtypes = [c_void_p] + +class ast_expr_op_minus(ast_expr_op): + def __init__(self, *args, **keywords): + if "ptr" in keywords: + self.ctx = keywords["ctx"] + self.ptr = keywords["ptr"] + return + raise Error + def __del__(self): + if hasattr(self, 'ptr'): + isl.isl_ast_expr_free(self.ptr) + def __new__(cls, *args, **keywords): + return super(ast_expr_op_minus, cls).__new__(cls) + def __str__(arg0): + try: + if not arg0.__class__ is ast_expr_op_minus: + arg0 = ast_expr_op_minus(arg0) + except: + raise + ptr = isl.isl_ast_expr_to_str(arg0.ptr) + res = cast(ptr, c_char_p).value.decode('ascii') + libc.free(ptr) + return res + def __repr__(self): + s = str(self) + if '"' in s: + return 'isl.ast_expr_op_minus("""%s""")' % s + else: + return 'isl.ast_expr_op_minus("%s")' % s + +isl.isl_ast_expr_copy.restype = c_void_p +isl.isl_ast_expr_copy.argtypes = [c_void_p] +isl.isl_ast_expr_free.restype = c_void_p +isl.isl_ast_expr_free.argtypes = [c_void_p] +isl.isl_ast_expr_to_str.restype = POINTER(c_char) +isl.isl_ast_expr_to_str.argtypes = [c_void_p] + +class ast_expr_op_mul(ast_expr_op): + def __init__(self, *args, **keywords): + if "ptr" in keywords: + self.ctx = keywords["ctx"] + self.ptr = keywords["ptr"] + return + raise Error + def __del__(self): + if hasattr(self, 'ptr'): + isl.isl_ast_expr_free(self.ptr) + def __new__(cls, *args, **keywords): + return super(ast_expr_op_mul, cls).__new__(cls) + def __str__(arg0): + try: + if not arg0.__class__ is ast_expr_op_mul: + arg0 = ast_expr_op_mul(arg0) + except: + raise + ptr = isl.isl_ast_expr_to_str(arg0.ptr) + res = cast(ptr, c_char_p).value.decode('ascii') + libc.free(ptr) + return res + def __repr__(self): + s = str(self) + if '"' in s: + return 'isl.ast_expr_op_mul("""%s""")' % s + else: + return 'isl.ast_expr_op_mul("%s")' % s + +isl.isl_ast_expr_copy.restype = c_void_p +isl.isl_ast_expr_copy.argtypes = [c_void_p] +isl.isl_ast_expr_free.restype = c_void_p +isl.isl_ast_expr_free.argtypes = [c_void_p] +isl.isl_ast_expr_to_str.restype = POINTER(c_char) +isl.isl_ast_expr_to_str.argtypes = [c_void_p] + +class ast_expr_op_or(ast_expr_op): + def __init__(self, *args, **keywords): + if "ptr" in keywords: + self.ctx = keywords["ctx"] + self.ptr = keywords["ptr"] + return + raise Error + def __del__(self): + if hasattr(self, 'ptr'): + isl.isl_ast_expr_free(self.ptr) + def __new__(cls, *args, **keywords): + return super(ast_expr_op_or, cls).__new__(cls) + def __str__(arg0): + try: + if not arg0.__class__ is ast_expr_op_or: + arg0 = ast_expr_op_or(arg0) + except: + raise + ptr = isl.isl_ast_expr_to_str(arg0.ptr) + res = cast(ptr, c_char_p).value.decode('ascii') + libc.free(ptr) + return res + def __repr__(self): + s = str(self) + if '"' in s: + return 'isl.ast_expr_op_or("""%s""")' % s + else: + return 'isl.ast_expr_op_or("%s")' % s + +isl.isl_ast_expr_copy.restype = c_void_p +isl.isl_ast_expr_copy.argtypes = [c_void_p] +isl.isl_ast_expr_free.restype = c_void_p +isl.isl_ast_expr_free.argtypes = [c_void_p] +isl.isl_ast_expr_to_str.restype = POINTER(c_char) +isl.isl_ast_expr_to_str.argtypes = [c_void_p] + +class ast_expr_op_or_else(ast_expr_op): + def __init__(self, *args, **keywords): + if "ptr" in keywords: + self.ctx = keywords["ctx"] + self.ptr = keywords["ptr"] + return + raise Error + def __del__(self): + if hasattr(self, 'ptr'): + isl.isl_ast_expr_free(self.ptr) + def __new__(cls, *args, **keywords): + return super(ast_expr_op_or_else, cls).__new__(cls) + def __str__(arg0): + try: + if not arg0.__class__ is ast_expr_op_or_else: + arg0 = ast_expr_op_or_else(arg0) + except: + raise + ptr = isl.isl_ast_expr_to_str(arg0.ptr) + res = cast(ptr, c_char_p).value.decode('ascii') + libc.free(ptr) + return res + def __repr__(self): + s = str(self) + if '"' in s: + return 'isl.ast_expr_op_or_else("""%s""")' % s + else: + return 'isl.ast_expr_op_or_else("%s")' % s + +isl.isl_ast_expr_copy.restype = c_void_p +isl.isl_ast_expr_copy.argtypes = [c_void_p] +isl.isl_ast_expr_free.restype = c_void_p +isl.isl_ast_expr_free.argtypes = [c_void_p] +isl.isl_ast_expr_to_str.restype = POINTER(c_char) +isl.isl_ast_expr_to_str.argtypes = [c_void_p] + +class ast_expr_op_pdiv_q(ast_expr_op): + def __init__(self, *args, **keywords): + if "ptr" in keywords: + self.ctx = keywords["ctx"] + self.ptr = keywords["ptr"] + return + raise Error + def __del__(self): + if hasattr(self, 'ptr'): + isl.isl_ast_expr_free(self.ptr) + def __new__(cls, *args, **keywords): + return super(ast_expr_op_pdiv_q, cls).__new__(cls) + def __str__(arg0): + try: + if not arg0.__class__ is ast_expr_op_pdiv_q: + arg0 = ast_expr_op_pdiv_q(arg0) + except: + raise + ptr = isl.isl_ast_expr_to_str(arg0.ptr) + res = cast(ptr, c_char_p).value.decode('ascii') + libc.free(ptr) + return res + def __repr__(self): + s = str(self) + if '"' in s: + return 'isl.ast_expr_op_pdiv_q("""%s""")' % s + else: + return 'isl.ast_expr_op_pdiv_q("%s")' % s + +isl.isl_ast_expr_copy.restype = c_void_p +isl.isl_ast_expr_copy.argtypes = [c_void_p] +isl.isl_ast_expr_free.restype = c_void_p +isl.isl_ast_expr_free.argtypes = [c_void_p] +isl.isl_ast_expr_to_str.restype = POINTER(c_char) +isl.isl_ast_expr_to_str.argtypes = [c_void_p] + +class ast_expr_op_pdiv_r(ast_expr_op): + def __init__(self, *args, **keywords): + if "ptr" in keywords: + self.ctx = keywords["ctx"] + self.ptr = keywords["ptr"] + return + raise Error + def __del__(self): + if hasattr(self, 'ptr'): + isl.isl_ast_expr_free(self.ptr) + def __new__(cls, *args, **keywords): + return super(ast_expr_op_pdiv_r, cls).__new__(cls) + def __str__(arg0): + try: + if not arg0.__class__ is ast_expr_op_pdiv_r: + arg0 = ast_expr_op_pdiv_r(arg0) + except: + raise + ptr = isl.isl_ast_expr_to_str(arg0.ptr) + res = cast(ptr, c_char_p).value.decode('ascii') + libc.free(ptr) + return res + def __repr__(self): + s = str(self) + if '"' in s: + return 'isl.ast_expr_op_pdiv_r("""%s""")' % s + else: + return 'isl.ast_expr_op_pdiv_r("%s")' % s + +isl.isl_ast_expr_copy.restype = c_void_p +isl.isl_ast_expr_copy.argtypes = [c_void_p] +isl.isl_ast_expr_free.restype = c_void_p +isl.isl_ast_expr_free.argtypes = [c_void_p] +isl.isl_ast_expr_to_str.restype = POINTER(c_char) +isl.isl_ast_expr_to_str.argtypes = [c_void_p] + +class ast_expr_op_select(ast_expr_op): + def __init__(self, *args, **keywords): + if "ptr" in keywords: + self.ctx = keywords["ctx"] + self.ptr = keywords["ptr"] + return + raise Error + def __del__(self): + if hasattr(self, 'ptr'): + isl.isl_ast_expr_free(self.ptr) + def __new__(cls, *args, **keywords): + return super(ast_expr_op_select, cls).__new__(cls) + def __str__(arg0): + try: + if not arg0.__class__ is ast_expr_op_select: + arg0 = ast_expr_op_select(arg0) + except: + raise + ptr = isl.isl_ast_expr_to_str(arg0.ptr) + res = cast(ptr, c_char_p).value.decode('ascii') + libc.free(ptr) + return res + def __repr__(self): + s = str(self) + if '"' in s: + return 'isl.ast_expr_op_select("""%s""")' % s + else: + return 'isl.ast_expr_op_select("%s")' % s + +isl.isl_ast_expr_copy.restype = c_void_p +isl.isl_ast_expr_copy.argtypes = [c_void_p] +isl.isl_ast_expr_free.restype = c_void_p +isl.isl_ast_expr_free.argtypes = [c_void_p] +isl.isl_ast_expr_to_str.restype = POINTER(c_char) +isl.isl_ast_expr_to_str.argtypes = [c_void_p] + +class ast_expr_op_sub(ast_expr_op): + def __init__(self, *args, **keywords): + if "ptr" in keywords: + self.ctx = keywords["ctx"] + self.ptr = keywords["ptr"] + return + raise Error + def __del__(self): + if hasattr(self, 'ptr'): + isl.isl_ast_expr_free(self.ptr) + def __new__(cls, *args, **keywords): + return super(ast_expr_op_sub, cls).__new__(cls) + def __str__(arg0): + try: + if not arg0.__class__ is ast_expr_op_sub: + arg0 = ast_expr_op_sub(arg0) + except: + raise + ptr = isl.isl_ast_expr_to_str(arg0.ptr) + res = cast(ptr, c_char_p).value.decode('ascii') + libc.free(ptr) + return res + def __repr__(self): + s = str(self) + if '"' in s: + return 'isl.ast_expr_op_sub("""%s""")' % s + else: + return 'isl.ast_expr_op_sub("%s")' % s + +isl.isl_ast_expr_copy.restype = c_void_p +isl.isl_ast_expr_copy.argtypes = [c_void_p] +isl.isl_ast_expr_free.restype = c_void_p +isl.isl_ast_expr_free.argtypes = [c_void_p] +isl.isl_ast_expr_to_str.restype = POINTER(c_char) +isl.isl_ast_expr_to_str.argtypes = [c_void_p] + +class ast_expr_op_zdiv_r(ast_expr_op): + def __init__(self, *args, **keywords): + if "ptr" in keywords: + self.ctx = keywords["ctx"] + self.ptr = keywords["ptr"] + return + raise Error + def __del__(self): + if hasattr(self, 'ptr'): + isl.isl_ast_expr_free(self.ptr) + def __new__(cls, *args, **keywords): + return super(ast_expr_op_zdiv_r, cls).__new__(cls) + def __str__(arg0): + try: + if not arg0.__class__ is ast_expr_op_zdiv_r: + arg0 = ast_expr_op_zdiv_r(arg0) + except: + raise + ptr = isl.isl_ast_expr_to_str(arg0.ptr) + res = cast(ptr, c_char_p).value.decode('ascii') + libc.free(ptr) + return res + def __repr__(self): + s = str(self) + if '"' in s: + return 'isl.ast_expr_op_zdiv_r("""%s""")' % s + else: + return 'isl.ast_expr_op_zdiv_r("%s")' % s + +isl.isl_ast_expr_copy.restype = c_void_p +isl.isl_ast_expr_copy.argtypes = [c_void_p] +isl.isl_ast_expr_free.restype = c_void_p +isl.isl_ast_expr_free.argtypes = [c_void_p] +isl.isl_ast_expr_to_str.restype = POINTER(c_char) +isl.isl_ast_expr_to_str.argtypes = [c_void_p] + +class ast_node(object): + def __init__(self, *args, **keywords): + if "ptr" in keywords: + self.ctx = keywords["ctx"] + self.ptr = keywords["ptr"] + return + if len(args) == 1 and isinstance(args[0], ast_node_for): + self.ctx = args[0].ctx + self.ptr = isl.isl_ast_node_copy(args[0].ptr) + return + if len(args) == 1 and isinstance(args[0], ast_node_if): + self.ctx = args[0].ctx + self.ptr = isl.isl_ast_node_copy(args[0].ptr) + return + if len(args) == 1 and isinstance(args[0], ast_node_block): + self.ctx = args[0].ctx + self.ptr = isl.isl_ast_node_copy(args[0].ptr) + return + if len(args) == 1 and isinstance(args[0], ast_node_mark): + self.ctx = args[0].ctx + self.ptr = isl.isl_ast_node_copy(args[0].ptr) + return + if len(args) == 1 and isinstance(args[0], ast_node_user): + self.ctx = args[0].ctx + self.ptr = isl.isl_ast_node_copy(args[0].ptr) + return + raise Error + def __del__(self): + if hasattr(self, 'ptr'): + isl.isl_ast_node_free(self.ptr) + def __new__(cls, *args, **keywords): + if "ptr" in keywords: + type = isl.isl_ast_node_get_type(keywords["ptr"]) + if type == 1: + return ast_node_for(**keywords) + if type == 2: + return ast_node_if(**keywords) + if type == 3: + return ast_node_block(**keywords) + if type == 4: + return ast_node_mark(**keywords) + if type == 5: + return ast_node_user(**keywords) + raise Error + return super(ast_node, cls).__new__(cls) + def __str__(arg0): + try: + if not arg0.__class__ is ast_node: + arg0 = ast_node(arg0) + except: + raise + ptr = isl.isl_ast_node_to_str(arg0.ptr) + res = cast(ptr, c_char_p).value.decode('ascii') + libc.free(ptr) + return res + def __repr__(self): + s = str(self) + if '"' in s: + return 'isl.ast_node("""%s""")' % s + else: + return 'isl.ast_node("%s")' % s + def map_descendant_bottom_up(arg0, arg1): + try: + if not arg0.__class__ is ast_node: + arg0 = ast_node(arg0) + except: + raise + exc_info = [None] + fn = CFUNCTYPE(c_void_p, c_void_p, c_void_p) + def cb_func(cb_arg0, cb_arg1): + cb_arg0 = ast_node(ctx=arg0.ctx, ptr=(cb_arg0)) + try: + res = arg1(cb_arg0) + except BaseException as e: + exc_info[0] = e + return None + return isl.isl_ast_node_copy(res.ptr) + cb1 = fn(cb_func) + ctx = arg0.ctx + res = isl.isl_ast_node_map_descendant_bottom_up(isl.isl_ast_node_copy(arg0.ptr), cb1, None) + if exc_info[0] is not None: + raise exc_info[0] + obj = ast_node(ctx=ctx, ptr=res) + return obj + def to_C_str(arg0): + try: + if not arg0.__class__ is ast_node: + arg0 = ast_node(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_ast_node_to_C_str(arg0.ptr) + if res == 0: + raise Error + string = cast(res, c_char_p).value.decode('ascii') + libc.free(res) + return string + def to_list(arg0): + try: + if not arg0.__class__ is ast_node: + arg0 = ast_node(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_ast_node_to_list(isl.isl_ast_node_copy(arg0.ptr)) + obj = ast_node_list(ctx=ctx, ptr=res) + return obj + +isl.isl_ast_node_map_descendant_bottom_up.restype = c_void_p +isl.isl_ast_node_map_descendant_bottom_up.argtypes = [c_void_p, c_void_p, c_void_p] +isl.isl_ast_node_to_C_str.restype = POINTER(c_char) +isl.isl_ast_node_to_C_str.argtypes = [c_void_p] +isl.isl_ast_node_to_list.restype = c_void_p +isl.isl_ast_node_to_list.argtypes = [c_void_p] +isl.isl_ast_node_copy.restype = c_void_p +isl.isl_ast_node_copy.argtypes = [c_void_p] +isl.isl_ast_node_free.restype = c_void_p +isl.isl_ast_node_free.argtypes = [c_void_p] +isl.isl_ast_node_to_str.restype = POINTER(c_char) +isl.isl_ast_node_to_str.argtypes = [c_void_p] +isl.isl_ast_node_get_type.argtypes = [c_void_p] + +class ast_node_block(ast_node): + def __init__(self, *args, **keywords): + if "ptr" in keywords: + self.ctx = keywords["ctx"] + self.ptr = keywords["ptr"] + return + if len(args) == 1 and args[0].__class__ is ast_node_list: + self.ctx = Context.getDefaultInstance() + self.ptr = isl.isl_ast_node_block_from_children(isl.isl_ast_node_list_copy(args[0].ptr)) + return + raise Error + def __del__(self): + if hasattr(self, 'ptr'): + isl.isl_ast_node_free(self.ptr) + def __new__(cls, *args, **keywords): + return super(ast_node_block, cls).__new__(cls) + def __str__(arg0): + try: + if not arg0.__class__ is ast_node_block: + arg0 = ast_node_block(arg0) + except: + raise + ptr = isl.isl_ast_node_to_str(arg0.ptr) + res = cast(ptr, c_char_p).value.decode('ascii') + libc.free(ptr) + return res + def __repr__(self): + s = str(self) + if '"' in s: + return 'isl.ast_node_block("""%s""")' % s + else: + return 'isl.ast_node_block("%s")' % s + def children(arg0): + try: + if not arg0.__class__ is ast_node: + arg0 = ast_node(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_ast_node_block_get_children(arg0.ptr) + obj = ast_node_list(ctx=ctx, ptr=res) + return obj + def get_children(arg0): + return arg0.children() + +isl.isl_ast_node_block_from_children.restype = c_void_p +isl.isl_ast_node_block_from_children.argtypes = [c_void_p] +isl.isl_ast_node_block_get_children.restype = c_void_p +isl.isl_ast_node_block_get_children.argtypes = [c_void_p] +isl.isl_ast_node_copy.restype = c_void_p +isl.isl_ast_node_copy.argtypes = [c_void_p] +isl.isl_ast_node_free.restype = c_void_p +isl.isl_ast_node_free.argtypes = [c_void_p] +isl.isl_ast_node_to_str.restype = POINTER(c_char) +isl.isl_ast_node_to_str.argtypes = [c_void_p] + +class ast_node_for(ast_node): + def __init__(self, *args, **keywords): + if "ptr" in keywords: + self.ctx = keywords["ctx"] + self.ptr = keywords["ptr"] + return + raise Error + def __del__(self): + if hasattr(self, 'ptr'): + isl.isl_ast_node_free(self.ptr) + def __new__(cls, *args, **keywords): + return super(ast_node_for, cls).__new__(cls) + def __str__(arg0): + try: + if not arg0.__class__ is ast_node_for: + arg0 = ast_node_for(arg0) + except: + raise + ptr = isl.isl_ast_node_to_str(arg0.ptr) + res = cast(ptr, c_char_p).value.decode('ascii') + libc.free(ptr) + return res + def __repr__(self): + s = str(self) + if '"' in s: + return 'isl.ast_node_for("""%s""")' % s + else: + return 'isl.ast_node_for("%s")' % s + def body(arg0): + try: + if not arg0.__class__ is ast_node: + arg0 = ast_node(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_ast_node_for_get_body(arg0.ptr) + obj = ast_node(ctx=ctx, ptr=res) + return obj + def get_body(arg0): + return arg0.body() + def cond(arg0): + try: + if not arg0.__class__ is ast_node: + arg0 = ast_node(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_ast_node_for_get_cond(arg0.ptr) + obj = ast_expr(ctx=ctx, ptr=res) + return obj + def get_cond(arg0): + return arg0.cond() + def inc(arg0): + try: + if not arg0.__class__ is ast_node: + arg0 = ast_node(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_ast_node_for_get_inc(arg0.ptr) + obj = ast_expr(ctx=ctx, ptr=res) + return obj + def get_inc(arg0): + return arg0.inc() + def init(arg0): + try: + if not arg0.__class__ is ast_node: + arg0 = ast_node(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_ast_node_for_get_init(arg0.ptr) + obj = ast_expr(ctx=ctx, ptr=res) + return obj + def get_init(arg0): + return arg0.init() + def is_degenerate(arg0): + try: + if not arg0.__class__ is ast_node: + arg0 = ast_node(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_ast_node_for_is_degenerate(arg0.ptr) + if res < 0: + raise Error + return bool(res) + def iterator(arg0): + try: + if not arg0.__class__ is ast_node: + arg0 = ast_node(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_ast_node_for_get_iterator(arg0.ptr) + obj = ast_expr(ctx=ctx, ptr=res) + return obj + def get_iterator(arg0): + return arg0.iterator() + +isl.isl_ast_node_for_get_body.restype = c_void_p +isl.isl_ast_node_for_get_body.argtypes = [c_void_p] +isl.isl_ast_node_for_get_cond.restype = c_void_p +isl.isl_ast_node_for_get_cond.argtypes = [c_void_p] +isl.isl_ast_node_for_get_inc.restype = c_void_p +isl.isl_ast_node_for_get_inc.argtypes = [c_void_p] +isl.isl_ast_node_for_get_init.restype = c_void_p +isl.isl_ast_node_for_get_init.argtypes = [c_void_p] +isl.isl_ast_node_for_is_degenerate.argtypes = [c_void_p] +isl.isl_ast_node_for_get_iterator.restype = c_void_p +isl.isl_ast_node_for_get_iterator.argtypes = [c_void_p] +isl.isl_ast_node_copy.restype = c_void_p +isl.isl_ast_node_copy.argtypes = [c_void_p] +isl.isl_ast_node_free.restype = c_void_p +isl.isl_ast_node_free.argtypes = [c_void_p] +isl.isl_ast_node_to_str.restype = POINTER(c_char) +isl.isl_ast_node_to_str.argtypes = [c_void_p] + +class ast_node_if(ast_node): + def __init__(self, *args, **keywords): + if "ptr" in keywords: + self.ctx = keywords["ctx"] + self.ptr = keywords["ptr"] + return + raise Error + def __del__(self): + if hasattr(self, 'ptr'): + isl.isl_ast_node_free(self.ptr) + def __new__(cls, *args, **keywords): + return super(ast_node_if, cls).__new__(cls) + def __str__(arg0): + try: + if not arg0.__class__ is ast_node_if: + arg0 = ast_node_if(arg0) + except: + raise + ptr = isl.isl_ast_node_to_str(arg0.ptr) + res = cast(ptr, c_char_p).value.decode('ascii') + libc.free(ptr) + return res + def __repr__(self): + s = str(self) + if '"' in s: + return 'isl.ast_node_if("""%s""")' % s + else: + return 'isl.ast_node_if("%s")' % s + def cond(arg0): + try: + if not arg0.__class__ is ast_node: + arg0 = ast_node(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_ast_node_if_get_cond(arg0.ptr) + obj = ast_expr(ctx=ctx, ptr=res) + return obj + def get_cond(arg0): + return arg0.cond() + def else_node(arg0): + try: + if not arg0.__class__ is ast_node: + arg0 = ast_node(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_ast_node_if_get_else_node(arg0.ptr) + obj = ast_node(ctx=ctx, ptr=res) + return obj + def get_else_node(arg0): + return arg0.else_node() + def has_else_node(arg0): + try: + if not arg0.__class__ is ast_node: + arg0 = ast_node(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_ast_node_if_has_else_node(arg0.ptr) + if res < 0: + raise Error + return bool(res) + def then_node(arg0): + try: + if not arg0.__class__ is ast_node: + arg0 = ast_node(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_ast_node_if_get_then_node(arg0.ptr) + obj = ast_node(ctx=ctx, ptr=res) + return obj + def get_then_node(arg0): + return arg0.then_node() + +isl.isl_ast_node_if_get_cond.restype = c_void_p +isl.isl_ast_node_if_get_cond.argtypes = [c_void_p] +isl.isl_ast_node_if_get_else_node.restype = c_void_p +isl.isl_ast_node_if_get_else_node.argtypes = [c_void_p] +isl.isl_ast_node_if_has_else_node.argtypes = [c_void_p] +isl.isl_ast_node_if_get_then_node.restype = c_void_p +isl.isl_ast_node_if_get_then_node.argtypes = [c_void_p] +isl.isl_ast_node_copy.restype = c_void_p +isl.isl_ast_node_copy.argtypes = [c_void_p] +isl.isl_ast_node_free.restype = c_void_p +isl.isl_ast_node_free.argtypes = [c_void_p] +isl.isl_ast_node_to_str.restype = POINTER(c_char) +isl.isl_ast_node_to_str.argtypes = [c_void_p] + +class ast_node_list(object): + def __init__(self, *args, **keywords): + if "ptr" in keywords: + self.ctx = keywords["ctx"] + self.ptr = keywords["ptr"] + return + if len(args) == 1 and type(args[0]) == int: + self.ctx = Context.getDefaultInstance() + self.ptr = isl.isl_ast_node_list_alloc(self.ctx, args[0]) + return + if len(args) == 1 and args[0].__class__ is ast_node: + self.ctx = Context.getDefaultInstance() + self.ptr = isl.isl_ast_node_list_from_ast_node(isl.isl_ast_node_copy(args[0].ptr)) + return + raise Error + def __del__(self): + if hasattr(self, 'ptr'): + isl.isl_ast_node_list_free(self.ptr) + def __str__(arg0): + try: + if not arg0.__class__ is ast_node_list: + arg0 = ast_node_list(arg0) + except: + raise + ptr = isl.isl_ast_node_list_to_str(arg0.ptr) + res = cast(ptr, c_char_p).value.decode('ascii') + libc.free(ptr) + return res + def __repr__(self): + s = str(self) + if '"' in s: + return 'isl.ast_node_list("""%s""")' % s + else: + return 'isl.ast_node_list("%s")' % s + def add(arg0, arg1): + try: + if not arg0.__class__ is ast_node_list: + arg0 = ast_node_list(arg0) + except: + raise + try: + if not arg1.__class__ is ast_node: + arg1 = ast_node(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_ast_node_list_add(isl.isl_ast_node_list_copy(arg0.ptr), isl.isl_ast_node_copy(arg1.ptr)) + obj = ast_node_list(ctx=ctx, ptr=res) + return obj + def at(arg0, arg1): + try: + if not arg0.__class__ is ast_node_list: + arg0 = ast_node_list(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_ast_node_list_get_at(arg0.ptr, arg1) + obj = ast_node(ctx=ctx, ptr=res) + return obj + def get_at(arg0, arg1): + return arg0.at(arg1) + def clear(arg0): + try: + if not arg0.__class__ is ast_node_list: + arg0 = ast_node_list(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_ast_node_list_clear(isl.isl_ast_node_list_copy(arg0.ptr)) + obj = ast_node_list(ctx=ctx, ptr=res) + return obj + def concat(arg0, arg1): + try: + if not arg0.__class__ is ast_node_list: + arg0 = ast_node_list(arg0) + except: + raise + try: + if not arg1.__class__ is ast_node_list: + arg1 = ast_node_list(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_ast_node_list_concat(isl.isl_ast_node_list_copy(arg0.ptr), isl.isl_ast_node_list_copy(arg1.ptr)) + obj = ast_node_list(ctx=ctx, ptr=res) + return obj + def drop(arg0, arg1, arg2): + try: + if not arg0.__class__ is ast_node_list: + arg0 = ast_node_list(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_ast_node_list_drop(isl.isl_ast_node_list_copy(arg0.ptr), arg1, arg2) + obj = ast_node_list(ctx=ctx, ptr=res) + return obj + def foreach(arg0, arg1): + try: + if not arg0.__class__ is ast_node_list: + arg0 = ast_node_list(arg0) + except: + raise + exc_info = [None] + fn = CFUNCTYPE(c_int, c_void_p, c_void_p) + def cb_func(cb_arg0, cb_arg1): + cb_arg0 = ast_node(ctx=arg0.ctx, ptr=(cb_arg0)) + try: + arg1(cb_arg0) + except BaseException as e: + exc_info[0] = e + return -1 + return 0 + cb1 = fn(cb_func) + ctx = arg0.ctx + res = isl.isl_ast_node_list_foreach(arg0.ptr, cb1, None) + if exc_info[0] is not None: + raise exc_info[0] + if res < 0: + raise Error + def foreach_scc(arg0, arg1, arg2): + try: + if not arg0.__class__ is ast_node_list: + arg0 = ast_node_list(arg0) + except: + raise + exc_info = [None] + fn = CFUNCTYPE(c_int, c_void_p, c_void_p, c_void_p) + def cb_func(cb_arg0, cb_arg1, cb_arg2): + cb_arg0 = ast_node(ctx=arg0.ctx, ptr=isl.isl_ast_node_copy(cb_arg0)) + cb_arg1 = ast_node(ctx=arg0.ctx, ptr=isl.isl_ast_node_copy(cb_arg1)) + try: + res = arg1(cb_arg0, cb_arg1) + except BaseException as e: + exc_info[0] = e + return -1 + return 1 if res else 0 + cb1 = fn(cb_func) + exc_info = [None] + fn = CFUNCTYPE(c_int, c_void_p, c_void_p) + def cb_func(cb_arg0, cb_arg1): + cb_arg0 = ast_node_list(ctx=arg0.ctx, ptr=(cb_arg0)) + try: + arg2(cb_arg0) + except BaseException as e: + exc_info[0] = e + return -1 + return 0 + cb2 = fn(cb_func) + ctx = arg0.ctx + res = isl.isl_ast_node_list_foreach_scc(arg0.ptr, cb1, None, cb2, None) + if exc_info[0] is not None: + raise exc_info[0] + if res < 0: + raise Error + def insert(arg0, arg1, arg2): + try: + if not arg0.__class__ is ast_node_list: + arg0 = ast_node_list(arg0) + except: + raise + try: + if not arg2.__class__ is ast_node: + arg2 = ast_node(arg2) + except: + raise + ctx = arg0.ctx + res = isl.isl_ast_node_list_insert(isl.isl_ast_node_list_copy(arg0.ptr), arg1, isl.isl_ast_node_copy(arg2.ptr)) + obj = ast_node_list(ctx=ctx, ptr=res) + return obj + def set_at(arg0, arg1, arg2): + try: + if not arg0.__class__ is ast_node_list: + arg0 = ast_node_list(arg0) + except: + raise + try: + if not arg2.__class__ is ast_node: + arg2 = ast_node(arg2) + except: + raise + ctx = arg0.ctx + res = isl.isl_ast_node_list_set_at(isl.isl_ast_node_list_copy(arg0.ptr), arg1, isl.isl_ast_node_copy(arg2.ptr)) + obj = ast_node_list(ctx=ctx, ptr=res) + return obj + def size(arg0): + try: + if not arg0.__class__ is ast_node_list: + arg0 = ast_node_list(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_ast_node_list_size(arg0.ptr) + if res < 0: + raise Error + return int(res) + +isl.isl_ast_node_list_alloc.restype = c_void_p +isl.isl_ast_node_list_alloc.argtypes = [Context, c_int] +isl.isl_ast_node_list_from_ast_node.restype = c_void_p +isl.isl_ast_node_list_from_ast_node.argtypes = [c_void_p] +isl.isl_ast_node_list_add.restype = c_void_p +isl.isl_ast_node_list_add.argtypes = [c_void_p, c_void_p] +isl.isl_ast_node_list_get_at.restype = c_void_p +isl.isl_ast_node_list_get_at.argtypes = [c_void_p, c_int] +isl.isl_ast_node_list_clear.restype = c_void_p +isl.isl_ast_node_list_clear.argtypes = [c_void_p] +isl.isl_ast_node_list_concat.restype = c_void_p +isl.isl_ast_node_list_concat.argtypes = [c_void_p, c_void_p] +isl.isl_ast_node_list_drop.restype = c_void_p +isl.isl_ast_node_list_drop.argtypes = [c_void_p, c_int, c_int] +isl.isl_ast_node_list_foreach.argtypes = [c_void_p, c_void_p, c_void_p] +isl.isl_ast_node_list_foreach_scc.argtypes = [c_void_p, c_void_p, c_void_p, c_void_p, c_void_p] +isl.isl_ast_node_list_insert.restype = c_void_p +isl.isl_ast_node_list_insert.argtypes = [c_void_p, c_int, c_void_p] +isl.isl_ast_node_list_set_at.restype = c_void_p +isl.isl_ast_node_list_set_at.argtypes = [c_void_p, c_int, c_void_p] +isl.isl_ast_node_list_size.argtypes = [c_void_p] +isl.isl_ast_node_list_copy.restype = c_void_p +isl.isl_ast_node_list_copy.argtypes = [c_void_p] +isl.isl_ast_node_list_free.restype = c_void_p +isl.isl_ast_node_list_free.argtypes = [c_void_p] +isl.isl_ast_node_list_to_str.restype = POINTER(c_char) +isl.isl_ast_node_list_to_str.argtypes = [c_void_p] + +class ast_node_mark(ast_node): + def __init__(self, *args, **keywords): + if "ptr" in keywords: + self.ctx = keywords["ctx"] + self.ptr = keywords["ptr"] + return + raise Error + def __del__(self): + if hasattr(self, 'ptr'): + isl.isl_ast_node_free(self.ptr) + def __new__(cls, *args, **keywords): + return super(ast_node_mark, cls).__new__(cls) + def __str__(arg0): + try: + if not arg0.__class__ is ast_node_mark: + arg0 = ast_node_mark(arg0) + except: + raise + ptr = isl.isl_ast_node_to_str(arg0.ptr) + res = cast(ptr, c_char_p).value.decode('ascii') + libc.free(ptr) + return res + def __repr__(self): + s = str(self) + if '"' in s: + return 'isl.ast_node_mark("""%s""")' % s + else: + return 'isl.ast_node_mark("%s")' % s + def id(arg0): + try: + if not arg0.__class__ is ast_node: + arg0 = ast_node(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_ast_node_mark_get_id(arg0.ptr) + obj = id(ctx=ctx, ptr=res) + return obj + def get_id(arg0): + return arg0.id() + def node(arg0): + try: + if not arg0.__class__ is ast_node: + arg0 = ast_node(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_ast_node_mark_get_node(arg0.ptr) + obj = ast_node(ctx=ctx, ptr=res) + return obj + def get_node(arg0): + return arg0.node() + +isl.isl_ast_node_mark_get_id.restype = c_void_p +isl.isl_ast_node_mark_get_id.argtypes = [c_void_p] +isl.isl_ast_node_mark_get_node.restype = c_void_p +isl.isl_ast_node_mark_get_node.argtypes = [c_void_p] +isl.isl_ast_node_copy.restype = c_void_p +isl.isl_ast_node_copy.argtypes = [c_void_p] +isl.isl_ast_node_free.restype = c_void_p +isl.isl_ast_node_free.argtypes = [c_void_p] +isl.isl_ast_node_to_str.restype = POINTER(c_char) +isl.isl_ast_node_to_str.argtypes = [c_void_p] + +class ast_node_user(ast_node): + def __init__(self, *args, **keywords): + if "ptr" in keywords: + self.ctx = keywords["ctx"] + self.ptr = keywords["ptr"] + return + if len(args) == 1 and args[0].__class__ is ast_expr: + self.ctx = Context.getDefaultInstance() + self.ptr = isl.isl_ast_node_user_from_expr(isl.isl_ast_expr_copy(args[0].ptr)) + return + raise Error + def __del__(self): + if hasattr(self, 'ptr'): + isl.isl_ast_node_free(self.ptr) + def __new__(cls, *args, **keywords): + return super(ast_node_user, cls).__new__(cls) + def __str__(arg0): + try: + if not arg0.__class__ is ast_node_user: + arg0 = ast_node_user(arg0) + except: + raise + ptr = isl.isl_ast_node_to_str(arg0.ptr) + res = cast(ptr, c_char_p).value.decode('ascii') + libc.free(ptr) + return res + def __repr__(self): + s = str(self) + if '"' in s: + return 'isl.ast_node_user("""%s""")' % s + else: + return 'isl.ast_node_user("%s")' % s + def expr(arg0): + try: + if not arg0.__class__ is ast_node: + arg0 = ast_node(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_ast_node_user_get_expr(arg0.ptr) + obj = ast_expr(ctx=ctx, ptr=res) + return obj + def get_expr(arg0): + return arg0.expr() + +isl.isl_ast_node_user_from_expr.restype = c_void_p +isl.isl_ast_node_user_from_expr.argtypes = [c_void_p] +isl.isl_ast_node_user_get_expr.restype = c_void_p +isl.isl_ast_node_user_get_expr.argtypes = [c_void_p] +isl.isl_ast_node_copy.restype = c_void_p +isl.isl_ast_node_copy.argtypes = [c_void_p] +isl.isl_ast_node_free.restype = c_void_p +isl.isl_ast_node_free.argtypes = [c_void_p] +isl.isl_ast_node_to_str.restype = POINTER(c_char) +isl.isl_ast_node_to_str.argtypes = [c_void_p] + +class union_map(object): + def __init__(self, *args, **keywords): + if "ptr" in keywords: + self.ctx = keywords["ctx"] + self.ptr = keywords["ptr"] + return + if len(args) == 1 and args[0].__class__ is basic_map: + self.ctx = Context.getDefaultInstance() + self.ptr = isl.isl_union_map_from_basic_map(isl.isl_basic_map_copy(args[0].ptr)) + return + if len(args) == 1 and args[0].__class__ is map: + self.ctx = Context.getDefaultInstance() + self.ptr = isl.isl_union_map_from_map(isl.isl_map_copy(args[0].ptr)) + return + if len(args) == 1 and type(args[0]) == str: + self.ctx = Context.getDefaultInstance() + self.ptr = isl.isl_union_map_read_from_str(self.ctx, args[0].encode('ascii')) + return + raise Error + def __del__(self): + if hasattr(self, 'ptr'): + isl.isl_union_map_free(self.ptr) + def __str__(arg0): + try: + if not arg0.__class__ is union_map: + arg0 = union_map(arg0) + except: + raise + ptr = isl.isl_union_map_to_str(arg0.ptr) + res = cast(ptr, c_char_p).value.decode('ascii') + libc.free(ptr) + return res + def __repr__(self): + s = str(self) + if '"' in s: + return 'isl.union_map("""%s""")' % s + else: + return 'isl.union_map("%s")' % s + def affine_hull(arg0): + try: + if not arg0.__class__ is union_map: + arg0 = union_map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_map_affine_hull(isl.isl_union_map_copy(arg0.ptr)) + obj = union_map(ctx=ctx, ptr=res) + return obj + def apply_domain(arg0, arg1): + try: + if not arg0.__class__ is union_map: + arg0 = union_map(arg0) + except: + raise + try: + if not arg1.__class__ is union_map: + arg1 = union_map(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_map_apply_domain(isl.isl_union_map_copy(arg0.ptr), isl.isl_union_map_copy(arg1.ptr)) + obj = union_map(ctx=ctx, ptr=res) + return obj + def apply_range(arg0, arg1): + try: + if not arg0.__class__ is union_map: + arg0 = union_map(arg0) + except: + raise + try: + if not arg1.__class__ is union_map: + arg1 = union_map(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_map_apply_range(isl.isl_union_map_copy(arg0.ptr), isl.isl_union_map_copy(arg1.ptr)) + obj = union_map(ctx=ctx, ptr=res) + return obj + def as_map(arg0): + try: + if not arg0.__class__ is union_map: + arg0 = union_map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_map_as_map(isl.isl_union_map_copy(arg0.ptr)) + obj = map(ctx=ctx, ptr=res) + return obj + def as_multi_union_pw_aff(arg0): + try: + if not arg0.__class__ is union_map: + arg0 = union_map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_map_as_multi_union_pw_aff(isl.isl_union_map_copy(arg0.ptr)) + obj = multi_union_pw_aff(ctx=ctx, ptr=res) + return obj + def as_union_pw_multi_aff(arg0): + try: + if not arg0.__class__ is union_map: + arg0 = union_map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_map_as_union_pw_multi_aff(isl.isl_union_map_copy(arg0.ptr)) + obj = union_pw_multi_aff(ctx=ctx, ptr=res) + return obj + def bind_range(arg0, arg1): + try: + if not arg0.__class__ is union_map: + arg0 = union_map(arg0) + except: + raise + try: + if not arg1.__class__ is multi_id: + arg1 = multi_id(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_map_bind_range(isl.isl_union_map_copy(arg0.ptr), isl.isl_multi_id_copy(arg1.ptr)) + obj = union_set(ctx=ctx, ptr=res) + return obj + def coalesce(arg0): + try: + if not arg0.__class__ is union_map: + arg0 = union_map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_map_coalesce(isl.isl_union_map_copy(arg0.ptr)) + obj = union_map(ctx=ctx, ptr=res) + return obj + def compute_divs(arg0): + try: + if not arg0.__class__ is union_map: + arg0 = union_map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_map_compute_divs(isl.isl_union_map_copy(arg0.ptr)) + obj = union_map(ctx=ctx, ptr=res) + return obj + def curry(arg0): + try: + if not arg0.__class__ is union_map: + arg0 = union_map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_map_curry(isl.isl_union_map_copy(arg0.ptr)) + obj = union_map(ctx=ctx, ptr=res) + return obj + def deltas(arg0): + try: + if not arg0.__class__ is union_map: + arg0 = union_map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_map_deltas(isl.isl_union_map_copy(arg0.ptr)) + obj = union_set(ctx=ctx, ptr=res) + return obj + def detect_equalities(arg0): + try: + if not arg0.__class__ is union_map: + arg0 = union_map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_map_detect_equalities(isl.isl_union_map_copy(arg0.ptr)) + obj = union_map(ctx=ctx, ptr=res) + return obj + def domain(arg0): + try: + if not arg0.__class__ is union_map: + arg0 = union_map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_map_domain(isl.isl_union_map_copy(arg0.ptr)) + obj = union_set(ctx=ctx, ptr=res) + return obj + def domain_factor_domain(arg0): + try: + if not arg0.__class__ is union_map: + arg0 = union_map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_map_domain_factor_domain(isl.isl_union_map_copy(arg0.ptr)) + obj = union_map(ctx=ctx, ptr=res) + return obj + def domain_factor_range(arg0): + try: + if not arg0.__class__ is union_map: + arg0 = union_map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_map_domain_factor_range(isl.isl_union_map_copy(arg0.ptr)) + obj = union_map(ctx=ctx, ptr=res) + return obj + def domain_map(arg0): + try: + if not arg0.__class__ is union_map: + arg0 = union_map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_map_domain_map(isl.isl_union_map_copy(arg0.ptr)) + obj = union_map(ctx=ctx, ptr=res) + return obj + def domain_map_union_pw_multi_aff(arg0): + try: + if not arg0.__class__ is union_map: + arg0 = union_map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_map_domain_map_union_pw_multi_aff(isl.isl_union_map_copy(arg0.ptr)) + obj = union_pw_multi_aff(ctx=ctx, ptr=res) + return obj + def domain_product(arg0, arg1): + try: + if not arg0.__class__ is union_map: + arg0 = union_map(arg0) + except: + raise + try: + if not arg1.__class__ is union_map: + arg1 = union_map(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_map_domain_product(isl.isl_union_map_copy(arg0.ptr), isl.isl_union_map_copy(arg1.ptr)) + obj = union_map(ctx=ctx, ptr=res) + return obj + def domain_reverse(arg0): + try: + if not arg0.__class__ is union_map: + arg0 = union_map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_map_domain_reverse(isl.isl_union_map_copy(arg0.ptr)) + obj = union_map(ctx=ctx, ptr=res) + return obj + def drop_unused_params(arg0): + try: + if not arg0.__class__ is union_map: + arg0 = union_map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_map_drop_unused_params(isl.isl_union_map_copy(arg0.ptr)) + obj = union_map(ctx=ctx, ptr=res) + return obj + @staticmethod + def empty(*args): + if len(args) == 0: + ctx = Context.getDefaultInstance() + res = isl.isl_union_map_empty_ctx(ctx) + obj = union_map(ctx=ctx, ptr=res) + return obj + raise Error + def eq_at(*args): + if len(args) == 2 and args[1].__class__ is multi_union_pw_aff: + args = list(args) + try: + if not args[0].__class__ is union_map: + args[0] = union_map(args[0]) + except: + raise + ctx = args[0].ctx + res = isl.isl_union_map_eq_at_multi_union_pw_aff(isl.isl_union_map_copy(args[0].ptr), isl.isl_multi_union_pw_aff_copy(args[1].ptr)) + obj = union_map(ctx=ctx, ptr=res) + return obj + raise Error + def every_map(arg0, arg1): + try: + if not arg0.__class__ is union_map: + arg0 = union_map(arg0) + except: + raise + exc_info = [None] + fn = CFUNCTYPE(c_int, c_void_p, c_void_p) + def cb_func(cb_arg0, cb_arg1): + cb_arg0 = map(ctx=arg0.ctx, ptr=isl.isl_map_copy(cb_arg0)) + try: + res = arg1(cb_arg0) + except BaseException as e: + exc_info[0] = e + return -1 + return 1 if res else 0 + cb1 = fn(cb_func) + ctx = arg0.ctx + res = isl.isl_union_map_every_map(arg0.ptr, cb1, None) + if exc_info[0] is not None: + raise exc_info[0] + if res < 0: + raise Error + return bool(res) + def extract_map(arg0, arg1): + try: + if not arg0.__class__ is union_map: + arg0 = union_map(arg0) + except: + raise + try: + if not arg1.__class__ is space: + arg1 = space(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_map_extract_map(arg0.ptr, isl.isl_space_copy(arg1.ptr)) + obj = map(ctx=ctx, ptr=res) + return obj + def factor_domain(arg0): + try: + if not arg0.__class__ is union_map: + arg0 = union_map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_map_factor_domain(isl.isl_union_map_copy(arg0.ptr)) + obj = union_map(ctx=ctx, ptr=res) + return obj + def factor_range(arg0): + try: + if not arg0.__class__ is union_map: + arg0 = union_map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_map_factor_range(isl.isl_union_map_copy(arg0.ptr)) + obj = union_map(ctx=ctx, ptr=res) + return obj + def fixed_power(*args): + if len(args) == 2 and (args[1].__class__ is val or type(args[1]) == int): + args = list(args) + try: + if not args[0].__class__ is union_map: + args[0] = union_map(args[0]) + except: + raise + try: + if not args[1].__class__ is val: + args[1] = val(args[1]) + except: + raise + ctx = args[0].ctx + res = isl.isl_union_map_fixed_power_val(isl.isl_union_map_copy(args[0].ptr), isl.isl_val_copy(args[1].ptr)) + obj = union_map(ctx=ctx, ptr=res) + return obj + raise Error + def foreach_map(arg0, arg1): + try: + if not arg0.__class__ is union_map: + arg0 = union_map(arg0) + except: + raise + exc_info = [None] + fn = CFUNCTYPE(c_int, c_void_p, c_void_p) + def cb_func(cb_arg0, cb_arg1): + cb_arg0 = map(ctx=arg0.ctx, ptr=(cb_arg0)) + try: + arg1(cb_arg0) + except BaseException as e: + exc_info[0] = e + return -1 + return 0 + cb1 = fn(cb_func) + ctx = arg0.ctx + res = isl.isl_union_map_foreach_map(arg0.ptr, cb1, None) + if exc_info[0] is not None: + raise exc_info[0] + if res < 0: + raise Error + @staticmethod + def convert_from(*args): + if len(args) == 1 and args[0].__class__ is multi_union_pw_aff: + ctx = args[0].ctx + res = isl.isl_union_map_from_multi_union_pw_aff(isl.isl_multi_union_pw_aff_copy(args[0].ptr)) + obj = union_map(ctx=ctx, ptr=res) + return obj + if len(args) == 1 and args[0].__class__ is union_pw_multi_aff: + ctx = args[0].ctx + res = isl.isl_union_map_from_union_pw_multi_aff(isl.isl_union_pw_multi_aff_copy(args[0].ptr)) + obj = union_map(ctx=ctx, ptr=res) + return obj + raise Error + @staticmethod + def from_domain(arg0): + try: + if not arg0.__class__ is union_set: + arg0 = union_set(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_map_from_domain(isl.isl_union_set_copy(arg0.ptr)) + obj = union_map(ctx=ctx, ptr=res) + return obj + @staticmethod + def from_domain_and_range(arg0, arg1): + try: + if not arg0.__class__ is union_set: + arg0 = union_set(arg0) + except: + raise + try: + if not arg1.__class__ is union_set: + arg1 = union_set(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_map_from_domain_and_range(isl.isl_union_set_copy(arg0.ptr), isl.isl_union_set_copy(arg1.ptr)) + obj = union_map(ctx=ctx, ptr=res) + return obj + @staticmethod + def from_range(arg0): + try: + if not arg0.__class__ is union_set: + arg0 = union_set(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_map_from_range(isl.isl_union_set_copy(arg0.ptr)) + obj = union_map(ctx=ctx, ptr=res) + return obj + def gist(arg0, arg1): + try: + if not arg0.__class__ is union_map: + arg0 = union_map(arg0) + except: + raise + try: + if not arg1.__class__ is union_map: + arg1 = union_map(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_map_gist(isl.isl_union_map_copy(arg0.ptr), isl.isl_union_map_copy(arg1.ptr)) + obj = union_map(ctx=ctx, ptr=res) + return obj + def gist_domain(arg0, arg1): + try: + if not arg0.__class__ is union_map: + arg0 = union_map(arg0) + except: + raise + try: + if not arg1.__class__ is union_set: + arg1 = union_set(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_map_gist_domain(isl.isl_union_map_copy(arg0.ptr), isl.isl_union_set_copy(arg1.ptr)) + obj = union_map(ctx=ctx, ptr=res) + return obj + def gist_params(arg0, arg1): + try: + if not arg0.__class__ is union_map: + arg0 = union_map(arg0) + except: + raise + try: + if not arg1.__class__ is set: + arg1 = set(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_map_gist_params(isl.isl_union_map_copy(arg0.ptr), isl.isl_set_copy(arg1.ptr)) + obj = union_map(ctx=ctx, ptr=res) + return obj + def gist_range(arg0, arg1): + try: + if not arg0.__class__ is union_map: + arg0 = union_map(arg0) + except: + raise + try: + if not arg1.__class__ is union_set: + arg1 = union_set(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_map_gist_range(isl.isl_union_map_copy(arg0.ptr), isl.isl_union_set_copy(arg1.ptr)) + obj = union_map(ctx=ctx, ptr=res) + return obj + def intersect(arg0, arg1): + try: + if not arg0.__class__ is union_map: + arg0 = union_map(arg0) + except: + raise + try: + if not arg1.__class__ is union_map: + arg1 = union_map(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_map_intersect(isl.isl_union_map_copy(arg0.ptr), isl.isl_union_map_copy(arg1.ptr)) + obj = union_map(ctx=ctx, ptr=res) + return obj + def intersect_domain(*args): + if len(args) == 2 and args[1].__class__ is space: + args = list(args) + try: + if not args[0].__class__ is union_map: + args[0] = union_map(args[0]) + except: + raise + ctx = args[0].ctx + res = isl.isl_union_map_intersect_domain_space(isl.isl_union_map_copy(args[0].ptr), isl.isl_space_copy(args[1].ptr)) + obj = union_map(ctx=ctx, ptr=res) + return obj + if len(args) == 2 and args[1].__class__ is union_set: + args = list(args) + try: + if not args[0].__class__ is union_map: + args[0] = union_map(args[0]) + except: + raise + ctx = args[0].ctx + res = isl.isl_union_map_intersect_domain_union_set(isl.isl_union_map_copy(args[0].ptr), isl.isl_union_set_copy(args[1].ptr)) + obj = union_map(ctx=ctx, ptr=res) + return obj + raise Error + def intersect_domain_factor_domain(arg0, arg1): + try: + if not arg0.__class__ is union_map: + arg0 = union_map(arg0) + except: + raise + try: + if not arg1.__class__ is union_map: + arg1 = union_map(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_map_intersect_domain_factor_domain(isl.isl_union_map_copy(arg0.ptr), isl.isl_union_map_copy(arg1.ptr)) + obj = union_map(ctx=ctx, ptr=res) + return obj + def intersect_domain_factor_range(arg0, arg1): + try: + if not arg0.__class__ is union_map: + arg0 = union_map(arg0) + except: + raise + try: + if not arg1.__class__ is union_map: + arg1 = union_map(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_map_intersect_domain_factor_range(isl.isl_union_map_copy(arg0.ptr), isl.isl_union_map_copy(arg1.ptr)) + obj = union_map(ctx=ctx, ptr=res) + return obj + def intersect_domain_wrapped_domain(*args): + if len(args) == 2 and args[1].__class__ is union_set: + args = list(args) + try: + if not args[0].__class__ is union_map: + args[0] = union_map(args[0]) + except: + raise + ctx = args[0].ctx + res = isl.isl_union_map_intersect_domain_wrapped_domain_union_set(isl.isl_union_map_copy(args[0].ptr), isl.isl_union_set_copy(args[1].ptr)) + obj = union_map(ctx=ctx, ptr=res) + return obj + raise Error + def intersect_params(arg0, arg1): + try: + if not arg0.__class__ is union_map: + arg0 = union_map(arg0) + except: + raise + try: + if not arg1.__class__ is set: + arg1 = set(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_map_intersect_params(isl.isl_union_map_copy(arg0.ptr), isl.isl_set_copy(arg1.ptr)) + obj = union_map(ctx=ctx, ptr=res) + return obj + def intersect_range(*args): + if len(args) == 2 and args[1].__class__ is space: + args = list(args) + try: + if not args[0].__class__ is union_map: + args[0] = union_map(args[0]) + except: + raise + ctx = args[0].ctx + res = isl.isl_union_map_intersect_range_space(isl.isl_union_map_copy(args[0].ptr), isl.isl_space_copy(args[1].ptr)) + obj = union_map(ctx=ctx, ptr=res) + return obj + if len(args) == 2 and args[1].__class__ is union_set: + args = list(args) + try: + if not args[0].__class__ is union_map: + args[0] = union_map(args[0]) + except: + raise + ctx = args[0].ctx + res = isl.isl_union_map_intersect_range_union_set(isl.isl_union_map_copy(args[0].ptr), isl.isl_union_set_copy(args[1].ptr)) + obj = union_map(ctx=ctx, ptr=res) + return obj + raise Error + def intersect_range_factor_domain(arg0, arg1): + try: + if not arg0.__class__ is union_map: + arg0 = union_map(arg0) + except: + raise + try: + if not arg1.__class__ is union_map: + arg1 = union_map(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_map_intersect_range_factor_domain(isl.isl_union_map_copy(arg0.ptr), isl.isl_union_map_copy(arg1.ptr)) + obj = union_map(ctx=ctx, ptr=res) + return obj + def intersect_range_factor_range(arg0, arg1): + try: + if not arg0.__class__ is union_map: + arg0 = union_map(arg0) + except: + raise + try: + if not arg1.__class__ is union_map: + arg1 = union_map(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_map_intersect_range_factor_range(isl.isl_union_map_copy(arg0.ptr), isl.isl_union_map_copy(arg1.ptr)) + obj = union_map(ctx=ctx, ptr=res) + return obj + def intersect_range_wrapped_domain(*args): + if len(args) == 2 and args[1].__class__ is union_set: + args = list(args) + try: + if not args[0].__class__ is union_map: + args[0] = union_map(args[0]) + except: + raise + ctx = args[0].ctx + res = isl.isl_union_map_intersect_range_wrapped_domain_union_set(isl.isl_union_map_copy(args[0].ptr), isl.isl_union_set_copy(args[1].ptr)) + obj = union_map(ctx=ctx, ptr=res) + return obj + raise Error + def is_bijective(arg0): + try: + if not arg0.__class__ is union_map: + arg0 = union_map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_map_is_bijective(arg0.ptr) + if res < 0: + raise Error + return bool(res) + def is_disjoint(arg0, arg1): + try: + if not arg0.__class__ is union_map: + arg0 = union_map(arg0) + except: + raise + try: + if not arg1.__class__ is union_map: + arg1 = union_map(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_map_is_disjoint(arg0.ptr, arg1.ptr) + if res < 0: + raise Error + return bool(res) + def is_empty(arg0): + try: + if not arg0.__class__ is union_map: + arg0 = union_map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_map_is_empty(arg0.ptr) + if res < 0: + raise Error + return bool(res) + def is_equal(arg0, arg1): + try: + if not arg0.__class__ is union_map: + arg0 = union_map(arg0) + except: + raise + try: + if not arg1.__class__ is union_map: + arg1 = union_map(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_map_is_equal(arg0.ptr, arg1.ptr) + if res < 0: + raise Error + return bool(res) + def is_injective(arg0): + try: + if not arg0.__class__ is union_map: + arg0 = union_map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_map_is_injective(arg0.ptr) + if res < 0: + raise Error + return bool(res) + def is_single_valued(arg0): + try: + if not arg0.__class__ is union_map: + arg0 = union_map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_map_is_single_valued(arg0.ptr) + if res < 0: + raise Error + return bool(res) + def is_strict_subset(arg0, arg1): + try: + if not arg0.__class__ is union_map: + arg0 = union_map(arg0) + except: + raise + try: + if not arg1.__class__ is union_map: + arg1 = union_map(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_map_is_strict_subset(arg0.ptr, arg1.ptr) + if res < 0: + raise Error + return bool(res) + def is_subset(arg0, arg1): + try: + if not arg0.__class__ is union_map: + arg0 = union_map(arg0) + except: + raise + try: + if not arg1.__class__ is union_map: + arg1 = union_map(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_map_is_subset(arg0.ptr, arg1.ptr) + if res < 0: + raise Error + return bool(res) + def isa_map(arg0): + try: + if not arg0.__class__ is union_map: + arg0 = union_map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_map_isa_map(arg0.ptr) + if res < 0: + raise Error + return bool(res) + def lexmax(arg0): + try: + if not arg0.__class__ is union_map: + arg0 = union_map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_map_lexmax(isl.isl_union_map_copy(arg0.ptr)) + obj = union_map(ctx=ctx, ptr=res) + return obj + def lexmin(arg0): + try: + if not arg0.__class__ is union_map: + arg0 = union_map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_map_lexmin(isl.isl_union_map_copy(arg0.ptr)) + obj = union_map(ctx=ctx, ptr=res) + return obj + def map_list(arg0): + try: + if not arg0.__class__ is union_map: + arg0 = union_map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_map_get_map_list(arg0.ptr) + obj = map_list(ctx=ctx, ptr=res) + return obj + def get_map_list(arg0): + return arg0.map_list() + def params(arg0): + try: + if not arg0.__class__ is union_map: + arg0 = union_map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_map_params(isl.isl_union_map_copy(arg0.ptr)) + obj = set(ctx=ctx, ptr=res) + return obj + def polyhedral_hull(arg0): + try: + if not arg0.__class__ is union_map: + arg0 = union_map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_map_polyhedral_hull(isl.isl_union_map_copy(arg0.ptr)) + obj = union_map(ctx=ctx, ptr=res) + return obj + def preimage_domain(*args): + if len(args) == 2 and args[1].__class__ is multi_aff: + args = list(args) + try: + if not args[0].__class__ is union_map: + args[0] = union_map(args[0]) + except: + raise + ctx = args[0].ctx + res = isl.isl_union_map_preimage_domain_multi_aff(isl.isl_union_map_copy(args[0].ptr), isl.isl_multi_aff_copy(args[1].ptr)) + obj = union_map(ctx=ctx, ptr=res) + return obj + if len(args) == 2 and args[1].__class__ is multi_pw_aff: + args = list(args) + try: + if not args[0].__class__ is union_map: + args[0] = union_map(args[0]) + except: + raise + ctx = args[0].ctx + res = isl.isl_union_map_preimage_domain_multi_pw_aff(isl.isl_union_map_copy(args[0].ptr), isl.isl_multi_pw_aff_copy(args[1].ptr)) + obj = union_map(ctx=ctx, ptr=res) + return obj + if len(args) == 2 and args[1].__class__ is pw_multi_aff: + args = list(args) + try: + if not args[0].__class__ is union_map: + args[0] = union_map(args[0]) + except: + raise + ctx = args[0].ctx + res = isl.isl_union_map_preimage_domain_pw_multi_aff(isl.isl_union_map_copy(args[0].ptr), isl.isl_pw_multi_aff_copy(args[1].ptr)) + obj = union_map(ctx=ctx, ptr=res) + return obj + if len(args) == 2 and args[1].__class__ is union_pw_multi_aff: + args = list(args) + try: + if not args[0].__class__ is union_map: + args[0] = union_map(args[0]) + except: + raise + ctx = args[0].ctx + res = isl.isl_union_map_preimage_domain_union_pw_multi_aff(isl.isl_union_map_copy(args[0].ptr), isl.isl_union_pw_multi_aff_copy(args[1].ptr)) + obj = union_map(ctx=ctx, ptr=res) + return obj + raise Error + def preimage_range(*args): + if len(args) == 2 and args[1].__class__ is multi_aff: + args = list(args) + try: + if not args[0].__class__ is union_map: + args[0] = union_map(args[0]) + except: + raise + ctx = args[0].ctx + res = isl.isl_union_map_preimage_range_multi_aff(isl.isl_union_map_copy(args[0].ptr), isl.isl_multi_aff_copy(args[1].ptr)) + obj = union_map(ctx=ctx, ptr=res) + return obj + if len(args) == 2 and args[1].__class__ is pw_multi_aff: + args = list(args) + try: + if not args[0].__class__ is union_map: + args[0] = union_map(args[0]) + except: + raise + ctx = args[0].ctx + res = isl.isl_union_map_preimage_range_pw_multi_aff(isl.isl_union_map_copy(args[0].ptr), isl.isl_pw_multi_aff_copy(args[1].ptr)) + obj = union_map(ctx=ctx, ptr=res) + return obj + if len(args) == 2 and args[1].__class__ is union_pw_multi_aff: + args = list(args) + try: + if not args[0].__class__ is union_map: + args[0] = union_map(args[0]) + except: + raise + ctx = args[0].ctx + res = isl.isl_union_map_preimage_range_union_pw_multi_aff(isl.isl_union_map_copy(args[0].ptr), isl.isl_union_pw_multi_aff_copy(args[1].ptr)) + obj = union_map(ctx=ctx, ptr=res) + return obj + raise Error + def product(arg0, arg1): + try: + if not arg0.__class__ is union_map: + arg0 = union_map(arg0) + except: + raise + try: + if not arg1.__class__ is union_map: + arg1 = union_map(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_map_product(isl.isl_union_map_copy(arg0.ptr), isl.isl_union_map_copy(arg1.ptr)) + obj = union_map(ctx=ctx, ptr=res) + return obj + def project_out_all_params(arg0): + try: + if not arg0.__class__ is union_map: + arg0 = union_map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_map_project_out_all_params(isl.isl_union_map_copy(arg0.ptr)) + obj = union_map(ctx=ctx, ptr=res) + return obj + def project_out_param(*args): + if len(args) == 2 and (args[1].__class__ is id or type(args[1]) == str): + args = list(args) + try: + if not args[0].__class__ is union_map: + args[0] = union_map(args[0]) + except: + raise + try: + if not args[1].__class__ is id: + args[1] = id(args[1]) + except: + raise + ctx = args[0].ctx + res = isl.isl_union_map_project_out_param_id(isl.isl_union_map_copy(args[0].ptr), isl.isl_id_copy(args[1].ptr)) + obj = union_map(ctx=ctx, ptr=res) + return obj + if len(args) == 2 and args[1].__class__ is id_list: + args = list(args) + try: + if not args[0].__class__ is union_map: + args[0] = union_map(args[0]) + except: + raise + ctx = args[0].ctx + res = isl.isl_union_map_project_out_param_id_list(isl.isl_union_map_copy(args[0].ptr), isl.isl_id_list_copy(args[1].ptr)) + obj = union_map(ctx=ctx, ptr=res) + return obj + raise Error + def range(arg0): + try: + if not arg0.__class__ is union_map: + arg0 = union_map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_map_range(isl.isl_union_map_copy(arg0.ptr)) + obj = union_set(ctx=ctx, ptr=res) + return obj + def range_factor_domain(arg0): + try: + if not arg0.__class__ is union_map: + arg0 = union_map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_map_range_factor_domain(isl.isl_union_map_copy(arg0.ptr)) + obj = union_map(ctx=ctx, ptr=res) + return obj + def range_factor_range(arg0): + try: + if not arg0.__class__ is union_map: + arg0 = union_map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_map_range_factor_range(isl.isl_union_map_copy(arg0.ptr)) + obj = union_map(ctx=ctx, ptr=res) + return obj + def range_map(arg0): + try: + if not arg0.__class__ is union_map: + arg0 = union_map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_map_range_map(isl.isl_union_map_copy(arg0.ptr)) + obj = union_map(ctx=ctx, ptr=res) + return obj + def range_product(arg0, arg1): + try: + if not arg0.__class__ is union_map: + arg0 = union_map(arg0) + except: + raise + try: + if not arg1.__class__ is union_map: + arg1 = union_map(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_map_range_product(isl.isl_union_map_copy(arg0.ptr), isl.isl_union_map_copy(arg1.ptr)) + obj = union_map(ctx=ctx, ptr=res) + return obj + def range_reverse(arg0): + try: + if not arg0.__class__ is union_map: + arg0 = union_map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_map_range_reverse(isl.isl_union_map_copy(arg0.ptr)) + obj = union_map(ctx=ctx, ptr=res) + return obj + def reverse(arg0): + try: + if not arg0.__class__ is union_map: + arg0 = union_map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_map_reverse(isl.isl_union_map_copy(arg0.ptr)) + obj = union_map(ctx=ctx, ptr=res) + return obj + def space(arg0): + try: + if not arg0.__class__ is union_map: + arg0 = union_map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_map_get_space(arg0.ptr) + obj = space(ctx=ctx, ptr=res) + return obj + def get_space(arg0): + return arg0.space() + def subtract(arg0, arg1): + try: + if not arg0.__class__ is union_map: + arg0 = union_map(arg0) + except: + raise + try: + if not arg1.__class__ is union_map: + arg1 = union_map(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_map_subtract(isl.isl_union_map_copy(arg0.ptr), isl.isl_union_map_copy(arg1.ptr)) + obj = union_map(ctx=ctx, ptr=res) + return obj + def subtract_domain(arg0, arg1): + try: + if not arg0.__class__ is union_map: + arg0 = union_map(arg0) + except: + raise + try: + if not arg1.__class__ is union_set: + arg1 = union_set(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_map_subtract_domain(isl.isl_union_map_copy(arg0.ptr), isl.isl_union_set_copy(arg1.ptr)) + obj = union_map(ctx=ctx, ptr=res) + return obj + def subtract_range(arg0, arg1): + try: + if not arg0.__class__ is union_map: + arg0 = union_map(arg0) + except: + raise + try: + if not arg1.__class__ is union_set: + arg1 = union_set(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_map_subtract_range(isl.isl_union_map_copy(arg0.ptr), isl.isl_union_set_copy(arg1.ptr)) + obj = union_map(ctx=ctx, ptr=res) + return obj + def uncurry(arg0): + try: + if not arg0.__class__ is union_map: + arg0 = union_map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_map_uncurry(isl.isl_union_map_copy(arg0.ptr)) + obj = union_map(ctx=ctx, ptr=res) + return obj + def union(arg0, arg1): + try: + if not arg0.__class__ is union_map: + arg0 = union_map(arg0) + except: + raise + try: + if not arg1.__class__ is union_map: + arg1 = union_map(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_map_union(isl.isl_union_map_copy(arg0.ptr), isl.isl_union_map_copy(arg1.ptr)) + obj = union_map(ctx=ctx, ptr=res) + return obj + def universe(arg0): + try: + if not arg0.__class__ is union_map: + arg0 = union_map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_map_universe(isl.isl_union_map_copy(arg0.ptr)) + obj = union_map(ctx=ctx, ptr=res) + return obj + def wrap(arg0): + try: + if not arg0.__class__ is union_map: + arg0 = union_map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_map_wrap(isl.isl_union_map_copy(arg0.ptr)) + obj = union_set(ctx=ctx, ptr=res) + return obj + def zip(arg0): + try: + if not arg0.__class__ is union_map: + arg0 = union_map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_map_zip(isl.isl_union_map_copy(arg0.ptr)) + obj = union_map(ctx=ctx, ptr=res) + return obj + +isl.isl_union_map_from_basic_map.restype = c_void_p +isl.isl_union_map_from_basic_map.argtypes = [c_void_p] +isl.isl_union_map_from_map.restype = c_void_p +isl.isl_union_map_from_map.argtypes = [c_void_p] +isl.isl_union_map_read_from_str.restype = c_void_p +isl.isl_union_map_read_from_str.argtypes = [Context, c_char_p] +isl.isl_union_map_affine_hull.restype = c_void_p +isl.isl_union_map_affine_hull.argtypes = [c_void_p] +isl.isl_union_map_apply_domain.restype = c_void_p +isl.isl_union_map_apply_domain.argtypes = [c_void_p, c_void_p] +isl.isl_union_map_apply_range.restype = c_void_p +isl.isl_union_map_apply_range.argtypes = [c_void_p, c_void_p] +isl.isl_union_map_as_map.restype = c_void_p +isl.isl_union_map_as_map.argtypes = [c_void_p] +isl.isl_union_map_as_multi_union_pw_aff.restype = c_void_p +isl.isl_union_map_as_multi_union_pw_aff.argtypes = [c_void_p] +isl.isl_union_map_as_union_pw_multi_aff.restype = c_void_p +isl.isl_union_map_as_union_pw_multi_aff.argtypes = [c_void_p] +isl.isl_union_map_bind_range.restype = c_void_p +isl.isl_union_map_bind_range.argtypes = [c_void_p, c_void_p] +isl.isl_union_map_coalesce.restype = c_void_p +isl.isl_union_map_coalesce.argtypes = [c_void_p] +isl.isl_union_map_compute_divs.restype = c_void_p +isl.isl_union_map_compute_divs.argtypes = [c_void_p] +isl.isl_union_map_curry.restype = c_void_p +isl.isl_union_map_curry.argtypes = [c_void_p] +isl.isl_union_map_deltas.restype = c_void_p +isl.isl_union_map_deltas.argtypes = [c_void_p] +isl.isl_union_map_detect_equalities.restype = c_void_p +isl.isl_union_map_detect_equalities.argtypes = [c_void_p] +isl.isl_union_map_domain.restype = c_void_p +isl.isl_union_map_domain.argtypes = [c_void_p] +isl.isl_union_map_domain_factor_domain.restype = c_void_p +isl.isl_union_map_domain_factor_domain.argtypes = [c_void_p] +isl.isl_union_map_domain_factor_range.restype = c_void_p +isl.isl_union_map_domain_factor_range.argtypes = [c_void_p] +isl.isl_union_map_domain_map.restype = c_void_p +isl.isl_union_map_domain_map.argtypes = [c_void_p] +isl.isl_union_map_domain_map_union_pw_multi_aff.restype = c_void_p +isl.isl_union_map_domain_map_union_pw_multi_aff.argtypes = [c_void_p] +isl.isl_union_map_domain_product.restype = c_void_p +isl.isl_union_map_domain_product.argtypes = [c_void_p, c_void_p] +isl.isl_union_map_domain_reverse.restype = c_void_p +isl.isl_union_map_domain_reverse.argtypes = [c_void_p] +isl.isl_union_map_drop_unused_params.restype = c_void_p +isl.isl_union_map_drop_unused_params.argtypes = [c_void_p] +isl.isl_union_map_empty_ctx.restype = c_void_p +isl.isl_union_map_empty_ctx.argtypes = [Context] +isl.isl_union_map_eq_at_multi_union_pw_aff.restype = c_void_p +isl.isl_union_map_eq_at_multi_union_pw_aff.argtypes = [c_void_p, c_void_p] +isl.isl_union_map_every_map.argtypes = [c_void_p, c_void_p, c_void_p] +isl.isl_union_map_extract_map.restype = c_void_p +isl.isl_union_map_extract_map.argtypes = [c_void_p, c_void_p] +isl.isl_union_map_factor_domain.restype = c_void_p +isl.isl_union_map_factor_domain.argtypes = [c_void_p] +isl.isl_union_map_factor_range.restype = c_void_p +isl.isl_union_map_factor_range.argtypes = [c_void_p] +isl.isl_union_map_fixed_power_val.restype = c_void_p +isl.isl_union_map_fixed_power_val.argtypes = [c_void_p, c_void_p] +isl.isl_union_map_foreach_map.argtypes = [c_void_p, c_void_p, c_void_p] +isl.isl_union_map_from_multi_union_pw_aff.restype = c_void_p +isl.isl_union_map_from_multi_union_pw_aff.argtypes = [c_void_p] +isl.isl_union_map_from_union_pw_multi_aff.restype = c_void_p +isl.isl_union_map_from_union_pw_multi_aff.argtypes = [c_void_p] +isl.isl_union_map_from_domain.restype = c_void_p +isl.isl_union_map_from_domain.argtypes = [c_void_p] +isl.isl_union_map_from_domain_and_range.restype = c_void_p +isl.isl_union_map_from_domain_and_range.argtypes = [c_void_p, c_void_p] +isl.isl_union_map_from_range.restype = c_void_p +isl.isl_union_map_from_range.argtypes = [c_void_p] +isl.isl_union_map_gist.restype = c_void_p +isl.isl_union_map_gist.argtypes = [c_void_p, c_void_p] +isl.isl_union_map_gist_domain.restype = c_void_p +isl.isl_union_map_gist_domain.argtypes = [c_void_p, c_void_p] +isl.isl_union_map_gist_params.restype = c_void_p +isl.isl_union_map_gist_params.argtypes = [c_void_p, c_void_p] +isl.isl_union_map_gist_range.restype = c_void_p +isl.isl_union_map_gist_range.argtypes = [c_void_p, c_void_p] +isl.isl_union_map_intersect.restype = c_void_p +isl.isl_union_map_intersect.argtypes = [c_void_p, c_void_p] +isl.isl_union_map_intersect_domain_space.restype = c_void_p +isl.isl_union_map_intersect_domain_space.argtypes = [c_void_p, c_void_p] +isl.isl_union_map_intersect_domain_union_set.restype = c_void_p +isl.isl_union_map_intersect_domain_union_set.argtypes = [c_void_p, c_void_p] +isl.isl_union_map_intersect_domain_factor_domain.restype = c_void_p +isl.isl_union_map_intersect_domain_factor_domain.argtypes = [c_void_p, c_void_p] +isl.isl_union_map_intersect_domain_factor_range.restype = c_void_p +isl.isl_union_map_intersect_domain_factor_range.argtypes = [c_void_p, c_void_p] +isl.isl_union_map_intersect_domain_wrapped_domain_union_set.restype = c_void_p +isl.isl_union_map_intersect_domain_wrapped_domain_union_set.argtypes = [c_void_p, c_void_p] +isl.isl_union_map_intersect_params.restype = c_void_p +isl.isl_union_map_intersect_params.argtypes = [c_void_p, c_void_p] +isl.isl_union_map_intersect_range_space.restype = c_void_p +isl.isl_union_map_intersect_range_space.argtypes = [c_void_p, c_void_p] +isl.isl_union_map_intersect_range_union_set.restype = c_void_p +isl.isl_union_map_intersect_range_union_set.argtypes = [c_void_p, c_void_p] +isl.isl_union_map_intersect_range_factor_domain.restype = c_void_p +isl.isl_union_map_intersect_range_factor_domain.argtypes = [c_void_p, c_void_p] +isl.isl_union_map_intersect_range_factor_range.restype = c_void_p +isl.isl_union_map_intersect_range_factor_range.argtypes = [c_void_p, c_void_p] +isl.isl_union_map_intersect_range_wrapped_domain_union_set.restype = c_void_p +isl.isl_union_map_intersect_range_wrapped_domain_union_set.argtypes = [c_void_p, c_void_p] +isl.isl_union_map_is_bijective.argtypes = [c_void_p] +isl.isl_union_map_is_disjoint.argtypes = [c_void_p, c_void_p] +isl.isl_union_map_is_empty.argtypes = [c_void_p] +isl.isl_union_map_is_equal.argtypes = [c_void_p, c_void_p] +isl.isl_union_map_is_injective.argtypes = [c_void_p] +isl.isl_union_map_is_single_valued.argtypes = [c_void_p] +isl.isl_union_map_is_strict_subset.argtypes = [c_void_p, c_void_p] +isl.isl_union_map_is_subset.argtypes = [c_void_p, c_void_p] +isl.isl_union_map_isa_map.argtypes = [c_void_p] +isl.isl_union_map_lexmax.restype = c_void_p +isl.isl_union_map_lexmax.argtypes = [c_void_p] +isl.isl_union_map_lexmin.restype = c_void_p +isl.isl_union_map_lexmin.argtypes = [c_void_p] +isl.isl_union_map_get_map_list.restype = c_void_p +isl.isl_union_map_get_map_list.argtypes = [c_void_p] +isl.isl_union_map_params.restype = c_void_p +isl.isl_union_map_params.argtypes = [c_void_p] +isl.isl_union_map_polyhedral_hull.restype = c_void_p +isl.isl_union_map_polyhedral_hull.argtypes = [c_void_p] +isl.isl_union_map_preimage_domain_multi_aff.restype = c_void_p +isl.isl_union_map_preimage_domain_multi_aff.argtypes = [c_void_p, c_void_p] +isl.isl_union_map_preimage_domain_multi_pw_aff.restype = c_void_p +isl.isl_union_map_preimage_domain_multi_pw_aff.argtypes = [c_void_p, c_void_p] +isl.isl_union_map_preimage_domain_pw_multi_aff.restype = c_void_p +isl.isl_union_map_preimage_domain_pw_multi_aff.argtypes = [c_void_p, c_void_p] +isl.isl_union_map_preimage_domain_union_pw_multi_aff.restype = c_void_p +isl.isl_union_map_preimage_domain_union_pw_multi_aff.argtypes = [c_void_p, c_void_p] +isl.isl_union_map_preimage_range_multi_aff.restype = c_void_p +isl.isl_union_map_preimage_range_multi_aff.argtypes = [c_void_p, c_void_p] +isl.isl_union_map_preimage_range_pw_multi_aff.restype = c_void_p +isl.isl_union_map_preimage_range_pw_multi_aff.argtypes = [c_void_p, c_void_p] +isl.isl_union_map_preimage_range_union_pw_multi_aff.restype = c_void_p +isl.isl_union_map_preimage_range_union_pw_multi_aff.argtypes = [c_void_p, c_void_p] +isl.isl_union_map_product.restype = c_void_p +isl.isl_union_map_product.argtypes = [c_void_p, c_void_p] +isl.isl_union_map_project_out_all_params.restype = c_void_p +isl.isl_union_map_project_out_all_params.argtypes = [c_void_p] +isl.isl_union_map_project_out_param_id.restype = c_void_p +isl.isl_union_map_project_out_param_id.argtypes = [c_void_p, c_void_p] +isl.isl_union_map_project_out_param_id_list.restype = c_void_p +isl.isl_union_map_project_out_param_id_list.argtypes = [c_void_p, c_void_p] +isl.isl_union_map_range.restype = c_void_p +isl.isl_union_map_range.argtypes = [c_void_p] +isl.isl_union_map_range_factor_domain.restype = c_void_p +isl.isl_union_map_range_factor_domain.argtypes = [c_void_p] +isl.isl_union_map_range_factor_range.restype = c_void_p +isl.isl_union_map_range_factor_range.argtypes = [c_void_p] +isl.isl_union_map_range_map.restype = c_void_p +isl.isl_union_map_range_map.argtypes = [c_void_p] +isl.isl_union_map_range_product.restype = c_void_p +isl.isl_union_map_range_product.argtypes = [c_void_p, c_void_p] +isl.isl_union_map_range_reverse.restype = c_void_p +isl.isl_union_map_range_reverse.argtypes = [c_void_p] +isl.isl_union_map_reverse.restype = c_void_p +isl.isl_union_map_reverse.argtypes = [c_void_p] +isl.isl_union_map_get_space.restype = c_void_p +isl.isl_union_map_get_space.argtypes = [c_void_p] +isl.isl_union_map_subtract.restype = c_void_p +isl.isl_union_map_subtract.argtypes = [c_void_p, c_void_p] +isl.isl_union_map_subtract_domain.restype = c_void_p +isl.isl_union_map_subtract_domain.argtypes = [c_void_p, c_void_p] +isl.isl_union_map_subtract_range.restype = c_void_p +isl.isl_union_map_subtract_range.argtypes = [c_void_p, c_void_p] +isl.isl_union_map_uncurry.restype = c_void_p +isl.isl_union_map_uncurry.argtypes = [c_void_p] +isl.isl_union_map_union.restype = c_void_p +isl.isl_union_map_union.argtypes = [c_void_p, c_void_p] +isl.isl_union_map_universe.restype = c_void_p +isl.isl_union_map_universe.argtypes = [c_void_p] +isl.isl_union_map_wrap.restype = c_void_p +isl.isl_union_map_wrap.argtypes = [c_void_p] +isl.isl_union_map_zip.restype = c_void_p +isl.isl_union_map_zip.argtypes = [c_void_p] +isl.isl_union_map_copy.restype = c_void_p +isl.isl_union_map_copy.argtypes = [c_void_p] +isl.isl_union_map_free.restype = c_void_p +isl.isl_union_map_free.argtypes = [c_void_p] +isl.isl_union_map_to_str.restype = POINTER(c_char) +isl.isl_union_map_to_str.argtypes = [c_void_p] + +class map(union_map): + def __init__(self, *args, **keywords): + if "ptr" in keywords: + self.ctx = keywords["ctx"] + self.ptr = keywords["ptr"] + return + if len(args) == 1 and args[0].__class__ is basic_map: + self.ctx = Context.getDefaultInstance() + self.ptr = isl.isl_map_from_basic_map(isl.isl_basic_map_copy(args[0].ptr)) + return + if len(args) == 1 and type(args[0]) == str: + self.ctx = Context.getDefaultInstance() + self.ptr = isl.isl_map_read_from_str(self.ctx, args[0].encode('ascii')) + return + raise Error + def __del__(self): + if hasattr(self, 'ptr'): + isl.isl_map_free(self.ptr) + def __str__(arg0): + try: + if not arg0.__class__ is map: + arg0 = map(arg0) + except: + raise + ptr = isl.isl_map_to_str(arg0.ptr) + res = cast(ptr, c_char_p).value.decode('ascii') + libc.free(ptr) + return res + def __repr__(self): + s = str(self) + if '"' in s: + return 'isl.map("""%s""")' % s + else: + return 'isl.map("%s")' % s + def affine_hull(arg0): + try: + if not arg0.__class__ is map: + arg0 = map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_map_affine_hull(isl.isl_map_copy(arg0.ptr)) + obj = basic_map(ctx=ctx, ptr=res) + return obj + def apply_domain(arg0, arg1): + try: + if not arg0.__class__ is map: + arg0 = map(arg0) + except: + raise + try: + if not arg1.__class__ is map: + arg1 = map(arg1) + except: + return union_map(arg0).apply_domain(arg1) + ctx = arg0.ctx + res = isl.isl_map_apply_domain(isl.isl_map_copy(arg0.ptr), isl.isl_map_copy(arg1.ptr)) + obj = map(ctx=ctx, ptr=res) + return obj + def apply_range(arg0, arg1): + try: + if not arg0.__class__ is map: + arg0 = map(arg0) + except: + raise + try: + if not arg1.__class__ is map: + arg1 = map(arg1) + except: + return union_map(arg0).apply_range(arg1) + ctx = arg0.ctx + res = isl.isl_map_apply_range(isl.isl_map_copy(arg0.ptr), isl.isl_map_copy(arg1.ptr)) + obj = map(ctx=ctx, ptr=res) + return obj + def as_pw_multi_aff(arg0): + try: + if not arg0.__class__ is map: + arg0 = map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_map_as_pw_multi_aff(isl.isl_map_copy(arg0.ptr)) + obj = pw_multi_aff(ctx=ctx, ptr=res) + return obj + def bind_domain(arg0, arg1): + try: + if not arg0.__class__ is map: + arg0 = map(arg0) + except: + raise + try: + if not arg1.__class__ is multi_id: + arg1 = multi_id(arg1) + except: + return union_map(arg0).bind_domain(arg1) + ctx = arg0.ctx + res = isl.isl_map_bind_domain(isl.isl_map_copy(arg0.ptr), isl.isl_multi_id_copy(arg1.ptr)) + obj = set(ctx=ctx, ptr=res) + return obj + def bind_range(arg0, arg1): + try: + if not arg0.__class__ is map: + arg0 = map(arg0) + except: + raise + try: + if not arg1.__class__ is multi_id: + arg1 = multi_id(arg1) + except: + return union_map(arg0).bind_range(arg1) + ctx = arg0.ctx + res = isl.isl_map_bind_range(isl.isl_map_copy(arg0.ptr), isl.isl_multi_id_copy(arg1.ptr)) + obj = set(ctx=ctx, ptr=res) + return obj + def coalesce(arg0): + try: + if not arg0.__class__ is map: + arg0 = map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_map_coalesce(isl.isl_map_copy(arg0.ptr)) + obj = map(ctx=ctx, ptr=res) + return obj + def complement(arg0): + try: + if not arg0.__class__ is map: + arg0 = map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_map_complement(isl.isl_map_copy(arg0.ptr)) + obj = map(ctx=ctx, ptr=res) + return obj + def curry(arg0): + try: + if not arg0.__class__ is map: + arg0 = map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_map_curry(isl.isl_map_copy(arg0.ptr)) + obj = map(ctx=ctx, ptr=res) + return obj + def deltas(arg0): + try: + if not arg0.__class__ is map: + arg0 = map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_map_deltas(isl.isl_map_copy(arg0.ptr)) + obj = set(ctx=ctx, ptr=res) + return obj + def detect_equalities(arg0): + try: + if not arg0.__class__ is map: + arg0 = map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_map_detect_equalities(isl.isl_map_copy(arg0.ptr)) + obj = map(ctx=ctx, ptr=res) + return obj + def domain(arg0): + try: + if not arg0.__class__ is map: + arg0 = map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_map_domain(isl.isl_map_copy(arg0.ptr)) + obj = set(ctx=ctx, ptr=res) + return obj + def domain_factor_domain(arg0): + try: + if not arg0.__class__ is map: + arg0 = map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_map_domain_factor_domain(isl.isl_map_copy(arg0.ptr)) + obj = map(ctx=ctx, ptr=res) + return obj + def domain_factor_range(arg0): + try: + if not arg0.__class__ is map: + arg0 = map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_map_domain_factor_range(isl.isl_map_copy(arg0.ptr)) + obj = map(ctx=ctx, ptr=res) + return obj + def domain_product(arg0, arg1): + try: + if not arg0.__class__ is map: + arg0 = map(arg0) + except: + raise + try: + if not arg1.__class__ is map: + arg1 = map(arg1) + except: + return union_map(arg0).domain_product(arg1) + ctx = arg0.ctx + res = isl.isl_map_domain_product(isl.isl_map_copy(arg0.ptr), isl.isl_map_copy(arg1.ptr)) + obj = map(ctx=ctx, ptr=res) + return obj + def domain_reverse(arg0): + try: + if not arg0.__class__ is map: + arg0 = map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_map_domain_reverse(isl.isl_map_copy(arg0.ptr)) + obj = map(ctx=ctx, ptr=res) + return obj + def domain_tuple_dim(arg0): + try: + if not arg0.__class__ is map: + arg0 = map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_map_domain_tuple_dim(arg0.ptr) + if res < 0: + raise Error + return int(res) + def domain_tuple_id(arg0): + try: + if not arg0.__class__ is map: + arg0 = map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_map_get_domain_tuple_id(arg0.ptr) + obj = id(ctx=ctx, ptr=res) + return obj + def get_domain_tuple_id(arg0): + return arg0.domain_tuple_id() + def drop_unused_params(arg0): + try: + if not arg0.__class__ is map: + arg0 = map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_map_drop_unused_params(isl.isl_map_copy(arg0.ptr)) + obj = map(ctx=ctx, ptr=res) + return obj + @staticmethod + def empty(arg0): + try: + if not arg0.__class__ is space: + arg0 = space(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_map_empty(isl.isl_space_copy(arg0.ptr)) + obj = map(ctx=ctx, ptr=res) + return obj + def eq_at(*args): + if len(args) == 2 and args[1].__class__ is multi_pw_aff: + args = list(args) + try: + if not args[0].__class__ is map: + args[0] = map(args[0]) + except: + raise + ctx = args[0].ctx + res = isl.isl_map_eq_at_multi_pw_aff(isl.isl_map_copy(args[0].ptr), isl.isl_multi_pw_aff_copy(args[1].ptr)) + obj = map(ctx=ctx, ptr=res) + return obj + raise Error + def factor_domain(arg0): + try: + if not arg0.__class__ is map: + arg0 = map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_map_factor_domain(isl.isl_map_copy(arg0.ptr)) + obj = map(ctx=ctx, ptr=res) + return obj + def factor_range(arg0): + try: + if not arg0.__class__ is map: + arg0 = map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_map_factor_range(isl.isl_map_copy(arg0.ptr)) + obj = map(ctx=ctx, ptr=res) + return obj + def fixed_power(*args): + if len(args) == 2 and (args[1].__class__ is val or type(args[1]) == int): + args = list(args) + try: + if not args[0].__class__ is map: + args[0] = map(args[0]) + except: + raise + try: + if not args[1].__class__ is val: + args[1] = val(args[1]) + except: + raise + ctx = args[0].ctx + res = isl.isl_map_fixed_power_val(isl.isl_map_copy(args[0].ptr), isl.isl_val_copy(args[1].ptr)) + obj = map(ctx=ctx, ptr=res) + return obj + raise Error + def flatten(arg0): + try: + if not arg0.__class__ is map: + arg0 = map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_map_flatten(isl.isl_map_copy(arg0.ptr)) + obj = map(ctx=ctx, ptr=res) + return obj + def flatten_domain(arg0): + try: + if not arg0.__class__ is map: + arg0 = map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_map_flatten_domain(isl.isl_map_copy(arg0.ptr)) + obj = map(ctx=ctx, ptr=res) + return obj + def flatten_range(arg0): + try: + if not arg0.__class__ is map: + arg0 = map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_map_flatten_range(isl.isl_map_copy(arg0.ptr)) + obj = map(ctx=ctx, ptr=res) + return obj + def foreach_basic_map(arg0, arg1): + try: + if not arg0.__class__ is map: + arg0 = map(arg0) + except: + raise + exc_info = [None] + fn = CFUNCTYPE(c_int, c_void_p, c_void_p) + def cb_func(cb_arg0, cb_arg1): + cb_arg0 = basic_map(ctx=arg0.ctx, ptr=(cb_arg0)) + try: + arg1(cb_arg0) + except BaseException as e: + exc_info[0] = e + return -1 + return 0 + cb1 = fn(cb_func) + ctx = arg0.ctx + res = isl.isl_map_foreach_basic_map(arg0.ptr, cb1, None) + if exc_info[0] is not None: + raise exc_info[0] + if res < 0: + raise Error + def gist(arg0, arg1): + try: + if not arg0.__class__ is map: + arg0 = map(arg0) + except: + raise + try: + if not arg1.__class__ is map: + arg1 = map(arg1) + except: + return union_map(arg0).gist(arg1) + ctx = arg0.ctx + res = isl.isl_map_gist(isl.isl_map_copy(arg0.ptr), isl.isl_map_copy(arg1.ptr)) + obj = map(ctx=ctx, ptr=res) + return obj + def gist_domain(arg0, arg1): + try: + if not arg0.__class__ is map: + arg0 = map(arg0) + except: + raise + try: + if not arg1.__class__ is set: + arg1 = set(arg1) + except: + return union_map(arg0).gist_domain(arg1) + ctx = arg0.ctx + res = isl.isl_map_gist_domain(isl.isl_map_copy(arg0.ptr), isl.isl_set_copy(arg1.ptr)) + obj = map(ctx=ctx, ptr=res) + return obj + def gist_params(arg0, arg1): + try: + if not arg0.__class__ is map: + arg0 = map(arg0) + except: + raise + try: + if not arg1.__class__ is set: + arg1 = set(arg1) + except: + return union_map(arg0).gist_params(arg1) + ctx = arg0.ctx + res = isl.isl_map_gist_params(isl.isl_map_copy(arg0.ptr), isl.isl_set_copy(arg1.ptr)) + obj = map(ctx=ctx, ptr=res) + return obj + def has_domain_tuple_id(arg0): + try: + if not arg0.__class__ is map: + arg0 = map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_map_has_domain_tuple_id(arg0.ptr) + if res < 0: + raise Error + return bool(res) + def has_range_tuple_id(arg0): + try: + if not arg0.__class__ is map: + arg0 = map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_map_has_range_tuple_id(arg0.ptr) + if res < 0: + raise Error + return bool(res) + def intersect(arg0, arg1): + try: + if not arg0.__class__ is map: + arg0 = map(arg0) + except: + raise + try: + if not arg1.__class__ is map: + arg1 = map(arg1) + except: + return union_map(arg0).intersect(arg1) + ctx = arg0.ctx + res = isl.isl_map_intersect(isl.isl_map_copy(arg0.ptr), isl.isl_map_copy(arg1.ptr)) + obj = map(ctx=ctx, ptr=res) + return obj + def intersect_domain(arg0, arg1): + try: + if not arg0.__class__ is map: + arg0 = map(arg0) + except: + raise + try: + if not arg1.__class__ is set: + arg1 = set(arg1) + except: + return union_map(arg0).intersect_domain(arg1) + ctx = arg0.ctx + res = isl.isl_map_intersect_domain(isl.isl_map_copy(arg0.ptr), isl.isl_set_copy(arg1.ptr)) + obj = map(ctx=ctx, ptr=res) + return obj + def intersect_domain_factor_domain(arg0, arg1): + try: + if not arg0.__class__ is map: + arg0 = map(arg0) + except: + raise + try: + if not arg1.__class__ is map: + arg1 = map(arg1) + except: + return union_map(arg0).intersect_domain_factor_domain(arg1) + ctx = arg0.ctx + res = isl.isl_map_intersect_domain_factor_domain(isl.isl_map_copy(arg0.ptr), isl.isl_map_copy(arg1.ptr)) + obj = map(ctx=ctx, ptr=res) + return obj + def intersect_domain_factor_range(arg0, arg1): + try: + if not arg0.__class__ is map: + arg0 = map(arg0) + except: + raise + try: + if not arg1.__class__ is map: + arg1 = map(arg1) + except: + return union_map(arg0).intersect_domain_factor_range(arg1) + ctx = arg0.ctx + res = isl.isl_map_intersect_domain_factor_range(isl.isl_map_copy(arg0.ptr), isl.isl_map_copy(arg1.ptr)) + obj = map(ctx=ctx, ptr=res) + return obj + def intersect_domain_wrapped_domain(arg0, arg1): + try: + if not arg0.__class__ is map: + arg0 = map(arg0) + except: + raise + try: + if not arg1.__class__ is set: + arg1 = set(arg1) + except: + return union_map(arg0).intersect_domain_wrapped_domain(arg1) + ctx = arg0.ctx + res = isl.isl_map_intersect_domain_wrapped_domain(isl.isl_map_copy(arg0.ptr), isl.isl_set_copy(arg1.ptr)) + obj = map(ctx=ctx, ptr=res) + return obj + def intersect_params(arg0, arg1): + try: + if not arg0.__class__ is map: + arg0 = map(arg0) + except: + raise + try: + if not arg1.__class__ is set: + arg1 = set(arg1) + except: + return union_map(arg0).intersect_params(arg1) + ctx = arg0.ctx + res = isl.isl_map_intersect_params(isl.isl_map_copy(arg0.ptr), isl.isl_set_copy(arg1.ptr)) + obj = map(ctx=ctx, ptr=res) + return obj + def intersect_range(arg0, arg1): + try: + if not arg0.__class__ is map: + arg0 = map(arg0) + except: + raise + try: + if not arg1.__class__ is set: + arg1 = set(arg1) + except: + return union_map(arg0).intersect_range(arg1) + ctx = arg0.ctx + res = isl.isl_map_intersect_range(isl.isl_map_copy(arg0.ptr), isl.isl_set_copy(arg1.ptr)) + obj = map(ctx=ctx, ptr=res) + return obj + def intersect_range_factor_domain(arg0, arg1): + try: + if not arg0.__class__ is map: + arg0 = map(arg0) + except: + raise + try: + if not arg1.__class__ is map: + arg1 = map(arg1) + except: + return union_map(arg0).intersect_range_factor_domain(arg1) + ctx = arg0.ctx + res = isl.isl_map_intersect_range_factor_domain(isl.isl_map_copy(arg0.ptr), isl.isl_map_copy(arg1.ptr)) + obj = map(ctx=ctx, ptr=res) + return obj + def intersect_range_factor_range(arg0, arg1): + try: + if not arg0.__class__ is map: + arg0 = map(arg0) + except: + raise + try: + if not arg1.__class__ is map: + arg1 = map(arg1) + except: + return union_map(arg0).intersect_range_factor_range(arg1) + ctx = arg0.ctx + res = isl.isl_map_intersect_range_factor_range(isl.isl_map_copy(arg0.ptr), isl.isl_map_copy(arg1.ptr)) + obj = map(ctx=ctx, ptr=res) + return obj + def intersect_range_wrapped_domain(arg0, arg1): + try: + if not arg0.__class__ is map: + arg0 = map(arg0) + except: + raise + try: + if not arg1.__class__ is set: + arg1 = set(arg1) + except: + return union_map(arg0).intersect_range_wrapped_domain(arg1) + ctx = arg0.ctx + res = isl.isl_map_intersect_range_wrapped_domain(isl.isl_map_copy(arg0.ptr), isl.isl_set_copy(arg1.ptr)) + obj = map(ctx=ctx, ptr=res) + return obj + def is_bijective(arg0): + try: + if not arg0.__class__ is map: + arg0 = map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_map_is_bijective(arg0.ptr) + if res < 0: + raise Error + return bool(res) + def is_disjoint(arg0, arg1): + try: + if not arg0.__class__ is map: + arg0 = map(arg0) + except: + raise + try: + if not arg1.__class__ is map: + arg1 = map(arg1) + except: + return union_map(arg0).is_disjoint(arg1) + ctx = arg0.ctx + res = isl.isl_map_is_disjoint(arg0.ptr, arg1.ptr) + if res < 0: + raise Error + return bool(res) + def is_empty(arg0): + try: + if not arg0.__class__ is map: + arg0 = map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_map_is_empty(arg0.ptr) + if res < 0: + raise Error + return bool(res) + def is_equal(arg0, arg1): + try: + if not arg0.__class__ is map: + arg0 = map(arg0) + except: + raise + try: + if not arg1.__class__ is map: + arg1 = map(arg1) + except: + return union_map(arg0).is_equal(arg1) + ctx = arg0.ctx + res = isl.isl_map_is_equal(arg0.ptr, arg1.ptr) + if res < 0: + raise Error + return bool(res) + def is_injective(arg0): + try: + if not arg0.__class__ is map: + arg0 = map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_map_is_injective(arg0.ptr) + if res < 0: + raise Error + return bool(res) + def is_single_valued(arg0): + try: + if not arg0.__class__ is map: + arg0 = map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_map_is_single_valued(arg0.ptr) + if res < 0: + raise Error + return bool(res) + def is_strict_subset(arg0, arg1): + try: + if not arg0.__class__ is map: + arg0 = map(arg0) + except: + raise + try: + if not arg1.__class__ is map: + arg1 = map(arg1) + except: + return union_map(arg0).is_strict_subset(arg1) + ctx = arg0.ctx + res = isl.isl_map_is_strict_subset(arg0.ptr, arg1.ptr) + if res < 0: + raise Error + return bool(res) + def is_subset(arg0, arg1): + try: + if not arg0.__class__ is map: + arg0 = map(arg0) + except: + raise + try: + if not arg1.__class__ is map: + arg1 = map(arg1) + except: + return union_map(arg0).is_subset(arg1) + ctx = arg0.ctx + res = isl.isl_map_is_subset(arg0.ptr, arg1.ptr) + if res < 0: + raise Error + return bool(res) + def lex_ge_at(*args): + if len(args) == 2 and args[1].__class__ is multi_pw_aff: + args = list(args) + try: + if not args[0].__class__ is map: + args[0] = map(args[0]) + except: + raise + ctx = args[0].ctx + res = isl.isl_map_lex_ge_at_multi_pw_aff(isl.isl_map_copy(args[0].ptr), isl.isl_multi_pw_aff_copy(args[1].ptr)) + obj = map(ctx=ctx, ptr=res) + return obj + raise Error + def lex_gt_at(*args): + if len(args) == 2 and args[1].__class__ is multi_pw_aff: + args = list(args) + try: + if not args[0].__class__ is map: + args[0] = map(args[0]) + except: + raise + ctx = args[0].ctx + res = isl.isl_map_lex_gt_at_multi_pw_aff(isl.isl_map_copy(args[0].ptr), isl.isl_multi_pw_aff_copy(args[1].ptr)) + obj = map(ctx=ctx, ptr=res) + return obj + raise Error + def lex_le_at(*args): + if len(args) == 2 and args[1].__class__ is multi_pw_aff: + args = list(args) + try: + if not args[0].__class__ is map: + args[0] = map(args[0]) + except: + raise + ctx = args[0].ctx + res = isl.isl_map_lex_le_at_multi_pw_aff(isl.isl_map_copy(args[0].ptr), isl.isl_multi_pw_aff_copy(args[1].ptr)) + obj = map(ctx=ctx, ptr=res) + return obj + raise Error + def lex_lt_at(*args): + if len(args) == 2 and args[1].__class__ is multi_pw_aff: + args = list(args) + try: + if not args[0].__class__ is map: + args[0] = map(args[0]) + except: + raise + ctx = args[0].ctx + res = isl.isl_map_lex_lt_at_multi_pw_aff(isl.isl_map_copy(args[0].ptr), isl.isl_multi_pw_aff_copy(args[1].ptr)) + obj = map(ctx=ctx, ptr=res) + return obj + raise Error + def lexmax(arg0): + try: + if not arg0.__class__ is map: + arg0 = map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_map_lexmax(isl.isl_map_copy(arg0.ptr)) + obj = map(ctx=ctx, ptr=res) + return obj + def lexmax_pw_multi_aff(arg0): + try: + if not arg0.__class__ is map: + arg0 = map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_map_lexmax_pw_multi_aff(isl.isl_map_copy(arg0.ptr)) + obj = pw_multi_aff(ctx=ctx, ptr=res) + return obj + def lexmin(arg0): + try: + if not arg0.__class__ is map: + arg0 = map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_map_lexmin(isl.isl_map_copy(arg0.ptr)) + obj = map(ctx=ctx, ptr=res) + return obj + def lexmin_pw_multi_aff(arg0): + try: + if not arg0.__class__ is map: + arg0 = map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_map_lexmin_pw_multi_aff(isl.isl_map_copy(arg0.ptr)) + obj = pw_multi_aff(ctx=ctx, ptr=res) + return obj + def lower_bound(*args): + if len(args) == 2 and args[1].__class__ is multi_pw_aff: + args = list(args) + try: + if not args[0].__class__ is map: + args[0] = map(args[0]) + except: + raise + ctx = args[0].ctx + res = isl.isl_map_lower_bound_multi_pw_aff(isl.isl_map_copy(args[0].ptr), isl.isl_multi_pw_aff_copy(args[1].ptr)) + obj = map(ctx=ctx, ptr=res) + return obj + raise Error + def max_multi_pw_aff(arg0): + try: + if not arg0.__class__ is map: + arg0 = map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_map_max_multi_pw_aff(isl.isl_map_copy(arg0.ptr)) + obj = multi_pw_aff(ctx=ctx, ptr=res) + return obj + def min_multi_pw_aff(arg0): + try: + if not arg0.__class__ is map: + arg0 = map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_map_min_multi_pw_aff(isl.isl_map_copy(arg0.ptr)) + obj = multi_pw_aff(ctx=ctx, ptr=res) + return obj + def n_basic_map(arg0): + try: + if not arg0.__class__ is map: + arg0 = map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_map_n_basic_map(arg0.ptr) + if res < 0: + raise Error + return int(res) + def params(arg0): + try: + if not arg0.__class__ is map: + arg0 = map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_map_params(isl.isl_map_copy(arg0.ptr)) + obj = set(ctx=ctx, ptr=res) + return obj + def polyhedral_hull(arg0): + try: + if not arg0.__class__ is map: + arg0 = map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_map_polyhedral_hull(isl.isl_map_copy(arg0.ptr)) + obj = basic_map(ctx=ctx, ptr=res) + return obj + def preimage_domain(*args): + if len(args) == 2 and args[1].__class__ is multi_aff: + args = list(args) + try: + if not args[0].__class__ is map: + args[0] = map(args[0]) + except: + raise + ctx = args[0].ctx + res = isl.isl_map_preimage_domain_multi_aff(isl.isl_map_copy(args[0].ptr), isl.isl_multi_aff_copy(args[1].ptr)) + obj = map(ctx=ctx, ptr=res) + return obj + if len(args) == 2 and args[1].__class__ is multi_pw_aff: + args = list(args) + try: + if not args[0].__class__ is map: + args[0] = map(args[0]) + except: + raise + ctx = args[0].ctx + res = isl.isl_map_preimage_domain_multi_pw_aff(isl.isl_map_copy(args[0].ptr), isl.isl_multi_pw_aff_copy(args[1].ptr)) + obj = map(ctx=ctx, ptr=res) + return obj + if len(args) == 2 and args[1].__class__ is pw_multi_aff: + args = list(args) + try: + if not args[0].__class__ is map: + args[0] = map(args[0]) + except: + raise + ctx = args[0].ctx + res = isl.isl_map_preimage_domain_pw_multi_aff(isl.isl_map_copy(args[0].ptr), isl.isl_pw_multi_aff_copy(args[1].ptr)) + obj = map(ctx=ctx, ptr=res) + return obj + raise Error + def preimage_range(*args): + if len(args) == 2 and args[1].__class__ is multi_aff: + args = list(args) + try: + if not args[0].__class__ is map: + args[0] = map(args[0]) + except: + raise + ctx = args[0].ctx + res = isl.isl_map_preimage_range_multi_aff(isl.isl_map_copy(args[0].ptr), isl.isl_multi_aff_copy(args[1].ptr)) + obj = map(ctx=ctx, ptr=res) + return obj + if len(args) == 2 and args[1].__class__ is pw_multi_aff: + args = list(args) + try: + if not args[0].__class__ is map: + args[0] = map(args[0]) + except: + raise + ctx = args[0].ctx + res = isl.isl_map_preimage_range_pw_multi_aff(isl.isl_map_copy(args[0].ptr), isl.isl_pw_multi_aff_copy(args[1].ptr)) + obj = map(ctx=ctx, ptr=res) + return obj + raise Error + def product(arg0, arg1): + try: + if not arg0.__class__ is map: + arg0 = map(arg0) + except: + raise + try: + if not arg1.__class__ is map: + arg1 = map(arg1) + except: + return union_map(arg0).product(arg1) + ctx = arg0.ctx + res = isl.isl_map_product(isl.isl_map_copy(arg0.ptr), isl.isl_map_copy(arg1.ptr)) + obj = map(ctx=ctx, ptr=res) + return obj + def project_out_all_params(arg0): + try: + if not arg0.__class__ is map: + arg0 = map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_map_project_out_all_params(isl.isl_map_copy(arg0.ptr)) + obj = map(ctx=ctx, ptr=res) + return obj + def project_out_param(*args): + if len(args) == 2 and (args[1].__class__ is id or type(args[1]) == str): + args = list(args) + try: + if not args[0].__class__ is map: + args[0] = map(args[0]) + except: + raise + try: + if not args[1].__class__ is id: + args[1] = id(args[1]) + except: + raise + ctx = args[0].ctx + res = isl.isl_map_project_out_param_id(isl.isl_map_copy(args[0].ptr), isl.isl_id_copy(args[1].ptr)) + obj = map(ctx=ctx, ptr=res) + return obj + if len(args) == 2 and args[1].__class__ is id_list: + args = list(args) + try: + if not args[0].__class__ is map: + args[0] = map(args[0]) + except: + raise + ctx = args[0].ctx + res = isl.isl_map_project_out_param_id_list(isl.isl_map_copy(args[0].ptr), isl.isl_id_list_copy(args[1].ptr)) + obj = map(ctx=ctx, ptr=res) + return obj + raise Error + def range(arg0): + try: + if not arg0.__class__ is map: + arg0 = map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_map_range(isl.isl_map_copy(arg0.ptr)) + obj = set(ctx=ctx, ptr=res) + return obj + def range_factor_domain(arg0): + try: + if not arg0.__class__ is map: + arg0 = map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_map_range_factor_domain(isl.isl_map_copy(arg0.ptr)) + obj = map(ctx=ctx, ptr=res) + return obj + def range_factor_range(arg0): + try: + if not arg0.__class__ is map: + arg0 = map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_map_range_factor_range(isl.isl_map_copy(arg0.ptr)) + obj = map(ctx=ctx, ptr=res) + return obj + def range_lattice_tile(arg0): + try: + if not arg0.__class__ is map: + arg0 = map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_map_get_range_lattice_tile(arg0.ptr) + obj = fixed_box(ctx=ctx, ptr=res) + return obj + def get_range_lattice_tile(arg0): + return arg0.range_lattice_tile() + def range_product(arg0, arg1): + try: + if not arg0.__class__ is map: + arg0 = map(arg0) + except: + raise + try: + if not arg1.__class__ is map: + arg1 = map(arg1) + except: + return union_map(arg0).range_product(arg1) + ctx = arg0.ctx + res = isl.isl_map_range_product(isl.isl_map_copy(arg0.ptr), isl.isl_map_copy(arg1.ptr)) + obj = map(ctx=ctx, ptr=res) + return obj + def range_reverse(arg0): + try: + if not arg0.__class__ is map: + arg0 = map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_map_range_reverse(isl.isl_map_copy(arg0.ptr)) + obj = map(ctx=ctx, ptr=res) + return obj + def range_simple_fixed_box_hull(arg0): + try: + if not arg0.__class__ is map: + arg0 = map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_map_get_range_simple_fixed_box_hull(arg0.ptr) + obj = fixed_box(ctx=ctx, ptr=res) + return obj + def get_range_simple_fixed_box_hull(arg0): + return arg0.range_simple_fixed_box_hull() + def range_tuple_dim(arg0): + try: + if not arg0.__class__ is map: + arg0 = map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_map_range_tuple_dim(arg0.ptr) + if res < 0: + raise Error + return int(res) + def range_tuple_id(arg0): + try: + if not arg0.__class__ is map: + arg0 = map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_map_get_range_tuple_id(arg0.ptr) + obj = id(ctx=ctx, ptr=res) + return obj + def get_range_tuple_id(arg0): + return arg0.range_tuple_id() + def reverse(arg0): + try: + if not arg0.__class__ is map: + arg0 = map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_map_reverse(isl.isl_map_copy(arg0.ptr)) + obj = map(ctx=ctx, ptr=res) + return obj + def sample(arg0): + try: + if not arg0.__class__ is map: + arg0 = map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_map_sample(isl.isl_map_copy(arg0.ptr)) + obj = basic_map(ctx=ctx, ptr=res) + return obj + def set_domain_tuple(*args): + if len(args) == 2 and (args[1].__class__ is id or type(args[1]) == str): + args = list(args) + try: + if not args[0].__class__ is map: + args[0] = map(args[0]) + except: + raise + try: + if not args[1].__class__ is id: + args[1] = id(args[1]) + except: + raise + ctx = args[0].ctx + res = isl.isl_map_set_domain_tuple_id(isl.isl_map_copy(args[0].ptr), isl.isl_id_copy(args[1].ptr)) + obj = map(ctx=ctx, ptr=res) + return obj + raise Error + def set_range_tuple(*args): + if len(args) == 2 and (args[1].__class__ is id or type(args[1]) == str): + args = list(args) + try: + if not args[0].__class__ is map: + args[0] = map(args[0]) + except: + raise + try: + if not args[1].__class__ is id: + args[1] = id(args[1]) + except: + raise + ctx = args[0].ctx + res = isl.isl_map_set_range_tuple_id(isl.isl_map_copy(args[0].ptr), isl.isl_id_copy(args[1].ptr)) + obj = map(ctx=ctx, ptr=res) + return obj + raise Error + def space(arg0): + try: + if not arg0.__class__ is map: + arg0 = map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_map_get_space(arg0.ptr) + obj = space(ctx=ctx, ptr=res) + return obj + def get_space(arg0): + return arg0.space() + def subtract(arg0, arg1): + try: + if not arg0.__class__ is map: + arg0 = map(arg0) + except: + raise + try: + if not arg1.__class__ is map: + arg1 = map(arg1) + except: + return union_map(arg0).subtract(arg1) + ctx = arg0.ctx + res = isl.isl_map_subtract(isl.isl_map_copy(arg0.ptr), isl.isl_map_copy(arg1.ptr)) + obj = map(ctx=ctx, ptr=res) + return obj + def to_list(arg0): + try: + if not arg0.__class__ is map: + arg0 = map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_map_to_list(isl.isl_map_copy(arg0.ptr)) + obj = map_list(ctx=ctx, ptr=res) + return obj + def to_union_map(arg0): + try: + if not arg0.__class__ is map: + arg0 = map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_map_to_union_map(isl.isl_map_copy(arg0.ptr)) + obj = union_map(ctx=ctx, ptr=res) + return obj + def uncurry(arg0): + try: + if not arg0.__class__ is map: + arg0 = map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_map_uncurry(isl.isl_map_copy(arg0.ptr)) + obj = map(ctx=ctx, ptr=res) + return obj + def union(arg0, arg1): + try: + if not arg0.__class__ is map: + arg0 = map(arg0) + except: + raise + try: + if not arg1.__class__ is map: + arg1 = map(arg1) + except: + return union_map(arg0).union(arg1) + ctx = arg0.ctx + res = isl.isl_map_union(isl.isl_map_copy(arg0.ptr), isl.isl_map_copy(arg1.ptr)) + obj = map(ctx=ctx, ptr=res) + return obj + @staticmethod + def universe(arg0): + try: + if not arg0.__class__ is space: + arg0 = space(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_map_universe(isl.isl_space_copy(arg0.ptr)) + obj = map(ctx=ctx, ptr=res) + return obj + def unshifted_simple_hull(arg0): + try: + if not arg0.__class__ is map: + arg0 = map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_map_unshifted_simple_hull(isl.isl_map_copy(arg0.ptr)) + obj = basic_map(ctx=ctx, ptr=res) + return obj + def upper_bound(*args): + if len(args) == 2 and args[1].__class__ is multi_pw_aff: + args = list(args) + try: + if not args[0].__class__ is map: + args[0] = map(args[0]) + except: + raise + ctx = args[0].ctx + res = isl.isl_map_upper_bound_multi_pw_aff(isl.isl_map_copy(args[0].ptr), isl.isl_multi_pw_aff_copy(args[1].ptr)) + obj = map(ctx=ctx, ptr=res) + return obj + raise Error + def wrap(arg0): + try: + if not arg0.__class__ is map: + arg0 = map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_map_wrap(isl.isl_map_copy(arg0.ptr)) + obj = set(ctx=ctx, ptr=res) + return obj + def zip(arg0): + try: + if not arg0.__class__ is map: + arg0 = map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_map_zip(isl.isl_map_copy(arg0.ptr)) + obj = map(ctx=ctx, ptr=res) + return obj + +isl.isl_map_from_basic_map.restype = c_void_p +isl.isl_map_from_basic_map.argtypes = [c_void_p] +isl.isl_map_read_from_str.restype = c_void_p +isl.isl_map_read_from_str.argtypes = [Context, c_char_p] +isl.isl_map_affine_hull.restype = c_void_p +isl.isl_map_affine_hull.argtypes = [c_void_p] +isl.isl_map_apply_domain.restype = c_void_p +isl.isl_map_apply_domain.argtypes = [c_void_p, c_void_p] +isl.isl_map_apply_range.restype = c_void_p +isl.isl_map_apply_range.argtypes = [c_void_p, c_void_p] +isl.isl_map_as_pw_multi_aff.restype = c_void_p +isl.isl_map_as_pw_multi_aff.argtypes = [c_void_p] +isl.isl_map_bind_domain.restype = c_void_p +isl.isl_map_bind_domain.argtypes = [c_void_p, c_void_p] +isl.isl_map_bind_range.restype = c_void_p +isl.isl_map_bind_range.argtypes = [c_void_p, c_void_p] +isl.isl_map_coalesce.restype = c_void_p +isl.isl_map_coalesce.argtypes = [c_void_p] +isl.isl_map_complement.restype = c_void_p +isl.isl_map_complement.argtypes = [c_void_p] +isl.isl_map_curry.restype = c_void_p +isl.isl_map_curry.argtypes = [c_void_p] +isl.isl_map_deltas.restype = c_void_p +isl.isl_map_deltas.argtypes = [c_void_p] +isl.isl_map_detect_equalities.restype = c_void_p +isl.isl_map_detect_equalities.argtypes = [c_void_p] +isl.isl_map_domain.restype = c_void_p +isl.isl_map_domain.argtypes = [c_void_p] +isl.isl_map_domain_factor_domain.restype = c_void_p +isl.isl_map_domain_factor_domain.argtypes = [c_void_p] +isl.isl_map_domain_factor_range.restype = c_void_p +isl.isl_map_domain_factor_range.argtypes = [c_void_p] +isl.isl_map_domain_product.restype = c_void_p +isl.isl_map_domain_product.argtypes = [c_void_p, c_void_p] +isl.isl_map_domain_reverse.restype = c_void_p +isl.isl_map_domain_reverse.argtypes = [c_void_p] +isl.isl_map_domain_tuple_dim.argtypes = [c_void_p] +isl.isl_map_get_domain_tuple_id.restype = c_void_p +isl.isl_map_get_domain_tuple_id.argtypes = [c_void_p] +isl.isl_map_drop_unused_params.restype = c_void_p +isl.isl_map_drop_unused_params.argtypes = [c_void_p] +isl.isl_map_empty.restype = c_void_p +isl.isl_map_empty.argtypes = [c_void_p] +isl.isl_map_eq_at_multi_pw_aff.restype = c_void_p +isl.isl_map_eq_at_multi_pw_aff.argtypes = [c_void_p, c_void_p] +isl.isl_map_factor_domain.restype = c_void_p +isl.isl_map_factor_domain.argtypes = [c_void_p] +isl.isl_map_factor_range.restype = c_void_p +isl.isl_map_factor_range.argtypes = [c_void_p] +isl.isl_map_fixed_power_val.restype = c_void_p +isl.isl_map_fixed_power_val.argtypes = [c_void_p, c_void_p] +isl.isl_map_flatten.restype = c_void_p +isl.isl_map_flatten.argtypes = [c_void_p] +isl.isl_map_flatten_domain.restype = c_void_p +isl.isl_map_flatten_domain.argtypes = [c_void_p] +isl.isl_map_flatten_range.restype = c_void_p +isl.isl_map_flatten_range.argtypes = [c_void_p] +isl.isl_map_foreach_basic_map.argtypes = [c_void_p, c_void_p, c_void_p] +isl.isl_map_gist.restype = c_void_p +isl.isl_map_gist.argtypes = [c_void_p, c_void_p] +isl.isl_map_gist_domain.restype = c_void_p +isl.isl_map_gist_domain.argtypes = [c_void_p, c_void_p] +isl.isl_map_gist_params.restype = c_void_p +isl.isl_map_gist_params.argtypes = [c_void_p, c_void_p] +isl.isl_map_has_domain_tuple_id.argtypes = [c_void_p] +isl.isl_map_has_range_tuple_id.argtypes = [c_void_p] +isl.isl_map_intersect.restype = c_void_p +isl.isl_map_intersect.argtypes = [c_void_p, c_void_p] +isl.isl_map_intersect_domain.restype = c_void_p +isl.isl_map_intersect_domain.argtypes = [c_void_p, c_void_p] +isl.isl_map_intersect_domain_factor_domain.restype = c_void_p +isl.isl_map_intersect_domain_factor_domain.argtypes = [c_void_p, c_void_p] +isl.isl_map_intersect_domain_factor_range.restype = c_void_p +isl.isl_map_intersect_domain_factor_range.argtypes = [c_void_p, c_void_p] +isl.isl_map_intersect_domain_wrapped_domain.restype = c_void_p +isl.isl_map_intersect_domain_wrapped_domain.argtypes = [c_void_p, c_void_p] +isl.isl_map_intersect_params.restype = c_void_p +isl.isl_map_intersect_params.argtypes = [c_void_p, c_void_p] +isl.isl_map_intersect_range.restype = c_void_p +isl.isl_map_intersect_range.argtypes = [c_void_p, c_void_p] +isl.isl_map_intersect_range_factor_domain.restype = c_void_p +isl.isl_map_intersect_range_factor_domain.argtypes = [c_void_p, c_void_p] +isl.isl_map_intersect_range_factor_range.restype = c_void_p +isl.isl_map_intersect_range_factor_range.argtypes = [c_void_p, c_void_p] +isl.isl_map_intersect_range_wrapped_domain.restype = c_void_p +isl.isl_map_intersect_range_wrapped_domain.argtypes = [c_void_p, c_void_p] +isl.isl_map_is_bijective.argtypes = [c_void_p] +isl.isl_map_is_disjoint.argtypes = [c_void_p, c_void_p] +isl.isl_map_is_empty.argtypes = [c_void_p] +isl.isl_map_is_equal.argtypes = [c_void_p, c_void_p] +isl.isl_map_is_injective.argtypes = [c_void_p] +isl.isl_map_is_single_valued.argtypes = [c_void_p] +isl.isl_map_is_strict_subset.argtypes = [c_void_p, c_void_p] +isl.isl_map_is_subset.argtypes = [c_void_p, c_void_p] +isl.isl_map_lex_ge_at_multi_pw_aff.restype = c_void_p +isl.isl_map_lex_ge_at_multi_pw_aff.argtypes = [c_void_p, c_void_p] +isl.isl_map_lex_gt_at_multi_pw_aff.restype = c_void_p +isl.isl_map_lex_gt_at_multi_pw_aff.argtypes = [c_void_p, c_void_p] +isl.isl_map_lex_le_at_multi_pw_aff.restype = c_void_p +isl.isl_map_lex_le_at_multi_pw_aff.argtypes = [c_void_p, c_void_p] +isl.isl_map_lex_lt_at_multi_pw_aff.restype = c_void_p +isl.isl_map_lex_lt_at_multi_pw_aff.argtypes = [c_void_p, c_void_p] +isl.isl_map_lexmax.restype = c_void_p +isl.isl_map_lexmax.argtypes = [c_void_p] +isl.isl_map_lexmax_pw_multi_aff.restype = c_void_p +isl.isl_map_lexmax_pw_multi_aff.argtypes = [c_void_p] +isl.isl_map_lexmin.restype = c_void_p +isl.isl_map_lexmin.argtypes = [c_void_p] +isl.isl_map_lexmin_pw_multi_aff.restype = c_void_p +isl.isl_map_lexmin_pw_multi_aff.argtypes = [c_void_p] +isl.isl_map_lower_bound_multi_pw_aff.restype = c_void_p +isl.isl_map_lower_bound_multi_pw_aff.argtypes = [c_void_p, c_void_p] +isl.isl_map_max_multi_pw_aff.restype = c_void_p +isl.isl_map_max_multi_pw_aff.argtypes = [c_void_p] +isl.isl_map_min_multi_pw_aff.restype = c_void_p +isl.isl_map_min_multi_pw_aff.argtypes = [c_void_p] +isl.isl_map_n_basic_map.argtypes = [c_void_p] +isl.isl_map_params.restype = c_void_p +isl.isl_map_params.argtypes = [c_void_p] +isl.isl_map_polyhedral_hull.restype = c_void_p +isl.isl_map_polyhedral_hull.argtypes = [c_void_p] +isl.isl_map_preimage_domain_multi_aff.restype = c_void_p +isl.isl_map_preimage_domain_multi_aff.argtypes = [c_void_p, c_void_p] +isl.isl_map_preimage_domain_multi_pw_aff.restype = c_void_p +isl.isl_map_preimage_domain_multi_pw_aff.argtypes = [c_void_p, c_void_p] +isl.isl_map_preimage_domain_pw_multi_aff.restype = c_void_p +isl.isl_map_preimage_domain_pw_multi_aff.argtypes = [c_void_p, c_void_p] +isl.isl_map_preimage_range_multi_aff.restype = c_void_p +isl.isl_map_preimage_range_multi_aff.argtypes = [c_void_p, c_void_p] +isl.isl_map_preimage_range_pw_multi_aff.restype = c_void_p +isl.isl_map_preimage_range_pw_multi_aff.argtypes = [c_void_p, c_void_p] +isl.isl_map_product.restype = c_void_p +isl.isl_map_product.argtypes = [c_void_p, c_void_p] +isl.isl_map_project_out_all_params.restype = c_void_p +isl.isl_map_project_out_all_params.argtypes = [c_void_p] +isl.isl_map_project_out_param_id.restype = c_void_p +isl.isl_map_project_out_param_id.argtypes = [c_void_p, c_void_p] +isl.isl_map_project_out_param_id_list.restype = c_void_p +isl.isl_map_project_out_param_id_list.argtypes = [c_void_p, c_void_p] +isl.isl_map_range.restype = c_void_p +isl.isl_map_range.argtypes = [c_void_p] +isl.isl_map_range_factor_domain.restype = c_void_p +isl.isl_map_range_factor_domain.argtypes = [c_void_p] +isl.isl_map_range_factor_range.restype = c_void_p +isl.isl_map_range_factor_range.argtypes = [c_void_p] +isl.isl_map_get_range_lattice_tile.restype = c_void_p +isl.isl_map_get_range_lattice_tile.argtypes = [c_void_p] +isl.isl_map_range_product.restype = c_void_p +isl.isl_map_range_product.argtypes = [c_void_p, c_void_p] +isl.isl_map_range_reverse.restype = c_void_p +isl.isl_map_range_reverse.argtypes = [c_void_p] +isl.isl_map_get_range_simple_fixed_box_hull.restype = c_void_p +isl.isl_map_get_range_simple_fixed_box_hull.argtypes = [c_void_p] +isl.isl_map_range_tuple_dim.argtypes = [c_void_p] +isl.isl_map_get_range_tuple_id.restype = c_void_p +isl.isl_map_get_range_tuple_id.argtypes = [c_void_p] +isl.isl_map_reverse.restype = c_void_p +isl.isl_map_reverse.argtypes = [c_void_p] +isl.isl_map_sample.restype = c_void_p +isl.isl_map_sample.argtypes = [c_void_p] +isl.isl_map_set_domain_tuple_id.restype = c_void_p +isl.isl_map_set_domain_tuple_id.argtypes = [c_void_p, c_void_p] +isl.isl_map_set_range_tuple_id.restype = c_void_p +isl.isl_map_set_range_tuple_id.argtypes = [c_void_p, c_void_p] +isl.isl_map_get_space.restype = c_void_p +isl.isl_map_get_space.argtypes = [c_void_p] +isl.isl_map_subtract.restype = c_void_p +isl.isl_map_subtract.argtypes = [c_void_p, c_void_p] +isl.isl_map_to_list.restype = c_void_p +isl.isl_map_to_list.argtypes = [c_void_p] +isl.isl_map_to_union_map.restype = c_void_p +isl.isl_map_to_union_map.argtypes = [c_void_p] +isl.isl_map_uncurry.restype = c_void_p +isl.isl_map_uncurry.argtypes = [c_void_p] +isl.isl_map_union.restype = c_void_p +isl.isl_map_union.argtypes = [c_void_p, c_void_p] +isl.isl_map_universe.restype = c_void_p +isl.isl_map_universe.argtypes = [c_void_p] +isl.isl_map_unshifted_simple_hull.restype = c_void_p +isl.isl_map_unshifted_simple_hull.argtypes = [c_void_p] +isl.isl_map_upper_bound_multi_pw_aff.restype = c_void_p +isl.isl_map_upper_bound_multi_pw_aff.argtypes = [c_void_p, c_void_p] +isl.isl_map_wrap.restype = c_void_p +isl.isl_map_wrap.argtypes = [c_void_p] +isl.isl_map_zip.restype = c_void_p +isl.isl_map_zip.argtypes = [c_void_p] +isl.isl_map_copy.restype = c_void_p +isl.isl_map_copy.argtypes = [c_void_p] +isl.isl_map_free.restype = c_void_p +isl.isl_map_free.argtypes = [c_void_p] +isl.isl_map_to_str.restype = POINTER(c_char) +isl.isl_map_to_str.argtypes = [c_void_p] + +class basic_map(map): + def __init__(self, *args, **keywords): + if "ptr" in keywords: + self.ctx = keywords["ctx"] + self.ptr = keywords["ptr"] + return + if len(args) == 1 and type(args[0]) == str: + self.ctx = Context.getDefaultInstance() + self.ptr = isl.isl_basic_map_read_from_str(self.ctx, args[0].encode('ascii')) + return + raise Error + def __del__(self): + if hasattr(self, 'ptr'): + isl.isl_basic_map_free(self.ptr) + def __str__(arg0): + try: + if not arg0.__class__ is basic_map: + arg0 = basic_map(arg0) + except: + raise + ptr = isl.isl_basic_map_to_str(arg0.ptr) + res = cast(ptr, c_char_p).value.decode('ascii') + libc.free(ptr) + return res + def __repr__(self): + s = str(self) + if '"' in s: + return 'isl.basic_map("""%s""")' % s + else: + return 'isl.basic_map("%s")' % s + def affine_hull(arg0): + try: + if not arg0.__class__ is basic_map: + arg0 = basic_map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_basic_map_affine_hull(isl.isl_basic_map_copy(arg0.ptr)) + obj = basic_map(ctx=ctx, ptr=res) + return obj + def apply_domain(arg0, arg1): + try: + if not arg0.__class__ is basic_map: + arg0 = basic_map(arg0) + except: + raise + try: + if not arg1.__class__ is basic_map: + arg1 = basic_map(arg1) + except: + return map(arg0).apply_domain(arg1) + ctx = arg0.ctx + res = isl.isl_basic_map_apply_domain(isl.isl_basic_map_copy(arg0.ptr), isl.isl_basic_map_copy(arg1.ptr)) + obj = basic_map(ctx=ctx, ptr=res) + return obj + def apply_range(arg0, arg1): + try: + if not arg0.__class__ is basic_map: + arg0 = basic_map(arg0) + except: + raise + try: + if not arg1.__class__ is basic_map: + arg1 = basic_map(arg1) + except: + return map(arg0).apply_range(arg1) + ctx = arg0.ctx + res = isl.isl_basic_map_apply_range(isl.isl_basic_map_copy(arg0.ptr), isl.isl_basic_map_copy(arg1.ptr)) + obj = basic_map(ctx=ctx, ptr=res) + return obj + def deltas(arg0): + try: + if not arg0.__class__ is basic_map: + arg0 = basic_map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_basic_map_deltas(isl.isl_basic_map_copy(arg0.ptr)) + obj = basic_set(ctx=ctx, ptr=res) + return obj + def detect_equalities(arg0): + try: + if not arg0.__class__ is basic_map: + arg0 = basic_map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_basic_map_detect_equalities(isl.isl_basic_map_copy(arg0.ptr)) + obj = basic_map(ctx=ctx, ptr=res) + return obj + def flatten(arg0): + try: + if not arg0.__class__ is basic_map: + arg0 = basic_map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_basic_map_flatten(isl.isl_basic_map_copy(arg0.ptr)) + obj = basic_map(ctx=ctx, ptr=res) + return obj + def flatten_domain(arg0): + try: + if not arg0.__class__ is basic_map: + arg0 = basic_map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_basic_map_flatten_domain(isl.isl_basic_map_copy(arg0.ptr)) + obj = basic_map(ctx=ctx, ptr=res) + return obj + def flatten_range(arg0): + try: + if not arg0.__class__ is basic_map: + arg0 = basic_map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_basic_map_flatten_range(isl.isl_basic_map_copy(arg0.ptr)) + obj = basic_map(ctx=ctx, ptr=res) + return obj + def gist(arg0, arg1): + try: + if not arg0.__class__ is basic_map: + arg0 = basic_map(arg0) + except: + raise + try: + if not arg1.__class__ is basic_map: + arg1 = basic_map(arg1) + except: + return map(arg0).gist(arg1) + ctx = arg0.ctx + res = isl.isl_basic_map_gist(isl.isl_basic_map_copy(arg0.ptr), isl.isl_basic_map_copy(arg1.ptr)) + obj = basic_map(ctx=ctx, ptr=res) + return obj + def intersect(arg0, arg1): + try: + if not arg0.__class__ is basic_map: + arg0 = basic_map(arg0) + except: + raise + try: + if not arg1.__class__ is basic_map: + arg1 = basic_map(arg1) + except: + return map(arg0).intersect(arg1) + ctx = arg0.ctx + res = isl.isl_basic_map_intersect(isl.isl_basic_map_copy(arg0.ptr), isl.isl_basic_map_copy(arg1.ptr)) + obj = basic_map(ctx=ctx, ptr=res) + return obj + def intersect_domain(arg0, arg1): + try: + if not arg0.__class__ is basic_map: + arg0 = basic_map(arg0) + except: + raise + try: + if not arg1.__class__ is basic_set: + arg1 = basic_set(arg1) + except: + return map(arg0).intersect_domain(arg1) + ctx = arg0.ctx + res = isl.isl_basic_map_intersect_domain(isl.isl_basic_map_copy(arg0.ptr), isl.isl_basic_set_copy(arg1.ptr)) + obj = basic_map(ctx=ctx, ptr=res) + return obj + def intersect_range(arg0, arg1): + try: + if not arg0.__class__ is basic_map: + arg0 = basic_map(arg0) + except: + raise + try: + if not arg1.__class__ is basic_set: + arg1 = basic_set(arg1) + except: + return map(arg0).intersect_range(arg1) + ctx = arg0.ctx + res = isl.isl_basic_map_intersect_range(isl.isl_basic_map_copy(arg0.ptr), isl.isl_basic_set_copy(arg1.ptr)) + obj = basic_map(ctx=ctx, ptr=res) + return obj + def is_empty(arg0): + try: + if not arg0.__class__ is basic_map: + arg0 = basic_map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_basic_map_is_empty(arg0.ptr) + if res < 0: + raise Error + return bool(res) + def is_equal(arg0, arg1): + try: + if not arg0.__class__ is basic_map: + arg0 = basic_map(arg0) + except: + raise + try: + if not arg1.__class__ is basic_map: + arg1 = basic_map(arg1) + except: + return map(arg0).is_equal(arg1) + ctx = arg0.ctx + res = isl.isl_basic_map_is_equal(arg0.ptr, arg1.ptr) + if res < 0: + raise Error + return bool(res) + def is_subset(arg0, arg1): + try: + if not arg0.__class__ is basic_map: + arg0 = basic_map(arg0) + except: + raise + try: + if not arg1.__class__ is basic_map: + arg1 = basic_map(arg1) + except: + return map(arg0).is_subset(arg1) + ctx = arg0.ctx + res = isl.isl_basic_map_is_subset(arg0.ptr, arg1.ptr) + if res < 0: + raise Error + return bool(res) + def lexmax(arg0): + try: + if not arg0.__class__ is basic_map: + arg0 = basic_map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_basic_map_lexmax(isl.isl_basic_map_copy(arg0.ptr)) + obj = map(ctx=ctx, ptr=res) + return obj + def lexmin(arg0): + try: + if not arg0.__class__ is basic_map: + arg0 = basic_map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_basic_map_lexmin(isl.isl_basic_map_copy(arg0.ptr)) + obj = map(ctx=ctx, ptr=res) + return obj + def reverse(arg0): + try: + if not arg0.__class__ is basic_map: + arg0 = basic_map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_basic_map_reverse(isl.isl_basic_map_copy(arg0.ptr)) + obj = basic_map(ctx=ctx, ptr=res) + return obj + def sample(arg0): + try: + if not arg0.__class__ is basic_map: + arg0 = basic_map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_basic_map_sample(isl.isl_basic_map_copy(arg0.ptr)) + obj = basic_map(ctx=ctx, ptr=res) + return obj + def union(arg0, arg1): + try: + if not arg0.__class__ is basic_map: + arg0 = basic_map(arg0) + except: + raise + try: + if not arg1.__class__ is basic_map: + arg1 = basic_map(arg1) + except: + return map(arg0).union(arg1) + ctx = arg0.ctx + res = isl.isl_basic_map_union(isl.isl_basic_map_copy(arg0.ptr), isl.isl_basic_map_copy(arg1.ptr)) + obj = map(ctx=ctx, ptr=res) + return obj + +isl.isl_basic_map_read_from_str.restype = c_void_p +isl.isl_basic_map_read_from_str.argtypes = [Context, c_char_p] +isl.isl_basic_map_affine_hull.restype = c_void_p +isl.isl_basic_map_affine_hull.argtypes = [c_void_p] +isl.isl_basic_map_apply_domain.restype = c_void_p +isl.isl_basic_map_apply_domain.argtypes = [c_void_p, c_void_p] +isl.isl_basic_map_apply_range.restype = c_void_p +isl.isl_basic_map_apply_range.argtypes = [c_void_p, c_void_p] +isl.isl_basic_map_deltas.restype = c_void_p +isl.isl_basic_map_deltas.argtypes = [c_void_p] +isl.isl_basic_map_detect_equalities.restype = c_void_p +isl.isl_basic_map_detect_equalities.argtypes = [c_void_p] +isl.isl_basic_map_flatten.restype = c_void_p +isl.isl_basic_map_flatten.argtypes = [c_void_p] +isl.isl_basic_map_flatten_domain.restype = c_void_p +isl.isl_basic_map_flatten_domain.argtypes = [c_void_p] +isl.isl_basic_map_flatten_range.restype = c_void_p +isl.isl_basic_map_flatten_range.argtypes = [c_void_p] +isl.isl_basic_map_gist.restype = c_void_p +isl.isl_basic_map_gist.argtypes = [c_void_p, c_void_p] +isl.isl_basic_map_intersect.restype = c_void_p +isl.isl_basic_map_intersect.argtypes = [c_void_p, c_void_p] +isl.isl_basic_map_intersect_domain.restype = c_void_p +isl.isl_basic_map_intersect_domain.argtypes = [c_void_p, c_void_p] +isl.isl_basic_map_intersect_range.restype = c_void_p +isl.isl_basic_map_intersect_range.argtypes = [c_void_p, c_void_p] +isl.isl_basic_map_is_empty.argtypes = [c_void_p] +isl.isl_basic_map_is_equal.argtypes = [c_void_p, c_void_p] +isl.isl_basic_map_is_subset.argtypes = [c_void_p, c_void_p] +isl.isl_basic_map_lexmax.restype = c_void_p +isl.isl_basic_map_lexmax.argtypes = [c_void_p] +isl.isl_basic_map_lexmin.restype = c_void_p +isl.isl_basic_map_lexmin.argtypes = [c_void_p] +isl.isl_basic_map_reverse.restype = c_void_p +isl.isl_basic_map_reverse.argtypes = [c_void_p] +isl.isl_basic_map_sample.restype = c_void_p +isl.isl_basic_map_sample.argtypes = [c_void_p] +isl.isl_basic_map_union.restype = c_void_p +isl.isl_basic_map_union.argtypes = [c_void_p, c_void_p] +isl.isl_basic_map_copy.restype = c_void_p +isl.isl_basic_map_copy.argtypes = [c_void_p] +isl.isl_basic_map_free.restype = c_void_p +isl.isl_basic_map_free.argtypes = [c_void_p] +isl.isl_basic_map_to_str.restype = POINTER(c_char) +isl.isl_basic_map_to_str.argtypes = [c_void_p] + +class union_set(object): + def __init__(self, *args, **keywords): + if "ptr" in keywords: + self.ctx = keywords["ctx"] + self.ptr = keywords["ptr"] + return + if len(args) == 1 and args[0].__class__ is basic_set: + self.ctx = Context.getDefaultInstance() + self.ptr = isl.isl_union_set_from_basic_set(isl.isl_basic_set_copy(args[0].ptr)) + return + if len(args) == 1 and args[0].__class__ is point: + self.ctx = Context.getDefaultInstance() + self.ptr = isl.isl_union_set_from_point(isl.isl_point_copy(args[0].ptr)) + return + if len(args) == 1 and args[0].__class__ is set: + self.ctx = Context.getDefaultInstance() + self.ptr = isl.isl_union_set_from_set(isl.isl_set_copy(args[0].ptr)) + return + if len(args) == 1 and type(args[0]) == str: + self.ctx = Context.getDefaultInstance() + self.ptr = isl.isl_union_set_read_from_str(self.ctx, args[0].encode('ascii')) + return + raise Error + def __del__(self): + if hasattr(self, 'ptr'): + isl.isl_union_set_free(self.ptr) + def __str__(arg0): + try: + if not arg0.__class__ is union_set: + arg0 = union_set(arg0) + except: + raise + ptr = isl.isl_union_set_to_str(arg0.ptr) + res = cast(ptr, c_char_p).value.decode('ascii') + libc.free(ptr) + return res + def __repr__(self): + s = str(self) + if '"' in s: + return 'isl.union_set("""%s""")' % s + else: + return 'isl.union_set("%s")' % s + def affine_hull(arg0): + try: + if not arg0.__class__ is union_set: + arg0 = union_set(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_set_affine_hull(isl.isl_union_set_copy(arg0.ptr)) + obj = union_set(ctx=ctx, ptr=res) + return obj + def apply(arg0, arg1): + try: + if not arg0.__class__ is union_set: + arg0 = union_set(arg0) + except: + raise + try: + if not arg1.__class__ is union_map: + arg1 = union_map(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_set_apply(isl.isl_union_set_copy(arg0.ptr), isl.isl_union_map_copy(arg1.ptr)) + obj = union_set(ctx=ctx, ptr=res) + return obj + def as_set(arg0): + try: + if not arg0.__class__ is union_set: + arg0 = union_set(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_set_as_set(isl.isl_union_set_copy(arg0.ptr)) + obj = set(ctx=ctx, ptr=res) + return obj + def coalesce(arg0): + try: + if not arg0.__class__ is union_set: + arg0 = union_set(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_set_coalesce(isl.isl_union_set_copy(arg0.ptr)) + obj = union_set(ctx=ctx, ptr=res) + return obj + def compute_divs(arg0): + try: + if not arg0.__class__ is union_set: + arg0 = union_set(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_set_compute_divs(isl.isl_union_set_copy(arg0.ptr)) + obj = union_set(ctx=ctx, ptr=res) + return obj + def detect_equalities(arg0): + try: + if not arg0.__class__ is union_set: + arg0 = union_set(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_set_detect_equalities(isl.isl_union_set_copy(arg0.ptr)) + obj = union_set(ctx=ctx, ptr=res) + return obj + def drop_unused_params(arg0): + try: + if not arg0.__class__ is union_set: + arg0 = union_set(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_set_drop_unused_params(isl.isl_union_set_copy(arg0.ptr)) + obj = union_set(ctx=ctx, ptr=res) + return obj + @staticmethod + def empty(*args): + if len(args) == 0: + ctx = Context.getDefaultInstance() + res = isl.isl_union_set_empty_ctx(ctx) + obj = union_set(ctx=ctx, ptr=res) + return obj + raise Error + def every_set(arg0, arg1): + try: + if not arg0.__class__ is union_set: + arg0 = union_set(arg0) + except: + raise + exc_info = [None] + fn = CFUNCTYPE(c_int, c_void_p, c_void_p) + def cb_func(cb_arg0, cb_arg1): + cb_arg0 = set(ctx=arg0.ctx, ptr=isl.isl_set_copy(cb_arg0)) + try: + res = arg1(cb_arg0) + except BaseException as e: + exc_info[0] = e + return -1 + return 1 if res else 0 + cb1 = fn(cb_func) + ctx = arg0.ctx + res = isl.isl_union_set_every_set(arg0.ptr, cb1, None) + if exc_info[0] is not None: + raise exc_info[0] + if res < 0: + raise Error + return bool(res) + def extract_set(arg0, arg1): + try: + if not arg0.__class__ is union_set: + arg0 = union_set(arg0) + except: + raise + try: + if not arg1.__class__ is space: + arg1 = space(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_set_extract_set(arg0.ptr, isl.isl_space_copy(arg1.ptr)) + obj = set(ctx=ctx, ptr=res) + return obj + def foreach_point(arg0, arg1): + try: + if not arg0.__class__ is union_set: + arg0 = union_set(arg0) + except: + raise + exc_info = [None] + fn = CFUNCTYPE(c_int, c_void_p, c_void_p) + def cb_func(cb_arg0, cb_arg1): + cb_arg0 = point(ctx=arg0.ctx, ptr=(cb_arg0)) + try: + arg1(cb_arg0) + except BaseException as e: + exc_info[0] = e + return -1 + return 0 + cb1 = fn(cb_func) + ctx = arg0.ctx + res = isl.isl_union_set_foreach_point(arg0.ptr, cb1, None) + if exc_info[0] is not None: + raise exc_info[0] + if res < 0: + raise Error + def foreach_set(arg0, arg1): + try: + if not arg0.__class__ is union_set: + arg0 = union_set(arg0) + except: + raise + exc_info = [None] + fn = CFUNCTYPE(c_int, c_void_p, c_void_p) + def cb_func(cb_arg0, cb_arg1): + cb_arg0 = set(ctx=arg0.ctx, ptr=(cb_arg0)) + try: + arg1(cb_arg0) + except BaseException as e: + exc_info[0] = e + return -1 + return 0 + cb1 = fn(cb_func) + ctx = arg0.ctx + res = isl.isl_union_set_foreach_set(arg0.ptr, cb1, None) + if exc_info[0] is not None: + raise exc_info[0] + if res < 0: + raise Error + def gist(arg0, arg1): + try: + if not arg0.__class__ is union_set: + arg0 = union_set(arg0) + except: + raise + try: + if not arg1.__class__ is union_set: + arg1 = union_set(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_set_gist(isl.isl_union_set_copy(arg0.ptr), isl.isl_union_set_copy(arg1.ptr)) + obj = union_set(ctx=ctx, ptr=res) + return obj + def gist_params(arg0, arg1): + try: + if not arg0.__class__ is union_set: + arg0 = union_set(arg0) + except: + raise + try: + if not arg1.__class__ is set: + arg1 = set(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_set_gist_params(isl.isl_union_set_copy(arg0.ptr), isl.isl_set_copy(arg1.ptr)) + obj = union_set(ctx=ctx, ptr=res) + return obj + def identity(arg0): + try: + if not arg0.__class__ is union_set: + arg0 = union_set(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_set_identity(isl.isl_union_set_copy(arg0.ptr)) + obj = union_map(ctx=ctx, ptr=res) + return obj + def intersect(arg0, arg1): + try: + if not arg0.__class__ is union_set: + arg0 = union_set(arg0) + except: + raise + try: + if not arg1.__class__ is union_set: + arg1 = union_set(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_set_intersect(isl.isl_union_set_copy(arg0.ptr), isl.isl_union_set_copy(arg1.ptr)) + obj = union_set(ctx=ctx, ptr=res) + return obj + def intersect_params(arg0, arg1): + try: + if not arg0.__class__ is union_set: + arg0 = union_set(arg0) + except: + raise + try: + if not arg1.__class__ is set: + arg1 = set(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_set_intersect_params(isl.isl_union_set_copy(arg0.ptr), isl.isl_set_copy(arg1.ptr)) + obj = union_set(ctx=ctx, ptr=res) + return obj + def is_disjoint(arg0, arg1): + try: + if not arg0.__class__ is union_set: + arg0 = union_set(arg0) + except: + raise + try: + if not arg1.__class__ is union_set: + arg1 = union_set(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_set_is_disjoint(arg0.ptr, arg1.ptr) + if res < 0: + raise Error + return bool(res) + def is_empty(arg0): + try: + if not arg0.__class__ is union_set: + arg0 = union_set(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_set_is_empty(arg0.ptr) + if res < 0: + raise Error + return bool(res) + def is_equal(arg0, arg1): + try: + if not arg0.__class__ is union_set: + arg0 = union_set(arg0) + except: + raise + try: + if not arg1.__class__ is union_set: + arg1 = union_set(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_set_is_equal(arg0.ptr, arg1.ptr) + if res < 0: + raise Error + return bool(res) + def is_strict_subset(arg0, arg1): + try: + if not arg0.__class__ is union_set: + arg0 = union_set(arg0) + except: + raise + try: + if not arg1.__class__ is union_set: + arg1 = union_set(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_set_is_strict_subset(arg0.ptr, arg1.ptr) + if res < 0: + raise Error + return bool(res) + def is_subset(arg0, arg1): + try: + if not arg0.__class__ is union_set: + arg0 = union_set(arg0) + except: + raise + try: + if not arg1.__class__ is union_set: + arg1 = union_set(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_set_is_subset(arg0.ptr, arg1.ptr) + if res < 0: + raise Error + return bool(res) + def isa_set(arg0): + try: + if not arg0.__class__ is union_set: + arg0 = union_set(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_set_isa_set(arg0.ptr) + if res < 0: + raise Error + return bool(res) + def lexmax(arg0): + try: + if not arg0.__class__ is union_set: + arg0 = union_set(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_set_lexmax(isl.isl_union_set_copy(arg0.ptr)) + obj = union_set(ctx=ctx, ptr=res) + return obj + def lexmin(arg0): + try: + if not arg0.__class__ is union_set: + arg0 = union_set(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_set_lexmin(isl.isl_union_set_copy(arg0.ptr)) + obj = union_set(ctx=ctx, ptr=res) + return obj + def params(arg0): + try: + if not arg0.__class__ is union_set: + arg0 = union_set(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_set_params(isl.isl_union_set_copy(arg0.ptr)) + obj = set(ctx=ctx, ptr=res) + return obj + def polyhedral_hull(arg0): + try: + if not arg0.__class__ is union_set: + arg0 = union_set(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_set_polyhedral_hull(isl.isl_union_set_copy(arg0.ptr)) + obj = union_set(ctx=ctx, ptr=res) + return obj + def preimage(*args): + if len(args) == 2 and args[1].__class__ is multi_aff: + args = list(args) + try: + if not args[0].__class__ is union_set: + args[0] = union_set(args[0]) + except: + raise + ctx = args[0].ctx + res = isl.isl_union_set_preimage_multi_aff(isl.isl_union_set_copy(args[0].ptr), isl.isl_multi_aff_copy(args[1].ptr)) + obj = union_set(ctx=ctx, ptr=res) + return obj + if len(args) == 2 and args[1].__class__ is pw_multi_aff: + args = list(args) + try: + if not args[0].__class__ is union_set: + args[0] = union_set(args[0]) + except: + raise + ctx = args[0].ctx + res = isl.isl_union_set_preimage_pw_multi_aff(isl.isl_union_set_copy(args[0].ptr), isl.isl_pw_multi_aff_copy(args[1].ptr)) + obj = union_set(ctx=ctx, ptr=res) + return obj + if len(args) == 2 and args[1].__class__ is union_pw_multi_aff: + args = list(args) + try: + if not args[0].__class__ is union_set: + args[0] = union_set(args[0]) + except: + raise + ctx = args[0].ctx + res = isl.isl_union_set_preimage_union_pw_multi_aff(isl.isl_union_set_copy(args[0].ptr), isl.isl_union_pw_multi_aff_copy(args[1].ptr)) + obj = union_set(ctx=ctx, ptr=res) + return obj + raise Error + def project_out_all_params(arg0): + try: + if not arg0.__class__ is union_set: + arg0 = union_set(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_set_project_out_all_params(isl.isl_union_set_copy(arg0.ptr)) + obj = union_set(ctx=ctx, ptr=res) + return obj + def sample_point(arg0): + try: + if not arg0.__class__ is union_set: + arg0 = union_set(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_set_sample_point(isl.isl_union_set_copy(arg0.ptr)) + obj = point(ctx=ctx, ptr=res) + return obj + def set_list(arg0): + try: + if not arg0.__class__ is union_set: + arg0 = union_set(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_set_get_set_list(arg0.ptr) + obj = set_list(ctx=ctx, ptr=res) + return obj + def get_set_list(arg0): + return arg0.set_list() + def space(arg0): + try: + if not arg0.__class__ is union_set: + arg0 = union_set(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_set_get_space(arg0.ptr) + obj = space(ctx=ctx, ptr=res) + return obj + def get_space(arg0): + return arg0.space() + def subtract(arg0, arg1): + try: + if not arg0.__class__ is union_set: + arg0 = union_set(arg0) + except: + raise + try: + if not arg1.__class__ is union_set: + arg1 = union_set(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_set_subtract(isl.isl_union_set_copy(arg0.ptr), isl.isl_union_set_copy(arg1.ptr)) + obj = union_set(ctx=ctx, ptr=res) + return obj + def to_list(arg0): + try: + if not arg0.__class__ is union_set: + arg0 = union_set(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_set_to_list(isl.isl_union_set_copy(arg0.ptr)) + obj = union_set_list(ctx=ctx, ptr=res) + return obj + def union(arg0, arg1): + try: + if not arg0.__class__ is union_set: + arg0 = union_set(arg0) + except: + raise + try: + if not arg1.__class__ is union_set: + arg1 = union_set(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_set_union(isl.isl_union_set_copy(arg0.ptr), isl.isl_union_set_copy(arg1.ptr)) + obj = union_set(ctx=ctx, ptr=res) + return obj + def universe(arg0): + try: + if not arg0.__class__ is union_set: + arg0 = union_set(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_set_universe(isl.isl_union_set_copy(arg0.ptr)) + obj = union_set(ctx=ctx, ptr=res) + return obj + def unwrap(arg0): + try: + if not arg0.__class__ is union_set: + arg0 = union_set(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_set_unwrap(isl.isl_union_set_copy(arg0.ptr)) + obj = union_map(ctx=ctx, ptr=res) + return obj + +isl.isl_union_set_from_basic_set.restype = c_void_p +isl.isl_union_set_from_basic_set.argtypes = [c_void_p] +isl.isl_union_set_from_point.restype = c_void_p +isl.isl_union_set_from_point.argtypes = [c_void_p] +isl.isl_union_set_from_set.restype = c_void_p +isl.isl_union_set_from_set.argtypes = [c_void_p] +isl.isl_union_set_read_from_str.restype = c_void_p +isl.isl_union_set_read_from_str.argtypes = [Context, c_char_p] +isl.isl_union_set_affine_hull.restype = c_void_p +isl.isl_union_set_affine_hull.argtypes = [c_void_p] +isl.isl_union_set_apply.restype = c_void_p +isl.isl_union_set_apply.argtypes = [c_void_p, c_void_p] +isl.isl_union_set_as_set.restype = c_void_p +isl.isl_union_set_as_set.argtypes = [c_void_p] +isl.isl_union_set_coalesce.restype = c_void_p +isl.isl_union_set_coalesce.argtypes = [c_void_p] +isl.isl_union_set_compute_divs.restype = c_void_p +isl.isl_union_set_compute_divs.argtypes = [c_void_p] +isl.isl_union_set_detect_equalities.restype = c_void_p +isl.isl_union_set_detect_equalities.argtypes = [c_void_p] +isl.isl_union_set_drop_unused_params.restype = c_void_p +isl.isl_union_set_drop_unused_params.argtypes = [c_void_p] +isl.isl_union_set_empty_ctx.restype = c_void_p +isl.isl_union_set_empty_ctx.argtypes = [Context] +isl.isl_union_set_every_set.argtypes = [c_void_p, c_void_p, c_void_p] +isl.isl_union_set_extract_set.restype = c_void_p +isl.isl_union_set_extract_set.argtypes = [c_void_p, c_void_p] +isl.isl_union_set_foreach_point.argtypes = [c_void_p, c_void_p, c_void_p] +isl.isl_union_set_foreach_set.argtypes = [c_void_p, c_void_p, c_void_p] +isl.isl_union_set_gist.restype = c_void_p +isl.isl_union_set_gist.argtypes = [c_void_p, c_void_p] +isl.isl_union_set_gist_params.restype = c_void_p +isl.isl_union_set_gist_params.argtypes = [c_void_p, c_void_p] +isl.isl_union_set_identity.restype = c_void_p +isl.isl_union_set_identity.argtypes = [c_void_p] +isl.isl_union_set_intersect.restype = c_void_p +isl.isl_union_set_intersect.argtypes = [c_void_p, c_void_p] +isl.isl_union_set_intersect_params.restype = c_void_p +isl.isl_union_set_intersect_params.argtypes = [c_void_p, c_void_p] +isl.isl_union_set_is_disjoint.argtypes = [c_void_p, c_void_p] +isl.isl_union_set_is_empty.argtypes = [c_void_p] +isl.isl_union_set_is_equal.argtypes = [c_void_p, c_void_p] +isl.isl_union_set_is_strict_subset.argtypes = [c_void_p, c_void_p] +isl.isl_union_set_is_subset.argtypes = [c_void_p, c_void_p] +isl.isl_union_set_isa_set.argtypes = [c_void_p] +isl.isl_union_set_lexmax.restype = c_void_p +isl.isl_union_set_lexmax.argtypes = [c_void_p] +isl.isl_union_set_lexmin.restype = c_void_p +isl.isl_union_set_lexmin.argtypes = [c_void_p] +isl.isl_union_set_params.restype = c_void_p +isl.isl_union_set_params.argtypes = [c_void_p] +isl.isl_union_set_polyhedral_hull.restype = c_void_p +isl.isl_union_set_polyhedral_hull.argtypes = [c_void_p] +isl.isl_union_set_preimage_multi_aff.restype = c_void_p +isl.isl_union_set_preimage_multi_aff.argtypes = [c_void_p, c_void_p] +isl.isl_union_set_preimage_pw_multi_aff.restype = c_void_p +isl.isl_union_set_preimage_pw_multi_aff.argtypes = [c_void_p, c_void_p] +isl.isl_union_set_preimage_union_pw_multi_aff.restype = c_void_p +isl.isl_union_set_preimage_union_pw_multi_aff.argtypes = [c_void_p, c_void_p] +isl.isl_union_set_project_out_all_params.restype = c_void_p +isl.isl_union_set_project_out_all_params.argtypes = [c_void_p] +isl.isl_union_set_sample_point.restype = c_void_p +isl.isl_union_set_sample_point.argtypes = [c_void_p] +isl.isl_union_set_get_set_list.restype = c_void_p +isl.isl_union_set_get_set_list.argtypes = [c_void_p] +isl.isl_union_set_get_space.restype = c_void_p +isl.isl_union_set_get_space.argtypes = [c_void_p] +isl.isl_union_set_subtract.restype = c_void_p +isl.isl_union_set_subtract.argtypes = [c_void_p, c_void_p] +isl.isl_union_set_to_list.restype = c_void_p +isl.isl_union_set_to_list.argtypes = [c_void_p] +isl.isl_union_set_union.restype = c_void_p +isl.isl_union_set_union.argtypes = [c_void_p, c_void_p] +isl.isl_union_set_universe.restype = c_void_p +isl.isl_union_set_universe.argtypes = [c_void_p] +isl.isl_union_set_unwrap.restype = c_void_p +isl.isl_union_set_unwrap.argtypes = [c_void_p] +isl.isl_union_set_copy.restype = c_void_p +isl.isl_union_set_copy.argtypes = [c_void_p] +isl.isl_union_set_free.restype = c_void_p +isl.isl_union_set_free.argtypes = [c_void_p] +isl.isl_union_set_to_str.restype = POINTER(c_char) +isl.isl_union_set_to_str.argtypes = [c_void_p] + +class set(union_set): + def __init__(self, *args, **keywords): + if "ptr" in keywords: + self.ctx = keywords["ctx"] + self.ptr = keywords["ptr"] + return + if len(args) == 1 and args[0].__class__ is basic_set: + self.ctx = Context.getDefaultInstance() + self.ptr = isl.isl_set_from_basic_set(isl.isl_basic_set_copy(args[0].ptr)) + return + if len(args) == 1 and args[0].__class__ is point: + self.ctx = Context.getDefaultInstance() + self.ptr = isl.isl_set_from_point(isl.isl_point_copy(args[0].ptr)) + return + if len(args) == 1 and type(args[0]) == str: + self.ctx = Context.getDefaultInstance() + self.ptr = isl.isl_set_read_from_str(self.ctx, args[0].encode('ascii')) + return + raise Error + def __del__(self): + if hasattr(self, 'ptr'): + isl.isl_set_free(self.ptr) + def __str__(arg0): + try: + if not arg0.__class__ is set: + arg0 = set(arg0) + except: + raise + ptr = isl.isl_set_to_str(arg0.ptr) + res = cast(ptr, c_char_p).value.decode('ascii') + libc.free(ptr) + return res + def __repr__(self): + s = str(self) + if '"' in s: + return 'isl.set("""%s""")' % s + else: + return 'isl.set("%s")' % s + def affine_hull(arg0): + try: + if not arg0.__class__ is set: + arg0 = set(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_set_affine_hull(isl.isl_set_copy(arg0.ptr)) + obj = basic_set(ctx=ctx, ptr=res) + return obj + def apply(arg0, arg1): + try: + if not arg0.__class__ is set: + arg0 = set(arg0) + except: + raise + try: + if not arg1.__class__ is map: + arg1 = map(arg1) + except: + return union_set(arg0).apply(arg1) + ctx = arg0.ctx + res = isl.isl_set_apply(isl.isl_set_copy(arg0.ptr), isl.isl_map_copy(arg1.ptr)) + obj = set(ctx=ctx, ptr=res) + return obj + def as_pw_multi_aff(arg0): + try: + if not arg0.__class__ is set: + arg0 = set(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_set_as_pw_multi_aff(isl.isl_set_copy(arg0.ptr)) + obj = pw_multi_aff(ctx=ctx, ptr=res) + return obj + def bind(arg0, arg1): + try: + if not arg0.__class__ is set: + arg0 = set(arg0) + except: + raise + try: + if not arg1.__class__ is multi_id: + arg1 = multi_id(arg1) + except: + return union_set(arg0).bind(arg1) + ctx = arg0.ctx + res = isl.isl_set_bind(isl.isl_set_copy(arg0.ptr), isl.isl_multi_id_copy(arg1.ptr)) + obj = set(ctx=ctx, ptr=res) + return obj + def coalesce(arg0): + try: + if not arg0.__class__ is set: + arg0 = set(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_set_coalesce(isl.isl_set_copy(arg0.ptr)) + obj = set(ctx=ctx, ptr=res) + return obj + def complement(arg0): + try: + if not arg0.__class__ is set: + arg0 = set(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_set_complement(isl.isl_set_copy(arg0.ptr)) + obj = set(ctx=ctx, ptr=res) + return obj + def detect_equalities(arg0): + try: + if not arg0.__class__ is set: + arg0 = set(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_set_detect_equalities(isl.isl_set_copy(arg0.ptr)) + obj = set(ctx=ctx, ptr=res) + return obj + def dim_max_val(arg0, arg1): + try: + if not arg0.__class__ is set: + arg0 = set(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_set_dim_max_val(isl.isl_set_copy(arg0.ptr), arg1) + obj = val(ctx=ctx, ptr=res) + return obj + def dim_min_val(arg0, arg1): + try: + if not arg0.__class__ is set: + arg0 = set(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_set_dim_min_val(isl.isl_set_copy(arg0.ptr), arg1) + obj = val(ctx=ctx, ptr=res) + return obj + def drop_unused_params(arg0): + try: + if not arg0.__class__ is set: + arg0 = set(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_set_drop_unused_params(isl.isl_set_copy(arg0.ptr)) + obj = set(ctx=ctx, ptr=res) + return obj + @staticmethod + def empty(arg0): + try: + if not arg0.__class__ is space: + arg0 = space(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_set_empty(isl.isl_space_copy(arg0.ptr)) + obj = set(ctx=ctx, ptr=res) + return obj + def flatten(arg0): + try: + if not arg0.__class__ is set: + arg0 = set(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_set_flatten(isl.isl_set_copy(arg0.ptr)) + obj = set(ctx=ctx, ptr=res) + return obj + def foreach_basic_set(arg0, arg1): + try: + if not arg0.__class__ is set: + arg0 = set(arg0) + except: + raise + exc_info = [None] + fn = CFUNCTYPE(c_int, c_void_p, c_void_p) + def cb_func(cb_arg0, cb_arg1): + cb_arg0 = basic_set(ctx=arg0.ctx, ptr=(cb_arg0)) + try: + arg1(cb_arg0) + except BaseException as e: + exc_info[0] = e + return -1 + return 0 + cb1 = fn(cb_func) + ctx = arg0.ctx + res = isl.isl_set_foreach_basic_set(arg0.ptr, cb1, None) + if exc_info[0] is not None: + raise exc_info[0] + if res < 0: + raise Error + def foreach_point(arg0, arg1): + try: + if not arg0.__class__ is set: + arg0 = set(arg0) + except: + raise + exc_info = [None] + fn = CFUNCTYPE(c_int, c_void_p, c_void_p) + def cb_func(cb_arg0, cb_arg1): + cb_arg0 = point(ctx=arg0.ctx, ptr=(cb_arg0)) + try: + arg1(cb_arg0) + except BaseException as e: + exc_info[0] = e + return -1 + return 0 + cb1 = fn(cb_func) + ctx = arg0.ctx + res = isl.isl_set_foreach_point(arg0.ptr, cb1, None) + if exc_info[0] is not None: + raise exc_info[0] + if res < 0: + raise Error + def gist(arg0, arg1): + try: + if not arg0.__class__ is set: + arg0 = set(arg0) + except: + raise + try: + if not arg1.__class__ is set: + arg1 = set(arg1) + except: + return union_set(arg0).gist(arg1) + ctx = arg0.ctx + res = isl.isl_set_gist(isl.isl_set_copy(arg0.ptr), isl.isl_set_copy(arg1.ptr)) + obj = set(ctx=ctx, ptr=res) + return obj + def gist_params(arg0, arg1): + try: + if not arg0.__class__ is set: + arg0 = set(arg0) + except: + raise + try: + if not arg1.__class__ is set: + arg1 = set(arg1) + except: + return union_set(arg0).gist_params(arg1) + ctx = arg0.ctx + res = isl.isl_set_gist_params(isl.isl_set_copy(arg0.ptr), isl.isl_set_copy(arg1.ptr)) + obj = set(ctx=ctx, ptr=res) + return obj + def identity(arg0): + try: + if not arg0.__class__ is set: + arg0 = set(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_set_identity(isl.isl_set_copy(arg0.ptr)) + obj = map(ctx=ctx, ptr=res) + return obj + def indicator_function(arg0): + try: + if not arg0.__class__ is set: + arg0 = set(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_set_indicator_function(isl.isl_set_copy(arg0.ptr)) + obj = pw_aff(ctx=ctx, ptr=res) + return obj + def insert_domain(arg0, arg1): + try: + if not arg0.__class__ is set: + arg0 = set(arg0) + except: + raise + try: + if not arg1.__class__ is space: + arg1 = space(arg1) + except: + return union_set(arg0).insert_domain(arg1) + ctx = arg0.ctx + res = isl.isl_set_insert_domain(isl.isl_set_copy(arg0.ptr), isl.isl_space_copy(arg1.ptr)) + obj = map(ctx=ctx, ptr=res) + return obj + def intersect(arg0, arg1): + try: + if not arg0.__class__ is set: + arg0 = set(arg0) + except: + raise + try: + if not arg1.__class__ is set: + arg1 = set(arg1) + except: + return union_set(arg0).intersect(arg1) + ctx = arg0.ctx + res = isl.isl_set_intersect(isl.isl_set_copy(arg0.ptr), isl.isl_set_copy(arg1.ptr)) + obj = set(ctx=ctx, ptr=res) + return obj + def intersect_params(arg0, arg1): + try: + if not arg0.__class__ is set: + arg0 = set(arg0) + except: + raise + try: + if not arg1.__class__ is set: + arg1 = set(arg1) + except: + return union_set(arg0).intersect_params(arg1) + ctx = arg0.ctx + res = isl.isl_set_intersect_params(isl.isl_set_copy(arg0.ptr), isl.isl_set_copy(arg1.ptr)) + obj = set(ctx=ctx, ptr=res) + return obj + def involves_locals(arg0): + try: + if not arg0.__class__ is set: + arg0 = set(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_set_involves_locals(arg0.ptr) + if res < 0: + raise Error + return bool(res) + def is_disjoint(arg0, arg1): + try: + if not arg0.__class__ is set: + arg0 = set(arg0) + except: + raise + try: + if not arg1.__class__ is set: + arg1 = set(arg1) + except: + return union_set(arg0).is_disjoint(arg1) + ctx = arg0.ctx + res = isl.isl_set_is_disjoint(arg0.ptr, arg1.ptr) + if res < 0: + raise Error + return bool(res) + def is_empty(arg0): + try: + if not arg0.__class__ is set: + arg0 = set(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_set_is_empty(arg0.ptr) + if res < 0: + raise Error + return bool(res) + def is_equal(arg0, arg1): + try: + if not arg0.__class__ is set: + arg0 = set(arg0) + except: + raise + try: + if not arg1.__class__ is set: + arg1 = set(arg1) + except: + return union_set(arg0).is_equal(arg1) + ctx = arg0.ctx + res = isl.isl_set_is_equal(arg0.ptr, arg1.ptr) + if res < 0: + raise Error + return bool(res) + def is_singleton(arg0): + try: + if not arg0.__class__ is set: + arg0 = set(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_set_is_singleton(arg0.ptr) + if res < 0: + raise Error + return bool(res) + def is_strict_subset(arg0, arg1): + try: + if not arg0.__class__ is set: + arg0 = set(arg0) + except: + raise + try: + if not arg1.__class__ is set: + arg1 = set(arg1) + except: + return union_set(arg0).is_strict_subset(arg1) + ctx = arg0.ctx + res = isl.isl_set_is_strict_subset(arg0.ptr, arg1.ptr) + if res < 0: + raise Error + return bool(res) + def is_subset(arg0, arg1): + try: + if not arg0.__class__ is set: + arg0 = set(arg0) + except: + raise + try: + if not arg1.__class__ is set: + arg1 = set(arg1) + except: + return union_set(arg0).is_subset(arg1) + ctx = arg0.ctx + res = isl.isl_set_is_subset(arg0.ptr, arg1.ptr) + if res < 0: + raise Error + return bool(res) + def is_wrapping(arg0): + try: + if not arg0.__class__ is set: + arg0 = set(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_set_is_wrapping(arg0.ptr) + if res < 0: + raise Error + return bool(res) + def lattice_tile(arg0): + try: + if not arg0.__class__ is set: + arg0 = set(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_set_get_lattice_tile(arg0.ptr) + obj = fixed_box(ctx=ctx, ptr=res) + return obj + def get_lattice_tile(arg0): + return arg0.lattice_tile() + def lexmax(arg0): + try: + if not arg0.__class__ is set: + arg0 = set(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_set_lexmax(isl.isl_set_copy(arg0.ptr)) + obj = set(ctx=ctx, ptr=res) + return obj + def lexmax_pw_multi_aff(arg0): + try: + if not arg0.__class__ is set: + arg0 = set(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_set_lexmax_pw_multi_aff(isl.isl_set_copy(arg0.ptr)) + obj = pw_multi_aff(ctx=ctx, ptr=res) + return obj + def lexmin(arg0): + try: + if not arg0.__class__ is set: + arg0 = set(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_set_lexmin(isl.isl_set_copy(arg0.ptr)) + obj = set(ctx=ctx, ptr=res) + return obj + def lexmin_pw_multi_aff(arg0): + try: + if not arg0.__class__ is set: + arg0 = set(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_set_lexmin_pw_multi_aff(isl.isl_set_copy(arg0.ptr)) + obj = pw_multi_aff(ctx=ctx, ptr=res) + return obj + def lower_bound(*args): + if len(args) == 2 and args[1].__class__ is multi_pw_aff: + args = list(args) + try: + if not args[0].__class__ is set: + args[0] = set(args[0]) + except: + raise + ctx = args[0].ctx + res = isl.isl_set_lower_bound_multi_pw_aff(isl.isl_set_copy(args[0].ptr), isl.isl_multi_pw_aff_copy(args[1].ptr)) + obj = set(ctx=ctx, ptr=res) + return obj + if len(args) == 2 and args[1].__class__ is multi_val: + args = list(args) + try: + if not args[0].__class__ is set: + args[0] = set(args[0]) + except: + raise + ctx = args[0].ctx + res = isl.isl_set_lower_bound_multi_val(isl.isl_set_copy(args[0].ptr), isl.isl_multi_val_copy(args[1].ptr)) + obj = set(ctx=ctx, ptr=res) + return obj + raise Error + def max_multi_pw_aff(arg0): + try: + if not arg0.__class__ is set: + arg0 = set(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_set_max_multi_pw_aff(isl.isl_set_copy(arg0.ptr)) + obj = multi_pw_aff(ctx=ctx, ptr=res) + return obj + def max_val(arg0, arg1): + try: + if not arg0.__class__ is set: + arg0 = set(arg0) + except: + raise + try: + if not arg1.__class__ is aff: + arg1 = aff(arg1) + except: + return union_set(arg0).max_val(arg1) + ctx = arg0.ctx + res = isl.isl_set_max_val(arg0.ptr, arg1.ptr) + obj = val(ctx=ctx, ptr=res) + return obj + def min_multi_pw_aff(arg0): + try: + if not arg0.__class__ is set: + arg0 = set(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_set_min_multi_pw_aff(isl.isl_set_copy(arg0.ptr)) + obj = multi_pw_aff(ctx=ctx, ptr=res) + return obj + def min_val(arg0, arg1): + try: + if not arg0.__class__ is set: + arg0 = set(arg0) + except: + raise + try: + if not arg1.__class__ is aff: + arg1 = aff(arg1) + except: + return union_set(arg0).min_val(arg1) + ctx = arg0.ctx + res = isl.isl_set_min_val(arg0.ptr, arg1.ptr) + obj = val(ctx=ctx, ptr=res) + return obj + def n_basic_set(arg0): + try: + if not arg0.__class__ is set: + arg0 = set(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_set_n_basic_set(arg0.ptr) + if res < 0: + raise Error + return int(res) + def param_pw_aff_on_domain(*args): + if len(args) == 2 and (args[1].__class__ is id or type(args[1]) == str): + args = list(args) + try: + if not args[0].__class__ is set: + args[0] = set(args[0]) + except: + raise + try: + if not args[1].__class__ is id: + args[1] = id(args[1]) + except: + raise + ctx = args[0].ctx + res = isl.isl_set_param_pw_aff_on_domain_id(isl.isl_set_copy(args[0].ptr), isl.isl_id_copy(args[1].ptr)) + obj = pw_aff(ctx=ctx, ptr=res) + return obj + raise Error + def params(arg0): + try: + if not arg0.__class__ is set: + arg0 = set(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_set_params(isl.isl_set_copy(arg0.ptr)) + obj = set(ctx=ctx, ptr=res) + return obj + def plain_multi_val_if_fixed(arg0): + try: + if not arg0.__class__ is set: + arg0 = set(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_set_get_plain_multi_val_if_fixed(arg0.ptr) + obj = multi_val(ctx=ctx, ptr=res) + return obj + def get_plain_multi_val_if_fixed(arg0): + return arg0.plain_multi_val_if_fixed() + def polyhedral_hull(arg0): + try: + if not arg0.__class__ is set: + arg0 = set(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_set_polyhedral_hull(isl.isl_set_copy(arg0.ptr)) + obj = basic_set(ctx=ctx, ptr=res) + return obj + def preimage(*args): + if len(args) == 2 and args[1].__class__ is multi_aff: + args = list(args) + try: + if not args[0].__class__ is set: + args[0] = set(args[0]) + except: + raise + ctx = args[0].ctx + res = isl.isl_set_preimage_multi_aff(isl.isl_set_copy(args[0].ptr), isl.isl_multi_aff_copy(args[1].ptr)) + obj = set(ctx=ctx, ptr=res) + return obj + if len(args) == 2 and args[1].__class__ is multi_pw_aff: + args = list(args) + try: + if not args[0].__class__ is set: + args[0] = set(args[0]) + except: + raise + ctx = args[0].ctx + res = isl.isl_set_preimage_multi_pw_aff(isl.isl_set_copy(args[0].ptr), isl.isl_multi_pw_aff_copy(args[1].ptr)) + obj = set(ctx=ctx, ptr=res) + return obj + if len(args) == 2 and args[1].__class__ is pw_multi_aff: + args = list(args) + try: + if not args[0].__class__ is set: + args[0] = set(args[0]) + except: + raise + ctx = args[0].ctx + res = isl.isl_set_preimage_pw_multi_aff(isl.isl_set_copy(args[0].ptr), isl.isl_pw_multi_aff_copy(args[1].ptr)) + obj = set(ctx=ctx, ptr=res) + return obj + raise Error + def product(arg0, arg1): + try: + if not arg0.__class__ is set: + arg0 = set(arg0) + except: + raise + try: + if not arg1.__class__ is set: + arg1 = set(arg1) + except: + return union_set(arg0).product(arg1) + ctx = arg0.ctx + res = isl.isl_set_product(isl.isl_set_copy(arg0.ptr), isl.isl_set_copy(arg1.ptr)) + obj = set(ctx=ctx, ptr=res) + return obj + def project_out_all_params(arg0): + try: + if not arg0.__class__ is set: + arg0 = set(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_set_project_out_all_params(isl.isl_set_copy(arg0.ptr)) + obj = set(ctx=ctx, ptr=res) + return obj + def project_out_param(*args): + if len(args) == 2 and (args[1].__class__ is id or type(args[1]) == str): + args = list(args) + try: + if not args[0].__class__ is set: + args[0] = set(args[0]) + except: + raise + try: + if not args[1].__class__ is id: + args[1] = id(args[1]) + except: + raise + ctx = args[0].ctx + res = isl.isl_set_project_out_param_id(isl.isl_set_copy(args[0].ptr), isl.isl_id_copy(args[1].ptr)) + obj = set(ctx=ctx, ptr=res) + return obj + if len(args) == 2 and args[1].__class__ is id_list: + args = list(args) + try: + if not args[0].__class__ is set: + args[0] = set(args[0]) + except: + raise + ctx = args[0].ctx + res = isl.isl_set_project_out_param_id_list(isl.isl_set_copy(args[0].ptr), isl.isl_id_list_copy(args[1].ptr)) + obj = set(ctx=ctx, ptr=res) + return obj + raise Error + def pw_aff_on_domain(*args): + if len(args) == 2 and (args[1].__class__ is val or type(args[1]) == int): + args = list(args) + try: + if not args[0].__class__ is set: + args[0] = set(args[0]) + except: + raise + try: + if not args[1].__class__ is val: + args[1] = val(args[1]) + except: + raise + ctx = args[0].ctx + res = isl.isl_set_pw_aff_on_domain_val(isl.isl_set_copy(args[0].ptr), isl.isl_val_copy(args[1].ptr)) + obj = pw_aff(ctx=ctx, ptr=res) + return obj + raise Error + def pw_multi_aff_on_domain(*args): + if len(args) == 2 and args[1].__class__ is multi_val: + args = list(args) + try: + if not args[0].__class__ is set: + args[0] = set(args[0]) + except: + raise + ctx = args[0].ctx + res = isl.isl_set_pw_multi_aff_on_domain_multi_val(isl.isl_set_copy(args[0].ptr), isl.isl_multi_val_copy(args[1].ptr)) + obj = pw_multi_aff(ctx=ctx, ptr=res) + return obj + raise Error + def sample(arg0): + try: + if not arg0.__class__ is set: + arg0 = set(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_set_sample(isl.isl_set_copy(arg0.ptr)) + obj = basic_set(ctx=ctx, ptr=res) + return obj + def sample_point(arg0): + try: + if not arg0.__class__ is set: + arg0 = set(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_set_sample_point(isl.isl_set_copy(arg0.ptr)) + obj = point(ctx=ctx, ptr=res) + return obj + def simple_fixed_box_hull(arg0): + try: + if not arg0.__class__ is set: + arg0 = set(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_set_get_simple_fixed_box_hull(arg0.ptr) + obj = fixed_box(ctx=ctx, ptr=res) + return obj + def get_simple_fixed_box_hull(arg0): + return arg0.simple_fixed_box_hull() + def space(arg0): + try: + if not arg0.__class__ is set: + arg0 = set(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_set_get_space(arg0.ptr) + obj = space(ctx=ctx, ptr=res) + return obj + def get_space(arg0): + return arg0.space() + def stride(arg0, arg1): + try: + if not arg0.__class__ is set: + arg0 = set(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_set_get_stride(arg0.ptr, arg1) + obj = val(ctx=ctx, ptr=res) + return obj + def get_stride(arg0, arg1): + return arg0.stride(arg1) + def subtract(arg0, arg1): + try: + if not arg0.__class__ is set: + arg0 = set(arg0) + except: + raise + try: + if not arg1.__class__ is set: + arg1 = set(arg1) + except: + return union_set(arg0).subtract(arg1) + ctx = arg0.ctx + res = isl.isl_set_subtract(isl.isl_set_copy(arg0.ptr), isl.isl_set_copy(arg1.ptr)) + obj = set(ctx=ctx, ptr=res) + return obj + def to_list(arg0): + try: + if not arg0.__class__ is set: + arg0 = set(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_set_to_list(isl.isl_set_copy(arg0.ptr)) + obj = set_list(ctx=ctx, ptr=res) + return obj + def to_union_set(arg0): + try: + if not arg0.__class__ is set: + arg0 = set(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_set_to_union_set(isl.isl_set_copy(arg0.ptr)) + obj = union_set(ctx=ctx, ptr=res) + return obj + def translation(arg0): + try: + if not arg0.__class__ is set: + arg0 = set(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_set_translation(isl.isl_set_copy(arg0.ptr)) + obj = map(ctx=ctx, ptr=res) + return obj + def tuple_dim(arg0): + try: + if not arg0.__class__ is set: + arg0 = set(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_set_tuple_dim(arg0.ptr) + if res < 0: + raise Error + return int(res) + def unbind_params(arg0, arg1): + try: + if not arg0.__class__ is set: + arg0 = set(arg0) + except: + raise + try: + if not arg1.__class__ is multi_id: + arg1 = multi_id(arg1) + except: + return union_set(arg0).unbind_params(arg1) + ctx = arg0.ctx + res = isl.isl_set_unbind_params(isl.isl_set_copy(arg0.ptr), isl.isl_multi_id_copy(arg1.ptr)) + obj = set(ctx=ctx, ptr=res) + return obj + def unbind_params_insert_domain(arg0, arg1): + try: + if not arg0.__class__ is set: + arg0 = set(arg0) + except: + raise + try: + if not arg1.__class__ is multi_id: + arg1 = multi_id(arg1) + except: + return union_set(arg0).unbind_params_insert_domain(arg1) + ctx = arg0.ctx + res = isl.isl_set_unbind_params_insert_domain(isl.isl_set_copy(arg0.ptr), isl.isl_multi_id_copy(arg1.ptr)) + obj = map(ctx=ctx, ptr=res) + return obj + def union(arg0, arg1): + try: + if not arg0.__class__ is set: + arg0 = set(arg0) + except: + raise + try: + if not arg1.__class__ is set: + arg1 = set(arg1) + except: + return union_set(arg0).union(arg1) + ctx = arg0.ctx + res = isl.isl_set_union(isl.isl_set_copy(arg0.ptr), isl.isl_set_copy(arg1.ptr)) + obj = set(ctx=ctx, ptr=res) + return obj + @staticmethod + def universe(arg0): + try: + if not arg0.__class__ is space: + arg0 = space(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_set_universe(isl.isl_space_copy(arg0.ptr)) + obj = set(ctx=ctx, ptr=res) + return obj + def unshifted_simple_hull(arg0): + try: + if not arg0.__class__ is set: + arg0 = set(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_set_unshifted_simple_hull(isl.isl_set_copy(arg0.ptr)) + obj = basic_set(ctx=ctx, ptr=res) + return obj + def unwrap(arg0): + try: + if not arg0.__class__ is set: + arg0 = set(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_set_unwrap(isl.isl_set_copy(arg0.ptr)) + obj = map(ctx=ctx, ptr=res) + return obj + def upper_bound(*args): + if len(args) == 2 and args[1].__class__ is multi_pw_aff: + args = list(args) + try: + if not args[0].__class__ is set: + args[0] = set(args[0]) + except: + raise + ctx = args[0].ctx + res = isl.isl_set_upper_bound_multi_pw_aff(isl.isl_set_copy(args[0].ptr), isl.isl_multi_pw_aff_copy(args[1].ptr)) + obj = set(ctx=ctx, ptr=res) + return obj + if len(args) == 2 and args[1].__class__ is multi_val: + args = list(args) + try: + if not args[0].__class__ is set: + args[0] = set(args[0]) + except: + raise + ctx = args[0].ctx + res = isl.isl_set_upper_bound_multi_val(isl.isl_set_copy(args[0].ptr), isl.isl_multi_val_copy(args[1].ptr)) + obj = set(ctx=ctx, ptr=res) + return obj + raise Error + def wrapped_reverse(arg0): + try: + if not arg0.__class__ is set: + arg0 = set(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_set_wrapped_reverse(isl.isl_set_copy(arg0.ptr)) + obj = set(ctx=ctx, ptr=res) + return obj + +isl.isl_set_from_basic_set.restype = c_void_p +isl.isl_set_from_basic_set.argtypes = [c_void_p] +isl.isl_set_from_point.restype = c_void_p +isl.isl_set_from_point.argtypes = [c_void_p] +isl.isl_set_read_from_str.restype = c_void_p +isl.isl_set_read_from_str.argtypes = [Context, c_char_p] +isl.isl_set_affine_hull.restype = c_void_p +isl.isl_set_affine_hull.argtypes = [c_void_p] +isl.isl_set_apply.restype = c_void_p +isl.isl_set_apply.argtypes = [c_void_p, c_void_p] +isl.isl_set_as_pw_multi_aff.restype = c_void_p +isl.isl_set_as_pw_multi_aff.argtypes = [c_void_p] +isl.isl_set_bind.restype = c_void_p +isl.isl_set_bind.argtypes = [c_void_p, c_void_p] +isl.isl_set_coalesce.restype = c_void_p +isl.isl_set_coalesce.argtypes = [c_void_p] +isl.isl_set_complement.restype = c_void_p +isl.isl_set_complement.argtypes = [c_void_p] +isl.isl_set_detect_equalities.restype = c_void_p +isl.isl_set_detect_equalities.argtypes = [c_void_p] +isl.isl_set_dim_max_val.restype = c_void_p +isl.isl_set_dim_max_val.argtypes = [c_void_p, c_int] +isl.isl_set_dim_min_val.restype = c_void_p +isl.isl_set_dim_min_val.argtypes = [c_void_p, c_int] +isl.isl_set_drop_unused_params.restype = c_void_p +isl.isl_set_drop_unused_params.argtypes = [c_void_p] +isl.isl_set_empty.restype = c_void_p +isl.isl_set_empty.argtypes = [c_void_p] +isl.isl_set_flatten.restype = c_void_p +isl.isl_set_flatten.argtypes = [c_void_p] +isl.isl_set_foreach_basic_set.argtypes = [c_void_p, c_void_p, c_void_p] +isl.isl_set_foreach_point.argtypes = [c_void_p, c_void_p, c_void_p] +isl.isl_set_gist.restype = c_void_p +isl.isl_set_gist.argtypes = [c_void_p, c_void_p] +isl.isl_set_gist_params.restype = c_void_p +isl.isl_set_gist_params.argtypes = [c_void_p, c_void_p] +isl.isl_set_identity.restype = c_void_p +isl.isl_set_identity.argtypes = [c_void_p] +isl.isl_set_indicator_function.restype = c_void_p +isl.isl_set_indicator_function.argtypes = [c_void_p] +isl.isl_set_insert_domain.restype = c_void_p +isl.isl_set_insert_domain.argtypes = [c_void_p, c_void_p] +isl.isl_set_intersect.restype = c_void_p +isl.isl_set_intersect.argtypes = [c_void_p, c_void_p] +isl.isl_set_intersect_params.restype = c_void_p +isl.isl_set_intersect_params.argtypes = [c_void_p, c_void_p] +isl.isl_set_involves_locals.argtypes = [c_void_p] +isl.isl_set_is_disjoint.argtypes = [c_void_p, c_void_p] +isl.isl_set_is_empty.argtypes = [c_void_p] +isl.isl_set_is_equal.argtypes = [c_void_p, c_void_p] +isl.isl_set_is_singleton.argtypes = [c_void_p] +isl.isl_set_is_strict_subset.argtypes = [c_void_p, c_void_p] +isl.isl_set_is_subset.argtypes = [c_void_p, c_void_p] +isl.isl_set_is_wrapping.argtypes = [c_void_p] +isl.isl_set_get_lattice_tile.restype = c_void_p +isl.isl_set_get_lattice_tile.argtypes = [c_void_p] +isl.isl_set_lexmax.restype = c_void_p +isl.isl_set_lexmax.argtypes = [c_void_p] +isl.isl_set_lexmax_pw_multi_aff.restype = c_void_p +isl.isl_set_lexmax_pw_multi_aff.argtypes = [c_void_p] +isl.isl_set_lexmin.restype = c_void_p +isl.isl_set_lexmin.argtypes = [c_void_p] +isl.isl_set_lexmin_pw_multi_aff.restype = c_void_p +isl.isl_set_lexmin_pw_multi_aff.argtypes = [c_void_p] +isl.isl_set_lower_bound_multi_pw_aff.restype = c_void_p +isl.isl_set_lower_bound_multi_pw_aff.argtypes = [c_void_p, c_void_p] +isl.isl_set_lower_bound_multi_val.restype = c_void_p +isl.isl_set_lower_bound_multi_val.argtypes = [c_void_p, c_void_p] +isl.isl_set_max_multi_pw_aff.restype = c_void_p +isl.isl_set_max_multi_pw_aff.argtypes = [c_void_p] +isl.isl_set_max_val.restype = c_void_p +isl.isl_set_max_val.argtypes = [c_void_p, c_void_p] +isl.isl_set_min_multi_pw_aff.restype = c_void_p +isl.isl_set_min_multi_pw_aff.argtypes = [c_void_p] +isl.isl_set_min_val.restype = c_void_p +isl.isl_set_min_val.argtypes = [c_void_p, c_void_p] +isl.isl_set_n_basic_set.argtypes = [c_void_p] +isl.isl_set_param_pw_aff_on_domain_id.restype = c_void_p +isl.isl_set_param_pw_aff_on_domain_id.argtypes = [c_void_p, c_void_p] +isl.isl_set_params.restype = c_void_p +isl.isl_set_params.argtypes = [c_void_p] +isl.isl_set_get_plain_multi_val_if_fixed.restype = c_void_p +isl.isl_set_get_plain_multi_val_if_fixed.argtypes = [c_void_p] +isl.isl_set_polyhedral_hull.restype = c_void_p +isl.isl_set_polyhedral_hull.argtypes = [c_void_p] +isl.isl_set_preimage_multi_aff.restype = c_void_p +isl.isl_set_preimage_multi_aff.argtypes = [c_void_p, c_void_p] +isl.isl_set_preimage_multi_pw_aff.restype = c_void_p +isl.isl_set_preimage_multi_pw_aff.argtypes = [c_void_p, c_void_p] +isl.isl_set_preimage_pw_multi_aff.restype = c_void_p +isl.isl_set_preimage_pw_multi_aff.argtypes = [c_void_p, c_void_p] +isl.isl_set_product.restype = c_void_p +isl.isl_set_product.argtypes = [c_void_p, c_void_p] +isl.isl_set_project_out_all_params.restype = c_void_p +isl.isl_set_project_out_all_params.argtypes = [c_void_p] +isl.isl_set_project_out_param_id.restype = c_void_p +isl.isl_set_project_out_param_id.argtypes = [c_void_p, c_void_p] +isl.isl_set_project_out_param_id_list.restype = c_void_p +isl.isl_set_project_out_param_id_list.argtypes = [c_void_p, c_void_p] +isl.isl_set_pw_aff_on_domain_val.restype = c_void_p +isl.isl_set_pw_aff_on_domain_val.argtypes = [c_void_p, c_void_p] +isl.isl_set_pw_multi_aff_on_domain_multi_val.restype = c_void_p +isl.isl_set_pw_multi_aff_on_domain_multi_val.argtypes = [c_void_p, c_void_p] +isl.isl_set_sample.restype = c_void_p +isl.isl_set_sample.argtypes = [c_void_p] +isl.isl_set_sample_point.restype = c_void_p +isl.isl_set_sample_point.argtypes = [c_void_p] +isl.isl_set_get_simple_fixed_box_hull.restype = c_void_p +isl.isl_set_get_simple_fixed_box_hull.argtypes = [c_void_p] +isl.isl_set_get_space.restype = c_void_p +isl.isl_set_get_space.argtypes = [c_void_p] +isl.isl_set_get_stride.restype = c_void_p +isl.isl_set_get_stride.argtypes = [c_void_p, c_int] +isl.isl_set_subtract.restype = c_void_p +isl.isl_set_subtract.argtypes = [c_void_p, c_void_p] +isl.isl_set_to_list.restype = c_void_p +isl.isl_set_to_list.argtypes = [c_void_p] +isl.isl_set_to_union_set.restype = c_void_p +isl.isl_set_to_union_set.argtypes = [c_void_p] +isl.isl_set_translation.restype = c_void_p +isl.isl_set_translation.argtypes = [c_void_p] +isl.isl_set_tuple_dim.argtypes = [c_void_p] +isl.isl_set_unbind_params.restype = c_void_p +isl.isl_set_unbind_params.argtypes = [c_void_p, c_void_p] +isl.isl_set_unbind_params_insert_domain.restype = c_void_p +isl.isl_set_unbind_params_insert_domain.argtypes = [c_void_p, c_void_p] +isl.isl_set_union.restype = c_void_p +isl.isl_set_union.argtypes = [c_void_p, c_void_p] +isl.isl_set_universe.restype = c_void_p +isl.isl_set_universe.argtypes = [c_void_p] +isl.isl_set_unshifted_simple_hull.restype = c_void_p +isl.isl_set_unshifted_simple_hull.argtypes = [c_void_p] +isl.isl_set_unwrap.restype = c_void_p +isl.isl_set_unwrap.argtypes = [c_void_p] +isl.isl_set_upper_bound_multi_pw_aff.restype = c_void_p +isl.isl_set_upper_bound_multi_pw_aff.argtypes = [c_void_p, c_void_p] +isl.isl_set_upper_bound_multi_val.restype = c_void_p +isl.isl_set_upper_bound_multi_val.argtypes = [c_void_p, c_void_p] +isl.isl_set_wrapped_reverse.restype = c_void_p +isl.isl_set_wrapped_reverse.argtypes = [c_void_p] +isl.isl_set_copy.restype = c_void_p +isl.isl_set_copy.argtypes = [c_void_p] +isl.isl_set_free.restype = c_void_p +isl.isl_set_free.argtypes = [c_void_p] +isl.isl_set_to_str.restype = POINTER(c_char) +isl.isl_set_to_str.argtypes = [c_void_p] + +class basic_set(set): + def __init__(self, *args, **keywords): + if "ptr" in keywords: + self.ctx = keywords["ctx"] + self.ptr = keywords["ptr"] + return + if len(args) == 1 and args[0].__class__ is point: + self.ctx = Context.getDefaultInstance() + self.ptr = isl.isl_basic_set_from_point(isl.isl_point_copy(args[0].ptr)) + return + if len(args) == 1 and type(args[0]) == str: + self.ctx = Context.getDefaultInstance() + self.ptr = isl.isl_basic_set_read_from_str(self.ctx, args[0].encode('ascii')) + return + raise Error + def __del__(self): + if hasattr(self, 'ptr'): + isl.isl_basic_set_free(self.ptr) + def __str__(arg0): + try: + if not arg0.__class__ is basic_set: + arg0 = basic_set(arg0) + except: + raise + ptr = isl.isl_basic_set_to_str(arg0.ptr) + res = cast(ptr, c_char_p).value.decode('ascii') + libc.free(ptr) + return res + def __repr__(self): + s = str(self) + if '"' in s: + return 'isl.basic_set("""%s""")' % s + else: + return 'isl.basic_set("%s")' % s + def affine_hull(arg0): + try: + if not arg0.__class__ is basic_set: + arg0 = basic_set(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_basic_set_affine_hull(isl.isl_basic_set_copy(arg0.ptr)) + obj = basic_set(ctx=ctx, ptr=res) + return obj + def apply(arg0, arg1): + try: + if not arg0.__class__ is basic_set: + arg0 = basic_set(arg0) + except: + raise + try: + if not arg1.__class__ is basic_map: + arg1 = basic_map(arg1) + except: + return set(arg0).apply(arg1) + ctx = arg0.ctx + res = isl.isl_basic_set_apply(isl.isl_basic_set_copy(arg0.ptr), isl.isl_basic_map_copy(arg1.ptr)) + obj = basic_set(ctx=ctx, ptr=res) + return obj + def detect_equalities(arg0): + try: + if not arg0.__class__ is basic_set: + arg0 = basic_set(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_basic_set_detect_equalities(isl.isl_basic_set_copy(arg0.ptr)) + obj = basic_set(ctx=ctx, ptr=res) + return obj + def dim_max_val(arg0, arg1): + try: + if not arg0.__class__ is basic_set: + arg0 = basic_set(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_basic_set_dim_max_val(isl.isl_basic_set_copy(arg0.ptr), arg1) + obj = val(ctx=ctx, ptr=res) + return obj + def flatten(arg0): + try: + if not arg0.__class__ is basic_set: + arg0 = basic_set(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_basic_set_flatten(isl.isl_basic_set_copy(arg0.ptr)) + obj = basic_set(ctx=ctx, ptr=res) + return obj + def gist(arg0, arg1): + try: + if not arg0.__class__ is basic_set: + arg0 = basic_set(arg0) + except: + raise + try: + if not arg1.__class__ is basic_set: + arg1 = basic_set(arg1) + except: + return set(arg0).gist(arg1) + ctx = arg0.ctx + res = isl.isl_basic_set_gist(isl.isl_basic_set_copy(arg0.ptr), isl.isl_basic_set_copy(arg1.ptr)) + obj = basic_set(ctx=ctx, ptr=res) + return obj + def intersect(arg0, arg1): + try: + if not arg0.__class__ is basic_set: + arg0 = basic_set(arg0) + except: + raise + try: + if not arg1.__class__ is basic_set: + arg1 = basic_set(arg1) + except: + return set(arg0).intersect(arg1) + ctx = arg0.ctx + res = isl.isl_basic_set_intersect(isl.isl_basic_set_copy(arg0.ptr), isl.isl_basic_set_copy(arg1.ptr)) + obj = basic_set(ctx=ctx, ptr=res) + return obj + def intersect_params(arg0, arg1): + try: + if not arg0.__class__ is basic_set: + arg0 = basic_set(arg0) + except: + raise + try: + if not arg1.__class__ is basic_set: + arg1 = basic_set(arg1) + except: + return set(arg0).intersect_params(arg1) + ctx = arg0.ctx + res = isl.isl_basic_set_intersect_params(isl.isl_basic_set_copy(arg0.ptr), isl.isl_basic_set_copy(arg1.ptr)) + obj = basic_set(ctx=ctx, ptr=res) + return obj + def is_empty(arg0): + try: + if not arg0.__class__ is basic_set: + arg0 = basic_set(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_basic_set_is_empty(arg0.ptr) + if res < 0: + raise Error + return bool(res) + def is_equal(arg0, arg1): + try: + if not arg0.__class__ is basic_set: + arg0 = basic_set(arg0) + except: + raise + try: + if not arg1.__class__ is basic_set: + arg1 = basic_set(arg1) + except: + return set(arg0).is_equal(arg1) + ctx = arg0.ctx + res = isl.isl_basic_set_is_equal(arg0.ptr, arg1.ptr) + if res < 0: + raise Error + return bool(res) + def is_subset(arg0, arg1): + try: + if not arg0.__class__ is basic_set: + arg0 = basic_set(arg0) + except: + raise + try: + if not arg1.__class__ is basic_set: + arg1 = basic_set(arg1) + except: + return set(arg0).is_subset(arg1) + ctx = arg0.ctx + res = isl.isl_basic_set_is_subset(arg0.ptr, arg1.ptr) + if res < 0: + raise Error + return bool(res) + def is_wrapping(arg0): + try: + if not arg0.__class__ is basic_set: + arg0 = basic_set(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_basic_set_is_wrapping(arg0.ptr) + if res < 0: + raise Error + return bool(res) + def lexmax(arg0): + try: + if not arg0.__class__ is basic_set: + arg0 = basic_set(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_basic_set_lexmax(isl.isl_basic_set_copy(arg0.ptr)) + obj = set(ctx=ctx, ptr=res) + return obj + def lexmin(arg0): + try: + if not arg0.__class__ is basic_set: + arg0 = basic_set(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_basic_set_lexmin(isl.isl_basic_set_copy(arg0.ptr)) + obj = set(ctx=ctx, ptr=res) + return obj + def params(arg0): + try: + if not arg0.__class__ is basic_set: + arg0 = basic_set(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_basic_set_params(isl.isl_basic_set_copy(arg0.ptr)) + obj = basic_set(ctx=ctx, ptr=res) + return obj + def sample(arg0): + try: + if not arg0.__class__ is basic_set: + arg0 = basic_set(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_basic_set_sample(isl.isl_basic_set_copy(arg0.ptr)) + obj = basic_set(ctx=ctx, ptr=res) + return obj + def sample_point(arg0): + try: + if not arg0.__class__ is basic_set: + arg0 = basic_set(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_basic_set_sample_point(isl.isl_basic_set_copy(arg0.ptr)) + obj = point(ctx=ctx, ptr=res) + return obj + def to_set(arg0): + try: + if not arg0.__class__ is basic_set: + arg0 = basic_set(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_basic_set_to_set(isl.isl_basic_set_copy(arg0.ptr)) + obj = set(ctx=ctx, ptr=res) + return obj + def union(arg0, arg1): + try: + if not arg0.__class__ is basic_set: + arg0 = basic_set(arg0) + except: + raise + try: + if not arg1.__class__ is basic_set: + arg1 = basic_set(arg1) + except: + return set(arg0).union(arg1) + ctx = arg0.ctx + res = isl.isl_basic_set_union(isl.isl_basic_set_copy(arg0.ptr), isl.isl_basic_set_copy(arg1.ptr)) + obj = set(ctx=ctx, ptr=res) + return obj + +isl.isl_basic_set_from_point.restype = c_void_p +isl.isl_basic_set_from_point.argtypes = [c_void_p] +isl.isl_basic_set_read_from_str.restype = c_void_p +isl.isl_basic_set_read_from_str.argtypes = [Context, c_char_p] +isl.isl_basic_set_affine_hull.restype = c_void_p +isl.isl_basic_set_affine_hull.argtypes = [c_void_p] +isl.isl_basic_set_apply.restype = c_void_p +isl.isl_basic_set_apply.argtypes = [c_void_p, c_void_p] +isl.isl_basic_set_detect_equalities.restype = c_void_p +isl.isl_basic_set_detect_equalities.argtypes = [c_void_p] +isl.isl_basic_set_dim_max_val.restype = c_void_p +isl.isl_basic_set_dim_max_val.argtypes = [c_void_p, c_int] +isl.isl_basic_set_flatten.restype = c_void_p +isl.isl_basic_set_flatten.argtypes = [c_void_p] +isl.isl_basic_set_gist.restype = c_void_p +isl.isl_basic_set_gist.argtypes = [c_void_p, c_void_p] +isl.isl_basic_set_intersect.restype = c_void_p +isl.isl_basic_set_intersect.argtypes = [c_void_p, c_void_p] +isl.isl_basic_set_intersect_params.restype = c_void_p +isl.isl_basic_set_intersect_params.argtypes = [c_void_p, c_void_p] +isl.isl_basic_set_is_empty.argtypes = [c_void_p] +isl.isl_basic_set_is_equal.argtypes = [c_void_p, c_void_p] +isl.isl_basic_set_is_subset.argtypes = [c_void_p, c_void_p] +isl.isl_basic_set_is_wrapping.argtypes = [c_void_p] +isl.isl_basic_set_lexmax.restype = c_void_p +isl.isl_basic_set_lexmax.argtypes = [c_void_p] +isl.isl_basic_set_lexmin.restype = c_void_p +isl.isl_basic_set_lexmin.argtypes = [c_void_p] +isl.isl_basic_set_params.restype = c_void_p +isl.isl_basic_set_params.argtypes = [c_void_p] +isl.isl_basic_set_sample.restype = c_void_p +isl.isl_basic_set_sample.argtypes = [c_void_p] +isl.isl_basic_set_sample_point.restype = c_void_p +isl.isl_basic_set_sample_point.argtypes = [c_void_p] +isl.isl_basic_set_to_set.restype = c_void_p +isl.isl_basic_set_to_set.argtypes = [c_void_p] +isl.isl_basic_set_union.restype = c_void_p +isl.isl_basic_set_union.argtypes = [c_void_p, c_void_p] +isl.isl_basic_set_copy.restype = c_void_p +isl.isl_basic_set_copy.argtypes = [c_void_p] +isl.isl_basic_set_free.restype = c_void_p +isl.isl_basic_set_free.argtypes = [c_void_p] +isl.isl_basic_set_to_str.restype = POINTER(c_char) +isl.isl_basic_set_to_str.argtypes = [c_void_p] + +class fixed_box(object): + def __init__(self, *args, **keywords): + if "ptr" in keywords: + self.ctx = keywords["ctx"] + self.ptr = keywords["ptr"] + return + if len(args) == 1 and type(args[0]) == str: + self.ctx = Context.getDefaultInstance() + self.ptr = isl.isl_fixed_box_read_from_str(self.ctx, args[0].encode('ascii')) + return + raise Error + def __del__(self): + if hasattr(self, 'ptr'): + isl.isl_fixed_box_free(self.ptr) + def __str__(arg0): + try: + if not arg0.__class__ is fixed_box: + arg0 = fixed_box(arg0) + except: + raise + ptr = isl.isl_fixed_box_to_str(arg0.ptr) + res = cast(ptr, c_char_p).value.decode('ascii') + libc.free(ptr) + return res + def __repr__(self): + s = str(self) + if '"' in s: + return 'isl.fixed_box("""%s""")' % s + else: + return 'isl.fixed_box("%s")' % s + def is_valid(arg0): + try: + if not arg0.__class__ is fixed_box: + arg0 = fixed_box(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_fixed_box_is_valid(arg0.ptr) + if res < 0: + raise Error + return bool(res) + def offset(arg0): + try: + if not arg0.__class__ is fixed_box: + arg0 = fixed_box(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_fixed_box_get_offset(arg0.ptr) + obj = multi_aff(ctx=ctx, ptr=res) + return obj + def get_offset(arg0): + return arg0.offset() + def size(arg0): + try: + if not arg0.__class__ is fixed_box: + arg0 = fixed_box(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_fixed_box_get_size(arg0.ptr) + obj = multi_val(ctx=ctx, ptr=res) + return obj + def get_size(arg0): + return arg0.size() + def space(arg0): + try: + if not arg0.__class__ is fixed_box: + arg0 = fixed_box(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_fixed_box_get_space(arg0.ptr) + obj = space(ctx=ctx, ptr=res) + return obj + def get_space(arg0): + return arg0.space() + +isl.isl_fixed_box_read_from_str.restype = c_void_p +isl.isl_fixed_box_read_from_str.argtypes = [Context, c_char_p] +isl.isl_fixed_box_is_valid.argtypes = [c_void_p] +isl.isl_fixed_box_get_offset.restype = c_void_p +isl.isl_fixed_box_get_offset.argtypes = [c_void_p] +isl.isl_fixed_box_get_size.restype = c_void_p +isl.isl_fixed_box_get_size.argtypes = [c_void_p] +isl.isl_fixed_box_get_space.restype = c_void_p +isl.isl_fixed_box_get_space.argtypes = [c_void_p] +isl.isl_fixed_box_copy.restype = c_void_p +isl.isl_fixed_box_copy.argtypes = [c_void_p] +isl.isl_fixed_box_free.restype = c_void_p +isl.isl_fixed_box_free.argtypes = [c_void_p] +isl.isl_fixed_box_to_str.restype = POINTER(c_char) +isl.isl_fixed_box_to_str.argtypes = [c_void_p] + +class id(object): + def __init__(self, *args, **keywords): + if "ptr" in keywords: + self.ctx = keywords["ctx"] + self.ptr = keywords["ptr"] + return + if len(args) == 1 and type(args[0]) == str: + self.ctx = Context.getDefaultInstance() + self.ptr = isl.isl_id_read_from_str(self.ctx, args[0].encode('ascii')) + return + if len(args) == 2 and type(args[0]) == str: + self.ctx = Context.getDefaultInstance() + name = args[0].encode('ascii') + self.ptr = isl.isl_id_alloc(self.ctx, name, args[1]) + self.ptr = isl.isl_id_set_free_user(self.ptr, Context.free_user) + if self.ptr is not None: + pythonapi.Py_IncRef(py_object(args[1])) + return + raise Error + def __del__(self): + if hasattr(self, 'ptr'): + isl.isl_id_free(self.ptr) + def __str__(arg0): + try: + if not arg0.__class__ is id: + arg0 = id(arg0) + except: + raise + ptr = isl.isl_id_to_str(arg0.ptr) + res = cast(ptr, c_char_p).value.decode('ascii') + libc.free(ptr) + return res + def __repr__(self): + s = str(self) + if '"' in s: + return 'isl.id("""%s""")' % s + else: + return 'isl.id("%s")' % s + def user(self): + free_user = cast(Context.free_user, c_void_p) + id_free_user = cast(isl.isl_id_get_free_user(self.ptr), c_void_p) + if id_free_user.value != free_user.value: + return None + return isl.isl_id_get_user(self.ptr) + def name(arg0): + try: + if not arg0.__class__ is id: + arg0 = id(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_id_get_name(arg0.ptr) + if res == 0: + raise Error + string = cast(res, c_char_p).value.decode('ascii') + return string + def get_name(arg0): + return arg0.name() + def to_list(arg0): + try: + if not arg0.__class__ is id: + arg0 = id(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_id_to_list(isl.isl_id_copy(arg0.ptr)) + obj = id_list(ctx=ctx, ptr=res) + return obj + +isl.isl_id_read_from_str.restype = c_void_p +isl.isl_id_read_from_str.argtypes = [Context, c_char_p] +isl.isl_id_get_name.restype = POINTER(c_char) +isl.isl_id_get_name.argtypes = [c_void_p] +isl.isl_id_to_list.restype = c_void_p +isl.isl_id_to_list.argtypes = [c_void_p] +isl.isl_id_copy.restype = c_void_p +isl.isl_id_copy.argtypes = [c_void_p] +isl.isl_id_free.restype = c_void_p +isl.isl_id_free.argtypes = [c_void_p] +isl.isl_id_to_str.restype = POINTER(c_char) +isl.isl_id_to_str.argtypes = [c_void_p] + +class id_list(object): + def __init__(self, *args, **keywords): + if "ptr" in keywords: + self.ctx = keywords["ctx"] + self.ptr = keywords["ptr"] + return + if len(args) == 1 and type(args[0]) == int: + self.ctx = Context.getDefaultInstance() + self.ptr = isl.isl_id_list_alloc(self.ctx, args[0]) + return + if len(args) == 1 and (args[0].__class__ is id or type(args[0]) == str): + args = list(args) + try: + if not args[0].__class__ is id: + args[0] = id(args[0]) + except: + raise + self.ctx = Context.getDefaultInstance() + self.ptr = isl.isl_id_list_from_id(isl.isl_id_copy(args[0].ptr)) + return + if len(args) == 1 and type(args[0]) == str: + self.ctx = Context.getDefaultInstance() + self.ptr = isl.isl_id_list_read_from_str(self.ctx, args[0].encode('ascii')) + return + raise Error + def __del__(self): + if hasattr(self, 'ptr'): + isl.isl_id_list_free(self.ptr) + def __str__(arg0): + try: + if not arg0.__class__ is id_list: + arg0 = id_list(arg0) + except: + raise + ptr = isl.isl_id_list_to_str(arg0.ptr) + res = cast(ptr, c_char_p).value.decode('ascii') + libc.free(ptr) + return res + def __repr__(self): + s = str(self) + if '"' in s: + return 'isl.id_list("""%s""")' % s + else: + return 'isl.id_list("%s")' % s + def add(arg0, arg1): + try: + if not arg0.__class__ is id_list: + arg0 = id_list(arg0) + except: + raise + try: + if not arg1.__class__ is id: + arg1 = id(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_id_list_add(isl.isl_id_list_copy(arg0.ptr), isl.isl_id_copy(arg1.ptr)) + obj = id_list(ctx=ctx, ptr=res) + return obj + def at(arg0, arg1): + try: + if not arg0.__class__ is id_list: + arg0 = id_list(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_id_list_get_at(arg0.ptr, arg1) + obj = id(ctx=ctx, ptr=res) + return obj + def get_at(arg0, arg1): + return arg0.at(arg1) + def clear(arg0): + try: + if not arg0.__class__ is id_list: + arg0 = id_list(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_id_list_clear(isl.isl_id_list_copy(arg0.ptr)) + obj = id_list(ctx=ctx, ptr=res) + return obj + def concat(arg0, arg1): + try: + if not arg0.__class__ is id_list: + arg0 = id_list(arg0) + except: + raise + try: + if not arg1.__class__ is id_list: + arg1 = id_list(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_id_list_concat(isl.isl_id_list_copy(arg0.ptr), isl.isl_id_list_copy(arg1.ptr)) + obj = id_list(ctx=ctx, ptr=res) + return obj + def drop(arg0, arg1, arg2): + try: + if not arg0.__class__ is id_list: + arg0 = id_list(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_id_list_drop(isl.isl_id_list_copy(arg0.ptr), arg1, arg2) + obj = id_list(ctx=ctx, ptr=res) + return obj + def foreach(arg0, arg1): + try: + if not arg0.__class__ is id_list: + arg0 = id_list(arg0) + except: + raise + exc_info = [None] + fn = CFUNCTYPE(c_int, c_void_p, c_void_p) + def cb_func(cb_arg0, cb_arg1): + cb_arg0 = id(ctx=arg0.ctx, ptr=(cb_arg0)) + try: + arg1(cb_arg0) + except BaseException as e: + exc_info[0] = e + return -1 + return 0 + cb1 = fn(cb_func) + ctx = arg0.ctx + res = isl.isl_id_list_foreach(arg0.ptr, cb1, None) + if exc_info[0] is not None: + raise exc_info[0] + if res < 0: + raise Error + def foreach_scc(arg0, arg1, arg2): + try: + if not arg0.__class__ is id_list: + arg0 = id_list(arg0) + except: + raise + exc_info = [None] + fn = CFUNCTYPE(c_int, c_void_p, c_void_p, c_void_p) + def cb_func(cb_arg0, cb_arg1, cb_arg2): + cb_arg0 = id(ctx=arg0.ctx, ptr=isl.isl_id_copy(cb_arg0)) + cb_arg1 = id(ctx=arg0.ctx, ptr=isl.isl_id_copy(cb_arg1)) + try: + res = arg1(cb_arg0, cb_arg1) + except BaseException as e: + exc_info[0] = e + return -1 + return 1 if res else 0 + cb1 = fn(cb_func) + exc_info = [None] + fn = CFUNCTYPE(c_int, c_void_p, c_void_p) + def cb_func(cb_arg0, cb_arg1): + cb_arg0 = id_list(ctx=arg0.ctx, ptr=(cb_arg0)) + try: + arg2(cb_arg0) + except BaseException as e: + exc_info[0] = e + return -1 + return 0 + cb2 = fn(cb_func) + ctx = arg0.ctx + res = isl.isl_id_list_foreach_scc(arg0.ptr, cb1, None, cb2, None) + if exc_info[0] is not None: + raise exc_info[0] + if res < 0: + raise Error + def insert(arg0, arg1, arg2): + try: + if not arg0.__class__ is id_list: + arg0 = id_list(arg0) + except: + raise + try: + if not arg2.__class__ is id: + arg2 = id(arg2) + except: + raise + ctx = arg0.ctx + res = isl.isl_id_list_insert(isl.isl_id_list_copy(arg0.ptr), arg1, isl.isl_id_copy(arg2.ptr)) + obj = id_list(ctx=ctx, ptr=res) + return obj + def set_at(arg0, arg1, arg2): + try: + if not arg0.__class__ is id_list: + arg0 = id_list(arg0) + except: + raise + try: + if not arg2.__class__ is id: + arg2 = id(arg2) + except: + raise + ctx = arg0.ctx + res = isl.isl_id_list_set_at(isl.isl_id_list_copy(arg0.ptr), arg1, isl.isl_id_copy(arg2.ptr)) + obj = id_list(ctx=ctx, ptr=res) + return obj + def size(arg0): + try: + if not arg0.__class__ is id_list: + arg0 = id_list(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_id_list_size(arg0.ptr) + if res < 0: + raise Error + return int(res) + +isl.isl_id_list_alloc.restype = c_void_p +isl.isl_id_list_alloc.argtypes = [Context, c_int] +isl.isl_id_list_from_id.restype = c_void_p +isl.isl_id_list_from_id.argtypes = [c_void_p] +isl.isl_id_list_read_from_str.restype = c_void_p +isl.isl_id_list_read_from_str.argtypes = [Context, c_char_p] +isl.isl_id_list_add.restype = c_void_p +isl.isl_id_list_add.argtypes = [c_void_p, c_void_p] +isl.isl_id_list_get_at.restype = c_void_p +isl.isl_id_list_get_at.argtypes = [c_void_p, c_int] +isl.isl_id_list_clear.restype = c_void_p +isl.isl_id_list_clear.argtypes = [c_void_p] +isl.isl_id_list_concat.restype = c_void_p +isl.isl_id_list_concat.argtypes = [c_void_p, c_void_p] +isl.isl_id_list_drop.restype = c_void_p +isl.isl_id_list_drop.argtypes = [c_void_p, c_int, c_int] +isl.isl_id_list_foreach.argtypes = [c_void_p, c_void_p, c_void_p] +isl.isl_id_list_foreach_scc.argtypes = [c_void_p, c_void_p, c_void_p, c_void_p, c_void_p] +isl.isl_id_list_insert.restype = c_void_p +isl.isl_id_list_insert.argtypes = [c_void_p, c_int, c_void_p] +isl.isl_id_list_set_at.restype = c_void_p +isl.isl_id_list_set_at.argtypes = [c_void_p, c_int, c_void_p] +isl.isl_id_list_size.argtypes = [c_void_p] +isl.isl_id_list_copy.restype = c_void_p +isl.isl_id_list_copy.argtypes = [c_void_p] +isl.isl_id_list_free.restype = c_void_p +isl.isl_id_list_free.argtypes = [c_void_p] +isl.isl_id_list_to_str.restype = POINTER(c_char) +isl.isl_id_list_to_str.argtypes = [c_void_p] + +class id_to_ast_expr(object): + def __init__(self, *args, **keywords): + if "ptr" in keywords: + self.ctx = keywords["ctx"] + self.ptr = keywords["ptr"] + return + if len(args) == 1 and type(args[0]) == int: + self.ctx = Context.getDefaultInstance() + self.ptr = isl.isl_id_to_ast_expr_alloc(self.ctx, args[0]) + return + if len(args) == 1 and type(args[0]) == str: + self.ctx = Context.getDefaultInstance() + self.ptr = isl.isl_id_to_ast_expr_read_from_str(self.ctx, args[0].encode('ascii')) + return + raise Error + def __del__(self): + if hasattr(self, 'ptr'): + isl.isl_id_to_ast_expr_free(self.ptr) + def __str__(arg0): + try: + if not arg0.__class__ is id_to_ast_expr: + arg0 = id_to_ast_expr(arg0) + except: + raise + ptr = isl.isl_id_to_ast_expr_to_str(arg0.ptr) + res = cast(ptr, c_char_p).value.decode('ascii') + libc.free(ptr) + return res + def __repr__(self): + s = str(self) + if '"' in s: + return 'isl.id_to_ast_expr("""%s""")' % s + else: + return 'isl.id_to_ast_expr("%s")' % s + def is_equal(arg0, arg1): + try: + if not arg0.__class__ is id_to_ast_expr: + arg0 = id_to_ast_expr(arg0) + except: + raise + try: + if not arg1.__class__ is id_to_ast_expr: + arg1 = id_to_ast_expr(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_id_to_ast_expr_is_equal(arg0.ptr, arg1.ptr) + if res < 0: + raise Error + return bool(res) + def set(arg0, arg1, arg2): + try: + if not arg0.__class__ is id_to_ast_expr: + arg0 = id_to_ast_expr(arg0) + except: + raise + try: + if not arg1.__class__ is id: + arg1 = id(arg1) + except: + raise + try: + if not arg2.__class__ is ast_expr: + arg2 = ast_expr(arg2) + except: + raise + ctx = arg0.ctx + res = isl.isl_id_to_ast_expr_set(isl.isl_id_to_ast_expr_copy(arg0.ptr), isl.isl_id_copy(arg1.ptr), isl.isl_ast_expr_copy(arg2.ptr)) + obj = id_to_ast_expr(ctx=ctx, ptr=res) + return obj + +isl.isl_id_to_ast_expr_alloc.restype = c_void_p +isl.isl_id_to_ast_expr_alloc.argtypes = [Context, c_int] +isl.isl_id_to_ast_expr_read_from_str.restype = c_void_p +isl.isl_id_to_ast_expr_read_from_str.argtypes = [Context, c_char_p] +isl.isl_id_to_ast_expr_is_equal.argtypes = [c_void_p, c_void_p] +isl.isl_id_to_ast_expr_set.restype = c_void_p +isl.isl_id_to_ast_expr_set.argtypes = [c_void_p, c_void_p, c_void_p] +isl.isl_id_to_ast_expr_copy.restype = c_void_p +isl.isl_id_to_ast_expr_copy.argtypes = [c_void_p] +isl.isl_id_to_ast_expr_free.restype = c_void_p +isl.isl_id_to_ast_expr_free.argtypes = [c_void_p] +isl.isl_id_to_ast_expr_to_str.restype = POINTER(c_char) +isl.isl_id_to_ast_expr_to_str.argtypes = [c_void_p] + +class id_to_id(object): + def __init__(self, *args, **keywords): + if "ptr" in keywords: + self.ctx = keywords["ctx"] + self.ptr = keywords["ptr"] + return + if len(args) == 1 and type(args[0]) == int: + self.ctx = Context.getDefaultInstance() + self.ptr = isl.isl_id_to_id_alloc(self.ctx, args[0]) + return + if len(args) == 1 and type(args[0]) == str: + self.ctx = Context.getDefaultInstance() + self.ptr = isl.isl_id_to_id_read_from_str(self.ctx, args[0].encode('ascii')) + return + raise Error + def __del__(self): + if hasattr(self, 'ptr'): + isl.isl_id_to_id_free(self.ptr) + def __str__(arg0): + try: + if not arg0.__class__ is id_to_id: + arg0 = id_to_id(arg0) + except: + raise + ptr = isl.isl_id_to_id_to_str(arg0.ptr) + res = cast(ptr, c_char_p).value.decode('ascii') + libc.free(ptr) + return res + def __repr__(self): + s = str(self) + if '"' in s: + return 'isl.id_to_id("""%s""")' % s + else: + return 'isl.id_to_id("%s")' % s + def is_equal(arg0, arg1): + try: + if not arg0.__class__ is id_to_id: + arg0 = id_to_id(arg0) + except: + raise + try: + if not arg1.__class__ is id_to_id: + arg1 = id_to_id(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_id_to_id_is_equal(arg0.ptr, arg1.ptr) + if res < 0: + raise Error + return bool(res) + def set(arg0, arg1, arg2): + try: + if not arg0.__class__ is id_to_id: + arg0 = id_to_id(arg0) + except: + raise + try: + if not arg1.__class__ is id: + arg1 = id(arg1) + except: + raise + try: + if not arg2.__class__ is id: + arg2 = id(arg2) + except: + raise + ctx = arg0.ctx + res = isl.isl_id_to_id_set(isl.isl_id_to_id_copy(arg0.ptr), isl.isl_id_copy(arg1.ptr), isl.isl_id_copy(arg2.ptr)) + obj = id_to_id(ctx=ctx, ptr=res) + return obj + +isl.isl_id_to_id_alloc.restype = c_void_p +isl.isl_id_to_id_alloc.argtypes = [Context, c_int] +isl.isl_id_to_id_read_from_str.restype = c_void_p +isl.isl_id_to_id_read_from_str.argtypes = [Context, c_char_p] +isl.isl_id_to_id_is_equal.argtypes = [c_void_p, c_void_p] +isl.isl_id_to_id_set.restype = c_void_p +isl.isl_id_to_id_set.argtypes = [c_void_p, c_void_p, c_void_p] +isl.isl_id_to_id_copy.restype = c_void_p +isl.isl_id_to_id_copy.argtypes = [c_void_p] +isl.isl_id_to_id_free.restype = c_void_p +isl.isl_id_to_id_free.argtypes = [c_void_p] +isl.isl_id_to_id_to_str.restype = POINTER(c_char) +isl.isl_id_to_id_to_str.argtypes = [c_void_p] + +class map_list(object): + def __init__(self, *args, **keywords): + if "ptr" in keywords: + self.ctx = keywords["ctx"] + self.ptr = keywords["ptr"] + return + if len(args) == 1 and type(args[0]) == int: + self.ctx = Context.getDefaultInstance() + self.ptr = isl.isl_map_list_alloc(self.ctx, args[0]) + return + if len(args) == 1 and args[0].__class__ is map: + self.ctx = Context.getDefaultInstance() + self.ptr = isl.isl_map_list_from_map(isl.isl_map_copy(args[0].ptr)) + return + if len(args) == 1 and type(args[0]) == str: + self.ctx = Context.getDefaultInstance() + self.ptr = isl.isl_map_list_read_from_str(self.ctx, args[0].encode('ascii')) + return + raise Error + def __del__(self): + if hasattr(self, 'ptr'): + isl.isl_map_list_free(self.ptr) + def __str__(arg0): + try: + if not arg0.__class__ is map_list: + arg0 = map_list(arg0) + except: + raise + ptr = isl.isl_map_list_to_str(arg0.ptr) + res = cast(ptr, c_char_p).value.decode('ascii') + libc.free(ptr) + return res + def __repr__(self): + s = str(self) + if '"' in s: + return 'isl.map_list("""%s""")' % s + else: + return 'isl.map_list("%s")' % s + def add(arg0, arg1): + try: + if not arg0.__class__ is map_list: + arg0 = map_list(arg0) + except: + raise + try: + if not arg1.__class__ is map: + arg1 = map(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_map_list_add(isl.isl_map_list_copy(arg0.ptr), isl.isl_map_copy(arg1.ptr)) + obj = map_list(ctx=ctx, ptr=res) + return obj + def at(arg0, arg1): + try: + if not arg0.__class__ is map_list: + arg0 = map_list(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_map_list_get_at(arg0.ptr, arg1) + obj = map(ctx=ctx, ptr=res) + return obj + def get_at(arg0, arg1): + return arg0.at(arg1) + def clear(arg0): + try: + if not arg0.__class__ is map_list: + arg0 = map_list(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_map_list_clear(isl.isl_map_list_copy(arg0.ptr)) + obj = map_list(ctx=ctx, ptr=res) + return obj + def concat(arg0, arg1): + try: + if not arg0.__class__ is map_list: + arg0 = map_list(arg0) + except: + raise + try: + if not arg1.__class__ is map_list: + arg1 = map_list(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_map_list_concat(isl.isl_map_list_copy(arg0.ptr), isl.isl_map_list_copy(arg1.ptr)) + obj = map_list(ctx=ctx, ptr=res) + return obj + def drop(arg0, arg1, arg2): + try: + if not arg0.__class__ is map_list: + arg0 = map_list(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_map_list_drop(isl.isl_map_list_copy(arg0.ptr), arg1, arg2) + obj = map_list(ctx=ctx, ptr=res) + return obj + def foreach(arg0, arg1): + try: + if not arg0.__class__ is map_list: + arg0 = map_list(arg0) + except: + raise + exc_info = [None] + fn = CFUNCTYPE(c_int, c_void_p, c_void_p) + def cb_func(cb_arg0, cb_arg1): + cb_arg0 = map(ctx=arg0.ctx, ptr=(cb_arg0)) + try: + arg1(cb_arg0) + except BaseException as e: + exc_info[0] = e + return -1 + return 0 + cb1 = fn(cb_func) + ctx = arg0.ctx + res = isl.isl_map_list_foreach(arg0.ptr, cb1, None) + if exc_info[0] is not None: + raise exc_info[0] + if res < 0: + raise Error + def foreach_scc(arg0, arg1, arg2): + try: + if not arg0.__class__ is map_list: + arg0 = map_list(arg0) + except: + raise + exc_info = [None] + fn = CFUNCTYPE(c_int, c_void_p, c_void_p, c_void_p) + def cb_func(cb_arg0, cb_arg1, cb_arg2): + cb_arg0 = map(ctx=arg0.ctx, ptr=isl.isl_map_copy(cb_arg0)) + cb_arg1 = map(ctx=arg0.ctx, ptr=isl.isl_map_copy(cb_arg1)) + try: + res = arg1(cb_arg0, cb_arg1) + except BaseException as e: + exc_info[0] = e + return -1 + return 1 if res else 0 + cb1 = fn(cb_func) + exc_info = [None] + fn = CFUNCTYPE(c_int, c_void_p, c_void_p) + def cb_func(cb_arg0, cb_arg1): + cb_arg0 = map_list(ctx=arg0.ctx, ptr=(cb_arg0)) + try: + arg2(cb_arg0) + except BaseException as e: + exc_info[0] = e + return -1 + return 0 + cb2 = fn(cb_func) + ctx = arg0.ctx + res = isl.isl_map_list_foreach_scc(arg0.ptr, cb1, None, cb2, None) + if exc_info[0] is not None: + raise exc_info[0] + if res < 0: + raise Error + def insert(arg0, arg1, arg2): + try: + if not arg0.__class__ is map_list: + arg0 = map_list(arg0) + except: + raise + try: + if not arg2.__class__ is map: + arg2 = map(arg2) + except: + raise + ctx = arg0.ctx + res = isl.isl_map_list_insert(isl.isl_map_list_copy(arg0.ptr), arg1, isl.isl_map_copy(arg2.ptr)) + obj = map_list(ctx=ctx, ptr=res) + return obj + def set_at(arg0, arg1, arg2): + try: + if not arg0.__class__ is map_list: + arg0 = map_list(arg0) + except: + raise + try: + if not arg2.__class__ is map: + arg2 = map(arg2) + except: + raise + ctx = arg0.ctx + res = isl.isl_map_list_set_at(isl.isl_map_list_copy(arg0.ptr), arg1, isl.isl_map_copy(arg2.ptr)) + obj = map_list(ctx=ctx, ptr=res) + return obj + def size(arg0): + try: + if not arg0.__class__ is map_list: + arg0 = map_list(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_map_list_size(arg0.ptr) + if res < 0: + raise Error + return int(res) + +isl.isl_map_list_alloc.restype = c_void_p +isl.isl_map_list_alloc.argtypes = [Context, c_int] +isl.isl_map_list_from_map.restype = c_void_p +isl.isl_map_list_from_map.argtypes = [c_void_p] +isl.isl_map_list_read_from_str.restype = c_void_p +isl.isl_map_list_read_from_str.argtypes = [Context, c_char_p] +isl.isl_map_list_add.restype = c_void_p +isl.isl_map_list_add.argtypes = [c_void_p, c_void_p] +isl.isl_map_list_get_at.restype = c_void_p +isl.isl_map_list_get_at.argtypes = [c_void_p, c_int] +isl.isl_map_list_clear.restype = c_void_p +isl.isl_map_list_clear.argtypes = [c_void_p] +isl.isl_map_list_concat.restype = c_void_p +isl.isl_map_list_concat.argtypes = [c_void_p, c_void_p] +isl.isl_map_list_drop.restype = c_void_p +isl.isl_map_list_drop.argtypes = [c_void_p, c_int, c_int] +isl.isl_map_list_foreach.argtypes = [c_void_p, c_void_p, c_void_p] +isl.isl_map_list_foreach_scc.argtypes = [c_void_p, c_void_p, c_void_p, c_void_p, c_void_p] +isl.isl_map_list_insert.restype = c_void_p +isl.isl_map_list_insert.argtypes = [c_void_p, c_int, c_void_p] +isl.isl_map_list_set_at.restype = c_void_p +isl.isl_map_list_set_at.argtypes = [c_void_p, c_int, c_void_p] +isl.isl_map_list_size.argtypes = [c_void_p] +isl.isl_map_list_copy.restype = c_void_p +isl.isl_map_list_copy.argtypes = [c_void_p] +isl.isl_map_list_free.restype = c_void_p +isl.isl_map_list_free.argtypes = [c_void_p] +isl.isl_map_list_to_str.restype = POINTER(c_char) +isl.isl_map_list_to_str.argtypes = [c_void_p] + +class multi_id(object): + def __init__(self, *args, **keywords): + if "ptr" in keywords: + self.ctx = keywords["ctx"] + self.ptr = keywords["ptr"] + return + if len(args) == 2 and args[0].__class__ is space and args[1].__class__ is id_list: + self.ctx = Context.getDefaultInstance() + self.ptr = isl.isl_multi_id_from_id_list(isl.isl_space_copy(args[0].ptr), isl.isl_id_list_copy(args[1].ptr)) + return + if len(args) == 1 and type(args[0]) == str: + self.ctx = Context.getDefaultInstance() + self.ptr = isl.isl_multi_id_read_from_str(self.ctx, args[0].encode('ascii')) + return + raise Error + def __del__(self): + if hasattr(self, 'ptr'): + isl.isl_multi_id_free(self.ptr) + def __str__(arg0): + try: + if not arg0.__class__ is multi_id: + arg0 = multi_id(arg0) + except: + raise + ptr = isl.isl_multi_id_to_str(arg0.ptr) + res = cast(ptr, c_char_p).value.decode('ascii') + libc.free(ptr) + return res + def __repr__(self): + s = str(self) + if '"' in s: + return 'isl.multi_id("""%s""")' % s + else: + return 'isl.multi_id("%s")' % s + def at(arg0, arg1): + try: + if not arg0.__class__ is multi_id: + arg0 = multi_id(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_multi_id_get_at(arg0.ptr, arg1) + obj = id(ctx=ctx, ptr=res) + return obj + def get_at(arg0, arg1): + return arg0.at(arg1) + def flat_range_product(arg0, arg1): + try: + if not arg0.__class__ is multi_id: + arg0 = multi_id(arg0) + except: + raise + try: + if not arg1.__class__ is multi_id: + arg1 = multi_id(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_multi_id_flat_range_product(isl.isl_multi_id_copy(arg0.ptr), isl.isl_multi_id_copy(arg1.ptr)) + obj = multi_id(ctx=ctx, ptr=res) + return obj + def list(arg0): + try: + if not arg0.__class__ is multi_id: + arg0 = multi_id(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_multi_id_get_list(arg0.ptr) + obj = id_list(ctx=ctx, ptr=res) + return obj + def get_list(arg0): + return arg0.list() + def plain_is_equal(arg0, arg1): + try: + if not arg0.__class__ is multi_id: + arg0 = multi_id(arg0) + except: + raise + try: + if not arg1.__class__ is multi_id: + arg1 = multi_id(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_multi_id_plain_is_equal(arg0.ptr, arg1.ptr) + if res < 0: + raise Error + return bool(res) + def range_product(arg0, arg1): + try: + if not arg0.__class__ is multi_id: + arg0 = multi_id(arg0) + except: + raise + try: + if not arg1.__class__ is multi_id: + arg1 = multi_id(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_multi_id_range_product(isl.isl_multi_id_copy(arg0.ptr), isl.isl_multi_id_copy(arg1.ptr)) + obj = multi_id(ctx=ctx, ptr=res) + return obj + def set_at(arg0, arg1, arg2): + try: + if not arg0.__class__ is multi_id: + arg0 = multi_id(arg0) + except: + raise + try: + if not arg2.__class__ is id: + arg2 = id(arg2) + except: + raise + ctx = arg0.ctx + res = isl.isl_multi_id_set_at(isl.isl_multi_id_copy(arg0.ptr), arg1, isl.isl_id_copy(arg2.ptr)) + obj = multi_id(ctx=ctx, ptr=res) + return obj + def size(arg0): + try: + if not arg0.__class__ is multi_id: + arg0 = multi_id(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_multi_id_size(arg0.ptr) + if res < 0: + raise Error + return int(res) + def space(arg0): + try: + if not arg0.__class__ is multi_id: + arg0 = multi_id(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_multi_id_get_space(arg0.ptr) + obj = space(ctx=ctx, ptr=res) + return obj + def get_space(arg0): + return arg0.space() + +isl.isl_multi_id_from_id_list.restype = c_void_p +isl.isl_multi_id_from_id_list.argtypes = [c_void_p, c_void_p] +isl.isl_multi_id_read_from_str.restype = c_void_p +isl.isl_multi_id_read_from_str.argtypes = [Context, c_char_p] +isl.isl_multi_id_get_at.restype = c_void_p +isl.isl_multi_id_get_at.argtypes = [c_void_p, c_int] +isl.isl_multi_id_flat_range_product.restype = c_void_p +isl.isl_multi_id_flat_range_product.argtypes = [c_void_p, c_void_p] +isl.isl_multi_id_get_list.restype = c_void_p +isl.isl_multi_id_get_list.argtypes = [c_void_p] +isl.isl_multi_id_plain_is_equal.argtypes = [c_void_p, c_void_p] +isl.isl_multi_id_range_product.restype = c_void_p +isl.isl_multi_id_range_product.argtypes = [c_void_p, c_void_p] +isl.isl_multi_id_set_at.restype = c_void_p +isl.isl_multi_id_set_at.argtypes = [c_void_p, c_int, c_void_p] +isl.isl_multi_id_size.argtypes = [c_void_p] +isl.isl_multi_id_get_space.restype = c_void_p +isl.isl_multi_id_get_space.argtypes = [c_void_p] +isl.isl_multi_id_copy.restype = c_void_p +isl.isl_multi_id_copy.argtypes = [c_void_p] +isl.isl_multi_id_free.restype = c_void_p +isl.isl_multi_id_free.argtypes = [c_void_p] +isl.isl_multi_id_to_str.restype = POINTER(c_char) +isl.isl_multi_id_to_str.argtypes = [c_void_p] + +class multi_val(object): + def __init__(self, *args, **keywords): + if "ptr" in keywords: + self.ctx = keywords["ctx"] + self.ptr = keywords["ptr"] + return + if len(args) == 2 and args[0].__class__ is space and args[1].__class__ is val_list: + self.ctx = Context.getDefaultInstance() + self.ptr = isl.isl_multi_val_from_val_list(isl.isl_space_copy(args[0].ptr), isl.isl_val_list_copy(args[1].ptr)) + return + if len(args) == 1 and type(args[0]) == str: + self.ctx = Context.getDefaultInstance() + self.ptr = isl.isl_multi_val_read_from_str(self.ctx, args[0].encode('ascii')) + return + raise Error + def __del__(self): + if hasattr(self, 'ptr'): + isl.isl_multi_val_free(self.ptr) + def __str__(arg0): + try: + if not arg0.__class__ is multi_val: + arg0 = multi_val(arg0) + except: + raise + ptr = isl.isl_multi_val_to_str(arg0.ptr) + res = cast(ptr, c_char_p).value.decode('ascii') + libc.free(ptr) + return res + def __repr__(self): + s = str(self) + if '"' in s: + return 'isl.multi_val("""%s""")' % s + else: + return 'isl.multi_val("%s")' % s + def add(*args): + if len(args) == 2 and args[1].__class__ is multi_val: + args = list(args) + try: + if not args[0].__class__ is multi_val: + args[0] = multi_val(args[0]) + except: + raise + ctx = args[0].ctx + res = isl.isl_multi_val_add(isl.isl_multi_val_copy(args[0].ptr), isl.isl_multi_val_copy(args[1].ptr)) + obj = multi_val(ctx=ctx, ptr=res) + return obj + if len(args) == 2 and (args[1].__class__ is val or type(args[1]) == int): + args = list(args) + try: + if not args[0].__class__ is multi_val: + args[0] = multi_val(args[0]) + except: + raise + try: + if not args[1].__class__ is val: + args[1] = val(args[1]) + except: + raise + ctx = args[0].ctx + res = isl.isl_multi_val_add_val(isl.isl_multi_val_copy(args[0].ptr), isl.isl_val_copy(args[1].ptr)) + obj = multi_val(ctx=ctx, ptr=res) + return obj + raise Error + def at(arg0, arg1): + try: + if not arg0.__class__ is multi_val: + arg0 = multi_val(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_multi_val_get_at(arg0.ptr, arg1) + obj = val(ctx=ctx, ptr=res) + return obj + def get_at(arg0, arg1): + return arg0.at(arg1) + def flat_range_product(arg0, arg1): + try: + if not arg0.__class__ is multi_val: + arg0 = multi_val(arg0) + except: + raise + try: + if not arg1.__class__ is multi_val: + arg1 = multi_val(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_multi_val_flat_range_product(isl.isl_multi_val_copy(arg0.ptr), isl.isl_multi_val_copy(arg1.ptr)) + obj = multi_val(ctx=ctx, ptr=res) + return obj + def has_range_tuple_id(arg0): + try: + if not arg0.__class__ is multi_val: + arg0 = multi_val(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_multi_val_has_range_tuple_id(arg0.ptr) + if res < 0: + raise Error + return bool(res) + def involves_nan(arg0): + try: + if not arg0.__class__ is multi_val: + arg0 = multi_val(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_multi_val_involves_nan(arg0.ptr) + if res < 0: + raise Error + return bool(res) + def list(arg0): + try: + if not arg0.__class__ is multi_val: + arg0 = multi_val(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_multi_val_get_list(arg0.ptr) + obj = val_list(ctx=ctx, ptr=res) + return obj + def get_list(arg0): + return arg0.list() + def max(arg0, arg1): + try: + if not arg0.__class__ is multi_val: + arg0 = multi_val(arg0) + except: + raise + try: + if not arg1.__class__ is multi_val: + arg1 = multi_val(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_multi_val_max(isl.isl_multi_val_copy(arg0.ptr), isl.isl_multi_val_copy(arg1.ptr)) + obj = multi_val(ctx=ctx, ptr=res) + return obj + def min(arg0, arg1): + try: + if not arg0.__class__ is multi_val: + arg0 = multi_val(arg0) + except: + raise + try: + if not arg1.__class__ is multi_val: + arg1 = multi_val(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_multi_val_min(isl.isl_multi_val_copy(arg0.ptr), isl.isl_multi_val_copy(arg1.ptr)) + obj = multi_val(ctx=ctx, ptr=res) + return obj + def neg(arg0): + try: + if not arg0.__class__ is multi_val: + arg0 = multi_val(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_multi_val_neg(isl.isl_multi_val_copy(arg0.ptr)) + obj = multi_val(ctx=ctx, ptr=res) + return obj + def plain_is_equal(arg0, arg1): + try: + if not arg0.__class__ is multi_val: + arg0 = multi_val(arg0) + except: + raise + try: + if not arg1.__class__ is multi_val: + arg1 = multi_val(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_multi_val_plain_is_equal(arg0.ptr, arg1.ptr) + if res < 0: + raise Error + return bool(res) + def product(arg0, arg1): + try: + if not arg0.__class__ is multi_val: + arg0 = multi_val(arg0) + except: + raise + try: + if not arg1.__class__ is multi_val: + arg1 = multi_val(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_multi_val_product(isl.isl_multi_val_copy(arg0.ptr), isl.isl_multi_val_copy(arg1.ptr)) + obj = multi_val(ctx=ctx, ptr=res) + return obj + def range_product(arg0, arg1): + try: + if not arg0.__class__ is multi_val: + arg0 = multi_val(arg0) + except: + raise + try: + if not arg1.__class__ is multi_val: + arg1 = multi_val(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_multi_val_range_product(isl.isl_multi_val_copy(arg0.ptr), isl.isl_multi_val_copy(arg1.ptr)) + obj = multi_val(ctx=ctx, ptr=res) + return obj + def range_tuple_id(arg0): + try: + if not arg0.__class__ is multi_val: + arg0 = multi_val(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_multi_val_get_range_tuple_id(arg0.ptr) + obj = id(ctx=ctx, ptr=res) + return obj + def get_range_tuple_id(arg0): + return arg0.range_tuple_id() + def reset_range_tuple_id(arg0): + try: + if not arg0.__class__ is multi_val: + arg0 = multi_val(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_multi_val_reset_range_tuple_id(isl.isl_multi_val_copy(arg0.ptr)) + obj = multi_val(ctx=ctx, ptr=res) + return obj + def scale(*args): + if len(args) == 2 and args[1].__class__ is multi_val: + args = list(args) + try: + if not args[0].__class__ is multi_val: + args[0] = multi_val(args[0]) + except: + raise + ctx = args[0].ctx + res = isl.isl_multi_val_scale_multi_val(isl.isl_multi_val_copy(args[0].ptr), isl.isl_multi_val_copy(args[1].ptr)) + obj = multi_val(ctx=ctx, ptr=res) + return obj + if len(args) == 2 and (args[1].__class__ is val or type(args[1]) == int): + args = list(args) + try: + if not args[0].__class__ is multi_val: + args[0] = multi_val(args[0]) + except: + raise + try: + if not args[1].__class__ is val: + args[1] = val(args[1]) + except: + raise + ctx = args[0].ctx + res = isl.isl_multi_val_scale_val(isl.isl_multi_val_copy(args[0].ptr), isl.isl_val_copy(args[1].ptr)) + obj = multi_val(ctx=ctx, ptr=res) + return obj + raise Error + def scale_down(*args): + if len(args) == 2 and args[1].__class__ is multi_val: + args = list(args) + try: + if not args[0].__class__ is multi_val: + args[0] = multi_val(args[0]) + except: + raise + ctx = args[0].ctx + res = isl.isl_multi_val_scale_down_multi_val(isl.isl_multi_val_copy(args[0].ptr), isl.isl_multi_val_copy(args[1].ptr)) + obj = multi_val(ctx=ctx, ptr=res) + return obj + if len(args) == 2 and (args[1].__class__ is val or type(args[1]) == int): + args = list(args) + try: + if not args[0].__class__ is multi_val: + args[0] = multi_val(args[0]) + except: + raise + try: + if not args[1].__class__ is val: + args[1] = val(args[1]) + except: + raise + ctx = args[0].ctx + res = isl.isl_multi_val_scale_down_val(isl.isl_multi_val_copy(args[0].ptr), isl.isl_val_copy(args[1].ptr)) + obj = multi_val(ctx=ctx, ptr=res) + return obj + raise Error + def set_at(arg0, arg1, arg2): + try: + if not arg0.__class__ is multi_val: + arg0 = multi_val(arg0) + except: + raise + try: + if not arg2.__class__ is val: + arg2 = val(arg2) + except: + raise + ctx = arg0.ctx + res = isl.isl_multi_val_set_at(isl.isl_multi_val_copy(arg0.ptr), arg1, isl.isl_val_copy(arg2.ptr)) + obj = multi_val(ctx=ctx, ptr=res) + return obj + def set_range_tuple(*args): + if len(args) == 2 and (args[1].__class__ is id or type(args[1]) == str): + args = list(args) + try: + if not args[0].__class__ is multi_val: + args[0] = multi_val(args[0]) + except: + raise + try: + if not args[1].__class__ is id: + args[1] = id(args[1]) + except: + raise + ctx = args[0].ctx + res = isl.isl_multi_val_set_range_tuple_id(isl.isl_multi_val_copy(args[0].ptr), isl.isl_id_copy(args[1].ptr)) + obj = multi_val(ctx=ctx, ptr=res) + return obj + raise Error + def size(arg0): + try: + if not arg0.__class__ is multi_val: + arg0 = multi_val(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_multi_val_size(arg0.ptr) + if res < 0: + raise Error + return int(res) + def space(arg0): + try: + if not arg0.__class__ is multi_val: + arg0 = multi_val(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_multi_val_get_space(arg0.ptr) + obj = space(ctx=ctx, ptr=res) + return obj + def get_space(arg0): + return arg0.space() + def sub(arg0, arg1): + try: + if not arg0.__class__ is multi_val: + arg0 = multi_val(arg0) + except: + raise + try: + if not arg1.__class__ is multi_val: + arg1 = multi_val(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_multi_val_sub(isl.isl_multi_val_copy(arg0.ptr), isl.isl_multi_val_copy(arg1.ptr)) + obj = multi_val(ctx=ctx, ptr=res) + return obj + @staticmethod + def zero(arg0): + try: + if not arg0.__class__ is space: + arg0 = space(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_multi_val_zero(isl.isl_space_copy(arg0.ptr)) + obj = multi_val(ctx=ctx, ptr=res) + return obj + +isl.isl_multi_val_from_val_list.restype = c_void_p +isl.isl_multi_val_from_val_list.argtypes = [c_void_p, c_void_p] +isl.isl_multi_val_read_from_str.restype = c_void_p +isl.isl_multi_val_read_from_str.argtypes = [Context, c_char_p] +isl.isl_multi_val_add.restype = c_void_p +isl.isl_multi_val_add.argtypes = [c_void_p, c_void_p] +isl.isl_multi_val_add_val.restype = c_void_p +isl.isl_multi_val_add_val.argtypes = [c_void_p, c_void_p] +isl.isl_multi_val_get_at.restype = c_void_p +isl.isl_multi_val_get_at.argtypes = [c_void_p, c_int] +isl.isl_multi_val_flat_range_product.restype = c_void_p +isl.isl_multi_val_flat_range_product.argtypes = [c_void_p, c_void_p] +isl.isl_multi_val_has_range_tuple_id.argtypes = [c_void_p] +isl.isl_multi_val_involves_nan.argtypes = [c_void_p] +isl.isl_multi_val_get_list.restype = c_void_p +isl.isl_multi_val_get_list.argtypes = [c_void_p] +isl.isl_multi_val_max.restype = c_void_p +isl.isl_multi_val_max.argtypes = [c_void_p, c_void_p] +isl.isl_multi_val_min.restype = c_void_p +isl.isl_multi_val_min.argtypes = [c_void_p, c_void_p] +isl.isl_multi_val_neg.restype = c_void_p +isl.isl_multi_val_neg.argtypes = [c_void_p] +isl.isl_multi_val_plain_is_equal.argtypes = [c_void_p, c_void_p] +isl.isl_multi_val_product.restype = c_void_p +isl.isl_multi_val_product.argtypes = [c_void_p, c_void_p] +isl.isl_multi_val_range_product.restype = c_void_p +isl.isl_multi_val_range_product.argtypes = [c_void_p, c_void_p] +isl.isl_multi_val_get_range_tuple_id.restype = c_void_p +isl.isl_multi_val_get_range_tuple_id.argtypes = [c_void_p] +isl.isl_multi_val_reset_range_tuple_id.restype = c_void_p +isl.isl_multi_val_reset_range_tuple_id.argtypes = [c_void_p] +isl.isl_multi_val_scale_multi_val.restype = c_void_p +isl.isl_multi_val_scale_multi_val.argtypes = [c_void_p, c_void_p] +isl.isl_multi_val_scale_val.restype = c_void_p +isl.isl_multi_val_scale_val.argtypes = [c_void_p, c_void_p] +isl.isl_multi_val_scale_down_multi_val.restype = c_void_p +isl.isl_multi_val_scale_down_multi_val.argtypes = [c_void_p, c_void_p] +isl.isl_multi_val_scale_down_val.restype = c_void_p +isl.isl_multi_val_scale_down_val.argtypes = [c_void_p, c_void_p] +isl.isl_multi_val_set_at.restype = c_void_p +isl.isl_multi_val_set_at.argtypes = [c_void_p, c_int, c_void_p] +isl.isl_multi_val_set_range_tuple_id.restype = c_void_p +isl.isl_multi_val_set_range_tuple_id.argtypes = [c_void_p, c_void_p] +isl.isl_multi_val_size.argtypes = [c_void_p] +isl.isl_multi_val_get_space.restype = c_void_p +isl.isl_multi_val_get_space.argtypes = [c_void_p] +isl.isl_multi_val_sub.restype = c_void_p +isl.isl_multi_val_sub.argtypes = [c_void_p, c_void_p] +isl.isl_multi_val_zero.restype = c_void_p +isl.isl_multi_val_zero.argtypes = [c_void_p] +isl.isl_multi_val_copy.restype = c_void_p +isl.isl_multi_val_copy.argtypes = [c_void_p] +isl.isl_multi_val_free.restype = c_void_p +isl.isl_multi_val_free.argtypes = [c_void_p] +isl.isl_multi_val_to_str.restype = POINTER(c_char) +isl.isl_multi_val_to_str.argtypes = [c_void_p] + +class point(basic_set): + def __init__(self, *args, **keywords): + if "ptr" in keywords: + self.ctx = keywords["ctx"] + self.ptr = keywords["ptr"] + return + raise Error + def __del__(self): + if hasattr(self, 'ptr'): + isl.isl_point_free(self.ptr) + def __str__(arg0): + try: + if not arg0.__class__ is point: + arg0 = point(arg0) + except: + raise + ptr = isl.isl_point_to_str(arg0.ptr) + res = cast(ptr, c_char_p).value.decode('ascii') + libc.free(ptr) + return res + def __repr__(self): + s = str(self) + if '"' in s: + return 'isl.point("""%s""")' % s + else: + return 'isl.point("%s")' % s + def multi_val(arg0): + try: + if not arg0.__class__ is point: + arg0 = point(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_point_get_multi_val(arg0.ptr) + obj = multi_val(ctx=ctx, ptr=res) + return obj + def get_multi_val(arg0): + return arg0.multi_val() + def to_set(arg0): + try: + if not arg0.__class__ is point: + arg0 = point(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_point_to_set(isl.isl_point_copy(arg0.ptr)) + obj = set(ctx=ctx, ptr=res) + return obj + +isl.isl_point_get_multi_val.restype = c_void_p +isl.isl_point_get_multi_val.argtypes = [c_void_p] +isl.isl_point_to_set.restype = c_void_p +isl.isl_point_to_set.argtypes = [c_void_p] +isl.isl_point_copy.restype = c_void_p +isl.isl_point_copy.argtypes = [c_void_p] +isl.isl_point_free.restype = c_void_p +isl.isl_point_free.argtypes = [c_void_p] +isl.isl_point_to_str.restype = POINTER(c_char) +isl.isl_point_to_str.argtypes = [c_void_p] + +class pw_aff_list(object): + def __init__(self, *args, **keywords): + if "ptr" in keywords: + self.ctx = keywords["ctx"] + self.ptr = keywords["ptr"] + return + if len(args) == 1 and type(args[0]) == int: + self.ctx = Context.getDefaultInstance() + self.ptr = isl.isl_pw_aff_list_alloc(self.ctx, args[0]) + return + if len(args) == 1 and args[0].__class__ is pw_aff: + self.ctx = Context.getDefaultInstance() + self.ptr = isl.isl_pw_aff_list_from_pw_aff(isl.isl_pw_aff_copy(args[0].ptr)) + return + if len(args) == 1 and type(args[0]) == str: + self.ctx = Context.getDefaultInstance() + self.ptr = isl.isl_pw_aff_list_read_from_str(self.ctx, args[0].encode('ascii')) + return + raise Error + def __del__(self): + if hasattr(self, 'ptr'): + isl.isl_pw_aff_list_free(self.ptr) + def __str__(arg0): + try: + if not arg0.__class__ is pw_aff_list: + arg0 = pw_aff_list(arg0) + except: + raise + ptr = isl.isl_pw_aff_list_to_str(arg0.ptr) + res = cast(ptr, c_char_p).value.decode('ascii') + libc.free(ptr) + return res + def __repr__(self): + s = str(self) + if '"' in s: + return 'isl.pw_aff_list("""%s""")' % s + else: + return 'isl.pw_aff_list("%s")' % s + def add(arg0, arg1): + try: + if not arg0.__class__ is pw_aff_list: + arg0 = pw_aff_list(arg0) + except: + raise + try: + if not arg1.__class__ is pw_aff: + arg1 = pw_aff(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_pw_aff_list_add(isl.isl_pw_aff_list_copy(arg0.ptr), isl.isl_pw_aff_copy(arg1.ptr)) + obj = pw_aff_list(ctx=ctx, ptr=res) + return obj + def at(arg0, arg1): + try: + if not arg0.__class__ is pw_aff_list: + arg0 = pw_aff_list(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_pw_aff_list_get_at(arg0.ptr, arg1) + obj = pw_aff(ctx=ctx, ptr=res) + return obj + def get_at(arg0, arg1): + return arg0.at(arg1) + def clear(arg0): + try: + if not arg0.__class__ is pw_aff_list: + arg0 = pw_aff_list(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_pw_aff_list_clear(isl.isl_pw_aff_list_copy(arg0.ptr)) + obj = pw_aff_list(ctx=ctx, ptr=res) + return obj + def concat(arg0, arg1): + try: + if not arg0.__class__ is pw_aff_list: + arg0 = pw_aff_list(arg0) + except: + raise + try: + if not arg1.__class__ is pw_aff_list: + arg1 = pw_aff_list(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_pw_aff_list_concat(isl.isl_pw_aff_list_copy(arg0.ptr), isl.isl_pw_aff_list_copy(arg1.ptr)) + obj = pw_aff_list(ctx=ctx, ptr=res) + return obj + def drop(arg0, arg1, arg2): + try: + if not arg0.__class__ is pw_aff_list: + arg0 = pw_aff_list(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_pw_aff_list_drop(isl.isl_pw_aff_list_copy(arg0.ptr), arg1, arg2) + obj = pw_aff_list(ctx=ctx, ptr=res) + return obj + def foreach(arg0, arg1): + try: + if not arg0.__class__ is pw_aff_list: + arg0 = pw_aff_list(arg0) + except: + raise + exc_info = [None] + fn = CFUNCTYPE(c_int, c_void_p, c_void_p) + def cb_func(cb_arg0, cb_arg1): + cb_arg0 = pw_aff(ctx=arg0.ctx, ptr=(cb_arg0)) + try: + arg1(cb_arg0) + except BaseException as e: + exc_info[0] = e + return -1 + return 0 + cb1 = fn(cb_func) + ctx = arg0.ctx + res = isl.isl_pw_aff_list_foreach(arg0.ptr, cb1, None) + if exc_info[0] is not None: + raise exc_info[0] + if res < 0: + raise Error + def foreach_scc(arg0, arg1, arg2): + try: + if not arg0.__class__ is pw_aff_list: + arg0 = pw_aff_list(arg0) + except: + raise + exc_info = [None] + fn = CFUNCTYPE(c_int, c_void_p, c_void_p, c_void_p) + def cb_func(cb_arg0, cb_arg1, cb_arg2): + cb_arg0 = pw_aff(ctx=arg0.ctx, ptr=isl.isl_pw_aff_copy(cb_arg0)) + cb_arg1 = pw_aff(ctx=arg0.ctx, ptr=isl.isl_pw_aff_copy(cb_arg1)) + try: + res = arg1(cb_arg0, cb_arg1) + except BaseException as e: + exc_info[0] = e + return -1 + return 1 if res else 0 + cb1 = fn(cb_func) + exc_info = [None] + fn = CFUNCTYPE(c_int, c_void_p, c_void_p) + def cb_func(cb_arg0, cb_arg1): + cb_arg0 = pw_aff_list(ctx=arg0.ctx, ptr=(cb_arg0)) + try: + arg2(cb_arg0) + except BaseException as e: + exc_info[0] = e + return -1 + return 0 + cb2 = fn(cb_func) + ctx = arg0.ctx + res = isl.isl_pw_aff_list_foreach_scc(arg0.ptr, cb1, None, cb2, None) + if exc_info[0] is not None: + raise exc_info[0] + if res < 0: + raise Error + def insert(arg0, arg1, arg2): + try: + if not arg0.__class__ is pw_aff_list: + arg0 = pw_aff_list(arg0) + except: + raise + try: + if not arg2.__class__ is pw_aff: + arg2 = pw_aff(arg2) + except: + raise + ctx = arg0.ctx + res = isl.isl_pw_aff_list_insert(isl.isl_pw_aff_list_copy(arg0.ptr), arg1, isl.isl_pw_aff_copy(arg2.ptr)) + obj = pw_aff_list(ctx=ctx, ptr=res) + return obj + def set_at(arg0, arg1, arg2): + try: + if not arg0.__class__ is pw_aff_list: + arg0 = pw_aff_list(arg0) + except: + raise + try: + if not arg2.__class__ is pw_aff: + arg2 = pw_aff(arg2) + except: + raise + ctx = arg0.ctx + res = isl.isl_pw_aff_list_set_at(isl.isl_pw_aff_list_copy(arg0.ptr), arg1, isl.isl_pw_aff_copy(arg2.ptr)) + obj = pw_aff_list(ctx=ctx, ptr=res) + return obj + def size(arg0): + try: + if not arg0.__class__ is pw_aff_list: + arg0 = pw_aff_list(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_pw_aff_list_size(arg0.ptr) + if res < 0: + raise Error + return int(res) + +isl.isl_pw_aff_list_alloc.restype = c_void_p +isl.isl_pw_aff_list_alloc.argtypes = [Context, c_int] +isl.isl_pw_aff_list_from_pw_aff.restype = c_void_p +isl.isl_pw_aff_list_from_pw_aff.argtypes = [c_void_p] +isl.isl_pw_aff_list_read_from_str.restype = c_void_p +isl.isl_pw_aff_list_read_from_str.argtypes = [Context, c_char_p] +isl.isl_pw_aff_list_add.restype = c_void_p +isl.isl_pw_aff_list_add.argtypes = [c_void_p, c_void_p] +isl.isl_pw_aff_list_get_at.restype = c_void_p +isl.isl_pw_aff_list_get_at.argtypes = [c_void_p, c_int] +isl.isl_pw_aff_list_clear.restype = c_void_p +isl.isl_pw_aff_list_clear.argtypes = [c_void_p] +isl.isl_pw_aff_list_concat.restype = c_void_p +isl.isl_pw_aff_list_concat.argtypes = [c_void_p, c_void_p] +isl.isl_pw_aff_list_drop.restype = c_void_p +isl.isl_pw_aff_list_drop.argtypes = [c_void_p, c_int, c_int] +isl.isl_pw_aff_list_foreach.argtypes = [c_void_p, c_void_p, c_void_p] +isl.isl_pw_aff_list_foreach_scc.argtypes = [c_void_p, c_void_p, c_void_p, c_void_p, c_void_p] +isl.isl_pw_aff_list_insert.restype = c_void_p +isl.isl_pw_aff_list_insert.argtypes = [c_void_p, c_int, c_void_p] +isl.isl_pw_aff_list_set_at.restype = c_void_p +isl.isl_pw_aff_list_set_at.argtypes = [c_void_p, c_int, c_void_p] +isl.isl_pw_aff_list_size.argtypes = [c_void_p] +isl.isl_pw_aff_list_copy.restype = c_void_p +isl.isl_pw_aff_list_copy.argtypes = [c_void_p] +isl.isl_pw_aff_list_free.restype = c_void_p +isl.isl_pw_aff_list_free.argtypes = [c_void_p] +isl.isl_pw_aff_list_to_str.restype = POINTER(c_char) +isl.isl_pw_aff_list_to_str.argtypes = [c_void_p] + +class pw_multi_aff_list(object): + def __init__(self, *args, **keywords): + if "ptr" in keywords: + self.ctx = keywords["ctx"] + self.ptr = keywords["ptr"] + return + if len(args) == 1 and type(args[0]) == int: + self.ctx = Context.getDefaultInstance() + self.ptr = isl.isl_pw_multi_aff_list_alloc(self.ctx, args[0]) + return + if len(args) == 1 and args[0].__class__ is pw_multi_aff: + self.ctx = Context.getDefaultInstance() + self.ptr = isl.isl_pw_multi_aff_list_from_pw_multi_aff(isl.isl_pw_multi_aff_copy(args[0].ptr)) + return + if len(args) == 1 and type(args[0]) == str: + self.ctx = Context.getDefaultInstance() + self.ptr = isl.isl_pw_multi_aff_list_read_from_str(self.ctx, args[0].encode('ascii')) + return + raise Error + def __del__(self): + if hasattr(self, 'ptr'): + isl.isl_pw_multi_aff_list_free(self.ptr) + def __str__(arg0): + try: + if not arg0.__class__ is pw_multi_aff_list: + arg0 = pw_multi_aff_list(arg0) + except: + raise + ptr = isl.isl_pw_multi_aff_list_to_str(arg0.ptr) + res = cast(ptr, c_char_p).value.decode('ascii') + libc.free(ptr) + return res + def __repr__(self): + s = str(self) + if '"' in s: + return 'isl.pw_multi_aff_list("""%s""")' % s + else: + return 'isl.pw_multi_aff_list("%s")' % s + def add(arg0, arg1): + try: + if not arg0.__class__ is pw_multi_aff_list: + arg0 = pw_multi_aff_list(arg0) + except: + raise + try: + if not arg1.__class__ is pw_multi_aff: + arg1 = pw_multi_aff(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_pw_multi_aff_list_add(isl.isl_pw_multi_aff_list_copy(arg0.ptr), isl.isl_pw_multi_aff_copy(arg1.ptr)) + obj = pw_multi_aff_list(ctx=ctx, ptr=res) + return obj + def at(arg0, arg1): + try: + if not arg0.__class__ is pw_multi_aff_list: + arg0 = pw_multi_aff_list(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_pw_multi_aff_list_get_at(arg0.ptr, arg1) + obj = pw_multi_aff(ctx=ctx, ptr=res) + return obj + def get_at(arg0, arg1): + return arg0.at(arg1) + def clear(arg0): + try: + if not arg0.__class__ is pw_multi_aff_list: + arg0 = pw_multi_aff_list(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_pw_multi_aff_list_clear(isl.isl_pw_multi_aff_list_copy(arg0.ptr)) + obj = pw_multi_aff_list(ctx=ctx, ptr=res) + return obj + def concat(arg0, arg1): + try: + if not arg0.__class__ is pw_multi_aff_list: + arg0 = pw_multi_aff_list(arg0) + except: + raise + try: + if not arg1.__class__ is pw_multi_aff_list: + arg1 = pw_multi_aff_list(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_pw_multi_aff_list_concat(isl.isl_pw_multi_aff_list_copy(arg0.ptr), isl.isl_pw_multi_aff_list_copy(arg1.ptr)) + obj = pw_multi_aff_list(ctx=ctx, ptr=res) + return obj + def drop(arg0, arg1, arg2): + try: + if not arg0.__class__ is pw_multi_aff_list: + arg0 = pw_multi_aff_list(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_pw_multi_aff_list_drop(isl.isl_pw_multi_aff_list_copy(arg0.ptr), arg1, arg2) + obj = pw_multi_aff_list(ctx=ctx, ptr=res) + return obj + def foreach(arg0, arg1): + try: + if not arg0.__class__ is pw_multi_aff_list: + arg0 = pw_multi_aff_list(arg0) + except: + raise + exc_info = [None] + fn = CFUNCTYPE(c_int, c_void_p, c_void_p) + def cb_func(cb_arg0, cb_arg1): + cb_arg0 = pw_multi_aff(ctx=arg0.ctx, ptr=(cb_arg0)) + try: + arg1(cb_arg0) + except BaseException as e: + exc_info[0] = e + return -1 + return 0 + cb1 = fn(cb_func) + ctx = arg0.ctx + res = isl.isl_pw_multi_aff_list_foreach(arg0.ptr, cb1, None) + if exc_info[0] is not None: + raise exc_info[0] + if res < 0: + raise Error + def foreach_scc(arg0, arg1, arg2): + try: + if not arg0.__class__ is pw_multi_aff_list: + arg0 = pw_multi_aff_list(arg0) + except: + raise + exc_info = [None] + fn = CFUNCTYPE(c_int, c_void_p, c_void_p, c_void_p) + def cb_func(cb_arg0, cb_arg1, cb_arg2): + cb_arg0 = pw_multi_aff(ctx=arg0.ctx, ptr=isl.isl_pw_multi_aff_copy(cb_arg0)) + cb_arg1 = pw_multi_aff(ctx=arg0.ctx, ptr=isl.isl_pw_multi_aff_copy(cb_arg1)) + try: + res = arg1(cb_arg0, cb_arg1) + except BaseException as e: + exc_info[0] = e + return -1 + return 1 if res else 0 + cb1 = fn(cb_func) + exc_info = [None] + fn = CFUNCTYPE(c_int, c_void_p, c_void_p) + def cb_func(cb_arg0, cb_arg1): + cb_arg0 = pw_multi_aff_list(ctx=arg0.ctx, ptr=(cb_arg0)) + try: + arg2(cb_arg0) + except BaseException as e: + exc_info[0] = e + return -1 + return 0 + cb2 = fn(cb_func) + ctx = arg0.ctx + res = isl.isl_pw_multi_aff_list_foreach_scc(arg0.ptr, cb1, None, cb2, None) + if exc_info[0] is not None: + raise exc_info[0] + if res < 0: + raise Error + def insert(arg0, arg1, arg2): + try: + if not arg0.__class__ is pw_multi_aff_list: + arg0 = pw_multi_aff_list(arg0) + except: + raise + try: + if not arg2.__class__ is pw_multi_aff: + arg2 = pw_multi_aff(arg2) + except: + raise + ctx = arg0.ctx + res = isl.isl_pw_multi_aff_list_insert(isl.isl_pw_multi_aff_list_copy(arg0.ptr), arg1, isl.isl_pw_multi_aff_copy(arg2.ptr)) + obj = pw_multi_aff_list(ctx=ctx, ptr=res) + return obj + def set_at(arg0, arg1, arg2): + try: + if not arg0.__class__ is pw_multi_aff_list: + arg0 = pw_multi_aff_list(arg0) + except: + raise + try: + if not arg2.__class__ is pw_multi_aff: + arg2 = pw_multi_aff(arg2) + except: + raise + ctx = arg0.ctx + res = isl.isl_pw_multi_aff_list_set_at(isl.isl_pw_multi_aff_list_copy(arg0.ptr), arg1, isl.isl_pw_multi_aff_copy(arg2.ptr)) + obj = pw_multi_aff_list(ctx=ctx, ptr=res) + return obj + def size(arg0): + try: + if not arg0.__class__ is pw_multi_aff_list: + arg0 = pw_multi_aff_list(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_pw_multi_aff_list_size(arg0.ptr) + if res < 0: + raise Error + return int(res) + +isl.isl_pw_multi_aff_list_alloc.restype = c_void_p +isl.isl_pw_multi_aff_list_alloc.argtypes = [Context, c_int] +isl.isl_pw_multi_aff_list_from_pw_multi_aff.restype = c_void_p +isl.isl_pw_multi_aff_list_from_pw_multi_aff.argtypes = [c_void_p] +isl.isl_pw_multi_aff_list_read_from_str.restype = c_void_p +isl.isl_pw_multi_aff_list_read_from_str.argtypes = [Context, c_char_p] +isl.isl_pw_multi_aff_list_add.restype = c_void_p +isl.isl_pw_multi_aff_list_add.argtypes = [c_void_p, c_void_p] +isl.isl_pw_multi_aff_list_get_at.restype = c_void_p +isl.isl_pw_multi_aff_list_get_at.argtypes = [c_void_p, c_int] +isl.isl_pw_multi_aff_list_clear.restype = c_void_p +isl.isl_pw_multi_aff_list_clear.argtypes = [c_void_p] +isl.isl_pw_multi_aff_list_concat.restype = c_void_p +isl.isl_pw_multi_aff_list_concat.argtypes = [c_void_p, c_void_p] +isl.isl_pw_multi_aff_list_drop.restype = c_void_p +isl.isl_pw_multi_aff_list_drop.argtypes = [c_void_p, c_int, c_int] +isl.isl_pw_multi_aff_list_foreach.argtypes = [c_void_p, c_void_p, c_void_p] +isl.isl_pw_multi_aff_list_foreach_scc.argtypes = [c_void_p, c_void_p, c_void_p, c_void_p, c_void_p] +isl.isl_pw_multi_aff_list_insert.restype = c_void_p +isl.isl_pw_multi_aff_list_insert.argtypes = [c_void_p, c_int, c_void_p] +isl.isl_pw_multi_aff_list_set_at.restype = c_void_p +isl.isl_pw_multi_aff_list_set_at.argtypes = [c_void_p, c_int, c_void_p] +isl.isl_pw_multi_aff_list_size.argtypes = [c_void_p] +isl.isl_pw_multi_aff_list_copy.restype = c_void_p +isl.isl_pw_multi_aff_list_copy.argtypes = [c_void_p] +isl.isl_pw_multi_aff_list_free.restype = c_void_p +isl.isl_pw_multi_aff_list_free.argtypes = [c_void_p] +isl.isl_pw_multi_aff_list_to_str.restype = POINTER(c_char) +isl.isl_pw_multi_aff_list_to_str.argtypes = [c_void_p] + +class schedule(object): + def __init__(self, *args, **keywords): + if "ptr" in keywords: + self.ctx = keywords["ctx"] + self.ptr = keywords["ptr"] + return + if len(args) == 1 and type(args[0]) == str: + self.ctx = Context.getDefaultInstance() + self.ptr = isl.isl_schedule_read_from_str(self.ctx, args[0].encode('ascii')) + return + raise Error + def __del__(self): + if hasattr(self, 'ptr'): + isl.isl_schedule_free(self.ptr) + def __str__(arg0): + try: + if not arg0.__class__ is schedule: + arg0 = schedule(arg0) + except: + raise + ptr = isl.isl_schedule_to_str(arg0.ptr) + res = cast(ptr, c_char_p).value.decode('ascii') + libc.free(ptr) + return res + def __repr__(self): + s = str(self) + if '"' in s: + return 'isl.schedule("""%s""")' % s + else: + return 'isl.schedule("%s")' % s + def domain(arg0): + try: + if not arg0.__class__ is schedule: + arg0 = schedule(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_schedule_get_domain(arg0.ptr) + obj = union_set(ctx=ctx, ptr=res) + return obj + def get_domain(arg0): + return arg0.domain() + @staticmethod + def from_domain(arg0): + try: + if not arg0.__class__ is union_set: + arg0 = union_set(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_schedule_from_domain(isl.isl_union_set_copy(arg0.ptr)) + obj = schedule(ctx=ctx, ptr=res) + return obj + def map(arg0): + try: + if not arg0.__class__ is schedule: + arg0 = schedule(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_schedule_get_map(arg0.ptr) + obj = union_map(ctx=ctx, ptr=res) + return obj + def get_map(arg0): + return arg0.map() + def pullback(*args): + if len(args) == 2 and args[1].__class__ is union_pw_multi_aff: + args = list(args) + try: + if not args[0].__class__ is schedule: + args[0] = schedule(args[0]) + except: + raise + ctx = args[0].ctx + res = isl.isl_schedule_pullback_union_pw_multi_aff(isl.isl_schedule_copy(args[0].ptr), isl.isl_union_pw_multi_aff_copy(args[1].ptr)) + obj = schedule(ctx=ctx, ptr=res) + return obj + raise Error + def root(arg0): + try: + if not arg0.__class__ is schedule: + arg0 = schedule(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_schedule_get_root(arg0.ptr) + obj = schedule_node(ctx=ctx, ptr=res) + return obj + def get_root(arg0): + return arg0.root() + +isl.isl_schedule_read_from_str.restype = c_void_p +isl.isl_schedule_read_from_str.argtypes = [Context, c_char_p] +isl.isl_schedule_get_domain.restype = c_void_p +isl.isl_schedule_get_domain.argtypes = [c_void_p] +isl.isl_schedule_from_domain.restype = c_void_p +isl.isl_schedule_from_domain.argtypes = [c_void_p] +isl.isl_schedule_get_map.restype = c_void_p +isl.isl_schedule_get_map.argtypes = [c_void_p] +isl.isl_schedule_pullback_union_pw_multi_aff.restype = c_void_p +isl.isl_schedule_pullback_union_pw_multi_aff.argtypes = [c_void_p, c_void_p] +isl.isl_schedule_get_root.restype = c_void_p +isl.isl_schedule_get_root.argtypes = [c_void_p] +isl.isl_schedule_copy.restype = c_void_p +isl.isl_schedule_copy.argtypes = [c_void_p] +isl.isl_schedule_free.restype = c_void_p +isl.isl_schedule_free.argtypes = [c_void_p] +isl.isl_schedule_to_str.restype = POINTER(c_char) +isl.isl_schedule_to_str.argtypes = [c_void_p] + +class schedule_constraints(object): + def __init__(self, *args, **keywords): + if "ptr" in keywords: + self.ctx = keywords["ctx"] + self.ptr = keywords["ptr"] + return + if len(args) == 1 and type(args[0]) == str: + self.ctx = Context.getDefaultInstance() + self.ptr = isl.isl_schedule_constraints_read_from_str(self.ctx, args[0].encode('ascii')) + return + raise Error + def __del__(self): + if hasattr(self, 'ptr'): + isl.isl_schedule_constraints_free(self.ptr) + def __str__(arg0): + try: + if not arg0.__class__ is schedule_constraints: + arg0 = schedule_constraints(arg0) + except: + raise + ptr = isl.isl_schedule_constraints_to_str(arg0.ptr) + res = cast(ptr, c_char_p).value.decode('ascii') + libc.free(ptr) + return res + def __repr__(self): + s = str(self) + if '"' in s: + return 'isl.schedule_constraints("""%s""")' % s + else: + return 'isl.schedule_constraints("%s")' % s + def coincidence(arg0): + try: + if not arg0.__class__ is schedule_constraints: + arg0 = schedule_constraints(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_schedule_constraints_get_coincidence(arg0.ptr) + obj = union_map(ctx=ctx, ptr=res) + return obj + def get_coincidence(arg0): + return arg0.coincidence() + def compute_schedule(arg0): + try: + if not arg0.__class__ is schedule_constraints: + arg0 = schedule_constraints(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_schedule_constraints_compute_schedule(isl.isl_schedule_constraints_copy(arg0.ptr)) + obj = schedule(ctx=ctx, ptr=res) + return obj + def conditional_validity(arg0): + try: + if not arg0.__class__ is schedule_constraints: + arg0 = schedule_constraints(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_schedule_constraints_get_conditional_validity(arg0.ptr) + obj = union_map(ctx=ctx, ptr=res) + return obj + def get_conditional_validity(arg0): + return arg0.conditional_validity() + def conditional_validity_condition(arg0): + try: + if not arg0.__class__ is schedule_constraints: + arg0 = schedule_constraints(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_schedule_constraints_get_conditional_validity_condition(arg0.ptr) + obj = union_map(ctx=ctx, ptr=res) + return obj + def get_conditional_validity_condition(arg0): + return arg0.conditional_validity_condition() + def context(arg0): + try: + if not arg0.__class__ is schedule_constraints: + arg0 = schedule_constraints(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_schedule_constraints_get_context(arg0.ptr) + obj = set(ctx=ctx, ptr=res) + return obj + def get_context(arg0): + return arg0.context() + def domain(arg0): + try: + if not arg0.__class__ is schedule_constraints: + arg0 = schedule_constraints(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_schedule_constraints_get_domain(arg0.ptr) + obj = union_set(ctx=ctx, ptr=res) + return obj + def get_domain(arg0): + return arg0.domain() + @staticmethod + def on_domain(arg0): + try: + if not arg0.__class__ is union_set: + arg0 = union_set(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_schedule_constraints_on_domain(isl.isl_union_set_copy(arg0.ptr)) + obj = schedule_constraints(ctx=ctx, ptr=res) + return obj + def proximity(arg0): + try: + if not arg0.__class__ is schedule_constraints: + arg0 = schedule_constraints(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_schedule_constraints_get_proximity(arg0.ptr) + obj = union_map(ctx=ctx, ptr=res) + return obj + def get_proximity(arg0): + return arg0.proximity() + def set_coincidence(arg0, arg1): + try: + if not arg0.__class__ is schedule_constraints: + arg0 = schedule_constraints(arg0) + except: + raise + try: + if not arg1.__class__ is union_map: + arg1 = union_map(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_schedule_constraints_set_coincidence(isl.isl_schedule_constraints_copy(arg0.ptr), isl.isl_union_map_copy(arg1.ptr)) + obj = schedule_constraints(ctx=ctx, ptr=res) + return obj + def set_conditional_validity(arg0, arg1, arg2): + try: + if not arg0.__class__ is schedule_constraints: + arg0 = schedule_constraints(arg0) + except: + raise + try: + if not arg1.__class__ is union_map: + arg1 = union_map(arg1) + except: + raise + try: + if not arg2.__class__ is union_map: + arg2 = union_map(arg2) + except: + raise + ctx = arg0.ctx + res = isl.isl_schedule_constraints_set_conditional_validity(isl.isl_schedule_constraints_copy(arg0.ptr), isl.isl_union_map_copy(arg1.ptr), isl.isl_union_map_copy(arg2.ptr)) + obj = schedule_constraints(ctx=ctx, ptr=res) + return obj + def set_context(arg0, arg1): + try: + if not arg0.__class__ is schedule_constraints: + arg0 = schedule_constraints(arg0) + except: + raise + try: + if not arg1.__class__ is set: + arg1 = set(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_schedule_constraints_set_context(isl.isl_schedule_constraints_copy(arg0.ptr), isl.isl_set_copy(arg1.ptr)) + obj = schedule_constraints(ctx=ctx, ptr=res) + return obj + def set_proximity(arg0, arg1): + try: + if not arg0.__class__ is schedule_constraints: + arg0 = schedule_constraints(arg0) + except: + raise + try: + if not arg1.__class__ is union_map: + arg1 = union_map(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_schedule_constraints_set_proximity(isl.isl_schedule_constraints_copy(arg0.ptr), isl.isl_union_map_copy(arg1.ptr)) + obj = schedule_constraints(ctx=ctx, ptr=res) + return obj + def set_validity(arg0, arg1): + try: + if not arg0.__class__ is schedule_constraints: + arg0 = schedule_constraints(arg0) + except: + raise + try: + if not arg1.__class__ is union_map: + arg1 = union_map(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_schedule_constraints_set_validity(isl.isl_schedule_constraints_copy(arg0.ptr), isl.isl_union_map_copy(arg1.ptr)) + obj = schedule_constraints(ctx=ctx, ptr=res) + return obj + def validity(arg0): + try: + if not arg0.__class__ is schedule_constraints: + arg0 = schedule_constraints(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_schedule_constraints_get_validity(arg0.ptr) + obj = union_map(ctx=ctx, ptr=res) + return obj + def get_validity(arg0): + return arg0.validity() + +isl.isl_schedule_constraints_read_from_str.restype = c_void_p +isl.isl_schedule_constraints_read_from_str.argtypes = [Context, c_char_p] +isl.isl_schedule_constraints_get_coincidence.restype = c_void_p +isl.isl_schedule_constraints_get_coincidence.argtypes = [c_void_p] +isl.isl_schedule_constraints_compute_schedule.restype = c_void_p +isl.isl_schedule_constraints_compute_schedule.argtypes = [c_void_p] +isl.isl_schedule_constraints_get_conditional_validity.restype = c_void_p +isl.isl_schedule_constraints_get_conditional_validity.argtypes = [c_void_p] +isl.isl_schedule_constraints_get_conditional_validity_condition.restype = c_void_p +isl.isl_schedule_constraints_get_conditional_validity_condition.argtypes = [c_void_p] +isl.isl_schedule_constraints_get_context.restype = c_void_p +isl.isl_schedule_constraints_get_context.argtypes = [c_void_p] +isl.isl_schedule_constraints_get_domain.restype = c_void_p +isl.isl_schedule_constraints_get_domain.argtypes = [c_void_p] +isl.isl_schedule_constraints_on_domain.restype = c_void_p +isl.isl_schedule_constraints_on_domain.argtypes = [c_void_p] +isl.isl_schedule_constraints_get_proximity.restype = c_void_p +isl.isl_schedule_constraints_get_proximity.argtypes = [c_void_p] +isl.isl_schedule_constraints_set_coincidence.restype = c_void_p +isl.isl_schedule_constraints_set_coincidence.argtypes = [c_void_p, c_void_p] +isl.isl_schedule_constraints_set_conditional_validity.restype = c_void_p +isl.isl_schedule_constraints_set_conditional_validity.argtypes = [c_void_p, c_void_p, c_void_p] +isl.isl_schedule_constraints_set_context.restype = c_void_p +isl.isl_schedule_constraints_set_context.argtypes = [c_void_p, c_void_p] +isl.isl_schedule_constraints_set_proximity.restype = c_void_p +isl.isl_schedule_constraints_set_proximity.argtypes = [c_void_p, c_void_p] +isl.isl_schedule_constraints_set_validity.restype = c_void_p +isl.isl_schedule_constraints_set_validity.argtypes = [c_void_p, c_void_p] +isl.isl_schedule_constraints_get_validity.restype = c_void_p +isl.isl_schedule_constraints_get_validity.argtypes = [c_void_p] +isl.isl_schedule_constraints_copy.restype = c_void_p +isl.isl_schedule_constraints_copy.argtypes = [c_void_p] +isl.isl_schedule_constraints_free.restype = c_void_p +isl.isl_schedule_constraints_free.argtypes = [c_void_p] +isl.isl_schedule_constraints_to_str.restype = POINTER(c_char) +isl.isl_schedule_constraints_to_str.argtypes = [c_void_p] + +class schedule_node(object): + def __init__(self, *args, **keywords): + if "ptr" in keywords: + self.ctx = keywords["ctx"] + self.ptr = keywords["ptr"] + return + if len(args) == 1 and isinstance(args[0], schedule_node_band): + self.ctx = args[0].ctx + self.ptr = isl.isl_schedule_node_copy(args[0].ptr) + return + if len(args) == 1 and isinstance(args[0], schedule_node_context): + self.ctx = args[0].ctx + self.ptr = isl.isl_schedule_node_copy(args[0].ptr) + return + if len(args) == 1 and isinstance(args[0], schedule_node_domain): + self.ctx = args[0].ctx + self.ptr = isl.isl_schedule_node_copy(args[0].ptr) + return + if len(args) == 1 and isinstance(args[0], schedule_node_expansion): + self.ctx = args[0].ctx + self.ptr = isl.isl_schedule_node_copy(args[0].ptr) + return + if len(args) == 1 and isinstance(args[0], schedule_node_extension): + self.ctx = args[0].ctx + self.ptr = isl.isl_schedule_node_copy(args[0].ptr) + return + if len(args) == 1 and isinstance(args[0], schedule_node_filter): + self.ctx = args[0].ctx + self.ptr = isl.isl_schedule_node_copy(args[0].ptr) + return + if len(args) == 1 and isinstance(args[0], schedule_node_leaf): + self.ctx = args[0].ctx + self.ptr = isl.isl_schedule_node_copy(args[0].ptr) + return + if len(args) == 1 and isinstance(args[0], schedule_node_guard): + self.ctx = args[0].ctx + self.ptr = isl.isl_schedule_node_copy(args[0].ptr) + return + if len(args) == 1 and isinstance(args[0], schedule_node_mark): + self.ctx = args[0].ctx + self.ptr = isl.isl_schedule_node_copy(args[0].ptr) + return + if len(args) == 1 and isinstance(args[0], schedule_node_sequence): + self.ctx = args[0].ctx + self.ptr = isl.isl_schedule_node_copy(args[0].ptr) + return + if len(args) == 1 and isinstance(args[0], schedule_node_set): + self.ctx = args[0].ctx + self.ptr = isl.isl_schedule_node_copy(args[0].ptr) + return + raise Error + def __del__(self): + if hasattr(self, 'ptr'): + isl.isl_schedule_node_free(self.ptr) + def __new__(cls, *args, **keywords): + if "ptr" in keywords: + type = isl.isl_schedule_node_get_type(keywords["ptr"]) + if type == 0: + return schedule_node_band(**keywords) + if type == 1: + return schedule_node_context(**keywords) + if type == 2: + return schedule_node_domain(**keywords) + if type == 3: + return schedule_node_expansion(**keywords) + if type == 4: + return schedule_node_extension(**keywords) + if type == 5: + return schedule_node_filter(**keywords) + if type == 6: + return schedule_node_leaf(**keywords) + if type == 7: + return schedule_node_guard(**keywords) + if type == 8: + return schedule_node_mark(**keywords) + if type == 9: + return schedule_node_sequence(**keywords) + if type == 10: + return schedule_node_set(**keywords) + raise Error + return super(schedule_node, cls).__new__(cls) + def __str__(arg0): + try: + if not arg0.__class__ is schedule_node: + arg0 = schedule_node(arg0) + except: + raise + ptr = isl.isl_schedule_node_to_str(arg0.ptr) + res = cast(ptr, c_char_p).value.decode('ascii') + libc.free(ptr) + return res + def __repr__(self): + s = str(self) + if '"' in s: + return 'isl.schedule_node("""%s""")' % s + else: + return 'isl.schedule_node("%s")' % s + def ancestor(arg0, arg1): + try: + if not arg0.__class__ is schedule_node: + arg0 = schedule_node(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_schedule_node_ancestor(isl.isl_schedule_node_copy(arg0.ptr), arg1) + obj = schedule_node(ctx=ctx, ptr=res) + return obj + def ancestor_child_position(arg0, arg1): + try: + if not arg0.__class__ is schedule_node: + arg0 = schedule_node(arg0) + except: + raise + try: + if not arg1.__class__ is schedule_node: + arg1 = schedule_node(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_schedule_node_get_ancestor_child_position(arg0.ptr, arg1.ptr) + if res < 0: + raise Error + return int(res) + def get_ancestor_child_position(arg0, arg1): + return arg0.ancestor_child_position(arg1) + def child(arg0, arg1): + try: + if not arg0.__class__ is schedule_node: + arg0 = schedule_node(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_schedule_node_child(isl.isl_schedule_node_copy(arg0.ptr), arg1) + obj = schedule_node(ctx=ctx, ptr=res) + return obj + def child_position(arg0): + try: + if not arg0.__class__ is schedule_node: + arg0 = schedule_node(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_schedule_node_get_child_position(arg0.ptr) + if res < 0: + raise Error + return int(res) + def get_child_position(arg0): + return arg0.child_position() + def every_descendant(arg0, arg1): + try: + if not arg0.__class__ is schedule_node: + arg0 = schedule_node(arg0) + except: + raise + exc_info = [None] + fn = CFUNCTYPE(c_int, c_void_p, c_void_p) + def cb_func(cb_arg0, cb_arg1): + cb_arg0 = schedule_node(ctx=arg0.ctx, ptr=isl.isl_schedule_node_copy(cb_arg0)) + try: + res = arg1(cb_arg0) + except BaseException as e: + exc_info[0] = e + return -1 + return 1 if res else 0 + cb1 = fn(cb_func) + ctx = arg0.ctx + res = isl.isl_schedule_node_every_descendant(arg0.ptr, cb1, None) + if exc_info[0] is not None: + raise exc_info[0] + if res < 0: + raise Error + return bool(res) + def first_child(arg0): + try: + if not arg0.__class__ is schedule_node: + arg0 = schedule_node(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_schedule_node_first_child(isl.isl_schedule_node_copy(arg0.ptr)) + obj = schedule_node(ctx=ctx, ptr=res) + return obj + def foreach_ancestor_top_down(arg0, arg1): + try: + if not arg0.__class__ is schedule_node: + arg0 = schedule_node(arg0) + except: + raise + exc_info = [None] + fn = CFUNCTYPE(c_int, c_void_p, c_void_p) + def cb_func(cb_arg0, cb_arg1): + cb_arg0 = schedule_node(ctx=arg0.ctx, ptr=isl.isl_schedule_node_copy(cb_arg0)) + try: + arg1(cb_arg0) + except BaseException as e: + exc_info[0] = e + return -1 + return 0 + cb1 = fn(cb_func) + ctx = arg0.ctx + res = isl.isl_schedule_node_foreach_ancestor_top_down(arg0.ptr, cb1, None) + if exc_info[0] is not None: + raise exc_info[0] + if res < 0: + raise Error + def foreach_descendant_top_down(arg0, arg1): + try: + if not arg0.__class__ is schedule_node: + arg0 = schedule_node(arg0) + except: + raise + exc_info = [None] + fn = CFUNCTYPE(c_int, c_void_p, c_void_p) + def cb_func(cb_arg0, cb_arg1): + cb_arg0 = schedule_node(ctx=arg0.ctx, ptr=isl.isl_schedule_node_copy(cb_arg0)) + try: + res = arg1(cb_arg0) + except BaseException as e: + exc_info[0] = e + return -1 + return 1 if res else 0 + cb1 = fn(cb_func) + ctx = arg0.ctx + res = isl.isl_schedule_node_foreach_descendant_top_down(arg0.ptr, cb1, None) + if exc_info[0] is not None: + raise exc_info[0] + if res < 0: + raise Error + @staticmethod + def from_domain(arg0): + try: + if not arg0.__class__ is union_set: + arg0 = union_set(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_schedule_node_from_domain(isl.isl_union_set_copy(arg0.ptr)) + obj = schedule_node(ctx=ctx, ptr=res) + return obj + @staticmethod + def from_extension(arg0): + try: + if not arg0.__class__ is union_map: + arg0 = union_map(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_schedule_node_from_extension(isl.isl_union_map_copy(arg0.ptr)) + obj = schedule_node(ctx=ctx, ptr=res) + return obj + def graft_after(arg0, arg1): + try: + if not arg0.__class__ is schedule_node: + arg0 = schedule_node(arg0) + except: + raise + try: + if not arg1.__class__ is schedule_node: + arg1 = schedule_node(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_schedule_node_graft_after(isl.isl_schedule_node_copy(arg0.ptr), isl.isl_schedule_node_copy(arg1.ptr)) + obj = schedule_node(ctx=ctx, ptr=res) + return obj + def graft_before(arg0, arg1): + try: + if not arg0.__class__ is schedule_node: + arg0 = schedule_node(arg0) + except: + raise + try: + if not arg1.__class__ is schedule_node: + arg1 = schedule_node(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_schedule_node_graft_before(isl.isl_schedule_node_copy(arg0.ptr), isl.isl_schedule_node_copy(arg1.ptr)) + obj = schedule_node(ctx=ctx, ptr=res) + return obj + def has_children(arg0): + try: + if not arg0.__class__ is schedule_node: + arg0 = schedule_node(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_schedule_node_has_children(arg0.ptr) + if res < 0: + raise Error + return bool(res) + def has_next_sibling(arg0): + try: + if not arg0.__class__ is schedule_node: + arg0 = schedule_node(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_schedule_node_has_next_sibling(arg0.ptr) + if res < 0: + raise Error + return bool(res) + def has_parent(arg0): + try: + if not arg0.__class__ is schedule_node: + arg0 = schedule_node(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_schedule_node_has_parent(arg0.ptr) + if res < 0: + raise Error + return bool(res) + def has_previous_sibling(arg0): + try: + if not arg0.__class__ is schedule_node: + arg0 = schedule_node(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_schedule_node_has_previous_sibling(arg0.ptr) + if res < 0: + raise Error + return bool(res) + def insert_context(arg0, arg1): + try: + if not arg0.__class__ is schedule_node: + arg0 = schedule_node(arg0) + except: + raise + try: + if not arg1.__class__ is set: + arg1 = set(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_schedule_node_insert_context(isl.isl_schedule_node_copy(arg0.ptr), isl.isl_set_copy(arg1.ptr)) + obj = schedule_node(ctx=ctx, ptr=res) + return obj + def insert_filter(arg0, arg1): + try: + if not arg0.__class__ is schedule_node: + arg0 = schedule_node(arg0) + except: + raise + try: + if not arg1.__class__ is union_set: + arg1 = union_set(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_schedule_node_insert_filter(isl.isl_schedule_node_copy(arg0.ptr), isl.isl_union_set_copy(arg1.ptr)) + obj = schedule_node(ctx=ctx, ptr=res) + return obj + def insert_guard(arg0, arg1): + try: + if not arg0.__class__ is schedule_node: + arg0 = schedule_node(arg0) + except: + raise + try: + if not arg1.__class__ is set: + arg1 = set(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_schedule_node_insert_guard(isl.isl_schedule_node_copy(arg0.ptr), isl.isl_set_copy(arg1.ptr)) + obj = schedule_node(ctx=ctx, ptr=res) + return obj + def insert_mark(arg0, arg1): + try: + if not arg0.__class__ is schedule_node: + arg0 = schedule_node(arg0) + except: + raise + try: + if not arg1.__class__ is id: + arg1 = id(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_schedule_node_insert_mark(isl.isl_schedule_node_copy(arg0.ptr), isl.isl_id_copy(arg1.ptr)) + obj = schedule_node(ctx=ctx, ptr=res) + return obj + def insert_partial_schedule(arg0, arg1): + try: + if not arg0.__class__ is schedule_node: + arg0 = schedule_node(arg0) + except: + raise + try: + if not arg1.__class__ is multi_union_pw_aff: + arg1 = multi_union_pw_aff(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_schedule_node_insert_partial_schedule(isl.isl_schedule_node_copy(arg0.ptr), isl.isl_multi_union_pw_aff_copy(arg1.ptr)) + obj = schedule_node(ctx=ctx, ptr=res) + return obj + def insert_sequence(arg0, arg1): + try: + if not arg0.__class__ is schedule_node: + arg0 = schedule_node(arg0) + except: + raise + try: + if not arg1.__class__ is union_set_list: + arg1 = union_set_list(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_schedule_node_insert_sequence(isl.isl_schedule_node_copy(arg0.ptr), isl.isl_union_set_list_copy(arg1.ptr)) + obj = schedule_node(ctx=ctx, ptr=res) + return obj + def insert_set(arg0, arg1): + try: + if not arg0.__class__ is schedule_node: + arg0 = schedule_node(arg0) + except: + raise + try: + if not arg1.__class__ is union_set_list: + arg1 = union_set_list(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_schedule_node_insert_set(isl.isl_schedule_node_copy(arg0.ptr), isl.isl_union_set_list_copy(arg1.ptr)) + obj = schedule_node(ctx=ctx, ptr=res) + return obj + def is_equal(arg0, arg1): + try: + if not arg0.__class__ is schedule_node: + arg0 = schedule_node(arg0) + except: + raise + try: + if not arg1.__class__ is schedule_node: + arg1 = schedule_node(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_schedule_node_is_equal(arg0.ptr, arg1.ptr) + if res < 0: + raise Error + return bool(res) + def is_subtree_anchored(arg0): + try: + if not arg0.__class__ is schedule_node: + arg0 = schedule_node(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_schedule_node_is_subtree_anchored(arg0.ptr) + if res < 0: + raise Error + return bool(res) + def map_descendant_bottom_up(arg0, arg1): + try: + if not arg0.__class__ is schedule_node: + arg0 = schedule_node(arg0) + except: + raise + exc_info = [None] + fn = CFUNCTYPE(c_void_p, c_void_p, c_void_p) + def cb_func(cb_arg0, cb_arg1): + cb_arg0 = schedule_node(ctx=arg0.ctx, ptr=(cb_arg0)) + try: + res = arg1(cb_arg0) + except BaseException as e: + exc_info[0] = e + return None + return isl.isl_schedule_node_copy(res.ptr) + cb1 = fn(cb_func) + ctx = arg0.ctx + res = isl.isl_schedule_node_map_descendant_bottom_up(isl.isl_schedule_node_copy(arg0.ptr), cb1, None) + if exc_info[0] is not None: + raise exc_info[0] + obj = schedule_node(ctx=ctx, ptr=res) + return obj + def n_children(arg0): + try: + if not arg0.__class__ is schedule_node: + arg0 = schedule_node(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_schedule_node_n_children(arg0.ptr) + if res < 0: + raise Error + return int(res) + def next_sibling(arg0): + try: + if not arg0.__class__ is schedule_node: + arg0 = schedule_node(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_schedule_node_next_sibling(isl.isl_schedule_node_copy(arg0.ptr)) + obj = schedule_node(ctx=ctx, ptr=res) + return obj + def order_after(arg0, arg1): + try: + if not arg0.__class__ is schedule_node: + arg0 = schedule_node(arg0) + except: + raise + try: + if not arg1.__class__ is union_set: + arg1 = union_set(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_schedule_node_order_after(isl.isl_schedule_node_copy(arg0.ptr), isl.isl_union_set_copy(arg1.ptr)) + obj = schedule_node(ctx=ctx, ptr=res) + return obj + def order_before(arg0, arg1): + try: + if not arg0.__class__ is schedule_node: + arg0 = schedule_node(arg0) + except: + raise + try: + if not arg1.__class__ is union_set: + arg1 = union_set(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_schedule_node_order_before(isl.isl_schedule_node_copy(arg0.ptr), isl.isl_union_set_copy(arg1.ptr)) + obj = schedule_node(ctx=ctx, ptr=res) + return obj + def parent(arg0): + try: + if not arg0.__class__ is schedule_node: + arg0 = schedule_node(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_schedule_node_parent(isl.isl_schedule_node_copy(arg0.ptr)) + obj = schedule_node(ctx=ctx, ptr=res) + return obj + def prefix_schedule_multi_union_pw_aff(arg0): + try: + if not arg0.__class__ is schedule_node: + arg0 = schedule_node(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_schedule_node_get_prefix_schedule_multi_union_pw_aff(arg0.ptr) + obj = multi_union_pw_aff(ctx=ctx, ptr=res) + return obj + def get_prefix_schedule_multi_union_pw_aff(arg0): + return arg0.prefix_schedule_multi_union_pw_aff() + def prefix_schedule_union_map(arg0): + try: + if not arg0.__class__ is schedule_node: + arg0 = schedule_node(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_schedule_node_get_prefix_schedule_union_map(arg0.ptr) + obj = union_map(ctx=ctx, ptr=res) + return obj + def get_prefix_schedule_union_map(arg0): + return arg0.prefix_schedule_union_map() + def prefix_schedule_union_pw_multi_aff(arg0): + try: + if not arg0.__class__ is schedule_node: + arg0 = schedule_node(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_schedule_node_get_prefix_schedule_union_pw_multi_aff(arg0.ptr) + obj = union_pw_multi_aff(ctx=ctx, ptr=res) + return obj + def get_prefix_schedule_union_pw_multi_aff(arg0): + return arg0.prefix_schedule_union_pw_multi_aff() + def previous_sibling(arg0): + try: + if not arg0.__class__ is schedule_node: + arg0 = schedule_node(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_schedule_node_previous_sibling(isl.isl_schedule_node_copy(arg0.ptr)) + obj = schedule_node(ctx=ctx, ptr=res) + return obj + def root(arg0): + try: + if not arg0.__class__ is schedule_node: + arg0 = schedule_node(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_schedule_node_root(isl.isl_schedule_node_copy(arg0.ptr)) + obj = schedule_node(ctx=ctx, ptr=res) + return obj + def schedule(arg0): + try: + if not arg0.__class__ is schedule_node: + arg0 = schedule_node(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_schedule_node_get_schedule(arg0.ptr) + obj = schedule(ctx=ctx, ptr=res) + return obj + def get_schedule(arg0): + return arg0.schedule() + def shared_ancestor(arg0, arg1): + try: + if not arg0.__class__ is schedule_node: + arg0 = schedule_node(arg0) + except: + raise + try: + if not arg1.__class__ is schedule_node: + arg1 = schedule_node(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_schedule_node_get_shared_ancestor(arg0.ptr, arg1.ptr) + obj = schedule_node(ctx=ctx, ptr=res) + return obj + def get_shared_ancestor(arg0, arg1): + return arg0.shared_ancestor(arg1) + def tree_depth(arg0): + try: + if not arg0.__class__ is schedule_node: + arg0 = schedule_node(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_schedule_node_get_tree_depth(arg0.ptr) + if res < 0: + raise Error + return int(res) + def get_tree_depth(arg0): + return arg0.tree_depth() + +isl.isl_schedule_node_ancestor.restype = c_void_p +isl.isl_schedule_node_ancestor.argtypes = [c_void_p, c_int] +isl.isl_schedule_node_get_ancestor_child_position.argtypes = [c_void_p, c_void_p] +isl.isl_schedule_node_child.restype = c_void_p +isl.isl_schedule_node_child.argtypes = [c_void_p, c_int] +isl.isl_schedule_node_get_child_position.argtypes = [c_void_p] +isl.isl_schedule_node_every_descendant.argtypes = [c_void_p, c_void_p, c_void_p] +isl.isl_schedule_node_first_child.restype = c_void_p +isl.isl_schedule_node_first_child.argtypes = [c_void_p] +isl.isl_schedule_node_foreach_ancestor_top_down.argtypes = [c_void_p, c_void_p, c_void_p] +isl.isl_schedule_node_foreach_descendant_top_down.argtypes = [c_void_p, c_void_p, c_void_p] +isl.isl_schedule_node_from_domain.restype = c_void_p +isl.isl_schedule_node_from_domain.argtypes = [c_void_p] +isl.isl_schedule_node_from_extension.restype = c_void_p +isl.isl_schedule_node_from_extension.argtypes = [c_void_p] +isl.isl_schedule_node_graft_after.restype = c_void_p +isl.isl_schedule_node_graft_after.argtypes = [c_void_p, c_void_p] +isl.isl_schedule_node_graft_before.restype = c_void_p +isl.isl_schedule_node_graft_before.argtypes = [c_void_p, c_void_p] +isl.isl_schedule_node_has_children.argtypes = [c_void_p] +isl.isl_schedule_node_has_next_sibling.argtypes = [c_void_p] +isl.isl_schedule_node_has_parent.argtypes = [c_void_p] +isl.isl_schedule_node_has_previous_sibling.argtypes = [c_void_p] +isl.isl_schedule_node_insert_context.restype = c_void_p +isl.isl_schedule_node_insert_context.argtypes = [c_void_p, c_void_p] +isl.isl_schedule_node_insert_filter.restype = c_void_p +isl.isl_schedule_node_insert_filter.argtypes = [c_void_p, c_void_p] +isl.isl_schedule_node_insert_guard.restype = c_void_p +isl.isl_schedule_node_insert_guard.argtypes = [c_void_p, c_void_p] +isl.isl_schedule_node_insert_mark.restype = c_void_p +isl.isl_schedule_node_insert_mark.argtypes = [c_void_p, c_void_p] +isl.isl_schedule_node_insert_partial_schedule.restype = c_void_p +isl.isl_schedule_node_insert_partial_schedule.argtypes = [c_void_p, c_void_p] +isl.isl_schedule_node_insert_sequence.restype = c_void_p +isl.isl_schedule_node_insert_sequence.argtypes = [c_void_p, c_void_p] +isl.isl_schedule_node_insert_set.restype = c_void_p +isl.isl_schedule_node_insert_set.argtypes = [c_void_p, c_void_p] +isl.isl_schedule_node_is_equal.argtypes = [c_void_p, c_void_p] +isl.isl_schedule_node_is_subtree_anchored.argtypes = [c_void_p] +isl.isl_schedule_node_map_descendant_bottom_up.restype = c_void_p +isl.isl_schedule_node_map_descendant_bottom_up.argtypes = [c_void_p, c_void_p, c_void_p] +isl.isl_schedule_node_n_children.argtypes = [c_void_p] +isl.isl_schedule_node_next_sibling.restype = c_void_p +isl.isl_schedule_node_next_sibling.argtypes = [c_void_p] +isl.isl_schedule_node_order_after.restype = c_void_p +isl.isl_schedule_node_order_after.argtypes = [c_void_p, c_void_p] +isl.isl_schedule_node_order_before.restype = c_void_p +isl.isl_schedule_node_order_before.argtypes = [c_void_p, c_void_p] +isl.isl_schedule_node_parent.restype = c_void_p +isl.isl_schedule_node_parent.argtypes = [c_void_p] +isl.isl_schedule_node_get_prefix_schedule_multi_union_pw_aff.restype = c_void_p +isl.isl_schedule_node_get_prefix_schedule_multi_union_pw_aff.argtypes = [c_void_p] +isl.isl_schedule_node_get_prefix_schedule_union_map.restype = c_void_p +isl.isl_schedule_node_get_prefix_schedule_union_map.argtypes = [c_void_p] +isl.isl_schedule_node_get_prefix_schedule_union_pw_multi_aff.restype = c_void_p +isl.isl_schedule_node_get_prefix_schedule_union_pw_multi_aff.argtypes = [c_void_p] +isl.isl_schedule_node_previous_sibling.restype = c_void_p +isl.isl_schedule_node_previous_sibling.argtypes = [c_void_p] +isl.isl_schedule_node_root.restype = c_void_p +isl.isl_schedule_node_root.argtypes = [c_void_p] +isl.isl_schedule_node_get_schedule.restype = c_void_p +isl.isl_schedule_node_get_schedule.argtypes = [c_void_p] +isl.isl_schedule_node_get_shared_ancestor.restype = c_void_p +isl.isl_schedule_node_get_shared_ancestor.argtypes = [c_void_p, c_void_p] +isl.isl_schedule_node_get_tree_depth.argtypes = [c_void_p] +isl.isl_schedule_node_copy.restype = c_void_p +isl.isl_schedule_node_copy.argtypes = [c_void_p] +isl.isl_schedule_node_free.restype = c_void_p +isl.isl_schedule_node_free.argtypes = [c_void_p] +isl.isl_schedule_node_to_str.restype = POINTER(c_char) +isl.isl_schedule_node_to_str.argtypes = [c_void_p] +isl.isl_schedule_node_get_type.argtypes = [c_void_p] + +class schedule_node_band(schedule_node): + def __init__(self, *args, **keywords): + if "ptr" in keywords: + self.ctx = keywords["ctx"] + self.ptr = keywords["ptr"] + return + raise Error + def __del__(self): + if hasattr(self, 'ptr'): + isl.isl_schedule_node_free(self.ptr) + def __new__(cls, *args, **keywords): + return super(schedule_node_band, cls).__new__(cls) + def __str__(arg0): + try: + if not arg0.__class__ is schedule_node_band: + arg0 = schedule_node_band(arg0) + except: + raise + ptr = isl.isl_schedule_node_to_str(arg0.ptr) + res = cast(ptr, c_char_p).value.decode('ascii') + libc.free(ptr) + return res + def __repr__(self): + s = str(self) + if '"' in s: + return 'isl.schedule_node_band("""%s""")' % s + else: + return 'isl.schedule_node_band("%s")' % s + def ast_build_options(arg0): + try: + if not arg0.__class__ is schedule_node: + arg0 = schedule_node(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_schedule_node_band_get_ast_build_options(arg0.ptr) + obj = union_set(ctx=ctx, ptr=res) + return obj + def get_ast_build_options(arg0): + return arg0.ast_build_options() + def ast_isolate_option(arg0): + try: + if not arg0.__class__ is schedule_node: + arg0 = schedule_node(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_schedule_node_band_get_ast_isolate_option(arg0.ptr) + obj = set(ctx=ctx, ptr=res) + return obj + def get_ast_isolate_option(arg0): + return arg0.ast_isolate_option() + def member_get_coincident(arg0, arg1): + try: + if not arg0.__class__ is schedule_node: + arg0 = schedule_node(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_schedule_node_band_member_get_coincident(arg0.ptr, arg1) + if res < 0: + raise Error + return bool(res) + def member_set_coincident(arg0, arg1, arg2): + try: + if not arg0.__class__ is schedule_node: + arg0 = schedule_node(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_schedule_node_band_member_set_coincident(isl.isl_schedule_node_copy(arg0.ptr), arg1, arg2) + obj = schedule_node(ctx=ctx, ptr=res) + return obj + def mod(arg0, arg1): + try: + if not arg0.__class__ is schedule_node: + arg0 = schedule_node(arg0) + except: + raise + try: + if not arg1.__class__ is multi_val: + arg1 = multi_val(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_schedule_node_band_mod(isl.isl_schedule_node_copy(arg0.ptr), isl.isl_multi_val_copy(arg1.ptr)) + obj = schedule_node(ctx=ctx, ptr=res) + return obj + def n_member(arg0): + try: + if not arg0.__class__ is schedule_node: + arg0 = schedule_node(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_schedule_node_band_n_member(arg0.ptr) + if res < 0: + raise Error + return int(res) + def partial_schedule(arg0): + try: + if not arg0.__class__ is schedule_node: + arg0 = schedule_node(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_schedule_node_band_get_partial_schedule(arg0.ptr) + obj = multi_union_pw_aff(ctx=ctx, ptr=res) + return obj + def get_partial_schedule(arg0): + return arg0.partial_schedule() + def permutable(arg0): + try: + if not arg0.__class__ is schedule_node: + arg0 = schedule_node(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_schedule_node_band_get_permutable(arg0.ptr) + if res < 0: + raise Error + return bool(res) + def get_permutable(arg0): + return arg0.permutable() + def scale(arg0, arg1): + try: + if not arg0.__class__ is schedule_node: + arg0 = schedule_node(arg0) + except: + raise + try: + if not arg1.__class__ is multi_val: + arg1 = multi_val(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_schedule_node_band_scale(isl.isl_schedule_node_copy(arg0.ptr), isl.isl_multi_val_copy(arg1.ptr)) + obj = schedule_node(ctx=ctx, ptr=res) + return obj + def scale_down(arg0, arg1): + try: + if not arg0.__class__ is schedule_node: + arg0 = schedule_node(arg0) + except: + raise + try: + if not arg1.__class__ is multi_val: + arg1 = multi_val(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_schedule_node_band_scale_down(isl.isl_schedule_node_copy(arg0.ptr), isl.isl_multi_val_copy(arg1.ptr)) + obj = schedule_node(ctx=ctx, ptr=res) + return obj + def set_ast_build_options(arg0, arg1): + try: + if not arg0.__class__ is schedule_node: + arg0 = schedule_node(arg0) + except: + raise + try: + if not arg1.__class__ is union_set: + arg1 = union_set(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_schedule_node_band_set_ast_build_options(isl.isl_schedule_node_copy(arg0.ptr), isl.isl_union_set_copy(arg1.ptr)) + obj = schedule_node(ctx=ctx, ptr=res) + return obj + def set_permutable(arg0, arg1): + try: + if not arg0.__class__ is schedule_node: + arg0 = schedule_node(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_schedule_node_band_set_permutable(isl.isl_schedule_node_copy(arg0.ptr), arg1) + obj = schedule_node(ctx=ctx, ptr=res) + return obj + def shift(arg0, arg1): + try: + if not arg0.__class__ is schedule_node: + arg0 = schedule_node(arg0) + except: + raise + try: + if not arg1.__class__ is multi_union_pw_aff: + arg1 = multi_union_pw_aff(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_schedule_node_band_shift(isl.isl_schedule_node_copy(arg0.ptr), isl.isl_multi_union_pw_aff_copy(arg1.ptr)) + obj = schedule_node(ctx=ctx, ptr=res) + return obj + def split(arg0, arg1): + try: + if not arg0.__class__ is schedule_node: + arg0 = schedule_node(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_schedule_node_band_split(isl.isl_schedule_node_copy(arg0.ptr), arg1) + obj = schedule_node(ctx=ctx, ptr=res) + return obj + def tile(arg0, arg1): + try: + if not arg0.__class__ is schedule_node: + arg0 = schedule_node(arg0) + except: + raise + try: + if not arg1.__class__ is multi_val: + arg1 = multi_val(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_schedule_node_band_tile(isl.isl_schedule_node_copy(arg0.ptr), isl.isl_multi_val_copy(arg1.ptr)) + obj = schedule_node(ctx=ctx, ptr=res) + return obj + def member_set_ast_loop_default(arg0, arg1): + try: + if not arg0.__class__ is schedule_node: + arg0 = schedule_node(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_schedule_node_band_member_set_ast_loop_type(isl.isl_schedule_node_copy(arg0.ptr), arg1, 0) + obj = schedule_node(ctx=ctx, ptr=res) + return obj + def member_set_ast_loop_atomic(arg0, arg1): + try: + if not arg0.__class__ is schedule_node: + arg0 = schedule_node(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_schedule_node_band_member_set_ast_loop_type(isl.isl_schedule_node_copy(arg0.ptr), arg1, 1) + obj = schedule_node(ctx=ctx, ptr=res) + return obj + def member_set_ast_loop_unroll(arg0, arg1): + try: + if not arg0.__class__ is schedule_node: + arg0 = schedule_node(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_schedule_node_band_member_set_ast_loop_type(isl.isl_schedule_node_copy(arg0.ptr), arg1, 2) + obj = schedule_node(ctx=ctx, ptr=res) + return obj + def member_set_ast_loop_separate(arg0, arg1): + try: + if not arg0.__class__ is schedule_node: + arg0 = schedule_node(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_schedule_node_band_member_set_ast_loop_type(isl.isl_schedule_node_copy(arg0.ptr), arg1, 3) + obj = schedule_node(ctx=ctx, ptr=res) + return obj + +isl.isl_schedule_node_band_get_ast_build_options.restype = c_void_p +isl.isl_schedule_node_band_get_ast_build_options.argtypes = [c_void_p] +isl.isl_schedule_node_band_get_ast_isolate_option.restype = c_void_p +isl.isl_schedule_node_band_get_ast_isolate_option.argtypes = [c_void_p] +isl.isl_schedule_node_band_member_get_coincident.argtypes = [c_void_p, c_int] +isl.isl_schedule_node_band_member_set_coincident.restype = c_void_p +isl.isl_schedule_node_band_member_set_coincident.argtypes = [c_void_p, c_int, c_int] +isl.isl_schedule_node_band_mod.restype = c_void_p +isl.isl_schedule_node_band_mod.argtypes = [c_void_p, c_void_p] +isl.isl_schedule_node_band_n_member.argtypes = [c_void_p] +isl.isl_schedule_node_band_get_partial_schedule.restype = c_void_p +isl.isl_schedule_node_band_get_partial_schedule.argtypes = [c_void_p] +isl.isl_schedule_node_band_get_permutable.argtypes = [c_void_p] +isl.isl_schedule_node_band_scale.restype = c_void_p +isl.isl_schedule_node_band_scale.argtypes = [c_void_p, c_void_p] +isl.isl_schedule_node_band_scale_down.restype = c_void_p +isl.isl_schedule_node_band_scale_down.argtypes = [c_void_p, c_void_p] +isl.isl_schedule_node_band_set_ast_build_options.restype = c_void_p +isl.isl_schedule_node_band_set_ast_build_options.argtypes = [c_void_p, c_void_p] +isl.isl_schedule_node_band_set_permutable.restype = c_void_p +isl.isl_schedule_node_band_set_permutable.argtypes = [c_void_p, c_int] +isl.isl_schedule_node_band_shift.restype = c_void_p +isl.isl_schedule_node_band_shift.argtypes = [c_void_p, c_void_p] +isl.isl_schedule_node_band_split.restype = c_void_p +isl.isl_schedule_node_band_split.argtypes = [c_void_p, c_int] +isl.isl_schedule_node_band_tile.restype = c_void_p +isl.isl_schedule_node_band_tile.argtypes = [c_void_p, c_void_p] +isl.isl_schedule_node_band_member_set_ast_loop_type.restype = c_void_p +isl.isl_schedule_node_band_member_set_ast_loop_type.argtypes = [c_void_p, c_int, c_int] +isl.isl_schedule_node_copy.restype = c_void_p +isl.isl_schedule_node_copy.argtypes = [c_void_p] +isl.isl_schedule_node_free.restype = c_void_p +isl.isl_schedule_node_free.argtypes = [c_void_p] +isl.isl_schedule_node_to_str.restype = POINTER(c_char) +isl.isl_schedule_node_to_str.argtypes = [c_void_p] + +class schedule_node_context(schedule_node): + def __init__(self, *args, **keywords): + if "ptr" in keywords: + self.ctx = keywords["ctx"] + self.ptr = keywords["ptr"] + return + raise Error + def __del__(self): + if hasattr(self, 'ptr'): + isl.isl_schedule_node_free(self.ptr) + def __new__(cls, *args, **keywords): + return super(schedule_node_context, cls).__new__(cls) + def __str__(arg0): + try: + if not arg0.__class__ is schedule_node_context: + arg0 = schedule_node_context(arg0) + except: + raise + ptr = isl.isl_schedule_node_to_str(arg0.ptr) + res = cast(ptr, c_char_p).value.decode('ascii') + libc.free(ptr) + return res + def __repr__(self): + s = str(self) + if '"' in s: + return 'isl.schedule_node_context("""%s""")' % s + else: + return 'isl.schedule_node_context("%s")' % s + def context(arg0): + try: + if not arg0.__class__ is schedule_node: + arg0 = schedule_node(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_schedule_node_context_get_context(arg0.ptr) + obj = set(ctx=ctx, ptr=res) + return obj + def get_context(arg0): + return arg0.context() + +isl.isl_schedule_node_context_get_context.restype = c_void_p +isl.isl_schedule_node_context_get_context.argtypes = [c_void_p] +isl.isl_schedule_node_copy.restype = c_void_p +isl.isl_schedule_node_copy.argtypes = [c_void_p] +isl.isl_schedule_node_free.restype = c_void_p +isl.isl_schedule_node_free.argtypes = [c_void_p] +isl.isl_schedule_node_to_str.restype = POINTER(c_char) +isl.isl_schedule_node_to_str.argtypes = [c_void_p] + +class schedule_node_domain(schedule_node): + def __init__(self, *args, **keywords): + if "ptr" in keywords: + self.ctx = keywords["ctx"] + self.ptr = keywords["ptr"] + return + raise Error + def __del__(self): + if hasattr(self, 'ptr'): + isl.isl_schedule_node_free(self.ptr) + def __new__(cls, *args, **keywords): + return super(schedule_node_domain, cls).__new__(cls) + def __str__(arg0): + try: + if not arg0.__class__ is schedule_node_domain: + arg0 = schedule_node_domain(arg0) + except: + raise + ptr = isl.isl_schedule_node_to_str(arg0.ptr) + res = cast(ptr, c_char_p).value.decode('ascii') + libc.free(ptr) + return res + def __repr__(self): + s = str(self) + if '"' in s: + return 'isl.schedule_node_domain("""%s""")' % s + else: + return 'isl.schedule_node_domain("%s")' % s + def domain(arg0): + try: + if not arg0.__class__ is schedule_node: + arg0 = schedule_node(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_schedule_node_domain_get_domain(arg0.ptr) + obj = union_set(ctx=ctx, ptr=res) + return obj + def get_domain(arg0): + return arg0.domain() + +isl.isl_schedule_node_domain_get_domain.restype = c_void_p +isl.isl_schedule_node_domain_get_domain.argtypes = [c_void_p] +isl.isl_schedule_node_copy.restype = c_void_p +isl.isl_schedule_node_copy.argtypes = [c_void_p] +isl.isl_schedule_node_free.restype = c_void_p +isl.isl_schedule_node_free.argtypes = [c_void_p] +isl.isl_schedule_node_to_str.restype = POINTER(c_char) +isl.isl_schedule_node_to_str.argtypes = [c_void_p] + +class schedule_node_expansion(schedule_node): + def __init__(self, *args, **keywords): + if "ptr" in keywords: + self.ctx = keywords["ctx"] + self.ptr = keywords["ptr"] + return + raise Error + def __del__(self): + if hasattr(self, 'ptr'): + isl.isl_schedule_node_free(self.ptr) + def __new__(cls, *args, **keywords): + return super(schedule_node_expansion, cls).__new__(cls) + def __str__(arg0): + try: + if not arg0.__class__ is schedule_node_expansion: + arg0 = schedule_node_expansion(arg0) + except: + raise + ptr = isl.isl_schedule_node_to_str(arg0.ptr) + res = cast(ptr, c_char_p).value.decode('ascii') + libc.free(ptr) + return res + def __repr__(self): + s = str(self) + if '"' in s: + return 'isl.schedule_node_expansion("""%s""")' % s + else: + return 'isl.schedule_node_expansion("%s")' % s + def contraction(arg0): + try: + if not arg0.__class__ is schedule_node: + arg0 = schedule_node(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_schedule_node_expansion_get_contraction(arg0.ptr) + obj = union_pw_multi_aff(ctx=ctx, ptr=res) + return obj + def get_contraction(arg0): + return arg0.contraction() + def expansion(arg0): + try: + if not arg0.__class__ is schedule_node: + arg0 = schedule_node(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_schedule_node_expansion_get_expansion(arg0.ptr) + obj = union_map(ctx=ctx, ptr=res) + return obj + def get_expansion(arg0): + return arg0.expansion() + +isl.isl_schedule_node_expansion_get_contraction.restype = c_void_p +isl.isl_schedule_node_expansion_get_contraction.argtypes = [c_void_p] +isl.isl_schedule_node_expansion_get_expansion.restype = c_void_p +isl.isl_schedule_node_expansion_get_expansion.argtypes = [c_void_p] +isl.isl_schedule_node_copy.restype = c_void_p +isl.isl_schedule_node_copy.argtypes = [c_void_p] +isl.isl_schedule_node_free.restype = c_void_p +isl.isl_schedule_node_free.argtypes = [c_void_p] +isl.isl_schedule_node_to_str.restype = POINTER(c_char) +isl.isl_schedule_node_to_str.argtypes = [c_void_p] + +class schedule_node_extension(schedule_node): + def __init__(self, *args, **keywords): + if "ptr" in keywords: + self.ctx = keywords["ctx"] + self.ptr = keywords["ptr"] + return + raise Error + def __del__(self): + if hasattr(self, 'ptr'): + isl.isl_schedule_node_free(self.ptr) + def __new__(cls, *args, **keywords): + return super(schedule_node_extension, cls).__new__(cls) + def __str__(arg0): + try: + if not arg0.__class__ is schedule_node_extension: + arg0 = schedule_node_extension(arg0) + except: + raise + ptr = isl.isl_schedule_node_to_str(arg0.ptr) + res = cast(ptr, c_char_p).value.decode('ascii') + libc.free(ptr) + return res + def __repr__(self): + s = str(self) + if '"' in s: + return 'isl.schedule_node_extension("""%s""")' % s + else: + return 'isl.schedule_node_extension("%s")' % s + def extension(arg0): + try: + if not arg0.__class__ is schedule_node: + arg0 = schedule_node(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_schedule_node_extension_get_extension(arg0.ptr) + obj = union_map(ctx=ctx, ptr=res) + return obj + def get_extension(arg0): + return arg0.extension() + +isl.isl_schedule_node_extension_get_extension.restype = c_void_p +isl.isl_schedule_node_extension_get_extension.argtypes = [c_void_p] +isl.isl_schedule_node_copy.restype = c_void_p +isl.isl_schedule_node_copy.argtypes = [c_void_p] +isl.isl_schedule_node_free.restype = c_void_p +isl.isl_schedule_node_free.argtypes = [c_void_p] +isl.isl_schedule_node_to_str.restype = POINTER(c_char) +isl.isl_schedule_node_to_str.argtypes = [c_void_p] + +class schedule_node_filter(schedule_node): + def __init__(self, *args, **keywords): + if "ptr" in keywords: + self.ctx = keywords["ctx"] + self.ptr = keywords["ptr"] + return + raise Error + def __del__(self): + if hasattr(self, 'ptr'): + isl.isl_schedule_node_free(self.ptr) + def __new__(cls, *args, **keywords): + return super(schedule_node_filter, cls).__new__(cls) + def __str__(arg0): + try: + if not arg0.__class__ is schedule_node_filter: + arg0 = schedule_node_filter(arg0) + except: + raise + ptr = isl.isl_schedule_node_to_str(arg0.ptr) + res = cast(ptr, c_char_p).value.decode('ascii') + libc.free(ptr) + return res + def __repr__(self): + s = str(self) + if '"' in s: + return 'isl.schedule_node_filter("""%s""")' % s + else: + return 'isl.schedule_node_filter("%s")' % s + def filter(arg0): + try: + if not arg0.__class__ is schedule_node: + arg0 = schedule_node(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_schedule_node_filter_get_filter(arg0.ptr) + obj = union_set(ctx=ctx, ptr=res) + return obj + def get_filter(arg0): + return arg0.filter() + +isl.isl_schedule_node_filter_get_filter.restype = c_void_p +isl.isl_schedule_node_filter_get_filter.argtypes = [c_void_p] +isl.isl_schedule_node_copy.restype = c_void_p +isl.isl_schedule_node_copy.argtypes = [c_void_p] +isl.isl_schedule_node_free.restype = c_void_p +isl.isl_schedule_node_free.argtypes = [c_void_p] +isl.isl_schedule_node_to_str.restype = POINTER(c_char) +isl.isl_schedule_node_to_str.argtypes = [c_void_p] + +class schedule_node_guard(schedule_node): + def __init__(self, *args, **keywords): + if "ptr" in keywords: + self.ctx = keywords["ctx"] + self.ptr = keywords["ptr"] + return + raise Error + def __del__(self): + if hasattr(self, 'ptr'): + isl.isl_schedule_node_free(self.ptr) + def __new__(cls, *args, **keywords): + return super(schedule_node_guard, cls).__new__(cls) + def __str__(arg0): + try: + if not arg0.__class__ is schedule_node_guard: + arg0 = schedule_node_guard(arg0) + except: + raise + ptr = isl.isl_schedule_node_to_str(arg0.ptr) + res = cast(ptr, c_char_p).value.decode('ascii') + libc.free(ptr) + return res + def __repr__(self): + s = str(self) + if '"' in s: + return 'isl.schedule_node_guard("""%s""")' % s + else: + return 'isl.schedule_node_guard("%s")' % s + def guard(arg0): + try: + if not arg0.__class__ is schedule_node: + arg0 = schedule_node(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_schedule_node_guard_get_guard(arg0.ptr) + obj = set(ctx=ctx, ptr=res) + return obj + def get_guard(arg0): + return arg0.guard() + +isl.isl_schedule_node_guard_get_guard.restype = c_void_p +isl.isl_schedule_node_guard_get_guard.argtypes = [c_void_p] +isl.isl_schedule_node_copy.restype = c_void_p +isl.isl_schedule_node_copy.argtypes = [c_void_p] +isl.isl_schedule_node_free.restype = c_void_p +isl.isl_schedule_node_free.argtypes = [c_void_p] +isl.isl_schedule_node_to_str.restype = POINTER(c_char) +isl.isl_schedule_node_to_str.argtypes = [c_void_p] + +class schedule_node_leaf(schedule_node): + def __init__(self, *args, **keywords): + if "ptr" in keywords: + self.ctx = keywords["ctx"] + self.ptr = keywords["ptr"] + return + raise Error + def __del__(self): + if hasattr(self, 'ptr'): + isl.isl_schedule_node_free(self.ptr) + def __new__(cls, *args, **keywords): + return super(schedule_node_leaf, cls).__new__(cls) + def __str__(arg0): + try: + if not arg0.__class__ is schedule_node_leaf: + arg0 = schedule_node_leaf(arg0) + except: + raise + ptr = isl.isl_schedule_node_to_str(arg0.ptr) + res = cast(ptr, c_char_p).value.decode('ascii') + libc.free(ptr) + return res + def __repr__(self): + s = str(self) + if '"' in s: + return 'isl.schedule_node_leaf("""%s""")' % s + else: + return 'isl.schedule_node_leaf("%s")' % s + +isl.isl_schedule_node_copy.restype = c_void_p +isl.isl_schedule_node_copy.argtypes = [c_void_p] +isl.isl_schedule_node_free.restype = c_void_p +isl.isl_schedule_node_free.argtypes = [c_void_p] +isl.isl_schedule_node_to_str.restype = POINTER(c_char) +isl.isl_schedule_node_to_str.argtypes = [c_void_p] + +class schedule_node_mark(schedule_node): + def __init__(self, *args, **keywords): + if "ptr" in keywords: + self.ctx = keywords["ctx"] + self.ptr = keywords["ptr"] + return + raise Error + def __del__(self): + if hasattr(self, 'ptr'): + isl.isl_schedule_node_free(self.ptr) + def __new__(cls, *args, **keywords): + return super(schedule_node_mark, cls).__new__(cls) + def __str__(arg0): + try: + if not arg0.__class__ is schedule_node_mark: + arg0 = schedule_node_mark(arg0) + except: + raise + ptr = isl.isl_schedule_node_to_str(arg0.ptr) + res = cast(ptr, c_char_p).value.decode('ascii') + libc.free(ptr) + return res + def __repr__(self): + s = str(self) + if '"' in s: + return 'isl.schedule_node_mark("""%s""")' % s + else: + return 'isl.schedule_node_mark("%s")' % s + +isl.isl_schedule_node_copy.restype = c_void_p +isl.isl_schedule_node_copy.argtypes = [c_void_p] +isl.isl_schedule_node_free.restype = c_void_p +isl.isl_schedule_node_free.argtypes = [c_void_p] +isl.isl_schedule_node_to_str.restype = POINTER(c_char) +isl.isl_schedule_node_to_str.argtypes = [c_void_p] + +class schedule_node_sequence(schedule_node): + def __init__(self, *args, **keywords): + if "ptr" in keywords: + self.ctx = keywords["ctx"] + self.ptr = keywords["ptr"] + return + raise Error + def __del__(self): + if hasattr(self, 'ptr'): + isl.isl_schedule_node_free(self.ptr) + def __new__(cls, *args, **keywords): + return super(schedule_node_sequence, cls).__new__(cls) + def __str__(arg0): + try: + if not arg0.__class__ is schedule_node_sequence: + arg0 = schedule_node_sequence(arg0) + except: + raise + ptr = isl.isl_schedule_node_to_str(arg0.ptr) + res = cast(ptr, c_char_p).value.decode('ascii') + libc.free(ptr) + return res + def __repr__(self): + s = str(self) + if '"' in s: + return 'isl.schedule_node_sequence("""%s""")' % s + else: + return 'isl.schedule_node_sequence("%s")' % s + +isl.isl_schedule_node_copy.restype = c_void_p +isl.isl_schedule_node_copy.argtypes = [c_void_p] +isl.isl_schedule_node_free.restype = c_void_p +isl.isl_schedule_node_free.argtypes = [c_void_p] +isl.isl_schedule_node_to_str.restype = POINTER(c_char) +isl.isl_schedule_node_to_str.argtypes = [c_void_p] + +class schedule_node_set(schedule_node): + def __init__(self, *args, **keywords): + if "ptr" in keywords: + self.ctx = keywords["ctx"] + self.ptr = keywords["ptr"] + return + raise Error + def __del__(self): + if hasattr(self, 'ptr'): + isl.isl_schedule_node_free(self.ptr) + def __new__(cls, *args, **keywords): + return super(schedule_node_set, cls).__new__(cls) + def __str__(arg0): + try: + if not arg0.__class__ is schedule_node_set: + arg0 = schedule_node_set(arg0) + except: + raise + ptr = isl.isl_schedule_node_to_str(arg0.ptr) + res = cast(ptr, c_char_p).value.decode('ascii') + libc.free(ptr) + return res + def __repr__(self): + s = str(self) + if '"' in s: + return 'isl.schedule_node_set("""%s""")' % s + else: + return 'isl.schedule_node_set("%s")' % s + +isl.isl_schedule_node_copy.restype = c_void_p +isl.isl_schedule_node_copy.argtypes = [c_void_p] +isl.isl_schedule_node_free.restype = c_void_p +isl.isl_schedule_node_free.argtypes = [c_void_p] +isl.isl_schedule_node_to_str.restype = POINTER(c_char) +isl.isl_schedule_node_to_str.argtypes = [c_void_p] + +class set_list(object): + def __init__(self, *args, **keywords): + if "ptr" in keywords: + self.ctx = keywords["ctx"] + self.ptr = keywords["ptr"] + return + if len(args) == 1 and type(args[0]) == int: + self.ctx = Context.getDefaultInstance() + self.ptr = isl.isl_set_list_alloc(self.ctx, args[0]) + return + if len(args) == 1 and args[0].__class__ is set: + self.ctx = Context.getDefaultInstance() + self.ptr = isl.isl_set_list_from_set(isl.isl_set_copy(args[0].ptr)) + return + if len(args) == 1 and type(args[0]) == str: + self.ctx = Context.getDefaultInstance() + self.ptr = isl.isl_set_list_read_from_str(self.ctx, args[0].encode('ascii')) + return + raise Error + def __del__(self): + if hasattr(self, 'ptr'): + isl.isl_set_list_free(self.ptr) + def __str__(arg0): + try: + if not arg0.__class__ is set_list: + arg0 = set_list(arg0) + except: + raise + ptr = isl.isl_set_list_to_str(arg0.ptr) + res = cast(ptr, c_char_p).value.decode('ascii') + libc.free(ptr) + return res + def __repr__(self): + s = str(self) + if '"' in s: + return 'isl.set_list("""%s""")' % s + else: + return 'isl.set_list("%s")' % s + def add(arg0, arg1): + try: + if not arg0.__class__ is set_list: + arg0 = set_list(arg0) + except: + raise + try: + if not arg1.__class__ is set: + arg1 = set(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_set_list_add(isl.isl_set_list_copy(arg0.ptr), isl.isl_set_copy(arg1.ptr)) + obj = set_list(ctx=ctx, ptr=res) + return obj + def at(arg0, arg1): + try: + if not arg0.__class__ is set_list: + arg0 = set_list(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_set_list_get_at(arg0.ptr, arg1) + obj = set(ctx=ctx, ptr=res) + return obj + def get_at(arg0, arg1): + return arg0.at(arg1) + def clear(arg0): + try: + if not arg0.__class__ is set_list: + arg0 = set_list(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_set_list_clear(isl.isl_set_list_copy(arg0.ptr)) + obj = set_list(ctx=ctx, ptr=res) + return obj + def concat(arg0, arg1): + try: + if not arg0.__class__ is set_list: + arg0 = set_list(arg0) + except: + raise + try: + if not arg1.__class__ is set_list: + arg1 = set_list(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_set_list_concat(isl.isl_set_list_copy(arg0.ptr), isl.isl_set_list_copy(arg1.ptr)) + obj = set_list(ctx=ctx, ptr=res) + return obj + def drop(arg0, arg1, arg2): + try: + if not arg0.__class__ is set_list: + arg0 = set_list(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_set_list_drop(isl.isl_set_list_copy(arg0.ptr), arg1, arg2) + obj = set_list(ctx=ctx, ptr=res) + return obj + def foreach(arg0, arg1): + try: + if not arg0.__class__ is set_list: + arg0 = set_list(arg0) + except: + raise + exc_info = [None] + fn = CFUNCTYPE(c_int, c_void_p, c_void_p) + def cb_func(cb_arg0, cb_arg1): + cb_arg0 = set(ctx=arg0.ctx, ptr=(cb_arg0)) + try: + arg1(cb_arg0) + except BaseException as e: + exc_info[0] = e + return -1 + return 0 + cb1 = fn(cb_func) + ctx = arg0.ctx + res = isl.isl_set_list_foreach(arg0.ptr, cb1, None) + if exc_info[0] is not None: + raise exc_info[0] + if res < 0: + raise Error + def foreach_scc(arg0, arg1, arg2): + try: + if not arg0.__class__ is set_list: + arg0 = set_list(arg0) + except: + raise + exc_info = [None] + fn = CFUNCTYPE(c_int, c_void_p, c_void_p, c_void_p) + def cb_func(cb_arg0, cb_arg1, cb_arg2): + cb_arg0 = set(ctx=arg0.ctx, ptr=isl.isl_set_copy(cb_arg0)) + cb_arg1 = set(ctx=arg0.ctx, ptr=isl.isl_set_copy(cb_arg1)) + try: + res = arg1(cb_arg0, cb_arg1) + except BaseException as e: + exc_info[0] = e + return -1 + return 1 if res else 0 + cb1 = fn(cb_func) + exc_info = [None] + fn = CFUNCTYPE(c_int, c_void_p, c_void_p) + def cb_func(cb_arg0, cb_arg1): + cb_arg0 = set_list(ctx=arg0.ctx, ptr=(cb_arg0)) + try: + arg2(cb_arg0) + except BaseException as e: + exc_info[0] = e + return -1 + return 0 + cb2 = fn(cb_func) + ctx = arg0.ctx + res = isl.isl_set_list_foreach_scc(arg0.ptr, cb1, None, cb2, None) + if exc_info[0] is not None: + raise exc_info[0] + if res < 0: + raise Error + def insert(arg0, arg1, arg2): + try: + if not arg0.__class__ is set_list: + arg0 = set_list(arg0) + except: + raise + try: + if not arg2.__class__ is set: + arg2 = set(arg2) + except: + raise + ctx = arg0.ctx + res = isl.isl_set_list_insert(isl.isl_set_list_copy(arg0.ptr), arg1, isl.isl_set_copy(arg2.ptr)) + obj = set_list(ctx=ctx, ptr=res) + return obj + def set_at(arg0, arg1, arg2): + try: + if not arg0.__class__ is set_list: + arg0 = set_list(arg0) + except: + raise + try: + if not arg2.__class__ is set: + arg2 = set(arg2) + except: + raise + ctx = arg0.ctx + res = isl.isl_set_list_set_at(isl.isl_set_list_copy(arg0.ptr), arg1, isl.isl_set_copy(arg2.ptr)) + obj = set_list(ctx=ctx, ptr=res) + return obj + def size(arg0): + try: + if not arg0.__class__ is set_list: + arg0 = set_list(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_set_list_size(arg0.ptr) + if res < 0: + raise Error + return int(res) + +isl.isl_set_list_alloc.restype = c_void_p +isl.isl_set_list_alloc.argtypes = [Context, c_int] +isl.isl_set_list_from_set.restype = c_void_p +isl.isl_set_list_from_set.argtypes = [c_void_p] +isl.isl_set_list_read_from_str.restype = c_void_p +isl.isl_set_list_read_from_str.argtypes = [Context, c_char_p] +isl.isl_set_list_add.restype = c_void_p +isl.isl_set_list_add.argtypes = [c_void_p, c_void_p] +isl.isl_set_list_get_at.restype = c_void_p +isl.isl_set_list_get_at.argtypes = [c_void_p, c_int] +isl.isl_set_list_clear.restype = c_void_p +isl.isl_set_list_clear.argtypes = [c_void_p] +isl.isl_set_list_concat.restype = c_void_p +isl.isl_set_list_concat.argtypes = [c_void_p, c_void_p] +isl.isl_set_list_drop.restype = c_void_p +isl.isl_set_list_drop.argtypes = [c_void_p, c_int, c_int] +isl.isl_set_list_foreach.argtypes = [c_void_p, c_void_p, c_void_p] +isl.isl_set_list_foreach_scc.argtypes = [c_void_p, c_void_p, c_void_p, c_void_p, c_void_p] +isl.isl_set_list_insert.restype = c_void_p +isl.isl_set_list_insert.argtypes = [c_void_p, c_int, c_void_p] +isl.isl_set_list_set_at.restype = c_void_p +isl.isl_set_list_set_at.argtypes = [c_void_p, c_int, c_void_p] +isl.isl_set_list_size.argtypes = [c_void_p] +isl.isl_set_list_copy.restype = c_void_p +isl.isl_set_list_copy.argtypes = [c_void_p] +isl.isl_set_list_free.restype = c_void_p +isl.isl_set_list_free.argtypes = [c_void_p] +isl.isl_set_list_to_str.restype = POINTER(c_char) +isl.isl_set_list_to_str.argtypes = [c_void_p] + +class space(object): + def __init__(self, *args, **keywords): + if "ptr" in keywords: + self.ctx = keywords["ctx"] + self.ptr = keywords["ptr"] + return + if len(args) == 1 and type(args[0]) == str: + self.ctx = Context.getDefaultInstance() + self.ptr = isl.isl_space_read_from_str(self.ctx, args[0].encode('ascii')) + return + raise Error + def __del__(self): + if hasattr(self, 'ptr'): + isl.isl_space_free(self.ptr) + def __str__(arg0): + try: + if not arg0.__class__ is space: + arg0 = space(arg0) + except: + raise + ptr = isl.isl_space_to_str(arg0.ptr) + res = cast(ptr, c_char_p).value.decode('ascii') + libc.free(ptr) + return res + def __repr__(self): + s = str(self) + if '"' in s: + return 'isl.space("""%s""")' % s + else: + return 'isl.space("%s")' % s + def add_named_tuple(*args): + if len(args) == 3 and (args[1].__class__ is id or type(args[1]) == str) and type(args[2]) == int: + args = list(args) + try: + if not args[0].__class__ is space: + args[0] = space(args[0]) + except: + raise + try: + if not args[1].__class__ is id: + args[1] = id(args[1]) + except: + raise + ctx = args[0].ctx + res = isl.isl_space_add_named_tuple_id_ui(isl.isl_space_copy(args[0].ptr), isl.isl_id_copy(args[1].ptr), args[2]) + obj = space(ctx=ctx, ptr=res) + return obj + raise Error + def add_param(*args): + if len(args) == 2 and (args[1].__class__ is id or type(args[1]) == str): + args = list(args) + try: + if not args[0].__class__ is space: + args[0] = space(args[0]) + except: + raise + try: + if not args[1].__class__ is id: + args[1] = id(args[1]) + except: + raise + ctx = args[0].ctx + res = isl.isl_space_add_param_id(isl.isl_space_copy(args[0].ptr), isl.isl_id_copy(args[1].ptr)) + obj = space(ctx=ctx, ptr=res) + return obj + raise Error + def add_unnamed_tuple(*args): + if len(args) == 2 and type(args[1]) == int: + args = list(args) + try: + if not args[0].__class__ is space: + args[0] = space(args[0]) + except: + raise + ctx = args[0].ctx + res = isl.isl_space_add_unnamed_tuple_ui(isl.isl_space_copy(args[0].ptr), args[1]) + obj = space(ctx=ctx, ptr=res) + return obj + raise Error + def curry(arg0): + try: + if not arg0.__class__ is space: + arg0 = space(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_space_curry(isl.isl_space_copy(arg0.ptr)) + obj = space(ctx=ctx, ptr=res) + return obj + def domain(arg0): + try: + if not arg0.__class__ is space: + arg0 = space(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_space_domain(isl.isl_space_copy(arg0.ptr)) + obj = space(ctx=ctx, ptr=res) + return obj + def domain_map_multi_aff(arg0): + try: + if not arg0.__class__ is space: + arg0 = space(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_space_domain_map_multi_aff(isl.isl_space_copy(arg0.ptr)) + obj = multi_aff(ctx=ctx, ptr=res) + return obj + def domain_map_pw_multi_aff(arg0): + try: + if not arg0.__class__ is space: + arg0 = space(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_space_domain_map_pw_multi_aff(isl.isl_space_copy(arg0.ptr)) + obj = pw_multi_aff(ctx=ctx, ptr=res) + return obj + def domain_reverse(arg0): + try: + if not arg0.__class__ is space: + arg0 = space(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_space_domain_reverse(isl.isl_space_copy(arg0.ptr)) + obj = space(ctx=ctx, ptr=res) + return obj + def domain_tuple_id(arg0): + try: + if not arg0.__class__ is space: + arg0 = space(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_space_get_domain_tuple_id(arg0.ptr) + obj = id(ctx=ctx, ptr=res) + return obj + def get_domain_tuple_id(arg0): + return arg0.domain_tuple_id() + def drop_all_params(arg0): + try: + if not arg0.__class__ is space: + arg0 = space(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_space_drop_all_params(isl.isl_space_copy(arg0.ptr)) + obj = space(ctx=ctx, ptr=res) + return obj + def flatten_domain(arg0): + try: + if not arg0.__class__ is space: + arg0 = space(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_space_flatten_domain(isl.isl_space_copy(arg0.ptr)) + obj = space(ctx=ctx, ptr=res) + return obj + def flatten_range(arg0): + try: + if not arg0.__class__ is space: + arg0 = space(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_space_flatten_range(isl.isl_space_copy(arg0.ptr)) + obj = space(ctx=ctx, ptr=res) + return obj + def has_domain_tuple_id(arg0): + try: + if not arg0.__class__ is space: + arg0 = space(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_space_has_domain_tuple_id(arg0.ptr) + if res < 0: + raise Error + return bool(res) + def has_range_tuple_id(arg0): + try: + if not arg0.__class__ is space: + arg0 = space(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_space_has_range_tuple_id(arg0.ptr) + if res < 0: + raise Error + return bool(res) + def identity_multi_aff_on_domain(arg0): + try: + if not arg0.__class__ is space: + arg0 = space(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_space_identity_multi_aff_on_domain(isl.isl_space_copy(arg0.ptr)) + obj = multi_aff(ctx=ctx, ptr=res) + return obj + def identity_multi_pw_aff_on_domain(arg0): + try: + if not arg0.__class__ is space: + arg0 = space(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_space_identity_multi_pw_aff_on_domain(isl.isl_space_copy(arg0.ptr)) + obj = multi_pw_aff(ctx=ctx, ptr=res) + return obj + def identity_pw_multi_aff_on_domain(arg0): + try: + if not arg0.__class__ is space: + arg0 = space(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_space_identity_pw_multi_aff_on_domain(isl.isl_space_copy(arg0.ptr)) + obj = pw_multi_aff(ctx=ctx, ptr=res) + return obj + def is_equal(arg0, arg1): + try: + if not arg0.__class__ is space: + arg0 = space(arg0) + except: + raise + try: + if not arg1.__class__ is space: + arg1 = space(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_space_is_equal(arg0.ptr, arg1.ptr) + if res < 0: + raise Error + return bool(res) + def is_wrapping(arg0): + try: + if not arg0.__class__ is space: + arg0 = space(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_space_is_wrapping(arg0.ptr) + if res < 0: + raise Error + return bool(res) + def map_from_set(arg0): + try: + if not arg0.__class__ is space: + arg0 = space(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_space_map_from_set(isl.isl_space_copy(arg0.ptr)) + obj = space(ctx=ctx, ptr=res) + return obj + def multi_aff(arg0, arg1): + try: + if not arg0.__class__ is space: + arg0 = space(arg0) + except: + raise + try: + if not arg1.__class__ is aff_list: + arg1 = aff_list(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_space_multi_aff(isl.isl_space_copy(arg0.ptr), isl.isl_aff_list_copy(arg1.ptr)) + obj = multi_aff(ctx=ctx, ptr=res) + return obj + def multi_aff_on_domain(*args): + if len(args) == 2 and args[1].__class__ is multi_val: + args = list(args) + try: + if not args[0].__class__ is space: + args[0] = space(args[0]) + except: + raise + ctx = args[0].ctx + res = isl.isl_space_multi_aff_on_domain_multi_val(isl.isl_space_copy(args[0].ptr), isl.isl_multi_val_copy(args[1].ptr)) + obj = multi_aff(ctx=ctx, ptr=res) + return obj + raise Error + def multi_id(arg0, arg1): + try: + if not arg0.__class__ is space: + arg0 = space(arg0) + except: + raise + try: + if not arg1.__class__ is id_list: + arg1 = id_list(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_space_multi_id(isl.isl_space_copy(arg0.ptr), isl.isl_id_list_copy(arg1.ptr)) + obj = multi_id(ctx=ctx, ptr=res) + return obj + def multi_pw_aff(arg0, arg1): + try: + if not arg0.__class__ is space: + arg0 = space(arg0) + except: + raise + try: + if not arg1.__class__ is pw_aff_list: + arg1 = pw_aff_list(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_space_multi_pw_aff(isl.isl_space_copy(arg0.ptr), isl.isl_pw_aff_list_copy(arg1.ptr)) + obj = multi_pw_aff(ctx=ctx, ptr=res) + return obj + def multi_union_pw_aff(arg0, arg1): + try: + if not arg0.__class__ is space: + arg0 = space(arg0) + except: + raise + try: + if not arg1.__class__ is union_pw_aff_list: + arg1 = union_pw_aff_list(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_space_multi_union_pw_aff(isl.isl_space_copy(arg0.ptr), isl.isl_union_pw_aff_list_copy(arg1.ptr)) + obj = multi_union_pw_aff(ctx=ctx, ptr=res) + return obj + def multi_val(arg0, arg1): + try: + if not arg0.__class__ is space: + arg0 = space(arg0) + except: + raise + try: + if not arg1.__class__ is val_list: + arg1 = val_list(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_space_multi_val(isl.isl_space_copy(arg0.ptr), isl.isl_val_list_copy(arg1.ptr)) + obj = multi_val(ctx=ctx, ptr=res) + return obj + def param_aff_on_domain(*args): + if len(args) == 2 and (args[1].__class__ is id or type(args[1]) == str): + args = list(args) + try: + if not args[0].__class__ is space: + args[0] = space(args[0]) + except: + raise + try: + if not args[1].__class__ is id: + args[1] = id(args[1]) + except: + raise + ctx = args[0].ctx + res = isl.isl_space_param_aff_on_domain_id(isl.isl_space_copy(args[0].ptr), isl.isl_id_copy(args[1].ptr)) + obj = aff(ctx=ctx, ptr=res) + return obj + raise Error + def params(arg0): + try: + if not arg0.__class__ is space: + arg0 = space(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_space_params(isl.isl_space_copy(arg0.ptr)) + obj = space(ctx=ctx, ptr=res) + return obj + def product(arg0, arg1): + try: + if not arg0.__class__ is space: + arg0 = space(arg0) + except: + raise + try: + if not arg1.__class__ is space: + arg1 = space(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_space_product(isl.isl_space_copy(arg0.ptr), isl.isl_space_copy(arg1.ptr)) + obj = space(ctx=ctx, ptr=res) + return obj + def range(arg0): + try: + if not arg0.__class__ is space: + arg0 = space(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_space_range(isl.isl_space_copy(arg0.ptr)) + obj = space(ctx=ctx, ptr=res) + return obj + def range_map_multi_aff(arg0): + try: + if not arg0.__class__ is space: + arg0 = space(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_space_range_map_multi_aff(isl.isl_space_copy(arg0.ptr)) + obj = multi_aff(ctx=ctx, ptr=res) + return obj + def range_map_pw_multi_aff(arg0): + try: + if not arg0.__class__ is space: + arg0 = space(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_space_range_map_pw_multi_aff(isl.isl_space_copy(arg0.ptr)) + obj = pw_multi_aff(ctx=ctx, ptr=res) + return obj + def range_reverse(arg0): + try: + if not arg0.__class__ is space: + arg0 = space(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_space_range_reverse(isl.isl_space_copy(arg0.ptr)) + obj = space(ctx=ctx, ptr=res) + return obj + def range_tuple_id(arg0): + try: + if not arg0.__class__ is space: + arg0 = space(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_space_get_range_tuple_id(arg0.ptr) + obj = id(ctx=ctx, ptr=res) + return obj + def get_range_tuple_id(arg0): + return arg0.range_tuple_id() + def reverse(arg0): + try: + if not arg0.__class__ is space: + arg0 = space(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_space_reverse(isl.isl_space_copy(arg0.ptr)) + obj = space(ctx=ctx, ptr=res) + return obj + def set_domain_tuple(*args): + if len(args) == 2 and (args[1].__class__ is id or type(args[1]) == str): + args = list(args) + try: + if not args[0].__class__ is space: + args[0] = space(args[0]) + except: + raise + try: + if not args[1].__class__ is id: + args[1] = id(args[1]) + except: + raise + ctx = args[0].ctx + res = isl.isl_space_set_domain_tuple_id(isl.isl_space_copy(args[0].ptr), isl.isl_id_copy(args[1].ptr)) + obj = space(ctx=ctx, ptr=res) + return obj + raise Error + def set_range_tuple(*args): + if len(args) == 2 and (args[1].__class__ is id or type(args[1]) == str): + args = list(args) + try: + if not args[0].__class__ is space: + args[0] = space(args[0]) + except: + raise + try: + if not args[1].__class__ is id: + args[1] = id(args[1]) + except: + raise + ctx = args[0].ctx + res = isl.isl_space_set_range_tuple_id(isl.isl_space_copy(args[0].ptr), isl.isl_id_copy(args[1].ptr)) + obj = space(ctx=ctx, ptr=res) + return obj + raise Error + def uncurry(arg0): + try: + if not arg0.__class__ is space: + arg0 = space(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_space_uncurry(isl.isl_space_copy(arg0.ptr)) + obj = space(ctx=ctx, ptr=res) + return obj + @staticmethod + def unit(): + ctx = Context.getDefaultInstance() + res = isl.isl_space_unit(ctx) + obj = space(ctx=ctx, ptr=res) + return obj + def universe_map(arg0): + try: + if not arg0.__class__ is space: + arg0 = space(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_space_universe_map(isl.isl_space_copy(arg0.ptr)) + obj = map(ctx=ctx, ptr=res) + return obj + def universe_set(arg0): + try: + if not arg0.__class__ is space: + arg0 = space(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_space_universe_set(isl.isl_space_copy(arg0.ptr)) + obj = set(ctx=ctx, ptr=res) + return obj + def unwrap(arg0): + try: + if not arg0.__class__ is space: + arg0 = space(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_space_unwrap(isl.isl_space_copy(arg0.ptr)) + obj = space(ctx=ctx, ptr=res) + return obj + def wrap(arg0): + try: + if not arg0.__class__ is space: + arg0 = space(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_space_wrap(isl.isl_space_copy(arg0.ptr)) + obj = space(ctx=ctx, ptr=res) + return obj + def wrapped_reverse(arg0): + try: + if not arg0.__class__ is space: + arg0 = space(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_space_wrapped_reverse(isl.isl_space_copy(arg0.ptr)) + obj = space(ctx=ctx, ptr=res) + return obj + def zero_aff_on_domain(arg0): + try: + if not arg0.__class__ is space: + arg0 = space(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_space_zero_aff_on_domain(isl.isl_space_copy(arg0.ptr)) + obj = aff(ctx=ctx, ptr=res) + return obj + def zero_multi_aff(arg0): + try: + if not arg0.__class__ is space: + arg0 = space(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_space_zero_multi_aff(isl.isl_space_copy(arg0.ptr)) + obj = multi_aff(ctx=ctx, ptr=res) + return obj + def zero_multi_pw_aff(arg0): + try: + if not arg0.__class__ is space: + arg0 = space(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_space_zero_multi_pw_aff(isl.isl_space_copy(arg0.ptr)) + obj = multi_pw_aff(ctx=ctx, ptr=res) + return obj + def zero_multi_union_pw_aff(arg0): + try: + if not arg0.__class__ is space: + arg0 = space(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_space_zero_multi_union_pw_aff(isl.isl_space_copy(arg0.ptr)) + obj = multi_union_pw_aff(ctx=ctx, ptr=res) + return obj + def zero_multi_val(arg0): + try: + if not arg0.__class__ is space: + arg0 = space(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_space_zero_multi_val(isl.isl_space_copy(arg0.ptr)) + obj = multi_val(ctx=ctx, ptr=res) + return obj + +isl.isl_space_read_from_str.restype = c_void_p +isl.isl_space_read_from_str.argtypes = [Context, c_char_p] +isl.isl_space_add_named_tuple_id_ui.restype = c_void_p +isl.isl_space_add_named_tuple_id_ui.argtypes = [c_void_p, c_void_p, c_int] +isl.isl_space_add_param_id.restype = c_void_p +isl.isl_space_add_param_id.argtypes = [c_void_p, c_void_p] +isl.isl_space_add_unnamed_tuple_ui.restype = c_void_p +isl.isl_space_add_unnamed_tuple_ui.argtypes = [c_void_p, c_int] +isl.isl_space_curry.restype = c_void_p +isl.isl_space_curry.argtypes = [c_void_p] +isl.isl_space_domain.restype = c_void_p +isl.isl_space_domain.argtypes = [c_void_p] +isl.isl_space_domain_map_multi_aff.restype = c_void_p +isl.isl_space_domain_map_multi_aff.argtypes = [c_void_p] +isl.isl_space_domain_map_pw_multi_aff.restype = c_void_p +isl.isl_space_domain_map_pw_multi_aff.argtypes = [c_void_p] +isl.isl_space_domain_reverse.restype = c_void_p +isl.isl_space_domain_reverse.argtypes = [c_void_p] +isl.isl_space_get_domain_tuple_id.restype = c_void_p +isl.isl_space_get_domain_tuple_id.argtypes = [c_void_p] +isl.isl_space_drop_all_params.restype = c_void_p +isl.isl_space_drop_all_params.argtypes = [c_void_p] +isl.isl_space_flatten_domain.restype = c_void_p +isl.isl_space_flatten_domain.argtypes = [c_void_p] +isl.isl_space_flatten_range.restype = c_void_p +isl.isl_space_flatten_range.argtypes = [c_void_p] +isl.isl_space_has_domain_tuple_id.argtypes = [c_void_p] +isl.isl_space_has_range_tuple_id.argtypes = [c_void_p] +isl.isl_space_identity_multi_aff_on_domain.restype = c_void_p +isl.isl_space_identity_multi_aff_on_domain.argtypes = [c_void_p] +isl.isl_space_identity_multi_pw_aff_on_domain.restype = c_void_p +isl.isl_space_identity_multi_pw_aff_on_domain.argtypes = [c_void_p] +isl.isl_space_identity_pw_multi_aff_on_domain.restype = c_void_p +isl.isl_space_identity_pw_multi_aff_on_domain.argtypes = [c_void_p] +isl.isl_space_is_equal.argtypes = [c_void_p, c_void_p] +isl.isl_space_is_wrapping.argtypes = [c_void_p] +isl.isl_space_map_from_set.restype = c_void_p +isl.isl_space_map_from_set.argtypes = [c_void_p] +isl.isl_space_multi_aff.restype = c_void_p +isl.isl_space_multi_aff.argtypes = [c_void_p, c_void_p] +isl.isl_space_multi_aff_on_domain_multi_val.restype = c_void_p +isl.isl_space_multi_aff_on_domain_multi_val.argtypes = [c_void_p, c_void_p] +isl.isl_space_multi_id.restype = c_void_p +isl.isl_space_multi_id.argtypes = [c_void_p, c_void_p] +isl.isl_space_multi_pw_aff.restype = c_void_p +isl.isl_space_multi_pw_aff.argtypes = [c_void_p, c_void_p] +isl.isl_space_multi_union_pw_aff.restype = c_void_p +isl.isl_space_multi_union_pw_aff.argtypes = [c_void_p, c_void_p] +isl.isl_space_multi_val.restype = c_void_p +isl.isl_space_multi_val.argtypes = [c_void_p, c_void_p] +isl.isl_space_param_aff_on_domain_id.restype = c_void_p +isl.isl_space_param_aff_on_domain_id.argtypes = [c_void_p, c_void_p] +isl.isl_space_params.restype = c_void_p +isl.isl_space_params.argtypes = [c_void_p] +isl.isl_space_product.restype = c_void_p +isl.isl_space_product.argtypes = [c_void_p, c_void_p] +isl.isl_space_range.restype = c_void_p +isl.isl_space_range.argtypes = [c_void_p] +isl.isl_space_range_map_multi_aff.restype = c_void_p +isl.isl_space_range_map_multi_aff.argtypes = [c_void_p] +isl.isl_space_range_map_pw_multi_aff.restype = c_void_p +isl.isl_space_range_map_pw_multi_aff.argtypes = [c_void_p] +isl.isl_space_range_reverse.restype = c_void_p +isl.isl_space_range_reverse.argtypes = [c_void_p] +isl.isl_space_get_range_tuple_id.restype = c_void_p +isl.isl_space_get_range_tuple_id.argtypes = [c_void_p] +isl.isl_space_reverse.restype = c_void_p +isl.isl_space_reverse.argtypes = [c_void_p] +isl.isl_space_set_domain_tuple_id.restype = c_void_p +isl.isl_space_set_domain_tuple_id.argtypes = [c_void_p, c_void_p] +isl.isl_space_set_range_tuple_id.restype = c_void_p +isl.isl_space_set_range_tuple_id.argtypes = [c_void_p, c_void_p] +isl.isl_space_uncurry.restype = c_void_p +isl.isl_space_uncurry.argtypes = [c_void_p] +isl.isl_space_unit.restype = c_void_p +isl.isl_space_unit.argtypes = [Context] +isl.isl_space_universe_map.restype = c_void_p +isl.isl_space_universe_map.argtypes = [c_void_p] +isl.isl_space_universe_set.restype = c_void_p +isl.isl_space_universe_set.argtypes = [c_void_p] +isl.isl_space_unwrap.restype = c_void_p +isl.isl_space_unwrap.argtypes = [c_void_p] +isl.isl_space_wrap.restype = c_void_p +isl.isl_space_wrap.argtypes = [c_void_p] +isl.isl_space_wrapped_reverse.restype = c_void_p +isl.isl_space_wrapped_reverse.argtypes = [c_void_p] +isl.isl_space_zero_aff_on_domain.restype = c_void_p +isl.isl_space_zero_aff_on_domain.argtypes = [c_void_p] +isl.isl_space_zero_multi_aff.restype = c_void_p +isl.isl_space_zero_multi_aff.argtypes = [c_void_p] +isl.isl_space_zero_multi_pw_aff.restype = c_void_p +isl.isl_space_zero_multi_pw_aff.argtypes = [c_void_p] +isl.isl_space_zero_multi_union_pw_aff.restype = c_void_p +isl.isl_space_zero_multi_union_pw_aff.argtypes = [c_void_p] +isl.isl_space_zero_multi_val.restype = c_void_p +isl.isl_space_zero_multi_val.argtypes = [c_void_p] +isl.isl_space_copy.restype = c_void_p +isl.isl_space_copy.argtypes = [c_void_p] +isl.isl_space_free.restype = c_void_p +isl.isl_space_free.argtypes = [c_void_p] +isl.isl_space_to_str.restype = POINTER(c_char) +isl.isl_space_to_str.argtypes = [c_void_p] + +class union_access_info(object): + def __init__(self, *args, **keywords): + if "ptr" in keywords: + self.ctx = keywords["ctx"] + self.ptr = keywords["ptr"] + return + if len(args) == 1 and args[0].__class__ is union_map: + self.ctx = Context.getDefaultInstance() + self.ptr = isl.isl_union_access_info_from_sink(isl.isl_union_map_copy(args[0].ptr)) + return + raise Error + def __del__(self): + if hasattr(self, 'ptr'): + isl.isl_union_access_info_free(self.ptr) + def __str__(arg0): + try: + if not arg0.__class__ is union_access_info: + arg0 = union_access_info(arg0) + except: + raise + ptr = isl.isl_union_access_info_to_str(arg0.ptr) + res = cast(ptr, c_char_p).value.decode('ascii') + libc.free(ptr) + return res + def __repr__(self): + s = str(self) + if '"' in s: + return 'isl.union_access_info("""%s""")' % s + else: + return 'isl.union_access_info("%s")' % s + def compute_flow(arg0): + try: + if not arg0.__class__ is union_access_info: + arg0 = union_access_info(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_access_info_compute_flow(isl.isl_union_access_info_copy(arg0.ptr)) + obj = union_flow(ctx=ctx, ptr=res) + return obj + def set_kill(arg0, arg1): + try: + if not arg0.__class__ is union_access_info: + arg0 = union_access_info(arg0) + except: + raise + try: + if not arg1.__class__ is union_map: + arg1 = union_map(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_access_info_set_kill(isl.isl_union_access_info_copy(arg0.ptr), isl.isl_union_map_copy(arg1.ptr)) + obj = union_access_info(ctx=ctx, ptr=res) + return obj + def set_may_source(arg0, arg1): + try: + if not arg0.__class__ is union_access_info: + arg0 = union_access_info(arg0) + except: + raise + try: + if not arg1.__class__ is union_map: + arg1 = union_map(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_access_info_set_may_source(isl.isl_union_access_info_copy(arg0.ptr), isl.isl_union_map_copy(arg1.ptr)) + obj = union_access_info(ctx=ctx, ptr=res) + return obj + def set_must_source(arg0, arg1): + try: + if not arg0.__class__ is union_access_info: + arg0 = union_access_info(arg0) + except: + raise + try: + if not arg1.__class__ is union_map: + arg1 = union_map(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_access_info_set_must_source(isl.isl_union_access_info_copy(arg0.ptr), isl.isl_union_map_copy(arg1.ptr)) + obj = union_access_info(ctx=ctx, ptr=res) + return obj + def set_schedule(arg0, arg1): + try: + if not arg0.__class__ is union_access_info: + arg0 = union_access_info(arg0) + except: + raise + try: + if not arg1.__class__ is schedule: + arg1 = schedule(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_access_info_set_schedule(isl.isl_union_access_info_copy(arg0.ptr), isl.isl_schedule_copy(arg1.ptr)) + obj = union_access_info(ctx=ctx, ptr=res) + return obj + def set_schedule_map(arg0, arg1): + try: + if not arg0.__class__ is union_access_info: + arg0 = union_access_info(arg0) + except: + raise + try: + if not arg1.__class__ is union_map: + arg1 = union_map(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_access_info_set_schedule_map(isl.isl_union_access_info_copy(arg0.ptr), isl.isl_union_map_copy(arg1.ptr)) + obj = union_access_info(ctx=ctx, ptr=res) + return obj + +isl.isl_union_access_info_from_sink.restype = c_void_p +isl.isl_union_access_info_from_sink.argtypes = [c_void_p] +isl.isl_union_access_info_compute_flow.restype = c_void_p +isl.isl_union_access_info_compute_flow.argtypes = [c_void_p] +isl.isl_union_access_info_set_kill.restype = c_void_p +isl.isl_union_access_info_set_kill.argtypes = [c_void_p, c_void_p] +isl.isl_union_access_info_set_may_source.restype = c_void_p +isl.isl_union_access_info_set_may_source.argtypes = [c_void_p, c_void_p] +isl.isl_union_access_info_set_must_source.restype = c_void_p +isl.isl_union_access_info_set_must_source.argtypes = [c_void_p, c_void_p] +isl.isl_union_access_info_set_schedule.restype = c_void_p +isl.isl_union_access_info_set_schedule.argtypes = [c_void_p, c_void_p] +isl.isl_union_access_info_set_schedule_map.restype = c_void_p +isl.isl_union_access_info_set_schedule_map.argtypes = [c_void_p, c_void_p] +isl.isl_union_access_info_copy.restype = c_void_p +isl.isl_union_access_info_copy.argtypes = [c_void_p] +isl.isl_union_access_info_free.restype = c_void_p +isl.isl_union_access_info_free.argtypes = [c_void_p] +isl.isl_union_access_info_to_str.restype = POINTER(c_char) +isl.isl_union_access_info_to_str.argtypes = [c_void_p] + +class union_flow(object): + def __init__(self, *args, **keywords): + if "ptr" in keywords: + self.ctx = keywords["ctx"] + self.ptr = keywords["ptr"] + return + raise Error + def __del__(self): + if hasattr(self, 'ptr'): + isl.isl_union_flow_free(self.ptr) + def __str__(arg0): + try: + if not arg0.__class__ is union_flow: + arg0 = union_flow(arg0) + except: + raise + ptr = isl.isl_union_flow_to_str(arg0.ptr) + res = cast(ptr, c_char_p).value.decode('ascii') + libc.free(ptr) + return res + def __repr__(self): + s = str(self) + if '"' in s: + return 'isl.union_flow("""%s""")' % s + else: + return 'isl.union_flow("%s")' % s + def full_may_dependence(arg0): + try: + if not arg0.__class__ is union_flow: + arg0 = union_flow(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_flow_get_full_may_dependence(arg0.ptr) + obj = union_map(ctx=ctx, ptr=res) + return obj + def get_full_may_dependence(arg0): + return arg0.full_may_dependence() + def full_must_dependence(arg0): + try: + if not arg0.__class__ is union_flow: + arg0 = union_flow(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_flow_get_full_must_dependence(arg0.ptr) + obj = union_map(ctx=ctx, ptr=res) + return obj + def get_full_must_dependence(arg0): + return arg0.full_must_dependence() + def may_dependence(arg0): + try: + if not arg0.__class__ is union_flow: + arg0 = union_flow(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_flow_get_may_dependence(arg0.ptr) + obj = union_map(ctx=ctx, ptr=res) + return obj + def get_may_dependence(arg0): + return arg0.may_dependence() + def may_no_source(arg0): + try: + if not arg0.__class__ is union_flow: + arg0 = union_flow(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_flow_get_may_no_source(arg0.ptr) + obj = union_map(ctx=ctx, ptr=res) + return obj + def get_may_no_source(arg0): + return arg0.may_no_source() + def must_dependence(arg0): + try: + if not arg0.__class__ is union_flow: + arg0 = union_flow(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_flow_get_must_dependence(arg0.ptr) + obj = union_map(ctx=ctx, ptr=res) + return obj + def get_must_dependence(arg0): + return arg0.must_dependence() + def must_no_source(arg0): + try: + if not arg0.__class__ is union_flow: + arg0 = union_flow(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_flow_get_must_no_source(arg0.ptr) + obj = union_map(ctx=ctx, ptr=res) + return obj + def get_must_no_source(arg0): + return arg0.must_no_source() + +isl.isl_union_flow_get_full_may_dependence.restype = c_void_p +isl.isl_union_flow_get_full_may_dependence.argtypes = [c_void_p] +isl.isl_union_flow_get_full_must_dependence.restype = c_void_p +isl.isl_union_flow_get_full_must_dependence.argtypes = [c_void_p] +isl.isl_union_flow_get_may_dependence.restype = c_void_p +isl.isl_union_flow_get_may_dependence.argtypes = [c_void_p] +isl.isl_union_flow_get_may_no_source.restype = c_void_p +isl.isl_union_flow_get_may_no_source.argtypes = [c_void_p] +isl.isl_union_flow_get_must_dependence.restype = c_void_p +isl.isl_union_flow_get_must_dependence.argtypes = [c_void_p] +isl.isl_union_flow_get_must_no_source.restype = c_void_p +isl.isl_union_flow_get_must_no_source.argtypes = [c_void_p] +isl.isl_union_flow_copy.restype = c_void_p +isl.isl_union_flow_copy.argtypes = [c_void_p] +isl.isl_union_flow_free.restype = c_void_p +isl.isl_union_flow_free.argtypes = [c_void_p] +isl.isl_union_flow_to_str.restype = POINTER(c_char) +isl.isl_union_flow_to_str.argtypes = [c_void_p] + +class union_pw_aff_list(object): + def __init__(self, *args, **keywords): + if "ptr" in keywords: + self.ctx = keywords["ctx"] + self.ptr = keywords["ptr"] + return + if len(args) == 1 and type(args[0]) == int: + self.ctx = Context.getDefaultInstance() + self.ptr = isl.isl_union_pw_aff_list_alloc(self.ctx, args[0]) + return + if len(args) == 1 and args[0].__class__ is union_pw_aff: + self.ctx = Context.getDefaultInstance() + self.ptr = isl.isl_union_pw_aff_list_from_union_pw_aff(isl.isl_union_pw_aff_copy(args[0].ptr)) + return + if len(args) == 1 and type(args[0]) == str: + self.ctx = Context.getDefaultInstance() + self.ptr = isl.isl_union_pw_aff_list_read_from_str(self.ctx, args[0].encode('ascii')) + return + raise Error + def __del__(self): + if hasattr(self, 'ptr'): + isl.isl_union_pw_aff_list_free(self.ptr) + def __str__(arg0): + try: + if not arg0.__class__ is union_pw_aff_list: + arg0 = union_pw_aff_list(arg0) + except: + raise + ptr = isl.isl_union_pw_aff_list_to_str(arg0.ptr) + res = cast(ptr, c_char_p).value.decode('ascii') + libc.free(ptr) + return res + def __repr__(self): + s = str(self) + if '"' in s: + return 'isl.union_pw_aff_list("""%s""")' % s + else: + return 'isl.union_pw_aff_list("%s")' % s + def add(arg0, arg1): + try: + if not arg0.__class__ is union_pw_aff_list: + arg0 = union_pw_aff_list(arg0) + except: + raise + try: + if not arg1.__class__ is union_pw_aff: + arg1 = union_pw_aff(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_pw_aff_list_add(isl.isl_union_pw_aff_list_copy(arg0.ptr), isl.isl_union_pw_aff_copy(arg1.ptr)) + obj = union_pw_aff_list(ctx=ctx, ptr=res) + return obj + def at(arg0, arg1): + try: + if not arg0.__class__ is union_pw_aff_list: + arg0 = union_pw_aff_list(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_pw_aff_list_get_at(arg0.ptr, arg1) + obj = union_pw_aff(ctx=ctx, ptr=res) + return obj + def get_at(arg0, arg1): + return arg0.at(arg1) + def clear(arg0): + try: + if not arg0.__class__ is union_pw_aff_list: + arg0 = union_pw_aff_list(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_pw_aff_list_clear(isl.isl_union_pw_aff_list_copy(arg0.ptr)) + obj = union_pw_aff_list(ctx=ctx, ptr=res) + return obj + def concat(arg0, arg1): + try: + if not arg0.__class__ is union_pw_aff_list: + arg0 = union_pw_aff_list(arg0) + except: + raise + try: + if not arg1.__class__ is union_pw_aff_list: + arg1 = union_pw_aff_list(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_pw_aff_list_concat(isl.isl_union_pw_aff_list_copy(arg0.ptr), isl.isl_union_pw_aff_list_copy(arg1.ptr)) + obj = union_pw_aff_list(ctx=ctx, ptr=res) + return obj + def drop(arg0, arg1, arg2): + try: + if not arg0.__class__ is union_pw_aff_list: + arg0 = union_pw_aff_list(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_pw_aff_list_drop(isl.isl_union_pw_aff_list_copy(arg0.ptr), arg1, arg2) + obj = union_pw_aff_list(ctx=ctx, ptr=res) + return obj + def foreach(arg0, arg1): + try: + if not arg0.__class__ is union_pw_aff_list: + arg0 = union_pw_aff_list(arg0) + except: + raise + exc_info = [None] + fn = CFUNCTYPE(c_int, c_void_p, c_void_p) + def cb_func(cb_arg0, cb_arg1): + cb_arg0 = union_pw_aff(ctx=arg0.ctx, ptr=(cb_arg0)) + try: + arg1(cb_arg0) + except BaseException as e: + exc_info[0] = e + return -1 + return 0 + cb1 = fn(cb_func) + ctx = arg0.ctx + res = isl.isl_union_pw_aff_list_foreach(arg0.ptr, cb1, None) + if exc_info[0] is not None: + raise exc_info[0] + if res < 0: + raise Error + def foreach_scc(arg0, arg1, arg2): + try: + if not arg0.__class__ is union_pw_aff_list: + arg0 = union_pw_aff_list(arg0) + except: + raise + exc_info = [None] + fn = CFUNCTYPE(c_int, c_void_p, c_void_p, c_void_p) + def cb_func(cb_arg0, cb_arg1, cb_arg2): + cb_arg0 = union_pw_aff(ctx=arg0.ctx, ptr=isl.isl_union_pw_aff_copy(cb_arg0)) + cb_arg1 = union_pw_aff(ctx=arg0.ctx, ptr=isl.isl_union_pw_aff_copy(cb_arg1)) + try: + res = arg1(cb_arg0, cb_arg1) + except BaseException as e: + exc_info[0] = e + return -1 + return 1 if res else 0 + cb1 = fn(cb_func) + exc_info = [None] + fn = CFUNCTYPE(c_int, c_void_p, c_void_p) + def cb_func(cb_arg0, cb_arg1): + cb_arg0 = union_pw_aff_list(ctx=arg0.ctx, ptr=(cb_arg0)) + try: + arg2(cb_arg0) + except BaseException as e: + exc_info[0] = e + return -1 + return 0 + cb2 = fn(cb_func) + ctx = arg0.ctx + res = isl.isl_union_pw_aff_list_foreach_scc(arg0.ptr, cb1, None, cb2, None) + if exc_info[0] is not None: + raise exc_info[0] + if res < 0: + raise Error + def insert(arg0, arg1, arg2): + try: + if not arg0.__class__ is union_pw_aff_list: + arg0 = union_pw_aff_list(arg0) + except: + raise + try: + if not arg2.__class__ is union_pw_aff: + arg2 = union_pw_aff(arg2) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_pw_aff_list_insert(isl.isl_union_pw_aff_list_copy(arg0.ptr), arg1, isl.isl_union_pw_aff_copy(arg2.ptr)) + obj = union_pw_aff_list(ctx=ctx, ptr=res) + return obj + def set_at(arg0, arg1, arg2): + try: + if not arg0.__class__ is union_pw_aff_list: + arg0 = union_pw_aff_list(arg0) + except: + raise + try: + if not arg2.__class__ is union_pw_aff: + arg2 = union_pw_aff(arg2) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_pw_aff_list_set_at(isl.isl_union_pw_aff_list_copy(arg0.ptr), arg1, isl.isl_union_pw_aff_copy(arg2.ptr)) + obj = union_pw_aff_list(ctx=ctx, ptr=res) + return obj + def size(arg0): + try: + if not arg0.__class__ is union_pw_aff_list: + arg0 = union_pw_aff_list(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_pw_aff_list_size(arg0.ptr) + if res < 0: + raise Error + return int(res) + +isl.isl_union_pw_aff_list_alloc.restype = c_void_p +isl.isl_union_pw_aff_list_alloc.argtypes = [Context, c_int] +isl.isl_union_pw_aff_list_from_union_pw_aff.restype = c_void_p +isl.isl_union_pw_aff_list_from_union_pw_aff.argtypes = [c_void_p] +isl.isl_union_pw_aff_list_read_from_str.restype = c_void_p +isl.isl_union_pw_aff_list_read_from_str.argtypes = [Context, c_char_p] +isl.isl_union_pw_aff_list_add.restype = c_void_p +isl.isl_union_pw_aff_list_add.argtypes = [c_void_p, c_void_p] +isl.isl_union_pw_aff_list_get_at.restype = c_void_p +isl.isl_union_pw_aff_list_get_at.argtypes = [c_void_p, c_int] +isl.isl_union_pw_aff_list_clear.restype = c_void_p +isl.isl_union_pw_aff_list_clear.argtypes = [c_void_p] +isl.isl_union_pw_aff_list_concat.restype = c_void_p +isl.isl_union_pw_aff_list_concat.argtypes = [c_void_p, c_void_p] +isl.isl_union_pw_aff_list_drop.restype = c_void_p +isl.isl_union_pw_aff_list_drop.argtypes = [c_void_p, c_int, c_int] +isl.isl_union_pw_aff_list_foreach.argtypes = [c_void_p, c_void_p, c_void_p] +isl.isl_union_pw_aff_list_foreach_scc.argtypes = [c_void_p, c_void_p, c_void_p, c_void_p, c_void_p] +isl.isl_union_pw_aff_list_insert.restype = c_void_p +isl.isl_union_pw_aff_list_insert.argtypes = [c_void_p, c_int, c_void_p] +isl.isl_union_pw_aff_list_set_at.restype = c_void_p +isl.isl_union_pw_aff_list_set_at.argtypes = [c_void_p, c_int, c_void_p] +isl.isl_union_pw_aff_list_size.argtypes = [c_void_p] +isl.isl_union_pw_aff_list_copy.restype = c_void_p +isl.isl_union_pw_aff_list_copy.argtypes = [c_void_p] +isl.isl_union_pw_aff_list_free.restype = c_void_p +isl.isl_union_pw_aff_list_free.argtypes = [c_void_p] +isl.isl_union_pw_aff_list_to_str.restype = POINTER(c_char) +isl.isl_union_pw_aff_list_to_str.argtypes = [c_void_p] + +class union_set_list(object): + def __init__(self, *args, **keywords): + if "ptr" in keywords: + self.ctx = keywords["ctx"] + self.ptr = keywords["ptr"] + return + if len(args) == 1 and type(args[0]) == int: + self.ctx = Context.getDefaultInstance() + self.ptr = isl.isl_union_set_list_alloc(self.ctx, args[0]) + return + if len(args) == 1 and args[0].__class__ is union_set: + self.ctx = Context.getDefaultInstance() + self.ptr = isl.isl_union_set_list_from_union_set(isl.isl_union_set_copy(args[0].ptr)) + return + if len(args) == 1 and type(args[0]) == str: + self.ctx = Context.getDefaultInstance() + self.ptr = isl.isl_union_set_list_read_from_str(self.ctx, args[0].encode('ascii')) + return + raise Error + def __del__(self): + if hasattr(self, 'ptr'): + isl.isl_union_set_list_free(self.ptr) + def __str__(arg0): + try: + if not arg0.__class__ is union_set_list: + arg0 = union_set_list(arg0) + except: + raise + ptr = isl.isl_union_set_list_to_str(arg0.ptr) + res = cast(ptr, c_char_p).value.decode('ascii') + libc.free(ptr) + return res + def __repr__(self): + s = str(self) + if '"' in s: + return 'isl.union_set_list("""%s""")' % s + else: + return 'isl.union_set_list("%s")' % s + def add(arg0, arg1): + try: + if not arg0.__class__ is union_set_list: + arg0 = union_set_list(arg0) + except: + raise + try: + if not arg1.__class__ is union_set: + arg1 = union_set(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_set_list_add(isl.isl_union_set_list_copy(arg0.ptr), isl.isl_union_set_copy(arg1.ptr)) + obj = union_set_list(ctx=ctx, ptr=res) + return obj + def at(arg0, arg1): + try: + if not arg0.__class__ is union_set_list: + arg0 = union_set_list(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_set_list_get_at(arg0.ptr, arg1) + obj = union_set(ctx=ctx, ptr=res) + return obj + def get_at(arg0, arg1): + return arg0.at(arg1) + def clear(arg0): + try: + if not arg0.__class__ is union_set_list: + arg0 = union_set_list(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_set_list_clear(isl.isl_union_set_list_copy(arg0.ptr)) + obj = union_set_list(ctx=ctx, ptr=res) + return obj + def concat(arg0, arg1): + try: + if not arg0.__class__ is union_set_list: + arg0 = union_set_list(arg0) + except: + raise + try: + if not arg1.__class__ is union_set_list: + arg1 = union_set_list(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_set_list_concat(isl.isl_union_set_list_copy(arg0.ptr), isl.isl_union_set_list_copy(arg1.ptr)) + obj = union_set_list(ctx=ctx, ptr=res) + return obj + def drop(arg0, arg1, arg2): + try: + if not arg0.__class__ is union_set_list: + arg0 = union_set_list(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_set_list_drop(isl.isl_union_set_list_copy(arg0.ptr), arg1, arg2) + obj = union_set_list(ctx=ctx, ptr=res) + return obj + def foreach(arg0, arg1): + try: + if not arg0.__class__ is union_set_list: + arg0 = union_set_list(arg0) + except: + raise + exc_info = [None] + fn = CFUNCTYPE(c_int, c_void_p, c_void_p) + def cb_func(cb_arg0, cb_arg1): + cb_arg0 = union_set(ctx=arg0.ctx, ptr=(cb_arg0)) + try: + arg1(cb_arg0) + except BaseException as e: + exc_info[0] = e + return -1 + return 0 + cb1 = fn(cb_func) + ctx = arg0.ctx + res = isl.isl_union_set_list_foreach(arg0.ptr, cb1, None) + if exc_info[0] is not None: + raise exc_info[0] + if res < 0: + raise Error + def foreach_scc(arg0, arg1, arg2): + try: + if not arg0.__class__ is union_set_list: + arg0 = union_set_list(arg0) + except: + raise + exc_info = [None] + fn = CFUNCTYPE(c_int, c_void_p, c_void_p, c_void_p) + def cb_func(cb_arg0, cb_arg1, cb_arg2): + cb_arg0 = union_set(ctx=arg0.ctx, ptr=isl.isl_union_set_copy(cb_arg0)) + cb_arg1 = union_set(ctx=arg0.ctx, ptr=isl.isl_union_set_copy(cb_arg1)) + try: + res = arg1(cb_arg0, cb_arg1) + except BaseException as e: + exc_info[0] = e + return -1 + return 1 if res else 0 + cb1 = fn(cb_func) + exc_info = [None] + fn = CFUNCTYPE(c_int, c_void_p, c_void_p) + def cb_func(cb_arg0, cb_arg1): + cb_arg0 = union_set_list(ctx=arg0.ctx, ptr=(cb_arg0)) + try: + arg2(cb_arg0) + except BaseException as e: + exc_info[0] = e + return -1 + return 0 + cb2 = fn(cb_func) + ctx = arg0.ctx + res = isl.isl_union_set_list_foreach_scc(arg0.ptr, cb1, None, cb2, None) + if exc_info[0] is not None: + raise exc_info[0] + if res < 0: + raise Error + def insert(arg0, arg1, arg2): + try: + if not arg0.__class__ is union_set_list: + arg0 = union_set_list(arg0) + except: + raise + try: + if not arg2.__class__ is union_set: + arg2 = union_set(arg2) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_set_list_insert(isl.isl_union_set_list_copy(arg0.ptr), arg1, isl.isl_union_set_copy(arg2.ptr)) + obj = union_set_list(ctx=ctx, ptr=res) + return obj + def set_at(arg0, arg1, arg2): + try: + if not arg0.__class__ is union_set_list: + arg0 = union_set_list(arg0) + except: + raise + try: + if not arg2.__class__ is union_set: + arg2 = union_set(arg2) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_set_list_set_at(isl.isl_union_set_list_copy(arg0.ptr), arg1, isl.isl_union_set_copy(arg2.ptr)) + obj = union_set_list(ctx=ctx, ptr=res) + return obj + def size(arg0): + try: + if not arg0.__class__ is union_set_list: + arg0 = union_set_list(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_union_set_list_size(arg0.ptr) + if res < 0: + raise Error + return int(res) + +isl.isl_union_set_list_alloc.restype = c_void_p +isl.isl_union_set_list_alloc.argtypes = [Context, c_int] +isl.isl_union_set_list_from_union_set.restype = c_void_p +isl.isl_union_set_list_from_union_set.argtypes = [c_void_p] +isl.isl_union_set_list_read_from_str.restype = c_void_p +isl.isl_union_set_list_read_from_str.argtypes = [Context, c_char_p] +isl.isl_union_set_list_add.restype = c_void_p +isl.isl_union_set_list_add.argtypes = [c_void_p, c_void_p] +isl.isl_union_set_list_get_at.restype = c_void_p +isl.isl_union_set_list_get_at.argtypes = [c_void_p, c_int] +isl.isl_union_set_list_clear.restype = c_void_p +isl.isl_union_set_list_clear.argtypes = [c_void_p] +isl.isl_union_set_list_concat.restype = c_void_p +isl.isl_union_set_list_concat.argtypes = [c_void_p, c_void_p] +isl.isl_union_set_list_drop.restype = c_void_p +isl.isl_union_set_list_drop.argtypes = [c_void_p, c_int, c_int] +isl.isl_union_set_list_foreach.argtypes = [c_void_p, c_void_p, c_void_p] +isl.isl_union_set_list_foreach_scc.argtypes = [c_void_p, c_void_p, c_void_p, c_void_p, c_void_p] +isl.isl_union_set_list_insert.restype = c_void_p +isl.isl_union_set_list_insert.argtypes = [c_void_p, c_int, c_void_p] +isl.isl_union_set_list_set_at.restype = c_void_p +isl.isl_union_set_list_set_at.argtypes = [c_void_p, c_int, c_void_p] +isl.isl_union_set_list_size.argtypes = [c_void_p] +isl.isl_union_set_list_copy.restype = c_void_p +isl.isl_union_set_list_copy.argtypes = [c_void_p] +isl.isl_union_set_list_free.restype = c_void_p +isl.isl_union_set_list_free.argtypes = [c_void_p] +isl.isl_union_set_list_to_str.restype = POINTER(c_char) +isl.isl_union_set_list_to_str.argtypes = [c_void_p] + +class val(object): + def __init__(self, *args, **keywords): + if "ptr" in keywords: + self.ctx = keywords["ctx"] + self.ptr = keywords["ptr"] + return + if len(args) == 1 and type(args[0]) == int: + self.ctx = Context.getDefaultInstance() + self.ptr = isl.isl_val_int_from_si(self.ctx, args[0]) + return + if len(args) == 1 and type(args[0]) == str: + self.ctx = Context.getDefaultInstance() + self.ptr = isl.isl_val_read_from_str(self.ctx, args[0].encode('ascii')) + return + raise Error + def __del__(self): + if hasattr(self, 'ptr'): + isl.isl_val_free(self.ptr) + def __str__(arg0): + try: + if not arg0.__class__ is val: + arg0 = val(arg0) + except: + raise + ptr = isl.isl_val_to_str(arg0.ptr) + res = cast(ptr, c_char_p).value.decode('ascii') + libc.free(ptr) + return res + def __repr__(self): + s = str(self) + if '"' in s: + return 'isl.val("""%s""")' % s + else: + return 'isl.val("%s")' % s + def abs(arg0): + try: + if not arg0.__class__ is val: + arg0 = val(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_val_abs(isl.isl_val_copy(arg0.ptr)) + obj = val(ctx=ctx, ptr=res) + return obj + def abs_eq(arg0, arg1): + try: + if not arg0.__class__ is val: + arg0 = val(arg0) + except: + raise + try: + if not arg1.__class__ is val: + arg1 = val(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_val_abs_eq(arg0.ptr, arg1.ptr) + if res < 0: + raise Error + return bool(res) + def add(arg0, arg1): + try: + if not arg0.__class__ is val: + arg0 = val(arg0) + except: + raise + try: + if not arg1.__class__ is val: + arg1 = val(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_val_add(isl.isl_val_copy(arg0.ptr), isl.isl_val_copy(arg1.ptr)) + obj = val(ctx=ctx, ptr=res) + return obj + def ceil(arg0): + try: + if not arg0.__class__ is val: + arg0 = val(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_val_ceil(isl.isl_val_copy(arg0.ptr)) + obj = val(ctx=ctx, ptr=res) + return obj + def cmp_si(arg0, arg1): + try: + if not arg0.__class__ is val: + arg0 = val(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_val_cmp_si(arg0.ptr, arg1) + return res + def den_si(arg0): + try: + if not arg0.__class__ is val: + arg0 = val(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_val_get_den_si(arg0.ptr) + return res + def get_den_si(arg0): + return arg0.den_si() + def div(arg0, arg1): + try: + if not arg0.__class__ is val: + arg0 = val(arg0) + except: + raise + try: + if not arg1.__class__ is val: + arg1 = val(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_val_div(isl.isl_val_copy(arg0.ptr), isl.isl_val_copy(arg1.ptr)) + obj = val(ctx=ctx, ptr=res) + return obj + def eq(arg0, arg1): + try: + if not arg0.__class__ is val: + arg0 = val(arg0) + except: + raise + try: + if not arg1.__class__ is val: + arg1 = val(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_val_eq(arg0.ptr, arg1.ptr) + if res < 0: + raise Error + return bool(res) + def floor(arg0): + try: + if not arg0.__class__ is val: + arg0 = val(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_val_floor(isl.isl_val_copy(arg0.ptr)) + obj = val(ctx=ctx, ptr=res) + return obj + def gcd(arg0, arg1): + try: + if not arg0.__class__ is val: + arg0 = val(arg0) + except: + raise + try: + if not arg1.__class__ is val: + arg1 = val(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_val_gcd(isl.isl_val_copy(arg0.ptr), isl.isl_val_copy(arg1.ptr)) + obj = val(ctx=ctx, ptr=res) + return obj + def ge(arg0, arg1): + try: + if not arg0.__class__ is val: + arg0 = val(arg0) + except: + raise + try: + if not arg1.__class__ is val: + arg1 = val(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_val_ge(arg0.ptr, arg1.ptr) + if res < 0: + raise Error + return bool(res) + def gt(arg0, arg1): + try: + if not arg0.__class__ is val: + arg0 = val(arg0) + except: + raise + try: + if not arg1.__class__ is val: + arg1 = val(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_val_gt(arg0.ptr, arg1.ptr) + if res < 0: + raise Error + return bool(res) + @staticmethod + def infty(): + ctx = Context.getDefaultInstance() + res = isl.isl_val_infty(ctx) + obj = val(ctx=ctx, ptr=res) + return obj + def inv(arg0): + try: + if not arg0.__class__ is val: + arg0 = val(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_val_inv(isl.isl_val_copy(arg0.ptr)) + obj = val(ctx=ctx, ptr=res) + return obj + def is_divisible_by(arg0, arg1): + try: + if not arg0.__class__ is val: + arg0 = val(arg0) + except: + raise + try: + if not arg1.__class__ is val: + arg1 = val(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_val_is_divisible_by(arg0.ptr, arg1.ptr) + if res < 0: + raise Error + return bool(res) + def is_infty(arg0): + try: + if not arg0.__class__ is val: + arg0 = val(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_val_is_infty(arg0.ptr) + if res < 0: + raise Error + return bool(res) + def is_int(arg0): + try: + if not arg0.__class__ is val: + arg0 = val(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_val_is_int(arg0.ptr) + if res < 0: + raise Error + return bool(res) + def is_nan(arg0): + try: + if not arg0.__class__ is val: + arg0 = val(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_val_is_nan(arg0.ptr) + if res < 0: + raise Error + return bool(res) + def is_neg(arg0): + try: + if not arg0.__class__ is val: + arg0 = val(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_val_is_neg(arg0.ptr) + if res < 0: + raise Error + return bool(res) + def is_neginfty(arg0): + try: + if not arg0.__class__ is val: + arg0 = val(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_val_is_neginfty(arg0.ptr) + if res < 0: + raise Error + return bool(res) + def is_negone(arg0): + try: + if not arg0.__class__ is val: + arg0 = val(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_val_is_negone(arg0.ptr) + if res < 0: + raise Error + return bool(res) + def is_nonneg(arg0): + try: + if not arg0.__class__ is val: + arg0 = val(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_val_is_nonneg(arg0.ptr) + if res < 0: + raise Error + return bool(res) + def is_nonpos(arg0): + try: + if not arg0.__class__ is val: + arg0 = val(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_val_is_nonpos(arg0.ptr) + if res < 0: + raise Error + return bool(res) + def is_one(arg0): + try: + if not arg0.__class__ is val: + arg0 = val(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_val_is_one(arg0.ptr) + if res < 0: + raise Error + return bool(res) + def is_pos(arg0): + try: + if not arg0.__class__ is val: + arg0 = val(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_val_is_pos(arg0.ptr) + if res < 0: + raise Error + return bool(res) + def is_rat(arg0): + try: + if not arg0.__class__ is val: + arg0 = val(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_val_is_rat(arg0.ptr) + if res < 0: + raise Error + return bool(res) + def is_zero(arg0): + try: + if not arg0.__class__ is val: + arg0 = val(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_val_is_zero(arg0.ptr) + if res < 0: + raise Error + return bool(res) + def le(arg0, arg1): + try: + if not arg0.__class__ is val: + arg0 = val(arg0) + except: + raise + try: + if not arg1.__class__ is val: + arg1 = val(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_val_le(arg0.ptr, arg1.ptr) + if res < 0: + raise Error + return bool(res) + def lt(arg0, arg1): + try: + if not arg0.__class__ is val: + arg0 = val(arg0) + except: + raise + try: + if not arg1.__class__ is val: + arg1 = val(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_val_lt(arg0.ptr, arg1.ptr) + if res < 0: + raise Error + return bool(res) + def max(arg0, arg1): + try: + if not arg0.__class__ is val: + arg0 = val(arg0) + except: + raise + try: + if not arg1.__class__ is val: + arg1 = val(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_val_max(isl.isl_val_copy(arg0.ptr), isl.isl_val_copy(arg1.ptr)) + obj = val(ctx=ctx, ptr=res) + return obj + def min(arg0, arg1): + try: + if not arg0.__class__ is val: + arg0 = val(arg0) + except: + raise + try: + if not arg1.__class__ is val: + arg1 = val(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_val_min(isl.isl_val_copy(arg0.ptr), isl.isl_val_copy(arg1.ptr)) + obj = val(ctx=ctx, ptr=res) + return obj + def mod(arg0, arg1): + try: + if not arg0.__class__ is val: + arg0 = val(arg0) + except: + raise + try: + if not arg1.__class__ is val: + arg1 = val(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_val_mod(isl.isl_val_copy(arg0.ptr), isl.isl_val_copy(arg1.ptr)) + obj = val(ctx=ctx, ptr=res) + return obj + def mul(arg0, arg1): + try: + if not arg0.__class__ is val: + arg0 = val(arg0) + except: + raise + try: + if not arg1.__class__ is val: + arg1 = val(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_val_mul(isl.isl_val_copy(arg0.ptr), isl.isl_val_copy(arg1.ptr)) + obj = val(ctx=ctx, ptr=res) + return obj + @staticmethod + def nan(): + ctx = Context.getDefaultInstance() + res = isl.isl_val_nan(ctx) + obj = val(ctx=ctx, ptr=res) + return obj + def ne(arg0, arg1): + try: + if not arg0.__class__ is val: + arg0 = val(arg0) + except: + raise + try: + if not arg1.__class__ is val: + arg1 = val(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_val_ne(arg0.ptr, arg1.ptr) + if res < 0: + raise Error + return bool(res) + def neg(arg0): + try: + if not arg0.__class__ is val: + arg0 = val(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_val_neg(isl.isl_val_copy(arg0.ptr)) + obj = val(ctx=ctx, ptr=res) + return obj + @staticmethod + def neginfty(): + ctx = Context.getDefaultInstance() + res = isl.isl_val_neginfty(ctx) + obj = val(ctx=ctx, ptr=res) + return obj + @staticmethod + def negone(): + ctx = Context.getDefaultInstance() + res = isl.isl_val_negone(ctx) + obj = val(ctx=ctx, ptr=res) + return obj + def num_si(arg0): + try: + if not arg0.__class__ is val: + arg0 = val(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_val_get_num_si(arg0.ptr) + return res + def get_num_si(arg0): + return arg0.num_si() + @staticmethod + def one(): + ctx = Context.getDefaultInstance() + res = isl.isl_val_one(ctx) + obj = val(ctx=ctx, ptr=res) + return obj + def pow2(arg0): + try: + if not arg0.__class__ is val: + arg0 = val(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_val_pow2(isl.isl_val_copy(arg0.ptr)) + obj = val(ctx=ctx, ptr=res) + return obj + def sgn(arg0): + try: + if not arg0.__class__ is val: + arg0 = val(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_val_sgn(arg0.ptr) + return res + def sub(arg0, arg1): + try: + if not arg0.__class__ is val: + arg0 = val(arg0) + except: + raise + try: + if not arg1.__class__ is val: + arg1 = val(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_val_sub(isl.isl_val_copy(arg0.ptr), isl.isl_val_copy(arg1.ptr)) + obj = val(ctx=ctx, ptr=res) + return obj + def to_list(arg0): + try: + if not arg0.__class__ is val: + arg0 = val(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_val_to_list(isl.isl_val_copy(arg0.ptr)) + obj = val_list(ctx=ctx, ptr=res) + return obj + def trunc(arg0): + try: + if not arg0.__class__ is val: + arg0 = val(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_val_trunc(isl.isl_val_copy(arg0.ptr)) + obj = val(ctx=ctx, ptr=res) + return obj + @staticmethod + def zero(): + ctx = Context.getDefaultInstance() + res = isl.isl_val_zero(ctx) + obj = val(ctx=ctx, ptr=res) + return obj + +isl.isl_val_int_from_si.restype = c_void_p +isl.isl_val_int_from_si.argtypes = [Context, c_long] +isl.isl_val_read_from_str.restype = c_void_p +isl.isl_val_read_from_str.argtypes = [Context, c_char_p] +isl.isl_val_abs.restype = c_void_p +isl.isl_val_abs.argtypes = [c_void_p] +isl.isl_val_abs_eq.argtypes = [c_void_p, c_void_p] +isl.isl_val_add.restype = c_void_p +isl.isl_val_add.argtypes = [c_void_p, c_void_p] +isl.isl_val_ceil.restype = c_void_p +isl.isl_val_ceil.argtypes = [c_void_p] +isl.isl_val_cmp_si.argtypes = [c_void_p, c_long] +isl.isl_val_get_den_si.argtypes = [c_void_p] +isl.isl_val_div.restype = c_void_p +isl.isl_val_div.argtypes = [c_void_p, c_void_p] +isl.isl_val_eq.argtypes = [c_void_p, c_void_p] +isl.isl_val_floor.restype = c_void_p +isl.isl_val_floor.argtypes = [c_void_p] +isl.isl_val_gcd.restype = c_void_p +isl.isl_val_gcd.argtypes = [c_void_p, c_void_p] +isl.isl_val_ge.argtypes = [c_void_p, c_void_p] +isl.isl_val_gt.argtypes = [c_void_p, c_void_p] +isl.isl_val_infty.restype = c_void_p +isl.isl_val_infty.argtypes = [Context] +isl.isl_val_inv.restype = c_void_p +isl.isl_val_inv.argtypes = [c_void_p] +isl.isl_val_is_divisible_by.argtypes = [c_void_p, c_void_p] +isl.isl_val_is_infty.argtypes = [c_void_p] +isl.isl_val_is_int.argtypes = [c_void_p] +isl.isl_val_is_nan.argtypes = [c_void_p] +isl.isl_val_is_neg.argtypes = [c_void_p] +isl.isl_val_is_neginfty.argtypes = [c_void_p] +isl.isl_val_is_negone.argtypes = [c_void_p] +isl.isl_val_is_nonneg.argtypes = [c_void_p] +isl.isl_val_is_nonpos.argtypes = [c_void_p] +isl.isl_val_is_one.argtypes = [c_void_p] +isl.isl_val_is_pos.argtypes = [c_void_p] +isl.isl_val_is_rat.argtypes = [c_void_p] +isl.isl_val_is_zero.argtypes = [c_void_p] +isl.isl_val_le.argtypes = [c_void_p, c_void_p] +isl.isl_val_lt.argtypes = [c_void_p, c_void_p] +isl.isl_val_max.restype = c_void_p +isl.isl_val_max.argtypes = [c_void_p, c_void_p] +isl.isl_val_min.restype = c_void_p +isl.isl_val_min.argtypes = [c_void_p, c_void_p] +isl.isl_val_mod.restype = c_void_p +isl.isl_val_mod.argtypes = [c_void_p, c_void_p] +isl.isl_val_mul.restype = c_void_p +isl.isl_val_mul.argtypes = [c_void_p, c_void_p] +isl.isl_val_nan.restype = c_void_p +isl.isl_val_nan.argtypes = [Context] +isl.isl_val_ne.argtypes = [c_void_p, c_void_p] +isl.isl_val_neg.restype = c_void_p +isl.isl_val_neg.argtypes = [c_void_p] +isl.isl_val_neginfty.restype = c_void_p +isl.isl_val_neginfty.argtypes = [Context] +isl.isl_val_negone.restype = c_void_p +isl.isl_val_negone.argtypes = [Context] +isl.isl_val_get_num_si.argtypes = [c_void_p] +isl.isl_val_one.restype = c_void_p +isl.isl_val_one.argtypes = [Context] +isl.isl_val_pow2.restype = c_void_p +isl.isl_val_pow2.argtypes = [c_void_p] +isl.isl_val_sgn.argtypes = [c_void_p] +isl.isl_val_sub.restype = c_void_p +isl.isl_val_sub.argtypes = [c_void_p, c_void_p] +isl.isl_val_to_list.restype = c_void_p +isl.isl_val_to_list.argtypes = [c_void_p] +isl.isl_val_trunc.restype = c_void_p +isl.isl_val_trunc.argtypes = [c_void_p] +isl.isl_val_zero.restype = c_void_p +isl.isl_val_zero.argtypes = [Context] +isl.isl_val_copy.restype = c_void_p +isl.isl_val_copy.argtypes = [c_void_p] +isl.isl_val_free.restype = c_void_p +isl.isl_val_free.argtypes = [c_void_p] +isl.isl_val_to_str.restype = POINTER(c_char) +isl.isl_val_to_str.argtypes = [c_void_p] + +class val_list(object): + def __init__(self, *args, **keywords): + if "ptr" in keywords: + self.ctx = keywords["ctx"] + self.ptr = keywords["ptr"] + return + if len(args) == 1 and type(args[0]) == int: + self.ctx = Context.getDefaultInstance() + self.ptr = isl.isl_val_list_alloc(self.ctx, args[0]) + return + if len(args) == 1 and (args[0].__class__ is val or type(args[0]) == int): + args = list(args) + try: + if not args[0].__class__ is val: + args[0] = val(args[0]) + except: + raise + self.ctx = Context.getDefaultInstance() + self.ptr = isl.isl_val_list_from_val(isl.isl_val_copy(args[0].ptr)) + return + if len(args) == 1 and type(args[0]) == str: + self.ctx = Context.getDefaultInstance() + self.ptr = isl.isl_val_list_read_from_str(self.ctx, args[0].encode('ascii')) + return + raise Error + def __del__(self): + if hasattr(self, 'ptr'): + isl.isl_val_list_free(self.ptr) + def __str__(arg0): + try: + if not arg0.__class__ is val_list: + arg0 = val_list(arg0) + except: + raise + ptr = isl.isl_val_list_to_str(arg0.ptr) + res = cast(ptr, c_char_p).value.decode('ascii') + libc.free(ptr) + return res + def __repr__(self): + s = str(self) + if '"' in s: + return 'isl.val_list("""%s""")' % s + else: + return 'isl.val_list("%s")' % s + def add(arg0, arg1): + try: + if not arg0.__class__ is val_list: + arg0 = val_list(arg0) + except: + raise + try: + if not arg1.__class__ is val: + arg1 = val(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_val_list_add(isl.isl_val_list_copy(arg0.ptr), isl.isl_val_copy(arg1.ptr)) + obj = val_list(ctx=ctx, ptr=res) + return obj + def at(arg0, arg1): + try: + if not arg0.__class__ is val_list: + arg0 = val_list(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_val_list_get_at(arg0.ptr, arg1) + obj = val(ctx=ctx, ptr=res) + return obj + def get_at(arg0, arg1): + return arg0.at(arg1) + def clear(arg0): + try: + if not arg0.__class__ is val_list: + arg0 = val_list(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_val_list_clear(isl.isl_val_list_copy(arg0.ptr)) + obj = val_list(ctx=ctx, ptr=res) + return obj + def concat(arg0, arg1): + try: + if not arg0.__class__ is val_list: + arg0 = val_list(arg0) + except: + raise + try: + if not arg1.__class__ is val_list: + arg1 = val_list(arg1) + except: + raise + ctx = arg0.ctx + res = isl.isl_val_list_concat(isl.isl_val_list_copy(arg0.ptr), isl.isl_val_list_copy(arg1.ptr)) + obj = val_list(ctx=ctx, ptr=res) + return obj + def drop(arg0, arg1, arg2): + try: + if not arg0.__class__ is val_list: + arg0 = val_list(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_val_list_drop(isl.isl_val_list_copy(arg0.ptr), arg1, arg2) + obj = val_list(ctx=ctx, ptr=res) + return obj + def foreach(arg0, arg1): + try: + if not arg0.__class__ is val_list: + arg0 = val_list(arg0) + except: + raise + exc_info = [None] + fn = CFUNCTYPE(c_int, c_void_p, c_void_p) + def cb_func(cb_arg0, cb_arg1): + cb_arg0 = val(ctx=arg0.ctx, ptr=(cb_arg0)) + try: + arg1(cb_arg0) + except BaseException as e: + exc_info[0] = e + return -1 + return 0 + cb1 = fn(cb_func) + ctx = arg0.ctx + res = isl.isl_val_list_foreach(arg0.ptr, cb1, None) + if exc_info[0] is not None: + raise exc_info[0] + if res < 0: + raise Error + def foreach_scc(arg0, arg1, arg2): + try: + if not arg0.__class__ is val_list: + arg0 = val_list(arg0) + except: + raise + exc_info = [None] + fn = CFUNCTYPE(c_int, c_void_p, c_void_p, c_void_p) + def cb_func(cb_arg0, cb_arg1, cb_arg2): + cb_arg0 = val(ctx=arg0.ctx, ptr=isl.isl_val_copy(cb_arg0)) + cb_arg1 = val(ctx=arg0.ctx, ptr=isl.isl_val_copy(cb_arg1)) + try: + res = arg1(cb_arg0, cb_arg1) + except BaseException as e: + exc_info[0] = e + return -1 + return 1 if res else 0 + cb1 = fn(cb_func) + exc_info = [None] + fn = CFUNCTYPE(c_int, c_void_p, c_void_p) + def cb_func(cb_arg0, cb_arg1): + cb_arg0 = val_list(ctx=arg0.ctx, ptr=(cb_arg0)) + try: + arg2(cb_arg0) + except BaseException as e: + exc_info[0] = e + return -1 + return 0 + cb2 = fn(cb_func) + ctx = arg0.ctx + res = isl.isl_val_list_foreach_scc(arg0.ptr, cb1, None, cb2, None) + if exc_info[0] is not None: + raise exc_info[0] + if res < 0: + raise Error + def insert(arg0, arg1, arg2): + try: + if not arg0.__class__ is val_list: + arg0 = val_list(arg0) + except: + raise + try: + if not arg2.__class__ is val: + arg2 = val(arg2) + except: + raise + ctx = arg0.ctx + res = isl.isl_val_list_insert(isl.isl_val_list_copy(arg0.ptr), arg1, isl.isl_val_copy(arg2.ptr)) + obj = val_list(ctx=ctx, ptr=res) + return obj + def set_at(arg0, arg1, arg2): + try: + if not arg0.__class__ is val_list: + arg0 = val_list(arg0) + except: + raise + try: + if not arg2.__class__ is val: + arg2 = val(arg2) + except: + raise + ctx = arg0.ctx + res = isl.isl_val_list_set_at(isl.isl_val_list_copy(arg0.ptr), arg1, isl.isl_val_copy(arg2.ptr)) + obj = val_list(ctx=ctx, ptr=res) + return obj + def size(arg0): + try: + if not arg0.__class__ is val_list: + arg0 = val_list(arg0) + except: + raise + ctx = arg0.ctx + res = isl.isl_val_list_size(arg0.ptr) + if res < 0: + raise Error + return int(res) + +isl.isl_val_list_alloc.restype = c_void_p +isl.isl_val_list_alloc.argtypes = [Context, c_int] +isl.isl_val_list_from_val.restype = c_void_p +isl.isl_val_list_from_val.argtypes = [c_void_p] +isl.isl_val_list_read_from_str.restype = c_void_p +isl.isl_val_list_read_from_str.argtypes = [Context, c_char_p] +isl.isl_val_list_add.restype = c_void_p +isl.isl_val_list_add.argtypes = [c_void_p, c_void_p] +isl.isl_val_list_get_at.restype = c_void_p +isl.isl_val_list_get_at.argtypes = [c_void_p, c_int] +isl.isl_val_list_clear.restype = c_void_p +isl.isl_val_list_clear.argtypes = [c_void_p] +isl.isl_val_list_concat.restype = c_void_p +isl.isl_val_list_concat.argtypes = [c_void_p, c_void_p] +isl.isl_val_list_drop.restype = c_void_p +isl.isl_val_list_drop.argtypes = [c_void_p, c_int, c_int] +isl.isl_val_list_foreach.argtypes = [c_void_p, c_void_p, c_void_p] +isl.isl_val_list_foreach_scc.argtypes = [c_void_p, c_void_p, c_void_p, c_void_p, c_void_p] +isl.isl_val_list_insert.restype = c_void_p +isl.isl_val_list_insert.argtypes = [c_void_p, c_int, c_void_p] +isl.isl_val_list_set_at.restype = c_void_p +isl.isl_val_list_set_at.argtypes = [c_void_p, c_int, c_void_p] +isl.isl_val_list_size.argtypes = [c_void_p] +isl.isl_val_list_copy.restype = c_void_p +isl.isl_val_list_copy.argtypes = [c_void_p] +isl.isl_val_list_free.restype = c_void_p +isl.isl_val_list_free.argtypes = [c_void_p] +isl.isl_val_list_to_str.restype = POINTER(c_char) +isl.isl_val_list_to_str.argtypes = [c_void_p] diff --git a/external/mit/isl/dist/interface/isl_config.h.in b/external/mit/isl/dist/interface/isl_config.h.in new file mode 100644 index 000000000000..ee53a6ac31b5 --- /dev/null +++ b/external/mit/isl/dist/interface/isl_config.h.in @@ -0,0 +1,162 @@ +/* isl_config.h.in. Generated from configure.ac by autoheader. */ + +/* Define if HeaderSearchOptions::AddPath takes 4 arguments */ +#undef ADDPATH_TAKES_4_ARGUMENTS + +/* Clang installation prefix */ +#undef CLANG_PREFIX + +/* Define to sysroot if needed */ +#undef CLANG_SYSROOT + +/* Define if CompilerInstance::createDiagnostics takes argc and argv */ +#undef CREATEDIAGNOSTICS_TAKES_ARG + +/* Define if CompilerInstance::createPreprocessor takes TranslationUnitKind */ +#undef CREATEPREPROCESSOR_TAKES_TUKIND + +/* Define if TargetInfo::CreateTargetInfo takes pointer */ +#undef CREATETARGETINFO_TAKES_POINTER + +/* Define if TargetInfo::CreateTargetInfo takes shared_ptr */ +#undef CREATETARGETINFO_TAKES_SHARED_PTR + +/* Define if CompilerInvocation::CreateFromArgs takes ArrayRef */ +#undef CREATE_FROM_ARGS_TAKES_ARRAYREF + +/* Define if Driver constructor takes default image name */ +#undef DRIVER_CTOR_TAKES_DEFAULTIMAGENAME + +/* Define to Diagnostic for older versions of clang */ +#undef DiagnosticsEngine + +/* Define if llvm/ADT/OwningPtr.h exists */ +#undef HAVE_ADT_OWNINGPTR_H + +/* 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 + +/* Define to 1 if you have the header file. */ +#undef HAVE_DLFCN_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_INTTYPES_H + +/* Define if Driver constructor takes IsProduction argument */ +#undef HAVE_ISPRODUCTION + +/* Define if clang/Lex/PreprocessorOptions.h exists */ +#undef HAVE_LEX_PREPROCESSOROPTIONS_H + +/* Define if llvm/Option/Arg.h exists */ +#undef HAVE_LLVM_OPTION_ARG_H + +/* Define if SourceManager has a setMainFileID method */ +#undef HAVE_SETMAINFILEID + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDIO_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define if llvm/TargetParser/Host.h exists */ +#undef HAVE_TARGETPARSER_HOST_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Return type of HandleTopLevelDeclReturn */ +#undef HandleTopLevelDeclContinue + +/* Return type of HandleTopLevelDeclReturn */ +#undef HandleTopLevelDeclReturn + +/* Define to Language::C or InputKind::C for newer versions of clang */ +#undef IK_C + +/* Define to the sub-directory where libtool stores uninstalled libraries. */ +#undef LT_OBJDIR + +/* Name of package */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the home page for this package. */ +#undef PACKAGE_URL + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Defined if CompilerInstance::setInvocation takes a shared_ptr */ +#undef SETINVOCATION_TAKES_SHARED_PTR + +/* Define to class with setLangDefaults method */ +#undef SETLANGDEFAULTS + +/* Define if CompilerInvocation::setLangDefaults takes 5 arguments */ +#undef SETLANGDEFAULTS_TAKES_5_ARGUMENTS + +/* Define to 1 if all of the C90 standard headers exist (not just the ones + required in a freestanding environment). This macro is provided for + backward compatibility; new code need not use it. */ +#undef STDC_HEADERS + +/* Define if Driver::BuildCompilation takes ArrayRef */ +#undef USE_ARRAYREF + +/* Version number of package */ +#undef VERSION + +/* Define to getParamType for newer versions of clang */ +#undef getArgType + +/* Define to getHostTriple for older versions of clang */ +#undef getDefaultTargetTriple + +/* Define to getInstantiationLineNumber for older versions of clang */ +#undef getExpansionLineNumber + +/* Define to getImmediateInstantiationRange for older versions of clang */ +#undef getImmediateExpansionRange + +/* Define to getNumParams for newer versions of clang */ +#undef getNumArgs + +/* Define to getResultType for older versions of clang */ +#undef getReturnType + +/* Define to InitializeBuiltins for older versions of clang */ +#undef initializeBuiltins diff --git a/external/mit/isl/dist/interface/ltmain.sh b/external/mit/isl/dist/interface/ltmain.sh new file mode 100755 index 000000000000..540a92ab5476 --- /dev/null +++ b/external/mit/isl/dist/interface/ltmain.sh @@ -0,0 +1,11251 @@ +#! /bin/sh +## DO NOT EDIT - This file generated from ./build-aux/ltmain.in +## by inline-source v2014-01-03.01 + +# libtool (GNU libtool) 2.4.6 +# Provide generalized library-building support services. +# Written by Gordon Matzigkeit , 1996 + +# Copyright (C) 1996-2015 Free Software Foundation, Inc. +# This is free software; see the source for copying conditions. There is NO +# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +# GNU Libtool is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# As a special exception to the GNU General Public License, +# if you distribute this file as part of a program or library that +# is built using GNU Libtool, you may include this file under the +# same distribution terms that you use for the rest of that program. +# +# GNU Libtool is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + + +PROGRAM=libtool +PACKAGE=libtool +VERSION="2.4.6 Debian-2.4.6-15build2" +package_revision=2.4.6 + + +## ------ ## +## Usage. ## +## ------ ## + +# Run './libtool --help' for help with using this script from the +# command line. + + +## ------------------------------- ## +## User overridable command paths. ## +## ------------------------------- ## + +# After configure completes, it has a better idea of some of the +# shell tools we need than the defaults used by the functions shared +# with bootstrap, so set those here where they can still be over- +# ridden by the user, but otherwise take precedence. + +: ${AUTOCONF="autoconf"} +: ${AUTOMAKE="automake"} + + +## -------------------------- ## +## Source external libraries. ## +## -------------------------- ## + +# Much of our low-level functionality needs to be sourced from external +# libraries, which are installed to $pkgauxdir. + +# Set a version string for this script. +scriptversion=2015-01-20.17; # UTC + +# General shell script boiler plate, and helper functions. +# Written by Gary V. Vaughan, 2004 + +# Copyright (C) 2004-2015 Free Software Foundation, Inc. +# This is free software; see the source for copying conditions. There is NO +# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. + +# As a special exception to the GNU General Public License, if you distribute +# this file as part of a program or library that is built using GNU Libtool, +# you may include this file under the same distribution terms that you use +# for the rest of that program. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNES FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# Please report bugs or propose patches to gary@gnu.org. + + +## ------ ## +## Usage. ## +## ------ ## + +# Evaluate this file near the top of your script to gain access to +# the functions and variables defined here: +# +# . `echo "$0" | ${SED-sed} 's|[^/]*$||'`/build-aux/funclib.sh +# +# If you need to override any of the default environment variable +# settings, do that before evaluating this file. + + +## -------------------- ## +## Shell normalisation. ## +## -------------------- ## + +# Some shells need a little help to be as Bourne compatible as possible. +# Before doing anything else, make sure all that help has been provided! + +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in *posix*) set -o posix ;; esac +fi + +# NLS nuisances: We save the old values in case they are required later. +_G_user_locale= +_G_safe_locale= +for _G_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES +do + eval "if test set = \"\${$_G_var+set}\"; then + save_$_G_var=\$$_G_var + $_G_var=C + export $_G_var + _G_user_locale=\"$_G_var=\\\$save_\$_G_var; \$_G_user_locale\" + _G_safe_locale=\"$_G_var=C; \$_G_safe_locale\" + fi" +done + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +# Make sure IFS has a sensible default +sp=' ' +nl=' +' +IFS="$sp $nl" + +# There are apparently some retarded systems that use ';' as a PATH separator! +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + + +## ------------------------- ## +## Locate command utilities. ## +## ------------------------- ## + + +# func_executable_p FILE +# ---------------------- +# Check that FILE is an executable regular file. +func_executable_p () +{ + test -f "$1" && test -x "$1" +} + + +# func_path_progs PROGS_LIST CHECK_FUNC [PATH] +# -------------------------------------------- +# Search for either a program that responds to --version with output +# containing "GNU", or else returned by CHECK_FUNC otherwise, by +# trying all the directories in PATH with each of the elements of +# PROGS_LIST. +# +# CHECK_FUNC should accept the path to a candidate program, and +# set $func_check_prog_result if it truncates its output less than +# $_G_path_prog_max characters. +func_path_progs () +{ + _G_progs_list=$1 + _G_check_func=$2 + _G_PATH=${3-"$PATH"} + + _G_path_prog_max=0 + _G_path_prog_found=false + _G_save_IFS=$IFS; IFS=${PATH_SEPARATOR-:} + for _G_dir in $_G_PATH; do + IFS=$_G_save_IFS + test -z "$_G_dir" && _G_dir=. + for _G_prog_name in $_G_progs_list; do + for _exeext in '' .EXE; do + _G_path_prog=$_G_dir/$_G_prog_name$_exeext + func_executable_p "$_G_path_prog" || continue + case `"$_G_path_prog" --version 2>&1` in + *GNU*) func_path_progs_result=$_G_path_prog _G_path_prog_found=: ;; + *) $_G_check_func $_G_path_prog + func_path_progs_result=$func_check_prog_result + ;; + esac + $_G_path_prog_found && break 3 + done + done + done + IFS=$_G_save_IFS + test -z "$func_path_progs_result" && { + echo "no acceptable sed could be found in \$PATH" >&2 + exit 1 + } +} + + +# We want to be able to use the functions in this file before configure +# has figured out where the best binaries are kept, which means we have +# to search for them ourselves - except when the results are already set +# where we skip the searches. + +# Unless the user overrides by setting SED, search the path for either GNU +# sed, or the sed that truncates its output the least. +test -z "$SED" && { + _G_sed_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ + for _G_i in 1 2 3 4 5 6 7; do + _G_sed_script=$_G_sed_script$nl$_G_sed_script + done + echo "$_G_sed_script" 2>/dev/null | sed 99q >conftest.sed + _G_sed_script= + + func_check_prog_sed () + { + _G_path_prog=$1 + + _G_count=0 + printf 0123456789 >conftest.in + while : + do + cat conftest.in conftest.in >conftest.tmp + mv conftest.tmp conftest.in + cp conftest.in conftest.nl + echo '' >> conftest.nl + "$_G_path_prog" -f conftest.sed conftest.out 2>/dev/null || break + diff conftest.out conftest.nl >/dev/null 2>&1 || break + _G_count=`expr $_G_count + 1` + if test "$_G_count" -gt "$_G_path_prog_max"; then + # Best one so far, save it but keep looking for a better one + func_check_prog_result=$_G_path_prog + _G_path_prog_max=$_G_count + fi + # 10*(2^10) chars as input seems more than enough + test 10 -lt "$_G_count" && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out + } + + func_path_progs "sed gsed" func_check_prog_sed $PATH:/usr/xpg4/bin + rm -f conftest.sed + SED=$func_path_progs_result +} + + +# Unless the user overrides by setting GREP, search the path for either GNU +# grep, or the grep that truncates its output the least. +test -z "$GREP" && { + func_check_prog_grep () + { + _G_path_prog=$1 + + _G_count=0 + _G_path_prog_max=0 + printf 0123456789 >conftest.in + while : + do + cat conftest.in conftest.in >conftest.tmp + mv conftest.tmp conftest.in + cp conftest.in conftest.nl + echo 'GREP' >> conftest.nl + "$_G_path_prog" -e 'GREP$' -e '-(cannot match)-' conftest.out 2>/dev/null || break + diff conftest.out conftest.nl >/dev/null 2>&1 || break + _G_count=`expr $_G_count + 1` + if test "$_G_count" -gt "$_G_path_prog_max"; then + # Best one so far, save it but keep looking for a better one + func_check_prog_result=$_G_path_prog + _G_path_prog_max=$_G_count + fi + # 10*(2^10) chars as input seems more than enough + test 10 -lt "$_G_count" && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out + } + + func_path_progs "grep ggrep" func_check_prog_grep $PATH:/usr/xpg4/bin + GREP=$func_path_progs_result +} + + +## ------------------------------- ## +## User overridable command paths. ## +## ------------------------------- ## + +# All uppercase variable names are used for environment variables. These +# variables can be overridden by the user before calling a script that +# uses them if a suitable command of that name is not already available +# in the command search PATH. + +: ${CP="cp -f"} +: ${ECHO="printf %s\n"} +: ${EGREP="$GREP -E"} +: ${FGREP="$GREP -F"} +: ${LN_S="ln -s"} +: ${MAKE="make"} +: ${MKDIR="mkdir"} +: ${MV="mv -f"} +: ${RM="rm -f"} +: ${SHELL="${CONFIG_SHELL-/bin/sh}"} + + +## -------------------- ## +## Useful sed snippets. ## +## -------------------- ## + +sed_dirname='s|/[^/]*$||' +sed_basename='s|^.*/||' + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +sed_quote_subst='s|\([`"$\\]\)|\\\1|g' + +# Same as above, but do not quote variable references. +sed_double_quote_subst='s/\(["`\\]\)/\\\1/g' + +# Sed substitution that turns a string into a regex matching for the +# string literally. +sed_make_literal_regex='s|[].[^$\\*\/]|\\&|g' + +# Sed substitution that converts a w32 file name or path +# that contains forward slashes, into one that contains +# (escaped) backslashes. A very naive implementation. +sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g' + +# Re-'\' parameter expansions in output of sed_double_quote_subst that +# were '\'-ed in input to the same. If an odd number of '\' preceded a +# '$' in input to sed_double_quote_subst, that '$' was protected from +# expansion. Since each input '\' is now two '\'s, look for any number +# of runs of four '\'s followed by two '\'s and then a '$'. '\' that '$'. +_G_bs='\\' +_G_bs2='\\\\' +_G_bs4='\\\\\\\\' +_G_dollar='\$' +sed_double_backslash="\ + s/$_G_bs4/&\\ +/g + s/^$_G_bs2$_G_dollar/$_G_bs&/ + s/\\([^$_G_bs]\\)$_G_bs2$_G_dollar/\\1$_G_bs2$_G_bs$_G_dollar/g + s/\n//g" + + +## ----------------- ## +## Global variables. ## +## ----------------- ## + +# Except for the global variables explicitly listed below, the following +# functions in the '^func_' namespace, and the '^require_' namespace +# variables initialised in the 'Resource management' section, sourcing +# this file will not pollute your global namespace with anything +# else. There's no portable way to scope variables in Bourne shell +# though, so actually running these functions will sometimes place +# results into a variable named after the function, and often use +# temporary variables in the '^_G_' namespace. If you are careful to +# avoid using those namespaces casually in your sourcing script, things +# should continue to work as you expect. And, of course, you can freely +# overwrite any of the functions or variables defined here before +# calling anything to customize them. + +EXIT_SUCCESS=0 +EXIT_FAILURE=1 +EXIT_MISMATCH=63 # $? = 63 is used to indicate version mismatch to missing. +EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake. + +# Allow overriding, eg assuming that you follow the convention of +# putting '$debug_cmd' at the start of all your functions, you can get +# bash to show function call trace with: +# +# debug_cmd='echo "${FUNCNAME[0]} $*" >&2' bash your-script-name +debug_cmd=${debug_cmd-":"} +exit_cmd=: + +# By convention, finish your script with: +# +# exit $exit_status +# +# so that you can set exit_status to non-zero if you want to indicate +# something went wrong during execution without actually bailing out at +# the point of failure. +exit_status=$EXIT_SUCCESS + +# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh +# is ksh but when the shell is invoked as "sh" and the current value of +# the _XPG environment variable is not equal to 1 (one), the special +# positional parameter $0, within a function call, is the name of the +# function. +progpath=$0 + +# The name of this program. +progname=`$ECHO "$progpath" |$SED "$sed_basename"` + +# Make sure we have an absolute progpath for reexecution: +case $progpath in + [\\/]*|[A-Za-z]:\\*) ;; + *[\\/]*) + progdir=`$ECHO "$progpath" |$SED "$sed_dirname"` + progdir=`cd "$progdir" && pwd` + progpath=$progdir/$progname + ;; + *) + _G_IFS=$IFS + IFS=${PATH_SEPARATOR-:} + for progdir in $PATH; do + IFS=$_G_IFS + test -x "$progdir/$progname" && break + done + IFS=$_G_IFS + test -n "$progdir" || progdir=`pwd` + progpath=$progdir/$progname + ;; +esac + + +## ----------------- ## +## Standard options. ## +## ----------------- ## + +# The following options affect the operation of the functions defined +# below, and should be set appropriately depending on run-time para- +# meters passed on the command line. + +opt_dry_run=false +opt_quiet=false +opt_verbose=false + +# Categories 'all' and 'none' are always available. Append any others +# you will pass as the first argument to func_warning from your own +# code. +warning_categories= + +# By default, display warnings according to 'opt_warning_types'. Set +# 'warning_func' to ':' to elide all warnings, or func_fatal_error to +# treat the next displayed warning as a fatal error. +warning_func=func_warn_and_continue + +# Set to 'all' to display all warnings, 'none' to suppress all +# warnings, or a space delimited list of some subset of +# 'warning_categories' to display only the listed warnings. +opt_warning_types=all + + +## -------------------- ## +## Resource management. ## +## -------------------- ## + +# This section contains definitions for functions that each ensure a +# particular resource (a file, or a non-empty configuration variable for +# example) is available, and if appropriate to extract default values +# from pertinent package files. Call them using their associated +# 'require_*' variable to ensure that they are executed, at most, once. +# +# It's entirely deliberate that calling these functions can set +# variables that don't obey the namespace limitations obeyed by the rest +# of this file, in order that that they be as useful as possible to +# callers. + + +# require_term_colors +# ------------------- +# Allow display of bold text on terminals that support it. +require_term_colors=func_require_term_colors +func_require_term_colors () +{ + $debug_cmd + + test -t 1 && { + # COLORTERM and USE_ANSI_COLORS environment variables take + # precedence, because most terminfo databases neglect to describe + # whether color sequences are supported. + test -n "${COLORTERM+set}" && : ${USE_ANSI_COLORS="1"} + + if test 1 = "$USE_ANSI_COLORS"; then + # Standard ANSI escape sequences + tc_reset='' + tc_bold=''; tc_standout='' + tc_red=''; tc_green='' + tc_blue=''; tc_cyan='' + else + # Otherwise trust the terminfo database after all. + test -n "`tput sgr0 2>/dev/null`" && { + tc_reset=`tput sgr0` + test -n "`tput bold 2>/dev/null`" && tc_bold=`tput bold` + tc_standout=$tc_bold + test -n "`tput smso 2>/dev/null`" && tc_standout=`tput smso` + test -n "`tput setaf 1 2>/dev/null`" && tc_red=`tput setaf 1` + test -n "`tput setaf 2 2>/dev/null`" && tc_green=`tput setaf 2` + test -n "`tput setaf 4 2>/dev/null`" && tc_blue=`tput setaf 4` + test -n "`tput setaf 5 2>/dev/null`" && tc_cyan=`tput setaf 5` + } + fi + } + + require_term_colors=: +} + + +## ----------------- ## +## Function library. ## +## ----------------- ## + +# This section contains a variety of useful functions to call in your +# scripts. Take note of the portable wrappers for features provided by +# some modern shells, which will fall back to slower equivalents on +# less featureful shells. + + +# func_append VAR VALUE +# --------------------- +# Append VALUE onto the existing contents of VAR. + + # We should try to minimise forks, especially on Windows where they are + # unreasonably slow, so skip the feature probes when bash or zsh are + # being used: + if test set = "${BASH_VERSION+set}${ZSH_VERSION+set}"; then + : ${_G_HAVE_ARITH_OP="yes"} + : ${_G_HAVE_XSI_OPS="yes"} + # The += operator was introduced in bash 3.1 + case $BASH_VERSION in + [12].* | 3.0 | 3.0*) ;; + *) + : ${_G_HAVE_PLUSEQ_OP="yes"} + ;; + esac + fi + + # _G_HAVE_PLUSEQ_OP + # Can be empty, in which case the shell is probed, "yes" if += is + # useable or anything else if it does not work. + test -z "$_G_HAVE_PLUSEQ_OP" \ + && (eval 'x=a; x+=" b"; test "a b" = "$x"') 2>/dev/null \ + && _G_HAVE_PLUSEQ_OP=yes + +if test yes = "$_G_HAVE_PLUSEQ_OP" +then + # This is an XSI compatible shell, allowing a faster implementation... + eval 'func_append () + { + $debug_cmd + + eval "$1+=\$2" + }' +else + # ...otherwise fall back to using expr, which is often a shell builtin. + func_append () + { + $debug_cmd + + eval "$1=\$$1\$2" + } +fi + + +# func_append_quoted VAR VALUE +# ---------------------------- +# Quote VALUE and append to the end of shell variable VAR, separated +# by a space. +if test yes = "$_G_HAVE_PLUSEQ_OP"; then + eval 'func_append_quoted () + { + $debug_cmd + + func_quote_for_eval "$2" + eval "$1+=\\ \$func_quote_for_eval_result" + }' +else + func_append_quoted () + { + $debug_cmd + + func_quote_for_eval "$2" + eval "$1=\$$1\\ \$func_quote_for_eval_result" + } +fi + + +# func_append_uniq VAR VALUE +# -------------------------- +# Append unique VALUE onto the existing contents of VAR, assuming +# entries are delimited by the first character of VALUE. For example: +# +# func_append_uniq options " --another-option option-argument" +# +# will only append to $options if " --another-option option-argument " +# is not already present somewhere in $options already (note spaces at +# each end implied by leading space in second argument). +func_append_uniq () +{ + $debug_cmd + + eval _G_current_value='`$ECHO $'$1'`' + _G_delim=`expr "$2" : '\(.\)'` + + case $_G_delim$_G_current_value$_G_delim in + *"$2$_G_delim"*) ;; + *) func_append "$@" ;; + esac +} + + +# func_arith TERM... +# ------------------ +# Set func_arith_result to the result of evaluating TERMs. + test -z "$_G_HAVE_ARITH_OP" \ + && (eval 'test 2 = $(( 1 + 1 ))') 2>/dev/null \ + && _G_HAVE_ARITH_OP=yes + +if test yes = "$_G_HAVE_ARITH_OP"; then + eval 'func_arith () + { + $debug_cmd + + func_arith_result=$(( $* )) + }' +else + func_arith () + { + $debug_cmd + + func_arith_result=`expr "$@"` + } +fi + + +# func_basename FILE +# ------------------ +# Set func_basename_result to FILE with everything up to and including +# the last / stripped. +if test yes = "$_G_HAVE_XSI_OPS"; then + # If this shell supports suffix pattern removal, then use it to avoid + # forking. Hide the definitions single quotes in case the shell chokes + # on unsupported syntax... + _b='func_basename_result=${1##*/}' + _d='case $1 in + */*) func_dirname_result=${1%/*}$2 ;; + * ) func_dirname_result=$3 ;; + esac' + +else + # ...otherwise fall back to using sed. + _b='func_basename_result=`$ECHO "$1" |$SED "$sed_basename"`' + _d='func_dirname_result=`$ECHO "$1" |$SED "$sed_dirname"` + if test "X$func_dirname_result" = "X$1"; then + func_dirname_result=$3 + else + func_append func_dirname_result "$2" + fi' +fi + +eval 'func_basename () +{ + $debug_cmd + + '"$_b"' +}' + + +# func_dirname FILE APPEND NONDIR_REPLACEMENT +# ------------------------------------------- +# Compute the dirname of FILE. If nonempty, add APPEND to the result, +# otherwise set result to NONDIR_REPLACEMENT. +eval 'func_dirname () +{ + $debug_cmd + + '"$_d"' +}' + + +# func_dirname_and_basename FILE APPEND NONDIR_REPLACEMENT +# -------------------------------------------------------- +# Perform func_basename and func_dirname in a single function +# call: +# dirname: Compute the dirname of FILE. If nonempty, +# add APPEND to the result, otherwise set result +# to NONDIR_REPLACEMENT. +# value returned in "$func_dirname_result" +# basename: Compute filename of FILE. +# value retuned in "$func_basename_result" +# For efficiency, we do not delegate to the functions above but instead +# duplicate the functionality here. +eval 'func_dirname_and_basename () +{ + $debug_cmd + + '"$_b"' + '"$_d"' +}' + + +# func_echo ARG... +# ---------------- +# Echo program name prefixed message. +func_echo () +{ + $debug_cmd + + _G_message=$* + + func_echo_IFS=$IFS + IFS=$nl + for _G_line in $_G_message; do + IFS=$func_echo_IFS + $ECHO "$progname: $_G_line" + done + IFS=$func_echo_IFS +} + + +# func_echo_all ARG... +# -------------------- +# Invoke $ECHO with all args, space-separated. +func_echo_all () +{ + $ECHO "$*" +} + + +# func_echo_infix_1 INFIX ARG... +# ------------------------------ +# Echo program name, followed by INFIX on the first line, with any +# additional lines not showing INFIX. +func_echo_infix_1 () +{ + $debug_cmd + + $require_term_colors + + _G_infix=$1; shift + _G_indent=$_G_infix + _G_prefix="$progname: $_G_infix: " + _G_message=$* + + # Strip color escape sequences before counting printable length + for _G_tc in "$tc_reset" "$tc_bold" "$tc_standout" "$tc_red" "$tc_green" "$tc_blue" "$tc_cyan" + do + test -n "$_G_tc" && { + _G_esc_tc=`$ECHO "$_G_tc" | $SED "$sed_make_literal_regex"` + _G_indent=`$ECHO "$_G_indent" | $SED "s|$_G_esc_tc||g"` + } + done + _G_indent="$progname: "`echo "$_G_indent" | $SED 's|.| |g'`" " ## exclude from sc_prohibit_nested_quotes + + func_echo_infix_1_IFS=$IFS + IFS=$nl + for _G_line in $_G_message; do + IFS=$func_echo_infix_1_IFS + $ECHO "$_G_prefix$tc_bold$_G_line$tc_reset" >&2 + _G_prefix=$_G_indent + done + IFS=$func_echo_infix_1_IFS +} + + +# func_error ARG... +# ----------------- +# Echo program name prefixed message to standard error. +func_error () +{ + $debug_cmd + + $require_term_colors + + func_echo_infix_1 " $tc_standout${tc_red}error$tc_reset" "$*" >&2 +} + + +# func_fatal_error ARG... +# ----------------------- +# Echo program name prefixed message to standard error, and exit. +func_fatal_error () +{ + $debug_cmd + + func_error "$*" + exit $EXIT_FAILURE +} + + +# func_grep EXPRESSION FILENAME +# ----------------------------- +# Check whether EXPRESSION matches any line of FILENAME, without output. +func_grep () +{ + $debug_cmd + + $GREP "$1" "$2" >/dev/null 2>&1 +} + + +# func_len STRING +# --------------- +# Set func_len_result to the length of STRING. STRING may not +# start with a hyphen. + test -z "$_G_HAVE_XSI_OPS" \ + && (eval 'x=a/b/c; + test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \ + && _G_HAVE_XSI_OPS=yes + +if test yes = "$_G_HAVE_XSI_OPS"; then + eval 'func_len () + { + $debug_cmd + + func_len_result=${#1} + }' +else + func_len () + { + $debug_cmd + + func_len_result=`expr "$1" : ".*" 2>/dev/null || echo $max_cmd_len` + } +fi + + +# func_mkdir_p DIRECTORY-PATH +# --------------------------- +# Make sure the entire path to DIRECTORY-PATH is available. +func_mkdir_p () +{ + $debug_cmd + + _G_directory_path=$1 + _G_dir_list= + + if test -n "$_G_directory_path" && test : != "$opt_dry_run"; then + + # Protect directory names starting with '-' + case $_G_directory_path in + -*) _G_directory_path=./$_G_directory_path ;; + esac + + # While some portion of DIR does not yet exist... + while test ! -d "$_G_directory_path"; do + # ...make a list in topmost first order. Use a colon delimited + # list incase some portion of path contains whitespace. + _G_dir_list=$_G_directory_path:$_G_dir_list + + # If the last portion added has no slash in it, the list is done + case $_G_directory_path in */*) ;; *) break ;; esac + + # ...otherwise throw away the child directory and loop + _G_directory_path=`$ECHO "$_G_directory_path" | $SED -e "$sed_dirname"` + done + _G_dir_list=`$ECHO "$_G_dir_list" | $SED 's|:*$||'` + + func_mkdir_p_IFS=$IFS; IFS=: + for _G_dir in $_G_dir_list; do + IFS=$func_mkdir_p_IFS + # mkdir can fail with a 'File exist' error if two processes + # try to create one of the directories concurrently. Don't + # stop in that case! + $MKDIR "$_G_dir" 2>/dev/null || : + done + IFS=$func_mkdir_p_IFS + + # Bail out if we (or some other process) failed to create a directory. + test -d "$_G_directory_path" || \ + func_fatal_error "Failed to create '$1'" + fi +} + + +# func_mktempdir [BASENAME] +# ------------------------- +# Make a temporary directory that won't clash with other running +# libtool processes, and avoids race conditions if possible. If +# given, BASENAME is the basename for that directory. +func_mktempdir () +{ + $debug_cmd + + _G_template=${TMPDIR-/tmp}/${1-$progname} + + if test : = "$opt_dry_run"; then + # Return a directory name, but don't create it in dry-run mode + _G_tmpdir=$_G_template-$$ + else + + # If mktemp works, use that first and foremost + _G_tmpdir=`mktemp -d "$_G_template-XXXXXXXX" 2>/dev/null` + + if test ! -d "$_G_tmpdir"; then + # Failing that, at least try and use $RANDOM to avoid a race + _G_tmpdir=$_G_template-${RANDOM-0}$$ + + func_mktempdir_umask=`umask` + umask 0077 + $MKDIR "$_G_tmpdir" + umask $func_mktempdir_umask + fi + + # If we're not in dry-run mode, bomb out on failure + test -d "$_G_tmpdir" || \ + func_fatal_error "cannot create temporary directory '$_G_tmpdir'" + fi + + $ECHO "$_G_tmpdir" +} + + +# func_normal_abspath PATH +# ------------------------ +# Remove doubled-up and trailing slashes, "." path components, +# and cancel out any ".." path components in PATH after making +# it an absolute path. +func_normal_abspath () +{ + $debug_cmd + + # These SED scripts presuppose an absolute path with a trailing slash. + _G_pathcar='s|^/\([^/]*\).*$|\1|' + _G_pathcdr='s|^/[^/]*||' + _G_removedotparts=':dotsl + s|/\./|/|g + t dotsl + s|/\.$|/|' + _G_collapseslashes='s|/\{1,\}|/|g' + _G_finalslash='s|/*$|/|' + + # Start from root dir and reassemble the path. + func_normal_abspath_result= + func_normal_abspath_tpath=$1 + func_normal_abspath_altnamespace= + case $func_normal_abspath_tpath in + "") + # Empty path, that just means $cwd. + func_stripname '' '/' "`pwd`" + func_normal_abspath_result=$func_stripname_result + return + ;; + # The next three entries are used to spot a run of precisely + # two leading slashes without using negated character classes; + # we take advantage of case's first-match behaviour. + ///*) + # Unusual form of absolute path, do nothing. + ;; + //*) + # Not necessarily an ordinary path; POSIX reserves leading '//' + # and for example Cygwin uses it to access remote file shares + # over CIFS/SMB, so we conserve a leading double slash if found. + func_normal_abspath_altnamespace=/ + ;; + /*) + # Absolute path, do nothing. + ;; + *) + # Relative path, prepend $cwd. + func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath + ;; + esac + + # Cancel out all the simple stuff to save iterations. We also want + # the path to end with a slash for ease of parsing, so make sure + # there is one (and only one) here. + func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ + -e "$_G_removedotparts" -e "$_G_collapseslashes" -e "$_G_finalslash"` + while :; do + # Processed it all yet? + if test / = "$func_normal_abspath_tpath"; then + # If we ascended to the root using ".." the result may be empty now. + if test -z "$func_normal_abspath_result"; then + func_normal_abspath_result=/ + fi + break + fi + func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \ + -e "$_G_pathcar"` + func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ + -e "$_G_pathcdr"` + # Figure out what to do with it + case $func_normal_abspath_tcomponent in + "") + # Trailing empty path component, ignore it. + ;; + ..) + # Parent dir; strip last assembled component from result. + func_dirname "$func_normal_abspath_result" + func_normal_abspath_result=$func_dirname_result + ;; + *) + # Actual path component, append it. + func_append func_normal_abspath_result "/$func_normal_abspath_tcomponent" + ;; + esac + done + # Restore leading double-slash if one was found on entry. + func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result +} + + +# func_notquiet ARG... +# -------------------- +# Echo program name prefixed message only when not in quiet mode. +func_notquiet () +{ + $debug_cmd + + $opt_quiet || func_echo ${1+"$@"} + + # A bug in bash halts the script if the last line of a function + # fails when set -e is in force, so we need another command to + # work around that: + : +} + + +# func_relative_path SRCDIR DSTDIR +# -------------------------------- +# Set func_relative_path_result to the relative path from SRCDIR to DSTDIR. +func_relative_path () +{ + $debug_cmd + + func_relative_path_result= + func_normal_abspath "$1" + func_relative_path_tlibdir=$func_normal_abspath_result + func_normal_abspath "$2" + func_relative_path_tbindir=$func_normal_abspath_result + + # Ascend the tree starting from libdir + while :; do + # check if we have found a prefix of bindir + case $func_relative_path_tbindir in + $func_relative_path_tlibdir) + # found an exact match + func_relative_path_tcancelled= + break + ;; + $func_relative_path_tlibdir*) + # found a matching prefix + func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir" + func_relative_path_tcancelled=$func_stripname_result + if test -z "$func_relative_path_result"; then + func_relative_path_result=. + fi + break + ;; + *) + func_dirname $func_relative_path_tlibdir + func_relative_path_tlibdir=$func_dirname_result + if test -z "$func_relative_path_tlibdir"; then + # Have to descend all the way to the root! + func_relative_path_result=../$func_relative_path_result + func_relative_path_tcancelled=$func_relative_path_tbindir + break + fi + func_relative_path_result=../$func_relative_path_result + ;; + esac + done + + # Now calculate path; take care to avoid doubling-up slashes. + func_stripname '' '/' "$func_relative_path_result" + func_relative_path_result=$func_stripname_result + func_stripname '/' '/' "$func_relative_path_tcancelled" + if test -n "$func_stripname_result"; then + func_append func_relative_path_result "/$func_stripname_result" + fi + + # Normalisation. If bindir is libdir, return '.' else relative path. + if test -n "$func_relative_path_result"; then + func_stripname './' '' "$func_relative_path_result" + func_relative_path_result=$func_stripname_result + fi + + test -n "$func_relative_path_result" || func_relative_path_result=. + + : +} + + +# func_quote_for_eval ARG... +# -------------------------- +# Aesthetically quote ARGs to be evaled later. +# This function returns two values: +# i) func_quote_for_eval_result +# double-quoted, suitable for a subsequent eval +# ii) func_quote_for_eval_unquoted_result +# has all characters that are still active within double +# quotes backslashified. +func_quote_for_eval () +{ + $debug_cmd + + func_quote_for_eval_unquoted_result= + func_quote_for_eval_result= + while test 0 -lt $#; do + case $1 in + *[\\\`\"\$]*) + _G_unquoted_arg=`printf '%s\n' "$1" |$SED "$sed_quote_subst"` ;; + *) + _G_unquoted_arg=$1 ;; + esac + if test -n "$func_quote_for_eval_unquoted_result"; then + func_append func_quote_for_eval_unquoted_result " $_G_unquoted_arg" + else + func_append func_quote_for_eval_unquoted_result "$_G_unquoted_arg" + fi + + case $_G_unquoted_arg in + # Double-quote args containing shell metacharacters to delay + # word splitting, command substitution and variable expansion + # for a subsequent eval. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + _G_quoted_arg=\"$_G_unquoted_arg\" + ;; + *) + _G_quoted_arg=$_G_unquoted_arg + ;; + esac + + if test -n "$func_quote_for_eval_result"; then + func_append func_quote_for_eval_result " $_G_quoted_arg" + else + func_append func_quote_for_eval_result "$_G_quoted_arg" + fi + shift + done +} + + +# func_quote_for_expand ARG +# ------------------------- +# Aesthetically quote ARG to be evaled later; same as above, +# but do not quote variable references. +func_quote_for_expand () +{ + $debug_cmd + + case $1 in + *[\\\`\"]*) + _G_arg=`$ECHO "$1" | $SED \ + -e "$sed_double_quote_subst" -e "$sed_double_backslash"` ;; + *) + _G_arg=$1 ;; + esac + + case $_G_arg in + # Double-quote args containing shell metacharacters to delay + # word splitting and command substitution for a subsequent eval. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + _G_arg=\"$_G_arg\" + ;; + esac + + func_quote_for_expand_result=$_G_arg +} + + +# func_stripname PREFIX SUFFIX NAME +# --------------------------------- +# strip PREFIX and SUFFIX from NAME, and store in func_stripname_result. +# PREFIX and SUFFIX must not contain globbing or regex special +# characters, hashes, percent signs, but SUFFIX may contain a leading +# dot (in which case that matches only a dot). +if test yes = "$_G_HAVE_XSI_OPS"; then + eval 'func_stripname () + { + $debug_cmd + + # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are + # positional parameters, so assign one to ordinary variable first. + func_stripname_result=$3 + func_stripname_result=${func_stripname_result#"$1"} + func_stripname_result=${func_stripname_result%"$2"} + }' +else + func_stripname () + { + $debug_cmd + + case $2 in + .*) func_stripname_result=`$ECHO "$3" | $SED -e "s%^$1%%" -e "s%\\\\$2\$%%"`;; + *) func_stripname_result=`$ECHO "$3" | $SED -e "s%^$1%%" -e "s%$2\$%%"`;; + esac + } +fi + + +# func_show_eval CMD [FAIL_EXP] +# ----------------------------- +# Unless opt_quiet is true, then output CMD. Then, if opt_dryrun is +# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP +# is given, then evaluate it. +func_show_eval () +{ + $debug_cmd + + _G_cmd=$1 + _G_fail_exp=${2-':'} + + func_quote_for_expand "$_G_cmd" + eval "func_notquiet $func_quote_for_expand_result" + + $opt_dry_run || { + eval "$_G_cmd" + _G_status=$? + if test 0 -ne "$_G_status"; then + eval "(exit $_G_status); $_G_fail_exp" + fi + } +} + + +# func_show_eval_locale CMD [FAIL_EXP] +# ------------------------------------ +# Unless opt_quiet is true, then output CMD. Then, if opt_dryrun is +# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP +# is given, then evaluate it. Use the saved locale for evaluation. +func_show_eval_locale () +{ + $debug_cmd + + _G_cmd=$1 + _G_fail_exp=${2-':'} + + $opt_quiet || { + func_quote_for_expand "$_G_cmd" + eval "func_echo $func_quote_for_expand_result" + } + + $opt_dry_run || { + eval "$_G_user_locale + $_G_cmd" + _G_status=$? + eval "$_G_safe_locale" + if test 0 -ne "$_G_status"; then + eval "(exit $_G_status); $_G_fail_exp" + fi + } +} + + +# func_tr_sh +# ---------- +# Turn $1 into a string suitable for a shell variable name. +# Result is stored in $func_tr_sh_result. All characters +# not in the set a-zA-Z0-9_ are replaced with '_'. Further, +# if $1 begins with a digit, a '_' is prepended as well. +func_tr_sh () +{ + $debug_cmd + + case $1 in + [0-9]* | *[!a-zA-Z0-9_]*) + func_tr_sh_result=`$ECHO "$1" | $SED -e 's/^\([0-9]\)/_\1/' -e 's/[^a-zA-Z0-9_]/_/g'` + ;; + * ) + func_tr_sh_result=$1 + ;; + esac +} + + +# func_verbose ARG... +# ------------------- +# Echo program name prefixed message in verbose mode only. +func_verbose () +{ + $debug_cmd + + $opt_verbose && func_echo "$*" + + : +} + + +# func_warn_and_continue ARG... +# ----------------------------- +# Echo program name prefixed warning message to standard error. +func_warn_and_continue () +{ + $debug_cmd + + $require_term_colors + + func_echo_infix_1 "${tc_red}warning$tc_reset" "$*" >&2 +} + + +# func_warning CATEGORY ARG... +# ---------------------------- +# Echo program name prefixed warning message to standard error. Warning +# messages can be filtered according to CATEGORY, where this function +# elides messages where CATEGORY is not listed in the global variable +# 'opt_warning_types'. +func_warning () +{ + $debug_cmd + + # CATEGORY must be in the warning_categories list! + case " $warning_categories " in + *" $1 "*) ;; + *) func_internal_error "invalid warning category '$1'" ;; + esac + + _G_category=$1 + shift + + case " $opt_warning_types " in + *" $_G_category "*) $warning_func ${1+"$@"} ;; + esac +} + + +# func_sort_ver VER1 VER2 +# ----------------------- +# 'sort -V' is not generally available. +# Note this deviates from the version comparison in automake +# in that it treats 1.5 < 1.5.0, and treats 1.4.4a < 1.4-p3a +# but this should suffice as we won't be specifying old +# version formats or redundant trailing .0 in bootstrap.conf. +# If we did want full compatibility then we should probably +# use m4_version_compare from autoconf. +func_sort_ver () +{ + $debug_cmd + + printf '%s\n%s\n' "$1" "$2" \ + | sort -t. -k 1,1n -k 2,2n -k 3,3n -k 4,4n -k 5,5n -k 6,6n -k 7,7n -k 8,8n -k 9,9n +} + +# func_lt_ver PREV CURR +# --------------------- +# Return true if PREV and CURR are in the correct order according to +# func_sort_ver, otherwise false. Use it like this: +# +# func_lt_ver "$prev_ver" "$proposed_ver" || func_fatal_error "..." +func_lt_ver () +{ + $debug_cmd + + test "x$1" = x`func_sort_ver "$1" "$2" | $SED 1q` +} + + +# Local variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'before-save-hook 'time-stamp) +# time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC" +# time-stamp-time-zone: "UTC" +# End: +#! /bin/sh + +# Set a version string for this script. +scriptversion=2015-10-07.11; # UTC + +# A portable, pluggable option parser for Bourne shell. +# Written by Gary V. Vaughan, 2010 + +# Copyright (C) 2010-2015 Free Software Foundation, Inc. +# This is free software; see the source for copying conditions. There is NO +# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# Please report bugs or propose patches to gary@gnu.org. + + +## ------ ## +## Usage. ## +## ------ ## + +# This file is a library for parsing options in your shell scripts along +# with assorted other useful supporting features that you can make use +# of too. +# +# For the simplest scripts you might need only: +# +# #!/bin/sh +# . relative/path/to/funclib.sh +# . relative/path/to/options-parser +# scriptversion=1.0 +# func_options ${1+"$@"} +# eval set dummy "$func_options_result"; shift +# ...rest of your script... +# +# In order for the '--version' option to work, you will need to have a +# suitably formatted comment like the one at the top of this file +# starting with '# Written by ' and ending with '# warranty; '. +# +# For '-h' and '--help' to work, you will also need a one line +# description of your script's purpose in a comment directly above the +# '# Written by ' line, like the one at the top of this file. +# +# The default options also support '--debug', which will turn on shell +# execution tracing (see the comment above debug_cmd below for another +# use), and '--verbose' and the func_verbose function to allow your script +# to display verbose messages only when your user has specified +# '--verbose'. +# +# After sourcing this file, you can plug processing for additional +# options by amending the variables from the 'Configuration' section +# below, and following the instructions in the 'Option parsing' +# section further down. + +## -------------- ## +## Configuration. ## +## -------------- ## + +# You should override these variables in your script after sourcing this +# file so that they reflect the customisations you have added to the +# option parser. + +# The usage line for option parsing errors and the start of '-h' and +# '--help' output messages. You can embed shell variables for delayed +# expansion at the time the message is displayed, but you will need to +# quote other shell meta-characters carefully to prevent them being +# expanded when the contents are evaled. +usage='$progpath [OPTION]...' + +# Short help message in response to '-h' and '--help'. Add to this or +# override it after sourcing this library to reflect the full set of +# options your script accepts. +usage_message="\ + --debug enable verbose shell tracing + -W, --warnings=CATEGORY + report the warnings falling in CATEGORY [all] + -v, --verbose verbosely report processing + --version print version information and exit + -h, --help print short or long help message and exit +" + +# Additional text appended to 'usage_message' in response to '--help'. +long_help_message=" +Warning categories include: + 'all' show all warnings + 'none' turn off all the warnings + 'error' warnings are treated as fatal errors" + +# Help message printed before fatal option parsing errors. +fatal_help="Try '\$progname --help' for more information." + + + +## ------------------------- ## +## Hook function management. ## +## ------------------------- ## + +# This section contains functions for adding, removing, and running hooks +# to the main code. A hook is just a named list of of function, that can +# be run in order later on. + +# func_hookable FUNC_NAME +# ----------------------- +# Declare that FUNC_NAME will run hooks added with +# 'func_add_hook FUNC_NAME ...'. +func_hookable () +{ + $debug_cmd + + func_append hookable_fns " $1" +} + + +# func_add_hook FUNC_NAME HOOK_FUNC +# --------------------------------- +# Request that FUNC_NAME call HOOK_FUNC before it returns. FUNC_NAME must +# first have been declared "hookable" by a call to 'func_hookable'. +func_add_hook () +{ + $debug_cmd + + case " $hookable_fns " in + *" $1 "*) ;; + *) func_fatal_error "'$1' does not accept hook functions." ;; + esac + + eval func_append ${1}_hooks '" $2"' +} + + +# func_remove_hook FUNC_NAME HOOK_FUNC +# ------------------------------------ +# Remove HOOK_FUNC from the list of functions called by FUNC_NAME. +func_remove_hook () +{ + $debug_cmd + + eval ${1}_hooks='`$ECHO "\$'$1'_hooks" |$SED "s| '$2'||"`' +} + + +# func_run_hooks FUNC_NAME [ARG]... +# --------------------------------- +# Run all hook functions registered to FUNC_NAME. +# It is assumed that the list of hook functions contains nothing more +# than a whitespace-delimited list of legal shell function names, and +# no effort is wasted trying to catch shell meta-characters or preserve +# whitespace. +func_run_hooks () +{ + $debug_cmd + + _G_rc_run_hooks=false + + case " $hookable_fns " in + *" $1 "*) ;; + *) func_fatal_error "'$1' does not support hook funcions.n" ;; + esac + + eval _G_hook_fns=\$$1_hooks; shift + + for _G_hook in $_G_hook_fns; do + if eval $_G_hook '"$@"'; then + # store returned options list back into positional + # parameters for next 'cmd' execution. + eval _G_hook_result=\$${_G_hook}_result + eval set dummy "$_G_hook_result"; shift + _G_rc_run_hooks=: + fi + done + + $_G_rc_run_hooks && func_run_hooks_result=$_G_hook_result +} + + + +## --------------- ## +## Option parsing. ## +## --------------- ## + +# In order to add your own option parsing hooks, you must accept the +# full positional parameter list in your hook function, you may remove/edit +# any options that you action, and then pass back the remaining unprocessed +# options in '_result', escaped suitably for +# 'eval'. In this case you also must return $EXIT_SUCCESS to let the +# hook's caller know that it should pay attention to +# '_result'. Returning $EXIT_FAILURE signalizes that +# arguments are left untouched by the hook and therefore caller will ignore the +# result variable. +# +# Like this: +# +# my_options_prep () +# { +# $debug_cmd +# +# # Extend the existing usage message. +# usage_message=$usage_message' +# -s, --silent don'\''t print informational messages +# ' +# # No change in '$@' (ignored completely by this hook). There is +# # no need to do the equivalent (but slower) action: +# # func_quote_for_eval ${1+"$@"} +# # my_options_prep_result=$func_quote_for_eval_result +# false +# } +# func_add_hook func_options_prep my_options_prep +# +# +# my_silent_option () +# { +# $debug_cmd +# +# args_changed=false +# +# # Note that for efficiency, we parse as many options as we can +# # recognise in a loop before passing the remainder back to the +# # caller on the first unrecognised argument we encounter. +# while test $# -gt 0; do +# opt=$1; shift +# case $opt in +# --silent|-s) opt_silent=: +# args_changed=: +# ;; +# # Separate non-argument short options: +# -s*) func_split_short_opt "$_G_opt" +# set dummy "$func_split_short_opt_name" \ +# "-$func_split_short_opt_arg" ${1+"$@"} +# shift +# args_changed=: +# ;; +# *) # Make sure the first unrecognised option "$_G_opt" +# # is added back to "$@", we could need that later +# # if $args_changed is true. +# set dummy "$_G_opt" ${1+"$@"}; shift; break ;; +# esac +# done +# +# if $args_changed; then +# func_quote_for_eval ${1+"$@"} +# my_silent_option_result=$func_quote_for_eval_result +# fi +# +# $args_changed +# } +# func_add_hook func_parse_options my_silent_option +# +# +# my_option_validation () +# { +# $debug_cmd +# +# $opt_silent && $opt_verbose && func_fatal_help "\ +# '--silent' and '--verbose' options are mutually exclusive." +# +# false +# } +# func_add_hook func_validate_options my_option_validation +# +# You'll also need to manually amend $usage_message to reflect the extra +# options you parse. It's preferable to append if you can, so that +# multiple option parsing hooks can be added safely. + + +# func_options_finish [ARG]... +# ---------------------------- +# Finishing the option parse loop (call 'func_options' hooks ATM). +func_options_finish () +{ + $debug_cmd + + _G_func_options_finish_exit=false + if func_run_hooks func_options ${1+"$@"}; then + func_options_finish_result=$func_run_hooks_result + _G_func_options_finish_exit=: + fi + + $_G_func_options_finish_exit +} + + +# func_options [ARG]... +# --------------------- +# All the functions called inside func_options are hookable. See the +# individual implementations for details. +func_hookable func_options +func_options () +{ + $debug_cmd + + _G_rc_options=false + + for my_func in options_prep parse_options validate_options options_finish + do + if eval func_$my_func '${1+"$@"}'; then + eval _G_res_var='$'"func_${my_func}_result" + eval set dummy "$_G_res_var" ; shift + _G_rc_options=: + fi + done + + # Save modified positional parameters for caller. As a top-level + # options-parser function we always need to set the 'func_options_result' + # variable (regardless the $_G_rc_options value). + if $_G_rc_options; then + func_options_result=$_G_res_var + else + func_quote_for_eval ${1+"$@"} + func_options_result=$func_quote_for_eval_result + fi + + $_G_rc_options +} + + +# func_options_prep [ARG]... +# -------------------------- +# All initialisations required before starting the option parse loop. +# Note that when calling hook functions, we pass through the list of +# positional parameters. If a hook function modifies that list, and +# needs to propagate that back to rest of this script, then the complete +# modified list must be put in 'func_run_hooks_result' before +# returning $EXIT_SUCCESS (otherwise $EXIT_FAILURE is returned). +func_hookable func_options_prep +func_options_prep () +{ + $debug_cmd + + # Option defaults: + opt_verbose=false + opt_warning_types= + + _G_rc_options_prep=false + if func_run_hooks func_options_prep ${1+"$@"}; then + _G_rc_options_prep=: + # save modified positional parameters for caller + func_options_prep_result=$func_run_hooks_result + fi + + $_G_rc_options_prep +} + + +# func_parse_options [ARG]... +# --------------------------- +# The main option parsing loop. +func_hookable func_parse_options +func_parse_options () +{ + $debug_cmd + + func_parse_options_result= + + _G_rc_parse_options=false + # this just eases exit handling + while test $# -gt 0; do + # Defer to hook functions for initial option parsing, so they + # get priority in the event of reusing an option name. + if func_run_hooks func_parse_options ${1+"$@"}; then + eval set dummy "$func_run_hooks_result"; shift + _G_rc_parse_options=: + fi + + # Break out of the loop if we already parsed every option. + test $# -gt 0 || break + + _G_match_parse_options=: + _G_opt=$1 + shift + case $_G_opt in + --debug|-x) debug_cmd='set -x' + func_echo "enabling shell trace mode" + $debug_cmd + ;; + + --no-warnings|--no-warning|--no-warn) + set dummy --warnings none ${1+"$@"} + shift + ;; + + --warnings|--warning|-W) + if test $# = 0 && func_missing_arg $_G_opt; then + _G_rc_parse_options=: + break + fi + case " $warning_categories $1" in + *" $1 "*) + # trailing space prevents matching last $1 above + func_append_uniq opt_warning_types " $1" + ;; + *all) + opt_warning_types=$warning_categories + ;; + *none) + opt_warning_types=none + warning_func=: + ;; + *error) + opt_warning_types=$warning_categories + warning_func=func_fatal_error + ;; + *) + func_fatal_error \ + "unsupported warning category: '$1'" + ;; + esac + shift + ;; + + --verbose|-v) opt_verbose=: ;; + --version) func_version ;; + -\?|-h) func_usage ;; + --help) func_help ;; + + # Separate optargs to long options (plugins may need this): + --*=*) func_split_equals "$_G_opt" + set dummy "$func_split_equals_lhs" \ + "$func_split_equals_rhs" ${1+"$@"} + shift + ;; + + # Separate optargs to short options: + -W*) + func_split_short_opt "$_G_opt" + set dummy "$func_split_short_opt_name" \ + "$func_split_short_opt_arg" ${1+"$@"} + shift + ;; + + # Separate non-argument short options: + -\?*|-h*|-v*|-x*) + func_split_short_opt "$_G_opt" + set dummy "$func_split_short_opt_name" \ + "-$func_split_short_opt_arg" ${1+"$@"} + shift + ;; + + --) _G_rc_parse_options=: ; break ;; + -*) func_fatal_help "unrecognised option: '$_G_opt'" ;; + *) set dummy "$_G_opt" ${1+"$@"}; shift + _G_match_parse_options=false + break + ;; + esac + + $_G_match_parse_options && _G_rc_parse_options=: + done + + + if $_G_rc_parse_options; then + # save modified positional parameters for caller + func_quote_for_eval ${1+"$@"} + func_parse_options_result=$func_quote_for_eval_result + fi + + $_G_rc_parse_options +} + + +# func_validate_options [ARG]... +# ------------------------------ +# Perform any sanity checks on option settings and/or unconsumed +# arguments. +func_hookable func_validate_options +func_validate_options () +{ + $debug_cmd + + _G_rc_validate_options=false + + # Display all warnings if -W was not given. + test -n "$opt_warning_types" || opt_warning_types=" $warning_categories" + + if func_run_hooks func_validate_options ${1+"$@"}; then + # save modified positional parameters for caller + func_validate_options_result=$func_run_hooks_result + _G_rc_validate_options=: + fi + + # Bail if the options were screwed! + $exit_cmd $EXIT_FAILURE + + $_G_rc_validate_options +} + + + +## ----------------- ## +## Helper functions. ## +## ----------------- ## + +# This section contains the helper functions used by the rest of the +# hookable option parser framework in ascii-betical order. + + +# func_fatal_help ARG... +# ---------------------- +# Echo program name prefixed message to standard error, followed by +# a help hint, and exit. +func_fatal_help () +{ + $debug_cmd + + eval \$ECHO \""Usage: $usage"\" + eval \$ECHO \""$fatal_help"\" + func_error ${1+"$@"} + exit $EXIT_FAILURE +} + + +# func_help +# --------- +# Echo long help message to standard output and exit. +func_help () +{ + $debug_cmd + + func_usage_message + $ECHO "$long_help_message" + exit 0 +} + + +# func_missing_arg ARGNAME +# ------------------------ +# Echo program name prefixed message to standard error and set global +# exit_cmd. +func_missing_arg () +{ + $debug_cmd + + func_error "Missing argument for '$1'." + exit_cmd=exit +} + + +# func_split_equals STRING +# ------------------------ +# Set func_split_equals_lhs and func_split_equals_rhs shell variables after +# splitting STRING at the '=' sign. +test -z "$_G_HAVE_XSI_OPS" \ + && (eval 'x=a/b/c; + test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \ + && _G_HAVE_XSI_OPS=yes + +if test yes = "$_G_HAVE_XSI_OPS" +then + # This is an XSI compatible shell, allowing a faster implementation... + eval 'func_split_equals () + { + $debug_cmd + + func_split_equals_lhs=${1%%=*} + func_split_equals_rhs=${1#*=} + test "x$func_split_equals_lhs" = "x$1" \ + && func_split_equals_rhs= + }' +else + # ...otherwise fall back to using expr, which is often a shell builtin. + func_split_equals () + { + $debug_cmd + + func_split_equals_lhs=`expr "x$1" : 'x\([^=]*\)'` + func_split_equals_rhs= + test "x$func_split_equals_lhs" = "x$1" \ + || func_split_equals_rhs=`expr "x$1" : 'x[^=]*=\(.*\)$'` + } +fi #func_split_equals + + +# func_split_short_opt SHORTOPT +# ----------------------------- +# Set func_split_short_opt_name and func_split_short_opt_arg shell +# variables after splitting SHORTOPT after the 2nd character. +if test yes = "$_G_HAVE_XSI_OPS" +then + # This is an XSI compatible shell, allowing a faster implementation... + eval 'func_split_short_opt () + { + $debug_cmd + + func_split_short_opt_arg=${1#??} + func_split_short_opt_name=${1%"$func_split_short_opt_arg"} + }' +else + # ...otherwise fall back to using expr, which is often a shell builtin. + func_split_short_opt () + { + $debug_cmd + + func_split_short_opt_name=`expr "x$1" : 'x-\(.\)'` + func_split_short_opt_arg=`expr "x$1" : 'x-.\(.*\)$'` + } +fi #func_split_short_opt + + +# func_usage +# ---------- +# Echo short help message to standard output and exit. +func_usage () +{ + $debug_cmd + + func_usage_message + $ECHO "Run '$progname --help |${PAGER-more}' for full usage" + exit 0 +} + + +# func_usage_message +# ------------------ +# Echo short help message to standard output. +func_usage_message () +{ + $debug_cmd + + eval \$ECHO \""Usage: $usage"\" + echo + $SED -n 's|^# || + /^Written by/{ + x;p;x + } + h + /^Written by/q' < "$progpath" + echo + eval \$ECHO \""$usage_message"\" +} + + +# func_version +# ------------ +# Echo version message to standard output and exit. +func_version () +{ + $debug_cmd + + printf '%s\n' "$progname $scriptversion" + $SED -n ' + /(C)/!b go + :more + /\./!{ + N + s|\n# | | + b more + } + :go + /^# Written by /,/# warranty; / { + s|^# || + s|^# *$|| + s|\((C)\)[ 0-9,-]*[ ,-]\([1-9][0-9]* \)|\1 \2| + p + } + /^# Written by / { + s|^# || + p + } + /^warranty; /q' < "$progpath" + + exit $? +} + + +# Local variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'before-save-hook 'time-stamp) +# time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC" +# time-stamp-time-zone: "UTC" +# End: + +# Set a version string. +scriptversion='(GNU libtool) 2.4.6' + + +# func_echo ARG... +# ---------------- +# Libtool also displays the current mode in messages, so override +# funclib.sh func_echo with this custom definition. +func_echo () +{ + $debug_cmd + + _G_message=$* + + func_echo_IFS=$IFS + IFS=$nl + for _G_line in $_G_message; do + IFS=$func_echo_IFS + $ECHO "$progname${opt_mode+: $opt_mode}: $_G_line" + done + IFS=$func_echo_IFS +} + + +# func_warning ARG... +# ------------------- +# Libtool warnings are not categorized, so override funclib.sh +# func_warning with this simpler definition. +func_warning () +{ + $debug_cmd + + $warning_func ${1+"$@"} +} + + +## ---------------- ## +## Options parsing. ## +## ---------------- ## + +# Hook in the functions to make sure our own options are parsed during +# the option parsing loop. + +usage='$progpath [OPTION]... [MODE-ARG]...' + +# Short help message in response to '-h'. +usage_message="Options: + --config show all configuration variables + --debug enable verbose shell tracing + -n, --dry-run display commands without modifying any files + --features display basic configuration information and exit + --mode=MODE use operation mode MODE + --no-warnings equivalent to '-Wnone' + --preserve-dup-deps don't remove duplicate dependency libraries + --quiet, --silent don't print informational messages + --tag=TAG use configuration variables from tag TAG + -v, --verbose print more informational messages than default + --version print version information + -W, --warnings=CATEGORY report the warnings falling in CATEGORY [all] + -h, --help, --help-all print short, long, or detailed help message +" + +# Additional text appended to 'usage_message' in response to '--help'. +func_help () +{ + $debug_cmd + + func_usage_message + $ECHO "$long_help_message + +MODE must be one of the following: + + clean remove files from the build directory + compile compile a source file into a libtool object + execute automatically set library path, then run a program + finish complete the installation of libtool libraries + install install libraries or executables + link create a library or an executable + uninstall remove libraries from an installed directory + +MODE-ARGS vary depending on the MODE. When passed as first option, +'--mode=MODE' may be abbreviated as 'MODE' or a unique abbreviation of that. +Try '$progname --help --mode=MODE' for a more detailed description of MODE. + +When reporting a bug, please describe a test case to reproduce it and +include the following information: + + host-triplet: $host + shell: $SHELL + compiler: $LTCC + compiler flags: $LTCFLAGS + linker: $LD (gnu? $with_gnu_ld) + version: $progname $scriptversion Debian-2.4.6-15build2 + automake: `($AUTOMAKE --version) 2>/dev/null |$SED 1q` + autoconf: `($AUTOCONF --version) 2>/dev/null |$SED 1q` + +Report bugs to . +GNU libtool home page: . +General help using GNU software: ." + exit 0 +} + + +# func_lo2o OBJECT-NAME +# --------------------- +# Transform OBJECT-NAME from a '.lo' suffix to the platform specific +# object suffix. + +lo2o=s/\\.lo\$/.$objext/ +o2lo=s/\\.$objext\$/.lo/ + +if test yes = "$_G_HAVE_XSI_OPS"; then + eval 'func_lo2o () + { + case $1 in + *.lo) func_lo2o_result=${1%.lo}.$objext ;; + * ) func_lo2o_result=$1 ;; + esac + }' + + # func_xform LIBOBJ-OR-SOURCE + # --------------------------- + # Transform LIBOBJ-OR-SOURCE from a '.o' or '.c' (or otherwise) + # suffix to a '.lo' libtool-object suffix. + eval 'func_xform () + { + func_xform_result=${1%.*}.lo + }' +else + # ...otherwise fall back to using sed. + func_lo2o () + { + func_lo2o_result=`$ECHO "$1" | $SED "$lo2o"` + } + + func_xform () + { + func_xform_result=`$ECHO "$1" | $SED 's|\.[^.]*$|.lo|'` + } +fi + + +# func_fatal_configuration ARG... +# ------------------------------- +# Echo program name prefixed message to standard error, followed by +# a configuration failure hint, and exit. +func_fatal_configuration () +{ + func__fatal_error ${1+"$@"} \ + "See the $PACKAGE documentation for more information." \ + "Fatal configuration error." +} + + +# func_config +# ----------- +# Display the configuration for all the tags in this script. +func_config () +{ + re_begincf='^# ### BEGIN LIBTOOL' + re_endcf='^# ### END LIBTOOL' + + # Default configuration. + $SED "1,/$re_begincf CONFIG/d;/$re_endcf CONFIG/,\$d" < "$progpath" + + # Now print the configurations for the tags. + for tagname in $taglist; do + $SED -n "/$re_begincf TAG CONFIG: $tagname\$/,/$re_endcf TAG CONFIG: $tagname\$/p" < "$progpath" + done + + exit $? +} + + +# func_features +# ------------- +# Display the features supported by this script. +func_features () +{ + echo "host: $host" + if test yes = "$build_libtool_libs"; then + echo "enable shared libraries" + else + echo "disable shared libraries" + fi + if test yes = "$build_old_libs"; then + echo "enable static libraries" + else + echo "disable static libraries" + fi + + exit $? +} + + +# func_enable_tag TAGNAME +# ----------------------- +# Verify that TAGNAME is valid, and either flag an error and exit, or +# enable the TAGNAME tag. We also add TAGNAME to the global $taglist +# variable here. +func_enable_tag () +{ + # Global variable: + tagname=$1 + + re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$" + re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$" + sed_extractcf=/$re_begincf/,/$re_endcf/p + + # Validate tagname. + case $tagname in + *[!-_A-Za-z0-9,/]*) + func_fatal_error "invalid tag name: $tagname" + ;; + esac + + # Don't test for the "default" C tag, as we know it's + # there but not specially marked. + case $tagname in + CC) ;; + *) + if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then + taglist="$taglist $tagname" + + # Evaluate the configuration. Be careful to quote the path + # and the sed script, to avoid splitting on whitespace, but + # also don't use non-portable quotes within backquotes within + # quotes we have to do it in 2 steps: + extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"` + eval "$extractedcf" + else + func_error "ignoring unknown tag $tagname" + fi + ;; + esac +} + + +# func_check_version_match +# ------------------------ +# Ensure that we are using m4 macros, and libtool script from the same +# release of libtool. +func_check_version_match () +{ + if test "$package_revision" != "$macro_revision"; then + if test "$VERSION" != "$macro_version"; then + if test -z "$macro_version"; then + cat >&2 <<_LT_EOF +$progname: Version mismatch error. This is $PACKAGE $VERSION, but the +$progname: definition of this LT_INIT comes from an older release. +$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION +$progname: and run autoconf again. +_LT_EOF + else + cat >&2 <<_LT_EOF +$progname: Version mismatch error. This is $PACKAGE $VERSION, but the +$progname: definition of this LT_INIT comes from $PACKAGE $macro_version. +$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION +$progname: and run autoconf again. +_LT_EOF + fi + else + cat >&2 <<_LT_EOF +$progname: Version mismatch error. This is $PACKAGE $VERSION, revision $package_revision, +$progname: but the definition of this LT_INIT comes from revision $macro_revision. +$progname: You should recreate aclocal.m4 with macros from revision $package_revision +$progname: of $PACKAGE $VERSION and run autoconf again. +_LT_EOF + fi + + exit $EXIT_MISMATCH + fi +} + + +# libtool_options_prep [ARG]... +# ----------------------------- +# Preparation for options parsed by libtool. +libtool_options_prep () +{ + $debug_mode + + # Option defaults: + opt_config=false + opt_dlopen= + opt_dry_run=false + opt_help=false + opt_mode= + opt_preserve_dup_deps=false + opt_quiet=false + + nonopt= + preserve_args= + + _G_rc_lt_options_prep=: + + # Shorthand for --mode=foo, only valid as the first argument + case $1 in + clean|clea|cle|cl) + shift; set dummy --mode clean ${1+"$@"}; shift + ;; + compile|compil|compi|comp|com|co|c) + shift; set dummy --mode compile ${1+"$@"}; shift + ;; + execute|execut|execu|exec|exe|ex|e) + shift; set dummy --mode execute ${1+"$@"}; shift + ;; + finish|finis|fini|fin|fi|f) + shift; set dummy --mode finish ${1+"$@"}; shift + ;; + install|instal|insta|inst|ins|in|i) + shift; set dummy --mode install ${1+"$@"}; shift + ;; + link|lin|li|l) + shift; set dummy --mode link ${1+"$@"}; shift + ;; + uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u) + shift; set dummy --mode uninstall ${1+"$@"}; shift + ;; + *) + _G_rc_lt_options_prep=false + ;; + esac + + if $_G_rc_lt_options_prep; then + # Pass back the list of options. + func_quote_for_eval ${1+"$@"} + libtool_options_prep_result=$func_quote_for_eval_result + fi + + $_G_rc_lt_options_prep +} +func_add_hook func_options_prep libtool_options_prep + + +# libtool_parse_options [ARG]... +# --------------------------------- +# Provide handling for libtool specific options. +libtool_parse_options () +{ + $debug_cmd + + _G_rc_lt_parse_options=false + + # Perform our own loop to consume as many options as possible in + # each iteration. + while test $# -gt 0; do + _G_match_lt_parse_options=: + _G_opt=$1 + shift + case $_G_opt in + --dry-run|--dryrun|-n) + opt_dry_run=: + ;; + + --config) func_config ;; + + --dlopen|-dlopen) + opt_dlopen="${opt_dlopen+$opt_dlopen +}$1" + shift + ;; + + --preserve-dup-deps) + opt_preserve_dup_deps=: ;; + + --features) func_features ;; + + --finish) set dummy --mode finish ${1+"$@"}; shift ;; + + --help) opt_help=: ;; + + --help-all) opt_help=': help-all' ;; + + --mode) test $# = 0 && func_missing_arg $_G_opt && break + opt_mode=$1 + case $1 in + # Valid mode arguments: + clean|compile|execute|finish|install|link|relink|uninstall) ;; + + # Catch anything else as an error + *) func_error "invalid argument for $_G_opt" + exit_cmd=exit + break + ;; + esac + shift + ;; + + --no-silent|--no-quiet) + opt_quiet=false + func_append preserve_args " $_G_opt" + ;; + + --no-warnings|--no-warning|--no-warn) + opt_warning=false + func_append preserve_args " $_G_opt" + ;; + + --no-verbose) + opt_verbose=false + func_append preserve_args " $_G_opt" + ;; + + --silent|--quiet) + opt_quiet=: + opt_verbose=false + func_append preserve_args " $_G_opt" + ;; + + --tag) test $# = 0 && func_missing_arg $_G_opt && break + opt_tag=$1 + func_append preserve_args " $_G_opt $1" + func_enable_tag "$1" + shift + ;; + + --verbose|-v) opt_quiet=false + opt_verbose=: + func_append preserve_args " $_G_opt" + ;; + + # An option not handled by this hook function: + *) set dummy "$_G_opt" ${1+"$@"} ; shift + _G_match_lt_parse_options=false + break + ;; + esac + $_G_match_lt_parse_options && _G_rc_lt_parse_options=: + done + + if $_G_rc_lt_parse_options; then + # save modified positional parameters for caller + func_quote_for_eval ${1+"$@"} + libtool_parse_options_result=$func_quote_for_eval_result + fi + + $_G_rc_lt_parse_options +} +func_add_hook func_parse_options libtool_parse_options + + + +# libtool_validate_options [ARG]... +# --------------------------------- +# Perform any sanity checks on option settings and/or unconsumed +# arguments. +libtool_validate_options () +{ + # save first non-option argument + if test 0 -lt $#; then + nonopt=$1 + shift + fi + + # preserve --debug + test : = "$debug_cmd" || func_append preserve_args " --debug" + + case $host in + # Solaris2 added to fix http://debbugs.gnu.org/cgi/bugreport.cgi?bug=16452 + # see also: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59788 + *cygwin* | *mingw* | *pw32* | *cegcc* | *solaris2* | *os2*) + # don't eliminate duplications in $postdeps and $predeps + opt_duplicate_compiler_generated_deps=: + ;; + *) + opt_duplicate_compiler_generated_deps=$opt_preserve_dup_deps + ;; + esac + + $opt_help || { + # Sanity checks first: + func_check_version_match + + test yes != "$build_libtool_libs" \ + && test yes != "$build_old_libs" \ + && func_fatal_configuration "not configured to build any kind of library" + + # Darwin sucks + eval std_shrext=\"$shrext_cmds\" + + # Only execute mode is allowed to have -dlopen flags. + if test -n "$opt_dlopen" && test execute != "$opt_mode"; then + func_error "unrecognized option '-dlopen'" + $ECHO "$help" 1>&2 + exit $EXIT_FAILURE + fi + + # Change the help message to a mode-specific one. + generic_help=$help + help="Try '$progname --help --mode=$opt_mode' for more information." + } + + # Pass back the unparsed argument list + func_quote_for_eval ${1+"$@"} + libtool_validate_options_result=$func_quote_for_eval_result +} +func_add_hook func_validate_options libtool_validate_options + + +# Process options as early as possible so that --help and --version +# can return quickly. +func_options ${1+"$@"} +eval set dummy "$func_options_result"; shift + + + +## ----------- ## +## Main. ## +## ----------- ## + +magic='%%%MAGIC variable%%%' +magic_exe='%%%MAGIC EXE variable%%%' + +# Global variables. +extracted_archives= +extracted_serial=0 + +# If this variable is set in any of the actions, the command in it +# will be execed at the end. This prevents here-documents from being +# left over by shells. +exec_cmd= + + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +$1 +_LTECHO_EOF' +} + +# func_generated_by_libtool +# True iff stdin has been generated by Libtool. This function is only +# a basic sanity check; it will hardly flush out determined imposters. +func_generated_by_libtool_p () +{ + $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1 +} + +# func_lalib_p file +# True iff FILE is a libtool '.la' library or '.lo' object file. +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_lalib_p () +{ + test -f "$1" && + $SED -e 4q "$1" 2>/dev/null | func_generated_by_libtool_p +} + +# func_lalib_unsafe_p file +# True iff FILE is a libtool '.la' library or '.lo' object file. +# This function implements the same check as func_lalib_p without +# resorting to external programs. To this end, it redirects stdin and +# closes it afterwards, without saving the original file descriptor. +# As a safety measure, use it only where a negative result would be +# fatal anyway. Works if 'file' does not exist. +func_lalib_unsafe_p () +{ + lalib_p=no + if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then + for lalib_p_l in 1 2 3 4 + do + read lalib_p_line + case $lalib_p_line in + \#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;; + esac + done + exec 0<&5 5<&- + fi + test yes = "$lalib_p" +} + +# func_ltwrapper_script_p file +# True iff FILE is a libtool wrapper script +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_ltwrapper_script_p () +{ + test -f "$1" && + $lt_truncate_bin < "$1" 2>/dev/null | func_generated_by_libtool_p +} + +# func_ltwrapper_executable_p file +# True iff FILE is a libtool wrapper executable +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_ltwrapper_executable_p () +{ + func_ltwrapper_exec_suffix= + case $1 in + *.exe) ;; + *) func_ltwrapper_exec_suffix=.exe ;; + esac + $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1 +} + +# func_ltwrapper_scriptname file +# Assumes file is an ltwrapper_executable +# uses $file to determine the appropriate filename for a +# temporary ltwrapper_script. +func_ltwrapper_scriptname () +{ + func_dirname_and_basename "$1" "" "." + func_stripname '' '.exe' "$func_basename_result" + func_ltwrapper_scriptname_result=$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper +} + +# func_ltwrapper_p file +# True iff FILE is a libtool wrapper script or wrapper executable +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_ltwrapper_p () +{ + func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1" +} + + +# func_execute_cmds commands fail_cmd +# Execute tilde-delimited COMMANDS. +# If FAIL_CMD is given, eval that upon failure. +# FAIL_CMD may read-access the current command in variable CMD! +func_execute_cmds () +{ + $debug_cmd + + save_ifs=$IFS; IFS='~' + for cmd in $1; do + IFS=$sp$nl + eval cmd=\"$cmd\" + IFS=$save_ifs + func_show_eval "$cmd" "${2-:}" + done + IFS=$save_ifs +} + + +# func_source file +# Source FILE, adding directory component if necessary. +# Note that it is not necessary on cygwin/mingw to append a dot to +# FILE even if both FILE and FILE.exe exist: automatic-append-.exe +# behavior happens only for exec(3), not for open(2)! Also, sourcing +# 'FILE.' does not work on cygwin managed mounts. +func_source () +{ + $debug_cmd + + case $1 in + */* | *\\*) . "$1" ;; + *) . "./$1" ;; + esac +} + + +# func_resolve_sysroot PATH +# Replace a leading = in PATH with a sysroot. Store the result into +# func_resolve_sysroot_result +func_resolve_sysroot () +{ + func_resolve_sysroot_result=$1 + case $func_resolve_sysroot_result in + =*) + func_stripname '=' '' "$func_resolve_sysroot_result" + func_resolve_sysroot_result=$lt_sysroot$func_stripname_result + ;; + esac +} + +# func_replace_sysroot PATH +# If PATH begins with the sysroot, replace it with = and +# store the result into func_replace_sysroot_result. +func_replace_sysroot () +{ + case $lt_sysroot:$1 in + ?*:"$lt_sysroot"*) + func_stripname "$lt_sysroot" '' "$1" + func_replace_sysroot_result='='$func_stripname_result + ;; + *) + # Including no sysroot. + func_replace_sysroot_result=$1 + ;; + esac +} + +# func_infer_tag arg +# Infer tagged configuration to use if any are available and +# if one wasn't chosen via the "--tag" command line option. +# Only attempt this if the compiler in the base compile +# command doesn't match the default compiler. +# arg is usually of the form 'gcc ...' +func_infer_tag () +{ + $debug_cmd + + if test -n "$available_tags" && test -z "$tagname"; then + CC_quoted= + for arg in $CC; do + func_append_quoted CC_quoted "$arg" + done + CC_expanded=`func_echo_all $CC` + CC_quoted_expanded=`func_echo_all $CC_quoted` + case $@ in + # Blanks in the command may have been stripped by the calling shell, + # but not from the CC environment variable when configure was run. + " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ + " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) ;; + # Blanks at the start of $base_compile will cause this to fail + # if we don't check for them as well. + *) + for z in $available_tags; do + if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then + # Evaluate the configuration. + eval "`$SED -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`" + CC_quoted= + for arg in $CC; do + # Double-quote args containing other shell metacharacters. + func_append_quoted CC_quoted "$arg" + done + CC_expanded=`func_echo_all $CC` + CC_quoted_expanded=`func_echo_all $CC_quoted` + case "$@ " in + " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ + " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) + # The compiler in the base compile command matches + # the one in the tagged configuration. + # Assume this is the tagged configuration we want. + tagname=$z + break + ;; + esac + fi + done + # If $tagname still isn't set, then no tagged configuration + # was found and let the user know that the "--tag" command + # line option must be used. + if test -z "$tagname"; then + func_echo "unable to infer tagged configuration" + func_fatal_error "specify a tag with '--tag'" +# else +# func_verbose "using $tagname tagged configuration" + fi + ;; + esac + fi +} + + + +# func_write_libtool_object output_name pic_name nonpic_name +# Create a libtool object file (analogous to a ".la" file), +# but don't create it if we're doing a dry run. +func_write_libtool_object () +{ + write_libobj=$1 + if test yes = "$build_libtool_libs"; then + write_lobj=\'$2\' + else + write_lobj=none + fi + + if test yes = "$build_old_libs"; then + write_oldobj=\'$3\' + else + write_oldobj=none + fi + + $opt_dry_run || { + cat >${write_libobj}T </dev/null` + if test "$?" -eq 0 && test -n "$func_convert_core_file_wine_to_w32_tmp"; then + func_convert_core_file_wine_to_w32_result=`$ECHO "$func_convert_core_file_wine_to_w32_tmp" | + $SED -e "$sed_naive_backslashify"` + else + func_convert_core_file_wine_to_w32_result= + fi + fi +} +# end: func_convert_core_file_wine_to_w32 + + +# func_convert_core_path_wine_to_w32 ARG +# Helper function used by path conversion functions when $build is *nix, and +# $host is mingw, cygwin, or some other w32 environment. Relies on a correctly +# configured wine environment available, with the winepath program in $build's +# $PATH. Assumes ARG has no leading or trailing path separator characters. +# +# ARG is path to be converted from $build format to win32. +# Result is available in $func_convert_core_path_wine_to_w32_result. +# Unconvertible file (directory) names in ARG are skipped; if no directory names +# are convertible, then the result may be empty. +func_convert_core_path_wine_to_w32 () +{ + $debug_cmd + + # unfortunately, winepath doesn't convert paths, only file names + func_convert_core_path_wine_to_w32_result= + if test -n "$1"; then + oldIFS=$IFS + IFS=: + for func_convert_core_path_wine_to_w32_f in $1; do + IFS=$oldIFS + func_convert_core_file_wine_to_w32 "$func_convert_core_path_wine_to_w32_f" + if test -n "$func_convert_core_file_wine_to_w32_result"; then + if test -z "$func_convert_core_path_wine_to_w32_result"; then + func_convert_core_path_wine_to_w32_result=$func_convert_core_file_wine_to_w32_result + else + func_append func_convert_core_path_wine_to_w32_result ";$func_convert_core_file_wine_to_w32_result" + fi + fi + done + IFS=$oldIFS + fi +} +# end: func_convert_core_path_wine_to_w32 + + +# func_cygpath ARGS... +# Wrapper around calling the cygpath program via LT_CYGPATH. This is used when +# when (1) $build is *nix and Cygwin is hosted via a wine environment; or (2) +# $build is MSYS and $host is Cygwin, or (3) $build is Cygwin. In case (1) or +# (2), returns the Cygwin file name or path in func_cygpath_result (input +# file name or path is assumed to be in w32 format, as previously converted +# from $build's *nix or MSYS format). In case (3), returns the w32 file name +# or path in func_cygpath_result (input file name or path is assumed to be in +# Cygwin format). Returns an empty string on error. +# +# ARGS are passed to cygpath, with the last one being the file name or path to +# be converted. +# +# Specify the absolute *nix (or w32) name to cygpath in the LT_CYGPATH +# environment variable; do not put it in $PATH. +func_cygpath () +{ + $debug_cmd + + if test -n "$LT_CYGPATH" && test -f "$LT_CYGPATH"; then + func_cygpath_result=`$LT_CYGPATH "$@" 2>/dev/null` + if test "$?" -ne 0; then + # on failure, ensure result is empty + func_cygpath_result= + fi + else + func_cygpath_result= + func_error "LT_CYGPATH is empty or specifies non-existent file: '$LT_CYGPATH'" + fi +} +#end: func_cygpath + + +# func_convert_core_msys_to_w32 ARG +# Convert file name or path ARG from MSYS format to w32 format. Return +# result in func_convert_core_msys_to_w32_result. +func_convert_core_msys_to_w32 () +{ + $debug_cmd + + # awkward: cmd appends spaces to result + func_convert_core_msys_to_w32_result=`( cmd //c echo "$1" ) 2>/dev/null | + $SED -e 's/[ ]*$//' -e "$sed_naive_backslashify"` +} +#end: func_convert_core_msys_to_w32 + + +# func_convert_file_check ARG1 ARG2 +# Verify that ARG1 (a file name in $build format) was converted to $host +# format in ARG2. Otherwise, emit an error message, but continue (resetting +# func_to_host_file_result to ARG1). +func_convert_file_check () +{ + $debug_cmd + + if test -z "$2" && test -n "$1"; then + func_error "Could not determine host file name corresponding to" + func_error " '$1'" + func_error "Continuing, but uninstalled executables may not work." + # Fallback: + func_to_host_file_result=$1 + fi +} +# end func_convert_file_check + + +# func_convert_path_check FROM_PATHSEP TO_PATHSEP FROM_PATH TO_PATH +# Verify that FROM_PATH (a path in $build format) was converted to $host +# format in TO_PATH. Otherwise, emit an error message, but continue, resetting +# func_to_host_file_result to a simplistic fallback value (see below). +func_convert_path_check () +{ + $debug_cmd + + if test -z "$4" && test -n "$3"; then + func_error "Could not determine the host path corresponding to" + func_error " '$3'" + func_error "Continuing, but uninstalled executables may not work." + # Fallback. This is a deliberately simplistic "conversion" and + # should not be "improved". See libtool.info. + if test "x$1" != "x$2"; then + lt_replace_pathsep_chars="s|$1|$2|g" + func_to_host_path_result=`echo "$3" | + $SED -e "$lt_replace_pathsep_chars"` + else + func_to_host_path_result=$3 + fi + fi +} +# end func_convert_path_check + + +# func_convert_path_front_back_pathsep FRONTPAT BACKPAT REPL ORIG +# Modifies func_to_host_path_result by prepending REPL if ORIG matches FRONTPAT +# and appending REPL if ORIG matches BACKPAT. +func_convert_path_front_back_pathsep () +{ + $debug_cmd + + case $4 in + $1 ) func_to_host_path_result=$3$func_to_host_path_result + ;; + esac + case $4 in + $2 ) func_append func_to_host_path_result "$3" + ;; + esac +} +# end func_convert_path_front_back_pathsep + + +################################################## +# $build to $host FILE NAME CONVERSION FUNCTIONS # +################################################## +# invoked via '$to_host_file_cmd ARG' +# +# In each case, ARG is the path to be converted from $build to $host format. +# Result will be available in $func_to_host_file_result. + + +# func_to_host_file ARG +# Converts the file name ARG from $build format to $host format. Return result +# in func_to_host_file_result. +func_to_host_file () +{ + $debug_cmd + + $to_host_file_cmd "$1" +} +# end func_to_host_file + + +# func_to_tool_file ARG LAZY +# converts the file name ARG from $build format to toolchain format. Return +# result in func_to_tool_file_result. If the conversion in use is listed +# in (the comma separated) LAZY, no conversion takes place. +func_to_tool_file () +{ + $debug_cmd + + case ,$2, in + *,"$to_tool_file_cmd",*) + func_to_tool_file_result=$1 + ;; + *) + $to_tool_file_cmd "$1" + func_to_tool_file_result=$func_to_host_file_result + ;; + esac +} +# end func_to_tool_file + + +# func_convert_file_noop ARG +# Copy ARG to func_to_host_file_result. +func_convert_file_noop () +{ + func_to_host_file_result=$1 +} +# end func_convert_file_noop + + +# func_convert_file_msys_to_w32 ARG +# Convert file name ARG from (mingw) MSYS to (mingw) w32 format; automatic +# conversion to w32 is not available inside the cwrapper. Returns result in +# func_to_host_file_result. +func_convert_file_msys_to_w32 () +{ + $debug_cmd + + func_to_host_file_result=$1 + if test -n "$1"; then + func_convert_core_msys_to_w32 "$1" + func_to_host_file_result=$func_convert_core_msys_to_w32_result + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_msys_to_w32 + + +# func_convert_file_cygwin_to_w32 ARG +# Convert file name ARG from Cygwin to w32 format. Returns result in +# func_to_host_file_result. +func_convert_file_cygwin_to_w32 () +{ + $debug_cmd + + func_to_host_file_result=$1 + if test -n "$1"; then + # because $build is cygwin, we call "the" cygpath in $PATH; no need to use + # LT_CYGPATH in this case. + func_to_host_file_result=`cygpath -m "$1"` + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_cygwin_to_w32 + + +# func_convert_file_nix_to_w32 ARG +# Convert file name ARG from *nix to w32 format. Requires a wine environment +# and a working winepath. Returns result in func_to_host_file_result. +func_convert_file_nix_to_w32 () +{ + $debug_cmd + + func_to_host_file_result=$1 + if test -n "$1"; then + func_convert_core_file_wine_to_w32 "$1" + func_to_host_file_result=$func_convert_core_file_wine_to_w32_result + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_nix_to_w32 + + +# func_convert_file_msys_to_cygwin ARG +# Convert file name ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. +# Returns result in func_to_host_file_result. +func_convert_file_msys_to_cygwin () +{ + $debug_cmd + + func_to_host_file_result=$1 + if test -n "$1"; then + func_convert_core_msys_to_w32 "$1" + func_cygpath -u "$func_convert_core_msys_to_w32_result" + func_to_host_file_result=$func_cygpath_result + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_msys_to_cygwin + + +# func_convert_file_nix_to_cygwin ARG +# Convert file name ARG from *nix to Cygwin format. Requires Cygwin installed +# in a wine environment, working winepath, and LT_CYGPATH set. Returns result +# in func_to_host_file_result. +func_convert_file_nix_to_cygwin () +{ + $debug_cmd + + func_to_host_file_result=$1 + if test -n "$1"; then + # convert from *nix to w32, then use cygpath to convert from w32 to cygwin. + func_convert_core_file_wine_to_w32 "$1" + func_cygpath -u "$func_convert_core_file_wine_to_w32_result" + func_to_host_file_result=$func_cygpath_result + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_nix_to_cygwin + + +############################################# +# $build to $host PATH CONVERSION FUNCTIONS # +############################################# +# invoked via '$to_host_path_cmd ARG' +# +# In each case, ARG is the path to be converted from $build to $host format. +# The result will be available in $func_to_host_path_result. +# +# Path separators are also converted from $build format to $host format. If +# ARG begins or ends with a path separator character, it is preserved (but +# converted to $host format) on output. +# +# All path conversion functions are named using the following convention: +# file name conversion function : func_convert_file_X_to_Y () +# path conversion function : func_convert_path_X_to_Y () +# where, for any given $build/$host combination the 'X_to_Y' value is the +# same. If conversion functions are added for new $build/$host combinations, +# the two new functions must follow this pattern, or func_init_to_host_path_cmd +# will break. + + +# func_init_to_host_path_cmd +# Ensures that function "pointer" variable $to_host_path_cmd is set to the +# appropriate value, based on the value of $to_host_file_cmd. +to_host_path_cmd= +func_init_to_host_path_cmd () +{ + $debug_cmd + + if test -z "$to_host_path_cmd"; then + func_stripname 'func_convert_file_' '' "$to_host_file_cmd" + to_host_path_cmd=func_convert_path_$func_stripname_result + fi +} + + +# func_to_host_path ARG +# Converts the path ARG from $build format to $host format. Return result +# in func_to_host_path_result. +func_to_host_path () +{ + $debug_cmd + + func_init_to_host_path_cmd + $to_host_path_cmd "$1" +} +# end func_to_host_path + + +# func_convert_path_noop ARG +# Copy ARG to func_to_host_path_result. +func_convert_path_noop () +{ + func_to_host_path_result=$1 +} +# end func_convert_path_noop + + +# func_convert_path_msys_to_w32 ARG +# Convert path ARG from (mingw) MSYS to (mingw) w32 format; automatic +# conversion to w32 is not available inside the cwrapper. Returns result in +# func_to_host_path_result. +func_convert_path_msys_to_w32 () +{ + $debug_cmd + + func_to_host_path_result=$1 + if test -n "$1"; then + # Remove leading and trailing path separator characters from ARG. MSYS + # behavior is inconsistent here; cygpath turns them into '.;' and ';.'; + # and winepath ignores them completely. + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" + func_to_host_path_result=$func_convert_core_msys_to_w32_result + func_convert_path_check : ";" \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" + fi +} +# end func_convert_path_msys_to_w32 + + +# func_convert_path_cygwin_to_w32 ARG +# Convert path ARG from Cygwin to w32 format. Returns result in +# func_to_host_file_result. +func_convert_path_cygwin_to_w32 () +{ + $debug_cmd + + func_to_host_path_result=$1 + if test -n "$1"; then + # See func_convert_path_msys_to_w32: + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_to_host_path_result=`cygpath -m -p "$func_to_host_path_tmp1"` + func_convert_path_check : ";" \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" + fi +} +# end func_convert_path_cygwin_to_w32 + + +# func_convert_path_nix_to_w32 ARG +# Convert path ARG from *nix to w32 format. Requires a wine environment and +# a working winepath. Returns result in func_to_host_file_result. +func_convert_path_nix_to_w32 () +{ + $debug_cmd + + func_to_host_path_result=$1 + if test -n "$1"; then + # See func_convert_path_msys_to_w32: + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" + func_to_host_path_result=$func_convert_core_path_wine_to_w32_result + func_convert_path_check : ";" \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" + fi +} +# end func_convert_path_nix_to_w32 + + +# func_convert_path_msys_to_cygwin ARG +# Convert path ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. +# Returns result in func_to_host_file_result. +func_convert_path_msys_to_cygwin () +{ + $debug_cmd + + func_to_host_path_result=$1 + if test -n "$1"; then + # See func_convert_path_msys_to_w32: + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" + func_cygpath -u -p "$func_convert_core_msys_to_w32_result" + func_to_host_path_result=$func_cygpath_result + func_convert_path_check : : \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" : "$1" + fi +} +# end func_convert_path_msys_to_cygwin + + +# func_convert_path_nix_to_cygwin ARG +# Convert path ARG from *nix to Cygwin format. Requires Cygwin installed in a +# a wine environment, working winepath, and LT_CYGPATH set. Returns result in +# func_to_host_file_result. +func_convert_path_nix_to_cygwin () +{ + $debug_cmd + + func_to_host_path_result=$1 + if test -n "$1"; then + # Remove leading and trailing path separator characters from + # ARG. msys behavior is inconsistent here, cygpath turns them + # into '.;' and ';.', and winepath ignores them completely. + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" + func_cygpath -u -p "$func_convert_core_path_wine_to_w32_result" + func_to_host_path_result=$func_cygpath_result + func_convert_path_check : : \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" : "$1" + fi +} +# end func_convert_path_nix_to_cygwin + + +# func_dll_def_p FILE +# True iff FILE is a Windows DLL '.def' file. +# Keep in sync with _LT_DLL_DEF_P in libtool.m4 +func_dll_def_p () +{ + $debug_cmd + + func_dll_def_p_tmp=`$SED -n \ + -e 's/^[ ]*//' \ + -e '/^\(;.*\)*$/d' \ + -e 's/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p' \ + -e q \ + "$1"` + test DEF = "$func_dll_def_p_tmp" +} + + +# func_mode_compile arg... +func_mode_compile () +{ + $debug_cmd + + # Get the compilation command and the source file. + base_compile= + srcfile=$nonopt # always keep a non-empty value in "srcfile" + suppress_opt=yes + suppress_output= + arg_mode=normal + libobj= + later= + pie_flag= + + for arg + do + case $arg_mode in + arg ) + # do not "continue". Instead, add this to base_compile + lastarg=$arg + arg_mode=normal + ;; + + target ) + libobj=$arg + arg_mode=normal + continue + ;; + + normal ) + # Accept any command-line options. + case $arg in + -o) + test -n "$libobj" && \ + func_fatal_error "you cannot specify '-o' more than once" + arg_mode=target + continue + ;; + + -pie | -fpie | -fPIE) + func_append pie_flag " $arg" + continue + ;; + + -shared | -static | -prefer-pic | -prefer-non-pic) + func_append later " $arg" + continue + ;; + + -no-suppress) + suppress_opt=no + continue + ;; + + -Xcompiler) + arg_mode=arg # the next one goes into the "base_compile" arg list + continue # The current "srcfile" will either be retained or + ;; # replaced later. I would guess that would be a bug. + + -Wc,*) + func_stripname '-Wc,' '' "$arg" + args=$func_stripname_result + lastarg= + save_ifs=$IFS; IFS=, + for arg in $args; do + IFS=$save_ifs + func_append_quoted lastarg "$arg" + done + IFS=$save_ifs + func_stripname ' ' '' "$lastarg" + lastarg=$func_stripname_result + + # Add the arguments to base_compile. + func_append base_compile " $lastarg" + continue + ;; + + *) + # Accept the current argument as the source file. + # The previous "srcfile" becomes the current argument. + # + lastarg=$srcfile + srcfile=$arg + ;; + esac # case $arg + ;; + esac # case $arg_mode + + # Aesthetically quote the previous argument. + func_append_quoted base_compile "$lastarg" + done # for arg + + case $arg_mode in + arg) + func_fatal_error "you must specify an argument for -Xcompile" + ;; + target) + func_fatal_error "you must specify a target with '-o'" + ;; + *) + # Get the name of the library object. + test -z "$libobj" && { + func_basename "$srcfile" + libobj=$func_basename_result + } + ;; + esac + + # Recognize several different file suffixes. + # If the user specifies -o file.o, it is replaced with file.lo + case $libobj in + *.[cCFSifmso] | \ + *.ada | *.adb | *.ads | *.asm | \ + *.c++ | *.cc | *.ii | *.class | *.cpp | *.cxx | \ + *.[fF][09]? | *.for | *.java | *.go | *.obj | *.sx | *.cu | *.cup) + func_xform "$libobj" + libobj=$func_xform_result + ;; + esac + + case $libobj in + *.lo) func_lo2o "$libobj"; obj=$func_lo2o_result ;; + *) + func_fatal_error "cannot determine name of library object from '$libobj'" + ;; + esac + + func_infer_tag $base_compile + + for arg in $later; do + case $arg in + -shared) + test yes = "$build_libtool_libs" \ + || func_fatal_configuration "cannot build a shared library" + build_old_libs=no + continue + ;; + + -static) + build_libtool_libs=no + build_old_libs=yes + continue + ;; + + -prefer-pic) + pic_mode=yes + continue + ;; + + -prefer-non-pic) + pic_mode=no + continue + ;; + esac + done + + func_quote_for_eval "$libobj" + test "X$libobj" != "X$func_quote_for_eval_result" \ + && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"' &()|`$[]' \ + && func_warning "libobj name '$libobj' may not contain shell special characters." + func_dirname_and_basename "$obj" "/" "" + objname=$func_basename_result + xdir=$func_dirname_result + lobj=$xdir$objdir/$objname + + test -z "$base_compile" && \ + func_fatal_help "you must specify a compilation command" + + # Delete any leftover library objects. + if test yes = "$build_old_libs"; then + removelist="$obj $lobj $libobj ${libobj}T" + else + removelist="$lobj $libobj ${libobj}T" + fi + + # On Cygwin there's no "real" PIC flag so we must build both object types + case $host_os in + cygwin* | mingw* | pw32* | os2* | cegcc*) + pic_mode=default + ;; + esac + if test no = "$pic_mode" && test pass_all != "$deplibs_check_method"; then + # non-PIC code in shared libraries is not supported + pic_mode=default + fi + + # Calculate the filename of the output object if compiler does + # not support -o with -c + if test no = "$compiler_c_o"; then + output_obj=`$ECHO "$srcfile" | $SED 's%^.*/%%; s%\.[^.]*$%%'`.$objext + lockfile=$output_obj.lock + else + output_obj= + need_locks=no + lockfile= + fi + + # Lock this critical section if it is needed + # We use this script file to make the link, it avoids creating a new file + if test yes = "$need_locks"; then + until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do + func_echo "Waiting for $lockfile to be removed" + sleep 2 + done + elif test warn = "$need_locks"; then + if test -f "$lockfile"; then + $ECHO "\ +*** ERROR, $lockfile exists and contains: +`cat $lockfile 2>/dev/null` + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support '-c' and '-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $opt_dry_run || $RM $removelist + exit $EXIT_FAILURE + fi + func_append removelist " $output_obj" + $ECHO "$srcfile" > "$lockfile" + fi + + $opt_dry_run || $RM $removelist + func_append removelist " $lockfile" + trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15 + + func_to_tool_file "$srcfile" func_convert_file_msys_to_w32 + srcfile=$func_to_tool_file_result + func_quote_for_eval "$srcfile" + qsrcfile=$func_quote_for_eval_result + + # Only build a PIC object if we are building libtool libraries. + if test yes = "$build_libtool_libs"; then + # Without this assignment, base_compile gets emptied. + fbsd_hideous_sh_bug=$base_compile + + if test no != "$pic_mode"; then + command="$base_compile $qsrcfile $pic_flag" + else + # Don't build PIC code + command="$base_compile $qsrcfile" + fi + + func_mkdir_p "$xdir$objdir" + + if test -z "$output_obj"; then + # Place PIC objects in $objdir + func_append command " -o $lobj" + fi + + func_show_eval_locale "$command" \ + 'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE' + + if test warn = "$need_locks" && + test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then + $ECHO "\ +*** ERROR, $lockfile contains: +`cat $lockfile 2>/dev/null` + +but it should contain: +$srcfile + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support '-c' and '-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $opt_dry_run || $RM $removelist + exit $EXIT_FAILURE + fi + + # Just move the object if needed, then go on to compile the next one + if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then + func_show_eval '$MV "$output_obj" "$lobj"' \ + 'error=$?; $opt_dry_run || $RM $removelist; exit $error' + fi + + # Allow error messages only from the first compilation. + if test yes = "$suppress_opt"; then + suppress_output=' >/dev/null 2>&1' + fi + fi + + # Only build a position-dependent object if we build old libraries. + if test yes = "$build_old_libs"; then + if test yes != "$pic_mode"; then + # Don't build PIC code + command="$base_compile $qsrcfile$pie_flag" + else + command="$base_compile $qsrcfile $pic_flag" + fi + if test yes = "$compiler_c_o"; then + func_append command " -o $obj" + fi + + # Suppress compiler output if we already did a PIC compilation. + func_append command "$suppress_output" + func_show_eval_locale "$command" \ + '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' + + if test warn = "$need_locks" && + test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then + $ECHO "\ +*** ERROR, $lockfile contains: +`cat $lockfile 2>/dev/null` + +but it should contain: +$srcfile + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support '-c' and '-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $opt_dry_run || $RM $removelist + exit $EXIT_FAILURE + fi + + # Just move the object if needed + if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then + func_show_eval '$MV "$output_obj" "$obj"' \ + 'error=$?; $opt_dry_run || $RM $removelist; exit $error' + fi + fi + + $opt_dry_run || { + func_write_libtool_object "$libobj" "$objdir/$objname" "$objname" + + # Unlock the critical section if it was locked + if test no != "$need_locks"; then + removelist=$lockfile + $RM "$lockfile" + fi + } + + exit $EXIT_SUCCESS +} + +$opt_help || { + test compile = "$opt_mode" && func_mode_compile ${1+"$@"} +} + +func_mode_help () +{ + # We need to display help for each of the modes. + case $opt_mode in + "") + # Generic help is extracted from the usage comments + # at the start of this file. + func_help + ;; + + clean) + $ECHO \ +"Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE... + +Remove files from the build directory. + +RM is the name of the program to use to delete files associated with each FILE +(typically '/bin/rm'). RM-OPTIONS are options (such as '-f') to be passed +to RM. + +If FILE is a libtool library, object or program, all the files associated +with it are deleted. Otherwise, only FILE itself is deleted using RM." + ;; + + compile) + $ECHO \ +"Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE + +Compile a source file into a libtool library object. + +This mode accepts the following additional options: + + -o OUTPUT-FILE set the output file name to OUTPUT-FILE + -no-suppress do not suppress compiler output for multiple passes + -prefer-pic try to build PIC objects only + -prefer-non-pic try to build non-PIC objects only + -shared do not build a '.o' file suitable for static linking + -static only build a '.o' file suitable for static linking + -Wc,FLAG pass FLAG directly to the compiler + +COMPILE-COMMAND is a command to be used in creating a 'standard' object file +from the given SOURCEFILE. + +The output file name is determined by removing the directory component from +SOURCEFILE, then substituting the C source code suffix '.c' with the +library object suffix, '.lo'." + ;; + + execute) + $ECHO \ +"Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]... + +Automatically set library path, then run a program. + +This mode accepts the following additional options: + + -dlopen FILE add the directory containing FILE to the library path + +This mode sets the library path environment variable according to '-dlopen' +flags. + +If any of the ARGS are libtool executable wrappers, then they are translated +into their corresponding uninstalled binary, and any of their required library +directories are added to the library path. + +Then, COMMAND is executed, with ARGS as arguments." + ;; + + finish) + $ECHO \ +"Usage: $progname [OPTION]... --mode=finish [LIBDIR]... + +Complete the installation of libtool libraries. + +Each LIBDIR is a directory that contains libtool libraries. + +The commands that this mode executes may require superuser privileges. Use +the '--dry-run' option if you just want to see what would be executed." + ;; + + install) + $ECHO \ +"Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND... + +Install executables or libraries. + +INSTALL-COMMAND is the installation command. The first component should be +either the 'install' or 'cp' program. + +The following components of INSTALL-COMMAND are treated specially: + + -inst-prefix-dir PREFIX-DIR Use PREFIX-DIR as a staging area for installation + +The rest of the components are interpreted as arguments to that command (only +BSD-compatible install options are recognized)." + ;; + + link) + $ECHO \ +"Usage: $progname [OPTION]... --mode=link LINK-COMMAND... + +Link object files or libraries together to form another library, or to +create an executable program. + +LINK-COMMAND is a command using the C compiler that you would use to create +a program from several object files. + +The following components of LINK-COMMAND are treated specially: + + -all-static do not do any dynamic linking at all + -avoid-version do not add a version suffix if possible + -bindir BINDIR specify path to binaries directory (for systems where + libraries must be found in the PATH setting at runtime) + -dlopen FILE '-dlpreopen' FILE if it cannot be dlopened at runtime + -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols + -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) + -export-symbols SYMFILE + try to export only the symbols listed in SYMFILE + -export-symbols-regex REGEX + try to export only the symbols matching REGEX + -LLIBDIR search LIBDIR for required installed libraries + -lNAME OUTPUT-FILE requires the installed library libNAME + -module build a library that can dlopened + -no-fast-install disable the fast-install mode + -no-install link a not-installable executable + -no-undefined declare that a library does not refer to external symbols + -o OUTPUT-FILE create OUTPUT-FILE from the specified objects + -objectlist FILE use a list of object files found in FILE to specify objects + -os2dllname NAME force a short DLL name on OS/2 (no effect on other OSes) + -precious-files-regex REGEX + don't remove output files matching REGEX + -release RELEASE specify package release information + -rpath LIBDIR the created library will eventually be installed in LIBDIR + -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries + -shared only do dynamic linking of libtool libraries + -shrext SUFFIX override the standard shared library file extension + -static do not do any dynamic linking of uninstalled libtool libraries + -static-libtool-libs + do not do any dynamic linking of libtool libraries + -version-info CURRENT[:REVISION[:AGE]] + specify library version info [each variable defaults to 0] + -weak LIBNAME declare that the target provides the LIBNAME interface + -Wc,FLAG + -Xcompiler FLAG pass linker-specific FLAG directly to the compiler + -Wl,FLAG + -Xlinker FLAG pass linker-specific FLAG directly to the linker + -XCClinker FLAG pass link-specific FLAG to the compiler driver (CC) + +All other options (arguments beginning with '-') are ignored. + +Every other argument is treated as a filename. Files ending in '.la' are +treated as uninstalled libtool libraries, other files are standard or library +object files. + +If the OUTPUT-FILE ends in '.la', then a libtool library is created, +only library objects ('.lo' files) may be specified, and '-rpath' is +required, except when creating a convenience library. + +If OUTPUT-FILE ends in '.a' or '.lib', then a standard library is created +using 'ar' and 'ranlib', or on Windows using 'lib'. + +If OUTPUT-FILE ends in '.lo' or '.$objext', then a reloadable object file +is created, otherwise an executable program is created." + ;; + + uninstall) + $ECHO \ +"Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... + +Remove libraries from an installation directory. + +RM is the name of the program to use to delete files associated with each FILE +(typically '/bin/rm'). RM-OPTIONS are options (such as '-f') to be passed +to RM. + +If FILE is a libtool library, all the files associated with it are deleted. +Otherwise, only FILE itself is deleted using RM." + ;; + + *) + func_fatal_help "invalid operation mode '$opt_mode'" + ;; + esac + + echo + $ECHO "Try '$progname --help' for more information about other modes." +} + +# Now that we've collected a possible --mode arg, show help if necessary +if $opt_help; then + if test : = "$opt_help"; then + func_mode_help + else + { + func_help noexit + for opt_mode in compile link execute install finish uninstall clean; do + func_mode_help + done + } | $SED -n '1p; 2,$s/^Usage:/ or: /p' + { + func_help noexit + for opt_mode in compile link execute install finish uninstall clean; do + echo + func_mode_help + done + } | + $SED '1d + /^When reporting/,/^Report/{ + H + d + } + $x + /information about other modes/d + /more detailed .*MODE/d + s/^Usage:.*--mode=\([^ ]*\) .*/Description of \1 mode:/' + fi + exit $? +fi + + +# func_mode_execute arg... +func_mode_execute () +{ + $debug_cmd + + # The first argument is the command name. + cmd=$nonopt + test -z "$cmd" && \ + func_fatal_help "you must specify a COMMAND" + + # Handle -dlopen flags immediately. + for file in $opt_dlopen; do + test -f "$file" \ + || func_fatal_help "'$file' is not a file" + + dir= + case $file in + *.la) + func_resolve_sysroot "$file" + file=$func_resolve_sysroot_result + + # Check to see that this really is a libtool archive. + func_lalib_unsafe_p "$file" \ + || func_fatal_help "'$lib' is not a valid libtool archive" + + # Read the libtool library. + dlname= + library_names= + func_source "$file" + + # Skip this library if it cannot be dlopened. + if test -z "$dlname"; then + # Warn if it was a shared library. + test -n "$library_names" && \ + func_warning "'$file' was not linked with '-export-dynamic'" + continue + fi + + func_dirname "$file" "" "." + dir=$func_dirname_result + + if test -f "$dir/$objdir/$dlname"; then + func_append dir "/$objdir" + else + if test ! -f "$dir/$dlname"; then + func_fatal_error "cannot find '$dlname' in '$dir' or '$dir/$objdir'" + fi + fi + ;; + + *.lo) + # Just add the directory containing the .lo file. + func_dirname "$file" "" "." + dir=$func_dirname_result + ;; + + *) + func_warning "'-dlopen' is ignored for non-libtool libraries and objects" + continue + ;; + esac + + # Get the absolute pathname. + absdir=`cd "$dir" && pwd` + test -n "$absdir" && dir=$absdir + + # Now add the directory to shlibpath_var. + if eval "test -z \"\$$shlibpath_var\""; then + eval "$shlibpath_var=\"\$dir\"" + else + eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" + fi + done + + # This variable tells wrapper scripts just to set shlibpath_var + # rather than running their programs. + libtool_execute_magic=$magic + + # Check if any of the arguments is a wrapper script. + args= + for file + do + case $file in + -* | *.la | *.lo ) ;; + *) + # Do a test to see if this is really a libtool program. + if func_ltwrapper_script_p "$file"; then + func_source "$file" + # Transform arg to wrapped name. + file=$progdir/$program + elif func_ltwrapper_executable_p "$file"; then + func_ltwrapper_scriptname "$file" + func_source "$func_ltwrapper_scriptname_result" + # Transform arg to wrapped name. + file=$progdir/$program + fi + ;; + esac + # Quote arguments (to preserve shell metacharacters). + func_append_quoted args "$file" + done + + if $opt_dry_run; then + # Display what would be done. + if test -n "$shlibpath_var"; then + eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\"" + echo "export $shlibpath_var" + fi + $ECHO "$cmd$args" + exit $EXIT_SUCCESS + else + if test -n "$shlibpath_var"; then + # Export the shlibpath_var. + eval "export $shlibpath_var" + fi + + # Restore saved environment variables + for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES + do + eval "if test \"\${save_$lt_var+set}\" = set; then + $lt_var=\$save_$lt_var; export $lt_var + else + $lt_unset $lt_var + fi" + done + + # Now prepare to actually exec the command. + exec_cmd=\$cmd$args + fi +} + +test execute = "$opt_mode" && func_mode_execute ${1+"$@"} + + +# func_mode_finish arg... +func_mode_finish () +{ + $debug_cmd + + libs= + libdirs= + admincmds= + + for opt in "$nonopt" ${1+"$@"} + do + if test -d "$opt"; then + func_append libdirs " $opt" + + elif test -f "$opt"; then + if func_lalib_unsafe_p "$opt"; then + func_append libs " $opt" + else + func_warning "'$opt' is not a valid libtool archive" + fi + + else + func_fatal_error "invalid argument '$opt'" + fi + done + + if test -n "$libs"; then + if test -n "$lt_sysroot"; then + sysroot_regex=`$ECHO "$lt_sysroot" | $SED "$sed_make_literal_regex"` + sysroot_cmd="s/\([ ']\)$sysroot_regex/\1/g;" + else + sysroot_cmd= + fi + + # Remove sysroot references + if $opt_dry_run; then + for lib in $libs; do + echo "removing references to $lt_sysroot and '=' prefixes from $lib" + done + else + tmpdir=`func_mktempdir` + for lib in $libs; do + $SED -e "$sysroot_cmd s/\([ ']-[LR]\)=/\1/g; s/\([ ']\)=/\1/g" $lib \ + > $tmpdir/tmp-la + mv -f $tmpdir/tmp-la $lib + done + ${RM}r "$tmpdir" + fi + fi + + if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then + for libdir in $libdirs; do + if test -n "$finish_cmds"; then + # Do each command in the finish commands. + func_execute_cmds "$finish_cmds" 'admincmds="$admincmds +'"$cmd"'"' + fi + if test -n "$finish_eval"; then + # Do the single finish_eval. + eval cmds=\"$finish_eval\" + $opt_dry_run || eval "$cmds" || func_append admincmds " + $cmds" + fi + done + fi + + # Exit here if they wanted silent mode. + $opt_quiet && exit $EXIT_SUCCESS + + if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then + echo "----------------------------------------------------------------------" + echo "Libraries have been installed in:" + for libdir in $libdirs; do + $ECHO " $libdir" + done + echo + echo "If you ever happen to want to link against installed libraries" + echo "in a given directory, LIBDIR, you must either use libtool, and" + echo "specify the full pathname of the library, or use the '-LLIBDIR'" + echo "flag during linking and do at least one of the following:" + if test -n "$shlibpath_var"; then + echo " - add LIBDIR to the '$shlibpath_var' environment variable" + echo " during execution" + fi + if test -n "$runpath_var"; then + echo " - add LIBDIR to the '$runpath_var' environment variable" + echo " during linking" + fi + if test -n "$hardcode_libdir_flag_spec"; then + libdir=LIBDIR + eval flag=\"$hardcode_libdir_flag_spec\" + + $ECHO " - use the '$flag' linker flag" + fi + if test -n "$admincmds"; then + $ECHO " - have your system administrator run these commands:$admincmds" + fi + if test -f /etc/ld.so.conf; then + echo " - have your system administrator add LIBDIR to '/etc/ld.so.conf'" + fi + echo + + echo "See any operating system documentation about shared libraries for" + case $host in + solaris2.[6789]|solaris2.1[0-9]) + echo "more information, such as the ld(1), crle(1) and ld.so(8) manual" + echo "pages." + ;; + *) + echo "more information, such as the ld(1) and ld.so(8) manual pages." + ;; + esac + echo "----------------------------------------------------------------------" + fi + exit $EXIT_SUCCESS +} + +test finish = "$opt_mode" && func_mode_finish ${1+"$@"} + + +# func_mode_install arg... +func_mode_install () +{ + $debug_cmd + + # There may be an optional sh(1) argument at the beginning of + # install_prog (especially on Windows NT). + if test "$SHELL" = "$nonopt" || test /bin/sh = "$nonopt" || + # Allow the use of GNU shtool's install command. + case $nonopt in *shtool*) :;; *) false;; esac + then + # Aesthetically quote it. + func_quote_for_eval "$nonopt" + install_prog="$func_quote_for_eval_result " + arg=$1 + shift + else + install_prog= + arg=$nonopt + fi + + # The real first argument should be the name of the installation program. + # Aesthetically quote it. + func_quote_for_eval "$arg" + func_append install_prog "$func_quote_for_eval_result" + install_shared_prog=$install_prog + case " $install_prog " in + *[\\\ /]cp\ *) install_cp=: ;; + *) install_cp=false ;; + esac + + # We need to accept at least all the BSD install flags. + dest= + files= + opts= + prev= + install_type= + isdir=false + stripme= + no_mode=: + for arg + do + arg2= + if test -n "$dest"; then + func_append files " $dest" + dest=$arg + continue + fi + + case $arg in + -d) isdir=: ;; + -f) + if $install_cp; then :; else + prev=$arg + fi + ;; + -g | -m | -o) + prev=$arg + ;; + -s) + stripme=" -s" + continue + ;; + -*) + ;; + *) + # If the previous option needed an argument, then skip it. + if test -n "$prev"; then + if test X-m = "X$prev" && test -n "$install_override_mode"; then + arg2=$install_override_mode + no_mode=false + fi + prev= + else + dest=$arg + continue + fi + ;; + esac + + # Aesthetically quote the argument. + func_quote_for_eval "$arg" + func_append install_prog " $func_quote_for_eval_result" + if test -n "$arg2"; then + func_quote_for_eval "$arg2" + fi + func_append install_shared_prog " $func_quote_for_eval_result" + done + + test -z "$install_prog" && \ + func_fatal_help "you must specify an install program" + + test -n "$prev" && \ + func_fatal_help "the '$prev' option requires an argument" + + if test -n "$install_override_mode" && $no_mode; then + if $install_cp; then :; else + func_quote_for_eval "$install_override_mode" + func_append install_shared_prog " -m $func_quote_for_eval_result" + fi + fi + + if test -z "$files"; then + if test -z "$dest"; then + func_fatal_help "no file or destination specified" + else + func_fatal_help "you must specify a destination" + fi + fi + + # Strip any trailing slash from the destination. + func_stripname '' '/' "$dest" + dest=$func_stripname_result + + # Check to see that the destination is a directory. + test -d "$dest" && isdir=: + if $isdir; then + destdir=$dest + destname= + else + func_dirname_and_basename "$dest" "" "." + destdir=$func_dirname_result + destname=$func_basename_result + + # Not a directory, so check to see that there is only one file specified. + set dummy $files; shift + test "$#" -gt 1 && \ + func_fatal_help "'$dest' is not a directory" + fi + case $destdir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + for file in $files; do + case $file in + *.lo) ;; + *) + func_fatal_help "'$destdir' must be an absolute directory name" + ;; + esac + done + ;; + esac + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic=$magic + + staticlibs= + future_libdirs= + current_libdirs= + for file in $files; do + + # Do each installation. + case $file in + *.$libext) + # Do the static libraries later. + func_append staticlibs " $file" + ;; + + *.la) + func_resolve_sysroot "$file" + file=$func_resolve_sysroot_result + + # Check to see that this really is a libtool archive. + func_lalib_unsafe_p "$file" \ + || func_fatal_help "'$file' is not a valid libtool archive" + + library_names= + old_library= + relink_command= + func_source "$file" + + # Add the libdir to current_libdirs if it is the destination. + if test "X$destdir" = "X$libdir"; then + case "$current_libdirs " in + *" $libdir "*) ;; + *) func_append current_libdirs " $libdir" ;; + esac + else + # Note the libdir as a future libdir. + case "$future_libdirs " in + *" $libdir "*) ;; + *) func_append future_libdirs " $libdir" ;; + esac + fi + + func_dirname "$file" "/" "" + dir=$func_dirname_result + func_append dir "$objdir" + + if test -n "$relink_command"; then + # Determine the prefix the user has applied to our future dir. + inst_prefix_dir=`$ECHO "$destdir" | $SED -e "s%$libdir\$%%"` + + # Don't allow the user to place us outside of our expected + # location b/c this prevents finding dependent libraries that + # are installed to the same prefix. + # At present, this check doesn't affect windows .dll's that + # are installed into $libdir/../bin (currently, that works fine) + # but it's something to keep an eye on. + test "$inst_prefix_dir" = "$destdir" && \ + func_fatal_error "error: cannot install '$file' to a directory not ending in $libdir" + + if test -n "$inst_prefix_dir"; then + # Stick the inst_prefix_dir data into the link command. + relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"` + else + relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%%"` + fi + + func_warning "relinking '$file'" + func_show_eval "$relink_command" \ + 'func_fatal_error "error: relink '\''$file'\'' with the above command before installing it"' + fi + + # See the names of the shared library. + set dummy $library_names; shift + if test -n "$1"; then + realname=$1 + shift + + srcname=$realname + test -n "$relink_command" && srcname=${realname}T + + # Install the shared library and build the symlinks. + func_show_eval "$install_shared_prog $dir/$srcname $destdir/$realname" \ + 'exit $?' + tstripme=$stripme + case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + case $realname in + *.dll.a) + tstripme= + ;; + esac + ;; + os2*) + case $realname in + *_dll.a) + tstripme= + ;; + esac + ;; + esac + if test -n "$tstripme" && test -n "$striplib"; then + func_show_eval "$striplib $destdir/$realname" 'exit $?' + fi + + if test "$#" -gt 0; then + # Delete the old symlinks, and create new ones. + # Try 'ln -sf' first, because the 'ln' binary might depend on + # the symlink we replace! Solaris /bin/ln does not understand -f, + # so we also need to try rm && ln -s. + for linkname + do + test "$linkname" != "$realname" \ + && func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })" + done + fi + + # Do each command in the postinstall commands. + lib=$destdir/$realname + func_execute_cmds "$postinstall_cmds" 'exit $?' + fi + + # Install the pseudo-library for information purposes. + func_basename "$file" + name=$func_basename_result + instname=$dir/${name}i + func_show_eval "$install_prog $instname $destdir/$name" 'exit $?' + + # Maybe install the static library, too. + test -n "$old_library" && func_append staticlibs " $dir/$old_library" + ;; + + *.lo) + # Install (i.e. copy) a libtool object. + + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile=$destdir/$destname + else + func_basename "$file" + destfile=$func_basename_result + destfile=$destdir/$destfile + fi + + # Deduce the name of the destination old-style object file. + case $destfile in + *.lo) + func_lo2o "$destfile" + staticdest=$func_lo2o_result + ;; + *.$objext) + staticdest=$destfile + destfile= + ;; + *) + func_fatal_help "cannot copy a libtool object to '$destfile'" + ;; + esac + + # Install the libtool object if requested. + test -n "$destfile" && \ + func_show_eval "$install_prog $file $destfile" 'exit $?' + + # Install the old object if enabled. + if test yes = "$build_old_libs"; then + # Deduce the name of the old-style object file. + func_lo2o "$file" + staticobj=$func_lo2o_result + func_show_eval "$install_prog \$staticobj \$staticdest" 'exit $?' + fi + exit $EXIT_SUCCESS + ;; + + *) + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile=$destdir/$destname + else + func_basename "$file" + destfile=$func_basename_result + destfile=$destdir/$destfile + fi + + # If the file is missing, and there is a .exe on the end, strip it + # because it is most likely a libtool script we actually want to + # install + stripped_ext= + case $file in + *.exe) + if test ! -f "$file"; then + func_stripname '' '.exe' "$file" + file=$func_stripname_result + stripped_ext=.exe + fi + ;; + esac + + # Do a test to see if this is really a libtool program. + case $host in + *cygwin* | *mingw*) + if func_ltwrapper_executable_p "$file"; then + func_ltwrapper_scriptname "$file" + wrapper=$func_ltwrapper_scriptname_result + else + func_stripname '' '.exe' "$file" + wrapper=$func_stripname_result + fi + ;; + *) + wrapper=$file + ;; + esac + if func_ltwrapper_script_p "$wrapper"; then + notinst_deplibs= + relink_command= + + func_source "$wrapper" + + # Check the variables that should have been set. + test -z "$generated_by_libtool_version" && \ + func_fatal_error "invalid libtool wrapper script '$wrapper'" + + finalize=: + for lib in $notinst_deplibs; do + # Check to see that each library is installed. + libdir= + if test -f "$lib"; then + func_source "$lib" + fi + libfile=$libdir/`$ECHO "$lib" | $SED 's%^.*/%%g'` + if test -n "$libdir" && test ! -f "$libfile"; then + func_warning "'$lib' has not been installed in '$libdir'" + finalize=false + fi + done + + relink_command= + func_source "$wrapper" + + outputname= + if test no = "$fast_install" && test -n "$relink_command"; then + $opt_dry_run || { + if $finalize; then + tmpdir=`func_mktempdir` + func_basename "$file$stripped_ext" + file=$func_basename_result + outputname=$tmpdir/$file + # Replace the output file specification. + relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'` + + $opt_quiet || { + func_quote_for_expand "$relink_command" + eval "func_echo $func_quote_for_expand_result" + } + if eval "$relink_command"; then : + else + func_error "error: relink '$file' with the above command before installing it" + $opt_dry_run || ${RM}r "$tmpdir" + continue + fi + file=$outputname + else + func_warning "cannot relink '$file'" + fi + } + else + # Install the binary that we compiled earlier. + file=`$ECHO "$file$stripped_ext" | $SED "s%\([^/]*\)$%$objdir/\1%"` + fi + fi + + # remove .exe since cygwin /usr/bin/install will append another + # one anyway + case $install_prog,$host in + */usr/bin/install*,*cygwin*) + case $file:$destfile in + *.exe:*.exe) + # this is ok + ;; + *.exe:*) + destfile=$destfile.exe + ;; + *:*.exe) + func_stripname '' '.exe' "$destfile" + destfile=$func_stripname_result + ;; + esac + ;; + esac + func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?' + $opt_dry_run || if test -n "$outputname"; then + ${RM}r "$tmpdir" + fi + ;; + esac + done + + for file in $staticlibs; do + func_basename "$file" + name=$func_basename_result + + # Set up the ranlib parameters. + oldlib=$destdir/$name + func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 + tool_oldlib=$func_to_tool_file_result + + func_show_eval "$install_prog \$file \$oldlib" 'exit $?' + + if test -n "$stripme" && test -n "$old_striplib"; then + func_show_eval "$old_striplib $tool_oldlib" 'exit $?' + fi + + # Do each command in the postinstall commands. + func_execute_cmds "$old_postinstall_cmds" 'exit $?' + done + + test -n "$future_libdirs" && \ + func_warning "remember to run '$progname --finish$future_libdirs'" + + if test -n "$current_libdirs"; then + # Maybe just do a dry run. + $opt_dry_run && current_libdirs=" -n$current_libdirs" + exec_cmd='$SHELL "$progpath" $preserve_args --finish$current_libdirs' + else + exit $EXIT_SUCCESS + fi +} + +test install = "$opt_mode" && func_mode_install ${1+"$@"} + + +# func_generate_dlsyms outputname originator pic_p +# Extract symbols from dlprefiles and create ${outputname}S.o with +# a dlpreopen symbol table. +func_generate_dlsyms () +{ + $debug_cmd + + my_outputname=$1 + my_originator=$2 + my_pic_p=${3-false} + my_prefix=`$ECHO "$my_originator" | $SED 's%[^a-zA-Z0-9]%_%g'` + my_dlsyms= + + if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then + if test -n "$NM" && test -n "$global_symbol_pipe"; then + my_dlsyms=${my_outputname}S.c + else + func_error "not configured to extract global symbols from dlpreopened files" + fi + fi + + if test -n "$my_dlsyms"; then + case $my_dlsyms in + "") ;; + *.c) + # Discover the nlist of each of the dlfiles. + nlist=$output_objdir/$my_outputname.nm + + func_show_eval "$RM $nlist ${nlist}S ${nlist}T" + + # Parse the name list into a source file. + func_verbose "creating $output_objdir/$my_dlsyms" + + $opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\ +/* $my_dlsyms - symbol resolution table for '$my_outputname' dlsym emulation. */ +/* Generated by $PROGRAM (GNU $PACKAGE) $VERSION */ + +#ifdef __cplusplus +extern \"C\" { +#endif + +#if defined __GNUC__ && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4)) +#pragma GCC diagnostic ignored \"-Wstrict-prototypes\" +#endif + +/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ +#if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE +/* DATA imports from DLLs on WIN32 can't be const, because runtime + relocations are performed -- see ld's documentation on pseudo-relocs. */ +# define LT_DLSYM_CONST +#elif defined __osf__ +/* This system does not cope well with relocations in const data. */ +# define LT_DLSYM_CONST +#else +# define LT_DLSYM_CONST const +#endif + +#define STREQ(s1, s2) (strcmp ((s1), (s2)) == 0) + +/* External symbol declarations for the compiler. */\ +" + + if test yes = "$dlself"; then + func_verbose "generating symbol list for '$output'" + + $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist" + + # Add our own program objects to the symbol list. + progfiles=`$ECHO "$objs$old_deplibs" | $SP2NL | $SED "$lo2o" | $NL2SP` + for progfile in $progfiles; do + func_to_tool_file "$progfile" func_convert_file_msys_to_w32 + func_verbose "extracting global C symbols from '$func_to_tool_file_result'" + $opt_dry_run || eval "$NM $func_to_tool_file_result | $global_symbol_pipe >> '$nlist'" + done + + if test -n "$exclude_expsyms"; then + $opt_dry_run || { + eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' + eval '$MV "$nlist"T "$nlist"' + } + fi + + if test -n "$export_symbols_regex"; then + $opt_dry_run || { + eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T' + eval '$MV "$nlist"T "$nlist"' + } + fi + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + export_symbols=$output_objdir/$outputname.exp + $opt_dry_run || { + $RM $export_symbols + eval "$SED -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' + case $host in + *cygwin* | *mingw* | *cegcc* ) + eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' + eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"' + ;; + esac + } + else + $opt_dry_run || { + eval "$SED -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"' + eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T' + eval '$MV "$nlist"T "$nlist"' + case $host in + *cygwin* | *mingw* | *cegcc* ) + eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' + eval 'cat "$nlist" >> "$output_objdir/$outputname.def"' + ;; + esac + } + fi + fi + + for dlprefile in $dlprefiles; do + func_verbose "extracting global C symbols from '$dlprefile'" + func_basename "$dlprefile" + name=$func_basename_result + case $host in + *cygwin* | *mingw* | *cegcc* ) + # if an import library, we need to obtain dlname + if func_win32_import_lib_p "$dlprefile"; then + func_tr_sh "$dlprefile" + eval "curr_lafile=\$libfile_$func_tr_sh_result" + dlprefile_dlbasename= + if test -n "$curr_lafile" && func_lalib_p "$curr_lafile"; then + # Use subshell, to avoid clobbering current variable values + dlprefile_dlname=`source "$curr_lafile" && echo "$dlname"` + if test -n "$dlprefile_dlname"; then + func_basename "$dlprefile_dlname" + dlprefile_dlbasename=$func_basename_result + else + # no lafile. user explicitly requested -dlpreopen . + $sharedlib_from_linklib_cmd "$dlprefile" + dlprefile_dlbasename=$sharedlib_from_linklib_result + fi + fi + $opt_dry_run || { + if test -n "$dlprefile_dlbasename"; then + eval '$ECHO ": $dlprefile_dlbasename" >> "$nlist"' + else + func_warning "Could not compute DLL name from $name" + eval '$ECHO ": $name " >> "$nlist"' + fi + func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 + eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe | + $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/_nm__//' >> '$nlist'" + } + else # not an import lib + $opt_dry_run || { + eval '$ECHO ": $name " >> "$nlist"' + func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 + eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" + } + fi + ;; + *) + $opt_dry_run || { + eval '$ECHO ": $name " >> "$nlist"' + func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 + eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" + } + ;; + esac + done + + $opt_dry_run || { + # Make sure we have at least an empty file. + test -f "$nlist" || : > "$nlist" + + if test -n "$exclude_expsyms"; then + $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T + $MV "$nlist"T "$nlist" + fi + + # Try sorting and uniquifying the output. + if $GREP -v "^: " < "$nlist" | + if sort -k 3 /dev/null 2>&1; then + sort -k 3 + else + sort +2 + fi | + uniq > "$nlist"S; then + : + else + $GREP -v "^: " < "$nlist" > "$nlist"S + fi + + if test -f "$nlist"S; then + eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"' + else + echo '/* NONE */' >> "$output_objdir/$my_dlsyms" + fi + + func_show_eval '$RM "${nlist}I"' + if test -n "$global_symbol_to_import"; then + eval "$global_symbol_to_import"' < "$nlist"S > "$nlist"I' + fi + + echo >> "$output_objdir/$my_dlsyms" "\ + +/* The mapping between symbol names and symbols. */ +typedef struct { + const char *name; + void *address; +} lt_dlsymlist; +extern LT_DLSYM_CONST lt_dlsymlist +lt_${my_prefix}_LTX_preloaded_symbols[];\ +" + + if test -s "$nlist"I; then + echo >> "$output_objdir/$my_dlsyms" "\ +static void lt_syminit(void) +{ + LT_DLSYM_CONST lt_dlsymlist *symbol = lt_${my_prefix}_LTX_preloaded_symbols; + for (; symbol->name; ++symbol) + {" + $SED 's/.*/ if (STREQ (symbol->name, \"&\")) symbol->address = (void *) \&&;/' < "$nlist"I >> "$output_objdir/$my_dlsyms" + echo >> "$output_objdir/$my_dlsyms" "\ + } +}" + fi + echo >> "$output_objdir/$my_dlsyms" "\ +LT_DLSYM_CONST lt_dlsymlist +lt_${my_prefix}_LTX_preloaded_symbols[] = +{ {\"$my_originator\", (void *) 0}," + + if test -s "$nlist"I; then + echo >> "$output_objdir/$my_dlsyms" "\ + {\"@INIT@\", (void *) <_syminit}," + fi + + case $need_lib_prefix in + no) + eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms" + ;; + *) + eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms" + ;; + esac + echo >> "$output_objdir/$my_dlsyms" "\ + {0, (void *) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt_${my_prefix}_LTX_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif\ +" + } # !$opt_dry_run + + pic_flag_for_symtable= + case "$compile_command " in + *" -static "*) ;; + *) + case $host in + # compiling the symbol table file with pic_flag works around + # a FreeBSD bug that causes programs to crash when -lm is + # linked before any other PIC object. But we must not use + # pic_flag when linking with -static. The problem exists in + # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. + *-*-freebsd2.*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) + pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;; + *-*-hpux*) + pic_flag_for_symtable=" $pic_flag" ;; + *) + $my_pic_p && pic_flag_for_symtable=" $pic_flag" + ;; + esac + ;; + esac + symtab_cflags= + for arg in $LTCFLAGS; do + case $arg in + -pie | -fpie | -fPIE) ;; + *) func_append symtab_cflags " $arg" ;; + esac + done + + # Now compile the dynamic symbol file. + func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?' + + # Clean up the generated files. + func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T" "${nlist}I"' + + # Transform the symbol file into the correct name. + symfileobj=$output_objdir/${my_outputname}S.$objext + case $host in + *cygwin* | *mingw* | *cegcc* ) + if test -f "$output_objdir/$my_outputname.def"; then + compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` + finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` + else + compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` + finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` + fi + ;; + *) + compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` + finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` + ;; + esac + ;; + *) + func_fatal_error "unknown suffix for '$my_dlsyms'" + ;; + esac + else + # We keep going just in case the user didn't refer to + # lt_preloaded_symbols. The linker will fail if global_symbol_pipe + # really was required. + + # Nullify the symbol file. + compile_command=`$ECHO "$compile_command" | $SED "s% @SYMFILE@%%"` + finalize_command=`$ECHO "$finalize_command" | $SED "s% @SYMFILE@%%"` + fi +} + +# func_cygming_gnu_implib_p ARG +# This predicate returns with zero status (TRUE) if +# ARG is a GNU/binutils-style import library. Returns +# with nonzero status (FALSE) otherwise. +func_cygming_gnu_implib_p () +{ + $debug_cmd + + func_to_tool_file "$1" func_convert_file_msys_to_w32 + func_cygming_gnu_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $EGREP ' (_head_[A-Za-z0-9_]+_[ad]l*|[A-Za-z0-9_]+_[ad]l*_iname)$'` + test -n "$func_cygming_gnu_implib_tmp" +} + +# func_cygming_ms_implib_p ARG +# This predicate returns with zero status (TRUE) if +# ARG is an MS-style import library. Returns +# with nonzero status (FALSE) otherwise. +func_cygming_ms_implib_p () +{ + $debug_cmd + + func_to_tool_file "$1" func_convert_file_msys_to_w32 + func_cygming_ms_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $GREP '_NULL_IMPORT_DESCRIPTOR'` + test -n "$func_cygming_ms_implib_tmp" +} + +# func_win32_libid arg +# return the library type of file 'arg' +# +# Need a lot of goo to handle *both* DLLs and import libs +# Has to be a shell function in order to 'eat' the argument +# that is supplied when $file_magic_command is called. +# Despite the name, also deal with 64 bit binaries. +func_win32_libid () +{ + $debug_cmd + + win32_libid_type=unknown + win32_fileres=`file -L $1 2>/dev/null` + case $win32_fileres in + *ar\ archive\ import\ library*) # definitely import + win32_libid_type="x86 archive import" + ;; + *ar\ archive*) # could be an import, or static + # Keep the egrep pattern in sync with the one in _LT_CHECK_MAGIC_METHOD. + if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | + $EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' >/dev/null; then + case $nm_interface in + "MS dumpbin") + if func_cygming_ms_implib_p "$1" || + func_cygming_gnu_implib_p "$1" + then + win32_nmres=import + else + win32_nmres= + fi + ;; + *) + func_to_tool_file "$1" func_convert_file_msys_to_w32 + win32_nmres=`eval $NM -f posix -A \"$func_to_tool_file_result\" | + $SED -n -e ' + 1,100{ + / I /{ + s|.*|import| + p + q + } + }'` + ;; + esac + case $win32_nmres in + import*) win32_libid_type="x86 archive import";; + *) win32_libid_type="x86 archive static";; + esac + fi + ;; + *DLL*) + win32_libid_type="x86 DLL" + ;; + *executable*) # but shell scripts are "executable" too... + case $win32_fileres in + *MS\ Windows\ PE\ Intel*) + win32_libid_type="x86 DLL" + ;; + esac + ;; + esac + $ECHO "$win32_libid_type" +} + +# func_cygming_dll_for_implib ARG +# +# Platform-specific function to extract the +# name of the DLL associated with the specified +# import library ARG. +# Invoked by eval'ing the libtool variable +# $sharedlib_from_linklib_cmd +# Result is available in the variable +# $sharedlib_from_linklib_result +func_cygming_dll_for_implib () +{ + $debug_cmd + + sharedlib_from_linklib_result=`$DLLTOOL --identify-strict --identify "$1"` +} + +# func_cygming_dll_for_implib_fallback_core SECTION_NAME LIBNAMEs +# +# The is the core of a fallback implementation of a +# platform-specific function to extract the name of the +# DLL associated with the specified import library LIBNAME. +# +# SECTION_NAME is either .idata$6 or .idata$7, depending +# on the platform and compiler that created the implib. +# +# Echos the name of the DLL associated with the +# specified import library. +func_cygming_dll_for_implib_fallback_core () +{ + $debug_cmd + + match_literal=`$ECHO "$1" | $SED "$sed_make_literal_regex"` + $OBJDUMP -s --section "$1" "$2" 2>/dev/null | + $SED '/^Contents of section '"$match_literal"':/{ + # Place marker at beginning of archive member dllname section + s/.*/====MARK====/ + p + d + } + # These lines can sometimes be longer than 43 characters, but + # are always uninteresting + /:[ ]*file format pe[i]\{,1\}-/d + /^In archive [^:]*:/d + # Ensure marker is printed + /^====MARK====/p + # Remove all lines with less than 43 characters + /^.\{43\}/!d + # From remaining lines, remove first 43 characters + s/^.\{43\}//' | + $SED -n ' + # Join marker and all lines until next marker into a single line + /^====MARK====/ b para + H + $ b para + b + :para + x + s/\n//g + # Remove the marker + s/^====MARK====// + # Remove trailing dots and whitespace + s/[\. \t]*$// + # Print + /./p' | + # we now have a list, one entry per line, of the stringified + # contents of the appropriate section of all members of the + # archive that possess that section. Heuristic: eliminate + # all those that have a first or second character that is + # a '.' (that is, objdump's representation of an unprintable + # character.) This should work for all archives with less than + # 0x302f exports -- but will fail for DLLs whose name actually + # begins with a literal '.' or a single character followed by + # a '.'. + # + # Of those that remain, print the first one. + $SED -e '/^\./d;/^.\./d;q' +} + +# func_cygming_dll_for_implib_fallback ARG +# Platform-specific function to extract the +# name of the DLL associated with the specified +# import library ARG. +# +# This fallback implementation is for use when $DLLTOOL +# does not support the --identify-strict option. +# Invoked by eval'ing the libtool variable +# $sharedlib_from_linklib_cmd +# Result is available in the variable +# $sharedlib_from_linklib_result +func_cygming_dll_for_implib_fallback () +{ + $debug_cmd + + if func_cygming_gnu_implib_p "$1"; then + # binutils import library + sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$7' "$1"` + elif func_cygming_ms_implib_p "$1"; then + # ms-generated import library + sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$6' "$1"` + else + # unknown + sharedlib_from_linklib_result= + fi +} + + +# func_extract_an_archive dir oldlib +func_extract_an_archive () +{ + $debug_cmd + + f_ex_an_ar_dir=$1; shift + f_ex_an_ar_oldlib=$1 + if test yes = "$lock_old_archive_extraction"; then + lockfile=$f_ex_an_ar_oldlib.lock + until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do + func_echo "Waiting for $lockfile to be removed" + sleep 2 + done + fi + func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" \ + 'stat=$?; rm -f "$lockfile"; exit $stat' + if test yes = "$lock_old_archive_extraction"; then + $opt_dry_run || rm -f "$lockfile" + fi + if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then + : + else + func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib" + fi +} + + +# func_extract_archives gentop oldlib ... +func_extract_archives () +{ + $debug_cmd + + my_gentop=$1; shift + my_oldlibs=${1+"$@"} + my_oldobjs= + my_xlib= + my_xabs= + my_xdir= + + for my_xlib in $my_oldlibs; do + # Extract the objects. + case $my_xlib in + [\\/]* | [A-Za-z]:[\\/]*) my_xabs=$my_xlib ;; + *) my_xabs=`pwd`"/$my_xlib" ;; + esac + func_basename "$my_xlib" + my_xlib=$func_basename_result + my_xlib_u=$my_xlib + while :; do + case " $extracted_archives " in + *" $my_xlib_u "*) + func_arith $extracted_serial + 1 + extracted_serial=$func_arith_result + my_xlib_u=lt$extracted_serial-$my_xlib ;; + *) break ;; + esac + done + extracted_archives="$extracted_archives $my_xlib_u" + my_xdir=$my_gentop/$my_xlib_u + + func_mkdir_p "$my_xdir" + + case $host in + *-darwin*) + func_verbose "Extracting $my_xabs" + # Do not bother doing anything if just a dry run + $opt_dry_run || { + darwin_orig_dir=`pwd` + cd $my_xdir || exit $? + darwin_archive=$my_xabs + darwin_curdir=`pwd` + func_basename "$darwin_archive" + darwin_base_archive=$func_basename_result + darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true` + if test -n "$darwin_arches"; then + darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'` + darwin_arch= + func_verbose "$darwin_base_archive has multiple architectures $darwin_arches" + for darwin_arch in $darwin_arches; do + func_mkdir_p "unfat-$$/$darwin_base_archive-$darwin_arch" + $LIPO -thin $darwin_arch -output "unfat-$$/$darwin_base_archive-$darwin_arch/$darwin_base_archive" "$darwin_archive" + cd "unfat-$$/$darwin_base_archive-$darwin_arch" + func_extract_an_archive "`pwd`" "$darwin_base_archive" + cd "$darwin_curdir" + $RM "unfat-$$/$darwin_base_archive-$darwin_arch/$darwin_base_archive" + done # $darwin_arches + ## Okay now we've a bunch of thin objects, gotta fatten them up :) + darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$sed_basename" | sort -u` + darwin_file= + darwin_files= + for darwin_file in $darwin_filelist; do + darwin_files=`find unfat-$$ -name $darwin_file -print | sort | $NL2SP` + $LIPO -create -output "$darwin_file" $darwin_files + done # $darwin_filelist + $RM -rf unfat-$$ + cd "$darwin_orig_dir" + else + cd $darwin_orig_dir + func_extract_an_archive "$my_xdir" "$my_xabs" + fi # $darwin_arches + } # !$opt_dry_run + ;; + *) + func_extract_an_archive "$my_xdir" "$my_xabs" + ;; + esac + my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | sort | $NL2SP` + done + + func_extract_archives_result=$my_oldobjs +} + + +# func_emit_wrapper [arg=no] +# +# Emit a libtool wrapper script on stdout. +# Don't directly open a file because we may want to +# incorporate the script contents within a cygwin/mingw +# wrapper executable. Must ONLY be called from within +# func_mode_link because it depends on a number of variables +# set therein. +# +# ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR +# variable will take. If 'yes', then the emitted script +# will assume that the directory where it is stored is +# the $objdir directory. This is a cygwin/mingw-specific +# behavior. +func_emit_wrapper () +{ + func_emit_wrapper_arg1=${1-no} + + $ECHO "\ +#! $SHELL + +# $output - temporary wrapper script for $objdir/$outputname +# Generated by $PROGRAM (GNU $PACKAGE) $VERSION +# +# The $output program cannot be directly executed until all the libtool +# libraries that it depends on are installed. +# +# This wrapper script should never be moved out of the build directory. +# If it is, it will not operate correctly. + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +sed_quote_subst='$sed_quote_subst' + +# Be Bourne compatible +if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else + case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac +fi +BIN_SH=xpg4; export BIN_SH # for Tru64 +DUALCASE=1; export DUALCASE # for MKS sh + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +relink_command=\"$relink_command\" + +# This environment variable determines our operation mode. +if test \"\$libtool_install_magic\" = \"$magic\"; then + # install mode needs the following variables: + generated_by_libtool_version='$macro_version' + notinst_deplibs='$notinst_deplibs' +else + # When we are sourced in execute mode, \$file and \$ECHO are already set. + if test \"\$libtool_execute_magic\" != \"$magic\"; then + file=\"\$0\"" + + qECHO=`$ECHO "$ECHO" | $SED "$sed_quote_subst"` + $ECHO "\ + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +\$1 +_LTECHO_EOF' +} + ECHO=\"$qECHO\" + fi + +# Very basic option parsing. These options are (a) specific to +# the libtool wrapper, (b) are identical between the wrapper +# /script/ and the wrapper /executable/ that is used only on +# windows platforms, and (c) all begin with the string "--lt-" +# (application programs are unlikely to have options that match +# this pattern). +# +# There are only two supported options: --lt-debug and +# --lt-dump-script. There is, deliberately, no --lt-help. +# +# The first argument to this parsing function should be the +# script's $0 value, followed by "$@". +lt_option_debug= +func_parse_lt_options () +{ + lt_script_arg0=\$0 + shift + for lt_opt + do + case \"\$lt_opt\" in + --lt-debug) lt_option_debug=1 ;; + --lt-dump-script) + lt_dump_D=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%/[^/]*$%%'\` + test \"X\$lt_dump_D\" = \"X\$lt_script_arg0\" && lt_dump_D=. + lt_dump_F=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%^.*/%%'\` + cat \"\$lt_dump_D/\$lt_dump_F\" + exit 0 + ;; + --lt-*) + \$ECHO \"Unrecognized --lt- option: '\$lt_opt'\" 1>&2 + exit 1 + ;; + esac + done + + # Print the debug banner immediately: + if test -n \"\$lt_option_debug\"; then + echo \"$outputname:$output:\$LINENO: libtool wrapper (GNU $PACKAGE) $VERSION\" 1>&2 + fi +} + +# Used when --lt-debug. Prints its arguments to stdout +# (redirection is the responsibility of the caller) +func_lt_dump_args () +{ + lt_dump_args_N=1; + for lt_arg + do + \$ECHO \"$outputname:$output:\$LINENO: newargv[\$lt_dump_args_N]: \$lt_arg\" + lt_dump_args_N=\`expr \$lt_dump_args_N + 1\` + done +} + +# Core function for launching the target application +func_exec_program_core () +{ +" + case $host in + # Backslashes separate directories on plain windows + *-*-mingw | *-*-os2* | *-cegcc*) + $ECHO "\ + if test -n \"\$lt_option_debug\"; then + \$ECHO \"$outputname:$output:\$LINENO: newargv[0]: \$progdir\\\\\$program\" 1>&2 + func_lt_dump_args \${1+\"\$@\"} 1>&2 + fi + exec \"\$progdir\\\\\$program\" \${1+\"\$@\"} +" + ;; + + *) + $ECHO "\ + if test -n \"\$lt_option_debug\"; then + \$ECHO \"$outputname:$output:\$LINENO: newargv[0]: \$progdir/\$program\" 1>&2 + func_lt_dump_args \${1+\"\$@\"} 1>&2 + fi + exec \"\$progdir/\$program\" \${1+\"\$@\"} +" + ;; + esac + $ECHO "\ + \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2 + exit 1 +} + +# A function to encapsulate launching the target application +# Strips options in the --lt-* namespace from \$@ and +# launches target application with the remaining arguments. +func_exec_program () +{ + case \" \$* \" in + *\\ --lt-*) + for lt_wr_arg + do + case \$lt_wr_arg in + --lt-*) ;; + *) set x \"\$@\" \"\$lt_wr_arg\"; shift;; + esac + shift + done ;; + esac + func_exec_program_core \${1+\"\$@\"} +} + + # Parse options + func_parse_lt_options \"\$0\" \${1+\"\$@\"} + + # Find the directory that this script lives in. + thisdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*$%%'\` + test \"x\$thisdir\" = \"x\$file\" && thisdir=. + + # Follow symbolic links until we get to the real thisdir. + file=\`ls -ld \"\$file\" | $SED -n 's/.*-> //p'\` + while test -n \"\$file\"; do + destdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*\$%%'\` + + # If there was a directory component, then change thisdir. + if test \"x\$destdir\" != \"x\$file\"; then + case \"\$destdir\" in + [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;; + *) thisdir=\"\$thisdir/\$destdir\" ;; + esac + fi + + file=\`\$ECHO \"\$file\" | $SED 's%^.*/%%'\` + file=\`ls -ld \"\$thisdir/\$file\" | $SED -n 's/.*-> //p'\` + done + + # Usually 'no', except on cygwin/mingw when embedded into + # the cwrapper. + WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_arg1 + if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then + # special case for '.' + if test \"\$thisdir\" = \".\"; then + thisdir=\`pwd\` + fi + # remove .libs from thisdir + case \"\$thisdir\" in + *[\\\\/]$objdir ) thisdir=\`\$ECHO \"\$thisdir\" | $SED 's%[\\\\/][^\\\\/]*$%%'\` ;; + $objdir ) thisdir=. ;; + esac + fi + + # Try to get the absolute directory name. + absdir=\`cd \"\$thisdir\" && pwd\` + test -n \"\$absdir\" && thisdir=\"\$absdir\" +" + + if test yes = "$fast_install"; then + $ECHO "\ + program=lt-'$outputname'$exeext + progdir=\"\$thisdir/$objdir\" + + if test ! -f \"\$progdir/\$program\" || + { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | $SED 1q\`; \\ + test \"X\$file\" != \"X\$progdir/\$program\"; }; then + + file=\"\$\$-\$program\" + + if test ! -d \"\$progdir\"; then + $MKDIR \"\$progdir\" + else + $RM \"\$progdir/\$file\" + fi" + + $ECHO "\ + + # relink executable if necessary + if test -n \"\$relink_command\"; then + if relink_command_output=\`eval \$relink_command 2>&1\`; then : + else + \$ECHO \"\$relink_command_output\" >&2 + $RM \"\$progdir/\$file\" + exit 1 + fi + fi + + $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || + { $RM \"\$progdir/\$program\"; + $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; } + $RM \"\$progdir/\$file\" + fi" + else + $ECHO "\ + program='$outputname' + progdir=\"\$thisdir/$objdir\" +" + fi + + $ECHO "\ + + if test -f \"\$progdir/\$program\"; then" + + # fixup the dll searchpath if we need to. + # + # Fix the DLL searchpath if we need to. Do this before prepending + # to shlibpath, because on Windows, both are PATH and uninstalled + # libraries must come first. + if test -n "$dllsearchpath"; then + $ECHO "\ + # Add the dll search path components to the executable PATH + PATH=$dllsearchpath:\$PATH +" + fi + + # Export our shlibpath_var if we have one. + if test yes = "$shlibpath_overrides_runpath" && test -n "$shlibpath_var" && test -n "$temp_rpath"; then + $ECHO "\ + # Add our own library path to $shlibpath_var + $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" + + # Some systems cannot cope with colon-terminated $shlibpath_var + # The second colon is a workaround for a bug in BeOS R4 sed + $shlibpath_var=\`\$ECHO \"\$$shlibpath_var\" | $SED 's/::*\$//'\` + + export $shlibpath_var +" + fi + + $ECHO "\ + if test \"\$libtool_execute_magic\" != \"$magic\"; then + # Run the actual program with our arguments. + func_exec_program \${1+\"\$@\"} + fi + else + # The program doesn't exist. + \$ECHO \"\$0: error: '\$progdir/\$program' does not exist\" 1>&2 + \$ECHO \"This script is just a wrapper for \$program.\" 1>&2 + \$ECHO \"See the $PACKAGE documentation for more information.\" 1>&2 + exit 1 + fi +fi\ +" +} + + +# func_emit_cwrapperexe_src +# emit the source code for a wrapper executable on stdout +# Must ONLY be called from within func_mode_link because +# it depends on a number of variable set therein. +func_emit_cwrapperexe_src () +{ + cat < +#include +#ifdef _MSC_VER +# include +# include +# include +#else +# include +# include +# ifdef __CYGWIN__ +# include +# endif +#endif +#include +#include +#include +#include +#include +#include +#include +#include + +#define STREQ(s1, s2) (strcmp ((s1), (s2)) == 0) + +/* declarations of non-ANSI functions */ +#if defined __MINGW32__ +# ifdef __STRICT_ANSI__ +int _putenv (const char *); +# endif +#elif defined __CYGWIN__ +# ifdef __STRICT_ANSI__ +char *realpath (const char *, char *); +int putenv (char *); +int setenv (const char *, const char *, int); +# endif +/* #elif defined other_platform || defined ... */ +#endif + +/* portability defines, excluding path handling macros */ +#if defined _MSC_VER +# define setmode _setmode +# define stat _stat +# define chmod _chmod +# define getcwd _getcwd +# define putenv _putenv +# define S_IXUSR _S_IEXEC +#elif defined __MINGW32__ +# define setmode _setmode +# define stat _stat +# define chmod _chmod +# define getcwd _getcwd +# define putenv _putenv +#elif defined __CYGWIN__ +# define HAVE_SETENV +# define FOPEN_WB "wb" +/* #elif defined other platforms ... */ +#endif + +#if defined PATH_MAX +# define LT_PATHMAX PATH_MAX +#elif defined MAXPATHLEN +# define LT_PATHMAX MAXPATHLEN +#else +# define LT_PATHMAX 1024 +#endif + +#ifndef S_IXOTH +# define S_IXOTH 0 +#endif +#ifndef S_IXGRP +# define S_IXGRP 0 +#endif + +/* path handling portability macros */ +#ifndef DIR_SEPARATOR +# define DIR_SEPARATOR '/' +# define PATH_SEPARATOR ':' +#endif + +#if defined _WIN32 || defined __MSDOS__ || defined __DJGPP__ || \ + defined __OS2__ +# define HAVE_DOS_BASED_FILE_SYSTEM +# define FOPEN_WB "wb" +# ifndef DIR_SEPARATOR_2 +# define DIR_SEPARATOR_2 '\\' +# endif +# ifndef PATH_SEPARATOR_2 +# define PATH_SEPARATOR_2 ';' +# endif +#endif + +#ifndef DIR_SEPARATOR_2 +# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR) +#else /* DIR_SEPARATOR_2 */ +# define IS_DIR_SEPARATOR(ch) \ + (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2)) +#endif /* DIR_SEPARATOR_2 */ + +#ifndef PATH_SEPARATOR_2 +# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR) +#else /* PATH_SEPARATOR_2 */ +# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2) +#endif /* PATH_SEPARATOR_2 */ + +#ifndef FOPEN_WB +# define FOPEN_WB "w" +#endif +#ifndef _O_BINARY +# define _O_BINARY 0 +#endif + +#define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type))) +#define XFREE(stale) do { \ + if (stale) { free (stale); stale = 0; } \ +} while (0) + +#if defined LT_DEBUGWRAPPER +static int lt_debug = 1; +#else +static int lt_debug = 0; +#endif + +const char *program_name = "libtool-wrapper"; /* in case xstrdup fails */ + +void *xmalloc (size_t num); +char *xstrdup (const char *string); +const char *base_name (const char *name); +char *find_executable (const char *wrapper); +char *chase_symlinks (const char *pathspec); +int make_executable (const char *path); +int check_executable (const char *path); +char *strendzap (char *str, const char *pat); +void lt_debugprintf (const char *file, int line, const char *fmt, ...); +void lt_fatal (const char *file, int line, const char *message, ...); +static const char *nonnull (const char *s); +static const char *nonempty (const char *s); +void lt_setenv (const char *name, const char *value); +char *lt_extend_str (const char *orig_value, const char *add, int to_end); +void lt_update_exe_path (const char *name, const char *value); +void lt_update_lib_path (const char *name, const char *value); +char **prepare_spawn (char **argv); +void lt_dump_script (FILE *f); +EOF + + cat <= 0) + && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) + return 1; + else + return 0; +} + +int +make_executable (const char *path) +{ + int rval = 0; + struct stat st; + + lt_debugprintf (__FILE__, __LINE__, "(make_executable): %s\n", + nonempty (path)); + if ((!path) || (!*path)) + return 0; + + if (stat (path, &st) >= 0) + { + rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR); + } + return rval; +} + +/* Searches for the full path of the wrapper. Returns + newly allocated full path name if found, NULL otherwise + Does not chase symlinks, even on platforms that support them. +*/ +char * +find_executable (const char *wrapper) +{ + int has_slash = 0; + const char *p; + const char *p_next; + /* static buffer for getcwd */ + char tmp[LT_PATHMAX + 1]; + size_t tmp_len; + char *concat_name; + + lt_debugprintf (__FILE__, __LINE__, "(find_executable): %s\n", + nonempty (wrapper)); + + if ((wrapper == NULL) || (*wrapper == '\0')) + return NULL; + + /* Absolute path? */ +#if defined HAVE_DOS_BASED_FILE_SYSTEM + if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':') + { + concat_name = xstrdup (wrapper); + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + } + else + { +#endif + if (IS_DIR_SEPARATOR (wrapper[0])) + { + concat_name = xstrdup (wrapper); + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + } +#if defined HAVE_DOS_BASED_FILE_SYSTEM + } +#endif + + for (p = wrapper; *p; p++) + if (*p == '/') + { + has_slash = 1; + break; + } + if (!has_slash) + { + /* no slashes; search PATH */ + const char *path = getenv ("PATH"); + if (path != NULL) + { + for (p = path; *p; p = p_next) + { + const char *q; + size_t p_len; + for (q = p; *q; q++) + if (IS_PATH_SEPARATOR (*q)) + break; + p_len = (size_t) (q - p); + p_next = (*q == '\0' ? q : q + 1); + if (p_len == 0) + { + /* empty path: current directory */ + if (getcwd (tmp, LT_PATHMAX) == NULL) + lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", + nonnull (strerror (errno))); + tmp_len = strlen (tmp); + concat_name = + XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); + memcpy (concat_name, tmp, tmp_len); + concat_name[tmp_len] = '/'; + strcpy (concat_name + tmp_len + 1, wrapper); + } + else + { + concat_name = + XMALLOC (char, p_len + 1 + strlen (wrapper) + 1); + memcpy (concat_name, p, p_len); + concat_name[p_len] = '/'; + strcpy (concat_name + p_len + 1, wrapper); + } + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + } + } + /* not found in PATH; assume curdir */ + } + /* Relative path | not found in path: prepend cwd */ + if (getcwd (tmp, LT_PATHMAX) == NULL) + lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", + nonnull (strerror (errno))); + tmp_len = strlen (tmp); + concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); + memcpy (concat_name, tmp, tmp_len); + concat_name[tmp_len] = '/'; + strcpy (concat_name + tmp_len + 1, wrapper); + + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + return NULL; +} + +char * +chase_symlinks (const char *pathspec) +{ +#ifndef S_ISLNK + return xstrdup (pathspec); +#else + char buf[LT_PATHMAX]; + struct stat s; + char *tmp_pathspec = xstrdup (pathspec); + char *p; + int has_symlinks = 0; + while (strlen (tmp_pathspec) && !has_symlinks) + { + lt_debugprintf (__FILE__, __LINE__, + "checking path component for symlinks: %s\n", + tmp_pathspec); + if (lstat (tmp_pathspec, &s) == 0) + { + if (S_ISLNK (s.st_mode) != 0) + { + has_symlinks = 1; + break; + } + + /* search backwards for last DIR_SEPARATOR */ + p = tmp_pathspec + strlen (tmp_pathspec) - 1; + while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) + p--; + if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) + { + /* no more DIR_SEPARATORS left */ + break; + } + *p = '\0'; + } + else + { + lt_fatal (__FILE__, __LINE__, + "error accessing file \"%s\": %s", + tmp_pathspec, nonnull (strerror (errno))); + } + } + XFREE (tmp_pathspec); + + if (!has_symlinks) + { + return xstrdup (pathspec); + } + + tmp_pathspec = realpath (pathspec, buf); + if (tmp_pathspec == 0) + { + lt_fatal (__FILE__, __LINE__, + "could not follow symlinks for %s", pathspec); + } + return xstrdup (tmp_pathspec); +#endif +} + +char * +strendzap (char *str, const char *pat) +{ + size_t len, patlen; + + assert (str != NULL); + assert (pat != NULL); + + len = strlen (str); + patlen = strlen (pat); + + if (patlen <= len) + { + str += len - patlen; + if (STREQ (str, pat)) + *str = '\0'; + } + return str; +} + +void +lt_debugprintf (const char *file, int line, const char *fmt, ...) +{ + va_list args; + if (lt_debug) + { + (void) fprintf (stderr, "%s:%s:%d: ", program_name, file, line); + va_start (args, fmt); + (void) vfprintf (stderr, fmt, args); + va_end (args); + } +} + +static void +lt_error_core (int exit_status, const char *file, + int line, const char *mode, + const char *message, va_list ap) +{ + fprintf (stderr, "%s:%s:%d: %s: ", program_name, file, line, mode); + vfprintf (stderr, message, ap); + fprintf (stderr, ".\n"); + + if (exit_status >= 0) + exit (exit_status); +} + +void +lt_fatal (const char *file, int line, const char *message, ...) +{ + va_list ap; + va_start (ap, message); + lt_error_core (EXIT_FAILURE, file, line, "FATAL", message, ap); + va_end (ap); +} + +static const char * +nonnull (const char *s) +{ + return s ? s : "(null)"; +} + +static const char * +nonempty (const char *s) +{ + return (s && !*s) ? "(empty)" : nonnull (s); +} + +void +lt_setenv (const char *name, const char *value) +{ + lt_debugprintf (__FILE__, __LINE__, + "(lt_setenv) setting '%s' to '%s'\n", + nonnull (name), nonnull (value)); + { +#ifdef HAVE_SETENV + /* always make a copy, for consistency with !HAVE_SETENV */ + char *str = xstrdup (value); + setenv (name, str, 1); +#else + size_t len = strlen (name) + 1 + strlen (value) + 1; + char *str = XMALLOC (char, len); + sprintf (str, "%s=%s", name, value); + if (putenv (str) != EXIT_SUCCESS) + { + XFREE (str); + } +#endif + } +} + +char * +lt_extend_str (const char *orig_value, const char *add, int to_end) +{ + char *new_value; + if (orig_value && *orig_value) + { + size_t orig_value_len = strlen (orig_value); + size_t add_len = strlen (add); + new_value = XMALLOC (char, add_len + orig_value_len + 1); + if (to_end) + { + strcpy (new_value, orig_value); + strcpy (new_value + orig_value_len, add); + } + else + { + strcpy (new_value, add); + strcpy (new_value + add_len, orig_value); + } + } + else + { + new_value = xstrdup (add); + } + return new_value; +} + +void +lt_update_exe_path (const char *name, const char *value) +{ + lt_debugprintf (__FILE__, __LINE__, + "(lt_update_exe_path) modifying '%s' by prepending '%s'\n", + nonnull (name), nonnull (value)); + + if (name && *name && value && *value) + { + char *new_value = lt_extend_str (getenv (name), value, 0); + /* some systems can't cope with a ':'-terminated path #' */ + size_t len = strlen (new_value); + while ((len > 0) && IS_PATH_SEPARATOR (new_value[len-1])) + { + new_value[--len] = '\0'; + } + lt_setenv (name, new_value); + XFREE (new_value); + } +} + +void +lt_update_lib_path (const char *name, const char *value) +{ + lt_debugprintf (__FILE__, __LINE__, + "(lt_update_lib_path) modifying '%s' by prepending '%s'\n", + nonnull (name), nonnull (value)); + + if (name && *name && value && *value) + { + char *new_value = lt_extend_str (getenv (name), value, 0); + lt_setenv (name, new_value); + XFREE (new_value); + } +} + +EOF + case $host_os in + mingw*) + cat <<"EOF" + +/* Prepares an argument vector before calling spawn(). + Note that spawn() does not by itself call the command interpreter + (getenv ("COMSPEC") != NULL ? getenv ("COMSPEC") : + ({ OSVERSIONINFO v; v.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + GetVersionEx(&v); + v.dwPlatformId == VER_PLATFORM_WIN32_NT; + }) ? "cmd.exe" : "command.com"). + Instead it simply concatenates the arguments, separated by ' ', and calls + CreateProcess(). We must quote the arguments since Win32 CreateProcess() + interprets characters like ' ', '\t', '\\', '"' (but not '<' and '>') in a + special way: + - Space and tab are interpreted as delimiters. They are not treated as + delimiters if they are surrounded by double quotes: "...". + - Unescaped double quotes are removed from the input. Their only effect is + that within double quotes, space and tab are treated like normal + characters. + - Backslashes not followed by double quotes are not special. + - But 2*n+1 backslashes followed by a double quote become + n backslashes followed by a double quote (n >= 0): + \" -> " + \\\" -> \" + \\\\\" -> \\" + */ +#define SHELL_SPECIAL_CHARS "\"\\ \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" +#define SHELL_SPACE_CHARS " \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" +char ** +prepare_spawn (char **argv) +{ + size_t argc; + char **new_argv; + size_t i; + + /* Count number of arguments. */ + for (argc = 0; argv[argc] != NULL; argc++) + ; + + /* Allocate new argument vector. */ + new_argv = XMALLOC (char *, argc + 1); + + /* Put quoted arguments into the new argument vector. */ + for (i = 0; i < argc; i++) + { + const char *string = argv[i]; + + if (string[0] == '\0') + new_argv[i] = xstrdup ("\"\""); + else if (strpbrk (string, SHELL_SPECIAL_CHARS) != NULL) + { + int quote_around = (strpbrk (string, SHELL_SPACE_CHARS) != NULL); + size_t length; + unsigned int backslashes; + const char *s; + char *quoted_string; + char *p; + + length = 0; + backslashes = 0; + if (quote_around) + length++; + for (s = string; *s != '\0'; s++) + { + char c = *s; + if (c == '"') + length += backslashes + 1; + length++; + if (c == '\\') + backslashes++; + else + backslashes = 0; + } + if (quote_around) + length += backslashes + 1; + + quoted_string = XMALLOC (char, length + 1); + + p = quoted_string; + backslashes = 0; + if (quote_around) + *p++ = '"'; + for (s = string; *s != '\0'; s++) + { + char c = *s; + if (c == '"') + { + unsigned int j; + for (j = backslashes + 1; j > 0; j--) + *p++ = '\\'; + } + *p++ = c; + if (c == '\\') + backslashes++; + else + backslashes = 0; + } + if (quote_around) + { + unsigned int j; + for (j = backslashes; j > 0; j--) + *p++ = '\\'; + *p++ = '"'; + } + *p = '\0'; + + new_argv[i] = quoted_string; + } + else + new_argv[i] = (char *) string; + } + new_argv[argc] = NULL; + + return new_argv; +} +EOF + ;; + esac + + cat <<"EOF" +void lt_dump_script (FILE* f) +{ +EOF + func_emit_wrapper yes | + $SED -n -e ' +s/^\(.\{79\}\)\(..*\)/\1\ +\2/ +h +s/\([\\"]\)/\\\1/g +s/$/\\n/ +s/\([^\n]*\).*/ fputs ("\1", f);/p +g +D' + cat <<"EOF" +} +EOF +} +# end: func_emit_cwrapperexe_src + +# func_win32_import_lib_p ARG +# True if ARG is an import lib, as indicated by $file_magic_cmd +func_win32_import_lib_p () +{ + $debug_cmd + + case `eval $file_magic_cmd \"\$1\" 2>/dev/null | $SED -e 10q` in + *import*) : ;; + *) false ;; + esac +} + +# func_suncc_cstd_abi +# !!ONLY CALL THIS FOR SUN CC AFTER $compile_command IS FULLY EXPANDED!! +# Several compiler flags select an ABI that is incompatible with the +# Cstd library. Avoid specifying it if any are in CXXFLAGS. +func_suncc_cstd_abi () +{ + $debug_cmd + + case " $compile_command " in + *" -compat=g "*|*\ -std=c++[0-9][0-9]\ *|*" -library=stdcxx4 "*|*" -library=stlport4 "*) + suncc_use_cstd_abi=no + ;; + *) + suncc_use_cstd_abi=yes + ;; + esac +} + +# func_mode_link arg... +func_mode_link () +{ + $debug_cmd + + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + # It is impossible to link a dll without this setting, and + # we shouldn't force the makefile maintainer to figure out + # what system we are compiling for in order to pass an extra + # flag for every libtool invocation. + # allow_undefined=no + + # FIXME: Unfortunately, there are problems with the above when trying + # to make a dll that has undefined symbols, in which case not + # even a static library is built. For now, we need to specify + # -no-undefined on the libtool link line when we can be certain + # that all symbols are satisfied, otherwise we get a static library. + allow_undefined=yes + ;; + *) + allow_undefined=yes + ;; + esac + libtool_args=$nonopt + base_compile="$nonopt $@" + compile_command=$nonopt + finalize_command=$nonopt + + compile_rpath= + finalize_rpath= + compile_shlibpath= + finalize_shlibpath= + convenience= + old_convenience= + deplibs= + old_deplibs= + compiler_flags= + linker_flags= + dllsearchpath= + lib_search_path=`pwd` + inst_prefix_dir= + new_inherited_linker_flags= + + avoid_version=no + bindir= + dlfiles= + dlprefiles= + dlself=no + export_dynamic=no + export_symbols= + export_symbols_regex= + generated= + libobjs= + ltlibs= + module=no + no_install=no + objs= + os2dllname= + non_pic_objects= + precious_files_regex= + prefer_static_libs=no + preload=false + prev= + prevarg= + release= + rpath= + xrpath= + perm_rpath= + temp_rpath= + thread_safe=no + vinfo= + vinfo_number=no + weak_libs= + single_module=$wl-single_module + func_infer_tag $base_compile + + # We need to know -static, to get the right output filenames. + for arg + do + case $arg in + -shared) + test yes != "$build_libtool_libs" \ + && func_fatal_configuration "cannot build a shared library" + build_old_libs=no + break + ;; + -all-static | -static | -static-libtool-libs) + case $arg in + -all-static) + if test yes = "$build_libtool_libs" && test -z "$link_static_flag"; then + func_warning "complete static linking is impossible in this configuration" + fi + if test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=yes + ;; + -static) + if test -z "$pic_flag" && test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=built + ;; + -static-libtool-libs) + if test -z "$pic_flag" && test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=yes + ;; + esac + build_libtool_libs=no + build_old_libs=yes + break + ;; + esac + done + + # See if our shared archives depend on static archives. + test -n "$old_archive_from_new_cmds" && build_old_libs=yes + + # Go through the arguments, transforming them on the way. + while test "$#" -gt 0; do + arg=$1 + shift + func_quote_for_eval "$arg" + qarg=$func_quote_for_eval_unquoted_result + func_append libtool_args " $func_quote_for_eval_result" + + # If the previous option needs an argument, assign it. + if test -n "$prev"; then + case $prev in + output) + func_append compile_command " @OUTPUT@" + func_append finalize_command " @OUTPUT@" + ;; + esac + + case $prev in + bindir) + bindir=$arg + prev= + continue + ;; + dlfiles|dlprefiles) + $preload || { + # Add the symbol object into the linking commands. + func_append compile_command " @SYMFILE@" + func_append finalize_command " @SYMFILE@" + preload=: + } + case $arg in + *.la | *.lo) ;; # We handle these cases below. + force) + if test no = "$dlself"; then + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + self) + if test dlprefiles = "$prev"; then + dlself=yes + elif test dlfiles = "$prev" && test yes != "$dlopen_self"; then + dlself=yes + else + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + *) + if test dlfiles = "$prev"; then + func_append dlfiles " $arg" + else + func_append dlprefiles " $arg" + fi + prev= + continue + ;; + esac + ;; + expsyms) + export_symbols=$arg + test -f "$arg" \ + || func_fatal_error "symbol file '$arg' does not exist" + prev= + continue + ;; + expsyms_regex) + export_symbols_regex=$arg + prev= + continue + ;; + framework) + case $host in + *-*-darwin*) + case "$deplibs " in + *" $qarg.ltframework "*) ;; + *) func_append deplibs " $qarg.ltframework" # this is fixed later + ;; + esac + ;; + esac + prev= + continue + ;; + inst_prefix) + inst_prefix_dir=$arg + prev= + continue + ;; + mllvm) + # Clang does not use LLVM to link, so we can simply discard any + # '-mllvm $arg' options when doing the link step. + prev= + continue + ;; + objectlist) + if test -f "$arg"; then + save_arg=$arg + moreargs= + for fil in `cat "$save_arg"` + do +# func_append moreargs " $fil" + arg=$fil + # A libtool-controlled object. + + # Check to see that this really is a libtool object. + if func_lalib_unsafe_p "$arg"; then + pic_object= + non_pic_object= + + # Read the .lo file + func_source "$arg" + + if test -z "$pic_object" || + test -z "$non_pic_object" || + test none = "$pic_object" && + test none = "$non_pic_object"; then + func_fatal_error "cannot find name of object for '$arg'" + fi + + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir=$func_dirname_result + + if test none != "$pic_object"; then + # Prepend the subdirectory the object is found in. + pic_object=$xdir$pic_object + + if test dlfiles = "$prev"; then + if test yes = "$build_libtool_libs" && test yes = "$dlopen_support"; then + func_append dlfiles " $pic_object" + prev= + continue + else + # If libtool objects are unsupported, then we need to preload. + prev=dlprefiles + fi + fi + + # CHECK ME: I think I busted this. -Ossama + if test dlprefiles = "$prev"; then + # Preload the old-style object. + func_append dlprefiles " $pic_object" + prev= + fi + + # A PIC object. + func_append libobjs " $pic_object" + arg=$pic_object + fi + + # Non-PIC object. + if test none != "$non_pic_object"; then + # Prepend the subdirectory the object is found in. + non_pic_object=$xdir$non_pic_object + + # A standard non-PIC object + func_append non_pic_objects " $non_pic_object" + if test -z "$pic_object" || test none = "$pic_object"; then + arg=$non_pic_object + fi + else + # If the PIC object exists, use it instead. + # $xdir was prepended to $pic_object above. + non_pic_object=$pic_object + func_append non_pic_objects " $non_pic_object" + fi + else + # Only an error if not doing a dry-run. + if $opt_dry_run; then + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir=$func_dirname_result + + func_lo2o "$arg" + pic_object=$xdir$objdir/$func_lo2o_result + non_pic_object=$xdir$func_lo2o_result + func_append libobjs " $pic_object" + func_append non_pic_objects " $non_pic_object" + else + func_fatal_error "'$arg' is not a valid libtool object" + fi + fi + done + else + func_fatal_error "link input file '$arg' does not exist" + fi + arg=$save_arg + prev= + continue + ;; + os2dllname) + os2dllname=$arg + prev= + continue + ;; + precious_regex) + precious_files_regex=$arg + prev= + continue + ;; + release) + release=-$arg + prev= + continue + ;; + rpath | xrpath) + # We need an absolute path. + case $arg in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + func_fatal_error "only absolute run-paths are allowed" + ;; + esac + if test rpath = "$prev"; then + case "$rpath " in + *" $arg "*) ;; + *) func_append rpath " $arg" ;; + esac + else + case "$xrpath " in + *" $arg "*) ;; + *) func_append xrpath " $arg" ;; + esac + fi + prev= + continue + ;; + shrext) + shrext_cmds=$arg + prev= + continue + ;; + weak) + func_append weak_libs " $arg" + prev= + continue + ;; + xcclinker) + func_append linker_flags " $qarg" + func_append compiler_flags " $qarg" + prev= + func_append compile_command " $qarg" + func_append finalize_command " $qarg" + continue + ;; + xcompiler) + func_append compiler_flags " $qarg" + prev= + func_append compile_command " $qarg" + func_append finalize_command " $qarg" + continue + ;; + xlinker) + func_append linker_flags " $qarg" + func_append compiler_flags " $wl$qarg" + prev= + func_append compile_command " $wl$qarg" + func_append finalize_command " $wl$qarg" + continue + ;; + *) + eval "$prev=\"\$arg\"" + prev= + continue + ;; + esac + fi # test -n "$prev" + + prevarg=$arg + + case $arg in + -all-static) + if test -n "$link_static_flag"; then + # See comment for -static flag below, for more details. + func_append compile_command " $link_static_flag" + func_append finalize_command " $link_static_flag" + fi + continue + ;; + + -allow-undefined) + # FIXME: remove this flag sometime in the future. + func_fatal_error "'-allow-undefined' must not be used because it is the default" + ;; + + -avoid-version) + avoid_version=yes + continue + ;; + + -bindir) + prev=bindir + continue + ;; + + -dlopen) + prev=dlfiles + continue + ;; + + -dlpreopen) + prev=dlprefiles + continue + ;; + + -export-dynamic) + export_dynamic=yes + continue + ;; + + -export-symbols | -export-symbols-regex) + if test -n "$export_symbols" || test -n "$export_symbols_regex"; then + func_fatal_error "more than one -exported-symbols argument is not allowed" + fi + if test X-export-symbols = "X$arg"; then + prev=expsyms + else + prev=expsyms_regex + fi + continue + ;; + + -framework) + prev=framework + continue + ;; + + -inst-prefix-dir) + prev=inst_prefix + continue + ;; + + # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* + # so, if we see these flags be careful not to treat them like -L + -L[A-Z][A-Z]*:*) + case $with_gcc/$host in + no/*-*-irix* | /*-*-irix*) + func_append compile_command " $arg" + func_append finalize_command " $arg" + ;; + esac + continue + ;; + + -L*) + func_stripname "-L" '' "$arg" + if test -z "$func_stripname_result"; then + if test "$#" -gt 0; then + func_fatal_error "require no space between '-L' and '$1'" + else + func_fatal_error "need path for '-L' option" + fi + fi + func_resolve_sysroot "$func_stripname_result" + dir=$func_resolve_sysroot_result + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + absdir=`cd "$dir" && pwd` + test -z "$absdir" && \ + func_fatal_error "cannot determine absolute directory name of '$dir'" + dir=$absdir + ;; + esac + case "$deplibs " in + *" -L$dir "* | *" $arg "*) + # Will only happen for absolute or sysroot arguments + ;; + *) + # Preserve sysroot, but never include relative directories + case $dir in + [\\/]* | [A-Za-z]:[\\/]* | =*) func_append deplibs " $arg" ;; + *) func_append deplibs " -L$dir" ;; + esac + func_append lib_search_path " $dir" + ;; + esac + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + testbindir=`$ECHO "$dir" | $SED 's*/lib$*/bin*'` + case :$dllsearchpath: in + *":$dir:"*) ;; + ::) dllsearchpath=$dir;; + *) func_append dllsearchpath ":$dir";; + esac + case :$dllsearchpath: in + *":$testbindir:"*) ;; + ::) dllsearchpath=$testbindir;; + *) func_append dllsearchpath ":$testbindir";; + esac + ;; + esac + continue + ;; + + -l*) + if test X-lc = "X$arg" || test X-lm = "X$arg"; then + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*) + # These systems don't actually have a C or math library (as such) + continue + ;; + *-*-os2*) + # These systems don't actually have a C library (as such) + test X-lc = "X$arg" && continue + ;; + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig*) + # Do not include libc due to us having libc/libc_r. + test X-lc = "X$arg" && continue + ;; + *-*-rhapsody* | *-*-darwin1.[012]) + # Rhapsody C and math libraries are in the System framework + func_append deplibs " System.ltframework" + continue + ;; + *-*-sco3.2v5* | *-*-sco5v6*) + # Causes problems with __ctype + test X-lc = "X$arg" && continue + ;; + *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) + # Compiler inserts libc in the correct place for threads to work + test X-lc = "X$arg" && continue + ;; + esac + elif test X-lc_r = "X$arg"; then + case $host in + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig*) + # Do not include libc_r directly, use -pthread flag. + continue + ;; + esac + fi + func_append deplibs " $arg" + continue + ;; + + -mllvm) + prev=mllvm + continue + ;; + + -module) + module=yes + continue + ;; + + # Tru64 UNIX uses -model [arg] to determine the layout of C++ + # classes, name mangling, and exception handling. + # Darwin uses the -arch flag to determine output architecture. + -model|-arch|-isysroot|--sysroot) + func_append compiler_flags " $arg" + func_append compile_command " $arg" + func_append finalize_command " $arg" + prev=xcompiler + continue + ;; + + -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ + |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) + func_append compiler_flags " $arg" + func_append compile_command " $arg" + func_append finalize_command " $arg" + case "$new_inherited_linker_flags " in + *" $arg "*) ;; + * ) func_append new_inherited_linker_flags " $arg" ;; + esac + continue + ;; + + -multi_module) + single_module=$wl-multi_module + continue + ;; + + -no-fast-install) + fast_install=no + continue + ;; + + -no-install) + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*) + # The PATH hackery in wrapper scripts is required on Windows + # and Darwin in order for the loader to find any dlls it needs. + func_warning "'-no-install' is ignored for $host" + func_warning "assuming '-no-fast-install' instead" + fast_install=no + ;; + *) no_install=yes ;; + esac + continue + ;; + + -no-undefined) + allow_undefined=no + continue + ;; + + -objectlist) + prev=objectlist + continue + ;; + + -os2dllname) + prev=os2dllname + continue + ;; + + -o) prev=output ;; + + -precious-files-regex) + prev=precious_regex + continue + ;; + + -release) + prev=release + continue + ;; + + -rpath) + prev=rpath + continue + ;; + + -R) + prev=xrpath + continue + ;; + + -R*) + func_stripname '-R' '' "$arg" + dir=$func_stripname_result + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + =*) + func_stripname '=' '' "$dir" + dir=$lt_sysroot$func_stripname_result + ;; + *) + func_fatal_error "only absolute run-paths are allowed" + ;; + esac + case "$xrpath " in + *" $dir "*) ;; + *) func_append xrpath " $dir" ;; + esac + continue + ;; + + -shared) + # The effects of -shared are defined in a previous loop. + continue + ;; + + -shrext) + prev=shrext + continue + ;; + + -static | -static-libtool-libs) + # The effects of -static are defined in a previous loop. + # We used to do the same as -all-static on platforms that + # didn't have a PIC flag, but the assumption that the effects + # would be equivalent was wrong. It would break on at least + # Digital Unix and AIX. + continue + ;; + + -thread-safe) + thread_safe=yes + continue + ;; + + -version-info) + prev=vinfo + continue + ;; + + -version-number) + prev=vinfo + vinfo_number=yes + continue + ;; + + -weak) + prev=weak + continue + ;; + + -Wc,*) + func_stripname '-Wc,' '' "$arg" + args=$func_stripname_result + arg= + save_ifs=$IFS; IFS=, + for flag in $args; do + IFS=$save_ifs + func_quote_for_eval "$flag" + func_append arg " $func_quote_for_eval_result" + func_append compiler_flags " $func_quote_for_eval_result" + done + IFS=$save_ifs + func_stripname ' ' '' "$arg" + arg=$func_stripname_result + ;; + + -Wl,*) + func_stripname '-Wl,' '' "$arg" + args=$func_stripname_result + arg= + save_ifs=$IFS; IFS=, + for flag in $args; do + IFS=$save_ifs + func_quote_for_eval "$flag" + func_append arg " $wl$func_quote_for_eval_result" + func_append compiler_flags " $wl$func_quote_for_eval_result" + func_append linker_flags " $func_quote_for_eval_result" + done + IFS=$save_ifs + func_stripname ' ' '' "$arg" + arg=$func_stripname_result + ;; + + -Xcompiler) + prev=xcompiler + continue + ;; + + -Xlinker) + prev=xlinker + continue + ;; + + -XCClinker) + prev=xcclinker + continue + ;; + + # -msg_* for osf cc + -msg_*) + func_quote_for_eval "$arg" + arg=$func_quote_for_eval_result + ;; + + # Flags to be passed through unchanged, with rationale: + # -64, -mips[0-9] enable 64-bit mode for the SGI compiler + # -r[0-9][0-9]* specify processor for the SGI compiler + # -xarch=*, -xtarget=* enable 64-bit mode for the Sun compiler + # +DA*, +DD* enable 64-bit mode for the HP compiler + # -q* compiler args for the IBM compiler + # -m*, -t[45]*, -txscale* architecture-specific flags for GCC + # -F/path path to uninstalled frameworks, gcc on darwin + # -p, -pg, --coverage, -fprofile-* profiling flags for GCC + # -fstack-protector* stack protector flags for GCC + # @file GCC response files + # -tp=* Portland pgcc target processor selection + # --sysroot=* for sysroot support + # -O*, -g*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization + # -specs=* GCC specs files + # -stdlib=* select c++ std lib with clang + # -fsanitize=* Clang/GCC memory and address sanitizer + # -fuse-ld=* Linker select flags for GCC + # -static-* direct GCC to link specific libraries statically + # -fcilkplus Cilk Plus language extension features for C/C++ + -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \ + -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \ + -O*|-g*|-flto*|-fwhopr*|-fuse-linker-plugin|-fstack-protector*|-stdlib=*| \ + -specs=*|-fsanitize=*|-fuse-ld=*|-static-*|-fcilkplus) + func_quote_for_eval "$arg" + arg=$func_quote_for_eval_result + func_append compile_command " $arg" + func_append finalize_command " $arg" + func_append compiler_flags " $arg" + continue + ;; + + -Z*) + if test os2 = "`expr $host : '.*\(os2\)'`"; then + # OS/2 uses -Zxxx to specify OS/2-specific options + compiler_flags="$compiler_flags $arg" + func_append compile_command " $arg" + func_append finalize_command " $arg" + case $arg in + -Zlinker | -Zstack) + prev=xcompiler + ;; + esac + continue + else + # Otherwise treat like 'Some other compiler flag' below + func_quote_for_eval "$arg" + arg=$func_quote_for_eval_result + fi + ;; + + # Some other compiler flag. + -* | +*) + func_quote_for_eval "$arg" + arg=$func_quote_for_eval_result + ;; + + *.$objext) + # A standard object. + func_append objs " $arg" + ;; + + *.lo) + # A libtool-controlled object. + + # Check to see that this really is a libtool object. + if func_lalib_unsafe_p "$arg"; then + pic_object= + non_pic_object= + + # Read the .lo file + func_source "$arg" + + if test -z "$pic_object" || + test -z "$non_pic_object" || + test none = "$pic_object" && + test none = "$non_pic_object"; then + func_fatal_error "cannot find name of object for '$arg'" + fi + + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir=$func_dirname_result + + test none = "$pic_object" || { + # Prepend the subdirectory the object is found in. + pic_object=$xdir$pic_object + + if test dlfiles = "$prev"; then + if test yes = "$build_libtool_libs" && test yes = "$dlopen_support"; then + func_append dlfiles " $pic_object" + prev= + continue + else + # If libtool objects are unsupported, then we need to preload. + prev=dlprefiles + fi + fi + + # CHECK ME: I think I busted this. -Ossama + if test dlprefiles = "$prev"; then + # Preload the old-style object. + func_append dlprefiles " $pic_object" + prev= + fi + + # A PIC object. + func_append libobjs " $pic_object" + arg=$pic_object + } + + # Non-PIC object. + if test none != "$non_pic_object"; then + # Prepend the subdirectory the object is found in. + non_pic_object=$xdir$non_pic_object + + # A standard non-PIC object + func_append non_pic_objects " $non_pic_object" + if test -z "$pic_object" || test none = "$pic_object"; then + arg=$non_pic_object + fi + else + # If the PIC object exists, use it instead. + # $xdir was prepended to $pic_object above. + non_pic_object=$pic_object + func_append non_pic_objects " $non_pic_object" + fi + else + # Only an error if not doing a dry-run. + if $opt_dry_run; then + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir=$func_dirname_result + + func_lo2o "$arg" + pic_object=$xdir$objdir/$func_lo2o_result + non_pic_object=$xdir$func_lo2o_result + func_append libobjs " $pic_object" + func_append non_pic_objects " $non_pic_object" + else + func_fatal_error "'$arg' is not a valid libtool object" + fi + fi + ;; + + *.$libext) + # An archive. + func_append deplibs " $arg" + func_append old_deplibs " $arg" + continue + ;; + + *.la) + # A libtool-controlled library. + + func_resolve_sysroot "$arg" + if test dlfiles = "$prev"; then + # This library was specified with -dlopen. + func_append dlfiles " $func_resolve_sysroot_result" + prev= + elif test dlprefiles = "$prev"; then + # The library was specified with -dlpreopen. + func_append dlprefiles " $func_resolve_sysroot_result" + prev= + else + func_append deplibs " $func_resolve_sysroot_result" + fi + continue + ;; + + # Some other compiler argument. + *) + # Unknown arguments in both finalize_command and compile_command need + # to be aesthetically quoted because they are evaled later. + func_quote_for_eval "$arg" + arg=$func_quote_for_eval_result + ;; + esac # arg + + # Now actually substitute the argument into the commands. + if test -n "$arg"; then + func_append compile_command " $arg" + func_append finalize_command " $arg" + fi + done # argument parsing loop + + test -n "$prev" && \ + func_fatal_help "the '$prevarg' option requires an argument" + + if test yes = "$export_dynamic" && test -n "$export_dynamic_flag_spec"; then + eval arg=\"$export_dynamic_flag_spec\" + func_append compile_command " $arg" + func_append finalize_command " $arg" + fi + + oldlibs= + # calculate the name of the file, without its directory + func_basename "$output" + outputname=$func_basename_result + libobjs_save=$libobjs + + if test -n "$shlibpath_var"; then + # get the directories listed in $shlibpath_var + eval shlib_search_path=\`\$ECHO \"\$$shlibpath_var\" \| \$SED \'s/:/ /g\'\` + else + shlib_search_path= + fi + eval sys_lib_search_path=\"$sys_lib_search_path_spec\" + eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" + + # Definition is injected by LT_CONFIG during libtool generation. + func_munge_path_list sys_lib_dlsearch_path "$LT_SYS_LIBRARY_PATH" + + func_dirname "$output" "/" "" + output_objdir=$func_dirname_result$objdir + func_to_tool_file "$output_objdir/" + tool_output_objdir=$func_to_tool_file_result + # Create the object directory. + func_mkdir_p "$output_objdir" + + # Determine the type of output + case $output in + "") + func_fatal_help "you must specify an output file" + ;; + *.$libext) linkmode=oldlib ;; + *.lo | *.$objext) linkmode=obj ;; + *.la) linkmode=lib ;; + *) linkmode=prog ;; # Anything else should be a program. + esac + + specialdeplibs= + + libs= + # Find all interdependent deplibs by searching for libraries + # that are linked more than once (e.g. -la -lb -la) + for deplib in $deplibs; do + if $opt_preserve_dup_deps; then + case "$libs " in + *" $deplib "*) func_append specialdeplibs " $deplib" ;; + esac + fi + func_append libs " $deplib" + done + + if test lib = "$linkmode"; then + libs="$predeps $libs $compiler_lib_search_path $postdeps" + + # Compute libraries that are listed more than once in $predeps + # $postdeps and mark them as special (i.e., whose duplicates are + # not to be eliminated). + pre_post_deps= + if $opt_duplicate_compiler_generated_deps; then + for pre_post_dep in $predeps $postdeps; do + case "$pre_post_deps " in + *" $pre_post_dep "*) func_append specialdeplibs " $pre_post_deps" ;; + esac + func_append pre_post_deps " $pre_post_dep" + done + fi + pre_post_deps= + fi + + deplibs= + newdependency_libs= + newlib_search_path= + need_relink=no # whether we're linking any uninstalled libtool libraries + notinst_deplibs= # not-installed libtool libraries + notinst_path= # paths that contain not-installed libtool libraries + + case $linkmode in + lib) + passes="conv dlpreopen link" + for file in $dlfiles $dlprefiles; do + case $file in + *.la) ;; + *) + func_fatal_help "libraries can '-dlopen' only libtool libraries: $file" + ;; + esac + done + ;; + prog) + compile_deplibs= + finalize_deplibs= + alldeplibs=false + newdlfiles= + newdlprefiles= + passes="conv scan dlopen dlpreopen link" + ;; + *) passes="conv" + ;; + esac + + for pass in $passes; do + # The preopen pass in lib mode reverses $deplibs; put it back here + # so that -L comes before libs that need it for instance... + if test lib,link = "$linkmode,$pass"; then + ## FIXME: Find the place where the list is rebuilt in the wrong + ## order, and fix it there properly + tmp_deplibs= + for deplib in $deplibs; do + tmp_deplibs="$deplib $tmp_deplibs" + done + deplibs=$tmp_deplibs + fi + + if test lib,link = "$linkmode,$pass" || + test prog,scan = "$linkmode,$pass"; then + libs=$deplibs + deplibs= + fi + if test prog = "$linkmode"; then + case $pass in + dlopen) libs=$dlfiles ;; + dlpreopen) libs=$dlprefiles ;; + link) + libs="$deplibs %DEPLIBS%" + test "X$link_all_deplibs" != Xno && libs="$libs $dependency_libs" + ;; + esac + fi + if test lib,dlpreopen = "$linkmode,$pass"; then + # Collect and forward deplibs of preopened libtool libs + for lib in $dlprefiles; do + # Ignore non-libtool-libs + dependency_libs= + func_resolve_sysroot "$lib" + case $lib in + *.la) func_source "$func_resolve_sysroot_result" ;; + esac + + # Collect preopened libtool deplibs, except any this library + # has declared as weak libs + for deplib in $dependency_libs; do + func_basename "$deplib" + deplib_base=$func_basename_result + case " $weak_libs " in + *" $deplib_base "*) ;; + *) func_append deplibs " $deplib" ;; + esac + done + done + libs=$dlprefiles + fi + if test dlopen = "$pass"; then + # Collect dlpreopened libraries + save_deplibs=$deplibs + deplibs= + fi + + for deplib in $libs; do + lib= + found=false + case $deplib in + -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ + |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) + if test prog,link = "$linkmode,$pass"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + func_append compiler_flags " $deplib" + if test lib = "$linkmode"; then + case "$new_inherited_linker_flags " in + *" $deplib "*) ;; + * ) func_append new_inherited_linker_flags " $deplib" ;; + esac + fi + fi + continue + ;; + -l*) + if test lib != "$linkmode" && test prog != "$linkmode"; then + func_warning "'-l' is ignored for archives/objects" + continue + fi + func_stripname '-l' '' "$deplib" + name=$func_stripname_result + if test lib = "$linkmode"; then + searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path" + else + searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path" + fi + for searchdir in $searchdirs; do + for search_ext in .la $std_shrext .so .a; do + # Search the libtool library + lib=$searchdir/lib$name$search_ext + if test -f "$lib"; then + if test .la = "$search_ext"; then + found=: + else + found=false + fi + break 2 + fi + done + done + if $found; then + # deplib is a libtool library + # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib, + # We need to do some special things here, and not later. + if test yes = "$allow_libtool_libs_with_static_runtimes"; then + case " $predeps $postdeps " in + *" $deplib "*) + if func_lalib_p "$lib"; then + library_names= + old_library= + func_source "$lib" + for l in $old_library $library_names; do + ll=$l + done + if test "X$ll" = "X$old_library"; then # only static version available + found=false + func_dirname "$lib" "" "." + ladir=$func_dirname_result + lib=$ladir/$old_library + if test prog,link = "$linkmode,$pass"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + test lib = "$linkmode" && newdependency_libs="$deplib $newdependency_libs" + fi + continue + fi + fi + ;; + *) ;; + esac + fi + else + # deplib doesn't seem to be a libtool library + if test prog,link = "$linkmode,$pass"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + test lib = "$linkmode" && newdependency_libs="$deplib $newdependency_libs" + fi + continue + fi + ;; # -l + *.ltframework) + if test prog,link = "$linkmode,$pass"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + if test lib = "$linkmode"; then + case "$new_inherited_linker_flags " in + *" $deplib "*) ;; + * ) func_append new_inherited_linker_flags " $deplib" ;; + esac + fi + fi + continue + ;; + -L*) + case $linkmode in + lib) + deplibs="$deplib $deplibs" + test conv = "$pass" && continue + newdependency_libs="$deplib $newdependency_libs" + func_stripname '-L' '' "$deplib" + func_resolve_sysroot "$func_stripname_result" + func_append newlib_search_path " $func_resolve_sysroot_result" + ;; + prog) + if test conv = "$pass"; then + deplibs="$deplib $deplibs" + continue + fi + if test scan = "$pass"; then + deplibs="$deplib $deplibs" + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + func_stripname '-L' '' "$deplib" + func_resolve_sysroot "$func_stripname_result" + func_append newlib_search_path " $func_resolve_sysroot_result" + ;; + *) + func_warning "'-L' is ignored for archives/objects" + ;; + esac # linkmode + continue + ;; # -L + -R*) + if test link = "$pass"; then + func_stripname '-R' '' "$deplib" + func_resolve_sysroot "$func_stripname_result" + dir=$func_resolve_sysroot_result + # Make sure the xrpath contains only unique directories. + case "$xrpath " in + *" $dir "*) ;; + *) func_append xrpath " $dir" ;; + esac + fi + deplibs="$deplib $deplibs" + continue + ;; + *.la) + func_resolve_sysroot "$deplib" + lib=$func_resolve_sysroot_result + ;; + *.$libext) + if test conv = "$pass"; then + deplibs="$deplib $deplibs" + continue + fi + case $linkmode in + lib) + # Linking convenience modules into shared libraries is allowed, + # but linking other static libraries is non-portable. + case " $dlpreconveniencelibs " in + *" $deplib "*) ;; + *) + valid_a_lib=false + case $deplibs_check_method in + match_pattern*) + set dummy $deplibs_check_method; shift + match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` + if eval "\$ECHO \"$deplib\"" 2>/dev/null | $SED 10q \ + | $EGREP "$match_pattern_regex" > /dev/null; then + valid_a_lib=: + fi + ;; + pass_all) + valid_a_lib=: + ;; + esac + if $valid_a_lib; then + echo + $ECHO "*** Warning: Linking the shared library $output against the" + $ECHO "*** static library $deplib is not portable!" + deplibs="$deplib $deplibs" + else + echo + $ECHO "*** Warning: Trying to link with static lib archive $deplib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have" + echo "*** because the file extensions .$libext of this argument makes me believe" + echo "*** that it is just a static archive that I should not use here." + fi + ;; + esac + continue + ;; + prog) + if test link != "$pass"; then + deplibs="$deplib $deplibs" + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + continue + ;; + esac # linkmode + ;; # *.$libext + *.lo | *.$objext) + if test conv = "$pass"; then + deplibs="$deplib $deplibs" + elif test prog = "$linkmode"; then + if test dlpreopen = "$pass" || test yes != "$dlopen_support" || test no = "$build_libtool_libs"; then + # If there is no dlopen support or we're linking statically, + # we need to preload. + func_append newdlprefiles " $deplib" + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + func_append newdlfiles " $deplib" + fi + fi + continue + ;; + %DEPLIBS%) + alldeplibs=: + continue + ;; + esac # case $deplib + + $found || test -f "$lib" \ + || func_fatal_error "cannot find the library '$lib' or unhandled argument '$deplib'" + + # Check to see that this really is a libtool archive. + func_lalib_unsafe_p "$lib" \ + || func_fatal_error "'$lib' is not a valid libtool archive" + + func_dirname "$lib" "" "." + ladir=$func_dirname_result + + dlname= + dlopen= + dlpreopen= + libdir= + library_names= + old_library= + inherited_linker_flags= + # If the library was installed with an old release of libtool, + # it will not redefine variables installed, or shouldnotlink + installed=yes + shouldnotlink=no + avoidtemprpath= + + + # Read the .la file + func_source "$lib" + + # Convert "-framework foo" to "foo.ltframework" + if test -n "$inherited_linker_flags"; then + tmp_inherited_linker_flags=`$ECHO "$inherited_linker_flags" | $SED 's/-framework \([^ $]*\)/\1.ltframework/g'` + for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do + case " $new_inherited_linker_flags " in + *" $tmp_inherited_linker_flag "*) ;; + *) func_append new_inherited_linker_flags " $tmp_inherited_linker_flag";; + esac + done + fi + dependency_libs=`$ECHO " $dependency_libs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + if test lib,link = "$linkmode,$pass" || + test prog,scan = "$linkmode,$pass" || + { test prog != "$linkmode" && test lib != "$linkmode"; }; then + test -n "$dlopen" && func_append dlfiles " $dlopen" + test -n "$dlpreopen" && func_append dlprefiles " $dlpreopen" + fi + + if test conv = "$pass"; then + # Only check for convenience libraries + deplibs="$lib $deplibs" + if test -z "$libdir"; then + if test -z "$old_library"; then + func_fatal_error "cannot find name of link library for '$lib'" + fi + # It is a libtool convenience library, so add in its objects. + func_append convenience " $ladir/$objdir/$old_library" + func_append old_convenience " $ladir/$objdir/$old_library" + tmp_libs= + for deplib in $dependency_libs; do + deplibs="$deplib $deplibs" + if $opt_preserve_dup_deps; then + case "$tmp_libs " in + *" $deplib "*) func_append specialdeplibs " $deplib" ;; + esac + fi + func_append tmp_libs " $deplib" + done + elif test prog != "$linkmode" && test lib != "$linkmode"; then + func_fatal_error "'$lib' is not a convenience library" + fi + continue + fi # $pass = conv + + + # Get the name of the library we link against. + linklib= + if test -n "$old_library" && + { test yes = "$prefer_static_libs" || + test built,no = "$prefer_static_libs,$installed"; }; then + linklib=$old_library + else + for l in $old_library $library_names; do + linklib=$l + done + fi + if test -z "$linklib"; then + func_fatal_error "cannot find name of link library for '$lib'" + fi + + # This library was specified with -dlopen. + if test dlopen = "$pass"; then + test -z "$libdir" \ + && func_fatal_error "cannot -dlopen a convenience library: '$lib'" + if test -z "$dlname" || + test yes != "$dlopen_support" || + test no = "$build_libtool_libs" + then + # If there is no dlname, no dlopen support or we're linking + # statically, we need to preload. We also need to preload any + # dependent libraries so libltdl's deplib preloader doesn't + # bomb out in the load deplibs phase. + func_append dlprefiles " $lib $dependency_libs" + else + func_append newdlfiles " $lib" + fi + continue + fi # $pass = dlopen + + # We need an absolute path. + case $ladir in + [\\/]* | [A-Za-z]:[\\/]*) abs_ladir=$ladir ;; + *) + abs_ladir=`cd "$ladir" && pwd` + if test -z "$abs_ladir"; then + func_warning "cannot determine absolute directory name of '$ladir'" + func_warning "passing it literally to the linker, although it might fail" + abs_ladir=$ladir + fi + ;; + esac + func_basename "$lib" + laname=$func_basename_result + + # Find the relevant object directory and library name. + if test yes = "$installed"; then + if test ! -f "$lt_sysroot$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then + func_warning "library '$lib' was moved." + dir=$ladir + absdir=$abs_ladir + libdir=$abs_ladir + else + dir=$lt_sysroot$libdir + absdir=$lt_sysroot$libdir + fi + test yes = "$hardcode_automatic" && avoidtemprpath=yes + else + if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then + dir=$ladir + absdir=$abs_ladir + # Remove this search path later + func_append notinst_path " $abs_ladir" + else + dir=$ladir/$objdir + absdir=$abs_ladir/$objdir + # Remove this search path later + func_append notinst_path " $abs_ladir" + fi + fi # $installed = yes + func_stripname 'lib' '.la' "$laname" + name=$func_stripname_result + + # This library was specified with -dlpreopen. + if test dlpreopen = "$pass"; then + if test -z "$libdir" && test prog = "$linkmode"; then + func_fatal_error "only libraries may -dlpreopen a convenience library: '$lib'" + fi + case $host in + # special handling for platforms with PE-DLLs. + *cygwin* | *mingw* | *cegcc* ) + # Linker will automatically link against shared library if both + # static and shared are present. Therefore, ensure we extract + # symbols from the import library if a shared library is present + # (otherwise, the dlopen module name will be incorrect). We do + # this by putting the import library name into $newdlprefiles. + # We recover the dlopen module name by 'saving' the la file + # name in a special purpose variable, and (later) extracting the + # dlname from the la file. + if test -n "$dlname"; then + func_tr_sh "$dir/$linklib" + eval "libfile_$func_tr_sh_result=\$abs_ladir/\$laname" + func_append newdlprefiles " $dir/$linklib" + else + func_append newdlprefiles " $dir/$old_library" + # Keep a list of preopened convenience libraries to check + # that they are being used correctly in the link pass. + test -z "$libdir" && \ + func_append dlpreconveniencelibs " $dir/$old_library" + fi + ;; + * ) + # Prefer using a static library (so that no silly _DYNAMIC symbols + # are required to link). + if test -n "$old_library"; then + func_append newdlprefiles " $dir/$old_library" + # Keep a list of preopened convenience libraries to check + # that they are being used correctly in the link pass. + test -z "$libdir" && \ + func_append dlpreconveniencelibs " $dir/$old_library" + # Otherwise, use the dlname, so that lt_dlopen finds it. + elif test -n "$dlname"; then + func_append newdlprefiles " $dir/$dlname" + else + func_append newdlprefiles " $dir/$linklib" + fi + ;; + esac + fi # $pass = dlpreopen + + if test -z "$libdir"; then + # Link the convenience library + if test lib = "$linkmode"; then + deplibs="$dir/$old_library $deplibs" + elif test prog,link = "$linkmode,$pass"; then + compile_deplibs="$dir/$old_library $compile_deplibs" + finalize_deplibs="$dir/$old_library $finalize_deplibs" + else + deplibs="$lib $deplibs" # used for prog,scan pass + fi + continue + fi + + + if test prog = "$linkmode" && test link != "$pass"; then + func_append newlib_search_path " $ladir" + deplibs="$lib $deplibs" + + linkalldeplibs=false + if test no != "$link_all_deplibs" || test -z "$library_names" || + test no = "$build_libtool_libs"; then + linkalldeplibs=: + fi + + tmp_libs= + for deplib in $dependency_libs; do + case $deplib in + -L*) func_stripname '-L' '' "$deplib" + func_resolve_sysroot "$func_stripname_result" + func_append newlib_search_path " $func_resolve_sysroot_result" + ;; + esac + # Need to link against all dependency_libs? + if $linkalldeplibs; then + deplibs="$deplib $deplibs" + else + # Need to hardcode shared library paths + # or/and link against static libraries + newdependency_libs="$deplib $newdependency_libs" + fi + if $opt_preserve_dup_deps; then + case "$tmp_libs " in + *" $deplib "*) func_append specialdeplibs " $deplib" ;; + esac + fi + func_append tmp_libs " $deplib" + done # for deplib + continue + fi # $linkmode = prog... + + if test prog,link = "$linkmode,$pass"; then + if test -n "$library_names" && + { { test no = "$prefer_static_libs" || + test built,yes = "$prefer_static_libs,$installed"; } || + test -z "$old_library"; }; then + # We need to hardcode the library path + if test -n "$shlibpath_var" && test -z "$avoidtemprpath"; then + # Make sure the rpath contains only unique directories. + case $temp_rpath: in + *"$absdir:"*) ;; + *) func_append temp_rpath "$absdir:" ;; + esac + fi + + # Hardcode the library path. + # Skip directories that are in the system default run-time + # search path. + case " $sys_lib_dlsearch_path " in + *" $absdir "*) ;; + *) + case "$compile_rpath " in + *" $absdir "*) ;; + *) func_append compile_rpath " $absdir" ;; + esac + ;; + esac + case " $sys_lib_dlsearch_path " in + *" $libdir "*) ;; + *) + case "$finalize_rpath " in + *" $libdir "*) ;; + *) func_append finalize_rpath " $libdir" ;; + esac + ;; + esac + fi # $linkmode,$pass = prog,link... + + if $alldeplibs && + { test pass_all = "$deplibs_check_method" || + { test yes = "$build_libtool_libs" && + test -n "$library_names"; }; }; then + # We only need to search for static libraries + continue + fi + fi + + link_static=no # Whether the deplib will be linked statically + use_static_libs=$prefer_static_libs + if test built = "$use_static_libs" && test yes = "$installed"; then + use_static_libs=no + fi + if test -n "$library_names" && + { test no = "$use_static_libs" || test -z "$old_library"; }; then + case $host in + *cygwin* | *mingw* | *cegcc* | *os2*) + # No point in relinking DLLs because paths are not encoded + func_append notinst_deplibs " $lib" + need_relink=no + ;; + *) + if test no = "$installed"; then + func_append notinst_deplibs " $lib" + need_relink=yes + fi + ;; + esac + # This is a shared library + + # Warn about portability, can't link against -module's on some + # systems (darwin). Don't bleat about dlopened modules though! + dlopenmodule= + for dlpremoduletest in $dlprefiles; do + if test "X$dlpremoduletest" = "X$lib"; then + dlopenmodule=$dlpremoduletest + break + fi + done + if test -z "$dlopenmodule" && test yes = "$shouldnotlink" && test link = "$pass"; then + echo + if test prog = "$linkmode"; then + $ECHO "*** Warning: Linking the executable $output against the loadable module" + else + $ECHO "*** Warning: Linking the shared library $output against the loadable module" + fi + $ECHO "*** $linklib is not portable!" + fi + if test lib = "$linkmode" && + test yes = "$hardcode_into_libs"; then + # Hardcode the library path. + # Skip directories that are in the system default run-time + # search path. + case " $sys_lib_dlsearch_path " in + *" $absdir "*) ;; + *) + case "$compile_rpath " in + *" $absdir "*) ;; + *) func_append compile_rpath " $absdir" ;; + esac + ;; + esac + case " $sys_lib_dlsearch_path " in + *" $libdir "*) ;; + *) + case "$finalize_rpath " in + *" $libdir "*) ;; + *) func_append finalize_rpath " $libdir" ;; + esac + ;; + esac + fi + + if test -n "$old_archive_from_expsyms_cmds"; then + # figure out the soname + set dummy $library_names + shift + realname=$1 + shift + libname=`eval "\\$ECHO \"$libname_spec\""` + # use dlname if we got it. it's perfectly good, no? + if test -n "$dlname"; then + soname=$dlname + elif test -n "$soname_spec"; then + # bleh windows + case $host in + *cygwin* | mingw* | *cegcc* | *os2*) + func_arith $current - $age + major=$func_arith_result + versuffix=-$major + ;; + esac + eval soname=\"$soname_spec\" + else + soname=$realname + fi + + # Make a new name for the extract_expsyms_cmds to use + soroot=$soname + func_basename "$soroot" + soname=$func_basename_result + func_stripname 'lib' '.dll' "$soname" + newlib=libimp-$func_stripname_result.a + + # If the library has no export list, then create one now + if test -f "$output_objdir/$soname-def"; then : + else + func_verbose "extracting exported symbol list from '$soname'" + func_execute_cmds "$extract_expsyms_cmds" 'exit $?' + fi + + # Create $newlib + if test -f "$output_objdir/$newlib"; then :; else + func_verbose "generating import library for '$soname'" + func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?' + fi + # make sure the library variables are pointing to the new library + dir=$output_objdir + linklib=$newlib + fi # test -n "$old_archive_from_expsyms_cmds" + + if test prog = "$linkmode" || test relink != "$opt_mode"; then + add_shlibpath= + add_dir= + add= + lib_linked=yes + case $hardcode_action in + immediate | unsupported) + if test no = "$hardcode_direct"; then + add=$dir/$linklib + case $host in + *-*-sco3.2v5.0.[024]*) add_dir=-L$dir ;; + *-*-sysv4*uw2*) add_dir=-L$dir ;; + *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \ + *-*-unixware7*) add_dir=-L$dir ;; + *-*-darwin* ) + # if the lib is a (non-dlopened) module then we cannot + # link against it, someone is ignoring the earlier warnings + if /usr/bin/file -L $add 2> /dev/null | + $GREP ": [^:]* bundle" >/dev/null; then + if test "X$dlopenmodule" != "X$lib"; then + $ECHO "*** Warning: lib $linklib is a module, not a shared library" + if test -z "$old_library"; then + echo + echo "*** And there doesn't seem to be a static archive available" + echo "*** The link will probably fail, sorry" + else + add=$dir/$old_library + fi + elif test -n "$old_library"; then + add=$dir/$old_library + fi + fi + esac + elif test no = "$hardcode_minus_L"; then + case $host in + *-*-sunos*) add_shlibpath=$dir ;; + esac + add_dir=-L$dir + add=-l$name + elif test no = "$hardcode_shlibpath_var"; then + add_shlibpath=$dir + add=-l$name + else + lib_linked=no + fi + ;; + relink) + if test yes = "$hardcode_direct" && + test no = "$hardcode_direct_absolute"; then + add=$dir/$linklib + elif test yes = "$hardcode_minus_L"; then + add_dir=-L$absdir + # Try looking first in the location we're being installed to. + if test -n "$inst_prefix_dir"; then + case $libdir in + [\\/]*) + func_append add_dir " -L$inst_prefix_dir$libdir" + ;; + esac + fi + add=-l$name + elif test yes = "$hardcode_shlibpath_var"; then + add_shlibpath=$dir + add=-l$name + else + lib_linked=no + fi + ;; + *) lib_linked=no ;; + esac + + if test yes != "$lib_linked"; then + func_fatal_configuration "unsupported hardcode properties" + fi + + if test -n "$add_shlibpath"; then + case :$compile_shlibpath: in + *":$add_shlibpath:"*) ;; + *) func_append compile_shlibpath "$add_shlibpath:" ;; + esac + fi + if test prog = "$linkmode"; then + test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" + test -n "$add" && compile_deplibs="$add $compile_deplibs" + else + test -n "$add_dir" && deplibs="$add_dir $deplibs" + test -n "$add" && deplibs="$add $deplibs" + if test yes != "$hardcode_direct" && + test yes != "$hardcode_minus_L" && + test yes = "$hardcode_shlibpath_var"; then + case :$finalize_shlibpath: in + *":$libdir:"*) ;; + *) func_append finalize_shlibpath "$libdir:" ;; + esac + fi + fi + fi + + if test prog = "$linkmode" || test relink = "$opt_mode"; then + add_shlibpath= + add_dir= + add= + # Finalize command for both is simple: just hardcode it. + if test yes = "$hardcode_direct" && + test no = "$hardcode_direct_absolute"; then + add=$libdir/$linklib + elif test yes = "$hardcode_minus_L"; then + add_dir=-L$libdir + add=-l$name + elif test yes = "$hardcode_shlibpath_var"; then + case :$finalize_shlibpath: in + *":$libdir:"*) ;; + *) func_append finalize_shlibpath "$libdir:" ;; + esac + add=-l$name + elif test yes = "$hardcode_automatic"; then + if test -n "$inst_prefix_dir" && + test -f "$inst_prefix_dir$libdir/$linklib"; then + add=$inst_prefix_dir$libdir/$linklib + else + add=$libdir/$linklib + fi + else + # We cannot seem to hardcode it, guess we'll fake it. + add_dir=-L$libdir + # Try looking first in the location we're being installed to. + if test -n "$inst_prefix_dir"; then + case $libdir in + [\\/]*) + func_append add_dir " -L$inst_prefix_dir$libdir" + ;; + esac + fi + add=-l$name + fi + + if test prog = "$linkmode"; then + test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" + test -n "$add" && finalize_deplibs="$add $finalize_deplibs" + else + test -n "$add_dir" && deplibs="$add_dir $deplibs" + test -n "$add" && deplibs="$add $deplibs" + fi + fi + elif test prog = "$linkmode"; then + # Here we assume that one of hardcode_direct or hardcode_minus_L + # is not unsupported. This is valid on all known static and + # shared platforms. + if test unsupported != "$hardcode_direct"; then + test -n "$old_library" && linklib=$old_library + compile_deplibs="$dir/$linklib $compile_deplibs" + finalize_deplibs="$dir/$linklib $finalize_deplibs" + else + compile_deplibs="-l$name -L$dir $compile_deplibs" + finalize_deplibs="-l$name -L$dir $finalize_deplibs" + fi + elif test yes = "$build_libtool_libs"; then + # Not a shared library + if test pass_all != "$deplibs_check_method"; then + # We're trying link a shared library against a static one + # but the system doesn't support it. + + # Just print a warning and add the library to dependency_libs so + # that the program can be linked against the static library. + echo + $ECHO "*** Warning: This system cannot link to static lib archive $lib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have." + if test yes = "$module"; then + echo "*** But as you try to build a module library, libtool will still create " + echo "*** a static module, that should work as long as the dlopening application" + echo "*** is linked with the -dlopen flag to resolve symbols at runtime." + if test -z "$global_symbol_pipe"; then + echo + echo "*** However, this would only work if libtool was able to extract symbol" + echo "*** lists from a program, using 'nm' or equivalent, but libtool could" + echo "*** not find such a program. So, this module is probably useless." + echo "*** 'nm' from GNU binutils and a full rebuild may help." + fi + if test no = "$build_old_libs"; then + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + fi + else + deplibs="$dir/$old_library $deplibs" + link_static=yes + fi + fi # link shared/static library? + + if test lib = "$linkmode"; then + if test -n "$dependency_libs" && + { test yes != "$hardcode_into_libs" || + test yes = "$build_old_libs" || + test yes = "$link_static"; }; then + # Extract -R from dependency_libs + temp_deplibs= + for libdir in $dependency_libs; do + case $libdir in + -R*) func_stripname '-R' '' "$libdir" + temp_xrpath=$func_stripname_result + case " $xrpath " in + *" $temp_xrpath "*) ;; + *) func_append xrpath " $temp_xrpath";; + esac;; + *) func_append temp_deplibs " $libdir";; + esac + done + dependency_libs=$temp_deplibs + fi + + func_append newlib_search_path " $absdir" + # Link against this library + test no = "$link_static" && newdependency_libs="$abs_ladir/$laname $newdependency_libs" + # ... and its dependency_libs + tmp_libs= + for deplib in $dependency_libs; do + newdependency_libs="$deplib $newdependency_libs" + case $deplib in + -L*) func_stripname '-L' '' "$deplib" + func_resolve_sysroot "$func_stripname_result";; + *) func_resolve_sysroot "$deplib" ;; + esac + if $opt_preserve_dup_deps; then + case "$tmp_libs " in + *" $func_resolve_sysroot_result "*) + func_append specialdeplibs " $func_resolve_sysroot_result" ;; + esac + fi + func_append tmp_libs " $func_resolve_sysroot_result" + done + + if test no != "$link_all_deplibs"; then + # Add the search paths of all dependency libraries + for deplib in $dependency_libs; do + path= + case $deplib in + -L*) path=$deplib ;; + *.la) + func_resolve_sysroot "$deplib" + deplib=$func_resolve_sysroot_result + func_dirname "$deplib" "" "." + dir=$func_dirname_result + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) absdir=$dir ;; + *) + absdir=`cd "$dir" && pwd` + if test -z "$absdir"; then + func_warning "cannot determine absolute directory name of '$dir'" + absdir=$dir + fi + ;; + esac + if $GREP "^installed=no" $deplib > /dev/null; then + case $host in + *-*-darwin*) + depdepl= + eval deplibrary_names=`$SED -n -e 's/^library_names=\(.*\)$/\1/p' $deplib` + if test -n "$deplibrary_names"; then + for tmp in $deplibrary_names; do + depdepl=$tmp + done + if test -f "$absdir/$objdir/$depdepl"; then + depdepl=$absdir/$objdir/$depdepl + darwin_install_name=`$OTOOL -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` + if test -z "$darwin_install_name"; then + darwin_install_name=`$OTOOL64 -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` + fi + func_append compiler_flags " $wl-dylib_file $wl$darwin_install_name:$depdepl" + func_append linker_flags " -dylib_file $darwin_install_name:$depdepl" + path= + fi + fi + ;; + *) + path=-L$absdir/$objdir + ;; + esac + else + eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` + test -z "$libdir" && \ + func_fatal_error "'$deplib' is not a valid libtool archive" + test "$absdir" != "$libdir" && \ + func_warning "'$deplib' seems to be moved" + + path=-L$absdir + fi + ;; + esac + case " $deplibs " in + *" $path "*) ;; + *) deplibs="$path $deplibs" ;; + esac + done + fi # link_all_deplibs != no + fi # linkmode = lib + done # for deplib in $libs + if test link = "$pass"; then + if test prog = "$linkmode"; then + compile_deplibs="$new_inherited_linker_flags $compile_deplibs" + finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs" + else + compiler_flags="$compiler_flags "`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + fi + fi + dependency_libs=$newdependency_libs + if test dlpreopen = "$pass"; then + # Link the dlpreopened libraries before other libraries + for deplib in $save_deplibs; do + deplibs="$deplib $deplibs" + done + fi + if test dlopen != "$pass"; then + test conv = "$pass" || { + # Make sure lib_search_path contains only unique directories. + lib_search_path= + for dir in $newlib_search_path; do + case "$lib_search_path " in + *" $dir "*) ;; + *) func_append lib_search_path " $dir" ;; + esac + done + newlib_search_path= + } + + if test prog,link = "$linkmode,$pass"; then + vars="compile_deplibs finalize_deplibs" + else + vars=deplibs + fi + for var in $vars dependency_libs; do + # Add libraries to $var in reverse order + eval tmp_libs=\"\$$var\" + new_libs= + for deplib in $tmp_libs; do + # FIXME: Pedantically, this is the right thing to do, so + # that some nasty dependency loop isn't accidentally + # broken: + #new_libs="$deplib $new_libs" + # Pragmatically, this seems to cause very few problems in + # practice: + case $deplib in + -L*) new_libs="$deplib $new_libs" ;; + -R*) ;; + *) + # And here is the reason: when a library appears more + # than once as an explicit dependence of a library, or + # is implicitly linked in more than once by the + # compiler, it is considered special, and multiple + # occurrences thereof are not removed. Compare this + # with having the same library being listed as a + # dependency of multiple other libraries: in this case, + # we know (pedantically, we assume) the library does not + # need to be listed more than once, so we keep only the + # last copy. This is not always right, but it is rare + # enough that we require users that really mean to play + # such unportable linking tricks to link the library + # using -Wl,-lname, so that libtool does not consider it + # for duplicate removal. + case " $specialdeplibs " in + *" $deplib "*) new_libs="$deplib $new_libs" ;; + *) + case " $new_libs " in + *" $deplib "*) ;; + *) new_libs="$deplib $new_libs" ;; + esac + ;; + esac + ;; + esac + done + tmp_libs= + for deplib in $new_libs; do + case $deplib in + -L*) + case " $tmp_libs " in + *" $deplib "*) ;; + *) func_append tmp_libs " $deplib" ;; + esac + ;; + *) func_append tmp_libs " $deplib" ;; + esac + done + eval $var=\"$tmp_libs\" + done # for var + fi + + # Add Sun CC postdeps if required: + test CXX = "$tagname" && { + case $host_os in + linux*) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) # Sun C++ 5.9 + func_suncc_cstd_abi + + if test no != "$suncc_use_cstd_abi"; then + func_append postdeps ' -library=Cstd -library=Crun' + fi + ;; + esac + ;; + + solaris*) + func_cc_basename "$CC" + case $func_cc_basename_result in + CC* | sunCC*) + func_suncc_cstd_abi + + if test no != "$suncc_use_cstd_abi"; then + func_append postdeps ' -library=Cstd -library=Crun' + fi + ;; + esac + ;; + esac + } + + # Last step: remove runtime libs from dependency_libs + # (they stay in deplibs) + tmp_libs= + for i in $dependency_libs; do + case " $predeps $postdeps $compiler_lib_search_path " in + *" $i "*) + i= + ;; + esac + if test -n "$i"; then + func_append tmp_libs " $i" + fi + done + dependency_libs=$tmp_libs + done # for pass + if test prog = "$linkmode"; then + dlfiles=$newdlfiles + fi + if test prog = "$linkmode" || test lib = "$linkmode"; then + dlprefiles=$newdlprefiles + fi + + case $linkmode in + oldlib) + if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then + func_warning "'-dlopen' is ignored for archives" + fi + + case " $deplibs" in + *\ -l* | *\ -L*) + func_warning "'-l' and '-L' are ignored for archives" ;; + esac + + test -n "$rpath" && \ + func_warning "'-rpath' is ignored for archives" + + test -n "$xrpath" && \ + func_warning "'-R' is ignored for archives" + + test -n "$vinfo" && \ + func_warning "'-version-info/-version-number' is ignored for archives" + + test -n "$release" && \ + func_warning "'-release' is ignored for archives" + + test -n "$export_symbols$export_symbols_regex" && \ + func_warning "'-export-symbols' is ignored for archives" + + # Now set the variables for building old libraries. + build_libtool_libs=no + oldlibs=$output + func_append objs "$old_deplibs" + ;; + + lib) + # Make sure we only generate libraries of the form 'libNAME.la'. + case $outputname in + lib*) + func_stripname 'lib' '.la' "$outputname" + name=$func_stripname_result + eval shared_ext=\"$shrext_cmds\" + eval libname=\"$libname_spec\" + ;; + *) + test no = "$module" \ + && func_fatal_help "libtool library '$output' must begin with 'lib'" + + if test no != "$need_lib_prefix"; then + # Add the "lib" prefix for modules if required + func_stripname '' '.la' "$outputname" + name=$func_stripname_result + eval shared_ext=\"$shrext_cmds\" + eval libname=\"$libname_spec\" + else + func_stripname '' '.la' "$outputname" + libname=$func_stripname_result + fi + ;; + esac + + if test -n "$objs"; then + if test pass_all != "$deplibs_check_method"; then + func_fatal_error "cannot build libtool library '$output' from non-libtool objects on this host:$objs" + else + echo + $ECHO "*** Warning: Linking the shared library $output against the non-libtool" + $ECHO "*** objects $objs is not portable!" + func_append libobjs " $objs" + fi + fi + + test no = "$dlself" \ + || func_warning "'-dlopen self' is ignored for libtool libraries" + + set dummy $rpath + shift + test 1 -lt "$#" \ + && func_warning "ignoring multiple '-rpath's for a libtool library" + + install_libdir=$1 + + oldlibs= + if test -z "$rpath"; then + if test yes = "$build_libtool_libs"; then + # Building a libtool convenience library. + # Some compilers have problems with a '.al' extension so + # convenience libraries should have the same extension an + # archive normally would. + oldlibs="$output_objdir/$libname.$libext $oldlibs" + build_libtool_libs=convenience + build_old_libs=yes + fi + + test -n "$vinfo" && \ + func_warning "'-version-info/-version-number' is ignored for convenience libraries" + + test -n "$release" && \ + func_warning "'-release' is ignored for convenience libraries" + else + + # Parse the version information argument. + save_ifs=$IFS; IFS=: + set dummy $vinfo 0 0 0 + shift + IFS=$save_ifs + + test -n "$7" && \ + func_fatal_help "too many parameters to '-version-info'" + + # convert absolute version numbers to libtool ages + # this retains compatibility with .la files and attempts + # to make the code below a bit more comprehensible + + case $vinfo_number in + yes) + number_major=$1 + number_minor=$2 + number_revision=$3 + # + # There are really only two kinds -- those that + # use the current revision as the major version + # and those that subtract age and use age as + # a minor version. But, then there is irix + # that has an extra 1 added just for fun + # + case $version_type in + # correct linux to gnu/linux during the next big refactor + darwin|freebsd-elf|linux|osf|windows|none) + func_arith $number_major + $number_minor + current=$func_arith_result + age=$number_minor + revision=$number_revision + ;; + freebsd-aout|qnx|sunos) + current=$number_major + revision=$number_minor + age=0 + ;; + irix|nonstopux) + func_arith $number_major + $number_minor + current=$func_arith_result + age=$number_minor + revision=$number_minor + lt_irix_increment=no + ;; + *) + func_fatal_configuration "$modename: unknown library version type '$version_type'" + ;; + esac + ;; + no) + current=$1 + revision=$2 + age=$3 + ;; + esac + + # Check that each of the things are valid numbers. + case $current in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + func_error "CURRENT '$current' must be a nonnegative integer" + func_fatal_error "'$vinfo' is not valid version information" + ;; + esac + + case $revision in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + func_error "REVISION '$revision' must be a nonnegative integer" + func_fatal_error "'$vinfo' is not valid version information" + ;; + esac + + case $age in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + func_error "AGE '$age' must be a nonnegative integer" + func_fatal_error "'$vinfo' is not valid version information" + ;; + esac + + if test "$age" -gt "$current"; then + func_error "AGE '$age' is greater than the current interface number '$current'" + func_fatal_error "'$vinfo' is not valid version information" + fi + + # Calculate the version variables. + major= + versuffix= + verstring= + case $version_type in + none) ;; + + darwin) + # Like Linux, but with the current version available in + # verstring for coding it into the library header + func_arith $current - $age + major=.$func_arith_result + versuffix=$major.$age.$revision + # Darwin ld doesn't like 0 for these options... + func_arith $current + 1 + minor_current=$func_arith_result + xlcverstring="$wl-compatibility_version $wl$minor_current $wl-current_version $wl$minor_current.$revision" + verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" + # On Darwin other compilers + case $CC in + nagfor*) + verstring="$wl-compatibility_version $wl$minor_current $wl-current_version $wl$minor_current.$revision" + ;; + *) + verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" + ;; + esac + ;; + + freebsd-aout) + major=.$current + versuffix=.$current.$revision + ;; + + freebsd-elf) + func_arith $current - $age + major=.$func_arith_result + versuffix=$major.$age.$revision + ;; + + irix | nonstopux) + if test no = "$lt_irix_increment"; then + func_arith $current - $age + else + func_arith $current - $age + 1 + fi + major=$func_arith_result + + case $version_type in + nonstopux) verstring_prefix=nonstopux ;; + *) verstring_prefix=sgi ;; + esac + verstring=$verstring_prefix$major.$revision + + # Add in all the interfaces that we are compatible with. + loop=$revision + while test 0 -ne "$loop"; do + func_arith $revision - $loop + iface=$func_arith_result + func_arith $loop - 1 + loop=$func_arith_result + verstring=$verstring_prefix$major.$iface:$verstring + done + + # Before this point, $major must not contain '.'. + major=.$major + versuffix=$major.$revision + ;; + + linux) # correct to gnu/linux during the next big refactor + func_arith $current - $age + major=.$func_arith_result + versuffix=$major.$age.$revision + ;; + + osf) + func_arith $current - $age + major=.$func_arith_result + versuffix=.$current.$age.$revision + verstring=$current.$age.$revision + + # Add in all the interfaces that we are compatible with. + loop=$age + while test 0 -ne "$loop"; do + func_arith $current - $loop + iface=$func_arith_result + func_arith $loop - 1 + loop=$func_arith_result + verstring=$verstring:$iface.0 + done + + # Make executables depend on our current version. + func_append verstring ":$current.0" + ;; + + qnx) + major=.$current + versuffix=.$current + ;; + + sco) + major=.$current + versuffix=.$current + ;; + + sunos) + major=.$current + versuffix=.$current.$revision + ;; + + windows) + # Use '-' rather than '.', since we only want one + # extension on DOS 8.3 file systems. + func_arith $current - $age + major=$func_arith_result + versuffix=-$major + ;; + + *) + func_fatal_configuration "unknown library version type '$version_type'" + ;; + esac + + # Clear the version info if we defaulted, and they specified a release. + if test -z "$vinfo" && test -n "$release"; then + major= + case $version_type in + darwin) + # we can't check for "0.0" in archive_cmds due to quoting + # problems, so we reset it completely + verstring= + ;; + *) + verstring=0.0 + ;; + esac + if test no = "$need_version"; then + versuffix= + else + versuffix=.0.0 + fi + fi + + # Remove version info from name if versioning should be avoided + if test yes,no = "$avoid_version,$need_version"; then + major= + versuffix= + verstring= + fi + + # Check to see if the archive will have undefined symbols. + if test yes = "$allow_undefined"; then + if test unsupported = "$allow_undefined_flag"; then + if test yes = "$build_old_libs"; then + func_warning "undefined symbols not allowed in $host shared libraries; building static only" + build_libtool_libs=no + else + func_fatal_error "can't build $host shared library unless -no-undefined is specified" + fi + fi + else + # Don't allow undefined symbols. + allow_undefined_flag=$no_undefined_flag + fi + + fi + + func_generate_dlsyms "$libname" "$libname" : + func_append libobjs " $symfileobj" + test " " = "$libobjs" && libobjs= + + if test relink != "$opt_mode"; then + # Remove our outputs, but don't remove object files since they + # may have been created when compiling PIC objects. + removelist= + tempremovelist=`$ECHO "$output_objdir/*"` + for p in $tempremovelist; do + case $p in + *.$objext | *.gcno) + ;; + $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/$libname$release.*) + if test -n "$precious_files_regex"; then + if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1 + then + continue + fi + fi + func_append removelist " $p" + ;; + *) ;; + esac + done + test -n "$removelist" && \ + func_show_eval "${RM}r \$removelist" + fi + + # Now set the variables for building old libraries. + if test yes = "$build_old_libs" && test convenience != "$build_libtool_libs"; then + func_append oldlibs " $output_objdir/$libname.$libext" + + # Transform .lo files to .o files. + oldobjs="$objs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.$libext$/d; $lo2o" | $NL2SP` + fi + + # Eliminate all temporary directories. + #for path in $notinst_path; do + # lib_search_path=`$ECHO "$lib_search_path " | $SED "s% $path % %g"` + # deplibs=`$ECHO "$deplibs " | $SED "s% -L$path % %g"` + # dependency_libs=`$ECHO "$dependency_libs " | $SED "s% -L$path % %g"` + #done + + if test -n "$xrpath"; then + # If the user specified any rpath flags, then add them. + temp_xrpath= + for libdir in $xrpath; do + func_replace_sysroot "$libdir" + func_append temp_xrpath " -R$func_replace_sysroot_result" + case "$finalize_rpath " in + *" $libdir "*) ;; + *) func_append finalize_rpath " $libdir" ;; + esac + done + if test yes != "$hardcode_into_libs" || test yes = "$build_old_libs"; then + dependency_libs="$temp_xrpath $dependency_libs" + fi + fi + + # Make sure dlfiles contains only unique files that won't be dlpreopened + old_dlfiles=$dlfiles + dlfiles= + for lib in $old_dlfiles; do + case " $dlprefiles $dlfiles " in + *" $lib "*) ;; + *) func_append dlfiles " $lib" ;; + esac + done + + # Make sure dlprefiles contains only unique files + old_dlprefiles=$dlprefiles + dlprefiles= + for lib in $old_dlprefiles; do + case "$dlprefiles " in + *" $lib "*) ;; + *) func_append dlprefiles " $lib" ;; + esac + done + + if test yes = "$build_libtool_libs"; then + if test -n "$rpath"; then + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc* | *-*-haiku*) + # these systems don't actually have a c library (as such)! + ;; + *-*-rhapsody* | *-*-darwin1.[012]) + # Rhapsody C library is in the System framework + func_append deplibs " System.ltframework" + ;; + *-*-netbsd*) + # Don't link with libc until the a.out ld.so is fixed. + ;; + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + # Do not include libc due to us having libc/libc_r. + ;; + *-*-sco3.2v5* | *-*-sco5v6*) + # Causes problems with __ctype + ;; + *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) + # Compiler inserts libc in the correct place for threads to work + ;; + *) + # Add libc to deplibs on all other systems if necessary. + if test yes = "$build_libtool_need_lc"; then + func_append deplibs " -lc" + fi + ;; + esac + fi + + # Transform deplibs into only deplibs that can be linked in shared. + name_save=$name + libname_save=$libname + release_save=$release + versuffix_save=$versuffix + major_save=$major + # I'm not sure if I'm treating the release correctly. I think + # release should show up in the -l (ie -lgmp5) so we don't want to + # add it in twice. Is that correct? + release= + versuffix= + major= + newdeplibs= + droppeddeps=no + case $deplibs_check_method in + pass_all) + # Don't check for shared/static. Everything works. + # This might be a little naive. We might want to check + # whether the library exists or not. But this is on + # osf3 & osf4 and I'm not really sure... Just + # implementing what was already the behavior. + newdeplibs=$deplibs + ;; + test_compile) + # This code stresses the "libraries are programs" paradigm to its + # limits. Maybe even breaks it. We compile a program, linking it + # against the deplibs as a proxy for the library. Then we can check + # whether they linked in statically or dynamically with ldd. + $opt_dry_run || $RM conftest.c + cat > conftest.c </dev/null` + $nocaseglob + else + potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null` + fi + for potent_lib in $potential_libs; do + # Follow soft links. + if ls -lLd "$potent_lib" 2>/dev/null | + $GREP " -> " >/dev/null; then + continue + fi + # The statement above tries to avoid entering an + # endless loop below, in case of cyclic links. + # We might still enter an endless loop, since a link + # loop can be closed while we follow links, + # but so what? + potlib=$potent_lib + while test -h "$potlib" 2>/dev/null; do + potliblink=`ls -ld $potlib | $SED 's/.* -> //'` + case $potliblink in + [\\/]* | [A-Za-z]:[\\/]*) potlib=$potliblink;; + *) potlib=`$ECHO "$potlib" | $SED 's|[^/]*$||'`"$potliblink";; + esac + done + if eval $file_magic_cmd \"\$potlib\" 2>/dev/null | + $SED -e 10q | + $EGREP "$file_magic_regex" > /dev/null; then + func_append newdeplibs " $a_deplib" + a_deplib= + break 2 + fi + done + done + fi + if test -n "$a_deplib"; then + droppeddeps=yes + echo + $ECHO "*** Warning: linker path does not have real file for library $a_deplib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have" + echo "*** because I did check the linker path looking for a file starting" + if test -z "$potlib"; then + $ECHO "*** with $libname but no candidates were found. (...for file magic test)" + else + $ECHO "*** with $libname and none of the candidates passed a file format test" + $ECHO "*** using a file magic. Last file checked: $potlib" + fi + fi + ;; + *) + # Add a -L argument. + func_append newdeplibs " $a_deplib" + ;; + esac + done # Gone through all deplibs. + ;; + match_pattern*) + set dummy $deplibs_check_method; shift + match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` + for a_deplib in $deplibs; do + case $a_deplib in + -l*) + func_stripname -l '' "$a_deplib" + name=$func_stripname_result + if test yes = "$allow_libtool_libs_with_static_runtimes"; then + case " $predeps $postdeps " in + *" $a_deplib "*) + func_append newdeplibs " $a_deplib" + a_deplib= + ;; + esac + fi + if test -n "$a_deplib"; then + libname=`eval "\\$ECHO \"$libname_spec\""` + for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do + potential_libs=`ls $i/$libname[.-]* 2>/dev/null` + for potent_lib in $potential_libs; do + potlib=$potent_lib # see symlink-check above in file_magic test + if eval "\$ECHO \"$potent_lib\"" 2>/dev/null | $SED 10q | \ + $EGREP "$match_pattern_regex" > /dev/null; then + func_append newdeplibs " $a_deplib" + a_deplib= + break 2 + fi + done + done + fi + if test -n "$a_deplib"; then + droppeddeps=yes + echo + $ECHO "*** Warning: linker path does not have real file for library $a_deplib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have" + echo "*** because I did check the linker path looking for a file starting" + if test -z "$potlib"; then + $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)" + else + $ECHO "*** with $libname and none of the candidates passed a file format test" + $ECHO "*** using a regex pattern. Last file checked: $potlib" + fi + fi + ;; + *) + # Add a -L argument. + func_append newdeplibs " $a_deplib" + ;; + esac + done # Gone through all deplibs. + ;; + none | unknown | *) + newdeplibs= + tmp_deplibs=`$ECHO " $deplibs" | $SED 's/ -lc$//; s/ -[LR][^ ]*//g'` + if test yes = "$allow_libtool_libs_with_static_runtimes"; then + for i in $predeps $postdeps; do + # can't use Xsed below, because $i might contain '/' + tmp_deplibs=`$ECHO " $tmp_deplibs" | $SED "s|$i||"` + done + fi + case $tmp_deplibs in + *[!\ \ ]*) + echo + if test none = "$deplibs_check_method"; then + echo "*** Warning: inter-library dependencies are not supported in this platform." + else + echo "*** Warning: inter-library dependencies are not known to be supported." + fi + echo "*** All declared inter-library dependencies are being dropped." + droppeddeps=yes + ;; + esac + ;; + esac + versuffix=$versuffix_save + major=$major_save + release=$release_save + libname=$libname_save + name=$name_save + + case $host in + *-*-rhapsody* | *-*-darwin1.[012]) + # On Rhapsody replace the C library with the System framework + newdeplibs=`$ECHO " $newdeplibs" | $SED 's/ -lc / System.ltframework /'` + ;; + esac + + if test yes = "$droppeddeps"; then + if test yes = "$module"; then + echo + echo "*** Warning: libtool could not satisfy all declared inter-library" + $ECHO "*** dependencies of module $libname. Therefore, libtool will create" + echo "*** a static module, that should work as long as the dlopening" + echo "*** application is linked with the -dlopen flag." + if test -z "$global_symbol_pipe"; then + echo + echo "*** However, this would only work if libtool was able to extract symbol" + echo "*** lists from a program, using 'nm' or equivalent, but libtool could" + echo "*** not find such a program. So, this module is probably useless." + echo "*** 'nm' from GNU binutils and a full rebuild may help." + fi + if test no = "$build_old_libs"; then + oldlibs=$output_objdir/$libname.$libext + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + else + echo "*** The inter-library dependencies that have been dropped here will be" + echo "*** automatically added whenever a program is linked with this library" + echo "*** or is declared to -dlopen it." + + if test no = "$allow_undefined"; then + echo + echo "*** Since this library must not contain undefined symbols," + echo "*** because either the platform does not support them or" + echo "*** it was explicitly requested with -no-undefined," + echo "*** libtool will only create a static version of it." + if test no = "$build_old_libs"; then + oldlibs=$output_objdir/$libname.$libext + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + fi + fi + fi + # Done checking deplibs! + deplibs=$newdeplibs + fi + # Time to change all our "foo.ltframework" stuff back to "-framework foo" + case $host in + *-*-darwin*) + newdeplibs=`$ECHO " $newdeplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + new_inherited_linker_flags=`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + deplibs=`$ECHO " $deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + ;; + esac + + # move library search paths that coincide with paths to not yet + # installed libraries to the beginning of the library search list + new_libs= + for path in $notinst_path; do + case " $new_libs " in + *" -L$path/$objdir "*) ;; + *) + case " $deplibs " in + *" -L$path/$objdir "*) + func_append new_libs " -L$path/$objdir" ;; + esac + ;; + esac + done + for deplib in $deplibs; do + case $deplib in + -L*) + case " $new_libs " in + *" $deplib "*) ;; + *) func_append new_libs " $deplib" ;; + esac + ;; + *) func_append new_libs " $deplib" ;; + esac + done + deplibs=$new_libs + + # All the library-specific variables (install_libdir is set above). + library_names= + old_library= + dlname= + + # Test again, we may have decided not to build it any more + if test yes = "$build_libtool_libs"; then + # Remove $wl instances when linking with ld. + # FIXME: should test the right _cmds variable. + case $archive_cmds in + *\$LD\ *) wl= ;; + esac + if test yes = "$hardcode_into_libs"; then + # Hardcode the library paths + hardcode_libdirs= + dep_rpath= + rpath=$finalize_rpath + test relink = "$opt_mode" || rpath=$compile_rpath$rpath + for libdir in $rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + func_replace_sysroot "$libdir" + libdir=$func_replace_sysroot_result + if test -z "$hardcode_libdirs"; then + hardcode_libdirs=$libdir + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + func_append dep_rpath " $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) func_append perm_rpath " $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir=$hardcode_libdirs + eval "dep_rpath=\"$hardcode_libdir_flag_spec\"" + fi + if test -n "$runpath_var" && test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + func_append rpath "$dir:" + done + eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" + fi + test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" + fi + + shlibpath=$finalize_shlibpath + test relink = "$opt_mode" || shlibpath=$compile_shlibpath$shlibpath + if test -n "$shlibpath"; then + eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" + fi + + # Get the real and link names of the library. + eval shared_ext=\"$shrext_cmds\" + eval library_names=\"$library_names_spec\" + set dummy $library_names + shift + realname=$1 + shift + + if test -n "$soname_spec"; then + eval soname=\"$soname_spec\" + else + soname=$realname + fi + if test -z "$dlname"; then + dlname=$soname + fi + + lib=$output_objdir/$realname + linknames= + for link + do + func_append linknames " $link" + done + + # Use standard objects if they are pic + test -z "$pic_flag" && libobjs=`$ECHO "$libobjs" | $SP2NL | $SED "$lo2o" | $NL2SP` + test "X$libobjs" = "X " && libobjs= + + delfiles= + if test -n "$export_symbols" && test -n "$include_expsyms"; then + $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp" + export_symbols=$output_objdir/$libname.uexp + func_append delfiles " $export_symbols" + fi + + orig_export_symbols= + case $host_os in + cygwin* | mingw* | cegcc*) + if test -n "$export_symbols" && test -z "$export_symbols_regex"; then + # exporting using user supplied symfile + func_dll_def_p "$export_symbols" || { + # and it's NOT already a .def file. Must figure out + # which of the given symbols are data symbols and tag + # them as such. So, trigger use of export_symbols_cmds. + # export_symbols gets reassigned inside the "prepare + # the list of exported symbols" if statement, so the + # include_expsyms logic still works. + orig_export_symbols=$export_symbols + export_symbols= + always_export_symbols=yes + } + fi + ;; + esac + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + if test yes = "$always_export_symbols" || test -n "$export_symbols_regex"; then + func_verbose "generating symbol list for '$libname.la'" + export_symbols=$output_objdir/$libname.exp + $opt_dry_run || $RM $export_symbols + cmds=$export_symbols_cmds + save_ifs=$IFS; IFS='~' + for cmd1 in $cmds; do + IFS=$save_ifs + # Take the normal branch if the nm_file_list_spec branch + # doesn't work or if tool conversion is not needed. + case $nm_file_list_spec~$to_tool_file_cmd in + *~func_convert_file_noop | *~func_convert_file_msys_to_w32 | ~*) + try_normal_branch=yes + eval cmd=\"$cmd1\" + func_len " $cmd" + len=$func_len_result + ;; + *) + try_normal_branch=no + ;; + esac + if test yes = "$try_normal_branch" \ + && { test "$len" -lt "$max_cmd_len" \ + || test "$max_cmd_len" -le -1; } + then + func_show_eval "$cmd" 'exit $?' + skipped_export=false + elif test -n "$nm_file_list_spec"; then + func_basename "$output" + output_la=$func_basename_result + save_libobjs=$libobjs + save_output=$output + output=$output_objdir/$output_la.nm + func_to_tool_file "$output" + libobjs=$nm_file_list_spec$func_to_tool_file_result + func_append delfiles " $output" + func_verbose "creating $NM input file list: $output" + for obj in $save_libobjs; do + func_to_tool_file "$obj" + $ECHO "$func_to_tool_file_result" + done > "$output" + eval cmd=\"$cmd1\" + func_show_eval "$cmd" 'exit $?' + output=$save_output + libobjs=$save_libobjs + skipped_export=false + else + # The command line is too long to execute in one step. + func_verbose "using reloadable object file for export list..." + skipped_export=: + # Break out early, otherwise skipped_export may be + # set to false by a later but shorter cmd. + break + fi + done + IFS=$save_ifs + if test -n "$export_symbols_regex" && test : != "$skipped_export"; then + func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' + func_show_eval '$MV "${export_symbols}T" "$export_symbols"' + fi + fi + fi + + if test -n "$export_symbols" && test -n "$include_expsyms"; then + tmp_export_symbols=$export_symbols + test -n "$orig_export_symbols" && tmp_export_symbols=$orig_export_symbols + $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' + fi + + if test : != "$skipped_export" && test -n "$orig_export_symbols"; then + # The given exports_symbols file has to be filtered, so filter it. + func_verbose "filter symbol list for '$libname.la' to tag DATA exports" + # FIXME: $output_objdir/$libname.filter potentially contains lots of + # 's' commands, which not all seds can handle. GNU sed should be fine + # though. Also, the filter scales superlinearly with the number of + # global variables. join(1) would be nice here, but unfortunately + # isn't a blessed tool. + $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter + func_append delfiles " $export_symbols $output_objdir/$libname.filter" + export_symbols=$output_objdir/$libname.def + $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols + fi + + tmp_deplibs= + for test_deplib in $deplibs; do + case " $convenience " in + *" $test_deplib "*) ;; + *) + func_append tmp_deplibs " $test_deplib" + ;; + esac + done + deplibs=$tmp_deplibs + + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec" && + test yes = "$compiler_needs_object" && + test -z "$libobjs"; then + # extract the archives, so we have objects to list. + # TODO: could optimize this to just extract one archive. + whole_archive_flag_spec= + fi + if test -n "$whole_archive_flag_spec"; then + save_libobjs=$libobjs + eval libobjs=\"\$libobjs $whole_archive_flag_spec\" + test "X$libobjs" = "X " && libobjs= + else + gentop=$output_objdir/${outputname}x + func_append generated " $gentop" + + func_extract_archives $gentop $convenience + func_append libobjs " $func_extract_archives_result" + test "X$libobjs" = "X " && libobjs= + fi + fi + + if test yes = "$thread_safe" && test -n "$thread_safe_flag_spec"; then + eval flag=\"$thread_safe_flag_spec\" + func_append linker_flags " $flag" + fi + + # Make a backup of the uninstalled library when relinking + if test relink = "$opt_mode"; then + $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $? + fi + + # Do each of the archive commands. + if test yes = "$module" && test -n "$module_cmds"; then + if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then + eval test_cmds=\"$module_expsym_cmds\" + cmds=$module_expsym_cmds + else + eval test_cmds=\"$module_cmds\" + cmds=$module_cmds + fi + else + if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then + eval test_cmds=\"$archive_expsym_cmds\" + cmds=$archive_expsym_cmds + else + eval test_cmds=\"$archive_cmds\" + cmds=$archive_cmds + fi + fi + + if test : != "$skipped_export" && + func_len " $test_cmds" && + len=$func_len_result && + test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then + : + else + # The command line is too long to link in one step, link piecewise + # or, if using GNU ld and skipped_export is not :, use a linker + # script. + + # Save the value of $output and $libobjs because we want to + # use them later. If we have whole_archive_flag_spec, we + # want to use save_libobjs as it was before + # whole_archive_flag_spec was expanded, because we can't + # assume the linker understands whole_archive_flag_spec. + # This may have to be revisited, in case too many + # convenience libraries get linked in and end up exceeding + # the spec. + if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then + save_libobjs=$libobjs + fi + save_output=$output + func_basename "$output" + output_la=$func_basename_result + + # Clear the reloadable object creation command queue and + # initialize k to one. + test_cmds= + concat_cmds= + objlist= + last_robj= + k=1 + + if test -n "$save_libobjs" && test : != "$skipped_export" && test yes = "$with_gnu_ld"; then + output=$output_objdir/$output_la.lnkscript + func_verbose "creating GNU ld script: $output" + echo 'INPUT (' > $output + for obj in $save_libobjs + do + func_to_tool_file "$obj" + $ECHO "$func_to_tool_file_result" >> $output + done + echo ')' >> $output + func_append delfiles " $output" + func_to_tool_file "$output" + output=$func_to_tool_file_result + elif test -n "$save_libobjs" && test : != "$skipped_export" && test -n "$file_list_spec"; then + output=$output_objdir/$output_la.lnk + func_verbose "creating linker input file list: $output" + : > $output + set x $save_libobjs + shift + firstobj= + if test yes = "$compiler_needs_object"; then + firstobj="$1 " + shift + fi + for obj + do + func_to_tool_file "$obj" + $ECHO "$func_to_tool_file_result" >> $output + done + func_append delfiles " $output" + func_to_tool_file "$output" + output=$firstobj\"$file_list_spec$func_to_tool_file_result\" + else + if test -n "$save_libobjs"; then + func_verbose "creating reloadable object files..." + output=$output_objdir/$output_la-$k.$objext + eval test_cmds=\"$reload_cmds\" + func_len " $test_cmds" + len0=$func_len_result + len=$len0 + + # Loop over the list of objects to be linked. + for obj in $save_libobjs + do + func_len " $obj" + func_arith $len + $func_len_result + len=$func_arith_result + if test -z "$objlist" || + test "$len" -lt "$max_cmd_len"; then + func_append objlist " $obj" + else + # The command $test_cmds is almost too long, add a + # command to the queue. + if test 1 -eq "$k"; then + # The first file doesn't have a previous command to add. + reload_objs=$objlist + eval concat_cmds=\"$reload_cmds\" + else + # All subsequent reloadable object files will link in + # the last one created. + reload_objs="$objlist $last_robj" + eval concat_cmds=\"\$concat_cmds~$reload_cmds~\$RM $last_robj\" + fi + last_robj=$output_objdir/$output_la-$k.$objext + func_arith $k + 1 + k=$func_arith_result + output=$output_objdir/$output_la-$k.$objext + objlist=" $obj" + func_len " $last_robj" + func_arith $len0 + $func_len_result + len=$func_arith_result + fi + done + # Handle the remaining objects by creating one last + # reloadable object file. All subsequent reloadable object + # files will link in the last one created. + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + reload_objs="$objlist $last_robj" + eval concat_cmds=\"\$concat_cmds$reload_cmds\" + if test -n "$last_robj"; then + eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\" + fi + func_append delfiles " $output" + + else + output= + fi + + ${skipped_export-false} && { + func_verbose "generating symbol list for '$libname.la'" + export_symbols=$output_objdir/$libname.exp + $opt_dry_run || $RM $export_symbols + libobjs=$output + # Append the command to create the export file. + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\" + if test -n "$last_robj"; then + eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\" + fi + } + + test -n "$save_libobjs" && + func_verbose "creating a temporary reloadable object file: $output" + + # Loop through the commands generated above and execute them. + save_ifs=$IFS; IFS='~' + for cmd in $concat_cmds; do + IFS=$save_ifs + $opt_quiet || { + func_quote_for_expand "$cmd" + eval "func_echo $func_quote_for_expand_result" + } + $opt_dry_run || eval "$cmd" || { + lt_exit=$? + + # Restore the uninstalled library and exit + if test relink = "$opt_mode"; then + ( cd "$output_objdir" && \ + $RM "${realname}T" && \ + $MV "${realname}U" "$realname" ) + fi + + exit $lt_exit + } + done + IFS=$save_ifs + + if test -n "$export_symbols_regex" && ${skipped_export-false}; then + func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' + func_show_eval '$MV "${export_symbols}T" "$export_symbols"' + fi + fi + + ${skipped_export-false} && { + if test -n "$export_symbols" && test -n "$include_expsyms"; then + tmp_export_symbols=$export_symbols + test -n "$orig_export_symbols" && tmp_export_symbols=$orig_export_symbols + $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' + fi + + if test -n "$orig_export_symbols"; then + # The given exports_symbols file has to be filtered, so filter it. + func_verbose "filter symbol list for '$libname.la' to tag DATA exports" + # FIXME: $output_objdir/$libname.filter potentially contains lots of + # 's' commands, which not all seds can handle. GNU sed should be fine + # though. Also, the filter scales superlinearly with the number of + # global variables. join(1) would be nice here, but unfortunately + # isn't a blessed tool. + $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter + func_append delfiles " $export_symbols $output_objdir/$libname.filter" + export_symbols=$output_objdir/$libname.def + $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols + fi + } + + libobjs=$output + # Restore the value of output. + output=$save_output + + if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then + eval libobjs=\"\$libobjs $whole_archive_flag_spec\" + test "X$libobjs" = "X " && libobjs= + fi + # Expand the library linking commands again to reset the + # value of $libobjs for piecewise linking. + + # Do each of the archive commands. + if test yes = "$module" && test -n "$module_cmds"; then + if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then + cmds=$module_expsym_cmds + else + cmds=$module_cmds + fi + else + if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then + cmds=$archive_expsym_cmds + else + cmds=$archive_cmds + fi + fi + fi + + if test -n "$delfiles"; then + # Append the command to remove temporary files to $cmds. + eval cmds=\"\$cmds~\$RM $delfiles\" + fi + + # Add any objects from preloaded convenience libraries + if test -n "$dlprefiles"; then + gentop=$output_objdir/${outputname}x + func_append generated " $gentop" + + func_extract_archives $gentop $dlprefiles + func_append libobjs " $func_extract_archives_result" + test "X$libobjs" = "X " && libobjs= + fi + + save_ifs=$IFS; IFS='~' + for cmd in $cmds; do + IFS=$sp$nl + eval cmd=\"$cmd\" + IFS=$save_ifs + $opt_quiet || { + func_quote_for_expand "$cmd" + eval "func_echo $func_quote_for_expand_result" + } + $opt_dry_run || eval "$cmd" || { + lt_exit=$? + + # Restore the uninstalled library and exit + if test relink = "$opt_mode"; then + ( cd "$output_objdir" && \ + $RM "${realname}T" && \ + $MV "${realname}U" "$realname" ) + fi + + exit $lt_exit + } + done + IFS=$save_ifs + + # Restore the uninstalled library and exit + if test relink = "$opt_mode"; then + $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $? + + if test -n "$convenience"; then + if test -z "$whole_archive_flag_spec"; then + func_show_eval '${RM}r "$gentop"' + fi + fi + + exit $EXIT_SUCCESS + fi + + # Create links to the real library. + for linkname in $linknames; do + if test "$realname" != "$linkname"; then + func_show_eval '(cd "$output_objdir" && $RM "$linkname" && $LN_S "$realname" "$linkname")' 'exit $?' + fi + done + + # If -module or -export-dynamic was specified, set the dlname. + if test yes = "$module" || test yes = "$export_dynamic"; then + # On all known operating systems, these are identical. + dlname=$soname + fi + fi + ;; + + obj) + if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then + func_warning "'-dlopen' is ignored for objects" + fi + + case " $deplibs" in + *\ -l* | *\ -L*) + func_warning "'-l' and '-L' are ignored for objects" ;; + esac + + test -n "$rpath" && \ + func_warning "'-rpath' is ignored for objects" + + test -n "$xrpath" && \ + func_warning "'-R' is ignored for objects" + + test -n "$vinfo" && \ + func_warning "'-version-info' is ignored for objects" + + test -n "$release" && \ + func_warning "'-release' is ignored for objects" + + case $output in + *.lo) + test -n "$objs$old_deplibs" && \ + func_fatal_error "cannot build library object '$output' from non-libtool objects" + + libobj=$output + func_lo2o "$libobj" + obj=$func_lo2o_result + ;; + *) + libobj= + obj=$output + ;; + esac + + # Delete the old objects. + $opt_dry_run || $RM $obj $libobj + + # Objects from convenience libraries. This assumes + # single-version convenience libraries. Whenever we create + # different ones for PIC/non-PIC, this we'll have to duplicate + # the extraction. + reload_conv_objs= + gentop= + # if reload_cmds runs $LD directly, get rid of -Wl from + # whole_archive_flag_spec and hope we can get by with turning comma + # into space. + case $reload_cmds in + *\$LD[\ \$]*) wl= ;; + esac + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec"; then + eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\" + test -n "$wl" || tmp_whole_archive_flags=`$ECHO "$tmp_whole_archive_flags" | $SED 's|,| |g'` + reload_conv_objs=$reload_objs\ $tmp_whole_archive_flags + else + gentop=$output_objdir/${obj}x + func_append generated " $gentop" + + func_extract_archives $gentop $convenience + reload_conv_objs="$reload_objs $func_extract_archives_result" + fi + fi + + # If we're not building shared, we need to use non_pic_objs + test yes = "$build_libtool_libs" || libobjs=$non_pic_objects + + # Create the old-style object. + reload_objs=$objs$old_deplibs' '`$ECHO "$libobjs" | $SP2NL | $SED "/\.$libext$/d; /\.lib$/d; $lo2o" | $NL2SP`' '$reload_conv_objs + + output=$obj + func_execute_cmds "$reload_cmds" 'exit $?' + + # Exit if we aren't doing a library object file. + if test -z "$libobj"; then + if test -n "$gentop"; then + func_show_eval '${RM}r "$gentop"' + fi + + exit $EXIT_SUCCESS + fi + + test yes = "$build_libtool_libs" || { + if test -n "$gentop"; then + func_show_eval '${RM}r "$gentop"' + fi + + # Create an invalid libtool object if no PIC, so that we don't + # accidentally link it into a program. + # $show "echo timestamp > $libobj" + # $opt_dry_run || eval "echo timestamp > $libobj" || exit $? + exit $EXIT_SUCCESS + } + + if test -n "$pic_flag" || test default != "$pic_mode"; then + # Only do commands if we really have different PIC objects. + reload_objs="$libobjs $reload_conv_objs" + output=$libobj + func_execute_cmds "$reload_cmds" 'exit $?' + fi + + if test -n "$gentop"; then + func_show_eval '${RM}r "$gentop"' + fi + + exit $EXIT_SUCCESS + ;; + + prog) + case $host in + *cygwin*) func_stripname '' '.exe' "$output" + output=$func_stripname_result.exe;; + esac + test -n "$vinfo" && \ + func_warning "'-version-info' is ignored for programs" + + test -n "$release" && \ + func_warning "'-release' is ignored for programs" + + $preload \ + && test unknown,unknown,unknown = "$dlopen_support,$dlopen_self,$dlopen_self_static" \ + && func_warning "'LT_INIT([dlopen])' not used. Assuming no dlopen support." + + case $host in + *-*-rhapsody* | *-*-darwin1.[012]) + # On Rhapsody replace the C library is the System framework + compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's/ -lc / System.ltframework /'` + finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's/ -lc / System.ltframework /'` + ;; + esac + + case $host in + *-*-darwin*) + # Don't allow lazy linking, it breaks C++ global constructors + # But is supposedly fixed on 10.4 or later (yay!). + if test CXX = "$tagname"; then + case ${MACOSX_DEPLOYMENT_TARGET-10.0} in + 10.[0123]) + func_append compile_command " $wl-bind_at_load" + func_append finalize_command " $wl-bind_at_load" + ;; + esac + fi + # Time to change all our "foo.ltframework" stuff back to "-framework foo" + compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + ;; + esac + + + # move library search paths that coincide with paths to not yet + # installed libraries to the beginning of the library search list + new_libs= + for path in $notinst_path; do + case " $new_libs " in + *" -L$path/$objdir "*) ;; + *) + case " $compile_deplibs " in + *" -L$path/$objdir "*) + func_append new_libs " -L$path/$objdir" ;; + esac + ;; + esac + done + for deplib in $compile_deplibs; do + case $deplib in + -L*) + case " $new_libs " in + *" $deplib "*) ;; + *) func_append new_libs " $deplib" ;; + esac + ;; + *) func_append new_libs " $deplib" ;; + esac + done + compile_deplibs=$new_libs + + + func_append compile_command " $compile_deplibs" + func_append finalize_command " $finalize_deplibs" + + if test -n "$rpath$xrpath"; then + # If the user specified any rpath flags, then add them. + for libdir in $rpath $xrpath; do + # This is the magic to use -rpath. + case "$finalize_rpath " in + *" $libdir "*) ;; + *) func_append finalize_rpath " $libdir" ;; + esac + done + fi + + # Now hardcode the library paths + rpath= + hardcode_libdirs= + for libdir in $compile_rpath $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs=$libdir + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + func_append rpath " $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) func_append perm_rpath " $libdir" ;; + esac + fi + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + testbindir=`$ECHO "$libdir" | $SED -e 's*/lib$*/bin*'` + case :$dllsearchpath: in + *":$libdir:"*) ;; + ::) dllsearchpath=$libdir;; + *) func_append dllsearchpath ":$libdir";; + esac + case :$dllsearchpath: in + *":$testbindir:"*) ;; + ::) dllsearchpath=$testbindir;; + *) func_append dllsearchpath ":$testbindir";; + esac + ;; + esac + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir=$hardcode_libdirs + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + compile_rpath=$rpath + + rpath= + hardcode_libdirs= + for libdir in $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs=$libdir + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + func_append rpath " $flag" + fi + elif test -n "$runpath_var"; then + case "$finalize_perm_rpath " in + *" $libdir "*) ;; + *) func_append finalize_perm_rpath " $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir=$hardcode_libdirs + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + finalize_rpath=$rpath + + if test -n "$libobjs" && test yes = "$build_old_libs"; then + # Transform all the library objects into standard objects. + compile_command=`$ECHO "$compile_command" | $SP2NL | $SED "$lo2o" | $NL2SP` + finalize_command=`$ECHO "$finalize_command" | $SP2NL | $SED "$lo2o" | $NL2SP` + fi + + func_generate_dlsyms "$outputname" "@PROGRAM@" false + + # template prelinking step + if test -n "$prelink_cmds"; then + func_execute_cmds "$prelink_cmds" 'exit $?' + fi + + wrappers_required=: + case $host in + *cegcc* | *mingw32ce*) + # Disable wrappers for cegcc and mingw32ce hosts, we are cross compiling anyway. + wrappers_required=false + ;; + *cygwin* | *mingw* ) + test yes = "$build_libtool_libs" || wrappers_required=false + ;; + *) + if test no = "$need_relink" || test yes != "$build_libtool_libs"; then + wrappers_required=false + fi + ;; + esac + $wrappers_required || { + # Replace the output file specification. + compile_command=`$ECHO "$compile_command" | $SED 's%@OUTPUT@%'"$output"'%g'` + link_command=$compile_command$compile_rpath + + # We have no uninstalled library dependencies, so finalize right now. + exit_status=0 + func_show_eval "$link_command" 'exit_status=$?' + + if test -n "$postlink_cmds"; then + func_to_tool_file "$output" + postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` + func_execute_cmds "$postlink_cmds" 'exit $?' + fi + + # Delete the generated files. + if test -f "$output_objdir/${outputname}S.$objext"; then + func_show_eval '$RM "$output_objdir/${outputname}S.$objext"' + fi + + exit $exit_status + } + + if test -n "$compile_shlibpath$finalize_shlibpath"; then + compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" + fi + if test -n "$finalize_shlibpath"; then + finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" + fi + + compile_var= + finalize_var= + if test -n "$runpath_var"; then + if test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + func_append rpath "$dir:" + done + compile_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + if test -n "$finalize_perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $finalize_perm_rpath; do + func_append rpath "$dir:" + done + finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + fi + + if test yes = "$no_install"; then + # We don't need to create a wrapper script. + link_command=$compile_var$compile_command$compile_rpath + # Replace the output file specification. + link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output"'%g'` + # Delete the old output file. + $opt_dry_run || $RM $output + # Link the executable and exit + func_show_eval "$link_command" 'exit $?' + + if test -n "$postlink_cmds"; then + func_to_tool_file "$output" + postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` + func_execute_cmds "$postlink_cmds" 'exit $?' + fi + + exit $EXIT_SUCCESS + fi + + case $hardcode_action,$fast_install in + relink,*) + # Fast installation is not supported + link_command=$compile_var$compile_command$compile_rpath + relink_command=$finalize_var$finalize_command$finalize_rpath + + func_warning "this platform does not like uninstalled shared libraries" + func_warning "'$output' will be relinked during installation" + ;; + *,yes) + link_command=$finalize_var$compile_command$finalize_rpath + relink_command=`$ECHO "$compile_var$compile_command$compile_rpath" | $SED 's%@OUTPUT@%\$progdir/\$file%g'` + ;; + *,no) + link_command=$compile_var$compile_command$compile_rpath + relink_command=$finalize_var$finalize_command$finalize_rpath + ;; + *,needless) + link_command=$finalize_var$compile_command$finalize_rpath + relink_command= + ;; + esac + + # Replace the output file specification. + link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` + + # Delete the old output files. + $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname + + func_show_eval "$link_command" 'exit $?' + + if test -n "$postlink_cmds"; then + func_to_tool_file "$output_objdir/$outputname" + postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` + func_execute_cmds "$postlink_cmds" 'exit $?' + fi + + # Now create the wrapper script. + func_verbose "creating $output" + + # Quote the relink command for shipping. + if test -n "$relink_command"; then + # Preserve any variables that may affect compiler behavior + for var in $variables_saved_for_relink; do + if eval test -z \"\${$var+set}\"; then + relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" + elif eval var_value=\$$var; test -z "$var_value"; then + relink_command="$var=; export $var; $relink_command" + else + func_quote_for_eval "$var_value" + relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" + fi + done + relink_command="(cd `pwd`; $relink_command)" + relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` + fi + + # Only actually do things if not in dry run mode. + $opt_dry_run || { + # win32 will think the script is a binary if it has + # a .exe suffix, so we strip it off here. + case $output in + *.exe) func_stripname '' '.exe' "$output" + output=$func_stripname_result ;; + esac + # test for cygwin because mv fails w/o .exe extensions + case $host in + *cygwin*) + exeext=.exe + func_stripname '' '.exe' "$outputname" + outputname=$func_stripname_result ;; + *) exeext= ;; + esac + case $host in + *cygwin* | *mingw* ) + func_dirname_and_basename "$output" "" "." + output_name=$func_basename_result + output_path=$func_dirname_result + cwrappersource=$output_path/$objdir/lt-$output_name.c + cwrapper=$output_path/$output_name.exe + $RM $cwrappersource $cwrapper + trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15 + + func_emit_cwrapperexe_src > $cwrappersource + + # The wrapper executable is built using the $host compiler, + # because it contains $host paths and files. If cross- + # compiling, it, like the target executable, must be + # executed on the $host or under an emulation environment. + $opt_dry_run || { + $LTCC $LTCFLAGS -o $cwrapper $cwrappersource + $STRIP $cwrapper + } + + # Now, create the wrapper script for func_source use: + func_ltwrapper_scriptname $cwrapper + $RM $func_ltwrapper_scriptname_result + trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15 + $opt_dry_run || { + # note: this script will not be executed, so do not chmod. + if test "x$build" = "x$host"; then + $cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result + else + func_emit_wrapper no > $func_ltwrapper_scriptname_result + fi + } + ;; + * ) + $RM $output + trap "$RM $output; exit $EXIT_FAILURE" 1 2 15 + + func_emit_wrapper no > $output + chmod +x $output + ;; + esac + } + exit $EXIT_SUCCESS + ;; + esac + + # See if we need to build an old-fashioned archive. + for oldlib in $oldlibs; do + + case $build_libtool_libs in + convenience) + oldobjs="$libobjs_save $symfileobj" + addlibs=$convenience + build_libtool_libs=no + ;; + module) + oldobjs=$libobjs_save + addlibs=$old_convenience + build_libtool_libs=no + ;; + *) + oldobjs="$old_deplibs $non_pic_objects" + $preload && test -f "$symfileobj" \ + && func_append oldobjs " $symfileobj" + addlibs=$old_convenience + ;; + esac + + if test -n "$addlibs"; then + gentop=$output_objdir/${outputname}x + func_append generated " $gentop" + + func_extract_archives $gentop $addlibs + func_append oldobjs " $func_extract_archives_result" + fi + + # Do each command in the archive commands. + if test -n "$old_archive_from_new_cmds" && test yes = "$build_libtool_libs"; then + cmds=$old_archive_from_new_cmds + else + + # Add any objects from preloaded convenience libraries + if test -n "$dlprefiles"; then + gentop=$output_objdir/${outputname}x + func_append generated " $gentop" + + func_extract_archives $gentop $dlprefiles + func_append oldobjs " $func_extract_archives_result" + fi + + # POSIX demands no paths to be encoded in archives. We have + # to avoid creating archives with duplicate basenames if we + # might have to extract them afterwards, e.g., when creating a + # static archive out of a convenience library, or when linking + # the entirety of a libtool archive into another (currently + # not supported by libtool). + if (for obj in $oldobjs + do + func_basename "$obj" + $ECHO "$func_basename_result" + done | sort | sort -uc >/dev/null 2>&1); then + : + else + echo "copying selected object files to avoid basename conflicts..." + gentop=$output_objdir/${outputname}x + func_append generated " $gentop" + func_mkdir_p "$gentop" + save_oldobjs=$oldobjs + oldobjs= + counter=1 + for obj in $save_oldobjs + do + func_basename "$obj" + objbase=$func_basename_result + case " $oldobjs " in + " ") oldobjs=$obj ;; + *[\ /]"$objbase "*) + while :; do + # Make sure we don't pick an alternate name that also + # overlaps. + newobj=lt$counter-$objbase + func_arith $counter + 1 + counter=$func_arith_result + case " $oldobjs " in + *[\ /]"$newobj "*) ;; + *) if test ! -f "$gentop/$newobj"; then break; fi ;; + esac + done + func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj" + func_append oldobjs " $gentop/$newobj" + ;; + *) func_append oldobjs " $obj" ;; + esac + done + fi + func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 + tool_oldlib=$func_to_tool_file_result + eval cmds=\"$old_archive_cmds\" + + func_len " $cmds" + len=$func_len_result + if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then + cmds=$old_archive_cmds + elif test -n "$archiver_list_spec"; then + func_verbose "using command file archive linking..." + for obj in $oldobjs + do + func_to_tool_file "$obj" + $ECHO "$func_to_tool_file_result" + done > $output_objdir/$libname.libcmd + func_to_tool_file "$output_objdir/$libname.libcmd" + oldobjs=" $archiver_list_spec$func_to_tool_file_result" + cmds=$old_archive_cmds + else + # the command line is too long to link in one step, link in parts + func_verbose "using piecewise archive linking..." + save_RANLIB=$RANLIB + RANLIB=: + objlist= + concat_cmds= + save_oldobjs=$oldobjs + oldobjs= + # Is there a better way of finding the last object in the list? + for obj in $save_oldobjs + do + last_oldobj=$obj + done + eval test_cmds=\"$old_archive_cmds\" + func_len " $test_cmds" + len0=$func_len_result + len=$len0 + for obj in $save_oldobjs + do + func_len " $obj" + func_arith $len + $func_len_result + len=$func_arith_result + func_append objlist " $obj" + if test "$len" -lt "$max_cmd_len"; then + : + else + # the above command should be used before it gets too long + oldobjs=$objlist + if test "$obj" = "$last_oldobj"; then + RANLIB=$save_RANLIB + fi + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + eval concat_cmds=\"\$concat_cmds$old_archive_cmds\" + objlist= + len=$len0 + fi + done + RANLIB=$save_RANLIB + oldobjs=$objlist + if test -z "$oldobjs"; then + eval cmds=\"\$concat_cmds\" + else + eval cmds=\"\$concat_cmds~\$old_archive_cmds\" + fi + fi + fi + func_execute_cmds "$cmds" 'exit $?' + done + + test -n "$generated" && \ + func_show_eval "${RM}r$generated" + + # Now create the libtool archive. + case $output in + *.la) + old_library= + test yes = "$build_old_libs" && old_library=$libname.$libext + func_verbose "creating $output" + + # Preserve any variables that may affect compiler behavior + for var in $variables_saved_for_relink; do + if eval test -z \"\${$var+set}\"; then + relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" + elif eval var_value=\$$var; test -z "$var_value"; then + relink_command="$var=; export $var; $relink_command" + else + func_quote_for_eval "$var_value" + relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" + fi + done + # Quote the link command for shipping. + relink_command="(cd `pwd`; $SHELL \"$progpath\" $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)" + relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` + if test yes = "$hardcode_automatic"; then + relink_command= + fi + + # Only create the output if not a dry run. + $opt_dry_run || { + for installed in no yes; do + if test yes = "$installed"; then + if test -z "$install_libdir"; then + break + fi + output=$output_objdir/${outputname}i + # Replace all uninstalled libtool libraries with the installed ones + newdependency_libs= + for deplib in $dependency_libs; do + case $deplib in + *.la) + func_basename "$deplib" + name=$func_basename_result + func_resolve_sysroot "$deplib" + eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $func_resolve_sysroot_result` + test -z "$libdir" && \ + func_fatal_error "'$deplib' is not a valid libtool archive" + func_append newdependency_libs " ${lt_sysroot:+=}$libdir/$name" + ;; + -L*) + func_stripname -L '' "$deplib" + func_replace_sysroot "$func_stripname_result" + func_append newdependency_libs " -L$func_replace_sysroot_result" + ;; + -R*) + func_stripname -R '' "$deplib" + func_replace_sysroot "$func_stripname_result" + func_append newdependency_libs " -R$func_replace_sysroot_result" + ;; + *) func_append newdependency_libs " $deplib" ;; + esac + done + dependency_libs=$newdependency_libs + newdlfiles= + + for lib in $dlfiles; do + case $lib in + *.la) + func_basename "$lib" + name=$func_basename_result + eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + test -z "$libdir" && \ + func_fatal_error "'$lib' is not a valid libtool archive" + func_append newdlfiles " ${lt_sysroot:+=}$libdir/$name" + ;; + *) func_append newdlfiles " $lib" ;; + esac + done + dlfiles=$newdlfiles + newdlprefiles= + for lib in $dlprefiles; do + case $lib in + *.la) + # Only pass preopened files to the pseudo-archive (for + # eventual linking with the app. that links it) if we + # didn't already link the preopened objects directly into + # the library: + func_basename "$lib" + name=$func_basename_result + eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + test -z "$libdir" && \ + func_fatal_error "'$lib' is not a valid libtool archive" + func_append newdlprefiles " ${lt_sysroot:+=}$libdir/$name" + ;; + esac + done + dlprefiles=$newdlprefiles + else + newdlfiles= + for lib in $dlfiles; do + case $lib in + [\\/]* | [A-Za-z]:[\\/]*) abs=$lib ;; + *) abs=`pwd`"/$lib" ;; + esac + func_append newdlfiles " $abs" + done + dlfiles=$newdlfiles + newdlprefiles= + for lib in $dlprefiles; do + case $lib in + [\\/]* | [A-Za-z]:[\\/]*) abs=$lib ;; + *) abs=`pwd`"/$lib" ;; + esac + func_append newdlprefiles " $abs" + done + dlprefiles=$newdlprefiles + fi + $RM $output + # place dlname in correct position for cygwin + # In fact, it would be nice if we could use this code for all target + # systems that can't hard-code library paths into their executables + # and that have no shared library path variable independent of PATH, + # but it turns out we can't easily determine that from inspecting + # libtool variables, so we have to hard-code the OSs to which it + # applies here; at the moment, that means platforms that use the PE + # object format with DLL files. See the long comment at the top of + # tests/bindir.at for full details. + tdlname=$dlname + case $host,$output,$installed,$module,$dlname in + *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll) + # If a -bindir argument was supplied, place the dll there. + if test -n "$bindir"; then + func_relative_path "$install_libdir" "$bindir" + tdlname=$func_relative_path_result/$dlname + else + # Otherwise fall back on heuristic. + tdlname=../bin/$dlname + fi + ;; + esac + $ECHO > $output "\ +# $outputname - a libtool library file +# Generated by $PROGRAM (GNU $PACKAGE) $VERSION +# +# Please DO NOT delete this file! +# It is necessary for linking the library. + +# The name that we can dlopen(3). +dlname='$tdlname' + +# Names of this library. +library_names='$library_names' + +# The name of the static archive. +old_library='$old_library' + +# Linker flags that cannot go in dependency_libs. +inherited_linker_flags='$new_inherited_linker_flags' + +# Libraries that this one depends upon. +dependency_libs='$dependency_libs' + +# Names of additional weak libraries provided by this library +weak_library_names='$weak_libs' + +# Version information for $libname. +current=$current +age=$age +revision=$revision + +# Is this an already installed library? +installed=$installed + +# Should we warn about portability when linking against -modules? +shouldnotlink=$module + +# Files to dlopen/dlpreopen +dlopen='$dlfiles' +dlpreopen='$dlprefiles' + +# Directory that this library needs to be installed in: +libdir='$install_libdir'" + if test no,yes = "$installed,$need_relink"; then + $ECHO >> $output "\ +relink_command=\"$relink_command\"" + fi + done + } + + # Do a symbolic link so that the libtool archive can be found in + # LD_LIBRARY_PATH before the program is installed. + func_show_eval '( cd "$output_objdir" && $RM "$outputname" && $LN_S "../$outputname" "$outputname" )' 'exit $?' + ;; + esac + exit $EXIT_SUCCESS +} + +if test link = "$opt_mode" || test relink = "$opt_mode"; then + func_mode_link ${1+"$@"} +fi + + +# func_mode_uninstall arg... +func_mode_uninstall () +{ + $debug_cmd + + RM=$nonopt + files= + rmforce=false + exit_status=0 + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic=$magic + + for arg + do + case $arg in + -f) func_append RM " $arg"; rmforce=: ;; + -*) func_append RM " $arg" ;; + *) func_append files " $arg" ;; + esac + done + + test -z "$RM" && \ + func_fatal_help "you must specify an RM program" + + rmdirs= + + for file in $files; do + func_dirname "$file" "" "." + dir=$func_dirname_result + if test . = "$dir"; then + odir=$objdir + else + odir=$dir/$objdir + fi + func_basename "$file" + name=$func_basename_result + test uninstall = "$opt_mode" && odir=$dir + + # Remember odir for removal later, being careful to avoid duplicates + if test clean = "$opt_mode"; then + case " $rmdirs " in + *" $odir "*) ;; + *) func_append rmdirs " $odir" ;; + esac + fi + + # Don't error if the file doesn't exist and rm -f was used. + if { test -L "$file"; } >/dev/null 2>&1 || + { test -h "$file"; } >/dev/null 2>&1 || + test -f "$file"; then + : + elif test -d "$file"; then + exit_status=1 + continue + elif $rmforce; then + continue + fi + + rmfiles=$file + + case $name in + *.la) + # Possibly a libtool archive, so verify it. + if func_lalib_p "$file"; then + func_source $dir/$name + + # Delete the libtool libraries and symlinks. + for n in $library_names; do + func_append rmfiles " $odir/$n" + done + test -n "$old_library" && func_append rmfiles " $odir/$old_library" + + case $opt_mode in + clean) + case " $library_names " in + *" $dlname "*) ;; + *) test -n "$dlname" && func_append rmfiles " $odir/$dlname" ;; + esac + test -n "$libdir" && func_append rmfiles " $odir/$name $odir/${name}i" + ;; + uninstall) + if test -n "$library_names"; then + # Do each command in the postuninstall commands. + func_execute_cmds "$postuninstall_cmds" '$rmforce || exit_status=1' + fi + + if test -n "$old_library"; then + # Do each command in the old_postuninstall commands. + func_execute_cmds "$old_postuninstall_cmds" '$rmforce || exit_status=1' + fi + # FIXME: should reinstall the best remaining shared library. + ;; + esac + fi + ;; + + *.lo) + # Possibly a libtool object, so verify it. + if func_lalib_p "$file"; then + + # Read the .lo file + func_source $dir/$name + + # Add PIC object to the list of files to remove. + if test -n "$pic_object" && test none != "$pic_object"; then + func_append rmfiles " $dir/$pic_object" + fi + + # Add non-PIC object to the list of files to remove. + if test -n "$non_pic_object" && test none != "$non_pic_object"; then + func_append rmfiles " $dir/$non_pic_object" + fi + fi + ;; + + *) + if test clean = "$opt_mode"; then + noexename=$name + case $file in + *.exe) + func_stripname '' '.exe' "$file" + file=$func_stripname_result + func_stripname '' '.exe' "$name" + noexename=$func_stripname_result + # $file with .exe has already been added to rmfiles, + # add $file without .exe + func_append rmfiles " $file" + ;; + esac + # Do a test to see if this is a libtool program. + if func_ltwrapper_p "$file"; then + if func_ltwrapper_executable_p "$file"; then + func_ltwrapper_scriptname "$file" + relink_command= + func_source $func_ltwrapper_scriptname_result + func_append rmfiles " $func_ltwrapper_scriptname_result" + else + relink_command= + func_source $dir/$noexename + fi + + # note $name still contains .exe if it was in $file originally + # as does the version of $file that was added into $rmfiles + func_append rmfiles " $odir/$name $odir/${name}S.$objext" + if test yes = "$fast_install" && test -n "$relink_command"; then + func_append rmfiles " $odir/lt-$name" + fi + if test "X$noexename" != "X$name"; then + func_append rmfiles " $odir/lt-$noexename.c" + fi + fi + fi + ;; + esac + func_show_eval "$RM $rmfiles" 'exit_status=1' + done + + # Try to remove the $objdir's in the directories where we deleted files + for dir in $rmdirs; do + if test -d "$dir"; then + func_show_eval "rmdir $dir >/dev/null 2>&1" + fi + done + + exit $exit_status +} + +if test uninstall = "$opt_mode" || test clean = "$opt_mode"; then + func_mode_uninstall ${1+"$@"} +fi + +test -z "$opt_mode" && { + help=$generic_help + func_fatal_help "you must specify a MODE" +} + +test -z "$exec_cmd" && \ + func_fatal_help "invalid operation mode '$opt_mode'" + +if test -n "$exec_cmd"; then + eval exec "$exec_cmd" + exit $EXIT_FAILURE +fi + +exit $exit_status + + +# The TAGs below are defined such that we never get into a situation +# where we disable both kinds of libraries. Given conflicting +# choices, we go for a static library, that is the most portable, +# since we can't tell whether shared libraries were disabled because +# the user asked for that or because the platform doesn't support +# them. This is particularly important on AIX, because we don't +# support having both static and shared libraries enabled at the same +# time on that platform, so we default to a shared-only configuration. +# If a disable-shared tag is given, we'll fallback to a static-only +# configuration. But we'll never go from static-only to shared-only. + +# ### BEGIN LIBTOOL TAG CONFIG: disable-shared +build_libtool_libs=no +build_old_libs=yes +# ### END LIBTOOL TAG CONFIG: disable-shared + +# ### BEGIN LIBTOOL TAG CONFIG: disable-static +build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac` +# ### END LIBTOOL TAG CONFIG: disable-static + +# Local Variables: +# mode:shell-script +# sh-indentation:2 +# End: diff --git a/external/mit/isl/dist/interface/missing b/external/mit/isl/dist/interface/missing new file mode 100755 index 000000000000..1fe1611f1851 --- /dev/null +++ b/external/mit/isl/dist/interface/missing @@ -0,0 +1,215 @@ +#! /bin/sh +# Common wrapper for a few potentially missing GNU programs. + +scriptversion=2018-03-07.03; # UTC + +# Copyright (C) 1996-2021 Free Software Foundation, Inc. +# Originally written by Fran,cois Pinard , 1996. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +if test $# -eq 0; then + echo 1>&2 "Try '$0 --help' for more information" + exit 1 +fi + +case $1 in + + --is-lightweight) + # Used by our autoconf macros to check whether the available missing + # script is modern enough. + exit 0 + ;; + + --run) + # Back-compat with the calling convention used by older automake. + shift + ;; + + -h|--h|--he|--hel|--help) + echo "\ +$0 [OPTION]... PROGRAM [ARGUMENT]... + +Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due +to PROGRAM being missing or too old. + +Options: + -h, --help display this help and exit + -v, --version output version information and exit + +Supported PROGRAM values: + aclocal autoconf autoheader autom4te automake makeinfo + bison yacc flex lex help2man + +Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and +'g' are ignored when checking the name. + +Send bug reports to ." + exit $? + ;; + + -v|--v|--ve|--ver|--vers|--versi|--versio|--version) + echo "missing $scriptversion (GNU Automake)" + exit $? + ;; + + -*) + echo 1>&2 "$0: unknown '$1' option" + echo 1>&2 "Try '$0 --help' for more information" + exit 1 + ;; + +esac + +# Run the given program, remember its exit status. +"$@"; st=$? + +# If it succeeded, we are done. +test $st -eq 0 && exit 0 + +# Also exit now if we it failed (or wasn't found), and '--version' was +# passed; such an option is passed most likely to detect whether the +# program is present and works. +case $2 in --version|--help) exit $st;; esac + +# Exit code 63 means version mismatch. This often happens when the user +# tries to use an ancient version of a tool on a file that requires a +# minimum version. +if test $st -eq 63; then + msg="probably too old" +elif test $st -eq 127; then + # Program was missing. + msg="missing on your system" +else + # Program was found and executed, but failed. Give up. + exit $st +fi + +perl_URL=https://www.perl.org/ +flex_URL=https://github.com/westes/flex +gnu_software_URL=https://www.gnu.org/software + +program_details () +{ + case $1 in + aclocal|automake) + echo "The '$1' program is part of the GNU Automake package:" + echo "<$gnu_software_URL/automake>" + echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:" + echo "<$gnu_software_URL/autoconf>" + echo "<$gnu_software_URL/m4/>" + echo "<$perl_URL>" + ;; + autoconf|autom4te|autoheader) + echo "The '$1' program is part of the GNU Autoconf package:" + echo "<$gnu_software_URL/autoconf/>" + echo "It also requires GNU m4 and Perl in order to run:" + echo "<$gnu_software_URL/m4/>" + echo "<$perl_URL>" + ;; + esac +} + +give_advice () +{ + # Normalize program name to check for. + normalized_program=`echo "$1" | sed ' + s/^gnu-//; t + s/^gnu//; t + s/^g//; t'` + + printf '%s\n' "'$1' is $msg." + + configure_deps="'configure.ac' or m4 files included by 'configure.ac'" + case $normalized_program in + autoconf*) + echo "You should only need it if you modified 'configure.ac'," + echo "or m4 files included by it." + program_details 'autoconf' + ;; + autoheader*) + echo "You should only need it if you modified 'acconfig.h' or" + echo "$configure_deps." + program_details 'autoheader' + ;; + automake*) + echo "You should only need it if you modified 'Makefile.am' or" + echo "$configure_deps." + program_details 'automake' + ;; + aclocal*) + echo "You should only need it if you modified 'acinclude.m4' or" + echo "$configure_deps." + program_details 'aclocal' + ;; + autom4te*) + echo "You might have modified some maintainer files that require" + echo "the 'autom4te' program to be rebuilt." + program_details 'autom4te' + ;; + bison*|yacc*) + echo "You should only need it if you modified a '.y' file." + echo "You may want to install the GNU Bison package:" + echo "<$gnu_software_URL/bison/>" + ;; + lex*|flex*) + echo "You should only need it if you modified a '.l' file." + echo "You may want to install the Fast Lexical Analyzer package:" + echo "<$flex_URL>" + ;; + help2man*) + echo "You should only need it if you modified a dependency" \ + "of a man page." + echo "You may want to install the GNU Help2man package:" + echo "<$gnu_software_URL/help2man/>" + ;; + makeinfo*) + echo "You should only need it if you modified a '.texi' file, or" + echo "any other file indirectly affecting the aspect of the manual." + echo "You might want to install the Texinfo package:" + echo "<$gnu_software_URL/texinfo/>" + echo "The spurious makeinfo call might also be the consequence of" + echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might" + echo "want to install GNU make:" + echo "<$gnu_software_URL/make/>" + ;; + *) + echo "You might have modified some files without having the proper" + echo "tools for further handling them. Check the 'README' file, it" + echo "often tells you about the needed prerequisites for installing" + echo "this package. You may also peek at any GNU archive site, in" + echo "case some other package contains this missing '$1' program." + ;; + esac +} + +give_advice "$1" | sed -e '1s/^/WARNING: /' \ + -e '2,$s/^/ /' >&2 + +# Propagate the correct exit status (expected to be 127 for a program +# not found, 63 for a program that failed due to version mismatch). +exit $st + +# Local variables: +# eval: (add-hook 'before-save-hook 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC0" +# time-stamp-end: "; # UTC" +# End: diff --git a/external/mit/isl/dist/interface/plain_cpp.cc b/external/mit/isl/dist/interface/plain_cpp.cc new file mode 100644 index 000000000000..326cf1221878 --- /dev/null +++ b/external/mit/isl/dist/interface/plain_cpp.cc @@ -0,0 +1,2098 @@ +/* + * Copyright 2016, 2017 Tobias Grosser. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY TOBIAS GROSSER ''AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL TOBIAS GROSSER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation + * are those of the authors and should not be interpreted as + * representing official policies, either expressed or implied, of + * Tobias Grosser. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "plain_cpp.h" +#include "isl_config.h" + +/* Print string formatted according to "fmt" to ostream "os". + * + * This osprintf method allows us to use printf style formatting constructs when + * writing to an ostream. + */ +static void osprintf(ostream &os, const char *format, va_list arguments) +{ + va_list copy; + char *string_pointer; + size_t size; + + va_copy(copy, arguments); + size = vsnprintf(NULL, 0, format, copy); + string_pointer = new char[size + 1]; + va_end(copy); + vsnprintf(string_pointer, size + 1, format, arguments); + os << string_pointer; + delete[] string_pointer; +} + +/* Print string formatted according to "fmt" to ostream "os". + * + * This osprintf method allows us to use printf style formatting constructs when + * writing to an ostream. + */ +static void osprintf(ostream &os, const char *format, ...) +{ + va_list arguments; + + va_start(arguments, format); + osprintf(os, format, arguments); + va_end(arguments); +} + +/* Print string formatted according to "fmt" to ostream "os" + * with the given indentation. + * + * This osprintf method allows us to use printf style formatting constructs when + * writing to an ostream. + */ +static void osprintf(ostream &os, int indent, const char *format, ...) +{ + va_list arguments; + + osprintf(os, "%*s", indent, " "); + va_start(arguments, format); + osprintf(os, format, arguments); + va_end(arguments); +} + +/* Convert "l" to a string. + */ +static std::string to_string(long l) +{ + std::ostringstream strm; + strm << l; + return strm.str(); +} + +/* Construct a generator for plain C++ bindings. + * + * "checked" is set if C++ bindings should be generated + * that rely on the user to check for error conditions. + */ +plain_cpp_generator::plain_cpp_generator(SourceManager &SM, + set &exported_types, + set exported_functions, set functions, + bool checked) : + cpp_generator(SM, exported_types, exported_functions, + functions), + checked(checked) +{ +} + +/* Generate a cpp interface based on the extracted types and functions. + * + * Print first a set of forward declarations for all isl wrapper + * classes, then the declarations of the classes, and at the end all + * implementations. + * + * If checked C++ bindings are being generated, + * then wrap them in a namespace to avoid conflicts + * with the default C++ bindings (with automatic checks using exceptions). + */ +void plain_cpp_generator::generate() +{ + ostream &os = cout; + + osprintf(os, "\n"); + osprintf(os, "namespace isl {\n\n"); + if (checked) + osprintf(os, "namespace checked {\n\n"); + + print_forward_declarations(os); + osprintf(os, "\n"); + print_declarations(os); + osprintf(os, "\n"); + print_implementations(os); + + if (checked) + osprintf(os, "} // namespace checked\n"); + osprintf(os, "} // namespace isl\n"); +} + +/* Print forward declarations for all classes to "os". +*/ +void plain_cpp_generator::print_forward_declarations(ostream &os) +{ + map::iterator ci; + + osprintf(os, "// forward declarations\n"); + + for (ci = classes.begin(); ci != classes.end(); ++ci) + print_class_forward_decl(os, ci->second); +} + +/* Print all declarations to "os". + */ +void plain_cpp_generator::print_declarations(ostream &os) +{ + map::iterator ci; + bool first = true; + + for (ci = classes.begin(); ci != classes.end(); ++ci) { + if (first) + first = false; + else + osprintf(os, "\n"); + + print_class(os, ci->second); + } +} + +/* Print all implementations to "os". + */ +void plain_cpp_generator::print_implementations(ostream &os) +{ + map::iterator ci; + bool first = true; + + for (ci = classes.begin(); ci != classes.end(); ++ci) { + if (first) + first = false; + else + osprintf(os, "\n"); + + print_class_impl(os, ci->second); + } +} + +/* If the printed class is a subclass that is based on a type function, + * then introduce a "type" field that holds the value of the type + * corresponding to the subclass and make the fields of the class + * accessible to the "isa" and "as" methods of the (immediate) superclass. + * In particular, "isa" needs access to the type field itself, + * while "as" needs access to the private constructor. + * In case of the "isa" method, all instances are made friends + * to avoid access right confusion. + */ +void plain_cpp_generator::decl_printer::print_subclass_type() +{ + std::string super; + const char *cppname = cppstring.c_str(); + const char *supername; + + if (!clazz.is_type_subclass()) + return; + + super = type2cpp(clazz.superclass_name); + supername = super.c_str(); + osprintf(os, " template \n"); + osprintf(os, " friend %s %s::isa() const;\n", + generator.isl_bool2cpp().c_str(), supername); + osprintf(os, " friend %s %s::as<%s>() const;\n", + cppname, supername, cppname); + osprintf(os, " static const auto type = %s;\n", + clazz.subclass_name.c_str()); +} + +/* Print declarations for class "clazz" to "os". + * + * If "clazz" is a subclass based on a type function, + * then it is made to inherit from the (immediate) superclass and + * a "type" attribute is added for use in the "as" and "isa" + * methods of the superclass. + * + * Conversely, if "clazz" is a superclass with a type function, + * then declare those "as" and "isa" methods. + * + * The pointer to the isl object is only added for classes that + * are not subclasses, since subclasses refer to the same isl object. + */ +void plain_cpp_generator::print_class(ostream &os, const isl_class &clazz) +{ + decl_printer printer(os, clazz, *this); + const char *name = clazz.name.c_str(); + const char *cppname = printer.cppstring.c_str(); + + osprintf(os, "// declarations for isl::%s\n", cppname); + + printer.print_class_factory(); + osprintf(os, "\n"); + osprintf(os, "class %s ", cppname); + if (clazz.is_type_subclass()) + osprintf(os, ": public %s ", + type2cpp(clazz.superclass_name).c_str()); + osprintf(os, "{\n"); + printer.print_subclass_type(); + printer.print_class_factory(" friend "); + osprintf(os, "\n"); + osprintf(os, "protected:\n"); + if (!clazz.is_type_subclass()) { + osprintf(os, " %s *ptr = nullptr;\n", name); + osprintf(os, "\n"); + } + printer.print_protected_constructors(); + osprintf(os, "\n"); + osprintf(os, "public:\n"); + printer.print_public_methods(); + + osprintf(os, "};\n"); +} + +/* Print forward declaration of class "clazz" to "os". + */ +void plain_cpp_generator::print_class_forward_decl(ostream &os, + const isl_class &clazz) +{ + std::string cppstring = type2cpp(clazz); + const char *cppname = cppstring.c_str(); + + osprintf(os, "class %s;\n", cppname); +} + +/* Print global factory functions. + * + * Each class has two global factory functions: + * + * set manage(__isl_take isl_set *ptr); + * set manage_copy(__isl_keep isl_set *ptr); + * + * A user can construct isl C++ objects from a raw pointer and indicate whether + * they intend to take the ownership of the object or not through these global + * factory functions. This ensures isl object creation is very explicit and + * pointers are not converted by accident. Thanks to overloading, manage() and + * manage_copy() can be called on any isl raw pointer and the corresponding + * object is automatically created, without the user having to choose the right + * isl object type. + * + * For a subclass based on a type function, no factory functions + * are introduced because they share the C object type with + * the superclass. + */ +void plain_cpp_generator::decl_printer::print_class_factory( + const std::string &prefix) +{ + const char *name = clazz.name.c_str(); + const char *cppname = cppstring.c_str(); + + if (clazz.is_type_subclass()) + return; + + os << prefix; + osprintf(os, "inline %s manage(__isl_take %s *ptr);\n", cppname, name); + os << prefix; + osprintf(os, "inline %s manage_copy(__isl_keep %s *ptr);\n", + cppname, name); +} + +/* Print declarations of protected constructors. + * + * Each class has currently one protected constructor: + * + * 1) Constructor from a plain isl_* C pointer + * + * Example: + * + * set(__isl_take isl_set *ptr); + * + * The raw pointer constructor is kept protected. Object creation is only + * possible through manage() or manage_copy(). + */ +void plain_cpp_generator::decl_printer::print_protected_constructors() +{ + const char *name = clazz.name.c_str(); + const char *cppname = cppstring.c_str(); + + osprintf(os, " inline explicit %s(__isl_take %s *ptr);\n", cppname, + name); +} + +/* Print declarations of public constructors. + * + * Each class currently has two public constructors: + * + * 1) A default constructor + * 2) A copy constructor + * + * Example: + * + * set(); + * set(const set &set); + */ +void plain_cpp_generator::decl_printer::print_public_constructors() +{ + const char *cppname = cppstring.c_str(); + osprintf(os, " inline /* implicit */ %s();\n", cppname); + + osprintf(os, " inline /* implicit */ %s(const %s &obj);\n", + cppname, cppname); +} + +/* Print declarations for "method". + */ +void plain_cpp_generator::decl_printer::print_method( + const ConversionMethod &method) +{ + print_full_method_header(method); +} + +/* Print declarations for "method". + */ +void plain_cpp_generator::decl_printer::print_method(const Method &method) +{ + print_full_method_header(method); +} + +/* Print a declaration for a constructor for the "id" class + * that takes a user object. + */ +void plain_cpp_generator::decl_printer::print_id_constructor_user() +{ + print_id_constructor_user_header(); +} + +/* Print a declaration for an "id" method + * for retrieving the user object associated to the identifier. + * If "optional" is set, the method returns a std::optional user object. + */ +void plain_cpp_generator::decl_printer::print_id_user(bool optional) +{ + print_id_user_header(optional); +} + +/* Print declarations of copy assignment operator. + * + * Each class has one assignment operator. + * + * isl:set &set::operator=(set obj) + * + */ +void plain_cpp_generator::decl_printer::print_copy_assignment() +{ + const char *cppname = cppstring.c_str(); + + osprintf(os, " inline %s &operator=(%s obj);\n", cppname, cppname); +} + +/* Print declaration of destructor. + * + * No explicit destructor is needed for type based subclasses. + */ +void plain_cpp_generator::decl_printer::print_destructor() +{ + const char *cppname = cppstring.c_str(); + + if (clazz.is_type_subclass()) + return; + + osprintf(os, " inline ~%s();\n", cppname); +} + +/* Print declaration of pointer functions. + * Since type based subclasses share the pointer with their superclass, + * they can also reuse these functions from the superclass. + * + * To obtain a raw pointer three functions are provided: + * + * 1) __isl_give isl_set *copy() + * + * Returns a pointer to a _copy_ of the internal object + * + * 2) __isl_keep isl_set *get() + * + * Returns a pointer to the internal object + * + * 3) __isl_give isl_set *release() + * + * Returns a pointer to the internal object and resets the + * internal pointer to nullptr. + * + * We also provide functionality to explicitly check if a pointer is + * currently managed by this object. + * + * 4) bool is_null() + * + * Check if the current object is a null pointer. + * + * The functions get() and release() model the value_ptr proposed in + * http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3339.pdf. + * The copy() function is an extension to allow the user to explicitly + * copy the underlying object. + * + * Also generate a declaration to delete copy() for r-values, for + * r-values release() should be used to avoid unnecessary copies. + */ +void plain_cpp_generator::decl_printer::print_ptr() +{ + const char *name = clazz.name.c_str(); + + if (clazz.is_type_subclass()) + return; + + osprintf(os, " inline __isl_give %s *copy() const &;\n", name); + osprintf(os, " inline __isl_give %s *copy() && = delete;\n", name); + osprintf(os, " inline __isl_keep %s *get() const;\n", name); + osprintf(os, " inline __isl_give %s *release();\n", name); + osprintf(os, " inline bool is_null() const;\n"); +} + +/* Print a template declaration with given indentation + * for the "isa_type" method that ensures it is only enabled + * when called with a template argument + * that represents a type that is equal to that + * of the return type of the type function of "super". + * In particular, "isa_type" gets called from "isa" + * with as template argument the type of the "type" field + * of the subclass. + * The check ensures that this subclass is in fact a direct subclass + * of "super". + */ +void plain_cpp_generator::decl_printer::print_isa_type_template(int indent, + const isl_class &super) +{ + osprintf(os, indent, + "template getNameAsString().c_str()); + osprintf(os, indent, + " const T>::value>::type>\n"); +} + +/* Print declarations for the "as" and "isa" methods, if the printed class + * is a superclass with a type function. + * + * "isa" checks whether an object is of a given subclass type. + * "isa_type" does the same, but gets passed the value of the type field + * of the subclass as a function argument and the type of this field + * as a template argument. + * "as" tries to cast an object to a given subclass type, returning + * an invalid object if the object is not of the given type. + */ +void plain_cpp_generator::decl_printer::print_downcast() +{ + if (!clazz.fn_type) + return; + + osprintf(os, "private:\n"); + print_isa_type_template(2, clazz); + osprintf(os, " inline %s isa_type(T subtype) const;\n", + generator.isl_bool2cpp().c_str()); + osprintf(os, "public:\n"); + osprintf(os, " template inline %s isa() const;\n", + generator.isl_bool2cpp().c_str()); + osprintf(os, " template inline T as() const;\n"); +} + +/* Print the declaration of the ctx method. + */ +void plain_cpp_generator::decl_printer::print_ctx() +{ + std::string ns = generator.isl_namespace(); + + osprintf(os, " inline %sctx ctx() const;\n", ns.c_str()); +} + +/* Print a separator between groups of method declarations. + */ +void plain_cpp_generator::decl_printer::print_method_separator() +{ + os << "\n"; +} + +/* Add a space to the return type "type" if needed, + * i.e., if it is not the type of a pointer. + */ +static string add_space_to_return_type(const string &type) +{ + if (type[type.size() - 1] == '*') + return type; + return type + " "; +} + +/* Print the prototype of the static inline method that is used + * as the C callback set by "method". + */ +void plain_cpp_generator::plain_printer::print_persistent_callback_prototype( + FunctionDecl *method) +{ + string callback_name, rettype, c_args; + ParmVarDecl *param = persistent_callback_arg(method); + const FunctionProtoType *callback; + QualType ptype; + string classname; + + ptype = param->getType(); + callback = extract_prototype(ptype); + + rettype = callback->getReturnType().getAsString(); + rettype = add_space_to_return_type(rettype); + callback_name = clazz.persistent_callback_name(method); + c_args = generator.generate_callback_args(ptype, false); + + if (!declarations) + classname = type2cpp(clazz) + "::"; + + osprintf(os, "%s%s%s(%s)", + rettype.c_str(), classname.c_str(), + callback_name.c_str(), c_args.c_str()); +} + +/* Print the prototype of the method for setting the callback function + * set by "method". + */ +void +plain_cpp_generator::plain_printer::print_persistent_callback_setter_prototype( + FunctionDecl *method) +{ + string classname, callback_name, cpptype; + ParmVarDecl *param = persistent_callback_arg(method); + + if (!declarations) + classname = type2cpp(clazz) + "::"; + + cpptype = generator.param2cpp(param->getOriginalType()); + callback_name = clazz.persistent_callback_name(method); + osprintf(os, "void %sset_%s_data(const %s &%s)", + classname.c_str(), callback_name.c_str(), cpptype.c_str(), + param->getName().str().c_str()); +} + +/* Given a method "method" for setting a persistent callback, + * print the fields that are needed for marshalling the callback. + * + * In particular, print + * - the declaration of a data structure for storing the C++ callback function + * - a shared pointer to such a data structure + * - the declaration of a static inline method + * for use as the C callback function + * - the declaration of a private method for setting the callback function + */ +void plain_cpp_generator::decl_printer::print_persistent_callback_data( + FunctionDecl *method) +{ + string callback_name; + ParmVarDecl *param = generator.persistent_callback_arg(method); + + callback_name = clazz.persistent_callback_name(method); + print_callback_data_decl(param, callback_name); + osprintf(os, ";\n"); + osprintf(os, " std::shared_ptr<%s_data> %s_data;\n", + callback_name.c_str(), callback_name.c_str()); + osprintf(os, " static inline "); + print_persistent_callback_prototype(method); + osprintf(os, ";\n"); + osprintf(os, " inline "); + print_persistent_callback_setter_prototype(method); + osprintf(os, ";\n"); +} + +/* Print declarations needed for the persistent callbacks of the class. + * + * In particular, if there are any persistent callbacks, then + * print a private method for copying callback data from + * one object to another, + * private data for keeping track of the persistent callbacks and + * public methods for setting the persistent callbacks. + */ +void plain_cpp_generator::decl_printer::print_persistent_callbacks() +{ + const char *cppname = cppstring.c_str(); + + if (!clazz.has_persistent_callbacks()) + return; + + osprintf(os, "private:\n"); + osprintf(os, " inline %s ©_callbacks(const %s &obj);\n", + cppname, cppname); + for (const auto &callback : clazz.persistent_callbacks) + print_persistent_callback_data(callback); + + osprintf(os, "public:\n"); + for (const auto &callback : clazz.persistent_callbacks) + print_method(Method(clazz, callback)); +} + +/* Print a declaration for the "get" method "fd", + * using a name that includes the "get_" prefix. + */ +void plain_cpp_generator::decl_printer::print_get_method(FunctionDecl *fd) +{ + string base = clazz.base_method_name(fd); + + print_method(Method(clazz, fd, base)); +} + +/* Print implementations for class "clazz" to "os". + */ +void plain_cpp_generator::print_class_impl(ostream &os, const isl_class &clazz) +{ + impl_printer printer(os, clazz, *this); + const char *cppname = printer.cppstring.c_str(); + + osprintf(os, "// implementations for isl::%s", cppname); + + printer.print_class_factory(); + printer.print_protected_constructors(); + printer.print_public_methods(); + printer.print_stream_insertion(); +} + +/* Print code for throwing an exception corresponding to the last error + * that occurred on "saved_ctx". + * This assumes that a valid isl::ctx is available in the "saved_ctx" variable, + * e.g., through a prior call to print_save_ctx. + */ +static void print_throw_last_error(ostream &os) +{ + osprintf(os, " exception::throw_last_error(saved_ctx);\n"); +} + +/* Print code with the given indentation + * for throwing an exception_invalid with the given message. + */ +static void print_throw_invalid(ostream &os, int indent, const char *msg) +{ + osprintf(os, indent, + "exception::throw_invalid(\"%s\", __FILE__, __LINE__);\n", msg); +} + +/* Print code for throwing an exception on NULL input. + */ +static void print_throw_NULL_input(ostream &os) +{ + print_throw_invalid(os, 4, "NULL input"); +} + +/* Print code with the given indentation + * for acting on an invalid error with message "msg". + * In particular, throw an exception_invalid. + * In the checked C++ bindings, isl_die is called instead with the code + * in "checked_code". + */ +void plain_cpp_generator::print_invalid(ostream &os, int indent, + const char *msg, const char *checked_code) +{ + if (checked) + osprintf(os, indent, + "isl_die(ctx().get(), isl_error_invalid, " + "\"%s\", %s);\n", msg, checked_code); + else + print_throw_invalid(os, indent, msg); +} + +/* Print an operator for inserting objects of the class + * into an output stream. + * + * Unless checked C++ bindings are being generated, + * the operator requires its argument to be non-NULL. + * An exception is thrown if anything went wrong during the printing. + * During this printing, isl is made not to print any error message + * because the error message is included in the exception. + * + * If checked C++ bindings are being generated and anything went wrong, + * then record this failure in the output stream. + */ +void plain_cpp_generator::impl_printer::print_stream_insertion() +{ + const char *name = clazz.name.c_str(); + const char *cppname = cppstring.c_str(); + + if (!clazz.fn_to_str) + return; + + osprintf(os, "\n"); + osprintf(os, "inline std::ostream &operator<<(std::ostream &os, "); + osprintf(os, "const %s &obj)\n", cppname); + osprintf(os, "{\n"); + print_check_ptr_start("obj.get()"); + osprintf(os, " char *str = %s_to_str(obj.get());\n", name); + print_check_ptr_end("str"); + if (generator.checked) { + osprintf(os, " if (!str) {\n"); + osprintf(os, " os.setstate(std::ios_base::badbit);\n"); + osprintf(os, " return os;\n"); + osprintf(os, " }\n"); + } + osprintf(os, " os << str;\n"); + osprintf(os, " free(str);\n"); + osprintf(os, " return os;\n"); + osprintf(os, "}\n"); +} + +/* Print code that checks that "ptr" is not NULL at input. + * + * Omit the check if checked C++ bindings are being generated. + */ +void plain_cpp_generator::impl_printer::print_check_ptr(const char *ptr) +{ + if (generator.checked) + return; + + osprintf(os, " if (!%s)\n", ptr); + print_throw_NULL_input(os); +} + +/* Print code that checks that "ptr" is not NULL at input and + * that saves a copy of the isl_ctx of "ptr" for a later check. + * + * Omit the check if checked C++ bindings are being generated. + */ +void plain_cpp_generator::impl_printer::print_check_ptr_start(const char *ptr) +{ + if (generator.checked) + return; + + print_check_ptr(ptr); + print_save_ctx(clazz.name + "_get_ctx(" + ptr + ")"); + print_on_error_continue(); +} + +/* Print code that checks that "ptr" is not NULL at the end. + * A copy of the isl_ctx is expected to have been saved by + * code generated by print_check_ptr_start. + * + * Omit the check if checked C++ bindings are being generated. + */ +void plain_cpp_generator::impl_printer::print_check_ptr_end(const char *ptr) +{ + if (generator.checked) + return; + + osprintf(os, " if (!%s)\n", ptr); + print_throw_last_error(os); +} + +/* Print implementation of global factory functions. + * + * Each class has two global factory functions: + * + * set manage(__isl_take isl_set *ptr); + * set manage_copy(__isl_keep isl_set *ptr); + * + * Unless checked C++ bindings are being generated, + * both functions require the argument to be non-NULL. + * An exception is thrown if anything went wrong during the copying + * in manage_copy. + * During the copying, isl is made not to print any error message + * because the error message is included in the exception. + * + * For a subclass based on a type function, no factory functions + * are introduced because they share the C object type with + * the superclass. + */ +void plain_cpp_generator::impl_printer::print_class_factory() +{ + const char *name = clazz.name.c_str(); + const char *cppname = cppstring.c_str(); + + if (clazz.is_type_subclass()) + return; + + osprintf(os, "\n"); + osprintf(os, "%s manage(__isl_take %s *ptr) {\n", cppname, name); + print_check_ptr("ptr"); + osprintf(os, " return %s(ptr);\n", cppname); + osprintf(os, "}\n"); + + osprintf(os, "%s manage_copy(__isl_keep %s *ptr) {\n", cppname, + name); + print_check_ptr_start("ptr"); + osprintf(os, " ptr = %s_copy(ptr);\n", name); + print_check_ptr_end("ptr"); + osprintf(os, " return %s(ptr);\n", cppname); + osprintf(os, "}\n"); +} + +/* Print implementations of protected constructors. + * + * The pointer to the isl object is either initialized directly or + * through the (immediate) superclass. + */ +void plain_cpp_generator::impl_printer::print_protected_constructors() +{ + const char *name = clazz.name.c_str(); + const char *cppname = cppstring.c_str(); + bool subclass = clazz.is_type_subclass(); + + osprintf(os, "\n"); + osprintf(os, "%s::%s(__isl_take %s *ptr)\n", cppname, cppname, name); + if (subclass) + osprintf(os, " : %s(ptr) {}\n", + type2cpp(clazz.superclass_name).c_str()); + else + osprintf(os, " : ptr(ptr) {}\n"); +} + +/* Print implementations of public constructors. + * + * The pointer to the isl object is either initialized directly or + * through the (immediate) superclass. + * + * If the class has any persistent callbacks, then copy them + * from the original object in the copy constructor. + * If the class is a subclass, then the persistent callbacks + * are assumed to be copied by the copy constructor of the superclass. + * + * Throw an exception from the copy constructor if anything went wrong + * during the copying or if the input is NULL, if any copying is performed. + * During the copying, isl is made not to print any error message + * because the error message is included in the exception. + * No exceptions are thrown if checked C++ bindings + * are being generated, + */ +void plain_cpp_generator::impl_printer::print_public_constructors() +{ + std::string super; + const char *cppname = cppstring.c_str(); + bool subclass = clazz.is_type_subclass(); + + osprintf(os, "\n"); + if (subclass) + super = type2cpp(clazz.superclass_name); + osprintf(os, "%s::%s()\n", cppname, cppname); + if (subclass) + osprintf(os, " : %s() {}\n\n", super.c_str()); + else + osprintf(os, " : ptr(nullptr) {}\n\n"); + osprintf(os, "%s::%s(const %s &obj)\n", cppname, cppname, cppname); + if (subclass) + osprintf(os, " : %s(obj)\n", super.c_str()); + else + osprintf(os, " : ptr(nullptr)\n"); + osprintf(os, "{\n"); + if (!subclass) { + print_check_ptr_start("obj.ptr"); + osprintf(os, " ptr = obj.copy();\n"); + if (clazz.has_persistent_callbacks()) + osprintf(os, " copy_callbacks(obj);\n"); + print_check_ptr_end("ptr"); + } + osprintf(os, "}\n"); +} + +/* Print definition for "method", + * without any automatic type conversions. + * + * This method distinguishes three kinds of methods: member methods, static + * methods, and constructors. + * + * Member methods and static methods return a newly managed + * isl C++ object. + * + * Constructors create a new object from a given set of input parameters. They + * do not return a value, but instead update the pointer stored inside the + * newly created object. + * + * Unless checked C++ bindings are being generated, + * the inputs of the method are first checked for being valid isl objects and + * a copy of the associated isl::ctx is saved (if needed). + * If any failure occurs, either during the check for the inputs or + * during the isl function call, an exception is thrown. + * During the function call, isl is made not to print any error message + * because the error message is included in the exception. + */ +void plain_cpp_generator::impl_printer::print_method(const Method &method) +{ + string methodname = method.fd->getName().str(); + int num_params = method.c_num_params(); + + osprintf(os, "\n"); + print_full_method_header(method); + osprintf(os, "{\n"); + print_argument_validity_check(method); + print_save_ctx(method); + print_on_error_continue(); + + for (const auto &callback : method.callbacks) + print_callback_local(callback); + + osprintf(os, " auto res = %s", methodname.c_str()); + + method.print_fd_arg_list(os, 0, num_params, [&] (int i, int arg) { + method.print_param_use(os, i); + }); + osprintf(os, ";\n"); + + print_exceptional_execution_check(method); + if (method.kind == Method::Kind::constructor) { + osprintf(os, " ptr = res;\n"); + } else { + print_method_return(method); + } + + osprintf(os, "}\n"); +} + +/* Convert argument of type "src" to "dst", with a name specified by "dst". + * + * If "src" is the same as "dst", then no argument conversion is needed. + * + * Otherwise, call the conversion function + * with as arguments the isl_ctx of the object and the argument name, + * or simply the argument name if the source type is an isl type. + * This means this isl_ctx should be available. + */ +void plain_cpp_generator::impl_printer::print_arg_conversion(ParmVarDecl *dst, + ParmVarDecl *src) +{ + std::string name = dst->getName().str(); + QualType type = dst->getOriginalType(); + string cpptype = generator.param2cpp(type); + + if (dst == src) + os << name; + else if (is_isl_type(src->getOriginalType())) + os << cpptype << "(" << name << ")"; + else + os << cpptype << "(ctx(), " << name << ")"; +} + +/* Print a definition for "method", + * where "this" or at least one of the argument types needs to be converted. + * + * "method" is assumed to be a member method. + * + * The generated method performs the required conversion(s) and + * calls the method generated without conversions. + * + * Perform a conversion from the argument in the method declaration + * (as specified by Method::get_param) to the argument of the C function, + * if needed. + * Such a conversion may require the isl_ctx to be available. + * In order to be able to use this isl_ctx, the current object needs + * to valid. The validity of other arguments is checked + * by the called method. + */ +void plain_cpp_generator::impl_printer::print_method( + const ConversionMethod &method) +{ + if (method.kind != Method::Kind::member_method) + die("Automatic conversion currently only supported " + "for object methods"); + + osprintf(os, "\n"); + print_full_method_header(method); + osprintf(os, "{\n"); + print_check_ptr("ptr"); + osprintf(os, " return "); + method.print_call(os, generator.isl_namespace()); + method.print_cpp_arg_list(os, [&] (int i, int arg) { + ParmVarDecl *param = method.fd->getParamDecl(i); + + print_arg_conversion(param, method.get_param(i)); + }); + osprintf(os, ";\n"); + osprintf(os, "}\n"); +} + +/* Print a definition for a constructor for the "id" class + * that takes a user object. + * + * The user object is taken as a std::any and copied into + * a new std::any object on the heap. + * A pointer to this heap object is stored in the isl_id and + * is scheduled to be freed when the reference count of the isl_id + * drops to zero. + * If the allocation of the isl_id fails, then the heap object + * will not be freed automatically, so it needs to be freed manually. + * + * Unless checked C++ bindings are being generated, + * the ctx argument is copied into the save_ctx variable + * for use by print_throw_last_error, which throws an exception + * if the construction fails. + * During the function call, isl is made not to print any error message + * because the error message is included in the exception. + */ +void plain_cpp_generator::impl_printer::print_id_constructor_user() +{ + print_id_constructor_user_header(); + os << "{\n"; + if (!generator.checked) { + print_save_ctx("ctx"); + print_on_error_continue(); + } + os << " std::any *p = new std::any(any);\n"; + os << " auto res = isl_id_alloc(ctx.get(), str.c_str(), p);\n"; + os << " res = isl_id_set_free_user(res, &ctx::free_user);\n"; + os << " if (!res) {\n"; + os << " delete p;\n"; + if (!generator.checked) + print_throw_last_error(os); + os << " }\n"; + os << " ptr = res;\n"; + os << "}\n"; +} + +/* Print a definition for an "id" method + * for retrieving the user object associated to the identifier. + * If "optional" is set, the method returns a std::optional user object. + * The returned object is of a type specified by template parameter T. + * + * The isl_id needs to have been created by the constructor generated + * by print_id_constructor_user. That is, it needs to have a user pointer and + * it needs to have its free_user callback set to &ctx::free_user. + * The object stored in the std::any also needs to be of the required type. + * + * If "optional" is set, return a std::nullopt if any of the checks fail. + * Otherwise, throw an exception_invalid (or call isl_die and + * return a default T in the checked C++ bindings). + */ +void plain_cpp_generator::impl_printer::print_id_user(bool optional) +{ + auto fail = [&] (const char *msg) { + if (optional) + os << " return std::nullopt;\n"; + else + generator.print_invalid(os, 4, msg, "return T()"); + }; + os << "\n"; + print_id_user_header(optional); + os << "{\n"; + print_check_ptr("ptr"); + os << " std::any *p = (std::any *) isl_id_get_user(ptr);\n"; + os << " if (!p)\n"; + fail("no user pointer"); + os << " if (isl_id_get_free_user(ptr) != &ctx::free_user)\n"; + fail("user pointer not attached by C++ interface"); + os << " T *res = std::any_cast(p);\n"; + os << " if (!res)\n"; + fail("user pointer not of given type"); + os << " return *res;\n"; + os << "}\n"; +} + +/* Print implementation of copy assignment operator. + * + * If the class has any persistent callbacks, then copy them + * from the original object. + */ +void plain_cpp_generator::impl_printer::print_copy_assignment() +{ + const char *name = clazz.name.c_str(); + const char *cppname = cppstring.c_str(); + + osprintf(os, "\n"); + osprintf(os, "%s &%s::operator=(%s obj) {\n", cppname, + cppname, cppname); + osprintf(os, " std::swap(this->ptr, obj.ptr);\n", name); + if (clazz.has_persistent_callbacks()) + osprintf(os, " copy_callbacks(obj);\n"); + osprintf(os, " return *this;\n"); + osprintf(os, "}\n"); +} + +/* Print implementation of destructor. + * + * No explicit destructor is needed for type based subclasses. + */ +void plain_cpp_generator::impl_printer::print_destructor() +{ + const char *name = clazz.name.c_str(); + const char *cppname = cppstring.c_str(); + + if (clazz.is_type_subclass()) + return; + + osprintf(os, "\n"); + osprintf(os, "%s::~%s() {\n", cppname, cppname); + osprintf(os, " if (ptr)\n"); + osprintf(os, " %s_free(ptr);\n", name); + osprintf(os, "}\n"); +} + +/* Print a check that the persistent callback corresponding to "fd" + * is not set, throwing an exception (or printing an error message + * and returning nullptr) if it is set. + */ +void plain_cpp_generator::print_check_no_persistent_callback(ostream &os, + const isl_class &clazz, FunctionDecl *fd) +{ + string callback_name = clazz.persistent_callback_name(fd); + + osprintf(os, " if (%s_data)\n", callback_name.c_str()); + print_invalid(os, 4, "cannot release object with persistent callbacks", + "return nullptr"); +} + +/* Print implementation of ptr() functions. + * Since type based subclasses share the pointer with their superclass, + * they can also reuse these functions from the superclass. + * + * If an object has persistent callbacks set, then the underlying + * C object pointer cannot be released because it references data + * in the C++ object. + */ +void plain_cpp_generator::impl_printer::print_ptr() +{ + const char *name = clazz.name.c_str(); + const char *cppname = cppstring.c_str(); + set::const_iterator in; + const set &callbacks = clazz.persistent_callbacks; + + if (clazz.is_type_subclass()) + return; + + osprintf(os, "\n"); + osprintf(os, "__isl_give %s *%s::copy() const & {\n", name, cppname); + osprintf(os, " return %s_copy(ptr);\n", name); + osprintf(os, "}\n\n"); + osprintf(os, "__isl_keep %s *%s::get() const {\n", name, cppname); + osprintf(os, " return ptr;\n"); + osprintf(os, "}\n\n"); + osprintf(os, "__isl_give %s *%s::release() {\n", name, cppname); + for (in = callbacks.begin(); in != callbacks.end(); ++in) + generator.print_check_no_persistent_callback(os, clazz, *in); + osprintf(os, " %s *tmp = ptr;\n", name); + osprintf(os, " ptr = nullptr;\n"); + osprintf(os, " return tmp;\n"); + osprintf(os, "}\n\n"); + osprintf(os, "bool %s::is_null() const {\n", cppname); + osprintf(os, " return ptr == nullptr;\n"); + osprintf(os, "}\n"); +} + +/* Print implementations for the "as" and "isa" methods, if the printed class + * is a superclass with a type function. + * + * "isa" checks whether an object is of a given subclass type. + * "isa_type" does the same, but gets passed the value of the type field + * of the subclass as a function argument and the type of this field + * as a template argument. + * "as" casts an object to a given subclass type, erroring out + * if the object is not of the given type. + * + * If the input is an invalid object, then these methods raise + * an exception. + * If checked bindings are being generated, + * then an invalid boolean or object is returned instead. + */ +void plain_cpp_generator::impl_printer::print_downcast() +{ + const char *cppname = cppstring.c_str(); + + if (!clazz.fn_type) + return; + + osprintf(os, "\n"); + osprintf(os, "template \n"); + osprintf(os, "%s %s::isa_type(T subtype) const\n", + generator.isl_bool2cpp().c_str(), cppname); + osprintf(os, "{\n"); + osprintf(os, " if (is_null())\n"); + if (generator.checked) + osprintf(os, " return boolean();\n"); + else + print_throw_NULL_input(os); + osprintf(os, " return %s(get()) == subtype;\n", + clazz.fn_type->getNameAsString().c_str()); + osprintf(os, "}\n"); + + osprintf(os, "template \n"); + osprintf(os, "%s %s::isa() const\n", + generator.isl_bool2cpp().c_str(), cppname); + osprintf(os, "{\n"); + osprintf(os, " return isa_type(T::type);\n"); + osprintf(os, "}\n"); + + osprintf(os, "template \n"); + osprintf(os, "T %s::as() const\n", cppname); + osprintf(os, "{\n"); + if (generator.checked) + osprintf(os, " if (isa().is_false())\n"); + else + osprintf(os, " if (!isa())\n"); + generator.print_invalid(os, 4, "not an object of the requested subtype", + "return T()"); + osprintf(os, " return T(copy());\n"); + osprintf(os, "}\n"); +} + +/* Print the implementation of the ctx method. + */ +void plain_cpp_generator::impl_printer::print_ctx() +{ + const char *name = clazz.name.c_str(); + const char *cppname = cppstring.c_str(); + std::string ns = generator.isl_namespace(); + + osprintf(os, "\n"); + osprintf(os, "%sctx %s::ctx() const {\n", ns.c_str(), cppname); + osprintf(os, " return %sctx(%s_get_ctx(ptr));\n", ns.c_str(), name); + osprintf(os, "}\n"); +} + +/* Print a separator between groups of method definitions. + * + * No additional separator is required between method definitions. + */ +void plain_cpp_generator::impl_printer::print_method_separator() +{ +} + +/* Print the implementations of the methods needed for the persistent callbacks + * of the class. + */ +void plain_cpp_generator::impl_printer::print_persistent_callbacks() +{ + const char *cppname = cppstring.c_str(); + string classname = type2cpp(clazz); + + if (!clazz.has_persistent_callbacks()) + return; + + osprintf(os, "\n"); + osprintf(os, "%s &%s::copy_callbacks(const %s &obj)\n", + cppname, classname.c_str(), cppname); + osprintf(os, "{\n"); + for (const auto &callback : clazz.persistent_callbacks) { + string callback_name = clazz.persistent_callback_name(callback); + + osprintf(os, " %s_data = obj.%s_data;\n", + callback_name.c_str(), callback_name.c_str()); + } + osprintf(os, " return *this;\n"); + osprintf(os, "}\n"); + + for (const auto &callback : clazz.persistent_callbacks) + print_set_persistent_callback(Method(clazz, callback)); +} + +/* Print a definition for the "get" method "fd" in class "clazz", + * using a name that includes the "get_" prefix, to "os". + * + * This definition simply calls the variant without the "get_" prefix and + * returns its result. + * Note that static methods are not considered to be "get" methods. + */ +void plain_cpp_generator::impl_printer::print_get_method(FunctionDecl *fd) +{ + string get_name = clazz.base_method_name(fd); + string name = clazz.method_name(fd); + int num_params = fd->getNumParams(); + + osprintf(os, "\n"); + print_full_method_header(Method(clazz, fd, get_name)); + osprintf(os, "{\n"); + osprintf(os, " return %s(", name.c_str()); + for (int i = 1; i < num_params; ++i) { + ParmVarDecl *param = fd->getParamDecl(i); + + if (i != 1) + osprintf(os, ", "); + osprintf(os, "%s", param->getName().str().c_str()); + } + osprintf(os, ");\n"); + osprintf(os, "}\n"); +} + +/* Print code that checks that all isl object arguments to "method" are valid + * (not NULL) and throws an exception if they are not. + * + * If checked bindings are being generated, + * then no such check is performed. + */ +void plain_cpp_generator::impl_printer::print_argument_validity_check( + const Method &method) +{ + int n; + bool first = true; + + if (generator.checked) + return; + + n = method.num_params(); + for (int i = 0; i < n; ++i) { + bool is_this; + ParmVarDecl *param = method.fd->getParamDecl(i); + string name = param->getName().str(); + const char *name_str = name.c_str(); + QualType type = param->getOriginalType(); + + is_this = i == 0 && method.kind == Method::Kind::member_method; + if (!is_this && (is_isl_ctx(type) || !is_isl_type(type))) + continue; + + if (first) + osprintf(os, " if ("); + else + osprintf(os, " || "); + + if (is_this) + osprintf(os, "!ptr"); + else + osprintf(os, "%s.is_null()", name_str); + + first = false; + } + if (first) + return; + osprintf(os, ")\n"); + print_throw_NULL_input(os); +} + +/* Print code for saving a copy of "ctx" in a "saved_ctx" variable. + */ +void plain_cpp_generator::impl_printer::print_save_ctx(const std::string &ctx) +{ + os << " auto saved_ctx = " << ctx << ";\n"; +} + +/* Print code for saving a copy of the isl::ctx available at the start + * of the method "method" in a "saved_ctx" variable, + * for use in exception handling. + * + * If checked bindings are being generated, + * then the "saved_ctx" variable is not needed. + * If "method" is a member function, then obtain the isl_ctx from + * the "this" object. + * If the first argument of the method is an isl::ctx, then use that one. + * Otherwise, save a copy of the isl::ctx associated to the first argument + * of isl object type. + */ +void plain_cpp_generator::impl_printer::print_save_ctx(const Method &method) +{ + int n; + ParmVarDecl *param = method.fd->getParamDecl(0); + QualType type = param->getOriginalType(); + + if (generator.checked) + return; + if (method.kind == Method::Kind::member_method) + return print_save_ctx("ctx()"); + if (is_isl_ctx(type)) + return print_save_ctx(param->getName().str()); + n = method.num_params(); + for (int i = 0; i < n; ++i) { + ParmVarDecl *param = method.fd->getParamDecl(i); + QualType type = param->getOriginalType(); + + if (!is_isl_type(type)) + continue; + print_save_ctx(param->getName().str() + ".ctx()"); + return; + } +} + +/* Print code to make isl not print an error message when an error occurs + * within the current scope (if exceptions are available), + * since the error message will be included in the exception. + * If exceptions are not available, then exception::on_error + * is set to ISL_ON_ERROR_ABORT and isl is therefore made to abort instead. + * + * If checked bindings are being generated, + * then leave it to the user to decide what isl should do on error. + * Otherwise, assume that a valid isl::ctx is available + * in the "saved_ctx" variable, + * e.g., through a prior call to print_save_ctx. + */ +void plain_cpp_generator::impl_printer::print_on_error_continue() +{ + if (generator.checked) + return; + osprintf(os, " options_scoped_set_on_error saved_on_error(saved_ctx, " + "exception::on_error);\n"); +} + +/* Print code to "os" that checks whether any of the persistent callbacks + * of the class of "method" is set and if it failed with an exception. + * If so, the "eptr" in the corresponding data structure contains the exception + * that was caught and that needs to be rethrown. + * This field is cleared because the callback and its data may get reused. + * + * The check only needs to be generated for member methods since + * an object is needed for any of the persistent callbacks to be set. + */ +static void print_persistent_callback_exceptional_execution_check(ostream &os, + const Method &method) +{ + if (method.kind != Method::Kind::member_method) + return; + + for (const auto &pcb : method.clazz.persistent_callbacks) { + auto callback_name = method.clazz.persistent_callback_name(pcb); + + osprintf(os, " if (%s_data && %s_data->eptr) {\n", + callback_name.c_str(), callback_name.c_str()); + osprintf(os, " std::exception_ptr eptr = %s_data->eptr;\n", + callback_name.c_str()); + osprintf(os, " %s_data->eptr = nullptr;\n", + callback_name.c_str()); + osprintf(os, " std::rethrow_exception(eptr);\n"); + osprintf(os, " }\n"); + } +} + +/* Print code that checks whether the execution of the core of "method" + * was successful. + * + * If checked bindings are being generated, + * then no checks are performed. + * + * Otherwise, first check if any of the callbacks failed with + * an exception. If so, the "eptr" in the corresponding data structure + * contains the exception that was caught and that needs to be rethrown. + * Then check if the function call failed in any other way and throw + * the appropriate exception. + * In particular, if the return type is isl_stat, isl_bool or isl_size, + * then a negative value indicates a failure. If the return type + * is an isl type, then a NULL value indicates a failure. + * Assume print_save_ctx has made sure that a valid isl::ctx + * is available in the "ctx" variable. + */ +void plain_cpp_generator::impl_printer::print_exceptional_execution_check( + const Method &method) +{ + bool check_null, check_neg; + QualType return_type = method.fd->getReturnType(); + + if (generator.checked) + return; + + print_persistent_callback_exceptional_execution_check(os, method); + + for (const auto &callback : method.callbacks) { + std::string name; + + name = callback->getName().str(); + osprintf(os, " if (%s_data.eptr)\n", name.c_str()); + osprintf(os, " std::rethrow_exception(%s_data.eptr);\n", + name.c_str()); + } + + check_neg = is_isl_neg_error(return_type); + check_null = is_isl_type(return_type); + if (!check_null && !check_neg) + return; + + if (check_neg) + osprintf(os, " if (res < 0)\n"); + else + osprintf(os, " if (!res)\n"); + print_throw_last_error(os); +} + +/* Return a pointer to the appropriate type printer, + * i.e., the regular type printer or the checked type printer + * depending on the setting of this->checked. + */ +std::unique_ptr plain_cpp_generator::type_printer() +{ + cpp_type_printer *printer; + + if (checked) + printer = new checked_cpp_type_printer(); + else + printer = new cpp_type_printer(); + + return std::unique_ptr(printer); +} + +/* Return the C++ return type of the method "method". + * + * Use the appropriate type printer. + */ +std::string plain_cpp_generator::get_return_type(const Method &method) +{ + return type_printer()->return_type(method); +} + +/* Given a method "method" for setting a persistent callback of its class, + * print the implementations of the methods needed for that callback. + * + * In particular, print + * - the implementation of a static inline method + * for use as the C callback function + * - the definition of a private method for setting the callback function + * - the public method for constructing a new object with the callback set. + */ +void plain_cpp_generator::impl_printer::print_set_persistent_callback( + const Method &method) +{ + string fullname = method.fd->getName().str(); + ParmVarDecl *param = persistent_callback_arg(method.fd); + string pname; + string callback_name = clazz.persistent_callback_name(method.fd); + + osprintf(os, "\n"); + print_persistent_callback_prototype(method.fd); + osprintf(os, "\n"); + osprintf(os, "{\n"); + print_callback_body(2, param, callback_name); + osprintf(os, "}\n\n"); + + pname = param->getName().str(); + print_persistent_callback_setter_prototype(method.fd); + osprintf(os, "\n"); + osprintf(os, "{\n"); + print_check_ptr_start("ptr"); + osprintf(os, " %s_data = std::make_shared();\n", + callback_name.c_str(), callback_name.c_str()); + osprintf(os, " %s_data->func = %s;\n", + callback_name.c_str(), pname.c_str()); + osprintf(os, " ptr = %s(ptr, &%s, %s_data.get());\n", + fullname.c_str(), callback_name.c_str(), callback_name.c_str()); + print_check_ptr_end("ptr"); + osprintf(os, "}\n\n"); + + print_full_method_header(method); + osprintf(os, "{\n"); + osprintf(os, " auto copy = *this;\n"); + osprintf(os, " copy.set_%s_data(%s);\n", + callback_name.c_str(), pname.c_str()); + osprintf(os, " return copy;\n"); + osprintf(os, "}\n"); +} + +/* Print the return statement of the C++ method "method". + * + * The result of the corresponding isl function is returned as a new + * object if the underlying isl function returns an isl_* ptr, as a bool + * if the isl function returns an isl_bool, as void if the isl functions + * returns an isl_stat, + * as std::string if the isl function returns 'const char *', and as + * unmodified return value otherwise. + * If checked C++ bindings are being generated, + * then an isl_bool return type is transformed into a boolean and + * an isl_stat into a stat since no exceptions can be generated + * on negative results from the isl function. + * If the method returns a new instance of the same object type and + * if the class has any persistent callbacks, then the data + * for these callbacks are copied from the original to the new object. + * If "clazz" is a subclass that is based on a type function and + * if the return type corresponds to the superclass data type, + * then it is replaced by the subclass data type. + */ +void plain_cpp_generator::impl_printer::print_method_return( + const Method &method) +{ + QualType return_type = method.fd->getReturnType(); + string rettype_str = generator.get_return_type(method); + bool returns_super = method.is_subclass_mutator(); + + if (is_isl_type(return_type) || + (generator.checked && is_isl_neg_error(return_type))) { + osprintf(os, " return manage(res)"); + if (is_mutator(clazz, method.fd) && + clazz.has_persistent_callbacks()) + osprintf(os, ".copy_callbacks(*this)"); + if (returns_super) + osprintf(os, ".as<%s>()", rettype_str.c_str()); + osprintf(os, ";\n"); + } else if (is_isl_stat(return_type)) { + osprintf(os, " return;\n"); + } else if (is_string(return_type)) { + osprintf(os, " std::string tmp(res);\n"); + if (gives(method.fd)) + osprintf(os, " free(res);\n"); + osprintf(os, " return tmp;\n"); + } else { + osprintf(os, " return res;\n"); + } +} + +/* Print the header for "method", including the terminating semicolon + * in case of a declaration and a newline. + * + * Use the appropriate type printer to print argument and return types. + */ +void plain_cpp_generator::plain_printer::print_full_method_header( + const Method &method) +{ + auto type_printer = generator.type_printer(); + + print_method_header(method, *type_printer); + + if (declarations) + osprintf(os, ";"); + osprintf(os, "\n"); +} + +/* Generate the list of argument types for a callback function of + * type "type". If "cpp" is set, then generate the C++ type list, otherwise + * the C type list. + * + * Use the appropriate type printer. + * For the plain C++ interface, the argument position is irrelevant, + * so simply pass in -1. + */ +string plain_cpp_generator::generate_callback_args(QualType type, bool cpp) +{ + return type_printer()->generate_callback_args(-1, type, cpp); +} + +/* Generate the full cpp type of a callback function of type "type". + * + * Use the appropriate type printer. + * For the plain C++ interface, the argument position is irrelevant, + * so simply pass in -1. + */ +string plain_cpp_generator::generate_callback_type(QualType type) +{ + return type_printer()->generate_callback_type(-1, type); +} + +/* Print the call to the C++ callback function "call", + * with the given indentation, wrapped + * for use inside the lambda function that is used as the C callback function, + * in the case where checked C++ bindings are being generated. + * + * In particular, print + * + * auto ret = @call@; + * return ret.release(); + */ +void plain_cpp_generator::impl_printer::print_wrapped_call_checked(int indent, + const string &call) +{ + osprintf(os, indent, "auto ret = %s;\n", call.c_str()); + osprintf(os, indent, "return ret.release();\n"); +} + +/* Print the call to the C++ callback function "call", + * with the given indentation and with return type "rtype", wrapped + * for use inside the lambda function that is used as the C callback function. + * + * In particular, print + * + * ISL_CPP_TRY { + * @call@; + * return isl_stat_ok; + * } ISL_CPP_CATCH_ALL { + * data->eptr = std::current_exception(); + * return isl_stat_error; + * } + * or + * ISL_CPP_TRY { + * auto ret = @call@; + * return ret ? isl_bool_true : isl_bool_false; + * } ISL_CPP_CATCH_ALL { + * data->eptr = std::current_exception(); + * return isl_bool_error; + * } + * or + * ISL_CPP_TRY { + * auto ret = @call@; + * return ret.release(); + * } ISL_CPP_CATCH_ALL { + * data->eptr = std::current_exception(); + * return NULL; + * } + * + * depending on the return type. + * + * where ISL_CPP_TRY is defined to "try" and ISL_CPP_CATCH_ALL to "catch (...)" + * (if exceptions are available). + * + * If checked C++ bindings are being generated, then + * the call is wrapped differently. + */ +void plain_cpp_generator::impl_printer::print_wrapped_call(int indent, + const string &call, QualType rtype) +{ + if (generator.checked) + return print_wrapped_call_checked(indent, call); + + osprintf(os, indent, "ISL_CPP_TRY {\n"); + if (is_isl_stat(rtype)) + osprintf(os, indent, " %s;\n", call.c_str()); + else + osprintf(os, indent, " auto ret = %s;\n", call.c_str()); + if (is_isl_stat(rtype)) + osprintf(os, indent, " return isl_stat_ok;\n"); + else if (is_isl_bool(rtype)) + osprintf(os, indent, + " return ret ? isl_bool_true : isl_bool_false;\n"); + else + osprintf(os, indent, " return ret.release();\n"); + osprintf(os, indent, "} ISL_CPP_CATCH_ALL {\n"); + osprintf(os, indent, " data->eptr = std::current_exception();\n"); + if (is_isl_stat(rtype)) + osprintf(os, indent, " return isl_stat_error;\n"); + else if (is_isl_bool(rtype)) + osprintf(os, indent, " return isl_bool_error;\n"); + else + osprintf(os, indent, " return NULL;\n"); + osprintf(os, indent, "}\n"); +} + +/* Print the declaration for a "prefix"_data data structure + * that can be used for passing to a C callback function + * containing a copy of the C++ callback function "param", + * along with an std::exception_ptr that is used to store any + * exceptions thrown in the C++ callback. + * + * If the C callback is of the form + * + * isl_stat (*fn)(__isl_take isl_map *map, void *user) + * + * then the following declaration is printed: + * + * struct _data { + * std::function func; + * std::exception_ptr eptr; + * } + * + * (without a newline or a semicolon). + * + * The std::exception_ptr object is not added to "prefix"_data + * if checked C++ bindings are being generated. + */ +void plain_cpp_generator::plain_printer::print_callback_data_decl( + ParmVarDecl *param, + const string &prefix) +{ + string cpp_args; + + cpp_args = generator.generate_callback_type(param->getType()); + + osprintf(os, " struct %s_data {\n", prefix.c_str()); + osprintf(os, " %s func;\n", cpp_args.c_str()); + if (!generator.checked) + osprintf(os, " std::exception_ptr eptr;\n"); + osprintf(os, " }"); +} + +/* Given a group of methods with the same name, + * should extra methods be added that take as arguments + * those types that can be converted to the original argument type + * through a unary constructor? + * + * Note that even if this method returns true, + * the extra methods are only printed by the caller + * if exactly one of the methods in the group was originally defined + * in the printed class. + * Signal that they should be printed if the group contains + * both methods originally defined in the printed class and + * methods that have been copied from an ancestor + * by checking whether there are at least two methods in the group. + */ +bool plain_cpp_generator::plain_printer::want_descendent_overloads( + const function_set &methods) +{ + return methods.size() > 1; +} + +/* Print the header of the constructor for the "id" class + * that takes a user object. + * + * The user object is taken as a std::any. + */ +void plain_cpp_generator::plain_printer::print_id_constructor_user_header() +{ + if (declarations) + os << " inline explicit "; + else + os << "id::"; + os << "id(" << generator.isl_namespace() << "ctx ctx, " + << "const std::string &str, const std::any &any)"; + if (declarations) + os << ";"; + os << "\n"; +} + +/* Print the header of the "id" method + * for retrieving the user object associated to the identifier. + * If "optional" is set, the method returns a std::optional user object. + * The returned object is of a type specified by template parameter T. + */ +void plain_cpp_generator::plain_printer::print_id_user_header(bool optional) +{ + auto indent = declarations ? " " : ""; + os << indent << "template \n"; + os << indent << (optional ? "std::optional " : "T "); + if (!declarations) + os << "id::"; + os << (optional ? "try_" : ""); + os << "user() const"; + if (declarations) + os << ";"; + os << "\n"; +} + +/* Perform printing by "fn" in a context that only gets compiled + * by C++17 compilers. + */ +static void on_cplusplus17(ostream &os, const std::function &fn) +{ + os << "#if __cplusplus >= 201703L\n"; + fn(); + os << "#endif\n"; +} + +/* Print declarations or definitions of the special methods of the "id" class + * that are not automatically derived from the C interface. + * + * In particular, print a constructor that takes a user pointer + * as well as methods for retrieving this user pointer. + * + * These methods require C++17 features. + */ +void plain_cpp_generator::plain_printer::print_special_id() +{ + os << "\n"; + on_cplusplus17(os, [this] () { + print_id_constructor_user(); + print_id_user(true); + print_id_user(false); + }); +} + +/* Print declarations or definitions of any special methods of this class + * not automatically derived from the C interface. + * + * In particular, print special methods for the "id" class. + */ +void plain_cpp_generator::plain_printer::print_special() +{ + if (clazz.name == "isl_id") + print_special_id(); +} + +/* Print declarations or definitions of the public methods. + */ +void plain_cpp_generator::plain_printer::print_public_methods() +{ + print_public_constructors(); + print_constructors(); + print_copy_assignment(); + print_destructor(); + print_ptr(); + print_downcast(); + print_ctx(); + print_method_separator(); + print_persistent_callbacks(); + print_methods(); + print_set_enums(); + print_special(); +} + +/* Print the body of C function callback with the given indentation + * that can be use as an argument to "param" for marshalling + * the corresponding C++ callback. + * The data structure that contains the C++ callback is of type + * "prefix"_data. + * + * For a callback of the form + * + * isl_stat (*fn)(__isl_take isl_map *map, void *user) + * + * the following code is generated: + * + * auto *data = static_cast_data *>(arg_1); + * ISL_CPP_TRY { + * stat ret = (data->func)(manage(arg_0)); + * return isl_stat_ok; + * } ISL_CPP_CATCH_ALL { + * data->eptr = std::current_exception(); + * return isl_stat_error; + * } + * + * If checked C++ bindings are being generated, then + * generate the following code: + * + * auto *data = static_cast_data *>(arg_1); + * stat ret = (data->func)(manage(arg_0)); + * return isl_stat(ret); + */ +void plain_cpp_generator::impl_printer::print_callback_body(int indent, + ParmVarDecl *param, const string &prefix) +{ + QualType ptype, rtype; + string call, last_idx; + const FunctionProtoType *callback; + int num_params; + + ptype = param->getType(); + + callback = extract_prototype(ptype); + rtype = callback->getReturnType(); + num_params = callback->getNumArgs(); + + last_idx = ::to_string(num_params - 1); + + call = "(data->func)("; + for (long i = 0; i < num_params - 1; i++) { + if (!generator.callback_takes_argument(param, i)) + call += "manage_copy"; + else + call += "manage"; + call += "(arg_" + ::to_string(i) + ")"; + if (i != num_params - 2) + call += ", "; + } + call += ")"; + + osprintf(os, indent, + "auto *data = static_cast(arg_%s);\n", + prefix.c_str(), last_idx.c_str()); + print_wrapped_call(indent, call, rtype); +} + +/* Print the local variables that are needed for a callback argument, + * in particular, print a lambda function that wraps the callback and + * a pointer to the actual C++ callback function. + * + * For a callback of the form + * + * isl_stat (*fn)(__isl_take isl_map *map, void *user) + * + * the following lambda function is generated: + * + * auto fn_lambda = [](isl_map *arg_0, void *arg_1) -> isl_stat { + * auto *data = static_cast(arg_1); + * try { + * stat ret = (data->func)(manage(arg_0)); + * return isl_stat_ok; + * } catch (...) { + * data->eptr = std::current_exception(); + * return isl_stat_error; + * } + * }; + * + * A copy of the std::function C++ callback function is stored in + * a fn_data data structure for passing to the C callback function, + * along with an std::exception_ptr that is used to store any + * exceptions thrown in the C++ callback. + * + * struct fn_data { + * std::function func; + * std::exception_ptr eptr; + * } fn_data = { fn }; + * + * This std::function object represents the actual user + * callback function together with the locally captured state at the caller. + * + * The lambda function is expected to be used as a C callback function + * where the lambda itself is provided as the function pointer and + * where the user void pointer is a pointer to fn_data. + * The std::function object is extracted from the pointer to fn_data + * inside the lambda function. + * + * The std::exception_ptr object is not added to fn_data + * if checked C++ bindings are being generated. + * The body of the generated lambda function then is as follows: + * + * stat ret = (data->func)(manage(arg_0)); + * return isl_stat(ret); + * + * If the C callback does not take its arguments, then + * manage_copy is used instead of manage. + */ +void plain_cpp_generator::impl_printer::print_callback_local(ParmVarDecl *param) +{ + string pname; + QualType ptype, rtype; + string c_args, cpp_args, rettype; + const FunctionProtoType *callback; + + pname = param->getName().str(); + ptype = param->getType(); + + c_args = generator.generate_callback_args(ptype, false); + + callback = extract_prototype(ptype); + rtype = callback->getReturnType(); + rettype = rtype.getAsString(); + + print_callback_data_decl(param, pname); + osprintf(os, " %s_data = { %s };\n", pname.c_str(), pname.c_str()); + osprintf(os, " auto %s_lambda = [](%s) -> %s {\n", + pname.c_str(), c_args.c_str(), rettype.c_str()); + print_callback_body(4, param, pname); + osprintf(os, " };\n"); +} + +/* Return the C++ counterpart to the isl_bool type. + * + * For the checked C++ bindings this is "boolean". + */ +std::string checked_cpp_type_printer::isl_bool() const +{ + return "boolean"; +} + +/* Return the C++ counterpart to the isl_bool type. + * + * Use the appropriate type printer. + */ +string plain_cpp_generator::isl_bool2cpp() +{ + return type_printer()->isl_bool(); +} + +/* Return the C++ counterpart to the isl_stat type. + * + * For the checked C++ bindings this is "stat". + */ +string checked_cpp_type_printer::isl_stat() const +{ + return "stat"; +} + +/* Return the C++ counterpart to the isl_size type. + * + * For the checked C++ bindings this is "class size". + */ +string checked_cpp_type_printer::isl_size() const +{ + return "class size"; +} + +/* Return the namespace of the generated C++ bindings. + * + * For the checked C++ bindings this is "isl::checked::". + */ +std::string checked_cpp_type_printer::isl_namespace() const +{ + return "isl::checked::"; +} + +/* Return the namespace of the generated C++ bindings. + * + * Use the appropriate type printer. + */ +string plain_cpp_generator::isl_namespace() +{ + return type_printer()->isl_namespace(); +} + +/* Translate parameter or return type "type" to its C++ name counterpart. + * + * Use the appropriate type printer. + * For the plain C++ interface, the argument position is irrelevant, + * so simply pass in -1. + */ +string plain_cpp_generator::param2cpp(QualType type) +{ + return type_printer()->param(-1, type); +} diff --git a/external/mit/isl/dist/interface/plain_cpp.h b/external/mit/isl/dist/interface/plain_cpp.h new file mode 100644 index 000000000000..17f4af05afe0 --- /dev/null +++ b/external/mit/isl/dist/interface/plain_cpp.h @@ -0,0 +1,174 @@ +#ifndef ISL_INTERFACE_PLAIN_CPP_H +#define ISL_INTERFACE_PLAIN_CPP_H + +#include +#include + +#include "cpp.h" +#include "generator.h" + +using namespace std; +using namespace clang; + +/* A type printer for converting argument and return types + * to string representations of the corresponding types + * in the checked C++ interface. + */ +struct checked_cpp_type_printer : public cpp_type_printer { + virtual std::string isl_bool() const override; + virtual std::string isl_stat() const override; + virtual std::string isl_size() const override; + virtual std::string isl_namespace() const override; +}; + +/* Generator for plain C++ bindings. + * + * "checked" is set if C++ bindings should be generated + * that rely on the user to check for error conditions. + */ +class plain_cpp_generator : public cpp_generator { + struct plain_printer; + struct decl_printer; + struct impl_printer; +protected: + bool checked; +public: + plain_cpp_generator(SourceManager &SM, + set &exported_types, + set exported_functions, + set functions, + bool checked = false); + + virtual void generate(); +private: + void print_forward_declarations(ostream &os); + void print_declarations(ostream &os); + void print_class(ostream &os, const isl_class &clazz); + void print_class_forward_decl(ostream &os, const isl_class &clazz); + void print_implementations(ostream &os); + void print_class_impl(ostream &os, const isl_class &clazz); + void print_check_no_persistent_callback(ostream &os, + const isl_class &clazz, FunctionDecl *fd); + void print_invalid(ostream &os, int indent, const char *msg, + const char *checked_code); + void print_method_param_use(ostream &os, ParmVarDecl *param, + bool load_from_this_ptr); + std::unique_ptr type_printer(); + std::string get_return_type(const Method &method); + string generate_callback_args(QualType type, bool cpp); + string generate_callback_type(QualType type); + string isl_bool2cpp(); + string isl_namespace(); + string param2cpp(QualType type); +}; + +/* A helper class for printing method declarations and definitions + * of a class for the plain C++ interface. + * + * "generator" is the C++ interface generator printing the classes. + */ +struct plain_cpp_generator::plain_printer : public cpp_generator::class_printer { + plain_cpp_generator &generator; + + plain_printer(std::ostream &os, const isl_class &clazz, + plain_cpp_generator &generator, bool is_declaration) : + class_printer(os, clazz, generator, is_declaration), + generator(generator) {} + + void print_persistent_callback_prototype(FunctionDecl *method); + void print_persistent_callback_setter_prototype(FunctionDecl *method); + void print_full_method_header(const Method &method); + void print_callback_data_decl(ParmVarDecl *param, const string &name); + virtual bool want_descendent_overloads(const function_set &methods) + override; + virtual void print_public_constructors() = 0; + virtual void print_copy_assignment() = 0; + virtual void print_destructor() = 0; + virtual void print_ptr() = 0; + virtual void print_downcast() = 0; + virtual void print_ctx() = 0; + virtual void print_method_separator() = 0; + virtual void print_persistent_callbacks() = 0; + void print_public_methods(); + void print_id_constructor_user_header(); + void print_id_user_header(bool optional); + virtual void print_id_constructor_user() = 0; + virtual void print_id_user(bool optional) = 0; + void print_special_id(); + void print_special(); +}; + +/* A helper class for printing method declarations of a class. + */ +struct plain_cpp_generator::decl_printer : + public plain_cpp_generator::plain_printer +{ + decl_printer(std::ostream &os, const isl_class &clazz, + plain_cpp_generator &generator) : + plain_printer(os, clazz, generator, true) {} + + void print_subclass_type(); + void print_class_factory(const std::string &prefix = std::string()); + void print_protected_constructors(); + virtual void print_copy_assignment() override; + virtual void print_public_constructors() override; + virtual void print_destructor() override; + virtual void print_ptr() override; + void print_isa_type_template(int indent, const isl_class &super); + virtual void print_downcast() override; + virtual void print_ctx() override; + virtual void print_method_separator() override; + void print_persistent_callback_data(FunctionDecl *method); + virtual void print_persistent_callbacks() override; + virtual void print_method(const Method &method) override; + virtual void print_method(const ConversionMethod &method) override; + virtual void print_get_method(FunctionDecl *fd) override; + virtual void print_id_constructor_user() override; + virtual void print_id_user(bool optional) override; +}; + +/* A helper class for printing method definitions of a class. + */ +struct plain_cpp_generator::impl_printer : + public plain_cpp_generator::plain_printer +{ + impl_printer(std::ostream &os, const isl_class &clazz, + plain_cpp_generator &generator) : + plain_printer(os, clazz, generator, false) {} + + void print_arg_conversion(ParmVarDecl *dst, ParmVarDecl *src); + virtual void print_method(const Method &method) override; + virtual void print_method(const ConversionMethod &method) override; + virtual void print_get_method(FunctionDecl *fd) override; + void print_check_ptr(const char *ptr); + void print_check_ptr_start(const char *ptr); + void print_check_ptr_end(const char *ptr); + void print_class_factory(); + void print_protected_constructors(); + virtual void print_public_constructors() override; + virtual void print_copy_assignment() override; + virtual void print_destructor() override; + virtual void print_ptr() override; + virtual void print_downcast() override; + virtual void print_ctx() override; + virtual void print_method_separator() override; + void print_set_persistent_callback(const Method &method); + virtual void print_persistent_callbacks() override; + void print_argument_validity_check(const Method &method); + void print_save_ctx(const std::string &ctx); + void print_save_ctx(const Method &method); + void print_on_error_continue(); + void print_exceptional_execution_check(const Method &method); + void print_method_return(const Method &method); + void print_stream_insertion(); + void print_wrapped_call_checked(int indent, const std::string &call); + void print_wrapped_call(int indent, const std::string &call, + QualType rtype); + void print_callback_body(int indent, ParmVarDecl *param, + const string &name); + void print_callback_local(ParmVarDecl *param); + virtual void print_id_constructor_user() override; + virtual void print_id_user(bool optional) override; +}; + +#endif diff --git a/external/mit/isl/dist/interface/python.cc b/external/mit/isl/dist/interface/python.cc new file mode 100644 index 000000000000..e4a828863129 --- /dev/null +++ b/external/mit/isl/dist/interface/python.cc @@ -0,0 +1,1179 @@ +/* + * Copyright 2011,2015 Sven Verdoolaege. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY SVEN VERDOOLAEGE ''AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SVEN VERDOOLAEGE OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation + * are those of the authors and should not be interpreted as + * representing official policies, either expressed or implied, of + * Sven Verdoolaege. + */ + +#include "isl_config.h" + +#include +#include + +#include +#include +#include +#include + +#include "python.h" +#include "generator.h" + +/* Argument format for Python methods with a fixed number of arguments. + */ +static const char *fixed_arg_fmt = "arg%d"; +/* Argument format for Python methods with a variable number of arguments. + */ +static const char *var_arg_fmt = "args[%d]"; + +/* Drop the "isl_" initial part of the type name "name". + */ +static string type2python(string name) +{ + return name.substr(4); +} + +/* Print the arguments of a method with "n_arg" arguments, starting at "first". + */ +void python_generator::print_method_arguments(int first, int n_arg) +{ + for (int i = first; i < n_arg; ++i) { + if (i > first) + printf(", "); + printf("arg%d", i); + } +} + +/* Print the start of a definition for method "name" + * (without specifying the arguments). + * If "is_static" is set, then mark the python method as static. + * + * If the method is called "from", then rename it to "convert_from" + * because "from" is a python keyword. + */ +static void print_method_def(bool is_static, const string &name) +{ + const char *s; + + if (is_static) + printf(" @staticmethod\n"); + + s = name.c_str(); + if (name == "from") + s = "convert_from"; + + printf(" def %s", s); +} + +/* Print the header of the method "name" with "n_arg" arguments. + * If "is_static" is set, then mark the python method as static. + */ +void python_generator::print_method_header(bool is_static, const string &name, + int n_arg) +{ + print_method_def(is_static, name); + printf("("); + print_method_arguments(0, n_arg); + printf("):\n"); +} + +/* Print formatted output with the given indentation. + */ +static void print_indent(int indent, const char *format, ...) +{ + va_list args; + + printf("%*s", indent, " "); + va_start(args, format); + vprintf(format, args); + va_end(args); +} + +/* Print a check that the argument in position "pos" is of type "type" + * with the given indentation. + * If this fails and if "upcast" is set, then convert the first + * argument to "super" and call the method "name" on it, passing + * the remaining of the "n" arguments. + * If the check fails and "upcast" is not set, then simply raise + * an exception. + * If "upcast" is not set, then the "super", "name" and "n" arguments + * to this function are ignored. + * "fmt" is the format for printing Python method arguments. + */ +void python_generator::print_type_check(int indent, const string &type, + const char *fmt, int pos, bool upcast, const string &super, + const string &name, int n) +{ + print_indent(indent, "try:\n"); + print_indent(indent, " if not "); + printf(fmt, pos); + printf(".__class__ is %s:\n", type.c_str()); + print_indent(indent, " "); + printf(fmt, pos); + printf(" = %s(", type.c_str()); + printf(fmt, pos); + printf(")\n"); + print_indent(indent, "except:\n"); + if (upcast) { + print_indent(indent, " return %s(", + type2python(super).c_str()); + printf(fmt, 0); + printf(").%s(", name.c_str()); + for (int i = 1; i < n; ++i) { + if (i != 1) + printf(", "); + printf(fmt, i); + } + printf(")\n"); + } else + print_indent(indent, " raise\n"); +} + +/* For each of the "n" initial arguments of the function "method" + * that refer to an isl structure, + * including the object on which the method is called, + * check if the corresponding actual argument is of the right type. + * If not, try and convert it to the right type. + * If that doesn't work and if "super" contains at least one element, + * try and convert self to the type of the first superclass in "super" and + * call the corresponding method. + * If "first_is_ctx" is set, then the first argument is skipped. + */ +void python_generator::print_type_checks(const string &cname, + FunctionDecl *method, bool first_is_ctx, int n, + const vector &super) +{ + for (int i = first_is_ctx; i < n; ++i) { + ParmVarDecl *param = method->getParamDecl(i); + string type; + + if (!is_isl_type(param->getOriginalType())) + continue; + type = type2python(extract_type(param->getOriginalType())); + if (!first_is_ctx && i > 0 && super.size() > 0) + print_type_check(8, type, fixed_arg_fmt, + i - first_is_ctx, true, + super[0], cname, n); + else + print_type_check(8, type, fixed_arg_fmt, + i - first_is_ctx, false, "", cname, -1); + } +} + +/* Print a call to the *_copy function corresponding to "type". + */ +void python_generator::print_copy(QualType type) +{ + string type_s = extract_type(type); + + printf("isl.%s_copy", type_s.c_str()); +} + +/* Construct a wrapper for callback argument "param" (at position "arg"). + * Assign the wrapper to "cb{arg}". + * + * The wrapper converts the arguments of the callback to python types, + * taking a copy if the C callback does not take its arguments. + * If any exception is thrown, the wrapper keeps track of it in exc_info[0] + * and returns a value indicating an error. Otherwise the wrapper + * returns a value indicating success. + * In case the C callback is expected to return an isl_stat, + * the error value is -1 and the success value is 0. + * In case the C callback is expected to return an isl_bool, + * the error value is -1 and the success value is 1 or 0 depending + * on the result of the Python callback. + * Otherwise, None is returned to indicate an error and + * a copy of the object in case of success. + */ +void python_generator::print_callback(ParmVarDecl *param, int arg) +{ + QualType type = param->getOriginalType(); + const FunctionProtoType *fn = extract_prototype(type); + QualType return_type = fn->getReturnType(); + unsigned n_arg = fn->getNumArgs(); + + printf(" exc_info = [None]\n"); + printf(" fn = CFUNCTYPE("); + if (is_isl_stat(return_type) || is_isl_bool(return_type)) + printf("c_int"); + else + printf("c_void_p"); + for (unsigned i = 0; i < n_arg - 1; ++i) { + if (!is_isl_type(fn->getArgType(i))) + die("Argument has non-isl type"); + printf(", c_void_p"); + } + printf(", c_void_p)\n"); + printf(" def cb_func("); + for (unsigned i = 0; i < n_arg; ++i) { + if (i) + printf(", "); + printf("cb_arg%d", i); + } + printf("):\n"); + for (unsigned i = 0; i < n_arg - 1; ++i) { + string arg_type; + arg_type = type2python(extract_type(fn->getArgType(i))); + printf(" cb_arg%d = %s(ctx=arg0.ctx, ptr=", + i, arg_type.c_str()); + if (!callback_takes_argument(param, i)) + print_copy(fn->getArgType(i)); + printf("(cb_arg%d))\n", i); + } + printf(" try:\n"); + if (is_isl_stat(return_type)) + printf(" arg%d(", arg); + else + printf(" res = arg%d(", arg); + for (unsigned i = 0; i < n_arg - 1; ++i) { + if (i) + printf(", "); + printf("cb_arg%d", i); + } + printf(")\n"); + printf(" except BaseException as e:\n"); + printf(" exc_info[0] = e\n"); + if (is_isl_stat(return_type) || is_isl_bool(return_type)) + printf(" return -1\n"); + else + printf(" return None\n"); + if (is_isl_stat(return_type)) { + printf(" return 0\n"); + } else if (is_isl_bool(return_type)) { + printf(" return 1 if res else 0\n"); + } else { + printf(" return "); + print_copy(return_type); + printf("(res.ptr)\n"); + } + printf(" cb%d = fn(cb_func)\n", arg); +} + +/* Print the argument at position "arg" in call to "fd". + * "fmt" is the format for printing Python method arguments. + * "skip" is the number of initial arguments of "fd" that are + * skipped in the Python method. + * + * If the (first) argument is an isl_ctx, then print "ctx", + * assuming that the caller has made the context available + * in a "ctx" variable. + * Otherwise, if the argument is a callback, then print a reference to + * the corresponding callback wrapper. + * Otherwise, if the argument is marked as consuming a reference, + * then pass a copy of the pointer stored in the corresponding + * argument passed to the Python method. + * Otherwise, if the argument is a string, then the python string is first + * encoded as a byte sequence, using 'ascii' as encoding. This assumes + * that all strings passed to isl can be converted to 'ascii'. + * Otherwise, if the argument is a pointer, then pass this pointer itself. + * Otherwise, pass the argument directly. + */ +void python_generator::print_arg_in_call(FunctionDecl *fd, const char *fmt, + int arg, int skip) +{ + ParmVarDecl *param = fd->getParamDecl(arg); + QualType type = param->getOriginalType(); + if (is_isl_ctx(type)) { + printf("ctx"); + } else if (is_callback(type)) { + printf("cb%d", arg - skip); + } else if (takes(param)) { + print_copy(type); + printf("("); + printf(fmt, arg - skip); + printf(".ptr)"); + } else if (is_string(type)) { + printf(fmt, arg - skip); + printf(".encode('ascii')"); + } else if (type->isPointerType()) { + printf(fmt, arg - skip); + printf(".ptr"); + } else { + printf(fmt, arg - skip); + } +} + +/* Generate code that raises the exception captured in "exc_info", if any, + * with the given indentation. + */ +static void print_rethrow(int indent, const char *exc_info) +{ + print_indent(indent, "if %s is not None:\n", exc_info); + print_indent(indent, " raise %s\n", exc_info); +} + +/* Print code with the given indentation that checks + * whether any of the persistent callbacks of "clazz" + * is set and if it failed with an exception. If so, the 'exc_info' + * field contains the exception and is raised again. + * The field is cleared because the callback and its data may get reused. + * "fmt" is the format for printing Python method arguments. + */ +static void print_persistent_callback_failure_check(int indent, + const isl_class &clazz, const char *fmt) +{ + const set &callbacks = clazz.persistent_callbacks; + set::const_iterator in; + + for (in = callbacks.begin(); in != callbacks.end(); ++in) { + string callback_name = clazz.persistent_callback_name(*in); + + print_indent(indent, "if hasattr("); + printf(fmt, 0); + printf(", '%s') and ", callback_name.c_str()); + printf(fmt, 0); + printf(".%s['exc_info'] != None:\n", callback_name.c_str()); + print_indent(indent, " exc_info = "); + printf(fmt, 0); + printf(".%s['exc_info'][0]\n", callback_name.c_str()); + print_indent(indent, " "); + printf(fmt, 0); + printf(".%s['exc_info'][0] = None\n", callback_name.c_str()); + print_rethrow(indent + 4, "exc_info"); + } +} + +/* Print the return statement of the python method corresponding + * to the C function "method" with the given indentation. + * If the object on which the method was called + * may have a persistent callback, then first check if any of those failed. + * "fmt" is the format for printing Python method arguments. + * + * If the method returns a new instance of the same object type and + * if the class has any persistent callbacks, then the data + * for these callbacks are copied from the original to the new object. + * If the method it itself setting a persistent callback, + * then keep track of the constructed C callback (such that it doesn't + * get destroyed) and the data structure that holds the captured exception + * (such that it can be raised again). + * The callback appears in position 1 and the C callback is therefore + * called "cb1". + * + * If the return type is a (const) char *, then convert the result + * to a Python string, raising an error on NULL and freeing + * the C string if needed. For python 3 compatibility, the string returned + * by isl is explicitly decoded as an 'ascii' string. This is correct + * as all strings returned by isl are expected to be 'ascii'. + * + * If the return type is isl_stat, isl_bool or isl_size, then + * raise an error on isl_stat_error, isl_bool_error or isl_size_error. + * In case of isl_bool, the result is converted to + * a Python boolean. + * In case of isl_size, the result is converted to a Python int. + */ +void python_generator::print_method_return(int indent, const isl_class &clazz, + FunctionDecl *method, const char *fmt) +{ + QualType return_type = method->getReturnType(); + + if (!is_static(clazz, method)) + print_persistent_callback_failure_check(indent, clazz, fmt); + + if (is_isl_type(return_type)) { + string type; + + type = type2python(extract_type(return_type)); + print_indent(indent, + "obj = %s(ctx=ctx, ptr=res)\n", type.c_str()); + if (is_mutator(clazz, method) && + clazz.has_persistent_callbacks()) + print_indent(indent, "obj.copy_callbacks(arg0)\n"); + if (clazz.persistent_callbacks.count(method)) { + string callback_name; + + callback_name = clazz.persistent_callback_name(method); + print_indent(indent, "obj.%s = { 'func': cb1, " + "'exc_info': exc_info }\n", + callback_name.c_str()); + } + print_indent(indent, "return obj\n"); + } else if (is_string(return_type)) { + print_indent(indent, "if res == 0:\n"); + print_indent(indent, " raise Error\n"); + print_indent(indent, "string = " + "cast(res, c_char_p).value.decode('ascii')\n"); + + if (gives(method)) + print_indent(indent, "libc.free(res)\n"); + + print_indent(indent, "return string\n"); + } else if (is_isl_neg_error(return_type)) { + print_indent(indent, "if res < 0:\n"); + print_indent(indent, " raise Error\n"); + if (is_isl_bool(return_type)) + print_indent(indent, "return bool(res)\n"); + else if (is_isl_size(return_type)) + print_indent(indent, "return int(res)\n"); + } else { + print_indent(indent, "return res\n"); + } +} + +/* Print a python "get" method corresponding to the C function "fd" + * in class "clazz" using a name that includes the "get_" prefix. + * + * This method simply calls the variant without the "get_" prefix and + * returns its result. + * Note that static methods are not considered to be "get" methods. + */ +void python_generator::print_get_method(const isl_class &clazz, + FunctionDecl *fd) +{ + string get_name = clazz.base_method_name(fd); + string name = clazz.method_name(fd); + int num_params = fd->getNumParams(); + + print_method_header(false, get_name, num_params); + printf(" return arg0.%s(", name.c_str()); + print_method_arguments(1, num_params); + printf(")\n"); +} + +/* Print a call to "method", along with the corresponding + * return statement, with the given indentation. + * "drop_ctx" is set if the first argument is an isl_ctx. + * + * A "ctx" variable is first initialized as it may be needed + * in the first call to print_arg_in_call and in print_method_return. + * + * If the method has any callback function, then any exception + * thrown in any callback also need to be rethrown. + */ +void python_generator::print_method_call(int indent, const isl_class &clazz, + FunctionDecl *method, const char *fmt, int drop_ctx) +{ + string fullname = method->getName().str(); + int num_params = method->getNumParams(); + int drop_user = 0; + + if (drop_ctx) { + print_indent(indent, "ctx = Context.getDefaultInstance()\n"); + } else { + print_indent(indent, "ctx = "); + printf(fmt, 0); + printf(".ctx\n"); + } + print_indent(indent, "res = isl.%s(", fullname.c_str()); + for (int i = 0; i < num_params; ++i) { + if (i > 0) + printf(", "); + print_arg_in_call(method, fmt, i, drop_ctx + drop_user); + if (!is_callback_arg(method, i)) + continue; + ++drop_user; + ++i; + printf(", None"); + } + printf(")\n"); + + if (drop_user > 0) + print_rethrow(indent, "exc_info[0]"); + + print_method_return(indent, clazz, method, fmt); +} + +/* Print a python method corresponding to the C function "method". + * "super" contains the superclasses of the class to which the method belongs, + * with the first element corresponding to the annotation that appears + * closest to the annotated type. This superclass is the least + * general extension of the annotated type in the linearization + * of the class hierarchy. + * + * If the first argument of "method" is something other than an instance + * of the class, then mark the python method as static. + * If, moreover, this first argument is an isl_ctx, then remove + * it from the arguments of the Python method. + * + * If the function has any callback arguments, then it also has corresponding + * "user" arguments. Since Python has closures, there is no need for such + * user arguments in the Python interface, so we simply drop them. + * We also create a wrapper ("cb{arg}") for each callback. + * + * If the function consumes a reference, then we pass it a copy of + * the actual argument. + * + * For methods that are identified as "get" methods, also + * print a variant of the method using a name that includes + * the "get_" prefix. + */ +void python_generator::print_method(const isl_class &clazz, + FunctionDecl *method, vector super) +{ + string cname = clazz.method_name(method); + int num_params = method->getNumParams(); + int drop_user = 0; + int drop_ctx = first_arg_is_isl_ctx(method); + + for (int i = 1; i < num_params; ++i) { + if (is_callback_arg(method, i)) + drop_user += 1; + } + + print_method_header(is_static(clazz, method), cname, + num_params - drop_ctx - drop_user); + + print_type_checks(cname, method, drop_ctx, + num_params, super); + drop_user = 0; + for (int i = 1; i < num_params; ++i) { + ParmVarDecl *param = method->getParamDecl(i); + QualType type = param->getOriginalType(); + if (!is_callback(type)) + continue; + print_callback(param, i - drop_ctx - drop_user); + drop_user += 1; + } + print_method_call(8, clazz, method, fixed_arg_fmt, drop_ctx); + + if (clazz.is_get_method(method)) + print_get_method(clazz, method); +} + +/* Print a condition that checks whether Python method argument "i" + * corresponds to the C function argument type "type". + */ +static void print_argument_check(QualType type, int i) +{ + if (generator::is_isl_type(type)) { + string type_str; + type_str = generator::extract_type(type); + type_str = type2python(type_str); + printf("args[%d].__class__ is %s", i, type_str.c_str()); + } else if (type->isPointerType()) { + printf("type(args[%d]) == str", i); + } else { + printf("type(args[%d]) == int", i); + } +} + +/* Is any element of "vector" set? + */ +static bool any(const std::vector &vector) +{ + return std::find(vector.begin(), vector.end(), true) != vector.end(); +} + +/* Print a test that checks whether the arguments passed + * to the Python method correspond to the arguments + * expected by "fd" and + * check if the object on which the method is called, if any, + * is of the right type. + * "drop_ctx" is set if the first argument of "fd" is an isl_ctx, + * which does not appear as an argument to the Python method. + * + * If an automatic conversion function is available for any + * of the argument types, then also allow the argument + * to be of the type as prescribed by the second input argument + * of the conversion function. + * The corresponding arguments are then converted to the expected types + * if needed. + * The object on which the method is called is also converted if needed. + * The argument tuple first needs to be converted to a list + * in order to be able to modify the entries. + */ +void python_generator::print_argument_checks(const isl_class &clazz, + FunctionDecl *fd, int drop_ctx) +{ + int num_params = fd->getNumParams(); + bool is_static = generator::is_static(clazz, fd); + int first = is_static ? drop_ctx : 1; + std::vector convert(num_params); + + printf(" if len(args) == %d", num_params - drop_ctx); + for (int i = first; i < num_params; ++i) { + ParmVarDecl *param = fd->getParamDecl(i); + QualType type = param->getOriginalType(); + const Type *ptr = type.getTypePtr(); + + printf(" and "); + if (conversions.count(ptr) == 0) { + print_argument_check(type, i - drop_ctx); + } else { + QualType type2 = conversions.at(ptr)->getOriginalType(); + convert[i] = true; + printf("("); + print_argument_check(type, i - drop_ctx); + printf(" or "); + print_argument_check(type2, i - drop_ctx); + printf(")"); + } + } + printf(":\n"); + + if (is_static && !any(convert)) + return; + print_indent(12, "args = list(args)\n"); + first = is_static ? drop_ctx : 0; + for (int i = first; i < num_params; ++i) { + bool is_self = !is_static && i == 0; + ParmVarDecl *param = fd->getParamDecl(i); + string type; + + if (!is_self && !convert[i]) + continue; + type = type2python(extract_type(param->getOriginalType())); + print_type_check(12, type, var_arg_fmt, + i - drop_ctx, false, "", "", -1); + } +} + +/* Print part of an overloaded python method corresponding to the C function + * "method". + * "drop_ctx" is set if the first argument of "method" is an isl_ctx. + * + * In particular, print code to test whether the arguments passed to + * the python method correspond to the arguments expected by "method" + * and to call "method" if they do. + */ +void python_generator::print_method_overload(const isl_class &clazz, + FunctionDecl *method) +{ + int drop_ctx = first_arg_is_isl_ctx(method); + + print_argument_checks(clazz, method, drop_ctx); + print_method_call(12, clazz, method, var_arg_fmt, drop_ctx); +} + +/* Print a python method with a name derived from "fullname" + * corresponding to the C functions "methods". + * "super" contains the superclasses of the class to which the method belongs. + * + * If "methods" consists of a single element that is not marked overloaded, + * the use print_method to print the method. + * Otherwise, print an overloaded method with pieces corresponding + * to each function in "methods". + */ +void python_generator::print_method(const isl_class &clazz, + const string &fullname, const function_set &methods, + vector super) +{ + string cname; + function_set::const_iterator it; + FunctionDecl *any_method; + + any_method = *methods.begin(); + if (methods.size() == 1 && !is_overload(any_method)) { + print_method(clazz, any_method, super); + return; + } + + cname = clazz.method_name(any_method); + + print_method_def(is_static(clazz, any_method), cname); + printf("(*args):\n"); + + for (it = methods.begin(); it != methods.end(); ++it) + print_method_overload(clazz, *it); + printf(" raise Error\n"); +} + +/* Print a python method "name" corresponding to "fd" setting + * the enum value "value". + * "super" contains the superclasses of the class to which the method belongs, + * with the first element corresponding to the annotation that appears + * closest to the annotated type. + * + * The last argument of the C function does not appear in the method call, + * but is fixed to "value" instead. + * Other than that, the method printed here is similar to one + * printed by python_generator::print_method, except that + * some of the special cases do not occur. + */ +void python_generator::print_set_enum(const isl_class &clazz, + FunctionDecl *fd, int value, const string &name, + const vector &super) +{ + string fullname = fd->getName().str(); + int num_params = fd->getNumParams(); + + print_method_header(is_static(clazz, fd), name, num_params - 1); + + print_type_checks(name, fd, false, num_params - 1, super); + printf(" ctx = arg0.ctx\n"); + printf(" res = isl.%s(", fullname.c_str()); + for (int i = 0; i < num_params - 1; ++i) { + if (i) + printf(", "); + print_arg_in_call(fd, fixed_arg_fmt, i, 0); + } + printf(", %d", value); + printf(")\n"); + print_method_return(8, clazz, fd, fixed_arg_fmt); +} + +/* Print python methods corresponding to "fd", which sets an enum. + * "super" contains the superclasses of the class to which the method belongs, + * with the first element corresponding to the annotation that appears + * closest to the annotated type. + * + * A method is generated for each value in the enum, setting + * the enum to that value. + */ +void python_generator::print_set_enum(const isl_class &clazz, + FunctionDecl *fd, const vector &super) +{ + vector::const_iterator it; + const vector &set_enums = clazz.set_enums.at(fd); + + for (it = set_enums.begin(); it != set_enums.end(); ++it) + print_set_enum(clazz, fd, it->value, it->method_name, super); +} + +/* Print part of the constructor for this isl_class. + * + * In particular, check if the actual arguments correspond to the + * formal arguments of "cons" and if so call "cons" and put the + * result in self.ptr and a reference to the default context in self.ctx. + */ +void python_generator::print_constructor(const isl_class &clazz, + FunctionDecl *cons) +{ + string fullname = cons->getName().str(); + string cname = clazz.method_name(cons); + int num_params = cons->getNumParams(); + int drop_ctx = first_arg_is_isl_ctx(cons); + + print_argument_checks(clazz, cons, drop_ctx); + printf(" self.ctx = Context.getDefaultInstance()\n"); + printf(" self.ptr = isl.%s(", fullname.c_str()); + if (drop_ctx) + printf("self.ctx"); + for (int i = drop_ctx; i < num_params; ++i) { + if (i) + printf(", "); + print_arg_in_call(cons, var_arg_fmt, i, drop_ctx); + } + printf(")\n"); + printf(" return\n"); +} + +/* The definition of the part of constructor for the "id" class + * that construct an object from a name and a user object, + * without the initial newline. + * + * Just like the parts generated by python_generator::print_constructor, + * the result of the isl_id_alloc call is stored in self.ptr and + * a reference to the default context is stored in self.ctx. + * Also, just like any other constructor or method with a string argument, + * the python string is first encoded as a byte sequence, + * using 'ascii' as encoding. + * + * Since the isl_id keeps a reference to the Python user object, + * the reference count of the Python object needs to be incremented, + * but only if the construction of the isl_id is successful. + * The reference count of the Python object is decremented again + * by Context.free_user when the reference count of the isl_id + * drops to zero. + */ +static const char *const id_constructor_user = &R"( + if len(args) == 2 and type(args[0]) == str: + self.ctx = Context.getDefaultInstance() + name = args[0].encode('ascii') + self.ptr = isl.isl_id_alloc(self.ctx, name, args[1]) + self.ptr = isl.isl_id_set_free_user(self.ptr, Context.free_user) + if self.ptr is not None: + pythonapi.Py_IncRef(py_object(args[1])) + return +)"[1]; + +/* Print any special constructor parts of this class that are not + * automatically derived from the C interface. + * + * In particular, print a special constructor part for the "id" class. + */ +void python_generator::print_special_constructors(const isl_class &clazz) +{ + if (clazz.name != "isl_id") + return; + + printf("%s", id_constructor_user); +} + +/* The definition of an "id" method + * for retrieving the user object associated to the identifier, + * without the initial newline. + * + * The isl_id needs to have been created by the constructor + * in id_constructor_user. That is, it needs to have a user pointer and + * it needs to have its free_user callback set to Context.free_user. + * The functions need to be cast to c_void_p to be able to compare + * the addresses. + * + * Return None if any of the checks fail. + * Note that isl_id_get_user returning NULL automatically results in None. + */ +static const char *const id_user = &R"( + def user(self): + free_user = cast(Context.free_user, c_void_p) + id_free_user = cast(isl.isl_id_get_free_user(self.ptr), c_void_p) + if id_free_user.value != free_user.value: + return None + return isl.isl_id_get_user(self.ptr) +)"[1]; + +/* Print any special methods of this class that are not + * automatically derived from the C interface. + * + * In particular, print a special method for the "id" class. + */ +void python_generator::print_special_methods(const isl_class &clazz) +{ + if (clazz.name != "isl_id") + return; + + printf("%s", id_user); +} + +/* If "clazz" has a type function describing subclasses, + * then add constructors that allow each of these subclasses + * to be treated as an object to the superclass. + */ +void python_generator::print_upcast_constructors(const isl_class &clazz) +{ + map::const_iterator i; + + if (!clazz.fn_type) + return; + + for (i = clazz.type_subclasses.begin(); + i != clazz.type_subclasses.end(); ++i) { + printf(" if len(args) == 1 and " + "isinstance(args[0], %s):\n", + type2python(i->second).c_str()); + printf(" self.ctx = args[0].ctx\n"); + printf(" self.ptr = isl.%s_copy(args[0].ptr)\n", + clazz.name.c_str()); + printf(" return\n"); + } +} + +/* Print the header of the class "name" with superclasses "super". + * The order of the superclasses is the opposite of the order + * in which the corresponding annotations appear in the source code. + * If "clazz" is a subclass derived from a type function, + * then the immediate superclass is recorded in "clazz" itself. + */ +void python_generator::print_class_header(const isl_class &clazz, + const string &name, const vector &super) +{ + printf("class %s", name.c_str()); + if (super.size() > 0) { + printf("("); + for (unsigned i = 0; i < super.size(); ++i) { + if (i > 0) + printf(", "); + printf("%s", type2python(super[i]).c_str()); + } + printf(")"); + } else if (clazz.is_type_subclass()) { + printf("(%s)", type2python(clazz.superclass_name).c_str()); + } else { + printf("(object)"); + } + printf(":\n"); +} + +/* Tell ctypes about the return type of "fd". + * In particular, if "fd" returns a pointer to an isl object, + * then tell ctypes it returns a "c_void_p". + * If "fd" returns a char *, then simply tell ctypes. + * + * Nothing needs to be done for functions returning + * isl_bool, isl_stat or isl_size since they are represented by an int and + * ctypes assumes that a function returns int by default. + */ +void python_generator::print_restype(FunctionDecl *fd) +{ + string fullname = fd->getName().str(); + QualType type = fd->getReturnType(); + if (is_isl_type(type)) + printf("isl.%s.restype = c_void_p\n", fullname.c_str()); + else if (is_string(type)) + printf("isl.%s.restype = POINTER(c_char)\n", fullname.c_str()); +} + +/* Tell ctypes about the types of the arguments of the function "fd". + * + * Any callback argument is followed by a user pointer argument. + * Each such pair or arguments is handled together. + */ +void python_generator::print_argtypes(FunctionDecl *fd) +{ + string fullname = fd->getName().str(); + int n = fd->getNumParams(); + + printf("isl.%s.argtypes = [", fullname.c_str()); + for (int i = 0; i < n; ++i) { + ParmVarDecl *param = fd->getParamDecl(i); + QualType type = param->getOriginalType(); + if (i) + printf(", "); + if (is_isl_ctx(type)) + printf("Context"); + else if (is_isl_type(type)) + printf("c_void_p"); + else if (is_callback(type)) + printf("c_void_p, c_void_p"); + else if (is_string(type)) + printf("c_char_p"); + else if (is_long(type)) + printf("c_long"); + else + printf("c_int"); + + if (is_callback(type)) + ++i; + } + printf("]\n"); +} + +/* Print type definitions for the method 'fd'. + */ +void python_generator::print_method_type(FunctionDecl *fd) +{ + print_restype(fd); + print_argtypes(fd); +} + +/* If "clazz" has a type function describing subclasses or + * if it is one of those type subclasses, then print a __new__ method. + * + * In the superclass, the __new__ method constructs an object + * of the subclass type specified by the type function, + * raising an error on an error type. + * In the subclass, the __new__ method reverts to the original behavior. + */ +void python_generator::print_new(const isl_class &clazz, + const string &python_name) +{ + if (!clazz.fn_type && !clazz.is_type_subclass()) + return; + + printf(" def __new__(cls, *args, **keywords):\n"); + + if (clazz.fn_type) { + map::const_iterator i; + + printf(" if \"ptr\" in keywords:\n"); + printf(" type = isl.%s(keywords[\"ptr\"])\n", + clazz.fn_type->getNameAsString().c_str()); + + for (i = clazz.type_subclasses.begin(); + i != clazz.type_subclasses.end(); ++i) { + printf(" if type == %d:\n", i->first); + printf(" return %s(**keywords)\n", + type2python(i->second).c_str()); + } + printf(" raise Error\n"); + } + + printf(" return super(%s, cls).__new__(cls)\n", + python_name.c_str()); +} + +/* Print declarations for methods printing the class representation, + * provided there is a corresponding *_to_str function. + * + * In particular, provide an implementation of __str__ and __repr__ methods to + * override the default representation used by python. Python uses __str__ to + * pretty print the class (e.g., when calling print(obj)) and uses __repr__ + * when printing a precise representation of an object (e.g., when dumping it + * in the REPL console). + * + * Check the type of the argument before calling the *_to_str function + * on it in case the method was called on an object from a subclass. + * + * The return value of the *_to_str function is decoded to a python string + * assuming an 'ascii' encoding. This is necessary for python 3 compatibility. + */ +void python_generator::print_representation(const isl_class &clazz, + const string &python_name) +{ + if (!clazz.fn_to_str) + return; + + printf(" def __str__(arg0):\n"); + print_type_check(8, python_name, fixed_arg_fmt, 0, false, "", "", -1); + printf(" ptr = isl.%s(arg0.ptr)\n", + string(clazz.fn_to_str->getName()).c_str()); + printf(" res = cast(ptr, c_char_p).value.decode('ascii')\n"); + printf(" libc.free(ptr)\n"); + printf(" return res\n"); + printf(" def __repr__(self):\n"); + printf(" s = str(self)\n"); + printf(" if '\"' in s:\n"); + printf(" return 'isl.%s(\"\"\"%%s\"\"\")' %% s\n", + python_name.c_str()); + printf(" else:\n"); + printf(" return 'isl.%s(\"%%s\")' %% s\n", + python_name.c_str()); +} + +/* If "clazz" has any persistent callbacks, then print the definition + * of a "copy_callbacks" function that copies the persistent callbacks + * from one object to another. + */ +void python_generator::print_copy_callbacks(const isl_class &clazz) +{ + const set &callbacks = clazz.persistent_callbacks; + set::const_iterator in; + + if (!clazz.has_persistent_callbacks()) + return; + + printf(" def copy_callbacks(self, obj):\n"); + for (in = callbacks.begin(); in != callbacks.end(); ++in) { + string callback_name = clazz.persistent_callback_name(*in); + + printf(" if hasattr(obj, '%s'):\n", + callback_name.c_str()); + printf(" self.%s = obj.%s\n", + callback_name.c_str(), callback_name.c_str()); + } +} + +/* Print code to set method type signatures. + * + * To be able to call C functions it is necessary to explicitly set their + * argument and result types. Do this for all exported constructors and + * methods (including those that set a persistent callback and + * those that set an enum value), + * as well as for the *_to_str and the type function, if they exist. + * Assuming each exported class has a *_copy and a *_free method, + * also unconditionally set the type of such methods. + */ +void python_generator::print_method_types(const isl_class &clazz) +{ + function_set::const_iterator in; + map::const_iterator it; + map >::const_iterator ie; + const set &callbacks = clazz.persistent_callbacks; + + for (in = clazz.constructors.begin(); in != clazz.constructors.end(); + ++in) + print_method_type(*in); + + for (in = callbacks.begin(); in != callbacks.end(); ++in) + print_method_type(*in); + for (it = clazz.methods.begin(); it != clazz.methods.end(); ++it) + for (in = it->second.begin(); in != it->second.end(); ++in) + print_method_type(*in); + for (ie = clazz.set_enums.begin(); ie != clazz.set_enums.end(); ++ie) + print_method_type(ie->first); + + print_method_type(clazz.fn_copy); + print_method_type(clazz.fn_free); + if (clazz.fn_to_str) + print_method_type(clazz.fn_to_str); + if (clazz.fn_type) + print_method_type(clazz.fn_type); +} + +/* Print out the definition of this isl_class. + * + * We first check if this isl_class is a subclass of one or more other classes. + * If it is, we make sure those superclasses are printed out first. + * + * Then we print a constructor with several cases, one for constructing + * a Python object from a return value, one for each function that + * was marked as a constructor, a class specific constructor, if any, and + * one for each type based subclass. + * + * Next, we print out some common methods, class specific methods and + * the methods corresponding + * to functions that are not marked as constructors, including those + * that set a persistent callback and those that set an enum value. + * + * Finally, we tell ctypes about the types of the arguments of the + * constructor functions and the return types of those function returning + * an isl object. + */ +void python_generator::print(const isl_class &clazz) +{ + string p_name = type2python(clazz.subclass_name); + vector super = find_superclasses(clazz.type); + const set &callbacks = clazz.persistent_callbacks; + + for (unsigned i = 0; i < super.size(); ++i) + if (done.find(super[i]) == done.end()) + print(classes[super[i]]); + if (clazz.is_type_subclass() && done.find(clazz.name) == done.end()) + print(classes[clazz.name]); + done.insert(clazz.subclass_name); + + printf("\n"); + print_class_header(clazz, p_name, super); + printf(" def __init__(self, *args, **keywords):\n"); + + printf(" if \"ptr\" in keywords:\n"); + printf(" self.ctx = keywords[\"ctx\"]\n"); + printf(" self.ptr = keywords[\"ptr\"]\n"); + printf(" return\n"); + + for (const auto &cons : clazz.constructors) + print_constructor(clazz, cons); + print_special_constructors(clazz); + print_upcast_constructors(clazz); + printf(" raise Error\n"); + printf(" def __del__(self):\n"); + printf(" if hasattr(self, 'ptr'):\n"); + printf(" isl.%s_free(self.ptr)\n", clazz.name.c_str()); + + print_new(clazz, p_name); + print_representation(clazz, p_name); + print_copy_callbacks(clazz); + + print_special_methods(clazz); + for (const auto &callback : callbacks) + print_method(clazz, callback, super); + for (const auto &kvp : clazz.methods) + print_method(clazz, kvp.first, kvp.second, super); + for (const auto &kvp : clazz.set_enums) + print_set_enum(clazz, kvp.first, super); + + printf("\n"); + + print_method_types(clazz); +} + +/* Generate a python interface based on the extracted types and + * functions. + * + * Print out each class in turn. If one of these is a subclass of some + * other class, make sure the superclass is printed out first. + * functions. + */ +void python_generator::generate() +{ + map::iterator ci; + + for (ci = classes.begin(); ci != classes.end(); ++ci) { + if (done.find(ci->first) == done.end()) + print(ci->second); + } +} diff --git a/external/mit/isl/dist/interface/python.h b/external/mit/isl/dist/interface/python.h new file mode 100644 index 000000000000..87d5caeefd0f --- /dev/null +++ b/external/mit/isl/dist/interface/python.h @@ -0,0 +1,68 @@ +#include +#include +#include "generator.h" + +using namespace std; +using namespace clang; + +class python_generator : public generator { +private: + set done; + +public: + python_generator(SourceManager &SM, set &exported_types, + set exported_functions, + set functions) : + generator(SM, exported_types, exported_functions, functions) {} + + virtual void generate(); + +private: + void print(const isl_class &clazz); + void print_method_arguments(int first, int n_arg); + void print_method_header(bool is_static, const string &name, int n_arg); + void print_class_header(const isl_class &clazz, const string &name, + const vector &super); + void print_type_check(int indent, const string &type, const char *fmt, + int pos, bool upcast, const string &super, + const string &name, int n); + void print_type_checks(const string &cname, FunctionDecl *method, + bool first_is_ctx, int n, const vector &super); + void print_copy(QualType type); + void print_callback(ParmVarDecl *param, int arg); + void print_arg_in_call(FunctionDecl *fd, const char *fmt, int arg, + int skip); + void print_argtypes(FunctionDecl *fd); + void print_method_return(int indent, const isl_class &clazz, + FunctionDecl *method, const char *fmt); + void print_restype(FunctionDecl *fd); + void print(map &classes, set &done); + void print_constructor(const isl_class &clazz, FunctionDecl *method); + void print_special_constructors(const isl_class &clazz); + void print_special_methods(const isl_class &clazz); + void print_upcast_constructors(const isl_class &clazz); + void print_new(const isl_class &clazz, + const string &python_name); + void print_representation(const isl_class &clazz, + const string &python_name); + void print_copy_callbacks(const isl_class &clazz); + void print_method_type(FunctionDecl *fd); + void print_method_types(const isl_class &clazz); + void print_get_method(const isl_class &clazz, FunctionDecl *fd); + void print_method(const isl_class &clazz, FunctionDecl *method, + vector super); + void print_method_call(int indent, const isl_class &clazz, + FunctionDecl *method, const char *fmt, + int drop_ctx); + void print_argument_checks(const isl_class &clazz, FunctionDecl *fd, + int drop_ctx); + void print_method_overload(const isl_class &clazz, + FunctionDecl *method); + void print_method(const isl_class &clazz, const string &fullname, + const function_set &methods, vector super); + void print_set_enum(const isl_class &clazz, FunctionDecl *fd, + int value, const string &name, const vector &super); + void print_set_enum(const isl_class &clazz, FunctionDecl *fd, + const vector &super); + +}; diff --git a/external/mit/isl/dist/interface/set_lang_defaults_arg4.h b/external/mit/isl/dist/interface/set_lang_defaults_arg4.h new file mode 100644 index 000000000000..82af7ff655b6 --- /dev/null +++ b/external/mit/isl/dist/interface/set_lang_defaults_arg4.h @@ -0,0 +1,16 @@ +#include +#include + +#include + +/* Convert a clang::PreprocessorOptions to the fourth argument + * of CompilerInvocation::setLangDefaults, which may be either + * a clang::PreprocessorOptions itself or its Includes. + */ +struct setLangDefaultsArg4 { + setLangDefaultsArg4(clang::PreprocessorOptions &PO) : PO(PO) {} + operator clang::PreprocessorOptions &() { return PO; } + operator std::vector &() { return PO.Includes; } + + clang::PreprocessorOptions &PO; +}; diff --git a/external/mit/isl/dist/interface/template_cpp.cc b/external/mit/isl/dist/interface/template_cpp.cc new file mode 100644 index 000000000000..b62e3b5cce01 --- /dev/null +++ b/external/mit/isl/dist/interface/template_cpp.cc @@ -0,0 +1,2984 @@ +/* + * Copyright 2020 Cerebras Systems. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY CEREBRAS SYSTEMS ''AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL CEREBRAS SYSTEMS OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation + * are those of the authors and should not be interpreted as + * representing official policies, either expressed or implied, of + * Cerebras Systems. + */ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "template_cpp.h" +#include "isl_config.h" + +/* The textual representation of this tuple kind. + * + * By default, the textual representation is just the name. + */ +std::string TupleKind::to_string() const +{ + return name; +} + +/* Return the parameters of this tuple kind. + * + * By default, there are no parameters. + */ +std::vector TupleKind::params() const +{ + return { }; +} + +/* Apply the substitution "subs" to this tuple kind and return the result. + * "self" is a shared pointer to this. + * + * If the name of this tuple kind appears in the substitution, + * then return the corresponding tuple kind pointer. + * Otherwise, return "self". + */ +TupleKindPtr TupleKind::apply(const Substitution &subs, + const TupleKindPtr &self) const +{ + if (subs.count(name) != 0) + return subs.at(name); + return self; +} + +/* Apply the substitution "subs" to "tuple" and return the result. + */ +static TupleKindPtr apply(const TupleKindPtr tuple, const Substitution &subs) +{ + return tuple->apply(subs, tuple); +} + +/* Return the left child of this tuple kind. + * + * Since this is not a pair, there is no left child. + */ +TupleKindPtr TupleKind::left() const +{ + return TupleKindPtr(); +} + +/* Return the right child of this tuple kind. + * + * Since this is not a pair, there is no right child. + */ +TupleKindPtr TupleKind::right() const +{ + return TupleKindPtr(); +} + +/* Helper class used to construct a pointer to a tuple kind + * that refers to a non-template type. + */ +struct Fixed { +}; + +/* Construct a pointer to a tuple kind that refers to a non-template type. + * + * Use an empty string as name. Since this is a non-template type, + * the kind name will never appear in the generated code. + */ +TupleKindPtr::TupleKindPtr(Fixed) : Base(std::make_shared("")) +{ +} + +/* Tuple pointers for non-template types. + */ +static TupleKindPtr Ctx{Fixed()}; +static TupleKindPtr Integer{Fixed()}; +static TupleKindPtr Str{Fixed()}; +static TupleKindPtr Res{Fixed()}; + +/* Special tuple pointers. + * Anonymous appears in the generated code but cannot be unified + * with anything else since it is a predefined template argument. + * Leaf can only be unified with something that is not a pair and + * does not appear in the generated code. + */ +static TupleKindPtr Anonymous("Anonymous"); +static TupleKindPtr Leaf("Leaf"); + +/* Placeholder tuple pointers that refer to (part of) the domain or range. + */ +static TupleKindPtr Domain("Domain"); +static TupleKindPtr Domain2("Domain2"); +static TupleKindPtr Domain3("Domain3"); +static TupleKindPtr Range("Range"); +static TupleKindPtr Range2("Range2"); +static TupleKindPtr Range3("Range3"); + +/* A representation of a proper tuple kind that is used as a template + * parameter or a template argument. + */ +struct ProperTupleKind : public TupleKind { + ProperTupleKind(const std::string &name) : TupleKind(name) {} + + virtual std::vector params() const override; +}; + +/* Return the parameters of this tuple kind. + * + * Return the name of this tuple kind, unless it is the special Anonymous + * predefined template argument. + */ +std::vector ProperTupleKind::params() const +{ + if (Anonymous.get() == this) + return { }; + return { name }; +} + +/* Construct a pointer to a tuple kind that refers + * to a proper tuple kind with the given name. + */ +TupleKindPtr::TupleKindPtr(const std::string &name) : + Base(std::make_shared(name)) +{ +} + +/* A tuple kind that represents an anonymous pair of nested tuple kinds. + */ +struct Pair : public TupleKind { + Pair(const TupleKindPtr &tuple1, const TupleKindPtr &tuple2) : + TupleKind(""), tuple1(tuple1), tuple2(tuple2) {} + + virtual std::string to_string() const override; + virtual std::vector params() const override; + virtual TupleKindPtr apply(const Substitution &match, + const TupleKindPtr &self) const override; + virtual TupleKindPtr left() const override; + virtual TupleKindPtr right() const override; + + const TupleKindPtr tuple1; + const TupleKindPtr tuple2; +}; + +/* The textual representation of this tuple kind. + * + * The textual representation of a pair is of the form "pair". + */ +std::string Pair::to_string() const +{ + return std::string("pair<") + tuple1->to_string() + ", " + + tuple2->to_string() + ">"; +} + +/* Add the elements of "vec2" that do not already appear in "vec1" + * at the end of "vec1". + * + * The two vectors are assumed not to have any repeated elements. + * The updated vector will then also not have repeated elements. + */ +static void combine(std::vector &vec1, + const std::vector &vec2) +{ + for (const auto &s : vec2) + if (std::find(vec1.begin(), vec1.end(), s) == vec1.end()) + vec1.emplace_back(s); +} + +/* Return the parameters of this tuple kind. + * + * Combine the parameters of the two nested tuple kinds. + */ +std::vector Pair::params() const +{ + auto names1 = tuple1->params(); + auto names2 = tuple2->params(); + + combine(names1, names2); + + return names1; +} + +/* Apply the substitution "subs" to this tuple kind and return the result. + * "self" is a shared pointer to this. + * + * Construct a new tuple kind consisting of the result of applying + * the substitution to the two nested tuple kinds. + */ +TupleKindPtr Pair::apply(const Substitution &subs, const TupleKindPtr &self) + const +{ + return TupleKindPtr(::apply(tuple1, subs), ::apply(tuple2, subs)); +} + +/* Return the left child of this tuple kind. + */ +TupleKindPtr Pair::left() const +{ + return tuple1; +} + +/* Return the right child of this tuple kind. + */ +TupleKindPtr Pair::right() const +{ + return tuple2; +} + +/* Construct a pointer to a tuple kind that refers + * to the given pair of nested tuple kinds. + */ +TupleKindPtr::TupleKindPtr(const TupleKindPtr &left, const TupleKindPtr &right) + : Base(std::make_shared(left, right)) +{ +} + +/* Is this a kind of object representing an anonymous function? + */ +bool Kind::is_anon() const +{ + return size() != 0 && back() == Anonymous; +} + +/* Is this a kind of object with a single tuple? + */ +bool Kind::is_set() const +{ + return size() == 1; +} + +/* Is this a kind of object with a single, anonymous tuple? + */ +bool Kind::is_anon_set() const +{ + return is_set() && is_anon(); +} + +/* Return the parameters of this kind. + * + * Collect the parameters of the tuple kinds in the sequence. + */ +std::vector Kind::params() const +{ + std::vector params; + + for (const auto &tuple : *this) + combine(params, tuple->params()); + + return params; +} + +/* Apply the substitution "subs" to this kind and return the result. + * + * Apply the substitution to each of the tuple kinds in the sequence. + */ +Kind Kind::apply(const Substitution &subs) const +{ + Kind applied; + + for (const auto &tuple : *this) + applied.emplace_back(::apply(tuple, subs)); + + return applied; +} + +/* A signature of a method in terms of kinds, + * consisting of a return kind and a sequence of argument kinds. + */ +struct Signature { + Kind ret; + std::vector args; + + std::vector params() const; + Signature apply(const Substitution &match) const; +}; + +/* Return the parameters of this signature. + * + * Collect the parameters of the argument kinds and the return kind. + */ +std::vector Signature::params() const +{ + std::vector params; + + for (const auto &arg : args) + combine(params, arg.params()); + combine(params, ret.params()); + + return params; +} + +/* Apply the substitution "subs" to this kind and return the result. + * + * Apply the substitution to the argument kinds and the return kind. + */ +Signature Signature::apply(const Substitution &subs) const +{ + std::vector applied_args; + + for (const auto &arg : args) + applied_args.emplace_back(arg.apply(subs)); + + return { ret.apply(subs), applied_args }; +} + +/* Return a renaming substitution that renames the elements of "params" + * using names starting with "prefix". + */ +static Substitution param_renamer(const std::vector ¶ms, + const std::string &prefix) +{ + Substitution renamer; + int n = 0; + + for (const auto &name : params) { + auto suffix = std::to_string(++n); + auto arg_name = prefix + suffix; + auto arg = TupleKindPtr(arg_name); + + if (name == Leaf->name) + generator::die("Leaf cannot be renamed"); + + renamer.emplace(name, arg); + } + + return renamer; +} + +/* Does the vector "v" contain the element "el"? + */ +static bool contains(const std::vector &v, const std::string &el) +{ + return find(v.begin(), v.end(), el) != v.end(); + } + + +/* Return the shared elements of "v1" and "v2", preserving the order + * of those elements in "v1". + */ +static std::vector intersect(const std::vector &v1, + const std::vector &v2) +{ + std::vector intersection; + + for (const auto &el : v1) + if (contains(v2, el)) + intersection.push_back(el); + + return intersection; +} + +/* Return a renaming substitution that renames + * any parameters that appears in both "sig" and "kind". + */ +static Substitution shared_param_renamer(const Signature &sig, const Kind &kind) +{ + return param_renamer(intersect(sig.params(), kind.params()), "Arg"); +} + +/* Signatures for unary operations. + * Functions have at least one tuple. + */ +static Signature un_params = { { }, { { } } }; +static Signature un_set = { { Domain }, { { Domain } } }; +static Signature un_map = { { Domain, Range }, { { Domain, Range } } }; +static std::vector un_op = { un_params, un_set, un_map }; +static std::vector fn_un_op = { un_set, un_map }; + +/* Signatures for binary operations, with the second argument + * possibly referring to part of the first argument. + * Functions have at least one tuple. + */ +static Signature bin_params = { { }, { { }, { } } }; +static Signature bin_set = { { Domain }, { { Domain }, { Domain } } }; +static Signature bin_map = + { { Domain, Range }, { { Domain, Range }, { Domain, Range } } }; +static std::vector bin_op = { bin_params, bin_set, bin_map }; +static std::vector fn_bin_op = { bin_set, bin_map }; +static Signature bin_set_params = { { Domain }, { { Domain }, { } } }; +static Signature bin_map_params = + { { Domain, Range }, { { Domain, Range }, { } } }; +static Signature bin_map_domain = + { { Domain, Range }, { { Domain, Range }, { Domain } } }; +static Signature bin_map_range = + { { Domain, Range }, { { Domain, Range }, { Range } } }; +static Signature bin_map_domain_wrapped_domain = + { { { Domain, Domain2 }, Range }, + { { { Domain, Domain2 }, Range }, { Domain } } }; +static Signature bin_map_range_wrapped_domain = + { { Domain, { Range, Range2 } }, + { { Domain, { Range, Range2 } }, { Range } } }; + +/* Signatures for binary operations, where the second argument + * is an identifier (with an anonymous tuple). + */ +static Signature bin_params_anon = { { }, { { }, { Anonymous } } }; +static Signature bin_set_anon = { { Domain }, { { Domain }, { Anonymous } } }; +static Signature bin_map_anon = + { { Domain, Range }, { { Domain, Range }, { Anonymous } } }; +static std::vector bin_op_anon = + { bin_params_anon, bin_set_anon, bin_map_anon }; + +/* Signatures for ternary operations, where the last two arguments are integers. + */ +static Signature ter_params_int_int = + { { }, { { }, { Integer }, { Integer } } }; +static Signature ter_set_int_int = + { { Domain }, { { Domain }, { Integer }, { Integer } } }; +static Signature ter_map_int_int = + { { Domain, Range }, { { Domain, Range }, { Integer }, { Integer } } }; +static std::vector ter_int_int = + { ter_params_int_int, ter_set_int_int, ter_map_int_int }; + +/* Signatures for ternary operations. + * Functions have at least one tuple. + */ +static Signature ter_set = + { { Domain }, { { Domain }, { Domain }, { Domain } } }; +static Signature ter_map = + { { Domain, Range }, + { { Domain, Range }, { Domain, Range }, { Domain, Range } } }; +static std::vector fn_ter_op = { ter_set, ter_map }; + +/* Signatures for naming a leaf tuple using an identifier (with an anonymous + * tuple). + */ +static Signature update_set = { { Domain2 }, { { Leaf }, { Anonymous } } }; +static Signature update_domain = + { { Domain2, Range }, { { Leaf, Range }, { Anonymous } } }; +static Signature update_range = + { { Domain, Range2 }, { { Domain, Leaf }, { Anonymous } } }; + +/* Signatures for the functions "min" and "max", which can be either + * unary or binary operations. + */ +static std::vector min_max = { un_set, bin_set, un_map, bin_map }; + +/* Signatures for adding an unnamed tuple to an object with zero or one tuple. + */ +static Signature to_set = { { Domain }, { { }, { Integer } } }; +static Signature add_range = { { Domain, Range }, { { Domain }, { Integer } } }; +/* Signatures for adding a named tuple to an object with zero or one tuple. + */ +static Signature to_set_named = + { { Domain }, { { }, { Anonymous }, { Integer } } }; +static Signature add_range_named = + { { Domain, Range }, { { Domain }, { Anonymous }, { Integer } } }; + +/* Signatures for methods applying a map to a set, a function or + * part of a map. + */ +static Signature set_forward = { { Range }, { { Domain }, { Domain, Range } } }; +static Signature domain_forward = + { { Domain2, Range }, { { Domain, Range }, { Domain, Domain2 } } }; +static Signature range_forward = + { { Domain, Range2 }, { { Domain, Range }, { Range, Range2 } } }; + +/* Signatures for methods plugging in a function into a set, a function or + * part of a map. + */ +static Signature set_backward = + { { Domain2 }, { { Domain }, { Domain2, Domain } } }; +static Signature domain_backward = + { { Domain2, Range }, { { Domain, Range }, { Domain2, Domain } } }; +static Signature range_backward = + { { Domain, Range2 }, { { Domain, Range }, { Range2, Range } } }; +static Signature domain_wrapped_domain_backward = + { { { Domain3, Domain2 }, Range }, + { { { Domain, Domain2 }, Range }, { Domain3, Domain } } }; + +/* Signatures for methods binding a set, a function, + * or (part of) a map to parameters or an object of the same kind. + */ +static Signature bind_set = { { }, { { Domain }, { Domain } } }; +static Signature bind_domain = { { Range }, { { Domain, Range }, { Domain } } }; +static Signature bind_range = { { Domain }, { { Domain, Range }, { Range } } }; +static Signature bind_domain_wrapped_domain = + { { Range2, Range }, { { { Domain2, Range2 }, Range }, { Domain2 } } }; + +/* Signatures for functions that take a callback accepting + * objects of the same kind (but a different type). + * + * The return and argument kinds of the callback appear + * at the position of the callback. + */ +static Signature each_params = { { Res }, { { }, { Res }, { } } }; +static Signature each_set = { { Res }, { { Domain }, { Res }, { Domain } } }; +static Signature each_map = + { { Res }, { { Domain, Range }, { Res }, { Domain, Range } } }; +static std::vector each = { each_params, each_set, each_map }; + +/* Signatures for isl_*_list_foreach_scc. + * + * The first callback takes two elements with the same tuple kinds. + * The second callback takes a list with the same tuple kinds. + */ +static Signature each_scc_params = + { { Res }, { { }, { Res }, { }, { }, { Res }, { } } }; +static Signature each_scc_set = + { { Res }, { { Domain }, + { Res }, { Domain }, { Domain }, + { Res }, { Domain } } }; +static Signature each_scc_map = + { { Res }, { { Domain, Range }, + { Res }, { Domain, Range }, { Domain, Range }, + { Res }, { Domain, Range } } }; +static std::vector each_scc = + { each_scc_params, each_scc_set, each_scc_map }; + +/* Signature for creating a map from a range, + * where the domain is given by an extra argument. + */ +static Signature map_from_range_and_domain = + { { Domain, Range }, { { Range }, { Domain } } }; + + +/* Signatures for creating a set from a parameter set or + * a map from a domain, + * where the domain/range is given by an extra argument. + */ +static Signature set_from_params = { { Domain }, { { }, { Domain } } }; +static Signature map_from_domain_and_range = + { { Domain, Range }, { { Domain }, { Range } } }; +static std::vector from_domain = + { set_from_params, map_from_domain_and_range }; + +/* Signatures for creating an anonymous set from a parameter set + * or a map from a domain, where the range is anonymous. + */ +static Signature anonymous_set_from_params = { { Anonymous }, { { } } }; +static Signature anonymous_map_from_domain = + { { Domain, Anonymous }, { { Domain } } }; +static std::vector anonymous_from_domain = + { anonymous_set_from_params, anonymous_map_from_domain }; + +/* Signatures for creating an anonymous function from a domain, + * where the second argument is an identifier (with an anonymous tuple). + */ +static Signature anonymous_set_from_params_bin_anon = + { { Anonymous }, { { }, { Anonymous } } }; +static Signature anonymous_map_from_domain_bin_anon = + { { Domain, Anonymous }, { { Domain }, { Anonymous } } }; +static std::vector anonymous_from_domain_bin_anon = { + anonymous_set_from_params_bin_anon, + anonymous_map_from_domain_bin_anon + }; + +/* Signature for creating a map from a domain, + * where the range tuple is equal to the domain tuple. + */ +static Signature set_to_map = { { Domain, Domain }, { { Domain } } }; + +/* Signatures for obtaining the range or the domain of a map. + * In case of a transformation, the domain and range are the same. + */ +static Signature domain = { { Domain }, { { Domain, Range } } }; +static Signature range = { { Range }, { { Domain, Range } } }; +static Signature transformation_domain = { { Domain }, { { Domain, Domain } } }; + +/* Signatures for obtaining the parameter domain of a set or map. + */ +static Signature set_params = { { }, { { Domain } } }; +static Signature map_params = { { }, { { Domain, Range } } }; + +/* Signatures for obtaining the domain of a function. + */ +static std::vector fn_domain = { domain, set_params }; + +/* Signatures for interchanging (wrapped) domain and range. + */ +static Signature set_reverse = + { { { Range, Domain } }, { { { Domain, Range } } } }; +static Signature map_reverse = { { Range, Domain }, { { Domain, Range } } }; +static Signature map_domain_reverse = + { { { Domain2, Domain }, Range }, { { { Domain, Domain2 }, Range } } }; +static Signature map_range_reverse = + { { Domain, { Range2, Range } }, { { Domain, { Range, Range2 } } } }; + +/* Signatures for constructing products. + */ +static Signature set_product = + { { { Domain, Range } }, { { Domain }, { Range } } }; +static Signature map_product = + { { { Domain, Domain2 }, { Range, Range2 } }, + { { Domain, Range }, { Domain2, Range2 } } }; +static Signature domain_product = + { { { Domain, Domain2 }, Range }, + { { Domain, Range }, { Domain2, Range } } }; +static Signature range_product = + { { Domain, { Range, Range2 } }, + { { Domain, Range }, { Domain, Range2 } } }; + +/* Signatures for obtaining factors from a product. + */ +static Signature domain_factor_domain = + { { Domain, Range }, { { { Domain, Domain2 }, Range } } }; +static Signature domain_factor_range = + { { Domain2, Range }, { { { Domain, Domain2 }, Range } } }; +static Signature range_factor_domain = + { { Domain, Range }, { { Domain, { Range, Range2 } } } }; +static Signature range_factor_range = + { { Domain, Range2 }, { { Domain, { Range, Range2 } } } }; + +/* Signatures for (un)currying. + */ +static Signature curry = + { { Domain, { Range, Range2 } }, + { { { Domain, Range }, Range2 } } }; +static Signature uncurry = + { { { Domain, Range }, Range2 }, + { { Domain, { Range, Range2 } } } }; + +/* Signatures for (un)wrapping. + */ +static Signature wrap = { { { Domain, Range } }, { { Domain, Range } } }; +static Signature unwrap = { { Domain, Range }, { { { Domain, Range } } } }; + +/* Signatures for constructing objects that map to the domain or range + * of a map. + */ +static Signature domain_map = + { { { Domain, Range }, Domain }, { { Domain, Range } } }; +static Signature range_map = + { { { Domain, Range }, Range }, { { Domain, Range } } }; + +/* Signature for applying a comparison between the domain and the range + * of a map. + */ +static Signature map_cmp = + { { Domain, Domain }, { { Domain, Domain }, { Domain, Range } } }; + +/* Signature for creating a set corresponding to the domains + * of two functions. + */ +static Signature set_join = + { { Domain }, { { Domain, Range }, { Domain, Range } } }; + +/* Signatures for flattening the domain or range of a map, + * replacing it with either an anonymous tuple or a tuple with a given name. + */ +static Signature anonymize_nested_domain = + { { Anonymous, Range2 }, { { { Domain, Range }, Range2 } } }; +static Signature anonymize_nested_range = + { { Domain, Anonymous }, { { Domain, { Range, Range2 } } } }; +static Signature replace_nested_domain = + { { Domain2, Range2 }, + { { { Domain, Range }, Range2 }, { Anonymous} } }; +static Signature replace_nested_range = + { { Domain, Range3 }, { { Domain, { Range, Range2 } }, { Anonymous} } }; +static std::vector flatten_domain = + { anonymize_nested_domain, replace_nested_domain }; +static std::vector flatten_range = + { anonymize_nested_range, replace_nested_range }; + +/* Signatures for "set_at" methods. + */ +static Signature set_at_set = + { { Domain }, { { Domain }, { Integer }, { Anonymous } } }; +static Signature set_at_map = + { { Domain, Range }, + { { Domain, Range }, { Integer }, { Domain, Anonymous } } }; +static std::vector set_at = { set_at_set, set_at_map }; + +/* Signatures for "list" methods, extracting a list + * from a multi-expression. + */ +static Signature to_list_set = { { Anonymous }, { { Domain } } }; +static Signature to_list_map = { { Domain, Anonymous }, { { Domain, Range } } }; + +/* Signatures for functions constructing an object from only an isl::ctx. + */ +static Signature ctx_params = { { }, { { Ctx } } }; +static Signature ctx_set = { { Domain }, { { Ctx } } }; +static Signature ctx_map = { { Domain, Range }, { { Ctx } } }; + +/* Helper structure for sorting the keys of static_methods and + * special_member_methods such that the larger keys appear first. + * In particular, a key should appear before any key that appears + * as a substring in the key. + * Note that this sorting is currently only important + * for special_member_methods. + */ +struct larger_infix { + bool operator()(const std::string &x, const std::string &y) const { + if (x.length() > y. length()) + return true; + return x < y; + } +}; + +/* A map from part of a type name to a sequence of signatures. + */ +typedef std::map, larger_infix> infix_map; + +/* A map from a method name to a map from part of a type name + * to a sequence of signatures. + */ +typedef std::map infix_map_map; + +/* Signatures for static methods. + * + * The "unit" static method is only available in a 0-tuple space. + * + * The "empty" static method creates union objects with the relevant + * number of tuples. + * + * The "universe" static methods create objects from the corresponding spaces. + */ +static const infix_map_map static_methods { + { "unit", + { { "space", { ctx_params } } } + }, + { "empty", + { + { "union_set", { ctx_params, ctx_set } }, + { "union_map", { ctx_map } }, + { "union_pw_multi_aff", { ctx_set, ctx_map } }, + } + }, + { "universe", + { + { "set", { un_params, un_set } }, + { "map", { un_map } }, + } + }, +}; + +/* Signatures for unary operations that either take something in a set space + * and return something in the same space or take something in a map space + * and return something in the range of that space. + */ +static std::vector range_op = { un_set, range }; + +/* Signatures for binary operations where the second argument + * is a (multi-)value. + */ +static std::vector bin_val = { bin_set, bin_map_range }; + +/* The (default) signatures for methods with a given name. + * Some of these are overridden by special_member_methods. + */ +static const std::unordered_map> +member_methods { + { "add", bin_op }, + { "add_constant", bin_val }, + { "add_named_tuple", { to_set_named, add_range_named } }, + { "add_param", bin_op_anon }, + { "add_unnamed_tuple", { to_set, add_range } }, + { "apply", { set_forward, range_forward } }, + { "apply_domain", { domain_forward } }, + { "apply_range", { range_forward } }, + { "as", un_op }, + { "as_map", { un_map } }, + { "as_union_map", { un_map } }, + { "as_set", { un_set } }, + { "bind", { bind_set, bind_range } }, + { "bind_domain", { bind_domain } }, + { "bind_range", { bind_range } }, + { "bind_domain_wrapped_domain", + { bind_domain_wrapped_domain } }, + { "ceil", fn_un_op }, + { "coalesce", un_op }, + { "cond", fn_ter_op }, + { "constant", range_op }, + { "curry", { curry } }, + { "deltas", { transformation_domain } }, + { "detect_equalities", un_op }, + { "domain", fn_domain }, + { "domain_factor_domain", + { domain_factor_domain } }, + { "domain_factor_range", + { domain_factor_range } }, + { "domain_map", { domain_map } }, + { "domain_product", { domain_product } }, + { "domain_reverse", { map_domain_reverse } }, + { "drop", ter_int_int }, + { "drop_all_params", un_op }, + { "drop_unused_params", un_op }, + { "eq_at", { map_cmp } }, + { "every", each }, + { "extract", bin_op }, + { "flatten_domain", flatten_domain }, + { "flatten_range", flatten_range }, + { "floor", fn_un_op }, + { "foreach", each }, + { "foreach_scc", each_scc }, + { "ge_set", { set_join } }, + { "gt_set", { set_join } }, + { "gist", bin_op }, + { "gist_domain", { bin_map_domain } }, + { "gist_params", { bin_set_params, bin_map_params } }, + { "identity", { un_map, set_to_map } }, + { "identity_on_domain", { set_to_map } }, + { "indicator_function", anonymous_from_domain }, + { "insert_domain", { map_from_range_and_domain } }, + { "intersect", bin_op }, + { "intersect_params", { bin_set_params, bin_map_params } }, + { "intersect_domain", { bin_map_domain } }, + { "intersect_domain_wrapped_domain", + { bin_map_domain_wrapped_domain } }, + { "intersect_range", { bin_map_range } }, + { "intersect_range_wrapped_domain", + { bin_map_range_wrapped_domain } }, + { "lattice_tile", { un_set } }, + { "le_set", { set_join } }, + { "lt_set", { set_join } }, + { "lex_le_at", { map_cmp } }, + { "lex_lt_at", { map_cmp } }, + { "lex_ge_at", { map_cmp } }, + { "lex_gt_at", { map_cmp } }, + { "lexmin", fn_un_op }, + { "lexmax", fn_un_op }, + { "list", { to_list_set, to_list_map } }, + { "lower_bound", fn_bin_op }, + { "map_from_set", { set_to_map } }, + { "max", min_max }, + { "max_val", range_op }, + { "max_multi_val", range_op }, + { "min", min_max }, + { "min_val", range_op }, + { "min_multi_val", range_op }, + { "mod", bin_val }, + { "on_domain", from_domain }, + { "neg", fn_un_op }, + { "offset", fn_un_op }, + { "param_on_domain", anonymous_from_domain_bin_anon }, + { "params", { set_params, map_params } }, + { "plain_multi_val_if_fixed", + { un_set } }, + { "preimage", { set_backward } }, + { "preimage_domain", { domain_backward } }, + { "preimage_domain_wrapped_domain", + { domain_wrapped_domain_backward } }, + { "preimage_range", { range_backward } }, + { "product", { set_product, map_product } }, + { "project_out_param", bin_op_anon }, + { "project_out_all_params", + un_op }, + { "pullback", { domain_backward, bind_domain } }, + { "range", { range } }, + { "range_factor_domain", + { range_factor_domain } }, + { "range_factor_range", { range_factor_range } }, + { "range_lattice_tile", { un_map } }, + { "range_map", { range_map } }, + { "range_product", { range_product } }, + { "range_reverse", { map_range_reverse } }, + { "range_simple_fixed_box_hull", + { un_map } }, + { "reverse", { map_reverse } }, + { "scale", bin_val }, + { "scale_down", bin_val }, + { "set_at", set_at }, + { "set_domain_tuple", { update_domain } }, + { "set_range_tuple", { update_set, update_range } }, + { "simple_fixed_box_hull", + { un_set } }, + { "sub", fn_bin_op }, + { "subtract", bin_op }, + { "subtract_domain", { bin_map_domain } }, + { "subtract_range", { bin_map_range } }, + { "translation", { set_to_map } }, + { "to", un_op }, + { "unbind_params", { set_from_params } }, + { "unbind_params_insert_domain", + { map_from_range_and_domain } }, + { "uncurry", { uncurry } }, + { "union_add", fn_bin_op }, + { "unite", bin_op }, + { "universe", un_op }, + { "unwrap", { unwrap } }, + { "upper_bound", fn_bin_op }, + { "wrap", { wrap } }, + { "wrapped_reverse", { set_reverse } }, + { "zero", fn_un_op }, + { "zero_on_domain", { anonymous_map_from_domain } }, +}; + +/* Signatures for constructors of multi-expressions + * from a space and a list, with a special case for multi-union-expressions. + */ +static Signature from_list_set = { { Domain }, { { Domain }, { Anonymous } } }; +static Signature from_list_map = + { { Domain, Range }, { { Domain, Range }, { Domain, Anonymous } } }; +static Signature from_list_map_union = + { { Domain, Range }, { { Range }, { Domain, Anonymous } } }; + +/* Signatures for methods of types containing a given substring + * that override the default signatures, where larger substrings + * appear first. + * + * In particular, "gist" is usually a regular binary operation, + * but for any type derived from "aff", the argument refers + * to the domain of the function. + * + * When constructing a multi-expression from a space and a list, + * the kind of the space is usually the same as that of + * the constructed multi-expression. However, if the constructed object + * is a multi-union-expression, then the space is the fixed range space + * of the multi-union-expression, so it always has a single tuple. + * This happens in particular for constructing objects + * of type "multi_union_pw_aff". + * See also the "space" method below. + * + * The "size" method can usually simply be inherited from + * the corresponding plain C++ type, but for a "fixed_box", + * the size lives in the space of the box or its range. + * + * The "space" method is usually a regular unary operation + * that returns the single space of the elements in the object, + * with the same number of tuples. + * However, a "union" object may contain elements from many spaces and + * therefore its space only refers to the symbolic constants and + * has zero tuples, except if it is also a "multi_union" object, + * in which case it has a fixed range space and the space of the object + * has a single tuple. + * Note that since "space' is also the name of a template class, + * the default space method is handled by print_type_named_member_method. + */ +static const infix_map_map special_member_methods { + { "gist", + { { "aff", { bin_set_params, bin_map_domain } } } + }, + { "multi_union_pw_aff", + { { "space", { from_list_set, from_list_map_union } } } + }, + { "size", + { { "fixed_box", range_op } }, + }, + { "space", + { + { "multi_union", range_op }, + { "union", { un_params, set_params, map_params } }, + } + }, +}; + +/* Generic kinds for objects with zero, one or two tuples, + * the last of which may be anonymous. + */ +static Kind params{}; +static Kind set_type{ Domain }; +static Kind set_anon{ Anonymous }; +static Kind map_type{ Domain, Range }; +static Kind map_anon{ Domain, Anonymous }; + +/* The initial sequence of specialization kinds for base types. + * The specialization kinds for other types are derived + * from the corresponding base types. + * + * In particular, this sequence specifies how many tuples + * a given type can have and whether it is anonymous. + * + * "space" can have any number of tuples. + * "set" and "point" can have zero or one tuple. + * "map" can only have two tuples. + * "aff" can have one or two tuples, the last of which is anonymous. + * "fixed_box" can represent a (proper) set) or a map. + * "val" and "id" are treated as anonymous sets so that + * they can form the basis of "multi_val" and "multi_id". + */ +static const std::unordered_map> base_kinds { + { "space", { params, set_type, map_type } }, + { "set", { params, set_type } }, + { "point", { params, set_type } }, + { "map", { map_type } }, + { "aff", { set_anon, map_anon } }, + { "fixed_box", { set_type, map_type } }, + { "val", { set_anon } }, + { "id", { set_anon } }, +}; + +/* Prefixes introduced by type constructors. + */ +static const std::unordered_set type_prefixes { + "basic", + "multi", + "pw", + "union", +}; + +/* If "type" has a "_list" suffix, then return "type" with this suffix removed. + * Otherwise, simply return "type". + */ +static std::string drop_list(const std::string &type) +{ + size_t pos = type.rfind('_'); + + if (pos == std::string::npos) + return type; + if (type.substr(pos + 1) == "list") + return type.substr(0, pos); + return type; +} + +/* Given the name of a plain C++ type, return the base type + * from which it was derived using type constructors. + * + * In particular, drop any "list" suffix and + * drop any prefixes from type_prefixes, stopping + * as soon as a base type is found for which kinds have been registered + * in base_kinds. + */ +static std::string base_type(const std::string &type) +{ + auto base = type; + size_t pos; + + base = drop_list(base); + while (base_kinds.count(base) == 0 && + (pos = base.find('_')) != std::string::npos && + type_prefixes.count(base.substr(0, pos)) != 0) { + base = base.substr(pos + 1); + } + + return base; +} + +/* A mapping from anonymous kinds to named kinds. + */ +static std::map anon_to_named { + { set_anon, set_type }, + { map_anon, map_type }, +}; + +/* Given a sequence of anonymous kinds, replace them + * by the corresponding named kinds. + */ +static std::vector add_name(const std::vector &tuples) +{ + std::vector named; + + for (const auto &tuple : tuples) + named.emplace_back(anon_to_named.at(tuple)); + + return named; +} + +/* Look up the (initial) specializations of the class called "name". + * If no specializations have been defined, then return an empty vector. + * + * Start from the initial specializations of the corresponding base type. + * If this template class is a multi-expression, then it was derived + * from an anonymous function type. Replace the final Anonymous + * tuple kind by a placeholder in this case. + */ +static std::vector lookup_class_tuples(const std::string &name) +{ + std::string base = base_type(name); + + if (base_kinds.count(base) == 0) + return { }; + if (name.find("multi_") != std::string::npos) + return add_name(base_kinds.at(base)); + return base_kinds.at(base); +} + +/* Add a template class called "name", of which the methods are described + * by "clazz" and the initial specializations by "class_tuples". + */ +void template_cpp_generator::add_template_class(const isl_class &clazz, + const std::string &name, const std::vector &class_tuples) +{ + auto isl_namespace = cpp_type_printer().isl_namespace(); + auto super = isl_namespace + name; + + template_classes.emplace(name, + template_class{name, super, clazz, class_tuples}); +} + +/* Construct a templated C++ bindings generator from + * the exported types and functions and the set of all declared functions. + * + * On top of the initialization of the shared parts + * of C++ bindings generators, add a template class + * for each plain C++ class for which template kinds + * have been defined. + * In particular, determine the base type from which the plain C++ class + * was derived using type constructors and check if any template kinds + * have been registered for this base type. + */ +template_cpp_generator::template_cpp_generator(clang::SourceManager &SM, + std::set &exported_types, + std::set exported_functions, + std::set functions) : + cpp_generator(SM, exported_types, exported_functions, + functions) +{ + for (const auto &kvp : classes) { + const auto &clazz = kvp.second; + std::string name = type2cpp(clazz); + const auto &class_tuples = lookup_class_tuples(name); + + if (class_tuples.empty()) + continue; + add_template_class(clazz, name, class_tuples); + } +} + +/* Call "fn" on each template class. + */ +void template_cpp_generator::foreach_template_class( + const std::function &fn) const +{ + for (const auto &kvp : template_classes) + fn(kvp.second); +} + +/* Print forward declarations for all template classes to "os". + * + * For template classes that represent an anonymous function + * that can also have a domain tuple, provide an _on alias + * that adds the fixed Anonymous tuple kind. + */ +void template_cpp_generator::print_forward_declarations(std::ostream &os) +{ + foreach_template_class([&os] (const template_class &template_class) { + auto name = template_class.class_name; + + os << "\n"; + os << "template \n"; + os << "struct " << name << ";\n"; + + if (!template_class.is_anon()) + return; + if (template_class.is_anon_set()) + return; + + os << "\n"; + os << "template \n"; + os << "using " << name << "_on = " + << name << ";\n"; + }); +} + +/* Print friend declarations for all template classes to "os". + */ +void template_cpp_generator::print_friends(std::ostream &os) +{ + foreach_template_class([&os] (const template_class &template_class) { + os << " template \n"; + os << " friend struct " << template_class.class_name << ";\n"; + }); +} + +/* Print a template parameter or argument. + * In case of a std::string, it's a template parameter + * that needs to be declared. + */ +static void print_template_arg(std::ostream &os, const std::string &arg) +{ + os << "typename " << arg; +} + +/* Print a template parameter or argument. + * In case of a TupleKindPtr, it's a template argument. + */ +static void print_template_arg(std::ostream &os, const TupleKindPtr &kind) +{ + os << kind->to_string(); +} + +/* Print a sequence of template parameters (std::string) or + * arguments (TupleKindPtr) "args", without the enclosing angle brackets. + */ +template +static void print_pure_template_args(std::ostream &os, const List &args) +{ + for (size_t i = 0; i < args.size(); ++i) { + if (i != 0) + os << ", "; + print_template_arg(os, args[i]); + } +} + +/* Print a sequence of template parameters (std::string) or + * arguments (TupleKindPtr) "args". + */ +template +static void print_template_args(std::ostream &os, const List &args) +{ + os << "<"; + print_pure_template_args(os, args); + os << ">"; +} + +/* Print a declaration of the template parameters "params". + */ +static void print_template(std::ostream &os, + const std::vector ¶ms) +{ + os << "template "; + print_template_args(os, params); + os << "\n"; +} + +/* Print a declaration of the template parameters "params", + * if there are any. + */ +static void print_non_empty_template(std::ostream &os, + const std::vector ¶ms) +{ + if (params.size() > 0) + print_template(os, params); +} + +/* Print a bare template type, i.e., without namespace, + * consisting of the type "type" and the kind "kind" to "os". + * + * In particular, print "type" followed by the template arguments + * as specified by "kind". + */ +static void print_bare_template_type(std::ostream &os, const std::string &type, + const Kind &kind) +{ + os << type; + print_template_args(os, kind); +} + +/* A specific instance of "template_class", with tuple kinds given by "kind". + */ +struct specialization { + struct template_class &template_class; + Kind kind; + + const std::string &base_name() const; + const std::string &class_name() const; +}; + +/* The name of the plain C++ interface class + * from which this template class (instance) derives. + */ +const std::string &specialization::base_name() const +{ + return template_class.super_name; +} + +/* The name of the template class. + */ +const std::string &specialization::class_name() const +{ + return template_class.class_name; +} + +/* Helper class for printing the specializations of template classes + * that is used to print both the class declarations and the class definitions. + * + * "os" is the stream onto which the classes should be printed. + * "generator" is the templated C++ interface generator printing the classes. + */ +struct specialization_printer { + specialization_printer(std::ostream &os, + template_cpp_generator &generator) : + os(os), generator(generator) {} + + virtual void print_class(const specialization &instance) const = 0; + void print_classes() const; + + std::ostream &os; + template_cpp_generator &generator; +}; + +/* Print all specializations of all template classes. + * + * Each class has a predefined set of initial specializations, + * but while such a specialization is being printed, + * the need for other specializations may arise and + * these are added at the end of the list of specializations. + * That is, class_tuples.size() may change during the execution + * of the loop. + * + * For each specialization of a template class, call + * the print_class virtual method. + */ +void specialization_printer::print_classes() const +{ + for (auto &kvp : generator.template_classes) { + auto &template_class = kvp.second; + const auto &class_tuples = template_class.class_tuples; + + for (size_t i = 0; i < class_tuples.size(); ++i) + print_class({ template_class, class_tuples[i] }); + } +} + +/* A helper class for printing method declarations and definitions + * of a template class specialization. + * + * "instance" is the template class specialization for which methods + * are printed. + * "generator" is the templated C++ interface generator printing the classes. + */ +struct template_cpp_generator::class_printer : + public cpp_generator::class_printer { + class_printer(const specialization &instance, + const specialization_printer &instance_printer, + bool is_declaration); + + void print_return_type(const Method &method, const Kind &kind) + const; + void print_method_template_arguments(const Signature &sig); + void print_method_header(const Method &method, const Signature &sig); + bool print_special_method(const Method &method, + const infix_map_map &special_methods); + void print_static_method(const Method &method); + void print_constructor(const Method &method); + bool is_return_kind(const Method &method, const Kind &return_kind); + void add_specialization(const Kind &kind); + bool print_matching_method(const Method &method, const Signature &sig, + const Kind &match_arg); + bool print_matching_method(const Method &method, const Signature &sig); + void print_matching_method(const Method &method, + const std::vector &signatures); + void print_at_method(const Method &method); + bool print_special_member_method(const Method &method); + bool print_type_named_member_method(const Method &method); + bool print_member_method_with_name(const Method &method, + const std::string &name); + void print_member_method(const Method &method); + void print_any_method(const Method &method); + virtual void print_method(const Method &method) override; + virtual void print_method(const ConversionMethod &method) override; + virtual void print_method_sig(const Method &method, + const Signature &sig, bool deleted) = 0; + virtual bool want_descendent_overloads(const function_set &methods) + override; + void print_all_methods(); + + const specialization &instance; + template_cpp_generator &generator; +}; + +/* Construct a class_printer from the template class specialization + * for which methods are printed and + * the printer of the template class. + * + * The template class printer is only used to obtain the output stream and + * the templated C++ interface generator printing the classes. + */ +template_cpp_generator::class_printer::class_printer( + const specialization &instance, + const specialization_printer &instance_printer, + bool is_declaration) : + cpp_generator::class_printer(instance_printer.os, + instance.template_class.clazz, instance_printer.generator, + is_declaration), + instance(instance), generator(instance_printer.generator) +{ +} + +/* An abstract template type printer, where the way of obtaining + * the argument kind is specified by the subclasses. + */ +struct template_cpp_type_printer : public cpp_type_printer { + template_cpp_type_printer() {} + + std::string base(const std::string &type, const Kind &kind) const; + virtual Kind kind(int arg) const = 0; + virtual std::string qualified(int arg, const std::string &cpp_type) + const override; +}; + +/* Print a template type consisting of the type "type" and the kind "kind", + * including the "typed::" namespace specifier. + */ +std::string template_cpp_type_printer::base(const std::string &type, + const Kind &kind) const +{ + std::ostringstream ss; + + ss << "typed::"; + print_bare_template_type(ss, type, kind); + return ss.str(); +} + +/* Return the qualified form of the given C++ isl type name appearing + * in argument position "arg" (-1 for return type). + * + * isl::ctx is not templated, so if "cpp_type" is "ctx", + * then print a non-templated version. + * Otherwise, look up the kind of the argument and print + * the corresponding template type. + */ +std::string template_cpp_type_printer::qualified(int arg, + const std::string &cpp_type) const +{ + if (cpp_type == "ctx") + return cpp_type_printer::qualified(arg, cpp_type); + + return base(cpp_type, kind(arg)); +} + +/* A template type printer for printing types with a fixed kind. + * + * "fixed_kind" is the fixed kind. + */ +struct template_cpp_kind_type_printer : public template_cpp_type_printer { + template_cpp_kind_type_printer(const Kind &kind) : + template_cpp_type_printer(), fixed_kind(kind) {} + + virtual Kind kind(int arg) const override; + + const Kind &fixed_kind; +}; + +/* Return the kind of the argument at position "arg", + * where position -1 refers to the return type. + * + * Always use the fixed kind. + */ +Kind template_cpp_kind_type_printer::kind(int arg) const +{ + return fixed_kind; +} + +/* A template type printer for printing a method with a given signature. + * + * "sig" is the signature of the method being printed. + */ +struct template_cpp_arg_type_printer : public template_cpp_type_printer { + template_cpp_arg_type_printer(const Signature &sig) : + template_cpp_type_printer(), sig(sig) {} + + virtual Kind kind(int arg) const override; + + const Signature &sig; +}; + +/* Return the kind of the argument at position "arg", + * where position -1 refers to the return type. + * + * Look up the kind in the signature. + */ +Kind template_cpp_arg_type_printer::kind(int arg) const +{ + int n_args = sig.args.size(); + + if (arg < 0) + return sig.ret; + if (arg >= n_args) + generator::die("argument out of bounds"); + return sig.args[arg]; +} + +/* A template type printer for printing a method with a given signature + * as part of a template class specialization of a given kind. + * + * "class_kind" is the template class specialization kind. + */ +struct template_method_type_printer : public template_cpp_arg_type_printer { + template_method_type_printer(const Signature &sig, + const Kind &class_kind) : + template_cpp_arg_type_printer(sig), + class_kind(class_kind) {} + + virtual std::string class_type(const std::string &cpp_name) + const override; + + const Kind &class_kind; +}; + +/* Print the class type "cpp_name". + * + * Print the templated version using the template class specialization kind. + */ +std::string template_method_type_printer::class_type( + const std::string &cpp_name) const +{ + return base(cpp_name, class_kind); +} + +/* Print the templated return type of "method" of the kind "return_kind". + * + * Construct a type printer with "return_kind" as fixed kind and + * use it to print the return type. + */ +void template_cpp_generator::class_printer::print_return_type( + const Method &method, const Kind &return_kind) const +{ + template_cpp_kind_type_printer printer(return_kind); + + os << printer.return_type(method); +} + +/* Remove the initial "n" elements from "v". + */ +template +static void drop_initial(std::vector &v, size_t n) +{ + v.erase(v.begin(), v.begin() + n); +} + +/* If a method with signature "sig" requires additional template parameters + * compared to those of the class, then print a declaration for them. + * If this->declarations is set, then this will be part of a method declaration, + * requiring extra indentation. + * + * Construct the sequence of all required template parameters + * with those of the template class appearing first. + * If this sequence has any parameters not induced by the template class itself, + * then print a declaration for these extra parameters. + */ +void template_cpp_generator::class_printer::print_method_template_arguments( + const Signature &sig) +{ + std::vector class_params, method_params; + + class_params = instance.kind.params(); + method_params = class_params; + combine(method_params, sig.params()); + + if (class_params.size() == method_params.size()) + return; + + drop_initial(method_params, class_params.size()); + + if (declarations) + os << " "; + print_template(os, method_params); +} + +/* Print the header for "method" with signature "sig". + * + * First print any additional template parameters that may be required and + * then print a regular method header, using a template type printer. + */ +void template_cpp_generator::class_printer::print_method_header( + const Method &method, const Signature &sig) +{ + template_method_type_printer type_printer(sig, instance.kind); + + print_method_template_arguments(sig); + cpp_generator::class_printer::print_method_header(method, + type_printer); +} + +/* Given a group of methods with the same name, + * should extra methods be added that take as arguments + * those types that can be converted to the original argument type + * through a unary constructor? + * + * Since type deduction does not consider implicit conversions, + * these extra methods should always be printed. + */ +bool template_cpp_generator::class_printer::want_descendent_overloads( + const function_set &methods) +{ + return true; +} + +/* Print all constructors and methods that forward + * to the corresponding methods in the plain C++ interface class. + */ +void template_cpp_generator::class_printer::print_all_methods() +{ + print_constructors(); + print_methods(); +} + +/* A helper class for printing method declarations + * of a template class specialization. + */ +struct template_cpp_generator::method_decl_printer : + public template_cpp_generator::class_printer { + method_decl_printer(const specialization &instance, + const struct specialization_printer &instance_printer) : + class_printer(instance, instance_printer, true) {} + + virtual void print_method_sig(const Method &method, + const Signature &sig, bool deleted) override; + virtual void print_get_method(FunctionDecl *fd) override; +}; + +/* Print a declaration of the method "method" with signature "sig". + * Mark is "delete" if "deleted" is set. + */ +void template_cpp_generator::method_decl_printer::print_method_sig( + const Method &method, const Signature &sig, bool deleted) +{ + print_method_header(method, sig); + if (deleted) + os << " = delete"; + os << ";\n"; +} + +/* Return the total number of arguments in the signature for "method", + * taking into account any possible callback arguments. + * + * In particular, if the method has a callback argument, + * then the return kind of the callback appears at the position + * of the callback and the kinds of the arguments (except + * the user pointer argument) appear in the following positions. + * The user pointer argument that follows the callback argument + * is also removed. + */ +static int total_params(const Method &method) +{ + int n = method.num_params(); + + for (const auto &callback : method.callbacks) { + auto callback_type = callback->getType(); + auto proto = generator::extract_prototype(callback_type); + + n += proto->getNumArgs() - 1; + n -= 1; + } + + return n; +} + +/* Return a signature for "method" that matches "instance". + */ +static Signature instance_sig(const Method &method, + const specialization &instance) +{ + std::vector args(total_params(method)); + + args[0] = instance.kind; + return { instance.kind, args }; +} + +/* Print a declaration for the "get" method "fd", + * using a name that includes the "get_" prefix. + * + * These methods are only included in the plain interface. + * Explicitly delete them from the templated interface. + */ +void template_cpp_generator::method_decl_printer::print_get_method( + FunctionDecl *fd) +{ + Method method(clazz, fd, clazz.base_method_name(fd)); + + print_method_sig(method, instance_sig(method, instance), true); +} + +/* A helper class for printing method definitions + * of a template class specialization. + */ +struct template_cpp_generator::method_impl_printer : + public template_cpp_generator::class_printer { + method_impl_printer(const specialization &instance, + const struct specialization_printer &instance_printer) : + class_printer(instance, instance_printer, false) {} + + void print_callback_method_body(const Method &method, + const Signature &sig); + void print_method_body(const Method &method, const Signature &sig); + void print_constructor_body(const Method &method, const Signature &sig); + virtual void print_method_sig(const Method &method, + const Signature &sig, bool deleted) override; + virtual void print_get_method(FunctionDecl *fd) override; +}; + +/* Print a definition of the constructor "method" with signature "sig". + * + * Simply pass all arguments to the constructor of the corresponding + * plain type. + */ +void template_cpp_generator::method_impl_printer::print_constructor_body( + const Method &method, const Signature &sig) +{ + const auto &base_name = instance.base_name(); + + os << " : " << base_name; + method.print_cpp_arg_list(os, [&] (int i, int arg) { + os << method.fd->getParamDecl(i)->getName().str(); + }); + os << "\n"; + + os << "{\n"; + os << "}\n"; +} + +/* Print the arguments of the callback function "callback" to "os", + * calling "print_arg" with the type and the name of the arguments, + * where the type is obtained from "type_printer" with argument positions + * shifted by "shift". + * None of the arguments should be skipped. + */ +static void print_callback_args(std::ostream &os, + const FunctionProtoType *callback, const cpp_type_printer &type_printer, + int shift, + const std::function &print_arg) +{ + auto n_arg = callback->getNumArgs() - 1; + + Method::print_arg_list(os, 0, n_arg, [&] (int i) { + auto type = callback->getArgType(i); + auto name = "arg" + std::to_string(i); + auto cpptype = type_printer.param(shift + i, type); + + print_arg(cpptype, name); + + return false; + }); +} + +/* Print a lambda corresponding to "callback" + * with signature "sig" and argument positions shifted by "shift". + * + * The lambda takes arguments with plain isl types and + * calls the callback of "method" with templated arguments. + */ +static void print_callback_lambda(std::ostream &os, ParmVarDecl *callback, + const Signature &sig, int shift) +{ + auto callback_type = callback->getType(); + auto callback_name = callback->getName().str(); + auto proto = generator::extract_prototype(callback_type); + + os << " auto lambda_" << callback_name << " = [&] "; + print_callback_args(os, proto, cpp_type_printer(), shift, + [&] (const std::string &type, const std::string &name) { + os << type << " " << name; + }); + os << " {\n"; + + os << " return " << callback_name; + print_callback_args(os, proto, template_cpp_arg_type_printer(sig), + shift, + [&] (const std::string &type, const std::string &name) { + os << type << "(" << name << ")"; + }); + os << ";\n"; + + os << " };\n"; +} + +/* Print lambdas for passing to the plain method corresponding to "method" + * with signature "sig". + * + * The method is assumed to have only callbacks as argument, + * which means the arguments of the first callback are shifted by 2 + * with respect to the arguments of the signature + * (one for the position of the callback argument plus + * one for the return kind of the callback). + * The arguments of a subsequent callback are shifted by + * the number of arguments of the previous callback minus one + * for the user pointer plus one for the return kind. + */ +static void print_callback_lambdas(std::ostream &os, const Method &method, + const Signature &sig) +{ + int shift; + + if (method.num_params() != 1 + 2 * method.callbacks.size()) + generator::die("callbacks are assumed to be only arguments"); + + shift = 2; + for (const auto &callback : method.callbacks) { + print_callback_lambda(os, callback, sig, shift); + shift += generator::prototype_n_args(callback->getType()); + } +} + +/* Print a definition of the member method "method", which is known + * to have a callback argument, with signature "sig". + * + * First print lambdas for passing to the corresponding plain method and + * calling the callback of "method" with templated arguments. + * Then call the plain method, replacing the original callbacks + * by the lambdas. + * + * The return value is assumed to be isl_bool or isl_stat + * so that no conversion to a template type is required. + */ +void template_cpp_generator::method_impl_printer::print_callback_method_body( + const Method &method, const Signature &sig) +{ + const auto &base_name = instance.base_name(); + auto return_type = method.fd->getReturnType(); + + if (!is_isl_bool(return_type) && !is_isl_stat(return_type)) + die("only isl_bool and isl_stat return types are supported"); + + os << "{\n"; + + print_callback_lambdas(os, method, sig); + + os << " return "; + os << base_name << "::" << method.name; + method.print_cpp_arg_list(os, [&] (int i, int arg) { + auto param = method.fd->getParamDecl(i); + + if (generator::is_callback(param->getType())) + os << "lambda_"; + os << param->getName().str(); + }); + os << ";\n"; + + os << "}\n"; +} + +/* Print a definition of the member or static method "method" + * with signature "sig". + * + * The body calls the corresponding method of the base class + * in the plain interface and + * then casts the result to the templated result type. + */ +void template_cpp_generator::method_impl_printer::print_method_body( + const Method &method, const Signature &sig) +{ + const auto &base_name = instance.base_name(); + + os << "{\n"; + os << " auto res = "; + os << base_name << "::" << method.name; + method.print_cpp_arg_list(os, [&] (int i, int arg) { + os << method.fd->getParamDecl(i)->getName().str(); + }); + os << ";\n"; + + os << " return "; + print_return_type(method, sig.ret); + os << "(res);\n"; + os << "}\n"; +} + +/* Print a definition of the method "method" with signature "sig", + * if "deleted" is not set. + * + * If "deleted" is set, then the corresponding declaration + * is marked "delete" and no definition needs to be printed. + * + * Otherwise print the method header, preceded by the template parameters, + * if needed. + * The body depends on whether the method is a constructor or + * takes any callbacks. + */ +void template_cpp_generator::method_impl_printer::print_method_sig( + const Method &method, const Signature &sig, bool deleted) +{ + if (deleted) + return; + + os << "\n"; + print_non_empty_template(os, instance.kind.params()); + print_method_header(method, sig); + os << "\n"; + if (method.kind == Method::Kind::constructor) + print_constructor_body(method, sig); + else if (method.callbacks.size() != 0) + print_callback_method_body(method, sig); + else + print_method_body(method, sig); +} + +/* Print a definition for the "get" method "fd" in class "clazz", + * using a name that includes the "get_" prefix, to "os". + * + * The declarations of these methods are explicitly delete'd + * so no definition needs to be printed. + */ +void template_cpp_generator::method_impl_printer::print_get_method( + FunctionDecl *fd) +{ +} + +/* Print a declaration or definition of the static method "method", + * if it has a signature specified by static_methods. + */ +void template_cpp_generator::class_printer::print_static_method( + const Method &method) +{ + print_special_method(method, static_methods); +} + +/* Signatures for constructors from a string. + */ +static Signature params_from_str = { { }, { { Ctx }, { Str } } }; +static Signature set_from_str = { { Domain }, { { Ctx }, { Str } } }; +static Signature map_from_str = { { Domain, Range }, { { Ctx }, { Str } } }; +static std::vector from_str = + { params_from_str, set_from_str, map_from_str }; + +/* Signature for a constructor from an integer. + */ +static Signature int_from_si = { { Anonymous }, { { Ctx }, { Integer } } }; + +/* Signatures for constructors of lists from the initial number + * of elements. + */ +static Signature alloc_params = { { }, { { Ctx }, { Integer } } }; +static Signature alloc_set = { { Domain }, { { Ctx }, { Integer } } }; +static Signature alloc_map = { { Domain, Range }, { { Ctx }, { Integer } } }; + +/* Signatures for constructors and methods named after some other class. + * + * Two forms of constructors are handled + * - conversion from another object + * - construction of a multi-expression from a space and a list + * + * Methods named after some other class also come in two forms + * - extraction of information such as the space or a list + * - construction of a multi-expression from a space and a list + * + * In both cases, the first form is a unary operation and + * the second has an extra argument with a kind that is equal + * to that of the first argument, except that the final tuple is anonymous. + */ +static std::vector constructor_sig = { + un_params, + un_set, + un_map, + from_list_set, + from_list_map, +}; + +/* Signatures for constructors derived from methods + * with the given names that override the default signatures. + */ +static const std::unordered_map> +special_constructors { + { "alloc", { alloc_params, alloc_set, alloc_map } }, + { "int_from_si", { int_from_si } }, + { "read_from_str", from_str }, +}; + +/* Print a declaration or definition of the constructor "method". + */ +void template_cpp_generator::class_printer::print_constructor( + const Method &method) +{ + if (special_constructors.count(method.name) != 0) { + const auto &sigs = special_constructors.at(method.name); + return print_matching_method(method, sigs); + } + print_matching_method(method, constructor_sig); +} + +/* Does this template class represent an anonymous function? + * + * If any specialization represents an anonymous function, + * then every specialization does, so simply check + * the first specialization. + */ +bool template_class::is_anon() const +{ + return class_tuples[0].is_anon(); +} + +/* Does this template class represent an anonymous value? + * + * That is, is there only a single specialization that moreover + * has a single, anonymous tuple? + */ +bool template_class::is_anon_set() const +{ + return class_tuples.size() == 1 && class_tuples[0].is_anon_set(); +} + +/* Update the substitution "sub" to map "general" to "specific" + * if "specific" is a special case of "general" consistent with "sub", + * given that "general" is not a pair and can be assigned "specific". + * Return true if successful. + * Otherwise, return false. + * + * Check whether "general" is already assigned something in "sub". + * If so, it must be assigned "specific". + * Otherwise, there is a conflict. + */ +static bool update_sub_base(Substitution &sub, const TupleKindPtr &general, + const TupleKindPtr &specific) +{ + auto name = general->name; + + if (sub.count(name) != 0 && sub.at(name) != specific) + return false; + sub.emplace(name, specific); + return true; +} + +/* Update the substitution "sub" to map "general" to "specific" + * if "specific" is a special case of "general" consistent with "sub". + * Return true if successful. + * Otherwise, return false. + * + * If "general" is a pair and "specific" is not, + * then "specific" cannot be a special case. + * If both are pairs, then update the substitution based + * on both sides. + * If "general" is Anonymous, then "specific" must be Anonymous as well. + * If "general" is Leaf, then "specific" cannot be a pair. + * + * Otherwise, assign "specific" to "general", if possible. + */ +static bool update_sub(Substitution &sub, const TupleKindPtr &general, + const TupleKindPtr &specific) +{ + if (general->left() && !specific->left()) + return false; + if (general->left()) + return update_sub(sub, general->left(), specific->left()) && + update_sub(sub, general->right(), specific->right()); + if (general == Anonymous && specific != Anonymous) + return false; + if (general == Leaf && specific->left()) + return false; + + return update_sub_base(sub, general, specific); +} + +/* Check if "specific" is a special case of "general" and, + * if so, return true along with a substitution + * that maps "general" to "specific". + * Otherwise return false. + * + * This can only happen if the number of tuple kinds is the same. + * If so, start with an empty substitution and update it + * for each pair of tuple kinds, checking that each update succeeds. + */ +static std::pair specializer(const Kind &general, + const Kind &specific) +{ + Substitution specializer; + + if (general.size() != specific.size()) + return { false, Substitution() }; + + for (size_t i = 0; i < general.size(); ++i) { + auto general_tuple = general[i]; + + if (!update_sub(specializer, general[i], specific[i])) + return { false, Substitution() }; + } + + return { true, specializer }; +} + +/* Is "kind1" equivalent to "kind2"? + * That is, is each a special case of the other? + */ +static bool equivalent(const Kind &kind1, const Kind &kind2) +{ + return specializer(kind1, kind2).first && + specializer(kind2, kind1).first; +} + +/* Add the specialization "kind" to the sequence of specializations, + * provided there is no equivalent specialization already in there. + */ +void template_class::add_specialization(const Kind &kind) +{ + for (const auto &special : class_tuples) + if (equivalent(special, kind)) + return; + class_tuples.emplace_back(kind); +} + +/* A type printer that prints the plain interface type, + * without namespace. + */ +struct plain_cpp_type_printer : public cpp_type_printer { + plain_cpp_type_printer() {} + + virtual std::string qualified(int arg, const std::string &cpp_type) + const override; +}; + +/* Return the qualified form of the given C++ isl type name appearing + * in argument position "arg" (-1 for return type). + * + * For printing the plain type without namespace, no modifications + * are required. + */ +std::string plain_cpp_type_printer::qualified(int arg, + const std::string &cpp_type) const +{ + return cpp_type; +} + +/* Return a string representation of the plain type "type". + * + * For the plain printer, the argument position is irrelevant, + * so simply pass in -1. + */ +static std::string plain_type(QualType type) +{ + return plain_cpp_type_printer().param(-1, type); +} + +/* Return a string representation of the plain return type of "method". + */ +static std::string plain_return_type(const Method &method) +{ + return plain_type(method.fd->getReturnType()); +} + +/* Return that part of the signature "sig" that should match + * the template class specialization for the given method. + * + * In particular, if the method is a regular member method, + * then the instance should match the first argument. + * Otherwise, it should match the return kind. + */ +static const Kind &matching_kind(const Method &method, const Signature &sig) +{ + if (method.kind == Method::Kind::member_method) + return sig.args[0]; + else + return sig.ret; +} + +/* Is it possible for "template_class" to have the given kind? + * + * If the template class represents an anonymous function, + * then so must the given kind. + * There should also be specialization with the same number of tuple kinds. + */ +static bool has_kind(const template_class &template_class, const Kind &kind) +{ + if (template_class.is_anon() && !kind.is_anon()) + return false; + for (const auto &class_tuple : template_class.class_tuples) + if (class_tuple.size() == kind.size()) + return true; + return false; +} + +/* Is "return_kind" a possible kind for the return type of "method"? + * + * If the return type is not a template class, + * then "return_kind" should not have any template parameters. + * Otherwise, "return_kind" should be a valid kind for the template class. + */ +bool template_cpp_generator::class_printer::is_return_kind( + const Method &method, const Kind &return_kind) +{ + const auto &template_classes = generator.template_classes; + auto return_type = plain_return_type(method); + + if (template_classes.count(return_type) == 0) + return return_kind.params().size() == 0; + return has_kind(template_classes.at(return_type), return_kind); +} + +/* Is "kind" a placeholder that can be assigned something else + * in a substitution? + * + * Anonymous can only be mapped to itself. This is taken care of + * by assign(). + * Leaf can only be assigned a placeholder, but there is no need + * to handle this specifically since Leaf can still be assigned + * to the placeholder. + */ +static bool assignable(const TupleKindPtr &kind) +{ + return kind != Anonymous && kind != Leaf; +} + +/* Return a substitution that maps "kind1" to "kind2", if possible. + * Otherwise return an empty substitution. + * + * Check if "kind1" can be assigned anything or + * if "kind1" and "kind2" are identical. + * The latter case handles mapping Anonymous to itself. + */ +static Substitution assign(const TupleKindPtr &kind1, const TupleKindPtr &kind2) +{ + Substitution res; + + if (assignable(kind1) || kind1 == kind2) + res.emplace(kind1->name, kind2); + return res; +} + +/* Return a substitution that first applies "first" and then "second". + * + * The result consists of "second" and of "second" applied to "first". + */ +static Substitution compose(const Substitution &first, + const Substitution &second) +{ + Substitution res = second; + + for (const auto &kvp : first) + res.emplace(kvp.first, apply(kvp.second, second)); + + return res; +} + +static Substitution compute_unifier(const TupleKindPtr &kind1, + const TupleKindPtr &kind2); + +/* Try and extend "unifier" with a unifier for "kind1" and "kind2". + * Return the resulting unifier if successful. + * Otherwise, return an empty substitution. + * + * First apply "unifier" to "kind1" and "kind2". + * Then compute a unifier for the resulting tuple kinds and + * combine it with "unifier". + */ +static Substitution combine_unifiers(const TupleKindPtr &kind1, + const TupleKindPtr &kind2, const Substitution &unifier) +{ + auto k1 = apply(kind1, unifier); + auto k2 = apply(kind2, unifier); + auto u = compute_unifier(k1, k2); + if (u.size() == 0) + return Substitution(); + return compose(unifier, u); +} + +/* Try and compute a unifier of "kind1" and "kind2", + * i.e., a substitution that produces the same result when + * applied to both "kind1" and "kind2", + * for the case where both "kind1" and "kind2" are pairs. + * Return this unifier if it was found. + * Return an empty substitution if no unifier can be found. + * + * First compute a unifier for the left parts of the pairs and, + * if successful, combine it with a unifier for the right parts. + */ +static Substitution compute_pair_unifier(const TupleKindPtr &kind1, + const TupleKindPtr &kind2) +{ + auto unifier_left = compute_unifier(kind1->left(), kind2->left()); + if (unifier_left.size() == 0) + return Substitution(); + return combine_unifiers(kind1->right(), kind2->right(), unifier_left); +} + +/* Try and compute a unifier of "kind1" and "kind2", + * i.e., a substitution that produces the same result when + * applied to both "kind1" and "kind2". + * Return this unifier if it was found. + * Return an empty substitution if no unifier can be found. + * + * If one of the tuple kinds is a pair then assign it + * to the other tuple kind, if possible. + * If neither is a pair, then try and assign one to the other. + * Otherwise, let compute_pair_unifier compute a unifier. + * + * Note that an assignment is added to the unifier even + * if "kind1" and "kind2" are identical. + * This ensures that a successful substitution is never empty. + */ +static Substitution compute_unifier(const TupleKindPtr &kind1, + const TupleKindPtr &kind2) +{ + if (kind1->left() && !kind2->left()) + return assign(kind2, kind1); + if (!kind1->left() && kind2->left()) + return assign(kind1, kind2); + if (!kind1->left() && !kind2->left()) { + if (assignable(kind1)) + return assign(kind1, kind2); + else + return assign(kind2, kind1); + } + + return compute_pair_unifier(kind1, kind2); +} + +/* Try and compute a unifier of "kind1" and "kind2", + * i.e., a substitution that produces the same result when + * applied to both "kind1" and "kind2". + * Return this unifier if it was found. + * Return an empty substitution if no unifier can be found. + * + * Start with an empty substitution and compute a unifier for + * each pair of tuple kinds, combining the results. + * If no combined unifier can be found or + * if the numbers of tuple kinds are different, then return + * an empty substitution. + * This assumes that the number of tuples is greater than zero, + * as otherwise an empty substitution would be returned as well. + */ +static Substitution compute_unifier(const Kind &kind1, const Kind &kind2) +{ + Substitution unifier; + + if (kind1.size() != kind2.size()) + return Substitution(); + + for (size_t i = 0; i < kind1.size(); ++i) + unifier = combine_unifiers(kind1[i], kind2[i], unifier); + + return unifier; +} + +/* Try and construct a Kind that is a specialization of both "general" and + * "specific", where "specific" is known _not_ to be a specialization + * of "general" and not to contain any Leaf. + * + * First check whether "general" is a specialization of "specific". + * If so, simply return "general". + * Otherwise, rename the placeholders in the two kinds apart and + * try and compute a unifier. + * If this succeeds, then return the result of applying the unifier. + */ +static std::pair unify(const Kind &general, const Kind &specific) +{ + if (specializer(specific, general).first) { + return { true, general }; + } else { + auto rename = param_renamer(specific.params(), "T"); + auto renamed = specific.apply(rename); + auto unifier = compute_unifier(general, renamed); + + if (unifier.size() == 0) + return { false, { } }; + + return { true, general.apply(unifier) }; + } +} + +/* Try and add a template class specialization corresponding to "kind". + * The new specialization needs to be a specialization of both + * the current specialization and "kind". + * + * The current template class specialization is known not to be a special case + * of "kind". + * + * Try and unify the two kinds and, if this succeeds, add the result + * to this list of template class specializations. + */ +void template_cpp_generator::class_printer::add_specialization( + const Kind &kind) +{ + auto maybe_unified = unify(kind, instance.kind); + + if (!maybe_unified.first) + return; + instance.template_class.add_specialization(maybe_unified.second); +} + +/* Does the type of the parameter at position "i" of "method" necessarily + * have a final Anonymous tuple? + * + * If the parameter is not of an isl type or if no specializations + * have been defined for the type, then it can be considered anonymous. + * Otherwise, if any specialization represents an anonymous function, + * then every specialization does, so simply check + * the first specialization. + */ +static bool param_is_anon(const Method &method, int i) +{ + ParmVarDecl *param = method.get_param(i); + QualType type = param->getOriginalType(); + + if (cpp_generator::is_isl_type(type)) { + const auto &name = type->getPointeeType().getAsString(); + const auto &cpp = cpp_generator::type2cpp(name); + const auto &tuples = lookup_class_tuples(cpp); + + if (tuples.empty()) + return true; + return tuples[0].is_anon(); + } + + return true; +} + +/* Replace the final tuple of "arg_kind" by Anonymous in "sig" and + * return the update signature, + * unless this would affect the class instance "instance_kind". + * + * If the original "instance_kind" is a special case + * of the result of the substitution, then "instance_kind" + * is not affected and the substitution can be applied + * to the entire signature. + */ +static Signature specialize_anonymous_arg(const Signature &sig, + const Kind &arg_kind, const Kind &instance_kind) +{ + const auto &subs = compute_unifier(arg_kind.back(), Anonymous); + const auto &specialized_instance = instance_kind.apply(subs); + + if (!specializer(specialized_instance, instance_kind).first) + return sig; + + return sig.apply(subs); +} + +/* If any of the arguments of "method" is of a type that necessarily + * has a final Anonymous tuple, but the corresponding entry + * in the signature "sig" is not Anonymous, then replace + * that entry by Anonymous and return the updated signature, + * unless this would affect the class instance "instance_kind". + */ +static Signature specialize_anonymous_args(const Signature &sig, + const Method &method, const Kind &instance_kind) +{ + auto specialized_sig = sig; + + method.on_cpp_arg_list([&] (int i, int arg) { + const auto &arg_kind = sig.args[arg]; + + if (arg_kind.is_anon()) + return; + if (!param_is_anon(method, i)) + return; + specialized_sig = specialize_anonymous_arg(specialized_sig, + arg_kind, instance_kind); + }); + + return specialized_sig; +} + +/* Print a declaration or definition of the method "method" + * if the template class specialization matches "match_arg". + * Return true if so. + * "sig" is the complete signature, of which "match_arg" refers + * to the first argument or the return type. + * + * Since "sig" may have parameters with the same names as + * those in instance.kind, rename them apart first. + * + * If the template class specialization is a special case of + * (the renamed) "match_arg" + * then apply the specializer to the complete (renamed) signature, + * specialize any anonymous arguments, + * check that the return kind is allowed and, if so, + * print the declaration or definition using the specialized signature. + * + * If the template class specialization is not a special case of "match_arg" + * then add a further specialization to the list of specializations + * of the template class. + */ +bool template_cpp_generator::class_printer::print_matching_method( + const Method &method, const Signature &sig, const Kind &match_arg) +{ + auto rename = shared_param_renamer(sig, instance.kind); + auto renamed_arg = match_arg.apply(rename); + auto maybe_specializer = specializer(renamed_arg, instance.kind); + if (maybe_specializer.first) { + const auto &specializer = maybe_specializer.second; + auto specialized_sig = sig.apply(rename).apply(specializer); + specialized_sig = specialize_anonymous_args(specialized_sig, + method, instance.kind); + if (!is_return_kind(method, specialized_sig.ret)) + return false; + + print_method_sig(method, specialized_sig, false); + } else { + add_specialization(match_arg); + } + return maybe_specializer.first; +} + +/* Is the first argument of "method" of type "isl_ctx *"? + */ +static bool first_arg_is_ctx(const Method &method) +{ + return generator::first_arg_is_isl_ctx(method.fd); +} + +/* Is the first signature argument set to { Ctx }? + */ +static bool first_kind_is_ctx(const Signature &sig) +{ + return sig.args[0].size() > 0 && sig.args[0][0] == Ctx; +} + +/* Print a declaration or definition of the member method "method" + * if it matches the signature "sig". + * Return true if so. + * + * First determine the part of the signature that needs to match + * the template class specialization and + * check that it has the same number of template arguments. + * Also check that the number of arguments of the signature + * matches that of the method. + * If there is at least one argument, then check that the first method argument + * is an isl_ctx if and only if the first signature argument is Ctx. + * + * If these tests succeed, proceed with the actual matching. + */ +bool template_cpp_generator::class_printer::print_matching_method( + const Method &method, const Signature &sig) +{ + auto match_arg = matching_kind(method, sig); + int n_args = sig.args.size(); + + if (match_arg.size() != instance.kind.size()) + return false; + if (n_args != total_params(method)) + return false; + if (n_args > 0 && first_arg_is_ctx(method) != first_kind_is_ctx(sig)) + return false; + + return print_matching_method(method, sig, match_arg); +} + +/* Print a declaration or definition of the member method "method" + * for each matching signature in "signatures". + * + * If there is no matching signature in "signatures", + * then explicitly delete the method (using a signature based on + * the specialization) so that it is not inherited from the base class. + */ +void template_cpp_generator::class_printer::print_matching_method( + const Method &method, const std::vector &signatures) +{ + auto any = false; + + for (const auto &sig : signatures) + if (print_matching_method(method, sig)) + any = true; + + if (!any) + print_method_sig(method, instance_sig(method, instance), true); +} + +/* Signatures for "at" methods applied to a multi-expression, + * which make the final tuple anonymous. + */ +static Signature select_set = { { Anonymous }, { { Domain }, { Integer } } }; +static Signature select_map = + { { Domain, Anonymous }, { { Domain, Range }, { Integer } } }; +static std::vector at_select = { select_set, select_map }; + +/* Signatures for other "at" methods applied to a list, + * which do not modify the tuple kind. + */ +static Signature bin_set_int = { { Domain }, { { Domain }, { Integer } } }; +static Signature bin_map_int = + { { Domain, Range }, { { Domain, Range }, { Integer } } }; +static std::vector at_keep = { bin_set_int, bin_map_int }; + +/* Print a declaration or definition of the "at" member method "method". + * + * There are two types of methods called "at". + * One type extracts an element from a multi-expression and + * the other extracts an element from a list. + * + * In the first case, the return type is an anonymous function + * while the object type is not. In this case, the return kind + * should have a final Anonymous tuple. + * Otherwise, the return kind should be the same as the object kind. + */ +void template_cpp_generator::class_printer::print_at_method( + const Method &method) +{ + auto anon = instance.template_class.is_anon(); + auto return_type = plain_return_type(method); + auto return_class = generator.template_classes.at(return_type); + + if (!anon && return_class.is_anon()) + return print_matching_method(method, at_select); + else + return print_matching_method(method, at_keep); +} + +/* Does the string "s" contain "sub" as a substring? + */ +static bool contains(const std::string &s, const std::string &sub) +{ + return s.find(sub) != std::string::npos; +} + +/* Print a declaration or definition of the member method "method", + * if it has a special signature in "special_methods". + * Return true if this is the case. + * + * Check if any special signatures are specified for this method and + * if the class name matches any of those with special signatures. + * If so, pick the one with the best match, i.e., the first match + * since the largest keys appear first. + */ +bool template_cpp_generator::class_printer::print_special_method( + const Method &method, const infix_map_map &special_methods) +{ + if (special_methods.count(method.name) == 0) + return false; + + for (const auto &kvp : special_methods.at(method.name)) { + if (!contains(instance.template_class.class_name, kvp.first)) + continue; + print_matching_method(method, kvp.second); + return true; + } + + return false; +} + +/* Print a declaration or definition of the member method "method", + * if it has a special signature specified by special_member_methods. + * Return true if this is the case. + */ +bool template_cpp_generator::class_printer::print_special_member_method( + const Method &method) +{ + return print_special_method(method, special_member_methods); +} + +/* Print a declaration or definition of the member method "method", + * if it is named after a template class. Return true if this is the case. + */ +bool template_cpp_generator::class_printer::print_type_named_member_method( + const Method &method) +{ + if (generator.template_classes.count(method.name) == 0) + return false; + + print_matching_method(method, constructor_sig); + + return true; +} + +/* Print a declaration or definition of the member method "method" + * using a signature associated to method name "name", if there is any. + * Return true if this is the case. + */ +bool template_cpp_generator::class_printer::print_member_method_with_name( + const Method &method, const std::string &name) +{ + if (member_methods.count(name) == 0) + return false; + + print_matching_method(method, member_methods.at(name)); + return true; +} + +/* If "sub" appears inside "str", then remove the first occurrence and + * return the result. Otherwise, simply return "str". + */ +static std::string drop_occurrence(const std::string &str, + const std::string &sub) +{ + auto res = str; + auto pos = str.find(sub); + + if (pos != std::string::npos) + res.erase(pos, sub.length()); + + return res; +} + +/* If "sub" appears in "str" next to an underscore, then remove the combination. + * Otherwise, simply return "str". + */ +static std::string drop_underscore_occurrence(const std::string &str, + const std::string &sub) +{ + auto res = drop_occurrence(str, sub + "_"); + if (res != str) + return res; + return drop_occurrence(res, std::string("_") + sub); +} + +/* Return the name of "method", with the name of the return type, + * along with an underscore, removed, if this combination appears in the name. + * Otherwise, simply return the name. + */ +const std::string name_without_return(const Method &method) +{ + auto return_infix = plain_return_type(method); + return drop_underscore_occurrence(method.name, return_infix); +} + +/* If this method has a callback, then remove the type + * of the first argument of the first callback from the name of the method. + * Otherwise, simply return the name of the method. + */ +const std::string callback_name(const Method &method) +{ + if (method.callbacks.size() == 0) + return method.name; + + auto type = method.callbacks.at(0)->getType(); + auto callback = cpp_generator::extract_prototype(type); + auto arg_type = plain_type(callback->getArgType(0)); + return generator::drop_suffix(method.name, "_" + arg_type); +} + +/* Print a declaration or definition of the member method "method". + * + * If the method is called "at", then it requires special treatment. + * Otherwise, check if the signature is overridden for this class or + * if the method is named after some other type. + * Otherwise look for an appropriate signature using different variations + * of the method name. First try the method name itself, + * then the method name with the return type removed and + * finally the method name with the callback argument type removed. + */ +void template_cpp_generator::class_printer::print_member_method( + const Method &method) +{ + if (method.name == "at") + return print_at_method(method); + if (print_special_member_method(method)) + return; + if (print_type_named_member_method(method)) + return; + if (print_member_method_with_name(method, method.name)) + return; + if (print_member_method_with_name(method, name_without_return(method))) + return; + if (print_member_method_with_name(method, callback_name(method))) + return; +} + +/* Print a declaration or definition of "method" based on its type. + */ +void template_cpp_generator::class_printer::print_any_method( + const Method &method) +{ + switch (method.kind) { + case Method::Kind::static_method: + print_static_method(method); + break; + case Method::Kind::constructor: + print_constructor(method); + break; + case Method::Kind::member_method: + print_member_method(method); + break; + } +} + +/* Print a declaration or definition of "method". + * + * Mark the method as not requiring copies of the arguments. + */ +void template_cpp_generator::class_printer::print_method(const Method &method) +{ + print_any_method(NoCopyMethod(method)); +} + +/* Print a declaration or definition of "method". + * + * Note that a ConversionMethod is already marked + * as not requiring copies of the arguments. + */ +void template_cpp_generator::class_printer::print_method( + const ConversionMethod &method) +{ + print_any_method(method); +} + +/* Helper class for printing the declarations for + * template class specializations. + */ +struct template_cpp_generator::class_decl_printer : + public specialization_printer +{ + class_decl_printer(std::ostream &os, + template_cpp_generator &generator) : + specialization_printer(os, generator) {} + + void print_arg_subclass_constructor(const specialization &instance, + const std::vector ¶ms) const; + void print_super_constructor(const specialization &instance) const; + virtual void print_class(const specialization &instance) const override; +}; + +/* Print the declaration and definition of a constructor + * for the template class specialization "instance" taking + * an instance with more specialized template arguments, + * where "params" holds the template parameters of "instance". + * It is assumed that there is at least one template parameter as otherwise + * there are no template arguments to be specialized and + * no constructor needs to be printed. + * + * In particular, the constructor takes an object of the same instance where + * for each template parameter, the corresponding template argument + * of the input object is a subclass of the template argument + * of the constructed object. + * + * Pick fresh names for all template parameters and + * add a constructor with these fresh names as extra template parameters and + * a constraint requiring that each of them is a subclass + * of the corresponding class template parameter. + * The plain C++ interface object of the constructed object is initialized with + * the plain C++ interface object of the constructor argument. + */ +void template_cpp_generator::class_decl_printer::print_arg_subclass_constructor( + const specialization &instance, + const std::vector ¶ms) const +{ + const auto &class_name = instance.class_name(); + auto rename = param_renamer(params, "Arg"); + auto derived = instance.kind.apply(rename); + + os << " template "; + os << "<"; + print_pure_template_args(os, derived.params()); + os << ",\n"; + os << " typename std::enable_if<\n"; + for (size_t i = 0; i < params.size(); ++i) { + if (i != 0) + os << " &&\n"; + os << " std::is_base_of<" + << params[i] << ", " + << rename.at(params[i])->params()[0] << ">{}"; + } + os << ",\n"; + os << " bool>::type = true>"; + os << "\n"; + os << " " << class_name << "(const "; + print_bare_template_type(os, class_name, derived); + os << " &obj) : " << instance.base_name() << "(obj) {}\n"; +} + +/* Print the declaration and definition of a constructor + * for the template class specialization "instance" taking + * an instance of the base class. + * + * If the instance kind is that of an anonymous set + * (i.e., it has a single tuple that is set to Anonymous), + * then allow the constructor to be called externally. + * This is mostly useful for being able to use isl::val and + * isl::typed::val interchangeably and similarly for isl::id. + * + * If the instance is of any other kind, then make this constructor private + * to avoid objects of the plain interface being converted automatically. + * Also make sure that it does not apply to any type derived + * from the base class. In particular, this makes sure it does + * not apply to any other specializations of this template class as + * otherwise any conflict in specializations would simply point + * to the private constructor. + * + * A factory method is added to be able to perform the conversion explicitly, + * with an explicit specification of the template arguments. + */ +void template_cpp_generator::class_decl_printer::print_super_constructor( + const specialization &instance) const +{ + bool hide = !instance.kind.is_anon_set(); + const auto &base_name = instance.base_name(); + const auto &arg_name = hide ? "base" : base_name; + + if (hide) { + os << " private:\n"; + os << " template {}, bool>::type = true>\n"; + } + os << " " << instance.class_name() + << "(const " << arg_name << " &obj) : " + << base_name << "(obj) {}\n"; + if (hide) + os << " public:\n"; + os << " static " << instance.class_name() << " from" + << "(const " << base_name << " &obj) {\n"; + os << " return " << instance.class_name() << "(obj);\n"; + os << " }\n"; +} + +/* Print a "declaration" for the given template class specialization. + * In particular, print the class definition and the method declarations. + * + * The template parameters are the distinct variable names + * in the instance kind. + * + * Each instance of the template class derives from the corresponding + * plain C++ interface class. + * + * All (other) template classes are made friends of this template class + * to allow them to call the private constructor taking an object + * of the plain interface. + * + * Besides the constructors and methods that forward + * to the corresponding methods in the plain C++ interface class, + * some extra constructors are defined. + * The default zero-argument constructor is useful for declaring + * a variable that only gets assigned a value at a later stage. + * The constructor taking an instance with more specialized + * template arguments is useful for lifting the class hierarchy + * of the template arguments to the template class. + * The constructor taking an instance of the base class + * is useful for (explicitly) constructing a template type + * from a plain type. + */ +void template_cpp_generator::class_decl_printer::print_class( + const specialization &instance) const +{ + const auto &class_name = instance.class_name(); + auto params = instance.kind.params(); + + os << "\n"; + + print_template(os, params); + + os << "struct "; + print_bare_template_type(os, class_name, instance.kind); + os << " : public " << instance.base_name() << " {\n"; + + generator.print_friends(os); + os << "\n"; + + os << " " << class_name << "() = default;\n"; + if (params.size() != 0) + print_arg_subclass_constructor(instance, params); + print_super_constructor(instance); + method_decl_printer(instance, *this).print_all_methods(); + + os << "};\n"; +} + +/* Helper class for printing the definitions of template class specializations. + */ +struct template_cpp_generator::class_impl_printer : + public specialization_printer +{ + class_impl_printer(std::ostream &os, + template_cpp_generator &generator) : + specialization_printer(os, generator) {} + + virtual void print_class(const specialization &instance) const override; +}; + +/* Print a definition for the given template class specialization. + * + * In particular, print definitions + * for the constructors and methods that forward + * to the corresponding methods in the plain C++ interface class. + * The extra constructors declared in the class definition + * are defined inline. + */ +void template_cpp_generator::class_impl_printer::print_class( + const specialization &instance) const +{ + method_impl_printer(instance, *this).print_all_methods(); +} + +/* Generate a templated cpp interface + * based on the extracted types and functions. + * + * First print forward declarations for all template classes, + * then the declarations of the classes, and at the end all + * method implementations. + */ +void template_cpp_generator::generate() +{ + ostream &os = std::cout; + + os << "\n"; + + print_forward_declarations(os); + class_decl_printer(os, *this).print_classes(); + class_impl_printer(os, *this).print_classes(); +} diff --git a/external/mit/isl/dist/interface/template_cpp.h b/external/mit/isl/dist/interface/template_cpp.h new file mode 100644 index 000000000000..ae3315d812d6 --- /dev/null +++ b/external/mit/isl/dist/interface/template_cpp.h @@ -0,0 +1,118 @@ +#ifndef ISL_INTERFACE_TEMPLATE_CPP_H +#define ISL_INTERFACE_TEMPLATE_CPP_H + +#include +#include +#include +#include +#include +#include +#include + +#include "cpp.h" + +struct Fixed; + +struct TupleKind; + +/* A shared pointer to a TupleKind. + */ +struct TupleKindPtr : public std::shared_ptr { + using Base = std::shared_ptr; + TupleKindPtr() = default; + TupleKindPtr(Fixed); + TupleKindPtr(Base base) : Base(base) {} + TupleKindPtr(const std::string &name); + TupleKindPtr(const TupleKindPtr &left, const TupleKindPtr &right); +}; + +/* A substitution mapping leaf tuple kind names to tuple kinds. + */ +using Substitution = std::unordered_map; + +/* A representation of a (possibly improper) tuple kind. + * That is, this also includes tuple kinds for types + * that do not have any tuples. + * + * The kind could be a name (the base case) or + * a (currently) unnamed nested pair of tuple kinds. + */ +struct TupleKind { + TupleKind(const std::string &name) : name(name) {} + + virtual std::string to_string() const; + virtual std::vector params() const; + virtual TupleKindPtr apply(const Substitution &subs, + const TupleKindPtr &self) const; + virtual TupleKindPtr left() const; + virtual TupleKindPtr right() const; + + const std::string name; +}; + +/* A sequence of tuple kinds, representing a kind of objects. + */ +struct Kind : public std::vector { + Kind() {} + Kind(std::initializer_list list) : vector(list) {} + + bool is_anon() const; + bool is_set() const; + bool is_anon_set() const; + std::vector params() const; + Kind apply(const Substitution &subs) const; +}; + +/* A representation of a template class. + * + * "class_name" is the name of the template class. + * "super_name" is the (fully qualified) name of the corresponding + * plain C++ interface class, from which this template class derives. + * "clazz" describes the plain class. + * + * "class_tuples" contains the specializations. + * It is initialized with a predefined set of specializations, + * but may be extended during the generations of the specializations. + */ +struct template_class { + const std::string class_name; + const std::string super_name; + const isl_class &clazz; + + std::vector class_tuples; + + bool is_anon() const; + bool is_anon_set() const; + void add_specialization(const Kind &kind); +}; + +/* A generator for templated C++ bindings. + * + * "template_classes" contains all generated template classes, + * keyed on their names. + */ +class template_cpp_generator : public cpp_generator { + struct class_printer; + struct method_decl_printer; + struct method_impl_printer; + struct class_decl_printer; + struct class_impl_printer; + + void add_template_class(const isl_class &clazz, const std::string &name, + const std::vector &class_tuples); +public: + template_cpp_generator(clang::SourceManager &SM, + std::set &exported_types, + std::set exported_functions, + std::set functions); + + virtual void generate() override; + void foreach_template_class( + const std::function &fn) const; + void print_forward_declarations(std::ostream &os); + void print_friends(std::ostream &os); + + std::map template_classes; +}; + +#endif diff --git a/external/mit/isl/dist/isl_aff.c b/external/mit/isl/dist/isl_aff.c new file mode 100644 index 000000000000..2635c2ccf680 --- /dev/null +++ b/external/mit/isl/dist/isl_aff.c @@ -0,0 +1,10126 @@ +/* + * Copyright 2011 INRIA Saclay + * Copyright 2011 Sven Verdoolaege + * Copyright 2012-2014 Ecole Normale Superieure + * Copyright 2014 INRIA Rocquencourt + * Copyright 2016 Sven Verdoolaege + * Copyright 2018,2020 Cerebras Systems + * Copyright 2021 Sven Verdoolaege + * Copyright 2022 Cerebras Systems + * + * 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 + * and Inria Paris - Rocquencourt, Domaine de Voluceau - Rocquencourt, + * B.P. 105 - 78153 Le Chesnay, France + * and Cerebras Systems, 175 S San Antonio Rd, Los Altos, CA, USA + * and Cerebras Systems, 1237 E Arques Ave, Sunnyvale, CA, USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#undef EL_BASE +#define EL_BASE aff + +#include +#include + +#undef EL_BASE +#define EL_BASE pw_aff + +#include +#include + +#undef EL_BASE +#define EL_BASE pw_multi_aff + +#include +#include + +#undef EL_BASE +#define EL_BASE union_pw_aff + +#include +#include + +#undef EL_BASE +#define EL_BASE union_pw_multi_aff + +#include + +/* Construct an isl_aff from the given domain local space "ls" and + * coefficients "v", where the local space is known to be valid + * for an affine expression. + */ +static __isl_give isl_aff *isl_aff_alloc_vec_validated( + __isl_take isl_local_space *ls, __isl_take isl_vec *v) +{ + isl_aff *aff; + + if (!ls || !v) + goto error; + + aff = isl_calloc_type(v->ctx, struct isl_aff); + if (!aff) + goto error; + + aff->ref = 1; + aff->ls = ls; + aff->v = v; + + return aff; +error: + isl_local_space_free(ls); + isl_vec_free(v); + return NULL; +} + +/* Construct an isl_aff from the given domain local space "ls" and + * coefficients "v". + * + * First check that "ls" is a valid domain local space + * for an affine expression. + */ +__isl_give isl_aff *isl_aff_alloc_vec(__isl_take isl_local_space *ls, + __isl_take isl_vec *v) +{ + isl_ctx *ctx; + + if (!ls) + return NULL; + + ctx = isl_local_space_get_ctx(ls); + if (!isl_local_space_divs_known(ls)) + isl_die(ctx, isl_error_invalid, "local space has unknown divs", + goto error); + if (!isl_local_space_is_set(ls)) + isl_die(ctx, isl_error_invalid, + "domain of affine expression should be a set", + goto error); + return isl_aff_alloc_vec_validated(ls, v); +error: + isl_local_space_free(ls); + isl_vec_free(v); + return NULL; +} + +__isl_give isl_aff *isl_aff_alloc(__isl_take isl_local_space *ls) +{ + isl_ctx *ctx; + isl_vec *v; + isl_size total; + + if (!ls) + return NULL; + + ctx = isl_local_space_get_ctx(ls); + + total = isl_local_space_dim(ls, isl_dim_all); + if (total < 0) + goto error; + v = isl_vec_alloc(ctx, 1 + 1 + total); + return isl_aff_alloc_vec(ls, v); +error: + isl_local_space_free(ls); + return NULL; +} + +__isl_give isl_aff *isl_aff_copy(__isl_keep isl_aff *aff) +{ + if (!aff) + return NULL; + + aff->ref++; + return aff; +} + +__isl_give isl_aff *isl_aff_dup(__isl_keep isl_aff *aff) +{ + if (!aff) + return NULL; + + return isl_aff_alloc_vec_validated(isl_local_space_copy(aff->ls), + isl_vec_copy(aff->v)); +} + +__isl_give isl_aff *isl_aff_cow(__isl_take isl_aff *aff) +{ + if (!aff) + return NULL; + + if (aff->ref == 1) + return aff; + aff->ref--; + return isl_aff_dup(aff); +} + +/* Return a copy of the rational affine expression of "aff". + */ +static __isl_give isl_vec *isl_aff_get_rat_aff(__isl_keep isl_aff *aff) +{ + if (!aff) + return NULL; + return isl_vec_copy(aff->v); +} + +/* Return the rational affine expression of "aff". + * This may be either a copy or the expression itself + * if there is only one reference to "aff". + * This allows the expression to be modified inplace + * if both the "aff" and its expression have only a single reference. + * The caller is not allowed to modify "aff" between this call and + * a subsequent call to isl_aff_restore_rat_aff. + * The only exception is that isl_aff_free can be called instead. + */ +static __isl_give isl_vec *isl_aff_take_rat_aff(__isl_keep isl_aff *aff) +{ + isl_vec *v; + + if (!aff) + return NULL; + if (aff->ref != 1) + return isl_aff_get_rat_aff(aff); + v = aff->v; + aff->v = NULL; + return v; +} + +/* Set the rational affine expression of "aff" to "v", + * where the rational affine expression of "aff" may be missing + * due to a preceding call to isl_aff_take_rat_aff. + * However, in this case, "aff" only has a single reference and + * then the call to isl_aff_cow has no effect. + */ +static __isl_give isl_aff *isl_aff_restore_rat_aff(__isl_keep isl_aff *aff, + __isl_take isl_vec *v) +{ + if (!aff || !v) + goto error; + + if (aff->v == v) { + isl_vec_free(v); + return aff; + } + + aff = isl_aff_cow(aff); + if (!aff) + goto error; + isl_vec_free(aff->v); + aff->v = v; + + return aff; +error: + isl_aff_free(aff); + isl_vec_free(v); + return NULL; +} + +__isl_give isl_aff *isl_aff_zero_on_domain(__isl_take isl_local_space *ls) +{ + isl_aff *aff; + + aff = isl_aff_alloc(ls); + if (!aff) + return NULL; + + isl_int_set_si(aff->v->el[0], 1); + isl_seq_clr(aff->v->el + 1, aff->v->size - 1); + + return aff; +} + +/* Return an affine expression that is equal to zero on domain space "space". + */ +__isl_give isl_aff *isl_aff_zero_on_domain_space(__isl_take isl_space *space) +{ + return isl_aff_zero_on_domain(isl_local_space_from_space(space)); +} + +/* This function performs the same operation as isl_aff_zero_on_domain_space, + * but is considered as a function on an isl_space when exported. + */ +__isl_give isl_aff *isl_space_zero_aff_on_domain(__isl_take isl_space *space) +{ + return isl_aff_zero_on_domain_space(space); +} + +/* Return a piecewise affine expression defined on the specified domain + * that is equal to zero. + */ +__isl_give isl_pw_aff *isl_pw_aff_zero_on_domain(__isl_take isl_local_space *ls) +{ + return isl_pw_aff_from_aff(isl_aff_zero_on_domain(ls)); +} + +/* Change "aff" into a NaN. + * + * Note that this function gets called from isl_aff_nan_on_domain, + * so "aff" may not have been initialized yet. + */ +static __isl_give isl_aff *isl_aff_set_nan(__isl_take isl_aff *aff) +{ + isl_vec *v; + + v = isl_aff_take_rat_aff(aff); + v = isl_vec_clr(v); + aff = isl_aff_restore_rat_aff(aff, v); + + return aff; +} + +/* Return an affine expression defined on the specified domain + * that represents NaN. + */ +__isl_give isl_aff *isl_aff_nan_on_domain(__isl_take isl_local_space *ls) +{ + isl_aff *aff; + + aff = isl_aff_alloc(ls); + return isl_aff_set_nan(aff); +} + +/* Return an affine expression defined on the specified domain space + * that represents NaN. + */ +__isl_give isl_aff *isl_aff_nan_on_domain_space(__isl_take isl_space *space) +{ + return isl_aff_nan_on_domain(isl_local_space_from_space(space)); +} + +/* Return a piecewise affine expression defined on the specified domain space + * that represents NaN. + */ +__isl_give isl_pw_aff *isl_pw_aff_nan_on_domain_space( + __isl_take isl_space *space) +{ + return isl_pw_aff_from_aff(isl_aff_nan_on_domain_space(space)); +} + +/* Return a piecewise affine expression defined on the specified domain + * that represents NaN. + */ +__isl_give isl_pw_aff *isl_pw_aff_nan_on_domain(__isl_take isl_local_space *ls) +{ + return isl_pw_aff_from_aff(isl_aff_nan_on_domain(ls)); +} + +/* Return an affine expression that is equal to "val" on + * domain local space "ls". + * + * Note that the encoding for the special value NaN + * is the same in isl_val and isl_aff, so this does not need + * to be treated in any special way. + */ +__isl_give isl_aff *isl_aff_val_on_domain(__isl_take isl_local_space *ls, + __isl_take isl_val *val) +{ + isl_aff *aff; + + if (!ls || !val) + goto error; + if (!isl_val_is_rat(val) && !isl_val_is_nan(val)) + isl_die(isl_val_get_ctx(val), isl_error_invalid, + "expecting rational value or NaN", goto error); + + aff = isl_aff_alloc(isl_local_space_copy(ls)); + if (!aff) + goto error; + + isl_seq_clr(aff->v->el + 2, aff->v->size - 2); + isl_int_set(aff->v->el[1], val->n); + isl_int_set(aff->v->el[0], val->d); + + isl_local_space_free(ls); + isl_val_free(val); + return aff; +error: + isl_local_space_free(ls); + isl_val_free(val); + return NULL; +} + +/* Return an affine expression that is equal to "val" on domain space "space". + */ +__isl_give isl_aff *isl_aff_val_on_domain_space(__isl_take isl_space *space, + __isl_take isl_val *val) +{ + return isl_aff_val_on_domain(isl_local_space_from_space(space), val); +} + +/* Return an affine expression that is equal to the specified dimension + * in "ls". + */ +__isl_give isl_aff *isl_aff_var_on_domain(__isl_take isl_local_space *ls, + enum isl_dim_type type, unsigned pos) +{ + isl_space *space; + isl_aff *aff; + + if (!ls) + return NULL; + + space = isl_local_space_get_space(ls); + if (!space) + goto error; + if (isl_space_is_map(space)) + isl_die(isl_space_get_ctx(space), isl_error_invalid, + "expecting (parameter) set space", goto error); + if (isl_local_space_check_range(ls, type, pos, 1) < 0) + goto error; + + isl_space_free(space); + aff = isl_aff_alloc(ls); + if (!aff) + return NULL; + + pos += isl_local_space_offset(aff->ls, type); + + isl_int_set_si(aff->v->el[0], 1); + isl_seq_clr(aff->v->el + 1, aff->v->size - 1); + isl_int_set_si(aff->v->el[1 + pos], 1); + + return aff; +error: + isl_local_space_free(ls); + isl_space_free(space); + return NULL; +} + +/* Return a piecewise affine expression that is equal to + * the specified dimension in "ls". + */ +__isl_give isl_pw_aff *isl_pw_aff_var_on_domain(__isl_take isl_local_space *ls, + enum isl_dim_type type, unsigned pos) +{ + 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; +} + +/* This function performs the same operation as + * isl_aff_param_on_domain_space_id, + * but is considered as a function on an isl_space when exported. + */ +__isl_give isl_aff *isl_space_param_aff_on_domain_id( + __isl_take isl_space *space, __isl_take isl_id *id) +{ + return isl_aff_param_on_domain_space_id(space, id); +} + +__isl_null isl_aff *isl_aff_free(__isl_take isl_aff *aff) +{ + if (!aff) + return NULL; + + if (--aff->ref > 0) + return NULL; + + isl_local_space_free(aff->ls); + isl_vec_free(aff->v); + + free(aff); + + return NULL; +} + +isl_ctx *isl_aff_get_ctx(__isl_keep isl_aff *aff) +{ + return aff ? isl_local_space_get_ctx(aff->ls) : NULL; +} + +/* Return a hash value that digests "aff". + */ +uint32_t isl_aff_get_hash(__isl_keep isl_aff *aff) +{ + uint32_t hash, ls_hash, v_hash; + + if (!aff) + return 0; + + hash = isl_hash_init(); + ls_hash = isl_local_space_get_hash(aff->ls); + isl_hash_hash(hash, ls_hash); + v_hash = isl_vec_get_hash(aff->v); + isl_hash_hash(hash, v_hash); + + return hash; +} + +/* Return the domain local space of "aff". + */ +static __isl_keep isl_local_space *isl_aff_peek_domain_local_space( + __isl_keep isl_aff *aff) +{ + return aff ? aff->ls : NULL; +} + +/* Return the number of variables of the given type in the domain of "aff". + */ +isl_size isl_aff_domain_dim(__isl_keep isl_aff *aff, enum isl_dim_type type) +{ + isl_local_space *ls; + + ls = isl_aff_peek_domain_local_space(aff); + return isl_local_space_dim(ls, type); +} + +/* Externally, an isl_aff has a map space, but internally, the + * ls field corresponds to the domain of that space. + */ +isl_size isl_aff_dim(__isl_keep isl_aff *aff, enum isl_dim_type type) +{ + if (!aff) + return isl_size_error; + if (type == isl_dim_out) + return 1; + if (type == isl_dim_in) + type = isl_dim_set; + return isl_aff_domain_dim(aff, type); +} + +/* Return the offset of the first coefficient of type "type" in + * the domain of "aff". + */ +isl_size isl_aff_domain_offset(__isl_keep isl_aff *aff, enum isl_dim_type type) +{ + isl_local_space *ls; + + ls = isl_aff_peek_domain_local_space(aff); + return isl_local_space_offset(ls, type); +} + +/* Return the position of the dimension of the given type and name + * in "aff". + * Return -1 if no such dimension can be found. + */ +int isl_aff_find_dim_by_name(__isl_keep isl_aff *aff, enum isl_dim_type type, + const char *name) +{ + if (!aff) + return -1; + if (type == isl_dim_out) + return -1; + if (type == isl_dim_in) + type = isl_dim_set; + return isl_local_space_find_dim_by_name(aff->ls, type, name); +} + +/* Return the domain space of "aff". + */ +static __isl_keep isl_space *isl_aff_peek_domain_space(__isl_keep isl_aff *aff) +{ + return aff ? isl_local_space_peek_space(aff->ls) : NULL; +} + +__isl_give isl_space *isl_aff_get_domain_space(__isl_keep isl_aff *aff) +{ + return isl_space_copy(isl_aff_peek_domain_space(aff)); +} + +__isl_give isl_space *isl_aff_get_space(__isl_keep isl_aff *aff) +{ + isl_space *space; + if (!aff) + return NULL; + space = isl_local_space_get_space(aff->ls); + space = isl_space_from_domain(space); + space = isl_space_add_dims(space, isl_dim_out, 1); + return space; +} + +/* Return a copy of the domain space of "aff". + */ +__isl_give isl_local_space *isl_aff_get_domain_local_space( + __isl_keep isl_aff *aff) +{ + return isl_local_space_copy(isl_aff_peek_domain_local_space(aff)); +} + +__isl_give isl_local_space *isl_aff_get_local_space(__isl_keep isl_aff *aff) +{ + isl_local_space *ls; + if (!aff) + return NULL; + ls = isl_local_space_copy(aff->ls); + ls = isl_local_space_from_domain(ls); + ls = isl_local_space_add_dims(ls, isl_dim_out, 1); + 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. + */ +const char *isl_aff_get_dim_name(__isl_keep isl_aff *aff, + enum isl_dim_type type, unsigned pos) +{ + if (!aff) + return NULL; + if (type == isl_dim_out) + return NULL; + if (type == isl_dim_in) + type = isl_dim_set; + return isl_local_space_get_dim_name(aff->ls, type, pos); +} + +__isl_give isl_aff *isl_aff_reset_domain_space(__isl_take isl_aff *aff, + __isl_take isl_space *space) +{ + aff = isl_aff_cow(aff); + if (!aff || !space) + goto error; + + aff->ls = isl_local_space_reset_space(aff->ls, space); + if (!aff->ls) + return isl_aff_free(aff); + + return aff; +error: + isl_aff_free(aff); + isl_space_free(space); + return NULL; +} + +/* Reset the space of "aff". 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. + */ +__isl_give isl_aff *isl_aff_reset_space_and_domain(__isl_take isl_aff *aff, + __isl_take isl_space *space, __isl_take isl_space *domain) +{ + isl_space_free(space); + return isl_aff_reset_domain_space(aff, domain); +} + +/* Reorder the dimensions of the domain of "aff" according + * to the given reordering. + */ +__isl_give isl_aff *isl_aff_realign_domain(__isl_take isl_aff *aff, + __isl_take isl_reordering *r) +{ + aff = isl_aff_cow(aff); + if (!aff) + goto error; + + r = isl_reordering_extend(r, aff->ls->div->n_row); + aff->v = isl_vec_reorder(aff->v, 2, isl_reordering_copy(r)); + aff->ls = isl_local_space_realign(aff->ls, r); + + if (!aff->v || !aff->ls) + return isl_aff_free(aff); + + return aff; +error: + isl_aff_free(aff); + isl_reordering_free(r); + return NULL; +} + +__isl_give isl_aff *isl_aff_align_params(__isl_take isl_aff *aff, + __isl_take isl_space *model) +{ + isl_space *domain_space; + isl_bool equal_params; + + domain_space = isl_aff_peek_domain_space(aff); + equal_params = isl_space_has_equal_params(domain_space, model); + if (equal_params < 0) + goto error; + if (!equal_params) { + isl_reordering *exp; + + exp = isl_parameter_alignment_reordering(domain_space, model); + aff = isl_aff_realign_domain(aff, exp); + } + + isl_space_free(model); + return aff; +error: + isl_space_free(model); + isl_aff_free(aff); + return NULL; +} + +#undef TYPE +#define TYPE isl_aff +#include "isl_unbind_params_templ.c" + +/* Is "aff" obviously equal to zero? + * + * If the denominator is zero, then "aff" is not equal to zero. + */ +isl_bool isl_aff_plain_is_zero(__isl_keep isl_aff *aff) +{ + int pos; + + if (!aff) + return isl_bool_error; + + if (isl_int_is_zero(aff->v->el[0])) + return isl_bool_false; + pos = isl_seq_first_non_zero(aff->v->el + 1, aff->v->size - 1); + return isl_bool_ok(pos < 0); +} + +/* Does "aff" represent NaN? + */ +isl_bool isl_aff_is_nan(__isl_keep isl_aff *aff) +{ + if (!aff) + return isl_bool_error; + + return isl_bool_ok(isl_seq_first_non_zero(aff->v->el, 2) < 0); +} + +/* Are "aff1" and "aff2" obviously equal? + * + * NaN is not equal to anything, not even to another NaN. + */ +isl_bool isl_aff_plain_is_equal(__isl_keep isl_aff *aff1, + __isl_keep isl_aff *aff2) +{ + isl_bool equal; + + if (!aff1 || !aff2) + return isl_bool_error; + + if (isl_aff_is_nan(aff1) || isl_aff_is_nan(aff2)) + return isl_bool_false; + + equal = isl_local_space_is_equal(aff1->ls, aff2->ls); + if (equal < 0 || !equal) + return equal; + + return isl_vec_is_equal(aff1->v, aff2->v); +} + +/* Return the common denominator of "aff" in "v". + * + * We cannot return anything meaningful in case of a NaN. + */ +isl_stat isl_aff_get_denominator(__isl_keep isl_aff *aff, isl_int *v) +{ + if (!aff) + return isl_stat_error; + if (isl_aff_is_nan(aff)) + isl_die(isl_aff_get_ctx(aff), isl_error_invalid, + "cannot get denominator of NaN", return isl_stat_error); + isl_int_set(*v, aff->v->el[0]); + return isl_stat_ok; +} + +/* Return the common denominator of "aff". + */ +__isl_give isl_val *isl_aff_get_denominator_val(__isl_keep isl_aff *aff) +{ + isl_ctx *ctx; + + if (!aff) + return NULL; + + ctx = isl_aff_get_ctx(aff); + if (isl_aff_is_nan(aff)) + return isl_val_nan(ctx); + return isl_val_int_from_isl_int(ctx, aff->v->el[0]); +} + +/* Return the constant term of "aff". + */ +__isl_give isl_val *isl_aff_get_constant_val(__isl_keep isl_aff *aff) +{ + isl_ctx *ctx; + isl_val *v; + + if (!aff) + return NULL; + + ctx = isl_aff_get_ctx(aff); + if (isl_aff_is_nan(aff)) + return isl_val_nan(ctx); + v = isl_val_rat_from_isl_int(ctx, aff->v->el[1], aff->v->el[0]); + return isl_val_normalize(v); +} + +/* Return the coefficient of the variable of type "type" at position "pos" + * of "aff". + */ +__isl_give isl_val *isl_aff_get_coefficient_val(__isl_keep isl_aff *aff, + enum isl_dim_type type, int pos) +{ + isl_ctx *ctx; + isl_val *v; + + if (!aff) + return NULL; + + ctx = isl_aff_get_ctx(aff); + if (type == isl_dim_out) + isl_die(ctx, isl_error_invalid, + "output/set dimension does not have a coefficient", + return NULL); + if (type == isl_dim_in) + type = isl_dim_set; + + if (isl_local_space_check_range(aff->ls, type, pos, 1) < 0) + return NULL; + + if (isl_aff_is_nan(aff)) + return isl_val_nan(ctx); + pos += isl_local_space_offset(aff->ls, type); + v = isl_val_rat_from_isl_int(ctx, aff->v->el[1 + pos], aff->v->el[0]); + return isl_val_normalize(v); +} + +/* Return the sign of the coefficient of the variable of type "type" + * at position "pos" of "aff". + */ +int isl_aff_coefficient_sgn(__isl_keep isl_aff *aff, enum isl_dim_type type, + int pos) +{ + isl_ctx *ctx; + + if (!aff) + return 0; + + ctx = isl_aff_get_ctx(aff); + if (type == isl_dim_out) + isl_die(ctx, isl_error_invalid, + "output/set dimension does not have a coefficient", + return 0); + if (type == isl_dim_in) + type = isl_dim_set; + + if (isl_local_space_check_range(aff->ls, type, pos, 1) < 0) + return 0; + + pos += isl_local_space_offset(aff->ls, type); + return isl_int_sgn(aff->v->el[1 + pos]); +} + +/* Replace the numerator of the constant term of "aff" by "v". + * + * A NaN is unaffected by this operation. + */ +__isl_give isl_aff *isl_aff_set_constant(__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[1], v); + + return aff; +} + +/* Replace the constant term of "aff" by "v". + * + * A NaN is unaffected by this operation. + */ +__isl_give isl_aff *isl_aff_set_constant_val(__isl_take isl_aff *aff, + __isl_take isl_val *v) +{ + if (!aff || !v) + goto error; + + if (isl_aff_is_nan(aff)) { + isl_val_free(v); + return aff; + } + + if (!isl_val_is_rat(v)) + isl_die(isl_aff_get_ctx(aff), isl_error_invalid, + "expecting rational value", goto error); + + if (isl_int_eq(aff->v->el[1], v->n) && + isl_int_eq(aff->v->el[0], v->d)) { + isl_val_free(v); + return aff; + } + + aff = isl_aff_cow(aff); + if (!aff) + goto error; + aff->v = isl_vec_cow(aff->v); + if (!aff->v) + goto error; + + if (isl_int_eq(aff->v->el[0], v->d)) { + isl_int_set(aff->v->el[1], v->n); + } else if (isl_int_is_one(v->d)) { + isl_int_mul(aff->v->el[1], aff->v->el[0], v->n); + } else { + isl_seq_scale(aff->v->el + 1, + aff->v->el + 1, v->d, aff->v->size - 1); + isl_int_mul(aff->v->el[1], aff->v->el[0], v->n); + isl_int_mul(aff->v->el[0], aff->v->el[0], v->d); + aff->v = isl_vec_normalize(aff->v); + if (!aff->v) + goto error; + } + + isl_val_free(v); + return aff; +error: + isl_aff_free(aff); + isl_val_free(v); + return NULL; +} + +/* Add "v" to the constant term of "aff". + * + * A NaN is unaffected by this operation. + */ +__isl_give isl_aff *isl_aff_add_constant(__isl_take isl_aff *aff, isl_int v) +{ + if (isl_int_is_zero(v)) + return aff; + + 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_addmul(aff->v->el[1], aff->v->el[0], v); + + return aff; +} + +/* Add "v" to the constant term of "aff", + * in case "aff" is a rational expression. + */ +static __isl_give isl_aff *isl_aff_add_rat_constant_val(__isl_take isl_aff *aff, + __isl_take isl_val *v) +{ + aff = isl_aff_cow(aff); + if (!aff) + goto error; + + aff->v = isl_vec_cow(aff->v); + if (!aff->v) + goto error; + + if (isl_int_is_one(v->d)) { + isl_int_addmul(aff->v->el[1], aff->v->el[0], v->n); + } else if (isl_int_eq(aff->v->el[0], v->d)) { + isl_int_add(aff->v->el[1], aff->v->el[1], v->n); + aff->v = isl_vec_normalize(aff->v); + if (!aff->v) + goto error; + } else { + isl_seq_scale(aff->v->el + 1, + aff->v->el + 1, v->d, aff->v->size - 1); + isl_int_addmul(aff->v->el[1], aff->v->el[0], v->n); + isl_int_mul(aff->v->el[0], aff->v->el[0], v->d); + aff->v = isl_vec_normalize(aff->v); + if (!aff->v) + goto error; + } + + isl_val_free(v); + return aff; +error: + isl_aff_free(aff); + isl_val_free(v); + return NULL; +} + +/* Return the first argument and free the second. + */ +static __isl_give isl_aff *pick_free(__isl_take isl_aff *aff, + __isl_take isl_val *v) +{ + isl_val_free(v); + return aff; +} + +/* Replace the first argument by NaN and free the second argument. + */ +static __isl_give isl_aff *set_nan_free_val(__isl_take isl_aff *aff, + __isl_take isl_val *v) +{ + isl_val_free(v); + return isl_aff_set_nan(aff); +} + +/* Add "v" to the constant term of "aff". + * + * A NaN is unaffected by this operation. + * Conversely, adding a NaN turns "aff" into a NaN. + */ +__isl_give isl_aff *isl_aff_add_constant_val(__isl_take isl_aff *aff, + __isl_take isl_val *v) +{ + isl_bool is_nan, is_zero, is_rat; + + is_nan = isl_aff_is_nan(aff); + is_zero = isl_val_is_zero(v); + if (is_nan < 0 || is_zero < 0) + goto error; + if (is_nan || is_zero) + return pick_free(aff, v); + + is_nan = isl_val_is_nan(v); + is_rat = isl_val_is_rat(v); + if (is_nan < 0 || is_rat < 0) + goto error; + if (is_nan) + return set_nan_free_val(aff, v); + if (!is_rat) + isl_die(isl_aff_get_ctx(aff), isl_error_invalid, + "expecting rational value or NaN", goto error); + + return isl_aff_add_rat_constant_val(aff, v); +error: + isl_aff_free(aff); + isl_val_free(v); + return NULL; +} + +__isl_give isl_aff *isl_aff_add_constant_si(__isl_take isl_aff *aff, int v) +{ + isl_int t; + + isl_int_init(t); + isl_int_set_si(t, v); + aff = isl_aff_add_constant(aff, t); + isl_int_clear(t); + + return aff; +} + +/* Add "v" to the numerator of the constant term of "aff". + * + * A NaN is unaffected by this operation. + */ +__isl_give isl_aff *isl_aff_add_constant_num(__isl_take isl_aff *aff, isl_int v) +{ + if (isl_int_is_zero(v)) + return aff; + + 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_add(aff->v->el[1], aff->v->el[1], v); + + return aff; +} + +/* Add "v" to the numerator of the constant term of "aff". + * + * A NaN is unaffected by this operation. + */ +__isl_give isl_aff *isl_aff_add_constant_num_si(__isl_take isl_aff *aff, int v) +{ + isl_int t; + + if (v == 0) + return aff; + + isl_int_init(t); + isl_int_set_si(t, v); + aff = isl_aff_add_constant_num(aff, t); + isl_int_clear(t); + + return aff; +} + +/* Replace the numerator of the constant term of "aff" by "v". + * + * A NaN is unaffected by this operation. + */ +__isl_give isl_aff *isl_aff_set_constant_si(__isl_take isl_aff *aff, 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_si(aff->v->el[1], v); + + return aff; +} + +/* Replace the numerator of the coefficient of the variable of type "type" + * at position "pos" of "aff" by "v". + * + * A NaN is unaffected by this operation. + */ +__isl_give isl_aff *isl_aff_set_coefficient(__isl_take isl_aff *aff, + enum isl_dim_type type, int pos, isl_int v) +{ + if (!aff) + return NULL; + + if (type == isl_dim_out) + isl_die(aff->v->ctx, isl_error_invalid, + "output/set dimension does not have a coefficient", + return isl_aff_free(aff)); + if (type == isl_dim_in) + type = isl_dim_set; + + if (isl_local_space_check_range(aff->ls, type, pos, 1) < 0) + return isl_aff_free(aff); + + 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); + + pos += isl_local_space_offset(aff->ls, type); + isl_int_set(aff->v->el[1 + pos], v); + + return aff; +} + +/* Replace the numerator of the coefficient of the variable of type "type" + * at position "pos" of "aff" by "v". + * + * A NaN is unaffected by this operation. + */ +__isl_give isl_aff *isl_aff_set_coefficient_si(__isl_take isl_aff *aff, + enum isl_dim_type type, int pos, int v) +{ + if (!aff) + return NULL; + + if (type == isl_dim_out) + isl_die(aff->v->ctx, isl_error_invalid, + "output/set dimension does not have a coefficient", + return isl_aff_free(aff)); + if (type == isl_dim_in) + type = isl_dim_set; + + if (isl_local_space_check_range(aff->ls, type, pos, 1) < 0) + return isl_aff_free(aff); + + if (isl_aff_is_nan(aff)) + return aff; + pos += isl_local_space_offset(aff->ls, type); + if (isl_int_cmp_si(aff->v->el[1 + pos], v) == 0) + 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_si(aff->v->el[1 + pos], v); + + return aff; +} + +/* Replace the coefficient of the variable of type "type" at position "pos" + * of "aff" by "v". + * + * A NaN is unaffected by this operation. + */ +__isl_give isl_aff *isl_aff_set_coefficient_val(__isl_take isl_aff *aff, + enum isl_dim_type type, int pos, __isl_take isl_val *v) +{ + if (!aff || !v) + goto error; + + if (type == isl_dim_out) + isl_die(aff->v->ctx, isl_error_invalid, + "output/set dimension does not have a coefficient", + goto error); + if (type == isl_dim_in) + type = isl_dim_set; + + if (isl_local_space_check_range(aff->ls, type, pos, 1) < 0) + return isl_aff_free(aff); + + if (isl_aff_is_nan(aff)) { + isl_val_free(v); + return aff; + } + if (!isl_val_is_rat(v)) + isl_die(isl_aff_get_ctx(aff), isl_error_invalid, + "expecting rational value", goto error); + + pos += isl_local_space_offset(aff->ls, type); + if (isl_int_eq(aff->v->el[1 + pos], v->n) && + isl_int_eq(aff->v->el[0], v->d)) { + isl_val_free(v); + return aff; + } + + aff = isl_aff_cow(aff); + if (!aff) + goto error; + aff->v = isl_vec_cow(aff->v); + if (!aff->v) + goto error; + + if (isl_int_eq(aff->v->el[0], v->d)) { + isl_int_set(aff->v->el[1 + pos], v->n); + } else if (isl_int_is_one(v->d)) { + isl_int_mul(aff->v->el[1 + pos], aff->v->el[0], v->n); + } else { + isl_seq_scale(aff->v->el + 1, + aff->v->el + 1, v->d, aff->v->size - 1); + isl_int_mul(aff->v->el[1 + pos], aff->v->el[0], v->n); + isl_int_mul(aff->v->el[0], aff->v->el[0], v->d); + aff->v = isl_vec_normalize(aff->v); + if (!aff->v) + goto error; + } + + isl_val_free(v); + return aff; +error: + isl_aff_free(aff); + isl_val_free(v); + return NULL; +} + +/* Add "v" to the coefficient of the variable of type "type" + * at position "pos" of "aff". + * + * A NaN is unaffected by this operation. + */ +__isl_give isl_aff *isl_aff_add_coefficient(__isl_take isl_aff *aff, + enum isl_dim_type type, int pos, isl_int v) +{ + if (!aff) + return NULL; + + if (type == isl_dim_out) + isl_die(aff->v->ctx, isl_error_invalid, + "output/set dimension does not have a coefficient", + return isl_aff_free(aff)); + if (type == isl_dim_in) + type = isl_dim_set; + + if (isl_local_space_check_range(aff->ls, type, pos, 1) < 0) + return isl_aff_free(aff); + + 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); + + pos += isl_local_space_offset(aff->ls, type); + isl_int_addmul(aff->v->el[1 + pos], aff->v->el[0], v); + + return aff; +} + +/* Add "v" to the coefficient of the variable of type "type" + * at position "pos" of "aff". + * + * A NaN is unaffected by this operation. + */ +__isl_give isl_aff *isl_aff_add_coefficient_val(__isl_take isl_aff *aff, + enum isl_dim_type type, int pos, __isl_take isl_val *v) +{ + if (!aff || !v) + goto error; + + if (isl_val_is_zero(v)) { + isl_val_free(v); + return aff; + } + + if (type == isl_dim_out) + isl_die(aff->v->ctx, isl_error_invalid, + "output/set dimension does not have a coefficient", + goto error); + if (type == isl_dim_in) + type = isl_dim_set; + + if (isl_local_space_check_range(aff->ls, type, pos, 1) < 0) + goto error; + + if (isl_aff_is_nan(aff)) { + isl_val_free(v); + return aff; + } + if (!isl_val_is_rat(v)) + isl_die(isl_aff_get_ctx(aff), isl_error_invalid, + "expecting rational value", goto error); + + aff = isl_aff_cow(aff); + if (!aff) + goto error; + + aff->v = isl_vec_cow(aff->v); + if (!aff->v) + goto error; + + pos += isl_local_space_offset(aff->ls, type); + if (isl_int_is_one(v->d)) { + isl_int_addmul(aff->v->el[1 + pos], aff->v->el[0], v->n); + } else if (isl_int_eq(aff->v->el[0], v->d)) { + isl_int_add(aff->v->el[1 + pos], aff->v->el[1 + pos], v->n); + aff->v = isl_vec_normalize(aff->v); + if (!aff->v) + goto error; + } else { + isl_seq_scale(aff->v->el + 1, + aff->v->el + 1, v->d, aff->v->size - 1); + isl_int_addmul(aff->v->el[1 + pos], aff->v->el[0], v->n); + isl_int_mul(aff->v->el[0], aff->v->el[0], v->d); + aff->v = isl_vec_normalize(aff->v); + if (!aff->v) + goto error; + } + + isl_val_free(v); + return aff; +error: + isl_aff_free(aff); + isl_val_free(v); + return NULL; +} + +__isl_give isl_aff *isl_aff_add_coefficient_si(__isl_take isl_aff *aff, + enum isl_dim_type type, int pos, int v) +{ + isl_int t; + + isl_int_init(t); + isl_int_set_si(t, v); + aff = isl_aff_add_coefficient(aff, type, pos, t); + isl_int_clear(t); + + return aff; +} + +__isl_give isl_aff *isl_aff_get_div(__isl_keep isl_aff *aff, int pos) +{ + if (!aff) + return NULL; + + return isl_local_space_get_div(aff->ls, pos); +} + +/* Return the negation of "aff". + * + * As a special case, -NaN = NaN. + */ +__isl_give isl_aff *isl_aff_neg(__isl_take isl_aff *aff) +{ + 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_seq_neg(aff->v->el + 1, aff->v->el + 1, aff->v->size - 1); + + return aff; +} + +/* Remove divs from the local space that do not appear in the affine + * expression. + * We currently only remove divs at the end. + * Some intermediate divs may also not appear directly in the affine + * expression, but we would also need to check that no other divs are + * defined in terms of them. + */ +__isl_give isl_aff *isl_aff_remove_unused_divs(__isl_take isl_aff *aff) +{ + int pos; + isl_size off; + isl_size n; + + n = isl_aff_domain_dim(aff, isl_dim_div); + off = isl_aff_domain_offset(aff, isl_dim_div); + if (n < 0 || off < 0) + return isl_aff_free(aff); + + pos = isl_seq_last_non_zero(aff->v->el + 1 + off, n) + 1; + if (pos == n) + return aff; + + aff = isl_aff_cow(aff); + if (!aff) + return NULL; + + aff->ls = isl_local_space_drop_dims(aff->ls, isl_dim_div, pos, n - pos); + aff->v = isl_vec_drop_els(aff->v, 1 + off + pos, n - pos); + if (!aff->ls || !aff->v) + return isl_aff_free(aff); + + return aff; +} + +/* Look for any divs in the aff->ls with a denominator equal to one + * and plug them into the affine expression and any subsequent divs + * that may reference the div. + */ +static __isl_give isl_aff *plug_in_integral_divs(__isl_take isl_aff *aff) +{ + int i; + isl_size n; + int len; + isl_int v; + isl_vec *vec; + isl_local_space *ls; + isl_size off; + + n = isl_aff_domain_dim(aff, isl_dim_div); + off = isl_aff_domain_offset(aff, isl_dim_div); + if (n < 0 || off < 0) + return isl_aff_free(aff); + len = aff->v->size; + for (i = 0; i < n; ++i) { + if (!isl_int_is_one(aff->ls->div->row[i][0])) + continue; + ls = isl_local_space_copy(aff->ls); + ls = isl_local_space_substitute_seq(ls, isl_dim_div, i, + aff->ls->div->row[i], len, i + 1, n - (i + 1)); + vec = isl_vec_copy(aff->v); + vec = isl_vec_cow(vec); + if (!ls || !vec) + goto error; + + isl_int_init(v); + + isl_seq_substitute(vec->el, off + i, aff->ls->div->row[i], + len, len, v); + + isl_int_clear(v); + + isl_vec_free(aff->v); + aff->v = vec; + isl_local_space_free(aff->ls); + aff->ls = ls; + } + + return aff; +error: + isl_vec_free(vec); + isl_local_space_free(ls); + return isl_aff_free(aff); +} + +/* Look for any divs j that appear with a unit coefficient inside + * the definitions of other divs i and plug them into the definitions + * of the divs i. + * + * In particular, an expression of the form + * + * floor((f(..) + floor(g(..)/n))/m) + * + * is simplified to + * + * floor((n * f(..) + g(..))/(n * m)) + * + * This simplification is correct because we can move the expression + * f(..) into the inner floor in the original expression to obtain + * + * floor(floor((n * f(..) + g(..))/n)/m) + * + * from which we can derive the simplified expression. + */ +static __isl_give isl_aff *plug_in_unit_divs(__isl_take isl_aff *aff) +{ + int i, j; + isl_size n; + isl_size off; + + n = isl_aff_domain_dim(aff, isl_dim_div); + off = isl_aff_domain_offset(aff, isl_dim_div); + if (n < 0 || off < 0) + return isl_aff_free(aff); + for (i = 1; i < n; ++i) { + for (j = 0; j < i; ++j) { + if (!isl_int_is_one(aff->ls->div->row[i][1 + off + j])) + continue; + aff->ls = isl_local_space_substitute_seq(aff->ls, + isl_dim_div, j, aff->ls->div->row[j], + aff->v->size, i, 1); + if (!aff->ls) + return isl_aff_free(aff); + } + } + + return aff; +} + +/* Swap divs "a" and "b" in "aff", which is assumed to be non-NULL. + * + * Even though this function is only called on isl_affs with a single + * reference, we are careful to only change aff->v and aff->ls together. + */ +static __isl_give isl_aff *swap_div(__isl_take isl_aff *aff, int a, int b) +{ + isl_size off = isl_aff_domain_offset(aff, isl_dim_div); + isl_local_space *ls; + isl_vec *v; + + if (off < 0) + return isl_aff_free(aff); + + ls = isl_local_space_copy(aff->ls); + ls = isl_local_space_swap_div(ls, a, b); + v = isl_vec_copy(aff->v); + v = isl_vec_cow(v); + if (!ls || !v) + goto error; + + isl_int_swap(v->el[1 + off + a], v->el[1 + off + b]); + isl_vec_free(aff->v); + aff->v = v; + isl_local_space_free(aff->ls); + aff->ls = ls; + + return aff; +error: + isl_vec_free(v); + isl_local_space_free(ls); + return isl_aff_free(aff); +} + +/* Merge divs "a" and "b" in "aff", which is assumed to be non-NULL. + * + * We currently do not actually remove div "b", but simply add its + * coefficient to that of "a" and then zero it out. + */ +static __isl_give isl_aff *merge_divs(__isl_take isl_aff *aff, int a, int b) +{ + isl_size off = isl_aff_domain_offset(aff, isl_dim_div); + + if (off < 0) + return isl_aff_free(aff); + + if (isl_int_is_zero(aff->v->el[1 + off + b])) + return aff; + + aff->v = isl_vec_cow(aff->v); + if (!aff->v) + return isl_aff_free(aff); + + isl_int_add(aff->v->el[1 + off + a], + aff->v->el[1 + off + a], aff->v->el[1 + off + b]); + isl_int_set_si(aff->v->el[1 + off + b], 0); + + return aff; +} + +/* Sort the divs in the local space of "aff" according to + * the comparison function "cmp_row" in isl_local_space.c, + * combining the coefficients of identical divs. + * + * Reordering divs does not change the semantics of "aff", + * so there is no need to call isl_aff_cow. + * Moreover, this function is currently only called on isl_affs + * with a single reference. + */ +static __isl_give isl_aff *sort_divs(__isl_take isl_aff *aff) +{ + isl_size n; + int i, j; + + n = isl_aff_dim(aff, isl_dim_div); + if (n < 0) + return isl_aff_free(aff); + for (i = 1; i < n; ++i) { + for (j = i - 1; j >= 0; --j) { + int cmp = isl_mat_cmp_div(aff->ls->div, j, j + 1); + if (cmp < 0) + break; + if (cmp == 0) + aff = merge_divs(aff, j, j + 1); + else + aff = swap_div(aff, j, j + 1); + if (!aff) + return NULL; + } + } + + return aff; +} + +/* Normalize the representation of "aff". + * + * This function should only be called on "new" isl_affs, i.e., + * with only a single reference. We therefore do not need to + * worry about affecting other instances. + */ +__isl_give isl_aff *isl_aff_normalize(__isl_take isl_aff *aff) +{ + if (!aff) + return NULL; + aff->v = isl_vec_normalize(aff->v); + if (!aff->v) + return isl_aff_free(aff); + aff = plug_in_integral_divs(aff); + aff = plug_in_unit_divs(aff); + aff = sort_divs(aff); + aff = isl_aff_remove_unused_divs(aff); + return aff; +} + +/* Given f, return floor(f). + * If f is an integer expression, then just return f. + * If f is a constant, then return the constant floor(f). + * Otherwise, if f = g/m, write g = q m + r, + * create a new div d = [r/m] and return the expression q + d. + * The coefficients in r are taken to lie between -m/2 and m/2. + * + * reduce_div_coefficients performs the same normalization. + * + * As a special case, floor(NaN) = NaN. + */ +__isl_give isl_aff *isl_aff_floor(__isl_take isl_aff *aff) +{ + int i; + int size; + isl_ctx *ctx; + isl_vec *div; + + if (!aff) + return NULL; + + if (isl_aff_is_nan(aff)) + return aff; + if (isl_int_is_one(aff->v->el[0])) + 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); + + if (isl_aff_is_cst(aff)) { + isl_int_fdiv_q(aff->v->el[1], aff->v->el[1], aff->v->el[0]); + isl_int_set_si(aff->v->el[0], 1); + return aff; + } + + div = isl_vec_copy(aff->v); + div = isl_vec_cow(div); + if (!div) + return isl_aff_free(aff); + + ctx = isl_aff_get_ctx(aff); + isl_int_fdiv_q(aff->v->el[0], aff->v->el[0], ctx->two); + for (i = 1; i < aff->v->size; ++i) { + isl_int_fdiv_r(div->el[i], div->el[i], div->el[0]); + isl_int_fdiv_q(aff->v->el[i], aff->v->el[i], div->el[0]); + if (isl_int_gt(div->el[i], aff->v->el[0])) { + isl_int_sub(div->el[i], div->el[i], div->el[0]); + isl_int_add_ui(aff->v->el[i], aff->v->el[i], 1); + } + } + + aff->ls = isl_local_space_add_div(aff->ls, div); + if (!aff->ls) + return isl_aff_free(aff); + + size = aff->v->size; + aff->v = isl_vec_extend(aff->v, size + 1); + if (!aff->v) + return isl_aff_free(aff); + isl_int_set_si(aff->v->el[0], 1); + isl_int_set_si(aff->v->el[size], 1); + + aff = isl_aff_normalize(aff); + + return aff; +} + +/* Compute + * + * aff mod m = aff - m * floor(aff/m) + * + * with m an integer value. + */ +__isl_give isl_aff *isl_aff_mod_val(__isl_take isl_aff *aff, + __isl_take isl_val *m) +{ + isl_aff *res; + + if (!aff || !m) + goto error; + + if (!isl_val_is_int(m)) + isl_die(isl_val_get_ctx(m), isl_error_invalid, + "expecting integer modulo", goto error); + + res = isl_aff_copy(aff); + aff = isl_aff_scale_down_val(aff, isl_val_copy(m)); + aff = isl_aff_floor(aff); + aff = isl_aff_scale_val(aff, m); + res = isl_aff_sub(res, aff); + + return res; +error: + isl_aff_free(aff); + isl_val_free(m); + return NULL; +} + +/* Compute + * + * pwaff mod m = pwaff - m * floor(pwaff/m) + */ +__isl_give isl_pw_aff *isl_pw_aff_mod(__isl_take isl_pw_aff *pwaff, isl_int m) +{ + isl_pw_aff *res; + + res = isl_pw_aff_copy(pwaff); + pwaff = isl_pw_aff_scale_down(pwaff, m); + pwaff = isl_pw_aff_floor(pwaff); + pwaff = isl_pw_aff_scale(pwaff, m); + res = isl_pw_aff_sub(res, pwaff); + + return res; +} + +/* Compute + * + * pa mod m = pa - m * floor(pa/m) + * + * with m an integer value. + */ +__isl_give isl_pw_aff *isl_pw_aff_mod_val(__isl_take isl_pw_aff *pa, + __isl_take isl_val *m) +{ + if (!pa || !m) + goto error; + if (!isl_val_is_int(m)) + isl_die(isl_pw_aff_get_ctx(pa), isl_error_invalid, + "expecting integer modulo", goto error); + pa = isl_pw_aff_mod(pa, m->n); + isl_val_free(m); + return pa; +error: + isl_pw_aff_free(pa); + isl_val_free(m); + return NULL; +} + +/* Given f, return ceil(f). + * If f is an integer expression, then just return f. + * Otherwise, let f be the expression + * + * e/m + * + * then return + * + * floor((e + m - 1)/m) + * + * As a special case, ceil(NaN) = NaN. + */ +__isl_give isl_aff *isl_aff_ceil(__isl_take isl_aff *aff) +{ + if (!aff) + return NULL; + + if (isl_aff_is_nan(aff)) + return aff; + if (isl_int_is_one(aff->v->el[0])) + 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_add(aff->v->el[1], aff->v->el[1], aff->v->el[0]); + isl_int_sub_ui(aff->v->el[1], aff->v->el[1], 1); + aff = isl_aff_floor(aff); + + return aff; +} + +/* Apply the expansion computed by isl_merge_divs. + * The expansion itself is given by "exp" while the resulting + * list of divs is given by "div". + */ +__isl_give isl_aff *isl_aff_expand_divs(__isl_take isl_aff *aff, + __isl_take isl_mat *div, int *exp) +{ + isl_size old_n_div; + isl_size new_n_div; + isl_size offset; + + aff = isl_aff_cow(aff); + + offset = isl_aff_domain_offset(aff, isl_dim_div); + old_n_div = isl_aff_domain_dim(aff, isl_dim_div); + new_n_div = isl_mat_rows(div); + if (offset < 0 || old_n_div < 0 || new_n_div < 0) + goto error; + + aff->v = isl_vec_expand(aff->v, 1 + offset, old_n_div, exp, new_n_div); + aff->ls = isl_local_space_replace_divs(aff->ls, div); + if (!aff->v || !aff->ls) + return isl_aff_free(aff); + return aff; +error: + isl_aff_free(aff); + isl_mat_free(div); + return NULL; +} + +/* Add two affine expressions that live in the same local space. + */ +static __isl_give isl_aff *add_expanded(__isl_take isl_aff *aff1, + __isl_take isl_aff *aff2) +{ + isl_int gcd, f; + + aff1 = isl_aff_cow(aff1); + if (!aff1 || !aff2) + goto error; + + aff1->v = isl_vec_cow(aff1->v); + if (!aff1->v) + goto error; + + isl_int_init(gcd); + isl_int_init(f); + isl_int_gcd(gcd, aff1->v->el[0], aff2->v->el[0]); + isl_int_divexact(f, aff2->v->el[0], gcd); + isl_seq_scale(aff1->v->el + 1, aff1->v->el + 1, f, aff1->v->size - 1); + isl_int_divexact(f, aff1->v->el[0], gcd); + isl_seq_addmul(aff1->v->el + 1, f, aff2->v->el + 1, aff1->v->size - 1); + isl_int_divexact(f, aff2->v->el[0], gcd); + isl_int_mul(aff1->v->el[0], aff1->v->el[0], f); + isl_int_clear(f); + isl_int_clear(gcd); + + isl_aff_free(aff2); + aff1 = isl_aff_normalize(aff1); + return aff1; +error: + isl_aff_free(aff1); + isl_aff_free(aff2); + return NULL; +} + +/* Replace one of the arguments by a NaN and free the other one. + */ +static __isl_give isl_aff *set_nan_free(__isl_take isl_aff *aff1, + __isl_take isl_aff *aff2) +{ + isl_aff_free(aff2); + return isl_aff_set_nan(aff1); +} + +/* Return the sum of "aff1" and "aff2". + * + * If either of the two is NaN, then the result is NaN. + */ +__isl_give isl_aff *isl_aff_add(__isl_take isl_aff *aff1, + __isl_take isl_aff *aff2) +{ + isl_ctx *ctx; + int *exp1 = NULL; + int *exp2 = NULL; + isl_mat *div; + isl_size n_div1, n_div2; + + if (!aff1 || !aff2) + goto error; + + ctx = isl_aff_get_ctx(aff1); + if (!isl_space_is_equal(aff1->ls->dim, aff2->ls->dim)) + isl_die(ctx, isl_error_invalid, + "spaces don't match", goto error); + + if (isl_aff_is_nan(aff1)) { + isl_aff_free(aff2); + return aff1; + } + if (isl_aff_is_nan(aff2)) { + isl_aff_free(aff1); + return aff2; + } + + n_div1 = isl_aff_dim(aff1, isl_dim_div); + n_div2 = isl_aff_dim(aff2, isl_dim_div); + if (n_div1 < 0 || n_div2 < 0) + goto error; + if (n_div1 == 0 && n_div2 == 0) + return add_expanded(aff1, aff2); + + exp1 = isl_alloc_array(ctx, int, n_div1); + exp2 = isl_alloc_array(ctx, int, n_div2); + if ((n_div1 && !exp1) || (n_div2 && !exp2)) + goto error; + + div = isl_merge_divs(aff1->ls->div, aff2->ls->div, exp1, exp2); + aff1 = isl_aff_expand_divs(aff1, isl_mat_copy(div), exp1); + aff2 = isl_aff_expand_divs(aff2, div, exp2); + free(exp1); + free(exp2); + + return add_expanded(aff1, aff2); +error: + free(exp1); + free(exp2); + isl_aff_free(aff1); + isl_aff_free(aff2); + return NULL; +} + +__isl_give isl_aff *isl_aff_sub(__isl_take isl_aff *aff1, + __isl_take isl_aff *aff2) +{ + return isl_aff_add(aff1, isl_aff_neg(aff2)); +} + +/* Return the result of scaling "aff" by a factor of "f". + * + * As a special case, f * NaN = NaN. + */ +__isl_give isl_aff *isl_aff_scale(__isl_take isl_aff *aff, isl_int f) +{ + isl_int gcd; + + if (!aff) + return NULL; + if (isl_aff_is_nan(aff)) + return aff; + + if (isl_int_is_one(f)) + 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); + + if (isl_int_is_pos(f) && isl_int_is_divisible_by(aff->v->el[0], f)) { + isl_int_divexact(aff->v->el[0], aff->v->el[0], f); + return aff; + } + + isl_int_init(gcd); + isl_int_gcd(gcd, aff->v->el[0], f); + isl_int_divexact(aff->v->el[0], aff->v->el[0], gcd); + isl_int_divexact(gcd, f, gcd); + isl_seq_scale(aff->v->el + 1, aff->v->el + 1, gcd, aff->v->size - 1); + isl_int_clear(gcd); + + return aff; +} + +/* Multiple "aff" by "v". + */ +__isl_give isl_aff *isl_aff_scale_val(__isl_take isl_aff *aff, + __isl_take isl_val *v) +{ + if (!aff || !v) + goto error; + + if (isl_val_is_one(v)) { + isl_val_free(v); + return aff; + } + + if (!isl_val_is_rat(v)) + isl_die(isl_aff_get_ctx(aff), isl_error_invalid, + "expecting rational factor", goto error); + + aff = isl_aff_scale(aff, v->n); + aff = isl_aff_scale_down(aff, v->d); + + isl_val_free(v); + return aff; +error: + isl_aff_free(aff); + isl_val_free(v); + return NULL; +} + +/* Return the result of scaling "aff" down by a factor of "f". + * + * As a special case, NaN/f = NaN. + */ +__isl_give isl_aff *isl_aff_scale_down(__isl_take isl_aff *aff, isl_int f) +{ + isl_int gcd; + + if (!aff) + return NULL; + if (isl_aff_is_nan(aff)) + return aff; + + if (isl_int_is_one(f)) + return aff; + + aff = isl_aff_cow(aff); + if (!aff) + return NULL; + + if (isl_int_is_zero(f)) + isl_die(isl_aff_get_ctx(aff), isl_error_invalid, + "cannot scale down by zero", return isl_aff_free(aff)); + + aff->v = isl_vec_cow(aff->v); + if (!aff->v) + return isl_aff_free(aff); + + isl_int_init(gcd); + isl_seq_gcd(aff->v->el + 1, aff->v->size - 1, &gcd); + isl_int_gcd(gcd, gcd, f); + isl_seq_scale_down(aff->v->el + 1, aff->v->el + 1, gcd, aff->v->size - 1); + isl_int_divexact(gcd, f, gcd); + isl_int_mul(aff->v->el[0], aff->v->el[0], gcd); + isl_int_clear(gcd); + + return aff; +} + +/* Divide "aff" by "v". + */ +__isl_give isl_aff *isl_aff_scale_down_val(__isl_take isl_aff *aff, + __isl_take isl_val *v) +{ + if (!aff || !v) + goto error; + + if (isl_val_is_one(v)) { + isl_val_free(v); + return aff; + } + + if (!isl_val_is_rat(v)) + isl_die(isl_aff_get_ctx(aff), isl_error_invalid, + "expecting rational factor", goto error); + if (!isl_val_is_pos(v)) + isl_die(isl_aff_get_ctx(aff), isl_error_invalid, + "factor needs to be positive", goto error); + + aff = isl_aff_scale(aff, v->d); + aff = isl_aff_scale_down(aff, v->n); + + isl_val_free(v); + return aff; +error: + isl_aff_free(aff); + isl_val_free(v); + return NULL; +} + +__isl_give isl_aff *isl_aff_scale_down_ui(__isl_take isl_aff *aff, unsigned f) +{ + isl_int v; + + if (f == 1) + return aff; + + isl_int_init(v); + isl_int_set_ui(v, f); + aff = isl_aff_scale_down(aff, v); + isl_int_clear(v); + + return aff; +} + +__isl_give isl_aff *isl_aff_set_dim_name(__isl_take isl_aff *aff, + enum isl_dim_type type, unsigned pos, const char *s) +{ + aff = isl_aff_cow(aff); + if (!aff) + return NULL; + if (type == isl_dim_out) + isl_die(aff->v->ctx, isl_error_invalid, + "cannot set name of output/set dimension", + return isl_aff_free(aff)); + if (type == isl_dim_in) + type = isl_dim_set; + aff->ls = isl_local_space_set_dim_name(aff->ls, type, pos, s); + if (!aff->ls) + return isl_aff_free(aff); + + return aff; +} + +__isl_give isl_aff *isl_aff_set_dim_id(__isl_take isl_aff *aff, + enum isl_dim_type type, unsigned pos, __isl_take isl_id *id) +{ + aff = isl_aff_cow(aff); + if (!aff) + goto error; + if (type == isl_dim_out) + isl_die(aff->v->ctx, isl_error_invalid, + "cannot set name of output/set dimension", + goto error); + if (type == isl_dim_in) + type = isl_dim_set; + aff->ls = isl_local_space_set_dim_id(aff->ls, type, pos, id); + if (!aff->ls) + return isl_aff_free(aff); + + return aff; +error: + isl_id_free(id); + isl_aff_free(aff); + return NULL; +} + +/* Replace the identifier of the input tuple of "aff" by "id". + * type is currently required to be equal to isl_dim_in + */ +__isl_give isl_aff *isl_aff_set_tuple_id(__isl_take isl_aff *aff, + enum isl_dim_type type, __isl_take isl_id *id) +{ + aff = isl_aff_cow(aff); + if (!aff) + goto error; + if (type != isl_dim_in) + isl_die(aff->v->ctx, isl_error_invalid, + "cannot only set id of input tuple", goto error); + aff->ls = isl_local_space_set_tuple_id(aff->ls, isl_dim_set, id); + if (!aff->ls) + return isl_aff_free(aff); + + return aff; +error: + isl_id_free(id); + isl_aff_free(aff); + return NULL; +} + +/* Exploit the equalities in "eq" to simplify the affine expression + * and the expressions of the integer divisions in the local space. + * The integer divisions in this local space are assumed to appear + * as regular dimensions in "eq". + */ +static __isl_give isl_aff *isl_aff_substitute_equalities_lifted( + __isl_take isl_aff *aff, __isl_take isl_basic_set *eq) +{ + int i, j; + unsigned o_div; + unsigned n_div; + + if (!eq) + goto error; + if (eq->n_eq == 0) { + isl_basic_set_free(eq); + return aff; + } + + aff = isl_aff_cow(aff); + if (!aff) + goto error; + + aff->ls = isl_local_space_substitute_equalities(aff->ls, + isl_basic_set_copy(eq)); + aff->v = isl_vec_cow(aff->v); + if (!aff->ls || !aff->v) + goto error; + + o_div = isl_basic_set_offset(eq, isl_dim_div); + n_div = eq->n_div; + for (i = 0; i < eq->n_eq; ++i) { + j = isl_seq_last_non_zero(eq->eq[i], o_div + n_div); + if (j < 0 || j == 0 || j >= o_div) + continue; + + isl_seq_elim(aff->v->el + 1, eq->eq[i], j, o_div, + &aff->v->el[0]); + } + + isl_basic_set_free(eq); + aff = isl_aff_normalize(aff); + return aff; +error: + isl_basic_set_free(eq); + isl_aff_free(aff); + return NULL; +} + +/* Exploit the equalities in "eq" to simplify the affine expression + * and the expressions of the integer divisions in the local space. + */ +__isl_give isl_aff *isl_aff_substitute_equalities(__isl_take isl_aff *aff, + __isl_take isl_basic_set *eq) +{ + isl_size n_div; + + n_div = isl_aff_domain_dim(aff, isl_dim_div); + if (n_div < 0) + goto error; + if (n_div > 0) + eq = isl_basic_set_add_dims(eq, isl_dim_set, n_div); + return isl_aff_substitute_equalities_lifted(aff, eq); +error: + isl_basic_set_free(eq); + isl_aff_free(aff); + return NULL; +} + +/* Look for equalities among the variables shared by context and aff + * and the integer divisions of aff, if any. + * The equalities are then used to eliminate coefficients and/or integer + * divisions from aff. + */ +__isl_give isl_aff *isl_aff_gist(__isl_take isl_aff *aff, + __isl_take isl_set *context) +{ + isl_local_space *ls; + isl_basic_set *hull; + + ls = isl_aff_get_domain_local_space(aff); + context = isl_local_space_lift_set(ls, context); + + hull = isl_set_affine_hull(context); + return isl_aff_substitute_equalities_lifted(aff, hull); +} + +__isl_give isl_aff *isl_aff_gist_params(__isl_take isl_aff *aff, + __isl_take isl_set *context) +{ + isl_set *dom_context = isl_set_universe(isl_aff_get_domain_space(aff)); + dom_context = isl_set_intersect_params(dom_context, context); + return isl_aff_gist(aff, dom_context); +} + +/* Return a basic set containing those elements in the space + * of aff where it is positive. "rational" should not be set. + * + * If "aff" is NaN, then it is not positive. + */ +static __isl_give isl_basic_set *aff_pos_basic_set(__isl_take isl_aff *aff, + int rational, void *user) +{ + isl_constraint *ineq; + isl_basic_set *bset; + isl_val *c; + + if (!aff) + return NULL; + if (isl_aff_is_nan(aff)) { + isl_space *space = isl_aff_get_domain_space(aff); + isl_aff_free(aff); + return isl_basic_set_empty(space); + } + if (rational) + isl_die(isl_aff_get_ctx(aff), isl_error_unsupported, + "rational sets not supported", goto error); + + ineq = isl_inequality_from_aff(aff); + c = isl_constraint_get_constant_val(ineq); + c = isl_val_sub_ui(c, 1); + ineq = isl_constraint_set_constant_val(ineq, c); + + bset = isl_basic_set_from_constraint(ineq); + bset = isl_basic_set_simplify(bset); + return bset; +error: + isl_aff_free(aff); + return NULL; +} + +/* Return a basic set containing those elements in the space + * of aff where it is non-negative. + * If "rational" is set, then return a rational basic set. + * + * If "aff" is NaN, then it is not non-negative (it's not negative either). + */ +static __isl_give isl_basic_set *aff_nonneg_basic_set( + __isl_take isl_aff *aff, int rational, void *user) +{ + isl_constraint *ineq; + isl_basic_set *bset; + + if (!aff) + return NULL; + if (isl_aff_is_nan(aff)) { + isl_space *space = isl_aff_get_domain_space(aff); + isl_aff_free(aff); + return isl_basic_set_empty(space); + } + + ineq = isl_inequality_from_aff(aff); + + bset = isl_basic_set_from_constraint(ineq); + if (rational) + bset = isl_basic_set_set_rational(bset); + bset = isl_basic_set_simplify(bset); + return bset; +} + +/* Return a basic set containing those elements in the space + * of aff where it is non-negative. + */ +__isl_give isl_basic_set *isl_aff_nonneg_basic_set(__isl_take isl_aff *aff) +{ + return aff_nonneg_basic_set(aff, 0, NULL); +} + +/* Return a basic set containing those elements in the domain space + * of "aff" where it is positive. + */ +__isl_give isl_basic_set *isl_aff_pos_basic_set(__isl_take isl_aff *aff) +{ + aff = isl_aff_add_constant_num_si(aff, -1); + return isl_aff_nonneg_basic_set(aff); +} + +/* Return a basic set containing those elements in the domain space + * of aff where it is negative. + */ +__isl_give isl_basic_set *isl_aff_neg_basic_set(__isl_take isl_aff *aff) +{ + aff = isl_aff_neg(aff); + return isl_aff_pos_basic_set(aff); +} + +/* Return a basic set containing those elements in the space + * of aff where it is zero. + * If "rational" is set, then return a rational basic set. + * + * If "aff" is NaN, then it is not zero. + */ +static __isl_give isl_basic_set *aff_zero_basic_set(__isl_take isl_aff *aff, + int rational, void *user) +{ + isl_constraint *ineq; + isl_basic_set *bset; + + if (!aff) + return NULL; + if (isl_aff_is_nan(aff)) { + isl_space *space = isl_aff_get_domain_space(aff); + isl_aff_free(aff); + return isl_basic_set_empty(space); + } + + ineq = isl_equality_from_aff(aff); + + bset = isl_basic_set_from_constraint(ineq); + if (rational) + bset = isl_basic_set_set_rational(bset); + bset = isl_basic_set_simplify(bset); + return bset; +} + +/* Return a basic set containing those elements in the space + * of aff where it is zero. + */ +__isl_give isl_basic_set *isl_aff_zero_basic_set(__isl_take isl_aff *aff) +{ + return aff_zero_basic_set(aff, 0, NULL); +} + +/* Return a basic set containing those elements in the shared space + * of aff1 and aff2 where aff1 is greater than or equal to aff2. + */ +__isl_give isl_basic_set *isl_aff_ge_basic_set(__isl_take isl_aff *aff1, + __isl_take isl_aff *aff2) +{ + aff1 = isl_aff_sub(aff1, aff2); + + return isl_aff_nonneg_basic_set(aff1); +} + +/* Return a basic set containing those elements in the shared domain space + * of "aff1" and "aff2" where "aff1" is greater than "aff2". + */ +__isl_give isl_basic_set *isl_aff_gt_basic_set(__isl_take isl_aff *aff1, + __isl_take isl_aff *aff2) +{ + aff1 = isl_aff_sub(aff1, aff2); + + return isl_aff_pos_basic_set(aff1); +} + +/* Return a set containing those elements in the shared space + * of aff1 and aff2 where aff1 is greater than or equal to aff2. + */ +__isl_give isl_set *isl_aff_ge_set(__isl_take isl_aff *aff1, + __isl_take isl_aff *aff2) +{ + return isl_set_from_basic_set(isl_aff_ge_basic_set(aff1, aff2)); +} + +/* Return a set containing those elements in the shared domain space + * of aff1 and aff2 where aff1 is greater than aff2. + * + * If either of the two inputs is NaN, then the result is empty, + * as comparisons with NaN always return false. + */ +__isl_give isl_set *isl_aff_gt_set(__isl_take isl_aff *aff1, + __isl_take isl_aff *aff2) +{ + return isl_set_from_basic_set(isl_aff_gt_basic_set(aff1, aff2)); +} + +/* Return a basic set containing those elements in the shared space + * of aff1 and aff2 where aff1 is smaller than or equal to aff2. + */ +__isl_give isl_basic_set *isl_aff_le_basic_set(__isl_take isl_aff *aff1, + __isl_take isl_aff *aff2) +{ + return isl_aff_ge_basic_set(aff2, aff1); +} + +/* Return a basic set containing those elements in the shared domain space + * of "aff1" and "aff2" where "aff1" is smaller than "aff2". + */ +__isl_give isl_basic_set *isl_aff_lt_basic_set(__isl_take isl_aff *aff1, + __isl_take isl_aff *aff2) +{ + return isl_aff_gt_basic_set(aff2, aff1); +} + +/* Return a set containing those elements in the shared space + * of aff1 and aff2 where aff1 is smaller than or equal to aff2. + */ +__isl_give isl_set *isl_aff_le_set(__isl_take isl_aff *aff1, + __isl_take isl_aff *aff2) +{ + return isl_aff_ge_set(aff2, aff1); +} + +/* Return a set containing those elements in the shared domain space + * of "aff1" and "aff2" where "aff1" is smaller than "aff2". + */ +__isl_give isl_set *isl_aff_lt_set(__isl_take isl_aff *aff1, + __isl_take isl_aff *aff2) +{ + return isl_set_from_basic_set(isl_aff_lt_basic_set(aff1, aff2)); +} + +/* Return a basic set containing those elements in the shared space + * of aff1 and aff2 where aff1 and aff2 are equal. + */ +__isl_give isl_basic_set *isl_aff_eq_basic_set(__isl_take isl_aff *aff1, + __isl_take isl_aff *aff2) +{ + aff1 = isl_aff_sub(aff1, aff2); + + return isl_aff_zero_basic_set(aff1); +} + +/* Return a set containing those elements in the shared space + * of aff1 and aff2 where aff1 and aff2 are equal. + */ +__isl_give isl_set *isl_aff_eq_set(__isl_take isl_aff *aff1, + __isl_take isl_aff *aff2) +{ + return isl_set_from_basic_set(isl_aff_eq_basic_set(aff1, aff2)); +} + +/* Return a set containing those elements in the shared domain space + * of aff1 and aff2 where aff1 and aff2 are not equal. + * + * If either of the two inputs is NaN, then the result is empty, + * as comparisons with NaN always return false. + */ +__isl_give isl_set *isl_aff_ne_set(__isl_take isl_aff *aff1, + __isl_take isl_aff *aff2) +{ + isl_set *set_lt, *set_gt; + + set_lt = isl_aff_lt_set(isl_aff_copy(aff1), + isl_aff_copy(aff2)); + set_gt = isl_aff_gt_set(aff1, aff2); + return isl_set_union_disjoint(set_lt, set_gt); +} + +__isl_give isl_aff *isl_aff_add_on_domain(__isl_keep isl_set *dom, + __isl_take isl_aff *aff1, __isl_take isl_aff *aff2) +{ + aff1 = isl_aff_add(aff1, aff2); + aff1 = isl_aff_gist(aff1, isl_set_copy(dom)); + return aff1; +} + +isl_bool isl_aff_is_empty(__isl_keep isl_aff *aff) +{ + if (!aff) + return isl_bool_error; + + return isl_bool_false; +} + +#undef TYPE +#define TYPE isl_aff +static +#include "check_type_range_templ.c" + +/* Check whether the given affine expression has non-zero coefficient + * 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 in the affine expression. + */ +isl_bool isl_aff_involves_dims(__isl_keep isl_aff *aff, + enum isl_dim_type type, unsigned first, unsigned n) +{ + int i; + int *active = NULL; + isl_bool involves = isl_bool_false; + + if (!aff) + return isl_bool_error; + if (n == 0) + return isl_bool_false; + if (isl_aff_check_range(aff, type, first, n) < 0) + return isl_bool_error; + + active = isl_local_space_get_active(aff->ls, aff->v->el + 2); + if (!active) + goto error; + + first += isl_local_space_offset(aff->ls, type) - 1; + for (i = 0; i < n; ++i) + if (active[first + i]) { + involves = isl_bool_true; + break; + } + + free(active); + + return involves; +error: + free(active); + return isl_bool_error; +} + +/* Does "aff" involve any local variables, i.e., integer divisions? + */ +isl_bool isl_aff_involves_locals(__isl_keep isl_aff *aff) +{ + isl_size n; + + n = isl_aff_dim(aff, isl_dim_div); + if (n < 0) + return isl_bool_error; + return isl_bool_ok(n > 0); +} + +__isl_give isl_aff *isl_aff_drop_dims(__isl_take isl_aff *aff, + enum isl_dim_type type, unsigned first, unsigned n) +{ + if (!aff) + return NULL; + if (type == isl_dim_out) + isl_die(isl_aff_get_ctx(aff), isl_error_invalid, + "cannot drop output/set dimension", + return isl_aff_free(aff)); + if (type == isl_dim_in) + type = isl_dim_set; + if (n == 0 && !isl_local_space_is_named_or_nested(aff->ls, type)) + return aff; + + if (isl_local_space_check_range(aff->ls, type, first, n) < 0) + return isl_aff_free(aff); + + aff = isl_aff_cow(aff); + if (!aff) + return NULL; + + aff->ls = isl_local_space_drop_dims(aff->ls, type, first, n); + if (!aff->ls) + return isl_aff_free(aff); + + first += 1 + isl_local_space_offset(aff->ls, type); + aff->v = isl_vec_drop_els(aff->v, first, n); + if (!aff->v) + return isl_aff_free(aff); + + return aff; +} + +/* Is the domain of "aff" a product? + */ +static isl_bool isl_aff_domain_is_product(__isl_keep isl_aff *aff) +{ + return isl_space_is_product(isl_aff_peek_domain_space(aff)); +} + +#undef TYPE +#define TYPE isl_aff +#include + +/* Project the domain of the affine expression onto its parameter space. + * The affine expression may not involve any of the domain dimensions. + */ +__isl_give isl_aff *isl_aff_project_domain_on_params(__isl_take isl_aff *aff) +{ + isl_space *space; + isl_size n; + + n = isl_aff_dim(aff, isl_dim_in); + if (n < 0) + return isl_aff_free(aff); + aff = isl_aff_drop_domain(aff, 0, n); + space = isl_aff_get_domain_space(aff); + space = isl_space_params(space); + aff = isl_aff_reset_domain_space(aff, space); + 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) +{ + if (!aff) + return NULL; + if (type == isl_dim_out) + isl_die(isl_aff_get_ctx(aff), isl_error_invalid, + "cannot insert output/set dimensions", + return isl_aff_free(aff)); + if (type == isl_dim_in) + type = isl_dim_set; + if (n == 0 && !isl_local_space_is_named_or_nested(aff->ls, type)) + return aff; + + if (isl_local_space_check_range(aff->ls, type, first, 0) < 0) + return isl_aff_free(aff); + + aff = isl_aff_cow(aff); + if (!aff) + return NULL; + + aff->ls = isl_local_space_insert_dims(aff->ls, type, first, n); + if (!aff->ls) + return isl_aff_free(aff); + + first += 1 + isl_local_space_offset(aff->ls, type); + aff->v = isl_vec_insert_zero_els(aff->v, first, n); + if (!aff->v) + return isl_aff_free(aff); + + return aff; +} + +__isl_give isl_aff *isl_aff_add_dims(__isl_take isl_aff *aff, + enum isl_dim_type type, unsigned n) +{ + isl_size pos; + + pos = isl_aff_dim(aff, type); + if (pos < 0) + return isl_aff_free(aff); + + return isl_aff_insert_dims(aff, type, pos, n); +} + +/* Move the "n" dimensions of "src_type" starting at "src_pos" of "aff" + * to dimensions of "dst_type" at "dst_pos". + * + * We only support moving input dimensions to parameters and vice versa. + */ +__isl_give isl_aff *isl_aff_move_dims(__isl_take isl_aff *aff, + enum isl_dim_type dst_type, unsigned dst_pos, + enum isl_dim_type src_type, unsigned src_pos, unsigned n) +{ + unsigned g_dst_pos; + unsigned g_src_pos; + isl_size src_off, dst_off; + + if (!aff) + return NULL; + if (n == 0 && + !isl_local_space_is_named_or_nested(aff->ls, src_type) && + !isl_local_space_is_named_or_nested(aff->ls, dst_type)) + return aff; + + if (dst_type == isl_dim_out || src_type == isl_dim_out) + isl_die(isl_aff_get_ctx(aff), isl_error_invalid, + "cannot move output/set dimension", + return isl_aff_free(aff)); + if (dst_type == isl_dim_div || src_type == isl_dim_div) + isl_die(isl_aff_get_ctx(aff), isl_error_invalid, + "cannot move divs", return isl_aff_free(aff)); + if (dst_type == isl_dim_in) + dst_type = isl_dim_set; + if (src_type == isl_dim_in) + src_type = isl_dim_set; + + if (isl_local_space_check_range(aff->ls, src_type, src_pos, n) < 0) + return isl_aff_free(aff); + if (dst_type == src_type) + isl_die(isl_aff_get_ctx(aff), isl_error_unsupported, + "moving dims within the same type not supported", + return isl_aff_free(aff)); + + aff = isl_aff_cow(aff); + src_off = isl_aff_domain_offset(aff, src_type); + dst_off = isl_aff_domain_offset(aff, dst_type); + if (src_off < 0 || dst_off < 0) + return isl_aff_free(aff); + + g_src_pos = 1 + src_off + src_pos; + g_dst_pos = 1 + dst_off + dst_pos; + if (dst_type > src_type) + g_dst_pos -= n; + + aff->v = isl_vec_move_els(aff->v, g_dst_pos, g_src_pos, n); + aff->ls = isl_local_space_move_dims(aff->ls, dst_type, dst_pos, + src_type, src_pos, n); + if (!aff->v || !aff->ls) + return isl_aff_free(aff); + + aff = sort_divs(aff); + + return aff; +} + +/* Given an affine function on a domain (A -> B), + * interchange A and B in the wrapped domain + * to obtain a function on the domain (B -> A). + * + * Since this may change the position of some variables, + * it may also change the normalized order of the local variables. + * Restore this order. Since sort_divs assumes the input + * has a single reference, an explicit isl_aff_cow is required. + */ +__isl_give isl_aff *isl_aff_domain_reverse(__isl_take isl_aff *aff) +{ + isl_space *space; + isl_local_space *ls; + isl_vec *v; + isl_size n_in, n_out; + unsigned offset; + + space = isl_aff_peek_domain_space(aff); + offset = isl_space_offset(space, isl_dim_set); + n_in = isl_space_wrapped_dim(space, isl_dim_set, isl_dim_in); + n_out = isl_space_wrapped_dim(space, isl_dim_set, isl_dim_out); + if (offset < 0 || n_in < 0 || n_out < 0) + return isl_aff_free(aff); + + v = isl_aff_take_rat_aff(aff); + v = isl_vec_move_els(v, 1 + 1 + offset, 1 + 1 + offset + n_in, n_out); + aff = isl_aff_restore_rat_aff(aff, v); + + ls = isl_aff_take_domain_local_space(aff); + ls = isl_local_space_wrapped_reverse(ls); + aff = isl_aff_restore_domain_local_space(aff, ls); + + aff = isl_aff_cow(aff); + aff = sort_divs(aff); + + return aff; +} + +/* Return a zero isl_aff in the given space. + * + * This is a helper function for isl_pw_*_as_* that ensures a uniform + * interface over all piecewise types. + */ +static __isl_give isl_aff *isl_aff_zero_in_space(__isl_take isl_space *space) +{ + isl_local_space *ls; + + ls = isl_local_space_from_space(isl_space_domain(space)); + return isl_aff_zero_on_domain(ls); +} + +#define isl_aff_involves_nan isl_aff_is_nan + +#undef PW +#define PW isl_pw_aff +#undef BASE +#define BASE aff +#undef EL_IS_ZERO +#define EL_IS_ZERO is_empty +#undef ZERO +#define ZERO empty +#undef IS_ZERO +#define IS_ZERO is_empty +#undef FIELD +#define FIELD aff +#undef DEFAULT_IS_ZERO +#define DEFAULT_IS_ZERO 0 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#undef BASE +#define BASE pw_aff + +#include +#include +#include + +#undef BASE +#define BASE aff + +#include + +/* Compute a piecewise quasi-affine expression with a domain that + * is the union of those of pwaff1 and pwaff2 and such that on each + * cell, the quasi-affine expression is the maximum of those of pwaff1 + * and pwaff2. If only one of pwaff1 or pwaff2 is defined on a given + * cell, then the associated expression is the defined one. + */ +__isl_give isl_pw_aff *isl_pw_aff_union_max(__isl_take isl_pw_aff *pwaff1, + __isl_take isl_pw_aff *pwaff2) +{ + isl_pw_aff_align_params_bin(&pwaff1, &pwaff2); + return isl_pw_aff_union_opt_cmp(pwaff1, pwaff2, &isl_aff_ge_set); +} + +/* Compute a piecewise quasi-affine expression with a domain that + * is the union of those of pwaff1 and pwaff2 and such that on each + * cell, the quasi-affine expression is the minimum of those of pwaff1 + * and pwaff2. If only one of pwaff1 or pwaff2 is defined on a given + * cell, then the associated expression is the defined one. + */ +__isl_give isl_pw_aff *isl_pw_aff_union_min(__isl_take isl_pw_aff *pwaff1, + __isl_take isl_pw_aff *pwaff2) +{ + isl_pw_aff_align_params_bin(&pwaff1, &pwaff2); + return isl_pw_aff_union_opt_cmp(pwaff1, pwaff2, &isl_aff_le_set); +} + +__isl_give isl_pw_aff *isl_pw_aff_union_opt(__isl_take isl_pw_aff *pwaff1, + __isl_take isl_pw_aff *pwaff2, int max) +{ + if (max) + return isl_pw_aff_union_max(pwaff1, pwaff2); + else + return isl_pw_aff_union_min(pwaff1, pwaff2); +} + +/* Is the domain of "pa" a product? + */ +static isl_bool isl_pw_aff_domain_is_product(__isl_keep isl_pw_aff *pa) +{ + return isl_space_domain_is_wrapping(isl_pw_aff_peek_space(pa)); +} + +#undef TYPE +#define TYPE isl_pw_aff +#include + +/* Return a set containing those elements in the domain + * of "pwaff" where it satisfies "fn" (if complement is 0) or + * does not satisfy "fn" (if complement is 1). + * + * The pieces with a NaN never belong to the result since + * NaN does not satisfy any property. + */ +static __isl_give isl_set *pw_aff_locus(__isl_take isl_pw_aff *pwaff, + __isl_give isl_basic_set *(*fn)(__isl_take isl_aff *aff, int rational, + void *user), + int complement, void *user) +{ + int i; + isl_set *set; + + if (!pwaff) + return NULL; + + set = isl_set_empty(isl_pw_aff_get_domain_space(pwaff)); + + for (i = 0; i < pwaff->n; ++i) { + isl_basic_set *bset; + isl_set *set_i, *locus; + isl_bool rational; + + if (isl_aff_is_nan(pwaff->p[i].aff)) + continue; + + rational = isl_set_has_rational(pwaff->p[i].set); + bset = fn(isl_aff_copy(pwaff->p[i].aff), rational, user); + locus = isl_set_from_basic_set(bset); + set_i = isl_set_copy(pwaff->p[i].set); + if (complement) + set_i = isl_set_subtract(set_i, locus); + else + set_i = isl_set_intersect(set_i, locus); + set = isl_set_union_disjoint(set, set_i); + } + + isl_pw_aff_free(pwaff); + + return set; +} + +/* Return a set containing those elements in the domain + * of "pa" where it is positive. + */ +__isl_give isl_set *isl_pw_aff_pos_set(__isl_take isl_pw_aff *pa) +{ + return pw_aff_locus(pa, &aff_pos_basic_set, 0, NULL); +} + +/* Return a set containing those elements in the domain + * of pwaff where it is non-negative. + */ +__isl_give isl_set *isl_pw_aff_nonneg_set(__isl_take isl_pw_aff *pwaff) +{ + return pw_aff_locus(pwaff, &aff_nonneg_basic_set, 0, NULL); +} + +/* Return a set containing those elements in the domain + * of pwaff where it is zero. + */ +__isl_give isl_set *isl_pw_aff_zero_set(__isl_take isl_pw_aff *pwaff) +{ + return pw_aff_locus(pwaff, &aff_zero_basic_set, 0, NULL); +} + +/* Return a set containing those elements in the domain + * of pwaff where it is not zero. + */ +__isl_give isl_set *isl_pw_aff_non_zero_set(__isl_take isl_pw_aff *pwaff) +{ + return pw_aff_locus(pwaff, &aff_zero_basic_set, 1, NULL); +} + +/* Bind the affine function "aff" to the parameter "id", + * returning the elements in the domain where the affine expression + * is equal to the parameter. + */ +__isl_give isl_basic_set *isl_aff_bind_id(__isl_take isl_aff *aff, + __isl_take isl_id *id) +{ + isl_space *space; + isl_aff *aff_id; + + space = isl_aff_get_domain_space(aff); + space = isl_space_add_param_id(space, isl_id_copy(id)); + + aff = isl_aff_align_params(aff, isl_space_copy(space)); + aff_id = isl_aff_param_on_domain_space_id(space, id); + + return isl_aff_eq_basic_set(aff, aff_id); +} + +/* Wrapper around isl_aff_bind_id for use as pw_aff_locus callback. + * "rational" should not be set. + */ +static __isl_give isl_basic_set *aff_bind_id(__isl_take isl_aff *aff, + int rational, void *user) +{ + isl_id *id = user; + + if (!aff) + return NULL; + if (rational) + isl_die(isl_aff_get_ctx(aff), isl_error_unsupported, + "rational binding not supported", goto error); + return isl_aff_bind_id(aff, isl_id_copy(id)); +error: + isl_aff_free(aff); + return NULL; +} + +/* Bind the piecewise affine function "pa" to the parameter "id", + * returning the elements in the domain where the expression + * is equal to the parameter. + */ +__isl_give isl_set *isl_pw_aff_bind_id(__isl_take isl_pw_aff *pa, + __isl_take isl_id *id) +{ + isl_set *bound; + + bound = pw_aff_locus(pa, &aff_bind_id, 0, id); + isl_id_free(id); + + return bound; +} + +/* Return a set containing those elements in the shared domain + * of pwaff1 and pwaff2 where pwaff1 is greater than (or equal) to pwaff2. + * + * We compute the difference on the shared domain and then construct + * the set of values where this difference is non-negative. + * If strict is set, we first subtract 1 from the difference. + * If equal is set, we only return the elements where pwaff1 and pwaff2 + * are equal. + */ +static __isl_give isl_set *pw_aff_gte_set(__isl_take isl_pw_aff *pwaff1, + __isl_take isl_pw_aff *pwaff2, int strict, int equal) +{ + isl_set *set1, *set2; + + set1 = isl_pw_aff_domain(isl_pw_aff_copy(pwaff1)); + set2 = isl_pw_aff_domain(isl_pw_aff_copy(pwaff2)); + set1 = isl_set_intersect(set1, set2); + pwaff1 = isl_pw_aff_intersect_domain(pwaff1, isl_set_copy(set1)); + pwaff2 = isl_pw_aff_intersect_domain(pwaff2, isl_set_copy(set1)); + pwaff1 = isl_pw_aff_add(pwaff1, isl_pw_aff_neg(pwaff2)); + + if (strict) { + isl_space *space = isl_set_get_space(set1); + isl_aff *aff; + aff = isl_aff_zero_on_domain(isl_local_space_from_space(space)); + aff = isl_aff_add_constant_si(aff, -1); + pwaff1 = isl_pw_aff_add(pwaff1, isl_pw_aff_alloc(set1, aff)); + } else + isl_set_free(set1); + + if (equal) + return isl_pw_aff_zero_set(pwaff1); + return isl_pw_aff_nonneg_set(pwaff1); +} + +/* Return a set containing those elements in the shared domain + * of pwaff1 and pwaff2 where pwaff1 is equal to pwaff2. + */ +__isl_give isl_set *isl_pw_aff_eq_set(__isl_take isl_pw_aff *pwaff1, + __isl_take isl_pw_aff *pwaff2) +{ + isl_pw_aff_align_params_bin(&pwaff1, &pwaff2); + return pw_aff_gte_set(pwaff1, pwaff2, 0, 1); +} + +/* Return a set containing those elements in the shared domain + * of pwaff1 and pwaff2 where pwaff1 is greater than or equal to pwaff2. + */ +__isl_give isl_set *isl_pw_aff_ge_set(__isl_take isl_pw_aff *pwaff1, + __isl_take isl_pw_aff *pwaff2) +{ + isl_pw_aff_align_params_bin(&pwaff1, &pwaff2); + return pw_aff_gte_set(pwaff1, pwaff2, 0, 0); +} + +/* Return a set containing those elements in the shared domain + * of pwaff1 and pwaff2 where pwaff1 is strictly greater than pwaff2. + */ +__isl_give isl_set *isl_pw_aff_gt_set(__isl_take isl_pw_aff *pwaff1, + __isl_take isl_pw_aff *pwaff2) +{ + isl_pw_aff_align_params_bin(&pwaff1, &pwaff2); + return pw_aff_gte_set(pwaff1, pwaff2, 1, 0); +} + +__isl_give isl_set *isl_pw_aff_le_set(__isl_take isl_pw_aff *pwaff1, + __isl_take isl_pw_aff *pwaff2) +{ + return isl_pw_aff_ge_set(pwaff2, pwaff1); +} + +__isl_give isl_set *isl_pw_aff_lt_set(__isl_take isl_pw_aff *pwaff1, + __isl_take isl_pw_aff *pwaff2) +{ + return isl_pw_aff_gt_set(pwaff2, pwaff1); +} + +/* Return a map containing pairs of elements in the domains of "pa1" and "pa2" + * where the function values are ordered in the same way as "order", + * which returns a set in the shared domain of its two arguments. + * + * Let "pa1" and "pa2" be defined on domains A and B respectively. + * We first pull back the two functions such that they are defined on + * the domain [A -> B]. Then we apply "order", resulting in a set + * in the space [A -> B]. Finally, we unwrap this set to obtain + * a map in the space A -> B. + */ +static __isl_give isl_map *isl_pw_aff_order_map( + __isl_take isl_pw_aff *pa1, __isl_take isl_pw_aff *pa2, + __isl_give isl_set *(*order)(__isl_take isl_pw_aff *pa1, + __isl_take isl_pw_aff *pa2)) +{ + isl_space *space1, *space2; + isl_multi_aff *ma; + isl_set *set; + + isl_pw_aff_align_params_bin(&pa1, &pa2); + space1 = isl_space_domain(isl_pw_aff_get_space(pa1)); + space2 = isl_space_domain(isl_pw_aff_get_space(pa2)); + space1 = isl_space_map_from_domain_and_range(space1, space2); + ma = isl_multi_aff_domain_map(isl_space_copy(space1)); + pa1 = isl_pw_aff_pullback_multi_aff(pa1, ma); + ma = isl_multi_aff_range_map(space1); + pa2 = isl_pw_aff_pullback_multi_aff(pa2, ma); + set = order(pa1, pa2); + + return isl_set_unwrap(set); +} + +/* Return a map containing pairs of elements in the domains of "pa1" and "pa2" + * where the function values are equal. + */ +__isl_give isl_map *isl_pw_aff_eq_map(__isl_take isl_pw_aff *pa1, + __isl_take isl_pw_aff *pa2) +{ + return isl_pw_aff_order_map(pa1, pa2, &isl_pw_aff_eq_set); +} + +/* Return a map containing pairs of elements in the domains of "pa1" and "pa2" + * where the function value of "pa1" is less than or equal to + * the function value of "pa2". + */ +__isl_give isl_map *isl_pw_aff_le_map(__isl_take isl_pw_aff *pa1, + __isl_take isl_pw_aff *pa2) +{ + return isl_pw_aff_order_map(pa1, pa2, &isl_pw_aff_le_set); +} + +/* Return a map containing pairs of elements in the domains of "pa1" and "pa2" + * where the function value of "pa1" is less than the function value of "pa2". + */ +__isl_give isl_map *isl_pw_aff_lt_map(__isl_take isl_pw_aff *pa1, + __isl_take isl_pw_aff *pa2) +{ + return isl_pw_aff_order_map(pa1, pa2, &isl_pw_aff_lt_set); +} + +/* Return a map containing pairs of elements in the domains of "pa1" and "pa2" + * where the function value of "pa1" is greater than or equal to + * the function value of "pa2". + */ +__isl_give isl_map *isl_pw_aff_ge_map(__isl_take isl_pw_aff *pa1, + __isl_take isl_pw_aff *pa2) +{ + return isl_pw_aff_order_map(pa1, pa2, &isl_pw_aff_ge_set); +} + +/* Return a map containing pairs of elements in the domains of "pa1" and "pa2" + * where the function value of "pa1" is greater than the function value + * of "pa2". + */ +__isl_give isl_map *isl_pw_aff_gt_map(__isl_take isl_pw_aff *pa1, + __isl_take isl_pw_aff *pa2) +{ + return isl_pw_aff_order_map(pa1, pa2, &isl_pw_aff_gt_set); +} + +/* Return a set containing those elements in the shared domain + * of the elements of list1 and list2 where each element in list1 + * has the relation specified by "fn" with each element in list2. + */ +static __isl_give isl_set *pw_aff_list_set(__isl_take isl_pw_aff_list *list1, + __isl_take isl_pw_aff_list *list2, + __isl_give isl_set *(*fn)(__isl_take isl_pw_aff *pwaff1, + __isl_take isl_pw_aff *pwaff2)) +{ + int i, j; + isl_ctx *ctx; + isl_set *set; + + if (!list1 || !list2) + goto error; + + ctx = isl_pw_aff_list_get_ctx(list1); + if (list1->n < 1 || list2->n < 1) + isl_die(ctx, isl_error_invalid, + "list should contain at least one element", goto error); + + set = isl_set_universe(isl_pw_aff_get_domain_space(list1->p[0])); + for (i = 0; i < list1->n; ++i) + for (j = 0; j < list2->n; ++j) { + isl_set *set_ij; + + set_ij = fn(isl_pw_aff_copy(list1->p[i]), + isl_pw_aff_copy(list2->p[j])); + set = isl_set_intersect(set, set_ij); + } + + isl_pw_aff_list_free(list1); + isl_pw_aff_list_free(list2); + return set; +error: + isl_pw_aff_list_free(list1); + isl_pw_aff_list_free(list2); + return NULL; +} + +/* Return a set containing those elements in the shared domain + * of the elements of list1 and list2 where each element in list1 + * is equal to each element in list2. + */ +__isl_give isl_set *isl_pw_aff_list_eq_set(__isl_take isl_pw_aff_list *list1, + __isl_take isl_pw_aff_list *list2) +{ + return pw_aff_list_set(list1, list2, &isl_pw_aff_eq_set); +} + +__isl_give isl_set *isl_pw_aff_list_ne_set(__isl_take isl_pw_aff_list *list1, + __isl_take isl_pw_aff_list *list2) +{ + return pw_aff_list_set(list1, list2, &isl_pw_aff_ne_set); +} + +/* Return a set containing those elements in the shared domain + * of the elements of list1 and list2 where each element in list1 + * is less than or equal to each element in list2. + */ +__isl_give isl_set *isl_pw_aff_list_le_set(__isl_take isl_pw_aff_list *list1, + __isl_take isl_pw_aff_list *list2) +{ + return pw_aff_list_set(list1, list2, &isl_pw_aff_le_set); +} + +__isl_give isl_set *isl_pw_aff_list_lt_set(__isl_take isl_pw_aff_list *list1, + __isl_take isl_pw_aff_list *list2) +{ + return pw_aff_list_set(list1, list2, &isl_pw_aff_lt_set); +} + +__isl_give isl_set *isl_pw_aff_list_ge_set(__isl_take isl_pw_aff_list *list1, + __isl_take isl_pw_aff_list *list2) +{ + return pw_aff_list_set(list1, list2, &isl_pw_aff_ge_set); +} + +__isl_give isl_set *isl_pw_aff_list_gt_set(__isl_take isl_pw_aff_list *list1, + __isl_take isl_pw_aff_list *list2) +{ + return pw_aff_list_set(list1, list2, &isl_pw_aff_gt_set); +} + + +/* Return a set containing those elements in the shared domain + * of pwaff1 and pwaff2 where pwaff1 is not equal to pwaff2. + */ +__isl_give isl_set *isl_pw_aff_ne_set(__isl_take isl_pw_aff *pwaff1, + __isl_take isl_pw_aff *pwaff2) +{ + isl_set *set_lt, *set_gt; + + isl_pw_aff_align_params_bin(&pwaff1, &pwaff2); + set_lt = isl_pw_aff_lt_set(isl_pw_aff_copy(pwaff1), + isl_pw_aff_copy(pwaff2)); + set_gt = isl_pw_aff_gt_set(pwaff1, pwaff2); + return isl_set_union_disjoint(set_lt, set_gt); +} + +__isl_give isl_pw_aff *isl_pw_aff_scale_down(__isl_take isl_pw_aff *pwaff, + isl_int v) +{ + int i; + + if (isl_int_is_one(v)) + return pwaff; + if (!isl_int_is_pos(v)) + isl_die(isl_pw_aff_get_ctx(pwaff), isl_error_invalid, + "factor needs to be positive", + return isl_pw_aff_free(pwaff)); + pwaff = isl_pw_aff_cow(pwaff); + if (!pwaff) + return NULL; + if (pwaff->n == 0) + return pwaff; + + for (i = 0; i < pwaff->n; ++i) { + pwaff->p[i].aff = isl_aff_scale_down(pwaff->p[i].aff, v); + if (!pwaff->p[i].aff) + return isl_pw_aff_free(pwaff); + } + + return pwaff; +} + +__isl_give isl_pw_aff *isl_pw_aff_floor(__isl_take isl_pw_aff *pwaff) +{ + struct isl_pw_aff_un_op_control control = { .fn_base = &isl_aff_floor }; + return isl_pw_aff_un_op(pwaff, &control); +} + +__isl_give isl_pw_aff *isl_pw_aff_ceil(__isl_take isl_pw_aff *pwaff) +{ + struct isl_pw_aff_un_op_control control = { .fn_base = &isl_aff_ceil }; + return isl_pw_aff_un_op(pwaff, &control); +} + +/* Assuming that "cond1" and "cond2" are disjoint, + * return an affine expression that is equal to pwaff1 on cond1 + * and to pwaff2 on cond2. + */ +static __isl_give isl_pw_aff *isl_pw_aff_select( + __isl_take isl_set *cond1, __isl_take isl_pw_aff *pwaff1, + __isl_take isl_set *cond2, __isl_take isl_pw_aff *pwaff2) +{ + pwaff1 = isl_pw_aff_intersect_domain(pwaff1, cond1); + pwaff2 = isl_pw_aff_intersect_domain(pwaff2, cond2); + + return isl_pw_aff_add_disjoint(pwaff1, pwaff2); +} + +/* Return an affine expression that is equal to pwaff_true for elements + * where "cond" is non-zero and to pwaff_false for elements where "cond" + * is zero. + * That is, return cond ? pwaff_true : pwaff_false; + * + * If "cond" involves and NaN, then we conservatively return a NaN + * on its entire domain. In principle, we could consider the pieces + * where it is NaN separately from those where it is not. + * + * If "pwaff_true" and "pwaff_false" are obviously equal to each other, + * then only use the domain of "cond" to restrict the domain. + */ +__isl_give isl_pw_aff *isl_pw_aff_cond(__isl_take isl_pw_aff *cond, + __isl_take isl_pw_aff *pwaff_true, __isl_take isl_pw_aff *pwaff_false) +{ + isl_set *cond_true, *cond_false; + isl_bool equal; + + if (!cond) + goto error; + if (isl_pw_aff_involves_nan(cond)) { + isl_space *space = isl_pw_aff_get_domain_space(cond); + isl_local_space *ls = isl_local_space_from_space(space); + isl_pw_aff_free(cond); + isl_pw_aff_free(pwaff_true); + isl_pw_aff_free(pwaff_false); + return isl_pw_aff_nan_on_domain(ls); + } + + pwaff_true = isl_pw_aff_align_params(pwaff_true, + isl_pw_aff_get_space(pwaff_false)); + pwaff_false = isl_pw_aff_align_params(pwaff_false, + isl_pw_aff_get_space(pwaff_true)); + equal = isl_pw_aff_plain_is_equal(pwaff_true, pwaff_false); + if (equal < 0) + goto error; + if (equal) { + isl_set *dom; + + dom = isl_set_coalesce(isl_pw_aff_domain(cond)); + isl_pw_aff_free(pwaff_false); + return isl_pw_aff_intersect_domain(pwaff_true, dom); + } + + cond_true = isl_pw_aff_non_zero_set(isl_pw_aff_copy(cond)); + cond_false = isl_pw_aff_zero_set(cond); + return isl_pw_aff_select(cond_true, pwaff_true, + cond_false, pwaff_false); +error: + isl_pw_aff_free(cond); + isl_pw_aff_free(pwaff_true); + isl_pw_aff_free(pwaff_false); + return NULL; +} + +isl_bool isl_aff_is_cst(__isl_keep isl_aff *aff) +{ + int pos; + + if (!aff) + return isl_bool_error; + + pos = isl_seq_first_non_zero(aff->v->el + 2, aff->v->size - 2); + return isl_bool_ok(pos == -1); +} + +/* Check whether pwaff is a piecewise constant. + */ +isl_bool isl_pw_aff_is_cst(__isl_keep isl_pw_aff *pwaff) +{ + int i; + + if (!pwaff) + return isl_bool_error; + + for (i = 0; i < pwaff->n; ++i) { + isl_bool is_cst = isl_aff_is_cst(pwaff->p[i].aff); + if (is_cst < 0 || !is_cst) + return is_cst; + } + + return isl_bool_true; +} + +/* Return the product of "aff1" and "aff2". + * + * If either of the two is NaN, then the result is NaN. + * + * Otherwise, at least one of "aff1" or "aff2" needs to be a constant. + */ +__isl_give isl_aff *isl_aff_mul(__isl_take isl_aff *aff1, + __isl_take isl_aff *aff2) +{ + if (!aff1 || !aff2) + goto error; + + if (isl_aff_is_nan(aff1)) { + isl_aff_free(aff2); + return aff1; + } + if (isl_aff_is_nan(aff2)) { + isl_aff_free(aff1); + return aff2; + } + + if (!isl_aff_is_cst(aff2) && isl_aff_is_cst(aff1)) + return isl_aff_mul(aff2, aff1); + + if (!isl_aff_is_cst(aff2)) + isl_die(isl_aff_get_ctx(aff1), isl_error_invalid, + "at least one affine expression should be constant", + goto error); + + aff1 = isl_aff_cow(aff1); + if (!aff1 || !aff2) + goto error; + + aff1 = isl_aff_scale(aff1, aff2->v->el[1]); + aff1 = isl_aff_scale_down(aff1, aff2->v->el[0]); + + isl_aff_free(aff2); + return aff1; +error: + isl_aff_free(aff1); + isl_aff_free(aff2); + return NULL; +} + +/* Divide "aff1" by "aff2", assuming "aff2" is a constant. + * + * If either of the two is NaN, then the result is NaN. + * A division by zero also results in NaN. + */ +__isl_give isl_aff *isl_aff_div(__isl_take isl_aff *aff1, + __isl_take isl_aff *aff2) +{ + isl_bool is_cst, is_zero; + int neg; + + if (!aff1 || !aff2) + goto error; + + if (isl_aff_is_nan(aff1)) { + isl_aff_free(aff2); + return aff1; + } + if (isl_aff_is_nan(aff2)) { + isl_aff_free(aff1); + return aff2; + } + + is_cst = isl_aff_is_cst(aff2); + if (is_cst < 0) + goto error; + if (!is_cst) + isl_die(isl_aff_get_ctx(aff2), isl_error_invalid, + "second argument should be a constant", goto error); + is_zero = isl_aff_plain_is_zero(aff2); + if (is_zero < 0) + goto error; + if (is_zero) + return set_nan_free(aff1, aff2); + + neg = isl_int_is_neg(aff2->v->el[1]); + if (neg) { + isl_int_neg(aff2->v->el[0], aff2->v->el[0]); + isl_int_neg(aff2->v->el[1], aff2->v->el[1]); + } + + aff1 = isl_aff_scale(aff1, aff2->v->el[0]); + aff1 = isl_aff_scale_down(aff1, aff2->v->el[1]); + + if (neg) { + isl_int_neg(aff2->v->el[0], aff2->v->el[0]); + isl_int_neg(aff2->v->el[1], aff2->v->el[1]); + } + + isl_aff_free(aff2); + return aff1; +error: + isl_aff_free(aff1); + isl_aff_free(aff2); + return NULL; +} + +__isl_give isl_pw_aff *isl_pw_aff_add(__isl_take isl_pw_aff *pwaff1, + __isl_take isl_pw_aff *pwaff2) +{ + isl_pw_aff_align_params_bin(&pwaff1, &pwaff2); + return isl_pw_aff_on_shared_domain(pwaff1, pwaff2, &isl_aff_add); +} + +__isl_give isl_pw_aff *isl_pw_aff_mul(__isl_take isl_pw_aff *pwaff1, + __isl_take isl_pw_aff *pwaff2) +{ + isl_pw_aff_align_params_bin(&pwaff1, &pwaff2); + return isl_pw_aff_on_shared_domain(pwaff1, pwaff2, &isl_aff_mul); +} + +/* Divide "pa1" by "pa2", assuming "pa2" is a piecewise constant. + */ +__isl_give isl_pw_aff *isl_pw_aff_div(__isl_take isl_pw_aff *pa1, + __isl_take isl_pw_aff *pa2) +{ + int is_cst; + + is_cst = isl_pw_aff_is_cst(pa2); + if (is_cst < 0) + goto error; + if (!is_cst) + isl_die(isl_pw_aff_get_ctx(pa2), isl_error_invalid, + "second argument should be a piecewise constant", + goto error); + isl_pw_aff_align_params_bin(&pa1, &pa2); + return isl_pw_aff_on_shared_domain(pa1, pa2, &isl_aff_div); +error: + isl_pw_aff_free(pa1); + isl_pw_aff_free(pa2); + return NULL; +} + +/* Compute the quotient of the integer division of "pa1" by "pa2" + * with rounding towards zero. + * "pa2" is assumed to be a piecewise constant. + * + * In particular, return + * + * pa1 >= 0 ? floor(pa1/pa2) : ceil(pa1/pa2) + * + */ +__isl_give isl_pw_aff *isl_pw_aff_tdiv_q(__isl_take isl_pw_aff *pa1, + __isl_take isl_pw_aff *pa2) +{ + int is_cst; + isl_set *cond; + isl_pw_aff *f, *c; + + is_cst = isl_pw_aff_is_cst(pa2); + if (is_cst < 0) + goto error; + if (!is_cst) + isl_die(isl_pw_aff_get_ctx(pa2), isl_error_invalid, + "second argument should be a piecewise constant", + goto error); + + pa1 = isl_pw_aff_div(pa1, pa2); + + cond = isl_pw_aff_nonneg_set(isl_pw_aff_copy(pa1)); + f = isl_pw_aff_floor(isl_pw_aff_copy(pa1)); + c = isl_pw_aff_ceil(pa1); + return isl_pw_aff_cond(isl_set_indicator_function(cond), f, c); +error: + isl_pw_aff_free(pa1); + isl_pw_aff_free(pa2); + return NULL; +} + +/* Compute the remainder of the integer division of "pa1" by "pa2" + * with rounding towards zero. + * "pa2" is assumed to be a piecewise constant. + * + * In particular, return + * + * pa1 - pa2 * (pa1 >= 0 ? floor(pa1/pa2) : ceil(pa1/pa2)) + * + */ +__isl_give isl_pw_aff *isl_pw_aff_tdiv_r(__isl_take isl_pw_aff *pa1, + __isl_take isl_pw_aff *pa2) +{ + int is_cst; + isl_pw_aff *res; + + is_cst = isl_pw_aff_is_cst(pa2); + if (is_cst < 0) + goto error; + if (!is_cst) + isl_die(isl_pw_aff_get_ctx(pa2), isl_error_invalid, + "second argument should be a piecewise constant", + goto error); + res = isl_pw_aff_tdiv_q(isl_pw_aff_copy(pa1), isl_pw_aff_copy(pa2)); + res = isl_pw_aff_mul(pa2, res); + res = isl_pw_aff_sub(pa1, res); + return res; +error: + isl_pw_aff_free(pa1); + isl_pw_aff_free(pa2); + return NULL; +} + +/* Does either of "pa1" or "pa2" involve any NaN? + */ +static isl_bool either_involves_nan(__isl_keep isl_pw_aff *pa1, + __isl_keep isl_pw_aff *pa2) +{ + isl_bool has_nan; + + has_nan = isl_pw_aff_involves_nan(pa1); + if (has_nan < 0 || has_nan) + return has_nan; + return isl_pw_aff_involves_nan(pa2); +} + +/* Return a piecewise affine expression defined on the specified domain + * that represents NaN. + */ +static __isl_give isl_pw_aff *nan_on_domain_set(__isl_take isl_set *dom) +{ + isl_local_space *ls; + isl_pw_aff *pa; + + ls = isl_local_space_from_space(isl_set_get_space(dom)); + pa = isl_pw_aff_nan_on_domain(ls); + pa = isl_pw_aff_intersect_domain(pa, dom); + + return pa; +} + +/* Replace "pa1" and "pa2" (at least one of which involves a NaN) + * by a NaN on their shared domain. + * + * In principle, the result could be refined to only being NaN + * on the parts of this domain where at least one of "pa1" or "pa2" is NaN. + */ +static __isl_give isl_pw_aff *replace_by_nan(__isl_take isl_pw_aff *pa1, + __isl_take isl_pw_aff *pa2) +{ + isl_set *dom; + + dom = isl_set_intersect(isl_pw_aff_domain(pa1), isl_pw_aff_domain(pa2)); + return nan_on_domain_set(dom); +} + +static __isl_give isl_pw_aff *pw_aff_min(__isl_take isl_pw_aff *pwaff1, + __isl_take isl_pw_aff *pwaff2) +{ + isl_set *le; + isl_set *dom; + + dom = isl_set_intersect(isl_pw_aff_domain(isl_pw_aff_copy(pwaff1)), + isl_pw_aff_domain(isl_pw_aff_copy(pwaff2))); + le = isl_pw_aff_le_set(isl_pw_aff_copy(pwaff1), + isl_pw_aff_copy(pwaff2)); + dom = isl_set_subtract(dom, isl_set_copy(le)); + return isl_pw_aff_select(le, pwaff1, dom, pwaff2); +} + +static __isl_give isl_pw_aff *pw_aff_max(__isl_take isl_pw_aff *pwaff1, + __isl_take isl_pw_aff *pwaff2) +{ + isl_set *ge; + isl_set *dom; + + dom = isl_set_intersect(isl_pw_aff_domain(isl_pw_aff_copy(pwaff1)), + isl_pw_aff_domain(isl_pw_aff_copy(pwaff2))); + ge = isl_pw_aff_ge_set(isl_pw_aff_copy(pwaff1), + isl_pw_aff_copy(pwaff2)); + dom = isl_set_subtract(dom, isl_set_copy(ge)); + return isl_pw_aff_select(ge, pwaff1, dom, pwaff2); +} + +/* Return an expression for the minimum (if "max" is not set) or + * the maximum (if "max" is set) of "pa1" and "pa2". + * If either expression involves any NaN, then return a NaN + * on the shared domain as result. + */ +static __isl_give isl_pw_aff *pw_aff_min_max(__isl_take isl_pw_aff *pa1, + __isl_take isl_pw_aff *pa2, int max) +{ + isl_bool has_nan; + + has_nan = either_involves_nan(pa1, pa2); + if (has_nan < 0) + pa1 = isl_pw_aff_free(pa1); + else if (has_nan) + return replace_by_nan(pa1, pa2); + + isl_pw_aff_align_params_bin(&pa1, &pa2); + if (max) + return pw_aff_max(pa1, pa2); + else + return pw_aff_min(pa1, pa2); +} + +/* Return an expression for the minimum of "pwaff1" and "pwaff2". + */ +__isl_give isl_pw_aff *isl_pw_aff_min(__isl_take isl_pw_aff *pwaff1, + __isl_take isl_pw_aff *pwaff2) +{ + return pw_aff_min_max(pwaff1, pwaff2, 0); +} + +/* Return an expression for the maximum of "pwaff1" and "pwaff2". + */ +__isl_give isl_pw_aff *isl_pw_aff_max(__isl_take isl_pw_aff *pwaff1, + __isl_take isl_pw_aff *pwaff2) +{ + return pw_aff_min_max(pwaff1, pwaff2, 1); +} + +/* Does "pa" not involve any NaN? + */ +static isl_bool pw_aff_no_nan(__isl_keep isl_pw_aff *pa, void *user) +{ + return isl_bool_not(isl_pw_aff_involves_nan(pa)); +} + +/* Does any element of "list" involve any NaN? + * + * That is, is it not the case that every element does not involve any NaN? + */ +static isl_bool isl_pw_aff_list_involves_nan(__isl_keep isl_pw_aff_list *list) +{ + return isl_bool_not(isl_pw_aff_list_every(list, &pw_aff_no_nan, NULL)); +} + +/* Replace "list" (consisting of "n" elements, of which + * at least one element involves a NaN) + * by a NaN on the shared domain of the elements. + * + * In principle, the result could be refined to only being NaN + * on the parts of this domain where at least one of the elements is NaN. + */ +static __isl_give isl_pw_aff *replace_list_by_nan( + __isl_take isl_pw_aff_list *list, int n) +{ + int i; + isl_set *dom; + + dom = isl_pw_aff_domain(isl_pw_aff_list_get_at(list, 0)); + for (i = 1; i < n; ++i) { + isl_set *dom_i; + + dom_i = isl_pw_aff_domain(isl_pw_aff_list_get_at(list, i)); + dom = isl_set_intersect(dom, dom_i); + } + + isl_pw_aff_list_free(list); + return nan_on_domain_set(dom); +} + +/* Return the set where the element at "pos1" of "list" is less than or + * equal to the element at "pos2". + * Equality is only allowed if "pos1" is smaller than "pos2". + */ +static __isl_give isl_set *less(__isl_keep isl_pw_aff_list *list, + int pos1, int pos2) +{ + isl_pw_aff *pa1, *pa2; + + pa1 = isl_pw_aff_list_get_at(list, pos1); + pa2 = isl_pw_aff_list_get_at(list, pos2); + + if (pos1 < pos2) + return isl_pw_aff_le_set(pa1, pa2); + else + return isl_pw_aff_lt_set(pa1, pa2); +} + +/* Return an isl_pw_aff that maps each element in the intersection of the + * domains of the piecewise affine expressions in "list" + * to the maximal (if "max" is set) or minimal (if "max" is not set) + * expression in "list" at that element. + * If any expression involves any NaN, then return a NaN + * on the shared domain as result. + * + * If "list" has n elements, then the result consists of n pieces, + * where, in the case of a minimum, each piece has as value expression + * the value expression of one of the elements and as domain + * the set of elements where that value expression + * is less than (or equal) to the other value expressions. + * In the case of a maximum, the condition is + * that all the other value expressions are less than (or equal) + * to the given value expression. + * + * In order to produce disjoint pieces, a pair of elements + * in the original domain is only allowed to be equal to each other + * on exactly one of the two pieces corresponding to the two elements. + * The position in the list is used to break ties. + * In particular, in the case of a minimum, + * in the piece corresponding to a given element, + * this element is allowed to be equal to any later element in the list, + * but not to any earlier element in the list. + */ +static __isl_give isl_pw_aff *isl_pw_aff_list_opt( + __isl_take isl_pw_aff_list *list, int max) +{ + int i, j; + isl_bool has_nan; + isl_size n; + isl_space *space; + isl_pw_aff *pa, *res; + + n = isl_pw_aff_list_size(list); + if (n < 0) + goto error; + if (n < 1) + isl_die(isl_pw_aff_list_get_ctx(list), isl_error_invalid, + "list should contain at least one element", goto error); + + has_nan = isl_pw_aff_list_involves_nan(list); + if (has_nan < 0) + goto error; + if (has_nan) + return replace_list_by_nan(list, n); + + pa = isl_pw_aff_list_get_at(list, 0); + space = isl_pw_aff_get_space(pa); + isl_pw_aff_free(pa); + res = isl_pw_aff_empty(space); + + for (i = 0; i < n; ++i) { + pa = isl_pw_aff_list_get_at(list, i); + for (j = 0; j < n; ++j) { + isl_set *dom; + + if (j == i) + continue; + if (max) + dom = less(list, j, i); + else + dom = less(list, i, j); + + pa = isl_pw_aff_intersect_domain(pa, dom); + } + res = isl_pw_aff_add_disjoint(res, pa); + } + + isl_pw_aff_list_free(list); + return res; +error: + isl_pw_aff_list_free(list); + return NULL; +} + +/* Return an isl_pw_aff that maps each element in the intersection of the + * domains of the elements of list to the minimal corresponding affine + * expression. + */ +__isl_give isl_pw_aff *isl_pw_aff_list_min(__isl_take isl_pw_aff_list *list) +{ + return isl_pw_aff_list_opt(list, 0); +} + +/* Return an isl_pw_aff that maps each element in the intersection of the + * domains of the elements of list to the maximal corresponding affine + * expression. + */ +__isl_give isl_pw_aff *isl_pw_aff_list_max(__isl_take isl_pw_aff_list *list) +{ + return isl_pw_aff_list_opt(list, 1); +} + +/* Mark the domains of "pwaff" as rational. + */ +__isl_give isl_pw_aff *isl_pw_aff_set_rational(__isl_take isl_pw_aff *pwaff) +{ + int i; + + pwaff = isl_pw_aff_cow(pwaff); + if (!pwaff) + return NULL; + if (pwaff->n == 0) + return pwaff; + + for (i = 0; i < pwaff->n; ++i) { + pwaff->p[i].set = isl_set_set_rational(pwaff->p[i].set); + if (!pwaff->p[i].set) + return isl_pw_aff_free(pwaff); + } + + return pwaff; +} + +/* Mark the domains of the elements of "list" as rational. + */ +__isl_give isl_pw_aff_list *isl_pw_aff_list_set_rational( + __isl_take isl_pw_aff_list *list) +{ + int i, n; + + if (!list) + return NULL; + if (list->n == 0) + return list; + + n = list->n; + for (i = 0; i < n; ++i) { + isl_pw_aff *pa; + + pa = isl_pw_aff_list_get_pw_aff(list, i); + pa = isl_pw_aff_set_rational(pa); + list = isl_pw_aff_list_set_pw_aff(list, i, pa); + } + + return list; +} + +/* Do the parameters of "aff" match those of "space"? + */ +isl_bool isl_aff_matching_params(__isl_keep isl_aff *aff, + __isl_keep isl_space *space) +{ + isl_space *aff_space; + isl_bool match; + + if (!aff || !space) + return isl_bool_error; + + aff_space = isl_aff_get_domain_space(aff); + + match = isl_space_has_equal_params(space, aff_space); + + isl_space_free(aff_space); + return match; +} + +/* Check that the domain space of "aff" matches "space". + */ +isl_stat isl_aff_check_match_domain_space(__isl_keep isl_aff *aff, + __isl_keep isl_space *space) +{ + isl_space *aff_space; + isl_bool match; + + if (!aff || !space) + return isl_stat_error; + + aff_space = isl_aff_get_domain_space(aff); + + match = isl_space_has_equal_params(space, aff_space); + if (match < 0) + goto error; + if (!match) + isl_die(isl_aff_get_ctx(aff), isl_error_invalid, + "parameters don't match", goto error); + match = isl_space_tuple_is_equal(space, isl_dim_in, + aff_space, isl_dim_set); + if (match < 0) + goto error; + if (!match) + isl_die(isl_aff_get_ctx(aff), isl_error_invalid, + "domains don't match", goto error); + isl_space_free(aff_space); + return isl_stat_ok; +error: + isl_space_free(aff_space); + return isl_stat_error; +} + +/* Return the shared (universe) domain of the elements of "ma". + * + * Since an isl_multi_aff (and an isl_aff) is always total, + * the domain is always the universe set in its domain space. + * This is a helper function for use in the generic isl_multi_*_bind. + */ +static __isl_give isl_basic_set *isl_multi_aff_domain( + __isl_take isl_multi_aff *ma) +{ + isl_space *space; + + space = isl_multi_aff_get_space(ma); + isl_multi_aff_free(ma); + + return isl_basic_set_universe(isl_space_domain(space)); +} + +#undef BASE +#define BASE aff + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#undef DOMBASE +#define DOMBASE set +#include +#include +#include + +#undef DOMBASE +#define DOMBASE basic_set +#include + +/* Construct an isl_multi_aff living in "space" that corresponds + * to the affine transformation matrix "mat". + */ +__isl_give isl_multi_aff *isl_multi_aff_from_aff_mat( + __isl_take isl_space *space, __isl_take isl_mat *mat) +{ + isl_ctx *ctx; + isl_local_space *ls = NULL; + isl_multi_aff *ma = NULL; + isl_size n_row, n_col, n_out, total; + int i; + + if (!space || !mat) + goto error; + + ctx = isl_mat_get_ctx(mat); + + n_row = isl_mat_rows(mat); + n_col = isl_mat_cols(mat); + n_out = isl_space_dim(space, isl_dim_out); + total = isl_space_dim(space, isl_dim_all); + if (n_row < 0 || n_col < 0 || n_out < 0 || total < 0) + goto error; + if (n_row < 1) + isl_die(ctx, isl_error_invalid, + "insufficient number of rows", goto error); + if (n_col < 1) + isl_die(ctx, isl_error_invalid, + "insufficient number of columns", goto error); + if (1 + n_out != n_row || 2 + total != n_row + n_col) + isl_die(ctx, isl_error_invalid, + "dimension mismatch", goto error); + + ma = isl_multi_aff_zero(isl_space_copy(space)); + space = isl_space_domain(space); + ls = isl_local_space_from_space(isl_space_copy(space)); + + for (i = 0; i < n_row - 1; ++i) { + isl_vec *v; + isl_aff *aff; + + v = isl_vec_alloc(ctx, 1 + n_col); + if (!v) + goto error; + isl_int_set(v->el[0], mat->row[0][0]); + isl_seq_cpy(v->el + 1, mat->row[1 + i], n_col); + v = isl_vec_normalize(v); + aff = isl_aff_alloc_vec_validated(isl_local_space_copy(ls), v); + ma = isl_multi_aff_set_aff(ma, i, aff); + } + + isl_space_free(space); + isl_local_space_free(ls); + isl_mat_free(mat); + return ma; +error: + isl_space_free(space); + isl_local_space_free(ls); + isl_mat_free(mat); + isl_multi_aff_free(ma); + return NULL; +} + +/* Return the constant terms of the affine expressions of "ma". + */ +__isl_give isl_multi_val *isl_multi_aff_get_constant_multi_val( + __isl_keep isl_multi_aff *ma) +{ + int i; + isl_size n; + isl_space *space; + isl_multi_val *mv; + + n = isl_multi_aff_size(ma); + if (n < 0) + return NULL; + space = isl_space_range(isl_multi_aff_get_space(ma)); + space = isl_space_drop_all_params(space); + mv = isl_multi_val_zero(space); + + for (i = 0; i < n; ++i) { + isl_aff *aff; + isl_val *val; + + aff = isl_multi_aff_get_at(ma, i); + val = isl_aff_get_constant_val(aff); + isl_aff_free(aff); + mv = isl_multi_val_set_at(mv, i, val); + } + + return mv; +} + +/* Remove any internal structure of the domain of "ma". + * If there is any such internal structure in the input, + * then the name of the corresponding space is also removed. + */ +__isl_give isl_multi_aff *isl_multi_aff_flatten_domain( + __isl_take isl_multi_aff *ma) +{ + isl_space *space; + + if (!ma) + return NULL; + + if (!ma->space->nested[0]) + return ma; + + space = isl_multi_aff_get_space(ma); + space = isl_space_flatten_domain(space); + ma = isl_multi_aff_reset_space(ma, space); + + return ma; +} + +/* Given a map space, return an isl_multi_aff that maps a wrapped copy + * of the space to its domain. + */ +__isl_give isl_multi_aff *isl_multi_aff_domain_map(__isl_take isl_space *space) +{ + int i; + isl_size n_in; + isl_local_space *ls; + isl_multi_aff *ma; + + if (!space) + return NULL; + if (!isl_space_is_map(space)) + isl_die(isl_space_get_ctx(space), isl_error_invalid, + "not a map space", goto error); + + n_in = isl_space_dim(space, isl_dim_in); + if (n_in < 0) + goto error; + space = isl_space_domain_map(space); + + ma = isl_multi_aff_alloc(isl_space_copy(space)); + if (n_in == 0) { + isl_space_free(space); + return ma; + } + + space = isl_space_domain(space); + ls = isl_local_space_from_space(space); + for (i = 0; i < n_in; ++i) { + isl_aff *aff; + + aff = isl_aff_var_on_domain(isl_local_space_copy(ls), + isl_dim_set, i); + ma = isl_multi_aff_set_aff(ma, i, aff); + } + isl_local_space_free(ls); + return ma; +error: + isl_space_free(space); + return NULL; +} + +/* This function performs the same operation as isl_multi_aff_domain_map, + * but is considered as a function on an isl_space when exported. + */ +__isl_give isl_multi_aff *isl_space_domain_map_multi_aff( + __isl_take isl_space *space) +{ + return isl_multi_aff_domain_map(space); +} + +/* Given a map space, return an isl_multi_aff that maps a wrapped copy + * of the space to its range. + */ +__isl_give isl_multi_aff *isl_multi_aff_range_map(__isl_take isl_space *space) +{ + int i; + isl_size n_in, n_out; + isl_local_space *ls; + isl_multi_aff *ma; + + if (!space) + return NULL; + if (!isl_space_is_map(space)) + isl_die(isl_space_get_ctx(space), isl_error_invalid, + "not a map space", goto error); + + n_in = isl_space_dim(space, isl_dim_in); + n_out = isl_space_dim(space, isl_dim_out); + if (n_in < 0 || n_out < 0) + goto error; + space = isl_space_range_map(space); + + ma = isl_multi_aff_alloc(isl_space_copy(space)); + if (n_out == 0) { + isl_space_free(space); + return ma; + } + + space = isl_space_domain(space); + ls = isl_local_space_from_space(space); + for (i = 0; i < n_out; ++i) { + isl_aff *aff; + + aff = isl_aff_var_on_domain(isl_local_space_copy(ls), + isl_dim_set, n_in + i); + ma = isl_multi_aff_set_aff(ma, i, aff); + } + isl_local_space_free(ls); + return ma; +error: + isl_space_free(space); + return NULL; +} + +/* This function performs the same operation as isl_multi_aff_range_map, + * but is considered as a function on an isl_space when exported. + */ +__isl_give isl_multi_aff *isl_space_range_map_multi_aff( + __isl_take isl_space *space) +{ + return isl_multi_aff_range_map(space); +} + +/* Given a map space, return an isl_pw_multi_aff that maps a wrapped copy + * of the space to its domain. + */ +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_domain_map( + __isl_take isl_space *space) +{ + return isl_pw_multi_aff_from_multi_aff(isl_multi_aff_domain_map(space)); +} + +/* This function performs the same operation as isl_pw_multi_aff_domain_map, + * but is considered as a function on an isl_space when exported. + */ +__isl_give isl_pw_multi_aff *isl_space_domain_map_pw_multi_aff( + __isl_take isl_space *space) +{ + return isl_pw_multi_aff_domain_map(space); +} + +/* Given a map space, return an isl_pw_multi_aff that maps a wrapped copy + * of the space to its range. + */ +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_range_map( + __isl_take isl_space *space) +{ + return isl_pw_multi_aff_from_multi_aff(isl_multi_aff_range_map(space)); +} + +/* This function performs the same operation as isl_pw_multi_aff_range_map, + * but is considered as a function on an isl_space when exported. + */ +__isl_give isl_pw_multi_aff *isl_space_range_map_pw_multi_aff( + __isl_take isl_space *space) +{ + return isl_pw_multi_aff_range_map(space); +} + +/* Given the space of a set and a range of set dimensions, + * construct an isl_multi_aff that projects out those dimensions. + */ +__isl_give isl_multi_aff *isl_multi_aff_project_out_map( + __isl_take isl_space *space, enum isl_dim_type type, + unsigned first, unsigned n) +{ + int i; + isl_size dim; + isl_local_space *ls; + isl_multi_aff *ma; + + if (!space) + return NULL; + if (!isl_space_is_set(space)) + isl_die(isl_space_get_ctx(space), isl_error_unsupported, + "expecting set space", goto error); + if (type != isl_dim_set) + isl_die(isl_space_get_ctx(space), isl_error_invalid, + "only set dimensions can be projected out", goto error); + if (isl_space_check_range(space, type, first, n) < 0) + goto error; + + dim = isl_space_dim(space, isl_dim_set); + if (dim < 0) + goto error; + + space = isl_space_from_domain(space); + space = isl_space_add_dims(space, isl_dim_out, dim - n); + + if (dim == n) + return isl_multi_aff_alloc(space); + + ma = isl_multi_aff_alloc(isl_space_copy(space)); + space = isl_space_domain(space); + ls = isl_local_space_from_space(space); + + for (i = 0; i < first; ++i) { + isl_aff *aff; + + aff = isl_aff_var_on_domain(isl_local_space_copy(ls), + isl_dim_set, i); + ma = isl_multi_aff_set_aff(ma, i, aff); + } + + for (i = 0; i < dim - (first + n); ++i) { + isl_aff *aff; + + aff = isl_aff_var_on_domain(isl_local_space_copy(ls), + isl_dim_set, first + n + i); + ma = isl_multi_aff_set_aff(ma, first + i, aff); + } + + isl_local_space_free(ls); + return ma; +error: + isl_space_free(space); + return NULL; +} + +/* Given the space of a set and a range of set dimensions, + * construct an isl_pw_multi_aff that projects out those dimensions. + */ +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_project_out_map( + __isl_take isl_space *space, enum isl_dim_type type, + unsigned first, unsigned n) +{ + isl_multi_aff *ma; + + ma = isl_multi_aff_project_out_map(space, type, first, n); + return isl_pw_multi_aff_from_multi_aff(ma); +} + +/* This function performs the same operation as isl_pw_multi_aff_from_multi_aff, + * but is considered as a function on an isl_multi_aff when exported. + */ +__isl_give isl_pw_multi_aff *isl_multi_aff_to_pw_multi_aff( + __isl_take isl_multi_aff *ma) +{ + return isl_pw_multi_aff_from_multi_aff(ma); +} + +/* Create a piecewise multi-affine expression in the given space that maps each + * input dimension to the corresponding output dimension. + */ +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_identity( + __isl_take isl_space *space) +{ + return isl_pw_multi_aff_from_multi_aff(isl_multi_aff_identity(space)); +} + +/* Create a piecewise multi expression that maps elements in the given space + * to themselves. + */ +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_identity_on_domain_space( + __isl_take isl_space *space) +{ + isl_multi_aff *ma; + + ma = isl_multi_aff_identity_on_domain_space(space); + return isl_pw_multi_aff_from_multi_aff(ma); +} + +/* This function performs the same operation as + * isl_pw_multi_aff_identity_on_domain_space, + * but is considered as a function on an isl_space when exported. + */ +__isl_give isl_pw_multi_aff *isl_space_identity_pw_multi_aff_on_domain( + __isl_take isl_space *space) +{ + return isl_pw_multi_aff_identity_on_domain_space(space); +} + +/* Exploit the equalities in "eq" to simplify the affine expressions. + */ +static __isl_give isl_multi_aff *isl_multi_aff_substitute_equalities( + __isl_take isl_multi_aff *maff, __isl_take isl_basic_set *eq) +{ + isl_size n; + int i; + + n = isl_multi_aff_size(maff); + if (n < 0 || !eq) + goto error; + + for (i = 0; i < n; ++i) { + isl_aff *aff; + + aff = isl_multi_aff_take_at(maff, i); + aff = isl_aff_substitute_equalities(aff, + isl_basic_set_copy(eq)); + maff = isl_multi_aff_restore_at(maff, i, aff); + } + + isl_basic_set_free(eq); + return maff; +error: + isl_basic_set_free(eq); + isl_multi_aff_free(maff); + return NULL; +} + +__isl_give isl_multi_aff *isl_multi_aff_scale(__isl_take isl_multi_aff *maff, + isl_int f) +{ + isl_size n; + int i; + + n = isl_multi_aff_size(maff); + if (n < 0) + return isl_multi_aff_free(maff); + + for (i = 0; i < n; ++i) { + isl_aff *aff; + + aff = isl_multi_aff_take_at(maff, i); + aff = isl_aff_scale(aff, f); + maff = isl_multi_aff_restore_at(maff, i, aff); + } + + return maff; +} + +__isl_give isl_multi_aff *isl_multi_aff_add_on_domain(__isl_keep isl_set *dom, + __isl_take isl_multi_aff *maff1, __isl_take isl_multi_aff *maff2) +{ + maff1 = isl_multi_aff_add(maff1, maff2); + maff1 = isl_multi_aff_gist(maff1, isl_set_copy(dom)); + return maff1; +} + +isl_bool isl_multi_aff_is_empty(__isl_keep isl_multi_aff *maff) +{ + if (!maff) + return isl_bool_error; + + return isl_bool_false; +} + +/* Return the set of domain elements where "ma1" is lexicographically + * smaller than or equal to "ma2". + */ +__isl_give isl_set *isl_multi_aff_lex_le_set(__isl_take isl_multi_aff *ma1, + __isl_take isl_multi_aff *ma2) +{ + return isl_multi_aff_lex_ge_set(ma2, ma1); +} + +/* Return the set of domain elements where "ma1" is lexicographically + * smaller than "ma2". + */ +__isl_give isl_set *isl_multi_aff_lex_lt_set(__isl_take isl_multi_aff *ma1, + __isl_take isl_multi_aff *ma2) +{ + return isl_multi_aff_lex_gt_set(ma2, ma1); +} + +/* Return the set of domain elements where "ma1" is lexicographically + * greater than to "ma2". If "equal" is set, then include the domain + * elements where they are equal. + * Do this for the case where there are no entries. + * In this case, "ma1" cannot be greater than "ma2", + * but it is (greater than or) equal to "ma2". + */ +static __isl_give isl_set *isl_multi_aff_lex_gte_set_0d( + __isl_take isl_multi_aff *ma1, __isl_take isl_multi_aff *ma2, int equal) +{ + isl_space *space; + + space = isl_multi_aff_get_domain_space(ma1); + + isl_multi_aff_free(ma1); + isl_multi_aff_free(ma2); + + if (equal) + return isl_set_universe(space); + else + return isl_set_empty(space); +} + +/* Return the set where entry "i" of "ma1" and "ma2" + * satisfy the relation prescribed by "cmp". + */ +static __isl_give isl_set *isl_multi_aff_order_at(__isl_keep isl_multi_aff *ma1, + __isl_keep isl_multi_aff *ma2, int i, + __isl_give isl_set *(*cmp)(__isl_take isl_aff *aff1, + __isl_take isl_aff *aff2)) +{ + isl_aff *aff1, *aff2; + + aff1 = isl_multi_aff_get_at(ma1, i); + aff2 = isl_multi_aff_get_at(ma2, i); + return cmp(aff1, aff2); +} + +/* Return the set of domain elements where "ma1" is lexicographically + * greater than to "ma2". If "equal" is set, then include the domain + * elements where they are equal. + * + * In particular, for all but the final entry, + * include the set of elements where this entry is strictly greater in "ma1" + * and all previous entries are equal. + * The final entry is also allowed to be equal in the two functions + * if "equal" is set. + * + * The case where there are no entries is handled separately. + */ +static __isl_give isl_set *isl_multi_aff_lex_gte_set( + __isl_take isl_multi_aff *ma1, __isl_take isl_multi_aff *ma2, int equal) +{ + int i; + isl_size n; + isl_space *space; + isl_set *res; + isl_set *equal_set; + isl_set *gte; + + if (isl_multi_aff_check_equal_space(ma1, ma2) < 0) + goto error; + n = isl_multi_aff_size(ma1); + if (n < 0) + goto error; + if (n == 0) + return isl_multi_aff_lex_gte_set_0d(ma1, ma2, equal); + + space = isl_multi_aff_get_domain_space(ma1); + res = isl_set_empty(isl_space_copy(space)); + equal_set = isl_set_universe(space); + + for (i = 0; i + 1 < n; ++i) { + isl_bool empty; + isl_set *gt, *eq; + + gt = isl_multi_aff_order_at(ma1, ma2, i, &isl_aff_gt_set); + gt = isl_set_intersect(gt, isl_set_copy(equal_set)); + res = isl_set_union(res, gt); + eq = isl_multi_aff_order_at(ma1, ma2, i, &isl_aff_eq_set); + equal_set = isl_set_intersect(equal_set, eq); + + empty = isl_set_is_empty(equal_set); + if (empty >= 0 && empty) + break; + } + + if (equal) + gte = isl_multi_aff_order_at(ma1, ma2, n - 1, &isl_aff_ge_set); + else + gte = isl_multi_aff_order_at(ma1, ma2, n - 1, &isl_aff_gt_set); + isl_multi_aff_free(ma1); + isl_multi_aff_free(ma2); + + gte = isl_set_intersect(gte, equal_set); + return isl_set_union(res, gte); +error: + isl_multi_aff_free(ma1); + isl_multi_aff_free(ma2); + return NULL; +} + +/* Return the set of domain elements where "ma1" is lexicographically + * greater than or equal to "ma2". + */ +__isl_give isl_set *isl_multi_aff_lex_ge_set(__isl_take isl_multi_aff *ma1, + __isl_take isl_multi_aff *ma2) +{ + return isl_multi_aff_lex_gte_set(ma1, ma2, 1); +} + +/* Return the set of domain elements where "ma1" is lexicographically + * greater than "ma2". + */ +__isl_give isl_set *isl_multi_aff_lex_gt_set(__isl_take isl_multi_aff *ma1, + __isl_take isl_multi_aff *ma2) +{ + return isl_multi_aff_lex_gte_set(ma1, ma2, 0); +} + +#define isl_multi_aff_zero_in_space isl_multi_aff_zero + +#undef PW +#define PW isl_pw_multi_aff +#undef BASE +#define BASE multi_aff +#undef EL_IS_ZERO +#define EL_IS_ZERO is_empty +#undef ZERO +#define ZERO empty +#undef IS_ZERO +#define IS_ZERO is_empty +#undef FIELD +#define FIELD maff +#undef DEFAULT_IS_ZERO +#define DEFAULT_IS_ZERO 0 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#undef BASE +#define BASE pw_multi_aff + +#include +#include "isl_union_locals_templ.c" +#include +#include + +#undef BASE +#define BASE multi_aff + +#include + +/* Generic function for extracting a factor from a product "pma". + * "check_space" checks that the space is that of the right kind of product. + * "space_factor" extracts the factor from the space. + * "multi_aff_factor" extracts the factor from the constituent functions. + */ +static __isl_give isl_pw_multi_aff *pw_multi_aff_factor( + __isl_take isl_pw_multi_aff *pma, + isl_stat (*check_space)(__isl_keep isl_pw_multi_aff *pma), + __isl_give isl_space *(*space_factor)(__isl_take isl_space *space), + __isl_give isl_multi_aff *(*multi_aff_factor)( + __isl_take isl_multi_aff *ma)) +{ + int i; + isl_space *space; + + if (check_space(pma) < 0) + return isl_pw_multi_aff_free(pma); + + space = isl_pw_multi_aff_take_space(pma); + space = space_factor(space); + + for (i = 0; pma && i < pma->n; ++i) { + isl_multi_aff *ma; + + ma = isl_pw_multi_aff_take_base_at(pma, i); + ma = multi_aff_factor(ma); + pma = isl_pw_multi_aff_restore_base_at(pma, i, ma); + } + + pma = isl_pw_multi_aff_restore_space(pma, space); + + return pma; +} + +/* Is the range of "pma" a wrapped relation? + */ +static isl_bool isl_pw_multi_aff_range_is_wrapping( + __isl_keep isl_pw_multi_aff *pma) +{ + return isl_space_range_is_wrapping(isl_pw_multi_aff_peek_space(pma)); +} + +/* Check that the range of "pma" is a product. + */ +static isl_stat pw_multi_aff_check_range_product( + __isl_keep isl_pw_multi_aff *pma) +{ + isl_bool wraps; + + wraps = isl_pw_multi_aff_range_is_wrapping(pma); + if (wraps < 0) + return isl_stat_error; + if (!wraps) + isl_die(isl_pw_multi_aff_get_ctx(pma), isl_error_invalid, + "range is not a product", return isl_stat_error); + return isl_stat_ok; +} + +/* Given a function A -> [B -> C], extract the function A -> B. + */ +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_range_factor_domain( + __isl_take isl_pw_multi_aff *pma) +{ + return pw_multi_aff_factor(pma, &pw_multi_aff_check_range_product, + &isl_space_range_factor_domain, + &isl_multi_aff_range_factor_domain); +} + +/* Given a function A -> [B -> C], extract the function A -> C. + */ +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_range_factor_range( + __isl_take isl_pw_multi_aff *pma) +{ + return pw_multi_aff_factor(pma, &pw_multi_aff_check_range_product, + &isl_space_range_factor_range, + &isl_multi_aff_range_factor_range); +} + +/* Given two piecewise multi affine expressions, return a piecewise + * multi-affine expression defined on the union of the definition domains + * of the inputs that is equal to the lexicographic maximum of the two + * inputs on each cell. If only one of the two inputs is defined on + * a given cell, then it is considered to be the maximum. + */ +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_union_lexmax( + __isl_take isl_pw_multi_aff *pma1, + __isl_take isl_pw_multi_aff *pma2) +{ + isl_pw_multi_aff_align_params_bin(&pma1, &pma2); + return isl_pw_multi_aff_union_opt_cmp(pma1, pma2, + &isl_multi_aff_lex_ge_set); +} + +/* Given two piecewise multi affine expressions, return a piecewise + * multi-affine expression defined on the union of the definition domains + * of the inputs that is equal to the lexicographic minimum of the two + * inputs on each cell. If only one of the two inputs is defined on + * a given cell, then it is considered to be the minimum. + */ +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_union_lexmin( + __isl_take isl_pw_multi_aff *pma1, + __isl_take isl_pw_multi_aff *pma2) +{ + isl_pw_multi_aff_align_params_bin(&pma1, &pma2); + return isl_pw_multi_aff_union_opt_cmp(pma1, pma2, + &isl_multi_aff_lex_le_set); +} + +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_add( + __isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2) +{ + isl_pw_multi_aff_align_params_bin(&pma1, &pma2); + return isl_pw_multi_aff_on_shared_domain(pma1, pma2, + &isl_multi_aff_add); +} + +/* Subtract "pma2" from "pma1" and return the result. + */ +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_sub( + __isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2) +{ + isl_pw_multi_aff_align_params_bin(&pma1, &pma2); + return isl_pw_multi_aff_on_shared_domain(pma1, pma2, + &isl_multi_aff_sub); +} + +/* Given two piecewise multi-affine expressions A -> B and C -> D, + * construct a piecewise multi-affine expression [A -> C] -> [B -> D]. + */ +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_product( + __isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2) +{ + int i, j, n; + isl_space *space; + isl_pw_multi_aff *res; + + if (isl_pw_multi_aff_align_params_bin(&pma1, &pma2) < 0) + goto error; + + n = pma1->n * pma2->n; + space = isl_space_product(isl_space_copy(pma1->dim), + isl_space_copy(pma2->dim)); + res = isl_pw_multi_aff_alloc_size(space, n); + + for (i = 0; i < pma1->n; ++i) { + for (j = 0; j < pma2->n; ++j) { + isl_set *domain; + isl_multi_aff *ma; + + domain = isl_set_product(isl_set_copy(pma1->p[i].set), + isl_set_copy(pma2->p[j].set)); + ma = isl_multi_aff_product( + isl_multi_aff_copy(pma1->p[i].maff), + isl_multi_aff_copy(pma2->p[j].maff)); + res = isl_pw_multi_aff_add_piece(res, domain, ma); + } + } + + isl_pw_multi_aff_free(pma1); + isl_pw_multi_aff_free(pma2); + return res; +error: + isl_pw_multi_aff_free(pma1); + isl_pw_multi_aff_free(pma2); + return NULL; +} + +/* Subtract the initial "n" elements in "ma" with coefficients in "c" and + * denominator "denom". + * "denom" is allowed to be negative, in which case the actual denominator + * is -denom and the expressions are added instead. + */ +static __isl_give isl_aff *subtract_initial(__isl_take isl_aff *aff, + __isl_keep isl_multi_aff *ma, int n, isl_int *c, isl_int denom) +{ + int i, first; + int sign; + isl_int d; + + first = isl_seq_first_non_zero(c, n); + if (first == -1) + return aff; + + sign = isl_int_sgn(denom); + isl_int_init(d); + isl_int_abs(d, denom); + for (i = first; i < n; ++i) { + isl_aff *aff_i; + + if (isl_int_is_zero(c[i])) + continue; + aff_i = isl_multi_aff_get_aff(ma, i); + aff_i = isl_aff_scale(aff_i, c[i]); + aff_i = isl_aff_scale_down(aff_i, d); + if (sign >= 0) + aff = isl_aff_sub(aff, aff_i); + else + aff = isl_aff_add(aff, aff_i); + } + isl_int_clear(d); + + return aff; +} + +/* Extract an affine expression that expresses the output dimension "pos" + * of "bmap" in terms of the parameters and input dimensions from + * equality "eq". + * Note that this expression may involve integer divisions defined + * in terms of parameters and input dimensions. + * The equality may also involve references to earlier (but not later) + * output dimensions. These are replaced by the corresponding elements + * in "ma". + * + * If the equality is of the form + * + * f(i) + h(j) + a x + g(i) = 0, + * + * with f(i) a linear combinations of the parameters and input dimensions, + * g(i) a linear combination of integer divisions defined in terms of the same + * and h(j) a linear combinations of earlier output dimensions, + * then the affine expression is + * + * (-f(i) - g(i))/a - h(j)/a + * + * If the equality is of the form + * + * f(i) + h(j) - a x + g(i) = 0, + * + * then the affine expression is + * + * (f(i) + g(i))/a - h(j)/(-a) + * + * + * If "div" refers to an integer division (i.e., it is smaller than + * the number of integer divisions), then the equality constraint + * does involve an integer division (the one at position "div") that + * is defined in terms of output dimensions. However, this integer + * division can be eliminated by exploiting a pair of constraints + * x >= l and x <= l + n, with n smaller than the coefficient of "div" + * in the equality constraint. "ineq" refers to inequality x >= l, i.e., + * -l + x >= 0. + * In particular, let + * + * x = e(i) + m floor(...) + * + * with e(i) the expression derived above and floor(...) the integer + * division involving output dimensions. + * From + * + * l <= x <= l + n, + * + * we have + * + * 0 <= x - l <= n + * + * This means + * + * e(i) + m floor(...) - l = (e(i) + m floor(...) - l) mod m + * = (e(i) - l) mod m + * + * Therefore, + * + * x - l = (e(i) - l) mod m + * + * or + * + * x = ((e(i) - l) mod m) + l + * + * The variable "shift" below contains the expression -l, which may + * also involve a linear combination of earlier output dimensions. + */ +static __isl_give isl_aff *extract_aff_from_equality( + __isl_keep isl_basic_map *bmap, int pos, int eq, int div, int ineq, + __isl_keep isl_multi_aff *ma) +{ + unsigned o_out; + isl_size n_div, n_out; + isl_ctx *ctx; + isl_local_space *ls; + isl_aff *aff, *shift; + isl_val *mod; + + ctx = isl_basic_map_get_ctx(bmap); + ls = isl_basic_map_get_local_space(bmap); + ls = isl_local_space_domain(ls); + aff = isl_aff_alloc(isl_local_space_copy(ls)); + if (!aff) + goto error; + o_out = isl_basic_map_offset(bmap, isl_dim_out); + n_out = isl_basic_map_dim(bmap, isl_dim_out); + n_div = isl_basic_map_dim(bmap, isl_dim_div); + if (n_out < 0 || n_div < 0) + goto error; + if (isl_int_is_neg(bmap->eq[eq][o_out + pos])) { + isl_seq_cpy(aff->v->el + 1, bmap->eq[eq], o_out); + isl_seq_cpy(aff->v->el + 1 + o_out, + bmap->eq[eq] + o_out + n_out, n_div); + } else { + isl_seq_neg(aff->v->el + 1, bmap->eq[eq], o_out); + isl_seq_neg(aff->v->el + 1 + o_out, + bmap->eq[eq] + o_out + n_out, n_div); + } + if (div < n_div) + isl_int_set_si(aff->v->el[1 + o_out + div], 0); + isl_int_abs(aff->v->el[0], bmap->eq[eq][o_out + pos]); + aff = subtract_initial(aff, ma, pos, bmap->eq[eq] + o_out, + bmap->eq[eq][o_out + pos]); + if (div < n_div) { + shift = isl_aff_alloc(isl_local_space_copy(ls)); + if (!shift) + goto error; + isl_seq_cpy(shift->v->el + 1, bmap->ineq[ineq], o_out); + isl_seq_cpy(shift->v->el + 1 + o_out, + bmap->ineq[ineq] + o_out + n_out, n_div); + isl_int_set_si(shift->v->el[0], 1); + shift = subtract_initial(shift, ma, pos, + bmap->ineq[ineq] + o_out, ctx->negone); + aff = isl_aff_add(aff, isl_aff_copy(shift)); + mod = isl_val_int_from_isl_int(ctx, + bmap->eq[eq][o_out + n_out + div]); + mod = isl_val_abs(mod); + aff = isl_aff_mod_val(aff, mod); + aff = isl_aff_sub(aff, shift); + } + + isl_local_space_free(ls); + return aff; +error: + isl_local_space_free(ls); + isl_aff_free(aff); + return NULL; +} + +/* Given a basic map with output dimensions defined + * in terms of the parameters input dimensions and earlier + * output dimensions using an equality (and possibly a pair on inequalities), + * extract an isl_aff that expresses output dimension "pos" in terms + * of the parameters and input dimensions. + * Note that this expression may involve integer divisions defined + * in terms of parameters and input dimensions. + * "ma" contains the expressions corresponding to earlier output dimensions. + * + * This function shares some similarities with + * isl_basic_map_has_defining_equality and isl_constraint_get_bound. + */ +static __isl_give isl_aff *extract_isl_aff_from_basic_map( + __isl_keep isl_basic_map *bmap, int pos, __isl_keep isl_multi_aff *ma) +{ + int eq, div, ineq; + isl_aff *aff; + + if (!bmap) + return NULL; + eq = isl_basic_map_output_defining_equality(bmap, pos, &div, &ineq); + if (eq >= bmap->n_eq) + isl_die(isl_basic_map_get_ctx(bmap), isl_error_invalid, + "unable to find suitable equality", return NULL); + aff = extract_aff_from_equality(bmap, pos, eq, div, ineq, ma); + + aff = isl_aff_remove_unused_divs(aff); + return aff; +} + +/* Given a basic map where each output dimension is defined + * in terms of the parameters and input dimensions using an equality, + * extract an isl_multi_aff that expresses the output dimensions in terms + * of the parameters and input dimensions. + */ +static __isl_give isl_multi_aff *extract_isl_multi_aff_from_basic_map( + __isl_take isl_basic_map *bmap) +{ + int i; + isl_size n_out; + isl_multi_aff *ma; + + if (!bmap) + return NULL; + + ma = isl_multi_aff_alloc(isl_basic_map_get_space(bmap)); + n_out = isl_basic_map_dim(bmap, isl_dim_out); + if (n_out < 0) + ma = isl_multi_aff_free(ma); + + for (i = 0; i < n_out; ++i) { + isl_aff *aff; + + aff = extract_isl_aff_from_basic_map(bmap, i, ma); + ma = isl_multi_aff_set_aff(ma, i, aff); + } + + isl_basic_map_free(bmap); + + return ma; +} + +/* Given a basic set where each set dimension is defined + * in terms of the parameters using an equality, + * extract an isl_multi_aff that expresses the set dimensions in terms + * of the parameters. + */ +__isl_give isl_multi_aff *isl_multi_aff_from_basic_set_equalities( + __isl_take isl_basic_set *bset) +{ + return extract_isl_multi_aff_from_basic_map(bset); +} + +/* Create an isl_pw_multi_aff that is equivalent to + * isl_map_intersect_domain(isl_map_from_basic_map(bmap), domain). + * The given basic map is such that each output dimension is defined + * in terms of the parameters and input dimensions using an equality. + * + * Since some applications expect the result of isl_pw_multi_aff_from_map + * to only contain integer affine expressions, we compute the floor + * of the expression before returning. + * + * Remove all constraints involving local variables without + * an explicit representation (resulting in the removal of those + * local variables) prior to the actual extraction to ensure + * that the local spaces in which the resulting affine expressions + * are created do not contain any unknown local variables. + * Removing such constraints is safe because constraints involving + * unknown local variables are not used to determine whether + * a basic map is obviously single-valued. + */ +static __isl_give isl_pw_multi_aff *plain_pw_multi_aff_from_map( + __isl_take isl_set *domain, __isl_take isl_basic_map *bmap) +{ + isl_multi_aff *ma; + + bmap = isl_basic_map_drop_constraints_involving_unknown_divs(bmap); + ma = extract_isl_multi_aff_from_basic_map(bmap); + ma = isl_multi_aff_floor(ma); + return isl_pw_multi_aff_alloc(domain, ma); +} + +/* Try and create an isl_pw_multi_aff that is equivalent to the given isl_map. + * This obviously only works if the input "map" is single-valued. + * If so, we compute the lexicographic minimum of the image in the form + * of an isl_pw_multi_aff. Since the image is unique, it is equal + * to its lexicographic minimum. + * If the input is not single-valued, we produce an error. + */ +static __isl_give isl_pw_multi_aff *pw_multi_aff_from_map_base( + __isl_take isl_map *map) +{ + int i; + int sv; + isl_pw_multi_aff *pma; + + sv = isl_map_is_single_valued(map); + if (sv < 0) + goto error; + if (!sv) + isl_die(isl_map_get_ctx(map), isl_error_invalid, + "map is not single-valued", goto error); + map = isl_map_make_disjoint(map); + if (!map) + return NULL; + + pma = isl_pw_multi_aff_empty(isl_map_get_space(map)); + + for (i = 0; i < map->n; ++i) { + isl_pw_multi_aff *pma_i; + isl_basic_map *bmap; + bmap = isl_basic_map_copy(map->p[i]); + pma_i = isl_basic_map_lexmin_pw_multi_aff(bmap); + pma = isl_pw_multi_aff_add_disjoint(pma, pma_i); + } + + isl_map_free(map); + return pma; +error: + isl_map_free(map); + return NULL; +} + +/* Construct an isl_aff from the given domain local space "ls" and + * coefficients "v", where the local space may involve + * local variables without a known expression, as long as these + * do not have a non-zero coefficient in "v". + * These need to be pruned away first since an isl_aff cannot + * reference any local variables without a known expression. + * For simplicity, remove all local variables that have a zero coefficient and + * that are not used in other local variables with a non-zero coefficient. + */ +static __isl_give isl_aff *isl_aff_alloc_vec_prune( + __isl_take isl_local_space *ls, __isl_take isl_vec *v) +{ + int i; + isl_size n_div, v_div; + + n_div = isl_local_space_dim(ls, isl_dim_div); + v_div = isl_local_space_var_offset(ls, isl_dim_div); + if (n_div < 0 || v_div < 0 || !v) + goto error; + for (i = n_div - 1; i >= 0; --i) { + isl_bool involves; + + if (!isl_int_is_zero(v->el[1 + 1 + v_div + i])) + continue; + involves = isl_local_space_involves_dims(ls, isl_dim_div, i, 1); + if (involves < 0) + goto error; + if (involves) + continue; + ls = isl_local_space_drop_dims(ls, isl_dim_div, i, 1); + v = isl_vec_drop_els(v, 1 + 1 + v_div + i, 1); + if (!v) + goto error; + } + + return isl_aff_alloc_vec(ls, v); +error: + isl_local_space_free(ls); + isl_vec_free(v); + return NULL; +} + +/* Try and create an isl_pw_multi_aff that is equivalent to the given isl_map, + * taking into account that the output dimension at position "d" + * can be represented as + * + * x = floor((e(...) + c1) / m) + * + * given that constraint "i" is of the form + * + * e(...) + c1 - m x >= 0 + * + * with e(...) an expression that does not involve any other output dimensions. + * + * + * Let "map" be of the form + * + * A -> B + * + * We construct a mapping + * + * A -> [A -> x = floor(...)] + * + * apply that to the map, obtaining + * + * [A -> x = floor(...)] -> B + * + * and equate dimension "d" to x. + * We then compute a isl_pw_multi_aff representation of the resulting map + * and plug in the mapping above. + * + * The constraint "i" is guaranteed by the caller not to involve + * any local variables without a known expression, but such local variables + * may appear in other constraints. They therefore need to be removed + * during the construction of the affine expression. + */ +static __isl_give isl_pw_multi_aff *pw_multi_aff_from_map_div( + __isl_take isl_map *map, __isl_take isl_basic_map *hull, int d, int i) +{ + isl_space *space = NULL; + isl_local_space *ls; + isl_multi_aff *ma; + isl_aff *aff; + isl_vec *v; + isl_map *insert; + isl_size n_in; + isl_pw_multi_aff *pma; + isl_bool is_set; + + is_set = isl_map_is_set(map); + if (is_set < 0) + goto error; + + space = isl_space_domain(isl_map_get_space(map)); + n_in = isl_space_dim(space, isl_dim_set); + if (n_in < 0) + goto error; + + ls = isl_basic_map_get_local_space(hull); + if (!is_set) + ls = isl_local_space_wrap(ls); + v = isl_basic_map_inequality_extract_output_upper_bound(hull, i, d); + isl_basic_map_free(hull); + + aff = isl_aff_alloc_vec_prune(ls, v); + aff = isl_aff_floor(aff); + if (is_set) { + aff = isl_aff_project_domain_on_params(aff); + isl_space_free(space); + ma = isl_multi_aff_from_aff(aff); + } else { + aff = isl_aff_domain_factor_domain(aff); + ma = isl_multi_aff_identity(isl_space_map_from_set(space)); + ma = isl_multi_aff_range_product(ma, + isl_multi_aff_from_aff(aff)); + } + + insert = isl_map_from_multi_aff_internal(isl_multi_aff_copy(ma)); + map = isl_map_apply_domain(map, insert); + map = isl_map_equate(map, isl_dim_in, n_in, isl_dim_out, d); + pma = isl_pw_multi_aff_from_map(map); + pma = isl_pw_multi_aff_pullback_multi_aff(pma, ma); + + return pma; +error: + isl_space_free(space); + isl_map_free(map); + isl_basic_map_free(hull); + return NULL; +} + +/* Try and create an isl_pw_multi_aff that is equivalent to the given isl_map. + * + * As a special case, we first check if there is any pair of constraints, + * shared by all the basic maps in "map" that force a given dimension + * to be equal to the floor of some affine combination of the input dimensions. + * + * In particular, if we can find two constraints + * + * e(...) + c1 - m x >= 0 i.e., m x <= e(...) + c1 + * + * and + * + * -e(...) + c2 + m x >= 0 i.e., m x >= e(...) - c2 + * + * where m > 1 and e only depends on parameters and input dimensions, + * and such that + * + * c1 + c2 < m i.e., -c2 >= c1 - (m - 1) + * + * then we know that we can take + * + * x = floor((e(...) + c1) / m) + * + * without having to perform any computation. + * + * Note that we know that + * + * c1 + c2 >= 1 + * + * If c1 + c2 were 0, then we would have detected an equality during + * simplification. If c1 + c2 were negative, then we would have detected + * a contradiction. + */ +static __isl_give isl_pw_multi_aff *pw_multi_aff_from_map_check_div( + __isl_take isl_map *map) +{ + int d; + isl_size dim; + isl_size i; + isl_size n_ineq; + isl_basic_map *hull; + + hull = isl_map_unshifted_simple_hull(isl_map_copy(map)); + dim = isl_map_dim(map, isl_dim_out); + n_ineq = isl_basic_map_n_inequality(hull); + if (dim < 0 || n_ineq < 0) + goto error; + + dim = isl_map_dim(map, isl_dim_out); + for (d = 0; d < dim; ++d) { + i = isl_basic_map_find_output_upper_div_constraint(hull, d); + if (i < 0) + goto error; + if (i >= n_ineq) + continue; + return pw_multi_aff_from_map_div(map, hull, d, i); + } + isl_basic_map_free(hull); + return pw_multi_aff_from_map_base(map); +error: + isl_map_free(map); + isl_basic_map_free(hull); + return NULL; +} + +/* Given an affine expression + * + * [A -> B] -> f(A,B) + * + * construct an isl_multi_aff + * + * [A -> B] -> B' + * + * such that dimension "d" in B' is set to "aff" and the remaining + * dimensions are set equal to the corresponding dimensions in B. + * "n_in" is the dimension of the space A. + * "n_out" is the dimension of the space B. + * + * If "is_set" is set, then the affine expression is of the form + * + * [B] -> f(B) + * + * and we construct an isl_multi_aff + * + * B -> B' + */ +static __isl_give isl_multi_aff *range_map(__isl_take isl_aff *aff, int d, + unsigned n_in, unsigned n_out, int is_set) +{ + int i; + isl_multi_aff *ma; + isl_space *space, *space2; + isl_local_space *ls; + + space = isl_aff_get_domain_space(aff); + ls = isl_local_space_from_space(isl_space_copy(space)); + space2 = isl_space_copy(space); + if (!is_set) + space2 = isl_space_range(isl_space_unwrap(space2)); + space = isl_space_map_from_domain_and_range(space, space2); + ma = isl_multi_aff_alloc(space); + ma = isl_multi_aff_set_aff(ma, d, aff); + + for (i = 0; i < n_out; ++i) { + if (i == d) + continue; + aff = isl_aff_var_on_domain(isl_local_space_copy(ls), + isl_dim_set, n_in + i); + ma = isl_multi_aff_set_aff(ma, i, aff); + } + + isl_local_space_free(ls); + + return ma; +} + +/* Try and create an isl_pw_multi_aff that is equivalent to the given isl_map, + * taking into account that the dimension at position "d" can be written as + * + * x = m a + f(..) (1) + * + * where m is equal to "gcd". + * "i" is the index of the equality in "hull" that defines f(..). + * In particular, the equality is of the form + * + * f(..) - x + m g(existentials) = 0 + * + * or + * + * -f(..) + x + m g(existentials) = 0 + * + * We basically plug (1) into "map", resulting in a map with "a" + * in the range instead of "x". The corresponding isl_pw_multi_aff + * defining "a" is then plugged back into (1) to obtain a definition for "x". + * + * Specifically, given the input map + * + * A -> B + * + * We first wrap it into a set + * + * [A -> B] + * + * and define (1) on top of the corresponding space, resulting in "aff". + * We use this to create an isl_multi_aff that maps the output position "d" + * from "a" to "x", leaving all other (intput and output) dimensions unchanged. + * We plug this into the wrapped map, unwrap the result and compute the + * corresponding isl_pw_multi_aff. + * The result is an expression + * + * A -> T(A) + * + * We adjust that to + * + * A -> [A -> T(A)] + * + * so that we can plug that into "aff", after extending the latter to + * a mapping + * + * [A -> B] -> B' + * + * + * If "map" is actually a set, then there is no "A" space, meaning + * that we do not need to perform any wrapping, and that the result + * of the recursive call is of the form + * + * [T] + * + * which is plugged into a mapping of the form + * + * B -> B' + */ +static __isl_give isl_pw_multi_aff *pw_multi_aff_from_map_stride( + __isl_take isl_map *map, __isl_take isl_basic_map *hull, int d, int i, + isl_int gcd) +{ + isl_set *set; + isl_space *space; + isl_local_space *ls; + isl_aff *aff; + isl_multi_aff *ma; + isl_pw_multi_aff *pma, *id; + isl_size n_in; + unsigned o_out; + isl_size n_out; + isl_bool is_set; + + is_set = isl_map_is_set(map); + if (is_set < 0) + goto error; + + n_in = isl_basic_map_dim(hull, isl_dim_in); + n_out = isl_basic_map_dim(hull, isl_dim_out); + if (n_in < 0 || n_out < 0) + goto error; + o_out = isl_basic_map_offset(hull, isl_dim_out); + + if (is_set) + set = map; + else + set = isl_map_wrap(map); + space = isl_space_map_from_set(isl_set_get_space(set)); + ma = isl_multi_aff_identity(space); + ls = isl_local_space_from_space(isl_set_get_space(set)); + aff = isl_aff_alloc(ls); + if (aff) { + isl_int_set_si(aff->v->el[0], 1); + if (isl_int_is_one(hull->eq[i][o_out + d])) + isl_seq_neg(aff->v->el + 1, hull->eq[i], + aff->v->size - 1); + else + isl_seq_cpy(aff->v->el + 1, hull->eq[i], + aff->v->size - 1); + isl_int_set(aff->v->el[1 + o_out + d], gcd); + } + ma = isl_multi_aff_set_aff(ma, n_in + d, isl_aff_copy(aff)); + set = isl_set_preimage_multi_aff(set, ma); + + ma = range_map(aff, d, n_in, n_out, is_set); + + if (is_set) + map = set; + else + map = isl_set_unwrap(set); + pma = isl_pw_multi_aff_from_map(map); + + if (!is_set) { + space = isl_pw_multi_aff_get_domain_space(pma); + space = isl_space_map_from_set(space); + id = isl_pw_multi_aff_identity(space); + pma = isl_pw_multi_aff_range_product(id, pma); + } + id = isl_pw_multi_aff_from_multi_aff(ma); + pma = isl_pw_multi_aff_pullback_pw_multi_aff(id, pma); + + isl_basic_map_free(hull); + return pma; +error: + isl_map_free(map); + isl_basic_map_free(hull); + return NULL; +} + +/* Try and create an isl_pw_multi_aff that is equivalent to the given isl_map. + * "hull" contains the equalities valid for "map". + * + * Check if any of the output dimensions is "strided". + * That is, we check if it can be written as + * + * x = m a + f(..) + * + * with m greater than 1, a some combination of existentially quantified + * variables and f an expression in the parameters and input dimensions. + * If so, we remove the stride in pw_multi_aff_from_map_stride. + * + * Otherwise, we continue with pw_multi_aff_from_map_check_div for a further + * special case. + */ +static __isl_give isl_pw_multi_aff *pw_multi_aff_from_map_check_strides( + __isl_take isl_map *map, __isl_take isl_basic_map *hull) +{ + int i, j; + isl_size n_out; + unsigned o_out; + isl_size n_div; + unsigned o_div; + isl_int gcd; + + n_div = isl_basic_map_dim(hull, isl_dim_div); + n_out = isl_basic_map_dim(hull, isl_dim_out); + if (n_div < 0 || n_out < 0) + goto error; + + if (n_div == 0) { + isl_basic_map_free(hull); + return pw_multi_aff_from_map_check_div(map); + } + + isl_int_init(gcd); + + o_div = isl_basic_map_offset(hull, isl_dim_div); + o_out = isl_basic_map_offset(hull, isl_dim_out); + + for (i = 0; i < n_out; ++i) { + for (j = 0; j < hull->n_eq; ++j) { + isl_int *eq = hull->eq[j]; + isl_pw_multi_aff *res; + + if (!isl_int_is_one(eq[o_out + i]) && + !isl_int_is_negone(eq[o_out + i])) + continue; + if (isl_seq_first_non_zero(eq + o_out, i) != -1) + continue; + if (isl_seq_first_non_zero(eq + o_out + i + 1, + n_out - (i + 1)) != -1) + continue; + isl_seq_gcd(eq + o_div, n_div, &gcd); + if (isl_int_is_zero(gcd)) + continue; + if (isl_int_is_one(gcd)) + continue; + + res = pw_multi_aff_from_map_stride(map, hull, + i, j, gcd); + isl_int_clear(gcd); + return res; + } + } + + isl_int_clear(gcd); + isl_basic_map_free(hull); + return pw_multi_aff_from_map_check_div(map); +error: + isl_map_free(map); + isl_basic_map_free(hull); + return NULL; +} + +/* Try and create an isl_pw_multi_aff that is equivalent to the given isl_map. + * + * As a special case, we first check if all output dimensions are uniquely + * defined in terms of the parameters and input dimensions over the entire + * domain. If so, we extract the desired isl_pw_multi_aff directly + * from the affine hull of "map" and its domain. + * + * Otherwise, continue with pw_multi_aff_from_map_check_strides for more + * special cases. + */ +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_map(__isl_take isl_map *map) +{ + isl_bool sv; + isl_size n; + isl_basic_map *hull; + + n = isl_map_n_basic_map(map); + if (n < 0) + goto error; + + if (n == 1) { + hull = isl_map_unshifted_simple_hull(isl_map_copy(map)); + hull = isl_basic_map_plain_affine_hull(hull); + sv = isl_basic_map_plain_is_single_valued(hull); + if (sv >= 0 && sv) + return plain_pw_multi_aff_from_map(isl_map_domain(map), + hull); + isl_basic_map_free(hull); + } + map = isl_map_detect_equalities(map); + hull = isl_map_unshifted_simple_hull(isl_map_copy(map)); + sv = isl_basic_map_plain_is_single_valued(hull); + if (sv >= 0 && sv) + return plain_pw_multi_aff_from_map(isl_map_domain(map), hull); + if (sv >= 0) + return pw_multi_aff_from_map_check_strides(map, hull); + isl_basic_map_free(hull); +error: + isl_map_free(map); + return NULL; +} + +/* This function performs the same operation as isl_pw_multi_aff_from_map, + * but is considered as a function on an isl_map when exported. + */ +__isl_give isl_pw_multi_aff *isl_map_as_pw_multi_aff(__isl_take isl_map *map) +{ + return isl_pw_multi_aff_from_map(map); +} + +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_set(__isl_take isl_set *set) +{ + return isl_pw_multi_aff_from_map(set); +} + +/* This function performs the same operation as isl_pw_multi_aff_from_set, + * but is considered as a function on an isl_set when exported. + */ +__isl_give isl_pw_multi_aff *isl_set_as_pw_multi_aff(__isl_take isl_set *set) +{ + return isl_pw_multi_aff_from_set(set); +} + +/* Convert "map" into an isl_pw_multi_aff (if possible) and + * add it to *user. + */ +static isl_stat pw_multi_aff_from_map(__isl_take isl_map *map, void *user) +{ + isl_union_pw_multi_aff **upma = user; + isl_pw_multi_aff *pma; + + pma = isl_pw_multi_aff_from_map(map); + *upma = isl_union_pw_multi_aff_add_pw_multi_aff(*upma, pma); + + return *upma ? isl_stat_ok : isl_stat_error; +} + +/* Create an isl_union_pw_multi_aff with the given isl_aff on a universe + * domain. + */ +__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_from_aff( + __isl_take isl_aff *aff) +{ + isl_multi_aff *ma; + isl_pw_multi_aff *pma; + + ma = isl_multi_aff_from_aff(aff); + pma = isl_pw_multi_aff_from_multi_aff(ma); + return isl_union_pw_multi_aff_from_pw_multi_aff(pma); +} + +/* Try and create an isl_union_pw_multi_aff that is equivalent + * to the given isl_union_map. + * The isl_union_map is required to be single-valued in each space. + * Otherwise, an error is produced. + */ +__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_from_union_map( + __isl_take isl_union_map *umap) +{ + isl_space *space; + isl_union_pw_multi_aff *upma; + + space = isl_union_map_get_space(umap); + upma = isl_union_pw_multi_aff_empty(space); + if (isl_union_map_foreach_map(umap, &pw_multi_aff_from_map, &upma) < 0) + upma = isl_union_pw_multi_aff_free(upma); + isl_union_map_free(umap); + + return upma; +} + +/* This function performs the same operation as + * isl_union_pw_multi_aff_from_union_map, + * but is considered as a function on an isl_union_map when exported. + */ +__isl_give isl_union_pw_multi_aff *isl_union_map_as_union_pw_multi_aff( + __isl_take isl_union_map *umap) +{ + return isl_union_pw_multi_aff_from_union_map(umap); +} + +/* Try and create an isl_union_pw_multi_aff that is equivalent + * to the given isl_union_set. + * The isl_union_set is required to be a singleton in each space. + * Otherwise, an error is produced. + */ +__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_from_union_set( + __isl_take isl_union_set *uset) +{ + return isl_union_pw_multi_aff_from_union_map(uset); +} + +/* Return the piecewise affine expression "set ? 1 : 0". + */ +__isl_give isl_pw_aff *isl_set_indicator_function(__isl_take isl_set *set) +{ + isl_pw_aff *pa; + isl_space *space = isl_set_get_space(set); + isl_local_space *ls = isl_local_space_from_space(space); + isl_aff *zero = isl_aff_zero_on_domain(isl_local_space_copy(ls)); + isl_aff *one = isl_aff_zero_on_domain(ls); + + one = isl_aff_add_constant_si(one, 1); + pa = isl_pw_aff_alloc(isl_set_copy(set), one); + set = isl_set_complement(set); + pa = isl_pw_aff_add_disjoint(pa, isl_pw_aff_alloc(set, zero)); + + return pa; +} + +/* Plug in "subs" for dimension "type", "pos" of "aff". + * + * Let i be the dimension to replace and let "subs" be of the form + * + * f/d + * + * and "aff" of the form + * + * (a i + g)/m + * + * The result is + * + * (a f + d g')/(m d) + * + * where g' is the result of plugging in "subs" in each of the integer + * divisions in g. + */ +__isl_give isl_aff *isl_aff_substitute(__isl_take isl_aff *aff, + enum isl_dim_type type, unsigned pos, __isl_keep isl_aff *subs) +{ + isl_ctx *ctx; + isl_int v; + isl_size n_div; + + aff = isl_aff_cow(aff); + if (!aff || !subs) + return isl_aff_free(aff); + + ctx = isl_aff_get_ctx(aff); + if (!isl_space_is_equal(aff->ls->dim, subs->ls->dim)) + isl_die(ctx, isl_error_invalid, + "spaces don't match", return isl_aff_free(aff)); + n_div = isl_aff_domain_dim(subs, isl_dim_div); + if (n_div < 0) + return isl_aff_free(aff); + if (n_div != 0) + isl_die(ctx, isl_error_unsupported, + "cannot handle divs yet", return isl_aff_free(aff)); + + aff->ls = isl_local_space_substitute(aff->ls, type, pos, subs); + if (!aff->ls) + return isl_aff_free(aff); + + aff->v = isl_vec_cow(aff->v); + if (!aff->v) + return isl_aff_free(aff); + + pos += isl_local_space_offset(aff->ls, type); + + isl_int_init(v); + isl_seq_substitute(aff->v->el, pos, subs->v->el, + aff->v->size, subs->v->size, v); + isl_int_clear(v); + + return aff; +} + +/* Plug in "subs" for dimension "type", "pos" in each of the affine + * expressions in "maff". + */ +__isl_give isl_multi_aff *isl_multi_aff_substitute( + __isl_take isl_multi_aff *maff, enum isl_dim_type type, unsigned pos, + __isl_keep isl_aff *subs) +{ + isl_size n; + int i; + + n = isl_multi_aff_size(maff); + if (n < 0 || !subs) + return isl_multi_aff_free(maff); + + if (type == isl_dim_in) + type = isl_dim_set; + + for (i = 0; i < n; ++i) { + isl_aff *aff; + + aff = isl_multi_aff_take_at(maff, i); + aff = isl_aff_substitute(aff, type, pos, subs); + maff = isl_multi_aff_restore_at(maff, i, aff); + } + + return maff; +} + +/* Plug in "subs" for input dimension "pos" of "pma". + * + * pma is of the form + * + * A_i(v) -> M_i(v) + * + * while subs is of the form + * + * v' = B_j(v) -> S_j + * + * Each pair i,j such that C_ij = A_i \cap B_i is non-empty + * has a contribution in the result, in particular + * + * C_ij(S_j) -> M_i(S_j) + * + * Note that plugging in S_j in C_ij may also result in an empty set + * and this contribution should simply be discarded. + */ +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_substitute( + __isl_take isl_pw_multi_aff *pma, unsigned pos, + __isl_keep isl_pw_aff *subs) +{ + int i, j, n; + isl_pw_multi_aff *res; + + if (!pma || !subs) + return isl_pw_multi_aff_free(pma); + + n = pma->n * subs->n; + res = isl_pw_multi_aff_alloc_size(isl_space_copy(pma->dim), n); + + for (i = 0; i < pma->n; ++i) { + for (j = 0; j < subs->n; ++j) { + isl_set *common; + isl_multi_aff *res_ij; + int empty; + + common = isl_set_intersect( + isl_set_copy(pma->p[i].set), + isl_set_copy(subs->p[j].set)); + common = isl_set_substitute(common, + pos, subs->p[j].aff); + empty = isl_set_plain_is_empty(common); + if (empty < 0 || empty) { + isl_set_free(common); + if (empty < 0) + goto error; + continue; + } + + res_ij = isl_multi_aff_substitute( + isl_multi_aff_copy(pma->p[i].maff), + isl_dim_in, pos, subs->p[j].aff); + + res = isl_pw_multi_aff_add_piece(res, common, res_ij); + } + } + + isl_pw_multi_aff_free(pma); + return res; +error: + isl_pw_multi_aff_free(pma); + isl_pw_multi_aff_free(res); + return NULL; +} + +/* Compute the preimage of a range of dimensions in the affine expression "src" + * under "ma" and put the result in "dst". The number of dimensions in "src" + * that precede the range is given by "n_before". The number of dimensions + * in the range is given by the number of output dimensions of "ma". + * The number of dimensions that follow the range is given by "n_after". + * If "has_denom" is set (to one), + * then "src" and "dst" have an extra initial denominator. + * "n_div_ma" is the number of existentials in "ma" + * "n_div_bset" is the number of existentials in "src" + * The resulting "dst" (which is assumed to have been allocated by + * the caller) contains coefficients for both sets of existentials, + * first those in "ma" and then those in "src". + * f, c1, c2 and g are temporary objects that have been initialized + * by the caller. + * + * Let src represent the expression + * + * (a(p) + f_u u + b v + f_w w + c(divs))/d + * + * and let ma represent the expressions + * + * v_i = (r_i(p) + s_i(y) + t_i(divs'))/m_i + * + * We start out with the following expression for dst: + * + * (a(p) + f_u u + 0 y + f_w w + 0 divs' + c(divs) + f \sum_i b_i v_i)/d + * + * with the multiplication factor f initially equal to 1 + * and f \sum_i b_i v_i kept separately. + * For each x_i that we substitute, we multiply the numerator + * (and denominator) of dst by c_1 = m_i and add the numerator + * of the x_i expression multiplied by c_2 = f b_i, + * after removing the common factors of c_1 and c_2. + * The multiplication factor f also needs to be multiplied by c_1 + * for the next x_j, j > i. + */ +isl_stat isl_seq_preimage(isl_int *dst, isl_int *src, + __isl_keep isl_multi_aff *ma, int n_before, int n_after, + int n_div_ma, int n_div_bmap, + isl_int f, isl_int c1, isl_int c2, isl_int g, int has_denom) +{ + int i; + isl_size n_param, n_in, n_out; + int o_dst, o_src; + + n_param = isl_multi_aff_dim(ma, isl_dim_param); + n_in = isl_multi_aff_dim(ma, isl_dim_in); + n_out = isl_multi_aff_dim(ma, isl_dim_out); + if (n_param < 0 || n_in < 0 || n_out < 0) + return isl_stat_error; + + isl_seq_cpy(dst, src, has_denom + 1 + n_param + n_before); + o_dst = o_src = has_denom + 1 + n_param + n_before; + isl_seq_clr(dst + o_dst, n_in); + o_dst += n_in; + o_src += n_out; + isl_seq_cpy(dst + o_dst, src + o_src, n_after); + o_dst += n_after; + o_src += n_after; + isl_seq_clr(dst + o_dst, n_div_ma); + o_dst += n_div_ma; + isl_seq_cpy(dst + o_dst, src + o_src, n_div_bmap); + + isl_int_set_si(f, 1); + + for (i = 0; i < n_out; ++i) { + int offset = has_denom + 1 + n_param + n_before + i; + + if (isl_int_is_zero(src[offset])) + continue; + isl_int_set(c1, ma->u.p[i]->v->el[0]); + isl_int_mul(c2, f, src[offset]); + isl_int_gcd(g, c1, c2); + isl_int_divexact(c1, c1, g); + isl_int_divexact(c2, c2, g); + + isl_int_mul(f, f, c1); + o_dst = has_denom; + o_src = 1; + isl_seq_combine(dst + o_dst, c1, dst + o_dst, + c2, ma->u.p[i]->v->el + o_src, 1 + n_param); + o_dst += 1 + n_param; + o_src += 1 + n_param; + isl_seq_scale(dst + o_dst, dst + o_dst, c1, n_before); + o_dst += n_before; + isl_seq_combine(dst + o_dst, c1, dst + o_dst, + c2, ma->u.p[i]->v->el + o_src, n_in); + o_dst += n_in; + o_src += n_in; + isl_seq_scale(dst + o_dst, dst + o_dst, c1, n_after); + o_dst += n_after; + isl_seq_combine(dst + o_dst, c1, dst + o_dst, + c2, ma->u.p[i]->v->el + o_src, n_div_ma); + o_dst += n_div_ma; + o_src += n_div_ma; + isl_seq_scale(dst + o_dst, dst + o_dst, c1, n_div_bmap); + if (has_denom) + isl_int_mul(dst[0], dst[0], c1); + } + + return isl_stat_ok; +} + +/* Compute the pullback of "aff" by the function represented by "ma". + * In other words, plug in "ma" in "aff". The result is an affine expression + * defined over the domain space of "ma". + * + * If "aff" is represented by + * + * (a(p) + b x + c(divs))/d + * + * and ma is represented by + * + * x = D(p) + F(y) + G(divs') + * + * then the result is + * + * (a(p) + b D(p) + b F(y) + b G(divs') + c(divs))/d + * + * The divs in the local space of the input are similarly adjusted + * through a call to isl_local_space_preimage_multi_aff. + */ +__isl_give isl_aff *isl_aff_pullback_multi_aff(__isl_take isl_aff *aff, + __isl_take isl_multi_aff *ma) +{ + isl_aff *res = NULL; + isl_local_space *ls; + isl_size n_div_aff, n_div_ma; + isl_int f, c1, c2, g; + + ma = isl_multi_aff_align_divs(ma); + if (!aff || !ma) + goto error; + + n_div_aff = isl_aff_dim(aff, isl_dim_div); + n_div_ma = ma->n ? isl_aff_dim(ma->u.p[0], isl_dim_div) : 0; + if (n_div_aff < 0 || n_div_ma < 0) + goto error; + + ls = isl_aff_get_domain_local_space(aff); + ls = isl_local_space_preimage_multi_aff(ls, isl_multi_aff_copy(ma)); + res = isl_aff_alloc(ls); + if (!res) + goto error; + + isl_int_init(f); + isl_int_init(c1); + isl_int_init(c2); + isl_int_init(g); + + if (isl_seq_preimage(res->v->el, aff->v->el, ma, 0, 0, + n_div_ma, n_div_aff, f, c1, c2, g, 1) < 0) + res = isl_aff_free(res); + + isl_int_clear(f); + isl_int_clear(c1); + isl_int_clear(c2); + isl_int_clear(g); + + isl_aff_free(aff); + isl_multi_aff_free(ma); + res = isl_aff_normalize(res); + return res; +error: + isl_aff_free(aff); + isl_multi_aff_free(ma); + isl_aff_free(res); + return NULL; +} + +/* Compute the pullback of "aff1" by the function represented by "aff2". + * In other words, plug in "aff2" in "aff1". The result is an affine expression + * defined over the domain space of "aff1". + * + * The domain of "aff1" should match the range of "aff2", which means + * that it should be single-dimensional. + */ +__isl_give isl_aff *isl_aff_pullback_aff(__isl_take isl_aff *aff1, + __isl_take isl_aff *aff2) +{ + isl_multi_aff *ma; + + ma = isl_multi_aff_from_aff(aff2); + return isl_aff_pullback_multi_aff(aff1, ma); +} + +/* Compute the pullback of "ma1" by the function represented by "ma2". + * In other words, plug in "ma2" in "ma1". + */ +__isl_give isl_multi_aff *isl_multi_aff_pullback_multi_aff( + __isl_take isl_multi_aff *ma1, __isl_take isl_multi_aff *ma2) +{ + int i; + isl_size n; + isl_space *space = NULL; + + isl_multi_aff_align_params_bin(&ma1, &ma2); + ma2 = isl_multi_aff_align_divs(ma2); + n = isl_multi_aff_size(ma1); + if (n < 0 || !ma2) + goto error; + + space = isl_space_join(isl_multi_aff_get_space(ma2), + isl_multi_aff_get_space(ma1)); + + for (i = 0; i < n; ++i) { + isl_aff *aff; + + aff = isl_multi_aff_take_at(ma1, i); + aff = isl_aff_pullback_multi_aff(aff, isl_multi_aff_copy(ma2)); + ma1 = isl_multi_aff_restore_at(ma1, i, aff); + } + + ma1 = isl_multi_aff_reset_space(ma1, space); + isl_multi_aff_free(ma2); + return ma1; +error: + isl_space_free(space); + isl_multi_aff_free(ma2); + isl_multi_aff_free(ma1); + return NULL; +} + +/* Extend the local space of "dst" to include the divs + * in the local space of "src". + * + * If "src" does not have any divs or if the local spaces of "dst" and + * "src" are the same, then no extension is required. + */ +__isl_give isl_aff *isl_aff_align_divs(__isl_take isl_aff *dst, + __isl_keep isl_aff *src) +{ + isl_ctx *ctx; + isl_size src_n_div, dst_n_div; + int *exp1 = NULL; + int *exp2 = NULL; + isl_bool equal; + isl_mat *div; + + if (!src || !dst) + return isl_aff_free(dst); + + ctx = isl_aff_get_ctx(src); + equal = isl_local_space_has_equal_space(src->ls, dst->ls); + if (equal < 0) + return isl_aff_free(dst); + if (!equal) + isl_die(ctx, isl_error_invalid, + "spaces don't match", goto error); + + src_n_div = isl_aff_domain_dim(src, isl_dim_div); + dst_n_div = isl_aff_domain_dim(dst, isl_dim_div); + if (src_n_div == 0) + return dst; + equal = isl_local_space_is_equal(src->ls, dst->ls); + if (equal < 0 || src_n_div < 0 || dst_n_div < 0) + return isl_aff_free(dst); + if (equal) + return dst; + + exp1 = isl_alloc_array(ctx, int, src_n_div); + exp2 = isl_alloc_array(ctx, int, dst_n_div); + if (!exp1 || (dst_n_div && !exp2)) + goto error; + + div = isl_merge_divs(src->ls->div, dst->ls->div, exp1, exp2); + dst = isl_aff_expand_divs(dst, div, exp2); + free(exp1); + free(exp2); + + return dst; +error: + free(exp1); + free(exp2); + return isl_aff_free(dst); +} + +/* Adjust the local spaces of the affine expressions in "maff" + * such that they all have the save divs. + */ +__isl_give isl_multi_aff *isl_multi_aff_align_divs( + __isl_take isl_multi_aff *maff) +{ + isl_aff *aff_0; + isl_size n; + int i; + + n = isl_multi_aff_size(maff); + if (n < 0) + return isl_multi_aff_free(maff); + if (n <= 1) + return maff; + + aff_0 = isl_multi_aff_take_at(maff, 0); + for (i = 1; i < n; ++i) { + isl_aff *aff_i; + + aff_i = isl_multi_aff_peek_at(maff, i); + aff_0 = isl_aff_align_divs(aff_0, aff_i); + } + maff = isl_multi_aff_restore_at(maff, 0, aff_0); + + aff_0 = isl_multi_aff_peek_at(maff, 0); + for (i = 1; i < n; ++i) { + isl_aff *aff_i; + + aff_i = isl_multi_aff_take_at(maff, i); + aff_i = isl_aff_align_divs(aff_i, aff_0); + maff = isl_multi_aff_restore_at(maff, i, aff_i); + } + + return maff; +} + +__isl_give isl_aff *isl_aff_lift(__isl_take isl_aff *aff) +{ + aff = isl_aff_cow(aff); + if (!aff) + return NULL; + + aff->ls = isl_local_space_lift(aff->ls); + if (!aff->ls) + return isl_aff_free(aff); + + return aff; +} + +/* Lift "maff" to a space with extra dimensions such that the result + * has no more existentially quantified variables. + * If "ls" is not NULL, then *ls is assigned the local space that lies + * at the basis of the lifting applied to "maff". + */ +__isl_give isl_multi_aff *isl_multi_aff_lift(__isl_take isl_multi_aff *maff, + __isl_give isl_local_space **ls) +{ + int i; + isl_space *space; + isl_aff *aff; + isl_size n, n_div; + + if (ls) + *ls = NULL; + + n = isl_multi_aff_size(maff); + if (n < 0) + return isl_multi_aff_free(maff); + + if (n == 0) { + if (ls) { + isl_space *space = isl_multi_aff_get_domain_space(maff); + *ls = isl_local_space_from_space(space); + if (!*ls) + return isl_multi_aff_free(maff); + } + return maff; + } + + maff = isl_multi_aff_align_divs(maff); + + aff = isl_multi_aff_peek_at(maff, 0); + n_div = isl_aff_dim(aff, isl_dim_div); + if (n_div < 0) + return isl_multi_aff_free(maff); + space = isl_multi_aff_get_space(maff); + space = isl_space_lift(isl_space_domain(space), n_div); + space = isl_space_extend_domain_with_range(space, + isl_multi_aff_get_space(maff)); + maff = isl_multi_aff_restore_space(maff, space); + + if (ls) { + aff = isl_multi_aff_peek_at(maff, 0); + *ls = isl_aff_get_domain_local_space(aff); + if (!*ls) + return isl_multi_aff_free(maff); + } + + for (i = 0; i < n; ++i) { + aff = isl_multi_aff_take_at(maff, i); + aff = isl_aff_lift(aff); + maff = isl_multi_aff_restore_at(maff, i, aff); + } + + return maff; +} + +#undef TYPE +#define TYPE isl_pw_multi_aff +static +#include "check_type_range_templ.c" + +/* Extract an isl_pw_aff corresponding to output dimension "pos" of "pma". + */ +__isl_give isl_pw_aff *isl_pw_multi_aff_get_at( + __isl_keep isl_pw_multi_aff *pma, int pos) +{ + int i; + isl_size n_out; + isl_space *space; + isl_pw_aff *pa; + + if (isl_pw_multi_aff_check_range(pma, isl_dim_out, pos, 1) < 0) + return NULL; + + n_out = isl_pw_multi_aff_dim(pma, isl_dim_out); + if (n_out < 0) + return NULL; + + space = isl_pw_multi_aff_get_space(pma); + space = isl_space_drop_dims(space, isl_dim_out, + pos + 1, n_out - pos - 1); + space = isl_space_drop_dims(space, isl_dim_out, 0, pos); + + pa = isl_pw_aff_alloc_size(space, pma->n); + for (i = 0; i < pma->n; ++i) { + isl_aff *aff; + aff = isl_multi_aff_get_aff(pma->p[i].maff, pos); + pa = isl_pw_aff_add_piece(pa, isl_set_copy(pma->p[i].set), aff); + } + + return pa; +} + +/* This is an alternative name for the function above. + */ +__isl_give isl_pw_aff *isl_pw_multi_aff_get_pw_aff( + __isl_keep isl_pw_multi_aff *pma, int pos) +{ + return isl_pw_multi_aff_get_at(pma, pos); +} + +/* Return an isl_pw_multi_aff with the given "set" as domain and + * an unnamed zero-dimensional range. + */ +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_domain( + __isl_take isl_set *set) +{ + isl_multi_aff *ma; + isl_space *space; + + space = isl_set_get_space(set); + space = isl_space_from_domain(space); + ma = isl_multi_aff_zero(space); + return isl_pw_multi_aff_alloc(set, ma); +} + +/* Add an isl_pw_multi_aff with the given "set" as domain and + * an unnamed zero-dimensional range to *user. + */ +static isl_stat add_pw_multi_aff_from_domain(__isl_take isl_set *set, + void *user) +{ + isl_union_pw_multi_aff **upma = user; + isl_pw_multi_aff *pma; + + pma = isl_pw_multi_aff_from_domain(set); + *upma = isl_union_pw_multi_aff_add_pw_multi_aff(*upma, pma); + + return isl_stat_ok; +} + +/* Return an isl_union_pw_multi_aff with the given "uset" as domain and + * an unnamed zero-dimensional range. + */ +__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_from_domain( + __isl_take isl_union_set *uset) +{ + isl_space *space; + isl_union_pw_multi_aff *upma; + + if (!uset) + return NULL; + + space = isl_union_set_get_space(uset); + upma = isl_union_pw_multi_aff_empty(space); + + if (isl_union_set_foreach_set(uset, + &add_pw_multi_aff_from_domain, &upma) < 0) + goto error; + + isl_union_set_free(uset); + return upma; +error: + isl_union_set_free(uset); + isl_union_pw_multi_aff_free(upma); + return NULL; +} + +/* Local data for bin_entry and the callback "fn". + */ +struct isl_union_pw_multi_aff_bin_data { + isl_union_pw_multi_aff *upma2; + isl_union_pw_multi_aff *res; + isl_pw_multi_aff *pma; + isl_stat (*fn)(__isl_take isl_pw_multi_aff *pma, void *user); +}; + +/* Given an isl_pw_multi_aff from upma1, store it in data->pma + * and call data->fn for each isl_pw_multi_aff in data->upma2. + */ +static isl_stat bin_entry(__isl_take isl_pw_multi_aff *pma, void *user) +{ + struct isl_union_pw_multi_aff_bin_data *data = user; + isl_stat r; + + data->pma = pma; + r = isl_union_pw_multi_aff_foreach_pw_multi_aff(data->upma2, + data->fn, data); + isl_pw_multi_aff_free(pma); + + return r; +} + +/* Call "fn" on each pair of isl_pw_multi_affs in "upma1" and "upma2". + * The isl_pw_multi_aff from upma1 is stored in data->pma (where data is + * passed as user field) and the isl_pw_multi_aff from upma2 is available + * as *entry. The callback should adjust data->res if desired. + */ +static __isl_give isl_union_pw_multi_aff *bin_op( + __isl_take isl_union_pw_multi_aff *upma1, + __isl_take isl_union_pw_multi_aff *upma2, + isl_stat (*fn)(__isl_take isl_pw_multi_aff *pma, void *user)) +{ + isl_space *space; + struct isl_union_pw_multi_aff_bin_data data = { NULL, NULL, NULL, fn }; + + space = isl_union_pw_multi_aff_get_space(upma2); + upma1 = isl_union_pw_multi_aff_align_params(upma1, space); + space = isl_union_pw_multi_aff_get_space(upma1); + upma2 = isl_union_pw_multi_aff_align_params(upma2, space); + + if (!upma1 || !upma2) + goto error; + + data.upma2 = upma2; + data.res = isl_union_pw_multi_aff_alloc_same_size(upma1); + if (isl_union_pw_multi_aff_foreach_pw_multi_aff(upma1, + &bin_entry, &data) < 0) + goto error; + + isl_union_pw_multi_aff_free(upma1); + isl_union_pw_multi_aff_free(upma2); + return data.res; +error: + isl_union_pw_multi_aff_free(upma1); + isl_union_pw_multi_aff_free(upma2); + isl_union_pw_multi_aff_free(data.res); + return NULL; +} + +/* Given two isl_pw_multi_affs A -> B and C -> D, + * construct an isl_pw_multi_aff (A * C) -> [B -> D]. + */ +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_range_product( + __isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2) +{ + isl_space *space; + + isl_pw_multi_aff_align_params_bin(&pma1, &pma2); + space = isl_space_range_product(isl_pw_multi_aff_get_space(pma1), + isl_pw_multi_aff_get_space(pma2)); + return isl_pw_multi_aff_on_shared_domain_in(pma1, pma2, space, + &isl_multi_aff_range_product); +} + +/* Given two isl_pw_multi_affs A -> B and C -> D, + * construct an isl_pw_multi_aff (A * C) -> (B, D). + */ +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_flat_range_product( + __isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2) +{ + isl_space *space; + + isl_pw_multi_aff_align_params_bin(&pma1, &pma2); + space = isl_space_range_product(isl_pw_multi_aff_get_space(pma1), + isl_pw_multi_aff_get_space(pma2)); + space = isl_space_flatten_range(space); + return isl_pw_multi_aff_on_shared_domain_in(pma1, pma2, space, + &isl_multi_aff_flat_range_product); +} + +/* If data->pma and "pma2" have the same domain space, then use "range_product" + * to compute some form of range product and add the result to data->res. + */ +static isl_stat gen_range_product_entry(__isl_take isl_pw_multi_aff *pma2, + __isl_give isl_pw_multi_aff *(*range_product)( + __isl_take isl_pw_multi_aff *pma1, + __isl_take isl_pw_multi_aff *pma2), + void *user) +{ + struct isl_union_pw_multi_aff_bin_data *data = user; + isl_bool match; + isl_space *space1, *space2; + + space1 = isl_pw_multi_aff_peek_space(data->pma); + space2 = isl_pw_multi_aff_peek_space(pma2); + match = isl_space_tuple_is_equal(space1, isl_dim_in, + space2, isl_dim_in); + if (match < 0 || !match) { + isl_pw_multi_aff_free(pma2); + return match < 0 ? isl_stat_error : isl_stat_ok; + } + + pma2 = range_product(isl_pw_multi_aff_copy(data->pma), pma2); + + data->res = isl_union_pw_multi_aff_add_pw_multi_aff(data->res, pma2); + + return isl_stat_ok; +} + +/* If data->pma and "pma2" have the same domain space, then compute + * their flat range product and add the result to data->res. + */ +static isl_stat flat_range_product_entry(__isl_take isl_pw_multi_aff *pma2, + void *user) +{ + return gen_range_product_entry(pma2, + &isl_pw_multi_aff_flat_range_product, user); +} + +/* Given two isl_union_pw_multi_affs A -> B and C -> D, + * construct an isl_union_pw_multi_aff (A * C) -> (B, D). + */ +__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_flat_range_product( + __isl_take isl_union_pw_multi_aff *upma1, + __isl_take isl_union_pw_multi_aff *upma2) +{ + return bin_op(upma1, upma2, &flat_range_product_entry); +} + +/* If data->pma and "pma2" have the same domain space, then compute + * their range product and add the result to data->res. + */ +static isl_stat range_product_entry(__isl_take isl_pw_multi_aff *pma2, + void *user) +{ + return gen_range_product_entry(pma2, + &isl_pw_multi_aff_range_product, user); +} + +/* Given two isl_union_pw_multi_affs A -> B and C -> D, + * construct an isl_union_pw_multi_aff (A * C) -> [B -> D]. + */ +__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_range_product( + __isl_take isl_union_pw_multi_aff *upma1, + __isl_take isl_union_pw_multi_aff *upma2) +{ + return bin_op(upma1, upma2, &range_product_entry); +} + +/* Replace the affine expressions at position "pos" in "pma" by "pa". + * The parameters are assumed to have been aligned. + * + * The implementation essentially performs an isl_pw_*_on_shared_domain, + * except that it works on two different isl_pw_* types. + */ +static __isl_give isl_pw_multi_aff *pw_multi_aff_set_pw_aff( + __isl_take isl_pw_multi_aff *pma, unsigned pos, + __isl_take isl_pw_aff *pa) +{ + int i, j, n; + isl_pw_multi_aff *res = NULL; + + if (!pma || !pa) + goto error; + + if (!isl_space_tuple_is_equal(pma->dim, isl_dim_in, + pa->dim, isl_dim_in)) + isl_die(isl_pw_multi_aff_get_ctx(pma), isl_error_invalid, + "domains don't match", goto error); + if (isl_pw_multi_aff_check_range(pma, isl_dim_out, pos, 1) < 0) + goto error; + + n = pma->n * pa->n; + res = isl_pw_multi_aff_alloc_size(isl_pw_multi_aff_get_space(pma), n); + + for (i = 0; i < pma->n; ++i) { + for (j = 0; j < pa->n; ++j) { + isl_set *common; + isl_multi_aff *res_ij; + int empty; + + common = isl_set_intersect(isl_set_copy(pma->p[i].set), + isl_set_copy(pa->p[j].set)); + empty = isl_set_plain_is_empty(common); + if (empty < 0 || empty) { + isl_set_free(common); + if (empty < 0) + goto error; + continue; + } + + res_ij = isl_multi_aff_set_aff( + isl_multi_aff_copy(pma->p[i].maff), pos, + isl_aff_copy(pa->p[j].aff)); + res_ij = isl_multi_aff_gist(res_ij, + isl_set_copy(common)); + + res = isl_pw_multi_aff_add_piece(res, common, res_ij); + } + } + + isl_pw_multi_aff_free(pma); + isl_pw_aff_free(pa); + return res; +error: + isl_pw_multi_aff_free(pma); + isl_pw_aff_free(pa); + return isl_pw_multi_aff_free(res); +} + +/* Replace the affine expressions at position "pos" in "pma" by "pa". + */ +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_set_pw_aff( + __isl_take isl_pw_multi_aff *pma, unsigned pos, + __isl_take isl_pw_aff *pa) +{ + isl_bool equal_params; + + if (!pma || !pa) + goto error; + equal_params = isl_space_has_equal_params(pma->dim, pa->dim); + if (equal_params < 0) + goto error; + if (equal_params) + return pw_multi_aff_set_pw_aff(pma, pos, pa); + if (isl_pw_multi_aff_check_named_params(pma) < 0 || + isl_pw_aff_check_named_params(pa) < 0) + goto error; + pma = isl_pw_multi_aff_align_params(pma, isl_pw_aff_get_space(pa)); + pa = isl_pw_aff_align_params(pa, isl_pw_multi_aff_get_space(pma)); + return pw_multi_aff_set_pw_aff(pma, pos, pa); +error: + isl_pw_multi_aff_free(pma); + isl_pw_aff_free(pa); + return NULL; +} + +/* Do the parameters of "pa" match those of "space"? + */ +isl_bool isl_pw_aff_matching_params(__isl_keep isl_pw_aff *pa, + __isl_keep isl_space *space) +{ + isl_space *pa_space; + isl_bool match; + + if (!pa || !space) + return isl_bool_error; + + pa_space = isl_pw_aff_get_space(pa); + + match = isl_space_has_equal_params(space, pa_space); + + isl_space_free(pa_space); + return match; +} + +/* Check that the domain space of "pa" matches "space". + */ +isl_stat isl_pw_aff_check_match_domain_space(__isl_keep isl_pw_aff *pa, + __isl_keep isl_space *space) +{ + isl_space *pa_space; + isl_bool match; + + if (!pa || !space) + return isl_stat_error; + + pa_space = isl_pw_aff_get_space(pa); + + match = isl_space_has_equal_params(space, pa_space); + if (match < 0) + goto error; + if (!match) + isl_die(isl_pw_aff_get_ctx(pa), isl_error_invalid, + "parameters don't match", goto error); + match = isl_space_tuple_is_equal(space, isl_dim_in, + pa_space, isl_dim_in); + if (match < 0) + goto error; + if (!match) + isl_die(isl_pw_aff_get_ctx(pa), isl_error_invalid, + "domains don't match", goto error); + isl_space_free(pa_space); + return isl_stat_ok; +error: + isl_space_free(pa_space); + return isl_stat_error; +} + +#undef BASE +#define BASE pw_aff +#undef DOMBASE +#define DOMBASE set + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Is every element of "mpa" defined over a single universe domain? + */ +isl_bool isl_multi_pw_aff_isa_multi_aff(__isl_keep isl_multi_pw_aff *mpa) +{ + return isl_multi_pw_aff_every(mpa, &isl_pw_aff_isa_aff); +} + +/* Given that every element of "mpa" is defined over a single universe domain, + * return the corresponding base expressions. + */ +__isl_give isl_multi_aff *isl_multi_pw_aff_as_multi_aff( + __isl_take isl_multi_pw_aff *mpa) +{ + int i; + isl_size n; + isl_multi_aff *ma; + + n = isl_multi_pw_aff_size(mpa); + if (n < 0) + mpa = isl_multi_pw_aff_free(mpa); + ma = isl_multi_aff_alloc(isl_multi_pw_aff_get_space(mpa)); + for (i = 0; i < n; ++i) { + isl_aff *aff; + + aff = isl_pw_aff_as_aff(isl_multi_pw_aff_get_at(mpa, i)); + ma = isl_multi_aff_set_aff(ma, i, aff); + } + isl_multi_pw_aff_free(mpa); + return ma; +} + +/* If "mpa" has an explicit domain, then intersect the domain of "map" + * with this explicit domain. + */ +__isl_give isl_map *isl_map_intersect_multi_pw_aff_explicit_domain( + __isl_take isl_map *map, __isl_keep isl_multi_pw_aff *mpa) +{ + isl_set *dom; + + if (!isl_multi_pw_aff_has_explicit_domain(mpa)) + return map; + + dom = isl_multi_pw_aff_domain(isl_multi_pw_aff_copy(mpa)); + map = isl_map_intersect_domain(map, dom); + + return map; +} + +/* Are all elements of "mpa" piecewise constants? + */ +isl_bool isl_multi_pw_aff_is_cst(__isl_keep isl_multi_pw_aff *mpa) +{ + return isl_multi_pw_aff_every(mpa, &isl_pw_aff_is_cst); +} + +/* Does "mpa" have a non-trivial explicit domain? + * + * The explicit domain, if present, is trivial if it represents + * an (obviously) universe set. + */ +isl_bool isl_multi_pw_aff_has_non_trivial_domain( + __isl_keep isl_multi_pw_aff *mpa) +{ + if (!mpa) + return isl_bool_error; + if (!isl_multi_pw_aff_has_explicit_domain(mpa)) + return isl_bool_false; + return isl_bool_not(isl_set_plain_is_universe(mpa->u.dom)); +} + +#undef BASE +#define BASE set + +#include "isl_opt_mpa_templ.c" + +/* Compute the minima of the set dimensions as a function of the + * parameters, but independently of the other set dimensions. + */ +__isl_give isl_multi_pw_aff *isl_set_min_multi_pw_aff(__isl_take isl_set *set) +{ + return set_opt_mpa(set, &isl_set_dim_min); +} + +/* Compute the maxima of the set dimensions as a function of the + * parameters, but independently of the other set dimensions. + */ +__isl_give isl_multi_pw_aff *isl_set_max_multi_pw_aff(__isl_take isl_set *set) +{ + return set_opt_mpa(set, &isl_set_dim_max); +} + +#undef BASE +#define BASE map + +#include "isl_opt_mpa_templ.c" + +/* Compute the minima of the output dimensions as a function of the + * parameters and input dimensions, but independently of + * the other output dimensions. + */ +__isl_give isl_multi_pw_aff *isl_map_min_multi_pw_aff(__isl_take isl_map *map) +{ + return map_opt_mpa(map, &isl_map_dim_min); +} + +/* Compute the maxima of the output dimensions as a function of the + * parameters and input dimensions, but independently of + * the other output dimensions. + */ +__isl_give isl_multi_pw_aff *isl_map_max_multi_pw_aff(__isl_take isl_map *map) +{ + return map_opt_mpa(map, &isl_map_dim_max); +} + +#undef TYPE +#define TYPE isl_pw_multi_aff +#include "isl_type_check_match_range_multi_val.c" + +/* Apply "fn" to the base expressions of "pma" and "mv". + */ +static __isl_give isl_pw_multi_aff *isl_pw_multi_aff_op_multi_val( + __isl_take isl_pw_multi_aff *pma, __isl_take isl_multi_val *mv, + __isl_give isl_multi_aff *(*fn)(__isl_take isl_multi_aff *ma, + __isl_take isl_multi_val *mv)) +{ + int i; + isl_size n; + + if (isl_pw_multi_aff_check_match_range_multi_val(pma, mv) < 0) + goto error; + + n = isl_pw_multi_aff_n_piece(pma); + if (n < 0) + goto error; + + for (i = 0; i < n; ++i) { + isl_multi_aff *ma; + + ma = isl_pw_multi_aff_take_base_at(pma, i); + ma = fn(ma, isl_multi_val_copy(mv)); + pma = isl_pw_multi_aff_restore_base_at(pma, i, ma); + } + + isl_multi_val_free(mv); + return pma; +error: + isl_multi_val_free(mv); + isl_pw_multi_aff_free(pma); + return NULL; +} + +/* Scale the elements of "pma" by the corresponding elements of "mv". + */ +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_scale_multi_val( + __isl_take isl_pw_multi_aff *pma, __isl_take isl_multi_val *mv) +{ + return isl_pw_multi_aff_op_multi_val(pma, mv, + &isl_multi_aff_scale_multi_val); +} + +/* Scale the elements of "pma" down by the corresponding elements of "mv". + */ +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_scale_down_multi_val( + __isl_take isl_pw_multi_aff *pma, __isl_take isl_multi_val *mv) +{ + return isl_pw_multi_aff_op_multi_val(pma, mv, + &isl_multi_aff_scale_down_multi_val); +} + +/* This function is called for each entry of an isl_union_pw_multi_aff. + * If the space of the entry matches that of data->mv, + * then apply isl_pw_multi_aff_scale_multi_val and return the result. + * Otherwise, return an empty isl_pw_multi_aff. + */ +static __isl_give isl_pw_multi_aff *union_pw_multi_aff_scale_multi_val_entry( + __isl_take isl_pw_multi_aff *pma, void *user) +{ + isl_bool equal; + isl_multi_val *mv = user; + + equal = isl_pw_multi_aff_match_range_multi_val(pma, mv); + if (equal < 0) + return isl_pw_multi_aff_free(pma); + if (!equal) { + isl_space *space = isl_pw_multi_aff_get_space(pma); + isl_pw_multi_aff_free(pma); + return isl_pw_multi_aff_empty(space); + } + + return isl_pw_multi_aff_scale_multi_val(pma, isl_multi_val_copy(mv)); +} + +/* Scale the elements of "upma" by the corresponding elements of "mv", + * for those entries that match the space of "mv". + */ +__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_scale_multi_val( + __isl_take isl_union_pw_multi_aff *upma, __isl_take isl_multi_val *mv) +{ + struct isl_union_pw_multi_aff_transform_control control = { + .fn = &union_pw_multi_aff_scale_multi_val_entry, + .fn_user = mv, + }; + + upma = isl_union_pw_multi_aff_align_params(upma, + isl_multi_val_get_space(mv)); + mv = isl_multi_val_align_params(mv, + isl_union_pw_multi_aff_get_space(upma)); + if (!upma || !mv) + goto error; + + return isl_union_pw_multi_aff_transform(upma, &control); + + isl_multi_val_free(mv); + return upma; +error: + isl_multi_val_free(mv); + isl_union_pw_multi_aff_free(upma); + return NULL; +} + +/* Construct and return a piecewise multi affine expression + * in the given space with value zero in each of the output dimensions and + * a universe domain. + */ +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_zero(__isl_take isl_space *space) +{ + return isl_pw_multi_aff_from_multi_aff(isl_multi_aff_zero(space)); +} + +/* Construct and return a piecewise multi affine expression + * that is equal to the given piecewise affine expression. + */ +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_pw_aff( + __isl_take isl_pw_aff *pa) +{ + int i; + isl_space *space; + isl_pw_multi_aff *pma; + + if (!pa) + return NULL; + + space = isl_pw_aff_get_space(pa); + pma = isl_pw_multi_aff_alloc_size(space, pa->n); + + for (i = 0; i < pa->n; ++i) { + isl_set *set; + isl_multi_aff *ma; + + set = isl_set_copy(pa->p[i].set); + ma = isl_multi_aff_from_aff(isl_aff_copy(pa->p[i].aff)); + pma = isl_pw_multi_aff_add_piece(pma, set, ma); + } + + isl_pw_aff_free(pa); + return pma; +} + +/* Construct and return a piecewise multi affine expression + * that is equal to the given multi piecewise affine expression + * on the shared domain of the piecewise affine expressions, + * in the special case of a 0D multi piecewise affine expression. + * + * Create a piecewise multi affine expression with the explicit domain of + * the 0D multi piecewise affine expression as domain. + */ +static __isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_multi_pw_aff_0D( + __isl_take isl_multi_pw_aff *mpa) +{ + isl_space *space; + isl_set *dom; + isl_multi_aff *ma; + + space = isl_multi_pw_aff_get_space(mpa); + dom = isl_multi_pw_aff_get_explicit_domain(mpa); + isl_multi_pw_aff_free(mpa); + + ma = isl_multi_aff_zero(space); + return isl_pw_multi_aff_alloc(dom, ma); +} + +/* Construct and return a piecewise multi affine expression + * that is equal to the given multi piecewise affine expression + * on the shared domain of the piecewise affine expressions. + */ +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_multi_pw_aff( + __isl_take isl_multi_pw_aff *mpa) +{ + int i; + isl_space *space; + isl_pw_aff *pa; + isl_pw_multi_aff *pma; + + if (!mpa) + return NULL; + + if (mpa->n == 0) + return isl_pw_multi_aff_from_multi_pw_aff_0D(mpa); + + space = isl_multi_pw_aff_get_space(mpa); + pa = isl_multi_pw_aff_get_pw_aff(mpa, 0); + pma = isl_pw_multi_aff_from_pw_aff(pa); + + for (i = 1; i < mpa->n; ++i) { + isl_pw_multi_aff *pma_i; + + pa = isl_multi_pw_aff_get_pw_aff(mpa, i); + pma_i = isl_pw_multi_aff_from_pw_aff(pa); + pma = isl_pw_multi_aff_range_product(pma, pma_i); + } + + pma = isl_pw_multi_aff_reset_space(pma, space); + + isl_multi_pw_aff_free(mpa); + return pma; +} + +/* Convenience function that constructs an isl_multi_pw_aff + * directly from an isl_aff. + */ +__isl_give isl_multi_pw_aff *isl_multi_pw_aff_from_aff(__isl_take isl_aff *aff) +{ + return isl_multi_pw_aff_from_pw_aff(isl_pw_aff_from_aff(aff)); +} + +/* Construct and return a multi piecewise affine expression + * that is equal to the given multi affine expression. + */ +__isl_give isl_multi_pw_aff *isl_multi_pw_aff_from_multi_aff( + __isl_take isl_multi_aff *ma) +{ + int i; + isl_size n; + isl_multi_pw_aff *mpa; + + n = isl_multi_aff_dim(ma, isl_dim_out); + if (n < 0) + ma = isl_multi_aff_free(ma); + if (!ma) + return NULL; + + mpa = isl_multi_pw_aff_alloc(isl_multi_aff_get_space(ma)); + + for (i = 0; i < n; ++i) { + isl_pw_aff *pa; + + pa = isl_pw_aff_from_aff(isl_multi_aff_get_aff(ma, i)); + mpa = isl_multi_pw_aff_set_pw_aff(mpa, i, pa); + } + + isl_multi_aff_free(ma); + return mpa; +} + +/* This function performs the same operation as isl_multi_pw_aff_from_multi_aff, + * but is considered as a function on an isl_multi_aff when exported. + */ +__isl_give isl_multi_pw_aff *isl_multi_aff_to_multi_pw_aff( + __isl_take isl_multi_aff *ma) +{ + return isl_multi_pw_aff_from_multi_aff(ma); +} + +/* Construct and return a multi piecewise affine expression + * that is equal to the given piecewise multi affine expression. + * + * If the resulting multi piecewise affine expression has + * an explicit domain, then assign it the domain of the input. + * In other cases, the domain is stored in the individual elements. + */ +__isl_give isl_multi_pw_aff *isl_multi_pw_aff_from_pw_multi_aff( + __isl_take isl_pw_multi_aff *pma) +{ + int i; + isl_size n; + isl_space *space; + isl_multi_pw_aff *mpa; + + n = isl_pw_multi_aff_dim(pma, isl_dim_out); + if (n < 0) + pma = isl_pw_multi_aff_free(pma); + space = isl_pw_multi_aff_get_space(pma); + mpa = isl_multi_pw_aff_alloc(space); + + for (i = 0; i < n; ++i) { + isl_pw_aff *pa; + + pa = isl_pw_multi_aff_get_pw_aff(pma, i); + mpa = isl_multi_pw_aff_set_pw_aff(mpa, i, pa); + } + if (isl_multi_pw_aff_has_explicit_domain(mpa)) { + isl_set *dom; + + dom = isl_pw_multi_aff_domain(isl_pw_multi_aff_copy(pma)); + mpa = isl_multi_pw_aff_intersect_domain(mpa, dom); + } + + isl_pw_multi_aff_free(pma); + return mpa; +} + +/* This function performs the same operation as + * isl_multi_pw_aff_from_pw_multi_aff, + * but is considered as a function on an isl_pw_multi_aff when exported. + */ +__isl_give isl_multi_pw_aff *isl_pw_multi_aff_to_multi_pw_aff( + __isl_take isl_pw_multi_aff *pma) +{ + return isl_multi_pw_aff_from_pw_multi_aff(pma); +} + +/* Do "pa1" and "pa2" represent the same function? + * + * We first check if they are obviously equal. + * If not, we convert them to maps and check if those are equal. + * + * If "pa1" or "pa2" contain any NaNs, then they are considered + * not to be the same. A NaN is not equal to anything, not even + * to another NaN. + */ +isl_bool isl_pw_aff_is_equal(__isl_keep isl_pw_aff *pa1, + __isl_keep isl_pw_aff *pa2) +{ + isl_bool equal; + isl_bool has_nan; + isl_map *map1, *map2; + + if (!pa1 || !pa2) + return isl_bool_error; + + equal = isl_pw_aff_plain_is_equal(pa1, pa2); + if (equal < 0 || equal) + return equal; + has_nan = either_involves_nan(pa1, pa2); + if (has_nan < 0) + return isl_bool_error; + if (has_nan) + return isl_bool_false; + + map1 = isl_map_from_pw_aff_internal(isl_pw_aff_copy(pa1)); + map2 = isl_map_from_pw_aff_internal(isl_pw_aff_copy(pa2)); + equal = isl_map_is_equal(map1, map2); + isl_map_free(map1); + isl_map_free(map2); + + return equal; +} + +/* Do "mpa1" and "mpa2" represent the same function? + * + * Note that we cannot convert the entire isl_multi_pw_aff + * to a map because the domains of the piecewise affine expressions + * may not be the same. + */ +isl_bool isl_multi_pw_aff_is_equal(__isl_keep isl_multi_pw_aff *mpa1, + __isl_keep isl_multi_pw_aff *mpa2) +{ + int i; + isl_bool equal, equal_params; + + if (!mpa1 || !mpa2) + return isl_bool_error; + + equal_params = isl_space_has_equal_params(mpa1->space, mpa2->space); + if (equal_params < 0) + return isl_bool_error; + if (!equal_params) { + if (!isl_space_has_named_params(mpa1->space)) + return isl_bool_false; + if (!isl_space_has_named_params(mpa2->space)) + return isl_bool_false; + mpa1 = isl_multi_pw_aff_copy(mpa1); + mpa2 = isl_multi_pw_aff_copy(mpa2); + mpa1 = isl_multi_pw_aff_align_params(mpa1, + isl_multi_pw_aff_get_space(mpa2)); + mpa2 = isl_multi_pw_aff_align_params(mpa2, + isl_multi_pw_aff_get_space(mpa1)); + equal = isl_multi_pw_aff_is_equal(mpa1, mpa2); + isl_multi_pw_aff_free(mpa1); + isl_multi_pw_aff_free(mpa2); + return equal; + } + + equal = isl_space_is_equal(mpa1->space, mpa2->space); + if (equal < 0 || !equal) + return equal; + + for (i = 0; i < mpa1->n; ++i) { + equal = isl_pw_aff_is_equal(mpa1->u.p[i], mpa2->u.p[i]); + if (equal < 0 || !equal) + return equal; + } + + return isl_bool_true; +} + +/* Do "pma1" and "pma2" represent the same function? + * + * First check if they are obviously equal. + * If not, then convert them to maps and check if those are equal. + * + * If "pa1" or "pa2" contain any NaNs, then they are considered + * not to be the same. A NaN is not equal to anything, not even + * to another NaN. + */ +isl_bool isl_pw_multi_aff_is_equal(__isl_keep isl_pw_multi_aff *pma1, + __isl_keep isl_pw_multi_aff *pma2) +{ + isl_bool equal; + isl_bool has_nan; + isl_map *map1, *map2; + + if (!pma1 || !pma2) + return isl_bool_error; + + equal = isl_pw_multi_aff_plain_is_equal(pma1, pma2); + if (equal < 0 || equal) + return equal; + has_nan = isl_pw_multi_aff_involves_nan(pma1); + if (has_nan >= 0 && !has_nan) + has_nan = isl_pw_multi_aff_involves_nan(pma2); + if (has_nan < 0 || has_nan) + return isl_bool_not(has_nan); + + map1 = isl_map_from_pw_multi_aff_internal(isl_pw_multi_aff_copy(pma1)); + map2 = isl_map_from_pw_multi_aff_internal(isl_pw_multi_aff_copy(pma2)); + equal = isl_map_is_equal(map1, map2); + isl_map_free(map1); + isl_map_free(map2); + + return equal; +} + +#undef BASE +#define BASE multi_aff + +#include "isl_multi_pw_aff_pullback_templ.c" + +#undef BASE +#define BASE pw_multi_aff + +#include "isl_multi_pw_aff_pullback_templ.c" + +/* Apply "aff" to "mpa". The range of "mpa" needs to be compatible + * with the domain of "aff". The domain of the result is the same + * as that of "mpa". + * "mpa" and "aff" are assumed to have been aligned. + * + * We first extract the parametric constant from "aff", defined + * over the correct domain. + * Then we add the appropriate combinations of the members of "mpa". + * Finally, we add the integer divisions through recursive calls. + */ +static __isl_give isl_pw_aff *isl_multi_pw_aff_apply_aff_aligned( + __isl_take isl_multi_pw_aff *mpa, __isl_take isl_aff *aff) +{ + int i; + isl_size n_in, n_div, n_mpa_in; + isl_space *space; + isl_val *v; + isl_pw_aff *pa; + isl_aff *tmp; + + n_in = isl_aff_dim(aff, isl_dim_in); + n_div = isl_aff_dim(aff, isl_dim_div); + n_mpa_in = isl_multi_pw_aff_dim(mpa, isl_dim_in); + if (n_in < 0 || n_div < 0 || n_mpa_in < 0) + goto error; + + space = isl_space_domain(isl_multi_pw_aff_get_space(mpa)); + tmp = isl_aff_copy(aff); + tmp = isl_aff_drop_dims(tmp, isl_dim_div, 0, n_div); + tmp = isl_aff_drop_dims(tmp, isl_dim_in, 0, n_in); + tmp = isl_aff_add_dims(tmp, isl_dim_in, n_mpa_in); + tmp = isl_aff_reset_domain_space(tmp, space); + pa = isl_pw_aff_from_aff(tmp); + + for (i = 0; i < n_in; ++i) { + isl_pw_aff *pa_i; + + if (!isl_aff_involves_dims(aff, isl_dim_in, i, 1)) + continue; + v = isl_aff_get_coefficient_val(aff, isl_dim_in, i); + pa_i = isl_multi_pw_aff_get_pw_aff(mpa, i); + pa_i = isl_pw_aff_scale_val(pa_i, v); + pa = isl_pw_aff_add(pa, pa_i); + } + + for (i = 0; i < n_div; ++i) { + isl_aff *div; + isl_pw_aff *pa_i; + + if (!isl_aff_involves_dims(aff, isl_dim_div, i, 1)) + continue; + div = isl_aff_get_div(aff, i); + pa_i = isl_multi_pw_aff_apply_aff_aligned( + isl_multi_pw_aff_copy(mpa), div); + pa_i = isl_pw_aff_floor(pa_i); + v = isl_aff_get_coefficient_val(aff, isl_dim_div, i); + pa_i = isl_pw_aff_scale_val(pa_i, v); + pa = isl_pw_aff_add(pa, pa_i); + } + + isl_multi_pw_aff_free(mpa); + isl_aff_free(aff); + + return pa; +error: + isl_multi_pw_aff_free(mpa); + isl_aff_free(aff); + return NULL; +} + +/* Apply "aff" to "mpa". The range of "mpa" needs to be compatible + * with the domain of "aff". The domain of the result is the same + * as that of "mpa". + */ +__isl_give isl_pw_aff *isl_multi_pw_aff_apply_aff( + __isl_take isl_multi_pw_aff *mpa, __isl_take isl_aff *aff) +{ + isl_bool equal_params; + + if (!aff || !mpa) + goto error; + equal_params = isl_space_has_equal_params(aff->ls->dim, mpa->space); + if (equal_params < 0) + goto error; + if (equal_params) + return isl_multi_pw_aff_apply_aff_aligned(mpa, aff); + + aff = isl_aff_align_params(aff, isl_multi_pw_aff_get_space(mpa)); + mpa = isl_multi_pw_aff_align_params(mpa, isl_aff_get_space(aff)); + + return isl_multi_pw_aff_apply_aff_aligned(mpa, aff); +error: + isl_aff_free(aff); + isl_multi_pw_aff_free(mpa); + return NULL; +} + +/* Apply "pa" to "mpa". The range of "mpa" needs to be compatible + * with the domain of "pa". The domain of the result is the same + * as that of "mpa". + * "mpa" and "pa" are assumed to have been aligned. + * + * We consider each piece in turn. Note that the domains of the + * pieces are assumed to be disjoint and they remain disjoint + * after taking the preimage (over the same function). + */ +static __isl_give isl_pw_aff *isl_multi_pw_aff_apply_pw_aff_aligned( + __isl_take isl_multi_pw_aff *mpa, __isl_take isl_pw_aff *pa) +{ + isl_space *space; + isl_pw_aff *res; + int i; + + if (!mpa || !pa) + goto error; + + space = isl_space_join(isl_multi_pw_aff_get_space(mpa), + isl_pw_aff_get_space(pa)); + res = isl_pw_aff_empty(space); + + for (i = 0; i < pa->n; ++i) { + isl_pw_aff *pa_i; + isl_set *domain; + + pa_i = isl_multi_pw_aff_apply_aff_aligned( + isl_multi_pw_aff_copy(mpa), + isl_aff_copy(pa->p[i].aff)); + domain = isl_set_copy(pa->p[i].set); + domain = isl_set_preimage_multi_pw_aff(domain, + isl_multi_pw_aff_copy(mpa)); + pa_i = isl_pw_aff_intersect_domain(pa_i, domain); + res = isl_pw_aff_add_disjoint(res, pa_i); + } + + isl_pw_aff_free(pa); + isl_multi_pw_aff_free(mpa); + return res; +error: + isl_pw_aff_free(pa); + isl_multi_pw_aff_free(mpa); + return NULL; +} + +/* Apply "pa" to "mpa". The range of "mpa" needs to be compatible + * with the domain of "pa". The domain of the result is the same + * as that of "mpa". + */ +__isl_give isl_pw_aff *isl_multi_pw_aff_apply_pw_aff( + __isl_take isl_multi_pw_aff *mpa, __isl_take isl_pw_aff *pa) +{ + isl_bool equal_params; + + if (!pa || !mpa) + goto error; + equal_params = isl_space_has_equal_params(pa->dim, mpa->space); + if (equal_params < 0) + goto error; + if (equal_params) + return isl_multi_pw_aff_apply_pw_aff_aligned(mpa, pa); + + pa = isl_pw_aff_align_params(pa, isl_multi_pw_aff_get_space(mpa)); + mpa = isl_multi_pw_aff_align_params(mpa, isl_pw_aff_get_space(pa)); + + return isl_multi_pw_aff_apply_pw_aff_aligned(mpa, pa); +error: + isl_pw_aff_free(pa); + isl_multi_pw_aff_free(mpa); + return NULL; +} + +/* Compute the pullback of "pa" by the function represented by "mpa". + * In other words, plug in "mpa" in "pa". + * + * The pullback is computed by applying "pa" to "mpa". + */ +__isl_give isl_pw_aff *isl_pw_aff_pullback_multi_pw_aff( + __isl_take isl_pw_aff *pa, __isl_take isl_multi_pw_aff *mpa) +{ + return isl_multi_pw_aff_apply_pw_aff(mpa, pa); +} + +#undef BASE +#define BASE multi_pw_aff + +#include "isl_multi_pw_aff_pullback_templ.c" + +/* Align the parameters of "mpa1" and "mpa2", check that the ranges + * of "mpa1" and "mpa2" live in the same space, construct map space + * between the domain spaces of "mpa1" and "mpa2" and call "order" + * with this map space as extract argument. + */ +static __isl_give isl_map *isl_multi_pw_aff_order_map( + __isl_take isl_multi_pw_aff *mpa1, __isl_take isl_multi_pw_aff *mpa2, + __isl_give isl_map *(*order)(__isl_keep isl_multi_pw_aff *mpa1, + __isl_keep isl_multi_pw_aff *mpa2, __isl_take isl_space *space)) +{ + int match; + isl_space *space1, *space2; + isl_map *res; + + mpa1 = isl_multi_pw_aff_align_params(mpa1, + isl_multi_pw_aff_get_space(mpa2)); + mpa2 = isl_multi_pw_aff_align_params(mpa2, + isl_multi_pw_aff_get_space(mpa1)); + if (!mpa1 || !mpa2) + goto error; + match = isl_space_tuple_is_equal(mpa1->space, isl_dim_out, + mpa2->space, isl_dim_out); + if (match < 0) + goto error; + if (!match) + isl_die(isl_multi_pw_aff_get_ctx(mpa1), isl_error_invalid, + "range spaces don't match", goto error); + space1 = isl_space_domain(isl_multi_pw_aff_get_space(mpa1)); + space2 = isl_space_domain(isl_multi_pw_aff_get_space(mpa2)); + space1 = isl_space_map_from_domain_and_range(space1, space2); + + res = order(mpa1, mpa2, space1); + isl_multi_pw_aff_free(mpa1); + isl_multi_pw_aff_free(mpa2); + return res; +error: + isl_multi_pw_aff_free(mpa1); + isl_multi_pw_aff_free(mpa2); + return NULL; +} + +/* Return a map containing pairs of elements in the domains of "mpa1" and "mpa2" + * where the function values are equal. "space" is the space of the result. + * The parameters of "mpa1" and "mpa2" are assumed to have been aligned. + * + * "mpa1" and "mpa2" are equal when each of the pairs of elements + * in the sequences are equal. + */ +static __isl_give isl_map *isl_multi_pw_aff_eq_map_on_space( + __isl_keep isl_multi_pw_aff *mpa1, __isl_keep isl_multi_pw_aff *mpa2, + __isl_take isl_space *space) +{ + int i; + isl_size n; + isl_map *res; + + n = isl_multi_pw_aff_dim(mpa1, isl_dim_out); + if (n < 0) + space = isl_space_free(space); + res = isl_map_universe(space); + + for (i = 0; i < n; ++i) { + isl_pw_aff *pa1, *pa2; + isl_map *map; + + pa1 = isl_multi_pw_aff_get_pw_aff(mpa1, i); + pa2 = isl_multi_pw_aff_get_pw_aff(mpa2, i); + map = isl_pw_aff_eq_map(pa1, pa2); + res = isl_map_intersect(res, map); + } + + return res; +} + +/* Return a map containing pairs of elements in the domains of "mpa1" and "mpa2" + * where the function values are equal. + */ +__isl_give isl_map *isl_multi_pw_aff_eq_map(__isl_take isl_multi_pw_aff *mpa1, + __isl_take isl_multi_pw_aff *mpa2) +{ + return isl_multi_pw_aff_order_map(mpa1, mpa2, + &isl_multi_pw_aff_eq_map_on_space); +} + +/* Intersect "map" with the result of applying "order" + * on two copies of "mpa". + */ +static __isl_give isl_map *isl_map_order_at_multi_pw_aff( + __isl_take isl_map *map, __isl_take isl_multi_pw_aff *mpa, + __isl_give isl_map *(*order)(__isl_take isl_multi_pw_aff *mpa1, + __isl_take isl_multi_pw_aff *mpa2)) +{ + return isl_map_intersect(map, order(mpa, isl_multi_pw_aff_copy(mpa))); +} + +/* Return the subset of "map" where the domain and the range + * have equal "mpa" values. + */ +__isl_give isl_map *isl_map_eq_at_multi_pw_aff(__isl_take isl_map *map, + __isl_take isl_multi_pw_aff *mpa) +{ + return isl_map_order_at_multi_pw_aff(map, mpa, + &isl_multi_pw_aff_eq_map); +} + +/* Return a map containing pairs of elements in the domains of "mpa1" and "mpa2" + * where the function values of "mpa1" lexicographically satisfies + * "strict_base"/"base" compared to that of "mpa2". + * "space" is the space of the result. + * The parameters of "mpa1" and "mpa2" are assumed to have been aligned. + * + * "mpa1" lexicographically satisfies "strict_base"/"base" compared to "mpa2" + * if, for some i, the i-th element of "mpa1" satisfies "strict_base"/"base" + * when compared to the i-th element of "mpa2" while all previous elements are + * pairwise equal. + * In particular, if i corresponds to the final elements + * then they need to satisfy "base", while "strict_base" needs to be satisfied + * for other values of i. + * If "base" is a strict order, then "base" and "strict_base" are the same. + */ +static __isl_give isl_map *isl_multi_pw_aff_lex_map_on_space( + __isl_keep isl_multi_pw_aff *mpa1, __isl_keep isl_multi_pw_aff *mpa2, + __isl_give isl_map *(*strict_base)(__isl_take isl_pw_aff *pa1, + __isl_take isl_pw_aff *pa2), + __isl_give isl_map *(*base)(__isl_take isl_pw_aff *pa1, + __isl_take isl_pw_aff *pa2), + __isl_take isl_space *space) +{ + int i; + isl_size n; + isl_map *res, *rest; + + n = isl_multi_pw_aff_dim(mpa1, isl_dim_out); + if (n < 0) + space = isl_space_free(space); + res = isl_map_empty(isl_space_copy(space)); + rest = isl_map_universe(space); + + for (i = 0; i < n; ++i) { + int last; + isl_pw_aff *pa1, *pa2; + isl_map *map; + + last = i == n - 1; + + pa1 = isl_multi_pw_aff_get_pw_aff(mpa1, i); + pa2 = isl_multi_pw_aff_get_pw_aff(mpa2, i); + map = last ? base(pa1, pa2) : strict_base(pa1, pa2); + map = isl_map_intersect(map, isl_map_copy(rest)); + res = isl_map_union(res, map); + + if (last) + continue; + + pa1 = isl_multi_pw_aff_get_pw_aff(mpa1, i); + pa2 = isl_multi_pw_aff_get_pw_aff(mpa2, i); + map = isl_pw_aff_eq_map(pa1, pa2); + rest = isl_map_intersect(rest, map); + } + + isl_map_free(rest); + return res; +} + +#undef ORDER +#define ORDER le +#undef STRICT_ORDER +#define STRICT_ORDER lt +#include "isl_aff_lex_templ.c" + +#undef ORDER +#define ORDER lt +#undef STRICT_ORDER +#define STRICT_ORDER lt +#include "isl_aff_lex_templ.c" + +#undef ORDER +#define ORDER ge +#undef STRICT_ORDER +#define STRICT_ORDER gt +#include "isl_aff_lex_templ.c" + +#undef ORDER +#define ORDER gt +#undef STRICT_ORDER +#define STRICT_ORDER gt +#include "isl_aff_lex_templ.c" + +/* Compare two isl_affs. + * + * Return -1 if "aff1" is "smaller" than "aff2", 1 if "aff1" is "greater" + * than "aff2" and 0 if they are equal. + * + * The order is fairly arbitrary. We do consider expressions that only involve + * earlier dimensions as "smaller". + */ +int isl_aff_plain_cmp(__isl_keep isl_aff *aff1, __isl_keep isl_aff *aff2) +{ + int cmp; + int last1, last2; + + if (aff1 == aff2) + return 0; + + if (!aff1) + return -1; + if (!aff2) + return 1; + + cmp = isl_local_space_cmp(aff1->ls, aff2->ls); + if (cmp != 0) + return cmp; + + last1 = isl_seq_last_non_zero(aff1->v->el + 1, aff1->v->size - 1); + last2 = isl_seq_last_non_zero(aff2->v->el + 1, aff1->v->size - 1); + if (last1 != last2) + return last1 - last2; + + return isl_seq_cmp(aff1->v->el, aff2->v->el, aff1->v->size); +} + +/* Compare two isl_pw_affs. + * + * Return -1 if "pa1" is "smaller" than "pa2", 1 if "pa1" is "greater" + * than "pa2" and 0 if they are equal. + * + * The order is fairly arbitrary. We do consider expressions that only involve + * earlier dimensions as "smaller". + */ +int isl_pw_aff_plain_cmp(__isl_keep isl_pw_aff *pa1, + __isl_keep isl_pw_aff *pa2) +{ + int i; + int cmp; + + if (pa1 == pa2) + return 0; + + if (!pa1) + return -1; + if (!pa2) + return 1; + + cmp = isl_space_cmp(pa1->dim, pa2->dim); + if (cmp != 0) + return cmp; + + if (pa1->n != pa2->n) + return pa1->n - pa2->n; + + for (i = 0; i < pa1->n; ++i) { + cmp = isl_set_plain_cmp(pa1->p[i].set, pa2->p[i].set); + if (cmp != 0) + return cmp; + cmp = isl_aff_plain_cmp(pa1->p[i].aff, pa2->p[i].aff); + if (cmp != 0) + return cmp; + } + + return 0; +} + +/* Return a piecewise affine expression that is equal to "v" on "domain". + */ +__isl_give isl_pw_aff *isl_pw_aff_val_on_domain(__isl_take isl_set *domain, + __isl_take isl_val *v) +{ + isl_space *space; + isl_local_space *ls; + isl_aff *aff; + + space = isl_set_get_space(domain); + ls = isl_local_space_from_space(space); + aff = isl_aff_val_on_domain(ls, v); + + return isl_pw_aff_alloc(domain, aff); +} + +/* This function performs the same operation as isl_pw_aff_val_on_domain, + * but is considered as a function on an isl_set when exported. + */ +__isl_give isl_pw_aff *isl_set_pw_aff_on_domain_val(__isl_take isl_set *domain, + __isl_take isl_val *v) +{ + return isl_pw_aff_val_on_domain(domain, v); +} + +/* Return a piecewise affine expression that is equal to the parameter + * with identifier "id" on "domain". + */ +__isl_give isl_pw_aff *isl_pw_aff_param_on_domain_id( + __isl_take isl_set *domain, __isl_take isl_id *id) +{ + isl_space *space; + isl_aff *aff; + + space = isl_set_get_space(domain); + space = isl_space_add_param_id(space, isl_id_copy(id)); + domain = isl_set_align_params(domain, isl_space_copy(space)); + aff = isl_aff_param_on_domain_space_id(space, id); + + return isl_pw_aff_alloc(domain, aff); +} + +/* This function performs the same operation as + * isl_pw_aff_param_on_domain_id, + * but is considered as a function on an isl_set when exported. + */ +__isl_give isl_pw_aff *isl_set_param_pw_aff_on_domain_id( + __isl_take isl_set *domain, __isl_take isl_id *id) +{ + return isl_pw_aff_param_on_domain_id(domain, id); +} + +/* Return a multi affine expression that is equal to "mv" on domain + * space "space". + */ +__isl_give isl_multi_aff *isl_multi_aff_multi_val_on_domain_space( + __isl_take isl_space *space, __isl_take isl_multi_val *mv) +{ + int i; + isl_size n; + isl_space *space2; + isl_local_space *ls; + isl_multi_aff *ma; + + n = isl_multi_val_dim(mv, isl_dim_set); + if (!space || n < 0) + goto error; + + space2 = isl_multi_val_get_space(mv); + space2 = isl_space_align_params(space2, isl_space_copy(space)); + space = isl_space_align_params(space, isl_space_copy(space2)); + space = isl_space_map_from_domain_and_range(space, space2); + ma = isl_multi_aff_alloc(isl_space_copy(space)); + ls = isl_local_space_from_space(isl_space_domain(space)); + for (i = 0; i < n; ++i) { + isl_val *v; + isl_aff *aff; + + v = isl_multi_val_get_val(mv, i); + aff = isl_aff_val_on_domain(isl_local_space_copy(ls), v); + ma = isl_multi_aff_set_aff(ma, i, aff); + } + isl_local_space_free(ls); + + isl_multi_val_free(mv); + return ma; +error: + isl_space_free(space); + isl_multi_val_free(mv); + return NULL; +} + +/* This is an alternative name for the function above. + */ +__isl_give isl_multi_aff *isl_multi_aff_multi_val_on_space( + __isl_take isl_space *space, __isl_take isl_multi_val *mv) +{ + return isl_multi_aff_multi_val_on_domain_space(space, mv); +} + +/* This function performs the same operation as + * isl_multi_aff_multi_val_on_domain_space, + * but is considered as a function on an isl_space when exported. + */ +__isl_give isl_multi_aff *isl_space_multi_aff_on_domain_multi_val( + __isl_take isl_space *space, __isl_take isl_multi_val *mv) +{ + return isl_multi_aff_multi_val_on_domain_space(space, mv); +} + +/* Return a piecewise multi-affine expression + * that is equal to "mv" on "domain". + */ +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_multi_val_on_domain( + __isl_take isl_set *domain, __isl_take isl_multi_val *mv) +{ + isl_space *space; + isl_multi_aff *ma; + + space = isl_set_get_space(domain); + ma = isl_multi_aff_multi_val_on_space(space, mv); + + return isl_pw_multi_aff_alloc(domain, ma); +} + +/* This function performs the same operation as + * isl_pw_multi_aff_multi_val_on_domain, + * but is considered as a function on an isl_set when exported. + */ +__isl_give isl_pw_multi_aff *isl_set_pw_multi_aff_on_domain_multi_val( + __isl_take isl_set *domain, __isl_take isl_multi_val *mv) +{ + return isl_pw_multi_aff_multi_val_on_domain(domain, mv); +} + +/* Internal data structure for isl_union_pw_multi_aff_multi_val_on_domain. + * mv is the value that should be attained on each domain set + * res collects the results + */ +struct isl_union_pw_multi_aff_multi_val_on_domain_data { + isl_multi_val *mv; + isl_union_pw_multi_aff *res; +}; + +/* Create an isl_pw_multi_aff equal to data->mv on "domain" + * and add it to data->res. + */ +static isl_stat pw_multi_aff_multi_val_on_domain(__isl_take isl_set *domain, + void *user) +{ + struct isl_union_pw_multi_aff_multi_val_on_domain_data *data = user; + isl_pw_multi_aff *pma; + isl_multi_val *mv; + + mv = isl_multi_val_copy(data->mv); + pma = isl_pw_multi_aff_multi_val_on_domain(domain, mv); + data->res = isl_union_pw_multi_aff_add_pw_multi_aff(data->res, pma); + + return data->res ? isl_stat_ok : isl_stat_error; +} + +/* Return a union piecewise multi-affine expression + * that is equal to "mv" on "domain". + */ +__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) +{ + struct isl_union_pw_multi_aff_multi_val_on_domain_data data; + isl_space *space; + + space = isl_union_set_get_space(domain); + data.res = isl_union_pw_multi_aff_empty(space); + data.mv = mv; + if (isl_union_set_foreach_set(domain, + &pw_multi_aff_multi_val_on_domain, &data) < 0) + data.res = isl_union_pw_multi_aff_free(data.res); + isl_union_set_free(domain); + isl_multi_val_free(mv); + return data.res; +} + +/* Compute the pullback of data->pma by the function represented by "pma2", + * provided the spaces match, and add the results to data->res. + */ +static isl_stat pullback_entry(__isl_take isl_pw_multi_aff *pma2, void *user) +{ + struct isl_union_pw_multi_aff_bin_data *data = user; + + if (!isl_space_tuple_is_equal(data->pma->dim, isl_dim_in, + pma2->dim, isl_dim_out)) { + isl_pw_multi_aff_free(pma2); + return isl_stat_ok; + } + + pma2 = isl_pw_multi_aff_pullback_pw_multi_aff( + isl_pw_multi_aff_copy(data->pma), pma2); + + data->res = isl_union_pw_multi_aff_add_pw_multi_aff(data->res, pma2); + if (!data->res) + return isl_stat_error; + + return isl_stat_ok; +} + +/* Compute the pullback of "upma1" by the function represented by "upma2". + */ +__isl_give isl_union_pw_multi_aff * +isl_union_pw_multi_aff_pullback_union_pw_multi_aff( + __isl_take isl_union_pw_multi_aff *upma1, + __isl_take isl_union_pw_multi_aff *upma2) +{ + return bin_op(upma1, upma2, &pullback_entry); +} + +/* Apply "upma2" to "upma1". + * + * That is, compute the pullback of "upma2" by "upma1". + */ +__isl_give isl_union_pw_multi_aff * +isl_union_pw_multi_aff_apply_union_pw_multi_aff( + __isl_take isl_union_pw_multi_aff *upma1, + __isl_take isl_union_pw_multi_aff *upma2) +{ + return isl_union_pw_multi_aff_pullback_union_pw_multi_aff(upma2, upma1); +} + +#undef BASE +#define BASE pw_multi_aff +static +#include "isl_copy_tuple_id_templ.c" + +/* Given a function "pma1" of the form A[B -> C] -> D and + * a function "pma2" of the form E -> B, + * replace the domain of the wrapped relation inside the domain of "pma1" + * by the preimage with respect to "pma2". + * In other words, plug in "pma2" in this nested domain. + * The result is of the form A[E -> C] -> D. + * + * In particular, extend E -> B to A[E -> C] -> A[B -> C] and + * plug that into "pma1". + */ +__isl_give isl_pw_multi_aff * +isl_pw_multi_aff_preimage_domain_wrapped_domain_pw_multi_aff( + __isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2) +{ + isl_space *pma1_space, *pma2_space; + isl_space *space; + isl_pw_multi_aff *id; + + pma1_space = isl_pw_multi_aff_peek_space(pma1); + pma2_space = isl_pw_multi_aff_peek_space(pma2); + + if (isl_space_check_domain_is_wrapping(pma1_space) < 0) + goto error; + if (isl_space_check_wrapped_tuple_is_equal(pma1_space, + isl_dim_in, isl_dim_in, pma2_space, isl_dim_out) < 0) + goto error; + + space = isl_space_domain(isl_space_copy(pma1_space)); + space = isl_space_range(isl_space_unwrap(space)); + id = isl_pw_multi_aff_identity_on_domain_space(space); + pma2 = isl_pw_multi_aff_product(pma2, id); + + pma2 = isl_pw_multi_aff_copy_tuple_id(pma2, isl_dim_in, + pma1_space, isl_dim_in); + pma2 = isl_pw_multi_aff_copy_tuple_id(pma2, isl_dim_out, + pma1_space, isl_dim_in); + + return isl_pw_multi_aff_pullback_pw_multi_aff(pma1, pma2); +error: + isl_pw_multi_aff_free(pma1); + isl_pw_multi_aff_free(pma2); + return NULL; +} + +/* If data->pma and "pma2" are such that + * data->pma is of the form A[B -> C] -> D and + * "pma2" is of the form E -> B, + * then replace the domain of the wrapped relation + * inside the domain of data->pma by the preimage with respect to "pma2" and + * add the result to data->res. + */ +static isl_stat preimage_domain_wrapped_domain_entry( + __isl_take isl_pw_multi_aff *pma2, void *user) +{ + struct isl_union_pw_multi_aff_bin_data *data = user; + isl_space *pma1_space, *pma2_space; + isl_bool match; + + pma1_space = isl_pw_multi_aff_peek_space(data->pma); + pma2_space = isl_pw_multi_aff_peek_space(pma2); + + match = isl_space_domain_is_wrapping(pma1_space); + if (match >= 0 && match) + match = isl_space_wrapped_tuple_is_equal(pma1_space, isl_dim_in, + isl_dim_in, pma2_space, isl_dim_out); + if (match < 0 || !match) { + isl_pw_multi_aff_free(pma2); + return match < 0 ? isl_stat_error : isl_stat_ok; + } + + pma2 = isl_pw_multi_aff_preimage_domain_wrapped_domain_pw_multi_aff( + isl_pw_multi_aff_copy(data->pma), pma2); + + data->res = isl_union_pw_multi_aff_add_pw_multi_aff(data->res, pma2); + + return isl_stat_non_null(data->res); +} + +/* For each pair of functions A[B -> C] -> D in "upma1" and + * E -> B in "upma2", + * replace the domain of the wrapped relation inside the domain of the first + * by the preimage with respect to the second and collect the results. + * In other words, plug in the second function in this nested domain. + * The results are of the form A[E -> C] -> D. + */ +__isl_give isl_union_pw_multi_aff * +isl_union_pw_multi_aff_preimage_domain_wrapped_domain_union_pw_multi_aff( + __isl_take isl_union_pw_multi_aff *upma1, + __isl_take isl_union_pw_multi_aff *upma2) +{ + return bin_op(upma1, upma2, &preimage_domain_wrapped_domain_entry); +} + +/* Check that the domain space of "upa" matches "space". + * + * This function is called from isl_multi_union_pw_aff_set_union_pw_aff and + * can in principle never fail since the space "space" is that + * of the isl_multi_union_pw_aff and is a set space such that + * there is no domain space to match. + * + * We check the parameters and double-check that "space" is + * indeed that of a set. + */ +static isl_stat isl_union_pw_aff_check_match_domain_space( + __isl_keep isl_union_pw_aff *upa, __isl_keep isl_space *space) +{ + isl_space *upa_space; + isl_bool match; + + if (!upa || !space) + return isl_stat_error; + + match = isl_space_is_set(space); + if (match < 0) + return isl_stat_error; + if (!match) + isl_die(isl_space_get_ctx(space), isl_error_invalid, + "expecting set space", return isl_stat_error); + + upa_space = isl_union_pw_aff_get_space(upa); + match = isl_space_has_equal_params(space, upa_space); + if (match < 0) + goto error; + if (!match) + isl_die(isl_space_get_ctx(space), isl_error_invalid, + "parameters don't match", goto error); + + isl_space_free(upa_space); + return isl_stat_ok; +error: + isl_space_free(upa_space); + return isl_stat_error; +} + +/* Do the parameters of "upa" match those of "space"? + */ +static isl_bool isl_union_pw_aff_matching_params( + __isl_keep isl_union_pw_aff *upa, __isl_keep isl_space *space) +{ + isl_space *upa_space; + isl_bool match; + + if (!upa || !space) + return isl_bool_error; + + upa_space = isl_union_pw_aff_get_space(upa); + + match = isl_space_has_equal_params(space, upa_space); + + isl_space_free(upa_space); + return match; +} + +/* Internal data structure for isl_union_pw_aff_reset_domain_space. + * space represents the new parameters. + * res collects the results. + */ +struct isl_union_pw_aff_reset_params_data { + isl_space *space; + isl_union_pw_aff *res; +}; + +/* Replace the parameters of "pa" by data->space and + * add the result to data->res. + */ +static isl_stat reset_params(__isl_take isl_pw_aff *pa, void *user) +{ + struct isl_union_pw_aff_reset_params_data *data = user; + isl_space *space; + + space = isl_pw_aff_get_space(pa); + 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); + + return data->res ? isl_stat_ok : isl_stat_error; +} + +/* Replace the domain space of "upa" by "space". + * Since a union expression does not have a (single) domain space, + * "space" is necessarily a parameter space. + * + * Since the order and the names of the parameters determine + * the hash value, we need to create a new hash table. + */ +static __isl_give isl_union_pw_aff *isl_union_pw_aff_reset_domain_space( + __isl_take isl_union_pw_aff *upa, __isl_take isl_space *space) +{ + struct isl_union_pw_aff_reset_params_data data = { space }; + isl_bool match; + + match = isl_union_pw_aff_matching_params(upa, space); + if (match < 0) + upa = isl_union_pw_aff_free(upa); + else if (match) { + isl_space_free(space); + return upa; + } + + data.res = isl_union_pw_aff_empty(isl_space_copy(space)); + if (isl_union_pw_aff_foreach_pw_aff(upa, &reset_params, &data) < 0) + data.res = isl_union_pw_aff_free(data.res); + + isl_union_pw_aff_free(upa); + isl_space_free(space); + return data.res; +} + +/* Return the floor of "pa". + */ +static __isl_give isl_pw_aff *floor_entry(__isl_take isl_pw_aff *pa, void *user) +{ + return isl_pw_aff_floor(pa); +} + +/* Given f, return floor(f). + */ +__isl_give isl_union_pw_aff *isl_union_pw_aff_floor( + __isl_take isl_union_pw_aff *upa) +{ + return isl_union_pw_aff_transform_inplace(upa, &floor_entry, NULL); +} + +/* Compute + * + * upa mod m = upa - m * floor(upa/m) + * + * with m an integer value. + */ +__isl_give isl_union_pw_aff *isl_union_pw_aff_mod_val( + __isl_take isl_union_pw_aff *upa, __isl_take isl_val *m) +{ + isl_union_pw_aff *res; + + if (!upa || !m) + goto error; + + if (!isl_val_is_int(m)) + isl_die(isl_val_get_ctx(m), isl_error_invalid, + "expecting integer modulo", goto error); + if (!isl_val_is_pos(m)) + isl_die(isl_val_get_ctx(m), isl_error_invalid, + "expecting positive modulo", goto error); + + res = isl_union_pw_aff_copy(upa); + upa = isl_union_pw_aff_scale_down_val(upa, isl_val_copy(m)); + upa = isl_union_pw_aff_floor(upa); + upa = isl_union_pw_aff_scale_val(upa, m); + res = isl_union_pw_aff_sub(res, upa); + + return res; +error: + isl_val_free(m); + isl_union_pw_aff_free(upa); + return NULL; +} + +/* 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. + */ +struct isl_union_pw_multi_aff_get_union_pw_aff_data { + int pos; + isl_union_pw_aff *res; +}; + +/* Extract an isl_pw_aff corresponding to output dimension "pos" of "pma" + * (assuming it has such a dimension) and add it to data->res. + */ +static isl_stat get_union_pw_aff(__isl_take isl_pw_multi_aff *pma, void *user) +{ + struct isl_union_pw_multi_aff_get_union_pw_aff_data *data = user; + isl_size n_out; + isl_pw_aff *pa; + + n_out = isl_pw_multi_aff_dim(pma, isl_dim_out); + if (n_out < 0) + return isl_stat_error; + if (data->pos >= n_out) { + isl_pw_multi_aff_free(pma); + return isl_stat_ok; + } + + pa = isl_pw_multi_aff_get_pw_aff(pma, data->pos); + isl_pw_multi_aff_free(pma); + + data->res = isl_union_pw_aff_add_pw_aff(data->res, pa); + + return data->res ? isl_stat_ok : isl_stat_error; +} + +/* Extract an isl_union_pw_aff corresponding to + * output dimension "pos" of "upma". + */ +__isl_give isl_union_pw_aff *isl_union_pw_multi_aff_get_union_pw_aff( + __isl_keep isl_union_pw_multi_aff *upma, int pos) +{ + struct isl_union_pw_multi_aff_get_union_pw_aff_data data; + isl_space *space; + + if (!upma) + return NULL; + + if (pos < 0) + isl_die(isl_union_pw_multi_aff_get_ctx(upma), isl_error_invalid, + "cannot extract at negative position", return NULL); + + space = isl_union_pw_multi_aff_get_space(upma); + data.res = isl_union_pw_aff_empty(space); + data.pos = pos; + if (isl_union_pw_multi_aff_foreach_pw_multi_aff(upma, + &get_union_pw_aff, &data) < 0) + data.res = isl_union_pw_aff_free(data.res); + + return data.res; +} + +/* Return a union piecewise affine expression + * that is equal to "aff" on "domain". + */ +__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_pw_aff *pa; + + 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; + isl_size dim; + + pa = isl_pw_aff_copy(data->pa); + dim = isl_set_dim(domain, isl_dim_set); + if (dim < 0) + pa = isl_pw_aff_free(pa); + 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.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_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_pw_aff_free(pa); + return NULL; +} + +/* Internal data structure for isl_union_pw_aff_val_on_domain. + * "v" is the value that the resulting isl_union_pw_aff needs to attain. + * "res" collects the results. + */ +struct isl_union_pw_aff_val_on_domain_data { + isl_val *v; + isl_union_pw_aff *res; +}; + +/* Construct a piecewise affine expression that is equal to data->v + * on "domain" and add the result to data->res. + */ +static isl_stat pw_aff_val_on_domain(__isl_take isl_set *domain, void *user) +{ + struct isl_union_pw_aff_val_on_domain_data *data = user; + isl_pw_aff *pa; + isl_val *v; + + v = isl_val_copy(data->v); + pa = isl_pw_aff_val_on_domain(domain, v); + 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 "v" 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_val_on_domain( + __isl_take isl_union_set *domain, __isl_take isl_val *v) +{ + struct isl_union_pw_aff_val_on_domain_data data; + isl_space *space; + + space = isl_union_set_get_space(domain); + data.res = isl_union_pw_aff_empty(space); + data.v = v; + if (isl_union_set_foreach_set(domain, &pw_aff_val_on_domain, &data) < 0) + data.res = isl_union_pw_aff_free(data.res); + isl_union_set_free(domain); + isl_val_free(v); + return data.res; +} + +/* Construct a piecewise multi affine expression + * that is equal to "pa" and add it to upma. + */ +static isl_stat pw_multi_aff_from_pw_aff_entry(__isl_take isl_pw_aff *pa, + void *user) +{ + isl_union_pw_multi_aff **upma = user; + isl_pw_multi_aff *pma; + + pma = isl_pw_multi_aff_from_pw_aff(pa); + *upma = isl_union_pw_multi_aff_add_pw_multi_aff(*upma, pma); + + return *upma ? isl_stat_ok : isl_stat_error; +} + +/* Construct and return a union piecewise multi affine expression + * that is equal to the given union piecewise affine expression. + */ +__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_from_union_pw_aff( + __isl_take isl_union_pw_aff *upa) +{ + isl_space *space; + isl_union_pw_multi_aff *upma; + + if (!upa) + return NULL; + + space = isl_union_pw_aff_get_space(upa); + upma = isl_union_pw_multi_aff_empty(space); + + if (isl_union_pw_aff_foreach_pw_aff(upa, + &pw_multi_aff_from_pw_aff_entry, &upma) < 0) + upma = isl_union_pw_multi_aff_free(upma); + + isl_union_pw_aff_free(upa); + return upma; +} + +/* Compute the set of elements in the domain of "pa" where it is zero and + * add this set to "uset". + */ +static isl_stat zero_union_set(__isl_take isl_pw_aff *pa, void *user) +{ + isl_union_set **uset = (isl_union_set **)user; + + *uset = isl_union_set_add_set(*uset, isl_pw_aff_zero_set(pa)); + + return *uset ? isl_stat_ok : isl_stat_error; +} + +/* Return a union set containing those elements in the domain + * of "upa" where it is zero. + */ +__isl_give isl_union_set *isl_union_pw_aff_zero_union_set( + __isl_take isl_union_pw_aff *upa) +{ + isl_union_set *zero; + + zero = isl_union_set_empty(isl_union_pw_aff_get_space(upa)); + if (isl_union_pw_aff_foreach_pw_aff(upa, &zero_union_set, &zero) < 0) + zero = isl_union_set_free(zero); + + isl_union_pw_aff_free(upa); + return zero; +} + +/* Internal data structure for isl_union_pw_aff_bind_id, + * storing the parameter that needs to be bound and + * the accumulated results. + */ +struct isl_bind_id_data { + isl_id *id; + isl_union_set *bound; +}; + +/* Bind the piecewise affine function "pa" to the parameter data->id, + * adding the resulting elements in the domain where the expression + * is equal to the parameter to data->bound. + */ +static isl_stat bind_id(__isl_take isl_pw_aff *pa, void *user) +{ + struct isl_bind_id_data *data = user; + isl_set *bound; + + bound = isl_pw_aff_bind_id(pa, isl_id_copy(data->id)); + data->bound = isl_union_set_add_set(data->bound, bound); + + return data->bound ? isl_stat_ok : isl_stat_error; +} + +/* Bind the union piecewise affine function "upa" to the parameter "id", + * returning the elements in the domain where the expression + * is equal to the parameter. + */ +__isl_give isl_union_set *isl_union_pw_aff_bind_id( + __isl_take isl_union_pw_aff *upa, __isl_take isl_id *id) +{ + struct isl_bind_id_data data = { id }; + + data.bound = isl_union_set_empty(isl_union_pw_aff_get_space(upa)); + if (isl_union_pw_aff_foreach_pw_aff(upa, &bind_id, &data) < 0) + data.bound = isl_union_set_free(data.bound); + + isl_union_pw_aff_free(upa); + isl_id_free(id); + return data.bound; +} + +/* Internal data structure for isl_union_pw_aff_pullback_union_pw_multi_aff. + * upma is the function that is plugged in. + * pa is the current part of the function in which upma is plugged in. + * res collects the results. + */ +struct isl_union_pw_aff_pullback_upma_data { + isl_union_pw_multi_aff *upma; + isl_pw_aff *pa; + isl_union_pw_aff *res; +}; + +/* Check if "pma" can be plugged into data->pa. + * If so, perform the pullback and add the result to data->res. + */ +static isl_stat pa_pb_pma(__isl_take isl_pw_multi_aff *pma, void *user) +{ + struct isl_union_pw_aff_pullback_upma_data *data = user; + isl_pw_aff *pa; + + if (!isl_space_tuple_is_equal(data->pa->dim, isl_dim_in, + pma->dim, isl_dim_out)) { + isl_pw_multi_aff_free(pma); + return isl_stat_ok; + } + + pa = isl_pw_aff_copy(data->pa); + pa = isl_pw_aff_pullback_pw_multi_aff(pa, pma); + + data->res = isl_union_pw_aff_add_pw_aff(data->res, pa); + + return data->res ? isl_stat_ok : isl_stat_error; +} + +/* Check if any of the elements of data->upma can be plugged into pa, + * add if so add the result to data->res. + */ +static isl_stat upa_pb_upma(__isl_take isl_pw_aff *pa, void *user) +{ + struct isl_union_pw_aff_pullback_upma_data *data = user; + isl_stat r; + + data->pa = pa; + r = isl_union_pw_multi_aff_foreach_pw_multi_aff(data->upma, + &pa_pb_pma, data); + isl_pw_aff_free(pa); + + return r; +} + +/* Compute the pullback of "upa" by the function represented by "upma". + * In other words, plug in "upma" in "upa". The result contains + * expressions defined over the domain space of "upma". + * + * Run over all pairs of elements in "upa" and "upma", perform + * the pullback when appropriate and collect the results. + * If the hash value were based on the domain space rather than + * the function space, then we could run through all elements + * of "upma" and directly pick out the corresponding element of "upa". + */ +__isl_give isl_union_pw_aff *isl_union_pw_aff_pullback_union_pw_multi_aff( + __isl_take isl_union_pw_aff *upa, + __isl_take isl_union_pw_multi_aff *upma) +{ + struct isl_union_pw_aff_pullback_upma_data data = { NULL, NULL }; + isl_space *space; + + space = isl_union_pw_multi_aff_get_space(upma); + upa = isl_union_pw_aff_align_params(upa, space); + space = isl_union_pw_aff_get_space(upa); + upma = isl_union_pw_multi_aff_align_params(upma, space); + + if (!upa || !upma) + goto error; + + data.upma = upma; + data.res = isl_union_pw_aff_alloc_same_size(upa); + if (isl_union_pw_aff_foreach_pw_aff(upa, &upa_pb_upma, &data) < 0) + data.res = isl_union_pw_aff_free(data.res); + + isl_union_pw_aff_free(upa); + isl_union_pw_multi_aff_free(upma); + return data.res; +error: + isl_union_pw_aff_free(upa); + isl_union_pw_multi_aff_free(upma); + return NULL; +} + +#undef BASE +#define BASE union_pw_aff +#undef DOMBASE +#define DOMBASE union_set + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Does "mupa" have a non-trivial explicit domain? + * + * The explicit domain, if present, is trivial if it represents + * an (obviously) universe parameter set. + */ +isl_bool isl_multi_union_pw_aff_has_non_trivial_domain( + __isl_keep isl_multi_union_pw_aff *mupa) +{ + isl_bool is_params, trivial; + isl_set *set; + + if (!mupa) + return isl_bool_error; + if (!isl_multi_union_pw_aff_has_explicit_domain(mupa)) + return isl_bool_false; + is_params = isl_union_set_is_params(mupa->u.dom); + if (is_params < 0 || !is_params) + return isl_bool_not(is_params); + set = isl_set_from_union_set(isl_union_set_copy(mupa->u.dom)); + trivial = isl_set_plain_is_universe(set); + isl_set_free(set); + return isl_bool_not(trivial); +} + +/* Construct a multiple union piecewise affine expression + * in the given space with value zero in each of the output dimensions. + * + * Since there is no canonical zero value for + * a union piecewise affine expression, we can only construct + * 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; + isl_size dim; + + 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); + dim = isl_space_dim(space, isl_dim_out); + if (dim < 0) + goto error; + if (dim != 0) + isl_die(isl_space_get_ctx(space), isl_error_invalid, + "expecting 0D space", goto error); + + return isl_multi_union_pw_aff_alloc(space); +error: + isl_space_free(space); + return NULL; +} + +/* Construct and return a multi union piecewise affine expression + * that is equal to the given multi affine expression. + */ +__isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_from_multi_aff( + __isl_take isl_multi_aff *ma) +{ + isl_multi_pw_aff *mpa; + + mpa = isl_multi_pw_aff_from_multi_aff(ma); + return isl_multi_union_pw_aff_from_multi_pw_aff(mpa); +} + +/* This function performs the same operation as + * isl_multi_union_pw_aff_from_multi_aff, but is considered as a function on an + * isl_multi_aff when exported. + */ +__isl_give isl_multi_union_pw_aff *isl_multi_aff_to_multi_union_pw_aff( + __isl_take isl_multi_aff *ma) +{ + return isl_multi_union_pw_aff_from_multi_aff(ma); +} + +/* Construct and return a multi union piecewise affine expression + * that is equal to the given multi piecewise affine expression. + * + * If the resulting multi union piecewise affine expression has + * an explicit domain, then assign it the domain of the input. + * In other cases, the domain is stored in the individual elements. + */ +__isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_from_multi_pw_aff( + __isl_take isl_multi_pw_aff *mpa) +{ + int i; + isl_size n; + isl_space *space; + isl_multi_union_pw_aff *mupa; + + n = isl_multi_pw_aff_dim(mpa, isl_dim_out); + if (n < 0) + mpa = isl_multi_pw_aff_free(mpa); + if (!mpa) + return NULL; + + space = isl_multi_pw_aff_get_space(mpa); + space = isl_space_range(space); + 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_multi_pw_aff_get_pw_aff(mpa, i); + upa = isl_union_pw_aff_from_pw_aff(pa); + mupa = isl_multi_union_pw_aff_restore_check_space(mupa, i, upa); + } + if (isl_multi_union_pw_aff_has_explicit_domain(mupa)) { + isl_union_set *dom; + isl_multi_pw_aff *copy; + + copy = isl_multi_pw_aff_copy(mpa); + dom = isl_union_set_from_set(isl_multi_pw_aff_domain(copy)); + mupa = isl_multi_union_pw_aff_intersect_domain(mupa, dom); + } + + isl_multi_pw_aff_free(mpa); + + return mupa; +} + +/* Extract the range space of "pma" and assign it to *space. + * If *space has already been set (through a previous call to this function), + * then check that the range space is the same. + */ +static isl_stat extract_space(__isl_take isl_pw_multi_aff *pma, void *user) +{ + isl_space **space = user; + isl_space *pma_space; + isl_bool equal; + + pma_space = isl_space_range(isl_pw_multi_aff_get_space(pma)); + isl_pw_multi_aff_free(pma); + + if (!pma_space) + return isl_stat_error; + if (!*space) { + *space = pma_space; + return isl_stat_ok; + } + + equal = isl_space_is_equal(pma_space, *space); + isl_space_free(pma_space); + + if (equal < 0) + return isl_stat_error; + if (!equal) + isl_die(isl_space_get_ctx(*space), isl_error_invalid, + "range spaces not the same", return isl_stat_error); + return isl_stat_ok; +} + +/* Construct and return a multi union piecewise affine expression + * that is equal to the given union piecewise multi affine expression. + * + * In order to be able to perform the conversion, the input + * needs to be non-empty and may only involve a single range space. + * + * If the resulting multi union piecewise affine expression has + * an explicit domain, then assign it the domain of the input. + * In other cases, the domain is stored in the individual elements. + */ +__isl_give isl_multi_union_pw_aff * +isl_multi_union_pw_aff_from_union_pw_multi_aff( + __isl_take isl_union_pw_multi_aff *upma) +{ + isl_space *space = NULL; + isl_multi_union_pw_aff *mupa; + int i; + isl_size n; + + n = isl_union_pw_multi_aff_n_pw_multi_aff(upma); + if (n < 0) + goto error; + if (n == 0) + isl_die(isl_union_pw_multi_aff_get_ctx(upma), isl_error_invalid, + "cannot extract range space from empty input", + goto error); + if (isl_union_pw_multi_aff_foreach_pw_multi_aff(upma, &extract_space, + &space) < 0) + goto error; + + if (!space) + goto error; + + n = isl_space_dim(space, isl_dim_set); + if (n < 0) + space = isl_space_free(space); + mupa = isl_multi_union_pw_aff_alloc(space); + + for (i = 0; i < n; ++i) { + isl_union_pw_aff *upa; + + upa = isl_union_pw_multi_aff_get_union_pw_aff(upma, i); + mupa = isl_multi_union_pw_aff_set_union_pw_aff(mupa, i, upa); + } + if (isl_multi_union_pw_aff_has_explicit_domain(mupa)) { + isl_union_set *dom; + isl_union_pw_multi_aff *copy; + + copy = isl_union_pw_multi_aff_copy(upma); + dom = isl_union_pw_multi_aff_domain(copy); + mupa = isl_multi_union_pw_aff_intersect_domain(mupa, dom); + } + + isl_union_pw_multi_aff_free(upma); + return mupa; +error: + isl_space_free(space); + isl_union_pw_multi_aff_free(upma); + return NULL; +} + +/* This function performs the same operation as + * isl_multi_union_pw_aff_from_union_pw_multi_aff, + * but is considered as a function on an isl_union_pw_multi_aff when exported. + */ +__isl_give isl_multi_union_pw_aff * +isl_union_pw_multi_aff_as_multi_union_pw_aff( + __isl_take isl_union_pw_multi_aff *upma) +{ + return isl_multi_union_pw_aff_from_union_pw_multi_aff(upma); +} + +/* Try and create an isl_multi_union_pw_aff that is equivalent + * to the given isl_union_map. + * The isl_union_map is required to be single-valued in each space. + * Moreover, it cannot be empty and all range spaces need to be the same. + * Otherwise, an error is produced. + */ +__isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_from_union_map( + __isl_take isl_union_map *umap) +{ + isl_union_pw_multi_aff *upma; + + upma = isl_union_pw_multi_aff_from_union_map(umap); + return isl_multi_union_pw_aff_from_union_pw_multi_aff(upma); +} + +/* This function performs the same operation as + * isl_multi_union_pw_aff_from_union_map, + * but is considered as a function on an isl_union_map when exported. + */ +__isl_give isl_multi_union_pw_aff *isl_union_map_as_multi_union_pw_aff( + __isl_take isl_union_map *umap) +{ + return isl_multi_union_pw_aff_from_union_map(umap); +} + +/* Return a multiple union piecewise affine expression + * that is equal to "mv" on "domain", assuming "domain" and "mv" + * have been aligned. + * + * If the resulting multi union piecewise affine expression has + * an explicit domain, then assign it the input domain. + * In other cases, the domain is stored in the individual elements. + */ +static __isl_give isl_multi_union_pw_aff * +isl_multi_union_pw_aff_multi_val_on_domain_aligned( + __isl_take isl_union_set *domain, __isl_take isl_multi_val *mv) +{ + int i; + isl_size n; + isl_space *space; + isl_multi_union_pw_aff *mupa; + + n = isl_multi_val_dim(mv, isl_dim_set); + if (!domain || n < 0) + goto error; + + space = isl_multi_val_get_space(mv); + mupa = isl_multi_union_pw_aff_alloc(space); + for (i = 0; i < n; ++i) { + isl_val *v; + isl_union_pw_aff *upa; + + v = isl_multi_val_get_val(mv, i); + upa = isl_union_pw_aff_val_on_domain(isl_union_set_copy(domain), + v); + mupa = isl_multi_union_pw_aff_set_union_pw_aff(mupa, i, upa); + } + if (isl_multi_union_pw_aff_has_explicit_domain(mupa)) + mupa = isl_multi_union_pw_aff_intersect_domain(mupa, + isl_union_set_copy(domain)); + + isl_union_set_free(domain); + isl_multi_val_free(mv); + return mupa; +error: + isl_union_set_free(domain); + isl_multi_val_free(mv); + return NULL; +} + +/* Return a multiple union piecewise affine expression + * that is equal to "mv" on "domain". + */ +__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_bool equal_params; + + if (!domain || !mv) + goto error; + equal_params = isl_space_has_equal_params(domain->dim, mv->space); + if (equal_params < 0) + goto error; + if (equal_params) + return isl_multi_union_pw_aff_multi_val_on_domain_aligned( + domain, mv); + domain = isl_union_set_align_params(domain, + isl_multi_val_get_space(mv)); + mv = isl_multi_val_align_params(mv, isl_union_set_get_space(domain)); + return isl_multi_union_pw_aff_multi_val_on_domain_aligned(domain, mv); +error: + isl_union_set_free(domain); + isl_multi_val_free(mv); + 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_pw_multi_aff *pma; + + 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. + * + * If the resulting multi union piecewise affine expression has + * an explicit domain, then assign it the input domain. + * In other cases, the domain is stored in the individual elements. + */ +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; + isl_size n; + isl_space *space; + isl_multi_union_pw_aff *mupa; + + n = isl_pw_multi_aff_dim(pma, isl_dim_set); + if (!domain || n < 0) + goto error; + 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); + } + if (isl_multi_union_pw_aff_has_explicit_domain(mupa)) + mupa = isl_multi_union_pw_aff_intersect_domain(mupa, + isl_union_set_copy(domain)); + + 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_pw_multi_aff_on_domain_aligned( + domain, pma); + domain = isl_union_set_align_params(domain, + 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_pw_multi_aff_free(pma); + return NULL; +} + +/* Return a union set containing those elements in the domains + * of the elements of "mupa" where they are all zero. + * + * If there are no elements, then simply return the entire domain. + */ +__isl_give isl_union_set *isl_multi_union_pw_aff_zero_union_set( + __isl_take isl_multi_union_pw_aff *mupa) +{ + int i; + isl_size n; + isl_union_pw_aff *upa; + isl_union_set *zero; + + n = isl_multi_union_pw_aff_dim(mupa, isl_dim_set); + if (n < 0) + mupa = isl_multi_union_pw_aff_free(mupa); + if (!mupa) + return NULL; + + if (n == 0) + return isl_multi_union_pw_aff_domain(mupa); + + upa = isl_multi_union_pw_aff_get_union_pw_aff(mupa, 0); + zero = isl_union_pw_aff_zero_union_set(upa); + + for (i = 1; i < n; ++i) { + isl_union_set *zero_i; + + upa = isl_multi_union_pw_aff_get_union_pw_aff(mupa, i); + zero_i = isl_union_pw_aff_zero_union_set(upa); + + zero = isl_union_set_intersect(zero, zero_i); + } + + isl_multi_union_pw_aff_free(mupa); + return zero; +} + +/* Construct a union map mapping the shared domain + * of the union piecewise affine expressions to the range of "mupa" + * in the special case of a 0D multi union piecewise affine expression. + * + * Construct a map between the explicit domain of "mupa" and + * the range space. + * Note that this assumes that the domain consists of explicit elements. + */ +static __isl_give isl_union_map *isl_union_map_from_multi_union_pw_aff_0D( + __isl_take isl_multi_union_pw_aff *mupa) +{ + isl_bool is_params; + isl_space *space; + isl_union_set *dom, *ran; + + space = isl_multi_union_pw_aff_get_space(mupa); + dom = isl_multi_union_pw_aff_domain(mupa); + ran = isl_union_set_from_set(isl_set_universe(space)); + + is_params = isl_union_set_is_params(dom); + if (is_params < 0) + dom = isl_union_set_free(dom); + else if (is_params) + isl_die(isl_union_set_get_ctx(dom), isl_error_invalid, + "cannot create union map from expression without " + "explicit domain elements", + dom = isl_union_set_free(dom)); + + return isl_union_map_from_domain_and_range(dom, ran); +} + +/* Construct a union map mapping the shared domain + * of the union piecewise affine expressions to the range of "mupa" + * with each dimension in the range equated to the + * corresponding union piecewise affine expression. + * + * If the input is zero-dimensional, then construct a mapping + * from its explicit domain. + */ +__isl_give isl_union_map *isl_union_map_from_multi_union_pw_aff( + __isl_take isl_multi_union_pw_aff *mupa) +{ + int i; + isl_size n; + isl_space *space; + isl_union_map *umap; + isl_union_pw_aff *upa; + + n = isl_multi_union_pw_aff_dim(mupa, isl_dim_set); + if (n < 0) + mupa = isl_multi_union_pw_aff_free(mupa); + if (!mupa) + return NULL; + + if (n == 0) + return isl_union_map_from_multi_union_pw_aff_0D(mupa); + + upa = isl_multi_union_pw_aff_get_union_pw_aff(mupa, 0); + umap = isl_union_map_from_union_pw_aff(upa); + + for (i = 1; i < n; ++i) { + isl_union_map *umap_i; + + upa = isl_multi_union_pw_aff_get_union_pw_aff(mupa, i); + umap_i = isl_union_map_from_union_pw_aff(upa); + umap = isl_union_map_flat_range_product(umap, umap_i); + } + + space = isl_multi_union_pw_aff_get_space(mupa); + umap = isl_union_map_reset_range_space(umap, space); + + isl_multi_union_pw_aff_free(mupa); + return umap; +} + +/* Internal data structure for isl_union_pw_multi_aff_reset_range_space. + * "range" is the space from which to set the range space. + * "res" collects the results. + */ +struct isl_union_pw_multi_aff_reset_range_space_data { + isl_space *range; + isl_union_pw_multi_aff *res; +}; + +/* Replace the range space of "pma" by the range space of data->range and + * add the result to data->res. + */ +static isl_stat reset_range_space(__isl_take isl_pw_multi_aff *pma, void *user) +{ + struct isl_union_pw_multi_aff_reset_range_space_data *data = user; + isl_space *space; + + space = isl_pw_multi_aff_get_space(pma); + space = isl_space_domain(space); + space = isl_space_extend_domain_with_range(space, + isl_space_copy(data->range)); + pma = isl_pw_multi_aff_reset_space(pma, space); + data->res = isl_union_pw_multi_aff_add_pw_multi_aff(data->res, pma); + + return data->res ? isl_stat_ok : isl_stat_error; +} + +/* Replace the range space of all the piecewise affine expressions in "upma" by + * the range space of "space". + * + * This assumes that all these expressions have the same output dimension. + * + * Since the spaces of the expressions change, so do their hash values. + * We therefore need to create a new isl_union_pw_multi_aff. + * Note that the hash value is currently computed based on the entire + * space even though there can only be a single expression with a given + * domain space. + */ +static __isl_give isl_union_pw_multi_aff * +isl_union_pw_multi_aff_reset_range_space( + __isl_take isl_union_pw_multi_aff *upma, __isl_take isl_space *space) +{ + struct isl_union_pw_multi_aff_reset_range_space_data data = { space }; + isl_space *space_upma; + + space_upma = isl_union_pw_multi_aff_get_space(upma); + data.res = isl_union_pw_multi_aff_empty(space_upma); + if (isl_union_pw_multi_aff_foreach_pw_multi_aff(upma, + &reset_range_space, &data) < 0) + data.res = isl_union_pw_multi_aff_free(data.res); + + isl_space_free(space); + isl_union_pw_multi_aff_free(upma); + return data.res; +} + +/* Construct and return a union piecewise multi affine expression + * that is equal to the given multi union piecewise affine expression, + * in the special case of a 0D multi union piecewise affine expression. + * + * Construct a union piecewise multi affine expression + * on top of the explicit domain of the input. + */ +__isl_give isl_union_pw_multi_aff * +isl_union_pw_multi_aff_from_multi_union_pw_aff_0D( + __isl_take isl_multi_union_pw_aff *mupa) +{ + isl_space *space; + isl_multi_val *mv; + isl_union_set *domain; + + space = isl_multi_union_pw_aff_get_space(mupa); + mv = isl_multi_val_zero(space); + domain = isl_multi_union_pw_aff_domain(mupa); + return isl_union_pw_multi_aff_multi_val_on_domain(domain, mv); +} + +/* Construct and return a union piecewise multi affine expression + * that is equal to the given multi union piecewise affine expression. + * + * If the input is zero-dimensional, then + * construct a union piecewise multi affine expression + * on top of the explicit domain of the input. + */ +__isl_give isl_union_pw_multi_aff * +isl_union_pw_multi_aff_from_multi_union_pw_aff( + __isl_take isl_multi_union_pw_aff *mupa) +{ + int i; + isl_size n; + isl_space *space; + isl_union_pw_multi_aff *upma; + isl_union_pw_aff *upa; + + n = isl_multi_union_pw_aff_dim(mupa, isl_dim_set); + if (n < 0) + mupa = isl_multi_union_pw_aff_free(mupa); + if (!mupa) + return NULL; + + if (n == 0) + return isl_union_pw_multi_aff_from_multi_union_pw_aff_0D(mupa); + + space = isl_multi_union_pw_aff_get_space(mupa); + upa = isl_multi_union_pw_aff_get_union_pw_aff(mupa, 0); + upma = isl_union_pw_multi_aff_from_union_pw_aff(upa); + + for (i = 1; i < n; ++i) { + isl_union_pw_multi_aff *upma_i; + + upa = isl_multi_union_pw_aff_get_union_pw_aff(mupa, i); + upma_i = isl_union_pw_multi_aff_from_union_pw_aff(upa); + upma = isl_union_pw_multi_aff_flat_range_product(upma, upma_i); + } + + upma = isl_union_pw_multi_aff_reset_range_space(upma, space); + + isl_multi_union_pw_aff_free(mupa); + return upma; +} + +/* Intersect the range of "mupa" with "range", + * in the special case where "mupa" is 0D. + * + * Intersect the domain of "mupa" with the constraints on the parameters + * of "range". + */ +static __isl_give isl_multi_union_pw_aff *mupa_intersect_range_0D( + __isl_take isl_multi_union_pw_aff *mupa, __isl_take isl_set *range) +{ + range = isl_set_params(range); + mupa = isl_multi_union_pw_aff_intersect_params(mupa, range); + return mupa; +} + +/* Intersect the range of "mupa" with "range". + * That is, keep only those domain elements that have a function value + * in "range". + */ +__isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_intersect_range( + __isl_take isl_multi_union_pw_aff *mupa, __isl_take isl_set *range) +{ + isl_union_pw_multi_aff *upma; + isl_union_set *domain; + isl_space *space; + isl_size n; + int match; + + n = isl_multi_union_pw_aff_dim(mupa, isl_dim_set); + if (n < 0 || !range) + goto error; + + space = isl_set_get_space(range); + match = isl_space_tuple_is_equal(mupa->space, isl_dim_set, + space, isl_dim_set); + isl_space_free(space); + if (match < 0) + goto error; + if (!match) + isl_die(isl_multi_union_pw_aff_get_ctx(mupa), isl_error_invalid, + "space don't match", goto error); + if (n == 0) + return mupa_intersect_range_0D(mupa, range); + + upma = isl_union_pw_multi_aff_from_multi_union_pw_aff( + isl_multi_union_pw_aff_copy(mupa)); + domain = isl_union_set_from_set(range); + domain = isl_union_set_preimage_union_pw_multi_aff(domain, upma); + mupa = isl_multi_union_pw_aff_intersect_domain(mupa, domain); + + return mupa; +error: + isl_multi_union_pw_aff_free(mupa); + isl_set_free(range); + return NULL; +} + +/* Return the shared domain of the elements of "mupa", + * in the special case where "mupa" is zero-dimensional. + * + * Return the explicit domain of "mupa". + * Note that this domain may be a parameter set, either + * because "mupa" is meant to live in a set space or + * because no explicit domain has been set. + */ +__isl_give isl_union_set *isl_multi_union_pw_aff_domain_0D( + __isl_take isl_multi_union_pw_aff *mupa) +{ + isl_union_set *dom; + + dom = isl_multi_union_pw_aff_get_explicit_domain(mupa); + isl_multi_union_pw_aff_free(mupa); + + return dom; +} + +/* Return the shared domain of the elements of "mupa". + * + * If "mupa" is zero-dimensional, then return its explicit domain. + */ +__isl_give isl_union_set *isl_multi_union_pw_aff_domain( + __isl_take isl_multi_union_pw_aff *mupa) +{ + int i; + isl_size n; + isl_union_pw_aff *upa; + isl_union_set *dom; + + n = isl_multi_union_pw_aff_dim(mupa, isl_dim_set); + if (n < 0) + mupa = isl_multi_union_pw_aff_free(mupa); + if (!mupa) + return NULL; + + if (n == 0) + return isl_multi_union_pw_aff_domain_0D(mupa); + + upa = isl_multi_union_pw_aff_get_union_pw_aff(mupa, 0); + dom = isl_union_pw_aff_domain(upa); + for (i = 1; i < n; ++i) { + isl_union_set *dom_i; + + upa = isl_multi_union_pw_aff_get_union_pw_aff(mupa, i); + dom_i = isl_union_pw_aff_domain(upa); + dom = isl_union_set_intersect(dom, dom_i); + } + + isl_multi_union_pw_aff_free(mupa); + return dom; +} + +/* Apply "aff" to "mupa". The space of "mupa" is equal to the domain of "aff". + * In particular, the spaces have been aligned. + * The result is defined over the shared domain of the elements of "mupa" + * + * We first extract the parametric constant part of "aff" and + * define that over the shared domain. + * Then we iterate over all input dimensions of "aff" and add the corresponding + * multiples of the elements of "mupa". + * Finally, we consider the integer divisions, calling the function + * recursively to obtain an isl_union_pw_aff corresponding to the + * integer division argument. + */ +static __isl_give isl_union_pw_aff *multi_union_pw_aff_apply_aff( + __isl_take isl_multi_union_pw_aff *mupa, __isl_take isl_aff *aff) +{ + int i; + isl_size n_in, n_div; + isl_union_pw_aff *upa; + isl_union_set *uset; + isl_val *v; + isl_aff *cst; + + n_in = isl_aff_dim(aff, isl_dim_in); + n_div = isl_aff_dim(aff, isl_dim_div); + if (n_in < 0 || n_div < 0) + goto error; + + uset = isl_multi_union_pw_aff_domain(isl_multi_union_pw_aff_copy(mupa)); + cst = isl_aff_copy(aff); + cst = isl_aff_drop_dims(cst, isl_dim_div, 0, n_div); + cst = isl_aff_drop_dims(cst, isl_dim_in, 0, n_in); + cst = isl_aff_project_domain_on_params(cst); + upa = isl_union_pw_aff_aff_on_domain(uset, cst); + + for (i = 0; i < n_in; ++i) { + isl_union_pw_aff *upa_i; + + if (!isl_aff_involves_dims(aff, isl_dim_in, i, 1)) + continue; + v = isl_aff_get_coefficient_val(aff, isl_dim_in, i); + upa_i = isl_multi_union_pw_aff_get_union_pw_aff(mupa, i); + upa_i = isl_union_pw_aff_scale_val(upa_i, v); + upa = isl_union_pw_aff_add(upa, upa_i); + } + + for (i = 0; i < n_div; ++i) { + isl_aff *div; + isl_union_pw_aff *upa_i; + + if (!isl_aff_involves_dims(aff, isl_dim_div, i, 1)) + continue; + div = isl_aff_get_div(aff, i); + upa_i = multi_union_pw_aff_apply_aff( + isl_multi_union_pw_aff_copy(mupa), div); + upa_i = isl_union_pw_aff_floor(upa_i); + v = isl_aff_get_coefficient_val(aff, isl_dim_div, i); + upa_i = isl_union_pw_aff_scale_val(upa_i, v); + upa = isl_union_pw_aff_add(upa, upa_i); + } + + isl_multi_union_pw_aff_free(mupa); + isl_aff_free(aff); + + return upa; +error: + isl_multi_union_pw_aff_free(mupa); + isl_aff_free(aff); + return NULL; +} + +/* Apply "aff" to "mupa". The space of "mupa" needs to be compatible + * with the domain of "aff". + * Furthermore, the dimension of this space needs to be greater than zero. + * The result is defined over the shared domain of the elements of "mupa" + * + * We perform these checks and then hand over control to + * multi_union_pw_aff_apply_aff. + */ +__isl_give isl_union_pw_aff *isl_multi_union_pw_aff_apply_aff( + __isl_take isl_multi_union_pw_aff *mupa, __isl_take isl_aff *aff) +{ + isl_size dim; + isl_space *space1, *space2; + isl_bool equal; + + mupa = isl_multi_union_pw_aff_align_params(mupa, + isl_aff_get_space(aff)); + aff = isl_aff_align_params(aff, isl_multi_union_pw_aff_get_space(mupa)); + if (!mupa || !aff) + goto error; + + space1 = isl_multi_union_pw_aff_get_space(mupa); + space2 = isl_aff_get_domain_space(aff); + equal = isl_space_is_equal(space1, space2); + isl_space_free(space1); + isl_space_free(space2); + if (equal < 0) + goto error; + if (!equal) + isl_die(isl_aff_get_ctx(aff), isl_error_invalid, + "spaces don't match", goto error); + dim = isl_aff_dim(aff, isl_dim_in); + if (dim < 0) + goto error; + if (dim == 0) + isl_die(isl_aff_get_ctx(aff), isl_error_invalid, + "cannot determine domains", goto error); + + return multi_union_pw_aff_apply_aff(mupa, aff); +error: + isl_multi_union_pw_aff_free(mupa); + isl_aff_free(aff); + return NULL; +} + +/* Apply "ma" to "mupa", in the special case where "mupa" is 0D. + * The space of "mupa" is known to be compatible with the domain of "ma". + * + * Construct an isl_multi_union_pw_aff that is equal to "ma" + * on the domain of "mupa". + */ +static __isl_give isl_multi_union_pw_aff *mupa_apply_multi_aff_0D( + __isl_take isl_multi_union_pw_aff *mupa, __isl_take isl_multi_aff *ma) +{ + isl_union_set *dom; + + dom = isl_multi_union_pw_aff_domain(mupa); + ma = isl_multi_aff_project_domain_on_params(ma); + + return isl_multi_union_pw_aff_multi_aff_on_domain(dom, ma); +} + +/* Apply "ma" to "mupa". The space of "mupa" needs to be compatible + * with the domain of "ma". + * The result is defined over the shared domain of the elements of "mupa" + */ +__isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_apply_multi_aff( + __isl_take isl_multi_union_pw_aff *mupa, __isl_take isl_multi_aff *ma) +{ + isl_space *space1, *space2; + isl_multi_union_pw_aff *res; + isl_bool equal; + int i; + isl_size n_in, n_out; + + mupa = isl_multi_union_pw_aff_align_params(mupa, + isl_multi_aff_get_space(ma)); + ma = isl_multi_aff_align_params(ma, + isl_multi_union_pw_aff_get_space(mupa)); + n_in = isl_multi_aff_dim(ma, isl_dim_in); + n_out = isl_multi_aff_dim(ma, isl_dim_out); + if (!mupa || n_in < 0 || n_out < 0) + goto error; + + space1 = isl_multi_union_pw_aff_get_space(mupa); + space2 = isl_multi_aff_get_domain_space(ma); + equal = isl_space_is_equal(space1, space2); + isl_space_free(space1); + isl_space_free(space2); + if (equal < 0) + goto error; + if (!equal) + isl_die(isl_multi_aff_get_ctx(ma), isl_error_invalid, + "spaces don't match", goto error); + if (n_in == 0) + return mupa_apply_multi_aff_0D(mupa, ma); + + space1 = isl_space_range(isl_multi_aff_get_space(ma)); + res = isl_multi_union_pw_aff_alloc(space1); + + for (i = 0; i < n_out; ++i) { + isl_aff *aff; + isl_union_pw_aff *upa; + + aff = isl_multi_aff_get_aff(ma, i); + upa = multi_union_pw_aff_apply_aff( + isl_multi_union_pw_aff_copy(mupa), aff); + res = isl_multi_union_pw_aff_set_union_pw_aff(res, i, upa); + } + + isl_multi_aff_free(ma); + isl_multi_union_pw_aff_free(mupa); + return res; +error: + isl_multi_union_pw_aff_free(mupa); + isl_multi_aff_free(ma); + return NULL; +} + +/* Apply "pa" to "mupa", in the special case where "mupa" is 0D. + * The space of "mupa" is known to be compatible with the domain of "pa". + * + * Construct an isl_multi_union_pw_aff that is equal to "pa" + * on the domain of "mupa". + */ +static __isl_give isl_union_pw_aff *isl_multi_union_pw_aff_apply_pw_aff_0D( + __isl_take isl_multi_union_pw_aff *mupa, __isl_take isl_pw_aff *pa) +{ + isl_union_set *dom; + + dom = isl_multi_union_pw_aff_domain(mupa); + pa = isl_pw_aff_project_domain_on_params(pa); + + return isl_union_pw_aff_pw_aff_on_domain(dom, pa); +} + +/* Apply "pa" to "mupa". The space of "mupa" needs to be compatible + * with the domain of "pa". + * Furthermore, the dimension of this space needs to be greater than zero. + * The result is defined over the shared domain of the elements of "mupa" + */ +__isl_give isl_union_pw_aff *isl_multi_union_pw_aff_apply_pw_aff( + __isl_take isl_multi_union_pw_aff *mupa, __isl_take isl_pw_aff *pa) +{ + int i; + isl_bool equal; + isl_size n_in; + isl_space *space, *space2; + isl_union_pw_aff *upa; + + mupa = isl_multi_union_pw_aff_align_params(mupa, + isl_pw_aff_get_space(pa)); + pa = isl_pw_aff_align_params(pa, + isl_multi_union_pw_aff_get_space(mupa)); + if (!mupa || !pa) + goto error; + + space = isl_multi_union_pw_aff_get_space(mupa); + space2 = isl_pw_aff_get_domain_space(pa); + equal = isl_space_is_equal(space, space2); + isl_space_free(space); + isl_space_free(space2); + if (equal < 0) + goto error; + if (!equal) + isl_die(isl_pw_aff_get_ctx(pa), isl_error_invalid, + "spaces don't match", goto error); + n_in = isl_pw_aff_dim(pa, isl_dim_in); + if (n_in < 0) + goto error; + if (n_in == 0) + return isl_multi_union_pw_aff_apply_pw_aff_0D(mupa, pa); + + space = isl_space_params(isl_multi_union_pw_aff_get_space(mupa)); + upa = isl_union_pw_aff_empty(space); + + for (i = 0; i < pa->n; ++i) { + isl_aff *aff; + isl_set *domain; + isl_multi_union_pw_aff *mupa_i; + isl_union_pw_aff *upa_i; + + mupa_i = isl_multi_union_pw_aff_copy(mupa); + domain = isl_set_copy(pa->p[i].set); + mupa_i = isl_multi_union_pw_aff_intersect_range(mupa_i, domain); + aff = isl_aff_copy(pa->p[i].aff); + upa_i = multi_union_pw_aff_apply_aff(mupa_i, aff); + upa = isl_union_pw_aff_union_add(upa, upa_i); + } + + isl_multi_union_pw_aff_free(mupa); + isl_pw_aff_free(pa); + return upa; +error: + isl_multi_union_pw_aff_free(mupa); + isl_pw_aff_free(pa); + return NULL; +} + +/* Apply "pma" to "mupa", in the special case where "mupa" is 0D. + * The space of "mupa" is known to be compatible with the domain of "pma". + * + * Construct an isl_multi_union_pw_aff that is equal to "pma" + * on the domain of "mupa". + */ +static __isl_give isl_multi_union_pw_aff *mupa_apply_pw_multi_aff_0D( + __isl_take isl_multi_union_pw_aff *mupa, + __isl_take isl_pw_multi_aff *pma) +{ + isl_union_set *dom; + + dom = isl_multi_union_pw_aff_domain(mupa); + pma = isl_pw_multi_aff_project_domain_on_params(pma); + + return isl_multi_union_pw_aff_pw_multi_aff_on_domain(dom, pma); +} + +/* Apply "pma" to "mupa". The space of "mupa" needs to be compatible + * with the domain of "pma". + * The result is defined over the shared domain of the elements of "mupa" + */ +__isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_apply_pw_multi_aff( + __isl_take isl_multi_union_pw_aff *mupa, + __isl_take isl_pw_multi_aff *pma) +{ + isl_space *space1, *space2; + isl_multi_union_pw_aff *res; + isl_bool equal; + int i; + isl_size n_in, n_out; + + mupa = isl_multi_union_pw_aff_align_params(mupa, + isl_pw_multi_aff_get_space(pma)); + pma = isl_pw_multi_aff_align_params(pma, + isl_multi_union_pw_aff_get_space(mupa)); + if (!mupa || !pma) + goto error; + + space1 = isl_multi_union_pw_aff_get_space(mupa); + space2 = isl_pw_multi_aff_get_domain_space(pma); + equal = isl_space_is_equal(space1, space2); + isl_space_free(space1); + isl_space_free(space2); + if (equal < 0) + goto error; + if (!equal) + isl_die(isl_pw_multi_aff_get_ctx(pma), isl_error_invalid, + "spaces don't match", goto error); + n_in = isl_pw_multi_aff_dim(pma, isl_dim_in); + n_out = isl_pw_multi_aff_dim(pma, isl_dim_out); + if (n_in < 0 || n_out < 0) + goto error; + if (n_in == 0) + return mupa_apply_pw_multi_aff_0D(mupa, pma); + + space1 = isl_space_range(isl_pw_multi_aff_get_space(pma)); + res = isl_multi_union_pw_aff_alloc(space1); + + for (i = 0; i < n_out; ++i) { + isl_pw_aff *pa; + isl_union_pw_aff *upa; + + pa = isl_pw_multi_aff_get_pw_aff(pma, i); + upa = isl_multi_union_pw_aff_apply_pw_aff( + isl_multi_union_pw_aff_copy(mupa), pa); + res = isl_multi_union_pw_aff_set_union_pw_aff(res, i, upa); + } + + isl_pw_multi_aff_free(pma); + isl_multi_union_pw_aff_free(mupa); + return res; +error: + isl_multi_union_pw_aff_free(mupa); + isl_pw_multi_aff_free(pma); + return NULL; +} + +/* Replace the explicit domain of "mupa" by its preimage under "upma". + * If the explicit domain only keeps track of constraints on the parameters, + * then only update those constraints. + */ +static __isl_give isl_multi_union_pw_aff *preimage_explicit_domain( + __isl_take isl_multi_union_pw_aff *mupa, + __isl_keep isl_union_pw_multi_aff *upma) +{ + isl_bool is_params; + + if (isl_multi_union_pw_aff_check_has_explicit_domain(mupa) < 0) + return isl_multi_union_pw_aff_free(mupa); + + mupa = isl_multi_union_pw_aff_cow(mupa); + if (!mupa) + return NULL; + + is_params = isl_union_set_is_params(mupa->u.dom); + if (is_params < 0) + return isl_multi_union_pw_aff_free(mupa); + + upma = isl_union_pw_multi_aff_copy(upma); + if (is_params) + mupa->u.dom = isl_union_set_intersect_params(mupa->u.dom, + isl_union_set_params(isl_union_pw_multi_aff_domain(upma))); + else + mupa->u.dom = isl_union_set_preimage_union_pw_multi_aff( + mupa->u.dom, upma); + if (!mupa->u.dom) + return isl_multi_union_pw_aff_free(mupa); + return mupa; +} + +/* Compute the pullback of "mupa" by the function represented by "upma". + * In other words, plug in "upma" in "mupa". The result contains + * expressions defined over the domain space of "upma". + * + * Run over all elements of "mupa" and plug in "upma" in each of them. + * + * If "mupa" has an explicit domain, then it is this domain + * that needs to undergo a pullback instead, i.e., a preimage. + */ +__isl_give isl_multi_union_pw_aff * +isl_multi_union_pw_aff_pullback_union_pw_multi_aff( + __isl_take isl_multi_union_pw_aff *mupa, + __isl_take isl_union_pw_multi_aff *upma) +{ + int i; + isl_size n; + + mupa = isl_multi_union_pw_aff_align_params(mupa, + isl_union_pw_multi_aff_get_space(upma)); + upma = isl_union_pw_multi_aff_align_params(upma, + isl_multi_union_pw_aff_get_space(mupa)); + mupa = isl_multi_union_pw_aff_cow(mupa); + n = isl_multi_union_pw_aff_dim(mupa, isl_dim_set); + if (n < 0 || !upma) + goto error; + + for (i = 0; i < n; ++i) { + isl_union_pw_aff *upa; + + upa = isl_multi_union_pw_aff_get_union_pw_aff(mupa, i); + upa = isl_union_pw_aff_pullback_union_pw_multi_aff(upa, + isl_union_pw_multi_aff_copy(upma)); + mupa = isl_multi_union_pw_aff_set_union_pw_aff(mupa, i, upa); + } + + if (isl_multi_union_pw_aff_has_explicit_domain(mupa)) + mupa = preimage_explicit_domain(mupa, upma); + + isl_union_pw_multi_aff_free(upma); + return mupa; +error: + isl_multi_union_pw_aff_free(mupa); + isl_union_pw_multi_aff_free(upma); + return NULL; +} + +/* Extract the sequence of elements in "mupa" with domain space "space" + * (ignoring parameters). + * + * For the elements of "mupa" that are not defined on the specified space, + * the corresponding element in the result is empty. + */ +__isl_give isl_multi_pw_aff *isl_multi_union_pw_aff_extract_multi_pw_aff( + __isl_keep isl_multi_union_pw_aff *mupa, __isl_take isl_space *space) +{ + int i; + isl_size n; + isl_space *space_mpa; + isl_multi_pw_aff *mpa; + + n = isl_multi_union_pw_aff_dim(mupa, isl_dim_set); + if (n < 0 || !space) + goto error; + + space_mpa = isl_multi_union_pw_aff_get_space(mupa); + space = isl_space_replace_params(space, space_mpa); + space_mpa = isl_space_map_from_domain_and_range(isl_space_copy(space), + space_mpa); + mpa = isl_multi_pw_aff_alloc(space_mpa); + + space = isl_space_from_domain(space); + space = isl_space_add_dims(space, isl_dim_out, 1); + for (i = 0; i < n; ++i) { + isl_union_pw_aff *upa; + isl_pw_aff *pa; + + upa = isl_multi_union_pw_aff_get_union_pw_aff(mupa, i); + pa = isl_union_pw_aff_extract_pw_aff(upa, + isl_space_copy(space)); + mpa = isl_multi_pw_aff_set_pw_aff(mpa, i, pa); + isl_union_pw_aff_free(upa); + } + + isl_space_free(space); + return mpa; +error: + isl_space_free(space); + return NULL; +} + +/* Data structure that specifies how isl_union_pw_multi_aff_un_op + * should modify the base expressions in the input. + * + * If "filter" is not NULL, then only the base expressions that satisfy "filter" + * are taken into account. + * "fn" is applied to each entry in the input. + */ +struct isl_union_pw_multi_aff_un_op_control { + isl_bool (*filter)(__isl_keep isl_pw_multi_aff *part); + __isl_give isl_pw_multi_aff *(*fn)(__isl_take isl_pw_multi_aff *pma); +}; + +/* Wrapper for isl_union_pw_multi_aff_un_op filter functions (which do not take + * a second argument) for use as an isl_union_pw_multi_aff_transform + * filter function (which does take a second argument). + * Simply call control->filter without the second argument. + */ +static isl_bool isl_union_pw_multi_aff_un_op_filter_drop_user( + __isl_take isl_pw_multi_aff *pma, void *user) +{ + struct isl_union_pw_multi_aff_un_op_control *control = user; + + return control->filter(pma); +} + +/* Wrapper for isl_union_pw_multi_aff_un_op base functions (which do not take + * a second argument) for use as an isl_union_pw_multi_aff_transform + * base function (which does take a second argument). + * Simply call control->fn without the second argument. + */ +static __isl_give isl_pw_multi_aff *isl_union_pw_multi_aff_un_op_drop_user( + __isl_take isl_pw_multi_aff *pma, void *user) +{ + struct isl_union_pw_multi_aff_un_op_control *control = user; + + return control->fn(pma); +} + +/* Construct an isl_union_pw_multi_aff that is obtained by + * modifying "upma" according to "control". + * + * isl_union_pw_multi_aff_transform performs essentially + * the same operation, but takes a filter and a callback function + * of a different form (with an extra argument). + * Call isl_union_pw_multi_aff_transform with wrappers + * that remove this extra argument. + */ +static __isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_un_op( + __isl_take isl_union_pw_multi_aff *upma, + struct isl_union_pw_multi_aff_un_op_control *control) +{ + struct isl_union_pw_multi_aff_transform_control t_control = { + .filter = &isl_union_pw_multi_aff_un_op_filter_drop_user, + .filter_user = control, + .fn = &isl_union_pw_multi_aff_un_op_drop_user, + .fn_user = control, + }; + + return isl_union_pw_multi_aff_transform(upma, &t_control); +} + +/* For each function in "upma" of the form A -> [B -> C], + * extract the function A -> B and collect the results. + */ +__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_range_factor_domain( + __isl_take isl_union_pw_multi_aff *upma) +{ + struct isl_union_pw_multi_aff_un_op_control control = { + .filter = &isl_pw_multi_aff_range_is_wrapping, + .fn = &isl_pw_multi_aff_range_factor_domain, + }; + return isl_union_pw_multi_aff_un_op(upma, &control); +} + +/* For each function in "upma" of the form A -> [B -> C], + * extract the function A -> C and collect the results. + */ +__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_range_factor_range( + __isl_take isl_union_pw_multi_aff *upma) +{ + struct isl_union_pw_multi_aff_un_op_control control = { + .filter = &isl_pw_multi_aff_range_is_wrapping, + .fn = &isl_pw_multi_aff_range_factor_range, + }; + return isl_union_pw_multi_aff_un_op(upma, &control); +} + +/* Evaluate the affine function "aff" in the void point "pnt". + * In particular, return the value NaN. + */ +static __isl_give isl_val *eval_void(__isl_take isl_aff *aff, + __isl_take isl_point *pnt) +{ + isl_ctx *ctx; + + ctx = isl_point_get_ctx(pnt); + isl_aff_free(aff); + isl_point_free(pnt); + return isl_val_nan(ctx); +} + +/* Evaluate the affine expression "aff" + * in the coordinates (with denominator) "pnt". + */ +static __isl_give isl_val *eval(__isl_keep isl_vec *aff, + __isl_keep isl_vec *pnt) +{ + isl_int n, d; + isl_ctx *ctx; + isl_val *v; + + if (!aff || !pnt) + return NULL; + + ctx = isl_vec_get_ctx(aff); + isl_int_init(n); + isl_int_init(d); + isl_seq_inner_product(aff->el + 1, pnt->el, pnt->size, &n); + isl_int_mul(d, aff->el[0], pnt->el[0]); + v = isl_val_rat_from_isl_int(ctx, n, d); + v = isl_val_normalize(v); + isl_int_clear(n); + isl_int_clear(d); + + return v; +} + +/* Check that the domain space of "aff" is equal to "space". + */ +static isl_stat isl_aff_check_has_domain_space(__isl_keep isl_aff *aff, + __isl_keep isl_space *space) +{ + isl_bool ok; + + ok = isl_space_is_equal(isl_aff_peek_domain_space(aff), space); + if (ok < 0) + return isl_stat_error; + if (!ok) + isl_die(isl_aff_get_ctx(aff), isl_error_invalid, + "incompatible spaces", return isl_stat_error); + return isl_stat_ok; +} + +/* Evaluate the affine function "aff" in "pnt". + */ +__isl_give isl_val *isl_aff_eval(__isl_take isl_aff *aff, + __isl_take isl_point *pnt) +{ + isl_bool is_void; + isl_val *v; + isl_local_space *ls; + + if (isl_aff_check_has_domain_space(aff, isl_point_peek_space(pnt)) < 0) + goto error; + is_void = isl_point_is_void(pnt); + if (is_void < 0) + goto error; + if (is_void) + return eval_void(aff, pnt); + + ls = isl_aff_get_domain_local_space(aff); + pnt = isl_local_space_lift_point(ls, pnt); + + v = eval(aff->v, isl_point_peek_vec(pnt)); + + isl_aff_free(aff); + isl_point_free(pnt); + + return v; +error: + isl_aff_free(aff); + isl_point_free(pnt); + return NULL; +} diff --git a/external/mit/isl/dist/isl_aff_lex_templ.c b/external/mit/isl/dist/isl_aff_lex_templ.c new file mode 100644 index 000000000000..9fbab61fb651 --- /dev/null +++ b/external/mit/isl/dist/isl_aff_lex_templ.c @@ -0,0 +1,55 @@ +/* + * Copyright 2014 INRIA Rocquencourt + * + * Use of this software is governed by the MIT license + * + * Written by Sven Verdoolaege, + * Inria Paris - Rocquencourt, Domaine de Voluceau - Rocquencourt, + * B.P. 105 - 78153 Le Chesnay, France + */ + +#define xFN(TYPE,NAME) TYPE ## _ ## NAME +#define FN(TYPE,NAME) xFN(TYPE,NAME) + +/* Return a map containing pairs of elements in the domains of "mpa1" and "mpa2" + * where the function value of "mpa1" lexicographically compares as "ORDER" + * to that of "mpa2". "space" is the space of the result. + * The parameters of "mpa1" and "mpa2" are assumed to have been aligned. + * + * "mpa1" is in the given lexicographic order compared to "mpa2" + * if, for some i, the i-th element of "mpa1" is in that order compared to + * the i-th element of "mpa2" while all previous elements are + * pairwise equal, where the order needs to be strict (not-equal) + * if i corresponds to anything but the last element. + * The strict version of "ORDER" is defined by "STRICT_ORDER", + * which is the same if "ORDER" itself is strict. + */ +static __isl_give isl_map *FN(FN(isl_multi_pw_aff_lex,ORDER),map_on_space)( + __isl_keep isl_multi_pw_aff *mpa1, __isl_keep isl_multi_pw_aff *mpa2, + __isl_take isl_space *space) +{ + return isl_multi_pw_aff_lex_map_on_space(mpa1, mpa2, + &FN(FN(isl_pw_aff,STRICT_ORDER),map), + &FN(FN(isl_pw_aff,ORDER),map), space); +} + +/* Return a map containing pairs of elements in the domains of "mpa1" and "mpa2" + * where the function value of "mpa1" lexicographically compares as "ORDER" + * to that of "mpa2". + */ +__isl_give isl_map *FN(FN(isl_multi_pw_aff_lex,ORDER),map)( + __isl_take isl_multi_pw_aff *mpa1, __isl_take isl_multi_pw_aff *mpa2) +{ + return isl_multi_pw_aff_order_map(mpa1, mpa2, + &FN(FN(isl_multi_pw_aff_lex,ORDER),map_on_space)); +} + +/* Return the subset of "map" where the domain and the range + * have "mpa" values that lexicographically compare as "ORDER". + */ +__isl_give isl_map *FN(FN(isl_map_lex,ORDER),at_multi_pw_aff)( + __isl_take isl_map *map, __isl_take isl_multi_pw_aff *mpa) +{ + return isl_map_order_at_multi_pw_aff(map, mpa, + &FN(FN(isl_multi_pw_aff_lex,ORDER),map)); +} diff --git a/external/mit/isl/dist/isl_aff_map.c b/external/mit/isl/dist/isl_aff_map.c new file mode 100644 index 000000000000..3f46d86b57e9 --- /dev/null +++ b/external/mit/isl/dist/isl_aff_map.c @@ -0,0 +1,601 @@ +/* + * Copyright 2011 INRIA Saclay + * Copyright 2012-2013 Ecole Normale Superieure + * Copyright 2016 Sven Verdoolaege + * + * 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 +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +/* Check that the input living in "space" lives in a map space. + * That is, check that "space" is a map space. + */ +static isl_stat check_input_is_map(__isl_keep isl_space *space) +{ + isl_bool is_set; + + is_set = isl_space_is_set(space); + if (is_set < 0) + return isl_stat_error; + if (is_set) + isl_die(isl_space_get_ctx(space), isl_error_invalid, + "space of input is not a map", return isl_stat_error); + return isl_stat_ok; +} + +/* Check that the input living in "space" lives in a set space. + * That is, check that "space" is a set space. + */ +static isl_stat check_input_is_set(__isl_keep isl_space *space) +{ + isl_bool is_set; + + is_set = isl_space_is_set(space); + if (is_set < 0) + return isl_stat_error; + if (!is_set) + isl_die(isl_space_get_ctx(space), isl_error_invalid, + "space of input is not a set", return isl_stat_error); + return isl_stat_ok; +} + +/* Construct a basic map mapping the domain of the affine expression + * to a one-dimensional range prescribed by the affine expression. + * If "rational" is set, then construct a rational basic map. + * + * A NaN affine expression cannot be converted to a basic map. + */ +static __isl_give isl_basic_map *isl_basic_map_from_aff2( + __isl_take isl_aff *aff, int rational) +{ + int k; + int pos; + isl_bool is_nan; + isl_local_space *ls; + isl_basic_map *bmap = NULL; + + if (!aff) + return NULL; + is_nan = isl_aff_is_nan(aff); + if (is_nan < 0) + goto error; + if (is_nan) + isl_die(isl_aff_get_ctx(aff), isl_error_invalid, + "cannot convert NaN", goto error); + + ls = isl_aff_get_local_space(aff); + bmap = isl_basic_map_from_local_space(ls); + bmap = isl_basic_map_extend_constraints(bmap, 1, 0); + k = isl_basic_map_alloc_equality(bmap); + if (k < 0) + goto error; + + pos = isl_basic_map_offset(bmap, isl_dim_out); + isl_seq_cpy(bmap->eq[k], aff->v->el + 1, pos); + isl_int_neg(bmap->eq[k][pos], aff->v->el[0]); + isl_seq_cpy(bmap->eq[k] + pos + 1, aff->v->el + 1 + pos, + aff->v->size - (pos + 1)); + + isl_aff_free(aff); + if (rational) + bmap = isl_basic_map_set_rational(bmap); + bmap = isl_basic_map_gauss(bmap, NULL); + bmap = isl_basic_map_finalize(bmap); + return bmap; +error: + isl_aff_free(aff); + isl_basic_map_free(bmap); + return NULL; +} + +/* Construct a basic map mapping the domain of the affine expression + * to a one-dimensional range prescribed by the affine expression. + */ +__isl_give isl_basic_map *isl_basic_map_from_aff(__isl_take isl_aff *aff) +{ + return isl_basic_map_from_aff2(aff, 0); +} + +/* Construct a map mapping the domain of the affine expression + * to a one-dimensional range prescribed by the affine expression. + */ +__isl_give isl_map *isl_map_from_aff(__isl_take isl_aff *aff) +{ + isl_basic_map *bmap; + + bmap = isl_basic_map_from_aff(aff); + return isl_map_from_basic_map(bmap); +} + +/* Construct a basic map mapping the domain of the multi-affine expression + * to its range, with each dimension in the range equated to the + * corresponding affine expression. + * If "rational" is set, then construct a rational basic map. + */ +__isl_give isl_basic_map *isl_basic_map_from_multi_aff2( + __isl_take isl_multi_aff *maff, int rational) +{ + int i; + isl_size dim; + isl_space *space; + isl_basic_map *bmap; + + dim = isl_multi_aff_dim(maff, isl_dim_out); + if (dim < 0) + goto error; + + if (dim != maff->n) + isl_die(isl_multi_aff_get_ctx(maff), isl_error_internal, + "invalid space", goto error); + + space = isl_space_domain(isl_multi_aff_get_space(maff)); + bmap = isl_basic_map_universe(isl_space_from_domain(space)); + if (rational) + bmap = isl_basic_map_set_rational(bmap); + + for (i = 0; i < maff->n; ++i) { + isl_aff *aff; + isl_basic_map *bmap_i; + + aff = isl_aff_copy(maff->u.p[i]); + bmap_i = isl_basic_map_from_aff2(aff, rational); + + bmap = isl_basic_map_flat_range_product(bmap, bmap_i); + } + + bmap = isl_basic_map_reset_space(bmap, isl_multi_aff_get_space(maff)); + + isl_multi_aff_free(maff); + return bmap; +error: + isl_multi_aff_free(maff); + return NULL; +} + +/* Construct a basic map mapping the domain of the multi-affine expression + * to its range, with each dimension in the range equated to the + * corresponding affine expression. + * If "ma" lives in a set space, then the result is actually a set. + */ +static __isl_give isl_basic_map *basic_map_from_multi_aff( + __isl_take isl_multi_aff *ma) +{ + return isl_basic_map_from_multi_aff2(ma, 0); +} + +/* Construct a basic map mapping the domain of the multi-affine expression + * to its range, with each dimension in the range equated to the + * corresponding affine expression. + */ +__isl_give isl_basic_map *isl_basic_map_from_multi_aff( + __isl_take isl_multi_aff *ma) +{ + if (check_input_is_map(isl_multi_aff_peek_space(ma)) < 0) + ma = isl_multi_aff_free(ma); + return basic_map_from_multi_aff(ma); +} + +/* Construct a basic set mapping the parameter domain + * of the multi-affine expression to its space, with each dimension + * in the space equated to the corresponding affine expression. + */ +__isl_give isl_basic_set *isl_basic_set_from_multi_aff( + __isl_take isl_multi_aff *ma) +{ + if (check_input_is_set(isl_multi_aff_peek_space(ma)) < 0) + ma = isl_multi_aff_free(ma); + return bset_from_bmap(basic_map_from_multi_aff(ma)); +} + +/* Construct a map mapping the domain of the multi-affine expression + * to its range, with each dimension in the range equated to the + * corresponding affine expression. + * If "maff" lives in a set space, then the result is actually a set. + */ +__isl_give isl_map *isl_map_from_multi_aff_internal( + __isl_take isl_multi_aff *maff) +{ + isl_basic_map *bmap; + + bmap = basic_map_from_multi_aff(maff); + return isl_map_from_basic_map(bmap); +} + +/* Construct a map mapping the domain the multi-affine expression + * to its range, with each dimension in the range equated to the + * corresponding affine expression. + */ +__isl_give isl_map *isl_map_from_multi_aff(__isl_take isl_multi_aff *ma) +{ + if (check_input_is_map(isl_multi_aff_peek_space(ma)) < 0) + ma = isl_multi_aff_free(ma); + return isl_map_from_multi_aff_internal(ma); +} + +/* This function performs the same operation as isl_map_from_multi_aff, + * but is considered as a function on an isl_multi_aff when exported. + */ +__isl_give isl_map *isl_multi_aff_as_map(__isl_take isl_multi_aff *ma) +{ + return isl_map_from_multi_aff(ma); +} + +/* Construct a set mapping the parameter domain the multi-affine expression + * to its space, with each dimension in the space equated to the + * corresponding affine expression. + */ +__isl_give isl_set *isl_set_from_multi_aff(__isl_take isl_multi_aff *ma) +{ + if (check_input_is_set(isl_multi_aff_peek_space(ma)) < 0) + ma = isl_multi_aff_free(ma); + return isl_map_from_multi_aff_internal(ma); +} + +/* This function performs the same operation as isl_set_from_multi_aff, + * but is considered as a function on an isl_multi_aff when exported. + */ +__isl_give isl_set *isl_multi_aff_as_set(__isl_take isl_multi_aff *ma) +{ + return isl_set_from_multi_aff(ma); +} + +/* Construct a basic map mapping a domain in the given space to + * to an n-dimensional range, with n the number of elements in the list, + * where each coordinate in the range is prescribed by the + * corresponding affine expression. + * The domains of all affine expressions in the list are assumed to match + * domain_space. + */ +__isl_give isl_basic_map *isl_basic_map_from_aff_list( + __isl_take isl_space *domain_space, __isl_take isl_aff_list *list) +{ + int i; + isl_space *space; + isl_basic_map *bmap; + + if (!list) + return NULL; + + space = isl_space_from_domain(domain_space); + bmap = isl_basic_map_universe(space); + + for (i = 0; i < list->n; ++i) { + isl_aff *aff; + isl_basic_map *bmap_i; + + aff = isl_aff_copy(list->p[i]); + bmap_i = isl_basic_map_from_aff(aff); + + bmap = isl_basic_map_flat_range_product(bmap, bmap_i); + } + + isl_aff_list_free(list); + return bmap; +} + +/* Construct a map with as domain the domain of pwaff and + * one-dimensional range corresponding to the affine expressions. + * If "pwaff" lives in a set space, then the result is actually a set. + */ +__isl_give isl_map *isl_map_from_pw_aff_internal(__isl_take isl_pw_aff *pwaff) +{ + int i; + isl_space *space; + isl_map *map; + + if (!pwaff) + return NULL; + + space = isl_pw_aff_get_space(pwaff); + map = isl_map_empty(space); + + for (i = 0; i < pwaff->n; ++i) { + isl_basic_map *bmap; + isl_map *map_i; + + bmap = isl_basic_map_from_aff(isl_aff_copy(pwaff->p[i].aff)); + map_i = isl_map_from_basic_map(bmap); + map_i = isl_map_intersect_domain(map_i, + isl_set_copy(pwaff->p[i].set)); + map = isl_map_union_disjoint(map, map_i); + } + + isl_pw_aff_free(pwaff); + + return map; +} + +/* Construct a map with as domain the domain of pwaff and + * one-dimensional range corresponding to the affine expressions. + */ +__isl_give isl_map *isl_map_from_pw_aff(__isl_take isl_pw_aff *pwaff) +{ + if (check_input_is_map(isl_pw_aff_peek_space(pwaff)) < 0) + pwaff = isl_pw_aff_free(pwaff); + return isl_map_from_pw_aff_internal(pwaff); +} + +/* This function performs the same operation as isl_map_from_pw_aff, + * but is considered as a function on an isl_pw_aff when exported. + */ +__isl_give isl_map *isl_pw_aff_as_map(__isl_take isl_pw_aff *pa) +{ + return isl_map_from_pw_aff(pa); +} + +/* Construct a one-dimensional set with as parameter domain + * the domain of pwaff and the single set dimension + * corresponding to the affine expressions. + */ +__isl_give isl_set *isl_set_from_pw_aff(__isl_take isl_pw_aff *pwaff) +{ + if (check_input_is_set(isl_pw_aff_peek_space(pwaff)) < 0) + pwaff = isl_pw_aff_free(pwaff); + return set_from_map(isl_map_from_pw_aff_internal(pwaff)); +} + +/* Construct a map mapping the domain of the piecewise multi-affine expression + * to its range, with each dimension in the range equated to the + * corresponding affine expression on its cell. + * If "pma" lives in a set space, then the result is actually a set. + * + * If the domain of "pma" is rational, then so is the constructed "map". + */ +__isl_give isl_map *isl_map_from_pw_multi_aff_internal( + __isl_take isl_pw_multi_aff *pma) +{ + int i; + isl_map *map; + + if (!pma) + return NULL; + + map = isl_map_empty(isl_pw_multi_aff_get_space(pma)); + + for (i = 0; i < pma->n; ++i) { + isl_bool rational; + isl_multi_aff *maff; + isl_basic_map *bmap; + isl_map *map_i; + + rational = isl_set_is_rational(pma->p[i].set); + if (rational < 0) + map = isl_map_free(map); + maff = isl_multi_aff_copy(pma->p[i].maff); + bmap = isl_basic_map_from_multi_aff2(maff, rational); + map_i = isl_map_from_basic_map(bmap); + map_i = isl_map_intersect_domain(map_i, + isl_set_copy(pma->p[i].set)); + map = isl_map_union_disjoint(map, map_i); + } + + isl_pw_multi_aff_free(pma); + return map; +} + +/* Construct a map mapping the domain of the piecewise multi-affine expression + * to its range, with each dimension in the range equated to the + * corresponding affine expression on its cell. + */ +__isl_give isl_map *isl_map_from_pw_multi_aff(__isl_take isl_pw_multi_aff *pma) +{ + if (check_input_is_map(isl_pw_multi_aff_peek_space(pma)) < 0) + pma = isl_pw_multi_aff_free(pma); + return isl_map_from_pw_multi_aff_internal(pma); +} + +/* This function performs the same operation as isl_map_from_pw_multi_aff, + * but is considered as a function on an isl_pw_multi_aff when exported. + */ +__isl_give isl_map *isl_pw_multi_aff_as_map(__isl_take isl_pw_multi_aff *pma) +{ + return isl_map_from_pw_multi_aff(pma); +} + +__isl_give isl_set *isl_set_from_pw_multi_aff(__isl_take isl_pw_multi_aff *pma) +{ + if (check_input_is_set(isl_pw_multi_aff_peek_space(pma)) < 0) + pma = isl_pw_multi_aff_free(pma); + return set_from_map(isl_map_from_pw_multi_aff_internal(pma)); +} + +/* This function performs the same operation as isl_set_from_pw_multi_aff, + * but is considered as a function on an isl_pw_multi_aff when exported. + */ +__isl_give isl_set *isl_pw_multi_aff_as_set(__isl_take isl_pw_multi_aff *pma) +{ + return isl_set_from_pw_multi_aff(pma); +} + +/* Construct a set or map mapping the shared (parameter) domain + * of the piecewise affine expressions to the range of "mpa" + * with each dimension in the range equated to the + * corresponding piecewise affine expression. + * + * If "mpa" has an explicit domain (i.e., it is zero-dimensional), + * then return a set or map with the same (parameter) domain. + */ +static __isl_give isl_map *map_from_multi_pw_aff( + __isl_take isl_multi_pw_aff *mpa) +{ + int i; + isl_size dim; + isl_space *space; + isl_map *map; + + dim = isl_multi_pw_aff_dim(mpa, isl_dim_out); + if (dim < 0) + goto error; + + if (isl_space_dim(mpa->space, isl_dim_out) != mpa->n) + isl_die(isl_multi_pw_aff_get_ctx(mpa), isl_error_internal, + "invalid space", goto error); + + space = isl_multi_pw_aff_get_domain_space(mpa); + map = isl_map_universe(isl_space_from_domain(space)); + + for (i = 0; i < mpa->n; ++i) { + isl_pw_aff *pa; + isl_map *map_i; + + pa = isl_pw_aff_copy(mpa->u.p[i]); + map_i = isl_map_from_pw_aff_internal(pa); + + map = isl_map_flat_range_product(map, map_i); + } + + map = isl_map_reset_space(map, isl_multi_pw_aff_get_space(mpa)); + + map = isl_map_intersect_multi_pw_aff_explicit_domain(map, mpa); + + isl_multi_pw_aff_free(mpa); + return map; +error: + isl_multi_pw_aff_free(mpa); + return NULL; +} + +/* Construct a map mapping the shared domain + * of the piecewise affine expressions to the range of "mpa" + * with each dimension in the range equated to the + * corresponding piecewise affine expression. + */ +__isl_give isl_map *isl_map_from_multi_pw_aff(__isl_take isl_multi_pw_aff *mpa) +{ + if (check_input_is_map(isl_multi_pw_aff_peek_space(mpa)) < 0) + mpa = isl_multi_pw_aff_free(mpa); + return map_from_multi_pw_aff(mpa); +} + +/* This function performs the same operation as isl_map_from_multi_pw_aff, + * but is considered as a function on an isl_multi_pw_aff when exported. + */ +__isl_give isl_map *isl_multi_pw_aff_as_map(__isl_take isl_multi_pw_aff *mpa) +{ + return isl_map_from_multi_pw_aff(mpa); +} + +/* Construct a set mapping the shared parameter domain + * of the piecewise affine expressions to the space of "mpa" + * with each dimension in the range equated to the + * corresponding piecewise affine expression. + */ +__isl_give isl_set *isl_set_from_multi_pw_aff(__isl_take isl_multi_pw_aff *mpa) +{ + if (check_input_is_set(isl_multi_pw_aff_peek_space(mpa)) < 0) + mpa = isl_multi_pw_aff_free(mpa); + return set_from_map(map_from_multi_pw_aff(mpa)); +} + +/* This function performs the same operation as isl_set_from_multi_pw_aff, + * but is considered as a function on an isl_multi_pw_aff when exported. + */ +__isl_give isl_set *isl_multi_pw_aff_as_set(__isl_take isl_multi_pw_aff *mpa) +{ + return isl_set_from_multi_pw_aff(mpa); +} + +/* Convert "pa" to an isl_map and add it to *umap. + */ +static isl_stat map_from_pw_aff_entry(__isl_take isl_pw_aff *pa, void *user) +{ + isl_union_map **umap = user; + isl_map *map; + + map = isl_map_from_pw_aff(pa); + *umap = isl_union_map_add_map(*umap, map); + + return *umap ? isl_stat_ok : isl_stat_error; +} + +/* Construct a union map mapping the domain of the union + * piecewise affine expression to its range, with the single output dimension + * equated to the corresponding affine expressions on their cells. + */ +__isl_give isl_union_map *isl_union_map_from_union_pw_aff( + __isl_take isl_union_pw_aff *upa) +{ + isl_space *space; + isl_union_map *umap; + + if (!upa) + return NULL; + + space = isl_union_pw_aff_get_space(upa); + umap = isl_union_map_empty(space); + + if (isl_union_pw_aff_foreach_pw_aff(upa, &map_from_pw_aff_entry, + &umap) < 0) + umap = isl_union_map_free(umap); + + isl_union_pw_aff_free(upa); + return umap; +} + +/* Convert "pma" to an isl_map and add it to *umap. + */ +static isl_stat map_from_pw_multi_aff(__isl_take isl_pw_multi_aff *pma, + void *user) +{ + isl_union_map **umap = user; + isl_map *map; + + map = isl_map_from_pw_multi_aff(pma); + *umap = isl_union_map_add_map(*umap, map); + + return isl_stat_ok; +} + +/* Construct a union map mapping the domain of the union + * piecewise multi-affine expression to its range, with each dimension + * in the range equated to the corresponding affine expression on its cell. + */ +__isl_give isl_union_map *isl_union_map_from_union_pw_multi_aff( + __isl_take isl_union_pw_multi_aff *upma) +{ + isl_space *space; + isl_union_map *umap; + + if (!upma) + return NULL; + + space = isl_union_pw_multi_aff_get_space(upma); + umap = isl_union_map_empty(space); + + if (isl_union_pw_multi_aff_foreach_pw_multi_aff(upma, + &map_from_pw_multi_aff, &umap) < 0) + goto error; + + isl_union_pw_multi_aff_free(upma); + return umap; +error: + isl_union_pw_multi_aff_free(upma); + isl_union_map_free(umap); + return NULL; +} + +/* This function performs the same operation as + * isl_union_map_from_union_pw_multi_aff, + * but is considered as a function on an isl_union_pw_multi_aff when exported. + */ +__isl_give isl_union_map *isl_union_pw_multi_aff_as_union_map( + __isl_take isl_union_pw_multi_aff *upma) +{ + return isl_union_map_from_union_pw_multi_aff(upma); +} diff --git a/external/mit/isl/dist/isl_aff_private.h b/external/mit/isl/dist/isl_aff_private.h new file mode 100644 index 000000000000..eb814ea92d84 --- /dev/null +++ b/external/mit/isl/dist/isl_aff_private.h @@ -0,0 +1,242 @@ +#ifndef ISL_AFF_PRIVATE_H +#define ISL_AFF_PRIVATE_H + +#include +#include +#include +#include +#include +#include +#include + +/* ls represents the domain space. + * + * If the first two elements of "v" (the denominator and the constant term) + * are zero, then the isl_aff represents NaN. + */ +struct isl_aff { + int ref; + + isl_local_space *ls; + isl_vec *v; +}; + +#undef EL +#define EL isl_aff + +#include + +struct isl_pw_aff_piece { + struct isl_set *set; + struct isl_aff *aff; +}; + +struct isl_pw_aff { + int ref; + + isl_space *dim; + + int n; + + size_t size; + struct isl_pw_aff_piece p[1]; +}; + +#undef PW +#define PW isl_pw_aff + +#include + +#undef EL +#define EL isl_pw_aff + +#include + +struct isl_pw_multi_aff_piece { + isl_set *set; + isl_multi_aff *maff; +}; + +struct isl_pw_multi_aff { + int ref; + + isl_space *dim; + + int n; + + size_t size; + struct isl_pw_multi_aff_piece p[1]; +}; + +#undef PW +#define PW isl_pw_multi_aff + +#include + +__isl_give isl_aff *isl_aff_alloc_vec(__isl_take isl_local_space *ls, + __isl_take isl_vec *v); +__isl_give isl_aff *isl_aff_alloc(__isl_take isl_local_space *ls); + +isl_size isl_aff_domain_dim(__isl_keep isl_aff *aff, enum isl_dim_type type); +isl_size isl_aff_domain_offset(__isl_keep isl_aff *aff, enum isl_dim_type type); + +__isl_give isl_aff *isl_aff_reset_space_and_domain(__isl_take isl_aff *aff, + __isl_take isl_space *space, __isl_take isl_space *domain); +__isl_give isl_aff *isl_aff_reset_domain_space(__isl_take isl_aff *aff, + __isl_take isl_space *space); +__isl_give isl_aff *isl_aff_realign_domain(__isl_take isl_aff *aff, + __isl_take isl_reordering *r); + +__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_add_constant(__isl_take isl_aff *aff, isl_int v); + +__isl_give isl_aff *isl_aff_domain_factor_domain(__isl_take isl_aff *aff); + +int isl_aff_plain_cmp(__isl_keep isl_aff *aff1, __isl_keep isl_aff *aff2); + +__isl_give isl_aff *isl_aff_remove_unused_divs(__isl_take isl_aff *aff); +__isl_give isl_aff *isl_aff_normalize(__isl_take isl_aff *aff); + +__isl_give isl_aff *isl_aff_expand_divs( __isl_take isl_aff *aff, + __isl_take isl_mat *div, int *exp); + +__isl_give isl_aff *isl_stream_read_aff(__isl_keep isl_stream *s); + +__isl_give isl_pw_aff *isl_pw_aff_alloc_size(__isl_take isl_space *space, + int n); +__isl_give isl_pw_aff *isl_pw_aff_reset_space(__isl_take isl_pw_aff *pwaff, + __isl_take isl_space *space); +__isl_give isl_pw_aff *isl_pw_aff_reset_domain_space( + __isl_take isl_pw_aff *pwaff, __isl_take isl_space *space); +__isl_give isl_pw_aff *isl_pw_aff_add_disjoint( + __isl_take isl_pw_aff *pwaff1, __isl_take isl_pw_aff *pwaff2); + +__isl_keep isl_aff *isl_pw_aff_peek_base_at(__isl_keep isl_pw_aff *pa, int pos); + +__isl_give isl_pw_aff *isl_pw_aff_domain_factor_domain( + __isl_take isl_pw_aff *pa); + +__isl_give isl_pw_aff *isl_pw_aff_union_opt(__isl_take isl_pw_aff *pwaff1, + __isl_take isl_pw_aff *pwaff2, int max); + +__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, + isl_int f); + +__isl_give isl_pw_aff *isl_stream_read_pw_aff(__isl_keep isl_stream *s); + +isl_bool isl_aff_matching_params(__isl_keep isl_aff *aff, + __isl_keep isl_space *space); +isl_stat isl_aff_check_match_domain_space(__isl_keep isl_aff *aff, + __isl_keep isl_space *space); + +#undef BASE +#define BASE aff + +#include + +__isl_give isl_multi_aff *isl_multi_aff_dup(__isl_keep isl_multi_aff *multi); + +__isl_give isl_multi_aff *isl_multi_aff_align_divs( + __isl_take isl_multi_aff *maff); + +__isl_give isl_multi_aff *isl_multi_aff_from_basic_set_equalities( + __isl_take isl_basic_set *bset); + +__isl_give isl_multi_aff *isl_multi_aff_from_aff_mat( + __isl_take isl_space *space, __isl_take isl_mat *mat); + +#undef EL +#define EL isl_pw_multi_aff + +#include + +__isl_keep isl_multi_aff *isl_pw_multi_aff_peek_base_at( + __isl_keep isl_pw_multi_aff *pma, int pos); + +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_move_dims( + __isl_take isl_pw_multi_aff *pma, + enum isl_dim_type dst_type, unsigned dst_pos, + enum isl_dim_type src_type, unsigned src_pos, unsigned n); + +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_reset_domain_space( + __isl_take isl_pw_multi_aff *pwmaff, __isl_take isl_space *space); +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_reset_space( + __isl_take isl_pw_multi_aff *pwmaff, __isl_take isl_space *space); +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_add_disjoint( + __isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2); + +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_project_out( + __isl_take isl_pw_multi_aff *pma, + enum isl_dim_type type, unsigned first, unsigned n); + +isl_stat isl_seq_preimage(isl_int *dst, isl_int *src, + __isl_keep isl_multi_aff *ma, int n_before, int n_after, + int n_div_ma, int n_div_bmap, + isl_int f, isl_int c1, isl_int c2, isl_int g, int has_denom); + +__isl_give isl_aff *isl_aff_substitute_equalities(__isl_take isl_aff *aff, + __isl_take isl_basic_set *eq); +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_substitute( + __isl_take isl_pw_multi_aff *pma, unsigned pos, + __isl_keep isl_pw_aff *subs); + +__isl_give isl_pw_multi_aff *isl_stream_read_pw_multi_aff( + __isl_keep isl_stream *s); + +__isl_give isl_union_pw_aff *isl_stream_read_union_pw_aff( + __isl_keep isl_stream *s); + +isl_stat isl_pw_aff_check_named_params(__isl_keep isl_pw_aff *pa); +isl_stat isl_multi_aff_check_named_params(__isl_keep isl_multi_aff *ma); +isl_stat isl_pw_multi_aff_check_named_params(__isl_keep isl_pw_multi_aff *pma); + +isl_bool isl_pw_aff_matching_params(__isl_keep isl_pw_aff *pa, + __isl_keep isl_space *space); +isl_stat isl_pw_aff_check_match_domain_space(__isl_keep isl_pw_aff *pa, + __isl_keep isl_space *space); + +__isl_give isl_basic_set *isl_aff_pos_basic_set(__isl_take isl_aff *aff); + +#undef BASE +#define BASE pw_aff +#undef DOMBASE +#define DOMBASE set +#define EXPLICIT_DOMAIN + +#include + +#undef EXPLICIT_DOMAIN + +__isl_give isl_map *isl_map_intersect_multi_pw_aff_explicit_domain( + __isl_take isl_map *map, __isl_keep isl_multi_pw_aff *mpa); + +#undef EL +#define EL isl_union_pw_aff + +#include + +#undef BASE +#define BASE union_pw_aff +#undef DOMBASE +#define DOMBASE union_set +#define EXPLICIT_DOMAIN + +#include + +#undef EXPLICIT_DOMAIN + +#undef EL +#define EL isl_union_pw_multi_aff + +#include + +#endif diff --git a/external/mit/isl/dist/isl_affine_hull.c b/external/mit/isl/dist/isl_affine_hull.c new file mode 100644 index 000000000000..386250916984 --- /dev/null +++ b/external/mit/isl/dist/isl_affine_hull.c @@ -0,0 +1,1252 @@ +/* + * Copyright 2008-2009 Katholieke Universiteit Leuven + * Copyright 2010 INRIA Saclay + * Copyright 2012 Ecole Normale Superieure + * + * 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 + */ + +#include +#include +#include +#include +#include +#include +#include "isl_equalities.h" +#include "isl_sample.h" +#include "isl_tab.h" +#include +#include + +#include +#include +#include +#include + +__isl_give isl_basic_map *isl_basic_map_implicit_equalities( + __isl_take isl_basic_map *bmap) +{ + struct isl_tab *tab; + + if (!bmap) + return bmap; + + bmap = isl_basic_map_gauss(bmap, NULL); + if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_EMPTY)) + return bmap; + if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_NO_IMPLICIT)) + return bmap; + if (bmap->n_ineq <= 1) + return bmap; + + tab = isl_tab_from_basic_map(bmap, 0); + if (isl_tab_detect_implicit_equalities(tab) < 0) + goto error; + bmap = isl_basic_map_update_from_tab(bmap, tab); + isl_tab_free(tab); + bmap = isl_basic_map_gauss(bmap, NULL); + ISL_F_SET(bmap, ISL_BASIC_MAP_NO_IMPLICIT); + return bmap; +error: + isl_tab_free(tab); + isl_basic_map_free(bmap); + return NULL; +} + +__isl_give isl_basic_set *isl_basic_set_implicit_equalities( + __isl_take isl_basic_set *bset) +{ + return bset_from_bmap( + isl_basic_map_implicit_equalities(bset_to_bmap(bset))); +} + +/* Make eq[row][col] of both bmaps equal so we can add the row + * add the column to the common matrix. + * Note that because of the echelon form, the columns of row row + * after column col are zero. + */ +static void set_common_multiple( + struct isl_basic_set *bset1, struct isl_basic_set *bset2, + unsigned row, unsigned col) +{ + isl_int m, c; + + if (isl_int_eq(bset1->eq[row][col], bset2->eq[row][col])) + return; + + isl_int_init(c); + isl_int_init(m); + isl_int_lcm(m, bset1->eq[row][col], bset2->eq[row][col]); + isl_int_divexact(c, m, bset1->eq[row][col]); + isl_seq_scale(bset1->eq[row], bset1->eq[row], c, col+1); + isl_int_divexact(c, m, bset2->eq[row][col]); + isl_seq_scale(bset2->eq[row], bset2->eq[row], c, col+1); + isl_int_clear(c); + isl_int_clear(m); +} + +/* Delete a given equality, moving all the following equalities one up. + */ +static void delete_row(__isl_keep isl_basic_set *bset, unsigned row) +{ + isl_int *t; + int r; + + t = bset->eq[row]; + bset->n_eq--; + for (r = row; r < bset->n_eq; ++r) + bset->eq[r] = bset->eq[r+1]; + bset->eq[bset->n_eq] = t; +} + +/* Make first row entries in column col of bset1 identical to + * those of bset2, using the fact that entry bset1->eq[row][col]=a + * is non-zero. Initially, these elements of bset1 are all zero. + * For each row i < row, we set + * A[i] = a * A[i] + B[i][col] * A[row] + * B[i] = a * B[i] + * so that + * A[i][col] = B[i][col] = a * old(B[i][col]) + */ +static isl_stat construct_column( + __isl_keep isl_basic_set *bset1, __isl_keep isl_basic_set *bset2, + unsigned row, unsigned col) +{ + int r; + isl_int a; + isl_int b; + isl_size total; + + total = isl_basic_set_dim(bset1, isl_dim_set); + if (total < 0) + return isl_stat_error; + + isl_int_init(a); + isl_int_init(b); + for (r = 0; r < row; ++r) { + if (isl_int_is_zero(bset2->eq[r][col])) + continue; + isl_int_gcd(b, bset2->eq[r][col], bset1->eq[row][col]); + isl_int_divexact(a, bset1->eq[row][col], b); + isl_int_divexact(b, bset2->eq[r][col], b); + isl_seq_combine(bset1->eq[r], a, bset1->eq[r], + b, bset1->eq[row], 1 + total); + isl_seq_scale(bset2->eq[r], bset2->eq[r], a, 1 + total); + } + isl_int_clear(a); + isl_int_clear(b); + delete_row(bset1, row); + + return isl_stat_ok; +} + +/* Make first row entries in column col of bset1 identical to + * those of bset2, using only these entries of the two matrices. + * Let t be the last row with different entries. + * For each row i < t, we set + * A[i] = (A[t][col]-B[t][col]) * A[i] + (B[i][col]-A[i][col) * A[t] + * B[i] = (A[t][col]-B[t][col]) * B[i] + (B[i][col]-A[i][col) * B[t] + * so that + * A[i][col] = B[i][col] = old(A[t][col]*B[i][col]-A[i][col]*B[t][col]) + */ +static isl_bool transform_column( + __isl_keep isl_basic_set *bset1, __isl_keep isl_basic_set *bset2, + unsigned row, unsigned col) +{ + int i, t; + isl_int a, b, g; + isl_size total; + + for (t = row-1; t >= 0; --t) + if (isl_int_ne(bset1->eq[t][col], bset2->eq[t][col])) + break; + if (t < 0) + return isl_bool_false; + + total = isl_basic_set_dim(bset1, isl_dim_set); + if (total < 0) + return isl_bool_error; + isl_int_init(a); + isl_int_init(b); + isl_int_init(g); + isl_int_sub(b, bset1->eq[t][col], bset2->eq[t][col]); + for (i = 0; i < t; ++i) { + isl_int_sub(a, bset2->eq[i][col], bset1->eq[i][col]); + isl_int_gcd(g, a, b); + isl_int_divexact(a, a, g); + isl_int_divexact(g, b, g); + isl_seq_combine(bset1->eq[i], g, bset1->eq[i], a, bset1->eq[t], + 1 + total); + isl_seq_combine(bset2->eq[i], g, bset2->eq[i], a, bset2->eq[t], + 1 + total); + } + isl_int_clear(a); + isl_int_clear(b); + isl_int_clear(g); + delete_row(bset1, t); + delete_row(bset2, t); + return isl_bool_true; +} + +/* The implementation is based on Section 5.2 of Michael Karr, + * "Affine Relationships Among Variables of a Program", + * except that the echelon form we use starts from the last column + * and that we are dealing with integer coefficients. + */ +static __isl_give isl_basic_set *affine_hull( + __isl_take isl_basic_set *bset1, __isl_take isl_basic_set *bset2) +{ + isl_size dim; + unsigned total; + int col; + int row; + + dim = isl_basic_set_dim(bset1, isl_dim_set); + if (dim < 0 || !bset2) + goto error; + + total = 1 + dim; + + row = 0; + for (col = total-1; col >= 0; --col) { + int is_zero1 = row >= bset1->n_eq || + isl_int_is_zero(bset1->eq[row][col]); + int is_zero2 = row >= bset2->n_eq || + isl_int_is_zero(bset2->eq[row][col]); + if (!is_zero1 && !is_zero2) { + set_common_multiple(bset1, bset2, row, col); + ++row; + } else if (!is_zero1 && is_zero2) { + if (construct_column(bset1, bset2, row, col) < 0) + goto error; + } else if (is_zero1 && !is_zero2) { + if (construct_column(bset2, bset1, row, col) < 0) + goto error; + } else { + isl_bool transform; + + transform = transform_column(bset1, bset2, row, col); + if (transform < 0) + goto error; + if (transform) + --row; + } + } + isl_assert(bset1->ctx, row == bset1->n_eq, goto error); + isl_basic_set_free(bset2); + bset1 = isl_basic_set_normalize_constraints(bset1); + return bset1; +error: + isl_basic_set_free(bset1); + isl_basic_set_free(bset2); + return NULL; +} + +/* Find an integer point in the set represented by "tab" + * that lies outside of the equality "eq" e(x) = 0. + * If "up" is true, look for a point satisfying e(x) - 1 >= 0. + * Otherwise, look for a point satisfying -e(x) - 1 >= 0 (i.e., e(x) <= -1). + * The point, if found, is returned. + * If no point can be found, a zero-length vector is returned. + * + * Before solving an ILP problem, we first check if simply + * adding the normal of the constraint to one of the known + * integer points in the basic set represented by "tab" + * yields another point inside the basic set. + * + * The caller of this function ensures that the tableau is bounded or + * that tab->basis and tab->n_unbounded have been set appropriately. + */ +static __isl_give isl_vec *outside_point(struct isl_tab *tab, isl_int *eq, + int up) +{ + struct isl_ctx *ctx; + struct isl_vec *sample = NULL; + struct isl_tab_undo *snap; + unsigned dim; + + if (!tab) + return NULL; + ctx = tab->mat->ctx; + + dim = tab->n_var; + sample = isl_vec_alloc(ctx, 1 + dim); + if (!sample) + return NULL; + isl_int_set_si(sample->el[0], 1); + isl_seq_combine(sample->el + 1, + ctx->one, tab->bmap->sample->el + 1, + up ? ctx->one : ctx->negone, eq + 1, dim); + if (isl_basic_map_contains(tab->bmap, sample)) + return sample; + isl_vec_free(sample); + sample = NULL; + + snap = isl_tab_snap(tab); + + if (!up) + isl_seq_neg(eq, eq, 1 + dim); + isl_int_sub_ui(eq[0], eq[0], 1); + + if (isl_tab_extend_cons(tab, 1) < 0) + goto error; + if (isl_tab_add_ineq(tab, eq) < 0) + goto error; + + sample = isl_tab_sample(tab); + + isl_int_add_ui(eq[0], eq[0], 1); + if (!up) + isl_seq_neg(eq, eq, 1 + dim); + + if (sample && isl_tab_rollback(tab, snap) < 0) + goto error; + + return sample; +error: + isl_vec_free(sample); + return NULL; +} + +__isl_give isl_basic_set *isl_basic_set_recession_cone( + __isl_take isl_basic_set *bset) +{ + int i; + isl_bool empty; + + empty = isl_basic_set_plain_is_empty(bset); + if (empty < 0) + return isl_basic_set_free(bset); + if (empty) + return bset; + + bset = isl_basic_set_cow(bset); + if (isl_basic_set_check_no_locals(bset) < 0) + return isl_basic_set_free(bset); + + for (i = 0; i < bset->n_eq; ++i) + isl_int_set_si(bset->eq[i][0], 0); + + for (i = 0; i < bset->n_ineq; ++i) + isl_int_set_si(bset->ineq[i][0], 0); + + ISL_F_CLR(bset, ISL_BASIC_SET_NO_IMPLICIT); + return isl_basic_set_implicit_equalities(bset); +} + +/* Move "sample" to a point that is one up (or down) from the original + * point in dimension "pos". + */ +static void adjacent_point(__isl_keep isl_vec *sample, int pos, int up) +{ + if (up) + isl_int_add_ui(sample->el[1 + pos], sample->el[1 + pos], 1); + else + isl_int_sub_ui(sample->el[1 + pos], sample->el[1 + pos], 1); +} + +/* Check if any points that are adjacent to "sample" also belong to "bset". + * If so, add them to "hull" and return the updated hull. + * + * Before checking whether and adjacent point belongs to "bset", we first + * check whether it already belongs to "hull" as this test is typically + * much cheaper. + */ +static __isl_give isl_basic_set *add_adjacent_points( + __isl_take isl_basic_set *hull, __isl_take isl_vec *sample, + __isl_keep isl_basic_set *bset) +{ + int i, up; + isl_size dim; + + dim = isl_basic_set_dim(hull, isl_dim_set); + if (!sample || dim < 0) + goto error; + + for (i = 0; i < dim; ++i) { + for (up = 0; up <= 1; ++up) { + int contains; + isl_basic_set *point; + + adjacent_point(sample, i, up); + contains = isl_basic_set_contains(hull, sample); + if (contains < 0) + goto error; + if (contains) { + adjacent_point(sample, i, !up); + continue; + } + contains = isl_basic_set_contains(bset, sample); + if (contains < 0) + goto error; + if (contains) { + point = isl_basic_set_from_vec( + isl_vec_copy(sample)); + hull = affine_hull(hull, point); + } + adjacent_point(sample, i, !up); + if (contains) + break; + } + } + + isl_vec_free(sample); + + return hull; +error: + isl_vec_free(sample); + isl_basic_set_free(hull); + return NULL; +} + +/* Extend an initial (under-)approximation of the affine hull of basic + * set represented by the tableau "tab" + * by looking for points that do not satisfy one of the equalities + * in the current approximation and adding them to that approximation + * until no such points can be found any more. + * + * The caller of this function ensures that "tab" is bounded or + * that tab->basis and tab->n_unbounded have been set appropriately. + * + * "bset" may be either NULL or the basic set represented by "tab". + * If "bset" is not NULL, we check for any point we find if any + * of its adjacent points also belong to "bset". + */ +static __isl_give isl_basic_set *extend_affine_hull(struct isl_tab *tab, + __isl_take isl_basic_set *hull, __isl_keep isl_basic_set *bset) +{ + int i, j; + unsigned dim; + + if (!tab || !hull) + goto error; + + dim = tab->n_var; + + if (isl_tab_extend_cons(tab, 2 * dim + 1) < 0) + goto error; + + for (i = 0; i < dim; ++i) { + struct isl_vec *sample; + struct isl_basic_set *point; + for (j = 0; j < hull->n_eq; ++j) { + sample = outside_point(tab, hull->eq[j], 1); + if (!sample) + goto error; + if (sample->size > 0) + break; + isl_vec_free(sample); + sample = outside_point(tab, hull->eq[j], 0); + if (!sample) + goto error; + if (sample->size > 0) + break; + isl_vec_free(sample); + + if (isl_tab_add_eq(tab, hull->eq[j]) < 0) + goto error; + } + if (j == hull->n_eq) + break; + if (tab->samples && + isl_tab_add_sample(tab, isl_vec_copy(sample)) < 0) + hull = isl_basic_set_free(hull); + if (bset) + hull = add_adjacent_points(hull, isl_vec_copy(sample), + bset); + point = isl_basic_set_from_vec(sample); + hull = affine_hull(hull, point); + if (!hull) + return NULL; + } + + return hull; +error: + isl_basic_set_free(hull); + return NULL; +} + +/* Construct an initial underapproximation of the hull of "bset" + * from "sample" and any of its adjacent points that also belong to "bset". + */ +static __isl_give isl_basic_set *initialize_hull(__isl_keep isl_basic_set *bset, + __isl_take isl_vec *sample) +{ + isl_basic_set *hull; + + hull = isl_basic_set_from_vec(isl_vec_copy(sample)); + hull = add_adjacent_points(hull, sample, bset); + + return hull; +} + +/* Look for all equalities satisfied by the integer points in bset, + * which is assumed to be bounded. + * + * The equalities are obtained by successively looking for + * a point that is affinely independent of the points found so far. + * In particular, for each equality satisfied by the points so far, + * we check if there is any point on a hyperplane parallel to the + * corresponding hyperplane shifted by at least one (in either direction). + */ +static __isl_give isl_basic_set *uset_affine_hull_bounded( + __isl_take isl_basic_set *bset) +{ + struct isl_vec *sample = NULL; + struct isl_basic_set *hull; + struct isl_tab *tab = NULL; + isl_size dim; + + if (isl_basic_set_plain_is_empty(bset)) + return bset; + + dim = isl_basic_set_dim(bset, isl_dim_set); + if (dim < 0) + return isl_basic_set_free(bset); + + if (bset->sample && bset->sample->size == 1 + dim) { + int contains = isl_basic_set_contains(bset, bset->sample); + if (contains < 0) + goto error; + if (contains) { + if (dim == 0) + return bset; + sample = isl_vec_copy(bset->sample); + } else { + isl_vec_free(bset->sample); + bset->sample = NULL; + } + } + + tab = isl_tab_from_basic_set(bset, 1); + if (!tab) + goto error; + if (tab->empty) { + isl_tab_free(tab); + isl_vec_free(sample); + return isl_basic_set_set_to_empty(bset); + } + + if (!sample) { + struct isl_tab_undo *snap; + snap = isl_tab_snap(tab); + sample = isl_tab_sample(tab); + if (isl_tab_rollback(tab, snap) < 0) + goto error; + isl_vec_free(tab->bmap->sample); + tab->bmap->sample = isl_vec_copy(sample); + } + + if (!sample) + goto error; + if (sample->size == 0) { + isl_tab_free(tab); + isl_vec_free(sample); + return isl_basic_set_set_to_empty(bset); + } + + hull = initialize_hull(bset, sample); + + hull = extend_affine_hull(tab, hull, bset); + isl_basic_set_free(bset); + isl_tab_free(tab); + + return hull; +error: + isl_vec_free(sample); + isl_tab_free(tab); + isl_basic_set_free(bset); + return NULL; +} + +/* Given an unbounded tableau and an integer point satisfying the tableau, + * construct an initial affine hull containing the recession cone + * shifted to the given point. + * + * The unbounded directions are taken from the last rows of the basis, + * which is assumed to have been initialized appropriately. + */ +static __isl_give isl_basic_set *initial_hull(struct isl_tab *tab, + __isl_take isl_vec *vec) +{ + int i; + int k; + struct isl_basic_set *bset = NULL; + struct isl_ctx *ctx; + isl_size dim; + + if (!vec || !tab) + return NULL; + ctx = vec->ctx; + isl_assert(ctx, vec->size != 0, goto error); + + bset = isl_basic_set_alloc(ctx, 0, vec->size - 1, 0, vec->size - 1, 0); + dim = isl_basic_set_dim(bset, isl_dim_set); + if (dim < 0) + goto error; + dim -= tab->n_unbounded; + for (i = 0; i < dim; ++i) { + k = isl_basic_set_alloc_equality(bset); + if (k < 0) + goto error; + isl_seq_cpy(bset->eq[k] + 1, tab->basis->row[1 + i] + 1, + vec->size - 1); + isl_seq_inner_product(bset->eq[k] + 1, vec->el +1, + vec->size - 1, &bset->eq[k][0]); + isl_int_neg(bset->eq[k][0], bset->eq[k][0]); + } + bset->sample = vec; + bset = isl_basic_set_gauss(bset, NULL); + + return bset; +error: + isl_basic_set_free(bset); + isl_vec_free(vec); + return NULL; +} + +/* Given a tableau of a set and a tableau of the corresponding + * recession cone, detect and add all equalities to the tableau. + * If the tableau is bounded, then we can simply keep the + * tableau in its state after the return from extend_affine_hull. + * However, if the tableau is unbounded, then + * isl_tab_set_initial_basis_with_cone will add some additional + * constraints to the tableau that have to be removed again. + * In this case, we therefore rollback to the state before + * any constraints were added and then add the equalities back in. + */ +struct isl_tab *isl_tab_detect_equalities(struct isl_tab *tab, + struct isl_tab *tab_cone) +{ + int j; + struct isl_vec *sample; + struct isl_basic_set *hull = NULL; + struct isl_tab_undo *snap; + + if (!tab || !tab_cone) + goto error; + + snap = isl_tab_snap(tab); + + isl_mat_free(tab->basis); + tab->basis = NULL; + + isl_assert(tab->mat->ctx, tab->bmap, goto error); + isl_assert(tab->mat->ctx, tab->samples, goto error); + isl_assert(tab->mat->ctx, tab->samples->n_col == 1 + tab->n_var, goto error); + isl_assert(tab->mat->ctx, tab->n_sample > tab->n_outside, goto error); + + if (isl_tab_set_initial_basis_with_cone(tab, tab_cone) < 0) + goto error; + + sample = isl_vec_alloc(tab->mat->ctx, 1 + tab->n_var); + if (!sample) + goto error; + + isl_seq_cpy(sample->el, tab->samples->row[tab->n_outside], sample->size); + + isl_vec_free(tab->bmap->sample); + tab->bmap->sample = isl_vec_copy(sample); + + if (tab->n_unbounded == 0) + hull = isl_basic_set_from_vec(isl_vec_copy(sample)); + else + hull = initial_hull(tab, isl_vec_copy(sample)); + + for (j = tab->n_outside + 1; j < tab->n_sample; ++j) { + isl_seq_cpy(sample->el, tab->samples->row[j], sample->size); + hull = affine_hull(hull, + isl_basic_set_from_vec(isl_vec_copy(sample))); + } + + isl_vec_free(sample); + + hull = extend_affine_hull(tab, hull, NULL); + if (!hull) + goto error; + + if (tab->n_unbounded == 0) { + isl_basic_set_free(hull); + return tab; + } + + if (isl_tab_rollback(tab, snap) < 0) + goto error; + + if (hull->n_eq > tab->n_zero) { + for (j = 0; j < hull->n_eq; ++j) { + isl_seq_normalize(tab->mat->ctx, hull->eq[j], 1 + tab->n_var); + if (isl_tab_add_eq(tab, hull->eq[j]) < 0) + goto error; + } + } + + isl_basic_set_free(hull); + + return tab; +error: + isl_basic_set_free(hull); + isl_tab_free(tab); + return NULL; +} + +/* Compute the affine hull of "bset", where "cone" is the recession cone + * of "bset". + * + * We first compute a unimodular transformation that puts the unbounded + * directions in the last dimensions. In particular, we take a transformation + * that maps all equalities to equalities (in HNF) on the first dimensions. + * Let x be the original dimensions and y the transformed, with y_1 bounded + * and y_2 unbounded. + * + * [ y_1 ] [ y_1 ] [ Q_1 ] + * x = U [ y_2 ] [ y_2 ] = [ Q_2 ] x + * + * Let's call the input basic set S. We compute S' = preimage(S, U) + * and drop the final dimensions including any constraints involving them. + * This results in set S''. + * Then we compute the affine hull A'' of S''. + * Let F y_1 >= g be the constraint system of A''. In the transformed + * space the y_2 are unbounded, so we can add them back without any constraints, + * resulting in + * + * [ y_1 ] + * [ F 0 ] [ y_2 ] >= g + * or + * [ Q_1 ] + * [ F 0 ] [ Q_2 ] x >= g + * or + * F Q_1 x >= g + * + * The affine hull in the original space is then obtained as + * A = preimage(A'', Q_1). + */ +static __isl_give isl_basic_set *affine_hull_with_cone( + __isl_take isl_basic_set *bset, __isl_take isl_basic_set *cone) +{ + isl_size total; + unsigned cone_dim; + struct isl_basic_set *hull; + struct isl_mat *M, *U, *Q; + + total = isl_basic_set_dim(cone, isl_dim_all); + if (!bset || total < 0) + goto error; + + cone_dim = total - cone->n_eq; + + M = isl_mat_sub_alloc6(bset->ctx, cone->eq, 0, cone->n_eq, 1, total); + M = isl_mat_left_hermite(M, 0, &U, &Q); + if (!M) + goto error; + isl_mat_free(M); + + U = isl_mat_lin_to_aff(U); + bset = isl_basic_set_preimage(bset, isl_mat_copy(U)); + + bset = isl_basic_set_drop_constraints_involving(bset, total - cone_dim, + cone_dim); + bset = isl_basic_set_drop_dims(bset, total - cone_dim, cone_dim); + + Q = isl_mat_lin_to_aff(Q); + Q = isl_mat_drop_rows(Q, 1 + total - cone_dim, cone_dim); + + if (bset && bset->sample && bset->sample->size == 1 + total) + bset->sample = isl_mat_vec_product(isl_mat_copy(Q), bset->sample); + + hull = uset_affine_hull_bounded(bset); + + if (!hull) { + isl_mat_free(Q); + isl_mat_free(U); + } else { + struct isl_vec *sample = isl_vec_copy(hull->sample); + U = isl_mat_drop_cols(U, 1 + total - cone_dim, cone_dim); + if (sample && sample->size > 0) + sample = isl_mat_vec_product(U, sample); + else + isl_mat_free(U); + hull = isl_basic_set_preimage(hull, Q); + if (hull) { + isl_vec_free(hull->sample); + hull->sample = sample; + } else + isl_vec_free(sample); + } + + isl_basic_set_free(cone); + + return hull; +error: + isl_basic_set_free(bset); + isl_basic_set_free(cone); + return NULL; +} + +/* Look for all equalities satisfied by the integer points in bset, + * which is assumed not to have any explicit equalities. + * + * The equalities are obtained by successively looking for + * a point that is affinely independent of the points found so far. + * In particular, for each equality satisfied by the points so far, + * we check if there is any point on a hyperplane parallel to the + * corresponding hyperplane shifted by at least one (in either direction). + * + * Before looking for any outside points, we first compute the recession + * cone. The directions of this recession cone will always be part + * of the affine hull, so there is no need for looking for any points + * in these directions. + * In particular, if the recession cone is full-dimensional, then + * the affine hull is simply the whole universe. + */ +static __isl_give isl_basic_set *uset_affine_hull( + __isl_take isl_basic_set *bset) +{ + struct isl_basic_set *cone; + isl_size total; + + if (isl_basic_set_plain_is_empty(bset)) + return bset; + + cone = isl_basic_set_recession_cone(isl_basic_set_copy(bset)); + if (!cone) + goto error; + if (cone->n_eq == 0) { + isl_space *space; + space = isl_basic_set_get_space(bset); + isl_basic_set_free(cone); + isl_basic_set_free(bset); + return isl_basic_set_universe(space); + } + + total = isl_basic_set_dim(cone, isl_dim_all); + if (total < 0) + bset = isl_basic_set_free(bset); + if (cone->n_eq < total) + return affine_hull_with_cone(bset, cone); + + isl_basic_set_free(cone); + return uset_affine_hull_bounded(bset); +error: + isl_basic_set_free(bset); + return NULL; +} + +/* Look for all equalities satisfied by the integer points in bmap + * that are independent of the equalities already explicitly available + * in bmap. + * + * We first remove all equalities already explicitly available, + * then look for additional equalities in the reduced space + * and then transform the result to the original space. + * The original equalities are _not_ added to this set. This is + * the responsibility of the calling function. + * The resulting basic set has all meaning about the dimensions removed. + * In particular, dimensions that correspond to existential variables + * in bmap and that are found to be fixed are not removed. + */ +static __isl_give isl_basic_set *equalities_in_underlying_set( + __isl_take isl_basic_map *bmap) +{ + struct isl_mat *T1 = NULL; + struct isl_mat *T2 = NULL; + struct isl_basic_set *bset = NULL; + struct isl_basic_set *hull = NULL; + + bset = isl_basic_map_underlying_set(bmap); + if (!bset) + return NULL; + if (bset->n_eq) + bset = isl_basic_set_remove_equalities(bset, &T1, &T2); + if (!bset) + goto error; + + hull = uset_affine_hull(bset); + if (!T2) + return hull; + + if (!hull) { + isl_mat_free(T1); + isl_mat_free(T2); + } else { + struct isl_vec *sample = isl_vec_copy(hull->sample); + if (sample && sample->size > 0) + sample = isl_mat_vec_product(T1, sample); + else + isl_mat_free(T1); + hull = isl_basic_set_preimage(hull, T2); + if (hull) { + isl_vec_free(hull->sample); + hull->sample = sample; + } else + isl_vec_free(sample); + } + + return hull; +error: + isl_mat_free(T1); + isl_mat_free(T2); + isl_basic_set_free(bset); + isl_basic_set_free(hull); + return NULL; +} + +/* Detect and make explicit all equalities satisfied by the (integer) + * points in bmap. + */ +__isl_give isl_basic_map *isl_basic_map_detect_equalities( + __isl_take isl_basic_map *bmap) +{ + int i, j; + isl_size total; + struct isl_basic_set *hull = NULL; + + if (!bmap) + return NULL; + if (bmap->n_ineq == 0) + return bmap; + if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_EMPTY)) + return bmap; + if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_ALL_EQUALITIES)) + return bmap; + if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_RATIONAL)) + return isl_basic_map_implicit_equalities(bmap); + + hull = equalities_in_underlying_set(isl_basic_map_copy(bmap)); + if (!hull) + goto error; + if (ISL_F_ISSET(hull, ISL_BASIC_SET_EMPTY)) { + isl_basic_set_free(hull); + return isl_basic_map_set_to_empty(bmap); + } + bmap = isl_basic_map_extend(bmap, 0, hull->n_eq, 0); + total = isl_basic_set_dim(hull, isl_dim_all); + if (total < 0) + goto error; + for (i = 0; i < hull->n_eq; ++i) { + j = isl_basic_map_alloc_equality(bmap); + if (j < 0) + goto error; + isl_seq_cpy(bmap->eq[j], hull->eq[i], 1 + total); + } + isl_vec_free(bmap->sample); + bmap->sample = isl_vec_copy(hull->sample); + isl_basic_set_free(hull); + ISL_F_SET(bmap, ISL_BASIC_MAP_NO_IMPLICIT | ISL_BASIC_MAP_ALL_EQUALITIES); + bmap = isl_basic_map_simplify(bmap); + return isl_basic_map_finalize(bmap); +error: + isl_basic_set_free(hull); + isl_basic_map_free(bmap); + return NULL; +} + +__isl_give isl_basic_set *isl_basic_set_detect_equalities( + __isl_take isl_basic_set *bset) +{ + return bset_from_bmap( + isl_basic_map_detect_equalities(bset_to_bmap(bset))); +} + +__isl_give isl_map *isl_map_detect_equalities(__isl_take isl_map *map) +{ + return isl_map_inline_foreach_basic_map(map, + &isl_basic_map_detect_equalities); +} + +__isl_give isl_set *isl_set_detect_equalities(__isl_take isl_set *set) +{ + return set_from_map(isl_map_detect_equalities(set_to_map(set))); +} + +/* Return the superset of "bmap" described by the equalities + * satisfied by "bmap" that are already known. + */ +__isl_give isl_basic_map *isl_basic_map_plain_affine_hull( + __isl_take isl_basic_map *bmap) +{ + bmap = isl_basic_map_cow(bmap); + if (bmap) + isl_basic_map_free_inequality(bmap, bmap->n_ineq); + bmap = isl_basic_map_finalize(bmap); + return bmap; +} + +/* Return the superset of "bset" described by the equalities + * satisfied by "bset" that are already known. + */ +__isl_give isl_basic_set *isl_basic_set_plain_affine_hull( + __isl_take isl_basic_set *bset) +{ + return isl_basic_map_plain_affine_hull(bset); +} + +/* After computing the rational affine hull (by detecting the implicit + * equalities), we compute the additional equalities satisfied by + * the integer points (if any) and add the original equalities back in. + */ +__isl_give isl_basic_map *isl_basic_map_affine_hull( + __isl_take isl_basic_map *bmap) +{ + bmap = isl_basic_map_detect_equalities(bmap); + bmap = isl_basic_map_plain_affine_hull(bmap); + return bmap; +} + +__isl_give isl_basic_set *isl_basic_set_affine_hull( + __isl_take isl_basic_set *bset) +{ + return bset_from_bmap(isl_basic_map_affine_hull(bset_to_bmap(bset))); +} + +/* Given a rational affine matrix "M", add stride constraints to "bmap" + * that ensure that + * + * M(x) + * + * is an integer vector. The variables x include all the variables + * of "bmap" except the unknown divs. + * + * If d is the common denominator of M, then we need to impose that + * + * d M(x) = 0 mod d + * + * or + * + * exists alpha : d M(x) = d alpha + * + * This function is similar to add_strides in isl_morph.c + */ +static __isl_give isl_basic_map *add_strides(__isl_take isl_basic_map *bmap, + __isl_keep isl_mat *M, int n_known) +{ + int i, div, k; + isl_int gcd; + + if (isl_int_is_one(M->row[0][0])) + return bmap; + + bmap = isl_basic_map_extend(bmap, M->n_row - 1, M->n_row - 1, 0); + + isl_int_init(gcd); + for (i = 1; i < M->n_row; ++i) { + isl_seq_gcd(M->row[i], M->n_col, &gcd); + if (isl_int_is_divisible_by(gcd, M->row[0][0])) + continue; + div = isl_basic_map_alloc_div(bmap); + if (div < 0) + goto error; + isl_int_set_si(bmap->div[div][0], 0); + k = isl_basic_map_alloc_equality(bmap); + if (k < 0) + goto error; + isl_seq_cpy(bmap->eq[k], M->row[i], M->n_col); + isl_seq_clr(bmap->eq[k] + M->n_col, bmap->n_div - n_known); + isl_int_set(bmap->eq[k][M->n_col - n_known + div], + M->row[0][0]); + } + isl_int_clear(gcd); + + return bmap; +error: + isl_int_clear(gcd); + isl_basic_map_free(bmap); + return NULL; +} + +/* If there are any equalities that involve (multiple) unknown divs, + * then extract the stride information encoded by those equalities + * and make it explicitly available in "bmap". + * + * We first sort the divs so that the unknown divs appear last and + * then we count how many equalities involve these divs. + * + * Let these equalities be of the form + * + * A(x) + B y = 0 + * + * where y represents the unknown divs and x the remaining variables. + * Let [H 0] be the Hermite Normal Form of B, i.e., + * + * B = [H 0] Q + * + * Then x is a solution of the equalities iff + * + * H^-1 A(x) (= - [I 0] Q y) + * + * is an integer vector. Let d be the common denominator of H^-1. + * We impose + * + * d H^-1 A(x) = d alpha + * + * in add_strides, with alpha fresh existentially quantified variables. + */ +static __isl_give isl_basic_map *isl_basic_map_make_strides_explicit( + __isl_take isl_basic_map *bmap) +{ + isl_bool known; + int n_known; + int n, n_col; + isl_size v_div; + isl_ctx *ctx; + isl_mat *A, *B, *M; + + known = isl_basic_map_divs_known(bmap); + if (known < 0) + return isl_basic_map_free(bmap); + if (known) + return bmap; + bmap = isl_basic_map_sort_divs(bmap); + bmap = isl_basic_map_gauss(bmap, NULL); + if (!bmap) + return NULL; + + for (n_known = 0; n_known < bmap->n_div; ++n_known) + if (isl_int_is_zero(bmap->div[n_known][0])) + break; + v_div = isl_basic_map_var_offset(bmap, isl_dim_div); + if (v_div < 0) + return isl_basic_map_free(bmap); + for (n = 0; n < bmap->n_eq; ++n) + if (isl_seq_first_non_zero(bmap->eq[n] + 1 + v_div + n_known, + bmap->n_div - n_known) == -1) + break; + if (n == 0) + return bmap; + ctx = isl_basic_map_get_ctx(bmap); + B = isl_mat_sub_alloc6(ctx, bmap->eq, 0, n, 0, 1 + v_div + n_known); + n_col = bmap->n_div - n_known; + A = isl_mat_sub_alloc6(ctx, bmap->eq, 0, n, 1 + v_div + n_known, n_col); + A = isl_mat_left_hermite(A, 0, NULL, NULL); + A = isl_mat_drop_cols(A, n, n_col - n); + A = isl_mat_lin_to_aff(A); + A = isl_mat_right_inverse(A); + B = isl_mat_insert_zero_rows(B, 0, 1); + B = isl_mat_set_element_si(B, 0, 0, 1); + M = isl_mat_product(A, B); + if (!M) + return isl_basic_map_free(bmap); + bmap = add_strides(bmap, M, n_known); + bmap = isl_basic_map_gauss(bmap, NULL); + isl_mat_free(M); + + return bmap; +} + +/* Compute the affine hull of each basic map in "map" separately + * and make all stride information explicit so that we can remove + * all unknown divs without losing this information. + * The result is also guaranteed to be gaussed. + * + * In simple cases where a div is determined by an equality, + * calling isl_basic_map_gauss is enough to make the stride information + * explicit, as it will derive an explicit representation for the div + * from the equality. If, however, the stride information + * is encoded through multiple unknown divs then we need to make + * some extra effort in isl_basic_map_make_strides_explicit. + */ +static __isl_give isl_map *isl_map_local_affine_hull(__isl_take isl_map *map) +{ + int i; + + map = isl_map_cow(map); + if (!map) + return NULL; + + for (i = 0; i < map->n; ++i) { + map->p[i] = isl_basic_map_affine_hull(map->p[i]); + map->p[i] = isl_basic_map_gauss(map->p[i], NULL); + map->p[i] = isl_basic_map_make_strides_explicit(map->p[i]); + if (!map->p[i]) + return isl_map_free(map); + } + + return map; +} + +static __isl_give isl_set *isl_set_local_affine_hull(__isl_take isl_set *set) +{ + return isl_map_local_affine_hull(set); +} + +/* Return an empty basic map living in the same space as "map". + */ +static __isl_give isl_basic_map *replace_map_by_empty_basic_map( + __isl_take isl_map *map) +{ + isl_space *space; + + space = isl_map_get_space(map); + isl_map_free(map); + return isl_basic_map_empty(space); +} + +/* Compute the affine hull of "map". + * + * We first compute the affine hull of each basic map separately. + * Then we align the divs and recompute the affine hulls of the basic + * maps since some of them may now have extra divs. + * In order to avoid performing parametric integer programming to + * compute explicit expressions for the divs, possible leading to + * an explosion in the number of basic maps, we first drop all unknown + * divs before aligning the divs. Note that isl_map_local_affine_hull tries + * to make sure that all stride information is explicitly available + * in terms of known divs. This involves calling isl_basic_set_gauss, + * which is also needed because affine_hull assumes its input has been gaussed, + * while isl_map_affine_hull may be called on input that has not been gaussed, + * in particular from initial_facet_constraint. + * Similarly, align_divs may reorder some divs so that we need to + * gauss the result again. + * Finally, we combine the individual affine hulls into a single + * affine hull. + */ +__isl_give isl_basic_map *isl_map_affine_hull(__isl_take isl_map *map) +{ + struct isl_basic_map *model = NULL; + struct isl_basic_map *hull = NULL; + struct isl_set *set; + isl_basic_set *bset; + + map = isl_map_detect_equalities(map); + map = isl_map_local_affine_hull(map); + map = isl_map_remove_empty_parts(map); + map = isl_map_remove_unknown_divs(map); + map = isl_map_align_divs_internal(map); + + if (!map) + return NULL; + + if (map->n == 0) + return replace_map_by_empty_basic_map(map); + + model = isl_basic_map_copy(map->p[0]); + set = isl_map_underlying_set(map); + set = isl_set_cow(set); + set = isl_set_local_affine_hull(set); + if (!set) + goto error; + + while (set->n > 1) + set->p[0] = affine_hull(set->p[0], set->p[--set->n]); + + bset = isl_basic_set_copy(set->p[0]); + hull = isl_basic_map_overlying_set(bset, model); + isl_set_free(set); + hull = isl_basic_map_simplify(hull); + return isl_basic_map_finalize(hull); +error: + isl_basic_map_free(model); + isl_set_free(set); + return NULL; +} + +__isl_give isl_basic_set *isl_set_affine_hull(__isl_take isl_set *set) +{ + return bset_from_bmap(isl_map_affine_hull(set_to_map(set))); +} diff --git a/external/mit/isl/dist/isl_align_params_bin_templ.c b/external/mit/isl/dist/isl_align_params_bin_templ.c new file mode 100644 index 000000000000..eae8d4d7fd0c --- /dev/null +++ b/external/mit/isl/dist/isl_align_params_bin_templ.c @@ -0,0 +1,8 @@ +#undef ARG1 +#define ARG1 TYPE +#undef ARG2 +#define ARG2 TYPE +#undef SUFFIX +#define SUFFIX bin + +#include "isl_align_params_templ.c" diff --git a/external/mit/isl/dist/isl_align_params_templ.c b/external/mit/isl/dist/isl_align_params_templ.c new file mode 100644 index 000000000000..f56df4956646 --- /dev/null +++ b/external/mit/isl/dist/isl_align_params_templ.c @@ -0,0 +1,40 @@ +/* + * Copyright 2011 Sven Verdoolaege + * + * Use of this software is governed by the MIT license + * + * Written by Sven Verdoolaege + */ + +#define xFN(TYPE,NAME) TYPE ## _ ## NAME +#define FN(TYPE,NAME) xFN(TYPE,NAME) + +/* Align the parameters of the two arguments of type ARG1 and ARG2 + * (if needed). + */ +isl_stat FN(FN(ARG1,align_params),SUFFIX)(__isl_keep ARG1 **obj1, + __isl_keep ARG2 **obj2) +{ + isl_space *space1, *space2; + isl_bool equal_params; + + space1 = FN(ARG1,peek_space)(*obj1); + space2 = FN(ARG2,peek_space)(*obj2); + equal_params = isl_space_has_equal_params(space1, space2); + if (equal_params < 0) + goto error; + if (equal_params) + return isl_stat_ok; + if (FN(ARG1,check_named_params)(*obj1) < 0 || + FN(ARG2,check_named_params)(*obj2) < 0) + goto error; + *obj1 = FN(ARG1,align_params)(*obj1, FN(ARG2,get_space)(*obj2)); + *obj2 = FN(ARG2,align_params)(*obj2, FN(ARG1,get_space)(*obj1)); + if (!*obj1 || !*obj2) + goto error; + return isl_stat_ok; +error: + *obj1 = FN(ARG1,free)(*obj1); + *obj2 = FN(ARG2,free)(*obj2); + return isl_stat_error; +} diff --git a/external/mit/isl/dist/isl_arg.c b/external/mit/isl/dist/isl_arg.c new file mode 100644 index 000000000000..8a9e26d1c62e --- /dev/null +++ b/external/mit/isl/dist/isl_arg.c @@ -0,0 +1,1312 @@ +/* + * 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 + */ + +#include +#include +#include + +#include +#include +#include + +static struct isl_arg help_arg[] = { +ISL_ARG_PHANTOM_BOOL('h', "help", NULL, "print this help, then exit") +{ isl_arg_end } +}; + +static void set_default_choice(struct isl_arg *arg, void *opt) +{ + if (arg->offset == ISL_ARG_OFFSET_NONE) + return; + *(unsigned *)(((char *)opt) + arg->offset) = arg->u.choice.default_value; +} + +static void set_default_flags(struct isl_arg *arg, void *opt) +{ + *(unsigned *)(((char *)opt) + arg->offset) = arg->u.flags.default_value; +} + +static void set_default_bool(struct isl_arg *arg, void *opt) +{ + if (arg->offset == ISL_ARG_OFFSET_NONE) + return; + *(unsigned *)(((char *)opt) + arg->offset) = arg->u.b.default_value; +} + +static void set_default_child(struct isl_arg *arg, void *opt) +{ + void *child; + + if (arg->offset == ISL_ARG_OFFSET_NONE) + child = opt; + else { + child = calloc(1, arg->u.child.child->options_size); + *(void **)(((char *)opt) + arg->offset) = child; + } + + if (child) + isl_args_set_defaults(arg->u.child.child, child); +} + +static void set_default_user(struct isl_arg *arg, void *opt) +{ + arg->u.user.init(((char *)opt) + arg->offset); +} + +static void set_default_int(struct isl_arg *arg, void *opt) +{ + *(int *)(((char *)opt) + arg->offset) = arg->u.i.default_value; +} + +static void set_default_long(struct isl_arg *arg, void *opt) +{ + *(long *)(((char *)opt) + arg->offset) = arg->u.l.default_value; +} + +static void set_default_ulong(struct isl_arg *arg, void *opt) +{ + *(unsigned long *)(((char *)opt) + arg->offset) = arg->u.ul.default_value; +} + +static void set_default_str(struct isl_arg *arg, void *opt) +{ + const char *str = NULL; + if (arg->u.str.default_value) + str = strdup(arg->u.str.default_value); + *(const char **)(((char *)opt) + arg->offset) = str; +} + +static void set_default_str_list(struct isl_arg *arg, void *opt) +{ + *(const char ***)(((char *) opt) + arg->offset) = NULL; + *(int *)(((char *) opt) + arg->u.str_list.offset_n) = 0; +} + +void isl_args_set_defaults(struct isl_args *args, void *opt) +{ + int i; + + for (i = 0; args->args[i].type != isl_arg_end; ++i) { + switch (args->args[i].type) { + case isl_arg_choice: + set_default_choice(&args->args[i], opt); + break; + case isl_arg_flags: + set_default_flags(&args->args[i], opt); + break; + case isl_arg_bool: + set_default_bool(&args->args[i], opt); + break; + case isl_arg_child: + set_default_child(&args->args[i], opt); + break; + case isl_arg_user: + set_default_user(&args->args[i], opt); + break; + case isl_arg_int: + set_default_int(&args->args[i], opt); + break; + case isl_arg_long: + set_default_long(&args->args[i], opt); + break; + case isl_arg_ulong: + set_default_ulong(&args->args[i], opt); + break; + case isl_arg_arg: + case isl_arg_str: + set_default_str(&args->args[i], opt); + break; + case isl_arg_str_list: + set_default_str_list(&args->args[i], opt); + break; + case isl_arg_alias: + case isl_arg_footer: + case isl_arg_version: + case isl_arg_end: + break; + } + } +} + +static void free_args(struct isl_arg *arg, void *opt); + +static void free_child(struct isl_arg *arg, void *opt) +{ + if (arg->offset == ISL_ARG_OFFSET_NONE) + free_args(arg->u.child.child->args, opt); + else + isl_args_free(arg->u.child.child, + *(void **)(((char *)opt) + arg->offset)); +} + +static void free_str_list(struct isl_arg *arg, void *opt) +{ + int i; + int n = *(int *)(((char *) opt) + arg->u.str_list.offset_n); + char **list = *(char ***)(((char *) opt) + arg->offset); + + for (i = 0; i < n; ++i) + free(list[i]); + free(list); +} + +static void free_user(struct isl_arg *arg, void *opt) +{ + if (arg->u.user.clear) + arg->u.user.clear(((char *)opt) + arg->offset); +} + +static void free_args(struct isl_arg *arg, void *opt) +{ + int i; + + for (i = 0; arg[i].type != isl_arg_end; ++i) { + switch (arg[i].type) { + case isl_arg_child: + free_child(&arg[i], opt); + break; + case isl_arg_arg: + case isl_arg_str: + free(*(char **)(((char *)opt) + arg[i].offset)); + break; + case isl_arg_str_list: + free_str_list(&arg[i], opt); + break; + case isl_arg_user: + free_user(&arg[i], opt); + break; + case isl_arg_alias: + case isl_arg_bool: + case isl_arg_choice: + case isl_arg_flags: + case isl_arg_int: + case isl_arg_long: + case isl_arg_ulong: + case isl_arg_version: + case isl_arg_footer: + case isl_arg_end: + break; + } + } +} + +void isl_args_free(struct isl_args *args, void *opt) +{ + if (!opt) + return; + + free_args(args->args, opt); + + free(opt); +} + +/* Data structure for collecting the prefixes of ancestor nodes. + * + * n is the number of prefixes. + * prefix[i] for i < n is a prefix of an ancestor. + * len[i] for i < n is the length of prefix[i]. + */ +struct isl_prefixes { + int n; + const char *prefix[10]; + size_t len[10]; +}; + +/* Add "prefix" to the list of prefixes and return the updated + * number of prefixes. + */ +static int add_prefix(struct isl_prefixes *prefixes, const char *prefix) +{ + int n = prefixes->n; + + if (!prefix) + return n; + + if (prefixes->n >= 10) { + fprintf(stderr, "too many prefixes\n"); + exit(EXIT_FAILURE); + } + prefixes->len[prefixes->n] = strlen(prefix); + prefixes->prefix[prefixes->n] = prefix; + prefixes->n++; + + return n; +} + +/* Drop all prefixes starting at "first". + */ +static void drop_prefix(struct isl_prefixes *prefixes, int first) +{ + prefixes->n = first; +} + +/* Print the prefixes in "prefixes". + */ +static int print_prefixes(struct isl_prefixes *prefixes) +{ + int i; + int len = 0; + + if (!prefixes) + return 0; + + for (i = 0; i < prefixes->n; ++i) { + printf("%s-", prefixes->prefix[i]); + len += strlen(prefixes->prefix[i]) + 1; + } + + return len; +} + +/* Check if "name" starts with one or more of the prefixes in "prefixes", + * starting at *first. If so, advance the pointer beyond the prefixes + * and return the updated pointer. Additionally, update *first to + * the index after the last prefix found. + */ +static const char *skip_prefixes(const char *name, + struct isl_prefixes *prefixes, int *first) +{ + int i; + + for (i = first ? *first : 0; i < prefixes->n; ++i) { + size_t len = prefixes->len[i]; + const char *prefix = prefixes->prefix[i]; + if (strncmp(name, prefix, len) == 0 && name[len] == '-') { + name += len + 1; + if (first) + *first = i + 1; + } + } + + return name; +} + +static int print_arg_help(struct isl_arg *decl, struct isl_prefixes *prefixes, + int no) +{ + int len = 0; + + if (!decl->long_name) { + printf(" -%c", decl->short_name); + return 4; + } + + if (decl->short_name) { + printf(" -%c, --", decl->short_name); + len += 8; + } else if (decl->flags & ISL_ARG_SINGLE_DASH) { + printf(" -"); + len += 3; + } else { + printf(" --"); + len += 8; + } + + if (no) { + printf("no-"); + len += 3; + } + len += print_prefixes(prefixes); + printf("%s", decl->long_name); + len += strlen(decl->long_name); + + while ((++decl)->type == isl_arg_alias) { + printf(", --"); + len += 4; + if (no) { + printf("no-"); + len += 3; + } + printf("%s", decl->long_name); + len += strlen(decl->long_name); + } + + return len; +} + +const void *isl_memrchr(const void *s, int c, size_t n) +{ + const char *p = s; + while (n-- > 0) + if (p[n] == c) + return p + n; + return NULL; +} + +static int wrap_msg(const char *s, int indent, int pos) +{ + int len; + int wrap_len = 75 - indent; + + if (pos + 1 >= indent) + printf("\n%*s", indent, ""); + else + printf("%*s", indent - pos, ""); + + len = strlen(s); + while (len > wrap_len) { + const char *space = isl_memrchr(s, ' ', wrap_len); + int l; + + if (!space) + space = strchr(s + wrap_len, ' '); + if (!space) + break; + l = space - s; + printf("%.*s", l, s); + s = space + 1; + len -= l + 1; + printf("\n%*s", indent, ""); + } + + printf("%s", s); + return len; +} + +static int print_help_msg(struct isl_arg *decl, int pos) +{ + if (!decl->help_msg) + return pos; + + return wrap_msg(decl->help_msg, 30, pos); +} + +static void print_default(struct isl_arg *decl, const char *def, int pos) +{ + const char *default_prefix = "[default: "; + const char *default_suffix = "]"; + int len; + + len = strlen(default_prefix) + strlen(def) + strlen(default_suffix); + + if (!decl->help_msg) { + if (pos >= 29) + printf("\n%30s", ""); + else + printf("%*s", 30 - pos, ""); + } else { + if (pos + len >= 48) + printf("\n%30s", ""); + else + printf(" "); + } + printf("%s%s%s", default_prefix, def, default_suffix); +} + +static void print_default_choice(struct isl_arg *decl, void *opt, int pos) +{ + int i; + const char *s = "none"; + unsigned *p; + + p = (unsigned *)(((char *) opt) + decl->offset); + for (i = 0; decl->u.choice.choice[i].name; ++i) + if (decl->u.choice.choice[i].value == *p) { + s = decl->u.choice.choice[i].name; + break; + } + + print_default(decl, s, pos); +} + +static void print_choice_help(struct isl_arg *decl, + struct isl_prefixes *prefixes, void *opt) +{ + int i; + int pos; + + pos = print_arg_help(decl, prefixes, 0); + printf("="); + pos++; + + for (i = 0; decl->u.choice.choice[i].name; ++i) { + if (i) { + printf("|"); + pos++; + } + printf("%s", decl->u.choice.choice[i].name); + pos += strlen(decl->u.choice.choice[i].name); + } + + pos = print_help_msg(decl, pos); + print_default_choice(decl, opt, pos); + + printf("\n"); +} + +static void print_default_flags(struct isl_arg *decl, void *opt, int pos) +{ + int i, first; + const char *default_prefix = "[default: "; + const char *default_suffix = "]"; + int len = strlen(default_prefix) + strlen(default_suffix); + unsigned *p; + + p = (unsigned *)(((char *) opt) + decl->offset); + for (i = 0; decl->u.flags.flags[i].name; ++i) + if ((*p & decl->u.flags.flags[i].mask) == + decl->u.flags.flags[i].value) + len += strlen(decl->u.flags.flags[i].name); + + if (!decl->help_msg) { + if (pos >= 29) + printf("\n%30s", ""); + else + printf("%*s", 30 - pos, ""); + } else { + if (pos + len >= 48) + printf("\n%30s", ""); + else + printf(" "); + } + printf("%s", default_prefix); + + for (first = 1, i = 0; decl->u.flags.flags[i].name; ++i) + if ((*p & decl->u.flags.flags[i].mask) == + decl->u.flags.flags[i].value) { + if (!first) + printf(","); + printf("%s", decl->u.flags.flags[i].name); + first = 0; + } + + printf("%s", default_suffix); +} + +static void print_flags_help(struct isl_arg *decl, + struct isl_prefixes *prefixes, void *opt) +{ + int i, j; + int pos; + + pos = print_arg_help(decl, prefixes, 0); + printf("="); + pos++; + + for (i = 0; decl->u.flags.flags[i].name; ++i) { + if (i) { + printf(","); + pos++; + } + for (j = i; + decl->u.flags.flags[j].mask == decl->u.flags.flags[i].mask; + ++j) { + if (j != i) { + printf("|"); + pos++; + } + printf("%s", decl->u.flags.flags[j].name); + pos += strlen(decl->u.flags.flags[j].name); + } + i = j - 1; + } + + pos = print_help_msg(decl, pos); + print_default_flags(decl, opt, pos); + + printf("\n"); +} + +static void print_bool_help(struct isl_arg *decl, + struct isl_prefixes *prefixes, void *opt) +{ + int pos; + unsigned *p = opt ? (unsigned *)(((char *) opt) + decl->offset) : NULL; + int no = p ? *p == 1 : 0; + pos = print_arg_help(decl, prefixes, no); + pos = print_help_msg(decl, pos); + if (decl->offset != ISL_ARG_OFFSET_NONE) + print_default(decl, no ? "yes" : "no", pos); + printf("\n"); +} + +static int print_argument_name(struct isl_arg *decl, const char *name, int pos) +{ + printf("%c<%s>", decl->long_name ? '=' : ' ', name); + return pos + 3 + strlen(name); +} + +static void print_int_help(struct isl_arg *decl, + struct isl_prefixes *prefixes, void *opt) +{ + int pos; + char val[20]; + int *p = (int *)(((char *) opt) + decl->offset); + pos = print_arg_help(decl, prefixes, 0); + pos = print_argument_name(decl, decl->argument_name, pos); + pos = print_help_msg(decl, pos); + snprintf(val, sizeof(val), "%d", *p); + print_default(decl, val, pos); + printf("\n"); +} + +static void print_long_help(struct isl_arg *decl, + struct isl_prefixes *prefixes, void *opt) +{ + int pos; + long *p = (long *)(((char *) opt) + decl->offset); + pos = print_arg_help(decl, prefixes, 0); + if (*p != decl->u.l.default_selected) { + printf("["); + pos++; + } + printf("=long"); + pos += 5; + if (*p != decl->u.l.default_selected) { + printf("]"); + pos++; + } + print_help_msg(decl, pos); + printf("\n"); +} + +static void print_ulong_help(struct isl_arg *decl, + struct isl_prefixes *prefixes) +{ + int pos; + pos = print_arg_help(decl, prefixes, 0); + printf("=ulong"); + pos += 6; + print_help_msg(decl, pos); + printf("\n"); +} + +static void print_str_help(struct isl_arg *decl, + struct isl_prefixes *prefixes, void *opt) +{ + int pos; + const char *a = decl->argument_name ? decl->argument_name : "string"; + const char **p = (const char **)(((char *) opt) + decl->offset); + pos = print_arg_help(decl, prefixes, 0); + pos = print_argument_name(decl, a, pos); + pos = print_help_msg(decl, pos); + if (*p) + print_default(decl, *p, pos); + printf("\n"); +} + +static void print_str_list_help(struct isl_arg *decl, + struct isl_prefixes *prefixes) +{ + int pos; + const char *a = decl->argument_name ? decl->argument_name : "string"; + pos = print_arg_help(decl, prefixes, 0); + pos = print_argument_name(decl, a, pos); + pos = print_help_msg(decl, pos); + printf("\n"); +} + +static void print_help(struct isl_arg *arg, + struct isl_prefixes *prefixes, void *opt) +{ + int i; + int any = 0; + + for (i = 0; arg[i].type != isl_arg_end; ++i) { + if (arg[i].flags & ISL_ARG_HIDDEN) + continue; + switch (arg[i].type) { + case isl_arg_flags: + print_flags_help(&arg[i], prefixes, opt); + any = 1; + break; + case isl_arg_choice: + print_choice_help(&arg[i], prefixes, opt); + any = 1; + break; + case isl_arg_bool: + print_bool_help(&arg[i], prefixes, opt); + any = 1; + break; + case isl_arg_int: + print_int_help(&arg[i], prefixes, opt); + any = 1; + break; + case isl_arg_long: + print_long_help(&arg[i], prefixes, opt); + any = 1; + break; + case isl_arg_ulong: + print_ulong_help(&arg[i], prefixes); + any = 1; + break; + case isl_arg_str: + print_str_help(&arg[i], prefixes, opt); + any = 1; + break; + case isl_arg_str_list: + print_str_list_help(&arg[i], prefixes); + any = 1; + break; + case isl_arg_alias: + case isl_arg_version: + case isl_arg_arg: + case isl_arg_footer: + case isl_arg_child: + case isl_arg_user: + case isl_arg_end: + break; + } + } + + for (i = 0; arg[i].type != isl_arg_end; ++i) { + void *child; + int first; + + if (arg[i].type != isl_arg_child) + continue; + if (arg[i].flags & ISL_ARG_HIDDEN) + continue; + + if (any) + printf("\n"); + if (arg[i].help_msg) + printf(" %s\n", arg[i].help_msg); + if (arg[i].offset == ISL_ARG_OFFSET_NONE) + child = opt; + else + child = *(void **)(((char *) opt) + arg[i].offset); + first = add_prefix(prefixes, arg[i].long_name); + print_help(arg[i].u.child.child->args, prefixes, child); + drop_prefix(prefixes, first); + any = 1; + } +} + +static const char *prog_name(const char *prog) +{ + const char *slash; + + slash = strrchr(prog, '/'); + if (slash) + prog = slash + 1; + if (strncmp(prog, "lt-", 3) == 0) + prog += 3; + + return prog; +} + +static int any_version(struct isl_arg *decl) +{ + int i; + + for (i = 0; decl[i].type != isl_arg_end; ++i) { + switch (decl[i].type) { + case isl_arg_version: + return 1; + case isl_arg_child: + if (any_version(decl[i].u.child.child->args)) + return 1; + break; + default: + break; + } + } + + return 0; +} + +static void print_help_and_exit(struct isl_arg *arg, const char *prog, + void *opt) +{ + int i; + struct isl_prefixes prefixes = { 0 }; + + printf("Usage: %s [OPTION...]", prog_name(prog)); + + for (i = 0; arg[i].type != isl_arg_end; ++i) + if (arg[i].type == isl_arg_arg) + printf(" %s", arg[i].argument_name); + + printf("\n\n"); + + print_help(arg, &prefixes, opt); + printf("\n"); + if (any_version(arg)) + printf(" -V, --version\n"); + print_bool_help(help_arg, NULL, NULL); + + for (i = 0; arg[i].type != isl_arg_end; ++i) { + if (arg[i].type != isl_arg_footer) + continue; + wrap_msg(arg[i].help_msg, 0, 0); + printf("\n"); + } + + exit(0); +} + +static int match_long_name(struct isl_arg *decl, + const char *start, const char *end) +{ + do { + if (end - start == strlen(decl->long_name) && + !strncmp(start, decl->long_name, end - start)) + return 1; + } while ((++decl)->type == isl_arg_alias); + + return 0; +} + +static const char *skip_dash_dash(struct isl_arg *decl, const char *arg) +{ + if (!strncmp(arg, "--", 2)) + return arg + 2; + if ((decl->flags & ISL_ARG_SINGLE_DASH) && arg[0] == '-') + return arg + 1; + return NULL; +} + +static const char *skip_name(struct isl_arg *decl, const char *arg, + struct isl_prefixes *prefixes, int need_argument, int *has_argument) +{ + const char *equal; + const char *name; + const char *end; + + if (arg[0] == '-' && arg[1] && arg[1] == decl->short_name) { + if (need_argument && !arg[2]) + return NULL; + if (has_argument) + *has_argument = arg[2] != '\0'; + return arg + 2; + } + if (!decl->long_name) + return NULL; + + name = skip_dash_dash(decl, arg); + if (!name) + return NULL; + + equal = strchr(name, '='); + if (need_argument && !equal) + return NULL; + + if (has_argument) + *has_argument = !!equal; + end = equal ? equal : name + strlen(name); + + name = skip_prefixes(name, prefixes, NULL); + + if (!match_long_name(decl, name, end)) + return NULL; + + return equal ? equal + 1 : end; +} + +static int parse_choice_option(struct isl_arg *decl, char **arg, + struct isl_prefixes *prefixes, void *opt) +{ + int i; + int has_argument; + const char *choice; + + choice = skip_name(decl, arg[0], prefixes, 0, &has_argument); + if (!choice) + return 0; + + if (!has_argument && (!arg[1] || arg[1][0] == '-')) { + unsigned u = decl->u.choice.default_selected; + if (decl->offset != ISL_ARG_OFFSET_NONE) + *(unsigned *)(((char *)opt) + decl->offset) = u; + if (decl->u.choice.set) + decl->u.choice.set(opt, u); + + return 1; + } + + if (!has_argument) + choice = arg[1]; + + for (i = 0; decl->u.choice.choice[i].name; ++i) { + unsigned u; + + if (strcmp(choice, decl->u.choice.choice[i].name)) + continue; + + u = decl->u.choice.choice[i].value; + if (decl->offset != ISL_ARG_OFFSET_NONE) + *(unsigned *)(((char *)opt) + decl->offset) = u; + if (decl->u.choice.set) + decl->u.choice.set(opt, u); + + return has_argument ? 1 : 2; + } + + return 0; +} + +static int set_flag(struct isl_arg *decl, unsigned *val, const char *flag, + size_t len) +{ + int i; + + for (i = 0; decl->u.flags.flags[i].name; ++i) { + if (strncmp(flag, decl->u.flags.flags[i].name, len)) + continue; + + *val &= ~decl->u.flags.flags[i].mask; + *val |= decl->u.flags.flags[i].value; + + return 1; + } + + return 0; +} + +static int parse_flags_option(struct isl_arg *decl, char **arg, + struct isl_prefixes *prefixes, void *opt) +{ + int has_argument; + const char *flags; + const char *comma; + unsigned val; + + flags = skip_name(decl, arg[0], prefixes, 0, &has_argument); + if (!flags) + return 0; + + if (!has_argument && !arg[1]) + return 0; + + if (!has_argument) + flags = arg[1]; + + val = 0; + + while ((comma = strchr(flags, ',')) != NULL) { + if (!set_flag(decl, &val, flags, comma - flags)) + return 0; + flags = comma + 1; + } + if (!set_flag(decl, &val, flags, strlen(flags))) + return 0; + + *(unsigned *)(((char *)opt) + decl->offset) = val; + + return has_argument ? 1 : 2; +} + +static int parse_bool_option(struct isl_arg *decl, char **arg, + struct isl_prefixes *prefixes, void *opt) +{ + const char *name; + unsigned *p = (unsigned *)(((char *)opt) + decl->offset); + int next_prefix; + + if (skip_name(decl, arg[0], prefixes, 0, NULL)) { + if ((decl->flags & ISL_ARG_BOOL_ARG) && arg[1]) { + char *endptr; + int val = strtol(arg[1], &endptr, 0); + if (*endptr == '\0' && (val == 0 || val == 1)) { + if (decl->offset != ISL_ARG_OFFSET_NONE) + *p = val; + if (decl->u.b.set) + decl->u.b.set(opt, val); + return 2; + } + } + if (decl->offset != ISL_ARG_OFFSET_NONE) + *p = 1; + if (decl->u.b.set) + decl->u.b.set(opt, 1); + + return 1; + } + + if (!decl->long_name) + return 0; + + name = skip_dash_dash(decl, arg[0]); + if (!name) + return 0; + + next_prefix = 0; + name = skip_prefixes(name, prefixes, &next_prefix); + + if (strncmp(name, "no-", 3)) + return 0; + name += 3; + + name = skip_prefixes(name, prefixes, &next_prefix); + + if (match_long_name(decl, name, name + strlen(name))) { + if (decl->offset != ISL_ARG_OFFSET_NONE) + *p = 0; + if (decl->u.b.set) + decl->u.b.set(opt, 0); + + return 1; + } + + return 0; +} + +static int parse_str_option(struct isl_arg *decl, char **arg, + struct isl_prefixes *prefixes, void *opt) +{ + int has_argument; + const char *s; + char **p = (char **)(((char *)opt) + decl->offset); + + s = skip_name(decl, arg[0], prefixes, 0, &has_argument); + if (!s) + return 0; + + if (has_argument) { + free(*p); + *p = strdup(s); + return 1; + } + + if (arg[1]) { + free(*p); + *p = strdup(arg[1]); + return 2; + } + + return 0; +} + +static int isl_arg_str_list_append(struct isl_arg *decl, void *opt, + const char *s) +{ + int *n = (int *)(((char *) opt) + decl->u.str_list.offset_n); + char **list = *(char ***)(((char *) opt) + decl->offset); + + list = realloc(list, (*n + 1) * sizeof(char *)); + if (!list) + return -1; + *(char ***)(((char *) opt) + decl->offset) = list; + list[*n] = strdup(s); + (*n)++; + return 0; +} + +static int parse_str_list_option(struct isl_arg *decl, char **arg, + struct isl_prefixes *prefixes, void *opt) +{ + int has_argument; + const char *s; + + s = skip_name(decl, arg[0], prefixes, 0, &has_argument); + if (!s) + return 0; + + if (has_argument) { + isl_arg_str_list_append(decl, opt, s); + return 1; + } + + if (arg[1]) { + isl_arg_str_list_append(decl, opt, arg[1]); + return 2; + } + + return 0; +} + +static int parse_int_option(struct isl_arg *decl, char **arg, + struct isl_prefixes *prefixes, void *opt) +{ + int has_argument; + const char *val; + char *endptr; + int *p = (int *)(((char *)opt) + decl->offset); + + val = skip_name(decl, arg[0], prefixes, 0, &has_argument); + if (!val) + return 0; + + if (has_argument) { + *p = atoi(val); + return 1; + } + + if (arg[1]) { + int i = strtol(arg[1], &endptr, 0); + if (*endptr == '\0') { + *p = i; + return 2; + } + } + + return 0; +} + +static int parse_long_option(struct isl_arg *decl, char **arg, + struct isl_prefixes *prefixes, void *opt) +{ + int has_argument; + const char *val; + char *endptr; + long *p = (long *)(((char *)opt) + decl->offset); + + val = skip_name(decl, arg[0], prefixes, 0, &has_argument); + if (!val) + return 0; + + if (has_argument) { + long l = strtol(val, NULL, 0); + *p = l; + if (decl->u.l.set) + decl->u.l.set(opt, l); + return 1; + } + + if (arg[1]) { + long l = strtol(arg[1], &endptr, 0); + if (*endptr == '\0') { + *p = l; + if (decl->u.l.set) + decl->u.l.set(opt, l); + return 2; + } + } + + if (decl->u.l.default_value != decl->u.l.default_selected) { + *p = decl->u.l.default_selected; + if (decl->u.l.set) + decl->u.l.set(opt, decl->u.l.default_selected); + return 1; + } + + return 0; +} + +static int parse_ulong_option(struct isl_arg *decl, char **arg, + struct isl_prefixes *prefixes, void *opt) +{ + int has_argument; + const char *val; + char *endptr; + unsigned long *p = (unsigned long *)(((char *)opt) + decl->offset); + + val = skip_name(decl, arg[0], prefixes, 0, &has_argument); + if (!val) + return 0; + + if (has_argument) { + *p = strtoul(val, NULL, 0); + return 1; + } + + if (arg[1]) { + unsigned long ul = strtoul(arg[1], &endptr, 0); + if (*endptr == '\0') { + *p = ul; + return 2; + } + } + + return 0; +} + +static int parse_option(struct isl_arg *decl, char **arg, + struct isl_prefixes *prefixes, void *opt); + +static int parse_child_option(struct isl_arg *decl, char **arg, + struct isl_prefixes *prefixes, void *opt) +{ + void *child; + int first, parsed; + + if (decl->offset == ISL_ARG_OFFSET_NONE) + child = opt; + else + child = *(void **)(((char *)opt) + decl->offset); + + first = add_prefix(prefixes, decl->long_name); + parsed = parse_option(decl->u.child.child->args, arg, prefixes, child); + drop_prefix(prefixes, first); + + return parsed; +} + +static int parse_option(struct isl_arg *decl, char **arg, + struct isl_prefixes *prefixes, void *opt) +{ + int i; + + for (i = 0; decl[i].type != isl_arg_end; ++i) { + int parsed = 0; + switch (decl[i].type) { + case isl_arg_choice: + parsed = parse_choice_option(&decl[i], arg, + prefixes, opt); + break; + case isl_arg_flags: + parsed = parse_flags_option(&decl[i], arg, + prefixes, opt); + break; + case isl_arg_int: + parsed = parse_int_option(&decl[i], arg, prefixes, opt); + break; + case isl_arg_long: + parsed = parse_long_option(&decl[i], arg, + prefixes, opt); + break; + case isl_arg_ulong: + parsed = parse_ulong_option(&decl[i], arg, + prefixes, opt); + break; + case isl_arg_bool: + parsed = parse_bool_option(&decl[i], arg, + prefixes, opt); + break; + case isl_arg_str: + parsed = parse_str_option(&decl[i], arg, prefixes, opt); + break; + case isl_arg_str_list: + parsed = parse_str_list_option(&decl[i], arg, prefixes, + opt); + break; + case isl_arg_child: + parsed = parse_child_option(&decl[i], arg, + prefixes, opt); + break; + case isl_arg_alias: + case isl_arg_arg: + case isl_arg_footer: + case isl_arg_user: + case isl_arg_version: + case isl_arg_end: + break; + } + if (parsed) + return parsed; + } + + return 0; +} + +static void print_version(struct isl_arg *decl) +{ + int i; + + for (i = 0; decl[i].type != isl_arg_end; ++i) { + switch (decl[i].type) { + case isl_arg_version: + decl[i].u.version.print_version(); + break; + case isl_arg_child: + print_version(decl[i].u.child.child->args); + break; + default: + break; + } + } +} + +static void print_version_and_exit(struct isl_arg *decl) +{ + print_version(decl); + + exit(0); +} + +static int drop_argument(int argc, char **argv, int drop, int n) +{ + for (; drop + n < argc; ++drop) + argv[drop] = argv[drop + n]; + + return argc - n; +} + +static int n_arg(struct isl_arg *arg) +{ + int i; + int n_arg = 0; + + for (i = 0; arg[i].type != isl_arg_end; ++i) + if (arg[i].type == isl_arg_arg) + n_arg++; + + return n_arg; +} + +static int next_arg(struct isl_arg *arg, int a) +{ + for (++a; arg[a].type != isl_arg_end; ++a) + if (arg[a].type == isl_arg_arg) + return a; + + return -1; +} + +/* Unless ISL_ARG_SKIP_HELP is set, check if "arg" is + * equal to "--help" or "-h" and if so call print_help_and_exit. + */ +static void check_help(struct isl_args *args, char *arg, char *prog, void *opt, + unsigned flags) +{ + if (ISL_FL_ISSET(flags, ISL_ARG_SKIP_HELP)) + return; + + if (strcmp(arg, "--help") == 0 || strcmp(arg, "-h") == 0) + print_help_and_exit(args->args, prog, opt); +} + +int isl_args_parse(struct isl_args *args, int argc, char **argv, void *opt, + unsigned flags) +{ + int a = -1; + int skip = 0; + int i; + int n; + struct isl_prefixes prefixes = { 0 }; + + n = n_arg(args->args); + + for (i = 1; i < argc; ++i) { + if ((strcmp(argv[i], "--version") == 0 || + strcmp(argv[i], "-V") == 0) && any_version(args->args)) + print_version_and_exit(args->args); + } + + while (argc > 1 + skip) { + int parsed; + if (argv[1 + skip][0] != '-') { + a = next_arg(args->args, a); + if (a >= 0) { + char **p; + p = (char **)(((char *)opt)+args->args[a].offset); + free(*p); + *p = strdup(argv[1 + skip]); + argc = drop_argument(argc, argv, 1 + skip, 1); + --n; + } else if (ISL_FL_ISSET(flags, ISL_ARG_ALL)) { + fprintf(stderr, "%s: extra argument: %s\n", + prog_name(argv[0]), argv[1 + skip]); + exit(-1); + } else + ++skip; + continue; + } + check_help(args, argv[1 + skip], argv[0], opt, flags); + parsed = parse_option(args->args, &argv[1 + skip], + &prefixes, opt); + if (parsed) + argc = drop_argument(argc, argv, 1 + skip, parsed); + else if (ISL_FL_ISSET(flags, ISL_ARG_ALL)) { + fprintf(stderr, "%s: unrecognized option: %s\n", + prog_name(argv[0]), argv[1 + skip]); + exit(-1); + } else + ++skip; + } + + if (n > 0) { + fprintf(stderr, "%s: expecting %d more argument(s)\n", + prog_name(argv[0]), n); + exit(-1); + } + + return argc; +} diff --git a/external/mit/isl/dist/isl_ast.c b/external/mit/isl/dist/isl_ast.c new file mode 100644 index 000000000000..c7164c4b3e7c --- /dev/null +++ b/external/mit/isl/dist/isl_ast.c @@ -0,0 +1,3940 @@ +/* + * Copyright 2012-2013 Ecole Normale Superieure + * Copyright 2022 Cerebras Systems + * + * Use of this software is governed by the MIT license + * + * Written by Sven Verdoolaege, + * Ecole Normale Superieure, 45 rue d’Ulm, 75230 Paris, France + * and Cerebras Systems, 1237 E Arques Ave, Sunnyvale, CA, USA + */ + +#include + +#include +#include +#include +#include + +#undef EL_BASE +#define EL_BASE ast_expr + +#include + +#undef EL_BASE +#define EL_BASE ast_node + +#include + +isl_ctx *isl_ast_print_options_get_ctx( + __isl_keep isl_ast_print_options *options) +{ + return options ? options->ctx : NULL; +} + +__isl_give isl_ast_print_options *isl_ast_print_options_alloc(isl_ctx *ctx) +{ + isl_ast_print_options *options; + + options = isl_calloc_type(ctx, isl_ast_print_options); + if (!options) + return NULL; + + options->ctx = ctx; + isl_ctx_ref(ctx); + options->ref = 1; + + return options; +} + +__isl_give isl_ast_print_options *isl_ast_print_options_dup( + __isl_keep isl_ast_print_options *options) +{ + isl_ctx *ctx; + isl_ast_print_options *dup; + + if (!options) + return NULL; + + ctx = isl_ast_print_options_get_ctx(options); + dup = isl_ast_print_options_alloc(ctx); + if (!dup) + return NULL; + + dup->print_for = options->print_for; + dup->print_for_user = options->print_for_user; + dup->print_user = options->print_user; + dup->print_user_user = options->print_user_user; + + return dup; +} + +__isl_give isl_ast_print_options *isl_ast_print_options_cow( + __isl_take isl_ast_print_options *options) +{ + if (!options) + return NULL; + + if (options->ref == 1) + return options; + options->ref--; + return isl_ast_print_options_dup(options); +} + +__isl_give isl_ast_print_options *isl_ast_print_options_copy( + __isl_keep isl_ast_print_options *options) +{ + if (!options) + return NULL; + + options->ref++; + return options; +} + +__isl_null isl_ast_print_options *isl_ast_print_options_free( + __isl_take isl_ast_print_options *options) +{ + if (!options) + return NULL; + + if (--options->ref > 0) + return NULL; + + isl_ctx_deref(options->ctx); + + free(options); + return NULL; +} + +/* Set the print_user callback of "options" to "print_user". + * + * If this callback is set, then it is used to print user nodes in the AST. + * Otherwise, the expression associated to the user node is printed. + */ +__isl_give isl_ast_print_options *isl_ast_print_options_set_print_user( + __isl_take isl_ast_print_options *options, + __isl_give isl_printer *(*print_user)(__isl_take isl_printer *p, + __isl_take isl_ast_print_options *options, + __isl_keep isl_ast_node *node, void *user), + void *user) +{ + options = isl_ast_print_options_cow(options); + if (!options) + return NULL; + + options->print_user = print_user; + options->print_user_user = user; + + return options; +} + +/* Set the print_for callback of "options" to "print_for". + * + * If this callback is set, then it used to print for nodes in the AST. + */ +__isl_give isl_ast_print_options *isl_ast_print_options_set_print_for( + __isl_take isl_ast_print_options *options, + __isl_give isl_printer *(*print_for)(__isl_take isl_printer *p, + __isl_take isl_ast_print_options *options, + __isl_keep isl_ast_node *node, void *user), + void *user) +{ + options = isl_ast_print_options_cow(options); + if (!options) + return NULL; + + options->print_for = print_for; + options->print_for_user = user; + + return options; +} + +/* Create a new operation expression of operation type "op", + * with arguments "args". + */ +static __isl_give isl_ast_expr *alloc_op(enum isl_ast_expr_op_type op, + __isl_take isl_ast_expr_list *args) +{ + isl_ctx *ctx; + isl_ast_expr *expr; + + if (!args) + return NULL; + + ctx = isl_ast_expr_list_get_ctx(args); + expr = isl_calloc_type(ctx, isl_ast_expr); + if (!expr) + goto error; + + expr->ctx = ctx; + isl_ctx_ref(ctx); + expr->ref = 1; + expr->type = isl_ast_expr_op; + expr->u.op.op = op; + expr->u.op.args = args; + + return expr; +error: + isl_ast_expr_list_free(args); + return NULL; +} + +/* Create a new operation expression of operation type "op", + * which will end up having "n_arg" arguments. + * The caller still needs to add those arguments. + */ +__isl_give isl_ast_expr *isl_ast_expr_alloc_op(isl_ctx *ctx, + enum isl_ast_expr_op_type op, int n_arg) +{ + isl_ast_expr_list *args; + + args = isl_ast_expr_list_alloc(ctx, n_arg); + return alloc_op(op, args); +} + +__isl_give isl_ast_expr *isl_ast_expr_copy(__isl_keep isl_ast_expr *expr) +{ + if (!expr) + return NULL; + + expr->ref++; + return expr; +} + +__isl_give isl_ast_expr *isl_ast_expr_dup(__isl_keep isl_ast_expr *expr) +{ + isl_ast_expr *dup; + + if (!expr) + return NULL; + + switch (expr->type) { + case isl_ast_expr_int: + dup = isl_ast_expr_from_val(isl_val_copy(expr->u.v)); + break; + case isl_ast_expr_id: + dup = isl_ast_expr_from_id(isl_id_copy(expr->u.id)); + break; + case isl_ast_expr_op: + dup = alloc_op(expr->u.op.op, + isl_ast_expr_list_copy(expr->u.op.args)); + break; + case isl_ast_expr_error: + dup = NULL; + } + + if (!dup) + return NULL; + + return dup; +} + +__isl_give isl_ast_expr *isl_ast_expr_cow(__isl_take isl_ast_expr *expr) +{ + if (!expr) + return NULL; + + if (expr->ref == 1) + return expr; + expr->ref--; + return isl_ast_expr_dup(expr); +} + +__isl_null isl_ast_expr *isl_ast_expr_free(__isl_take isl_ast_expr *expr) +{ + if (!expr) + return NULL; + + if (--expr->ref > 0) + return NULL; + + isl_ctx_deref(expr->ctx); + + switch (expr->type) { + case isl_ast_expr_int: + isl_val_free(expr->u.v); + break; + case isl_ast_expr_id: + isl_id_free(expr->u.id); + break; + case isl_ast_expr_op: + isl_ast_expr_list_free(expr->u.op.args); + break; + case isl_ast_expr_error: + break; + } + + free(expr); + return NULL; +} + +isl_ctx *isl_ast_expr_get_ctx(__isl_keep isl_ast_expr *expr) +{ + return expr ? expr->ctx : NULL; +} + +enum isl_ast_expr_type isl_ast_expr_get_type(__isl_keep isl_ast_expr *expr) +{ + return expr ? expr->type : isl_ast_expr_error; +} + +/* Return the integer value represented by "expr". + */ +__isl_give isl_val *isl_ast_expr_int_get_val(__isl_keep isl_ast_expr *expr) +{ + if (!expr) + return NULL; + if (expr->type != isl_ast_expr_int) + isl_die(isl_ast_expr_get_ctx(expr), isl_error_invalid, + "expression not an int", return NULL); + return isl_val_copy(expr->u.v); +} + +/* This is an alternative name for the function above. + */ +__isl_give isl_val *isl_ast_expr_get_val(__isl_keep isl_ast_expr *expr) +{ + return isl_ast_expr_int_get_val(expr); +} + +__isl_give isl_id *isl_ast_expr_id_get_id(__isl_keep isl_ast_expr *expr) +{ + if (!expr) + return NULL; + if (expr->type != isl_ast_expr_id) + isl_die(isl_ast_expr_get_ctx(expr), isl_error_invalid, + "expression not an identifier", return NULL); + + return isl_id_copy(expr->u.id); +} + +/* This is an alternative name for the function above. + */ +__isl_give isl_id *isl_ast_expr_get_id(__isl_keep isl_ast_expr *expr) +{ + return isl_ast_expr_id_get_id(expr); +} + +/* Check that "expr" is of type isl_ast_expr_op. + */ +static isl_stat isl_ast_expr_check_op(__isl_keep isl_ast_expr *expr) +{ + if (!expr) + return isl_stat_error; + if (expr->type != isl_ast_expr_op) + isl_die(isl_ast_expr_get_ctx(expr), isl_error_invalid, + "expression not an operation", return isl_stat_error); + return isl_stat_ok; +} + +/* Return the type of operation represented by "expr". + */ +enum isl_ast_expr_op_type isl_ast_expr_op_get_type( + __isl_keep isl_ast_expr *expr) +{ + if (isl_ast_expr_check_op(expr) < 0) + return isl_ast_expr_op_error; + return expr->u.op.op; +} + +/* This is an alternative name for the function above. + */ +enum isl_ast_expr_op_type isl_ast_expr_get_op_type( + __isl_keep isl_ast_expr *expr) +{ + return isl_ast_expr_op_get_type(expr); +} + +/* Return the number of arguments of the operation represented by "expr". + */ +isl_size isl_ast_expr_op_get_n_arg(__isl_keep isl_ast_expr *expr) +{ + if (isl_ast_expr_check_op(expr) < 0) + return isl_size_error; + return isl_ast_expr_list_size(expr->u.op.args); +} + +/* This is an alternative name for the function above. + */ +isl_size isl_ast_expr_get_op_n_arg(__isl_keep isl_ast_expr *expr) +{ + return isl_ast_expr_op_get_n_arg(expr); +} + +/* Return the argument at position "pos" of the operation represented by "expr". + */ +__isl_give isl_ast_expr *isl_ast_expr_op_get_arg(__isl_keep isl_ast_expr *expr, + int pos) +{ + if (isl_ast_expr_check_op(expr) < 0) + return NULL; + + return isl_ast_expr_list_get_at(expr->u.op.args, pos); +} + +/* This is an alternative name for the function above. + */ +__isl_give isl_ast_expr *isl_ast_expr_get_op_arg(__isl_keep isl_ast_expr *expr, + int pos) +{ + return isl_ast_expr_op_get_arg(expr, pos); +} + +/* Return a copy of the arguments of the operation represented by "expr". + */ +static __isl_give isl_ast_expr_list *isl_ast_expr_op_get_args( + __isl_keep isl_ast_expr *expr) +{ + if (isl_ast_expr_check_op(expr) < 0) + return NULL; + return isl_ast_expr_list_copy(expr->u.op.args); +} + +/* Return the arguments of the operation expression "expr". + * This may be either a copy or the arguments themselves + * if there is only one reference to "expr". + * This allows the arguments to be modified inplace + * if both "expr" and its arguments have only a single reference. + * The caller is not allowed to modify "expr" between this call and + * the subsequent call to isl_ast_expr_op_restore_args. + * The only exception is that isl_ast_expr_free can be called instead. + */ +static __isl_give isl_ast_expr_list *isl_ast_expr_op_take_args( + __isl_keep isl_ast_expr *expr) +{ + isl_ast_expr_list *args; + + if (isl_ast_expr_check_op(expr) < 0) + return NULL; + if (expr->ref != 1) + return isl_ast_expr_op_get_args(expr); + args = expr->u.op.args; + expr->u.op.args = NULL; + return args; +} + +/* Set the arguments of the operation expression "expr" to "args", + * where the arguments of "args" may be missing + * due to a preceding call to isl_ast_expr_op_take_args. + * However, in this case, "expr" only has a single reference and + * then the call to isl_ast_expr_cow has no effect. + */ +static __isl_give isl_ast_expr *isl_ast_expr_op_restore_args( + __isl_take isl_ast_expr *expr, __isl_take isl_ast_expr_list *args) +{ + if (isl_ast_expr_check_op(expr) < 0 || !args) + goto error; + if (expr->u.op.args == args) { + isl_ast_expr_list_free(args); + return expr; + } + + expr = isl_ast_expr_cow(expr); + if (!expr) + goto error; + + isl_ast_expr_list_free(expr->u.op.args); + expr->u.op.args = args; + + return expr; +error: + isl_ast_expr_free(expr); + isl_ast_expr_list_free(args); + return NULL; +} + +/* Add "arg" to the arguments of the operation expression "expr". + */ +__isl_give isl_ast_expr *isl_ast_expr_op_add_arg(__isl_take isl_ast_expr *expr, + __isl_take isl_ast_expr *arg) +{ + isl_ast_expr_list *args; + + args = isl_ast_expr_op_take_args(expr); + args = isl_ast_expr_list_add(args, arg); + expr = isl_ast_expr_op_restore_args(expr, args); + + return expr; +} + +/* Replace the argument at position "pos" of "expr" by "arg". + */ +__isl_give isl_ast_expr *isl_ast_expr_set_op_arg(__isl_take isl_ast_expr *expr, + int pos, __isl_take isl_ast_expr *arg) +{ + isl_ast_expr_list *args; + + args = isl_ast_expr_op_take_args(expr); + args = isl_ast_expr_list_set_at(args, pos, arg); + expr = isl_ast_expr_op_restore_args(expr, args); + + return expr; +} + +/* Are the lists of AST expressions "list1" and "list2" the same? + */ +static isl_bool isl_ast_expr_list_is_equal(__isl_keep isl_ast_expr_list *list1, + __isl_keep isl_ast_expr_list *list2) +{ + int i; + isl_size n1, n2; + + if (!list1 || !list2) + return isl_bool_error; + if (list1 == list2) + return isl_bool_true; + + n1 = isl_ast_expr_list_size(list1); + n2 = isl_ast_expr_list_size(list2); + if (n1 < 0 || n2 < 0) + return isl_bool_error; + if (n1 != n2) + return isl_bool_false; + for (i = 0; i < n1; ++i) { + isl_ast_expr *expr1, *expr2; + isl_bool equal; + + expr1 = isl_ast_expr_list_get_at(list1, i); + expr2 = isl_ast_expr_list_get_at(list2, i); + equal = isl_ast_expr_is_equal(expr1, expr2); + isl_ast_expr_free(expr1); + isl_ast_expr_free(expr2); + if (equal < 0 || !equal) + return equal; + } + + return isl_bool_true; +} + +/* Is "expr1" equal to "expr2"? + */ +isl_bool isl_ast_expr_is_equal(__isl_keep isl_ast_expr *expr1, + __isl_keep isl_ast_expr *expr2) +{ + if (!expr1 || !expr2) + return isl_bool_error; + + if (expr1 == expr2) + return isl_bool_true; + if (expr1->type != expr2->type) + return isl_bool_false; + switch (expr1->type) { + case isl_ast_expr_int: + return isl_val_eq(expr1->u.v, expr2->u.v); + case isl_ast_expr_id: + return isl_bool_ok(expr1->u.id == expr2->u.id); + case isl_ast_expr_op: + if (expr1->u.op.op != expr2->u.op.op) + return isl_bool_false; + return isl_ast_expr_list_is_equal(expr1->u.op.args, + expr2->u.op.args); + case isl_ast_expr_error: + return isl_bool_error; + } + + isl_die(isl_ast_expr_get_ctx(expr1), isl_error_internal, + "unhandled case", return isl_bool_error); +} + +/* Create a new id expression representing "id". + */ +__isl_give isl_ast_expr *isl_ast_expr_from_id(__isl_take isl_id *id) +{ + isl_ctx *ctx; + isl_ast_expr *expr; + + if (!id) + return NULL; + + ctx = isl_id_get_ctx(id); + expr = isl_calloc_type(ctx, isl_ast_expr); + if (!expr) + goto error; + + expr->ctx = ctx; + isl_ctx_ref(ctx); + expr->ref = 1; + expr->type = isl_ast_expr_id; + expr->u.id = id; + + return expr; +error: + isl_id_free(id); + return NULL; +} + +/* Create a new integer expression representing "i". + */ +__isl_give isl_ast_expr *isl_ast_expr_alloc_int_si(isl_ctx *ctx, int i) +{ + isl_ast_expr *expr; + + expr = isl_calloc_type(ctx, isl_ast_expr); + if (!expr) + return NULL; + + expr->ctx = ctx; + isl_ctx_ref(ctx); + expr->ref = 1; + expr->type = isl_ast_expr_int; + expr->u.v = isl_val_int_from_si(ctx, i); + if (!expr->u.v) + return isl_ast_expr_free(expr); + + return expr; +} + +/* Create a new integer expression representing "v". + */ +__isl_give isl_ast_expr *isl_ast_expr_from_val(__isl_take isl_val *v) +{ + isl_ctx *ctx; + isl_ast_expr *expr; + + if (!v) + return NULL; + if (!isl_val_is_int(v)) + isl_die(isl_val_get_ctx(v), isl_error_invalid, + "expecting integer value", goto error); + + ctx = isl_val_get_ctx(v); + expr = isl_calloc_type(ctx, isl_ast_expr); + if (!expr) + goto error; + + expr->ctx = ctx; + isl_ctx_ref(ctx); + expr->ref = 1; + expr->type = isl_ast_expr_int; + expr->u.v = v; + + return expr; +error: + isl_val_free(v); + return NULL; +} + +/* Create an expression representing the unary operation "type" applied to + * "arg". + */ +__isl_give isl_ast_expr *isl_ast_expr_alloc_unary( + enum isl_ast_expr_op_type type, __isl_take isl_ast_expr *arg) +{ + isl_ctx *ctx; + isl_ast_expr *expr = NULL; + isl_ast_expr_list *args; + + if (!arg) + return NULL; + + ctx = isl_ast_expr_get_ctx(arg); + expr = isl_ast_expr_alloc_op(ctx, type, 1); + + args = isl_ast_expr_op_take_args(expr); + args = isl_ast_expr_list_add(args, arg); + expr = isl_ast_expr_op_restore_args(expr, args); + + return expr; +} + +/* Create an expression representing the negation of "arg". + */ +__isl_give isl_ast_expr *isl_ast_expr_neg(__isl_take isl_ast_expr *arg) +{ + return isl_ast_expr_alloc_unary(isl_ast_expr_op_minus, arg); +} + +/* Create an expression representing the address of "expr". + */ +__isl_give isl_ast_expr *isl_ast_expr_address_of(__isl_take isl_ast_expr *expr) +{ + if (!expr) + return NULL; + + if (isl_ast_expr_get_type(expr) != isl_ast_expr_op || + isl_ast_expr_get_op_type(expr) != isl_ast_expr_op_access) + isl_die(isl_ast_expr_get_ctx(expr), isl_error_invalid, + "can only take address of access expressions", + return isl_ast_expr_free(expr)); + + return isl_ast_expr_alloc_unary(isl_ast_expr_op_address_of, expr); +} + +/* Create an expression representing the binary operation "type" + * applied to "expr1" and "expr2". + */ +__isl_give isl_ast_expr *isl_ast_expr_alloc_binary( + enum isl_ast_expr_op_type type, + __isl_take isl_ast_expr *expr1, __isl_take isl_ast_expr *expr2) +{ + isl_ctx *ctx; + isl_ast_expr *expr = NULL; + isl_ast_expr_list *args; + + if (!expr1 || !expr2) + goto error; + + ctx = isl_ast_expr_get_ctx(expr1); + expr = isl_ast_expr_alloc_op(ctx, type, 2); + + args = isl_ast_expr_op_take_args(expr); + args = isl_ast_expr_list_add(args, expr1); + args = isl_ast_expr_list_add(args, expr2); + expr = isl_ast_expr_op_restore_args(expr, args); + + return expr; +error: + isl_ast_expr_free(expr1); + isl_ast_expr_free(expr2); + return NULL; +} + +/* Create an expression representing the sum of "expr1" and "expr2". + */ +__isl_give isl_ast_expr *isl_ast_expr_add(__isl_take isl_ast_expr *expr1, + __isl_take isl_ast_expr *expr2) +{ + return isl_ast_expr_alloc_binary(isl_ast_expr_op_add, expr1, expr2); +} + +/* Create an expression representing the difference of "expr1" and "expr2". + */ +__isl_give isl_ast_expr *isl_ast_expr_sub(__isl_take isl_ast_expr *expr1, + __isl_take isl_ast_expr *expr2) +{ + return isl_ast_expr_alloc_binary(isl_ast_expr_op_sub, expr1, expr2); +} + +/* Create an expression representing the product of "expr1" and "expr2". + */ +__isl_give isl_ast_expr *isl_ast_expr_mul(__isl_take isl_ast_expr *expr1, + __isl_take isl_ast_expr *expr2) +{ + return isl_ast_expr_alloc_binary(isl_ast_expr_op_mul, expr1, expr2); +} + +/* Create an expression representing the quotient of "expr1" and "expr2". + */ +__isl_give isl_ast_expr *isl_ast_expr_div(__isl_take isl_ast_expr *expr1, + __isl_take isl_ast_expr *expr2) +{ + return isl_ast_expr_alloc_binary(isl_ast_expr_op_div, expr1, expr2); +} + +/* Create an expression representing the quotient of the integer + * division of "expr1" by "expr2", where "expr1" is known to be + * non-negative. + */ +__isl_give isl_ast_expr *isl_ast_expr_pdiv_q(__isl_take isl_ast_expr *expr1, + __isl_take isl_ast_expr *expr2) +{ + return isl_ast_expr_alloc_binary(isl_ast_expr_op_pdiv_q, expr1, expr2); +} + +/* Create an expression representing the remainder of the integer + * division of "expr1" by "expr2", where "expr1" is known to be + * non-negative. + */ +__isl_give isl_ast_expr *isl_ast_expr_pdiv_r(__isl_take isl_ast_expr *expr1, + __isl_take isl_ast_expr *expr2) +{ + return isl_ast_expr_alloc_binary(isl_ast_expr_op_pdiv_r, expr1, expr2); +} + +/* Create an expression representing the conjunction of "expr1" and "expr2". + */ +__isl_give isl_ast_expr *isl_ast_expr_and(__isl_take isl_ast_expr *expr1, + __isl_take isl_ast_expr *expr2) +{ + return isl_ast_expr_alloc_binary(isl_ast_expr_op_and, expr1, expr2); +} + +/* Create an expression representing the conjunction of "expr1" and "expr2", + * where "expr2" is evaluated only if "expr1" is evaluated to true. + */ +__isl_give isl_ast_expr *isl_ast_expr_and_then(__isl_take isl_ast_expr *expr1, + __isl_take isl_ast_expr *expr2) +{ + return isl_ast_expr_alloc_binary(isl_ast_expr_op_and_then, expr1, expr2); +} + +/* Create an expression representing the disjunction of "expr1" and "expr2". + */ +__isl_give isl_ast_expr *isl_ast_expr_or(__isl_take isl_ast_expr *expr1, + __isl_take isl_ast_expr *expr2) +{ + return isl_ast_expr_alloc_binary(isl_ast_expr_op_or, expr1, expr2); +} + +/* Create an expression representing the disjunction of "expr1" and "expr2", + * where "expr2" is evaluated only if "expr1" is evaluated to false. + */ +__isl_give isl_ast_expr *isl_ast_expr_or_else(__isl_take isl_ast_expr *expr1, + __isl_take isl_ast_expr *expr2) +{ + return isl_ast_expr_alloc_binary(isl_ast_expr_op_or_else, expr1, expr2); +} + +/* Create an expression representing "expr1" less than or equal to "expr2". + */ +__isl_give isl_ast_expr *isl_ast_expr_le(__isl_take isl_ast_expr *expr1, + __isl_take isl_ast_expr *expr2) +{ + return isl_ast_expr_alloc_binary(isl_ast_expr_op_le, expr1, expr2); +} + +/* Create an expression representing "expr1" less than "expr2". + */ +__isl_give isl_ast_expr *isl_ast_expr_lt(__isl_take isl_ast_expr *expr1, + __isl_take isl_ast_expr *expr2) +{ + return isl_ast_expr_alloc_binary(isl_ast_expr_op_lt, expr1, expr2); +} + +/* Create an expression representing "expr1" greater than or equal to "expr2". + */ +__isl_give isl_ast_expr *isl_ast_expr_ge(__isl_take isl_ast_expr *expr1, + __isl_take isl_ast_expr *expr2) +{ + return isl_ast_expr_alloc_binary(isl_ast_expr_op_ge, expr1, expr2); +} + +/* Create an expression representing "expr1" greater than "expr2". + */ +__isl_give isl_ast_expr *isl_ast_expr_gt(__isl_take isl_ast_expr *expr1, + __isl_take isl_ast_expr *expr2) +{ + return isl_ast_expr_alloc_binary(isl_ast_expr_op_gt, expr1, expr2); +} + +/* Create an expression representing "expr1" equal to "expr2". + */ +__isl_give isl_ast_expr *isl_ast_expr_eq(__isl_take isl_ast_expr *expr1, + __isl_take isl_ast_expr *expr2) +{ + return isl_ast_expr_alloc_binary(isl_ast_expr_op_eq, expr1, expr2); +} + +/* Create an expression of type "type" with as arguments "arg0" followed + * by "arguments". + */ +static __isl_give isl_ast_expr *ast_expr_with_arguments( + enum isl_ast_expr_op_type type, __isl_take isl_ast_expr *arg0, + __isl_take isl_ast_expr_list *arguments) +{ + arguments = isl_ast_expr_list_insert(arguments, 0, arg0); + return alloc_op(type, arguments); +} + +/* Create an expression representing an access to "array" with index + * expressions "indices". + */ +__isl_give isl_ast_expr *isl_ast_expr_access(__isl_take isl_ast_expr *array, + __isl_take isl_ast_expr_list *indices) +{ + return ast_expr_with_arguments(isl_ast_expr_op_access, array, indices); +} + +/* Create an expression representing a call to "function" with argument + * expressions "arguments". + */ +__isl_give isl_ast_expr *isl_ast_expr_call(__isl_take isl_ast_expr *function, + __isl_take isl_ast_expr_list *arguments) +{ + return ast_expr_with_arguments(isl_ast_expr_op_call, function, arguments); +} + +/* Wrapper around isl_ast_expr_substitute_ids for use + * as an isl_ast_expr_list_map callback. + */ +static __isl_give isl_ast_expr *substitute_ids(__isl_take isl_ast_expr *expr, + void *user) +{ + isl_id_to_ast_expr *id2expr = user; + + return isl_ast_expr_substitute_ids(expr, + isl_id_to_ast_expr_copy(id2expr)); +} + +/* For each subexpression of "expr" of type isl_ast_expr_id, + * if it appears in "id2expr", then replace it by the corresponding + * expression. + */ +__isl_give isl_ast_expr *isl_ast_expr_substitute_ids( + __isl_take isl_ast_expr *expr, __isl_take isl_id_to_ast_expr *id2expr) +{ + isl_maybe_isl_ast_expr m; + isl_ast_expr_list *args; + + if (!expr || !id2expr) + goto error; + + switch (expr->type) { + case isl_ast_expr_int: + break; + case isl_ast_expr_id: + m = isl_id_to_ast_expr_try_get(id2expr, expr->u.id); + if (m.valid < 0) + goto error; + if (!m.valid) + break; + isl_ast_expr_free(expr); + expr = m.value; + break; + case isl_ast_expr_op: + args = isl_ast_expr_op_take_args(expr); + args = isl_ast_expr_list_map(args, &substitute_ids, id2expr); + expr = isl_ast_expr_op_restore_args(expr, args); + break; + case isl_ast_expr_error: + expr = isl_ast_expr_free(expr); + break; + } + + isl_id_to_ast_expr_free(id2expr); + return expr; +error: + isl_ast_expr_free(expr); + isl_id_to_ast_expr_free(id2expr); + return NULL; +} + +isl_ctx *isl_ast_node_get_ctx(__isl_keep isl_ast_node *node) +{ + return node ? node->ctx : NULL; +} + +enum isl_ast_node_type isl_ast_node_get_type(__isl_keep isl_ast_node *node) +{ + return node ? node->type : isl_ast_node_error; +} + +__isl_give isl_ast_node *isl_ast_node_alloc(isl_ctx *ctx, + enum isl_ast_node_type type) +{ + isl_ast_node *node; + + node = isl_calloc_type(ctx, isl_ast_node); + if (!node) + return NULL; + + node->ctx = ctx; + isl_ctx_ref(ctx); + node->ref = 1; + node->type = type; + + return node; +} + +/* Create an if node with the given guard. + * + * The then body needs to be filled in later. + */ +__isl_give isl_ast_node *isl_ast_node_alloc_if(__isl_take isl_ast_expr *guard) +{ + isl_ast_node *node; + + if (!guard) + return NULL; + + node = isl_ast_node_alloc(isl_ast_expr_get_ctx(guard), isl_ast_node_if); + if (!node) + goto error; + node->u.i.guard = guard; + + return node; +error: + isl_ast_expr_free(guard); + return NULL; +} + +/* Create a for node with the given iterator. + * + * The remaining fields need to be filled in later. + */ +__isl_give isl_ast_node *isl_ast_node_alloc_for(__isl_take isl_id *id) +{ + isl_ast_node *node; + isl_ctx *ctx; + + if (!id) + return NULL; + + ctx = isl_id_get_ctx(id); + node = isl_ast_node_alloc(ctx, isl_ast_node_for); + if (!node) + goto error; + + node->u.f.iterator = isl_ast_expr_from_id(id); + if (!node->u.f.iterator) + return isl_ast_node_free(node); + + return node; +error: + isl_id_free(id); + return NULL; +} + +/* Create a mark node, marking "node" with "id". + */ +__isl_give isl_ast_node *isl_ast_node_alloc_mark(__isl_take isl_id *id, + __isl_take isl_ast_node *node) +{ + isl_ctx *ctx; + isl_ast_node *mark; + + if (!id || !node) + goto error; + + ctx = isl_id_get_ctx(id); + mark = isl_ast_node_alloc(ctx, isl_ast_node_mark); + if (!mark) + goto error; + + mark->u.m.mark = id; + mark->u.m.node = node; + + return mark; +error: + isl_id_free(id); + isl_ast_node_free(node); + return NULL; +} + +/* Create a user node evaluating "expr". + */ +__isl_give isl_ast_node *isl_ast_node_user_from_expr( + __isl_take isl_ast_expr *expr) +{ + isl_ctx *ctx; + isl_ast_node *node; + + if (!expr) + return NULL; + + ctx = isl_ast_expr_get_ctx(expr); + node = isl_ast_node_alloc(ctx, isl_ast_node_user); + if (!node) + goto error; + + node->u.e.expr = expr; + + return node; +error: + isl_ast_expr_free(expr); + return NULL; +} + +/* This is an alternative name for the function above. + */ +__isl_give isl_ast_node *isl_ast_node_alloc_user(__isl_take isl_ast_expr *expr) +{ + return isl_ast_node_user_from_expr(expr); +} + +/* Create a block node with the given children. + */ +__isl_give isl_ast_node *isl_ast_node_block_from_children( + __isl_take isl_ast_node_list *list) +{ + isl_ast_node *node; + isl_ctx *ctx; + + if (!list) + return NULL; + + ctx = isl_ast_node_list_get_ctx(list); + node = isl_ast_node_alloc(ctx, isl_ast_node_block); + if (!node) + goto error; + + node->u.b.children = list; + + return node; +error: + isl_ast_node_list_free(list); + return NULL; +} + +/* This is an alternative name for the function above. + */ +__isl_give isl_ast_node *isl_ast_node_alloc_block( + __isl_take isl_ast_node_list *list) +{ + return isl_ast_node_block_from_children(list); +} + +/* Represent the given list of nodes as a single node, either by + * extract the node from a single element list or by creating + * a block node with the list of nodes as children. + */ +__isl_give isl_ast_node *isl_ast_node_from_ast_node_list( + __isl_take isl_ast_node_list *list) +{ + isl_size n; + isl_ast_node *node; + + n = isl_ast_node_list_n_ast_node(list); + if (n < 0) + goto error; + if (n != 1) + return isl_ast_node_alloc_block(list); + + node = isl_ast_node_list_get_ast_node(list, 0); + isl_ast_node_list_free(list); + + return node; +error: + isl_ast_node_list_free(list); + return NULL; +} + +__isl_give isl_ast_node *isl_ast_node_copy(__isl_keep isl_ast_node *node) +{ + if (!node) + return NULL; + + node->ref++; + return node; +} + +/* Return a fresh copy of "node". + * + * In the case of a degenerate for node, take into account + * that "cond" and "inc" are NULL. + */ +__isl_give isl_ast_node *isl_ast_node_dup(__isl_keep isl_ast_node *node) +{ + isl_ast_node *dup; + + if (!node) + return NULL; + + dup = isl_ast_node_alloc(isl_ast_node_get_ctx(node), node->type); + if (!dup) + return NULL; + + switch (node->type) { + case isl_ast_node_if: + dup->u.i.guard = isl_ast_expr_copy(node->u.i.guard); + dup->u.i.then = isl_ast_node_copy(node->u.i.then); + dup->u.i.else_node = isl_ast_node_copy(node->u.i.else_node); + if (!dup->u.i.guard || !dup->u.i.then || + (node->u.i.else_node && !dup->u.i.else_node)) + return isl_ast_node_free(dup); + break; + case isl_ast_node_for: + dup->u.f.degenerate = node->u.f.degenerate; + dup->u.f.iterator = isl_ast_expr_copy(node->u.f.iterator); + dup->u.f.init = isl_ast_expr_copy(node->u.f.init); + dup->u.f.body = isl_ast_node_copy(node->u.f.body); + if (!dup->u.f.iterator || !dup->u.f.init || !dup->u.f.body) + return isl_ast_node_free(dup); + if (node->u.f.degenerate) + break; + dup->u.f.cond = isl_ast_expr_copy(node->u.f.cond); + dup->u.f.inc = isl_ast_expr_copy(node->u.f.inc); + if (!dup->u.f.cond || !dup->u.f.inc) + return isl_ast_node_free(dup); + break; + case isl_ast_node_block: + dup->u.b.children = isl_ast_node_list_copy(node->u.b.children); + if (!dup->u.b.children) + return isl_ast_node_free(dup); + break; + case isl_ast_node_mark: + dup->u.m.mark = isl_id_copy(node->u.m.mark); + dup->u.m.node = isl_ast_node_copy(node->u.m.node); + if (!dup->u.m.mark || !dup->u.m.node) + return isl_ast_node_free(dup); + break; + case isl_ast_node_user: + dup->u.e.expr = isl_ast_expr_copy(node->u.e.expr); + if (!dup->u.e.expr) + return isl_ast_node_free(dup); + break; + case isl_ast_node_error: + break; + } + + if (!node->annotation) + return dup; + dup->annotation = isl_id_copy(node->annotation); + if (!dup->annotation) + return isl_ast_node_free(dup); + + return dup; +} + +__isl_give isl_ast_node *isl_ast_node_cow(__isl_take isl_ast_node *node) +{ + if (!node) + return NULL; + + if (node->ref == 1) + return node; + node->ref--; + return isl_ast_node_dup(node); +} + +__isl_null isl_ast_node *isl_ast_node_free(__isl_take isl_ast_node *node) +{ + if (!node) + return NULL; + + if (--node->ref > 0) + return NULL; + + switch (node->type) { + case isl_ast_node_if: + isl_ast_expr_free(node->u.i.guard); + isl_ast_node_free(node->u.i.then); + isl_ast_node_free(node->u.i.else_node); + break; + case isl_ast_node_for: + isl_ast_expr_free(node->u.f.iterator); + isl_ast_expr_free(node->u.f.init); + isl_ast_expr_free(node->u.f.cond); + isl_ast_expr_free(node->u.f.inc); + isl_ast_node_free(node->u.f.body); + break; + case isl_ast_node_block: + isl_ast_node_list_free(node->u.b.children); + break; + case isl_ast_node_mark: + isl_id_free(node->u.m.mark); + isl_ast_node_free(node->u.m.node); + break; + case isl_ast_node_user: + isl_ast_expr_free(node->u.e.expr); + break; + case isl_ast_node_error: + break; + } + + isl_id_free(node->annotation); + isl_ctx_deref(node->ctx); + free(node); + + return NULL; +} + +/* Check that "node" is of type "type", printing "msg" if not. + */ +static isl_stat isl_ast_node_check_type(__isl_keep isl_ast_node *node, + enum isl_ast_node_type type, const char *msg) +{ + if (!node) + return isl_stat_error; + if (node->type != type) + isl_die(isl_ast_node_get_ctx(node), isl_error_invalid, msg, + return isl_stat_error); + return isl_stat_ok; +} + +/* Check that "node" is of type isl_ast_node_block. + */ +static isl_stat isl_ast_node_check_block(__isl_keep isl_ast_node *node) +{ + return isl_ast_node_check_type(node, isl_ast_node_block, + "not a block node"); +} + +/* Check that "node" is of type isl_ast_node_if. + */ +static isl_stat isl_ast_node_check_if(__isl_keep isl_ast_node *node) +{ + return isl_ast_node_check_type(node, isl_ast_node_if, "not an if node"); +} + +/* Check that "node" is of type isl_ast_node_for. + */ +static isl_stat isl_ast_node_check_for(__isl_keep isl_ast_node *node) +{ + return isl_ast_node_check_type(node, isl_ast_node_for, + "not a for node"); +} + +/* Check that "node" is of type isl_ast_node_mark. + */ +static isl_stat isl_ast_node_check_mark(__isl_keep isl_ast_node *node) +{ + return isl_ast_node_check_type(node, isl_ast_node_mark, + "not a mark node"); +} + +/* Check that "node" is of type isl_ast_node_user. + */ +static isl_stat isl_ast_node_check_user(__isl_keep isl_ast_node *node) +{ + return isl_ast_node_check_type(node, isl_ast_node_user, + "not a user node"); +} + +#undef NODE_TYPE +#define NODE_TYPE for +#undef FIELD_NAME +#define FIELD_NAME init +#undef FIELD_TYPE +#define FIELD_TYPE isl_ast_expr +#undef FIELD +#define FIELD u.f.init +#include "isl_ast_node_set_field_templ.c" + +#undef NODE_TYPE +#define NODE_TYPE for +#undef FIELD_NAME +#define FIELD_NAME cond +#undef FIELD_TYPE +#define FIELD_TYPE isl_ast_expr +#undef FIELD +#define FIELD u.f.cond +#include "isl_ast_node_set_field_templ.c" + +#undef NODE_TYPE +#define NODE_TYPE for +#undef FIELD_NAME +#define FIELD_NAME inc +#undef FIELD_TYPE +#define FIELD_TYPE isl_ast_expr +#undef FIELD +#define FIELD u.f.inc +#include "isl_ast_node_set_field_templ.c" + +#undef NODE_TYPE +#define NODE_TYPE for +#undef FIELD_NAME +#define FIELD_NAME body +#undef FIELD_TYPE +#define FIELD_TYPE isl_ast_node +#undef FIELD +#define FIELD u.f.body +#include "isl_ast_node_set_field_templ.c" + +/* Return the body of the for-node "node", + * This may be either a copy or the body itself + * if there is only one reference to "node". + * This allows the body to be modified inplace + * if both "node" and its body have only a single reference. + * The caller is not allowed to modify "node" between this call and + * the subsequent call to isl_ast_node_for_restore_body. + * The only exception is that isl_ast_node_free can be called instead. + */ +static __isl_give isl_ast_node *isl_ast_node_for_take_body( + __isl_keep isl_ast_node *node) +{ + isl_ast_node *body; + + if (isl_ast_node_check_for(node) < 0) + return NULL; + if (node->ref != 1) + return isl_ast_node_for_get_body(node); + body = node->u.f.body; + node->u.f.body = NULL; + return body; +} + +/* Set the body of the for-node "node" to "body", + * where the body of "node" may be missing + * due to a preceding call to isl_ast_node_for_take_body. + * However, in this case, "node" only has a single reference. + */ +static __isl_give isl_ast_node *isl_ast_node_for_restore_body( + __isl_take isl_ast_node *node, __isl_take isl_ast_node *body) +{ + return isl_ast_node_for_set_body(node, body); +} + +__isl_give isl_ast_node *isl_ast_node_for_get_body( + __isl_keep isl_ast_node *node) +{ + if (isl_ast_node_check_for(node) < 0) + return NULL; + return isl_ast_node_copy(node->u.f.body); +} + +/* Mark the given for node as being degenerate. + */ +__isl_give isl_ast_node *isl_ast_node_for_mark_degenerate( + __isl_take isl_ast_node *node) +{ + node = isl_ast_node_cow(node); + if (!node) + return NULL; + node->u.f.degenerate = 1; + return node; +} + +isl_bool isl_ast_node_for_is_degenerate(__isl_keep isl_ast_node *node) +{ + if (isl_ast_node_check_for(node) < 0) + return isl_bool_error; + return isl_bool_ok(node->u.f.degenerate); +} + +__isl_give isl_ast_expr *isl_ast_node_for_get_iterator( + __isl_keep isl_ast_node *node) +{ + if (isl_ast_node_check_for(node) < 0) + return NULL; + return isl_ast_expr_copy(node->u.f.iterator); +} + +__isl_give isl_ast_expr *isl_ast_node_for_get_init( + __isl_keep isl_ast_node *node) +{ + if (isl_ast_node_check_for(node) < 0) + return NULL; + return isl_ast_expr_copy(node->u.f.init); +} + +/* Return the condition expression of the given for node. + * + * If the for node is degenerate, then the condition is not explicitly + * stored in the node. Instead, it is constructed as + * + * iterator <= init + */ +__isl_give isl_ast_expr *isl_ast_node_for_get_cond( + __isl_keep isl_ast_node *node) +{ + if (isl_ast_node_check_for(node) < 0) + return NULL; + if (!node->u.f.degenerate) + return isl_ast_expr_copy(node->u.f.cond); + + return isl_ast_expr_alloc_binary(isl_ast_expr_op_le, + isl_ast_expr_copy(node->u.f.iterator), + isl_ast_expr_copy(node->u.f.init)); +} + +/* Return the increment of the given for node. + * + * If the for node is degenerate, then the increment is not explicitly + * stored in the node. We simply return "1". + */ +__isl_give isl_ast_expr *isl_ast_node_for_get_inc( + __isl_keep isl_ast_node *node) +{ + if (isl_ast_node_check_for(node) < 0) + return NULL; + if (!node->u.f.degenerate) + return isl_ast_expr_copy(node->u.f.inc); + return isl_ast_expr_alloc_int_si(isl_ast_node_get_ctx(node), 1); +} + +#undef NODE_TYPE +#define NODE_TYPE if +#undef FIELD_NAME +#define FIELD_NAME then +#undef FIELD_TYPE +#define FIELD_TYPE isl_ast_node +#undef FIELD +#define FIELD u.i.then +#include "isl_ast_node_set_field_templ.c" + +/* Return the then-branch of the if-node "node", + * This may be either a copy or the branch itself + * if there is only one reference to "node". + * This allows the branch to be modified inplace + * if both "node" and its then-branch have only a single reference. + * The caller is not allowed to modify "node" between this call and + * the subsequent call to isl_ast_node_if_restore_then_node. + * The only exception is that isl_ast_node_free can be called instead. + */ +static __isl_give isl_ast_node *isl_ast_node_if_take_then_node( + __isl_keep isl_ast_node *node) +{ + isl_ast_node *then_node; + + if (isl_ast_node_check_if(node) < 0) + return NULL; + if (node->ref != 1) + return isl_ast_node_if_get_then_node(node); + then_node = node->u.i.then; + node->u.i.then = NULL; + return then_node; +} + +/* Set the then-branch of the if-node "node" to "child", + * where the then-branch of "node" may be missing + * due to a preceding call to isl_ast_node_if_take_then_node. + * However, in this case, "node" only has a single reference. + */ +static __isl_give isl_ast_node *isl_ast_node_if_restore_then_node( + __isl_take isl_ast_node *node, __isl_take isl_ast_node *child) +{ + return isl_ast_node_if_set_then(node, child); +} + +/* Return the then-node of the given if-node. + */ +__isl_give isl_ast_node *isl_ast_node_if_get_then_node( + __isl_keep isl_ast_node *node) +{ + if (isl_ast_node_check_if(node) < 0) + return NULL; + return isl_ast_node_copy(node->u.i.then); +} + +/* This is an alternative name for the function above. + */ +__isl_give isl_ast_node *isl_ast_node_if_get_then( + __isl_keep isl_ast_node *node) +{ + return isl_ast_node_if_get_then_node(node); +} + +/* Does the given if-node have an else-node? + */ +isl_bool isl_ast_node_if_has_else_node(__isl_keep isl_ast_node *node) +{ + if (isl_ast_node_check_if(node) < 0) + return isl_bool_error; + return isl_bool_ok(node->u.i.else_node != NULL); +} + +/* This is an alternative name for the function above. + */ +isl_bool isl_ast_node_if_has_else(__isl_keep isl_ast_node *node) +{ + return isl_ast_node_if_has_else_node(node); +} + +/* Return the else-node of the given if-node, + * assuming there is one. + */ +__isl_give isl_ast_node *isl_ast_node_if_get_else_node( + __isl_keep isl_ast_node *node) +{ + if (isl_ast_node_check_if(node) < 0) + return NULL; + return isl_ast_node_copy(node->u.i.else_node); +} + +/* This is an alternative name for the function above. + */ +__isl_give isl_ast_node *isl_ast_node_if_get_else( + __isl_keep isl_ast_node *node) +{ + return isl_ast_node_if_get_else_node(node); +} + +#undef NODE_TYPE +#define NODE_TYPE if +#undef FIELD_NAME +#define FIELD_NAME else_node +#undef FIELD_TYPE +#define FIELD_TYPE isl_ast_node +#undef FIELD +#define FIELD u.i.else_node +static +#include "isl_ast_node_set_field_templ.c" + +/* Return the else-branch of the if-node "node", + * This may be either a copy or the branch itself + * if there is only one reference to "node". + * This allows the branch to be modified inplace + * if both "node" and its else-branch have only a single reference. + * The caller is not allowed to modify "node" between this call and + * the subsequent call to isl_ast_node_if_restore_else_node. + * The only exception is that isl_ast_node_free can be called instead. + */ +static __isl_give isl_ast_node *isl_ast_node_if_take_else_node( + __isl_keep isl_ast_node *node) +{ + isl_ast_node *else_node; + + if (isl_ast_node_check_if(node) < 0) + return NULL; + if (node->ref != 1) + return isl_ast_node_if_get_else_node(node); + else_node = node->u.i.else_node; + node->u.i.else_node = NULL; + return else_node; +} + +/* Set the else-branch of the if-node "node" to "child", + * where the else-branch of "node" may be missing + * due to a preceding call to isl_ast_node_if_take_else_node. + * However, in this case, "node" only has a single reference. + */ +static __isl_give isl_ast_node *isl_ast_node_if_restore_else_node( + __isl_take isl_ast_node *node, __isl_take isl_ast_node *child) +{ + return isl_ast_node_if_set_else_node(node, child); +} + +__isl_give isl_ast_expr *isl_ast_node_if_get_cond( + __isl_keep isl_ast_node *node) +{ + if (isl_ast_node_check_if(node) < 0) + return NULL; + return isl_ast_expr_copy(node->u.i.guard); +} + +__isl_give isl_ast_node_list *isl_ast_node_block_get_children( + __isl_keep isl_ast_node *node) +{ + if (isl_ast_node_check_block(node) < 0) + return NULL; + return isl_ast_node_list_copy(node->u.b.children); +} + +#undef NODE_TYPE +#define NODE_TYPE block +#undef FIELD_NAME +#define FIELD_NAME children +#undef FIELD_TYPE +#define FIELD_TYPE isl_ast_node_list +#undef FIELD +#define FIELD u.b.children +static +#include "isl_ast_node_set_field_templ.c" + +/* Return the children of the block-node "node", + * This may be either a copy or the children themselves + * if there is only one reference to "node". + * This allows the children to be modified inplace + * if both "node" and its children have only a single reference. + * The caller is not allowed to modify "node" between this call and + * the subsequent call to isl_ast_node_block_restore_children. + * The only exception is that isl_ast_node_free can be called instead. + */ +static __isl_give isl_ast_node_list *isl_ast_node_block_take_children( + __isl_keep isl_ast_node *node) +{ + isl_ast_node_list *children; + + if (isl_ast_node_check_block(node) < 0) + return NULL; + if (node->ref != 1) + return isl_ast_node_block_get_children(node); + children = node->u.b.children; + node->u.b.children = NULL; + return children; +} + +/* Set the children of the block-node "node" to "children", + * where the children of "node" may be missing + * due to a preceding call to isl_ast_node_block_take_children. + * However, in this case, "node" only has a single reference. + */ +static __isl_give isl_ast_node *isl_ast_node_block_restore_children( + __isl_take isl_ast_node *node, __isl_take isl_ast_node_list *children) +{ + return isl_ast_node_block_set_children(node, children); +} + +__isl_give isl_ast_expr *isl_ast_node_user_get_expr( + __isl_keep isl_ast_node *node) +{ + if (isl_ast_node_check_user(node) < 0) + return NULL; + + return isl_ast_expr_copy(node->u.e.expr); +} + +/* Return the mark identifier of the mark node "node". + */ +__isl_give isl_id *isl_ast_node_mark_get_id(__isl_keep isl_ast_node *node) +{ + if (isl_ast_node_check_mark(node) < 0) + return NULL; + + return isl_id_copy(node->u.m.mark); +} + +/* Return the node marked by mark node "node". + */ +__isl_give isl_ast_node *isl_ast_node_mark_get_node( + __isl_keep isl_ast_node *node) +{ + if (isl_ast_node_check_mark(node) < 0) + return NULL; + + return isl_ast_node_copy(node->u.m.node); +} + +#undef NODE_TYPE +#define NODE_TYPE mark +#undef FIELD_NAME +#define FIELD_NAME node +#undef FIELD_TYPE +#define FIELD_TYPE isl_ast_node +#undef FIELD +#define FIELD u.m.node +static +#include "isl_ast_node_set_field_templ.c" + +/* Return the child of the mark-node "node", + * This may be either a copy or the child itself + * if there is only one reference to "node". + * This allows the child to be modified inplace + * if both "node" and its child have only a single reference. + * The caller is not allowed to modify "node" between this call and + * the subsequent call to isl_ast_node_mark_restore_node. + * The only exception is that isl_ast_node_free can be called instead. + */ +static __isl_give isl_ast_node *isl_ast_node_mark_take_node( + __isl_keep isl_ast_node *node) +{ + isl_ast_node *child; + + if (isl_ast_node_check_mark(node) < 0) + return NULL; + if (node->ref != 1) + return isl_ast_node_mark_get_node(node); + child = node->u.m.node; + node->u.m.node = NULL; + return child; +} + +/* Set the child of the mark-node "node" to "child", + * where the child of "node" may be missing + * due to a preceding call to isl_ast_node_mark_take_node. + * However, in this case, "node" only has a single reference. + */ +static __isl_give isl_ast_node *isl_ast_node_mark_restore_node( + __isl_take isl_ast_node *node, __isl_take isl_ast_node *child) +{ + return isl_ast_node_mark_set_node(node, child); +} + +__isl_give isl_id *isl_ast_node_get_annotation(__isl_keep isl_ast_node *node) +{ + return node ? isl_id_copy(node->annotation) : NULL; +} + +/* Check that "node" is of any type. + * That is, simply check that it is a valid node. + */ +static isl_stat isl_ast_node_check_any(__isl_keep isl_ast_node *node) +{ + return isl_stat_non_null(node); +} + +#undef NODE_TYPE +#define NODE_TYPE any +#undef FIELD_NAME +#define FIELD_NAME annotation +#undef FIELD_TYPE +#define FIELD_TYPE isl_id +#undef FIELD +#define FIELD annotation +static +#include "isl_ast_node_set_field_templ.c" + +/* Replace node->annotation by "annotation". + */ +__isl_give isl_ast_node *isl_ast_node_set_annotation( + __isl_take isl_ast_node *node, __isl_take isl_id *annotation) +{ + return isl_ast_node_any_set_annotation(node, annotation); +} + +static __isl_give isl_ast_node *traverse(__isl_take isl_ast_node *node, + __isl_give isl_ast_node *(*enter)(__isl_take isl_ast_node *node, + int *more, void *user), + __isl_give isl_ast_node *(*leave)(__isl_take isl_ast_node *node, + void *user), + void *user); + +/* Traverse the elements of "list" and all their descendants + * in depth first preorder. Call "enter" whenever a node is entered and "leave" + * whenever a node is left. + * + * Return the updated node. + */ +static __isl_give isl_ast_node_list *traverse_list( + __isl_take isl_ast_node_list *list, + __isl_give isl_ast_node *(*enter)(__isl_take isl_ast_node *node, + int *more, void *user), + __isl_give isl_ast_node *(*leave)(__isl_take isl_ast_node *node, + void *user), + void *user) +{ + int i; + isl_size n; + + n = isl_ast_node_list_size(list); + if (n < 0) + return isl_ast_node_list_free(list); + + for (i = 0; i < n; ++i) { + isl_ast_node *node; + + node = isl_ast_node_list_get_at(list, i); + node = traverse(node, enter, leave, user); + list = isl_ast_node_list_set_at(list, i, node); + } + + return list; +} + +/* Traverse the descendants of "node" (including the node itself) + * in depth first preorder. Call "enter" whenever a node is entered and "leave" + * whenever a node is left. + * + * If "enter" sets the "more" argument to zero, then the subtree rooted + * at the given node is skipped. + * + * Return the updated node. + */ +static __isl_give isl_ast_node *traverse(__isl_take isl_ast_node *node, + __isl_give isl_ast_node *(*enter)(__isl_take isl_ast_node *node, + int *more, void *user), + __isl_give isl_ast_node *(*leave)(__isl_take isl_ast_node *node, + void *user), + void *user) +{ + int more; + isl_bool has_else; + isl_ast_node *child; + isl_ast_node_list *children; + + node = enter(node, &more, user); + if (!node) + return NULL; + if (!more) + return node; + + switch (node->type) { + case isl_ast_node_for: + child = isl_ast_node_for_take_body(node); + child = traverse(child, enter, leave, user); + node = isl_ast_node_for_restore_body(node, child); + return leave(node, user); + case isl_ast_node_if: + child = isl_ast_node_if_take_then_node(node); + child = traverse(child, enter, leave, user); + node = isl_ast_node_if_restore_then_node(node, child); + has_else = isl_ast_node_if_has_else_node(node); + if (has_else < 0) + return isl_ast_node_free(node); + if (!has_else) + return leave(node, user); + child = isl_ast_node_if_take_else_node(node); + child = traverse(child, enter, leave, user); + node = isl_ast_node_if_restore_else_node(node, child); + return leave(node, user); + case isl_ast_node_block: + children = isl_ast_node_block_take_children(node); + children = traverse_list(children, enter, leave, user); + node = isl_ast_node_block_restore_children(node, children); + return leave(node, user); + case isl_ast_node_mark: + child = isl_ast_node_mark_take_node(node); + child = traverse(child, enter, leave, user); + node = isl_ast_node_mark_restore_node(node, child); + return leave(node, user); + case isl_ast_node_user: + return leave(node, user); + case isl_ast_node_error: + return isl_ast_node_free(node); + } + + return node; +} + +/* Internal data structure storing the arguments of + * isl_ast_node_foreach_descendant_top_down. + */ +struct isl_ast_node_preorder_data { + isl_bool (*fn)(__isl_keep isl_ast_node *node, void *user); + void *user; +}; + +/* Enter "node" and set *more to continue traversing its descendants. + * + * In the case of a depth first preorder traversal, call data->fn and + * let it decide whether to continue. + */ +static __isl_give isl_ast_node *preorder_enter(__isl_take isl_ast_node *node, + int *more, void *user) +{ + struct isl_ast_node_preorder_data *data = user; + isl_bool m; + + if (!node) + return NULL; + m = data->fn(node, data->user); + if (m < 0) + return isl_ast_node_free(node); + *more = m; + return node; +} + +/* Leave "node". + * + * In the case of a depth first preorder traversal, nothing needs to be done. + */ +static __isl_give isl_ast_node *preorder_leave(__isl_take isl_ast_node *node, + void *user) +{ + return node; +} + +/* Traverse the descendants of "node" (including the node itself) + * in depth first preorder. + * + * 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 isl_stat_ok on success and isl_stat_error on failure. + */ +isl_stat isl_ast_node_foreach_descendant_top_down( + __isl_keep isl_ast_node *node, + isl_bool (*fn)(__isl_keep isl_ast_node *node, void *user), void *user) +{ + struct isl_ast_node_preorder_data data = { fn, user }; + + node = isl_ast_node_copy(node); + node = traverse(node, &preorder_enter, &preorder_leave, &data); + isl_ast_node_free(node); + + return isl_stat_non_null(node); +} + +/* Internal data structure storing the arguments of + * isl_ast_node_map_descendant_bottom_up. + */ +struct isl_ast_node_postorder_data { + __isl_give isl_ast_node *(*fn)(__isl_take isl_ast_node *node, + void *user); + void *user; +}; + +/* Enter "node" and set *more to continue traversing its descendants. + * + * In the case of a depth-first post-order traversal, + * nothing needs to be done and traversal always continues. + */ +static __isl_give isl_ast_node *postorder_enter(__isl_take isl_ast_node *node, + int *more, void *user) +{ + *more = 1; + return node; +} + +/* Leave "node". + * + * In the case of a depth-first post-order traversal, call data->fn. + */ +static __isl_give isl_ast_node *postorder_leave(__isl_take isl_ast_node *node, + void *user) +{ + struct isl_ast_node_postorder_data *data = user; + + if (!node) + return NULL; + + node = data->fn(node, data->user); + return node; +} + +/* Traverse the descendants of "node" (including the node itself) + * in depth-first post-order, where the user callback is allowed to modify the + * visited node. + * + * Return the updated node. + */ +__isl_give isl_ast_node *isl_ast_node_map_descendant_bottom_up( + __isl_take isl_ast_node *node, + __isl_give isl_ast_node *(*fn)(__isl_take isl_ast_node *node, + void *user), void *user) +{ + struct isl_ast_node_postorder_data data = { fn, user }; + + return traverse(node, &postorder_enter, &postorder_leave, &data); +} + +/* Textual C representation of the various operators. + */ +static char *op_str_c[] = { + [isl_ast_expr_op_and] = "&&", + [isl_ast_expr_op_and_then] = "&&", + [isl_ast_expr_op_or] = "||", + [isl_ast_expr_op_or_else] = "||", + [isl_ast_expr_op_max] = "max", + [isl_ast_expr_op_min] = "min", + [isl_ast_expr_op_minus] = "-", + [isl_ast_expr_op_add] = "+", + [isl_ast_expr_op_sub] = "-", + [isl_ast_expr_op_mul] = "*", + [isl_ast_expr_op_fdiv_q] = "floord", + [isl_ast_expr_op_pdiv_q] = "/", + [isl_ast_expr_op_pdiv_r] = "%", + [isl_ast_expr_op_zdiv_r] = "%", + [isl_ast_expr_op_div] = "/", + [isl_ast_expr_op_eq] = "==", + [isl_ast_expr_op_le] = "<=", + [isl_ast_expr_op_ge] = ">=", + [isl_ast_expr_op_lt] = "<", + [isl_ast_expr_op_gt] = ">", + [isl_ast_expr_op_member] = ".", + [isl_ast_expr_op_address_of] = "&" +}; + +/* Precedence in C of the various operators. + * Based on http://en.wikipedia.org/wiki/Operators_in_C_and_C++ + * Lowest value means highest precedence. + */ +static int op_prec[] = { + [isl_ast_expr_op_and] = 13, + [isl_ast_expr_op_and_then] = 13, + [isl_ast_expr_op_or] = 14, + [isl_ast_expr_op_or_else] = 14, + [isl_ast_expr_op_max] = 2, + [isl_ast_expr_op_min] = 2, + [isl_ast_expr_op_minus] = 3, + [isl_ast_expr_op_add] = 6, + [isl_ast_expr_op_sub] = 6, + [isl_ast_expr_op_mul] = 5, + [isl_ast_expr_op_div] = 5, + [isl_ast_expr_op_fdiv_q] = 2, + [isl_ast_expr_op_pdiv_q] = 5, + [isl_ast_expr_op_pdiv_r] = 5, + [isl_ast_expr_op_zdiv_r] = 5, + [isl_ast_expr_op_cond] = 15, + [isl_ast_expr_op_select] = 15, + [isl_ast_expr_op_eq] = 9, + [isl_ast_expr_op_le] = 8, + [isl_ast_expr_op_ge] = 8, + [isl_ast_expr_op_lt] = 8, + [isl_ast_expr_op_gt] = 8, + [isl_ast_expr_op_call] = 2, + [isl_ast_expr_op_access] = 2, + [isl_ast_expr_op_member] = 2, + [isl_ast_expr_op_address_of] = 3 +}; + +/* Is the operator left-to-right associative? + */ +static int op_left[] = { + [isl_ast_expr_op_and] = 1, + [isl_ast_expr_op_and_then] = 1, + [isl_ast_expr_op_or] = 1, + [isl_ast_expr_op_or_else] = 1, + [isl_ast_expr_op_max] = 1, + [isl_ast_expr_op_min] = 1, + [isl_ast_expr_op_minus] = 0, + [isl_ast_expr_op_add] = 1, + [isl_ast_expr_op_sub] = 1, + [isl_ast_expr_op_mul] = 1, + [isl_ast_expr_op_div] = 1, + [isl_ast_expr_op_fdiv_q] = 1, + [isl_ast_expr_op_pdiv_q] = 1, + [isl_ast_expr_op_pdiv_r] = 1, + [isl_ast_expr_op_zdiv_r] = 1, + [isl_ast_expr_op_cond] = 0, + [isl_ast_expr_op_select] = 0, + [isl_ast_expr_op_eq] = 1, + [isl_ast_expr_op_le] = 1, + [isl_ast_expr_op_ge] = 1, + [isl_ast_expr_op_lt] = 1, + [isl_ast_expr_op_gt] = 1, + [isl_ast_expr_op_call] = 1, + [isl_ast_expr_op_access] = 1, + [isl_ast_expr_op_member] = 1, + [isl_ast_expr_op_address_of] = 0 +}; + +static int is_and(enum isl_ast_expr_op_type op) +{ + return op == isl_ast_expr_op_and || op == isl_ast_expr_op_and_then; +} + +static int is_or(enum isl_ast_expr_op_type op) +{ + return op == isl_ast_expr_op_or || op == isl_ast_expr_op_or_else; +} + +static int is_add_sub(enum isl_ast_expr_op_type op) +{ + return op == isl_ast_expr_op_add || op == isl_ast_expr_op_sub; +} + +static int is_div_mod(enum isl_ast_expr_op_type op) +{ + return op == isl_ast_expr_op_div || + op == isl_ast_expr_op_pdiv_r || + op == isl_ast_expr_op_zdiv_r; +} + +static __isl_give isl_printer *print_ast_expr_c(__isl_take isl_printer *p, + __isl_keep isl_ast_expr *expr); + +/* Do we need/want parentheses around "expr" as a subexpression of + * an "op" operation? If "left" is set, then "expr" is the left-most + * operand. + * + * We only need parentheses if "expr" represents an operation. + * + * If op has a higher precedence than expr->u.op.op, then we need + * parentheses. + * If op and expr->u.op.op have the same precedence, but the operations + * are performed in an order that is different from the associativity, + * then we need parentheses. + * + * An and inside an or technically does not require parentheses, + * but some compilers complain about that, so we add them anyway. + * + * Computations such as "a / b * c" and "a % b + c" can be somewhat + * difficult to read, so we add parentheses for those as well. + */ +static int sub_expr_need_parens(enum isl_ast_expr_op_type op, + __isl_keep isl_ast_expr *expr, int left) +{ + if (expr->type != isl_ast_expr_op) + return 0; + + if (op_prec[expr->u.op.op] > op_prec[op]) + return 1; + if (op_prec[expr->u.op.op] == op_prec[op] && left != op_left[op]) + return 1; + + if (is_or(op) && is_and(expr->u.op.op)) + return 1; + if (op == isl_ast_expr_op_mul && expr->u.op.op != isl_ast_expr_op_mul && + op_prec[expr->u.op.op] == op_prec[op]) + return 1; + if (is_add_sub(op) && is_div_mod(expr->u.op.op)) + return 1; + + return 0; +} + +/* Print the subexpression at position "pos" of operation expression "expr" + * in C format. + * If "left" is set, then "expr" is the left-most operand. + */ +static __isl_give isl_printer *print_sub_expr_c(__isl_take isl_printer *p, + __isl_keep isl_ast_expr *expr, int pos, int left) +{ + int need_parens; + isl_ast_expr *arg; + + if (!expr) + return isl_printer_free(p); + + arg = isl_ast_expr_list_get_at(expr->u.op.args, pos); + need_parens = sub_expr_need_parens(expr->u.op.op, arg, left); + + if (need_parens) + p = isl_printer_print_str(p, "("); + p = print_ast_expr_c(p, arg); + if (need_parens) + p = isl_printer_print_str(p, ")"); + + isl_ast_expr_free(arg); + + return p; +} + +#define isl_ast_expr_op_last isl_ast_expr_op_address_of + +/* Data structure that holds the user-specified textual + * representations for the operators in C format. + * The entries are either NULL or copies of strings. + * A NULL entry means that the default name should be used. + */ +struct isl_ast_expr_op_names { + char *op_str[isl_ast_expr_op_last + 1]; +}; + +/* Create an empty struct isl_ast_expr_op_names. + */ +static void *create_names(isl_ctx *ctx) +{ + return isl_calloc_type(ctx, struct isl_ast_expr_op_names); +} + +/* Free a struct isl_ast_expr_op_names along with all memory + * owned by the struct. + */ +static void free_names(void *user) +{ + int i; + struct isl_ast_expr_op_names *names = user; + + if (!user) + return; + + for (i = 0; i <= isl_ast_expr_op_last; ++i) + free(names->op_str[i]); + free(user); +} + +/* Create an identifier that is used to store + * an isl_ast_expr_op_names note. + */ +static __isl_give isl_id *names_id(isl_ctx *ctx) +{ + return isl_id_alloc(ctx, "isl_ast_expr_op_type_names", NULL); +} + +/* Ensure that "p" has a note identified by "id". + * If there is no such note yet, then it is created by "note_create" and + * scheduled do be freed by "note_free". + */ +static __isl_give isl_printer *alloc_note(__isl_take isl_printer *p, + __isl_keep isl_id *id, void *(*note_create)(isl_ctx *), + void (*note_free)(void *)) +{ + isl_ctx *ctx; + isl_id *note_id; + isl_bool has_note; + void *note; + + has_note = isl_printer_has_note(p, id); + if (has_note < 0) + return isl_printer_free(p); + if (has_note) + return p; + + ctx = isl_printer_get_ctx(p); + note = note_create(ctx); + if (!note) + return isl_printer_free(p); + note_id = isl_id_alloc(ctx, NULL, note); + if (!note_id) + note_free(note); + else + note_id = isl_id_set_free_user(note_id, note_free); + + p = isl_printer_set_note(p, isl_id_copy(id), note_id); + + return p; +} + +/* Ensure that "p" has an isl_ast_expr_op_names note identified by "id". + */ +static __isl_give isl_printer *alloc_names(__isl_take isl_printer *p, + __isl_keep isl_id *id) +{ + return alloc_note(p, id, &create_names, &free_names); +} + +/* Retrieve the note identified by "id" from "p". + * The note is assumed to exist. + */ +static void *get_note(__isl_keep isl_printer *p, __isl_keep isl_id *id) +{ + void *note; + + id = isl_printer_get_note(p, isl_id_copy(id)); + note = isl_id_get_user(id); + isl_id_free(id); + + return note; +} + +/* Use "name" to print operations of type "type" to "p". + * + * Store the name in an isl_ast_expr_op_names note attached to "p", such that + * it can be retrieved by get_op_str. + */ +__isl_give isl_printer *isl_ast_expr_op_type_set_print_name( + __isl_take isl_printer *p, enum isl_ast_expr_op_type type, + __isl_keep const char *name) +{ + isl_id *id; + struct isl_ast_expr_op_names *names; + + if (!p) + return NULL; + if (type > isl_ast_expr_op_last) + isl_die(isl_printer_get_ctx(p), isl_error_invalid, + "invalid type", return isl_printer_free(p)); + + id = names_id(isl_printer_get_ctx(p)); + p = alloc_names(p, id); + names = get_note(p, id); + isl_id_free(id); + if (!names) + return isl_printer_free(p); + free(names->op_str[type]); + names->op_str[type] = strdup(name); + + return p; +} + +/* This is an alternative name for the function above. + */ +__isl_give isl_printer *isl_ast_op_type_set_print_name( + __isl_take isl_printer *p, enum isl_ast_expr_op_type type, + __isl_keep const char *name) +{ + return isl_ast_expr_op_type_set_print_name(p, type, name); +} + +/* Return the textual representation of "type" in C format. + * + * If there is a user-specified name in an isl_ast_expr_op_names note + * associated to "p", then return that. + * Otherwise, return the default name in op_str_c. + */ +static const char *get_op_str_c(__isl_keep isl_printer *p, + enum isl_ast_expr_op_type type) +{ + isl_id *id; + isl_bool has_names; + struct isl_ast_expr_op_names *names = NULL; + + id = names_id(isl_printer_get_ctx(p)); + has_names = isl_printer_has_note(p, id); + if (has_names >= 0 && has_names) + names = get_note(p, id); + isl_id_free(id); + if (names && names->op_str[type]) + return names->op_str[type]; + return op_str_c[type]; +} + +/* Print the expression at position "pos" in "list" in C format. + */ +static __isl_give isl_printer *print_at_c(__isl_take isl_printer *p, + __isl_keep isl_ast_expr_list *list, int pos) +{ + isl_ast_expr *expr; + + expr = isl_ast_expr_list_get_at(list, pos); + p = print_ast_expr_c(p, expr); + isl_ast_expr_free(expr); + + return p; +} + +/* Print a min or max reduction "expr" in C format. + */ +static __isl_give isl_printer *print_min_max_c(__isl_take isl_printer *p, + __isl_keep isl_ast_expr *expr) +{ + int i = 0; + isl_size n; + + n = isl_ast_expr_list_size(expr->u.op.args); + if (n < 0) + return isl_printer_free(p); + + for (i = 1; i < n; ++i) { + p = isl_printer_print_str(p, get_op_str_c(p, expr->u.op.op)); + p = isl_printer_print_str(p, "("); + } + p = print_at_c(p, expr->u.op.args, 0); + for (i = 1; i < n; ++i) { + p = isl_printer_print_str(p, ", "); + p = print_at_c(p, expr->u.op.args, i); + p = isl_printer_print_str(p, ")"); + } + + return p; +} + +/* Print a function call "expr" in C format. + * + * The first argument represents the function to be called. + */ +static __isl_give isl_printer *print_call_c(__isl_take isl_printer *p, + __isl_keep isl_ast_expr *expr) +{ + int i = 0; + isl_size n; + + n = isl_ast_expr_list_size(expr->u.op.args); + if (n < 0) + return isl_printer_free(p); + + p = print_at_c(p, expr->u.op.args, 0); + p = isl_printer_print_str(p, "("); + for (i = 1; i < n; ++i) { + if (i != 1) + p = isl_printer_print_str(p, ", "); + p = print_at_c(p, expr->u.op.args, i); + } + p = isl_printer_print_str(p, ")"); + + return p; +} + +/* Print an array access "expr" in C format. + * + * The first argument represents the array being accessed. + */ +static __isl_give isl_printer *print_access_c(__isl_take isl_printer *p, + __isl_keep isl_ast_expr *expr) +{ + int i = 0; + isl_size n; + + n = isl_ast_expr_list_size(expr->u.op.args); + if (n < 0) + return isl_printer_free(p); + + p = print_at_c(p, expr->u.op.args, 0); + for (i = 1; i < n; ++i) { + p = isl_printer_print_str(p, "["); + p = print_at_c(p, expr->u.op.args, i); + p = isl_printer_print_str(p, "]"); + } + + return p; +} + +/* Print "expr" to "p" in C format. + */ +static __isl_give isl_printer *print_ast_expr_c(__isl_take isl_printer *p, + __isl_keep isl_ast_expr *expr) +{ + isl_size n; + + if (!p) + return NULL; + if (!expr) + return isl_printer_free(p); + + switch (expr->type) { + case isl_ast_expr_op: + if (expr->u.op.op == isl_ast_expr_op_call) { + p = print_call_c(p, expr); + break; + } + if (expr->u.op.op == isl_ast_expr_op_access) { + p = print_access_c(p, expr); + break; + } + n = isl_ast_expr_list_size(expr->u.op.args); + if (n < 0) + return isl_printer_free(p); + if (n == 1) { + p = isl_printer_print_str(p, + get_op_str_c(p, expr->u.op.op)); + p = print_sub_expr_c(p, expr, 0, 0); + break; + } + if (expr->u.op.op == isl_ast_expr_op_fdiv_q) { + const char *name; + + name = get_op_str_c(p, isl_ast_expr_op_fdiv_q); + p = isl_printer_print_str(p, name); + p = isl_printer_print_str(p, "("); + p = print_at_c(p, expr->u.op.args, 0); + p = isl_printer_print_str(p, ", "); + p = print_at_c(p, expr->u.op.args, 1); + p = isl_printer_print_str(p, ")"); + break; + } + if (expr->u.op.op == isl_ast_expr_op_max || + expr->u.op.op == isl_ast_expr_op_min) { + p = print_min_max_c(p, expr); + break; + } + if (expr->u.op.op == isl_ast_expr_op_cond || + expr->u.op.op == isl_ast_expr_op_select) { + p = print_at_c(p, expr->u.op.args, 0); + p = isl_printer_print_str(p, " ? "); + p = print_at_c(p, expr->u.op.args, 1); + p = isl_printer_print_str(p, " : "); + p = print_at_c(p, expr->u.op.args, 2); + break; + } + if (n != 2) + isl_die(isl_printer_get_ctx(p), isl_error_internal, + "operation should have two arguments", + return isl_printer_free(p)); + p = print_sub_expr_c(p, expr, 0, 1); + if (expr->u.op.op != isl_ast_expr_op_member) + p = isl_printer_print_str(p, " "); + p = isl_printer_print_str(p, get_op_str_c(p, expr->u.op.op)); + if (expr->u.op.op != isl_ast_expr_op_member) + p = isl_printer_print_str(p, " "); + p = print_sub_expr_c(p, expr, 1, 0); + break; + case isl_ast_expr_id: + p = isl_printer_print_str(p, isl_id_get_name(expr->u.id)); + break; + case isl_ast_expr_int: + p = isl_printer_print_val(p, expr->u.v); + break; + case isl_ast_expr_error: + break; + } + + return p; +} + +/* Textual representation of the isl_ast_expr_op_type elements + * for use in a YAML representation of an isl_ast_expr. + */ +static char *op_str[] = { + [isl_ast_expr_op_and] = "and", + [isl_ast_expr_op_and_then] = "and_then", + [isl_ast_expr_op_or] = "or", + [isl_ast_expr_op_or_else] = "or_else", + [isl_ast_expr_op_max] = "max", + [isl_ast_expr_op_min] = "min", + [isl_ast_expr_op_minus] = "minus", + [isl_ast_expr_op_add] = "add", + [isl_ast_expr_op_sub] = "sub", + [isl_ast_expr_op_mul] = "mul", + [isl_ast_expr_op_div] = "div", + [isl_ast_expr_op_fdiv_q] = "fdiv_q", + [isl_ast_expr_op_pdiv_q] = "pdiv_q", + [isl_ast_expr_op_pdiv_r] = "pdiv_r", + [isl_ast_expr_op_zdiv_r] = "zdiv_r", + [isl_ast_expr_op_cond] = "cond", + [isl_ast_expr_op_select] = "select", + [isl_ast_expr_op_eq] = "eq", + [isl_ast_expr_op_le] = "le", + [isl_ast_expr_op_lt] = "lt", + [isl_ast_expr_op_ge] = "ge", + [isl_ast_expr_op_gt] = "gt", + [isl_ast_expr_op_call] = "call", + [isl_ast_expr_op_access] = "access", + [isl_ast_expr_op_member] = "member", + [isl_ast_expr_op_address_of] = "address_of" +}; + +static __isl_give isl_printer *print_ast_expr_isl(__isl_take isl_printer *p, + __isl_keep isl_ast_expr *expr); + +/* Print the arguments of "expr" to "p" in isl format. + * + * If there are no arguments, then nothing needs to be printed. + * Otherwise add an "args" key to the current mapping with as value + * the list of arguments of "expr". + */ +static __isl_give isl_printer *print_arguments(__isl_take isl_printer *p, + __isl_keep isl_ast_expr *expr) +{ + int i; + isl_size n; + + n = isl_ast_expr_get_op_n_arg(expr); + if (n < 0) + return isl_printer_free(p); + if (n == 0) + return p; + + p = isl_printer_print_str(p, "args"); + p = isl_printer_yaml_next(p); + p = isl_printer_yaml_start_sequence(p); + for (i = 0; i < n; ++i) { + isl_ast_expr *arg; + + arg = isl_ast_expr_get_op_arg(expr, i); + p = print_ast_expr_isl(p, arg); + isl_ast_expr_free(arg); + p = isl_printer_yaml_next(p); + } + p = isl_printer_yaml_end_sequence(p); + + return p; +} + +/* Textual representations of the YAML keys for an isl_ast_expr object. + */ +static char *expr_str[] = { + [isl_ast_expr_op] = "op", + [isl_ast_expr_id] = "id", + [isl_ast_expr_int] = "val", +}; + +/* Print "expr" to "p" in isl format. + * + * In particular, print the isl_ast_expr as a YAML document. + */ +static __isl_give isl_printer *print_ast_expr_isl(__isl_take isl_printer *p, + __isl_keep isl_ast_expr *expr) +{ + enum isl_ast_expr_type type; + enum isl_ast_expr_op_type op; + isl_id *id; + isl_val *v; + + if (!expr) + return isl_printer_free(p); + + p = isl_printer_yaml_start_mapping(p); + type = isl_ast_expr_get_type(expr); + switch (type) { + case isl_ast_expr_error: + return isl_printer_free(p); + case isl_ast_expr_op: + op = isl_ast_expr_get_op_type(expr); + if (op == isl_ast_expr_op_error) + return isl_printer_free(p); + p = isl_printer_print_str(p, expr_str[type]); + p = isl_printer_yaml_next(p); + p = isl_printer_print_str(p, op_str[op]); + p = isl_printer_yaml_next(p); + p = print_arguments(p, expr); + break; + case isl_ast_expr_id: + p = isl_printer_print_str(p, expr_str[type]); + p = isl_printer_yaml_next(p); + id = isl_ast_expr_get_id(expr); + p = isl_printer_print_id(p, id); + isl_id_free(id); + break; + case isl_ast_expr_int: + p = isl_printer_print_str(p, expr_str[type]); + p = isl_printer_yaml_next(p); + v = isl_ast_expr_get_val(expr); + p = isl_printer_print_val(p, v); + isl_val_free(v); + break; + } + p = isl_printer_yaml_end_mapping(p); + + return p; +} + +/* Print "expr" to "p". + * + * Only an isl and a C format are supported. + */ +__isl_give isl_printer *isl_printer_print_ast_expr(__isl_take isl_printer *p, + __isl_keep isl_ast_expr *expr) +{ + int format; + + if (!p) + return NULL; + + format = isl_printer_get_output_format(p); + switch (format) { + case ISL_FORMAT_ISL: + p = print_ast_expr_isl(p, expr); + break; + case ISL_FORMAT_C: + p = print_ast_expr_c(p, expr); + break; + default: + isl_die(isl_printer_get_ctx(p), isl_error_unsupported, + "output format not supported for ast_expr", + return isl_printer_free(p)); + } + + return p; +} + +#undef KEY +#define KEY enum isl_ast_expr_op_type +#undef KEY_ERROR +#define KEY_ERROR isl_ast_expr_op_error +#undef KEY_END +#define KEY_END (isl_ast_expr_op_address_of + 1) +#undef KEY_STR +#define KEY_STR op_str +#undef KEY_EXTRACT +#define KEY_EXTRACT extract_op_type +#undef KEY_GET +#define KEY_GET get_op_type +#include "extract_key.c" + +/* Return the next token, which is assumed to be a key in a YAML mapping, + * from "s" as a string. + */ +static __isl_give char *next_key(__isl_keep isl_stream *s) +{ + struct isl_token *tok; + char *str; + isl_ctx *ctx; + + if (!s) + return NULL; + tok = isl_stream_next_token(s); + if (!tok) { + isl_stream_error(s, NULL, "unexpected EOF"); + return NULL; + } + ctx = isl_stream_get_ctx(s); + str = isl_token_get_str(ctx, tok); + isl_token_free(tok); + return str; +} + +/* Remove the next token, which is assumed to be the key "expected" + * in a YAML mapping, from "s" and move to the corresponding value. + */ +static isl_stat eat_key(__isl_keep isl_stream *s, const char *expected) +{ + char *str; + int ok; + + str = next_key(s); + if (!str) + return isl_stat_error; + ok = !strcmp(str, expected); + free(str); + + if (!ok) { + isl_stream_error(s, NULL, "expecting different key"); + return isl_stat_error; + } + + if (isl_stream_yaml_next(s) < 0) + return isl_stat_error; + + return isl_stat_ok; +} + +#undef EL_BASE +#define EL_BASE ast_expr + +#include + +/* Read an isl_ast_expr object of type isl_ast_expr_op from "s", + * where the "op" key has already been read by the caller. + * + * Read the operation type and the arguments and + * return the corresponding isl_ast_expr object. + */ +static __isl_give isl_ast_expr *read_op(__isl_keep isl_stream *s) +{ + enum isl_ast_expr_op_type op; + isl_ast_expr_list *list; + + op = get_op_type(s); + if (op < 0) + return NULL; + if (isl_stream_yaml_next(s) < 0) + return NULL; + if (eat_key(s, "args") < 0) + return NULL; + + list = isl_stream_yaml_read_ast_expr_list(s); + + return alloc_op(op, list); +} + +/* Read an isl_ast_expr object of type isl_ast_expr_id from "s", + * where the "id" key has already been read by the caller. + */ +static __isl_give isl_ast_expr *read_id(__isl_keep isl_stream *s) +{ + return isl_ast_expr_from_id(isl_stream_read_id(s)); +} + +/* Read an isl_ast_expr object of type isl_ast_expr_int from "s", + * where the "val" key has already been read by the caller. + */ +static __isl_give isl_ast_expr *read_int(__isl_keep isl_stream *s) +{ + return isl_ast_expr_from_val(isl_stream_read_val(s)); +} + +#undef KEY +#define KEY enum isl_ast_expr_type +#undef KEY_ERROR +#define KEY_ERROR isl_ast_expr_error +#undef KEY_END +#define KEY_END (isl_ast_expr_int + 1) +#undef KEY_STR +#define KEY_STR expr_str +#undef KEY_EXTRACT +#define KEY_EXTRACT extract_expr_type +#undef KEY_GET +#define KEY_GET get_expr_type +#include "extract_key.c" + +/* Read an isl_ast_expr object from "s". + * + * The keys in the YAML mapping are assumed to appear + * in the same order as the one in which they are printed + * by print_ast_expr_isl. + * In particular, the isl_ast_expr_op type, which is the only one + * with more than one element, is identified by the "op" key and + * not by the "args" key. + */ +__isl_give isl_ast_expr *isl_stream_read_ast_expr(__isl_keep isl_stream *s) +{ + enum isl_ast_expr_type type; + isl_bool more; + isl_ast_expr *expr; + + if (isl_stream_yaml_read_start_mapping(s)) + return NULL; + more = isl_stream_yaml_next(s); + if (more < 0) + return NULL; + if (!more) { + isl_stream_error(s, NULL, "missing key"); + return NULL; + } + + type = get_expr_type(s); + if (type < 0) + return NULL; + if (isl_stream_yaml_next(s) < 0) + return NULL; + switch (type) { + case isl_ast_expr_op: + expr = read_op(s); + break; + case isl_ast_expr_id: + expr = read_id(s); + break; + case isl_ast_expr_int: + expr = read_int(s); + break; + case isl_ast_expr_error: + return NULL; + } + + if (isl_stream_yaml_read_end_mapping(s) < 0) + return isl_ast_expr_free(expr); + + return expr; +} + +static __isl_give isl_printer *print_ast_node_isl(__isl_take isl_printer *p, + __isl_keep isl_ast_node *node); + +/* Print a YAML sequence containing the entries in "list" to "p". + */ +static __isl_give isl_printer *print_ast_node_list(__isl_take isl_printer *p, + __isl_keep isl_ast_node_list *list) +{ + int i; + isl_size n; + + n = isl_ast_node_list_n_ast_node(list); + if (n < 0) + return isl_printer_free(p); + + p = isl_printer_yaml_start_sequence(p); + for (i = 0; i < n; ++i) { + isl_ast_node *node; + + node = isl_ast_node_list_get_ast_node(list, i); + p = print_ast_node_isl(p, node); + isl_ast_node_free(node); + p = isl_printer_yaml_next(p); + } + p = isl_printer_yaml_end_sequence(p); + + return p; +} + +/* Print "node" to "p" in "isl format". + * + * In particular, print the isl_ast_node as a YAML document. + */ +static __isl_give isl_printer *print_ast_node_isl(__isl_take isl_printer *p, + __isl_keep isl_ast_node *node) +{ + switch (node->type) { + case isl_ast_node_for: + p = isl_printer_yaml_start_mapping(p); + p = isl_printer_print_str(p, "iterator"); + p = isl_printer_yaml_next(p); + p = isl_printer_print_ast_expr(p, node->u.f.iterator); + p = isl_printer_yaml_next(p); + if (node->u.f.degenerate) { + p = isl_printer_print_str(p, "value"); + p = isl_printer_yaml_next(p); + p = isl_printer_print_ast_expr(p, node->u.f.init); + p = isl_printer_yaml_next(p); + } else { + p = isl_printer_print_str(p, "init"); + p = isl_printer_yaml_next(p); + p = isl_printer_print_ast_expr(p, node->u.f.init); + p = isl_printer_yaml_next(p); + p = isl_printer_print_str(p, "cond"); + p = isl_printer_yaml_next(p); + p = isl_printer_print_ast_expr(p, node->u.f.cond); + p = isl_printer_yaml_next(p); + p = isl_printer_print_str(p, "inc"); + p = isl_printer_yaml_next(p); + p = isl_printer_print_ast_expr(p, node->u.f.inc); + p = isl_printer_yaml_next(p); + } + if (node->u.f.body) { + p = isl_printer_print_str(p, "body"); + p = isl_printer_yaml_next(p); + p = isl_printer_print_ast_node(p, node->u.f.body); + p = isl_printer_yaml_next(p); + } + p = isl_printer_yaml_end_mapping(p); + break; + case isl_ast_node_mark: + p = isl_printer_yaml_start_mapping(p); + p = isl_printer_print_str(p, "mark"); + p = isl_printer_yaml_next(p); + p = isl_printer_print_id(p, node->u.m.mark); + p = isl_printer_yaml_next(p); + p = isl_printer_print_str(p, "node"); + p = isl_printer_yaml_next(p); + p = isl_printer_print_ast_node(p, node->u.m.node); + p = isl_printer_yaml_end_mapping(p); + break; + case isl_ast_node_user: + p = isl_printer_yaml_start_mapping(p); + p = isl_printer_print_str(p, "user"); + p = isl_printer_yaml_next(p); + p = isl_printer_print_ast_expr(p, node->u.e.expr); + p = isl_printer_yaml_end_mapping(p); + break; + case isl_ast_node_if: + p = isl_printer_yaml_start_mapping(p); + p = isl_printer_print_str(p, "guard"); + p = isl_printer_yaml_next(p); + p = isl_printer_print_ast_expr(p, node->u.i.guard); + p = isl_printer_yaml_next(p); + if (node->u.i.then) { + p = isl_printer_print_str(p, "then"); + p = isl_printer_yaml_next(p); + p = isl_printer_print_ast_node(p, node->u.i.then); + p = isl_printer_yaml_next(p); + } + if (node->u.i.else_node) { + p = isl_printer_print_str(p, "else"); + p = isl_printer_yaml_next(p); + p = isl_printer_print_ast_node(p, node->u.i.else_node); + } + p = isl_printer_yaml_end_mapping(p); + break; + case isl_ast_node_block: + p = print_ast_node_list(p, node->u.b.children); + break; + case isl_ast_node_error: + break; + } + return p; +} + +/* Do we need to print a block around the body "node" of a for or if node? + * + * If the node is a block, then we need to print a block. + * Also if the node is a degenerate for then we will print it as + * an assignment followed by the body of the for loop, so we need a block + * as well. + * If the node is an if node with an else, then we print a block + * to avoid spurious dangling else warnings emitted by some compilers. + * If the node is a mark, then in principle, we would have to check + * the child of the mark node. However, even if the child would not + * require us to print a block, for readability it is probably best + * to print a block anyway. + * If the ast_always_print_block option has been set, then we print a block. + */ +static int need_block(__isl_keep isl_ast_node *node) +{ + isl_ctx *ctx; + + if (node->type == isl_ast_node_block) + return 1; + if (node->type == isl_ast_node_for && node->u.f.degenerate) + return 1; + if (node->type == isl_ast_node_if && node->u.i.else_node) + return 1; + if (node->type == isl_ast_node_mark) + return 1; + + ctx = isl_ast_node_get_ctx(node); + return isl_options_get_ast_always_print_block(ctx); +} + +static __isl_give isl_printer *print_ast_node_c(__isl_take isl_printer *p, + __isl_keep isl_ast_node *node, + __isl_keep isl_ast_print_options *options, int in_block, int in_list); +static __isl_give isl_printer *print_if_c(__isl_take isl_printer *p, + __isl_keep isl_ast_node *node, + __isl_keep isl_ast_print_options *options, int new_line, + int force_block); + +/* Print the body "node" of a for or if node. + * If "else_node" is set, then it is printed as well. + * If "force_block" is set, then print out the body as a block. + * + * We first check if we need to print out a block. + * We always print out a block if there is an else node to make + * sure that the else node is matched to the correct if node. + * For consistency, the corresponding else node is also printed as a block. + * + * If the else node is itself an if, then we print it as + * + * } else if (..) { + * } + * + * Otherwise the else node is printed as + * + * } else { + * node + * } + */ +static __isl_give isl_printer *print_body_c(__isl_take isl_printer *p, + __isl_keep isl_ast_node *node, __isl_keep isl_ast_node *else_node, + __isl_keep isl_ast_print_options *options, int force_block) +{ + if (!node) + return isl_printer_free(p); + + if (!force_block && !else_node && !need_block(node)) { + p = isl_printer_end_line(p); + p = isl_printer_indent(p, 2); + p = isl_ast_node_print(node, p, + isl_ast_print_options_copy(options)); + p = isl_printer_indent(p, -2); + return p; + } + + p = isl_printer_print_str(p, " {"); + p = isl_printer_end_line(p); + p = isl_printer_indent(p, 2); + p = print_ast_node_c(p, node, options, 1, 0); + p = isl_printer_indent(p, -2); + p = isl_printer_start_line(p); + p = isl_printer_print_str(p, "}"); + if (else_node) { + if (else_node->type == isl_ast_node_if) { + p = isl_printer_print_str(p, " else "); + p = print_if_c(p, else_node, options, 0, 1); + } else { + p = isl_printer_print_str(p, " else"); + p = print_body_c(p, else_node, NULL, options, 1); + } + } else + p = isl_printer_end_line(p); + + return p; +} + +/* Print the start of a compound statement. + */ +static __isl_give isl_printer *start_block(__isl_take isl_printer *p) +{ + p = isl_printer_start_line(p); + p = isl_printer_print_str(p, "{"); + p = isl_printer_end_line(p); + p = isl_printer_indent(p, 2); + + return p; +} + +/* Print the end of a compound statement. + */ +static __isl_give isl_printer *end_block(__isl_take isl_printer *p) +{ + p = isl_printer_indent(p, -2); + p = isl_printer_start_line(p); + p = isl_printer_print_str(p, "}"); + p = isl_printer_end_line(p); + + return p; +} + +/* Print the for node "node". + * + * If the for node is degenerate, it is printed as + * + * type iterator = init; + * body + * + * Otherwise, it is printed as + * + * for (type iterator = init; cond; iterator += inc) + * body + * + * "in_block" is set if we are currently inside a block. + * "in_list" is set if the current node is not alone in the block. + * If we are not in a block or if the current not is not alone in the block + * then we print a block around a degenerate for loop such that the variable + * declaration will not conflict with any potential other declaration + * of the same variable. + */ +static __isl_give isl_printer *print_for_c(__isl_take isl_printer *p, + __isl_keep isl_ast_node *node, + __isl_keep isl_ast_print_options *options, int in_block, int in_list) +{ + isl_id *id; + const char *name; + const char *type; + + type = isl_options_get_ast_iterator_type(isl_printer_get_ctx(p)); + if (!node->u.f.degenerate) { + id = isl_ast_expr_get_id(node->u.f.iterator); + name = isl_id_get_name(id); + isl_id_free(id); + p = isl_printer_start_line(p); + p = isl_printer_print_str(p, "for ("); + p = isl_printer_print_str(p, type); + p = isl_printer_print_str(p, " "); + p = isl_printer_print_str(p, name); + p = isl_printer_print_str(p, " = "); + p = isl_printer_print_ast_expr(p, node->u.f.init); + p = isl_printer_print_str(p, "; "); + p = isl_printer_print_ast_expr(p, node->u.f.cond); + p = isl_printer_print_str(p, "; "); + p = isl_printer_print_str(p, name); + p = isl_printer_print_str(p, " += "); + p = isl_printer_print_ast_expr(p, node->u.f.inc); + p = isl_printer_print_str(p, ")"); + p = print_body_c(p, node->u.f.body, NULL, options, 0); + } else { + id = isl_ast_expr_get_id(node->u.f.iterator); + name = isl_id_get_name(id); + isl_id_free(id); + if (!in_block || in_list) + p = start_block(p); + p = isl_printer_start_line(p); + p = isl_printer_print_str(p, type); + p = isl_printer_print_str(p, " "); + p = isl_printer_print_str(p, name); + p = isl_printer_print_str(p, " = "); + p = isl_printer_print_ast_expr(p, node->u.f.init); + p = isl_printer_print_str(p, ";"); + p = isl_printer_end_line(p); + p = print_ast_node_c(p, node->u.f.body, options, 1, 0); + if (!in_block || in_list) + p = end_block(p); + } + + return p; +} + +/* Print the if node "node". + * If "new_line" is set then the if node should be printed on a new line. + * If "force_block" is set, then print out the body as a block. + */ +static __isl_give isl_printer *print_if_c(__isl_take isl_printer *p, + __isl_keep isl_ast_node *node, + __isl_keep isl_ast_print_options *options, int new_line, + int force_block) +{ + if (new_line) + p = isl_printer_start_line(p); + p = isl_printer_print_str(p, "if ("); + p = isl_printer_print_ast_expr(p, node->u.i.guard); + p = isl_printer_print_str(p, ")"); + p = print_body_c(p, node->u.i.then, node->u.i.else_node, options, + force_block); + + return p; +} + +/* Print the "node" to "p". + * + * "in_block" is set if we are currently inside a block. + * If so, we do not print a block around the children of a block node. + * We do this to avoid an extra block around the body of a degenerate + * for node. + * + * "in_list" is set if the current node is not alone in the block. + */ +static __isl_give isl_printer *print_ast_node_c(__isl_take isl_printer *p, + __isl_keep isl_ast_node *node, + __isl_keep isl_ast_print_options *options, int in_block, int in_list) +{ + switch (node->type) { + case isl_ast_node_for: + if (options->print_for) + return options->print_for(p, + isl_ast_print_options_copy(options), + node, options->print_for_user); + p = print_for_c(p, node, options, in_block, in_list); + break; + case isl_ast_node_if: + p = print_if_c(p, node, options, 1, 0); + break; + case isl_ast_node_block: + if (!in_block) + p = start_block(p); + p = isl_ast_node_list_print(node->u.b.children, p, options); + if (!in_block) + p = end_block(p); + break; + case isl_ast_node_mark: + p = isl_printer_start_line(p); + p = isl_printer_print_str(p, "// "); + p = isl_printer_print_str(p, isl_id_get_name(node->u.m.mark)); + p = isl_printer_end_line(p); + p = print_ast_node_c(p, node->u.m.node, options, 0, in_list); + break; + case isl_ast_node_user: + if (options->print_user) + return options->print_user(p, + isl_ast_print_options_copy(options), + node, options->print_user_user); + p = isl_printer_start_line(p); + p = isl_printer_print_ast_expr(p, node->u.e.expr); + p = isl_printer_print_str(p, ";"); + p = isl_printer_end_line(p); + break; + case isl_ast_node_error: + break; + } + return p; +} + +/* Print the for node "node" to "p". + */ +__isl_give isl_printer *isl_ast_node_for_print(__isl_keep isl_ast_node *node, + __isl_take isl_printer *p, __isl_take isl_ast_print_options *options) +{ + if (isl_ast_node_check_for(node) < 0 || !options) + goto error; + p = print_for_c(p, node, options, 0, 0); + isl_ast_print_options_free(options); + return p; +error: + isl_ast_print_options_free(options); + isl_printer_free(p); + return NULL; +} + +/* Print the if node "node" to "p". + */ +__isl_give isl_printer *isl_ast_node_if_print(__isl_keep isl_ast_node *node, + __isl_take isl_printer *p, __isl_take isl_ast_print_options *options) +{ + if (isl_ast_node_check_if(node) < 0 || !options) + goto error; + p = print_if_c(p, node, options, 1, 0); + isl_ast_print_options_free(options); + return p; +error: + isl_ast_print_options_free(options); + isl_printer_free(p); + return NULL; +} + +/* Print "node" to "p". + * + * "node" is assumed to be either the outermost node in an AST or + * a node that is known not to be a block. + * If "node" is a block (and is therefore outermost) and + * if the ast_print_outermost_block options is not set, + * then act as if the printing occurs inside a block, such + * that no "extra" block will get printed. + */ +__isl_give isl_printer *isl_ast_node_print(__isl_keep isl_ast_node *node, + __isl_take isl_printer *p, __isl_take isl_ast_print_options *options) +{ + int in_block = 0; + + if (!options || !node) + goto error; + if (node->type == isl_ast_node_block) { + isl_ctx *ctx; + + ctx = isl_ast_node_get_ctx(node); + in_block = !isl_options_get_ast_print_outermost_block(ctx); + } + p = print_ast_node_c(p, node, options, in_block, 0); + isl_ast_print_options_free(options); + return p; +error: + isl_ast_print_options_free(options); + isl_printer_free(p); + return NULL; +} + +/* Print "node" to "p". + */ +__isl_give isl_printer *isl_printer_print_ast_node(__isl_take isl_printer *p, + __isl_keep isl_ast_node *node) +{ + int format; + isl_ast_print_options *options; + + if (!p) + return NULL; + + format = isl_printer_get_output_format(p); + switch (format) { + case ISL_FORMAT_ISL: + p = print_ast_node_isl(p, node); + break; + case ISL_FORMAT_C: + options = isl_ast_print_options_alloc(isl_printer_get_ctx(p)); + p = isl_ast_node_print(node, p, options); + break; + default: + isl_die(isl_printer_get_ctx(p), isl_error_unsupported, + "output format not supported for ast_node", + return isl_printer_free(p)); + } + + return p; +} + +/* Print the list of nodes "list" to "p". + */ +__isl_give isl_printer *isl_ast_node_list_print( + __isl_keep isl_ast_node_list *list, __isl_take isl_printer *p, + __isl_keep isl_ast_print_options *options) +{ + int i; + + if (!p || !list || !options) + return isl_printer_free(p); + + for (i = 0; i < list->n; ++i) + p = print_ast_node_c(p, list->p[i], options, 1, 1); + + return p; +} + +/* Is the next token on "s" the start of a YAML sequence + * (rather than a YAML mapping)? + * + * A YAML sequence starts with either a '[' or a '-', depending on the format. + */ +static isl_bool next_is_sequence(__isl_keep isl_stream *s) +{ + struct isl_token *tok; + int type; + int seq; + + tok = isl_stream_next_token(s); + if (!tok) + return isl_bool_error; + type = isl_token_get_type(tok); + seq = type == '[' || type == '-'; + isl_stream_push_token(s, tok); + + return isl_bool_ok(seq); +} + +#undef EL_BASE +#define EL_BASE ast_node + +#include + +/* Read an isl_ast_node object of type isl_ast_node_block from "s". + */ +static __isl_give isl_ast_node *read_block(__isl_keep isl_stream *s) +{ + isl_ast_node_list *children; + + children = isl_stream_yaml_read_ast_node_list(s); + return isl_ast_node_block_from_children(children); +} + +/* Textual representation of the first YAML key used + * while printing an isl_ast_node of a given type. + * + * An isl_ast_node of type isl_ast_node_block is not printed + * as a YAML mapping and is therefore assigned a dummy key. + */ +static char *node_first_str[] = { + [isl_ast_node_for] = "iterator", + [isl_ast_node_mark] = "mark", + [isl_ast_node_user] = "user", + [isl_ast_node_if] = "guard", + [isl_ast_node_block] = "", +}; + +#undef KEY +#define KEY enum isl_ast_node_type +#undef KEY_ERROR +#define KEY_ERROR isl_ast_node_error +#undef KEY_END +#define KEY_END (isl_ast_node_user + 1) +#undef KEY_STR +#define KEY_STR node_first_str +#undef KEY_EXTRACT +#define KEY_EXTRACT extract_node_type +#undef KEY_GET +#define KEY_GET get_node_type +#include "extract_key.c" + +static __isl_give isl_ast_node *read_body(__isl_keep isl_stream *s, + __isl_take isl_ast_node *node) +{ + if (eat_key(s, "body") < 0) + return isl_ast_node_free(node); + node = isl_ast_node_for_set_body(node, isl_stream_read_ast_node(s)); + if (isl_stream_yaml_next(s) < 0) + return isl_ast_node_free(node); + return node; +} + +/* Read an isl_ast_node object of type isl_ast_node_for from "s", + * where the initial "iterator" key has already been read by the caller. + * + * If the initial value is printed as the value of the key "value", + * then the for-loop is degenerate and can at most have + * a further "body" element. + * Otherwise, the for-loop also has "cond" and "inc" elements. + */ +static __isl_give isl_ast_node *read_for(__isl_keep isl_stream *s) +{ + isl_id *id; + isl_ast_expr *expr; + isl_ast_node *node; + char *key; + isl_bool more; + int is_value, is_init; + + expr = isl_stream_read_ast_expr(s); + id = isl_ast_expr_id_get_id(expr); + isl_ast_expr_free(expr); + if (!id) + return NULL; + if (isl_stream_yaml_next(s) < 0) + id = isl_id_free(id); + + node = isl_ast_node_alloc_for(id); + + key = next_key(s); + if (!key) + return isl_ast_node_free(node); + is_value = !strcmp(key, "value"); + is_init = !strcmp(key, "init"); + free(key); + if (!is_value && !is_init) + isl_die(isl_stream_get_ctx(s), isl_error_invalid, + "unexpected key", return isl_ast_node_free(node)); + if (isl_stream_yaml_next(s) < 0) + return isl_ast_node_free(node); + node = isl_ast_node_for_set_init(node, isl_stream_read_ast_expr(s)); + if ((more = isl_stream_yaml_next(s)) < 0) + return isl_ast_node_free(node); + if (is_value) { + node = isl_ast_node_for_mark_degenerate(node); + if (more) + node = read_body(s, node); + return node; + } + + if (eat_key(s, "cond") < 0) + return isl_ast_node_free(node); + node = isl_ast_node_for_set_cond(node, isl_stream_read_ast_expr(s)); + if (isl_stream_yaml_next(s) < 0) + return isl_ast_node_free(node); + if (eat_key(s, "inc") < 0) + return isl_ast_node_free(node); + node = isl_ast_node_for_set_inc(node, isl_stream_read_ast_expr(s)); + if ((more = isl_stream_yaml_next(s)) < 0) + return isl_ast_node_free(node); + + if (more) + node = read_body(s, node); + + return node; +} + +/* Read an isl_ast_node object of type isl_ast_node_mark from "s", + * where the initial "mark" key has already been read by the caller. + */ +static __isl_give isl_ast_node *read_mark(__isl_keep isl_stream *s) +{ + isl_id *id; + isl_ast_node *node; + + id = isl_stream_read_id(s); + if (!id) + return NULL; + if (isl_stream_yaml_next(s) < 0) + goto error; + if (eat_key(s, "node") < 0) + goto error; + node = isl_stream_read_ast_node(s); + node = isl_ast_node_alloc_mark(id, node); + if (isl_stream_yaml_next(s) < 0) + return isl_ast_node_free(node); + return node; +error: + isl_id_free(id); + return NULL; +} + +/* Read an isl_ast_node object of type isl_ast_node_user from "s", + * where the "user" key has already been read by the caller. + */ +static __isl_give isl_ast_node *read_user(__isl_keep isl_stream *s) +{ + isl_ast_node *node; + + node = isl_ast_node_alloc_user(isl_stream_read_ast_expr(s)); + if (isl_stream_yaml_next(s) < 0) + return isl_ast_node_free(node); + return node; +} + +/* Read an isl_ast_node object of type isl_ast_node_if from "s", + * where the initial "guard" key has already been read by the caller. + */ +static __isl_give isl_ast_node *read_if(__isl_keep isl_stream *s) +{ + isl_bool more; + isl_ast_node *node; + + node = isl_ast_node_alloc_if(isl_stream_read_ast_expr(s)); + if ((more = isl_stream_yaml_next(s)) < 0) + return isl_ast_node_free(node); + if (!more) + return node; + + if (eat_key(s, "then") < 0) + return isl_ast_node_free(node); + node = isl_ast_node_if_set_then(node, isl_stream_read_ast_node(s)); + if ((more = isl_stream_yaml_next(s)) < 0) + return isl_ast_node_free(node); + if (!more) + return node; + + if (eat_key(s, "else") < 0) + return isl_ast_node_free(node); + node = isl_ast_node_if_set_else_node(node, isl_stream_read_ast_node(s)); + if (isl_stream_yaml_next(s) < 0) + return isl_ast_node_free(node); + + return node; +} + +/* Read an isl_ast_node object from "s". + * + * A block node is printed as a YAML sequence by print_ast_node_isl. + * Every other node type is printed as a YAML mapping. + * + * First check if the next element is a sequence and if so, + * read a block node. + * Otherwise, read a node based on the first mapping key + * that is used to print a node type. + * Note that the keys in the YAML mapping are assumed to appear + * in the same order as the one in which they are printed + * by print_ast_node_isl. + */ +__isl_give isl_ast_node *isl_stream_read_ast_node(__isl_keep isl_stream *s) +{ + enum isl_ast_node_type type; + isl_bool more; + isl_bool seq; + isl_ast_node *node; + + seq = next_is_sequence(s); + if (seq < 0) + return NULL; + if (seq) + return read_block(s); + + if (isl_stream_yaml_read_start_mapping(s)) + return NULL; + more = isl_stream_yaml_next(s); + if (more < 0) + return NULL; + if (!more) { + isl_stream_error(s, NULL, "missing key"); + return NULL; + } + + type = get_node_type(s); + if (type < 0) + return NULL; + if (isl_stream_yaml_next(s) < 0) + return NULL; + + switch (type) { + case isl_ast_node_block: + isl_die(isl_stream_get_ctx(s), isl_error_internal, + "block cannot be detected as mapping", + return NULL); + case isl_ast_node_for: + node = read_for(s); + break; + case isl_ast_node_mark: + node = read_mark(s); + break; + case isl_ast_node_user: + node = read_user(s); + break; + case isl_ast_node_if: + node = read_if(s); + break; + case isl_ast_node_error: + return NULL; + } + + if (isl_stream_yaml_read_end_mapping(s) < 0) + return isl_ast_node_free(node); + + return node; +} + +#define ISL_AST_MACRO_FDIV_Q (1 << 0) +#define ISL_AST_MACRO_MIN (1 << 1) +#define ISL_AST_MACRO_MAX (1 << 2) +#define ISL_AST_MACRO_ALL (ISL_AST_MACRO_FDIV_Q | \ + ISL_AST_MACRO_MIN | \ + ISL_AST_MACRO_MAX) + +static int ast_expr_required_macros(__isl_keep isl_ast_expr *expr, int macros); + +/* Wrapper around ast_expr_required_macros for use + * as an isl_ast_expr_list_foreach callback. + */ +static isl_stat entry_required_macros(__isl_take isl_ast_expr *expr, void *user) +{ + int *macros = user; + + *macros = ast_expr_required_macros(expr, *macros); + isl_ast_expr_free(expr); + + return isl_stat_ok; +} + +/* If "expr" contains an isl_ast_expr_op_min, isl_ast_expr_op_max or + * isl_ast_expr_op_fdiv_q then set the corresponding bit in "macros". + */ +static int ast_expr_required_macros(__isl_keep isl_ast_expr *expr, int macros) +{ + if (macros == ISL_AST_MACRO_ALL) + return macros; + + if (expr->type != isl_ast_expr_op) + return macros; + + if (expr->u.op.op == isl_ast_expr_op_min) + macros |= ISL_AST_MACRO_MIN; + if (expr->u.op.op == isl_ast_expr_op_max) + macros |= ISL_AST_MACRO_MAX; + if (expr->u.op.op == isl_ast_expr_op_fdiv_q) + macros |= ISL_AST_MACRO_FDIV_Q; + + isl_ast_expr_list_foreach(expr->u.op.args, + &entry_required_macros, ¯os); + + return macros; +} + +static int ast_node_list_required_macros(__isl_keep isl_ast_node_list *list, + int macros); + +/* If "node" contains an isl_ast_expr_op_min, isl_ast_expr_op_max or + * isl_ast_expr_op_fdiv_q then set the corresponding bit in "macros". + */ +static int ast_node_required_macros(__isl_keep isl_ast_node *node, int macros) +{ + if (macros == ISL_AST_MACRO_ALL) + return macros; + + switch (node->type) { + case isl_ast_node_for: + macros = ast_expr_required_macros(node->u.f.init, macros); + if (!node->u.f.degenerate) { + macros = ast_expr_required_macros(node->u.f.cond, + macros); + macros = ast_expr_required_macros(node->u.f.inc, + macros); + } + macros = ast_node_required_macros(node->u.f.body, macros); + break; + case isl_ast_node_if: + macros = ast_expr_required_macros(node->u.i.guard, macros); + macros = ast_node_required_macros(node->u.i.then, macros); + if (node->u.i.else_node) + macros = ast_node_required_macros(node->u.i.else_node, + macros); + break; + case isl_ast_node_block: + macros = ast_node_list_required_macros(node->u.b.children, + macros); + break; + case isl_ast_node_mark: + macros = ast_node_required_macros(node->u.m.node, macros); + break; + case isl_ast_node_user: + macros = ast_expr_required_macros(node->u.e.expr, macros); + break; + case isl_ast_node_error: + break; + } + + return macros; +} + +/* If "list" contains an isl_ast_expr_op_min, isl_ast_expr_op_max or + * isl_ast_expr_op_fdiv_q then set the corresponding bit in "macros". + */ +static int ast_node_list_required_macros(__isl_keep isl_ast_node_list *list, + int macros) +{ + int i; + + for (i = 0; i < list->n; ++i) + macros = ast_node_required_macros(list->p[i], macros); + + return macros; +} + +/* Data structure for keeping track of whether a macro definition + * for a given type has already been printed. + * The value is zero if no definition has been printed and non-zero otherwise. + */ +struct isl_ast_expr_op_printed { + char printed[isl_ast_expr_op_last + 1]; +}; + +/* Create an empty struct isl_ast_expr_op_printed. + */ +static void *create_printed(isl_ctx *ctx) +{ + return isl_calloc_type(ctx, struct isl_ast_expr_op_printed); +} + +/* Free a struct isl_ast_expr_op_printed. + */ +static void free_printed(void *user) +{ + free(user); +} + +/* Ensure that "p" has an isl_ast_expr_op_printed note identified by "id". + */ +static __isl_give isl_printer *alloc_printed(__isl_take isl_printer *p, + __isl_keep isl_id *id) +{ + return alloc_note(p, id, &create_printed, &free_printed); +} + +/* Create an identifier that is used to store + * an isl_ast_expr_op_printed note. + */ +static __isl_give isl_id *printed_id(isl_ctx *ctx) +{ + return isl_id_alloc(ctx, "isl_ast_expr_op_type_printed", NULL); +} + +/* Did the user specify that a macro definition should only be + * printed once and has a macro definition for "type" already + * been printed to "p"? + * If definitions should only be printed once, but a definition + * for "p" has not yet been printed, then mark it as having been + * printed so that it will not printed again. + * The actual printing is taken care of by the caller. + */ +static isl_bool already_printed_once(__isl_keep isl_printer *p, + enum isl_ast_expr_op_type type) +{ + isl_ctx *ctx; + isl_id *id; + struct isl_ast_expr_op_printed *printed; + + if (!p) + return isl_bool_error; + + ctx = isl_printer_get_ctx(p); + if (!isl_options_get_ast_print_macro_once(ctx)) + return isl_bool_false; + + if (type > isl_ast_expr_op_last) + isl_die(isl_printer_get_ctx(p), isl_error_invalid, + "invalid type", return isl_bool_error); + + id = printed_id(isl_printer_get_ctx(p)); + p = alloc_printed(p, id); + printed = get_note(p, id); + isl_id_free(id); + if (!printed) + return isl_bool_error; + + if (printed->printed[type]) + return isl_bool_true; + + printed->printed[type] = 1; + return isl_bool_false; +} + +/* Print a macro definition for the operator "type". + * + * If the user has specified that a macro definition should + * only be printed once to any given printer and if the macro definition + * has already been printed to "p", then do not print the definition. + */ +__isl_give isl_printer *isl_ast_expr_op_type_print_macro( + enum isl_ast_expr_op_type type, __isl_take isl_printer *p) +{ + isl_bool skip; + + skip = already_printed_once(p, type); + if (skip < 0) + return isl_printer_free(p); + if (skip) + return p; + + switch (type) { + case isl_ast_expr_op_min: + p = isl_printer_start_line(p); + p = isl_printer_print_str(p, "#define "); + p = isl_printer_print_str(p, get_op_str_c(p, type)); + p = isl_printer_print_str(p, + "(x,y) ((x) < (y) ? (x) : (y))"); + p = isl_printer_end_line(p); + break; + case isl_ast_expr_op_max: + p = isl_printer_start_line(p); + p = isl_printer_print_str(p, "#define "); + p = isl_printer_print_str(p, get_op_str_c(p, type)); + p = isl_printer_print_str(p, + "(x,y) ((x) > (y) ? (x) : (y))"); + p = isl_printer_end_line(p); + break; + case isl_ast_expr_op_fdiv_q: + p = isl_printer_start_line(p); + p = isl_printer_print_str(p, "#define "); + p = isl_printer_print_str(p, get_op_str_c(p, type)); + p = isl_printer_print_str(p, + "(n,d) " + "(((n)<0) ? -((-(n)+(d)-1)/(d)) : (n)/(d))"); + p = isl_printer_end_line(p); + break; + default: + break; + } + + return p; +} + +/* This is an alternative name for the function above. + */ +__isl_give isl_printer *isl_ast_op_type_print_macro( + enum isl_ast_expr_op_type type, __isl_take isl_printer *p) +{ + return isl_ast_expr_op_type_print_macro(type, p); +} + +/* Call "fn" for each type of operation represented in the "macros" + * bit vector. + */ +static isl_stat foreach_ast_expr_op_type(int macros, + isl_stat (*fn)(enum isl_ast_expr_op_type type, void *user), void *user) +{ + if (macros & ISL_AST_MACRO_MIN && fn(isl_ast_expr_op_min, user) < 0) + return isl_stat_error; + if (macros & ISL_AST_MACRO_MAX && fn(isl_ast_expr_op_max, user) < 0) + return isl_stat_error; + if (macros & ISL_AST_MACRO_FDIV_Q && + fn(isl_ast_expr_op_fdiv_q, user) < 0) + return isl_stat_error; + + return isl_stat_ok; +} + +/* Call "fn" for each type of operation that appears in "expr" + * and that requires a macro definition. + */ +isl_stat isl_ast_expr_foreach_ast_expr_op_type(__isl_keep isl_ast_expr *expr, + isl_stat (*fn)(enum isl_ast_expr_op_type type, void *user), void *user) +{ + int macros; + + if (!expr) + return isl_stat_error; + + macros = ast_expr_required_macros(expr, 0); + return foreach_ast_expr_op_type(macros, fn, user); +} + +/* This is an alternative name for the function above. + */ +isl_stat isl_ast_expr_foreach_ast_op_type(__isl_keep isl_ast_expr *expr, + isl_stat (*fn)(enum isl_ast_expr_op_type type, void *user), void *user) +{ + return isl_ast_expr_foreach_ast_expr_op_type(expr, fn, user); +} + +/* Call "fn" for each type of operation that appears in "node" + * and that requires a macro definition. + */ +isl_stat isl_ast_node_foreach_ast_expr_op_type(__isl_keep isl_ast_node *node, + isl_stat (*fn)(enum isl_ast_expr_op_type type, void *user), void *user) +{ + int macros; + + if (!node) + return isl_stat_error; + + macros = ast_node_required_macros(node, 0); + return foreach_ast_expr_op_type(macros, fn, user); +} + +/* This is an alternative name for the function above. + */ +isl_stat isl_ast_node_foreach_ast_op_type(__isl_keep isl_ast_node *node, + isl_stat (*fn)(enum isl_ast_expr_op_type type, void *user), void *user) +{ + return isl_ast_node_foreach_ast_expr_op_type(node, fn, user); +} + +static isl_stat ast_op_type_print_macro(enum isl_ast_expr_op_type type, + void *user) +{ + isl_printer **p = user; + + *p = isl_ast_expr_op_type_print_macro(type, *p); + + return isl_stat_ok; +} + +/* Print macro definitions for all the macros used in the result + * of printing "expr". + */ +__isl_give isl_printer *isl_ast_expr_print_macros( + __isl_keep isl_ast_expr *expr, __isl_take isl_printer *p) +{ + if (isl_ast_expr_foreach_ast_expr_op_type(expr, + &ast_op_type_print_macro, &p) < 0) + return isl_printer_free(p); + return p; +} + +/* Print macro definitions for all the macros used in the result + * of printing "node". + */ +__isl_give isl_printer *isl_ast_node_print_macros( + __isl_keep isl_ast_node *node, __isl_take isl_printer *p) +{ + if (isl_ast_node_foreach_ast_expr_op_type(node, + &ast_op_type_print_macro, &p) < 0) + return isl_printer_free(p); + return p; +} + +/* Return a string containing C code representing this isl_ast_expr. + */ +__isl_give char *isl_ast_expr_to_C_str(__isl_keep isl_ast_expr *expr) +{ + isl_printer *p; + char *str; + + if (!expr) + return NULL; + + p = isl_printer_to_str(isl_ast_expr_get_ctx(expr)); + p = isl_printer_set_output_format(p, ISL_FORMAT_C); + p = isl_printer_print_ast_expr(p, expr); + + str = isl_printer_get_str(p); + + isl_printer_free(p); + + return str; +} + +/* Return a string containing C code representing this isl_ast_node. + */ +__isl_give char *isl_ast_node_to_C_str(__isl_keep isl_ast_node *node) +{ + isl_printer *p; + char *str; + + if (!node) + return NULL; + + p = isl_printer_to_str(isl_ast_node_get_ctx(node)); + p = isl_printer_set_output_format(p, ISL_FORMAT_C); + p = isl_printer_print_ast_node(p, node); + + str = isl_printer_get_str(p); + + isl_printer_free(p); + + return str; +} diff --git a/external/mit/isl/dist/isl_ast_build.c b/external/mit/isl/dist/isl_ast_build.c new file mode 100644 index 000000000000..9f04e1c3e1ed --- /dev/null +++ b/external/mit/isl/dist/isl_ast_build.c @@ -0,0 +1,2459 @@ +/* + * Copyright 2012-2013 Ecole Normale Superieure + * Copyright 2014 INRIA Rocquencourt + * + * Use of this software is governed by the MIT license + * + * Written by Sven Verdoolaege, + * Ecole Normale Superieure, 45 rue d’Ulm, 75230 Paris, France + * and Inria Paris - Rocquencourt, Domaine de Voluceau - Rocquencourt, + * B.P. 105 - 78153 Le Chesnay, France + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Construct a map that isolates the current dimension. + * + * Essentially, the current dimension of "set" is moved to the single output + * dimension in the result, with the current dimension in the domain replaced + * by an unconstrained variable. + */ +__isl_give isl_map *isl_ast_build_map_to_iterator( + __isl_keep isl_ast_build *build, __isl_take isl_set *set) +{ + isl_map *map; + + map = isl_map_from_domain(set); + map = isl_map_add_dims(map, isl_dim_out, 1); + + if (!build) + return isl_map_free(map); + + map = isl_map_equate(map, isl_dim_in, build->depth, isl_dim_out, 0); + map = isl_map_eliminate(map, isl_dim_in, build->depth, 1); + + return map; +} + +/* Initialize the information derived during the AST generation to default + * values for a schedule domain in "space". + * + * We also check that the remaining fields are not NULL so that + * the calling functions don't have to perform this test. + */ +static __isl_give isl_ast_build *isl_ast_build_init_derived( + __isl_take isl_ast_build *build, __isl_take isl_space *space) +{ + isl_ctx *ctx; + isl_vec *strides; + isl_size dim; + + build = isl_ast_build_cow(build); + if (!build || !build->domain) + goto error; + + ctx = isl_ast_build_get_ctx(build); + dim = isl_space_dim(space, isl_dim_set); + if (dim < 0) + goto error; + strides = isl_vec_alloc(ctx, dim); + strides = isl_vec_set_si(strides, 1); + + isl_vec_free(build->strides); + build->strides = strides; + + space = isl_space_map_from_set(space); + isl_multi_aff_free(build->offsets); + build->offsets = isl_multi_aff_zero(isl_space_copy(space)); + isl_multi_aff_free(build->values); + build->values = isl_multi_aff_identity(isl_space_copy(space)); + isl_multi_aff_free(build->internal2input); + build->internal2input = isl_multi_aff_identity(space); + + if (!build->iterators || !build->domain || !build->generated || + !build->pending || !build->values || !build->internal2input || + !build->strides || !build->offsets || !build->options) + return isl_ast_build_free(build); + + return build; +error: + isl_space_free(space); + return isl_ast_build_free(build); +} + +/* Return an isl_id called "c%d", with "%d" set to "i". + * If an isl_id with such a name already appears among the parameters + * in build->domain, then adjust the name to "c%d_%d". + */ +static __isl_give isl_id *generate_name(isl_ctx *ctx, int i, + __isl_keep isl_ast_build *build) +{ + int j; + char name[23]; + isl_set *dom = build->domain; + + snprintf(name, sizeof(name), "c%d", i); + j = 0; + while (isl_set_find_dim_by_name(dom, isl_dim_param, name) >= 0) + snprintf(name, sizeof(name), "c%d_%d", i, j++); + return isl_id_alloc(ctx, name, NULL); +} + +/* Create an isl_ast_build with "set" as domain. + * + * The input set is usually a parameter domain, but we currently allow it to + * be any kind of set. We set the domain of the returned isl_ast_build + * to "set" and initialize all the other fields to default values. + */ +__isl_give isl_ast_build *isl_ast_build_from_context(__isl_take isl_set *set) +{ + int i; + isl_size n; + isl_ctx *ctx; + isl_space *space; + isl_ast_build *build; + + set = isl_set_compute_divs(set); + n = isl_set_dim(set, isl_dim_set); + if (n < 0) + goto error; + + ctx = isl_set_get_ctx(set); + + build = isl_calloc_type(ctx, isl_ast_build); + if (!build) + goto error; + + build->ref = 1; + build->domain = set; + build->generated = isl_set_copy(build->domain); + build->pending = isl_set_universe(isl_set_get_space(build->domain)); + build->options = isl_union_map_empty(isl_space_params_alloc(ctx, 0)); + build->depth = n; + build->iterators = isl_id_list_alloc(ctx, n); + for (i = 0; i < n; ++i) { + isl_id *id; + if (isl_set_has_dim_id(set, isl_dim_set, i)) + id = isl_set_get_dim_id(set, isl_dim_set, i); + else + id = generate_name(ctx, i, build); + build->iterators = isl_id_list_add(build->iterators, id); + } + space = isl_set_get_space(set); + if (isl_space_is_params(space)) + space = isl_space_set_from_params(space); + + return isl_ast_build_init_derived(build, space); +error: + isl_set_free(set); + return NULL; +} + +/* Create an isl_ast_build with a universe (parametric) context. + */ +__isl_give isl_ast_build *isl_ast_build_alloc(isl_ctx *ctx) +{ + isl_space *space; + isl_set *context; + + space = isl_space_params_alloc(ctx, 0); + context = isl_set_universe(space); + + return isl_ast_build_from_context(context); +} + +__isl_give isl_ast_build *isl_ast_build_copy(__isl_keep isl_ast_build *build) +{ + if (!build) + return NULL; + + build->ref++; + return build; +} + +__isl_give isl_ast_build *isl_ast_build_dup(__isl_keep isl_ast_build *build) +{ + isl_ctx *ctx; + isl_ast_build *dup; + + if (!build) + return NULL; + + ctx = isl_ast_build_get_ctx(build); + dup = isl_calloc_type(ctx, isl_ast_build); + if (!dup) + return NULL; + + dup->ref = 1; + dup->outer_pos = build->outer_pos; + dup->depth = build->depth; + dup->iterators = isl_id_list_copy(build->iterators); + dup->domain = isl_set_copy(build->domain); + dup->generated = isl_set_copy(build->generated); + dup->pending = isl_set_copy(build->pending); + dup->values = isl_multi_aff_copy(build->values); + dup->internal2input = isl_multi_aff_copy(build->internal2input); + dup->value = isl_pw_aff_copy(build->value); + dup->strides = isl_vec_copy(build->strides); + dup->offsets = isl_multi_aff_copy(build->offsets); + dup->executed = isl_union_map_copy(build->executed); + dup->single_valued = build->single_valued; + dup->options = isl_union_map_copy(build->options); + dup->at_each_domain = build->at_each_domain; + dup->at_each_domain_user = build->at_each_domain_user; + dup->before_each_for = build->before_each_for; + dup->before_each_for_user = build->before_each_for_user; + dup->after_each_for = build->after_each_for; + dup->after_each_for_user = build->after_each_for_user; + dup->before_each_mark = build->before_each_mark; + dup->before_each_mark_user = build->before_each_mark_user; + dup->after_each_mark = build->after_each_mark; + dup->after_each_mark_user = build->after_each_mark_user; + dup->create_leaf = build->create_leaf; + dup->create_leaf_user = build->create_leaf_user; + dup->node = isl_schedule_node_copy(build->node); + if (build->loop_type) { + int i; + + dup->n = build->n; + dup->loop_type = isl_alloc_array(ctx, + enum isl_ast_loop_type, dup->n); + if (dup->n && !dup->loop_type) + return isl_ast_build_free(dup); + for (i = 0; i < dup->n; ++i) + dup->loop_type[i] = build->loop_type[i]; + } + + if (!dup->iterators || !dup->domain || !dup->generated || + !dup->pending || !dup->values || + !dup->strides || !dup->offsets || !dup->options || + (build->internal2input && !dup->internal2input) || + (build->executed && !dup->executed) || + (build->value && !dup->value) || + (build->node && !dup->node)) + return isl_ast_build_free(dup); + + return dup; +} + +/* Align the parameters of "build" to those of "model", introducing + * additional parameters if needed. + */ +__isl_give isl_ast_build *isl_ast_build_align_params( + __isl_take isl_ast_build *build, __isl_take isl_space *model) +{ + build = isl_ast_build_cow(build); + if (!build) + goto error; + + build->domain = isl_set_align_params(build->domain, + isl_space_copy(model)); + build->generated = isl_set_align_params(build->generated, + isl_space_copy(model)); + build->pending = isl_set_align_params(build->pending, + isl_space_copy(model)); + build->values = isl_multi_aff_align_params(build->values, + isl_space_copy(model)); + build->offsets = isl_multi_aff_align_params(build->offsets, + isl_space_copy(model)); + build->options = isl_union_map_align_params(build->options, + isl_space_copy(model)); + if (build->internal2input) { + build->internal2input = + isl_multi_aff_align_params(build->internal2input, + model); + if (!build->internal2input) + return isl_ast_build_free(build); + } else { + isl_space_free(model); + } + + if (!build->domain || !build->values || !build->offsets || + !build->options) + return isl_ast_build_free(build); + + return build; +error: + isl_space_free(model); + return NULL; +} + +__isl_give isl_ast_build *isl_ast_build_cow(__isl_take isl_ast_build *build) +{ + if (!build) + return NULL; + + if (build->ref == 1) + return build; + build->ref--; + return isl_ast_build_dup(build); +} + +__isl_null isl_ast_build *isl_ast_build_free( + __isl_take isl_ast_build *build) +{ + if (!build) + return NULL; + + if (--build->ref > 0) + return NULL; + + isl_id_list_free(build->iterators); + isl_set_free(build->domain); + isl_set_free(build->generated); + isl_set_free(build->pending); + isl_multi_aff_free(build->values); + isl_multi_aff_free(build->internal2input); + isl_pw_aff_free(build->value); + isl_vec_free(build->strides); + isl_multi_aff_free(build->offsets); + isl_multi_aff_free(build->schedule_map); + isl_union_map_free(build->executed); + isl_union_map_free(build->options); + isl_schedule_node_free(build->node); + free(build->loop_type); + isl_set_free(build->isolated); + + free(build); + + return NULL; +} + +isl_ctx *isl_ast_build_get_ctx(__isl_keep isl_ast_build *build) +{ + return build ? isl_set_get_ctx(build->domain) : NULL; +} + +/* Replace build->options by "options". + */ +__isl_give isl_ast_build *isl_ast_build_set_options( + __isl_take isl_ast_build *build, __isl_take isl_union_map *options) +{ + build = isl_ast_build_cow(build); + + if (!build || !options) + goto error; + + isl_union_map_free(build->options); + build->options = options; + + return build; +error: + isl_union_map_free(options); + return isl_ast_build_free(build); +} + +/* Set the iterators for the next code generation. + * + * If we still have some iterators left from the previous code generation + * (if any) or if iterators have already been set by a previous + * call to this function, then we remove them first. + */ +__isl_give isl_ast_build *isl_ast_build_set_iterators( + __isl_take isl_ast_build *build, __isl_take isl_id_list *iterators) +{ + isl_size dim, n_it; + + build = isl_ast_build_cow(build); + if (!build) + goto error; + + dim = isl_ast_build_dim(build, isl_dim_set); + n_it = isl_id_list_n_id(build->iterators); + if (dim < 0 || n_it < 0) + goto error; + if (n_it < dim) + isl_die(isl_ast_build_get_ctx(build), isl_error_internal, + "isl_ast_build in inconsistent state", goto error); + if (n_it > dim) + build->iterators = isl_id_list_drop(build->iterators, + dim, n_it - dim); + build->iterators = isl_id_list_concat(build->iterators, iterators); + if (!build->iterators) + return isl_ast_build_free(build); + + return build; +error: + isl_id_list_free(iterators); + return isl_ast_build_free(build); +} + +/* Set the "at_each_domain" callback of "build" to "fn". + */ +__isl_give isl_ast_build *isl_ast_build_set_at_each_domain( + __isl_take isl_ast_build *build, + __isl_give isl_ast_node *(*fn)(__isl_take isl_ast_node *node, + __isl_keep isl_ast_build *build, void *user), void *user) +{ + build = isl_ast_build_cow(build); + + if (!build) + return NULL; + + build->at_each_domain = fn; + build->at_each_domain_user = user; + + return build; +} + +/* Set the "before_each_for" callback of "build" to "fn". + */ +__isl_give isl_ast_build *isl_ast_build_set_before_each_for( + __isl_take isl_ast_build *build, + __isl_give isl_id *(*fn)(__isl_keep isl_ast_build *build, + void *user), void *user) +{ + build = isl_ast_build_cow(build); + + if (!build) + return NULL; + + build->before_each_for = fn; + build->before_each_for_user = user; + + return build; +} + +/* Set the "after_each_for" callback of "build" to "fn". + */ +__isl_give isl_ast_build *isl_ast_build_set_after_each_for( + __isl_take isl_ast_build *build, + __isl_give isl_ast_node *(*fn)(__isl_take isl_ast_node *node, + __isl_keep isl_ast_build *build, void *user), void *user) +{ + build = isl_ast_build_cow(build); + + if (!build) + return NULL; + + build->after_each_for = fn; + build->after_each_for_user = user; + + return build; +} + +/* Set the "before_each_mark" callback of "build" to "fn". + */ +__isl_give isl_ast_build *isl_ast_build_set_before_each_mark( + __isl_take isl_ast_build *build, + isl_stat (*fn)(__isl_keep isl_id *mark, __isl_keep isl_ast_build *build, + void *user), void *user) +{ + build = isl_ast_build_cow(build); + + if (!build) + return NULL; + + build->before_each_mark = fn; + build->before_each_mark_user = user; + + return build; +} + +/* Set the "after_each_mark" callback of "build" to "fn". + */ +__isl_give isl_ast_build *isl_ast_build_set_after_each_mark( + __isl_take isl_ast_build *build, + __isl_give isl_ast_node *(*fn)(__isl_take isl_ast_node *node, + __isl_keep isl_ast_build *build, void *user), void *user) +{ + build = isl_ast_build_cow(build); + + if (!build) + return NULL; + + build->after_each_mark = fn; + build->after_each_mark_user = user; + + return build; +} + +/* Set the "create_leaf" callback of "build" to "fn". + */ +__isl_give isl_ast_build *isl_ast_build_set_create_leaf( + __isl_take isl_ast_build *build, + __isl_give isl_ast_node *(*fn)(__isl_take isl_ast_build *build, + void *user), void *user) +{ + build = isl_ast_build_cow(build); + + if (!build) + return NULL; + + build->create_leaf = fn; + build->create_leaf_user = user; + + return build; +} + +/* Clear all information that is specific to this code generation + * and that is (probably) not meaningful to any nested code generation. + */ +__isl_give isl_ast_build *isl_ast_build_clear_local_info( + __isl_take isl_ast_build *build) +{ + isl_space *space; + + build = isl_ast_build_cow(build); + if (!build) + return NULL; + + space = isl_union_map_get_space(build->options); + isl_union_map_free(build->options); + build->options = isl_union_map_empty(space); + + build->at_each_domain = NULL; + build->at_each_domain_user = NULL; + build->before_each_for = NULL; + build->before_each_for_user = NULL; + build->after_each_for = NULL; + build->after_each_for_user = NULL; + build->before_each_mark = NULL; + build->before_each_mark_user = NULL; + build->after_each_mark = NULL; + build->after_each_mark_user = NULL; + build->create_leaf = NULL; + build->create_leaf_user = NULL; + + if (!build->options) + return isl_ast_build_free(build); + + return build; +} + +/* Have any loops been eliminated? + * That is, do any of the original schedule dimensions have a fixed + * value that has been substituted? + */ +static int any_eliminated(isl_ast_build *build) +{ + int i; + + for (i = 0; i < build->depth; ++i) + if (isl_ast_build_has_affine_value(build, i)) + return 1; + + return 0; +} + +/* Clear build->schedule_map. + * This function should be called whenever anything that might affect + * the result of isl_ast_build_get_schedule_map_multi_aff changes. + * In particular, it should be called when the depth is changed or + * when an iterator is determined to have a fixed value. + */ +static void isl_ast_build_reset_schedule_map(__isl_keep isl_ast_build *build) +{ + if (!build) + return; + isl_multi_aff_free(build->schedule_map); + build->schedule_map = NULL; +} + +/* Do we need a (non-trivial) schedule map? + * That is, is the internal schedule space different from + * the external schedule space? + * + * The internal and external schedule spaces are only the same + * if code has been generated for the entire schedule and if none + * of the loops have been eliminated. + */ +isl_bool isl_ast_build_need_schedule_map(__isl_keep isl_ast_build *build) +{ + isl_size dim; + + dim = isl_ast_build_dim(build, isl_dim_set); + if (dim < 0) + return isl_bool_error; + return isl_bool_ok(build->depth != dim || any_eliminated(build)); +} + +/* Return a mapping from the internal schedule space to the external + * schedule space in the form of an isl_multi_aff. + * The internal schedule space originally corresponds to that of the + * input schedule. This may change during the code generation if + * if isl_ast_build_insert_dim is ever called. + * The external schedule space corresponds to the + * loops that have been generated. + * + * Currently, the only difference between the internal schedule domain + * and the external schedule domain is that some dimensions are projected + * out in the external schedule domain. In particular, the dimensions + * for which no code has been generated yet and the dimensions that correspond + * to eliminated loops. + * + * We cache a copy of the schedule_map in build->schedule_map. + * The cache is cleared through isl_ast_build_reset_schedule_map + * whenever anything changes that might affect the result of this function. + */ +__isl_give isl_multi_aff *isl_ast_build_get_schedule_map_multi_aff( + __isl_keep isl_ast_build *build) +{ + isl_bool needs_map; + isl_space *space; + isl_multi_aff *ma; + + if (!build) + return NULL; + if (build->schedule_map) + return isl_multi_aff_copy(build->schedule_map); + needs_map = isl_ast_build_need_schedule_map(build); + if (needs_map < 0) + return NULL; + + space = isl_ast_build_get_space(build, 1); + space = isl_space_map_from_set(space); + ma = isl_multi_aff_identity(space); + if (needs_map) { + int i; + isl_size dim = isl_ast_build_dim(build, isl_dim_set); + + if (dim < 0) + ma = isl_multi_aff_free(ma); + ma = isl_multi_aff_drop_dims(ma, isl_dim_out, + build->depth, dim - build->depth); + for (i = build->depth - 1; i >= 0; --i) + if (isl_ast_build_has_affine_value(build, i)) + ma = isl_multi_aff_drop_dims(ma, + isl_dim_out, i, 1); + } + + build->schedule_map = ma; + return isl_multi_aff_copy(build->schedule_map); +} + +/* Return a mapping from the internal schedule space to the external + * schedule space in the form of an isl_map. + */ +__isl_give isl_map *isl_ast_build_get_schedule_map( + __isl_keep isl_ast_build *build) +{ + isl_multi_aff *ma; + + ma = isl_ast_build_get_schedule_map_multi_aff(build); + return isl_map_from_multi_aff(ma); +} + +/* Return the position of the dimension in build->domain for which + * an AST node is currently being generated. + */ +isl_size isl_ast_build_get_depth(__isl_keep isl_ast_build *build) +{ + return build ? build->depth : isl_size_error; +} + +/* Prepare for generating code for the next level. + * In particular, increase the depth and reset any information + * that is local to the current depth. + */ +__isl_give isl_ast_build *isl_ast_build_increase_depth( + __isl_take isl_ast_build *build) +{ + build = isl_ast_build_cow(build); + if (!build) + return NULL; + build->depth++; + isl_ast_build_reset_schedule_map(build); + build->value = isl_pw_aff_free(build->value); + return build; +} + +void isl_ast_build_dump(__isl_keep isl_ast_build *build) +{ + if (!build) + return; + + fprintf(stderr, "domain: "); + isl_set_dump(build->domain); + fprintf(stderr, "generated: "); + isl_set_dump(build->generated); + fprintf(stderr, "pending: "); + isl_set_dump(build->pending); + fprintf(stderr, "iterators: "); + isl_id_list_dump(build->iterators); + fprintf(stderr, "values: "); + isl_multi_aff_dump(build->values); + if (build->value) { + fprintf(stderr, "value: "); + isl_pw_aff_dump(build->value); + } + fprintf(stderr, "strides: "); + isl_vec_dump(build->strides); + fprintf(stderr, "offsets: "); + isl_multi_aff_dump(build->offsets); + fprintf(stderr, "internal2input: "); + isl_multi_aff_dump(build->internal2input); +} + +/* Initialize "build" for AST construction in schedule space "space" + * in the case that build->domain is a parameter set. + * + * build->iterators is assumed to have been updated already. + */ +static __isl_give isl_ast_build *isl_ast_build_init( + __isl_take isl_ast_build *build, __isl_take isl_space *space) +{ + isl_set *set; + + build = isl_ast_build_cow(build); + if (!build) + goto error; + + set = isl_set_universe(isl_space_copy(space)); + build->domain = isl_set_intersect_params(isl_set_copy(set), + build->domain); + build->pending = isl_set_intersect_params(isl_set_copy(set), + build->pending); + build->generated = isl_set_intersect_params(set, build->generated); + + return isl_ast_build_init_derived(build, space); +error: + isl_ast_build_free(build); + isl_space_free(space); + return NULL; +} + +/* Assign "aff" to *user and return -1, effectively extracting + * the first (and presumably only) affine expression in the isl_pw_aff + * on which this function is used. + */ +static isl_stat extract_single_piece(__isl_take isl_set *set, + __isl_take isl_aff *aff, void *user) +{ + isl_aff **p = user; + + *p = aff; + isl_set_free(set); + + return isl_stat_error; +} + +/* Intersect "set" with the stride constraint of "build", if any. + */ +static __isl_give isl_set *intersect_stride_constraint(__isl_take isl_set *set, + __isl_keep isl_ast_build *build) +{ + isl_set *stride; + + if (!build) + return isl_set_free(set); + if (!isl_ast_build_has_stride(build, build->depth)) + return set; + + stride = isl_ast_build_get_stride_constraint(build); + return isl_set_intersect(set, stride); +} + +/* Check if the given bounds on the current dimension (together with + * the stride constraint, if any) imply that + * this current dimension attains only a single value (in terms of + * parameters and outer dimensions). + * If so, we record it in build->value. + * If, moreover, this value can be represented as a single affine expression, + * then we also update build->values, effectively marking the current + * dimension as "eliminated". + * + * When computing the gist of the fixed value that can be represented + * as a single affine expression, it is important to only take into + * account the domain constraints in the original AST build and + * not the domain of the affine expression itself. + * Otherwise, a [i/3] is changed into a i/3 because we know that i + * is a multiple of 3, but then we end up not expressing anywhere + * in the context that i is a multiple of 3. + */ +static __isl_give isl_ast_build *update_values( + __isl_take isl_ast_build *build, __isl_take isl_basic_set *bounds) +{ + isl_bool sv; + isl_size n; + isl_pw_multi_aff *pma; + isl_aff *aff = NULL; + isl_map *it_map; + isl_set *set; + + set = isl_set_from_basic_set(bounds); + set = isl_set_intersect(set, isl_set_copy(build->domain)); + set = intersect_stride_constraint(set, build); + it_map = isl_ast_build_map_to_iterator(build, set); + + sv = isl_map_is_single_valued(it_map); + if (sv < 0) + build = isl_ast_build_free(build); + if (!build || !sv) { + isl_map_free(it_map); + return build; + } + + pma = isl_pw_multi_aff_from_map(it_map); + build->value = isl_pw_multi_aff_get_pw_aff(pma, 0); + build->value = isl_ast_build_compute_gist_pw_aff(build, build->value); + build->value = isl_pw_aff_coalesce(build->value); + isl_pw_multi_aff_free(pma); + + n = isl_pw_aff_n_piece(build->value); + if (n < 0) + return isl_ast_build_free(build); + if (n != 1) + return build; + + isl_pw_aff_foreach_piece(build->value, &extract_single_piece, &aff); + + build->values = isl_multi_aff_set_aff(build->values, build->depth, aff); + if (!build->values) + return isl_ast_build_free(build); + isl_ast_build_reset_schedule_map(build); + return build; +} + +/* Update the AST build based on the given loop bounds for + * the current dimension and the stride information available in the build. + * + * We first make sure that the bounds do not refer to any iterators + * that have already been eliminated. + * Then, we check if the bounds imply that the current iterator + * has a fixed value. + * If they do and if this fixed value can be expressed as a single + * affine expression, we eliminate the iterators from the bounds. + * Note that we cannot simply plug in this single value using + * isl_basic_set_preimage_multi_aff as the single value may only + * be defined on a subset of the domain. Plugging in the value + * would restrict the build domain to this subset, while this + * restriction may not be reflected in the generated code. + * Finally, we intersect build->domain with the updated bounds. + * We also add the stride constraint unless we have been able + * to find a fixed value expressed as a single affine expression. + * + * Note that the check for a fixed value in update_values requires + * us to intersect the bounds with the current build domain. + * When we intersect build->domain with the updated bounds in + * the final step, we make sure that these updated bounds have + * not been intersected with the old build->domain. + * Otherwise, we would indirectly intersect the build domain with itself, + * which can lead to inefficiencies, in particular if the build domain + * contains any unknown divs. + * + * The pending and generated sets are not updated by this function to + * match the updated domain. + * The caller still needs to call isl_ast_build_set_pending_generated. + */ +__isl_give isl_ast_build *isl_ast_build_set_loop_bounds( + __isl_take isl_ast_build *build, __isl_take isl_basic_set *bounds) +{ + isl_set *set; + + build = isl_ast_build_cow(build); + if (!build) + goto error; + + build = update_values(build, isl_basic_set_copy(bounds)); + if (!build) + goto error; + set = isl_set_from_basic_set(isl_basic_set_copy(bounds)); + if (isl_ast_build_has_affine_value(build, build->depth)) { + set = isl_set_eliminate(set, isl_dim_set, build->depth, 1); + set = isl_set_compute_divs(set); + build->pending = isl_set_intersect(build->pending, + isl_set_copy(set)); + build->domain = isl_set_intersect(build->domain, set); + } else { + build->domain = isl_set_intersect(build->domain, set); + build = isl_ast_build_include_stride(build); + if (!build) + goto error; + } + isl_basic_set_free(bounds); + + if (!build->domain || !build->pending || !build->generated) + return isl_ast_build_free(build); + + return build; +error: + isl_ast_build_free(build); + isl_basic_set_free(bounds); + return NULL; +} + +/* Update the pending and generated sets of "build" according to "bounds". + * If the build has an affine value at the current depth, + * then isl_ast_build_set_loop_bounds has already set the pending set. + * Otherwise, do it here. + */ +__isl_give isl_ast_build *isl_ast_build_set_pending_generated( + __isl_take isl_ast_build *build, __isl_take isl_basic_set *bounds) +{ + isl_basic_set *generated, *pending; + + if (!build) + goto error; + + if (isl_ast_build_has_affine_value(build, build->depth)) { + isl_basic_set_free(bounds); + return build; + } + + build = isl_ast_build_cow(build); + if (!build) + goto error; + + pending = isl_basic_set_copy(bounds); + pending = isl_basic_set_drop_constraints_involving_dims(pending, + isl_dim_set, build->depth, 1); + build->pending = isl_set_intersect(build->pending, + isl_set_from_basic_set(pending)); + generated = bounds; + generated = isl_basic_set_drop_constraints_not_involving_dims( + generated, isl_dim_set, build->depth, 1); + build->generated = isl_set_intersect(build->generated, + isl_set_from_basic_set(generated)); + + if (!build->pending || !build->generated) + return isl_ast_build_free(build); + + return build; +error: + isl_ast_build_free(build); + isl_basic_set_free(bounds); + return NULL; +} + +/* Intersect build->domain with "set", where "set" is specified + * in terms of the internal schedule domain. + */ +static __isl_give isl_ast_build *isl_ast_build_restrict_internal( + __isl_take isl_ast_build *build, __isl_take isl_set *set) +{ + build = isl_ast_build_cow(build); + if (!build) + goto error; + + set = isl_set_compute_divs(set); + build->domain = isl_set_intersect(build->domain, set); + build->domain = isl_set_coalesce(build->domain); + + if (!build->domain) + return isl_ast_build_free(build); + + return build; +error: + isl_ast_build_free(build); + isl_set_free(set); + return NULL; +} + +/* Intersect build->generated and build->domain with "set", + * where "set" is specified in terms of the internal schedule domain. + */ +__isl_give isl_ast_build *isl_ast_build_restrict_generated( + __isl_take isl_ast_build *build, __isl_take isl_set *set) +{ + set = isl_set_compute_divs(set); + build = isl_ast_build_restrict_internal(build, isl_set_copy(set)); + build = isl_ast_build_cow(build); + if (!build) + goto error; + + build->generated = isl_set_intersect(build->generated, set); + build->generated = isl_set_coalesce(build->generated); + + if (!build->generated) + return isl_ast_build_free(build); + + return build; +error: + isl_ast_build_free(build); + isl_set_free(set); + return NULL; +} + +/* Replace the set of pending constraints by "guard", which is then + * no longer considered as pending. + * That is, add "guard" to the generated constraints and clear all pending + * constraints, making the domain equal to the generated constraints. + */ +__isl_give isl_ast_build *isl_ast_build_replace_pending_by_guard( + __isl_take isl_ast_build *build, __isl_take isl_set *guard) +{ + build = isl_ast_build_restrict_generated(build, guard); + build = isl_ast_build_cow(build); + if (!build) + return NULL; + + isl_set_free(build->domain); + build->domain = isl_set_copy(build->generated); + isl_set_free(build->pending); + build->pending = isl_set_universe(isl_set_get_space(build->domain)); + + if (!build->pending) + return isl_ast_build_free(build); + + return build; +} + +/* Intersect build->domain with "set", where "set" is specified + * in terms of the external schedule domain. + */ +__isl_give isl_ast_build *isl_ast_build_restrict( + __isl_take isl_ast_build *build, __isl_take isl_set *set) +{ + isl_bool needs_map; + + if (isl_set_is_params(set)) + return isl_ast_build_restrict_generated(build, set); + + needs_map = isl_ast_build_need_schedule_map(build); + if (needs_map < 0) + goto error; + if (needs_map) { + isl_multi_aff *ma; + ma = isl_ast_build_get_schedule_map_multi_aff(build); + set = isl_set_preimage_multi_aff(set, ma); + } + return isl_ast_build_restrict_generated(build, set); +error: + isl_ast_build_free(build); + isl_set_free(set); + return NULL; +} + +/* Replace build->executed by "executed". + */ +__isl_give isl_ast_build *isl_ast_build_set_executed( + __isl_take isl_ast_build *build, __isl_take isl_union_map *executed) +{ + build = isl_ast_build_cow(build); + if (!build) + goto error; + + isl_union_map_free(build->executed); + build->executed = executed; + + return build; +error: + isl_ast_build_free(build); + isl_union_map_free(executed); + return NULL; +} + +/* Does "build" point to a band node? + * That is, are we currently handling a band node inside a schedule tree? + */ +int isl_ast_build_has_schedule_node(__isl_keep isl_ast_build *build) +{ + if (!build) + return -1; + return build->node != NULL; +} + +/* Return a copy of the band node that "build" refers to. + */ +__isl_give isl_schedule_node *isl_ast_build_get_schedule_node( + __isl_keep isl_ast_build *build) +{ + if (!build) + return NULL; + return isl_schedule_node_copy(build->node); +} + +/* Extract the loop AST generation types for the members of build->node + * and store them in build->loop_type. + */ +static __isl_give isl_ast_build *extract_loop_types( + __isl_take isl_ast_build *build) +{ + int i; + isl_size n; + isl_ctx *ctx; + isl_schedule_node *node; + + if (!build) + return NULL; + n = isl_schedule_node_band_n_member(build->node); + if (n < 0) + return isl_ast_build_free(build); + ctx = isl_ast_build_get_ctx(build); + if (!build->node) + isl_die(ctx, isl_error_internal, "missing AST node", + return isl_ast_build_free(build)); + + free(build->loop_type); + build->n = n; + build->loop_type = isl_alloc_array(ctx, + enum isl_ast_loop_type, build->n); + if (build->n && !build->loop_type) + return isl_ast_build_free(build); + node = build->node; + for (i = 0; i < build->n; ++i) + build->loop_type[i] = + isl_schedule_node_band_member_get_ast_loop_type(node, i); + + return build; +} + +/* Replace the band node that "build" refers to by "node" and + * extract the corresponding loop AST generation types. + */ +__isl_give isl_ast_build *isl_ast_build_set_schedule_node( + __isl_take isl_ast_build *build, + __isl_take isl_schedule_node *node) +{ + build = isl_ast_build_cow(build); + if (!build || !node) + goto error; + + isl_schedule_node_free(build->node); + build->node = node; + + build = extract_loop_types(build); + + return build; +error: + isl_ast_build_free(build); + isl_schedule_node_free(node); + return NULL; +} + +/* Remove any reference to a band node from "build". + */ +__isl_give isl_ast_build *isl_ast_build_reset_schedule_node( + __isl_take isl_ast_build *build) +{ + build = isl_ast_build_cow(build); + if (!build) + return NULL; + + isl_schedule_node_free(build->node); + build->node = NULL; + + return build; +} + +/* Return a copy of the current schedule domain. + */ +__isl_give isl_set *isl_ast_build_get_domain(__isl_keep isl_ast_build *build) +{ + return build ? isl_set_copy(build->domain) : NULL; +} + +/* Return a copy of the set of pending constraints. + */ +__isl_give isl_set *isl_ast_build_get_pending( + __isl_keep isl_ast_build *build) +{ + return build ? isl_set_copy(build->pending) : NULL; +} + +/* Return a copy of the set of generated constraints. + */ +__isl_give isl_set *isl_ast_build_get_generated( + __isl_keep isl_ast_build *build) +{ + return build ? isl_set_copy(build->generated) : NULL; +} + +/* Return a copy of the map from the internal schedule domain + * to the original input schedule domain. + */ +__isl_give isl_multi_aff *isl_ast_build_get_internal2input( + __isl_keep isl_ast_build *build) +{ + return build ? isl_multi_aff_copy(build->internal2input) : NULL; +} + +/* Return the number of variables of the given type + * in the (internal) schedule space. + */ +isl_size isl_ast_build_dim(__isl_keep isl_ast_build *build, + enum isl_dim_type type) +{ + if (!build) + return isl_size_error; + return isl_set_dim(build->domain, type); +} + +/* Return the (schedule) space of "build". + * + * If "internal" is set, then this space is the space of the internal + * representation of the entire schedule, including those parts for + * which no code has been generated yet. + * + * If "internal" is not set, then this space is the external representation + * of the loops generated so far. + */ +__isl_give isl_space *isl_ast_build_get_space(__isl_keep isl_ast_build *build, + int internal) +{ + int i; + isl_size dim; + isl_bool needs_map; + isl_space *space; + + if (!build) + return NULL; + + space = isl_set_get_space(build->domain); + if (internal) + return space; + + needs_map = isl_ast_build_need_schedule_map(build); + if (needs_map < 0) + return isl_space_free(space); + if (!needs_map) + return space; + + dim = isl_ast_build_dim(build, isl_dim_set); + if (dim < 0) + return isl_space_free(space); + space = isl_space_drop_dims(space, isl_dim_set, + build->depth, dim - build->depth); + 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; +} + +/* Return the external representation of the schedule space of "build", + * i.e., a space with a dimension for each loop generated so far, + * with the names of the dimensions set to the loop iterators. + */ +__isl_give isl_space *isl_ast_build_get_schedule_space( + __isl_keep isl_ast_build *build) +{ + isl_space *space; + int i, skip; + + if (!build) + return NULL; + + space = isl_ast_build_get_space(build, 0); + + skip = 0; + for (i = 0; i < build->depth; ++i) { + isl_id *id; + + if (isl_ast_build_has_affine_value(build, i)) { + skip++; + continue; + } + + id = isl_ast_build_get_iterator_id(build, i); + space = isl_space_set_dim_id(space, isl_dim_set, i - skip, id); + } + + return space; +} + +/* Return the current schedule, as stored in build->executed, in terms + * of the external schedule domain. + */ +__isl_give isl_union_map *isl_ast_build_get_schedule( + __isl_keep isl_ast_build *build) +{ + isl_bool needs_map; + isl_union_map *executed; + isl_union_map *schedule; + + needs_map = isl_ast_build_need_schedule_map(build); + if (needs_map < 0) + return NULL; + + executed = isl_union_map_copy(build->executed); + if (needs_map) { + isl_map *proj = isl_ast_build_get_schedule_map(build); + executed = isl_union_map_apply_domain(executed, + isl_union_map_from_map(proj)); + } + schedule = isl_union_map_reverse(executed); + + return schedule; +} + +/* Return the iterator attached to the internal schedule dimension "pos". + */ +__isl_give isl_id *isl_ast_build_get_iterator_id( + __isl_keep isl_ast_build *build, int pos) +{ + if (!build) + return NULL; + + return isl_id_list_get_id(build->iterators, pos); +} + +/* Set the stride and offset of the current dimension to the given + * value and expression. + */ +static __isl_give isl_ast_build *set_stride(__isl_take isl_ast_build *build, + __isl_take isl_val *stride, __isl_take isl_aff *offset) +{ + int pos; + + build = isl_ast_build_cow(build); + if (!build || !stride || !offset) + goto error; + + pos = build->depth; + + 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) + return isl_ast_build_free(build); + + return build; +error: + isl_val_free(stride); + isl_aff_free(offset); + return isl_ast_build_free(build); +} + +/* Return a set expressing the stride constraint at the current depth. + * + * In particular, if the current iterator (i) is known to attain values + * + * f + s a + * + * where f is the offset and s is the stride, then the returned set + * expresses the constraint + * + * (f - i) mod s = 0 + */ +__isl_give isl_set *isl_ast_build_get_stride_constraint( + __isl_keep isl_ast_build *build) +{ + isl_aff *aff; + isl_set *set; + isl_val *stride; + int pos; + + if (!build) + return NULL; + + pos = build->depth; + + if (!isl_ast_build_has_stride(build, pos)) + return isl_set_universe(isl_ast_build_get_space(build, 1)); + + stride = isl_ast_build_get_stride(build, pos); + aff = isl_ast_build_get_offset(build, pos); + aff = isl_aff_add_coefficient_si(aff, isl_dim_in, pos, -1); + aff = isl_aff_mod_val(aff, stride); + set = isl_set_from_basic_set(isl_aff_zero_basic_set(aff)); + + return set; +} + +/* Return the expansion implied by the stride and offset at the current + * depth. + * + * That is, return the mapping + * + * [i_0, ..., i_{d-1}, i_d, i_{d+1}, ...] + * -> [i_0, ..., i_{d-1}, s * i_d + offset(i), i_{d+1}, ...] + * + * where s is the stride at the current depth d and offset(i) is + * the corresponding offset. + */ +__isl_give isl_multi_aff *isl_ast_build_get_stride_expansion( + __isl_keep isl_ast_build *build) +{ + isl_space *space; + isl_multi_aff *ma; + isl_size pos; + isl_aff *aff, *offset; + isl_val *stride; + + pos = isl_ast_build_get_depth(build); + if (pos < 0) + return NULL; + + space = isl_ast_build_get_space(build, 1); + space = isl_space_map_from_set(space); + ma = isl_multi_aff_identity(space); + + if (!isl_ast_build_has_stride(build, pos)) + return ma; + + offset = isl_ast_build_get_offset(build, pos); + stride = isl_ast_build_get_stride(build, pos); + aff = isl_multi_aff_get_aff(ma, pos); + aff = isl_aff_scale_val(aff, stride); + aff = isl_aff_add(aff, offset); + ma = isl_multi_aff_set_aff(ma, pos, aff); + + return ma; +} + +/* Add constraints corresponding to any previously detected + * stride on the current dimension to build->domain. + */ +__isl_give isl_ast_build *isl_ast_build_include_stride( + __isl_take isl_ast_build *build) +{ + isl_set *set; + + if (!build) + return NULL; + if (!isl_ast_build_has_stride(build, build->depth)) + return build; + build = isl_ast_build_cow(build); + if (!build) + return NULL; + + set = isl_ast_build_get_stride_constraint(build); + + build->domain = isl_set_intersect(build->domain, isl_set_copy(set)); + build->generated = isl_set_intersect(build->generated, set); + if (!build->domain || !build->generated) + return isl_ast_build_free(build); + + return build; +} + +/* 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 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_size pos; + isl_bool no_stride; + isl_val *stride; + isl_aff *offset; + isl_stride_info *si; + + pos = isl_ast_build_get_depth(build); + if (pos < 0) + goto error; + + 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); + + 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; +} + +/* Does "map" not involve the input dimension data->depth? + */ +static isl_bool free_of_depth(__isl_keep isl_map *map, void *user) +{ + int *depth = user; + + return isl_bool_not(isl_map_involves_dims(map, isl_dim_in, *depth, 1)); +} + +/* Do any options depend on the value of the dimension at the current depth? + */ +int isl_ast_build_options_involve_depth(__isl_keep isl_ast_build *build) +{ + isl_bool free; + + if (!build) + return -1; + + free = isl_union_map_every_map(build->options, &free_of_depth, + &build->depth); + return isl_bool_not(free); +} + +/* Construct the map + * + * { [i] -> [i] : i < pos; [i] -> [i + 1] : i >= pos } + * + * with "space" the parameter space of the constructed map. + */ +static __isl_give isl_map *construct_insertion_map(__isl_take isl_space *space, + int pos) +{ + isl_constraint *c; + isl_basic_map *bmap1, *bmap2; + + space = isl_space_set_from_params(space); + space = isl_space_add_dims(space, isl_dim_set, 1); + space = isl_space_map_from_set(space); + c = isl_constraint_alloc_equality(isl_local_space_from_space(space)); + c = isl_constraint_set_coefficient_si(c, isl_dim_in, 0, 1); + c = isl_constraint_set_coefficient_si(c, isl_dim_out, 0, -1); + bmap1 = isl_basic_map_from_constraint(isl_constraint_copy(c)); + c = isl_constraint_set_constant_si(c, 1); + bmap2 = isl_basic_map_from_constraint(c); + + bmap1 = isl_basic_map_upper_bound_si(bmap1, isl_dim_in, 0, pos - 1); + bmap2 = isl_basic_map_lower_bound_si(bmap2, isl_dim_in, 0, pos); + + return isl_basic_map_union(bmap1, bmap2); +} + +static const char *option_str[] = { + [isl_ast_loop_atomic] = "atomic", + [isl_ast_loop_unroll] = "unroll", + [isl_ast_loop_separate] = "separate" +}; + +/* Update the "options" to reflect the insertion of a dimension + * at position "pos" in the schedule domain space. + * "space" is the original domain space before the insertion and + * may be named and/or structured. + * + * The (relevant) input options all have "space" as domain, which + * has to be mapped to the extended space. + * The values of the ranges also refer to the schedule domain positions + * and they therefore also need to be adjusted. In particular, values + * smaller than pos do not need to change, while values greater than or + * equal to pos need to be incremented. + * That is, we need to apply the following map. + * + * { atomic[i] -> atomic[i] : i < pos; [i] -> [i + 1] : i >= pos; + * unroll[i] -> unroll[i] : i < pos; [i] -> [i + 1] : i >= pos; + * separate[i] -> separate[i] : i < pos; [i] -> [i + 1] : i >= pos; + * separation_class[[i] -> [c]] + * -> separation_class[[i] -> [c]] : i < pos; + * separation_class[[i] -> [c]] + * -> separation_class[[i + 1] -> [c]] : i >= pos } + */ +static __isl_give isl_union_map *options_insert_dim( + __isl_take isl_union_map *options, __isl_take isl_space *space, int pos) +{ + isl_map *map; + isl_union_map *insertion; + enum isl_ast_loop_type type; + const char *name = "separation_class"; + + space = isl_space_map_from_set(space); + map = isl_map_identity(space); + map = isl_map_insert_dims(map, isl_dim_out, pos, 1); + options = isl_union_map_apply_domain(options, + isl_union_map_from_map(map)); + + if (!options) + return NULL; + + map = construct_insertion_map(isl_union_map_get_space(options), pos); + + insertion = isl_union_map_empty(isl_union_map_get_space(options)); + + for (type = isl_ast_loop_atomic; + type <= isl_ast_loop_separate; ++type) { + isl_map *map_type = isl_map_copy(map); + const char *name = option_str[type]; + map_type = isl_map_set_tuple_name(map_type, isl_dim_in, name); + map_type = isl_map_set_tuple_name(map_type, isl_dim_out, name); + insertion = isl_union_map_add_map(insertion, map_type); + } + + map = isl_map_product(map, isl_map_identity(isl_map_get_space(map))); + map = isl_map_set_tuple_name(map, isl_dim_in, name); + map = isl_map_set_tuple_name(map, isl_dim_out, name); + insertion = isl_union_map_add_map(insertion, map); + + options = isl_union_map_apply_range(options, insertion); + + return options; +} + +/* If we are generating an AST from a schedule tree (build->node is set), + * then update the loop AST generation types + * to reflect the insertion of a dimension at (global) position "pos" + * in the schedule domain space. + * We do not need to adjust any isolate option since we would not be inserting + * any dimensions if there were any isolate option. + */ +static __isl_give isl_ast_build *node_insert_dim( + __isl_take isl_ast_build *build, int pos) +{ + int i; + int local_pos; + enum isl_ast_loop_type *loop_type; + isl_ctx *ctx; + + build = isl_ast_build_cow(build); + if (!build) + return NULL; + if (!build->node) + return build; + + ctx = isl_ast_build_get_ctx(build); + local_pos = pos - build->outer_pos; + loop_type = isl_realloc_array(ctx, build->loop_type, + enum isl_ast_loop_type, build->n + 1); + if (!loop_type) + return isl_ast_build_free(build); + build->loop_type = loop_type; + for (i = build->n - 1; i >= local_pos; --i) + loop_type[i + 1] = loop_type[i]; + loop_type[local_pos] = isl_ast_loop_default; + build->n++; + + return build; +} + +/* Insert a single dimension in the schedule domain at position "pos". + * The new dimension is given an isl_id with the empty string as name. + * + * The main difficulty is updating build->options to reflect the + * extra dimension. This is handled in options_insert_dim. + * + * Note that because of the dimension manipulations, the resulting + * schedule domain space will always be unnamed and unstructured. + * However, the original schedule domain space may be named and/or + * structured, so we have to take this possibility into account + * while performing the transformations. + * + * Since the inserted schedule dimension is used by the caller + * to differentiate between different domain spaces, there is + * no longer a uniform mapping from the internal schedule space + * to the input schedule space. The internal2input mapping is + * therefore removed. + */ +__isl_give isl_ast_build *isl_ast_build_insert_dim( + __isl_take isl_ast_build *build, int pos) +{ + isl_ctx *ctx; + isl_space *space, *ma_space; + isl_id *id; + isl_multi_aff *ma; + + build = isl_ast_build_cow(build); + if (!build) + return NULL; + + ctx = isl_ast_build_get_ctx(build); + id = isl_id_alloc(ctx, "", NULL); + if (!build->node) + space = isl_ast_build_get_space(build, 1); + build->iterators = isl_id_list_insert(build->iterators, pos, id); + build->domain = isl_set_insert_dims(build->domain, + isl_dim_set, pos, 1); + build->generated = isl_set_insert_dims(build->generated, + isl_dim_set, pos, 1); + build->pending = isl_set_insert_dims(build->pending, + isl_dim_set, pos, 1); + build->strides = isl_vec_insert_els(build->strides, pos, 1); + build->strides = isl_vec_set_element_si(build->strides, pos, 1); + ma_space = isl_space_params(isl_multi_aff_get_space(build->offsets)); + ma_space = isl_space_set_from_params(ma_space); + ma_space = isl_space_add_dims(ma_space, isl_dim_set, 1); + ma_space = isl_space_map_from_set(ma_space); + ma = isl_multi_aff_zero(isl_space_copy(ma_space)); + build->offsets = isl_multi_aff_splice(build->offsets, pos, pos, ma); + ma = isl_multi_aff_identity(ma_space); + build->values = isl_multi_aff_splice(build->values, pos, pos, ma); + if (!build->node) + build->options = options_insert_dim(build->options, space, pos); + build->internal2input = isl_multi_aff_free(build->internal2input); + + if (!build->iterators || !build->domain || !build->generated || + !build->pending || !build->values || + !build->strides || !build->offsets || !build->options) + return isl_ast_build_free(build); + + build = node_insert_dim(build, pos); + + return build; +} + +/* Scale down the current dimension by a factor of "m". + * "umap" is an isl_union_map that implements the scaling down. + * That is, it is of the form + * + * { [.... i ....] -> [.... i' ....] : i = m i' } + * + * This function is called right after the strides have been + * detected, but before any constraints on the current dimension + * have been included in build->domain. + * We therefore only need to update stride, offset, the options and + * the mapping from internal schedule space to the original schedule + * space, if we are still keeping track of such a mapping. + * The latter mapping is updated by plugging in + * { [... i ...] -> [... m i ... ] }. + */ +__isl_give isl_ast_build *isl_ast_build_scale_down( + __isl_take isl_ast_build *build, __isl_take isl_val *m, + __isl_take isl_union_map *umap) +{ + isl_aff *aff; + isl_val *v; + int depth; + + build = isl_ast_build_cow(build); + if (!build || !umap || !m) + goto error; + + depth = build->depth; + + if (build->internal2input) { + isl_space *space; + isl_multi_aff *ma; + isl_aff *aff; + + space = isl_multi_aff_get_space(build->internal2input); + space = isl_space_map_from_set(isl_space_domain(space)); + ma = isl_multi_aff_identity(space); + aff = isl_multi_aff_get_aff(ma, depth); + aff = isl_aff_scale_val(aff, isl_val_copy(m)); + ma = isl_multi_aff_set_aff(ma, depth, aff); + build->internal2input = + isl_multi_aff_pullback_multi_aff(build->internal2input, ma); + if (!build->internal2input) + goto error; + } + + v = isl_vec_get_element_val(build->strides, depth); + v = isl_val_div(v, isl_val_copy(m)); + build->strides = isl_vec_set_element_val(build->strides, depth, v); + + aff = isl_multi_aff_get_aff(build->offsets, depth); + aff = isl_aff_scale_down_val(aff, m); + build->offsets = isl_multi_aff_set_aff(build->offsets, depth, aff); + build->options = isl_union_map_apply_domain(build->options, umap); + if (!build->strides || !build->offsets || !build->options) + return isl_ast_build_free(build); + + return build; +error: + isl_val_free(m); + isl_union_map_free(umap); + return isl_ast_build_free(build); +} + +/* Return a list of "n" isl_ids called "c%d", with "%d" starting at "first". + * If an isl_id with such a name already appears among the parameters + * in build->domain, then adjust the name to "c%d_%d". + */ +static __isl_give isl_id_list *generate_names(isl_ctx *ctx, int n, int first, + __isl_keep isl_ast_build *build) +{ + int i; + isl_id_list *names; + + names = isl_id_list_alloc(ctx, n); + for (i = 0; i < n; ++i) { + isl_id *id; + + id = generate_name(ctx, first + i, build); + names = isl_id_list_add(names, id); + } + + return names; +} + +/* Embed "options" into the given isl_ast_build space. + * + * This function is called from within a nested call to + * isl_ast_build_node_from_schedule_map. + * "options" refers to the additional schedule, + * while space refers to both the space of the outer isl_ast_build and + * that of the additional schedule. + * Specifically, space is of the form + * + * [I -> S] + * + * while options lives in the space(s) + * + * S -> * + * + * We compute + * + * [I -> S] -> S + * + * and compose this with options, to obtain the new options + * living in the space(s) + * + * [I -> S] -> * + */ +static __isl_give isl_union_map *embed_options( + __isl_take isl_union_map *options, __isl_take isl_space *space) +{ + isl_map *map; + + map = isl_map_universe(isl_space_unwrap(space)); + map = isl_map_range_map(map); + + options = isl_union_map_apply_range( + isl_union_map_from_map(map), options); + + return options; +} + +/* Update "build" for use in a (possibly nested) code generation. That is, + * extend "build" from an AST build on some domain O to an AST build + * on domain [O -> S], with S corresponding to "space". + * If the original domain is a parameter domain, then the new domain is + * simply S. + * "iterators" is a list of iterators for S, but the number of elements + * may be smaller or greater than the number of set dimensions of S. + * If "keep_iterators" is set, then any extra ids in build->iterators + * are reused for S. Otherwise, these extra ids are dropped. + * + * We first update build->outer_pos to the current depth. + * This depth is zero in case this is the outermost code generation. + * + * We then add additional ids such that the number of iterators is at least + * equal to the dimension of the new build domain. + * + * If the original domain is parametric, then we are constructing + * an isl_ast_build for the outer code generation and we pass control + * to isl_ast_build_init. + * + * Otherwise, we adjust the fields of "build" to include "space". + */ +__isl_give isl_ast_build *isl_ast_build_product( + __isl_take isl_ast_build *build, __isl_take isl_space *space) +{ + isl_ctx *ctx; + isl_vec *strides; + isl_set *set; + isl_multi_aff *embedding; + isl_size dim, space_dim, n_it; + + build = isl_ast_build_cow(build); + if (!build) + goto error; + + build->outer_pos = build->depth; + + ctx = isl_ast_build_get_ctx(build); + dim = isl_ast_build_dim(build, isl_dim_set); + space_dim = isl_space_dim(space, isl_dim_set); + n_it = isl_id_list_n_id(build->iterators); + if (dim < 0 || space_dim < 0 || n_it < 0) + goto error; + dim += space_dim; + if (n_it < dim) { + isl_id_list *l; + l = generate_names(ctx, dim - n_it, n_it, build); + build->iterators = isl_id_list_concat(build->iterators, l); + } + + if (isl_set_is_params(build->domain)) + return isl_ast_build_init(build, space); + + set = isl_set_universe(isl_space_copy(space)); + build->domain = isl_set_product(build->domain, isl_set_copy(set)); + build->pending = isl_set_product(build->pending, isl_set_copy(set)); + build->generated = isl_set_product(build->generated, set); + + strides = isl_vec_alloc(ctx, space_dim); + strides = isl_vec_set_si(strides, 1); + build->strides = isl_vec_concat(build->strides, strides); + + space = isl_space_map_from_set(space); + build->offsets = isl_multi_aff_align_params(build->offsets, + isl_space_copy(space)); + build->offsets = isl_multi_aff_product(build->offsets, + isl_multi_aff_zero(isl_space_copy(space))); + build->values = isl_multi_aff_align_params(build->values, + isl_space_copy(space)); + embedding = isl_multi_aff_identity(space); + build->values = isl_multi_aff_product(build->values, + isl_multi_aff_copy(embedding)); + if (build->internal2input) { + build->internal2input = + isl_multi_aff_product(build->internal2input, embedding); + build->internal2input = + isl_multi_aff_flatten_range(build->internal2input); + if (!build->internal2input) + return isl_ast_build_free(build); + } else { + isl_multi_aff_free(embedding); + } + + space = isl_ast_build_get_space(build, 1); + build->options = embed_options(build->options, space); + + if (!build->iterators || !build->domain || !build->generated || + !build->pending || !build->values || + !build->strides || !build->offsets || !build->options) + return isl_ast_build_free(build); + + return build; +error: + isl_ast_build_free(build); + isl_space_free(space); + return NULL; +} + +/* Does "aff" only attain non-negative values over build->domain? + * That is, does it not attain any negative values? + */ +isl_bool isl_ast_build_aff_is_nonneg(__isl_keep isl_ast_build *build, + __isl_keep isl_aff *aff) +{ + isl_set *test; + isl_bool empty; + + if (!build) + return isl_bool_error; + + aff = isl_aff_copy(aff); + test = isl_set_from_basic_set(isl_aff_neg_basic_set(aff)); + test = isl_set_intersect(test, isl_set_copy(build->domain)); + empty = isl_set_is_empty(test); + isl_set_free(test); + + return empty; +} + +/* Does the dimension at (internal) position "pos" have a non-trivial stride? + */ +isl_bool isl_ast_build_has_stride(__isl_keep isl_ast_build *build, int pos) +{ + isl_val *v; + isl_bool has_stride; + + if (!build) + return isl_bool_error; + + v = isl_vec_get_element_val(build->strides, pos); + has_stride = isl_bool_not(isl_val_is_one(v)); + isl_val_free(v); + + return has_stride; +} + +/* Given that the dimension at position "pos" takes on values + * + * f + s a + * + * with a an integer, return s. + */ +__isl_give isl_val *isl_ast_build_get_stride(__isl_keep isl_ast_build *build, + int pos) +{ + if (!build) + return NULL; + + return isl_vec_get_element_val(build->strides, pos); +} + +/* Given that the dimension at position "pos" takes on values + * + * f + s a + * + * with a an integer, return f. + */ +__isl_give isl_aff *isl_ast_build_get_offset( + __isl_keep isl_ast_build *build, int pos) +{ + if (!build) + return NULL; + + return isl_multi_aff_get_aff(build->offsets, pos); +} + +/* Is the dimension at position "pos" known to attain only a single + * value that, moreover, can be described by a single affine expression + * in terms of the outer dimensions and parameters? + * + * If not, then the corresponding affine expression in build->values + * is set to be equal to the same input dimension. + * Otherwise, it is set to the requested expression in terms of + * outer dimensions and parameters. + */ +isl_bool isl_ast_build_has_affine_value(__isl_keep isl_ast_build *build, + int pos) +{ + isl_aff *aff; + isl_bool involves; + + if (!build) + 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); + + return isl_bool_not(involves); +} + +/* Plug in the known values (fixed affine expressions in terms of + * parameters and outer loop iterators) of all loop iterators + * in the domain of "umap". + * + * We simply precompose "umap" with build->values. + */ +__isl_give isl_union_map *isl_ast_build_substitute_values_union_map_domain( + __isl_keep isl_ast_build *build, __isl_take isl_union_map *umap) +{ + isl_multi_aff *values; + + if (!build) + return isl_union_map_free(umap); + + values = isl_multi_aff_copy(build->values); + umap = isl_union_map_preimage_domain_multi_aff(umap, values); + + return umap; +} + +/* Is the current dimension known to attain only a single value? + */ +int isl_ast_build_has_value(__isl_keep isl_ast_build *build) +{ + if (!build) + return -1; + + return build->value != NULL; +} + +/* Simplify the basic set "bset" based on what we know about + * the iterators of already generated loops. + * + * "bset" is assumed to live in the (internal) schedule domain. + */ +__isl_give isl_basic_set *isl_ast_build_compute_gist_basic_set( + __isl_keep isl_ast_build *build, __isl_take isl_basic_set *bset) +{ + if (!build) + goto error; + + bset = isl_basic_set_preimage_multi_aff(bset, + isl_multi_aff_copy(build->values)); + bset = isl_basic_set_gist(bset, + isl_set_simple_hull(isl_set_copy(build->domain))); + + return bset; +error: + isl_basic_set_free(bset); + return NULL; +} + +/* Simplify the set "set" based on what we know about + * the iterators of already generated loops. + * + * "set" is assumed to live in the (internal) schedule domain. + */ +__isl_give isl_set *isl_ast_build_compute_gist( + __isl_keep isl_ast_build *build, __isl_take isl_set *set) +{ + if (!build) + goto error; + + if (!isl_set_is_params(set)) + set = isl_set_preimage_multi_aff(set, + isl_multi_aff_copy(build->values)); + set = isl_set_gist(set, isl_set_copy(build->domain)); + + return set; +error: + isl_set_free(set); + return NULL; +} + +/* Include information about what we know about the iterators of + * already generated loops to "set". + * + * We currently only plug in the known affine values of outer loop + * iterators. + * In principle we could also introduce equalities or even other + * constraints implied by the intersection of "set" and build->domain. + */ +__isl_give isl_set *isl_ast_build_specialize(__isl_keep isl_ast_build *build, + __isl_take isl_set *set) +{ + if (!build) + return isl_set_free(set); + + return isl_set_preimage_multi_aff(set, + isl_multi_aff_copy(build->values)); +} + +/* Plug in the known affine values of outer loop iterators in "bset". + */ +__isl_give isl_basic_set *isl_ast_build_specialize_basic_set( + __isl_keep isl_ast_build *build, __isl_take isl_basic_set *bset) +{ + if (!build) + return isl_basic_set_free(bset); + + return isl_basic_set_preimage_multi_aff(bset, + isl_multi_aff_copy(build->values)); +} + +/* Simplify the map "map" based on what we know about + * the iterators of already generated loops. + * + * The domain of "map" is assumed to live in the (internal) schedule domain. + */ +__isl_give isl_map *isl_ast_build_compute_gist_map_domain( + __isl_keep isl_ast_build *build, __isl_take isl_map *map) +{ + if (!build) + goto error; + + map = isl_map_gist_domain(map, isl_set_copy(build->domain)); + + return map; +error: + isl_map_free(map); + return NULL; +} + +/* Simplify the affine expression "aff" based on what we know about + * the iterators of already generated loops. + * + * The domain of "aff" is assumed to live in the (internal) schedule domain. + */ +__isl_give isl_aff *isl_ast_build_compute_gist_aff( + __isl_keep isl_ast_build *build, __isl_take isl_aff *aff) +{ + if (!build) + goto error; + + aff = isl_aff_gist(aff, isl_set_copy(build->domain)); + + return aff; +error: + isl_aff_free(aff); + return NULL; +} + +/* Simplify the piecewise affine expression "aff" based on what we know about + * the iterators of already generated loops. + * + * The domain of "pa" is assumed to live in the (internal) schedule domain. + */ +__isl_give isl_pw_aff *isl_ast_build_compute_gist_pw_aff( + __isl_keep isl_ast_build *build, __isl_take isl_pw_aff *pa) +{ + if (!build) + goto error; + + if (!isl_set_is_params(build->domain)) + pa = isl_pw_aff_pullback_multi_aff(pa, + isl_multi_aff_copy(build->values)); + pa = isl_pw_aff_gist(pa, isl_set_copy(build->domain)); + + return pa; +error: + isl_pw_aff_free(pa); + return NULL; +} + +/* Simplify the piecewise multi-affine expression "aff" based on what + * we know about the iterators of already generated loops. + * + * The domain of "pma" is assumed to live in the (internal) schedule domain. + */ +__isl_give isl_pw_multi_aff *isl_ast_build_compute_gist_pw_multi_aff( + __isl_keep isl_ast_build *build, __isl_take isl_pw_multi_aff *pma) +{ + if (!build) + goto error; + + pma = isl_pw_multi_aff_pullback_multi_aff(pma, + isl_multi_aff_copy(build->values)); + pma = isl_pw_multi_aff_gist(pma, isl_set_copy(build->domain)); + + return pma; +error: + isl_pw_multi_aff_free(pma); + return NULL; +} + +/* Extract the schedule domain of the given type from build->options + * at the current depth. + * + * In particular, find the subset of build->options that is of + * the following form + * + * schedule_domain -> type[depth] + * + * and return the corresponding domain, after eliminating inner dimensions + * and divs that depend on the current dimension. + * + * Note that the domain of build->options has been reformulated + * in terms of the internal build space in embed_options, + * but the position is still that within the current code generation. + */ +__isl_give isl_set *isl_ast_build_get_option_domain( + __isl_keep isl_ast_build *build, enum isl_ast_loop_type type) +{ + const char *name; + isl_space *space; + isl_map *option; + isl_set *domain; + int local_pos; + + if (!build) + return NULL; + + name = option_str[type]; + local_pos = build->depth - build->outer_pos; + + space = isl_ast_build_get_space(build, 1); + space = isl_space_from_domain(space); + space = isl_space_add_dims(space, isl_dim_out, 1); + space = isl_space_set_tuple_name(space, isl_dim_out, name); + + option = isl_union_map_extract_map(build->options, space); + option = isl_map_fix_si(option, isl_dim_out, 0, local_pos); + + domain = isl_map_domain(option); + domain = isl_ast_build_eliminate(build, domain); + + return domain; +} + +/* How does the user want the current schedule dimension to be generated? + * These choices have been extracted from the schedule node + * in extract_loop_types and stored in build->loop_type. + * They have been updated to reflect any dimension insertion in + * node_insert_dim. + * Return isl_ast_domain_error on error. + * + * If "isolated" is set, then we get the loop AST generation type + * directly from the band node since node_insert_dim cannot have been + * called on a band with the isolate option. + */ +enum isl_ast_loop_type isl_ast_build_get_loop_type( + __isl_keep isl_ast_build *build, int isolated) +{ + int local_pos; + isl_ctx *ctx; + + if (!build) + return isl_ast_loop_error; + ctx = isl_ast_build_get_ctx(build); + if (!build->node) + isl_die(ctx, isl_error_internal, + "only works for schedule tree based AST generation", + return isl_ast_loop_error); + + local_pos = build->depth - build->outer_pos; + if (!isolated) + return build->loop_type[local_pos]; + return isl_schedule_node_band_member_get_isolate_ast_loop_type( + build->node, local_pos); +} + +/* Extract the isolated set from the isolate option, if any, + * and store in the build. + * If there is no isolate option, then the isolated set is + * set to the empty set. + * + * The isolate option is of the form + * + * isolate[[outer bands] -> current_band] + * + * We flatten this set and then map it back to the internal + * schedule space. + * + * If we have already extracted the isolated set + * or if internal2input is no longer set, then we do not + * need to do anything. In the latter case, we know + * that the current band cannot have any isolate option. + */ +__isl_give isl_ast_build *isl_ast_build_extract_isolated( + __isl_take isl_ast_build *build) +{ + isl_set *isolated; + + if (!build) + return NULL; + if (!build->internal2input) + return build; + if (build->isolated) + return build; + + build = isl_ast_build_cow(build); + if (!build) + return NULL; + + isolated = isl_schedule_node_band_get_ast_isolate_option(build->node); + isolated = isl_set_flatten(isolated); + isolated = isl_set_preimage_multi_aff(isolated, + isl_multi_aff_copy(build->internal2input)); + + build->isolated = isolated; + if (!build->isolated) + return isl_ast_build_free(build); + + return build; +} + +/* Does "build" have a non-empty isolated set? + * + * The caller is assumed to have called isl_ast_build_extract_isolated first. + */ +int isl_ast_build_has_isolated(__isl_keep isl_ast_build *build) +{ + int empty; + + if (!build) + return -1; + if (!build->internal2input) + return 0; + if (!build->isolated) + isl_die(isl_ast_build_get_ctx(build), isl_error_internal, + "isolated set not extracted yet", return -1); + + empty = isl_set_plain_is_empty(build->isolated); + return empty < 0 ? -1 : !empty; +} + +/* Return a copy of the isolated set of "build". + * + * The caller is assume to have called isl_ast_build_has_isolated first, + * with this function returning true. + * In particular, this function should not be called if we are no + * longer keeping track of internal2input (and there therefore could + * not possibly be any isolated set). + */ +__isl_give isl_set *isl_ast_build_get_isolated(__isl_keep isl_ast_build *build) +{ + if (!build) + return NULL; + if (!build->internal2input) + isl_die(isl_ast_build_get_ctx(build), isl_error_internal, + "build cannot have isolated set", return NULL); + + return isl_set_copy(build->isolated); +} + +/* Extract the separation class mapping at the current depth. + * + * In particular, find and return the subset of build->options that is of + * the following form + * + * schedule_domain -> separation_class[[depth] -> [class]] + * + * The caller is expected to eliminate inner dimensions from the domain. + * + * Note that the domain of build->options has been reformulated + * in terms of the internal build space in embed_options, + * but the position is still that within the current code generation. + */ +__isl_give isl_map *isl_ast_build_get_separation_class( + __isl_keep isl_ast_build *build) +{ + isl_ctx *ctx; + isl_space *space_sep, *space; + isl_map *res; + int local_pos; + + if (!build) + return NULL; + + local_pos = build->depth - build->outer_pos; + ctx = isl_ast_build_get_ctx(build); + space_sep = isl_space_alloc(ctx, 0, 1, 1); + space_sep = isl_space_wrap(space_sep); + space_sep = isl_space_set_tuple_name(space_sep, isl_dim_set, + "separation_class"); + space = isl_ast_build_get_space(build, 1); + space_sep = isl_space_align_params(space_sep, isl_space_copy(space)); + space = isl_space_map_from_domain_and_range(space, space_sep); + + res = isl_union_map_extract_map(build->options, space); + res = isl_map_fix_si(res, isl_dim_out, 0, local_pos); + res = isl_map_coalesce(res); + + return res; +} + +/* Eliminate dimensions inner to the current dimension. + */ +__isl_give isl_set *isl_ast_build_eliminate_inner( + __isl_keep isl_ast_build *build, __isl_take isl_set *set) +{ + int dim; + int depth; + + if (!build) + return isl_set_free(set); + + dim = isl_set_dim(set, isl_dim_set); + depth = build->depth; + set = isl_set_detect_equalities(set); + set = isl_set_eliminate(set, isl_dim_set, depth + 1, dim - (depth + 1)); + + return set; +} + +/* Eliminate unknown divs and divs that depend on the current dimension. + * + * Note that during the elimination of unknown divs, we may discover + * an explicit representation of some other unknown divs, which may + * depend on the current dimension. We therefore need to eliminate + * unknown divs first. + */ +__isl_give isl_set *isl_ast_build_eliminate_divs( + __isl_keep isl_ast_build *build, __isl_take isl_set *set) +{ + int depth; + + if (!build) + return isl_set_free(set); + + set = isl_set_remove_unknown_divs(set); + depth = build->depth; + set = isl_set_remove_divs_involving_dims(set, isl_dim_set, depth, 1); + + return set; +} + +/* Eliminate dimensions inner to the current dimension as well as + * unknown divs and divs that depend on the current dimension. + * The result then consists only of constraints that are independent + * of the current dimension and upper and lower bounds on the current + * dimension. + */ +__isl_give isl_set *isl_ast_build_eliminate( + __isl_keep isl_ast_build *build, __isl_take isl_set *domain) +{ + domain = isl_ast_build_eliminate_inner(build, domain); + domain = isl_ast_build_eliminate_divs(build, domain); + return domain; +} + +/* Replace build->single_valued by "sv". + */ +__isl_give isl_ast_build *isl_ast_build_set_single_valued( + __isl_take isl_ast_build *build, int sv) +{ + if (!build) + return build; + if (build->single_valued == sv) + return build; + build = isl_ast_build_cow(build); + if (!build) + return build; + build->single_valued = sv; + + return build; +} diff --git a/external/mit/isl/dist/isl_ast_build_expr.c b/external/mit/isl/dist/isl_ast_build_expr.c new file mode 100644 index 000000000000..590fa6f5e5a5 --- /dev/null +++ b/external/mit/isl/dist/isl_ast_build_expr.c @@ -0,0 +1,2772 @@ +/* + * Copyright 2012-2014 Ecole Normale Superieure + * Copyright 2014 INRIA Rocquencourt + * + * Use of this software is governed by the MIT license + * + * Written by Sven Verdoolaege, + * Ecole Normale Superieure, 45 rue d’Ulm, 75230 Paris, France + * and Inria Paris - Rocquencourt, Domaine de Voluceau - Rocquencourt, + * B.P. 105 - 78153 Le Chesnay, France + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Compute the "opposite" of the (numerator of the) argument of a div + * with denominator "d". + * + * In particular, compute + * + * -aff + (d - 1) + */ +static __isl_give isl_aff *oppose_div_arg(__isl_take isl_aff *aff, + __isl_take isl_val *d) +{ + aff = isl_aff_neg(aff); + aff = isl_aff_add_constant_val(aff, d); + aff = isl_aff_add_constant_si(aff, -1); + + return aff; +} + +/* Internal data structure used inside isl_ast_expr_add_term. + * The domain of "build" is used to simplify the expressions. + * "build" needs to be set by the caller of isl_ast_expr_add_term. + * "ls" is the domain local space of the affine expression + * of which a term is being added. + * "cst" is the constant term of the expression in which the added term + * appears. It may be modified by isl_ast_expr_add_term. + * + * "v" is the coefficient of the term that is being constructed and + * is set internally by isl_ast_expr_add_term. + */ +struct isl_ast_add_term_data { + isl_ast_build *build; + isl_local_space *ls; + isl_val *cst; + isl_val *v; +}; + +/* Given the numerator "aff" of the argument of an integer division + * with denominator "d", check if it can be made non-negative over + * data->build->domain by stealing part of the constant term of + * the expression in which the integer division appears. + * + * In particular, the outer expression is of the form + * + * v * floor(aff/d) + cst + * + * We already know that "aff" itself may attain negative values. + * Here we check if aff + d*floor(cst/v) is non-negative, such + * that we could rewrite the expression to + * + * v * floor((aff + d*floor(cst/v))/d) + cst - v*floor(cst/v) + * + * Note that aff + d*floor(cst/v) can only possibly be non-negative + * if data->cst and data->v have the same sign. + * Similarly, if floor(cst/v) is zero, then there is no point in + * checking again. + */ +static isl_bool is_non_neg_after_stealing(__isl_keep isl_aff *aff, + __isl_keep isl_val *d, struct isl_ast_add_term_data *data) +{ + isl_aff *shifted; + isl_val *shift; + isl_bool is_zero; + isl_bool non_neg; + + if (isl_val_sgn(data->cst) != isl_val_sgn(data->v)) + return isl_bool_false; + + shift = isl_val_div(isl_val_copy(data->cst), isl_val_copy(data->v)); + shift = isl_val_floor(shift); + is_zero = isl_val_is_zero(shift); + if (is_zero < 0 || is_zero) { + isl_val_free(shift); + return isl_bool_not(is_zero); + } + shift = isl_val_mul(shift, isl_val_copy(d)); + shifted = isl_aff_copy(aff); + shifted = isl_aff_add_constant_val(shifted, shift); + non_neg = isl_ast_build_aff_is_nonneg(data->build, shifted); + isl_aff_free(shifted); + + return non_neg; +} + +/* Given the numerator "aff" of the argument of an integer division + * with denominator "d", steal part of the constant term of + * the expression in which the integer division appears to make it + * non-negative over data->build->domain. + * + * In particular, the outer expression is of the form + * + * v * floor(aff/d) + cst + * + * We know that "aff" itself may attain negative values, + * but that aff + d*floor(cst/v) is non-negative. + * Find the minimal positive value that we need to add to "aff" + * to make it positive and adjust data->cst accordingly. + * That is, compute the minimal value "m" of "aff" over + * data->build->domain and take + * + * s = ceil(-m/d) + * + * such that + * + * aff + d * s >= 0 + * + * and rewrite the expression to + * + * v * floor((aff + s*d)/d) + (cst - v*s) + */ +static __isl_give isl_aff *steal_from_cst(__isl_take isl_aff *aff, + __isl_keep isl_val *d, struct isl_ast_add_term_data *data) +{ + isl_set *domain; + isl_val *shift, *t; + + domain = isl_ast_build_get_domain(data->build); + shift = isl_set_min_val(domain, aff); + isl_set_free(domain); + + shift = isl_val_neg(shift); + shift = isl_val_div(shift, isl_val_copy(d)); + shift = isl_val_ceil(shift); + + t = isl_val_copy(shift); + t = isl_val_mul(t, isl_val_copy(data->v)); + data->cst = isl_val_sub(data->cst, t); + + shift = isl_val_mul(shift, isl_val_copy(d)); + return isl_aff_add_constant_val(aff, shift); +} + +/* Construct an expression representing the binary operation "type" + * (some division or modulo) applied to the expressions + * constructed from "aff" and "v". + */ +static __isl_give isl_ast_expr *div_mod(enum isl_ast_expr_op_type type, + __isl_take isl_aff *aff, __isl_take isl_val *v, + __isl_keep isl_ast_build *build) +{ + isl_ast_expr *expr1, *expr2; + + expr1 = isl_ast_expr_from_aff(aff, build); + expr2 = isl_ast_expr_from_val(v); + return isl_ast_expr_alloc_binary(type, expr1, expr2); +} + +/* Create an isl_ast_expr evaluating the div at position "pos" in data->ls. + * The result is simplified in terms of data->build->domain. + * This function may change (the sign of) data->v. + * + * data->ls is known to be non-NULL. + * + * Let the div be of the form floor(e/d). + * If the ast_build_prefer_pdiv option is set then we check if "e" + * is non-negative, so that we can generate + * + * (pdiv_q, expr(e), expr(d)) + * + * instead of + * + * (fdiv_q, expr(e), expr(d)) + * + * If the ast_build_prefer_pdiv option is set and + * if "e" is not non-negative, then we check if "-e + d - 1" is non-negative. + * If so, we can rewrite + * + * floor(e/d) = -ceil(-e/d) = -floor((-e + d - 1)/d) + * + * and still use pdiv_q, while changing the sign of data->v. + * + * Otherwise, we check if + * + * e + d*floor(cst/v) + * + * is non-negative and if so, replace floor(e/d) by + * + * floor((e + s*d)/d) - s + * + * with s the minimal shift that makes the argument non-negative. + */ +static __isl_give isl_ast_expr *var_div(struct isl_ast_add_term_data *data, + int pos) +{ + isl_ctx *ctx = isl_local_space_get_ctx(data->ls); + isl_aff *aff; + isl_val *d; + enum isl_ast_expr_op_type type; + + aff = isl_local_space_get_div(data->ls, pos); + d = isl_aff_get_denominator_val(aff); + aff = isl_aff_scale_val(aff, isl_val_copy(d)); + + type = isl_ast_expr_op_fdiv_q; + if (isl_options_get_ast_build_prefer_pdiv(ctx)) { + isl_bool non_neg; + non_neg = isl_ast_build_aff_is_nonneg(data->build, aff); + if (non_neg >= 0 && !non_neg) { + isl_aff *opp = oppose_div_arg(isl_aff_copy(aff), + isl_val_copy(d)); + non_neg = isl_ast_build_aff_is_nonneg(data->build, opp); + if (non_neg >= 0 && non_neg) { + data->v = isl_val_neg(data->v); + isl_aff_free(aff); + aff = opp; + } else + isl_aff_free(opp); + } + if (non_neg >= 0 && !non_neg) { + non_neg = is_non_neg_after_stealing(aff, d, data); + if (non_neg >= 0 && non_neg) + aff = steal_from_cst(aff, d, data); + } + if (non_neg < 0) + aff = isl_aff_free(aff); + else if (non_neg) + type = isl_ast_expr_op_pdiv_q; + } + + return div_mod(type, aff, d, data->build); +} + +/* Create an isl_ast_expr evaluating the specified dimension of data->ls. + * The result is simplified in terms of data->build->domain. + * This function may change (the sign of) data->v. + * + * The isl_ast_expr is constructed based on the type of the dimension. + * - divs are constructed by var_div + * - set variables are constructed from the iterator isl_ids in data->build + * - parameters are constructed from the isl_ids in data->ls + */ +static __isl_give isl_ast_expr *var(struct isl_ast_add_term_data *data, + enum isl_dim_type type, int pos) +{ + isl_ctx *ctx = isl_local_space_get_ctx(data->ls); + isl_id *id; + + if (type == isl_dim_div) + return var_div(data, pos); + + if (type == isl_dim_set) { + id = isl_ast_build_get_iterator_id(data->build, pos); + return isl_ast_expr_from_id(id); + } + + if (!isl_local_space_has_dim_id(data->ls, type, pos)) + isl_die(ctx, isl_error_internal, "unnamed dimension", + return NULL); + id = isl_local_space_get_dim_id(data->ls, type, pos); + return isl_ast_expr_from_id(id); +} + +/* Does "expr" represent the zero integer? + */ +static isl_bool ast_expr_is_zero(__isl_keep isl_ast_expr *expr) +{ + if (!expr) + return isl_bool_error; + if (expr->type != isl_ast_expr_int) + return isl_bool_false; + return isl_val_is_zero(expr->u.v); +} + +/* Create an expression representing the sum of "expr1" and "expr2", + * provided neither of the two expressions is identically zero. + */ +static __isl_give isl_ast_expr *ast_expr_add(__isl_take isl_ast_expr *expr1, + __isl_take isl_ast_expr *expr2) +{ + if (!expr1 || !expr2) + goto error; + + if (ast_expr_is_zero(expr1)) { + isl_ast_expr_free(expr1); + return expr2; + } + + if (ast_expr_is_zero(expr2)) { + isl_ast_expr_free(expr2); + return expr1; + } + + return isl_ast_expr_add(expr1, expr2); +error: + isl_ast_expr_free(expr1); + isl_ast_expr_free(expr2); + return NULL; +} + +/* Subtract expr2 from expr1. + * + * If expr2 is zero, we simply return expr1. + * If expr1 is zero, we return + * + * (isl_ast_expr_op_minus, expr2) + * + * Otherwise, we return + * + * (isl_ast_expr_op_sub, expr1, expr2) + */ +static __isl_give isl_ast_expr *ast_expr_sub(__isl_take isl_ast_expr *expr1, + __isl_take isl_ast_expr *expr2) +{ + if (!expr1 || !expr2) + goto error; + + if (ast_expr_is_zero(expr2)) { + isl_ast_expr_free(expr2); + return expr1; + } + + if (ast_expr_is_zero(expr1)) { + isl_ast_expr_free(expr1); + return isl_ast_expr_neg(expr2); + } + + return isl_ast_expr_sub(expr1, expr2); +error: + isl_ast_expr_free(expr1); + isl_ast_expr_free(expr2); + return NULL; +} + +/* Return an isl_ast_expr that represents + * + * v * (aff mod d) + * + * v is assumed to be non-negative. + * The result is simplified in terms of build->domain. + */ +static __isl_give isl_ast_expr *isl_ast_expr_mod(__isl_keep isl_val *v, + __isl_keep isl_aff *aff, __isl_keep isl_val *d, + __isl_keep isl_ast_build *build) +{ + isl_ast_expr *expr; + isl_ast_expr *c; + + if (!aff) + return NULL; + + expr = div_mod(isl_ast_expr_op_pdiv_r, + isl_aff_copy(aff), isl_val_copy(d), build); + + if (!isl_val_is_one(v)) { + c = isl_ast_expr_from_val(isl_val_copy(v)); + expr = isl_ast_expr_mul(c, expr); + } + + return expr; +} + +/* Create an isl_ast_expr that scales "expr" by "v". + * + * If v is 1, we simply return expr. + * If v is -1, we return + * + * (isl_ast_expr_op_minus, expr) + * + * Otherwise, we return + * + * (isl_ast_expr_op_mul, expr(v), expr) + */ +static __isl_give isl_ast_expr *scale(__isl_take isl_ast_expr *expr, + __isl_take isl_val *v) +{ + isl_ast_expr *c; + + if (!expr || !v) + goto error; + if (isl_val_is_one(v)) { + isl_val_free(v); + return expr; + } + + if (isl_val_is_negone(v)) { + isl_val_free(v); + expr = isl_ast_expr_neg(expr); + } else { + c = isl_ast_expr_from_val(v); + expr = isl_ast_expr_mul(c, expr); + } + + return expr; +error: + isl_val_free(v); + isl_ast_expr_free(expr); + return NULL; +} + +/* Add an expression for "*v" times the specified dimension of data->ls + * to expr. + * If the dimension is an integer division, then this function + * may modify data->cst in order to make the numerator non-negative. + * The result is simplified in terms of data->build->domain. + * + * Let e be the expression for the specified dimension, + * multiplied by the absolute value of "*v". + * If "*v" is negative, we create + * + * (isl_ast_expr_op_sub, expr, e) + * + * except when expr is trivially zero, in which case we create + * + * (isl_ast_expr_op_minus, e) + * + * instead. + * + * If "*v" is positive, we simply create + * + * (isl_ast_expr_op_add, expr, e) + * + */ +static __isl_give isl_ast_expr *isl_ast_expr_add_term( + __isl_take isl_ast_expr *expr, enum isl_dim_type type, int pos, + __isl_take isl_val *v, struct isl_ast_add_term_data *data) +{ + isl_ast_expr *term; + + if (!expr) + return NULL; + + data->v = v; + term = var(data, type, pos); + v = data->v; + + if (isl_val_is_neg(v) && !ast_expr_is_zero(expr)) { + v = isl_val_neg(v); + term = scale(term, v); + return ast_expr_sub(expr, term); + } else { + term = scale(term, v); + return ast_expr_add(expr, term); + } +} + +/* Add an expression for "v" to expr. + */ +static __isl_give isl_ast_expr *isl_ast_expr_add_int( + __isl_take isl_ast_expr *expr, __isl_take isl_val *v) +{ + isl_ast_expr *expr_int; + + if (!expr || !v) + goto error; + + if (isl_val_is_zero(v)) { + isl_val_free(v); + return expr; + } + + if (isl_val_is_neg(v) && !ast_expr_is_zero(expr)) { + v = isl_val_neg(v); + expr_int = isl_ast_expr_from_val(v); + return ast_expr_sub(expr, expr_int); + } else { + expr_int = isl_ast_expr_from_val(v); + return ast_expr_add(expr, expr_int); + } +error: + isl_ast_expr_free(expr); + isl_val_free(v); + return NULL; +} + +/* Internal data structure used inside extract_modulos. + * + * If any modulo expressions are detected in "aff", then the + * expression is removed from "aff" and added to either "pos" or "neg" + * depending on the sign of the coefficient of the modulo expression + * inside "aff". + * + * "add" is an expression that needs to be added to "aff" at the end of + * the computation. It is NULL as long as no modulos have been extracted. + * + * "i" is the position in "aff" of the div under investigation + * "v" is the coefficient in "aff" of the div + * "div" is the argument of the div, with the denominator removed + * "d" is the original denominator of the argument of the div + * + * "nonneg" is an affine expression that is non-negative over "build" + * and that can be used to extract a modulo expression from "div". + * In particular, if "sign" is 1, then the coefficients of "nonneg" + * are equal to those of "div" modulo "d". If "sign" is -1, then + * the coefficients of "nonneg" are opposite to those of "div" modulo "d". + * If "sign" is 0, then no such affine expression has been found (yet). + */ +struct isl_extract_mod_data { + isl_ast_build *build; + isl_aff *aff; + + isl_ast_expr *pos; + isl_ast_expr *neg; + + isl_aff *add; + + int i; + isl_val *v; + isl_val *d; + isl_aff *div; + + isl_aff *nonneg; + int sign; +}; + +/* Does + * + * arg mod data->d + * + * represent (a special case of) a test for some linear expression + * being even? + * + * In particular, is it of the form + * + * (lin - 1) mod 2 + * + * ? + */ +static isl_bool is_even_test(struct isl_extract_mod_data *data, + __isl_keep isl_aff *arg) +{ + isl_bool res; + isl_val *cst; + + res = isl_val_eq_si(data->d, 2); + if (res < 0 || !res) + return res; + + cst = isl_aff_get_constant_val(arg); + res = isl_val_eq_si(cst, -1); + isl_val_free(cst); + + return res; +} + +/* Given that data->v * div_i in data->aff is equal to + * + * f * (term - (arg mod d)) + * + * with data->d * f = data->v and "arg" non-negative on data->build, add + * + * f * term + * + * to data->add and + * + * abs(f) * (arg mod d) + * + * to data->neg or data->pos depending on the sign of -f. + * + * In the special case that "arg mod d" is of the form "(lin - 1) mod 2", + * with "lin" some linear expression, first replace + * + * f * (term - ((lin - 1) mod 2)) + * + * by + * + * -f * (1 - term - (lin mod 2)) + * + * These two are equal because + * + * ((lin - 1) mod 2) + (lin mod 2) = 1 + * + * Also, if "lin - 1" is non-negative, then "lin" is non-negative too. + */ +static isl_stat extract_term_and_mod(struct isl_extract_mod_data *data, + __isl_take isl_aff *term, __isl_take isl_aff *arg) +{ + isl_bool even; + isl_ast_expr *expr; + int s; + + even = is_even_test(data, arg); + if (even < 0) { + arg = isl_aff_free(arg); + } else if (even) { + term = oppose_div_arg(term, isl_val_copy(data->d)); + data->v = isl_val_neg(data->v); + arg = isl_aff_set_constant_si(arg, 0); + } + + data->v = isl_val_div(data->v, isl_val_copy(data->d)); + s = isl_val_sgn(data->v); + data->v = isl_val_abs(data->v); + expr = isl_ast_expr_mod(data->v, arg, data->d, data->build); + isl_aff_free(arg); + if (s > 0) + data->neg = ast_expr_add(data->neg, expr); + else + data->pos = ast_expr_add(data->pos, expr); + data->aff = isl_aff_set_coefficient_si(data->aff, + isl_dim_div, data->i, 0); + if (s < 0) + data->v = isl_val_neg(data->v); + term = isl_aff_scale_val(term, isl_val_copy(data->v)); + + if (!data->add) + data->add = term; + else + data->add = isl_aff_add(data->add, term); + if (!data->add) + return isl_stat_error; + + return isl_stat_ok; +} + +/* Given that data->v * div_i in data->aff is of the form + * + * f * d * floor(div/d) + * + * with div nonnegative on data->build, rewrite it as + * + * f * (div - (div mod d)) = f * div - f * (div mod d) + * + * and add + * + * f * div + * + * to data->add and + * + * abs(f) * (div mod d) + * + * to data->neg or data->pos depending on the sign of -f. + */ +static isl_stat extract_mod(struct isl_extract_mod_data *data) +{ + return extract_term_and_mod(data, isl_aff_copy(data->div), + isl_aff_copy(data->div)); +} + +/* Given that data->v * div_i in data->aff is of the form + * + * f * d * floor(div/d) (1) + * + * check if div is non-negative on data->build and, if so, + * extract the corresponding modulo from data->aff. + * If not, then check if + * + * -div + d - 1 + * + * is non-negative on data->build. If so, replace (1) by + * + * -f * d * floor((-div + d - 1)/d) + * + * and extract the corresponding modulo from data->aff. + * + * This function may modify data->div. + */ +static isl_stat extract_nonneg_mod(struct isl_extract_mod_data *data) +{ + isl_bool mod; + + mod = isl_ast_build_aff_is_nonneg(data->build, data->div); + if (mod < 0) + goto error; + if (mod) + return extract_mod(data); + + data->div = oppose_div_arg(data->div, isl_val_copy(data->d)); + mod = isl_ast_build_aff_is_nonneg(data->build, data->div); + if (mod < 0) + goto error; + if (mod) { + data->v = isl_val_neg(data->v); + return extract_mod(data); + } + + return isl_stat_ok; +error: + data->aff = isl_aff_free(data->aff); + return isl_stat_error; +} + +/* Is the affine expression of constraint "c" "simpler" than data->nonneg + * for use in extracting a modulo expression? + * + * We currently only consider the constant term of the affine expression. + * In particular, we prefer the affine expression with the smallest constant + * term. + * This means that if there are two constraints, say x >= 0 and -x + 10 >= 0, + * then we would pick x >= 0 + * + * More detailed heuristics could be used if it turns out that there is a need. + */ +static int mod_constraint_is_simpler(struct isl_extract_mod_data *data, + __isl_keep isl_constraint *c) +{ + isl_val *v1, *v2; + int simpler; + + if (!data->nonneg) + return 1; + + v1 = isl_val_abs(isl_constraint_get_constant_val(c)); + v2 = isl_val_abs(isl_aff_get_constant_val(data->nonneg)); + simpler = isl_val_lt(v1, v2); + isl_val_free(v1); + isl_val_free(v2); + + return simpler; +} + +/* Check if the coefficients of "c" are either equal or opposite to those + * of data->div modulo data->d. If so, and if "c" is "simpler" than + * data->nonneg, then replace data->nonneg by the affine expression of "c" + * and set data->sign accordingly. + * + * Both "c" and data->div are assumed not to involve any integer divisions. + * + * Before we start the actual comparison, we first quickly check if + * "c" and data->div have the same non-zero coefficients. + * If not, then we assume that "c" is not of the desired form. + * Note that while the coefficients of data->div can be reasonably expected + * not to involve any coefficients that are multiples of d, "c" may + * very well involve such coefficients. This means that we may actually + * miss some cases. + * + * If the constant term is "too large", then the constraint is rejected, + * where "too large" is fairly arbitrarily set to 1 << 15. + * We do this to avoid picking up constraints that bound a variable + * by a very large number, say the largest or smallest possible + * variable in the representation of some integer type. + */ +static isl_stat check_parallel_or_opposite(__isl_take isl_constraint *c, + void *user) +{ + struct isl_extract_mod_data *data = user; + enum isl_dim_type c_type[2] = { isl_dim_param, isl_dim_set }; + enum isl_dim_type a_type[2] = { isl_dim_param, isl_dim_in }; + int i, t; + isl_size n[2]; + isl_bool parallel = isl_bool_true, opposite = isl_bool_true; + + for (t = 0; t < 2; ++t) { + n[t] = isl_constraint_dim(c, c_type[t]); + if (n[t] < 0) + goto error; + for (i = 0; i < n[t]; ++i) { + isl_bool a, b; + + a = isl_constraint_involves_dims(c, c_type[t], i, 1); + b = isl_aff_involves_dims(data->div, a_type[t], i, 1); + if (a < 0 || b < 0) + goto error; + if (a != b) + parallel = opposite = isl_bool_false; + } + } + + if (parallel || opposite) { + isl_val *v; + + v = isl_val_abs(isl_constraint_get_constant_val(c)); + if (isl_val_cmp_si(v, 1 << 15) > 0) + parallel = opposite = isl_bool_false; + isl_val_free(v); + } + + for (t = 0; t < 2; ++t) { + for (i = 0; i < n[t]; ++i) { + isl_val *v1, *v2; + + if (!parallel && !opposite) + break; + v1 = isl_constraint_get_coefficient_val(c, + c_type[t], i); + v2 = isl_aff_get_coefficient_val(data->div, + a_type[t], i); + if (parallel) { + v1 = isl_val_sub(v1, isl_val_copy(v2)); + parallel = isl_val_is_divisible_by(v1, data->d); + v1 = isl_val_add(v1, isl_val_copy(v2)); + } + if (opposite) { + v1 = isl_val_add(v1, isl_val_copy(v2)); + opposite = isl_val_is_divisible_by(v1, data->d); + } + isl_val_free(v1); + isl_val_free(v2); + if (parallel < 0 || opposite < 0) + goto error; + } + } + + if ((parallel || opposite) && mod_constraint_is_simpler(data, c)) { + isl_aff_free(data->nonneg); + data->nonneg = isl_constraint_get_aff(c); + data->sign = parallel ? 1 : -1; + } + + isl_constraint_free(c); + + if (data->sign != 0 && data->nonneg == NULL) + return isl_stat_error; + + return isl_stat_ok; +error: + isl_constraint_free(c); + return isl_stat_error; +} + +/* Given that data->v * div_i in data->aff is of the form + * + * f * d * floor(div/d) (1) + * + * see if we can find an expression div' that is non-negative over data->build + * and that is related to div through + * + * div' = div + d * e + * + * or + * + * div' = -div + d - 1 + d * e + * + * with e some affine expression. + * If so, we write (1) as + * + * f * div + f * (div' mod d) + * + * or + * + * -f * (-div + d - 1) - f * (div' mod d) + * + * exploiting (in the second case) the fact that + * + * f * d * floor(div/d) = -f * d * floor((-div + d - 1)/d) + * + * + * We first try to find an appropriate expression for div' + * from the constraints of data->build->domain (which is therefore + * guaranteed to be non-negative on data->build), where we remove + * any integer divisions from the constraints and skip this step + * if "div" itself involves any integer divisions. + * If we cannot find an appropriate expression this way, then + * we pass control to extract_nonneg_mod where check + * if div or "-div + d -1" themselves happen to be + * non-negative on data->build. + * + * While looking for an appropriate constraint in data->build->domain, + * we ignore the constant term, so after finding such a constraint, + * we still need to fix up the constant term. + * In particular, if a is the constant term of "div" + * (or d - 1 - the constant term of "div" if data->sign < 0) + * and b is the constant term of the constraint, then we need to find + * a non-negative constant c such that + * + * b + c \equiv a mod d + * + * We therefore take + * + * c = (a - b) mod d + * + * and add it to b to obtain the constant term of div'. + * If this constant term is "too negative", then we add an appropriate + * multiple of d to make it positive. + * + * + * Note that the above is only a very simple heuristic for finding an + * appropriate expression. We could try a bit harder by also considering + * sums of constraints that involve disjoint sets of variables or + * we could consider arbitrary linear combinations of constraints, + * although that could potentially be much more expensive as it involves + * the solution of an LP problem. + * + * In particular, if v_i is a column vector representing constraint i, + * w represents div and e_i is the i-th unit vector, then we are looking + * for a solution of the constraints + * + * \sum_i lambda_i v_i = w + \sum_i alpha_i d e_i + * + * with \lambda_i >= 0 and alpha_i of unrestricted sign. + * If we are not just interested in a non-negative expression, but + * also in one with a minimal range, then we don't just want + * c = \sum_i lambda_i v_i to be non-negative over the domain, + * but also beta - c = \sum_i mu_i v_i, where beta is a scalar + * that we want to minimize and we now also have to take into account + * the constant terms of the constraints. + * Alternatively, we could first compute the dual of the domain + * and plug in the constraints on the coefficients. + */ +static isl_stat try_extract_mod(struct isl_extract_mod_data *data) +{ + isl_basic_set *hull; + isl_val *v1, *v2; + isl_stat r; + isl_size n; + + if (!data->build) + goto error; + + n = isl_aff_dim(data->div, isl_dim_div); + if (n < 0) + goto error; + + if (isl_aff_involves_dims(data->div, isl_dim_div, 0, n)) + return extract_nonneg_mod(data); + + hull = isl_set_simple_hull(isl_set_copy(data->build->domain)); + hull = isl_basic_set_remove_divs(hull); + data->sign = 0; + data->nonneg = NULL; + r = isl_basic_set_foreach_constraint(hull, &check_parallel_or_opposite, + data); + isl_basic_set_free(hull); + + if (!data->sign || r < 0) { + isl_aff_free(data->nonneg); + if (r < 0) + goto error; + return extract_nonneg_mod(data); + } + + v1 = isl_aff_get_constant_val(data->div); + v2 = isl_aff_get_constant_val(data->nonneg); + if (data->sign < 0) { + v1 = isl_val_neg(v1); + v1 = isl_val_add(v1, isl_val_copy(data->d)); + v1 = isl_val_sub_ui(v1, 1); + } + v1 = isl_val_sub(v1, isl_val_copy(v2)); + v1 = isl_val_mod(v1, isl_val_copy(data->d)); + v1 = isl_val_add(v1, v2); + v2 = isl_val_div(isl_val_copy(v1), isl_val_copy(data->d)); + v2 = isl_val_ceil(v2); + if (isl_val_is_neg(v2)) { + v2 = isl_val_mul(v2, isl_val_copy(data->d)); + v1 = isl_val_sub(v1, isl_val_copy(v2)); + } + data->nonneg = isl_aff_set_constant_val(data->nonneg, v1); + isl_val_free(v2); + + if (data->sign < 0) { + data->div = oppose_div_arg(data->div, isl_val_copy(data->d)); + data->v = isl_val_neg(data->v); + } + + return extract_term_and_mod(data, + isl_aff_copy(data->div), data->nonneg); +error: + data->aff = isl_aff_free(data->aff); + return isl_stat_error; +} + +/* Check if "data->aff" involves any (implicit) modulo computations based + * on div "data->i". + * If so, remove them from aff and add expressions corresponding + * to those modulo computations to data->pos and/or data->neg. + * + * "aff" is assumed to be an integer affine expression. + * + * In particular, check if (v * div_j) is of the form + * + * f * m * floor(a / m) + * + * and, if so, rewrite it as + * + * f * (a - (a mod m)) = f * a - f * (a mod m) + * + * and extract out -f * (a mod m). + * In particular, if f > 0, we add (f * (a mod m)) to *neg. + * If f < 0, we add ((-f) * (a mod m)) to *pos. + * + * Note that in order to represent "a mod m" as + * + * (isl_ast_expr_op_pdiv_r, a, m) + * + * we need to make sure that a is non-negative. + * If not, we check if "-a + m - 1" is non-negative. + * If so, we can rewrite + * + * floor(a/m) = -ceil(-a/m) = -floor((-a + m - 1)/m) + * + * and still extract a modulo. + */ +static int extract_modulo(struct isl_extract_mod_data *data) +{ + data->div = isl_aff_get_div(data->aff, data->i); + data->d = isl_aff_get_denominator_val(data->div); + if (isl_val_is_divisible_by(data->v, data->d)) { + data->div = isl_aff_scale_val(data->div, isl_val_copy(data->d)); + if (try_extract_mod(data) < 0) + data->aff = isl_aff_free(data->aff); + } + isl_aff_free(data->div); + isl_val_free(data->d); + return 0; +} + +/* Check if "aff" involves any (implicit) modulo computations. + * If so, remove them from aff and add expressions corresponding + * to those modulo computations to *pos and/or *neg. + * We only do this if the option ast_build_prefer_pdiv is set. + * + * "aff" is assumed to be an integer affine expression. + * + * A modulo expression is of the form + * + * a mod m = a - m * floor(a / m) + * + * To detect them in aff, we look for terms of the form + * + * f * m * floor(a / m) + * + * rewrite them as + * + * f * (a - (a mod m)) = f * a - f * (a mod m) + * + * and extract out -f * (a mod m). + * In particular, if f > 0, we add (f * (a mod m)) to *neg. + * If f < 0, we add ((-f) * (a mod m)) to *pos. + */ +static __isl_give isl_aff *extract_modulos(__isl_take isl_aff *aff, + __isl_keep isl_ast_expr **pos, __isl_keep isl_ast_expr **neg, + __isl_keep isl_ast_build *build) +{ + struct isl_extract_mod_data data = { build, aff, *pos, *neg }; + isl_ctx *ctx; + isl_size n; + + if (!aff) + return NULL; + + ctx = isl_aff_get_ctx(aff); + if (!isl_options_get_ast_build_prefer_pdiv(ctx)) + return aff; + + n = isl_aff_dim(data.aff, isl_dim_div); + if (n < 0) + return isl_aff_free(aff); + for (data.i = 0; data.i < n; ++data.i) { + data.v = isl_aff_get_coefficient_val(data.aff, + isl_dim_div, data.i); + if (!data.v) + return isl_aff_free(aff); + if (isl_val_is_zero(data.v) || + isl_val_is_one(data.v) || isl_val_is_negone(data.v)) { + isl_val_free(data.v); + continue; + } + if (extract_modulo(&data) < 0) + data.aff = isl_aff_free(data.aff); + isl_val_free(data.v); + if (!data.aff) + break; + } + + if (data.add) + data.aff = isl_aff_add(data.aff, data.add); + + *pos = data.pos; + *neg = data.neg; + return data.aff; +} + +/* Call "fn" on every non-zero coefficient of "aff", + * passing it in the type of dimension (in terms of the domain), + * the position and the value, as long as "fn" returns isl_bool_true. + * If "reverse" is set, then the coefficients are considered in reverse order + * within each type. + */ +static isl_bool every_non_zero_coefficient(__isl_keep isl_aff *aff, + int reverse, + isl_bool (*fn)(enum isl_dim_type type, int pos, __isl_take isl_val *v, + void *user), + void *user) +{ + int i, j; + enum isl_dim_type t[] = { isl_dim_param, isl_dim_in, isl_dim_div }; + enum isl_dim_type l[] = { isl_dim_param, isl_dim_set, isl_dim_div }; + isl_val *v; + + for (i = 0; i < 3; ++i) { + isl_size n; + + n = isl_aff_dim(aff, t[i]); + if (n < 0) + return isl_bool_error; + for (j = 0; j < n; ++j) { + isl_bool ok; + int pos; + + pos = reverse ? n - 1 - j : j; + v = isl_aff_get_coefficient_val(aff, t[i], pos); + ok = isl_val_is_zero(v); + if (ok >= 0 && !ok) + ok = fn(l[i], pos, v, user); + else + isl_val_free(v); + if (ok < 0 || !ok) + return ok; + } + } + + return isl_bool_true; +} + +/* Internal data structure for extract_rational. + * + * "d" is the denominator of the original affine expression. + * "ls" is its domain local space. + * "rat" collects the rational part. + */ +struct isl_ast_extract_rational_data { + isl_val *d; + isl_local_space *ls; + + isl_aff *rat; +}; + +/* Given a non-zero term in an affine expression equal to "v" times + * the variable of type "type" at position "pos", + * add it to data->rat if "v" is not a multiple of data->d. + */ +static isl_bool add_rational(enum isl_dim_type type, int pos, + __isl_take isl_val *v, void *user) +{ + struct isl_ast_extract_rational_data *data = user; + isl_aff *rat; + + if (isl_val_is_divisible_by(v, data->d)) { + isl_val_free(v); + return isl_bool_true; + } + rat = isl_aff_var_on_domain(isl_local_space_copy(data->ls), type, pos); + rat = isl_aff_scale_val(rat, v); + data->rat = isl_aff_add(data->rat, rat); + return isl_bool_true; +} + +/* Check if aff involves any non-integer coefficients. + * If so, split aff into + * + * aff = aff1 + (aff2 / d) + * + * with both aff1 and aff2 having only integer coefficients. + * Return aff1 and add (aff2 / d) to *expr. + */ +static __isl_give isl_aff *extract_rational(__isl_take isl_aff *aff, + __isl_keep isl_ast_expr **expr, __isl_keep isl_ast_build *build) +{ + struct isl_ast_extract_rational_data data = { NULL }; + isl_ast_expr *rat_expr; + isl_val *v; + + if (!aff) + return NULL; + data.d = isl_aff_get_denominator_val(aff); + if (!data.d) + goto error; + if (isl_val_is_one(data.d)) { + isl_val_free(data.d); + return aff; + } + + aff = isl_aff_scale_val(aff, isl_val_copy(data.d)); + + data.ls = isl_aff_get_domain_local_space(aff); + data.rat = isl_aff_zero_on_domain(isl_local_space_copy(data.ls)); + + if (every_non_zero_coefficient(aff, 0, &add_rational, &data) < 0) + goto error; + + v = isl_aff_get_constant_val(aff); + if (isl_val_is_divisible_by(v, data.d)) { + isl_val_free(v); + } else { + isl_aff *rat_0; + + rat_0 = isl_aff_val_on_domain(isl_local_space_copy(data.ls), v); + data.rat = isl_aff_add(data.rat, rat_0); + } + + isl_local_space_free(data.ls); + + aff = isl_aff_sub(aff, isl_aff_copy(data.rat)); + aff = isl_aff_scale_down_val(aff, isl_val_copy(data.d)); + + rat_expr = div_mod(isl_ast_expr_op_div, data.rat, data.d, build); + *expr = ast_expr_add(*expr, rat_expr); + + return aff; +error: + isl_aff_free(data.rat); + isl_local_space_free(data.ls); + isl_aff_free(aff); + isl_val_free(data.d); + return NULL; +} + +/* Internal data structure for isl_ast_expr_from_aff. + * + * "term" contains the information for adding a term. + * "expr" collects the results. + */ +struct isl_ast_add_terms_data { + struct isl_ast_add_term_data *term; + isl_ast_expr *expr; +}; + +/* Given a non-zero term in an affine expression equal to "v" times + * the variable of type "type" at position "pos", + * add the corresponding AST expression to data->expr. + */ +static isl_bool add_term(enum isl_dim_type type, int pos, + __isl_take isl_val *v, void *user) +{ + struct isl_ast_add_terms_data *data = user; + + data->expr = + isl_ast_expr_add_term(data->expr, type, pos, v, data->term); + + return isl_bool_true; +} + +/* Add terms to "expr" for each variable in "aff". + * The result is simplified in terms of data->build->domain. + */ +static __isl_give isl_ast_expr *add_terms(__isl_take isl_ast_expr *expr, + __isl_keep isl_aff *aff, struct isl_ast_add_term_data *data) +{ + struct isl_ast_add_terms_data terms_data = { data, expr }; + + if (every_non_zero_coefficient(aff, 0, &add_term, &terms_data) < 0) + return isl_ast_expr_free(terms_data.expr); + + return terms_data.expr; +} + +/* Construct an isl_ast_expr that evaluates the affine expression "aff". + * The result is simplified in terms of build->domain. + * + * We first extract hidden modulo computations from the affine expression + * and then add terms for each variable with a non-zero coefficient. + * Finally, if the affine expression has a non-trivial denominator, + * we divide the resulting isl_ast_expr by this denominator. + */ +__isl_give isl_ast_expr *isl_ast_expr_from_aff(__isl_take isl_aff *aff, + __isl_keep isl_ast_build *build) +{ + isl_ctx *ctx = isl_aff_get_ctx(aff); + isl_ast_expr *expr, *expr_neg; + struct isl_ast_add_term_data term_data; + + if (!aff) + return NULL; + + expr = isl_ast_expr_alloc_int_si(ctx, 0); + expr_neg = isl_ast_expr_alloc_int_si(ctx, 0); + + aff = extract_rational(aff, &expr, build); + + aff = extract_modulos(aff, &expr, &expr_neg, build); + expr = ast_expr_sub(expr, expr_neg); + + term_data.build = build; + term_data.ls = isl_aff_get_domain_local_space(aff); + term_data.cst = isl_aff_get_constant_val(aff); + expr = add_terms(expr, aff, &term_data); + + expr = isl_ast_expr_add_int(expr, term_data.cst); + isl_local_space_free(term_data.ls); + + isl_aff_free(aff); + return expr; +} + +/* Internal data structure for coefficients_of_sign. + * + * "sign" is the sign of the coefficients that should be retained. + * "aff" is the affine expression of which some coefficients are zeroed out. + */ +struct isl_ast_coefficients_of_sign_data { + int sign; + isl_aff *aff; +}; + +/* Clear the specified coefficient of data->aff if the value "v" + * does not have the required sign. + */ +static isl_bool clear_opposite_sign(enum isl_dim_type type, int pos, + __isl_take isl_val *v, void *user) +{ + struct isl_ast_coefficients_of_sign_data *data = user; + + if (type == isl_dim_set) + type = isl_dim_in; + if (data->sign * isl_val_sgn(v) < 0) + data->aff = isl_aff_set_coefficient_si(data->aff, type, pos, 0); + isl_val_free(v); + + return isl_bool_true; +} + +/* Extract the coefficients of "aff" (excluding the constant term) + * that have the given sign. + * + * Take a copy of "aff" and clear the coefficients that do not have + * the required sign. + * Consider the coefficients in reverse order since clearing + * the coefficient of an integer division in data.aff + * could result in the removal of that integer division from data.aff, + * changing the positions of all subsequent integer divisions of data.aff, + * while those of "aff" remain the same. + */ +static __isl_give isl_aff *coefficients_of_sign(__isl_take isl_aff *aff, + int sign) +{ + struct isl_ast_coefficients_of_sign_data data; + + data.sign = sign; + data.aff = isl_aff_copy(aff); + if (every_non_zero_coefficient(aff, 1, &clear_opposite_sign, &data) < 0) + data.aff = isl_aff_free(data.aff); + isl_aff_free(aff); + + data.aff = isl_aff_set_constant_si(data.aff, 0); + + return data.aff; +} + +/* Should the constant term "v" be considered positive? + * + * A positive constant will be added to "pos" by the caller, + * while a negative constant will be added to "neg". + * If either "pos" or "neg" is exactly zero, then we prefer + * to add the constant "v" to that side, irrespective of the sign of "v". + * This results in slightly shorter expressions and may reduce the risk + * of overflows. + */ +static isl_bool constant_is_considered_positive(__isl_keep isl_val *v, + __isl_keep isl_ast_expr *pos, __isl_keep isl_ast_expr *neg) +{ + isl_bool zero; + + zero = ast_expr_is_zero(pos); + if (zero < 0 || zero) + return zero; + zero = ast_expr_is_zero(neg); + if (zero < 0 || zero) + return isl_bool_not(zero); + return isl_val_is_pos(v); +} + +/* Check if the equality + * + * aff = 0 + * + * represents a stride constraint on the integer division "pos". + * + * In particular, if the integer division "pos" is equal to + * + * floor(e/d) + * + * then check if aff is equal to + * + * e - d floor(e/d) + * + * or its opposite. + * + * If so, the equality is exactly + * + * e mod d = 0 + * + * Note that in principle we could also accept + * + * e - d floor(e'/d) + * + * where e and e' differ by a constant. + */ +static isl_bool is_stride_constraint(__isl_keep isl_aff *aff, int pos) +{ + isl_aff *div; + isl_val *c, *d; + isl_bool eq; + + div = isl_aff_get_div(aff, pos); + c = isl_aff_get_coefficient_val(aff, isl_dim_div, pos); + d = isl_aff_get_denominator_val(div); + eq = isl_val_abs_eq(c, d); + if (eq >= 0 && eq) { + aff = isl_aff_copy(aff); + aff = isl_aff_set_coefficient_si(aff, isl_dim_div, pos, 0); + div = isl_aff_scale_val(div, d); + if (isl_val_is_pos(c)) + div = isl_aff_neg(div); + eq = isl_aff_plain_is_equal(div, aff); + isl_aff_free(aff); + } else + isl_val_free(d); + isl_val_free(c); + isl_aff_free(div); + + return eq; +} + +/* Are all coefficients of "aff" (zero or) negative? + */ +static isl_bool all_negative_coefficients(__isl_keep isl_aff *aff) +{ + int i; + isl_size n; + + n = isl_aff_dim(aff, isl_dim_param); + if (n < 0) + return isl_bool_error; + for (i = 0; i < n; ++i) + if (isl_aff_coefficient_sgn(aff, isl_dim_param, i) > 0) + return isl_bool_false; + + n = isl_aff_dim(aff, isl_dim_in); + if (n < 0) + return isl_bool_error; + for (i = 0; i < n; ++i) + if (isl_aff_coefficient_sgn(aff, isl_dim_in, i) > 0) + return isl_bool_false; + + return isl_bool_true; +} + +/* Give an equality of the form + * + * aff = e - d floor(e/d) = 0 + * + * or + * + * aff = -e + d floor(e/d) = 0 + * + * with the integer division "pos" equal to floor(e/d), + * construct the AST expression + * + * (isl_ast_expr_op_eq, + * (isl_ast_expr_op_zdiv_r, expr(e), expr(d)), expr(0)) + * + * If e only has negative coefficients, then construct + * + * (isl_ast_expr_op_eq, + * (isl_ast_expr_op_zdiv_r, expr(-e), expr(d)), expr(0)) + * + * instead. + */ +static __isl_give isl_ast_expr *extract_stride_constraint( + __isl_take isl_aff *aff, int pos, __isl_keep isl_ast_build *build) +{ + isl_bool all_neg; + isl_ctx *ctx; + isl_val *c; + isl_ast_expr *expr, *cst; + + if (!aff) + return NULL; + + ctx = isl_aff_get_ctx(aff); + + c = isl_aff_get_coefficient_val(aff, isl_dim_div, pos); + aff = isl_aff_set_coefficient_si(aff, isl_dim_div, pos, 0); + + all_neg = all_negative_coefficients(aff); + if (all_neg < 0) + aff = isl_aff_free(aff); + else if (all_neg) + aff = isl_aff_neg(aff); + + cst = isl_ast_expr_from_val(isl_val_abs(c)); + expr = isl_ast_expr_from_aff(aff, build); + + expr = isl_ast_expr_alloc_binary(isl_ast_expr_op_zdiv_r, expr, cst); + cst = isl_ast_expr_alloc_int_si(ctx, 0); + expr = isl_ast_expr_alloc_binary(isl_ast_expr_op_eq, expr, cst); + + return expr; +} + +/* Construct an isl_ast_expr evaluating + * + * "expr_pos" == "expr_neg", if "eq" is set, or + * "expr_pos" >= "expr_neg", if "eq" is not set + * + * However, if "expr_pos" is an integer constant (and "expr_neg" is not), + * then the two expressions are interchanged. This ensures that, + * e.g., "i <= 5" is constructed rather than "5 >= i". + */ +static __isl_give isl_ast_expr *construct_constraint_expr(int eq, + __isl_take isl_ast_expr *expr_pos, __isl_take isl_ast_expr *expr_neg) +{ + isl_ast_expr *expr; + enum isl_ast_expr_op_type type; + int pos_is_cst, neg_is_cst; + + pos_is_cst = isl_ast_expr_get_type(expr_pos) == isl_ast_expr_int; + neg_is_cst = isl_ast_expr_get_type(expr_neg) == isl_ast_expr_int; + if (pos_is_cst && !neg_is_cst) { + type = eq ? isl_ast_expr_op_eq : isl_ast_expr_op_le; + expr = isl_ast_expr_alloc_binary(type, expr_neg, expr_pos); + } else { + type = eq ? isl_ast_expr_op_eq : isl_ast_expr_op_ge; + expr = isl_ast_expr_alloc_binary(type, expr_pos, expr_neg); + } + + return expr; +} + +/* Construct an isl_ast_expr that evaluates the condition "aff" == 0 + * (if "eq" is set) or "aff" >= 0 (otherwise). + * The result is simplified in terms of build->domain. + * + * We first extract hidden modulo computations from "aff" + * and then collect all the terms with a positive coefficient in cons_pos + * and the terms with a negative coefficient in cons_neg. + * + * The result is then essentially of the form + * + * (isl_ast_expr_op_ge, expr(pos), expr(-neg))) + * + * or + * + * (isl_ast_expr_op_eq, expr(pos), expr(-neg))) + * + * However, if there are no terms with positive coefficients (or no terms + * with negative coefficients), then the constant term is added to "pos" + * (or "neg"), ignoring the sign of the constant term. + */ +static __isl_give isl_ast_expr *isl_ast_expr_from_constraint_no_stride( + int eq, __isl_take isl_aff *aff, __isl_keep isl_ast_build *build) +{ + isl_bool cst_is_pos; + isl_ctx *ctx; + isl_ast_expr *expr_pos; + isl_ast_expr *expr_neg; + isl_aff *aff_pos, *aff_neg; + struct isl_ast_add_term_data data; + + ctx = isl_aff_get_ctx(aff); + expr_pos = isl_ast_expr_alloc_int_si(ctx, 0); + expr_neg = isl_ast_expr_alloc_int_si(ctx, 0); + + aff = extract_modulos(aff, &expr_pos, &expr_neg, build); + + data.build = build; + data.ls = isl_aff_get_domain_local_space(aff); + data.cst = isl_aff_get_constant_val(aff); + + aff_pos = coefficients_of_sign(isl_aff_copy(aff), 1); + aff_neg = isl_aff_neg(coefficients_of_sign(aff, -1)); + + expr_pos = add_terms(expr_pos, aff_pos, &data); + data.cst = isl_val_neg(data.cst); + expr_neg = add_terms(expr_neg, aff_neg, &data); + data.cst = isl_val_neg(data.cst); + isl_local_space_free(data.ls); + + cst_is_pos = + constant_is_considered_positive(data.cst, expr_pos, expr_neg); + if (cst_is_pos < 0) + expr_pos = isl_ast_expr_free(expr_pos); + + if (cst_is_pos) { + expr_pos = isl_ast_expr_add_int(expr_pos, data.cst); + } else { + data.cst = isl_val_neg(data.cst); + expr_neg = isl_ast_expr_add_int(expr_neg, data.cst); + } + + isl_aff_free(aff_pos); + isl_aff_free(aff_neg); + return construct_constraint_expr(eq, expr_pos, expr_neg); +} + +/* Construct an isl_ast_expr that evaluates the condition "constraint". + * The result is simplified in terms of build->domain. + * + * We first check if the constraint is an equality of the form + * + * e - d floor(e/d) = 0 + * + * i.e., + * + * e mod d = 0 + * + * If so, we convert it to + * + * (isl_ast_expr_op_eq, + * (isl_ast_expr_op_zdiv_r, expr(e), expr(d)), expr(0)) + */ +static __isl_give isl_ast_expr *isl_ast_expr_from_constraint( + __isl_take isl_constraint *constraint, __isl_keep isl_ast_build *build) +{ + int i; + isl_size n; + isl_aff *aff; + isl_bool eq; + + aff = isl_constraint_get_aff(constraint); + eq = isl_constraint_is_equality(constraint); + isl_constraint_free(constraint); + if (eq < 0) + goto error; + + n = isl_aff_dim(aff, isl_dim_div); + if (n < 0) + aff = isl_aff_free(aff); + if (eq && n > 0) + for (i = 0; i < n; ++i) { + isl_bool is_stride; + is_stride = is_stride_constraint(aff, i); + if (is_stride < 0) + goto error; + if (is_stride) + return extract_stride_constraint(aff, i, build); + } + + return isl_ast_expr_from_constraint_no_stride(eq, aff, build); +error: + isl_aff_free(aff); + return NULL; +} + +/* Wrapper around isl_constraint_cmp_last_non_zero for use + * as a callback to isl_constraint_list_sort. + * If isl_constraint_cmp_last_non_zero cannot tell the constraints + * apart, then use isl_constraint_plain_cmp instead. + */ +static int cmp_constraint(__isl_keep isl_constraint *a, + __isl_keep isl_constraint *b, void *user) +{ + int cmp; + + cmp = isl_constraint_cmp_last_non_zero(a, b); + if (cmp != 0) + return cmp; + return isl_constraint_plain_cmp(a, b); +} + +/* Construct an isl_ast_expr that evaluates the conditions defining "bset". + * The result is simplified in terms of build->domain. + * + * If "bset" is not bounded by any constraint, then we construct + * the expression "1", i.e., "true". + * + * Otherwise, we sort the constraints, putting constraints that involve + * integer divisions after those that do not, and construct an "and" + * of the ast expressions of the individual constraints. + * + * Each constraint is added to the generated constraints of the build + * after it has been converted to an AST expression so that it can be used + * to simplify the following constraints. This may change the truth value + * of subsequent constraints that do not satisfy the earlier constraints, + * but this does not affect the outcome of the conjunction as it is + * only true if all the conjuncts are true (no matter in what order + * they are evaluated). In particular, the constraints that do not + * involve integer divisions may serve to simplify some constraints + * that do involve integer divisions. + */ +__isl_give isl_ast_expr *isl_ast_build_expr_from_basic_set( + __isl_keep isl_ast_build *build, __isl_take isl_basic_set *bset) +{ + int i; + isl_size n; + isl_constraint *c; + isl_constraint_list *list; + isl_ast_expr *res; + isl_set *set; + + list = isl_basic_set_get_constraint_list(bset); + isl_basic_set_free(bset); + list = isl_constraint_list_sort(list, &cmp_constraint, NULL); + n = isl_constraint_list_n_constraint(list); + if (n < 0) + build = NULL; + if (n == 0) { + isl_ctx *ctx = isl_constraint_list_get_ctx(list); + isl_constraint_list_free(list); + return isl_ast_expr_alloc_int_si(ctx, 1); + } + + build = isl_ast_build_copy(build); + + c = isl_constraint_list_get_constraint(list, 0); + bset = isl_basic_set_from_constraint(isl_constraint_copy(c)); + set = isl_set_from_basic_set(bset); + res = isl_ast_expr_from_constraint(c, build); + build = isl_ast_build_restrict_generated(build, set); + + for (i = 1; i < n; ++i) { + isl_ast_expr *expr; + + c = isl_constraint_list_get_constraint(list, i); + bset = isl_basic_set_from_constraint(isl_constraint_copy(c)); + set = isl_set_from_basic_set(bset); + expr = isl_ast_expr_from_constraint(c, build); + build = isl_ast_build_restrict_generated(build, set); + res = isl_ast_expr_and(res, expr); + } + + isl_constraint_list_free(list); + isl_ast_build_free(build); + return res; +} + +/* Construct an isl_ast_expr that evaluates the conditions defining "set". + * The result is simplified in terms of build->domain. + * + * If "set" is an (obviously) empty set, then return the expression "0". + * + * If there are multiple disjuncts in the description of the set, + * then subsequent disjuncts are simplified in a context where + * the previous disjuncts have been removed from build->domain. + * In particular, constraints that ensure that there is no overlap + * with these previous disjuncts, can be removed. + * This is mostly useful for disjuncts that are only defined by + * a single constraint (relative to the build domain) as the opposite + * of that single constraint can then be removed from the other disjuncts. + * In order not to increase the number of disjuncts in the build domain + * after subtracting the previous disjuncts of "set", the simple hull + * is computed after taking the difference with each of these disjuncts. + * This means that constraints that prevent overlap with a union + * of multiple previous disjuncts are not removed. + * + * "set" lives in the internal schedule space. + */ +__isl_give isl_ast_expr *isl_ast_build_expr_from_set_internal( + __isl_keep isl_ast_build *build, __isl_take isl_set *set) +{ + int i; + isl_size n; + isl_basic_set *bset; + isl_basic_set_list *list; + isl_set *domain; + isl_ast_expr *res; + + list = isl_set_get_basic_set_list(set); + isl_set_free(set); + + n = isl_basic_set_list_n_basic_set(list); + if (n < 0) + build = NULL; + if (n == 0) { + isl_ctx *ctx = isl_ast_build_get_ctx(build); + isl_basic_set_list_free(list); + return isl_ast_expr_from_val(isl_val_zero(ctx)); + } + + domain = isl_ast_build_get_domain(build); + + bset = isl_basic_set_list_get_basic_set(list, 0); + set = isl_set_from_basic_set(isl_basic_set_copy(bset)); + res = isl_ast_build_expr_from_basic_set(build, bset); + + for (i = 1; i < n; ++i) { + isl_ast_expr *expr; + isl_set *rest; + + rest = isl_set_subtract(isl_set_copy(domain), set); + rest = isl_set_from_basic_set(isl_set_simple_hull(rest)); + domain = isl_set_intersect(domain, rest); + bset = isl_basic_set_list_get_basic_set(list, i); + set = isl_set_from_basic_set(isl_basic_set_copy(bset)); + bset = isl_basic_set_gist(bset, + isl_set_simple_hull(isl_set_copy(domain))); + expr = isl_ast_build_expr_from_basic_set(build, bset); + res = isl_ast_expr_or(res, expr); + } + + isl_set_free(domain); + isl_set_free(set); + isl_basic_set_list_free(list); + return res; +} + +/* Construct an isl_ast_expr that evaluates the conditions defining "set". + * The result is simplified in terms of build->domain. + * + * If "set" is an (obviously) empty set, then return the expression "0". + * + * "set" lives in the external schedule space. + * + * The internal AST expression generation assumes that there are + * no unknown divs, so make sure an explicit representation is available. + * Since the set comes from the outside, it may have constraints that + * are redundant with respect to the build domain. Remove them first. + */ +__isl_give isl_ast_expr *isl_ast_build_expr_from_set( + __isl_keep isl_ast_build *build, __isl_take isl_set *set) +{ + isl_bool needs_map; + + needs_map = isl_ast_build_need_schedule_map(build); + if (needs_map < 0) { + set = isl_set_free(set); + } else if (needs_map) { + isl_multi_aff *ma; + ma = isl_ast_build_get_schedule_map_multi_aff(build); + set = isl_set_preimage_multi_aff(set, ma); + } + + set = isl_set_compute_divs(set); + set = isl_ast_build_compute_gist(build, set); + return isl_ast_build_expr_from_set_internal(build, set); +} + +/* State of data about previous pieces in + * isl_ast_build_expr_from_pw_aff_internal. + * + * isl_state_none: no data about previous pieces + * isl_state_single: data about a single previous piece + * isl_state_min: data represents minimum of several pieces + * isl_state_max: data represents maximum of several pieces + */ +enum isl_from_pw_aff_state { + isl_state_none, + isl_state_single, + isl_state_min, + isl_state_max +}; + +/* Internal date structure representing a single piece in the input of + * isl_ast_build_expr_from_pw_aff_internal. + * + * If "state" is isl_state_none, then "set_list" and "aff_list" are not used. + * If "state" is isl_state_single, then "set_list" and "aff_list" contain the + * single previous subpiece. + * If "state" is isl_state_min, then "set_list" and "aff_list" contain + * a sequence of several previous subpieces that are equal to the minimum + * of the entries in "aff_list" over the union of "set_list" + * If "state" is isl_state_max, then "set_list" and "aff_list" contain + * a sequence of several previous subpieces that are equal to the maximum + * of the entries in "aff_list" over the union of "set_list" + * + * During the construction of the pieces, "set" is NULL. + * After the construction, "set" is set to the union of the elements + * in "set_list", at which point "set_list" is set to NULL. + */ +struct isl_from_pw_aff_piece { + enum isl_from_pw_aff_state state; + isl_set *set; + isl_set_list *set_list; + isl_aff_list *aff_list; +}; + +/* Internal data structure for isl_ast_build_expr_from_pw_aff_internal. + * + * "build" specifies the domain against which the result is simplified. + * "dom" is the domain of the entire isl_pw_aff. + * + * "n" is the number of pieces constructed already. + * In particular, during the construction of the pieces, "n" points to + * the piece that is being constructed. After the construction of the + * pieces, "n" is set to the total number of pieces. + * "max" is the total number of allocated entries. + * "p" contains the individual pieces. + */ +struct isl_from_pw_aff_data { + isl_ast_build *build; + isl_set *dom; + + int n; + int max; + struct isl_from_pw_aff_piece *p; +}; + +/* Initialize "data" based on "build" and "pa". + */ +static isl_stat isl_from_pw_aff_data_init(struct isl_from_pw_aff_data *data, + __isl_keep isl_ast_build *build, __isl_keep isl_pw_aff *pa) +{ + isl_size n; + isl_ctx *ctx; + + ctx = isl_pw_aff_get_ctx(pa); + n = isl_pw_aff_n_piece(pa); + if (n < 0) + return isl_stat_error; + if (n == 0) + isl_die(ctx, isl_error_invalid, + "cannot handle void expression", return isl_stat_error); + data->max = n; + data->p = isl_calloc_array(ctx, struct isl_from_pw_aff_piece, n); + if (!data->p) + return isl_stat_error; + data->build = build; + data->dom = isl_pw_aff_domain(isl_pw_aff_copy(pa)); + data->n = 0; + + return isl_stat_ok; +} + +/* Free all memory allocated for "data". + */ +static void isl_from_pw_aff_data_clear(struct isl_from_pw_aff_data *data) +{ + int i; + + isl_set_free(data->dom); + if (!data->p) + return; + + for (i = 0; i < data->max; ++i) { + isl_set_free(data->p[i].set); + isl_set_list_free(data->p[i].set_list); + isl_aff_list_free(data->p[i].aff_list); + } + free(data->p); +} + +/* Initialize the current entry of "data" to an unused piece. + */ +static void set_none(struct isl_from_pw_aff_data *data) +{ + data->p[data->n].state = isl_state_none; + data->p[data->n].set_list = NULL; + data->p[data->n].aff_list = NULL; +} + +/* Store "set" and "aff" in the current entry of "data" as a single subpiece. + */ +static void set_single(struct isl_from_pw_aff_data *data, + __isl_take isl_set *set, __isl_take isl_aff *aff) +{ + data->p[data->n].state = isl_state_single; + data->p[data->n].set_list = isl_set_list_from_set(set); + data->p[data->n].aff_list = isl_aff_list_from_aff(aff); +} + +/* Extend the current entry of "data" with "set" and "aff" + * as a minimum expression. + */ +static isl_stat extend_min(struct isl_from_pw_aff_data *data, + __isl_take isl_set *set, __isl_take isl_aff *aff) +{ + int n = data->n; + data->p[n].state = isl_state_min; + data->p[n].set_list = isl_set_list_add(data->p[n].set_list, set); + data->p[n].aff_list = isl_aff_list_add(data->p[n].aff_list, aff); + + if (!data->p[n].set_list || !data->p[n].aff_list) + return isl_stat_error; + return isl_stat_ok; +} + +/* Extend the current entry of "data" with "set" and "aff" + * as a maximum expression. + */ +static isl_stat extend_max(struct isl_from_pw_aff_data *data, + __isl_take isl_set *set, __isl_take isl_aff *aff) +{ + int n = data->n; + data->p[n].state = isl_state_max; + data->p[n].set_list = isl_set_list_add(data->p[n].set_list, set); + data->p[n].aff_list = isl_aff_list_add(data->p[n].aff_list, aff); + + if (!data->p[n].set_list || !data->p[n].aff_list) + return isl_stat_error; + return isl_stat_ok; +} + +/* Extend the domain of the current entry of "data", which is assumed + * to contain a single subpiece, with "set". If "replace" is set, + * then also replace the affine function by "aff". Otherwise, + * simply free "aff". + */ +static isl_stat extend_domain(struct isl_from_pw_aff_data *data, + __isl_take isl_set *set, __isl_take isl_aff *aff, int replace) +{ + int n = data->n; + isl_set *set_n; + + set_n = isl_set_list_get_set(data->p[n].set_list, 0); + set_n = isl_set_union(set_n, set); + data->p[n].set_list = + isl_set_list_set_set(data->p[n].set_list, 0, set_n); + + if (replace) + data->p[n].aff_list = + isl_aff_list_set_aff(data->p[n].aff_list, 0, aff); + else + isl_aff_free(aff); + + if (!data->p[n].set_list || !data->p[n].aff_list) + return isl_stat_error; + return isl_stat_ok; +} + +/* Construct an isl_ast_expr from "list" within "build". + * If "state" is isl_state_single, then "list" contains a single entry and + * an isl_ast_expr is constructed for that entry. + * Otherwise a min or max expression is constructed from "list" + * depending on "state". + */ +static __isl_give isl_ast_expr *ast_expr_from_aff_list( + __isl_take isl_aff_list *list, enum isl_from_pw_aff_state state, + __isl_keep isl_ast_build *build) +{ + int i; + isl_size n; + isl_aff *aff; + isl_ast_expr *expr = NULL; + enum isl_ast_expr_op_type op_type; + + if (state == isl_state_single) { + aff = isl_aff_list_get_aff(list, 0); + isl_aff_list_free(list); + return isl_ast_expr_from_aff(aff, build); + } + n = isl_aff_list_n_aff(list); + if (n < 0) + goto error; + op_type = state == isl_state_min ? isl_ast_expr_op_min + : isl_ast_expr_op_max; + expr = isl_ast_expr_alloc_op(isl_ast_build_get_ctx(build), op_type, n); + + for (i = 0; i < n; ++i) { + isl_ast_expr *expr_i; + + aff = isl_aff_list_get_aff(list, i); + expr_i = isl_ast_expr_from_aff(aff, build); + expr = isl_ast_expr_op_add_arg(expr, expr_i); + } + + isl_aff_list_free(list); + return expr; +error: + isl_aff_list_free(list); + isl_ast_expr_free(expr); + return NULL; +} + +/* Extend the list of expressions in "next" to take into account + * the piece at position "pos" in "data", allowing for a further extension + * for the next piece(s). + * In particular, "next" is extended with a select operation that selects + * an isl_ast_expr corresponding to data->aff_list on data->set and + * to an expression that will be filled in by later calls. + * Return a pointer to the arguments of this select operation. + * Afterwards, the state of "data" is set to isl_state_none. + * + * The constraints of data->set are added to the generated + * constraints of the build such that they can be exploited to simplify + * the AST expression constructed from data->aff_list. + */ +static isl_ast_expr_list **add_intermediate_piece( + struct isl_from_pw_aff_data *data, + int pos, isl_ast_expr_list **next) +{ + isl_ctx *ctx; + isl_ast_build *build; + isl_ast_expr *ternary, *arg; + isl_set *set, *gist; + + set = data->p[pos].set; + data->p[pos].set = NULL; + ctx = isl_ast_build_get_ctx(data->build); + ternary = isl_ast_expr_alloc_op(ctx, isl_ast_expr_op_select, 3); + gist = isl_set_gist(isl_set_copy(set), isl_set_copy(data->dom)); + arg = isl_ast_build_expr_from_set_internal(data->build, gist); + ternary = isl_ast_expr_op_add_arg(ternary, arg); + build = isl_ast_build_copy(data->build); + build = isl_ast_build_restrict_generated(build, set); + arg = ast_expr_from_aff_list(data->p[pos].aff_list, + data->p[pos].state, build); + data->p[pos].aff_list = NULL; + isl_ast_build_free(build); + ternary = isl_ast_expr_op_add_arg(ternary, arg); + data->p[pos].state = isl_state_none; + if (!ternary) + return NULL; + + *next = isl_ast_expr_list_add(*next, ternary); + return &ternary->u.op.args; +} + +/* Extend the list of expressions in "next" to take into account + * the final piece, located at position "pos" in "data". + * In particular, "next" is extended with an expression + * to evaluate data->aff_list and the domain is ignored. + * Return isl_stat_ok on success and isl_stat_error on failure. + * + * The constraints of data->set are however added to the generated + * constraints of the build such that they can be exploited to simplify + * the AST expression constructed from data->aff_list. + */ +static isl_stat add_last_piece(struct isl_from_pw_aff_data *data, + int pos, isl_ast_expr_list **next) +{ + isl_ast_build *build; + isl_ast_expr *last; + + if (data->p[pos].state == isl_state_none) + isl_die(isl_ast_build_get_ctx(data->build), isl_error_invalid, + "cannot handle void expression", return isl_stat_error); + + build = isl_ast_build_copy(data->build); + build = isl_ast_build_restrict_generated(build, data->p[pos].set); + data->p[pos].set = NULL; + last = ast_expr_from_aff_list(data->p[pos].aff_list, + data->p[pos].state, build); + *next = isl_ast_expr_list_add(*next, last); + data->p[pos].aff_list = NULL; + isl_ast_build_free(build); + data->p[pos].state = isl_state_none; + if (!*next) + return isl_stat_error; + + return isl_stat_ok; +} + +/* Return -1 if the piece "p1" should be sorted before "p2" + * and 1 if it should be sorted after "p2". + * Return 0 if they do not need to be sorted in a specific order. + * + * Pieces are sorted according to the number of disjuncts + * in their domains. + */ +static int sort_pieces_cmp(const void *p1, const void *p2, void *arg) +{ + const struct isl_from_pw_aff_piece *piece1 = p1; + const struct isl_from_pw_aff_piece *piece2 = p2; + isl_size n1, n2; + + n1 = isl_set_n_basic_set(piece1->set); + n2 = isl_set_n_basic_set(piece2->set); + + return n1 - n2; +} + +/* Construct an isl_ast_expr from the pieces in "data". + * Return the result or NULL on failure. + * + * When this function is called, data->n points to the current piece. + * If this is an effective piece, then first increment data->n such + * that data->n contains the number of pieces. + * The "set_list" fields are subsequently replaced by the corresponding + * "set" fields, after which the pieces are sorted according to + * the number of disjuncts in these "set" fields. + * + * Construct intermediate AST expressions for the initial pieces and + * finish off with the final pieces. + * + * Any piece that is not the very first is added to the list of arguments + * of the previously constructed piece. + * In order not to have to special case the first piece, + * an extra list is created to hold the final result. + */ +static isl_ast_expr *build_pieces(struct isl_from_pw_aff_data *data) +{ + int i; + isl_ctx *ctx; + isl_ast_expr_list *res_list; + isl_ast_expr_list **next = &res_list; + isl_ast_expr *res; + + if (data->p[data->n].state != isl_state_none) + data->n++; + ctx = isl_ast_build_get_ctx(data->build); + if (data->n == 0) + isl_die(ctx, isl_error_invalid, + "cannot handle void expression", return NULL); + + for (i = 0; i < data->n; ++i) { + data->p[i].set = isl_set_list_union(data->p[i].set_list); + if (data->p[i].state != isl_state_single) + data->p[i].set = isl_set_coalesce(data->p[i].set); + data->p[i].set_list = NULL; + } + + if (isl_sort(data->p, data->n, sizeof(data->p[0]), + &sort_pieces_cmp, NULL) < 0) + return NULL; + + res_list = isl_ast_expr_list_alloc(ctx, 1); + if (!res_list) + return NULL; + for (i = 0; i + 1 < data->n; ++i) { + next = add_intermediate_piece(data, i, next); + if (!next) + goto error; + } + + if (add_last_piece(data, data->n - 1, next) < 0) + goto error; + + res = isl_ast_expr_list_get_at(res_list, 0); + isl_ast_expr_list_free(res_list); + return res; +error: + isl_ast_expr_list_free(res_list); + return NULL; +} + +/* Is the domain of the current entry of "data", which is assumed + * to contain a single subpiece, a subset of "set"? + */ +static isl_bool single_is_subset(struct isl_from_pw_aff_data *data, + __isl_keep isl_set *set) +{ + isl_bool subset; + isl_set *set_n; + + set_n = isl_set_list_get_set(data->p[data->n].set_list, 0); + subset = isl_set_is_subset(set_n, set); + isl_set_free(set_n); + + return subset; +} + +/* Is "aff" a rational expression, i.e., does it have a denominator + * different from one? + */ +static isl_bool aff_is_rational(__isl_keep isl_aff *aff) +{ + isl_bool rational; + isl_val *den; + + den = isl_aff_get_denominator_val(aff); + rational = isl_bool_not(isl_val_is_one(den)); + isl_val_free(den); + + return rational; +} + +/* Does "list" consist of a single rational affine expression? + */ +static isl_bool is_single_rational_aff(__isl_keep isl_aff_list *list) +{ + isl_size n; + isl_bool rational; + isl_aff *aff; + + n = isl_aff_list_n_aff(list); + if (n < 0) + return isl_bool_error; + if (n != 1) + return isl_bool_false; + aff = isl_aff_list_get_aff(list, 0); + rational = aff_is_rational(aff); + isl_aff_free(aff); + + return rational; +} + +/* Can the list of subpieces in the last piece of "data" be extended with + * "set" and "aff" based on "test"? + * In particular, is it the case for each entry (set_i, aff_i) that + * + * test(aff, aff_i) holds on set_i, and + * test(aff_i, aff) holds on set? + * + * "test" returns the set of elements where the tests holds, meaning + * that test(aff_i, aff) holds on set if set is a subset of test(aff_i, aff). + * + * This function is used to detect min/max expressions. + * If the ast_build_detect_min_max option is turned off, then + * do not even try and perform any detection and return false instead. + * + * Rational affine expressions are not considered for min/max expressions + * since the combined expression will be defined on the union of the domains, + * while a rational expression may only yield integer values + * on its own definition domain. + */ +static isl_bool extends(struct isl_from_pw_aff_data *data, + __isl_keep isl_set *set, __isl_keep isl_aff *aff, + __isl_give isl_basic_set *(*test)(__isl_take isl_aff *aff1, + __isl_take isl_aff *aff2)) +{ + int i; + isl_size n; + isl_bool is_rational; + isl_ctx *ctx; + isl_set *dom; + + is_rational = aff_is_rational(aff); + if (is_rational >= 0 && !is_rational) + is_rational = is_single_rational_aff(data->p[data->n].aff_list); + if (is_rational < 0 || is_rational) + return isl_bool_not(is_rational); + + ctx = isl_ast_build_get_ctx(data->build); + if (!isl_options_get_ast_build_detect_min_max(ctx)) + return isl_bool_false; + + n = isl_set_list_n_set(data->p[data->n].set_list); + if (n < 0) + return isl_bool_error; + + dom = isl_ast_build_get_domain(data->build); + set = isl_set_intersect(dom, isl_set_copy(set)); + + for (i = 0; i < n ; ++i) { + isl_aff *aff_i; + isl_set *valid; + isl_set *dom, *required; + isl_bool is_valid; + + aff_i = isl_aff_list_get_aff(data->p[data->n].aff_list, i); + valid = isl_set_from_basic_set(test(isl_aff_copy(aff), aff_i)); + required = isl_set_list_get_set(data->p[data->n].set_list, i); + dom = isl_ast_build_get_domain(data->build); + required = isl_set_intersect(dom, required); + is_valid = isl_set_is_subset(required, valid); + isl_set_free(required); + isl_set_free(valid); + if (is_valid < 0 || !is_valid) { + isl_set_free(set); + return is_valid; + } + + aff_i = isl_aff_list_get_aff(data->p[data->n].aff_list, i); + valid = isl_set_from_basic_set(test(aff_i, isl_aff_copy(aff))); + is_valid = isl_set_is_subset(set, valid); + isl_set_free(valid); + if (is_valid < 0 || !is_valid) { + isl_set_free(set); + return is_valid; + } + } + + isl_set_free(set); + return isl_bool_true; +} + +/* Can the list of pieces in "data" be extended with "set" and "aff" + * to form/preserve a minimum expression? + * In particular, is it the case for each entry (set_i, aff_i) that + * + * aff >= aff_i on set_i, and + * aff_i >= aff on set? + */ +static isl_bool extends_min(struct isl_from_pw_aff_data *data, + __isl_keep isl_set *set, __isl_keep isl_aff *aff) +{ + return extends(data, set, aff, &isl_aff_ge_basic_set); +} + +/* Can the list of pieces in "data" be extended with "set" and "aff" + * to form/preserve a maximum expression? + * In particular, is it the case for each entry (set_i, aff_i) that + * + * aff <= aff_i on set_i, and + * aff_i <= aff on set? + */ +static isl_bool extends_max(struct isl_from_pw_aff_data *data, + __isl_keep isl_set *set, __isl_keep isl_aff *aff) +{ + return extends(data, set, aff, &isl_aff_le_basic_set); +} + +/* This function is called during the construction of an isl_ast_expr + * that evaluates an isl_pw_aff. + * If the last piece of "data" contains a single subpiece and + * if its affine function is equal to "aff" on a part of the domain + * that includes either "set" or the domain of that single subpiece, + * then extend the domain of that single subpiece with "set". + * If it was the original domain of the single subpiece where + * the two affine functions are equal, then also replace + * the affine function of the single subpiece by "aff". + * If the last piece of "data" contains either a single subpiece + * or a minimum, then check if this minimum expression can be extended + * with (set, aff). + * If so, extend the sequence and return. + * Perform the same operation for maximum expressions. + * If no such extension can be performed, then move to the next piece + * in "data" (if the current piece contains any data), and then store + * the current subpiece in the current piece of "data" for later handling. + */ +static isl_stat ast_expr_from_pw_aff(__isl_take isl_set *set, + __isl_take isl_aff *aff, void *user) +{ + struct isl_from_pw_aff_data *data = user; + isl_bool test; + enum isl_from_pw_aff_state state; + + state = data->p[data->n].state; + if (state == isl_state_single) { + isl_aff *aff0; + isl_set *eq; + isl_bool subset1, subset2 = isl_bool_false; + aff0 = isl_aff_list_get_aff(data->p[data->n].aff_list, 0); + eq = isl_aff_eq_set(isl_aff_copy(aff), aff0); + subset1 = isl_set_is_subset(set, eq); + if (subset1 >= 0 && !subset1) + subset2 = single_is_subset(data, eq); + isl_set_free(eq); + if (subset1 < 0 || subset2 < 0) + goto error; + if (subset1) + return extend_domain(data, set, aff, 0); + if (subset2) + return extend_domain(data, set, aff, 1); + } + if (state == isl_state_single || state == isl_state_min) { + test = extends_min(data, set, aff); + if (test < 0) + goto error; + if (test) + return extend_min(data, set, aff); + } + if (state == isl_state_single || state == isl_state_max) { + test = extends_max(data, set, aff); + if (test < 0) + goto error; + if (test) + return extend_max(data, set, aff); + } + if (state != isl_state_none) + data->n++; + set_single(data, set, aff); + + return isl_stat_ok; +error: + isl_set_free(set); + isl_aff_free(aff); + return isl_stat_error; +} + +/* Construct an isl_ast_expr that evaluates "pa". + * The result is simplified in terms of build->domain. + * + * The domain of "pa" lives in the internal schedule space. + */ +__isl_give isl_ast_expr *isl_ast_build_expr_from_pw_aff_internal( + __isl_keep isl_ast_build *build, __isl_take isl_pw_aff *pa) +{ + struct isl_from_pw_aff_data data = { NULL }; + isl_ast_expr *res = NULL; + + pa = isl_ast_build_compute_gist_pw_aff(build, pa); + pa = isl_pw_aff_coalesce(pa); + if (!pa) + return NULL; + + if (isl_from_pw_aff_data_init(&data, build, pa) < 0) + goto error; + set_none(&data); + + if (isl_pw_aff_foreach_piece(pa, &ast_expr_from_pw_aff, &data) >= 0) + res = build_pieces(&data); + + isl_pw_aff_free(pa); + isl_from_pw_aff_data_clear(&data); + return res; +error: + isl_pw_aff_free(pa); + isl_from_pw_aff_data_clear(&data); + return NULL; +} + +/* Construct an isl_ast_expr that evaluates "pa". + * The result is simplified in terms of build->domain. + * + * The domain of "pa" lives in the external schedule space. + */ +__isl_give isl_ast_expr *isl_ast_build_expr_from_pw_aff( + __isl_keep isl_ast_build *build, __isl_take isl_pw_aff *pa) +{ + isl_ast_expr *expr; + isl_bool needs_map; + + needs_map = isl_ast_build_need_schedule_map(build); + if (needs_map < 0) { + pa = isl_pw_aff_free(pa); + } else if (needs_map) { + isl_multi_aff *ma; + ma = isl_ast_build_get_schedule_map_multi_aff(build); + pa = isl_pw_aff_pullback_multi_aff(pa, ma); + } + expr = isl_ast_build_expr_from_pw_aff_internal(build, pa); + return expr; +} + +/* Set the ids of the input dimensions of "mpa" to the iterator ids + * of "build". + * + * The domain of "mpa" is assumed to live in the internal schedule domain. + */ +static __isl_give isl_multi_pw_aff *set_iterator_names( + __isl_keep isl_ast_build *build, __isl_take isl_multi_pw_aff *mpa) +{ + int i; + isl_size n; + + n = isl_multi_pw_aff_dim(mpa, isl_dim_in); + if (n < 0) + return isl_multi_pw_aff_free(mpa); + for (i = 0; i < n; ++i) { + isl_id *id; + + id = isl_ast_build_get_iterator_id(build, i); + mpa = isl_multi_pw_aff_set_dim_id(mpa, isl_dim_in, i, id); + } + + return mpa; +} + +/* Construct an isl_ast_expr of type "type" with as first argument "arg0" and + * the remaining arguments derived from "mpa". + * That is, construct a call or access expression that calls/accesses "arg0" + * with arguments/indices specified by "mpa". + */ +static __isl_give isl_ast_expr *isl_ast_build_with_arguments( + __isl_keep isl_ast_build *build, enum isl_ast_expr_op_type type, + __isl_take isl_ast_expr *arg0, __isl_take isl_multi_pw_aff *mpa) +{ + int i; + isl_size n; + isl_ctx *ctx; + isl_ast_expr *expr; + + ctx = isl_ast_build_get_ctx(build); + + n = isl_multi_pw_aff_dim(mpa, isl_dim_out); + expr = n >= 0 ? isl_ast_expr_alloc_op(ctx, type, 1 + n) : NULL; + expr = isl_ast_expr_op_add_arg(expr, arg0); + for (i = 0; i < n; ++i) { + isl_pw_aff *pa; + isl_ast_expr *arg; + + pa = isl_multi_pw_aff_get_pw_aff(mpa, i); + arg = isl_ast_build_expr_from_pw_aff_internal(build, pa); + expr = isl_ast_expr_op_add_arg(expr, arg); + } + + isl_multi_pw_aff_free(mpa); + return expr; +} + +static __isl_give isl_ast_expr *isl_ast_build_from_multi_pw_aff_internal( + __isl_keep isl_ast_build *build, enum isl_ast_expr_op_type type, + __isl_take isl_multi_pw_aff *mpa); + +/* Construct an isl_ast_expr that accesses the member specified by "mpa". + * The range of "mpa" is assumed to be wrapped relation. + * The domain of this wrapped relation specifies the structure being + * accessed, while the range of this wrapped relation spacifies the + * member of the structure being accessed. + * + * The domain of "mpa" is assumed to live in the internal schedule domain. + */ +static __isl_give isl_ast_expr *isl_ast_build_from_multi_pw_aff_member( + __isl_keep isl_ast_build *build, __isl_take isl_multi_pw_aff *mpa) +{ + isl_id *id; + isl_multi_pw_aff *domain; + isl_ast_expr *domain_expr, *expr; + enum isl_ast_expr_op_type type = isl_ast_expr_op_access; + + domain = isl_multi_pw_aff_copy(mpa); + domain = isl_multi_pw_aff_range_factor_domain(domain); + domain_expr = isl_ast_build_from_multi_pw_aff_internal(build, + type, domain); + mpa = isl_multi_pw_aff_range_factor_range(mpa); + if (!isl_multi_pw_aff_has_tuple_id(mpa, isl_dim_out)) + isl_die(isl_ast_build_get_ctx(build), isl_error_invalid, + "missing field name", goto error); + id = isl_multi_pw_aff_get_tuple_id(mpa, isl_dim_out); + expr = isl_ast_expr_from_id(id); + expr = isl_ast_expr_alloc_binary(isl_ast_expr_op_member, + domain_expr, expr); + return isl_ast_build_with_arguments(build, type, expr, mpa); +error: + isl_multi_pw_aff_free(mpa); + return NULL; +} + +/* Construct an isl_ast_expr of type "type" that calls or accesses + * the element specified by "mpa". + * The first argument is obtained from the output tuple name. + * The remaining arguments are given by the piecewise affine expressions. + * + * If the range of "mpa" is a mapped relation, then we assume it + * represents an access to a member of a structure. + * + * The domain of "mpa" is assumed to live in the internal schedule domain. + */ +static __isl_give isl_ast_expr *isl_ast_build_from_multi_pw_aff_internal( + __isl_keep isl_ast_build *build, enum isl_ast_expr_op_type type, + __isl_take isl_multi_pw_aff *mpa) +{ + isl_ctx *ctx; + isl_id *id; + isl_ast_expr *expr; + + if (!mpa) + goto error; + + if (type == isl_ast_expr_op_access && + isl_multi_pw_aff_range_is_wrapping(mpa)) + return isl_ast_build_from_multi_pw_aff_member(build, mpa); + + mpa = set_iterator_names(build, mpa); + if (!build || !mpa) + goto error; + + ctx = isl_ast_build_get_ctx(build); + + if (isl_multi_pw_aff_has_tuple_id(mpa, isl_dim_out)) + id = isl_multi_pw_aff_get_tuple_id(mpa, isl_dim_out); + else + id = isl_id_alloc(ctx, "", NULL); + + expr = isl_ast_expr_from_id(id); + return isl_ast_build_with_arguments(build, type, expr, mpa); +error: + isl_multi_pw_aff_free(mpa); + return NULL; +} + +/* Construct an isl_ast_expr of type "type" that calls or accesses + * the element specified by "pma". + * The first argument is obtained from the output tuple name. + * The remaining arguments are given by the piecewise affine expressions. + * + * The domain of "pma" is assumed to live in the internal schedule domain. + */ +static __isl_give isl_ast_expr *isl_ast_build_from_pw_multi_aff_internal( + __isl_keep isl_ast_build *build, enum isl_ast_expr_op_type type, + __isl_take isl_pw_multi_aff *pma) +{ + isl_multi_pw_aff *mpa; + + mpa = isl_multi_pw_aff_from_pw_multi_aff(pma); + return isl_ast_build_from_multi_pw_aff_internal(build, type, mpa); +} + +/* Construct an isl_ast_expr of type "type" that calls or accesses + * the element specified by "mpa". + * The first argument is obtained from the output tuple name. + * The remaining arguments are given by the piecewise affine expressions. + * + * The domain of "mpa" is assumed to live in the external schedule domain. + */ +static __isl_give isl_ast_expr *isl_ast_build_from_multi_pw_aff( + __isl_keep isl_ast_build *build, enum isl_ast_expr_op_type type, + __isl_take isl_multi_pw_aff *mpa) +{ + isl_bool is_domain; + isl_bool needs_map; + isl_ast_expr *expr; + isl_space *space_build, *space_mpa; + + space_build = isl_ast_build_get_space(build, 0); + space_mpa = isl_multi_pw_aff_get_space(mpa); + is_domain = isl_space_tuple_is_equal(space_build, isl_dim_set, + space_mpa, isl_dim_in); + isl_space_free(space_build); + isl_space_free(space_mpa); + if (is_domain < 0) + goto error; + if (!is_domain) + isl_die(isl_ast_build_get_ctx(build), isl_error_invalid, + "spaces don't match", goto error); + + needs_map = isl_ast_build_need_schedule_map(build); + if (needs_map < 0) + goto error; + if (needs_map) { + isl_multi_aff *ma; + ma = isl_ast_build_get_schedule_map_multi_aff(build); + mpa = isl_multi_pw_aff_pullback_multi_aff(mpa, ma); + } + + expr = isl_ast_build_from_multi_pw_aff_internal(build, type, mpa); + return expr; +error: + isl_multi_pw_aff_free(mpa); + return NULL; +} + +/* Construct an isl_ast_expr that calls the domain element specified by "mpa". + * The name of the function is obtained from the output tuple name. + * The arguments are given by the piecewise affine expressions. + * + * The domain of "mpa" is assumed to live in the external schedule domain. + */ +__isl_give isl_ast_expr *isl_ast_build_call_from_multi_pw_aff( + __isl_keep isl_ast_build *build, __isl_take isl_multi_pw_aff *mpa) +{ + return isl_ast_build_from_multi_pw_aff(build, + isl_ast_expr_op_call, mpa); +} + +/* Construct an isl_ast_expr that accesses the array element specified by "mpa". + * The name of the array is obtained from the output tuple name. + * The index expressions are given by the piecewise affine expressions. + * + * The domain of "mpa" is assumed to live in the external schedule domain. + */ +__isl_give isl_ast_expr *isl_ast_build_access_from_multi_pw_aff( + __isl_keep isl_ast_build *build, __isl_take isl_multi_pw_aff *mpa) +{ + return isl_ast_build_from_multi_pw_aff(build, + isl_ast_expr_op_access, mpa); +} + +/* Construct an isl_ast_expr of type "type" that calls or accesses + * the element specified by "pma". + * The first argument is obtained from the output tuple name. + * The remaining arguments are given by the piecewise affine expressions. + * + * The domain of "pma" is assumed to live in the external schedule domain. + */ +static __isl_give isl_ast_expr *isl_ast_build_from_pw_multi_aff( + __isl_keep isl_ast_build *build, enum isl_ast_expr_op_type type, + __isl_take isl_pw_multi_aff *pma) +{ + isl_multi_pw_aff *mpa; + + mpa = isl_multi_pw_aff_from_pw_multi_aff(pma); + return isl_ast_build_from_multi_pw_aff(build, type, mpa); +} + +/* Construct an isl_ast_expr that calls the domain element specified by "pma". + * The name of the function is obtained from the output tuple name. + * The arguments are given by the piecewise affine expressions. + * + * The domain of "pma" is assumed to live in the external schedule domain. + */ +__isl_give isl_ast_expr *isl_ast_build_call_from_pw_multi_aff( + __isl_keep isl_ast_build *build, __isl_take isl_pw_multi_aff *pma) +{ + return isl_ast_build_from_pw_multi_aff(build, + isl_ast_expr_op_call, pma); +} + +/* Construct an isl_ast_expr that accesses the array element specified by "pma". + * The name of the array is obtained from the output tuple name. + * The index expressions are given by the piecewise affine expressions. + * + * The domain of "pma" is assumed to live in the external schedule domain. + */ +__isl_give isl_ast_expr *isl_ast_build_access_from_pw_multi_aff( + __isl_keep isl_ast_build *build, __isl_take isl_pw_multi_aff *pma) +{ + return isl_ast_build_from_pw_multi_aff(build, + isl_ast_expr_op_access, pma); +} + +/* Construct an isl_ast_expr that calls the domain element + * specified by "executed". + * + * "executed" is assumed to be single-valued, with a domain that lives + * in the internal schedule space. + */ +__isl_give isl_ast_node *isl_ast_build_call_from_executed( + __isl_keep isl_ast_build *build, __isl_take isl_map *executed) +{ + isl_pw_multi_aff *iteration; + isl_ast_expr *expr; + + iteration = isl_pw_multi_aff_from_map(executed); + iteration = isl_ast_build_compute_gist_pw_multi_aff(build, iteration); + iteration = isl_pw_multi_aff_intersect_domain(iteration, + isl_ast_build_get_domain(build)); + expr = isl_ast_build_from_pw_multi_aff_internal(build, + isl_ast_expr_op_call, iteration); + return isl_ast_node_alloc_user(expr); +} diff --git a/external/mit/isl/dist/isl_ast_build_expr.h b/external/mit/isl/dist/isl_ast_build_expr.h new file mode 100644 index 000000000000..362f2bffc4ad --- /dev/null +++ b/external/mit/isl/dist/isl_ast_build_expr.h @@ -0,0 +1,22 @@ +#ifndef ISL_AST_BUILD_EXPR_PRIVATE_H +#define ISL_AST_BUILD_EXPR_PRIVATE_H + +#include +#include + +__isl_give isl_ast_expr *isl_ast_build_expr_from_basic_set( + __isl_keep isl_ast_build *build, __isl_take isl_basic_set *bset); +__isl_give isl_ast_expr *isl_ast_build_expr_from_set_internal( + __isl_keep isl_ast_build *build, __isl_take isl_set *set); + +__isl_give isl_ast_expr *isl_ast_build_expr_from_pw_aff_internal( + __isl_keep isl_ast_build *build, __isl_take isl_pw_aff *pa); +__isl_give isl_ast_expr *isl_ast_expr_from_aff(__isl_take isl_aff *aff, + __isl_keep isl_ast_build *build); +__isl_give isl_ast_expr *isl_ast_expr_set_op_arg(__isl_take isl_ast_expr *expr, + int pos, __isl_take isl_ast_expr *arg); + +__isl_give isl_ast_node *isl_ast_build_call_from_executed( + __isl_keep isl_ast_build *build, __isl_take isl_map *executed); + +#endif diff --git a/external/mit/isl/dist/isl_ast_build_private.h b/external/mit/isl/dist/isl_ast_build_private.h new file mode 100644 index 000000000000..cb10fb4d86f3 --- /dev/null +++ b/external/mit/isl/dist/isl_ast_build_private.h @@ -0,0 +1,327 @@ +#ifndef ISL_AST_BUILD_PRIVATE_H +#define ISL_AST_BUILD_PRIVATE_H + +#include +#include +#include +#include +#include +#include + +/* An isl_ast_build represents the context in which AST is being + * generated. That is, it (mostly) contains information about outer + * loops that can be used to simplify inner loops. + * + * "domain" represents constraints on the internal schedule domain, + * corresponding to the context of the AST generation and the constraints + * implied by the loops that have already been generated. + * When an isl_ast_build is first created, outside any AST generation, + * the domain is typically a parameter set. It is only when a AST + * generation phase is initiated that the domain of the isl_ast_build + * is changed to refer to the internal schedule domain. + * The domain then lives in a space of the form + * + * S + * + * or + * + * [O -> S] + * + * O represents the loops generated in outer AST generations. + * S represents the loops (both generated and to be generated) + * of the current AST generation. + * Both include eliminated loops. + * "domain" is expected not to have any unknown divs because + * it is used as the context argument in a call to isl_basic_set_gist + * in isl_ast_build_compute_gist_basic_set. + * + * "depth" is equal to the number of loops that have already + * been generated (including those in outer AST generations). + * "outer_pos" is equal to the number of loops in outer AST generations. + * + * "generated" is a superset of "domain" corresponding to those + * constraints that were either given by the user or that have + * effectively been generated (as bounds on a for loop). + * + * "pending" is a superset of "domain" corresponding to the constraints + * that still need to be generated (as guards), but that may end up + * not getting generated if they are implied by any constraints + * enforced by inner loops. + * + * "strides" contains the stride of each loop. The number of elements + * is equal to the number of dimensions in "domain". + * "offsets" contains the offsets of strided loops. If s is the stride + * for a given dimension and f is the corresponding offset, then the + * dimension takes on values + * + * f + s a + * + * with a an integer. For non-strided loops, the offset is zero. + * + * "iterators" contains the loop iterators of both generated and + * to be generated loops. The number of elements is at least as + * large as the dimension of the internal schedule domain. The + * number may be larger, in which case the additional ids can be + * used in a nested AST generation should the schedule be non-injective. + * + * "values" lives in the space + * + * [O -> S] -> [O -> S] (or S -> S) + * + * and expresses (if possible) loop iterators in terms of parameters + * and outer loop iterators. If the value of a given loop iterator + * cannot be expressed as an affine expression (either because the iterator + * attains multiple values or because the single value is a piecewise + * affine expression), then it is expressed in "values" as being equal + * to itself. + * + * "value" is the value of the loop iterator at the current depth. + * It is NULL if it has not been computed yet or if the value of the + * given loop iterator cannot be expressed as a piecewise affine expression + * (because the iterator attains multiple values). + * + * "schedule_map" maps the internal schedule domain to the external schedule + * domain. It may be NULL if it hasn't been computed yet. + * See isl_ast_build_get_schedule_map_multi_aff. + * + * "internal2input" maps the internal schedule domain to the original + * input schedule domain. In case of a schedule tree input, the original + * input schedule domain consist of the flat product of all outer + * band node spaces, including the current band node. + * It may be NULL if there no longer is such a uniform mapping + * (because different iterations have been rescheduled differently). + * + * "options" contains the AST build options in case we are generating + * an AST from a flat schedule map. When creating an AST from a schedule + * tree, this field is ignored. + * + * The "create_leaf" callback is called for every leaf in the generated AST. + * The callback is responsible for creating the node to be placed at those + * leaves. If this callback is not set, then isl will generated user + * nodes with call expressions corresponding to an element of the domain. + * + * The "at_each_domain" callback is called on every node created to represent + * an element of the domain. Each of these nodes is a user node + * with as expression a call expression. + * + * The "before_each_for" callback is called on each for node before + * its children have been created. + * + * The "after_each_for" callback is called on each for node after + * its children have been created. + * + * The "before_each_mark" callback is called before we handle the subtree + * of an isl_schedule_node_mark node. + * + * The "after_each_mark" callback is called after we have handled the subtree + * of an isl_schedule_node_mark node. + * + * "executed" contains the inverse schedule at this point + * of the AST generation. + * It is currently only used in isl_ast_build_get_schedule, which is + * in turn only used by user code from within a callback. + * The value is set right before we may be calling such a callback. + * + * "single_valued" is set if the current inverse schedule (which may or may + * not be stored in "executed") is known to be single valued, specifically + * an inverse schedule that was not (appeared not to be) single valued + * is extended to a single valued inverse schedule. This is mainly used + * to avoid an infinite recursion when we fail to detect later on that + * the extended inverse schedule is single valued. + * + * "node" points to the current band node in case we are generating + * an AST from a schedule tree. It may be NULL if we are not generating + * an AST from a schedule tree or if we are not inside a band node. + * + * "loop_type" originally contains loop AST generation types for + * the "n" members of "node" and it is updated (along with "n") when + * a schedule dimension is inserted. + * It is NULL if "node" is NULL. + * + * "isolated" is the piece of the schedule domain isolated by the isolate + * option on the current band. This set may be NULL if we have not checked + * for the isolate option yet. + */ +struct isl_ast_build { + int ref; + + int outer_pos; + int depth; + + isl_id_list *iterators; + + isl_set *domain; + isl_set *generated; + isl_set *pending; + isl_multi_aff *values; + + isl_pw_aff *value; + + isl_vec *strides; + isl_multi_aff *offsets; + + isl_multi_aff *schedule_map; + isl_multi_aff *internal2input; + + isl_union_map *options; + + __isl_give isl_ast_node *(*at_each_domain)( + __isl_take isl_ast_node *node, + __isl_keep isl_ast_build *build, void *user); + void *at_each_domain_user; + + __isl_give isl_id *(*before_each_for)( + __isl_keep isl_ast_build *context, void *user); + void *before_each_for_user; + __isl_give isl_ast_node *(*after_each_for)( + __isl_take isl_ast_node *node, + __isl_keep isl_ast_build *context, void *user); + void *after_each_for_user; + + isl_stat (*before_each_mark)(__isl_keep isl_id *mark, + __isl_keep isl_ast_build *build, void *user); + void *before_each_mark_user; + __isl_give isl_ast_node *(*after_each_mark)( + __isl_take isl_ast_node *node, + __isl_keep isl_ast_build *context, void *user); + void *after_each_mark_user; + + __isl_give isl_ast_node *(*create_leaf)( + __isl_take isl_ast_build *build, void *user); + void *create_leaf_user; + + isl_union_map *executed; + int single_valued; + + isl_schedule_node *node; + int n; + enum isl_ast_loop_type *loop_type; + isl_set *isolated; +}; + +__isl_give isl_ast_build *isl_ast_build_clear_local_info( + __isl_take isl_ast_build *build); +__isl_give isl_ast_build *isl_ast_build_increase_depth( + __isl_take isl_ast_build *build); +isl_size isl_ast_build_get_depth(__isl_keep isl_ast_build *build); +isl_size isl_ast_build_dim(__isl_keep isl_ast_build *build, + enum isl_dim_type type); +__isl_give isl_space *isl_ast_build_get_space( + __isl_keep isl_ast_build *build, int internal); +__isl_give isl_ast_build *isl_ast_build_align_params( + __isl_take isl_ast_build *build, __isl_take isl_space *model); +__isl_give isl_ast_build *isl_ast_build_cow( + __isl_take isl_ast_build *build); +__isl_give isl_ast_build *isl_ast_build_insert_dim( + __isl_take isl_ast_build *build, int pos); +__isl_give isl_ast_build *isl_ast_build_scale_down( + __isl_take isl_ast_build *build, __isl_take isl_val *m, + __isl_take isl_union_map *umap); +__isl_give isl_ast_build *isl_ast_build_product( + __isl_take isl_ast_build *build, __isl_take isl_space *embedding); +__isl_give isl_ast_build *isl_ast_build_set_loop_bounds( + __isl_take isl_ast_build *build, __isl_take isl_basic_set *bounds); +__isl_give isl_ast_build *isl_ast_build_set_pending_generated( + __isl_take isl_ast_build *build, __isl_take isl_basic_set *bounds); +__isl_give isl_ast_build *isl_ast_build_detect_strides( + __isl_take isl_ast_build *build, __isl_take isl_set *set); +__isl_give isl_ast_build *isl_ast_build_include_stride( + __isl_take isl_ast_build *build); +__isl_give isl_ast_build *isl_ast_build_set_executed( + __isl_take isl_ast_build *build, + __isl_take isl_union_map *executed); +__isl_give isl_ast_build *isl_ast_build_set_single_valued( + __isl_take isl_ast_build *build, int sv); +__isl_give isl_multi_aff *isl_ast_build_get_internal2input( + __isl_keep isl_ast_build *build); +__isl_give isl_set *isl_ast_build_get_domain( + __isl_keep isl_ast_build *build); +__isl_give isl_set *isl_ast_build_get_pending( + __isl_keep isl_ast_build *build); +__isl_give isl_set *isl_ast_build_get_generated( + __isl_keep isl_ast_build *build); +__isl_give isl_ast_build *isl_ast_build_restrict_generated( + __isl_take isl_ast_build *build, __isl_take isl_set *set); +__isl_give isl_ast_build *isl_ast_build_replace_pending_by_guard( + __isl_take isl_ast_build *build, __isl_take isl_set *guard); +isl_bool isl_ast_build_need_schedule_map(__isl_keep isl_ast_build *build); +__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); +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); + +int isl_ast_build_has_schedule_node(__isl_keep isl_ast_build *build); +__isl_give isl_schedule_node *isl_ast_build_get_schedule_node( + __isl_keep isl_ast_build *build); +__isl_give isl_ast_build *isl_ast_build_set_schedule_node( + __isl_take isl_ast_build *build, + __isl_take isl_schedule_node *node); +__isl_give isl_ast_build *isl_ast_build_reset_schedule_node( + __isl_take isl_ast_build *build); + +__isl_give isl_ast_build *isl_ast_build_extract_isolated( + __isl_take isl_ast_build *build); +int isl_ast_build_has_isolated(__isl_keep isl_ast_build *build); +__isl_give isl_set *isl_ast_build_get_isolated( + __isl_keep isl_ast_build *build); + +__isl_give isl_basic_set *isl_ast_build_specialize_basic_set( + __isl_keep isl_ast_build *build, __isl_take isl_basic_set *bset); +__isl_give isl_basic_set *isl_ast_build_compute_gist_basic_set( + __isl_keep isl_ast_build *build, __isl_take isl_basic_set *bset); +__isl_give isl_set *isl_ast_build_specialize(__isl_keep isl_ast_build *build, + __isl_take isl_set *set); +__isl_give isl_set *isl_ast_build_compute_gist( + __isl_keep isl_ast_build *build, __isl_take isl_set *set); +__isl_give isl_map *isl_ast_build_compute_gist_map_domain( + __isl_keep isl_ast_build *build, __isl_take isl_map *map); +__isl_give isl_aff *isl_ast_build_compute_gist_aff( + __isl_keep isl_ast_build *build, __isl_take isl_aff *aff); +__isl_give isl_pw_aff *isl_ast_build_compute_gist_pw_aff( + __isl_keep isl_ast_build *build, __isl_take isl_pw_aff *pa); +__isl_give isl_pw_multi_aff *isl_ast_build_compute_gist_pw_multi_aff( + __isl_keep isl_ast_build *build, __isl_take isl_pw_multi_aff *pma); + +__isl_give isl_union_map *isl_ast_build_substitute_values_union_map_domain( + __isl_keep isl_ast_build *build, __isl_take isl_union_map *umap); + +isl_bool isl_ast_build_aff_is_nonneg(__isl_keep isl_ast_build *build, + __isl_keep isl_aff *aff); + +isl_bool isl_ast_build_has_stride(__isl_keep isl_ast_build *build, int pos); +__isl_give isl_aff *isl_ast_build_get_offset(__isl_keep isl_ast_build *build, + int pos); +__isl_give isl_val *isl_ast_build_get_stride(__isl_keep isl_ast_build *build, + int pos); +__isl_give isl_set *isl_ast_build_get_stride_constraint( + __isl_keep isl_ast_build *build); +__isl_give isl_multi_aff *isl_ast_build_get_stride_expansion( + __isl_keep isl_ast_build *build); + +void isl_ast_build_dump(__isl_keep isl_ast_build *build); + +__isl_give isl_set *isl_ast_build_get_option_domain( + __isl_keep isl_ast_build *build, enum isl_ast_loop_type type); +__isl_give isl_map *isl_ast_build_get_separation_class( + __isl_keep isl_ast_build *build); +__isl_give isl_set *isl_ast_build_eliminate( + __isl_keep isl_ast_build *build, __isl_take isl_set *domain); +__isl_give isl_set *isl_ast_build_eliminate_inner( + __isl_keep isl_ast_build *build, __isl_take isl_set *set); +__isl_give isl_set *isl_ast_build_eliminate_divs( + __isl_keep isl_ast_build *build, __isl_take isl_set *set); + +enum isl_ast_loop_type isl_ast_build_get_loop_type( + __isl_keep isl_ast_build *build, int isolated); + +__isl_give isl_map *isl_ast_build_map_to_iterator( + __isl_keep isl_ast_build *build, __isl_take isl_set *set); + +int isl_ast_build_options_involve_depth(__isl_keep isl_ast_build *build); + +#endif diff --git a/external/mit/isl/dist/isl_ast_codegen.c b/external/mit/isl/dist/isl_ast_codegen.c new file mode 100644 index 000000000000..774dfab72296 --- /dev/null +++ b/external/mit/isl/dist/isl_ast_codegen.c @@ -0,0 +1,5941 @@ +/* + * Copyright 2012-2014 Ecole Normale Superieure + * Copyright 2014 INRIA Rocquencourt + * + * Use of this software is governed by the MIT license + * + * Written by Sven Verdoolaege, + * Ecole Normale Superieure, 45 rue d’Ulm, 75230 Paris, France + * and Inria Paris - Rocquencourt, Domaine de Voluceau - Rocquencourt, + * B.P. 105 - 78153 Le Chesnay, France + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Try and reduce the number of disjuncts in the representation of "set", + * without dropping explicit representations of local variables. + */ +static __isl_give isl_set *isl_set_coalesce_preserve(__isl_take isl_set *set) +{ + isl_ctx *ctx; + int save_preserve; + + if (!set) + return NULL; + + ctx = isl_set_get_ctx(set); + save_preserve = isl_options_get_coalesce_preserve_locals(ctx); + isl_options_set_coalesce_preserve_locals(ctx, 1); + set = isl_set_coalesce(set); + isl_options_set_coalesce_preserve_locals(ctx, save_preserve); + return set; +} + +/* Data used in generate_domain. + * + * "build" is the input build. + * "list" collects the results. + */ +struct isl_generate_domain_data { + isl_ast_build *build; + + isl_ast_graft_list *list; +}; + +static __isl_give isl_ast_graft_list *generate_next_level( + __isl_take isl_union_map *executed, + __isl_take isl_ast_build *build); +static __isl_give isl_ast_graft_list *generate_code( + __isl_take isl_union_map *executed, __isl_take isl_ast_build *build, + int internal); + +/* Generate an AST for a single domain based on + * the (non single valued) inverse schedule "executed". + * + * We extend the schedule with the iteration domain + * and continue generating through a call to generate_code. + * + * In particular, if executed has the form + * + * S -> D + * + * then we continue generating code on + * + * [S -> D] -> D + * + * The extended inverse schedule is clearly single valued + * ensuring that the nested generate_code will not reach this function, + * but will instead create calls to all elements of D that need + * to be executed from the current schedule domain. + */ +static isl_stat generate_non_single_valued(__isl_take isl_map *executed, + struct isl_generate_domain_data *data) +{ + isl_map *identity; + isl_ast_build *build; + isl_ast_graft_list *list; + + build = isl_ast_build_copy(data->build); + + identity = isl_set_identity(isl_map_range(isl_map_copy(executed))); + executed = isl_map_domain_product(executed, identity); + build = isl_ast_build_set_single_valued(build, 1); + + list = generate_code(isl_union_map_from_map(executed), build, 1); + + data->list = isl_ast_graft_list_concat(data->list, list); + + return isl_stat_ok; +} + +/* Call the at_each_domain callback, if requested by the user, + * after recording the current inverse schedule in the build. + */ +static __isl_give isl_ast_graft *at_each_domain(__isl_take isl_ast_graft *graft, + __isl_keep isl_map *executed, __isl_keep isl_ast_build *build) +{ + if (!graft || !build) + return isl_ast_graft_free(graft); + if (!build->at_each_domain) + return graft; + + build = isl_ast_build_copy(build); + build = isl_ast_build_set_executed(build, + isl_union_map_from_map(isl_map_copy(executed))); + if (!build) + return isl_ast_graft_free(graft); + + graft->node = build->at_each_domain(graft->node, + build, build->at_each_domain_user); + isl_ast_build_free(build); + + if (!graft->node) + graft = isl_ast_graft_free(graft); + + return graft; +} + +/* Generate a call expression for the single executed + * domain element "map" and put a guard around it based its (simplified) + * domain. "executed" is the original inverse schedule from which "map" + * has been derived. In particular, "map" is either identical to "executed" + * or it is the result of gisting "executed" with respect to the build domain. + * "executed" is only used if there is an at_each_domain callback. + * + * At this stage, any pending constraints in the build can no longer + * be simplified with respect to any enforced constraints since + * the call node does not have any enforced constraints. + * Since all pending constraints not covered by any enforced constraints + * will be added as a guard to the graft in create_node_scaled, + * even in the eliminated case, the pending constraints + * can be considered to have been generated by outer constructs. + * + * If the user has set an at_each_domain callback, it is called + * on the constructed call expression node. + */ +static isl_stat add_domain(__isl_take isl_map *executed, + __isl_take isl_map *map, struct isl_generate_domain_data *data) +{ + isl_ast_build *build; + isl_ast_graft *graft; + isl_ast_graft_list *list; + isl_set *guard, *pending; + + build = isl_ast_build_copy(data->build); + pending = isl_ast_build_get_pending(build); + build = isl_ast_build_replace_pending_by_guard(build, pending); + + guard = isl_map_domain(isl_map_copy(map)); + guard = isl_set_compute_divs(guard); + guard = isl_set_coalesce_preserve(guard); + guard = isl_set_gist(guard, isl_ast_build_get_generated(build)); + guard = isl_ast_build_specialize(build, guard); + + graft = isl_ast_graft_alloc_domain(map, build); + graft = at_each_domain(graft, executed, build); + isl_ast_build_free(build); + isl_map_free(executed); + graft = isl_ast_graft_add_guard(graft, guard, data->build); + + list = isl_ast_graft_list_from_ast_graft(graft); + data->list = isl_ast_graft_list_concat(data->list, list); + + return isl_stat_ok; +} + +/* Generate an AST for a single domain based on + * the inverse schedule "executed" and add it to data->list. + * + * If there is more than one domain element associated to the current + * schedule "time", then we need to continue the generation process + * in generate_non_single_valued. + * Note that the inverse schedule being single-valued may depend + * on constraints that are only available in the original context + * domain specified by the user. We therefore first introduce + * some of the constraints of data->build->domain. In particular, + * we intersect with a single-disjunct approximation of this set. + * We perform this approximation to avoid further splitting up + * the executed relation, possibly introducing a disjunctive guard + * on the statement. + * + * On the other hand, we only perform the test after having taken the gist + * of the domain as the resulting map is the one from which the call + * expression is constructed. Using this map to construct the call + * expression usually yields simpler results in cases where the original + * map is not obviously single-valued. + * If the original map is obviously single-valued, then the gist + * operation is skipped. + * + * Because we perform the single-valuedness test on the gisted map, + * we may in rare cases fail to recognize that the inverse schedule + * is single-valued. This becomes problematic if this happens + * from the recursive call through generate_non_single_valued + * as we would then end up in an infinite recursion. + * We therefore check if we are inside a call to generate_non_single_valued + * and revert to the ungisted map if the gisted map turns out not to be + * single-valued. + * + * Otherwise, call add_domain to generate a call expression (with guard) and + * to call the at_each_domain callback, if any. + */ +static isl_stat generate_domain(__isl_take isl_map *executed, void *user) +{ + struct isl_generate_domain_data *data = user; + isl_set *domain; + isl_map *map = NULL; + int empty, sv; + + domain = isl_ast_build_get_domain(data->build); + domain = isl_set_from_basic_set(isl_set_simple_hull(domain)); + executed = isl_map_intersect_domain(executed, domain); + empty = isl_map_is_empty(executed); + if (empty < 0) + goto error; + if (empty) { + isl_map_free(executed); + return isl_stat_ok; + } + + sv = isl_map_plain_is_single_valued(executed); + if (sv < 0) + goto error; + if (sv) + return add_domain(executed, isl_map_copy(executed), data); + + executed = isl_map_coalesce(executed); + map = isl_map_copy(executed); + map = isl_ast_build_compute_gist_map_domain(data->build, map); + sv = isl_map_is_single_valued(map); + if (sv < 0) + goto error; + if (!sv) { + isl_map_free(map); + if (data->build->single_valued) + map = isl_map_copy(executed); + else + return generate_non_single_valued(executed, data); + } + + return add_domain(executed, map, data); +error: + isl_map_free(map); + isl_map_free(executed); + return isl_stat_error; +} + +/* Call build->create_leaf to a create "leaf" node in the AST, + * encapsulate the result in an isl_ast_graft and return the result + * as a 1-element list. + * + * Note that the node returned by the user may be an entire tree. + * + * Since the node itself cannot enforce any constraints, we turn + * all pending constraints into guards and add them to the resulting + * graft to ensure that they will be generated. + * + * Before we pass control to the user, we first clear some information + * from the build that is (presumbably) only meaningful + * for the current code generation. + * This includes the create_leaf callback itself, so we make a copy + * of the build first. + */ +static __isl_give isl_ast_graft_list *call_create_leaf( + __isl_take isl_union_map *executed, __isl_take isl_ast_build *build) +{ + isl_set *guard; + isl_ast_node *node; + isl_ast_graft *graft; + isl_ast_build *user_build; + + guard = isl_ast_build_get_pending(build); + user_build = isl_ast_build_copy(build); + user_build = isl_ast_build_replace_pending_by_guard(user_build, + isl_set_copy(guard)); + user_build = isl_ast_build_set_executed(user_build, executed); + user_build = isl_ast_build_clear_local_info(user_build); + if (!user_build) + node = NULL; + else + node = build->create_leaf(user_build, build->create_leaf_user); + graft = isl_ast_graft_alloc(node, build); + graft = isl_ast_graft_add_guard(graft, guard, build); + isl_ast_build_free(build); + return isl_ast_graft_list_from_ast_graft(graft); +} + +static __isl_give isl_ast_graft_list *build_ast_from_child( + __isl_take isl_ast_build *build, __isl_take isl_schedule_node *node, + __isl_take isl_union_map *executed); + +/* Generate an AST after having handled the complete schedule + * of this call to the code generator or the complete band + * if we are generating an AST from a schedule tree. + * + * If we are inside a band node, then move on to the child of the band. + * + * If the user has specified a create_leaf callback, control + * is passed to the user in call_create_leaf. + * + * Otherwise, we generate one or more calls for each individual + * domain in generate_domain. + */ +static __isl_give isl_ast_graft_list *generate_inner_level( + __isl_take isl_union_map *executed, __isl_take isl_ast_build *build) +{ + isl_ctx *ctx; + struct isl_generate_domain_data data = { build }; + + if (!build || !executed) + goto error; + + if (isl_ast_build_has_schedule_node(build)) { + isl_schedule_node *node; + node = isl_ast_build_get_schedule_node(build); + build = isl_ast_build_reset_schedule_node(build); + return build_ast_from_child(build, node, executed); + } + + if (build->create_leaf) + return call_create_leaf(executed, build); + + ctx = isl_union_map_get_ctx(executed); + data.list = isl_ast_graft_list_alloc(ctx, 0); + if (isl_union_map_foreach_map(executed, &generate_domain, &data) < 0) + data.list = isl_ast_graft_list_free(data.list); + + if (0) +error: data.list = NULL; + isl_ast_build_free(build); + isl_union_map_free(executed); + return data.list; +} + +/* Call the before_each_for callback, if requested by the user. + */ +static __isl_give isl_ast_node *before_each_for(__isl_take isl_ast_node *node, + __isl_keep isl_ast_build *build) +{ + isl_id *id; + + if (!node || !build) + return isl_ast_node_free(node); + if (!build->before_each_for) + return node; + id = build->before_each_for(build, build->before_each_for_user); + node = isl_ast_node_set_annotation(node, id); + return node; +} + +/* Call the after_each_for callback, if requested by the user. + */ +static __isl_give isl_ast_graft *after_each_for(__isl_take isl_ast_graft *graft, + __isl_keep isl_ast_build *build) +{ + if (!graft || !build) + return isl_ast_graft_free(graft); + if (!build->after_each_for) + return graft; + graft->node = build->after_each_for(graft->node, build, + build->after_each_for_user); + if (!graft->node) + return isl_ast_graft_free(graft); + return graft; +} + +/* Plug in all the know values of the current and outer dimensions + * in the domain of "executed". In principle, we only need to plug + * in the known value of the current dimension since the values of + * outer dimensions have been plugged in already. + * However, it turns out to be easier to just plug in all known values. + */ +static __isl_give isl_union_map *plug_in_values( + __isl_take isl_union_map *executed, __isl_keep isl_ast_build *build) +{ + return isl_ast_build_substitute_values_union_map_domain(build, + executed); +} + +/* Check if the constraint "c" is a lower bound on dimension "pos", + * an upper bound, or independent of dimension "pos". + */ +static int constraint_type(isl_constraint *c, int pos) +{ + if (isl_constraint_is_lower_bound(c, isl_dim_set, pos)) + return 1; + if (isl_constraint_is_upper_bound(c, isl_dim_set, pos)) + return 2; + return 0; +} + +/* Compare the types of the constraints "a" and "b", + * resulting in constraints that are independent of "depth" + * to be sorted before the lower bounds on "depth", which in + * turn are sorted before the upper bounds on "depth". + */ +static int cmp_constraint(__isl_keep isl_constraint *a, + __isl_keep isl_constraint *b, void *user) +{ + int *depth = user; + int t1 = constraint_type(a, *depth); + int t2 = constraint_type(b, *depth); + + return t1 - t2; +} + +/* Extract a lower bound on dimension "pos" from constraint "c". + * + * If the constraint is of the form + * + * a x + f(...) >= 0 + * + * then we essentially return + * + * l = ceil(-f(...)/a) + * + * However, if the current dimension is strided, then we need to make + * sure that the lower bound we construct is of the form + * + * f + s a + * + * with f the offset and s the stride. + * We therefore compute + * + * f + s * ceil((l - f)/s) + */ +static __isl_give isl_aff *lower_bound(__isl_keep isl_constraint *c, + int pos, __isl_keep isl_ast_build *build) +{ + isl_aff *aff; + + aff = isl_constraint_get_bound(c, isl_dim_set, pos); + aff = isl_aff_ceil(aff); + + if (isl_ast_build_has_stride(build, pos)) { + isl_aff *offset; + isl_val *stride; + + offset = isl_ast_build_get_offset(build, pos); + stride = isl_ast_build_get_stride(build, pos); + + aff = isl_aff_sub(aff, isl_aff_copy(offset)); + aff = isl_aff_scale_down_val(aff, isl_val_copy(stride)); + aff = isl_aff_ceil(aff); + aff = isl_aff_scale_val(aff, stride); + aff = isl_aff_add(aff, offset); + } + + aff = isl_ast_build_compute_gist_aff(build, aff); + + return aff; +} + +/* Return the exact lower bound (or upper bound if "upper" is set) + * of "domain" as a piecewise affine expression. + * + * If we are computing a lower bound (of a strided dimension), then + * we need to make sure it is of the form + * + * f + s a + * + * where f is the offset and s is the stride. + * We therefore need to include the stride constraint before computing + * the minimum. + */ +static __isl_give isl_pw_aff *exact_bound(__isl_keep isl_set *domain, + __isl_keep isl_ast_build *build, int upper) +{ + isl_set *stride; + isl_map *it_map; + isl_pw_aff *pa; + isl_pw_multi_aff *pma; + + domain = isl_set_copy(domain); + if (!upper) { + stride = isl_ast_build_get_stride_constraint(build); + domain = isl_set_intersect(domain, stride); + } + it_map = isl_ast_build_map_to_iterator(build, domain); + if (upper) + pma = isl_map_lexmax_pw_multi_aff(it_map); + else + pma = isl_map_lexmin_pw_multi_aff(it_map); + pa = isl_pw_multi_aff_get_pw_aff(pma, 0); + isl_pw_multi_aff_free(pma); + pa = isl_ast_build_compute_gist_pw_aff(build, pa); + pa = isl_pw_aff_coalesce(pa); + + return pa; +} + +/* Callback for sorting the isl_pw_aff_list passed to reduce_list and + * remove_redundant_lower_bounds. + */ +static int reduce_list_cmp(__isl_keep isl_pw_aff *a, __isl_keep isl_pw_aff *b, + void *user) +{ + return isl_pw_aff_plain_cmp(a, b); +} + +/* Given a list of lower bounds "list", remove those that are redundant + * with respect to the other bounds in "list" and the domain of "build". + * + * We first sort the bounds in the same way as they would be sorted + * by set_for_node_expressions so that we can try and remove the last + * bounds first. + * + * For a lower bound to be effective, there needs to be at least + * one domain element for which it is larger than all other lower bounds. + * For each lower bound we therefore intersect the domain with + * the conditions that it is larger than all other bounds and + * check whether the result is empty. If so, the bound can be removed. + */ +static __isl_give isl_pw_aff_list *remove_redundant_lower_bounds( + __isl_take isl_pw_aff_list *list, __isl_keep isl_ast_build *build) +{ + int i, j; + isl_size n; + isl_set *domain; + + list = isl_pw_aff_list_sort(list, &reduce_list_cmp, NULL); + + n = isl_pw_aff_list_n_pw_aff(list); + if (n < 0) + return isl_pw_aff_list_free(list); + if (n <= 1) + return list; + + domain = isl_ast_build_get_domain(build); + + for (i = n - 1; i >= 0; --i) { + isl_pw_aff *pa_i; + isl_set *domain_i; + int empty; + + domain_i = isl_set_copy(domain); + pa_i = isl_pw_aff_list_get_pw_aff(list, i); + + for (j = 0; j < n; ++j) { + isl_pw_aff *pa_j; + isl_set *better; + + if (j == i) + continue; + + pa_j = isl_pw_aff_list_get_pw_aff(list, j); + better = isl_pw_aff_gt_set(isl_pw_aff_copy(pa_i), pa_j); + domain_i = isl_set_intersect(domain_i, better); + } + + empty = isl_set_is_empty(domain_i); + + isl_set_free(domain_i); + isl_pw_aff_free(pa_i); + + if (empty < 0) + goto error; + if (!empty) + continue; + list = isl_pw_aff_list_drop(list, i, 1); + n--; + } + + isl_set_free(domain); + + return list; +error: + isl_set_free(domain); + return isl_pw_aff_list_free(list); +} + +/* Extract a lower bound on dimension "pos" from each constraint + * in "constraints" and return the list of lower bounds. + * If "constraints" has zero elements, then we extract a lower bound + * from "domain" instead. + * + * If the current dimension is strided, then the lower bound + * is adjusted by lower_bound to match the stride information. + * This modification may make one or more lower bounds redundant + * with respect to the other lower bounds. We therefore check + * for this condition and remove the redundant lower bounds. + */ +static __isl_give isl_pw_aff_list *lower_bounds( + __isl_keep isl_constraint_list *constraints, int pos, + __isl_keep isl_set *domain, __isl_keep isl_ast_build *build) +{ + isl_ctx *ctx; + isl_pw_aff_list *list; + int i; + isl_size n; + + if (!build) + return NULL; + + n = isl_constraint_list_n_constraint(constraints); + if (n < 0) + return NULL; + if (n == 0) { + isl_pw_aff *pa; + pa = exact_bound(domain, build, 0); + return isl_pw_aff_list_from_pw_aff(pa); + } + + ctx = isl_ast_build_get_ctx(build); + list = isl_pw_aff_list_alloc(ctx,n); + + for (i = 0; i < n; ++i) { + isl_aff *aff; + isl_constraint *c; + + c = isl_constraint_list_get_constraint(constraints, i); + aff = lower_bound(c, pos, build); + isl_constraint_free(c); + list = isl_pw_aff_list_add(list, isl_pw_aff_from_aff(aff)); + } + + if (isl_ast_build_has_stride(build, pos)) + list = remove_redundant_lower_bounds(list, build); + + return list; +} + +/* Extract an upper bound on dimension "pos" from each constraint + * in "constraints" and return the list of upper bounds. + * If "constraints" has zero elements, then we extract an upper bound + * from "domain" instead. + */ +static __isl_give isl_pw_aff_list *upper_bounds( + __isl_keep isl_constraint_list *constraints, int pos, + __isl_keep isl_set *domain, __isl_keep isl_ast_build *build) +{ + isl_ctx *ctx; + isl_pw_aff_list *list; + int i; + isl_size n; + + n = isl_constraint_list_n_constraint(constraints); + if (n < 0) + return NULL; + if (n == 0) { + isl_pw_aff *pa; + pa = exact_bound(domain, build, 1); + return isl_pw_aff_list_from_pw_aff(pa); + } + + ctx = isl_ast_build_get_ctx(build); + list = isl_pw_aff_list_alloc(ctx,n); + + for (i = 0; i < n; ++i) { + isl_aff *aff; + isl_constraint *c; + + c = isl_constraint_list_get_constraint(constraints, i); + aff = isl_constraint_get_bound(c, isl_dim_set, pos); + isl_constraint_free(c); + aff = isl_aff_floor(aff); + list = isl_pw_aff_list_add(list, isl_pw_aff_from_aff(aff)); + } + + return list; +} + +/* Return an isl_ast_expr that performs the reduction of type "type" + * on AST expressions corresponding to the elements in "list". + * + * The list is assumed to contain at least one element. + * If the list contains exactly one element, then the returned isl_ast_expr + * simply computes that affine expression. + * If the list contains more than one element, then we sort it + * using a fairly arbitrary but hopefully reasonably stable order. + */ +static __isl_give isl_ast_expr *reduce_list(enum isl_ast_expr_op_type type, + __isl_keep isl_pw_aff_list *list, __isl_keep isl_ast_build *build) +{ + int i; + isl_size n; + isl_ctx *ctx; + isl_ast_expr *expr; + + n = isl_pw_aff_list_n_pw_aff(list); + if (n < 0) + return NULL; + + if (n == 1) + return isl_ast_build_expr_from_pw_aff_internal(build, + isl_pw_aff_list_get_pw_aff(list, 0)); + + ctx = isl_pw_aff_list_get_ctx(list); + expr = isl_ast_expr_alloc_op(ctx, type, n); + + list = isl_pw_aff_list_copy(list); + list = isl_pw_aff_list_sort(list, &reduce_list_cmp, NULL); + if (!list) + return isl_ast_expr_free(expr); + + for (i = 0; i < n; ++i) { + isl_ast_expr *expr_i; + + expr_i = isl_ast_build_expr_from_pw_aff_internal(build, + isl_pw_aff_list_get_pw_aff(list, i)); + expr = isl_ast_expr_op_add_arg(expr, expr_i); + } + + isl_pw_aff_list_free(list); + return expr; +} + +/* Add guards implied by the "generated constraints", + * but not (necessarily) enforced by the generated AST to "guard". + * In particular, if there is any stride constraints, + * then add the guard implied by those constraints. + * If we have generated a degenerate loop, then add the guard + * implied by "bounds" on the outer dimensions, i.e., the guard + * that ensures that the single value actually exists. + * Since there may also be guards implied by a combination + * of these constraints, we first combine them before + * deriving the implied constraints. + */ +static __isl_give isl_set *add_implied_guards(__isl_take isl_set *guard, + int degenerate, __isl_keep isl_basic_set *bounds, + __isl_keep isl_ast_build *build) +{ + isl_size depth; + isl_bool has_stride; + isl_space *space; + isl_set *dom, *set; + + depth = isl_ast_build_get_depth(build); + has_stride = isl_ast_build_has_stride(build, depth); + if (depth < 0 || has_stride < 0) + return isl_set_free(guard); + if (!has_stride && !degenerate) + return guard; + + space = isl_basic_set_get_space(bounds); + dom = isl_set_universe(space); + + if (degenerate) { + bounds = isl_basic_set_copy(bounds); + bounds = isl_basic_set_drop_constraints_not_involving_dims( + bounds, isl_dim_set, depth, 1); + set = isl_set_from_basic_set(bounds); + dom = isl_set_intersect(dom, set); + } + + if (has_stride) { + set = isl_ast_build_get_stride_constraint(build); + dom = isl_set_intersect(dom, set); + } + + dom = isl_set_eliminate(dom, isl_dim_set, depth, 1); + dom = isl_ast_build_compute_gist(build, dom); + guard = isl_set_intersect(guard, dom); + + return guard; +} + +/* Update "graft" based on "sub_build" for the degenerate case. + * + * "build" is the build in which graft->node was created + * "sub_build" contains information about the current level itself, + * including the single value attained. + * + * We set the initialization part of the for loop to the single + * value attained by the current dimension. + * The increment and condition are not strictly needed as they are known + * to be "1" and "iterator <= value" respectively. + */ +static __isl_give isl_ast_graft *refine_degenerate( + __isl_take isl_ast_graft *graft, __isl_keep isl_ast_build *build, + __isl_keep isl_ast_build *sub_build) +{ + isl_pw_aff *value; + isl_ast_expr *init; + + if (!graft || !sub_build) + return isl_ast_graft_free(graft); + + value = isl_pw_aff_copy(sub_build->value); + + init = isl_ast_build_expr_from_pw_aff_internal(build, value); + graft->node = isl_ast_node_for_set_init(graft->node, init); + if (!graft->node) + return isl_ast_graft_free(graft); + + return graft; +} + +/* Return the intersection of constraints in "list" as a set. + */ +static __isl_give isl_set *intersect_constraints( + __isl_keep isl_constraint_list *list) +{ + int i; + isl_size n; + isl_basic_set *bset; + + n = isl_constraint_list_n_constraint(list); + if (n < 0) + return NULL; + if (n < 1) + isl_die(isl_constraint_list_get_ctx(list), isl_error_internal, + "expecting at least one constraint", return NULL); + + bset = isl_basic_set_from_constraint( + isl_constraint_list_get_constraint(list, 0)); + for (i = 1; i < n; ++i) { + isl_basic_set *bset_i; + + bset_i = isl_basic_set_from_constraint( + isl_constraint_list_get_constraint(list, i)); + bset = isl_basic_set_intersect(bset, bset_i); + } + + return isl_set_from_basic_set(bset); +} + +/* Compute the constraints on the outer dimensions enforced by + * graft->node and add those constraints to graft->enforced, + * in case the upper bound is expressed as a set "upper". + * + * In particular, if l(...) is a lower bound in "lower", and + * + * -a i + f(...) >= 0 or a i <= f(...) + * + * is an upper bound ocnstraint on the current dimension i, + * then the for loop enforces the constraint + * + * -a l(...) + f(...) >= 0 or a l(...) <= f(...) + * + * We therefore simply take each lower bound in turn, plug it into + * the upper bounds and compute the intersection over all lower bounds. + * + * If a lower bound is a rational expression, then + * isl_basic_set_preimage_multi_aff will force this rational + * expression to have only integer values. However, the loop + * itself does not enforce this integrality constraint. We therefore + * use the ceil of the lower bounds instead of the lower bounds themselves. + * Other constraints will make sure that the for loop is only executed + * when each of the lower bounds attains an integral value. + * In particular, potentially rational values only occur in + * lower_bound if the offset is a (seemingly) rational expression, + * but then outer conditions will make sure that this rational expression + * only attains integer values. + */ +static __isl_give isl_ast_graft *set_enforced_from_set( + __isl_take isl_ast_graft *graft, + __isl_keep isl_pw_aff_list *lower, int pos, __isl_keep isl_set *upper) +{ + isl_space *space; + isl_basic_set *enforced; + isl_pw_multi_aff *pma; + int i; + isl_size n; + + n = isl_pw_aff_list_n_pw_aff(lower); + if (!graft || n < 0) + return isl_ast_graft_free(graft); + + space = isl_set_get_space(upper); + enforced = isl_basic_set_universe(isl_space_copy(space)); + + space = isl_space_map_from_set(space); + pma = isl_pw_multi_aff_identity(space); + + for (i = 0; i < n; ++i) { + isl_pw_aff *pa; + isl_set *enforced_i; + isl_basic_set *hull; + isl_pw_multi_aff *pma_i; + + pa = isl_pw_aff_list_get_pw_aff(lower, i); + pa = isl_pw_aff_ceil(pa); + pma_i = isl_pw_multi_aff_copy(pma); + pma_i = isl_pw_multi_aff_set_pw_aff(pma_i, pos, pa); + enforced_i = isl_set_copy(upper); + enforced_i = isl_set_preimage_pw_multi_aff(enforced_i, pma_i); + hull = isl_set_simple_hull(enforced_i); + enforced = isl_basic_set_intersect(enforced, hull); + } + + isl_pw_multi_aff_free(pma); + + graft = isl_ast_graft_enforce(graft, enforced); + + return graft; +} + +/* Compute the constraints on the outer dimensions enforced by + * graft->node and add those constraints to graft->enforced, + * in case the upper bound is expressed as + * a list of affine expressions "upper". + * + * The enforced condition is that each lower bound expression is less + * than or equal to each upper bound expression. + */ +static __isl_give isl_ast_graft *set_enforced_from_list( + __isl_take isl_ast_graft *graft, + __isl_keep isl_pw_aff_list *lower, __isl_keep isl_pw_aff_list *upper) +{ + isl_set *cond; + isl_basic_set *enforced; + + lower = isl_pw_aff_list_copy(lower); + upper = isl_pw_aff_list_copy(upper); + cond = isl_pw_aff_list_le_set(lower, upper); + enforced = isl_set_simple_hull(cond); + graft = isl_ast_graft_enforce(graft, enforced); + + return graft; +} + +/* Does "aff" have a negative constant term? + */ +static isl_bool aff_constant_is_negative(__isl_keep isl_set *set, + __isl_keep isl_aff *aff, void *user) +{ + isl_bool is_neg; + isl_val *v; + + v = isl_aff_get_constant_val(aff); + is_neg = isl_val_is_neg(v); + isl_val_free(v); + + return is_neg; +} + +/* Does "pa" have a negative constant term over its entire domain? + */ +static isl_bool pw_aff_constant_is_negative(__isl_keep isl_pw_aff *pa, + void *user) +{ + return isl_pw_aff_every_piece(pa, &aff_constant_is_negative, NULL); +} + +/* Does each element in "list" have a negative constant term? + */ +static int list_constant_is_negative(__isl_keep isl_pw_aff_list *list) +{ + return isl_pw_aff_list_every(list, &pw_aff_constant_is_negative, NULL); +} + +/* Add 1 to each of the elements in "list", where each of these elements + * is defined over the internal schedule space of "build". + */ +static __isl_give isl_pw_aff_list *list_add_one( + __isl_take isl_pw_aff_list *list, __isl_keep isl_ast_build *build) +{ + int i; + isl_size n; + isl_space *space; + isl_aff *aff; + isl_pw_aff *one; + + n = isl_pw_aff_list_n_pw_aff(list); + if (n < 0) + return isl_pw_aff_list_free(list); + + space = isl_ast_build_get_space(build, 1); + aff = isl_aff_zero_on_domain(isl_local_space_from_space(space)); + aff = isl_aff_add_constant_si(aff, 1); + one = isl_pw_aff_from_aff(aff); + + for (i = 0; i < n; ++i) { + isl_pw_aff *pa; + pa = isl_pw_aff_list_get_pw_aff(list, i); + pa = isl_pw_aff_add(pa, isl_pw_aff_copy(one)); + list = isl_pw_aff_list_set_pw_aff(list, i, pa); + } + + isl_pw_aff_free(one); + + return list; +} + +/* Set the condition part of the for node graft->node in case + * the upper bound is represented as a list of piecewise affine expressions. + * + * In particular, set the condition to + * + * iterator <= min(list of upper bounds) + * + * If each of the upper bounds has a negative constant term, then + * set the condition to + * + * iterator < min(list of (upper bound + 1)s) + * + */ +static __isl_give isl_ast_graft *set_for_cond_from_list( + __isl_take isl_ast_graft *graft, __isl_keep isl_pw_aff_list *list, + __isl_keep isl_ast_build *build) +{ + int neg; + isl_ast_expr *bound, *iterator, *cond; + enum isl_ast_expr_op_type type = isl_ast_expr_op_le; + + if (!graft || !list) + return isl_ast_graft_free(graft); + + neg = list_constant_is_negative(list); + if (neg < 0) + return isl_ast_graft_free(graft); + list = isl_pw_aff_list_copy(list); + if (neg) { + list = list_add_one(list, build); + type = isl_ast_expr_op_lt; + } + + bound = reduce_list(isl_ast_expr_op_min, list, build); + iterator = isl_ast_expr_copy(graft->node->u.f.iterator); + cond = isl_ast_expr_alloc_binary(type, iterator, bound); + graft->node = isl_ast_node_for_set_cond(graft->node, cond); + + isl_pw_aff_list_free(list); + if (!graft->node) + return isl_ast_graft_free(graft); + return graft; +} + +/* Set the condition part of the for node graft->node in case + * the upper bound is represented as a set. + */ +static __isl_give isl_ast_graft *set_for_cond_from_set( + __isl_take isl_ast_graft *graft, __isl_keep isl_set *set, + __isl_keep isl_ast_build *build) +{ + isl_ast_expr *cond; + + if (!graft) + return NULL; + + cond = isl_ast_build_expr_from_set_internal(build, isl_set_copy(set)); + graft->node = isl_ast_node_for_set_cond(graft->node, cond); + if (!graft->node) + return isl_ast_graft_free(graft); + return graft; +} + +/* Construct an isl_ast_expr for the increment (i.e., stride) of + * the current dimension. + */ +static __isl_give isl_ast_expr *for_inc(__isl_keep isl_ast_build *build) +{ + isl_size depth; + isl_val *v; + isl_ctx *ctx; + + depth = isl_ast_build_get_depth(build); + if (depth < 0) + return NULL; + ctx = isl_ast_build_get_ctx(build); + + if (!isl_ast_build_has_stride(build, depth)) + return isl_ast_expr_alloc_int_si(ctx, 1); + + v = isl_ast_build_get_stride(build, depth); + return isl_ast_expr_from_val(v); +} + +/* Should we express the loop condition as + * + * iterator <= min(list of upper bounds) + * + * or as a conjunction of constraints? + * + * The first is constructed from a list of upper bounds. + * The second is constructed from a set. + * + * If there are no upper bounds in "constraints", then this could mean + * that "domain" simply doesn't have an upper bound or that we didn't + * pick any upper bound. In the first case, we want to generate the + * loop condition as a(n empty) conjunction of constraints + * In the second case, we will compute + * a single upper bound from "domain" and so we use the list form. + * + * If there are upper bounds in "constraints", + * then we use the list form iff the atomic_upper_bound option is set. + */ +static int use_upper_bound_list(isl_ctx *ctx, int n_upper, + __isl_keep isl_set *domain, int depth) +{ + if (n_upper > 0) + return isl_options_get_ast_build_atomic_upper_bound(ctx); + else + return isl_set_dim_has_upper_bound(domain, isl_dim_set, depth); +} + +/* Fill in the expressions of the for node in graft->node. + * + * In particular, + * - set the initialization part of the loop to the maximum of the lower bounds + * - extract the increment from the stride of the current dimension + * - construct the for condition either based on a list of upper bounds + * or on a set of upper bound constraints. + */ +static __isl_give isl_ast_graft *set_for_node_expressions( + __isl_take isl_ast_graft *graft, __isl_keep isl_pw_aff_list *lower, + int use_list, __isl_keep isl_pw_aff_list *upper_list, + __isl_keep isl_set *upper_set, __isl_keep isl_ast_build *build) +{ + isl_ast_expr *init; + + if (!graft) + return NULL; + + init = reduce_list(isl_ast_expr_op_max, lower, build); + graft->node = isl_ast_node_for_set_init(graft->node, init); + graft->node = isl_ast_node_for_set_inc(graft->node, for_inc(build)); + + if (!graft->node) + graft = isl_ast_graft_free(graft); + + if (use_list) + graft = set_for_cond_from_list(graft, upper_list, build); + else + graft = set_for_cond_from_set(graft, upper_set, build); + + return graft; +} + +/* Update "graft" based on "bounds" and "domain" for the generic, + * non-degenerate, case. + * + * "c_lower" and "c_upper" contain the lower and upper bounds + * that the loop node should express. + * "domain" is the subset of the intersection of the constraints + * for which some code is executed. + * + * There may be zero lower bounds or zero upper bounds in "constraints" + * in case the list of constraints was created + * based on the atomic option or based on separation with explicit bounds. + * In that case, we use "domain" to derive lower and/or upper bounds. + * + * We first compute a list of one or more lower bounds. + * + * Then we decide if we want to express the condition as + * + * iterator <= min(list of upper bounds) + * + * or as a conjunction of constraints. + * + * The set of enforced constraints is then computed either based on + * a list of upper bounds or on a set of upper bound constraints. + * We do not compute any enforced constraints if we were forced + * to compute a lower or upper bound using exact_bound. The domains + * of the resulting expressions may imply some bounds on outer dimensions + * that we do not want to appear in the enforced constraints since + * they are not actually enforced by the corresponding code. + * + * Finally, we fill in the expressions of the for node. + */ +static __isl_give isl_ast_graft *refine_generic_bounds( + __isl_take isl_ast_graft *graft, + __isl_take isl_constraint_list *c_lower, + __isl_take isl_constraint_list *c_upper, + __isl_keep isl_set *domain, __isl_keep isl_ast_build *build) +{ + isl_size depth; + isl_ctx *ctx; + isl_pw_aff_list *lower; + int use_list; + isl_set *upper_set = NULL; + isl_pw_aff_list *upper_list = NULL; + isl_size n_lower, n_upper; + + depth = isl_ast_build_get_depth(build); + if (!graft || !c_lower || !c_upper || depth < 0) + goto error; + + ctx = isl_ast_graft_get_ctx(graft); + + n_lower = isl_constraint_list_n_constraint(c_lower); + n_upper = isl_constraint_list_n_constraint(c_upper); + if (n_lower < 0 || n_upper < 0) + goto error; + + use_list = use_upper_bound_list(ctx, n_upper, domain, depth); + + lower = lower_bounds(c_lower, depth, domain, build); + + if (use_list) + upper_list = upper_bounds(c_upper, depth, domain, build); + else if (n_upper > 0) + upper_set = intersect_constraints(c_upper); + else + upper_set = isl_set_universe(isl_set_get_space(domain)); + + if (n_lower == 0 || n_upper == 0) + ; + else if (use_list) + graft = set_enforced_from_list(graft, lower, upper_list); + else + graft = set_enforced_from_set(graft, lower, depth, upper_set); + + graft = set_for_node_expressions(graft, lower, use_list, upper_list, + upper_set, build); + + isl_pw_aff_list_free(lower); + isl_pw_aff_list_free(upper_list); + isl_set_free(upper_set); + isl_constraint_list_free(c_lower); + isl_constraint_list_free(c_upper); + + return graft; +error: + isl_constraint_list_free(c_lower); + isl_constraint_list_free(c_upper); + return isl_ast_graft_free(graft); +} + +/* Internal data structure used inside count_constraints to keep + * track of the number of constraints that are independent of dimension "pos", + * the lower bounds in "pos" and the upper bounds in "pos". + */ +struct isl_ast_count_constraints_data { + int pos; + + int n_indep; + int n_lower; + int n_upper; +}; + +/* Increment data->n_indep, data->lower or data->upper depending + * on whether "c" is independent of dimensions data->pos, + * a lower bound or an upper bound. + */ +static isl_stat count_constraints(__isl_take isl_constraint *c, void *user) +{ + struct isl_ast_count_constraints_data *data = user; + + if (isl_constraint_is_lower_bound(c, isl_dim_set, data->pos)) + data->n_lower++; + else if (isl_constraint_is_upper_bound(c, isl_dim_set, data->pos)) + data->n_upper++; + else + data->n_indep++; + + isl_constraint_free(c); + + return isl_stat_ok; +} + +/* Update "graft" based on "bounds" and "domain" for the generic, + * non-degenerate, case. + * + * "list" respresent the list of bounds that need to be encoded by + * the for loop. Only the constraints that involve the iterator + * are relevant here. The other constraints are taken care of by + * the caller and are included in the generated constraints of "build". + * "domain" is the subset of the intersection of the constraints + * for which some code is executed. + * "build" is the build in which graft->node was created. + * + * We separate lower bounds, upper bounds and constraints that + * are independent of the loop iterator. + * + * The actual for loop bounds are generated in refine_generic_bounds. + */ +static __isl_give isl_ast_graft *refine_generic_split( + __isl_take isl_ast_graft *graft, __isl_take isl_constraint_list *list, + __isl_keep isl_set *domain, __isl_keep isl_ast_build *build) +{ + struct isl_ast_count_constraints_data data; + isl_size depth; + isl_constraint_list *lower; + isl_constraint_list *upper; + + depth = isl_ast_build_get_depth(build); + if (depth < 0) + list = isl_constraint_list_free(list); + if (!list) + return isl_ast_graft_free(graft); + + data.pos = depth; + + list = isl_constraint_list_sort(list, &cmp_constraint, &data.pos); + if (!list) + return isl_ast_graft_free(graft); + + data.n_indep = data.n_lower = data.n_upper = 0; + if (isl_constraint_list_foreach(list, &count_constraints, &data) < 0) { + isl_constraint_list_free(list); + return isl_ast_graft_free(graft); + } + + lower = isl_constraint_list_drop(list, 0, data.n_indep); + upper = isl_constraint_list_copy(lower); + lower = isl_constraint_list_drop(lower, data.n_lower, data.n_upper); + upper = isl_constraint_list_drop(upper, 0, data.n_lower); + + return refine_generic_bounds(graft, lower, upper, domain, build); +} + +/* Update "graft" based on "bounds" and "domain" for the generic, + * non-degenerate, case. + * + * "bounds" respresent the bounds that need to be encoded by + * the for loop (or a guard around the for loop). + * "domain" is the subset of "bounds" for which some code is executed. + * "build" is the build in which graft->node was created. + * + * We break up "bounds" into a list of constraints and continue with + * refine_generic_split. + */ +static __isl_give isl_ast_graft *refine_generic( + __isl_take isl_ast_graft *graft, + __isl_keep isl_basic_set *bounds, __isl_keep isl_set *domain, + __isl_keep isl_ast_build *build) +{ + isl_constraint_list *list; + + if (!build || !graft) + return isl_ast_graft_free(graft); + + list = isl_basic_set_get_constraint_list(bounds); + + graft = refine_generic_split(graft, list, domain, build); + + return graft; +} + +/* Create a for node for the current level. + * + * Mark the for node degenerate if "degenerate" is set. + */ +static __isl_give isl_ast_node *create_for(__isl_keep isl_ast_build *build, + int degenerate) +{ + isl_size depth; + isl_id *id; + isl_ast_node *node; + + depth = isl_ast_build_get_depth(build); + if (depth < 0) + return NULL; + + id = isl_ast_build_get_iterator_id(build, depth); + node = isl_ast_node_alloc_for(id); + if (degenerate) + node = isl_ast_node_for_mark_degenerate(node); + + return node; +} + +/* If the ast_build_exploit_nested_bounds option is set, then return + * the constraints enforced by all elements in "list". + * Otherwise, return the universe. + */ +static __isl_give isl_basic_set *extract_shared_enforced( + __isl_keep isl_ast_graft_list *list, __isl_keep isl_ast_build *build) +{ + isl_ctx *ctx; + isl_space *space; + + if (!list) + return NULL; + + ctx = isl_ast_graft_list_get_ctx(list); + if (isl_options_get_ast_build_exploit_nested_bounds(ctx)) + return isl_ast_graft_list_extract_shared_enforced(list, build); + + space = isl_ast_build_get_space(build, 1); + return isl_basic_set_universe(space); +} + +/* Return the pending constraints of "build" that are not already taken + * care of (by a combination of "enforced" and the generated constraints + * of "build"). + */ +static __isl_give isl_set *extract_pending(__isl_keep isl_ast_build *build, + __isl_keep isl_basic_set *enforced) +{ + isl_set *guard, *context; + + guard = isl_ast_build_get_pending(build); + context = isl_set_from_basic_set(isl_basic_set_copy(enforced)); + context = isl_set_intersect(context, + isl_ast_build_get_generated(build)); + return isl_set_gist(guard, context); +} + +/* Create an AST node for the current dimension based on + * the schedule domain "bounds" and return the node encapsulated + * in an isl_ast_graft. + * + * "executed" is the current inverse schedule, taking into account + * the bounds in "bounds" + * "domain" is the domain of "executed", with inner dimensions projected out. + * It may be a strict subset of "bounds" in case "bounds" was created + * based on the atomic option or based on separation with explicit bounds. + * + * "domain" may satisfy additional equalities that result + * from intersecting "executed" with "bounds" in add_node. + * It may also satisfy some global constraints that were dropped out because + * we performed separation with explicit bounds. + * The very first step is then to copy these constraints to "bounds". + * + * Since we may be calling before_each_for and after_each_for + * callbacks, we record the current inverse schedule in the build. + * + * We consider three builds, + * "build" is the one in which the current level is created, + * "body_build" is the build in which the next level is created, + * "sub_build" is essentially the same as "body_build", except that + * the depth has not been increased yet. + * + * "build" already contains information (in strides and offsets) + * about the strides at the current level, but this information is not + * reflected in the build->domain. + * We first add this information and the "bounds" to the sub_build->domain. + * isl_ast_build_set_loop_bounds adds the stride information and + * checks whether the current dimension attains + * only a single value and whether this single value can be represented using + * a single affine expression. + * In the first case, the current level is considered "degenerate". + * In the second, sub-case, the current level is considered "eliminated". + * Eliminated levels don't need to be reflected in the AST since we can + * simply plug in the affine expression. For degenerate, but non-eliminated, + * levels, we do introduce a for node, but mark is as degenerate so that + * it can be printed as an assignment of the single value to the loop + * "iterator". + * + * If the current level is eliminated, we explicitly plug in the value + * for the current level found by isl_ast_build_set_loop_bounds in the + * inverse schedule. This ensures that if we are working on a slice + * of the domain based on information available in the inverse schedule + * and the build domain, that then this information is also reflected + * in the inverse schedule. This operation also eliminates the current + * dimension from the inverse schedule making sure no inner dimensions depend + * on the current dimension. Otherwise, we create a for node, marking + * it degenerate if appropriate. The initial for node is still incomplete + * and will be completed in either refine_degenerate or refine_generic. + * + * We then generate a sequence of grafts for the next level, + * create a surrounding graft for the current level and insert + * the for node we created (if the current level is not eliminated). + * Before creating a graft for the current level, we first extract + * hoistable constraints from the child guards and combine them + * with the pending constraints in the build. These constraints + * are used to simplify the child guards and then added to the guard + * of the current graft to ensure that they will be generated. + * If the hoisted guard is a disjunction, then we use it directly + * to gist the guards on the children before intersect it with the + * pending constraints. We do so because this disjunction is typically + * identical to the guards on the children such that these guards + * can be effectively removed completely. After the intersection, + * the gist operation would have a harder time figuring this out. + * + * Finally, we set the bounds of the for loop in either + * refine_degenerate or refine_generic. + * We do so in a context where the pending constraints of the build + * have been replaced by the guard of the current graft. + */ +static __isl_give isl_ast_graft *create_node_scaled( + __isl_take isl_union_map *executed, + __isl_take isl_basic_set *bounds, __isl_take isl_set *domain, + __isl_take isl_ast_build *build) +{ + isl_size depth; + int degenerate; + isl_bool eliminated; + isl_size n; + isl_basic_set *hull; + isl_basic_set *enforced; + isl_set *guard, *hoisted; + isl_ast_node *node = NULL; + isl_ast_graft *graft; + isl_ast_graft_list *children; + isl_ast_build *sub_build; + isl_ast_build *body_build; + + domain = isl_ast_build_eliminate_divs(build, domain); + domain = isl_set_detect_equalities(domain); + hull = isl_set_unshifted_simple_hull(isl_set_copy(domain)); + bounds = isl_basic_set_intersect(bounds, hull); + build = isl_ast_build_set_executed(build, isl_union_map_copy(executed)); + + depth = isl_ast_build_get_depth(build); + if (depth < 0) + build = isl_ast_build_free(build); + sub_build = isl_ast_build_copy(build); + bounds = isl_basic_set_remove_redundancies(bounds); + bounds = isl_ast_build_specialize_basic_set(sub_build, bounds); + sub_build = isl_ast_build_set_loop_bounds(sub_build, + isl_basic_set_copy(bounds)); + degenerate = isl_ast_build_has_value(sub_build); + eliminated = isl_ast_build_has_affine_value(sub_build, depth); + if (degenerate < 0 || eliminated < 0) + executed = isl_union_map_free(executed); + if (!degenerate) + bounds = isl_ast_build_compute_gist_basic_set(build, bounds); + sub_build = isl_ast_build_set_pending_generated(sub_build, + isl_basic_set_copy(bounds)); + if (eliminated) + executed = plug_in_values(executed, sub_build); + else + node = create_for(build, degenerate); + + body_build = isl_ast_build_copy(sub_build); + body_build = isl_ast_build_increase_depth(body_build); + if (!eliminated) + node = before_each_for(node, body_build); + children = generate_next_level(executed, + isl_ast_build_copy(body_build)); + + enforced = extract_shared_enforced(children, build); + guard = extract_pending(sub_build, enforced); + hoisted = isl_ast_graft_list_extract_hoistable_guard(children, build); + n = isl_set_n_basic_set(hoisted); + if (n < 0) + children = isl_ast_graft_list_free(children); + if (n > 1) + children = isl_ast_graft_list_gist_guards(children, + isl_set_copy(hoisted)); + guard = isl_set_intersect(guard, hoisted); + if (!eliminated) + guard = add_implied_guards(guard, degenerate, bounds, build); + + graft = isl_ast_graft_alloc_from_children(children, + isl_set_copy(guard), enforced, build, sub_build); + + if (!eliminated) { + isl_ast_build *for_build; + + graft = isl_ast_graft_insert_for(graft, node); + for_build = isl_ast_build_copy(build); + for_build = isl_ast_build_replace_pending_by_guard(for_build, + isl_set_copy(guard)); + if (degenerate) + graft = refine_degenerate(graft, for_build, sub_build); + else + graft = refine_generic(graft, bounds, + domain, for_build); + isl_ast_build_free(for_build); + } + isl_set_free(guard); + if (!eliminated) + graft = after_each_for(graft, body_build); + + isl_ast_build_free(body_build); + isl_ast_build_free(sub_build); + isl_ast_build_free(build); + isl_basic_set_free(bounds); + isl_set_free(domain); + + return graft; +} + +/* Internal data structure for checking if all constraints involving + * the input dimension "depth" are such that the other coefficients + * are multiples of "m", reducing "m" if they are not. + * If "m" is reduced all the way down to "1", then the check has failed + * and we break out of the iteration. + */ +struct isl_check_scaled_data { + int depth; + isl_val *m; +}; + +/* If constraint "c" involves the input dimension data->depth, + * then make sure that all the other coefficients are multiples of data->m, + * reducing data->m if needed. + * Break out of the iteration if data->m has become equal to "1". + */ +static isl_stat constraint_check_scaled(__isl_take isl_constraint *c, + void *user) +{ + struct isl_check_scaled_data *data = user; + int i, j; + isl_size n; + enum isl_dim_type t[] = { isl_dim_param, isl_dim_in, isl_dim_out, + isl_dim_div }; + + if (!isl_constraint_involves_dims(c, isl_dim_in, data->depth, 1)) { + isl_constraint_free(c); + return isl_stat_ok; + } + + for (i = 0; i < 4; ++i) { + n = isl_constraint_dim(c, t[i]); + if (n < 0) + break; + for (j = 0; j < n; ++j) { + isl_val *d; + + if (t[i] == isl_dim_in && j == data->depth) + continue; + if (!isl_constraint_involves_dims(c, t[i], j, 1)) + continue; + d = isl_constraint_get_coefficient_val(c, t[i], j); + data->m = isl_val_gcd(data->m, d); + if (isl_val_is_one(data->m)) + break; + } + if (j < n) + break; + } + + isl_constraint_free(c); + + return i < 4 ? isl_stat_error : isl_stat_ok; +} + +/* For each constraint of "bmap" that involves the input dimension data->depth, + * make sure that all the other coefficients are multiples of data->m, + * reducing data->m if needed. + * Break out of the iteration if data->m has become equal to "1". + */ +static isl_stat basic_map_check_scaled(__isl_take isl_basic_map *bmap, + void *user) +{ + isl_stat r; + + r = isl_basic_map_foreach_constraint(bmap, + &constraint_check_scaled, user); + isl_basic_map_free(bmap); + + return r; +} + +/* For each constraint of "map" that involves the input dimension data->depth, + * make sure that all the other coefficients are multiples of data->m, + * reducing data->m if needed. + * Break out of the iteration if data->m has become equal to "1". + */ +static isl_stat map_check_scaled(__isl_take isl_map *map, void *user) +{ + isl_stat r; + + r = isl_map_foreach_basic_map(map, &basic_map_check_scaled, user); + isl_map_free(map); + + return r; +} + +/* Create an AST node for the current dimension based on + * the schedule domain "bounds" and return the node encapsulated + * in an isl_ast_graft. + * + * "executed" is the current inverse schedule, taking into account + * the bounds in "bounds" + * "domain" is the domain of "executed", with inner dimensions projected out. + * + * + * Before moving on to the actual AST node construction in create_node_scaled, + * we first check if the current dimension is strided and if we can scale + * down this stride. Note that we only do this if the ast_build_scale_strides + * option is set. + * + * In particular, let the current dimension take on values + * + * f + s a + * + * with a an integer. We check if we can find an integer m that (obviously) + * divides both f and s. + * + * If so, we check if the current dimension only appears in constraints + * where the coefficients of the other variables are multiples of m. + * We perform this extra check to avoid the risk of introducing + * divisions by scaling down the current dimension. + * + * If so, we scale the current dimension down by a factor of m. + * That is, we plug in + * + * i = m i' (1) + * + * Note that in principle we could always scale down strided loops + * by plugging in + * + * i = f + s i' + * + * but this may result in i' taking on larger values than the original i, + * due to the shift by "f". + * By constrast, the scaling in (1) can only reduce the (absolute) value "i". + */ +static __isl_give isl_ast_graft *create_node(__isl_take isl_union_map *executed, + __isl_take isl_basic_set *bounds, __isl_take isl_set *domain, + __isl_take isl_ast_build *build) +{ + struct isl_check_scaled_data data; + isl_size depth; + isl_ctx *ctx; + isl_aff *offset; + isl_val *d; + + ctx = isl_ast_build_get_ctx(build); + if (!isl_options_get_ast_build_scale_strides(ctx)) + return create_node_scaled(executed, bounds, domain, build); + + depth = isl_ast_build_get_depth(build); + if (depth < 0) + build = isl_ast_build_free(build); + data.depth = depth; + if (!isl_ast_build_has_stride(build, data.depth)) + return create_node_scaled(executed, bounds, domain, build); + + offset = isl_ast_build_get_offset(build, data.depth); + data.m = isl_ast_build_get_stride(build, data.depth); + if (!data.m) + offset = isl_aff_free(offset); + offset = isl_aff_scale_down_val(offset, isl_val_copy(data.m)); + d = isl_aff_get_denominator_val(offset); + if (!d) + executed = isl_union_map_free(executed); + + if (executed && isl_val_is_divisible_by(data.m, d)) + data.m = isl_val_div(data.m, d); + else { + data.m = isl_val_set_si(data.m, 1); + isl_val_free(d); + } + + if (!isl_val_is_one(data.m)) { + if (isl_union_map_foreach_map(executed, &map_check_scaled, + &data) < 0 && + !isl_val_is_one(data.m)) + executed = isl_union_map_free(executed); + } + + if (!isl_val_is_one(data.m)) { + isl_space *space; + isl_multi_aff *ma; + isl_aff *aff; + isl_map *map; + isl_union_map *umap; + + space = isl_ast_build_get_space(build, 1); + space = isl_space_map_from_set(space); + ma = isl_multi_aff_identity(space); + aff = isl_multi_aff_get_aff(ma, data.depth); + aff = isl_aff_scale_val(aff, isl_val_copy(data.m)); + ma = isl_multi_aff_set_aff(ma, data.depth, aff); + + bounds = isl_basic_set_preimage_multi_aff(bounds, + isl_multi_aff_copy(ma)); + domain = isl_set_preimage_multi_aff(domain, + isl_multi_aff_copy(ma)); + map = isl_map_reverse(isl_map_from_multi_aff(ma)); + umap = isl_union_map_from_map(map); + executed = isl_union_map_apply_domain(executed, + isl_union_map_copy(umap)); + build = isl_ast_build_scale_down(build, isl_val_copy(data.m), + umap); + } + isl_aff_free(offset); + isl_val_free(data.m); + + return create_node_scaled(executed, bounds, domain, build); +} + +/* Add the basic set to the list that "user" points to. + */ +static isl_stat collect_basic_set(__isl_take isl_basic_set *bset, void *user) +{ + isl_basic_set_list **list = user; + + *list = isl_basic_set_list_add(*list, bset); + + return isl_stat_ok; +} + +/* Extract the basic sets of "set" and collect them in an isl_basic_set_list. + */ +static __isl_give isl_basic_set_list *isl_basic_set_list_from_set( + __isl_take isl_set *set) +{ + isl_size n; + isl_ctx *ctx; + isl_basic_set_list *list; + + n = isl_set_n_basic_set(set); + if (n < 0) + set = isl_set_free(set); + if (!set) + return NULL; + + ctx = isl_set_get_ctx(set); + + list = isl_basic_set_list_alloc(ctx, n); + if (isl_set_foreach_basic_set(set, &collect_basic_set, &list) < 0) + list = isl_basic_set_list_free(list); + + isl_set_free(set); + return list; +} + +/* Generate code for the schedule domain "bounds" + * and add the result to "list". + * + * We mainly detect strides here and check if the bounds do not + * conflict with the current build domain + * and then pass over control to create_node. + * + * "bounds" reflects the bounds on the current dimension and possibly + * some extra conditions on outer dimensions. + * It does not, however, include any divs involving the current dimension, + * so it does not capture any stride constraints. + * We therefore need to compute that part of the schedule domain that + * intersects with "bounds" and derive the strides from the result. + */ +static __isl_give isl_ast_graft_list *add_node( + __isl_take isl_ast_graft_list *list, __isl_take isl_union_map *executed, + __isl_take isl_basic_set *bounds, __isl_take isl_ast_build *build) +{ + isl_ast_graft *graft; + isl_set *domain = NULL; + isl_union_set *uset; + int empty, disjoint; + + uset = isl_union_set_from_basic_set(isl_basic_set_copy(bounds)); + executed = isl_union_map_intersect_domain(executed, uset); + empty = isl_union_map_is_empty(executed); + if (empty < 0) + goto error; + if (empty) + goto done; + + uset = isl_union_map_domain(isl_union_map_copy(executed)); + domain = isl_set_from_union_set(uset); + domain = isl_ast_build_specialize(build, domain); + + domain = isl_set_compute_divs(domain); + domain = isl_ast_build_eliminate_inner(build, domain); + disjoint = isl_set_is_disjoint(domain, build->domain); + if (disjoint < 0) + goto error; + if (disjoint) + goto done; + + build = isl_ast_build_detect_strides(build, isl_set_copy(domain)); + + graft = create_node(executed, bounds, domain, + isl_ast_build_copy(build)); + list = isl_ast_graft_list_add(list, graft); + isl_ast_build_free(build); + return list; +error: + list = isl_ast_graft_list_free(list); +done: + isl_set_free(domain); + isl_basic_set_free(bounds); + isl_union_map_free(executed); + isl_ast_build_free(build); + return list; +} + +/* Does any element of i follow or coincide with any element of j + * at the current depth for equal values of the outer dimensions? + */ +static isl_bool domain_follows_at_depth(__isl_keep isl_basic_set *i, + __isl_keep isl_basic_set *j, void *user) +{ + int depth = *(int *) user; + isl_basic_map *test; + isl_bool empty; + int l; + + test = isl_basic_map_from_domain_and_range(isl_basic_set_copy(i), + isl_basic_set_copy(j)); + for (l = 0; l < depth; ++l) + test = isl_basic_map_equate(test, isl_dim_in, l, + isl_dim_out, l); + test = isl_basic_map_order_ge(test, isl_dim_in, depth, + isl_dim_out, depth); + empty = isl_basic_map_is_empty(test); + isl_basic_map_free(test); + + return isl_bool_not(empty); +} + +/* Split up each element of "list" into a part that is related to "bset" + * according to "gt" and a part that is not. + * Return a list that consist of "bset" and all the pieces. + */ +static __isl_give isl_basic_set_list *add_split_on( + __isl_take isl_basic_set_list *list, __isl_take isl_basic_set *bset, + __isl_keep isl_basic_map *gt) +{ + int i; + isl_size n; + isl_basic_set_list *res; + + n = isl_basic_set_list_n_basic_set(list); + if (n < 0) + bset = isl_basic_set_free(bset); + + gt = isl_basic_map_copy(gt); + gt = isl_basic_map_intersect_domain(gt, isl_basic_set_copy(bset)); + res = isl_basic_set_list_from_basic_set(bset); + for (i = 0; res && i < n; ++i) { + isl_basic_set *bset; + isl_set *set1, *set2; + isl_basic_map *bmap; + int empty; + + bset = isl_basic_set_list_get_basic_set(list, i); + bmap = isl_basic_map_copy(gt); + bmap = isl_basic_map_intersect_range(bmap, bset); + bset = isl_basic_map_range(bmap); + empty = isl_basic_set_is_empty(bset); + if (empty < 0) + res = isl_basic_set_list_free(res); + if (empty) { + isl_basic_set_free(bset); + bset = isl_basic_set_list_get_basic_set(list, i); + res = isl_basic_set_list_add(res, bset); + continue; + } + + res = isl_basic_set_list_add(res, isl_basic_set_copy(bset)); + set1 = isl_set_from_basic_set(bset); + bset = isl_basic_set_list_get_basic_set(list, i); + set2 = isl_set_from_basic_set(bset); + set1 = isl_set_subtract(set2, set1); + set1 = isl_set_make_disjoint(set1); + + res = isl_basic_set_list_concat(res, + isl_basic_set_list_from_set(set1)); + } + isl_basic_map_free(gt); + isl_basic_set_list_free(list); + return res; +} + +static __isl_give isl_ast_graft_list *generate_sorted_domains( + __isl_keep isl_basic_set_list *domain_list, + __isl_keep isl_union_map *executed, + __isl_keep isl_ast_build *build); + +/* Internal data structure for add_nodes. + * + * "executed" and "build" are extra arguments to be passed to add_node. + * "list" collects the results. + */ +struct isl_add_nodes_data { + isl_union_map *executed; + isl_ast_build *build; + + isl_ast_graft_list *list; +}; + +/* Generate code for the schedule domains in "scc" + * and add the results to "list". + * + * The domains in "scc" form a strongly connected component in the ordering. + * If the number of domains in "scc" is larger than 1, then this means + * that we cannot determine a valid ordering for the domains in the component. + * This should be fairly rare because the individual domains + * have been made disjoint first. + * The problem is that the domains may be integrally disjoint but not + * rationally disjoint. For example, we may have domains + * + * { [i,i] : 0 <= i <= 1 } and { [i,1-i] : 0 <= i <= 1 } + * + * These two domains have an empty intersection, but their rational + * relaxations do intersect. It is impossible to order these domains + * in the second dimension because the first should be ordered before + * the second for outer dimension equal to 0, while it should be ordered + * after for outer dimension equal to 1. + * + * This may happen in particular in case of unrolling since the domain + * of each slice is replaced by its simple hull. + * + * For each basic set i in "scc" and for each of the following basic sets j, + * we split off that part of the basic set i that shares the outer dimensions + * with j and lies before j in the current dimension. + * We collect all the pieces in a new list that replaces "scc". + * + * While the elements in "scc" should be disjoint, we double-check + * this property to avoid running into an infinite recursion in case + * they intersect due to some internal error. + */ +static isl_stat add_nodes(__isl_take isl_basic_set_list *scc, void *user) +{ + struct isl_add_nodes_data *data = user; + int i; + isl_size depth; + isl_size n; + isl_basic_set *bset, *first; + isl_basic_set_list *list; + isl_space *space; + isl_basic_map *gt; + + n = isl_basic_set_list_n_basic_set(scc); + if (n < 0) + goto error; + bset = isl_basic_set_list_get_basic_set(scc, 0); + if (n == 1) { + isl_basic_set_list_free(scc); + data->list = add_node(data->list, + isl_union_map_copy(data->executed), bset, + isl_ast_build_copy(data->build)); + return data->list ? isl_stat_ok : isl_stat_error; + } + + depth = isl_ast_build_get_depth(data->build); + if (depth < 0) + bset = isl_basic_set_free(bset); + space = isl_basic_set_get_space(bset); + space = isl_space_map_from_set(space); + gt = isl_basic_map_universe(space); + for (i = 0; i < depth; ++i) + gt = isl_basic_map_equate(gt, isl_dim_in, i, isl_dim_out, i); + gt = isl_basic_map_order_gt(gt, isl_dim_in, depth, isl_dim_out, depth); + + first = isl_basic_set_copy(bset); + list = isl_basic_set_list_from_basic_set(bset); + for (i = 1; i < n; ++i) { + int disjoint; + + bset = isl_basic_set_list_get_basic_set(scc, i); + + disjoint = isl_basic_set_is_disjoint(bset, first); + if (disjoint < 0) + list = isl_basic_set_list_free(list); + else if (!disjoint) + isl_die(isl_basic_set_list_get_ctx(scc), + isl_error_internal, + "basic sets in scc are assumed to be disjoint", + list = isl_basic_set_list_free(list)); + + list = add_split_on(list, bset, gt); + } + isl_basic_set_free(first); + isl_basic_map_free(gt); + isl_basic_set_list_free(scc); + scc = list; + data->list = isl_ast_graft_list_concat(data->list, + generate_sorted_domains(scc, data->executed, data->build)); + isl_basic_set_list_free(scc); + + return data->list ? isl_stat_ok : isl_stat_error; +error: + isl_basic_set_list_free(scc); + return isl_stat_error; +} + +/* Sort the domains in "domain_list" according to the execution order + * at the current depth (for equal values of the outer dimensions), + * generate code for each of them, collecting the results in a list. + * If no code is generated (because the intersection of the inverse schedule + * with the domains turns out to be empty), then an empty list is returned. + * + * The caller is responsible for ensuring that the basic sets in "domain_list" + * are pair-wise disjoint. It can, however, in principle happen that + * two basic sets should be ordered one way for one value of the outer + * dimensions and the other way for some other value of the outer dimensions. + * We therefore play safe and look for strongly connected components. + * The function add_nodes takes care of handling non-trivial components. + */ +static __isl_give isl_ast_graft_list *generate_sorted_domains( + __isl_keep isl_basic_set_list *domain_list, + __isl_keep isl_union_map *executed, __isl_keep isl_ast_build *build) +{ + isl_ctx *ctx; + struct isl_add_nodes_data data; + isl_size depth; + isl_size n; + + n = isl_basic_set_list_n_basic_set(domain_list); + if (n < 0) + return NULL; + + ctx = isl_basic_set_list_get_ctx(domain_list); + data.list = isl_ast_graft_list_alloc(ctx, n); + if (n == 0) + return data.list; + if (n == 1) + return add_node(data.list, isl_union_map_copy(executed), + isl_basic_set_list_get_basic_set(domain_list, 0), + isl_ast_build_copy(build)); + + depth = isl_ast_build_get_depth(build); + data.executed = executed; + data.build = build; + if (depth < 0 || isl_basic_set_list_foreach_scc(domain_list, + &domain_follows_at_depth, &depth, + &add_nodes, &data) < 0) + data.list = isl_ast_graft_list_free(data.list); + + return data.list; +} + +/* Do i and j share any values for the outer dimensions? + */ +static isl_bool shared_outer(__isl_keep isl_basic_set *i, + __isl_keep isl_basic_set *j, void *user) +{ + int depth = *(int *) user; + isl_basic_map *test; + isl_bool empty; + int l; + + test = isl_basic_map_from_domain_and_range(isl_basic_set_copy(i), + isl_basic_set_copy(j)); + for (l = 0; l < depth; ++l) + test = isl_basic_map_equate(test, isl_dim_in, l, + isl_dim_out, l); + empty = isl_basic_map_is_empty(test); + isl_basic_map_free(test); + + return isl_bool_not(empty); +} + +/* Internal data structure for generate_sorted_domains_wrap. + * + * "n" is the total number of basic sets + * "executed" and "build" are extra arguments to be passed + * to generate_sorted_domains. + * + * "single" is set to 1 by generate_sorted_domains_wrap if there + * is only a single component. + * "list" collects the results. + */ +struct isl_ast_generate_parallel_domains_data { + isl_size n; + isl_union_map *executed; + isl_ast_build *build; + + int single; + isl_ast_graft_list *list; +}; + +/* Call generate_sorted_domains on "scc", fuse the result into a list + * with either zero or one graft and collect the these single element + * lists into data->list. + * + * If there is only one component, i.e., if the number of basic sets + * in the current component is equal to the total number of basic sets, + * then data->single is set to 1 and the result of generate_sorted_domains + * is not fused. + */ +static isl_stat generate_sorted_domains_wrap(__isl_take isl_basic_set_list *scc, + void *user) +{ + struct isl_ast_generate_parallel_domains_data *data = user; + isl_ast_graft_list *list; + isl_size n; + + n = isl_basic_set_list_n_basic_set(scc); + if (n < 0) + scc = isl_basic_set_list_free(scc); + list = generate_sorted_domains(scc, data->executed, data->build); + data->single = n == data->n; + if (!data->single) + list = isl_ast_graft_list_fuse(list, data->build); + if (!data->list) + data->list = list; + else + data->list = isl_ast_graft_list_concat(data->list, list); + + isl_basic_set_list_free(scc); + if (!data->list) + return isl_stat_error; + + return isl_stat_ok; +} + +/* Look for any (weakly connected) components in the "domain_list" + * of domains that share some values of the outer dimensions. + * That is, domains in different components do not share any values + * of the outer dimensions. This means that these components + * can be freely reordered. + * Within each of the components, we sort the domains according + * to the execution order at the current depth. + * + * If there is more than one component, then generate_sorted_domains_wrap + * fuses the result of each call to generate_sorted_domains + * into a list with either zero or one graft and collects these (at most) + * single element lists into a bigger list. This means that the elements of the + * final list can be freely reordered. In particular, we sort them + * according to an arbitrary but fixed ordering to ease merging of + * graft lists from different components. + */ +static __isl_give isl_ast_graft_list *generate_parallel_domains( + __isl_keep isl_basic_set_list *domain_list, + __isl_keep isl_union_map *executed, __isl_keep isl_ast_build *build) +{ + isl_size depth; + struct isl_ast_generate_parallel_domains_data data; + + data.n = isl_basic_set_list_n_basic_set(domain_list); + if (data.n < 0) + return NULL; + + if (data.n <= 1) + return generate_sorted_domains(domain_list, executed, build); + + depth = isl_ast_build_get_depth(build); + if (depth < 0) + return NULL; + data.list = NULL; + data.executed = executed; + data.build = build; + data.single = 0; + if (isl_basic_set_list_foreach_scc(domain_list, &shared_outer, &depth, + &generate_sorted_domains_wrap, + &data) < 0) + data.list = isl_ast_graft_list_free(data.list); + + if (!data.single) + data.list = isl_ast_graft_list_sort_guard(data.list); + + return data.list; +} + +/* Internal data for separate_domain. + * + * "explicit" is set if we only want to use explicit bounds. + * + * "domain" collects the separated domains. + */ +struct isl_separate_domain_data { + isl_ast_build *build; + int explicit; + isl_set *domain; +}; + +/* Extract implicit bounds on the current dimension for the executed "map". + * + * The domain of "map" may involve inner dimensions, so we + * need to eliminate them. + */ +static __isl_give isl_set *implicit_bounds(__isl_take isl_map *map, + __isl_keep isl_ast_build *build) +{ + isl_set *domain; + + domain = isl_map_domain(map); + domain = isl_ast_build_eliminate(build, domain); + + return domain; +} + +/* Extract explicit bounds on the current dimension for the executed "map". + * + * Rather than eliminating the inner dimensions as in implicit_bounds, + * we simply drop any constraints involving those inner dimensions. + * The idea is that most bounds that are implied by constraints on the + * inner dimensions will be enforced by for loops and not by explicit guards. + * There is then no need to separate along those bounds. + */ +static __isl_give isl_set *explicit_bounds(__isl_take isl_map *map, + __isl_keep isl_ast_build *build) +{ + isl_set *domain; + isl_size depth; + isl_size dim; + + depth = isl_ast_build_get_depth(build); + dim = isl_map_dim(map, isl_dim_out); + if (depth < 0 || dim < 0) + return isl_map_domain(isl_map_free(map)); + map = isl_map_drop_constraints_involving_dims(map, isl_dim_out, 0, dim); + + domain = isl_map_domain(map); + dim = isl_set_dim(domain, isl_dim_set); + domain = isl_set_detect_equalities(domain); + domain = isl_set_drop_constraints_involving_dims(domain, + isl_dim_set, depth + 1, dim - (depth + 1)); + domain = isl_set_remove_divs_involving_dims(domain, + isl_dim_set, depth, 1); + domain = isl_set_remove_unknown_divs(domain); + + return domain; +} + +/* Split data->domain into pieces that intersect with the range of "map" + * and pieces that do not intersect with the range of "map" + * and then add that part of the range of "map" that does not intersect + * with data->domain. + */ +static isl_stat separate_domain(__isl_take isl_map *map, void *user) +{ + struct isl_separate_domain_data *data = user; + isl_set *domain; + isl_set *d1, *d2; + + if (data->explicit) + domain = explicit_bounds(map, data->build); + else + domain = implicit_bounds(map, data->build); + + domain = isl_set_coalesce(domain); + domain = isl_set_make_disjoint(domain); + d1 = isl_set_subtract(isl_set_copy(domain), isl_set_copy(data->domain)); + d2 = isl_set_subtract(isl_set_copy(data->domain), isl_set_copy(domain)); + data->domain = isl_set_intersect(data->domain, domain); + data->domain = isl_set_union(data->domain, d1); + data->domain = isl_set_union(data->domain, d2); + + return isl_stat_ok; +} + +/* Separate the schedule domains of "executed". + * + * That is, break up the domain of "executed" into basic sets, + * such that for each basic set S, every element in S is associated with + * the same domain spaces. + * + * "space" is the (single) domain space of "executed". + */ +static __isl_give isl_set *separate_schedule_domains( + __isl_take isl_space *space, __isl_take isl_union_map *executed, + __isl_keep isl_ast_build *build) +{ + struct isl_separate_domain_data data = { build }; + isl_ctx *ctx; + + ctx = isl_ast_build_get_ctx(build); + data.explicit = isl_options_get_ast_build_separation_bounds(ctx) == + ISL_AST_BUILD_SEPARATION_BOUNDS_EXPLICIT; + data.domain = isl_set_empty(space); + if (isl_union_map_foreach_map(executed, &separate_domain, &data) < 0) + data.domain = isl_set_free(data.domain); + + isl_union_map_free(executed); + return data.domain; +} + +/* Temporary data used during the search for a lower bound for unrolling. + * + * "build" is the build in which the unrolling will be performed + * "domain" is the original set for which to find a lower bound + * "depth" is the dimension for which to find a lower boudn + * "expansion" is the expansion that needs to be applied to "domain" + * in the unrolling that will be performed + * + * "lower" is the best lower bound found so far. It is NULL if we have not + * found any yet. + * "n" is the corresponding size. If lower is NULL, then the value of n + * is undefined. + * "n_div" is the maximal number of integer divisions in the first + * unrolled iteration (after expansion). It is set to -1 if it hasn't + * been computed yet. + */ +struct isl_find_unroll_data { + isl_ast_build *build; + isl_set *domain; + int depth; + isl_basic_map *expansion; + + isl_aff *lower; + int *n; + int n_div; +}; + +/* Return the constraint + * + * i_"depth" = aff + offset + */ +static __isl_give isl_constraint *at_offset(int depth, __isl_keep isl_aff *aff, + int offset) +{ + aff = isl_aff_copy(aff); + aff = isl_aff_add_coefficient_si(aff, isl_dim_in, depth, -1); + aff = isl_aff_add_constant_si(aff, offset); + return isl_equality_from_aff(aff); +} + +/* Update *user to the number of integer divisions in the first element + * of "ma", if it is larger than the current value. + */ +static isl_stat update_n_div(__isl_take isl_set *set, + __isl_take isl_multi_aff *ma, void *user) +{ + isl_aff *aff; + int *n = user; + isl_size n_div; + + aff = isl_multi_aff_get_aff(ma, 0); + n_div = isl_aff_dim(aff, isl_dim_div); + isl_aff_free(aff); + isl_multi_aff_free(ma); + isl_set_free(set); + + if (n_div > *n) + *n = n_div; + + return n_div >= 0 ? isl_stat_ok : isl_stat_error; +} + +/* Get the number of integer divisions in the expression for the iterator + * value at the first slice in the unrolling based on lower bound "lower", + * taking into account the expansion that needs to be performed on this slice. + */ +static int get_expanded_n_div(struct isl_find_unroll_data *data, + __isl_keep isl_aff *lower) +{ + isl_constraint *c; + isl_set *set; + isl_map *it_map, *expansion; + isl_pw_multi_aff *pma; + int n; + + c = at_offset(data->depth, lower, 0); + set = isl_set_copy(data->domain); + set = isl_set_add_constraint(set, c); + expansion = isl_map_from_basic_map(isl_basic_map_copy(data->expansion)); + set = isl_set_apply(set, expansion); + it_map = isl_ast_build_map_to_iterator(data->build, set); + pma = isl_pw_multi_aff_from_map(it_map); + n = 0; + if (isl_pw_multi_aff_foreach_piece(pma, &update_n_div, &n) < 0) + n = -1; + isl_pw_multi_aff_free(pma); + + return n; +} + +/* Is the lower bound "lower" with corresponding iteration count "n" + * better than the one stored in "data"? + * If there is no upper bound on the iteration count ("n" is infinity) or + * if the count is too large, then we cannot use this lower bound. + * Otherwise, if there was no previous lower bound or + * if the iteration count of the new lower bound is smaller than + * the iteration count of the previous lower bound, then we consider + * the new lower bound to be better. + * If the iteration count is the same, then compare the number + * of integer divisions that would be needed to express + * the iterator value at the first slice in the unrolling + * according to the lower bound. If we end up computing this + * number, then store the lowest value in data->n_div. + */ +static int is_better_lower_bound(struct isl_find_unroll_data *data, + __isl_keep isl_aff *lower, __isl_keep isl_val *n) +{ + int cmp; + int n_div; + + if (!n) + return -1; + if (isl_val_is_infty(n)) + return 0; + if (isl_val_cmp_si(n, INT_MAX) > 0) + return 0; + if (!data->lower) + return 1; + cmp = isl_val_cmp_si(n, *data->n); + if (cmp < 0) + return 1; + if (cmp > 0) + return 0; + if (data->n_div < 0) + data->n_div = get_expanded_n_div(data, data->lower); + if (data->n_div < 0) + return -1; + if (data->n_div == 0) + return 0; + n_div = get_expanded_n_div(data, lower); + if (n_div < 0) + return -1; + if (n_div >= data->n_div) + return 0; + data->n_div = n_div; + + return 1; +} + +/* Check if we can use "c" as a lower bound and if it is better than + * any previously found lower bound. + * + * If "c" does not involve the dimension at the current depth, + * then we cannot use it. + * Otherwise, let "c" be of the form + * + * i >= f(j)/a + * + * We compute the maximal value of + * + * -ceil(f(j)/a)) + i + 1 + * + * over the domain. If there is such a value "n", then we know + * + * -ceil(f(j)/a)) + i + 1 <= n + * + * or + * + * i < ceil(f(j)/a)) + n + * + * meaning that we can use ceil(f(j)/a)) as a lower bound for unrolling. + * We just need to check if we have found any lower bound before and + * if the new lower bound is better (smaller n or fewer integer divisions) + * than the previously found lower bounds. + */ +static isl_stat update_unrolling_lower_bound(struct isl_find_unroll_data *data, + __isl_keep isl_constraint *c) +{ + isl_aff *aff, *lower; + isl_val *max; + int better; + + if (!isl_constraint_is_lower_bound(c, isl_dim_set, data->depth)) + return isl_stat_ok; + + lower = isl_constraint_get_bound(c, isl_dim_set, data->depth); + lower = isl_aff_ceil(lower); + aff = isl_aff_copy(lower); + aff = isl_aff_neg(aff); + aff = isl_aff_add_coefficient_si(aff, isl_dim_in, data->depth, 1); + aff = isl_aff_add_constant_si(aff, 1); + max = isl_set_max_val(data->domain, aff); + isl_aff_free(aff); + + better = is_better_lower_bound(data, lower, max); + if (better < 0 || !better) { + isl_val_free(max); + isl_aff_free(lower); + return better < 0 ? isl_stat_error : isl_stat_ok; + } + + isl_aff_free(data->lower); + data->lower = lower; + *data->n = isl_val_get_num_si(max); + isl_val_free(max); + + return isl_stat_ok; +} + +/* Check if we can use "c" as a lower bound and if it is better than + * any previously found lower bound. + */ +static isl_stat constraint_find_unroll(__isl_take isl_constraint *c, void *user) +{ + struct isl_find_unroll_data *data; + isl_stat r; + + data = (struct isl_find_unroll_data *) user; + r = update_unrolling_lower_bound(data, c); + isl_constraint_free(c); + + return r; +} + +/* Look for a lower bound l(i) on the dimension at "depth" + * and a size n such that "domain" is a subset of + * + * { [i] : l(i) <= i_d < l(i) + n } + * + * where d is "depth" and l(i) depends only on earlier dimensions. + * Furthermore, try and find a lower bound such that n is as small as possible. + * In particular, "n" needs to be finite. + * "build" is the build in which the unrolling will be performed. + * "expansion" is the expansion that needs to be applied to "domain" + * in the unrolling that will be performed. + * + * Inner dimensions have been eliminated from "domain" by the caller. + * + * We first construct a collection of lower bounds on the input set + * by computing its simple hull. We then iterate through them, + * discarding those that we cannot use (either because they do not + * involve the dimension at "depth" or because they have no corresponding + * upper bound, meaning that "n" would be unbounded) and pick out the + * best from the remaining ones. + * + * If we cannot find a suitable lower bound, then we consider that + * to be an error. + */ +static __isl_give isl_aff *find_unroll_lower_bound( + __isl_keep isl_ast_build *build, __isl_keep isl_set *domain, + int depth, __isl_keep isl_basic_map *expansion, int *n) +{ + struct isl_find_unroll_data data = + { build, domain, depth, expansion, NULL, n, -1 }; + isl_basic_set *hull; + + hull = isl_set_simple_hull(isl_set_copy(domain)); + + if (isl_basic_set_foreach_constraint(hull, + &constraint_find_unroll, &data) < 0) + goto error; + + isl_basic_set_free(hull); + + if (!data.lower) + isl_die(isl_set_get_ctx(domain), isl_error_invalid, + "cannot find lower bound for unrolling", return NULL); + + return data.lower; +error: + isl_basic_set_free(hull); + return isl_aff_free(data.lower); +} + +/* Call "fn" on each iteration of the current dimension of "domain". + * If "init" is not NULL, then it is called with the number of + * iterations before any call to "fn". + * Return -1 on failure. + * + * Since we are going to be iterating over the individual values, + * we first check if there are any strides on the current dimension. + * If there is, we rewrite the current dimension i as + * + * i = stride i' + offset + * + * and then iterate over individual values of i' instead. + * + * We then look for a lower bound on i' and a size such that the domain + * is a subset of + * + * { [j,i'] : l(j) <= i' < l(j) + n } + * + * and then take slices of the domain at values of i' + * between l(j) and l(j) + n - 1. + * + * We compute the unshifted simple hull of each slice to ensure that + * we have a single basic set per offset. The slicing constraint + * may get simplified away before the unshifted simple hull is taken + * and may therefore in some rare cases disappear from the result. + * We therefore explicitly add the constraint back after computing + * the unshifted simple hull to ensure that the basic sets + * remain disjoint. The constraints that are dropped by taking the hull + * will be taken into account at the next level, as in the case of the + * atomic option. + * + * Finally, we map i' back to i and call "fn". + */ +static int foreach_iteration(__isl_take isl_set *domain, + __isl_keep isl_ast_build *build, int (*init)(int n, void *user), + int (*fn)(__isl_take isl_basic_set *bset, void *user), void *user) +{ + int i, n; + isl_bool empty; + isl_size depth; + isl_multi_aff *expansion; + isl_basic_map *bmap; + isl_aff *lower = NULL; + isl_ast_build *stride_build; + + depth = isl_ast_build_get_depth(build); + if (depth < 0) + domain = isl_set_free(domain); + + domain = isl_ast_build_eliminate_inner(build, domain); + domain = isl_set_intersect(domain, isl_ast_build_get_domain(build)); + stride_build = isl_ast_build_copy(build); + stride_build = isl_ast_build_detect_strides(stride_build, + isl_set_copy(domain)); + expansion = isl_ast_build_get_stride_expansion(stride_build); + + domain = isl_set_preimage_multi_aff(domain, + isl_multi_aff_copy(expansion)); + domain = isl_ast_build_eliminate_divs(stride_build, domain); + isl_ast_build_free(stride_build); + + bmap = isl_basic_map_from_multi_aff(expansion); + + empty = isl_set_is_empty(domain); + if (empty < 0) { + n = -1; + } else if (empty) { + n = 0; + } else { + lower = find_unroll_lower_bound(build, domain, depth, bmap, &n); + if (!lower) + n = -1; + } + if (n >= 0 && init && init(n, user) < 0) + n = -1; + for (i = 0; i < n; ++i) { + isl_set *set; + isl_basic_set *bset; + isl_constraint *slice; + + slice = at_offset(depth, lower, i); + set = isl_set_copy(domain); + set = isl_set_add_constraint(set, isl_constraint_copy(slice)); + bset = isl_set_unshifted_simple_hull(set); + bset = isl_basic_set_add_constraint(bset, slice); + bset = isl_basic_set_apply(bset, isl_basic_map_copy(bmap)); + + if (fn(bset, user) < 0) + break; + } + + isl_aff_free(lower); + isl_set_free(domain); + isl_basic_map_free(bmap); + + return n < 0 || i < n ? -1 : 0; +} + +/* Data structure for storing the results and the intermediate objects + * of compute_domains. + * + * "list" is the main result of the function and contains a list + * of disjoint basic sets for which code should be generated. + * + * "executed" and "build" are inputs to compute_domains. + * "schedule_domain" is the domain of "executed". + * + * "option" contains the domains at the current depth that should by + * atomic, separated or unrolled. These domains are as specified by + * the user, except that inner dimensions have been eliminated and + * that they have been made pair-wise disjoint. + * + * "sep_class" contains the user-specified split into separation classes + * specialized to the current depth. + * "done" contains the union of the separation domains that have already + * been handled. + */ +struct isl_codegen_domains { + isl_basic_set_list *list; + + isl_union_map *executed; + isl_ast_build *build; + isl_set *schedule_domain; + + isl_set *option[4]; + + isl_map *sep_class; + isl_set *done; +}; + +/* Internal data structure for do_unroll. + * + * "domains" stores the results of compute_domains. + * "class_domain" is the original class domain passed to do_unroll. + * "unroll_domain" collects the unrolled iterations. + */ +struct isl_ast_unroll_data { + struct isl_codegen_domains *domains; + isl_set *class_domain; + isl_set *unroll_domain; +}; + +/* Given an iteration of an unrolled domain represented by "bset", + * add it to data->domains->list. + * Since we may have dropped some constraints, we intersect with + * the class domain again to ensure that each element in the list + * is disjoint from the other class domains. + */ +static int do_unroll_iteration(__isl_take isl_basic_set *bset, void *user) +{ + struct isl_ast_unroll_data *data = user; + isl_set *set; + isl_basic_set_list *list; + + set = isl_set_from_basic_set(bset); + data->unroll_domain = isl_set_union(data->unroll_domain, + isl_set_copy(set)); + set = isl_set_intersect(set, isl_set_copy(data->class_domain)); + set = isl_set_make_disjoint(set); + list = isl_basic_set_list_from_set(set); + data->domains->list = isl_basic_set_list_concat(data->domains->list, + list); + + return 0; +} + +/* Extend domains->list with a list of basic sets, one for each value + * of the current dimension in "domain" and remove the corresponding + * sets from the class domain. Return the updated class domain. + * The divs that involve the current dimension have not been projected out + * from this domain. + * + * We call foreach_iteration to iterate over the individual values and + * in do_unroll_iteration we collect the individual basic sets in + * domains->list and their union in data->unroll_domain, which is then + * used to update the class domain. + */ +static __isl_give isl_set *do_unroll(struct isl_codegen_domains *domains, + __isl_take isl_set *domain, __isl_take isl_set *class_domain) +{ + struct isl_ast_unroll_data data; + + if (!domain) + return isl_set_free(class_domain); + if (!class_domain) + return isl_set_free(domain); + + data.domains = domains; + data.class_domain = class_domain; + data.unroll_domain = isl_set_empty(isl_set_get_space(domain)); + + if (foreach_iteration(domain, domains->build, NULL, + &do_unroll_iteration, &data) < 0) + data.unroll_domain = isl_set_free(data.unroll_domain); + + class_domain = isl_set_subtract(class_domain, data.unroll_domain); + + return class_domain; +} + +/* Add domains to domains->list for each individual value of the current + * dimension, for that part of the schedule domain that lies in the + * intersection of the option domain and the class domain. + * Remove the corresponding sets from the class domain and + * return the updated class domain. + * + * We first break up the unroll option domain into individual pieces + * and then handle each of them separately. The unroll option domain + * has been made disjoint in compute_domains_init_options, + * + * Note that we actively want to combine different pieces of the + * schedule domain that have the same value at the current dimension. + * We therefore need to break up the unroll option domain before + * intersecting with class and schedule domain, hoping that the + * unroll option domain specified by the user is relatively simple. + */ +static __isl_give isl_set *compute_unroll_domains( + struct isl_codegen_domains *domains, __isl_take isl_set *class_domain) +{ + isl_set *unroll_domain; + isl_basic_set_list *unroll_list; + int i; + isl_size n; + isl_bool empty; + + empty = isl_set_is_empty(domains->option[isl_ast_loop_unroll]); + if (empty < 0) + return isl_set_free(class_domain); + if (empty) + return class_domain; + + unroll_domain = isl_set_copy(domains->option[isl_ast_loop_unroll]); + unroll_list = isl_basic_set_list_from_set(unroll_domain); + + n = isl_basic_set_list_n_basic_set(unroll_list); + if (n < 0) + class_domain = isl_set_free(class_domain); + for (i = 0; i < n; ++i) { + isl_basic_set *bset; + + bset = isl_basic_set_list_get_basic_set(unroll_list, i); + unroll_domain = isl_set_from_basic_set(bset); + unroll_domain = isl_set_intersect(unroll_domain, + isl_set_copy(class_domain)); + unroll_domain = isl_set_intersect(unroll_domain, + isl_set_copy(domains->schedule_domain)); + + empty = isl_set_is_empty(unroll_domain); + if (empty >= 0 && empty) { + isl_set_free(unroll_domain); + continue; + } + + class_domain = do_unroll(domains, unroll_domain, class_domain); + } + + isl_basic_set_list_free(unroll_list); + + return class_domain; +} + +/* Try and construct a single basic set that includes the intersection of + * the schedule domain, the atomic option domain and the class domain. + * Add the resulting basic set(s) to domains->list and remove them + * from class_domain. Return the updated class domain. + * + * We construct a single domain rather than trying to combine + * the schedule domains of individual domains because we are working + * within a single component so that non-overlapping schedule domains + * should already have been separated. + * We do however need to make sure that this single domains is a subset + * of the class domain so that it would not intersect with any other + * class domains. This means that we may end up splitting up the atomic + * domain in case separation classes are being used. + * + * "domain" is the intersection of the schedule domain and the class domain, + * with inner dimensions projected out. + */ +static __isl_give isl_set *compute_atomic_domain( + struct isl_codegen_domains *domains, __isl_take isl_set *class_domain) +{ + isl_basic_set *bset; + isl_basic_set_list *list; + isl_set *domain, *atomic_domain; + int empty; + + domain = isl_set_copy(domains->option[isl_ast_loop_atomic]); + domain = isl_set_intersect(domain, isl_set_copy(class_domain)); + domain = isl_set_intersect(domain, + isl_set_copy(domains->schedule_domain)); + empty = isl_set_is_empty(domain); + if (empty < 0) + class_domain = isl_set_free(class_domain); + if (empty) { + isl_set_free(domain); + return class_domain; + } + + domain = isl_ast_build_eliminate(domains->build, domain); + domain = isl_set_coalesce_preserve(domain); + bset = isl_set_unshifted_simple_hull(domain); + domain = isl_set_from_basic_set(bset); + atomic_domain = isl_set_copy(domain); + domain = isl_set_intersect(domain, isl_set_copy(class_domain)); + class_domain = isl_set_subtract(class_domain, atomic_domain); + domain = isl_set_make_disjoint(domain); + list = isl_basic_set_list_from_set(domain); + domains->list = isl_basic_set_list_concat(domains->list, list); + + return class_domain; +} + +/* Split up the schedule domain into uniform basic sets, + * in the sense that each element in a basic set is associated to + * elements of the same domains, and add the result to domains->list. + * Do this for that part of the schedule domain that lies in the + * intersection of "class_domain" and the separate option domain. + * + * "class_domain" may or may not include the constraints + * of the schedule domain, but this does not make a difference + * since we are going to intersect it with the domain of the inverse schedule. + * If it includes schedule domain constraints, then they may involve + * inner dimensions, but we will eliminate them in separation_domain. + */ +static int compute_separate_domain(struct isl_codegen_domains *domains, + __isl_keep isl_set *class_domain) +{ + isl_space *space; + isl_set *domain; + isl_union_map *executed; + isl_basic_set_list *list; + int empty; + + domain = isl_set_copy(domains->option[isl_ast_loop_separate]); + domain = isl_set_intersect(domain, isl_set_copy(class_domain)); + executed = isl_union_map_copy(domains->executed); + executed = isl_union_map_intersect_domain(executed, + isl_union_set_from_set(domain)); + empty = isl_union_map_is_empty(executed); + if (empty < 0 || empty) { + isl_union_map_free(executed); + return empty < 0 ? -1 : 0; + } + + space = isl_set_get_space(class_domain); + domain = separate_schedule_domains(space, executed, domains->build); + + list = isl_basic_set_list_from_set(domain); + domains->list = isl_basic_set_list_concat(domains->list, list); + + return 0; +} + +/* Split up the domain at the current depth into disjoint + * basic sets for which code should be generated separately + * for the given separation class domain. + * + * If any separation classes have been defined, then "class_domain" + * is the domain of the current class and does not refer to inner dimensions. + * Otherwise, "class_domain" is the universe domain. + * + * We first make sure that the class domain is disjoint from + * previously considered class domains. + * + * The separate domains can be computed directly from the "class_domain". + * + * The unroll, atomic and remainder domains need the constraints + * from the schedule domain. + * + * For unrolling, the actual schedule domain is needed (with divs that + * may refer to the current dimension) so that stride detection can be + * performed. + * + * For atomic and remainder domains, inner dimensions and divs involving + * the current dimensions should be eliminated. + * In case we are working within a separation class, we need to intersect + * the result with the current "class_domain" to ensure that the domains + * are disjoint from those generated from other class domains. + * + * The domain that has been made atomic may be larger than specified + * by the user since it needs to be representable as a single basic set. + * This possibly larger domain is removed from class_domain by + * compute_atomic_domain. It is computed first so that the extended domain + * would not overlap with any domains computed before. + * Similary, the unrolled domains may have some constraints removed and + * may therefore also be larger than specified by the user. + * + * If anything is left after handling separate, unroll and atomic, + * we split it up into basic sets and append the basic sets to domains->list. + */ +static isl_stat compute_partial_domains(struct isl_codegen_domains *domains, + __isl_take isl_set *class_domain) +{ + isl_basic_set_list *list; + isl_set *domain; + + class_domain = isl_set_subtract(class_domain, + isl_set_copy(domains->done)); + domains->done = isl_set_union(domains->done, + isl_set_copy(class_domain)); + + class_domain = compute_atomic_domain(domains, class_domain); + class_domain = compute_unroll_domains(domains, class_domain); + + domain = isl_set_copy(class_domain); + + if (compute_separate_domain(domains, domain) < 0) + goto error; + domain = isl_set_subtract(domain, + isl_set_copy(domains->option[isl_ast_loop_separate])); + + domain = isl_set_intersect(domain, + isl_set_copy(domains->schedule_domain)); + + domain = isl_ast_build_eliminate(domains->build, domain); + domain = isl_set_intersect(domain, isl_set_copy(class_domain)); + + domain = isl_set_coalesce_preserve(domain); + domain = isl_set_make_disjoint(domain); + + list = isl_basic_set_list_from_set(domain); + domains->list = isl_basic_set_list_concat(domains->list, list); + + isl_set_free(class_domain); + + return isl_stat_ok; +error: + isl_set_free(domain); + isl_set_free(class_domain); + return isl_stat_error; +} + +/* Split up the domain at the current depth into disjoint + * basic sets for which code should be generated separately + * for the separation class identified by "pnt". + * + * We extract the corresponding class domain from domains->sep_class, + * eliminate inner dimensions and pass control to compute_partial_domains. + */ +static isl_stat compute_class_domains(__isl_take isl_point *pnt, void *user) +{ + struct isl_codegen_domains *domains = user; + isl_set *class_set; + isl_set *domain; + int disjoint; + + class_set = isl_set_from_point(pnt); + domain = isl_map_domain(isl_map_intersect_range( + isl_map_copy(domains->sep_class), class_set)); + domain = isl_ast_build_compute_gist(domains->build, domain); + domain = isl_ast_build_eliminate(domains->build, domain); + + disjoint = isl_set_plain_is_disjoint(domain, domains->schedule_domain); + if (disjoint < 0) + return isl_stat_error; + if (disjoint) { + isl_set_free(domain); + return isl_stat_ok; + } + + return compute_partial_domains(domains, domain); +} + +/* Extract the domains at the current depth that should be atomic, + * separated or unrolled and store them in option. + * + * The domains specified by the user might overlap, so we make + * them disjoint by subtracting earlier domains from later domains. + */ +static void compute_domains_init_options(isl_set *option[4], + __isl_keep isl_ast_build *build) +{ + enum isl_ast_loop_type type, type2; + isl_set *unroll; + + for (type = isl_ast_loop_atomic; + type <= isl_ast_loop_separate; ++type) { + option[type] = isl_ast_build_get_option_domain(build, type); + for (type2 = isl_ast_loop_atomic; type2 < type; ++type2) + option[type] = isl_set_subtract(option[type], + isl_set_copy(option[type2])); + } + + unroll = option[isl_ast_loop_unroll]; + unroll = isl_set_coalesce(unroll); + unroll = isl_set_make_disjoint(unroll); + option[isl_ast_loop_unroll] = unroll; +} + +/* Split up the domain at the current depth into disjoint + * basic sets for which code should be generated separately, + * based on the user-specified options. + * Return the list of disjoint basic sets. + * + * There are three kinds of domains that we need to keep track of. + * - the "schedule domain" is the domain of "executed" + * - the "class domain" is the domain corresponding to the currrent + * separation class + * - the "option domain" is the domain corresponding to one of the options + * atomic, unroll or separate + * + * We first consider the individial values of the separation classes + * and split up the domain for each of them separately. + * Finally, we consider the remainder. If no separation classes were + * specified, then we call compute_partial_domains with the universe + * "class_domain". Otherwise, we take the "schedule_domain" as "class_domain", + * with inner dimensions removed. We do this because we want to + * avoid computing the complement of the class domains (i.e., the difference + * between the universe and domains->done). + */ +static __isl_give isl_basic_set_list *compute_domains( + __isl_keep isl_union_map *executed, __isl_keep isl_ast_build *build) +{ + struct isl_codegen_domains domains; + isl_ctx *ctx; + isl_set *domain; + isl_union_set *schedule_domain; + isl_set *classes; + isl_space *space; + int n_param; + enum isl_ast_loop_type type; + isl_bool empty; + + if (!executed) + return NULL; + + ctx = isl_union_map_get_ctx(executed); + domains.list = isl_basic_set_list_alloc(ctx, 0); + + schedule_domain = isl_union_map_domain(isl_union_map_copy(executed)); + domain = isl_set_from_union_set(schedule_domain); + + compute_domains_init_options(domains.option, build); + + domains.sep_class = isl_ast_build_get_separation_class(build); + classes = isl_map_range(isl_map_copy(domains.sep_class)); + n_param = isl_set_dim(classes, isl_dim_param); + if (n_param < 0) + classes = isl_set_free(classes); + classes = isl_set_project_out(classes, isl_dim_param, 0, n_param); + + space = isl_set_get_space(domain); + domains.build = build; + domains.schedule_domain = isl_set_copy(domain); + domains.executed = executed; + domains.done = isl_set_empty(space); + + if (isl_set_foreach_point(classes, &compute_class_domains, &domains) < 0) + domains.list = isl_basic_set_list_free(domains.list); + isl_set_free(classes); + + empty = isl_set_is_empty(domains.done); + if (empty < 0) { + domains.list = isl_basic_set_list_free(domains.list); + domain = isl_set_free(domain); + } else if (empty) { + isl_set_free(domain); + domain = isl_set_universe(isl_set_get_space(domains.done)); + } else { + domain = isl_ast_build_eliminate(build, domain); + } + if (compute_partial_domains(&domains, domain) < 0) + domains.list = isl_basic_set_list_free(domains.list); + + isl_set_free(domains.schedule_domain); + isl_set_free(domains.done); + isl_map_free(domains.sep_class); + for (type = isl_ast_loop_atomic; type <= isl_ast_loop_separate; ++type) + isl_set_free(domains.option[type]); + + return domains.list; +} + +/* Generate code for a single component, after shifting (if any) + * has been applied, in case the schedule was specified as a union map. + * + * We first split up the domain at the current depth into disjoint + * basic sets based on the user-specified options. + * Then we generated code for each of them and concatenate the results. + */ +static __isl_give isl_ast_graft_list *generate_shifted_component_flat( + __isl_take isl_union_map *executed, __isl_take isl_ast_build *build) +{ + isl_basic_set_list *domain_list; + isl_ast_graft_list *list = NULL; + + domain_list = compute_domains(executed, build); + list = generate_parallel_domains(domain_list, executed, build); + + isl_basic_set_list_free(domain_list); + isl_union_map_free(executed); + isl_ast_build_free(build); + + return list; +} + +/* Generate code for a single component, after shifting (if any) + * has been applied, in case the schedule was specified as a schedule tree + * and the separate option was specified. + * + * We perform separation on the domain of "executed" and then generate + * an AST for each of the resulting disjoint basic sets. + */ +static __isl_give isl_ast_graft_list *generate_shifted_component_tree_separate( + __isl_take isl_union_map *executed, __isl_take isl_ast_build *build) +{ + isl_space *space; + isl_set *domain; + isl_basic_set_list *domain_list; + isl_ast_graft_list *list; + + space = isl_ast_build_get_space(build, 1); + domain = separate_schedule_domains(space, + isl_union_map_copy(executed), build); + domain_list = isl_basic_set_list_from_set(domain); + + list = generate_parallel_domains(domain_list, executed, build); + + isl_basic_set_list_free(domain_list); + isl_union_map_free(executed); + isl_ast_build_free(build); + + return list; +} + +/* Internal data structure for generate_shifted_component_tree_unroll. + * + * "executed" and "build" are inputs to generate_shifted_component_tree_unroll. + * "list" collects the constructs grafts. + */ +struct isl_ast_unroll_tree_data { + isl_union_map *executed; + isl_ast_build *build; + isl_ast_graft_list *list; +}; + +/* Initialize data->list to a list of "n" elements. + */ +static int init_unroll_tree(int n, void *user) +{ + struct isl_ast_unroll_tree_data *data = user; + isl_ctx *ctx; + + ctx = isl_ast_build_get_ctx(data->build); + data->list = isl_ast_graft_list_alloc(ctx, n); + + return 0; +} + +/* Given an iteration of an unrolled domain represented by "bset", + * generate the corresponding AST and add the result to data->list. + */ +static int do_unroll_tree_iteration(__isl_take isl_basic_set *bset, void *user) +{ + struct isl_ast_unroll_tree_data *data = user; + + data->list = add_node(data->list, isl_union_map_copy(data->executed), + bset, isl_ast_build_copy(data->build)); + + return 0; +} + +/* Generate code for a single component, after shifting (if any) + * has been applied, in case the schedule was specified as a schedule tree + * and the unroll option was specified. + * + * We call foreach_iteration to iterate over the individual values and + * construct and collect the corresponding grafts in do_unroll_tree_iteration. + */ +static __isl_give isl_ast_graft_list *generate_shifted_component_tree_unroll( + __isl_take isl_union_map *executed, __isl_take isl_set *domain, + __isl_take isl_ast_build *build) +{ + struct isl_ast_unroll_tree_data data = { executed, build, NULL }; + + if (foreach_iteration(domain, build, &init_unroll_tree, + &do_unroll_tree_iteration, &data) < 0) + data.list = isl_ast_graft_list_free(data.list); + + isl_union_map_free(executed); + isl_ast_build_free(build); + + return data.list; +} + +/* Does "domain" involve a disjunction that is purely based on + * constraints involving only outer dimension? + * + * In particular, is there a disjunction such that the constraints + * involving the current and later dimensions are the same over + * all the disjuncts? + */ +static isl_bool has_pure_outer_disjunction(__isl_keep isl_set *domain, + __isl_keep isl_ast_build *build) +{ + isl_basic_set *hull; + isl_set *shared, *inner; + isl_bool equal; + isl_size depth; + isl_size n; + isl_size dim; + + n = isl_set_n_basic_set(domain); + if (n < 0) + return isl_bool_error; + if (n <= 1) + return isl_bool_false; + dim = isl_set_dim(domain, isl_dim_set); + depth = isl_ast_build_get_depth(build); + if (dim < 0 || depth < 0) + return isl_bool_error; + + inner = isl_set_copy(domain); + inner = isl_set_drop_constraints_not_involving_dims(inner, + isl_dim_set, depth, dim - depth); + hull = isl_set_plain_unshifted_simple_hull(isl_set_copy(inner)); + shared = isl_set_from_basic_set(hull); + equal = isl_set_plain_is_equal(inner, shared); + isl_set_free(inner); + isl_set_free(shared); + + return equal; +} + +/* Generate code for a single component, after shifting (if any) + * has been applied, in case the schedule was specified as a schedule tree. + * In particular, handle the base case where there is either no isolated + * set or we are within the isolated set (in which case "isolated" is set) + * or the iterations that precede or follow the isolated set. + * + * The schedule domain is broken up or combined into basic sets + * according to the AST generation option specified in the current + * schedule node, which may be either atomic, separate, unroll or + * unspecified. If the option is unspecified, then we currently simply + * split the schedule domain into disjoint basic sets. + * + * In case the separate option is specified, the AST generation is + * handled by generate_shifted_component_tree_separate. + * In the other cases, we need the global schedule domain. + * In the unroll case, the AST generation is then handled by + * generate_shifted_component_tree_unroll which needs the actual + * schedule domain (with divs that may refer to the current dimension) + * so that stride detection can be performed. + * In the atomic or unspecified case, inner dimensions and divs involving + * the current dimensions should be eliminated. + * The result is then either combined into a single basic set or + * split up into disjoint basic sets. + * Finally an AST is generated for each basic set and the results are + * concatenated. + * + * If the schedule domain involves a disjunction that is purely based on + * constraints involving only outer dimension, then it is treated as + * if atomic was specified. This ensures that only a single loop + * is generated instead of a sequence of identical loops with + * different guards. + */ +static __isl_give isl_ast_graft_list *generate_shifted_component_tree_base( + __isl_take isl_union_map *executed, __isl_take isl_ast_build *build, + int isolated) +{ + isl_bool outer_disjunction; + isl_union_set *schedule_domain; + isl_set *domain; + isl_basic_set_list *domain_list; + isl_ast_graft_list *list; + enum isl_ast_loop_type type; + + type = isl_ast_build_get_loop_type(build, isolated); + if (type < 0) + goto error; + + if (type == isl_ast_loop_separate) + return generate_shifted_component_tree_separate(executed, + build); + + schedule_domain = isl_union_map_domain(isl_union_map_copy(executed)); + domain = isl_set_from_union_set(schedule_domain); + + if (type == isl_ast_loop_unroll) + return generate_shifted_component_tree_unroll(executed, domain, + build); + + domain = isl_ast_build_eliminate(build, domain); + domain = isl_set_coalesce_preserve(domain); + + outer_disjunction = has_pure_outer_disjunction(domain, build); + if (outer_disjunction < 0) + domain = isl_set_free(domain); + + if (outer_disjunction || type == isl_ast_loop_atomic) { + isl_basic_set *hull; + hull = isl_set_unshifted_simple_hull(domain); + domain_list = isl_basic_set_list_from_basic_set(hull); + } else { + domain = isl_set_make_disjoint(domain); + domain_list = isl_basic_set_list_from_set(domain); + } + + list = generate_parallel_domains(domain_list, executed, build); + + isl_basic_set_list_free(domain_list); + isl_union_map_free(executed); + isl_ast_build_free(build); + + return list; +error: + isl_union_map_free(executed); + isl_ast_build_free(build); + return NULL; +} + +/* Extract out the disjunction imposed by "domain" on the outer + * schedule dimensions. + * + * In particular, remove all inner dimensions from "domain" (including + * the current dimension) and then remove the constraints that are shared + * by all disjuncts in the result. + */ +static __isl_give isl_set *extract_disjunction(__isl_take isl_set *domain, + __isl_keep isl_ast_build *build) +{ + isl_set *hull; + isl_size depth; + isl_size dim; + + domain = isl_ast_build_specialize(build, domain); + depth = isl_ast_build_get_depth(build); + dim = isl_set_dim(domain, isl_dim_set); + if (depth < 0 || dim < 0) + return isl_set_free(domain); + domain = isl_set_eliminate(domain, isl_dim_set, depth, dim - depth); + domain = isl_set_remove_unknown_divs(domain); + hull = isl_set_copy(domain); + hull = isl_set_from_basic_set(isl_set_unshifted_simple_hull(hull)); + domain = isl_set_gist(domain, hull); + + return domain; +} + +/* Add "guard" to the grafts in "list". + * "build" is the outer AST build, while "sub_build" includes "guard" + * in its generated domain. + * + * First combine the grafts into a single graft and then add the guard. + * If the list is empty, or if some error occurred, then simply return + * the list. + */ +static __isl_give isl_ast_graft_list *list_add_guard( + __isl_take isl_ast_graft_list *list, __isl_keep isl_set *guard, + __isl_keep isl_ast_build *build, __isl_keep isl_ast_build *sub_build) +{ + isl_ast_graft *graft; + isl_size n; + + list = isl_ast_graft_list_fuse(list, sub_build); + + n = isl_ast_graft_list_n_ast_graft(list); + if (n < 0) + return isl_ast_graft_list_free(list); + if (n != 1) + return list; + + graft = isl_ast_graft_list_get_ast_graft(list, 0); + graft = isl_ast_graft_add_guard(graft, isl_set_copy(guard), build); + list = isl_ast_graft_list_set_ast_graft(list, 0, graft); + + return list; +} + +/* Generate code for a single component, after shifting (if any) + * has been applied, in case the schedule was specified as a schedule tree. + * In particular, do so for the specified subset of the schedule domain. + * + * If we are outside of the isolated part, then "domain" may include + * a disjunction. Explicitly generate this disjunction at this point + * instead of relying on the disjunction getting hoisted back up + * to this level. + */ +static __isl_give isl_ast_graft_list *generate_shifted_component_tree_part( + __isl_keep isl_union_map *executed, __isl_take isl_set *domain, + __isl_keep isl_ast_build *build, int isolated) +{ + isl_union_set *uset; + isl_ast_graft_list *list; + isl_ast_build *sub_build; + int empty; + + uset = isl_union_set_from_set(isl_set_copy(domain)); + executed = isl_union_map_copy(executed); + executed = isl_union_map_intersect_domain(executed, uset); + empty = isl_union_map_is_empty(executed); + if (empty < 0) + goto error; + if (empty) { + isl_ctx *ctx; + isl_union_map_free(executed); + isl_set_free(domain); + ctx = isl_ast_build_get_ctx(build); + return isl_ast_graft_list_alloc(ctx, 0); + } + + sub_build = isl_ast_build_copy(build); + if (!isolated) { + domain = extract_disjunction(domain, build); + sub_build = isl_ast_build_restrict_generated(sub_build, + isl_set_copy(domain)); + } + list = generate_shifted_component_tree_base(executed, + isl_ast_build_copy(sub_build), isolated); + if (!isolated) + list = list_add_guard(list, domain, build, sub_build); + isl_ast_build_free(sub_build); + isl_set_free(domain); + return list; +error: + isl_union_map_free(executed); + isl_set_free(domain); + return NULL; +} + +/* Generate code for a single component, after shifting (if any) + * has been applied, in case the schedule was specified as a schedule tree. + * In particular, do so for the specified sequence of subsets + * of the schedule domain, "before", "isolated", "after" and "other", + * where only the "isolated" part is considered to be isolated. + */ +static __isl_give isl_ast_graft_list *generate_shifted_component_parts( + __isl_take isl_union_map *executed, __isl_take isl_set *before, + __isl_take isl_set *isolated, __isl_take isl_set *after, + __isl_take isl_set *other, __isl_take isl_ast_build *build) +{ + isl_ast_graft_list *list, *res; + + res = generate_shifted_component_tree_part(executed, before, build, 0); + list = generate_shifted_component_tree_part(executed, isolated, + build, 1); + res = isl_ast_graft_list_concat(res, list); + list = generate_shifted_component_tree_part(executed, after, build, 0); + res = isl_ast_graft_list_concat(res, list); + list = generate_shifted_component_tree_part(executed, other, build, 0); + res = isl_ast_graft_list_concat(res, list); + + isl_union_map_free(executed); + isl_ast_build_free(build); + + return res; +} + +/* Does "set" intersect "first", but not "second"? + */ +static isl_bool only_intersects_first(__isl_keep isl_set *set, + __isl_keep isl_set *first, __isl_keep isl_set *second) +{ + isl_bool disjoint; + + disjoint = isl_set_is_disjoint(set, first); + if (disjoint < 0) + return isl_bool_error; + if (disjoint) + return isl_bool_false; + + return isl_set_is_disjoint(set, second); +} + +/* Generate code for a single component, after shifting (if any) + * has been applied, in case the schedule was specified as a schedule tree. + * In particular, do so in case of isolation where there is + * only an "isolated" part and an "after" part. + * "dead1" and "dead2" are freed by this function in order to simplify + * the caller. + * + * The "before" and "other" parts are set to empty sets. + */ +static __isl_give isl_ast_graft_list *generate_shifted_component_only_after( + __isl_take isl_union_map *executed, __isl_take isl_set *isolated, + __isl_take isl_set *after, __isl_take isl_ast_build *build, + __isl_take isl_set *dead1, __isl_take isl_set *dead2) +{ + isl_set *empty; + + empty = isl_set_empty(isl_set_get_space(after)); + isl_set_free(dead1); + isl_set_free(dead2); + return generate_shifted_component_parts(executed, isl_set_copy(empty), + isolated, after, empty, build); +} + +/* Generate code for a single component, after shifting (if any) + * has been applied, in case the schedule was specified as a schedule tree. + * + * We first check if the user has specified an isolated schedule domain + * and that we are not already outside of this isolated schedule domain. + * If so, we break up the schedule domain into iterations that + * precede the isolated domain, the isolated domain itself, + * the iterations that follow the isolated domain and + * the remaining iterations (those that are incomparable + * 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 + * elements need to be scheduled before, break up the schedule domain + * in only two parts, the isolated domain, and a part that will be + * scheduled after the isolated domain. + * + * If no isolated set has been specified, then we generate an + * AST for the entire inverse schedule. + */ +static __isl_give isl_ast_graft_list *generate_shifted_component_tree( + __isl_take isl_union_map *executed, __isl_take isl_ast_build *build) +{ + int i; + isl_size depth; + int empty, has_isolate; + isl_space *space; + isl_union_set *schedule_domain; + isl_set *domain; + isl_basic_set *hull; + isl_set *isolated, *before, *after, *test; + isl_map *gt, *lt; + isl_bool pure; + + build = isl_ast_build_extract_isolated(build); + has_isolate = isl_ast_build_has_isolated(build); + if (has_isolate < 0) + executed = isl_union_map_free(executed); + else if (!has_isolate) + return generate_shifted_component_tree_base(executed, build, 0); + + schedule_domain = isl_union_map_domain(isl_union_map_copy(executed)); + domain = isl_set_from_union_set(schedule_domain); + + isolated = isl_ast_build_get_isolated(build); + isolated = isl_set_intersect(isolated, isl_set_copy(domain)); + test = isl_ast_build_specialize(build, isl_set_copy(isolated)); + empty = isl_set_is_empty(test); + isl_set_free(test); + if (empty < 0) + goto error; + if (empty) { + isl_set_free(isolated); + isl_set_free(domain); + return generate_shifted_component_tree_base(executed, build, 0); + } + depth = isl_ast_build_get_depth(build); + if (depth < 0) + goto error; + + isolated = isl_ast_build_eliminate(build, isolated); + hull = isl_set_unshifted_simple_hull(isolated); + isolated = isl_set_from_basic_set(hull); + + space = isl_space_map_from_set(isl_set_get_space(isolated)); + gt = isl_map_universe(space); + for (i = 0; i < depth; ++i) + gt = isl_map_equate(gt, isl_dim_in, i, isl_dim_out, i); + gt = isl_map_order_gt(gt, isl_dim_in, depth, isl_dim_out, depth); + lt = isl_map_reverse(isl_map_copy(gt)); + before = isl_set_apply(isl_set_copy(isolated), gt); + after = isl_set_apply(isl_set_copy(isolated), lt); + + domain = isl_set_subtract(domain, isl_set_copy(isolated)); + pure = only_intersects_first(domain, after, before); + if (pure < 0) + executed = isl_union_map_free(executed); + else if (pure) + return generate_shifted_component_only_after(executed, isolated, + domain, build, before, after); + domain = isl_set_subtract(domain, isl_set_copy(before)); + domain = isl_set_subtract(domain, isl_set_copy(after)); + after = isl_set_subtract(after, isl_set_copy(isolated)); + after = isl_set_subtract(after, isl_set_copy(before)); + before = isl_set_subtract(before, isl_set_copy(isolated)); + + return generate_shifted_component_parts(executed, before, isolated, + after, domain, build); +error: + isl_set_free(domain); + isl_set_free(isolated); + isl_union_map_free(executed); + isl_ast_build_free(build); + return NULL; +} + +/* Generate code for a single component, after shifting (if any) + * has been applied. + * + * Call generate_shifted_component_tree or generate_shifted_component_flat + * depending on whether the schedule was specified as a schedule tree. + */ +static __isl_give isl_ast_graft_list *generate_shifted_component( + __isl_take isl_union_map *executed, __isl_take isl_ast_build *build) +{ + if (isl_ast_build_has_schedule_node(build)) + return generate_shifted_component_tree(executed, build); + else + return generate_shifted_component_flat(executed, build); +} + +struct isl_set_map_pair { + isl_set *set; + isl_map *map; +}; + +/* Given an array "domain" of isl_set_map_pairs and an array "order" + * of indices into the "domain" array, + * return the union of the "map" fields of the elements + * indexed by the first "n" elements of "order". + */ +static __isl_give isl_union_map *construct_component_executed( + struct isl_set_map_pair *domain, int *order, int n) +{ + int i; + isl_map *map; + isl_union_map *executed; + + map = isl_map_copy(domain[order[0]].map); + executed = isl_union_map_from_map(map); + for (i = 1; i < n; ++i) { + map = isl_map_copy(domain[order[i]].map); + executed = isl_union_map_add_map(executed, map); + } + + return executed; +} + +/* Generate code for a single component, after shifting (if any) + * has been applied. + * + * The component inverse schedule is specified as the "map" fields + * of the elements of "domain" indexed by the first "n" elements of "order". + */ +static __isl_give isl_ast_graft_list *generate_shifted_component_from_list( + struct isl_set_map_pair *domain, int *order, int n, + __isl_take isl_ast_build *build) +{ + isl_union_map *executed; + + executed = construct_component_executed(domain, order, n); + return generate_shifted_component(executed, build); +} + +/* Does set dimension "pos" of "set" have an obviously fixed value? + */ +static int dim_is_fixed(__isl_keep isl_set *set, int pos) +{ + int fixed; + isl_val *v; + + v = isl_set_plain_get_val_if_fixed(set, isl_dim_set, pos); + if (!v) + return -1; + fixed = !isl_val_is_nan(v); + isl_val_free(v); + + return fixed; +} + +/* Given an array "domain" of isl_set_map_pairs and an array "order" + * of indices into the "domain" array, + * do all (except for at most one) of the "set" field of the elements + * indexed by the first "n" elements of "order" have a fixed value + * at position "depth"? + */ +static int at_most_one_non_fixed(struct isl_set_map_pair *domain, + int *order, int n, int depth) +{ + int i; + int non_fixed = -1; + + for (i = 0; i < n; ++i) { + int f; + + f = dim_is_fixed(domain[order[i]].set, depth); + if (f < 0) + return -1; + if (f) + continue; + if (non_fixed >= 0) + return 0; + non_fixed = i; + } + + return 1; +} + +/* Given an array "domain" of isl_set_map_pairs and an array "order" + * of indices into the "domain" array, + * eliminate the inner dimensions from the "set" field of the elements + * indexed by the first "n" elements of "order", provided the current + * dimension does not have a fixed value. + * + * Return the index of the first element in "order" with a corresponding + * "set" field that does not have an (obviously) fixed value. + */ +static int eliminate_non_fixed(struct isl_set_map_pair *domain, + int *order, int n, int depth, __isl_keep isl_ast_build *build) +{ + int i; + int base = -1; + + for (i = n - 1; i >= 0; --i) { + int f; + f = dim_is_fixed(domain[order[i]].set, depth); + if (f < 0) + return -1; + if (f) + continue; + domain[order[i]].set = isl_ast_build_eliminate_inner(build, + domain[order[i]].set); + base = i; + } + + return base; +} + +/* Given an array "domain" of isl_set_map_pairs and an array "order" + * of indices into the "domain" array, + * find the element of "domain" (amongst those indexed by the first "n" + * elements of "order") with the "set" field that has the smallest + * value for the current iterator. + * + * Note that the domain with the smallest value may depend on the parameters + * and/or outer loop dimension. Since the result of this function is only + * used as heuristic, we only make a reasonable attempt at finding the best + * domain, one that should work in case a single domain provides the smallest + * value for the current dimension over all values of the parameters + * and outer dimensions. + * + * In particular, we compute the smallest value of the first domain + * and replace it by that of any later domain if that later domain + * has a smallest value that is smaller for at least some value + * of the parameters and outer dimensions. + */ +static int first_offset(struct isl_set_map_pair *domain, int *order, int n, + __isl_keep isl_ast_build *build) +{ + int i; + isl_map *min_first; + int first = 0; + + min_first = isl_ast_build_map_to_iterator(build, + isl_set_copy(domain[order[0]].set)); + min_first = isl_map_lexmin(min_first); + + for (i = 1; i < n; ++i) { + isl_map *min, *test; + int empty; + + min = isl_ast_build_map_to_iterator(build, + isl_set_copy(domain[order[i]].set)); + min = isl_map_lexmin(min); + test = isl_map_copy(min); + test = isl_map_apply_domain(isl_map_copy(min_first), test); + test = isl_map_order_lt(test, isl_dim_in, 0, isl_dim_out, 0); + empty = isl_map_is_empty(test); + isl_map_free(test); + if (empty >= 0 && !empty) { + isl_map_free(min_first); + first = i; + min_first = min; + } else + isl_map_free(min); + + if (empty < 0) + break; + } + + isl_map_free(min_first); + + return i < n ? -1 : first; +} + +/* Construct a shifted inverse schedule based on the original inverse schedule, + * the stride and the offset. + * + * The original inverse schedule is specified as the "map" fields + * of the elements of "domain" indexed by the first "n" elements of "order". + * + * "stride" and "offset" are such that the difference + * between the values of the current dimension of domain "i" + * and the values of the current dimension for some reference domain are + * equal to + * + * stride * integer + offset[i] + * + * Moreover, 0 <= offset[i] < stride. + * + * For each domain, we create a map + * + * { [..., j, ...] -> [..., j - offset[i], offset[i], ....] } + * + * where j refers to the current dimension and the other dimensions are + * unchanged, and apply this map to the original schedule domain. + * + * For example, for the original schedule + * + * { A[i] -> [2i]: 0 <= i < 10; B[i] -> [2i+1] : 0 <= i < 10 } + * + * and assuming the offset is 0 for the A domain and 1 for the B domain, + * we apply the mapping + * + * { [j] -> [j, 0] } + * + * to the schedule of the "A" domain and the mapping + * + * { [j - 1] -> [j, 1] } + * + * to the schedule of the "B" domain. + * + * + * Note that after the transformation, the differences between pairs + * of values of the current dimension over all domains are multiples + * of stride and that we have therefore exposed the stride. + * + * + * To see that the mapping preserves the lexicographic order, + * first note that each of the individual maps above preserves the order. + * If the value of the current iterator is j1 in one domain and j2 in another, + * then if j1 = j2, we know that the same map is applied to both domains + * and the order is preserved. + * Otherwise, let us assume, without loss of generality, that j1 < j2. + * If c1 >= c2 (with c1 and c2 the corresponding offsets), then + * + * j1 - c1 < j2 - c2 + * + * and the order is preserved. + * If c1 < c2, then we know + * + * 0 <= c2 - c1 < s + * + * We also have + * + * j2 - j1 = n * s + r + * + * with n >= 0 and 0 <= r < s. + * In other words, r = c2 - c1. + * If n > 0, then + * + * j1 - c1 < j2 - c2 + * + * If n = 0, then + * + * j1 - c1 = j2 - c2 + * + * and so + * + * (j1 - c1, c1) << (j2 - c2, c2) + * + * with "<<" the lexicographic order, proving that the order is preserved + * in all cases. + */ +static __isl_give isl_union_map *construct_shifted_executed( + struct isl_set_map_pair *domain, int *order, int n, + __isl_keep isl_val *stride, __isl_keep isl_multi_val *offset, + __isl_keep isl_ast_build *build) +{ + int i; + isl_union_map *executed; + isl_space *space; + isl_map *map; + isl_size depth; + isl_constraint *c; + + depth = isl_ast_build_get_depth(build); + if (depth < 0) + return NULL; + space = isl_ast_build_get_space(build, 1); + executed = isl_union_map_empty(isl_space_copy(space)); + space = isl_space_map_from_set(space); + map = isl_map_identity(isl_space_copy(space)); + map = isl_map_eliminate(map, isl_dim_out, depth, 1); + map = isl_map_insert_dims(map, isl_dim_out, depth + 1, 1); + space = isl_space_insert_dims(space, isl_dim_out, depth + 1, 1); + + c = isl_constraint_alloc_equality(isl_local_space_from_space(space)); + c = isl_constraint_set_coefficient_si(c, isl_dim_in, depth, 1); + c = isl_constraint_set_coefficient_si(c, isl_dim_out, depth, -1); + + for (i = 0; i < n; ++i) { + isl_map *map_i; + isl_val *v; + + v = isl_multi_val_get_val(offset, i); + if (!v) + break; + map_i = isl_map_copy(map); + map_i = isl_map_fix_val(map_i, isl_dim_out, depth + 1, + isl_val_copy(v)); + v = isl_val_neg(v); + c = isl_constraint_set_constant_val(c, v); + map_i = isl_map_add_constraint(map_i, isl_constraint_copy(c)); + + map_i = isl_map_apply_domain(isl_map_copy(domain[order[i]].map), + map_i); + executed = isl_union_map_add_map(executed, map_i); + } + + isl_constraint_free(c); + isl_map_free(map); + + if (i < n) + executed = isl_union_map_free(executed); + + return executed; +} + +/* Generate code for a single component, after exposing the stride, + * given that the schedule domain is "shifted strided". + * + * The component inverse schedule is specified as the "map" fields + * of the elements of "domain" indexed by the first "n" elements of "order". + * + * The schedule domain being "shifted strided" means that the differences + * between the values of the current dimension of domain "i" + * and the values of the current dimension for some reference domain are + * equal to + * + * stride * integer + offset[i] + * + * We first look for the domain with the "smallest" value for the current + * dimension and adjust the offsets such that the offset of the "smallest" + * domain is equal to zero. The other offsets are reduced modulo stride. + * + * Based on this information, we construct a new inverse schedule in + * construct_shifted_executed that exposes the stride. + * Since this involves the introduction of a new schedule dimension, + * the build needs to be changed accordingly. + * After computing the AST, the newly introduced dimension needs + * to be removed again from the list of grafts. We do this by plugging + * in a mapping that represents the new schedule domain in terms of the + * old schedule domain. + */ +static __isl_give isl_ast_graft_list *generate_shift_component( + struct isl_set_map_pair *domain, int *order, int n, + __isl_keep isl_val *stride, __isl_keep isl_multi_val *offset, + __isl_take isl_ast_build *build) +{ + isl_ast_graft_list *list; + int first; + isl_size depth; + isl_val *val; + isl_multi_val *mv; + isl_space *space; + isl_multi_aff *ma, *zero; + isl_union_map *executed; + + depth = isl_ast_build_get_depth(build); + + first = first_offset(domain, order, n, build); + if (depth < 0 || first < 0) + goto error; + + mv = isl_multi_val_copy(offset); + val = isl_multi_val_get_val(offset, first); + val = isl_val_neg(val); + mv = isl_multi_val_add_val(mv, val); + mv = isl_multi_val_mod_val(mv, isl_val_copy(stride)); + + executed = construct_shifted_executed(domain, order, n, stride, mv, + build); + space = isl_ast_build_get_space(build, 1); + space = isl_space_map_from_set(space); + ma = isl_multi_aff_identity(isl_space_copy(space)); + space = isl_space_from_domain(isl_space_domain(space)); + space = isl_space_add_dims(space, isl_dim_out, 1); + zero = isl_multi_aff_zero(space); + ma = isl_multi_aff_range_splice(ma, depth + 1, zero); + build = isl_ast_build_insert_dim(build, depth + 1); + list = generate_shifted_component(executed, build); + + list = isl_ast_graft_list_preimage_multi_aff(list, ma); + + isl_multi_val_free(mv); + + return list; +error: + isl_ast_build_free(build); + return NULL; +} + +/* Does any node in the schedule tree rooted at the current schedule node + * of "build" depend on outer schedule nodes? + */ +static int has_anchored_subtree(__isl_keep isl_ast_build *build) +{ + isl_schedule_node *node; + int dependent = 0; + + node = isl_ast_build_get_schedule_node(build); + dependent = isl_schedule_node_is_subtree_anchored(node); + isl_schedule_node_free(node); + + return dependent; +} + +/* Generate code for a single component. + * + * The component inverse schedule is specified as the "map" fields + * of the elements of "domain" indexed by the first "n" elements of "order". + * + * This function may modify the "set" fields of "domain". + * + * Before proceeding with the actual code generation for the component, + * we first check if there are any "shifted" strides, meaning that + * the schedule domains of the individual domains are all strided, + * but that they have different offsets, resulting in the union + * of schedule domains not being strided anymore. + * + * The simplest example is the schedule + * + * { A[i] -> [2i]: 0 <= i < 10; B[i] -> [2i+1] : 0 <= i < 10 } + * + * Both schedule domains are strided, but their union is not. + * This function detects such cases and then rewrites the schedule to + * + * { A[i] -> [2i, 0]: 0 <= i < 10; B[i] -> [2i, 1] : 0 <= i < 10 } + * + * In the new schedule, the schedule domains have the same offset (modulo + * the stride), ensuring that the union of schedule domains is also strided. + * + * + * If there is only a single domain in the component, then there is + * nothing to do. Similarly, if the current schedule dimension has + * a fixed value for almost all domains then there is nothing to be done. + * In particular, we need at least two domains where the current schedule + * dimension does not have a fixed value. + * Finally, in case of a schedule map input, + * if any of the options refer to the current schedule dimension, + * then we bail out as well. It would be possible to reformulate the options + * in terms of the new schedule domain, but that would introduce constraints + * that separate the domains in the options and that is something we would + * like to avoid. + * In the case of a schedule tree input, we bail out if any of + * the descendants of the current schedule node refer to outer + * schedule nodes in any way. + * + * + * To see if there is any shifted stride, we look at the differences + * between the values of the current dimension in pairs of domains + * for equal values of outer dimensions. These differences should be + * of the form + * + * m x + r + * + * with "m" the stride and "r" a constant. Note that we cannot perform + * this analysis on individual domains as the lower bound in each domain + * may depend on parameters or outer dimensions and so the current dimension + * itself may not have a fixed remainder on division by the stride. + * + * In particular, we compare the first domain that does not have an + * obviously fixed value for the current dimension to itself and all + * other domains and collect the offsets and the gcd of the strides. + * If the gcd becomes one, then we failed to find shifted strides. + * If the gcd is zero, then the differences were all fixed, meaning + * that some domains had non-obviously fixed values for the current dimension. + * If all the offsets are the same (for those domains that do not have + * an obviously fixed value for the current dimension), then we do not + * apply the transformation. + * If none of the domains were skipped, then there is nothing to do. + * If some of them were skipped, then if we apply separation, the schedule + * domain should get split in pieces with a (non-shifted) stride. + * + * Otherwise, we apply a shift to expose the stride in + * generate_shift_component. + */ +static __isl_give isl_ast_graft_list *generate_component( + struct isl_set_map_pair *domain, int *order, int n, + __isl_take isl_ast_build *build) +{ + int i, d; + isl_size depth; + isl_ctx *ctx; + isl_map *map; + isl_set *deltas; + isl_val *gcd = NULL; + isl_multi_val *mv; + int fixed, skip; + int base; + isl_ast_graft_list *list; + int res = 0; + + depth = isl_ast_build_get_depth(build); + if (depth < 0) + goto error; + + skip = n == 1; + if (skip >= 0 && !skip) + skip = at_most_one_non_fixed(domain, order, n, depth); + if (skip >= 0 && !skip) { + if (isl_ast_build_has_schedule_node(build)) + skip = has_anchored_subtree(build); + else + skip = isl_ast_build_options_involve_depth(build); + } + if (skip < 0) + goto error; + if (skip) + return generate_shifted_component_from_list(domain, + order, n, build); + + base = eliminate_non_fixed(domain, order, n, depth, build); + if (base < 0) + goto error; + + ctx = isl_ast_build_get_ctx(build); + + mv = isl_multi_val_zero(isl_space_set_alloc(ctx, 0, n)); + + fixed = 1; + for (i = 0; i < n; ++i) { + isl_val *r, *m; + + map = isl_map_from_domain_and_range( + isl_set_copy(domain[order[base]].set), + isl_set_copy(domain[order[i]].set)); + for (d = 0; d < depth; ++d) + map = isl_map_equate(map, isl_dim_in, d, + isl_dim_out, d); + deltas = isl_map_deltas(map); + res = isl_set_dim_residue_class_val(deltas, depth, &m, &r); + isl_set_free(deltas); + if (res < 0) + break; + + if (i == 0) + gcd = m; + else + gcd = isl_val_gcd(gcd, m); + if (isl_val_is_one(gcd)) { + isl_val_free(r); + break; + } + mv = isl_multi_val_set_val(mv, i, r); + + res = dim_is_fixed(domain[order[i]].set, depth); + if (res < 0) + break; + if (res) + continue; + + if (fixed && i > base) { + isl_val *a, *b; + a = isl_multi_val_get_val(mv, i); + b = isl_multi_val_get_val(mv, base); + if (isl_val_ne(a, b)) + fixed = 0; + isl_val_free(a); + isl_val_free(b); + } + } + + if (res < 0 || !gcd) { + isl_ast_build_free(build); + list = NULL; + } else if (i < n || fixed || isl_val_is_zero(gcd)) { + list = generate_shifted_component_from_list(domain, + order, n, build); + } else { + list = generate_shift_component(domain, order, n, gcd, mv, + build); + } + + isl_val_free(gcd); + isl_multi_val_free(mv); + + return list; +error: + isl_ast_build_free(build); + return NULL; +} + +/* Store both "map" itself and its domain in the + * structure pointed to by *next and advance to the next array element. + */ +static isl_stat extract_domain(__isl_take isl_map *map, void *user) +{ + struct isl_set_map_pair **next = user; + + (*next)->map = isl_map_copy(map); + (*next)->set = isl_map_domain(map); + (*next)++; + + return isl_stat_ok; +} + +static isl_bool after_in_tree(__isl_keep isl_union_map *umap, + __isl_keep isl_schedule_node *node); + +/* Is any domain element of "umap" scheduled after any of + * the corresponding image elements by the tree rooted at + * the child of "node"? + */ +static isl_bool after_in_child(__isl_keep isl_union_map *umap, + __isl_keep isl_schedule_node *node) +{ + isl_schedule_node *child; + isl_bool after; + + child = isl_schedule_node_get_child(node, 0); + after = after_in_tree(umap, child); + isl_schedule_node_free(child); + + return after; +} + +/* Is any domain element of "umap" scheduled after any of + * the corresponding image elements by the tree rooted at + * the band node "node"? + * + * We first check if any domain element is scheduled after any + * of the corresponding image elements by the band node itself. + * If not, we restrict "map" to those pairs of element that + * are scheduled together by the band node and continue with + * the child of the band node. + * If there are no such pairs then the map passed to after_in_child + * will be empty causing it to return 0. + */ +static isl_bool after_in_band(__isl_keep isl_union_map *umap, + __isl_keep isl_schedule_node *node) +{ + isl_multi_union_pw_aff *mupa; + isl_union_map *partial, *test, *gt, *universe, *umap1, *umap2; + isl_union_set *domain, *range; + isl_space *space; + isl_bool empty; + isl_bool after; + isl_size n; + + n = isl_schedule_node_band_n_member(node); + if (n < 0) + return isl_bool_error; + if (n == 0) + return after_in_child(umap, node); + + mupa = isl_schedule_node_band_get_partial_schedule(node); + space = isl_multi_union_pw_aff_get_space(mupa); + partial = isl_union_map_from_multi_union_pw_aff(mupa); + test = isl_union_map_copy(umap); + test = isl_union_map_apply_domain(test, isl_union_map_copy(partial)); + test = isl_union_map_apply_range(test, isl_union_map_copy(partial)); + gt = isl_union_map_from_map(isl_map_lex_gt(space)); + test = isl_union_map_intersect(test, gt); + empty = isl_union_map_is_empty(test); + isl_union_map_free(test); + + if (empty < 0 || !empty) { + isl_union_map_free(partial); + return isl_bool_not(empty); + } + + universe = isl_union_map_universe(isl_union_map_copy(umap)); + domain = isl_union_map_domain(isl_union_map_copy(universe)); + range = isl_union_map_range(universe); + umap1 = isl_union_map_copy(partial); + umap1 = isl_union_map_intersect_domain(umap1, domain); + umap2 = isl_union_map_intersect_domain(partial, range); + test = isl_union_map_apply_range(umap1, isl_union_map_reverse(umap2)); + test = isl_union_map_intersect(test, isl_union_map_copy(umap)); + after = after_in_child(test, node); + isl_union_map_free(test); + return after; +} + +/* Is any domain element of "umap" scheduled after any of + * the corresponding image elements by the tree rooted at + * the context node "node"? + * + * The context constraints apply to the schedule domain, + * so we cannot apply them directly to "umap", which contains + * pairs of statement instances. Instead, we add them + * to the range of the prefix schedule for both domain and + * range of "umap". + */ +static isl_bool after_in_context(__isl_keep isl_union_map *umap, + __isl_keep isl_schedule_node *node) +{ + isl_union_map *prefix, *universe, *umap1, *umap2; + isl_union_set *domain, *range; + isl_set *context; + isl_bool after; + + umap = isl_union_map_copy(umap); + context = isl_schedule_node_context_get_context(node); + prefix = isl_schedule_node_get_prefix_schedule_union_map(node); + universe = isl_union_map_universe(isl_union_map_copy(umap)); + domain = isl_union_map_domain(isl_union_map_copy(universe)); + range = isl_union_map_range(universe); + umap1 = isl_union_map_copy(prefix); + umap1 = isl_union_map_intersect_domain(umap1, domain); + umap2 = isl_union_map_intersect_domain(prefix, range); + umap1 = isl_union_map_intersect_range(umap1, + isl_union_set_from_set(context)); + umap1 = isl_union_map_apply_range(umap1, isl_union_map_reverse(umap2)); + umap = isl_union_map_intersect(umap, umap1); + + after = after_in_child(umap, node); + + isl_union_map_free(umap); + + return after; +} + +/* Is any domain element of "umap" scheduled after any of + * the corresponding image elements by the tree rooted at + * the expansion node "node"? + * + * We apply the expansion to domain and range of "umap" and + * continue with its child. + */ +static isl_bool after_in_expansion(__isl_keep isl_union_map *umap, + __isl_keep isl_schedule_node *node) +{ + isl_union_map *expansion; + isl_bool after; + + expansion = isl_schedule_node_expansion_get_expansion(node); + umap = isl_union_map_copy(umap); + umap = isl_union_map_apply_domain(umap, isl_union_map_copy(expansion)); + umap = isl_union_map_apply_range(umap, expansion); + + after = after_in_child(umap, node); + + isl_union_map_free(umap); + + return after; +} + +/* Is any domain element of "umap" scheduled after any of + * the corresponding image elements by the tree rooted at + * the extension node "node"? + * + * Since the extension node may add statement instances before or + * after the pairs of statement instances in "umap", we return isl_bool_true + * to ensure that these pairs are not broken up. + */ +static isl_bool after_in_extension(__isl_keep isl_union_map *umap, + __isl_keep isl_schedule_node *node) +{ + return isl_bool_true; +} + +/* Is any domain element of "umap" scheduled after any of + * the corresponding image elements by the tree rooted at + * the filter node "node"? + * + * We intersect domain and range of "umap" with the filter and + * continue with its child. + */ +static isl_bool after_in_filter(__isl_keep isl_union_map *umap, + __isl_keep isl_schedule_node *node) +{ + isl_union_set *filter; + isl_bool after; + + umap = isl_union_map_copy(umap); + filter = isl_schedule_node_filter_get_filter(node); + umap = isl_union_map_intersect_domain(umap, isl_union_set_copy(filter)); + umap = isl_union_map_intersect_range(umap, filter); + + after = after_in_child(umap, node); + + isl_union_map_free(umap); + + return after; +} + +/* Is any domain element of "umap" scheduled after any of + * the corresponding image elements by the tree rooted at + * the set node "node"? + * + * This is only the case if this condition holds in any + * of the (filter) children of the set node. + * In particular, if the domain and the range of "umap" + * are contained in different children, then the condition + * does not hold. + */ +static isl_bool after_in_set(__isl_keep isl_union_map *umap, + __isl_keep isl_schedule_node *node) +{ + int i; + isl_size n; + + n = isl_schedule_node_n_children(node); + if (n < 0) + return isl_bool_error; + for (i = 0; i < n; ++i) { + isl_schedule_node *child; + isl_bool after; + + child = isl_schedule_node_get_child(node, i); + after = after_in_tree(umap, child); + isl_schedule_node_free(child); + + if (after < 0 || after) + return after; + } + + return isl_bool_false; +} + +/* Return the filter of child "i" of "node". + */ +static __isl_give isl_union_set *child_filter( + __isl_keep isl_schedule_node *node, int i) +{ + isl_schedule_node *child; + isl_union_set *filter; + + child = isl_schedule_node_get_child(node, i); + filter = isl_schedule_node_filter_get_filter(child); + isl_schedule_node_free(child); + + return filter; +} + +/* Is any domain element of "umap" scheduled after any of + * the corresponding image elements by the tree rooted at + * the sequence node "node"? + * + * This happens in particular if any domain element is + * contained in a later child than one containing a range element or + * if the condition holds within a given child in the sequence. + * The later part of the condition is checked by after_in_set. + */ +static isl_bool after_in_sequence(__isl_keep isl_union_map *umap, + __isl_keep isl_schedule_node *node) +{ + int i, j; + isl_size n; + isl_union_map *umap_i; + isl_bool empty; + isl_bool after = isl_bool_false; + + n = isl_schedule_node_n_children(node); + if (n < 0) + return isl_bool_error; + for (i = 1; i < n; ++i) { + isl_union_set *filter_i; + + umap_i = isl_union_map_copy(umap); + filter_i = child_filter(node, i); + umap_i = isl_union_map_intersect_domain(umap_i, filter_i); + empty = isl_union_map_is_empty(umap_i); + if (empty < 0) + goto error; + if (empty) { + isl_union_map_free(umap_i); + continue; + } + + for (j = 0; j < i; ++j) { + isl_union_set *filter_j; + isl_union_map *umap_ij; + + umap_ij = isl_union_map_copy(umap_i); + filter_j = child_filter(node, j); + umap_ij = isl_union_map_intersect_range(umap_ij, + filter_j); + empty = isl_union_map_is_empty(umap_ij); + isl_union_map_free(umap_ij); + + if (empty < 0) + goto error; + if (!empty) + after = isl_bool_true; + if (after) + break; + } + + isl_union_map_free(umap_i); + if (after) + break; + } + + if (after < 0 || after) + return after; + + return after_in_set(umap, node); +error: + isl_union_map_free(umap_i); + return isl_bool_error; +} + +/* Is any domain element of "umap" scheduled after any of + * the corresponding image elements by the tree rooted at "node"? + * + * If "umap" is empty, then clearly there is no such element. + * Otherwise, consider the different types of nodes separately. + */ +static isl_bool after_in_tree(__isl_keep isl_union_map *umap, + __isl_keep isl_schedule_node *node) +{ + isl_bool empty; + enum isl_schedule_node_type type; + + empty = isl_union_map_is_empty(umap); + if (empty < 0) + return isl_bool_error; + if (empty) + return isl_bool_false; + if (!node) + return isl_bool_error; + + type = isl_schedule_node_get_type(node); + switch (type) { + case isl_schedule_node_error: + return isl_bool_error; + case isl_schedule_node_leaf: + return isl_bool_false; + case isl_schedule_node_band: + return after_in_band(umap, node); + case isl_schedule_node_domain: + isl_die(isl_schedule_node_get_ctx(node), isl_error_internal, + "unexpected internal domain node", + return isl_bool_error); + case isl_schedule_node_context: + return after_in_context(umap, node); + case isl_schedule_node_expansion: + return after_in_expansion(umap, node); + case isl_schedule_node_extension: + return after_in_extension(umap, node); + case isl_schedule_node_filter: + return after_in_filter(umap, node); + case isl_schedule_node_guard: + case isl_schedule_node_mark: + return after_in_child(umap, node); + case isl_schedule_node_set: + return after_in_set(umap, node); + case isl_schedule_node_sequence: + return after_in_sequence(umap, node); + } + + return isl_bool_true; +} + +/* Is any domain element of "map1" scheduled after any domain + * element of "map2" by the subtree underneath the current band node, + * while at the same time being scheduled together by the current + * band node, i.e., by "map1" and "map2? + * + * If the child of the current band node is a leaf, then + * no element can be scheduled after any other element. + * + * Otherwise, we construct a relation between domain elements + * of "map1" and domain elements of "map2" that are scheduled + * together and then check if the subtree underneath the current + * band node determines their relative order. + */ +static isl_bool after_in_subtree(__isl_keep isl_ast_build *build, + __isl_keep isl_map *map1, __isl_keep isl_map *map2) +{ + isl_schedule_node *node; + isl_map *map; + isl_union_map *umap; + isl_bool after; + + node = isl_ast_build_get_schedule_node(build); + if (!node) + return isl_bool_error; + node = isl_schedule_node_child(node, 0); + if (isl_schedule_node_get_type(node) == isl_schedule_node_leaf) { + isl_schedule_node_free(node); + return isl_bool_false; + } + map = isl_map_copy(map2); + map = isl_map_apply_domain(map, isl_map_copy(map1)); + umap = isl_union_map_from_map(map); + after = after_in_tree(umap, node); + isl_union_map_free(umap); + isl_schedule_node_free(node); + return after; +} + +/* Internal data for any_scheduled_after. + * + * "build" is the build in which the AST is constructed. + * "depth" is the number of loops that have already been generated + * "group_coscheduled" is a local copy of options->ast_build_group_coscheduled + * "domain" is an array of set-map pairs corresponding to the different + * iteration domains. The set is the schedule domain, i.e., the domain + * of the inverse schedule, while the map is the inverse schedule itself. + */ +struct isl_any_scheduled_after_data { + isl_ast_build *build; + int depth; + int group_coscheduled; + struct isl_set_map_pair *domain; +}; + +/* Is any element of domain "i" scheduled after any element of domain "j" + * (for a common iteration of the first data->depth loops)? + * + * data->domain[i].set contains the domain of the inverse schedule + * for domain "i", i.e., elements in the schedule domain. + * + * If we are inside a band of a schedule tree and there is a pair + * of elements in the two domains that is schedule together by + * the current band, then we check if any element of "i" may be schedule + * after element of "j" by the descendants of the band node. + * + * If data->group_coscheduled is set, then we also return 1 if there + * is any pair of elements in the two domains that are scheduled together. + */ +static isl_bool any_scheduled_after(int i, int j, void *user) +{ + struct isl_any_scheduled_after_data *data = user; + isl_size dim = isl_set_dim(data->domain[i].set, isl_dim_set); + int pos; + + if (dim < 0) + return isl_bool_error; + + for (pos = data->depth; pos < dim; ++pos) { + int follows; + + follows = isl_set_follows_at(data->domain[i].set, + data->domain[j].set, pos); + + if (follows < -1) + return isl_bool_error; + if (follows > 0) + return isl_bool_true; + if (follows < 0) + return isl_bool_false; + } + + if (isl_ast_build_has_schedule_node(data->build)) { + isl_bool after; + + after = after_in_subtree(data->build, data->domain[i].map, + data->domain[j].map); + if (after < 0 || after) + return after; + } + + return isl_bool_ok(data->group_coscheduled); +} + +/* Look for independent components at the current depth and generate code + * for each component separately. The resulting lists of grafts are + * merged in an attempt to combine grafts with identical guards. + * + * Code for two domains can be generated separately if all the elements + * of one domain are scheduled before (or together with) all the elements + * of the other domain. We therefore consider the graph with as nodes + * the domains and an edge between two nodes if any element of the first + * node is scheduled after any element of the second node. + * If the ast_build_group_coscheduled is set, then we also add an edge if + * there is any pair of elements in the two domains that are scheduled + * together. + * Code is then generated (by generate_component) + * for each of the strongly connected components in this graph + * in their topological order. + * + * Since the test is performed on the domain of the inverse schedules of + * the different domains, we precompute these domains and store + * them in data.domain. + */ +static __isl_give isl_ast_graft_list *generate_components( + __isl_take isl_union_map *executed, __isl_take isl_ast_build *build) +{ + int i; + isl_ctx *ctx = isl_ast_build_get_ctx(build); + isl_size n = isl_union_map_n_map(executed); + isl_size depth; + struct isl_any_scheduled_after_data data; + struct isl_set_map_pair *next; + struct isl_tarjan_graph *g = NULL; + isl_ast_graft_list *list = NULL; + int n_domain = 0; + + data.domain = NULL; + if (n < 0) + goto error; + data.domain = isl_calloc_array(ctx, struct isl_set_map_pair, n); + if (!data.domain) + goto error; + n_domain = n; + + next = data.domain; + if (isl_union_map_foreach_map(executed, &extract_domain, &next) < 0) + goto error; + + depth = isl_ast_build_get_depth(build); + if (depth < 0) + goto error; + data.build = build; + data.depth = depth; + data.group_coscheduled = isl_options_get_ast_build_group_coscheduled(ctx); + g = isl_tarjan_graph_init(ctx, n, &any_scheduled_after, &data); + if (!g) + goto error; + + list = isl_ast_graft_list_alloc(ctx, 0); + + i = 0; + while (list && n) { + isl_ast_graft_list *list_c; + int first = i; + + if (g->order[i] == -1) + isl_die(ctx, isl_error_internal, "cannot happen", + goto error); + ++i; --n; + while (g->order[i] != -1) { + ++i; --n; + } + + list_c = generate_component(data.domain, + g->order + first, i - first, + isl_ast_build_copy(build)); + list = isl_ast_graft_list_merge(list, list_c, build); + + ++i; + } + + if (0) +error: list = isl_ast_graft_list_free(list); + isl_tarjan_graph_free(g); + for (i = 0; i < n_domain; ++i) { + isl_map_free(data.domain[i].map); + isl_set_free(data.domain[i].set); + } + free(data.domain); + isl_union_map_free(executed); + isl_ast_build_free(build); + + return list; +} + +/* Generate code for the next level (and all inner levels). + * + * If "executed" is empty, i.e., no code needs to be generated, + * then we return an empty list. + * + * If we have already generated code for all loop levels, then we pass + * control to generate_inner_level. + * + * If "executed" lives in a single space, i.e., if code needs to be + * generated for a single domain, then there can only be a single + * component and we go directly to generate_shifted_component. + * Otherwise, we call generate_components to detect the components + * and to call generate_component on each of them separately. + */ +static __isl_give isl_ast_graft_list *generate_next_level( + __isl_take isl_union_map *executed, __isl_take isl_ast_build *build) +{ + isl_size depth; + isl_size dim; + isl_size n; + + if (!build || !executed) + goto error; + + if (isl_union_map_is_empty(executed)) { + isl_ctx *ctx = isl_ast_build_get_ctx(build); + isl_union_map_free(executed); + isl_ast_build_free(build); + return isl_ast_graft_list_alloc(ctx, 0); + } + + depth = isl_ast_build_get_depth(build); + dim = isl_ast_build_dim(build, isl_dim_set); + if (depth < 0 || dim < 0) + goto error; + if (depth >= dim) + return generate_inner_level(executed, build); + + n = isl_union_map_n_map(executed); + if (n < 0) + goto error; + if (n == 1) + return generate_shifted_component(executed, build); + + return generate_components(executed, build); +error: + isl_union_map_free(executed); + isl_ast_build_free(build); + return NULL; +} + +/* Internal data structure used by isl_ast_build_node_from_schedule_map. + * internal, executed and build are the inputs to generate_code. + * list collects the output. + */ +struct isl_generate_code_data { + int internal; + isl_union_map *executed; + isl_ast_build *build; + + isl_ast_graft_list *list; +}; + +/* Given an inverse schedule in terms of the external build schedule, i.e., + * + * [E -> S] -> D + * + * with E the external build schedule and S the additional schedule "space", + * reformulate the inverse schedule in terms of the internal schedule domain, + * i.e., return + * + * [I -> S] -> D + * + * We first obtain a mapping + * + * I -> E + * + * take the inverse and the product with S -> S, resulting in + * + * [I -> S] -> [E -> S] + * + * Applying the map to the input produces the desired result. + */ +static __isl_give isl_union_map *internal_executed( + __isl_take isl_union_map *executed, __isl_keep isl_space *space, + __isl_keep isl_ast_build *build) +{ + isl_map *id, *proj; + + proj = isl_ast_build_get_schedule_map(build); + proj = isl_map_reverse(proj); + space = isl_space_map_from_set(isl_space_copy(space)); + id = isl_map_identity(space); + proj = isl_map_product(proj, id); + executed = isl_union_map_apply_domain(executed, + isl_union_map_from_map(proj)); + return executed; +} + +/* Generate an AST that visits the elements in the range of data->executed + * in the relative order specified by the corresponding domain element(s) + * for those domain elements that belong to "set". + * Add the result to data->list. + * + * The caller ensures that "set" is a universe domain. + * "space" is the space of the additional part of the schedule. + * It is equal to the space of "set" if build->domain is parametric. + * Otherwise, it is equal to the range of the wrapped space of "set". + * + * If the build space is not parametric and + * if isl_ast_build_node_from_schedule_map + * was called from an outside user (data->internal not set), then + * the (inverse) schedule refers to the external build domain and needs to + * be transformed to refer to the internal build domain. + * + * If the build space is parametric, then we add some of the parameter + * constraints to the executed relation. Adding these constraints + * allows for an earlier detection of conflicts in some cases. + * However, we do not want to divide the executed relation into + * more disjuncts than necessary. We therefore approximate + * the constraints on the parameters by a single disjunct set. + * + * The build is extended to include the additional part of the schedule. + * If the original build space was not parametric, then the options + * in data->build refer only to the additional part of the schedule + * and they need to be adjusted to refer to the complete AST build + * domain. + * + * After having adjusted inverse schedule and build, we start generating + * code with the outer loop of the current code generation + * in generate_next_level. + * + * If the original build space was not parametric, we undo the embedding + * on the resulting isl_ast_node_list so that it can be used within + * the outer AST build. + */ +static isl_stat generate_code_in_space(struct isl_generate_code_data *data, + __isl_take isl_set *set, __isl_take isl_space *space) +{ + isl_union_map *executed; + isl_ast_build *build; + isl_ast_graft_list *list; + int embed; + + executed = isl_union_map_copy(data->executed); + executed = isl_union_map_intersect_domain(executed, + isl_union_set_from_set(set)); + + embed = !isl_set_is_params(data->build->domain); + if (embed && !data->internal) + executed = internal_executed(executed, space, data->build); + if (!embed) { + isl_set *domain; + domain = isl_ast_build_get_domain(data->build); + domain = isl_set_from_basic_set(isl_set_simple_hull(domain)); + executed = isl_union_map_intersect_params(executed, domain); + } + + build = isl_ast_build_copy(data->build); + build = isl_ast_build_product(build, space); + + list = generate_next_level(executed, build); + + list = isl_ast_graft_list_unembed(list, embed); + + data->list = isl_ast_graft_list_concat(data->list, list); + + return isl_stat_ok; +} + +/* Generate an AST that visits the elements in the range of data->executed + * in the relative order specified by the corresponding domain element(s) + * for those domain elements that belong to "set". + * Add the result to data->list. + * + * The caller ensures that "set" is a universe domain. + * + * If the build space S is not parametric, then the space of "set" + * need to be a wrapped relation with S as domain. That is, it needs + * to be of the form + * + * [S -> T] + * + * Check this property and pass control to generate_code_in_space + * passing along T. + * If the build space is not parametric, then T is the space of "set". + */ +static isl_stat generate_code_set(__isl_take isl_set *set, void *user) +{ + struct isl_generate_code_data *data = user; + isl_space *space, *build_space; + int is_domain; + + space = isl_set_get_space(set); + + if (isl_set_is_params(data->build->domain)) + return generate_code_in_space(data, set, space); + + build_space = isl_ast_build_get_space(data->build, data->internal); + space = isl_space_unwrap(space); + is_domain = isl_space_is_domain(build_space, space); + isl_space_free(build_space); + space = isl_space_range(space); + + if (is_domain < 0) + goto error; + if (!is_domain) + isl_die(isl_set_get_ctx(set), isl_error_invalid, + "invalid nested schedule space", goto error); + + return generate_code_in_space(data, set, space); +error: + isl_set_free(set); + isl_space_free(space); + return isl_stat_error; +} + +/* Generate an AST that visits the elements in the range of "executed" + * in the relative order specified by the corresponding domain element(s). + * + * "build" is an isl_ast_build that has either been constructed by + * isl_ast_build_from_context or passed to a callback set by + * isl_ast_build_set_create_leaf. + * In the first case, the space of the isl_ast_build is typically + * a parametric space, although this is currently not enforced. + * In the second case, the space is never a parametric space. + * If the space S is not parametric, then the domain space(s) of "executed" + * need to be wrapped relations with S as domain. + * + * If the domain of "executed" consists of several spaces, then an AST + * is generated for each of them (in arbitrary order) and the results + * are concatenated. + * + * If "internal" is set, then the domain "S" above refers to the internal + * schedule domain representation. Otherwise, it refers to the external + * representation, as returned by isl_ast_build_get_schedule_space. + * + * We essentially run over all the spaces in the domain of "executed" + * and call generate_code_set on each of them. + */ +static __isl_give isl_ast_graft_list *generate_code( + __isl_take isl_union_map *executed, __isl_take isl_ast_build *build, + int internal) +{ + isl_ctx *ctx; + struct isl_generate_code_data data = { 0 }; + isl_space *space; + isl_union_set *schedule_domain; + isl_union_map *universe; + + if (!build) + goto error; + space = isl_ast_build_get_space(build, 1); + space = isl_space_align_params(space, + isl_union_map_get_space(executed)); + space = isl_space_align_params(space, + isl_union_map_get_space(build->options)); + build = isl_ast_build_align_params(build, isl_space_copy(space)); + executed = isl_union_map_align_params(executed, space); + if (!executed || !build) + goto error; + + ctx = isl_ast_build_get_ctx(build); + + data.internal = internal; + data.executed = executed; + data.build = build; + data.list = isl_ast_graft_list_alloc(ctx, 0); + + universe = isl_union_map_universe(isl_union_map_copy(executed)); + schedule_domain = isl_union_map_domain(universe); + if (isl_union_set_foreach_set(schedule_domain, &generate_code_set, + &data) < 0) + data.list = isl_ast_graft_list_free(data.list); + + isl_union_set_free(schedule_domain); + isl_union_map_free(executed); + + isl_ast_build_free(build); + return data.list; +error: + isl_union_map_free(executed); + isl_ast_build_free(build); + return NULL; +} + +/* Generate an AST that visits the elements in the domain of "schedule" + * in the relative order specified by the corresponding image element(s). + * + * "build" is an isl_ast_build that has either been constructed by + * isl_ast_build_from_context or passed to a callback set by + * isl_ast_build_set_create_leaf. + * In the first case, the space of the isl_ast_build is typically + * a parametric space, although this is currently not enforced. + * In the second case, the space is never a parametric space. + * If the space S is not parametric, then the range space(s) of "schedule" + * need to be wrapped relations with S as domain. + * + * If the range of "schedule" consists of several spaces, then an AST + * is generated for each of them (in arbitrary order) and the results + * are concatenated. + * + * We first initialize the local copies of the relevant options. + * We do this here rather than when the isl_ast_build is created + * because the options may have changed between the construction + * of the isl_ast_build and the call to isl_generate_code. + * + * The main computation is performed on an inverse schedule (with + * the schedule domain in the domain and the elements to be executed + * in the range) called "executed". + */ +__isl_give isl_ast_node *isl_ast_build_node_from_schedule_map( + __isl_keep isl_ast_build *build, __isl_take isl_union_map *schedule) +{ + isl_ast_graft_list *list; + isl_ast_node *node; + isl_union_map *executed; + + build = isl_ast_build_copy(build); + build = isl_ast_build_set_single_valued(build, 0); + schedule = isl_union_map_coalesce(schedule); + schedule = isl_union_map_remove_redundancies(schedule); + executed = isl_union_map_reverse(schedule); + list = generate_code(executed, isl_ast_build_copy(build), 0); + node = isl_ast_node_from_graft_list(list, build); + isl_ast_build_free(build); + + return node; +} + +/* The old name for isl_ast_build_node_from_schedule_map. + * It is being kept for backward compatibility, but + * it will be removed in the future. + */ +__isl_give isl_ast_node *isl_ast_build_ast_from_schedule( + __isl_keep isl_ast_build *build, __isl_take isl_union_map *schedule) +{ + return isl_ast_build_node_from_schedule_map(build, schedule); +} + +/* Generate an AST that visits the elements in the domain of "executed" + * in the relative order specified by the leaf node "node". + * + * The relation "executed" maps the outer generated loop iterators + * to the domain elements executed by those iterations. + * + * Simply pass control to generate_inner_level. + * Note that the current build does not refer to any band node, so + * that generate_inner_level will not try to visit the child of + * the leaf node. + * + * If multiple statement instances reach a leaf, + * then they can be executed in any order. + * Group the list of grafts based on shared guards + * such that identical guards are only generated once + * when the list is eventually passed on to isl_ast_graft_list_fuse. + */ +static __isl_give isl_ast_graft_list *build_ast_from_leaf( + __isl_take isl_ast_build *build, __isl_take isl_schedule_node *node, + __isl_take isl_union_map *executed) +{ + isl_ast_graft_list *list; + + isl_schedule_node_free(node); + list = generate_inner_level(executed, isl_ast_build_copy(build)); + list = isl_ast_graft_list_group_on_guard(list, build); + isl_ast_build_free(build); + + return list; +} + +/* Check that the band partial schedule "partial" does not filter out + * any statement instances, as specified by the range of "executed". + */ +static isl_stat check_band_schedule_total_on_instances( + __isl_keep isl_multi_union_pw_aff *partial, + __isl_keep isl_union_map *executed) +{ + isl_bool subset; + isl_union_set *domain, *instances; + + instances = isl_union_map_range(isl_union_map_copy(executed)); + partial = isl_multi_union_pw_aff_copy(partial); + domain = isl_multi_union_pw_aff_domain(partial); + subset = isl_union_set_is_subset(instances, domain); + isl_union_set_free(domain); + isl_union_set_free(instances); + + if (subset < 0) + return isl_stat_error; + if (!subset) + isl_die(isl_union_map_get_ctx(executed), isl_error_invalid, + "band node is not allowed to drop statement instances", + return isl_stat_error); + return isl_stat_ok; +} + +/* Generate an AST that visits the elements in the domain of "executed" + * in the relative order specified by the band node "node" and its descendants. + * + * The relation "executed" maps the outer generated loop iterators + * to the domain elements executed by those iterations. + * + * If the band is empty, we continue with its descendants. + * Otherwise, we extend the build and the inverse schedule with + * the additional space/partial schedule and continue generating + * an AST in generate_next_level. + * As soon as we have extended the inverse schedule with the additional + * partial schedule, we look for equalities that may exists between + * the old and the new part. + */ +static __isl_give isl_ast_graft_list *build_ast_from_band( + __isl_take isl_ast_build *build, __isl_take isl_schedule_node *node, + __isl_take isl_union_map *executed) +{ + isl_space *space; + isl_multi_union_pw_aff *extra; + isl_union_map *extra_umap; + isl_ast_graft_list *list; + isl_size n1, n2; + isl_size n; + + n = isl_schedule_node_band_n_member(node); + if (!build || n < 0 || !executed) + goto error; + + if (n == 0) + return build_ast_from_child(build, node, executed); + + extra = isl_schedule_node_band_get_partial_schedule(node); + extra = isl_multi_union_pw_aff_align_params(extra, + isl_ast_build_get_space(build, 1)); + space = isl_multi_union_pw_aff_get_space(extra); + + if (check_band_schedule_total_on_instances(extra, executed) < 0) + executed = isl_union_map_free(executed); + + extra_umap = isl_union_map_from_multi_union_pw_aff(extra); + extra_umap = isl_union_map_reverse(extra_umap); + + executed = isl_union_map_domain_product(executed, extra_umap); + executed = isl_union_map_detect_equalities(executed); + + n1 = isl_ast_build_dim(build, isl_dim_param); + build = isl_ast_build_product(build, space); + n2 = isl_ast_build_dim(build, isl_dim_param); + if (n1 < 0 || n2 < 0) + build = isl_ast_build_free(build); + else if (n2 > n1) + isl_die(isl_ast_build_get_ctx(build), isl_error_invalid, + "band node is not allowed to introduce new parameters", + build = isl_ast_build_free(build)); + build = isl_ast_build_set_schedule_node(build, node); + + list = generate_next_level(executed, build); + + list = isl_ast_graft_list_unembed(list, 1); + + return list; +error: + isl_schedule_node_free(node); + isl_union_map_free(executed); + isl_ast_build_free(build); + return NULL; +} + +/* Hoist a list of grafts (in practice containing a single graft) + * from "sub_build" (which includes extra context information) + * to "build". + * + * In particular, project out all additional parameters introduced + * by the context node from the enforced constraints and the guard + * of the single graft. + */ +static __isl_give isl_ast_graft_list *hoist_out_of_context( + __isl_take isl_ast_graft_list *list, __isl_keep isl_ast_build *build, + __isl_keep isl_ast_build *sub_build) +{ + isl_ast_graft *graft; + isl_basic_set *enforced; + isl_set *guard; + isl_size n_param, extra_param; + + n_param = isl_ast_build_dim(build, isl_dim_param); + extra_param = isl_ast_build_dim(sub_build, isl_dim_param); + if (n_param < 0 || extra_param < 0) + return isl_ast_graft_list_free(list); + + if (extra_param == n_param) + return list; + + extra_param -= n_param; + enforced = isl_ast_graft_list_extract_shared_enforced(list, sub_build); + enforced = isl_basic_set_project_out(enforced, isl_dim_param, + n_param, extra_param); + enforced = isl_basic_set_remove_unknown_divs(enforced); + guard = isl_ast_graft_list_extract_hoistable_guard(list, sub_build); + guard = isl_set_remove_divs_involving_dims(guard, isl_dim_param, + n_param, extra_param); + guard = isl_set_project_out(guard, isl_dim_param, n_param, extra_param); + guard = isl_set_compute_divs(guard); + graft = isl_ast_graft_alloc_from_children(list, guard, enforced, + build, sub_build); + list = isl_ast_graft_list_from_ast_graft(graft); + + return list; +} + +/* Generate an AST that visits the elements in the domain of "executed" + * in the relative order specified by the context node "node" + * and its descendants. + * + * The relation "executed" maps the outer generated loop iterators + * to the domain elements executed by those iterations. + * + * The context node may introduce additional parameters as well as + * 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) + * to the domain of "executed". Since the context constraints + * are specified in terms of the input schedule, we first need + * to map them to the internal schedule domain. + * + * After constructing the AST from the descendants of "node", + * we combine the list of grafts into a single graft within + * the new build, in order to be able to exploit the additional + * context constraints during this combination. + * + * Additionally, if the current node is the outermost node in + * the schedule tree (apart from the root domain node), we generate + * all pending guards, again to be able to exploit the additional + * context constraints. We currently do not do this for internal + * context nodes since we may still want to hoist conditions + * to outer AST nodes. + * + * If the context node introduced any new parameters, then they + * are removed from the set of enforced constraints and guard + * in hoist_out_of_context. + */ +static __isl_give isl_ast_graft_list *build_ast_from_context( + __isl_take isl_ast_build *build, __isl_take isl_schedule_node *node, + __isl_take isl_union_map *executed) +{ + isl_set *context; + isl_space *space; + isl_multi_aff *internal2input; + isl_ast_build *sub_build; + isl_ast_graft_list *list; + isl_size n; + isl_size depth; + + depth = isl_schedule_node_get_tree_depth(node); + if (depth < 0) + build = isl_ast_build_free(build); + space = isl_ast_build_get_space(build, 1); + context = isl_schedule_node_context_get_context(node); + context = isl_set_align_params(context, space); + sub_build = isl_ast_build_copy(build); + space = isl_set_get_space(context); + sub_build = isl_ast_build_align_params(sub_build, space); + internal2input = isl_ast_build_get_internal2input(sub_build); + context = isl_set_preimage_multi_aff(context, internal2input); + sub_build = isl_ast_build_restrict_generated(sub_build, + isl_set_copy(context)); + context = isl_set_from_basic_set(isl_set_simple_hull(context)); + executed = isl_union_map_intersect_domain(executed, + isl_union_set_from_set(context)); + + list = build_ast_from_child(isl_ast_build_copy(sub_build), + node, executed); + n = isl_ast_graft_list_n_ast_graft(list); + if (n < 0) + list = isl_ast_graft_list_free(list); + + list = isl_ast_graft_list_fuse(list, sub_build); + if (depth == 1) + list = isl_ast_graft_list_insert_pending_guard_nodes(list, + sub_build); + if (n >= 1) + list = hoist_out_of_context(list, build, sub_build); + + isl_ast_build_free(build); + isl_ast_build_free(sub_build); + + return list; +} + +/* Generate an AST that visits the elements in the domain of "executed" + * in the relative order specified by the expansion node "node" and + * its descendants. + * + * The relation "executed" maps the outer generated loop iterators + * to the domain elements executed by those iterations. + * + * We expand the domain elements by the expansion and + * continue with the descendants of the node. + */ +static __isl_give isl_ast_graft_list *build_ast_from_expansion( + __isl_take isl_ast_build *build, __isl_take isl_schedule_node *node, + __isl_take isl_union_map *executed) +{ + isl_union_map *expansion; + isl_size n1, n2; + + expansion = isl_schedule_node_expansion_get_expansion(node); + expansion = isl_union_map_align_params(expansion, + isl_union_map_get_space(executed)); + + n1 = isl_union_map_dim(executed, isl_dim_param); + executed = isl_union_map_apply_range(executed, expansion); + n2 = isl_union_map_dim(executed, isl_dim_param); + if (n1 < 0 || n2 < 0) + goto error; + if (n2 > n1) + isl_die(isl_ast_build_get_ctx(build), isl_error_invalid, + "expansion node is not allowed to introduce " + "new parameters", goto error); + + return build_ast_from_child(build, node, executed); +error: + isl_ast_build_free(build); + isl_schedule_node_free(node); + isl_union_map_free(executed); + return NULL; +} + +/* Generate an AST that visits the elements in the domain of "executed" + * in the relative order specified by the extension node "node" and + * its descendants. + * + * The relation "executed" maps the outer generated loop iterators + * to the domain elements executed by those iterations. + * + * Extend the inverse schedule with the extension applied to current + * set of generated constraints. Since the extension if formulated + * in terms of the input schedule, it first needs to be transformed + * to refer to the internal schedule. + */ +static __isl_give isl_ast_graft_list *build_ast_from_extension( + __isl_take isl_ast_build *build, __isl_take isl_schedule_node *node, + __isl_take isl_union_map *executed) +{ + isl_union_set *schedule_domain; + isl_union_map *extension; + isl_set *set; + + set = isl_ast_build_get_generated(build); + set = isl_set_from_basic_set(isl_set_simple_hull(set)); + schedule_domain = isl_union_set_from_set(set); + + extension = isl_schedule_node_extension_get_extension(node); + + extension = isl_union_map_preimage_domain_multi_aff(extension, + isl_multi_aff_copy(build->internal2input)); + extension = isl_union_map_intersect_domain(extension, schedule_domain); + extension = isl_ast_build_substitute_values_union_map_domain(build, + extension); + executed = isl_union_map_union(executed, extension); + + return build_ast_from_child(build, node, executed); +} + +/* Generate an AST that visits the elements in the domain of "executed" + * in the relative order specified by the filter node "node" and + * its descendants. + * + * The relation "executed" maps the outer generated loop iterators + * to the domain elements executed by those iterations. + * + * We simply intersect the iteration domain (i.e., the range of "executed") + * with the filter and continue with the descendants of the node, + * unless the resulting inverse schedule is empty, in which + * case we return an empty list. + * + * If the result of the intersection is equal to the original "executed" + * relation, then keep the original representation since the intersection + * may have unnecessarily broken up the relation into a greater number + * of disjuncts. + */ +static __isl_give isl_ast_graft_list *build_ast_from_filter( + __isl_take isl_ast_build *build, __isl_take isl_schedule_node *node, + __isl_take isl_union_map *executed) +{ + isl_ctx *ctx; + isl_union_set *filter; + isl_union_map *orig; + isl_ast_graft_list *list; + int empty; + isl_bool unchanged; + isl_size n1, n2; + + orig = isl_union_map_copy(executed); + if (!build || !node || !executed) + goto error; + + filter = isl_schedule_node_filter_get_filter(node); + filter = isl_union_set_align_params(filter, + isl_union_map_get_space(executed)); + n1 = isl_union_map_dim(executed, isl_dim_param); + executed = isl_union_map_intersect_range(executed, filter); + n2 = isl_union_map_dim(executed, isl_dim_param); + if (n1 < 0 || n2 < 0) + goto error; + if (n2 > n1) + isl_die(isl_ast_build_get_ctx(build), isl_error_invalid, + "filter node is not allowed to introduce " + "new parameters", goto error); + + unchanged = isl_union_map_is_subset(orig, executed); + empty = isl_union_map_is_empty(executed); + if (unchanged < 0 || empty < 0) + goto error; + if (unchanged) { + isl_union_map_free(executed); + return build_ast_from_child(build, node, orig); + } + isl_union_map_free(orig); + if (!empty) + return build_ast_from_child(build, node, executed); + + ctx = isl_ast_build_get_ctx(build); + list = isl_ast_graft_list_alloc(ctx, 0); + isl_ast_build_free(build); + isl_schedule_node_free(node); + isl_union_map_free(executed); + return list; +error: + isl_ast_build_free(build); + isl_schedule_node_free(node); + isl_union_map_free(executed); + isl_union_map_free(orig); + return NULL; +} + +/* Generate an AST that visits the elements in the domain of "executed" + * in the relative order specified by the guard node "node" and + * its descendants. + * + * The relation "executed" maps the outer generated loop iterators + * to the domain elements executed by those iterations. + * + * Ensure that the associated guard is enforced by the outer AST + * constructs by adding it to the guard of the graft. + * Since we know that we will enforce the guard, we can also include it + * in the generated constraints used to construct an AST for + * the descendant nodes. + */ +static __isl_give isl_ast_graft_list *build_ast_from_guard( + __isl_take isl_ast_build *build, __isl_take isl_schedule_node *node, + __isl_take isl_union_map *executed) +{ + isl_space *space; + isl_set *guard, *hoisted; + isl_basic_set *enforced; + isl_ast_build *sub_build; + isl_ast_graft *graft; + isl_ast_graft_list *list; + isl_size n1, n2, n; + + space = isl_ast_build_get_space(build, 1); + guard = isl_schedule_node_guard_get_guard(node); + n1 = isl_space_dim(space, isl_dim_param); + guard = isl_set_align_params(guard, space); + n2 = isl_set_dim(guard, isl_dim_param); + if (n1 < 0 || n2 < 0) + guard = isl_set_free(guard); + else if (n2 > n1) + isl_die(isl_ast_build_get_ctx(build), isl_error_invalid, + "guard node is not allowed to introduce " + "new parameters", guard = isl_set_free(guard)); + guard = isl_set_preimage_multi_aff(guard, + isl_multi_aff_copy(build->internal2input)); + guard = isl_ast_build_specialize(build, guard); + guard = isl_set_gist(guard, isl_set_copy(build->generated)); + + sub_build = isl_ast_build_copy(build); + sub_build = isl_ast_build_restrict_generated(sub_build, + isl_set_copy(guard)); + + list = build_ast_from_child(isl_ast_build_copy(sub_build), + node, executed); + + hoisted = isl_ast_graft_list_extract_hoistable_guard(list, sub_build); + n = isl_set_n_basic_set(hoisted); + if (n < 0) + list = isl_ast_graft_list_free(list); + if (n > 1) + list = isl_ast_graft_list_gist_guards(list, + isl_set_copy(hoisted)); + guard = isl_set_intersect(guard, hoisted); + enforced = extract_shared_enforced(list, build); + graft = isl_ast_graft_alloc_from_children(list, guard, enforced, + build, sub_build); + + isl_ast_build_free(sub_build); + isl_ast_build_free(build); + return isl_ast_graft_list_from_ast_graft(graft); +} + +/* Call the before_each_mark callback, if requested by the user. + * + * Return 0 on success and -1 on error. + * + * The caller is responsible for recording the current inverse schedule + * in "build". + */ +static isl_stat before_each_mark(__isl_keep isl_id *mark, + __isl_keep isl_ast_build *build) +{ + if (!build) + return isl_stat_error; + if (!build->before_each_mark) + return isl_stat_ok; + return build->before_each_mark(mark, build, + build->before_each_mark_user); +} + +/* Call the after_each_mark callback, if requested by the user. + * + * The caller is responsible for recording the current inverse schedule + * in "build". + */ +static __isl_give isl_ast_graft *after_each_mark( + __isl_take isl_ast_graft *graft, __isl_keep isl_ast_build *build) +{ + if (!graft || !build) + return isl_ast_graft_free(graft); + if (!build->after_each_mark) + return graft; + graft->node = build->after_each_mark(graft->node, build, + build->after_each_mark_user); + if (!graft->node) + return isl_ast_graft_free(graft); + return graft; +} + + +/* Generate an AST that visits the elements in the domain of "executed" + * in the relative order specified by the mark node "node" and + * its descendants. + * + * The relation "executed" maps the outer generated loop iterators + * to the domain elements executed by those iterations. + + * Since we may be calling before_each_mark and after_each_mark + * callbacks, we record the current inverse schedule in the build. + * + * We generate an AST for the child of the mark node, combine + * the graft list into a single graft and then insert the mark + * in the AST of that single graft. + */ +static __isl_give isl_ast_graft_list *build_ast_from_mark( + __isl_take isl_ast_build *build, __isl_take isl_schedule_node *node, + __isl_take isl_union_map *executed) +{ + isl_id *mark; + isl_ast_graft *graft; + isl_ast_graft_list *list; + isl_size n; + + build = isl_ast_build_set_executed(build, isl_union_map_copy(executed)); + + mark = isl_schedule_node_mark_get_id(node); + if (before_each_mark(mark, build) < 0) + node = isl_schedule_node_free(node); + + list = build_ast_from_child(isl_ast_build_copy(build), node, executed); + list = isl_ast_graft_list_fuse(list, build); + n = isl_ast_graft_list_n_ast_graft(list); + if (n < 0) + list = isl_ast_graft_list_free(list); + if (n == 0) { + isl_id_free(mark); + } else { + graft = isl_ast_graft_list_get_ast_graft(list, 0); + graft = isl_ast_graft_insert_mark(graft, mark); + graft = after_each_mark(graft, build); + list = isl_ast_graft_list_set_ast_graft(list, 0, graft); + } + isl_ast_build_free(build); + + return list; +} + +static __isl_give isl_ast_graft_list *build_ast_from_schedule_node( + __isl_take isl_ast_build *build, __isl_take isl_schedule_node *node, + __isl_take isl_union_map *executed); + +/* Generate an AST that visits the elements in the domain of "executed" + * in the relative order specified by the sequence (or set) node "node" and + * its descendants. + * + * The relation "executed" maps the outer generated loop iterators + * to the domain elements executed by those iterations. + * + * We simply generate an AST for each of the children and concatenate + * the results. + */ +static __isl_give isl_ast_graft_list *build_ast_from_sequence( + __isl_take isl_ast_build *build, __isl_take isl_schedule_node *node, + __isl_take isl_union_map *executed) +{ + int i; + isl_size n; + isl_ctx *ctx; + isl_ast_graft_list *list; + + ctx = isl_ast_build_get_ctx(build); + list = isl_ast_graft_list_alloc(ctx, 0); + + n = isl_schedule_node_n_children(node); + if (n < 0) + list = isl_ast_graft_list_free(list); + for (i = 0; i < n; ++i) { + isl_schedule_node *child; + isl_ast_graft_list *list_i; + + child = isl_schedule_node_get_child(node, i); + list_i = build_ast_from_schedule_node(isl_ast_build_copy(build), + child, isl_union_map_copy(executed)); + list = isl_ast_graft_list_concat(list, list_i); + } + isl_ast_build_free(build); + isl_schedule_node_free(node); + isl_union_map_free(executed); + + return list; +} + +/* Generate an AST that visits the elements in the domain of "executed" + * in the relative order specified by the node "node" and its descendants. + * + * The relation "executed" maps the outer generated loop iterators + * to the domain elements executed by those iterations. + * + * The node types are handled in separate functions. + * Set nodes are currently treated in the same way as sequence nodes. + * The children of a set node may be executed in any order, + * including the order of the children. + */ +static __isl_give isl_ast_graft_list *build_ast_from_schedule_node( + __isl_take isl_ast_build *build, __isl_take isl_schedule_node *node, + __isl_take isl_union_map *executed) +{ + enum isl_schedule_node_type type; + + type = isl_schedule_node_get_type(node); + + switch (type) { + case isl_schedule_node_error: + goto error; + case isl_schedule_node_leaf: + return build_ast_from_leaf(build, node, executed); + case isl_schedule_node_band: + return build_ast_from_band(build, node, executed); + case isl_schedule_node_context: + return build_ast_from_context(build, node, executed); + case isl_schedule_node_domain: + isl_die(isl_schedule_node_get_ctx(node), isl_error_unsupported, + "unexpected internal domain node", goto error); + case isl_schedule_node_expansion: + return build_ast_from_expansion(build, node, executed); + case isl_schedule_node_extension: + return build_ast_from_extension(build, node, executed); + case isl_schedule_node_filter: + return build_ast_from_filter(build, node, executed); + case isl_schedule_node_guard: + return build_ast_from_guard(build, node, executed); + case isl_schedule_node_mark: + return build_ast_from_mark(build, node, executed); + case isl_schedule_node_sequence: + case isl_schedule_node_set: + return build_ast_from_sequence(build, node, executed); + } + + isl_die(isl_ast_build_get_ctx(build), isl_error_internal, + "unhandled type", goto error); +error: + isl_union_map_free(executed); + isl_schedule_node_free(node); + isl_ast_build_free(build); + + return NULL; +} + +/* Generate an AST that visits the elements in the domain of "executed" + * in the relative order specified by the (single) child of "node" and + * its descendants. + * + * The relation "executed" maps the outer generated loop iterators + * to the domain elements executed by those iterations. + * + * This function is never called on a leaf, set or sequence node, + * so the node always has exactly one child. + */ +static __isl_give isl_ast_graft_list *build_ast_from_child( + __isl_take isl_ast_build *build, __isl_take isl_schedule_node *node, + __isl_take isl_union_map *executed) +{ + node = isl_schedule_node_child(node, 0); + return build_ast_from_schedule_node(build, node, executed); +} + +/* Generate an AST that visits the elements in the domain of the domain + * node "node" in the relative order specified by its descendants. + * + * An initial inverse schedule is created that maps a zero-dimensional + * schedule space to the node domain. + * The input "build" is assumed to have a parametric domain and + * is replaced by the same zero-dimensional schedule space. + * + * We also add some of the parameter constraints in the build domain + * to the executed relation. Adding these constraints + * allows for an earlier detection of conflicts in some cases. + * However, we do not want to divide the executed relation into + * more disjuncts than necessary. We therefore approximate + * the constraints on the parameters by a single disjunct set. + */ +static __isl_give isl_ast_node *build_ast_from_domain( + __isl_take isl_ast_build *build, __isl_take isl_schedule_node *node) +{ + isl_ctx *ctx; + isl_union_set *domain, *schedule_domain; + isl_union_map *executed; + isl_space *space; + isl_set *set; + isl_ast_graft_list *list; + isl_ast_node *ast; + int is_params; + + if (!build) + goto error; + + ctx = isl_ast_build_get_ctx(build); + space = isl_ast_build_get_space(build, 1); + is_params = isl_space_is_params(space); + isl_space_free(space); + if (is_params < 0) + goto error; + if (!is_params) + isl_die(ctx, isl_error_unsupported, + "expecting parametric initial context", goto error); + + domain = isl_schedule_node_domain_get_domain(node); + domain = isl_union_set_coalesce(domain); + + space = isl_union_set_get_space(domain); + space = isl_space_set_from_params(space); + build = isl_ast_build_product(build, space); + + set = isl_ast_build_get_domain(build); + set = isl_set_from_basic_set(isl_set_simple_hull(set)); + schedule_domain = isl_union_set_from_set(set); + + executed = isl_union_map_from_domain_and_range(schedule_domain, domain); + list = build_ast_from_child(isl_ast_build_copy(build), node, executed); + ast = isl_ast_node_from_graft_list(list, build); + isl_ast_build_free(build); + + return ast; +error: + isl_schedule_node_free(node); + isl_ast_build_free(build); + return NULL; +} + +/* Generate an AST that visits the elements in the domain of "schedule" + * in the relative order specified by the schedule tree. + * + * "build" is an isl_ast_build that has been created using + * isl_ast_build_alloc or isl_ast_build_from_context based + * on a parametric set. + * + * The construction starts at the root node of the schedule, + * which is assumed to be a domain node. + */ +__isl_give isl_ast_node *isl_ast_build_node_from_schedule( + __isl_keep isl_ast_build *build, __isl_take isl_schedule *schedule) +{ + isl_ctx *ctx; + isl_schedule_node *node; + + if (!build || !schedule) + goto error; + + 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); + build = isl_ast_build_set_single_valued(build, 0); + if (isl_schedule_node_get_type(node) != isl_schedule_node_domain) + isl_die(ctx, isl_error_unsupported, + "expecting root domain node", + build = isl_ast_build_free(build)); + return build_ast_from_domain(build, node); +error: + isl_schedule_free(schedule); + return NULL; +} diff --git a/external/mit/isl/dist/isl_ast_graft.c b/external/mit/isl/dist/isl_ast_graft.c new file mode 100644 index 000000000000..d83377694ee8 --- /dev/null +++ b/external/mit/isl/dist/isl_ast_graft.c @@ -0,0 +1,1580 @@ +/* + * Copyright 2012 Ecole Normale Superieure + * Copyright 2014 INRIA Rocquencourt + * Copyright 2019 Cerebras Systems + * + * Use of this software is governed by the MIT license + * + * Written by Sven Verdoolaege, + * Ecole Normale Superieure, 45 rue d’Ulm, 75230 Paris, France + * and Inria Paris - Rocquencourt, Domaine de Voluceau - Rocquencourt, + * B.P. 105 - 78153 Le Chesnay, France + * and Cerebras Systems, 175 S San Antonio Rd, Los Altos, CA, USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include "isl_set_to_ast_graft_list.h" + +static __isl_give isl_ast_graft *isl_ast_graft_copy( + __isl_keep isl_ast_graft *graft); +static __isl_give isl_ast_graft *isl_stream_read_ast_graft( + __isl_keep isl_stream *s); + +#undef EL_BASE +#define EL_BASE ast_graft + +#include +#include + +#undef BASE +#define BASE ast_graft +#include + +isl_ctx *isl_ast_graft_get_ctx(__isl_keep isl_ast_graft *graft) +{ + if (!graft) + return NULL; + return isl_basic_set_get_ctx(graft->enforced); +} + +__isl_give isl_ast_node *isl_ast_graft_get_node( + __isl_keep isl_ast_graft *graft) +{ + return graft ? isl_ast_node_copy(graft->node) : NULL; +} + +/* Create a graft for "node" with guards "guard" and + * enforced conditions "enforced". + */ +static isl_ast_graft *graft_alloc(__isl_take isl_ast_node *node, + __isl_take isl_set *guard, __isl_take isl_basic_set *enforced) +{ + isl_ctx *ctx; + isl_ast_graft *graft; + + if (!node || !guard || !enforced) + goto error; + + ctx = isl_ast_node_get_ctx(node); + graft = isl_calloc_type(ctx, isl_ast_graft); + if (!graft) + goto error; + + graft->ref = 1; + graft->node = node; + graft->guard = guard; + graft->enforced = enforced; + + return graft; +error: + isl_ast_node_free(node); + isl_set_free(guard); + isl_basic_set_free(enforced); + return NULL; +} + +/* Create a graft for "node" with no guards and no enforced conditions. + */ +__isl_give isl_ast_graft *isl_ast_graft_alloc( + __isl_take isl_ast_node *node, __isl_keep isl_ast_build *build) +{ + isl_space *space; + isl_set *guard; + isl_basic_set *enforced; + + if (!node) + return NULL; + + space = isl_ast_build_get_space(build, 1); + + guard = isl_set_universe(isl_space_copy(space)); + enforced = isl_basic_set_universe(space); + + return graft_alloc(node, guard, enforced); +} + +/* Create a graft with no guards and no enforced conditions + * encapsulating a call to the domain element specified by "executed". + * "executed" is assumed to be single-valued. + */ +__isl_give isl_ast_graft *isl_ast_graft_alloc_domain( + __isl_take isl_map *executed, __isl_keep isl_ast_build *build) +{ + isl_ast_node *node; + + node = isl_ast_build_call_from_executed(build, executed); + + return isl_ast_graft_alloc(node, build); +} + +static __isl_give isl_ast_graft *isl_ast_graft_copy( + __isl_keep isl_ast_graft *graft) +{ + if (!graft) + return NULL; + + graft->ref++; + return graft; +} + +/* Do all the grafts in "list" have the same guard and is this guard + * independent of the current depth? + */ +static isl_bool equal_independent_guards(__isl_keep isl_ast_graft_list *list, + __isl_keep isl_ast_build *build) +{ + int i; + isl_size n; + isl_size depth; + isl_size dim; + isl_ast_graft *graft_0; + isl_bool equal = isl_bool_true; + isl_bool skip; + + n = isl_ast_graft_list_n_ast_graft(list); + depth = isl_ast_build_get_depth(build); + if (n < 0 || depth < 0) + return isl_bool_error; + graft_0 = isl_ast_graft_list_get_ast_graft(list, 0); + if (!graft_0) + return isl_bool_error; + + dim = isl_set_dim(graft_0->guard, isl_dim_set); + if (dim < 0) + skip = isl_bool_error; + else if (dim <= depth) + skip = isl_bool_false; + else + skip = isl_set_involves_dims(graft_0->guard, + isl_dim_set, depth, 1); + if (skip < 0 || skip) { + isl_ast_graft_free(graft_0); + return isl_bool_not(skip); + } + + for (i = 1; i < n; ++i) { + isl_ast_graft *graft; + graft = isl_ast_graft_list_get_ast_graft(list, i); + if (!graft) + equal = isl_bool_error; + else + equal = isl_set_is_equal(graft_0->guard, graft->guard); + isl_ast_graft_free(graft); + if (equal < 0 || !equal) + break; + } + + isl_ast_graft_free(graft_0); + + return equal; +} + +/* Hoist "guard" out of the current level (given by "build"). + * + * In particular, eliminate the dimension corresponding to the current depth. + */ +static __isl_give isl_set *hoist_guard(__isl_take isl_set *guard, + __isl_keep isl_ast_build *build) +{ + isl_size depth; + isl_size dim; + + depth = isl_ast_build_get_depth(build); + dim = isl_set_dim(guard, isl_dim_set); + if (depth < 0 || dim < 0) + return isl_set_free(guard); + if (depth < dim) { + guard = isl_set_remove_divs_involving_dims(guard, + isl_dim_set, depth, 1); + guard = isl_set_eliminate(guard, isl_dim_set, depth, 1); + guard = isl_set_compute_divs(guard); + } + + return guard; +} + +/* Extract a common guard from the grafts in "list" that can be hoisted + * out of the current level. If no such guard can be found, then return + * a universal set. + * + * If all the grafts in the list have the same guard and if this guard + * is independent of the current level, then it can be hoisted out. + * If there is only one graft in the list and if its guard + * depends on the current level, then we eliminate this level and + * return the result. + * + * Otherwise, we return the unshifted simple hull of the guards. + * In order to be able to hoist as many constraints as possible, + * but at the same time avoid hoisting constraints that did not + * appear in the guards in the first place, we intersect the guards + * with all the information that is available (i.e., the domain + * from the build and the enforced constraints of the graft) and + * compute the unshifted hull of the result using only constraints + * from the original guards. + * In particular, intersecting the guards with other known information + * allows us to hoist guards that are only explicit is some of + * the grafts and implicit in the others. + * + * The special case for equal guards is needed in case those guards + * are non-convex. Taking the simple hull would remove information + * and would not allow for these guards to be hoisted completely. + */ +__isl_give isl_set *isl_ast_graft_list_extract_hoistable_guard( + __isl_keep isl_ast_graft_list *list, __isl_keep isl_ast_build *build) +{ + int i; + isl_size n; + isl_bool equal; + isl_ctx *ctx; + isl_set *guard; + isl_set_list *set_list; + isl_basic_set *hull; + + if (!list || !build) + return NULL; + + n = isl_ast_graft_list_n_ast_graft(list); + if (n < 0) + return NULL; + if (n == 0) + return isl_set_universe(isl_ast_build_get_space(build, 1)); + + equal = equal_independent_guards(list, build); + if (equal < 0) + return NULL; + + if (equal || n == 1) { + isl_ast_graft *graft_0; + + graft_0 = isl_ast_graft_list_get_ast_graft(list, 0); + if (!graft_0) + return NULL; + guard = isl_set_copy(graft_0->guard); + if (!equal) + guard = hoist_guard(guard, build); + isl_ast_graft_free(graft_0); + return guard; + } + + ctx = isl_ast_build_get_ctx(build); + set_list = isl_set_list_alloc(ctx, n); + guard = isl_set_empty(isl_ast_build_get_space(build, 1)); + for (i = 0; i < n; ++i) { + isl_ast_graft *graft; + isl_basic_set *enforced; + isl_set *guard_i; + + graft = isl_ast_graft_list_get_ast_graft(list, i); + enforced = isl_ast_graft_get_enforced(graft); + guard_i = isl_set_copy(graft->guard); + isl_ast_graft_free(graft); + set_list = isl_set_list_add(set_list, isl_set_copy(guard_i)); + guard_i = isl_set_intersect(guard_i, + isl_set_from_basic_set(enforced)); + guard_i = isl_set_intersect(guard_i, + isl_ast_build_get_domain(build)); + guard = isl_set_union(guard, guard_i); + } + hull = isl_set_unshifted_simple_hull_from_set_list(guard, set_list); + guard = isl_set_from_basic_set(hull); + return hoist_guard(guard, build); +} + +/* Internal data structure used inside insert_if. + * + * list is the list of guarded nodes created by each call to insert_if. + * node is the original node that is guarded by insert_if. + * build is the build in which the AST is constructed. + */ +struct isl_insert_if_data { + isl_ast_node_list *list; + isl_ast_node *node; + isl_ast_build *build; +}; + +static isl_stat insert_if(__isl_take isl_basic_set *bset, void *user); + +/* Insert an if node around "node" testing the condition encoded + * in guard "guard". + * + * If the user does not want any disjunctions in the if conditions + * and if "guard" does involve a disjunction, then we make the different + * disjuncts disjoint and insert an if node corresponding to each disjunct + * around a copy of "node". The result is then a block node containing + * this sequence of guarded copies of "node". + */ +static __isl_give isl_ast_node *ast_node_insert_if( + __isl_take isl_ast_node *node, __isl_take isl_set *guard, + __isl_keep isl_ast_build *build) +{ + struct isl_insert_if_data data; + isl_ctx *ctx; + isl_size n; + + n = isl_set_n_basic_set(guard); + if (n < 0) + goto error; + ctx = isl_ast_build_get_ctx(build); + if (isl_options_get_ast_build_allow_or(ctx) || n <= 1) { + isl_ast_node *if_node; + isl_ast_expr *expr; + + expr = isl_ast_build_expr_from_set_internal(build, guard); + + if_node = isl_ast_node_alloc_if(expr); + return isl_ast_node_if_set_then(if_node, node); + } + + guard = isl_set_make_disjoint(guard); + + data.list = isl_ast_node_list_alloc(ctx, 0); + data.node = node; + data.build = build; + if (isl_set_foreach_basic_set(guard, &insert_if, &data) < 0) + data.list = isl_ast_node_list_free(data.list); + + isl_set_free(guard); + isl_ast_node_free(data.node); + return isl_ast_node_alloc_block(data.list); +error: + isl_set_free(guard); + isl_ast_node_free(node); + return NULL; +} + +/* Insert an if node around a copy of "data->node" testing the condition + * encoded in guard "bset" and add the result to data->list. + */ +static isl_stat insert_if(__isl_take isl_basic_set *bset, void *user) +{ + struct isl_insert_if_data *data = user; + isl_ast_node *node; + isl_set *set; + + set = isl_set_from_basic_set(bset); + node = isl_ast_node_copy(data->node); + node = ast_node_insert_if(node, set, data->build); + data->list = isl_ast_node_list_add(data->list, node); + + return isl_stat_ok; +} + +/* Insert an if node around graft->node testing the condition encoded + * in guard "guard", assuming guard involves any conditions. + */ +static __isl_give isl_ast_graft *insert_if_node( + __isl_take isl_ast_graft *graft, __isl_take isl_set *guard, + __isl_keep isl_ast_build *build) +{ + int univ; + + if (!graft) + goto error; + + univ = isl_set_plain_is_universe(guard); + if (univ < 0) + goto error; + if (univ) { + isl_set_free(guard); + return graft; + } + + graft->node = ast_node_insert_if(graft->node, guard, build); + + if (!graft->node) + return isl_ast_graft_free(graft); + + return graft; +error: + isl_set_free(guard); + return isl_ast_graft_free(graft); +} + +/* Insert an if node around graft->node testing the condition encoded + * in graft->guard, assuming graft->guard involves any conditions. + */ +static __isl_give isl_ast_graft *insert_pending_guard_node( + __isl_take isl_ast_graft *graft, __isl_keep isl_ast_build *build) +{ + if (!graft) + return NULL; + + return insert_if_node(graft, isl_set_copy(graft->guard), build); +} + +/* Replace graft->enforced by "enforced". + */ +__isl_give isl_ast_graft *isl_ast_graft_set_enforced( + __isl_take isl_ast_graft *graft, __isl_take isl_basic_set *enforced) +{ + if (!graft || !enforced) + goto error; + + isl_basic_set_free(graft->enforced); + graft->enforced = enforced; + + return graft; +error: + isl_basic_set_free(enforced); + return isl_ast_graft_free(graft); +} + +/* Update "enforced" such that it only involves constraints that are + * also enforced by "graft". + */ +static __isl_give isl_basic_set *update_enforced( + __isl_take isl_basic_set *enforced, __isl_keep isl_ast_graft *graft, + int depth) +{ + isl_size dim; + isl_basic_set *enforced_g; + + enforced_g = isl_ast_graft_get_enforced(graft); + dim = isl_basic_set_dim(enforced_g, isl_dim_set); + if (dim < 0) + enforced_g = isl_basic_set_free(enforced_g); + if (depth < dim) + enforced_g = isl_basic_set_eliminate(enforced_g, + isl_dim_set, depth, 1); + enforced_g = isl_basic_set_remove_unknown_divs(enforced_g); + enforced_g = isl_basic_set_align_params(enforced_g, + isl_basic_set_get_space(enforced)); + enforced = isl_basic_set_align_params(enforced, + isl_basic_set_get_space(enforced_g)); + enforced = isl_set_simple_hull(isl_basic_set_union(enforced, + enforced_g)); + + return enforced; +} + +/* Extend the node at *body with node. + * + * If body points to the else branch, then *body may still be NULL. + * If so, we simply attach node to this else branch. + * Otherwise, we attach a list containing the statements already + * attached at *body followed by node. + */ +static void extend_body(__isl_keep isl_ast_node **body, + __isl_take isl_ast_node *node) +{ + isl_ast_node_list *list; + + if (!*body) { + *body = node; + return; + } + + if ((*body)->type == isl_ast_node_block) { + list = isl_ast_node_block_get_children(*body); + isl_ast_node_free(*body); + } else + list = isl_ast_node_list_from_ast_node(*body); + list = isl_ast_node_list_add(list, node); + *body = isl_ast_node_alloc_block(list); +} + +/* Merge "graft" into the last graft of "list". + * body points to the then or else branch of an if node in that last graft. + * + * We attach graft->node to this branch and update the enforced + * set of the last graft of "list" to take into account the enforced + * set of "graft". + */ +static __isl_give isl_ast_graft_list *graft_extend_body( + __isl_take isl_ast_graft_list *list, + __isl_keep isl_ast_node **body, __isl_take isl_ast_graft *graft, + __isl_keep isl_ast_build *build) +{ + isl_size n; + isl_size depth; + isl_ast_graft *last; + isl_space *space; + isl_basic_set *enforced; + + n = isl_ast_graft_list_n_ast_graft(list); + depth = isl_ast_build_get_depth(build); + if (n < 0 || depth < 0 || !graft) + goto error; + extend_body(body, isl_ast_node_copy(graft->node)); + if (!*body) + goto error; + + last = isl_ast_graft_list_get_ast_graft(list, n - 1); + + space = isl_ast_build_get_space(build, 1); + enforced = isl_basic_set_empty(space); + enforced = update_enforced(enforced, last, depth); + enforced = update_enforced(enforced, graft, depth); + last = isl_ast_graft_set_enforced(last, enforced); + + list = isl_ast_graft_list_set_ast_graft(list, n - 1, last); + isl_ast_graft_free(graft); + return list; +error: + isl_ast_graft_free(graft); + return isl_ast_graft_list_free(list); +} + +/* Merge "graft" into the last graft of "list", attaching graft->node + * to the then branch of "last_if". + */ +static __isl_give isl_ast_graft_list *extend_then( + __isl_take isl_ast_graft_list *list, + __isl_keep isl_ast_node *last_if, __isl_take isl_ast_graft *graft, + __isl_keep isl_ast_build *build) +{ + return graft_extend_body(list, &last_if->u.i.then, graft, build); +} + +/* Merge "graft" into the last graft of "list", attaching graft->node + * to the else branch of "last_if". + */ +static __isl_give isl_ast_graft_list *extend_else( + __isl_take isl_ast_graft_list *list, + __isl_keep isl_ast_node *last_if, __isl_take isl_ast_graft *graft, + __isl_keep isl_ast_build *build) +{ + return graft_extend_body(list, &last_if->u.i.else_node, graft, build); +} + +/* This data structure keeps track of an if node. + * + * "node" is the actual if-node + * "guard" is the original, non-simplified guard of the node + * "complement" is the complement of "guard" in the context of outer if nodes + */ +struct isl_if_node { + isl_ast_node *node; + isl_set *guard; + isl_set *complement; +}; + +/* Given a list of "n" if nodes, clear those starting at "first" + * and return "first" (i.e., the updated size of the array). + */ +static int clear_if_nodes(struct isl_if_node *if_node, int first, int n) +{ + int i; + + for (i = first; i < n; ++i) { + isl_set_free(if_node[i].guard); + isl_set_free(if_node[i].complement); + } + + return first; +} + +/* For each graft in "list", + * insert an if node around graft->node testing the condition encoded + * in graft->guard, assuming graft->guard involves any conditions. + * + * We keep track of a list of generated if nodes that can be extended + * without changing the order of the elements in "list". + * If the guard of a graft is a subset of either the guard or its complement + * of one of those if nodes, then the node + * of the new graft is inserted into the then or else branch of the last graft + * and the current graft is discarded. + * The guard of the node is then simplified based on the conditions + * enforced at that then or else branch. + * Otherwise, the current graft is appended to the list. + * + * We only construct else branches if allowed by the user. + */ +static __isl_give isl_ast_graft_list *insert_pending_guard_nodes( + __isl_take isl_ast_graft_list *list, + __isl_keep isl_ast_build *build) +{ + int i, j, n_if; + isl_size n; + int allow_else; + isl_ctx *ctx; + isl_ast_graft_list *res; + struct isl_if_node *if_node = NULL; + + n = isl_ast_graft_list_n_ast_graft(list); + if (!build || n < 0) + return isl_ast_graft_list_free(list); + + ctx = isl_ast_build_get_ctx(build); + + allow_else = isl_options_get_ast_build_allow_else(ctx); + + n_if = 0; + if (n > 1) { + if_node = isl_alloc_array(ctx, struct isl_if_node, n - 1); + if (!if_node) + return isl_ast_graft_list_free(list); + } + + res = isl_ast_graft_list_alloc(ctx, n); + + for (i = 0; i < n; ++i) { + isl_set *guard; + isl_ast_graft *graft; + int subset, found_then, found_else; + isl_ast_node *node; + + graft = isl_ast_graft_list_get_ast_graft(list, i); + if (!graft) + break; + subset = 0; + found_then = found_else = -1; + if (n_if > 0) { + isl_set *test; + test = isl_set_copy(graft->guard); + test = isl_set_intersect(test, + isl_set_copy(build->domain)); + for (j = n_if - 1; j >= 0; --j) { + subset = isl_set_is_subset(test, + if_node[j].guard); + if (subset < 0 || subset) { + found_then = j; + break; + } + if (!allow_else) + continue; + subset = isl_set_is_subset(test, + if_node[j].complement); + if (subset < 0 || subset) { + found_else = j; + break; + } + } + n_if = clear_if_nodes(if_node, j + 1, n_if); + isl_set_free(test); + } + if (subset < 0) { + graft = isl_ast_graft_free(graft); + break; + } + + guard = isl_set_copy(graft->guard); + if (found_then >= 0) + graft->guard = isl_set_gist(graft->guard, + isl_set_copy(if_node[found_then].guard)); + else if (found_else >= 0) + graft->guard = isl_set_gist(graft->guard, + isl_set_copy(if_node[found_else].complement)); + + node = graft->node; + if (!graft->guard) + graft = isl_ast_graft_free(graft); + graft = insert_pending_guard_node(graft, build); + if (graft && graft->node != node && i != n - 1) { + isl_set *set; + if_node[n_if].node = graft->node; + if_node[n_if].guard = guard; + if (found_then >= 0) + set = if_node[found_then].guard; + else if (found_else >= 0) + set = if_node[found_else].complement; + else + set = build->domain; + set = isl_set_copy(set); + set = isl_set_subtract(set, isl_set_copy(guard)); + if_node[n_if].complement = set; + n_if++; + } else + isl_set_free(guard); + if (!graft) + break; + + if (found_then >= 0) + res = extend_then(res, if_node[found_then].node, + graft, build); + else if (found_else >= 0) + res = extend_else(res, if_node[found_else].node, + graft, build); + else + res = isl_ast_graft_list_add(res, graft); + } + if (i < n) + res = isl_ast_graft_list_free(res); + + isl_ast_graft_list_free(list); + clear_if_nodes(if_node, 0, n_if); + free(if_node); + return res; +} + +/* For each graft in "list", + * insert an if node around graft->node testing the condition encoded + * in graft->guard, assuming graft->guard involves any conditions. + * Subsequently remove the guards from the grafts. + */ +__isl_give isl_ast_graft_list *isl_ast_graft_list_insert_pending_guard_nodes( + __isl_take isl_ast_graft_list *list, __isl_keep isl_ast_build *build) +{ + int i; + isl_size n; + isl_set *universe; + + list = insert_pending_guard_nodes(list, build); + n = isl_ast_graft_list_n_ast_graft(list); + if (n < 0) + return isl_ast_graft_list_free(list); + + universe = isl_set_universe(isl_ast_build_get_space(build, 1)); + for (i = 0; i < n; ++i) { + isl_ast_graft *graft; + + graft = isl_ast_graft_list_get_ast_graft(list, i); + if (!graft) + break; + isl_set_free(graft->guard); + graft->guard = isl_set_copy(universe); + if (!graft->guard) + graft = isl_ast_graft_free(graft); + list = isl_ast_graft_list_set_ast_graft(list, i, graft); + } + isl_set_free(universe); + if (i < n) + return isl_ast_graft_list_free(list); + + return list; +} + +/* Collect the nodes contained in the grafts in "list" in a node list. + */ +static __isl_give isl_ast_node_list *extract_node_list( + __isl_keep isl_ast_graft_list *list) +{ + int i; + isl_size n; + isl_ctx *ctx; + isl_ast_node_list *node_list; + + n = isl_ast_graft_list_n_ast_graft(list); + if (n < 0) + return NULL; + ctx = isl_ast_graft_list_get_ctx(list); + node_list = isl_ast_node_list_alloc(ctx, n); + for (i = 0; i < n; ++i) { + isl_ast_node *node; + isl_ast_graft *graft; + + graft = isl_ast_graft_list_get_ast_graft(list, i); + node = isl_ast_graft_get_node(graft); + node_list = isl_ast_node_list_add(node_list, node); + isl_ast_graft_free(graft); + } + + return node_list; +} + +/* Look for shared enforced constraints by all the elements in "list" + * on outer loops (with respect to the current depth) and return the result. + * + * If there are no elements in "list", then return the empty set. + */ +__isl_give isl_basic_set *isl_ast_graft_list_extract_shared_enforced( + __isl_keep isl_ast_graft_list *list, + __isl_keep isl_ast_build *build) +{ + int i; + isl_size n; + isl_size depth; + isl_space *space; + isl_basic_set *enforced; + + n = isl_ast_graft_list_n_ast_graft(list); + depth = isl_ast_build_get_depth(build); + if (n < 0 || depth < 0) + return NULL; + + space = isl_ast_build_get_space(build, 1); + enforced = isl_basic_set_empty(space); + + for (i = 0; i < n; ++i) { + isl_ast_graft *graft; + + graft = isl_ast_graft_list_get_ast_graft(list, i); + enforced = update_enforced(enforced, graft, depth); + isl_ast_graft_free(graft); + } + + return enforced; +} + +/* Record "guard" in "graft" so that it will be enforced somewhere + * up the tree. If the graft already has a guard, then it may be partially + * redundant in combination with the new guard and in the context + * the generated constraints of "build". In fact, the new guard + * may in itself have some redundant constraints. + * We therefore (re)compute the gist of the intersection + * and coalesce the result. + */ +static __isl_give isl_ast_graft *store_guard(__isl_take isl_ast_graft *graft, + __isl_take isl_set *guard, __isl_keep isl_ast_build *build) +{ + int is_universe; + + if (!graft) + goto error; + + is_universe = isl_set_plain_is_universe(guard); + if (is_universe < 0) + goto error; + if (is_universe) { + isl_set_free(guard); + return graft; + } + + graft->guard = isl_set_intersect(graft->guard, guard); + graft->guard = isl_set_gist(graft->guard, + isl_ast_build_get_generated(build)); + graft->guard = isl_set_coalesce(graft->guard); + if (!graft->guard) + return isl_ast_graft_free(graft); + + return graft; +error: + isl_set_free(guard); + return isl_ast_graft_free(graft); +} + +/* For each graft in "list", replace its guard with the gist with + * respect to "context". + */ +static __isl_give isl_ast_graft_list *gist_guards( + __isl_take isl_ast_graft_list *list, __isl_keep isl_set *context) +{ + int i; + isl_size n; + + n = isl_ast_graft_list_n_ast_graft(list); + if (!list) + return isl_ast_graft_list_free(list); + + for (i = 0; i < n; ++i) { + isl_ast_graft *graft; + + graft = isl_ast_graft_list_get_ast_graft(list, i); + if (!graft) + break; + graft->guard = isl_set_gist(graft->guard, + isl_set_copy(context)); + if (!graft->guard) + graft = isl_ast_graft_free(graft); + list = isl_ast_graft_list_set_ast_graft(list, i, graft); + } + if (i < n) + return isl_ast_graft_list_free(list); + + return list; +} + +/* For each graft in "list", replace its guard with the gist with + * respect to "context". + */ +__isl_give isl_ast_graft_list *isl_ast_graft_list_gist_guards( + __isl_take isl_ast_graft_list *list, __isl_take isl_set *context) +{ + list = gist_guards(list, context); + isl_set_free(context); + + return list; +} + +/* Allocate a graft in "build" based on the list of grafts in "sub_build". + * "guard" and "enforced" are the guard and enforced constraints + * of the allocated graft. The guard is used to simplify the guards + * of the elements in "list". + * + * The node is initialized to either a block containing the nodes of "children" + * or, if there is only a single child, the node of that child. + * If the current level requires a for node, it should be inserted by + * a subsequent call to isl_ast_graft_insert_for. + */ +__isl_give isl_ast_graft *isl_ast_graft_alloc_from_children( + __isl_take isl_ast_graft_list *list, __isl_take isl_set *guard, + __isl_take isl_basic_set *enforced, __isl_keep isl_ast_build *build, + __isl_keep isl_ast_build *sub_build) +{ + isl_ast_build *guard_build; + isl_ast_node *node; + isl_ast_node_list *node_list; + isl_ast_graft *graft; + + guard_build = isl_ast_build_copy(sub_build); + guard_build = isl_ast_build_replace_pending_by_guard(guard_build, + isl_set_copy(guard)); + list = gist_guards(list, guard); + list = insert_pending_guard_nodes(list, guard_build); + isl_ast_build_free(guard_build); + + node_list = extract_node_list(list); + node = isl_ast_node_from_ast_node_list(node_list); + isl_ast_graft_list_free(list); + + graft = isl_ast_graft_alloc(node, build); + graft = store_guard(graft, guard, build); + graft = isl_ast_graft_enforce(graft, enforced); + + return graft; +} + +/* Combine the grafts in the list into a single graft. + * + * The guard is initialized to the shared guard of the list elements (if any), + * provided it does not depend on the current dimension. + * The guards in the elements are then simplified with respect to the + * hoisted guard and materialized as if nodes around the contained AST nodes + * in the context of "sub_build". + * + * The enforced set is initialized to the simple hull of the enforced sets + * of the elements, provided the ast_build_exploit_nested_bounds option is set + * or the new graft will be used at the same level. + * + * The node is initialized to either a block containing the nodes of "list" + * or, if there is only a single element, the node of that element. + */ +static __isl_give isl_ast_graft *ast_graft_list_fuse( + __isl_take isl_ast_graft_list *list, __isl_keep isl_ast_build *build) +{ + isl_ast_graft *graft; + isl_basic_set *enforced; + isl_set *guard; + + if (!list) + return NULL; + + enforced = isl_ast_graft_list_extract_shared_enforced(list, build); + guard = isl_ast_graft_list_extract_hoistable_guard(list, build); + graft = isl_ast_graft_alloc_from_children(list, guard, enforced, + build, build); + + return graft; +} + +/* Combine the grafts in the list into a single graft. + * Return a list containing this single graft. + * If the original list is empty, then return an empty list. + */ +__isl_give isl_ast_graft_list *isl_ast_graft_list_fuse( + __isl_take isl_ast_graft_list *list, + __isl_keep isl_ast_build *build) +{ + isl_size n; + isl_ast_graft *graft; + + n = isl_ast_graft_list_n_ast_graft(list); + if (n < 0) + return isl_ast_graft_list_free(list); + if (n <= 1) + return list; + graft = ast_graft_list_fuse(list, build); + return isl_ast_graft_list_from_ast_graft(graft); +} + +/* Combine the two grafts into a single graft. + * Return a list containing this single graft. + */ +static __isl_give isl_ast_graft *isl_ast_graft_fuse( + __isl_take isl_ast_graft *graft1, __isl_take isl_ast_graft *graft2, + __isl_keep isl_ast_build *build) +{ + isl_ctx *ctx; + isl_ast_graft_list *list; + + ctx = isl_ast_build_get_ctx(build); + + list = isl_ast_graft_list_alloc(ctx, 2); + list = isl_ast_graft_list_add(list, graft1); + list = isl_ast_graft_list_add(list, graft2); + + return ast_graft_list_fuse(list, build); +} + +/* Insert a for node enclosing the current graft->node. + */ +__isl_give isl_ast_graft *isl_ast_graft_insert_for( + __isl_take isl_ast_graft *graft, __isl_take isl_ast_node *node) +{ + if (!graft) + goto error; + + graft->node = isl_ast_node_for_set_body(node, graft->node); + if (!graft->node) + return isl_ast_graft_free(graft); + + return graft; +error: + isl_ast_node_free(node); + isl_ast_graft_free(graft); + return NULL; +} + +/* Insert a mark governing the current graft->node. + */ +__isl_give isl_ast_graft *isl_ast_graft_insert_mark( + __isl_take isl_ast_graft *graft, __isl_take isl_id *mark) +{ + if (!graft) + goto error; + + graft->node = isl_ast_node_alloc_mark(mark, graft->node); + if (!graft->node) + return isl_ast_graft_free(graft); + + return graft; +error: + isl_id_free(mark); + isl_ast_graft_free(graft); + return NULL; +} + +/* Represent the graft list as an AST node. + * This operation drops the information about guards in the grafts, so + * if there are any pending guards, then they are materialized as if nodes. + */ +__isl_give isl_ast_node *isl_ast_node_from_graft_list( + __isl_take isl_ast_graft_list *list, + __isl_keep isl_ast_build *build) +{ + isl_ast_node_list *node_list; + + list = insert_pending_guard_nodes(list, build); + node_list = extract_node_list(list); + isl_ast_graft_list_free(list); + + return isl_ast_node_from_ast_node_list(node_list); +} + +__isl_null isl_ast_graft *isl_ast_graft_free(__isl_take isl_ast_graft *graft) +{ + if (!graft) + return NULL; + + if (--graft->ref > 0) + return NULL; + + isl_ast_node_free(graft->node); + isl_set_free(graft->guard); + isl_basic_set_free(graft->enforced); + free(graft); + + return NULL; +} + +/* Record that the grafted tree enforces + * "enforced" by intersecting graft->enforced with "enforced". + */ +__isl_give isl_ast_graft *isl_ast_graft_enforce( + __isl_take isl_ast_graft *graft, __isl_take isl_basic_set *enforced) +{ + if (!graft || !enforced) + goto error; + + enforced = isl_basic_set_align_params(enforced, + isl_basic_set_get_space(graft->enforced)); + graft->enforced = isl_basic_set_align_params(graft->enforced, + isl_basic_set_get_space(enforced)); + graft->enforced = isl_basic_set_intersect(graft->enforced, enforced); + if (!graft->enforced) + return isl_ast_graft_free(graft); + + return graft; +error: + isl_basic_set_free(enforced); + return isl_ast_graft_free(graft); +} + +__isl_give isl_basic_set *isl_ast_graft_get_enforced( + __isl_keep isl_ast_graft *graft) +{ + return graft ? isl_basic_set_copy(graft->enforced) : NULL; +} + +__isl_give isl_set *isl_ast_graft_get_guard(__isl_keep isl_ast_graft *graft) +{ + return graft ? isl_set_copy(graft->guard) : NULL; +} + +/* Record that "guard" needs to be inserted in "graft". + */ +__isl_give isl_ast_graft *isl_ast_graft_add_guard( + __isl_take isl_ast_graft *graft, + __isl_take isl_set *guard, __isl_keep isl_ast_build *build) +{ + return store_guard(graft, guard, build); +} + +/* Reformulate the "graft", which was generated in the context + * of an inner code generation, in terms of the outer code generation + * AST build. + * + * If "product" is set, then the domain of the inner code generation build is + * + * [O -> S] + * + * with O the domain of the outer code generation build. + * We essentially need to project out S. + * + * If "product" is not set, then we need to project the domains onto + * their parameter spaces. + */ +__isl_give isl_ast_graft *isl_ast_graft_unembed(__isl_take isl_ast_graft *graft, + int product) +{ + isl_basic_set *enforced; + + if (!graft) + return NULL; + + if (product) { + enforced = graft->enforced; + enforced = isl_basic_map_domain(isl_basic_set_unwrap(enforced)); + graft->enforced = enforced; + graft->guard = isl_map_domain(isl_set_unwrap(graft->guard)); + } else { + graft->enforced = isl_basic_set_params(graft->enforced); + graft->guard = isl_set_params(graft->guard); + } + graft->guard = isl_set_compute_divs(graft->guard); + + if (!graft->enforced || !graft->guard) + return isl_ast_graft_free(graft); + + return graft; +} + +/* Reformulate the grafts in "list", which were generated in the context + * of an inner code generation, in terms of the outer code generation + * AST build. + */ +__isl_give isl_ast_graft_list *isl_ast_graft_list_unembed( + __isl_take isl_ast_graft_list *list, int product) +{ + int i; + isl_size n; + + n = isl_ast_graft_list_n_ast_graft(list); + if (n < 0) + return isl_ast_graft_list_free(list); + for (i = 0; i < n; ++i) { + isl_ast_graft *graft; + + graft = isl_ast_graft_list_get_ast_graft(list, i); + graft = isl_ast_graft_unembed(graft, product); + list = isl_ast_graft_list_set_ast_graft(list, i, graft); + } + + return list; +} + +/* Compute the preimage of "graft" under the function represented by "ma". + * In other words, plug in "ma" in "enforced" and "guard" fields of "graft". + */ +__isl_give isl_ast_graft *isl_ast_graft_preimage_multi_aff( + __isl_take isl_ast_graft *graft, __isl_take isl_multi_aff *ma) +{ + isl_basic_set *enforced; + + if (!graft) + return NULL; + + enforced = graft->enforced; + graft->enforced = isl_basic_set_preimage_multi_aff(enforced, + isl_multi_aff_copy(ma)); + graft->guard = isl_set_preimage_multi_aff(graft->guard, ma); + + if (!graft->enforced || !graft->guard) + return isl_ast_graft_free(graft); + + return graft; +} + +/* Compute the preimage of all the grafts in "list" under + * the function represented by "ma". + */ +__isl_give isl_ast_graft_list *isl_ast_graft_list_preimage_multi_aff( + __isl_take isl_ast_graft_list *list, __isl_take isl_multi_aff *ma) +{ + int i; + isl_size n; + + n = isl_ast_graft_list_n_ast_graft(list); + if (n < 0) + list = isl_ast_graft_list_free(list); + for (i = 0; i < n; ++i) { + isl_ast_graft *graft; + + graft = isl_ast_graft_list_get_ast_graft(list, i); + graft = isl_ast_graft_preimage_multi_aff(graft, + isl_multi_aff_copy(ma)); + list = isl_ast_graft_list_set_ast_graft(list, i, graft); + } + + isl_multi_aff_free(ma); + return list; +} + +/* Compare two grafts based on their guards. + */ +static int cmp_graft(__isl_keep isl_ast_graft *a, __isl_keep isl_ast_graft *b, + void *user) +{ + return isl_set_plain_cmp(a->guard, b->guard); +} + +/* Order the elements in "list" based on their guards. + */ +__isl_give isl_ast_graft_list *isl_ast_graft_list_sort_guard( + __isl_take isl_ast_graft_list *list) +{ + return isl_ast_graft_list_sort(list, &cmp_graft, NULL); +} + +/* Merge the given two lists into a single list of grafts, + * merging grafts with the same guard into a single graft. + * + * "list2" has been sorted using isl_ast_graft_list_sort. + * "list1" may be the result of a previous call to isl_ast_graft_list_merge + * and may therefore not be completely sorted. + * + * The elements in "list2" need to be executed after those in "list1", + * but if the guard of a graft in "list2" is disjoint from the guards + * of some final elements in "list1", then it can be moved up to before + * those final elements. + * + * In particular, we look at each element g of "list2" in turn + * and move it up beyond elements of "list1" that would be sorted + * after g as long as each of these elements has a guard that is disjoint + * from that of g. + * + * We do not allow the second or any later element of "list2" to be moved + * before a previous elements of "list2" even if the reason that + * that element didn't move up further was that its guard was not disjoint + * from that of the previous element in "list1". + */ +__isl_give isl_ast_graft_list *isl_ast_graft_list_merge( + __isl_take isl_ast_graft_list *list1, + __isl_take isl_ast_graft_list *list2, + __isl_keep isl_ast_build *build) +{ + int i, j, first; + + if (!list1 || !list2 || !build) + goto error; + if (list2->n == 0) { + isl_ast_graft_list_free(list2); + return list1; + } + if (list1->n == 0) { + isl_ast_graft_list_free(list1); + return list2; + } + + first = 0; + for (i = 0; i < list2->n; ++i) { + isl_ast_graft *graft; + graft = isl_ast_graft_list_get_ast_graft(list2, i); + if (!graft) + break; + + for (j = list1->n; j >= 0; --j) { + int cmp, disjoint; + isl_ast_graft *graft_j; + + if (j == first) + cmp = -1; + else + cmp = isl_set_plain_cmp(list1->p[j - 1]->guard, + graft->guard); + if (cmp > 0) { + 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; + } + if (!disjoint) + cmp = -1; + } + if (cmp > 0) + continue; + if (cmp < 0) { + list1 = isl_ast_graft_list_insert(list1, j, + graft); + break; + } + + --j; + + graft_j = isl_ast_graft_list_get_ast_graft(list1, j); + graft_j = isl_ast_graft_fuse(graft_j, graft, build); + list1 = isl_ast_graft_list_set_ast_graft(list1, j, + graft_j); + break; + } + + 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) + break; + } + if (i < list2->n) + list1 = isl_ast_graft_list_free(list1); + isl_ast_graft_list_free(list2); + + return list1; +error: + isl_ast_graft_list_free(list1); + isl_ast_graft_list_free(list2); + return NULL; +} + +/* Internal data structure for split_on_guard. + * + * "guard2list" is the constructed associative array. + * "any_match" gets set if any guard was seen more than once. + */ +struct isl_split_on_guard_data { + isl_set_to_ast_graft_list *guard2list; + int *any_match; +}; + +/* Add "graft" to the list associated to its guard in data->guard2list. + * If some other graft was already associated to this guard, + * then set data->any_match. + */ +static isl_stat add_to_guard_list(__isl_take isl_ast_graft *graft, void *user) +{ + struct isl_split_on_guard_data *data = user; + isl_set *guard; + isl_maybe_isl_ast_graft_list m; + + if (!graft) + return isl_stat_error; + m = isl_set_to_ast_graft_list_try_get(data->guard2list, graft->guard); + if (m.valid < 0) + return isl_stat_non_null(isl_ast_graft_free(graft)); + + if (m.valid) { + *data->any_match = 1; + m.value = isl_ast_graft_list_add(m.value, graft); + } else { + m.value = isl_ast_graft_list_from_ast_graft(graft); + } + guard = isl_set_copy(graft->guard); + data->guard2list = + isl_set_to_ast_graft_list_set(data->guard2list, guard, m.value); + + return isl_stat_non_null(data->guard2list); +} + +/* Construct an associative array that groups the elements + * of "list" based on their guards. + * If any guard appears more than once, then set "any_match". + */ +static __isl_give isl_set_to_ast_graft_list *split_on_guard( + __isl_keep isl_ast_graft_list *list, int *any_match) +{ + struct isl_split_on_guard_data data = { NULL, any_match }; + isl_size n; + isl_ctx *ctx; + + n = isl_ast_graft_list_size(list); + if (n < 0) + return NULL; + + ctx = isl_ast_graft_list_get_ctx(list); + data.guard2list = isl_set_to_ast_graft_list_alloc(ctx, n); + + if (isl_ast_graft_list_foreach(list, &add_to_guard_list, &data) < 0) + return isl_set_to_ast_graft_list_free(data.guard2list); + + return data.guard2list; +} + +/* Add the elements of "guard_list" to "list". + */ +static isl_stat add_same_guard(__isl_take isl_set *guard, + __isl_take isl_ast_graft_list *guard_list, void *user) +{ + isl_ast_graft_list **list = user; + + isl_set_free(guard); + *list = isl_ast_graft_list_concat(*list, guard_list); + + return isl_stat_non_null(*list); +} + +/* Given an associative array "guard2list" containing the elements + * of "list" grouped on common guards, reconstruct "list" + * by placing elements with the same guard consecutively. + */ +static __isl_give isl_ast_graft_list *reconstruct( + __isl_take isl_ast_graft_list *list, + __isl_keep isl_set_to_ast_graft_list *guard2list, + __isl_keep isl_ast_build *build) +{ + list = isl_ast_graft_list_clear(list); + if (isl_set_to_ast_graft_list_foreach(guard2list, + &add_same_guard, &list) < 0) + list = isl_ast_graft_list_free(list); + + return list; +} + +/* Group the grafts in "list" based on identical guards. + * + * Note that there need to be a least three elements in the list + * for the elements not to be grouped already. + * + * Group the elements in an associative array based on their guards. + * If any guard was seen more than once, then reconstruct the list + * from the associative array. Otherwise, simply return the original list. + */ +__isl_give isl_ast_graft_list *isl_ast_graft_list_group_on_guard( + __isl_take isl_ast_graft_list *list, __isl_keep isl_ast_build *build) +{ + int any_match = 0; + isl_size n; + isl_set_to_ast_graft_list *guard2list; + + n = isl_ast_graft_list_size(list); + if (n < 0) + return isl_ast_graft_list_free(list); + if (n <= 2) + return list; + + guard2list = split_on_guard(list, &any_match); + if (any_match) + list = reconstruct(list, guard2list, build); + + isl_set_to_ast_graft_list_free(guard2list); + + return list; +} + +/* An enumeration of the keys that appear in the textual representation + * of an isl_sat_graft object. + */ +enum isl_graft_key { + isl_graft_key_error = -1, + isl_graft_key_guard, + isl_graft_key_enforced, + isl_graft_key_node, + isl_graft_key_end +}; + +/* Textual representations of the keys for an isl_sat_graft object. + */ +static char *key_str[] = { + [isl_graft_key_guard] = "guard", + [isl_graft_key_enforced] = "enforced", + [isl_graft_key_node] = "node", +}; + +__isl_give isl_printer *isl_printer_print_ast_graft(__isl_take isl_printer *p, + __isl_keep isl_ast_graft *graft) +{ + if (!p) + return NULL; + if (!graft) + return isl_printer_free(p); + + p = isl_printer_print_str(p, "("); + p = isl_printer_print_str(p, key_str[isl_graft_key_guard]); + p = isl_printer_print_str(p, ": "); + p = isl_printer_print_set(p, graft->guard); + p = isl_printer_print_str(p, ", "); + p = isl_printer_print_str(p, key_str[isl_graft_key_enforced]); + p = isl_printer_print_str(p, ": "); + p = isl_printer_print_basic_set(p, graft->enforced); + p = isl_printer_print_str(p, ", "); + p = isl_printer_print_str(p, key_str[isl_graft_key_node]); + p = isl_printer_print_str(p, ": "); + p = isl_printer_print_ast_node(p, graft->node); + p = isl_printer_print_str(p, ")"); + + return p; +} + +#undef KEY +#define KEY enum isl_graft_key +#undef KEY_ERROR +#define KEY_ERROR isl_graft_key_error +#undef KEY_END +#define KEY_END isl_graft_key_end +#undef KEY_STR +#define KEY_STR key_str +#undef KEY_EXTRACT +#define KEY_EXTRACT extract_key +#undef KEY_GET +#define KEY_GET get_key +#include "extract_key.c" + +/* Read the key "key" from "s", along with the subsequent colon. + */ +static isl_stat read_key(__isl_keep isl_stream *s, enum isl_graft_key key) +{ + enum isl_graft_key extracted; + + extracted = get_key(s); + if (extracted < 0) + return isl_stat_error; + if (extracted != key) + isl_die(isl_stream_get_ctx(s), isl_error_invalid, + "expecting different field", return isl_stat_error); + if (isl_stream_eat(s, ':') < 0) + return isl_stat_error; + return isl_stat_ok; +} + +/* Read an isl_ast_graft object from "s". + * + * Read the pieces in the way they are printed in isl_printer_print_ast_graft. + */ +static __isl_give isl_ast_graft *isl_stream_read_ast_graft( + __isl_keep isl_stream *s) +{ + isl_set *guard; + isl_basic_set *enforced = NULL; + isl_ast_node *node = NULL; + + if (isl_stream_eat(s, '(') < 0) + return NULL; + if (read_key(s, isl_graft_key_guard) < 0) + return NULL; + guard = isl_stream_read_set(s); + if (!guard) + goto error; + if (isl_stream_eat(s, ',') < 0) + goto error; + if (read_key(s, isl_graft_key_enforced) < 0) + goto error; + enforced = isl_stream_read_basic_set(s); + if (!enforced) + goto error; + if (isl_stream_eat(s, ',') < 0) + goto error; + if (read_key(s, isl_graft_key_node) < 0) + goto error; + node = isl_stream_read_ast_node(s); + if (!node) + goto error; + if (isl_stream_eat(s, ')') < 0) + goto error; + return graft_alloc(node, guard, enforced); +error: + isl_set_free(guard); + isl_basic_set_free(enforced); + isl_ast_node_free(node); + return NULL; +} diff --git a/external/mit/isl/dist/isl_ast_graft_private.h b/external/mit/isl/dist/isl_ast_graft_private.h new file mode 100644 index 000000000000..5bf010b882a9 --- /dev/null +++ b/external/mit/isl/dist/isl_ast_graft_private.h @@ -0,0 +1,108 @@ +#ifndef ISL_AST_GRAFT_PRIVATE_H +#define ISL_AST_GRAFT_PRIVATE_H + +#include +#include +#include +#include +#include +#include + +struct isl_ast_graft; +typedef struct isl_ast_graft isl_ast_graft; + +/* Representation of part of an AST ("node") with some additional polyhedral + * information about the tree. + * + * "guard" contains conditions that should still be enforced by + * some ancestor of the current tree. In particular, the already + * generated tree assumes that these conditions hold, but may not + * have enforced them itself. + * The guard should not contain any unknown divs as it will be used + * to generate an if condition. + * + * "enforced" expresses constraints that are already enforced by the for + * nodes in the current tree and that therefore do not need to be enforced + * by any ancestor. + * The constraints only involve outer loop iterators. + */ +struct isl_ast_graft { + int ref; + + isl_ast_node *node; + + isl_set *guard; + isl_basic_set *enforced; +}; + +ISL_DECLARE_LIST(ast_graft) + +#undef EL +#define EL isl_ast_graft + +#include + +isl_ctx *isl_ast_graft_get_ctx(__isl_keep isl_ast_graft *graft); + +__isl_give isl_ast_graft *isl_ast_graft_alloc( + __isl_take isl_ast_node *node, __isl_keep isl_ast_build *build); +__isl_give isl_ast_graft *isl_ast_graft_alloc_from_children( + __isl_take isl_ast_graft_list *list, __isl_take isl_set *guard, + __isl_take isl_basic_set *enforced, __isl_keep isl_ast_build *build, + __isl_keep isl_ast_build *sub_build); +__isl_give isl_ast_graft_list *isl_ast_graft_list_fuse( + __isl_take isl_ast_graft_list *children, + __isl_keep isl_ast_build *build); +__isl_give isl_ast_graft *isl_ast_graft_alloc_domain( + __isl_take isl_map *schedule, __isl_keep isl_ast_build *build); +__isl_null isl_ast_graft *isl_ast_graft_free(__isl_take isl_ast_graft *graft); +__isl_give isl_ast_graft_list *isl_ast_graft_list_sort_guard( + __isl_take isl_ast_graft_list *list); + +__isl_give isl_ast_graft_list *isl_ast_graft_list_merge( + __isl_take isl_ast_graft_list *list1, + __isl_take isl_ast_graft_list *list2, + __isl_keep isl_ast_build *build); +__isl_give isl_ast_graft_list *isl_ast_graft_list_group_on_guard( + __isl_take isl_ast_graft_list *list, __isl_keep isl_ast_build *build); + +__isl_give isl_ast_node *isl_ast_graft_get_node( + __isl_keep isl_ast_graft *graft); +__isl_give isl_basic_set *isl_ast_graft_get_enforced( + __isl_keep isl_ast_graft *graft); +__isl_give isl_set *isl_ast_graft_get_guard(__isl_keep isl_ast_graft *graft); + +__isl_give isl_ast_graft *isl_ast_graft_insert_for( + __isl_take isl_ast_graft *graft, __isl_take isl_ast_node *node); +__isl_give isl_ast_graft *isl_ast_graft_add_guard( + __isl_take isl_ast_graft *graft, + __isl_take isl_set *guard, __isl_keep isl_ast_build *build); +__isl_give isl_ast_graft *isl_ast_graft_enforce( + __isl_take isl_ast_graft *graft, __isl_take isl_basic_set *enforced); + +__isl_give isl_ast_graft *isl_ast_graft_insert_mark( + __isl_take isl_ast_graft *graft, __isl_take isl_id *mark); + +__isl_give isl_ast_graft_list *isl_ast_graft_list_unembed( + __isl_take isl_ast_graft_list *list, int product); +__isl_give isl_ast_graft_list *isl_ast_graft_list_preimage_multi_aff( + __isl_take isl_ast_graft_list *list, __isl_take isl_multi_aff *ma); +__isl_give isl_ast_graft_list *isl_ast_graft_list_insert_pending_guard_nodes( + __isl_take isl_ast_graft_list *list, __isl_keep isl_ast_build *build); + +__isl_give isl_ast_node *isl_ast_node_from_graft_list( + __isl_take isl_ast_graft_list *list, __isl_keep isl_ast_build *build); + +__isl_give isl_basic_set *isl_ast_graft_list_extract_shared_enforced( + __isl_keep isl_ast_graft_list *list, __isl_keep isl_ast_build *build); +__isl_give isl_set *isl_ast_graft_list_extract_hoistable_guard( + __isl_keep isl_ast_graft_list *list, __isl_keep isl_ast_build *build); +__isl_give isl_ast_graft_list *isl_ast_graft_list_gist_guards( + __isl_take isl_ast_graft_list *list, __isl_take isl_set *context); + +__isl_give isl_printer *isl_printer_print_ast_graft(__isl_take isl_printer *p, + __isl_keep isl_ast_graft *graft); + +__isl_give isl_ast_graft_list *isl_stream_read_ast_graft_list(isl_stream *s); + +#endif diff --git a/external/mit/isl/dist/isl_ast_node_set_field_templ.c b/external/mit/isl/dist/isl_ast_node_set_field_templ.c new file mode 100644 index 000000000000..6eed55bbdd42 --- /dev/null +++ b/external/mit/isl/dist/isl_ast_node_set_field_templ.c @@ -0,0 +1,41 @@ +/* + * Copyright 2012 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 + */ + +#define xFN(TYPE,NAME) TYPE ## _ ## NAME +#define FN(TYPE,NAME) xFN(TYPE,NAME) + +/* Replace the field FIELD of "node" by "field", + * where the field may or may not have already been set in "node". + * However, if the field has not already been set, + * then "node" is required to have a single reference. + * In this case the call to isl_ast_node_cow has no effect. + */ +__isl_give isl_ast_node *FN(FN(FN(isl_ast_node,NODE_TYPE),set),FIELD_NAME)( + __isl_take isl_ast_node *node, __isl_take FIELD_TYPE *field) +{ + if (FN(isl_ast_node_check,NODE_TYPE)(node) < 0 || !field) + goto error; + if (node->FIELD == field) { + FN(FIELD_TYPE,free)(field); + return node; + } + + node = isl_ast_node_cow(node); + if (!node) + goto error; + + FN(FIELD_TYPE,free)(node->FIELD); + node->FIELD = field; + + return node; +error: + isl_ast_node_free(node); + FN(FIELD_TYPE,free)(field); + return NULL; +} diff --git a/external/mit/isl/dist/isl_ast_private.h b/external/mit/isl/dist/isl_ast_private.h new file mode 100644 index 000000000000..8bff794c0c48 --- /dev/null +++ b/external/mit/isl/dist/isl_ast_private.h @@ -0,0 +1,134 @@ +#ifndef ISL_AST_PRIVATE_H +#define ISL_AST_PRIVATE_H + +#include +#include +#include +#include +#include +#include +#include + +#undef EL +#define EL isl_ast_expr + +#include + +/* An expression is either an integer, an identifier or an operation + * with zero or more arguments. + */ +struct isl_ast_expr { + int ref; + + isl_ctx *ctx; + + enum isl_ast_expr_type type; + + union { + isl_val *v; + isl_id *id; + struct { + enum isl_ast_expr_op_type op; + isl_ast_expr_list *args; + } op; + } u; +}; + +__isl_give isl_ast_expr *isl_ast_expr_alloc_int_si(isl_ctx *ctx, int i); +__isl_give isl_ast_expr *isl_ast_expr_alloc_op(isl_ctx *ctx, + enum isl_ast_expr_op_type op, int n_arg); +__isl_give isl_ast_expr *isl_ast_expr_op_add_arg(__isl_take isl_ast_expr *expr, + __isl_take isl_ast_expr *arg); +__isl_give isl_ast_expr *isl_ast_expr_alloc_binary( + enum isl_ast_expr_op_type type, + __isl_take isl_ast_expr *expr1, __isl_take isl_ast_expr *expr2); + +__isl_give isl_ast_expr *isl_stream_read_ast_expr(__isl_keep isl_stream *s); + +#undef EL +#define EL isl_ast_node + +#include + +/* A node is either a block, an if, a for, a user node or a mark node. + * "else_node" is NULL if the if node does not have an else branch. + * "cond" and "inc" are NULL for degenerate for nodes. + * In case of a mark node, "mark" is the mark and "node" is the marked node. + */ +struct isl_ast_node { + int ref; + + isl_ctx *ctx; + enum isl_ast_node_type type; + + union { + struct { + isl_ast_node_list *children; + } b; + struct { + isl_ast_expr *guard; + isl_ast_node *then; + isl_ast_node *else_node; + } i; + struct { + unsigned degenerate : 1; + isl_ast_expr *iterator; + isl_ast_expr *init; + isl_ast_expr *cond; + isl_ast_expr *inc; + isl_ast_node *body; + } f; + struct { + isl_ast_expr *expr; + } e; + struct { + isl_id *mark; + isl_ast_node *node; + } m; + } u; + + isl_id *annotation; +}; + +__isl_give isl_ast_node *isl_ast_node_alloc_for(__isl_take isl_id *id); +__isl_give isl_ast_node *isl_ast_node_for_mark_degenerate( + __isl_take isl_ast_node *node); +__isl_give isl_ast_node *isl_ast_node_alloc_if(__isl_take isl_ast_expr *guard); +__isl_give isl_ast_node *isl_ast_node_alloc_block( + __isl_take isl_ast_node_list *list); +__isl_give isl_ast_node *isl_ast_node_alloc_mark(__isl_take isl_id *id, + __isl_take isl_ast_node *node); +__isl_give isl_ast_node *isl_ast_node_from_ast_node_list( + __isl_take isl_ast_node_list *list); +__isl_give isl_ast_node *isl_ast_node_for_set_init( + __isl_take isl_ast_node *node, __isl_take isl_ast_expr *init); +__isl_give isl_ast_node *isl_ast_node_for_set_cond( + __isl_take isl_ast_node *node, __isl_take isl_ast_expr *init); +__isl_give isl_ast_node *isl_ast_node_for_set_inc( + __isl_take isl_ast_node *node, __isl_take isl_ast_expr *init); +__isl_give isl_ast_node *isl_ast_node_for_set_body( + __isl_take isl_ast_node *node, __isl_take isl_ast_node *body); +__isl_give isl_ast_node *isl_ast_node_if_set_then( + __isl_take isl_ast_node *node, __isl_take isl_ast_node *child); + +__isl_give isl_ast_node *isl_stream_read_ast_node(__isl_keep isl_stream *s); + +struct isl_ast_print_options { + int ref; + isl_ctx *ctx; + + __isl_give isl_printer *(*print_for)(__isl_take isl_printer *p, + __isl_take isl_ast_print_options *options, + __isl_keep isl_ast_node *node, void *user); + void *print_for_user; + __isl_give isl_printer *(*print_user)(__isl_take isl_printer *p, + __isl_take isl_ast_print_options *options, + __isl_keep isl_ast_node *node, void *user); + void *print_user_user; +}; + +__isl_give isl_printer *isl_ast_node_list_print( + __isl_keep isl_ast_node_list *list, __isl_take isl_printer *p, + __isl_keep isl_ast_print_options *options); + +#endif diff --git a/external/mit/isl/dist/isl_basis_reduction.h b/external/mit/isl/dist/isl_basis_reduction.h new file mode 100644 index 000000000000..2517c2f16057 --- /dev/null +++ b/external/mit/isl/dist/isl_basis_reduction.h @@ -0,0 +1,27 @@ +/* + * 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_BASIS_REDUCTION_H +#define ISL_BASIS_REDUCTION_H + +#include +#include +#include "isl_tab.h" + +#if defined(__cplusplus) +extern "C" { +#endif + +struct isl_tab *isl_tab_compute_reduced_basis(struct isl_tab *tab); + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/external/mit/isl/dist/isl_bernstein.c b/external/mit/isl/dist/isl_bernstein.c new file mode 100644 index 000000000000..eddea8346e1e --- /dev/null +++ b/external/mit/isl/dist/isl_bernstein.c @@ -0,0 +1,583 @@ +/* + * Copyright 2006-2007 Universiteit Leiden + * Copyright 2008-2009 Katholieke Universiteit Leuven + * Copyright 2010 INRIA Saclay + * + * Use of this software is governed by the MIT license + * + * Written by Sven Verdoolaege, Leiden Institute of Advanced Computer Science, + * Universiteit Leiden, Niels Bohrweg 1, 2333 CA Leiden, The Netherlands + * and 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 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct bernstein_data { + enum isl_fold type; + isl_qpolynomial *poly; + int check_tight; + + isl_cell *cell; + + isl_qpolynomial_fold *fold; + isl_qpolynomial_fold *fold_tight; + isl_pw_qpolynomial_fold *pwf; + isl_pw_qpolynomial_fold *pwf_tight; +}; + +static isl_bool vertex_is_integral(__isl_keep isl_basic_set *vertex) +{ + isl_size nvar; + isl_size nparam; + int i; + + nvar = isl_basic_set_dim(vertex, isl_dim_set); + nparam = isl_basic_set_dim(vertex, isl_dim_param); + if (nvar < 0 || nparam < 0) + return isl_bool_error; + for (i = 0; i < nvar; ++i) { + int r = nvar - 1 - i; + if (!isl_int_is_one(vertex->eq[r][1 + nparam + i]) && + !isl_int_is_negone(vertex->eq[r][1 + nparam + i])) + return isl_bool_false; + } + + return isl_bool_true; +} + +static __isl_give isl_qpolynomial *vertex_coordinate( + __isl_keep isl_basic_set *vertex, int i, __isl_take isl_space *space) +{ + isl_size nvar; + isl_size nparam; + isl_size total; + int r; + isl_int denom; + isl_qpolynomial *v; + + isl_int_init(denom); + + nvar = isl_basic_set_dim(vertex, isl_dim_set); + nparam = isl_basic_set_dim(vertex, isl_dim_param); + total = isl_basic_set_dim(vertex, isl_dim_all); + if (nvar < 0 || nparam < 0 || total < 0) + goto error; + r = nvar - 1 - i; + + isl_int_set(denom, vertex->eq[r][1 + nparam + i]); + isl_assert(vertex->ctx, !isl_int_is_zero(denom), goto error); + + if (isl_int_is_pos(denom)) + isl_seq_neg(vertex->eq[r], vertex->eq[r], 1 + total); + else + isl_int_neg(denom, denom); + + v = isl_qpolynomial_from_affine(space, vertex->eq[r], denom); + isl_int_clear(denom); + + return v; +error: + isl_space_free(space); + isl_int_clear(denom); + return NULL; +} + +/* Check whether the bound associated to the selection "k" is tight, + * which is the case if we select exactly one vertex (i.e., one of the + * exponents in "k" is exactly "d") and if that vertex + * is integral for all values of the parameters. + * + * If the degree "d" is zero, then there are no exponents. + * Since the polynomial is a constant expression in this case, + * the bound is necessarily tight. + */ +static isl_bool is_tight(int *k, int n, int d, isl_cell *cell) +{ + int i; + + if (d == 0) + return isl_bool_true; + + for (i = 0; i < n; ++i) { + int v; + if (!k[i]) + continue; + if (k[i] != d) + return isl_bool_false; + v = cell->ids[n - 1 - i]; + return vertex_is_integral(cell->vertices->v[v].vertex); + } + + return isl_bool_false; +} + +static isl_stat add_fold(__isl_take isl_qpolynomial *b, __isl_keep isl_set *dom, + int *k, int n, int d, struct bernstein_data *data) +{ + isl_qpolynomial_fold *fold; + isl_bool tight; + + fold = isl_qpolynomial_fold_alloc(data->type, b); + + tight = isl_bool_false; + if (data->check_tight) + tight = is_tight(k, n, d, data->cell); + if (tight < 0) + return isl_stat_error; + if (tight) + data->fold_tight = isl_qpolynomial_fold_fold_on_domain(dom, + data->fold_tight, fold); + else + data->fold = isl_qpolynomial_fold_fold_on_domain(dom, + data->fold, fold); + return isl_stat_ok; +} + +/* Extract the coefficients of the Bernstein base polynomials and store + * them in data->fold and data->fold_tight. + * + * In particular, the coefficient of each monomial + * of multi-degree (k[0], k[1], ..., k[n-1]) is divided by the corresponding + * multinomial coefficient d!/k[0]! k[1]! ... k[n-1]! + * + * c[i] contains the coefficient of the selected powers of the first i+1 vars. + * multinom[i] contains the partial multinomial coefficient. + */ +static isl_stat extract_coefficients(isl_qpolynomial *poly, + __isl_keep isl_set *dom, struct bernstein_data *data) +{ + int i; + int d; + isl_size n; + isl_ctx *ctx; + isl_qpolynomial **c = NULL; + int *k = NULL; + int *left = NULL; + isl_vec *multinom = NULL; + + n = isl_qpolynomial_dim(poly, isl_dim_in); + if (n < 0) + return isl_stat_error; + + ctx = isl_qpolynomial_get_ctx(poly); + d = isl_qpolynomial_degree(poly); + isl_assert(ctx, n >= 2, return isl_stat_error); + + c = isl_calloc_array(ctx, isl_qpolynomial *, n); + k = isl_alloc_array(ctx, int, n); + left = isl_alloc_array(ctx, int, n); + multinom = isl_vec_alloc(ctx, n); + if (!c || !k || !left || !multinom) + goto error; + + isl_int_set_si(multinom->el[0], 1); + for (k[0] = d; k[0] >= 0; --k[0]) { + int i = 1; + isl_qpolynomial_free(c[0]); + c[0] = isl_qpolynomial_coeff(poly, isl_dim_in, n - 1, k[0]); + left[0] = d - k[0]; + k[1] = -1; + isl_int_set(multinom->el[1], multinom->el[0]); + while (i > 0) { + if (i == n - 1) { + int j; + isl_space *space; + isl_qpolynomial *b; + isl_qpolynomial *f; + for (j = 2; j <= left[i - 1]; ++j) + isl_int_divexact_ui(multinom->el[i], + multinom->el[i], j); + b = isl_qpolynomial_coeff(c[i - 1], isl_dim_in, + n - 1 - i, left[i - 1]); + b = isl_qpolynomial_project_domain_on_params(b); + space = isl_qpolynomial_get_domain_space(b); + f = isl_qpolynomial_rat_cst_on_domain(space, + ctx->one, multinom->el[i]); + b = isl_qpolynomial_mul(b, f); + k[n - 1] = left[n - 2]; + if (add_fold(b, dom, k, n, d, data) < 0) + goto error; + --i; + continue; + } + if (k[i] >= left[i - 1]) { + --i; + continue; + } + ++k[i]; + if (k[i]) + isl_int_divexact_ui(multinom->el[i], + multinom->el[i], k[i]); + isl_qpolynomial_free(c[i]); + c[i] = isl_qpolynomial_coeff(c[i - 1], isl_dim_in, + n - 1 - i, k[i]); + left[i] = left[i - 1] - k[i]; + k[i + 1] = -1; + isl_int_set(multinom->el[i + 1], multinom->el[i]); + ++i; + } + isl_int_mul_ui(multinom->el[0], multinom->el[0], k[0]); + } + + for (i = 0; i < n; ++i) + isl_qpolynomial_free(c[i]); + + isl_vec_free(multinom); + free(left); + free(k); + free(c); + return isl_stat_ok; +error: + isl_vec_free(multinom); + free(left); + free(k); + if (c) + for (i = 0; i < n; ++i) + isl_qpolynomial_free(c[i]); + free(c); + return isl_stat_error; +} + +/* Perform bernstein expansion on the parametric vertices that are active + * on "cell". + * + * data->poly has been homogenized in the calling function. + * + * We plug in the barycentric coordinates for the set variables + * + * \vec x = \sum_i \alpha_i v_i(\vec p) + * + * and the constant "1 = \sum_i \alpha_i" for the homogeneous dimension. + * Next, we extract the coefficients of the Bernstein base polynomials. + */ +static isl_stat bernstein_coefficients_cell(__isl_take isl_cell *cell, + void *user) +{ + int i, j; + struct bernstein_data *data = (struct bernstein_data *)user; + isl_space *space_param; + isl_space *space_dst; + isl_qpolynomial *poly = data->poly; + isl_size n_in; + unsigned nvar; + int n_vertices; + isl_qpolynomial **subs; + isl_pw_qpolynomial_fold *pwf; + isl_set *dom; + isl_ctx *ctx; + + n_in = isl_qpolynomial_dim(poly, isl_dim_in); + if (n_in < 0) + goto error; + + nvar = n_in - 1; + n_vertices = cell->n_vertices; + + ctx = isl_qpolynomial_get_ctx(poly); + if (n_vertices > nvar + 1 && ctx->opt->bernstein_triangulate) + return isl_cell_foreach_simplex(cell, + &bernstein_coefficients_cell, user); + + subs = isl_alloc_array(ctx, isl_qpolynomial *, 1 + nvar); + if (!subs) + goto error; + + space_param = isl_basic_set_get_space(cell->dom); + space_dst = isl_qpolynomial_get_domain_space(poly); + space_dst = isl_space_add_dims(space_dst, isl_dim_set, n_vertices); + + for (i = 0; i < 1 + nvar; ++i) + subs[i] = + isl_qpolynomial_zero_on_domain(isl_space_copy(space_dst)); + + for (i = 0; i < n_vertices; ++i) { + isl_qpolynomial *c; + c = isl_qpolynomial_var_on_domain(isl_space_copy(space_dst), + isl_dim_set, 1 + nvar + i); + for (j = 0; j < nvar; ++j) { + int k = cell->ids[i]; + isl_qpolynomial *v; + v = vertex_coordinate(cell->vertices->v[k].vertex, j, + isl_space_copy(space_param)); + v = isl_qpolynomial_add_dims(v, isl_dim_in, + 1 + nvar + n_vertices); + v = isl_qpolynomial_mul(v, isl_qpolynomial_copy(c)); + subs[1 + j] = isl_qpolynomial_add(subs[1 + j], v); + } + subs[0] = isl_qpolynomial_add(subs[0], c); + } + isl_space_free(space_dst); + + poly = isl_qpolynomial_copy(poly); + + poly = isl_qpolynomial_add_dims(poly, isl_dim_in, n_vertices); + poly = isl_qpolynomial_substitute(poly, isl_dim_in, 0, 1 + nvar, subs); + poly = isl_qpolynomial_drop_dims(poly, isl_dim_in, 0, 1 + nvar); + + data->cell = cell; + dom = isl_set_from_basic_set(isl_basic_set_copy(cell->dom)); + data->fold = isl_qpolynomial_fold_empty(data->type, + isl_space_copy(space_param)); + data->fold_tight = isl_qpolynomial_fold_empty(data->type, space_param); + if (extract_coefficients(poly, dom, data) < 0) { + data->fold = isl_qpolynomial_fold_free(data->fold); + data->fold_tight = isl_qpolynomial_fold_free(data->fold_tight); + } + + pwf = isl_pw_qpolynomial_fold_alloc(data->type, isl_set_copy(dom), + data->fold); + data->pwf = isl_pw_qpolynomial_fold_fold(data->pwf, pwf); + pwf = isl_pw_qpolynomial_fold_alloc(data->type, dom, data->fold_tight); + data->pwf_tight = isl_pw_qpolynomial_fold_fold(data->pwf_tight, pwf); + + isl_qpolynomial_free(poly); + isl_cell_free(cell); + for (i = 0; i < 1 + nvar; ++i) + isl_qpolynomial_free(subs[i]); + free(subs); + return isl_stat_ok; +error: + isl_cell_free(cell); + return isl_stat_error; +} + +/* Base case of applying bernstein expansion. + * + * We compute the chamber decomposition of the parametric polytope "bset" + * and then perform bernstein expansion on the parametric vertices + * that are active on each chamber. + * + * If the polynomial does not depend on the set variables + * (and in particular if the number of set variables is zero) + * then the bound is equal to the polynomial and + * no actual bernstein expansion needs to be performed. + */ +static __isl_give isl_pw_qpolynomial_fold *bernstein_coefficients_base( + __isl_take isl_basic_set *bset, + __isl_take isl_qpolynomial *poly, struct bernstein_data *data, + isl_bool *tight) +{ + int degree; + isl_size nvar; + isl_space *space; + isl_vertices *vertices; + isl_bool covers; + + nvar = isl_basic_set_dim(bset, isl_dim_set); + if (nvar < 0) + bset = isl_basic_set_free(bset); + if (nvar == 0) + return isl_qpolynomial_cst_bound(bset, poly, data->type, tight); + + degree = isl_qpolynomial_degree(poly); + if (degree < -1) + bset = isl_basic_set_free(bset); + if (degree <= 0) + return isl_qpolynomial_cst_bound(bset, poly, data->type, tight); + + space = isl_basic_set_get_space(bset); + space = isl_space_params(space); + space = isl_space_from_domain(space); + space = isl_space_add_dims(space, isl_dim_set, 1); + data->pwf = isl_pw_qpolynomial_fold_zero(isl_space_copy(space), + data->type); + data->pwf_tight = isl_pw_qpolynomial_fold_zero(space, data->type); + data->poly = isl_qpolynomial_homogenize(isl_qpolynomial_copy(poly)); + vertices = isl_basic_set_compute_vertices(bset); + if (isl_vertices_foreach_disjoint_cell(vertices, + &bernstein_coefficients_cell, data) < 0) + data->pwf = isl_pw_qpolynomial_fold_free(data->pwf); + isl_vertices_free(vertices); + isl_qpolynomial_free(data->poly); + + isl_basic_set_free(bset); + isl_qpolynomial_free(poly); + + covers = isl_pw_qpolynomial_fold_covers(data->pwf_tight, data->pwf); + if (covers < 0) + goto error; + + if (tight) + *tight = covers; + + if (covers) { + isl_pw_qpolynomial_fold_free(data->pwf); + return data->pwf_tight; + } + + data->pwf = isl_pw_qpolynomial_fold_fold(data->pwf, data->pwf_tight); + + return data->pwf; +error: + isl_pw_qpolynomial_fold_free(data->pwf_tight); + isl_pw_qpolynomial_fold_free(data->pwf); + return NULL; +} + +/* Apply bernstein expansion recursively by working in on len[i] + * set variables at a time, with i ranging from n_group - 1 to 0. + */ +static __isl_give isl_pw_qpolynomial_fold *bernstein_coefficients_recursive( + __isl_take isl_pw_qpolynomial *pwqp, + int n_group, int *len, struct bernstein_data *data, isl_bool *tight) +{ + int i; + isl_size nparam; + isl_size nvar; + isl_pw_qpolynomial_fold *pwf; + + nparam = isl_pw_qpolynomial_dim(pwqp, isl_dim_param); + nvar = isl_pw_qpolynomial_dim(pwqp, isl_dim_in); + if (nparam < 0 || nvar < 0) + goto error; + + pwqp = isl_pw_qpolynomial_move_dims(pwqp, isl_dim_param, nparam, + isl_dim_in, 0, nvar - len[n_group - 1]); + pwf = isl_pw_qpolynomial_bound(pwqp, data->type, tight); + + for (i = n_group - 2; i >= 0; --i) { + nparam = isl_pw_qpolynomial_fold_dim(pwf, isl_dim_param); + if (nparam < 0) + return isl_pw_qpolynomial_fold_free(pwf); + pwf = isl_pw_qpolynomial_fold_move_dims(pwf, isl_dim_in, 0, + isl_dim_param, nparam - len[i], len[i]); + if (tight && !*tight) + tight = NULL; + pwf = isl_pw_qpolynomial_fold_bound(pwf, tight); + } + + return pwf; +error: + isl_pw_qpolynomial_free(pwqp); + return NULL; +} + +static __isl_give isl_pw_qpolynomial_fold *bernstein_coefficients_factors( + __isl_take isl_basic_set *bset, + __isl_take isl_qpolynomial *poly, struct bernstein_data *data, + isl_bool *tight) +{ + isl_factorizer *f; + isl_set *set; + isl_pw_qpolynomial *pwqp; + isl_pw_qpolynomial_fold *pwf; + + f = isl_basic_set_factorizer(bset); + if (!f) + goto error; + if (f->n_group == 0) { + isl_factorizer_free(f); + return bernstein_coefficients_base(bset, poly, data, tight); + } + + set = isl_set_from_basic_set(bset); + pwqp = isl_pw_qpolynomial_alloc(set, poly); + pwqp = isl_pw_qpolynomial_morph_domain(pwqp, isl_morph_copy(f->morph)); + + pwf = bernstein_coefficients_recursive(pwqp, f->n_group, f->len, data, + tight); + + isl_factorizer_free(f); + + return pwf; +error: + isl_basic_set_free(bset); + isl_qpolynomial_free(poly); + return NULL; +} + +static __isl_give isl_pw_qpolynomial_fold *bernstein_coefficients_full_recursive( + __isl_take isl_basic_set *bset, + __isl_take isl_qpolynomial *poly, struct bernstein_data *data, + isl_bool *tight) +{ + int i; + int *len; + isl_size nvar; + isl_pw_qpolynomial_fold *pwf; + isl_set *set; + isl_pw_qpolynomial *pwqp; + + nvar = isl_basic_set_dim(bset, isl_dim_set); + if (nvar < 0 || !poly) + goto error; + + len = isl_alloc_array(bset->ctx, int, nvar); + if (nvar && !len) + goto error; + + for (i = 0; i < nvar; ++i) + len[i] = 1; + + set = isl_set_from_basic_set(bset); + pwqp = isl_pw_qpolynomial_alloc(set, poly); + + pwf = bernstein_coefficients_recursive(pwqp, nvar, len, data, tight); + + free(len); + + return pwf; +error: + isl_basic_set_free(bset); + isl_qpolynomial_free(poly); + return NULL; +} + +/* Compute a bound on the polynomial defined over the parametric polytope + * using bernstein expansion and store the result + * in bound->pwf and bound->pwf_tight. + * + * If bernstein_recurse is set to ISL_BERNSTEIN_FACTORS, we check if + * the polytope can be factorized and apply bernstein expansion recursively + * on the factors. + * If bernstein_recurse is set to ISL_BERNSTEIN_INTERVALS, we apply + * bernstein expansion recursively on each dimension. + * Otherwise, we apply bernstein expansion on the entire polytope. + */ +isl_stat isl_qpolynomial_bound_on_domain_bernstein( + __isl_take isl_basic_set *bset, __isl_take isl_qpolynomial *poly, + struct isl_bound *bound) +{ + struct bernstein_data data; + isl_pw_qpolynomial_fold *pwf; + isl_size nvar; + isl_bool tight = isl_bool_false; + isl_bool *tp = bound->check_tight ? &tight : NULL; + + nvar = isl_basic_set_dim(bset, isl_dim_set); + if (nvar < 0 || !poly) + goto error; + + data.type = bound->type; + data.check_tight = bound->check_tight; + + if (bset->ctx->opt->bernstein_recurse & ISL_BERNSTEIN_FACTORS) + pwf = bernstein_coefficients_factors(bset, poly, &data, tp); + else if (nvar > 1 && + (bset->ctx->opt->bernstein_recurse & ISL_BERNSTEIN_INTERVALS)) + pwf = bernstein_coefficients_full_recursive(bset, poly, &data, tp); + else + pwf = bernstein_coefficients_base(bset, poly, &data, tp); + + if (tight) + return isl_bound_add_tight(bound, pwf); + else + return isl_bound_add(bound, pwf); +error: + isl_basic_set_free(bset); + isl_qpolynomial_free(poly); + return isl_stat_error; +} diff --git a/external/mit/isl/dist/isl_bernstein.h b/external/mit/isl/dist/isl_bernstein.h new file mode 100644 index 000000000000..ca11df4bf0f7 --- /dev/null +++ b/external/mit/isl/dist/isl_bernstein.h @@ -0,0 +1,5 @@ +#include + +isl_stat isl_qpolynomial_bound_on_domain_bernstein( + __isl_take isl_basic_set *bset, __isl_take isl_qpolynomial *poly, + struct isl_bound *bound); diff --git a/external/mit/isl/dist/isl_bind_domain_templ.c b/external/mit/isl/dist/isl_bind_domain_templ.c new file mode 100644 index 000000000000..06cbf07c7ef7 --- /dev/null +++ b/external/mit/isl/dist/isl_bind_domain_templ.c @@ -0,0 +1,168 @@ +/* + * Copyright 2018 Cerebras Systems + * + * Use of this software is governed by the MIT license + * + * Written by Sven Verdoolaege, + * Cerebras Systems, 175 S San Antonio Rd, Los Altos, CA, USA + */ + +#include + +/* Merge parameter "param" into the input dimension "i" of "obj". + * + * First plug in the parameter for the input dimension in "obj". + * The drop the (now defunct) input dimension and + * move the parameter in its original position. + * Since dimension manipulations destroy spaces, modify the space + * separately by only dropping the parameter. + */ +static __isl_give TYPE *FN(TYPE,merge_param)(__isl_take TYPE *obj, int i, + int param) +{ + isl_id *id; + isl_aff *aff; + isl_space *space; + isl_multi_aff *ma; + + space = FN(TYPE,get_domain_space)(obj); + id = isl_space_get_dim_id(space, isl_dim_param, param); + aff = isl_aff_param_on_domain_space_id(isl_space_copy(space), id); + space = isl_space_map_from_set(space); + ma = isl_multi_aff_identity(space); + ma = isl_multi_aff_set_aff(ma, i, aff); + obj = FN(TYPE,pullback_multi_aff)(obj, ma); + space = FN(TYPE,get_domain_space)(obj); + obj = FN(TYPE,drop_dims)(obj, isl_dim_in, i, 1); + obj = FN(TYPE,move_dims)(obj, isl_dim_in, i, isl_dim_param, param, 1); + space = isl_space_drop_dims(space, isl_dim_param, param, 1); + obj = FN(TYPE,reset_domain_space)(obj, space); + + return obj; +} + +/* Given a tuple of identifiers "tuple" that correspond + * to the initial input dimensions of "obj", + * if any of those identifiers appear as parameters + * in "obj", then equate those parameters with the corresponding + * input dimensions and project out the parameters. + * The result therefore has no such parameters. + */ +static __isl_give TYPE *FN(TYPE,equate_initial_params)(__isl_take TYPE *obj, + __isl_keep isl_multi_id *tuple) +{ + int i; + isl_size n; + + n = isl_multi_id_size(tuple); + if (n < 0) + return FN(TYPE,free)(obj); + for (i = 0; i < n; ++i) { + isl_id *id; + int pos; + + id = isl_multi_id_get_at(tuple, i); + if (!id) + return FN(TYPE,free)(obj); + pos = FN(TYPE,find_dim_by_id)(obj, isl_dim_param, id); + isl_id_free(id); + if (pos < 0) + continue; + obj = FN(TYPE,merge_param)(obj, i, pos); + } + + return obj; +} + +/* Given a tuple of identifiers "tuple" in a space that corresponds + * to the domain of "obj", if any of those identifiers appear as parameters + * in "obj", then equate those parameters with the corresponding + * input dimensions and project out the parameters. + * The result therefore has no such parameters. + */ +static __isl_give TYPE *FN(TYPE,equate_domain_params)(__isl_take TYPE *obj, + __isl_keep isl_multi_id *tuple) +{ + isl_stat r; + isl_space *obj_space, *tuple_space; + + obj_space = FN(TYPE,get_space)(obj); + tuple_space = isl_multi_id_peek_space(tuple); + r = isl_space_check_domain_tuples(tuple_space, obj_space); + isl_space_free(obj_space); + if (r < 0) + return FN(TYPE,free)(obj); + + return FN(TYPE,equate_initial_params)(obj, tuple); +} + +/* Bind the domain dimensions of the function "obj" to parameters + * with identifiers specified by "tuple", living in the same space + * as the domain of "obj". + * + * If no parameters with these identifiers appear in "obj" already, + * then the domain dimensions are simply reinterpreted as parameters. + * Otherwise, the parameters are first equated to the corresponding + * domain dimensions. + */ +__isl_give TYPE *FN(TYPE,bind_domain)(__isl_take TYPE *obj, + __isl_take isl_multi_id *tuple) +{ + isl_space *space; + + obj = FN(TYPE,equate_domain_params)(obj, tuple); + space = FN(TYPE,get_space)(obj); + space = isl_space_bind_map_domain(space, tuple); + isl_multi_id_free(tuple); + obj = FN(TYPE,reset_space)(obj, space); + + return obj; +} + +/* Given a tuple of identifiers "tuple" in a space that corresponds + * to the domain of the wrapped relation in the domain of "obj", + * if any of those identifiers appear as parameters + * in "obj", then equate those parameters with the corresponding + * input dimensions and project out the parameters. + * The result therefore has no such parameters. + */ +static __isl_give TYPE *FN(TYPE,equate_domain_wrapped_domain_params)( + __isl_take TYPE *obj, __isl_keep isl_multi_id *tuple) +{ + isl_stat r; + isl_space *obj_space, *tuple_space; + + obj_space = FN(TYPE,get_space)(obj); + tuple_space = isl_multi_id_peek_space(tuple); + r = isl_space_check_domain_wrapped_domain_tuples(tuple_space, + obj_space); + isl_space_free(obj_space); + if (r < 0) + return FN(TYPE,free)(obj); + + return FN(TYPE,equate_initial_params)(obj, tuple); +} + +/* Given a function living in a space of the form [A -> B] -> C and + * a tuple of identifiers in A, bind the domain dimensions of the relation + * wrapped in the domain of "obj" with identifiers specified by "tuple", + * returning a function in the space B -> C. + * + * If no parameters with these identifiers appear in "obj" already, + * then the domain dimensions are simply reinterpreted as parameters. + * Otherwise, the parameters are first equated to the corresponding + * domain dimensions. + */ +__isl_give TYPE *FN(TYPE,bind_domain_wrapped_domain)(__isl_take TYPE *obj, + __isl_take isl_multi_id *tuple) +{ + isl_space *space; + + obj = FN(TYPE,equate_domain_wrapped_domain_params)(obj, tuple); + space = FN(TYPE,get_space)(obj); + space = isl_space_bind_domain_wrapped_domain(space, tuple); + isl_multi_id_free(tuple); + obj = FN(TYPE,reset_space)(obj, space); + + return obj; +} diff --git a/external/mit/isl/dist/isl_blk.c b/external/mit/isl/dist/isl_blk.c new file mode 100644 index 000000000000..0b03ecf0dd3c --- /dev/null +++ b/external/mit/isl/dist/isl_blk.c @@ -0,0 +1,134 @@ +/* + * 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 + */ + +#include +#include + +/* The maximal number of cache misses before first element is evicted */ +#define ISL_BLK_MAX_MISS 100 + +struct isl_blk isl_blk_empty() +{ + struct isl_blk block; + block.size = 0; + block.data = NULL; + return block; +} + +static int isl_blk_is_empty(struct isl_blk block) +{ + return block.size == 0 && block.data == NULL; +} + +static struct isl_blk isl_blk_error() +{ + struct isl_blk block; + block.size = -1; + block.data = NULL; + return block; +} + +int isl_blk_is_error(struct isl_blk block) +{ + return block.size == -1 && block.data == NULL; +} + +static void isl_blk_free_force(struct isl_ctx *ctx, struct isl_blk block) +{ + int i; + + for (i = 0; i < block.size; ++i) + isl_int_clear(block.data[i]); + free(block.data); +} + +static struct isl_blk extend(struct isl_ctx *ctx, struct isl_blk block, + size_t new_n) +{ + int i; + isl_int *p; + + if (block.size >= new_n) + return block; + + p = isl_realloc_array(ctx, block.data, isl_int, new_n); + if (!p) { + isl_blk_free_force(ctx, block); + return isl_blk_error(); + } + block.data = p; + + for (i = block.size; i < new_n; ++i) + isl_int_init(block.data[i]); + block.size = new_n; + + return block; +} + +struct isl_blk isl_blk_alloc(struct isl_ctx *ctx, size_t n) +{ + int i; + struct isl_blk block; + + block = isl_blk_empty(); + if (n && ctx->n_cached) { + int best = 0; + for (i = 1; ctx->cache[best].size != n && i < ctx->n_cached; ++i) { + if (ctx->cache[best].size < n) { + if (ctx->cache[i].size > ctx->cache[best].size) + best = i; + } else if (ctx->cache[i].size >= n && + ctx->cache[i].size < ctx->cache[best].size) + best = i; + } + if (ctx->cache[best].size < 2 * n + 100) { + block = ctx->cache[best]; + if (--ctx->n_cached != best) + ctx->cache[best] = ctx->cache[ctx->n_cached]; + if (best == 0) + ctx->n_miss = 0; + } else if (ctx->n_miss++ >= ISL_BLK_MAX_MISS) { + isl_blk_free_force(ctx, ctx->cache[0]); + if (--ctx->n_cached != 0) + ctx->cache[0] = ctx->cache[ctx->n_cached]; + ctx->n_miss = 0; + } + } + + return extend(ctx, block, n); +} + +struct isl_blk isl_blk_extend(struct isl_ctx *ctx, struct isl_blk block, + size_t new_n) +{ + if (isl_blk_is_empty(block)) + return isl_blk_alloc(ctx, new_n); + + return extend(ctx, block, new_n); +} + +void isl_blk_free(struct isl_ctx *ctx, struct isl_blk block) +{ + if (isl_blk_is_empty(block) || isl_blk_is_error(block)) + return; + + if (ctx->n_cached < ISL_BLK_CACHE_SIZE) + ctx->cache[ctx->n_cached++] = block; + else + isl_blk_free_force(ctx, block); +} + +void isl_blk_clear_cache(struct isl_ctx *ctx) +{ + int i; + + for (i = 0; i < ctx->n_cached; ++i) + isl_blk_free_force(ctx, ctx->cache[i]); + ctx->n_cached = 0; +} diff --git a/external/mit/isl/dist/isl_blk.h b/external/mit/isl/dist/isl_blk.h new file mode 100644 index 000000000000..7756e010ec28 --- /dev/null +++ b/external/mit/isl/dist/isl_blk.h @@ -0,0 +1,40 @@ +/* + * 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_BLK_H +#define ISL_BLK_H + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +struct isl_blk { + size_t size; + isl_int *data; +}; + +#define ISL_BLK_CACHE_SIZE 20 + +struct isl_ctx; + +struct isl_blk isl_blk_alloc(struct isl_ctx *ctx, size_t n); +struct isl_blk isl_blk_empty(void); +int isl_blk_is_error(struct isl_blk block); +struct isl_blk isl_blk_extend(struct isl_ctx *ctx, struct isl_blk block, + size_t new_n); +void isl_blk_free(struct isl_ctx *ctx, struct isl_blk block); +void isl_blk_clear_cache(struct isl_ctx *ctx); + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/external/mit/isl/dist/isl_bound.c b/external/mit/isl/dist/isl_bound.c new file mode 100644 index 000000000000..64247aca052b --- /dev/null +++ b/external/mit/isl/dist/isl_bound.c @@ -0,0 +1,427 @@ +/* + * Copyright 2010 INRIA Saclay + * + * 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 + */ + +#include +#include +#include +#include +#include +#include +#include + +/* Given a polynomial "poly" that is constant in terms + * of the domain variables, construct a polynomial reduction + * of type "type" that is equal to "poly" on "bset", + * with the domain projected onto the parameters. + */ +__isl_give isl_pw_qpolynomial_fold *isl_qpolynomial_cst_bound( + __isl_take isl_basic_set *bset, __isl_take isl_qpolynomial *poly, + enum isl_fold type, isl_bool *tight) +{ + isl_set *dom; + isl_qpolynomial_fold *fold; + isl_pw_qpolynomial_fold *pwf; + + fold = isl_qpolynomial_fold_alloc(type, poly); + dom = isl_set_from_basic_set(bset); + if (tight) + *tight = isl_bool_true; + pwf = isl_pw_qpolynomial_fold_alloc(type, dom, fold); + return isl_pw_qpolynomial_fold_project_domain_on_params(pwf); +} + +/* Add the bound "pwf", which is not known to be tight, + * to the output of "bound". + */ +isl_stat isl_bound_add(struct isl_bound *bound, + __isl_take isl_pw_qpolynomial_fold *pwf) +{ + bound->pwf = isl_pw_qpolynomial_fold_fold(bound->pwf, pwf); + return isl_stat_non_null(bound->pwf); +} + +/* Add the bound "pwf", which is known to be tight, + * to the output of "bound". + */ +isl_stat isl_bound_add_tight(struct isl_bound *bound, + __isl_take isl_pw_qpolynomial_fold *pwf) +{ + bound->pwf_tight = isl_pw_qpolynomial_fold_fold(bound->pwf_tight, pwf); + return isl_stat_non_null(bound->pwf); +} + +/* Given a polynomial "poly" that is constant in terms + * of the domain variables and the domain "bset", + * construct the corresponding polynomial reduction and + * add it to the tight bounds of "bound". + */ +static isl_stat add_constant_poly(__isl_take isl_basic_set *bset, + __isl_take isl_qpolynomial *poly, struct isl_bound *bound) +{ + isl_pw_qpolynomial_fold *pwf; + + pwf = isl_qpolynomial_cst_bound(bset, poly, bound->type, NULL); + return isl_bound_add_tight(bound, pwf); +} + +/* Compute a bound on the polynomial defined over the parametric polytope + * using either range propagation or bernstein expansion and + * store the result in bound->pwf and bound->pwf_tight. + * Since bernstein expansion requires bounded domains, we apply + * range propagation on unbounded domains. Otherwise, we respect the choice + * of the user. + * + * If the polynomial does not depend on the set variables + * then the bound is equal to the polynomial and + * it can be added to "bound" directly. + */ +static isl_stat compressed_guarded_poly_bound(__isl_take isl_basic_set *bset, + __isl_take isl_qpolynomial *poly, void *user) +{ + struct isl_bound *bound = (struct isl_bound *)user; + isl_ctx *ctx; + int bounded; + int degree; + + if (!bset || !poly) + goto error; + + degree = isl_qpolynomial_degree(poly); + if (degree < -1) + goto error; + if (degree <= 0) + return add_constant_poly(bset, poly, bound); + + ctx = isl_basic_set_get_ctx(bset); + if (ctx->opt->bound == ISL_BOUND_RANGE) + return isl_qpolynomial_bound_on_domain_range(bset, poly, bound); + + bounded = isl_basic_set_is_bounded(bset); + if (bounded < 0) + goto error; + if (bounded) + return isl_qpolynomial_bound_on_domain_bernstein(bset, poly, bound); + else + return isl_qpolynomial_bound_on_domain_range(bset, poly, bound); +error: + isl_basic_set_free(bset); + isl_qpolynomial_free(poly); + return isl_stat_error; +} + +static isl_stat unwrapped_guarded_poly_bound(__isl_take isl_basic_set *bset, + __isl_take isl_qpolynomial *poly, void *user) +{ + struct isl_bound *bound = (struct isl_bound *)user; + isl_pw_qpolynomial_fold *top_pwf; + isl_pw_qpolynomial_fold *top_pwf_tight; + isl_space *space; + isl_morph *morph; + isl_stat r; + + bset = isl_basic_set_detect_equalities(bset); + + if (!bset) + goto error; + + if (bset->n_eq == 0) + return compressed_guarded_poly_bound(bset, poly, user); + + morph = isl_basic_set_full_compression(bset); + + bset = isl_morph_basic_set(isl_morph_copy(morph), bset); + poly = isl_qpolynomial_morph_domain(poly, isl_morph_copy(morph)); + + space = isl_morph_get_ran_space(morph); + space = isl_space_params(space); + + top_pwf = bound->pwf; + top_pwf_tight = bound->pwf_tight; + + space = isl_space_from_domain(space); + space = isl_space_add_dims(space, isl_dim_out, 1); + bound->pwf = isl_pw_qpolynomial_fold_zero(isl_space_copy(space), + bound->type); + bound->pwf_tight = isl_pw_qpolynomial_fold_zero(space, bound->type); + + r = compressed_guarded_poly_bound(bset, poly, user); + + morph = isl_morph_dom_params(morph); + morph = isl_morph_ran_params(morph); + morph = isl_morph_inverse(morph); + + bound->pwf = isl_pw_qpolynomial_fold_morph_domain(bound->pwf, + isl_morph_copy(morph)); + bound->pwf_tight = isl_pw_qpolynomial_fold_morph_domain( + bound->pwf_tight, morph); + + isl_bound_add(bound, top_pwf); + isl_bound_add_tight(bound, top_pwf_tight); + + return r; +error: + isl_basic_set_free(bset); + isl_qpolynomial_free(poly); + return isl_stat_error; +} + +/* Update bound->pwf and bound->pwf_tight with a bound + * of type bound->type on the polynomial "poly" over the domain "bset". + * + * If the original problem had a wrapped relation in the domain, + * meaning that the bound should be computed over the range + * of this relation, then temporarily treat the domain dimensions + * of this wrapped relation as parameters, compute a bound + * in terms of these and the original parameters, + * turn the parameters back into set dimensions and + * add the results to bound->pwf and bound->pwf_tight. + * + * Note that even though "bset" is known to live in the same space + * as the domain of "poly", the names of the set dimensions + * may be different (or missing). Make sure the naming is exactly + * the same before turning these dimensions into parameters + * to ensure that the spaces are still the same after + * this operation. + */ +static isl_stat guarded_poly_bound(__isl_take isl_basic_set *bset, + __isl_take isl_qpolynomial *poly, void *user) +{ + struct isl_bound *bound = (struct isl_bound *)user; + isl_space *space; + isl_pw_qpolynomial_fold *top_pwf; + isl_pw_qpolynomial_fold *top_pwf_tight; + isl_size nparam; + isl_size n_in; + isl_stat r; + + if (!bound->wrapping) + return unwrapped_guarded_poly_bound(bset, poly, user); + + nparam = isl_space_dim(bound->dim, isl_dim_param); + n_in = isl_space_dim(bound->dim, isl_dim_in); + if (nparam < 0 || n_in < 0) + goto error; + + space = isl_qpolynomial_get_domain_space(poly); + bset = isl_basic_set_reset_space(bset, space); + + bset = isl_basic_set_move_dims(bset, isl_dim_param, nparam, + isl_dim_set, 0, n_in); + poly = isl_qpolynomial_move_dims(poly, isl_dim_param, nparam, + isl_dim_in, 0, n_in); + + space = isl_basic_set_get_space(bset); + space = isl_space_params(space); + + top_pwf = bound->pwf; + top_pwf_tight = bound->pwf_tight; + + space = isl_space_from_domain(space); + space = isl_space_add_dims(space, isl_dim_out, 1); + bound->pwf = isl_pw_qpolynomial_fold_zero(isl_space_copy(space), + bound->type); + bound->pwf_tight = isl_pw_qpolynomial_fold_zero(space, bound->type); + + r = unwrapped_guarded_poly_bound(bset, poly, user); + + bound->pwf = isl_pw_qpolynomial_fold_reset_space(bound->pwf, + isl_space_copy(bound->dim)); + bound->pwf_tight = isl_pw_qpolynomial_fold_reset_space(bound->pwf_tight, + isl_space_copy(bound->dim)); + + isl_bound_add(bound, top_pwf); + isl_bound_add_tight(bound, top_pwf_tight); + + return r; +error: + isl_basic_set_free(bset); + isl_qpolynomial_free(poly); + return isl_stat_error; +} + +static isl_stat guarded_qp(__isl_take isl_qpolynomial *qp, void *user) +{ + struct isl_bound *bound = (struct isl_bound *)user; + isl_stat r; + + r = isl_qpolynomial_as_polynomial_on_domain(qp, bound->bset, + &guarded_poly_bound, user); + isl_qpolynomial_free(qp); + return r; +} + +static isl_stat basic_guarded_fold(__isl_take isl_basic_set *bset, void *user) +{ + struct isl_bound *bound = (struct isl_bound *)user; + isl_stat r; + + bound->bset = bset; + r = isl_qpolynomial_fold_foreach_qpolynomial(bound->fold, + &guarded_qp, user); + isl_basic_set_free(bset); + return r; +} + +static isl_stat guarded_fold(__isl_take isl_set *set, + __isl_take isl_qpolynomial_fold *fold, void *user) +{ + struct isl_bound *bound = (struct isl_bound *)user; + + if (!set || !fold) + goto error; + + set = isl_set_make_disjoint(set); + + bound->fold = fold; + bound->type = isl_qpolynomial_fold_get_type(fold); + + if (isl_set_foreach_basic_set(set, &basic_guarded_fold, bound) < 0) + goto error; + + isl_set_free(set); + isl_qpolynomial_fold_free(fold); + + return isl_stat_ok; +error: + isl_set_free(set); + isl_qpolynomial_fold_free(fold); + return isl_stat_error; +} + +__isl_give isl_pw_qpolynomial_fold *isl_pw_qpolynomial_fold_bound( + __isl_take isl_pw_qpolynomial_fold *pwf, isl_bool *tight) +{ + isl_size nvar; + struct isl_bound bound; + isl_bool covers; + + if (!pwf) + return NULL; + + bound.dim = isl_pw_qpolynomial_fold_get_domain_space(pwf); + + bound.wrapping = isl_space_is_wrapping(bound.dim); + if (bound.wrapping) + bound.dim = isl_space_unwrap(bound.dim); + nvar = isl_space_dim(bound.dim, isl_dim_out); + if (nvar < 0) + bound.dim = isl_space_free(bound.dim); + bound.dim = isl_space_domain(bound.dim); + bound.dim = isl_space_from_domain(bound.dim); + bound.dim = isl_space_add_dims(bound.dim, isl_dim_out, 1); + + if (nvar == 0) { + if (tight) + *tight = isl_bool_true; + return isl_pw_qpolynomial_fold_reset_space(pwf, bound.dim); + } + + if (isl_pw_qpolynomial_fold_is_zero(pwf)) { + enum isl_fold type = pwf->type; + isl_pw_qpolynomial_fold_free(pwf); + if (tight) + *tight = isl_bool_true; + return isl_pw_qpolynomial_fold_zero(bound.dim, type); + } + + bound.pwf = isl_pw_qpolynomial_fold_zero(isl_space_copy(bound.dim), + pwf->type); + bound.pwf_tight = isl_pw_qpolynomial_fold_zero(isl_space_copy(bound.dim), + pwf->type); + bound.check_tight = !!tight; + + if (isl_pw_qpolynomial_fold_foreach_lifted_piece(pwf, + guarded_fold, &bound) < 0) + goto error; + + covers = isl_pw_qpolynomial_fold_covers(bound.pwf_tight, bound.pwf); + if (covers < 0) + goto error; + + if (tight) + *tight = covers; + + isl_space_free(bound.dim); + isl_pw_qpolynomial_fold_free(pwf); + + if (covers) { + isl_pw_qpolynomial_fold_free(bound.pwf); + return bound.pwf_tight; + } + + bound.pwf = isl_pw_qpolynomial_fold_fold(bound.pwf, bound.pwf_tight); + + return bound.pwf; +error: + isl_pw_qpolynomial_fold_free(bound.pwf_tight); + isl_pw_qpolynomial_fold_free(bound.pwf); + isl_pw_qpolynomial_fold_free(pwf); + isl_space_free(bound.dim); + return NULL; +} + +__isl_give isl_pw_qpolynomial_fold *isl_pw_qpolynomial_bound( + __isl_take isl_pw_qpolynomial *pwqp, enum isl_fold type, + isl_bool *tight) +{ + isl_pw_qpolynomial_fold *pwf; + + pwf = isl_pw_qpolynomial_fold_from_pw_qpolynomial(type, pwqp); + return isl_pw_qpolynomial_fold_bound(pwf, tight); +} + +struct isl_union_bound_data { + enum isl_fold type; + isl_bool tight; + isl_union_pw_qpolynomial_fold *res; +}; + +static isl_stat bound_pw(__isl_take isl_pw_qpolynomial *pwqp, void *user) +{ + struct isl_union_bound_data *data = user; + isl_pw_qpolynomial_fold *pwf; + + pwf = isl_pw_qpolynomial_bound(pwqp, data->type, + data->tight ? &data->tight : NULL); + data->res = isl_union_pw_qpolynomial_fold_fold_pw_qpolynomial_fold( + data->res, pwf); + + return isl_stat_ok; +} + +__isl_give isl_union_pw_qpolynomial_fold *isl_union_pw_qpolynomial_bound( + __isl_take isl_union_pw_qpolynomial *upwqp, + enum isl_fold type, isl_bool *tight) +{ + isl_space *space; + struct isl_union_bound_data data = { type, 1, NULL }; + + if (!upwqp) + return NULL; + + if (!tight) + data.tight = isl_bool_false; + + space = isl_union_pw_qpolynomial_get_space(upwqp); + data.res = isl_union_pw_qpolynomial_fold_zero(space, type); + if (isl_union_pw_qpolynomial_foreach_pw_qpolynomial(upwqp, + &bound_pw, &data) < 0) + goto error; + + isl_union_pw_qpolynomial_free(upwqp); + if (tight) + *tight = data.tight; + + return data.res; +error: + isl_union_pw_qpolynomial_free(upwqp); + isl_union_pw_qpolynomial_fold_free(data.res); + return NULL; +} diff --git a/external/mit/isl/dist/isl_bound.h b/external/mit/isl/dist/isl_bound.h new file mode 100644 index 000000000000..13a5813a77e3 --- /dev/null +++ b/external/mit/isl/dist/isl_bound.h @@ -0,0 +1,29 @@ +#ifndef ISL_BOUND_H +#define ISL_BOUND_H + +#include + +struct isl_bound { + /* input */ + int check_tight; + int wrapping; + enum isl_fold type; + isl_space *dim; + isl_basic_set *bset; + isl_qpolynomial_fold *fold; + + /* output */ + isl_pw_qpolynomial_fold *pwf; + isl_pw_qpolynomial_fold *pwf_tight; +}; + +__isl_give isl_pw_qpolynomial_fold *isl_qpolynomial_cst_bound( + __isl_take isl_basic_set *bset, __isl_take isl_qpolynomial *poly, + enum isl_fold type, isl_bool *tight); + +isl_stat isl_bound_add(struct isl_bound *bound, + __isl_take isl_pw_qpolynomial_fold *pwf); +isl_stat isl_bound_add_tight(struct isl_bound *bound, + __isl_take isl_pw_qpolynomial_fold *pwf); + +#endif diff --git a/external/mit/isl/dist/isl_box.c b/external/mit/isl/dist/isl_box.c new file mode 100644 index 000000000000..c674af0d3762 --- /dev/null +++ b/external/mit/isl/dist/isl_box.c @@ -0,0 +1,636 @@ +/* + * Copyright 2010-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 +#include +#include +#include +#include +#include +#include +#include + +/* Representation of a box of fixed size containing the elements + * [offset, offset + size). + * "size" lives in the target space of "offset". + * + * If any of the "offsets" is NaN, then the object represents + * the failure of finding a fixed-size box. + */ +struct isl_fixed_box { + isl_multi_aff *offset; + isl_multi_val *size; +}; + +/* Free "box" and return NULL. + */ +__isl_null isl_fixed_box *isl_fixed_box_free(__isl_take isl_fixed_box *box) +{ + if (!box) + return NULL; + isl_multi_aff_free(box->offset); + isl_multi_val_free(box->size); + free(box); + return NULL; +} + +/* Construct an isl_fixed_box with the given offset and size. + */ +static __isl_give isl_fixed_box *isl_fixed_box_alloc( + __isl_take isl_multi_aff *offset, __isl_take isl_multi_val *size) +{ + isl_ctx *ctx; + isl_fixed_box *box; + + if (!offset || !size) + goto error; + ctx = isl_multi_aff_get_ctx(offset); + box = isl_alloc_type(ctx, struct isl_fixed_box); + if (!box) + goto error; + box->offset = offset; + box->size = size; + + return box; +error: + isl_multi_aff_free(offset); + isl_multi_val_free(size); + return NULL; +} + +/* Construct an initial isl_fixed_box with zero offsets + * in the given space and zero corresponding sizes. + */ +static __isl_give isl_fixed_box *isl_fixed_box_init( + __isl_take isl_space *space) +{ + isl_multi_aff *offset; + isl_multi_val *size; + + offset = isl_multi_aff_zero(isl_space_copy(space)); + space = isl_space_drop_all_params(isl_space_range(space)); + size = isl_multi_val_zero(space); + return isl_fixed_box_alloc(offset, size); +} + +/* Return a copy of "box". + */ +__isl_give isl_fixed_box *isl_fixed_box_copy(__isl_keep isl_fixed_box *box) +{ + isl_multi_aff *offset; + isl_multi_val *size; + + offset = isl_fixed_box_get_offset(box); + size = isl_fixed_box_get_size(box); + return isl_fixed_box_alloc(offset, size); +} + +/* Replace the offset and size in direction "pos" by "offset" and "size" + * (without checking whether "box" is a valid box). + */ +static __isl_give isl_fixed_box *isl_fixed_box_set_extent( + __isl_take isl_fixed_box *box, int pos, __isl_keep isl_aff *offset, + __isl_keep isl_val *size) +{ + if (!box) + return NULL; + box->offset = isl_multi_aff_set_aff(box->offset, pos, + isl_aff_copy(offset)); + box->size = isl_multi_val_set_val(box->size, pos, isl_val_copy(size)); + if (!box->offset || !box->size) + return isl_fixed_box_free(box); + return box; +} + +/* Replace the offset and size in direction "pos" by "offset" and "size", + * if "box" is a valid box. + */ +static __isl_give isl_fixed_box *isl_fixed_box_set_valid_extent( + __isl_take isl_fixed_box *box, int pos, __isl_keep isl_aff *offset, + __isl_keep isl_val *size) +{ + isl_bool valid; + + valid = isl_fixed_box_is_valid(box); + if (valid < 0 || !valid) + return box; + return isl_fixed_box_set_extent(box, pos, offset, size); +} + +/* Replace "box" by an invalid box, by setting all offsets to NaN + * (and all sizes to infinity). + */ +static __isl_give isl_fixed_box *isl_fixed_box_invalidate( + __isl_take isl_fixed_box *box) +{ + int i; + isl_size n; + isl_space *space; + isl_val *infty; + isl_aff *nan; + + if (!box) + return NULL; + n = isl_multi_val_dim(box->size, isl_dim_set); + if (n < 0) + return isl_fixed_box_free(box); + + infty = isl_val_infty(isl_fixed_box_get_ctx(box)); + space = isl_space_domain(isl_fixed_box_get_space(box)); + nan = isl_aff_nan_on_domain(isl_local_space_from_space(space)); + for (i = 0; i < n; ++i) + box = isl_fixed_box_set_extent(box, i, nan, infty); + isl_aff_free(nan); + isl_val_free(infty); + + if (!box->offset || !box->size) + return isl_fixed_box_free(box); + return box; +} + +/* Project the domain of the fixed box onto its parameter space. + * In particular, project out the domain of the offset. + */ +static __isl_give isl_fixed_box *isl_fixed_box_project_domain_on_params( + __isl_take isl_fixed_box *box) +{ + isl_bool valid; + + valid = isl_fixed_box_is_valid(box); + if (valid < 0) + return isl_fixed_box_free(box); + if (!valid) + return box; + + box->offset = isl_multi_aff_project_domain_on_params(box->offset); + if (!box->offset) + return isl_fixed_box_free(box); + + return box; +} + +/* Return the isl_ctx to which "box" belongs. + */ +isl_ctx *isl_fixed_box_get_ctx(__isl_keep isl_fixed_box *box) +{ + if (!box) + return NULL; + return isl_multi_aff_get_ctx(box->offset); +} + +/* Return the space in which "box" lives. + */ +__isl_give isl_space *isl_fixed_box_get_space(__isl_keep isl_fixed_box *box) +{ + if (!box) + return NULL; + return isl_multi_aff_get_space(box->offset); +} + +/* Does "box" contain valid information? + */ +isl_bool isl_fixed_box_is_valid(__isl_keep isl_fixed_box *box) +{ + if (!box) + return isl_bool_error; + return isl_bool_not(isl_multi_aff_involves_nan(box->offset)); +} + +/* Return the offsets of the box "box". + */ +__isl_give isl_multi_aff *isl_fixed_box_get_offset( + __isl_keep isl_fixed_box *box) +{ + if (!box) + return NULL; + return isl_multi_aff_copy(box->offset); +} + +/* Return the sizes of the box "box". + */ +__isl_give isl_multi_val *isl_fixed_box_get_size(__isl_keep isl_fixed_box *box) +{ + if (!box) + return NULL; + return isl_multi_val_copy(box->size); +} + +/* Data used in set_dim_extent and compute_size_in_direction. + * + * "bset" is a wrapped copy of the basic map that has the selected + * output dimension as range. + * "pos" is the position of the variable representing the output dimension, + * i.e., the variable for which the size should be computed. This variable + * is also the last variable in "bset". + * "size" is the best size found so far + * (infinity if no offset was found so far). + * "offset" is the offset corresponding to the best size + * (NULL if no offset was found so far). + */ +struct isl_size_info { + isl_basic_set *bset; + isl_size pos; + isl_val *size; + isl_aff *offset; +}; + +/* Is "c" a suitable bound on dimension "pos" for use as a lower bound + * of a fixed-size range. + * In particular, it needs to be a lower bound on "pos". + * In order for the final offset not to be too complicated, + * the constraint itself should also not involve any integer divisions. + */ +static isl_bool is_suitable_bound(__isl_keep isl_constraint *c, unsigned pos) +{ + isl_size n_div; + isl_bool is_bound, any_divs; + + is_bound = isl_constraint_is_lower_bound(c, isl_dim_set, pos); + if (is_bound < 0 || !is_bound) + return is_bound; + + n_div = isl_constraint_dim(c, isl_dim_div); + if (n_div < 0) + return isl_bool_error; + any_divs = isl_constraint_involves_dims(c, isl_dim_div, 0, n_div); + return isl_bool_not(any_divs); +} + +/* Given a constraint from the basic set describing the bounds on + * an array index, check if it is a lower bound, say m i >= b(x), and, + * if so, check whether the expression "i - ceil(b(x)/m) + 1" has a constant + * upper bound. If so, and if this bound is smaller than any bound + * derived from earlier constraints, set the size to this bound on + * the expression and the lower bound to ceil(b(x)/m). + */ +static isl_stat compute_size_in_direction(__isl_take isl_constraint *c, + void *user) +{ + struct isl_size_info *info = user; + isl_val *v; + isl_aff *aff; + isl_aff *lb; + isl_bool is_bound, better; + + is_bound = is_suitable_bound(c, info->pos); + if (is_bound < 0 || !is_bound) { + isl_constraint_free(c); + return is_bound < 0 ? isl_stat_error : isl_stat_ok; + } + + aff = isl_constraint_get_bound(c, isl_dim_set, info->pos); + aff = isl_aff_ceil(aff); + + lb = isl_aff_copy(aff); + + aff = isl_aff_neg(aff); + aff = isl_aff_add_coefficient_si(aff, isl_dim_in, info->pos, 1); + + v = isl_basic_set_max_val(info->bset, aff); + isl_aff_free(aff); + + v = isl_val_add_ui(v, 1); + better = isl_val_lt(v, info->size); + if (better >= 0 && better) { + isl_val_free(info->size); + info->size = isl_val_copy(v); + lb = isl_aff_domain_factor_domain(lb); + isl_aff_free(info->offset); + info->offset = isl_aff_copy(lb); + } + isl_val_free(v); + isl_aff_free(lb); + + isl_constraint_free(c); + + return better < 0 ? isl_stat_error : isl_stat_ok; +} + +/* Look for a fixed-size range of values for the output dimension "pos" + * of "map", by looking for a lower-bound expression in the parameters + * and input dimensions such that the range of the output dimension + * is a constant shifted by this expression. + * + * In particular, look through the explicit lower bounds on the output dimension + * for candidate expressions and pick the one that results in the smallest size. + * Initialize the size with infinity and if no better size is found + * then invalidate the box. Otherwise, set the offset and size + * in the given direction by those that correspond to the smallest size. + * + * Note that while evaluating the size corresponding to a lower bound, + * an affine expression is constructed from the lower bound. + * This lower bound may therefore not have any unknown local variables. + * Eliminate any unknown local variables up front. + * No such restriction needs to be imposed on the set over which + * the size is computed. + */ +static __isl_give isl_fixed_box *set_dim_extent(__isl_take isl_fixed_box *box, + __isl_keep isl_map *map, int pos) +{ + struct isl_size_info info; + isl_bool valid; + isl_ctx *ctx; + isl_basic_set *bset; + + if (!box || !map) + return isl_fixed_box_free(box); + + ctx = isl_map_get_ctx(map); + map = isl_map_copy(map); + map = isl_map_project_onto(map, isl_dim_out, pos, 1); + info.size = isl_val_infty(ctx); + info.offset = NULL; + info.pos = isl_map_dim(map, isl_dim_in); + info.bset = isl_basic_map_wrap(isl_map_simple_hull(map)); + bset = isl_basic_set_copy(info.bset); + bset = isl_basic_set_remove_unknown_divs(bset); + if (info.pos < 0) + bset = isl_basic_set_free(bset); + if (isl_basic_set_foreach_constraint(bset, + &compute_size_in_direction, &info) < 0) + box = isl_fixed_box_free(box); + isl_basic_set_free(bset); + valid = isl_val_is_int(info.size); + if (valid < 0) + box = isl_fixed_box_free(box); + else if (valid) + box = isl_fixed_box_set_valid_extent(box, pos, + info.offset, info.size); + else + box = isl_fixed_box_invalidate(box); + isl_val_free(info.size); + isl_aff_free(info.offset); + isl_basic_set_free(info.bset); + + return box; +} + +/* Try and construct a fixed-size rectangular box with an offset + * in terms of the domain of "map" that contains the range of "map". + * If no such box can be constructed, then return an invalidated box, + * i.e., one where isl_fixed_box_is_valid returns false. + * + * Iterate over the dimensions in the range + * setting the corresponding offset and extent. + */ +__isl_give isl_fixed_box *isl_map_get_range_simple_fixed_box_hull( + __isl_keep isl_map *map) +{ + int i; + isl_size n; + isl_space *space; + isl_fixed_box *box; + + n = isl_map_dim(map, isl_dim_out); + if (n < 0) + return NULL; + space = isl_map_get_space(map); + box = isl_fixed_box_init(space); + + map = isl_map_detect_equalities(isl_map_copy(map)); + for (i = 0; i < n; ++i) { + isl_bool valid; + + box = set_dim_extent(box, map, i); + valid = isl_fixed_box_is_valid(box); + if (valid < 0 || !valid) + break; + } + isl_map_free(map); + + return box; +} + +/* Compute a fixed box from "set" using "map_box" by treating it as a map + * with a zero-dimensional domain and + * project out the domain again from the result. + */ +static __isl_give isl_fixed_box *fixed_box_as_map(__isl_keep isl_set *set, + __isl_give isl_fixed_box *(*map_box)(__isl_keep isl_map *map)) +{ + isl_map *map; + isl_fixed_box *box; + + map = isl_map_from_range(isl_set_copy(set)); + box = map_box(map); + isl_map_free(map); + box = isl_fixed_box_project_domain_on_params(box); + + return box; +} + +/* Try and construct a fixed-size rectangular box with an offset + * in terms of the parameters of "set" that contains "set". + * If no such box can be constructed, then return an invalidated box, + * i.e., one where isl_fixed_box_is_valid returns false. + * + * Compute the box using isl_map_get_range_simple_fixed_box_hull + * by constructing a map from the set and + * project out the domain again from the result. + */ +__isl_give isl_fixed_box *isl_set_get_simple_fixed_box_hull( + __isl_keep isl_set *set) +{ + return fixed_box_as_map(set, &isl_map_get_range_simple_fixed_box_hull); +} + +/* Check whether the output elements lie on a rectangular lattice, + * possibly depending on the parameters and the input dimensions. + * Return a tile in this lattice. + * If no stride information can be found, then return a tile of size 1 + * (and offset 0). + * + * Obtain stride information in each output dimension separately and + * combine the results. + */ +__isl_give isl_fixed_box *isl_map_get_range_lattice_tile( + __isl_keep isl_map *map) +{ + int i; + isl_size n; + isl_space *space; + isl_fixed_box *box; + + n = isl_map_dim(map, isl_dim_out); + if (n < 0) + return NULL; + space = isl_map_get_space(map); + box = isl_fixed_box_init(space); + + for (i = 0; i < n; ++i) { + isl_val *stride; + isl_aff *offset; + isl_stride_info *si; + + si = isl_map_get_range_stride_info(map, i); + stride = isl_stride_info_get_stride(si); + offset = isl_stride_info_get_offset(si); + isl_stride_info_free(si); + + box = isl_fixed_box_set_valid_extent(box, i, offset, stride); + + isl_aff_free(offset); + isl_val_free(stride); + } + + return box; +} + +/* Check whether the elements lie on a rectangular lattice, + * possibly depending on the parameters. + * Return a tile in this lattice. + * If no stride information can be found, then return a tile of size 1 + * (and offset 0). + * + * Consider the set as a map with a zero-dimensional domain and + * obtain a lattice tile of that map. + */ +__isl_give isl_fixed_box *isl_set_get_lattice_tile(__isl_keep isl_set *set) +{ + return fixed_box_as_map(set, &isl_map_get_range_lattice_tile); +} + +/* An enumeration of the keys that may appear in a YAML mapping + * of an isl_fixed_box object. + */ +enum isl_fb_key { + isl_fb_key_error = -1, + isl_fb_key_offset, + isl_fb_key_size, + isl_fb_key_end, +}; + +/* Textual representations of the YAML keys for an isl_fixed_box object. + */ +static char *key_str[] = { + [isl_fb_key_offset] = "offset", + [isl_fb_key_size] = "size", +}; + +#undef BASE +#define BASE multi_val +#include "print_yaml_field_templ.c" + +#undef BASE +#define BASE multi_aff +#include "print_yaml_field_templ.c" + +/* Print the information contained in "box" to "p". + * The information is printed as a YAML document. + */ +__isl_give isl_printer *isl_printer_print_fixed_box( + __isl_take isl_printer *p, __isl_keep isl_fixed_box *box) +{ + if (!box) + return isl_printer_free(p); + + p = isl_printer_yaml_start_mapping(p); + p = print_yaml_field_multi_aff(p, key_str[isl_fb_key_offset], + box->offset); + p = print_yaml_field_multi_val(p, key_str[isl_fb_key_size], box->size); + p = isl_printer_yaml_end_mapping(p); + + return p; +} + +#undef BASE +#define BASE fixed_box +#include + +#undef KEY +#define KEY enum isl_fb_key +#undef KEY_ERROR +#define KEY_ERROR isl_fb_key_error +#undef KEY_END +#define KEY_END isl_fb_key_end +#undef KEY_STR +#define KEY_STR key_str +#undef KEY_EXTRACT +#define KEY_EXTRACT extract_key +#undef KEY_GET +#define KEY_GET get_key +#include "extract_key.c" + +#undef BASE +#define BASE multi_val +#include "read_in_string_templ.c" + +#undef BASE +#define BASE multi_aff +#include "read_in_string_templ.c" + +/* Read an isl_fixed_box object from "s". + * + * The input needs to contain both an offset and a size. + * If either is specified multiple times, then the last specification + * overrides all previous ones. This is simpler than checking + * that each is only specified once. + */ +static __isl_give isl_fixed_box *isl_stream_read_fixed_box(isl_stream *s) +{ + isl_bool more; + isl_multi_aff *offset = NULL; + isl_multi_val *size = NULL; + + if (isl_stream_yaml_read_start_mapping(s) < 0) + return NULL; + + while ((more = isl_stream_yaml_next(s)) == isl_bool_true) { + enum isl_fb_key key; + + key = get_key(s); + if (isl_stream_yaml_next(s) < 0) + goto error; + switch (key) { + case isl_fb_key_end: + case isl_fb_key_error: + goto error; + case isl_fb_key_offset: + isl_multi_aff_free(offset); + offset = read_multi_aff(s); + if (!offset) + goto error; + break; + case isl_fb_key_size: + isl_multi_val_free(size); + size = read_multi_val(s); + if (!size) + goto error; + break; + } + } + if (more < 0) + goto error; + + if (isl_stream_yaml_read_end_mapping(s) < 0) + goto error; + + if (!offset) { + isl_stream_error(s, NULL, "no offset specified"); + goto error; + } + + if (!size) { + isl_stream_error(s, NULL, "no size specified"); + goto error; + } + + return isl_fixed_box_alloc(offset, size); +error: + isl_multi_aff_free(offset); + isl_multi_val_free(size); + return NULL; +} + +#undef TYPE_BASE +#define TYPE_BASE fixed_box +#include "isl_read_from_str_templ.c" diff --git a/external/mit/isl/dist/isl_check_named_params_templ.c b/external/mit/isl/dist/isl_check_named_params_templ.c new file mode 100644 index 000000000000..f900768ec478 --- /dev/null +++ b/external/mit/isl/dist/isl_check_named_params_templ.c @@ -0,0 +1,10 @@ +#define xFN(TYPE,NAME) TYPE ## _ ## NAME +#define FN(TYPE,NAME) xFN(TYPE,NAME) + +/* Check that "obj" has only named parameters, reporting an error + * if it does not. + */ +isl_stat FN(TYPE,check_named_params)(__isl_keep TYPE *obj) +{ + return isl_space_check_named_params(FN(TYPE,peek_space)(obj)); +} diff --git a/external/mit/isl/dist/isl_coalesce.c b/external/mit/isl/dist/isl_coalesce.c new file mode 100644 index 000000000000..5d0d173af9fe --- /dev/null +++ b/external/mit/isl/dist/isl_coalesce.c @@ -0,0 +1,4264 @@ +/* + * Copyright 2008-2009 Katholieke Universiteit Leuven + * Copyright 2010 INRIA Saclay + * Copyright 2012-2013 Ecole Normale Superieure + * Copyright 2014 INRIA Rocquencourt + * Copyright 2016 INRIA Paris + * Copyright 2020 Cerebras Systems + * + * 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 + * and Inria Paris - Rocquencourt, Domaine de Voluceau - Rocquencourt, + * B.P. 105 - 78153 Le Chesnay, France + * and Centre de Recherche Inria de Paris, 2 rue Simone Iff - Voie DQ12, + * CS 42112, 75589 Paris Cedex 12, France + * and Cerebras Systems, 175 S San Antonio Rd, Los Altos, CA, USA + */ + +#include +#include "isl_map_private.h" +#include +#include +#include "isl_tab.h" +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#define STATUS_ERROR -1 +#define STATUS_REDUNDANT 1 +#define STATUS_VALID 2 +#define STATUS_SEPARATE 3 +#define STATUS_CUT 4 +#define STATUS_ADJ_EQ 5 +#define STATUS_ADJ_INEQ 6 + +static int status_in(isl_int *ineq, struct isl_tab *tab) +{ + enum isl_ineq_type type = isl_tab_ineq_type(tab, ineq); + switch (type) { + default: + case isl_ineq_error: return STATUS_ERROR; + case isl_ineq_redundant: return STATUS_VALID; + case isl_ineq_separate: return STATUS_SEPARATE; + case isl_ineq_cut: return STATUS_CUT; + case isl_ineq_adj_eq: return STATUS_ADJ_EQ; + case isl_ineq_adj_ineq: return STATUS_ADJ_INEQ; + } +} + +/* Compute the position of the equalities of basic map "bmap_i" + * with respect to the basic map represented by "tab_j". + * The resulting array has twice as many entries as the number + * of equalities corresponding to the two inequalities to which + * each equality corresponds. + */ +static int *eq_status_in(__isl_keep isl_basic_map *bmap_i, + struct isl_tab *tab_j) +{ + int k, l; + int *eq; + isl_size dim; + + dim = isl_basic_map_dim(bmap_i, isl_dim_all); + if (dim < 0) + return NULL; + + eq = isl_calloc_array(bmap_i->ctx, int, 2 * bmap_i->n_eq); + if (!eq) + return NULL; + + for (k = 0; k < bmap_i->n_eq; ++k) { + for (l = 0; l < 2; ++l) { + isl_seq_neg(bmap_i->eq[k], bmap_i->eq[k], 1+dim); + eq[2 * k + l] = status_in(bmap_i->eq[k], tab_j); + if (eq[2 * k + l] == STATUS_ERROR) + goto error; + } + } + + return eq; +error: + free(eq); + return NULL; +} + +/* Compute the position of the inequalities of basic map "bmap_i" + * (also represented by "tab_i", if not NULL) with respect to the basic map + * represented by "tab_j". + */ +static int *ineq_status_in(__isl_keep isl_basic_map *bmap_i, + struct isl_tab *tab_i, struct isl_tab *tab_j) +{ + int k; + unsigned n_eq = bmap_i->n_eq; + int *ineq = isl_calloc_array(bmap_i->ctx, int, bmap_i->n_ineq); + + if (!ineq) + return NULL; + + for (k = 0; k < bmap_i->n_ineq; ++k) { + if (tab_i && isl_tab_is_redundant(tab_i, n_eq + k)) { + ineq[k] = STATUS_REDUNDANT; + continue; + } + ineq[k] = status_in(bmap_i->ineq[k], tab_j); + if (ineq[k] == STATUS_ERROR) + goto error; + if (ineq[k] == STATUS_SEPARATE) + break; + } + + return ineq; +error: + free(ineq); + return NULL; +} + +static int any(int *con, unsigned len, int status) +{ + int i; + + for (i = 0; i < len ; ++i) + if (con[i] == status) + return 1; + return 0; +} + +/* Return the first position of "status" in the list "con" of length "len". + * Return -1 if there is no such entry. + */ +static int find(int *con, unsigned len, int status) +{ + int i; + + for (i = 0; i < len ; ++i) + if (con[i] == status) + return i; + return -1; +} + +static int count(int *con, unsigned len, int status) +{ + int i; + int c = 0; + + for (i = 0; i < len ; ++i) + if (con[i] == status) + c++; + return c; +} + +static int all(int *con, unsigned len, int status) +{ + int i; + + for (i = 0; i < len ; ++i) { + if (con[i] == STATUS_REDUNDANT) + continue; + if (con[i] != status) + return 0; + } + return 1; +} + +/* Internal information associated to a basic map in a map + * that is to be coalesced by isl_map_coalesce. + * + * "bmap" is the basic map itself (or NULL if "removed" is set) + * "tab" is the corresponding tableau (or NULL if "removed" is set) + * "hull_hash" identifies the affine space in which "bmap" lives. + * "modified" is set if this basic map may not be identical + * to any of the basic maps in the input. + * "removed" is set if this basic map has been removed from the map + * "simplify" is set if this basic map may have some unknown integer + * divisions that were not present in the input basic maps. The basic + * map should then be simplified such that we may be able to find + * a definition among the constraints. + * + * "eq" and "ineq" are only set if we are currently trying to coalesce + * this basic map with another basic map, in which case they represent + * the position of the inequalities of this basic map with respect to + * the other basic map. The number of elements in the "eq" array + * is twice the number of equalities in the "bmap", corresponding + * to the two inequalities that make up each equality. + */ +struct isl_coalesce_info { + isl_basic_map *bmap; + struct isl_tab *tab; + uint32_t hull_hash; + int modified; + int removed; + int simplify; + int *eq; + 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) +{ + isl_size 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) +{ + isl_size 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) +{ + isl_size 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) +{ + isl_size 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) +{ + isl_size 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) +{ + isl_size 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? + */ +static int all_valid_or_cut(struct isl_coalesce_info *info) +{ + int i; + + for (i = 0; i < 2 * info->bmap->n_eq; ++i) { + if (info->eq[i] == STATUS_REDUNDANT) + continue; + if (info->eq[i] == STATUS_VALID) + continue; + if (info->eq[i] == STATUS_CUT) + continue; + return 0; + } + + for (i = 0; i < info->bmap->n_ineq; ++i) { + if (info->ineq[i] == STATUS_REDUNDANT) + continue; + if (info->ineq[i] == STATUS_VALID) + continue; + if (info->ineq[i] == STATUS_CUT) + continue; + return 0; + } + + return 1; +} + +/* Compute the hash of the (apparent) affine hull of info->bmap (with + * the existentially quantified variables removed) and store it + * in info->hash. + */ +static int coalesce_info_set_hull_hash(struct isl_coalesce_info *info) +{ + isl_basic_map *hull; + isl_size n_div; + + hull = isl_basic_map_copy(info->bmap); + hull = isl_basic_map_plain_affine_hull(hull); + n_div = isl_basic_map_dim(hull, isl_dim_div); + if (n_div < 0) + hull = isl_basic_map_free(hull); + hull = isl_basic_map_drop_constraints_involving_dims(hull, + isl_dim_div, 0, n_div); + info->hull_hash = isl_basic_map_get_hash(hull); + isl_basic_map_free(hull); + + return hull ? 0 : -1; +} + +/* Free all the allocated memory in an array + * of "n" isl_coalesce_info elements. + */ +static void clear_coalesce_info(int n, struct isl_coalesce_info *info) +{ + int i; + + if (!info) + return; + + for (i = 0; i < n; ++i) { + isl_basic_map_free(info[i].bmap); + isl_tab_free(info[i].tab); + } + + free(info); +} + +/* Clear the memory associated to "info". + */ +static void clear(struct isl_coalesce_info *info) +{ + info->bmap = isl_basic_map_free(info->bmap); + isl_tab_free(info->tab); + info->tab = NULL; +} + +/* Drop the basic map represented by "info". + * That is, clear the memory associated to the entry and + * mark it as having been removed. + */ +static void drop(struct isl_coalesce_info *info) +{ + clear(info); + info->removed = 1; +} + +/* Exchange the information in "info1" with that in "info2". + */ +static void exchange(struct isl_coalesce_info *info1, + struct isl_coalesce_info *info2) +{ + struct isl_coalesce_info info; + + info = *info1; + *info1 = *info2; + *info2 = info; +} + +/* This type represents the kind of change that has been performed + * while trying to coalesce two basic maps. + * + * isl_change_none: nothing was changed + * isl_change_drop_first: the first basic map was removed + * isl_change_drop_second: the second basic map was removed + * isl_change_fuse: the two basic maps were replaced by a new basic map. + */ +enum isl_change { + isl_change_error = -1, + isl_change_none = 0, + isl_change_drop_first, + isl_change_drop_second, + isl_change_fuse, +}; + +/* Update "change" based on an interchange of the first and the second + * basic map. That is, interchange isl_change_drop_first and + * isl_change_drop_second. + */ +static enum isl_change invert_change(enum isl_change change) +{ + switch (change) { + case isl_change_error: + return isl_change_error; + case isl_change_none: + return isl_change_none; + case isl_change_drop_first: + return isl_change_drop_second; + case isl_change_drop_second: + return isl_change_drop_first; + case isl_change_fuse: + return isl_change_fuse; + } + + return isl_change_error; +} + +/* Add the valid constraints of the basic map represented by "info" + * to "bmap". "len" is the size of the constraints. + * If only one of the pair of inequalities that make up an equality + * is valid, then add that inequality. + */ +static __isl_give isl_basic_map *add_valid_constraints( + __isl_take isl_basic_map *bmap, struct isl_coalesce_info *info, + unsigned len) +{ + int k, l; + + if (!bmap) + return NULL; + + for (k = 0; k < info->bmap->n_eq; ++k) { + if (info->eq[2 * k] == STATUS_VALID && + info->eq[2 * k + 1] == STATUS_VALID) { + l = isl_basic_map_alloc_equality(bmap); + if (l < 0) + return isl_basic_map_free(bmap); + isl_seq_cpy(bmap->eq[l], info->bmap->eq[k], len); + } else if (info->eq[2 * k] == STATUS_VALID) { + l = isl_basic_map_alloc_inequality(bmap); + if (l < 0) + return isl_basic_map_free(bmap); + isl_seq_neg(bmap->ineq[l], info->bmap->eq[k], len); + } else if (info->eq[2 * k + 1] == STATUS_VALID) { + l = isl_basic_map_alloc_inequality(bmap); + if (l < 0) + return isl_basic_map_free(bmap); + isl_seq_cpy(bmap->ineq[l], info->bmap->eq[k], len); + } + } + + for (k = 0; k < info->bmap->n_ineq; ++k) { + if (info->ineq[k] != STATUS_VALID) + continue; + l = isl_basic_map_alloc_inequality(bmap); + if (l < 0) + return isl_basic_map_free(bmap); + isl_seq_cpy(bmap->ineq[l], info->bmap->ineq[k], len); + } + + return bmap; +} + +/* Is "bmap" defined by a number of (non-redundant) constraints that + * is greater than the number of constraints of basic maps i and j combined? + * Equalities are counted as two inequalities. + */ +static int number_of_constraints_increases(int i, int j, + struct isl_coalesce_info *info, + __isl_keep isl_basic_map *bmap, struct isl_tab *tab) +{ + int k, n_old, n_new; + + n_old = 2 * info[i].bmap->n_eq + info[i].bmap->n_ineq; + n_old += 2 * info[j].bmap->n_eq + info[j].bmap->n_ineq; + + n_new = 2 * bmap->n_eq; + for (k = 0; k < bmap->n_ineq; ++k) + if (!isl_tab_is_redundant(tab, bmap->n_eq + k)) + ++n_new; + + return n_new > n_old; +} + +/* Replace the pair of basic maps i and j by the basic map bounded + * by the valid constraints in both basic maps and the constraints + * in extra (if not NULL). + * Place the fused basic map in the position that is the smallest of i and j. + * + * If "detect_equalities" is set, then look for equalities encoded + * as pairs of inequalities. + * If "check_number" is set, then the original basic maps are only + * replaced if the total number of constraints does not increase. + * While the number of integer divisions in the two basic maps + * is assumed to be the same, the actual definitions may be different. + * We only copy the definition from one of the basic maps if it is + * the same as that of the other basic map. Otherwise, we mark + * the integer division as unknown and simplify the basic map + * in an attempt to recover the integer division definition. + * If any extra constraints get introduced, then these may + * involve integer divisions with a unit coefficient. + * Eliminate those that do not appear with any other coefficient + * in other constraints, to ensure they get eliminated completely, + * improving the chances of further coalescing. + */ +static enum isl_change fuse(int i, int j, struct isl_coalesce_info *info, + __isl_keep isl_mat *extra, int detect_equalities, int check_number) +{ + int k, l; + struct isl_basic_map *fused = NULL; + struct isl_tab *fused_tab = NULL; + isl_size total = isl_basic_map_dim(info[i].bmap, isl_dim_all); + unsigned extra_rows = extra ? extra->n_row : 0; + unsigned n_eq, n_ineq; + int simplify = 0; + + if (total < 0) + return isl_change_error; + if (j < i) + return fuse(j, i, info, extra, detect_equalities, check_number); + + n_eq = info[i].bmap->n_eq + info[j].bmap->n_eq; + n_ineq = info[i].bmap->n_ineq + info[j].bmap->n_ineq; + fused = isl_basic_map_alloc_space(isl_space_copy(info[i].bmap->dim), + info[i].bmap->n_div, n_eq, n_eq + n_ineq + extra_rows); + fused = add_valid_constraints(fused, &info[i], 1 + total); + fused = add_valid_constraints(fused, &info[j], 1 + total); + if (!fused) + goto error; + if (ISL_F_ISSET(info[i].bmap, ISL_BASIC_MAP_RATIONAL) && + ISL_F_ISSET(info[j].bmap, ISL_BASIC_MAP_RATIONAL)) + ISL_F_SET(fused, ISL_BASIC_MAP_RATIONAL); + + for (k = 0; k < info[i].bmap->n_div; ++k) { + int l = isl_basic_map_alloc_div(fused); + if (l < 0) + goto error; + if (isl_seq_eq(info[i].bmap->div[k], info[j].bmap->div[k], + 1 + 1 + total)) { + isl_seq_cpy(fused->div[l], info[i].bmap->div[k], + 1 + 1 + total); + } else { + isl_int_set_si(fused->div[l][0], 0); + simplify = 1; + } + } + + for (k = 0; k < extra_rows; ++k) { + l = isl_basic_map_alloc_inequality(fused); + if (l < 0) + goto error; + isl_seq_cpy(fused->ineq[l], extra->row[k], 1 + total); + } + + if (detect_equalities) + fused = isl_basic_map_detect_inequality_pairs(fused, NULL); + fused = isl_basic_map_gauss(fused, NULL); + if (simplify || info[j].simplify) { + fused = isl_basic_map_simplify(fused); + info[i].simplify = 0; + } else if (extra_rows > 0) { + fused = isl_basic_map_eliminate_pure_unit_divs(fused); + } + fused = isl_basic_map_finalize(fused); + + fused_tab = isl_tab_from_basic_map(fused, 0); + if (isl_tab_detect_redundant(fused_tab) < 0) + goto error; + + if (check_number && + number_of_constraints_increases(i, j, info, fused, fused_tab)) { + isl_tab_free(fused_tab); + isl_basic_map_free(fused); + return isl_change_none; + } + + clear(&info[i]); + info[i].bmap = fused; + info[i].tab = fused_tab; + info[i].modified = 1; + drop(&info[j]); + + return isl_change_fuse; +error: + isl_tab_free(fused_tab); + isl_basic_map_free(fused); + return isl_change_error; +} + +/* Given a pair of basic maps i and j such that all constraints are either + * "valid" or "cut", check if the facets corresponding to the "cut" + * constraints of i lie entirely within basic map j. + * If so, replace the pair by the basic map consisting of the valid + * constraints in both basic maps. + * Checking whether the facet lies entirely within basic map j + * is performed by checking whether the constraints of basic map j + * are valid for the facet. These tests are performed on a rational + * tableau to avoid the theoretical possibility that a constraint + * that was considered to be a cut constraint for the entire basic map i + * happens to be considered to be a valid constraint for the facet, + * even though it cuts off the same rational points. + * + * To see that we are not introducing any extra points, call the + * two basic maps A and B and the resulting map U and let x + * be an element of U \setminus ( A \cup B ). + * A line connecting x with an element of A \cup B meets a facet F + * of either A or B. Assume it is a facet of B and let c_1 be + * the corresponding facet constraint. We have c_1(x) < 0 and + * so c_1 is a cut constraint. This implies that there is some + * (possibly rational) point x' satisfying the constraints of A + * and the opposite of c_1 as otherwise c_1 would have been marked + * valid for A. The line connecting x and x' meets a facet of A + * in a (possibly rational) point that also violates c_1, but this + * is impossible since all cut constraints of B are valid for all + * cut facets of A. + * In case F is a facet of A rather than B, then we can apply the + * above reasoning to find a facet of B separating x from A \cup B first. + */ +static enum isl_change check_facets(int i, int j, + struct isl_coalesce_info *info) +{ + int k, l; + struct isl_tab_undo *snap, *snap2; + unsigned n_eq = info[i].bmap->n_eq; + + snap = isl_tab_snap(info[i].tab); + if (isl_tab_mark_rational(info[i].tab) < 0) + return isl_change_error; + snap2 = isl_tab_snap(info[i].tab); + + for (k = 0; k < info[i].bmap->n_ineq; ++k) { + if (info[i].ineq[k] != STATUS_CUT) + continue; + if (isl_tab_select_facet(info[i].tab, n_eq + k) < 0) + return isl_change_error; + for (l = 0; l < info[j].bmap->n_ineq; ++l) { + int stat; + if (info[j].ineq[l] != STATUS_CUT) + continue; + stat = status_in(info[j].bmap->ineq[l], info[i].tab); + if (stat < 0) + return isl_change_error; + if (stat != STATUS_VALID) + break; + } + if (isl_tab_rollback(info[i].tab, snap2) < 0) + return isl_change_error; + if (l < info[j].bmap->n_ineq) + break; + } + + if (k < info[i].bmap->n_ineq) { + if (isl_tab_rollback(info[i].tab, snap) < 0) + return isl_change_error; + return isl_change_none; + } + return fuse(i, j, info, NULL, 0, 0); +} + +/* Check if info->bmap contains the basic map represented + * by the tableau "tab". + * For each equality, we check both the constraint itself + * (as an inequality) and its negation. Make sure the + * equality is returned to its original state before returning. + */ +static isl_bool contains(struct isl_coalesce_info *info, struct isl_tab *tab) +{ + int k; + isl_size dim; + isl_basic_map *bmap = info->bmap; + + dim = isl_basic_map_dim(bmap, isl_dim_all); + if (dim < 0) + return isl_bool_error; + for (k = 0; k < bmap->n_eq; ++k) { + int stat; + isl_seq_neg(bmap->eq[k], bmap->eq[k], 1 + dim); + stat = status_in(bmap->eq[k], tab); + isl_seq_neg(bmap->eq[k], bmap->eq[k], 1 + dim); + if (stat < 0) + return isl_bool_error; + if (stat != STATUS_VALID) + return isl_bool_false; + stat = status_in(bmap->eq[k], tab); + if (stat < 0) + return isl_bool_error; + if (stat != STATUS_VALID) + return isl_bool_false; + } + + for (k = 0; k < bmap->n_ineq; ++k) { + int stat; + if (info->ineq[k] == STATUS_REDUNDANT) + continue; + stat = status_in(bmap->ineq[k], tab); + if (stat < 0) + return isl_bool_error; + if (stat != STATUS_VALID) + return isl_bool_false; + } + return isl_bool_true; +} + +/* Basic map "i" has an inequality "k" that is adjacent + * to some inequality of basic map "j". All the other inequalities + * are valid for "j". + * If not NULL, then "extra" contains extra wrapping constraints that are valid + * for both "i" and "j". + * Check if basic map "j" forms an extension of basic map "i", + * taking into account the extra constraints, if any. + * + * Note that this function is only called if some of the equalities or + * inequalities of basic map "j" do cut basic map "i". The function is + * correct even if there are no such cut constraints, but in that case + * the additional checks performed by this function are overkill. + * + * In particular, we replace constraint k, say f >= 0, by constraint + * f <= -1, add the inequalities of "j" that are valid for "i", + * as well as the "extra" constraints, if any, + * and check if the result is a subset of basic map "j". + * To improve the chances of the subset relation being detected, + * any variable that only attains a single integer value + * in the tableau of "i" is first fixed to that value. + * If the result is a subset, then we know that this result is exactly equal + * to basic map "j" since all its constraints are valid for basic map "j". + * By combining the valid constraints of "i" (all equalities and all + * inequalities except "k"), the valid constraints of "j" and + * the "extra" constraints, if any, we therefore + * obtain a basic map that is equal to their union. + * In this case, there is no need to perform a rollback of the tableau + * since it is going to be destroyed in fuse(). + * + * + * |\__ |\__ + * | \__ | \__ + * | \_ => | \__ + * |_______| _ |_________\ + * + * + * |\ |\ + * | \ | \ + * | \ | \ + * | | | \ + * | ||\ => | \ + * | || \ | \ + * | || | | | + * |__||_/ |_____/ + * + * + * _______ _______ + * | | __ | \__ + * | ||__| => | __| + * |_______| |_______/ + */ +static enum isl_change is_adj_ineq_extension_with_wraps(int i, int j, int k, + struct isl_coalesce_info *info, __isl_keep isl_mat *extra) +{ + struct isl_tab_undo *snap; + isl_size n_eq_i, n_ineq_j, n_extra; + isl_size total = isl_basic_map_dim(info[i].bmap, isl_dim_all); + isl_stat r; + isl_bool super; + + if (total < 0) + return isl_change_error; + + n_eq_i = isl_basic_map_n_equality(info[i].bmap); + n_ineq_j = isl_basic_map_n_inequality(info[j].bmap); + n_extra = isl_mat_rows(extra); + if (n_eq_i < 0 || n_ineq_j < 0 || n_extra < 0) + return isl_change_error; + + if (isl_tab_extend_cons(info[i].tab, 1 + n_ineq_j + n_extra) < 0) + return isl_change_error; + + snap = isl_tab_snap(info[i].tab); + + if (isl_tab_unrestrict(info[i].tab, n_eq_i + k) < 0) + return isl_change_error; + + isl_seq_neg(info[i].bmap->ineq[k], info[i].bmap->ineq[k], 1 + total); + isl_int_sub_ui(info[i].bmap->ineq[k][0], info[i].bmap->ineq[k][0], 1); + r = isl_tab_add_ineq(info[i].tab, info[i].bmap->ineq[k]); + isl_seq_neg(info[i].bmap->ineq[k], info[i].bmap->ineq[k], 1 + total); + isl_int_sub_ui(info[i].bmap->ineq[k][0], info[i].bmap->ineq[k][0], 1); + if (r < 0) + return isl_change_error; + + for (k = 0; k < n_ineq_j; ++k) { + if (info[j].ineq[k] != STATUS_VALID) + continue; + if (isl_tab_add_ineq(info[i].tab, info[j].bmap->ineq[k]) < 0) + return isl_change_error; + } + for (k = 0; k < n_extra; ++k) { + if (isl_tab_add_ineq(info[i].tab, extra->row[k]) < 0) + return isl_change_error; + } + if (isl_tab_detect_constants(info[i].tab) < 0) + return isl_change_error; + + super = contains(&info[j], info[i].tab); + if (super < 0) + return isl_change_error; + if (super) + return fuse(i, j, info, extra, 0, 0); + + if (isl_tab_rollback(info[i].tab, snap) < 0) + return isl_change_error; + + return isl_change_none; +} + +/* Given an affine transformation matrix "T", does row "row" represent + * anything other than a unit vector (possibly shifted by a constant) + * that is not involved in any of the other rows? + * + * That is, if a constraint involves the variable corresponding to + * the row, then could its preimage by "T" have any coefficients + * that are different from those in the original constraint? + */ +static int not_unique_unit_row(__isl_keep isl_mat *T, int row) +{ + int i, j; + int len = T->n_col - 1; + + i = isl_seq_first_non_zero(T->row[row] + 1, len); + if (i < 0) + return 1; + if (!isl_int_is_one(T->row[row][1 + i]) && + !isl_int_is_negone(T->row[row][1 + i])) + return 1; + + j = isl_seq_first_non_zero(T->row[row] + 1 + i + 1, len - (i + 1)); + if (j >= 0) + return 1; + + for (j = 1; j < T->n_row; ++j) { + if (j == row) + continue; + if (!isl_int_is_zero(T->row[j][1 + i])) + return 1; + } + + return 0; +} + +/* Does inequality constraint "ineq" of "bmap" involve any of + * the variables marked in "affected"? + * "total" is the total number of variables, i.e., the number + * of entries in "affected". + */ +static isl_bool is_affected(__isl_keep isl_basic_map *bmap, int ineq, + int *affected, int total) +{ + int i; + + for (i = 0; i < total; ++i) { + if (!affected[i]) + continue; + if (!isl_int_is_zero(bmap->ineq[ineq][1 + i])) + return isl_bool_true; + } + + return isl_bool_false; +} + +/* Given the compressed version of inequality constraint "ineq" + * of info->bmap in "v", check if the constraint can be tightened, + * where the compression is based on an equality constraint valid + * for info->tab. + * If so, add the tightened version of the inequality constraint + * to info->tab. "v" may be modified by this function. + * + * That is, if the compressed constraint is of the form + * + * m f() + c >= 0 + * + * with 0 < c < m, then it is equivalent to + * + * f() >= 0 + * + * This means that c can also be subtracted from the original, + * uncompressed constraint without affecting the integer points + * in info->tab. Add this tightened constraint as an extra row + * to info->tab to make this information explicitly available. + */ +static __isl_give isl_vec *try_tightening(struct isl_coalesce_info *info, + int ineq, __isl_take isl_vec *v) +{ + isl_ctx *ctx; + isl_stat r; + + if (!v) + return NULL; + + ctx = isl_vec_get_ctx(v); + isl_seq_gcd(v->el + 1, v->size - 1, &ctx->normalize_gcd); + if (isl_int_is_zero(ctx->normalize_gcd) || + isl_int_is_one(ctx->normalize_gcd)) { + return v; + } + + v = isl_vec_cow(v); + if (!v) + return NULL; + + isl_int_fdiv_r(v->el[0], v->el[0], ctx->normalize_gcd); + if (isl_int_is_zero(v->el[0])) + return v; + + if (isl_tab_extend_cons(info->tab, 1) < 0) + return isl_vec_free(v); + + isl_int_sub(info->bmap->ineq[ineq][0], + info->bmap->ineq[ineq][0], v->el[0]); + r = isl_tab_add_ineq(info->tab, info->bmap->ineq[ineq]); + isl_int_add(info->bmap->ineq[ineq][0], + info->bmap->ineq[ineq][0], v->el[0]); + + if (r < 0) + return isl_vec_free(v); + + return v; +} + +/* Tighten the (non-redundant) constraints on the facet represented + * by info->tab. + * In particular, on input, info->tab represents the result + * of relaxing the "n" inequality constraints of info->bmap in "relaxed" + * by one, i.e., replacing f_i >= 0 by f_i + 1 >= 0, and then + * replacing the one at index "l" by the corresponding equality, + * i.e., f_k + 1 = 0, with k = relaxed[l]. + * + * Compute a variable compression from the equality constraint f_k + 1 = 0 + * and use it to tighten the other constraints of info->bmap + * (that is, all constraints that have not been relaxed), + * updating info->tab (and leaving info->bmap untouched). + * The compression handles essentially two cases, one where a variable + * is assigned a fixed value and can therefore be eliminated, and one + * where one variable is a shifted multiple of some other variable and + * can therefore be replaced by that multiple. + * Gaussian elimination would also work for the first case, but for + * the second case, the effectiveness would depend on the order + * of the variables. + * After compression, some of the constraints may have coefficients + * with a common divisor. If this divisor does not divide the constant + * term, then the constraint can be tightened. + * The tightening is performed on the tableau info->tab by introducing + * extra (temporary) constraints. + * + * Only constraints that are possibly affected by the compression are + * considered. In particular, if the constraint only involves variables + * that are directly mapped to a distinct set of other variables, then + * no common divisor can be introduced and no tightening can occur. + * + * It is important to only consider the non-redundant constraints + * since the facet constraint has been relaxed prior to the call + * to this function, meaning that the constraints that were redundant + * prior to the relaxation may no longer be redundant. + * These constraints will be ignored in the fused result, so + * the fusion detection should not exploit them. + */ +static isl_stat tighten_on_relaxed_facet(struct isl_coalesce_info *info, + int n, int *relaxed, int l) +{ + isl_size total; + isl_ctx *ctx; + isl_vec *v = NULL; + isl_mat *T; + int i; + int k; + int *affected; + + k = relaxed[l]; + ctx = isl_basic_map_get_ctx(info->bmap); + total = isl_basic_map_dim(info->bmap, isl_dim_all); + if (total < 0) + return isl_stat_error; + isl_int_add_ui(info->bmap->ineq[k][0], info->bmap->ineq[k][0], 1); + T = isl_mat_sub_alloc6(ctx, info->bmap->ineq, k, 1, 0, 1 + total); + T = isl_mat_variable_compression(T, NULL); + isl_int_sub_ui(info->bmap->ineq[k][0], info->bmap->ineq[k][0], 1); + if (!T) + return isl_stat_error; + if (T->n_col == 0) { + isl_mat_free(T); + return isl_stat_ok; + } + + affected = isl_alloc_array(ctx, int, total); + if (!affected) + goto error; + + for (i = 0; i < total; ++i) + affected[i] = not_unique_unit_row(T, 1 + i); + + for (i = 0; i < info->bmap->n_ineq; ++i) { + isl_bool handle; + if (any(relaxed, n, i)) + continue; + if (info->ineq[i] == STATUS_REDUNDANT) + continue; + handle = is_affected(info->bmap, i, affected, total); + if (handle < 0) + goto error; + if (!handle) + continue; + v = isl_vec_alloc(ctx, 1 + total); + if (!v) + goto error; + isl_seq_cpy(v->el, info->bmap->ineq[i], 1 + total); + v = isl_vec_mat_product(v, isl_mat_copy(T)); + v = try_tightening(info, i, v); + isl_vec_free(v); + if (!v) + goto error; + } + + isl_mat_free(T); + free(affected); + return isl_stat_ok; +error: + isl_mat_free(T); + free(affected); + return isl_stat_error; +} + +/* Replace the basic maps "i" and "j" by an extension of "i" + * along the "n" inequality constraints in "relax" by one. + * The tableau info[i].tab has already been extended. + * Extend info[i].bmap accordingly by relaxing all constraints in "relax" + * by one. + * Each integer division that does not have exactly the same + * definition in "i" and "j" is marked unknown and the basic map + * is scheduled to be simplified in an attempt to recover + * the integer division definition. + * Place the extension in the position that is the smallest of i and j. + */ +static enum isl_change extend(int i, int j, int n, int *relax, + struct isl_coalesce_info *info) +{ + int l; + isl_size total; + + info[i].bmap = isl_basic_map_cow(info[i].bmap); + total = isl_basic_map_dim(info[i].bmap, isl_dim_all); + if (total < 0) + return isl_change_error; + for (l = 0; l < info[i].bmap->n_div; ++l) + if (!isl_seq_eq(info[i].bmap->div[l], + info[j].bmap->div[l], 1 + 1 + total)) { + isl_int_set_si(info[i].bmap->div[l][0], 0); + info[i].simplify = 1; + } + for (l = 0; l < n; ++l) + isl_int_add_ui(info[i].bmap->ineq[relax[l]][0], + info[i].bmap->ineq[relax[l]][0], 1); + ISL_F_CLR(info[i].bmap, ISL_BASIC_MAP_NO_REDUNDANT); + ISL_F_SET(info[i].bmap, ISL_BASIC_MAP_FINAL); + drop(&info[j]); + info[i].modified = 1; + if (j < i) + exchange(&info[i], &info[j]); + return isl_change_fuse; +} + +/* Basic map "i" has "n" inequality constraints (collected in "relax") + * that are such that they include basic map "j" if they are relaxed + * by one. All the other inequalities are valid for "j". + * Check if basic map "j" forms an extension of basic map "i". + * + * In particular, relax the constraints in "relax", compute the corresponding + * facets one by one and check whether each of these is included + * in the other basic map. + * Before testing for inclusion, the constraints on each facet + * are tightened to increase the chance of an inclusion being detected. + * (Adding the valid constraints of "j" to the tableau of "i", as is done + * in is_adj_ineq_extension, may further increase those chances, but this + * is not currently done.) + * If each facet is included, we know that relaxing the constraints extends + * the basic map with exactly the other basic map (we already know that this + * other basic map is included in the extension, because all other + * inequality constraints are valid of "j") and we can replace the + * two basic maps by this extension. + * + * If any of the relaxed constraints turn out to be redundant, then bail out. + * isl_tab_select_facet refuses to handle such constraints. It may be + * possible to handle them anyway by making a distinction between + * redundant constraints with a corresponding facet that still intersects + * the set (allowing isl_tab_select_facet to handle them) and + * those where the facet does not intersect the set (which can be ignored + * because the empty facet is trivially included in the other disjunct). + * However, relaxed constraints that turn out to be redundant should + * be fairly rare and no such instance has been reported where + * coalescing would be successful. + * ____ _____ + * / || / | + * / || / | + * \ || => \ | + * \ || \ | + * \___|| \____| + * + * + * \ |\ + * |\\ | \ + * | \\ | \ + * | | => | / + * | / | / + * |/ |/ + */ +static enum isl_change is_relaxed_extension(int i, int j, int n, int *relax, + struct isl_coalesce_info *info) +{ + int l; + isl_bool super; + struct isl_tab_undo *snap, *snap2; + unsigned n_eq = info[i].bmap->n_eq; + + for (l = 0; l < n; ++l) + if (isl_tab_is_equality(info[i].tab, n_eq + relax[l])) + return isl_change_none; + + snap = isl_tab_snap(info[i].tab); + for (l = 0; l < n; ++l) + if (isl_tab_relax(info[i].tab, n_eq + relax[l]) < 0) + return isl_change_error; + for (l = 0; l < n; ++l) { + if (!isl_tab_is_redundant(info[i].tab, n_eq + relax[l])) + continue; + if (isl_tab_rollback(info[i].tab, snap) < 0) + return isl_change_error; + return isl_change_none; + } + snap2 = isl_tab_snap(info[i].tab); + for (l = 0; l < n; ++l) { + if (isl_tab_rollback(info[i].tab, snap2) < 0) + return isl_change_error; + if (isl_tab_select_facet(info[i].tab, n_eq + relax[l]) < 0) + return isl_change_error; + if (tighten_on_relaxed_facet(&info[i], n, relax, l) < 0) + return isl_change_error; + super = contains(&info[j], info[i].tab); + if (super < 0) + return isl_change_error; + if (super) + continue; + if (isl_tab_rollback(info[i].tab, snap) < 0) + return isl_change_error; + return isl_change_none; + } + + if (isl_tab_rollback(info[i].tab, snap2) < 0) + return isl_change_error; + return extend(i, j, n, relax, info); +} + +/* Data structure that keeps track of the wrapping constraints + * and of information to bound the coefficients of those constraints. + * + * "failed" is set if wrapping has failed. + * bound is set if we want to apply a bound on the coefficients + * mat contains the wrapping constraints + * max is the bound on the coefficients (if bound is set) + */ +struct isl_wraps { + int failed; + int bound; + isl_mat *mat; + isl_int max; +}; + +/* Update wraps->max to be greater than or equal to the coefficients + * in the equalities and inequalities of info->bmap that can be removed + * if we end up applying wrapping. + */ +static isl_stat wraps_update_max(struct isl_wraps *wraps, + struct isl_coalesce_info *info) +{ + int k; + isl_int max_k; + isl_size total = isl_basic_map_dim(info->bmap, isl_dim_all); + + if (total < 0) + return isl_stat_error; + isl_int_init(max_k); + + for (k = 0; k < info->bmap->n_eq; ++k) { + if (info->eq[2 * k] == STATUS_VALID && + info->eq[2 * k + 1] == STATUS_VALID) + continue; + isl_seq_abs_max(info->bmap->eq[k] + 1, total, &max_k); + if (isl_int_abs_gt(max_k, wraps->max)) + isl_int_set(wraps->max, max_k); + } + + for (k = 0; k < info->bmap->n_ineq; ++k) { + if (info->ineq[k] == STATUS_VALID || + info->ineq[k] == STATUS_REDUNDANT) + continue; + isl_seq_abs_max(info->bmap->ineq[k] + 1, total, &max_k); + if (isl_int_abs_gt(max_k, wraps->max)) + isl_int_set(wraps->max, max_k); + } + + isl_int_clear(max_k); + + return isl_stat_ok; +} + +/* Initialize the isl_wraps data structure. + * If we want to bound the coefficients of the wrapping constraints, + * we set wraps->max to the largest coefficient + * in the equalities and inequalities that can be removed if we end up + * applying wrapping. + */ +static isl_stat wraps_init(struct isl_wraps *wraps, __isl_take isl_mat *mat, + struct isl_coalesce_info *info, int i, int j) +{ + isl_ctx *ctx; + + wraps->failed = 0; + wraps->bound = 0; + wraps->mat = mat; + if (!mat) + return isl_stat_error; + wraps->mat->n_row = 0; + ctx = isl_mat_get_ctx(mat); + wraps->bound = isl_options_get_coalesce_bounded_wrapping(ctx); + if (!wraps->bound) + return isl_stat_ok; + isl_int_init(wraps->max); + isl_int_set_si(wraps->max, 0); + if (wraps_update_max(wraps, &info[i]) < 0) + return isl_stat_error; + if (wraps_update_max(wraps, &info[j]) < 0) + return isl_stat_error; + + return isl_stat_ok; +} + +/* Free the contents of the isl_wraps data structure. + */ +static void wraps_free(struct isl_wraps *wraps) +{ + isl_mat_free(wraps->mat); + if (wraps->bound) + isl_int_clear(wraps->max); +} + +/* Mark the wrapping as failed. + */ +static isl_stat wraps_mark_failed(struct isl_wraps *wraps) +{ + wraps->failed = 1; + return isl_stat_ok; +} + +/* Is the wrapping constraint in row "row" allowed? + * + * If wraps->bound is set, we check that none of the coefficients + * is greater than wraps->max. + */ +static int allow_wrap(struct isl_wraps *wraps, int row) +{ + int i; + + if (!wraps->bound) + return 1; + + for (i = 1; i < wraps->mat->n_col; ++i) + if (isl_int_abs_gt(wraps->mat->row[row][i], wraps->max)) + return 0; + + return 1; +} + +/* Wrap "ineq" (or its opposite if "negate" is set) around "bound" + * to include "set" and add the result in position "w" of "wraps". + * "len" is the total number of coefficients in "bound" and "ineq". + * Return 1 on success, 0 on failure and -1 on error. + * Wrapping can fail if the result of wrapping is equal to "bound" + * or if we want to bound the sizes of the coefficients and + * the wrapped constraint does not satisfy this bound. + */ +static int add_wrap(struct isl_wraps *wraps, int w, isl_int *bound, + isl_int *ineq, unsigned len, __isl_keep isl_set *set, int negate) +{ + isl_seq_cpy(wraps->mat->row[w], bound, len); + if (negate) { + isl_seq_neg(wraps->mat->row[w + 1], ineq, len); + ineq = wraps->mat->row[w + 1]; + } + if (!isl_set_wrap_facet(set, wraps->mat->row[w], ineq)) + return -1; + if (isl_seq_eq(wraps->mat->row[w], bound, len)) + return 0; + if (!allow_wrap(wraps, w)) + return 0; + return 1; +} + +/* This function has two modes of operations. + * + * If "add_valid" is set, then all the constraints of info->bmap + * (except the opposite of "bound") are valid for the other basic map. + * In this case, attempts are made to wrap some of these valid constraints + * to more tightly fit around "set". Only successful wrappings are recorded + * and failed wrappings are ignored. + * + * If "add_valid" is not set, then some of the constraints of info->bmap + * are not valid for the other basic map, and only those are considered + * for wrapping. In this case all attempted wrappings need to succeed. + * Otherwise "wraps" is marked as failed. + * Note that the constraints that are valid for the other basic map + * will be added to the combined basic map by default, so there is + * no need to wrap them. + * The caller wrap_in_facets even relies on this function not wrapping + * any constraints that are already valid. + * + * Only consider constraints that are not redundant (as determined + * by info->tab) and that are valid or invalid depending on "add_valid". + * Wrap each constraint around "bound" such that it includes the whole + * set "set" and append the resulting constraint to "wraps". + * "wraps" is assumed to have been pre-allocated to the appropriate size. + * wraps->n_row is the number of actual wrapped constraints that have + * been added. + * If any of the wrapping problems results in a constraint that is + * identical to "bound", then this means that "set" is unbounded in such + * a way that no wrapping is possible. + * Similarly, if we want to bound the coefficients of the wrapping + * constraints and a newly added wrapping constraint does not + * satisfy the bound, then the wrapping is considered to have failed. + * Note though that "wraps" is only marked failed if "add_valid" is not set. + */ +static isl_stat add_selected_wraps(struct isl_wraps *wraps, + struct isl_coalesce_info *info, isl_int *bound, __isl_keep isl_set *set, + int add_valid) +{ + int l, m; + int w; + int added; + isl_basic_map *bmap = info->bmap; + isl_size total = isl_basic_map_dim(bmap, isl_dim_all); + unsigned len = 1 + total; + + if (total < 0) + return isl_stat_error; + + w = wraps->mat->n_row; + + for (l = 0; l < bmap->n_ineq; ++l) { + int is_valid = info->ineq[l] == STATUS_VALID; + if ((!add_valid && is_valid) || + info->ineq[l] == STATUS_REDUNDANT) + continue; + if (isl_seq_is_neg(bound, bmap->ineq[l], len)) + continue; + if (isl_seq_eq(bound, bmap->ineq[l], len)) + continue; + if (isl_tab_is_redundant(info->tab, bmap->n_eq + l)) + continue; + + added = add_wrap(wraps, w, bound, bmap->ineq[l], len, set, 0); + if (added < 0) + return isl_stat_error; + if (!added && !is_valid) + goto unbounded; + if (added) + ++w; + } + for (l = 0; l < bmap->n_eq; ++l) { + if (isl_seq_is_neg(bound, bmap->eq[l], len)) + continue; + if (isl_seq_eq(bound, bmap->eq[l], len)) + continue; + + for (m = 0; m < 2; ++m) { + if (info->eq[2 * l + m] == STATUS_VALID) + continue; + added = add_wrap(wraps, w, bound, bmap->eq[l], len, + set, !m); + if (added < 0) + return isl_stat_error; + if (!added) + goto unbounded; + ++w; + } + } + + wraps->mat->n_row = w; + return isl_stat_ok; +unbounded: + return wraps_mark_failed(wraps); +} + +/* For each constraint in info->bmap that is not redundant (as determined + * by info->tab) and that is not a valid constraint for the other basic map, + * wrap the constraint around "bound" such that it includes the whole + * set "set" and append the resulting constraint to "wraps". + * Note that the constraints that are valid for the other basic map + * will be added to the combined basic map by default, so there is + * no need to wrap them. + * The caller wrap_in_facets even relies on this function not wrapping + * any constraints that are already valid. + * "wraps" is assumed to have been pre-allocated to the appropriate size. + * wraps->n_row is the number of actual wrapped constraints that have + * been added. + * If any of the wrapping problems results in a constraint that is + * identical to "bound", then this means that "set" is unbounded in such + * a way that no wrapping is possible. If this happens then "wraps" + * is marked as failed. + * Similarly, if we want to bound the coefficients of the wrapping + * constraints and a newly added wrapping constraint does not + * satisfy the bound, then "wraps" is also marked as failed. + */ +static isl_stat add_wraps(struct isl_wraps *wraps, + struct isl_coalesce_info *info, isl_int *bound, __isl_keep isl_set *set) +{ + return add_selected_wraps(wraps, info, bound, set, 0); +} + +/* Check if the constraints in "wraps" from "first" until the last + * are all valid for the basic set represented by "tab", + * dropping the invalid constraints if "keep" is set and + * marking the wrapping as failed if "keep" is not set and + * any constraint turns out to be invalid. + */ +static isl_stat check_wraps(struct isl_wraps *wraps, int first, + struct isl_tab *tab, int keep) +{ + int i; + + for (i = wraps->mat->n_row - 1; i >= first; --i) { + enum isl_ineq_type type; + type = isl_tab_ineq_type(tab, wraps->mat->row[i]); + if (type == isl_ineq_error) + return isl_stat_error; + if (type == isl_ineq_redundant) + continue; + if (!keep) + return wraps_mark_failed(wraps); + wraps->mat = isl_mat_drop_rows(wraps->mat, i, 1); + if (!wraps->mat) + return isl_stat_error; + } + + return isl_stat_ok; +} + +/* Return a set that corresponds to the non-redundant constraints + * (as recorded in tab) of bmap. + * + * It's important to remove the redundant constraints as some + * of the other constraints may have been modified after the + * constraints were marked redundant. + * In particular, a constraint may have been relaxed. + * Redundant constraints are ignored when a constraint is relaxed + * and should therefore continue to be ignored ever after. + * Otherwise, the relaxation might be thwarted by some of + * these constraints. + * + * Update the underlying set to ensure that the dimension doesn't change. + * Otherwise the integer divisions could get dropped if the tab + * turns out to be empty. + */ +static __isl_give isl_set *set_from_updated_bmap(__isl_keep isl_basic_map *bmap, + struct isl_tab *tab) +{ + isl_basic_set *bset; + + bmap = isl_basic_map_copy(bmap); + bset = isl_basic_map_underlying_set(bmap); + bset = isl_basic_set_cow(bset); + bset = isl_basic_set_update_from_tab(bset, tab); + return isl_set_from_basic_set(bset); +} + +/* Does "info" have any cut constraints that are redundant? + */ +static isl_bool has_redundant_cuts(struct isl_coalesce_info *info) +{ + int l; + isl_size n_eq, n_ineq; + + n_eq = isl_basic_map_n_equality(info->bmap); + n_ineq = isl_basic_map_n_inequality(info->bmap); + if (n_eq < 0 || n_ineq < 0) + return isl_bool_error; + for (l = 0; l < n_ineq; ++l) { + int red; + + if (info->ineq[l] != STATUS_CUT) + continue; + red = isl_tab_is_redundant(info->tab, n_eq + l); + if (red < 0) + return isl_bool_error; + if (red) + return isl_bool_true; + } + + return isl_bool_false; +} + +/* Wrap some constraints of info->bmap that bound the facet defined + * by inequality "k" around (the opposite of) this inequality to + * include "set". "bound" may be used to store the negated inequality. + * + * If "add_valid" is set, then all ridges are already valid and + * the purpose is to wrap "set" more tightly. In this case, + * wrapping doesn't fail, although it is possible that no constraint + * gets wrapped. + * + * If "add_valid" is not set, then some of the ridges are cut constraints + * and only those are wrapped around "set". + * + * Since the wrapped constraints are not guaranteed to contain the whole + * of info->bmap, we check them in check_wraps. + * If any of the wrapped constraints turn out to be invalid, then + * check_wraps will mark "wraps" as failed if "add_valid" is not set. + * If "add_valid" is set, then the offending constraints are + * simply removed. + * + * If the facet turns out to be empty, then no wrapping can be performed. + * This is considered a failure, unless "add_valid" is set. + * + * If any of the cut constraints of info->bmap turn out + * to be redundant with respect to other constraints + * then these will neither be wrapped nor added directly to the result. + * The result may therefore not be correct. + * Skip wrapping and mark "wraps" as failed in this case. + */ +static isl_stat add_selected_wraps_around_facet(struct isl_wraps *wraps, + struct isl_coalesce_info *info, int k, isl_int *bound, + __isl_keep isl_set *set, int add_valid) +{ + isl_bool nowrap; + struct isl_tab_undo *snap; + int n; + isl_size total = isl_basic_map_dim(info->bmap, isl_dim_all); + + if (total < 0) + return isl_stat_error; + + snap = isl_tab_snap(info->tab); + + if (isl_tab_select_facet(info->tab, info->bmap->n_eq + k) < 0) + return isl_stat_error; + if (isl_tab_detect_redundant(info->tab) < 0) + return isl_stat_error; + if (info->tab->empty) { + if (isl_tab_rollback(info->tab, snap) < 0) + return isl_stat_error; + if (!add_valid) + return wraps_mark_failed(wraps); + return isl_stat_ok; + } + nowrap = has_redundant_cuts(info); + if (nowrap < 0) + return isl_stat_error; + + n = wraps->mat->n_row; + if (!nowrap) { + isl_seq_neg(bound, info->bmap->ineq[k], 1 + total); + + if (add_selected_wraps(wraps, info, bound, set, add_valid) < 0) + return isl_stat_error; + } + + if (isl_tab_rollback(info->tab, snap) < 0) + return isl_stat_error; + if (nowrap) + return wraps_mark_failed(wraps); + if (check_wraps(wraps, n, info->tab, add_valid) < 0) + return isl_stat_error; + + return isl_stat_ok; +} + +/* Wrap the constraints of info->bmap that bound the facet defined + * by inequality "k" around (the opposite of) this inequality to + * include "set". "bound" may be used to store the negated inequality. + * If any of the wrapped constraints turn out to be invalid for info->bmap + * itself, then mark "wraps" as failed. + */ +static isl_stat add_wraps_around_facet(struct isl_wraps *wraps, + struct isl_coalesce_info *info, int k, isl_int *bound, + __isl_keep isl_set *set) +{ + return add_selected_wraps_around_facet(wraps, info, k, bound, set, 0); +} + +/* Wrap the (valid) constraints of info->bmap that bound the facet defined + * by inequality "k" around (the opposite of) this inequality to + * include "set" more tightly. + * "bound" may be used to store the negated inequality. + * Remove any wrapping constraints that turn out to be invalid + * for info->bmap itself. + */ +static isl_stat add_valid_wraps_around_facet(struct isl_wraps *wraps, + struct isl_coalesce_info *info, int k, isl_int *bound, + __isl_keep isl_set *set) +{ + return add_selected_wraps_around_facet(wraps, info, k, bound, set, 1); +} + +/* Basic map "i" has an inequality (say "k") that is adjacent + * to some inequality of basic map "j". All the other inequalities + * are valid for "j". + * Check if basic map "j" forms an extension of basic map "i". + * + * Note that this function is only called if some of the equalities or + * inequalities of basic map "j" do cut basic map "i". The function is + * correct even if there are no such cut constraints, but in that case + * the additional checks performed by this function are overkill. + * + * First try and wrap the ridges of "k" around "j". + * Note that those ridges are already valid for "j", + * but the wrapped versions may wrap "j" more tightly, + * increasing the chances of "j" being detected as an extension of "i" + */ +static enum isl_change is_adj_ineq_extension(int i, int j, + struct isl_coalesce_info *info) +{ + int k; + enum isl_change change; + isl_size total; + isl_size n_eq_i, n_ineq_i; + struct isl_wraps wraps; + isl_ctx *ctx; + isl_mat *mat; + isl_vec *bound; + isl_set *set_j; + isl_stat r; + + 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", + return isl_change_error); + + total = isl_basic_map_dim(info[i].bmap, isl_dim_all); + n_eq_i = isl_basic_map_n_equality(info[i].bmap); + n_ineq_i = isl_basic_map_n_inequality(info[i].bmap); + if (total < 0 || n_eq_i < 0 || n_ineq_i < 0) + return isl_change_error; + + set_j = set_from_updated_bmap(info[j].bmap, info[j].tab); + ctx = isl_basic_map_get_ctx(info[i].bmap); + bound = isl_vec_alloc(ctx, 1 + total); + mat = isl_mat_alloc(ctx, 2 * n_eq_i + n_ineq_i, 1 + total); + if (wraps_init(&wraps, mat, info, i, j) < 0) + goto error; + if (!bound || !set_j) + goto error; + r = add_valid_wraps_around_facet(&wraps, &info[i], k, bound->el, set_j); + if (r < 0) + goto error; + + change = is_adj_ineq_extension_with_wraps(i, j, k, info, wraps.mat); + + wraps_free(&wraps); + isl_vec_free(bound); + isl_set_free(set_j); + + return change; +error: + wraps_free(&wraps); + isl_vec_free(bound); + isl_set_free(set_j); + return isl_change_error; +} + +/* Both basic maps have at least one inequality with and adjacent + * (but opposite) inequality in the other basic map. + * Check that there are no cut constraints and that there is only + * a single pair of adjacent inequalities. + * If so, we can replace the pair by a single basic map described + * by all but the pair of adjacent inequalities. + * Any additional points introduced lie strictly between the two + * adjacent hyperplanes and can therefore be integral. + * + * ____ _____ + * / ||\ / \ + * / || \ / \ + * \ || \ => \ \ + * \ || / \ / + * \___||_/ \_____/ + * + * The test for a single pair of adjacent inequalities is important + * for avoiding the combination of two basic maps like the following + * + * /| + * / | + * /__| + * _____ + * | | + * | | + * |___| + * + * If there are some cut constraints on one side, then we may + * still be able to fuse the two basic maps, but we need to perform + * some additional checks in is_adj_ineq_extension. + */ +static enum isl_change check_adj_ineq(int i, int j, + struct isl_coalesce_info *info) +{ + int count_i, count_j; + int cut_i, cut_j; + + 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_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); + + if (count_i == 1 && !cut_i) + return is_adj_ineq_extension(i, j, info); + + if (count_j == 1 && !cut_j) + return is_adj_ineq_extension(j, i, info); + + return isl_change_none; +} + +/* Given a basic set i with a constraint k that is adjacent to + * basic set j, check if we can wrap + * both the facet corresponding to k (if "wrap_facet" is set) and basic map j + * (always) around their ridges to include the other set. + * If so, replace the pair of basic sets by their union. + * + * All constraints of i (except k) are assumed to be valid or + * cut constraints for j. + * Wrapping the cut constraints to include basic map j may result + * in constraints that are no longer valid of basic map i + * we have to check that the resulting wrapping constraints are valid for i. + * If "wrap_facet" is not set, then all constraints of i (except k) + * are assumed to be valid for j. + * ____ _____ + * / | / \ + * / || / | + * \ || => \ | + * \ || \ | + * \___|| \____| + * + */ +static enum isl_change can_wrap_in_facet(int i, int j, int k, + struct isl_coalesce_info *info, int wrap_facet) +{ + enum isl_change change = isl_change_none; + struct isl_wraps wraps; + isl_ctx *ctx; + isl_mat *mat; + struct isl_set *set_i = NULL; + struct isl_set *set_j = NULL; + struct isl_vec *bound = NULL; + isl_size total = isl_basic_map_dim(info[i].bmap, isl_dim_all); + + if (total < 0) + return isl_change_error; + set_i = set_from_updated_bmap(info[i].bmap, info[i].tab); + set_j = set_from_updated_bmap(info[j].bmap, info[j].tab); + ctx = isl_basic_map_get_ctx(info[i].bmap); + mat = isl_mat_alloc(ctx, 2 * (info[i].bmap->n_eq + info[j].bmap->n_eq) + + info[i].bmap->n_ineq + info[j].bmap->n_ineq, + 1 + total); + if (wraps_init(&wraps, mat, info, i, j) < 0) + goto error; + bound = isl_vec_alloc(ctx, 1 + total); + if (!set_i || !set_j || !bound) + goto error; + + isl_seq_cpy(bound->el, info[i].bmap->ineq[k], 1 + total); + isl_int_add_ui(bound->el[0], bound->el[0], 1); + isl_seq_normalize(ctx, bound->el, 1 + total); + + isl_seq_cpy(wraps.mat->row[0], bound->el, 1 + total); + wraps.mat->n_row = 1; + + if (add_wraps(&wraps, &info[j], bound->el, set_i) < 0) + goto error; + if (wraps.failed) + goto unbounded; + + if (wrap_facet) { + if (add_wraps_around_facet(&wraps, &info[i], k, + bound->el, set_j) < 0) + goto error; + if (wraps.failed) + goto unbounded; + } + + change = fuse(i, j, info, wraps.mat, 0, 0); + +unbounded: + wraps_free(&wraps); + + isl_set_free(set_i); + isl_set_free(set_j); + + isl_vec_free(bound); + + return change; +error: + wraps_free(&wraps); + isl_vec_free(bound); + isl_set_free(set_i); + isl_set_free(set_j); + return isl_change_error; +} + +/* Given a cut constraint t(x) >= 0 of basic map i, stored in row "w" + * of wrap.mat, replace it by its relaxed version t(x) + 1 >= 0, and + * add wrapping constraints to wrap.mat for all constraints + * of basic map j that bound the part of basic map j that sticks out + * of the cut constraint. + * "set_i" is the underlying set of basic map i. + * If any wrapping fails, then wraps->mat.n_row is reset to zero. + * + * In particular, we first intersect basic map j with t(x) + 1 = 0. + * If the result is empty, then t(x) >= 0 was actually a valid constraint + * (with respect to the integer points), so we add t(x) >= 0 instead. + * Otherwise, we wrap the constraints of basic map j that are not + * redundant in this intersection and that are not already valid + * for basic map i over basic map i. + * Note that it is sufficient to wrap the constraints to include + * basic map i, because we will only wrap the constraints that do + * not include basic map i already. The wrapped constraint will + * therefore be more relaxed compared to the original constraint. + * Since the original constraint is valid for basic map j, so is + * the wrapped constraint. + */ +static isl_stat wrap_in_facet(struct isl_wraps *wraps, int w, + struct isl_coalesce_info *info_j, __isl_keep isl_set *set_i, + struct isl_tab_undo *snap) +{ + isl_int_add_ui(wraps->mat->row[w][0], wraps->mat->row[w][0], 1); + if (isl_tab_add_eq(info_j->tab, wraps->mat->row[w]) < 0) + return isl_stat_error; + if (isl_tab_detect_redundant(info_j->tab) < 0) + return isl_stat_error; + + if (info_j->tab->empty) + isl_int_sub_ui(wraps->mat->row[w][0], wraps->mat->row[w][0], 1); + else if (add_wraps(wraps, info_j, wraps->mat->row[w], set_i) < 0) + return isl_stat_error; + + if (isl_tab_rollback(info_j->tab, snap) < 0) + return isl_stat_error; + + return isl_stat_ok; +} + +/* Given a pair of basic maps i and j such that j sticks out + * of i at n cut constraints, each time by at most one, + * try to compute wrapping constraints and replace the two + * basic maps by a single basic map. + * The other constraints of i are assumed to be valid for j. + * "set_i" is the underlying set of basic map i. + * "wraps" has been initialized to be of the right size. + * + * For each cut constraint t(x) >= 0 of i, we add the relaxed version + * t(x) + 1 >= 0, along with wrapping constraints for all constraints + * of basic map j that bound the part of basic map j that sticks out + * of the cut constraint. + * + * If any wrapping fails, i.e., if we cannot wrap to touch + * the union, then we give up. + * Otherwise, the pair of basic maps is replaced by their union. + */ +static enum isl_change try_wrap_in_facets(int i, int j, + struct isl_coalesce_info *info, struct isl_wraps *wraps, + __isl_keep isl_set *set_i) +{ + int k, l, w; + isl_size total; + struct isl_tab_undo *snap; + + total = isl_basic_map_dim(info[i].bmap, isl_dim_all); + if (total < 0) + return isl_change_error; + + snap = isl_tab_snap(info[j].tab); + + for (k = 0; k < info[i].bmap->n_eq; ++k) { + for (l = 0; l < 2; ++l) { + if (info[i].eq[2 * k + l] != STATUS_CUT) + continue; + w = wraps->mat->n_row++; + if (l == 0) + isl_seq_neg(wraps->mat->row[w], + info[i].bmap->eq[k], 1 + total); + else + isl_seq_cpy(wraps->mat->row[w], + info[i].bmap->eq[k], 1 + total); + if (wrap_in_facet(wraps, w, &info[j], set_i, snap) < 0) + return isl_change_error; + + if (wraps->failed) + return isl_change_none; + } + } + + for (k = 0; k < info[i].bmap->n_ineq; ++k) { + if (info[i].ineq[k] != STATUS_CUT) + continue; + w = wraps->mat->n_row++; + isl_seq_cpy(wraps->mat->row[w], + info[i].bmap->ineq[k], 1 + total); + if (wrap_in_facet(wraps, w, &info[j], set_i, snap) < 0) + return isl_change_error; + + if (wraps->failed) + return isl_change_none; + } + + return fuse(i, j, info, wraps->mat, 0, 1); +} + +/* Given a pair of basic maps i and j such that j sticks out + * of i at n cut constraints, each time by at most one, + * try to compute wrapping constraints and replace the two + * basic maps by a single basic map. + * The other constraints of i are assumed to be valid for j. + * + * The core computation is performed by try_wrap_in_facets. + * This function simply extracts an underlying set representation + * of basic map i and initializes the data structure for keeping + * track of wrapping constraints. + */ +static enum isl_change wrap_in_facets(int i, int j, int n, + struct isl_coalesce_info *info) +{ + enum isl_change change = isl_change_none; + struct isl_wraps wraps; + isl_ctx *ctx; + isl_mat *mat; + isl_set *set_i = NULL; + isl_size total = isl_basic_map_dim(info[i].bmap, isl_dim_all); + int max_wrap; + + if (total < 0) + return isl_change_error; + if (isl_tab_extend_cons(info[j].tab, 1) < 0) + return isl_change_error; + + max_wrap = 1 + 2 * info[j].bmap->n_eq + info[j].bmap->n_ineq; + max_wrap *= n; + + set_i = set_from_updated_bmap(info[i].bmap, info[i].tab); + ctx = isl_basic_map_get_ctx(info[i].bmap); + mat = isl_mat_alloc(ctx, max_wrap, 1 + total); + if (wraps_init(&wraps, mat, info, i, j) < 0) + goto error; + if (!set_i) + goto error; + + change = try_wrap_in_facets(i, j, info, &wraps, set_i); + + wraps_free(&wraps); + isl_set_free(set_i); + + return change; +error: + wraps_free(&wraps); + isl_set_free(set_i); + return isl_change_error; +} + +/* Return the effect of inequality "ineq" on the tableau "tab", + * after relaxing the constant term of "ineq" by one. + */ +static enum isl_ineq_type type_of_relaxed(struct isl_tab *tab, isl_int *ineq) +{ + enum isl_ineq_type type; + + isl_int_add_ui(ineq[0], ineq[0], 1); + type = isl_tab_ineq_type(tab, ineq); + isl_int_sub_ui(ineq[0], ineq[0], 1); + + return type; +} + +/* Given two basic sets i and j, + * check if relaxing all the cut constraints of i by one turns + * them into valid constraint for j and check if we can wrap in + * the bits that are sticking out. + * If so, replace the pair by their union. + * + * We first check if all relaxed cut inequalities of i are valid for j + * and then try to wrap in the intersections of the relaxed cut inequalities + * with j. + * + * During this wrapping, we consider the points of j that lie at a distance + * of exactly 1 from i. In particular, we ignore the points that lie in + * between this lower-dimensional space and the basic map i. + * We can therefore only apply this to integer maps. + * ____ _____ + * / ___|_ / \ + * / | | / | + * \ | | => \ | + * \|____| \ | + * \___| \____/ + * + * _____ ______ + * | ____|_ | \ + * | | | | | + * | | | => | | + * |_| | | | + * |_____| \______| + * + * _______ + * | | + * | |\ | + * | | \ | + * | | \ | + * | | \| + * | | \ + * | |_____\ + * | | + * |_______| + * + * Wrapping can fail if the result of wrapping one of the facets + * around its edges does not produce any new facet constraint. + * In particular, this happens when we try to wrap in unbounded sets. + * + * _______________________________________________________________________ + * | + * | ___ + * | | | + * |_| |_________________________________________________________________ + * |___| + * + * The following is not an acceptable result of coalescing the above two + * sets as it includes extra integer points. + * _______________________________________________________________________ + * | + * | + * | + * | + * \______________________________________________________________________ + */ +static enum isl_change can_wrap_in_set(int i, int j, + struct isl_coalesce_info *info) +{ + int k, l; + int n; + isl_size total; + + if (ISL_F_ISSET(info[i].bmap, ISL_BASIC_MAP_RATIONAL) || + ISL_F_ISSET(info[j].bmap, ISL_BASIC_MAP_RATIONAL)) + return isl_change_none; + + n = count_eq(&info[i], STATUS_CUT) + count_ineq(&info[i], STATUS_CUT); + if (n == 0) + return isl_change_none; + + total = isl_basic_map_dim(info[i].bmap, isl_dim_all); + if (total < 0) + return isl_change_error; + for (k = 0; k < info[i].bmap->n_eq; ++k) { + for (l = 0; l < 2; ++l) { + enum isl_ineq_type type; + + if (info[i].eq[2 * k + l] != STATUS_CUT) + continue; + + if (l == 0) + isl_seq_neg(info[i].bmap->eq[k], + info[i].bmap->eq[k], 1 + total); + type = type_of_relaxed(info[j].tab, + info[i].bmap->eq[k]); + if (l == 0) + isl_seq_neg(info[i].bmap->eq[k], + info[i].bmap->eq[k], 1 + total); + if (type == isl_ineq_error) + return isl_change_error; + if (type != isl_ineq_redundant) + return isl_change_none; + } + } + + for (k = 0; k < info[i].bmap->n_ineq; ++k) { + enum isl_ineq_type type; + + if (info[i].ineq[k] != STATUS_CUT) + continue; + + type = type_of_relaxed(info[j].tab, info[i].bmap->ineq[k]); + if (type == isl_ineq_error) + return isl_change_error; + if (type != isl_ineq_redundant) + return isl_change_none; + } + + return wrap_in_facets(i, j, n, info); +} + +/* Check if either i or j has only cut constraints that can + * be used to wrap in (a facet of) the other basic set. + * if so, replace the pair by their union. + */ +static enum isl_change check_wrap(int i, int j, struct isl_coalesce_info *info) +{ + enum isl_change change = isl_change_none; + + change = can_wrap_in_set(i, j, info); + if (change != isl_change_none) + return change; + + change = can_wrap_in_set(j, i, info); + return change; +} + +/* Check if all inequality constraints of "i" that cut "j" cease + * to be cut constraints if they are relaxed by one. + * If so, collect the cut constraints in "list". + * The caller is responsible for allocating "list". + */ +static isl_bool all_cut_by_one(int i, int j, struct isl_coalesce_info *info, + int *list) +{ + int l, n; + + n = 0; + for (l = 0; l < info[i].bmap->n_ineq; ++l) { + enum isl_ineq_type type; + + if (info[i].ineq[l] != STATUS_CUT) + continue; + type = type_of_relaxed(info[j].tab, info[i].bmap->ineq[l]); + if (type == isl_ineq_error) + return isl_bool_error; + if (type != isl_ineq_redundant) + return isl_bool_false; + list[n++] = l; + } + + return isl_bool_true; +} + +/* Given two basic maps such that "j" has at least one equality constraint + * that is adjacent to an inequality constraint of "i" and such that "i" has + * exactly one inequality constraint that is adjacent to an equality + * constraint of "j", check whether "i" can be extended to include "j" or + * whether "j" can be wrapped into "i". + * All remaining constraints of "i" and "j" are assumed to be valid + * or cut constraints of the other basic map. + * However, none of the equality constraints of "i" are cut constraints. + * + * If "i" has any "cut" inequality constraints, then check if relaxing + * each of them by one is sufficient for them to become valid. + * If so, check if the inequality constraint adjacent to an equality + * constraint of "j" along with all these cut constraints + * can be relaxed by one to contain exactly "j". + * Otherwise, or if this fails, check if "j" can be wrapped into "i". + */ +static enum isl_change check_single_adj_eq(int i, int j, + struct isl_coalesce_info *info) +{ + enum isl_change change = isl_change_none; + int k; + int n_cut; + int *relax; + isl_ctx *ctx; + isl_bool try_relax; + + n_cut = count_ineq(&info[i], STATUS_CUT); + + k = find_ineq(&info[i], STATUS_ADJ_EQ); + + if (n_cut > 0) { + ctx = isl_basic_map_get_ctx(info[i].bmap); + relax = isl_calloc_array(ctx, int, 1 + n_cut); + if (!relax) + return isl_change_error; + relax[0] = k; + try_relax = all_cut_by_one(i, j, info, relax + 1); + if (try_relax < 0) + change = isl_change_error; + } else { + try_relax = isl_bool_true; + relax = &k; + } + if (try_relax && change == isl_change_none) + change = is_relaxed_extension(i, j, 1 + n_cut, relax, info); + if (n_cut > 0) + free(relax); + if (change != isl_change_none) + return change; + + change = can_wrap_in_facet(i, j, k, info, n_cut > 0); + + return change; +} + +/* At least one of the basic maps has an equality that is adjacent + * 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 + * check if all its constraints are either valid or cut constraints + * and, if so, try wrapping in the first map into the second. + * Otherwise, try to extend one basic map with the other or + * wrap one basic map in the other. + */ +static enum isl_change check_adj_eq(int i, int j, + struct isl_coalesce_info *info) +{ + 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_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_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_eq(&info[i], STATUS_CUT)) + return isl_change_none; + 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 + * to include the other set. + * + * We perform basically the same operations as can_wrap_in_facet, + * except that we don't need to select a facet of one of the sets. + * _ + * \\ \\ + * \\ => \\ + * \ \| + * + * If there is more than one equality of "i" adjacent to an equality of "j", + * then the result will satisfy one or more equalities that are a linear + * combination of these equalities. These will be encoded as pairs + * of inequalities in the wrapping constraints and need to be made + * explicit. + */ +static enum isl_change check_eq_adj_eq(int i, int j, + struct isl_coalesce_info *info) +{ + int k; + enum isl_change change = isl_change_none; + int detect_equalities = 0; + struct isl_wraps wraps; + isl_ctx *ctx; + isl_mat *mat; + struct isl_set *set_i = NULL; + struct isl_set *set_j = NULL; + struct isl_vec *bound = NULL; + isl_size total = isl_basic_map_dim(info[i].bmap, isl_dim_all); + + if (total < 0) + return isl_change_error; + if (count_eq(&info[i], STATUS_ADJ_EQ) != 1) + detect_equalities = 1; + + 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); + ctx = isl_basic_map_get_ctx(info[i].bmap); + mat = isl_mat_alloc(ctx, 2 * (info[i].bmap->n_eq + info[j].bmap->n_eq) + + info[i].bmap->n_ineq + info[j].bmap->n_ineq, + 1 + total); + if (wraps_init(&wraps, mat, info, i, j) < 0) + goto error; + bound = isl_vec_alloc(ctx, 1 + total); + if (!set_i || !set_j || !bound) + goto error; + + if (k % 2 == 0) + isl_seq_neg(bound->el, info[i].bmap->eq[k / 2], 1 + total); + else + isl_seq_cpy(bound->el, info[i].bmap->eq[k / 2], 1 + total); + isl_int_add_ui(bound->el[0], bound->el[0], 1); + + isl_seq_cpy(wraps.mat->row[0], bound->el, 1 + total); + wraps.mat->n_row = 1; + + if (add_wraps(&wraps, &info[j], bound->el, set_i) < 0) + goto error; + if (wraps.failed) + goto unbounded; + + isl_int_sub_ui(bound->el[0], bound->el[0], 1); + isl_seq_neg(bound->el, bound->el, 1 + total); + + isl_seq_cpy(wraps.mat->row[wraps.mat->n_row], bound->el, 1 + total); + wraps.mat->n_row++; + + if (add_wraps(&wraps, &info[i], bound->el, set_j) < 0) + goto error; + if (wraps.failed) + goto unbounded; + + change = fuse(i, j, info, wraps.mat, detect_equalities, 0); + + if (0) { +error: change = isl_change_error; + } +unbounded: + + wraps_free(&wraps); + isl_set_free(set_i); + isl_set_free(set_j); + isl_vec_free(bound); + + return change; +} + +/* Initialize the "eq" and "ineq" fields of "info". + */ +static void init_status(struct isl_coalesce_info *info) +{ + info->eq = info->ineq = NULL; +} + +/* Set info->eq to the positions of the equalities of info->bmap + * with respect to the basic map represented by "tab". + * If info->eq has already been computed, then do not compute it again. + */ +static void set_eq_status_in(struct isl_coalesce_info *info, + struct isl_tab *tab) +{ + if (info->eq) + return; + info->eq = eq_status_in(info->bmap, tab); +} + +/* Set info->ineq to the positions of the inequalities of info->bmap + * with respect to the basic map represented by "tab". + * If info->ineq has already been computed, then do not compute it again. + */ +static void set_ineq_status_in(struct isl_coalesce_info *info, + struct isl_tab *tab) +{ + if (info->ineq) + return; + info->ineq = ineq_status_in(info->bmap, info->tab, tab); +} + +/* Free the memory allocated by the "eq" and "ineq" fields of "info". + * This function assumes that init_status has been called on "info" first, + * after which the "eq" and "ineq" fields may or may not have been + * assigned a newly allocated array. + */ +static void clear_status(struct isl_coalesce_info *info) +{ + free(info->eq); + free(info->ineq); +} + +/* Are all inequality constraints of the basic map represented by "info" + * valid for the other basic map, except for a single constraint + * that is adjacent to an inequality constraint of the other basic map? + */ +static int all_ineq_valid_or_single_adj_ineq(struct isl_coalesce_info *info) +{ + int i; + int k = -1; + + for (i = 0; i < info->bmap->n_ineq; ++i) { + if (info->ineq[i] == STATUS_REDUNDANT) + continue; + if (info->ineq[i] == STATUS_VALID) + continue; + if (info->ineq[i] != STATUS_ADJ_INEQ) + return 0; + if (k != -1) + return 0; + k = i; + } + + return k != -1; +} + +/* Basic map "i" has one or more equality constraints that separate it + * from basic map "j". Check if it happens to be an extension + * of basic map "j". + * In particular, check that all constraints of "j" are valid for "i", + * except for one inequality constraint that is adjacent + * to an inequality constraints of "i". + * If so, check for "i" being an extension of "j" by calling + * is_adj_ineq_extension. + * + * Clean up the memory allocated for keeping track of the status + * of the constraints before returning. + */ +static enum isl_change separating_equality(int i, int j, + struct isl_coalesce_info *info) +{ + enum isl_change change = isl_change_none; + + if (all(info[j].eq, 2 * info[j].bmap->n_eq, STATUS_VALID) && + all_ineq_valid_or_single_adj_ineq(&info[j])) + change = is_adj_ineq_extension(j, i, info); + + clear_status(&info[i]); + clear_status(&info[j]); + return change; +} + +/* Check if the union of the given pair of basic maps + * can be represented by a single basic map. + * If so, replace the pair by the single basic map and return + * isl_change_drop_first, isl_change_drop_second or isl_change_fuse. + * Otherwise, return isl_change_none. + * The two basic maps are assumed to live in the same local space. + * The "eq" and "ineq" fields of info[i] and info[j] are assumed + * to have been initialized by the caller, either to NULL or + * to valid information. + * + * We first check the effect of each constraint of one basic map + * on the other basic map. + * The constraint may be + * redundant the constraint is redundant in its own + * basic map and should be ignore and removed + * in the end + * valid all (integer) points of the other basic map + * satisfy the constraint + * separate no (integer) point of the other basic map + * satisfies the constraint + * cut some but not all points of the other basic map + * satisfy the constraint + * adj_eq the given constraint is adjacent (on the outside) + * to an equality of the other basic map + * adj_ineq the given constraint is adjacent (on the outside) + * to an inequality of the other basic map + * + * We consider seven cases in which we can replace the pair by a single + * basic map. We ignore all "redundant" constraints. + * + * 1. all constraints of one basic map are valid + * => the other basic map is a subset and can be removed + * + * 2. all constraints of both basic maps are either "valid" or "cut" + * and the facets corresponding to the "cut" constraints + * of one of the basic maps lies entirely inside the other basic map + * => the pair can be replaced by a basic map consisting + * of the valid constraints in both basic maps + * + * 3. there is a single pair of adjacent inequalities + * (all other constraints are "valid") + * => the pair can be replaced by a basic map consisting + * of the valid constraints in both basic maps + * + * 4. one basic map has a single adjacent inequality, while the other + * constraints are "valid". The other basic map has some + * "cut" constraints, but replacing the adjacent inequality by + * its opposite and adding the valid constraints of the other + * basic map results in a subset of the other basic map + * => the pair can be replaced by a basic map consisting + * of the valid constraints in both basic maps + * + * 5. there is a single adjacent pair of an inequality and an equality, + * the other constraints of the basic map containing the inequality are + * "valid". Moreover, if the inequality the basic map is relaxed + * and then turned into an equality, then resulting facet lies + * entirely inside the other basic map + * => the pair can be replaced by the basic map containing + * the inequality, with the inequality relaxed. + * + * 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 + * ridges to include the other basic map + * => the pair can be replaced by a basic map consisting + * of the valid constraints in both basic maps together + * with all wrapping constraints + * + * 7. one of the basic maps extends beyond the other by at most one. + * Moreover, the facets corresponding to the cut constraints and + * the pieces of the other basic map at offset one from these cut + * constraints can be wrapped around their ridges to include + * the union of the two basic maps + * => the pair can be replaced by a basic map consisting + * of the valid constraints in both basic maps together + * with all wrapping constraints + * + * 8. the two basic maps live in adjacent hyperplanes. In principle + * such sets can always be combined through wrapping, but we impose + * that there is only one such pair, to avoid overeager coalescing. + * + * Throughout the computation, we maintain a collection of tableaus + * corresponding to the basic maps. When the basic maps are dropped + * or combined, the tableaus are modified accordingly. + */ +static enum isl_change coalesce_local_pair_reuse(int i, int j, + struct isl_coalesce_info *info) +{ + enum isl_change change = isl_change_none; + + set_ineq_status_in(&info[i], info[j].tab); + if (info[i].bmap->n_ineq && !info[i].ineq) + goto error; + if (any_ineq(&info[i], STATUS_ERROR)) + goto error; + 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_ineq(&info[j], STATUS_ERROR)) + goto error; + 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_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_eq(&info[j], STATUS_ERROR)) + goto error; + + if (any_eq(&info[i], STATUS_SEPARATE)) + return separating_equality(i, j, info); + 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) && + all(info[i].ineq, info[i].bmap->n_ineq, STATUS_VALID)) { + drop(&info[j]); + change = isl_change_drop_second; + } else if (all(info[j].eq, 2 * info[j].bmap->n_eq, STATUS_VALID) && + all(info[j].ineq, info[j].bmap->n_ineq, STATUS_VALID)) { + drop(&info[i]); + change = isl_change_drop_first; + } else if (any_eq(&info[i], STATUS_ADJ_EQ)) { + change = check_eq_adj_eq(i, j, info); + } else if (any_eq(&info[j], STATUS_ADJ_EQ)) { + change = check_eq_adj_eq(j, i, info); + } 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_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_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); + } + +done: + clear_status(&info[i]); + clear_status(&info[j]); + return change; +error: + clear_status(&info[i]); + clear_status(&info[j]); + return isl_change_error; +} + +/* Check if the union of the given pair of basic maps + * can be represented by a single basic map. + * If so, replace the pair by the single basic map and return + * isl_change_drop_first, isl_change_drop_second or isl_change_fuse. + * Otherwise, return isl_change_none. + * The two basic maps are assumed to live in the same local space. + */ +static enum isl_change coalesce_local_pair(int i, int j, + struct isl_coalesce_info *info) +{ + init_status(&info[i]); + init_status(&info[j]); + return coalesce_local_pair_reuse(i, j, info); +} + +/* Shift the integer division at position "div" of the basic map + * represented by "info" by "shift". + * + * That is, if the integer division has the form + * + * floor(f(x)/d) + * + * then replace it by + * + * floor((f(x) + shift * d)/d) - shift + */ +static isl_stat shift_div(struct isl_coalesce_info *info, int div, + isl_int shift) +{ + isl_size total, n_div; + + info->bmap = isl_basic_map_shift_div(info->bmap, div, 0, shift); + if (!info->bmap) + return isl_stat_error; + + total = isl_basic_map_dim(info->bmap, isl_dim_all); + n_div = isl_basic_map_dim(info->bmap, isl_dim_div); + if (total < 0 || n_div < 0) + return isl_stat_error; + total -= n_div; + if (isl_tab_shift_var(info->tab, total + div, shift) < 0) + return isl_stat_error; + + return isl_stat_ok; +} + +/* If the integer division at position "div" is defined by an equality, + * i.e., a stride constraint, then change the integer division expression + * to have a constant term equal to zero. + * + * Let the equality constraint be + * + * c + f + m a = 0 + * + * The integer division expression is then typically of the form + * + * a = floor((-f - c')/m) + * + * The integer division is first shifted by t = floor(c/m), + * turning the equality constraint into + * + * c - m floor(c/m) + f + m a' = 0 + * + * i.e., + * + * (c mod m) + f + m a' = 0 + * + * That is, + * + * a' = (-f - (c mod m))/m = floor((-f)/m) + * + * because a' is an integer and 0 <= (c mod m) < m. + * The constant term of a' can therefore be zeroed out, + * but only if the integer division expression is of the expected form. + */ +static isl_stat normalize_stride_div(struct isl_coalesce_info *info, int div) +{ + isl_bool defined, valid; + isl_stat r; + isl_constraint *c; + isl_int shift, stride; + + defined = isl_basic_map_has_defining_equality(info->bmap, isl_dim_div, + div, &c); + if (defined < 0) + return isl_stat_error; + if (!defined) + return isl_stat_ok; + if (!c) + return isl_stat_error; + valid = isl_constraint_is_div_equality(c, div); + isl_int_init(shift); + isl_int_init(stride); + isl_constraint_get_constant(c, &shift); + isl_constraint_get_coefficient(c, isl_dim_div, div, &stride); + isl_int_fdiv_q(shift, shift, stride); + r = shift_div(info, div, shift); + isl_int_clear(stride); + isl_int_clear(shift); + isl_constraint_free(c); + if (r < 0 || valid < 0) + return isl_stat_error; + if (!valid) + return isl_stat_ok; + info->bmap = isl_basic_map_set_div_expr_constant_num_si_inplace( + info->bmap, div, 0); + if (!info->bmap) + return isl_stat_error; + return isl_stat_ok; +} + +/* The basic maps represented by "info1" and "info2" are known + * to have the same number of integer divisions. + * Check if pairs of integer divisions are equal to each other + * despite the fact that they differ by a rational constant. + * + * In particular, look for any pair of integer divisions that + * only differ in their constant terms. + * If either of these integer divisions is defined + * by stride constraints, then modify it to have a zero constant term. + * If both are defined by stride constraints then in the end they will have + * the same (zero) constant term. + */ +static isl_stat harmonize_stride_divs(struct isl_coalesce_info *info1, + struct isl_coalesce_info *info2) +{ + int i; + isl_size n; + + n = isl_basic_map_dim(info1->bmap, isl_dim_div); + if (n < 0) + return isl_stat_error; + for (i = 0; i < n; ++i) { + isl_bool known, harmonize; + + known = isl_basic_map_div_is_known(info1->bmap, i); + if (known >= 0 && known) + known = isl_basic_map_div_is_known(info2->bmap, i); + if (known < 0) + return isl_stat_error; + if (!known) + continue; + harmonize = isl_basic_map_equal_div_expr_except_constant( + info1->bmap, i, info2->bmap, i); + if (harmonize < 0) + return isl_stat_error; + if (!harmonize) + continue; + if (normalize_stride_div(info1, i) < 0) + return isl_stat_error; + if (normalize_stride_div(info2, i) < 0) + return isl_stat_error; + } + + return isl_stat_ok; +} + +/* If "shift" is an integer constant, then shift the integer division + * at position "div" of the basic map represented by "info" by "shift". + * If "shift" is not an integer constant, then do nothing. + * If "shift" is equal to zero, then no shift needs to be performed either. + * + * That is, if the integer division has the form + * + * floor(f(x)/d) + * + * then replace it by + * + * floor((f(x) + shift * d)/d) - shift + */ +static isl_stat shift_if_cst_int(struct isl_coalesce_info *info, int div, + __isl_keep isl_aff *shift) +{ + isl_bool cst; + isl_stat r; + isl_int d; + isl_val *c; + + cst = isl_aff_is_cst(shift); + if (cst < 0 || !cst) + return cst < 0 ? isl_stat_error : isl_stat_ok; + + c = isl_aff_get_constant_val(shift); + cst = isl_val_is_int(c); + if (cst >= 0 && cst) + cst = isl_bool_not(isl_val_is_zero(c)); + if (cst < 0 || !cst) { + isl_val_free(c); + return cst < 0 ? isl_stat_error : isl_stat_ok; + } + + isl_int_init(d); + r = isl_val_get_num_isl_int(c, &d); + if (r >= 0) + r = shift_div(info, div, d); + isl_int_clear(d); + + isl_val_free(c); + + return r; +} + +/* Check if some of the divs in the basic map represented by "info1" + * are shifts of the corresponding divs in the basic map represented + * by "info2", taking into account the equality constraints "eq1" of "info1" + * and "eq2" of "info2". If so, align them with those of "info2". + * "info1" and "info2" are assumed to have the same number + * of integer divisions. + * + * An integer division is considered to be a shift of another integer + * division if, after simplification with respect to the equality + * constraints of the other basic map, one is equal to the other + * plus a constant. + * + * In particular, for each pair of integer divisions, if both are known, + * have the same denominator and are not already equal to each other, + * simplify each with respect to the equality constraints + * of the other basic map. If the difference is an integer constant, + * then move this difference outside. + * That is, if, after simplification, one integer division is of the form + * + * floor((f(x) + c_1)/d) + * + * while the other is of the form + * + * floor((f(x) + c_2)/d) + * + * and n = (c_2 - c_1)/d is an integer, then replace the first + * integer division by + * + * floor((f_1(x) + c_1 + n * d)/d) - n, + * + * where floor((f_1(x) + c_1 + n * d)/d) = floor((f2(x) + c_2)/d) + * after simplification with respect to the equality constraints. + */ +static isl_stat harmonize_divs_with_hulls(struct isl_coalesce_info *info1, + struct isl_coalesce_info *info2, __isl_keep isl_basic_set *eq1, + __isl_keep isl_basic_set *eq2) +{ + int i; + isl_size total; + isl_local_space *ls1, *ls2; + + total = isl_basic_map_dim(info1->bmap, isl_dim_all); + if (total < 0) + return isl_stat_error; + ls1 = isl_local_space_wrap(isl_basic_map_get_local_space(info1->bmap)); + ls2 = isl_local_space_wrap(isl_basic_map_get_local_space(info2->bmap)); + for (i = 0; i < info1->bmap->n_div; ++i) { + isl_stat r; + isl_aff *div1, *div2; + + if (!isl_local_space_div_is_known(ls1, i) || + !isl_local_space_div_is_known(ls2, i)) + continue; + if (isl_int_ne(info1->bmap->div[i][0], info2->bmap->div[i][0])) + continue; + if (isl_seq_eq(info1->bmap->div[i] + 1, + info2->bmap->div[i] + 1, 1 + total)) + continue; + div1 = isl_local_space_get_div(ls1, i); + div2 = isl_local_space_get_div(ls2, i); + div1 = isl_aff_substitute_equalities(div1, + isl_basic_set_copy(eq2)); + div2 = isl_aff_substitute_equalities(div2, + isl_basic_set_copy(eq1)); + div2 = isl_aff_sub(div2, div1); + r = shift_if_cst_int(info1, i, div2); + isl_aff_free(div2); + if (r < 0) + break; + } + isl_local_space_free(ls1); + isl_local_space_free(ls2); + + if (i < info1->bmap->n_div) + return isl_stat_error; + return isl_stat_ok; +} + +/* Check if some of the divs in the basic map represented by "info1" + * are shifts of the corresponding divs in the basic map represented + * by "info2". If so, align them with those of "info2". + * Only do this if "info1" and "info2" have the same number + * of integer divisions. + * + * An integer division is considered to be a shift of another integer + * division if, after simplification with respect to the equality + * constraints of the other basic map, one is equal to the other + * plus a constant. + * + * First check if pairs of integer divisions are equal to each other + * despite the fact that they differ by a rational constant. + * If so, try and arrange for them to have the same constant term. + * + * Then, extract the equality constraints and continue with + * harmonize_divs_with_hulls. + * + * If the equality constraints of both basic maps are the same, + * then there is no need to perform any shifting since + * the coefficients of the integer divisions should have been + * reduced in the same way. + */ +static isl_stat harmonize_divs(struct isl_coalesce_info *info1, + struct isl_coalesce_info *info2) +{ + isl_bool equal; + isl_basic_map *bmap1, *bmap2; + isl_basic_set *eq1, *eq2; + isl_stat r; + + if (!info1->bmap || !info2->bmap) + return isl_stat_error; + + if (info1->bmap->n_div != info2->bmap->n_div) + return isl_stat_ok; + if (info1->bmap->n_div == 0) + return isl_stat_ok; + + if (harmonize_stride_divs(info1, info2) < 0) + return isl_stat_error; + + bmap1 = isl_basic_map_copy(info1->bmap); + bmap2 = isl_basic_map_copy(info2->bmap); + eq1 = isl_basic_map_wrap(isl_basic_map_plain_affine_hull(bmap1)); + eq2 = isl_basic_map_wrap(isl_basic_map_plain_affine_hull(bmap2)); + equal = isl_basic_set_plain_is_equal(eq1, eq2); + if (equal < 0) + r = isl_stat_error; + else if (equal) + r = isl_stat_ok; + else + r = harmonize_divs_with_hulls(info1, info2, eq1, eq2); + isl_basic_set_free(eq1); + isl_basic_set_free(eq2); + + return r; +} + +/* Do the two basic maps live in the same local space, i.e., + * do they have the same (known) divs? + * If either basic map has any unknown divs, then we can only assume + * that they do not live in the same local space. + */ +static isl_bool same_divs(__isl_keep isl_basic_map *bmap1, + __isl_keep isl_basic_map *bmap2) +{ + int i; + isl_bool known; + isl_size total; + + if (!bmap1 || !bmap2) + return isl_bool_error; + if (bmap1->n_div != bmap2->n_div) + return isl_bool_false; + + if (bmap1->n_div == 0) + return isl_bool_true; + + known = isl_basic_map_divs_known(bmap1); + if (known < 0 || !known) + return known; + known = isl_basic_map_divs_known(bmap2); + if (known < 0 || !known) + return known; + + total = isl_basic_map_dim(bmap1, isl_dim_all); + if (total < 0) + return isl_bool_error; + for (i = 0; i < bmap1->n_div; ++i) + if (!isl_seq_eq(bmap1->div[i], bmap2->div[i], 2 + total)) + return isl_bool_false; + + return isl_bool_true; +} + +/* Assuming that "tab" contains the equality constraints and + * the initial inequality constraints of "bmap", copy the remaining + * inequality constraints of "bmap" to "Tab". + */ +static isl_stat copy_ineq(struct isl_tab *tab, __isl_keep isl_basic_map *bmap) +{ + int i, n_ineq; + + if (!bmap) + return isl_stat_error; + + n_ineq = tab->n_con - tab->n_eq; + for (i = n_ineq; i < bmap->n_ineq; ++i) + if (isl_tab_add_ineq(tab, bmap->ineq[i]) < 0) + return isl_stat_error; + + return isl_stat_ok; +} + +/* Description of an integer division that is added + * during an expansion. + * "pos" is the position of the corresponding variable. + * "cst" indicates whether this integer division has a fixed value. + * "val" contains the fixed value, if the value is fixed. + */ +struct isl_expanded { + int pos; + isl_bool cst; + isl_int val; +}; + +/* For each of the "n" integer division variables "expanded", + * if the variable has a fixed value, then add two inequality + * constraints expressing the fixed value. + * Otherwise, add the corresponding div constraints. + * The caller is responsible for removing the div constraints + * that it added for all these "n" integer divisions. + * + * The div constraints and the pair of inequality constraints + * forcing the fixed value cannot both be added for a given variable + * as the combination may render some of the original constraints redundant. + * These would then be ignored during the coalescing detection, + * while they could remain in the fused result. + * + * The two added inequality constraints are + * + * -a + v >= 0 + * a - v >= 0 + * + * with "a" the variable and "v" its fixed value. + * The facet corresponding to one of these two constraints is selected + * in the tableau to ensure that the pair of inequality constraints + * is treated as an equality constraint. + * + * The information in info->ineq is thrown away because it was + * computed in terms of div constraints, while some of those + * have now been replaced by these pairs of inequality constraints. + */ +static isl_stat fix_constant_divs(struct isl_coalesce_info *info, + int n, struct isl_expanded *expanded) +{ + unsigned o_div; + int i; + isl_vec *ineq; + + o_div = isl_basic_map_offset(info->bmap, isl_dim_div) - 1; + ineq = isl_vec_alloc(isl_tab_get_ctx(info->tab), 1 + info->tab->n_var); + if (!ineq) + return isl_stat_error; + isl_seq_clr(ineq->el + 1, info->tab->n_var); + + for (i = 0; i < n; ++i) { + if (!expanded[i].cst) { + info->bmap = isl_basic_map_extend_constraints( + info->bmap, 0, 2); + info->bmap = isl_basic_map_add_div_constraints( + info->bmap, expanded[i].pos - o_div); + } else { + isl_int_set_si(ineq->el[1 + expanded[i].pos], -1); + isl_int_set(ineq->el[0], expanded[i].val); + info->bmap = isl_basic_map_add_ineq(info->bmap, + ineq->el); + isl_int_set_si(ineq->el[1 + expanded[i].pos], 1); + isl_int_neg(ineq->el[0], expanded[i].val); + info->bmap = isl_basic_map_add_ineq(info->bmap, + ineq->el); + isl_int_set_si(ineq->el[1 + expanded[i].pos], 0); + } + if (copy_ineq(info->tab, info->bmap) < 0) + break; + if (expanded[i].cst && + isl_tab_select_facet(info->tab, info->tab->n_con - 1) < 0) + break; + } + + isl_vec_free(ineq); + + clear_status(info); + init_status(info); + + return i < n ? isl_stat_error : isl_stat_ok; +} + +/* Insert the "n" integer division variables "expanded" + * into info->tab and info->bmap and + * update info->ineq with respect to the redundant constraints + * in the resulting tableau. + * "bmap" contains the result of this insertion in info->bmap, + * while info->bmap is the original version + * of "bmap", i.e., the one that corresponds to the current + * state of info->tab. The number of constraints in info->bmap + * is assumed to be the same as the number of constraints + * in info->tab. This is required to be able to detect + * the extra constraints in "bmap". + * + * In particular, introduce extra variables corresponding + * to the extra integer divisions and add the div constraints + * that were added to "bmap" after info->tab was created + * from info->bmap. + * Furthermore, check if these extra integer divisions happen + * to attain a fixed integer value in info->tab. + * If so, replace the corresponding div constraints by pairs + * of inequality constraints that fix these + * integer divisions to their single integer values. + * Replace info->bmap by "bmap" to match the changes to info->tab. + * info->ineq was computed without a tableau and therefore + * does not take into account the redundant constraints + * in the tableau. Mark them here. + * There is no need to check the newly added div constraints + * since they cannot be redundant. + * The redundancy check is not performed when constants have been discovered + * since info->ineq is completely thrown away in this case. + */ +static isl_stat tab_insert_divs(struct isl_coalesce_info *info, + int n, struct isl_expanded *expanded, __isl_take isl_basic_map *bmap) +{ + int i, n_ineq; + unsigned n_eq; + struct isl_tab_undo *snap; + int any; + + if (!bmap) + return isl_stat_error; + if (info->bmap->n_eq + info->bmap->n_ineq != info->tab->n_con) + isl_die(isl_basic_map_get_ctx(bmap), isl_error_internal, + "original tableau does not correspond " + "to original basic map", goto error); + + if (isl_tab_extend_vars(info->tab, n) < 0) + goto error; + if (isl_tab_extend_cons(info->tab, 2 * n) < 0) + goto error; + + for (i = 0; i < n; ++i) { + if (isl_tab_insert_var(info->tab, expanded[i].pos) < 0) + goto error; + } + + snap = isl_tab_snap(info->tab); + + n_ineq = info->tab->n_con - info->tab->n_eq; + if (copy_ineq(info->tab, bmap) < 0) + goto error; + + isl_basic_map_free(info->bmap); + info->bmap = bmap; + + any = 0; + for (i = 0; i < n; ++i) { + expanded[i].cst = isl_tab_is_constant(info->tab, + expanded[i].pos, &expanded[i].val); + if (expanded[i].cst < 0) + return isl_stat_error; + if (expanded[i].cst) + any = 1; + } + + if (any) { + if (isl_tab_rollback(info->tab, snap) < 0) + return isl_stat_error; + info->bmap = isl_basic_map_cow(info->bmap); + info->bmap = isl_basic_map_free_inequality(info->bmap, 2 * n); + if (!info->bmap) + return isl_stat_error; + + return fix_constant_divs(info, n, expanded); + } + + n_eq = info->bmap->n_eq; + for (i = 0; i < n_ineq; ++i) { + if (isl_tab_is_redundant(info->tab, n_eq + i)) + info->ineq[i] = STATUS_REDUNDANT; + } + + return isl_stat_ok; +error: + isl_basic_map_free(bmap); + return isl_stat_error; +} + +/* Expand info->tab and info->bmap in the same way "bmap" was expanded + * in isl_basic_map_expand_divs using the expansion "exp" and + * update info->ineq with respect to the redundant constraints + * in the resulting tableau. info->bmap is the original version + * of "bmap", i.e., the one that corresponds to the current + * state of info->tab. The number of constraints in info->bmap + * is assumed to be the same as the number of constraints + * in info->tab. This is required to be able to detect + * the extra constraints in "bmap". + * + * Extract the positions where extra local variables are introduced + * from "exp" and call tab_insert_divs. + */ +static isl_stat expand_tab(struct isl_coalesce_info *info, int *exp, + __isl_take isl_basic_map *bmap) +{ + isl_ctx *ctx; + struct isl_expanded *expanded; + int i, j, k, n; + int extra_var; + isl_size total, n_div; + unsigned pos; + isl_stat r; + + total = isl_basic_map_dim(bmap, isl_dim_all); + n_div = isl_basic_map_dim(bmap, isl_dim_div); + if (total < 0 || n_div < 0) + return isl_stat_error; + pos = total - n_div; + extra_var = total - info->tab->n_var; + n = n_div - extra_var; + + ctx = isl_basic_map_get_ctx(bmap); + expanded = isl_calloc_array(ctx, struct isl_expanded, extra_var); + if (extra_var && !expanded) + goto error; + + i = 0; + k = 0; + for (j = 0; j < n_div; ++j) { + if (i < n && exp[i] == j) { + ++i; + continue; + } + expanded[k++].pos = pos + j; + } + + for (k = 0; k < extra_var; ++k) + isl_int_init(expanded[k].val); + + r = tab_insert_divs(info, extra_var, expanded, bmap); + + for (k = 0; k < extra_var; ++k) + isl_int_clear(expanded[k].val); + free(expanded); + + return r; +error: + isl_basic_map_free(bmap); + return isl_stat_error; +} + +/* Check if the union of the basic maps represented by info[i] and info[j] + * can be represented by a single basic map, + * after expanding the divs of info[i] to match those of info[j]. + * If so, replace the pair by the single basic map and return + * isl_change_drop_first, isl_change_drop_second or isl_change_fuse. + * Otherwise, return isl_change_none. + * + * The caller has already checked for info[j] being a subset of info[i]. + * If some of the divs of info[j] are unknown, then the expanded info[i] + * will not have the corresponding div constraints. The other patterns + * therefore cannot apply. Skip the computation in this case. + * + * The expansion is performed using the divs "div" and expansion "exp" + * computed by the caller. + * info[i].bmap has already been expanded and the result is passed in + * as "bmap". + * The "eq" and "ineq" fields of info[i] reflect the status of + * the constraints of the expanded "bmap" with respect to info[j].tab. + * However, inequality constraints that are redundant in info[i].tab + * have not yet been marked as such because no tableau was available. + * + * Replace info[i].bmap by "bmap" and expand info[i].tab as well, + * updating info[i].ineq with respect to the redundant constraints. + * Then try and coalesce the expanded info[i] with info[j], + * reusing the information in info[i].eq and info[i].ineq. + * If this does not result in any coalescing or if it results in info[j] + * getting dropped (which should not happen in practice, since the case + * of info[j] being a subset of info[i] has already been checked by + * the caller), then revert info[i] to its original state. + */ +static enum isl_change coalesce_expand_tab_divs(__isl_take isl_basic_map *bmap, + int i, int j, struct isl_coalesce_info *info, __isl_keep isl_mat *div, + int *exp) +{ + isl_bool known; + isl_basic_map *bmap_i; + struct isl_tab_undo *snap; + enum isl_change change = isl_change_none; + + known = isl_basic_map_divs_known(info[j].bmap); + if (known < 0 || !known) { + clear_status(&info[i]); + isl_basic_map_free(bmap); + return known < 0 ? isl_change_error : isl_change_none; + } + + bmap_i = isl_basic_map_copy(info[i].bmap); + snap = isl_tab_snap(info[i].tab); + if (expand_tab(&info[i], exp, bmap) < 0) + change = isl_change_error; + + init_status(&info[j]); + if (change == isl_change_none) + change = coalesce_local_pair_reuse(i, j, info); + else + clear_status(&info[i]); + if (change != isl_change_none && change != isl_change_drop_second) { + isl_basic_map_free(bmap_i); + } else { + isl_basic_map_free(info[i].bmap); + info[i].bmap = bmap_i; + + if (isl_tab_rollback(info[i].tab, snap) < 0) + change = isl_change_error; + } + + return change; +} + +/* Check if the union of "bmap" and the basic map represented by info[j] + * can be represented by a single basic map, + * after expanding the divs of "bmap" to match those of info[j]. + * If so, replace the pair by the single basic map and return + * isl_change_drop_first, isl_change_drop_second or isl_change_fuse. + * Otherwise, return isl_change_none. + * + * In particular, check if the expanded "bmap" contains the basic map + * represented by the tableau info[j].tab. + * The expansion is performed using the divs "div" and expansion "exp" + * computed by the caller. + * Then we check if all constraints of the expanded "bmap" are valid for + * info[j].tab. + * + * If "i" is not equal to -1, then "bmap" is equal to info[i].bmap. + * In this case, the positions of the constraints of info[i].bmap + * with respect to the basic map represented by info[j] are stored + * in info[i]. + * + * If the expanded "bmap" does not contain the basic map + * represented by the tableau info[j].tab and if "i" is not -1, + * i.e., if the original "bmap" is info[i].bmap, then expand info[i].tab + * as well and check if that results in coalescing. + */ +static enum isl_change coalesce_with_expanded_divs( + __isl_keep isl_basic_map *bmap, int i, int j, + struct isl_coalesce_info *info, __isl_keep isl_mat *div, int *exp) +{ + enum isl_change change = isl_change_none; + struct isl_coalesce_info info_local, *info_i; + + info_i = i >= 0 ? &info[i] : &info_local; + init_status(info_i); + bmap = isl_basic_map_copy(bmap); + bmap = isl_basic_map_expand_divs(bmap, isl_mat_copy(div), exp); + bmap = isl_basic_map_mark_final(bmap); + + 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_eq(info_i, STATUS_ERROR)) + goto error; + 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_ineq(info_i, STATUS_ERROR)) + goto error; + if (any_ineq(info_i, STATUS_SEPARATE)) + goto done; + + if (all(info_i->eq, 2 * bmap->n_eq, STATUS_VALID) && + all(info_i->ineq, bmap->n_ineq, STATUS_VALID)) { + drop(&info[j]); + change = isl_change_drop_second; + } + + if (change == isl_change_none && i != -1) + return coalesce_expand_tab_divs(bmap, i, j, info, div, exp); + +done: + isl_basic_map_free(bmap); + clear_status(info_i); + return change; +error: + isl_basic_map_free(bmap); + clear_status(info_i); + return isl_change_error; +} + +/* Check if the union of "bmap_i" and the basic map represented by info[j] + * can be represented by a single basic map, + * after aligning the divs of "bmap_i" to match those of info[j]. + * If so, replace the pair by the single basic map and return + * isl_change_drop_first, isl_change_drop_second or isl_change_fuse. + * Otherwise, return isl_change_none. + * + * In particular, check if "bmap_i" contains the basic map represented by + * info[j] after aligning the divs of "bmap_i" to those of info[j]. + * Note that this can only succeed if the number of divs of "bmap_i" + * is smaller than (or equal to) the number of divs of info[j]. + * + * We first check if the divs of "bmap_i" are all known and form a subset + * of those of info[j].bmap. If so, we pass control over to + * coalesce_with_expanded_divs. + * + * If "i" is not equal to -1, then "bmap" is equal to info[i].bmap. + */ +static enum isl_change coalesce_after_aligning_divs( + __isl_keep isl_basic_map *bmap_i, int i, int j, + struct isl_coalesce_info *info) +{ + isl_bool known; + isl_mat *div_i, *div_j, *div; + int *exp1 = NULL; + int *exp2 = NULL; + isl_ctx *ctx; + enum isl_change change; + + known = isl_basic_map_divs_known(bmap_i); + if (known < 0) + return isl_change_error; + if (!known) + return isl_change_none; + + ctx = isl_basic_map_get_ctx(bmap_i); + + div_i = isl_basic_map_get_divs(bmap_i); + div_j = isl_basic_map_get_divs(info[j].bmap); + + if (!div_i || !div_j) + goto error; + + exp1 = isl_alloc_array(ctx, int, div_i->n_row); + exp2 = isl_alloc_array(ctx, int, div_j->n_row); + if ((div_i->n_row && !exp1) || (div_j->n_row && !exp2)) + goto error; + + div = isl_merge_divs(div_i, div_j, exp1, exp2); + if (!div) + goto error; + + if (div->n_row == div_j->n_row) + change = coalesce_with_expanded_divs(bmap_i, + i, j, info, div, exp1); + else + change = isl_change_none; + + isl_mat_free(div); + + isl_mat_free(div_i); + isl_mat_free(div_j); + + free(exp2); + free(exp1); + + return change; +error: + isl_mat_free(div_i); + isl_mat_free(div_j); + free(exp1); + free(exp2); + return isl_change_error; +} + +/* Check if basic map "j" is a subset of basic map "i" after + * exploiting the extra equalities of "j" to simplify the divs of "i". + * If so, remove basic map "j" and return isl_change_drop_second. + * + * If "j" does not have any equalities or if they are the same + * as those of "i", then we cannot exploit them to simplify the divs. + * Similarly, if there are no divs in "i", then they cannot be simplified. + * If, on the other hand, the affine hulls of "i" and "j" do not intersect, + * then "j" cannot be a subset of "i". + * + * Otherwise, we intersect "i" with the affine hull of "j" and then + * check if "j" is a subset of the result after aligning the divs. + * If so, then "j" is definitely a subset of "i" and can be removed. + * Note that if after intersection with the affine hull of "j". + * "i" still has more divs than "j", then there is no way we can + * align the divs of "i" to those of "j". + */ +static enum isl_change coalesce_subset_with_equalities(int i, int j, + struct isl_coalesce_info *info) +{ + isl_basic_map *hull_i, *hull_j, *bmap_i; + int equal, empty; + enum isl_change change; + + if (info[j].bmap->n_eq == 0) + return isl_change_none; + if (info[i].bmap->n_div == 0) + return isl_change_none; + + hull_i = isl_basic_map_copy(info[i].bmap); + hull_i = isl_basic_map_plain_affine_hull(hull_i); + hull_j = isl_basic_map_copy(info[j].bmap); + hull_j = isl_basic_map_plain_affine_hull(hull_j); + + hull_j = isl_basic_map_intersect(hull_j, isl_basic_map_copy(hull_i)); + equal = isl_basic_map_plain_is_equal(hull_i, hull_j); + empty = isl_basic_map_plain_is_empty(hull_j); + isl_basic_map_free(hull_i); + + if (equal < 0 || equal || empty < 0 || empty) { + isl_basic_map_free(hull_j); + if (equal < 0 || empty < 0) + return isl_change_error; + return isl_change_none; + } + + bmap_i = isl_basic_map_copy(info[i].bmap); + bmap_i = isl_basic_map_intersect(bmap_i, hull_j); + if (!bmap_i) + return isl_change_error; + + if (bmap_i->n_div > info[j].bmap->n_div) { + isl_basic_map_free(bmap_i); + return isl_change_none; + } + + change = coalesce_after_aligning_divs(bmap_i, -1, j, info); + + isl_basic_map_free(bmap_i); + + return change; +} + +/* Check if the union of the basic maps represented by info[i] and info[j] + * can be represented by a single basic map, by aligning or equating + * their integer divisions. + * If so, replace the pair by the single basic map and return + * isl_change_drop_first, isl_change_drop_second or isl_change_fuse. + * Otherwise, return isl_change_none. + * + * Note that we only perform any test if the number of divs is different + * in the two basic maps. In case the number of divs is the same, + * we have already established that the divs are different + * in the two basic maps. + * In particular, if the number of divs of basic map i is smaller than + * the number of divs of basic map j, then we check if j is a subset of i + * and vice versa. + */ +static enum isl_change coalesce_divs(int i, int j, + struct isl_coalesce_info *info) +{ + enum isl_change change = isl_change_none; + + if (info[i].bmap->n_div < info[j].bmap->n_div) + change = coalesce_after_aligning_divs(info[i].bmap, i, j, info); + if (change != isl_change_none) + return change; + + if (info[j].bmap->n_div < info[i].bmap->n_div) + change = coalesce_after_aligning_divs(info[j].bmap, j, i, info); + if (change != isl_change_none) + return invert_change(change); + + change = coalesce_subset_with_equalities(i, j, info); + if (change != isl_change_none) + return change; + + change = coalesce_subset_with_equalities(j, i, info); + if (change != isl_change_none) + return invert_change(change); + + return isl_change_none; +} + +/* Does "bmap" involve any divs that themselves refer to divs? + */ +static isl_bool has_nested_div(__isl_keep isl_basic_map *bmap) +{ + int i; + isl_size total; + isl_size n_div; + + total = isl_basic_map_dim(bmap, isl_dim_all); + n_div = isl_basic_map_dim(bmap, isl_dim_div); + if (total < 0 || n_div < 0) + return isl_bool_error; + total -= n_div; + + for (i = 0; i < n_div; ++i) + if (isl_seq_first_non_zero(bmap->div[i] + 2 + total, + n_div) != -1) + return isl_bool_true; + + return isl_bool_false; +} + +/* Return a list of affine expressions, one for each integer division + * in "bmap_i". For each integer division that also appears in "bmap_j", + * the affine expression is set to NaN. The number of NaNs in the list + * is equal to the number of integer divisions in "bmap_j". + * For the other integer divisions of "bmap_i", the corresponding + * element in the list is a purely affine expression equal to the integer + * division in "hull". + * If no such list can be constructed, then the number of elements + * in the returned list is smaller than the number of integer divisions + * in "bmap_i". + * The integer division of "bmap_i" and "bmap_j" are assumed to be known and + * not contain any nested divs. + */ +static __isl_give isl_aff_list *set_up_substitutions( + __isl_keep isl_basic_map *bmap_i, __isl_keep isl_basic_map *bmap_j, + __isl_take isl_basic_map *hull) +{ + isl_size n_div_i, n_div_j, total; + isl_ctx *ctx; + isl_local_space *ls; + isl_basic_set *wrap_hull; + isl_aff *aff_nan; + isl_aff_list *list; + int i, j; + + n_div_i = isl_basic_map_dim(bmap_i, isl_dim_div); + n_div_j = isl_basic_map_dim(bmap_j, isl_dim_div); + total = isl_basic_map_dim(bmap_i, isl_dim_all); + if (!hull || n_div_i < 0 || n_div_j < 0 || total < 0) + return NULL; + + ctx = isl_basic_map_get_ctx(hull); + total -= n_div_i; + + ls = isl_basic_map_get_local_space(bmap_i); + ls = isl_local_space_wrap(ls); + wrap_hull = isl_basic_map_wrap(hull); + + aff_nan = isl_aff_nan_on_domain(isl_local_space_copy(ls)); + list = isl_aff_list_alloc(ctx, n_div_i); + + j = 0; + for (i = 0; i < n_div_i; ++i) { + isl_aff *aff; + isl_size n_div; + + if (j < n_div_j && + isl_basic_map_equal_div_expr_part(bmap_i, i, bmap_j, j, + 0, 2 + total)) { + ++j; + list = isl_aff_list_add(list, isl_aff_copy(aff_nan)); + continue; + } + if (n_div_i - i <= n_div_j - j) + break; + + aff = isl_local_space_get_div(ls, i); + aff = isl_aff_substitute_equalities(aff, + isl_basic_set_copy(wrap_hull)); + aff = isl_aff_floor(aff); + n_div = isl_aff_dim(aff, isl_dim_div); + if (n_div < 0) + goto error; + if (n_div != 0) { + isl_aff_free(aff); + break; + } + + list = isl_aff_list_add(list, aff); + } + + isl_aff_free(aff_nan); + isl_local_space_free(ls); + isl_basic_set_free(wrap_hull); + + return list; +error: + isl_aff_free(aff_nan); + isl_local_space_free(ls); + isl_basic_set_free(wrap_hull); + isl_aff_list_free(list); + return NULL; +} + +/* Add variables to info->bmap and info->tab corresponding to the elements + * in "list" that are not set to NaN. + * "extra_var" is the number of these elements. + * "dim" is the offset in the variables of "tab" where we should + * start considering the elements in "list". + * When this function returns, the total number of variables in "tab" + * is equal to "dim" plus the number of elements in "list". + * + * The newly added existentially quantified variables are not given + * an explicit representation because the corresponding div constraints + * do not appear in info->bmap. These constraints are not added + * to info->bmap because for internal consistency, they would need to + * be added to info->tab as well, where they could combine with the equality + * that is added later to result in constraints that do not hold + * in the original input. + */ +static isl_stat add_sub_vars(struct isl_coalesce_info *info, + __isl_keep isl_aff_list *list, int dim, int extra_var) +{ + int i, j, d; + isl_size n; + + info->bmap = isl_basic_map_cow(info->bmap); + info->bmap = isl_basic_map_extend(info->bmap, extra_var, 0, 0); + n = isl_aff_list_n_aff(list); + if (!info->bmap || n < 0) + return isl_stat_error; + for (i = 0; i < n; ++i) { + int is_nan; + isl_aff *aff; + + aff = isl_aff_list_get_aff(list, i); + is_nan = isl_aff_is_nan(aff); + isl_aff_free(aff); + if (is_nan < 0) + return isl_stat_error; + if (is_nan) + continue; + + if (isl_tab_insert_var(info->tab, dim + i) < 0) + return isl_stat_error; + d = isl_basic_map_alloc_div(info->bmap); + if (d < 0) + return isl_stat_error; + info->bmap = isl_basic_map_mark_div_unknown(info->bmap, d); + for (j = d; j > i; --j) + info->bmap = isl_basic_map_swap_div(info->bmap, + j - 1, j); + if (!info->bmap) + return isl_stat_error; + } + + return isl_stat_ok; +} + +/* For each element in "list" that is not set to NaN, fix the corresponding + * variable in "tab" to the purely affine expression defined by the element. + * "dim" is the offset in the variables of "tab" where we should + * start considering the elements in "list". + * + * This function assumes that a sufficient number of rows and + * elements in the constraint array are available in the tableau. + */ +static isl_stat add_sub_equalities(struct isl_tab *tab, + __isl_keep isl_aff_list *list, int dim) +{ + int i; + isl_size n; + isl_ctx *ctx; + isl_vec *sub; + isl_aff *aff; + + n = isl_aff_list_n_aff(list); + if (n < 0) + return isl_stat_error; + + ctx = isl_tab_get_ctx(tab); + sub = isl_vec_alloc(ctx, 1 + dim + n); + if (!sub) + return isl_stat_error; + isl_seq_clr(sub->el + 1 + dim, n); + + for (i = 0; i < n; ++i) { + aff = isl_aff_list_get_aff(list, i); + if (!aff) + goto error; + if (isl_aff_is_nan(aff)) { + isl_aff_free(aff); + continue; + } + isl_seq_cpy(sub->el, aff->v->el + 1, 1 + dim); + isl_int_neg(sub->el[1 + dim + i], aff->v->el[0]); + if (isl_tab_add_eq(tab, sub->el) < 0) + goto error; + isl_int_set_si(sub->el[1 + dim + i], 0); + isl_aff_free(aff); + } + + isl_vec_free(sub); + return isl_stat_ok; +error: + isl_aff_free(aff); + isl_vec_free(sub); + return isl_stat_error; +} + +/* Add variables to info->tab and info->bmap corresponding to the elements + * in "list" that are not set to NaN. The value of the added variable + * in info->tab is fixed to the purely affine expression defined by the element. + * "dim" is the offset in the variables of info->tab where we should + * start considering the elements in "list". + * When this function returns, the total number of variables in info->tab + * is equal to "dim" plus the number of elements in "list". + */ +static isl_stat add_subs(struct isl_coalesce_info *info, + __isl_keep isl_aff_list *list, int dim) +{ + int extra_var; + isl_size n; + + n = isl_aff_list_n_aff(list); + if (n < 0) + return isl_stat_error; + + extra_var = n - (info->tab->n_var - dim); + + if (isl_tab_extend_vars(info->tab, extra_var) < 0) + return isl_stat_error; + if (isl_tab_extend_cons(info->tab, 2 * extra_var) < 0) + return isl_stat_error; + if (add_sub_vars(info, list, dim, extra_var) < 0) + return isl_stat_error; + + return add_sub_equalities(info->tab, list, dim); +} + +/* Coalesce basic map "j" into basic map "i" after adding the extra integer + * divisions in "i" but not in "j" to basic map "j", with values + * specified by "list". The total number of elements in "list" + * is equal to the number of integer divisions in "i", while the number + * of NaN elements in the list is equal to the number of integer divisions + * in "j". + * + * If no coalescing can be performed, then we need to revert basic map "j" + * to its original state. We do the same if basic map "i" gets dropped + * during the coalescing, even though this should not happen in practice + * since we have already checked for "j" being a subset of "i" + * before we reach this stage. + */ +static enum isl_change coalesce_with_subs(int i, int j, + struct isl_coalesce_info *info, __isl_keep isl_aff_list *list) +{ + isl_basic_map *bmap_j; + struct isl_tab_undo *snap; + isl_size dim, n_div; + enum isl_change change; + + bmap_j = isl_basic_map_copy(info[j].bmap); + snap = isl_tab_snap(info[j].tab); + + dim = isl_basic_map_dim(bmap_j, isl_dim_all); + n_div = isl_basic_map_dim(bmap_j, isl_dim_div); + if (dim < 0 || n_div < 0) + goto error; + dim -= n_div; + if (add_subs(&info[j], list, dim) < 0) + goto error; + + change = coalesce_local_pair(i, j, info); + if (change != isl_change_none && change != isl_change_drop_first) { + isl_basic_map_free(bmap_j); + } else { + isl_basic_map_free(info[j].bmap); + info[j].bmap = bmap_j; + + if (isl_tab_rollback(info[j].tab, snap) < 0) + return isl_change_error; + } + + return change; +error: + isl_basic_map_free(bmap_j); + return isl_change_error; +} + +/* Check if we can coalesce basic map "j" into basic map "i" after copying + * those extra integer divisions in "i" that can be simplified away + * using the extra equalities in "j". + * All divs are assumed to be known and not contain any nested divs. + * + * We first check if there are any extra equalities in "j" that we + * can exploit. Then we check if every integer division in "i" + * either already appears in "j" or can be simplified using the + * extra equalities to a purely affine expression. + * If these tests succeed, then we try to coalesce the two basic maps + * by introducing extra dimensions in "j" corresponding to + * the extra integer divisions "i" fixed to the corresponding + * purely affine expression. + */ +static enum isl_change check_coalesce_into_eq(int i, int j, + struct isl_coalesce_info *info) +{ + isl_size n_div_i, n_div_j, n; + isl_basic_map *hull_i, *hull_j; + isl_bool equal, empty; + isl_aff_list *list; + enum isl_change change; + + n_div_i = isl_basic_map_dim(info[i].bmap, isl_dim_div); + n_div_j = isl_basic_map_dim(info[j].bmap, isl_dim_div); + if (n_div_i < 0 || n_div_j < 0) + return isl_change_error; + if (n_div_i <= n_div_j) + return isl_change_none; + if (info[j].bmap->n_eq == 0) + return isl_change_none; + + hull_i = isl_basic_map_copy(info[i].bmap); + hull_i = isl_basic_map_plain_affine_hull(hull_i); + hull_j = isl_basic_map_copy(info[j].bmap); + hull_j = isl_basic_map_plain_affine_hull(hull_j); + + hull_j = isl_basic_map_intersect(hull_j, isl_basic_map_copy(hull_i)); + equal = isl_basic_map_plain_is_equal(hull_i, hull_j); + empty = isl_basic_map_plain_is_empty(hull_j); + isl_basic_map_free(hull_i); + + if (equal < 0 || empty < 0) + goto error; + if (equal || empty) { + isl_basic_map_free(hull_j); + return isl_change_none; + } + + list = set_up_substitutions(info[i].bmap, info[j].bmap, hull_j); + if (!list) + return isl_change_error; + n = isl_aff_list_n_aff(list); + if (n < 0) + change = isl_change_error; + else if (n < n_div_i) + change = isl_change_none; + else + change = coalesce_with_subs(i, j, info, list); + + isl_aff_list_free(list); + + return change; +error: + isl_basic_map_free(hull_j); + return isl_change_error; +} + +/* Check if we can coalesce basic maps "i" and "j" after copying + * those extra integer divisions in one of the basic maps that can + * be simplified away using the extra equalities in the other basic map. + * We require all divs to be known in both basic maps. + * Furthermore, to simplify the comparison of div expressions, + * we do not allow any nested integer divisions. + */ +static enum isl_change check_coalesce_eq(int i, int j, + struct isl_coalesce_info *info) +{ + isl_bool known, nested; + enum isl_change change; + + known = isl_basic_map_divs_known(info[i].bmap); + if (known < 0 || !known) + return known < 0 ? isl_change_error : isl_change_none; + known = isl_basic_map_divs_known(info[j].bmap); + if (known < 0 || !known) + return known < 0 ? isl_change_error : isl_change_none; + nested = has_nested_div(info[i].bmap); + if (nested < 0 || nested) + return nested < 0 ? isl_change_error : isl_change_none; + nested = has_nested_div(info[j].bmap); + if (nested < 0 || nested) + return nested < 0 ? isl_change_error : isl_change_none; + + change = check_coalesce_into_eq(i, j, info); + if (change != isl_change_none) + return change; + change = check_coalesce_into_eq(j, i, info); + if (change != isl_change_none) + return invert_change(change); + + return isl_change_none; +} + +/* Check if the union of the given pair of basic maps + * can be represented by a single basic map. + * If so, replace the pair by the single basic map and return + * isl_change_drop_first, isl_change_drop_second or isl_change_fuse. + * Otherwise, return isl_change_none. + * + * We first check if the two basic maps live in the same local space, + * after aligning the divs that differ by only an integer constant. + * If so, we do the complete check. Otherwise, we check if they have + * the same number of integer divisions and can be coalesced, if one is + * an obvious subset of the other or if the extra integer divisions + * of one basic map can be simplified away using the extra equalities + * of the other basic map. + * + * Note that trying to coalesce pairs of disjuncts with the same + * number, but different local variables may drop the explicit + * representation of some of these local variables. + * This operation is therefore not performed when + * the "coalesce_preserve_locals" option is set. + */ +static enum isl_change coalesce_pair(int i, int j, + struct isl_coalesce_info *info) +{ + int preserve; + isl_bool same; + enum isl_change change; + isl_ctx *ctx; + + if (harmonize_divs(&info[i], &info[j]) < 0) + return isl_change_error; + same = same_divs(info[i].bmap, info[j].bmap); + if (same < 0) + return isl_change_error; + if (same) + return coalesce_local_pair(i, j, info); + + ctx = isl_basic_map_get_ctx(info[i].bmap); + preserve = isl_options_get_coalesce_preserve_locals(ctx); + if (!preserve && info[i].bmap->n_div == info[j].bmap->n_div) { + change = coalesce_local_pair(i, j, info); + if (change != isl_change_none) + return change; + } + + change = coalesce_divs(i, j, info); + if (change != isl_change_none) + return change; + + return check_coalesce_eq(i, j, info); +} + +/* Return the maximum of "a" and "b". + */ +static int isl_max(int a, int b) +{ + return a > b ? a : b; +} + +/* Pairwise coalesce the basic maps in the range [start1, end1[ of "info" + * with those in the range [start2, end2[, skipping basic maps + * that have been removed (either before or within this function). + * + * For each basic map i in the first range, we check if it can be coalesced + * with respect to any previously considered basic map j in the second range. + * If i gets dropped (because it was a subset of some j), then + * we can move on to the next basic map. + * If j gets dropped, we need to continue checking against the other + * previously considered basic maps. + * If the two basic maps got fused, then we recheck the fused basic map + * against the previously considered basic maps, starting at i + 1 + * (even if start2 is greater than i + 1). + */ +static int coalesce_range(isl_ctx *ctx, struct isl_coalesce_info *info, + int start1, int end1, int start2, int end2) +{ + int i, j; + + for (i = end1 - 1; i >= start1; --i) { + if (info[i].removed) + continue; + for (j = isl_max(i + 1, start2); j < end2; ++j) { + enum isl_change changed; + + if (info[j].removed) + continue; + if (info[i].removed) + isl_die(ctx, isl_error_internal, + "basic map unexpectedly removed", + return -1); + changed = coalesce_pair(i, j, info); + switch (changed) { + case isl_change_error: + return -1; + case isl_change_none: + case isl_change_drop_second: + continue; + case isl_change_drop_first: + j = end2; + break; + case isl_change_fuse: + j = i; + break; + } + } + } + + return 0; +} + +/* Pairwise coalesce the basic maps described by the "n" elements of "info". + * + * We consider groups of basic maps that live in the same apparent + * affine hull and we first coalesce within such a group before we + * coalesce the elements in the group with elements of previously + * considered groups. If a fuse happens during the second phase, + * then we also reconsider the elements within the group. + */ +static int coalesce(isl_ctx *ctx, int n, struct isl_coalesce_info *info) +{ + int start, end; + + for (end = n; end > 0; end = start) { + start = end - 1; + while (start >= 1 && + info[start - 1].hull_hash == info[start].hull_hash) + start--; + if (coalesce_range(ctx, info, start, end, start, end) < 0) + return -1; + if (coalesce_range(ctx, info, start, end, end, n) < 0) + return -1; + } + + return 0; +} + +/* Update the basic maps in "map" based on the information in "info". + * In particular, remove the basic maps that have been marked removed and + * update the others based on the information in the corresponding tableau. + * Since we detected implicit equalities without calling + * isl_basic_map_gauss, we need to do it now. + * Also call isl_basic_map_simplify if we may have lost the definition + * of one or more integer divisions. + * If a basic map is still equal to the one from which the corresponding "info" + * entry was created, then redundant constraint and + * implicit equality constraint detection have been performed + * on the corresponding tableau and the basic map can be marked as such. + */ +static __isl_give isl_map *update_basic_maps(__isl_take isl_map *map, + int n, struct isl_coalesce_info *info) +{ + int i; + + if (!map) + return NULL; + + for (i = n - 1; i >= 0; --i) { + if (info[i].removed) { + isl_basic_map_free(map->p[i]); + if (i != map->n - 1) + map->p[i] = map->p[map->n - 1]; + map->n--; + continue; + } + + info[i].bmap = isl_basic_map_update_from_tab(info[i].bmap, + info[i].tab); + info[i].bmap = isl_basic_map_gauss(info[i].bmap, NULL); + if (info[i].simplify) + info[i].bmap = isl_basic_map_simplify(info[i].bmap); + info[i].bmap = isl_basic_map_finalize(info[i].bmap); + if (!info[i].bmap) + return isl_map_free(map); + if (!info[i].modified) { + ISL_F_SET(info[i].bmap, ISL_BASIC_MAP_NO_IMPLICIT); + ISL_F_SET(info[i].bmap, ISL_BASIC_MAP_NO_REDUNDANT); + } + isl_basic_map_free(map->p[i]); + map->p[i] = info[i].bmap; + info[i].bmap = NULL; + } + + return map; +} + +/* For each pair of basic maps in the map, check if the union of the two + * can be represented by a single basic map. + * If so, replace the pair by the single basic map and start over. + * + * We factor out any (hidden) common factor from the constraint + * coefficients to improve the detection of adjacent constraints. + * Note that this function does not call isl_basic_map_gauss, + * but it does make sure that only a single copy of the basic map + * is affected. This means that isl_basic_map_gauss may have + * to be called at the end of the computation (in update_basic_maps) + * on this single copy to ensure that + * the basic maps are not left in an unexpected state. + * + * Since we are constructing the tableaus of the basic maps anyway, + * we exploit them to detect implicit equalities and redundant constraints. + * This also helps the coalescing as it can ignore the redundant constraints. + * In order to avoid confusion, we make all implicit equalities explicit + * in the basic maps. If the basic map only has a single reference + * (this happens in particular if it was modified by + * isl_basic_map_reduce_coefficients), then isl_basic_map_gauss + * does not get called on the result. The call to + * isl_basic_map_gauss in update_basic_maps resolves this as well. + * For each basic map, we also compute the hash of the apparent affine hull + * for use in coalesce. + */ +__isl_give isl_map *isl_map_coalesce(__isl_take isl_map *map) +{ + int i; + unsigned n; + isl_ctx *ctx; + struct isl_coalesce_info *info = NULL; + + map = isl_map_remove_empty_parts(map); + if (!map) + return NULL; + + if (map->n <= 1) + return map; + + ctx = isl_map_get_ctx(map); + map = isl_map_sort_divs(map); + map = isl_map_cow(map); + + if (!map) + return NULL; + + n = map->n; + + info = isl_calloc_array(map->ctx, struct isl_coalesce_info, n); + if (!info) + goto error; + + for (i = 0; i < map->n; ++i) { + map->p[i] = isl_basic_map_reduce_coefficients(map->p[i]); + if (!map->p[i]) + goto error; + info[i].bmap = isl_basic_map_copy(map->p[i]); + info[i].tab = isl_tab_from_basic_map(info[i].bmap, 0); + if (!info[i].tab) + goto error; + if (!ISL_F_ISSET(info[i].bmap, ISL_BASIC_MAP_NO_IMPLICIT)) + if (isl_tab_detect_implicit_equalities(info[i].tab) < 0) + goto error; + info[i].bmap = isl_tab_make_equalities_explicit(info[i].tab, + info[i].bmap); + if (!info[i].bmap) + goto error; + if (!ISL_F_ISSET(info[i].bmap, ISL_BASIC_MAP_NO_REDUNDANT)) + if (isl_tab_detect_redundant(info[i].tab) < 0) + goto error; + if (coalesce_info_set_hull_hash(&info[i]) < 0) + goto error; + } + for (i = map->n - 1; i >= 0; --i) + if (info[i].tab->empty) + drop(&info[i]); + + if (coalesce(ctx, n, info) < 0) + goto error; + + map = update_basic_maps(map, n, info); + + clear_coalesce_info(n, info); + + return map; +error: + clear_coalesce_info(n, info); + isl_map_free(map); + return NULL; +} + +/* For each pair of basic sets in the set, check if the union of the two + * can be represented by a single basic set. + * If so, replace the pair by the single basic set and start over. + */ +__isl_give isl_set *isl_set_coalesce(__isl_take isl_set *set) +{ + return set_from_map(isl_map_coalesce(set_to_map(set))); +} diff --git a/external/mit/isl/dist/isl_config.h.in b/external/mit/isl/dist/isl_config.h.in new file mode 100644 index 000000000000..6a1a9b5698a6 --- /dev/null +++ b/external/mit/isl/dist/isl_config.h.in @@ -0,0 +1,144 @@ +/* isl_config.h.in. Generated from configure.ac by autoheader. */ + +/* most gcc compilers know a function __attribute__((__warn_unused_result__)) + */ +#undef GCC_WARN_UNUSED_RESULT + +/* define if the compiler supports basic C++11 syntax */ +#undef HAVE_CXX11 + +/* define if the compiler supports basic C++17 syntax */ +#undef HAVE_CXX17 + +/* Define to 1 if you have the declaration of `ffs', and to 0 if you don't. */ +#undef HAVE_DECL_FFS + +/* Define to 1 if you have the declaration of `mp_get_memory_functions', and + to 0 if you don't. */ +#undef HAVE_DECL_MP_GET_MEMORY_FUNCTIONS + +/* Define to 1 if you have the declaration of `snprintf', and to 0 if you + don't. */ +#undef HAVE_DECL_SNPRINTF + +/* Define to 1 if you have the declaration of `strcasecmp', and to 0 if you + don't. */ +#undef HAVE_DECL_STRCASECMP + +/* Define to 1 if you have the declaration of `strncasecmp', and to 0 if you + don't. */ +#undef HAVE_DECL_STRNCASECMP + +/* Define to 1 if you have the declaration of `_BitScanForward', and to 0 if + you don't. */ +#undef HAVE_DECL__BITSCANFORWARD + +/* Define to 1 if you have the declaration of `_snprintf', and to 0 if you + don't. */ +#undef HAVE_DECL__SNPRINTF + +/* Define to 1 if you have the declaration of `_stricmp', and to 0 if you + don't. */ +#undef HAVE_DECL__STRICMP + +/* Define to 1 if you have the declaration of `_strnicmp', and to 0 if you + don't. */ +#undef HAVE_DECL__STRNICMP + +/* Define to 1 if you have the declaration of `__builtin_ffs', and to 0 if you + don't. */ +#undef HAVE_DECL___BUILTIN_FFS + +/* Define to 1 if you have the header file. */ +#undef HAVE_DLFCN_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the `gmp' library (-lgmp). */ +#undef HAVE_LIBGMP + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDIO_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_UNISTD_H + +/* define if your compiler has __attribute__ */ +#undef HAVE___ATTRIBUTE__ + +/* Define to the sub-directory where libtool stores uninstalled libraries. */ +#undef LT_OBJDIR + +/* Name of package */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the home page for this package. */ +#undef PACKAGE_URL + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* The size of `char', as computed by sizeof. */ +#undef SIZEOF_CHAR + +/* The size of `int', as computed by sizeof. */ +#undef SIZEOF_INT + +/* The size of `long', as computed by sizeof. */ +#undef SIZEOF_LONG + +/* The size of `short', as computed by sizeof. */ +#undef SIZEOF_SHORT + +/* The size of `void*', as computed by sizeof. */ +#undef SIZEOF_VOIDP + +/* Define to 1 if all of the C90 standard headers exist (not just the ones + required in a freestanding environment). This macro is provided for + backward compatibility; new code need not use it. */ +#undef STDC_HEADERS + +/* use gmp to implement isl_int */ +#undef USE_GMP_FOR_MP + +/* use imath to implement isl_int */ +#undef USE_IMATH_FOR_MP + +/* Use small integer optimization */ +#undef USE_SMALL_INT_OPT + +/* Version number of package */ +#undef VERSION + +#include diff --git a/external/mit/isl/dist/isl_config_post.h b/external/mit/isl/dist/isl_config_post.h new file mode 100644 index 000000000000..4ceb7f0edb73 --- /dev/null +++ b/external/mit/isl/dist/isl_config_post.h @@ -0,0 +1,38 @@ +#ifndef HAVE___ATTRIBUTE__ +#define __attribute__(x) +#endif + +#if HAVE_DECL_FFS +#include +#endif + +#if (HAVE_DECL_FFS==0) && (HAVE_DECL___BUILTIN_FFS==1) +#define ffs __builtin_ffs +#endif + +#if !HAVE_DECL_FFS && !HAVE_DECL___BUILTIN_FFS && HAVE_DECL__BITSCANFORWARD +int isl_ffs(int i); +#define ffs isl_ffs +#endif + +#if HAVE_DECL_STRCASECMP || HAVE_DECL_STRNCASECMP +#include +#endif + +#if !HAVE_DECL_STRCASECMP && HAVE_DECL__STRICMP +#define strcasecmp _stricmp +#endif + +#if !HAVE_DECL_STRNCASECMP && HAVE_DECL__STRNICMP +#define strncasecmp _strnicmp +#endif + +#if HAVE_DECL__SNPRINTF +#define snprintf _snprintf +#endif + +#ifdef GCC_WARN_UNUSED_RESULT +#define WARN_UNUSED GCC_WARN_UNUSED_RESULT +#else +#define WARN_UNUSED +#endif diff --git a/external/mit/isl/dist/isl_constraint.c b/external/mit/isl/dist/isl_constraint.c new file mode 100644 index 000000000000..4fc7aba8c9b4 --- /dev/null +++ b/external/mit/isl/dist/isl_constraint.c @@ -0,0 +1,1371 @@ +/* + * Copyright 2008-2009 Katholieke Universiteit Leuven + * Copyright 2010 INRIA Saclay + * + * 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 + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#undef EL_BASE +#define EL_BASE constraint + +#include + +isl_ctx *isl_constraint_get_ctx(__isl_keep isl_constraint *c) +{ + return c ? isl_local_space_get_ctx(c->ls) : NULL; +} + +static isl_size n(__isl_keep isl_constraint *c, enum isl_dim_type type) +{ + return isl_local_space_dim(c->ls, type); +} + +static unsigned offset(__isl_keep isl_constraint *c, enum isl_dim_type type) +{ + return isl_local_space_offset(c->ls, type); +} + +__isl_give isl_constraint *isl_constraint_alloc_vec(int eq, + __isl_take isl_local_space *ls, __isl_take isl_vec *v) +{ + isl_constraint *constraint; + + if (!ls || !v) + goto error; + + constraint = isl_alloc_type(isl_vec_get_ctx(v), isl_constraint); + if (!constraint) + goto error; + + constraint->ref = 1; + constraint->eq = eq; + constraint->ls = ls; + constraint->v = v; + + return constraint; +error: + isl_local_space_free(ls); + isl_vec_free(v); + return NULL; +} + +__isl_give isl_constraint *isl_constraint_alloc(int eq, + __isl_take isl_local_space *ls) +{ + isl_size dim; + isl_ctx *ctx; + isl_vec *v; + + dim = isl_local_space_dim(ls, isl_dim_all); + if (dim < 0) + ls = isl_local_space_free(ls); + if (!ls) + return NULL; + + ctx = isl_local_space_get_ctx(ls); + v = isl_vec_alloc(ctx, 1 + dim); + v = isl_vec_clr(v); + return isl_constraint_alloc_vec(eq, ls, v); +} + +__isl_give isl_constraint *isl_basic_map_constraint( + __isl_take isl_basic_map *bmap, isl_int **line) +{ + int eq; + isl_size dim; + isl_ctx *ctx; + isl_vec *v; + isl_local_space *ls = NULL; + isl_constraint *constraint; + + if (!bmap || !line) + goto error; + + eq = line >= bmap->eq; + + ctx = isl_basic_map_get_ctx(bmap); + ls = isl_basic_map_get_local_space(bmap); + dim = isl_local_space_dim(ls, isl_dim_all); + if (dim < 0) + goto error; + v = isl_vec_alloc(ctx, 1 + dim); + if (!v) + goto error; + isl_seq_cpy(v->el, line[0], v->size); + constraint = isl_constraint_alloc_vec(eq, ls, v); + + isl_basic_map_free(bmap); + return constraint; +error: + isl_local_space_free(ls); + isl_basic_map_free(bmap); + return NULL; +} + +__isl_give isl_constraint *isl_basic_set_constraint( + __isl_take isl_basic_set *bset, isl_int **line) +{ + return isl_basic_map_constraint(bset_to_bmap(bset), line); +} + +__isl_give isl_constraint *isl_constraint_alloc_equality( + __isl_take isl_local_space *ls) +{ + return isl_constraint_alloc(1, ls); +} + +__isl_give isl_constraint *isl_constraint_alloc_inequality( + __isl_take isl_local_space *ls) +{ + return isl_constraint_alloc(0, ls); +} + +__isl_give isl_constraint *isl_constraint_dup(__isl_keep isl_constraint *c) +{ + if (!c) + return NULL; + + return isl_constraint_alloc_vec(c->eq, isl_local_space_copy(c->ls), + isl_vec_copy(c->v)); +} + +__isl_give isl_constraint *isl_constraint_cow(__isl_take isl_constraint *c) +{ + if (!c) + return NULL; + + if (c->ref == 1) + return c; + c->ref--; + return isl_constraint_dup(c); +} + +__isl_give isl_constraint *isl_constraint_copy( + __isl_keep isl_constraint *constraint) +{ + if (!constraint) + return NULL; + + constraint->ref++; + return constraint; +} + +__isl_null isl_constraint *isl_constraint_free(__isl_take isl_constraint *c) +{ + if (!c) + return NULL; + + if (--c->ref > 0) + return NULL; + + isl_local_space_free(c->ls); + isl_vec_free(c->v); + free(c); + + return NULL; +} + +/* Return the number of constraints in "bmap", i.e., the + * number of times isl_basic_map_foreach_constraint will + * call the callback. + */ +isl_size isl_basic_map_n_constraint(__isl_keep isl_basic_map *bmap) +{ + if (!bmap) + return isl_size_error; + + return bmap->n_eq + bmap->n_ineq; +} + +/* Return the number of constraints in "bset", i.e., the + * number of times isl_basic_set_foreach_constraint will + * call the callback. + */ +isl_size isl_basic_set_n_constraint(__isl_keep isl_basic_set *bset) +{ + return isl_basic_map_n_constraint(bset); +} + +isl_stat isl_basic_map_foreach_constraint(__isl_keep isl_basic_map *bmap, + isl_stat (*fn)(__isl_take isl_constraint *c, void *user), void *user) +{ + int i; + struct isl_constraint *c; + + if (!bmap) + return isl_stat_error; + + isl_assert(bmap->ctx, ISL_F_ISSET(bmap, ISL_BASIC_MAP_FINAL), + return isl_stat_error); + + for (i = 0; i < bmap->n_eq; ++i) { + c = isl_basic_map_constraint(isl_basic_map_copy(bmap), + &bmap->eq[i]); + if (!c) + return isl_stat_error; + if (fn(c, user) < 0) + return isl_stat_error; + } + + for (i = 0; i < bmap->n_ineq; ++i) { + c = isl_basic_map_constraint(isl_basic_map_copy(bmap), + &bmap->ineq[i]); + if (!c) + return isl_stat_error; + if (fn(c, user) < 0) + return isl_stat_error; + } + + return isl_stat_ok; +} + +isl_stat isl_basic_set_foreach_constraint(__isl_keep isl_basic_set *bset, + isl_stat (*fn)(__isl_take isl_constraint *c, void *user), void *user) +{ + return isl_basic_map_foreach_constraint(bset_to_bmap(bset), fn, user); +} + +/* Add the constraint to the list that "user" points to, if it is not + * a div constraint. + */ +static isl_stat collect_constraint(__isl_take isl_constraint *constraint, + void *user) +{ + isl_constraint_list **list = user; + isl_bool is_div; + + is_div = isl_constraint_is_div_constraint(constraint); + if (is_div < 0 || is_div) + isl_constraint_free(constraint); + else + *list = isl_constraint_list_add(*list, constraint); + + return is_div < 0 ? isl_stat_error : isl_stat_ok; +} + +/* Return a list of constraints that, when combined, are equivalent + * to "bmap". The input is required to have only known divs. + * + * There is no need to include the div constraints as they are + * implied by the div expressions. + */ +__isl_give isl_constraint_list *isl_basic_map_get_constraint_list( + __isl_keep isl_basic_map *bmap) +{ + isl_size n; + isl_bool known; + isl_ctx *ctx; + isl_constraint_list *list; + + known = isl_basic_map_divs_known(bmap); + if (known < 0) + return NULL; + ctx = isl_basic_map_get_ctx(bmap); + if (!known) + isl_die(ctx, isl_error_invalid, + "input involves unknown divs", return NULL); + + n = isl_basic_map_n_constraint(bmap); + if (n < 0) + return NULL; + list = isl_constraint_list_alloc(ctx, n); + if (isl_basic_map_foreach_constraint(bmap, + &collect_constraint, &list) < 0) + list = isl_constraint_list_free(list); + + return list; +} + +/* Return a list of constraints that, when combined, are equivalent + * to "bset". The input is required to have only known divs. + */ +__isl_give isl_constraint_list *isl_basic_set_get_constraint_list( + __isl_keep isl_basic_set *bset) +{ + return isl_basic_map_get_constraint_list(bset); +} + +int isl_constraint_is_equal(__isl_keep isl_constraint *constraint1, + __isl_keep isl_constraint *constraint2) +{ + int equal; + + if (!constraint1 || !constraint2) + return 0; + if (constraint1->eq != constraint2->eq) + return 0; + equal = isl_local_space_is_equal(constraint1->ls, constraint2->ls); + if (equal < 0 || !equal) + return equal; + return isl_vec_is_equal(constraint1->v, constraint2->v); +} + +__isl_give isl_basic_map *isl_basic_map_add_constraint( + __isl_take isl_basic_map *bmap, __isl_take isl_constraint *constraint) +{ + isl_ctx *ctx; + isl_space *space; + int equal_space; + + if (!bmap || !constraint) + goto error; + + ctx = isl_constraint_get_ctx(constraint); + space = isl_constraint_get_space(constraint); + equal_space = isl_space_is_equal(bmap->dim, space); + isl_space_free(space); + isl_assert(ctx, equal_space, goto error); + + bmap = isl_basic_map_intersect(bmap, + isl_basic_map_from_constraint(constraint)); + return bmap; +error: + isl_basic_map_free(bmap); + isl_constraint_free(constraint); + return NULL; +} + +__isl_give isl_basic_set *isl_basic_set_add_constraint( + __isl_take isl_basic_set *bset, __isl_take isl_constraint *constraint) +{ + return bset_from_bmap(isl_basic_map_add_constraint(bset_to_bmap(bset), + constraint)); +} + +__isl_give isl_map *isl_map_add_constraint(__isl_take isl_map *map, + __isl_take isl_constraint *constraint) +{ + isl_basic_map *bmap; + + bmap = isl_basic_map_from_constraint(constraint); + map = isl_map_intersect(map, isl_map_from_basic_map(bmap)); + + return map; +} + +__isl_give isl_set *isl_set_add_constraint(__isl_take isl_set *set, + __isl_take isl_constraint *constraint) +{ + return isl_map_add_constraint(set, constraint); +} + +/* Return the space of "constraint". + */ +static __isl_keep isl_space *isl_constraint_peek_space( + __isl_keep isl_constraint *constraint) +{ + return constraint ? isl_local_space_peek_space(constraint->ls) : NULL; +} + +__isl_give isl_space *isl_constraint_get_space( + __isl_keep isl_constraint *constraint) +{ + return constraint ? isl_local_space_get_space(constraint->ls) : NULL; +} + +__isl_give isl_local_space *isl_constraint_get_local_space( + __isl_keep isl_constraint *constraint) +{ + return constraint ? isl_local_space_copy(constraint->ls) : NULL; +} + +isl_size isl_constraint_dim(__isl_keep isl_constraint *constraint, + enum isl_dim_type type) +{ + if (!constraint) + return isl_size_error; + return n(constraint, type); +} + +#undef TYPE +#define TYPE isl_constraint +static +#include "check_type_range_templ.c" + +isl_bool isl_constraint_involves_dims(__isl_keep isl_constraint *constraint, + enum isl_dim_type type, unsigned first, unsigned n) +{ + int i; + int *active = NULL; + isl_bool involves = isl_bool_false; + + if (!constraint) + return isl_bool_error; + if (n == 0) + return isl_bool_false; + + if (isl_constraint_check_range(constraint, type, first, n) < 0) + return isl_bool_error; + + active = isl_local_space_get_active(constraint->ls, + constraint->v->el + 1); + if (!active) + goto error; + + first += isl_local_space_offset(constraint->ls, type) - 1; + for (i = 0; i < n; ++i) + if (active[first + i]) { + involves = isl_bool_true; + break; + } + + free(active); + + return involves; +error: + free(active); + return isl_bool_error; +} + +/* Does the given constraint represent a lower bound on the given + * dimension? + */ +isl_bool isl_constraint_is_lower_bound(__isl_keep isl_constraint *constraint, + enum isl_dim_type type, unsigned pos) +{ + if (isl_constraint_check_range(constraint, type, pos, 1) < 0) + return isl_bool_error; + + pos += isl_local_space_offset(constraint->ls, type); + return isl_bool_ok(isl_int_is_pos(constraint->v->el[pos])); +} + +/* Does the given constraint represent an upper bound on the given + * dimension? + */ +isl_bool isl_constraint_is_upper_bound(__isl_keep isl_constraint *constraint, + enum isl_dim_type type, unsigned pos) +{ + if (isl_constraint_check_range(constraint, type, pos, 1) < 0) + return isl_bool_error; + + pos += isl_local_space_offset(constraint->ls, type); + return isl_bool_ok(isl_int_is_neg(constraint->v->el[pos])); +} + +const char *isl_constraint_get_dim_name(__isl_keep isl_constraint *constraint, + enum isl_dim_type type, unsigned pos) +{ + return constraint ? + isl_local_space_get_dim_name(constraint->ls, type, pos) : NULL; +} + +void isl_constraint_get_constant(__isl_keep isl_constraint *constraint, + isl_int *v) +{ + if (!constraint) + return; + isl_int_set(*v, constraint->v->el[0]); +} + +/* Return the constant term of "constraint". + */ +__isl_give isl_val *isl_constraint_get_constant_val( + __isl_keep isl_constraint *constraint) +{ + isl_ctx *ctx; + + if (!constraint) + return NULL; + + ctx = isl_constraint_get_ctx(constraint); + return isl_val_int_from_isl_int(ctx, constraint->v->el[0]); +} + +void isl_constraint_get_coefficient(__isl_keep isl_constraint *constraint, + enum isl_dim_type type, int pos, isl_int *v) +{ + if (isl_constraint_check_range(constraint, type, pos, 1) < 0) + return; + + pos += isl_local_space_offset(constraint->ls, type); + isl_int_set(*v, constraint->v->el[pos]); +} + +/* Return the coefficient of the variable of type "type" at position "pos" + * of "constraint". + */ +__isl_give isl_val *isl_constraint_get_coefficient_val( + __isl_keep isl_constraint *constraint, enum isl_dim_type type, int pos) +{ + isl_ctx *ctx; + + if (isl_constraint_check_range(constraint, type, pos, 1) < 0) + return NULL; + + ctx = isl_constraint_get_ctx(constraint); + pos += isl_local_space_offset(constraint->ls, type); + return isl_val_int_from_isl_int(ctx, constraint->v->el[pos]); +} + +__isl_give isl_aff *isl_constraint_get_div(__isl_keep isl_constraint *constraint, + int pos) +{ + if (!constraint) + return NULL; + + return isl_local_space_get_div(constraint->ls, pos); +} + +__isl_give isl_constraint *isl_constraint_set_constant( + __isl_take isl_constraint *constraint, isl_int v) +{ + constraint = isl_constraint_cow(constraint); + if (!constraint) + return NULL; + + constraint->v = isl_vec_cow(constraint->v); + if (!constraint->v) + return isl_constraint_free(constraint); + + isl_int_set(constraint->v->el[0], v); + return constraint; +} + +/* Replace the constant term of "constraint" by "v". + */ +__isl_give isl_constraint *isl_constraint_set_constant_val( + __isl_take isl_constraint *constraint, __isl_take isl_val *v) +{ + constraint = isl_constraint_cow(constraint); + if (!constraint || !v) + goto error; + if (!isl_val_is_int(v)) + isl_die(isl_constraint_get_ctx(constraint), isl_error_invalid, + "expecting integer value", goto error); + constraint->v = isl_vec_set_element_val(constraint->v, 0, v); + if (!constraint->v) + constraint = isl_constraint_free(constraint); + return constraint; +error: + isl_val_free(v); + return isl_constraint_free(constraint); +} + +__isl_give isl_constraint *isl_constraint_set_constant_si( + __isl_take isl_constraint *constraint, int v) +{ + constraint = isl_constraint_cow(constraint); + if (!constraint) + return NULL; + + constraint->v = isl_vec_cow(constraint->v); + if (!constraint->v) + return isl_constraint_free(constraint); + + isl_int_set_si(constraint->v->el[0], v); + return constraint; +} + +/* Replace the coefficient of the variable of type "type" at position "pos" + * of "constraint" by "v". + */ +__isl_give isl_constraint *isl_constraint_set_coefficient_val( + __isl_take isl_constraint *constraint, + enum isl_dim_type type, int pos, __isl_take isl_val *v) +{ + constraint = isl_constraint_cow(constraint); + if (!constraint || !v) + goto error; + if (!isl_val_is_int(v)) + isl_die(isl_constraint_get_ctx(constraint), isl_error_invalid, + "expecting integer value", goto error); + if (isl_constraint_check_range(constraint, type, pos, 1) < 0) + goto error; + + pos += isl_local_space_offset(constraint->ls, type); + constraint->v = isl_vec_set_element_val(constraint->v, pos, v); + if (!constraint->v) + constraint = isl_constraint_free(constraint); + return constraint; +error: + isl_val_free(v); + return isl_constraint_free(constraint); +} + +__isl_give isl_constraint *isl_constraint_set_coefficient_si( + __isl_take isl_constraint *constraint, + enum isl_dim_type type, int pos, int v) +{ + constraint = isl_constraint_cow(constraint); + if (isl_constraint_check_range(constraint, type, pos, 1) < 0) + return isl_constraint_free(constraint); + + constraint->v = isl_vec_cow(constraint->v); + if (!constraint->v) + return isl_constraint_free(constraint); + + pos += isl_local_space_offset(constraint->ls, type); + isl_int_set_si(constraint->v->el[pos], v); + + return constraint; +} + +__isl_give isl_constraint *isl_constraint_negate( + __isl_take isl_constraint *constraint) +{ + isl_ctx *ctx; + + constraint = isl_constraint_cow(constraint); + if (!constraint) + return NULL; + + ctx = isl_constraint_get_ctx(constraint); + if (isl_constraint_is_equality(constraint)) + isl_die(ctx, isl_error_invalid, "cannot negate equality", + return isl_constraint_free(constraint)); + constraint->v = isl_vec_neg(constraint->v); + constraint->v = isl_vec_cow(constraint->v); + if (!constraint->v) + return isl_constraint_free(constraint); + isl_int_sub_ui(constraint->v->el[0], constraint->v->el[0], 1); + return constraint; +} + +isl_bool isl_constraint_is_equality(struct isl_constraint *constraint) +{ + if (!constraint) + return isl_bool_error; + return isl_bool_ok(constraint->eq); +} + +isl_bool isl_constraint_is_div_constraint(__isl_keep isl_constraint *constraint) +{ + int i; + isl_size n_div; + + if (!constraint) + return isl_bool_error; + if (isl_constraint_is_equality(constraint)) + return isl_bool_false; + n_div = isl_constraint_dim(constraint, isl_dim_div); + if (n_div < 0) + return isl_bool_error; + for (i = 0; i < n_div; ++i) { + isl_bool is_div; + is_div = isl_local_space_is_div_constraint(constraint->ls, + constraint->v->el, i); + if (is_div < 0 || is_div) + return is_div; + } + + return isl_bool_false; +} + +/* Is "constraint" an equality that corresponds to integer division "div"? + * + * That is, given an integer division of the form + * + * a = floor((f + c)/m) + * + * is the equality of the form + * + * -f + m d + c' = 0 + * ? + * Note that the constant term is not checked explicitly, but given + * that this is a valid equality constraint, the constant c' necessarily + * has a value close to -c. + */ +isl_bool isl_constraint_is_div_equality(__isl_keep isl_constraint *constraint, + unsigned div) +{ + isl_bool equality; + + equality = isl_constraint_is_equality(constraint); + if (equality < 0 || !equality) + return equality; + return isl_local_space_is_div_equality(constraint->ls, + constraint->v->el, div); +} + +/* We manually set ISL_BASIC_SET_FINAL instead of calling + * isl_basic_map_finalize because we want to keep the position + * of the divs and we therefore do not want to throw away redundant divs. + * This is arguably a bit fragile. + */ +__isl_give isl_basic_map *isl_basic_map_from_constraint( + __isl_take isl_constraint *constraint) +{ + int k; + isl_local_space *ls; + struct isl_basic_map *bmap; + isl_int *c; + isl_size total; + + if (!constraint) + return NULL; + + ls = isl_local_space_copy(constraint->ls); + bmap = isl_basic_map_from_local_space(ls); + bmap = isl_basic_map_extend_constraints(bmap, 1, 1); + if (isl_constraint_is_equality(constraint)) { + k = isl_basic_map_alloc_equality(bmap); + if (k < 0) + goto error; + c = bmap->eq[k]; + } + else { + k = isl_basic_map_alloc_inequality(bmap); + if (k < 0) + goto error; + c = bmap->ineq[k]; + } + total = isl_basic_map_dim(bmap, isl_dim_all); + if (total < 0) + goto error; + isl_seq_cpy(c, constraint->v->el, 1 + total); + isl_constraint_free(constraint); + if (bmap) + ISL_F_SET(bmap, ISL_BASIC_SET_FINAL); + return bmap; +error: + isl_constraint_free(constraint); + isl_basic_map_free(bmap); + return NULL; +} + +__isl_give isl_basic_set *isl_basic_set_from_constraint( + __isl_take isl_constraint *constraint) +{ + isl_space *space; + + space = isl_constraint_peek_space(constraint); + if (isl_space_check_is_set(space) < 0) + goto error; + return bset_from_bmap(isl_basic_map_from_constraint(constraint)); +error: + isl_constraint_free(constraint); + return NULL; +} + +/* Is the variable of "type" at position "pos" of "bmap" defined + * in terms of earlier dimensions through an equality? + * + * If so, and if c is not NULL, then return a copy of this equality in *c. + */ +isl_bool isl_basic_map_has_defining_equality( + __isl_keep isl_basic_map *bmap, enum isl_dim_type type, int pos, + __isl_give isl_constraint **c) +{ + int i; + unsigned offset; + isl_size total; + + if (isl_basic_map_check_range(bmap, type, pos, 1) < 0) + return isl_bool_error; + offset = isl_basic_map_offset(bmap, type); + total = isl_basic_map_dim(bmap, isl_dim_all); + if (total < 0) + return isl_bool_error; + for (i = 0; i < bmap->n_eq; ++i) { + if (isl_int_is_zero(bmap->eq[i][offset + pos]) || + isl_seq_first_non_zero(bmap->eq[i]+offset+pos+1, + 1+total-offset-pos-1) != -1) + continue; + if (c) + *c = isl_basic_map_constraint(isl_basic_map_copy(bmap), + &bmap->eq[i]); + return isl_bool_true; + } + return isl_bool_false; +} + +/* Is the variable of "type" at position "pos" of "bset" defined + * in terms of earlier dimensions through an equality? + * + * If so, and if c is not NULL, then return a copy of this equality in *c. + */ +isl_bool isl_basic_set_has_defining_equality( + __isl_keep isl_basic_set *bset, enum isl_dim_type type, int pos, + __isl_give isl_constraint **c) +{ + return isl_basic_map_has_defining_equality(bset_to_bmap(bset), + type, pos, c); +} + +isl_bool isl_basic_set_has_defining_inequalities( + struct isl_basic_set *bset, enum isl_dim_type type, int pos, + struct isl_constraint **lower, + struct isl_constraint **upper) +{ + int i, j; + unsigned offset; + isl_size total; + isl_int m; + isl_int **lower_line, **upper_line; + + if (isl_basic_set_check_range(bset, type, pos, 1) < 0) + return isl_bool_error; + offset = isl_basic_set_offset(bset, type); + total = isl_basic_set_dim(bset, isl_dim_all); + if (total < 0) + return isl_bool_error; + isl_int_init(m); + for (i = 0; i < bset->n_ineq; ++i) { + if (isl_int_is_zero(bset->ineq[i][offset + pos])) + continue; + if (isl_int_is_one(bset->ineq[i][offset + pos])) + continue; + if (isl_int_is_negone(bset->ineq[i][offset + pos])) + continue; + if (isl_seq_first_non_zero(bset->ineq[i]+offset+pos+1, + 1+total-offset-pos-1) != -1) + continue; + for (j = i + 1; j < bset->n_ineq; ++j) { + if (!isl_seq_is_neg(bset->ineq[i]+1, bset->ineq[j]+1, + total)) + continue; + isl_int_add(m, bset->ineq[i][0], bset->ineq[j][0]); + if (isl_int_abs_ge(m, bset->ineq[i][offset+pos])) + continue; + + if (isl_int_is_pos(bset->ineq[i][offset+pos])) { + lower_line = &bset->ineq[i]; + upper_line = &bset->ineq[j]; + } else { + lower_line = &bset->ineq[j]; + upper_line = &bset->ineq[i]; + } + *lower = isl_basic_set_constraint( + isl_basic_set_copy(bset), lower_line); + *upper = isl_basic_set_constraint( + isl_basic_set_copy(bset), upper_line); + isl_int_clear(m); + return isl_bool_true; + } + } + *lower = NULL; + *upper = NULL; + isl_int_clear(m); + return isl_bool_false; +} + +/* Given two constraints "a" and "b" on the variable at position "abs_pos" + * (in "a" and "b"), add a constraint to "bset" that ensures that the + * bound implied by "a" is (strictly) larger than the bound implied by "b". + * + * If both constraints imply lower bounds, then this means that "a" is + * active in the result. + * If both constraints imply upper bounds, then this means that "b" is + * active in the result. + */ +static __isl_give isl_basic_set *add_larger_bound_constraint( + __isl_take isl_basic_set *bset, isl_int *a, isl_int *b, + unsigned abs_pos, int strict) +{ + int k; + isl_int t; + isl_size total; + + total = isl_basic_set_dim(bset, isl_dim_all); + if (total < 0) + return isl_basic_set_free(bset); + k = isl_basic_set_alloc_inequality(bset); + if (k < 0) + goto error; + + isl_int_init(t); + isl_int_neg(t, b[1 + abs_pos]); + + isl_seq_combine(bset->ineq[k], t, a, a[1 + abs_pos], b, 1 + abs_pos); + isl_seq_combine(bset->ineq[k] + 1 + abs_pos, + t, a + 1 + abs_pos + 1, a[1 + abs_pos], b + 1 + abs_pos + 1, + total - abs_pos); + + if (strict) + isl_int_sub_ui(bset->ineq[k][0], bset->ineq[k][0], 1); + + isl_int_clear(t); + + return bset; +error: + isl_basic_set_free(bset); + return NULL; +} + +/* Add constraints to "context" that ensure that "u" is the smallest + * (and therefore active) upper bound on "abs_pos" in "bset" and return + * the resulting basic set. + */ +static __isl_give isl_basic_set *set_smallest_upper_bound( + __isl_keep isl_basic_set *context, + __isl_keep isl_basic_set *bset, unsigned abs_pos, int n_upper, int u) +{ + int j; + + context = isl_basic_set_copy(context); + context = isl_basic_set_cow(context); + + context = isl_basic_set_extend_constraints(context, 0, n_upper - 1); + + for (j = 0; j < bset->n_ineq; ++j) { + if (j == u) + continue; + if (!isl_int_is_neg(bset->ineq[j][1 + abs_pos])) + continue; + context = add_larger_bound_constraint(context, + bset->ineq[j], bset->ineq[u], abs_pos, j > u); + } + + context = isl_basic_set_simplify(context); + context = isl_basic_set_finalize(context); + + return context; +} + +/* Add constraints to "context" that ensure that "u" is the largest + * (and therefore active) upper bound on "abs_pos" in "bset" and return + * the resulting basic set. + */ +static __isl_give isl_basic_set *set_largest_lower_bound( + __isl_keep isl_basic_set *context, + __isl_keep isl_basic_set *bset, unsigned abs_pos, int n_lower, int l) +{ + int j; + + context = isl_basic_set_copy(context); + context = isl_basic_set_cow(context); + + context = isl_basic_set_extend_constraints(context, 0, n_lower - 1); + + for (j = 0; j < bset->n_ineq; ++j) { + if (j == l) + continue; + if (!isl_int_is_pos(bset->ineq[j][1 + abs_pos])) + continue; + context = add_larger_bound_constraint(context, + bset->ineq[l], bset->ineq[j], abs_pos, j > l); + } + + context = isl_basic_set_simplify(context); + context = isl_basic_set_finalize(context); + + return context; +} + +static isl_stat foreach_upper_bound(__isl_keep isl_basic_set *bset, + enum isl_dim_type type, unsigned abs_pos, + __isl_take isl_basic_set *context, int n_upper, + isl_stat (*fn)(__isl_take isl_constraint *lower, + __isl_take isl_constraint *upper, + __isl_take isl_basic_set *bset, void *user), void *user) +{ + isl_basic_set *context_i; + isl_constraint *upper = NULL; + int i; + + for (i = 0; i < bset->n_ineq; ++i) { + if (isl_int_is_zero(bset->ineq[i][1 + abs_pos])) + continue; + + context_i = set_smallest_upper_bound(context, bset, + abs_pos, n_upper, i); + if (isl_basic_set_is_empty(context_i)) { + isl_basic_set_free(context_i); + continue; + } + upper = isl_basic_set_constraint(isl_basic_set_copy(bset), + &bset->ineq[i]); + if (!upper || !context_i) + goto error; + if (fn(NULL, upper, context_i, user) < 0) + break; + } + + isl_basic_set_free(context); + + if (i < bset->n_ineq) + return isl_stat_error; + + return isl_stat_ok; +error: + isl_constraint_free(upper); + isl_basic_set_free(context_i); + isl_basic_set_free(context); + return isl_stat_error; +} + +static isl_stat foreach_lower_bound(__isl_keep isl_basic_set *bset, + enum isl_dim_type type, unsigned abs_pos, + __isl_take isl_basic_set *context, int n_lower, + isl_stat (*fn)(__isl_take isl_constraint *lower, + __isl_take isl_constraint *upper, + __isl_take isl_basic_set *bset, void *user), void *user) +{ + isl_basic_set *context_i; + isl_constraint *lower = NULL; + int i; + + for (i = 0; i < bset->n_ineq; ++i) { + if (isl_int_is_zero(bset->ineq[i][1 + abs_pos])) + continue; + + context_i = set_largest_lower_bound(context, bset, + abs_pos, n_lower, i); + if (isl_basic_set_is_empty(context_i)) { + isl_basic_set_free(context_i); + continue; + } + lower = isl_basic_set_constraint(isl_basic_set_copy(bset), + &bset->ineq[i]); + if (!lower || !context_i) + goto error; + if (fn(lower, NULL, context_i, user) < 0) + break; + } + + isl_basic_set_free(context); + + if (i < bset->n_ineq) + return isl_stat_error; + + return isl_stat_ok; +error: + isl_constraint_free(lower); + isl_basic_set_free(context_i); + isl_basic_set_free(context); + return isl_stat_error; +} + +static isl_stat foreach_bound_pair(__isl_keep isl_basic_set *bset, + enum isl_dim_type type, unsigned abs_pos, + __isl_take isl_basic_set *context, int n_lower, int n_upper, + isl_stat (*fn)(__isl_take isl_constraint *lower, + __isl_take isl_constraint *upper, + __isl_take isl_basic_set *bset, void *user), void *user) +{ + isl_basic_set *context_i, *context_j; + isl_constraint *lower = NULL; + isl_constraint *upper = NULL; + int i, j; + + for (i = 0; i < bset->n_ineq; ++i) { + if (!isl_int_is_pos(bset->ineq[i][1 + abs_pos])) + continue; + + context_i = set_largest_lower_bound(context, bset, + abs_pos, n_lower, i); + if (isl_basic_set_is_empty(context_i)) { + isl_basic_set_free(context_i); + continue; + } + + for (j = 0; j < bset->n_ineq; ++j) { + if (!isl_int_is_neg(bset->ineq[j][1 + abs_pos])) + continue; + + context_j = set_smallest_upper_bound(context_i, bset, + abs_pos, n_upper, j); + context_j = isl_basic_set_extend_constraints(context_j, + 0, 1); + context_j = add_larger_bound_constraint(context_j, + bset->ineq[i], bset->ineq[j], abs_pos, 0); + context_j = isl_basic_set_simplify(context_j); + context_j = isl_basic_set_finalize(context_j); + if (isl_basic_set_is_empty(context_j)) { + isl_basic_set_free(context_j); + continue; + } + lower = isl_basic_set_constraint(isl_basic_set_copy(bset), + &bset->ineq[i]); + upper = isl_basic_set_constraint(isl_basic_set_copy(bset), + &bset->ineq[j]); + if (!lower || !upper || !context_j) + goto error; + if (fn(lower, upper, context_j, user) < 0) + break; + } + + isl_basic_set_free(context_i); + + if (j < bset->n_ineq) + break; + } + + isl_basic_set_free(context); + + if (i < bset->n_ineq) + return isl_stat_error; + + return isl_stat_ok; +error: + isl_constraint_free(lower); + isl_constraint_free(upper); + isl_basic_set_free(context_i); + isl_basic_set_free(context_j); + isl_basic_set_free(context); + return isl_stat_error; +} + +/* For each pair of lower and upper bounds on the variable "pos" + * of type "type", call "fn" with these lower and upper bounds and the + * set of constraints on the remaining variables where these bounds + * are active, i.e., (stricly) larger/smaller than the other lower/upper bounds. + * + * If the designated variable is equal to an affine combination of the + * other variables then fn is called with both lower and upper + * set to the corresponding equality. + * + * If there is no lower (or upper) bound, then NULL is passed + * as the corresponding bound. + * + * We first check if the variable is involved in any equality. + * If not, we count the number of lower and upper bounds and + * act accordingly. + */ +isl_stat isl_basic_set_foreach_bound_pair(__isl_keep isl_basic_set *bset, + enum isl_dim_type type, unsigned pos, + isl_stat (*fn)(__isl_take isl_constraint *lower, + __isl_take isl_constraint *upper, + __isl_take isl_basic_set *bset, void *user), void *user) +{ + int i; + isl_constraint *lower = NULL; + isl_constraint *upper = NULL; + isl_basic_set *context = NULL; + unsigned abs_pos; + int n_lower, n_upper; + isl_size off; + + if (isl_basic_set_check_range(bset, type, pos, 1) < 0) + return isl_stat_error; + isl_assert(bset->ctx, type == isl_dim_param || type == isl_dim_set, + return isl_stat_error); + + off = isl_basic_set_var_offset(bset, type); + if (off < 0) + return isl_stat_error; + abs_pos = off + pos; + + for (i = 0; i < bset->n_eq; ++i) { + if (isl_int_is_zero(bset->eq[i][1 + abs_pos])) + continue; + + lower = isl_basic_set_constraint(isl_basic_set_copy(bset), + &bset->eq[i]); + upper = isl_constraint_copy(lower); + context = isl_basic_set_remove_dims(isl_basic_set_copy(bset), + type, pos, 1); + if (!lower || !upper || !context) + goto error; + return fn(lower, upper, context, user); + } + + n_lower = 0; + n_upper = 0; + for (i = 0; i < bset->n_ineq; ++i) { + if (isl_int_is_pos(bset->ineq[i][1 + abs_pos])) + n_lower++; + else if (isl_int_is_neg(bset->ineq[i][1 + abs_pos])) + n_upper++; + } + + context = isl_basic_set_copy(bset); + context = isl_basic_set_cow(context); + if (!context) + goto error; + for (i = context->n_ineq - 1; i >= 0; --i) + if (!isl_int_is_zero(context->ineq[i][1 + abs_pos])) + isl_basic_set_drop_inequality(context, i); + + context = isl_basic_set_drop(context, type, pos, 1); + if (!n_lower && !n_upper) + return fn(NULL, NULL, context, user); + if (!n_lower) + return foreach_upper_bound(bset, type, abs_pos, context, n_upper, + fn, user); + if (!n_upper) + return foreach_lower_bound(bset, type, abs_pos, context, n_lower, + fn, user); + return foreach_bound_pair(bset, type, abs_pos, context, n_lower, n_upper, + fn, user); +error: + isl_constraint_free(lower); + isl_constraint_free(upper); + isl_basic_set_free(context); + return isl_stat_error; +} + +__isl_give isl_aff *isl_constraint_get_bound( + __isl_keep isl_constraint *constraint, enum isl_dim_type type, int pos) +{ + isl_space *space; + isl_aff *aff; + isl_ctx *ctx; + + if (isl_constraint_check_range(constraint, type, pos, 1) < 0) + return NULL; + space = isl_constraint_peek_space(constraint); + if (isl_space_check_is_set(space) < 0) + return NULL; + + ctx = isl_constraint_get_ctx(constraint); + pos += offset(constraint, type); + if (isl_int_is_zero(constraint->v->el[pos])) + isl_die(ctx, isl_error_invalid, + "constraint does not define a bound on given dimension", + return NULL); + + aff = isl_aff_alloc(isl_local_space_copy(constraint->ls)); + if (!aff) + return NULL; + + if (isl_int_is_neg(constraint->v->el[pos])) + isl_seq_cpy(aff->v->el + 1, constraint->v->el, aff->v->size - 1); + else + isl_seq_neg(aff->v->el + 1, constraint->v->el, aff->v->size - 1); + isl_int_set_si(aff->v->el[1 + pos], 0); + isl_int_abs(aff->v->el[0], constraint->v->el[pos]); + aff = isl_aff_normalize(aff); + + return aff; +} + +/* For an inequality constraint + * + * f >= 0 + * + * or an equality constraint + * + * f = 0 + * + * return the affine expression f. + */ +__isl_give isl_aff *isl_constraint_get_aff( + __isl_keep isl_constraint *constraint) +{ + isl_aff *aff; + + if (!constraint) + return NULL; + + aff = isl_aff_alloc(isl_local_space_copy(constraint->ls)); + if (!aff) + return NULL; + + isl_seq_cpy(aff->v->el + 1, constraint->v->el, aff->v->size - 1); + isl_int_set_si(aff->v->el[0], 1); + + return aff; +} + +/* Construct an inequality (eq = 0) or equality (eq = 1) constraint from "aff". + * In particular, construct aff >= 0 or aff = 0. + * + * The denominator of "aff" can be ignored. + */ +static __isl_give isl_constraint *isl_constraint_alloc_aff(int eq, + __isl_take isl_aff *aff) +{ + isl_local_space *ls; + isl_vec *v; + + if (!aff) + return NULL; + ls = isl_aff_get_domain_local_space(aff); + v = isl_vec_drop_els(isl_vec_copy(aff->v), 0, 1); + isl_aff_free(aff); + + return isl_constraint_alloc_vec(eq, ls, v); +} + +/* Construct an equality constraint equating the given affine expression + * to zero. + */ +__isl_give isl_constraint *isl_equality_from_aff(__isl_take isl_aff *aff) +{ + return isl_constraint_alloc_aff(1, aff); +} + +/* Construct an inequality constraint enforcing the given affine expression + * to be non-negative. + */ +__isl_give isl_constraint *isl_inequality_from_aff(__isl_take isl_aff *aff) +{ + return isl_constraint_alloc_aff(0, aff); +} + +/* Compare two isl_constraints. + * + * Return -1 if "c1" is "smaller" than "c2", 1 if "c1" is "greater" + * than "c2" and 0 if they are equal. + * + * The order is fairly arbitrary. We do consider constraints that only involve + * earlier dimensions as "smaller". + */ +int isl_constraint_plain_cmp(__isl_keep isl_constraint *c1, + __isl_keep isl_constraint *c2) +{ + int cmp; + int last1, last2; + + if (c1 == c2) + return 0; + if (!c1) + return -1; + if (!c2) + return 1; + cmp = isl_local_space_cmp(c1->ls, c2->ls); + if (cmp != 0) + return cmp; + + last1 = isl_seq_last_non_zero(c1->v->el + 1, c1->v->size - 1); + last2 = isl_seq_last_non_zero(c2->v->el + 1, c1->v->size - 1); + if (last1 != last2) + return last1 - last2; + + return isl_seq_cmp(c1->v->el, c2->v->el, c1->v->size); +} + +/* Compare two constraints based on their final (non-zero) coefficients. + * In particular, the constraint that involves later variables or + * that has a larger coefficient for a shared latest variable + * is considered "greater" than the other constraint. + * + * Return -1 if "c1" is "smaller" than "c2", 1 if "c1" is "greater" + * than "c2" and 0 if they are equal. + * + * If the constraints live in different local spaces, then we cannot + * really compare the constraints so we compare the local spaces instead. + */ +int isl_constraint_cmp_last_non_zero(__isl_keep isl_constraint *c1, + __isl_keep isl_constraint *c2) +{ + int cmp; + int last1, last2; + + if (c1 == c2) + return 0; + if (!c1) + return -1; + if (!c2) + return 1; + cmp = isl_local_space_cmp(c1->ls, c2->ls); + if (cmp != 0) + return cmp; + + last1 = isl_seq_last_non_zero(c1->v->el + 1, c1->v->size - 1); + last2 = isl_seq_last_non_zero(c2->v->el + 1, c1->v->size - 1); + if (last1 != last2) + return last1 - last2; + if (last1 == -1) + return 0; + return isl_int_abs_cmp(c1->v->el[1 + last1], c2->v->el[1 + last2]); +} diff --git a/external/mit/isl/dist/isl_constraint_private.h b/external/mit/isl/dist/isl_constraint_private.h new file mode 100644 index 000000000000..901bdcac2e74 --- /dev/null +++ b/external/mit/isl/dist/isl_constraint_private.h @@ -0,0 +1,32 @@ +#ifndef ISL_CONSTRAINT_PRIVATE_H +#define ISL_CONSTRAINT_PRIVATE_H + +#include +#include +#include + +struct isl_constraint { + int ref; + + int eq; + isl_local_space *ls; + isl_vec *v; +}; + +#undef EL +#define EL isl_constraint + +#include + +__isl_give isl_constraint *isl_basic_set_constraint( + __isl_take isl_basic_set *bset, isl_int **line); + +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_bool isl_constraint_is_div_equality(__isl_keep isl_constraint *constraint, + unsigned div); + +#endif diff --git a/external/mit/isl/dist/isl_convex_hull.c b/external/mit/isl/dist/isl_convex_hull.c new file mode 100644 index 000000000000..a15092e68d58 --- /dev/null +++ b/external/mit/isl/dist/isl_convex_hull.c @@ -0,0 +1,3148 @@ +/* + * Copyright 2008-2009 Katholieke Universiteit Leuven + * Copyright 2014 INRIA Rocquencourt + * + * 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 Paris - Rocquencourt, Domaine de Voluceau - Rocquencourt, + * B.P. 105 - 78153 Le Chesnay, France + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "isl_equalities.h" +#include "isl_tab.h" +#include + +#include +#include +#include + +static __isl_give isl_basic_set *uset_convex_hull_wrap_bounded( + __isl_take isl_set *set); + +/* Remove redundant + * constraints. If the minimal value along the normal of a constraint + * is the same if the constraint is removed, then the constraint is redundant. + * + * Since some constraints may be mutually redundant, sort the constraints + * first such that constraints that involve existentially quantified + * variables are considered for removal before those that do not. + * The sorting is also needed for the use in map_simple_hull. + * + * Note that isl_tab_detect_implicit_equalities may also end up + * marking some constraints as redundant. Make sure the constraints + * are preserved and undo those marking such that isl_tab_detect_redundant + * can consider the constraints in the sorted order. + * + * Alternatively, we could have intersected the basic map with the + * corresponding equality and then checked if the dimension was that + * of a facet. + */ +__isl_give isl_basic_map *isl_basic_map_remove_redundancies( + __isl_take isl_basic_map *bmap) +{ + struct isl_tab *tab; + + if (!bmap) + return NULL; + + bmap = isl_basic_map_gauss(bmap, NULL); + if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_EMPTY)) + return bmap; + if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_NO_REDUNDANT)) + return bmap; + if (bmap->n_ineq <= 1) + return bmap; + + bmap = isl_basic_map_sort_constraints(bmap); + tab = isl_tab_from_basic_map(bmap, 0); + if (!tab) + goto error; + tab->preserve = 1; + if (isl_tab_detect_implicit_equalities(tab) < 0) + goto error; + if (isl_tab_restore_redundant(tab) < 0) + goto error; + tab->preserve = 0; + if (isl_tab_detect_redundant(tab) < 0) + goto error; + bmap = isl_basic_map_update_from_tab(bmap, tab); + isl_tab_free(tab); + if (!bmap) + return NULL; + ISL_F_SET(bmap, ISL_BASIC_MAP_NO_IMPLICIT); + ISL_F_SET(bmap, ISL_BASIC_MAP_NO_REDUNDANT); + return bmap; +error: + isl_tab_free(tab); + isl_basic_map_free(bmap); + return NULL; +} + +__isl_give isl_basic_set *isl_basic_set_remove_redundancies( + __isl_take isl_basic_set *bset) +{ + return bset_from_bmap( + isl_basic_map_remove_redundancies(bset_to_bmap(bset))); +} + +/* Remove redundant constraints in each of the basic maps. + */ +__isl_give isl_map *isl_map_remove_redundancies(__isl_take isl_map *map) +{ + return isl_map_inline_foreach_basic_map(map, + &isl_basic_map_remove_redundancies); +} + +__isl_give isl_set *isl_set_remove_redundancies(__isl_take isl_set *set) +{ + return isl_map_remove_redundancies(set); +} + +/* Check if the set set is bound in the direction of the affine + * constraint c and if so, set the constant term such that the + * resulting constraint is a bounding constraint for the set. + */ +static isl_bool uset_is_bound(__isl_keep isl_set *set, isl_int *c, unsigned len) +{ + int first; + int j; + isl_int opt; + isl_int opt_denom; + + isl_int_init(opt); + isl_int_init(opt_denom); + first = 1; + for (j = 0; j < set->n; ++j) { + enum isl_lp_result res; + + if (ISL_F_ISSET(set->p[j], ISL_BASIC_SET_EMPTY)) + continue; + + res = isl_basic_set_solve_lp(set->p[j], + 0, c, set->ctx->one, &opt, &opt_denom, NULL); + if (res == isl_lp_unbounded) + break; + if (res == isl_lp_error) + goto error; + if (res == isl_lp_empty) { + set->p[j] = isl_basic_set_set_to_empty(set->p[j]); + if (!set->p[j]) + goto error; + continue; + } + if (first || isl_int_is_neg(opt)) { + if (!isl_int_is_one(opt_denom)) + isl_seq_scale(c, c, opt_denom, len); + isl_int_sub(c[0], c[0], opt); + } + first = 0; + } + isl_int_clear(opt); + isl_int_clear(opt_denom); + return isl_bool_ok(j >= set->n); +error: + isl_int_clear(opt); + isl_int_clear(opt_denom); + return isl_bool_error; +} + +static __isl_give isl_set *isl_set_add_basic_set_equality( + __isl_take isl_set *set, isl_int *c) +{ + int i; + + set = isl_set_cow(set); + if (!set) + return NULL; + for (i = 0; i < set->n; ++i) { + set->p[i] = isl_basic_set_add_eq(set->p[i], c); + if (!set->p[i]) + goto error; + } + return set; +error: + isl_set_free(set); + return NULL; +} + +/* Given a union of basic sets, construct the constraints for wrapping + * a facet around one of its ridges. + * In particular, if each of n the d-dimensional basic sets i in "set" + * contains the origin, satisfies the constraints x_1 >= 0 and x_2 >= 0 + * and is defined by the constraints + * [ 1 ] + * A_i [ x ] >= 0 + * + * then the resulting set is of dimension n*(1+d) and has as constraints + * + * [ a_i ] + * A_i [ x_i ] >= 0 + * + * a_i >= 0 + * + * \sum_i x_{i,1} = 1 + */ +static __isl_give isl_basic_set *wrap_constraints(__isl_keep isl_set *set) +{ + struct isl_basic_set *lp; + unsigned n_eq; + unsigned n_ineq; + int i, j, k; + isl_size dim, lp_dim; + + dim = isl_set_dim(set, isl_dim_set); + if (dim < 0) + return NULL; + + dim += 1; + n_eq = 1; + n_ineq = set->n; + for (i = 0; i < set->n; ++i) { + n_eq += set->p[i]->n_eq; + n_ineq += set->p[i]->n_ineq; + } + lp = isl_basic_set_alloc(set->ctx, 0, dim * set->n, 0, n_eq, n_ineq); + lp = isl_basic_set_set_rational(lp); + if (!lp) + return NULL; + lp_dim = isl_basic_set_dim(lp, isl_dim_set); + if (lp_dim < 0) + return isl_basic_set_free(lp); + k = isl_basic_set_alloc_equality(lp); + isl_int_set_si(lp->eq[k][0], -1); + for (i = 0; i < set->n; ++i) { + isl_int_set_si(lp->eq[k][1+dim*i], 0); + isl_int_set_si(lp->eq[k][1+dim*i+1], 1); + isl_seq_clr(lp->eq[k]+1+dim*i+2, dim-2); + } + for (i = 0; i < set->n; ++i) { + k = isl_basic_set_alloc_inequality(lp); + isl_seq_clr(lp->ineq[k], 1+lp_dim); + isl_int_set_si(lp->ineq[k][1+dim*i], 1); + + for (j = 0; j < set->p[i]->n_eq; ++j) { + k = isl_basic_set_alloc_equality(lp); + isl_seq_clr(lp->eq[k], 1+dim*i); + isl_seq_cpy(lp->eq[k]+1+dim*i, set->p[i]->eq[j], dim); + isl_seq_clr(lp->eq[k]+1+dim*(i+1), dim*(set->n-i-1)); + } + + for (j = 0; j < set->p[i]->n_ineq; ++j) { + k = isl_basic_set_alloc_inequality(lp); + isl_seq_clr(lp->ineq[k], 1+dim*i); + isl_seq_cpy(lp->ineq[k]+1+dim*i, set->p[i]->ineq[j], dim); + isl_seq_clr(lp->ineq[k]+1+dim*(i+1), dim*(set->n-i-1)); + } + } + return lp; +} + +/* Given a facet "facet" of the convex hull of "set" and a facet "ridge" + * of that facet, compute the other facet of the convex hull that contains + * the ridge. + * + * We first transform the set such that the facet constraint becomes + * + * x_1 >= 0 + * + * I.e., the facet lies in + * + * x_1 = 0 + * + * and on that facet, the constraint that defines the ridge is + * + * x_2 >= 0 + * + * (This transformation is not strictly needed, all that is needed is + * that the ridge contains the origin.) + * + * Since the ridge contains the origin, the cone of the convex hull + * will be of the form + * + * x_1 >= 0 + * x_2 >= a x_1 + * + * with this second constraint defining the new facet. + * The constant a is obtained by settting x_1 in the cone of the + * convex hull to 1 and minimizing x_2. + * Now, each element in the cone of the convex hull is the sum + * of elements in the cones of the basic sets. + * If a_i is the dilation factor of basic set i, then the problem + * we need to solve is + * + * min \sum_i x_{i,2} + * st + * \sum_i x_{i,1} = 1 + * a_i >= 0 + * [ a_i ] + * A [ x_i ] >= 0 + * + * with + * [ 1 ] + * A_i [ x_i ] >= 0 + * + * the constraints of each (transformed) basic set. + * If a = n/d, then the constraint defining the new facet (in the transformed + * space) is + * + * -n x_1 + d x_2 >= 0 + * + * In the original space, we need to take the same combination of the + * corresponding constraints "facet" and "ridge". + * + * If a = -infty = "-1/0", then we just return the original facet constraint. + * This means that the facet is unbounded, but has a bounded intersection + * with the union of sets. + */ +isl_int *isl_set_wrap_facet(__isl_keep isl_set *set, + isl_int *facet, isl_int *ridge) +{ + int i; + isl_ctx *ctx; + struct isl_mat *T = NULL; + struct isl_basic_set *lp = NULL; + struct isl_vec *obj; + enum isl_lp_result res; + isl_int num, den; + isl_size dim; + + dim = isl_set_dim(set, isl_dim_set); + if (dim < 0) + return NULL; + ctx = set->ctx; + set = isl_set_copy(set); + set = isl_set_set_rational(set); + + dim += 1; + T = isl_mat_alloc(ctx, 3, dim); + if (!T) + goto error; + isl_int_set_si(T->row[0][0], 1); + isl_seq_clr(T->row[0]+1, dim - 1); + isl_seq_cpy(T->row[1], facet, dim); + isl_seq_cpy(T->row[2], ridge, dim); + T = isl_mat_right_inverse(T); + set = isl_set_preimage(set, T); + T = NULL; + if (!set) + goto error; + lp = wrap_constraints(set); + obj = isl_vec_alloc(ctx, 1 + dim*set->n); + if (!obj) + goto error; + isl_int_set_si(obj->block.data[0], 0); + for (i = 0; i < set->n; ++i) { + isl_seq_clr(obj->block.data + 1 + dim*i, 2); + isl_int_set_si(obj->block.data[1 + dim*i+2], 1); + isl_seq_clr(obj->block.data + 1 + dim*i+3, dim-3); + } + isl_int_init(num); + isl_int_init(den); + res = isl_basic_set_solve_lp(lp, 0, + obj->block.data, ctx->one, &num, &den, NULL); + if (res == isl_lp_ok) { + isl_int_neg(num, num); + isl_seq_combine(facet, num, facet, den, ridge, dim); + isl_seq_normalize(ctx, facet, dim); + } + isl_int_clear(num); + isl_int_clear(den); + isl_vec_free(obj); + isl_basic_set_free(lp); + isl_set_free(set); + if (res == isl_lp_error) + return NULL; + isl_assert(ctx, res == isl_lp_ok || res == isl_lp_unbounded, + return NULL); + return facet; +error: + isl_basic_set_free(lp); + isl_mat_free(T); + isl_set_free(set); + return NULL; +} + +/* Compute the constraint of a facet of "set". + * + * We first compute the intersection with a bounding constraint + * that is orthogonal to one of the coordinate axes. + * If the affine hull of this intersection has only one equality, + * we have found a facet. + * Otherwise, we wrap the current bounding constraint around + * one of the equalities of the face (one that is not equal to + * the current bounding constraint). + * This process continues until we have found a facet. + * The dimension of the intersection increases by at least + * one on each iteration, so termination is guaranteed. + */ +static __isl_give isl_mat *initial_facet_constraint(__isl_keep isl_set *set) +{ + struct isl_set *slice = NULL; + struct isl_basic_set *face = NULL; + int i; + isl_size dim = isl_set_dim(set, isl_dim_set); + isl_bool is_bound; + isl_mat *bounds = NULL; + + if (dim < 0) + return NULL; + isl_assert(set->ctx, set->n > 0, goto error); + bounds = isl_mat_alloc(set->ctx, 1, 1 + dim); + if (!bounds) + return NULL; + + isl_seq_clr(bounds->row[0], dim); + isl_int_set_si(bounds->row[0][1 + dim - 1], 1); + is_bound = uset_is_bound(set, bounds->row[0], 1 + dim); + if (is_bound < 0) + goto error; + isl_assert(set->ctx, is_bound, goto error); + isl_seq_normalize(set->ctx, bounds->row[0], 1 + dim); + bounds->n_row = 1; + + for (;;) { + slice = isl_set_copy(set); + slice = isl_set_add_basic_set_equality(slice, bounds->row[0]); + face = isl_set_affine_hull(slice); + if (!face) + goto error; + if (face->n_eq == 1) { + isl_basic_set_free(face); + break; + } + for (i = 0; i < face->n_eq; ++i) + if (!isl_seq_eq(bounds->row[0], face->eq[i], 1 + dim) && + !isl_seq_is_neg(bounds->row[0], + face->eq[i], 1 + dim)) + break; + isl_assert(set->ctx, i < face->n_eq, goto error); + if (!isl_set_wrap_facet(set, bounds->row[0], face->eq[i])) + goto error; + isl_seq_normalize(set->ctx, bounds->row[0], bounds->n_col); + isl_basic_set_free(face); + } + + return bounds; +error: + isl_basic_set_free(face); + isl_mat_free(bounds); + return NULL; +} + +/* Given the bounding constraint "c" of a facet of the convex hull of "set", + * compute a hyperplane description of the facet, i.e., compute the facets + * of the facet. + * + * We compute an affine transformation that transforms the constraint + * + * [ 1 ] + * c [ x ] = 0 + * + * to the constraint + * + * z_1 = 0 + * + * by computing the right inverse U of a matrix that starts with the rows + * + * [ 1 0 ] + * [ c ] + * + * Then + * [ 1 ] [ 1 ] + * [ x ] = U [ z ] + * and + * [ 1 ] [ 1 ] + * [ z ] = Q [ x ] + * + * with Q = U^{-1} + * Since z_1 is zero, we can drop this variable as well as the corresponding + * column of U to obtain + * + * [ 1 ] [ 1 ] + * [ x ] = U' [ z' ] + * and + * [ 1 ] [ 1 ] + * [ z' ] = Q' [ x ] + * + * with Q' equal to Q, but without the corresponding row. + * After computing the facets of the facet in the z' space, + * we convert them back to the x space through Q. + */ +static __isl_give isl_basic_set *compute_facet(__isl_keep isl_set *set, + isl_int *c) +{ + struct isl_mat *m, *U, *Q; + struct isl_basic_set *facet = NULL; + struct isl_ctx *ctx; + isl_size dim; + + dim = isl_set_dim(set, isl_dim_set); + if (dim < 0) + return NULL; + ctx = set->ctx; + set = isl_set_copy(set); + m = isl_mat_alloc(set->ctx, 2, 1 + dim); + if (!m) + goto error; + isl_int_set_si(m->row[0][0], 1); + isl_seq_clr(m->row[0]+1, dim); + isl_seq_cpy(m->row[1], c, 1+dim); + U = isl_mat_right_inverse(m); + Q = isl_mat_right_inverse(isl_mat_copy(U)); + U = isl_mat_drop_cols(U, 1, 1); + Q = isl_mat_drop_rows(Q, 1, 1); + set = isl_set_preimage(set, U); + facet = uset_convex_hull_wrap_bounded(set); + facet = isl_basic_set_preimage(facet, Q); + if (facet && facet->n_eq != 0) + isl_die(ctx, isl_error_internal, "unexpected equality", + return isl_basic_set_free(facet)); + return facet; +error: + isl_basic_set_free(facet); + isl_set_free(set); + return NULL; +} + +/* Given an initial facet constraint, compute the remaining facets. + * We do this by running through all facets found so far and computing + * the adjacent facets through wrapping, adding those facets that we + * hadn't already found before. + * + * For each facet we have found so far, we first compute its facets + * in the resulting convex hull. That is, we compute the ridges + * of the resulting convex hull contained in the facet. + * We also compute the corresponding facet in the current approximation + * of the convex hull. There is no need to wrap around the ridges + * in this facet since that would result in a facet that is already + * present in the current approximation. + * + * This function can still be significantly optimized by checking which of + * the facets of the basic sets are also facets of the convex hull and + * using all the facets so far to help in constructing the facets of the + * facets + * and/or + * using the technique in section "3.1 Ridge Generation" of + * "Extended Convex Hull" by Fukuda et al. + */ +static __isl_give isl_basic_set *extend(__isl_take isl_basic_set *hull, + __isl_keep isl_set *set) +{ + int i, j, f; + int k; + struct isl_basic_set *facet = NULL; + struct isl_basic_set *hull_facet = NULL; + isl_size dim; + + dim = isl_set_dim(set, isl_dim_set); + if (dim < 0 || !hull) + return isl_basic_set_free(hull); + + isl_assert(set->ctx, set->n > 0, goto error); + + for (i = 0; i < hull->n_ineq; ++i) { + facet = compute_facet(set, hull->ineq[i]); + facet = isl_basic_set_add_eq(facet, hull->ineq[i]); + facet = isl_basic_set_gauss(facet, NULL); + facet = isl_basic_set_normalize_constraints(facet); + hull_facet = isl_basic_set_copy(hull); + hull_facet = isl_basic_set_add_eq(hull_facet, hull->ineq[i]); + hull_facet = isl_basic_set_gauss(hull_facet, NULL); + hull_facet = isl_basic_set_normalize_constraints(hull_facet); + if (!facet || !hull_facet) + goto error; + hull = isl_basic_set_cow(hull); + hull = isl_basic_set_extend(hull, 0, 0, facet->n_ineq); + if (!hull) + goto error; + for (j = 0; j < facet->n_ineq; ++j) { + for (f = 0; f < hull_facet->n_ineq; ++f) + if (isl_seq_eq(facet->ineq[j], + hull_facet->ineq[f], 1 + dim)) + break; + if (f < hull_facet->n_ineq) + continue; + k = isl_basic_set_alloc_inequality(hull); + if (k < 0) + goto error; + isl_seq_cpy(hull->ineq[k], hull->ineq[i], 1+dim); + if (!isl_set_wrap_facet(set, hull->ineq[k], facet->ineq[j])) + goto error; + } + isl_basic_set_free(hull_facet); + isl_basic_set_free(facet); + } + hull = isl_basic_set_simplify(hull); + hull = isl_basic_set_finalize(hull); + return hull; +error: + isl_basic_set_free(hull_facet); + isl_basic_set_free(facet); + isl_basic_set_free(hull); + return NULL; +} + +/* Special case for computing the convex hull of a one dimensional set. + * We simply collect the lower and upper bounds of each basic set + * and the biggest of those. + */ +static __isl_give isl_basic_set *convex_hull_1d(__isl_take isl_set *set) +{ + struct isl_mat *c = NULL; + isl_int *lower = NULL; + isl_int *upper = NULL; + int i, j, k; + isl_int a, b; + struct isl_basic_set *hull; + + for (i = 0; i < set->n; ++i) { + set->p[i] = isl_basic_set_simplify(set->p[i]); + if (!set->p[i]) + goto error; + } + set = isl_set_remove_empty_parts(set); + if (!set) + goto error; + isl_assert(set->ctx, set->n > 0, goto error); + c = isl_mat_alloc(set->ctx, 2, 2); + if (!c) + goto error; + + if (set->p[0]->n_eq > 0) { + isl_assert(set->ctx, set->p[0]->n_eq == 1, goto error); + lower = c->row[0]; + upper = c->row[1]; + if (isl_int_is_pos(set->p[0]->eq[0][1])) { + isl_seq_cpy(lower, set->p[0]->eq[0], 2); + isl_seq_neg(upper, set->p[0]->eq[0], 2); + } else { + isl_seq_neg(lower, set->p[0]->eq[0], 2); + isl_seq_cpy(upper, set->p[0]->eq[0], 2); + } + } else { + for (j = 0; j < set->p[0]->n_ineq; ++j) { + if (isl_int_is_pos(set->p[0]->ineq[j][1])) { + lower = c->row[0]; + isl_seq_cpy(lower, set->p[0]->ineq[j], 2); + } else { + upper = c->row[1]; + isl_seq_cpy(upper, set->p[0]->ineq[j], 2); + } + } + } + + isl_int_init(a); + isl_int_init(b); + for (i = 0; i < set->n; ++i) { + struct isl_basic_set *bset = set->p[i]; + int has_lower = 0; + int has_upper = 0; + + for (j = 0; j < bset->n_eq; ++j) { + has_lower = 1; + has_upper = 1; + if (lower) { + isl_int_mul(a, lower[0], bset->eq[j][1]); + isl_int_mul(b, lower[1], bset->eq[j][0]); + if (isl_int_lt(a, b) && isl_int_is_pos(bset->eq[j][1])) + isl_seq_cpy(lower, bset->eq[j], 2); + if (isl_int_gt(a, b) && isl_int_is_neg(bset->eq[j][1])) + isl_seq_neg(lower, bset->eq[j], 2); + } + if (upper) { + isl_int_mul(a, upper[0], bset->eq[j][1]); + isl_int_mul(b, upper[1], bset->eq[j][0]); + if (isl_int_lt(a, b) && isl_int_is_pos(bset->eq[j][1])) + isl_seq_neg(upper, bset->eq[j], 2); + if (isl_int_gt(a, b) && isl_int_is_neg(bset->eq[j][1])) + isl_seq_cpy(upper, bset->eq[j], 2); + } + } + for (j = 0; j < bset->n_ineq; ++j) { + if (isl_int_is_pos(bset->ineq[j][1])) + has_lower = 1; + if (isl_int_is_neg(bset->ineq[j][1])) + has_upper = 1; + if (lower && isl_int_is_pos(bset->ineq[j][1])) { + isl_int_mul(a, lower[0], bset->ineq[j][1]); + isl_int_mul(b, lower[1], bset->ineq[j][0]); + if (isl_int_lt(a, b)) + isl_seq_cpy(lower, bset->ineq[j], 2); + } + if (upper && isl_int_is_neg(bset->ineq[j][1])) { + isl_int_mul(a, upper[0], bset->ineq[j][1]); + isl_int_mul(b, upper[1], bset->ineq[j][0]); + if (isl_int_gt(a, b)) + isl_seq_cpy(upper, bset->ineq[j], 2); + } + } + if (!has_lower) + lower = NULL; + if (!has_upper) + upper = NULL; + } + isl_int_clear(a); + isl_int_clear(b); + + hull = isl_basic_set_alloc(set->ctx, 0, 1, 0, 0, 2); + hull = isl_basic_set_set_rational(hull); + if (!hull) + goto error; + if (lower) { + k = isl_basic_set_alloc_inequality(hull); + isl_seq_cpy(hull->ineq[k], lower, 2); + } + if (upper) { + k = isl_basic_set_alloc_inequality(hull); + isl_seq_cpy(hull->ineq[k], upper, 2); + } + hull = isl_basic_set_finalize(hull); + isl_set_free(set); + isl_mat_free(c); + return hull; +error: + isl_set_free(set); + isl_mat_free(c); + return NULL; +} + +static __isl_give isl_basic_set *convex_hull_0d(__isl_take isl_set *set) +{ + struct isl_basic_set *convex_hull; + + if (!set) + return NULL; + + if (isl_set_is_empty(set)) + convex_hull = isl_basic_set_empty(isl_space_copy(set->dim)); + else + convex_hull = isl_basic_set_universe(isl_space_copy(set->dim)); + isl_set_free(set); + return convex_hull; +} + +/* Compute the convex hull of a pair of basic sets without any parameters or + * integer divisions using Fourier-Motzkin elimination. + * The convex hull is the set of all points that can be written as + * the sum of points from both basic sets (in homogeneous coordinates). + * We set up the constraints in a space with dimensions for each of + * the three sets and then project out the dimensions corresponding + * to the two original basic sets, retaining only those corresponding + * to the convex hull. + */ +static __isl_give isl_basic_set *convex_hull_pair_elim( + __isl_take isl_basic_set *bset1, __isl_take isl_basic_set *bset2) +{ + int i, j, k; + struct isl_basic_set *bset[2]; + struct isl_basic_set *hull = NULL; + isl_size dim; + + dim = isl_basic_set_dim(bset1, isl_dim_set); + if (dim < 0 || !bset2) + goto error; + + hull = isl_basic_set_alloc(bset1->ctx, 0, 2 + 3 * dim, 0, + 1 + dim + bset1->n_eq + bset2->n_eq, + 2 + bset1->n_ineq + bset2->n_ineq); + bset[0] = bset1; + bset[1] = bset2; + for (i = 0; i < 2; ++i) { + for (j = 0; j < bset[i]->n_eq; ++j) { + k = isl_basic_set_alloc_equality(hull); + if (k < 0) + goto error; + isl_seq_clr(hull->eq[k], (i+1) * (1+dim)); + isl_seq_clr(hull->eq[k]+(i+2)*(1+dim), (1-i)*(1+dim)); + isl_seq_cpy(hull->eq[k]+(i+1)*(1+dim), bset[i]->eq[j], + 1+dim); + } + for (j = 0; j < bset[i]->n_ineq; ++j) { + k = isl_basic_set_alloc_inequality(hull); + if (k < 0) + goto error; + isl_seq_clr(hull->ineq[k], (i+1) * (1+dim)); + isl_seq_clr(hull->ineq[k]+(i+2)*(1+dim), (1-i)*(1+dim)); + isl_seq_cpy(hull->ineq[k]+(i+1)*(1+dim), + bset[i]->ineq[j], 1+dim); + } + k = isl_basic_set_alloc_inequality(hull); + if (k < 0) + goto error; + isl_seq_clr(hull->ineq[k], 1+2+3*dim); + isl_int_set_si(hull->ineq[k][(i+1)*(1+dim)], 1); + } + for (j = 0; j < 1+dim; ++j) { + k = isl_basic_set_alloc_equality(hull); + if (k < 0) + goto error; + isl_seq_clr(hull->eq[k], 1+2+3*dim); + isl_int_set_si(hull->eq[k][j], -1); + isl_int_set_si(hull->eq[k][1+dim+j], 1); + isl_int_set_si(hull->eq[k][2*(1+dim)+j], 1); + } + hull = isl_basic_set_set_rational(hull); + hull = isl_basic_set_remove_dims(hull, isl_dim_set, dim, 2*(1+dim)); + hull = isl_basic_set_remove_redundancies(hull); + isl_basic_set_free(bset1); + isl_basic_set_free(bset2); + return hull; +error: + isl_basic_set_free(bset1); + isl_basic_set_free(bset2); + isl_basic_set_free(hull); + return NULL; +} + +/* Is the set bounded for each value of the parameters? + */ +isl_bool isl_basic_set_is_bounded(__isl_keep isl_basic_set *bset) +{ + struct isl_tab *tab; + isl_bool bounded; + + if (!bset) + return isl_bool_error; + if (isl_basic_set_plain_is_empty(bset)) + return isl_bool_true; + + tab = isl_tab_from_recession_cone(bset, 1); + bounded = isl_tab_cone_is_bounded(tab); + isl_tab_free(tab); + return bounded; +} + +/* Is the image bounded for each value of the parameters and + * the domain variables? + */ +isl_bool isl_basic_map_image_is_bounded(__isl_keep isl_basic_map *bmap) +{ + isl_size nparam = isl_basic_map_dim(bmap, isl_dim_param); + isl_size n_in = isl_basic_map_dim(bmap, isl_dim_in); + isl_bool bounded; + + if (nparam < 0 || n_in < 0) + return isl_bool_error; + + bmap = isl_basic_map_copy(bmap); + bmap = isl_basic_map_cow(bmap); + bmap = isl_basic_map_move_dims(bmap, isl_dim_param, nparam, + isl_dim_in, 0, n_in); + bounded = isl_basic_set_is_bounded(bset_from_bmap(bmap)); + isl_basic_map_free(bmap); + + return bounded; +} + +/* Is the set bounded for each value of the parameters? + */ +isl_bool isl_set_is_bounded(__isl_keep isl_set *set) +{ + int i; + + if (!set) + return isl_bool_error; + + for (i = 0; i < set->n; ++i) { + isl_bool bounded = isl_basic_set_is_bounded(set->p[i]); + if (!bounded || bounded < 0) + return bounded; + } + return isl_bool_true; +} + +/* Compute the lineality space of the convex hull of bset1 and bset2. + * + * We first compute the intersection of the recession cone of bset1 + * with the negative of the recession cone of bset2 and then compute + * the linear hull of the resulting cone. + */ +static __isl_give isl_basic_set *induced_lineality_space( + __isl_take isl_basic_set *bset1, __isl_take isl_basic_set *bset2) +{ + int i, k; + struct isl_basic_set *lin = NULL; + isl_size dim; + + dim = isl_basic_set_dim(bset1, isl_dim_all); + if (dim < 0 || !bset2) + goto error; + + lin = isl_basic_set_alloc_space(isl_basic_set_get_space(bset1), 0, + bset1->n_eq + bset2->n_eq, + bset1->n_ineq + bset2->n_ineq); + lin = isl_basic_set_set_rational(lin); + if (!lin) + goto error; + for (i = 0; i < bset1->n_eq; ++i) { + k = isl_basic_set_alloc_equality(lin); + if (k < 0) + goto error; + isl_int_set_si(lin->eq[k][0], 0); + isl_seq_cpy(lin->eq[k] + 1, bset1->eq[i] + 1, dim); + } + for (i = 0; i < bset1->n_ineq; ++i) { + k = isl_basic_set_alloc_inequality(lin); + if (k < 0) + goto error; + isl_int_set_si(lin->ineq[k][0], 0); + isl_seq_cpy(lin->ineq[k] + 1, bset1->ineq[i] + 1, dim); + } + for (i = 0; i < bset2->n_eq; ++i) { + k = isl_basic_set_alloc_equality(lin); + if (k < 0) + goto error; + isl_int_set_si(lin->eq[k][0], 0); + isl_seq_neg(lin->eq[k] + 1, bset2->eq[i] + 1, dim); + } + for (i = 0; i < bset2->n_ineq; ++i) { + k = isl_basic_set_alloc_inequality(lin); + if (k < 0) + goto error; + isl_int_set_si(lin->ineq[k][0], 0); + isl_seq_neg(lin->ineq[k] + 1, bset2->ineq[i] + 1, dim); + } + + isl_basic_set_free(bset1); + isl_basic_set_free(bset2); + return isl_basic_set_affine_hull(lin); +error: + isl_basic_set_free(lin); + isl_basic_set_free(bset1); + isl_basic_set_free(bset2); + return NULL; +} + +static __isl_give isl_basic_set *uset_convex_hull(__isl_take isl_set *set); + +/* Given a set and a linear space "lin" of dimension n > 0, + * project the linear space from the set, compute the convex hull + * and then map the set back to the original space. + * + * Let + * + * M x = 0 + * + * describe the linear space. We first compute the Hermite normal + * form H = M U of M = H Q, to obtain + * + * H Q x = 0 + * + * The last n rows of H will be zero, so the last n variables of x' = Q x + * are the one we want to project out. We do this by transforming each + * basic set A x >= b to A U x' >= b and then removing the last n dimensions. + * After computing the convex hull in x'_1, i.e., A' x'_1 >= b', + * we transform the hull back to the original space as A' Q_1 x >= b', + * with Q_1 all but the last n rows of Q. + */ +static __isl_give isl_basic_set *modulo_lineality(__isl_take isl_set *set, + __isl_take isl_basic_set *lin) +{ + isl_size total = isl_basic_set_dim(lin, isl_dim_all); + unsigned lin_dim; + struct isl_basic_set *hull; + struct isl_mat *M, *U, *Q; + + if (!set || total < 0) + goto error; + lin_dim = total - lin->n_eq; + M = isl_mat_sub_alloc6(set->ctx, lin->eq, 0, lin->n_eq, 1, total); + M = isl_mat_left_hermite(M, 0, &U, &Q); + if (!M) + goto error; + isl_mat_free(M); + isl_basic_set_free(lin); + + Q = isl_mat_drop_rows(Q, Q->n_row - lin_dim, lin_dim); + + U = isl_mat_lin_to_aff(U); + Q = isl_mat_lin_to_aff(Q); + + set = isl_set_preimage(set, U); + set = isl_set_remove_dims(set, isl_dim_set, total - lin_dim, lin_dim); + hull = uset_convex_hull(set); + hull = isl_basic_set_preimage(hull, Q); + + return hull; +error: + isl_basic_set_free(lin); + isl_set_free(set); + return NULL; +} + +/* Given two polyhedra with as constraints h_{ij} x >= 0 in homegeneous space, + * set up an LP for solving + * + * \sum_j \alpha_{1j} h_{1j} = \sum_j \alpha_{2j} h_{2j} + * + * \alpha{i0} corresponds to the (implicit) positivity constraint 1 >= 0 + * The next \alpha{ij} correspond to the equalities and come in pairs. + * The final \alpha{ij} correspond to the inequalities. + */ +static __isl_give isl_basic_set *valid_direction_lp( + __isl_take isl_basic_set *bset1, __isl_take isl_basic_set *bset2) +{ + isl_space *space; + struct isl_basic_set *lp; + unsigned d; + int n; + int i, j, k; + isl_size total; + + total = isl_basic_set_dim(bset1, isl_dim_all); + if (total < 0 || !bset2) + goto error; + d = 1 + total; + n = 2 + + 2 * bset1->n_eq + bset1->n_ineq + 2 * bset2->n_eq + bset2->n_ineq; + space = isl_space_set_alloc(bset1->ctx, 0, n); + lp = isl_basic_set_alloc_space(space, 0, d, n); + if (!lp) + goto error; + for (i = 0; i < n; ++i) { + k = isl_basic_set_alloc_inequality(lp); + if (k < 0) + goto error; + isl_seq_clr(lp->ineq[k] + 1, n); + isl_int_set_si(lp->ineq[k][0], -1); + isl_int_set_si(lp->ineq[k][1 + i], 1); + } + for (i = 0; i < d; ++i) { + k = isl_basic_set_alloc_equality(lp); + if (k < 0) + goto error; + n = 0; + isl_int_set_si(lp->eq[k][n], 0); n++; + /* positivity constraint 1 >= 0 */ + isl_int_set_si(lp->eq[k][n], i == 0); n++; + for (j = 0; j < bset1->n_eq; ++j) { + isl_int_set(lp->eq[k][n], bset1->eq[j][i]); n++; + isl_int_neg(lp->eq[k][n], bset1->eq[j][i]); n++; + } + for (j = 0; j < bset1->n_ineq; ++j) { + isl_int_set(lp->eq[k][n], bset1->ineq[j][i]); n++; + } + /* positivity constraint 1 >= 0 */ + isl_int_set_si(lp->eq[k][n], -(i == 0)); n++; + for (j = 0; j < bset2->n_eq; ++j) { + isl_int_neg(lp->eq[k][n], bset2->eq[j][i]); n++; + isl_int_set(lp->eq[k][n], bset2->eq[j][i]); n++; + } + for (j = 0; j < bset2->n_ineq; ++j) { + isl_int_neg(lp->eq[k][n], bset2->ineq[j][i]); n++; + } + } + lp = isl_basic_set_gauss(lp, NULL); + isl_basic_set_free(bset1); + isl_basic_set_free(bset2); + return lp; +error: + isl_basic_set_free(bset1); + isl_basic_set_free(bset2); + return NULL; +} + +/* Compute a vector s in the homogeneous space such that > 0 + * for all rays in the homogeneous space of the two cones that correspond + * to the input polyhedra bset1 and bset2. + * + * We compute s as a vector that satisfies + * + * s = \sum_j \alpha_{ij} h_{ij} for i = 1,2 (*) + * + * with h_{ij} the normals of the facets of polyhedron i + * (including the "positivity constraint" 1 >= 0) and \alpha_{ij} + * strictly positive numbers. For simplicity we impose \alpha_{ij} >= 1. + * We first set up an LP with as variables the \alpha{ij}. + * In this formulation, for each polyhedron i, + * the first constraint is the positivity constraint, followed by pairs + * of variables for the equalities, followed by variables for the inequalities. + * We then simply pick a feasible solution and compute s using (*). + * + * Note that we simply pick any valid direction and make no attempt + * to pick a "good" or even the "best" valid direction. + */ +static __isl_give isl_vec *valid_direction( + __isl_take isl_basic_set *bset1, __isl_take isl_basic_set *bset2) +{ + struct isl_basic_set *lp; + struct isl_tab *tab; + struct isl_vec *sample = NULL; + struct isl_vec *dir; + isl_size d; + int i; + int n; + + if (!bset1 || !bset2) + goto error; + lp = valid_direction_lp(isl_basic_set_copy(bset1), + isl_basic_set_copy(bset2)); + tab = isl_tab_from_basic_set(lp, 0); + sample = isl_tab_get_sample_value(tab); + isl_tab_free(tab); + isl_basic_set_free(lp); + if (!sample) + goto error; + d = isl_basic_set_dim(bset1, isl_dim_all); + if (d < 0) + goto error; + dir = isl_vec_alloc(bset1->ctx, 1 + d); + if (!dir) + goto error; + isl_seq_clr(dir->block.data + 1, dir->size - 1); + n = 1; + /* positivity constraint 1 >= 0 */ + isl_int_set(dir->block.data[0], sample->block.data[n]); n++; + for (i = 0; i < bset1->n_eq; ++i) { + isl_int_sub(sample->block.data[n], + sample->block.data[n], sample->block.data[n+1]); + isl_seq_combine(dir->block.data, + bset1->ctx->one, dir->block.data, + sample->block.data[n], bset1->eq[i], 1 + d); + + n += 2; + } + for (i = 0; i < bset1->n_ineq; ++i) + isl_seq_combine(dir->block.data, + bset1->ctx->one, dir->block.data, + sample->block.data[n++], bset1->ineq[i], 1 + d); + isl_vec_free(sample); + isl_seq_normalize(bset1->ctx, dir->el, dir->size); + isl_basic_set_free(bset1); + isl_basic_set_free(bset2); + return dir; +error: + isl_vec_free(sample); + isl_basic_set_free(bset1); + isl_basic_set_free(bset2); + return NULL; +} + +/* Given a polyhedron b_i + A_i x >= 0 and a map T = S^{-1}, + * compute b_i' + A_i' x' >= 0, with + * + * [ b_i A_i ] [ y' ] [ y' ] + * [ 1 0 ] S^{-1} [ x' ] >= 0 or [ b_i' A_i' ] [ x' ] >= 0 + * + * In particular, add the "positivity constraint" and then perform + * the mapping. + */ +static __isl_give isl_basic_set *homogeneous_map(__isl_take isl_basic_set *bset, + __isl_take isl_mat *T) +{ + int k; + isl_size total; + + total = isl_basic_set_dim(bset, isl_dim_all); + if (total < 0) + goto error; + bset = isl_basic_set_extend_constraints(bset, 0, 1); + k = isl_basic_set_alloc_inequality(bset); + if (k < 0) + goto error; + isl_seq_clr(bset->ineq[k] + 1, total); + isl_int_set_si(bset->ineq[k][0], 1); + bset = isl_basic_set_preimage(bset, T); + return bset; +error: + isl_mat_free(T); + isl_basic_set_free(bset); + return NULL; +} + +/* Compute the convex hull of a pair of basic sets without any parameters or + * integer divisions, where the convex hull is known to be pointed, + * but the basic sets may be unbounded. + * + * We turn this problem into the computation of a convex hull of a pair + * _bounded_ polyhedra by "changing the direction of the homogeneous + * dimension". This idea is due to Matthias Koeppe. + * + * Consider the cones in homogeneous space that correspond to the + * input polyhedra. The rays of these cones are also rays of the + * polyhedra if the coordinate that corresponds to the homogeneous + * dimension is zero. That is, if the inner product of the rays + * with the homogeneous direction is zero. + * The cones in the homogeneous space can also be considered to + * correspond to other pairs of polyhedra by chosing a different + * homogeneous direction. To ensure that both of these polyhedra + * are bounded, we need to make sure that all rays of the cones + * correspond to vertices and not to rays. + * Let s be a direction such that > 0 for all rays r of both cones. + * Then using s as a homogeneous direction, we obtain a pair of polytopes. + * The vector s is computed in valid_direction. + * + * Note that we need to consider _all_ rays of the cones and not just + * the rays that correspond to rays in the polyhedra. If we were to + * only consider those rays and turn them into vertices, then we + * may inadvertently turn some vertices into rays. + * + * The standard homogeneous direction is the unit vector in the 0th coordinate. + * We therefore transform the two polyhedra such that the selected + * direction is mapped onto this standard direction and then proceed + * with the normal computation. + * Let S be a non-singular square matrix with s as its first row, + * then we want to map the polyhedra to the space + * + * [ y' ] [ y ] [ y ] [ y' ] + * [ x' ] = S [ x ] i.e., [ x ] = S^{-1} [ x' ] + * + * We take S to be the unimodular completion of s to limit the growth + * of the coefficients in the following computations. + * + * Let b_i + A_i x >= 0 be the constraints of polyhedron i. + * We first move to the homogeneous dimension + * + * b_i y + A_i x >= 0 [ b_i A_i ] [ y ] [ 0 ] + * y >= 0 or [ 1 0 ] [ x ] >= [ 0 ] + * + * Then we change directoin + * + * [ b_i A_i ] [ y' ] [ y' ] + * [ 1 0 ] S^{-1} [ x' ] >= 0 or [ b_i' A_i' ] [ x' ] >= 0 + * + * Then we compute the convex hull of the polytopes b_i' + A_i' x' >= 0 + * resulting in b' + A' x' >= 0, which we then convert back + * + * [ y ] [ y ] + * [ b' A' ] S [ x ] >= 0 or [ b A ] [ x ] >= 0 + * + * The polyhedron b + A x >= 0 is then the convex hull of the input polyhedra. + */ +static __isl_give isl_basic_set *convex_hull_pair_pointed( + __isl_take isl_basic_set *bset1, __isl_take isl_basic_set *bset2) +{ + struct isl_ctx *ctx = NULL; + struct isl_vec *dir = NULL; + struct isl_mat *T = NULL; + struct isl_mat *T2 = NULL; + struct isl_basic_set *hull; + struct isl_set *set; + + if (!bset1 || !bset2) + goto error; + ctx = isl_basic_set_get_ctx(bset1); + dir = valid_direction(isl_basic_set_copy(bset1), + isl_basic_set_copy(bset2)); + if (!dir) + goto error; + T = isl_mat_alloc(ctx, dir->size, dir->size); + if (!T) + goto error; + isl_seq_cpy(T->row[0], dir->block.data, dir->size); + T = isl_mat_unimodular_complete(T, 1); + T2 = isl_mat_right_inverse(isl_mat_copy(T)); + + bset1 = homogeneous_map(bset1, isl_mat_copy(T2)); + bset2 = homogeneous_map(bset2, T2); + set = isl_set_alloc_space(isl_basic_set_get_space(bset1), 2, 0); + set = isl_set_add_basic_set(set, bset1); + set = isl_set_add_basic_set(set, bset2); + hull = uset_convex_hull(set); + hull = isl_basic_set_preimage(hull, T); + + isl_vec_free(dir); + + return hull; +error: + isl_vec_free(dir); + isl_basic_set_free(bset1); + isl_basic_set_free(bset2); + return NULL; +} + +static __isl_give isl_basic_set *uset_convex_hull_wrap(__isl_take isl_set *set); +static __isl_give isl_basic_set *modulo_affine_hull( + __isl_take isl_set *set, __isl_take isl_basic_set *affine_hull); + +/* Compute the convex hull of a pair of basic sets without any parameters or + * integer divisions. + * + * This function is called from uset_convex_hull_unbounded, which + * means that the complete convex hull is unbounded. Some pairs + * of basic sets may still be bounded, though. + * They may even lie inside a lower dimensional space, in which + * case they need to be handled inside their affine hull since + * the main algorithm assumes that the result is full-dimensional. + * + * If the convex hull of the two basic sets would have a non-trivial + * lineality space, we first project out this lineality space. + */ +static __isl_give isl_basic_set *convex_hull_pair( + __isl_take isl_basic_set *bset1, __isl_take isl_basic_set *bset2) +{ + isl_basic_set *lin, *aff; + isl_bool bounded1, bounded2; + isl_size total; + + if (bset1->ctx->opt->convex == ISL_CONVEX_HULL_FM) + return convex_hull_pair_elim(bset1, bset2); + + aff = isl_set_affine_hull(isl_basic_set_union(isl_basic_set_copy(bset1), + isl_basic_set_copy(bset2))); + if (!aff) + goto error; + if (aff->n_eq != 0) + return modulo_affine_hull(isl_basic_set_union(bset1, bset2), aff); + isl_basic_set_free(aff); + + bounded1 = isl_basic_set_is_bounded(bset1); + bounded2 = isl_basic_set_is_bounded(bset2); + + if (bounded1 < 0 || bounded2 < 0) + goto error; + + if (bounded1 && bounded2) + return uset_convex_hull_wrap(isl_basic_set_union(bset1, bset2)); + + if (bounded1 || bounded2) + return convex_hull_pair_pointed(bset1, bset2); + + lin = induced_lineality_space(isl_basic_set_copy(bset1), + isl_basic_set_copy(bset2)); + if (!lin) + goto error; + if (isl_basic_set_plain_is_universe(lin)) { + isl_basic_set_free(bset1); + isl_basic_set_free(bset2); + return lin; + } + total = isl_basic_set_dim(lin, isl_dim_all); + if (lin->n_eq < total) { + struct isl_set *set; + set = isl_set_alloc_space(isl_basic_set_get_space(bset1), 2, 0); + set = isl_set_add_basic_set(set, bset1); + set = isl_set_add_basic_set(set, bset2); + return modulo_lineality(set, lin); + } + isl_basic_set_free(lin); + if (total < 0) + goto error; + + return convex_hull_pair_pointed(bset1, bset2); +error: + isl_basic_set_free(bset1); + isl_basic_set_free(bset2); + return NULL; +} + +/* Compute the lineality space of a basic set. + * We basically just drop the constants and turn every inequality + * into an equality. + * Any explicit representations of local variables are removed + * because they may no longer be valid representations + * in the lineality space. + */ +__isl_give isl_basic_set *isl_basic_set_lineality_space( + __isl_take isl_basic_set *bset) +{ + int i, k; + struct isl_basic_set *lin = NULL; + isl_size n_div, dim; + + n_div = isl_basic_set_dim(bset, isl_dim_div); + dim = isl_basic_set_dim(bset, isl_dim_all); + if (n_div < 0 || dim < 0) + return isl_basic_set_free(bset); + + lin = isl_basic_set_alloc_space(isl_basic_set_get_space(bset), + n_div, dim, 0); + for (i = 0; i < n_div; ++i) + if (isl_basic_set_alloc_div(lin) < 0) + goto error; + if (!lin) + goto error; + for (i = 0; i < bset->n_eq; ++i) { + k = isl_basic_set_alloc_equality(lin); + if (k < 0) + goto error; + isl_int_set_si(lin->eq[k][0], 0); + isl_seq_cpy(lin->eq[k] + 1, bset->eq[i] + 1, dim); + } + lin = isl_basic_set_gauss(lin, NULL); + if (!lin) + goto error; + for (i = 0; i < bset->n_ineq && lin->n_eq < dim; ++i) { + k = isl_basic_set_alloc_equality(lin); + if (k < 0) + goto error; + isl_int_set_si(lin->eq[k][0], 0); + isl_seq_cpy(lin->eq[k] + 1, bset->ineq[i] + 1, dim); + lin = isl_basic_set_gauss(lin, NULL); + if (!lin) + goto error; + } + isl_basic_set_free(bset); + return lin; +error: + isl_basic_set_free(lin); + isl_basic_set_free(bset); + return NULL; +} + +/* Compute the (linear) hull of the lineality spaces of the basic sets in the + * set "set". + */ +__isl_give isl_basic_set *isl_set_combined_lineality_space( + __isl_take isl_set *set) +{ + int i; + struct isl_set *lin = NULL; + + if (!set) + return NULL; + if (set->n == 0) { + isl_space *space = isl_set_get_space(set); + isl_set_free(set); + return isl_basic_set_empty(space); + } + + lin = isl_set_alloc_space(isl_set_get_space(set), set->n, 0); + for (i = 0; i < set->n; ++i) + lin = isl_set_add_basic_set(lin, + isl_basic_set_lineality_space(isl_basic_set_copy(set->p[i]))); + isl_set_free(set); + return isl_set_affine_hull(lin); +} + +/* Compute the convex hull of a set without any parameters or + * integer divisions. + * In each step, we combined two basic sets until only one + * basic set is left. + * The input basic sets are assumed not to have a non-trivial + * lineality space. If any of the intermediate results has + * a non-trivial lineality space, it is projected out. + */ +static __isl_give isl_basic_set *uset_convex_hull_unbounded( + __isl_take isl_set *set) +{ + isl_basic_set_list *list; + + list = isl_set_get_basic_set_list(set); + isl_set_free(set); + + while (list) { + isl_size n, total; + struct isl_basic_set *t; + isl_basic_set *bset1, *bset2; + + n = isl_basic_set_list_n_basic_set(list); + if (n < 0) + goto error; + if (n < 2) + isl_die(isl_basic_set_list_get_ctx(list), + isl_error_internal, + "expecting at least two elements", goto error); + bset1 = isl_basic_set_list_get_basic_set(list, n - 1); + bset2 = isl_basic_set_list_get_basic_set(list, n - 2); + bset1 = convex_hull_pair(bset1, bset2); + if (n == 2) { + isl_basic_set_list_free(list); + return bset1; + } + bset1 = isl_basic_set_underlying_set(bset1); + list = isl_basic_set_list_drop(list, n - 2, 2); + list = isl_basic_set_list_add(list, bset1); + + t = isl_basic_set_list_get_basic_set(list, n - 2); + t = isl_basic_set_lineality_space(t); + if (!t) + goto error; + if (isl_basic_set_plain_is_universe(t)) { + isl_basic_set_list_free(list); + return t; + } + total = isl_basic_set_dim(t, isl_dim_all); + if (t->n_eq < total) { + set = isl_basic_set_list_union(list); + return modulo_lineality(set, t); + } + isl_basic_set_free(t); + if (total < 0) + goto error; + } + + return NULL; +error: + isl_basic_set_list_free(list); + return NULL; +} + +/* Compute an initial hull for wrapping containing a single initial + * facet. + * This function assumes that the given set is bounded. + */ +static __isl_give isl_basic_set *initial_hull(__isl_take isl_basic_set *hull, + __isl_keep isl_set *set) +{ + struct isl_mat *bounds = NULL; + isl_size dim; + int k; + + if (!hull) + goto error; + bounds = initial_facet_constraint(set); + if (!bounds) + goto error; + k = isl_basic_set_alloc_inequality(hull); + if (k < 0) + goto error; + dim = isl_set_dim(set, isl_dim_set); + if (dim < 0) + goto error; + isl_assert(set->ctx, 1 + dim == bounds->n_col, goto error); + isl_seq_cpy(hull->ineq[k], bounds->row[0], bounds->n_col); + isl_mat_free(bounds); + + return hull; +error: + isl_basic_set_free(hull); + isl_mat_free(bounds); + return NULL; +} + +struct max_constraint { + struct isl_mat *c; + int count; + int ineq; +}; + +static isl_bool max_constraint_equal(const void *entry, const void *val) +{ + struct max_constraint *a = (struct max_constraint *)entry; + isl_int *b = (isl_int *)val; + + return isl_bool_ok(isl_seq_eq(a->c->row[0] + 1, b, a->c->n_col - 1)); +} + +static isl_stat update_constraint(struct isl_ctx *ctx, + struct isl_hash_table *table, + isl_int *con, unsigned len, int n, int ineq) +{ + struct isl_hash_table_entry *entry; + struct max_constraint *c; + uint32_t c_hash; + + c_hash = isl_seq_get_hash(con + 1, len); + entry = isl_hash_table_find(ctx, table, c_hash, max_constraint_equal, + con + 1, 0); + if (!entry) + return isl_stat_error; + if (entry == isl_hash_table_entry_none) + return isl_stat_ok; + c = entry->data; + if (c->count < n) { + isl_hash_table_remove(ctx, table, entry); + return isl_stat_ok; + } + c->count++; + if (isl_int_gt(c->c->row[0][0], con[0])) + return isl_stat_ok; + if (isl_int_eq(c->c->row[0][0], con[0])) { + if (ineq) + c->ineq = ineq; + return isl_stat_ok; + } + c->c = isl_mat_cow(c->c); + isl_int_set(c->c->row[0][0], con[0]); + c->ineq = ineq; + + return isl_stat_ok; +} + +/* Check whether the constraint hash table "table" contains the constraint + * "con". + */ +static isl_bool has_constraint(struct isl_ctx *ctx, + struct isl_hash_table *table, isl_int *con, unsigned len, int n) +{ + struct isl_hash_table_entry *entry; + struct max_constraint *c; + uint32_t c_hash; + + c_hash = isl_seq_get_hash(con + 1, len); + entry = isl_hash_table_find(ctx, table, c_hash, max_constraint_equal, + con + 1, 0); + if (!entry) + return isl_bool_error; + if (entry == isl_hash_table_entry_none) + return isl_bool_false; + c = entry->data; + if (c->count < n) + return isl_bool_false; + return isl_bool_ok(isl_int_eq(c->c->row[0][0], con[0])); +} + +/* Are the constraints of "bset" known to be facets? + * If there are any equality constraints, then they are not. + * If there may be redundant constraints, then those + * redundant constraints are not facets. + */ +static isl_bool has_facets(__isl_keep isl_basic_set *bset) +{ + isl_size n_eq; + + n_eq = isl_basic_set_n_equality(bset); + if (n_eq < 0) + return isl_bool_error; + if (n_eq != 0) + return isl_bool_false; + return ISL_F_ISSET(bset, ISL_BASIC_SET_NO_REDUNDANT); +} + +/* Check for inequality constraints of a basic set without equalities + * or redundant constraints + * such that the same or more stringent copies of the constraint appear + * in all of the basic sets. Such constraints are necessarily facet + * constraints of the convex hull. + * + * If the resulting basic set is by chance identical to one of + * the basic sets in "set", then we know that this basic set contains + * all other basic sets and is therefore the convex hull of set. + * In this case we set *is_hull to 1. + */ +static __isl_give isl_basic_set *common_constraints( + __isl_take isl_basic_set *hull, __isl_keep isl_set *set, int *is_hull) +{ + int i, j, s, n; + int min_constraints; + int best; + struct max_constraint *constraints = NULL; + struct isl_hash_table *table = NULL; + isl_size total; + + *is_hull = 0; + + for (i = 0; i < set->n; ++i) { + isl_bool facets = has_facets(set->p[i]); + if (facets < 0) + return isl_basic_set_free(hull); + if (facets) + break; + } + if (i >= set->n) + return hull; + min_constraints = set->p[i]->n_ineq; + best = i; + for (i = best + 1; i < set->n; ++i) { + isl_bool facets = has_facets(set->p[i]); + if (facets < 0) + return isl_basic_set_free(hull); + if (!facets) + continue; + if (set->p[i]->n_ineq >= min_constraints) + continue; + min_constraints = set->p[i]->n_ineq; + best = i; + } + constraints = isl_calloc_array(hull->ctx, struct max_constraint, + min_constraints); + if (!constraints) + return hull; + table = isl_alloc_type(hull->ctx, struct isl_hash_table); + if (isl_hash_table_init(hull->ctx, table, min_constraints)) + goto error; + + total = isl_set_dim(set, isl_dim_all); + if (total < 0) + goto error; + for (i = 0; i < set->p[best]->n_ineq; ++i) { + constraints[i].c = isl_mat_sub_alloc6(hull->ctx, + set->p[best]->ineq + i, 0, 1, 0, 1 + total); + if (!constraints[i].c) + goto error; + constraints[i].ineq = 1; + } + for (i = 0; i < min_constraints; ++i) { + struct isl_hash_table_entry *entry; + uint32_t c_hash; + c_hash = isl_seq_get_hash(constraints[i].c->row[0] + 1, total); + entry = isl_hash_table_find(hull->ctx, table, c_hash, + max_constraint_equal, constraints[i].c->row[0] + 1, 1); + if (!entry) + goto error; + isl_assert(hull->ctx, !entry->data, goto error); + entry->data = &constraints[i]; + } + + n = 0; + for (s = 0; s < set->n; ++s) { + if (s == best) + continue; + + for (i = 0; i < set->p[s]->n_eq; ++i) { + isl_int *eq = set->p[s]->eq[i]; + for (j = 0; j < 2; ++j) { + isl_seq_neg(eq, eq, 1 + total); + if (update_constraint(hull->ctx, table, + eq, total, n, 0) < 0) + goto error; + } + } + for (i = 0; i < set->p[s]->n_ineq; ++i) { + isl_int *ineq = set->p[s]->ineq[i]; + if (update_constraint(hull->ctx, table, ineq, total, n, + set->p[s]->n_eq == 0) < 0) + goto error; + } + ++n; + } + + for (i = 0; i < min_constraints; ++i) { + if (constraints[i].count < n) + continue; + if (!constraints[i].ineq) + continue; + j = isl_basic_set_alloc_inequality(hull); + if (j < 0) + goto error; + isl_seq_cpy(hull->ineq[j], constraints[i].c->row[0], 1 + total); + } + + for (s = 0; s < set->n; ++s) { + if (set->p[s]->n_eq) + continue; + if (set->p[s]->n_ineq != hull->n_ineq) + continue; + for (i = 0; i < set->p[s]->n_ineq; ++i) { + isl_bool has; + isl_int *ineq = set->p[s]->ineq[i]; + has = has_constraint(hull->ctx, table, ineq, total, n); + if (has < 0) + goto error; + if (!has) + break; + } + if (i == set->p[s]->n_ineq) + *is_hull = 1; + } + + isl_hash_table_clear(table); + for (i = 0; i < min_constraints; ++i) + isl_mat_free(constraints[i].c); + free(constraints); + free(table); + return hull; +error: + isl_hash_table_clear(table); + free(table); + if (constraints) + for (i = 0; i < min_constraints; ++i) + isl_mat_free(constraints[i].c); + free(constraints); + return hull; +} + +/* Create a template for the convex hull of "set" and fill it up + * obvious facet constraints, if any. If the result happens to + * be the convex hull of "set" then *is_hull is set to 1. + */ +static __isl_give isl_basic_set *proto_hull(__isl_keep isl_set *set, + int *is_hull) +{ + struct isl_basic_set *hull; + unsigned n_ineq; + int i; + + n_ineq = 1; + for (i = 0; i < set->n; ++i) { + n_ineq += set->p[i]->n_eq; + n_ineq += set->p[i]->n_ineq; + } + hull = isl_basic_set_alloc_space(isl_space_copy(set->dim), 0, 0, n_ineq); + hull = isl_basic_set_set_rational(hull); + if (!hull) + return NULL; + return common_constraints(hull, set, is_hull); +} + +static __isl_give isl_basic_set *uset_convex_hull_wrap(__isl_take isl_set *set) +{ + struct isl_basic_set *hull; + int is_hull; + + hull = proto_hull(set, &is_hull); + if (hull && !is_hull) { + if (hull->n_ineq == 0) + hull = initial_hull(hull, set); + hull = extend(hull, set); + } + isl_set_free(set); + + return hull; +} + +/* Compute the convex hull of a set without any parameters or + * integer divisions. Depending on whether the set is bounded, + * we pass control to the wrapping based convex hull or + * the Fourier-Motzkin elimination based convex hull. + * We also handle a few special cases before checking the boundedness. + */ +static __isl_give isl_basic_set *uset_convex_hull(__isl_take isl_set *set) +{ + isl_bool bounded; + isl_size dim; + struct isl_basic_set *convex_hull = NULL; + struct isl_basic_set *lin; + + dim = isl_set_dim(set, isl_dim_all); + if (dim < 0) + goto error; + if (dim == 0) + return convex_hull_0d(set); + + set = isl_set_coalesce(set); + set = isl_set_set_rational(set); + + if (!set) + return NULL; + if (set->n == 1) { + convex_hull = isl_basic_set_copy(set->p[0]); + isl_set_free(set); + return convex_hull; + } + if (dim == 1) + return convex_hull_1d(set); + + bounded = isl_set_is_bounded(set); + if (bounded < 0) + goto error; + if (bounded && set->ctx->opt->convex == ISL_CONVEX_HULL_WRAP) + return uset_convex_hull_wrap(set); + + lin = isl_set_combined_lineality_space(isl_set_copy(set)); + if (!lin) + goto error; + if (isl_basic_set_plain_is_universe(lin)) { + isl_set_free(set); + return lin; + } + if (lin->n_eq < dim) + return modulo_lineality(set, lin); + isl_basic_set_free(lin); + + return uset_convex_hull_unbounded(set); +error: + isl_set_free(set); + isl_basic_set_free(convex_hull); + return NULL; +} + +/* This is the core procedure, where "set" is a "pure" set, i.e., + * without parameters or divs and where the convex hull of set is + * known to be full-dimensional. + */ +static __isl_give isl_basic_set *uset_convex_hull_wrap_bounded( + __isl_take isl_set *set) +{ + struct isl_basic_set *convex_hull = NULL; + isl_size dim; + + dim = isl_set_dim(set, isl_dim_all); + if (dim < 0) + goto error; + + if (dim == 0) { + convex_hull = isl_basic_set_universe(isl_space_copy(set->dim)); + isl_set_free(set); + convex_hull = isl_basic_set_set_rational(convex_hull); + return convex_hull; + } + + set = isl_set_set_rational(set); + set = isl_set_coalesce(set); + if (!set) + goto error; + if (set->n == 1) { + convex_hull = isl_basic_set_copy(set->p[0]); + isl_set_free(set); + convex_hull = isl_basic_map_remove_redundancies(convex_hull); + return convex_hull; + } + if (dim == 1) + return convex_hull_1d(set); + + return uset_convex_hull_wrap(set); +error: + isl_set_free(set); + return NULL; +} + +/* Compute the convex hull of set "set" with affine hull "affine_hull", + * We first remove the equalities (transforming the set), compute the + * convex hull of the transformed set and then add the equalities back + * (after performing the inverse transformation. + */ +static __isl_give isl_basic_set *modulo_affine_hull( + __isl_take isl_set *set, __isl_take isl_basic_set *affine_hull) +{ + struct isl_mat *T; + struct isl_mat *T2; + struct isl_basic_set *dummy; + struct isl_basic_set *convex_hull; + + dummy = isl_basic_set_remove_equalities( + isl_basic_set_copy(affine_hull), &T, &T2); + if (!dummy) + goto error; + isl_basic_set_free(dummy); + set = isl_set_preimage(set, T); + convex_hull = uset_convex_hull(set); + convex_hull = isl_basic_set_preimage(convex_hull, T2); + convex_hull = isl_basic_set_intersect(convex_hull, affine_hull); + return convex_hull; +error: + isl_mat_free(T); + isl_mat_free(T2); + isl_basic_set_free(affine_hull); + isl_set_free(set); + return NULL; +} + +/* Return an empty basic map living in the same space as "map". + */ +static __isl_give isl_basic_map *replace_map_by_empty_basic_map( + __isl_take isl_map *map) +{ + isl_space *space; + + space = isl_map_get_space(map); + isl_map_free(map); + return isl_basic_map_empty(space); +} + +/* Compute the convex hull of a map. + * + * The implementation was inspired by "Extended Convex Hull" by Fukuda et al., + * specifically, the wrapping of facets to obtain new facets. + */ +__isl_give isl_basic_map *isl_map_convex_hull(__isl_take isl_map *map) +{ + struct isl_basic_set *bset; + struct isl_basic_map *model = NULL; + struct isl_basic_set *affine_hull = NULL; + struct isl_basic_map *convex_hull = NULL; + struct isl_set *set = NULL; + + map = isl_map_detect_equalities(map); + map = isl_map_align_divs_internal(map); + if (!map) + goto error; + + if (map->n == 0) + return replace_map_by_empty_basic_map(map); + + model = isl_basic_map_copy(map->p[0]); + set = isl_map_underlying_set(map); + if (!set) + goto error; + + affine_hull = isl_set_affine_hull(isl_set_copy(set)); + if (!affine_hull) + goto error; + if (affine_hull->n_eq != 0) + bset = modulo_affine_hull(set, affine_hull); + else { + isl_basic_set_free(affine_hull); + bset = uset_convex_hull(set); + } + + convex_hull = isl_basic_map_overlying_set(bset, model); + if (!convex_hull) + return NULL; + + ISL_F_SET(convex_hull, ISL_BASIC_MAP_NO_IMPLICIT); + ISL_F_SET(convex_hull, ISL_BASIC_MAP_ALL_EQUALITIES); + ISL_F_CLR(convex_hull, ISL_BASIC_MAP_RATIONAL); + return convex_hull; +error: + isl_set_free(set); + isl_basic_map_free(model); + return NULL; +} + +__isl_give isl_basic_set *isl_set_convex_hull(__isl_take isl_set *set) +{ + return bset_from_bmap(isl_map_convex_hull(set_to_map(set))); +} + +__isl_give isl_basic_map *isl_map_polyhedral_hull(__isl_take isl_map *map) +{ + isl_basic_map *hull; + + hull = isl_map_convex_hull(map); + return isl_basic_map_remove_divs(hull); +} + +__isl_give isl_basic_set *isl_set_polyhedral_hull(__isl_take isl_set *set) +{ + return bset_from_bmap(isl_map_polyhedral_hull(set_to_map(set))); +} + +struct sh_data_entry { + struct isl_hash_table *table; + struct isl_tab *tab; +}; + +/* Holds the data needed during the simple hull computation. + * In particular, + * n the number of basic sets in the original set + * hull_table a hash table of already computed constraints + * in the simple hull + * p for each basic set, + * table a hash table of the constraints + * tab the tableau corresponding to the basic set + */ +struct sh_data { + struct isl_ctx *ctx; + unsigned n; + struct isl_hash_table *hull_table; + struct sh_data_entry p[1]; +}; + +static void sh_data_free(struct sh_data *data) +{ + int i; + + if (!data) + return; + isl_hash_table_free(data->ctx, data->hull_table); + for (i = 0; i < data->n; ++i) { + isl_hash_table_free(data->ctx, data->p[i].table); + isl_tab_free(data->p[i].tab); + } + free(data); +} + +struct ineq_cmp_data { + unsigned len; + isl_int *p; +}; + +static isl_bool has_ineq(const void *entry, const void *val) +{ + isl_int *row = (isl_int *)entry; + struct ineq_cmp_data *v = (struct ineq_cmp_data *)val; + + return isl_bool_ok(isl_seq_eq(row + 1, v->p + 1, v->len) || + isl_seq_is_neg(row + 1, v->p + 1, v->len)); +} + +static int hash_ineq(struct isl_ctx *ctx, struct isl_hash_table *table, + isl_int *ineq, unsigned len) +{ + uint32_t c_hash; + struct ineq_cmp_data v; + struct isl_hash_table_entry *entry; + + v.len = len; + v.p = ineq; + c_hash = isl_seq_get_hash(ineq + 1, len); + entry = isl_hash_table_find(ctx, table, c_hash, has_ineq, &v, 1); + if (!entry) + return - 1; + entry->data = ineq; + return 0; +} + +/* Fill hash table "table" with the constraints of "bset". + * Equalities are added as two inequalities. + * The value in the hash table is a pointer to the (in)equality of "bset". + */ +static isl_stat hash_basic_set(struct isl_hash_table *table, + __isl_keep isl_basic_set *bset) +{ + int i, j; + isl_size dim = isl_basic_set_dim(bset, isl_dim_all); + + if (dim < 0) + return isl_stat_error; + for (i = 0; i < bset->n_eq; ++i) { + for (j = 0; j < 2; ++j) { + isl_seq_neg(bset->eq[i], bset->eq[i], 1 + dim); + if (hash_ineq(bset->ctx, table, bset->eq[i], dim) < 0) + return isl_stat_error; + } + } + for (i = 0; i < bset->n_ineq; ++i) { + if (hash_ineq(bset->ctx, table, bset->ineq[i], dim) < 0) + return isl_stat_error; + } + return isl_stat_ok; +} + +static struct sh_data *sh_data_alloc(__isl_keep isl_set *set, unsigned n_ineq) +{ + struct sh_data *data; + int i; + + data = isl_calloc(set->ctx, struct sh_data, + sizeof(struct sh_data) + + (set->n - 1) * sizeof(struct sh_data_entry)); + if (!data) + return NULL; + data->ctx = set->ctx; + data->n = set->n; + data->hull_table = isl_hash_table_alloc(set->ctx, n_ineq); + if (!data->hull_table) + goto error; + for (i = 0; i < set->n; ++i) { + data->p[i].table = isl_hash_table_alloc(set->ctx, + 2 * set->p[i]->n_eq + set->p[i]->n_ineq); + if (!data->p[i].table) + goto error; + if (hash_basic_set(data->p[i].table, set->p[i]) < 0) + goto error; + } + return data; +error: + sh_data_free(data); + return NULL; +} + +/* Check if inequality "ineq" is a bound for basic set "j" or if + * it can be relaxed (by increasing the constant term) to become + * a bound for that basic set. In the latter case, the constant + * term is updated. + * Relaxation of the constant term is only allowed if "shift" is set. + * + * Return 1 if "ineq" is a bound + * 0 if "ineq" may attain arbitrarily small values on basic set "j" + * -1 if some error occurred + */ +static int is_bound(struct sh_data *data, __isl_keep isl_set *set, int j, + isl_int *ineq, int shift) +{ + enum isl_lp_result res; + isl_int opt; + + if (!data->p[j].tab) { + data->p[j].tab = isl_tab_from_basic_set(set->p[j], 0); + if (!data->p[j].tab) + return -1; + } + + isl_int_init(opt); + + res = isl_tab_min(data->p[j].tab, ineq, data->ctx->one, + &opt, NULL, 0); + if (res == isl_lp_ok && isl_int_is_neg(opt)) { + if (shift) + isl_int_sub(ineq[0], ineq[0], opt); + else + res = isl_lp_unbounded; + } + + isl_int_clear(opt); + + return (res == isl_lp_ok || res == isl_lp_empty) ? 1 : + res == isl_lp_unbounded ? 0 : -1; +} + +/* Set the constant term of "ineq" to the maximum of those of the constraints + * in the basic sets of "set" following "i" that are parallel to "ineq". + * That is, if any of the basic sets of "set" following "i" have a more + * relaxed copy of "ineq", then replace "ineq" by the most relaxed copy. + * "c_hash" is the hash value of the linear part of "ineq". + * "v" has been set up for use by has_ineq. + * + * Note that the two inequality constraints corresponding to an equality are + * represented by the same inequality constraint in data->p[j].table + * (but with different hash values). This means the constraint (or at + * least its constant term) may need to be temporarily negated to get + * the actually hashed constraint. + */ +static isl_stat set_max_constant_term(struct sh_data *data, + __isl_keep isl_set *set, + int i, isl_int *ineq, uint32_t c_hash, struct ineq_cmp_data *v) +{ + int j; + isl_ctx *ctx; + struct isl_hash_table_entry *entry; + + ctx = isl_set_get_ctx(set); + for (j = i + 1; j < set->n; ++j) { + int neg; + isl_int *ineq_j; + + entry = isl_hash_table_find(ctx, data->p[j].table, + c_hash, &has_ineq, v, 0); + if (!entry) + return isl_stat_error; + if (entry == isl_hash_table_entry_none) + continue; + + ineq_j = entry->data; + neg = isl_seq_is_neg(ineq_j + 1, ineq + 1, v->len); + if (neg) + isl_int_neg(ineq_j[0], ineq_j[0]); + if (isl_int_gt(ineq_j[0], ineq[0])) + isl_int_set(ineq[0], ineq_j[0]); + if (neg) + isl_int_neg(ineq_j[0], ineq_j[0]); + } + + return isl_stat_ok; +} + +/* Check if inequality "ineq" from basic set "i" is or can be relaxed to + * become a bound on the whole set. If so, add the (relaxed) inequality + * to "hull". Relaxation is only allowed if "shift" is set. + * + * We first check if "hull" already contains a translate of the inequality. + * If so, we are done. + * Then, we check if any of the previous basic sets contains a translate + * of the inequality. If so, then we have already considered this + * inequality and we are done. + * Otherwise, for each basic set other than "i", we check if the inequality + * is a bound on the basic set, but first replace the constant term + * by the maximal value of any translate of the inequality in any + * of the following basic sets. + * For previous basic sets, we know that they do not contain a translate + * of the inequality, so we directly call is_bound. + * For following basic sets, we first check if a translate of the + * inequality appears in its description. If so, the constant term + * of the inequality has already been updated with respect to this + * translate and the inequality is therefore known to be a bound + * of this basic set. + */ +static __isl_give isl_basic_set *add_bound(__isl_take isl_basic_set *hull, + struct sh_data *data, __isl_keep isl_set *set, int i, isl_int *ineq, + int shift) +{ + uint32_t c_hash; + struct ineq_cmp_data v; + struct isl_hash_table_entry *entry; + int j, k; + isl_size total; + + total = isl_basic_set_dim(hull, isl_dim_all); + if (total < 0) + return isl_basic_set_free(hull); + + v.len = total; + v.p = ineq; + c_hash = isl_seq_get_hash(ineq + 1, v.len); + + entry = isl_hash_table_find(hull->ctx, data->hull_table, c_hash, + has_ineq, &v, 0); + if (!entry) + return isl_basic_set_free(hull); + if (entry != isl_hash_table_entry_none) + return hull; + + for (j = 0; j < i; ++j) { + entry = isl_hash_table_find(hull->ctx, data->p[j].table, + c_hash, has_ineq, &v, 0); + if (!entry) + return isl_basic_set_free(hull); + if (entry != isl_hash_table_entry_none) + break; + } + if (j < i) + return hull; + + k = isl_basic_set_alloc_inequality(hull); + if (k < 0) + goto error; + isl_seq_cpy(hull->ineq[k], ineq, 1 + v.len); + + if (set_max_constant_term(data, set, i, hull->ineq[k], c_hash, &v) < 0) + goto error; + for (j = 0; j < i; ++j) { + int bound; + bound = is_bound(data, set, j, hull->ineq[k], shift); + if (bound < 0) + goto error; + if (!bound) + break; + } + if (j < i) + return isl_basic_set_free_inequality(hull, 1); + + for (j = i + 1; j < set->n; ++j) { + int bound; + entry = isl_hash_table_find(hull->ctx, data->p[j].table, + c_hash, has_ineq, &v, 0); + if (!entry) + return isl_basic_set_free(hull); + if (entry != isl_hash_table_entry_none) + continue; + bound = is_bound(data, set, j, hull->ineq[k], shift); + if (bound < 0) + goto error; + if (!bound) + break; + } + if (j < set->n) + return isl_basic_set_free_inequality(hull, 1); + + entry = isl_hash_table_find(hull->ctx, data->hull_table, c_hash, + has_ineq, &v, 1); + if (!entry) + goto error; + entry->data = hull->ineq[k]; + + return hull; +error: + isl_basic_set_free(hull); + return NULL; +} + +/* Check if any inequality from basic set "i" is or can be relaxed to + * become a bound on the whole set. If so, add the (relaxed) inequality + * to "hull". Relaxation is only allowed if "shift" is set. + */ +static __isl_give isl_basic_set *add_bounds(__isl_take isl_basic_set *bset, + struct sh_data *data, __isl_keep isl_set *set, int i, int shift) +{ + int j, k; + isl_size dim = isl_basic_set_dim(bset, isl_dim_all); + + if (dim < 0) + return isl_basic_set_free(bset); + + for (j = 0; j < set->p[i]->n_eq; ++j) { + for (k = 0; k < 2; ++k) { + isl_seq_neg(set->p[i]->eq[j], set->p[i]->eq[j], 1+dim); + bset = add_bound(bset, data, set, i, set->p[i]->eq[j], + shift); + } + } + for (j = 0; j < set->p[i]->n_ineq; ++j) + bset = add_bound(bset, data, set, i, set->p[i]->ineq[j], shift); + return bset; +} + +/* Compute a superset of the convex hull of set that is described + * by only (translates of) the constraints in the constituents of set. + * Translation is only allowed if "shift" is set. + */ +static __isl_give isl_basic_set *uset_simple_hull(__isl_take isl_set *set, + int shift) +{ + struct sh_data *data = NULL; + struct isl_basic_set *hull = NULL; + unsigned n_ineq; + int i; + + if (!set) + return NULL; + + n_ineq = 0; + for (i = 0; i < set->n; ++i) { + if (!set->p[i]) + goto error; + n_ineq += 2 * set->p[i]->n_eq + set->p[i]->n_ineq; + } + + hull = isl_basic_set_alloc_space(isl_space_copy(set->dim), 0, 0, n_ineq); + if (!hull) + goto error; + + data = sh_data_alloc(set, n_ineq); + if (!data) + goto error; + + for (i = 0; i < set->n; ++i) + hull = add_bounds(hull, data, set, i, shift); + + sh_data_free(data); + isl_set_free(set); + + return hull; +error: + sh_data_free(data); + isl_basic_set_free(hull); + isl_set_free(set); + return NULL; +} + +/* Compute a superset of the convex hull of map that is described + * by only (translates of) the constraints in the constituents of map. + * Handle trivial cases where map is NULL or contains at most one disjunct. + */ +static __isl_give isl_basic_map *map_simple_hull_trivial( + __isl_take isl_map *map) +{ + isl_basic_map *hull; + + if (!map) + return NULL; + if (map->n == 0) + return replace_map_by_empty_basic_map(map); + + hull = isl_basic_map_copy(map->p[0]); + isl_map_free(map); + return hull; +} + +/* Return a copy of the simple hull cached inside "map". + * "shift" determines whether to return the cached unshifted or shifted + * simple hull. + */ +static __isl_give isl_basic_map *cached_simple_hull(__isl_take isl_map *map, + int shift) +{ + isl_basic_map *hull; + + hull = isl_basic_map_copy(map->cached_simple_hull[shift]); + isl_map_free(map); + + return hull; +} + +/* Compute a superset of the convex hull of map that is described + * by only (translates of) the constraints in the constituents of map. + * Translation is only allowed if "shift" is set. + * + * The constraints are sorted while removing redundant constraints + * in order to indicate a preference of which constraints should + * be preserved. In particular, pairs of constraints that are + * sorted together are preferred to either both be preserved + * or both be removed. The sorting is performed inside + * isl_basic_map_remove_redundancies. + * + * The result of the computation is stored in map->cached_simple_hull[shift] + * such that it can be reused in subsequent calls. The cache is cleared + * whenever the map is modified (in isl_map_cow). + * Note that the results need to be stored in the input map for there + * to be any chance that they may get reused. In particular, they + * are stored in a copy of the input map that is saved before + * the integer division alignment. + */ +static __isl_give isl_basic_map *map_simple_hull(__isl_take isl_map *map, + int shift) +{ + struct isl_set *set = NULL; + struct isl_basic_map *model = NULL; + struct isl_basic_map *hull; + struct isl_basic_map *affine_hull; + struct isl_basic_set *bset = NULL; + isl_map *input; + + if (!map || map->n <= 1) + return map_simple_hull_trivial(map); + + if (map->cached_simple_hull[shift]) + return cached_simple_hull(map, shift); + + map = isl_map_detect_equalities(map); + if (!map || map->n <= 1) + return map_simple_hull_trivial(map); + affine_hull = isl_map_affine_hull(isl_map_copy(map)); + input = isl_map_copy(map); + map = isl_map_align_divs_internal(map); + model = map ? isl_basic_map_copy(map->p[0]) : NULL; + + set = isl_map_underlying_set(map); + + bset = uset_simple_hull(set, shift); + + hull = isl_basic_map_overlying_set(bset, model); + + hull = isl_basic_map_intersect(hull, affine_hull); + hull = isl_basic_map_remove_redundancies(hull); + + if (hull) { + ISL_F_SET(hull, ISL_BASIC_MAP_NO_IMPLICIT); + ISL_F_SET(hull, ISL_BASIC_MAP_ALL_EQUALITIES); + } + + hull = isl_basic_map_finalize(hull); + if (input) + input->cached_simple_hull[shift] = isl_basic_map_copy(hull); + isl_map_free(input); + + return hull; +} + +/* Compute a superset of the convex hull of map that is described + * by only translates of the constraints in the constituents of map. + */ +__isl_give isl_basic_map *isl_map_simple_hull(__isl_take isl_map *map) +{ + return map_simple_hull(map, 1); +} + +__isl_give isl_basic_set *isl_set_simple_hull(__isl_take isl_set *set) +{ + return bset_from_bmap(isl_map_simple_hull(set_to_map(set))); +} + +/* Compute a superset of the convex hull of map that is described + * by only the constraints in the constituents of map. + */ +__isl_give isl_basic_map *isl_map_unshifted_simple_hull( + __isl_take isl_map *map) +{ + return map_simple_hull(map, 0); +} + +__isl_give isl_basic_set *isl_set_unshifted_simple_hull( + __isl_take isl_set *set) +{ + return isl_map_unshifted_simple_hull(set); +} + +/* Drop all inequalities from "bmap1" that do not also appear in "bmap2". + * A constraint that appears with different constant terms + * in "bmap1" and "bmap2" is also kept, with the least restrictive + * (i.e., greatest) constant term. + * "bmap1" and "bmap2" are assumed to have the same (known) + * integer divisions. + * The constraints of both "bmap1" and "bmap2" are assumed + * to have been sorted using isl_basic_map_sort_constraints. + * + * Run through the inequality constraints of "bmap1" and "bmap2" + * in sorted order. + * Each constraint of "bmap1" without a matching constraint in "bmap2" + * is removed. + * If a match is found, the constraint is kept. If needed, the constant + * term of the constraint is adjusted. + */ +static __isl_give isl_basic_map *select_shared_inequalities( + __isl_take isl_basic_map *bmap1, __isl_keep isl_basic_map *bmap2) +{ + int i1, i2; + + bmap1 = isl_basic_map_cow(bmap1); + if (!bmap1 || !bmap2) + return isl_basic_map_free(bmap1); + + i1 = bmap1->n_ineq - 1; + i2 = bmap2->n_ineq - 1; + while (bmap1 && i1 >= 0 && i2 >= 0) { + int cmp; + + cmp = isl_basic_map_constraint_cmp(bmap1, bmap1->ineq[i1], + bmap2->ineq[i2]); + if (cmp < 0) { + --i2; + continue; + } + if (cmp > 0) { + if (isl_basic_map_drop_inequality(bmap1, i1) < 0) + bmap1 = isl_basic_map_free(bmap1); + --i1; + continue; + } + if (isl_int_lt(bmap1->ineq[i1][0], bmap2->ineq[i2][0])) + isl_int_set(bmap1->ineq[i1][0], bmap2->ineq[i2][0]); + --i1; + --i2; + } + for (; i1 >= 0; --i1) + if (isl_basic_map_drop_inequality(bmap1, i1) < 0) + bmap1 = isl_basic_map_free(bmap1); + + return bmap1; +} + +/* Drop all equalities from "bmap1" that do not also appear in "bmap2". + * "bmap1" and "bmap2" are assumed to have the same (known) + * integer divisions. + * + * Run through the equality constraints of "bmap1" and "bmap2". + * Each constraint of "bmap1" without a matching constraint in "bmap2" + * is removed. + */ +static __isl_give isl_basic_map *select_shared_equalities( + __isl_take isl_basic_map *bmap1, __isl_keep isl_basic_map *bmap2) +{ + int i1, i2; + isl_size total; + + bmap1 = isl_basic_map_cow(bmap1); + total = isl_basic_map_dim(bmap1, isl_dim_all); + if (total < 0 || !bmap2) + return isl_basic_map_free(bmap1); + + i1 = bmap1->n_eq - 1; + i2 = bmap2->n_eq - 1; + while (bmap1 && i1 >= 0 && i2 >= 0) { + int last1, last2; + + last1 = isl_seq_last_non_zero(bmap1->eq[i1] + 1, total); + last2 = isl_seq_last_non_zero(bmap2->eq[i2] + 1, total); + if (last1 > last2) { + --i2; + continue; + } + if (last1 < last2) { + if (isl_basic_map_drop_equality(bmap1, i1) < 0) + bmap1 = isl_basic_map_free(bmap1); + --i1; + continue; + } + if (!isl_seq_eq(bmap1->eq[i1], bmap2->eq[i2], 1 + total)) { + if (isl_basic_map_drop_equality(bmap1, i1) < 0) + bmap1 = isl_basic_map_free(bmap1); + } + --i1; + --i2; + } + for (; i1 >= 0; --i1) + if (isl_basic_map_drop_equality(bmap1, i1) < 0) + bmap1 = isl_basic_map_free(bmap1); + + return bmap1; +} + +/* Compute a superset of "bmap1" and "bmap2" that is described + * by only the constraints that appear in both "bmap1" and "bmap2". + * + * First drop constraints that involve unknown integer divisions + * since it is not trivial to check whether two such integer divisions + * in different basic maps are the same. + * Then align the remaining (known) divs and sort the constraints. + * Finally drop all inequalities and equalities from "bmap1" that + * do not also appear in "bmap2". + */ +__isl_give isl_basic_map *isl_basic_map_plain_unshifted_simple_hull( + __isl_take isl_basic_map *bmap1, __isl_take isl_basic_map *bmap2) +{ + if (isl_basic_map_check_equal_space(bmap1, bmap2) < 0) + goto error; + + bmap1 = isl_basic_map_drop_constraints_involving_unknown_divs(bmap1); + bmap2 = isl_basic_map_drop_constraints_involving_unknown_divs(bmap2); + bmap1 = isl_basic_map_order_divs(bmap1); + bmap2 = isl_basic_map_align_divs(bmap2, bmap1); + bmap1 = isl_basic_map_align_divs(bmap1, bmap2); + bmap1 = isl_basic_map_sort_constraints(bmap1); + bmap2 = isl_basic_map_sort_constraints(bmap2); + + bmap1 = select_shared_inequalities(bmap1, bmap2); + bmap1 = select_shared_equalities(bmap1, bmap2); + + isl_basic_map_free(bmap2); + bmap1 = isl_basic_map_finalize(bmap1); + return bmap1; +error: + isl_basic_map_free(bmap1); + isl_basic_map_free(bmap2); + return NULL; +} + +/* Compute a superset of the convex hull of "map" that is described + * by only the constraints in the constituents of "map". + * In particular, the result is composed of constraints that appear + * in each of the basic maps of "map" + * + * Constraints that involve unknown integer divisions are dropped + * since it is not trivial to check whether two such integer divisions + * in different basic maps are the same. + * + * The hull is initialized from the first basic map and then + * updated with respect to the other basic maps in turn. + */ +__isl_give isl_basic_map *isl_map_plain_unshifted_simple_hull( + __isl_take isl_map *map) +{ + int i; + isl_basic_map *hull; + + if (!map) + return NULL; + if (map->n <= 1) + return map_simple_hull_trivial(map); + map = isl_map_drop_constraints_involving_unknown_divs(map); + hull = isl_basic_map_copy(map->p[0]); + for (i = 1; i < map->n; ++i) { + isl_basic_map *bmap_i; + + bmap_i = isl_basic_map_copy(map->p[i]); + hull = isl_basic_map_plain_unshifted_simple_hull(hull, bmap_i); + } + + isl_map_free(map); + return hull; +} + +/* Compute a superset of the convex hull of "set" that is described + * by only the constraints in the constituents of "set". + * In particular, the result is composed of constraints that appear + * in each of the basic sets of "set" + */ +__isl_give isl_basic_set *isl_set_plain_unshifted_simple_hull( + __isl_take isl_set *set) +{ + return isl_map_plain_unshifted_simple_hull(set); +} + +/* Check if "ineq" is a bound on "set" and, if so, add it to "hull". + * + * For each basic set in "set", we first check if the basic set + * contains a translate of "ineq". If this translate is more relaxed, + * then we assume that "ineq" is not a bound on this basic set. + * Otherwise, we know that it is a bound. + * If the basic set does not contain a translate of "ineq", then + * we call is_bound to perform the test. + */ +static __isl_give isl_basic_set *add_bound_from_constraint( + __isl_take isl_basic_set *hull, struct sh_data *data, + __isl_keep isl_set *set, isl_int *ineq) +{ + int i, k; + isl_ctx *ctx; + uint32_t c_hash; + struct ineq_cmp_data v; + isl_size total; + + total = isl_basic_set_dim(hull, isl_dim_all); + if (total < 0 || !set) + return isl_basic_set_free(hull); + + v.len = total; + v.p = ineq; + c_hash = isl_seq_get_hash(ineq + 1, v.len); + + ctx = isl_basic_set_get_ctx(hull); + for (i = 0; i < set->n; ++i) { + int bound; + struct isl_hash_table_entry *entry; + + entry = isl_hash_table_find(ctx, data->p[i].table, + c_hash, &has_ineq, &v, 0); + if (!entry) + return isl_basic_set_free(hull); + if (entry != isl_hash_table_entry_none) { + isl_int *ineq_i = entry->data; + int neg, more_relaxed; + + neg = isl_seq_is_neg(ineq_i + 1, ineq + 1, v.len); + if (neg) + isl_int_neg(ineq_i[0], ineq_i[0]); + more_relaxed = isl_int_gt(ineq_i[0], ineq[0]); + if (neg) + isl_int_neg(ineq_i[0], ineq_i[0]); + if (more_relaxed) + break; + else + continue; + } + bound = is_bound(data, set, i, ineq, 0); + if (bound < 0) + return isl_basic_set_free(hull); + if (!bound) + break; + } + if (i < set->n) + return hull; + + k = isl_basic_set_alloc_inequality(hull); + if (k < 0) + return isl_basic_set_free(hull); + isl_seq_cpy(hull->ineq[k], ineq, 1 + v.len); + + return hull; +} + +/* Compute a superset of the convex hull of "set" that is described + * by only some of the "n_ineq" constraints in the list "ineq", where "set" + * has no parameters or integer divisions. + * + * The inequalities in "ineq" are assumed to have been sorted such + * that constraints with the same linear part appear together and + * that among constraints with the same linear part, those with + * smaller constant term appear first. + * + * We reuse the same data structure that is used by uset_simple_hull, + * but we do not need the hull table since we will not consider the + * same constraint more than once. We therefore allocate it with zero size. + * + * We run through the constraints and try to add them one by one, + * skipping identical constraints. If we have added a constraint and + * the next constraint is a more relaxed translate, then we skip this + * next constraint as well. + */ +static __isl_give isl_basic_set *uset_unshifted_simple_hull_from_constraints( + __isl_take isl_set *set, int n_ineq, isl_int **ineq) +{ + int i; + int last_added = 0; + struct sh_data *data = NULL; + isl_basic_set *hull = NULL; + isl_size dim; + + hull = isl_basic_set_alloc_space(isl_set_get_space(set), 0, 0, n_ineq); + if (!hull) + goto error; + + data = sh_data_alloc(set, 0); + if (!data) + goto error; + + dim = isl_set_dim(set, isl_dim_set); + if (dim < 0) + goto error; + for (i = 0; i < n_ineq; ++i) { + int hull_n_ineq = hull->n_ineq; + int parallel; + + parallel = i > 0 && isl_seq_eq(ineq[i - 1] + 1, ineq[i] + 1, + dim); + if (parallel && + (last_added || isl_int_eq(ineq[i - 1][0], ineq[i][0]))) + continue; + hull = add_bound_from_constraint(hull, data, set, ineq[i]); + if (!hull) + goto error; + last_added = hull->n_ineq > hull_n_ineq; + } + + sh_data_free(data); + isl_set_free(set); + return hull; +error: + sh_data_free(data); + isl_set_free(set); + isl_basic_set_free(hull); + return NULL; +} + +/* Collect pointers to all the inequalities in the elements of "list" + * in "ineq". For equalities, store both a pointer to the equality and + * a pointer to its opposite, which is first copied to "mat". + * "ineq" and "mat" are assumed to have been preallocated to the right size + * (the number of inequalities + 2 times the number of equalites and + * the number of equalities, respectively). + */ +static __isl_give isl_mat *collect_inequalities(__isl_take isl_mat *mat, + __isl_keep isl_basic_set_list *list, isl_int **ineq) +{ + int i, j, n_eq, n_ineq; + isl_size n; + + n = isl_basic_set_list_n_basic_set(list); + if (!mat || n < 0) + return isl_mat_free(mat); + + n_eq = 0; + n_ineq = 0; + for (i = 0; i < n; ++i) { + isl_basic_set *bset; + bset = isl_basic_set_list_get_basic_set(list, i); + if (!bset) + return isl_mat_free(mat); + for (j = 0; j < bset->n_eq; ++j) { + ineq[n_ineq++] = mat->row[n_eq]; + ineq[n_ineq++] = bset->eq[j]; + isl_seq_neg(mat->row[n_eq++], bset->eq[j], mat->n_col); + } + for (j = 0; j < bset->n_ineq; ++j) + ineq[n_ineq++] = bset->ineq[j]; + isl_basic_set_free(bset); + } + + return mat; +} + +/* Comparison routine for use as an isl_sort callback. + * + * Constraints with the same linear part are sorted together and + * among constraints with the same linear part, those with smaller + * constant term are sorted first. + */ +static int cmp_ineq(const void *a, const void *b, void *arg) +{ + unsigned dim = *(unsigned *) arg; + isl_int * const *ineq1 = a; + isl_int * const *ineq2 = b; + int cmp; + + cmp = isl_seq_cmp((*ineq1) + 1, (*ineq2) + 1, dim); + if (cmp != 0) + return cmp; + return isl_int_cmp((*ineq1)[0], (*ineq2)[0]); +} + +/* Compute a superset of the convex hull of "set" that is described + * by only constraints in the elements of "list", where "set" has + * no parameters or integer divisions. + * + * We collect all the constraints in those elements and then + * sort the constraints such that constraints with the same linear part + * are sorted together and that those with smaller constant term are + * sorted first. + */ +static __isl_give isl_basic_set *uset_unshifted_simple_hull_from_basic_set_list( + __isl_take isl_set *set, __isl_take isl_basic_set_list *list) +{ + int i, n_eq, n_ineq; + isl_size n; + isl_size dim; + isl_ctx *ctx; + isl_mat *mat = NULL; + isl_int **ineq = NULL; + isl_basic_set *hull; + + n = isl_basic_set_list_n_basic_set(list); + if (!set || n < 0) + goto error; + ctx = isl_set_get_ctx(set); + + n_eq = 0; + n_ineq = 0; + for (i = 0; i < n; ++i) { + isl_basic_set *bset; + bset = isl_basic_set_list_get_basic_set(list, i); + if (!bset) + goto error; + n_eq += bset->n_eq; + n_ineq += 2 * bset->n_eq + bset->n_ineq; + isl_basic_set_free(bset); + } + + ineq = isl_alloc_array(ctx, isl_int *, n_ineq); + if (n_ineq > 0 && !ineq) + goto error; + + dim = isl_set_dim(set, isl_dim_set); + if (dim < 0) + goto error; + mat = isl_mat_alloc(ctx, n_eq, 1 + dim); + mat = collect_inequalities(mat, list, ineq); + if (!mat) + goto error; + + if (isl_sort(ineq, n_ineq, sizeof(ineq[0]), &cmp_ineq, &dim) < 0) + goto error; + + hull = uset_unshifted_simple_hull_from_constraints(set, n_ineq, ineq); + + isl_mat_free(mat); + free(ineq); + isl_basic_set_list_free(list); + return hull; +error: + isl_mat_free(mat); + free(ineq); + isl_set_free(set); + isl_basic_set_list_free(list); + return NULL; +} + +/* Compute a superset of the convex hull of "map" that is described + * by only constraints in the elements of "list". + * + * If the list is empty, then we can only describe the universe set. + * If the input map is empty, then all constraints are valid, so + * we return the intersection of the elements in "list". + * + * Otherwise, we align all divs and temporarily treat them + * as regular variables, computing the unshifted simple hull in + * uset_unshifted_simple_hull_from_basic_set_list. + */ +static __isl_give isl_basic_map *map_unshifted_simple_hull_from_basic_map_list( + __isl_take isl_map *map, __isl_take isl_basic_map_list *list) +{ + isl_size n; + isl_basic_map *model; + isl_basic_map *hull; + isl_set *set; + isl_basic_set_list *bset_list; + + n = isl_basic_map_list_n_basic_map(list); + if (!map || n < 0) + goto error; + + if (n == 0) { + isl_space *space; + + space = isl_map_get_space(map); + isl_map_free(map); + isl_basic_map_list_free(list); + return isl_basic_map_universe(space); + } + if (isl_map_plain_is_empty(map)) { + isl_map_free(map); + return isl_basic_map_list_intersect(list); + } + + map = isl_map_align_divs_to_basic_map_list(map, list); + if (!map) + goto error; + list = isl_basic_map_list_align_divs_to_basic_map(list, map->p[0]); + + model = isl_basic_map_list_get_basic_map(list, 0); + + set = isl_map_underlying_set(map); + bset_list = isl_basic_map_list_underlying_set(list); + + hull = uset_unshifted_simple_hull_from_basic_set_list(set, bset_list); + hull = isl_basic_map_overlying_set(hull, model); + + return hull; +error: + isl_map_free(map); + isl_basic_map_list_free(list); + return NULL; +} + +/* Return a sequence of the basic maps that make up the maps in "list". + */ +static __isl_give isl_basic_map_list *collect_basic_maps( + __isl_take isl_map_list *list) +{ + int i; + isl_size n; + isl_ctx *ctx; + isl_basic_map_list *bmap_list; + + if (!list) + return NULL; + n = isl_map_list_n_map(list); + ctx = isl_map_list_get_ctx(list); + bmap_list = isl_basic_map_list_alloc(ctx, 0); + if (n < 0) + bmap_list = isl_basic_map_list_free(bmap_list); + + for (i = 0; i < n; ++i) { + isl_map *map; + isl_basic_map_list *list_i; + + map = isl_map_list_get_map(list, i); + map = isl_map_compute_divs(map); + list_i = isl_map_get_basic_map_list(map); + isl_map_free(map); + bmap_list = isl_basic_map_list_concat(bmap_list, list_i); + } + + isl_map_list_free(list); + return bmap_list; +} + +/* Compute a superset of the convex hull of "map" that is described + * by only constraints in the elements of "list". + * + * If "map" is the universe, then the convex hull (and therefore + * any superset of the convexhull) is the universe as well. + * + * Otherwise, we collect all the basic maps in the map list and + * continue with map_unshifted_simple_hull_from_basic_map_list. + */ +__isl_give isl_basic_map *isl_map_unshifted_simple_hull_from_map_list( + __isl_take isl_map *map, __isl_take isl_map_list *list) +{ + isl_basic_map_list *bmap_list; + int is_universe; + + is_universe = isl_map_plain_is_universe(map); + if (is_universe < 0) + map = isl_map_free(map); + if (is_universe < 0 || is_universe) { + isl_map_list_free(list); + return isl_map_unshifted_simple_hull(map); + } + + bmap_list = collect_basic_maps(list); + return map_unshifted_simple_hull_from_basic_map_list(map, bmap_list); +} + +/* Compute a superset of the convex hull of "set" that is described + * by only constraints in the elements of "list". + */ +__isl_give isl_basic_set *isl_set_unshifted_simple_hull_from_set_list( + __isl_take isl_set *set, __isl_take isl_set_list *list) +{ + return isl_map_unshifted_simple_hull_from_map_list(set, list); +} + +/* Given a set "set", return parametric bounds on the dimension "dim". + */ +static __isl_give isl_basic_set *set_bounds(__isl_keep isl_set *set, int dim) +{ + isl_size set_dim = isl_set_dim(set, isl_dim_set); + if (set_dim < 0) + return NULL; + set = isl_set_copy(set); + set = isl_set_eliminate_dims(set, dim + 1, set_dim - (dim + 1)); + set = isl_set_eliminate_dims(set, 0, dim); + return isl_set_convex_hull(set); +} + +/* Computes a "simple hull" and then check if each dimension in the + * resulting hull is bounded by a symbolic constant. If not, the + * hull is intersected with the corresponding bounds on the whole set. + */ +__isl_give isl_basic_set *isl_set_bounded_simple_hull(__isl_take isl_set *set) +{ + int i, j; + struct isl_basic_set *hull; + isl_size nparam, dim, total; + unsigned left; + int removed_divs = 0; + + hull = isl_set_simple_hull(isl_set_copy(set)); + nparam = isl_basic_set_dim(hull, isl_dim_param); + dim = isl_basic_set_dim(hull, isl_dim_set); + total = isl_basic_set_dim(hull, isl_dim_all); + if (nparam < 0 || dim < 0 || total < 0) + goto error; + + for (i = 0; i < dim; ++i) { + int lower = 0, upper = 0; + struct isl_basic_set *bounds; + + left = total - nparam - i - 1; + for (j = 0; j < hull->n_eq; ++j) { + if (isl_int_is_zero(hull->eq[j][1 + nparam + i])) + continue; + if (isl_seq_first_non_zero(hull->eq[j]+1+nparam+i+1, + left) == -1) + break; + } + if (j < hull->n_eq) + continue; + + for (j = 0; j < hull->n_ineq; ++j) { + if (isl_int_is_zero(hull->ineq[j][1 + nparam + i])) + continue; + if (isl_seq_first_non_zero(hull->ineq[j]+1+nparam+i+1, + left) != -1 || + isl_seq_first_non_zero(hull->ineq[j]+1+nparam, + i) != -1) + continue; + if (isl_int_is_pos(hull->ineq[j][1 + nparam + i])) + lower = 1; + else + upper = 1; + if (lower && upper) + break; + } + + if (lower && upper) + continue; + + if (!removed_divs) { + set = isl_set_remove_divs(set); + if (!set) + goto error; + removed_divs = 1; + } + bounds = set_bounds(set, i); + hull = isl_basic_set_intersect(hull, bounds); + if (!hull) + goto error; + } + + isl_set_free(set); + return hull; +error: + isl_set_free(set); + isl_basic_set_free(hull); + return NULL; +} diff --git a/external/mit/isl/dist/isl_copy_tuple_id_templ.c b/external/mit/isl/dist/isl_copy_tuple_id_templ.c new file mode 100644 index 000000000000..5f32f1478f01 --- /dev/null +++ b/external/mit/isl/dist/isl_copy_tuple_id_templ.c @@ -0,0 +1,37 @@ +/* + * Copyright 2019 Cerebras Systems + * + * Use of this software is governed by the MIT license + * + * Written by Sven Verdoolaege, + * Cerebras Systems, 175 S San Antonio Rd, Los Altos, CA, USA + */ + +#define xCAT(A,B) A ## B +#define CAT(A,B) xCAT(A,B) +#undef TYPE +#define TYPE CAT(isl_,BASE) +#define xBFN(BASE,NAME) isl_ ## BASE ## _ ## NAME +#define BFN(BASE,NAME) xBFN(BASE,NAME) + +/* Copy the identifier of tuple "src_type" in "src" + * to that of "dst_type" in "dst", if there is any such identifier. + */ +__isl_give TYPE *BFN(BASE,copy_tuple_id)(__isl_take TYPE *dst, + enum isl_dim_type dst_type, __isl_keep isl_space *src, + enum isl_dim_type src_type) +{ + isl_bool has_id; + isl_id *id; + + has_id = isl_space_has_tuple_id(src, src_type); + if (has_id < 0) + return FN(TYPE,free)(dst); + if (!has_id) + return dst; + + id = isl_space_get_tuple_id(src, src_type); + dst = FN(TYPE,set_tuple_id)(dst, dst_type, id); + + return dst; +} diff --git a/external/mit/isl/dist/isl_ctx.c b/external/mit/isl/dist/isl_ctx.c new file mode 100644 index 000000000000..017e4af888aa --- /dev/null +++ b/external/mit/isl/dist/isl_ctx.c @@ -0,0 +1,409 @@ +/* + * 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 + */ + +#include +#include +#include + +#define __isl_calloc(type,size) ((type *)calloc(1, size)) +#define __isl_calloc_type(type) __isl_calloc(type,sizeof(type)) + +/* Construct an isl_stat indicating whether "obj" is non-NULL. + * + * That is, return isl_stat_ok if "obj" is non_NULL and + * isl_stat_error otherwise. + */ +isl_stat isl_stat_non_null(void *obj) +{ + if (obj != NULL) + return isl_stat_ok; + return isl_stat_error; +} + +/* Return the negation of "b", where the negation of isl_bool_error + * is isl_bool_error again. + */ +isl_bool isl_bool_not(isl_bool b) +{ + if (b < 0) + return isl_bool_error; + if (b == isl_bool_false) + return isl_bool_true; + return isl_bool_false; +} + +/* Create an isl_bool from an integer. + * + * Return isl_bool_false if b is zero, otherwise return isl_bool_true. + * This function never returns isl_bool_error. + */ +isl_bool isl_bool_ok(int b) +{ + if (b) + return isl_bool_true; + return isl_bool_false; +} + +/* Check that the result of an allocation ("p") is not NULL and + * complain if it is. + * The only exception is when allocation size ("size") is equal to zero. + */ +static void *check_non_null(isl_ctx *ctx, void *p, size_t size) +{ + if (p || size == 0) + return p; + isl_die(ctx, isl_error_alloc, "allocation failure", return NULL); +} + +/* Prepare for performing the next "operation" in the context. + * Return 0 if we are allowed to perform this operation and + * return -1 if we should abort the computation. + * + * In particular, we should stop if the user has explicitly aborted + * the computation or if the maximal number of operations has been exceeded. + */ +int isl_ctx_next_operation(isl_ctx *ctx) +{ + if (!ctx) + return -1; + if (ctx->abort) { + isl_ctx_set_error(ctx, isl_error_abort); + return -1; + } + if (ctx->max_operations && ctx->operations >= ctx->max_operations) + isl_die(ctx, isl_error_quota, + "maximal number of operations exceeded", return -1); + ctx->operations++; + return 0; +} + +/* Call malloc and complain if it fails. + * If ctx is NULL, then return NULL. + */ +void *isl_malloc_or_die(isl_ctx *ctx, size_t size) +{ + if (isl_ctx_next_operation(ctx) < 0) + return NULL; + return ctx ? check_non_null(ctx, malloc(size), size) : NULL; +} + +/* Call calloc and complain if it fails. + * If ctx is NULL, then return NULL. + */ +void *isl_calloc_or_die(isl_ctx *ctx, size_t nmemb, size_t size) +{ + if (isl_ctx_next_operation(ctx) < 0) + return NULL; + return ctx ? check_non_null(ctx, calloc(nmemb, size), nmemb) : NULL; +} + +/* Call realloc and complain if it fails. + * If ctx is NULL, then return NULL. + */ +void *isl_realloc_or_die(isl_ctx *ctx, void *ptr, size_t size) +{ + if (isl_ctx_next_operation(ctx) < 0) + return NULL; + 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_full_error(ctx, error, msg, file, line); + + switch (ctx->opt->on_error) { + case ISL_ON_ERROR_WARN: + fprintf(stderr, "%s:%d: %s\n", file, line, msg); + return; + case ISL_ON_ERROR_CONTINUE: + return; + case ISL_ON_ERROR_ABORT: + fprintf(stderr, "%s:%d: %s\n", file, line, msg); + abort(); + return; + } +} + +static struct isl_options *find_nested_options(struct isl_args *args, + void *opt, struct isl_args *wanted) +{ + int i; + struct isl_options *options; + + if (args == wanted) + return opt; + + for (i = 0; args->args[i].type != isl_arg_end; ++i) { + struct isl_arg *arg = &args->args[i]; + void *child; + + if (arg->type != isl_arg_child) + continue; + + if (arg->offset == ISL_ARG_OFFSET_NONE) + child = opt; + else + child = *(void **)(((char *)opt) + arg->offset); + + options = find_nested_options(arg->u.child.child, + child, wanted); + if (options) + return options; + } + + return NULL; +} + +static struct isl_options *find_nested_isl_options(struct isl_args *args, + void *opt) +{ + return find_nested_options(args, opt, &isl_options_args); +} + +void *isl_ctx_peek_options(isl_ctx *ctx, struct isl_args *args) +{ + if (!ctx) + return NULL; + if (args == &isl_options_args) + return ctx->opt; + return find_nested_options(ctx->user_args, ctx->user_opt, args); +} + +isl_ctx *isl_ctx_alloc_with_options(struct isl_args *args, void *user_opt) +{ + struct isl_ctx *ctx = NULL; + struct isl_options *opt = NULL; + int opt_allocated = 0; + + if (!user_opt) + return NULL; + + opt = find_nested_isl_options(args, user_opt); + if (!opt) { + opt = isl_options_new_with_defaults(); + if (!opt) + goto error; + opt_allocated = 1; + } + + ctx = __isl_calloc_type(struct isl_ctx); + if (!ctx) + goto error; + + if (isl_hash_table_init(ctx, &ctx->id_table, 0)) + goto error; + + ctx->stats = isl_calloc_type(ctx, struct isl_stats); + if (!ctx->stats) + goto error; + + ctx->user_args = args; + ctx->user_opt = user_opt; + ctx->opt_allocated = opt_allocated; + ctx->opt = opt; + ctx->ref = 0; + + isl_int_init(ctx->zero); + isl_int_set_si(ctx->zero, 0); + + isl_int_init(ctx->one); + isl_int_set_si(ctx->one, 1); + + isl_int_init(ctx->two); + isl_int_set_si(ctx->two, 2); + + isl_int_init(ctx->negone); + isl_int_set_si(ctx->negone, -1); + + isl_int_init(ctx->normalize_gcd); + + ctx->n_cached = 0; + ctx->n_miss = 0; + + isl_ctx_reset_error(ctx); + + ctx->operations = 0; + isl_ctx_set_max_operations(ctx, ctx->opt->max_operations); + + return ctx; +error: + isl_args_free(args, user_opt); + if (opt_allocated) + isl_options_free(opt); + free(ctx); + return NULL; +} + +struct isl_ctx *isl_ctx_alloc() +{ + struct isl_options *opt; + + opt = isl_options_new_with_defaults(); + + return isl_ctx_alloc_with_options(&isl_options_args, opt); +} + +void isl_ctx_ref(struct isl_ctx *ctx) +{ + ctx->ref++; +} + +void isl_ctx_deref(struct isl_ctx *ctx) +{ + isl_assert(ctx, ctx->ref > 0, return); + ctx->ref--; +} + +/* Print statistics on usage. + */ +static void print_stats(isl_ctx *ctx) +{ + fprintf(stderr, "operations: %lu\n", ctx->operations); +} + +void isl_ctx_free(struct isl_ctx *ctx) +{ + if (!ctx) + return; + if (ctx->ref != 0) + isl_die(ctx, isl_error_invalid, + "isl_ctx not freed as some objects still reference it", + return); + + if (ctx->opt->print_stats) + print_stats(ctx); + + isl_hash_table_clear(&ctx->id_table); + isl_blk_clear_cache(ctx); + isl_int_clear(ctx->zero); + isl_int_clear(ctx->one); + isl_int_clear(ctx->two); + isl_int_clear(ctx->negone); + isl_int_clear(ctx->normalize_gcd); + isl_args_free(ctx->user_args, ctx->user_opt); + if (ctx->opt_allocated) + isl_options_free(ctx->opt); + free(ctx->stats); + free(ctx); +} + +struct isl_options *isl_ctx_options(isl_ctx *ctx) +{ + if (!ctx) + return NULL; + return ctx->opt; +} + +enum isl_error isl_ctx_last_error(isl_ctx *ctx) +{ + 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) +{ + isl_ctx_set_full_error(ctx, error, NULL, NULL, -1); +} + +void isl_ctx_abort(isl_ctx *ctx) +{ + if (ctx) + ctx->abort = 1; +} + +void isl_ctx_resume(isl_ctx *ctx) +{ + if (ctx) + ctx->abort = 0; +} + +int isl_ctx_aborted(isl_ctx *ctx) +{ + return ctx ? ctx->abort : -1; +} + +int isl_ctx_parse_options(isl_ctx *ctx, int argc, char **argv, unsigned flags) +{ + if (!ctx) + return -1; + return isl_args_parse(ctx->user_args, argc, argv, ctx->user_opt, flags); +} + +/* Set the maximal number of iterations of "ctx" to "max_operations". + */ +void isl_ctx_set_max_operations(isl_ctx *ctx, unsigned long max_operations) +{ + if (!ctx) + return; + ctx->max_operations = max_operations; +} + +/* Return the maximal number of iterations of "ctx". + */ +unsigned long isl_ctx_get_max_operations(isl_ctx *ctx) +{ + return ctx ? ctx->max_operations : 0; +} + +/* Reset the number of operations performed by "ctx". + */ +void isl_ctx_reset_operations(isl_ctx *ctx) +{ + if (!ctx) + return; + ctx->operations = 0; +} diff --git a/external/mit/isl/dist/isl_ctx_private.h b/external/mit/isl/dist/isl_ctx_private.h new file mode 100644 index 000000000000..5083a965e927 --- /dev/null +++ b/external/mit/isl/dist/isl_ctx_private.h @@ -0,0 +1,47 @@ +#include +#include + +/* "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; + + struct isl_stats *stats; + + int opt_allocated; + struct isl_options *opt; + void *user_opt; + struct isl_args *user_args; + + isl_int zero; + isl_int one; + isl_int two; + isl_int negone; + + isl_int normalize_gcd; + + int n_cached; + int n_miss; + struct isl_blk cache[ISL_BLK_CACHE_SIZE]; + struct isl_hash_table id_table; + + enum isl_error error; + const char *error_msg; + const char *error_file; + int error_line; + + int abort; + + unsigned long operations; + unsigned long max_operations; +}; + +int isl_ctx_next_operation(isl_ctx *ctx); + +void isl_ctx_set_full_error(isl_ctx *ctx, enum isl_error error, const char *msg, + const char *file, int line); diff --git a/external/mit/isl/dist/isl_deprecated.c b/external/mit/isl/dist/isl_deprecated.c new file mode 100644 index 000000000000..f65be1f8d775 --- /dev/null +++ b/external/mit/isl/dist/isl_deprecated.c @@ -0,0 +1,15 @@ +#include + +/* This function was replaced by isl_constraint_alloc_equality. + */ +__isl_give isl_constraint *isl_equality_alloc(__isl_take isl_local_space *ls) +{ + return isl_constraint_alloc_equality(ls); +} + +/* This function was replaced by isl_constraint_alloc_inequality. + */ +__isl_give isl_constraint *isl_inequality_alloc(__isl_take isl_local_space *ls) +{ + return isl_constraint_alloc_inequality(ls); +} diff --git a/external/mit/isl/dist/isl_dim_map.c b/external/mit/isl/dist/isl_dim_map.c new file mode 100644 index 000000000000..08597bb1fabf --- /dev/null +++ b/external/mit/isl/dist/isl_dim_map.c @@ -0,0 +1,252 @@ +/* + * Copyright 2008-2009 Katholieke Universiteit Leuven + * Copyright 2010-2011 INRIA Saclay + * + * 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 + */ + +#include +#include +#include +#include + +struct isl_dim_map_entry { + int pos; + int sgn; +}; + +/* Maps dst positions to src positions */ +struct isl_dim_map { + unsigned len; + struct isl_dim_map_entry m[1]; +}; + +__isl_give isl_dim_map *isl_dim_map_alloc(isl_ctx *ctx, unsigned len) +{ + int i; + struct isl_dim_map *dim_map; + dim_map = isl_alloc(ctx, struct isl_dim_map, + sizeof(struct isl_dim_map) + len * sizeof(struct isl_dim_map_entry)); + if (!dim_map) + return NULL; + dim_map->len = 1 + len; + dim_map->m[0].pos = 0; + dim_map->m[0].sgn = 1; + for (i = 0; i < len; ++i) + dim_map->m[1 + i].sgn = 0; + return dim_map; +} + +/* Free "dim_map" and return NULL. + */ +__isl_null isl_dim_map *isl_dim_map_free(__isl_take isl_dim_map *dim_map) +{ + free(dim_map); + return NULL; +} + +void isl_dim_map_range(__isl_keep isl_dim_map *dim_map, + unsigned dst_pos, int dst_stride, unsigned src_pos, int src_stride, + unsigned n, int sign) +{ + int i; + + if (!dim_map) + return; + + for (i = 0; i < n; ++i) { + unsigned d = 1 + dst_pos + dst_stride * i; + unsigned s = 1 + src_pos + src_stride * i; + dim_map->m[d].pos = s; + dim_map->m[d].sgn = sign; + } +} + +void isl_dim_map_dim_range(__isl_keep isl_dim_map *dim_map, + __isl_keep isl_space *space, enum isl_dim_type type, + unsigned first, unsigned n, unsigned dst_pos) +{ + int i; + isl_size off; + + off = isl_space_offset(space, type); + if (!dim_map || off < 0) + return; + + for (i = 0; i < n; ++i) { + dim_map->m[1 + dst_pos + i].pos = 1 + off + first + i; + dim_map->m[1 + dst_pos + i].sgn = 1; + } +} + +void isl_dim_map_dim(__isl_keep isl_dim_map *dim_map, + __isl_keep isl_space *space, enum isl_dim_type type, unsigned dst_pos) +{ + isl_size dim = isl_space_dim(space, type); + + if (dim < 0) + return; + isl_dim_map_dim_range(dim_map, space, type, 0, dim, dst_pos); +} + +void isl_dim_map_div(__isl_keep isl_dim_map *dim_map, + __isl_keep isl_basic_map *bmap, unsigned dst_pos) +{ + int i; + unsigned src_pos; + + if (!dim_map || !bmap) + return; + + src_pos = isl_basic_map_offset(bmap, isl_dim_div); + for (i = 0; i < bmap->n_div; ++i) { + dim_map->m[1 + dst_pos + i].pos = src_pos + i; + dim_map->m[1 + dst_pos + i].sgn = 1; + } +} + +void isl_dim_map_dump(struct isl_dim_map *dim_map) +{ + int i; + + for (i = 0; i < dim_map->len; ++i) + fprintf(stderr, "%d -> %d * %d; ", i, + dim_map->m[i].sgn, dim_map->m[i].pos); + fprintf(stderr, "\n"); +} + +static void copy_constraint_dim_map(isl_int *dst, isl_int *src, + struct isl_dim_map *dim_map) +{ + int i; + + for (i = 0; i < dim_map->len; ++i) { + if (dim_map->m[i].sgn == 0) + isl_int_set_si(dst[i], 0); + else if (dim_map->m[i].sgn > 0) + isl_int_set(dst[i], src[dim_map->m[i].pos]); + else + isl_int_neg(dst[i], src[dim_map->m[i].pos]); + } +} + +static void copy_div_dim_map(isl_int *dst, isl_int *src, + struct isl_dim_map *dim_map) +{ + isl_int_set(dst[0], src[0]); + copy_constraint_dim_map(dst+1, src+1, dim_map); +} + +__isl_give isl_basic_map *isl_basic_map_add_constraints_dim_map( + __isl_take isl_basic_map *dst, __isl_take isl_basic_map *src, + __isl_take isl_dim_map *dim_map) +{ + int i; + + if (!src || !dst || !dim_map) + goto error; + + for (i = 0; i < src->n_eq; ++i) { + int i1 = isl_basic_map_alloc_equality(dst); + if (i1 < 0) + goto error; + copy_constraint_dim_map(dst->eq[i1], src->eq[i], dim_map); + } + + for (i = 0; i < src->n_ineq; ++i) { + int i1 = isl_basic_map_alloc_inequality(dst); + if (i1 < 0) + goto error; + copy_constraint_dim_map(dst->ineq[i1], src->ineq[i], dim_map); + } + + for (i = 0; i < src->n_div; ++i) { + int i1 = isl_basic_map_alloc_div(dst); + if (i1 < 0) + goto error; + copy_div_dim_map(dst->div[i1], src->div[i], dim_map); + } + + isl_dim_map_free(dim_map); + isl_basic_map_free(src); + + return dst; +error: + isl_dim_map_free(dim_map); + isl_basic_map_free(src); + isl_basic_map_free(dst); + return NULL; +} + +__isl_give isl_basic_set *isl_basic_set_add_constraints_dim_map( + __isl_take isl_basic_set *dst, __isl_take isl_basic_set *src, + __isl_take isl_dim_map *dim_map) +{ + return isl_basic_map_add_constraints_dim_map(dst, src, dim_map); +} + +/* Extend the given dim_map with mappings for the divs in bmap. + */ +__isl_give isl_dim_map *isl_dim_map_extend(__isl_keep isl_dim_map *dim_map, + __isl_keep isl_basic_map *bmap) +{ + int i; + struct isl_dim_map *res; + int offset; + + if (!dim_map) + return NULL; + + offset = isl_basic_map_offset(bmap, isl_dim_div); + + res = isl_dim_map_alloc(bmap->ctx, dim_map->len - 1 + bmap->n_div); + if (!res) + return NULL; + + for (i = 0; i < dim_map->len; ++i) + res->m[i] = dim_map->m[i]; + for (i = 0; i < bmap->n_div; ++i) { + res->m[dim_map->len + i].pos = offset + i; + res->m[dim_map->len + i].sgn = 1; + } + + return res; +} + +/* Extract a dim_map from a reordering. + * We essentially need to reverse the mapping, and add an offset + * of 1 for the constant term. + */ +__isl_give isl_dim_map *isl_dim_map_from_reordering( + __isl_keep isl_reordering *exp) +{ + int i; + isl_ctx *ctx; + isl_size dim; + isl_space *space; + struct isl_dim_map *dim_map; + + if (!exp) + return NULL; + + ctx = isl_reordering_get_ctx(exp); + space = isl_reordering_peek_space(exp); + dim = isl_space_dim(space, isl_dim_all); + if (dim < 0) + return NULL; + dim_map = isl_dim_map_alloc(ctx, dim); + if (!dim_map) + return NULL; + + for (i = 0; i < exp->src_len; ++i) { + dim_map->m[1 + exp->pos[i]].pos = 1 + i; + dim_map->m[1 + exp->pos[i]].sgn = 1; + } + + return dim_map; +} diff --git a/external/mit/isl/dist/isl_dim_map.h b/external/mit/isl/dist/isl_dim_map.h new file mode 100644 index 000000000000..5e45fe00b2b8 --- /dev/null +++ b/external/mit/isl/dist/isl_dim_map.h @@ -0,0 +1,37 @@ +#ifndef ISL_DIM_MAP_H +#define ISL_DIM_MAP_H + +#include +#include +#include +#include + +struct isl_dim_map; +typedef struct isl_dim_map isl_dim_map; + +__isl_give isl_dim_map *isl_dim_map_alloc(isl_ctx *ctx, unsigned len); +__isl_null isl_dim_map *isl_dim_map_free(__isl_take isl_dim_map *dim_map); +void isl_dim_map_range(__isl_keep isl_dim_map *dim_map, + unsigned dst_pos, int dst_stride, unsigned src_pos, int src_stride, + unsigned n, int sign); +void isl_dim_map_dim_range(__isl_keep isl_dim_map *dim_map, + __isl_keep isl_space *space, enum isl_dim_type type, + unsigned first, unsigned n, unsigned dst_pos); +void isl_dim_map_dim(__isl_keep isl_dim_map *dim_map, + __isl_keep isl_space *space, enum isl_dim_type type, unsigned dst_pos); +void isl_dim_map_div(__isl_keep isl_dim_map *dim_map, + __isl_keep isl_basic_map *bmap, unsigned dst_pos); +__isl_give isl_basic_set *isl_basic_set_add_constraints_dim_map( + __isl_take isl_basic_set *dst, __isl_take isl_basic_set *src, + __isl_take isl_dim_map *dim_map); +__isl_give isl_basic_map *isl_basic_map_add_constraints_dim_map( + __isl_take isl_basic_map *dst, __isl_take isl_basic_map *src, + __isl_take isl_dim_map *dim_map); + +__isl_give isl_dim_map *isl_dim_map_extend(__isl_keep isl_dim_map *dim_map, + __isl_keep isl_basic_map *bmap); + +__isl_give isl_dim_map *isl_dim_map_from_reordering( + __isl_keep isl_reordering *exp); + +#endif diff --git a/external/mit/isl/dist/isl_domain_factor_templ.c b/external/mit/isl/dist/isl_domain_factor_templ.c new file mode 100644 index 000000000000..c64e9a262f0f --- /dev/null +++ b/external/mit/isl/dist/isl_domain_factor_templ.c @@ -0,0 +1,67 @@ +/* + * Copyright 2012 Ecole Normale Superieure + * Copyright 2017 Sven Verdoolaege + * + * Use of this software is governed by the MIT license + * + * Written by Sven Verdoolaege, + * Ecole Normale Superieure, 45 rue d'Ulm, 75230 Paris, France + */ + +#define xFN(TYPE,NAME) TYPE ## _ ## NAME +#define FN(TYPE,NAME) xFN(TYPE,NAME) + +/* Drop the "n" domain dimensions starting at "first" from "obj", + * after checking that they do not appear in the affine expression. + */ +static __isl_give TYPE *FN(TYPE,drop_domain)(__isl_take TYPE *obj, + unsigned first, unsigned n) +{ + isl_bool involves; + + involves = FN(TYPE,involves_dims)(obj, isl_dim_in, first, n); + if (involves < 0) + return FN(TYPE,free)(obj); + if (involves) + isl_die(FN(TYPE,get_ctx)(obj), isl_error_invalid, + "affine expression involves some of the domain dimensions", + return FN(TYPE,free)(obj)); + return FN(TYPE,drop_dims)(obj, isl_dim_in, first, n); +} + +/* Check that the domain of "obj" is a product. + */ +static isl_stat FN(TYPE,check_domain_product)(__isl_keep TYPE *obj) +{ + isl_bool is_product; + + is_product = FN(TYPE,domain_is_product)(obj); + if (is_product < 0) + return isl_stat_error; + if (!is_product) + isl_die(FN(TYPE,get_ctx)(obj), isl_error_invalid, + "domain is not a product", return isl_stat_error); + return isl_stat_ok; +} + +/* Given an affine function with a domain of the form [A -> B] that + * does not depend on B, return the same function on domain A. + */ +__isl_give TYPE *FN(TYPE,domain_factor_domain)(__isl_take TYPE *obj) +{ + isl_space *space; + isl_size n, n_in; + + if (FN(TYPE,check_domain_product)(obj) < 0) + return FN(TYPE,free)(obj); + space = FN(TYPE,get_domain_space)(obj); + n = isl_space_dim(space, isl_dim_set); + space = isl_space_factor_domain(space); + n_in = isl_space_dim(space, isl_dim_set); + if (n < 0 || n_in < 0) + obj = FN(TYPE,free)(obj); + else + obj = FN(TYPE,drop_domain)(obj, n_in, n - n_in); + obj = FN(TYPE,reset_domain_space)(obj, space); + return obj; +} diff --git a/external/mit/isl/dist/isl_drop_unused_params_templ.c b/external/mit/isl/dist/isl_drop_unused_params_templ.c new file mode 100644 index 000000000000..08664e9d93ff --- /dev/null +++ b/external/mit/isl/dist/isl_drop_unused_params_templ.c @@ -0,0 +1,30 @@ +/* + * Use of this software is governed by the MIT license + */ + +#define xFN(TYPE,NAME) TYPE ## _ ## NAME +#define FN(TYPE,NAME) xFN(TYPE,NAME) + +/* Drop all parameters not referenced by "obj". + */ +__isl_give TYPE *FN(TYPE,drop_unused_params)(__isl_take TYPE *obj) +{ + int i; + isl_size n; + + n = FN(TYPE,dim)(obj, isl_dim_param); + if (n < 0 || FN(TYPE,check_named_params)(obj) < 0) + return FN(TYPE,free)(obj); + + for (i = n - 1; i >= 0; i--) { + isl_bool involves; + + involves = FN(TYPE,involves_dims)(obj, isl_dim_param, i, 1); + if (involves < 0) + return FN(TYPE,free)(obj); + if (!involves) + obj = FN(TYPE,drop_dims)(obj, isl_dim_param, i, 1); + } + + return obj; +} diff --git a/external/mit/isl/dist/isl_equalities.c b/external/mit/isl/dist/isl_equalities.c new file mode 100644 index 000000000000..90dfb7709ce7 --- /dev/null +++ b/external/mit/isl/dist/isl_equalities.c @@ -0,0 +1,897 @@ +/* + * Copyright 2008-2009 Katholieke Universiteit Leuven + * Copyright 2010 INRIA Saclay + * + * 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 + */ + +#include +#include +#include +#include "isl_map_private.h" +#include "isl_equalities.h" +#include + +/* Given a set of modulo constraints + * + * c + A y = 0 mod d + * + * this function computes a particular solution y_0 + * + * The input is given as a matrix B = [ c A ] and a vector d. + * + * The output is matrix containing the solution y_0 or + * a zero-column matrix if the constraints admit no integer solution. + * + * The given set of constrains is equivalent to + * + * c + A y = -D x + * + * with D = diag d and x a fresh set of variables. + * Reducing both c and A modulo d does not change the + * value of y in the solution and may lead to smaller coefficients. + * Let M = [ D A ] and [ H 0 ] = M U, the Hermite normal form of M. + * Then + * [ x ] + * M [ y ] = - c + * and so + * [ x ] + * [ H 0 ] U^{-1} [ y ] = - c + * Let + * [ A ] [ x ] + * [ B ] = U^{-1} [ y ] + * then + * H A + 0 B = -c + * + * so B may be chosen arbitrarily, e.g., B = 0, and then + * + * [ x ] = [ -c ] + * U^{-1} [ y ] = [ 0 ] + * or + * [ x ] [ -c ] + * [ y ] = U [ 0 ] + * specifically, + * + * y = U_{2,1} (-c) + * + * If any of the coordinates of this y are non-integer + * then the constraints admit no integer solution and + * a zero-column matrix is returned. + */ +static __isl_give isl_mat *particular_solution(__isl_keep isl_mat *B, + __isl_keep isl_vec *d) +{ + int i, j; + struct isl_mat *M = NULL; + struct isl_mat *C = NULL; + struct isl_mat *U = NULL; + struct isl_mat *H = NULL; + struct isl_mat *cst = NULL; + struct isl_mat *T = NULL; + + M = isl_mat_alloc(B->ctx, B->n_row, B->n_row + B->n_col - 1); + C = isl_mat_alloc(B->ctx, 1 + B->n_row, 1); + if (!M || !C) + goto error; + isl_int_set_si(C->row[0][0], 1); + for (i = 0; i < B->n_row; ++i) { + isl_seq_clr(M->row[i], B->n_row); + isl_int_set(M->row[i][i], d->block.data[i]); + isl_int_neg(C->row[1 + i][0], B->row[i][0]); + isl_int_fdiv_r(C->row[1+i][0], C->row[1+i][0], M->row[i][i]); + for (j = 0; j < B->n_col - 1; ++j) + isl_int_fdiv_r(M->row[i][B->n_row + j], + B->row[i][1 + j], M->row[i][i]); + } + M = isl_mat_left_hermite(M, 0, &U, NULL); + if (!M || !U) + goto error; + H = isl_mat_sub_alloc(M, 0, B->n_row, 0, B->n_row); + H = isl_mat_lin_to_aff(H); + C = isl_mat_inverse_product(H, C); + if (!C) + goto error; + for (i = 0; i < B->n_row; ++i) { + if (!isl_int_is_divisible_by(C->row[1+i][0], C->row[0][0])) + break; + isl_int_divexact(C->row[1+i][0], C->row[1+i][0], C->row[0][0]); + } + if (i < B->n_row) + cst = isl_mat_alloc(B->ctx, B->n_row, 0); + else + cst = isl_mat_sub_alloc(C, 1, B->n_row, 0, 1); + T = isl_mat_sub_alloc(U, B->n_row, B->n_col - 1, 0, B->n_row); + cst = isl_mat_product(T, cst); + isl_mat_free(M); + isl_mat_free(C); + isl_mat_free(U); + return cst; +error: + isl_mat_free(M); + isl_mat_free(C); + isl_mat_free(U); + return NULL; +} + +/* Compute and return the matrix + * + * U_1^{-1} diag(d_1, 1, ..., 1) + * + * with U_1 the unimodular completion of the first (and only) row of B. + * The columns of this matrix generate the lattice that satisfies + * the single (linear) modulo constraint. + */ +static __isl_take isl_mat *parameter_compression_1(__isl_keep isl_mat *B, + __isl_keep isl_vec *d) +{ + struct isl_mat *U; + + U = isl_mat_alloc(B->ctx, B->n_col - 1, B->n_col - 1); + if (!U) + return NULL; + isl_seq_cpy(U->row[0], B->row[0] + 1, B->n_col - 1); + U = isl_mat_unimodular_complete(U, 1); + U = isl_mat_right_inverse(U); + if (!U) + return NULL; + isl_mat_col_mul(U, 0, d->block.data[0], 0); + U = isl_mat_lin_to_aff(U); + return U; +} + +/* Compute a common lattice of solutions to the linear modulo + * constraints specified by B and d. + * See also the documentation of isl_mat_parameter_compression. + * We put the matrix + * + * A = [ L_1^{-T} L_2^{-T} ... L_k^{-T} ] + * + * on a common denominator. This denominator D is the lcm of modulos d. + * Since L_i = U_i^{-1} diag(d_i, 1, ... 1), we have + * L_i^{-T} = U_i^T diag(d_i, 1, ... 1)^{-T} = U_i^T diag(1/d_i, 1, ..., 1). + * Putting this on the common denominator, we have + * D * L_i^{-T} = U_i^T diag(D/d_i, D, ..., D). + */ +static __isl_give isl_mat *parameter_compression_multi(__isl_keep isl_mat *B, + __isl_keep isl_vec *d) +{ + int i, j, k; + isl_int D; + struct isl_mat *A = NULL, *U = NULL; + struct isl_mat *T; + unsigned size; + + isl_int_init(D); + + isl_vec_lcm(d, &D); + + size = B->n_col - 1; + A = isl_mat_alloc(B->ctx, size, B->n_row * size); + U = isl_mat_alloc(B->ctx, size, size); + if (!U || !A) + goto error; + for (i = 0; i < B->n_row; ++i) { + isl_seq_cpy(U->row[0], B->row[i] + 1, size); + U = isl_mat_unimodular_complete(U, 1); + if (!U) + goto error; + isl_int_divexact(D, D, d->block.data[i]); + for (k = 0; k < U->n_col; ++k) + isl_int_mul(A->row[k][i*size+0], D, U->row[0][k]); + isl_int_mul(D, D, d->block.data[i]); + for (j = 1; j < U->n_row; ++j) + for (k = 0; k < U->n_col; ++k) + isl_int_mul(A->row[k][i*size+j], + D, U->row[j][k]); + } + A = isl_mat_left_hermite(A, 0, NULL, NULL); + T = isl_mat_sub_alloc(A, 0, A->n_row, 0, A->n_row); + T = isl_mat_lin_to_aff(T); + if (!T) + goto error; + isl_int_set(T->row[0][0], D); + T = isl_mat_right_inverse(T); + if (!T) + goto error; + isl_assert(T->ctx, isl_int_is_one(T->row[0][0]), goto error); + T = isl_mat_transpose(T); + isl_mat_free(A); + isl_mat_free(U); + + isl_int_clear(D); + return T; +error: + isl_mat_free(A); + isl_mat_free(U); + isl_int_clear(D); + return NULL; +} + +/* Given a set of modulo constraints + * + * c + A y = 0 mod d + * + * this function returns an affine transformation T, + * + * y = T y' + * + * that bijectively maps the integer vectors y' to integer + * vectors y that satisfy the modulo constraints. + * + * This function is inspired by Section 2.5.3 + * of B. Meister, "Stating and Manipulating Periodicity in the Polytope + * Model. Applications to Program Analysis and Optimization". + * However, the implementation only follows the algorithm of that + * section for computing a particular solution and not for computing + * a general homogeneous solution. The latter is incomplete and + * may remove some valid solutions. + * Instead, we use an adaptation of the algorithm in Section 7 of + * B. Meister, S. Verdoolaege, "Polynomial Approximations in the Polytope + * Model: Bringing the Power of Quasi-Polynomials to the Masses". + * + * The input is given as a matrix B = [ c A ] and a vector d. + * Each element of the vector d corresponds to a row in B. + * The output is a lower triangular matrix. + * If no integer vector y satisfies the given constraints then + * a matrix with zero columns is returned. + * + * We first compute a particular solution y_0 to the given set of + * modulo constraints in particular_solution. If no such solution + * exists, then we return a zero-columned transformation matrix. + * Otherwise, we compute the generic solution to + * + * A y = 0 mod d + * + * That is we want to compute G such that + * + * y = G y'' + * + * with y'' integer, describes the set of solutions. + * + * We first remove the common factors of each row. + * In particular if gcd(A_i,d_i) != 1, then we divide the whole + * row i (including d_i) by this common factor. If afterwards gcd(A_i) != 1, + * then we divide this row of A by the common factor, unless gcd(A_i) = 0. + * In the later case, we simply drop the row (in both A and d). + * + * If there are no rows left in A, then G is the identity matrix. Otherwise, + * for each row i, we now determine the lattice of integer vectors + * that satisfies this row. Let U_i be the unimodular extension of the + * row A_i. This unimodular extension exists because gcd(A_i) = 1. + * The first component of + * + * y' = U_i y + * + * needs to be a multiple of d_i. Let y' = diag(d_i, 1, ..., 1) y''. + * Then, + * + * y = U_i^{-1} diag(d_i, 1, ..., 1) y'' + * + * for arbitrary integer vectors y''. That is, y belongs to the lattice + * generated by the columns of L_i = U_i^{-1} diag(d_i, 1, ..., 1). + * If there is only one row, then G = L_1. + * + * If there is more than one row left, we need to compute the intersection + * of the lattices. That is, we need to compute an L such that + * + * L = L_i L_i' for all i + * + * with L_i' some integer matrices. Let A be constructed as follows + * + * A = [ L_1^{-T} L_2^{-T} ... L_k^{-T} ] + * + * and computed the Hermite Normal Form of A = [ H 0 ] U + * Then, + * + * L_i^{-T} = H U_{1,i} + * + * or + * + * H^{-T} = L_i U_{1,i}^T + * + * In other words G = L = H^{-T}. + * To ensure that G is lower triangular, we compute and use its Hermite + * normal form. + * + * The affine transformation matrix returned is then + * + * [ 1 0 ] + * [ y_0 G ] + * + * as any y = y_0 + G y' with y' integer is a solution to the original + * modulo constraints. + */ +__isl_give isl_mat *isl_mat_parameter_compression(__isl_take isl_mat *B, + __isl_take isl_vec *d) +{ + int i; + struct isl_mat *cst = NULL; + struct isl_mat *T = NULL; + isl_int D; + + if (!B || !d) + goto error; + isl_assert(B->ctx, B->n_row == d->size, goto error); + cst = particular_solution(B, d); + if (!cst) + goto error; + if (cst->n_col == 0) { + T = isl_mat_alloc(B->ctx, B->n_col, 0); + isl_mat_free(cst); + isl_mat_free(B); + isl_vec_free(d); + return T; + } + isl_int_init(D); + /* Replace a*g*row = 0 mod g*m by row = 0 mod m */ + for (i = 0; i < B->n_row; ++i) { + isl_seq_gcd(B->row[i] + 1, B->n_col - 1, &D); + if (isl_int_is_one(D)) + continue; + if (isl_int_is_zero(D)) { + B = isl_mat_drop_rows(B, i, 1); + d = isl_vec_cow(d); + if (!B || !d) + goto error2; + isl_seq_cpy(d->block.data+i, d->block.data+i+1, + d->size - (i+1)); + d->size--; + i--; + continue; + } + B = isl_mat_cow(B); + if (!B) + goto error2; + isl_seq_scale_down(B->row[i] + 1, B->row[i] + 1, D, B->n_col-1); + isl_int_gcd(D, D, d->block.data[i]); + d = isl_vec_cow(d); + if (!d) + goto error2; + isl_int_divexact(d->block.data[i], d->block.data[i], D); + } + isl_int_clear(D); + if (B->n_row == 0) + T = isl_mat_identity(B->ctx, B->n_col); + else if (B->n_row == 1) + T = parameter_compression_1(B, d); + else + T = parameter_compression_multi(B, d); + T = isl_mat_left_hermite(T, 0, NULL, NULL); + if (!T) + goto error; + isl_mat_sub_copy(T->ctx, T->row + 1, cst->row, cst->n_row, 0, 0, 1); + isl_mat_free(cst); + isl_mat_free(B); + isl_vec_free(d); + return T; +error2: + isl_int_clear(D); +error: + isl_mat_free(cst); + isl_mat_free(B); + isl_vec_free(d); + return NULL; +} + +/* Given a set of equalities + * + * B(y) + A x = 0 (*) + * + * compute and return an affine transformation T, + * + * y = T y' + * + * that bijectively maps the integer vectors y' to integer + * vectors y that satisfy the modulo constraints for some value of x. + * + * Let [H 0] be the Hermite Normal Form of A, i.e., + * + * A = [H 0] Q + * + * Then y is a solution of (*) iff + * + * H^-1 B(y) (= - [I 0] Q x) + * + * is an integer vector. Let d be the common denominator of H^-1. + * We impose + * + * d H^-1 B(y) = 0 mod d + * + * and compute the solution using isl_mat_parameter_compression. + */ +__isl_give isl_mat *isl_mat_parameter_compression_ext(__isl_take isl_mat *B, + __isl_take isl_mat *A) +{ + isl_ctx *ctx; + isl_vec *d; + int n_row, n_col; + + if (!A) + return isl_mat_free(B); + + ctx = isl_mat_get_ctx(A); + n_row = A->n_row; + n_col = A->n_col; + A = isl_mat_left_hermite(A, 0, NULL, NULL); + A = isl_mat_drop_cols(A, n_row, n_col - n_row); + A = isl_mat_lin_to_aff(A); + A = isl_mat_right_inverse(A); + d = isl_vec_alloc(ctx, n_row); + if (A) + d = isl_vec_set(d, A->row[0][0]); + A = isl_mat_drop_rows(A, 0, 1); + A = isl_mat_drop_cols(A, 0, 1); + B = isl_mat_product(A, B); + + return isl_mat_parameter_compression(B, d); +} + +/* Return a compression matrix that indicates that there are no solutions + * to the original constraints. In particular, return a zero-column + * matrix with 1 + dim rows. If "T2" is not NULL, then assign *T2 + * the inverse of this matrix. *T2 may already have been assigned + * matrix, so free it first. + * "free1", "free2" and "free3" are temporary matrices that are + * not useful when an empty compression is returned. They are + * simply freed. + */ +static __isl_give isl_mat *empty_compression(isl_ctx *ctx, unsigned dim, + __isl_give isl_mat **T2, __isl_take isl_mat *free1, + __isl_take isl_mat *free2, __isl_take isl_mat *free3) +{ + isl_mat_free(free1); + isl_mat_free(free2); + isl_mat_free(free3); + if (T2) { + isl_mat_free(*T2); + *T2 = isl_mat_alloc(ctx, 0, 1 + dim); + } + return isl_mat_alloc(ctx, 1 + dim, 0); +} + +/* Given a matrix that maps a (possibly) parametric domain to + * a parametric domain, add in rows that map the "nparam" parameters onto + * themselves. + */ +static __isl_give isl_mat *insert_parameter_rows(__isl_take isl_mat *mat, + unsigned nparam) +{ + int i; + + if (nparam == 0) + return mat; + if (!mat) + return NULL; + + mat = isl_mat_insert_rows(mat, 1, nparam); + if (!mat) + return NULL; + + for (i = 0; i < nparam; ++i) { + isl_seq_clr(mat->row[1 + i], mat->n_col); + isl_int_set(mat->row[1 + i][1 + i], mat->row[0][0]); + } + + return mat; +} + +/* Given a set of equalities + * + * -C(y) + M x = 0 + * + * this function computes a unimodular transformation from a lower-dimensional + * space to the original space that bijectively maps the integer points x' + * in the lower-dimensional space to the integer points x in the original + * space that satisfy the equalities. + * + * The input is given as a matrix B = [ -C M ] and the output is a + * matrix that maps [1 x'] to [1 x]. + * The number of equality constraints in B is assumed to be smaller than + * or equal to the number of variables x. + * "first" is the position of the first x variable. + * The preceding variables are considered to be y-variables. + * If T2 is not NULL, then *T2 is set to a matrix mapping [1 x] to [1 x']. + * + * First compute the (left) Hermite normal form of M, + * + * M [U1 U2] = M U = H = [H1 0] + * or + * M = H Q = [H1 0] [Q1] + * [Q2] + * + * with U, Q unimodular, Q = U^{-1} (and H lower triangular). + * Define the transformed variables as + * + * x = [U1 U2] [ x1' ] = [U1 U2] [Q1] x + * [ x2' ] [Q2] + * + * The equalities then become + * + * -C(y) + H1 x1' = 0 or x1' = H1^{-1} C(y) = C'(y) + * + * If the denominator of the constant term does not divide the + * the common denominator of the coefficients of y, then every + * integer point is mapped to a non-integer point and then the original set + * has no integer solutions (since the x' are a unimodular transformation + * of the x). In this case, a zero-column matrix is returned. + * Otherwise, the transformation is given by + * + * x = U1 H1^{-1} C(y) + U2 x2' + * + * The inverse transformation is simply + * + * x2' = Q2 x + */ +__isl_give isl_mat *isl_mat_final_variable_compression(__isl_take isl_mat *B, + int first, __isl_give isl_mat **T2) +{ + int i, n; + isl_ctx *ctx; + isl_mat *H = NULL, *C, *H1, *U = NULL, *U1, *U2; + unsigned dim; + + if (T2) + *T2 = NULL; + if (!B) + goto error; + + ctx = isl_mat_get_ctx(B); + dim = B->n_col - 1; + n = dim - first; + if (n < B->n_row) + isl_die(ctx, isl_error_invalid, "too many equality constraints", + goto error); + H = isl_mat_sub_alloc(B, 0, B->n_row, 1 + first, n); + H = isl_mat_left_hermite(H, 0, &U, T2); + if (!H || !U || (T2 && !*T2)) + goto error; + if (T2) { + *T2 = isl_mat_drop_rows(*T2, 0, B->n_row); + *T2 = isl_mat_diagonal(isl_mat_identity(ctx, 1 + first), *T2); + if (!*T2) + goto error; + } + C = isl_mat_alloc(ctx, 1 + B->n_row, 1 + first); + if (!C) + goto error; + isl_int_set_si(C->row[0][0], 1); + isl_seq_clr(C->row[0] + 1, first); + isl_mat_sub_neg(ctx, C->row + 1, B->row, B->n_row, 0, 0, 1 + first); + H1 = isl_mat_sub_alloc(H, 0, H->n_row, 0, H->n_row); + H1 = isl_mat_lin_to_aff(H1); + C = isl_mat_inverse_product(H1, C); + if (!C) + goto error; + isl_mat_free(H); + if (!isl_int_is_one(C->row[0][0])) { + isl_int g; + + isl_int_init(g); + for (i = 0; i < B->n_row; ++i) { + isl_seq_gcd(C->row[1 + i] + 1, first, &g); + isl_int_gcd(g, g, C->row[0][0]); + if (!isl_int_is_divisible_by(C->row[1 + i][0], g)) + break; + } + isl_int_clear(g); + + if (i < B->n_row) + return empty_compression(ctx, dim, T2, B, C, U); + C = isl_mat_normalize(C); + } + U1 = isl_mat_sub_alloc(U, 0, U->n_row, 0, B->n_row); + U1 = isl_mat_lin_to_aff(U1); + U2 = isl_mat_sub_alloc(U, 0, U->n_row, B->n_row, U->n_row - B->n_row); + U2 = isl_mat_lin_to_aff(U2); + isl_mat_free(U); + C = isl_mat_product(U1, C); + C = isl_mat_aff_direct_sum(C, U2); + C = insert_parameter_rows(C, first); + + isl_mat_free(B); + + return C; +error: + isl_mat_free(B); + isl_mat_free(H); + isl_mat_free(U); + if (T2) { + isl_mat_free(*T2); + *T2 = NULL; + } + return NULL; +} + +/* Given a set of equalities + * + * M x - c = 0 + * + * this function computes a unimodular transformation from a lower-dimensional + * space to the original space that bijectively maps the integer points x' + * in the lower-dimensional space to the integer points x in the original + * space that satisfy the equalities. + * + * The input is given as a matrix B = [ -c M ] and the output is a + * matrix that maps [1 x'] to [1 x]. + * The number of equality constraints in B is assumed to be smaller than + * or equal to the number of variables x. + * If T2 is not NULL, then *T2 is set to a matrix mapping [1 x] to [1 x']. + */ +__isl_give isl_mat *isl_mat_variable_compression(__isl_take isl_mat *B, + __isl_give isl_mat **T2) +{ + return isl_mat_final_variable_compression(B, 0, T2); +} + +/* Return "bset" and set *T and *T2 to the identity transformation + * on "bset" (provided T and T2 are not NULL). + */ +static __isl_give isl_basic_set *return_with_identity( + __isl_take isl_basic_set *bset, __isl_give isl_mat **T, + __isl_give isl_mat **T2) +{ + isl_size dim; + isl_mat *id; + + dim = isl_basic_set_dim(bset, isl_dim_set); + if (dim < 0) + return isl_basic_set_free(bset); + if (!T && !T2) + return bset; + + id = isl_mat_identity(isl_basic_map_get_ctx(bset), 1 + dim); + if (T) + *T = isl_mat_copy(id); + if (T2) + *T2 = isl_mat_copy(id); + isl_mat_free(id); + + return bset; +} + +/* Use the n equalities of bset to unimodularly transform the + * variables x such that n transformed variables x1' have a constant value + * and rewrite the constraints of bset in terms of the remaining + * transformed variables x2'. The matrix pointed to by T maps + * the new variables x2' back to the original variables x, while T2 + * maps the original variables to the new variables. + */ +static __isl_give isl_basic_set *compress_variables( + __isl_take isl_basic_set *bset, + __isl_give isl_mat **T, __isl_give isl_mat **T2) +{ + struct isl_mat *B, *TC; + isl_size dim; + + if (T) + *T = NULL; + if (T2) + *T2 = NULL; + if (isl_basic_set_check_no_params(bset) < 0 || + isl_basic_set_check_no_locals(bset) < 0) + return isl_basic_set_free(bset); + dim = isl_basic_set_dim(bset, isl_dim_set); + if (dim < 0) + return isl_basic_set_free(bset); + isl_assert(bset->ctx, bset->n_eq <= dim, goto error); + if (bset->n_eq == 0) + return return_with_identity(bset, T, T2); + + B = isl_mat_sub_alloc6(bset->ctx, bset->eq, 0, bset->n_eq, 0, 1 + dim); + TC = isl_mat_variable_compression(B, T2); + if (!TC) + goto error; + if (TC->n_col == 0) { + isl_mat_free(TC); + if (T2) { + isl_mat_free(*T2); + *T2 = NULL; + } + bset = isl_basic_set_set_to_empty(bset); + return return_with_identity(bset, T, T2); + } + + bset = isl_basic_set_preimage(bset, T ? isl_mat_copy(TC) : TC); + if (T) + *T = TC; + return bset; +error: + isl_basic_set_free(bset); + return NULL; +} + +__isl_give isl_basic_set *isl_basic_set_remove_equalities( + __isl_take isl_basic_set *bset, __isl_give isl_mat **T, + __isl_give isl_mat **T2) +{ + if (T) + *T = NULL; + if (T2) + *T2 = NULL; + if (isl_basic_set_check_no_params(bset) < 0) + return isl_basic_set_free(bset); + bset = isl_basic_set_gauss(bset, NULL); + if (ISL_F_ISSET(bset, ISL_BASIC_SET_EMPTY)) + return return_with_identity(bset, T, T2); + bset = compress_variables(bset, T, T2); + return bset; +} + +/* Check if dimension dim belongs to a residue class + * i_dim \equiv r mod m + * with m != 1 and if so return m in *modulo and r in *residue. + * As a special case, when i_dim has a fixed value v, then + * *modulo is set to 0 and *residue to v. + * + * If i_dim does not belong to such a residue class, then *modulo + * is set to 1 and *residue is set to 0. + */ +isl_stat isl_basic_set_dim_residue_class(__isl_keep isl_basic_set *bset, + int pos, isl_int *modulo, isl_int *residue) +{ + isl_bool fixed; + struct isl_ctx *ctx; + struct isl_mat *H = NULL, *U = NULL, *C, *H1, *U1; + isl_size total; + isl_size nparam; + + if (!bset || !modulo || !residue) + return isl_stat_error; + + fixed = isl_basic_set_plain_dim_is_fixed(bset, pos, residue); + if (fixed < 0) + return isl_stat_error; + if (fixed) { + isl_int_set_si(*modulo, 0); + return isl_stat_ok; + } + + ctx = isl_basic_set_get_ctx(bset); + total = isl_basic_set_dim(bset, isl_dim_all); + nparam = isl_basic_set_dim(bset, isl_dim_param); + if (total < 0 || nparam < 0) + return isl_stat_error; + H = isl_mat_sub_alloc6(ctx, bset->eq, 0, bset->n_eq, 1, total); + H = isl_mat_left_hermite(H, 0, &U, NULL); + if (!H) + return isl_stat_error; + + isl_seq_gcd(U->row[nparam + pos]+bset->n_eq, + total-bset->n_eq, modulo); + if (isl_int_is_zero(*modulo)) + isl_int_set_si(*modulo, 1); + if (isl_int_is_one(*modulo)) { + isl_int_set_si(*residue, 0); + isl_mat_free(H); + isl_mat_free(U); + return isl_stat_ok; + } + + C = isl_mat_alloc(ctx, 1 + bset->n_eq, 1); + if (!C) + goto error; + isl_int_set_si(C->row[0][0], 1); + isl_mat_sub_neg(ctx, C->row + 1, bset->eq, bset->n_eq, 0, 0, 1); + H1 = isl_mat_sub_alloc(H, 0, H->n_row, 0, H->n_row); + H1 = isl_mat_lin_to_aff(H1); + C = isl_mat_inverse_product(H1, C); + isl_mat_free(H); + U1 = isl_mat_sub_alloc(U, nparam+pos, 1, 0, bset->n_eq); + U1 = isl_mat_lin_to_aff(U1); + isl_mat_free(U); + C = isl_mat_product(U1, C); + if (!C) + return isl_stat_error; + if (!isl_int_is_divisible_by(C->row[1][0], C->row[0][0])) { + bset = isl_basic_set_copy(bset); + bset = isl_basic_set_set_to_empty(bset); + isl_basic_set_free(bset); + isl_int_set_si(*modulo, 1); + isl_int_set_si(*residue, 0); + return isl_stat_ok; + } + isl_int_divexact(*residue, C->row[1][0], C->row[0][0]); + isl_int_fdiv_r(*residue, *residue, *modulo); + isl_mat_free(C); + return isl_stat_ok; +error: + isl_mat_free(H); + isl_mat_free(U); + return isl_stat_error; +} + +/* Check if dimension dim belongs to a residue class + * i_dim \equiv r mod m + * with m != 1 and if so return m in *modulo and r in *residue. + * As a special case, when i_dim has a fixed value v, then + * *modulo is set to 0 and *residue to v. + * + * If i_dim does not belong to such a residue class, then *modulo + * is set to 1 and *residue is set to 0. + */ +isl_stat isl_set_dim_residue_class(__isl_keep isl_set *set, + int pos, isl_int *modulo, isl_int *residue) +{ + isl_int m; + isl_int r; + int i; + + if (!set || !modulo || !residue) + return isl_stat_error; + + if (set->n == 0) { + isl_int_set_si(*modulo, 0); + isl_int_set_si(*residue, 0); + return isl_stat_ok; + } + + if (isl_basic_set_dim_residue_class(set->p[0], pos, modulo, residue)<0) + return isl_stat_error; + + if (set->n == 1) + return isl_stat_ok; + + if (isl_int_is_one(*modulo)) + return isl_stat_ok; + + isl_int_init(m); + isl_int_init(r); + + for (i = 1; i < set->n; ++i) { + if (isl_basic_set_dim_residue_class(set->p[i], pos, &m, &r) < 0) + goto error; + isl_int_gcd(*modulo, *modulo, m); + isl_int_sub(m, *residue, r); + isl_int_gcd(*modulo, *modulo, m); + if (!isl_int_is_zero(*modulo)) + isl_int_fdiv_r(*residue, *residue, *modulo); + if (isl_int_is_one(*modulo)) + break; + } + + isl_int_clear(m); + isl_int_clear(r); + + return isl_stat_ok; +error: + isl_int_clear(m); + isl_int_clear(r); + return isl_stat_error; +} + +/* Check if dimension "dim" belongs to a residue class + * i_dim \equiv r mod m + * with m != 1 and if so return m in *modulo and r in *residue. + * As a special case, when i_dim has a fixed value v, then + * *modulo is set to 0 and *residue to v. + * + * If i_dim does not belong to such a residue class, then *modulo + * is set to 1 and *residue is set to 0. + */ +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) +{ + *modulo = NULL; + *residue = NULL; + if (!set) + return isl_stat_error; + *modulo = isl_val_alloc(isl_set_get_ctx(set)); + *residue = isl_val_alloc(isl_set_get_ctx(set)); + if (!*modulo || !*residue) + goto error; + if (isl_set_dim_residue_class(set, pos, + &(*modulo)->n, &(*residue)->n) < 0) + goto error; + isl_int_set_si((*modulo)->d, 1); + isl_int_set_si((*residue)->d, 1); + return isl_stat_ok; +error: + isl_val_free(*modulo); + isl_val_free(*residue); + return isl_stat_error; +} diff --git a/external/mit/isl/dist/isl_equalities.h b/external/mit/isl/dist/isl_equalities.h new file mode 100644 index 000000000000..05c69ddd8d97 --- /dev/null +++ b/external/mit/isl/dist/isl_equalities.h @@ -0,0 +1,36 @@ +/* + * 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_EQUALITIES_H +#define ISL_EQUALITIES_H + +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +__isl_give isl_mat *isl_mat_final_variable_compression(__isl_take isl_mat *B, + int first, __isl_give isl_mat **T2); +__isl_give isl_mat *isl_mat_variable_compression(__isl_take isl_mat *B, + __isl_give isl_mat **T2); +__isl_give isl_mat *isl_mat_parameter_compression(__isl_take isl_mat *B, + __isl_take isl_vec *d); +__isl_give isl_mat *isl_mat_parameter_compression_ext(__isl_take isl_mat *B, + __isl_take isl_mat *A); +__isl_give isl_basic_set *isl_basic_set_remove_equalities( + __isl_take isl_basic_set *bset, __isl_give isl_mat **T, + __isl_give isl_mat **T2); + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/external/mit/isl/dist/isl_factorization.c b/external/mit/isl/dist/isl_factorization.c new file mode 100644 index 000000000000..bd4a259d930a --- /dev/null +++ b/external/mit/isl/dist/isl_factorization.c @@ -0,0 +1,389 @@ +/* + * Copyright 2005-2007 Universiteit Leiden + * Copyright 2008-2009 Katholieke Universiteit Leuven + * Copyright 2010 INRIA Saclay + * + * Use of this software is governed by the MIT license + * + * Written by Sven Verdoolaege, Leiden Institute of Advanced Computer Science, + * Universiteit Leiden, Niels Bohrweg 1, 2333 CA Leiden, The Netherlands + * and 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 + */ + +#include +#include +#include +#include + +/* Return the isl_ctx to which "f" belongs. + */ +isl_ctx *isl_factorizer_get_ctx(__isl_keep isl_factorizer *f) +{ + if (!f) + return NULL; + return isl_basic_set_get_ctx(f->bset); +} + +static __isl_give isl_factorizer *isl_factorizer_alloc( + __isl_keep isl_basic_set *bset, __isl_take isl_morph *morph, + int n_group) +{ + isl_factorizer *f = NULL; + int *len = NULL; + + if (!morph) + return NULL; + + if (n_group > 0) { + len = isl_alloc_array(morph->dom->ctx, int, n_group); + if (!len) + goto error; + } + + f = isl_alloc_type(morph->dom->ctx, struct isl_factorizer); + if (!f) + goto error; + + f->bset = isl_basic_set_copy(bset); + f->morph = morph; + f->n_group = n_group; + f->len = len; + + return f; +error: + free(len); + isl_morph_free(morph); + return NULL; +} + +__isl_null isl_factorizer *isl_factorizer_free(__isl_take isl_factorizer *f) +{ + if (!f) + return NULL; + + isl_basic_set_free(f->bset); + isl_morph_free(f->morph); + free(f->len); + free(f); + return NULL; +} + +void isl_factorizer_dump(__isl_take isl_factorizer *f) +{ + int i; + + if (!f) + return; + + isl_morph_print_internal(f->morph, stderr); + fprintf(stderr, "["); + for (i = 0; i < f->n_group; ++i) { + if (i) + fprintf(stderr, ", "); + fprintf(stderr, "%d", f->len[i]); + } + fprintf(stderr, "]\n"); +} + +__isl_give isl_factorizer *isl_factorizer_identity(__isl_keep isl_basic_set *bset) +{ + return isl_factorizer_alloc(bset, isl_morph_identity(bset), 0); +} + +__isl_give isl_factorizer *isl_factorizer_groups(__isl_keep isl_basic_set *bset, + __isl_take isl_mat *Q, __isl_take isl_mat *U, int n, int *len) +{ + int i; + isl_size nvar, off; + isl_space *space; + isl_basic_set *dom; + isl_basic_set *ran; + isl_morph *morph; + isl_factorizer *f; + isl_mat *id; + + nvar = isl_basic_set_dim(bset, isl_dim_set); + off = isl_basic_set_var_offset(bset, isl_dim_set); + if (nvar < 0 || off < 0 || !Q || !U) + goto error; + + id = isl_mat_identity(bset->ctx, 1 + off); + Q = isl_mat_diagonal(isl_mat_copy(id), Q); + U = isl_mat_diagonal(id, U); + + space = isl_basic_set_get_space(bset); + dom = isl_basic_set_universe(isl_space_copy(space)); + space = isl_space_drop_dims(space, isl_dim_set, 0, nvar); + space = isl_space_add_dims(space, isl_dim_set, nvar); + ran = isl_basic_set_universe(space); + morph = isl_morph_alloc(dom, ran, Q, U); + f = isl_factorizer_alloc(bset, morph, n); + if (!f) + return NULL; + for (i = 0; i < n; ++i) + f->len[i] = len[i]; + return f; +error: + isl_mat_free(Q); + isl_mat_free(U); + return NULL; +} + +struct isl_factor_groups { + int *pos; /* for each column: row position of pivot */ + int *group; /* group to which a column belongs */ + int *cnt; /* number of columns in the group */ + int *rowgroup; /* group to which a constraint belongs */ +}; + +/* Initialize isl_factor_groups structure: find pivot row positions, + * each column initially belongs to its own group and the groups + * of the constraints are still unknown. + */ +static int init_groups(struct isl_factor_groups *g, __isl_keep isl_mat *H) +{ + int i, j; + + if (!H) + return -1; + + g->pos = isl_alloc_array(H->ctx, int, H->n_col); + g->group = isl_alloc_array(H->ctx, int, H->n_col); + g->cnt = isl_alloc_array(H->ctx, int, H->n_col); + g->rowgroup = isl_alloc_array(H->ctx, int, H->n_row); + + if (!g->pos || !g->group || !g->cnt || !g->rowgroup) + return -1; + + for (i = 0; i < H->n_row; ++i) + g->rowgroup[i] = -1; + for (i = 0, j = 0; i < H->n_col; ++i) { + for ( ; j < H->n_row; ++j) + if (!isl_int_is_zero(H->row[j][i])) + break; + g->pos[i] = j; + } + for (i = 0; i < H->n_col; ++i) { + g->group[i] = i; + g->cnt[i] = 1; + } + + return 0; +} + +/* Update group[k] to the group column k belongs to. + * When merging two groups, only the group of the current + * group leader is changed. Here we change the group of + * the other members to also point to the group that the + * old group leader now points to. + */ +static void update_group(struct isl_factor_groups *g, int k) +{ + int p = g->group[k]; + while (g->cnt[p] == 0) + p = g->group[p]; + g->group[k] = p; +} + +/* Merge group i with all groups of the subsequent columns + * with non-zero coefficients in row j of H. + * (The previous columns are all zero; otherwise we would have handled + * the row before.) + */ +static int update_group_i_with_row_j(struct isl_factor_groups *g, int i, int j, + __isl_keep isl_mat *H) +{ + int k; + + g->rowgroup[j] = g->group[i]; + for (k = i + 1; k < H->n_col && j >= g->pos[k]; ++k) { + update_group(g, k); + update_group(g, i); + if (g->group[k] != g->group[i] && + !isl_int_is_zero(H->row[j][k])) { + isl_assert(H->ctx, g->cnt[g->group[k]] != 0, return -1); + isl_assert(H->ctx, g->cnt[g->group[i]] != 0, return -1); + if (g->group[i] < g->group[k]) { + g->cnt[g->group[i]] += g->cnt[g->group[k]]; + g->cnt[g->group[k]] = 0; + g->group[g->group[k]] = g->group[i]; + } else { + g->cnt[g->group[k]] += g->cnt[g->group[i]]; + g->cnt[g->group[i]] = 0; + g->group[g->group[i]] = g->group[k]; + } + } + } + + return 0; +} + +/* Update the group information based on the constraint matrix. + */ +static int update_groups(struct isl_factor_groups *g, __isl_keep isl_mat *H) +{ + int i, j; + + for (i = 0; i < H->n_col && g->cnt[0] < H->n_col; ++i) { + if (g->pos[i] == H->n_row) + continue; /* A line direction */ + if (g->rowgroup[g->pos[i]] == -1) + g->rowgroup[g->pos[i]] = i; + for (j = g->pos[i] + 1; j < H->n_row; ++j) { + if (isl_int_is_zero(H->row[j][i])) + continue; + if (g->rowgroup[j] != -1) + continue; + if (update_group_i_with_row_j(g, i, j, H) < 0) + return -1; + } + } + for (i = 1; i < H->n_col; ++i) + update_group(g, i); + + return 0; +} + +static void clear_groups(struct isl_factor_groups *g) +{ + if (!g) + return; + free(g->pos); + free(g->group); + free(g->cnt); + free(g->rowgroup); +} + +/* Determine if the set variables of the basic set can be factorized and + * return the results in an isl_factorizer. + * + * The algorithm works by first computing the Hermite normal form + * and then grouping columns linked by one or more constraints together, + * where a constraints "links" two or more columns if the constraint + * has nonzero coefficients in the columns. + */ +__isl_give isl_factorizer *isl_basic_set_factorizer( + __isl_keep isl_basic_set *bset) +{ + int i, j, n, done; + isl_mat *H, *U, *Q; + isl_size nvar, first; + struct isl_factor_groups g = { 0 }; + isl_factorizer *f; + + nvar = isl_basic_set_dim(bset, isl_dim_set); + first = isl_basic_set_var_offset(bset, isl_dim_set); + if (nvar < 0 || first < 0 || isl_basic_set_check_no_locals(bset) < 0) + return NULL; + + if (nvar <= 1) + return isl_factorizer_identity(bset); + + H = isl_mat_alloc(bset->ctx, bset->n_eq + bset->n_ineq, nvar); + if (!H) + return NULL; + isl_mat_sub_copy(bset->ctx, H->row, bset->eq, bset->n_eq, + 0, 1 + first, nvar); + isl_mat_sub_copy(bset->ctx, H->row + bset->n_eq, bset->ineq, bset->n_ineq, + 0, 1 + first, nvar); + H = isl_mat_left_hermite(H, 0, &U, &Q); + + if (init_groups(&g, H) < 0) + goto error; + if (update_groups(&g, H) < 0) + goto error; + + if (g.cnt[0] == nvar) { + isl_mat_free(H); + isl_mat_free(U); + isl_mat_free(Q); + clear_groups(&g); + + return isl_factorizer_identity(bset); + } + + done = 0; + n = 0; + while (done != nvar) { + int group = g.group[done]; + for (i = 1; i < g.cnt[group]; ++i) { + if (g.group[done + i] == group) + continue; + for (j = done + g.cnt[group]; j < nvar; ++j) + if (g.group[j] == group) + break; + if (j == nvar) + isl_die(bset->ctx, isl_error_internal, + "internal error", goto error); + g.group[j] = g.group[done + i]; + Q = isl_mat_swap_rows(Q, done + i, j); + U = isl_mat_swap_cols(U, done + i, j); + } + done += g.cnt[group]; + g.pos[n++] = g.cnt[group]; + } + + f = isl_factorizer_groups(bset, Q, U, n, g.pos); + + isl_mat_free(H); + clear_groups(&g); + + return f; +error: + isl_mat_free(H); + isl_mat_free(U); + isl_mat_free(Q); + clear_groups(&g); + return NULL; +} + +/* Given the factorizer "f" of a basic set, + * call "test" on each resulting factor as long as each call succeeds. + */ +__isl_give isl_bool isl_factorizer_every_factor_basic_set( + __isl_keep isl_factorizer *f, + isl_bool (*test)(__isl_keep isl_basic_set *bset, void *user), + void *user) +{ + int i, n; + isl_bool every = isl_bool_true; + isl_size nparam, nvar; + isl_basic_set *bset; + + if (!f) + return isl_bool_error; + nparam = isl_basic_set_dim(f->bset, isl_dim_param); + nvar = isl_basic_set_dim(f->bset, isl_dim_set); + if (nparam < 0 || nvar < 0) + return isl_bool_error; + + bset = isl_basic_set_copy(f->bset); + bset = isl_morph_basic_set(isl_morph_copy(f->morph), bset); + + for (i = 0, n = 0; i < f->n_group; ++i) { + isl_basic_set *factor; + + factor = isl_basic_set_copy(bset); + factor = isl_basic_set_drop_constraints_involving(factor, + nparam + n + f->len[i], nvar - n - f->len[i]); + factor = isl_basic_set_drop_constraints_involving(factor, + nparam, n); + factor = isl_basic_set_drop(factor, isl_dim_set, + n + f->len[i], nvar - n - f->len[i]); + factor = isl_basic_set_drop(factor, isl_dim_set, 0, n); + every = test(factor, user); + isl_basic_set_free(factor); + + if (every < 0 || !every) + break; + + n += f->len[i]; + } + + isl_basic_set_free(bset); + + return every; +} diff --git a/external/mit/isl/dist/isl_factorization.h b/external/mit/isl/dist/isl_factorization.h new file mode 100644 index 000000000000..8b9bf76be3c3 --- /dev/null +++ b/external/mit/isl/dist/isl_factorization.h @@ -0,0 +1,42 @@ +#ifndef ISL_FACTORIZATION_H +#define ISL_FACTORIZATION_H + +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +/* Data for factorizing the basic set "bset". + * After applying "morph" to the basic set, there are "n_group" + * groups of consecutive set variables, each of length "len[i]", + * with 0 <= i < n_group. + * If no factorization is possible, then "n_group" is set to 0. + */ +struct isl_factorizer { + isl_basic_set *bset; + isl_morph *morph; + int n_group; + int *len; +}; +typedef struct isl_factorizer isl_factorizer; + +__isl_give isl_factorizer *isl_basic_set_factorizer( + __isl_keep isl_basic_set *bset); + +isl_ctx *isl_factorizer_get_ctx(__isl_keep isl_factorizer *f); + +__isl_null isl_factorizer *isl_factorizer_free(__isl_take isl_factorizer *f); +void isl_factorizer_dump(__isl_take isl_factorizer *f); + +__isl_give isl_bool isl_factorizer_every_factor_basic_set( + __isl_keep isl_factorizer *f, + isl_bool (*test)(__isl_keep isl_basic_set *bset, void *user), + void *user); + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/external/mit/isl/dist/isl_farkas.c b/external/mit/isl/dist/isl_farkas.c new file mode 100644 index 000000000000..4ff6d8a4059d --- /dev/null +++ b/external/mit/isl/dist/isl_farkas.c @@ -0,0 +1,966 @@ +/* + * Copyright 2010 INRIA Saclay + * + * 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 + */ + +#include +#include +#include +#include +#include +#include +#include + +/* + * Let C be a cone and define + * + * C' := { y | forall x in C : y x >= 0 } + * + * C' contains the coefficients of all linear constraints + * that are valid for C. + * Furthermore, C'' = C. + * + * If C is defined as { x | A x >= 0 } + * then any element in C' must be a non-negative combination + * of the rows of A, i.e., y = t A with t >= 0. That is, + * + * C' = { y | exists t >= 0 : y = t A } + * + * If any of the rows in A actually represents an equality, then + * also negative combinations of this row are allowed and so the + * non-negativity constraint on the corresponding element of t + * can be dropped. + * + * A polyhedron P = { x | b + A x >= 0 } can be represented + * in homogeneous coordinates by the cone + * C = { [z,x] | b z + A x >= and z >= 0 } + * The valid linear constraints on C correspond to the valid affine + * constraints on P. + * This is essentially Farkas' lemma. + * + * Since + * [ 1 0 ] + * [ w y ] = [t_0 t] [ b A ] + * + * we have + * + * C' = { w, y | exists t_0, t >= 0 : y = t A and w = t_0 + t b } + * or + * + * C' = { w, y | exists t >= 0 : y = t A and w - t b >= 0 } + * + * In practice, we introduce an extra variable (w), shifting all + * other variables to the right, and an extra inequality + * (w - t b >= 0) corresponding to the positivity constraint on + * the homogeneous coordinate. + * + * When going back from coefficients to solutions, we immediately + * plug in 1 for z, which corresponds to shifting all variables + * to the left, with the leftmost ending up in the constant position. + */ + +/* Add the given prefix to all named isl_dim_set dimensions in "space". + */ +static __isl_give isl_space *isl_space_prefix(__isl_take isl_space *space, + const char *prefix) +{ + int i; + isl_ctx *ctx; + isl_size nvar; + size_t prefix_len = strlen(prefix); + + if (!space) + return NULL; + + ctx = isl_space_get_ctx(space); + nvar = isl_space_dim(space, isl_dim_set); + if (nvar < 0) + return isl_space_free(space); + + for (i = 0; i < nvar; ++i) { + const char *name; + char *prefix_name; + + name = isl_space_get_dim_name(space, isl_dim_set, i); + if (!name) + continue; + + prefix_name = isl_alloc_array(ctx, char, + prefix_len + strlen(name) + 1); + if (!prefix_name) + goto error; + memcpy(prefix_name, prefix, prefix_len); + strcpy(prefix_name + prefix_len, name); + + space = isl_space_set_dim_name(space, + isl_dim_set, i, prefix_name); + free(prefix_name); + } + + return space; +error: + isl_space_free(space); + return NULL; +} + +/* Given a dimension specification of the solutions space, construct + * a dimension specification for the space of coefficients. + * + * In particular transform + * + * [params] -> { S } + * + * to + * + * { coefficients[[cst, params] -> S] } + * + * and prefix each dimension name with "c_". + */ +static __isl_give isl_space *isl_space_coefficients(__isl_take isl_space *space) +{ + isl_space *space_param; + isl_size nvar; + isl_size nparam; + + nvar = isl_space_dim(space, isl_dim_set); + nparam = isl_space_dim(space, isl_dim_param); + if (nvar < 0 || nparam < 0) + return isl_space_free(space); + space_param = isl_space_copy(space); + space_param = isl_space_drop_dims(space_param, isl_dim_set, 0, nvar); + space_param = isl_space_move_dims(space_param, isl_dim_set, 0, + isl_dim_param, 0, nparam); + space_param = isl_space_prefix(space_param, "c_"); + space_param = isl_space_insert_dims(space_param, isl_dim_set, 0, 1); + space_param = isl_space_set_dim_name(space_param, + isl_dim_set, 0, "c_cst"); + space = isl_space_drop_dims(space, isl_dim_param, 0, nparam); + space = isl_space_prefix(space, "c_"); + space = isl_space_join(isl_space_from_domain(space_param), + isl_space_from_range(space)); + space = isl_space_wrap(space); + space = isl_space_set_tuple_name(space, isl_dim_set, "coefficients"); + + return space; +} + +/* Drop the given prefix from all named dimensions of type "type" in "space". + */ +static __isl_give isl_space *isl_space_unprefix(__isl_take isl_space *space, + enum isl_dim_type type, const char *prefix) +{ + int i; + isl_size n; + size_t prefix_len = strlen(prefix); + + n = isl_space_dim(space, type); + if (n < 0) + return isl_space_free(space); + + for (i = 0; i < n; ++i) { + const char *name; + + name = isl_space_get_dim_name(space, type, i); + if (!name) + continue; + if (strncmp(name, prefix, prefix_len)) + continue; + + space = isl_space_set_dim_name(space, + type, i, name + prefix_len); + } + + return space; +} + +/* Given a dimension specification of the space of coefficients, construct + * a dimension specification for the space of solutions. + * + * In particular transform + * + * { coefficients[[cst, params] -> S] } + * + * to + * + * [params] -> { S } + * + * and drop the "c_" prefix from the dimension names. + */ +static __isl_give isl_space *isl_space_solutions(__isl_take isl_space *space) +{ + isl_size nparam; + + space = isl_space_unwrap(space); + space = isl_space_drop_dims(space, isl_dim_in, 0, 1); + space = isl_space_unprefix(space, isl_dim_in, "c_"); + space = isl_space_unprefix(space, isl_dim_out, "c_"); + nparam = isl_space_dim(space, isl_dim_in); + if (nparam < 0) + return isl_space_free(space); + space = isl_space_move_dims(space, + isl_dim_param, 0, isl_dim_in, 0, nparam); + space = isl_space_range(space); + + return space; +} + +/* Return the rational universe basic set in the given space. + */ +static __isl_give isl_basic_set *rational_universe(__isl_take isl_space *space) +{ + isl_basic_set *bset; + + bset = isl_basic_set_universe(space); + bset = isl_basic_set_set_rational(bset); + + return bset; +} + +/* Compute the dual of "bset" by applying Farkas' lemma. + * As explained above, we add an extra dimension to represent + * the coefficient of the constant term when going from solutions + * to coefficients (shift == 1) and we drop the extra dimension when going + * in the opposite direction (shift == -1). + * The dual can be created in an arbitrary space. + * The caller is responsible for putting the result in the appropriate space. + * + * If "bset" is (obviously) empty, then the way this emptiness + * is represented by the constraints does not allow for the application + * of the standard farkas algorithm. We therefore handle this case + * specifically and return the universe basic set. + */ +static __isl_give isl_basic_set *farkas(__isl_take isl_basic_set *bset, + int shift) +{ + int i, j, k; + isl_ctx *ctx; + isl_space *space; + isl_basic_set *dual = NULL; + isl_size total; + + total = isl_basic_set_dim(bset, isl_dim_all); + if (total < 0) + return isl_basic_set_free(bset); + + ctx = isl_basic_set_get_ctx(bset); + space = isl_space_set_alloc(ctx, 0, total + shift); + if (isl_basic_set_plain_is_empty(bset)) { + isl_basic_set_free(bset); + return rational_universe(space); + } + + dual = isl_basic_set_alloc_space(space, bset->n_eq + bset->n_ineq, + total, bset->n_ineq + (shift > 0)); + dual = isl_basic_set_set_rational(dual); + + for (i = 0; i < bset->n_eq + bset->n_ineq; ++i) { + k = isl_basic_set_alloc_div(dual); + if (k < 0) + goto error; + isl_int_set_si(dual->div[k][0], 0); + } + + for (i = 0; i < total; ++i) { + k = isl_basic_set_alloc_equality(dual); + if (k < 0) + goto error; + isl_seq_clr(dual->eq[k], 1 + shift + total); + isl_int_set_si(dual->eq[k][1 + shift + i], -1); + for (j = 0; j < bset->n_eq; ++j) + isl_int_set(dual->eq[k][1 + shift + total + j], + bset->eq[j][1 + i]); + for (j = 0; j < bset->n_ineq; ++j) + isl_int_set(dual->eq[k][1 + shift + total + bset->n_eq + j], + bset->ineq[j][1 + i]); + } + + for (i = 0; i < bset->n_ineq; ++i) { + k = isl_basic_set_alloc_inequality(dual); + if (k < 0) + goto error; + isl_seq_clr(dual->ineq[k], + 1 + shift + total + bset->n_eq + bset->n_ineq); + isl_int_set_si(dual->ineq[k][1 + shift + total + bset->n_eq + i], 1); + } + + if (shift > 0) { + k = isl_basic_set_alloc_inequality(dual); + if (k < 0) + goto error; + isl_seq_clr(dual->ineq[k], 2 + total); + isl_int_set_si(dual->ineq[k][1], 1); + for (j = 0; j < bset->n_eq; ++j) + isl_int_neg(dual->ineq[k][2 + total + j], + bset->eq[j][0]); + for (j = 0; j < bset->n_ineq; ++j) + isl_int_neg(dual->ineq[k][2 + total + bset->n_eq + j], + bset->ineq[j][0]); + } + + dual = isl_basic_set_remove_divs(dual); + dual = isl_basic_set_simplify(dual); + dual = isl_basic_set_finalize(dual); + + isl_basic_set_free(bset); + return dual; +error: + isl_basic_set_free(bset); + isl_basic_set_free(dual); + return NULL; +} + +/* Construct a basic set containing the tuples of coefficients of all + * valid affine constraints on the given basic set, ignoring + * the space of input and output and without any further decomposition. + */ +static __isl_give isl_basic_set *isl_basic_set_coefficients_base( + __isl_take isl_basic_set *bset) +{ + return farkas(bset, 1); +} + +/* Return the inverse mapping of "morph". + */ +static __isl_give isl_mat *peek_inv(__isl_keep isl_morph *morph) +{ + return morph ? morph->inv : NULL; +} + +/* Return a copy of the inverse mapping of "morph". + */ +static __isl_give isl_mat *get_inv(__isl_keep isl_morph *morph) +{ + return isl_mat_copy(peek_inv(morph)); +} + +/* Information about a single factor within isl_basic_set_coefficients_product. + * + * "start" is the position of the first coefficient (beyond + * the one corresponding to the constant term) in this factor. + * "dim" is the number of coefficients (other than + * the one corresponding to the constant term) in this factor. + * "n_line" is the number of lines in "coeff". + * "n_ray" is the number of rays (other than lines) in "coeff". + * "n_vertex" is the number of vertices in "coeff". + * + * While iterating over the vertices, + * "pos" represents the inequality constraint corresponding + * to the current vertex. + */ +struct isl_coefficients_factor_data { + isl_basic_set *coeff; + int start; + int dim; + int n_line; + int n_ray; + int n_vertex; + int pos; +}; + +/* Internal data structure for isl_basic_set_coefficients_product. + * "n" is the number of factors in the factorization. + * "pos" is the next factor that will be considered. + * "start_next" is the position of the first coefficient (beyond + * the one corresponding to the constant term) in the next factor. + * "factors" contains information about the individual "n" factors. + */ +struct isl_coefficients_product_data { + int n; + int pos; + int start_next; + struct isl_coefficients_factor_data *factors; +}; + +/* Initialize the internal data structure for + * isl_basic_set_coefficients_product. + */ +static isl_stat isl_coefficients_product_data_init(isl_ctx *ctx, + struct isl_coefficients_product_data *data, int n) +{ + data->n = n; + data->pos = 0; + data->start_next = 0; + data->factors = isl_calloc_array(ctx, + struct isl_coefficients_factor_data, n); + if (!data->factors) + return isl_stat_error; + return isl_stat_ok; +} + +/* Free all memory allocated in "data". + */ +static void isl_coefficients_product_data_clear( + struct isl_coefficients_product_data *data) +{ + int i; + + if (data->factors) { + for (i = 0; i < data->n; ++i) { + isl_basic_set_free(data->factors[i].coeff); + } + } + free(data->factors); +} + +/* Does inequality "ineq" in the (dual) basic set "bset" represent a ray? + * In particular, does it have a zero denominator + * (i.e., a zero coefficient for the constant term)? + */ +static int is_ray(__isl_keep isl_basic_set *bset, int ineq) +{ + return isl_int_is_zero(bset->ineq[ineq][1]); +} + +/* isl_factorizer_every_factor_basic_set callback that + * constructs a basic set containing the tuples of coefficients of all + * valid affine constraints on the factor "bset" and + * extracts further information that will be used + * when combining the results over the different factors. + */ +static isl_bool isl_basic_set_coefficients_factor( + __isl_keep isl_basic_set *bset, void *user) +{ + struct isl_coefficients_product_data *data = user; + isl_basic_set *coeff; + isl_size n_eq, n_ineq, dim; + int i, n_ray, n_vertex; + + coeff = isl_basic_set_coefficients_base(isl_basic_set_copy(bset)); + data->factors[data->pos].coeff = coeff; + if (!coeff) + return isl_bool_error; + + dim = isl_basic_set_dim(bset, isl_dim_set); + n_eq = isl_basic_set_n_equality(coeff); + n_ineq = isl_basic_set_n_inequality(coeff); + if (dim < 0 || n_eq < 0 || n_ineq < 0) + return isl_bool_error; + n_ray = n_vertex = 0; + for (i = 0; i < n_ineq; ++i) { + if (is_ray(coeff, i)) + n_ray++; + else + n_vertex++; + } + data->factors[data->pos].start = data->start_next; + data->factors[data->pos].dim = dim; + data->factors[data->pos].n_line = n_eq; + data->factors[data->pos].n_ray = n_ray; + data->factors[data->pos].n_vertex = n_vertex; + data->pos++; + data->start_next += dim; + + return isl_bool_true; +} + +/* Clear an entry in the product, given that there is a "total" number + * of coefficients (other than that of the constant term). + */ +static void clear_entry(isl_int *entry, int total) +{ + isl_seq_clr(entry, 1 + 1 + total); +} + +/* Set the part of the entry corresponding to factor "data", + * from the factor coefficients in "src". + */ +static void set_factor(isl_int *entry, isl_int *src, + struct isl_coefficients_factor_data *data) +{ + isl_seq_cpy(entry + 1 + 1 + data->start, src + 1 + 1, data->dim); +} + +/* Set the part of the entry corresponding to factor "data", + * from the factor coefficients in "src" multiplied by "f". + */ +static void scale_factor(isl_int *entry, isl_int *src, isl_int f, + struct isl_coefficients_factor_data *data) +{ + isl_seq_scale(entry + 1 + 1 + data->start, src + 1 + 1, f, data->dim); +} + +/* Add all lines from the given factor to "bset", + * given that there is a "total" number of coefficients + * (other than that of the constant term). + */ +static __isl_give isl_basic_set *add_lines(__isl_take isl_basic_set *bset, + struct isl_coefficients_factor_data *factor, int total) +{ + int i; + + for (i = 0; i < factor->n_line; ++i) { + int k; + + k = isl_basic_set_alloc_equality(bset); + if (k < 0) + return isl_basic_set_free(bset); + clear_entry(bset->eq[k], total); + set_factor(bset->eq[k], factor->coeff->eq[i], factor); + } + + return bset; +} + +/* Add all rays (other than lines) from the given factor to "bset", + * given that there is a "total" number of coefficients + * (other than that of the constant term). + */ +static __isl_give isl_basic_set *add_rays(__isl_take isl_basic_set *bset, + struct isl_coefficients_factor_data *data, int total) +{ + int i; + int n_ineq = data->n_ray + data->n_vertex; + + for (i = 0; i < n_ineq; ++i) { + int k; + + if (!is_ray(data->coeff, i)) + continue; + + k = isl_basic_set_alloc_inequality(bset); + if (k < 0) + return isl_basic_set_free(bset); + clear_entry(bset->ineq[k], total); + set_factor(bset->ineq[k], data->coeff->ineq[i], data); + } + + return bset; +} + +/* Move to the first vertex of the given factor starting + * at inequality constraint "start", setting factor->pos and + * returning 1 if a vertex is found. + */ +static int factor_first_vertex(struct isl_coefficients_factor_data *factor, + int start) +{ + int j; + int n = factor->n_ray + factor->n_vertex; + + for (j = start; j < n; ++j) { + if (is_ray(factor->coeff, j)) + continue; + factor->pos = j; + return 1; + } + + return 0; +} + +/* Move to the first constraint in each factor starting at "first" + * that represents a vertex. + * In particular, skip the initial constraints that correspond to rays. + */ +static void first_vertex(struct isl_coefficients_product_data *data, int first) +{ + int i; + + for (i = first; i < data->n; ++i) + factor_first_vertex(&data->factors[i], 0); +} + +/* Move to the next vertex in the product. + * In particular, move to the next vertex of the last factor. + * If all vertices of this last factor have already been considered, + * then move to the next vertex of the previous factor(s) + * until a factor is found that still has a next vertex. + * Once such a next vertex has been found, the subsequent + * factors are reset to the first vertex. + * Return 1 if any next vertex was found. + */ +static int next_vertex(struct isl_coefficients_product_data *data) +{ + int i; + + for (i = data->n - 1; i >= 0; --i) { + struct isl_coefficients_factor_data *factor = &data->factors[i]; + + if (!factor_first_vertex(factor, factor->pos + 1)) + continue; + first_vertex(data, i + 1); + return 1; + } + + return 0; +} + +/* Add a vertex to the product "bset" combining the currently selected + * vertices of the factors. + * + * In the dual representation, the constant term is always zero. + * The vertex itself is the sum of the contributions of the factors + * with a shared denominator in position 1. + * + * First compute the shared denominator (lcm) and + * then scale the numerators to this shared denominator. + */ +static __isl_give isl_basic_set *add_vertex(__isl_take isl_basic_set *bset, + struct isl_coefficients_product_data *data) +{ + int i; + int k; + isl_int lcm, f; + + k = isl_basic_set_alloc_inequality(bset); + if (k < 0) + return isl_basic_set_free(bset); + + isl_int_init(lcm); + isl_int_init(f); + isl_int_set_si(lcm, 1); + for (i = 0; i < data->n; ++i) { + struct isl_coefficients_factor_data *factor = &data->factors[i]; + isl_basic_set *coeff = factor->coeff; + int pos = factor->pos; + isl_int_lcm(lcm, lcm, coeff->ineq[pos][1]); + } + isl_int_set_si(bset->ineq[k][0], 0); + isl_int_set(bset->ineq[k][1], lcm); + + for (i = 0; i < data->n; ++i) { + struct isl_coefficients_factor_data *factor = &data->factors[i]; + isl_basic_set *coeff = factor->coeff; + int pos = factor->pos; + isl_int_divexact(f, lcm, coeff->ineq[pos][1]); + scale_factor(bset->ineq[k], coeff->ineq[pos], f, factor); + } + + isl_int_clear(f); + isl_int_clear(lcm); + + return bset; +} + +/* Combine the duals of the factors in the factorization of a basic set + * to form the dual of the entire basic set. + * The dual share the coefficient of the constant term. + * All other coefficients are specific to a factor. + * Any constraint not involving the coefficient of the constant term + * can therefor simply be copied into the appropriate position. + * This includes all equality constraints since the coefficient + * of the constant term can always be increased and therefore + * never appears in an equality constraint. + * The inequality constraints involving the coefficient of + * the constant term need to be combined across factors. + * In particular, if this coefficient needs to be greater than or equal + * to some linear combination of the other coefficients in each factor, + * then it needs to be greater than or equal to the sum of + * these linear combinations across the factors. + * + * Alternatively, the constraints of the dual can be seen + * as the vertices, rays and lines of the original basic set. + * Clearly, rays and lines can simply be copied, + * while vertices needs to be combined across factors. + * This means that the number of rays and lines in the product + * is equal to the sum of the numbers in the factors, + * while the number of vertices is the product + * of the number of vertices in the factors. Note that each + * factor has at least one vertex. + * The only exception is when the factor is the dual of an obviously empty set, + * in which case a universe dual is created. + * In this case, return a universe dual for the product as well. + * + * While constructing the vertices, look for the first combination + * of inequality constraints that represent a vertex, + * construct the corresponding vertex and then move on + * to the next combination of inequality constraints until + * all combinations have been considered. + */ +static __isl_give isl_basic_set *construct_product(isl_ctx *ctx, + struct isl_coefficients_product_data *data) +{ + int i; + int n_line, n_ray, n_vertex; + int total; + isl_space *space; + isl_basic_set *product; + + if (!data->factors) + return NULL; + + total = data->start_next; + + n_line = 0; + n_ray = 0; + n_vertex = 1; + for (i = 0; i < data->n; ++i) { + n_line += data->factors[i].n_line; + n_ray += data->factors[i].n_ray; + n_vertex *= data->factors[i].n_vertex; + } + + space = isl_space_set_alloc(ctx, 0, 1 + total); + if (n_vertex == 0) + return rational_universe(space); + product = isl_basic_set_alloc_space(space, 0, n_line, n_ray + n_vertex); + product = isl_basic_set_set_rational(product); + + for (i = 0; i < data->n; ++i) + product = add_lines(product, &data->factors[i], total); + for (i = 0; i < data->n; ++i) + product = add_rays(product, &data->factors[i], total); + + first_vertex(data, 0); + do { + product = add_vertex(product, data); + } while (next_vertex(data)); + + return product; +} + +/* Given a factorization "f" of a basic set, + * construct a basic set containing the tuples of coefficients of all + * valid affine constraints on the product of the factors, ignoring + * the space of input and output. + * Note that this product may not be equal to the original basic set, + * if a non-trivial transformation is involved. + * This is handled by the caller. + * + * Compute the tuples of coefficients for each factor separately and + * then combine the results. + */ +static __isl_give isl_basic_set *isl_basic_set_coefficients_product( + __isl_take isl_factorizer *f) +{ + struct isl_coefficients_product_data data; + isl_ctx *ctx; + isl_basic_set *coeff; + isl_bool every; + + ctx = isl_factorizer_get_ctx(f); + if (isl_coefficients_product_data_init(ctx, &data, f->n_group) < 0) + f = isl_factorizer_free(f); + every = isl_factorizer_every_factor_basic_set(f, + &isl_basic_set_coefficients_factor, &data); + isl_factorizer_free(f); + if (every >= 0) + coeff = construct_product(ctx, &data); + else + coeff = NULL; + isl_coefficients_product_data_clear(&data); + + return coeff; +} + +/* Given a factorization "f" of a basic set, + * construct a basic set containing the tuples of coefficients of all + * valid affine constraints on the basic set, ignoring + * the space of input and output. + * + * The factorization may involve a linear transformation of the basic set. + * In particular, the transformed basic set is formulated + * in terms of x' = U x, i.e., x = V x', with V = U^{-1}. + * The dual is then computed in terms of y' with y'^t [z; x'] >= 0. + * Plugging in y' = [1 0; 0 V^t] y yields + * y^t [1 0; 0 V] [z; x'] >= 0, i.e., y^t [z; x] >= 0, which is + * the desired set of coefficients y. + * Note that this transformation to y' only needs to be applied + * if U is not the identity matrix. + */ +static __isl_give isl_basic_set *isl_basic_set_coefficients_morphed_product( + __isl_take isl_factorizer *f) +{ + isl_bool is_identity; + isl_space *space; + isl_mat *inv; + isl_multi_aff *ma; + isl_basic_set *coeff; + + if (!f) + goto error; + is_identity = isl_mat_is_scaled_identity(peek_inv(f->morph)); + if (is_identity < 0) + goto error; + if (is_identity) + return isl_basic_set_coefficients_product(f); + + inv = get_inv(f->morph); + inv = isl_mat_transpose(inv); + inv = isl_mat_lin_to_aff(inv); + + coeff = isl_basic_set_coefficients_product(f); + space = isl_space_map_from_set(isl_basic_set_get_space(coeff)); + ma = isl_multi_aff_from_aff_mat(space, inv); + coeff = isl_basic_set_preimage_multi_aff(coeff, ma); + + return coeff; +error: + isl_factorizer_free(f); + return NULL; +} + +/* Construct a basic set containing the tuples of coefficients of all + * valid affine constraints on the given basic set, ignoring + * the space of input and output. + * + * The caller has already checked that "bset" does not involve + * any local variables. It may have parameters, though. + * Treat them as regular variables internally. + * This is especially important for the factorization, + * since the (original) parameters should be taken into account + * explicitly in this factorization. + * + * Check if the basic set can be factorized. + * If so, compute constraints on the coefficients of the factors + * separately and combine the results. + * Otherwise, compute the results for the input basic set as a whole. + */ +static __isl_give isl_basic_set *basic_set_coefficients( + __isl_take isl_basic_set *bset) +{ + isl_factorizer *f; + isl_size nparam; + + nparam = isl_basic_set_dim(bset, isl_dim_param); + if (nparam < 0) + return isl_basic_set_free(bset); + bset = isl_basic_set_move_dims(bset, isl_dim_set, 0, + isl_dim_param, 0, nparam); + + f = isl_basic_set_factorizer(bset); + if (!f) + return isl_basic_set_free(bset); + if (f->n_group > 0) { + isl_basic_set_free(bset); + return isl_basic_set_coefficients_morphed_product(f); + } + isl_factorizer_free(f); + return isl_basic_set_coefficients_base(bset); +} + +/* Construct a basic set containing the tuples of coefficients of all + * valid affine constraints on the given basic set. + */ +__isl_give isl_basic_set *isl_basic_set_coefficients( + __isl_take isl_basic_set *bset) +{ + isl_space *space; + + if (!bset) + return NULL; + if (bset->n_div) + isl_die(bset->ctx, isl_error_invalid, + "input set not allowed to have local variables", + goto error); + + space = isl_basic_set_get_space(bset); + space = isl_space_coefficients(space); + + bset = basic_set_coefficients(bset); + bset = isl_basic_set_reset_space(bset, space); + return bset; +error: + isl_basic_set_free(bset); + return NULL; +} + +/* Construct a basic set containing the elements that satisfy all + * affine constraints whose coefficient tuples are + * contained in the given basic set. + */ +__isl_give isl_basic_set *isl_basic_set_solutions( + __isl_take isl_basic_set *bset) +{ + isl_space *space; + + if (!bset) + return NULL; + if (bset->n_div) + isl_die(bset->ctx, isl_error_invalid, + "input set not allowed to have local variables", + goto error); + + space = isl_basic_set_get_space(bset); + space = isl_space_solutions(space); + + bset = farkas(bset, -1); + bset = isl_basic_set_reset_space(bset, space); + return bset; +error: + isl_basic_set_free(bset); + return NULL; +} + +/* Construct a basic set containing the tuples of coefficients of all + * valid affine constraints on the given set. + */ +__isl_give isl_basic_set *isl_set_coefficients(__isl_take isl_set *set) +{ + int i; + isl_basic_set *coeff; + + if (!set) + return NULL; + if (set->n == 0) { + isl_space *space = isl_set_get_space(set); + space = isl_space_coefficients(space); + isl_set_free(set); + return rational_universe(space); + } + + coeff = isl_basic_set_coefficients(isl_basic_set_copy(set->p[0])); + + for (i = 1; i < set->n; ++i) { + isl_basic_set *bset, *coeff_i; + bset = isl_basic_set_copy(set->p[i]); + coeff_i = isl_basic_set_coefficients(bset); + coeff = isl_basic_set_intersect(coeff, coeff_i); + } + + isl_set_free(set); + return coeff; +} + +/* Wrapper around isl_basic_set_coefficients for use + * as a isl_basic_set_list_map callback. + */ +static __isl_give isl_basic_set *coefficients_wrap( + __isl_take isl_basic_set *bset, void *user) +{ + return isl_basic_set_coefficients(bset); +} + +/* Replace the elements of "list" by the result of applying + * isl_basic_set_coefficients to them. + */ +__isl_give isl_basic_set_list *isl_basic_set_list_coefficients( + __isl_take isl_basic_set_list *list) +{ + return isl_basic_set_list_map(list, &coefficients_wrap, NULL); +} + +/* Construct a basic set containing the elements that satisfy all + * affine constraints whose coefficient tuples are + * contained in the given set. + */ +__isl_give isl_basic_set *isl_set_solutions(__isl_take isl_set *set) +{ + int i; + isl_basic_set *sol; + + if (!set) + return NULL; + if (set->n == 0) { + isl_space *space = isl_set_get_space(set); + space = isl_space_solutions(space); + isl_set_free(set); + return rational_universe(space); + } + + sol = isl_basic_set_solutions(isl_basic_set_copy(set->p[0])); + + for (i = 1; i < set->n; ++i) { + isl_basic_set *bset, *sol_i; + bset = isl_basic_set_copy(set->p[i]); + sol_i = isl_basic_set_solutions(bset); + sol = isl_basic_set_intersect(sol, sol_i); + } + + isl_set_free(set); + return sol; +} diff --git a/external/mit/isl/dist/isl_ffs.c b/external/mit/isl/dist/isl_ffs.c new file mode 100644 index 000000000000..c1ee928f8b81 --- /dev/null +++ b/external/mit/isl/dist/isl_ffs.c @@ -0,0 +1,24 @@ +#include + +#if !HAVE_DECL_FFS && !HAVE_DECL___BUILTIN_FFS && HAVE_DECL__BITSCANFORWARD +#include + +/* Implementation of ffs in terms of _BitScanForward. + * + * ffs returns the position of the least significant bit set in i, + * with the least significant bit is position 1, or 0 if not bits are set. + * + * _BitScanForward returns 1 if mask is non-zero and sets index + * to the position of the least significant bit set in i, + * with the least significant bit is position 0. + */ +int isl_ffs(int i) +{ + unsigned char non_zero; + unsigned long index, mask = i; + + non_zero = _BitScanForward(&index, mask); + + return non_zero ? 1 + index : 0; +} +#endif diff --git a/external/mit/isl/dist/isl_flow.c b/external/mit/isl/dist/isl_flow.c new file mode 100644 index 000000000000..c083a96538a7 --- /dev/null +++ b/external/mit/isl/dist/isl_flow.c @@ -0,0 +1,3346 @@ +/* + * Copyright 2005-2007 Universiteit Leiden + * Copyright 2008-2009 Katholieke Universiteit Leuven + * Copyright 2010 INRIA Saclay + * Copyright 2012 Universiteit Leiden + * Copyright 2014 Ecole Normale Superieure + * + * Use of this software is governed by the MIT license + * + * Written by Sven Verdoolaege, Leiden Institute of Advanced Computer Science, + * Universiteit Leiden, Niels Bohrweg 1, 2333 CA Leiden, The Netherlands + * and 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 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +enum isl_restriction_type { + isl_restriction_type_empty, + isl_restriction_type_none, + isl_restriction_type_input, + isl_restriction_type_output +}; + +struct isl_restriction { + enum isl_restriction_type type; + + isl_set *source; + isl_set *sink; +}; + +/* Create a restriction of the given type. + */ +static __isl_give isl_restriction *isl_restriction_alloc( + __isl_take isl_map *source_map, enum isl_restriction_type type) +{ + isl_ctx *ctx; + isl_restriction *restr; + + if (!source_map) + return NULL; + + ctx = isl_map_get_ctx(source_map); + restr = isl_calloc_type(ctx, struct isl_restriction); + if (!restr) + goto error; + + restr->type = type; + + isl_map_free(source_map); + return restr; +error: + isl_map_free(source_map); + return NULL; +} + +/* Create a restriction that doesn't restrict anything. + */ +__isl_give isl_restriction *isl_restriction_none(__isl_take isl_map *source_map) +{ + return isl_restriction_alloc(source_map, isl_restriction_type_none); +} + +/* Create a restriction that removes everything. + */ +__isl_give isl_restriction *isl_restriction_empty( + __isl_take isl_map *source_map) +{ + return isl_restriction_alloc(source_map, isl_restriction_type_empty); +} + +/* Create a restriction on the input of the maximization problem + * based on the given source and sink restrictions. + */ +__isl_give isl_restriction *isl_restriction_input( + __isl_take isl_set *source_restr, __isl_take isl_set *sink_restr) +{ + isl_ctx *ctx; + isl_restriction *restr; + + if (!source_restr || !sink_restr) + goto error; + + ctx = isl_set_get_ctx(source_restr); + restr = isl_calloc_type(ctx, struct isl_restriction); + if (!restr) + goto error; + + restr->type = isl_restriction_type_input; + restr->source = source_restr; + restr->sink = sink_restr; + + return restr; +error: + isl_set_free(source_restr); + isl_set_free(sink_restr); + return NULL; +} + +/* Create a restriction on the output of the maximization problem + * based on the given source restriction. + */ +__isl_give isl_restriction *isl_restriction_output( + __isl_take isl_set *source_restr) +{ + isl_ctx *ctx; + isl_restriction *restr; + + if (!source_restr) + return NULL; + + ctx = isl_set_get_ctx(source_restr); + restr = isl_calloc_type(ctx, struct isl_restriction); + if (!restr) + goto error; + + restr->type = isl_restriction_type_output; + restr->source = source_restr; + + return restr; +error: + isl_set_free(source_restr); + return NULL; +} + +__isl_null isl_restriction *isl_restriction_free( + __isl_take isl_restriction *restr) +{ + if (!restr) + return NULL; + + isl_set_free(restr->source); + isl_set_free(restr->sink); + free(restr); + return NULL; +} + +isl_ctx *isl_restriction_get_ctx(__isl_keep isl_restriction *restr) +{ + return restr ? isl_set_get_ctx(restr->source) : NULL; +} + +/* A private structure to keep track of a mapping together with + * a user-specified identifier and a boolean indicating whether + * the map represents a must or may access/dependence. + */ +struct isl_labeled_map { + struct isl_map *map; + void *data; + int must; +}; + +typedef isl_bool (*isl_access_coscheduled)(void *first, void *second); + +/* A structure containing the input for dependence analysis: + * - a sink + * - n_must + n_may (<= max_source) sources + * - a function for determining the relative order of sources and sink + * - an optional function "coscheduled" for determining whether sources + * may be coscheduled. If "coscheduled" is NULL, then the sources + * are assumed not to be coscheduled. + * The must sources are placed before the may sources. + * + * domain_map is an auxiliary map that maps the sink access relation + * to the domain of this access relation. + * This field is only needed when restrict_fn is set and + * the field itself is set by isl_access_info_compute_flow. + * + * restrict_fn is a callback that (if not NULL) will be called + * right before any lexicographical maximization. + */ +struct isl_access_info { + isl_map *domain_map; + struct isl_labeled_map sink; + isl_access_level_before level_before; + isl_access_coscheduled coscheduled; + + isl_access_restrict restrict_fn; + void *restrict_user; + + int max_source; + int n_must; + int n_may; + struct isl_labeled_map source[1]; +}; + +/* A structure containing the output of dependence analysis: + * - n_source dependences + * - a wrapped subset of the sink for which definitely no source could be found + * - a wrapped subset of the sink for which possibly no source could be found + */ +struct isl_flow { + isl_set *must_no_source; + isl_set *may_no_source; + int n_source; + struct isl_labeled_map *dep; +}; + +/* Construct an isl_access_info structure and fill it up with + * the given data. The number of sources is set to 0. + */ +__isl_give isl_access_info *isl_access_info_alloc(__isl_take isl_map *sink, + void *sink_user, isl_access_level_before fn, int max_source) +{ + isl_ctx *ctx; + struct isl_access_info *acc; + + if (!sink) + return NULL; + + ctx = isl_map_get_ctx(sink); + isl_assert(ctx, max_source >= 0, goto error); + + acc = isl_calloc(ctx, struct isl_access_info, + sizeof(struct isl_access_info) + + (max_source - 1) * sizeof(struct isl_labeled_map)); + if (!acc) + goto error; + + acc->sink.map = sink; + acc->sink.data = sink_user; + acc->level_before = fn; + acc->max_source = max_source; + acc->n_must = 0; + acc->n_may = 0; + + return acc; +error: + isl_map_free(sink); + return NULL; +} + +/* Free the given isl_access_info structure. + */ +__isl_null isl_access_info *isl_access_info_free( + __isl_take isl_access_info *acc) +{ + int i; + + if (!acc) + return NULL; + isl_map_free(acc->domain_map); + isl_map_free(acc->sink.map); + for (i = 0; i < acc->n_must + acc->n_may; ++i) + isl_map_free(acc->source[i].map); + free(acc); + return NULL; +} + +isl_ctx *isl_access_info_get_ctx(__isl_keep isl_access_info *acc) +{ + return acc ? isl_map_get_ctx(acc->sink.map) : NULL; +} + +__isl_give isl_access_info *isl_access_info_set_restrict( + __isl_take isl_access_info *acc, isl_access_restrict fn, void *user) +{ + if (!acc) + return NULL; + acc->restrict_fn = fn; + acc->restrict_user = user; + return acc; +} + +/* Add another source to an isl_access_info structure, making + * sure the "must" sources are placed before the "may" sources. + * This function may be called at most max_source times on a + * given isl_access_info structure, with max_source as specified + * in the call to isl_access_info_alloc that constructed the structure. + */ +__isl_give isl_access_info *isl_access_info_add_source( + __isl_take isl_access_info *acc, __isl_take isl_map *source, + int must, void *source_user) +{ + isl_ctx *ctx; + + if (!acc) + goto error; + ctx = isl_map_get_ctx(acc->sink.map); + isl_assert(ctx, acc->n_must + acc->n_may < acc->max_source, goto error); + + if (must) { + if (acc->n_may) + acc->source[acc->n_must + acc->n_may] = + acc->source[acc->n_must]; + acc->source[acc->n_must].map = source; + acc->source[acc->n_must].data = source_user; + acc->source[acc->n_must].must = 1; + acc->n_must++; + } else { + acc->source[acc->n_must + acc->n_may].map = source; + acc->source[acc->n_must + acc->n_may].data = source_user; + acc->source[acc->n_must + acc->n_may].must = 0; + acc->n_may++; + } + + return acc; +error: + isl_map_free(source); + isl_access_info_free(acc); + return NULL; +} + +/* A helper struct carrying the isl_access_info and an error condition. + */ +struct access_sort_info { + isl_access_info *access_info; + int error; +}; + +/* Return -n, 0 or n (with n a positive value), depending on whether + * the source access identified by p1 should be sorted before, together + * or after that identified by p2. + * + * If p1 appears before p2, then it should be sorted first. + * For more generic initial schedules, it is possible that neither + * p1 nor p2 appears before the other, or at least not in any obvious way. + * We therefore also check if p2 appears before p1, in which case p2 + * should be sorted first. + * If not, we try to order the two statements based on the description + * of the iteration domains. This results in an arbitrary, but fairly + * stable ordering. + * + * In case of an error, sort_info.error is set to true and all elements are + * reported to be equal. + */ +static int access_sort_cmp(const void *p1, const void *p2, void *user) +{ + struct access_sort_info *sort_info = user; + isl_access_info *acc = sort_info->access_info; + + if (sort_info->error) + return 0; + + const struct isl_labeled_map *i1, *i2; + int level1, level2; + uint32_t h1, h2; + i1 = (const struct isl_labeled_map *) p1; + i2 = (const struct isl_labeled_map *) p2; + + level1 = acc->level_before(i1->data, i2->data); + if (level1 < 0) + goto error; + if (level1 % 2) + return -1; + + level2 = acc->level_before(i2->data, i1->data); + if (level2 < 0) + goto error; + if (level2 % 2) + return 1; + + h1 = isl_map_get_hash(i1->map); + h2 = isl_map_get_hash(i2->map); + return h1 > h2 ? 1 : h1 < h2 ? -1 : 0; +error: + sort_info->error = 1; + return 0; +} + +/* Sort the must source accesses in their textual order. + */ +static __isl_give isl_access_info *isl_access_info_sort_sources( + __isl_take isl_access_info *acc) +{ + struct access_sort_info sort_info; + + sort_info.access_info = acc; + sort_info.error = 0; + + if (!acc) + return NULL; + if (acc->n_must <= 1) + return acc; + + if (isl_sort(acc->source, acc->n_must, sizeof(struct isl_labeled_map), + access_sort_cmp, &sort_info) < 0) + return isl_access_info_free(acc); + if (sort_info.error) + return isl_access_info_free(acc); + + return acc; +} + +/* Align the parameters of the two spaces if needed and then call + * isl_space_join. + */ +static __isl_give isl_space *space_align_and_join(__isl_take isl_space *left, + __isl_take isl_space *right) +{ + isl_bool equal_params; + + equal_params = isl_space_has_equal_params(left, right); + if (equal_params < 0) + goto error; + if (equal_params) + return isl_space_join(left, right); + + left = isl_space_align_params(left, isl_space_copy(right)); + right = isl_space_align_params(right, isl_space_copy(left)); + return isl_space_join(left, right); +error: + isl_space_free(left); + isl_space_free(right); + return NULL; +} + +/* Initialize an empty isl_flow structure corresponding to a given + * isl_access_info structure. + * For each must access, two dependences are created (initialized + * to the empty relation), one for the resulting must dependences + * and one for the resulting may dependences. May accesses can + * only lead to may dependences, so only one dependence is created + * for each of them. + * This function is private as isl_flow structures are only supposed + * to be created by isl_access_info_compute_flow. + */ +static __isl_give isl_flow *isl_flow_alloc(__isl_keep isl_access_info *acc) +{ + int i, n; + struct isl_ctx *ctx; + struct isl_flow *dep; + + if (!acc) + return NULL; + + ctx = isl_map_get_ctx(acc->sink.map); + dep = isl_calloc_type(ctx, struct isl_flow); + if (!dep) + return NULL; + + n = 2 * acc->n_must + acc->n_may; + dep->dep = isl_calloc_array(ctx, struct isl_labeled_map, n); + if (n && !dep->dep) + goto error; + + dep->n_source = n; + for (i = 0; i < acc->n_must; ++i) { + isl_space *space; + space = space_align_and_join( + isl_map_get_space(acc->source[i].map), + isl_space_reverse(isl_map_get_space(acc->sink.map))); + dep->dep[2 * i].map = isl_map_empty(space); + dep->dep[2 * i + 1].map = isl_map_copy(dep->dep[2 * i].map); + dep->dep[2 * i].data = acc->source[i].data; + dep->dep[2 * i + 1].data = acc->source[i].data; + dep->dep[2 * i].must = 1; + dep->dep[2 * i + 1].must = 0; + if (!dep->dep[2 * i].map || !dep->dep[2 * i + 1].map) + goto error; + } + for (i = acc->n_must; i < acc->n_must + acc->n_may; ++i) { + isl_space *space; + space = space_align_and_join( + isl_map_get_space(acc->source[i].map), + isl_space_reverse(isl_map_get_space(acc->sink.map))); + dep->dep[acc->n_must + i].map = isl_map_empty(space); + dep->dep[acc->n_must + i].data = acc->source[i].data; + dep->dep[acc->n_must + i].must = 0; + if (!dep->dep[acc->n_must + i].map) + goto error; + } + + return dep; +error: + isl_flow_free(dep); + return NULL; +} + +/* Iterate over all sources and for each resulting flow dependence + * that is not empty, call the user specfied function. + * The second argument in this function call identifies the source, + * while the third argument correspond to the final argument of + * the isl_flow_foreach call. + */ +isl_stat isl_flow_foreach(__isl_keep isl_flow *deps, + isl_stat (*fn)(__isl_take isl_map *dep, int must, void *dep_user, + void *user), + void *user) +{ + int i; + + if (!deps) + return isl_stat_error; + + for (i = 0; i < deps->n_source; ++i) { + if (isl_map_plain_is_empty(deps->dep[i].map)) + continue; + if (fn(isl_map_copy(deps->dep[i].map), deps->dep[i].must, + deps->dep[i].data, user) < 0) + return isl_stat_error; + } + + return isl_stat_ok; +} + +/* Return a copy of the subset of the sink for which no source could be found. + */ +__isl_give isl_map *isl_flow_get_no_source(__isl_keep isl_flow *deps, int must) +{ + if (!deps) + return NULL; + + if (must) + return isl_set_unwrap(isl_set_copy(deps->must_no_source)); + else + return isl_set_unwrap(isl_set_copy(deps->may_no_source)); +} + +__isl_null isl_flow *isl_flow_free(__isl_take isl_flow *deps) +{ + int i; + + if (!deps) + return NULL; + isl_set_free(deps->must_no_source); + isl_set_free(deps->may_no_source); + if (deps->dep) { + for (i = 0; i < deps->n_source; ++i) + isl_map_free(deps->dep[i].map); + free(deps->dep); + } + free(deps); + + return NULL; +} + +isl_ctx *isl_flow_get_ctx(__isl_keep isl_flow *deps) +{ + return deps ? isl_set_get_ctx(deps->must_no_source) : NULL; +} + +/* Return a map that enforces that the domain iteration occurs after + * the range iteration at the given level. + * If level is odd, then the domain iteration should occur after + * the target iteration in their shared level/2 outermost loops. + * In this case we simply need to enforce that these outermost + * loop iterations are the same. + * If level is even, then the loop iterator of the domain should + * be greater than the loop iterator of the range at the last + * of the level/2 shared loops, i.e., loop level/2 - 1. + */ +static __isl_give isl_map *after_at_level(__isl_take isl_space *space, + int level) +{ + struct isl_basic_map *bmap; + + if (level % 2) + bmap = isl_basic_map_equal(space, level/2); + else + bmap = isl_basic_map_more_at(space, level/2 - 1); + + return isl_map_from_basic_map(bmap); +} + +/* Compute the partial lexicographic maximum of "dep" on domain "sink", + * but first check if the user has set acc->restrict_fn and if so + * update either the input or the output of the maximization problem + * with respect to the resulting restriction. + * + * Since the user expects a mapping from sink iterations to source iterations, + * whereas the domain of "dep" is a wrapped map, mapping sink iterations + * to accessed array elements, we first need to project out the accessed + * sink array elements by applying acc->domain_map. + * Similarly, the sink restriction specified by the user needs to be + * converted back to the wrapped map. + */ +static __isl_give isl_map *restricted_partial_lexmax( + __isl_keep isl_access_info *acc, __isl_take isl_map *dep, + int source, __isl_take isl_set *sink, __isl_give isl_set **empty) +{ + isl_map *source_map; + isl_restriction *restr; + isl_set *sink_domain; + isl_set *sink_restr; + isl_map *res; + + if (!acc->restrict_fn) + return isl_map_partial_lexmax(dep, sink, empty); + + source_map = isl_map_copy(dep); + source_map = isl_map_apply_domain(source_map, + isl_map_copy(acc->domain_map)); + sink_domain = isl_set_copy(sink); + sink_domain = isl_set_apply(sink_domain, isl_map_copy(acc->domain_map)); + restr = acc->restrict_fn(source_map, sink_domain, + acc->source[source].data, acc->restrict_user); + isl_set_free(sink_domain); + isl_map_free(source_map); + + if (!restr) + goto error; + if (restr->type == isl_restriction_type_input) { + dep = isl_map_intersect_range(dep, isl_set_copy(restr->source)); + sink_restr = isl_set_copy(restr->sink); + sink_restr = isl_set_apply(sink_restr, + isl_map_reverse(isl_map_copy(acc->domain_map))); + sink = isl_set_intersect(sink, sink_restr); + } else if (restr->type == isl_restriction_type_empty) { + isl_space *space = isl_map_get_space(dep); + isl_map_free(dep); + dep = isl_map_empty(space); + } + + res = isl_map_partial_lexmax(dep, sink, empty); + + if (restr->type == isl_restriction_type_output) + res = isl_map_intersect_range(res, isl_set_copy(restr->source)); + + isl_restriction_free(restr); + return res; +error: + isl_map_free(dep); + isl_set_free(sink); + *empty = NULL; + return NULL; +} + +/* Compute the last iteration of must source j that precedes the sink + * at the given level for sink iterations in set_C. + * The subset of set_C for which no such iteration can be found is returned + * in *empty. + */ +static struct isl_map *last_source(struct isl_access_info *acc, + struct isl_set *set_C, + int j, int level, struct isl_set **empty) +{ + struct isl_map *read_map; + struct isl_map *write_map; + struct isl_map *dep_map; + struct isl_map *after; + struct isl_map *result; + + read_map = isl_map_copy(acc->sink.map); + write_map = isl_map_copy(acc->source[j].map); + write_map = isl_map_reverse(write_map); + dep_map = isl_map_apply_range(read_map, write_map); + after = after_at_level(isl_map_get_space(dep_map), level); + dep_map = isl_map_intersect(dep_map, after); + result = restricted_partial_lexmax(acc, dep_map, j, set_C, empty); + result = isl_map_reverse(result); + + return result; +} + +/* For a given mapping between iterations of must source j and iterations + * of the sink, compute the last iteration of must source k preceding + * the sink at level before_level for any of the sink iterations, + * but following the corresponding iteration of must source j at level + * after_level. + */ +static struct isl_map *last_later_source(struct isl_access_info *acc, + struct isl_map *old_map, + int j, int before_level, + int k, int after_level, + struct isl_set **empty) +{ + isl_space *space; + struct isl_set *set_C; + struct isl_map *read_map; + struct isl_map *write_map; + struct isl_map *dep_map; + struct isl_map *after_write; + struct isl_map *before_read; + struct isl_map *result; + + set_C = isl_map_range(isl_map_copy(old_map)); + read_map = isl_map_copy(acc->sink.map); + write_map = isl_map_copy(acc->source[k].map); + + write_map = isl_map_reverse(write_map); + dep_map = isl_map_apply_range(read_map, write_map); + space = space_align_and_join(isl_map_get_space(acc->source[k].map), + isl_space_reverse(isl_map_get_space(acc->source[j].map))); + after_write = after_at_level(space, after_level); + after_write = isl_map_apply_range(after_write, old_map); + after_write = isl_map_reverse(after_write); + dep_map = isl_map_intersect(dep_map, after_write); + before_read = after_at_level(isl_map_get_space(dep_map), before_level); + dep_map = isl_map_intersect(dep_map, before_read); + result = restricted_partial_lexmax(acc, dep_map, k, set_C, empty); + result = isl_map_reverse(result); + + return result; +} + +/* Given a shared_level between two accesses, return 1 if the + * the first can precede the second at the requested target_level. + * If the target level is odd, i.e., refers to a statement level + * dimension, then first needs to precede second at the requested + * level, i.e., shared_level must be equal to target_level. + * If the target level is odd, then the two loops should share + * at least the requested number of outer loops. + */ +static int can_precede_at_level(int shared_level, int target_level) +{ + if (shared_level < target_level) + return 0; + if ((target_level % 2) && shared_level > target_level) + return 0; + return 1; +} + +/* Given a possible flow dependence temp_rel[j] between source j and the sink + * at level sink_level, remove those elements for which + * there is an iteration of another source k < j that is closer to the sink. + * The flow dependences temp_rel[k] are updated with the improved sources. + * Any improved source needs to precede the sink at the same level + * and needs to follow source j at the same or a deeper level. + * The lower this level, the later the execution date of source k. + * We therefore consider lower levels first. + * + * If temp_rel[j] is empty, then there can be no improvement and + * we return immediately. + * + * This function returns isl_stat_ok in case it was executed successfully and + * isl_stat_error in case of errors during the execution of this function. + */ +static isl_stat intermediate_sources(__isl_keep isl_access_info *acc, + struct isl_map **temp_rel, int j, int sink_level) +{ + int k, level; + isl_size n_in = isl_map_dim(acc->source[j].map, isl_dim_in); + int depth = 2 * n_in + 1; + + if (n_in < 0) + return isl_stat_error; + if (isl_map_plain_is_empty(temp_rel[j])) + return isl_stat_ok; + + for (k = j - 1; k >= 0; --k) { + int plevel, plevel2; + plevel = acc->level_before(acc->source[k].data, acc->sink.data); + if (plevel < 0) + return isl_stat_error; + if (!can_precede_at_level(plevel, sink_level)) + continue; + + plevel2 = acc->level_before(acc->source[j].data, + acc->source[k].data); + if (plevel2 < 0) + return isl_stat_error; + + for (level = sink_level; level <= depth; ++level) { + struct isl_map *T; + struct isl_set *trest; + struct isl_map *copy; + + if (!can_precede_at_level(plevel2, level)) + continue; + + copy = isl_map_copy(temp_rel[j]); + T = last_later_source(acc, copy, j, sink_level, k, + level, &trest); + if (isl_map_plain_is_empty(T)) { + isl_set_free(trest); + isl_map_free(T); + continue; + } + temp_rel[j] = isl_map_intersect_range(temp_rel[j], trest); + temp_rel[k] = isl_map_union_disjoint(temp_rel[k], T); + } + } + + return isl_stat_ok; +} + +/* Compute all iterations of may source j that precedes the sink at the given + * level for sink iterations in set_C. + */ +static __isl_give isl_map *all_sources(__isl_keep isl_access_info *acc, + __isl_take isl_set *set_C, int j, int level) +{ + isl_map *read_map; + isl_map *write_map; + isl_map *dep_map; + isl_map *after; + + read_map = isl_map_copy(acc->sink.map); + read_map = isl_map_intersect_domain(read_map, set_C); + write_map = isl_map_copy(acc->source[acc->n_must + j].map); + write_map = isl_map_reverse(write_map); + dep_map = isl_map_apply_range(read_map, write_map); + after = after_at_level(isl_map_get_space(dep_map), level); + dep_map = isl_map_intersect(dep_map, after); + + return isl_map_reverse(dep_map); +} + +/* For a given mapping between iterations of must source k and iterations + * of the sink, compute all iterations of may source j preceding + * the sink at level before_level for any of the sink iterations, + * but following the corresponding iteration of must source k at level + * after_level. + */ +static __isl_give isl_map *all_later_sources(__isl_keep isl_access_info *acc, + __isl_take isl_map *old_map, + int j, int before_level, int k, int after_level) +{ + isl_space *space; + isl_set *set_C; + isl_map *read_map; + isl_map *write_map; + isl_map *dep_map; + isl_map *after_write; + isl_map *before_read; + + set_C = isl_map_range(isl_map_copy(old_map)); + read_map = isl_map_copy(acc->sink.map); + read_map = isl_map_intersect_domain(read_map, set_C); + write_map = isl_map_copy(acc->source[acc->n_must + j].map); + + write_map = isl_map_reverse(write_map); + dep_map = isl_map_apply_range(read_map, write_map); + space = isl_space_join(isl_map_get_space( + acc->source[acc->n_must + j].map), + isl_space_reverse(isl_map_get_space(acc->source[k].map))); + after_write = after_at_level(space, after_level); + after_write = isl_map_apply_range(after_write, old_map); + after_write = isl_map_reverse(after_write); + dep_map = isl_map_intersect(dep_map, after_write); + before_read = after_at_level(isl_map_get_space(dep_map), before_level); + dep_map = isl_map_intersect(dep_map, before_read); + return isl_map_reverse(dep_map); +} + +/* Given the must and may dependence relations for the must accesses + * for level sink_level, check if there are any accesses of may access j + * that occur in between and return their union. + * If some of these accesses are intermediate with respect to + * (previously thought to be) must dependences, then these + * must dependences are turned into may dependences. + */ +static __isl_give isl_map *all_intermediate_sources( + __isl_keep isl_access_info *acc, __isl_take isl_map *map, + struct isl_map **must_rel, struct isl_map **may_rel, + int j, int sink_level) +{ + int k, level; + isl_size n_in = isl_map_dim(acc->source[acc->n_must + j].map, + isl_dim_in); + int depth = 2 * n_in + 1; + + if (n_in < 0) + return isl_map_free(map); + for (k = 0; k < acc->n_must; ++k) { + int plevel; + + if (isl_map_plain_is_empty(may_rel[k]) && + isl_map_plain_is_empty(must_rel[k])) + continue; + + plevel = acc->level_before(acc->source[k].data, + acc->source[acc->n_must + j].data); + if (plevel < 0) + return isl_map_free(map); + + for (level = sink_level; level <= depth; ++level) { + isl_map *T; + isl_map *copy; + isl_set *ran; + + if (!can_precede_at_level(plevel, level)) + continue; + + copy = isl_map_copy(may_rel[k]); + T = all_later_sources(acc, copy, j, sink_level, k, level); + map = isl_map_union(map, T); + + copy = isl_map_copy(must_rel[k]); + T = all_later_sources(acc, copy, j, sink_level, k, level); + ran = isl_map_range(isl_map_copy(T)); + map = isl_map_union(map, T); + may_rel[k] = isl_map_union_disjoint(may_rel[k], + isl_map_intersect_range(isl_map_copy(must_rel[k]), + isl_set_copy(ran))); + T = isl_map_from_domain_and_range( + isl_set_universe( + isl_space_domain(isl_map_get_space(must_rel[k]))), + ran); + must_rel[k] = isl_map_subtract(must_rel[k], T); + } + } + + return map; +} + +/* Given a dependence relation "old_map" between a must-source and the sink, + * return a subset of the dependences, augmented with instances + * of the source at position "pos" in "acc" that are coscheduled + * with the must-source and that access the same element. + * That is, if the input lives in a space T -> K, then the output + * lives in the space [T -> S] -> K, with S the space of source "pos", and + * the domain factor of the domain product is a subset of the input. + * The sources are considered to be coscheduled if they have the same values + * for the initial "depth" coordinates. + * + * First construct a dependence relation S -> K and a mapping + * between coscheduled sources T -> S. + * The second is combined with the original dependence relation T -> K + * to form a relation in T -> [S -> K], which is subsequently + * uncurried to [T -> S] -> K. + * This result is then intersected with the dependence relation S -> K + * to form the output. + * + * In case a negative depth is given, NULL is returned to indicate an error. + */ +static __isl_give isl_map *coscheduled_source(__isl_keep isl_access_info *acc, + __isl_keep isl_map *old_map, int pos, int depth) +{ + isl_space *space; + isl_set *set_C; + isl_map *read_map; + isl_map *write_map; + isl_map *dep_map; + isl_map *equal; + isl_map *map; + + if (depth < 0) + return NULL; + + set_C = isl_map_range(isl_map_copy(old_map)); + read_map = isl_map_copy(acc->sink.map); + read_map = isl_map_intersect_domain(read_map, set_C); + write_map = isl_map_copy(acc->source[pos].map); + dep_map = isl_map_domain_product(write_map, read_map); + dep_map = isl_set_unwrap(isl_map_domain(dep_map)); + space = isl_space_join(isl_map_get_space(old_map), + isl_space_reverse(isl_map_get_space(dep_map))); + equal = isl_map_from_basic_map(isl_basic_map_equal(space, depth)); + map = isl_map_range_product(equal, isl_map_copy(old_map)); + map = isl_map_uncurry(map); + map = isl_map_intersect_domain_factor_range(map, dep_map); + + return map; +} + +/* After the dependences derived from a must-source have been computed + * at a certain level, check if any of the sources of the must-dependences + * may be coscheduled with other sources. + * If they are any such sources, then there is no way of determining + * which of the sources actually comes last and the must-dependences + * need to be turned into may-dependences, while dependences from + * the other sources need to be added to the may-dependences as well. + * "acc" describes the sources and a callback for checking whether + * two sources may be coscheduled. If acc->coscheduled is NULL then + * the sources are assumed not to be coscheduled. + * "must_rel" and "may_rel" describe the must and may-dependence relations + * computed at the current level for the must-sources. Some of the dependences + * may be moved from "must_rel" to "may_rel". + * "flow" contains all dependences computed so far (apart from those + * in "must_rel" and "may_rel") and may be updated with additional + * dependences derived from may-sources. + * + * In particular, consider all the must-sources with a non-empty + * dependence relation in "must_rel". They are considered in reverse + * order because that is the order in which they are considered in the caller. + * If any of the must-sources are coscheduled, then the last one + * is the one that will have a corresponding dependence relation. + * For each must-source i, consider both all the previous must-sources + * and all the may-sources. If any of those may be coscheduled with + * must-source i, then compute the coscheduled instances that access + * the same memory elements. The result is a relation [T -> S] -> K. + * The projection onto T -> K is a subset of the must-dependence relation + * that needs to be turned into may-dependences. + * The projection onto S -> K needs to be added to the may-dependences + * of source S. + * Since a given must-source instance may be coscheduled with several + * other source instances, the dependences that need to be turned + * into may-dependences are first collected and only actually removed + * from the must-dependences after all other sources have been considered. + */ +static __isl_give isl_flow *handle_coscheduled(__isl_keep isl_access_info *acc, + __isl_keep isl_map **must_rel, __isl_keep isl_map **may_rel, + __isl_take isl_flow *flow) +{ + int i, j; + + if (!acc->coscheduled) + return flow; + for (i = acc->n_must - 1; i >= 0; --i) { + isl_map *move; + + if (isl_map_plain_is_empty(must_rel[i])) + continue; + move = isl_map_empty(isl_map_get_space(must_rel[i])); + for (j = i - 1; j >= 0; --j) { + int depth; + isl_bool coscheduled; + isl_map *map, *factor; + + coscheduled = acc->coscheduled(acc->source[i].data, + acc->source[j].data); + if (coscheduled < 0) { + isl_map_free(move); + return isl_flow_free(flow); + } + if (!coscheduled) + continue; + depth = acc->level_before(acc->source[i].data, + acc->source[j].data) / 2; + map = coscheduled_source(acc, must_rel[i], j, depth); + factor = isl_map_domain_factor_range(isl_map_copy(map)); + may_rel[j] = isl_map_union(may_rel[j], factor); + map = isl_map_domain_factor_domain(map); + move = isl_map_union(move, map); + } + for (j = 0; j < acc->n_may; ++j) { + int depth, pos; + isl_bool coscheduled; + isl_map *map, *factor; + + pos = acc->n_must + j; + coscheduled = acc->coscheduled(acc->source[i].data, + acc->source[pos].data); + if (coscheduled < 0) { + isl_map_free(move); + return isl_flow_free(flow); + } + if (!coscheduled) + continue; + depth = acc->level_before(acc->source[i].data, + acc->source[pos].data) / 2; + map = coscheduled_source(acc, must_rel[i], pos, depth); + factor = isl_map_domain_factor_range(isl_map_copy(map)); + pos = 2 * acc->n_must + j; + flow->dep[pos].map = isl_map_union(flow->dep[pos].map, + factor); + map = isl_map_domain_factor_domain(map); + move = isl_map_union(move, map); + } + must_rel[i] = isl_map_subtract(must_rel[i], isl_map_copy(move)); + may_rel[i] = isl_map_union(may_rel[i], move); + } + + return flow; +} + +/* Compute dependences for the case where all accesses are "may" + * accesses, which boils down to computing memory based dependences. + * The generic algorithm would also work in this case, but it would + * be overkill to use it. + */ +static __isl_give isl_flow *compute_mem_based_dependences( + __isl_keep isl_access_info *acc) +{ + int i; + isl_set *mustdo; + isl_set *maydo; + isl_flow *res; + + res = isl_flow_alloc(acc); + if (!res) + return NULL; + + mustdo = isl_map_domain(isl_map_copy(acc->sink.map)); + maydo = isl_set_copy(mustdo); + + for (i = 0; i < acc->n_may; ++i) { + int plevel; + int is_before; + isl_space *space; + isl_map *before; + isl_map *dep; + + plevel = acc->level_before(acc->source[i].data, acc->sink.data); + if (plevel < 0) + goto error; + + is_before = plevel & 1; + plevel >>= 1; + + space = isl_map_get_space(res->dep[i].map); + if (is_before) + before = isl_map_lex_le_first(space, plevel); + else + before = isl_map_lex_lt_first(space, plevel); + dep = isl_map_apply_range(isl_map_copy(acc->source[i].map), + isl_map_reverse(isl_map_copy(acc->sink.map))); + dep = isl_map_intersect(dep, before); + mustdo = isl_set_subtract(mustdo, + isl_map_range(isl_map_copy(dep))); + res->dep[i].map = isl_map_union(res->dep[i].map, dep); + } + + res->may_no_source = isl_set_subtract(maydo, isl_set_copy(mustdo)); + res->must_no_source = mustdo; + + return res; +error: + isl_set_free(mustdo); + isl_set_free(maydo); + isl_flow_free(res); + return NULL; +} + +/* Compute dependences for the case where there is at least one + * "must" access. + * + * The core algorithm considers all levels in which a source may precede + * the sink, where a level may either be a statement level or a loop level. + * The outermost statement level is 1, the first loop level is 2, etc... + * The algorithm basically does the following: + * for all levels l of the read access from innermost to outermost + * for all sources w that may precede the sink access at that level + * compute the last iteration of the source that precedes the sink access + * at that level + * add result to possible last accesses at level l of source w + * for all sources w2 that we haven't considered yet at this level that may + * also precede the sink access + * for all levels l2 of w from l to innermost + * for all possible last accesses dep of w at l + * compute last iteration of w2 between the source and sink + * of dep + * add result to possible last accesses at level l of write w2 + * and replace possible last accesses dep by the remainder + * + * + * The above algorithm is applied to the must access. During the course + * of the algorithm, we keep track of sink iterations that still + * need to be considered. These iterations are split into those that + * haven't been matched to any source access (mustdo) and those that have only + * been matched to may accesses (maydo). + * At the end of each level, must-sources and may-sources that are coscheduled + * with the sources of the must-dependences at that level are considered. + * If any coscheduled instances are found, then corresponding may-dependences + * are added and the original must-dependences are turned into may-dependences. + * Afterwards, the may accesses that occur after must-dependence sources + * are considered. + * In particular, we consider may accesses that precede the remaining + * sink iterations, moving elements from mustdo to maydo when appropriate, + * and may accesses that occur between a must source and a sink of any + * dependences found at the current level, turning must dependences into + * may dependences when appropriate. + * + */ +static __isl_give isl_flow *compute_val_based_dependences( + __isl_keep isl_access_info *acc) +{ + isl_ctx *ctx; + isl_flow *res; + isl_set *mustdo = NULL; + isl_set *maydo = NULL; + int level, j; + isl_size n_in; + int depth; + isl_map **must_rel = NULL; + isl_map **may_rel = NULL; + + if (!acc) + return NULL; + + res = isl_flow_alloc(acc); + if (!res) + goto error; + ctx = isl_map_get_ctx(acc->sink.map); + + n_in = isl_map_dim(acc->sink.map, isl_dim_in); + if (n_in < 0) + goto error; + depth = 2 * n_in + 1; + mustdo = isl_map_domain(isl_map_copy(acc->sink.map)); + maydo = isl_set_empty(isl_set_get_space(mustdo)); + if (!mustdo || !maydo) + goto error; + if (isl_set_plain_is_empty(mustdo)) + goto done; + + must_rel = isl_calloc_array(ctx, struct isl_map *, acc->n_must); + may_rel = isl_calloc_array(ctx, struct isl_map *, acc->n_must); + if (!must_rel || !may_rel) + goto error; + + for (level = depth; level >= 1; --level) { + for (j = acc->n_must-1; j >=0; --j) { + isl_space *space; + space = isl_map_get_space(res->dep[2 * j].map); + must_rel[j] = isl_map_empty(space); + may_rel[j] = isl_map_copy(must_rel[j]); + } + + for (j = acc->n_must - 1; j >= 0; --j) { + struct isl_map *T; + struct isl_set *rest; + int plevel; + + plevel = acc->level_before(acc->source[j].data, + acc->sink.data); + if (plevel < 0) + goto error; + if (!can_precede_at_level(plevel, level)) + continue; + + T = last_source(acc, mustdo, j, level, &rest); + must_rel[j] = isl_map_union_disjoint(must_rel[j], T); + mustdo = rest; + + if (intermediate_sources(acc, must_rel, j, level) < 0) + goto error; + + T = last_source(acc, maydo, j, level, &rest); + may_rel[j] = isl_map_union_disjoint(may_rel[j], T); + maydo = rest; + + if (intermediate_sources(acc, may_rel, j, level) < 0) + goto error; + + if (isl_set_plain_is_empty(mustdo) && + isl_set_plain_is_empty(maydo)) + break; + } + for (j = j - 1; j >= 0; --j) { + int plevel; + + plevel = acc->level_before(acc->source[j].data, + acc->sink.data); + if (plevel < 0) + goto error; + if (!can_precede_at_level(plevel, level)) + continue; + + if (intermediate_sources(acc, must_rel, j, level) < 0) + goto error; + if (intermediate_sources(acc, may_rel, j, level) < 0) + goto error; + } + + res = handle_coscheduled(acc, must_rel, may_rel, res); + if (!res) + goto error; + + for (j = 0; j < acc->n_may; ++j) { + int plevel; + isl_map *T; + isl_set *ran; + + plevel = acc->level_before(acc->source[acc->n_must + j].data, + acc->sink.data); + if (plevel < 0) + goto error; + if (!can_precede_at_level(plevel, level)) + continue; + + T = all_sources(acc, isl_set_copy(maydo), j, level); + res->dep[2 * acc->n_must + j].map = + isl_map_union(res->dep[2 * acc->n_must + j].map, T); + T = all_sources(acc, isl_set_copy(mustdo), j, level); + ran = isl_map_range(isl_map_copy(T)); + res->dep[2 * acc->n_must + j].map = + isl_map_union(res->dep[2 * acc->n_must + j].map, T); + mustdo = isl_set_subtract(mustdo, isl_set_copy(ran)); + maydo = isl_set_union_disjoint(maydo, ran); + + T = res->dep[2 * acc->n_must + j].map; + T = all_intermediate_sources(acc, T, must_rel, may_rel, + j, level); + res->dep[2 * acc->n_must + j].map = T; + } + + for (j = acc->n_must - 1; j >= 0; --j) { + res->dep[2 * j].map = + isl_map_union_disjoint(res->dep[2 * j].map, + must_rel[j]); + res->dep[2 * j + 1].map = + isl_map_union_disjoint(res->dep[2 * j + 1].map, + may_rel[j]); + } + + if (isl_set_plain_is_empty(mustdo) && + isl_set_plain_is_empty(maydo)) + break; + } + + free(must_rel); + free(may_rel); +done: + res->must_no_source = mustdo; + res->may_no_source = maydo; + return res; +error: + if (must_rel) + for (j = 0; j < acc->n_must; ++j) + isl_map_free(must_rel[j]); + if (may_rel) + for (j = 0; j < acc->n_must; ++j) + isl_map_free(may_rel[j]); + isl_flow_free(res); + isl_set_free(mustdo); + isl_set_free(maydo); + free(must_rel); + free(may_rel); + return NULL; +} + +/* Given a "sink" access, a list of n "source" accesses, + * compute for each iteration of the sink access + * and for each element accessed by that iteration, + * the source access in the list that last accessed the + * element accessed by the sink access before this sink access. + * Each access is given as a map from the loop iterators + * to the array indices. + * The result is a list of n relations between source and sink + * iterations and a subset of the domain of the sink access, + * corresponding to those iterations that access an element + * not previously accessed. + * + * To deal with multi-valued sink access relations, the sink iteration + * domain is first extended with dimensions that correspond to the data + * space. However, these extra dimensions are not projected out again. + * It is up to the caller to decide whether these dimensions should be kept. + */ +static __isl_give isl_flow *access_info_compute_flow_core( + __isl_take isl_access_info *acc) +{ + struct isl_flow *res = NULL; + + if (!acc) + return NULL; + + acc->sink.map = isl_map_range_map(acc->sink.map); + if (!acc->sink.map) + goto error; + + if (acc->n_must == 0) + res = compute_mem_based_dependences(acc); + else { + acc = isl_access_info_sort_sources(acc); + res = compute_val_based_dependences(acc); + } + acc = isl_access_info_free(acc); + if (!res) + return NULL; + if (!res->must_no_source || !res->may_no_source) + goto error; + return res; +error: + isl_access_info_free(acc); + isl_flow_free(res); + return NULL; +} + +/* Given a "sink" access, a list of n "source" accesses, + * compute for each iteration of the sink access + * and for each element accessed by that iteration, + * the source access in the list that last accessed the + * element accessed by the sink access before this sink access. + * Each access is given as a map from the loop iterators + * to the array indices. + * The result is a list of n relations between source and sink + * iterations and a subset of the domain of the sink access, + * corresponding to those iterations that access an element + * not previously accessed. + * + * To deal with multi-valued sink access relations, + * access_info_compute_flow_core extends the sink iteration domain + * with dimensions that correspond to the data space. These extra dimensions + * are projected out from the result of access_info_compute_flow_core. + */ +__isl_give isl_flow *isl_access_info_compute_flow(__isl_take isl_access_info *acc) +{ + int j; + struct isl_flow *res; + + if (!acc) + return NULL; + + acc->domain_map = isl_map_domain_map(isl_map_copy(acc->sink.map)); + res = access_info_compute_flow_core(acc); + if (!res) + return NULL; + + for (j = 0; j < res->n_source; ++j) { + res->dep[j].map = isl_map_range_factor_domain(res->dep[j].map); + if (!res->dep[j].map) + goto error; + } + + return res; +error: + isl_flow_free(res); + return NULL; +} + + +/* Keep track of some information about a schedule for a given + * access. In particular, keep track of which dimensions + * have a constant value and of the actual constant values. + */ +struct isl_sched_info { + int *is_cst; + isl_vec *cst; +}; + +static void sched_info_free(__isl_take struct isl_sched_info *info) +{ + if (!info) + return; + isl_vec_free(info->cst); + free(info->is_cst); + free(info); +} + +/* Extract information on the constant dimensions of the schedule + * for a given access. The "map" is of the form + * + * [S -> D] -> A + * + * with S the schedule domain, D the iteration domain and A the data domain. + */ +static __isl_give struct isl_sched_info *sched_info_alloc( + __isl_keep isl_map *map) +{ + isl_ctx *ctx; + isl_space *space; + struct isl_sched_info *info; + int i; + isl_size n; + + if (!map) + return NULL; + + space = isl_space_unwrap(isl_space_domain(isl_map_get_space(map))); + if (!space) + return NULL; + n = isl_space_dim(space, isl_dim_in); + isl_space_free(space); + if (n < 0) + return NULL; + + ctx = isl_map_get_ctx(map); + info = isl_alloc_type(ctx, struct isl_sched_info); + if (!info) + return NULL; + info->is_cst = isl_alloc_array(ctx, int, n); + info->cst = isl_vec_alloc(ctx, n); + if (n && (!info->is_cst || !info->cst)) + goto error; + + for (i = 0; i < n; ++i) { + isl_val *v; + + v = isl_map_plain_get_val_if_fixed(map, isl_dim_in, i); + if (!v) + goto error; + info->is_cst[i] = !isl_val_is_nan(v); + if (info->is_cst[i]) + info->cst = isl_vec_set_element_val(info->cst, i, v); + else + isl_val_free(v); + } + + return info; +error: + sched_info_free(info); + return NULL; +} + +/* The different types of access relations that isl_union_access_info + * keeps track of. + + * "isl_access_sink" represents the sink accesses. + * "isl_access_must_source" represents the definite source accesses. + * "isl_access_may_source" represents the possible source accesses. + * "isl_access_kill" represents the kills. + * + * isl_access_sink is sometimes treated differently and + * should therefore appear first. + */ +enum isl_access_type { + isl_access_sink, + isl_access_must_source, + isl_access_may_source, + isl_access_kill, + isl_access_end +}; + +/* This structure represents the input for a dependence analysis computation. + * + * "access" contains the access relations. + * + * "schedule" or "schedule_map" represents the execution order. + * Exactly one of these fields should be NULL. The other field + * determines the execution order. + * + * The domains of these four maps refer to the same iteration spaces(s). + * The ranges of the first three maps also refer to the same data space(s). + * + * After a call to isl_union_access_info_introduce_schedule, + * the "schedule_map" field no longer contains useful information. + */ +struct isl_union_access_info { + isl_union_map *access[isl_access_end]; + + isl_schedule *schedule; + isl_union_map *schedule_map; +}; + +/* Free "access" and return NULL. + */ +__isl_null isl_union_access_info *isl_union_access_info_free( + __isl_take isl_union_access_info *access) +{ + enum isl_access_type i; + + if (!access) + return NULL; + + for (i = isl_access_sink; i < isl_access_end; ++i) + isl_union_map_free(access->access[i]); + isl_schedule_free(access->schedule); + isl_union_map_free(access->schedule_map); + free(access); + + return NULL; +} + +/* Return the isl_ctx to which "access" belongs. + */ +isl_ctx *isl_union_access_info_get_ctx(__isl_keep isl_union_access_info *access) +{ + if (!access) + return NULL; + return isl_union_map_get_ctx(access->access[isl_access_sink]); +} + +/* Construct an empty (invalid) isl_union_access_info object. + * The caller is responsible for setting the sink access relation and + * initializing all the other fields, e.g., by calling + * isl_union_access_info_init. + */ +static __isl_give isl_union_access_info *isl_union_access_info_alloc( + isl_ctx *ctx) +{ + return isl_calloc_type(ctx, isl_union_access_info); +} + +/* Initialize all the fields of "info", except the sink access relation, + * which is assumed to have been set by the caller. + * + * By default, we use the schedule field of the isl_union_access_info, + * but this may be overridden by a call + * to isl_union_access_info_set_schedule_map. + */ +static __isl_give isl_union_access_info *isl_union_access_info_init( + __isl_take isl_union_access_info *info) +{ + isl_space *space; + isl_union_map *empty; + enum isl_access_type i; + + if (!info) + return NULL; + if (!info->access[isl_access_sink]) + return isl_union_access_info_free(info); + + space = isl_union_map_get_space(info->access[isl_access_sink]); + empty = isl_union_map_empty(isl_space_copy(space)); + for (i = isl_access_sink + 1; i < isl_access_end; ++i) + if (!info->access[i]) + info->access[i] = isl_union_map_copy(empty); + isl_union_map_free(empty); + if (!info->schedule && !info->schedule_map) + info->schedule = isl_schedule_empty(isl_space_copy(space)); + isl_space_free(space); + + for (i = isl_access_sink + 1; i < isl_access_end; ++i) + if (!info->access[i]) + return isl_union_access_info_free(info); + if (!info->schedule && !info->schedule_map) + return isl_union_access_info_free(info); + + return info; +} + +/* Create a new isl_union_access_info with the given sink accesses and + * and no other accesses or schedule information. + */ +__isl_give isl_union_access_info *isl_union_access_info_from_sink( + __isl_take isl_union_map *sink) +{ + isl_ctx *ctx; + isl_union_access_info *access; + + if (!sink) + return NULL; + ctx = isl_union_map_get_ctx(sink); + access = isl_union_access_info_alloc(ctx); + if (!access) + goto error; + access->access[isl_access_sink] = sink; + return isl_union_access_info_init(access); +error: + isl_union_map_free(sink); + return NULL; +} + +/* Replace the access relation of type "type" of "info" by "access". + */ +static __isl_give isl_union_access_info *isl_union_access_info_set( + __isl_take isl_union_access_info *info, + enum isl_access_type type, __isl_take isl_union_map *access) +{ + if (!info || !access) + goto error; + + isl_union_map_free(info->access[type]); + info->access[type] = access; + + return info; +error: + isl_union_access_info_free(info); + isl_union_map_free(access); + return NULL; +} + +/* Replace the definite source accesses of "access" by "must_source". + */ +__isl_give isl_union_access_info *isl_union_access_info_set_must_source( + __isl_take isl_union_access_info *access, + __isl_take isl_union_map *must_source) +{ + return isl_union_access_info_set(access, isl_access_must_source, + must_source); +} + +/* Replace the possible source accesses of "access" by "may_source". + */ +__isl_give isl_union_access_info *isl_union_access_info_set_may_source( + __isl_take isl_union_access_info *access, + __isl_take isl_union_map *may_source) +{ + return isl_union_access_info_set(access, isl_access_may_source, + may_source); +} + +/* Replace the kills of "info" by "kill". + */ +__isl_give isl_union_access_info *isl_union_access_info_set_kill( + __isl_take isl_union_access_info *info, __isl_take isl_union_map *kill) +{ + return isl_union_access_info_set(info, isl_access_kill, kill); +} + +/* Return the access relation of type "type" of "info". + */ +static __isl_give isl_union_map *isl_union_access_info_get( + __isl_keep isl_union_access_info *info, enum isl_access_type type) +{ + if (!info) + return NULL; + return isl_union_map_copy(info->access[type]); +} + +/* Return the definite source accesses of "info". + */ +__isl_give isl_union_map *isl_union_access_info_get_must_source( + __isl_keep isl_union_access_info *info) +{ + return isl_union_access_info_get(info, isl_access_must_source); +} + +/* Return the possible source accesses of "info". + */ +__isl_give isl_union_map *isl_union_access_info_get_may_source( + __isl_keep isl_union_access_info *info) +{ + return isl_union_access_info_get(info, isl_access_may_source); +} + +/* Return the kills of "info". + */ +__isl_give isl_union_map *isl_union_access_info_get_kill( + __isl_keep isl_union_access_info *info) +{ + return isl_union_access_info_get(info, isl_access_kill); +} + +/* Does "info" specify any kills? + */ +static isl_bool isl_union_access_has_kill( + __isl_keep isl_union_access_info *info) +{ + isl_bool empty; + + if (!info) + return isl_bool_error; + empty = isl_union_map_is_empty(info->access[isl_access_kill]); + return isl_bool_not(empty); +} + +/* Replace the schedule of "access" by "schedule". + * Also free the schedule_map in case it was set last. + */ +__isl_give isl_union_access_info *isl_union_access_info_set_schedule( + __isl_take isl_union_access_info *access, + __isl_take isl_schedule *schedule) +{ + if (!access || !schedule) + goto error; + + access->schedule_map = isl_union_map_free(access->schedule_map); + isl_schedule_free(access->schedule); + access->schedule = schedule; + + return access; +error: + isl_union_access_info_free(access); + isl_schedule_free(schedule); + return NULL; +} + +/* Replace the schedule map of "access" by "schedule_map". + * Also free the schedule in case it was set last. + */ +__isl_give isl_union_access_info *isl_union_access_info_set_schedule_map( + __isl_take isl_union_access_info *access, + __isl_take isl_union_map *schedule_map) +{ + if (!access || !schedule_map) + goto error; + + isl_union_map_free(access->schedule_map); + access->schedule = isl_schedule_free(access->schedule); + access->schedule_map = schedule_map; + + return access; +error: + isl_union_access_info_free(access); + isl_union_map_free(schedule_map); + return NULL; +} + +__isl_give isl_union_access_info *isl_union_access_info_copy( + __isl_keep isl_union_access_info *access) +{ + isl_union_access_info *copy; + enum isl_access_type i; + + if (!access) + return NULL; + copy = isl_union_access_info_from_sink( + isl_union_map_copy(access->access[isl_access_sink])); + for (i = isl_access_sink + 1; i < isl_access_end; ++i) + copy = isl_union_access_info_set(copy, i, + isl_union_map_copy(access->access[i])); + if (access->schedule) + copy = isl_union_access_info_set_schedule(copy, + isl_schedule_copy(access->schedule)); + else + copy = isl_union_access_info_set_schedule_map(copy, + isl_union_map_copy(access->schedule_map)); + + return copy; +} + +#undef BASE +#define BASE union_map +#include "print_yaml_field_templ.c" + +/* An enumeration of the various keys that may appear in a YAML mapping + * of an isl_union_access_info object. + * The keys for the access relation types are assumed to have the same values + * as the access relation types in isl_access_type. + */ +enum isl_ai_key { + isl_ai_key_error = -1, + isl_ai_key_sink = isl_access_sink, + isl_ai_key_must_source = isl_access_must_source, + isl_ai_key_may_source = isl_access_may_source, + isl_ai_key_kill = isl_access_kill, + isl_ai_key_schedule_map, + isl_ai_key_schedule, + isl_ai_key_end +}; + +/* Textual representations of the YAML keys for an isl_union_access_info + * object. + */ +static char *key_str[] = { + [isl_ai_key_sink] = "sink", + [isl_ai_key_must_source] = "must_source", + [isl_ai_key_may_source] = "may_source", + [isl_ai_key_kill] = "kill", + [isl_ai_key_schedule_map] = "schedule_map", + [isl_ai_key_schedule] = "schedule", +}; + +/* Print a key-value pair corresponding to the access relation of type "type" + * of a YAML mapping of "info" to "p". + * + * The sink access relation is always printed, but any other access relation + * is only printed if it is non-empty. + */ +static __isl_give isl_printer *print_access_field(__isl_take isl_printer *p, + __isl_keep isl_union_access_info *info, enum isl_access_type type) +{ + if (type != isl_access_sink) { + isl_bool empty; + + empty = isl_union_map_is_empty(info->access[type]); + if (empty < 0) + return isl_printer_free(p); + if (empty) + return p; + } + return print_yaml_field_union_map(p, key_str[type], info->access[type]); +} + +/* Print the information contained in "access" to "p". + * The information is printed as a YAML document. + */ +__isl_give isl_printer *isl_printer_print_union_access_info( + __isl_take isl_printer *p, __isl_keep isl_union_access_info *access) +{ + enum isl_access_type i; + + if (!access) + return isl_printer_free(p); + + p = isl_printer_yaml_start_mapping(p); + for (i = isl_access_sink; i < isl_access_end; ++i) + p = print_access_field(p, access, i); + if (access->schedule) { + p = isl_printer_print_str(p, key_str[isl_ai_key_schedule]); + p = isl_printer_yaml_next(p); + p = isl_printer_print_schedule(p, access->schedule); + p = isl_printer_yaml_next(p); + } else { + p = print_yaml_field_union_map(p, + key_str[isl_ai_key_schedule_map], access->schedule_map); + } + p = isl_printer_yaml_end_mapping(p); + + return p; +} + +/* Return a string representation of the information in "access". + * The information is printed in flow format. + */ +__isl_give char *isl_union_access_info_to_str( + __isl_keep isl_union_access_info *access) +{ + isl_printer *p; + char *s; + + if (!access) + return NULL; + + p = isl_printer_to_str(isl_union_access_info_get_ctx(access)); + p = isl_printer_set_yaml_style(p, ISL_YAML_STYLE_FLOW); + p = isl_printer_print_union_access_info(p, access); + s = isl_printer_get_str(p); + isl_printer_free(p); + + return s; +} + +#undef KEY +#define KEY enum isl_ai_key +#undef KEY_ERROR +#define KEY_ERROR isl_ai_key_error +#undef KEY_END +#define KEY_END isl_ai_key_end +#undef KEY_STR +#define KEY_STR key_str +#undef KEY_EXTRACT +#define KEY_EXTRACT extract_key +#undef KEY_GET +#define KEY_GET get_key +#include "extract_key.c" + +#undef BASE +#define BASE union_map +#include "read_in_string_templ.c" + +/* Read an isl_union_access_info object from "s". + * + * Start off with an empty (invalid) isl_union_access_info object and + * then fill up the fields based on the input. + * The input needs to contain at least a description of the sink + * access relation as well as some form of schedule. + * The other access relations are set to empty relations + * by isl_union_access_info_init if they are not specified in the input. + */ +__isl_give isl_union_access_info *isl_stream_read_union_access_info( + isl_stream *s) +{ + isl_ctx *ctx; + isl_union_access_info *info; + isl_bool more; + int sink_set = 0; + int schedule_set = 0; + + if (isl_stream_yaml_read_start_mapping(s) < 0) + return NULL; + + ctx = isl_stream_get_ctx(s); + info = isl_union_access_info_alloc(ctx); + while ((more = isl_stream_yaml_next(s)) == isl_bool_true) { + enum isl_ai_key key; + enum isl_access_type type; + isl_union_map *access, *schedule_map; + isl_schedule *schedule; + + key = get_key(s); + if (isl_stream_yaml_next(s) < 0) + return isl_union_access_info_free(info); + switch (key) { + case isl_ai_key_end: + case isl_ai_key_error: + return isl_union_access_info_free(info); + case isl_ai_key_sink: + sink_set = 1; + case isl_ai_key_must_source: + case isl_ai_key_may_source: + case isl_ai_key_kill: + type = (enum isl_access_type) key; + access = read_union_map(s); + info = isl_union_access_info_set(info, type, access); + if (!info) + return NULL; + break; + case isl_ai_key_schedule_map: + schedule_set = 1; + schedule_map = read_union_map(s); + info = isl_union_access_info_set_schedule_map(info, + schedule_map); + if (!info) + return NULL; + break; + case isl_ai_key_schedule: + schedule_set = 1; + schedule = isl_stream_read_schedule(s); + info = isl_union_access_info_set_schedule(info, + schedule); + if (!info) + return NULL; + break; + } + } + if (more < 0) + return isl_union_access_info_free(info); + + if (isl_stream_yaml_read_end_mapping(s) < 0) + return isl_union_access_info_free(info); + + if (!sink_set) { + isl_stream_error(s, NULL, "no sink specified"); + return isl_union_access_info_free(info); + } + + if (!schedule_set) { + isl_stream_error(s, NULL, "no schedule specified"); + return isl_union_access_info_free(info); + } + + return isl_union_access_info_init(info); +} + +/* Read an isl_union_access_info object from the file "input". + */ +__isl_give isl_union_access_info *isl_union_access_info_read_from_file( + isl_ctx *ctx, FILE *input) +{ + isl_stream *s; + isl_union_access_info *access; + + s = isl_stream_new_file(ctx, input); + if (!s) + return NULL; + access = isl_stream_read_union_access_info(s); + isl_stream_free(s); + + return access; +} + +/* Update the fields of "access" such that they all have the same parameters, + * keeping in mind that the schedule_map field may be NULL and ignoring + * the schedule field. + */ +static __isl_give isl_union_access_info *isl_union_access_info_align_params( + __isl_take isl_union_access_info *access) +{ + isl_space *space; + enum isl_access_type i; + + if (!access) + return NULL; + + space = isl_union_map_get_space(access->access[isl_access_sink]); + for (i = isl_access_sink + 1; i < isl_access_end; ++i) + space = isl_space_align_params(space, + isl_union_map_get_space(access->access[i])); + if (access->schedule_map) + space = isl_space_align_params(space, + isl_union_map_get_space(access->schedule_map)); + for (i = isl_access_sink; i < isl_access_end; ++i) + access->access[i] = + isl_union_map_align_params(access->access[i], + isl_space_copy(space)); + if (!access->schedule_map) { + isl_space_free(space); + } else { + access->schedule_map = + isl_union_map_align_params(access->schedule_map, space); + if (!access->schedule_map) + return isl_union_access_info_free(access); + } + + for (i = isl_access_sink; i < isl_access_end; ++i) + if (!access->access[i]) + return isl_union_access_info_free(access); + + return access; +} + +/* Prepend the schedule dimensions to the iteration domains. + * + * That is, if the schedule is of the form + * + * D -> S + * + * while the access relations are of the form + * + * D -> A + * + * then the updated access relations are of the form + * + * [S -> D] -> A + * + * The schedule map is also replaced by the map + * + * [S -> D] -> D + * + * that is used during the internal computation. + * Neither the original schedule map nor this updated schedule map + * are used after the call to this function. + */ +static __isl_give isl_union_access_info * +isl_union_access_info_introduce_schedule( + __isl_take isl_union_access_info *access) +{ + isl_union_map *sm; + enum isl_access_type i; + + if (!access) + return NULL; + + sm = isl_union_map_reverse(access->schedule_map); + sm = isl_union_map_range_map(sm); + for (i = isl_access_sink; i < isl_access_end; ++i) + access->access[i] = + isl_union_map_apply_range(isl_union_map_copy(sm), + access->access[i]); + access->schedule_map = sm; + + for (i = isl_access_sink; i < isl_access_end; ++i) + if (!access->access[i]) + return isl_union_access_info_free(access); + if (!access->schedule_map) + return isl_union_access_info_free(access); + + return access; +} + +/* This structure represents the result of a dependence analysis computation. + * + * "must_dep" represents the full definite dependences + * "may_dep" represents the full non-definite dependences. + * Both are of the form + * + * [Source] -> [[Sink -> Data]] + * + * (after the schedule dimensions have been projected out). + * "must_no_source" represents the subset of the sink accesses for which + * definitely no source was found. + * "may_no_source" represents the subset of the sink accesses for which + * possibly, but not definitely, no source was found. + */ +struct isl_union_flow { + isl_union_map *must_dep; + isl_union_map *may_dep; + isl_union_map *must_no_source; + isl_union_map *may_no_source; +}; + +/* Return the isl_ctx to which "flow" belongs. + */ +isl_ctx *isl_union_flow_get_ctx(__isl_keep isl_union_flow *flow) +{ + return flow ? isl_union_map_get_ctx(flow->must_dep) : NULL; +} + +/* Free "flow" and return NULL. + */ +__isl_null isl_union_flow *isl_union_flow_free(__isl_take isl_union_flow *flow) +{ + if (!flow) + return NULL; + isl_union_map_free(flow->must_dep); + isl_union_map_free(flow->may_dep); + isl_union_map_free(flow->must_no_source); + isl_union_map_free(flow->may_no_source); + free(flow); + return NULL; +} + +void isl_union_flow_dump(__isl_keep isl_union_flow *flow) +{ + if (!flow) + return; + + fprintf(stderr, "must dependences: "); + isl_union_map_dump(flow->must_dep); + fprintf(stderr, "may dependences: "); + isl_union_map_dump(flow->may_dep); + fprintf(stderr, "must no source: "); + isl_union_map_dump(flow->must_no_source); + fprintf(stderr, "may no source: "); + isl_union_map_dump(flow->may_no_source); +} + +/* Return the full definite dependences in "flow", with accessed elements. + */ +__isl_give isl_union_map *isl_union_flow_get_full_must_dependence( + __isl_keep isl_union_flow *flow) +{ + if (!flow) + return NULL; + return isl_union_map_copy(flow->must_dep); +} + +/* Return the full possible dependences in "flow", including the definite + * dependences, with accessed elements. + */ +__isl_give isl_union_map *isl_union_flow_get_full_may_dependence( + __isl_keep isl_union_flow *flow) +{ + if (!flow) + return NULL; + return isl_union_map_union(isl_union_map_copy(flow->must_dep), + isl_union_map_copy(flow->may_dep)); +} + +/* Return the definite dependences in "flow", without the accessed elements. + */ +__isl_give isl_union_map *isl_union_flow_get_must_dependence( + __isl_keep isl_union_flow *flow) +{ + isl_union_map *dep; + + if (!flow) + return NULL; + dep = isl_union_map_copy(flow->must_dep); + return isl_union_map_range_factor_domain(dep); +} + +/* Return the possible dependences in "flow", including the definite + * dependences, without the accessed elements. + */ +__isl_give isl_union_map *isl_union_flow_get_may_dependence( + __isl_keep isl_union_flow *flow) +{ + isl_union_map *dep; + + if (!flow) + return NULL; + dep = isl_union_map_union(isl_union_map_copy(flow->must_dep), + isl_union_map_copy(flow->may_dep)); + return isl_union_map_range_factor_domain(dep); +} + +/* Return the non-definite dependences in "flow". + */ +static __isl_give isl_union_map *isl_union_flow_get_non_must_dependence( + __isl_keep isl_union_flow *flow) +{ + if (!flow) + return NULL; + return isl_union_map_copy(flow->may_dep); +} + +/* Return the subset of the sink accesses for which definitely + * no source was found. + */ +__isl_give isl_union_map *isl_union_flow_get_must_no_source( + __isl_keep isl_union_flow *flow) +{ + if (!flow) + return NULL; + return isl_union_map_copy(flow->must_no_source); +} + +/* Return the subset of the sink accesses for which possibly + * no source was found, including those for which definitely + * no source was found. + */ +__isl_give isl_union_map *isl_union_flow_get_may_no_source( + __isl_keep isl_union_flow *flow) +{ + if (!flow) + return NULL; + return isl_union_map_union(isl_union_map_copy(flow->must_no_source), + isl_union_map_copy(flow->may_no_source)); +} + +/* Return the subset of the sink accesses for which possibly, but not + * definitely, no source was found. + */ +static __isl_give isl_union_map *isl_union_flow_get_non_must_no_source( + __isl_keep isl_union_flow *flow) +{ + if (!flow) + return NULL; + return isl_union_map_copy(flow->may_no_source); +} + +/* Create a new isl_union_flow object, initialized with empty + * dependence relations and sink subsets. + */ +static __isl_give isl_union_flow *isl_union_flow_alloc( + __isl_take isl_space *space) +{ + isl_ctx *ctx; + isl_union_map *empty; + isl_union_flow *flow; + + if (!space) + return NULL; + ctx = isl_space_get_ctx(space); + flow = isl_alloc_type(ctx, isl_union_flow); + if (!flow) + goto error; + + empty = isl_union_map_empty(space); + flow->must_dep = isl_union_map_copy(empty); + flow->may_dep = isl_union_map_copy(empty); + flow->must_no_source = isl_union_map_copy(empty); + flow->may_no_source = empty; + + if (!flow->must_dep || !flow->may_dep || + !flow->must_no_source || !flow->may_no_source) + return isl_union_flow_free(flow); + + return flow; +error: + isl_space_free(space); + return NULL; +} + +/* Copy this isl_union_flow object. + */ +__isl_give isl_union_flow *isl_union_flow_copy(__isl_keep isl_union_flow *flow) +{ + isl_union_flow *copy; + + if (!flow) + return NULL; + + copy = isl_union_flow_alloc(isl_union_map_get_space(flow->must_dep)); + + if (!copy) + return NULL; + + copy->must_dep = isl_union_map_union(copy->must_dep, + isl_union_map_copy(flow->must_dep)); + copy->may_dep = isl_union_map_union(copy->may_dep, + isl_union_map_copy(flow->may_dep)); + copy->must_no_source = isl_union_map_union(copy->must_no_source, + isl_union_map_copy(flow->must_no_source)); + copy->may_no_source = isl_union_map_union(copy->may_no_source, + isl_union_map_copy(flow->may_no_source)); + + if (!copy->must_dep || !copy->may_dep || + !copy->must_no_source || !copy->may_no_source) + return isl_union_flow_free(copy); + + return copy; +} + +/* Drop the schedule dimensions from the iteration domains in "flow". + * In particular, the schedule dimensions have been prepended + * to the iteration domains prior to the dependence analysis by + * replacing the iteration domain D, by the wrapped map [S -> D]. + * Replace these wrapped maps by the original D. + * + * In particular, the dependences computed by access_info_compute_flow_core + * are of the form + * + * [S -> D] -> [[S' -> D'] -> A] + * + * The schedule dimensions are projected out by first currying the range, + * resulting in + * + * [S -> D] -> [S' -> [D' -> A]] + * + * and then computing the factor range + * + * D -> [D' -> A] + */ +static __isl_give isl_union_flow *isl_union_flow_drop_schedule( + __isl_take isl_union_flow *flow) +{ + if (!flow) + return NULL; + + flow->must_dep = isl_union_map_range_curry(flow->must_dep); + flow->must_dep = isl_union_map_factor_range(flow->must_dep); + flow->may_dep = isl_union_map_range_curry(flow->may_dep); + flow->may_dep = isl_union_map_factor_range(flow->may_dep); + flow->must_no_source = + isl_union_map_domain_factor_range(flow->must_no_source); + flow->may_no_source = + isl_union_map_domain_factor_range(flow->may_no_source); + + if (!flow->must_dep || !flow->may_dep || + !flow->must_no_source || !flow->may_no_source) + return isl_union_flow_free(flow); + + return flow; +} + +struct isl_compute_flow_data { + isl_union_map *must_source; + isl_union_map *may_source; + isl_union_flow *flow; + + int count; + int must; + isl_space *dim; + struct isl_sched_info *sink_info; + struct isl_sched_info **source_info; + isl_access_info *accesses; +}; + +static isl_stat count_matching_array(__isl_take isl_map *map, void *user) +{ + int eq; + isl_space *space; + struct isl_compute_flow_data *data; + + data = (struct isl_compute_flow_data *)user; + + space = isl_space_range(isl_map_get_space(map)); + + eq = isl_space_is_equal(space, data->dim); + + isl_space_free(space); + isl_map_free(map); + + if (eq < 0) + return isl_stat_error; + if (eq) + data->count++; + + return isl_stat_ok; +} + +static isl_stat collect_matching_array(__isl_take isl_map *map, void *user) +{ + int eq; + isl_space *space; + struct isl_sched_info *info; + struct isl_compute_flow_data *data; + + data = (struct isl_compute_flow_data *)user; + + space = isl_space_range(isl_map_get_space(map)); + + eq = isl_space_is_equal(space, data->dim); + + isl_space_free(space); + + if (eq < 0) + goto error; + if (!eq) { + isl_map_free(map); + return isl_stat_ok; + } + + info = sched_info_alloc(map); + data->source_info[data->count] = info; + + data->accesses = isl_access_info_add_source(data->accesses, + map, data->must, info); + + data->count++; + + return isl_stat_ok; +error: + isl_map_free(map); + return isl_stat_error; +} + +/* Determine the shared nesting level and the "textual order" of + * the given accesses. + * + * We first determine the minimal schedule dimension for both accesses. + * + * If among those dimensions, we can find one where both have a fixed + * value and if moreover those values are different, then the previous + * dimension is the last shared nesting level and the textual order + * is determined based on the order of the fixed values. + * If no such fixed values can be found, then we set the shared + * nesting level to the minimal schedule dimension, with no textual ordering. + */ +static int before(void *first, void *second) +{ + struct isl_sched_info *info1 = first; + struct isl_sched_info *info2 = second; + isl_size n1, n2; + int i; + + n1 = isl_vec_size(info1->cst); + n2 = isl_vec_size(info2->cst); + if (n1 < 0 || n2 < 0) + return -1; + + if (n2 < n1) + n1 = n2; + + for (i = 0; i < n1; ++i) { + int r; + int cmp; + + if (!info1->is_cst[i]) + continue; + if (!info2->is_cst[i]) + continue; + cmp = isl_vec_cmp_element(info1->cst, info2->cst, i); + if (cmp == 0) + continue; + + r = 2 * i + (cmp < 0); + + return r; + } + + return 2 * n1; +} + +/* Check if the given two accesses may be coscheduled. + * If so, return isl_bool_true. Otherwise return isl_bool_false. + * + * Two accesses may only be coscheduled if the fixed schedule + * coordinates have the same values. + */ +static isl_bool coscheduled(void *first, void *second) +{ + struct isl_sched_info *info1 = first; + struct isl_sched_info *info2 = second; + isl_size n1, n2; + int i; + + n1 = isl_vec_size(info1->cst); + n2 = isl_vec_size(info2->cst); + if (n1 < 0 || n2 < 0) + return isl_bool_error; + + if (n2 < n1) + n1 = n2; + + for (i = 0; i < n1; ++i) { + int cmp; + + if (!info1->is_cst[i]) + continue; + if (!info2->is_cst[i]) + continue; + cmp = isl_vec_cmp_element(info1->cst, info2->cst, i); + if (cmp != 0) + return isl_bool_false; + } + + return isl_bool_true; +} + +/* Given a sink access, look for all the source accesses that access + * the same array and perform dataflow analysis on them using + * isl_access_info_compute_flow_core. + */ +static isl_stat compute_flow(__isl_take isl_map *map, void *user) +{ + int i; + isl_ctx *ctx; + struct isl_compute_flow_data *data; + isl_flow *flow; + isl_union_flow *df; + + data = (struct isl_compute_flow_data *)user; + df = data->flow; + + ctx = isl_map_get_ctx(map); + + data->accesses = NULL; + data->sink_info = NULL; + data->source_info = NULL; + data->count = 0; + data->dim = isl_space_range(isl_map_get_space(map)); + + if (isl_union_map_foreach_map(data->must_source, + &count_matching_array, data) < 0) + goto error; + if (isl_union_map_foreach_map(data->may_source, + &count_matching_array, data) < 0) + goto error; + + data->sink_info = sched_info_alloc(map); + data->source_info = isl_calloc_array(ctx, struct isl_sched_info *, + data->count); + + data->accesses = isl_access_info_alloc(isl_map_copy(map), + data->sink_info, &before, data->count); + if (!data->sink_info || (data->count && !data->source_info) || + !data->accesses) + goto error; + data->accesses->coscheduled = &coscheduled; + data->count = 0; + data->must = 1; + if (isl_union_map_foreach_map(data->must_source, + &collect_matching_array, data) < 0) + goto error; + data->must = 0; + if (isl_union_map_foreach_map(data->may_source, + &collect_matching_array, data) < 0) + goto error; + + flow = access_info_compute_flow_core(data->accesses); + data->accesses = NULL; + + if (!flow) + goto error; + + df->must_no_source = isl_union_map_union(df->must_no_source, + isl_union_map_from_map(isl_flow_get_no_source(flow, 1))); + df->may_no_source = isl_union_map_union(df->may_no_source, + isl_union_map_from_map(isl_flow_get_no_source(flow, 0))); + + for (i = 0; i < flow->n_source; ++i) { + isl_union_map *dep; + dep = isl_union_map_from_map(isl_map_copy(flow->dep[i].map)); + if (flow->dep[i].must) + df->must_dep = isl_union_map_union(df->must_dep, dep); + else + df->may_dep = isl_union_map_union(df->may_dep, dep); + } + + isl_flow_free(flow); + + sched_info_free(data->sink_info); + if (data->source_info) { + for (i = 0; i < data->count; ++i) + sched_info_free(data->source_info[i]); + free(data->source_info); + } + isl_space_free(data->dim); + isl_map_free(map); + + return isl_stat_ok; +error: + isl_access_info_free(data->accesses); + sched_info_free(data->sink_info); + if (data->source_info) { + for (i = 0; i < data->count; ++i) + sched_info_free(data->source_info[i]); + free(data->source_info); + } + isl_space_free(data->dim); + isl_map_free(map); + + return isl_stat_error; +} + +/* Add the kills of "info" to the must-sources. + */ +static __isl_give isl_union_access_info * +isl_union_access_info_add_kill_to_must_source( + __isl_take isl_union_access_info *info) +{ + isl_union_map *must, *kill; + + must = isl_union_access_info_get_must_source(info); + kill = isl_union_access_info_get_kill(info); + must = isl_union_map_union(must, kill); + return isl_union_access_info_set_must_source(info, must); +} + +/* Drop dependences from "flow" that purely originate from kills. + * That is, only keep those dependences that originate from + * the original must-sources "must" and/or the original may-sources "may". + * In particular, "must" contains the must-sources from before + * the kills were added and "may" contains the may-source from before + * the kills were removed. + * + * The dependences are of the form + * + * Source -> [Sink -> Data] + * + * Only those dependences are kept where the Source -> Data part + * is a subset of the original may-sources or must-sources. + * Of those, only the must-dependences that intersect with the must-sources + * remain must-dependences. + * If there is some overlap between the may-sources and the must-sources, + * then the may-dependences and must-dependences may also overlap. + * This should be fine since the may-dependences are only kept + * disjoint from the must-dependences for the isl_union_map_compute_flow + * interface. This interface does not support kills, so it will + * not end up calling this function. + */ +static __isl_give isl_union_flow *isl_union_flow_drop_kill_source( + __isl_take isl_union_flow *flow, __isl_take isl_union_map *must, + __isl_take isl_union_map *may) +{ + isl_union_map *move; + + if (!flow) + goto error; + move = isl_union_map_copy(flow->must_dep); + move = isl_union_map_intersect_range_factor_range(move, + isl_union_map_copy(may)); + may = isl_union_map_union(may, isl_union_map_copy(must)); + flow->may_dep = isl_union_map_intersect_range_factor_range( + flow->may_dep, may); + flow->must_dep = isl_union_map_intersect_range_factor_range( + flow->must_dep, must); + flow->may_dep = isl_union_map_union(flow->may_dep, move); + if (!flow->must_dep || !flow->may_dep) + return isl_union_flow_free(flow); + + return flow; +error: + isl_union_map_free(must); + isl_union_map_free(may); + return NULL; +} + +/* Remove the must accesses from the may accesses. + * + * A must access always trumps a may access, so there is no need + * for a must access to also be considered as a may access. Doing so + * would only cost extra computations only to find out that + * the duplicated may access does not make any difference. + */ +static __isl_give isl_union_access_info *isl_union_access_info_normalize( + __isl_take isl_union_access_info *access) +{ + if (!access) + return NULL; + access->access[isl_access_may_source] = + isl_union_map_subtract(access->access[isl_access_may_source], + isl_union_map_copy(access->access[isl_access_must_source])); + if (!access->access[isl_access_may_source]) + return isl_union_access_info_free(access); + + return access; +} + +/* Given a description of the "sink" accesses, the "source" accesses and + * a schedule, compute for each instance of a sink access + * and for each element accessed by that instance, + * the possible or definite source accesses that last accessed the + * element accessed by the sink access before this sink access + * in the sense that there is no intermediate definite source access. + * + * The must_no_source and may_no_source elements of the result + * are subsets of access->sink. The elements must_dep and may_dep + * map domain elements of access->{may,must)_source to + * domain elements of access->sink. + * + * This function is used when only the schedule map representation + * is available. + * + * We first prepend the schedule dimensions to the domain + * of the accesses so that we can easily compare their relative order. + * Then we consider each sink access individually in compute_flow. + */ +static __isl_give isl_union_flow *compute_flow_union_map( + __isl_take isl_union_access_info *access) +{ + struct isl_compute_flow_data data; + isl_union_map *sink; + + access = isl_union_access_info_align_params(access); + access = isl_union_access_info_introduce_schedule(access); + if (!access) + return NULL; + + data.must_source = access->access[isl_access_must_source]; + data.may_source = access->access[isl_access_may_source]; + + sink = access->access[isl_access_sink]; + data.flow = isl_union_flow_alloc(isl_union_map_get_space(sink)); + + if (isl_union_map_foreach_map(sink, &compute_flow, &data) < 0) + goto error; + + data.flow = isl_union_flow_drop_schedule(data.flow); + + isl_union_access_info_free(access); + return data.flow; +error: + isl_union_access_info_free(access); + isl_union_flow_free(data.flow); + return NULL; +} + +/* A schedule access relation. + * + * The access relation "access" is of the form [S -> D] -> A, + * where S corresponds to the prefix schedule at "node". + * "must" is only relevant for source accesses and indicates + * whether the access is a must source or a may source. + */ +struct isl_scheduled_access { + isl_map *access; + int must; + isl_schedule_node *node; +}; + +/* Data structure for keeping track of individual scheduled sink and source + * accesses when computing dependence analysis based on a schedule tree. + * + * "n_sink" is the number of used entries in "sink" + * "n_source" is the number of used entries in "source" + * + * "set_sink", "must" and "node" are only used inside collect_sink_source, + * to keep track of the current node and + * of what extract_sink_source needs to do. + */ +struct isl_compute_flow_schedule_data { + isl_union_access_info *access; + + int n_sink; + int n_source; + + struct isl_scheduled_access *sink; + struct isl_scheduled_access *source; + + int set_sink; + int must; + isl_schedule_node *node; +}; + +/* Align the parameters of all sinks with all sources. + * + * If there are no sinks or no sources, then no alignment is needed. + */ +static void isl_compute_flow_schedule_data_align_params( + struct isl_compute_flow_schedule_data *data) +{ + int i; + isl_space *space; + + if (data->n_sink == 0 || data->n_source == 0) + return; + + space = isl_map_get_space(data->sink[0].access); + + for (i = 1; i < data->n_sink; ++i) + space = isl_space_align_params(space, + isl_map_get_space(data->sink[i].access)); + for (i = 0; i < data->n_source; ++i) + space = isl_space_align_params(space, + isl_map_get_space(data->source[i].access)); + + for (i = 0; i < data->n_sink; ++i) + data->sink[i].access = + isl_map_align_params(data->sink[i].access, + isl_space_copy(space)); + for (i = 0; i < data->n_source; ++i) + data->source[i].access = + isl_map_align_params(data->source[i].access, + isl_space_copy(space)); + + isl_space_free(space); +} + +/* Free all the memory referenced from "data". + * Do not free "data" itself as it may be allocated on the stack. + */ +static void isl_compute_flow_schedule_data_clear( + struct isl_compute_flow_schedule_data *data) +{ + int i; + + if (!data->sink) + return; + + for (i = 0; i < data->n_sink; ++i) { + isl_map_free(data->sink[i].access); + isl_schedule_node_free(data->sink[i].node); + } + + for (i = 0; i < data->n_source; ++i) { + isl_map_free(data->source[i].access); + isl_schedule_node_free(data->source[i].node); + } + + free(data->sink); +} + +/* isl_schedule_foreach_schedule_node_top_down callback for counting + * (an upper bound on) the number of sinks and sources. + * + * Sinks and sources are only extracted at leaves of the tree, + * so we skip the node if it is not a leaf. + * Otherwise we increment data->n_sink and data->n_source with + * the number of spaces in the sink and source access domains + * that reach this node. + */ +static isl_bool count_sink_source(__isl_keep isl_schedule_node *node, + void *user) +{ + struct isl_compute_flow_schedule_data *data = user; + isl_union_set *domain; + isl_union_map *umap; + isl_bool r = isl_bool_false; + isl_size n; + + if (isl_schedule_node_get_type(node) != isl_schedule_node_leaf) + return isl_bool_true; + + domain = isl_schedule_node_get_universe_domain(node); + + umap = isl_union_map_copy(data->access->access[isl_access_sink]); + umap = isl_union_map_intersect_domain(umap, isl_union_set_copy(domain)); + data->n_sink += n = isl_union_map_n_map(umap); + isl_union_map_free(umap); + if (n < 0) + r = isl_bool_error; + + umap = isl_union_map_copy(data->access->access[isl_access_must_source]); + umap = isl_union_map_intersect_domain(umap, isl_union_set_copy(domain)); + data->n_source += n = isl_union_map_n_map(umap); + isl_union_map_free(umap); + if (n < 0) + r = isl_bool_error; + + umap = isl_union_map_copy(data->access->access[isl_access_may_source]); + umap = isl_union_map_intersect_domain(umap, isl_union_set_copy(domain)); + data->n_source += n = isl_union_map_n_map(umap); + isl_union_map_free(umap); + if (n < 0) + r = isl_bool_error; + + isl_union_set_free(domain); + + return r; +} + +/* Add a single scheduled sink or source (depending on data->set_sink) + * with scheduled access relation "map", must property data->must and + * schedule node data->node to the list of sinks or sources. + */ +static isl_stat extract_sink_source(__isl_take isl_map *map, void *user) +{ + struct isl_compute_flow_schedule_data *data = user; + struct isl_scheduled_access *access; + + if (data->set_sink) + access = data->sink + data->n_sink++; + else + access = data->source + data->n_source++; + + access->access = map; + access->must = data->must; + access->node = isl_schedule_node_copy(data->node); + + return isl_stat_ok; +} + +/* isl_schedule_foreach_schedule_node_top_down callback for collecting + * individual scheduled source and sink accesses (taking into account + * the domain of the schedule). + * + * We only collect accesses at the leaves of the schedule tree. + * We prepend the schedule dimensions at the leaf to the iteration + * domains of the source and sink accesses and then extract + * the individual accesses (per space). + * + * In particular, if the prefix schedule at the node is of the form + * + * D -> S + * + * while the access relations are of the form + * + * D -> A + * + * then the updated access relations are of the form + * + * [S -> D] -> A + * + * Note that S consists of a single space such that introducing S + * in the access relations does not increase the number of spaces. + */ +static isl_bool collect_sink_source(__isl_keep isl_schedule_node *node, + void *user) +{ + struct isl_compute_flow_schedule_data *data = user; + isl_union_map *prefix; + isl_union_map *umap; + isl_bool r = isl_bool_false; + + if (isl_schedule_node_get_type(node) != isl_schedule_node_leaf) + return isl_bool_true; + + data->node = node; + + prefix = isl_schedule_node_get_prefix_schedule_relation(node); + prefix = isl_union_map_reverse(prefix); + prefix = isl_union_map_range_map(prefix); + + data->set_sink = 1; + umap = isl_union_map_copy(data->access->access[isl_access_sink]); + umap = isl_union_map_apply_range(isl_union_map_copy(prefix), umap); + if (isl_union_map_foreach_map(umap, &extract_sink_source, data) < 0) + r = isl_bool_error; + isl_union_map_free(umap); + + data->set_sink = 0; + data->must = 1; + umap = isl_union_map_copy(data->access->access[isl_access_must_source]); + umap = isl_union_map_apply_range(isl_union_map_copy(prefix), umap); + if (isl_union_map_foreach_map(umap, &extract_sink_source, data) < 0) + r = isl_bool_error; + isl_union_map_free(umap); + + data->set_sink = 0; + data->must = 0; + umap = isl_union_map_copy(data->access->access[isl_access_may_source]); + umap = isl_union_map_apply_range(isl_union_map_copy(prefix), umap); + if (isl_union_map_foreach_map(umap, &extract_sink_source, data) < 0) + r = isl_bool_error; + isl_union_map_free(umap); + + isl_union_map_free(prefix); + + return r; +} + +/* isl_access_info_compute_flow callback for determining whether + * the shared nesting level and the ordering within that level + * for two scheduled accesses for use in compute_single_flow. + * + * The tokens passed to this function refer to the leaves + * in the schedule tree where the accesses take place. + * + * If n is the shared number of loops, then we need to return + * "2 * n + 1" if "first" precedes "second" inside the innermost + * shared loop and "2 * n" otherwise. + * + * The innermost shared ancestor may be the leaves themselves + * if the accesses take place in the same leaf. Otherwise, + * it is either a set node or a sequence node. Only in the case + * of a sequence node do we consider one access to precede the other. + */ +static int before_node(void *first, void *second) +{ + isl_schedule_node *node1 = first; + isl_schedule_node *node2 = second; + isl_schedule_node *shared; + isl_size depth; + int before = 0; + + shared = isl_schedule_node_get_shared_ancestor(node1, node2); + depth = isl_schedule_node_get_schedule_depth(shared); + if (depth < 0) { + isl_schedule_node_free(shared); + return -1; + } + + if (isl_schedule_node_get_type(shared) == isl_schedule_node_sequence) { + isl_size pos1, pos2; + + pos1 = isl_schedule_node_get_ancestor_child_position(node1, + shared); + pos2 = isl_schedule_node_get_ancestor_child_position(node2, + shared); + if (pos1 < 0 || pos2 < 0) { + isl_schedule_node_free(shared); + return -1; + } + before = pos1 < pos2; + } + + isl_schedule_node_free(shared); + + return 2 * depth + before; +} + +/* Check if the given two accesses may be coscheduled. + * If so, return isl_bool_true. Otherwise return isl_bool_false. + * + * Two accesses may only be coscheduled if they appear in the same leaf. + */ +static isl_bool coscheduled_node(void *first, void *second) +{ + isl_schedule_node *node1 = first; + isl_schedule_node *node2 = second; + + return isl_bool_ok(node1 == node2); +} + +/* Add the scheduled sources from "data" that access + * the same data space as "sink" to "access". + */ +static __isl_give isl_access_info *add_matching_sources( + __isl_take isl_access_info *access, struct isl_scheduled_access *sink, + struct isl_compute_flow_schedule_data *data) +{ + int i; + isl_space *space; + + space = isl_space_range(isl_map_get_space(sink->access)); + for (i = 0; i < data->n_source; ++i) { + struct isl_scheduled_access *source; + isl_space *source_space; + int eq; + + source = &data->source[i]; + source_space = isl_map_get_space(source->access); + source_space = isl_space_range(source_space); + eq = isl_space_is_equal(space, source_space); + isl_space_free(source_space); + + if (!eq) + continue; + if (eq < 0) + goto error; + + access = isl_access_info_add_source(access, + isl_map_copy(source->access), source->must, source->node); + } + + isl_space_free(space); + return access; +error: + isl_space_free(space); + isl_access_info_free(access); + return NULL; +} + +/* Given a scheduled sink access relation "sink", compute the corresponding + * dependences on the sources in "data" and add the computed dependences + * to "uf". + * + * The dependences computed by access_info_compute_flow_core are of the form + * + * [S -> I] -> [[S' -> I'] -> A] + * + * The schedule dimensions are projected out by first currying the range, + * resulting in + * + * [S -> I] -> [S' -> [I' -> A]] + * + * and then computing the factor range + * + * I -> [I' -> A] + */ +static __isl_give isl_union_flow *compute_single_flow( + __isl_take isl_union_flow *uf, struct isl_scheduled_access *sink, + struct isl_compute_flow_schedule_data *data) +{ + int i; + isl_access_info *access; + isl_flow *flow; + isl_map *map; + + if (!uf) + return NULL; + + access = isl_access_info_alloc(isl_map_copy(sink->access), sink->node, + &before_node, data->n_source); + if (access) + access->coscheduled = &coscheduled_node; + access = add_matching_sources(access, sink, data); + + flow = access_info_compute_flow_core(access); + if (!flow) + return isl_union_flow_free(uf); + + map = isl_map_domain_factor_range(isl_flow_get_no_source(flow, 1)); + uf->must_no_source = isl_union_map_union(uf->must_no_source, + isl_union_map_from_map(map)); + map = isl_map_domain_factor_range(isl_flow_get_no_source(flow, 0)); + uf->may_no_source = isl_union_map_union(uf->may_no_source, + isl_union_map_from_map(map)); + + for (i = 0; i < flow->n_source; ++i) { + isl_union_map *dep; + + map = isl_map_range_curry(isl_map_copy(flow->dep[i].map)); + map = isl_map_factor_range(map); + dep = isl_union_map_from_map(map); + if (flow->dep[i].must) + uf->must_dep = isl_union_map_union(uf->must_dep, dep); + else + uf->may_dep = isl_union_map_union(uf->may_dep, dep); + } + + isl_flow_free(flow); + + return uf; +} + +/* Given a description of the "sink" accesses, the "source" accesses and + * a schedule, compute for each instance of a sink access + * and for each element accessed by that instance, + * the possible or definite source accesses that last accessed the + * element accessed by the sink access before this sink access + * in the sense that there is no intermediate definite source access. + * Only consider dependences between statement instances that belong + * to the domain of the schedule. + * + * The must_no_source and may_no_source elements of the result + * are subsets of access->sink. The elements must_dep and may_dep + * map domain elements of access->{may,must)_source to + * domain elements of access->sink. + * + * This function is used when a schedule tree representation + * is available. + * + * We extract the individual scheduled source and sink access relations + * (taking into account the domain of the schedule) and + * then compute dependences for each scheduled sink individually. + */ +static __isl_give isl_union_flow *compute_flow_schedule( + __isl_take isl_union_access_info *access) +{ + struct isl_compute_flow_schedule_data data = { access }; + int i, n; + isl_ctx *ctx; + isl_space *space; + isl_union_flow *flow; + + ctx = isl_union_access_info_get_ctx(access); + + data.n_sink = 0; + data.n_source = 0; + if (isl_schedule_foreach_schedule_node_top_down(access->schedule, + &count_sink_source, &data) < 0) + goto error; + + n = data.n_sink + data.n_source; + data.sink = isl_calloc_array(ctx, struct isl_scheduled_access, n); + if (n && !data.sink) + goto error; + data.source = data.sink + data.n_sink; + + data.n_sink = 0; + data.n_source = 0; + if (isl_schedule_foreach_schedule_node_top_down(access->schedule, + &collect_sink_source, &data) < 0) + goto error; + + space = isl_union_map_get_space(access->access[isl_access_sink]); + flow = isl_union_flow_alloc(space); + + isl_compute_flow_schedule_data_align_params(&data); + + for (i = 0; i < data.n_sink; ++i) + flow = compute_single_flow(flow, &data.sink[i], &data); + + isl_compute_flow_schedule_data_clear(&data); + + isl_union_access_info_free(access); + return flow; +error: + isl_union_access_info_free(access); + isl_compute_flow_schedule_data_clear(&data); + return NULL; +} + +/* Given a description of the "sink" accesses, the "source" accesses and + * a schedule, compute for each instance of a sink access + * and for each element accessed by that instance, + * the possible or definite source accesses that last accessed the + * element accessed by the sink access before this sink access + * in the sense that there is no intermediate definite source access. + * + * The must_no_source and may_no_source elements of the result + * are subsets of access->sink. The elements must_dep and may_dep + * map domain elements of access->{may,must)_source to + * domain elements of access->sink. + * + * If any kills have been specified, then they are treated as + * must-sources internally. Any dependence that purely derives + * from an original kill is removed from the output. + * + * We check whether the schedule is available as a schedule tree + * or a schedule map and call the corresponding function to perform + * the analysis. + */ +__isl_give isl_union_flow *isl_union_access_info_compute_flow( + __isl_take isl_union_access_info *access) +{ + isl_bool has_kill; + isl_union_map *must = NULL, *may = NULL; + isl_union_flow *flow; + + has_kill = isl_union_access_has_kill(access); + if (has_kill < 0) + goto error; + if (has_kill) { + must = isl_union_access_info_get_must_source(access); + may = isl_union_access_info_get_may_source(access); + } + access = isl_union_access_info_add_kill_to_must_source(access); + access = isl_union_access_info_normalize(access); + if (!access) + goto error; + if (access->schedule) + flow = compute_flow_schedule(access); + else + flow = compute_flow_union_map(access); + if (has_kill) + flow = isl_union_flow_drop_kill_source(flow, must, may); + return flow; +error: + isl_union_access_info_free(access); + isl_union_map_free(must); + isl_union_map_free(may); + return NULL; +} + +/* Print the information contained in "flow" to "p". + * The information is printed as a YAML document. + */ +__isl_give isl_printer *isl_printer_print_union_flow( + __isl_take isl_printer *p, __isl_keep isl_union_flow *flow) +{ + isl_union_map *umap; + + if (!flow) + return isl_printer_free(p); + + p = isl_printer_yaml_start_mapping(p); + umap = isl_union_flow_get_full_must_dependence(flow); + p = print_yaml_field_union_map(p, "must_dependence", umap); + isl_union_map_free(umap); + umap = isl_union_flow_get_full_may_dependence(flow); + p = print_yaml_field_union_map(p, "may_dependence", umap); + isl_union_map_free(umap); + p = print_yaml_field_union_map(p, "must_no_source", + flow->must_no_source); + umap = isl_union_flow_get_may_no_source(flow); + p = print_yaml_field_union_map(p, "may_no_source", umap); + isl_union_map_free(umap); + p = isl_printer_yaml_end_mapping(p); + + return p; +} + +/* Return a string representation of the information in "flow". + * The information is printed in flow format. + */ +__isl_give char *isl_union_flow_to_str(__isl_keep isl_union_flow *flow) +{ + isl_printer *p; + char *s; + + if (!flow) + return NULL; + + p = isl_printer_to_str(isl_union_flow_get_ctx(flow)); + p = isl_printer_set_yaml_style(p, ISL_YAML_STYLE_FLOW); + p = isl_printer_print_union_flow(p, flow); + s = isl_printer_get_str(p); + isl_printer_free(p); + + return s; +} + +/* Given a collection of "sink" and "source" accesses, + * compute for each iteration of a sink access + * and for each element accessed by that iteration, + * the source access in the list that last accessed the + * element accessed by the sink access before this sink access. + * Each access is given as a map from the loop iterators + * to the array indices. + * The result is a relations between source and sink + * iterations and a subset of the domain of the sink accesses, + * corresponding to those iterations that access an element + * not previously accessed. + * + * We collect the inputs in an isl_union_access_info object, + * call isl_union_access_info_compute_flow and extract + * the outputs from the result. + */ +int isl_union_map_compute_flow(__isl_take isl_union_map *sink, + __isl_take isl_union_map *must_source, + __isl_take isl_union_map *may_source, + __isl_take isl_union_map *schedule, + __isl_give isl_union_map **must_dep, __isl_give isl_union_map **may_dep, + __isl_give isl_union_map **must_no_source, + __isl_give isl_union_map **may_no_source) +{ + isl_union_access_info *access; + isl_union_flow *flow; + + access = isl_union_access_info_from_sink(sink); + access = isl_union_access_info_set_must_source(access, must_source); + access = isl_union_access_info_set_may_source(access, may_source); + access = isl_union_access_info_set_schedule_map(access, schedule); + flow = isl_union_access_info_compute_flow(access); + + if (must_dep) + *must_dep = isl_union_flow_get_must_dependence(flow); + if (may_dep) + *may_dep = isl_union_flow_get_non_must_dependence(flow); + if (must_no_source) + *must_no_source = isl_union_flow_get_must_no_source(flow); + if (may_no_source) + *may_no_source = isl_union_flow_get_non_must_no_source(flow); + + isl_union_flow_free(flow); + + if ((must_dep && !*must_dep) || (may_dep && !*may_dep) || + (must_no_source && !*must_no_source) || + (may_no_source && !*may_no_source)) + goto error; + + return 0; +error: + if (must_dep) + *must_dep = isl_union_map_free(*must_dep); + if (may_dep) + *may_dep = isl_union_map_free(*may_dep); + if (must_no_source) + *must_no_source = isl_union_map_free(*must_no_source); + if (may_no_source) + *may_no_source = isl_union_map_free(*may_no_source); + return -1; +} diff --git a/external/mit/isl/dist/isl_fold.c b/external/mit/isl/dist/isl_fold.c new file mode 100644 index 000000000000..33ea278e44cf --- /dev/null +++ b/external/mit/isl/dist/isl_fold.c @@ -0,0 +1,2184 @@ +/* + * Copyright 2010 INRIA Saclay + * + * 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 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#undef EL_BASE +#define EL_BASE pw_qpolynomial_fold + +#include + +enum isl_fold isl_fold_type_negate(enum isl_fold type) +{ + switch (type) { + case isl_fold_error: + return isl_fold_error; + case isl_fold_min: + return isl_fold_max; + case isl_fold_max: + return isl_fold_min; + case isl_fold_list: + return isl_fold_list; + } + + isl_die(NULL, isl_error_internal, "unhandled isl_fold type", abort()); +} + +/* Construct a new reduction with the given type, domain space and + * list of polynomials. + */ +static __isl_give isl_qpolynomial_fold *qpolynomial_fold_alloc( + enum isl_fold type, __isl_take isl_space *space, + __isl_take isl_qpolynomial_list *list) +{ + isl_ctx *ctx; + isl_qpolynomial_fold *fold; + + if (type < 0 || !space || !list) + goto error; + + ctx = isl_space_get_ctx(space); + fold = isl_calloc_type(ctx, struct isl_qpolynomial_fold); + if (!fold) + goto error; + + fold->ref = 1; + fold->type = type; + fold->dim = space; + fold->list = list; + + return fold; +error: + isl_space_free(space); + isl_qpolynomial_list_free(list); + return NULL; +} + +isl_ctx *isl_qpolynomial_fold_get_ctx(__isl_keep isl_qpolynomial_fold *fold) +{ + return fold ? fold->dim->ctx : NULL; +} + +/* Return the domain space of "fold". + */ +static __isl_keep isl_space *isl_qpolynomial_fold_peek_domain_space( + __isl_keep isl_qpolynomial_fold *fold) +{ + return fold ? fold->dim : NULL; +} + +__isl_give isl_space *isl_qpolynomial_fold_get_domain_space( + __isl_keep isl_qpolynomial_fold *fold) +{ + return isl_space_copy(isl_qpolynomial_fold_peek_domain_space(fold)); +} + +/* Return the space of the domain of "fold". + * This may be either a copy or the space itself + * if there is only one reference to "fold". + * This allows the space to be modified inplace + * if both the expression and its space have only a single reference. + * The caller is not allowed to modify "fold" between this call and + * a subsequent call to isl_qpolynomial_fold_restore_domain_space. + * The only exception is that isl_qpolynomial_fold_free can be called instead. + */ +static __isl_give isl_space *isl_qpolynomial_fold_take_domain_space( + __isl_keep isl_qpolynomial_fold *fold) +{ + isl_space *space; + + if (!fold) + return NULL; + if (fold->ref != 1) + return isl_qpolynomial_fold_get_domain_space(fold); + space = fold->dim; + fold->dim = NULL; + return space; +} + +/* Set the space of the domain of "fold" to "space", + * where the space of "fold" may be missing + * due to a preceding call to isl_qpolynomial_fold_take_domain_space. + * However, in this case, "fold" only has a single reference and + * then the call to isl_qpolynomial_fold_cow has no effect. + */ +static +__isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_restore_domain_space( + __isl_keep isl_qpolynomial_fold *fold, __isl_take isl_space *space) +{ + if (!fold || !space) + goto error; + + if (fold->dim == space) { + isl_space_free(space); + return fold; + } + + fold = isl_qpolynomial_fold_cow(fold); + if (!fold) + goto error; + isl_space_free(fold->dim); + fold->dim = space; + + return fold; +error: + isl_qpolynomial_fold_free(fold); + isl_space_free(space); + return NULL; +} + +__isl_give isl_space *isl_qpolynomial_fold_get_space( + __isl_keep isl_qpolynomial_fold *fold) +{ + isl_space *space; + if (!fold) + return NULL; + space = isl_space_copy(fold->dim); + space = isl_space_from_domain(space); + space = isl_space_add_dims(space, isl_dim_out, 1); + return space; +} + +/* Return the list of polynomials in the reduction "fold". + */ +__isl_keep isl_qpolynomial_list *isl_qpolynomial_fold_peek_list( + __isl_keep isl_qpolynomial_fold *fold) +{ + return fold ? fold->list : NULL; +} + +/* Return a copy of the list of polynomials in the reduction "fold". + */ +static __isl_give isl_qpolynomial_list *isl_qpolynomial_fold_get_list( + __isl_keep isl_qpolynomial_fold *fold) +{ + return isl_qpolynomial_list_copy(isl_qpolynomial_fold_peek_list(fold)); +} + +/* Return the list of polynomials of "fold". + * This may be either a copy or the list itself + * if there is only one reference to "fold". + * This allows the list to be modified inplace + * if both the expression and its list have only a single reference. + * The caller is not allowed to modify "fold" between this call and + * a subsequent call to isl_qpolynomial_fold_restore_list. + * The only exception is that isl_qpolynomial_fold_free can be called instead. + */ +static __isl_give isl_qpolynomial_list *isl_qpolynomial_fold_take_list( + __isl_keep isl_qpolynomial_fold *fold) +{ + isl_qpolynomial_list *list; + + if (!fold) + return NULL; + if (fold->ref != 1) + return isl_qpolynomial_fold_get_list(fold); + list = fold->list; + fold->list = NULL; + return list; +} + +/* Set the space of the list of polynomials of "fold" to "space", + * where the list of polynomials of "fold" may be missing + * due to a preceding call to isl_qpolynomial_fold_take_list. + * However, in this case, "fold" only has a single reference and + * then the call to isl_qpolynomial_fold_cow has no effect. + */ +static __isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_restore_list( + __isl_keep isl_qpolynomial_fold *fold, + __isl_take isl_qpolynomial_list *list) +{ + if (!fold || !list) + goto error; + + if (fold->list == list) { + isl_qpolynomial_list_free(list); + return fold; + } + + fold = isl_qpolynomial_fold_cow(fold); + if (!fold) + goto error; + isl_qpolynomial_list_free(fold->list); + fold->list = list; + + return fold; +error: + isl_qpolynomial_fold_free(fold); + isl_qpolynomial_list_free(list); + return NULL; +} + +/* isl_qpolynomial_list_map callback that calls + * isl_qpolynomial_reset_domain_space on "qp". + */ +static __isl_give isl_qpolynomial *reset_domain_space( + __isl_take isl_qpolynomial *qp, void *user) +{ + isl_space *space = user; + + return isl_qpolynomial_reset_domain_space(qp, isl_space_copy(space)); +} + +/* Replace the domain space of "fold" by "space". + * + * Replace the domain space itself and that of all polynomials + * in the list. + */ +__isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_reset_domain_space( + __isl_take isl_qpolynomial_fold *fold, __isl_take isl_space *space) +{ + isl_qpolynomial_list *list; + + list = isl_qpolynomial_fold_take_list(fold); + list = isl_qpolynomial_list_map(list, &reset_domain_space, space); + fold = isl_qpolynomial_fold_restore_list(fold, list); + + isl_space_free(isl_qpolynomial_fold_take_domain_space(fold)); + fold = isl_qpolynomial_fold_restore_domain_space(fold, space); + + return fold; +} + +/* Reset the space of "fold". 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. + */ +__isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_reset_space_and_domain( + __isl_take isl_qpolynomial_fold *fold, __isl_take isl_space *space, + __isl_take isl_space *domain) +{ + isl_space_free(space); + return isl_qpolynomial_fold_reset_domain_space(fold, domain); +} + +/* Internal data structure for isl_qpolynomial_fold_*_dims + * representing their arguments. + */ +struct isl_fold_dims_data { + enum isl_dim_type type; + unsigned first; + unsigned n; +}; + +/* isl_qpolynomial_list_every callback that checks whether "qp" + * does not involve any dimensions in the given range. + */ +static isl_bool not_involved(__isl_keep isl_qpolynomial *qp, void *user) +{ + struct isl_fold_dims_data *data = user; + isl_bool involves; + + involves = isl_qpolynomial_involves_dims(qp, data->type, + data->first, data->n); + return isl_bool_not(involves); +} + +/* Does "fold" involve any dimensions in the given range. + * + * It involves any of those dimensions if it is not the case + * that every polynomial in the reduction does not involve + * any of the dimensions. + */ +static isl_bool isl_qpolynomial_fold_involves_dims( + __isl_keep isl_qpolynomial_fold *fold, + enum isl_dim_type type, unsigned first, unsigned n) +{ + struct isl_fold_dims_data data = { type, first, n }; + isl_qpolynomial_list *list; + isl_bool not; + + if (!fold) + return isl_bool_error; + if (n == 0) + return isl_bool_false; + + list = isl_qpolynomial_fold_peek_list(fold); + not = isl_qpolynomial_list_every(list, ¬_involved, &data); + return isl_bool_not(not); +} + +/* Internal data structure for isl_qpolynomial_fold_set_dim_name + * representing its arguments. + */ +struct isl_fold_set_dim_name_data { + enum isl_dim_type type; + unsigned pos; + const char *s; +}; + +/* isl_qpolynomial_list_map callback for calling + * isl_qpolynomial_set_dim_name on "qp". + */ +static __isl_give isl_qpolynomial *set_dim_name(__isl_take isl_qpolynomial *qp, + void *user) +{ + struct isl_fold_set_dim_name_data *data = user; + + qp = isl_qpolynomial_set_dim_name(qp, data->type, data->pos, data->s); + return qp; +} + +/* Given a dimension type for an isl_qpolynomial_fold, + * return the corresponding type for the domain. + */ +static enum isl_dim_type domain_type(enum isl_dim_type type) +{ + if (type == isl_dim_in) + return isl_dim_set; + return type; +} + +__isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_set_dim_name( + __isl_take isl_qpolynomial_fold *fold, + enum isl_dim_type type, unsigned pos, const char *s) +{ + struct isl_fold_set_dim_name_data data = { type, pos, s }; + enum isl_dim_type set_type; + isl_space *space; + isl_qpolynomial_list *list; + + list = isl_qpolynomial_fold_take_list(fold); + list = isl_qpolynomial_list_map(list, &set_dim_name, &data); + fold = isl_qpolynomial_fold_restore_list(fold, list); + + set_type = domain_type(type); + space = isl_qpolynomial_fold_take_domain_space(fold); + space = isl_space_set_dim_name(space, set_type, pos, s); + fold = isl_qpolynomial_fold_restore_domain_space(fold, space); + + return fold; +} + +/* isl_qpolynomial_list_map callback for calling + * isl_qpolynomial_drop_dims on "qp". + */ +static __isl_give isl_qpolynomial *drop_dims(__isl_take isl_qpolynomial *qp, + void *user) +{ + struct isl_fold_dims_data *data = user; + + qp = isl_qpolynomial_drop_dims(qp, data->type, data->first, data->n); + return qp; +} + +__isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_drop_dims( + __isl_take isl_qpolynomial_fold *fold, + enum isl_dim_type type, unsigned first, unsigned n) +{ + struct isl_fold_dims_data data = { type, first, n }; + enum isl_dim_type set_type; + isl_space *space; + isl_qpolynomial_list *list; + + if (!fold) + return NULL; + if (n == 0) + return fold; + + set_type = domain_type(type); + + list = isl_qpolynomial_fold_take_list(fold); + list = isl_qpolynomial_list_map(list, &drop_dims, &data); + fold = isl_qpolynomial_fold_restore_list(fold, list); + + space = isl_qpolynomial_fold_take_domain_space(fold); + space = isl_space_drop_dims(space, set_type, first, n); + fold = isl_qpolynomial_fold_restore_domain_space(fold, space); + + return fold; +} + +/* isl_qpolynomial_list_map callback for calling + * isl_qpolynomial_insert_dims on "qp". + */ +static __isl_give isl_qpolynomial *insert_dims(__isl_take isl_qpolynomial *qp, + void *user) +{ + struct isl_fold_dims_data *data = user; + + qp = isl_qpolynomial_insert_dims(qp, data->type, data->first, data->n); + return qp; +} + +__isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_insert_dims( + __isl_take isl_qpolynomial_fold *fold, + enum isl_dim_type type, unsigned first, unsigned n) +{ + struct isl_fold_dims_data data = { type, first, n }; + enum isl_dim_type set_type; + isl_space *space; + isl_qpolynomial_list *list; + + if (!fold) + return NULL; + if (n == 0 && !isl_space_is_named_or_nested(fold->dim, type)) + return fold; + + list = isl_qpolynomial_fold_take_list(fold); + list = isl_qpolynomial_list_map(list, &insert_dims, &data); + fold = isl_qpolynomial_fold_restore_list(fold, list); + + set_type = domain_type(type); + space = isl_qpolynomial_fold_take_domain_space(fold); + space = isl_space_insert_dims(space, set_type, first, n); + fold = isl_qpolynomial_fold_restore_domain_space(fold, space); + + return fold; +} + +/* Determine the sign of the constant quasipolynomial "qp". + * + * Return + * -1 if qp <= 0 + * 1 if qp >= 0 + * 0 if unknown + * + * For qp == 0, we can return either -1 or 1. In practice, we return 1. + * For qp == NaN, the sign is undefined, so we return 0. + */ +static int isl_qpolynomial_cst_sign(__isl_keep isl_qpolynomial *qp) +{ + isl_poly_cst *cst; + + if (isl_qpolynomial_is_nan(qp)) + return 0; + + cst = isl_poly_as_cst(qp->poly); + if (!cst) + return 0; + + return isl_int_sgn(cst->n) < 0 ? -1 : 1; +} + +static int isl_qpolynomial_aff_sign(__isl_keep isl_set *set, + __isl_keep isl_qpolynomial *qp) +{ + enum isl_lp_result res; + isl_vec *aff; + isl_int opt; + int sgn = 0; + + aff = isl_qpolynomial_extract_affine(qp); + if (!aff) + return 0; + + isl_int_init(opt); + + res = isl_set_solve_lp(set, 0, aff->el + 1, aff->el[0], + &opt, NULL, NULL); + if (res == isl_lp_error) + goto done; + if (res == isl_lp_empty || + (res == isl_lp_ok && !isl_int_is_neg(opt))) { + sgn = 1; + goto done; + } + + res = isl_set_solve_lp(set, 1, aff->el + 1, aff->el[0], + &opt, NULL, NULL); + if (res == isl_lp_ok && !isl_int_is_pos(opt)) + sgn = -1; + +done: + isl_int_clear(opt); + isl_vec_free(aff); + return sgn; +} + +/* Determine, if possible, the sign of the quasipolynomial "qp" on + * the domain "set". + * + * If qp is a constant, then the problem is trivial. + * If qp is linear, then we check if the minimum of the corresponding + * affine constraint is non-negative or if the maximum is non-positive. + * + * Otherwise, we check if the outermost variable "v" has a lower bound "l" + * in "set". If so, we write qp(v,v') as + * + * q(v,v') * (v - l) + r(v') + * + * if q(v,v') and r(v') have the same known sign, then the original + * quasipolynomial has the same sign as well. + * + * Return + * -1 if qp <= 0 + * 1 if qp >= 0 + * 0 if unknown + */ +static int isl_qpolynomial_sign(__isl_keep isl_set *set, + __isl_keep isl_qpolynomial *qp) +{ + isl_size d; + int i; + isl_bool is; + isl_poly_rec *rec; + isl_vec *v; + isl_int l; + enum isl_lp_result res; + int sgn = 0; + + is = isl_qpolynomial_is_cst(qp, NULL, NULL); + if (is < 0) + return 0; + if (is) + return isl_qpolynomial_cst_sign(qp); + + is = isl_qpolynomial_is_affine(qp); + if (is < 0) + return 0; + if (is) + return isl_qpolynomial_aff_sign(set, qp); + + if (qp->div->n_row > 0) + return 0; + + rec = isl_poly_as_rec(qp->poly); + if (!rec) + return 0; + + d = isl_space_dim(qp->dim, isl_dim_all); + if (d < 0) + return 0; + v = isl_vec_alloc(set->ctx, 2 + d); + if (!v) + return 0; + + isl_seq_clr(v->el + 1, 1 + d); + isl_int_set_si(v->el[0], 1); + isl_int_set_si(v->el[2 + qp->poly->var], 1); + + isl_int_init(l); + + res = isl_set_solve_lp(set, 0, v->el + 1, v->el[0], &l, NULL, NULL); + if (res == isl_lp_ok) { + isl_qpolynomial *min; + isl_qpolynomial *base; + isl_qpolynomial *r, *q; + isl_qpolynomial *t; + + min = isl_qpolynomial_cst_on_domain(isl_space_copy(qp->dim), l); + base = isl_qpolynomial_var_pow_on_domain(isl_space_copy(qp->dim), + qp->poly->var, 1); + + r = isl_qpolynomial_alloc(isl_space_copy(qp->dim), 0, + isl_poly_copy(rec->p[rec->n - 1])); + q = isl_qpolynomial_copy(r); + + for (i = rec->n - 2; i >= 0; --i) { + r = isl_qpolynomial_mul(r, isl_qpolynomial_copy(min)); + t = isl_qpolynomial_alloc(isl_space_copy(qp->dim), 0, + isl_poly_copy(rec->p[i])); + r = isl_qpolynomial_add(r, t); + if (i == 0) + break; + q = isl_qpolynomial_mul(q, isl_qpolynomial_copy(base)); + q = isl_qpolynomial_add(q, isl_qpolynomial_copy(r)); + } + + if (isl_qpolynomial_is_zero(q)) + sgn = isl_qpolynomial_sign(set, r); + else if (isl_qpolynomial_is_zero(r)) + sgn = isl_qpolynomial_sign(set, q); + else { + int sgn_q, sgn_r; + sgn_r = isl_qpolynomial_sign(set, r); + sgn_q = isl_qpolynomial_sign(set, q); + if (sgn_r == sgn_q) + sgn = sgn_r; + } + + isl_qpolynomial_free(min); + isl_qpolynomial_free(base); + isl_qpolynomial_free(q); + isl_qpolynomial_free(r); + } + + isl_int_clear(l); + + isl_vec_free(v); + + return sgn; +} + +/* Check that "fold1" and "fold2" have the same type. + */ +static isl_stat isl_qpolynomial_fold_check_equal_type( + __isl_keep isl_qpolynomial_fold *fold1, + __isl_keep isl_qpolynomial_fold *fold2) +{ + enum isl_fold type1, type2; + + type1 = isl_qpolynomial_fold_get_type(fold1); + type2 = isl_qpolynomial_fold_get_type(fold2); + if (type1 < 0 || type2 < 0) + return isl_stat_error; + if (type1 != type2) + isl_die(isl_qpolynomial_fold_get_ctx(fold1), isl_error_invalid, + "fold types don't match", return isl_stat_error); + return isl_stat_ok; +} + +/* Check that "fold1" and "fold2" have the same (domain) space. + */ +static isl_stat isl_qpolynomial_fold_check_equal_space( + __isl_keep isl_qpolynomial_fold *fold1, + __isl_keep isl_qpolynomial_fold *fold2) +{ + isl_bool equal; + isl_space *space1, *space2; + + space1 = isl_qpolynomial_fold_peek_domain_space(fold1); + space2 = isl_qpolynomial_fold_peek_domain_space(fold2); + equal = isl_space_is_equal(space1, space2); + if (equal < 0) + return isl_stat_error; + if (!equal) + isl_die(isl_qpolynomial_fold_get_ctx(fold1), isl_error_invalid, + "spaces don't match", return isl_stat_error); + return isl_stat_ok; +} + +/* Combine "list1" and "list2" into a single list, eliminating + * those elements of one list that are already covered by the other + * list on "set". + * + * "better" is the sign that the difference qp1 - qp2 needs to have for qp1 + * to be covered by qp2. + */ +static __isl_give isl_qpolynomial_list *merge_lists(__isl_keep isl_set *set, + __isl_take isl_qpolynomial_list *list1, + __isl_take isl_qpolynomial_list *list2, int better) +{ + int i, j; + isl_size n1, n2; + + n1 = isl_qpolynomial_list_size(list1); + n2 = isl_qpolynomial_list_size(list2); + if (n1 < 0 || n2 < 0) + goto error; + + for (i = n2 - 1; i >= 0; --i) { + for (j = n1 - 1; j >= 0; --j) { + isl_qpolynomial *qp1, *qp2, *d; + int sgn; + isl_bool equal; + + qp1 = isl_qpolynomial_list_peek(list1, j); + qp2 = isl_qpolynomial_list_peek(list2, i); + equal = isl_qpolynomial_plain_is_equal(qp1, qp2); + if (equal < 0) + goto error; + if (equal) + break; + d = isl_qpolynomial_sub( + isl_qpolynomial_copy(qp1), + isl_qpolynomial_copy(qp2)); + sgn = isl_qpolynomial_sign(set, d); + isl_qpolynomial_free(d); + if (sgn == 0) + continue; + if (sgn != better) + break; + list1 = isl_qpolynomial_list_drop(list1, j, 1); + n1--; + } + if (j < 0) + continue; + list2 = isl_qpolynomial_list_drop(list2, i, 1); + n2--; + } + + return isl_qpolynomial_list_concat(list1, list2); +error: + isl_qpolynomial_list_free(list1); + isl_qpolynomial_list_free(list2); + return NULL; +} + +/* Combine "fold1" and "fold2" into a single reduction, eliminating + * those elements of one reduction that are already covered by the other + * reduction on "set". + * + * If "fold1" or "fold2" is an empty reduction, then return + * the other reduction. + * If "fold1" or "fold2" is a NaN, then return this NaN. + */ +__isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_fold_on_domain( + __isl_keep isl_set *set, + __isl_take isl_qpolynomial_fold *fold1, + __isl_take isl_qpolynomial_fold *fold2) +{ + isl_qpolynomial_list *list1; + isl_qpolynomial_list *list2; + int better; + + if (isl_qpolynomial_fold_check_equal_type(fold1, fold2) < 0) + goto error; + if (isl_qpolynomial_fold_check_equal_space(fold1, fold2) < 0) + goto error; + + better = fold1->type == isl_fold_max ? -1 : 1; + + if (isl_qpolynomial_fold_is_empty(fold1) || + isl_qpolynomial_fold_is_nan(fold2)) { + isl_qpolynomial_fold_free(fold1); + return fold2; + } + + if (isl_qpolynomial_fold_is_empty(fold2) || + isl_qpolynomial_fold_is_nan(fold1)) { + isl_qpolynomial_fold_free(fold2); + return fold1; + } + + list1 = isl_qpolynomial_fold_take_list(fold1); + list2 = isl_qpolynomial_fold_take_list(fold2); + + list1 = merge_lists(set, list1, list2, better); + + fold1 = isl_qpolynomial_fold_restore_list(fold1, list1); + isl_qpolynomial_fold_free(fold2); + + return fold1; +error: + isl_qpolynomial_fold_free(fold1); + isl_qpolynomial_fold_free(fold2); + return NULL; +} + +/* isl_qpolynomial_list_map callback for adding "qp2" to "qp". + */ +static __isl_give isl_qpolynomial *add_qpolynomial( + __isl_take isl_qpolynomial *qp, void *user) +{ + isl_qpolynomial *qp2 = user; + + return isl_qpolynomial_add(qp, isl_qpolynomial_copy(qp2)); +} + +__isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_add_qpolynomial( + __isl_take isl_qpolynomial_fold *fold, __isl_take isl_qpolynomial *qp) +{ + isl_qpolynomial_list *list; + + if (!fold || !qp) + goto error; + + if (isl_qpolynomial_is_zero(qp)) { + isl_qpolynomial_free(qp); + return fold; + } + + list = isl_qpolynomial_fold_take_list(fold); + list = isl_qpolynomial_list_map(list, &add_qpolynomial, qp); + fold = isl_qpolynomial_fold_restore_list(fold, list); + + isl_qpolynomial_free(qp); + return fold; +error: + isl_qpolynomial_fold_free(fold); + isl_qpolynomial_free(qp); + return NULL; +} + +__isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_add_on_domain( + __isl_keep isl_set *dom, + __isl_take isl_qpolynomial_fold *fold1, + __isl_take isl_qpolynomial_fold *fold2) +{ + int i; + isl_size n1, n2; + isl_qpolynomial_fold *res = NULL; + isl_qpolynomial *qp; + isl_qpolynomial_list *list1, *list2; + + if (!fold1 || !fold2) + goto error; + + if (isl_qpolynomial_fold_is_empty(fold1)) { + isl_qpolynomial_fold_free(fold1); + return fold2; + } + + if (isl_qpolynomial_fold_is_empty(fold2)) { + isl_qpolynomial_fold_free(fold2); + return fold1; + } + + list1 = isl_qpolynomial_fold_peek_list(fold1); + list2 = isl_qpolynomial_fold_peek_list(fold2); + n1 = isl_qpolynomial_list_size(list1); + n2 = isl_qpolynomial_list_size(list2); + if (n1 < 0 || n2 < 0) + goto error; + + if (n1 == 1 && n2 != 1) + return isl_qpolynomial_fold_add_on_domain(dom, fold2, fold1); + + qp = isl_qpolynomial_list_get_at(list2, 0); + if (n2 == 1) { + res = isl_qpolynomial_fold_add_qpolynomial(fold1, qp); + isl_qpolynomial_fold_free(fold2); + return res; + } + + res = isl_qpolynomial_fold_add_qpolynomial( + isl_qpolynomial_fold_copy(fold1), qp); + + for (i = 1; i < n2; ++i) { + isl_qpolynomial_fold *res_i; + + qp = isl_qpolynomial_list_get_at(list2, i); + res_i = isl_qpolynomial_fold_add_qpolynomial( + isl_qpolynomial_fold_copy(fold1), qp); + res = isl_qpolynomial_fold_fold_on_domain(dom, res, res_i); + } + + isl_qpolynomial_fold_free(fold1); + isl_qpolynomial_fold_free(fold2); + return res; +error: + isl_qpolynomial_fold_free(res); + isl_qpolynomial_fold_free(fold1); + isl_qpolynomial_fold_free(fold2); + return NULL; +} + +/* isl_qpolynomial_list_map callback for calling + * isl_qpolynomial_substitute_equalities on "qp" and "eq". + */ +static __isl_give isl_qpolynomial *substitute_equalities( + __isl_take isl_qpolynomial *qp, void *user) +{ + isl_basic_set *eq = user; + + eq = isl_basic_set_copy(eq); + return isl_qpolynomial_substitute_equalities(qp, eq); +} + +__isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_substitute_equalities( + __isl_take isl_qpolynomial_fold *fold, __isl_take isl_basic_set *eq) +{ + isl_qpolynomial_list *list; + + list = isl_qpolynomial_fold_take_list(fold); + list = isl_qpolynomial_list_map(list, &substitute_equalities, eq); + fold = isl_qpolynomial_fold_restore_list(fold, list); + + isl_basic_set_free(eq); + return fold; +} + +/* isl_qpolynomial_list_map callback for calling + * isl_qpolynomial_substitute_equalities on "qp" and "context". + */ +static __isl_give isl_qpolynomial *gist(__isl_take isl_qpolynomial *qp, + void *user) +{ + isl_set *context = user; + + return isl_qpolynomial_gist(qp, isl_set_copy(context)); +} + +__isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_gist( + __isl_take isl_qpolynomial_fold *fold, __isl_take isl_set *context) +{ + isl_qpolynomial_list *list; + + list = isl_qpolynomial_fold_take_list(fold); + list = isl_qpolynomial_list_map(list, &gist, context); + fold = isl_qpolynomial_fold_restore_list(fold, list); + + isl_set_free(context); + return fold; +} + +__isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_gist_params( + __isl_take isl_qpolynomial_fold *fold, __isl_take isl_set *context) +{ + isl_space *space = isl_qpolynomial_fold_get_domain_space(fold); + isl_set *dom_context = isl_set_universe(space); + dom_context = isl_set_intersect_params(dom_context, context); + return isl_qpolynomial_fold_gist(fold, dom_context); +} + +/* Return a zero (i.e., empty) isl_qpolynomial_fold in the given space. + * + * This is a helper function for isl_pw_*_as_* that ensures a uniform + * interface over all piecewise types. + */ +static __isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_zero_in_space( + __isl_take isl_space *space, enum isl_fold type) +{ + return isl_qpolynomial_fold_empty(type, isl_space_domain(space)); +} + +#define isl_qpolynomial_fold_involves_nan isl_qpolynomial_fold_is_nan + +#define HAS_TYPE + +#undef PW +#define PW isl_pw_qpolynomial_fold +#undef BASE +#define BASE qpolynomial_fold +#undef EL_IS_ZERO +#define EL_IS_ZERO is_empty +#undef ZERO +#define ZERO zero +#undef IS_ZERO +#define IS_ZERO is_zero +#undef FIELD +#define FIELD fold +#undef DEFAULT_IS_ZERO +#define DEFAULT_IS_ZERO 1 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#undef BASE +#define BASE pw_qpolynomial_fold + +#include +#include + +/* Construct a new reduction of the given type and space + * with an empty list of polynomials. + */ +__isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_empty(enum isl_fold type, + __isl_take isl_space *space) +{ + isl_ctx *ctx; + isl_qpolynomial_list *list; + + if (!space) + return NULL; + ctx = isl_space_get_ctx(space); + list = isl_qpolynomial_list_alloc(ctx, 0); + return qpolynomial_fold_alloc(type, space, list); +} + +/* Construct a new reduction of the given type and + * a single given polynomial. + */ +__isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_alloc( + enum isl_fold type, __isl_take isl_qpolynomial *qp) +{ + isl_space *space; + isl_qpolynomial_list *list; + + space = isl_qpolynomial_get_domain_space(qp); + list = isl_qpolynomial_list_from_qpolynomial(qp); + return qpolynomial_fold_alloc(type, space, list); +} + +__isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_copy( + __isl_keep isl_qpolynomial_fold *fold) +{ + if (!fold) + return NULL; + + fold->ref++; + return fold; +} + +__isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_dup( + __isl_keep isl_qpolynomial_fold *fold) +{ + enum isl_fold type; + isl_space *space; + isl_qpolynomial_list *list; + + type = isl_qpolynomial_fold_get_type(fold); + space = isl_qpolynomial_fold_get_domain_space(fold); + list = isl_qpolynomial_fold_get_list(fold); + return qpolynomial_fold_alloc(type, space, list); +} + +__isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_cow( + __isl_take isl_qpolynomial_fold *fold) +{ + if (!fold) + return NULL; + + if (fold->ref == 1) + return fold; + fold->ref--; + return isl_qpolynomial_fold_dup(fold); +} + +__isl_null isl_qpolynomial_fold *isl_qpolynomial_fold_free( + __isl_take isl_qpolynomial_fold *fold) +{ + if (!fold) + return NULL; + if (--fold->ref > 0) + return NULL; + + isl_qpolynomial_list_free(fold->list); + isl_space_free(fold->dim); + free(fold); + + return NULL; +} + +isl_bool isl_qpolynomial_fold_is_empty(__isl_keep isl_qpolynomial_fold *fold) +{ + isl_size n; + isl_qpolynomial_list *list; + + list = isl_qpolynomial_fold_peek_list(fold); + n = isl_qpolynomial_list_size(list); + if (n < 0) + return isl_bool_error; + + return isl_bool_ok(n == 0); +} + +/* Does "fold" represent max(NaN) or min(NaN)? + */ +isl_bool isl_qpolynomial_fold_is_nan(__isl_keep isl_qpolynomial_fold *fold) +{ + isl_size n; + isl_qpolynomial *qp; + isl_qpolynomial_list *list; + + list = isl_qpolynomial_fold_peek_list(fold); + n = isl_qpolynomial_list_size(list); + if (n < 0) + return isl_bool_error; + if (n != 1) + return isl_bool_false; + qp = isl_qpolynomial_list_peek(list, 0); + return isl_qpolynomial_is_nan(qp); +} + +__isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_fold( + __isl_take isl_qpolynomial_fold *fold1, + __isl_take isl_qpolynomial_fold *fold2) +{ + isl_qpolynomial_list *list1, *list2; + + if (isl_qpolynomial_fold_check_equal_type(fold1, fold2) < 0) + goto error; + if (isl_qpolynomial_fold_check_equal_space(fold1, fold2) < 0) + goto error; + + if (isl_qpolynomial_fold_is_empty(fold1)) { + isl_qpolynomial_fold_free(fold1); + return fold2; + } + + if (isl_qpolynomial_fold_is_empty(fold2)) { + isl_qpolynomial_fold_free(fold2); + return fold1; + } + + list1 = isl_qpolynomial_fold_take_list(fold1); + list2 = isl_qpolynomial_fold_take_list(fold2); + list1 = isl_qpolynomial_list_concat(list1, list2); + fold1 = isl_qpolynomial_fold_restore_list(fold1, list1); + isl_qpolynomial_fold_free(fold2); + + return fold1; +error: + isl_qpolynomial_fold_free(fold1); + isl_qpolynomial_fold_free(fold2); + return NULL; +} + +__isl_give isl_pw_qpolynomial_fold *isl_pw_qpolynomial_fold_fold( + __isl_take isl_pw_qpolynomial_fold *pw1, + __isl_take isl_pw_qpolynomial_fold *pw2) +{ + int i, j, n; + struct isl_pw_qpolynomial_fold *res; + isl_set *set; + + if (!pw1 || !pw2) + goto error; + + isl_assert(pw1->dim->ctx, isl_space_is_equal(pw1->dim, pw2->dim), goto error); + + if (isl_pw_qpolynomial_fold_is_zero(pw1)) { + isl_pw_qpolynomial_fold_free(pw1); + return pw2; + } + + if (isl_pw_qpolynomial_fold_is_zero(pw2)) { + isl_pw_qpolynomial_fold_free(pw2); + return pw1; + } + + if (pw1->type != pw2->type) + isl_die(pw1->dim->ctx, isl_error_invalid, + "fold types don't match", goto error); + + n = (pw1->n + 1) * (pw2->n + 1); + res = isl_pw_qpolynomial_fold_alloc_size(isl_space_copy(pw1->dim), + pw1->type, n); + + for (i = 0; i < pw1->n; ++i) { + set = isl_set_copy(pw1->p[i].set); + for (j = 0; j < pw2->n; ++j) { + struct isl_set *common; + isl_qpolynomial_fold *sum; + set = isl_set_subtract(set, + isl_set_copy(pw2->p[j].set)); + common = isl_set_intersect(isl_set_copy(pw1->p[i].set), + isl_set_copy(pw2->p[j].set)); + if (isl_set_plain_is_empty(common)) { + isl_set_free(common); + continue; + } + + sum = isl_qpolynomial_fold_fold_on_domain(common, + isl_qpolynomial_fold_copy(pw1->p[i].fold), + isl_qpolynomial_fold_copy(pw2->p[j].fold)); + + res = isl_pw_qpolynomial_fold_add_piece(res, common, sum); + } + res = isl_pw_qpolynomial_fold_add_piece(res, set, + isl_qpolynomial_fold_copy(pw1->p[i].fold)); + } + + for (j = 0; j < pw2->n; ++j) { + set = isl_set_copy(pw2->p[j].set); + for (i = 0; i < pw1->n; ++i) + set = isl_set_subtract(set, isl_set_copy(pw1->p[i].set)); + res = isl_pw_qpolynomial_fold_add_piece(res, set, + isl_qpolynomial_fold_copy(pw2->p[j].fold)); + } + + isl_pw_qpolynomial_fold_free(pw1); + isl_pw_qpolynomial_fold_free(pw2); + + return res; +error: + isl_pw_qpolynomial_fold_free(pw1); + isl_pw_qpolynomial_fold_free(pw2); + return NULL; +} + +__isl_give isl_union_pw_qpolynomial_fold *isl_union_pw_qpolynomial_fold_fold_pw_qpolynomial_fold( + __isl_take isl_union_pw_qpolynomial_fold *u, + __isl_take isl_pw_qpolynomial_fold *part) +{ + struct isl_hash_table_entry *entry; + + u = isl_union_pw_qpolynomial_fold_cow(u); + + if (!part || !u) + goto error; + if (isl_space_check_equal_params(part->dim, u->space) < 0) + goto error; + + entry = isl_union_pw_qpolynomial_fold_find_part_entry(u, part->dim, 1); + if (!entry) + goto error; + + if (!entry->data) + entry->data = part; + else { + entry->data = isl_pw_qpolynomial_fold_fold(entry->data, + isl_pw_qpolynomial_fold_copy(part)); + if (!entry->data) + goto error; + isl_pw_qpolynomial_fold_free(part); + } + + return u; +error: + isl_pw_qpolynomial_fold_free(part); + isl_union_pw_qpolynomial_fold_free(u); + return NULL; +} + +static isl_stat fold_part(__isl_take isl_pw_qpolynomial_fold *part, void *user) +{ + isl_union_pw_qpolynomial_fold **u; + u = (isl_union_pw_qpolynomial_fold **)user; + + *u = isl_union_pw_qpolynomial_fold_fold_pw_qpolynomial_fold(*u, part); + + return isl_stat_ok; +} + +__isl_give isl_union_pw_qpolynomial_fold *isl_union_pw_qpolynomial_fold_fold( + __isl_take isl_union_pw_qpolynomial_fold *u1, + __isl_take isl_union_pw_qpolynomial_fold *u2) +{ + u1 = isl_union_pw_qpolynomial_fold_cow(u1); + + if (!u1 || !u2) + goto error; + + if (isl_union_pw_qpolynomial_fold_foreach_pw_qpolynomial_fold(u2, + &fold_part, &u1) < 0) + goto error; + + isl_union_pw_qpolynomial_fold_free(u2); + + return u1; +error: + isl_union_pw_qpolynomial_fold_free(u1); + isl_union_pw_qpolynomial_fold_free(u2); + return NULL; +} + +__isl_give isl_pw_qpolynomial_fold *isl_pw_qpolynomial_fold_from_pw_qpolynomial( + enum isl_fold type, __isl_take isl_pw_qpolynomial *pwqp) +{ + int i; + isl_pw_qpolynomial_fold *pwf; + + if (!pwqp) + return NULL; + + pwf = isl_pw_qpolynomial_fold_alloc_size(isl_space_copy(pwqp->dim), + type, pwqp->n); + + for (i = 0; i < pwqp->n; ++i) + pwf = isl_pw_qpolynomial_fold_add_piece(pwf, + isl_set_copy(pwqp->p[i].set), + isl_qpolynomial_fold_alloc(type, + isl_qpolynomial_copy(pwqp->p[i].qp))); + + isl_pw_qpolynomial_free(pwqp); + + return pwf; +} + +__isl_give isl_pw_qpolynomial_fold *isl_pw_qpolynomial_fold_add( + __isl_take isl_pw_qpolynomial_fold *pwf1, + __isl_take isl_pw_qpolynomial_fold *pwf2) +{ + return isl_pw_qpolynomial_fold_union_add_(pwf1, pwf2); +} + +/* Compare two quasi-polynomial reductions. + * + * Return -1 if "fold1" is "smaller" than "fold2", 1 if "fold1" is "greater" + * than "fold2" and 0 if they are equal. + */ +int isl_qpolynomial_fold_plain_cmp(__isl_keep isl_qpolynomial_fold *fold1, + __isl_keep isl_qpolynomial_fold *fold2) +{ + int i; + isl_size n1, n2; + isl_qpolynomial_list *list1, *list2; + + if (fold1 == fold2) + return 0; + list1 = isl_qpolynomial_fold_peek_list(fold1); + list2 = isl_qpolynomial_fold_peek_list(fold2); + n1 = isl_qpolynomial_list_size(list1); + n2 = isl_qpolynomial_list_size(list2); + if (n1 < 0) + return -1; + if (n2 < 0) + return 1; + + if (n1 != n2) + return n1 - n2; + + for (i = 0; i < n1; ++i) { + int cmp; + isl_qpolynomial *qp1, *qp2; + + qp1 = isl_qpolynomial_list_peek(list1, i); + qp2 = isl_qpolynomial_list_peek(list2, i); + cmp = isl_qpolynomial_plain_cmp(qp1, qp2); + if (cmp != 0) + return cmp; + } + + return 0; +} + +/* Are the lists "list1" and "list2", both consisting of "n" elements + * obviously equal to each other? + */ +static isl_bool isl_qpolynomial_list_plain_is_equal(unsigned n, + isl_qpolynomial_list *list1, isl_qpolynomial_list *list2) +{ + int i; + + for (i = 0; i < n; ++i) { + isl_bool eq; + isl_qpolynomial *qp1, *qp2; + + qp1 = isl_qpolynomial_list_peek(list1, i); + qp2 = isl_qpolynomial_list_peek(list2, i); + eq = isl_qpolynomial_plain_is_equal(qp1, qp2); + if (eq < 0 || !eq) + return eq; + } + + return isl_bool_true; +} + +/* Wrapper around isl_qpolynomial_plain_cmp for use + * as a isl_qpolynomial_list_sort callback. + */ +static int qpolynomial_cmp(__isl_keep isl_qpolynomial *a, + __isl_keep isl_qpolynomial *b, void *user) +{ + return isl_qpolynomial_plain_cmp(a, b); +} + +isl_bool isl_qpolynomial_fold_plain_is_equal( + __isl_keep isl_qpolynomial_fold *fold1, + __isl_keep isl_qpolynomial_fold *fold2) +{ + isl_bool equal; + isl_size n1, n2; + isl_qpolynomial_list *list1, *list2; + + list1 = isl_qpolynomial_fold_peek_list(fold1); + list2 = isl_qpolynomial_fold_peek_list(fold2); + n1 = isl_qpolynomial_list_size(list1); + n2 = isl_qpolynomial_list_size(list2); + if (n1 < 0 || n2 < 0) + return isl_bool_error; + + if (n1 != n2) + return isl_bool_false; + + list1 = isl_qpolynomial_list_copy(list1); + list1 = isl_qpolynomial_list_sort(list1, &qpolynomial_cmp, NULL); + list2 = isl_qpolynomial_list_copy(list2); + list2 = isl_qpolynomial_list_sort(list2, &qpolynomial_cmp, NULL); + equal = isl_qpolynomial_list_plain_is_equal(n1, list1, list2); + isl_qpolynomial_list_free(list1); + isl_qpolynomial_list_free(list2); + return equal; +} + +__isl_give isl_val *isl_qpolynomial_fold_eval( + __isl_take isl_qpolynomial_fold *fold, __isl_take isl_point *pnt) +{ + isl_size n; + isl_ctx *ctx; + isl_val *v; + isl_qpolynomial *qp; + isl_qpolynomial_list *list; + + if (!fold || !pnt) + goto error; + ctx = isl_point_get_ctx(pnt); + isl_assert(pnt->dim->ctx, isl_space_is_equal(pnt->dim, fold->dim), goto error); + isl_assert(pnt->dim->ctx, + fold->type == isl_fold_max || fold->type == isl_fold_min, + goto error); + + list = isl_qpolynomial_fold_peek_list(fold); + n = isl_qpolynomial_list_size(list); + if (n < 0) + goto error; + + if (n == 0) + v = isl_val_zero(ctx); + else { + int i; + + qp = isl_qpolynomial_list_get_at(list, 0); + v = isl_qpolynomial_eval(qp, isl_point_copy(pnt)); + for (i = 1; i < n; ++i) { + isl_val *v_i; + + qp = isl_qpolynomial_list_get_at(list, i); + v_i = isl_qpolynomial_eval(qp, isl_point_copy(pnt)); + if (fold->type == isl_fold_max) + v = isl_val_max(v, v_i); + else + v = isl_val_min(v, v_i); + } + } + isl_qpolynomial_fold_free(fold); + isl_point_free(pnt); + + return v; +error: + isl_qpolynomial_fold_free(fold); + isl_point_free(pnt); + return NULL; +} + +size_t isl_pw_qpolynomial_fold_size(__isl_keep isl_pw_qpolynomial_fold *pwf) +{ + int i; + size_t n = 0; + + for (i = 0; i < pwf->n; ++i) { + isl_size n_i; + isl_qpolynomial_list *list; + + list = isl_qpolynomial_fold_peek_list(pwf->p[i].fold); + n_i = isl_qpolynomial_list_size(list); + if (n_i < 0) + return isl_size_error; + + n += n_i; + } + + return n; +} + +__isl_give isl_val *isl_qpolynomial_fold_opt_on_domain( + __isl_take isl_qpolynomial_fold *fold, __isl_take isl_set *set, int max) +{ + int i; + isl_size n; + isl_val *opt; + isl_qpolynomial *qp; + isl_qpolynomial_list *list; + + list = isl_qpolynomial_fold_peek_list(fold); + n = isl_qpolynomial_list_size(list); + if (!set || n < 0) + goto error; + + if (n == 0) { + opt = isl_val_zero(isl_set_get_ctx(set)); + isl_set_free(set); + isl_qpolynomial_fold_free(fold); + return opt; + } + + qp = isl_qpolynomial_list_get_at(list, 0); + opt = isl_qpolynomial_opt_on_domain(qp, isl_set_copy(set), max); + for (i = 1; i < n; ++i) { + isl_val *opt_i; + + qp = isl_qpolynomial_list_get_at(list, i); + opt_i = isl_qpolynomial_opt_on_domain(qp, + isl_set_copy(set), max); + if (max) + opt = isl_val_max(opt, opt_i); + else + opt = isl_val_min(opt, opt_i); + } + + isl_set_free(set); + isl_qpolynomial_fold_free(fold); + + return opt; +error: + isl_set_free(set); + isl_qpolynomial_fold_free(fold); + return NULL; +} + +/* Check whether for each quasi-polynomial in "fold2" there is + * a quasi-polynomial in "fold1" that dominates it on "set". + */ +static isl_bool qpolynomial_fold_covers_on_domain(__isl_keep isl_set *set, + __isl_keep isl_qpolynomial_fold *fold1, + __isl_keep isl_qpolynomial_fold *fold2) +{ + int i, j; + int covers; + isl_size n1, n2; + isl_qpolynomial_list *list1, *list2; + + list1 = isl_qpolynomial_fold_peek_list(fold1); + list2 = isl_qpolynomial_fold_peek_list(fold2); + n1 = isl_qpolynomial_list_size(list1); + n2 = isl_qpolynomial_list_size(list2); + if (!set || n1 < 0 || n2 < 0) + return isl_bool_error; + + covers = fold1->type == isl_fold_max ? 1 : -1; + + for (i = 0; i < n2; ++i) { + for (j = 0; j < n1; ++j) { + isl_qpolynomial *qp1, *qp2, *d; + int sgn; + + qp1 = isl_qpolynomial_list_get_at(list1, j); + qp2 = isl_qpolynomial_list_get_at(list2, i); + d = isl_qpolynomial_sub(qp1, qp2); + sgn = isl_qpolynomial_sign(set, d); + isl_qpolynomial_free(d); + if (sgn == covers) + break; + } + if (j >= n1) + return isl_bool_false; + } + + return isl_bool_true; +} + +/* Check whether "pwf1" dominated "pwf2", i.e., the domain of "pwf1" contains + * that of "pwf2" and on each cell, the corresponding fold from pwf1 dominates + * that of pwf2. + */ +isl_bool isl_pw_qpolynomial_fold_covers( + __isl_keep isl_pw_qpolynomial_fold *pwf1, + __isl_keep isl_pw_qpolynomial_fold *pwf2) +{ + int i, j; + isl_set *dom1, *dom2; + isl_bool is_subset; + + if (!pwf1 || !pwf2) + return isl_bool_error; + + if (pwf2->n == 0) + return isl_bool_true; + if (pwf1->n == 0) + return isl_bool_false; + + dom1 = isl_pw_qpolynomial_fold_domain(isl_pw_qpolynomial_fold_copy(pwf1)); + dom2 = isl_pw_qpolynomial_fold_domain(isl_pw_qpolynomial_fold_copy(pwf2)); + is_subset = isl_set_is_subset(dom2, dom1); + isl_set_free(dom1); + isl_set_free(dom2); + + if (is_subset < 0 || !is_subset) + return is_subset; + + for (i = 0; i < pwf2->n; ++i) { + for (j = 0; j < pwf1->n; ++j) { + isl_bool is_empty; + isl_set *common; + isl_bool covers; + + common = isl_set_intersect(isl_set_copy(pwf1->p[j].set), + isl_set_copy(pwf2->p[i].set)); + is_empty = isl_set_is_empty(common); + if (is_empty < 0 || is_empty) { + isl_set_free(common); + if (is_empty < 0) + return isl_bool_error; + continue; + } + covers = qpolynomial_fold_covers_on_domain(common, + pwf1->p[j].fold, pwf2->p[i].fold); + isl_set_free(common); + if (covers < 0 || !covers) + return covers; + } + } + + return isl_bool_true; +} + +/* isl_qpolynomial_list_map callback that calls + * isl_qpolynomial_morph_domain on "qp". + */ +static __isl_give isl_qpolynomial *morph_domain( + __isl_take isl_qpolynomial *qp, void *user) +{ + isl_morph *morph = user; + + return isl_qpolynomial_morph_domain(qp, isl_morph_copy(morph)); +} + +__isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_morph_domain( + __isl_take isl_qpolynomial_fold *fold, __isl_take isl_morph *morph) +{ + isl_space *space; + isl_qpolynomial_list *list; + + space = isl_qpolynomial_fold_peek_domain_space(fold); + if (isl_morph_check_applies(morph, space) < 0) + goto error; + + list = isl_qpolynomial_fold_take_list(fold); + list = isl_qpolynomial_list_map(list, &morph_domain, morph); + fold = isl_qpolynomial_fold_restore_list(fold, list); + + space = isl_morph_get_ran_space(morph); + isl_space_free(isl_qpolynomial_fold_take_domain_space(fold)); + fold = isl_qpolynomial_fold_restore_domain_space(fold, space); + + isl_morph_free(morph); + + return fold; +error: + isl_qpolynomial_fold_free(fold); + isl_morph_free(morph); + return NULL; +} + +enum isl_fold isl_qpolynomial_fold_get_type(__isl_keep isl_qpolynomial_fold *fold) +{ + if (!fold) + return isl_fold_error; + return fold->type; +} + +/* Return the type of this piecewise quasipolynomial reduction. + */ +enum isl_fold isl_pw_qpolynomial_fold_get_type( + __isl_keep isl_pw_qpolynomial_fold *pwf) +{ + if (!pwf) + return isl_fold_error; + return pwf->type; +} + +enum isl_fold isl_union_pw_qpolynomial_fold_get_type( + __isl_keep isl_union_pw_qpolynomial_fold *upwf) +{ + if (!upwf) + return isl_fold_error; + return upwf->type; +} + +/* isl_qpolynomial_list_map callback that calls + * isl_qpolynomial_lift on "qp". + */ +static __isl_give isl_qpolynomial *lift(__isl_take isl_qpolynomial *qp, + void *user) +{ + isl_space *space = user; + + return isl_qpolynomial_lift(qp, isl_space_copy(space)); +} + +__isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_lift( + __isl_take isl_qpolynomial_fold *fold, __isl_take isl_space *space) +{ + isl_qpolynomial_list *list; + + if (!fold || !space) + goto error; + + if (isl_space_is_equal(fold->dim, space)) { + isl_space_free(space); + return fold; + } + + list = isl_qpolynomial_fold_take_list(fold); + list = isl_qpolynomial_list_map(list, &lift, space); + fold = isl_qpolynomial_fold_restore_list(fold, list); + + isl_space_free(isl_qpolynomial_fold_take_domain_space(fold)); + fold = isl_qpolynomial_fold_restore_domain_space(fold, space); + + return fold; +error: + isl_qpolynomial_fold_free(fold); + isl_space_free(space); + return NULL; +} + +isl_stat isl_qpolynomial_fold_foreach_qpolynomial( + __isl_keep isl_qpolynomial_fold *fold, + isl_stat (*fn)(__isl_take isl_qpolynomial *qp, void *user), void *user) +{ + isl_qpolynomial_list *list; + + list = isl_qpolynomial_fold_peek_list(fold); + return isl_qpolynomial_list_foreach(list, fn, user); +} + +/* Internal data structure for isl_qpolynomial_fold_move_dims + * representing its arguments. + */ +struct isl_fold_move_dims_data { + enum isl_dim_type dst_type; + unsigned dst_pos; + enum isl_dim_type src_type; + unsigned src_pos; + unsigned n; +}; + +/* isl_qpolynomial_list_map callback for calling + * isl_qpolynomial_move_dims on "qp". + */ +static __isl_give isl_qpolynomial *move_dims(__isl_take isl_qpolynomial *qp, + void *user) +{ + struct isl_fold_move_dims_data *data = user; + + qp = isl_qpolynomial_move_dims(qp, data->dst_type, data->dst_pos, + data->src_type, data->src_pos, data->n); + return qp; +} + +__isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_move_dims( + __isl_take isl_qpolynomial_fold *fold, + enum isl_dim_type dst_type, unsigned dst_pos, + enum isl_dim_type src_type, unsigned src_pos, unsigned n) +{ + struct isl_fold_move_dims_data data = + { dst_type, dst_pos, src_type, src_pos, n }; + enum isl_dim_type set_src_type, set_dst_type; + isl_space *space; + isl_qpolynomial_list *list; + + if (n == 0) + return fold; + + fold = isl_qpolynomial_fold_cow(fold); + if (!fold) + return NULL; + + set_src_type = domain_type(src_type); + set_dst_type = domain_type(dst_type); + + list = isl_qpolynomial_fold_take_list(fold); + list = isl_qpolynomial_list_map(list, &move_dims, &data); + fold = isl_qpolynomial_fold_restore_list(fold, list); + + space = isl_qpolynomial_fold_take_domain_space(fold); + space = isl_space_move_dims(space, set_dst_type, dst_pos, + set_src_type, src_pos, n); + fold = isl_qpolynomial_fold_restore_domain_space(fold, space); + + return fold; +} + +/* Internal data structure for isl_qpolynomial_fold_substitute + * representing its arguments. + */ +struct isl_fold_substitute { + enum isl_dim_type type; + unsigned first; + unsigned n; + isl_qpolynomial **subs; +}; + +/* isl_qpolynomial_list_map callback for calling + * isl_qpolynomial_substitute on "qp". + */ +static __isl_give isl_qpolynomial *substitute(__isl_take isl_qpolynomial *qp, + void *user) +{ + struct isl_fold_substitute *data = user; + + qp = isl_qpolynomial_substitute(qp, + data->type, data->first, data->n, data->subs); + return qp; +} + +/* For each 0 <= i < "n", replace variable "first" + i of type "type" + * in fold->qp[k] by subs[i]. + */ +__isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_substitute( + __isl_take isl_qpolynomial_fold *fold, + enum isl_dim_type type, unsigned first, unsigned n, + __isl_keep isl_qpolynomial **subs) +{ + struct isl_fold_substitute data = { type, first, n, subs }; + isl_qpolynomial_list *list; + + if (n == 0) + return fold; + + list = isl_qpolynomial_fold_take_list(fold); + list = isl_qpolynomial_list_map(list, &substitute, &data); + fold = isl_qpolynomial_fold_restore_list(fold, list); + + return fold; +} + +static isl_stat add_pwqp(__isl_take isl_pw_qpolynomial *pwqp, void *user) +{ + isl_pw_qpolynomial_fold *pwf; + isl_union_pw_qpolynomial_fold **upwf; + struct isl_hash_table_entry *entry; + + upwf = (isl_union_pw_qpolynomial_fold **)user; + + entry = isl_union_pw_qpolynomial_fold_find_part_entry(*upwf, + pwqp->dim, 1); + if (!entry) + goto error; + + pwf = isl_pw_qpolynomial_fold_from_pw_qpolynomial((*upwf)->type, pwqp); + if (!entry->data) + entry->data = pwf; + else { + entry->data = isl_pw_qpolynomial_fold_add(entry->data, pwf); + if (!entry->data) + return isl_stat_error; + if (isl_pw_qpolynomial_fold_is_zero(entry->data)) + *upwf = isl_union_pw_qpolynomial_fold_remove_part_entry( + *upwf, entry); + } + + return isl_stat_ok; +error: + isl_pw_qpolynomial_free(pwqp); + return isl_stat_error; +} + +__isl_give isl_union_pw_qpolynomial_fold *isl_union_pw_qpolynomial_fold_add_union_pw_qpolynomial( + __isl_take isl_union_pw_qpolynomial_fold *upwf, + __isl_take isl_union_pw_qpolynomial *upwqp) +{ + upwf = isl_union_pw_qpolynomial_fold_align_params(upwf, + isl_union_pw_qpolynomial_get_space(upwqp)); + upwqp = isl_union_pw_qpolynomial_align_params(upwqp, + isl_union_pw_qpolynomial_fold_get_space(upwf)); + + upwf = isl_union_pw_qpolynomial_fold_cow(upwf); + if (!upwf || !upwqp) + goto error; + + if (isl_union_pw_qpolynomial_foreach_pw_qpolynomial(upwqp, &add_pwqp, + &upwf) < 0) + goto error; + + isl_union_pw_qpolynomial_free(upwqp); + + return upwf; +error: + isl_union_pw_qpolynomial_fold_free(upwf); + isl_union_pw_qpolynomial_free(upwqp); + return NULL; +} + +static isl_bool join_compatible(__isl_keep isl_space *space1, + __isl_keep isl_space *space2) +{ + isl_bool m; + m = isl_space_has_equal_params(space1, space2); + if (m < 0 || !m) + return m; + return isl_space_tuple_is_equal(space1, isl_dim_out, + space2, isl_dim_in); +} + +/* Compute the intersection of the range of the map and the domain + * of the piecewise quasipolynomial reduction and then compute a bound + * on the associated quasipolynomial reduction over all elements + * in this intersection. + * + * We first introduce some unconstrained dimensions in the + * piecewise quasipolynomial, intersect the resulting domain + * with the wrapped map and the compute the sum. + */ +__isl_give isl_pw_qpolynomial_fold *isl_map_apply_pw_qpolynomial_fold( + __isl_take isl_map *map, __isl_take isl_pw_qpolynomial_fold *pwf, + isl_bool *tight) +{ + isl_ctx *ctx; + isl_set *dom; + isl_space *map_space; + isl_space *pwf_space; + isl_size n_in; + isl_bool ok; + + ctx = isl_map_get_ctx(map); + if (!ctx) + goto error; + + map_space = isl_map_get_space(map); + pwf_space = isl_pw_qpolynomial_fold_get_space(pwf); + ok = join_compatible(map_space, pwf_space); + isl_space_free(map_space); + isl_space_free(pwf_space); + if (ok < 0) + goto error; + if (!ok) + isl_die(ctx, isl_error_invalid, "incompatible dimensions", + goto error); + + n_in = isl_map_dim(map, isl_dim_in); + if (n_in < 0) + goto error; + pwf = isl_pw_qpolynomial_fold_insert_dims(pwf, isl_dim_in, 0, n_in); + + dom = isl_map_wrap(map); + pwf = isl_pw_qpolynomial_fold_reset_domain_space(pwf, + isl_set_get_space(dom)); + + pwf = isl_pw_qpolynomial_fold_intersect_domain(pwf, dom); + pwf = isl_pw_qpolynomial_fold_bound(pwf, tight); + + return pwf; +error: + isl_map_free(map); + isl_pw_qpolynomial_fold_free(pwf); + return NULL; +} + +__isl_give isl_pw_qpolynomial_fold *isl_set_apply_pw_qpolynomial_fold( + __isl_take isl_set *set, __isl_take isl_pw_qpolynomial_fold *pwf, + isl_bool *tight) +{ + return isl_map_apply_pw_qpolynomial_fold(set, pwf, tight); +} + +struct isl_apply_fold_data { + isl_union_pw_qpolynomial_fold *upwf; + isl_union_pw_qpolynomial_fold *res; + isl_map *map; + isl_bool tight; +}; + +static isl_stat pw_qpolynomial_fold_apply( + __isl_take isl_pw_qpolynomial_fold *pwf, void *user) +{ + isl_space *map_dim; + isl_space *pwf_dim; + struct isl_apply_fold_data *data = user; + isl_bool ok; + + map_dim = isl_map_get_space(data->map); + pwf_dim = isl_pw_qpolynomial_fold_get_space(pwf); + ok = join_compatible(map_dim, pwf_dim); + isl_space_free(map_dim); + isl_space_free(pwf_dim); + + if (ok < 0) + return isl_stat_error; + if (ok) { + pwf = isl_map_apply_pw_qpolynomial_fold(isl_map_copy(data->map), + pwf, data->tight ? &data->tight : NULL); + data->res = isl_union_pw_qpolynomial_fold_fold_pw_qpolynomial_fold( + data->res, pwf); + } else + isl_pw_qpolynomial_fold_free(pwf); + + return isl_stat_ok; +} + +static isl_stat map_apply(__isl_take isl_map *map, void *user) +{ + struct isl_apply_fold_data *data = user; + isl_stat r; + + data->map = map; + r = isl_union_pw_qpolynomial_fold_foreach_pw_qpolynomial_fold( + data->upwf, &pw_qpolynomial_fold_apply, data); + + isl_map_free(map); + return r; +} + +__isl_give isl_union_pw_qpolynomial_fold *isl_union_map_apply_union_pw_qpolynomial_fold( + __isl_take isl_union_map *umap, + __isl_take isl_union_pw_qpolynomial_fold *upwf, isl_bool *tight) +{ + isl_space *space; + enum isl_fold type; + struct isl_apply_fold_data data; + + upwf = isl_union_pw_qpolynomial_fold_align_params(upwf, + isl_union_map_get_space(umap)); + umap = isl_union_map_align_params(umap, + isl_union_pw_qpolynomial_fold_get_space(upwf)); + + data.upwf = upwf; + data.tight = tight ? isl_bool_true : isl_bool_false; + space = isl_union_pw_qpolynomial_fold_get_space(upwf); + type = isl_union_pw_qpolynomial_fold_get_type(upwf); + data.res = isl_union_pw_qpolynomial_fold_zero(space, type); + if (isl_union_map_foreach_map(umap, &map_apply, &data) < 0) + goto error; + + isl_union_map_free(umap); + isl_union_pw_qpolynomial_fold_free(upwf); + + if (tight) + *tight = data.tight; + + return data.res; +error: + isl_union_map_free(umap); + isl_union_pw_qpolynomial_fold_free(upwf); + isl_union_pw_qpolynomial_fold_free(data.res); + return NULL; +} + +__isl_give isl_union_pw_qpolynomial_fold *isl_union_set_apply_union_pw_qpolynomial_fold( + __isl_take isl_union_set *uset, + __isl_take isl_union_pw_qpolynomial_fold *upwf, isl_bool *tight) +{ + return isl_union_map_apply_union_pw_qpolynomial_fold(uset, upwf, tight); +} + +/* isl_qpolynomial_list_map callback for calling + * isl_qpolynomial_realign_domain on "qp". + */ +static __isl_give isl_qpolynomial *realign_domain( + __isl_take isl_qpolynomial *qp, void *user) +{ + isl_reordering *r = user; + + qp = isl_qpolynomial_realign_domain(qp, isl_reordering_copy(r)); + return qp; +} + +/* Reorder the dimension of "fold" according to the given reordering. + */ +__isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_realign_domain( + __isl_take isl_qpolynomial_fold *fold, __isl_take isl_reordering *r) +{ + isl_space *space; + isl_qpolynomial_list *list; + + list = isl_qpolynomial_fold_take_list(fold); + list = isl_qpolynomial_list_map(list, &realign_domain, r); + fold = isl_qpolynomial_fold_restore_list(fold, list); + + space = isl_reordering_get_space(r); + fold = isl_qpolynomial_fold_reset_domain_space(fold, space); + + isl_reordering_free(r); + + return fold; +} + +/* isl_qpolynomial_list_map callback for calling + * isl_qpolynomial_mul_isl_int on "qp". + */ +static __isl_give isl_qpolynomial *mul_int(__isl_take isl_qpolynomial *qp, + void *user) +{ + isl_int *v = user; + + qp = isl_qpolynomial_mul_isl_int(qp, *v); + return qp; +} + +__isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_mul_isl_int( + __isl_take isl_qpolynomial_fold *fold, isl_int v) +{ + isl_qpolynomial_list *list; + + if (isl_int_is_one(v)) + return fold; + if (fold && isl_int_is_zero(v)) { + isl_qpolynomial_fold *zero; + isl_space *space = isl_space_copy(fold->dim); + zero = isl_qpolynomial_fold_empty(fold->type, space); + isl_qpolynomial_fold_free(fold); + return zero; + } + + fold = isl_qpolynomial_fold_cow(fold); + if (!fold) + return NULL; + + if (isl_int_is_neg(v)) + fold->type = isl_fold_type_negate(fold->type); + + list = isl_qpolynomial_fold_take_list(fold); + list = isl_qpolynomial_list_map(list, &mul_int, &v); + fold = isl_qpolynomial_fold_restore_list(fold, list); + + return fold; +} + +__isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_scale( + __isl_take isl_qpolynomial_fold *fold, isl_int v) +{ + return isl_qpolynomial_fold_mul_isl_int(fold, v); +} + +/* isl_qpolynomial_list_map callback for calling + * isl_qpolynomial_scale_val on "qp". + */ +static __isl_give isl_qpolynomial *scale_val(__isl_take isl_qpolynomial *qp, + void *user) +{ + isl_val *v = user; + + qp = isl_qpolynomial_scale_val(qp, isl_val_copy(v)); + return qp; +} + +/* Multiply "fold" by "v". + */ +__isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_scale_val( + __isl_take isl_qpolynomial_fold *fold, __isl_take isl_val *v) +{ + isl_qpolynomial_list *list; + + if (!fold || !v) + goto error; + + if (isl_val_is_one(v)) { + isl_val_free(v); + return fold; + } + if (isl_val_is_zero(v)) { + isl_qpolynomial_fold *zero; + isl_space *space = isl_qpolynomial_fold_get_domain_space(fold); + zero = isl_qpolynomial_fold_empty(fold->type, space); + isl_qpolynomial_fold_free(fold); + isl_val_free(v); + return zero; + } + if (!isl_val_is_rat(v)) + isl_die(isl_qpolynomial_fold_get_ctx(fold), isl_error_invalid, + "expecting rational factor", goto error); + + fold = isl_qpolynomial_fold_cow(fold); + if (!fold) + goto error; + + if (isl_val_is_neg(v)) + fold->type = isl_fold_type_negate(fold->type); + + list = isl_qpolynomial_fold_take_list(fold); + list = isl_qpolynomial_list_map(list, &scale_val, v); + fold = isl_qpolynomial_fold_restore_list(fold, list); + + isl_val_free(v); + return fold; +error: + isl_val_free(v); + isl_qpolynomial_fold_free(fold); + return NULL; +} + +/* Divide "fold" by "v". + */ +__isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_scale_down_val( + __isl_take isl_qpolynomial_fold *fold, __isl_take isl_val *v) +{ + if (!fold || !v) + goto error; + + if (isl_val_is_one(v)) { + isl_val_free(v); + return fold; + } + if (!isl_val_is_rat(v)) + isl_die(isl_qpolynomial_fold_get_ctx(fold), isl_error_invalid, + "expecting rational factor", goto error); + if (isl_val_is_zero(v)) + isl_die(isl_val_get_ctx(v), isl_error_invalid, + "cannot scale down by zero", goto error); + + return isl_qpolynomial_fold_scale_val(fold, isl_val_inv(v)); +error: + isl_val_free(v); + isl_qpolynomial_fold_free(fold); + return NULL; +} diff --git a/external/mit/isl/dist/isl_from_range_templ.c b/external/mit/isl/dist/isl_from_range_templ.c new file mode 100644 index 000000000000..08c640d8b9b6 --- /dev/null +++ b/external/mit/isl/dist/isl_from_range_templ.c @@ -0,0 +1,29 @@ +/* + * Copyright 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 + */ + +/* Convert an object defined over a parameter domain + * into one that is defined over a zero-dimensional set. + */ +__isl_give TYPE *FN(TYPE,from_range)(__isl_take TYPE *obj) +{ + isl_space *space; + + if (!obj) + return NULL; + if (!isl_space_is_set(FN(TYPE,peek_space)(obj))) + isl_die(FN(TYPE,get_ctx)(obj), isl_error_invalid, + "not living in a set space", + return FN(TYPE,free)(obj)); + + space = FN(TYPE,get_space)(obj); + space = isl_space_from_range(space); + obj = FN(TYPE,reset_space)(obj, space); + + return obj; +} diff --git a/external/mit/isl/dist/isl_gmp.c b/external/mit/isl/dist/isl_gmp.c new file mode 100644 index 000000000000..d488fd2eb303 --- /dev/null +++ b/external/mit/isl/dist/isl_gmp.c @@ -0,0 +1,24 @@ +/* + * 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 + */ + +#include + +uint32_t isl_gmp_hash(mpz_t v, uint32_t hash) +{ + int sa = v[0]._mp_size; + int abs_sa = sa < 0 ? -sa : sa; + unsigned char *data = (unsigned char *)v[0]._mp_d; + unsigned char *end = data + abs_sa * sizeof(v[0]._mp_d[0]); + + if (sa < 0) + isl_hash_byte(hash, 0xFF); + for (; data < end; ++data) + isl_hash_byte(hash, *data); + return hash; +} diff --git a/external/mit/isl/dist/isl_hash.c b/external/mit/isl/dist/isl_hash.c new file mode 100644 index 000000000000..d0f6564a0201 --- /dev/null +++ b/external/mit/isl/dist/isl_hash.c @@ -0,0 +1,286 @@ +/* + * 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 + */ + +#include +#include +#include +#include "isl_config.h" + +uint32_t isl_hash_string(uint32_t hash, const char *s) +{ + for (; *s; s++) + isl_hash_byte(hash, *s); + return hash; +} + +uint32_t isl_hash_mem(uint32_t hash, const void *p, size_t len) +{ + int i; + const char *s = p; + for (i = 0; i < len; ++i) + isl_hash_byte(hash, s[i]); + return hash; +} + +static unsigned int round_up(unsigned int v) +{ + int old_v = v; + + while (v) { + old_v = v; + v ^= v & -v; + } + return old_v << 1; +} + +int isl_hash_table_init(struct isl_ctx *ctx, struct isl_hash_table *table, + int min_size) +{ + size_t size; + + if (!table) + return -1; + + if (min_size < 2) + min_size = 2; + table->bits = ffs(round_up(4 * (min_size + 1) / 3 - 1)) - 1; + table->n = 0; + + size = 1 << table->bits; + table->entries = isl_calloc_array(ctx, struct isl_hash_table_entry, + size); + if (!table->entries) + return -1; + + return 0; +} + +/* Dummy comparison function that always returns false. + */ +static isl_bool no(const void *entry, const void *val) +{ + return isl_bool_false; +} + +/* Extend "table" to twice its size. + * Return 0 on success and -1 on error. + * + * We reuse isl_hash_table_find to create entries in the extended table. + * Since all entries in the original table are assumed to be different, + * there is no need to compare them against each other. + */ +static int grow_table(struct isl_ctx *ctx, struct isl_hash_table *table) +{ + int n; + size_t old_size, size; + struct isl_hash_table_entry *entries; + uint32_t h; + + entries = table->entries; + old_size = 1 << table->bits; + size = 2 * old_size; + table->entries = isl_calloc_array(ctx, struct isl_hash_table_entry, + size); + if (!table->entries) { + table->entries = entries; + return -1; + } + + n = table->n; + table->n = 0; + table->bits++; + + for (h = 0; h < old_size; ++h) { + struct isl_hash_table_entry *entry; + + if (!entries[h].data) + continue; + + entry = isl_hash_table_find(ctx, table, entries[h].hash, + &no, NULL, 1); + if (!entry) { + table->bits--; + free(table->entries); + table->entries = entries; + table->n = n; + return -1; + } + + *entry = entries[h]; + } + + free(entries); + + return 0; +} + +struct isl_hash_table *isl_hash_table_alloc(struct isl_ctx *ctx, int min_size) +{ + struct isl_hash_table *table = NULL; + + table = isl_alloc_type(ctx, struct isl_hash_table); + if (isl_hash_table_init(ctx, table, min_size)) + goto error; + return table; +error: + isl_hash_table_free(ctx, table); + return NULL; +} + +void isl_hash_table_clear(struct isl_hash_table *table) +{ + if (!table) + return; + free(table->entries); +} + +void isl_hash_table_free(struct isl_ctx *ctx, struct isl_hash_table *table) +{ + if (!table) + return; + isl_hash_table_clear(table); + free(table); +} + +/* A dummy entry that is used by isl_hash_table_find + * to make a distinction between a missing entry and an error condition. + */ +static struct isl_hash_table_entry none = { 0, NULL }; +struct isl_hash_table_entry *isl_hash_table_entry_none = &none; + +struct isl_hash_table_entry *isl_hash_table_find(struct isl_ctx *ctx, + struct isl_hash_table *table, + uint32_t key_hash, + isl_bool (*eq)(const void *entry, const void *val), + const void *val, int reserve) +{ + size_t size; + uint32_t h, key_bits; + + key_bits = isl_hash_bits(key_hash, table->bits); + size = 1 << table->bits; + for (h = key_bits; table->entries[h].data; h = (h+1) % size) { + isl_bool equal; + + if (table->entries[h].hash != key_hash) + continue; + equal = eq(table->entries[h].data, val); + if (equal < 0) + return NULL; + if (equal) + return &table->entries[h]; + } + + if (!reserve) + return isl_hash_table_entry_none; + + if (4 * table->n >= 3 * size) { + if (grow_table(ctx, table) < 0) + return NULL; + return isl_hash_table_find(ctx, table, key_hash, eq, val, 1); + } + + table->n++; + table->entries[h].hash = key_hash; + + return &table->entries[h]; +} + +/* Return the first entry containing data in "table". + * Return isl_hash_table_entry_none is there is no such entry and + * NULL on error. + */ +struct isl_hash_table_entry *isl_hash_table_first(struct isl_hash_table *table) +{ + size_t size; + uint32_t h; + + if (!table->entries) + return NULL; + + size = 1 << table->bits; + for (h = 0; h < size; ++ h) + if (table->entries[h].data) + return &table->entries[h]; + + return isl_hash_table_entry_none; +} + +isl_stat isl_hash_table_foreach(isl_ctx *ctx, struct isl_hash_table *table, + isl_stat (*fn)(void **entry, void *user), void *user) +{ + size_t size; + uint32_t h; + + if (!table->entries) + return isl_stat_error; + + size = 1 << table->bits; + for (h = 0; h < size; ++ h) + if (table->entries[h].data && + fn(&table->entries[h].data, user) < 0) + return isl_stat_error; + + return isl_stat_ok; +} + +/* Does "test" succeed on every (non-empty) entry of "table"? + */ +isl_bool isl_hash_table_every(isl_ctx *ctx, struct isl_hash_table *table, + isl_bool (*test)(void **entry, void *user), void *user) +{ + size_t size; + uint32_t h; + + if (!table->entries) + return isl_bool_error; + + size = 1 << table->bits; + for (h = 0; h < size; ++ h) { + isl_bool r; + + if (!table->entries[h].data) + continue; + r = test(&table->entries[h].data, user); + if (r < 0 || !r) + return r; + } + + return isl_bool_true; +} + +void isl_hash_table_remove(struct isl_ctx *ctx, + struct isl_hash_table *table, + struct isl_hash_table_entry *entry) +{ + int h, h2; + size_t size; + + if (!table || !entry) + return; + + size = 1 << table->bits; + h = entry - table->entries; + isl_assert(ctx, h >= 0 && h < size, return); + + for (h2 = h+1; table->entries[h2 % size].data; h2++) { + uint32_t bits = isl_hash_bits(table->entries[h2 % size].hash, + table->bits); + uint32_t offset = (size + bits - (h+1)) % size; + if (offset <= h2 - (h+1)) + continue; + *entry = table->entries[h2 % size]; + h = h2; + entry = &table->entries[h % size]; + } + + entry->hash = 0; + entry->data = NULL; + table->n--; +} diff --git a/external/mit/isl/dist/isl_hash_private.h b/external/mit/isl/dist/isl_hash_private.h new file mode 100644 index 000000000000..bc5acb4b7937 --- /dev/null +++ b/external/mit/isl/dist/isl_hash_private.h @@ -0,0 +1,8 @@ +#ifndef ISL_HASH_PRIVATE_H +#define ISL_HASH_PRIVATE_H + +#include + +struct isl_hash_table_entry *isl_hash_table_first(struct isl_hash_table *table); + +#endif diff --git a/external/mit/isl/dist/isl_id.c b/external/mit/isl/dist/isl_id.c new file mode 100644 index 000000000000..d1f575e2461f --- /dev/null +++ b/external/mit/isl/dist/isl_id.c @@ -0,0 +1,308 @@ +/* + * 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 + */ + +#include +#include +#include + +#undef EL_BASE +#define EL_BASE id + +#include +#include + +/* A special, static isl_id to use as domains (and ranges) + * of sets and parameters domains. + * The user should never get a hold on this isl_id. + */ +isl_id isl_id_none = { + .ref = -1, + .ctx = NULL, + .name = "#none", + .user = NULL +}; + +isl_ctx *isl_id_get_ctx(__isl_keep isl_id *id) +{ + return id ? id->ctx : NULL; +} + +void *isl_id_get_user(__isl_keep isl_id *id) +{ + return id ? id->user : NULL; +} + +const char *isl_id_get_name(__isl_keep isl_id *id) +{ + return id ? id->name : NULL; +} + +static __isl_give isl_id *id_alloc(isl_ctx *ctx, const char *name, void *user) +{ + const char *copy = name ? strdup(name) : NULL; + isl_id *id; + + if (name && !copy) + return NULL; + id = isl_calloc_type(ctx, struct isl_id); + if (!id) + goto error; + + id->ctx = ctx; + isl_ctx_ref(id->ctx); + id->ref = 1; + id->name = copy; + id->user = user; + + id->hash = isl_hash_init(); + if (name) + id->hash = isl_hash_string(id->hash, name); + else + id->hash = isl_hash_builtin(id->hash, user); + + return id; +error: + free((char *)copy); + return NULL; +} + +uint32_t isl_id_get_hash(__isl_keep isl_id *id) +{ + return id ? id->hash : 0; +} + +struct isl_name_and_user { + const char *name; + void *user; +}; + +static isl_bool isl_id_has_name_and_user(const void *entry, const void *val) +{ + isl_id *id = (isl_id *)entry; + struct isl_name_and_user *nu = (struct isl_name_and_user *) val; + + if (id->user != nu->user) + return isl_bool_false; + if (id->name == nu->name) + return isl_bool_true; + if (!id->name || !nu->name) + return isl_bool_false; + + return isl_bool_ok(!strcmp(id->name, nu->name)); +} + +__isl_give isl_id *isl_id_alloc(isl_ctx *ctx, const char *name, void *user) +{ + struct isl_hash_table_entry *entry; + uint32_t id_hash; + struct isl_name_and_user nu = { name, user }; + + if (!ctx) + return NULL; + + id_hash = isl_hash_init(); + if (name) + id_hash = isl_hash_string(id_hash, name); + else + id_hash = isl_hash_builtin(id_hash, user); + entry = isl_hash_table_find(ctx, &ctx->id_table, id_hash, + isl_id_has_name_and_user, &nu, 1); + if (!entry) + return NULL; + if (entry->data) + return isl_id_copy(entry->data); + entry->data = id_alloc(ctx, name, user); + if (!entry->data) + ctx->id_table.n--; + return entry->data; +} + +/* If the id has a negative refcount, then it is a static isl_id + * which should not be changed. + */ +__isl_give isl_id *isl_id_copy(isl_id *id) +{ + if (!id) + return NULL; + + if (id->ref < 0) + return id; + + id->ref++; + return id; +} + +/* Compare two isl_ids. + * + * The order is fairly arbitrary. We do keep the comparison of + * the user pointers as a last resort since these pointer values + * may not be stable across different systems or even different runs. + */ +int isl_id_cmp(__isl_keep isl_id *id1, __isl_keep isl_id *id2) +{ + if (id1 == id2) + return 0; + if (!id1) + return -1; + if (!id2) + return 1; + if (!id1->name != !id2->name) + return !id1->name - !id2->name; + if (id1->name) { + int cmp = strcmp(id1->name, id2->name); + if (cmp != 0) + return cmp; + } + if (id1->user < id2->user) + return -1; + else + return 1; +} + +static isl_bool isl_id_eq(const void *entry, const void *name) +{ + return isl_bool_ok(entry == name); +} + +uint32_t isl_hash_id(uint32_t hash, __isl_keep isl_id *id) +{ + if (id) + isl_hash_hash(hash, id->hash); + + return hash; +} + +/* Replace the free_user callback by "free_user". + */ +__isl_give isl_id *isl_id_set_free_user(__isl_take isl_id *id, + void (*free_user)(void *user)) +{ + if (!id) + return NULL; + + id->free_user = free_user; + + return id; +} + +/* Retrieve the callback set by isl_id_set_free_user, + * or NULL if no such callback was set. + */ +void (*isl_id_get_free_user(__isl_keep isl_id *id))(void *user) +{ + if (!id) + return NULL; + return id->free_user; +} + +/* If the id has a negative refcount, then it is a static isl_id + * and should not be freed. + */ +__isl_null isl_id *isl_id_free(__isl_take isl_id *id) +{ + struct isl_hash_table_entry *entry; + + if (!id) + return NULL; + + if (id->ref < 0) + return NULL; + + if (--id->ref > 0) + return NULL; + + entry = isl_hash_table_find(id->ctx, &id->ctx->id_table, id->hash, + isl_id_eq, id, 0); + if (!entry) + return NULL; + if (entry == isl_hash_table_entry_none) + isl_die(id->ctx, isl_error_unknown, + "unable to find id", (void)0); + else + isl_hash_table_remove(id->ctx, &id->ctx->id_table, entry); + + if (id->free_user) + id->free_user(id->user); + + free((char *)id->name); + isl_ctx_deref(id->ctx); + free(id); + + return NULL; +} + +__isl_give isl_printer *isl_printer_print_id(__isl_take isl_printer *p, + __isl_keep isl_id *id) +{ + if (!id) + goto error; + + if (id->name) + p = isl_printer_print_str(p, id->name); + if (id->user) { + char buffer[50]; + snprintf(buffer, sizeof(buffer), "@%p", id->user); + p = isl_printer_print_str(p, buffer); + } + return p; +error: + isl_printer_free(p); + return NULL; +} + +/* Read an isl_id from "s" based on its name. + */ +__isl_give isl_id *isl_stream_read_id(__isl_keep isl_stream *s) +{ + struct isl_token *tok; + char *str; + isl_ctx *ctx; + isl_id *id; + + if (!s) + return NULL; + tok = isl_stream_next_token(s); + if (!tok) { + isl_stream_error(s, NULL, "unexpected EOF"); + return NULL; + } + ctx = isl_stream_get_ctx(s); + str = isl_token_get_str(ctx, tok); + isl_token_free(tok); + if (!str) + return NULL; + id = isl_id_alloc(ctx, str, NULL); + free(str); + + return id; +} + +#undef TYPE_BASE +#define TYPE_BASE id +#include "isl_read_from_str_templ.c" + +/* Is "id1" (obviously) equal to "id2"? + * + * isl_id objects can be compared by pointer value, but + * isl_multi_*_plain_is_equal needs an isl_*_plain_is_equal. + */ +static isl_bool isl_id_plain_is_equal(__isl_keep isl_id *id1, + __isl_keep isl_id *id2) +{ + if (!id1 || !id2) + return isl_bool_error; + return id1 == id2; +} + +#undef BASE +#define BASE id + +#include +#include +#include diff --git a/external/mit/isl/dist/isl_id_private.h b/external/mit/isl/dist/isl_id_private.h new file mode 100644 index 000000000000..bcc22175a095 --- /dev/null +++ b/external/mit/isl/dist/isl_id_private.h @@ -0,0 +1,47 @@ +/* + * 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_ID_PRIVATE_H +#define ISL_ID_PRIVATE_H + +#include +#include + +/* Represent a name and/or user pointer. + * + * If "free_user" is set, then it will be called on "user" when + * the last instance of the isl_id is freed. + */ +struct isl_id { + int ref; + isl_ctx *ctx; + + const char *name; + void *user; + uint32_t hash; + + __isl_give void (*free_user)(void *user); +}; + +#undef EL +#define EL isl_id + +#include + +uint32_t isl_hash_id(uint32_t hash, __isl_keep isl_id *id); +int isl_id_cmp(__isl_keep isl_id *id1, __isl_keep isl_id *id2); + +extern isl_id isl_id_none; + +#undef BASE +#define BASE id + +#include + +#endif diff --git a/external/mit/isl/dist/isl_id_to_ast_expr.c b/external/mit/isl/dist/isl_id_to_ast_expr.c new file mode 100644 index 000000000000..5a41ab67e8d8 --- /dev/null +++ b/external/mit/isl/dist/isl_id_to_ast_expr.c @@ -0,0 +1,21 @@ +#include +#include + +#include "isl_ast_private.h" + +#define isl_id_is_equal(id1,id2) isl_bool_ok(id1 == id2) + +#define ISL_KEY isl_id +#define ISL_VAL isl_ast_expr +#define ISL_HMAP_SUFFIX id_to_ast_expr +#define ISL_HMAP isl_id_to_ast_expr +#define ISL_HMAP_IS_EQUAL isl_id_to_ast_expr_is_equal +#define ISL_KEY_IS_EQUAL isl_id_is_equal +#define ISL_VAL_IS_EQUAL isl_ast_expr_is_equal +#define ISL_KEY_PRINT isl_printer_print_id +#define ISL_VAL_PRINT isl_printer_print_ast_expr +#define ISL_HMAP_HAVE_READ_FROM_STR +#define ISL_KEY_READ isl_stream_read_id +#define ISL_VAL_READ isl_stream_read_ast_expr + +#include diff --git a/external/mit/isl/dist/isl_id_to_id.c b/external/mit/isl/dist/isl_id_to_id.c new file mode 100644 index 000000000000..ca42f0d8fa73 --- /dev/null +++ b/external/mit/isl/dist/isl_id_to_id.c @@ -0,0 +1,20 @@ +#include +#include +#include + +#define isl_id_is_equal(id1,id2) isl_bool_ok(id1 == id2) + +#define ISL_KEY isl_id +#define ISL_VAL isl_id +#define ISL_HMAP_SUFFIX id_to_id +#define ISL_HMAP isl_id_to_id +#define ISL_HMAP_IS_EQUAL isl_id_to_id_is_equal +#define ISL_KEY_IS_EQUAL isl_id_is_equal +#define ISL_VAL_IS_EQUAL isl_id_is_equal +#define ISL_KEY_PRINT isl_printer_print_id +#define ISL_VAL_PRINT isl_printer_print_id +#define ISL_HMAP_HAVE_READ_FROM_STR +#define ISL_KEY_READ isl_stream_read_id +#define ISL_VAL_READ isl_stream_read_id + +#include diff --git a/external/mit/isl/dist/isl_id_to_pw_aff.c b/external/mit/isl/dist/isl_id_to_pw_aff.c new file mode 100644 index 000000000000..fcfa8c16af61 --- /dev/null +++ b/external/mit/isl/dist/isl_id_to_pw_aff.c @@ -0,0 +1,21 @@ +#include +#include + +#include "isl_aff_private.h" + +#define isl_id_is_equal(id1,id2) isl_bool_ok(id1 == id2) + +#define ISL_KEY isl_id +#define ISL_VAL isl_pw_aff +#define ISL_HMAP_SUFFIX id_to_pw_aff +#define ISL_HMAP isl_id_to_pw_aff +#define ISL_HMAP_IS_EQUAL isl_id_to_pw_aff_plain_is_equal +#define ISL_KEY_IS_EQUAL isl_id_is_equal +#define ISL_VAL_IS_EQUAL isl_pw_aff_plain_is_equal +#define ISL_KEY_PRINT isl_printer_print_id +#define ISL_VAL_PRINT isl_printer_print_pw_aff +#define ISL_HMAP_HAVE_READ_FROM_STR +#define ISL_KEY_READ isl_stream_read_id +#define ISL_VAL_READ isl_stream_read_pw_aff + +#include diff --git a/external/mit/isl/dist/isl_ilp.c b/external/mit/isl/dist/isl_ilp.c new file mode 100644 index 000000000000..2c004efe4b2c --- /dev/null +++ b/external/mit/isl/dist/isl_ilp.c @@ -0,0 +1,898 @@ +/* + * 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 + */ + +#include +#include +#include +#include +#include "isl_sample.h" +#include +#include "isl_equalities.h" +#include +#include +#include +#include +#include +#include +#include + +/* 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 + * the given basic set. + * Note that U may not contain all points that satisfy this property. + * + * We simply add the sum of all negative coefficients to the constant + * term. This ensures that if x satisfies the resulting constraints, + * then x plus any sum of unit vectors satisfies the original constraints. + */ +static __isl_give isl_basic_set *unit_box_base_points( + __isl_take isl_basic_set *bset) +{ + int i, j, k; + struct isl_basic_set *unit_box = NULL; + isl_size total; + + if (!bset) + goto error; + + if (bset->n_eq != 0) { + isl_space *space = isl_basic_set_get_space(bset); + isl_basic_set_free(bset); + return isl_basic_set_empty(space); + } + + total = isl_basic_set_dim(bset, isl_dim_all); + if (total < 0) + goto error; + unit_box = isl_basic_set_alloc_space(isl_basic_set_get_space(bset), + 0, 0, bset->n_ineq); + + for (i = 0; i < bset->n_ineq; ++i) { + k = isl_basic_set_alloc_inequality(unit_box); + if (k < 0) + goto error; + isl_seq_cpy(unit_box->ineq[k], bset->ineq[i], 1 + total); + for (j = 0; j < total; ++j) { + if (isl_int_is_nonneg(unit_box->ineq[k][1 + j])) + continue; + isl_int_add(unit_box->ineq[k][0], + unit_box->ineq[k][0], unit_box->ineq[k][1 + j]); + } + } + + isl_basic_set_free(bset); + return unit_box; +error: + isl_basic_set_free(bset); + isl_basic_set_free(unit_box); + return NULL; +} + +/* Find an integer point in "bset", preferably one that is + * close to minimizing "f". + * + * We first check if we can easily put unit boxes inside bset. + * If so, we take the best base point of any of the unit boxes we can find + * and round it up to the nearest integer. + * If not, we simply pick any integer point in "bset". + */ +static __isl_give isl_vec *initial_solution(__isl_keep isl_basic_set *bset, + isl_int *f) +{ + enum isl_lp_result res; + struct isl_basic_set *unit_box; + struct isl_vec *sol; + + unit_box = unit_box_base_points(isl_basic_set_copy(bset)); + + res = isl_basic_set_solve_lp(unit_box, 0, f, bset->ctx->one, + NULL, NULL, &sol); + if (res == isl_lp_ok) { + isl_basic_set_free(unit_box); + return isl_vec_ceil(sol); + } + + isl_basic_set_free(unit_box); + + return isl_basic_set_sample_vec(isl_basic_set_copy(bset)); +} + +/* Restrict "bset" to those points with values for f in the interval [l, u]. + */ +static __isl_give isl_basic_set *add_bounds(__isl_take isl_basic_set *bset, + isl_int *f, isl_int l, isl_int u) +{ + int k; + isl_size total; + + total = isl_basic_set_dim(bset, isl_dim_all); + if (total < 0) + return isl_basic_set_free(bset); + bset = isl_basic_set_extend_constraints(bset, 0, 2); + + k = isl_basic_set_alloc_inequality(bset); + if (k < 0) + goto error; + isl_seq_cpy(bset->ineq[k], f, 1 + total); + isl_int_sub(bset->ineq[k][0], bset->ineq[k][0], l); + + k = isl_basic_set_alloc_inequality(bset); + if (k < 0) + goto error; + isl_seq_neg(bset->ineq[k], f, 1 + total); + isl_int_add(bset->ineq[k][0], bset->ineq[k][0], u); + + return bset; +error: + isl_basic_set_free(bset); + return NULL; +} + +/* Find an integer point in "bset" that minimizes f (in any) such that + * the value of f lies inside the interval [l, u]. + * Return this integer point if it can be found. + * Otherwise, return sol. + * + * We perform a number of steps until l > u. + * In each step, we look for an integer point with value in either + * the whole interval [l, u] or half of the interval [l, l+floor(u-l-1/2)]. + * The choice depends on whether we have found an integer point in the + * previous step. If so, we look for the next point in half of the remaining + * interval. + * If we find a point, the current solution is updated and u is set + * to its value minus 1. + * If no point can be found, we update l to the upper bound of the interval + * we checked (u or l+floor(u-l-1/2)) plus 1. + */ +static __isl_give isl_vec *solve_ilp_search(__isl_keep isl_basic_set *bset, + isl_int *f, isl_int *opt, __isl_take isl_vec *sol, isl_int l, isl_int u) +{ + isl_int tmp; + int divide = 1; + + isl_int_init(tmp); + + while (isl_int_le(l, u)) { + struct isl_basic_set *slice; + struct isl_vec *sample; + + if (!divide) + isl_int_set(tmp, u); + else { + isl_int_sub(tmp, u, l); + isl_int_fdiv_q_ui(tmp, tmp, 2); + isl_int_add(tmp, tmp, l); + } + slice = add_bounds(isl_basic_set_copy(bset), f, l, tmp); + sample = isl_basic_set_sample_vec(slice); + if (!sample) { + isl_vec_free(sol); + sol = NULL; + break; + } + if (sample->size > 0) { + isl_vec_free(sol); + sol = sample; + isl_seq_inner_product(f, sol->el, sol->size, opt); + isl_int_sub_ui(u, *opt, 1); + divide = 1; + } else { + isl_vec_free(sample); + if (!divide) + break; + isl_int_add_ui(l, tmp, 1); + divide = 0; + } + } + + isl_int_clear(tmp); + + return sol; +} + +/* Find an integer point in "bset" that minimizes f (if any). + * If sol_p is not NULL then the integer point is returned in *sol_p. + * The optimal value of f is returned in *opt. + * + * The algorithm maintains a currently best solution and an interval [l, u] + * of values of f for which integer solutions could potentially still be found. + * The initial value of the best solution so far is any solution. + * The initial value of l is minimal value of f over the rationals + * (rounded up to the nearest integer). + * The initial value of u is the value of f at the initial solution minus 1. + * + * We then call solve_ilp_search to perform a binary search on the interval. + */ +static enum isl_lp_result solve_ilp(__isl_keep isl_basic_set *bset, + isl_int *f, isl_int *opt, __isl_give isl_vec **sol_p) +{ + enum isl_lp_result res; + isl_int l, u; + struct isl_vec *sol; + + res = isl_basic_set_solve_lp(bset, 0, f, bset->ctx->one, + opt, NULL, &sol); + if (res == isl_lp_ok && isl_int_is_one(sol->el[0])) { + if (sol_p) + *sol_p = sol; + else + isl_vec_free(sol); + return isl_lp_ok; + } + isl_vec_free(sol); + if (res == isl_lp_error || res == isl_lp_empty) + return res; + + sol = initial_solution(bset, f); + if (!sol) + return isl_lp_error; + if (sol->size == 0) { + isl_vec_free(sol); + return isl_lp_empty; + } + if (res == isl_lp_unbounded) { + isl_vec_free(sol); + return isl_lp_unbounded; + } + + isl_int_init(l); + isl_int_init(u); + + isl_int_set(l, *opt); + + isl_seq_inner_product(f, sol->el, sol->size, opt); + isl_int_sub_ui(u, *opt, 1); + + sol = solve_ilp_search(bset, f, opt, sol, l, u); + if (!sol) + res = isl_lp_error; + + isl_int_clear(l); + isl_int_clear(u); + + if (sol_p) + *sol_p = sol; + else + isl_vec_free(sol); + + return res; +} + +static enum isl_lp_result solve_ilp_with_eq(__isl_keep isl_basic_set *bset, + int max, isl_int *f, isl_int *opt, __isl_give isl_vec **sol_p) +{ + isl_size dim; + enum isl_lp_result res; + struct isl_mat *T = NULL; + struct isl_vec *v; + + bset = isl_basic_set_copy(bset); + dim = isl_basic_set_dim(bset, isl_dim_all); + if (dim < 0) + goto error; + v = isl_vec_alloc(bset->ctx, 1 + dim); + if (!v) + goto error; + isl_seq_cpy(v->el, f, 1 + dim); + bset = isl_basic_set_remove_equalities(bset, &T, NULL); + v = isl_vec_mat_product(v, isl_mat_copy(T)); + if (!v) + goto error; + res = isl_basic_set_solve_ilp(bset, max, v->el, opt, sol_p); + isl_vec_free(v); + if (res == isl_lp_ok && sol_p) { + *sol_p = isl_mat_vec_product(T, *sol_p); + if (!*sol_p) + res = isl_lp_error; + } else + isl_mat_free(T); + isl_basic_set_free(bset); + return res; +error: + isl_mat_free(T); + isl_basic_set_free(bset); + return isl_lp_error; +} + +/* Find an integer point in "bset" that minimizes (or maximizes if max is set) + * f (if any). + * If sol_p is not NULL then the integer point is returned in *sol_p. + * The optimal value of f is returned in *opt. + * + * If there is any equality among the points in "bset", then we first + * project it out. Otherwise, we continue with solve_ilp above. + */ +enum isl_lp_result isl_basic_set_solve_ilp(__isl_keep isl_basic_set *bset, + int max, isl_int *f, isl_int *opt, __isl_give isl_vec **sol_p) +{ + isl_size dim; + enum isl_lp_result res; + + if (sol_p) + *sol_p = NULL; + + if (isl_basic_set_check_no_params(bset) < 0) + return isl_lp_error; + + if (isl_basic_set_plain_is_empty(bset)) + return isl_lp_empty; + + if (bset->n_eq) + return solve_ilp_with_eq(bset, max, f, opt, sol_p); + + dim = isl_basic_set_dim(bset, isl_dim_all); + if (dim < 0) + return isl_lp_error; + + if (max) + isl_seq_neg(f, f, 1 + dim); + + res = solve_ilp(bset, f, opt, sol_p); + + if (max) { + isl_seq_neg(f, f, 1 + dim); + isl_int_neg(*opt, *opt); + } + + return res; +} + +static enum isl_lp_result basic_set_opt(__isl_keep isl_basic_set *bset, int max, + __isl_keep isl_aff *obj, isl_int *opt) +{ + enum isl_lp_result res; + + if (!obj) + return isl_lp_error; + bset = isl_basic_set_copy(bset); + bset = isl_basic_set_underlying_set(bset); + res = isl_basic_set_solve_ilp(bset, max, obj->v->el + 1, opt, NULL); + isl_basic_set_free(bset); + return res; +} + +enum isl_lp_result isl_basic_set_opt(__isl_keep isl_basic_set *bset, int max, + __isl_keep isl_aff *obj, isl_int *opt) +{ + int *exp1 = NULL; + int *exp2 = NULL; + isl_ctx *ctx; + isl_mat *bset_div = NULL; + isl_mat *div = NULL; + enum isl_lp_result res; + isl_size bset_n_div, obj_n_div; + + if (!bset || !obj) + return isl_lp_error; + + ctx = isl_aff_get_ctx(obj); + if (!isl_space_is_equal(bset->dim, obj->ls->dim)) + isl_die(ctx, isl_error_invalid, + "spaces don't match", return isl_lp_error); + if (!isl_int_is_one(obj->v->el[0])) + isl_die(ctx, isl_error_unsupported, + "expecting integer affine expression", + return isl_lp_error); + + bset_n_div = isl_basic_set_dim(bset, isl_dim_div); + obj_n_div = isl_aff_dim(obj, isl_dim_div); + if (bset_n_div < 0 || obj_n_div < 0) + return isl_lp_error; + if (bset_n_div == 0 && obj_n_div == 0) + return basic_set_opt(bset, max, obj, opt); + + bset = isl_basic_set_copy(bset); + obj = isl_aff_copy(obj); + + bset_div = isl_basic_set_get_divs(bset); + exp1 = isl_alloc_array(ctx, int, bset_n_div); + exp2 = isl_alloc_array(ctx, int, obj_n_div); + if (!bset_div || (bset_n_div && !exp1) || (obj_n_div && !exp2)) + goto error; + + div = isl_merge_divs(bset_div, obj->ls->div, exp1, exp2); + + bset = isl_basic_set_expand_divs(bset, isl_mat_copy(div), exp1); + obj = isl_aff_expand_divs(obj, isl_mat_copy(div), exp2); + + res = basic_set_opt(bset, max, obj, opt); + + isl_mat_free(bset_div); + isl_mat_free(div); + free(exp1); + free(exp2); + isl_basic_set_free(bset); + isl_aff_free(obj); + + return res; +error: + isl_mat_free(div); + isl_mat_free(bset_div); + free(exp1); + free(exp2); + isl_basic_set_free(bset); + isl_aff_free(obj); + return isl_lp_error; +} + +/* Compute the minimum (maximum if max is set) of the integer affine + * expression obj over the points in set and put the result in *opt. + * + * The parameters are assumed to have been aligned. + */ +static enum isl_lp_result isl_set_opt_aligned(__isl_keep isl_set *set, int max, + __isl_keep isl_aff *obj, isl_int *opt) +{ + int i; + enum isl_lp_result res; + int empty = 1; + isl_int opt_i; + + if (!set || !obj) + return isl_lp_error; + if (set->n == 0) + return isl_lp_empty; + + res = isl_basic_set_opt(set->p[0], max, obj, opt); + if (res == isl_lp_error || res == isl_lp_unbounded) + return res; + if (set->n == 1) + return res; + if (res == isl_lp_ok) + empty = 0; + + isl_int_init(opt_i); + for (i = 1; i < set->n; ++i) { + res = isl_basic_set_opt(set->p[i], max, obj, &opt_i); + if (res == isl_lp_error || res == isl_lp_unbounded) { + isl_int_clear(opt_i); + return res; + } + if (res == isl_lp_empty) + continue; + empty = 0; + if (max ? isl_int_gt(opt_i, *opt) : isl_int_lt(opt_i, *opt)) + isl_int_set(*opt, opt_i); + } + isl_int_clear(opt_i); + + return empty ? isl_lp_empty : isl_lp_ok; +} + +/* Compute the minimum (maximum if max is set) of the integer affine + * expression obj over the points in set and put the result in *opt. + */ +enum isl_lp_result isl_set_opt(__isl_keep isl_set *set, int max, + __isl_keep isl_aff *obj, isl_int *opt) +{ + enum isl_lp_result res; + isl_bool aligned; + + if (!set || !obj) + return isl_lp_error; + + aligned = isl_set_space_has_equal_params(set, obj->ls->dim); + if (aligned < 0) + return isl_lp_error; + if (aligned) + return isl_set_opt_aligned(set, max, obj, opt); + + set = isl_set_copy(set); + obj = isl_aff_copy(obj); + set = isl_set_align_params(set, isl_aff_get_domain_space(obj)); + obj = isl_aff_align_params(obj, isl_set_get_space(set)); + + res = isl_set_opt_aligned(set, max, obj, opt); + + isl_set_free(set); + isl_aff_free(obj); + + return res; +} + +/* 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. + * + * Return "v" with denominator set to 1 if lp_res is isl_lp_ok. + * Return NULL on error. + * Return a NaN if lp_res is isl_lp_empty. + * Return infinity or negative infinity if lp_res is isl_lp_unbounded, + * depending on "max". + */ +static __isl_give isl_val *convert_lp_result(enum isl_lp_result lp_res, + __isl_take isl_val *v, int max) +{ + isl_ctx *ctx; + + if (lp_res == isl_lp_ok) { + isl_int_set_si(v->d, 1); + return isl_val_normalize(v); + } + ctx = isl_val_get_ctx(v); + isl_val_free(v); + if (lp_res == isl_lp_error) + return NULL; + if (lp_res == isl_lp_empty) + return isl_val_nan(ctx); + if (max) + return isl_val_infty(ctx); + else + return isl_val_neginfty(ctx); +} + +/* Return the minimum (maximum if max is set) of the integer affine + * expression "obj" over the points in "bset". + * + * Return infinity or negative infinity if the optimal value is unbounded and + * NaN if "bset" is empty. + * + * Call isl_basic_set_opt and translate the results. + */ +__isl_give isl_val *isl_basic_set_opt_val(__isl_keep isl_basic_set *bset, + int max, __isl_keep isl_aff *obj) +{ + isl_ctx *ctx; + isl_val *res; + enum isl_lp_result lp_res; + + if (!bset || !obj) + return NULL; + + ctx = isl_aff_get_ctx(obj); + res = isl_val_alloc(ctx); + if (!res) + return NULL; + lp_res = isl_basic_set_opt(bset, max, obj, &res->n); + return convert_lp_result(lp_res, res, max); +} + +/* Return the maximum of the integer affine + * expression "obj" over the points in "bset". + * + * Return infinity or negative infinity if the optimal value is unbounded and + * NaN if "bset" is empty. + */ +__isl_give isl_val *isl_basic_set_max_val(__isl_keep isl_basic_set *bset, + __isl_keep isl_aff *obj) +{ + return isl_basic_set_opt_val(bset, 1, obj); +} + +/* Return the minimum (maximum if max is set) of the integer affine + * expression "obj" over the points in "set". + * + * Return infinity or negative infinity if the optimal value is unbounded and + * NaN if "set" is empty. + * + * Call isl_set_opt and translate the results. + */ +__isl_give isl_val *isl_set_opt_val(__isl_keep isl_set *set, int max, + __isl_keep isl_aff *obj) +{ + isl_ctx *ctx; + isl_val *res; + enum isl_lp_result lp_res; + + if (!set || !obj) + return NULL; + + ctx = isl_aff_get_ctx(obj); + res = isl_val_alloc(ctx); + if (!res) + return NULL; + lp_res = isl_set_opt(set, max, obj, &res->n); + return convert_lp_result(lp_res, res, max); +} + +/* Return the minimum of the integer affine + * expression "obj" over the points in "set". + * + * Return infinity or negative infinity if the optimal value is unbounded and + * NaN if "set" is empty. + */ +__isl_give isl_val *isl_set_min_val(__isl_keep isl_set *set, + __isl_keep isl_aff *obj) +{ + return isl_set_opt_val(set, 0, obj); +} + +/* Return the maximum of the integer affine + * expression "obj" over the points in "set". + * + * Return infinity or negative infinity if the optimal value is unbounded and + * NaN if "set" is empty. + */ +__isl_give isl_val *isl_set_max_val(__isl_keep isl_set *set, + __isl_keep isl_aff *obj) +{ + return isl_set_opt_val(set, 1, obj); +} + +/* Return the optimum (min or max depending on "max") of "v1" and "v2", + * where either may be NaN, signifying an uninitialized value. + * That is, if either is NaN, then return the other one. + */ +static __isl_give isl_val *val_opt(__isl_take isl_val *v1, + __isl_take isl_val *v2, int max) +{ + if (!v1 || !v2) + goto error; + if (isl_val_is_nan(v1)) { + isl_val_free(v1); + return v2; + } + if (isl_val_is_nan(v2)) { + isl_val_free(v2); + return v1; + } + if (max) + return isl_val_max(v1, v2); + else + return isl_val_min(v1, v2); +error: + isl_val_free(v1); + isl_val_free(v2); + return NULL; +} + +/* Internal data structure for isl_pw_aff_opt_val. + * + * "max" is set if the maximum should be computed. + * "res" contains the current optimum and is initialized to NaN. + */ +struct isl_pw_aff_opt_data { + int max; + + isl_val *res; +}; + +/* Update the optimum in data->res with respect to the affine function + * "aff" defined over "set". + */ +static isl_stat piece_opt(__isl_take isl_set *set, __isl_take isl_aff *aff, + void *user) +{ + struct isl_pw_aff_opt_data *data = user; + isl_val *opt; + + opt = isl_set_opt_val(set, data->max, aff); + isl_set_free(set); + isl_aff_free(aff); + + data->res = val_opt(data->res, opt, data->max); + if (!data->res) + return isl_stat_error; + + return isl_stat_ok; +} + +/* Return the minimum (maximum if "max" is set) of the integer piecewise affine + * expression "pa" over its definition domain. + * + * Return infinity or negative infinity if the optimal value is unbounded and + * NaN if the domain of "pa" is empty. + * + * Initialize the result to NaN and then update it for each of the pieces + * in "pa". + */ +static __isl_give isl_val *isl_pw_aff_opt_val(__isl_take isl_pw_aff *pa, + int max) +{ + struct isl_pw_aff_opt_data data = { max }; + + data.res = isl_val_nan(isl_pw_aff_get_ctx(pa)); + if (isl_pw_aff_foreach_piece(pa, &piece_opt, &data) < 0) + data.res = isl_val_free(data.res); + + isl_pw_aff_free(pa); + return data.res; +} + +#undef TYPE +#define TYPE isl_pw_aff +#include "isl_ilp_opt_fn_val_templ.c" + +#undef TYPE +#define TYPE isl_pw_multi_aff +#include "isl_ilp_opt_multi_val_templ.c" + +#undef TYPE +#define TYPE isl_multi_pw_aff +#include "isl_ilp_opt_multi_val_templ.c" + +/* Internal data structure for isl_union_pw_aff_opt_val. + * + * "max" is set if the maximum should be computed. + * "res" contains the current optimum and is initialized to NaN. + */ +struct isl_union_pw_aff_opt_data { + int max; + + isl_val *res; +}; + +/* Update the optimum in data->res with the optimum of "pa". + */ +static isl_stat pw_aff_opt(__isl_take isl_pw_aff *pa, void *user) +{ + struct isl_union_pw_aff_opt_data *data = user; + isl_val *opt; + + opt = isl_pw_aff_opt_val(pa, data->max); + + data->res = val_opt(data->res, opt, data->max); + if (!data->res) + return isl_stat_error; + + return isl_stat_ok; +} + +/* Return the minimum (maximum if "max" is set) of the integer piecewise affine + * expression "upa" over its definition domain. + * + * Return infinity or negative infinity if the optimal value is unbounded and + * NaN if the domain of the expression is empty. + * + * Initialize the result to NaN and then update it + * for each of the piecewise affine expressions in "upa". + */ +static __isl_give isl_val *isl_union_pw_aff_opt_val( + __isl_take isl_union_pw_aff *upa, int max) +{ + struct isl_union_pw_aff_opt_data data = { max }; + + data.res = isl_val_nan(isl_union_pw_aff_get_ctx(upa)); + if (isl_union_pw_aff_foreach_pw_aff(upa, &pw_aff_opt, &data) < 0) + data.res = isl_val_free(data.res); + isl_union_pw_aff_free(upa); + + return data.res; +} + +#undef TYPE +#define TYPE isl_union_pw_aff +#include "isl_ilp_opt_fn_val_templ.c" + +/* Return a list of minima (maxima if "max" is set) + * for each of the expressions in "mupa" over their domains. + * + * An element in the list is infinity or negative infinity if the optimal + * value of the corresponding expression is unbounded and + * NaN if the domain of the expression is empty. + * + * Iterate over all the expressions in "mupa" and collect the results. + */ +static __isl_give isl_multi_val *isl_multi_union_pw_aff_opt_multi_val( + __isl_take isl_multi_union_pw_aff *mupa, int max) +{ + int i; + isl_size n; + isl_multi_val *mv; + + n = isl_multi_union_pw_aff_size(mupa); + if (n < 0) + mupa = isl_multi_union_pw_aff_free(mupa); + if (!mupa) + return NULL; + + mv = isl_multi_val_zero(isl_multi_union_pw_aff_get_space(mupa)); + + for (i = 0; i < n; ++i) { + isl_val *v; + isl_union_pw_aff *upa; + + upa = isl_multi_union_pw_aff_get_union_pw_aff(mupa, i); + v = isl_union_pw_aff_opt_val(upa, max); + mv = isl_multi_val_set_val(mv, i, v); + } + + isl_multi_union_pw_aff_free(mupa); + return mv; +} + +/* Return a list of minima (maxima if "max" is set) over the points in "uset" + * for each of the expressions in "obj". + * + * An element in the list is infinity or negative infinity if the optimal + * value of the corresponding expression is unbounded and + * NaN if the intersection of "uset" with the domain of the expression + * is empty. + */ +static __isl_give isl_multi_val *isl_union_set_opt_multi_union_pw_aff( + __isl_keep isl_union_set *uset, int max, + __isl_keep isl_multi_union_pw_aff *obj) +{ + uset = isl_union_set_copy(uset); + obj = isl_multi_union_pw_aff_copy(obj); + obj = isl_multi_union_pw_aff_intersect_domain(obj, uset); + return isl_multi_union_pw_aff_opt_multi_val(obj, max); +} + +/* Return a list of minima over the points in "uset" + * for each of the expressions in "obj". + * + * An element in the list is infinity or negative infinity if the optimal + * value of the corresponding expression is unbounded and + * NaN if the intersection of "uset" with the domain of the expression + * is empty. + */ +__isl_give isl_multi_val *isl_union_set_min_multi_union_pw_aff( + __isl_keep isl_union_set *uset, __isl_keep isl_multi_union_pw_aff *obj) +{ + return isl_union_set_opt_multi_union_pw_aff(uset, 0, obj); +} + +/* Return a list of minima + * for each of the expressions in "mupa" over their domains. + * + * An element in the list is negative infinity if the optimal + * value of the corresponding expression is unbounded and + * NaN if the domain of the expression is empty. + */ +__isl_give isl_multi_val *isl_multi_union_pw_aff_min_multi_val( + __isl_take isl_multi_union_pw_aff *mupa) +{ + return isl_multi_union_pw_aff_opt_multi_val(mupa, 0); +} + +/* Return a list of maxima + * for each of the expressions in "mupa" over their domains. + * + * An element in the list is infinity if the optimal + * value of the corresponding expression is unbounded and + * NaN if the domain of the expression is empty. + */ +__isl_give isl_multi_val *isl_multi_union_pw_aff_max_multi_val( + __isl_take isl_multi_union_pw_aff *mupa) +{ + return isl_multi_union_pw_aff_opt_multi_val(mupa, 1); +} + +#undef BASE +#define BASE basic_set +#include "isl_ilp_opt_val_templ.c" + +/* 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) +{ + return isl_basic_set_dim_opt_val(bset, 1, pos); +} + +#undef BASE +#define BASE set +#include "isl_ilp_opt_val_templ.c" + +/* Return the minimal value attained by the given set dimension, + * independently of the parameter values and of any other dimensions. + * + * Return negative infinity if the optimal value is unbounded and + * NaN if "set" is empty. + */ +__isl_give isl_val *isl_set_dim_min_val(__isl_take isl_set *set, int pos) +{ + return isl_set_dim_opt_val(set, 0, pos); +} + +/* 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 "set" is empty. + */ +__isl_give isl_val *isl_set_dim_max_val(__isl_take isl_set *set, int pos) +{ + return isl_set_dim_opt_val(set, 1, pos); +} diff --git a/external/mit/isl/dist/isl_ilp_opt_fn_val_templ.c b/external/mit/isl/dist/isl_ilp_opt_fn_val_templ.c new file mode 100644 index 000000000000..6b2c5323225a --- /dev/null +++ b/external/mit/isl/dist/isl_ilp_opt_fn_val_templ.c @@ -0,0 +1,32 @@ +/* + * Copyright 2018 Sven Verdoolaege + * + * Use of this software is governed by the MIT license + * + * Written by Sven Verdoolaege. + */ + +#define xFN(TYPE,NAME) TYPE ## _ ## NAME +#define FN(TYPE,NAME) xFN(TYPE,NAME) + +/* Return the minimum of the integer piecewise affine + * expression "f" over its definition domain. + * + * Return negative infinity if the optimal value is unbounded and + * NaN if the domain of the expression is empty. + */ +__isl_give isl_val *FN(TYPE,min_val)(__isl_take TYPE *f) +{ + return FN(TYPE,opt_val)(f, 0); +} + +/* Return the maximum of the integer piecewise affine + * expression "f" over its definition domain. + * + * Return infinity if the optimal value is unbounded and + * NaN if the domain of the expression is empty. + */ +__isl_give isl_val *FN(TYPE,max_val)(__isl_take TYPE *f) +{ + return FN(TYPE,opt_val)(f, 1); +} diff --git a/external/mit/isl/dist/isl_ilp_opt_multi_val_templ.c b/external/mit/isl/dist/isl_ilp_opt_multi_val_templ.c new file mode 100644 index 000000000000..13d0230b593e --- /dev/null +++ b/external/mit/isl/dist/isl_ilp_opt_multi_val_templ.c @@ -0,0 +1,75 @@ +/* + * Copyright 2019 Cerebras Systems + * + * Use of this software is governed by the MIT license + * + * Written by Sven Verdoolaege, + * Cerebras Systems, 175 S San Antonio Rd, Los Altos, CA, USA + */ + +#define xFN(TYPE,NAME) TYPE ## _ ## NAME +#define FN(TYPE,NAME) xFN(TYPE,NAME) + +/* Return a list of minima (maxima if "max" is set) + * for each of the expressions in "f" over their (shared) domain. + * + * An element in the list is infinity or negative infinity if the optimal + * value of the corresponding expression is unbounded and + * NaN if the domain of the expression is empty. + * + * Iterate over all the expressions in "f" and collect the results. + */ +static __isl_give isl_multi_val *FN(TYPE,opt_multi_val)(__isl_take TYPE *f, + int max) +{ + int i; + isl_size n; + isl_space *space; + isl_multi_val *mv; + + n = FN(TYPE,dim)(f, isl_dim_out); + if (n < 0) + f = FN(TYPE,free)(f); + if (!f) + return NULL; + + space = isl_space_range(FN(TYPE,get_space)(f)); + space = isl_space_drop_all_params(space); + mv = isl_multi_val_zero(space); + + for (i = 0; i < n; ++i) { + isl_val *v; + isl_pw_aff *pa; + + pa = FN(TYPE,get_pw_aff)(f, i); + v = isl_pw_aff_opt_val(pa, max); + mv = isl_multi_val_set_val(mv, i, v); + } + + FN(TYPE,free)(f); + return mv; +} + +/* Return a list of minima + * for each of the expressions in "f" over their (shared) domain. + * + * An element in the list is negative infinity if the optimal + * value of the corresponding expression is unbounded and + * NaN if the domain of the expression is empty. + */ +__isl_give isl_multi_val *FN(TYPE,min_multi_val)(__isl_take TYPE *f) +{ + return FN(TYPE,opt_multi_val)(f, 0); +} + +/* Return a list of maxima + * for each of the expressions in "f" over their (shared) domain. + * + * An element in the list is infinity if the optimal + * value of the corresponding expression is unbounded and + * NaN if the domain of the expression is empty. + */ +__isl_give isl_multi_val *FN(TYPE,max_multi_val)(__isl_take TYPE *f) +{ + return FN(TYPE,opt_multi_val)(f, 1); +} diff --git a/external/mit/isl/dist/isl_ilp_opt_val_templ.c b/external/mit/isl/dist/isl_ilp_opt_val_templ.c new file mode 100644 index 000000000000..7e3520d65460 --- /dev/null +++ b/external/mit/isl/dist/isl_ilp_opt_val_templ.c @@ -0,0 +1,42 @@ +/* + * Copyright 2017 Sven Verdoolaege + * + * Use of this software is governed by the MIT license + * + * Written by Sven Verdoolaege + */ + +#define xCAT(A,B) A ## B +#define CAT(A,B) xCAT(A,B) +#undef TYPE +#define TYPE CAT(isl_,BASE) +#define xBFN(BASE,NAME) isl_ ## BASE ## _ ## NAME +#define BFN(BASE,NAME) xBFN(BASE,NAME) + +/* Return the minimal (maximal if "max" is set) value attained + * by the given set dimension, + * independently of the parameter values and of any other dimensions. + * + * Return infinity or negative infinity if the optimal value is unbounded and + * NaN if "set" is empty. + */ +static __isl_give isl_val *BFN(BASE,dim_opt_val)(__isl_take TYPE *set, int max, + int pos) +{ + isl_local_space *ls; + isl_aff *obj; + isl_val *v; + + if (BFN(BASE,check_range)(set, isl_dim_set, pos, 1) < 0) + goto error; + ls = isl_local_space_from_space(BFN(BASE,get_space)(set)); + obj = isl_aff_var_on_domain(ls, isl_dim_set, pos); + v = BFN(BASE,opt_val)(set, max, obj); + isl_aff_free(obj); + BFN(BASE,free)(set); + + return v; +error: + BFN(BASE,free)(set); + return NULL; +} diff --git a/external/mit/isl/dist/isl_ilp_private.h b/external/mit/isl/dist/isl_ilp_private.h new file mode 100644 index 000000000000..932b2c3d4f27 --- /dev/null +++ b/external/mit/isl/dist/isl_ilp_private.h @@ -0,0 +1,11 @@ +#ifndef ISL_ILP_PRIVATE_H +#define ISL_ILP_PRIVATE_H + +#include +#include +#include + +enum isl_lp_result isl_basic_set_solve_ilp(__isl_keep isl_basic_set *bset, + int max, isl_int *f, isl_int *opt, __isl_give isl_vec **sol_p); + +#endif diff --git a/external/mit/isl/dist/isl_imath.c b/external/mit/isl/dist/isl_imath.c new file mode 100644 index 000000000000..d870f1486da8 --- /dev/null +++ b/external/mit/isl/dist/isl_imath.c @@ -0,0 +1,83 @@ +#include + +uint32_t isl_imath_hash(mp_int v, uint32_t hash) +{ + unsigned const char *data = (unsigned char *)v->digits; + unsigned const char *end = data + v->used * sizeof(v->digits[0]); + + if (v->sign == 1) + isl_hash_byte(hash, 0xFF); + for (; data < end; ++data) + isl_hash_byte(hash, *data); + return hash; +} + +/* Try a standard conversion that fits into a long. + */ +int isl_imath_fits_slong_p(mp_int op) +{ + long out; + mp_result res = mp_int_to_int(op, &out); + return res == MP_OK; +} + +/* Try a standard conversion that fits into an unsigned long. + */ +int isl_imath_fits_ulong_p(mp_int op) +{ + unsigned long out; + mp_result res = mp_int_to_uint(op, &out); + return res == MP_OK; +} + +void isl_imath_addmul_ui(mp_int rop, mp_int op1, unsigned long op2) +{ + mpz_t temp; + mp_int_init(&temp); + + mp_int_set_uvalue(&temp, op2); + mp_int_mul(op1, &temp, &temp); + mp_int_add(rop, &temp, rop); + + mp_int_clear(&temp); +} + +void isl_imath_submul_ui(mp_int rop, mp_int op1, unsigned long op2) +{ + mpz_t temp; + mp_int_init(&temp); + + mp_int_set_uvalue(&temp, op2); + mp_int_mul(op1, &temp, &temp); + mp_int_sub(rop, &temp, rop); + + mp_int_clear(&temp); +} + +/* Compute the division of lhs by a rhs of type unsigned long, rounding towards + * positive infinity (Ceil). + */ +void isl_imath_cdiv_q_ui(mp_int rop, mp_int lhs, unsigned long rhs) +{ + mpz_t temp; + mp_int_init(&temp); + + mp_int_set_uvalue(&temp, rhs); + impz_cdiv_q(rop, lhs, &temp); + + mp_int_clear(&temp); +} + +/* Compute the division of lhs by a rhs of type unsigned long, rounding towards + * negative infinity (Floor). + */ +void isl_imath_fdiv_q_ui(mp_int rop, mp_int lhs, unsigned long rhs) +{ + mpz_t temp; + mp_int_init(&temp); + + mp_int_set_uvalue(&temp, rhs); + impz_fdiv_q(rop, lhs, &temp); + + mp_int_clear(&temp); +} diff --git a/external/mit/isl/dist/isl_imath.h b/external/mit/isl/dist/isl_imath.h new file mode 100644 index 000000000000..9efbe319ee2e --- /dev/null +++ b/external/mit/isl/dist/isl_imath.h @@ -0,0 +1,10 @@ +#include +#include + +uint32_t isl_imath_hash(mp_int v, uint32_t hash); +int isl_imath_fits_ulong_p(mp_int op); +int isl_imath_fits_slong_p(mp_int op); +void isl_imath_addmul_ui(mp_int rop, mp_int op1, unsigned long op2); +void isl_imath_submul_ui(mp_int rop, mp_int op1, unsigned long op2); +void isl_imath_cdiv_q_ui(mp_int rop, mp_int op1, unsigned long op2); +void isl_imath_fdiv_q_ui(mp_int rop, mp_int op1, unsigned long op2); diff --git a/external/mit/isl/dist/isl_input.c b/external/mit/isl/dist/isl_input.c new file mode 100644 index 000000000000..08260cd5b51e --- /dev/null +++ b/external/mit/isl/dist/isl_input.c @@ -0,0 +1,4289 @@ +/* + * Copyright 2008-2009 Katholieke Universiteit Leuven + * Copyright 2010 INRIA Saclay + * Copyright 2012-2013 Ecole Normale Superieure + * Copyright 2019,2022 Cerebras Systems + * + * 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 + * and Cerebras Systems, 175 S San Antonio Rd, Los Altos, CA, USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "isl_polynomial_private.h" +#include +#include +#include +#include +#include +#include +#include + +struct variable { + char *name; + int pos; + struct variable *next; +}; + +struct vars { + struct isl_ctx *ctx; + int n; + struct variable *v; +}; + +static struct vars *vars_new(struct isl_ctx *ctx) +{ + struct vars *v; + v = isl_alloc_type(ctx, struct vars); + if (!v) + return NULL; + v->ctx = ctx; + v->n = 0; + v->v = NULL; + return v; +} + +static void variable_free(struct variable *var) +{ + while (var) { + struct variable *next = var->next; + free(var->name); + free(var); + var = next; + } +} + +static void vars_free(struct vars *v) +{ + if (!v) + return; + variable_free(v->v); + free(v); +} + +static void vars_drop(struct vars *v, int n) +{ + struct variable *var; + + if (!v || !v->v) + return; + + v->n -= n; + + var = v->v; + while (--n >= 0) { + struct variable *next = var->next; + free(var->name); + free(var); + var = next; + } + v->v = var; +} + +static struct variable *variable_new(struct vars *v, const char *name, int len, + int pos) +{ + struct variable *var; + var = isl_calloc_type(v->ctx, struct variable); + if (!var) + goto error; + var->name = strdup(name); + var->name[len] = '\0'; + var->pos = pos; + var->next = v->v; + return var; +error: + variable_free(v->v); + return NULL; +} + +static int vars_pos(struct vars *v, const char *s, int len) +{ + int pos; + struct variable *q; + + if (len == -1) + len = strlen(s); + for (q = v->v; q; q = q->next) { + if (strncmp(q->name, s, len) == 0 && q->name[len] == '\0') + break; + } + if (q) + pos = q->pos; + else { + pos = v->n; + v->v = variable_new(v, s, len, v->n); + if (!v->v) + return -1; + v->n++; + } + return pos; +} + +static int vars_add_anon(struct vars *v) +{ + v->v = variable_new(v, "", 0, v->n); + + if (!v->v) + return -1; + v->n++; + + return 0; +} + +/* Obtain next token, with some preprocessing. + * In particular, evaluate expressions of the form x^y, + * with x and y values. + */ +static struct isl_token *next_token(__isl_keep isl_stream *s) +{ + struct isl_token *tok, *tok2; + + tok = isl_stream_next_token(s); + if (!tok || tok->type != ISL_TOKEN_VALUE) + return tok; + if (!isl_stream_eat_if_available(s, '^')) + return tok; + tok2 = isl_stream_next_token(s); + if (!tok2 || tok2->type != ISL_TOKEN_VALUE) { + isl_stream_error(s, tok2, "expecting constant value"); + goto error; + } + + isl_int_pow_ui(tok->u.v, tok->u.v, isl_int_get_ui(tok2->u.v)); + + isl_token_free(tok2); + return tok; +error: + isl_token_free(tok); + isl_token_free(tok2); + return NULL; +} + +/* Read an isl_val from "s". + * + * The following token sequences are recognized + * + * "infty" -> infty + * "-" "infty" -> -infty + * "NaN" -> NaN + * n "/" d -> n/d + * "-" n "/" d -> -n/d + * v -> v + * "-" v -> -v + * + * where n, d and v are integer constants. + */ +__isl_give isl_val *isl_stream_read_val(__isl_keep isl_stream *s) +{ + struct isl_token *tok = NULL; + struct isl_token *tok2 = NULL; + int sign = 1; + isl_val *val; + + if (isl_stream_eat_if_available(s, '-')) + sign = -1; + tok = next_token(s); + if (!tok) { + isl_stream_error(s, NULL, "unexpected EOF"); + goto error; + } + if (tok->type == ISL_TOKEN_INFTY) { + isl_token_free(tok); + if (sign > 0) + return isl_val_infty(s->ctx); + else + return isl_val_neginfty(s->ctx); + } + if (sign > 0 && tok->type == ISL_TOKEN_NAN) { + isl_token_free(tok); + return isl_val_nan(s->ctx); + } + if (tok->type != ISL_TOKEN_VALUE) { + isl_stream_error(s, tok, "expecting value"); + goto error; + } + + if (sign < 0) + isl_int_neg(tok->u.v, tok->u.v); + + if (isl_stream_eat_if_available(s, '/')) { + tok2 = next_token(s); + if (!tok2) { + isl_stream_error(s, NULL, "unexpected EOF"); + goto error; + } + if (tok2->type != ISL_TOKEN_VALUE) { + isl_stream_error(s, tok2, "expecting value"); + goto error; + } + val = isl_val_rat_from_isl_int(s->ctx, tok->u.v, tok2->u.v); + val = isl_val_normalize(val); + } else { + val = isl_val_int_from_isl_int(s->ctx, tok->u.v); + } + + isl_token_free(tok); + isl_token_free(tok2); + return val; +error: + isl_token_free(tok); + isl_token_free(tok2); + return NULL; +} + +#undef TYPE_BASE +#define TYPE_BASE val +#include "isl_read_from_str_templ.c" + +static isl_stat accept_cst_factor(__isl_keep isl_stream *s, isl_int *f) +{ + struct isl_token *tok; + + if (isl_stream_eat_if_available(s, '-')) + isl_int_neg(*f, *f); + tok = next_token(s); + if (!tok || tok->type != ISL_TOKEN_VALUE) { + isl_stream_error(s, tok, "expecting constant value"); + goto error; + } + + isl_int_mul(*f, *f, tok->u.v); + + isl_token_free(tok); + + if (isl_stream_eat_if_available(s, '*')) + return accept_cst_factor(s, f); + + return isl_stat_ok; +error: + isl_token_free(tok); + return isl_stat_error; +} + +/* Given an affine expression aff, return an affine expression + * for aff % d, with d the next token on the stream, which is + * assumed to be a constant. + * + * We introduce an integer division q = [aff/d] and the result + * is set to aff - d q. + */ +static __isl_give isl_pw_aff *affine_mod(__isl_keep isl_stream *s, + struct vars *v, __isl_take isl_pw_aff *aff) +{ + struct isl_token *tok; + isl_pw_aff *q; + + tok = next_token(s); + if (!tok || tok->type != ISL_TOKEN_VALUE) { + isl_stream_error(s, tok, "expecting constant value"); + goto error; + } + + q = isl_pw_aff_copy(aff); + q = isl_pw_aff_scale_down(q, tok->u.v); + q = isl_pw_aff_floor(q); + q = isl_pw_aff_scale(q, tok->u.v); + + aff = isl_pw_aff_sub(aff, q); + + isl_token_free(tok); + return aff; +error: + isl_pw_aff_free(aff); + isl_token_free(tok); + return NULL; +} + +static __isl_give isl_pw_aff *accept_affine(__isl_keep isl_stream *s, + __isl_take isl_space *space, struct vars *v); +static __isl_give isl_pw_aff_list *accept_affine_list(__isl_keep isl_stream *s, + __isl_take isl_space *space, struct vars *v); + +static __isl_give isl_pw_aff *accept_minmax(__isl_keep isl_stream *s, + __isl_take isl_space *space, struct vars *v) +{ + struct isl_token *tok; + isl_pw_aff_list *list = NULL; + int min; + + tok = isl_stream_next_token(s); + if (!tok) + goto error; + min = tok->type == ISL_TOKEN_MIN; + isl_token_free(tok); + + if (isl_stream_eat(s, '(')) + goto error; + + list = accept_affine_list(s, isl_space_copy(space), v); + if (!list) + goto error; + + if (isl_stream_eat(s, ')')) + goto error; + + isl_space_free(space); + return min ? isl_pw_aff_list_min(list) : isl_pw_aff_list_max(list); +error: + isl_space_free(space); + isl_pw_aff_list_free(list); + return NULL; +} + +/* Divide "pa" by an integer constant read from the stream. + */ +static __isl_give isl_pw_aff *pw_aff_div_by_cst(__isl_keep isl_stream *s, + __isl_take isl_pw_aff *pa) +{ + struct isl_token *tok; + + tok = next_token(s); + if (!tok || tok->type != ISL_TOKEN_VALUE) { + isl_stream_error(s, tok, "expecting denominator"); + isl_token_free(tok); + return isl_pw_aff_free(pa); + } + + pa = isl_pw_aff_scale_down(pa, tok->u.v); + + isl_token_free(tok); + + return pa; +} + +/* Return the (signed) value that is next on the stream, + * using "next" to read the next token and printing "msg" in case of an error. + */ +static struct isl_token *next_signed_value_fn(__isl_keep isl_stream *s, + struct isl_token *(*next)(__isl_keep isl_stream *s), char *msg) +{ + struct isl_token *tok; + int sign = 1; + + if (isl_stream_eat_if_available(s, '-')) + sign = -1; + tok = next(s); + if (!tok || tok->type != ISL_TOKEN_VALUE) { + isl_stream_error(s, tok, msg); + isl_token_free(tok); + return NULL; + } + if (sign < 0) + isl_int_neg(tok->u.v, tok->u.v); + return tok; +} + +/* Return the (signed) value that is next on the stream, + * printing "msg" in case of an error. + */ +static struct isl_token *next_signed_value(__isl_keep isl_stream *s, char *msg) +{ + return next_signed_value_fn(s, &isl_stream_next_token, msg); +} + +/* Return the (signed) value that is next on the stream, + * provided it is on the same line, + * printing "msg" in case of an error. + */ +static struct isl_token *next_signed_value_on_same_line( + __isl_keep isl_stream *s, char *msg) +{ + return next_signed_value_fn(s, + &isl_stream_next_token_on_same_line, msg); +} + +/* Is "tok" the start of an integer division? + */ +static int is_start_of_div(struct isl_token *tok) +{ + if (!tok) + return 0; + if (tok->type == '[') + return 1; + if (tok->type == ISL_TOKEN_FLOOR) + return 1; + if (tok->type == ISL_TOKEN_CEIL) + return 1; + if (tok->type == ISL_TOKEN_FLOORD) + return 1; + if (tok->type == ISL_TOKEN_CEILD) + return 1; + return 0; +} + +/* Read an integer division from "s" and return it as an isl_pw_aff. + * + * The integer division can be of the form + * + * [] + * floor() + * ceil() + * floord(,) + * ceild(,) + */ +static __isl_give isl_pw_aff *accept_div(__isl_keep isl_stream *s, + __isl_take isl_space *space, struct vars *v) +{ + int f = 0; + int c = 0; + int extra = 0; + isl_pw_aff *pwaff = NULL; + + if (isl_stream_eat_if_available(s, ISL_TOKEN_FLOORD)) + extra = f = 1; + else if (isl_stream_eat_if_available(s, ISL_TOKEN_CEILD)) + extra = c = 1; + else if (isl_stream_eat_if_available(s, ISL_TOKEN_FLOOR)) + f = 1; + else if (isl_stream_eat_if_available(s, ISL_TOKEN_CEIL)) + c = 1; + if (f || c) { + if (isl_stream_eat(s, '(')) + goto error; + } else { + if (isl_stream_eat(s, '[')) + goto error; + } + + pwaff = accept_affine(s, isl_space_copy(space), v); + + if (extra) { + if (isl_stream_eat(s, ',')) + goto error; + + pwaff = pw_aff_div_by_cst(s, pwaff); + } + + if (c) + pwaff = isl_pw_aff_ceil(pwaff); + else + pwaff = isl_pw_aff_floor(pwaff); + + if (f || c) { + if (isl_stream_eat(s, ')')) + goto error; + } else { + if (isl_stream_eat(s, ']')) + goto error; + } + + isl_space_free(space); + return pwaff; +error: + isl_space_free(space); + isl_pw_aff_free(pwaff); + return NULL; +} + +static __isl_give isl_pw_aff *accept_affine_factor(__isl_keep isl_stream *s, + __isl_take isl_space *space, struct vars *v) +{ + struct isl_token *tok = NULL; + isl_pw_aff *res = NULL; + + tok = next_token(s); + if (!tok) { + isl_stream_error(s, NULL, "unexpected EOF"); + goto error; + } + + if (tok->type == ISL_TOKEN_AFF) { + res = isl_pw_aff_copy(tok->u.pwaff); + isl_token_free(tok); + } else if (tok->type == ISL_TOKEN_IDENT) { + int n = v->n; + int pos = vars_pos(v, tok->u.s, -1); + isl_aff *aff; + + if (pos < 0) + goto error; + if (pos >= n) { + vars_drop(v, v->n - n); + isl_stream_error(s, tok, "unknown identifier"); + goto error; + } + + aff = isl_aff_zero_on_domain(isl_local_space_from_space(isl_space_copy(space))); + if (!aff) + goto error; + aff->v = isl_vec_set_element_si(aff->v, 2 + pos, 1); + if (!aff->v) + aff = isl_aff_free(aff); + res = isl_pw_aff_from_aff(aff); + isl_token_free(tok); + } else if (tok->type == ISL_TOKEN_VALUE) { + if (isl_stream_eat_if_available(s, '*') || + isl_stream_next_token_is(s, ISL_TOKEN_IDENT)) { + if (isl_stream_eat_if_available(s, '-')) + isl_int_neg(tok->u.v, tok->u.v); + res = accept_affine_factor(s, isl_space_copy(space), v); + res = isl_pw_aff_scale(res, tok->u.v); + } else { + isl_local_space *ls; + isl_aff *aff; + ls = isl_local_space_from_space(isl_space_copy(space)); + aff = isl_aff_zero_on_domain(ls); + aff = isl_aff_add_constant(aff, tok->u.v); + res = isl_pw_aff_from_aff(aff); + } + isl_token_free(tok); + } else if (tok->type == '(') { + isl_token_free(tok); + tok = NULL; + res = accept_affine(s, isl_space_copy(space), v); + if (!res) + goto error; + if (isl_stream_eat(s, ')')) + goto error; + } else if (is_start_of_div(tok)) { + isl_stream_push_token(s, tok); + tok = NULL; + res = accept_div(s, isl_space_copy(space), v); + } else if (tok->type == ISL_TOKEN_MIN || tok->type == ISL_TOKEN_MAX) { + isl_stream_push_token(s, tok); + tok = NULL; + res = accept_minmax(s, isl_space_copy(space), v); + } else { + isl_stream_error(s, tok, "expecting factor"); + goto error; + } + if (isl_stream_eat_if_available(s, '%') || + isl_stream_eat_if_available(s, ISL_TOKEN_MOD)) { + isl_space_free(space); + return affine_mod(s, v, res); + } + if (isl_stream_eat_if_available(s, '*')) { + isl_int f; + isl_int_init(f); + isl_int_set_si(f, 1); + if (accept_cst_factor(s, &f) < 0) { + isl_int_clear(f); + goto error2; + } + res = isl_pw_aff_scale(res, f); + isl_int_clear(f); + } + if (isl_stream_eat_if_available(s, '/')) + res = pw_aff_div_by_cst(s, res); + if (isl_stream_eat_if_available(s, ISL_TOKEN_INT_DIV)) + res = isl_pw_aff_floor(pw_aff_div_by_cst(s, res)); + + isl_space_free(space); + return res; +error: + isl_token_free(tok); +error2: + isl_pw_aff_free(res); + isl_space_free(space); + return NULL; +} + +/* Return a piecewise affine expression defined on the specified domain + * that represents NaN. + */ +static __isl_give isl_pw_aff *nan_on_domain(__isl_keep isl_space *space) +{ + return isl_pw_aff_nan_on_domain_space(isl_space_copy(space)); +} + +static __isl_give isl_pw_aff *accept_affine(__isl_keep isl_stream *s, + __isl_take isl_space *space, struct vars *v) +{ + struct isl_token *tok = NULL; + isl_local_space *ls; + isl_pw_aff *res; + int op = 1; + int sign = 1; + + ls = isl_local_space_from_space(isl_space_copy(space)); + res = isl_pw_aff_from_aff(isl_aff_zero_on_domain(ls)); + if (!res) + goto error; + + for (;;) { + tok = next_token(s); + if (!tok) { + isl_stream_error(s, NULL, "unexpected EOF"); + goto error; + } + if (tok->type == '-') { + sign = -sign; + isl_token_free(tok); + continue; + } + if (tok->type == '(' || is_start_of_div(tok) || + tok->type == ISL_TOKEN_MIN || tok->type == ISL_TOKEN_MAX || + tok->type == ISL_TOKEN_IDENT || + tok->type == ISL_TOKEN_VALUE || + tok->type == ISL_TOKEN_AFF) { + isl_pw_aff *term; + if (tok->type == ISL_TOKEN_VALUE && sign < 0) { + isl_int_neg(tok->u.v, tok->u.v); + sign = 1; + } + isl_stream_push_token(s, tok); + tok = NULL; + term = accept_affine_factor(s, + isl_space_copy(space), v); + if (op * sign < 0) + res = isl_pw_aff_sub(res, term); + else + res = isl_pw_aff_add(res, term); + if (!res) + goto error; + } else if (tok->type == ISL_TOKEN_NAN) { + res = isl_pw_aff_add(res, nan_on_domain(space)); + } else { + isl_stream_error(s, tok, "unexpected isl_token"); + isl_stream_push_token(s, tok); + isl_pw_aff_free(res); + isl_space_free(space); + return NULL; + } + isl_token_free(tok); + + tok = next_token(s); + sign = 1; + if (tok && tok->type == '-') { + op = -1; + isl_token_free(tok); + } else if (tok && tok->type == '+') { + op = 1; + isl_token_free(tok); + } else { + if (tok) + isl_stream_push_token(s, tok); + break; + } + } + + isl_space_free(space); + return res; +error: + isl_space_free(space); + isl_token_free(tok); + isl_pw_aff_free(res); + return NULL; +} + +/* Is "type" the type of a comparison operator between lists + * of affine expressions? + */ +static int is_list_comparator_type(int type) +{ + switch (type) { + case ISL_TOKEN_LEX_LT: + case ISL_TOKEN_LEX_GT: + case ISL_TOKEN_LEX_LE: + case ISL_TOKEN_LEX_GE: + return 1; + default: + return 0; + } +} + +static int is_comparator(struct isl_token *tok) +{ + if (!tok) + return 0; + if (is_list_comparator_type(tok->type)) + return 1; + + switch (tok->type) { + case ISL_TOKEN_LT: + case ISL_TOKEN_GT: + case ISL_TOKEN_LE: + case ISL_TOKEN_GE: + case ISL_TOKEN_NE: + case '=': + return 1; + default: + return 0; + } +} + +static __isl_give isl_map *read_formula(__isl_keep isl_stream *s, + struct vars *v, __isl_take isl_map *map, int rational); +static __isl_give isl_pw_aff *accept_extended_affine(__isl_keep isl_stream *s, + __isl_take isl_space *space, struct vars *v, int rational); + +/* Accept a ternary operator, given the first argument. + */ +static __isl_give isl_pw_aff *accept_ternary(__isl_keep isl_stream *s, + __isl_take isl_map *cond, struct vars *v, int rational) +{ + isl_space *space; + isl_pw_aff *pwaff1 = NULL, *pwaff2 = NULL, *pa_cond; + + if (!cond) + return NULL; + + if (isl_stream_eat(s, '?')) + goto error; + + space = isl_space_wrap(isl_map_get_space(cond)); + pwaff1 = accept_extended_affine(s, space, v, rational); + if (!pwaff1) + goto error; + + if (isl_stream_eat(s, ':')) + goto error; + + space = isl_pw_aff_get_domain_space(pwaff1); + pwaff2 = accept_extended_affine(s, space, v, rational); + if (!pwaff2) + goto error; + + pa_cond = isl_set_indicator_function(isl_map_wrap(cond)); + return isl_pw_aff_cond(pa_cond, pwaff1, pwaff2); +error: + isl_map_free(cond); + isl_pw_aff_free(pwaff1); + isl_pw_aff_free(pwaff2); + return NULL; +} + +/* Set *line and *col to those of the next token, if any. + */ +static void set_current_line_col(__isl_keep isl_stream *s, int *line, int *col) +{ + struct isl_token *tok; + + tok = isl_stream_next_token(s); + if (!tok) + return; + + *line = tok->line; + *col = tok->col; + isl_stream_push_token(s, tok); +} + +/* Push a token encapsulating "pa" onto "s", with the given + * line and column. + */ +static isl_stat push_aff(__isl_keep isl_stream *s, int line, int col, + __isl_take isl_pw_aff *pa) +{ + struct isl_token *tok; + + tok = isl_token_new(s->ctx, line, col, 0); + if (!tok) + goto error; + tok->type = ISL_TOKEN_AFF; + tok->u.pwaff = pa; + isl_stream_push_token(s, tok); + + return isl_stat_ok; +error: + isl_pw_aff_free(pa); + return isl_stat_error; +} + +/* Is the next token a comparison operator? + */ +static int next_is_comparator(__isl_keep isl_stream *s) +{ + int is_comp; + struct isl_token *tok; + + tok = isl_stream_next_token(s); + if (!tok) + return 0; + + is_comp = is_comparator(tok); + isl_stream_push_token(s, tok); + + return is_comp; +} + +/* Accept an affine expression that may involve ternary operators. + * We first read an affine expression. + * If it is not followed by a comparison operator, we simply return it. + * Otherwise, we assume the affine expression is part of the first + * argument of a ternary operator and try to parse that. + */ +static __isl_give isl_pw_aff *accept_extended_affine(__isl_keep isl_stream *s, + __isl_take isl_space *space, struct vars *v, int rational) +{ + isl_map *cond; + isl_pw_aff *pwaff; + int line = -1, col = -1; + + set_current_line_col(s, &line, &col); + + pwaff = accept_affine(s, space, v); + if (rational) + pwaff = isl_pw_aff_set_rational(pwaff); + if (!pwaff) + return NULL; + if (!next_is_comparator(s)) + return pwaff; + + space = isl_pw_aff_get_domain_space(pwaff); + cond = isl_map_universe(isl_space_unwrap(space)); + + if (push_aff(s, line, col, pwaff) < 0) + cond = isl_map_free(cond); + if (!cond) + return NULL; + + cond = read_formula(s, v, cond, rational); + + return accept_ternary(s, cond, v, rational); +} + +static __isl_give isl_map *read_var_def(__isl_keep isl_stream *s, + __isl_take isl_map *map, enum isl_dim_type type, struct vars *v, + int rational) +{ + isl_pw_aff *def; + isl_size pos; + isl_map *def_map; + + if (type == isl_dim_param) + pos = isl_map_dim(map, isl_dim_param); + else { + pos = isl_map_dim(map, isl_dim_in); + if (type == isl_dim_out) { + isl_size n_out = isl_map_dim(map, isl_dim_out); + if (pos < 0 || n_out < 0) + return isl_map_free(map); + pos += n_out; + } + type = isl_dim_in; + } + if (pos < 0) + return isl_map_free(map); + --pos; + + def = accept_extended_affine(s, isl_space_wrap(isl_map_get_space(map)), + v, rational); + def_map = isl_map_from_pw_aff(def); + def_map = isl_map_equate(def_map, type, pos, isl_dim_out, 0); + def_map = isl_set_unwrap(isl_map_domain(def_map)); + + map = isl_map_intersect(map, def_map); + + return map; +} + +static __isl_give isl_pw_aff_list *accept_affine_list(__isl_keep isl_stream *s, + __isl_take isl_space *space, struct vars *v) +{ + isl_pw_aff *pwaff; + isl_pw_aff_list *list; + struct isl_token *tok = NULL; + + pwaff = accept_affine(s, isl_space_copy(space), v); + list = isl_pw_aff_list_from_pw_aff(pwaff); + if (!list) + goto error; + + for (;;) { + tok = isl_stream_next_token(s); + if (!tok) { + isl_stream_error(s, NULL, "unexpected EOF"); + goto error; + } + if (tok->type != ',') { + isl_stream_push_token(s, tok); + break; + } + isl_token_free(tok); + + pwaff = accept_affine(s, isl_space_copy(space), v); + list = isl_pw_aff_list_concat(list, + isl_pw_aff_list_from_pw_aff(pwaff)); + if (!list) + goto error; + } + + isl_space_free(space); + return list; +error: + isl_space_free(space); + isl_pw_aff_list_free(list); + return NULL; +} + +static __isl_give isl_map *read_defined_var_list(__isl_keep isl_stream *s, + struct vars *v, __isl_take isl_map *map, int rational) +{ + struct isl_token *tok; + + while ((tok = isl_stream_next_token(s)) != NULL) { + int p; + int n = v->n; + + if (tok->type != ISL_TOKEN_IDENT) + break; + + p = vars_pos(v, tok->u.s, -1); + if (p < 0) + goto error; + if (p < n) { + isl_stream_error(s, tok, "expecting unique identifier"); + goto error; + } + + map = isl_map_add_dims(map, isl_dim_out, 1); + + isl_token_free(tok); + tok = isl_stream_next_token(s); + if (tok && tok->type == '=') { + isl_token_free(tok); + map = read_var_def(s, map, isl_dim_out, v, rational); + tok = isl_stream_next_token(s); + } + + if (!tok || tok->type != ',') + break; + + isl_token_free(tok); + } + if (tok) + isl_stream_push_token(s, tok); + + return map; +error: + isl_token_free(tok); + isl_map_free(map); + return NULL; +} + +static int next_is_tuple(__isl_keep isl_stream *s) +{ + struct isl_token *tok; + int is_tuple; + + tok = isl_stream_next_token(s); + if (!tok) + return 0; + if (tok->type == '[') { + isl_stream_push_token(s, tok); + return 1; + } + if (tok->type != ISL_TOKEN_IDENT && !tok->is_keyword) { + isl_stream_push_token(s, tok); + return 0; + } + + is_tuple = isl_stream_next_token_is(s, '['); + + isl_stream_push_token(s, tok); + + return is_tuple; +} + +/* Does the next token mark the end of a tuple element? + */ +static int next_is_end_tuple_element(__isl_keep isl_stream *s) +{ + return isl_stream_next_token_is(s, ',') || + isl_stream_next_token_is(s, ']'); +} + +/* Is the next token one that necessarily forms the start of a condition? + */ +static int next_is_condition_start(__isl_keep isl_stream *s) +{ + return isl_stream_next_token_is(s, ISL_TOKEN_EXISTS) || + isl_stream_next_token_is(s, ISL_TOKEN_NOT) || + isl_stream_next_token_is(s, ISL_TOKEN_TRUE) || + isl_stream_next_token_is(s, ISL_TOKEN_FALSE) || + isl_stream_next_token_is(s, ISL_TOKEN_MAP); +} + +/* Is "pa" an expression in term of earlier dimensions? + * The alternative is that the dimension is defined to be equal to itself, + * meaning that it has a universe domain and an expression that depends + * on itself. "i" is the position of the expression in a sequence + * of "n" expressions. The final dimensions of "pa" correspond to + * these "n" expressions. + */ +static isl_bool pw_aff_is_expr(__isl_keep isl_pw_aff *pa, int i, int n) +{ + isl_aff *aff; + + if (!pa) + return isl_bool_error; + if (pa->n != 1) + return isl_bool_true; + if (!isl_set_plain_is_universe(pa->p[0].set)) + return isl_bool_true; + + aff = pa->p[0].aff; + if (isl_int_is_zero(aff->v->el[aff->v->size - n + i])) + return isl_bool_true; + return isl_bool_false; +} + +/* Does the tuple contain any dimensions that are defined + * in terms of earlier dimensions? + */ +static isl_bool tuple_has_expr(__isl_keep isl_multi_pw_aff *tuple) +{ + int i; + isl_size n; + isl_bool has_expr = isl_bool_false; + isl_pw_aff *pa; + + n = isl_multi_pw_aff_dim(tuple, isl_dim_out); + if (n < 0) + return isl_bool_error; + for (i = 0; i < n; ++i) { + pa = isl_multi_pw_aff_get_pw_aff(tuple, i); + has_expr = pw_aff_is_expr(pa, i, n); + isl_pw_aff_free(pa); + if (has_expr < 0 || has_expr) + break; + } + + return has_expr; +} + +/* Set the name of dimension "pos" in "space" to "name". + * During printing, we add primes if the same name appears more than once + * to distinguish the occurrences. Here, we remove those primes from "name" + * before setting the name of the dimension. + */ +static __isl_give isl_space *space_set_dim_name(__isl_take isl_space *space, + int pos, char *name) +{ + char *prime; + + if (!name) + return space; + + prime = strchr(name, '\''); + if (prime) + *prime = '\0'; + space = isl_space_set_dim_name(space, isl_dim_out, pos, name); + if (prime) + *prime = '\''; + + return space; +} + +/* Set the name of the last (output) dimension of "space" to "name", + * ignoring any primes in "name". + */ +static __isl_give isl_space *space_set_last_dim_name( + __isl_take isl_space *space, char *name) +{ + isl_size pos; + + pos = isl_space_dim(space, isl_dim_out); + if (pos < 0) + return isl_space_free(space); + return space_set_dim_name(space, pos - 1, name); +} + +/* Construct an isl_pw_aff defined on a "space" (with v->n variables) + * that is equal to the last of those variables. + */ +static __isl_give isl_pw_aff *identity_tuple_el_on_space( + __isl_take isl_space *space, struct vars *v) +{ + isl_aff *aff; + + aff = isl_aff_zero_on_domain(isl_local_space_from_space(space)); + aff = isl_aff_add_coefficient_si(aff, isl_dim_in, v->n - 1, 1); + return isl_pw_aff_from_aff(aff); +} + +/* Construct an isl_pw_aff defined on the domain space of "pa" + * that is equal to the last variable in "v". + * + * That is, if D is the domain space of "pa", then construct + * + * D[..., i] -> i. + */ +static __isl_give isl_pw_aff *init_range(__isl_keep isl_pw_aff *pa, + struct vars *v) +{ + isl_space *space; + + space = isl_pw_aff_get_domain_space(pa); + return identity_tuple_el_on_space(space, v); +} + +/* Impose the lower bound "lower" on the variable represented by "range_pa". + * + * In particular, "range_pa" is of the form + * + * D[..., i] -> i : C + * + * with D also the domains space of "lower' and "C" some constraints. + * + * Return the expression + * + * D[..., i] -> i : C and i >= lower + */ +static __isl_give isl_pw_aff *set_lower(__isl_take isl_pw_aff *range_pa, + __isl_take isl_pw_aff *lower) +{ + isl_set *range; + + range = isl_pw_aff_ge_set(isl_pw_aff_copy(range_pa), lower); + return isl_pw_aff_intersect_domain(range_pa, range); +} + +/* Impose the upper bound "upper" on the variable represented by "range_pa". + * + * In particular, "range_pa" is of the form + * + * D[..., i] -> i : C + * + * with D also the domains space of "upper' and "C" some constraints. + * + * Return the expression + * + * D[..., i] -> i : C and i <= upper + */ +static __isl_give isl_pw_aff *set_upper(__isl_take isl_pw_aff *range_pa, + __isl_take isl_pw_aff *upper) +{ + isl_set *range; + + range = isl_pw_aff_le_set(isl_pw_aff_copy(range_pa), upper); + return isl_pw_aff_intersect_domain(range_pa, range); +} + +/* Construct a piecewise affine expression corresponding + * to the last variable in "v" that is greater than or equal to "pa". + * + * In particular, if D is the domain space of "pa", + * then construct the expression + * + * D[..., i] -> i, + * + * impose lower bound "pa" and return + * + * D[..., i] -> i : i >= pa + */ +static __isl_give isl_pw_aff *construct_lower(__isl_take isl_pw_aff *pa, + struct vars *v) +{ + return set_lower(init_range(pa, v), pa); +} + +/* Construct a piecewise affine expression corresponding + * to the last variable in "v" that is smaller than or equal to "pa". + * + * In particular, if D is the domain space of "pa", + * then construct the expression + * + * D[..., i] -> i, + * + * impose lower bound "pa" and return + * + * D[..., i] -> i : i <= pa + */ +static __isl_give isl_pw_aff *construct_upper(__isl_take isl_pw_aff *pa, + struct vars *v) +{ + return set_upper(init_range(pa, v), pa); +} + +/* Construct a piecewise affine expression corresponding + * to the last variable in "v" that ranges between "pa" and "pa2". + * + * In particular, if D is the domain space of "pa" (and "pa2"), + * then construct the expression + * + * D[..., i] -> i, + * + * impose lower bound "pa" and upper bound "pa2" and return + * + * D[..., i] -> i : pa <= i <= pa2 + */ +static __isl_give isl_pw_aff *construct_range(__isl_take isl_pw_aff *pa, + __isl_take isl_pw_aff *pa2, struct vars *v) +{ + return set_upper(set_lower(init_range(pa, v), pa), pa2); +} + +static int resolve_paren_expr(__isl_keep isl_stream *s, + struct vars *v, __isl_take isl_map *map, int rational); + +/* Given that the (piecewise) affine expression "pa" + * has just been parsed, followed by a colon, + * continue parsing as part of a piecewise affine expression. + * + * In particular, check if the colon is followed by a condition. + * If so, parse the conditions(a) on "pa" and include them in the domain. + * Otherwise, if the colon is followed by another (piecewise) affine expression + * then consider the two expressions as endpoints of a range of values and + * return a piecewise affine expression that takes values in that range. + * Note that an affine expression followed by a comparison operator + * is considered to be part of a condition. + * If the colon is not followed by anything (inside the tuple element), + * then consider "pa" as a lower bound on a range of values without upper bound + * and return a piecewise affine expression that takes values in that range. + */ +static __isl_give isl_pw_aff *update_piecewise_affine_colon( + __isl_take isl_pw_aff *pa, __isl_keep isl_stream *s, + struct vars *v, int rational) +{ + isl_space *dom_space; + isl_map *map; + + dom_space = isl_pw_aff_get_domain_space(pa); + map = isl_map_universe(isl_space_from_domain(dom_space)); + + if (isl_stream_next_token_is(s, '(')) + if (resolve_paren_expr(s, v, isl_map_copy(map), rational)) + goto error; + if (next_is_end_tuple_element(s)) { + isl_map_free(map); + return construct_lower(pa, v); + } + if (!next_is_condition_start(s)) { + int line = -1, col = -1; + isl_space *space; + isl_pw_aff *pa2; + + set_current_line_col(s, &line, &col); + space = isl_space_wrap(isl_map_get_space(map)); + pa2 = accept_affine(s, space, v); + if (rational) + pa2 = isl_pw_aff_set_rational(pa2); + if (!next_is_comparator(s)) { + isl_map_free(map); + pa2 = isl_pw_aff_domain_factor_domain(pa2); + return construct_range(pa, pa2, v); + } + if (push_aff(s, line, col, pa2) < 0) + goto error; + } + + map = read_formula(s, v, map, rational); + pa = isl_pw_aff_intersect_domain(pa, isl_map_domain(map)); + + return pa; +error: + isl_map_free(map); + isl_pw_aff_free(pa); + return NULL; +} + +/* Accept a piecewise affine expression. + * + * At the outer level, the piecewise affine expression may be of the form + * + * aff1 : condition1; aff2 : conditions2; ... + * + * or one of + * + * aff : + * aff1 : aff2 + * : aff + * : + * + * or simply + * + * aff + * + * each of the affine expressions may in turn include ternary operators. + * + * If the first token is a colon, then the expression must be + * ":" or ": aff2", depending on whether anything follows the colon + * inside the tuple element. + * The first is considered to represent an arbitrary value. + * The second is considered to represent a range of values + * with the given upper bound and no lower bound. + * + * There may be parentheses around some subexpression of "aff1" + * around "aff1" itself, around "aff1 : condition1" and/or + * around the entire piecewise affine expression. + * We therefore remove the opening parenthesis (if any) from the stream + * in case the closing parenthesis follows the colon, but if the closing + * parenthesis is the first thing in the stream after the parsed affine + * expression, we push the parsed expression onto the stream and parse + * again in case the parentheses enclose some subexpression of "aff1". + */ +static __isl_give isl_pw_aff *accept_piecewise_affine(__isl_keep isl_stream *s, + __isl_take isl_space *space, struct vars *v, int rational) +{ + isl_pw_aff *res; + isl_space *res_space; + + if (isl_stream_eat_if_available(s, ':')) { + if (next_is_end_tuple_element(s)) + return identity_tuple_el_on_space(space, v); + else + return construct_upper(accept_affine(s, space, v), v); + } + + res_space = isl_space_from_domain(isl_space_copy(space)); + res_space = isl_space_add_dims(res_space, isl_dim_out, 1); + res = isl_pw_aff_empty(res_space); + do { + isl_pw_aff *pa; + int seen_paren; + int line = -1, col = -1; + + set_current_line_col(s, &line, &col); + seen_paren = isl_stream_eat_if_available(s, '('); + if (seen_paren) + pa = accept_piecewise_affine(s, isl_space_copy(space), + v, rational); + else + pa = accept_extended_affine(s, isl_space_copy(space), + v, rational); + if (seen_paren && isl_stream_eat_if_available(s, ')')) { + seen_paren = 0; + if (push_aff(s, line, col, pa) < 0) + goto error; + pa = accept_extended_affine(s, isl_space_copy(space), + v, rational); + } + if (pa && isl_stream_eat_if_available(s, ':')) + pa = update_piecewise_affine_colon(pa, s, v, rational); + + res = isl_pw_aff_union_add(res, pa); + + if (!res || (seen_paren && isl_stream_eat(s, ')'))) + goto error; + } while (isl_stream_eat_if_available(s, ';')); + + isl_space_free(space); + + return res; +error: + isl_space_free(space); + return isl_pw_aff_free(res); +} + +/* Read an affine expression from "s" for use in read_tuple. + * + * accept_extended_affine requires a wrapped space as input. + * read_tuple on the other hand expects each isl_pw_aff + * to have an anonymous space. We therefore adjust the space + * of the isl_pw_aff before returning it. + */ +static __isl_give isl_pw_aff *read_tuple_var_def(__isl_keep isl_stream *s, + struct vars *v, int rational) +{ + isl_space *space; + isl_pw_aff *def; + + space = isl_space_wrap(isl_space_alloc(s->ctx, 0, v->n, 0)); + + def = accept_piecewise_affine(s, space, v, rational); + def = isl_pw_aff_domain_factor_domain(def); + + return def; +} + +/* Read a list of tuple elements by calling "read_el" on each of them and + * return a space with the same number of set dimensions derived from + * the parameter space "space" and possibly updated by "read_el". + * The elements in the list are separated by either "," or "][". + * If "comma" is set then only "," is allowed. + */ +static __isl_give isl_space *read_tuple_list(__isl_keep isl_stream *s, + struct vars *v, __isl_take isl_space *space, int rational, int comma, + __isl_give isl_space *(*read_el)(__isl_keep isl_stream *s, + struct vars *v, __isl_take isl_space *space, int rational, + void *user), + void *user) +{ + if (!space) + return NULL; + + space = isl_space_set_from_params(space); + + if (isl_stream_next_token_is(s, ']')) + return space; + + for (;;) { + struct isl_token *tok; + + space = isl_space_add_dims(space, isl_dim_set, 1); + + space = read_el(s, v, space, rational, user); + if (!space) + return NULL; + + tok = isl_stream_next_token(s); + if (!comma && tok && tok->type == ']' && + isl_stream_next_token_is(s, '[')) { + isl_token_free(tok); + tok = isl_stream_next_token(s); + } else if (!tok || tok->type != ',') { + if (tok) + isl_stream_push_token(s, tok); + break; + } + + isl_token_free(tok); + } + + return space; +} + +/* Read a tuple space from "s" derived from the parameter space "space". + * Call "read_el" on each element in the tuples. + */ +static __isl_give isl_space *read_tuple_space(__isl_keep isl_stream *s, + struct vars *v, __isl_take isl_space *space, int rational, int comma, + __isl_give isl_space *(*read_el)(__isl_keep isl_stream *s, + struct vars *v, __isl_take isl_space *space, int rational, + void *user), + void *user) +{ + struct isl_token *tok; + char *name = NULL; + isl_space *res = NULL; + + tok = isl_stream_next_token(s); + if (!tok) + goto error; + if (tok->type == ISL_TOKEN_IDENT || tok->is_keyword) { + name = strdup(tok->u.s); + isl_token_free(tok); + if (!name) + goto error; + } else + isl_stream_push_token(s, tok); + if (isl_stream_eat(s, '[')) + goto error; + if (next_is_tuple(s)) { + isl_space *out; + res = read_tuple_space(s, v, isl_space_copy(space), + rational, comma, read_el, user); + if (isl_stream_eat(s, ISL_TOKEN_TO)) + goto error; + out = read_tuple_space(s, v, isl_space_copy(space), + rational, comma, read_el, user); + res = isl_space_product(res, out); + } else + res = read_tuple_list(s, v, isl_space_copy(space), + rational, comma, read_el, user); + if (!res || isl_stream_eat(s, ']')) + goto error; + + if (name) { + res = isl_space_set_tuple_name(res, isl_dim_set, name); + free(name); + } + + isl_space_free(space); + return res; +error: + free(name); + isl_space_free(res); + isl_space_free(space); + return NULL; +} + +/* Construct an isl_pw_aff defined on a space with v->n variables + * that is equal to the last of those variables. + */ +static __isl_give isl_pw_aff *identity_tuple_el(struct vars *v) +{ + isl_space *space; + + space = isl_space_set_alloc(v->ctx, 0, v->n); + return identity_tuple_el_on_space(space, v); +} + +/* This function is called for each element in a tuple inside read_tuple. + * Add a new variable to "v" and construct a corresponding isl_pw_aff defined + * over a space containing all variables in "v" defined so far. + * The isl_pw_aff expresses the new variable in terms of earlier variables + * if a definition is provided. Otherwise, it is represented as being + * equal to itself. + * Add the isl_pw_aff to *list. + * If the new variable was named, then adjust "space" accordingly and + * return the updated space. + */ +static __isl_give isl_space *read_tuple_pw_aff_el(__isl_keep isl_stream *s, + struct vars *v, __isl_take isl_space *space, int rational, void *user) +{ + isl_pw_aff_list **list = (isl_pw_aff_list **) user; + isl_pw_aff *pa; + struct isl_token *tok; + int new_name = 0; + + tok = next_token(s); + if (!tok) { + isl_stream_error(s, NULL, "unexpected EOF"); + return isl_space_free(space); + } + + if (tok->type == ISL_TOKEN_IDENT) { + int n = v->n; + int p = vars_pos(v, tok->u.s, -1); + if (p < 0) + goto error; + new_name = p >= n; + } + + if (tok->type == '*') { + if (vars_add_anon(v) < 0) + goto error; + isl_token_free(tok); + pa = identity_tuple_el(v); + } else if (new_name) { + space = space_set_last_dim_name(space, v->v->name); + isl_token_free(tok); + if (isl_stream_eat_if_available(s, '=')) + pa = read_tuple_var_def(s, v, rational); + else + pa = identity_tuple_el(v); + } else { + isl_stream_push_token(s, tok); + tok = NULL; + if (vars_add_anon(v) < 0) + goto error; + pa = read_tuple_var_def(s, v, rational); + } + + *list = isl_pw_aff_list_add(*list, pa); + if (!*list) + return isl_space_free(space); + + return space; +error: + isl_token_free(tok); + return isl_space_free(space); +} + +/* Read a tuple and represent it as an isl_multi_pw_aff. + * The range space of the isl_multi_pw_aff is the space of the tuple. + * The domain space is an anonymous space + * with a dimension for each variable in the set of variables in "v", + * including the variables in the range. + * If a given dimension is not defined in terms of earlier dimensions in + * the input, then the corresponding isl_pw_aff is set equal to one time + * the variable corresponding to the dimension being defined. + * + * The elements in the tuple are collected in a list by read_tuple_pw_aff_el. + * Each element in this list is defined over a space representing + * the variables defined so far. We need to adjust the earlier + * elements to have as many variables in the domain as the final + * element in the list. + */ +static __isl_give isl_multi_pw_aff *read_tuple(__isl_keep isl_stream *s, + struct vars *v, int rational, int comma) +{ + int i; + isl_size n; + isl_space *space; + isl_pw_aff_list *list; + + space = isl_space_params_alloc(v->ctx, 0); + list = isl_pw_aff_list_alloc(s->ctx, 0); + space = read_tuple_space(s, v, space, rational, comma, + &read_tuple_pw_aff_el, &list); + n = isl_space_dim(space, isl_dim_set); + if (n < 0) + space = isl_space_free(space); + for (i = 0; i + 1 < n; ++i) { + isl_pw_aff *pa; + + pa = isl_pw_aff_list_get_pw_aff(list, i); + pa = isl_pw_aff_add_dims(pa, isl_dim_in, n - (i + 1)); + list = isl_pw_aff_list_set_pw_aff(list, i, pa); + } + + space = isl_space_from_range(space); + space = isl_space_add_dims(space, isl_dim_in, v->n); + return isl_multi_pw_aff_from_pw_aff_list(space, list); +} + +/* Add the tuple represented by the isl_multi_pw_aff "tuple" to "map". + * We first create the appropriate space in "map" based on the range + * space of this isl_multi_pw_aff. Then, we add equalities based + * on the affine expressions. These live in an anonymous space, + * however, so we first need to reset the space to that of "map". + */ +static __isl_give isl_map *map_from_tuple(__isl_take isl_multi_pw_aff *tuple, + __isl_take isl_map *map, enum isl_dim_type type, struct vars *v, + int rational) +{ + int i; + isl_size n; + isl_ctx *ctx; + isl_space *space = NULL; + + n = isl_multi_pw_aff_dim(tuple, isl_dim_out); + if (!map || n < 0) + goto error; + ctx = isl_multi_pw_aff_get_ctx(tuple); + space = isl_space_range(isl_multi_pw_aff_get_space(tuple)); + if (!space) + goto error; + + if (type == isl_dim_param) { + if (isl_space_has_tuple_name(space, isl_dim_set) || + isl_space_is_wrapping(space)) { + isl_die(ctx, isl_error_invalid, + "parameter tuples cannot be named or nested", + goto error); + } + map = isl_map_add_dims(map, type, n); + for (i = 0; i < n; ++i) { + isl_id *id; + if (!isl_space_has_dim_name(space, isl_dim_set, i)) + isl_die(ctx, isl_error_invalid, + "parameters must be named", + goto error); + id = isl_space_get_dim_id(space, isl_dim_set, i); + map = isl_map_set_dim_id(map, isl_dim_param, i, id); + } + } else if (type == isl_dim_in) { + isl_set *set; + + set = isl_set_universe(isl_space_copy(space)); + if (rational) + set = isl_set_set_rational(set); + set = isl_set_intersect_params(set, isl_map_params(map)); + map = isl_map_from_domain(set); + } else { + isl_set *set; + + set = isl_set_universe(isl_space_copy(space)); + if (rational) + set = isl_set_set_rational(set); + map = isl_map_from_domain_and_range(isl_map_domain(map), set); + } + + for (i = 0; i < n; ++i) { + isl_pw_aff *pa; + isl_space *space; + isl_aff *aff; + isl_set *set; + isl_map *map_i; + + pa = isl_multi_pw_aff_get_pw_aff(tuple, i); + space = isl_pw_aff_get_domain_space(pa); + aff = isl_aff_zero_on_domain(isl_local_space_from_space(space)); + aff = isl_aff_add_coefficient_si(aff, + isl_dim_in, v->n - n + i, -1); + pa = isl_pw_aff_add(pa, isl_pw_aff_from_aff(aff)); + if (rational) + pa = isl_pw_aff_set_rational(pa); + set = isl_pw_aff_zero_set(pa); + map_i = isl_map_from_range(set); + map_i = isl_map_reset_space(map_i, isl_map_get_space(map)); + map = isl_map_intersect(map, map_i); + } + + isl_space_free(space); + isl_multi_pw_aff_free(tuple); + return map; +error: + isl_space_free(space); + isl_multi_pw_aff_free(tuple); + isl_map_free(map); + return NULL; +} + +/* Read a tuple from "s" and add it to "map". + * The tuple is initially represented as an isl_multi_pw_aff and + * then added to "map". + */ +static __isl_give isl_map *read_map_tuple(__isl_keep isl_stream *s, + __isl_take isl_map *map, enum isl_dim_type type, struct vars *v, + int comma) +{ + isl_bool rational; + isl_multi_pw_aff *tuple; + + rational = isl_map_is_rational(map); + if (rational < 0) + return isl_map_free(map); + tuple = read_tuple(s, v, rational, comma); + if (!tuple) + return isl_map_free(map); + + return map_from_tuple(tuple, map, type, v, rational); +} + +/* Read the parameter domain of an expression from "s" (if any) and + * check that it does not involve any constraints. + * "v" contains a description of the identifiers parsed so far + * (of which there should not be any at this point) and is extended + * by this function. + */ +static __isl_give isl_set *read_universe_params(__isl_keep isl_stream *s, + struct vars *v) +{ + isl_set *dom; + + dom = isl_set_universe(isl_space_params_alloc(s->ctx, 0)); + if (next_is_tuple(s)) { + dom = read_map_tuple(s, dom, isl_dim_param, v, 0); + if (isl_stream_eat(s, ISL_TOKEN_TO)) + return isl_set_free(dom); + } + if (!isl_set_plain_is_universe(dom)) + isl_die(s->ctx, isl_error_invalid, + "expecting universe parameter domain", + return isl_set_free(dom)); + + return dom; +} + +/* Read the parameter domain of an expression from "s" (if any), + * check that it does not involve any constraints and return its space. + * "v" contains a description of the identifiers parsed so far + * (of which there should not be any at this point) and is extended + * by this function. + */ +static __isl_give isl_space *read_params(__isl_keep isl_stream *s, + struct vars *v) +{ + isl_space *space; + isl_set *set; + + set = read_universe_params(s, v); + space = isl_set_get_space(set); + isl_set_free(set); + + return space; +} + +/* This function is called for each element in a tuple inside read_space_tuples. + * Add a new variable to "v" and adjust "space" accordingly + * if the variable has a name. + */ +static __isl_give isl_space *read_tuple_id(__isl_keep isl_stream *s, + struct vars *v, __isl_take isl_space *space, int rational, void *user) +{ + struct isl_token *tok; + + tok = next_token(s); + if (!tok) { + isl_stream_error(s, NULL, "unexpected EOF"); + return isl_space_free(space); + } + + if (tok->type == ISL_TOKEN_IDENT) { + int n = v->n; + int p = vars_pos(v, tok->u.s, -1); + if (p < 0) + goto error; + if (p < n) { + isl_stream_error(s, tok, "expecting fresh identifier"); + goto error; + } + space = space_set_last_dim_name(space, v->v->name); + } else if (tok->type == '*') { + if (vars_add_anon(v) < 0) + goto error; + } else { + isl_stream_error(s, tok, "expecting identifier or '*'"); + goto error; + } + + isl_token_free(tok); + return space; +error: + isl_token_free(tok); + return isl_space_free(space); +} + +/* Given a parameter space "params", extend it with one or two tuples + * read from "s". + * "v" contains a description of the identifiers parsed so far and is extended + * by this function. + */ +static __isl_give isl_space *read_space_tuples(__isl_keep isl_stream *s, + struct vars *v, __isl_take isl_space *params) +{ + isl_space *space, *ran; + + space = read_tuple_space(s, v, isl_space_copy(params), 1, 1, + &read_tuple_id, NULL); + if (isl_stream_eat_if_available(s, ISL_TOKEN_TO)) { + ran = read_tuple_space(s, v, isl_space_copy(params), 1, 1, + &read_tuple_id, NULL); + space = isl_space_unwrap(isl_space_product(space, ran)); + } + isl_space_free(params); + + return space; +} + +/* Read an isl_space object from "s". + * + * First read the parameters (if any). + * + * Then check if the description is of the special form "{ : }", + * in which case it represents a parameter space. + * Otherwise, it has one or two tuples. + */ +__isl_give isl_space *isl_stream_read_space(__isl_keep isl_stream *s) +{ + struct vars *v; + isl_space *space; + + v = vars_new(s->ctx); + if (!v) + return NULL; + space = read_params(s, v); + + if (isl_stream_eat(s, '{')) + goto error; + + if (!isl_stream_eat_if_available(s, ':')) + space = read_space_tuples(s, v, space); + + if (isl_stream_eat(s, '}')) + goto error; + + vars_free(v); + return space; +error: + vars_free(v); + isl_space_free(space); + return NULL; +} + +#undef TYPE_BASE +#define TYPE_BASE space +#include "isl_read_from_str_templ.c" + +/* Given two equal-length lists of piecewise affine expression with the space + * of "set" as domain, construct a set in the same space that expresses + * that "left" and "right" satisfy the comparison "type". + * + * A space is constructed of the same dimension as the number of elements + * in the two lists. The comparison is then expressed in a map from + * this space to itself and wrapped into a set. Finally the two lists + * of piecewise affine expressions are plugged into this set. + * + * Let S be the space of "set" and T the constructed space. + * The lists are first changed into two isl_multi_pw_affs in S -> T and + * then combined into an isl_multi_pw_aff in S -> [T -> T], + * while the comparison is first expressed in T -> T, then [T -> T] + * and finally in S. + */ +static __isl_give isl_set *list_cmp(__isl_keep isl_set *set, int type, + __isl_take isl_pw_aff_list *left, __isl_take isl_pw_aff_list *right) +{ + isl_space *space; + isl_size n; + isl_multi_pw_aff *mpa1, *mpa2; + + n = isl_pw_aff_list_n_pw_aff(left); + if (!set || n < 0 || !right) + goto error; + + space = isl_set_get_space(set); + space = isl_space_from_domain(space); + space = isl_space_add_dims(space, isl_dim_out, n); + mpa1 = isl_multi_pw_aff_from_pw_aff_list(isl_space_copy(space), left); + mpa2 = isl_multi_pw_aff_from_pw_aff_list(isl_space_copy(space), right); + mpa1 = isl_multi_pw_aff_range_product(mpa1, mpa2); + + space = isl_space_range(space); + switch (type) { + case ISL_TOKEN_LEX_LT: + set = isl_map_wrap(isl_map_lex_lt(space)); + break; + case ISL_TOKEN_LEX_GT: + set = isl_map_wrap(isl_map_lex_gt(space)); + break; + case ISL_TOKEN_LEX_LE: + set = isl_map_wrap(isl_map_lex_le(space)); + break; + case ISL_TOKEN_LEX_GE: + set = isl_map_wrap(isl_map_lex_ge(space)); + break; + default: + isl_multi_pw_aff_free(mpa1); + isl_space_free(space); + isl_die(isl_set_get_ctx(set), isl_error_internal, + "unhandled list comparison type", return NULL); + } + set = isl_set_preimage_multi_pw_aff(set, mpa1); + return set; +error: + isl_pw_aff_list_free(left); + isl_pw_aff_list_free(right); + return NULL; +} + +/* Construct constraints of the form + * + * a op b + * + * where a is an element in "left", op is an operator of type "type" and + * b is an element in "right", add the constraints to "set" and return + * the result. + * "rational" is set if the constraints should be treated as + * a rational constraints. + * + * If "type" is the type of a comparison operator between lists + * of affine expressions, then a single (compound) constraint + * is constructed by list_cmp instead. + */ +static __isl_give isl_set *construct_constraints( + __isl_take isl_set *set, int type, + __isl_keep isl_pw_aff_list *left, __isl_keep isl_pw_aff_list *right, + int rational) +{ + isl_set *cond; + + left = isl_pw_aff_list_copy(left); + right = isl_pw_aff_list_copy(right); + if (rational) { + left = isl_pw_aff_list_set_rational(left); + right = isl_pw_aff_list_set_rational(right); + } + if (is_list_comparator_type(type)) + cond = list_cmp(set, type, left, right); + else if (type == ISL_TOKEN_LE) + cond = isl_pw_aff_list_le_set(left, right); + else if (type == ISL_TOKEN_GE) + cond = isl_pw_aff_list_ge_set(left, right); + else if (type == ISL_TOKEN_LT) + cond = isl_pw_aff_list_lt_set(left, right); + else if (type == ISL_TOKEN_GT) + cond = isl_pw_aff_list_gt_set(left, right); + else if (type == ISL_TOKEN_NE) + cond = isl_pw_aff_list_ne_set(left, right); + else + cond = isl_pw_aff_list_eq_set(left, right); + + return isl_set_intersect(set, cond); +} + +/* Read a constraint from "s", add it to "map" and return the result. + * "v" contains a description of the identifiers parsed so far. + * "rational" is set if the constraint should be treated as + * a rational constraint. + * The constraint read from "s" may be applied to multiple pairs + * of affine expressions and may be chained. + * In particular, a list of affine expressions is read, followed + * by a comparison operator and another list of affine expressions. + * The comparison operator is then applied to each pair of elements + * in the two lists and the results are added to "map". + * However, if the operator expects two lists of affine expressions, + * then it is applied directly to those lists and the two lists + * are required to have the same length. + * If the next token is another comparison operator, then another + * list of affine expressions is read and the process repeats. + * + * The processing is performed on a wrapped copy of "map" because + * an affine expression cannot have a binary relation as domain. + */ +static __isl_give isl_map *add_constraint(__isl_keep isl_stream *s, + struct vars *v, __isl_take isl_map *map, int rational) +{ + struct isl_token *tok; + int type; + isl_pw_aff_list *list1 = NULL, *list2 = NULL; + isl_size n1, n2; + isl_set *set; + + set = isl_map_wrap(map); + list1 = accept_affine_list(s, isl_set_get_space(set), v); + if (!list1) + goto error; + tok = isl_stream_next_token(s); + if (!is_comparator(tok)) { + isl_stream_error(s, tok, "missing operator"); + if (tok) + isl_stream_push_token(s, tok); + goto error; + } + type = tok->type; + isl_token_free(tok); + for (;;) { + list2 = accept_affine_list(s, isl_set_get_space(set), v); + n1 = isl_pw_aff_list_n_pw_aff(list1); + n2 = isl_pw_aff_list_n_pw_aff(list2); + if (n1 < 0 || n2 < 0) + goto error; + if (is_list_comparator_type(type) && n1 != n2) { + isl_stream_error(s, NULL, + "list arguments not of same size"); + goto error; + } + + set = construct_constraints(set, type, list1, list2, rational); + isl_pw_aff_list_free(list1); + list1 = list2; + + if (!next_is_comparator(s)) + break; + tok = isl_stream_next_token(s); + type = tok->type; + isl_token_free(tok); + } + isl_pw_aff_list_free(list1); + + return isl_set_unwrap(set); +error: + isl_pw_aff_list_free(list1); + isl_pw_aff_list_free(list2); + isl_set_free(set); + return NULL; +} + +static __isl_give isl_map *read_exists(__isl_keep isl_stream *s, + struct vars *v, __isl_take isl_map *map, int rational) +{ + int n = v->n; + int seen_paren = isl_stream_eat_if_available(s, '('); + + map = isl_map_from_domain(isl_map_wrap(map)); + map = read_defined_var_list(s, v, map, rational); + + if (isl_stream_eat(s, ':')) + goto error; + + map = read_formula(s, v, map, rational); + map = isl_set_unwrap(isl_map_domain(map)); + + vars_drop(v, v->n - n); + if (seen_paren && isl_stream_eat(s, ')')) + goto error; + + return map; +error: + isl_map_free(map); + return NULL; +} + +/* Parse an expression between parentheses and push the result + * back on the stream. + * + * The parsed expression may be either an affine expression + * or a condition. The first type is pushed onto the stream + * as an isl_pw_aff, while the second is pushed as an isl_map. + * + * If the initial token indicates the start of a condition, + * we parse it as such. + * Otherwise, we first parse an affine expression and push + * that onto the stream. If the affine expression covers the + * entire expression between parentheses, we return. + * Otherwise, we assume that the affine expression is the + * start of a condition and continue parsing. + */ +static int resolve_paren_expr(__isl_keep isl_stream *s, + struct vars *v, __isl_take isl_map *map, int rational) +{ + struct isl_token *tok, *tok2; + int has_paren; + int line, col; + isl_pw_aff *pwaff; + + tok = isl_stream_next_token(s); + if (!tok || tok->type != '(') + goto error; + + if (isl_stream_next_token_is(s, '(')) + if (resolve_paren_expr(s, v, isl_map_copy(map), rational)) + goto error; + + if (next_is_condition_start(s)) { + map = read_formula(s, v, map, rational); + if (isl_stream_eat(s, ')')) + goto error; + tok->type = ISL_TOKEN_MAP; + tok->u.map = map; + isl_stream_push_token(s, tok); + return 0; + } + + tok2 = isl_stream_next_token(s); + if (!tok2) + goto error; + line = tok2->line; + col = tok2->col; + isl_stream_push_token(s, tok2); + + pwaff = accept_affine(s, isl_space_wrap(isl_map_get_space(map)), v); + if (!pwaff) + goto error; + + has_paren = isl_stream_eat_if_available(s, ')'); + + if (push_aff(s, line, col, pwaff) < 0) + goto error; + + if (has_paren) { + isl_token_free(tok); + isl_map_free(map); + return 0; + } + + map = read_formula(s, v, map, rational); + if (isl_stream_eat(s, ')')) + goto error; + + tok->type = ISL_TOKEN_MAP; + tok->u.map = map; + isl_stream_push_token(s, tok); + + return 0; +error: + isl_token_free(tok); + isl_map_free(map); + return -1; +} + +static __isl_give isl_map *read_conjunct(__isl_keep isl_stream *s, + struct vars *v, __isl_take isl_map *map, int rational) +{ + if (isl_stream_next_token_is(s, '(')) + if (resolve_paren_expr(s, v, isl_map_copy(map), rational)) + goto error; + + if (isl_stream_next_token_is(s, ISL_TOKEN_MAP)) { + struct isl_token *tok; + tok = isl_stream_next_token(s); + if (!tok) + goto error; + isl_map_free(map); + map = isl_map_copy(tok->u.map); + isl_token_free(tok); + return map; + } + + if (isl_stream_eat_if_available(s, ISL_TOKEN_EXISTS)) + return read_exists(s, v, map, rational); + + if (isl_stream_eat_if_available(s, ISL_TOKEN_TRUE)) + return map; + + if (isl_stream_eat_if_available(s, ISL_TOKEN_FALSE)) { + isl_space *space = isl_map_get_space(map); + isl_map_free(map); + return isl_map_empty(space); + } + + return add_constraint(s, v, map, rational); +error: + isl_map_free(map); + return NULL; +} + +static __isl_give isl_map *read_conjuncts(__isl_keep isl_stream *s, + struct vars *v, __isl_take isl_map *map, int rational) +{ + isl_map *res; + int negate; + + negate = isl_stream_eat_if_available(s, ISL_TOKEN_NOT); + res = read_conjunct(s, v, isl_map_copy(map), rational); + if (negate) + res = isl_map_subtract(isl_map_copy(map), res); + + while (res && isl_stream_eat_if_available(s, ISL_TOKEN_AND)) { + isl_map *res_i; + + negate = isl_stream_eat_if_available(s, ISL_TOKEN_NOT); + res_i = read_conjunct(s, v, isl_map_copy(map), rational); + if (negate) + res = isl_map_subtract(res, res_i); + else + res = isl_map_intersect(res, res_i); + } + + isl_map_free(map); + return res; +} + +static __isl_give isl_map *read_disjuncts(__isl_keep isl_stream *s, + struct vars *v, __isl_take isl_map *map, int rational) +{ + isl_map *res; + + if (isl_stream_next_token_is(s, '}')) + return map; + + res = read_conjuncts(s, v, isl_map_copy(map), rational); + while (isl_stream_eat_if_available(s, ISL_TOKEN_OR)) { + isl_map *res_i; + + res_i = read_conjuncts(s, v, isl_map_copy(map), rational); + res = isl_map_union(res, res_i); + } + + isl_map_free(map); + return res; +} + +/* Read a first order formula from "s", add the corresponding + * constraints to "map" and return the result. + * + * In particular, read a formula of the form + * + * a + * + * or + * + * a implies b + * + * where a and b are disjunctions. + * + * In the first case, map is replaced by + * + * map \cap { [..] : a } + * + * In the second case, it is replaced by + * + * (map \setminus { [..] : a}) \cup (map \cap { [..] : b }) + */ +static __isl_give isl_map *read_formula(__isl_keep isl_stream *s, + struct vars *v, __isl_take isl_map *map, int rational) +{ + isl_map *res; + + res = read_disjuncts(s, v, isl_map_copy(map), rational); + + if (isl_stream_eat_if_available(s, ISL_TOKEN_IMPLIES)) { + isl_map *res2; + + res = isl_map_subtract(isl_map_copy(map), res); + res2 = read_disjuncts(s, v, map, rational); + res = isl_map_union(res, res2); + } else + isl_map_free(map); + + return res; +} + +static isl_size polylib_pos_to_isl_pos(__isl_keep isl_basic_map *bmap, int pos) +{ + isl_size n_out, n_in, n_param, n_div; + + n_param = isl_basic_map_dim(bmap, isl_dim_param); + n_in = isl_basic_map_dim(bmap, isl_dim_in); + n_out = isl_basic_map_dim(bmap, isl_dim_out); + n_div = isl_basic_map_dim(bmap, isl_dim_div); + if (n_param < 0 || n_in < 0 || n_out < 0 || n_div < 0) + return isl_size_error; + + if (pos < n_out) + return 1 + n_param + n_in + pos; + pos -= n_out; + + if (pos < n_in) + return 1 + n_param + pos; + pos -= n_in; + + if (pos < n_div) + return 1 + n_param + n_in + n_out + pos; + pos -= n_div; + + if (pos < n_param) + return 1 + pos; + + return 0; +} + +static __isl_give isl_basic_map *basic_map_read_polylib_constraint( + __isl_keep isl_stream *s, __isl_take isl_basic_map *bmap) +{ + int j; + struct isl_token *tok; + int type; + int k; + isl_int *c; + isl_size total; + + if (!bmap) + return NULL; + + tok = isl_stream_next_token(s); + if (!tok || tok->type != ISL_TOKEN_VALUE) { + isl_stream_error(s, tok, "expecting coefficient"); + isl_token_free(tok); + goto error; + } + if (!tok->on_new_line) { + isl_stream_error(s, tok, "coefficient should appear on new line"); + isl_token_free(tok); + goto error; + } + + type = isl_int_get_si(tok->u.v); + isl_token_free(tok); + + isl_assert(s->ctx, type == 0 || type == 1, goto error); + if (type == 0) { + k = isl_basic_map_alloc_equality(bmap); + c = bmap->eq[k]; + } else { + k = isl_basic_map_alloc_inequality(bmap); + c = bmap->ineq[k]; + } + if (k < 0) + goto error; + + total = isl_basic_map_dim(bmap, isl_dim_all); + if (total < 0) + return isl_basic_map_free(bmap); + for (j = 0; j < 1 + total; ++j) { + isl_size pos; + tok = next_signed_value_on_same_line(s, + "expecting coefficient on same line"); + if (!tok) + goto error; + pos = polylib_pos_to_isl_pos(bmap, j); + if (pos >= 0) + isl_int_set(c[pos], tok->u.v); + isl_token_free(tok); + if (pos < 0) + return isl_basic_map_free(bmap); + } + + return bmap; +error: + isl_basic_map_free(bmap); + return NULL; +} + +static __isl_give isl_basic_map *basic_map_read_polylib( + __isl_keep isl_stream *s) +{ + int i; + struct isl_token *tok; + struct isl_token *tok2; + int n_row, n_col; + int on_new_line; + unsigned in = 0, out, local = 0; + struct isl_basic_map *bmap = NULL; + int nparam = 0; + + tok = isl_stream_next_token(s); + if (!tok) { + isl_stream_error(s, NULL, "unexpected EOF"); + return NULL; + } + tok2 = isl_stream_next_token(s); + if (!tok2) { + isl_token_free(tok); + isl_stream_error(s, NULL, "unexpected EOF"); + return NULL; + } + if (tok->type != ISL_TOKEN_VALUE || tok2->type != ISL_TOKEN_VALUE) { + isl_token_free(tok2); + isl_token_free(tok); + isl_stream_error(s, NULL, + "expecting constraint matrix dimensions"); + return NULL; + } + n_row = isl_int_get_si(tok->u.v); + n_col = isl_int_get_si(tok2->u.v); + on_new_line = tok2->on_new_line; + isl_token_free(tok2); + isl_token_free(tok); + isl_assert(s->ctx, !on_new_line, return NULL); + isl_assert(s->ctx, n_row >= 0, return NULL); + isl_assert(s->ctx, n_col >= 2 + nparam, return NULL); + tok = isl_stream_next_token_on_same_line(s); + if (tok) { + if (tok->type != ISL_TOKEN_VALUE) { + isl_stream_error(s, tok, + "expecting number of output dimensions"); + isl_token_free(tok); + goto error; + } + out = isl_int_get_si(tok->u.v); + isl_token_free(tok); + + tok = isl_stream_next_token_on_same_line(s); + if (!tok || tok->type != ISL_TOKEN_VALUE) { + isl_stream_error(s, tok, + "expecting number of input dimensions"); + isl_token_free(tok); + goto error; + } + in = isl_int_get_si(tok->u.v); + isl_token_free(tok); + + tok = isl_stream_next_token_on_same_line(s); + if (!tok || tok->type != ISL_TOKEN_VALUE) { + isl_stream_error(s, tok, + "expecting number of existentials"); + isl_token_free(tok); + goto error; + } + local = isl_int_get_si(tok->u.v); + isl_token_free(tok); + + tok = isl_stream_next_token_on_same_line(s); + if (!tok || tok->type != ISL_TOKEN_VALUE) { + isl_stream_error(s, tok, + "expecting number of parameters"); + isl_token_free(tok); + goto error; + } + nparam = isl_int_get_si(tok->u.v); + isl_token_free(tok); + if (n_col != 1 + out + in + local + nparam + 1) { + isl_stream_error(s, NULL, + "dimensions don't match"); + goto error; + } + } else + out = n_col - 2 - nparam; + bmap = isl_basic_map_alloc(s->ctx, nparam, in, out, local, n_row, n_row); + if (!bmap) + return NULL; + + for (i = 0; i < local; ++i) { + int k = isl_basic_map_alloc_div(bmap); + if (k < 0) + goto error; + isl_seq_clr(bmap->div[k], 1 + 1 + nparam + in + out + local); + } + + for (i = 0; i < n_row; ++i) + bmap = basic_map_read_polylib_constraint(s, bmap); + + if (!bmap) + return NULL; + + tok = isl_stream_next_token_on_same_line(s); + if (tok) { + isl_stream_error(s, tok, "unexpected extra token on line"); + isl_token_free(tok); + goto error; + } + + bmap = isl_basic_map_simplify(bmap); + bmap = isl_basic_map_finalize(bmap); + return bmap; +error: + isl_basic_map_free(bmap); + return NULL; +} + +static __isl_give isl_map *map_read_polylib(__isl_keep isl_stream *s) +{ + struct isl_token *tok; + struct isl_token *tok2; + int i, n; + struct isl_map *map; + + tok = isl_stream_next_token(s); + if (!tok) { + isl_stream_error(s, NULL, "unexpected EOF"); + return NULL; + } + tok2 = isl_stream_next_token_on_same_line(s); + if (tok2 && tok2->type == ISL_TOKEN_VALUE) { + isl_stream_push_token(s, tok2); + isl_stream_push_token(s, tok); + return isl_map_from_basic_map(basic_map_read_polylib(s)); + } + if (tok2) { + isl_stream_error(s, tok2, "unexpected token"); + isl_stream_push_token(s, tok2); + isl_stream_push_token(s, tok); + return NULL; + } + n = isl_int_get_si(tok->u.v); + isl_token_free(tok); + + isl_assert(s->ctx, n >= 1, return NULL); + + map = isl_map_from_basic_map(basic_map_read_polylib(s)); + + for (i = 1; map && i < n; ++i) + map = isl_map_union(map, + isl_map_from_basic_map(basic_map_read_polylib(s))); + + return map; +} + +static int optional_power(__isl_keep isl_stream *s) +{ + int pow; + struct isl_token *tok; + + tok = isl_stream_next_token(s); + if (!tok) + return 1; + if (tok->type != '^') { + isl_stream_push_token(s, tok); + return 1; + } + isl_token_free(tok); + tok = isl_stream_next_token(s); + if (!tok || tok->type != ISL_TOKEN_VALUE) { + isl_stream_error(s, tok, "expecting exponent"); + if (tok) + isl_stream_push_token(s, tok); + return 1; + } + pow = isl_int_get_si(tok->u.v); + isl_token_free(tok); + return pow; +} + +static __isl_give isl_pw_qpolynomial *read_term(__isl_keep isl_stream *s, + __isl_keep isl_map *map, struct vars *v); + +static __isl_give isl_pw_qpolynomial *read_factor(__isl_keep isl_stream *s, + __isl_keep isl_map *map, struct vars *v) +{ + isl_pw_qpolynomial *pwqp; + struct isl_token *tok; + + tok = next_token(s); + if (!tok) { + isl_stream_error(s, NULL, "unexpected EOF"); + return NULL; + } + if (tok->type == '(') { + int pow; + + isl_token_free(tok); + pwqp = read_term(s, map, v); + if (!pwqp) + return NULL; + if (isl_stream_eat(s, ')')) + goto error; + pow = optional_power(s); + pwqp = isl_pw_qpolynomial_pow(pwqp, pow); + } else if (tok->type == ISL_TOKEN_VALUE) { + struct isl_token *tok2; + isl_qpolynomial *qp; + + tok2 = isl_stream_next_token(s); + if (tok2 && tok2->type == '/') { + isl_token_free(tok2); + tok2 = next_token(s); + if (!tok2 || tok2->type != ISL_TOKEN_VALUE) { + isl_stream_error(s, tok2, "expected denominator"); + isl_token_free(tok); + isl_token_free(tok2); + return NULL; + } + qp = isl_qpolynomial_rat_cst_on_domain(isl_map_get_space(map), + tok->u.v, tok2->u.v); + isl_token_free(tok2); + } else { + isl_stream_push_token(s, tok2); + qp = isl_qpolynomial_cst_on_domain(isl_map_get_space(map), + tok->u.v); + } + isl_token_free(tok); + pwqp = isl_pw_qpolynomial_from_qpolynomial(qp); + } else if (tok->type == ISL_TOKEN_INFTY) { + isl_qpolynomial *qp; + isl_token_free(tok); + qp = isl_qpolynomial_infty_on_domain(isl_map_get_space(map)); + pwqp = isl_pw_qpolynomial_from_qpolynomial(qp); + } else if (tok->type == ISL_TOKEN_NAN) { + isl_qpolynomial *qp; + isl_token_free(tok); + qp = isl_qpolynomial_nan_on_domain(isl_map_get_space(map)); + pwqp = isl_pw_qpolynomial_from_qpolynomial(qp); + } else if (tok->type == ISL_TOKEN_IDENT) { + int n = v->n; + int pos = vars_pos(v, tok->u.s, -1); + int pow; + isl_qpolynomial *qp; + if (pos < 0) { + isl_token_free(tok); + return NULL; + } + if (pos >= n) { + vars_drop(v, v->n - n); + isl_stream_error(s, tok, "unknown identifier"); + isl_token_free(tok); + return NULL; + } + isl_token_free(tok); + pow = optional_power(s); + qp = isl_qpolynomial_var_pow_on_domain(isl_map_get_space(map), pos, pow); + pwqp = isl_pw_qpolynomial_from_qpolynomial(qp); + } else if (is_start_of_div(tok)) { + isl_pw_aff *pwaff; + int pow; + + isl_stream_push_token(s, tok); + pwaff = accept_div(s, isl_map_get_space(map), v); + pow = optional_power(s); + pwqp = isl_pw_qpolynomial_from_pw_aff(pwaff); + pwqp = isl_pw_qpolynomial_pow(pwqp, pow); + } else if (tok->type == '-') { + isl_token_free(tok); + pwqp = read_factor(s, map, v); + pwqp = isl_pw_qpolynomial_neg(pwqp); + } else { + isl_stream_error(s, tok, "unexpected isl_token"); + isl_stream_push_token(s, tok); + return NULL; + } + + if (isl_stream_eat_if_available(s, '*') || + isl_stream_next_token_is(s, ISL_TOKEN_IDENT)) { + isl_pw_qpolynomial *pwqp2; + + pwqp2 = read_factor(s, map, v); + pwqp = isl_pw_qpolynomial_mul(pwqp, pwqp2); + } + + return pwqp; +error: + isl_pw_qpolynomial_free(pwqp); + return NULL; +} + +static __isl_give isl_pw_qpolynomial *read_term(__isl_keep isl_stream *s, + __isl_keep isl_map *map, struct vars *v) +{ + struct isl_token *tok; + isl_pw_qpolynomial *pwqp; + + pwqp = read_factor(s, map, v); + + for (;;) { + tok = next_token(s); + if (!tok) + return pwqp; + + if (tok->type == '+') { + isl_pw_qpolynomial *pwqp2; + + isl_token_free(tok); + pwqp2 = read_factor(s, map, v); + pwqp = isl_pw_qpolynomial_add(pwqp, pwqp2); + } else if (tok->type == '-') { + isl_pw_qpolynomial *pwqp2; + + isl_token_free(tok); + pwqp2 = read_factor(s, map, v); + pwqp = isl_pw_qpolynomial_sub(pwqp, pwqp2); + } else { + isl_stream_push_token(s, tok); + break; + } + } + + return pwqp; +} + +static __isl_give isl_map *read_optional_formula(__isl_keep isl_stream *s, + __isl_take isl_map *map, struct vars *v, int rational) +{ + struct isl_token *tok; + + tok = isl_stream_next_token(s); + if (!tok) { + isl_stream_error(s, NULL, "unexpected EOF"); + goto error; + } + if (tok->type == ':' || + (tok->type == ISL_TOKEN_OR && !strcmp(tok->u.s, "|"))) { + isl_token_free(tok); + map = read_formula(s, v, map, rational); + } else + isl_stream_push_token(s, tok); + + return map; +error: + isl_map_free(map); + return NULL; +} + +static struct isl_obj obj_read_poly(__isl_keep isl_stream *s, + __isl_take isl_map *map, struct vars *v, int n) +{ + struct isl_obj obj = { isl_obj_pw_qpolynomial, NULL }; + isl_pw_qpolynomial *pwqp; + struct isl_set *set; + + pwqp = read_term(s, map, v); + map = read_optional_formula(s, map, v, 0); + set = isl_map_range(map); + + pwqp = isl_pw_qpolynomial_intersect_domain(pwqp, set); + + vars_drop(v, v->n - n); + + obj.v = pwqp; + return obj; +} + +static struct isl_obj obj_read_poly_or_fold(__isl_keep isl_stream *s, + __isl_take isl_set *set, struct vars *v, int n) +{ + int min, max; + struct isl_obj obj = { isl_obj_pw_qpolynomial_fold, NULL }; + isl_pw_qpolynomial *pwqp; + isl_pw_qpolynomial_fold *pwf = NULL; + enum isl_fold fold; + + max = isl_stream_eat_if_available(s, ISL_TOKEN_MAX); + min = !max && isl_stream_eat_if_available(s, ISL_TOKEN_MIN); + if (!min && !max) + return obj_read_poly(s, set, v, n); + fold = max ? isl_fold_max : isl_fold_min; + + if (isl_stream_eat(s, '(')) + goto error; + + pwqp = read_term(s, set, v); + pwf = isl_pw_qpolynomial_fold_from_pw_qpolynomial(fold, pwqp); + + while (isl_stream_eat_if_available(s, ',')) { + isl_pw_qpolynomial_fold *pwf_i; + pwqp = read_term(s, set, v); + pwf_i = isl_pw_qpolynomial_fold_from_pw_qpolynomial(fold, pwqp); + pwf = isl_pw_qpolynomial_fold_fold(pwf, pwf_i); + } + + if (isl_stream_eat(s, ')')) + goto error; + + set = read_optional_formula(s, set, v, 0); + pwf = isl_pw_qpolynomial_fold_intersect_domain(pwf, set); + + vars_drop(v, v->n - n); + + obj.v = pwf; + return obj; +error: + isl_set_free(set); + isl_pw_qpolynomial_fold_free(pwf); + obj.type = isl_obj_none; + return obj; +} + +static int is_rational(__isl_keep isl_stream *s) +{ + struct isl_token *tok; + + tok = isl_stream_next_token(s); + if (!tok) + return 0; + if (tok->type == ISL_TOKEN_RAT && isl_stream_next_token_is(s, ':')) { + isl_token_free(tok); + isl_stream_eat(s, ':'); + return 1; + } + + isl_stream_push_token(s, tok); + + return 0; +} + +static struct isl_obj obj_read_body(__isl_keep isl_stream *s, + __isl_take isl_map *map, struct vars *v) +{ + struct isl_token *tok; + struct isl_obj obj = { isl_obj_set, NULL }; + int n = v->n; + int rational; + + rational = is_rational(s); + if (rational) + map = isl_map_set_rational(map); + + if (isl_stream_next_token_is(s, ':')) { + obj.type = isl_obj_set; + obj.v = read_optional_formula(s, map, v, rational); + return obj; + } + + if (!next_is_tuple(s)) + return obj_read_poly_or_fold(s, map, v, n); + + map = read_map_tuple(s, map, isl_dim_in, v, 0); + if (!map) + goto error; + tok = isl_stream_next_token(s); + if (!tok) + goto error; + if (tok->type == ISL_TOKEN_TO) { + obj.type = isl_obj_map; + isl_token_free(tok); + if (!next_is_tuple(s)) { + isl_set *set = isl_map_domain(map); + return obj_read_poly_or_fold(s, set, v, n); + } + map = read_map_tuple(s, map, isl_dim_out, v, 0); + if (!map) + goto error; + } else { + map = isl_map_domain(map); + isl_stream_push_token(s, tok); + } + + map = read_optional_formula(s, map, v, rational); + + vars_drop(v, v->n - n); + + obj.v = map; + return obj; +error: + isl_map_free(map); + obj.type = isl_obj_none; + return obj; +} + +static struct isl_obj to_union(isl_ctx *ctx, struct isl_obj obj) +{ + if (obj.type == isl_obj_map) { + obj.v = isl_union_map_from_map(obj.v); + obj.type = isl_obj_union_map; + } else if (obj.type == isl_obj_set) { + obj.v = isl_union_set_from_set(obj.v); + obj.type = isl_obj_union_set; + } else if (obj.type == isl_obj_pw_qpolynomial) { + obj.v = isl_union_pw_qpolynomial_from_pw_qpolynomial(obj.v); + obj.type = isl_obj_union_pw_qpolynomial; + } else if (obj.type == isl_obj_pw_qpolynomial_fold) { + obj.v = isl_union_pw_qpolynomial_fold_from_pw_qpolynomial_fold(obj.v); + obj.type = isl_obj_union_pw_qpolynomial_fold; + } else + isl_assert(ctx, 0, goto error); + return obj; +error: + obj.type->free(obj.v); + obj.type = isl_obj_none; + return obj; +} + +static struct isl_obj obj_add(__isl_keep isl_stream *s, + struct isl_obj obj1, struct isl_obj obj2) +{ + if (obj2.type == isl_obj_none || !obj2.v) + goto error; + if (obj1.type == isl_obj_set && obj2.type == isl_obj_union_set) + obj1 = to_union(s->ctx, obj1); + if (obj1.type == isl_obj_union_set && obj2.type == isl_obj_set) + obj2 = to_union(s->ctx, obj2); + if (obj1.type == isl_obj_map && obj2.type == isl_obj_union_map) + obj1 = to_union(s->ctx, obj1); + if (obj1.type == isl_obj_union_map && obj2.type == isl_obj_map) + obj2 = to_union(s->ctx, obj2); + if (obj1.type == isl_obj_pw_qpolynomial && + obj2.type == isl_obj_union_pw_qpolynomial) + obj1 = to_union(s->ctx, obj1); + if (obj1.type == isl_obj_union_pw_qpolynomial && + obj2.type == isl_obj_pw_qpolynomial) + obj2 = to_union(s->ctx, obj2); + if (obj1.type == isl_obj_pw_qpolynomial_fold && + obj2.type == isl_obj_union_pw_qpolynomial_fold) + obj1 = to_union(s->ctx, obj1); + if (obj1.type == isl_obj_union_pw_qpolynomial_fold && + obj2.type == isl_obj_pw_qpolynomial_fold) + obj2 = to_union(s->ctx, obj2); + if (obj1.type != obj2.type) { + isl_stream_error(s, NULL, + "attempt to combine incompatible objects"); + goto error; + } + if (!obj1.type->add) + isl_die(s->ctx, isl_error_internal, + "combination not supported on object type", goto error); + if (obj1.type == isl_obj_map && !isl_map_has_equal_space(obj1.v, obj2.v)) { + obj1 = to_union(s->ctx, obj1); + obj2 = to_union(s->ctx, obj2); + } + if (obj1.type == isl_obj_set && !isl_set_has_equal_space(obj1.v, obj2.v)) { + obj1 = to_union(s->ctx, obj1); + obj2 = to_union(s->ctx, obj2); + } + if (obj1.type == isl_obj_pw_qpolynomial && + !isl_pw_qpolynomial_has_equal_space(obj1.v, obj2.v)) { + obj1 = to_union(s->ctx, obj1); + obj2 = to_union(s->ctx, obj2); + } + if (obj1.type == isl_obj_pw_qpolynomial_fold && + !isl_pw_qpolynomial_fold_has_equal_space(obj1.v, obj2.v)) { + obj1 = to_union(s->ctx, obj1); + obj2 = to_union(s->ctx, obj2); + } + obj1.v = obj1.type->add(obj1.v, obj2.v); + return obj1; +error: + obj1.type->free(obj1.v); + obj2.type->free(obj2.v); + obj1.type = isl_obj_none; + obj1.v = NULL; + return obj1; +} + +/* Are the first two tokens on "s", "domain" (either as a string + * or as an identifier) followed by ":"? + */ +static int next_is_domain_colon(__isl_keep isl_stream *s) +{ + struct isl_token *tok; + char *name; + int res; + + tok = isl_stream_next_token(s); + if (!tok) + return 0; + if (tok->type != ISL_TOKEN_IDENT && tok->type != ISL_TOKEN_STRING) { + isl_stream_push_token(s, tok); + return 0; + } + + name = isl_token_get_str(s->ctx, tok); + res = !strcmp(name, "domain") && isl_stream_next_token_is(s, ':'); + free(name); + + isl_stream_push_token(s, tok); + + return res; +} + +/* Do the first tokens on "s" look like a schedule? + * + * The root of a schedule is always a domain node, so the first thing + * we expect in the stream is a domain key, i.e., "domain" followed + * by ":". If the schedule was printed in YAML flow style, then + * we additionally expect a "{" to open the outer mapping. + */ +static int next_is_schedule(__isl_keep isl_stream *s) +{ + struct isl_token *tok; + int is_schedule; + + tok = isl_stream_next_token(s); + if (!tok) + return 0; + if (tok->type != '{') { + isl_stream_push_token(s, tok); + return next_is_domain_colon(s); + } + + is_schedule = next_is_domain_colon(s); + isl_stream_push_token(s, tok); + + return is_schedule; +} + +/* Read an isl_schedule from "s" and store it in an isl_obj. + */ +static struct isl_obj schedule_read(__isl_keep isl_stream *s) +{ + struct isl_obj obj; + + obj.type = isl_obj_schedule; + obj.v = isl_stream_read_schedule(s); + + return obj; +} + +/* Read a disjunction of object bodies from "s". + * That is, read the inside of the braces, but not the braces themselves. + * "v" contains a description of the identifiers parsed so far. + * "map" contains information about the parameters. + */ +static struct isl_obj obj_read_disjuncts(__isl_keep isl_stream *s, + struct vars *v, __isl_keep isl_map *map) +{ + struct isl_obj obj = { isl_obj_set, NULL }; + + if (isl_stream_next_token_is(s, '}')) { + obj.type = isl_obj_union_set; + obj.v = isl_union_set_empty(isl_map_get_space(map)); + return obj; + } + + for (;;) { + struct isl_obj o; + o = obj_read_body(s, isl_map_copy(map), v); + if (!obj.v) + obj = o; + else + obj = obj_add(s, obj, o); + if (obj.type == isl_obj_none || !obj.v) + return obj; + if (!isl_stream_eat_if_available(s, ';')) + break; + if (isl_stream_next_token_is(s, '}')) + break; + } + + return obj; +} + +static struct isl_obj obj_read(__isl_keep isl_stream *s) +{ + isl_map *map = NULL; + struct isl_token *tok; + struct vars *v = NULL; + struct isl_obj obj = { isl_obj_set, NULL }; + + if (next_is_schedule(s)) + return schedule_read(s); + + tok = next_token(s); + if (!tok) { + isl_stream_error(s, NULL, "unexpected EOF"); + goto error; + } + if (tok->type == ISL_TOKEN_VALUE) { + struct isl_token *tok2; + struct isl_map *map; + + tok2 = isl_stream_next_token(s); + if (!tok2 || tok2->type != ISL_TOKEN_VALUE || + isl_int_is_neg(tok2->u.v)) { + if (tok2) + isl_stream_push_token(s, tok2); + obj.type = isl_obj_val; + obj.v = isl_val_int_from_isl_int(s->ctx, tok->u.v); + isl_token_free(tok); + return obj; + } + isl_stream_push_token(s, tok2); + isl_stream_push_token(s, tok); + map = map_read_polylib(s); + if (!map) + goto error; + if (isl_map_may_be_set(map)) + obj.v = isl_map_range(map); + else { + obj.type = isl_obj_map; + obj.v = map; + } + return obj; + } + v = vars_new(s->ctx); + if (!v) { + isl_stream_push_token(s, tok); + goto error; + } + map = isl_map_universe(isl_space_params_alloc(s->ctx, 0)); + if (tok->type == '[') { + isl_stream_push_token(s, tok); + map = read_map_tuple(s, map, isl_dim_param, v, 0); + if (!map) + goto error; + tok = isl_stream_next_token(s); + if (!tok || tok->type != ISL_TOKEN_TO) { + isl_stream_error(s, tok, "expecting '->'"); + if (tok) + isl_stream_push_token(s, tok); + goto error; + } + isl_token_free(tok); + tok = isl_stream_next_token(s); + } + if (!tok || tok->type != '{') { + isl_stream_error(s, tok, "expecting '{'"); + if (tok) + isl_stream_push_token(s, tok); + goto error; + } + isl_token_free(tok); + + tok = isl_stream_next_token(s); + if (!tok) + ; + else if (tok->type == ISL_TOKEN_IDENT && !strcmp(tok->u.s, "Sym")) { + isl_token_free(tok); + if (isl_stream_eat(s, '=')) + goto error; + map = read_map_tuple(s, map, isl_dim_param, v, 1); + if (!map) + goto error; + } else + isl_stream_push_token(s, tok); + + obj = obj_read_disjuncts(s, v, map); + if (obj.type == isl_obj_none || !obj.v) + goto error; + + tok = isl_stream_next_token(s); + if (tok && tok->type == '}') { + isl_token_free(tok); + } else { + isl_stream_error(s, tok, "unexpected isl_token"); + if (tok) + isl_token_free(tok); + goto error; + } + + vars_free(v); + isl_map_free(map); + + return obj; +error: + isl_map_free(map); + obj.type->free(obj.v); + if (v) + vars_free(v); + obj.v = NULL; + return obj; +} + +struct isl_obj isl_stream_read_obj(__isl_keep isl_stream *s) +{ + return obj_read(s); +} + +__isl_give isl_map *isl_stream_read_map(__isl_keep isl_stream *s) +{ + struct isl_obj obj; + + obj = obj_read(s); + if (obj.v) + isl_assert(s->ctx, obj.type == isl_obj_map || + obj.type == isl_obj_set, goto error); + + if (obj.type == isl_obj_set) + obj.v = isl_map_from_range(obj.v); + + return obj.v; +error: + obj.type->free(obj.v); + return NULL; +} + +__isl_give isl_set *isl_stream_read_set(__isl_keep isl_stream *s) +{ + struct isl_obj obj; + + obj = obj_read(s); + if (obj.v) { + if (obj.type == isl_obj_map && isl_map_may_be_set(obj.v)) { + obj.v = isl_map_range(obj.v); + obj.type = isl_obj_set; + } + isl_assert(s->ctx, obj.type == isl_obj_set, goto error); + } + + return obj.v; +error: + obj.type->free(obj.v); + return NULL; +} + +__isl_give isl_union_map *isl_stream_read_union_map(__isl_keep isl_stream *s) +{ + struct isl_obj obj; + + obj = obj_read(s); + if (obj.type == isl_obj_map) { + obj.type = isl_obj_union_map; + obj.v = isl_union_map_from_map(obj.v); + } + if (obj.type == isl_obj_set) { + obj.type = isl_obj_union_set; + obj.v = isl_union_set_from_set(obj.v); + } + if (obj.v && obj.type == isl_obj_union_set && + isl_union_set_is_empty(obj.v)) + obj.type = isl_obj_union_map; + if (obj.v && obj.type != isl_obj_union_map) + isl_die(s->ctx, isl_error_invalid, "invalid input", goto error); + + return obj.v; +error: + obj.type->free(obj.v); + return NULL; +} + +/* Extract an isl_union_set from "obj". + * This only works if the object was detected as either a set + * (in which case it is converted to a union set) or a union set. + */ +static __isl_give isl_union_set *extract_union_set(isl_ctx *ctx, + struct isl_obj obj) +{ + if (obj.type == isl_obj_set) { + obj.type = isl_obj_union_set; + obj.v = isl_union_set_from_set(obj.v); + } + if (obj.v) + isl_assert(ctx, obj.type == isl_obj_union_set, goto error); + + return obj.v; +error: + obj.type->free(obj.v); + return NULL; +} + +/* Read an isl_union_set from "s". + * First read a generic object and then try and extract + * an isl_union_set from that. + */ +__isl_give isl_union_set *isl_stream_read_union_set(__isl_keep isl_stream *s) +{ + struct isl_obj obj; + + obj = obj_read(s); + return extract_union_set(s->ctx, obj); +} + +static __isl_give isl_basic_map *isl_stream_read_basic_map( + __isl_keep isl_stream *s) +{ + struct isl_obj obj; + struct isl_map *map; + struct isl_basic_map *bmap; + + obj = obj_read(s); + if (obj.v && (obj.type != isl_obj_map && obj.type != isl_obj_set)) + isl_die(s->ctx, isl_error_invalid, "not a (basic) set or map", + goto error); + map = obj.v; + if (!map) + return NULL; + + if (map->n > 1) + isl_die(s->ctx, isl_error_invalid, + "set or map description involves " + "more than one disjunct", goto error); + + if (map->n == 0) + bmap = isl_basic_map_empty(isl_map_get_space(map)); + else + bmap = isl_basic_map_copy(map->p[0]); + + isl_map_free(map); + + return bmap; +error: + obj.type->free(obj.v); + return NULL; +} + +/* Read an isl_basic_set object from "s". + */ +__isl_give isl_basic_set *isl_stream_read_basic_set(__isl_keep isl_stream *s) +{ + isl_basic_map *bmap; + bmap = isl_stream_read_basic_map(s); + if (!bmap) + return NULL; + if (!isl_basic_map_may_be_set(bmap)) + isl_die(s->ctx, isl_error_invalid, + "input is not a set", goto error); + return isl_basic_map_range(bmap); +error: + isl_basic_map_free(bmap); + return NULL; +} + +__isl_give isl_basic_map *isl_basic_map_read_from_file(isl_ctx *ctx, + FILE *input) +{ + struct isl_basic_map *bmap; + isl_stream *s = isl_stream_new_file(ctx, input); + if (!s) + return NULL; + bmap = isl_stream_read_basic_map(s); + isl_stream_free(s); + return bmap; +} + +__isl_give isl_basic_set *isl_basic_set_read_from_file(isl_ctx *ctx, + FILE *input) +{ + isl_basic_set *bset; + isl_stream *s = isl_stream_new_file(ctx, input); + if (!s) + return NULL; + bset = isl_stream_read_basic_set(s); + isl_stream_free(s); + return bset; +} + +#undef TYPE_BASE +#define TYPE_BASE basic_map +#include "isl_read_from_str_templ.c" + +#undef TYPE_BASE +#define TYPE_BASE basic_set +#include "isl_read_from_str_templ.c" + +__isl_give isl_map *isl_map_read_from_file(struct isl_ctx *ctx, + FILE *input) +{ + struct isl_map *map; + isl_stream *s = isl_stream_new_file(ctx, input); + if (!s) + return NULL; + map = isl_stream_read_map(s); + isl_stream_free(s); + return map; +} + +#undef TYPE_BASE +#define TYPE_BASE map +#include "isl_read_from_str_templ.c" + +__isl_give isl_set *isl_set_read_from_file(struct isl_ctx *ctx, + FILE *input) +{ + isl_set *set; + isl_stream *s = isl_stream_new_file(ctx, input); + if (!s) + return NULL; + set = isl_stream_read_set(s); + isl_stream_free(s); + return set; +} + +#undef TYPE_BASE +#define TYPE_BASE set +#include "isl_read_from_str_templ.c" + +__isl_give isl_union_map *isl_union_map_read_from_file(isl_ctx *ctx, + FILE *input) +{ + isl_union_map *umap; + isl_stream *s = isl_stream_new_file(ctx, input); + if (!s) + return NULL; + umap = isl_stream_read_union_map(s); + isl_stream_free(s); + return umap; +} + +#undef TYPE_BASE +#define TYPE_BASE union_map +#include "isl_read_from_str_templ.c" + +__isl_give isl_union_set *isl_union_set_read_from_file(isl_ctx *ctx, + FILE *input) +{ + isl_union_set *uset; + isl_stream *s = isl_stream_new_file(ctx, input); + if (!s) + return NULL; + uset = isl_stream_read_union_set(s); + isl_stream_free(s); + return uset; +} + +#undef TYPE_BASE +#define TYPE_BASE union_set +#include "isl_read_from_str_templ.c" + +static __isl_give isl_vec *isl_vec_read_polylib(__isl_keep isl_stream *s) +{ + struct isl_vec *vec = NULL; + struct isl_token *tok; + unsigned size; + int j; + + tok = isl_stream_next_token(s); + if (!tok || tok->type != ISL_TOKEN_VALUE) { + isl_stream_error(s, tok, "expecting vector length"); + goto error; + } + + size = isl_int_get_si(tok->u.v); + isl_token_free(tok); + + vec = isl_vec_alloc(s->ctx, size); + + for (j = 0; j < size; ++j) { + tok = next_signed_value(s, "expecting constant value"); + if (!tok) + goto error; + isl_int_set(vec->el[j], tok->u.v); + isl_token_free(tok); + } + + return vec; +error: + isl_token_free(tok); + isl_vec_free(vec); + return NULL; +} + +static __isl_give isl_vec *vec_read(__isl_keep isl_stream *s) +{ + return isl_vec_read_polylib(s); +} + +__isl_give isl_vec *isl_vec_read_from_file(isl_ctx *ctx, FILE *input) +{ + isl_vec *v; + isl_stream *s = isl_stream_new_file(ctx, input); + if (!s) + return NULL; + v = vec_read(s); + isl_stream_free(s); + return v; +} + +__isl_give isl_pw_qpolynomial *isl_stream_read_pw_qpolynomial( + __isl_keep isl_stream *s) +{ + struct isl_obj obj; + + obj = obj_read(s); + if (obj.v) + isl_assert(s->ctx, obj.type == isl_obj_pw_qpolynomial, + goto error); + + return obj.v; +error: + obj.type->free(obj.v); + return NULL; +} + +#undef TYPE_BASE +#define TYPE_BASE pw_qpolynomial +#include "isl_read_from_str_templ.c" + +__isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_read_from_file(isl_ctx *ctx, + FILE *input) +{ + isl_pw_qpolynomial *pwqp; + isl_stream *s = isl_stream_new_file(ctx, input); + if (!s) + return NULL; + pwqp = isl_stream_read_pw_qpolynomial(s); + isl_stream_free(s); + return pwqp; +} + +/* Read an isl_pw_qpolynomial_fold from "s". + * First read a generic object and + * then check that it is an isl_pw_qpolynomial_fold. + */ +__isl_give isl_pw_qpolynomial_fold *isl_stream_read_pw_qpolynomial_fold( + __isl_keep isl_stream *s) +{ + struct isl_obj obj; + + obj = obj_read(s); + if (obj.v && obj.type != isl_obj_pw_qpolynomial_fold) + isl_die(s->ctx, isl_error_invalid, "invalid input", goto error); + + return obj.v; +error: + obj.type->free(obj.v); + return NULL; +} + +#undef TYPE_BASE +#define TYPE_BASE pw_qpolynomial_fold +#include "isl_read_from_str_templ.c" + +/* Is the next token an identifier not in "v"? + */ +static int next_is_fresh_ident(__isl_keep isl_stream *s, struct vars *v) +{ + int n = v->n; + int fresh; + struct isl_token *tok; + + tok = isl_stream_next_token(s); + if (!tok) + return 0; + fresh = tok->type == ISL_TOKEN_IDENT && vars_pos(v, tok->u.s, -1) >= n; + isl_stream_push_token(s, tok); + + vars_drop(v, v->n - n); + + return fresh; +} + +/* First read the domain of the affine expression, which may be + * a parameter space or a set. + * The tricky part is that we don't know if the domain is a set or not, + * so when we are trying to read the domain, we may actually be reading + * the affine expression itself (defined on a parameter domains) + * If the tuple we are reading is named, we assume it's the domain. + * Also, if inside the tuple, the first thing we find is a nested tuple + * or a new identifier, we again assume it's the domain. + * Finally, if the tuple is empty, then it must be the domain + * since it does not contain an affine expression. + * Otherwise, we assume we are reading an affine expression. + */ +static __isl_give isl_set *read_aff_domain(__isl_keep isl_stream *s, + __isl_take isl_set *dom, struct vars *v) +{ + struct isl_token *tok, *tok2; + int is_empty; + + 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, 0); + } + if (!tok || tok->type != '[') { + isl_stream_error(s, tok, "expecting '['"); + goto error; + } + tok2 = isl_stream_next_token(s); + is_empty = tok2 && tok2->type == ']'; + if (tok2) + 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, 0); + } else + isl_stream_push_token(s, tok); + + return dom; +error: + if (tok) + isl_stream_push_token(s, tok); + isl_set_free(dom); + return NULL; +} + +/* Read an affine expression from "s". + */ +__isl_give isl_aff *isl_stream_read_aff(__isl_keep isl_stream *s) +{ + isl_aff *aff; + isl_multi_aff *ma; + isl_size dim; + + ma = isl_stream_read_multi_aff(s); + dim = isl_multi_aff_dim(ma, isl_dim_out); + if (dim < 0) + goto error; + if (dim != 1) + isl_die(s->ctx, isl_error_invalid, + "expecting single affine expression", + goto error); + + aff = isl_multi_aff_get_aff(ma, 0); + isl_multi_aff_free(ma); + return aff; +error: + isl_multi_aff_free(ma); + return NULL; +} + +/* Read a piecewise affine expression from "s" with domain (space) "dom". + */ +static __isl_give isl_pw_aff *read_pw_aff_with_dom(__isl_keep isl_stream *s, + __isl_take isl_set *dom, struct vars *v) +{ + isl_pw_aff *pwaff = NULL; + + if (!isl_set_is_params(dom) && isl_stream_eat(s, ISL_TOKEN_TO)) + goto error; + + if (isl_stream_eat(s, '[')) + goto error; + + pwaff = accept_affine(s, isl_set_get_space(dom), v); + + if (isl_stream_eat(s, ']')) + goto error; + + dom = read_optional_formula(s, dom, v, 0); + pwaff = isl_pw_aff_intersect_domain(pwaff, dom); + + return pwaff; +error: + isl_set_free(dom); + isl_pw_aff_free(pwaff); + return NULL; +} + +/* Read an affine expression, together with optional constraints + * on the domain from "s". "dom" represents the initial constraints + * on the parameter domain. + * "v" contains a description of the identifiers parsed so far. + */ +static __isl_give isl_pw_aff *read_conditional_aff(__isl_keep isl_stream *s, + __isl_take isl_set *dom, struct vars *v) +{ + isl_set *aff_dom; + isl_pw_aff *pa; + int n; + + n = v->n; + aff_dom = read_aff_domain(s, dom, v); + pa = read_pw_aff_with_dom(s, aff_dom, v); + vars_drop(v, v->n - n); + + return pa; +} + +#undef BASE +#define BASE aff +#include "isl_stream_read_pw_with_params_templ.c" + +#undef TYPE_BASE +#define TYPE_BASE aff +#include "isl_read_from_str_templ.c" + +#undef TYPE_BASE +#define TYPE_BASE pw_aff +#include "isl_stream_read_with_params_templ.c" +#include "isl_read_from_str_templ.c" + +/* Given that "pa" is the element at position "pos" of a tuple + * returned by read_tuple, check that it does not involve any + * output/set dimensions (appearing at the "n" positions starting at "first"), + * remove those from the domain and replace the domain space + * with "domain_space". + * + * In particular, the result of read_tuple is of the form + * [input, output] -> [output], with anonymous domain. + * The function read_tuple accepts tuples where some output or + * set dimensions are defined in terms of other output or set dimensions + * since this function is also used to read maps. As a special case, + * read_tuple also accepts dimensions that are defined in terms of themselves + * (i.e., that are not defined). + * These cases are not allowed here. + */ +static __isl_give isl_pw_aff *separate_tuple_entry(__isl_take isl_pw_aff *pa, + int pos, unsigned first, unsigned n, __isl_take isl_space *domain_space) +{ + isl_bool involves; + + involves = isl_pw_aff_involves_dims(pa, isl_dim_in, first, pos + 1); + if (involves < 0) { + pa = isl_pw_aff_free(pa); + } else if (involves) { + isl_die(isl_pw_aff_get_ctx(pa), isl_error_invalid, + "not an affine expression", + pa = isl_pw_aff_free(pa)); + } + pa = isl_pw_aff_drop_dims(pa, isl_dim_in, first, n); + pa = isl_pw_aff_reset_domain_space(pa, domain_space); + + return pa; +} + +/* Set entry "pos" of "mpa" to the corresponding entry in "tuple", + * as obtained from read_tuple(). + * The "n" output dimensions also appear among the input dimensions + * at position "first". + * + * The entry is not allowed to depend on any (other) output dimensions. + */ +static __isl_give isl_multi_pw_aff *isl_multi_pw_aff_set_tuple_entry( + __isl_take isl_multi_pw_aff *mpa, __isl_take isl_pw_aff *tuple_el, + int pos, unsigned first, unsigned n) +{ + isl_space *space; + isl_pw_aff *pa; + + space = isl_multi_pw_aff_get_domain_space(mpa); + pa = separate_tuple_entry(tuple_el, pos, first, n, space); + return isl_multi_pw_aff_set_pw_aff(mpa, pos, pa); +} + +#undef BASE +#define BASE pw_aff + +#include + +/* Read a tuple of piecewise affine expressions, + * including optional constraints on the domain from "s". + * "dom" represents the initial constraints on the domain. + * + * The input format is similar to that of a map, except that any conditions + * on the domains should be specified inside the tuple since each + * piecewise affine expression may have a different domain. + * However, additional, shared conditions can also be specified. + * This is especially useful for setting the explicit domain + * of a zero-dimensional isl_multi_pw_aff. + * + * The isl_multi_pw_aff may live in either a set or a map space. + * First read the first tuple and check if it is followed by a "->". + * If so, convert the tuple into the domain of the isl_multi_pw_aff and + * read in the next tuple. This tuple (or the first tuple if it was + * not followed by a "->") is then converted into an isl_multi_pw_aff + * through a call to isl_multi_pw_aff_from_tuple. + * The domain of the result is intersected with the domain. + * + * Note that the last tuple may introduce new identifiers, + * but these cannot be referenced in the description of the domain. + */ +static __isl_give isl_multi_pw_aff *read_conditional_multi_pw_aff( + __isl_keep isl_stream *s, __isl_take isl_set *dom, struct vars *v) +{ + isl_multi_pw_aff *tuple; + isl_multi_pw_aff *mpa; + int n = v->n; + int n_dom; + + n_dom = v->n; + tuple = read_tuple(s, v, 0, 0); + if (!tuple) + goto error; + if (isl_stream_eat_if_available(s, ISL_TOKEN_TO)) { + isl_map *map = map_from_tuple(tuple, dom, isl_dim_in, v, 0); + dom = isl_map_domain(map); + n_dom = v->n; + tuple = read_tuple(s, v, 0, 0); + if (!tuple) + goto error; + } + mpa = isl_multi_pw_aff_from_tuple(isl_set_get_space(dom), tuple); + if (!mpa) + dom = isl_set_free(dom); + + vars_drop(v, v->n - n_dom); + dom = read_optional_formula(s, dom, v, 0); + + vars_drop(v, v->n - n); + + mpa = isl_multi_pw_aff_intersect_domain(mpa, dom); + + return mpa; +error: + isl_set_free(dom); + return NULL; +} + +/* Read a tuple of affine expressions, together with optional constraints + * on the domain from "s". "dom" represents the initial constraints + * on the domain. + * + * Read a tuple of piecewise affine expressions with optional constraints and + * convert the result to an isl_pw_multi_aff on the shared domain. + */ +static __isl_give isl_pw_multi_aff *read_conditional_multi_aff( + __isl_keep isl_stream *s, __isl_take isl_set *dom, struct vars *v) +{ + isl_multi_pw_aff *mpa; + + mpa = read_conditional_multi_pw_aff(s, dom, v); + return isl_pw_multi_aff_from_multi_pw_aff(mpa); +} + +/* Read an isl_union_pw_multi_aff from "s" with parameter domain "dom". + * "v" contains a description of the identifiers parsed so far. + * + * In particular, read a sequence + * of zero or more tuples of affine expressions with optional conditions and + * add them up. + */ +static __isl_give isl_union_pw_multi_aff * +isl_stream_read_with_params_union_pw_multi_aff(__isl_keep isl_stream *s, + __isl_keep isl_set *dom, struct vars *v) +{ + isl_union_pw_multi_aff *upma; + + upma = isl_union_pw_multi_aff_empty(isl_set_get_space(dom)); + + do { + isl_pw_multi_aff *pma; + isl_union_pw_multi_aff *upma2; + + if (isl_stream_next_token_is(s, '}')) + break; + + pma = read_conditional_multi_aff(s, isl_set_copy(dom), v); + upma2 = isl_union_pw_multi_aff_from_pw_multi_aff(pma); + upma = isl_union_pw_multi_aff_union_add(upma, upma2); + if (!upma) + return NULL; + } while (isl_stream_eat_if_available(s, ';')); + + return upma; +} + +#undef BASE +#define BASE multi_aff +#include "isl_stream_read_pw_with_params_templ.c" + +#undef TYPE_BASE +#define TYPE_BASE pw_multi_aff +#include "isl_stream_read_with_params_templ.c" +#include "isl_read_from_str_templ.c" + +#undef TYPE_BASE +#define TYPE_BASE union_pw_multi_aff +#include "isl_stream_read_with_params_templ.c" +#include "isl_read_from_str_templ.c" + +#undef BASE +#define BASE val + +#include + +#undef BASE +#define BASE id + +#include + +/* Set entry "pos" of "ma" to the corresponding entry in "tuple", + * as obtained from read_tuple(). + * The "n" output dimensions also appear among the input dimensions + * at position "first". + * + * The entry is not allowed to depend on any (other) output dimensions. + */ +static __isl_give isl_multi_aff *isl_multi_aff_set_tuple_entry( + __isl_take isl_multi_aff *ma, __isl_take isl_pw_aff *tuple_el, + int pos, unsigned first, unsigned n) +{ + isl_space *space; + isl_pw_aff *pa; + isl_aff *aff; + + space = isl_multi_aff_get_domain_space(ma); + pa = separate_tuple_entry(tuple_el, pos, first, n, space); + aff = isl_pw_aff_as_aff(pa); + return isl_multi_aff_set_aff(ma, pos, aff); +} + +#undef BASE +#define BASE aff + +#include + +/* Read a multi-affine expression from "s". + * If the multi-affine expression has a domain, then the tuple + * representing this domain cannot involve any affine expressions. + * The tuple representing the actual expressions needs to consist + * of only affine expressions. + */ +__isl_give isl_multi_aff *isl_stream_read_multi_aff(__isl_keep isl_stream *s) +{ + struct vars *v; + isl_multi_pw_aff *tuple = NULL; + isl_space *dom_space = NULL; + isl_multi_aff *ma = NULL; + + v = vars_new(s->ctx); + if (!v) + return NULL; + + dom_space = read_params(s, v); + if (!dom_space) + goto error; + if (isl_stream_eat(s, '{')) + goto error; + + tuple = read_tuple(s, v, 0, 0); + if (!tuple) + goto error; + if (isl_stream_eat_if_available(s, ISL_TOKEN_TO)) { + isl_space *space; + isl_bool has_expr; + + has_expr = tuple_has_expr(tuple); + if (has_expr < 0) + goto error; + if (has_expr) + isl_die(s->ctx, isl_error_invalid, + "expecting universe domain", goto error); + space = isl_space_range(isl_multi_pw_aff_get_space(tuple)); + dom_space = isl_space_align_params(space, dom_space); + isl_multi_pw_aff_free(tuple); + tuple = read_tuple(s, v, 0, 0); + if (!tuple) + goto error; + } + + if (isl_stream_eat(s, '}')) + goto error; + + ma = isl_multi_aff_from_tuple(dom_space, tuple); + + vars_free(v); + return ma; +error: + isl_multi_pw_aff_free(tuple); + vars_free(v); + isl_space_free(dom_space); + isl_multi_aff_free(ma); + return NULL; +} + +#undef TYPE_BASE +#define TYPE_BASE multi_aff +#include "isl_read_from_str_templ.c" + +/* Read an isl_multi_pw_aff from "s" with parameter domain "dom".. + * "v" contains a description of the identifiers parsed so far. + */ +static __isl_give isl_multi_pw_aff *isl_stream_read_with_params_multi_pw_aff( + __isl_keep isl_stream *s, __isl_keep isl_set *dom, struct vars *v) +{ + return read_conditional_multi_pw_aff(s, isl_set_copy(dom), v); +} + +#undef TYPE_BASE +#define TYPE_BASE multi_pw_aff +#include "isl_stream_read_with_params_templ.c" +#include "isl_read_from_str_templ.c" + +/* Read the body of an isl_union_pw_aff from "s" with parameter domain "dom". + */ +static __isl_give isl_union_pw_aff *read_union_pw_aff_with_dom( + __isl_keep isl_stream *s, __isl_take isl_set *dom, struct vars *v) +{ + isl_pw_aff *pa; + isl_union_pw_aff *upa = NULL; + isl_set *aff_dom; + int n; + + n = v->n; + aff_dom = read_aff_domain(s, isl_set_copy(dom), v); + pa = read_pw_aff_with_dom(s, aff_dom, v); + vars_drop(v, v->n - n); + + upa = isl_union_pw_aff_from_pw_aff(pa); + + while (isl_stream_eat_if_available(s, ';')) { + isl_pw_aff *pa_i; + isl_union_pw_aff *upa_i; + + n = v->n; + aff_dom = read_aff_domain(s, isl_set_copy(dom), v); + pa_i = read_pw_aff_with_dom(s, aff_dom, v); + vars_drop(v, v->n - n); + + upa_i = isl_union_pw_aff_from_pw_aff(pa_i); + upa = isl_union_pw_aff_union_add(upa, upa_i); + } + + isl_set_free(dom); + return upa; +} + +/* Read an isl_union_pw_aff from "s" with parameter domain "dom". + * "v" contains a description of the identifiers parsed so far. + */ +static __isl_give isl_union_pw_aff *isl_stream_read_with_params_union_pw_aff( + __isl_keep isl_stream *s, __isl_keep isl_set *dom, struct vars *v) +{ + return read_union_pw_aff_with_dom(s, isl_set_copy(dom), v); +} + +#undef TYPE_BASE +#define TYPE_BASE union_pw_aff +#include "isl_stream_read_with_params_templ.c" +#include "isl_read_from_str_templ.c" + +/* This function is called for each element in a tuple inside + * isl_stream_read_multi_union_pw_aff. + * + * Read a '{', the union piecewise affine expression body and a '}' and + * add the isl_union_pw_aff to *list. + */ +static __isl_give isl_space *read_union_pw_aff_el(__isl_keep isl_stream *s, + struct vars *v, __isl_take isl_space *space, int rational, void *user) +{ + isl_set *dom; + isl_union_pw_aff *upa; + isl_union_pw_aff_list **list = (isl_union_pw_aff_list **) user; + + dom = isl_set_universe(isl_space_params(isl_space_copy(space))); + if (isl_stream_eat(s, '{')) + goto error; + upa = read_union_pw_aff_with_dom(s, dom, v); + *list = isl_union_pw_aff_list_add(*list, upa); + if (isl_stream_eat(s, '}')) + return isl_space_free(space); + if (!*list) + return isl_space_free(space); + return space; +error: + isl_set_free(dom); + return isl_space_free(space); +} + +/* Do the next tokens in "s" correspond to an empty tuple? + * In particular, does the stream start with a '[', followed by a ']', + * not followed by a "->"? + */ +static int next_is_empty_tuple(__isl_keep isl_stream *s) +{ + struct isl_token *tok, *tok2, *tok3; + int is_empty_tuple = 0; + + tok = isl_stream_next_token(s); + if (!tok) + return 0; + if (tok->type != '[') { + isl_stream_push_token(s, tok); + return 0; + } + + tok2 = isl_stream_next_token(s); + if (tok2 && tok2->type == ']') { + tok3 = isl_stream_next_token(s); + is_empty_tuple = !tok || tok->type != ISL_TOKEN_TO; + if (tok3) + isl_stream_push_token(s, tok3); + } + if (tok2) + isl_stream_push_token(s, tok2); + isl_stream_push_token(s, tok); + + return is_empty_tuple; +} + +/* Do the next tokens in "s" correspond to a tuple of parameters? + * In particular, does the stream start with a '[' that is not + * followed by a '{' or a nested tuple? + */ +static int next_is_param_tuple(__isl_keep isl_stream *s) +{ + struct isl_token *tok, *tok2; + int is_tuple; + + tok = isl_stream_next_token(s); + if (!tok) + return 0; + if (tok->type != '[' || next_is_tuple(s)) { + isl_stream_push_token(s, tok); + return 0; + } + + tok2 = isl_stream_next_token(s); + is_tuple = tok2 && tok2->type != '{'; + if (tok2) + isl_stream_push_token(s, tok2); + isl_stream_push_token(s, tok); + + return is_tuple; +} + +/* Read the core of a body of an isl_multi_union_pw_aff from "s", + * i.e., everything except the parameter specification and + * without shared domain constraints. + * "v" contains a description of the identifiers parsed so far. + * The parameters, if any, are specified by "space". + * + * The body is of the form + * + * [{ [..] : ... ; [..] : ... }, { [..] : ... ; [..] : ... }] + * + * Read the tuple, collecting the individual isl_union_pw_aff + * elements in a list and construct the result from the tuple space and + * the list. + */ +static __isl_give isl_multi_union_pw_aff *read_multi_union_pw_aff_body_core( + __isl_keep isl_stream *s, struct vars *v, __isl_take isl_space *space) +{ + isl_union_pw_aff_list *list; + isl_multi_union_pw_aff *mupa; + + list = isl_union_pw_aff_list_alloc(s->ctx, 0); + space = read_tuple_space(s, v, space, 1, 0, + &read_union_pw_aff_el, &list); + mupa = isl_multi_union_pw_aff_from_union_pw_aff_list(space, list); + + return mupa; +} + +/* Read the body of an isl_union_set from "s", + * i.e., everything except the parameter specification. + * "v" contains a description of the identifiers parsed so far. + * The parameters, if any, are specified by "space". + * + * First read a generic disjunction of object bodies and then try and extract + * an isl_union_set from that. + */ +static __isl_give isl_union_set *read_union_set_body(__isl_keep isl_stream *s, + struct vars *v, __isl_take isl_space *space) +{ + struct isl_obj obj = { isl_obj_set, NULL }; + isl_map *map; + + map = isl_set_universe(space); + if (isl_stream_eat(s, '{') < 0) + goto error; + obj = obj_read_disjuncts(s, v, map); + if (isl_stream_eat(s, '}') < 0) + goto error; + isl_map_free(map); + + return extract_union_set(s->ctx, obj); +error: + obj.type->free(obj.v); + isl_map_free(map); + return NULL; +} + +/* Read the body of an isl_multi_union_pw_aff from "s", + * i.e., everything except the parameter specification. + * "v" contains a description of the identifiers parsed so far. + * The parameters, if any, are specified by "space". + * + * In particular, handle the special case with shared domain constraints. + * These are specified as + * + * ([...] : ...) + * + * and are especially useful for setting the explicit domain + * of a zero-dimensional isl_multi_union_pw_aff. + * The core isl_multi_union_pw_aff body ([...]) is read by + * read_multi_union_pw_aff_body_core. + */ +static __isl_give isl_multi_union_pw_aff *read_multi_union_pw_aff_body( + __isl_keep isl_stream *s, struct vars *v, __isl_take isl_space *space) +{ + isl_multi_union_pw_aff *mupa; + + if (!isl_stream_next_token_is(s, '(')) + return read_multi_union_pw_aff_body_core(s, v, space); + + if (isl_stream_eat(s, '(') < 0) + goto error; + mupa = read_multi_union_pw_aff_body_core(s, v, isl_space_copy(space)); + if (isl_stream_eat_if_available(s, ':')) { + isl_union_set *dom; + + dom = read_union_set_body(s, v, space); + mupa = isl_multi_union_pw_aff_intersect_domain(mupa, dom); + } else { + isl_space_free(space); + } + if (isl_stream_eat(s, ')') < 0) + return isl_multi_union_pw_aff_free(mupa); + + return mupa; +error: + isl_space_free(space); + return NULL; +} + +/* Read an isl_multi_union_pw_aff from "s". + * + * The input has the form + * + * [{ [..] : ... ; [..] : ... }, { [..] : ... ; [..] : ... }] + * + * or + * + * [..] -> [{ [..] : ... ; [..] : ... }, { [..] : ... ; [..] : ... }] + * + * Additionally, a shared domain may be specified as + * + * ([..] : ...) + * + * or + * + * [..] -> ([..] : ...) + * + * The first case is handled by the caller, the second case + * is handled by read_multi_union_pw_aff_body. + * + * We first check for the special case of an empty tuple "[]". + * Then we check if there are any parameters. + * Finally, read the tuple and construct the result. + */ +static __isl_give isl_multi_union_pw_aff *read_multi_union_pw_aff_core( + __isl_keep isl_stream *s) +{ + struct vars *v; + isl_set *dom = NULL; + isl_space *space; + isl_multi_union_pw_aff *mupa = NULL; + + if (next_is_empty_tuple(s)) { + if (isl_stream_eat(s, '[')) + return NULL; + if (isl_stream_eat(s, ']')) + return NULL; + space = isl_space_set_alloc(s->ctx, 0, 0); + return isl_multi_union_pw_aff_zero(space); + } + + v = vars_new(s->ctx); + if (!v) + return NULL; + + dom = isl_set_universe(isl_space_params_alloc(s->ctx, 0)); + if (next_is_param_tuple(s)) { + dom = read_map_tuple(s, dom, isl_dim_param, v, 0); + if (isl_stream_eat(s, ISL_TOKEN_TO)) + goto error; + } + space = isl_set_get_space(dom); + isl_set_free(dom); + mupa = read_multi_union_pw_aff_body(s, v, space); + + vars_free(v); + + return mupa; +error: + vars_free(v); + isl_set_free(dom); + isl_multi_union_pw_aff_free(mupa); + return NULL; +} + +/* Read an isl_multi_union_pw_aff from "s". + * + * In particular, handle the special case with shared domain constraints. + * These are specified as + * + * ([...] : ...) + * + * and are especially useful for setting the explicit domain + * of a zero-dimensional isl_multi_union_pw_aff. + * The core isl_multi_union_pw_aff ([...]) is read by + * read_multi_union_pw_aff_core. + */ +__isl_give isl_multi_union_pw_aff *isl_stream_read_multi_union_pw_aff( + __isl_keep isl_stream *s) +{ + isl_multi_union_pw_aff *mupa; + + if (!isl_stream_next_token_is(s, '(')) + return read_multi_union_pw_aff_core(s); + + if (isl_stream_eat(s, '(') < 0) + return NULL; + mupa = read_multi_union_pw_aff_core(s); + if (isl_stream_eat_if_available(s, ':')) { + isl_union_set *dom; + + dom = isl_stream_read_union_set(s); + mupa = isl_multi_union_pw_aff_intersect_domain(mupa, dom); + } + if (isl_stream_eat(s, ')') < 0) + return isl_multi_union_pw_aff_free(mupa); + return mupa; +} + +#undef TYPE_BASE +#define TYPE_BASE multi_union_pw_aff +#include "isl_read_from_str_templ.c" + +__isl_give isl_union_pw_qpolynomial *isl_stream_read_union_pw_qpolynomial( + __isl_keep isl_stream *s) +{ + struct isl_obj obj; + + obj = obj_read(s); + if (obj.type == isl_obj_pw_qpolynomial) { + obj.type = isl_obj_union_pw_qpolynomial; + obj.v = isl_union_pw_qpolynomial_from_pw_qpolynomial(obj.v); + } + if (obj.v) + isl_assert(s->ctx, obj.type == isl_obj_union_pw_qpolynomial, + goto error); + + return obj.v; +error: + obj.type->free(obj.v); + return NULL; +} + +#undef TYPE_BASE +#define TYPE_BASE union_pw_qpolynomial +#include "isl_read_from_str_templ.c" diff --git a/external/mit/isl/dist/isl_insert_domain_templ.c b/external/mit/isl/dist/isl_insert_domain_templ.c new file mode 100644 index 000000000000..0b88d1c0d857 --- /dev/null +++ b/external/mit/isl/dist/isl_insert_domain_templ.c @@ -0,0 +1,39 @@ +/* + * Copyright 2019 Cerebras Systems + * + * Use of this software is governed by the MIT license + * + * Written by Sven Verdoolaege, + * Cerebras Systems, 175 S San Antonio Rd, Los Altos, CA, USA + */ + +/* Given a function defined over a parameter domain, + * convert it to a function defined over a domain corresponding + * to "domain". + */ +__isl_give TYPE *FN(TYPE,insert_domain)(__isl_take TYPE *obj, + __isl_take isl_space *domain) +{ + isl_size dim; + isl_space *obj_space; + + obj_space = FN(TYPE,peek_space)(obj); + if (isl_space_check_is_set(domain) < 0 || + isl_space_check_is_set(obj_space) < 0) + goto error; + dim = isl_space_dim(domain, isl_dim_set); + if (dim < 0) + goto error; + + domain = isl_space_replace_params(domain, obj_space); + + obj = FN(TYPE,from_range)(obj); + obj = FN(TYPE,add_dims)(obj, isl_dim_in, dim); + obj = FN(TYPE,reset_domain_space)(obj, domain); + + return obj; +error: + isl_space_free(domain); + FN(TYPE,free)(obj); + return NULL; +} diff --git a/external/mit/isl/dist/isl_int.h b/external/mit/isl/dist/isl_int.h new file mode 100644 index 000000000000..07be2bae563b --- /dev/null +++ b/external/mit/isl/dist/isl_int.h @@ -0,0 +1,52 @@ +/* + * 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_INT_H +#define ISL_INT_H +#define ISL_DEPRECATED_INT_H + +#include +#include +#include +#include + +#ifdef USE_GMP_FOR_MP +#include +#endif + +#ifdef USE_IMATH_FOR_MP +#ifdef USE_SMALL_INT_OPT +#include +#else /* USE_SMALL_INT_OPT */ +#include +#endif /* USE_SMALL_INT_OPT */ +#endif /* USE_IMATH_FOR_MP */ + +#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) + +#ifndef USE_SMALL_INT_OPT +#define isl_int_print(out,i,width) \ + do { \ + char *s; \ + s = isl_int_get_str(i); \ + fprintf(out, "%*s", width, s); \ + isl_int_free_str(s); \ + } while (0) +#endif /* USE_SMALL_INT_OPT */ + +__isl_give isl_printer *isl_printer_print_isl_int(__isl_take isl_printer *p, + isl_int i); + +#endif /* ISL_INT_H */ diff --git a/external/mit/isl/dist/isl_int_gmp.h b/external/mit/isl/dist/isl_int_gmp.h new file mode 100644 index 000000000000..3a35e262e641 --- /dev/null +++ b/external/mit/isl/dist/isl_int_gmp.h @@ -0,0 +1,89 @@ +#ifndef ISL_INT_GMP_H +#define ISL_INT_GMP_H + +#include + +/* isl_int is the basic integer type, implemented with GMP's mpz_t. 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_si(r,i) mpz_set_si(r,i) +#define isl_int_set_ui(r,i) mpz_set_ui(r,i) +#define isl_int_fits_slong(r) mpz_fits_slong_p(r) +#define isl_int_get_si(r) mpz_get_si(r) +#define isl_int_fits_ulong(r) mpz_fits_ulong_p(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) +#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_si(r,i,j) mpz_mul_si(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_addmul_ui(r,i,j) mpz_addmul_ui(r,i,j) +#define isl_int_submul(r,i,j) mpz_submul(r,i,j) +#define isl_int_submul_ui(r,i,j) mpz_submul_ui(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_cdiv_q_ui(r,i,j) mpz_cdiv_q_ui(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_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_cmp(i,j) mpz_cmpabs(i,j) +#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_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) + +#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 + +typedef void (*isl_int_print_mp_free_t)(void *, size_t); +#define isl_int_free_str(s) \ + do { \ + isl_int_print_mp_free_t mp_free; \ + mp_get_memory_functions(NULL, NULL, &mp_free); \ + (*mp_free)(s, strlen(s) + 1); \ + } while (0) + +#endif /* ISL_INT_GMP_H */ diff --git a/external/mit/isl/dist/isl_int_imath.h b/external/mit/isl/dist/isl_int_imath.h new file mode 100644 index 000000000000..ed314b65460d --- /dev/null +++ b/external/mit/isl/dist/isl_int_imath.h @@ -0,0 +1,75 @@ +#ifndef ISL_INT_IMATH_H +#define ISL_INT_IMATH_H + +#include + +/* isl_int is the basic integer type, implemented with imath's mp_int. */ +typedef mp_int isl_int; + +#define isl_int_init(i) i = mp_int_alloc() +#define isl_int_clear(i) mp_int_free(i) + +#define isl_int_set(r,i) impz_set(r,i) +#define isl_int_set_si(r,i) impz_set_si(r,i) +#define isl_int_set_ui(r,i) impz_set_ui(r,i) +#define isl_int_fits_slong(r) isl_imath_fits_slong_p(r) +#define isl_int_get_si(r) impz_get_si(r) +#define isl_int_fits_ulong(r) isl_imath_fits_ulong_p(r) +#define isl_int_get_ui(r) impz_get_ui(r) +#define isl_int_get_d(r) impz_get_si(r) +#define isl_int_get_str(r) impz_get_str(0, 10, r) +#define isl_int_abs(r,i) impz_abs(r,i) +#define isl_int_neg(r,i) impz_neg(r,i) +#define isl_int_swap(i,j) impz_swap(i,j) +#define isl_int_swap_or_set(i,j) impz_swap(i,j) +#define isl_int_add_ui(r,i,j) impz_add_ui(r,i,j) +#define isl_int_sub_ui(r,i,j) impz_sub_ui(r,i,j) + +#define isl_int_add(r,i,j) impz_add(r,i,j) +#define isl_int_sub(r,i,j) impz_sub(r,i,j) +#define isl_int_mul(r,i,j) impz_mul(r,i,j) +#define isl_int_mul_2exp(r,i,j) impz_mul_2exp(r,i,j) +#define isl_int_mul_si(r,i,j) mp_int_mul_value(i,j,r) +#define isl_int_mul_ui(r,i,j) impz_mul_ui(r,i,j) +#define isl_int_pow_ui(r,i,j) impz_pow_ui(r,i,j) +#define isl_int_addmul(r,i,j) impz_addmul(r,i,j) +#define isl_int_addmul_ui(r,i,j) isl_imath_addmul_ui(r,i,j) +#define isl_int_submul(r,i,j) impz_submul(r,i,j) +#define isl_int_submul_ui(r,i,j) isl_imath_submul_ui(r,i,j) + +#define isl_int_gcd(r,i,j) impz_gcd(r,i,j) +#define isl_int_lcm(r,i,j) impz_lcm(r,i,j) +#define isl_int_divexact(r,i,j) impz_divexact(r,i,j) +#define isl_int_divexact_ui(r,i,j) impz_divexact_ui(r,i,j) +#define isl_int_tdiv_q(r,i,j) impz_tdiv_q(r,i,j) +#define isl_int_cdiv_q(r,i,j) impz_cdiv_q(r,i,j) +#define isl_int_cdiv_q_ui(r,i,j) isl_imath_cdiv_q_ui(r,i,j) +#define isl_int_fdiv_q(r,i,j) impz_fdiv_q(r,i,j) +#define isl_int_fdiv_r(r,i,j) impz_fdiv_r(r,i,j) +#define isl_int_fdiv_q_ui(r,i,j) isl_imath_fdiv_q_ui(r,i,j) + +#define isl_int_read(r,s) impz_set_str(r,s,10) +#define isl_int_sgn(i) impz_sgn(i) +#define isl_int_cmp(i,j) impz_cmp(i,j) +#define isl_int_cmp_si(i,si) impz_cmp_si(i,si) +#define isl_int_eq(i,j) (impz_cmp(i,j) == 0) +#define isl_int_ne(i,j) (impz_cmp(i,j) != 0) +#define isl_int_lt(i,j) (impz_cmp(i,j) < 0) +#define isl_int_le(i,j) (impz_cmp(i,j) <= 0) +#define isl_int_gt(i,j) (impz_cmp(i,j) > 0) +#define isl_int_ge(i,j) (impz_cmp(i,j) >= 0) +#define isl_int_abs_cmp(i,j) impz_cmpabs(i,j) +#define isl_int_abs_eq(i,j) (impz_cmpabs(i,j) == 0) +#define isl_int_abs_ne(i,j) (impz_cmpabs(i,j) != 0) +#define isl_int_abs_lt(i,j) (impz_cmpabs(i,j) < 0) +#define isl_int_abs_gt(i,j) (impz_cmpabs(i,j) > 0) +#define isl_int_abs_ge(i,j) (impz_cmpabs(i,j) >= 0) +#define isl_int_is_divisible_by(i,j) impz_divisible_p(i,j) + +uint32_t isl_imath_hash(mp_int v, uint32_t hash); +#define isl_int_hash(v,h) isl_imath_hash(v,h) + +typedef void (*isl_int_print_mp_free_t)(void *, size_t); +#define isl_int_free_str(s) free(s) + +#endif /* ISL_INT_IMATH_H */ diff --git a/external/mit/isl/dist/isl_int_sioimath.c b/external/mit/isl/dist/isl_int_sioimath.c new file mode 100644 index 000000000000..170286213c6a --- /dev/null +++ b/external/mit/isl/dist/isl_int_sioimath.c @@ -0,0 +1,223 @@ +#include +#include + +#include + +extern int isl_sioimath_decode(isl_sioimath val, int32_t *small, mp_int *big); +extern int isl_sioimath_decode_big(isl_sioimath val, mp_int *big); +extern int isl_sioimath_decode_small(isl_sioimath val, int32_t *small); + +extern isl_sioimath isl_sioimath_encode_small(int32_t val); +extern isl_sioimath isl_sioimath_encode_big(mp_int val); +extern int isl_sioimath_is_small(isl_sioimath val); +extern int isl_sioimath_is_big(isl_sioimath val); +extern int32_t isl_sioimath_get_small(isl_sioimath val); +extern mp_int isl_sioimath_get_big(isl_sioimath val); + +extern void isl_siomath_uint32_to_digits(uint32_t num, mp_digit *digits, + mp_size *used); +extern void isl_siomath_ulong_to_digits(unsigned long num, mp_digit *digits, + mp_size *used); +extern void isl_siomath_uint64_to_digits(uint64_t num, mp_digit *digits, + mp_size *used); + +extern mp_int isl_sioimath_bigarg_src(isl_sioimath arg, + isl_sioimath_scratchspace_t *scratch); +extern mp_int isl_sioimath_siarg_src(signed long arg, + isl_sioimath_scratchspace_t *scratch); +extern mp_int isl_sioimath_si64arg_src(int64_t arg, + isl_sioimath_scratchspace_t *scratch); +extern mp_int isl_sioimath_uiarg_src(unsigned long arg, + isl_sioimath_scratchspace_t *scratch); +extern mp_int isl_sioimath_reinit_big(isl_sioimath_ptr ptr); +extern void isl_sioimath_set_small(isl_sioimath_ptr ptr, int32_t val); +extern void isl_sioimath_set_int32(isl_sioimath_ptr ptr, int32_t val); +extern void isl_sioimath_set_int64(isl_sioimath_ptr ptr, int64_t val); +extern void isl_sioimath_promote(isl_sioimath_ptr dst); +extern void isl_sioimath_try_demote(isl_sioimath_ptr dst); + +extern void isl_sioimath_init(isl_sioimath_ptr dst); +extern void isl_sioimath_clear(isl_sioimath_ptr dst); +extern void isl_sioimath_set(isl_sioimath_ptr dst, isl_sioimath_src val); +extern void isl_sioimath_set_si(isl_sioimath_ptr dst, long val); +extern void isl_sioimath_set_ui(isl_sioimath_ptr dst, unsigned long val); +extern int isl_sioimath_fits_slong(isl_sioimath_src val); +extern long isl_sioimath_get_si(isl_sioimath_src val); +extern int isl_sioimath_fits_ulong(isl_sioimath_src val); +extern unsigned long isl_sioimath_get_ui(isl_sioimath_src val); +extern double isl_sioimath_get_d(isl_sioimath_src val); +extern char *isl_sioimath_get_str(isl_sioimath_src val); +extern void isl_sioimath_abs(isl_sioimath_ptr dst, isl_sioimath_src arg); +extern void isl_sioimath_neg(isl_sioimath_ptr dst, isl_sioimath_src arg); +extern void isl_sioimath_swap(isl_sioimath_ptr lhs, isl_sioimath_ptr rhs); +extern void isl_sioimath_add_ui(isl_sioimath_ptr dst, isl_sioimath lhs, + unsigned long rhs); +extern void isl_sioimath_sub_ui(isl_sioimath_ptr dst, isl_sioimath lhs, + unsigned long rhs); + +extern void isl_sioimath_add(isl_sioimath_ptr dst, isl_sioimath_src lhs, + isl_sioimath_src rhs); +extern void isl_sioimath_sub(isl_sioimath_ptr dst, isl_sioimath_src lhs, + isl_sioimath_src rhs); +extern void isl_sioimath_mul(isl_sioimath_ptr dst, isl_sioimath_src lhs, + isl_sioimath_src rhs); +extern void isl_sioimath_mul_2exp(isl_sioimath_ptr dst, isl_sioimath lhs, + unsigned long rhs); +extern void isl_sioimath_mul_si(isl_sioimath_ptr dst, isl_sioimath lhs, + signed long rhs); +extern void isl_sioimath_mul_ui(isl_sioimath_ptr dst, isl_sioimath lhs, + unsigned long rhs); +extern void isl_sioimath_pow_ui(isl_sioimath_ptr dst, isl_sioimath_src lhs, + unsigned long rhs); +extern void isl_sioimath_addmul(isl_sioimath_ptr dst, isl_sioimath_src lhs, + isl_sioimath_src rhs); +extern void isl_sioimath_addmul_ui(isl_sioimath_ptr dst, isl_sioimath_src lhs, + unsigned long rhs); +extern void isl_sioimath_submul(isl_sioimath_ptr dst, isl_sioimath_src lhs, + isl_sioimath_src rhs); +extern void isl_sioimath_submul_ui(isl_sioimath_ptr dst, isl_sioimath_src lhs, + unsigned long rhs); + +/* Implements the Euclidean algorithm to compute the greatest common divisor of + * two values in small representation. + */ +static uint32_t isl_sioimath_smallgcd(int32_t lhs, int32_t rhs) +{ + uint32_t dividend, divisor, remainder; + + dividend = labs(lhs); + divisor = labs(rhs); + while (divisor) { + remainder = dividend % divisor; + dividend = divisor; + divisor = remainder; + } + + return dividend; +} + +/* Compute the greatest common divisor. + * + * Per GMP convention, gcd(0,0)==0 and otherwise always positive. + */ +void isl_sioimath_gcd(isl_sioimath_ptr dst, isl_sioimath_src lhs, + isl_sioimath_src rhs) +{ + int32_t lhssmall, rhssmall; + uint32_t smallgcd; + isl_sioimath_scratchspace_t scratchlhs, scratchrhs; + + if (isl_sioimath_decode_small(lhs, &lhssmall) && + isl_sioimath_decode_small(rhs, &rhssmall)) { + smallgcd = isl_sioimath_smallgcd(lhssmall, rhssmall); + isl_sioimath_set_small(dst, smallgcd); + return; + } + + impz_gcd(isl_sioimath_reinit_big(dst), + isl_sioimath_bigarg_src(lhs, &scratchlhs), + isl_sioimath_bigarg_src(rhs, &scratchrhs)); + isl_sioimath_try_demote(dst); +} + +/* Compute the lowest common multiple of two numbers. + */ +void isl_sioimath_lcm(isl_sioimath_ptr dst, isl_sioimath_src lhs, + isl_sioimath_src rhs) +{ + int32_t lhssmall, rhssmall; + uint32_t smallgcd; + uint64_t multiple; + isl_sioimath_scratchspace_t scratchlhs, scratchrhs; + + if (isl_sioimath_decode_small(lhs, &lhssmall) && + isl_sioimath_decode_small(rhs, &rhssmall)) { + if (lhssmall == 0 || rhssmall == 0) { + isl_sioimath_set_small(dst, 0); + return; + } + smallgcd = isl_sioimath_smallgcd(lhssmall, rhssmall); + multiple = (uint64_t) abs(lhssmall) * (uint64_t) abs(rhssmall); + isl_sioimath_set_int64(dst, multiple / smallgcd); + return; + } + + impz_lcm(isl_sioimath_reinit_big(dst), + isl_sioimath_bigarg_src(lhs, &scratchlhs), + isl_sioimath_bigarg_src(rhs, &scratchrhs)); + isl_sioimath_try_demote(dst); +} + +extern void isl_sioimath_tdiv_q(isl_sioimath_ptr dst, isl_sioimath_src lhs, + isl_sioimath_src rhs); +extern void isl_sioimath_tdiv_q_ui(isl_sioimath_ptr dst, isl_sioimath_src lhs, + unsigned long rhs); +extern void isl_sioimath_cdiv_q(isl_sioimath_ptr dst, isl_sioimath_src lhs, + isl_sioimath_src rhs); +extern void isl_sioimath_cdiv_q_ui(isl_sioimath_ptr dst, isl_sioimath_src lhs, + unsigned long rhs); +extern void isl_sioimath_fdiv_q(isl_sioimath_ptr dst, isl_sioimath_src lhs, + isl_sioimath_src rhs); +extern void isl_sioimath_fdiv_q_ui(isl_sioimath_ptr dst, isl_sioimath_src lhs, + unsigned long rhs); +extern void isl_sioimath_fdiv_r(isl_sioimath_ptr dst, isl_sioimath_src lhs, + isl_sioimath_src rhs); + +/* Parse a number from a string. + * If it has less than 10 characters then it will fit into the small + * representation (i.e. strlen("2147483647")). Otherwise, let IMath parse it. + */ +void isl_sioimath_read(isl_sioimath_ptr dst, const char *str) +{ + int32_t small; + + if (strlen(str) < 10) { + small = strtol(str, NULL, 10); + isl_sioimath_set_small(dst, small); + return; + } + + mp_int_read_string(isl_sioimath_reinit_big(dst), 10, str); + isl_sioimath_try_demote(dst); +} + +extern int isl_sioimath_sgn(isl_sioimath_src arg); +extern int isl_sioimath_cmp(isl_sioimath_src lhs, isl_sioimath_src rhs); +extern int isl_sioimath_cmp_si(isl_sioimath_src lhs, signed long rhs); +extern int isl_sioimath_abs_cmp(isl_sioimath_src lhs, isl_sioimath_src rhs); +extern int isl_sioimath_is_divisible_by(isl_sioimath_src lhs, + isl_sioimath_src rhs); + +extern uint32_t isl_sioimath_hash(isl_sioimath_src arg, uint32_t hash); +extern size_t isl_sioimath_sizeinbase(isl_sioimath_src arg, int base); +extern void isl_sioimath_print(FILE *out, isl_sioimath_src i, int width); + +/* Print an isl_int to FILE*. Adds space padding to the left until at least + * width characters are printed. + */ +void isl_sioimath_print(FILE *out, isl_sioimath_src i, int width) +{ + size_t len; + int32_t small; + mp_int big; + char *buf; + + if (isl_sioimath_decode_small(i, &small)) { + fprintf(out, "%*" PRIi32, width, small); + return; + } + + big = isl_sioimath_get_big(i); + len = mp_int_string_len(big, 10); + buf = malloc(len); + mp_int_to_string(big, 10, buf, len); + fprintf(out, "%*s", width, buf); + free(buf); +} + +/* Print a number to stdout. Meant for debugging. + */ +void isl_sioimath_dump(isl_sioimath_src arg) +{ + isl_sioimath_print(stdout, arg, 0); +} diff --git a/external/mit/isl/dist/isl_int_sioimath.h b/external/mit/isl/dist/isl_int_sioimath.h new file mode 100644 index 000000000000..a2112cd8e2fb --- /dev/null +++ b/external/mit/isl/dist/isl_int_sioimath.h @@ -0,0 +1,1254 @@ +/* + * Copyright 2015 INRIA Paris-Rocquencourt + * + * Use of this software is governed by the MIT license + * + * Written by Michael Kruse, INRIA Paris-Rocquencourt, + * Domaine de Voluceau, Rocquenqourt, B.P. 105, + * 78153 Le Chesnay Cedex France + */ +#ifndef ISL_INT_SIOIMATH_H +#define ISL_INT_SIOIMATH_H + +#include +#include +#include +#include + +#include +#include + +#define ARRAY_SIZE(array) (sizeof(array)/sizeof(*array)) + +/* Visual Studio before VS2015 does not support the inline keyword when + * compiling in C mode because it was introduced in C99 which it does not + * officially support. Instead, it has a proprietary extension using __inline. + */ +#if defined(_MSC_VER) && (_MSC_VER < 1900) +#define inline __inline +#endif + +/* The type to represent integers optimized for small values. It is either a + * pointer to an mp_int ( = mpz_t*; big representation) or an int32_t (small + * represenation) with a discriminator at the least significant bit. In big + * representation it will be always zero because of heap alignment. It is set + * to 1 for small representation and use the 32 most significant bits for the + * int32_t. + * + * Structure on 64 bit machines, with 8-byte aligment (3 bits): + * + * Big representation: + * MSB LSB + * |------------------------------------------------------------000 + * | mpz_t* | + * | != NULL | + * + * Small representation: + * MSB 32 LSB + * |------------------------------|00000000000000000000000000000001 + * | int32_t | + * | 2147483647 ... -2147483647 | + * ^ + * | + * discriminator bit + * + * On 32 bit machines isl_sioimath type is blown up to 8 bytes, i.e. + * isl_sioimath is guaranteed to be at least 8 bytes. This is to ensure the + * int32_t can be hidden in that type without data loss. In the future we might + * optimize this to use 31 hidden bits in a 32 bit pointer. We may also use 63 + * bits on 64 bit machines, but this comes with the cost of additional overflow + * checks because there is no standardized 128 bit integer we could expand to. + * + * We use native integer types and avoid union structures to avoid assumptions + * on the machine's endianness. + * + * This implementation makes the following assumptions: + * - long can represent any int32_t + * - mp_small is signed long + * - mp_usmall is unsigned long + * - adresses returned by malloc are aligned to 2-byte boundaries (leastmost + * bit is zero) + */ +#if UINT64_MAX > UINTPTR_MAX +typedef uint64_t isl_sioimath; +#else +typedef uintptr_t isl_sioimath; +#endif + +/* The negation of the smallest possible number in int32_t, INT32_MIN + * (0x80000000u, -2147483648), cannot be represented in an int32_t, therefore + * every operation that may produce this value needs to special-case it. + * The operations are: + * abs(INT32_MIN) + * -INT32_MIN (negation) + * -1 * INT32_MIN (multiplication) + * INT32_MIN/-1 (any division: divexact, fdiv, cdiv, tdiv) + * To avoid checking these cases, we exclude INT32_MIN from small + * representation. + */ +#define ISL_SIOIMATH_SMALL_MIN (-INT32_MAX) + +/* Largest possible number in small representation */ +#define ISL_SIOIMATH_SMALL_MAX INT32_MAX + +/* Used for function parameters the function modifies. */ +typedef isl_sioimath *isl_sioimath_ptr; + +/* Used for function parameters that are read-only. */ +typedef isl_sioimath isl_sioimath_src; + +/* Return whether the argument is stored in small representation. + */ +inline int isl_sioimath_is_small(isl_sioimath val) +{ + return val & 0x00000001; +} + +/* Return whether the argument is stored in big representation. + */ +inline int isl_sioimath_is_big(isl_sioimath val) +{ + return !isl_sioimath_is_small(val); +} + +/* Get the number of an isl_int in small representation. Result is undefined if + * val is not stored in that format. + */ +inline int32_t isl_sioimath_get_small(isl_sioimath val) +{ + return val >> 32; +} + +/* Get the number of an in isl_int in big representation. Result is undefined if + * val is not stored in that format. + */ +inline mp_int isl_sioimath_get_big(isl_sioimath val) +{ + return (mp_int)(uintptr_t) val; +} + +/* Return 1 if val is stored in small representation and store its value to + * small. We rely on the compiler to optimize the isl_sioimath_get_small such + * that the shift is moved into the branch that executes in case of small + * representation. If there is no such branch, then a single shift is still + * cheaper than introducing branching code. + */ +inline int isl_sioimath_decode_small(isl_sioimath val, int32_t *small) +{ + *small = isl_sioimath_get_small(val); + return isl_sioimath_is_small(val); +} + +/* Return 1 if val is stored in big representation and store its value to big. + */ +inline int isl_sioimath_decode_big(isl_sioimath val, mp_int *big) +{ + *big = isl_sioimath_get_big(val); + return isl_sioimath_is_big(val); +} + +/* Encode a small representation into an isl_int. + */ +inline isl_sioimath isl_sioimath_encode_small(int32_t val) +{ + return ((isl_sioimath) val) << 32 | 0x00000001; +} + +/* Encode a big representation. + */ +inline isl_sioimath isl_sioimath_encode_big(mp_int val) +{ + return (isl_sioimath)(uintptr_t) val; +} + +/* A common situation is to call an IMath function with at least one argument + * that is currently in small representation or an integer parameter, i.e. a big + * representation of the same number is required. Promoting the original + * argument comes with multiple problems, such as modifying a read-only + * argument, the responsibility of deallocation and the execution cost. Instead, + * we make a copy by 'faking' the IMath internal structure. + * + * We reserve the maximum number of required digits on the stack to avoid heap + * allocations. + * + * mp_digit can be uint32_t or uint16_t. This code must work for little and big + * endian digits. The structure for an uint64_t argument and 32-bit mp_digits is + * sketched below. + * + * |----------------------------| + * uint64_t + * + * |-------------||-------------| + * mp_digit mp_digit + * digits[1] digits[0] + * Most sig digit Least sig digit + */ +typedef struct { + mpz_t big; + mp_digit digits[(sizeof(uintmax_t) + sizeof(mp_digit) - 1) / + sizeof(mp_digit)]; +} isl_sioimath_scratchspace_t; + +/* Convert a native integer to IMath's digit representation. A native integer + * might be big- or little endian, but IMath always stores the least significant + * digit in the lowest array indices. memcpy therefore is not possible. + * + * We also have to consider that long and mp_digit can be of different sizes, + * depending on the compiler (LP64, LLP64) and IMath's USE_64BIT_WORDS. This + * macro should work for all of them. + * + * "used" is set to the number of written digits. It must be minimal (IMath + * checks zeroness using the used field), but always at least one. Also note + * that the result of num>>(sizeof(num)*CHAR_BIT) is undefined. + */ +#define ISL_SIOIMATH_TO_DIGITS(num, digits, used) \ + do { \ + int i = 0; \ + do { \ + (digits)[i] = \ + ((num) >> (sizeof(mp_digit) * CHAR_BIT * i)); \ + i += 1; \ + if (i >= (sizeof(num) + sizeof(mp_digit) - 1) / \ + sizeof(mp_digit)) \ + break; \ + if (((num) >> (sizeof(mp_digit) * CHAR_BIT * i)) == 0) \ + break; \ + } while (1); \ + (used) = i; \ + } while (0) + +inline void isl_siomath_uint32_to_digits(uint32_t num, mp_digit *digits, + mp_size *used) +{ + ISL_SIOIMATH_TO_DIGITS(num, digits, *used); +} + +inline void isl_siomath_ulong_to_digits(unsigned long num, mp_digit *digits, + mp_size *used) +{ + ISL_SIOIMATH_TO_DIGITS(num, digits, *used); +} + +inline void isl_siomath_uint64_to_digits(uint64_t num, mp_digit *digits, + mp_size *used) +{ + ISL_SIOIMATH_TO_DIGITS(num, digits, *used); +} + +/* Get the IMath representation of an isl_int without modifying it. + * For the case it is not in big representation yet, pass some scratch space we + * can use to store the big representation in. + * In order to avoid requiring init and free on the scratch space, we directly + * modify the internal representation. + * + * The name derives from its indented use: getting the big representation of an + * input (src) argument. + */ +inline mp_int isl_sioimath_bigarg_src(isl_sioimath arg, + isl_sioimath_scratchspace_t *scratch) +{ + mp_int big; + int32_t small; + uint32_t num; + + if (isl_sioimath_decode_big(arg, &big)) + return big; + + small = isl_sioimath_get_small(arg); + scratch->big.digits = scratch->digits; + scratch->big.alloc = ARRAY_SIZE(scratch->digits); + if (small >= 0) { + scratch->big.sign = MP_ZPOS; + num = small; + } else { + scratch->big.sign = MP_NEG; + num = -small; + } + + isl_siomath_uint32_to_digits(num, scratch->digits, &scratch->big.used); + return &scratch->big; +} + +/* Create a temporary IMath mp_int for a signed long. + */ +inline mp_int isl_sioimath_siarg_src(signed long arg, + isl_sioimath_scratchspace_t *scratch) +{ + unsigned long num; + + scratch->big.digits = scratch->digits; + scratch->big.alloc = ARRAY_SIZE(scratch->digits); + if (arg >= 0) { + scratch->big.sign = MP_ZPOS; + num = arg; + } else { + scratch->big.sign = MP_NEG; + num = (arg == LONG_MIN) ? ((unsigned long) LONG_MAX) + 1 : -arg; + } + + isl_siomath_ulong_to_digits(num, scratch->digits, &scratch->big.used); + return &scratch->big; +} + +/* Create a temporary IMath mp_int for an int64_t. + */ +inline mp_int isl_sioimath_si64arg_src(int64_t arg, + isl_sioimath_scratchspace_t *scratch) +{ + uint64_t num; + + scratch->big.digits = scratch->digits; + scratch->big.alloc = ARRAY_SIZE(scratch->digits); + if (arg >= 0) { + scratch->big.sign = MP_ZPOS; + num = arg; + } else { + scratch->big.sign = MP_NEG; + num = (arg == INT64_MIN) ? ((uint64_t) INT64_MAX) + 1 : -arg; + } + + isl_siomath_uint64_to_digits(num, scratch->digits, &scratch->big.used); + return &scratch->big; +} + +/* Create a temporary IMath mp_int for an unsigned long. + */ +inline mp_int isl_sioimath_uiarg_src(unsigned long arg, + isl_sioimath_scratchspace_t *scratch) +{ + scratch->big.digits = scratch->digits; + scratch->big.alloc = ARRAY_SIZE(scratch->digits); + scratch->big.sign = MP_ZPOS; + + isl_siomath_ulong_to_digits(arg, scratch->digits, &scratch->big.used); + return &scratch->big; +} + +/* Ensure big representation. Does not preserve the current number. + * Callers may use the fact that the value _is_ preserved if the presentation + * was big before. + */ +inline mp_int isl_sioimath_reinit_big(isl_sioimath_ptr ptr) +{ + if (isl_sioimath_is_small(*ptr)) + *ptr = isl_sioimath_encode_big(mp_int_alloc()); + return isl_sioimath_get_big(*ptr); +} + +/* Set ptr to a number in small representation. + */ +inline void isl_sioimath_set_small(isl_sioimath_ptr ptr, int32_t val) +{ + if (isl_sioimath_is_big(*ptr)) + mp_int_free(isl_sioimath_get_big(*ptr)); + *ptr = isl_sioimath_encode_small(val); +} + +/* Set ptr to val, choosing small representation if possible. + */ +inline void isl_sioimath_set_int32(isl_sioimath_ptr ptr, int32_t val) +{ + if (ISL_SIOIMATH_SMALL_MIN <= val && val <= ISL_SIOIMATH_SMALL_MAX) { + isl_sioimath_set_small(ptr, val); + return; + } + + mp_int_init_value(isl_sioimath_reinit_big(ptr), val); +} + +/* Assign an int64_t number using small representation if possible. + */ +inline void isl_sioimath_set_int64(isl_sioimath_ptr ptr, int64_t val) +{ + if (ISL_SIOIMATH_SMALL_MIN <= val && val <= ISL_SIOIMATH_SMALL_MAX) { + isl_sioimath_set_small(ptr, val); + return; + } + + isl_sioimath_scratchspace_t scratch; + mp_int_copy(isl_sioimath_si64arg_src(val, &scratch), + isl_sioimath_reinit_big(ptr)); +} + +/* Convert to big representation while preserving the current number. + */ +inline void isl_sioimath_promote(isl_sioimath_ptr dst) +{ + int32_t small; + + if (isl_sioimath_is_big(*dst)) + return; + + small = isl_sioimath_get_small(*dst); + mp_int_set_value(isl_sioimath_reinit_big(dst), small); +} + +/* Convert to small representation while preserving the current number. Does + * nothing if dst doesn't fit small representation. + */ +inline void isl_sioimath_try_demote(isl_sioimath_ptr dst) +{ + mp_small small; + + if (isl_sioimath_is_small(*dst)) + return; + + if (mp_int_to_int(isl_sioimath_get_big(*dst), &small) != MP_OK) + return; + + if (ISL_SIOIMATH_SMALL_MIN <= small && small <= ISL_SIOIMATH_SMALL_MAX) + isl_sioimath_set_small(dst, small); +} + +/* Initialize an isl_int. The implicit value is 0 in small representation. + */ +inline void isl_sioimath_init(isl_sioimath_ptr dst) +{ + *dst = isl_sioimath_encode_small(0); +} + +/* Free the resources taken by an isl_int. + */ +inline void isl_sioimath_clear(isl_sioimath_ptr dst) +{ + if (isl_sioimath_is_small(*dst)) + return; + + mp_int_free(isl_sioimath_get_big(*dst)); +} + +/* Copy the value of one isl_int to another. + */ +inline void isl_sioimath_set(isl_sioimath_ptr dst, isl_sioimath_src val) +{ + if (isl_sioimath_is_small(val)) { + isl_sioimath_set_small(dst, isl_sioimath_get_small(val)); + return; + } + + mp_int_copy(isl_sioimath_get_big(val), isl_sioimath_reinit_big(dst)); +} + +/* Store a signed long into an isl_int. + */ +inline void isl_sioimath_set_si(isl_sioimath_ptr dst, long val) +{ + if (ISL_SIOIMATH_SMALL_MIN <= val && val <= ISL_SIOIMATH_SMALL_MAX) { + isl_sioimath_set_small(dst, val); + return; + } + + mp_int_set_value(isl_sioimath_reinit_big(dst), val); +} + +/* Store an unsigned long into an isl_int. + */ +inline void isl_sioimath_set_ui(isl_sioimath_ptr dst, unsigned long val) +{ + if (val <= ISL_SIOIMATH_SMALL_MAX) { + isl_sioimath_set_small(dst, val); + return; + } + + mp_int_set_uvalue(isl_sioimath_reinit_big(dst), val); +} + +/* Return whether a number can be represented by a signed long. + */ +inline int isl_sioimath_fits_slong(isl_sioimath_src val) +{ + mp_small dummy; + + if (isl_sioimath_is_small(val)) + return 1; + + return mp_int_to_int(isl_sioimath_get_big(val), &dummy) == MP_OK; +} + +/* Return a number as signed long. Result is undefined if the number cannot be + * represented as long. + */ +inline long isl_sioimath_get_si(isl_sioimath_src val) +{ + mp_small result; + + if (isl_sioimath_is_small(val)) + return isl_sioimath_get_small(val); + + mp_int_to_int(isl_sioimath_get_big(val), &result); + return result; +} + +/* Return whether a number can be represented as unsigned long. + */ +inline int isl_sioimath_fits_ulong(isl_sioimath_src val) +{ + mp_usmall dummy; + + if (isl_sioimath_is_small(val)) + return isl_sioimath_get_small(val) >= 0; + + return mp_int_to_uint(isl_sioimath_get_big(val), &dummy) == MP_OK; +} + +/* Return a number as unsigned long. Result is undefined if the number cannot be + * represented as unsigned long. + */ +inline unsigned long isl_sioimath_get_ui(isl_sioimath_src val) +{ + mp_usmall result; + + if (isl_sioimath_is_small(val)) + return isl_sioimath_get_small(val); + + mp_int_to_uint(isl_sioimath_get_big(val), &result); + return result; +} + +/* Return a number as floating point value. + */ +inline double isl_sioimath_get_d(isl_sioimath_src val) +{ + mp_int big; + double result = 0; + int i; + + if (isl_sioimath_is_small(val)) + return isl_sioimath_get_small(val); + + big = isl_sioimath_get_big(val); + for (i = 0; i < big->used; ++i) + result = result * (double) ((uintmax_t) MP_DIGIT_MAX + 1) + + (double) big->digits[i]; + + if (big->sign == MP_NEG) + result = -result; + + return result; +} + +/* Format a number as decimal string. + * + * The largest possible string from small representation is 12 characters + * ("-2147483647"). + */ +inline char *isl_sioimath_get_str(isl_sioimath_src val) +{ + char *result; + + if (isl_sioimath_is_small(val)) { + result = malloc(12); + snprintf(result, 12, "%" PRIi32, isl_sioimath_get_small(val)); + return result; + } + + return impz_get_str(NULL, 10, isl_sioimath_get_big(val)); +} + +/* Return the absolute value. + */ +inline void isl_sioimath_abs(isl_sioimath_ptr dst, isl_sioimath_src arg) +{ + if (isl_sioimath_is_small(arg)) { + isl_sioimath_set_small(dst, labs(isl_sioimath_get_small(arg))); + return; + } + + mp_int_abs(isl_sioimath_get_big(arg), isl_sioimath_reinit_big(dst)); +} + +/* Return the negation of a number. + */ +inline void isl_sioimath_neg(isl_sioimath_ptr dst, isl_sioimath_src arg) +{ + if (isl_sioimath_is_small(arg)) { + isl_sioimath_set_small(dst, -isl_sioimath_get_small(arg)); + return; + } + + mp_int_neg(isl_sioimath_get_big(arg), isl_sioimath_reinit_big(dst)); +} + +/* Swap two isl_ints. + * + * isl_sioimath can be copied bytewise; nothing depends on its address. It can + * also be stored in a CPU register. + */ +inline void isl_sioimath_swap(isl_sioimath_ptr lhs, isl_sioimath_ptr rhs) +{ + isl_sioimath tmp = *lhs; + *lhs = *rhs; + *rhs = tmp; +} + +/* Add an unsigned long to the number. + * + * On LP64 unsigned long exceeds the range of an int64_t, therefore we check in + * advance whether small representation possibly overflows. + */ +inline void isl_sioimath_add_ui(isl_sioimath_ptr dst, isl_sioimath lhs, + unsigned long rhs) +{ + int32_t smalllhs; + isl_sioimath_scratchspace_t lhsscratch; + + if (isl_sioimath_decode_small(lhs, &smalllhs) && + (rhs <= (uint64_t) INT64_MAX - (uint64_t) ISL_SIOIMATH_SMALL_MAX)) { + isl_sioimath_set_int64(dst, (int64_t) smalllhs + rhs); + return; + } + + impz_add_ui(isl_sioimath_reinit_big(dst), + isl_sioimath_bigarg_src(lhs, &lhsscratch), rhs); + isl_sioimath_try_demote(dst); +} + +/* Subtract an unsigned long. + * + * On LP64 unsigned long exceeds the range of an int64_t. If + * ISL_SIOIMATH_SMALL_MIN-rhs>=INT64_MIN we can do the calculation using int64_t + * without risking an overflow. + */ +inline void isl_sioimath_sub_ui(isl_sioimath_ptr dst, isl_sioimath lhs, + unsigned long rhs) +{ + int32_t smalllhs; + isl_sioimath_scratchspace_t lhsscratch; + + if (isl_sioimath_decode_small(lhs, &smalllhs) && + (rhs < (uint64_t) INT64_MIN - (uint64_t) ISL_SIOIMATH_SMALL_MIN)) { + isl_sioimath_set_int64(dst, (int64_t) smalllhs - rhs); + return; + } + + impz_sub_ui(isl_sioimath_reinit_big(dst), + isl_sioimath_bigarg_src(lhs, &lhsscratch), rhs); + isl_sioimath_try_demote(dst); +} + +/* Sum of two isl_ints. + */ +inline void isl_sioimath_add(isl_sioimath_ptr dst, isl_sioimath_src lhs, + isl_sioimath_src rhs) +{ + isl_sioimath_scratchspace_t scratchlhs, scratchrhs; + int32_t smalllhs, smallrhs; + + if (isl_sioimath_decode_small(lhs, &smalllhs) && + isl_sioimath_decode_small(rhs, &smallrhs)) { + isl_sioimath_set_int64( + dst, (int64_t) smalllhs + (int64_t) smallrhs); + return; + } + + mp_int_add(isl_sioimath_bigarg_src(lhs, &scratchlhs), + isl_sioimath_bigarg_src(rhs, &scratchrhs), + isl_sioimath_reinit_big(dst)); + isl_sioimath_try_demote(dst); +} + +/* Subtract two isl_ints. + */ +inline void isl_sioimath_sub(isl_sioimath_ptr dst, isl_sioimath_src lhs, + isl_sioimath_src rhs) +{ + isl_sioimath_scratchspace_t scratchlhs, scratchrhs; + int32_t smalllhs, smallrhs; + + if (isl_sioimath_decode_small(lhs, &smalllhs) && + isl_sioimath_decode_small(rhs, &smallrhs)) { + isl_sioimath_set_int64( + dst, (int64_t) smalllhs - (int64_t) smallrhs); + return; + } + + mp_int_sub(isl_sioimath_bigarg_src(lhs, &scratchlhs), + isl_sioimath_bigarg_src(rhs, &scratchrhs), + isl_sioimath_reinit_big(dst)); + isl_sioimath_try_demote(dst); +} + +/* Multiply two isl_ints. + */ +inline void isl_sioimath_mul(isl_sioimath_ptr dst, isl_sioimath_src lhs, + isl_sioimath_src rhs) +{ + isl_sioimath_scratchspace_t scratchlhs, scratchrhs; + int32_t smalllhs, smallrhs; + + if (isl_sioimath_decode_small(lhs, &smalllhs) && + isl_sioimath_decode_small(rhs, &smallrhs)) { + isl_sioimath_set_int64( + dst, (int64_t) smalllhs * (int64_t) smallrhs); + return; + } + + mp_int_mul(isl_sioimath_bigarg_src(lhs, &scratchlhs), + isl_sioimath_bigarg_src(rhs, &scratchrhs), + isl_sioimath_reinit_big(dst)); + isl_sioimath_try_demote(dst); +} + +/* Shift lhs by rhs bits to the left and store the result in dst. Effectively, + * this operation computes 'lhs * 2^rhs'. + */ +inline void isl_sioimath_mul_2exp(isl_sioimath_ptr dst, isl_sioimath lhs, + unsigned long rhs) +{ + isl_sioimath_scratchspace_t scratchlhs; + int32_t smalllhs; + + if (isl_sioimath_decode_small(lhs, &smalllhs) && (rhs <= 32ul)) { + isl_sioimath_set_int64(dst, ((int64_t) smalllhs) << rhs); + return; + } + + mp_int_mul_pow2(isl_sioimath_bigarg_src(lhs, &scratchlhs), rhs, + isl_sioimath_reinit_big(dst)); +} + +/* Multiply an isl_int and a signed long. + */ +inline void isl_sioimath_mul_si(isl_sioimath_ptr dst, isl_sioimath lhs, + signed long rhs) +{ + isl_sioimath_scratchspace_t scratchlhs, scratchrhs; + int32_t smalllhs; + + if (isl_sioimath_decode_small(lhs, &smalllhs) && (rhs > LONG_MIN) && + (labs(rhs) <= UINT32_MAX)) { + isl_sioimath_set_int64(dst, (int64_t) smalllhs * (int64_t) rhs); + return; + } + + mp_int_mul(isl_sioimath_bigarg_src(lhs, &scratchlhs), + isl_sioimath_siarg_src(rhs, &scratchrhs), + isl_sioimath_reinit_big(dst)); + isl_sioimath_try_demote(dst); +} + +/* Multiply an isl_int and an unsigned long. + */ +inline void isl_sioimath_mul_ui(isl_sioimath_ptr dst, isl_sioimath lhs, + unsigned long rhs) +{ + isl_sioimath_scratchspace_t scratchlhs, scratchrhs; + int32_t smalllhs; + + if (isl_sioimath_decode_small(lhs, &smalllhs) && (rhs <= UINT32_MAX)) { + isl_sioimath_set_int64(dst, (int64_t) smalllhs * (int64_t) rhs); + return; + } + + mp_int_mul(isl_sioimath_bigarg_src(lhs, &scratchlhs), + isl_sioimath_uiarg_src(rhs, &scratchrhs), + isl_sioimath_reinit_big(dst)); + isl_sioimath_try_demote(dst); +} + +/* Compute the power of an isl_int to an unsigned long. + * Always let IMath do it; the result is unlikely to be small except in some + * special cases. + * Note: 0^0 == 1 + */ +inline void isl_sioimath_pow_ui(isl_sioimath_ptr dst, isl_sioimath_src lhs, + unsigned long rhs) +{ + isl_sioimath_scratchspace_t scratchlhs, scratchrhs; + int32_t smalllhs; + + switch (rhs) { + case 0: + isl_sioimath_set_small(dst, 1); + return; + case 1: + isl_sioimath_set(dst, lhs); + return; + case 2: + isl_sioimath_mul(dst, lhs, lhs); + return; + } + + if (isl_sioimath_decode_small(lhs, &smalllhs)) { + switch (smalllhs) { + case 0: + isl_sioimath_set_small(dst, 0); + return; + case 1: + isl_sioimath_set_small(dst, 1); + return; + case 2: + isl_sioimath_set_small(dst, 1); + isl_sioimath_mul_2exp(dst, *dst, rhs); + return; + default: + if ((MP_SMALL_MIN <= rhs) && (rhs <= MP_SMALL_MAX)) { + mp_int_expt_value(smalllhs, rhs, + isl_sioimath_reinit_big(dst)); + isl_sioimath_try_demote(dst); + return; + } + } + } + + mp_int_expt_full(isl_sioimath_bigarg_src(lhs, &scratchlhs), + isl_sioimath_uiarg_src(rhs, &scratchrhs), + isl_sioimath_reinit_big(dst)); + isl_sioimath_try_demote(dst); +} + +/* Fused multiply-add. + */ +inline void isl_sioimath_addmul(isl_sioimath_ptr dst, isl_sioimath_src lhs, + isl_sioimath_src rhs) +{ + isl_sioimath tmp; + isl_sioimath_init(&tmp); + isl_sioimath_mul(&tmp, lhs, rhs); + isl_sioimath_add(dst, *dst, tmp); + isl_sioimath_clear(&tmp); +} + +/* Fused multiply-add with an unsigned long. + */ +inline void isl_sioimath_addmul_ui(isl_sioimath_ptr dst, isl_sioimath_src lhs, + unsigned long rhs) +{ + isl_sioimath tmp; + isl_sioimath_init(&tmp); + isl_sioimath_mul_ui(&tmp, lhs, rhs); + isl_sioimath_add(dst, *dst, tmp); + isl_sioimath_clear(&tmp); +} + +/* Fused multiply-subtract. + */ +inline void isl_sioimath_submul(isl_sioimath_ptr dst, isl_sioimath_src lhs, + isl_sioimath_src rhs) +{ + isl_sioimath tmp; + isl_sioimath_init(&tmp); + isl_sioimath_mul(&tmp, lhs, rhs); + isl_sioimath_sub(dst, *dst, tmp); + isl_sioimath_clear(&tmp); +} + +/* Fused multiply-add with an unsigned long. + */ +inline void isl_sioimath_submul_ui(isl_sioimath_ptr dst, isl_sioimath_src lhs, + unsigned long rhs) +{ + isl_sioimath tmp; + isl_sioimath_init(&tmp); + isl_sioimath_mul_ui(&tmp, lhs, rhs); + isl_sioimath_sub(dst, *dst, tmp); + isl_sioimath_clear(&tmp); +} + +void isl_sioimath_gcd(isl_sioimath_ptr dst, isl_sioimath_src lhs, + isl_sioimath_src rhs); +void isl_sioimath_lcm(isl_sioimath_ptr dst, isl_sioimath_src lhs, + isl_sioimath_src rhs); + +/* Divide lhs by rhs, rounding to zero (Truncate). + */ +inline void isl_sioimath_tdiv_q(isl_sioimath_ptr dst, isl_sioimath_src lhs, + isl_sioimath_src rhs) +{ + isl_sioimath_scratchspace_t lhsscratch, rhsscratch; + int32_t lhssmall, rhssmall; + + if (isl_sioimath_decode_small(lhs, &lhssmall) && + isl_sioimath_decode_small(rhs, &rhssmall)) { + isl_sioimath_set_small(dst, lhssmall / rhssmall); + return; + } + + mp_int_div(isl_sioimath_bigarg_src(lhs, &lhsscratch), + isl_sioimath_bigarg_src(rhs, &rhsscratch), + isl_sioimath_reinit_big(dst), NULL); + isl_sioimath_try_demote(dst); + return; +} + +/* Divide lhs by an unsigned long rhs, rounding to zero (Truncate). + */ +inline void isl_sioimath_tdiv_q_ui(isl_sioimath_ptr dst, isl_sioimath_src lhs, + unsigned long rhs) +{ + isl_sioimath_scratchspace_t lhsscratch, rhsscratch; + int32_t lhssmall; + + if (isl_sioimath_is_small(lhs) && (rhs <= (unsigned long) INT32_MAX)) { + lhssmall = isl_sioimath_get_small(lhs); + isl_sioimath_set_small(dst, lhssmall / (int32_t) rhs); + return; + } + + if (rhs <= MP_SMALL_MAX) { + mp_int_div_value(isl_sioimath_bigarg_src(lhs, &lhsscratch), rhs, + isl_sioimath_reinit_big(dst), NULL); + isl_sioimath_try_demote(dst); + return; + } + + mp_int_div(isl_sioimath_bigarg_src(lhs, &lhsscratch), + isl_sioimath_uiarg_src(rhs, &rhsscratch), + isl_sioimath_reinit_big(dst), NULL); + isl_sioimath_try_demote(dst); +} + +/* Divide lhs by rhs, rounding to positive infinity (Ceil). + */ +inline void isl_sioimath_cdiv_q(isl_sioimath_ptr dst, isl_sioimath_src lhs, + isl_sioimath_src rhs) +{ + int32_t lhssmall, rhssmall; + isl_sioimath_scratchspace_t lhsscratch, rhsscratch; + int32_t q; + + if (isl_sioimath_decode_small(lhs, &lhssmall) && + isl_sioimath_decode_small(rhs, &rhssmall)) { + if ((lhssmall >= 0) && (rhssmall >= 0)) + q = ((int64_t) lhssmall + (int64_t) rhssmall - 1) / + rhssmall; + else if ((lhssmall < 0) && (rhssmall < 0)) + q = ((int64_t) lhssmall + (int64_t) rhssmall + 1) / + rhssmall; + else + q = lhssmall / rhssmall; + isl_sioimath_set_small(dst, q); + return; + } + + impz_cdiv_q(isl_sioimath_reinit_big(dst), + isl_sioimath_bigarg_src(lhs, &lhsscratch), + isl_sioimath_bigarg_src(rhs, &rhsscratch)); + isl_sioimath_try_demote(dst); +} + +/* Compute the division of lhs by a rhs of type unsigned long, rounding towards + * positive infinity (Ceil). + */ +inline void isl_sioimath_cdiv_q_ui(isl_sioimath_ptr dst, isl_sioimath_src lhs, + unsigned long rhs) +{ + isl_sioimath_scratchspace_t lhsscratch, rhsscratch; + int32_t lhssmall, q; + + if (isl_sioimath_decode_small(lhs, &lhssmall) && (rhs <= INT32_MAX)) { + if (lhssmall >= 0) + q = ((int64_t) lhssmall + ((int64_t) rhs - 1)) / + (int64_t) rhs; + else + q = lhssmall / (int32_t) rhs; + isl_sioimath_set_small(dst, q); + return; + } + + impz_cdiv_q(isl_sioimath_reinit_big(dst), + isl_sioimath_bigarg_src(lhs, &lhsscratch), + isl_sioimath_uiarg_src(rhs, &rhsscratch)); + isl_sioimath_try_demote(dst); +} + +/* Divide lhs by rhs, rounding to negative infinity (Floor). + */ +inline void isl_sioimath_fdiv_q(isl_sioimath_ptr dst, isl_sioimath_src lhs, + isl_sioimath_src rhs) +{ + isl_sioimath_scratchspace_t lhsscratch, rhsscratch; + int32_t lhssmall, rhssmall; + int32_t q; + + if (isl_sioimath_decode_small(lhs, &lhssmall) && + isl_sioimath_decode_small(rhs, &rhssmall)) { + if ((lhssmall < 0) && (rhssmall >= 0)) + q = ((int64_t) lhssmall - ((int64_t) rhssmall - 1)) / + rhssmall; + else if ((lhssmall >= 0) && (rhssmall < 0)) + q = ((int64_t) lhssmall - ((int64_t) rhssmall + 1)) / + rhssmall; + else + q = lhssmall / rhssmall; + isl_sioimath_set_small(dst, q); + return; + } + + impz_fdiv_q(isl_sioimath_reinit_big(dst), + isl_sioimath_bigarg_src(lhs, &lhsscratch), + isl_sioimath_bigarg_src(rhs, &rhsscratch)); + isl_sioimath_try_demote(dst); +} + +/* Compute the division of lhs by a rhs of type unsigned long, rounding towards + * negative infinity (Floor). + */ +inline void isl_sioimath_fdiv_q_ui(isl_sioimath_ptr dst, isl_sioimath_src lhs, + unsigned long rhs) +{ + isl_sioimath_scratchspace_t lhsscratch, rhsscratch; + int32_t lhssmall, q; + + if (isl_sioimath_decode_small(lhs, &lhssmall) && (rhs <= INT32_MAX)) { + if (lhssmall >= 0) + q = (uint32_t) lhssmall / rhs; + else + q = ((int64_t) lhssmall - ((int64_t) rhs - 1)) / + (int64_t) rhs; + isl_sioimath_set_small(dst, q); + return; + } + + impz_fdiv_q(isl_sioimath_reinit_big(dst), + isl_sioimath_bigarg_src(lhs, &lhsscratch), + isl_sioimath_uiarg_src(rhs, &rhsscratch)); + isl_sioimath_try_demote(dst); +} + +/* Get the remainder of: lhs divided by rhs rounded towards negative infinite + * (Floor). + */ +inline void isl_sioimath_fdiv_r(isl_sioimath_ptr dst, isl_sioimath_src lhs, + isl_sioimath_src rhs) +{ + isl_sioimath_scratchspace_t lhsscratch, rhsscratch; + int64_t lhssmall, rhssmall; + int32_t r; + + if (isl_sioimath_is_small(lhs) && isl_sioimath_is_small(rhs)) { + lhssmall = isl_sioimath_get_small(lhs); + rhssmall = isl_sioimath_get_small(rhs); + r = (rhssmall + lhssmall % rhssmall) % rhssmall; + isl_sioimath_set_small(dst, r); + return; + } + + impz_fdiv_r(isl_sioimath_reinit_big(dst), + isl_sioimath_bigarg_src(lhs, &lhsscratch), + isl_sioimath_bigarg_src(rhs, &rhsscratch)); + isl_sioimath_try_demote(dst); +} + +void isl_sioimath_read(isl_sioimath_ptr dst, const char *str); + +/* Return: + * +1 for a positive number + * -1 for a negative number + * 0 if the number is zero + */ +inline int isl_sioimath_sgn(isl_sioimath_src arg) +{ + int32_t small; + + if (isl_sioimath_decode_small(arg, &small)) + return (small > 0) - (small < 0); + + return mp_int_compare_zero(isl_sioimath_get_big(arg)); +} + +/* Return: + * +1 if lhs > rhs + * -1 if lhs < rhs + * 0 if lhs = rhs + */ +inline int isl_sioimath_cmp(isl_sioimath_src lhs, isl_sioimath_src rhs) +{ + isl_sioimath_scratchspace_t lhsscratch, rhsscratch; + int32_t lhssmall, rhssmall; + + if (isl_sioimath_decode_small(lhs, &lhssmall) && + isl_sioimath_decode_small(rhs, &rhssmall)) + return (lhssmall > rhssmall) - (lhssmall < rhssmall); + + if (isl_sioimath_decode_small(rhs, &rhssmall)) + return mp_int_compare_value( + isl_sioimath_bigarg_src(lhs, &lhsscratch), rhssmall); + + if (isl_sioimath_decode_small(lhs, &lhssmall)) + return -mp_int_compare_value( + isl_sioimath_bigarg_src(rhs, &rhsscratch), lhssmall); + + return mp_int_compare( + isl_sioimath_get_big(lhs), isl_sioimath_get_big(rhs)); +} + +/* As isl_sioimath_cmp, but with signed long rhs. + */ +inline int isl_sioimath_cmp_si(isl_sioimath_src lhs, signed long rhs) +{ + int32_t lhssmall; + + if (isl_sioimath_decode_small(lhs, &lhssmall)) + return (lhssmall > rhs) - (lhssmall < rhs); + + return mp_int_compare_value(isl_sioimath_get_big(lhs), rhs); +} + +/* Return: + * +1 if |lhs| > |rhs| + * -1 if |lhs| < |rhs| + * 0 if |lhs| = |rhs| + */ +inline int isl_sioimath_abs_cmp(isl_sioimath_src lhs, isl_sioimath_src rhs) +{ + isl_sioimath_scratchspace_t lhsscratch, rhsscratch; + int32_t lhssmall, rhssmall; + + if (isl_sioimath_decode_small(lhs, &lhssmall) && + isl_sioimath_decode_small(rhs, &rhssmall)) { + lhssmall = labs(lhssmall); + rhssmall = labs(rhssmall); + return (lhssmall > rhssmall) - (lhssmall < rhssmall); + } + + return mp_int_compare_unsigned( + isl_sioimath_bigarg_src(lhs, &lhsscratch), + isl_sioimath_bigarg_src(rhs, &rhsscratch)); +} + +/* Return whether lhs is divisible by rhs. + * In particular, can rhs be multiplied by some integer to result in lhs? + * If rhs is zero, then this means lhs has to be zero too. + */ +inline int isl_sioimath_is_divisible_by(isl_sioimath_src lhs, + isl_sioimath_src rhs) +{ + isl_sioimath_scratchspace_t lhsscratch, rhsscratch; + int32_t lhssmall, rhssmall; + mpz_t rem; + int cmp; + + if (isl_sioimath_sgn(rhs) == 0) + return isl_sioimath_sgn(lhs) == 0; + + if (isl_sioimath_decode_small(lhs, &lhssmall) && + isl_sioimath_decode_small(rhs, &rhssmall)) + return lhssmall % rhssmall == 0; + + if (isl_sioimath_decode_small(rhs, &rhssmall)) + return mp_int_divisible_value( + isl_sioimath_bigarg_src(lhs, &lhsscratch), rhssmall); + + mp_int_init(&rem); + mp_int_div(isl_sioimath_bigarg_src(lhs, &lhsscratch), + isl_sioimath_bigarg_src(rhs, &rhsscratch), NULL, &rem); + cmp = mp_int_compare_zero(&rem); + mp_int_clear(&rem); + return cmp == 0; +} + +/* Return a hash code of an isl_sioimath. + * The hash code for a number in small and big representation must be identical + * on the same machine because small representation if not obligatory if fits. + */ +inline uint32_t isl_sioimath_hash(isl_sioimath_src arg, uint32_t hash) +{ + int32_t small; + int i; + uint32_t num; + mp_digit digits[(sizeof(uint32_t) + sizeof(mp_digit) - 1) / + sizeof(mp_digit)]; + mp_size used; + const unsigned char *digitdata = (const unsigned char *) &digits; + + if (isl_sioimath_decode_small(arg, &small)) { + if (small < 0) + isl_hash_byte(hash, 0xFF); + num = labs(small); + + isl_siomath_uint32_to_digits(num, digits, &used); + for (i = 0; i < used * sizeof(mp_digit); i += 1) + isl_hash_byte(hash, digitdata[i]); + return hash; + } + + return isl_imath_hash(isl_sioimath_get_big(arg), hash); +} + +/* Return the number of digits in a number of the given base or more, i.e. the + * string length without sign and null terminator. + * + * Current implementation for small representation returns the maximal number + * of binary digits in that representation, which can be much larger than the + * smallest possible solution. + */ +inline size_t isl_sioimath_sizeinbase(isl_sioimath_src arg, int base) +{ + int32_t small; + + if (isl_sioimath_decode_small(arg, &small)) + return sizeof(int32_t) * CHAR_BIT - 1; + + return impz_sizeinbase(isl_sioimath_get_big(arg), base); +} + +void isl_sioimath_print(FILE *out, isl_sioimath_src i, int width); +void isl_sioimath_dump(isl_sioimath_src arg); + +typedef isl_sioimath isl_int[1]; +#define isl_int_init(i) isl_sioimath_init((i)) +#define isl_int_clear(i) isl_sioimath_clear((i)) + +#define isl_int_set(r, i) isl_sioimath_set((r), *(i)) +#define isl_int_set_si(r, i) isl_sioimath_set_si((r), i) +#define isl_int_set_ui(r, i) isl_sioimath_set_ui((r), i) +#define isl_int_fits_slong(r) isl_sioimath_fits_slong(*(r)) +#define isl_int_get_si(r) isl_sioimath_get_si(*(r)) +#define isl_int_fits_ulong(r) isl_sioimath_fits_ulong(*(r)) +#define isl_int_get_ui(r) isl_sioimath_get_ui(*(r)) +#define isl_int_get_d(r) isl_sioimath_get_d(*(r)) +#define isl_int_get_str(r) isl_sioimath_get_str(*(r)) +#define isl_int_abs(r, i) isl_sioimath_abs((r), *(i)) +#define isl_int_neg(r, i) isl_sioimath_neg((r), *(i)) +#define isl_int_swap(i, j) isl_sioimath_swap((i), (j)) +#define isl_int_swap_or_set(i, j) isl_sioimath_swap((i), (j)) +#define isl_int_add_ui(r, i, j) isl_sioimath_add_ui((r), *(i), j) +#define isl_int_sub_ui(r, i, j) isl_sioimath_sub_ui((r), *(i), j) + +#define isl_int_add(r, i, j) isl_sioimath_add((r), *(i), *(j)) +#define isl_int_sub(r, i, j) isl_sioimath_sub((r), *(i), *(j)) +#define isl_int_mul(r, i, j) isl_sioimath_mul((r), *(i), *(j)) +#define isl_int_mul_2exp(r, i, j) isl_sioimath_mul_2exp((r), *(i), j) +#define isl_int_mul_si(r, i, j) isl_sioimath_mul_si((r), *(i), j) +#define isl_int_mul_ui(r, i, j) isl_sioimath_mul_ui((r), *(i), j) +#define isl_int_pow_ui(r, i, j) isl_sioimath_pow_ui((r), *(i), j) +#define isl_int_addmul(r, i, j) isl_sioimath_addmul((r), *(i), *(j)) +#define isl_int_addmul_ui(r, i, j) isl_sioimath_addmul_ui((r), *(i), j) +#define isl_int_submul(r, i, j) isl_sioimath_submul((r), *(i), *(j)) +#define isl_int_submul_ui(r, i, j) isl_sioimath_submul_ui((r), *(i), j) + +#define isl_int_gcd(r, i, j) isl_sioimath_gcd((r), *(i), *(j)) +#define isl_int_lcm(r, i, j) isl_sioimath_lcm((r), *(i), *(j)) +#define isl_int_divexact(r, i, j) isl_sioimath_tdiv_q((r), *(i), *(j)) +#define isl_int_divexact_ui(r, i, j) isl_sioimath_tdiv_q_ui((r), *(i), j) +#define isl_int_tdiv_q(r, i, j) isl_sioimath_tdiv_q((r), *(i), *(j)) +#define isl_int_cdiv_q(r, i, j) isl_sioimath_cdiv_q((r), *(i), *(j)) +#define isl_int_cdiv_q_ui(r, i, j) isl_sioimath_cdiv_q_ui((r), *(i), j) +#define isl_int_fdiv_q(r, i, j) isl_sioimath_fdiv_q((r), *(i), *(j)) +#define isl_int_fdiv_r(r, i, j) isl_sioimath_fdiv_r((r), *(i), *(j)) +#define isl_int_fdiv_q_ui(r, i, j) isl_sioimath_fdiv_q_ui((r), *(i), j) + +#define isl_int_read(r, s) isl_sioimath_read((r), s) +#define isl_int_sgn(i) isl_sioimath_sgn(*(i)) +#define isl_int_cmp(i, j) isl_sioimath_cmp(*(i), *(j)) +#define isl_int_cmp_si(i, si) isl_sioimath_cmp_si(*(i), si) +#define isl_int_eq(i, j) (isl_sioimath_cmp(*(i), *(j)) == 0) +#define isl_int_ne(i, j) (isl_sioimath_cmp(*(i), *(j)) != 0) +#define isl_int_lt(i, j) (isl_sioimath_cmp(*(i), *(j)) < 0) +#define isl_int_le(i, j) (isl_sioimath_cmp(*(i), *(j)) <= 0) +#define isl_int_gt(i, j) (isl_sioimath_cmp(*(i), *(j)) > 0) +#define isl_int_ge(i, j) (isl_sioimath_cmp(*(i), *(j)) >= 0) +#define isl_int_abs_cmp(i, j) isl_sioimath_abs_cmp(*(i), *(j)) +#define isl_int_abs_eq(i, j) (isl_sioimath_abs_cmp(*(i), *(j)) == 0) +#define isl_int_abs_ne(i, j) (isl_sioimath_abs_cmp(*(i), *(j)) != 0) +#define isl_int_abs_lt(i, j) (isl_sioimath_abs_cmp(*(i), *(j)) < 0) +#define isl_int_abs_gt(i, j) (isl_sioimath_abs_cmp(*(i), *(j)) > 0) +#define isl_int_abs_ge(i, j) (isl_sioimath_abs_cmp(*(i), *(j)) >= 0) +#define isl_int_is_divisible_by(i, j) isl_sioimath_is_divisible_by(*(i), *(j)) + +#define isl_int_hash(v, h) isl_sioimath_hash(*(v), h) +#define isl_int_free_str(s) free(s) +#define isl_int_print(out, i, width) isl_sioimath_print(out, *(i), width) + +#endif /* ISL_INT_SIOIMATH_H */ diff --git a/external/mit/isl/dist/isl_list_macro.h b/external/mit/isl/dist/isl_list_macro.h new file mode 100644 index 000000000000..72f258a298da --- /dev/null +++ b/external/mit/isl/dist/isl_list_macro.h @@ -0,0 +1,8 @@ +#define xCAT(A,B) A ## B +#define CAT(A,B) xCAT(A,B) +#undef EL +#define EL CAT(isl_,EL_BASE) +#define xFN(TYPE,NAME) TYPE ## _ ## NAME +#define FN(TYPE,NAME) xFN(TYPE,NAME) +#define xLIST(EL) EL ## _list +#define LIST(EL) xLIST(EL) diff --git a/external/mit/isl/dist/isl_list_private.h b/external/mit/isl/dist/isl_list_private.h new file mode 100644 index 000000000000..006b2871e4c9 --- /dev/null +++ b/external/mit/isl/dist/isl_list_private.h @@ -0,0 +1,10 @@ +#ifndef ISL_LIST_PRIVATE_H +#define ISL_LIST_PRIVATE_H + +#include + +#define ISL_DECLARE_LIST_FN_PRIVATE(EL) \ +__isl_keep isl_##EL *isl_##EL##_list_peek( \ + __isl_keep isl_##EL##_list *list, int index); + +#endif diff --git a/external/mit/isl/dist/isl_list_read_templ.c b/external/mit/isl/dist/isl_list_read_templ.c new file mode 100644 index 000000000000..11c2bd52183f --- /dev/null +++ b/external/mit/isl/dist/isl_list_read_templ.c @@ -0,0 +1,49 @@ +/* + * Copyright 2017 Sven Verdoolaege + * + * Use of this software is governed by the MIT license + * + * Written by Sven Verdoolaege. + */ + +#include + +#include + +/* Read a list of elements of type EL from "s". + * The input format corresponds to the way lists are printed + * by isl_printer_print_list_*. + * In particular, the elements are separated by a comma and + * the entire list is surrounded by parentheses. + */ +__isl_give LIST(EL) *FN(isl_stream_read,LIST(EL_BASE))(isl_stream *s) +{ + isl_ctx *ctx; + LIST(EL) *list; + + if (!s) + return NULL; + ctx = isl_stream_get_ctx(s); + list = FN(LIST(EL),alloc)(ctx, 0); + if (!list) + return NULL; + if (isl_stream_eat(s, '(') < 0) + return FN(LIST(EL),free)(list); + if (isl_stream_eat_if_available(s, ')')) + return list; + do { + EL *el; + + el = FN(isl_stream_read,EL_BASE)(s); + list = FN(LIST(EL),add)(list, el); + if (!list) + return NULL; + } while (isl_stream_eat_if_available(s, ',')); + if (isl_stream_eat(s, ')') < 0) + return FN(LIST(EL),free)(list); + return list; +} + +#undef TYPE_BASE +#define TYPE_BASE LIST(EL_BASE) +#include "isl_read_from_str_templ.c" diff --git a/external/mit/isl/dist/isl_list_read_yaml_templ.c b/external/mit/isl/dist/isl_list_read_yaml_templ.c new file mode 100644 index 000000000000..5b6143df9ee4 --- /dev/null +++ b/external/mit/isl/dist/isl_list_read_yaml_templ.c @@ -0,0 +1,40 @@ +/* + * Copyright 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 + +#include + +/* Read a sequence of EL objects and return them as a list. + */ +static __isl_give LIST(EL) *FN(isl_stream_yaml_read,LIST(EL_BASE))( + isl_stream *s) +{ + isl_ctx *ctx; + LIST(EL) *list; + isl_bool more; + + ctx = isl_stream_get_ctx(s); + + if (isl_stream_yaml_read_start_sequence(s) < 0) + return NULL; + + list = FN(LIST(EL),alloc)(ctx, 0); + while ((more = isl_stream_yaml_next(s)) == isl_bool_true) { + EL *el; + + el = FN(isl_stream_read,EL_BASE)(s); + list = FN(LIST(EL),add)(list, el); + } + + if (more < 0 || isl_stream_yaml_read_end_sequence(s) < 0) + return FN(LIST(EL),free)(list); + + return list; +} diff --git a/external/mit/isl/dist/isl_list_templ.c b/external/mit/isl/dist/isl_list_templ.c new file mode 100644 index 000000000000..4b04052896c1 --- /dev/null +++ b/external/mit/isl/dist/isl_list_templ.c @@ -0,0 +1,699 @@ +/* + * Copyright 2008-2009 Katholieke Universiteit Leuven + * Copyright 2011 INRIA Saclay + * Copyright 2012-2013 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 + */ + +#include +#include +#include + +#include + +#define xS(TYPE,NAME) struct TYPE ## _ ## NAME +#define S(TYPE,NAME) xS(TYPE,NAME) + +isl_ctx *FN(LIST(EL),get_ctx)(__isl_keep LIST(EL) *list) +{ + return list ? list->ctx : NULL; +} + +__isl_give LIST(EL) *FN(LIST(EL),alloc)(isl_ctx *ctx, int n) +{ + LIST(EL) *list; + + if (n < 0) + isl_die(ctx, isl_error_invalid, + "cannot create list of negative length", + return NULL); + list = isl_alloc(ctx, LIST(EL), + sizeof(LIST(EL)) + (n - 1) * sizeof(struct EL *)); + if (!list) + return NULL; + + list->ctx = ctx; + isl_ctx_ref(ctx); + list->ref = 1; + list->size = n; + list->n = 0; + return list; +} + +__isl_give LIST(EL) *FN(LIST(EL),copy)(__isl_keep LIST(EL) *list) +{ + if (!list) + return NULL; + + list->ref++; + return list; +} + +__isl_give LIST(EL) *FN(LIST(EL),dup)(__isl_keep LIST(EL) *list) +{ + int i; + LIST(EL) *dup; + + if (!list) + return NULL; + + dup = FN(LIST(EL),alloc)(FN(LIST(EL),get_ctx)(list), list->n); + if (!dup) + return NULL; + for (i = 0; i < list->n; ++i) + dup = FN(LIST(EL),add)(dup, FN(EL,copy)(list->p[i])); + return dup; +} + +__isl_give LIST(EL) *FN(LIST(EL),cow)(__isl_take LIST(EL) *list) +{ + if (!list) + return NULL; + + if (list->ref == 1) + return list; + list->ref--; + return FN(LIST(EL),dup)(list); +} + +/* Make sure "list" has room for at least "n" more pieces. + * Always return a list with a single reference. + * + * If there is only one reference to list, we extend it in place. + * Otherwise, we create a new LIST(EL) and copy the elements. + */ +static __isl_give LIST(EL) *FN(LIST(EL),grow)(__isl_take LIST(EL) *list, int n) +{ + isl_ctx *ctx; + int i, new_size; + LIST(EL) *res; + + if (!list) + return NULL; + if (list->ref == 1 && list->n + n <= list->size) + return list; + + ctx = FN(LIST(EL),get_ctx)(list); + new_size = ((list->n + n + 1) * 3) / 2; + if (list->ref == 1) { + res = isl_realloc(ctx, list, LIST(EL), + sizeof(LIST(EL)) + (new_size - 1) * sizeof(EL *)); + if (!res) + return FN(LIST(EL),free)(list); + res->size = new_size; + return res; + } + + if (list->n + n <= list->size && list->size < new_size) + new_size = list->size; + + res = FN(LIST(EL),alloc)(ctx, new_size); + if (!res) + return FN(LIST(EL),free)(list); + + for (i = 0; i < list->n; ++i) + res = FN(LIST(EL),add)(res, FN(EL,copy)(list->p[i])); + + FN(LIST(EL),free)(list); + return res; +} + +/* Check that "index" is a valid position in "list". + */ +static isl_stat FN(LIST(EL),check_index)(__isl_keep LIST(EL) *list, int index) +{ + if (!list) + return isl_stat_error; + if (index < 0 || index >= list->n) + isl_die(FN(LIST(EL),get_ctx)(list), isl_error_invalid, + "index out of bounds", return isl_stat_error); + return isl_stat_ok; +} + +__isl_give LIST(EL) *FN(LIST(EL),add)(__isl_take LIST(EL) *list, + __isl_take struct EL *el) +{ + list = FN(LIST(EL),grow)(list, 1); + if (!list || !el) + goto error; + list->p[list->n] = el; + list->n++; + return list; +error: + FN(EL,free)(el); + FN(LIST(EL),free)(list); + return NULL; +} + +/* Remove the "n" elements starting at "first" from "list". + */ +__isl_give LIST(EL) *FN(LIST(EL),drop)(__isl_take LIST(EL) *list, + unsigned first, unsigned n) +{ + int i; + + if (!list) + return NULL; + if (first + n > list->n || first + n < first) + isl_die(list->ctx, isl_error_invalid, + "index out of bounds", return FN(LIST(EL),free)(list)); + if (n == 0) + return list; + list = FN(LIST(EL),cow)(list); + if (!list) + return NULL; + for (i = 0; i < n; ++i) + FN(EL,free)(list->p[first + i]); + for (i = first; i + n < list->n; ++i) + list->p[i] = list->p[i + n]; + list->n -= n; + return list; +} + +/* Remove all elements from "list". + */ +__isl_give LIST(EL) *FN(LIST(EL),clear)(__isl_take LIST(EL) *list) +{ + if (!list) + return NULL; + return FN(LIST(EL),drop)(list, 0, list->n); +} + +/* Insert "el" at position "pos" in "list". + * + * If there is only one reference to "list" and if it already has space + * for one extra element, we insert it directly into "list". + * Otherwise, we create a new list consisting of "el" and copied + * elements from "list". + */ +__isl_give LIST(EL) *FN(LIST(EL),insert)(__isl_take LIST(EL) *list, + unsigned pos, __isl_take struct EL *el) +{ + int i; + isl_ctx *ctx; + LIST(EL) *res; + + if (!list || !el) + goto error; + ctx = FN(LIST(EL),get_ctx)(list); + if (pos > list->n) + isl_die(ctx, isl_error_invalid, + "index out of bounds", goto error); + + if (list->ref == 1 && list->size > list->n) { + for (i = list->n; i > pos; --i) + list->p[i] = list->p[i - 1]; + list->n++; + list->p[pos] = el; + return list; + } + + res = FN(LIST(EL),alloc)(ctx, list->n + 1); + for (i = 0; i < pos; ++i) + res = FN(LIST(EL),add)(res, FN(EL,copy)(list->p[i])); + res = FN(LIST(EL),add)(res, el); + for (i = pos; i < list->n; ++i) + res = FN(LIST(EL),add)(res, FN(EL,copy)(list->p[i])); + FN(LIST(EL),free)(list); + + return res; +error: + FN(EL,free)(el); + FN(LIST(EL),free)(list); + return NULL; +} + +__isl_null LIST(EL) *FN(LIST(EL),free)(__isl_take LIST(EL) *list) +{ + int i; + + if (!list) + return NULL; + + if (--list->ref > 0) + return NULL; + + isl_ctx_deref(list->ctx); + for (i = 0; i < list->n; ++i) + FN(EL,free)(list->p[i]); + free(list); + + return NULL; +} + +/* Return the number of elements in "list". + */ +isl_size FN(LIST(EL),size)(__isl_keep LIST(EL) *list) +{ + return list ? list->n : isl_size_error; +} + +/* This is an alternative name for the function above. + */ +isl_size FN(FN(LIST(EL),n),EL_BASE)(__isl_keep LIST(EL) *list) +{ + return FN(LIST(EL),size)(list); +} + +/* Return the element at position "index" in "list". + */ +__isl_keep EL *FN(LIST(EL),peek)(__isl_keep LIST(EL) *list, int index) +{ + if (FN(LIST(EL),check_index)(list, index) < 0) + return NULL; + return list->p[index]; +} + +/* Return a copy of the element at position "index" in "list". + */ +__isl_give EL *FN(LIST(EL),get_at)(__isl_keep LIST(EL) *list, int index) +{ + return FN(EL,copy)(FN(LIST(EL),peek)(list, index)); +} + +/* This is an alternative name for the function above. + */ +__isl_give EL *FN(FN(LIST(EL),get),EL_BASE)(__isl_keep LIST(EL) *list, + int index) +{ + return FN(LIST(EL),get_at)(list, index); +} + +/* Replace the element at position "index" in "list" by "el". + */ +__isl_give LIST(EL) *FN(LIST(EL),set_at)(__isl_take LIST(EL) *list, + int index, __isl_take EL *el) +{ + if (!list || !el) + goto error; + if (FN(LIST(EL),check_index)(list, index) < 0) + goto error; + if (list->p[index] == el) { + FN(EL,free)(el); + return list; + } + list = FN(LIST(EL),cow)(list); + if (!list) + goto error; + FN(EL,free)(list->p[index]); + list->p[index] = el; + return list; +error: + FN(EL,free)(el); + FN(LIST(EL),free)(list); + return NULL; +} + +/* This is an alternative name for the function above. + */ +__isl_give LIST(EL) *FN(FN(LIST(EL),set),EL_BASE)(__isl_take LIST(EL) *list, + int index, __isl_take EL *el) +{ + return FN(LIST(EL),set_at)(list, index, el); +} + +/* Return the element at position "index" of "list". + * This may be either a copy or the element itself + * if there is only one reference to "list". + * This allows the element to be modified inplace + * if both the list and the element have only a single reference. + * The caller is not allowed to modify "list" between + * this call to isl_list_*_take_* and a subsequent call + * to isl_list_*_restore_*. + * The only exception is that isl_list_*_free can be called instead. + */ +static __isl_give EL *FN(FN(LIST(EL),take),EL_BASE)(__isl_keep LIST(EL) *list, + int index) +{ + EL *el; + + if (FN(LIST(EL),check_index)(list, index) < 0) + return NULL; + if (list->ref != 1) + return FN(FN(LIST(EL),get),EL_BASE)(list, index); + el = list->p[index]; + list->p[index] = NULL; + return el; +} + +/* Set the element at position "index" of "list" to "el", + * where the position may be empty due to a previous call + * to isl_list_*_take_*. + */ +static __isl_give LIST(EL) *FN(FN(LIST(EL),restore),EL_BASE)( + __isl_take LIST(EL) *list, int index, __isl_take EL *el) +{ + return FN(FN(LIST(EL),set),EL_BASE)(list, index, el); +} + +/* Swap the elements of "list" in positions "pos1" and "pos2". + */ +__isl_give LIST(EL) *FN(LIST(EL),swap)(__isl_take LIST(EL) *list, + unsigned pos1, unsigned pos2) +{ + EL *el1, *el2; + + if (pos1 == pos2) + return list; + el1 = FN(FN(LIST(EL),take),EL_BASE)(list, pos1); + el2 = FN(FN(LIST(EL),take),EL_BASE)(list, pos2); + list = FN(FN(LIST(EL),restore),EL_BASE)(list, pos1, el2); + list = FN(FN(LIST(EL),restore),EL_BASE)(list, pos2, el1); + return list; +} + +/* Reverse the elements of "list". + */ +__isl_give LIST(EL) *FN(LIST(EL),reverse)(__isl_take LIST(EL) *list) +{ + int i, n; + + n = FN(LIST(EL),size)(list); + for (i = 0; i < n - 1 - i; ++i) + list = FN(LIST(EL),swap)(list, i, n - 1 - i); + return list; +} + +isl_stat FN(LIST(EL),foreach)(__isl_keep LIST(EL) *list, + isl_stat (*fn)(__isl_take EL *el, void *user), void *user) +{ + int i; + + if (!list) + return isl_stat_error; + + for (i = 0; i < list->n; ++i) { + EL *el = FN(EL,copy)(list->p[i]); + if (!el) + return isl_stat_error; + if (fn(el, user) < 0) + return isl_stat_error; + } + + return isl_stat_ok; +} + +/* Does "test" succeed on every element of "list"? + */ +isl_bool FN(LIST(EL),every)(__isl_keep LIST(EL) *list, + isl_bool (*test)(__isl_keep EL *el, void *user), void *user) +{ + int i; + + if (!list) + return isl_bool_error; + + for (i = 0; i < list->n; ++i) { + isl_bool r; + + r = test(list->p[i], user); + if (r < 0 || !r) + return r; + } + + return isl_bool_true; +} + +/* Replace each element in "list" by the result of calling "fn" + * on the element. + */ +__isl_give LIST(EL) *FN(LIST(EL),map)(__isl_keep LIST(EL) *list, + __isl_give EL *(*fn)(__isl_take EL *el, void *user), void *user) +{ + int i, n; + + if (!list) + return NULL; + + n = list->n; + for (i = 0; i < n; ++i) { + EL *el = FN(FN(LIST(EL),take),EL_BASE)(list, i); + if (!el) + return FN(LIST(EL),free)(list); + el = fn(el, user); + list = FN(FN(LIST(EL),restore),EL_BASE)(list, i, el); + } + + return list; +} + +/* Internal data structure for isl_*_list_sort. + * + * "cmp" is the original comparison function. + * "user" is a user provided pointer that should be passed to "cmp". + */ +S(LIST(EL),sort_data) { + int (*cmp)(__isl_keep EL *a, __isl_keep EL *b, void *user); + void *user; +}; + +/* Compare two entries of an isl_*_list based on the user provided + * comparison function on pairs of isl_* objects. + */ +static int FN(LIST(EL),cmp)(const void *a, const void *b, void *user) +{ + S(LIST(EL),sort_data) *data = user; + EL * const *el1 = a; + EL * const *el2 = b; + + return data->cmp(*el1, *el2, data->user); +} + +/* Sort the elements of "list" in ascending order according to + * comparison function "cmp". + */ +__isl_give LIST(EL) *FN(LIST(EL),sort)(__isl_take LIST(EL) *list, + int (*cmp)(__isl_keep EL *a, __isl_keep EL *b, void *user), void *user) +{ + S(LIST(EL),sort_data) data = { cmp, user }; + + if (!list) + return NULL; + if (list->n <= 1) + return list; + list = FN(LIST(EL),cow)(list); + if (!list) + return NULL; + + if (isl_sort(list->p, list->n, sizeof(list->p[0]), + &FN(LIST(EL),cmp), &data) < 0) + return FN(LIST(EL),free)(list); + + return list; +} + +/* Internal data structure for isl_*_list_foreach_scc. + * + * "list" is the original list. + * "follows" is the user provided callback that defines the edges of the graph. + */ +S(LIST(EL),foreach_scc_data) { + LIST(EL) *list; + isl_bool (*follows)(__isl_keep EL *a, __isl_keep EL *b, void *user); + void *follows_user; +}; + +/* Does element i of data->list follow element j? + * + * Use the user provided callback to find out. + */ +static isl_bool FN(LIST(EL),follows)(int i, int j, void *user) +{ + S(LIST(EL),foreach_scc_data) *data = user; + + return data->follows(data->list->p[i], data->list->p[j], + data->follows_user); +} + +/* Call "fn" on the sublist of "list" that consists of the elements + * with indices specified by the "n" elements of "pos". + */ +static isl_stat FN(LIST(EL),call_on_scc)(__isl_keep LIST(EL) *list, int *pos, + int n, isl_stat (*fn)(__isl_take LIST(EL) *scc, void *user), void *user) +{ + int i; + isl_ctx *ctx; + LIST(EL) *slice; + + ctx = FN(LIST(EL),get_ctx)(list); + slice = FN(LIST(EL),alloc)(ctx, n); + for (i = 0; i < n; ++i) { + EL *el; + + el = FN(EL,copy)(list->p[pos[i]]); + slice = FN(LIST(EL),add)(slice, el); + } + + return fn(slice, user); +} + +/* Call "fn" on each of the strongly connected components (SCCs) of + * the graph with as vertices the elements of "list" and + * a directed edge from node b to node a iff follows(a, b) + * returns 1. follows should return -1 on error. + * + * If SCC a contains a node i that follows a node j in another SCC b + * (i.e., follows(i, j, user) returns 1), then fn will be called on SCC a + * after being called on SCC b. + * + * We simply call isl_tarjan_graph_init, extract the SCCs from the result and + * call fn on each of them. + */ +isl_stat FN(LIST(EL),foreach_scc)(__isl_keep LIST(EL) *list, + isl_bool (*follows)(__isl_keep EL *a, __isl_keep EL *b, void *user), + void *follows_user, + isl_stat (*fn)(__isl_take LIST(EL) *scc, void *user), void *fn_user) +{ + S(LIST(EL),foreach_scc_data) data = { list, follows, follows_user }; + int i, n; + isl_ctx *ctx; + struct isl_tarjan_graph *g; + + if (!list) + return isl_stat_error; + if (list->n == 0) + return isl_stat_ok; + if (list->n == 1) + return fn(FN(LIST(EL),copy)(list), fn_user); + + ctx = FN(LIST(EL),get_ctx)(list); + n = list->n; + g = isl_tarjan_graph_init(ctx, n, &FN(LIST(EL),follows), &data); + if (!g) + return isl_stat_error; + + i = 0; + do { + int first; + + if (g->order[i] == -1) + isl_die(ctx, isl_error_internal, "cannot happen", + break); + first = i; + while (g->order[i] != -1) { + ++i; --n; + } + if (first == 0 && n == 0) { + isl_tarjan_graph_free(g); + return fn(FN(LIST(EL),copy)(list), fn_user); + } + if (FN(LIST(EL),call_on_scc)(list, g->order + first, i - first, + fn, fn_user) < 0) + break; + ++i; + } while (n); + + isl_tarjan_graph_free(g); + + return n > 0 ? isl_stat_error : isl_stat_ok; +} + +__isl_give LIST(EL) *FN(FN(LIST(EL),from),EL_BASE)(__isl_take EL *el) +{ + isl_ctx *ctx; + LIST(EL) *list; + + if (!el) + return NULL; + ctx = FN(EL,get_ctx)(el); + list = FN(LIST(EL),alloc)(ctx, 1); + if (!list) + goto error; + list = FN(LIST(EL),add)(list, el); + return list; +error: + FN(EL,free)(el); + return NULL; +} + +/* This function performs the same operation as isl_*_list_from_*, + * but is considered as a function on the element when exported. + */ +__isl_give LIST(EL) *FN(EL,to_list)(__isl_take EL *el) +{ + return FN(FN(LIST(EL),from),EL_BASE)(el); +} + +/* Append the elements of "list2" to "list1", where "list1" is known + * to have only a single reference and enough room to hold + * the extra elements. + */ +static __isl_give LIST(EL) *FN(LIST(EL),concat_inplace)( + __isl_take LIST(EL) *list1, __isl_take LIST(EL) *list2) +{ + int i; + + for (i = 0; i < list2->n; ++i) + list1 = FN(LIST(EL),add)(list1, FN(EL,copy)(list2->p[i])); + FN(LIST(EL),free)(list2); + return list1; +} + +/* Concatenate "list1" and "list2". + * If "list1" has only one reference and has enough room + * for the elements of "list2", the add the elements to "list1" itself. + * Otherwise, create a new list to store the result. + */ +__isl_give LIST(EL) *FN(LIST(EL),concat)(__isl_take LIST(EL) *list1, + __isl_take LIST(EL) *list2) +{ + int i; + isl_ctx *ctx; + LIST(EL) *res; + + if (!list1 || !list2) + goto error; + + if (list1->ref == 1 && list1->n + list2->n <= list1->size) + return FN(LIST(EL),concat_inplace)(list1, list2); + + ctx = FN(LIST(EL),get_ctx)(list1); + res = FN(LIST(EL),alloc)(ctx, list1->n + list2->n); + for (i = 0; i < list1->n; ++i) + res = FN(LIST(EL),add)(res, FN(EL,copy)(list1->p[i])); + for (i = 0; i < list2->n; ++i) + res = FN(LIST(EL),add)(res, FN(EL,copy)(list2->p[i])); + + FN(LIST(EL),free)(list1); + FN(LIST(EL),free)(list2); + return res; +error: + FN(LIST(EL),free)(list1); + FN(LIST(EL),free)(list2); + return NULL; +} + +__isl_give isl_printer *CAT(isl_printer_print_,LIST(EL_BASE))( + __isl_take isl_printer *p, __isl_keep LIST(EL) *list) +{ + int i; + + if (!p || !list) + goto error; + p = isl_printer_print_str(p, "("); + for (i = 0; i < list->n; ++i) { + if (i) + p = isl_printer_print_str(p, ","); + p = CAT(isl_printer_print_,EL_BASE)(p, list->p[i]); + } + p = isl_printer_print_str(p, ")"); + return p; +error: + isl_printer_free(p); + return NULL; +} + +#undef BASE +#define BASE LIST(EL_BASE) + +#define PRINT_DUMP_DEFAULT 0 +#include "print_templ.c" +#undef PRINT_DUMP_DEFAULT diff --git a/external/mit/isl/dist/isl_list_templ.h b/external/mit/isl/dist/isl_list_templ.h new file mode 100644 index 000000000000..893f9d91d4c8 --- /dev/null +++ b/external/mit/isl/dist/isl_list_templ.h @@ -0,0 +1,16 @@ +#define xFN(TYPE,NAME) TYPE ## _ ## NAME +#define FN(TYPE,NAME) xFN(TYPE,NAME) +#define xLIST(EL) EL ## _list +#define LIST(EL) xLIST(EL) + +struct LIST(EL) { + int ref; + isl_ctx *ctx; + + int n; + + size_t size; + struct EL *p[1]; +}; + +__isl_give LIST(EL) *FN(LIST(EL),dup)(__isl_keep LIST(EL) *list); diff --git a/external/mit/isl/dist/isl_local.c b/external/mit/isl/dist/isl_local.c new file mode 100644 index 000000000000..b607c5dc41f0 --- /dev/null +++ b/external/mit/isl/dist/isl_local.c @@ -0,0 +1,406 @@ +/* + * Copyright 2011 INRIA Saclay + * Copyright 2014 Ecole Normale Superieure + * Copyright 2015 Sven Verdoolaege + * + * 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 +#include +#include +#include +#include +#include + +/* Return the isl_ctx to which "local" belongs. + */ +isl_ctx *isl_local_get_ctx(__isl_keep isl_local *local) +{ + if (!local) + return NULL; + + return isl_mat_get_ctx(local); +} + +/* Create an isl_local object from a matrix describing + * integer divisions. + * + * An isl_local object is current defined as exactly such a matrix, + * so simply return the input. + */ +__isl_give isl_local *isl_local_alloc_from_mat(__isl_take isl_mat *mat) +{ + return mat; +} + +/* Return a new reference to "local". + */ +__isl_give isl_local *isl_local_copy(__isl_keep isl_local *local) +{ + return isl_local_alloc_from_mat(isl_mat_copy(local)); +} + +/* Free "local" and return NULL. + */ +__isl_null isl_local *isl_local_free(__isl_take isl_local *local) +{ + isl_mat_free(local); + return NULL; +} + +/* Return the number of local variables (isl_dim_div), + * the number of other variables (isl_dim_set) or + * the total number of variables (isl_dim_all) in "local". + * + * Other types do not have any meaning for an isl_local object. + */ +isl_size isl_local_dim(__isl_keep isl_local *local, enum isl_dim_type type) +{ + isl_mat *mat = local; + + if (!local) + return isl_size_error; + if (type == isl_dim_div) + return isl_mat_rows(mat); + if (type == isl_dim_all) { + isl_size cols = isl_mat_cols(mat); + if (cols < 0) + return isl_size_error; + return cols - 2; + } + if (type == isl_dim_set) { + isl_size total, n_div; + + total = isl_local_dim(local, isl_dim_all); + n_div = isl_local_dim(local, isl_dim_div); + if (total < 0 || n_div < 0) + return isl_size_error; + return total - n_div; + } + isl_die(isl_local_get_ctx(local), isl_error_unsupported, + "unsupported dimension type", return isl_size_error); +} + +#undef TYPE +#define TYPE isl_local +static +#include "check_type_range_templ.c" + +/* Check that "pos" is a valid position for a variable in "local". + */ +static isl_stat isl_local_check_pos(__isl_keep isl_local *local, int pos) +{ + return isl_local_check_range(local, isl_dim_div, pos, 1); +} + +/* Given local variables "local", + * is the variable at position "pos" marked as not having + * an explicit representation? + * Note that even if this variable is not marked in this way and therefore + * does have an explicit representation, this representation may still + * depend (indirectly) on other local variables that do not + * have an explicit representation. + */ +isl_bool isl_local_div_is_marked_unknown(__isl_keep isl_local *local, int pos) +{ + isl_mat *mat = local; + + if (isl_local_check_pos(local, pos) < 0) + return isl_bool_error; + return isl_bool_ok(isl_int_is_zero(mat->row[pos][0])); +} + +/* Given local variables "local", + * does the variable at position "pos" have a complete explicit representation? + * Having a complete explicit representation requires not only + * an explicit representation, but also that all local variables + * that appear in this explicit representation in turn have + * a complete explicit representation. + */ +isl_bool isl_local_div_is_known(__isl_keep isl_local *local, int pos) +{ + isl_bool marked; + int i, off; + isl_size n, cols; + isl_mat *mat = local; + + if (isl_local_check_pos(local, pos) < 0) + return isl_bool_error; + + marked = isl_local_div_is_marked_unknown(local, pos); + if (marked < 0 || marked) + return isl_bool_not(marked); + + n = isl_local_dim(local, isl_dim_div); + cols = isl_mat_cols(mat); + if (n < 0 || cols < 0) + return isl_bool_error; + off = cols - n; + + for (i = n - 1; i >= 0; --i) { + isl_bool known; + + if (isl_int_is_zero(mat->row[pos][off + i])) + continue; + known = isl_local_div_is_known(local, i); + if (known < 0 || !known) + return known; + } + + return isl_bool_true; +} + +/* Does "local" have an explicit representation for all local variables? + */ +isl_bool isl_local_divs_known(__isl_keep isl_local *local) +{ + int i; + isl_size n; + + n = isl_local_dim(local, isl_dim_div); + if (n < 0) + return isl_bool_error; + + for (i = 0; i < n; ++i) { + isl_bool unknown = isl_local_div_is_marked_unknown(local, i); + if (unknown < 0 || unknown) + return isl_bool_not(unknown); + } + + return isl_bool_true; +} + +/* Compare two sets of local variables, defined over + * the same space. + * + * Return -1 if "local1" is "smaller" than "local2", 1 if "local1" is "greater" + * than "local2" and 0 if they are equal. + * + * The order is fairly arbitrary. We do "prefer" divs that only involve + * earlier dimensions in the sense that we consider matrices where + * the first differing div involves earlier dimensions to be smaller. + */ +int isl_local_cmp(__isl_keep isl_local *local1, __isl_keep isl_local *local2) +{ + int i; + int cmp; + isl_bool unknown1, unknown2; + int last1, last2; + isl_size n_col; + isl_mat *mat1 = local1; + isl_mat *mat2 = local2; + + if (local1 == local2) + return 0; + if (!local1) + return -1; + if (!local2) + return 1; + + if (mat1->n_row != mat2->n_row) + return mat1->n_row - mat2->n_row; + + n_col = isl_mat_cols(mat1); + if (n_col < 0) + return -1; + for (i = 0; i < mat1->n_row; ++i) { + unknown1 = isl_local_div_is_marked_unknown(local1, i); + unknown2 = isl_local_div_is_marked_unknown(local2, i); + if (unknown1 && unknown2) + continue; + if (unknown1) + return 1; + if (unknown2) + return -1; + last1 = isl_seq_last_non_zero(mat1->row[i] + 1, n_col - 1); + last2 = isl_seq_last_non_zero(mat2->row[i] + 1, n_col - 1); + if (last1 != last2) + return last1 - last2; + cmp = isl_seq_cmp(mat1->row[i], mat2->row[i], n_col); + if (cmp != 0) + return cmp; + } + + return 0; +} + +/* Return the position of the variables of the given type + * within the sequence of variables of "local". + * + * Only the position of the local variables can be obtained. + * It is equal to the total number of variables minus + * the number of local variables. + */ +isl_size isl_local_var_offset(__isl_keep isl_local *local, + enum isl_dim_type type) +{ + isl_size n_div, n_all; + + if (!local) + return isl_size_error; + if (type != isl_dim_div) + isl_die(isl_local_get_ctx(local), isl_error_unsupported, + "only the offset of the local variables " + "can be obtained", return isl_size_error); + + n_div = isl_local_dim(local, isl_dim_div); + n_all = isl_local_dim(local, isl_dim_all); + if (n_div < 0 || n_all < 0) + return isl_size_error; + return n_all - n_div; +} + +/* Reorder the columns of the given local variables according to the + * given reordering. + * The order of the local variables themselves is assumed not to change. + */ +__isl_give isl_local *isl_local_reorder(__isl_take isl_local *local, + __isl_take isl_reordering *r) +{ + isl_mat *div = local; + int i, j; + isl_mat *mat; + int extra; + + if (!local || !r) + goto error; + + extra = r->dst_len - r->src_len; + mat = isl_mat_alloc(div->ctx, div->n_row, div->n_col + extra); + if (!mat) + goto error; + + for (i = 0; i < div->n_row; ++i) { + isl_seq_cpy(mat->row[i], div->row[i], 2); + isl_seq_clr(mat->row[i] + 2, mat->n_col - 2); + for (j = 0; j < r->src_len; ++j) + isl_int_set(mat->row[i][2 + r->pos[j]], + div->row[i][2 + j]); + } + + isl_reordering_free(r); + isl_local_free(local); + return isl_local_alloc_from_mat(mat); +error: + isl_reordering_free(r); + isl_local_free(local); + return NULL; +} + +/* Move the "n" variables starting at "src_pos" of "local" to "dst_pos". + * + * Moving local variables is not allowed. + */ +__isl_give isl_local *isl_local_move_vars(__isl_take isl_local *local, + unsigned dst_pos, unsigned src_pos, unsigned n) +{ + isl_mat *mat = local; + isl_size v_div; + + v_div = isl_local_var_offset(local, isl_dim_div); + if (v_div < 0) + return isl_local_free(local); + if (n == 0) + return local; + + if (dst_pos >= v_div || src_pos >= v_div) + isl_die(isl_local_get_ctx(local), isl_error_invalid, + "cannot move local variables", + return isl_local_free(local)); + + mat = isl_mat_move_cols(mat, 2 + dst_pos, 2 + src_pos, n); + + return isl_local_alloc_from_mat(mat); +} + +/* Does "local" depend on the specified variables? + * + * If the specified variables are local variables themselves, + * then only later local variables could possibly depend on them. + */ +isl_bool isl_local_involves_vars(__isl_keep isl_local *local, + unsigned first, unsigned n) +{ + isl_mat *mat = local; + int i, first_div; + isl_size v_div, n_div; + + v_div = isl_local_var_offset(local, isl_dim_div); + n_div = isl_local_dim(local, isl_dim_div); + if (v_div < 0 || n_div < 0 || + isl_local_check_range(local, isl_dim_all, first, n) < 0) + return isl_bool_error; + + first_div = (first >= v_div) ? first - v_div + 1 : 0; + for (i = first_div; i < n_div; ++i) { + isl_bool unknown; + + unknown = isl_local_div_is_marked_unknown(local, i); + if (unknown < 0) + return isl_bool_error; + if (unknown) + continue; + if (isl_seq_first_non_zero(mat->row[i] + 1 + 1 + first, n) >= 0) + return isl_bool_true; + } + + return isl_bool_false; +} + +/* Extend a vector "v" representing an integer point + * in the domain space of "local" + * to one that also includes values for the local variables. + * All local variables are required to have an explicit representation. + * If there are no local variables, then the point is not required + * to be integral. + */ +__isl_give isl_vec *isl_local_extend_point_vec(__isl_keep isl_local *local, + __isl_take isl_vec *v) +{ + isl_size dim, n_div, size; + isl_bool known; + isl_mat *mat = local; + + if (!local || !v) + return isl_vec_free(v); + known = isl_local_divs_known(local); + if (known < 0) + return isl_vec_free(v); + if (!known) + isl_die(isl_local_get_ctx(local), isl_error_invalid, + "unknown local variables", return isl_vec_free(v)); + dim = isl_local_dim(local, isl_dim_set); + n_div = isl_local_dim(local, isl_dim_div); + size = isl_vec_size(v); + if (dim < 0 || n_div < 0 || size < 0) + return isl_vec_free(v); + if (size != 1 + dim) + isl_die(isl_local_get_ctx(local), isl_error_invalid, + "incorrect size", return isl_vec_free(v)); + if (n_div == 0) + return v; + if (!isl_int_is_one(v->el[0])) + isl_die(isl_local_get_ctx(local), isl_error_invalid, + "expecting integer point", return isl_vec_free(v)); + { + int i; + v = isl_vec_add_els(v, n_div); + if (!v) + return NULL; + + for (i = 0; i < n_div; ++i) { + isl_seq_inner_product(mat->row[i] + 1, v->el, + 1 + dim + i, &v->el[1+dim+i]); + isl_int_fdiv_q(v->el[1+dim+i], v->el[1+dim+i], + mat->row[i][0]); + } + } + + return v; +} diff --git a/external/mit/isl/dist/isl_local.h b/external/mit/isl/dist/isl_local.h new file mode 100644 index 000000000000..03e4a539709d --- /dev/null +++ b/external/mit/isl/dist/isl_local.h @@ -0,0 +1,33 @@ +#ifndef ISL_LOCAL_H +#define ISL_LOCAL_H + +#include +#include + +typedef isl_mat isl_local; + +__isl_give isl_local *isl_local_copy(__isl_keep isl_local *local); +__isl_null isl_local *isl_local_free(__isl_take isl_local *local); + +isl_bool isl_local_div_is_marked_unknown(__isl_keep isl_local *local, int pos); +isl_bool isl_local_div_is_known(__isl_keep isl_local *local, int pos); +isl_bool isl_local_divs_known(__isl_keep isl_local *local); + +int isl_local_cmp(__isl_keep isl_local *local1, __isl_keep isl_local *local2); + +isl_size isl_local_var_offset(__isl_keep isl_local *local, + enum isl_dim_type type); + +__isl_give isl_local *isl_local_reorder(__isl_take isl_local *local, + __isl_take isl_reordering *r); + +__isl_give isl_local *isl_local_move_vars(__isl_take isl_local *local, + unsigned dst_pos, unsigned src_pos, unsigned n); + +isl_bool isl_local_involves_vars(__isl_keep isl_local *local, + unsigned first, unsigned n); + +__isl_give isl_vec *isl_local_extend_point_vec(__isl_keep isl_local *local, + __isl_take isl_vec *v); + +#endif diff --git a/external/mit/isl/dist/isl_local_private.h b/external/mit/isl/dist/isl_local_private.h new file mode 100644 index 000000000000..bb44d36b83a3 --- /dev/null +++ b/external/mit/isl/dist/isl_local_private.h @@ -0,0 +1,8 @@ +#ifndef ISL_LOCAL_PRIVATE_H +#define ISL_LOCAL_PRIVATE_H + +#include + +__isl_give isl_local *isl_local_alloc_from_mat(__isl_take isl_mat *mat); + +#endif diff --git a/external/mit/isl/dist/isl_local_space.c b/external/mit/isl/dist/isl_local_space.c new file mode 100644 index 000000000000..840275a9493a --- /dev/null +++ b/external/mit/isl/dist/isl_local_space.c @@ -0,0 +1,1833 @@ +/* + * Copyright 2011 INRIA Saclay + * Copyright 2012-2014 Ecole Normale Superieure + * Copyright 2019 Cerebras Systems + * + * 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 + * and Cerebras Systems, 175 S San Antonio Rd, Los Altos, CA, USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +isl_ctx *isl_local_space_get_ctx(__isl_keep isl_local_space *ls) +{ + return ls ? ls->dim->ctx : NULL; +} + +/* Return a hash value that digests "ls". + */ +uint32_t isl_local_space_get_hash(__isl_keep isl_local_space *ls) +{ + uint32_t hash, space_hash, div_hash; + + if (!ls) + return 0; + + hash = isl_hash_init(); + space_hash = isl_space_get_full_hash(isl_local_space_peek_space(ls)); + isl_hash_hash(hash, space_hash); + div_hash = isl_mat_get_hash(ls->div); + isl_hash_hash(hash, div_hash); + + return hash; +} + +__isl_give isl_local_space *isl_local_space_alloc_div( + __isl_take isl_space *space, __isl_take isl_mat *div) +{ + isl_ctx *ctx; + isl_local_space *ls = NULL; + + if (!space || !div) + goto error; + + ctx = isl_space_get_ctx(space); + ls = isl_calloc_type(ctx, struct isl_local_space); + if (!ls) + goto error; + + ls->ref = 1; + ls->dim = space; + ls->div = div; + + return ls; +error: + isl_mat_free(div); + isl_space_free(space); + isl_local_space_free(ls); + return NULL; +} + +__isl_give isl_local_space *isl_local_space_alloc(__isl_take isl_space *space, + unsigned n_div) +{ + isl_ctx *ctx; + isl_mat *div; + isl_size total; + + if (!space) + return NULL; + + total = isl_space_dim(space, isl_dim_all); + if (total < 0) + return isl_local_space_from_space(isl_space_free(space)); + + ctx = isl_space_get_ctx(space); + div = isl_mat_alloc(ctx, n_div, 1 + 1 + total + n_div); + return isl_local_space_alloc_div(space, div); +} + +__isl_give isl_local_space *isl_local_space_from_space( + __isl_take isl_space *space) +{ + return isl_local_space_alloc(space, 0); +} + +__isl_give isl_local_space *isl_local_space_copy(__isl_keep isl_local_space *ls) +{ + if (!ls) + return NULL; + + ls->ref++; + return ls; +} + +__isl_give isl_local_space *isl_local_space_dup(__isl_keep isl_local_space *ls) +{ + if (!ls) + return NULL; + + return isl_local_space_alloc_div(isl_space_copy(ls->dim), + isl_mat_copy(ls->div)); + +} + +__isl_give isl_local_space *isl_local_space_cow(__isl_take isl_local_space *ls) +{ + if (!ls) + return NULL; + + if (ls->ref == 1) + return ls; + ls->ref--; + return isl_local_space_dup(ls); +} + +__isl_null isl_local_space *isl_local_space_free( + __isl_take isl_local_space *ls) +{ + if (!ls) + return NULL; + + if (--ls->ref > 0) + return NULL; + + isl_space_free(ls->dim); + isl_mat_free(ls->div); + + free(ls); + + return NULL; +} + +/* Is the local space that of a parameter domain? + */ +isl_bool isl_local_space_is_params(__isl_keep isl_local_space *ls) +{ + if (!ls) + return isl_bool_error; + return isl_space_is_params(ls->dim); +} + +/* Is the local space that of a set? + */ +isl_bool isl_local_space_is_set(__isl_keep isl_local_space *ls) +{ + return ls ? isl_space_is_set(ls->dim) : isl_bool_error; +} + +#undef TYPE +#define TYPE isl_local_space + +#include "isl_type_has_equal_space_bin_templ.c" +#include "isl_type_has_space_templ.c" + +/* Check that the space of "ls" is equal to "space". + */ +static isl_stat isl_local_space_check_has_space(__isl_keep isl_local_space *ls, + __isl_keep isl_space *space) +{ + isl_bool ok; + + ok = isl_local_space_has_space(ls, space); + if (ok < 0) + return isl_stat_error; + if (!ok) + isl_die(isl_local_space_get_ctx(ls), isl_error_invalid, + "spaces don't match", return isl_stat_error); + return isl_stat_ok; +} + +/* Return true if the two local spaces are identical, with identical + * expressions for the integer divisions. + */ +isl_bool isl_local_space_is_equal(__isl_keep isl_local_space *ls1, + __isl_keep isl_local_space *ls2) +{ + isl_bool equal; + + equal = isl_local_space_has_equal_space(ls1, ls2); + if (equal < 0 || !equal) + return equal; + + if (!isl_local_space_divs_known(ls1)) + return isl_bool_false; + if (!isl_local_space_divs_known(ls2)) + return isl_bool_false; + + return isl_mat_is_equal(ls1->div, ls2->div); +} + +/* Compare two isl_local_spaces. + * + * Return -1 if "ls1" is "smaller" than "ls2", 1 if "ls1" is "greater" + * than "ls2" and 0 if they are equal. + */ +int isl_local_space_cmp(__isl_keep isl_local_space *ls1, + __isl_keep isl_local_space *ls2) +{ + int cmp; + + if (ls1 == ls2) + return 0; + if (!ls1) + return -1; + if (!ls2) + return 1; + + cmp = isl_space_cmp(ls1->dim, ls2->dim); + if (cmp != 0) + return cmp; + + return isl_local_cmp(ls1->div, ls2->div); +} + +isl_size isl_local_space_dim(__isl_keep isl_local_space *ls, + enum isl_dim_type type) +{ + if (!ls) + return isl_size_error; + if (type == isl_dim_div) + return ls->div->n_row; + if (type == isl_dim_all) { + isl_size dim = isl_space_dim(ls->dim, isl_dim_all); + if (dim < 0) + return isl_size_error; + return dim + ls->div->n_row; + } + return isl_space_dim(ls->dim, type); +} + +#undef TYPE +#define TYPE isl_local_space +#include "check_type_range_templ.c" + +/* Return the position of the variables of the given type + * within the sequence of variables of "ls". + */ +isl_size isl_local_space_var_offset(__isl_keep isl_local_space *ls, + enum isl_dim_type type) +{ + isl_space *space; + + space = isl_local_space_peek_space(ls); + switch (type) { + case isl_dim_param: + case isl_dim_in: + case isl_dim_out: return isl_space_offset(space, type); + case isl_dim_div: return isl_space_dim(space, isl_dim_all); + case isl_dim_cst: + default: + isl_die(isl_local_space_get_ctx(ls), isl_error_invalid, + "invalid dimension type", return isl_size_error); + } +} + +/* Return the position of the coefficients of the variables of the given type + * within the sequence of coefficients of "ls". + */ +unsigned isl_local_space_offset(__isl_keep isl_local_space *ls, + enum isl_dim_type type) +{ + if (!ls) + return 0; + + switch (type) { + case isl_dim_cst: return 0; + case isl_dim_param: + case isl_dim_in: + case isl_dim_out: + case isl_dim_div: return 1 + isl_local_space_var_offset(ls, type); + default: return 0; + } +} + +/* Return the position of the dimension of the given type and name + * in "ls". + * Return -1 if no such dimension can be found. + */ +int isl_local_space_find_dim_by_name(__isl_keep isl_local_space *ls, + enum isl_dim_type type, const char *name) +{ + if (!ls) + return -1; + if (type == isl_dim_div) + return -1; + return isl_space_find_dim_by_name(ls->dim, type, name); +} + +/* Does the given dimension have a name? + */ +isl_bool isl_local_space_has_dim_name(__isl_keep isl_local_space *ls, + enum isl_dim_type type, unsigned pos) +{ + return ls ? isl_space_has_dim_name(ls->dim, type, pos) : isl_bool_error; +} + +const char *isl_local_space_get_dim_name(__isl_keep isl_local_space *ls, + enum isl_dim_type type, unsigned pos) +{ + return ls ? isl_space_get_dim_name(ls->dim, type, pos) : NULL; +} + +isl_bool isl_local_space_has_dim_id(__isl_keep isl_local_space *ls, + enum isl_dim_type type, unsigned pos) +{ + return ls ? isl_space_has_dim_id(ls->dim, type, pos) : isl_bool_error; +} + +__isl_give isl_id *isl_local_space_get_dim_id(__isl_keep isl_local_space *ls, + enum isl_dim_type type, unsigned pos) +{ + return ls ? isl_space_get_dim_id(ls->dim, type, pos) : NULL; +} + +/* Return the argument of the integer division at position "pos" in "ls". + * All local variables in "ls" are known to have a (complete) explicit + * representation. + */ +static __isl_give isl_aff *extract_div(__isl_keep isl_local_space *ls, int pos) +{ + isl_aff *aff; + + aff = isl_aff_alloc(isl_local_space_copy(ls)); + if (!aff) + return NULL; + isl_seq_cpy(aff->v->el, ls->div->row[pos], aff->v->size); + return aff; +} + +/* Return the argument of the integer division at position "pos" in "ls". + * The integer division at that position is known to have a complete + * explicit representation, but some of the others do not. + * Remove them first because the domain of an isl_aff + * is not allowed to have unknown local variables. + */ +static __isl_give isl_aff *drop_unknown_divs_and_extract_div( + __isl_keep isl_local_space *ls, int pos) +{ + int i; + isl_size n; + isl_bool unknown; + isl_aff *aff; + + n = isl_local_space_dim(ls, isl_dim_div); + if (n < 0) + return NULL; + ls = isl_local_space_copy(ls); + for (i = n - 1; i >= 0; --i) { + unknown = isl_local_space_div_is_marked_unknown(ls, i); + if (unknown < 0) + ls = isl_local_space_free(ls); + else if (!unknown) + continue; + ls = isl_local_space_drop_dims(ls, isl_dim_div, i, 1); + if (pos > i) + --pos; + } + aff = extract_div(ls, pos); + isl_local_space_free(ls); + return aff; +} + +/* Return the argument of the integer division at position "pos" in "ls". + * The integer division is assumed to have a complete explicit + * representation. If some of the other integer divisions + * do not have an explicit representation, then they need + * to be removed first because the domain of an isl_aff + * is not allowed to have unknown local variables. + */ +__isl_give isl_aff *isl_local_space_get_div(__isl_keep isl_local_space *ls, + int pos) +{ + isl_bool known; + + if (!ls) + return NULL; + + if (pos < 0 || pos >= ls->div->n_row) + isl_die(isl_local_space_get_ctx(ls), isl_error_invalid, + "index out of bounds", return NULL); + + known = isl_local_space_div_is_known(ls, pos); + if (known < 0) + return NULL; + if (!known) + isl_die(isl_local_space_get_ctx(ls), isl_error_invalid, + "expression of div unknown", return NULL); + if (!isl_local_space_is_set(ls)) + isl_die(isl_local_space_get_ctx(ls), isl_error_invalid, + "cannot represent divs of map spaces", return NULL); + + known = isl_local_space_divs_known(ls); + if (known < 0) + return NULL; + if (known) + return extract_div(ls, pos); + else + return drop_unknown_divs_and_extract_div(ls, pos); +} + +/* Return the space of "ls". + */ +__isl_keep isl_space *isl_local_space_peek_space(__isl_keep isl_local_space *ls) +{ + if (!ls) + return NULL; + + return ls->dim; +} + +__isl_give isl_space *isl_local_space_get_space(__isl_keep isl_local_space *ls) +{ + return isl_space_copy(isl_local_space_peek_space(ls)); +} + +/* 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; +} + +/* Return the local variables of "ls". + */ +__isl_keep isl_local *isl_local_space_peek_local(__isl_keep isl_local_space *ls) +{ + return ls ? ls->div : NULL; +} + +/* Return a copy of the local variables of "ls". + */ +__isl_give isl_local *isl_local_space_get_local(__isl_keep isl_local_space *ls) +{ + return isl_local_copy(isl_local_space_peek_local(ls)); +} + +/* Return the local variables of "ls". + * This may be either a copy or the local variables itself + * if there is only one reference to "ls". + * This allows the local variables to be modified inplace + * if both the local space and its local variables have only a single reference. + * The caller is not allowed to modify "ls" between this call and + * the subsequent call to isl_local_space_restore_local. + * The only exception is that isl_local_space_free can be called instead. + */ +static __isl_give isl_local *isl_local_space_take_local( + __isl_keep isl_local_space *ls) +{ + isl_local *local; + + if (!ls) + return NULL; + if (ls->ref != 1) + return isl_local_space_get_local(ls); + local = ls->div; + ls->div = NULL; + return local; +} + +/* Set the local variables of "ls" to "local", + * where the local variables of "ls" may be missing + * due to a preceding call to isl_local_space_take_local. + * However, in this case, "ls" only has a single reference and + * then the call to isl_local_space_cow has no effect. + */ +static __isl_give isl_local_space *isl_local_space_restore_local( + __isl_take isl_local_space *ls, __isl_take isl_local *local) +{ + if (!ls || !local) + goto error; + + if (ls->div == local) { + isl_local_free(local); + return ls; + } + + ls = isl_local_space_cow(ls); + if (!ls) + goto error; + isl_local_free(ls->div); + ls->div = local; + + return ls; +error: + isl_local_space_free(ls); + isl_local_free(local); + return NULL; +} + +/* Replace the identifier of the tuple of type "type" by "id". + */ +__isl_give isl_local_space *isl_local_space_set_tuple_id( + __isl_take isl_local_space *ls, + enum isl_dim_type type, __isl_take isl_id *id) +{ + ls = isl_local_space_cow(ls); + if (!ls) + goto error; + ls->dim = isl_space_set_tuple_id(ls->dim, type, id); + if (!ls->dim) + return isl_local_space_free(ls); + return ls; +error: + isl_id_free(id); + return NULL; +} + +__isl_give isl_local_space *isl_local_space_set_dim_name( + __isl_take isl_local_space *ls, + enum isl_dim_type type, unsigned pos, const char *s) +{ + ls = isl_local_space_cow(ls); + if (!ls) + return NULL; + ls->dim = isl_space_set_dim_name(ls->dim, type, pos, s); + if (!ls->dim) + return isl_local_space_free(ls); + + return ls; +} + +__isl_give isl_local_space *isl_local_space_set_dim_id( + __isl_take isl_local_space *ls, + enum isl_dim_type type, unsigned pos, __isl_take isl_id *id) +{ + ls = isl_local_space_cow(ls); + if (!ls) + goto error; + ls->dim = isl_space_set_dim_id(ls->dim, type, pos, id); + if (!ls->dim) + return isl_local_space_free(ls); + + return ls; +error: + isl_id_free(id); + 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 *space) +{ + ls = isl_local_space_cow(ls); + if (!ls || !space) + goto error; + + isl_space_free(ls->dim); + ls->dim = space; + + return ls; +error: + isl_local_space_free(ls); + isl_space_free(space); + return NULL; +} + +/* Reorder the dimensions of "ls" according to the given reordering. + * The reordering r is assumed to have been extended with the local + * variables, leaving them in the same order. + */ +__isl_give isl_local_space *isl_local_space_realign( + __isl_take isl_local_space *ls, __isl_take isl_reordering *r) +{ + isl_local *local; + + local = isl_local_space_take_local(ls); + local = isl_local_reorder(local, isl_reordering_copy(r)); + ls = isl_local_space_restore_local(ls, local); + + ls = isl_local_space_reset_space(ls, isl_reordering_get_space(r)); + + isl_reordering_free(r); + return ls; +} + +__isl_give isl_local_space *isl_local_space_add_div( + __isl_take isl_local_space *ls, __isl_take isl_vec *div) +{ + ls = isl_local_space_cow(ls); + if (!ls || !div) + goto error; + + if (ls->div->n_col != div->size) + isl_die(isl_local_space_get_ctx(ls), isl_error_invalid, + "incompatible dimensions", goto error); + + ls->div = isl_mat_add_zero_cols(ls->div, 1); + ls->div = isl_mat_add_rows(ls->div, 1); + if (!ls->div) + goto error; + + isl_seq_cpy(ls->div->row[ls->div->n_row - 1], div->el, div->size); + isl_int_set_si(ls->div->row[ls->div->n_row - 1][div->size], 0); + + isl_vec_free(div); + return ls; +error: + isl_local_space_free(ls); + isl_vec_free(div); + return NULL; +} + +__isl_give isl_local_space *isl_local_space_replace_divs( + __isl_take isl_local_space *ls, __isl_take isl_mat *div) +{ + ls = isl_local_space_cow(ls); + + if (!ls || !div) + goto error; + + isl_mat_free(ls->div); + ls->div = div; + return ls; +error: + isl_mat_free(div); + isl_local_space_free(ls); + return NULL; +} + +/* Copy row "s" of "src" to row "d" of "dst", applying the expansion + * defined by "exp". + */ +static void expand_row(__isl_keep isl_mat *dst, int d, + __isl_keep isl_mat *src, int s, int *exp) +{ + int i; + unsigned c = src->n_col - src->n_row; + + isl_seq_cpy(dst->row[d], src->row[s], c); + isl_seq_clr(dst->row[d] + c, dst->n_col - c); + + for (i = 0; i < s; ++i) + isl_int_set(dst->row[d][c + exp[i]], src->row[s][c + i]); +} + +/* Compare (known) divs. + * Return non-zero if at least one of the two divs is unknown. + * In particular, if both divs are unknown, we respect their + * current order. Otherwise, we sort the known div after the unknown + * div only if the known div depends on the unknown div. + */ +static int cmp_row(isl_int *row_i, isl_int *row_j, int i, int j, + unsigned n_row, unsigned n_col) +{ + int li, lj; + int unknown_i, unknown_j; + + unknown_i = isl_int_is_zero(row_i[0]); + unknown_j = isl_int_is_zero(row_j[0]); + + if (unknown_i && unknown_j) + return i - j; + + if (unknown_i) + li = n_col - n_row + i; + else + li = isl_seq_last_non_zero(row_i, n_col); + if (unknown_j) + lj = n_col - n_row + j; + else + lj = isl_seq_last_non_zero(row_j, n_col); + + if (li != lj) + return li - lj; + + return isl_seq_cmp(row_i, row_j, n_col); +} + +/* Call cmp_row for divs in a matrix. + */ +int isl_mat_cmp_div(__isl_keep isl_mat *div, int i, int j) +{ + return cmp_row(div->row[i], div->row[j], i, j, div->n_row, div->n_col); +} + +/* Call cmp_row for divs in a basic map. + */ +static int bmap_cmp_row(__isl_keep isl_basic_map *bmap, int i, int j, + unsigned total) +{ + return cmp_row(bmap->div[i], bmap->div[j], i, j, bmap->n_div, total); +} + +/* Sort the divs in "bmap". + * + * We first make sure divs are placed after divs on which they depend. + * Then we perform a simple insertion sort based on the same ordering + * that is used in isl_merge_divs. + */ +__isl_give isl_basic_map *isl_basic_map_sort_divs( + __isl_take isl_basic_map *bmap) +{ + int i, j; + isl_size total; + + bmap = isl_basic_map_order_divs(bmap); + if (!bmap) + return NULL; + if (bmap->n_div <= 1) + return bmap; + + total = isl_basic_map_dim(bmap, isl_dim_all); + if (total < 0) + return isl_basic_map_free(bmap); + for (i = 1; i < bmap->n_div; ++i) { + for (j = i - 1; j >= 0; --j) { + if (bmap_cmp_row(bmap, j, j + 1, 2 + total) <= 0) + break; + bmap = isl_basic_map_swap_div(bmap, j, j + 1); + if (!bmap) + return NULL; + } + } + + return bmap; +} + +/* Sort the divs in the basic maps of "map". + */ +__isl_give isl_map *isl_map_sort_divs(__isl_take isl_map *map) +{ + return isl_map_inline_foreach_basic_map(map, &isl_basic_map_sort_divs); +} + +/* Combine the two lists of divs into a single list. + * For each row i in div1, exp1[i] is set to the position of the corresponding + * row in the result. Similarly for div2 and exp2. + * This function guarantees + * exp1[i] >= i + * exp1[i+1] > exp1[i] + * For optimal merging, the two input list should have been sorted. + */ +__isl_give isl_mat *isl_merge_divs(__isl_keep isl_mat *div1, + __isl_keep isl_mat *div2, int *exp1, int *exp2) +{ + int i, j, k; + isl_mat *div = NULL; + unsigned d; + + if (!div1 || !div2) + return NULL; + + d = div1->n_col - div1->n_row; + div = isl_mat_alloc(div1->ctx, 1 + div1->n_row + div2->n_row, + d + div1->n_row + div2->n_row); + if (!div) + return NULL; + + for (i = 0, j = 0, k = 0; i < div1->n_row && j < div2->n_row; ++k) { + int cmp; + + expand_row(div, k, div1, i, exp1); + expand_row(div, k + 1, div2, j, exp2); + + cmp = isl_mat_cmp_div(div, k, k + 1); + if (cmp == 0) { + exp1[i++] = k; + exp2[j++] = k; + } else if (cmp < 0) { + exp1[i++] = k; + } else { + exp2[j++] = k; + isl_seq_cpy(div->row[k], div->row[k + 1], div->n_col); + } + } + for (; i < div1->n_row; ++i, ++k) { + expand_row(div, k, div1, i, exp1); + exp1[i] = k; + } + for (; j < div2->n_row; ++j, ++k) { + expand_row(div, k, div2, j, exp2); + exp2[j] = k; + } + + div->n_row = k; + div->n_col = d + k; + + return div; +} + +/* Swap divs "a" and "b" in "ls". + */ +__isl_give isl_local_space *isl_local_space_swap_div( + __isl_take isl_local_space *ls, int a, int b) +{ + int offset; + + ls = isl_local_space_cow(ls); + if (!ls) + return NULL; + if (a < 0 || a >= ls->div->n_row || b < 0 || b >= ls->div->n_row) + isl_die(isl_local_space_get_ctx(ls), isl_error_invalid, + "index out of bounds", return isl_local_space_free(ls)); + offset = ls->div->n_col - ls->div->n_row; + ls->div = isl_mat_swap_cols(ls->div, offset + a, offset + b); + ls->div = isl_mat_swap_rows(ls->div, a, b); + if (!ls->div) + return isl_local_space_free(ls); + return ls; +} + +/* Construct a local space that contains all the divs in either + * "ls1" or "ls2". + */ +__isl_give isl_local_space *isl_local_space_intersect( + __isl_take isl_local_space *ls1, __isl_take isl_local_space *ls2) +{ + isl_ctx *ctx; + int *exp1 = NULL; + int *exp2 = NULL; + isl_mat *div = NULL; + isl_bool equal; + + if (!ls1 || !ls2) + goto error; + + ctx = isl_local_space_get_ctx(ls1); + if (!isl_space_is_equal(ls1->dim, ls2->dim)) + isl_die(ctx, isl_error_invalid, + "spaces should be identical", goto error); + + if (ls2->div->n_row == 0) { + isl_local_space_free(ls2); + return ls1; + } + + if (ls1->div->n_row == 0) { + isl_local_space_free(ls1); + return ls2; + } + + exp1 = isl_alloc_array(ctx, int, ls1->div->n_row); + exp2 = isl_alloc_array(ctx, int, ls2->div->n_row); + if (!exp1 || !exp2) + goto error; + + div = isl_merge_divs(ls1->div, ls2->div, exp1, exp2); + if (!div) + goto error; + + equal = isl_mat_is_equal(ls1->div, div); + if (equal < 0) + goto error; + if (!equal) + ls1 = isl_local_space_cow(ls1); + if (!ls1) + goto error; + + free(exp1); + free(exp2); + isl_local_space_free(ls2); + isl_mat_free(ls1->div); + ls1->div = div; + + return ls1; +error: + free(exp1); + free(exp2); + isl_mat_free(div); + isl_local_space_free(ls1); + isl_local_space_free(ls2); + return NULL; +} + +/* Is the local variable "div" of "ls" marked as not having + * an explicit representation? + * Note that even if this variable is not marked in this way and therefore + * does have an explicit representation, this representation may still + * depend (indirectly) on other local variables that do not + * have an explicit representation. + */ +isl_bool isl_local_space_div_is_marked_unknown(__isl_keep isl_local_space *ls, + int div) +{ + if (!ls) + return isl_bool_error; + return isl_local_div_is_marked_unknown(ls->div, div); +} + +/* Does "ls" have a complete explicit representation for div "div"? + */ +isl_bool isl_local_space_div_is_known(__isl_keep isl_local_space *ls, int div) +{ + if (!ls) + return isl_bool_error; + return isl_local_div_is_known(ls->div, div); +} + +/* Does "ls" have an explicit representation for all local variables? + */ +isl_bool isl_local_space_divs_known(__isl_keep isl_local_space *ls) +{ + if (!ls) + return isl_bool_error; + return isl_local_divs_known(ls->div); +} + +__isl_give isl_local_space *isl_local_space_domain( + __isl_take isl_local_space *ls) +{ + isl_size n_out; + + n_out = isl_local_space_dim(ls, isl_dim_out); + if (n_out < 0) + return isl_local_space_free(ls); + ls = isl_local_space_drop_dims(ls, isl_dim_out, 0, n_out); + ls = isl_local_space_cow(ls); + if (!ls) + return NULL; + ls->dim = isl_space_domain(ls->dim); + if (!ls->dim) + return isl_local_space_free(ls); + return ls; +} + +__isl_give isl_local_space *isl_local_space_range( + __isl_take isl_local_space *ls) +{ + isl_size n_in; + + n_in = isl_local_space_dim(ls, isl_dim_in); + if (n_in < 0) + return isl_local_space_free(ls); + ls = isl_local_space_drop_dims(ls, isl_dim_in, 0, n_in); + ls = isl_local_space_cow(ls); + if (!ls) + return NULL; + + ls->dim = isl_space_range(ls->dim); + if (!ls->dim) + return isl_local_space_free(ls); + return ls; +} + +/* Construct a local space for a map that has the given local + * space as domain and that has a zero-dimensional range. + */ +__isl_give isl_local_space *isl_local_space_from_domain( + __isl_take isl_local_space *ls) +{ + ls = isl_local_space_cow(ls); + if (!ls) + return NULL; + ls->dim = isl_space_from_domain(ls->dim); + if (!ls->dim) + return isl_local_space_free(ls); + return ls; +} + +__isl_give isl_local_space *isl_local_space_add_dims( + __isl_take isl_local_space *ls, enum isl_dim_type type, unsigned n) +{ + isl_size pos; + + pos = isl_local_space_dim(ls, type); + if (pos < 0) + return isl_local_space_free(ls); + return isl_local_space_insert_dims(ls, type, pos, n); +} + +/* Lift the basic set "bset", living in the space of "ls" + * to live in a space with extra coordinates corresponding + * to the local variables of "ls". + */ +__isl_give isl_basic_set *isl_local_space_lift_basic_set( + __isl_take isl_local_space *ls, __isl_take isl_basic_set *bset) +{ + isl_size n_local; + isl_space *space; + isl_basic_set *ls_bset; + + n_local = isl_local_space_dim(ls, isl_dim_div); + space = isl_basic_set_peek_space(bset); + if (n_local < 0 || + isl_local_space_check_has_space(ls, space) < 0) + goto error; + + if (n_local == 0) { + isl_local_space_free(ls); + return bset; + } + + bset = isl_basic_set_add_dims(bset, isl_dim_set, n_local); + ls_bset = isl_basic_set_from_local_space(ls); + ls_bset = isl_basic_set_lift(ls_bset); + ls_bset = isl_basic_set_flatten(ls_bset); + bset = isl_basic_set_intersect(bset, ls_bset); + + return bset; +error: + isl_local_space_free(ls); + isl_basic_set_free(bset); + return NULL; +} + +/* Lift the set "set", living in the space of "ls" + * to live in a space with extra coordinates corresponding + * to the local variables of "ls". + */ +__isl_give isl_set *isl_local_space_lift_set(__isl_take isl_local_space *ls, + __isl_take isl_set *set) +{ + isl_size n_local; + isl_basic_set *bset; + + n_local = isl_local_space_dim(ls, isl_dim_div); + if (n_local < 0 || + isl_local_space_check_has_space(ls, isl_set_peek_space(set)) < 0) + goto error; + + if (n_local == 0) { + isl_local_space_free(ls); + return set; + } + + set = isl_set_add_dims(set, isl_dim_set, n_local); + bset = isl_basic_set_from_local_space(ls); + bset = isl_basic_set_lift(bset); + bset = isl_basic_set_flatten(bset); + set = isl_set_intersect(set, isl_set_from_basic_set(bset)); + + return set; +error: + isl_local_space_free(ls); + isl_set_free(set); + return NULL; +} + +/* Remove common factor of non-constant terms and denominator. + */ +static __isl_give isl_local_space *normalize_div( + __isl_take isl_local_space *ls, int div) +{ + isl_ctx *ctx = ls->div->ctx; + unsigned total = ls->div->n_col - 2; + + isl_seq_gcd(ls->div->row[div] + 2, total, &ctx->normalize_gcd); + isl_int_gcd(ctx->normalize_gcd, + ctx->normalize_gcd, ls->div->row[div][0]); + if (isl_int_is_one(ctx->normalize_gcd)) + return ls; + + isl_seq_scale_down(ls->div->row[div] + 2, ls->div->row[div] + 2, + ctx->normalize_gcd, total); + isl_int_divexact(ls->div->row[div][0], ls->div->row[div][0], + ctx->normalize_gcd); + isl_int_fdiv_q(ls->div->row[div][1], ls->div->row[div][1], + ctx->normalize_gcd); + + return ls; +} + +/* Exploit the equalities in "eq" to simplify the expressions of + * the integer divisions in "ls". + * The integer divisions in "ls" are assumed to appear as regular + * dimensions in "eq". + */ +__isl_give isl_local_space *isl_local_space_substitute_equalities( + __isl_take isl_local_space *ls, __isl_take isl_basic_set *eq) +{ + int i, j, k; + isl_size total, dim; + unsigned n_div; + + if (!ls || !eq) + goto error; + + total = isl_space_dim(eq->dim, isl_dim_all); + dim = isl_local_space_dim(ls, isl_dim_all); + if (dim < 0 || total < 0) + goto error; + if (dim != total) + isl_die(isl_local_space_get_ctx(ls), isl_error_invalid, + "spaces don't match", goto error); + total++; + n_div = eq->n_div; + for (i = 0; i < eq->n_eq; ++i) { + j = isl_seq_last_non_zero(eq->eq[i], total + n_div); + if (j < 0 || j == 0 || j >= total) + continue; + + for (k = 0; k < ls->div->n_row; ++k) { + if (isl_int_is_zero(ls->div->row[k][1 + j])) + continue; + ls = isl_local_space_cow(ls); + if (!ls) + goto error; + ls->div = isl_mat_cow(ls->div); + if (!ls->div) + goto error; + isl_seq_elim(ls->div->row[k] + 1, eq->eq[i], j, total, + &ls->div->row[k][0]); + ls = normalize_div(ls, k); + if (!ls) + goto error; + } + } + + isl_basic_set_free(eq); + return ls; +error: + isl_basic_set_free(eq); + isl_local_space_free(ls); + return NULL; +} + +/* Plug in the affine expressions "subs" of length "subs_len" (including + * the denominator and the constant term) into the variable at position "pos" + * of the "n" div expressions starting at "first". + * + * Let i be the dimension to replace and let "subs" be of the form + * + * f/d + * + * Any integer division starting at "first" with a non-zero coefficient for i, + * + * floor((a i + g)/m) + * + * is replaced by + * + * floor((a f + d g)/(m d)) + */ +__isl_give isl_local_space *isl_local_space_substitute_seq( + __isl_take isl_local_space *ls, + enum isl_dim_type type, unsigned pos, isl_int *subs, int subs_len, + int first, int n) +{ + int i; + isl_int v; + + if (n == 0) + return ls; + ls = isl_local_space_cow(ls); + if (!ls) + return NULL; + ls->div = isl_mat_cow(ls->div); + if (!ls->div) + return isl_local_space_free(ls); + + if (first + n > ls->div->n_row) + isl_die(isl_local_space_get_ctx(ls), isl_error_invalid, + "index out of bounds", return isl_local_space_free(ls)); + + pos += isl_local_space_offset(ls, type); + + isl_int_init(v); + for (i = first; i < first + n; ++i) { + if (isl_int_is_zero(ls->div->row[i][1 + pos])) + continue; + isl_seq_substitute(ls->div->row[i], pos, subs, + ls->div->n_col, subs_len, v); + ls = normalize_div(ls, i); + if (!ls) + break; + } + isl_int_clear(v); + + return ls; +} + +/* Plug in "subs" for dimension "type", "pos" in the integer divisions + * of "ls". + * + * Let i be the dimension to replace and let "subs" be of the form + * + * f/d + * + * Any integer division with a non-zero coefficient for i, + * + * floor((a i + g)/m) + * + * is replaced by + * + * floor((a f + d g)/(m d)) + */ +__isl_give isl_local_space *isl_local_space_substitute( + __isl_take isl_local_space *ls, + enum isl_dim_type type, unsigned pos, __isl_keep isl_aff *subs) +{ + isl_size n_div; + + ls = isl_local_space_cow(ls); + if (!ls || !subs) + return isl_local_space_free(ls); + + if (!isl_space_is_equal(ls->dim, subs->ls->dim)) + isl_die(isl_local_space_get_ctx(ls), isl_error_invalid, + "spaces don't match", return isl_local_space_free(ls)); + n_div = isl_local_space_dim(subs->ls, isl_dim_div); + if (n_div < 0) + return isl_local_space_free(ls); + if (n_div != 0) + isl_die(isl_local_space_get_ctx(ls), isl_error_unsupported, + "cannot handle divs yet", + return isl_local_space_free(ls)); + + return isl_local_space_substitute_seq(ls, type, pos, subs->v->el, + subs->v->size, 0, ls->div->n_row); +} + +isl_bool isl_local_space_is_named_or_nested(__isl_keep isl_local_space *ls, + enum isl_dim_type type) +{ + if (!ls) + return isl_bool_error; + return isl_space_is_named_or_nested(ls->dim, type); +} + +__isl_give isl_local_space *isl_local_space_drop_dims( + __isl_take isl_local_space *ls, + enum isl_dim_type type, unsigned first, unsigned n) +{ + if (!ls) + return NULL; + if (n == 0 && !isl_local_space_is_named_or_nested(ls, type)) + return ls; + + if (isl_local_space_check_range(ls, type, first, n) < 0) + return isl_local_space_free(ls); + + ls = isl_local_space_cow(ls); + if (!ls) + return NULL; + + if (type == isl_dim_div) { + ls->div = isl_mat_drop_rows(ls->div, first, n); + } else { + ls->dim = isl_space_drop_dims(ls->dim, type, first, n); + if (!ls->dim) + return isl_local_space_free(ls); + } + + first += 1 + isl_local_space_offset(ls, type); + ls->div = isl_mat_drop_cols(ls->div, first, n); + if (!ls->div) + return isl_local_space_free(ls); + + return ls; +} + +__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) +{ + if (!ls) + return NULL; + if (n == 0 && !isl_local_space_is_named_or_nested(ls, type)) + return ls; + + if (isl_local_space_check_range(ls, type, first, 0) < 0) + return isl_local_space_free(ls); + + ls = isl_local_space_cow(ls); + if (!ls) + return NULL; + + if (type == isl_dim_div) { + ls->div = isl_mat_insert_zero_rows(ls->div, first, n); + } else { + ls->dim = isl_space_insert_dims(ls->dim, type, first, n); + if (!ls->dim) + return isl_local_space_free(ls); + } + + first += 1 + isl_local_space_offset(ls, type); + ls->div = isl_mat_insert_zero_cols(ls->div, first, n); + if (!ls->div) + return isl_local_space_free(ls); + + return ls; +} + +/* Does the linear part of "constraint" correspond to + * integer division "div" in "ls"? + * + * That is, given div = floor((c + f)/m), is the constraint of the form + * + * f - m d + c' >= 0 [sign = 1] + * or + * -f + m d + c'' >= 0 [sign = -1] + * ? + * If so, set *sign to the corresponding value. + */ +static isl_bool is_linear_div_constraint(__isl_keep isl_local_space *ls, + isl_int *constraint, unsigned div, int *sign) +{ + isl_bool unknown; + unsigned pos; + + unknown = isl_local_space_div_is_marked_unknown(ls, div); + if (unknown < 0) + return isl_bool_error; + if (unknown) + return isl_bool_false; + + pos = isl_local_space_offset(ls, isl_dim_div) + div; + + if (isl_int_eq(constraint[pos], ls->div->row[div][0])) { + *sign = -1; + if (!isl_seq_is_neg(constraint + 1, + ls->div->row[div] + 2, pos - 1)) + return isl_bool_false; + } else if (isl_int_abs_eq(constraint[pos], ls->div->row[div][0])) { + *sign = 1; + if (!isl_seq_eq(constraint + 1, ls->div->row[div] + 2, pos - 1)) + return isl_bool_false; + } else { + return isl_bool_false; + } + if (isl_seq_first_non_zero(constraint + pos + 1, + ls->div->n_row - div - 1) != -1) + return isl_bool_false; + return isl_bool_true; +} + +/* Check if the constraints pointed to by "constraint" is a div + * constraint corresponding to div "div" in "ls". + * + * That is, if div = floor(f/m), then check if the constraint is + * + * f - m d >= 0 + * or + * -(f-(m-1)) + m d >= 0 + * + * First check if the linear part is of the right form and + * then check the constant term. + */ +isl_bool isl_local_space_is_div_constraint(__isl_keep isl_local_space *ls, + isl_int *constraint, unsigned div) +{ + int sign; + isl_bool linear; + + linear = is_linear_div_constraint(ls, constraint, div, &sign); + if (linear < 0 || !linear) + return linear; + + if (sign < 0) { + int neg; + isl_int_sub(ls->div->row[div][1], + ls->div->row[div][1], ls->div->row[div][0]); + isl_int_add_ui(ls->div->row[div][1], ls->div->row[div][1], 1); + neg = isl_seq_is_neg(constraint, ls->div->row[div] + 1, 1); + isl_int_sub_ui(ls->div->row[div][1], ls->div->row[div][1], 1); + isl_int_add(ls->div->row[div][1], + ls->div->row[div][1], ls->div->row[div][0]); + if (!neg) + return isl_bool_false; + } else { + if (!isl_int_eq(constraint[0], ls->div->row[div][1])) + return isl_bool_false; + } + + return isl_bool_true; +} + +/* Is the constraint pointed to by "constraint" one + * of an equality that corresponds to integer division "div" in "ls"? + * + * That is, given an integer division of the form + * + * a = floor((f + c)/m) + * + * is the equality of the form + * + * -f + m d + c' = 0 + * ? + * Note that the constant term is not checked explicitly, but given + * that this is a valid equality constraint, the constant c' necessarily + * has a value close to -c. + */ +isl_bool isl_local_space_is_div_equality(__isl_keep isl_local_space *ls, + isl_int *constraint, unsigned div) +{ + int sign; + isl_bool linear; + + linear = is_linear_div_constraint(ls, constraint, div, &sign); + if (linear < 0 || !linear) + return linear; + + return isl_bool_ok(sign < 0); +} + +/* + * Set active[i] to 1 if the dimension at position i is involved + * in the linear expression l. + */ +int *isl_local_space_get_active(__isl_keep isl_local_space *ls, isl_int *l) +{ + int i, j; + isl_ctx *ctx; + int *active = NULL; + isl_size total; + unsigned offset; + + ctx = isl_local_space_get_ctx(ls); + total = isl_local_space_dim(ls, isl_dim_all); + if (total < 0) + return NULL; + active = isl_calloc_array(ctx, int, total); + if (total && !active) + return NULL; + + for (i = 0; i < total; ++i) + active[i] = !isl_int_is_zero(l[i]); + + offset = isl_local_space_offset(ls, isl_dim_div) - 1; + for (i = ls->div->n_row - 1; i >= 0; --i) { + if (!active[offset + i]) + continue; + for (j = 0; j < total; ++j) + active[j] |= !isl_int_is_zero(ls->div->row[i][2 + j]); + } + + return active; +} + +/* Given a local space "ls" of a set, create a local space + * for the lift of the set. In particular, the result + * is of the form [dim -> local[..]], with ls->div->n_row variables in the + * range of the wrapped map. + */ +__isl_give isl_local_space *isl_local_space_lift( + __isl_take isl_local_space *ls) +{ + ls = isl_local_space_cow(ls); + if (!ls) + return NULL; + + ls->dim = isl_space_lift(ls->dim, ls->div->n_row); + ls->div = isl_mat_drop_rows(ls->div, 0, ls->div->n_row); + if (!ls->dim || !ls->div) + return isl_local_space_free(ls); + + return ls; +} + +/* Construct a basic map that maps a set living in local space "ls" + * to the corresponding lifted local space. + */ +__isl_give isl_basic_map *isl_local_space_lifting( + __isl_take isl_local_space *ls) +{ + isl_basic_map *lifting; + isl_basic_set *bset; + + if (!ls) + return NULL; + if (!isl_local_space_is_set(ls)) + isl_die(isl_local_space_get_ctx(ls), isl_error_invalid, + "lifting only defined on set spaces", goto error); + + bset = isl_basic_set_from_local_space(ls); + lifting = isl_basic_set_unwrap(isl_basic_set_lift(bset)); + lifting = isl_basic_map_domain_map(lifting); + lifting = isl_basic_map_reverse(lifting); + + return lifting; +error: + isl_local_space_free(ls); + return NULL; +} + +/* Compute the preimage of "ls" under the function represented by "ma". + * In other words, plug in "ma" in "ls". The result is a local space + * that is part of the domain space of "ma". + * + * If the divs in "ls" are represented as + * + * floor((a_i(p) + b_i x + c_i(divs))/n_i) + * + * and ma is represented by + * + * x = D(p) + F(y) + G(divs') + * + * then the resulting divs are + * + * floor((a_i(p) + b_i D(p) + b_i F(y) + B_i G(divs') + c_i(divs))/n_i) + * + * We first copy over the divs from "ma" and then + * we add the modified divs from "ls". + */ +__isl_give isl_local_space *isl_local_space_preimage_multi_aff( + __isl_take isl_local_space *ls, __isl_take isl_multi_aff *ma) +{ + int i; + isl_space *space; + isl_local_space *res = NULL; + isl_size n_div_ls, n_div_ma; + isl_int f, c1, c2, g; + + ma = isl_multi_aff_align_divs(ma); + if (!ls || !ma) + goto error; + if (!isl_space_is_range_internal(ls->dim, ma->space)) + isl_die(isl_local_space_get_ctx(ls), isl_error_invalid, + "spaces don't match", goto error); + + n_div_ls = isl_local_space_dim(ls, isl_dim_div); + n_div_ma = ma->n ? isl_aff_dim(ma->u.p[0], isl_dim_div) : 0; + if (n_div_ls < 0 || n_div_ma < 0) + goto error; + + space = isl_space_domain(isl_multi_aff_get_space(ma)); + res = isl_local_space_alloc(space, n_div_ma + n_div_ls); + if (!res) + goto error; + + if (n_div_ma) { + isl_mat_free(res->div); + res->div = isl_mat_copy(ma->u.p[0]->ls->div); + res->div = isl_mat_add_zero_cols(res->div, n_div_ls); + res->div = isl_mat_add_rows(res->div, n_div_ls); + if (!res->div) + goto error; + } + + isl_int_init(f); + isl_int_init(c1); + isl_int_init(c2); + isl_int_init(g); + + for (i = 0; i < ls->div->n_row; ++i) { + if (isl_int_is_zero(ls->div->row[i][0])) { + isl_int_set_si(res->div->row[n_div_ma + i][0], 0); + continue; + } + if (isl_seq_preimage(res->div->row[n_div_ma + i], + ls->div->row[i], + ma, 0, 0, n_div_ma, n_div_ls, f, c1, c2, g, 1) < 0) + res = isl_local_space_free(res); + res = normalize_div(res, n_div_ma + i); + if (!res) + break; + } + + isl_int_clear(f); + isl_int_clear(c1); + isl_int_clear(c2); + isl_int_clear(g); + + isl_local_space_free(ls); + isl_multi_aff_free(ma); + return res; +error: + isl_local_space_free(ls); + isl_multi_aff_free(ma); + isl_local_space_free(res); + return NULL; +} + +/* Move the "n" dimensions of "src_type" starting at "src_pos" of "ls" + * to dimensions of "dst_type" at "dst_pos". + * + * Moving to/from local dimensions is not allowed. + * We currently assume that the dimension type changes. + */ +__isl_give isl_local_space *isl_local_space_move_dims( + __isl_take isl_local_space *ls, + enum isl_dim_type dst_type, unsigned dst_pos, + enum isl_dim_type src_type, unsigned src_pos, unsigned n) +{ + isl_space *space; + isl_local *local; + isl_size v_src, v_dst; + unsigned g_dst_pos; + unsigned g_src_pos; + + if (!ls) + return NULL; + if (n == 0 && + !isl_local_space_is_named_or_nested(ls, src_type) && + !isl_local_space_is_named_or_nested(ls, dst_type)) + return ls; + + if (isl_local_space_check_range(ls, src_type, src_pos, n) < 0) + return isl_local_space_free(ls); + if (isl_local_space_check_range(ls, dst_type, dst_pos, 0) < 0) + return isl_local_space_free(ls); + if (src_type == isl_dim_div) + isl_die(isl_local_space_get_ctx(ls), isl_error_invalid, + "cannot move divs", return isl_local_space_free(ls)); + if (dst_type == isl_dim_div) + isl_die(isl_local_space_get_ctx(ls), isl_error_invalid, + "cannot move to divs", return isl_local_space_free(ls)); + if (dst_type == src_type && dst_pos == src_pos) + return ls; + if (dst_type == src_type) + isl_die(isl_local_space_get_ctx(ls), isl_error_unsupported, + "moving dims within the same type not supported", + return isl_local_space_free(ls)); + + v_src = isl_local_space_var_offset(ls, src_type); + v_dst = isl_local_space_var_offset(ls, dst_type); + if (v_src < 0 || v_dst < 0) + return isl_local_space_free(ls); + g_src_pos = v_src + src_pos; + g_dst_pos = v_dst + dst_pos; + if (dst_type > src_type) + g_dst_pos -= n; + + local = isl_local_space_take_local(ls); + local = isl_local_move_vars(local, g_dst_pos, g_src_pos, n); + ls = isl_local_space_restore_local(ls, local); + + space = isl_local_space_take_space(ls); + space = isl_space_move_dims(space, dst_type, dst_pos, + src_type, src_pos, n); + ls = isl_local_space_restore_space(ls, space); + + return ls; +} + +/* Given a local space (A -> B), return the corresponding local space + * (B -> A). + */ +__isl_give isl_local_space *isl_local_space_wrapped_reverse( + __isl_take isl_local_space *ls) +{ + isl_space *space; + isl_local *local; + isl_size n_in, n_out; + unsigned offset; + + space = isl_local_space_peek_space(ls); + offset = isl_space_offset(space, isl_dim_set); + n_in = isl_space_wrapped_dim(space, isl_dim_set, isl_dim_in); + n_out = isl_space_wrapped_dim(space, isl_dim_set, isl_dim_out); + if (offset < 0 || n_in < 0 || n_out < 0) + return isl_local_space_free(ls); + + space = isl_local_space_take_space(ls); + space = isl_space_wrapped_reverse(space); + ls = isl_local_space_restore_space(ls, space); + + local = isl_local_space_take_local(ls); + local = isl_local_move_vars(local, offset, offset + n_in, n_out); + ls = isl_local_space_restore_local(ls, local); + + return ls; +} + +/* Remove any internal structure of the domain of "ls". + * If there is any such internal structure in the input, + * then the name of the corresponding space is also removed. + */ +__isl_give isl_local_space *isl_local_space_flatten_domain( + __isl_take isl_local_space *ls) +{ + if (!ls) + return NULL; + + if (!ls->dim->nested[0]) + return ls; + + ls = isl_local_space_cow(ls); + if (!ls) + return NULL; + + ls->dim = isl_space_flatten_domain(ls->dim); + if (!ls->dim) + return isl_local_space_free(ls); + + return ls; +} + +/* Remove any internal structure of the range of "ls". + * If there is any such internal structure in the input, + * then the name of the corresponding space is also removed. + */ +__isl_give isl_local_space *isl_local_space_flatten_range( + __isl_take isl_local_space *ls) +{ + if (!ls) + return NULL; + + if (!ls->dim->nested[1]) + return ls; + + ls = isl_local_space_cow(ls); + if (!ls) + return NULL; + + ls->dim = isl_space_flatten_range(ls->dim); + if (!ls->dim) + return isl_local_space_free(ls); + + return ls; +} + +/* Given the local space "ls" of a map, return the local space of a set + * that lives in a space that wraps the space of "ls" and that has + * the same divs. + */ +__isl_give isl_local_space *isl_local_space_wrap(__isl_take isl_local_space *ls) +{ + ls = isl_local_space_cow(ls); + if (!ls) + return NULL; + + ls->dim = isl_space_wrap(ls->dim); + if (!ls->dim) + return isl_local_space_free(ls); + + return ls; +} + +/* Lift the point "pnt", living in the (set) space of "ls" + * to live in a space with extra coordinates corresponding + * to the local variables of "ls". + */ +__isl_give isl_point *isl_local_space_lift_point(__isl_take isl_local_space *ls, + __isl_take isl_point *pnt) +{ + isl_size n_local; + isl_space *space; + isl_local *local; + isl_vec *vec; + + if (isl_local_space_check_has_space(ls, isl_point_peek_space(pnt)) < 0) + goto error; + + local = isl_local_space_peek_local(ls); + n_local = isl_local_space_dim(ls, isl_dim_div); + if (n_local < 0) + goto error; + + space = isl_point_take_space(pnt); + vec = isl_point_take_vec(pnt); + + space = isl_space_lift(space, n_local); + vec = isl_local_extend_point_vec(local, vec); + + pnt = isl_point_restore_vec(pnt, vec); + pnt = isl_point_restore_space(pnt, space); + + isl_local_space_free(ls); + + return pnt; +error: + isl_local_space_free(ls); + isl_point_free(pnt); + return NULL; +} + +/* Do any of the local variables in "ls" depend on the specified dimensions? + */ +isl_bool isl_local_space_involves_dims(__isl_keep isl_local_space *ls, + enum isl_dim_type type, unsigned first, unsigned n) +{ + isl_local *local; + isl_size off; + + off = isl_local_space_var_offset(ls, type); + if (off < 0 || isl_local_space_check_range(ls, type, first, n) < 0) + return isl_bool_error; + + local = isl_local_space_peek_local(ls); + return isl_local_involves_vars(local, off + first, n); +} diff --git a/external/mit/isl/dist/isl_local_space_private.h b/external/mit/isl/dist/isl_local_space_private.h new file mode 100644 index 000000000000..9a3b276c2b51 --- /dev/null +++ b/external/mit/isl/dist/isl_local_space_private.h @@ -0,0 +1,106 @@ +#ifndef ISL_LOCAL_SPACE_PRIVATE_H +#define ISL_LOCAL_SPACE_PRIVATE_H + +#include +#include +#include + +struct isl_local_space { + int ref; + + isl_space *dim; + isl_mat *div; +}; + +isl_stat isl_local_space_check_range(__isl_keep isl_local_space *ls, + enum isl_dim_type type, unsigned first, unsigned n); + +uint32_t isl_local_space_get_hash(__isl_keep isl_local_space *ls); + +__isl_give isl_local_space *isl_local_space_alloc(__isl_take isl_space *space, + unsigned n_div); +__isl_give isl_local_space *isl_local_space_alloc_div( + __isl_take isl_space *space, __isl_take isl_mat *div); + +__isl_keep isl_space *isl_local_space_peek_space( + __isl_keep isl_local_space *ls); + +__isl_give isl_local_space *isl_local_space_swap_div( + __isl_take isl_local_space *ls, int a, int b); +__isl_give isl_local_space *isl_local_space_add_div( + __isl_take isl_local_space *ls, __isl_take isl_vec *div); + +int isl_mat_cmp_div(__isl_keep isl_mat *div, int i, int j); +__isl_give isl_mat *isl_merge_divs(__isl_keep isl_mat *div1, + __isl_keep isl_mat *div2, int *exp1, int *exp2); + +isl_size isl_local_space_var_offset(__isl_keep isl_local_space *ls, + enum isl_dim_type type); +unsigned isl_local_space_offset(__isl_keep isl_local_space *ls, + enum isl_dim_type type); +isl_bool isl_local_space_involves_dims(__isl_keep isl_local_space *ls, + enum isl_dim_type type, unsigned first, unsigned n); + +__isl_give isl_local_space *isl_local_space_replace_divs( + __isl_take isl_local_space *ls, __isl_take isl_mat *div); +isl_bool isl_local_space_div_is_marked_unknown(__isl_keep isl_local_space *ls, + int div); +isl_bool isl_local_space_div_is_known(__isl_keep isl_local_space *ls, int div); +isl_bool isl_local_space_divs_known(__isl_keep isl_local_space *ls); + +__isl_give isl_basic_set *isl_local_space_lift_basic_set( + __isl_take isl_local_space *ls, __isl_take isl_basic_set *bset); +__isl_give isl_set *isl_local_space_lift_set(__isl_take isl_local_space *ls, + __isl_take isl_set *set); +__isl_give isl_local_space *isl_local_space_substitute_equalities( + __isl_take isl_local_space *ls, __isl_take isl_basic_set *eq); + +isl_bool isl_local_space_is_named_or_nested(__isl_keep isl_local_space *ls, + enum isl_dim_type type); + +isl_bool isl_local_space_has_equal_space(__isl_keep isl_local_space *ls1, + __isl_keep isl_local_space *ls2); + +__isl_give isl_local_space *isl_local_space_reset_space( + __isl_take isl_local_space *ls, __isl_take isl_space *space); +__isl_give isl_local_space *isl_local_space_realign( + __isl_take isl_local_space *ls, __isl_take isl_reordering *r); + +isl_bool isl_local_space_is_div_constraint(__isl_keep isl_local_space *ls, + isl_int *constraint, unsigned div); +isl_bool isl_local_space_is_div_equality(__isl_keep isl_local_space *ls, + isl_int *constraint, unsigned div); + +int *isl_local_space_get_active(__isl_keep isl_local_space *ls, isl_int *l); + +__isl_give isl_local_space *isl_local_space_substitute_seq( + __isl_take isl_local_space *ls, + enum isl_dim_type type, unsigned pos, isl_int *subs, int subs_len, + int first, int n); +__isl_give isl_local_space *isl_local_space_substitute( + __isl_take isl_local_space *ls, + enum isl_dim_type type, unsigned pos, __isl_keep isl_aff *subs); + +__isl_give isl_local_space *isl_local_space_lift( + __isl_take isl_local_space *ls); + +__isl_give isl_local_space *isl_local_space_preimage_multi_aff( + __isl_take isl_local_space *ls, __isl_take isl_multi_aff *ma); + +__isl_give isl_local_space *isl_local_space_wrapped_reverse( + __isl_take isl_local_space *ls); +__isl_give isl_local_space *isl_local_space_move_dims( + __isl_take isl_local_space *ls, + enum isl_dim_type dst_type, unsigned dst_pos, + enum isl_dim_type src_type, unsigned src_pos, unsigned n); + +int isl_local_space_cmp(__isl_keep isl_local_space *ls1, + __isl_keep isl_local_space *ls2); + +__isl_give isl_point *isl_local_space_lift_point(__isl_take isl_local_space *ls, + __isl_take isl_point *pnt); + +isl_bool isl_local_space_has_space(__isl_keep isl_local_space *ls, + __isl_keep isl_space *space); + +#endif diff --git a/external/mit/isl/dist/isl_lp.c b/external/mit/isl/dist/isl_lp.c new file mode 100644 index 000000000000..c6cc83848b78 --- /dev/null +++ b/external/mit/isl/dist/isl_lp.c @@ -0,0 +1,371 @@ +/* + * 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 + */ + +#include +#include +#include +#include +#include "isl_tab.h" +#include +#include +#include +#include +#include +#include + +#include +#include + +static enum isl_lp_result isl_tab_solve_lp(__isl_keep isl_basic_map *bmap, + int maximize, isl_int *f, isl_int denom, isl_int *opt, + isl_int *opt_denom, __isl_give isl_vec **sol) +{ + struct isl_tab *tab; + enum isl_lp_result res; + isl_size dim = isl_basic_map_dim(bmap, isl_dim_all); + + if (dim < 0) + return isl_lp_error; + if (maximize) + isl_seq_neg(f, f, 1 + dim); + + bmap = isl_basic_map_gauss(bmap, NULL); + tab = isl_tab_from_basic_map(bmap, 0); + res = isl_tab_min(tab, f, denom, opt, opt_denom, 0); + if (res == isl_lp_ok && sol) { + *sol = isl_tab_get_sample_value(tab); + if (!*sol) + res = isl_lp_error; + } + isl_tab_free(tab); + + if (maximize) + isl_seq_neg(f, f, 1 + dim); + if (maximize && opt) + isl_int_neg(*opt, *opt); + + return res; +} + +/* Given a basic map "bmap" and an affine combination of the variables "f" + * with denominator "denom", set *opt / *opt_denom to the minimal + * (or maximal if "maximize" is true) value attained by f/d over "bmap", + * assuming the basic map is not empty and the expression cannot attain + * arbitrarily small (or large) values. + * If opt_denom is NULL, then *opt is rounded up (or down) + * to the nearest integer. + * The return value reflects the nature of the result (empty, unbounded, + * minimal or maximal value returned in *opt). + */ +enum isl_lp_result isl_basic_map_solve_lp(__isl_keep isl_basic_map *bmap, + int max, isl_int *f, isl_int d, isl_int *opt, isl_int *opt_denom, + __isl_give isl_vec **sol) +{ + if (sol) + *sol = NULL; + + if (!bmap) + return isl_lp_error; + + return isl_tab_solve_lp(bmap, max, f, d, opt, opt_denom, sol); +} + +enum isl_lp_result isl_basic_set_solve_lp(__isl_keep isl_basic_set *bset, + int max, isl_int *f, isl_int d, isl_int *opt, isl_int *opt_denom, + __isl_give isl_vec **sol) +{ + return isl_basic_map_solve_lp(bset_to_bmap(bset), max, + f, d, opt, opt_denom, sol); +} + +enum isl_lp_result isl_map_solve_lp(__isl_keep isl_map *map, int max, + isl_int *f, isl_int d, isl_int *opt, + isl_int *opt_denom, + __isl_give isl_vec **sol) +{ + int i; + isl_int o; + isl_int t; + isl_int opt_i; + isl_int opt_denom_i; + enum isl_lp_result res; + int max_div; + isl_vec *v = NULL; + + if (!map) + return isl_lp_error; + if (map->n == 0) + return isl_lp_empty; + + max_div = 0; + for (i = 0; i < map->n; ++i) + if (map->p[i]->n_div > max_div) + max_div = map->p[i]->n_div; + if (max_div > 0) { + isl_size total = isl_map_dim(map, isl_dim_all); + if (total < 0) + return isl_lp_error; + v = isl_vec_alloc(map->ctx, 1 + total + max_div); + if (!v) + return isl_lp_error; + isl_seq_cpy(v->el, f, 1 + total); + isl_seq_clr(v->el + 1 + total, max_div); + f = v->el; + } + + if (!opt && map->n > 1 && sol) { + isl_int_init(o); + opt = &o; + } + if (map->n > 0) + isl_int_init(opt_i); + if (map->n > 0 && opt_denom) { + isl_int_init(opt_denom_i); + isl_int_init(t); + } + + res = isl_basic_map_solve_lp(map->p[0], max, f, d, + opt, opt_denom, sol); + if (res == isl_lp_error || res == isl_lp_unbounded) + goto done; + + if (sol) + *sol = NULL; + + for (i = 1; i < map->n; ++i) { + isl_vec *sol_i = NULL; + enum isl_lp_result res_i; + int better; + + res_i = isl_basic_map_solve_lp(map->p[i], max, f, d, + &opt_i, + opt_denom ? &opt_denom_i : NULL, + sol ? &sol_i : NULL); + if (res_i == isl_lp_error || res_i == isl_lp_unbounded) { + res = res_i; + goto done; + } + if (res_i == isl_lp_empty) + continue; + if (res == isl_lp_empty) { + better = 1; + } else if (!opt_denom) { + if (max) + better = isl_int_gt(opt_i, *opt); + else + better = isl_int_lt(opt_i, *opt); + } else { + isl_int_mul(t, opt_i, *opt_denom); + isl_int_submul(t, *opt, opt_denom_i); + if (max) + better = isl_int_is_pos(t); + else + better = isl_int_is_neg(t); + } + if (better) { + res = res_i; + if (opt) + isl_int_set(*opt, opt_i); + if (opt_denom) + isl_int_set(*opt_denom, opt_denom_i); + if (sol) { + isl_vec_free(*sol); + *sol = sol_i; + } + } else + isl_vec_free(sol_i); + } + +done: + isl_vec_free(v); + if (map->n > 0 && opt_denom) { + isl_int_clear(opt_denom_i); + isl_int_clear(t); + } + if (map->n > 0) + isl_int_clear(opt_i); + if (opt == &o) + isl_int_clear(o); + return res; +} + +enum isl_lp_result isl_set_solve_lp(__isl_keep isl_set *set, int max, + isl_int *f, isl_int d, isl_int *opt, + isl_int *opt_denom, + __isl_give isl_vec **sol) +{ + return isl_map_solve_lp(set_to_map(set), max, + f, d, opt, opt_denom, sol); +} + +/* Return the optimal (rational) value of "obj" over "bset", assuming + * that "obj" and "bset" have aligned parameters and divs. + * If "max" is set, then the maximal value is computed. + * Otherwise, the minimal value is computed. + * + * Return infinity or negative infinity if the optimal value is unbounded and + * NaN if "bset" is empty. + * + * Call isl_basic_set_solve_lp and translate the results. + */ +static __isl_give isl_val *basic_set_opt_lp( + __isl_keep isl_basic_set *bset, int max, __isl_keep isl_aff *obj) +{ + isl_ctx *ctx; + isl_val *res; + enum isl_lp_result lp_res; + + if (!bset || !obj) + return NULL; + + ctx = isl_aff_get_ctx(obj); + res = isl_val_alloc(ctx); + if (!res) + return NULL; + lp_res = isl_basic_set_solve_lp(bset, max, obj->v->el + 1, + obj->v->el[0], &res->n, &res->d, NULL); + if (lp_res == isl_lp_ok) + return isl_val_normalize(res); + isl_val_free(res); + if (lp_res == isl_lp_error) + return NULL; + if (lp_res == isl_lp_empty) + return isl_val_nan(ctx); + if (max) + return isl_val_infty(ctx); + else + return isl_val_neginfty(ctx); +} + +/* Return the optimal (rational) value of "obj" over "bset", assuming + * that "obj" and "bset" have aligned parameters. + * If "max" is set, then the maximal value is computed. + * Otherwise, the minimal value is computed. + * + * Return infinity or negative infinity if the optimal value is unbounded and + * NaN if "bset" is empty. + * + * Align the divs of "bset" and "obj" and call basic_set_opt_lp. + */ +static __isl_give isl_val *isl_basic_set_opt_lp_val_aligned( + __isl_keep isl_basic_set *bset, int max, __isl_keep isl_aff *obj) +{ + int *exp1 = NULL; + int *exp2 = NULL; + isl_ctx *ctx; + isl_mat *bset_div = NULL; + isl_mat *div = NULL; + isl_val *res; + isl_size bset_n_div, obj_n_div; + + if (!bset || !obj) + return NULL; + + ctx = isl_aff_get_ctx(obj); + if (!isl_space_is_equal(bset->dim, obj->ls->dim)) + isl_die(ctx, isl_error_invalid, + "spaces don't match", return NULL); + + bset_n_div = isl_basic_set_dim(bset, isl_dim_div); + obj_n_div = isl_aff_dim(obj, isl_dim_div); + if (bset_n_div < 0 || obj_n_div < 0) + return NULL; + if (bset_n_div == 0 && obj_n_div == 0) + return basic_set_opt_lp(bset, max, obj); + + bset = isl_basic_set_copy(bset); + obj = isl_aff_copy(obj); + + bset_div = isl_basic_set_get_divs(bset); + exp1 = isl_alloc_array(ctx, int, bset_n_div); + exp2 = isl_alloc_array(ctx, int, obj_n_div); + if (!bset_div || (bset_n_div && !exp1) || (obj_n_div && !exp2)) + goto error; + + div = isl_merge_divs(bset_div, obj->ls->div, exp1, exp2); + + bset = isl_basic_set_expand_divs(bset, isl_mat_copy(div), exp1); + obj = isl_aff_expand_divs(obj, isl_mat_copy(div), exp2); + + res = basic_set_opt_lp(bset, max, obj); + + isl_mat_free(bset_div); + isl_mat_free(div); + free(exp1); + free(exp2); + isl_basic_set_free(bset); + isl_aff_free(obj); + + return res; +error: + isl_mat_free(div); + isl_mat_free(bset_div); + free(exp1); + free(exp2); + isl_basic_set_free(bset); + isl_aff_free(obj); + return NULL; +} + +/* Return the optimal (rational) value of "obj" over "bset". + * If "max" is set, then the maximal value is computed. + * Otherwise, the minimal value is computed. + * + * Return infinity or negative infinity if the optimal value is unbounded and + * NaN if "bset" is empty. + */ +static __isl_give isl_val *isl_basic_set_opt_lp_val( + __isl_keep isl_basic_set *bset, int max, __isl_keep isl_aff *obj) +{ + isl_bool equal; + isl_val *res; + + if (!bset || !obj) + return NULL; + + equal = isl_basic_set_space_has_equal_params(bset, obj->ls->dim); + if (equal < 0) + return NULL; + if (equal) + return isl_basic_set_opt_lp_val_aligned(bset, max, obj); + + bset = isl_basic_set_copy(bset); + obj = isl_aff_copy(obj); + bset = isl_basic_set_align_params(bset, isl_aff_get_domain_space(obj)); + obj = isl_aff_align_params(obj, isl_basic_set_get_space(bset)); + + res = isl_basic_set_opt_lp_val_aligned(bset, max, obj); + + isl_basic_set_free(bset); + isl_aff_free(obj); + + return res; +} + +/* Return the minimal (rational) value of "obj" over "bset". + * + * Return negative infinity if the minimal value is unbounded and + * NaN if "bset" is empty. + */ +__isl_give isl_val *isl_basic_set_min_lp_val(__isl_keep isl_basic_set *bset, + __isl_keep isl_aff *obj) +{ + return isl_basic_set_opt_lp_val(bset, 0, obj); +} + +/* Return the maximal (rational) value of "obj" over "bset". + * + * Return infinity if the maximal value is unbounded and + * NaN if "bset" is empty. + */ +__isl_give isl_val *isl_basic_set_max_lp_val(__isl_keep isl_basic_set *bset, + __isl_keep isl_aff *obj) +{ + return isl_basic_set_opt_lp_val(bset, 1, obj); +} diff --git a/external/mit/isl/dist/isl_lp_private.h b/external/mit/isl/dist/isl_lp_private.h new file mode 100644 index 000000000000..ddc44c1eeda5 --- /dev/null +++ b/external/mit/isl/dist/isl_lp_private.h @@ -0,0 +1,21 @@ +#ifndef ISL_LP_PRIVATE_H +#define ISL_LP_PRIVATE_H + +#include +#include +#include + +enum isl_lp_result isl_basic_map_solve_lp(__isl_keep isl_basic_map *bmap, + int max, isl_int *f, isl_int denom, isl_int *opt, isl_int *opt_denom, + __isl_give isl_vec **sol); +enum isl_lp_result isl_basic_set_solve_lp(__isl_keep isl_basic_set *bset, + int max, isl_int *f, isl_int denom, isl_int *opt, isl_int *opt_denom, + __isl_give isl_vec **sol); +enum isl_lp_result isl_map_solve_lp(__isl_keep isl_map *map, int max, + isl_int *f, isl_int denom, isl_int *opt, isl_int *opt_denom, + __isl_give isl_vec **sol); +enum isl_lp_result isl_set_solve_lp(__isl_keep isl_set *set, int max, + isl_int *f, isl_int denom, isl_int *opt, isl_int *opt_denom, + __isl_give isl_vec **sol); + +#endif diff --git a/external/mit/isl/dist/isl_map.c b/external/mit/isl/dist/isl_map.c new file mode 100644 index 000000000000..03a63ed27dce --- /dev/null +++ b/external/mit/isl/dist/isl_map.c @@ -0,0 +1,14680 @@ +/* + * Copyright 2008-2009 Katholieke Universiteit Leuven + * Copyright 2010 INRIA Saclay + * Copyright 2012-2014 Ecole Normale Superieure + * Copyright 2014 INRIA Rocquencourt + * Copyright 2016 INRIA Paris + * Copyright 2016 Sven Verdoolaege + * Copyright 2018-2019 Cerebras Systems + * Copyright 2022 Cerebras Systems + * + * 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 + * and Inria Paris - Rocquencourt, Domaine de Voluceau - Rocquencourt, + * B.P. 105 - 78153 Le Chesnay, France + * and Centre de Recherche Inria de Paris, 2 rue Simone Iff - Voie DQ12, + * CS 42112, 75589 Paris Cedex 12, France + * and Cerebras Systems, 175 S San Antonio Rd, Los Altos, CA, USA + */ + +#include +#include +#include +#include +#include +#include +#include "isl_space_private.h" +#include "isl_equalities.h" +#include +#include +#include +#include +#include +#include "isl_sample.h" +#include +#include "isl_tab.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +/* Treat "bset" as a basic map. + * Internally, isl_basic_set is defined to isl_basic_map, so in practice, + * this function performs a redundant cast. + */ +static __isl_keep const isl_basic_map *const_bset_to_bmap( + __isl_keep const isl_basic_set *bset) +{ + return (const isl_basic_map *) bset; +} + +#undef TYPE +#define TYPE isl_basic_map +#include "has_single_reference_templ.c" + +static unsigned pos(__isl_keep isl_space *space, enum isl_dim_type type) +{ + switch (type) { + case isl_dim_param: return 1; + case isl_dim_in: return 1 + space->nparam; + case isl_dim_out: return 1 + space->nparam + space->n_in; + default: return 0; + } +} + +isl_size isl_basic_map_dim(__isl_keep isl_basic_map *bmap, + enum isl_dim_type type) +{ + if (!bmap) + return isl_size_error; + switch (type) { + case isl_dim_cst: return 1; + case isl_dim_param: + case isl_dim_in: + case isl_dim_out: return isl_space_dim(bmap->dim, type); + case isl_dim_div: return bmap->n_div; + case isl_dim_all: return isl_basic_map_total_dim(bmap); + default: return 0; + } +} + +/* Return the space of "map". + */ +__isl_keep isl_space *isl_map_peek_space(__isl_keep const isl_map *map) +{ + return map ? map->dim : NULL; +} + +/* Return the space of "set". + */ +__isl_keep isl_space *isl_set_peek_space(__isl_keep isl_set *set) +{ + return isl_map_peek_space(set_to_map(set)); +} + +isl_size isl_map_dim(__isl_keep isl_map *map, enum isl_dim_type type) +{ + return isl_space_dim(isl_map_peek_space(map), type); +} + +/* Return the dimensionality of the domain (tuple) of the map. + */ +isl_size isl_map_domain_tuple_dim(__isl_keep isl_map *map) +{ + return isl_map_dim(map, isl_dim_in); +} + +/* Return the dimensionality of the range (tuple) of the map. + */ +isl_size isl_map_range_tuple_dim(__isl_keep isl_map *map) +{ + return isl_map_dim(map, isl_dim_out); +} + +isl_size isl_set_dim(__isl_keep isl_set *set, enum isl_dim_type type) +{ + return isl_map_dim(set_to_map(set), type); +} + +/* Return the dimensionality of the (tuple of the) set. + */ +isl_size isl_set_tuple_dim(__isl_keep isl_set *set) +{ + return isl_set_dim(set, isl_dim_set); +} + +/* Return the position of the variables of the given type + * within the sequence of variables of "bmap". + */ +isl_size isl_basic_map_var_offset(__isl_keep isl_basic_map *bmap, + enum isl_dim_type type) +{ + isl_space *space; + + space = isl_basic_map_peek_space(bmap); + + switch (type) { + case isl_dim_param: + case isl_dim_in: + case isl_dim_out: return isl_space_offset(space, type); + case isl_dim_div: return isl_space_dim(space, isl_dim_all); + case isl_dim_cst: + default: + isl_die(isl_basic_map_get_ctx(bmap), isl_error_invalid, + "invalid dimension type", return isl_size_error); + } +} + +/* Return the position of the variables of the given type + * within the sequence of variables of "bset". + */ +isl_size isl_basic_set_var_offset(__isl_keep isl_basic_set *bset, + enum isl_dim_type type) +{ + return isl_basic_map_var_offset(bset_to_bmap(bset), type); +} + +/* Return the position of the coefficients of the variables of the given type + * within the sequence of coefficients of "bmap". + */ +unsigned isl_basic_map_offset(__isl_keep isl_basic_map *bmap, + enum isl_dim_type type) +{ + switch (type) { + case isl_dim_cst: return 0; + case isl_dim_param: + case isl_dim_in: + case isl_dim_out: + case isl_dim_div: return 1 + isl_basic_map_var_offset(bmap, type); + default: return 0; + } +} + +unsigned isl_basic_set_offset(__isl_keep isl_basic_set *bset, + enum isl_dim_type type) +{ + return isl_basic_map_offset(bset, type); +} + +static unsigned map_offset(__isl_keep isl_map *map, enum isl_dim_type type) +{ + return pos(map->dim, type); +} + +isl_size isl_basic_set_dim(__isl_keep isl_basic_set *bset, + enum isl_dim_type type) +{ + return isl_basic_map_dim(bset, type); +} + +isl_size isl_basic_set_n_dim(__isl_keep isl_basic_set *bset) +{ + return isl_basic_set_dim(bset, isl_dim_set); +} + +isl_size isl_basic_set_n_param(__isl_keep isl_basic_set *bset) +{ + return isl_basic_set_dim(bset, isl_dim_param); +} + +isl_size isl_basic_set_total_dim(__isl_keep const isl_basic_set *bset) +{ + return isl_basic_map_total_dim(const_bset_to_bmap(bset)); +} + +isl_size isl_set_n_dim(__isl_keep isl_set *set) +{ + return isl_set_dim(set, isl_dim_set); +} + +isl_size isl_set_n_param(__isl_keep isl_set *set) +{ + return isl_set_dim(set, isl_dim_param); +} + +isl_size isl_basic_map_total_dim(__isl_keep const isl_basic_map *bmap) +{ + isl_size dim; + + if (!bmap) + return isl_size_error; + dim = isl_space_dim(bmap->dim, isl_dim_all); + if (dim < 0) + return isl_size_error; + return dim + bmap->n_div; +} + +/* Return the number of equality constraints in the description of "bmap". + * Return isl_size_error on error. + */ +isl_size isl_basic_map_n_equality(__isl_keep isl_basic_map *bmap) +{ + if (!bmap) + return isl_size_error; + return bmap->n_eq; +} + +/* Return the number of equality constraints in the description of "bset". + * Return isl_size_error on error. + */ +isl_size isl_basic_set_n_equality(__isl_keep isl_basic_set *bset) +{ + return isl_basic_map_n_equality(bset_to_bmap(bset)); +} + +/* Return the number of inequality constraints in the description of "bmap". + * Return isl_size_error on error. + */ +isl_size isl_basic_map_n_inequality(__isl_keep isl_basic_map *bmap) +{ + if (!bmap) + return isl_size_error; + return bmap->n_ineq; +} + +/* Return the number of inequality constraints in the description of "bset". + * Return isl_size_error on error. + */ +isl_size isl_basic_set_n_inequality(__isl_keep isl_basic_set *bset) +{ + return isl_basic_map_n_inequality(bset_to_bmap(bset)); +} + +/* Do "bmap1" and "bmap2" have the same parameters? + */ +static isl_bool isl_basic_map_has_equal_params(__isl_keep isl_basic_map *bmap1, + __isl_keep isl_basic_map *bmap2) +{ + isl_space *space1, *space2; + + space1 = isl_basic_map_peek_space(bmap1); + space2 = isl_basic_map_peek_space(bmap2); + return isl_space_has_equal_params(space1, space2); +} + +/* Do "map1" and "map2" have the same parameters? + */ +isl_bool isl_map_has_equal_params(__isl_keep isl_map *map1, + __isl_keep isl_map *map2) +{ + isl_space *space1, *space2; + + space1 = isl_map_peek_space(map1); + space2 = isl_map_peek_space(map2); + return isl_space_has_equal_params(space1, space2); +} + +/* Do "map" and "set" have the same parameters? + */ +static isl_bool isl_map_set_has_equal_params(__isl_keep isl_map *map, + __isl_keep isl_set *set) +{ + return isl_map_has_equal_params(map, set_to_map(set)); +} + +/* Is the tuple of type "type" of "bmap" the same as the single tuple of "bset"? + */ +static isl_bool isl_basic_map_set_tuple_is_equal(__isl_keep isl_basic_map *bmap, + enum isl_dim_type type, __isl_keep isl_basic_set *bset) +{ + isl_space *bmap_space, *bset_space; + + bmap_space = isl_basic_map_peek_space(bmap); + bset_space = isl_basic_set_peek_space(bset); + return isl_space_tuple_is_equal(bmap_space, type, + bset_space, isl_dim_set); +} + +/* Is the tuple of type "type" of "map" the same as the single tuple of "set"? + */ +static isl_bool isl_map_set_tuple_is_equal(__isl_keep isl_map *map, + enum isl_dim_type type, __isl_keep isl_set *set) +{ + return isl_map_tuple_is_equal(map, type, set_to_map(set), isl_dim_set); +} + +isl_bool isl_map_compatible_domain(__isl_keep isl_map *map, + __isl_keep isl_set *set) +{ + isl_bool m; + if (!map || !set) + return isl_bool_error; + m = isl_map_has_equal_params(map, set_to_map(set)); + if (m < 0 || !m) + return m; + return isl_map_set_tuple_is_equal(map, isl_dim_in, set); +} + +isl_bool isl_basic_map_compatible_domain(__isl_keep isl_basic_map *bmap, + __isl_keep isl_basic_set *bset) +{ + isl_bool m; + if (!bmap || !bset) + return isl_bool_error; + m = isl_basic_map_has_equal_params(bmap, bset_to_bmap(bset)); + if (m < 0 || !m) + return m; + return isl_basic_map_set_tuple_is_equal(bmap, isl_dim_in, bset); +} + +isl_bool isl_map_compatible_range(__isl_keep isl_map *map, + __isl_keep isl_set *set) +{ + isl_bool m; + if (!map || !set) + return isl_bool_error; + m = isl_map_has_equal_params(map, set_to_map(set)); + if (m < 0 || !m) + return m; + return isl_map_set_tuple_is_equal(map, isl_dim_out, set); +} + +isl_bool isl_basic_map_compatible_range(__isl_keep isl_basic_map *bmap, + __isl_keep isl_basic_set *bset) +{ + isl_bool m; + if (!bmap || !bset) + return isl_bool_error; + m = isl_basic_map_has_equal_params(bmap, bset_to_bmap(bset)); + if (m < 0 || !m) + return m; + return isl_basic_map_set_tuple_is_equal(bmap, isl_dim_out, bset); +} + +isl_ctx *isl_basic_map_get_ctx(__isl_keep isl_basic_map *bmap) +{ + return bmap ? bmap->ctx : NULL; +} + +isl_ctx *isl_basic_set_get_ctx(__isl_keep isl_basic_set *bset) +{ + return bset ? bset->ctx : NULL; +} + +isl_ctx *isl_map_get_ctx(__isl_keep isl_map *map) +{ + return map ? map->ctx : NULL; +} + +isl_ctx *isl_set_get_ctx(__isl_keep isl_set *set) +{ + return set ? set->ctx : NULL; +} + +/* Return the space of "bmap". + */ +__isl_keep isl_space *isl_basic_map_peek_space( + __isl_keep const isl_basic_map *bmap) +{ + return bmap ? bmap->dim : NULL; +} + +/* Return the space of "bset". + */ +__isl_keep isl_space *isl_basic_set_peek_space(__isl_keep isl_basic_set *bset) +{ + return isl_basic_map_peek_space(bset_to_bmap(bset)); +} + +__isl_give isl_space *isl_basic_map_get_space(__isl_keep isl_basic_map *bmap) +{ + return isl_space_copy(isl_basic_map_peek_space(bmap)); +} + +__isl_give isl_space *isl_basic_set_get_space(__isl_keep isl_basic_set *bset) +{ + return isl_basic_map_get_space(bset_to_bmap(bset)); +} + +/* Return the space of "bmap". + * This may be either a copy or the space itself + * if there is only one reference to "bmap". + * This allows the space to be modified inplace + * if both the basic map and its space have only a single reference. + * The caller is not allowed to modify "bmap" between this call and + * a subsequent call to isl_basic_map_restore_space. + * The only exception is that isl_basic_map_free can be called instead. + */ +static __isl_give isl_space *isl_basic_map_take_space( + __isl_keep isl_basic_map *bmap) +{ + isl_space *space; + + if (!bmap) + return NULL; + if (bmap->ref != 1) + return isl_basic_map_get_space(bmap); + space = bmap->dim; + bmap->dim = NULL; + return space; +} + +/* Set the space of "bmap" to "space", where the space of "bmap" may be missing + * due to a preceding call to isl_basic_map_take_space. + * However, in this case, "bmap" only has a single reference and + * then the call to isl_basic_map_cow has no effect. + */ +static __isl_give isl_basic_map *isl_basic_map_restore_space( + __isl_take isl_basic_map *bmap, __isl_take isl_space *space) +{ + if (!bmap || !space) + goto error; + + if (bmap->dim == space) { + isl_space_free(space); + return bmap; + } + + bmap = isl_basic_map_cow(bmap); + if (!bmap) + goto error; + isl_space_free(bmap->dim); + bmap->dim = space; + + return bmap; +error: + isl_basic_map_free(bmap); + isl_space_free(space); + return NULL; +} + +/* Extract the divs in "bmap" as a matrix. + */ +__isl_give isl_mat *isl_basic_map_get_divs(__isl_keep isl_basic_map *bmap) +{ + int i; + isl_ctx *ctx; + isl_mat *div; + isl_size v_div; + unsigned cols; + + v_div = isl_basic_map_var_offset(bmap, isl_dim_div); + if (v_div < 0) + return NULL; + + ctx = isl_basic_map_get_ctx(bmap); + cols = 1 + 1 + v_div + bmap->n_div; + div = isl_mat_alloc(ctx, bmap->n_div, cols); + if (!div) + return NULL; + + for (i = 0; i < bmap->n_div; ++i) + isl_seq_cpy(div->row[i], bmap->div[i], cols); + + return div; +} + +/* Extract the divs in "bset" as a matrix. + */ +__isl_give isl_mat *isl_basic_set_get_divs(__isl_keep isl_basic_set *bset) +{ + return isl_basic_map_get_divs(bset); +} + +__isl_give isl_local_space *isl_basic_map_get_local_space( + __isl_keep isl_basic_map *bmap) +{ + isl_mat *div; + + if (!bmap) + return NULL; + + div = isl_basic_map_get_divs(bmap); + return isl_local_space_alloc_div(isl_space_copy(bmap->dim), div); +} + +__isl_give isl_local_space *isl_basic_set_get_local_space( + __isl_keep isl_basic_set *bset) +{ + return isl_basic_map_get_local_space(bset); +} + +/* For each known div d = floor(f/m), add the constraints + * + * f - m d >= 0 + * -(f-(m-1)) + m d >= 0 + * + * Do not finalize the result. + */ +static __isl_give isl_basic_map *add_known_div_constraints( + __isl_take isl_basic_map *bmap) +{ + int i; + isl_size n_div; + + n_div = isl_basic_map_dim(bmap, isl_dim_div); + if (n_div < 0) + return isl_basic_map_free(bmap); + if (n_div == 0) + return bmap; + bmap = isl_basic_map_cow(bmap); + bmap = isl_basic_map_extend_constraints(bmap, 0, 2 * n_div); + if (!bmap) + return NULL; + for (i = 0; i < n_div; ++i) { + if (isl_int_is_zero(bmap->div[i][0])) + continue; + bmap = isl_basic_map_add_div_constraints(bmap, i); + } + + return bmap; +} + +__isl_give isl_basic_map *isl_basic_map_from_local_space( + __isl_take isl_local_space *ls) +{ + int i; + isl_size n_div; + isl_basic_map *bmap; + + n_div = isl_local_space_dim(ls, isl_dim_div); + if (n_div < 0) + ls = isl_local_space_free(ls); + if (!ls) + return NULL; + + bmap = isl_basic_map_alloc_space(isl_local_space_get_space(ls), + n_div, 0, 2 * n_div); + + for (i = 0; i < n_div; ++i) + if (isl_basic_map_alloc_div(bmap) < 0) + goto error; + + for (i = 0; i < n_div; ++i) + isl_seq_cpy(bmap->div[i], ls->div->row[i], ls->div->n_col); + bmap = add_known_div_constraints(bmap); + + isl_local_space_free(ls); + return bmap; +error: + isl_local_space_free(ls); + isl_basic_map_free(bmap); + return NULL; +} + +__isl_give isl_basic_set *isl_basic_set_from_local_space( + __isl_take isl_local_space *ls) +{ + return isl_basic_map_from_local_space(ls); +} + +__isl_give isl_space *isl_map_get_space(__isl_keep isl_map *map) +{ + return isl_space_copy(isl_map_peek_space(map)); +} + +__isl_give isl_space *isl_set_get_space(__isl_keep isl_set *set) +{ + if (!set) + return NULL; + return isl_space_copy(set->dim); +} + +/* Return the space of "map". + * This may be either a copy or the space itself + * if there is only one reference to "map". + * This allows the space to be modified inplace + * if both the map and its space have only a single reference. + * The caller is not allowed to modify "map" between this call and + * a subsequent call to isl_map_restore_space. + * The only exception is that isl_map_free can be called instead. + */ +static __isl_give isl_space *isl_map_take_space(__isl_keep isl_map *map) +{ + isl_space *space; + + if (!map) + return NULL; + if (map->ref != 1) + return isl_map_get_space(map); + space = map->dim; + map->dim = NULL; + return space; +} + +/* Set the space of "map" to "space", where the space of "map" may be missing + * due to a preceding call to isl_map_take_space. + * However, in this case, "map" only has a single reference and + * then the call to isl_map_cow has no effect. + */ +static __isl_give isl_map *isl_map_restore_space(__isl_take isl_map *map, + __isl_take isl_space *space) +{ + if (!map || !space) + goto error; + + if (map->dim == space) { + isl_space_free(space); + return map; + } + + map = isl_map_cow(map); + if (!map) + goto error; + isl_space_free(map->dim); + map->dim = space; + + return map; +error: + isl_map_free(map); + isl_space_free(space); + return NULL; +} + +__isl_give isl_basic_map *isl_basic_map_set_tuple_name( + __isl_take isl_basic_map *bmap, enum isl_dim_type type, const char *s) +{ + isl_space *space; + + space = isl_basic_map_take_space(bmap); + space = isl_space_set_tuple_name(space, type, s); + bmap = isl_basic_map_restore_space(bmap, space); + bmap = isl_basic_map_finalize(bmap); + return bmap; +} + +__isl_give isl_basic_set *isl_basic_set_set_tuple_name( + __isl_take isl_basic_set *bset, const char *s) +{ + return isl_basic_map_set_tuple_name(bset, isl_dim_set, s); +} + +const char *isl_basic_map_get_tuple_name(__isl_keep isl_basic_map *bmap, + enum isl_dim_type type) +{ + return bmap ? isl_space_get_tuple_name(bmap->dim, type) : NULL; +} + +__isl_give isl_map *isl_map_set_tuple_name(__isl_take isl_map *map, + enum isl_dim_type type, const char *s) +{ + int i; + isl_space *space; + + map = isl_map_cow(map); + if (!map) + return NULL; + + for (i = 0; i < map->n; ++i) { + map->p[i] = isl_basic_map_set_tuple_name(map->p[i], type, s); + if (!map->p[i]) + goto error; + } + + space = isl_map_take_space(map); + space = isl_space_set_tuple_name(space, type, s); + map = isl_map_restore_space(map, space); + + return map; +error: + isl_map_free(map); + return NULL; +} + +/* Replace the identifier of the tuple of type "type" by "id". + */ +__isl_give isl_basic_map *isl_basic_map_set_tuple_id( + __isl_take isl_basic_map *bmap, + enum isl_dim_type type, __isl_take isl_id *id) +{ + isl_space *space; + + space = isl_basic_map_take_space(bmap); + space = isl_space_set_tuple_id(space, type, id); + bmap = isl_basic_map_restore_space(bmap, space); + bmap = isl_basic_map_finalize(bmap); + return bmap; +} + +/* Replace the identifier of the tuple by "id". + */ +__isl_give isl_basic_set *isl_basic_set_set_tuple_id( + __isl_take isl_basic_set *bset, __isl_take isl_id *id) +{ + return isl_basic_map_set_tuple_id(bset, isl_dim_set, id); +} + +/* Does the input or output tuple have a name? + */ +isl_bool isl_map_has_tuple_name(__isl_keep isl_map *map, enum isl_dim_type type) +{ + return map ? isl_space_has_tuple_name(map->dim, type) : isl_bool_error; +} + +const char *isl_map_get_tuple_name(__isl_keep isl_map *map, + enum isl_dim_type type) +{ + return map ? isl_space_get_tuple_name(map->dim, type) : NULL; +} + +__isl_give isl_set *isl_set_set_tuple_name(__isl_take isl_set *set, + const char *s) +{ + return set_from_map(isl_map_set_tuple_name(set_to_map(set), + isl_dim_set, s)); +} + +__isl_give isl_map *isl_map_set_tuple_id(__isl_take isl_map *map, + enum isl_dim_type type, __isl_take isl_id *id) +{ + isl_space *space; + + space = isl_map_take_space(map); + space = isl_space_set_tuple_id(space, type, id); + map = isl_map_restore_space(map, space); + + return isl_map_reset_space(map, isl_map_get_space(map)); +} + +/* Replace the identifier of the domain tuple of "map" by "id". + */ +__isl_give isl_map *isl_map_set_domain_tuple_id(__isl_take isl_map *map, + __isl_take isl_id *id) +{ + return isl_map_set_tuple_id(map, isl_dim_in, id); +} + +/* Replace the identifier of the range tuple of "map" by "id". + */ +__isl_give isl_map *isl_map_set_range_tuple_id(__isl_take isl_map *map, + __isl_take isl_id *id) +{ + return isl_map_set_tuple_id(map, isl_dim_out, id); +} + +__isl_give isl_set *isl_set_set_tuple_id(__isl_take isl_set *set, + __isl_take isl_id *id) +{ + return isl_map_set_tuple_id(set, isl_dim_set, id); +} + +__isl_give isl_map *isl_map_reset_tuple_id(__isl_take isl_map *map, + enum isl_dim_type type) +{ + isl_space *space; + + space = isl_map_take_space(map); + space = isl_space_reset_tuple_id(space, type); + map = isl_map_restore_space(map, space); + + return isl_map_reset_space(map, isl_map_get_space(map)); +} + +__isl_give isl_set *isl_set_reset_tuple_id(__isl_take isl_set *set) +{ + return isl_map_reset_tuple_id(set, isl_dim_set); +} + +isl_bool isl_map_has_tuple_id(__isl_keep isl_map *map, enum isl_dim_type type) +{ + return map ? isl_space_has_tuple_id(map->dim, type) : isl_bool_error; +} + +/* Does the domain tuple of "map" have an identifier? + */ +isl_bool isl_map_has_domain_tuple_id(__isl_keep isl_map *map) +{ + return isl_map_has_tuple_id(map, isl_dim_in); +} + +/* Does the range tuple of "map" have an identifier? + */ +isl_bool isl_map_has_range_tuple_id(__isl_keep isl_map *map) +{ + return isl_map_has_tuple_id(map, isl_dim_out); +} + +__isl_give isl_id *isl_map_get_tuple_id(__isl_keep isl_map *map, + enum isl_dim_type type) +{ + return map ? isl_space_get_tuple_id(map->dim, type) : NULL; +} + +/* Return the identifier of the domain tuple of "map", assuming it has one. + */ +__isl_give isl_id *isl_map_get_domain_tuple_id(__isl_keep isl_map *map) +{ + return isl_map_get_tuple_id(map, isl_dim_in); +} + +/* Return the identifier of the range tuple of "map", assuming it has one. + */ +__isl_give isl_id *isl_map_get_range_tuple_id(__isl_keep isl_map *map) +{ + return isl_map_get_tuple_id(map, isl_dim_out); +} + +isl_bool isl_set_has_tuple_id(__isl_keep isl_set *set) +{ + return isl_map_has_tuple_id(set, isl_dim_set); +} + +__isl_give isl_id *isl_set_get_tuple_id(__isl_keep isl_set *set) +{ + return isl_map_get_tuple_id(set, isl_dim_set); +} + +/* Does the set tuple have a name? + */ +isl_bool isl_set_has_tuple_name(__isl_keep isl_set *set) +{ + if (!set) + return isl_bool_error; + return isl_space_has_tuple_name(set->dim, isl_dim_set); +} + + +const char *isl_basic_set_get_tuple_name(__isl_keep isl_basic_set *bset) +{ + return bset ? isl_space_get_tuple_name(bset->dim, isl_dim_set) : NULL; +} + +const char *isl_set_get_tuple_name(__isl_keep isl_set *set) +{ + return set ? isl_space_get_tuple_name(set->dim, isl_dim_set) : NULL; +} + +const char *isl_basic_map_get_dim_name(__isl_keep isl_basic_map *bmap, + enum isl_dim_type type, unsigned pos) +{ + return bmap ? isl_space_get_dim_name(bmap->dim, type, pos) : NULL; +} + +const char *isl_basic_set_get_dim_name(__isl_keep isl_basic_set *bset, + enum isl_dim_type type, unsigned pos) +{ + return bset ? isl_space_get_dim_name(bset->dim, type, pos) : NULL; +} + +/* Does the given dimension have a name? + */ +isl_bool isl_map_has_dim_name(__isl_keep isl_map *map, + enum isl_dim_type type, unsigned pos) +{ + if (!map) + return isl_bool_error; + return isl_space_has_dim_name(map->dim, type, pos); +} + +const char *isl_map_get_dim_name(__isl_keep isl_map *map, + enum isl_dim_type type, unsigned pos) +{ + return map ? isl_space_get_dim_name(map->dim, type, pos) : NULL; +} + +const char *isl_set_get_dim_name(__isl_keep isl_set *set, + enum isl_dim_type type, unsigned pos) +{ + return set ? isl_space_get_dim_name(set->dim, type, pos) : NULL; +} + +/* Does the given dimension have a name? + */ +isl_bool isl_set_has_dim_name(__isl_keep isl_set *set, + enum isl_dim_type type, unsigned pos) +{ + if (!set) + return isl_bool_error; + return isl_space_has_dim_name(set->dim, type, pos); +} + +__isl_give isl_basic_map *isl_basic_map_set_dim_name( + __isl_take isl_basic_map *bmap, + enum isl_dim_type type, unsigned pos, const char *s) +{ + isl_space *space; + + space = isl_basic_map_take_space(bmap); + space = isl_space_set_dim_name(space, type, pos, s); + bmap = isl_basic_map_restore_space(bmap, space); + return isl_basic_map_finalize(bmap); +} + +__isl_give isl_map *isl_map_set_dim_name(__isl_take isl_map *map, + enum isl_dim_type type, unsigned pos, const char *s) +{ + int i; + isl_space *space; + + map = isl_map_cow(map); + if (!map) + return NULL; + + for (i = 0; i < map->n; ++i) { + map->p[i] = isl_basic_map_set_dim_name(map->p[i], type, pos, s); + if (!map->p[i]) + goto error; + } + + space = isl_map_take_space(map); + space = isl_space_set_dim_name(space, type, pos, s); + map = isl_map_restore_space(map, space); + + return map; +error: + isl_map_free(map); + return NULL; +} + +__isl_give isl_basic_set *isl_basic_set_set_dim_name( + __isl_take isl_basic_set *bset, + enum isl_dim_type type, unsigned pos, const char *s) +{ + return bset_from_bmap(isl_basic_map_set_dim_name(bset_to_bmap(bset), + type, pos, s)); +} + +__isl_give isl_set *isl_set_set_dim_name(__isl_take isl_set *set, + enum isl_dim_type type, unsigned pos, const char *s) +{ + return set_from_map(isl_map_set_dim_name(set_to_map(set), + type, pos, s)); +} + +isl_bool isl_basic_map_has_dim_id(__isl_keep isl_basic_map *bmap, + enum isl_dim_type type, unsigned pos) +{ + if (!bmap) + return isl_bool_error; + return isl_space_has_dim_id(bmap->dim, type, pos); +} + +__isl_give isl_id *isl_basic_set_get_dim_id(__isl_keep isl_basic_set *bset, + enum isl_dim_type type, unsigned pos) +{ + return bset ? isl_space_get_dim_id(bset->dim, type, pos) : NULL; +} + +isl_bool isl_map_has_dim_id(__isl_keep isl_map *map, + enum isl_dim_type type, unsigned pos) +{ + return map ? isl_space_has_dim_id(map->dim, type, pos) : isl_bool_error; +} + +__isl_give isl_id *isl_map_get_dim_id(__isl_keep isl_map *map, + enum isl_dim_type type, unsigned pos) +{ + return map ? isl_space_get_dim_id(map->dim, type, pos) : NULL; +} + +isl_bool isl_set_has_dim_id(__isl_keep isl_set *set, + enum isl_dim_type type, unsigned pos) +{ + return isl_map_has_dim_id(set, type, pos); +} + +__isl_give isl_id *isl_set_get_dim_id(__isl_keep isl_set *set, + enum isl_dim_type type, unsigned pos) +{ + return isl_map_get_dim_id(set, type, pos); +} + +__isl_give isl_map *isl_map_set_dim_id(__isl_take isl_map *map, + enum isl_dim_type type, unsigned pos, __isl_take isl_id *id) +{ + isl_space *space; + + space = isl_map_take_space(map); + space = isl_space_set_dim_id(space, type, pos, id); + map = isl_map_restore_space(map, space); + + return isl_map_reset_space(map, isl_map_get_space(map)); +} + +__isl_give isl_set *isl_set_set_dim_id(__isl_take isl_set *set, + enum isl_dim_type type, unsigned pos, __isl_take isl_id *id) +{ + return isl_map_set_dim_id(set, type, pos, id); +} + +int isl_map_find_dim_by_id(__isl_keep isl_map *map, enum isl_dim_type type, + __isl_keep isl_id *id) +{ + if (!map) + return -1; + return isl_space_find_dim_by_id(map->dim, type, id); +} + +int isl_set_find_dim_by_id(__isl_keep isl_set *set, enum isl_dim_type type, + __isl_keep isl_id *id) +{ + return isl_map_find_dim_by_id(set, type, id); +} + +/* Return the position of the dimension of the given type and name + * in "bmap". + * Return -1 if no such dimension can be found. + */ +int isl_basic_map_find_dim_by_name(__isl_keep isl_basic_map *bmap, + enum isl_dim_type type, const char *name) +{ + if (!bmap) + return -1; + return isl_space_find_dim_by_name(bmap->dim, type, name); +} + +int isl_map_find_dim_by_name(__isl_keep isl_map *map, enum isl_dim_type type, + const char *name) +{ + if (!map) + return -1; + return isl_space_find_dim_by_name(map->dim, type, name); +} + +int isl_set_find_dim_by_name(__isl_keep isl_set *set, enum isl_dim_type type, + const char *name) +{ + return isl_map_find_dim_by_name(set, type, name); +} + +/* Check whether equality i of bset is a pure stride constraint + * on a single dimension, i.e., of the form + * + * v = k e + * + * with k a constant and e an existentially quantified variable. + */ +isl_bool isl_basic_set_eq_is_stride(__isl_keep isl_basic_set *bset, int i) +{ + isl_size nparam; + isl_size d; + isl_size n_div; + int pos1; + int pos2; + + nparam = isl_basic_set_dim(bset, isl_dim_param); + d = isl_basic_set_dim(bset, isl_dim_set); + n_div = isl_basic_set_dim(bset, isl_dim_div); + if (nparam < 0 || d < 0 || n_div < 0) + return isl_bool_error; + + if (!isl_int_is_zero(bset->eq[i][0])) + return isl_bool_false; + + if (isl_seq_first_non_zero(bset->eq[i] + 1, nparam) != -1) + return isl_bool_false; + pos1 = isl_seq_first_non_zero(bset->eq[i] + 1 + nparam, d); + if (pos1 == -1) + return isl_bool_false; + if (isl_seq_first_non_zero(bset->eq[i] + 1 + nparam + pos1 + 1, + d - pos1 - 1) != -1) + return isl_bool_false; + + pos2 = isl_seq_first_non_zero(bset->eq[i] + 1 + nparam + d, n_div); + if (pos2 == -1) + return isl_bool_false; + if (isl_seq_first_non_zero(bset->eq[i] + 1 + nparam + d + pos2 + 1, + n_div - pos2 - 1) != -1) + return isl_bool_false; + if (!isl_int_is_one(bset->eq[i][1 + nparam + pos1]) && + !isl_int_is_negone(bset->eq[i][1 + nparam + pos1])) + return isl_bool_false; + + return isl_bool_true; +} + +/* Reset the user pointer on all identifiers of parameters and tuples + * of the space of "map". + */ +__isl_give isl_map *isl_map_reset_user(__isl_take isl_map *map) +{ + isl_space *space; + + space = isl_map_get_space(map); + space = isl_space_reset_user(space); + map = isl_map_reset_space(map, space); + + return map; +} + +/* Reset the user pointer on all identifiers of parameters and tuples + * of the space of "set". + */ +__isl_give isl_set *isl_set_reset_user(__isl_take isl_set *set) +{ + return isl_map_reset_user(set); +} + +isl_bool isl_basic_map_is_rational(__isl_keep isl_basic_map *bmap) +{ + if (!bmap) + return isl_bool_error; + return ISL_F_ISSET(bmap, ISL_BASIC_MAP_RATIONAL); +} + +/* Has "map" been marked as a rational map? + * In particular, have all basic maps in "map" been marked this way? + * An empty map is not considered to be rational. + * Maps where only some of the basic maps are marked rational + * are not allowed. + */ +isl_bool isl_map_is_rational(__isl_keep isl_map *map) +{ + int i; + isl_bool rational; + + if (!map) + return isl_bool_error; + if (map->n == 0) + return isl_bool_false; + rational = isl_basic_map_is_rational(map->p[0]); + if (rational < 0) + return rational; + for (i = 1; i < map->n; ++i) { + isl_bool rational_i; + + rational_i = isl_basic_map_is_rational(map->p[i]); + if (rational_i < 0) + return rational_i; + if (rational != rational_i) + isl_die(isl_map_get_ctx(map), isl_error_unsupported, + "mixed rational and integer basic maps " + "not supported", return isl_bool_error); + } + + return rational; +} + +/* Has "set" been marked as a rational set? + * In particular, have all basic set in "set" been marked this way? + * An empty set is not considered to be rational. + * Sets where only some of the basic sets are marked rational + * are not allowed. + */ +isl_bool isl_set_is_rational(__isl_keep isl_set *set) +{ + return isl_map_is_rational(set); +} + +int isl_basic_set_is_rational(__isl_keep isl_basic_set *bset) +{ + return isl_basic_map_is_rational(bset); +} + +/* Does "bmap" contain any rational points? + * + * If "bmap" has an equality for each dimension, equating the dimension + * to an integer constant, then it has no rational points, even if it + * is marked as rational. + */ +isl_bool isl_basic_map_has_rational(__isl_keep isl_basic_map *bmap) +{ + isl_bool has_rational = isl_bool_true; + isl_size total; + + if (!bmap) + return isl_bool_error; + if (isl_basic_map_plain_is_empty(bmap)) + return isl_bool_false; + if (!isl_basic_map_is_rational(bmap)) + return isl_bool_false; + bmap = isl_basic_map_copy(bmap); + bmap = isl_basic_map_implicit_equalities(bmap); + total = isl_basic_map_dim(bmap, isl_dim_all); + if (total < 0) + return isl_bool_error; + if (bmap->n_eq == total) { + int i, j; + for (i = 0; i < bmap->n_eq; ++i) { + j = isl_seq_first_non_zero(bmap->eq[i] + 1, total); + if (j < 0) + break; + if (!isl_int_is_one(bmap->eq[i][1 + j]) && + !isl_int_is_negone(bmap->eq[i][1 + j])) + break; + j = isl_seq_first_non_zero(bmap->eq[i] + 1 + j + 1, + total - j - 1); + if (j >= 0) + break; + } + if (i == bmap->n_eq) + has_rational = isl_bool_false; + } + isl_basic_map_free(bmap); + + return has_rational; +} + +/* Does "map" contain any rational points? + */ +isl_bool isl_map_has_rational(__isl_keep isl_map *map) +{ + int i; + isl_bool has_rational; + + if (!map) + return isl_bool_error; + for (i = 0; i < map->n; ++i) { + has_rational = isl_basic_map_has_rational(map->p[i]); + if (has_rational < 0 || has_rational) + return has_rational; + } + return isl_bool_false; +} + +/* Does "set" contain any rational points? + */ +isl_bool isl_set_has_rational(__isl_keep isl_set *set) +{ + return isl_map_has_rational(set); +} + +/* Is this basic set a parameter domain? + */ +isl_bool isl_basic_set_is_params(__isl_keep isl_basic_set *bset) +{ + if (!bset) + return isl_bool_error; + return isl_space_is_params(bset->dim); +} + +/* Is this set a parameter domain? + */ +isl_bool isl_set_is_params(__isl_keep isl_set *set) +{ + if (!set) + return isl_bool_error; + return isl_space_is_params(set->dim); +} + +/* Is this map actually a parameter domain? + * Users should never call this function. Outside of isl, + * a map can never be a parameter domain. + */ +isl_bool isl_map_is_params(__isl_keep isl_map *map) +{ + if (!map) + return isl_bool_error; + return isl_space_is_params(map->dim); +} + +static __isl_give isl_basic_map *basic_map_init(isl_ctx *ctx, + __isl_take isl_basic_map *bmap, unsigned extra, + unsigned n_eq, unsigned n_ineq) +{ + int i; + isl_space *space = isl_basic_map_peek_space(bmap); + isl_size n_var = isl_space_dim(space, isl_dim_all); + size_t row_size = 1 + n_var + extra; + + bmap->ctx = ctx; + isl_ctx_ref(ctx); + + if (n_var < 0) + return isl_basic_map_free(bmap); + + bmap->block = isl_blk_alloc(ctx, (n_ineq + n_eq) * row_size); + if (isl_blk_is_error(bmap->block)) + goto error; + + bmap->ineq = isl_alloc_array(ctx, isl_int *, n_ineq + n_eq); + if ((n_ineq + n_eq) && !bmap->ineq) + goto error; + + if (extra == 0) { + bmap->block2 = isl_blk_empty(); + bmap->div = NULL; + } else { + bmap->block2 = isl_blk_alloc(ctx, extra * (1 + row_size)); + if (isl_blk_is_error(bmap->block2)) + goto error; + + bmap->div = isl_alloc_array(ctx, isl_int *, extra); + if (!bmap->div) + goto error; + } + + for (i = 0; i < n_ineq + n_eq; ++i) + bmap->ineq[i] = bmap->block.data + i * row_size; + + for (i = 0; i < extra; ++i) + bmap->div[i] = bmap->block2.data + i * (1 + row_size); + + bmap->ref = 1; + bmap->flags = 0; + bmap->c_size = n_eq + n_ineq; + bmap->eq = bmap->ineq + n_ineq; + bmap->extra = extra; + bmap->n_eq = 0; + bmap->n_ineq = 0; + bmap->n_div = 0; + bmap->sample = NULL; + + return bmap; +error: + isl_basic_map_free(bmap); + return NULL; +} + +__isl_give isl_basic_set *isl_basic_set_alloc(isl_ctx *ctx, + unsigned nparam, unsigned dim, unsigned extra, + unsigned n_eq, unsigned n_ineq) +{ + struct isl_basic_map *bmap; + isl_space *space; + + space = isl_space_set_alloc(ctx, nparam, dim); + if (!space) + return NULL; + + bmap = isl_basic_map_alloc_space(space, extra, n_eq, n_ineq); + return bset_from_bmap(bmap); +} + +__isl_give isl_basic_set *isl_basic_set_alloc_space(__isl_take isl_space *space, + unsigned extra, unsigned n_eq, unsigned n_ineq) +{ + struct isl_basic_map *bmap; + if (!space) + return NULL; + isl_assert(space->ctx, space->n_in == 0, goto error); + bmap = isl_basic_map_alloc_space(space, extra, n_eq, n_ineq); + return bset_from_bmap(bmap); +error: + isl_space_free(space); + return NULL; +} + +__isl_give isl_basic_map *isl_basic_map_alloc_space(__isl_take isl_space *space, + unsigned extra, unsigned n_eq, unsigned n_ineq) +{ + struct isl_basic_map *bmap; + + if (!space) + return NULL; + bmap = isl_calloc_type(space->ctx, struct isl_basic_map); + if (!bmap) + goto error; + bmap->dim = space; + + return basic_map_init(space->ctx, bmap, extra, n_eq, n_ineq); +error: + isl_space_free(space); + return NULL; +} + +__isl_give isl_basic_map *isl_basic_map_alloc(isl_ctx *ctx, + unsigned nparam, unsigned in, unsigned out, unsigned extra, + unsigned n_eq, unsigned n_ineq) +{ + struct isl_basic_map *bmap; + isl_space *space; + + space = isl_space_alloc(ctx, nparam, in, out); + if (!space) + return NULL; + + bmap = isl_basic_map_alloc_space(space, extra, n_eq, n_ineq); + return bmap; +} + +static __isl_give isl_basic_map *dup_constraints(__isl_take isl_basic_map *dst, + __isl_keep isl_basic_map *src) +{ + int i; + isl_size total = isl_basic_map_dim(src, isl_dim_all); + + if (!dst || total < 0) + return isl_basic_map_free(dst); + + for (i = 0; i < src->n_eq; ++i) { + int j = isl_basic_map_alloc_equality(dst); + if (j < 0) + return isl_basic_map_free(dst); + isl_seq_cpy(dst->eq[j], src->eq[i], 1+total); + } + + for (i = 0; i < src->n_ineq; ++i) { + int j = isl_basic_map_alloc_inequality(dst); + if (j < 0) + return isl_basic_map_free(dst); + isl_seq_cpy(dst->ineq[j], src->ineq[i], 1+total); + } + + for (i = 0; i < src->n_div; ++i) { + int j = isl_basic_map_alloc_div(dst); + if (j < 0) + return isl_basic_map_free(dst); + isl_seq_cpy(dst->div[j], src->div[i], 1+1+total); + } + ISL_F_SET(dst, ISL_BASIC_SET_FINAL); + return dst; +} + +__isl_give isl_basic_map *isl_basic_map_dup(__isl_keep isl_basic_map *bmap) +{ + struct isl_basic_map *dup; + + if (!bmap) + return NULL; + dup = isl_basic_map_alloc_space(isl_space_copy(bmap->dim), + bmap->n_div, bmap->n_eq, bmap->n_ineq); + dup = dup_constraints(dup, bmap); + if (!dup) + return NULL; + dup->flags = bmap->flags; + dup->sample = isl_vec_copy(bmap->sample); + return dup; +} + +__isl_give isl_basic_set *isl_basic_set_dup(__isl_keep isl_basic_set *bset) +{ + struct isl_basic_map *dup; + + dup = isl_basic_map_dup(bset_to_bmap(bset)); + return bset_from_bmap(dup); +} + +__isl_give isl_basic_set *isl_basic_set_copy(__isl_keep isl_basic_set *bset) +{ + return bset_from_bmap(isl_basic_map_copy(bset_to_bmap(bset))); +} + +__isl_give isl_set *isl_set_copy(__isl_keep isl_set *set) +{ + if (!set) + return NULL; + + set->ref++; + return set; +} + +__isl_give isl_basic_map *isl_basic_map_copy(__isl_keep isl_basic_map *bmap) +{ + if (!bmap) + return NULL; + + if (ISL_F_ISSET(bmap, ISL_BASIC_SET_FINAL)) { + bmap->ref++; + return bmap; + } + bmap = isl_basic_map_dup(bmap); + if (bmap) + ISL_F_SET(bmap, ISL_BASIC_SET_FINAL); + return bmap; +} + +__isl_give isl_map *isl_map_copy(__isl_keep isl_map *map) +{ + if (!map) + return NULL; + + map->ref++; + return map; +} + +__isl_null isl_basic_map *isl_basic_map_free(__isl_take isl_basic_map *bmap) +{ + if (!bmap) + return NULL; + + if (--bmap->ref > 0) + return NULL; + + isl_ctx_deref(bmap->ctx); + free(bmap->div); + isl_blk_free(bmap->ctx, bmap->block2); + free(bmap->ineq); + isl_blk_free(bmap->ctx, bmap->block); + isl_vec_free(bmap->sample); + isl_space_free(bmap->dim); + free(bmap); + + return NULL; +} + +__isl_null isl_basic_set *isl_basic_set_free(__isl_take isl_basic_set *bset) +{ + return isl_basic_map_free(bset_to_bmap(bset)); +} + +static int room_for_con(__isl_keep isl_basic_map *bmap, unsigned n) +{ + return bmap->n_eq + bmap->n_ineq + n <= bmap->c_size; +} + +/* Check that "bset" does not involve any parameters. + */ +isl_stat isl_basic_set_check_no_params(__isl_keep isl_basic_set *bset) +{ + isl_size nparam; + + nparam = isl_basic_set_dim(bset, isl_dim_param); + if (nparam < 0) + return isl_stat_error; + if (nparam != 0) + isl_die(isl_basic_set_get_ctx(bset), isl_error_invalid, + "basic set should not have any parameters", + return isl_stat_error); + return isl_stat_ok; +} + +/* Check that "bset" does not involve any local variables. + */ +isl_stat isl_basic_set_check_no_locals(__isl_keep isl_basic_set *bset) +{ + isl_size n_div; + + n_div = isl_basic_set_dim(bset, isl_dim_div); + if (n_div < 0) + return isl_stat_error; + if (n_div != 0) + isl_die(isl_basic_set_get_ctx(bset), isl_error_invalid, + "basic set should not have any local variables", + return isl_stat_error); + return isl_stat_ok; +} + +#undef TYPE +#define TYPE isl_map + +#include "isl_check_named_params_templ.c" + +#undef TYPE +#define TYPE isl_basic_map + +static +#include "isl_check_named_params_templ.c" + +/* Check that "bmap1" and "bmap2" have the same parameters, + * reporting an error if they do not. + */ +static isl_stat isl_basic_map_check_equal_params( + __isl_keep isl_basic_map *bmap1, __isl_keep isl_basic_map *bmap2) +{ + isl_bool match; + + match = isl_basic_map_has_equal_params(bmap1, bmap2); + if (match < 0) + return isl_stat_error; + if (!match) + isl_die(isl_basic_map_get_ctx(bmap1), isl_error_invalid, + "parameters don't match", return isl_stat_error); + return isl_stat_ok; +} + +#undef TYPE +#define TYPE isl_map + +#include "isl_align_params_bin_templ.c" + +#undef SUFFIX +#define SUFFIX set +#undef ARG1 +#define ARG1 isl_map +#undef ARG2 +#define ARG2 isl_set + +#include "isl_align_params_templ.c" + +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_bool r; + + if (!map1 || !map2) + return isl_bool_error; + if (isl_map_has_equal_params(map1, map2)) + return fn(map1, map2); + if (isl_map_check_named_params(map1) < 0) + return isl_bool_error; + if (isl_map_check_named_params(map2) < 0) + return isl_bool_error; + map1 = isl_map_copy(map1); + map2 = isl_map_copy(map2); + map1 = isl_map_align_params(map1, isl_map_get_space(map2)); + map2 = isl_map_align_params(map2, isl_map_get_space(map1)); + r = fn(map1, map2); + isl_map_free(map1); + isl_map_free(map2); + return r; +} + +int isl_basic_map_alloc_equality(__isl_keep isl_basic_map *bmap) +{ + isl_size total; + struct isl_ctx *ctx; + + total = isl_basic_map_dim(bmap, isl_dim_all); + if (total < 0) + return -1; + ctx = bmap->ctx; + isl_assert(ctx, room_for_con(bmap, 1), return -1); + isl_assert(ctx, (bmap->eq - bmap->ineq) + bmap->n_eq <= bmap->c_size, + return -1); + ISL_F_CLR(bmap, ISL_BASIC_MAP_NO_REDUNDANT); + ISL_F_CLR(bmap, ISL_BASIC_MAP_NO_IMPLICIT); + ISL_F_CLR(bmap, ISL_BASIC_MAP_ALL_EQUALITIES); + ISL_F_CLR(bmap, ISL_BASIC_MAP_NORMALIZED_DIVS); + if ((bmap->eq - bmap->ineq) + bmap->n_eq == bmap->c_size) { + isl_int *t; + int j = isl_basic_map_alloc_inequality(bmap); + if (j < 0) + return -1; + t = bmap->ineq[j]; + bmap->ineq[j] = bmap->ineq[bmap->n_ineq - 1]; + bmap->ineq[bmap->n_ineq - 1] = bmap->eq[-1]; + bmap->eq[-1] = t; + bmap->n_eq++; + bmap->n_ineq--; + bmap->eq--; + return 0; + } + isl_seq_clr(bmap->eq[bmap->n_eq] + 1 + total, + bmap->extra - bmap->n_div); + return bmap->n_eq++; +} + +int isl_basic_set_alloc_equality(__isl_keep isl_basic_set *bset) +{ + return isl_basic_map_alloc_equality(bset_to_bmap(bset)); +} + +__isl_give isl_basic_map *isl_basic_map_free_equality( + __isl_take isl_basic_map *bmap, unsigned n) +{ + if (!bmap) + return NULL; + if (n > bmap->n_eq) + isl_die(isl_basic_map_get_ctx(bmap), isl_error_invalid, + "invalid number of equalities", + isl_basic_map_free(bmap)); + bmap->n_eq -= n; + return bmap; +} + +__isl_give isl_basic_set *isl_basic_set_free_equality( + __isl_take isl_basic_set *bset, unsigned n) +{ + return bset_from_bmap(isl_basic_map_free_equality(bset_to_bmap(bset), + n)); +} + +/* Drop the equality constraint at position "pos", + * preserving the order of the other equality constraints. + */ +int isl_basic_map_drop_equality(__isl_keep isl_basic_map *bmap, unsigned pos) +{ + isl_int *t; + int r; + + if (!bmap) + return -1; + isl_assert(bmap->ctx, pos < bmap->n_eq, return -1); + + t = bmap->eq[pos]; + bmap->n_eq--; + for (r = pos; r < bmap->n_eq; ++r) + bmap->eq[r] = bmap->eq[r + 1]; + bmap->eq[bmap->n_eq] = t; + + return 0; +} + +/* Turn inequality "pos" of "bmap" into an equality. + * + * In particular, we move the inequality in front of the equalities + * and move the last inequality in the position of the moved inequality. + * Note that isl_tab_make_equalities_explicit depends on this particular + * change in the ordering of the constraints. + */ +void isl_basic_map_inequality_to_equality( + __isl_keep isl_basic_map *bmap, unsigned pos) +{ + isl_int *t; + + t = bmap->ineq[pos]; + bmap->ineq[pos] = bmap->ineq[bmap->n_ineq - 1]; + bmap->ineq[bmap->n_ineq - 1] = bmap->eq[-1]; + bmap->eq[-1] = t; + bmap->n_eq++; + bmap->n_ineq--; + bmap->eq--; + ISL_F_CLR(bmap, ISL_BASIC_MAP_NO_REDUNDANT); + ISL_F_CLR(bmap, ISL_BASIC_MAP_SORTED); + ISL_F_CLR(bmap, ISL_BASIC_MAP_NORMALIZED_DIVS); + ISL_F_CLR(bmap, ISL_BASIC_MAP_ALL_EQUALITIES); +} + +static int room_for_ineq(__isl_keep isl_basic_map *bmap, unsigned n) +{ + return bmap->n_ineq + n <= bmap->eq - bmap->ineq; +} + +int isl_basic_map_alloc_inequality(__isl_keep isl_basic_map *bmap) +{ + isl_size total; + struct isl_ctx *ctx; + + total = isl_basic_map_dim(bmap, isl_dim_all); + if (total < 0) + return -1; + ctx = bmap->ctx; + isl_assert(ctx, room_for_ineq(bmap, 1), return -1); + ISL_F_CLR(bmap, ISL_BASIC_MAP_NO_IMPLICIT); + ISL_F_CLR(bmap, ISL_BASIC_MAP_NO_REDUNDANT); + ISL_F_CLR(bmap, ISL_BASIC_MAP_SORTED); + ISL_F_CLR(bmap, ISL_BASIC_MAP_ALL_EQUALITIES); + isl_seq_clr(bmap->ineq[bmap->n_ineq] + 1 + total, + bmap->extra - bmap->n_div); + return bmap->n_ineq++; +} + +int isl_basic_set_alloc_inequality(__isl_keep isl_basic_set *bset) +{ + return isl_basic_map_alloc_inequality(bset_to_bmap(bset)); +} + +__isl_give isl_basic_map *isl_basic_map_free_inequality( + __isl_take isl_basic_map *bmap, unsigned n) +{ + if (!bmap) + return NULL; + if (n > bmap->n_ineq) + isl_die(isl_basic_map_get_ctx(bmap), isl_error_invalid, + "invalid number of inequalities", + return isl_basic_map_free(bmap)); + bmap->n_ineq -= n; + return bmap; +} + +__isl_give isl_basic_set *isl_basic_set_free_inequality( + __isl_take isl_basic_set *bset, unsigned n) +{ + return bset_from_bmap(isl_basic_map_free_inequality(bset_to_bmap(bset), + n)); +} + +int isl_basic_map_drop_inequality(__isl_keep isl_basic_map *bmap, unsigned pos) +{ + isl_int *t; + if (!bmap) + return -1; + isl_assert(bmap->ctx, pos < bmap->n_ineq, return -1); + + if (pos != bmap->n_ineq - 1) { + t = bmap->ineq[pos]; + bmap->ineq[pos] = bmap->ineq[bmap->n_ineq - 1]; + bmap->ineq[bmap->n_ineq - 1] = t; + ISL_F_CLR(bmap, ISL_BASIC_MAP_SORTED); + } + bmap->n_ineq--; + return 0; +} + +int isl_basic_set_drop_inequality(__isl_keep isl_basic_set *bset, unsigned pos) +{ + return isl_basic_map_drop_inequality(bset_to_bmap(bset), pos); +} + +__isl_give isl_basic_map *isl_basic_map_add_eq(__isl_take isl_basic_map *bmap, + isl_int *eq) +{ + isl_bool empty; + isl_size total; + int k; + + empty = isl_basic_map_plain_is_empty(bmap); + if (empty < 0) + return isl_basic_map_free(bmap); + if (empty) + return bmap; + + bmap = isl_basic_map_cow(bmap); + bmap = isl_basic_map_extend_constraints(bmap, 1, 0); + total = isl_basic_map_dim(bmap, isl_dim_all); + if (total < 0) + return isl_basic_map_free(bmap); + k = isl_basic_map_alloc_equality(bmap); + if (k < 0) + goto error; + isl_seq_cpy(bmap->eq[k], eq, 1 + total); + return bmap; +error: + isl_basic_map_free(bmap); + return NULL; +} + +__isl_give isl_basic_set *isl_basic_set_add_eq(__isl_take isl_basic_set *bset, + isl_int *eq) +{ + return bset_from_bmap(isl_basic_map_add_eq(bset_to_bmap(bset), eq)); +} + +__isl_give isl_basic_map *isl_basic_map_add_ineq(__isl_take isl_basic_map *bmap, + isl_int *ineq) +{ + isl_size total; + int k; + + bmap = isl_basic_map_cow(bmap); + bmap = isl_basic_map_extend_constraints(bmap, 0, 1); + total = isl_basic_map_dim(bmap, isl_dim_all); + if (total < 0) + return isl_basic_map_free(bmap); + k = isl_basic_map_alloc_inequality(bmap); + if (k < 0) + goto error; + isl_seq_cpy(bmap->ineq[k], ineq, 1 + total); + return bmap; +error: + isl_basic_map_free(bmap); + return NULL; +} + +__isl_give isl_basic_set *isl_basic_set_add_ineq(__isl_take isl_basic_set *bset, + isl_int *ineq) +{ + return bset_from_bmap(isl_basic_map_add_ineq(bset_to_bmap(bset), ineq)); +} + +int isl_basic_map_alloc_div(__isl_keep isl_basic_map *bmap) +{ + isl_size total; + + total = isl_basic_map_dim(bmap, isl_dim_all); + if (total < 0) + return -1; + isl_assert(bmap->ctx, bmap->n_div < bmap->extra, return -1); + isl_seq_clr(bmap->div[bmap->n_div] + 1 + 1 + total, + bmap->extra - bmap->n_div); + ISL_F_CLR(bmap, ISL_BASIC_MAP_NORMALIZED_DIVS); + return bmap->n_div++; +} + +int isl_basic_set_alloc_div(__isl_keep isl_basic_set *bset) +{ + return isl_basic_map_alloc_div(bset_to_bmap(bset)); +} + +#undef TYPE +#define TYPE isl_basic_map +#include "check_type_range_templ.c" + +/* Check that there are "n" dimensions of type "type" starting at "first" + * in "bset". + */ +isl_stat isl_basic_set_check_range(__isl_keep isl_basic_set *bset, + enum isl_dim_type type, unsigned first, unsigned n) +{ + return isl_basic_map_check_range(bset_to_bmap(bset), + type, first, n); +} + +/* Insert an extra integer division, prescribed by "div", to "bmap" + * at (integer division) position "pos". + * + * The integer division is first added at the end and then moved + * into the right position. + */ +__isl_give isl_basic_map *isl_basic_map_insert_div( + __isl_take isl_basic_map *bmap, int pos, __isl_keep isl_vec *div) +{ + int i, k; + isl_size total; + + bmap = isl_basic_map_cow(bmap); + total = isl_basic_map_dim(bmap, isl_dim_all); + if (total < 0 || !div) + return isl_basic_map_free(bmap); + + if (div->size != 1 + 1 + total) + isl_die(isl_basic_map_get_ctx(bmap), isl_error_invalid, + "unexpected size", return isl_basic_map_free(bmap)); + if (isl_basic_map_check_range(bmap, isl_dim_div, pos, 0) < 0) + return isl_basic_map_free(bmap); + + bmap = isl_basic_map_extend(bmap, 1, 0, 2); + k = isl_basic_map_alloc_div(bmap); + if (k < 0) + return isl_basic_map_free(bmap); + isl_seq_cpy(bmap->div[k], div->el, div->size); + isl_int_set_si(bmap->div[k][div->size], 0); + + for (i = k; i > pos; --i) + bmap = isl_basic_map_swap_div(bmap, i, i - 1); + + return bmap; +} + +isl_stat isl_basic_map_free_div(__isl_keep isl_basic_map *bmap, unsigned n) +{ + if (!bmap) + return isl_stat_error; + isl_assert(bmap->ctx, n <= bmap->n_div, return isl_stat_error); + bmap->n_div -= n; + return isl_stat_ok; +} + +static __isl_give isl_basic_map *add_constraints( + __isl_take isl_basic_map *bmap1, __isl_take isl_basic_map *bmap2, + unsigned i_pos, unsigned o_pos) +{ + isl_size total, n_param, n_in, n_out, n_div; + unsigned o_in, o_out; + isl_ctx *ctx; + isl_space *space; + struct isl_dim_map *dim_map; + + space = isl_basic_map_peek_space(bmap2); + if (!bmap1 || !space) + goto error; + + total = isl_basic_map_dim(bmap1, isl_dim_all); + n_param = isl_basic_map_dim(bmap2, isl_dim_param); + n_in = isl_basic_map_dim(bmap2, isl_dim_in); + o_in = isl_basic_map_offset(bmap1, isl_dim_in) - 1 + i_pos; + n_out = isl_basic_map_dim(bmap2, isl_dim_out); + o_out = isl_basic_map_offset(bmap1, isl_dim_out) - 1 + o_pos; + n_div = isl_basic_map_dim(bmap2, isl_dim_div); + if (total < 0 || n_param < 0 || n_in < 0 || n_out < 0 || n_div < 0) + goto error; + ctx = isl_basic_map_get_ctx(bmap1); + dim_map = isl_dim_map_alloc(ctx, total + n_div); + isl_dim_map_dim_range(dim_map, space, isl_dim_param, 0, n_param, 0); + isl_dim_map_dim_range(dim_map, space, isl_dim_in, 0, n_in, o_in); + isl_dim_map_dim_range(dim_map, space, isl_dim_out, 0, n_out, o_out); + isl_dim_map_div(dim_map, bmap2, total); + + return isl_basic_map_add_constraints_dim_map(bmap1, bmap2, dim_map); +error: + isl_basic_map_free(bmap1); + isl_basic_map_free(bmap2); + return NULL; +} + +__isl_give isl_basic_map *isl_basic_map_extend(__isl_take isl_basic_map *base, + unsigned extra, unsigned n_eq, unsigned n_ineq) +{ + isl_space *space; + struct isl_basic_map *ext; + unsigned flags; + int dims_ok; + + if (!base) + goto error; + + dims_ok = base->extra >= base->n_div + extra; + + if (dims_ok && room_for_con(base, n_eq + n_ineq) && + room_for_ineq(base, n_ineq)) + return base; + + extra += base->extra; + n_eq += base->n_eq; + n_ineq += base->n_ineq; + + space = isl_basic_map_get_space(base); + ext = isl_basic_map_alloc_space(space, extra, n_eq, n_ineq); + if (!ext) + goto error; + + if (dims_ok) + ext->sample = isl_vec_copy(base->sample); + flags = base->flags; + ext = add_constraints(ext, base, 0, 0); + if (ext) { + ext->flags = flags; + ISL_F_CLR(ext, ISL_BASIC_SET_FINAL); + } + + return ext; + +error: + isl_basic_map_free(base); + return NULL; +} + +__isl_give isl_basic_set *isl_basic_set_extend(__isl_take isl_basic_set *base, + unsigned extra, unsigned n_eq, unsigned n_ineq) +{ + return bset_from_bmap(isl_basic_map_extend(bset_to_bmap(base), + extra, n_eq, n_ineq)); +} + +__isl_give isl_basic_map *isl_basic_map_extend_constraints( + __isl_take isl_basic_map *base, unsigned n_eq, unsigned n_ineq) +{ + return isl_basic_map_extend(base, 0, n_eq, n_ineq); +} + +__isl_give isl_basic_set *isl_basic_set_extend_constraints( + __isl_take isl_basic_set *base, unsigned n_eq, unsigned n_ineq) +{ + isl_basic_map *bmap = bset_to_bmap(base); + bmap = isl_basic_map_extend_constraints(bmap, n_eq, n_ineq); + return bset_from_bmap(bmap); +} + +__isl_give isl_basic_set *isl_basic_set_cow(__isl_take isl_basic_set *bset) +{ + return bset_from_bmap(isl_basic_map_cow(bset_to_bmap(bset))); +} + +__isl_give isl_basic_map *isl_basic_map_cow(__isl_take isl_basic_map *bmap) +{ + if (!bmap) + return NULL; + + if (bmap->ref > 1) { + bmap->ref--; + bmap = isl_basic_map_dup(bmap); + } + if (bmap) { + ISL_F_CLR(bmap, ISL_BASIC_SET_FINAL); + ISL_F_CLR(bmap, ISL_BASIC_MAP_REDUCED_COEFFICIENTS); + } + return bmap; +} + +/* Clear all cached information in "map", either because it is about + * to be modified or because it is being freed. + * Always return the same pointer that is passed in. + * This is needed for the use in isl_map_free. + */ +static __isl_give isl_map *clear_caches(__isl_take isl_map *map) +{ + isl_basic_map_free(map->cached_simple_hull[0]); + isl_basic_map_free(map->cached_simple_hull[1]); + map->cached_simple_hull[0] = NULL; + map->cached_simple_hull[1] = NULL; + return map; +} + +__isl_give isl_set *isl_set_cow(__isl_take isl_set *set) +{ + return isl_map_cow(set); +} + +/* Return an isl_map that is equal to "map" and that has only + * a single reference. + * + * If the original input already has only one reference, then + * simply return it, but clear all cached information, since + * it may be rendered invalid by the operations that will be + * performed on the result. + * + * Otherwise, create a duplicate (without any cached information). + */ +__isl_give isl_map *isl_map_cow(__isl_take isl_map *map) +{ + if (!map) + return NULL; + + if (map->ref == 1) + return clear_caches(map); + map->ref--; + return isl_map_dup(map); +} + +static void swap_vars(struct isl_blk blk, isl_int *a, + unsigned a_len, unsigned b_len) +{ + isl_seq_cpy(blk.data, a+a_len, b_len); + isl_seq_cpy(blk.data+b_len, a, a_len); + isl_seq_cpy(a, blk.data, b_len+a_len); +} + +static __isl_give isl_basic_map *isl_basic_map_swap_vars( + __isl_take isl_basic_map *bmap, unsigned pos, unsigned n1, unsigned n2) +{ + int i; + struct isl_blk blk; + + if (isl_basic_map_check_range(bmap, isl_dim_all, pos - 1, n1 + n2) < 0) + goto error; + + if (n1 == 0 || n2 == 0) + return bmap; + + bmap = isl_basic_map_cow(bmap); + if (!bmap) + return NULL; + + blk = isl_blk_alloc(bmap->ctx, n1 + n2); + if (isl_blk_is_error(blk)) + goto error; + + for (i = 0; i < bmap->n_eq; ++i) + swap_vars(blk, + bmap->eq[i] + pos, n1, n2); + + for (i = 0; i < bmap->n_ineq; ++i) + swap_vars(blk, + bmap->ineq[i] + pos, n1, n2); + + for (i = 0; i < bmap->n_div; ++i) + swap_vars(blk, + bmap->div[i]+1 + pos, n1, n2); + + isl_blk_free(bmap->ctx, blk); + + ISL_F_CLR(bmap, ISL_BASIC_SET_SORTED); + bmap = isl_basic_map_gauss(bmap, NULL); + return isl_basic_map_finalize(bmap); +error: + isl_basic_map_free(bmap); + return NULL; +} + +/* The given basic map has turned out to be empty. + * Explicitly mark it as such and change the representation + * to a canonical representation of the empty basic map. + * Since the basic map has conflicting constraints, + * it must have at least one constraint, except perhaps + * if it was already explicitly marked as being empty. + * Do nothing in the latter case, i.e., if it has been marked empty and + * has no constraints. + */ +__isl_give isl_basic_map *isl_basic_map_set_to_empty( + __isl_take isl_basic_map *bmap) +{ + int i = 0; + isl_bool empty; + isl_size n; + isl_size total; + + n = isl_basic_map_n_constraint(bmap); + empty = isl_basic_map_plain_is_empty(bmap); + if (n < 0 || empty < 0) + return isl_basic_map_free(bmap); + if (n == 0 && empty) + return bmap; + total = isl_basic_map_dim(bmap, isl_dim_all); + if (total < 0) + return isl_basic_map_free(bmap); + if (isl_basic_map_free_div(bmap, bmap->n_div) < 0) + return isl_basic_map_free(bmap); + bmap = isl_basic_map_free_inequality(bmap, bmap->n_ineq); + if (!bmap) + return NULL; + if (bmap->n_eq > 0) { + bmap = isl_basic_map_free_equality(bmap, bmap->n_eq - 1); + if (!bmap) + return NULL; + } else { + i = isl_basic_map_alloc_equality(bmap); + if (i < 0) + goto error; + } + isl_int_set_si(bmap->eq[i][0], 1); + isl_seq_clr(bmap->eq[i]+1, total); + ISL_F_SET(bmap, ISL_BASIC_MAP_EMPTY); + isl_vec_free(bmap->sample); + bmap->sample = NULL; + return isl_basic_map_finalize(bmap); +error: + isl_basic_map_free(bmap); + return NULL; +} + +__isl_give isl_basic_set *isl_basic_set_set_to_empty( + __isl_take isl_basic_set *bset) +{ + return bset_from_bmap(isl_basic_map_set_to_empty(bset_to_bmap(bset))); +} + +__isl_give isl_basic_map *isl_basic_map_set_rational( + __isl_take isl_basic_map *bmap) +{ + if (!bmap) + return NULL; + + if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_RATIONAL)) + return bmap; + + bmap = isl_basic_map_cow(bmap); + if (!bmap) + return NULL; + + ISL_F_SET(bmap, ISL_BASIC_MAP_RATIONAL); + + return isl_basic_map_finalize(bmap); +} + +__isl_give isl_basic_set *isl_basic_set_set_rational( + __isl_take isl_basic_set *bset) +{ + return isl_basic_map_set_rational(bset); +} + +__isl_give isl_basic_set *isl_basic_set_set_integral( + __isl_take isl_basic_set *bset) +{ + if (!bset) + return NULL; + + if (!ISL_F_ISSET(bset, ISL_BASIC_MAP_RATIONAL)) + return bset; + + bset = isl_basic_set_cow(bset); + if (!bset) + return NULL; + + ISL_F_CLR(bset, ISL_BASIC_MAP_RATIONAL); + + return isl_basic_set_finalize(bset); +} + +__isl_give isl_map *isl_map_set_rational(__isl_take isl_map *map) +{ + int i; + + map = isl_map_cow(map); + if (!map) + return NULL; + for (i = 0; i < map->n; ++i) { + map->p[i] = isl_basic_map_set_rational(map->p[i]); + if (!map->p[i]) + goto error; + } + return map; +error: + isl_map_free(map); + return NULL; +} + +__isl_give isl_set *isl_set_set_rational(__isl_take isl_set *set) +{ + return isl_map_set_rational(set); +} + +/* Swap divs "a" and "b" in "bmap" (without modifying any of the constraints + * of "bmap"). + */ +static void swap_div(__isl_keep isl_basic_map *bmap, int a, int b) +{ + isl_int *t = bmap->div[a]; + bmap->div[a] = bmap->div[b]; + bmap->div[b] = t; +} + +/* Swap divs "a" and "b" in "bmap" and adjust the constraints and + * div definitions accordingly. + */ +__isl_give isl_basic_map *isl_basic_map_swap_div(__isl_take isl_basic_map *bmap, + int a, int b) +{ + int i; + isl_size off; + + off = isl_basic_map_var_offset(bmap, isl_dim_div); + if (off < 0) + return isl_basic_map_free(bmap); + + swap_div(bmap, a, b); + + for (i = 0; i < bmap->n_eq; ++i) + isl_int_swap(bmap->eq[i][1+off+a], bmap->eq[i][1+off+b]); + + for (i = 0; i < bmap->n_ineq; ++i) + isl_int_swap(bmap->ineq[i][1+off+a], bmap->ineq[i][1+off+b]); + + for (i = 0; i < bmap->n_div; ++i) + isl_int_swap(bmap->div[i][1+1+off+a], bmap->div[i][1+1+off+b]); + ISL_F_CLR(bmap, ISL_BASIC_MAP_SORTED); + + return bmap; +} + +static void constraint_drop_vars(isl_int *c, unsigned n, unsigned rem) +{ + isl_seq_cpy(c, c + n, rem); + isl_seq_clr(c + rem, n); +} + +/* Drop n dimensions starting at first. + * + * In principle, this frees up some extra variables as the number + * of columns remains constant, but we would have to extend + * the div array too as the number of rows in this array is assumed + * to be equal to extra. + */ +__isl_give isl_basic_set *isl_basic_set_drop_dims( + __isl_take isl_basic_set *bset, unsigned first, unsigned n) +{ + return isl_basic_map_drop(bset_to_bmap(bset), isl_dim_set, first, n); +} + +/* Move "n" divs starting at "first" to the end of the list of divs. + */ +static __isl_give isl_basic_map *move_divs_last(__isl_take isl_basic_map *bmap, + unsigned first, unsigned n) +{ + isl_int **div; + int i; + + if (first + n == bmap->n_div) + return bmap; + + div = isl_alloc_array(bmap->ctx, isl_int *, n); + if (!div) + goto error; + for (i = 0; i < n; ++i) + div[i] = bmap->div[first + i]; + for (i = 0; i < bmap->n_div - first - n; ++i) + bmap->div[first + i] = bmap->div[first + n + i]; + for (i = 0; i < n; ++i) + bmap->div[bmap->n_div - n + i] = div[i]; + free(div); + return bmap; +error: + isl_basic_map_free(bmap); + return NULL; +} + +#undef TYPE +#define TYPE isl_map +static +#include "check_type_range_templ.c" + +/* Check that there are "n" dimensions of type "type" starting at "first" + * in "set". + */ +isl_stat isl_set_check_range(__isl_keep isl_set *set, + enum isl_dim_type type, unsigned first, unsigned n) +{ + return isl_map_check_range(set_to_map(set), type, first, n); +} + +/* Drop "n" dimensions of type "type" starting at "first". + * Perform the core computation, without cowing or + * simplifying and finalizing the result. + * + * In principle, this frees up some extra variables as the number + * of columns remains constant, but we would have to extend + * the div array too as the number of rows in this array is assumed + * to be equal to extra. + */ +__isl_give isl_basic_map *isl_basic_map_drop_core( + __isl_take isl_basic_map *bmap, enum isl_dim_type type, + unsigned first, unsigned n) +{ + int i; + unsigned offset; + unsigned left; + isl_size total; + + if (isl_basic_map_check_range(bmap, type, first, n) < 0) + return isl_basic_map_free(bmap); + + total = isl_basic_map_dim(bmap, isl_dim_all); + if (total < 0) + return isl_basic_map_free(bmap); + + offset = isl_basic_map_offset(bmap, type) + first; + left = total - (offset - 1) - n; + for (i = 0; i < bmap->n_eq; ++i) + constraint_drop_vars(bmap->eq[i]+offset, n, left); + + for (i = 0; i < bmap->n_ineq; ++i) + constraint_drop_vars(bmap->ineq[i]+offset, n, left); + + for (i = 0; i < bmap->n_div; ++i) + constraint_drop_vars(bmap->div[i]+1+offset, n, left); + + if (type == isl_dim_div) { + bmap = move_divs_last(bmap, first, n); + if (!bmap) + return NULL; + if (isl_basic_map_free_div(bmap, n) < 0) + return isl_basic_map_free(bmap); + } else + bmap->dim = isl_space_drop_dims(bmap->dim, type, first, n); + if (!bmap->dim) + return isl_basic_map_free(bmap); + + ISL_F_CLR(bmap, ISL_BASIC_MAP_NO_REDUNDANT); + ISL_F_CLR(bmap, ISL_BASIC_MAP_SORTED); + return bmap; +} + +/* Drop "n" dimensions of type "type" starting at "first". + * + * In principle, this frees up some extra variables as the number + * of columns remains constant, but we would have to extend + * the div array too as the number of rows in this array is assumed + * to be equal to extra. + */ +__isl_give isl_basic_map *isl_basic_map_drop(__isl_take isl_basic_map *bmap, + enum isl_dim_type type, unsigned first, unsigned n) +{ + if (!bmap) + return NULL; + if (n == 0 && !isl_space_is_named_or_nested(bmap->dim, type)) + return bmap; + + bmap = isl_basic_map_cow(bmap); + if (!bmap) + return NULL; + + bmap = isl_basic_map_drop_core(bmap, type, first, n); + + bmap = isl_basic_map_simplify(bmap); + return isl_basic_map_finalize(bmap); +} + +__isl_give isl_basic_set *isl_basic_set_drop(__isl_take isl_basic_set *bset, + enum isl_dim_type type, unsigned first, unsigned n) +{ + return bset_from_bmap(isl_basic_map_drop(bset_to_bmap(bset), + type, first, n)); +} + +/* No longer consider "map" to be normalized. + */ +static __isl_give isl_map *isl_map_unmark_normalized(__isl_take isl_map *map) +{ + if (!map) + return NULL; + ISL_F_CLR(map, ISL_MAP_NORMALIZED); + return map; +} + +__isl_give isl_map *isl_map_drop(__isl_take isl_map *map, + enum isl_dim_type type, unsigned first, unsigned n) +{ + int i; + isl_space *space; + + if (isl_map_check_range(map, type, first, n) < 0) + return isl_map_free(map); + + if (n == 0 && !isl_space_is_named_or_nested(map->dim, type)) + return map; + map = isl_map_cow(map); + if (!map) + goto error; + + for (i = 0; i < map->n; ++i) { + map->p[i] = isl_basic_map_drop(map->p[i], type, first, n); + if (!map->p[i]) + goto error; + } + map = isl_map_unmark_normalized(map); + + space = isl_map_take_space(map); + space = isl_space_drop_dims(space, type, first, n); + map = isl_map_restore_space(map, space); + + return map; +error: + isl_map_free(map); + return NULL; +} + +__isl_give isl_set *isl_set_drop(__isl_take isl_set *set, + enum isl_dim_type type, unsigned first, unsigned n) +{ + return set_from_map(isl_map_drop(set_to_map(set), type, first, n)); +} + +/* Drop the integer division at position "div", which is assumed + * not to appear in any of the constraints or + * in any of the other integer divisions. + * + * Since the integer division is redundant, there is no need to cow. + */ +__isl_give isl_basic_map *isl_basic_map_drop_div( + __isl_take isl_basic_map *bmap, unsigned div) +{ + return isl_basic_map_drop_core(bmap, isl_dim_div, div, 1); +} + +/* Eliminate the specified n dimensions starting at first from the + * constraints, without removing the dimensions from the space. + * If the set is rational, the dimensions are eliminated using Fourier-Motzkin. + */ +__isl_give isl_map *isl_map_eliminate(__isl_take isl_map *map, + enum isl_dim_type type, unsigned first, unsigned n) +{ + int i; + + if (n == 0) + return map; + + if (isl_map_check_range(map, type, first, n) < 0) + return isl_map_free(map); + + map = isl_map_cow(map); + if (!map) + return NULL; + + for (i = 0; i < map->n; ++i) { + map->p[i] = isl_basic_map_eliminate(map->p[i], type, first, n); + if (!map->p[i]) + goto error; + } + return map; +error: + isl_map_free(map); + return NULL; +} + +/* Eliminate the specified n dimensions starting at first from the + * constraints, without removing the dimensions from the space. + * If the set is rational, the dimensions are eliminated using Fourier-Motzkin. + */ +__isl_give isl_set *isl_set_eliminate(__isl_take isl_set *set, + enum isl_dim_type type, unsigned first, unsigned n) +{ + return set_from_map(isl_map_eliminate(set_to_map(set), type, first, n)); +} + +/* Eliminate the specified n dimensions starting at first from the + * constraints, without removing the dimensions from the space. + * If the set is rational, the dimensions are eliminated using Fourier-Motzkin. + */ +__isl_give isl_set *isl_set_eliminate_dims(__isl_take isl_set *set, + unsigned first, unsigned n) +{ + return isl_set_eliminate(set, isl_dim_set, first, n); +} + +__isl_give isl_basic_map *isl_basic_map_remove_divs( + __isl_take isl_basic_map *bmap) +{ + isl_size v_div; + + v_div = isl_basic_map_var_offset(bmap, isl_dim_div); + if (v_div < 0) + return isl_basic_map_free(bmap); + bmap = isl_basic_map_eliminate_vars(bmap, v_div, bmap->n_div); + if (!bmap) + return NULL; + bmap->n_div = 0; + return isl_basic_map_finalize(bmap); +} + +__isl_give isl_basic_set *isl_basic_set_remove_divs( + __isl_take isl_basic_set *bset) +{ + return bset_from_bmap(isl_basic_map_remove_divs(bset_to_bmap(bset))); +} + +__isl_give isl_map *isl_map_remove_divs(__isl_take isl_map *map) +{ + int i; + + if (!map) + return NULL; + if (map->n == 0) + return map; + + map = isl_map_cow(map); + if (!map) + return NULL; + + for (i = 0; i < map->n; ++i) { + map->p[i] = isl_basic_map_remove_divs(map->p[i]); + if (!map->p[i]) + goto error; + } + return map; +error: + isl_map_free(map); + return NULL; +} + +__isl_give isl_set *isl_set_remove_divs(__isl_take isl_set *set) +{ + return isl_map_remove_divs(set); +} + +__isl_give isl_basic_map *isl_basic_map_remove_dims( + __isl_take isl_basic_map *bmap, enum isl_dim_type type, + unsigned first, unsigned n) +{ + if (isl_basic_map_check_range(bmap, type, first, n) < 0) + return isl_basic_map_free(bmap); + if (n == 0 && !isl_space_is_named_or_nested(bmap->dim, type)) + return bmap; + bmap = isl_basic_map_eliminate_vars(bmap, + isl_basic_map_offset(bmap, type) - 1 + first, n); + if (!bmap) + return bmap; + if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_EMPTY) && type == isl_dim_div) + return bmap; + bmap = isl_basic_map_drop(bmap, type, first, n); + return bmap; +} + +/* Return true if the definition of the given div (recursively) involves + * any of the given variables. + */ +static isl_bool div_involves_vars(__isl_keep isl_basic_map *bmap, int div, + unsigned first, unsigned n) +{ + int i; + unsigned div_offset = isl_basic_map_offset(bmap, isl_dim_div); + + if (isl_int_is_zero(bmap->div[div][0])) + return isl_bool_false; + if (isl_seq_first_non_zero(bmap->div[div] + 1 + 1 + first, n) >= 0) + return isl_bool_true; + + for (i = bmap->n_div - 1; i >= 0; --i) { + isl_bool involves; + + if (isl_int_is_zero(bmap->div[div][1 + div_offset + i])) + continue; + involves = div_involves_vars(bmap, i, first, n); + if (involves < 0 || involves) + return involves; + } + + return isl_bool_false; +} + +/* Try and add a lower and/or upper bound on "div" to "bmap" + * based on inequality "i". + * "total" is the total number of variables (excluding the divs). + * "v" is a temporary object that can be used during the calculations. + * If "lb" is set, then a lower bound should be constructed. + * If "ub" is set, then an upper bound should be constructed. + * + * The calling function has already checked that the inequality does not + * reference "div", but we still need to check that the inequality is + * of the right form. We'll consider the case where we want to construct + * a lower bound. The construction of upper bounds is similar. + * + * Let "div" be of the form + * + * q = floor((a + f(x))/d) + * + * We essentially check if constraint "i" is of the form + * + * b + f(x) >= 0 + * + * so that we can use it to derive a lower bound on "div". + * However, we allow a slightly more general form + * + * b + g(x) >= 0 + * + * with the condition that the coefficients of g(x) - f(x) are all + * divisible by d. + * Rewriting this constraint as + * + * 0 >= -b - g(x) + * + * adding a + f(x) to both sides and dividing by d, we obtain + * + * (a + f(x))/d >= (a-b)/d + (f(x)-g(x))/d + * + * Taking the floor on both sides, we obtain + * + * q >= floor((a-b)/d) + (f(x)-g(x))/d + * + * or + * + * (g(x)-f(x))/d + ceil((b-a)/d) + q >= 0 + * + * In the case of an upper bound, we construct the constraint + * + * (g(x)+f(x))/d + floor((b+a)/d) - q >= 0 + * + */ +static __isl_give isl_basic_map *insert_bounds_on_div_from_ineq( + __isl_take isl_basic_map *bmap, int div, int i, + unsigned total, isl_int v, int lb, int ub) +{ + int j; + + for (j = 0; (lb || ub) && j < total + bmap->n_div; ++j) { + if (lb) { + isl_int_sub(v, bmap->ineq[i][1 + j], + bmap->div[div][1 + 1 + j]); + lb = isl_int_is_divisible_by(v, bmap->div[div][0]); + } + if (ub) { + isl_int_add(v, bmap->ineq[i][1 + j], + bmap->div[div][1 + 1 + j]); + ub = isl_int_is_divisible_by(v, bmap->div[div][0]); + } + } + if (!lb && !ub) + return bmap; + + bmap = isl_basic_map_cow(bmap); + bmap = isl_basic_map_extend_constraints(bmap, 0, lb + ub); + if (lb) { + int k = isl_basic_map_alloc_inequality(bmap); + if (k < 0) + goto error; + for (j = 0; j < 1 + total + bmap->n_div; ++j) { + isl_int_sub(bmap->ineq[k][j], bmap->ineq[i][j], + bmap->div[div][1 + j]); + isl_int_cdiv_q(bmap->ineq[k][j], + bmap->ineq[k][j], bmap->div[div][0]); + } + isl_int_set_si(bmap->ineq[k][1 + total + div], 1); + } + if (ub) { + int k = isl_basic_map_alloc_inequality(bmap); + if (k < 0) + goto error; + for (j = 0; j < 1 + total + bmap->n_div; ++j) { + isl_int_add(bmap->ineq[k][j], bmap->ineq[i][j], + bmap->div[div][1 + j]); + isl_int_fdiv_q(bmap->ineq[k][j], + bmap->ineq[k][j], bmap->div[div][0]); + } + isl_int_set_si(bmap->ineq[k][1 + total + div], -1); + } + + return bmap; +error: + isl_basic_map_free(bmap); + return NULL; +} + +/* This function is called right before "div" is eliminated from "bmap" + * using Fourier-Motzkin. + * Look through the constraints of "bmap" for constraints on the argument + * of the integer division and use them to construct constraints on the + * integer division itself. These constraints can then be combined + * during the Fourier-Motzkin elimination. + * Note that it is only useful to introduce lower bounds on "div" + * if "bmap" already contains upper bounds on "div" as the newly + * introduce lower bounds can then be combined with the pre-existing + * upper bounds. Similarly for upper bounds. + * We therefore first check if "bmap" contains any lower and/or upper bounds + * on "div". + * + * It is interesting to note that the introduction of these constraints + * can indeed lead to more accurate results, even when compared to + * deriving constraints on the argument of "div" from constraints on "div". + * Consider, for example, the set + * + * { [i,j,k] : 3 + i + 2j >= 0 and 2 * [(i+2j)/4] <= k } + * + * The second constraint can be rewritten as + * + * 2 * [(-i-2j+3)/4] + k >= 0 + * + * from which we can derive + * + * -i - 2j + 3 >= -2k + * + * or + * + * i + 2j <= 3 + 2k + * + * Combined with the first constraint, we obtain + * + * -3 <= 3 + 2k or k >= -3 + * + * If, on the other hand we derive a constraint on [(i+2j)/4] from + * the first constraint, we obtain + * + * [(i + 2j)/4] >= [-3/4] = -1 + * + * Combining this constraint with the second constraint, we obtain + * + * k >= -2 + */ +static __isl_give isl_basic_map *insert_bounds_on_div( + __isl_take isl_basic_map *bmap, int div) +{ + int i; + int check_lb, check_ub; + isl_int v; + isl_size v_div; + + if (!bmap) + return NULL; + + if (isl_int_is_zero(bmap->div[div][0])) + return bmap; + + v_div = isl_basic_map_var_offset(bmap, isl_dim_div); + if (v_div < 0) + return isl_basic_map_free(bmap); + + check_lb = 0; + check_ub = 0; + for (i = 0; (!check_lb || !check_ub) && i < bmap->n_ineq; ++i) { + int s = isl_int_sgn(bmap->ineq[i][1 + v_div + div]); + if (s > 0) + check_ub = 1; + if (s < 0) + check_lb = 1; + } + + if (!check_lb && !check_ub) + return bmap; + + isl_int_init(v); + + for (i = 0; bmap && i < bmap->n_ineq; ++i) { + if (!isl_int_is_zero(bmap->ineq[i][1 + v_div + div])) + continue; + + bmap = insert_bounds_on_div_from_ineq(bmap, div, i, v_div, v, + check_lb, check_ub); + } + + isl_int_clear(v); + + return bmap; +} + +/* Remove all divs (recursively) involving any of the given dimensions + * in their definitions. + */ +__isl_give isl_basic_map *isl_basic_map_remove_divs_involving_dims( + __isl_take isl_basic_map *bmap, + enum isl_dim_type type, unsigned first, unsigned n) +{ + int i; + isl_size off; + + if (isl_basic_map_check_range(bmap, type, first, n) < 0) + return isl_basic_map_free(bmap); + off = isl_basic_map_var_offset(bmap, type); + if (off < 0) + return isl_basic_map_free(bmap); + first += off; + + for (i = bmap->n_div - 1; i >= 0; --i) { + isl_bool involves; + + involves = div_involves_vars(bmap, i, first, n); + if (involves < 0) + return isl_basic_map_free(bmap); + if (!involves) + continue; + bmap = insert_bounds_on_div(bmap, i); + bmap = isl_basic_map_remove_dims(bmap, isl_dim_div, i, 1); + if (!bmap) + return NULL; + i = bmap->n_div; + } + + return bmap; +} + +__isl_give isl_basic_set *isl_basic_set_remove_divs_involving_dims( + __isl_take isl_basic_set *bset, + enum isl_dim_type type, unsigned first, unsigned n) +{ + return isl_basic_map_remove_divs_involving_dims(bset, type, first, n); +} + +__isl_give isl_map *isl_map_remove_divs_involving_dims(__isl_take isl_map *map, + enum isl_dim_type type, unsigned first, unsigned n) +{ + int i; + + if (!map) + return NULL; + if (map->n == 0) + return map; + + map = isl_map_cow(map); + if (!map) + return NULL; + + for (i = 0; i < map->n; ++i) { + map->p[i] = isl_basic_map_remove_divs_involving_dims(map->p[i], + type, first, n); + if (!map->p[i]) + goto error; + } + return map; +error: + isl_map_free(map); + return NULL; +} + +__isl_give isl_set *isl_set_remove_divs_involving_dims(__isl_take isl_set *set, + enum isl_dim_type type, unsigned first, unsigned n) +{ + return set_from_map(isl_map_remove_divs_involving_dims(set_to_map(set), + type, first, n)); +} + +/* Does the description of "bmap" depend on the specified dimensions? + * We also check whether the dimensions appear in any of the div definitions. + * In principle there is no need for this check. If the dimensions appear + * in a div definition, they also appear in the defining constraints of that + * div. + */ +isl_bool isl_basic_map_involves_dims(__isl_keep isl_basic_map *bmap, + enum isl_dim_type type, unsigned first, unsigned n) +{ + int i; + + if (isl_basic_map_check_range(bmap, type, first, n) < 0) + return isl_bool_error; + + first += isl_basic_map_offset(bmap, type); + for (i = 0; i < bmap->n_eq; ++i) + if (isl_seq_first_non_zero(bmap->eq[i] + first, n) >= 0) + return isl_bool_true; + for (i = 0; i < bmap->n_ineq; ++i) + if (isl_seq_first_non_zero(bmap->ineq[i] + first, n) >= 0) + return isl_bool_true; + for (i = 0; i < bmap->n_div; ++i) { + if (isl_int_is_zero(bmap->div[i][0])) + continue; + if (isl_seq_first_non_zero(bmap->div[i] + 1 + first, n) >= 0) + return isl_bool_true; + } + + return isl_bool_false; +} + +isl_bool isl_map_involves_dims(__isl_keep isl_map *map, + enum isl_dim_type type, unsigned first, unsigned n) +{ + int i; + + if (isl_map_check_range(map, type, first, n) < 0) + return isl_bool_error; + + for (i = 0; i < map->n; ++i) { + isl_bool involves = isl_basic_map_involves_dims(map->p[i], + type, first, n); + if (involves < 0 || involves) + return involves; + } + + return isl_bool_false; +} + +isl_bool isl_basic_set_involves_dims(__isl_keep isl_basic_set *bset, + enum isl_dim_type type, unsigned first, unsigned n) +{ + return isl_basic_map_involves_dims(bset, type, first, n); +} + +isl_bool isl_set_involves_dims(__isl_keep isl_set *set, + enum isl_dim_type type, unsigned first, unsigned n) +{ + return isl_map_involves_dims(set, type, first, n); +} + +/* Does "bset" involve any local variables, i.e., integer divisions? + */ +static isl_bool isl_basic_set_involves_locals(__isl_keep isl_basic_set *bset) +{ + isl_size n; + + n = isl_basic_set_dim(bset, isl_dim_div); + if (n < 0) + return isl_bool_error; + return isl_bool_ok(n > 0); +} + +/* isl_set_every_basic_set callback that checks whether "bset" + * is free of local variables. + */ +static isl_bool basic_set_no_locals(__isl_keep isl_basic_set *bset, void *user) +{ + return isl_bool_not(isl_basic_set_involves_locals(bset)); +} + +/* Does "set" involve any local variables, i.e., integer divisions? + */ +isl_bool isl_set_involves_locals(__isl_keep isl_set *set) +{ + isl_bool no_locals; + + no_locals = isl_set_every_basic_set(set, &basic_set_no_locals, NULL); + return isl_bool_not(no_locals); +} + +/* Drop all constraints in bmap that involve any of the dimensions + * first to first+n-1. + * This function only performs the actual removal of constraints. + * + * This function should not call finalize since it is used by + * remove_redundant_divs, which in turn is called by isl_basic_map_finalize. + */ +__isl_give isl_basic_map *isl_basic_map_drop_constraints_involving( + __isl_take isl_basic_map *bmap, unsigned first, unsigned n) +{ + int i; + + if (n == 0) + return bmap; + + bmap = isl_basic_map_cow(bmap); + + if (!bmap) + return NULL; + + for (i = bmap->n_eq - 1; i >= 0; --i) { + if (isl_seq_first_non_zero(bmap->eq[i] + 1 + first, n) == -1) + continue; + if (isl_basic_map_drop_equality(bmap, i) < 0) + return isl_basic_map_free(bmap); + } + + for (i = bmap->n_ineq - 1; i >= 0; --i) { + if (isl_seq_first_non_zero(bmap->ineq[i] + 1 + first, n) == -1) + continue; + if (isl_basic_map_drop_inequality(bmap, i) < 0) + return isl_basic_map_free(bmap); + } + + return bmap; +} + +/* Drop all constraints in bset that involve any of the dimensions + * first to first+n-1. + * This function only performs the actual removal of constraints. + */ +__isl_give isl_basic_set *isl_basic_set_drop_constraints_involving( + __isl_take isl_basic_set *bset, unsigned first, unsigned n) +{ + return isl_basic_map_drop_constraints_involving(bset, first, n); +} + +/* Drop all constraints in bmap that do not involve any of the dimensions + * first to first + n - 1 of the given type. + */ +__isl_give isl_basic_map *isl_basic_map_drop_constraints_not_involving_dims( + __isl_take isl_basic_map *bmap, + enum isl_dim_type type, unsigned first, unsigned n) +{ + int i; + + if (n == 0) { + isl_space *space = isl_basic_map_get_space(bmap); + isl_basic_map_free(bmap); + return isl_basic_map_universe(space); + } + bmap = isl_basic_map_cow(bmap); + if (!bmap) + return NULL; + + if (isl_basic_map_check_range(bmap, type, first, n) < 0) + return isl_basic_map_free(bmap); + + first += isl_basic_map_offset(bmap, type) - 1; + + for (i = bmap->n_eq - 1; i >= 0; --i) { + if (isl_seq_first_non_zero(bmap->eq[i] + 1 + first, n) != -1) + continue; + if (isl_basic_map_drop_equality(bmap, i) < 0) + return isl_basic_map_free(bmap); + } + + for (i = bmap->n_ineq - 1; i >= 0; --i) { + if (isl_seq_first_non_zero(bmap->ineq[i] + 1 + first, n) != -1) + continue; + if (isl_basic_map_drop_inequality(bmap, i) < 0) + return isl_basic_map_free(bmap); + } + + bmap = isl_basic_map_add_known_div_constraints(bmap); + return bmap; +} + +/* Drop all constraints in bset that do not involve any of the dimensions + * first to first + n - 1 of the given type. + */ +__isl_give isl_basic_set *isl_basic_set_drop_constraints_not_involving_dims( + __isl_take isl_basic_set *bset, + enum isl_dim_type type, unsigned first, unsigned n) +{ + return isl_basic_map_drop_constraints_not_involving_dims(bset, + type, first, n); +} + +/* Drop all constraints in bmap that involve any of the dimensions + * first to first + n - 1 of the given type. + */ +__isl_give isl_basic_map *isl_basic_map_drop_constraints_involving_dims( + __isl_take isl_basic_map *bmap, + enum isl_dim_type type, unsigned first, unsigned n) +{ + if (!bmap) + return NULL; + if (n == 0) + return bmap; + + if (isl_basic_map_check_range(bmap, type, first, n) < 0) + return isl_basic_map_free(bmap); + + bmap = isl_basic_map_remove_divs_involving_dims(bmap, type, first, n); + first += isl_basic_map_offset(bmap, type) - 1; + bmap = isl_basic_map_drop_constraints_involving(bmap, first, n); + bmap = isl_basic_map_add_known_div_constraints(bmap); + return bmap; +} + +/* Drop all constraints in bset that involve any of the dimensions + * first to first + n - 1 of the given type. + */ +__isl_give isl_basic_set *isl_basic_set_drop_constraints_involving_dims( + __isl_take isl_basic_set *bset, + enum isl_dim_type type, unsigned first, unsigned n) +{ + return isl_basic_map_drop_constraints_involving_dims(bset, + type, first, n); +} + +/* Drop constraints from "map" by applying "drop" to each basic map. + */ +static __isl_give isl_map *drop_constraints(__isl_take isl_map *map, + enum isl_dim_type type, unsigned first, unsigned n, + __isl_give isl_basic_map *(*drop)(__isl_take isl_basic_map *bmap, + enum isl_dim_type type, unsigned first, unsigned n)) +{ + int i; + + if (isl_map_check_range(map, type, first, n) < 0) + return isl_map_free(map); + + map = isl_map_cow(map); + if (!map) + return NULL; + + for (i = 0; i < map->n; ++i) { + map->p[i] = drop(map->p[i], type, first, n); + if (!map->p[i]) + return isl_map_free(map); + } + + if (map->n > 1) + ISL_F_CLR(map, ISL_MAP_DISJOINT); + + return map; +} + +/* Drop all constraints in map that involve any of the dimensions + * first to first + n - 1 of the given type. + */ +__isl_give isl_map *isl_map_drop_constraints_involving_dims( + __isl_take isl_map *map, + enum isl_dim_type type, unsigned first, unsigned n) +{ + if (n == 0) + return map; + return drop_constraints(map, type, first, n, + &isl_basic_map_drop_constraints_involving_dims); +} + +/* Drop all constraints in "map" that do not involve any of the dimensions + * first to first + n - 1 of the given type. + */ +__isl_give isl_map *isl_map_drop_constraints_not_involving_dims( + __isl_take isl_map *map, + enum isl_dim_type type, unsigned first, unsigned n) +{ + if (n == 0) { + isl_space *space = isl_map_get_space(map); + isl_map_free(map); + return isl_map_universe(space); + } + return drop_constraints(map, type, first, n, + &isl_basic_map_drop_constraints_not_involving_dims); +} + +/* Drop all constraints in set that involve any of the dimensions + * first to first + n - 1 of the given type. + */ +__isl_give isl_set *isl_set_drop_constraints_involving_dims( + __isl_take isl_set *set, + enum isl_dim_type type, unsigned first, unsigned n) +{ + return isl_map_drop_constraints_involving_dims(set, type, first, n); +} + +/* Drop all constraints in "set" that do not involve any of the dimensions + * first to first + n - 1 of the given type. + */ +__isl_give isl_set *isl_set_drop_constraints_not_involving_dims( + __isl_take isl_set *set, + enum isl_dim_type type, unsigned first, unsigned n) +{ + return isl_map_drop_constraints_not_involving_dims(set, type, first, n); +} + +/* Does local variable "div" of "bmap" have a complete explicit representation? + * Having a complete explicit representation requires not only + * an explicit representation, but also that all local variables + * that appear in this explicit representation in turn have + * a complete explicit representation. + */ +isl_bool isl_basic_map_div_is_known(__isl_keep isl_basic_map *bmap, int div) +{ + int i; + unsigned div_offset = isl_basic_map_offset(bmap, isl_dim_div); + isl_bool marked; + + marked = isl_basic_map_div_is_marked_unknown(bmap, div); + if (marked < 0 || marked) + return isl_bool_not(marked); + + for (i = bmap->n_div - 1; i >= 0; --i) { + isl_bool known; + + if (isl_int_is_zero(bmap->div[div][1 + div_offset + i])) + continue; + known = isl_basic_map_div_is_known(bmap, i); + if (known < 0 || !known) + return known; + } + + return isl_bool_true; +} + +/* Remove all divs that are unknown or defined in terms of unknown divs. + */ +__isl_give isl_basic_map *isl_basic_map_remove_unknown_divs( + __isl_take isl_basic_map *bmap) +{ + int i; + + if (!bmap) + return NULL; + + for (i = bmap->n_div - 1; i >= 0; --i) { + if (isl_basic_map_div_is_known(bmap, i)) + continue; + bmap = isl_basic_map_remove_dims(bmap, isl_dim_div, i, 1); + if (!bmap) + return NULL; + i = bmap->n_div; + } + + return bmap; +} + +/* Remove all divs that are unknown or defined in terms of unknown divs. + */ +__isl_give isl_basic_set *isl_basic_set_remove_unknown_divs( + __isl_take isl_basic_set *bset) +{ + return isl_basic_map_remove_unknown_divs(bset); +} + +__isl_give isl_map *isl_map_remove_unknown_divs(__isl_take isl_map *map) +{ + int i; + + if (!map) + return NULL; + if (map->n == 0) + return map; + + map = isl_map_cow(map); + if (!map) + return NULL; + + for (i = 0; i < map->n; ++i) { + map->p[i] = isl_basic_map_remove_unknown_divs(map->p[i]); + if (!map->p[i]) + goto error; + } + return map; +error: + isl_map_free(map); + return NULL; +} + +__isl_give isl_set *isl_set_remove_unknown_divs(__isl_take isl_set *set) +{ + return set_from_map(isl_map_remove_unknown_divs(set_to_map(set))); +} + +__isl_give isl_basic_set *isl_basic_set_remove_dims( + __isl_take isl_basic_set *bset, + enum isl_dim_type type, unsigned first, unsigned n) +{ + isl_basic_map *bmap = bset_to_bmap(bset); + bmap = isl_basic_map_remove_dims(bmap, type, first, n); + return bset_from_bmap(bmap); +} + +__isl_give isl_map *isl_map_remove_dims(__isl_take isl_map *map, + enum isl_dim_type type, unsigned first, unsigned n) +{ + int i; + + if (n == 0) + return map; + + map = isl_map_cow(map); + if (isl_map_check_range(map, type, first, n) < 0) + return isl_map_free(map); + + for (i = 0; i < map->n; ++i) { + map->p[i] = isl_basic_map_eliminate_vars(map->p[i], + isl_basic_map_offset(map->p[i], type) - 1 + first, n); + if (!map->p[i]) + goto error; + } + map = isl_map_drop(map, type, first, n); + return map; +error: + isl_map_free(map); + return NULL; +} + +__isl_give isl_set *isl_set_remove_dims(__isl_take isl_set *bset, + enum isl_dim_type type, unsigned first, unsigned n) +{ + return set_from_map(isl_map_remove_dims(set_to_map(bset), + type, first, n)); +} + +/* Project out n inputs starting at first using Fourier-Motzkin */ +__isl_give isl_map *isl_map_remove_inputs(__isl_take isl_map *map, + unsigned first, unsigned n) +{ + return isl_map_remove_dims(map, isl_dim_in, first, n); +} + +void isl_basic_set_print_internal(__isl_keep isl_basic_set *bset, + FILE *out, int indent) +{ + isl_printer *p; + + if (!bset) { + fprintf(out, "null basic set\n"); + return; + } + + fprintf(out, "%*s", indent, ""); + fprintf(out, "ref: %d, nparam: %d, dim: %d, extra: %d, flags: %x\n", + bset->ref, bset->dim->nparam, bset->dim->n_out, + bset->extra, bset->flags); + + p = isl_printer_to_file(isl_basic_set_get_ctx(bset), out); + p = isl_printer_set_dump(p, 1); + p = isl_printer_set_indent(p, indent); + p = isl_printer_start_line(p); + p = isl_printer_print_basic_set(p, bset); + p = isl_printer_end_line(p); + isl_printer_free(p); +} + +void isl_basic_map_print_internal(__isl_keep isl_basic_map *bmap, + FILE *out, int indent) +{ + isl_printer *p; + + if (!bmap) { + fprintf(out, "null basic map\n"); + return; + } + + fprintf(out, "%*s", indent, ""); + fprintf(out, "ref: %d, nparam: %d, in: %d, out: %d, extra: %d, " + "flags: %x, n_name: %d\n", + bmap->ref, + bmap->dim->nparam, bmap->dim->n_in, bmap->dim->n_out, + bmap->extra, bmap->flags, bmap->dim->n_id); + + p = isl_printer_to_file(isl_basic_map_get_ctx(bmap), out); + p = isl_printer_set_dump(p, 1); + p = isl_printer_set_indent(p, indent); + p = isl_printer_start_line(p); + p = isl_printer_print_basic_map(p, bmap); + p = isl_printer_end_line(p); + isl_printer_free(p); +} + +__isl_give isl_basic_map *isl_inequality_negate(__isl_take isl_basic_map *bmap, + unsigned pos) +{ + isl_size total; + + total = isl_basic_map_dim(bmap, isl_dim_all); + if (total < 0) + return isl_basic_map_free(bmap); + if (pos >= bmap->n_ineq) + isl_die(isl_basic_map_get_ctx(bmap), isl_error_invalid, + "invalid position", return isl_basic_map_free(bmap)); + isl_seq_neg(bmap->ineq[pos], bmap->ineq[pos], 1 + total); + isl_int_sub_ui(bmap->ineq[pos][0], bmap->ineq[pos][0], 1); + ISL_F_CLR(bmap, ISL_BASIC_MAP_NO_REDUNDANT); + ISL_F_CLR(bmap, ISL_BASIC_MAP_SORTED); + return bmap; +} + +__isl_give isl_set *isl_set_alloc_space(__isl_take isl_space *space, int n, + unsigned flags) +{ + if (isl_space_check_is_set(space) < 0) + goto error; + return isl_map_alloc_space(space, n, flags); +error: + isl_space_free(space); + return NULL; +} + +/* Make sure "map" has room for at least "n" more basic maps. + */ +__isl_give isl_map *isl_map_grow(__isl_take isl_map *map, int n) +{ + int i; + struct isl_map *grown = NULL; + + if (!map) + return NULL; + isl_assert(map->ctx, n >= 0, goto error); + if (map->n + n <= map->size) + return map; + grown = isl_map_alloc_space(isl_map_get_space(map), map->n + n, map->flags); + if (!grown) + goto error; + for (i = 0; i < map->n; ++i) { + grown->p[i] = isl_basic_map_copy(map->p[i]); + if (!grown->p[i]) + goto error; + grown->n++; + } + isl_map_free(map); + return grown; +error: + isl_map_free(grown); + isl_map_free(map); + return NULL; +} + +/* Make sure "set" has room for at least "n" more basic sets. + */ +__isl_give isl_set *isl_set_grow(__isl_take isl_set *set, int n) +{ + return set_from_map(isl_map_grow(set_to_map(set), n)); +} + +__isl_give isl_set *isl_set_from_basic_set(__isl_take isl_basic_set *bset) +{ + return isl_map_from_basic_map(bset); +} + +/* This function performs the same operation as isl_set_from_basic_set, + * but is considered as a function on an isl_basic_set when exported. + */ +__isl_give isl_set *isl_basic_set_to_set(__isl_take isl_basic_set *bset) +{ + return isl_set_from_basic_set(bset); +} + +__isl_give isl_map *isl_map_from_basic_map(__isl_take isl_basic_map *bmap) +{ + struct isl_map *map; + + if (!bmap) + return NULL; + + map = isl_map_alloc_space(isl_space_copy(bmap->dim), 1, ISL_MAP_DISJOINT); + return isl_map_add_basic_map(map, bmap); +} + +__isl_give isl_set *isl_set_add_basic_set(__isl_take isl_set *set, + __isl_take isl_basic_set *bset) +{ + return set_from_map(isl_map_add_basic_map(set_to_map(set), + bset_to_bmap(bset))); +} + +__isl_null isl_set *isl_set_free(__isl_take isl_set *set) +{ + return isl_map_free(set); +} + +void isl_set_print_internal(__isl_keep isl_set *set, FILE *out, int indent) +{ + int i; + + if (!set) { + fprintf(out, "null set\n"); + return; + } + + fprintf(out, "%*s", indent, ""); + fprintf(out, "ref: %d, n: %d, nparam: %d, dim: %d, flags: %x\n", + set->ref, set->n, set->dim->nparam, set->dim->n_out, + set->flags); + for (i = 0; i < set->n; ++i) { + fprintf(out, "%*s", indent, ""); + fprintf(out, "basic set %d:\n", i); + isl_basic_set_print_internal(set->p[i], out, indent+4); + } +} + +void isl_map_print_internal(__isl_keep isl_map *map, FILE *out, int indent) +{ + int i; + + if (!map) { + fprintf(out, "null map\n"); + return; + } + + fprintf(out, "%*s", indent, ""); + fprintf(out, "ref: %d, n: %d, nparam: %d, in: %d, out: %d, " + "flags: %x, n_name: %d\n", + map->ref, map->n, map->dim->nparam, map->dim->n_in, + map->dim->n_out, map->flags, map->dim->n_id); + for (i = 0; i < map->n; ++i) { + fprintf(out, "%*s", indent, ""); + fprintf(out, "basic map %d:\n", i); + isl_basic_map_print_internal(map->p[i], out, indent+4); + } +} + +/* Check that the space of "bset" is the same as that of the domain of "bmap". + */ +static isl_stat isl_basic_map_check_compatible_domain( + __isl_keep isl_basic_map *bmap, __isl_keep isl_basic_set *bset) +{ + isl_bool ok; + + ok = isl_basic_map_compatible_domain(bmap, bset); + if (ok < 0) + return isl_stat_error; + if (!ok) + isl_die(isl_basic_set_get_ctx(bset), isl_error_invalid, + "incompatible spaces", return isl_stat_error); + + return isl_stat_ok; +} + +__isl_give isl_basic_map *isl_basic_map_intersect_domain( + __isl_take isl_basic_map *bmap, __isl_take isl_basic_set *bset) +{ + struct isl_basic_map *bmap_domain; + isl_size dim; + + if (isl_basic_map_check_equal_params(bmap, bset_to_bmap(bset)) < 0) + goto error; + + dim = isl_basic_set_dim(bset, isl_dim_set); + if (dim < 0) + goto error; + if (dim != 0 && + isl_basic_map_check_compatible_domain(bmap, bset) < 0) + goto error; + + bmap = isl_basic_map_cow(bmap); + if (!bmap) + goto error; + bmap = isl_basic_map_extend(bmap, + bset->n_div, bset->n_eq, bset->n_ineq); + bmap_domain = isl_basic_map_from_domain(bset); + bmap = add_constraints(bmap, bmap_domain, 0, 0); + + bmap = isl_basic_map_simplify(bmap); + return isl_basic_map_finalize(bmap); +error: + isl_basic_map_free(bmap); + isl_basic_set_free(bset); + return NULL; +} + +/* Check that the space of "bset" is the same as that of the range of "bmap". + */ +static isl_stat isl_basic_map_check_compatible_range( + __isl_keep isl_basic_map *bmap, __isl_keep isl_basic_set *bset) +{ + isl_bool ok; + + ok = isl_basic_map_compatible_range(bmap, bset); + if (ok < 0) + return isl_stat_error; + if (!ok) + isl_die(isl_basic_set_get_ctx(bset), isl_error_invalid, + "incompatible spaces", return isl_stat_error); + + return isl_stat_ok; +} + +__isl_give isl_basic_map *isl_basic_map_intersect_range( + __isl_take isl_basic_map *bmap, __isl_take isl_basic_set *bset) +{ + struct isl_basic_map *bmap_range; + isl_size dim; + + if (isl_basic_map_check_equal_params(bmap, bset_to_bmap(bset)) < 0) + goto error; + + dim = isl_basic_set_dim(bset, isl_dim_set); + if (dim < 0) + goto error; + if (dim != 0 && isl_basic_map_check_compatible_range(bmap, bset) < 0) + goto error; + + if (isl_basic_set_plain_is_universe(bset)) { + isl_basic_set_free(bset); + return bmap; + } + + bmap = isl_basic_map_cow(bmap); + if (!bmap) + goto error; + bmap = isl_basic_map_extend(bmap, + bset->n_div, bset->n_eq, bset->n_ineq); + bmap_range = bset_to_bmap(bset); + bmap = add_constraints(bmap, bmap_range, 0, 0); + + bmap = isl_basic_map_simplify(bmap); + return isl_basic_map_finalize(bmap); +error: + isl_basic_map_free(bmap); + isl_basic_set_free(bset); + return NULL; +} + +isl_bool isl_basic_map_contains(__isl_keep isl_basic_map *bmap, + __isl_keep isl_vec *vec) +{ + int i; + isl_size total; + isl_int s; + + total = isl_basic_map_dim(bmap, isl_dim_all); + if (total < 0 || !vec) + return isl_bool_error; + + if (1 + total != vec->size) + return isl_bool_false; + + isl_int_init(s); + + for (i = 0; i < bmap->n_eq; ++i) { + isl_seq_inner_product(vec->el, bmap->eq[i], 1 + total, &s); + if (!isl_int_is_zero(s)) { + isl_int_clear(s); + return isl_bool_false; + } + } + + for (i = 0; i < bmap->n_ineq; ++i) { + isl_seq_inner_product(vec->el, bmap->ineq[i], 1 + total, &s); + if (isl_int_is_neg(s)) { + isl_int_clear(s); + return isl_bool_false; + } + } + + isl_int_clear(s); + + return isl_bool_true; +} + +isl_bool isl_basic_set_contains(__isl_keep isl_basic_set *bset, + __isl_keep isl_vec *vec) +{ + return isl_basic_map_contains(bset_to_bmap(bset), vec); +} + +__isl_give isl_basic_map *isl_basic_map_intersect( + __isl_take isl_basic_map *bmap1, __isl_take isl_basic_map *bmap2) +{ + struct isl_vec *sample = NULL; + isl_space *space1, *space2; + isl_size dim1, dim2, nparam1, nparam2; + + if (isl_basic_map_check_equal_params(bmap1, bmap2) < 0) + goto error; + space1 = isl_basic_map_peek_space(bmap1); + space2 = isl_basic_map_peek_space(bmap2); + dim1 = isl_space_dim(space1, isl_dim_all); + dim2 = isl_space_dim(space2, isl_dim_all); + nparam1 = isl_space_dim(space1, isl_dim_param); + nparam2 = isl_space_dim(space2, isl_dim_param); + if (dim1 < 0 || dim2 < 0 || nparam1 < 0 || nparam2 < 0) + goto error; + if (dim1 == nparam1 && dim2 != nparam2) + return isl_basic_map_intersect(bmap2, bmap1); + + if (dim2 != nparam2 && + isl_basic_map_check_equal_space(bmap1, bmap2) < 0) + goto error; + + if (isl_basic_map_plain_is_empty(bmap1)) { + isl_basic_map_free(bmap2); + return bmap1; + } + if (isl_basic_map_plain_is_empty(bmap2)) { + isl_basic_map_free(bmap1); + return bmap2; + } + + if (bmap1->sample && + isl_basic_map_contains(bmap1, bmap1->sample) > 0 && + isl_basic_map_contains(bmap2, bmap1->sample) > 0) + sample = isl_vec_copy(bmap1->sample); + else if (bmap2->sample && + isl_basic_map_contains(bmap1, bmap2->sample) > 0 && + isl_basic_map_contains(bmap2, bmap2->sample) > 0) + sample = isl_vec_copy(bmap2->sample); + + bmap1 = isl_basic_map_cow(bmap1); + if (!bmap1) + goto error; + bmap1 = isl_basic_map_extend(bmap1, + bmap2->n_div, bmap2->n_eq, bmap2->n_ineq); + bmap1 = add_constraints(bmap1, bmap2, 0, 0); + + if (!bmap1) + isl_vec_free(sample); + else if (sample) { + isl_vec_free(bmap1->sample); + bmap1->sample = sample; + } + + bmap1 = isl_basic_map_simplify(bmap1); + return isl_basic_map_finalize(bmap1); +error: + if (sample) + isl_vec_free(sample); + isl_basic_map_free(bmap1); + isl_basic_map_free(bmap2); + return NULL; +} + +__isl_give isl_basic_set *isl_basic_set_intersect( + __isl_take isl_basic_set *bset1, __isl_take isl_basic_set *bset2) +{ + return bset_from_bmap(isl_basic_map_intersect(bset_to_bmap(bset1), + bset_to_bmap(bset2))); +} + +__isl_give isl_basic_set *isl_basic_set_intersect_params( + __isl_take isl_basic_set *bset1, __isl_take isl_basic_set *bset2) +{ + return isl_basic_set_intersect(bset1, bset2); +} + +/* Does "map" consist of a single disjunct, without any local variables? + */ +static isl_bool is_convex_no_locals(__isl_keep isl_map *map) +{ + isl_size n_div; + + if (!map) + return isl_bool_error; + if (map->n != 1) + return isl_bool_false; + n_div = isl_basic_map_dim(map->p[0], isl_dim_div); + if (n_div < 0) + return isl_bool_error; + if (n_div != 0) + return isl_bool_false; + return isl_bool_true; +} + +/* Check that "map" consists of a single disjunct, without any local variables. + */ +static isl_stat check_convex_no_locals(__isl_keep isl_map *map) +{ + isl_bool ok; + + ok = is_convex_no_locals(map); + if (ok < 0) + return isl_stat_error; + if (ok) + return isl_stat_ok; + + isl_die(isl_map_get_ctx(map), isl_error_internal, + "unexpectedly not convex or involving local variables", + return isl_stat_error); +} + +/* Special case of isl_map_intersect, where both map1 and map2 + * are convex, without any divs and such that either map1 or map2 + * contains a single constraint. This constraint is then simply + * added to the other map. + */ +static __isl_give isl_map *map_intersect_add_constraint( + __isl_take isl_map *map1, __isl_take isl_map *map2) +{ + if (check_convex_no_locals(map1) < 0 || + check_convex_no_locals(map2) < 0) + goto error; + + if (map2->p[0]->n_eq + map2->p[0]->n_ineq != 1) + return isl_map_intersect(map2, map1); + + map1 = isl_map_cow(map1); + if (!map1) + goto error; + if (isl_map_plain_is_empty(map1)) { + isl_map_free(map2); + return map1; + } + if (map2->p[0]->n_eq == 1) + map1->p[0] = isl_basic_map_add_eq(map1->p[0], map2->p[0]->eq[0]); + else + map1->p[0] = isl_basic_map_add_ineq(map1->p[0], + map2->p[0]->ineq[0]); + + map1->p[0] = isl_basic_map_simplify(map1->p[0]); + map1->p[0] = isl_basic_map_finalize(map1->p[0]); + if (!map1->p[0]) + goto error; + + if (isl_basic_map_plain_is_empty(map1->p[0])) { + isl_basic_map_free(map1->p[0]); + map1->n = 0; + } + + isl_map_free(map2); + + map1 = isl_map_unmark_normalized(map1); + return map1; +error: + isl_map_free(map1); + isl_map_free(map2); + return NULL; +} + +/* map2 may be either a parameter domain or a map living in the same + * space as map1. + */ +static __isl_give isl_map *map_intersect_internal(__isl_take isl_map *map1, + __isl_take isl_map *map2) +{ + unsigned flags = 0; + isl_bool equal; + isl_map *result; + int i, j; + isl_size dim2, nparam2; + + if (!map1 || !map2) + goto error; + + if ((isl_map_plain_is_empty(map1) || + isl_map_plain_is_universe(map2)) && + isl_space_is_equal(map1->dim, map2->dim)) { + isl_map_free(map2); + return map1; + } + if ((isl_map_plain_is_empty(map2) || + isl_map_plain_is_universe(map1)) && + isl_space_is_equal(map1->dim, map2->dim)) { + isl_map_free(map1); + return map2; + } + + if (is_convex_no_locals(map1) == isl_bool_true && + is_convex_no_locals(map2) == isl_bool_true && + isl_space_is_equal(map1->dim, map2->dim) && + (map1->p[0]->n_eq + map1->p[0]->n_ineq == 1 || + map2->p[0]->n_eq + map2->p[0]->n_ineq == 1)) + return map_intersect_add_constraint(map1, map2); + + equal = isl_map_plain_is_equal(map1, map2); + if (equal < 0) + goto error; + if (equal) { + isl_map_free(map2); + return map1; + } + + dim2 = isl_map_dim(map2, isl_dim_all); + nparam2 = isl_map_dim(map2, isl_dim_param); + if (dim2 < 0 || nparam2 < 0) + goto error; + if (dim2 != nparam2) + isl_assert(map1->ctx, + isl_space_is_equal(map1->dim, map2->dim), goto error); + + if (ISL_F_ISSET(map1, ISL_MAP_DISJOINT) && + ISL_F_ISSET(map2, ISL_MAP_DISJOINT)) + ISL_FL_SET(flags, ISL_MAP_DISJOINT); + + result = isl_map_alloc_space(isl_space_copy(map1->dim), + map1->n * map2->n, flags); + if (!result) + goto error; + for (i = 0; i < map1->n; ++i) + for (j = 0; j < map2->n; ++j) { + struct isl_basic_map *part; + part = isl_basic_map_intersect( + isl_basic_map_copy(map1->p[i]), + isl_basic_map_copy(map2->p[j])); + if (isl_basic_map_is_empty(part) < 0) + part = isl_basic_map_free(part); + result = isl_map_add_basic_map(result, part); + if (!result) + goto error; + } + isl_map_free(map1); + isl_map_free(map2); + return result; +error: + isl_map_free(map1); + isl_map_free(map2); + return NULL; +} + +static __isl_give isl_map *map_intersect(__isl_take isl_map *map1, + __isl_take isl_map *map2) +{ + if (isl_map_check_equal_space(map1, map2) < 0) + goto error; + return map_intersect_internal(map1, map2); +error: + isl_map_free(map1); + isl_map_free(map2); + return NULL; +} + +__isl_give isl_map *isl_map_intersect(__isl_take isl_map *map1, + __isl_take isl_map *map2) +{ + isl_map_align_params_bin(&map1, &map2); + return map_intersect(map1, map2); +} + +__isl_give isl_set *isl_set_intersect(__isl_take isl_set *set1, + __isl_take isl_set *set2) +{ + return set_from_map(isl_map_intersect(set_to_map(set1), + set_to_map(set2))); +} + +/* map_intersect_internal accepts intersections + * with parameter domains, so we can just call that function. + */ +__isl_give isl_map *isl_map_intersect_params(__isl_take isl_map *map, + __isl_take isl_set *params) +{ + isl_map_align_params_set(&map, ¶ms); + return map_intersect_internal(map, params); +} + +__isl_give isl_set *isl_set_intersect_params(__isl_take isl_set *set, + __isl_take isl_set *params) +{ + return isl_map_intersect_params(set, params); +} + +__isl_give isl_basic_map *isl_basic_map_reverse(__isl_take isl_basic_map *bmap) +{ + isl_space *space; + unsigned pos; + isl_size n1, n2; + + if (!bmap) + return NULL; + bmap = isl_basic_map_cow(bmap); + if (!bmap) + return NULL; + space = isl_space_reverse(isl_space_copy(bmap->dim)); + pos = isl_basic_map_offset(bmap, isl_dim_in); + n1 = isl_basic_map_dim(bmap, isl_dim_in); + n2 = isl_basic_map_dim(bmap, isl_dim_out); + if (n1 < 0 || n2 < 0) + bmap = isl_basic_map_free(bmap); + bmap = isl_basic_map_swap_vars(bmap, pos, n1, n2); + return isl_basic_map_reset_space(bmap, space); +} + +/* Given a basic map where the tuple of type "type" is a wrapped map, + * swap domain and range of that wrapped map. + */ +static __isl_give isl_basic_map *isl_basic_map_reverse_wrapped( + __isl_take isl_basic_map *bmap, enum isl_dim_type type) +{ + isl_space *space; + isl_size offset, n1, n2; + + space = isl_basic_map_peek_space(bmap); + offset = isl_basic_map_var_offset(bmap, type); + n1 = isl_space_wrapped_dim(space, type, isl_dim_in); + n2 = isl_space_wrapped_dim(space, type, isl_dim_out); + if (offset < 0 || n1 < 0 || n2 < 0) + return isl_basic_map_free(bmap); + + bmap = isl_basic_map_swap_vars(bmap, 1 + offset, n1, n2); + + space = isl_basic_map_take_space(bmap); + space = isl_space_reverse_wrapped(space, type); + bmap = isl_basic_map_restore_space(bmap, space); + + return bmap; +} + +/* Given a basic map (A -> B) -> C, return the corresponding basic map + * (B -> A) -> C. + */ +static __isl_give isl_basic_map *isl_basic_map_domain_reverse( + __isl_take isl_basic_map *bmap) +{ + isl_space *space; + + space = isl_basic_map_peek_space(bmap); + if (isl_space_check_domain_is_wrapping(space) < 0) + return isl_basic_map_free(bmap); + bmap = isl_basic_map_reverse_wrapped(bmap, isl_dim_in); + + return bmap; +} + +/* Given a basic map A -> (B -> C), return the corresponding basic map + * A -> (C -> B). + */ +static __isl_give isl_basic_map *isl_basic_map_range_reverse( + __isl_take isl_basic_map *bmap) +{ + isl_space *space; + + space = isl_basic_map_peek_space(bmap); + if (isl_space_check_range_is_wrapping(space) < 0) + return isl_basic_map_free(bmap); + bmap = isl_basic_map_reverse_wrapped(bmap, isl_dim_out); + + return bmap; +} + +/* Given a basic map that is actually a basic set (A -> B), + * return the corresponding basic set (B -> A) as a basic map. + */ +static __isl_give isl_basic_map *isl_basic_map_set_reverse( + __isl_take isl_basic_map *bmap) +{ + isl_space *space; + + space = isl_basic_map_peek_space(bmap); + if (isl_space_check_is_wrapping(space) < 0) + return isl_basic_map_free(bmap); + bmap = isl_basic_map_reverse_wrapped(bmap, isl_dim_set); + + return bmap; +} + +static __isl_give isl_basic_map *basic_map_space_reset( + __isl_take isl_basic_map *bmap, enum isl_dim_type type) +{ + isl_space *space; + + if (!bmap) + return NULL; + if (!isl_space_is_named_or_nested(bmap->dim, type)) + return bmap; + + space = isl_basic_map_get_space(bmap); + space = isl_space_reset(space, type); + bmap = isl_basic_map_reset_space(bmap, space); + return bmap; +} + +__isl_give isl_basic_map *isl_basic_map_insert_dims( + __isl_take isl_basic_map *bmap, enum isl_dim_type type, + unsigned pos, unsigned n) +{ + isl_bool rational, is_empty; + isl_space *res_space; + struct isl_basic_map *res; + struct isl_dim_map *dim_map; + isl_size total; + unsigned off; + enum isl_dim_type t; + + if (n == 0) + return basic_map_space_reset(bmap, type); + + is_empty = isl_basic_map_plain_is_empty(bmap); + total = isl_basic_map_dim(bmap, isl_dim_all); + if (is_empty < 0 || total < 0) + return isl_basic_map_free(bmap); + res_space = isl_space_insert_dims(isl_basic_map_get_space(bmap), + type, pos, n); + if (!res_space) + return isl_basic_map_free(bmap); + if (is_empty) { + isl_basic_map_free(bmap); + return isl_basic_map_empty(res_space); + } + + dim_map = isl_dim_map_alloc(bmap->ctx, total + n); + off = 0; + for (t = isl_dim_param; t <= isl_dim_out; ++t) { + isl_size dim; + + if (t != type) { + isl_dim_map_dim(dim_map, bmap->dim, t, off); + } else { + isl_size size = isl_basic_map_dim(bmap, t); + if (size < 0) + dim_map = isl_dim_map_free(dim_map); + isl_dim_map_dim_range(dim_map, bmap->dim, t, + 0, pos, off); + isl_dim_map_dim_range(dim_map, bmap->dim, t, + pos, size - pos, off + pos + n); + } + dim = isl_space_dim(res_space, t); + if (dim < 0) + dim_map = isl_dim_map_free(dim_map); + off += dim; + } + isl_dim_map_div(dim_map, bmap, off); + + res = isl_basic_map_alloc_space(res_space, + bmap->n_div, bmap->n_eq, bmap->n_ineq); + rational = isl_basic_map_is_rational(bmap); + if (rational < 0) + res = isl_basic_map_free(res); + if (rational) + res = isl_basic_map_set_rational(res); + res = isl_basic_map_add_constraints_dim_map(res, bmap, dim_map); + return isl_basic_map_finalize(res); +} + +__isl_give isl_basic_set *isl_basic_set_insert_dims( + __isl_take isl_basic_set *bset, + enum isl_dim_type type, unsigned pos, unsigned n) +{ + return isl_basic_map_insert_dims(bset, type, pos, n); +} + +__isl_give isl_basic_map *isl_basic_map_add_dims(__isl_take isl_basic_map *bmap, + enum isl_dim_type type, unsigned n) +{ + isl_size dim; + + dim = isl_basic_map_dim(bmap, type); + if (dim < 0) + return isl_basic_map_free(bmap); + return isl_basic_map_insert_dims(bmap, type, dim, n); +} + +__isl_give isl_basic_set *isl_basic_set_add_dims(__isl_take isl_basic_set *bset, + enum isl_dim_type type, unsigned n) +{ + if (!bset) + return NULL; + isl_assert(bset->ctx, type != isl_dim_in, goto error); + return isl_basic_map_add_dims(bset, type, n); +error: + isl_basic_set_free(bset); + return NULL; +} + +static __isl_give isl_map *map_space_reset(__isl_take isl_map *map, + enum isl_dim_type type) +{ + isl_space *space; + + if (!map || !isl_space_is_named_or_nested(map->dim, type)) + return map; + + space = isl_map_get_space(map); + space = isl_space_reset(space, type); + map = isl_map_reset_space(map, space); + return map; +} + +__isl_give isl_map *isl_map_insert_dims(__isl_take isl_map *map, + enum isl_dim_type type, unsigned pos, unsigned n) +{ + int i; + isl_space *space; + + if (n == 0) + return map_space_reset(map, type); + + map = isl_map_cow(map); + if (!map) + return NULL; + + for (i = 0; i < map->n; ++i) { + map->p[i] = isl_basic_map_insert_dims(map->p[i], type, pos, n); + if (!map->p[i]) + goto error; + } + + space = isl_map_take_space(map); + space = isl_space_insert_dims(space, type, pos, n); + map = isl_map_restore_space(map, space); + + return map; +error: + isl_map_free(map); + return NULL; +} + +__isl_give isl_set *isl_set_insert_dims(__isl_take isl_set *set, + enum isl_dim_type type, unsigned pos, unsigned n) +{ + return isl_map_insert_dims(set, type, pos, n); +} + +__isl_give isl_map *isl_map_add_dims(__isl_take isl_map *map, + enum isl_dim_type type, unsigned n) +{ + isl_size dim; + + dim = isl_map_dim(map, type); + if (dim < 0) + return isl_map_free(map); + return isl_map_insert_dims(map, type, dim, n); +} + +__isl_give isl_set *isl_set_add_dims(__isl_take isl_set *set, + enum isl_dim_type type, unsigned n) +{ + if (!set) + return NULL; + isl_assert(set->ctx, type != isl_dim_in, goto error); + return set_from_map(isl_map_add_dims(set_to_map(set), type, n)); +error: + isl_set_free(set); + return NULL; +} + +__isl_give isl_basic_map *isl_basic_map_move_dims( + __isl_take isl_basic_map *bmap, + enum isl_dim_type dst_type, unsigned dst_pos, + enum isl_dim_type src_type, unsigned src_pos, unsigned n) +{ + isl_space *space; + struct isl_dim_map *dim_map; + struct isl_basic_map *res; + enum isl_dim_type t; + isl_size total; + unsigned off; + + if (!bmap) + return NULL; + if (n == 0) { + bmap = isl_basic_map_reset(bmap, src_type); + bmap = isl_basic_map_reset(bmap, dst_type); + return bmap; + } + + if (isl_basic_map_check_range(bmap, src_type, src_pos, n) < 0) + return isl_basic_map_free(bmap); + + if (dst_type == src_type && dst_pos == src_pos) + return bmap; + + isl_assert(bmap->ctx, dst_type != src_type, goto error); + + if (pos(bmap->dim, dst_type) + dst_pos == + pos(bmap->dim, src_type) + src_pos + + ((src_type < dst_type) ? n : 0)) { + space = isl_basic_map_take_space(bmap); + space = isl_space_move_dims(space, dst_type, dst_pos, + src_type, src_pos, n); + bmap = isl_basic_map_restore_space(bmap, space); + bmap = isl_basic_map_finalize(bmap); + + return bmap; + } + + total = isl_basic_map_dim(bmap, isl_dim_all); + if (total < 0) + return isl_basic_map_free(bmap); + dim_map = isl_dim_map_alloc(bmap->ctx, total); + + off = 0; + space = isl_basic_map_peek_space(bmap); + for (t = isl_dim_param; t <= isl_dim_out; ++t) { + isl_size size = isl_space_dim(space, t); + if (size < 0) + dim_map = isl_dim_map_free(dim_map); + if (t == dst_type) { + isl_dim_map_dim_range(dim_map, space, t, + 0, dst_pos, off); + off += dst_pos; + isl_dim_map_dim_range(dim_map, space, src_type, + src_pos, n, off); + off += n; + isl_dim_map_dim_range(dim_map, space, t, + dst_pos, size - dst_pos, off); + off += size - dst_pos; + } else if (t == src_type) { + isl_dim_map_dim_range(dim_map, space, t, + 0, src_pos, off); + off += src_pos; + isl_dim_map_dim_range(dim_map, space, t, + src_pos + n, size - src_pos - n, off); + off += size - src_pos - n; + } else { + isl_dim_map_dim(dim_map, space, t, off); + off += size; + } + } + isl_dim_map_div(dim_map, bmap, off); + + res = isl_basic_map_alloc_space(isl_basic_map_get_space(bmap), + bmap->n_div, bmap->n_eq, bmap->n_ineq); + bmap = isl_basic_map_add_constraints_dim_map(res, bmap, dim_map); + space = isl_basic_map_take_space(bmap); + space = isl_space_move_dims(space, dst_type, dst_pos, + src_type, src_pos, n); + bmap = isl_basic_map_restore_space(bmap, space); + if (!bmap) + goto error; + + ISL_F_CLR(bmap, ISL_BASIC_MAP_SORTED); + bmap = isl_basic_map_gauss(bmap, NULL); + bmap = isl_basic_map_finalize(bmap); + + return bmap; +error: + isl_basic_map_free(bmap); + return NULL; +} + +__isl_give isl_basic_set *isl_basic_set_move_dims(__isl_take isl_basic_set *bset, + enum isl_dim_type dst_type, unsigned dst_pos, + enum isl_dim_type src_type, unsigned src_pos, unsigned n) +{ + isl_basic_map *bmap = bset_to_bmap(bset); + bmap = isl_basic_map_move_dims(bmap, dst_type, dst_pos, + src_type, src_pos, n); + return bset_from_bmap(bmap); +} + +__isl_give isl_set *isl_set_move_dims(__isl_take isl_set *set, + enum isl_dim_type dst_type, unsigned dst_pos, + enum isl_dim_type src_type, unsigned src_pos, unsigned n) +{ + if (!set) + return NULL; + isl_assert(set->ctx, dst_type != isl_dim_in, goto error); + return set_from_map(isl_map_move_dims(set_to_map(set), + dst_type, dst_pos, src_type, src_pos, n)); +error: + isl_set_free(set); + return NULL; +} + +__isl_give isl_map *isl_map_move_dims(__isl_take isl_map *map, + enum isl_dim_type dst_type, unsigned dst_pos, + enum isl_dim_type src_type, unsigned src_pos, unsigned n) +{ + int i; + isl_space *space; + + if (n == 0) { + map = isl_map_reset(map, src_type); + map = isl_map_reset(map, dst_type); + return map; + } + + if (isl_map_check_range(map, src_type, src_pos, n)) + return isl_map_free(map); + + if (dst_type == src_type && dst_pos == src_pos) + return map; + + isl_assert(map->ctx, dst_type != src_type, goto error); + + map = isl_map_cow(map); + if (!map) + return NULL; + + for (i = 0; i < map->n; ++i) { + map->p[i] = isl_basic_map_move_dims(map->p[i], + dst_type, dst_pos, + src_type, src_pos, n); + if (!map->p[i]) + goto error; + } + + space = isl_map_take_space(map); + space = isl_space_move_dims(space, dst_type, dst_pos, + src_type, src_pos, n); + map = isl_map_restore_space(map, space); + + return map; +error: + isl_map_free(map); + return NULL; +} + +/* Move the specified dimensions to the last columns right before + * the divs. Don't change the dimension specification of bmap. + * That's the responsibility of the caller. + */ +static __isl_give isl_basic_map *move_last(__isl_take isl_basic_map *bmap, + enum isl_dim_type type, unsigned first, unsigned n) +{ + isl_space *space; + struct isl_dim_map *dim_map; + struct isl_basic_map *res; + enum isl_dim_type t; + isl_size total; + unsigned off; + + if (!bmap) + return NULL; + if (isl_basic_map_offset(bmap, type) + first + n == + isl_basic_map_offset(bmap, isl_dim_div)) + return bmap; + + total = isl_basic_map_dim(bmap, isl_dim_all); + if (total < 0) + return isl_basic_map_free(bmap); + dim_map = isl_dim_map_alloc(bmap->ctx, total); + + off = 0; + space = isl_basic_map_peek_space(bmap); + for (t = isl_dim_param; t <= isl_dim_out; ++t) { + isl_size size = isl_space_dim(space, t); + if (size < 0) + dim_map = isl_dim_map_free(dim_map); + if (t == type) { + isl_dim_map_dim_range(dim_map, space, t, + 0, first, off); + off += first; + isl_dim_map_dim_range(dim_map, space, t, + first, n, total - bmap->n_div - n); + isl_dim_map_dim_range(dim_map, space, t, + first + n, size - (first + n), off); + off += size - (first + n); + } else { + isl_dim_map_dim(dim_map, space, t, off); + off += size; + } + } + isl_dim_map_div(dim_map, bmap, off + n); + + res = isl_basic_map_alloc_space(isl_basic_map_get_space(bmap), + bmap->n_div, bmap->n_eq, bmap->n_ineq); + res = isl_basic_map_add_constraints_dim_map(res, bmap, dim_map); + return res; +} + +/* Insert "n" rows in the divs of "bmap". + * + * The number of columns is not changed, which means that the last + * dimensions of "bmap" are being reintepreted as the new divs. + * The space of "bmap" is not adjusted, however, which means + * that "bmap" is left in an inconsistent state. Removing "n" dimensions + * from the space of "bmap" is the responsibility of the caller. + */ +static __isl_give isl_basic_map *insert_div_rows(__isl_take isl_basic_map *bmap, + int n) +{ + int i; + size_t row_size; + isl_int **new_div; + isl_int *old; + + bmap = isl_basic_map_cow(bmap); + if (!bmap) + return NULL; + + row_size = isl_basic_map_offset(bmap, isl_dim_div) + bmap->extra; + old = bmap->block2.data; + bmap->block2 = isl_blk_extend(bmap->ctx, bmap->block2, + (bmap->extra + n) * (1 + row_size)); + if (!bmap->block2.data) + return isl_basic_map_free(bmap); + new_div = isl_alloc_array(bmap->ctx, isl_int *, bmap->extra + n); + if (!new_div) + return isl_basic_map_free(bmap); + for (i = 0; i < n; ++i) { + new_div[i] = bmap->block2.data + + (bmap->extra + i) * (1 + row_size); + isl_seq_clr(new_div[i], 1 + row_size); + } + for (i = 0; i < bmap->extra; ++i) + new_div[n + i] = bmap->block2.data + (bmap->div[i] - old); + free(bmap->div); + bmap->div = new_div; + bmap->n_div += n; + bmap->extra += n; + + return bmap; +} + +/* Drop constraints from "bmap" that only involve the variables + * of "type" in the range [first, first + n] that are not related + * to any of the variables outside that interval. + * These constraints cannot influence the values for the variables + * outside the interval, except in case they cause "bmap" to be empty. + * Only drop the constraints if "bmap" is known to be non-empty. + */ +static __isl_give isl_basic_map *drop_irrelevant_constraints( + __isl_take isl_basic_map *bmap, enum isl_dim_type type, + unsigned first, unsigned n) +{ + int i; + int *groups; + isl_size dim, n_div; + isl_bool non_empty; + + non_empty = isl_basic_map_plain_is_non_empty(bmap); + if (non_empty < 0) + return isl_basic_map_free(bmap); + if (!non_empty) + return bmap; + + dim = isl_basic_map_dim(bmap, isl_dim_all); + n_div = isl_basic_map_dim(bmap, isl_dim_div); + if (dim < 0 || n_div < 0) + return isl_basic_map_free(bmap); + groups = isl_calloc_array(isl_basic_map_get_ctx(bmap), int, dim); + if (!groups) + return isl_basic_map_free(bmap); + first += isl_basic_map_offset(bmap, type) - 1; + for (i = 0; i < first; ++i) + groups[i] = -1; + for (i = first + n; i < dim - n_div; ++i) + groups[i] = -1; + + bmap = isl_basic_map_drop_unrelated_constraints(bmap, groups); + + return bmap; +} + +/* Turn the n dimensions of type type, starting at first + * into existentially quantified variables. + * + * If a subset of the projected out variables are unrelated + * to any of the variables that remain, then the constraints + * involving this subset are simply dropped first. + */ +__isl_give isl_basic_map *isl_basic_map_project_out( + __isl_take isl_basic_map *bmap, + enum isl_dim_type type, unsigned first, unsigned n) +{ + isl_bool empty; + isl_space *space; + + if (n == 0) + return basic_map_space_reset(bmap, type); + if (type == isl_dim_div) + isl_die(isl_basic_map_get_ctx(bmap), isl_error_invalid, + "cannot project out existentially quantified variables", + return isl_basic_map_free(bmap)); + + empty = isl_basic_map_plain_is_empty(bmap); + if (empty < 0) + return isl_basic_map_free(bmap); + if (empty) + bmap = isl_basic_map_set_to_empty(bmap); + + bmap = drop_irrelevant_constraints(bmap, type, first, n); + if (!bmap) + return NULL; + + if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_RATIONAL)) + return isl_basic_map_remove_dims(bmap, type, first, n); + + if (isl_basic_map_check_range(bmap, type, first, n) < 0) + return isl_basic_map_free(bmap); + + bmap = move_last(bmap, type, first, n); + bmap = isl_basic_map_cow(bmap); + bmap = insert_div_rows(bmap, n); + + space = isl_basic_map_take_space(bmap); + space = isl_space_drop_dims(space, type, first, n); + bmap = isl_basic_map_restore_space(bmap, space); + bmap = isl_basic_map_simplify(bmap); + bmap = isl_basic_map_drop_redundant_divs(bmap); + return isl_basic_map_finalize(bmap); +} + +/* Turn the n dimensions of type type, starting at first + * into existentially quantified variables. + */ +__isl_give isl_basic_set *isl_basic_set_project_out( + __isl_take isl_basic_set *bset, enum isl_dim_type type, + unsigned first, unsigned n) +{ + return bset_from_bmap(isl_basic_map_project_out(bset_to_bmap(bset), + type, first, n)); +} + +/* Turn the n dimensions of type type, starting at first + * into existentially quantified variables. + */ +__isl_give isl_map *isl_map_project_out(__isl_take isl_map *map, + enum isl_dim_type type, unsigned first, unsigned n) +{ + int i; + isl_space *space; + + if (n == 0) + return map_space_reset(map, type); + + if (isl_map_check_range(map, type, first, n) < 0) + return isl_map_free(map); + + map = isl_map_cow(map); + if (!map) + return NULL; + + for (i = 0; i < map->n; ++i) { + map->p[i] = isl_basic_map_project_out(map->p[i], type, first, n); + if (!map->p[i]) + goto error; + } + + if (map->n > 1) + ISL_F_CLR(map, ISL_MAP_DISJOINT); + map = isl_map_unmark_normalized(map); + + space = isl_map_take_space(map); + space = isl_space_drop_dims(space, type, first, n); + map = isl_map_restore_space(map, space); + + return map; +error: + isl_map_free(map); + return NULL; +} + +#undef TYPE +#define TYPE isl_map +#include "isl_project_out_all_params_templ.c" +#include "isl_project_out_param_templ.c" + +/* Turn all the dimensions of type "type", except the "n" starting at "first" + * into existentially quantified variables. + */ +__isl_give isl_map *isl_map_project_onto(__isl_take isl_map *map, + enum isl_dim_type type, unsigned first, unsigned n) +{ + isl_size dim; + + dim = isl_map_dim(map, type); + if (isl_map_check_range(map, type, first, n) < 0 || dim < 0) + return isl_map_free(map); + map = isl_map_project_out(map, type, first + n, dim - (first + n)); + map = isl_map_project_out(map, type, 0, first); + return map; +} + +/* Turn the n dimensions of type type, starting at first + * into existentially quantified variables. + */ +__isl_give isl_set *isl_set_project_out(__isl_take isl_set *set, + enum isl_dim_type type, unsigned first, unsigned n) +{ + return set_from_map(isl_map_project_out(set_to_map(set), + type, first, n)); +} + +/* If "set" involves a parameter with identifier "id", + * then turn it into an existentially quantified variable. + */ +__isl_give isl_set *isl_set_project_out_param_id(__isl_take isl_set *set, + __isl_take isl_id *id) +{ + return set_from_map(isl_map_project_out_param_id(set_to_map(set), id)); +} + +/* If "set" involves any of the parameters with identifiers in "list", + * then turn them into existentially quantified variables. + */ +__isl_give isl_set *isl_set_project_out_param_id_list(__isl_take isl_set *set, + __isl_take isl_id_list *list) +{ + isl_map *map; + + map = set_to_map(set); + map = isl_map_project_out_param_id_list(map, list); + return set_from_map(map); +} + +/* Project out all parameters from "set" by existentially quantifying + * over them. + */ +__isl_give isl_set *isl_set_project_out_all_params(__isl_take isl_set *set) +{ + return set_from_map(isl_map_project_out_all_params(set_to_map(set))); +} + +/* Return a map that projects the elements in "set" onto their + * "n" set dimensions starting at "first". + * "type" should be equal to isl_dim_set. + */ +__isl_give isl_map *isl_set_project_onto_map(__isl_take isl_set *set, + enum isl_dim_type type, unsigned first, unsigned n) +{ + int i; + isl_map *map; + + if (type != isl_dim_set) + isl_die(isl_set_get_ctx(set), isl_error_invalid, + "only set dimensions can be projected out", goto error); + if (isl_set_check_range(set, type, first, n) < 0) + return isl_set_free(set); + + map = isl_map_from_domain(set); + map = isl_map_add_dims(map, isl_dim_out, n); + for (i = 0; i < n; ++i) + map = isl_map_equate(map, isl_dim_in, first + i, + isl_dim_out, i); + return map; +error: + isl_set_free(set); + return NULL; +} + +static __isl_give isl_basic_map *add_divs(__isl_take isl_basic_map *bmap, + unsigned n) +{ + int i, j; + isl_size total; + + total = isl_basic_map_dim(bmap, isl_dim_all); + if (total < 0) + return isl_basic_map_free(bmap); + for (i = 0; i < n; ++i) { + j = isl_basic_map_alloc_div(bmap); + if (j < 0) + goto error; + isl_seq_clr(bmap->div[j], 1 + 1 + total); + } + return bmap; +error: + isl_basic_map_free(bmap); + return NULL; +} + +/* Does "bmap2" apply to the range of "bmap1" (ignoring parameters)? + */ +isl_bool isl_basic_map_applies_range(__isl_keep isl_basic_map *bmap1, + __isl_keep isl_basic_map *bmap2) +{ + isl_space *space1, *space2; + + space1 = isl_basic_map_peek_space(bmap1); + space2 = isl_basic_map_peek_space(bmap2); + return isl_space_tuple_is_equal(space1, isl_dim_out, + space2, isl_dim_in); +} + +/* Check that "bmap2" applies to the range of "bmap1" (ignoring parameters). + */ +static isl_stat isl_basic_map_check_applies_range( + __isl_keep isl_basic_map *bmap1, __isl_keep isl_basic_map *bmap2) +{ + isl_bool equal; + + equal = isl_basic_map_applies_range(bmap1, bmap2); + if (equal < 0) + return isl_stat_error; + if (!equal) + isl_die(isl_basic_map_get_ctx(bmap1), isl_error_invalid, + "spaces don't match", return isl_stat_error); + return isl_stat_ok; +} + +__isl_give isl_basic_map *isl_basic_map_apply_range( + __isl_take isl_basic_map *bmap1, __isl_take isl_basic_map *bmap2) +{ + isl_space *space_result = NULL; + struct isl_basic_map *bmap; + isl_size n_in, n_out, n, nparam; + unsigned total, pos; + struct isl_dim_map *dim_map1, *dim_map2; + + if (isl_basic_map_check_equal_params(bmap1, bmap2) < 0) + goto error; + if (isl_basic_map_check_applies_range(bmap1, bmap2) < 0) + goto error; + + n_in = isl_basic_map_dim(bmap1, isl_dim_in); + n_out = isl_basic_map_dim(bmap2, isl_dim_out); + n = isl_basic_map_dim(bmap1, isl_dim_out); + nparam = isl_basic_map_dim(bmap1, isl_dim_param); + if (n_in < 0 || n_out < 0 || n < 0 || nparam < 0) + goto error; + + space_result = isl_space_join(isl_basic_map_get_space(bmap1), + isl_basic_map_get_space(bmap2)); + + total = nparam + n_in + n_out + bmap1->n_div + bmap2->n_div + n; + dim_map1 = isl_dim_map_alloc(bmap1->ctx, total); + dim_map2 = isl_dim_map_alloc(bmap1->ctx, total); + isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_param, pos = 0); + isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_param, pos = 0); + isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_in, pos += nparam); + isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_out, pos += n_in); + isl_dim_map_div(dim_map1, bmap1, pos += n_out); + isl_dim_map_div(dim_map2, bmap2, pos += bmap1->n_div); + isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_out, pos += bmap2->n_div); + isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_in, pos); + + bmap = isl_basic_map_alloc_space(space_result, + bmap1->n_div + bmap2->n_div + n, + bmap1->n_eq + bmap2->n_eq, + bmap1->n_ineq + bmap2->n_ineq); + bmap = isl_basic_map_add_constraints_dim_map(bmap, bmap1, dim_map1); + bmap = isl_basic_map_add_constraints_dim_map(bmap, bmap2, dim_map2); + bmap = add_divs(bmap, n); + bmap = isl_basic_map_simplify(bmap); + bmap = isl_basic_map_drop_redundant_divs(bmap); + return isl_basic_map_finalize(bmap); +error: + isl_basic_map_free(bmap1); + isl_basic_map_free(bmap2); + return NULL; +} + +__isl_give isl_basic_set *isl_basic_set_apply(__isl_take isl_basic_set *bset, + __isl_take isl_basic_map *bmap) +{ + if (isl_basic_map_check_compatible_domain(bmap, bset) < 0) + goto error; + + return bset_from_bmap(isl_basic_map_apply_range(bset_to_bmap(bset), + bmap)); +error: + isl_basic_set_free(bset); + isl_basic_map_free(bmap); + return NULL; +} + +__isl_give isl_basic_map *isl_basic_map_apply_domain( + __isl_take isl_basic_map *bmap1, __isl_take isl_basic_map *bmap2) +{ + if (isl_basic_map_check_equal_params(bmap1, bmap2) < 0) + goto error; + if (!isl_space_tuple_is_equal(bmap1->dim, isl_dim_in, + bmap2->dim, isl_dim_in)) + isl_die(isl_basic_map_get_ctx(bmap1), isl_error_invalid, + "spaces don't match", goto error); + + bmap1 = isl_basic_map_reverse(bmap1); + bmap1 = isl_basic_map_apply_range(bmap1, bmap2); + return isl_basic_map_reverse(bmap1); +error: + isl_basic_map_free(bmap1); + isl_basic_map_free(bmap2); + return NULL; +} + +/* Given two basic maps A -> f(A) and B -> g(B), construct a basic map + * A \cap B -> f(A) + f(B) + */ +__isl_give isl_basic_map *isl_basic_map_sum(__isl_take isl_basic_map *bmap1, + __isl_take isl_basic_map *bmap2) +{ + isl_size n_in, n_out, nparam; + unsigned total, pos; + struct isl_basic_map *bmap = NULL; + struct isl_dim_map *dim_map1, *dim_map2; + int i; + + if (isl_basic_map_check_equal_space(bmap1, bmap2) < 0) + goto error; + + nparam = isl_basic_map_dim(bmap1, isl_dim_param); + n_in = isl_basic_map_dim(bmap1, isl_dim_in); + n_out = isl_basic_map_dim(bmap1, isl_dim_out); + if (nparam < 0 || n_in < 0 || n_out < 0) + goto error; + + total = nparam + n_in + n_out + bmap1->n_div + bmap2->n_div + 2 * n_out; + dim_map1 = isl_dim_map_alloc(bmap1->ctx, total); + dim_map2 = isl_dim_map_alloc(bmap2->ctx, total); + isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_param, pos = 0); + isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_param, pos); + isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_in, pos += nparam); + isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_in, pos); + isl_dim_map_div(dim_map1, bmap1, pos += n_in + n_out); + isl_dim_map_div(dim_map2, bmap2, pos += bmap1->n_div); + isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_out, pos += bmap2->n_div); + isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_out, pos += n_out); + + bmap = isl_basic_map_alloc_space(isl_space_copy(bmap1->dim), + bmap1->n_div + bmap2->n_div + 2 * n_out, + bmap1->n_eq + bmap2->n_eq + n_out, + bmap1->n_ineq + bmap2->n_ineq); + for (i = 0; i < n_out; ++i) { + int j = isl_basic_map_alloc_equality(bmap); + if (j < 0) + goto error; + isl_seq_clr(bmap->eq[j], 1+total); + isl_int_set_si(bmap->eq[j][1+nparam+n_in+i], -1); + isl_int_set_si(bmap->eq[j][1+pos+i], 1); + isl_int_set_si(bmap->eq[j][1+pos-n_out+i], 1); + } + bmap = isl_basic_map_add_constraints_dim_map(bmap, bmap1, dim_map1); + bmap = isl_basic_map_add_constraints_dim_map(bmap, bmap2, dim_map2); + bmap = add_divs(bmap, 2 * n_out); + + bmap = isl_basic_map_simplify(bmap); + return isl_basic_map_finalize(bmap); +error: + isl_basic_map_free(bmap); + isl_basic_map_free(bmap1); + isl_basic_map_free(bmap2); + return NULL; +} + +/* Given two maps A -> f(A) and B -> g(B), construct a map + * A \cap B -> f(A) + f(B) + */ +__isl_give isl_map *isl_map_sum(__isl_take isl_map *map1, + __isl_take isl_map *map2) +{ + struct isl_map *result; + int i, j; + + if (isl_map_check_equal_space(map1, map2) < 0) + goto error; + + result = isl_map_alloc_space(isl_space_copy(map1->dim), + map1->n * map2->n, 0); + if (!result) + goto error; + for (i = 0; i < map1->n; ++i) + for (j = 0; j < map2->n; ++j) { + struct isl_basic_map *part; + part = isl_basic_map_sum( + isl_basic_map_copy(map1->p[i]), + isl_basic_map_copy(map2->p[j])); + if (isl_basic_map_is_empty(part)) + isl_basic_map_free(part); + else + result = isl_map_add_basic_map(result, part); + if (!result) + goto error; + } + isl_map_free(map1); + isl_map_free(map2); + return result; +error: + isl_map_free(map1); + isl_map_free(map2); + return NULL; +} + +__isl_give isl_set *isl_set_sum(__isl_take isl_set *set1, + __isl_take isl_set *set2) +{ + return set_from_map(isl_map_sum(set_to_map(set1), set_to_map(set2))); +} + +/* Given a basic map A -> f(A), construct A -> -f(A). + */ +__isl_give isl_basic_map *isl_basic_map_neg(__isl_take isl_basic_map *bmap) +{ + int i, j; + unsigned off; + isl_size n; + + bmap = isl_basic_map_cow(bmap); + n = isl_basic_map_dim(bmap, isl_dim_out); + if (n < 0) + return isl_basic_map_free(bmap); + + off = isl_basic_map_offset(bmap, isl_dim_out); + for (i = 0; i < bmap->n_eq; ++i) + for (j = 0; j < n; ++j) + isl_int_neg(bmap->eq[i][off+j], bmap->eq[i][off+j]); + for (i = 0; i < bmap->n_ineq; ++i) + for (j = 0; j < n; ++j) + isl_int_neg(bmap->ineq[i][off+j], bmap->ineq[i][off+j]); + for (i = 0; i < bmap->n_div; ++i) + for (j = 0; j < n; ++j) + isl_int_neg(bmap->div[i][1+off+j], bmap->div[i][1+off+j]); + bmap = isl_basic_map_gauss(bmap, NULL); + return isl_basic_map_finalize(bmap); +} + +__isl_give isl_basic_set *isl_basic_set_neg(__isl_take isl_basic_set *bset) +{ + return isl_basic_map_neg(bset); +} + +/* Given a map A -> f(A), construct A -> -f(A). + */ +__isl_give isl_map *isl_map_neg(__isl_take isl_map *map) +{ + int i; + + map = isl_map_cow(map); + if (!map) + return NULL; + + for (i = 0; i < map->n; ++i) { + map->p[i] = isl_basic_map_neg(map->p[i]); + if (!map->p[i]) + goto error; + } + + return map; +error: + isl_map_free(map); + return NULL; +} + +__isl_give isl_set *isl_set_neg(__isl_take isl_set *set) +{ + return set_from_map(isl_map_neg(set_to_map(set))); +} + +/* Given a basic map A -> f(A) and an integer d, construct a basic map + * A -> floor(f(A)/d). + */ +__isl_give isl_basic_map *isl_basic_map_floordiv(__isl_take isl_basic_map *bmap, + isl_int d) +{ + isl_size n_in, n_out, nparam; + unsigned total, pos; + struct isl_basic_map *result = NULL; + struct isl_dim_map *dim_map; + int i; + + nparam = isl_basic_map_dim(bmap, isl_dim_param); + n_in = isl_basic_map_dim(bmap, isl_dim_in); + n_out = isl_basic_map_dim(bmap, isl_dim_out); + if (nparam < 0 || n_in < 0 || n_out < 0) + return isl_basic_map_free(bmap); + + total = nparam + n_in + n_out + bmap->n_div + n_out; + dim_map = isl_dim_map_alloc(bmap->ctx, total); + isl_dim_map_dim(dim_map, bmap->dim, isl_dim_param, pos = 0); + isl_dim_map_dim(dim_map, bmap->dim, isl_dim_in, pos += nparam); + isl_dim_map_div(dim_map, bmap, pos += n_in + n_out); + isl_dim_map_dim(dim_map, bmap->dim, isl_dim_out, pos += bmap->n_div); + + result = isl_basic_map_alloc_space(isl_space_copy(bmap->dim), + bmap->n_div + n_out, + bmap->n_eq, bmap->n_ineq + 2 * n_out); + result = isl_basic_map_add_constraints_dim_map(result, bmap, dim_map); + result = add_divs(result, n_out); + for (i = 0; i < n_out; ++i) { + int j; + j = isl_basic_map_alloc_inequality(result); + if (j < 0) + goto error; + isl_seq_clr(result->ineq[j], 1+total); + isl_int_neg(result->ineq[j][1+nparam+n_in+i], d); + isl_int_set_si(result->ineq[j][1+pos+i], 1); + j = isl_basic_map_alloc_inequality(result); + if (j < 0) + goto error; + isl_seq_clr(result->ineq[j], 1+total); + isl_int_set(result->ineq[j][1+nparam+n_in+i], d); + isl_int_set_si(result->ineq[j][1+pos+i], -1); + isl_int_sub_ui(result->ineq[j][0], d, 1); + } + + result = isl_basic_map_simplify(result); + return isl_basic_map_finalize(result); +error: + isl_basic_map_free(result); + return NULL; +} + +/* Given a map A -> f(A) and an integer d, construct a map + * A -> floor(f(A)/d). + */ +__isl_give isl_map *isl_map_floordiv(__isl_take isl_map *map, isl_int d) +{ + int i; + + map = isl_map_cow(map); + if (!map) + return NULL; + + ISL_F_CLR(map, ISL_MAP_DISJOINT); + for (i = 0; i < map->n; ++i) { + map->p[i] = isl_basic_map_floordiv(map->p[i], d); + if (!map->p[i]) + goto error; + } + map = isl_map_unmark_normalized(map); + + return map; +error: + isl_map_free(map); + return NULL; +} + +/* Given a map A -> f(A) and an integer d, construct a map + * A -> floor(f(A)/d). + */ +__isl_give isl_map *isl_map_floordiv_val(__isl_take isl_map *map, + __isl_take isl_val *d) +{ + if (!map || !d) + goto error; + if (!isl_val_is_int(d)) + isl_die(isl_val_get_ctx(d), isl_error_invalid, + "expecting integer denominator", goto error); + map = isl_map_floordiv(map, d->n); + isl_val_free(d); + return map; +error: + isl_map_free(map); + isl_val_free(d); + return NULL; +} + +static __isl_give isl_basic_map *var_equal(__isl_take isl_basic_map *bmap, + unsigned pos) +{ + int i; + isl_size nparam; + isl_size n_in; + isl_size total; + + total = isl_basic_map_dim(bmap, isl_dim_all); + nparam = isl_basic_map_dim(bmap, isl_dim_param); + n_in = isl_basic_map_dim(bmap, isl_dim_in); + if (total < 0 || nparam < 0 || n_in < 0) + return isl_basic_map_free(bmap); + i = isl_basic_map_alloc_equality(bmap); + if (i < 0) + goto error; + isl_seq_clr(bmap->eq[i], 1 + total); + isl_int_set_si(bmap->eq[i][1+nparam+pos], -1); + isl_int_set_si(bmap->eq[i][1+nparam+n_in+pos], 1); + return isl_basic_map_finalize(bmap); +error: + isl_basic_map_free(bmap); + return NULL; +} + +/* Add a constraint to "bmap" expressing i_pos < o_pos + */ +static __isl_give isl_basic_map *var_less(__isl_take isl_basic_map *bmap, + unsigned pos) +{ + int i; + isl_size nparam; + isl_size n_in; + isl_size total; + + total = isl_basic_map_dim(bmap, isl_dim_all); + nparam = isl_basic_map_dim(bmap, isl_dim_param); + n_in = isl_basic_map_dim(bmap, isl_dim_in); + if (total < 0 || nparam < 0 || n_in < 0) + return isl_basic_map_free(bmap); + i = isl_basic_map_alloc_inequality(bmap); + if (i < 0) + goto error; + isl_seq_clr(bmap->ineq[i], 1 + total); + isl_int_set_si(bmap->ineq[i][0], -1); + isl_int_set_si(bmap->ineq[i][1+nparam+pos], -1); + isl_int_set_si(bmap->ineq[i][1+nparam+n_in+pos], 1); + return isl_basic_map_finalize(bmap); +error: + isl_basic_map_free(bmap); + return NULL; +} + +/* Add a constraint to "bmap" expressing i_pos <= o_pos + */ +static __isl_give isl_basic_map *var_less_or_equal( + __isl_take isl_basic_map *bmap, unsigned pos) +{ + int i; + isl_size nparam; + isl_size n_in; + isl_size total; + + total = isl_basic_map_dim(bmap, isl_dim_all); + nparam = isl_basic_map_dim(bmap, isl_dim_param); + n_in = isl_basic_map_dim(bmap, isl_dim_in); + if (total < 0 || nparam < 0 || n_in < 0) + return isl_basic_map_free(bmap); + i = isl_basic_map_alloc_inequality(bmap); + if (i < 0) + goto error; + isl_seq_clr(bmap->ineq[i], 1 + total); + isl_int_set_si(bmap->ineq[i][1+nparam+pos], -1); + isl_int_set_si(bmap->ineq[i][1+nparam+n_in+pos], 1); + return isl_basic_map_finalize(bmap); +error: + isl_basic_map_free(bmap); + return NULL; +} + +/* Add a constraint to "bmap" expressing i_pos > o_pos + */ +static __isl_give isl_basic_map *var_more(__isl_take isl_basic_map *bmap, + unsigned pos) +{ + int i; + isl_size nparam; + isl_size n_in; + isl_size total; + + total = isl_basic_map_dim(bmap, isl_dim_all); + nparam = isl_basic_map_dim(bmap, isl_dim_param); + n_in = isl_basic_map_dim(bmap, isl_dim_in); + if (total < 0 || nparam < 0 || n_in < 0) + return isl_basic_map_free(bmap); + i = isl_basic_map_alloc_inequality(bmap); + if (i < 0) + goto error; + isl_seq_clr(bmap->ineq[i], 1 + total); + isl_int_set_si(bmap->ineq[i][0], -1); + isl_int_set_si(bmap->ineq[i][1+nparam+pos], 1); + isl_int_set_si(bmap->ineq[i][1+nparam+n_in+pos], -1); + return isl_basic_map_finalize(bmap); +error: + isl_basic_map_free(bmap); + return NULL; +} + +/* Add a constraint to "bmap" expressing i_pos >= o_pos + */ +static __isl_give isl_basic_map *var_more_or_equal( + __isl_take isl_basic_map *bmap, unsigned pos) +{ + int i; + isl_size nparam; + isl_size n_in; + isl_size total; + + total = isl_basic_map_dim(bmap, isl_dim_all); + nparam = isl_basic_map_dim(bmap, isl_dim_param); + n_in = isl_basic_map_dim(bmap, isl_dim_in); + if (total < 0 || nparam < 0 || n_in < 0) + return isl_basic_map_free(bmap); + i = isl_basic_map_alloc_inequality(bmap); + if (i < 0) + goto error; + isl_seq_clr(bmap->ineq[i], 1 + total); + isl_int_set_si(bmap->ineq[i][1+nparam+pos], 1); + isl_int_set_si(bmap->ineq[i][1+nparam+n_in+pos], -1); + return isl_basic_map_finalize(bmap); +error: + isl_basic_map_free(bmap); + return NULL; +} + +__isl_give isl_basic_map *isl_basic_map_equal( + __isl_take isl_space *space, unsigned n_equal) +{ + int i; + struct isl_basic_map *bmap; + bmap = isl_basic_map_alloc_space(space, 0, n_equal, 0); + if (!bmap) + return NULL; + for (i = 0; i < n_equal && bmap; ++i) + bmap = var_equal(bmap, i); + return isl_basic_map_finalize(bmap); +} + +/* Return a relation on of dimension "space" expressing i_[0..pos] << o_[0..pos] + */ +__isl_give isl_basic_map *isl_basic_map_less_at(__isl_take isl_space *space, + unsigned pos) +{ + int i; + struct isl_basic_map *bmap; + bmap = isl_basic_map_alloc_space(space, 0, pos, 1); + if (!bmap) + return NULL; + for (i = 0; i < pos && bmap; ++i) + bmap = var_equal(bmap, i); + if (bmap) + bmap = var_less(bmap, pos); + return isl_basic_map_finalize(bmap); +} + +/* Return a relation on "space" expressing i_[0..pos] <<= o_[0..pos] + */ +__isl_give isl_basic_map *isl_basic_map_less_or_equal_at( + __isl_take isl_space *space, unsigned pos) +{ + int i; + isl_basic_map *bmap; + + bmap = isl_basic_map_alloc_space(space, 0, pos, 1); + for (i = 0; i < pos; ++i) + bmap = var_equal(bmap, i); + bmap = var_less_or_equal(bmap, pos); + return isl_basic_map_finalize(bmap); +} + +/* Return a relation on "space" expressing i_pos > o_pos + */ +__isl_give isl_basic_map *isl_basic_map_more_at(__isl_take isl_space *space, + unsigned pos) +{ + int i; + struct isl_basic_map *bmap; + bmap = isl_basic_map_alloc_space(space, 0, pos, 1); + if (!bmap) + return NULL; + for (i = 0; i < pos && bmap; ++i) + bmap = var_equal(bmap, i); + if (bmap) + bmap = var_more(bmap, pos); + return isl_basic_map_finalize(bmap); +} + +/* Return a relation on "space" expressing i_[0..pos] >>= o_[0..pos] + */ +__isl_give isl_basic_map *isl_basic_map_more_or_equal_at( + __isl_take isl_space *space, unsigned pos) +{ + int i; + isl_basic_map *bmap; + + bmap = isl_basic_map_alloc_space(space, 0, pos, 1); + for (i = 0; i < pos; ++i) + bmap = var_equal(bmap, i); + bmap = var_more_or_equal(bmap, pos); + return isl_basic_map_finalize(bmap); +} + +static __isl_give isl_map *map_lex_lte_first(__isl_take isl_space *space, + unsigned n, int equal) +{ + struct isl_map *map; + int i; + + if (n == 0 && equal) + return isl_map_universe(space); + + map = isl_map_alloc_space(isl_space_copy(space), n, ISL_MAP_DISJOINT); + + for (i = 0; i + 1 < n; ++i) + map = isl_map_add_basic_map(map, + isl_basic_map_less_at(isl_space_copy(space), i)); + if (n > 0) { + if (equal) + map = isl_map_add_basic_map(map, + isl_basic_map_less_or_equal_at(space, n - 1)); + else + map = isl_map_add_basic_map(map, + isl_basic_map_less_at(space, n - 1)); + } else + isl_space_free(space); + + return map; +} + +static __isl_give isl_map *map_lex_lte(__isl_take isl_space *space, int equal) +{ + if (!space) + return NULL; + return map_lex_lte_first(space, space->n_out, equal); +} + +__isl_give isl_map *isl_map_lex_lt_first(__isl_take isl_space *space, + unsigned n) +{ + return map_lex_lte_first(space, n, 0); +} + +__isl_give isl_map *isl_map_lex_le_first(__isl_take isl_space *space, + unsigned n) +{ + return map_lex_lte_first(space, n, 1); +} + +__isl_give isl_map *isl_map_lex_lt(__isl_take isl_space *set_space) +{ + return map_lex_lte(isl_space_map_from_set(set_space), 0); +} + +__isl_give isl_map *isl_map_lex_le(__isl_take isl_space *set_space) +{ + return map_lex_lte(isl_space_map_from_set(set_space), 1); +} + +static __isl_give isl_map *map_lex_gte_first(__isl_take isl_space *space, + unsigned n, int equal) +{ + struct isl_map *map; + int i; + + if (n == 0 && equal) + return isl_map_universe(space); + + map = isl_map_alloc_space(isl_space_copy(space), n, ISL_MAP_DISJOINT); + + for (i = 0; i + 1 < n; ++i) + map = isl_map_add_basic_map(map, + isl_basic_map_more_at(isl_space_copy(space), i)); + if (n > 0) { + if (equal) + map = isl_map_add_basic_map(map, + isl_basic_map_more_or_equal_at(space, n - 1)); + else + map = isl_map_add_basic_map(map, + isl_basic_map_more_at(space, n - 1)); + } else + isl_space_free(space); + + return map; +} + +static __isl_give isl_map *map_lex_gte(__isl_take isl_space *space, int equal) +{ + if (!space) + return NULL; + return map_lex_gte_first(space, space->n_out, equal); +} + +__isl_give isl_map *isl_map_lex_gt_first(__isl_take isl_space *space, + unsigned n) +{ + return map_lex_gte_first(space, n, 0); +} + +__isl_give isl_map *isl_map_lex_ge_first(__isl_take isl_space *space, + unsigned n) +{ + return map_lex_gte_first(space, n, 1); +} + +__isl_give isl_map *isl_map_lex_gt(__isl_take isl_space *set_space) +{ + return map_lex_gte(isl_space_map_from_set(set_space), 0); +} + +__isl_give isl_map *isl_map_lex_ge(__isl_take isl_space *set_space) +{ + return map_lex_gte(isl_space_map_from_set(set_space), 1); +} + +__isl_give isl_map *isl_set_lex_le_set(__isl_take isl_set *set1, + __isl_take isl_set *set2) +{ + isl_map *map; + map = isl_map_lex_le(isl_set_get_space(set1)); + map = isl_map_intersect_domain(map, set1); + map = isl_map_intersect_range(map, set2); + return map; +} + +__isl_give isl_map *isl_set_lex_lt_set(__isl_take isl_set *set1, + __isl_take isl_set *set2) +{ + isl_map *map; + map = isl_map_lex_lt(isl_set_get_space(set1)); + map = isl_map_intersect_domain(map, set1); + map = isl_map_intersect_range(map, set2); + return map; +} + +__isl_give isl_map *isl_set_lex_ge_set(__isl_take isl_set *set1, + __isl_take isl_set *set2) +{ + isl_map *map; + map = isl_map_lex_ge(isl_set_get_space(set1)); + map = isl_map_intersect_domain(map, set1); + map = isl_map_intersect_range(map, set2); + return map; +} + +__isl_give isl_map *isl_set_lex_gt_set(__isl_take isl_set *set1, + __isl_take isl_set *set2) +{ + isl_map *map; + map = isl_map_lex_gt(isl_set_get_space(set1)); + map = isl_map_intersect_domain(map, set1); + map = isl_map_intersect_range(map, set2); + return map; +} + +__isl_give isl_map *isl_map_lex_le_map(__isl_take isl_map *map1, + __isl_take isl_map *map2) +{ + isl_map *map; + map = isl_map_lex_le(isl_space_range(isl_map_get_space(map1))); + map = isl_map_apply_domain(map, isl_map_reverse(map1)); + map = isl_map_apply_range(map, isl_map_reverse(map2)); + return map; +} + +__isl_give isl_map *isl_map_lex_lt_map(__isl_take isl_map *map1, + __isl_take isl_map *map2) +{ + isl_map *map; + map = isl_map_lex_lt(isl_space_range(isl_map_get_space(map1))); + map = isl_map_apply_domain(map, isl_map_reverse(map1)); + map = isl_map_apply_range(map, isl_map_reverse(map2)); + return map; +} + +__isl_give isl_map *isl_map_lex_ge_map(__isl_take isl_map *map1, + __isl_take isl_map *map2) +{ + isl_map *map; + map = isl_map_lex_ge(isl_space_range(isl_map_get_space(map1))); + map = isl_map_apply_domain(map, isl_map_reverse(map1)); + map = isl_map_apply_range(map, isl_map_reverse(map2)); + return map; +} + +__isl_give isl_map *isl_map_lex_gt_map(__isl_take isl_map *map1, + __isl_take isl_map *map2) +{ + isl_map *map; + map = isl_map_lex_gt(isl_space_range(isl_map_get_space(map1))); + map = isl_map_apply_domain(map, isl_map_reverse(map1)); + map = isl_map_apply_range(map, isl_map_reverse(map2)); + return map; +} + +/* For the div d = floor(f/m) at position "div", add the constraint + * + * f - m d >= 0 + */ +static __isl_give isl_basic_map *add_upper_div_constraint( + __isl_take isl_basic_map *bmap, unsigned div) +{ + int i; + isl_size v_div = isl_basic_map_var_offset(bmap, isl_dim_div); + isl_size n_div; + unsigned pos; + + n_div = isl_basic_map_dim(bmap, isl_dim_div); + if (v_div < 0 || n_div < 0) + return isl_basic_map_free(bmap); + pos = v_div + div; + i = isl_basic_map_alloc_inequality(bmap); + if (i < 0) + return isl_basic_map_free(bmap); + isl_seq_cpy(bmap->ineq[i], bmap->div[div] + 1, 1 + v_div + n_div); + isl_int_neg(bmap->ineq[i][1 + pos], bmap->div[div][0]); + + return bmap; +} + +/* For the div d = floor(f/m) at position "div", add the constraint + * + * -(f-(m-1)) + m d >= 0 + */ +static __isl_give isl_basic_map *add_lower_div_constraint( + __isl_take isl_basic_map *bmap, unsigned div) +{ + int i; + isl_size v_div = isl_basic_map_var_offset(bmap, isl_dim_div); + isl_size n_div; + unsigned pos; + + n_div = isl_basic_map_dim(bmap, isl_dim_div); + if (v_div < 0 || n_div < 0) + return isl_basic_map_free(bmap); + pos = v_div + div; + i = isl_basic_map_alloc_inequality(bmap); + if (i < 0) + return isl_basic_map_free(bmap); + isl_seq_neg(bmap->ineq[i], bmap->div[div] + 1, 1 + v_div + n_div); + isl_int_set(bmap->ineq[i][1 + pos], bmap->div[div][0]); + isl_int_add(bmap->ineq[i][0], bmap->ineq[i][0], bmap->ineq[i][1 + pos]); + isl_int_sub_ui(bmap->ineq[i][0], bmap->ineq[i][0], 1); + + return bmap; +} + +/* For the div d = floor(f/m) at position "pos", add the constraints + * + * f - m d >= 0 + * -(f-(m-1)) + m d >= 0 + * + * Note that the second constraint is the negation of + * + * f - m d >= m + */ +__isl_give isl_basic_map *isl_basic_map_add_div_constraints( + __isl_take isl_basic_map *bmap, unsigned pos) +{ + bmap = add_upper_div_constraint(bmap, pos); + bmap = add_lower_div_constraint(bmap, pos); + return bmap; +} + +/* For each known div d = floor(f/m), add the constraints + * + * f - m d >= 0 + * -(f-(m-1)) + m d >= 0 + * + * Remove duplicate constraints in case of some these div constraints + * already appear in "bmap". + */ +__isl_give isl_basic_map *isl_basic_map_add_known_div_constraints( + __isl_take isl_basic_map *bmap) +{ + isl_size n_div; + + n_div = isl_basic_map_dim(bmap, isl_dim_div); + if (n_div < 0) + return isl_basic_map_free(bmap); + if (n_div == 0) + return bmap; + + bmap = add_known_div_constraints(bmap); + bmap = isl_basic_map_remove_duplicate_constraints(bmap, NULL, 0); + bmap = isl_basic_map_finalize(bmap); + return bmap; +} + +/* Add the div constraint of sign "sign" for div "div" of "bmap". + * + * In particular, if this div is of the form d = floor(f/m), + * then add the constraint + * + * f - m d >= 0 + * + * if sign < 0 or the constraint + * + * -(f-(m-1)) + m d >= 0 + * + * if sign > 0. + */ +__isl_give isl_basic_map *isl_basic_map_add_div_constraint( + __isl_take isl_basic_map *bmap, unsigned div, int sign) +{ + if (sign < 0) + return add_upper_div_constraint(bmap, div); + else + return add_lower_div_constraint(bmap, div); +} + +__isl_give isl_basic_set *isl_basic_map_underlying_set( + __isl_take isl_basic_map *bmap) +{ + isl_space *space; + + if (!bmap) + goto error; + if (bmap->dim->nparam == 0 && bmap->dim->n_in == 0 && + bmap->n_div == 0 && + !isl_space_is_named_or_nested(bmap->dim, isl_dim_in) && + !isl_space_is_named_or_nested(bmap->dim, isl_dim_out)) + return bset_from_bmap(bmap); + bmap = isl_basic_map_cow(bmap); + if (!bmap) + return NULL; + space = isl_basic_map_take_space(bmap); + space = isl_space_underlying(space, bmap->n_div); + bmap = isl_basic_map_restore_space(bmap, space); + if (!bmap) + return NULL; + bmap->extra -= bmap->n_div; + bmap->n_div = 0; + bmap = isl_basic_map_finalize(bmap); + return bset_from_bmap(bmap); +error: + isl_basic_map_free(bmap); + return NULL; +} + +__isl_give isl_basic_set *isl_basic_set_underlying_set( + __isl_take isl_basic_set *bset) +{ + return isl_basic_map_underlying_set(bset_to_bmap(bset)); +} + +/* Replace each element in "list" by the result of applying + * isl_basic_map_underlying_set to the element. + */ +__isl_give isl_basic_set_list *isl_basic_map_list_underlying_set( + __isl_take isl_basic_map_list *list) +{ + int i; + isl_size n; + + n = isl_basic_map_list_n_basic_map(list); + if (n < 0) + goto error; + + for (i = 0; i < n; ++i) { + isl_basic_map *bmap; + isl_basic_set *bset; + + bmap = isl_basic_map_list_get_basic_map(list, i); + bset = isl_basic_set_underlying_set(bmap); + list = isl_basic_set_list_set_basic_set(list, i, bset); + } + + return list; +error: + isl_basic_map_list_free(list); + return NULL; +} + +__isl_give isl_basic_map *isl_basic_map_overlying_set( + __isl_take isl_basic_set *bset, __isl_take isl_basic_map *like) +{ + struct isl_basic_map *bmap; + struct isl_ctx *ctx; + isl_size dim, bmap_total; + unsigned total; + int i; + + if (!bset || !like) + goto error; + ctx = bset->ctx; + if (isl_basic_set_check_no_params(bset) < 0 || + isl_basic_set_check_no_locals(bset) < 0) + goto error; + dim = isl_basic_set_dim(bset, isl_dim_set); + bmap_total = isl_basic_map_dim(like, isl_dim_all); + if (dim < 0 || bmap_total < 0) + goto error; + isl_assert(ctx, dim == bmap_total, goto error); + if (like->n_div == 0) { + isl_space *space = isl_basic_map_get_space(like); + isl_basic_map_free(like); + return isl_basic_map_reset_space(bset, space); + } + bset = isl_basic_set_cow(bset); + if (!bset) + goto error; + total = dim + bset->extra; + bmap = bset_to_bmap(bset); + isl_space_free(isl_basic_map_take_space(bmap)); + bmap = isl_basic_map_restore_space(bmap, isl_basic_map_get_space(like)); + if (!bmap) + goto error; + bmap->n_div = like->n_div; + bmap->extra += like->n_div; + if (bmap->extra) { + unsigned ltotal; + isl_int **div; + ltotal = total - bmap->extra + like->extra; + if (ltotal > total) + ltotal = total; + bmap->block2 = isl_blk_extend(ctx, bmap->block2, + bmap->extra * (1 + 1 + total)); + if (isl_blk_is_error(bmap->block2)) + goto error; + div = isl_realloc_array(ctx, bmap->div, isl_int *, bmap->extra); + if (!div) + goto error; + bmap->div = div; + for (i = 0; i < bmap->extra; ++i) + bmap->div[i] = bmap->block2.data + i * (1 + 1 + total); + for (i = 0; i < like->n_div; ++i) { + isl_seq_cpy(bmap->div[i], like->div[i], 1 + 1 + ltotal); + isl_seq_clr(bmap->div[i]+1+1+ltotal, total - ltotal); + } + bmap = isl_basic_map_add_known_div_constraints(bmap); + } + isl_basic_map_free(like); + bmap = isl_basic_map_simplify(bmap); + bmap = isl_basic_map_finalize(bmap); + return bmap; +error: + isl_basic_map_free(like); + isl_basic_set_free(bset); + return NULL; +} + +__isl_give isl_basic_set *isl_basic_set_from_underlying_set( + __isl_take isl_basic_set *bset, __isl_take isl_basic_set *like) +{ + return bset_from_bmap(isl_basic_map_overlying_set(bset, + bset_to_bmap(like))); +} + +__isl_give isl_set *isl_map_underlying_set(__isl_take isl_map *map) +{ + int i; + + map = isl_map_cow(map); + if (!map) + return NULL; + map->dim = isl_space_cow(map->dim); + if (!map->dim) + goto error; + + for (i = 1; i < map->n; ++i) + isl_assert(map->ctx, map->p[0]->n_div == map->p[i]->n_div, + goto error); + for (i = 0; i < map->n; ++i) { + map->p[i] = bset_to_bmap( + isl_basic_map_underlying_set(map->p[i])); + if (!map->p[i]) + goto error; + } + if (map->n == 0) + map->dim = isl_space_underlying(map->dim, 0); + else { + isl_space_free(map->dim); + map->dim = isl_space_copy(map->p[0]->dim); + } + if (!map->dim) + goto error; + return set_from_map(map); +error: + isl_map_free(map); + return NULL; +} + +/* Replace the space of "bmap" by "space". + * + * If the space of "bmap" is identical to "space" (including the identifiers + * of the input and output dimensions), then simply return the original input. + */ +__isl_give isl_basic_map *isl_basic_map_reset_space( + __isl_take isl_basic_map *bmap, __isl_take isl_space *space) +{ + isl_bool equal; + isl_space *bmap_space; + + bmap_space = isl_basic_map_peek_space(bmap); + equal = isl_space_is_equal(bmap_space, space); + if (equal >= 0 && equal) + equal = isl_space_has_equal_ids(bmap_space, space); + if (equal < 0) + goto error; + if (equal) { + isl_space_free(space); + return bmap; + } + isl_space_free(isl_basic_map_take_space(bmap)); + bmap = isl_basic_map_restore_space(bmap, space); + + bmap = isl_basic_map_finalize(bmap); + + return bmap; +error: + isl_basic_map_free(bmap); + isl_space_free(space); + return NULL; +} + +__isl_give isl_basic_set *isl_basic_set_reset_space( + __isl_take isl_basic_set *bset, __isl_take isl_space *space) +{ + return bset_from_bmap(isl_basic_map_reset_space(bset_to_bmap(bset), + space)); +} + +/* Check that the total dimensions of "map" and "space" are the same. + */ +static isl_stat check_map_space_equal_total_dim(__isl_keep isl_map *map, + __isl_keep isl_space *space) +{ + isl_size dim1, dim2; + + dim1 = isl_map_dim(map, isl_dim_all); + dim2 = isl_space_dim(space, isl_dim_all); + if (dim1 < 0 || dim2 < 0) + return isl_stat_error; + if (dim1 == dim2) + return isl_stat_ok; + isl_die(isl_map_get_ctx(map), isl_error_invalid, + "total dimensions do not match", return isl_stat_error); +} + +__isl_give isl_map *isl_map_reset_space(__isl_take isl_map *map, + __isl_take isl_space *space) +{ + int i; + + map = isl_map_cow(map); + if (!map || !space) + goto error; + + for (i = 0; i < map->n; ++i) { + map->p[i] = isl_basic_map_reset_space(map->p[i], + isl_space_copy(space)); + if (!map->p[i]) + goto error; + } + isl_space_free(isl_map_take_space(map)); + map = isl_map_restore_space(map, space); + + return map; +error: + isl_map_free(map); + isl_space_free(space); + return NULL; +} + +/* Replace the space of "map" by "space", without modifying + * the dimension of "map". + * + * If the space of "map" is identical to "space" (including the identifiers + * of the input and output dimensions), then simply return the original input. + */ +__isl_give isl_map *isl_map_reset_equal_dim_space(__isl_take isl_map *map, + __isl_take isl_space *space) +{ + isl_bool equal; + isl_space *map_space; + + map_space = isl_map_peek_space(map); + equal = isl_space_is_equal(map_space, space); + if (equal >= 0 && equal) + equal = isl_space_has_equal_ids(map_space, space); + if (equal < 0) + goto error; + if (equal) { + isl_space_free(space); + return map; + } + if (check_map_space_equal_total_dim(map, space) < 0) + goto error; + return isl_map_reset_space(map, space); +error: + isl_map_free(map); + isl_space_free(space); + return NULL; +} + +__isl_give isl_set *isl_set_reset_space(__isl_take isl_set *set, + __isl_take isl_space *space) +{ + return set_from_map(isl_map_reset_space(set_to_map(set), space)); +} + +/* Compute the parameter domain of the given basic set. + */ +__isl_give isl_basic_set *isl_basic_set_params(__isl_take isl_basic_set *bset) +{ + isl_bool is_params; + isl_space *space; + isl_size n; + + is_params = isl_basic_set_is_params(bset); + if (is_params < 0) + return isl_basic_set_free(bset); + if (is_params) + return bset; + + n = isl_basic_set_dim(bset, isl_dim_set); + if (n < 0) + return isl_basic_set_free(bset); + bset = isl_basic_set_project_out(bset, isl_dim_set, 0, n); + space = isl_basic_set_get_space(bset); + space = isl_space_params(space); + bset = isl_basic_set_reset_space(bset, space); + return bset; +} + +/* Construct a zero-dimensional basic set with the given parameter domain. + */ +__isl_give isl_basic_set *isl_basic_set_from_params( + __isl_take isl_basic_set *bset) +{ + isl_space *space; + space = isl_basic_set_get_space(bset); + space = isl_space_set_from_params(space); + bset = isl_basic_set_reset_space(bset, space); + return bset; +} + +/* Compute the parameter domain of the given set. + */ +__isl_give isl_set *isl_set_params(__isl_take isl_set *set) +{ + return isl_map_params(set_to_map(set)); +} + +/* Construct a zero-dimensional set with the given parameter domain. + */ +__isl_give isl_set *isl_set_from_params(__isl_take isl_set *set) +{ + isl_space *space; + space = isl_set_get_space(set); + space = isl_space_set_from_params(space); + set = isl_set_reset_space(set, space); + return set; +} + +/* Compute the parameter domain of the given map. + */ +__isl_give isl_set *isl_map_params(__isl_take isl_map *map) +{ + isl_space *space; + isl_size n_in, n_out; + + n_in = isl_map_dim(map, isl_dim_in); + n_out = isl_map_dim(map, isl_dim_out); + if (n_in < 0 || n_out < 0) + return isl_map_free(map); + map = isl_map_project_out(map, isl_dim_in, 0, n_in); + map = isl_map_project_out(map, isl_dim_out, 0, n_out); + space = isl_map_get_space(map); + space = isl_space_params(space); + map = isl_map_reset_space(map, space); + return map; +} + +__isl_give isl_basic_set *isl_basic_map_domain(__isl_take isl_basic_map *bmap) +{ + isl_space *space; + isl_size n_out; + + n_out = isl_basic_map_dim(bmap, isl_dim_out); + if (n_out < 0) + return isl_basic_map_free(bmap); + space = isl_space_domain(isl_basic_map_get_space(bmap)); + + bmap = isl_basic_map_project_out(bmap, isl_dim_out, 0, n_out); + + return isl_basic_map_reset_space(bmap, space); +} + +isl_bool isl_basic_map_may_be_set(__isl_keep isl_basic_map *bmap) +{ + if (!bmap) + return isl_bool_error; + return isl_space_may_be_set(bmap->dim); +} + +/* Is this basic map actually a set? + * Users should never call this function. Outside of isl, + * the type should indicate whether something is a set or a map. + */ +isl_bool isl_basic_map_is_set(__isl_keep isl_basic_map *bmap) +{ + if (!bmap) + return isl_bool_error; + return isl_space_is_set(bmap->dim); +} + +__isl_give isl_basic_set *isl_basic_map_range(__isl_take isl_basic_map *bmap) +{ + isl_bool is_set; + + is_set = isl_basic_map_is_set(bmap); + if (is_set < 0) + goto error; + if (is_set) + return bmap; + return isl_basic_map_domain(isl_basic_map_reverse(bmap)); +error: + isl_basic_map_free(bmap); + return NULL; +} + +__isl_give isl_basic_map *isl_basic_map_domain_map( + __isl_take isl_basic_map *bmap) +{ + int i; + isl_space *space; + isl_basic_map *domain; + isl_size nparam, n_in, n_out; + + nparam = isl_basic_map_dim(bmap, isl_dim_param); + n_in = isl_basic_map_dim(bmap, isl_dim_in); + n_out = isl_basic_map_dim(bmap, isl_dim_out); + if (nparam < 0 || n_in < 0 || n_out < 0) + return isl_basic_map_free(bmap); + + space = isl_basic_map_get_space(bmap); + space = isl_space_from_range(isl_space_domain(space)); + domain = isl_basic_map_universe(space); + + bmap = isl_basic_map_from_domain(isl_basic_map_wrap(bmap)); + bmap = isl_basic_map_apply_range(bmap, domain); + bmap = isl_basic_map_extend_constraints(bmap, n_in, 0); + + for (i = 0; i < n_in; ++i) + bmap = isl_basic_map_equate(bmap, isl_dim_in, i, + isl_dim_out, i); + + bmap = isl_basic_map_gauss(bmap, NULL); + return isl_basic_map_finalize(bmap); +} + +__isl_give isl_basic_map *isl_basic_map_range_map( + __isl_take isl_basic_map *bmap) +{ + int i; + isl_space *space; + isl_basic_map *range; + isl_size nparam, n_in, n_out; + + nparam = isl_basic_map_dim(bmap, isl_dim_param); + n_in = isl_basic_map_dim(bmap, isl_dim_in); + n_out = isl_basic_map_dim(bmap, isl_dim_out); + if (nparam < 0 || n_in < 0 || n_out < 0) + return isl_basic_map_free(bmap); + + space = isl_basic_map_get_space(bmap); + space = isl_space_from_range(isl_space_range(space)); + range = isl_basic_map_universe(space); + + bmap = isl_basic_map_from_domain(isl_basic_map_wrap(bmap)); + bmap = isl_basic_map_apply_range(bmap, range); + bmap = isl_basic_map_extend_constraints(bmap, n_out, 0); + + for (i = 0; i < n_out; ++i) + bmap = isl_basic_map_equate(bmap, isl_dim_in, n_in + i, + isl_dim_out, i); + + bmap = isl_basic_map_gauss(bmap, NULL); + return isl_basic_map_finalize(bmap); +} + +int isl_map_may_be_set(__isl_keep isl_map *map) +{ + if (!map) + return -1; + return isl_space_may_be_set(map->dim); +} + +/* Is this map actually a set? + * Users should never call this function. Outside of isl, + * the type should indicate whether something is a set or a map. + */ +isl_bool isl_map_is_set(__isl_keep isl_map *map) +{ + if (!map) + return isl_bool_error; + return isl_space_is_set(map->dim); +} + +__isl_give isl_set *isl_map_range(__isl_take isl_map *map) +{ + isl_space *space; + isl_size n_in; + + n_in = isl_map_dim(map, isl_dim_in); + if (n_in < 0) + return set_from_map(isl_map_free(map)); + space = isl_space_range(isl_map_get_space(map)); + + map = isl_map_project_out(map, isl_dim_in, 0, n_in); + + return set_from_map(isl_map_reset_space(map, space)); +} + +/* Transform "map" by applying "fn_space" to its space and "fn_bmap" + * to each of its basic maps. + */ +static __isl_give isl_map *isl_map_transform(__isl_take isl_map *map, + __isl_give isl_space *(*fn_space)(__isl_take isl_space *space), + __isl_give isl_basic_map *(*fn_bmap)(__isl_take isl_basic_map *bmap)) +{ + int i; + isl_space *space; + + map = isl_map_cow(map); + if (!map) + return NULL; + + for (i = 0; i < map->n; ++i) { + map->p[i] = fn_bmap(map->p[i]); + if (!map->p[i]) + return isl_map_free(map); + } + map = isl_map_unmark_normalized(map); + + space = isl_map_take_space(map); + space = fn_space(space); + map = isl_map_restore_space(map, space); + + return map; +} + +__isl_give isl_map *isl_map_domain_map(__isl_take isl_map *map) +{ + return isl_map_transform(map, &isl_space_domain_map, + &isl_basic_map_domain_map); +} + +__isl_give isl_map *isl_map_range_map(__isl_take isl_map *map) +{ + return isl_map_transform(map, &isl_space_range_map, + &isl_basic_map_range_map); +} + +/* Given a wrapped map of the form A[B -> C], + * return the map A[B -> C] -> B. + */ +__isl_give isl_map *isl_set_wrapped_domain_map(__isl_take isl_set *set) +{ + isl_id *id; + isl_map *map; + + if (!set) + return NULL; + if (!isl_set_has_tuple_id(set)) + return isl_map_domain_map(isl_set_unwrap(set)); + + id = isl_set_get_tuple_id(set); + map = isl_map_domain_map(isl_set_unwrap(set)); + map = isl_map_set_tuple_id(map, isl_dim_in, id); + + return map; +} + +__isl_give isl_basic_map *isl_basic_map_from_domain( + __isl_take isl_basic_set *bset) +{ + return isl_basic_map_reverse(isl_basic_map_from_range(bset)); +} + +__isl_give isl_basic_map *isl_basic_map_from_range( + __isl_take isl_basic_set *bset) +{ + isl_space *space; + space = isl_basic_set_get_space(bset); + space = isl_space_from_range(space); + bset = isl_basic_set_reset_space(bset, space); + return bset_to_bmap(bset); +} + +/* Create a relation with the given set as range. + * The domain of the created relation is a zero-dimensional + * flat anonymous space. + */ +__isl_give isl_map *isl_map_from_range(__isl_take isl_set *set) +{ + isl_space *space; + space = isl_set_get_space(set); + space = isl_space_from_range(space); + set = isl_set_reset_space(set, space); + return set_to_map(set); +} + +/* Create a relation with the given set as domain. + * The range of the created relation is a zero-dimensional + * flat anonymous space. + */ +__isl_give isl_map *isl_map_from_domain(__isl_take isl_set *set) +{ + return isl_map_reverse(isl_map_from_range(set)); +} + +__isl_give isl_basic_map *isl_basic_map_from_domain_and_range( + __isl_take isl_basic_set *domain, __isl_take isl_basic_set *range) +{ + return isl_basic_map_apply_range(isl_basic_map_reverse(domain), range); +} + +__isl_give isl_map *isl_map_from_domain_and_range(__isl_take isl_set *domain, + __isl_take isl_set *range) +{ + return isl_map_apply_range(isl_map_reverse(domain), range); +} + +/* Return a newly allocated isl_map with given space and flags and + * room for "n" basic maps. + * Make sure that all cached information is cleared. + */ +__isl_give isl_map *isl_map_alloc_space(__isl_take isl_space *space, int n, + unsigned flags) +{ + struct isl_map *map; + + if (!space) + return NULL; + if (n < 0) + isl_die(space->ctx, isl_error_internal, + "negative number of basic maps", goto error); + map = isl_calloc(space->ctx, struct isl_map, + sizeof(struct isl_map) + + (n - 1) * sizeof(struct isl_basic_map *)); + if (!map) + goto error; + + map->ctx = space->ctx; + isl_ctx_ref(map->ctx); + map->ref = 1; + map->size = n; + map->n = 0; + map->dim = space; + map->flags = flags; + return map; +error: + isl_space_free(space); + return NULL; +} + +__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(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 *space) +{ + struct isl_basic_set *bset; + 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 *space) +{ + struct isl_basic_map *bmap; + 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 *space) +{ + struct isl_basic_set *bset; + bset = isl_basic_set_alloc_space(space, 0, 0, 0); + bset = isl_basic_set_finalize(bset); + return bset; +} + +__isl_give isl_basic_map *isl_basic_map_nat_universe( + __isl_take isl_space *space) +{ + int i; + isl_size total = isl_space_dim(space, isl_dim_all); + isl_basic_map *bmap; + + if (total < 0) + space = isl_space_free(space); + bmap = isl_basic_map_alloc_space(space, 0, 0, total); + for (i = 0; i < total; ++i) { + int k = isl_basic_map_alloc_inequality(bmap); + if (k < 0) + goto error; + isl_seq_clr(bmap->ineq[k], 1 + total); + isl_int_set_si(bmap->ineq[k][1 + i], 1); + } + return bmap; +error: + isl_basic_map_free(bmap); + return NULL; +} + +__isl_give isl_basic_set *isl_basic_set_nat_universe( + __isl_take isl_space *space) +{ + return isl_basic_map_nat_universe(space); +} + +__isl_give isl_map *isl_map_nat_universe(__isl_take isl_space *space) +{ + return isl_map_from_basic_map(isl_basic_map_nat_universe(space)); +} + +__isl_give isl_set *isl_set_nat_universe(__isl_take isl_space *space) +{ + return isl_map_nat_universe(space); +} + +__isl_give isl_map *isl_map_empty(__isl_take isl_space *space) +{ + return isl_map_alloc_space(space, 0, ISL_MAP_DISJOINT); +} + +__isl_give isl_set *isl_set_empty(__isl_take isl_space *space) +{ + return isl_set_alloc_space(space, 0, ISL_MAP_DISJOINT); +} + +__isl_give isl_map *isl_map_universe(__isl_take isl_space *space) +{ + struct isl_map *map; + if (!space) + return NULL; + 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; +} + +/* This function performs the same operation as isl_map_universe, + * but is considered as a function on an isl_space when exported. + */ +__isl_give isl_map *isl_space_universe_map(__isl_take isl_space *space) +{ + return isl_map_universe(space); +} + +__isl_give isl_set *isl_set_universe(__isl_take isl_space *space) +{ + struct isl_set *set; + if (!space) + return NULL; + 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; +} + +/* This function performs the same operation as isl_set_universe, + * but is considered as a function on an isl_space when exported. + */ +__isl_give isl_set *isl_space_universe_set(__isl_take isl_space *space) +{ + return isl_set_universe(space); +} + +__isl_give isl_map *isl_map_dup(__isl_keep isl_map *map) +{ + int i; + struct isl_map *dup; + + if (!map) + return NULL; + dup = isl_map_alloc_space(isl_space_copy(map->dim), map->n, map->flags); + for (i = 0; i < map->n; ++i) + dup = isl_map_add_basic_map(dup, isl_basic_map_copy(map->p[i])); + return dup; +} + +__isl_give isl_map *isl_map_add_basic_map(__isl_take isl_map *map, + __isl_take isl_basic_map *bmap) +{ + if (!bmap || !map) + goto error; + if (isl_basic_map_plain_is_empty(bmap)) { + isl_basic_map_free(bmap); + return map; + } + if (isl_map_basic_map_check_equal_space(map, bmap) < 0) + goto error; + isl_assert(map->ctx, map->n < map->size, goto error); + map->p[map->n] = bmap; + map->n++; + map = isl_map_unmark_normalized(map); + return map; +error: + if (map) + isl_map_free(map); + if (bmap) + isl_basic_map_free(bmap); + return NULL; +} + +__isl_null isl_map *isl_map_free(__isl_take isl_map *map) +{ + int i; + + if (!map) + return NULL; + + if (--map->ref > 0) + return NULL; + + clear_caches(map); + isl_ctx_deref(map->ctx); + for (i = 0; i < map->n; ++i) + isl_basic_map_free(map->p[i]); + isl_space_free(map->dim); + free(map); + + return NULL; +} + +static __isl_give isl_basic_map *isl_basic_map_fix_pos_si( + __isl_take isl_basic_map *bmap, unsigned pos, int value) +{ + int j; + isl_size total; + + total = isl_basic_map_dim(bmap, isl_dim_all); + if (total < 0) + return isl_basic_map_free(bmap); + + bmap = isl_basic_map_cow(bmap); + bmap = isl_basic_map_extend_constraints(bmap, 1, 0); + j = isl_basic_map_alloc_equality(bmap); + if (j < 0) + goto error; + isl_seq_clr(bmap->eq[j] + 1, total); + isl_int_set_si(bmap->eq[j][pos], -1); + isl_int_set_si(bmap->eq[j][0], value); + bmap = isl_basic_map_simplify(bmap); + return isl_basic_map_finalize(bmap); +error: + isl_basic_map_free(bmap); + return NULL; +} + +static __isl_give isl_basic_map *isl_basic_map_fix_pos( + __isl_take isl_basic_map *bmap, unsigned pos, isl_int value) +{ + int j; + isl_size total; + + total = isl_basic_map_dim(bmap, isl_dim_all); + if (total < 0) + return isl_basic_map_free(bmap); + + bmap = isl_basic_map_cow(bmap); + bmap = isl_basic_map_extend_constraints(bmap, 1, 0); + j = isl_basic_map_alloc_equality(bmap); + if (j < 0) + goto error; + isl_seq_clr(bmap->eq[j] + 1, total); + isl_int_set_si(bmap->eq[j][pos], -1); + isl_int_set(bmap->eq[j][0], value); + bmap = isl_basic_map_simplify(bmap); + return isl_basic_map_finalize(bmap); +error: + isl_basic_map_free(bmap); + return NULL; +} + +__isl_give isl_basic_map *isl_basic_map_fix_si(__isl_take isl_basic_map *bmap, + enum isl_dim_type type, unsigned pos, int value) +{ + if (isl_basic_map_check_range(bmap, type, pos, 1) < 0) + return isl_basic_map_free(bmap); + return isl_basic_map_fix_pos_si(bmap, + isl_basic_map_offset(bmap, type) + pos, value); +} + +__isl_give isl_basic_map *isl_basic_map_fix(__isl_take isl_basic_map *bmap, + enum isl_dim_type type, unsigned pos, isl_int value) +{ + if (isl_basic_map_check_range(bmap, type, pos, 1) < 0) + return isl_basic_map_free(bmap); + return isl_basic_map_fix_pos(bmap, + isl_basic_map_offset(bmap, type) + pos, value); +} + +/* Fix the value of the variable at position "pos" of type "type" of "bmap" + * to be equal to "v". + */ +__isl_give isl_basic_map *isl_basic_map_fix_val(__isl_take isl_basic_map *bmap, + enum isl_dim_type type, unsigned pos, __isl_take isl_val *v) +{ + if (!bmap || !v) + goto error; + if (!isl_val_is_int(v)) + isl_die(isl_basic_map_get_ctx(bmap), isl_error_invalid, + "expecting integer value", goto error); + if (isl_basic_map_check_range(bmap, type, pos, 1) < 0) + goto error; + pos += isl_basic_map_offset(bmap, type); + bmap = isl_basic_map_fix_pos(bmap, pos, v->n); + isl_val_free(v); + return bmap; +error: + isl_basic_map_free(bmap); + isl_val_free(v); + return NULL; +} + +/* Fix the value of the variable at position "pos" of type "type" of "bset" + * to be equal to "v". + */ +__isl_give isl_basic_set *isl_basic_set_fix_val(__isl_take isl_basic_set *bset, + enum isl_dim_type type, unsigned pos, __isl_take isl_val *v) +{ + return isl_basic_map_fix_val(bset, type, pos, v); +} + +__isl_give isl_basic_set *isl_basic_set_fix_si(__isl_take isl_basic_set *bset, + enum isl_dim_type type, unsigned pos, int value) +{ + return bset_from_bmap(isl_basic_map_fix_si(bset_to_bmap(bset), + type, pos, value)); +} + +__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) +{ + return bset_from_bmap(isl_basic_map_fix(bset_to_bmap(bset), + type, pos, value)); +} + +/* Remove the basic map at position "i" from "map" if this basic map + * is (obviously) empty. + */ +static __isl_give isl_map *remove_if_empty(__isl_take isl_map *map, int i) +{ + isl_bool empty; + + if (!map) + return NULL; + + empty = isl_basic_map_plain_is_empty(map->p[i]); + if (empty < 0) + return isl_map_free(map); + if (!empty) + return map; + + isl_basic_map_free(map->p[i]); + map->n--; + if (i != map->n) { + map->p[i] = map->p[map->n]; + map = isl_map_unmark_normalized(map); + + } + + return map; +} + +/* Perform "fn" on each basic map of "map", where we may not be holding + * the only reference to "map". + * In particular, "fn" should be a semantics preserving operation + * that we want to apply to all copies of "map". We therefore need + * to be careful not to modify "map" in a way that breaks "map" + * in case anything goes wrong. + */ +__isl_give isl_map *isl_map_inline_foreach_basic_map(__isl_take isl_map *map, + __isl_give isl_basic_map *(*fn)(__isl_take isl_basic_map *bmap)) +{ + struct isl_basic_map *bmap; + int i; + + if (!map) + return NULL; + + for (i = map->n - 1; i >= 0; --i) { + bmap = isl_basic_map_copy(map->p[i]); + bmap = fn(bmap); + if (!bmap) + goto error; + isl_basic_map_free(map->p[i]); + map->p[i] = bmap; + map = remove_if_empty(map, i); + if (!map) + return NULL; + } + + return map; +error: + isl_map_free(map); + return NULL; +} + +__isl_give isl_map *isl_map_fix_si(__isl_take isl_map *map, + enum isl_dim_type type, unsigned pos, int value) +{ + int i; + + map = isl_map_cow(map); + if (isl_map_check_range(map, type, pos, 1) < 0) + return isl_map_free(map); + for (i = map->n - 1; i >= 0; --i) { + map->p[i] = isl_basic_map_fix_si(map->p[i], type, pos, value); + map = remove_if_empty(map, i); + if (!map) + return NULL; + } + map = isl_map_unmark_normalized(map); + return map; +} + +__isl_give isl_set *isl_set_fix_si(__isl_take isl_set *set, + enum isl_dim_type type, unsigned pos, int value) +{ + return set_from_map(isl_map_fix_si(set_to_map(set), type, pos, value)); +} + +__isl_give isl_map *isl_map_fix(__isl_take isl_map *map, + enum isl_dim_type type, unsigned pos, isl_int value) +{ + int i; + + map = isl_map_cow(map); + if (isl_map_check_range(map, type, pos, 1) < 0) + return isl_map_free(map); + for (i = 0; i < map->n; ++i) { + map->p[i] = isl_basic_map_fix(map->p[i], type, pos, value); + if (!map->p[i]) + goto error; + } + map = isl_map_unmark_normalized(map); + return map; +error: + isl_map_free(map); + return NULL; +} + +__isl_give isl_set *isl_set_fix(__isl_take isl_set *set, + enum isl_dim_type type, unsigned pos, isl_int value) +{ + return set_from_map(isl_map_fix(set_to_map(set), type, pos, value)); +} + +/* Fix the value of the variable at position "pos" of type "type" of "map" + * to be equal to "v". + */ +__isl_give isl_map *isl_map_fix_val(__isl_take isl_map *map, + enum isl_dim_type type, unsigned pos, __isl_take isl_val *v) +{ + int i; + + map = isl_map_cow(map); + if (!map || !v) + goto error; + + if (!isl_val_is_int(v)) + isl_die(isl_map_get_ctx(map), isl_error_invalid, + "expecting integer value", goto error); + if (isl_map_check_range(map, type, pos, 1) < 0) + goto error; + for (i = map->n - 1; i >= 0; --i) { + map->p[i] = isl_basic_map_fix_val(map->p[i], type, pos, + isl_val_copy(v)); + map = remove_if_empty(map, i); + if (!map) + goto error; + } + map = isl_map_unmark_normalized(map); + isl_val_free(v); + return map; +error: + isl_map_free(map); + isl_val_free(v); + return NULL; +} + +/* Fix the value of the variable at position "pos" of type "type" of "set" + * to be equal to "v". + */ +__isl_give isl_set *isl_set_fix_val(__isl_take isl_set *set, + enum isl_dim_type type, unsigned pos, __isl_take isl_val *v) +{ + return isl_map_fix_val(set, type, pos, v); +} + +__isl_give isl_map *isl_map_fix_input_si(__isl_take isl_map *map, + unsigned input, int value) +{ + return isl_map_fix_si(map, isl_dim_in, input, value); +} + +__isl_give isl_set *isl_set_fix_dim_si(__isl_take isl_set *set, unsigned dim, + int value) +{ + return set_from_map(isl_map_fix_si(set_to_map(set), + isl_dim_set, dim, value)); +} + +static __isl_give isl_basic_map *basic_map_bound_si( + __isl_take isl_basic_map *bmap, + enum isl_dim_type type, unsigned pos, int value, int upper) +{ + int j; + isl_size total; + + if (isl_basic_map_check_range(bmap, type, pos, 1) < 0) + return isl_basic_map_free(bmap); + total = isl_basic_map_dim(bmap, isl_dim_all); + if (total < 0) + return isl_basic_map_free(bmap); + pos += isl_basic_map_offset(bmap, type); + bmap = isl_basic_map_cow(bmap); + bmap = isl_basic_map_extend_constraints(bmap, 0, 1); + j = isl_basic_map_alloc_inequality(bmap); + if (j < 0) + goto error; + isl_seq_clr(bmap->ineq[j], 1 + total); + if (upper) { + isl_int_set_si(bmap->ineq[j][pos], -1); + isl_int_set_si(bmap->ineq[j][0], value); + } else { + isl_int_set_si(bmap->ineq[j][pos], 1); + isl_int_set_si(bmap->ineq[j][0], -value); + } + bmap = isl_basic_map_simplify(bmap); + return isl_basic_map_finalize(bmap); +error: + isl_basic_map_free(bmap); + return NULL; +} + +__isl_give isl_basic_map *isl_basic_map_lower_bound_si( + __isl_take isl_basic_map *bmap, + enum isl_dim_type type, unsigned pos, int value) +{ + return basic_map_bound_si(bmap, type, pos, value, 0); +} + +/* Constrain the values of the given dimension to be no greater than "value". + */ +__isl_give isl_basic_map *isl_basic_map_upper_bound_si( + __isl_take isl_basic_map *bmap, + enum isl_dim_type type, unsigned pos, int value) +{ + return basic_map_bound_si(bmap, type, pos, value, 1); +} + +static __isl_give isl_map *map_bound_si(__isl_take isl_map *map, + enum isl_dim_type type, unsigned pos, int value, int upper) +{ + int i; + + map = isl_map_cow(map); + if (isl_map_check_range(map, type, pos, 1) < 0) + return isl_map_free(map); + for (i = 0; i < map->n; ++i) { + map->p[i] = basic_map_bound_si(map->p[i], + type, pos, value, upper); + if (!map->p[i]) + goto error; + } + map = isl_map_unmark_normalized(map); + return map; +error: + isl_map_free(map); + return NULL; +} + +__isl_give isl_map *isl_map_lower_bound_si(__isl_take isl_map *map, + enum isl_dim_type type, unsigned pos, int value) +{ + return map_bound_si(map, type, pos, value, 0); +} + +__isl_give isl_map *isl_map_upper_bound_si(__isl_take isl_map *map, + enum isl_dim_type type, unsigned pos, int value) +{ + return map_bound_si(map, type, pos, value, 1); +} + +__isl_give isl_set *isl_set_lower_bound_si(__isl_take isl_set *set, + enum isl_dim_type type, unsigned pos, int value) +{ + return set_from_map(isl_map_lower_bound_si(set_to_map(set), + type, pos, value)); +} + +__isl_give isl_set *isl_set_upper_bound_si(__isl_take isl_set *set, + enum isl_dim_type type, unsigned pos, int value) +{ + return isl_map_upper_bound_si(set, type, pos, value); +} + +/* Bound the given variable of "bmap" from below (or above is "upper" + * is set) to "value". + */ +static __isl_give isl_basic_map *basic_map_bound( + __isl_take isl_basic_map *bmap, + enum isl_dim_type type, unsigned pos, isl_int value, int upper) +{ + int j; + isl_size total; + + if (isl_basic_map_check_range(bmap, type, pos, 1) < 0) + return isl_basic_map_free(bmap); + total = isl_basic_map_dim(bmap, isl_dim_all); + if (total < 0) + return isl_basic_map_free(bmap); + pos += isl_basic_map_offset(bmap, type); + bmap = isl_basic_map_cow(bmap); + bmap = isl_basic_map_extend_constraints(bmap, 0, 1); + j = isl_basic_map_alloc_inequality(bmap); + if (j < 0) + goto error; + isl_seq_clr(bmap->ineq[j], 1 + total); + if (upper) { + isl_int_set_si(bmap->ineq[j][pos], -1); + isl_int_set(bmap->ineq[j][0], value); + } else { + isl_int_set_si(bmap->ineq[j][pos], 1); + isl_int_neg(bmap->ineq[j][0], value); + } + bmap = isl_basic_map_simplify(bmap); + return isl_basic_map_finalize(bmap); +error: + isl_basic_map_free(bmap); + return NULL; +} + +/* Bound the given variable of "map" from below (or above is "upper" + * is set) to "value". + */ +static __isl_give isl_map *map_bound(__isl_take isl_map *map, + enum isl_dim_type type, unsigned pos, isl_int value, int upper) +{ + int i; + + map = isl_map_cow(map); + if (isl_map_check_range(map, type, pos, 1) < 0) + return isl_map_free(map); + for (i = map->n - 1; i >= 0; --i) { + map->p[i] = basic_map_bound(map->p[i], type, pos, value, upper); + map = remove_if_empty(map, i); + if (!map) + return NULL; + } + map = isl_map_unmark_normalized(map); + return map; +} + +__isl_give isl_map *isl_map_lower_bound(__isl_take isl_map *map, + enum isl_dim_type type, unsigned pos, isl_int value) +{ + return map_bound(map, type, pos, value, 0); +} + +__isl_give isl_map *isl_map_upper_bound(__isl_take isl_map *map, + enum isl_dim_type type, unsigned pos, isl_int value) +{ + return map_bound(map, type, pos, value, 1); +} + +__isl_give isl_set *isl_set_lower_bound(__isl_take isl_set *set, + enum isl_dim_type type, unsigned pos, isl_int value) +{ + return isl_map_lower_bound(set, type, pos, value); +} + +__isl_give isl_set *isl_set_upper_bound(__isl_take isl_set *set, + enum isl_dim_type type, unsigned pos, isl_int value) +{ + return isl_map_upper_bound(set, type, pos, value); +} + +/* Force the values of the variable at position "pos" of type "type" of "map" + * to be no smaller than "value". + */ +__isl_give isl_map *isl_map_lower_bound_val(__isl_take isl_map *map, + enum isl_dim_type type, unsigned pos, __isl_take isl_val *value) +{ + if (!value) + goto error; + if (!isl_val_is_int(value)) + isl_die(isl_map_get_ctx(map), isl_error_invalid, + "expecting integer value", goto error); + map = isl_map_lower_bound(map, type, pos, value->n); + isl_val_free(value); + return map; +error: + isl_val_free(value); + isl_map_free(map); + return NULL; +} + +/* Force the values of the variable at position "pos" of type "type" of "set" + * to be no smaller than "value". + */ +__isl_give isl_set *isl_set_lower_bound_val(__isl_take isl_set *set, + enum isl_dim_type type, unsigned pos, __isl_take isl_val *value) +{ + isl_map *map; + + map = set_to_map(set); + return set_from_map(isl_map_lower_bound_val(map, type, pos, value)); +} + +/* Force the values of the variable at position "pos" of type "type" of "map" + * to be no greater than "value". + */ +__isl_give isl_map *isl_map_upper_bound_val(__isl_take isl_map *map, + enum isl_dim_type type, unsigned pos, __isl_take isl_val *value) +{ + if (!value) + goto error; + if (!isl_val_is_int(value)) + isl_die(isl_map_get_ctx(map), isl_error_invalid, + "expecting integer value", goto error); + map = isl_map_upper_bound(map, type, pos, value->n); + isl_val_free(value); + return map; +error: + isl_val_free(value); + isl_map_free(map); + return NULL; +} + +/* Force the values of the variable at position "pos" of type "type" of "set" + * to be no greater than "value". + */ +__isl_give isl_set *isl_set_upper_bound_val(__isl_take isl_set *set, + enum isl_dim_type type, unsigned pos, __isl_take isl_val *value) +{ + isl_map *map; + + map = set_to_map(set); + return set_from_map(isl_map_upper_bound_val(map, type, pos, value)); +} + +/* If "mv" has an explicit domain, then intersect the domain of "map" + * with this explicit domain. + * + * An isl_multi_val object never has an explicit domain, + * so simply return "map". + */ +static __isl_give isl_map *isl_map_intersect_multi_val_explicit_domain( + __isl_take isl_map *map, __isl_keep isl_multi_val *mv) +{ + return map; +} + +#undef BASE +#define BASE val +#include "isl_map_bound_templ.c" + +/* Apply "map_bound" to "set" with the corresponding value in "bound" + * for each set dimension, by treating the set as a map. + */ +static __isl_give isl_set *set_bound_multi_val(__isl_take isl_set *set, + __isl_take isl_multi_val *bound, + __isl_give isl_map *map_bound(__isl_take isl_map *map, + unsigned pos, __isl_take isl_val *value)) +{ + isl_map *map; + + map = set_to_map(set); + return set_from_map(map_bound_multi_val(map, bound, map_bound)); +} + +#undef BASE +#define BASE pw_aff +#include "isl_map_bound_templ.c" + +/* Apply "map_bound" to "set" with the corresponding value in "bound" + * for each set dimension, by converting the set and the bound + * to objects living in a map space. + */ +static __isl_give isl_set *set_bound_multi_pw_aff(__isl_take isl_set *set, + __isl_take isl_multi_pw_aff *bound, + __isl_give isl_map *set_bound(__isl_take isl_map *map, + unsigned pos, __isl_take TYPE *value)) +{ + isl_map *map; + + map = isl_map_from_range(set); + bound = isl_multi_pw_aff_from_range(bound); + map = map_bound_multi_pw_aff(map, bound, set_bound); + return isl_map_range(map); +} + +/* Wrapper around isl_map_lower_bound_val for use in map_bound_multi_val, + * setting a bound on the given output dimension. + */ +static __isl_give isl_map *map_lower_bound_val(__isl_take isl_map *map, + unsigned pos, __isl_take isl_val *v) +{ + return isl_map_lower_bound_val(map, isl_dim_out, pos, v); +} + +/* Force the values of the set dimensions of "set" + * to be no smaller than the corresponding values in "lower". + */ +__isl_give isl_set *isl_set_lower_bound_multi_val(__isl_take isl_set *set, + __isl_take isl_multi_val *lower) +{ + return set_bound_multi_val(set, lower, &map_lower_bound_val); +} + +/* Wrapper around isl_map_upper_bound_val for use in map_bound_multi_val, + * setting a bound on the given output dimension. + */ +static __isl_give isl_map *map_upper_bound_val(__isl_take isl_map *map, + unsigned pos, __isl_take isl_val *v) +{ + return isl_map_upper_bound_val(map, isl_dim_out, pos, v); +} + +/* Force the values of the set dimensions of "set" + * to be no greater than the corresponding values in "upper". + */ +__isl_give isl_set *isl_set_upper_bound_multi_val(__isl_take isl_set *set, + __isl_take isl_multi_val *upper) +{ + return set_bound_multi_val(set, upper, &map_upper_bound_val); +} + +/* Force the symbolic constant expression "bound" + * to satisfy the relation "order" with respect to + * the output variable at position "pos" of "map". + * + * Create an affine expression representing the output variable + * in terms of the range and + * compare it using "order" to "bound" (defined on the domain). + * The result is a relation between elements in domain and range that + * can be intersected with "map". + */ +static __isl_give isl_map *map_bound_pw_aff(__isl_take isl_map *map, + unsigned pos, __isl_take isl_pw_aff *bound, + __isl_give isl_map *(*order)(__isl_take isl_pw_aff *pa1, + __isl_take isl_pw_aff *pa2)) +{ + isl_space *space; + isl_local_space *ls; + isl_pw_aff *var; + + space = isl_space_range(isl_map_get_space(map)); + ls = isl_local_space_from_space(space); + var = isl_pw_aff_var_on_domain(ls, isl_dim_set, pos); + map = isl_map_intersect(map, order(bound, var)); + return map; +} + +/* Force the values of the output variable at position "pos" of "map" + * to be no smaller than the symbolic constant expression "lower". + */ +static __isl_give isl_map *map_lower_bound_pw_aff(__isl_take isl_map *map, + unsigned pos, __isl_take isl_pw_aff *lower) +{ + return map_bound_pw_aff(map, pos, lower, &isl_pw_aff_le_map); +} + +/* Force the values of the output variable at position "pos" of "map" + * to be no greater than the symbolic constant expression "upper". + */ +static __isl_give isl_map *map_upper_bound_pw_aff(__isl_take isl_map *map, + unsigned pos, __isl_take isl_pw_aff *upper) +{ + return map_bound_pw_aff(map, pos, upper, &isl_pw_aff_ge_map); +} + +/* Force the values of the set dimensions of "set" + * to be no smaller than the corresponding constant symbolic expressions + * in "lower". + */ +__isl_give isl_set *isl_set_lower_bound_multi_pw_aff(__isl_take isl_set *set, + __isl_take isl_multi_pw_aff *lower) +{ + return set_bound_multi_pw_aff(set, lower, &map_lower_bound_pw_aff); +} + +/* Force the values of the set dimensions of "set" + * to be no greater than the corresponding constant symbolic expressions + * in "upper". + */ +__isl_give isl_set *isl_set_upper_bound_multi_pw_aff(__isl_take isl_set *set, + __isl_take isl_multi_pw_aff *upper) +{ + return set_bound_multi_pw_aff(set, upper, &map_upper_bound_pw_aff); +} + +/* Force the values of the output dimensions of "map" + * to be no smaller than the corresponding constant symbolic expressions + * in "lower". + */ +__isl_give isl_map *isl_map_lower_bound_multi_pw_aff(__isl_take isl_map *map, + __isl_take isl_multi_pw_aff *lower) +{ + return map_bound_multi_pw_aff(map, lower, &map_lower_bound_pw_aff); +} + +/* Force the values of the output dimensions of "map" + * to be no greater than the corresponding constant symbolic expressions + * in "upper". + */ +__isl_give isl_map *isl_map_upper_bound_multi_pw_aff(__isl_take isl_map *map, + __isl_take isl_multi_pw_aff *upper) +{ + return map_bound_multi_pw_aff(map, upper, &map_upper_bound_pw_aff); +} + +/* Bound the given variable of "bset" from below (or above is "upper" + * is set) to "value". + */ +static __isl_give isl_basic_set *isl_basic_set_bound( + __isl_take isl_basic_set *bset, enum isl_dim_type type, unsigned pos, + isl_int value, int upper) +{ + return bset_from_bmap(basic_map_bound(bset_to_bmap(bset), + type, pos, value, upper)); +} + +/* Bound the given variable of "bset" from below (or above is "upper" + * is set) to "value". + */ +static __isl_give isl_basic_set *isl_basic_set_bound_val( + __isl_take isl_basic_set *bset, enum isl_dim_type type, unsigned pos, + __isl_take isl_val *value, int upper) +{ + if (!value) + goto error; + if (!isl_val_is_int(value)) + isl_die(isl_basic_set_get_ctx(bset), isl_error_invalid, + "expecting integer value", goto error); + bset = isl_basic_set_bound(bset, type, pos, value->n, upper); + isl_val_free(value); + return bset; +error: + isl_val_free(value); + isl_basic_set_free(bset); + return NULL; +} + +/* Bound the given variable of "bset" from below to "value". + */ +__isl_give isl_basic_set *isl_basic_set_lower_bound_val( + __isl_take isl_basic_set *bset, enum isl_dim_type type, unsigned pos, + __isl_take isl_val *value) +{ + return isl_basic_set_bound_val(bset, type, pos, value, 0); +} + +/* Bound the given variable of "bset" from above to "value". + */ +__isl_give isl_basic_set *isl_basic_set_upper_bound_val( + __isl_take isl_basic_set *bset, enum isl_dim_type type, unsigned pos, + __isl_take isl_val *value) +{ + return isl_basic_set_bound_val(bset, type, pos, value, 1); +} + +__isl_give isl_map *isl_map_reverse(__isl_take isl_map *map) +{ + return isl_map_transform(map, &isl_space_reverse, + &isl_basic_map_reverse); +} + +/* Given a map (A -> B) -> C, return the corresponding map (B -> A) -> C. + */ +__isl_give isl_map *isl_map_domain_reverse(__isl_take isl_map *map) +{ + return isl_map_transform(map, &isl_space_domain_reverse, + &isl_basic_map_domain_reverse); +} + +/* Given a map A -> (B -> C), return the corresponding map A -> (C -> B). + */ +__isl_give isl_map *isl_map_range_reverse(__isl_take isl_map *map) +{ + return isl_map_transform(map, &isl_space_range_reverse, + &isl_basic_map_range_reverse); +} + +/* Given a set (A -> B), return the corresponding set (B -> A). + */ +__isl_give isl_set *isl_set_wrapped_reverse(__isl_take isl_set *set) +{ + isl_map *map = set_to_map(set); + + map = isl_map_transform(map, &isl_space_wrapped_reverse, + &isl_basic_map_set_reverse); + return set_from_map(map); +} + +#undef TYPE +#define TYPE isl_pw_multi_aff +#undef SUFFIX +#define SUFFIX _pw_multi_aff +#undef EMPTY +#define EMPTY isl_pw_multi_aff_empty +#undef ADD +#define ADD isl_pw_multi_aff_union_add +#include "isl_map_lexopt_templ.c" + +/* Given a map "map", compute the lexicographically minimal + * (or maximal) image element for each domain element in dom, + * in the form of an isl_pw_multi_aff. + * If "empty" is not NULL, then set *empty to those elements in dom that + * do not have an image element. + * If "flags" includes ISL_OPT_FULL, then "dom" is NULL and the optimum + * should be computed over the domain of "map". "empty" is also NULL + * in this case. + * + * We first compute the lexicographically minimal or maximal element + * in the first basic map. This results in a partial solution "res" + * and a subset "todo" of dom that still need to be handled. + * We then consider each of the remaining maps in "map" and successively + * update both "res" and "todo". + * If "empty" is NULL, then the todo sets are not needed and therefore + * also not computed. + */ +static __isl_give isl_pw_multi_aff *isl_map_partial_lexopt_aligned_pw_multi_aff( + __isl_take isl_map *map, __isl_take isl_set *dom, + __isl_give isl_set **empty, unsigned flags) +{ + int i; + int full; + isl_pw_multi_aff *res; + isl_set *todo; + + full = ISL_FL_ISSET(flags, ISL_OPT_FULL); + if (!map || (!full && !dom)) + goto error; + + if (isl_map_plain_is_empty(map)) { + if (empty) + *empty = dom; + else + isl_set_free(dom); + return isl_pw_multi_aff_from_map(map); + } + + res = basic_map_partial_lexopt_pw_multi_aff( + isl_basic_map_copy(map->p[0]), + isl_set_copy(dom), empty, flags); + + if (empty) + todo = *empty; + for (i = 1; i < map->n; ++i) { + isl_pw_multi_aff *res_i; + + res_i = basic_map_partial_lexopt_pw_multi_aff( + isl_basic_map_copy(map->p[i]), + isl_set_copy(dom), empty, flags); + + if (ISL_FL_ISSET(flags, ISL_OPT_MAX)) + res = isl_pw_multi_aff_union_lexmax(res, res_i); + else + res = isl_pw_multi_aff_union_lexmin(res, res_i); + + if (empty) + todo = isl_set_intersect(todo, *empty); + } + + isl_set_free(dom); + isl_map_free(map); + + if (empty) + *empty = todo; + + return res; +error: + if (empty) + *empty = NULL; + isl_set_free(dom); + isl_map_free(map); + return NULL; +} + +#undef TYPE +#define TYPE isl_map +#undef SUFFIX +#define SUFFIX +#undef EMPTY +#define EMPTY isl_map_empty +#undef ADD +#define ADD isl_map_union_disjoint +#include "isl_map_lexopt_templ.c" + +/* Given a map "map", compute the lexicographically minimal + * (or maximal) image element for each domain element in "dom", + * in the form of an isl_map. + * If "empty" is not NULL, then set *empty to those elements in "dom" that + * do not have an image element. + * If "flags" includes ISL_OPT_FULL, then "dom" is NULL and the optimum + * should be computed over the domain of "map". "empty" is also NULL + * in this case. + * + * If the input consists of more than one disjunct, then first + * compute the desired result in the form of an isl_pw_multi_aff and + * then convert that into an isl_map. + * + * This function used to have an explicit implementation in terms + * of isl_maps, but it would continually intersect the domains of + * partial results with the complement of the domain of the next + * partial solution, potentially leading to an explosion in the number + * of disjuncts if there are several disjuncts in the input. + * An even earlier implementation of this function would look for + * better results in the domain of the partial result and for extra + * results in the complement of this domain, which would lead to + * even more splintering. + */ +static __isl_give isl_map *isl_map_partial_lexopt_aligned( + __isl_take isl_map *map, __isl_take isl_set *dom, + __isl_give isl_set **empty, unsigned flags) +{ + int full; + struct isl_map *res; + isl_pw_multi_aff *pma; + + full = ISL_FL_ISSET(flags, ISL_OPT_FULL); + if (!map || (!full && !dom)) + goto error; + + if (isl_map_plain_is_empty(map)) { + if (empty) + *empty = dom; + else + isl_set_free(dom); + return map; + } + + if (map->n == 1) { + res = basic_map_partial_lexopt(isl_basic_map_copy(map->p[0]), + dom, empty, flags); + isl_map_free(map); + return res; + } + + pma = isl_map_partial_lexopt_aligned_pw_multi_aff(map, dom, empty, + flags); + return isl_map_from_pw_multi_aff_internal(pma); +error: + if (empty) + *empty = NULL; + isl_set_free(dom); + isl_map_free(map); + return NULL; +} + +__isl_give isl_map *isl_map_partial_lexmax( + __isl_take isl_map *map, __isl_take isl_set *dom, + __isl_give isl_set **empty) +{ + return isl_map_partial_lexopt(map, dom, empty, ISL_OPT_MAX); +} + +__isl_give isl_map *isl_map_partial_lexmin( + __isl_take isl_map *map, __isl_take isl_set *dom, + __isl_give isl_set **empty) +{ + return isl_map_partial_lexopt(map, dom, empty, 0); +} + +__isl_give isl_set *isl_set_partial_lexmin( + __isl_take isl_set *set, __isl_take isl_set *dom, + __isl_give isl_set **empty) +{ + return set_from_map(isl_map_partial_lexmin(set_to_map(set), + dom, empty)); +} + +__isl_give isl_set *isl_set_partial_lexmax( + __isl_take isl_set *set, __isl_take isl_set *dom, + __isl_give isl_set **empty) +{ + return set_from_map(isl_map_partial_lexmax(set_to_map(set), + dom, empty)); +} + +/* Compute the lexicographic minimum (or maximum if "flags" includes + * ISL_OPT_MAX) of "bset" over its parametric domain. + */ +__isl_give isl_set *isl_basic_set_lexopt(__isl_take isl_basic_set *bset, + unsigned flags) +{ + return isl_basic_map_lexopt(bset, flags); +} + +__isl_give isl_map *isl_basic_map_lexmax(__isl_take isl_basic_map *bmap) +{ + return isl_basic_map_lexopt(bmap, ISL_OPT_MAX); +} + +__isl_give isl_set *isl_basic_set_lexmin(__isl_take isl_basic_set *bset) +{ + return set_from_map(isl_basic_map_lexmin(bset_to_bmap(bset))); +} + +__isl_give isl_set *isl_basic_set_lexmax(__isl_take isl_basic_set *bset) +{ + return set_from_map(isl_basic_map_lexmax(bset_to_bmap(bset))); +} + +/* Compute the lexicographic minimum of "bset" over its parametric domain + * for the purpose of quantifier elimination. + * That is, find an explicit representation for all the existentially + * quantified variables in "bset" by computing their lexicographic + * minimum. + */ +static __isl_give isl_set *isl_basic_set_lexmin_compute_divs( + __isl_take isl_basic_set *bset) +{ + return isl_basic_set_lexopt(bset, ISL_OPT_QE); +} + +/* Given a basic map with one output dimension, compute the minimum or + * maximum of that dimension as an isl_pw_aff. + * + * 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_pw_multi_aff *pma; + isl_pw_aff *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; +} + +/* Compute the minimum or maximum of the given output dimension + * as a function of the parameters and the input dimensions, + * but independently of the other output dimensions. + * + * We first project out the other output dimension and then compute + * the "lexicographic" maximum in each basic map, combining the results + * using isl_pw_aff_union_max. + */ +static __isl_give isl_pw_aff *map_dim_opt(__isl_take isl_map *map, int pos, + int max) +{ + int i; + isl_pw_aff *pwaff; + isl_size n_out; + + n_out = isl_map_dim(map, isl_dim_out); + if (n_out < 0) + map = isl_map_free(map); + map = isl_map_project_out(map, isl_dim_out, pos + 1, n_out - (pos + 1)); + map = isl_map_project_out(map, isl_dim_out, 0, pos); + if (!map) + return NULL; + + if (map->n == 0) { + isl_space *space = isl_map_get_space(map); + isl_map_free(map); + return isl_pw_aff_empty(space); + } + + pwaff = basic_map_dim_opt(map->p[0], max); + for (i = 1; i < map->n; ++i) { + isl_pw_aff *pwaff_i; + + pwaff_i = basic_map_dim_opt(map->p[i], max); + pwaff = isl_pw_aff_union_opt(pwaff, pwaff_i, max); + } + + isl_map_free(map); + + return pwaff; +} + +/* Compute the minimum of the given output dimension as a function of the + * parameters and input dimensions, but independently of + * the other output dimensions. + */ +__isl_give isl_pw_aff *isl_map_dim_min(__isl_take isl_map *map, int pos) +{ + return map_dim_opt(map, pos, 0); +} + +/* Compute the maximum of the given output dimension as a function of the + * parameters and input dimensions, but independently of + * the other output dimensions. + */ +__isl_give isl_pw_aff *isl_map_dim_max(__isl_take isl_map *map, int pos) +{ + return map_dim_opt(map, pos, 1); +} + +/* Compute the minimum or maximum of the given set dimension + * as a function of the parameters, + * but independently of the other set dimensions. + */ +static __isl_give isl_pw_aff *set_dim_opt(__isl_take isl_set *set, int pos, + int max) +{ + return map_dim_opt(set, pos, max); +} + +/* Compute the maximum of the given set dimension as a function of the + * parameters, but independently of the other set dimensions. + */ +__isl_give isl_pw_aff *isl_set_dim_max(__isl_take isl_set *set, int pos) +{ + return set_dim_opt(set, pos, 1); +} + +/* Compute the minimum of the given set dimension as a function of the + * parameters, but independently of the other set dimensions. + */ +__isl_give isl_pw_aff *isl_set_dim_min(__isl_take isl_set *set, int pos) +{ + return set_dim_opt(set, pos, 0); +} + +/* Apply a preimage specified by "mat" on the parameters of "bset". + * bset is assumed to have only parameters and divs. + */ +static __isl_give isl_basic_set *basic_set_parameter_preimage( + __isl_take isl_basic_set *bset, __isl_take isl_mat *mat) +{ + isl_size nparam; + + nparam = isl_basic_set_dim(bset, isl_dim_param); + if (nparam < 0 || !mat) + goto error; + + bset->dim = isl_space_cow(bset->dim); + if (!bset->dim) + goto error; + + isl_assert(bset->ctx, mat->n_row == 1 + nparam, goto error); + + bset->dim->nparam = 0; + bset->dim->n_out = nparam; + bset = isl_basic_set_preimage(bset, mat); + if (bset) { + bset->dim->nparam = bset->dim->n_out; + bset->dim->n_out = 0; + } + return bset; +error: + isl_mat_free(mat); + isl_basic_set_free(bset); + return NULL; +} + +/* Apply a preimage specified by "mat" on the parameters of "set". + * set is assumed to have only parameters and divs. + */ +static __isl_give isl_set *set_parameter_preimage(__isl_take isl_set *set, + __isl_take isl_mat *mat) +{ + isl_space *space; + isl_size nparam; + + nparam = isl_set_dim(set, isl_dim_param); + if (nparam < 0 || !mat) + goto error; + + if (mat->n_row != 1 + nparam) + isl_die(isl_set_get_ctx(set), isl_error_internal, + "unexpected number of rows", goto error); + + space = isl_set_get_space(set); + space = isl_space_move_dims(space, isl_dim_set, 0, + isl_dim_param, 0, nparam); + set = isl_set_reset_space(set, space); + set = isl_set_preimage(set, mat); + nparam = isl_set_dim(set, isl_dim_out); + if (nparam < 0) + set = isl_set_free(set); + space = isl_set_get_space(set); + space = isl_space_move_dims(space, isl_dim_param, 0, + isl_dim_out, 0, nparam); + set = isl_set_reset_space(set, space); + return set; +error: + isl_mat_free(mat); + isl_set_free(set); + return NULL; +} + +/* Intersect the basic set "bset" with the affine space specified by the + * equalities in "eq". + */ +static __isl_give isl_basic_set *basic_set_append_equalities( + __isl_take isl_basic_set *bset, __isl_take isl_mat *eq) +{ + int i, k; + unsigned len; + + if (!bset || !eq) + goto error; + + bset = isl_basic_set_extend(bset, 0, eq->n_row, 0); + if (!bset) + goto error; + + len = isl_basic_set_offset(bset, isl_dim_div) + bset->extra; + for (i = 0; i < eq->n_row; ++i) { + k = isl_basic_set_alloc_equality(bset); + if (k < 0) + goto error; + isl_seq_cpy(bset->eq[k], eq->row[i], eq->n_col); + isl_seq_clr(bset->eq[k] + eq->n_col, len - eq->n_col); + } + isl_mat_free(eq); + + bset = isl_basic_set_gauss(bset, NULL); + bset = isl_basic_set_finalize(bset); + + return bset; +error: + isl_mat_free(eq); + isl_basic_set_free(bset); + return NULL; +} + +/* Intersect the set "set" with the affine space specified by the + * equalities in "eq". + */ +static __isl_give isl_set *set_append_equalities(__isl_take isl_set *set, + __isl_take isl_mat *eq) +{ + int i; + + if (!set || !eq) + goto error; + + for (i = 0; i < set->n; ++i) { + set->p[i] = basic_set_append_equalities(set->p[i], + isl_mat_copy(eq)); + if (!set->p[i]) + goto error; + } + isl_mat_free(eq); + return set; +error: + isl_mat_free(eq); + isl_set_free(set); + return NULL; +} + +/* Given a basic set "bset" that only involves parameters and existentially + * quantified variables, return the index of the first equality + * that only involves parameters. If there is no such equality then + * return bset->n_eq. + * + * This function assumes that isl_basic_set_gauss has been called on "bset". + */ +static int first_parameter_equality(__isl_keep isl_basic_set *bset) +{ + int i, j; + isl_size nparam, n_div; + + nparam = isl_basic_set_dim(bset, isl_dim_param); + n_div = isl_basic_set_dim(bset, isl_dim_div); + if (nparam < 0 || n_div < 0) + return -1; + + for (i = 0, j = n_div - 1; i < bset->n_eq && j >= 0; --j) { + if (!isl_int_is_zero(bset->eq[i][1 + nparam + j])) + ++i; + } + + return i; +} + +/* Compute an explicit representation for the existentially quantified + * variables in "bset" by computing the "minimal value" of the set + * variables. Since there are no set variables, the computation of + * the minimal value essentially computes an explicit representation + * of the non-empty part(s) of "bset". + * + * The input only involves parameters and existentially quantified variables. + * All equalities among parameters have been removed. + * + * Since the existentially quantified variables in the result are in general + * going to be different from those in the input, we first replace + * them by the minimal number of variables based on their equalities. + * This should simplify the parametric integer programming. + */ +static __isl_give isl_set *base_compute_divs(__isl_take isl_basic_set *bset) +{ + isl_morph *morph1, *morph2; + isl_set *set; + isl_size n; + + if (!bset) + return NULL; + if (bset->n_eq == 0) + return isl_basic_set_lexmin_compute_divs(bset); + + morph1 = isl_basic_set_parameter_compression(bset); + bset = isl_morph_basic_set(isl_morph_copy(morph1), bset); + bset = isl_basic_set_lift(bset); + morph2 = isl_basic_set_variable_compression(bset, isl_dim_set); + bset = isl_morph_basic_set(morph2, bset); + n = isl_basic_set_dim(bset, isl_dim_set); + if (n < 0) + bset = isl_basic_set_free(bset); + bset = isl_basic_set_project_out(bset, isl_dim_set, 0, n); + + set = isl_basic_set_lexmin_compute_divs(bset); + + set = isl_morph_set(isl_morph_inverse(morph1), set); + + return set; +} + +/* Project the given basic set onto its parameter domain, possibly introducing + * new, explicit, existential variables in the constraints. + * The input has parameters and (possibly implicit) existential variables. + * The output has the same parameters, but only + * explicit existentially quantified variables. + * + * The actual projection is performed by pip, but pip doesn't seem + * to like equalities very much, so we first remove the equalities + * among the parameters by performing a variable compression on + * the parameters. Afterward, an inverse transformation is performed + * and the equalities among the parameters are inserted back in. + * + * The variable compression on the parameters may uncover additional + * equalities that were only implicit before. We therefore check + * if there are any new parameter equalities in the result and + * if so recurse. The removal of parameter equalities is required + * for the parameter compression performed by base_compute_divs. + */ +static __isl_give isl_set *parameter_compute_divs( + __isl_take isl_basic_set *bset) +{ + int i; + struct isl_mat *eq; + struct isl_mat *T, *T2; + struct isl_set *set; + isl_size nparam; + + bset = isl_basic_set_cow(bset); + if (!bset) + return NULL; + + if (bset->n_eq == 0) + return base_compute_divs(bset); + + bset = isl_basic_set_gauss(bset, NULL); + if (!bset) + return NULL; + if (isl_basic_set_plain_is_empty(bset)) + return isl_set_from_basic_set(bset); + + i = first_parameter_equality(bset); + if (i == bset->n_eq) + return base_compute_divs(bset); + + nparam = isl_basic_set_dim(bset, isl_dim_param); + if (nparam < 0) + return isl_set_from_basic_set(isl_basic_set_free(bset)); + eq = isl_mat_sub_alloc6(bset->ctx, bset->eq, i, bset->n_eq - i, + 0, 1 + nparam); + eq = isl_mat_cow(eq); + T = isl_mat_variable_compression(isl_mat_copy(eq), &T2); + if (T && T->n_col == 0) { + isl_mat_free(T); + isl_mat_free(T2); + isl_mat_free(eq); + bset = isl_basic_set_set_to_empty(bset); + return isl_set_from_basic_set(bset); + } + bset = basic_set_parameter_preimage(bset, T); + + i = first_parameter_equality(bset); + if (!bset) + set = NULL; + else if (i == bset->n_eq) + set = base_compute_divs(bset); + else + set = parameter_compute_divs(bset); + set = set_parameter_preimage(set, T2); + set = set_append_equalities(set, eq); + return set; +} + +/* Insert the divs from "ls" before those of "bmap". + * + * The number of columns is not changed, which means that the last + * dimensions of "bmap" are being reintepreted as the divs from "ls". + * The caller is responsible for removing the same number of dimensions + * from the space of "bmap". + */ +static __isl_give isl_basic_map *insert_divs_from_local_space( + __isl_take isl_basic_map *bmap, __isl_keep isl_local_space *ls) +{ + int i; + isl_size n_div; + int old_n_div; + + n_div = isl_local_space_dim(ls, isl_dim_div); + if (n_div < 0) + return isl_basic_map_free(bmap); + if (n_div == 0) + return bmap; + + old_n_div = bmap->n_div; + bmap = insert_div_rows(bmap, n_div); + if (!bmap) + return NULL; + + for (i = 0; i < n_div; ++i) { + isl_seq_cpy(bmap->div[i], ls->div->row[i], ls->div->n_col); + isl_seq_clr(bmap->div[i] + ls->div->n_col, old_n_div); + } + + return bmap; +} + +/* Replace the space of "bmap" by the space and divs of "ls". + * + * If "ls" has any divs, then we simplify the result since we may + * have discovered some additional equalities that could simplify + * the div expressions. + */ +static __isl_give isl_basic_map *basic_replace_space_by_local_space( + __isl_take isl_basic_map *bmap, __isl_take isl_local_space *ls) +{ + isl_size n_div; + + bmap = isl_basic_map_cow(bmap); + n_div = isl_local_space_dim(ls, isl_dim_div); + if (!bmap || n_div < 0) + goto error; + + bmap = insert_divs_from_local_space(bmap, ls); + if (!bmap) + goto error; + + isl_space_free(bmap->dim); + bmap->dim = isl_local_space_get_space(ls); + if (!bmap->dim) + goto error; + + isl_local_space_free(ls); + if (n_div > 0) + bmap = isl_basic_map_simplify(bmap); + bmap = isl_basic_map_finalize(bmap); + return bmap; +error: + isl_basic_map_free(bmap); + isl_local_space_free(ls); + return NULL; +} + +/* Replace the space of "map" by the space and divs of "ls". + */ +static __isl_give isl_map *replace_space_by_local_space(__isl_take isl_map *map, + __isl_take isl_local_space *ls) +{ + int i; + + map = isl_map_cow(map); + if (!map || !ls) + goto error; + + for (i = 0; i < map->n; ++i) { + map->p[i] = basic_replace_space_by_local_space(map->p[i], + isl_local_space_copy(ls)); + if (!map->p[i]) + goto error; + } + isl_space_free(isl_map_take_space(map)); + map = isl_map_restore_space(map, isl_local_space_get_space(ls)); + + isl_local_space_free(ls); + return map; +error: + isl_local_space_free(ls); + isl_map_free(map); + return NULL; +} + +/* Compute an explicit representation for the existentially + * quantified variables for which do not know any explicit representation yet. + * + * We first sort the existentially quantified variables so that the + * existentially quantified variables for which we already have an explicit + * representation are placed before those for which we do not. + * The input dimensions, the output dimensions and the existentially + * quantified variables for which we already have an explicit + * representation are then turned into parameters. + * compute_divs returns a map with the same parameters and + * no input or output dimensions and the dimension specification + * is reset to that of the input, including the existentially quantified + * variables for which we already had an explicit representation. + */ +static __isl_give isl_map *compute_divs(__isl_take isl_basic_map *bmap) +{ + struct isl_basic_set *bset; + struct isl_set *set; + struct isl_map *map; + isl_space *space; + isl_local_space *ls; + isl_size nparam; + isl_size n_in; + isl_size n_out; + int n_known; + int i; + + bmap = isl_basic_map_sort_divs(bmap); + bmap = isl_basic_map_cow(bmap); + if (!bmap) + return NULL; + + n_known = isl_basic_map_first_unknown_div(bmap); + nparam = isl_basic_map_dim(bmap, isl_dim_param); + n_in = isl_basic_map_dim(bmap, isl_dim_in); + n_out = isl_basic_map_dim(bmap, isl_dim_out); + if (n_known < 0 || nparam < 0 || n_in < 0 || n_out < 0) + return isl_map_from_basic_map(isl_basic_map_free(bmap)); + + space = isl_space_set_alloc(bmap->ctx, + nparam + n_in + n_out + n_known, 0); + if (!space) + goto error; + + ls = isl_basic_map_get_local_space(bmap); + ls = isl_local_space_drop_dims(ls, isl_dim_div, + n_known, bmap->n_div - n_known); + if (n_known > 0) { + for (i = n_known; i < bmap->n_div; ++i) + swap_div(bmap, i - n_known, i); + bmap->n_div -= n_known; + bmap->extra -= n_known; + } + bmap = isl_basic_map_reset_space(bmap, space); + bset = bset_from_bmap(bmap); + + set = parameter_compute_divs(bset); + map = set_to_map(set); + map = replace_space_by_local_space(map, ls); + + return map; +error: + isl_basic_map_free(bmap); + return NULL; +} + +/* Remove the explicit representation of local variable "div", + * if there is any. + */ +__isl_give isl_basic_map *isl_basic_map_mark_div_unknown( + __isl_take isl_basic_map *bmap, int div) +{ + isl_bool unknown; + + unknown = isl_basic_map_div_is_marked_unknown(bmap, div); + if (unknown < 0) + return isl_basic_map_free(bmap); + if (unknown) + return bmap; + + bmap = isl_basic_map_cow(bmap); + if (!bmap) + return NULL; + isl_int_set_si(bmap->div[div][0], 0); + return bmap; +} + +/* Is local variable "div" of "bmap" marked as not having an explicit + * representation? + * Note that even if "div" is not marked in this way and therefore + * has an explicit representation, this representation may still + * depend (indirectly) on other local variables that do not + * have an explicit representation. + */ +isl_bool isl_basic_map_div_is_marked_unknown(__isl_keep isl_basic_map *bmap, + int div) +{ + if (isl_basic_map_check_range(bmap, isl_dim_div, div, 1) < 0) + return isl_bool_error; + return isl_int_is_zero(bmap->div[div][0]); +} + +/* Return the position of the first local variable that does not + * have an explicit representation. + * Return the total number of local variables if they all have + * an explicit representation. + * Return -1 on error. + */ +int isl_basic_map_first_unknown_div(__isl_keep isl_basic_map *bmap) +{ + int i; + + if (!bmap) + return -1; + + for (i = 0; i < bmap->n_div; ++i) { + if (!isl_basic_map_div_is_known(bmap, i)) + return i; + } + return bmap->n_div; +} + +/* Return the position of the first local variable that does not + * have an explicit representation. + * Return the total number of local variables if they all have + * an explicit representation. + * Return -1 on error. + */ +int isl_basic_set_first_unknown_div(__isl_keep isl_basic_set *bset) +{ + return isl_basic_map_first_unknown_div(bset); +} + +/* Does "bmap" have an explicit representation for all local variables? + */ +isl_bool isl_basic_map_divs_known(__isl_keep isl_basic_map *bmap) +{ + int first; + isl_size n; + + n = isl_basic_map_dim(bmap, isl_dim_div); + first = isl_basic_map_first_unknown_div(bmap); + if (n < 0 || first < 0) + return isl_bool_error; + return first == n; +} + +/* Do all basic maps in "map" have an explicit representation + * for all local variables? + */ +isl_bool isl_map_divs_known(__isl_keep isl_map *map) +{ + int i; + + if (!map) + return isl_bool_error; + + for (i = 0; i < map->n; ++i) { + int known = isl_basic_map_divs_known(map->p[i]); + if (known <= 0) + return known; + } + + return isl_bool_true; +} + +/* If bmap contains any unknown divs, then compute explicit + * expressions for them. However, this computation may be + * quite expensive, so first try to remove divs that aren't + * strictly needed. + */ +__isl_give isl_map *isl_basic_map_compute_divs(__isl_take isl_basic_map *bmap) +{ + int known; + struct isl_map *map; + + known = isl_basic_map_divs_known(bmap); + if (known < 0) + goto error; + if (known) + return isl_map_from_basic_map(bmap); + + bmap = isl_basic_map_drop_redundant_divs(bmap); + + known = isl_basic_map_divs_known(bmap); + if (known < 0) + goto error; + if (known) + return isl_map_from_basic_map(bmap); + + map = compute_divs(bmap); + return map; +error: + isl_basic_map_free(bmap); + return NULL; +} + +__isl_give isl_map *isl_map_compute_divs(__isl_take isl_map *map) +{ + int i; + int known; + struct isl_map *res; + + if (!map) + return NULL; + if (map->n == 0) + return map; + + known = isl_map_divs_known(map); + if (known < 0) { + isl_map_free(map); + return NULL; + } + if (known) + return map; + + res = isl_basic_map_compute_divs(isl_basic_map_copy(map->p[0])); + for (i = 1 ; i < map->n; ++i) { + struct isl_map *r2; + r2 = isl_basic_map_compute_divs(isl_basic_map_copy(map->p[i])); + if (ISL_F_ISSET(map, ISL_MAP_DISJOINT)) + res = isl_map_union_disjoint(res, r2); + else + res = isl_map_union(res, r2); + } + isl_map_free(map); + + return res; +} + +__isl_give isl_set *isl_basic_set_compute_divs(__isl_take isl_basic_set *bset) +{ + return set_from_map(isl_basic_map_compute_divs(bset_to_bmap(bset))); +} + +__isl_give isl_set *isl_set_compute_divs(__isl_take isl_set *set) +{ + return set_from_map(isl_map_compute_divs(set_to_map(set))); +} + +__isl_give isl_set *isl_map_domain(__isl_take isl_map *map) +{ + isl_space *space; + isl_size n_out; + + n_out = isl_map_dim(map, isl_dim_out); + if (n_out < 0) + return set_from_map(isl_map_free(map)); + space = isl_space_domain(isl_map_get_space(map)); + + map = isl_map_project_out(map, isl_dim_out, 0, n_out); + + return set_from_map(isl_map_reset_space(map, space)); +} + +/* Return the union of "map1" and "map2", where we assume for now that + * "map1" and "map2" are disjoint. Note that the basic maps inside + * "map1" or "map2" may not be disjoint from each other. + * Also note that this function is also called from isl_map_union, + * which takes care of handling the situation where "map1" and "map2" + * may not be disjoint. + * + * If one of the inputs is empty, we can simply return the other input. + * Similarly, if one of the inputs is universal, then it is equal to the union. + */ +static __isl_give isl_map *map_union_disjoint(__isl_take isl_map *map1, + __isl_take isl_map *map2) +{ + int i; + unsigned flags = 0; + struct isl_map *map = NULL; + int is_universe; + + if (isl_map_check_equal_space(map1, map2) < 0) + goto error; + + if (map1->n == 0) { + isl_map_free(map1); + return map2; + } + if (map2->n == 0) { + isl_map_free(map2); + return map1; + } + + is_universe = isl_map_plain_is_universe(map1); + if (is_universe < 0) + goto error; + if (is_universe) { + isl_map_free(map2); + return map1; + } + + is_universe = isl_map_plain_is_universe(map2); + if (is_universe < 0) + goto error; + if (is_universe) { + isl_map_free(map1); + return map2; + } + + if (ISL_F_ISSET(map1, ISL_MAP_DISJOINT) && + ISL_F_ISSET(map2, ISL_MAP_DISJOINT)) + ISL_FL_SET(flags, ISL_MAP_DISJOINT); + + map = isl_map_alloc_space(isl_space_copy(map1->dim), + map1->n + map2->n, flags); + if (!map) + goto error; + for (i = 0; i < map1->n; ++i) { + map = isl_map_add_basic_map(map, + isl_basic_map_copy(map1->p[i])); + if (!map) + goto error; + } + for (i = 0; i < map2->n; ++i) { + map = isl_map_add_basic_map(map, + isl_basic_map_copy(map2->p[i])); + if (!map) + goto error; + } + isl_map_free(map1); + isl_map_free(map2); + return map; +error: + isl_map_free(map); + isl_map_free(map1); + isl_map_free(map2); + return NULL; +} + +/* Return the union of "map1" and "map2", where "map1" and "map2" are + * guaranteed to be disjoint by the caller. + * + * Note that this functions is called from within isl_map_make_disjoint, + * so we have to be careful not to touch the constraints of the inputs + * in any way. + */ +__isl_give isl_map *isl_map_union_disjoint(__isl_take isl_map *map1, + __isl_take isl_map *map2) +{ + isl_map_align_params_bin(&map1, &map2); + return map_union_disjoint(map1, map2); +} + +/* Return the union of "map1" and "map2", where "map1" and "map2" may + * not be disjoint. + * + * We currently simply call map_union_disjoint, the internal operation + * of which does not really depend on the inputs being disjoint. + * If the result contains more than one basic map, then we clear + * the disjoint flag since the result may contain basic maps from + * both inputs and these are not guaranteed to be disjoint. + * + * As a special case, if "map1" and "map2" are obviously equal, + * then we simply return "map1". + */ +__isl_give isl_map *isl_map_union(__isl_take isl_map *map1, + __isl_take isl_map *map2) +{ + int equal; + + if (isl_map_align_params_bin(&map1, &map2) < 0) + goto error; + + equal = isl_map_plain_is_equal(map1, map2); + if (equal < 0) + goto error; + if (equal) { + isl_map_free(map2); + return map1; + } + + map1 = map_union_disjoint(map1, map2); + if (!map1) + return NULL; + if (map1->n > 1) + ISL_F_CLR(map1, ISL_MAP_DISJOINT); + return map1; +error: + isl_map_free(map1); + isl_map_free(map2); + return NULL; +} + +__isl_give isl_set *isl_set_union_disjoint( + __isl_take isl_set *set1, __isl_take isl_set *set2) +{ + return set_from_map(isl_map_union_disjoint(set_to_map(set1), + set_to_map(set2))); +} + +__isl_give isl_set *isl_set_union(__isl_take isl_set *set1, + __isl_take isl_set *set2) +{ + return set_from_map(isl_map_union(set_to_map(set1), set_to_map(set2))); +} + +/* Apply "fn" to pairs of elements from "map" and "set" and collect + * the results in a map living in "space". + * + * "map" and "set" are assumed to be compatible and non-NULL. + */ +static __isl_give isl_map *map_intersect_set(__isl_take isl_map *map, + __isl_take isl_space *space, __isl_take isl_set *set, + __isl_give isl_basic_map *fn(__isl_take isl_basic_map *bmap, + __isl_take isl_basic_set *bset)) +{ + unsigned flags = 0; + struct isl_map *result; + int i, j; + + if (isl_set_plain_is_universe(set)) { + isl_set_free(set); + return isl_map_reset_equal_dim_space(map, space); + } + + if (ISL_F_ISSET(map, ISL_MAP_DISJOINT) && + ISL_F_ISSET(set, ISL_MAP_DISJOINT)) + ISL_FL_SET(flags, ISL_MAP_DISJOINT); + + result = isl_map_alloc_space(space, map->n * set->n, flags); + for (i = 0; result && i < map->n; ++i) + for (j = 0; j < set->n; ++j) { + result = isl_map_add_basic_map(result, + fn(isl_basic_map_copy(map->p[i]), + isl_basic_set_copy(set->p[j]))); + if (!result) + break; + } + + isl_map_free(map); + isl_set_free(set); + return result; +} + +__isl_give isl_map *isl_map_intersect_range(__isl_take isl_map *map, + __isl_take isl_set *set) +{ + isl_bool ok; + isl_space *space; + + isl_map_align_params_set(&map, &set); + ok = isl_map_compatible_range(map, set); + if (ok < 0) + goto error; + if (!ok) + isl_die(set->ctx, isl_error_invalid, + "incompatible spaces", goto error); + + space = isl_map_get_space(map); + return map_intersect_set(map, space, set, + &isl_basic_map_intersect_range); +error: + isl_map_free(map); + isl_set_free(set); + return NULL; +} + +/* Intersect the domain of "map" with "set". + * + * If the domain dimensions of "map" do not have any identifiers, + * then copy them over from "set". + */ +__isl_give isl_map *isl_map_intersect_domain(__isl_take isl_map *map, + __isl_take isl_set *set) +{ + isl_bool ok; + isl_space *space; + + isl_map_align_params_set(&map, &set); + ok = isl_map_compatible_domain(map, set); + if (ok < 0) + goto error; + if (!ok) + isl_die(set->ctx, isl_error_invalid, + "incompatible spaces", goto error); + + space = isl_map_get_space(map); + space = isl_space_copy_ids_if_unset(space, isl_dim_in, + isl_set_peek_space(set), isl_dim_set); + return map_intersect_set(map, space, set, + &isl_basic_map_intersect_domain); +error: + isl_map_free(map); + isl_set_free(set); + return NULL; +} + +#undef BASE +#define BASE map +static +#include "isl_copy_tuple_id_templ.c" + +/* Data structure that specifies how isl_map_intersect_factor + * should operate. + * + * "preserve_type" is the tuple where the factor differs from + * the input map and of which the identifiers needs + * to be preserved explicitly. + * "other_factor" is used to extract the space of the other factor + * from the space of the product ("map"). + * "product" is used to combine the given factor and a universe map + * in the space returned by "other_factor" to produce a map + * that lives in the same space as the input map. + */ +struct isl_intersect_factor_control { + enum isl_dim_type preserve_type; + __isl_give isl_space *(*other_factor)(__isl_take isl_space *space); + __isl_give isl_map *(*product)(__isl_take isl_map *factor, + __isl_take isl_map *other); +}; + +/* Given a map "map" in some product space and a map "factor" + * living in some factor space, return the intersection. + * + * After aligning the parameters, + * the map "factor" is first extended to a map living in the same space + * as "map" and then a regular intersection is computed. + * + * Note that the extension is computed as a product, which is anonymous + * by default. If "map" has an identifier on the corresponding tuple, + * then this identifier needs to be set on the product + * before the intersection is computed. + */ +static __isl_give isl_map *isl_map_intersect_factor( + __isl_take isl_map *map, __isl_take isl_map *factor, + struct isl_intersect_factor_control *control) +{ + isl_bool equal; + isl_space *space; + isl_map *other, *product; + + equal = isl_map_has_equal_params(map, factor); + if (equal < 0) + goto error; + if (!equal) { + map = isl_map_align_params(map, isl_map_get_space(factor)); + factor = isl_map_align_params(factor, isl_map_get_space(map)); + } + + space = isl_map_get_space(map); + other = isl_map_universe(control->other_factor(space)); + product = control->product(factor, other); + + space = isl_map_peek_space(map); + product = isl_map_copy_tuple_id(product, control->preserve_type, + space, control->preserve_type); + return map_intersect(map, product); +error: + isl_map_free(map); + isl_map_free(factor); + return NULL; +} + +/* Return the domain product of "map2" and "map1". + */ +static __isl_give isl_map *isl_map_reverse_domain_product( + __isl_take isl_map *map1, __isl_take isl_map *map2) +{ + return isl_map_domain_product(map2, map1); +} + +/* Return the range product of "map2" and "map1". + */ +static __isl_give isl_map *isl_map_reverse_range_product( + __isl_take isl_map *map1, __isl_take isl_map *map2) +{ + return isl_map_range_product(map2, map1); +} + +/* Given a map "map" in a space [A -> B] -> C and a map "factor" + * in the space A -> C, return the intersection. + */ +__isl_give isl_map *isl_map_intersect_domain_factor_domain( + __isl_take isl_map *map, __isl_take isl_map *factor) +{ + struct isl_intersect_factor_control control = { + .preserve_type = isl_dim_in, + .other_factor = isl_space_domain_factor_range, + .product = isl_map_domain_product, + }; + + return isl_map_intersect_factor(map, factor, &control); +} + +/* Given a map "map" in a space [A -> B] -> C and a map "factor" + * in the space B -> C, return the intersection. + */ +__isl_give isl_map *isl_map_intersect_domain_factor_range( + __isl_take isl_map *map, __isl_take isl_map *factor) +{ + struct isl_intersect_factor_control control = { + .preserve_type = isl_dim_in, + .other_factor = isl_space_domain_factor_domain, + .product = isl_map_reverse_domain_product, + }; + + return isl_map_intersect_factor(map, factor, &control); +} + +/* Given a map "map" in a space A -> [B -> C] and a map "factor" + * in the space A -> B, return the intersection. + */ +__isl_give isl_map *isl_map_intersect_range_factor_domain( + __isl_take isl_map *map, __isl_take isl_map *factor) +{ + struct isl_intersect_factor_control control = { + .preserve_type = isl_dim_out, + .other_factor = isl_space_range_factor_range, + .product = isl_map_range_product, + }; + + return isl_map_intersect_factor(map, factor, &control); +} + +/* Given a map "map" in a space A -> [B -> C] and a map "factor" + * in the space A -> C, return the intersection. + */ +__isl_give isl_map *isl_map_intersect_range_factor_range( + __isl_take isl_map *map, __isl_take isl_map *factor) +{ + struct isl_intersect_factor_control control = { + .preserve_type = isl_dim_out, + .other_factor = isl_space_range_factor_domain, + .product = isl_map_reverse_range_product, + }; + + return isl_map_intersect_factor(map, factor, &control); +} + +/* Given a set "set" in a space [A -> B] and a set "domain" + * in the space A, return the intersection. + * + * The set "domain" is first extended to a set living in the space + * [A -> B] and then a regular intersection is computed. + */ +__isl_give isl_set *isl_set_intersect_factor_domain(__isl_take isl_set *set, + __isl_take isl_set *domain) +{ + struct isl_intersect_factor_control control = { + .preserve_type = isl_dim_set, + .other_factor = isl_space_factor_range, + .product = isl_map_range_product, + }; + + return set_from_map(isl_map_intersect_factor(set_to_map(set), + set_to_map(domain), &control)); +} + +/* Given a set "set" in a space [A -> B] and a set "range" + * in the space B, return the intersection. + * + * The set "range" is first extended to a set living in the space + * [A -> B] and then a regular intersection is computed. + */ +__isl_give isl_set *isl_set_intersect_factor_range(__isl_take isl_set *set, + __isl_take isl_set *range) +{ + struct isl_intersect_factor_control control = { + .preserve_type = isl_dim_set, + .other_factor = isl_space_factor_domain, + .product = isl_map_reverse_range_product, + }; + + return set_from_map(isl_map_intersect_factor(set_to_map(set), + set_to_map(range), &control)); +} + +#undef BASE +#define BASE set +static +#include "isl_copy_tuple_id_templ.c" + +/* Given a map "map" in a space [A -> B] -> C and a set "domain" + * in the space A, return the intersection. + * + * The set "domain" is extended to a set living in the space [A -> B] and + * the domain of "map" is intersected with this set. + * + * If "map" has an identifier on the domain tuple, + * then this identifier needs to be set on this product + * before the intersection is computed. + */ +__isl_give isl_map *isl_map_intersect_domain_wrapped_domain( + __isl_take isl_map *map, __isl_take isl_set *domain) +{ + isl_space *space; + isl_set *factor; + + isl_map_align_params_set(&map, &domain); + space = isl_map_get_space(map); + space = isl_space_domain_wrapped_range(space); + factor = isl_set_universe(space); + domain = isl_set_product(domain, factor); + space = isl_map_peek_space(map); + domain = isl_set_copy_tuple_id(domain, isl_dim_set, space, isl_dim_in); + return isl_map_intersect_domain(map, domain); +} + +/* Given a map "map" in a space A -> [B -> C] and a set "domain" + * in the space B, return the intersection. + * + * The set "domain" is extended to a set living in the space [B -> C] and + * the range of "map" is intersected with this set. + * + * If "map" has an identifier on the range tuple, + * then this identifier needs to be set on this product + * before the intersection is computed. + */ +__isl_give isl_map *isl_map_intersect_range_wrapped_domain( + __isl_take isl_map *map, __isl_take isl_set *domain) +{ + isl_space *space; + isl_set *factor; + + isl_map_align_params_set(&map, &domain); + space = isl_map_get_space(map); + space = isl_space_range_wrapped_range(space); + factor = isl_set_universe(space); + domain = isl_set_product(domain, factor); + space = isl_map_peek_space(map); + domain = isl_set_copy_tuple_id(domain, isl_dim_set, space, isl_dim_out); + return isl_map_intersect_range(map, domain); +} + +__isl_give isl_map *isl_map_apply_domain(__isl_take isl_map *map1, + __isl_take isl_map *map2) +{ + if (isl_map_align_params_bin(&map1, &map2) < 0) + goto error; + map1 = isl_map_reverse(map1); + map1 = isl_map_apply_range(map1, map2); + return isl_map_reverse(map1); +error: + isl_map_free(map1); + isl_map_free(map2); + return NULL; +} + +__isl_give isl_map *isl_map_apply_range(__isl_take isl_map *map1, + __isl_take isl_map *map2) +{ + isl_space *space; + struct isl_map *result; + int i, j; + + if (isl_map_align_params_bin(&map1, &map2) < 0) + goto error; + + space = isl_space_join(isl_space_copy(map1->dim), + isl_space_copy(map2->dim)); + + result = isl_map_alloc_space(space, map1->n * map2->n, 0); + if (!result) + goto error; + for (i = 0; i < map1->n; ++i) + for (j = 0; j < map2->n; ++j) { + result = isl_map_add_basic_map(result, + isl_basic_map_apply_range( + isl_basic_map_copy(map1->p[i]), + isl_basic_map_copy(map2->p[j]))); + if (!result) + goto error; + } + isl_map_free(map1); + isl_map_free(map2); + if (result && result->n <= 1) + ISL_F_SET(result, ISL_MAP_DISJOINT); + return result; +error: + isl_map_free(map1); + isl_map_free(map2); + return NULL; +} + +/* Is "bmap" a transformation, i.e., + * does it relate elements from the same space. + */ +isl_bool isl_basic_map_is_transformation(__isl_keep isl_basic_map *bmap) +{ + isl_space *space; + + space = isl_basic_map_peek_space(bmap); + return isl_space_tuple_is_equal(space, isl_dim_in, space, isl_dim_out); +} + +/* Check that "bmap" is a transformation, i.e., + * that it relates elements from the same space. + */ +static isl_stat isl_basic_map_check_transformation( + __isl_keep isl_basic_map *bmap) +{ + isl_bool equal; + + equal = isl_basic_map_is_transformation(bmap); + if (equal < 0) + return isl_stat_error; + if (!equal) + isl_die(isl_basic_map_get_ctx(bmap), isl_error_invalid, + "domain and range don't match", return isl_stat_error); + return isl_stat_ok; +} + +/* + * returns range - domain + */ +__isl_give isl_basic_set *isl_basic_map_deltas(__isl_take isl_basic_map *bmap) +{ + isl_space *target_space; + struct isl_basic_set *bset; + isl_size dim; + isl_size nparam; + isl_size total; + int i; + + if (isl_basic_map_check_transformation(bmap) < 0) + return isl_basic_map_free(bmap); + dim = isl_basic_map_dim(bmap, isl_dim_in); + nparam = isl_basic_map_dim(bmap, isl_dim_param); + if (dim < 0 || nparam < 0) + goto error; + target_space = isl_space_domain(isl_basic_map_get_space(bmap)); + bmap = isl_basic_map_from_range(isl_basic_map_wrap(bmap)); + bmap = isl_basic_map_add_dims(bmap, isl_dim_in, dim); + total = isl_basic_map_dim(bmap, isl_dim_all); + if (total < 0) + bmap = isl_basic_map_free(bmap); + bmap = isl_basic_map_extend_constraints(bmap, dim, 0); + for (i = 0; i < dim; ++i) { + int j = isl_basic_map_alloc_equality(bmap); + if (j < 0) { + bmap = isl_basic_map_free(bmap); + break; + } + isl_seq_clr(bmap->eq[j], 1 + total); + isl_int_set_si(bmap->eq[j][1+nparam+i], 1); + isl_int_set_si(bmap->eq[j][1+nparam+dim+i], 1); + isl_int_set_si(bmap->eq[j][1+nparam+2*dim+i], -1); + } + bset = isl_basic_map_domain(bmap); + bset = isl_basic_set_reset_space(bset, target_space); + return bset; +error: + isl_basic_map_free(bmap); + return NULL; +} + +/* Is the tuple of type "type1" of "map" the same as + * the tuple of type "type2" of "space"? + */ +isl_bool isl_map_space_tuple_is_equal(__isl_keep isl_map *map, + enum isl_dim_type type1, __isl_keep isl_space *space, + enum isl_dim_type type2) +{ + isl_space *map_space; + + map_space = isl_map_peek_space(map); + return isl_space_tuple_is_equal(map_space, type1, space, type2); +} + +/* Is the tuple of type "type1" of "map1" the same as + * the tuple of type "type2" of "map2"? + */ +isl_bool isl_map_tuple_is_equal(__isl_keep isl_map *map1, + enum isl_dim_type type1, __isl_keep isl_map *map2, + enum isl_dim_type type2) +{ + isl_space *space1, *space2; + + space1 = isl_map_peek_space(map1); + space2 = isl_map_peek_space(map2); + return isl_space_tuple_is_equal(space1, type1, space2, type2); +} + +/* Is the space of "obj" equal to "space", ignoring parameters? + */ +isl_bool isl_map_has_space_tuples(__isl_keep isl_map *map, + __isl_keep isl_space *space) +{ + isl_space *map_space; + + map_space = isl_map_peek_space(map); + return isl_space_has_equal_tuples(map_space, space); +} + +/* Check that "map" is a transformation, i.e., + * that it relates elements from the same space. + */ +isl_stat isl_map_check_transformation(__isl_keep isl_map *map) +{ + isl_bool equal; + + equal = isl_map_tuple_is_equal(map, isl_dim_in, map, isl_dim_out); + if (equal < 0) + return isl_stat_error; + if (!equal) + isl_die(isl_map_get_ctx(map), isl_error_invalid, + "domain and range don't match", return isl_stat_error); + return isl_stat_ok; +} + +/* + * returns range - domain + */ +__isl_give isl_set *isl_map_deltas(__isl_take isl_map *map) +{ + int i; + isl_space *space; + struct isl_set *result; + + if (isl_map_check_transformation(map) < 0) + goto error; + space = isl_map_get_space(map); + space = isl_space_domain(space); + result = isl_set_alloc_space(space, map->n, 0); + if (!result) + goto error; + for (i = 0; i < map->n; ++i) + result = isl_set_add_basic_set(result, + isl_basic_map_deltas(isl_basic_map_copy(map->p[i]))); + isl_map_free(map); + return result; +error: + isl_map_free(map); + return NULL; +} + +/* + * returns [domain -> range] -> range - domain + */ +__isl_give isl_basic_map *isl_basic_map_deltas_map( + __isl_take isl_basic_map *bmap) +{ + int i, k; + isl_space *space; + isl_basic_map *domain; + isl_size nparam, n; + isl_size total; + + if (isl_basic_map_check_transformation(bmap) < 0) + return isl_basic_map_free(bmap); + + nparam = isl_basic_map_dim(bmap, isl_dim_param); + n = isl_basic_map_dim(bmap, isl_dim_in); + if (nparam < 0 || n < 0) + return isl_basic_map_free(bmap); + + space = isl_basic_map_get_space(bmap); + space = isl_space_from_range(isl_space_domain(space)); + domain = isl_basic_map_universe(space); + + bmap = isl_basic_map_from_domain(isl_basic_map_wrap(bmap)); + bmap = isl_basic_map_apply_range(bmap, domain); + bmap = isl_basic_map_extend_constraints(bmap, n, 0); + + total = isl_basic_map_dim(bmap, isl_dim_all); + if (total < 0) + return isl_basic_map_free(bmap); + + for (i = 0; i < n; ++i) { + k = isl_basic_map_alloc_equality(bmap); + if (k < 0) + goto error; + isl_seq_clr(bmap->eq[k], 1 + total); + isl_int_set_si(bmap->eq[k][1 + nparam + i], 1); + isl_int_set_si(bmap->eq[k][1 + nparam + n + i], -1); + isl_int_set_si(bmap->eq[k][1 + nparam + n + n + i], 1); + } + + bmap = isl_basic_map_gauss(bmap, NULL); + return isl_basic_map_finalize(bmap); +error: + isl_basic_map_free(bmap); + return NULL; +} + +/* + * returns [domain -> range] -> range - domain + */ +__isl_give isl_map *isl_map_deltas_map(__isl_take isl_map *map) +{ + if (isl_map_check_transformation(map) < 0) + return isl_map_free(map); + + return isl_map_transform(map, &isl_space_range_map, + &isl_basic_map_deltas_map); +} + +/* Return pairs of elements { x -> y } such that y - x is in "deltas". + */ +__isl_give isl_map *isl_set_translation(__isl_take isl_set *deltas) +{ + isl_space *space; + isl_map *map; + + space = isl_space_map_from_set(isl_set_get_space(deltas)); + map = isl_map_deltas_map(isl_map_universe(space)); + map = isl_map_intersect_range(map, deltas); + + return isl_set_unwrap(isl_map_domain(map)); +} + +__isl_give isl_basic_map *isl_basic_map_identity(__isl_take isl_space *space) +{ + isl_size n_in, n_out; + + n_in = isl_space_dim(space, isl_dim_in); + n_out = isl_space_dim(space, isl_dim_out); + if (n_in < 0 || n_out < 0) + goto error; + if (n_in != n_out) + isl_die(space->ctx, isl_error_invalid, + "number of input and output dimensions needs to be " + "the same", goto error); + return isl_basic_map_equal(space, n_in); +error: + isl_space_free(space); + return NULL; +} + +__isl_give isl_map *isl_map_identity(__isl_take isl_space *space) +{ + return isl_map_from_basic_map(isl_basic_map_identity(space)); +} + +__isl_give isl_map *isl_set_identity(__isl_take isl_set *set) +{ + isl_space *space = isl_set_get_space(set); + isl_map *id; + id = isl_map_identity(isl_space_map_from_set(space)); + return isl_map_intersect_range(id, set); +} + +/* Construct a basic set with all set dimensions having only non-negative + * values. + */ +__isl_give isl_basic_set *isl_basic_set_positive_orthant( + __isl_take isl_space *space) +{ + int i; + isl_size nparam; + isl_size dim; + isl_size total; + struct isl_basic_set *bset; + + nparam = isl_space_dim(space, isl_dim_param); + dim = isl_space_dim(space, isl_dim_set); + total = isl_space_dim(space, isl_dim_all); + if (nparam < 0 || dim < 0 || total < 0) + space = isl_space_free(space); + bset = isl_basic_set_alloc_space(space, 0, 0, dim); + if (!bset) + return NULL; + for (i = 0; i < dim; ++i) { + int k = isl_basic_set_alloc_inequality(bset); + if (k < 0) + goto error; + isl_seq_clr(bset->ineq[k], 1 + total); + isl_int_set_si(bset->ineq[k][1 + nparam + i], 1); + } + return bset; +error: + isl_basic_set_free(bset); + return NULL; +} + +/* Construct the half-space x_pos >= 0. + */ +static __isl_give isl_basic_set *nonneg_halfspace(__isl_take isl_space *space, + int pos) +{ + int k; + isl_size total; + isl_basic_set *nonneg; + + total = isl_space_dim(space, isl_dim_all); + if (total < 0) + space = isl_space_free(space); + nonneg = isl_basic_set_alloc_space(space, 0, 0, 1); + k = isl_basic_set_alloc_inequality(nonneg); + if (k < 0) + goto error; + isl_seq_clr(nonneg->ineq[k], 1 + total); + isl_int_set_si(nonneg->ineq[k][pos], 1); + + return isl_basic_set_finalize(nonneg); +error: + isl_basic_set_free(nonneg); + return NULL; +} + +/* Construct the half-space x_pos <= -1. + */ +static __isl_give isl_basic_set *neg_halfspace(__isl_take isl_space *space, + int pos) +{ + int k; + isl_size total; + isl_basic_set *neg; + + total = isl_space_dim(space, isl_dim_all); + if (total < 0) + space = isl_space_free(space); + neg = isl_basic_set_alloc_space(space, 0, 0, 1); + k = isl_basic_set_alloc_inequality(neg); + if (k < 0) + goto error; + isl_seq_clr(neg->ineq[k], 1 + total); + isl_int_set_si(neg->ineq[k][0], -1); + isl_int_set_si(neg->ineq[k][pos], -1); + + return isl_basic_set_finalize(neg); +error: + isl_basic_set_free(neg); + return NULL; +} + +__isl_give isl_set *isl_set_split_dims(__isl_take isl_set *set, + enum isl_dim_type type, unsigned first, unsigned n) +{ + int i; + unsigned offset; + isl_basic_set *nonneg; + isl_basic_set *neg; + + if (n == 0) + return set; + + if (isl_set_check_range(set, type, first, n) < 0) + return isl_set_free(set); + + offset = pos(set->dim, type); + for (i = 0; i < n; ++i) { + nonneg = nonneg_halfspace(isl_set_get_space(set), + offset + first + i); + neg = neg_halfspace(isl_set_get_space(set), offset + first + i); + + set = isl_set_intersect(set, isl_basic_set_union(nonneg, neg)); + } + + return set; +} + +static isl_stat foreach_orthant(__isl_take isl_set *set, int *signs, int first, + int len, + isl_stat (*fn)(__isl_take isl_set *orthant, int *signs, void *user), + void *user) +{ + isl_set *half; + + if (!set) + return isl_stat_error; + if (isl_set_plain_is_empty(set)) { + isl_set_free(set); + return isl_stat_ok; + } + if (first == len) + return fn(set, signs, user); + + signs[first] = 1; + half = isl_set_from_basic_set(nonneg_halfspace(isl_set_get_space(set), + 1 + first)); + half = isl_set_intersect(half, isl_set_copy(set)); + if (foreach_orthant(half, signs, first + 1, len, fn, user) < 0) + goto error; + + signs[first] = -1; + half = isl_set_from_basic_set(neg_halfspace(isl_set_get_space(set), + 1 + first)); + half = isl_set_intersect(half, set); + return foreach_orthant(half, signs, first + 1, len, fn, user); +error: + isl_set_free(set); + return isl_stat_error; +} + +/* Call "fn" on the intersections of "set" with each of the orthants + * (except for obviously empty intersections). The orthant is identified + * by the signs array, with each entry having value 1 or -1 according + * to the sign of the corresponding variable. + */ +isl_stat isl_set_foreach_orthant(__isl_keep isl_set *set, + isl_stat (*fn)(__isl_take isl_set *orthant, int *signs, void *user), + void *user) +{ + isl_size nparam; + isl_size nvar; + int *signs; + isl_stat r; + + if (!set) + return isl_stat_error; + if (isl_set_plain_is_empty(set)) + return isl_stat_ok; + + nparam = isl_set_dim(set, isl_dim_param); + nvar = isl_set_dim(set, isl_dim_set); + if (nparam < 0 || nvar < 0) + return isl_stat_error; + + signs = isl_alloc_array(set->ctx, int, nparam + nvar); + + r = foreach_orthant(isl_set_copy(set), signs, 0, nparam + nvar, + fn, user); + + free(signs); + + return r; +} + +isl_bool isl_set_is_equal(__isl_keep isl_set *set1, __isl_keep isl_set *set2) +{ + return isl_map_is_equal(set_to_map(set1), set_to_map(set2)); +} + +isl_bool isl_basic_map_is_subset(__isl_keep isl_basic_map *bmap1, + __isl_keep isl_basic_map *bmap2) +{ + isl_bool is_subset; + struct isl_map *map1; + struct isl_map *map2; + + if (!bmap1 || !bmap2) + return isl_bool_error; + + map1 = isl_map_from_basic_map(isl_basic_map_copy(bmap1)); + map2 = isl_map_from_basic_map(isl_basic_map_copy(bmap2)); + + is_subset = isl_map_is_subset(map1, map2); + + isl_map_free(map1); + isl_map_free(map2); + + return is_subset; +} + +isl_bool isl_basic_set_is_subset(__isl_keep isl_basic_set *bset1, + __isl_keep isl_basic_set *bset2) +{ + return isl_basic_map_is_subset(bset1, bset2); +} + +isl_bool isl_basic_map_is_equal(__isl_keep isl_basic_map *bmap1, + __isl_keep isl_basic_map *bmap2) +{ + isl_bool is_subset; + + if (!bmap1 || !bmap2) + return isl_bool_error; + is_subset = isl_basic_map_is_subset(bmap1, bmap2); + if (is_subset != isl_bool_true) + return is_subset; + is_subset = isl_basic_map_is_subset(bmap2, bmap1); + return is_subset; +} + +isl_bool isl_basic_set_is_equal(__isl_keep isl_basic_set *bset1, + __isl_keep isl_basic_set *bset2) +{ + return isl_basic_map_is_equal( + bset_to_bmap(bset1), bset_to_bmap(bset2)); +} + +isl_bool isl_map_is_empty(__isl_keep isl_map *map) +{ + int i; + int is_empty; + + if (!map) + return isl_bool_error; + for (i = 0; i < map->n; ++i) { + is_empty = isl_basic_map_is_empty(map->p[i]); + if (is_empty < 0) + return isl_bool_error; + if (!is_empty) + return isl_bool_false; + } + return isl_bool_true; +} + +isl_bool isl_map_plain_is_empty(__isl_keep isl_map *map) +{ + return map ? map->n == 0 : isl_bool_error; +} + +isl_bool isl_set_plain_is_empty(__isl_keep isl_set *set) +{ + return set ? set->n == 0 : isl_bool_error; +} + +isl_bool isl_set_is_empty(__isl_keep isl_set *set) +{ + return isl_map_is_empty(set_to_map(set)); +} + +#undef TYPE +#define TYPE isl_basic_map + +static +#include "isl_type_has_equal_space_bin_templ.c" +#include "isl_type_check_equal_space_templ.c" + +/* Check that "bset1" and "bset2" live in the same space, + * reporting an error if they do not. + */ +isl_stat isl_basic_set_check_equal_space(__isl_keep isl_basic_set *bset1, + __isl_keep isl_basic_set *bset2) +{ + return isl_basic_map_check_equal_space(bset_to_bmap(bset1), + bset_to_bmap(bset1)); +} + +#undef TYPE +#define TYPE isl_map + +#include "isl_type_has_equal_space_bin_templ.c" +#include "isl_type_check_equal_space_templ.c" +#include "isl_type_has_space_templ.c" + +isl_bool isl_set_has_equal_space(__isl_keep isl_set *set1, + __isl_keep isl_set *set2) +{ + return isl_map_has_equal_space(set_to_map(set1), set_to_map(set2)); +} + +#undef TYPE1 +#define TYPE1 isl_map +#undef TYPE2 +#define TYPE2 isl_basic_map +#undef TYPE_PAIR +#define TYPE_PAIR isl_map_basic_map + +static +#include "isl_type_has_equal_space_templ.c" +#include "isl_type_check_equal_space_templ.c" + +/* Check that "set" and "bset" live in the same space, + * reporting an error if they do not. + */ +isl_stat isl_set_basic_set_check_equal_space(__isl_keep isl_set *set, + __isl_keep isl_basic_set *bset) +{ + return isl_map_basic_map_check_equal_space(set_to_map(set), + bset_to_bmap(bset)); +} + +static isl_bool map_is_equal(__isl_keep isl_map *map1, __isl_keep isl_map *map2) +{ + isl_bool is_subset; + + if (!map1 || !map2) + return isl_bool_error; + is_subset = isl_map_is_subset(map1, map2); + if (is_subset != isl_bool_true) + return is_subset; + is_subset = isl_map_is_subset(map2, map1); + return is_subset; +} + +/* Is "map1" equal to "map2"? + * + * First check if they are obviously equal. + * If not, then perform a more detailed analysis. + */ +isl_bool isl_map_is_equal(__isl_keep isl_map *map1, __isl_keep isl_map *map2) +{ + isl_bool equal; + + equal = isl_map_plain_is_equal(map1, map2); + if (equal < 0 || equal) + return equal; + return isl_map_align_params_map_map_and_test(map1, map2, &map_is_equal); +} + +isl_bool isl_basic_map_is_strict_subset(__isl_keep isl_basic_map *bmap1, + __isl_keep isl_basic_map *bmap2) +{ + isl_bool is_subset; + + if (!bmap1 || !bmap2) + return isl_bool_error; + is_subset = isl_basic_map_is_subset(bmap1, bmap2); + if (is_subset != isl_bool_true) + return is_subset; + is_subset = isl_basic_map_is_subset(bmap2, bmap1); + return isl_bool_not(is_subset); +} + +isl_bool isl_map_is_strict_subset(__isl_keep isl_map *map1, + __isl_keep isl_map *map2) +{ + isl_bool is_subset; + + if (!map1 || !map2) + return isl_bool_error; + is_subset = isl_map_is_subset(map1, map2); + if (is_subset != isl_bool_true) + return is_subset; + is_subset = isl_map_is_subset(map2, map1); + return isl_bool_not(is_subset); +} + +isl_bool isl_set_is_strict_subset(__isl_keep isl_set *set1, + __isl_keep isl_set *set2) +{ + return isl_map_is_strict_subset(set_to_map(set1), set_to_map(set2)); +} + +/* Is "bmap" obviously equal to the universe with the same space? + * + * That is, does it not have any constraints? + */ +isl_bool isl_basic_map_plain_is_universe(__isl_keep isl_basic_map *bmap) +{ + if (!bmap) + return isl_bool_error; + return bmap->n_eq == 0 && bmap->n_ineq == 0; +} + +/* Is "bset" obviously equal to the universe with the same space? + */ +isl_bool isl_basic_set_plain_is_universe(__isl_keep isl_basic_set *bset) +{ + return isl_basic_map_plain_is_universe(bset); +} + +/* If "c" does not involve any existentially quantified variables, + * then set *univ to false and abort + */ +static isl_stat involves_divs(__isl_take isl_constraint *c, void *user) +{ + isl_bool *univ = user; + isl_size n; + + n = isl_constraint_dim(c, isl_dim_div); + if (n < 0) + c = isl_constraint_free(c); + *univ = isl_constraint_involves_dims(c, isl_dim_div, 0, n); + isl_constraint_free(c); + if (*univ < 0 || !*univ) + return isl_stat_error; + return isl_stat_ok; +} + +/* Is "bmap" equal to the universe with the same space? + * + * First check if it is obviously equal to the universe. + * If not and if there are any constraints not involving + * existentially quantified variables, then it is certainly + * not equal to the universe. + * Otherwise, check if the universe is a subset of "bmap". + */ +isl_bool isl_basic_map_is_universe(__isl_keep isl_basic_map *bmap) +{ + isl_size n_div; + isl_bool univ; + isl_basic_map *test; + + univ = isl_basic_map_plain_is_universe(bmap); + if (univ < 0 || univ) + return univ; + n_div = isl_basic_map_dim(bmap, isl_dim_div); + if (n_div < 0) + return isl_bool_error; + if (n_div == 0) + return isl_bool_false; + univ = isl_bool_true; + if (isl_basic_map_foreach_constraint(bmap, &involves_divs, &univ) < 0 && + univ) + return isl_bool_error; + if (univ < 0 || !univ) + return univ; + test = isl_basic_map_universe(isl_basic_map_get_space(bmap)); + univ = isl_basic_map_is_subset(test, bmap); + isl_basic_map_free(test); + return univ; +} + +/* Is "bset" equal to the universe with the same space? + */ +isl_bool isl_basic_set_is_universe(__isl_keep isl_basic_set *bset) +{ + return isl_basic_map_is_universe(bset); +} + +isl_bool isl_map_plain_is_universe(__isl_keep isl_map *map) +{ + int i; + + if (!map) + return isl_bool_error; + + for (i = 0; i < map->n; ++i) { + isl_bool r = isl_basic_map_plain_is_universe(map->p[i]); + if (r < 0 || r) + return r; + } + + return isl_bool_false; +} + +isl_bool isl_set_plain_is_universe(__isl_keep isl_set *set) +{ + return isl_map_plain_is_universe(set_to_map(set)); +} + +isl_bool isl_basic_map_is_empty(__isl_keep isl_basic_map *bmap) +{ + struct isl_basic_set *bset = NULL; + struct isl_vec *sample = NULL; + isl_bool empty, non_empty; + + if (!bmap) + return isl_bool_error; + + if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_EMPTY)) + return isl_bool_true; + + if (isl_basic_map_plain_is_universe(bmap)) + return isl_bool_false; + + if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_RATIONAL)) { + struct isl_basic_map *copy = isl_basic_map_copy(bmap); + copy = isl_basic_map_remove_redundancies(copy); + empty = isl_basic_map_plain_is_empty(copy); + isl_basic_map_free(copy); + return empty; + } + + non_empty = isl_basic_map_plain_is_non_empty(bmap); + if (non_empty < 0) + return isl_bool_error; + if (non_empty) + return isl_bool_false; + isl_vec_free(bmap->sample); + bmap->sample = NULL; + bset = isl_basic_map_underlying_set(isl_basic_map_copy(bmap)); + if (!bset) + return isl_bool_error; + sample = isl_basic_set_sample_vec(bset); + if (!sample) + return isl_bool_error; + empty = sample->size == 0; + isl_vec_free(bmap->sample); + bmap->sample = sample; + if (empty) + ISL_F_SET(bmap, ISL_BASIC_MAP_EMPTY); + + return empty; +} + +isl_bool isl_basic_map_plain_is_empty(__isl_keep isl_basic_map *bmap) +{ + if (!bmap) + return isl_bool_error; + return ISL_F_ISSET(bmap, ISL_BASIC_MAP_EMPTY); +} + +isl_bool isl_basic_set_plain_is_empty(__isl_keep isl_basic_set *bset) +{ + if (!bset) + return isl_bool_error; + return ISL_F_ISSET(bset, ISL_BASIC_SET_EMPTY); +} + +/* Is "bmap" known to be non-empty? + * + * That is, is the cached sample still valid? + */ +isl_bool isl_basic_map_plain_is_non_empty(__isl_keep isl_basic_map *bmap) +{ + isl_size total; + + if (!bmap) + return isl_bool_error; + if (!bmap->sample) + return isl_bool_false; + total = isl_basic_map_dim(bmap, isl_dim_all); + if (total < 0) + return isl_bool_error; + if (bmap->sample->size != 1 + total) + return isl_bool_false; + return isl_basic_map_contains(bmap, bmap->sample); +} + +isl_bool isl_basic_set_is_empty(__isl_keep isl_basic_set *bset) +{ + return isl_basic_map_is_empty(bset_to_bmap(bset)); +} + +__isl_give isl_map *isl_basic_map_union(__isl_take isl_basic_map *bmap1, + __isl_take isl_basic_map *bmap2) +{ + struct isl_map *map; + + if (isl_basic_map_check_equal_space(bmap1, bmap2) < 0) + goto error; + + map = isl_map_alloc_space(isl_space_copy(bmap1->dim), 2, 0); + if (!map) + goto error; + map = isl_map_add_basic_map(map, bmap1); + map = isl_map_add_basic_map(map, bmap2); + return map; +error: + isl_basic_map_free(bmap1); + isl_basic_map_free(bmap2); + return NULL; +} + +__isl_give isl_set *isl_basic_set_union(__isl_take isl_basic_set *bset1, + __isl_take isl_basic_set *bset2) +{ + return set_from_map(isl_basic_map_union(bset_to_bmap(bset1), + bset_to_bmap(bset2))); +} + +/* Order divs such that any div only depends on previous divs */ +__isl_give isl_basic_map *isl_basic_map_order_divs( + __isl_take isl_basic_map *bmap) +{ + int i; + isl_size off; + + off = isl_basic_map_var_offset(bmap, isl_dim_div); + if (off < 0) + return isl_basic_map_free(bmap); + + for (i = 0; i < bmap->n_div; ++i) { + int pos; + if (isl_int_is_zero(bmap->div[i][0])) + continue; + pos = isl_seq_first_non_zero(bmap->div[i]+1+1+off+i, + bmap->n_div-i); + if (pos == -1) + continue; + if (pos == 0) + isl_die(isl_basic_map_get_ctx(bmap), isl_error_internal, + "integer division depends on itself", + return isl_basic_map_free(bmap)); + bmap = isl_basic_map_swap_div(bmap, i, i + pos); + if (!bmap) + return NULL; + --i; + } + return bmap; +} + +__isl_give isl_map *isl_map_order_divs(__isl_take isl_map *map) +{ + int i; + + if (!map) + return 0; + + for (i = 0; i < map->n; ++i) { + map->p[i] = isl_basic_map_order_divs(map->p[i]); + if (!map->p[i]) + goto error; + } + + return map; +error: + isl_map_free(map); + return NULL; +} + +/* Sort the local variables of "bset". + */ +__isl_give isl_basic_set *isl_basic_set_sort_divs( + __isl_take isl_basic_set *bset) +{ + return bset_from_bmap(isl_basic_map_sort_divs(bset_to_bmap(bset))); +} + +/* Apply the expansion computed by isl_merge_divs. + * The expansion itself is given by "exp" while the resulting + * list of divs is given by "div". + * + * Move the integer divisions of "bmap" into the right position + * according to "exp" and then introduce the additional integer + * divisions, adding div constraints. + * The moving should be done first to avoid moving coefficients + * in the definitions of the extra integer divisions. + */ +__isl_give isl_basic_map *isl_basic_map_expand_divs( + __isl_take isl_basic_map *bmap, __isl_take isl_mat *div, int *exp) +{ + int i, j; + int n_div; + + bmap = isl_basic_map_cow(bmap); + if (!bmap || !div) + goto error; + + if (div->n_row < bmap->n_div) + isl_die(isl_mat_get_ctx(div), isl_error_invalid, + "not an expansion", goto error); + + n_div = bmap->n_div; + bmap = isl_basic_map_extend(bmap, div->n_row - n_div, 0, + 2 * (div->n_row - n_div)); + + for (i = n_div; i < div->n_row; ++i) + if (isl_basic_map_alloc_div(bmap) < 0) + goto error; + + for (j = n_div - 1; j >= 0; --j) { + if (exp[j] == j) + break; + bmap = isl_basic_map_swap_div(bmap, j, exp[j]); + if (!bmap) + goto error; + } + j = 0; + for (i = 0; i < div->n_row; ++i) { + if (j < n_div && exp[j] == i) { + j++; + } else { + isl_seq_cpy(bmap->div[i], div->row[i], div->n_col); + if (isl_basic_map_div_is_marked_unknown(bmap, i)) + continue; + bmap = isl_basic_map_add_div_constraints(bmap, i); + if (!bmap) + goto error; + } + } + + isl_mat_free(div); + return bmap; +error: + isl_basic_map_free(bmap); + isl_mat_free(div); + return NULL; +} + +/* Apply the expansion computed by isl_merge_divs. + * The expansion itself is given by "exp" while the resulting + * list of divs is given by "div". + */ +__isl_give isl_basic_set *isl_basic_set_expand_divs( + __isl_take isl_basic_set *bset, __isl_take isl_mat *div, int *exp) +{ + return isl_basic_map_expand_divs(bset, div, exp); +} + +/* Look for a div in dst that corresponds to the div "div" in src. + * The divs before "div" in src and dst are assumed to be the same. + * + * Return the position of the corresponding div in dst + * if there is one. Otherwise, return a position beyond the integer divisions. + * Return -1 on error. + */ +static int find_div(__isl_keep isl_basic_map *dst, + __isl_keep isl_basic_map *src, unsigned div) +{ + int i; + isl_size n_div; + isl_size v_div; + + v_div = isl_basic_map_var_offset(src, isl_dim_div); + n_div = isl_basic_map_dim(dst, isl_dim_div); + if (n_div < 0 || v_div < 0) + return -1; + isl_assert(dst->ctx, div <= n_div, return -1); + for (i = div; i < n_div; ++i) + if (isl_seq_eq(dst->div[i], src->div[div], 1+1+v_div+div) && + isl_seq_first_non_zero(dst->div[i] + 1 + 1 + v_div + div, + n_div - div) == -1) + return i; + return n_div; +} + +/* Align the divs of "dst" to those of "src", adding divs from "src" + * if needed. That is, make sure that the first src->n_div divs + * of the result are equal to those of src. + * The integer division of "src" are assumed to be ordered. + * + * The integer divisions are swapped into the right position + * (possibly after adding them first). This may result + * in the remaining integer divisions appearing in the wrong order, + * i.e., with some integer division appearing before + * some other integer division on which it depends. + * The integer divisions therefore need to be ordered. + * This will not affect the integer divisions aligned to those of "src", + * since "src" is assumed to have ordered integer divisions. + * + * The result is not finalized as by design it will have redundant + * divs if any divs from "src" were copied. + */ +__isl_give isl_basic_map *isl_basic_map_align_divs( + __isl_take isl_basic_map *dst, __isl_keep isl_basic_map *src) +{ + int i; + isl_bool known; + int extended; + isl_size v_div; + isl_size dst_n_div; + + if (!dst || !src) + return isl_basic_map_free(dst); + + if (src->n_div == 0) + return dst; + + known = isl_basic_map_divs_known(src); + if (known < 0) + return isl_basic_map_free(dst); + if (!known) + isl_die(isl_basic_map_get_ctx(src), isl_error_invalid, + "some src divs are unknown", + return isl_basic_map_free(dst)); + + v_div = isl_basic_map_var_offset(src, isl_dim_div); + if (v_div < 0) + return isl_basic_map_free(dst); + + extended = 0; + dst_n_div = isl_basic_map_dim(dst, isl_dim_div); + if (dst_n_div < 0) + dst = isl_basic_map_free(dst); + for (i = 0; i < src->n_div; ++i) { + int j = find_div(dst, src, i); + if (j < 0) + dst = isl_basic_map_free(dst); + if (j == dst_n_div) { + if (!extended) { + int extra = src->n_div - i; + dst = isl_basic_map_cow(dst); + if (!dst) + return isl_basic_map_free(dst); + dst = isl_basic_map_extend(dst, + extra, 0, 2 * extra); + extended = 1; + } + j = isl_basic_map_alloc_div(dst); + if (j < 0) + return isl_basic_map_free(dst); + isl_seq_cpy(dst->div[j], src->div[i], 1+1+v_div+i); + isl_seq_clr(dst->div[j]+1+1+v_div+i, dst->n_div - i); + dst_n_div++; + dst = isl_basic_map_add_div_constraints(dst, j); + if (!dst) + return isl_basic_map_free(dst); + } + if (j != i) + dst = isl_basic_map_swap_div(dst, i, j); + if (!dst) + return isl_basic_map_free(dst); + } + return isl_basic_map_order_divs(dst); +} + +__isl_give isl_map *isl_map_align_divs_internal(__isl_take isl_map *map) +{ + int i; + + if (!map) + return NULL; + if (map->n == 0) + return map; + map = isl_map_compute_divs(map); + map = isl_map_order_divs(map); + map = isl_map_cow(map); + if (!map) + return NULL; + + for (i = 1; i < map->n; ++i) + map->p[0] = isl_basic_map_align_divs(map->p[0], map->p[i]); + for (i = 1; i < map->n; ++i) { + map->p[i] = isl_basic_map_align_divs(map->p[i], map->p[0]); + if (!map->p[i]) + return isl_map_free(map); + } + + map = isl_map_unmark_normalized(map); + return map; +} + +__isl_give isl_map *isl_map_align_divs(__isl_take isl_map *map) +{ + return isl_map_align_divs_internal(map); +} + +__isl_give isl_set *isl_set_align_divs(__isl_take isl_set *set) +{ + return set_from_map(isl_map_align_divs_internal(set_to_map(set))); +} + +/* Align the divs of the basic maps in "map" to those + * of the basic maps in "list", as well as to the other basic maps in "map". + * The elements in "list" are assumed to have known divs. + */ +__isl_give isl_map *isl_map_align_divs_to_basic_map_list( + __isl_take isl_map *map, __isl_keep isl_basic_map_list *list) +{ + int i; + isl_size n; + + n = isl_basic_map_list_n_basic_map(list); + map = isl_map_compute_divs(map); + map = isl_map_cow(map); + if (!map || n < 0) + return isl_map_free(map); + if (map->n == 0) + return map; + + for (i = 0; i < n; ++i) { + isl_basic_map *bmap; + + bmap = isl_basic_map_list_get_basic_map(list, i); + bmap = isl_basic_map_order_divs(bmap); + map->p[0] = isl_basic_map_align_divs(map->p[0], bmap); + isl_basic_map_free(bmap); + } + if (!map->p[0]) + return isl_map_free(map); + + return isl_map_align_divs_internal(map); +} + +/* Align the divs of each element of "list" to those of "bmap". + * Both "bmap" and the elements of "list" are assumed to have known divs. + */ +__isl_give isl_basic_map_list *isl_basic_map_list_align_divs_to_basic_map( + __isl_take isl_basic_map_list *list, __isl_keep isl_basic_map *bmap) +{ + int i; + isl_size n; + + n = isl_basic_map_list_n_basic_map(list); + if (n < 0 || !bmap) + return isl_basic_map_list_free(list); + + for (i = 0; i < n; ++i) { + isl_basic_map *bmap_i; + + bmap_i = isl_basic_map_list_get_basic_map(list, i); + bmap_i = isl_basic_map_align_divs(bmap_i, bmap); + list = isl_basic_map_list_set_basic_map(list, i, bmap_i); + } + + return list; +} + +__isl_give isl_set *isl_set_apply( __isl_take isl_set *set, + __isl_take isl_map *map) +{ + isl_bool ok; + + isl_map_align_params_set(&map, &set); + ok = isl_map_compatible_domain(map, set); + if (ok < 0) + goto error; + if (!ok) + isl_die(isl_set_get_ctx(set), isl_error_invalid, + "incompatible spaces", goto error); + map = isl_map_intersect_domain(map, set); + set = isl_map_range(map); + return set; +error: + isl_set_free(set); + isl_map_free(map); + return NULL; +} + +/* There is no need to cow as removing empty parts doesn't change + * the meaning of the set. + */ +__isl_give isl_map *isl_map_remove_empty_parts(__isl_take isl_map *map) +{ + int i; + + if (!map) + return NULL; + + for (i = map->n - 1; i >= 0; --i) + map = remove_if_empty(map, i); + + return map; +} + +__isl_give isl_set *isl_set_remove_empty_parts(__isl_take isl_set *set) +{ + return set_from_map(isl_map_remove_empty_parts(set_to_map(set))); +} + +/* Create a binary relation that maps the shared initial "pos" dimensions + * of "bset1" and "bset2" to the remaining dimensions of "bset1" and "bset2". + */ +static __isl_give isl_basic_map *join_initial(__isl_keep isl_basic_set *bset1, + __isl_keep isl_basic_set *bset2, int pos) +{ + isl_basic_map *bmap1; + isl_basic_map *bmap2; + + bmap1 = isl_basic_map_from_range(isl_basic_set_copy(bset1)); + bmap2 = isl_basic_map_from_range(isl_basic_set_copy(bset2)); + bmap1 = isl_basic_map_move_dims(bmap1, isl_dim_in, 0, + isl_dim_out, 0, pos); + bmap2 = isl_basic_map_move_dims(bmap2, isl_dim_in, 0, + isl_dim_out, 0, pos); + return isl_basic_map_range_product(bmap1, bmap2); +} + +/* Given two basic sets bset1 and bset2, compute the maximal difference + * between the values of dimension pos in bset1 and those in bset2 + * for any common value of the parameters and dimensions preceding pos. + */ +static enum isl_lp_result basic_set_maximal_difference_at( + __isl_keep isl_basic_set *bset1, __isl_keep isl_basic_set *bset2, + int pos, isl_int *opt) +{ + isl_basic_map *bmap1; + struct isl_ctx *ctx; + struct isl_vec *obj; + isl_size total; + isl_size nparam; + isl_size dim1; + enum isl_lp_result res; + + nparam = isl_basic_set_dim(bset1, isl_dim_param); + dim1 = isl_basic_set_dim(bset1, isl_dim_set); + if (nparam < 0 || dim1 < 0 || !bset2) + return isl_lp_error; + + bmap1 = join_initial(bset1, bset2, pos); + total = isl_basic_map_dim(bmap1, isl_dim_all); + if (total < 0) + return isl_lp_error; + + ctx = bmap1->ctx; + obj = isl_vec_alloc(ctx, 1 + total); + if (!obj) + goto error; + isl_seq_clr(obj->block.data, 1 + total); + isl_int_set_si(obj->block.data[1+nparam+pos], 1); + isl_int_set_si(obj->block.data[1+nparam+pos+(dim1-pos)], -1); + res = isl_basic_map_solve_lp(bmap1, 1, obj->block.data, ctx->one, + opt, NULL, NULL); + isl_basic_map_free(bmap1); + isl_vec_free(obj); + return res; +error: + isl_basic_map_free(bmap1); + return isl_lp_error; +} + +/* Given two _disjoint_ basic sets bset1 and bset2, check whether + * for any common value of the parameters and dimensions preceding pos + * in both basic sets, the values of dimension pos in bset1 are + * smaller or larger than those in bset2. + * + * Returns + * 1 if bset1 follows bset2 + * -1 if bset1 precedes bset2 + * 0 if bset1 and bset2 are incomparable + * -2 if some error occurred. + */ +int isl_basic_set_compare_at(__isl_keep isl_basic_set *bset1, + __isl_keep isl_basic_set *bset2, int pos) +{ + isl_int opt; + enum isl_lp_result res; + int cmp; + + isl_int_init(opt); + + res = basic_set_maximal_difference_at(bset1, bset2, pos, &opt); + + if (res == isl_lp_empty) + cmp = 0; + else if ((res == isl_lp_ok && isl_int_is_pos(opt)) || + res == isl_lp_unbounded) + cmp = 1; + else if (res == isl_lp_ok && isl_int_is_neg(opt)) + cmp = -1; + else + cmp = -2; + + isl_int_clear(opt); + return cmp; +} + +/* Given two basic sets bset1 and bset2, check whether + * for any common value of the parameters and dimensions preceding pos + * there is a value of dimension pos in bset1 that is larger + * than a value of the same dimension in bset2. + * + * Return + * 1 if there exists such a pair + * 0 if there is no such pair, but there is a pair of equal values + * -1 otherwise + * -2 if some error occurred. + */ +int isl_basic_set_follows_at(__isl_keep isl_basic_set *bset1, + __isl_keep isl_basic_set *bset2, int pos) +{ + isl_bool empty; + isl_basic_map *bmap; + isl_size dim1; + + dim1 = isl_basic_set_dim(bset1, isl_dim_set); + if (dim1 < 0) + return -2; + bmap = join_initial(bset1, bset2, pos); + bmap = isl_basic_map_order_ge(bmap, isl_dim_out, 0, + isl_dim_out, dim1 - pos); + empty = isl_basic_map_is_empty(bmap); + if (empty < 0) + goto error; + if (empty) { + isl_basic_map_free(bmap); + return -1; + } + bmap = isl_basic_map_order_gt(bmap, isl_dim_out, 0, + isl_dim_out, dim1 - pos); + empty = isl_basic_map_is_empty(bmap); + if (empty < 0) + goto error; + isl_basic_map_free(bmap); + if (empty) + return 0; + return 1; +error: + isl_basic_map_free(bmap); + return -2; +} + +/* Given two sets set1 and set2, check whether + * for any common value of the parameters and dimensions preceding pos + * there is a value of dimension pos in set1 that is larger + * than a value of the same dimension in set2. + * + * Return + * 1 if there exists such a pair + * 0 if there is no such pair, but there is a pair of equal values + * -1 otherwise + * -2 if some error occurred. + */ +int isl_set_follows_at(__isl_keep isl_set *set1, + __isl_keep isl_set *set2, int pos) +{ + int i, j; + int follows = -1; + + if (!set1 || !set2) + return -2; + + for (i = 0; i < set1->n; ++i) + for (j = 0; j < set2->n; ++j) { + int f; + f = isl_basic_set_follows_at(set1->p[i], set2->p[j], pos); + if (f == 1 || f == -2) + return f; + if (f > follows) + follows = f; + } + + return follows; +} + +static isl_bool isl_basic_map_plain_has_fixed_var( + __isl_keep isl_basic_map *bmap, unsigned pos, isl_int *val) +{ + int i; + int d; + isl_size total; + + total = isl_basic_map_dim(bmap, isl_dim_all); + if (total < 0) + return isl_bool_error; + for (i = 0, d = total-1; i < bmap->n_eq && d+1 > pos; ++i) { + for (; d+1 > pos; --d) + if (!isl_int_is_zero(bmap->eq[i][1+d])) + break; + if (d != pos) + continue; + if (isl_seq_first_non_zero(bmap->eq[i]+1, d) != -1) + return isl_bool_false; + if (isl_seq_first_non_zero(bmap->eq[i]+1+d+1, total-d-1) != -1) + return isl_bool_false; + if (!isl_int_is_one(bmap->eq[i][1+d])) + return isl_bool_false; + if (val) + isl_int_neg(*val, bmap->eq[i][0]); + return isl_bool_true; + } + return isl_bool_false; +} + +static isl_bool isl_map_plain_has_fixed_var(__isl_keep isl_map *map, + unsigned pos, isl_int *val) +{ + int i; + isl_int v; + isl_int tmp; + isl_bool fixed; + + if (!map) + return isl_bool_error; + if (map->n == 0) + return isl_bool_false; + if (map->n == 1) + return isl_basic_map_plain_has_fixed_var(map->p[0], pos, val); + isl_int_init(v); + isl_int_init(tmp); + fixed = isl_basic_map_plain_has_fixed_var(map->p[0], pos, &v); + for (i = 1; fixed == isl_bool_true && i < map->n; ++i) { + fixed = isl_basic_map_plain_has_fixed_var(map->p[i], pos, &tmp); + if (fixed == isl_bool_true && isl_int_ne(tmp, v)) + fixed = isl_bool_false; + } + if (val) + isl_int_set(*val, v); + isl_int_clear(tmp); + isl_int_clear(v); + return fixed; +} + +static isl_bool isl_basic_set_plain_has_fixed_var( + __isl_keep isl_basic_set *bset, unsigned pos, isl_int *val) +{ + return isl_basic_map_plain_has_fixed_var(bset_to_bmap(bset), + pos, val); +} + +isl_bool isl_basic_map_plain_is_fixed(__isl_keep isl_basic_map *bmap, + enum isl_dim_type type, unsigned pos, isl_int *val) +{ + if (isl_basic_map_check_range(bmap, type, pos, 1) < 0) + return isl_bool_error; + return isl_basic_map_plain_has_fixed_var(bmap, + isl_basic_map_offset(bmap, type) - 1 + pos, val); +} + +/* If "bmap" obviously lies on a hyperplane where the given dimension + * has a fixed value, then return that value. + * Otherwise return NaN. + */ +__isl_give isl_val *isl_basic_map_plain_get_val_if_fixed( + __isl_keep isl_basic_map *bmap, + enum isl_dim_type type, unsigned pos) +{ + isl_ctx *ctx; + isl_val *v; + isl_bool fixed; + + if (!bmap) + return NULL; + ctx = isl_basic_map_get_ctx(bmap); + v = isl_val_alloc(ctx); + if (!v) + return NULL; + fixed = isl_basic_map_plain_is_fixed(bmap, type, pos, &v->n); + if (fixed < 0) + return isl_val_free(v); + if (fixed) { + isl_int_set_si(v->d, 1); + return v; + } + isl_val_free(v); + return isl_val_nan(ctx); +} + +isl_bool isl_map_plain_is_fixed(__isl_keep isl_map *map, + enum isl_dim_type type, unsigned pos, isl_int *val) +{ + if (isl_map_check_range(map, type, pos, 1) < 0) + return isl_bool_error; + return isl_map_plain_has_fixed_var(map, + map_offset(map, type) - 1 + pos, val); +} + +/* If "map" obviously lies on a hyperplane where the given dimension + * has a fixed value, then return that value. + * Otherwise return NaN. + */ +__isl_give isl_val *isl_map_plain_get_val_if_fixed(__isl_keep isl_map *map, + enum isl_dim_type type, unsigned pos) +{ + isl_ctx *ctx; + isl_val *v; + isl_bool fixed; + + if (!map) + return NULL; + ctx = isl_map_get_ctx(map); + v = isl_val_alloc(ctx); + if (!v) + return NULL; + fixed = isl_map_plain_is_fixed(map, type, pos, &v->n); + if (fixed < 0) + return isl_val_free(v); + if (fixed) { + isl_int_set_si(v->d, 1); + return v; + } + isl_val_free(v); + return isl_val_nan(ctx); +} + +/* If "set" obviously lies on a hyperplane where the given dimension + * has a fixed value, then return that value. + * Otherwise return NaN. + */ +__isl_give isl_val *isl_set_plain_get_val_if_fixed(__isl_keep isl_set *set, + enum isl_dim_type type, unsigned pos) +{ + return isl_map_plain_get_val_if_fixed(set, type, pos); +} + +/* Return a sequence of values in the same space as "set" + * that are equal to the corresponding set dimensions of "set" + * for those set dimensions that obviously lie on a hyperplane + * where the dimension has a fixed value. + * The other elements are set to NaN. + */ +__isl_give isl_multi_val *isl_set_get_plain_multi_val_if_fixed( + __isl_keep isl_set *set) +{ + int i; + isl_size n; + isl_space *space; + isl_multi_val *mv; + + space = isl_space_drop_all_params(isl_set_get_space(set)); + mv = isl_multi_val_alloc(space); + n = isl_multi_val_size(mv); + if (n < 0) + return isl_multi_val_free(mv); + + for (i = 0; i < n; ++i) { + isl_val *v; + + v = isl_set_plain_get_val_if_fixed(set, isl_dim_set, i); + mv = isl_multi_val_set_val(mv, i, v); + } + + return mv; +} + +/* Check if dimension dim has fixed value and if so and if val is not NULL, + * then return this fixed value in *val. + */ +isl_bool isl_basic_set_plain_dim_is_fixed(__isl_keep isl_basic_set *bset, + unsigned dim, isl_int *val) +{ + isl_size nparam; + + nparam = isl_basic_set_dim(bset, isl_dim_param); + if (nparam < 0) + return isl_bool_error; + return isl_basic_set_plain_has_fixed_var(bset, nparam + dim, val); +} + +/* Return -1 if the constraint "c1" should be sorted before "c2" + * and 1 if it should be sorted after "c2". + * Return 0 if the two constraints are the same (up to the constant term). + * + * In particular, if a constraint involves later variables than another + * then it is sorted after this other constraint. + * uset_gist depends on constraints without existentially quantified + * variables sorting first. + * + * For constraints that have the same latest variable, those + * with the same coefficient for this latest variable (first in absolute value + * and then in actual value) are grouped together. + * This is useful for detecting pairs of constraints that can + * be chained in their printed representation. + * + * Finally, within a group, constraints are sorted according to + * their coefficients (excluding the constant term). + */ +static int sort_constraint_cmp(const void *p1, const void *p2, void *arg) +{ + isl_int **c1 = (isl_int **) p1; + isl_int **c2 = (isl_int **) p2; + int l1, l2; + unsigned size = *(unsigned *) arg; + int cmp; + + l1 = isl_seq_last_non_zero(*c1 + 1, size); + l2 = isl_seq_last_non_zero(*c2 + 1, size); + + if (l1 != l2) + return l1 - l2; + + cmp = isl_int_abs_cmp((*c1)[1 + l1], (*c2)[1 + l1]); + if (cmp != 0) + return cmp; + cmp = isl_int_cmp((*c1)[1 + l1], (*c2)[1 + l1]); + if (cmp != 0) + return -cmp; + + return isl_seq_cmp(*c1 + 1, *c2 + 1, size); +} + +/* Return -1 if the constraint "c1" of "bmap" is sorted before "c2" + * by isl_basic_map_sort_constraints, 1 if it is sorted after "c2" + * and 0 if the two constraints are the same (up to the constant term). + */ +int isl_basic_map_constraint_cmp(__isl_keep isl_basic_map *bmap, + isl_int *c1, isl_int *c2) +{ + isl_size total; + unsigned size; + + total = isl_basic_map_dim(bmap, isl_dim_all); + if (total < 0) + return -2; + size = total; + return sort_constraint_cmp(&c1, &c2, &size); +} + +__isl_give isl_basic_map *isl_basic_map_sort_constraints( + __isl_take isl_basic_map *bmap) +{ + isl_size total; + unsigned size; + + if (!bmap) + return NULL; + if (bmap->n_ineq == 0) + return bmap; + if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_SORTED)) + return bmap; + total = isl_basic_map_dim(bmap, isl_dim_all); + if (total < 0) + return isl_basic_map_free(bmap); + size = total; + if (isl_sort(bmap->ineq, bmap->n_ineq, sizeof(isl_int *), + &sort_constraint_cmp, &size) < 0) + return isl_basic_map_free(bmap); + ISL_F_SET(bmap, ISL_BASIC_MAP_SORTED); + return bmap; +} + +__isl_give isl_basic_set *isl_basic_set_sort_constraints( + __isl_take isl_basic_set *bset) +{ + isl_basic_map *bmap = bset_to_bmap(bset); + return bset_from_bmap(isl_basic_map_sort_constraints(bmap)); +} + +__isl_give isl_basic_map *isl_basic_map_normalize( + __isl_take isl_basic_map *bmap) +{ + bmap = isl_basic_map_remove_redundancies(bmap); + bmap = isl_basic_map_sort_constraints(bmap); + return bmap; +} +int isl_basic_map_plain_cmp(__isl_keep isl_basic_map *bmap1, + __isl_keep isl_basic_map *bmap2) +{ + int i, cmp; + isl_size total; + isl_space *space1, *space2; + + if (!bmap1 || !bmap2) + return -1; + + if (bmap1 == bmap2) + return 0; + space1 = isl_basic_map_peek_space(bmap1); + space2 = isl_basic_map_peek_space(bmap2); + cmp = isl_space_cmp(space1, space2); + if (cmp) + return cmp; + if (ISL_F_ISSET(bmap1, ISL_BASIC_MAP_RATIONAL) != + ISL_F_ISSET(bmap2, ISL_BASIC_MAP_RATIONAL)) + return ISL_F_ISSET(bmap1, ISL_BASIC_MAP_RATIONAL) ? -1 : 1; + if (ISL_F_ISSET(bmap1, ISL_BASIC_MAP_EMPTY) && + ISL_F_ISSET(bmap2, ISL_BASIC_MAP_EMPTY)) + return 0; + if (ISL_F_ISSET(bmap1, ISL_BASIC_MAP_EMPTY)) + return 1; + if (ISL_F_ISSET(bmap2, ISL_BASIC_MAP_EMPTY)) + return -1; + if (bmap1->n_eq != bmap2->n_eq) + return bmap1->n_eq - bmap2->n_eq; + if (bmap1->n_ineq != bmap2->n_ineq) + return bmap1->n_ineq - bmap2->n_ineq; + if (bmap1->n_div != bmap2->n_div) + return bmap1->n_div - bmap2->n_div; + total = isl_basic_map_dim(bmap1, isl_dim_all); + if (total < 0) + return -1; + for (i = 0; i < bmap1->n_eq; ++i) { + cmp = isl_seq_cmp(bmap1->eq[i], bmap2->eq[i], 1+total); + if (cmp) + return cmp; + } + for (i = 0; i < bmap1->n_ineq; ++i) { + cmp = isl_seq_cmp(bmap1->ineq[i], bmap2->ineq[i], 1+total); + if (cmp) + return cmp; + } + for (i = 0; i < bmap1->n_div; ++i) { + isl_bool unknown1, unknown2; + + unknown1 = isl_basic_map_div_is_marked_unknown(bmap1, i); + unknown2 = isl_basic_map_div_is_marked_unknown(bmap2, i); + if (unknown1 < 0 || unknown2 < 0) + return -1; + if (unknown1 && unknown2) + continue; + if (unknown1) + return 1; + if (unknown2) + return -1; + cmp = isl_seq_cmp(bmap1->div[i], bmap2->div[i], 1+1+total); + if (cmp) + return cmp; + } + return 0; +} + +int isl_basic_set_plain_cmp(__isl_keep isl_basic_set *bset1, + __isl_keep isl_basic_set *bset2) +{ + return isl_basic_map_plain_cmp(bset1, bset2); +} + +int isl_set_plain_cmp(__isl_keep isl_set *set1, __isl_keep isl_set *set2) +{ + int i, cmp; + + if (set1 == set2) + return 0; + if (set1->n != set2->n) + return set1->n - set2->n; + + for (i = 0; i < set1->n; ++i) { + cmp = isl_basic_set_plain_cmp(set1->p[i], set2->p[i]); + if (cmp) + return cmp; + } + + return 0; +} + +isl_bool isl_basic_map_plain_is_equal(__isl_keep isl_basic_map *bmap1, + __isl_keep isl_basic_map *bmap2) +{ + if (!bmap1 || !bmap2) + return isl_bool_error; + return isl_basic_map_plain_cmp(bmap1, bmap2) == 0; +} + +isl_bool isl_basic_set_plain_is_equal(__isl_keep isl_basic_set *bset1, + __isl_keep isl_basic_set *bset2) +{ + return isl_basic_map_plain_is_equal(bset_to_bmap(bset1), + bset_to_bmap(bset2)); +} + +static int qsort_bmap_cmp(const void *p1, const void *p2) +{ + isl_basic_map *bmap1 = *(isl_basic_map **) p1; + isl_basic_map *bmap2 = *(isl_basic_map **) p2; + + return isl_basic_map_plain_cmp(bmap1, bmap2); +} + +/* Sort the basic maps of "map" and remove duplicate basic maps. + * + * While removing basic maps, we make sure that the basic maps remain + * sorted because isl_map_normalize expects the basic maps of the result + * to be sorted. + */ +static __isl_give isl_map *sort_and_remove_duplicates(__isl_take isl_map *map) +{ + int i, j; + + map = isl_map_remove_empty_parts(map); + if (!map) + return NULL; + qsort(map->p, map->n, sizeof(struct isl_basic_map *), qsort_bmap_cmp); + for (i = map->n - 1; i >= 1; --i) { + if (!isl_basic_map_plain_is_equal(map->p[i - 1], map->p[i])) + continue; + isl_basic_map_free(map->p[i-1]); + for (j = i; j < map->n; ++j) + map->p[j - 1] = map->p[j]; + map->n--; + } + + return map; +} + +/* Remove obvious duplicates among the basic maps of "map". + * + * Unlike isl_map_normalize, this function does not remove redundant + * constraints and only removes duplicates that have exactly the same + * constraints in the input. It does sort the constraints and + * the basic maps to ease the detection of duplicates. + * + * If "map" has already been normalized or if the basic maps are + * disjoint, then there can be no duplicates. + */ +__isl_give isl_map *isl_map_remove_obvious_duplicates(__isl_take isl_map *map) +{ + int i; + isl_basic_map *bmap; + + if (!map) + return NULL; + if (map->n <= 1) + return map; + if (ISL_F_ISSET(map, ISL_MAP_NORMALIZED | ISL_MAP_DISJOINT)) + return map; + for (i = 0; i < map->n; ++i) { + bmap = isl_basic_map_copy(map->p[i]); + bmap = isl_basic_map_sort_constraints(bmap); + if (!bmap) + return isl_map_free(map); + isl_basic_map_free(map->p[i]); + map->p[i] = bmap; + } + + map = sort_and_remove_duplicates(map); + return map; +} + +/* We normalize in place, but if anything goes wrong we need + * to return NULL, so we need to make sure we don't change the + * meaning of any possible other copies of map. + */ +__isl_give isl_map *isl_map_normalize(__isl_take isl_map *map) +{ + int i; + struct isl_basic_map *bmap; + + if (!map) + return NULL; + if (ISL_F_ISSET(map, ISL_MAP_NORMALIZED)) + return map; + for (i = 0; i < map->n; ++i) { + bmap = isl_basic_map_normalize(isl_basic_map_copy(map->p[i])); + if (!bmap) + goto error; + isl_basic_map_free(map->p[i]); + map->p[i] = bmap; + } + + map = sort_and_remove_duplicates(map); + if (map) + ISL_F_SET(map, ISL_MAP_NORMALIZED); + return map; +error: + isl_map_free(map); + return NULL; +} + +__isl_give isl_set *isl_set_normalize(__isl_take isl_set *set) +{ + return set_from_map(isl_map_normalize(set_to_map(set))); +} + +isl_bool isl_map_plain_is_equal(__isl_keep isl_map *map1, + __isl_keep isl_map *map2) +{ + int i; + isl_bool equal; + + if (!map1 || !map2) + return isl_bool_error; + + if (map1 == map2) + return isl_bool_true; + equal = isl_map_has_equal_space(map1, map2); + if (equal < 0 || !equal) + return equal; + + map1 = isl_map_copy(map1); + map2 = isl_map_copy(map2); + map1 = isl_map_normalize(map1); + map2 = isl_map_normalize(map2); + if (!map1 || !map2) + goto error; + equal = map1->n == map2->n; + for (i = 0; equal && i < map1->n; ++i) { + equal = isl_basic_map_plain_is_equal(map1->p[i], map2->p[i]); + if (equal < 0) + goto error; + } + isl_map_free(map1); + isl_map_free(map2); + return equal; +error: + isl_map_free(map1); + isl_map_free(map2); + return isl_bool_error; +} + +isl_bool isl_set_plain_is_equal(__isl_keep isl_set *set1, + __isl_keep isl_set *set2) +{ + return isl_map_plain_is_equal(set_to_map(set1), set_to_map(set2)); +} + +/* Return the basic maps in "map" as a list. + */ +__isl_give isl_basic_map_list *isl_map_get_basic_map_list( + __isl_keep isl_map *map) +{ + int i; + isl_ctx *ctx; + isl_basic_map_list *list; + + if (!map) + return NULL; + ctx = isl_map_get_ctx(map); + list = isl_basic_map_list_alloc(ctx, map->n); + + for (i = 0; i < map->n; ++i) { + isl_basic_map *bmap; + + bmap = isl_basic_map_copy(map->p[i]); + list = isl_basic_map_list_add(list, bmap); + } + + return list; +} + +/* Return the intersection of the elements in the non-empty list "list". + * All elements are assumed to live in the same space. + */ +__isl_give isl_basic_map *isl_basic_map_list_intersect( + __isl_take isl_basic_map_list *list) +{ + int i; + isl_size n; + isl_basic_map *bmap; + + n = isl_basic_map_list_n_basic_map(list); + if (n < 0) + goto error; + if (n < 1) + isl_die(isl_basic_map_list_get_ctx(list), isl_error_invalid, + "expecting non-empty list", goto error); + + bmap = isl_basic_map_list_get_basic_map(list, 0); + for (i = 1; i < n; ++i) { + isl_basic_map *bmap_i; + + bmap_i = isl_basic_map_list_get_basic_map(list, i); + bmap = isl_basic_map_intersect(bmap, bmap_i); + } + + isl_basic_map_list_free(list); + return bmap; +error: + isl_basic_map_list_free(list); + return NULL; +} + +/* Return the intersection of the elements in the non-empty list "list". + * All elements are assumed to live in the same space. + */ +__isl_give isl_basic_set *isl_basic_set_list_intersect( + __isl_take isl_basic_set_list *list) +{ + return isl_basic_map_list_intersect(list); +} + +/* Return the union of the elements of "list". + * The list is required to have at least one element. + */ +__isl_give isl_set *isl_basic_set_list_union( + __isl_take isl_basic_set_list *list) +{ + int i; + isl_size n; + isl_space *space; + isl_basic_set *bset; + isl_set *set; + + n = isl_basic_set_list_n_basic_set(list); + if (n < 0) + goto error; + if (n < 1) + isl_die(isl_basic_set_list_get_ctx(list), isl_error_invalid, + "expecting non-empty list", goto error); + + bset = isl_basic_set_list_get_basic_set(list, 0); + space = isl_basic_set_get_space(bset); + isl_basic_set_free(bset); + + set = isl_set_alloc_space(space, n, 0); + for (i = 0; i < n; ++i) { + bset = isl_basic_set_list_get_basic_set(list, i); + set = isl_set_add_basic_set(set, bset); + } + + isl_basic_set_list_free(list); + return set; +error: + isl_basic_set_list_free(list); + return NULL; +} + +/* Return the union of the elements in the non-empty list "list". + * All elements are assumed to live in the same space. + */ +__isl_give isl_set *isl_set_list_union(__isl_take isl_set_list *list) +{ + int i; + isl_size n; + isl_set *set; + + n = isl_set_list_n_set(list); + if (n < 0) + goto error; + if (n < 1) + isl_die(isl_set_list_get_ctx(list), isl_error_invalid, + "expecting non-empty list", goto error); + + set = isl_set_list_get_set(list, 0); + for (i = 1; i < n; ++i) { + isl_set *set_i; + + set_i = isl_set_list_get_set(list, i); + set = isl_set_union(set, set_i); + } + + isl_set_list_free(list); + return set; +error: + isl_set_list_free(list); + return NULL; +} + +__isl_give isl_basic_map *isl_basic_map_product( + __isl_take isl_basic_map *bmap1, __isl_take isl_basic_map *bmap2) +{ + isl_space *space_result = NULL; + struct isl_basic_map *bmap; + unsigned in1, in2, out1, out2, nparam, total, pos; + struct isl_dim_map *dim_map1, *dim_map2; + + if (isl_basic_map_check_equal_params(bmap1, bmap2) < 0) + goto error; + space_result = isl_space_product(isl_space_copy(bmap1->dim), + isl_space_copy(bmap2->dim)); + + in1 = isl_basic_map_dim(bmap1, isl_dim_in); + in2 = isl_basic_map_dim(bmap2, isl_dim_in); + out1 = isl_basic_map_dim(bmap1, isl_dim_out); + out2 = isl_basic_map_dim(bmap2, isl_dim_out); + nparam = isl_basic_map_dim(bmap1, isl_dim_param); + + total = nparam + in1 + in2 + out1 + out2 + bmap1->n_div + bmap2->n_div; + dim_map1 = isl_dim_map_alloc(bmap1->ctx, total); + dim_map2 = isl_dim_map_alloc(bmap1->ctx, total); + isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_param, pos = 0); + isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_param, pos = 0); + isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_in, pos += nparam); + isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_in, pos += in1); + isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_out, pos += in2); + isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_out, pos += out1); + isl_dim_map_div(dim_map1, bmap1, pos += out2); + isl_dim_map_div(dim_map2, bmap2, pos += bmap1->n_div); + + bmap = isl_basic_map_alloc_space(space_result, + bmap1->n_div + bmap2->n_div, + bmap1->n_eq + bmap2->n_eq, + bmap1->n_ineq + bmap2->n_ineq); + bmap = isl_basic_map_add_constraints_dim_map(bmap, bmap1, dim_map1); + bmap = isl_basic_map_add_constraints_dim_map(bmap, bmap2, dim_map2); + bmap = isl_basic_map_simplify(bmap); + return isl_basic_map_finalize(bmap); +error: + isl_basic_map_free(bmap1); + isl_basic_map_free(bmap2); + return NULL; +} + +__isl_give isl_basic_map *isl_basic_map_flat_product( + __isl_take isl_basic_map *bmap1, __isl_take isl_basic_map *bmap2) +{ + isl_basic_map *prod; + + prod = isl_basic_map_product(bmap1, bmap2); + prod = isl_basic_map_flatten(prod); + return prod; +} + +__isl_give isl_basic_set *isl_basic_set_flat_product( + __isl_take isl_basic_set *bset1, __isl_take isl_basic_set *bset2) +{ + return isl_basic_map_flat_range_product(bset1, bset2); +} + +__isl_give isl_basic_map *isl_basic_map_domain_product( + __isl_take isl_basic_map *bmap1, __isl_take isl_basic_map *bmap2) +{ + isl_space *space1, *space2; + isl_space *space_result = NULL; + isl_basic_map *bmap; + isl_size in1, in2, out, nparam; + unsigned total, pos; + struct isl_dim_map *dim_map1, *dim_map2; + + in1 = isl_basic_map_dim(bmap1, isl_dim_in); + in2 = isl_basic_map_dim(bmap2, isl_dim_in); + out = isl_basic_map_dim(bmap1, isl_dim_out); + nparam = isl_basic_map_dim(bmap1, isl_dim_param); + if (in1 < 0 || in2 < 0 || out < 0 || nparam < 0) + goto error; + + space1 = isl_basic_map_get_space(bmap1); + space2 = isl_basic_map_get_space(bmap2); + space_result = isl_space_domain_product(space1, space2); + + total = nparam + in1 + in2 + out + bmap1->n_div + bmap2->n_div; + dim_map1 = isl_dim_map_alloc(bmap1->ctx, total); + dim_map2 = isl_dim_map_alloc(bmap1->ctx, total); + isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_param, pos = 0); + isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_param, pos = 0); + isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_in, pos += nparam); + isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_in, pos += in1); + isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_out, pos += in2); + isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_out, pos); + isl_dim_map_div(dim_map1, bmap1, pos += out); + isl_dim_map_div(dim_map2, bmap2, pos += bmap1->n_div); + + bmap = isl_basic_map_alloc_space(space_result, + bmap1->n_div + bmap2->n_div, + bmap1->n_eq + bmap2->n_eq, + bmap1->n_ineq + bmap2->n_ineq); + bmap = isl_basic_map_add_constraints_dim_map(bmap, bmap1, dim_map1); + bmap = isl_basic_map_add_constraints_dim_map(bmap, bmap2, dim_map2); + bmap = isl_basic_map_simplify(bmap); + return isl_basic_map_finalize(bmap); +error: + isl_basic_map_free(bmap1); + isl_basic_map_free(bmap2); + return NULL; +} + +__isl_give isl_basic_map *isl_basic_map_range_product( + __isl_take isl_basic_map *bmap1, __isl_take isl_basic_map *bmap2) +{ + isl_bool rational; + isl_space *space_result = NULL; + isl_basic_map *bmap; + isl_size in, out1, out2, nparam; + unsigned total, pos; + struct isl_dim_map *dim_map1, *dim_map2; + + rational = isl_basic_map_is_rational(bmap1); + if (rational >= 0 && rational) + rational = isl_basic_map_is_rational(bmap2); + in = isl_basic_map_dim(bmap1, isl_dim_in); + out1 = isl_basic_map_dim(bmap1, isl_dim_out); + out2 = isl_basic_map_dim(bmap2, isl_dim_out); + nparam = isl_basic_map_dim(bmap1, isl_dim_param); + if (in < 0 || out1 < 0 || out2 < 0 || nparam < 0 || rational < 0) + goto error; + + if (isl_basic_map_check_equal_params(bmap1, bmap2) < 0) + goto error; + + space_result = isl_space_range_product(isl_space_copy(bmap1->dim), + isl_space_copy(bmap2->dim)); + + total = nparam + in + out1 + out2 + bmap1->n_div + bmap2->n_div; + dim_map1 = isl_dim_map_alloc(bmap1->ctx, total); + dim_map2 = isl_dim_map_alloc(bmap1->ctx, total); + isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_param, pos = 0); + isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_param, pos = 0); + isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_in, pos += nparam); + isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_in, pos); + isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_out, pos += in); + isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_out, pos += out1); + isl_dim_map_div(dim_map1, bmap1, pos += out2); + isl_dim_map_div(dim_map2, bmap2, pos += bmap1->n_div); + + bmap = isl_basic_map_alloc_space(space_result, + bmap1->n_div + bmap2->n_div, + bmap1->n_eq + bmap2->n_eq, + bmap1->n_ineq + bmap2->n_ineq); + bmap = isl_basic_map_add_constraints_dim_map(bmap, bmap1, dim_map1); + bmap = isl_basic_map_add_constraints_dim_map(bmap, bmap2, dim_map2); + if (rational) + bmap = isl_basic_map_set_rational(bmap); + bmap = isl_basic_map_simplify(bmap); + return isl_basic_map_finalize(bmap); +error: + isl_basic_map_free(bmap1); + isl_basic_map_free(bmap2); + return NULL; +} + +__isl_give isl_basic_map *isl_basic_map_flat_range_product( + __isl_take isl_basic_map *bmap1, __isl_take isl_basic_map *bmap2) +{ + isl_basic_map *prod; + + prod = isl_basic_map_range_product(bmap1, bmap2); + prod = isl_basic_map_flatten_range(prod); + return prod; +} + +/* Apply "basic_map_product" to each pair of basic maps in "map1" and "map2" + * and collect the results. + * The result live in the space obtained by calling "space_product" + * on the spaces of "map1" and "map2". + * If "remove_duplicates" is set then the result may contain duplicates + * (even if the inputs do not) and so we try and remove the obvious + * duplicates. + */ +static __isl_give isl_map *map_product(__isl_take isl_map *map1, + __isl_take isl_map *map2, + __isl_give isl_space *(*space_product)(__isl_take isl_space *left, + __isl_take isl_space *right), + __isl_give isl_basic_map *(*basic_map_product)( + __isl_take isl_basic_map *left, + __isl_take isl_basic_map *right), + int remove_duplicates) +{ + unsigned flags = 0; + struct isl_map *result; + int i, j; + isl_bool m; + + m = isl_map_has_equal_params(map1, map2); + if (m < 0) + goto error; + if (!m) + isl_die(isl_map_get_ctx(map1), isl_error_invalid, + "parameters don't match", goto error); + + if (ISL_F_ISSET(map1, ISL_MAP_DISJOINT) && + ISL_F_ISSET(map2, ISL_MAP_DISJOINT)) + ISL_FL_SET(flags, ISL_MAP_DISJOINT); + + result = isl_map_alloc_space(space_product(isl_space_copy(map1->dim), + isl_space_copy(map2->dim)), + map1->n * map2->n, flags); + if (!result) + goto error; + for (i = 0; i < map1->n; ++i) + for (j = 0; j < map2->n; ++j) { + struct isl_basic_map *part; + part = basic_map_product(isl_basic_map_copy(map1->p[i]), + isl_basic_map_copy(map2->p[j])); + if (isl_basic_map_is_empty(part)) + isl_basic_map_free(part); + else + result = isl_map_add_basic_map(result, part); + if (!result) + goto error; + } + if (remove_duplicates) + result = isl_map_remove_obvious_duplicates(result); + isl_map_free(map1); + isl_map_free(map2); + return result; +error: + isl_map_free(map1); + isl_map_free(map2); + return NULL; +} + +/* Given two maps A -> B and C -> D, construct a map [A -> C] -> [B -> D] + */ +__isl_give isl_map *isl_map_product(__isl_take isl_map *map1, + __isl_take isl_map *map2) +{ + isl_map_align_params_bin(&map1, &map2); + return map_product(map1, map2, &isl_space_product, + &isl_basic_map_product, 0); +} + +/* Given two maps A -> B and C -> D, construct a map (A, C) -> (B, D) + */ +__isl_give isl_map *isl_map_flat_product(__isl_take isl_map *map1, + __isl_take isl_map *map2) +{ + isl_map *prod; + + prod = isl_map_product(map1, map2); + prod = isl_map_flatten(prod); + return prod; +} + +/* Given two set A and B, construct its Cartesian product A x B. + */ +__isl_give isl_set *isl_set_product(__isl_take isl_set *set1, + __isl_take isl_set *set2) +{ + return isl_map_range_product(set1, set2); +} + +__isl_give isl_set *isl_set_flat_product(__isl_take isl_set *set1, + __isl_take isl_set *set2) +{ + return isl_map_flat_range_product(set1, set2); +} + +/* Given two maps A -> B and C -> D, construct a map [A -> C] -> (B * D) + */ +__isl_give isl_map *isl_map_domain_product(__isl_take isl_map *map1, + __isl_take isl_map *map2) +{ + isl_map_align_params_bin(&map1, &map2); + return map_product(map1, map2, &isl_space_domain_product, + &isl_basic_map_domain_product, 1); +} + +/* Given two maps A -> B and C -> D, construct a map (A * C) -> [B -> D] + */ +__isl_give isl_map *isl_map_range_product(__isl_take isl_map *map1, + __isl_take isl_map *map2) +{ + isl_map_align_params_bin(&map1, &map2); + return map_product(map1, map2, &isl_space_range_product, + &isl_basic_map_range_product, 1); +} + +/* Given a map of the form [A -> B] -> [C -> D], return the map A -> C. + */ +__isl_give isl_map *isl_map_factor_domain(__isl_take isl_map *map) +{ + isl_space *space; + isl_size total1, keep1, total2, keep2; + + total1 = isl_map_dim(map, isl_dim_in); + total2 = isl_map_dim(map, isl_dim_out); + if (total1 < 0 || total2 < 0) + return isl_map_free(map); + if (!isl_space_domain_is_wrapping(map->dim) || + !isl_space_range_is_wrapping(map->dim)) + isl_die(isl_map_get_ctx(map), isl_error_invalid, + "not a product", return isl_map_free(map)); + + space = isl_map_get_space(map); + space = isl_space_factor_domain(space); + keep1 = isl_space_dim(space, isl_dim_in); + keep2 = isl_space_dim(space, isl_dim_out); + if (keep1 < 0 || keep2 < 0) + map = isl_map_free(map); + map = isl_map_project_out(map, isl_dim_in, keep1, total1 - keep1); + map = isl_map_project_out(map, isl_dim_out, keep2, total2 - keep2); + map = isl_map_reset_space(map, space); + + return map; +} + +/* Given a map of the form [A -> B] -> [C -> D], return the map B -> D. + */ +__isl_give isl_map *isl_map_factor_range(__isl_take isl_map *map) +{ + isl_space *space; + isl_size total1, keep1, total2, keep2; + + total1 = isl_map_dim(map, isl_dim_in); + total2 = isl_map_dim(map, isl_dim_out); + if (total1 < 0 || total2 < 0) + return isl_map_free(map); + if (!isl_space_domain_is_wrapping(map->dim) || + !isl_space_range_is_wrapping(map->dim)) + isl_die(isl_map_get_ctx(map), isl_error_invalid, + "not a product", return isl_map_free(map)); + + space = isl_map_get_space(map); + space = isl_space_factor_range(space); + keep1 = isl_space_dim(space, isl_dim_in); + keep2 = isl_space_dim(space, isl_dim_out); + if (keep1 < 0 || keep2 < 0) + map = isl_map_free(map); + map = isl_map_project_out(map, isl_dim_in, 0, total1 - keep1); + map = isl_map_project_out(map, isl_dim_out, 0, total2 - keep2); + map = isl_map_reset_space(map, space); + + return map; +} + +/* Given a map of the form [A -> B] -> C, return the map A -> C. + */ +__isl_give isl_map *isl_map_domain_factor_domain(__isl_take isl_map *map) +{ + isl_space *space; + isl_size total, keep; + + total = isl_map_dim(map, isl_dim_in); + if (total < 0) + return isl_map_free(map); + if (!isl_space_domain_is_wrapping(map->dim)) + isl_die(isl_map_get_ctx(map), isl_error_invalid, + "domain is not a product", return isl_map_free(map)); + + space = isl_map_get_space(map); + space = isl_space_domain_factor_domain(space); + keep = isl_space_dim(space, isl_dim_in); + if (keep < 0) + map = isl_map_free(map); + map = isl_map_project_out(map, isl_dim_in, keep, total - keep); + map = isl_map_reset_space(map, space); + + return map; +} + +/* Given a map of the form [A -> B] -> C, return the map B -> C. + */ +__isl_give isl_map *isl_map_domain_factor_range(__isl_take isl_map *map) +{ + isl_space *space; + isl_size total, keep; + + total = isl_map_dim(map, isl_dim_in); + if (total < 0) + return isl_map_free(map); + if (!isl_space_domain_is_wrapping(map->dim)) + isl_die(isl_map_get_ctx(map), isl_error_invalid, + "domain is not a product", return isl_map_free(map)); + + space = isl_map_get_space(map); + space = isl_space_domain_factor_range(space); + keep = isl_space_dim(space, isl_dim_in); + if (keep < 0) + map = isl_map_free(map); + map = isl_map_project_out(map, isl_dim_in, 0, total - keep); + map = isl_map_reset_space(map, space); + + return map; +} + +/* Given a map A -> [B -> C], extract the map A -> B. + */ +__isl_give isl_map *isl_map_range_factor_domain(__isl_take isl_map *map) +{ + isl_space *space; + isl_size total, keep; + + total = isl_map_dim(map, isl_dim_out); + if (total < 0) + return isl_map_free(map); + if (!isl_space_range_is_wrapping(map->dim)) + isl_die(isl_map_get_ctx(map), isl_error_invalid, + "range is not a product", return isl_map_free(map)); + + space = isl_map_get_space(map); + space = isl_space_range_factor_domain(space); + keep = isl_space_dim(space, isl_dim_out); + if (keep < 0) + map = isl_map_free(map); + map = isl_map_project_out(map, isl_dim_out, keep, total - keep); + map = isl_map_reset_space(map, space); + + return map; +} + +/* Given a map A -> [B -> C], extract the map A -> C. + */ +__isl_give isl_map *isl_map_range_factor_range(__isl_take isl_map *map) +{ + isl_space *space; + isl_size total, keep; + + total = isl_map_dim(map, isl_dim_out); + if (total < 0) + return isl_map_free(map); + if (!isl_space_range_is_wrapping(map->dim)) + isl_die(isl_map_get_ctx(map), isl_error_invalid, + "range is not a product", return isl_map_free(map)); + + space = isl_map_get_space(map); + space = isl_space_range_factor_range(space); + keep = isl_space_dim(space, isl_dim_out); + if (keep < 0) + map = isl_map_free(map); + map = isl_map_project_out(map, isl_dim_out, 0, total - keep); + map = isl_map_reset_space(map, space); + + return map; +} + +/* Given two maps A -> B and C -> D, construct a map (A, C) -> (B * D) + */ +__isl_give isl_map *isl_map_flat_domain_product(__isl_take isl_map *map1, + __isl_take isl_map *map2) +{ + isl_map *prod; + + prod = isl_map_domain_product(map1, map2); + prod = isl_map_flatten_domain(prod); + return prod; +} + +/* Given two maps A -> B and C -> D, construct a map (A * C) -> (B, D) + */ +__isl_give isl_map *isl_map_flat_range_product(__isl_take isl_map *map1, + __isl_take isl_map *map2) +{ + isl_map *prod; + + prod = isl_map_range_product(map1, map2); + prod = isl_map_flatten_range(prod); + return prod; +} + +uint32_t isl_basic_map_get_hash(__isl_keep isl_basic_map *bmap) +{ + int i; + uint32_t hash = isl_hash_init(); + isl_size total; + + if (!bmap) + return 0; + bmap = isl_basic_map_copy(bmap); + bmap = isl_basic_map_normalize(bmap); + total = isl_basic_map_dim(bmap, isl_dim_all); + if (total < 0) + return 0; + isl_hash_byte(hash, bmap->n_eq & 0xFF); + for (i = 0; i < bmap->n_eq; ++i) { + uint32_t c_hash; + c_hash = isl_seq_get_hash(bmap->eq[i], 1 + total); + isl_hash_hash(hash, c_hash); + } + isl_hash_byte(hash, bmap->n_ineq & 0xFF); + for (i = 0; i < bmap->n_ineq; ++i) { + uint32_t c_hash; + c_hash = isl_seq_get_hash(bmap->ineq[i], 1 + total); + isl_hash_hash(hash, c_hash); + } + isl_hash_byte(hash, bmap->n_div & 0xFF); + for (i = 0; i < bmap->n_div; ++i) { + uint32_t c_hash; + if (isl_int_is_zero(bmap->div[i][0])) + continue; + isl_hash_byte(hash, i & 0xFF); + c_hash = isl_seq_get_hash(bmap->div[i], 1 + 1 + total); + isl_hash_hash(hash, c_hash); + } + isl_basic_map_free(bmap); + return hash; +} + +uint32_t isl_basic_set_get_hash(__isl_keep isl_basic_set *bset) +{ + return isl_basic_map_get_hash(bset_to_bmap(bset)); +} + +uint32_t isl_map_get_hash(__isl_keep isl_map *map) +{ + int i; + uint32_t hash; + + if (!map) + return 0; + map = isl_map_copy(map); + map = isl_map_normalize(map); + if (!map) + return 0; + + hash = isl_hash_init(); + for (i = 0; i < map->n; ++i) { + uint32_t bmap_hash; + bmap_hash = isl_basic_map_get_hash(map->p[i]); + isl_hash_hash(hash, bmap_hash); + } + + isl_map_free(map); + + return hash; +} + +uint32_t isl_set_get_hash(__isl_keep isl_set *set) +{ + return isl_map_get_hash(set_to_map(set)); +} + +/* Return the number of basic maps in the (current) representation of "map". + */ +isl_size isl_map_n_basic_map(__isl_keep isl_map *map) +{ + return map ? map->n : isl_size_error; +} + +isl_size isl_set_n_basic_set(__isl_keep isl_set *set) +{ + return set ? set->n : isl_size_error; +} + +isl_stat isl_map_foreach_basic_map(__isl_keep isl_map *map, + isl_stat (*fn)(__isl_take isl_basic_map *bmap, void *user), void *user) +{ + int i; + + if (!map) + return isl_stat_error; + + for (i = 0; i < map->n; ++i) + if (fn(isl_basic_map_copy(map->p[i]), user) < 0) + return isl_stat_error; + + return isl_stat_ok; +} + +isl_stat isl_set_foreach_basic_set(__isl_keep isl_set *set, + isl_stat (*fn)(__isl_take isl_basic_set *bset, void *user), void *user) +{ + int i; + + if (!set) + return isl_stat_error; + + for (i = 0; i < set->n; ++i) + if (fn(isl_basic_set_copy(set->p[i]), user) < 0) + return isl_stat_error; + + return isl_stat_ok; +} + +/* Does "test" succeed on every basic set in "set"? + */ +isl_bool isl_set_every_basic_set(__isl_keep isl_set *set, + isl_bool (*test)(__isl_keep isl_basic_set *bset, void *user), + void *user) +{ + int i; + + if (!set) + return isl_bool_error; + + for (i = 0; i < set->n; ++i) { + isl_bool r; + + r = test(set->p[i], user); + if (r < 0 || !r) + return r; + } + + return isl_bool_true; +} + +/* Return a list of basic sets, the union of which is equal to "set". + */ +__isl_give isl_basic_set_list *isl_set_get_basic_set_list( + __isl_keep isl_set *set) +{ + int i; + isl_basic_set_list *list; + + if (!set) + return NULL; + + list = isl_basic_set_list_alloc(isl_set_get_ctx(set), set->n); + for (i = 0; i < set->n; ++i) { + isl_basic_set *bset; + + bset = isl_basic_set_copy(set->p[i]); + list = isl_basic_set_list_add(list, bset); + } + + return list; +} + +__isl_give isl_basic_set *isl_basic_set_lift(__isl_take isl_basic_set *bset) +{ + isl_space *space; + + if (!bset) + return NULL; + + bset = isl_basic_set_cow(bset); + if (!bset) + return NULL; + + space = isl_basic_set_get_space(bset); + space = isl_space_lift(space, bset->n_div); + if (!space) + goto error; + isl_space_free(bset->dim); + bset->dim = space; + bset->extra -= bset->n_div; + bset->n_div = 0; + + bset = isl_basic_set_finalize(bset); + + return bset; +error: + isl_basic_set_free(bset); + return NULL; +} + +__isl_give isl_set *isl_set_lift(__isl_take isl_set *set) +{ + int i; + isl_space *space; + unsigned n_div; + + set = set_from_map(isl_map_align_divs_internal(set_to_map(set))); + + if (!set) + return NULL; + + set = isl_set_cow(set); + if (!set) + return NULL; + + n_div = set->p[0]->n_div; + space = isl_set_get_space(set); + space = isl_space_lift(space, n_div); + if (!space) + goto error; + isl_space_free(set->dim); + set->dim = space; + + for (i = 0; i < set->n; ++i) { + set->p[i] = isl_basic_set_lift(set->p[i]); + if (!set->p[i]) + goto error; + } + + return set; +error: + isl_set_free(set); + return NULL; +} + +int isl_basic_set_size(__isl_keep isl_basic_set *bset) +{ + isl_size dim; + int size = 0; + + dim = isl_basic_set_dim(bset, isl_dim_all); + if (dim < 0) + return -1; + size += bset->n_eq * (1 + dim); + size += bset->n_ineq * (1 + dim); + size += bset->n_div * (2 + dim); + + return size; +} + +int isl_set_size(__isl_keep isl_set *set) +{ + int i; + int size = 0; + + if (!set) + return -1; + + for (i = 0; i < set->n; ++i) + size += isl_basic_set_size(set->p[i]); + + return size; +} + +/* Check if there is any lower bound (if lower == 0) and/or upper + * bound (if upper == 0) on the specified dim. + */ +static isl_bool basic_map_dim_is_bounded(__isl_keep isl_basic_map *bmap, + enum isl_dim_type type, unsigned pos, int lower, int upper) +{ + int i; + + if (isl_basic_map_check_range(bmap, type, pos, 1) < 0) + return isl_bool_error; + + pos += isl_basic_map_offset(bmap, type); + + for (i = 0; i < bmap->n_div; ++i) { + if (isl_int_is_zero(bmap->div[i][0])) + continue; + if (!isl_int_is_zero(bmap->div[i][1 + pos])) + return isl_bool_true; + } + + for (i = 0; i < bmap->n_eq; ++i) + if (!isl_int_is_zero(bmap->eq[i][pos])) + return isl_bool_true; + + for (i = 0; i < bmap->n_ineq; ++i) { + int sgn = isl_int_sgn(bmap->ineq[i][pos]); + if (sgn > 0) + lower = 1; + if (sgn < 0) + upper = 1; + } + + return lower && upper; +} + +isl_bool isl_basic_map_dim_is_bounded(__isl_keep isl_basic_map *bmap, + enum isl_dim_type type, unsigned pos) +{ + return basic_map_dim_is_bounded(bmap, type, pos, 0, 0); +} + +isl_bool isl_basic_map_dim_has_lower_bound(__isl_keep isl_basic_map *bmap, + enum isl_dim_type type, unsigned pos) +{ + return basic_map_dim_is_bounded(bmap, type, pos, 0, 1); +} + +isl_bool isl_basic_map_dim_has_upper_bound(__isl_keep isl_basic_map *bmap, + enum isl_dim_type type, unsigned pos) +{ + return basic_map_dim_is_bounded(bmap, type, pos, 1, 0); +} + +isl_bool isl_map_dim_is_bounded(__isl_keep isl_map *map, + enum isl_dim_type type, unsigned pos) +{ + int i; + + if (!map) + return isl_bool_error; + + for (i = 0; i < map->n; ++i) { + isl_bool bounded; + bounded = isl_basic_map_dim_is_bounded(map->p[i], type, pos); + if (bounded < 0 || !bounded) + return bounded; + } + + return isl_bool_true; +} + +/* Return true if the specified dim is involved in both an upper bound + * and a lower bound. + */ +isl_bool isl_set_dim_is_bounded(__isl_keep isl_set *set, + enum isl_dim_type type, unsigned pos) +{ + return isl_map_dim_is_bounded(set_to_map(set), type, pos); +} + +/* Does "map" have a bound (according to "fn") for any of its basic maps? + */ +static isl_bool has_any_bound(__isl_keep isl_map *map, + enum isl_dim_type type, unsigned pos, + isl_bool (*fn)(__isl_keep isl_basic_map *bmap, + enum isl_dim_type type, unsigned pos)) +{ + int i; + + if (!map) + return isl_bool_error; + + for (i = 0; i < map->n; ++i) { + isl_bool bounded; + bounded = fn(map->p[i], type, pos); + if (bounded < 0 || bounded) + return bounded; + } + + return isl_bool_false; +} + +/* Return 1 if the specified dim is involved in any lower bound. + */ +isl_bool isl_set_dim_has_any_lower_bound(__isl_keep isl_set *set, + enum isl_dim_type type, unsigned pos) +{ + return has_any_bound(set, type, pos, + &isl_basic_map_dim_has_lower_bound); +} + +/* Return 1 if the specified dim is involved in any upper bound. + */ +isl_bool isl_set_dim_has_any_upper_bound(__isl_keep isl_set *set, + enum isl_dim_type type, unsigned pos) +{ + return has_any_bound(set, type, pos, + &isl_basic_map_dim_has_upper_bound); +} + +/* Does "map" have a bound (according to "fn") for all of its basic maps? + */ +static isl_bool has_bound(__isl_keep isl_map *map, + enum isl_dim_type type, unsigned pos, + isl_bool (*fn)(__isl_keep isl_basic_map *bmap, + enum isl_dim_type type, unsigned pos)) +{ + int i; + + if (!map) + return isl_bool_error; + + for (i = 0; i < map->n; ++i) { + isl_bool bounded; + bounded = fn(map->p[i], type, pos); + if (bounded < 0 || !bounded) + return bounded; + } + + return isl_bool_true; +} + +/* Return 1 if the specified dim has a lower bound (in each of its basic sets). + */ +isl_bool isl_set_dim_has_lower_bound(__isl_keep isl_set *set, + enum isl_dim_type type, unsigned pos) +{ + return has_bound(set, type, pos, &isl_basic_map_dim_has_lower_bound); +} + +/* Return 1 if the specified dim has an upper bound (in each of its basic sets). + */ +isl_bool isl_set_dim_has_upper_bound(__isl_keep isl_set *set, + enum isl_dim_type type, unsigned pos) +{ + return has_bound(set, type, pos, &isl_basic_map_dim_has_upper_bound); +} + +/* For each of the "n" variables starting at "first", determine + * the sign of the variable and put the results in the first "n" + * elements of the array "signs". + * Sign + * 1 means that the variable is non-negative + * -1 means that the variable is non-positive + * 0 means the variable attains both positive and negative values. + */ +isl_stat isl_basic_set_vars_get_sign(__isl_keep isl_basic_set *bset, + unsigned first, unsigned n, int *signs) +{ + isl_vec *bound = NULL; + struct isl_tab *tab = NULL; + struct isl_tab_undo *snap; + int i; + isl_size total; + + total = isl_basic_set_dim(bset, isl_dim_all); + if (total < 0 || !signs) + return isl_stat_error; + + bound = isl_vec_alloc(bset->ctx, 1 + total); + tab = isl_tab_from_basic_set(bset, 0); + if (!bound || !tab) + goto error; + + isl_seq_clr(bound->el, bound->size); + isl_int_set_si(bound->el[0], -1); + + snap = isl_tab_snap(tab); + for (i = 0; i < n; ++i) { + int empty; + + isl_int_set_si(bound->el[1 + first + i], -1); + if (isl_tab_add_ineq(tab, bound->el) < 0) + goto error; + empty = tab->empty; + isl_int_set_si(bound->el[1 + first + i], 0); + if (isl_tab_rollback(tab, snap) < 0) + goto error; + + if (empty) { + signs[i] = 1; + continue; + } + + isl_int_set_si(bound->el[1 + first + i], 1); + if (isl_tab_add_ineq(tab, bound->el) < 0) + goto error; + empty = tab->empty; + isl_int_set_si(bound->el[1 + first + i], 0); + if (isl_tab_rollback(tab, snap) < 0) + goto error; + + signs[i] = empty ? -1 : 0; + } + + isl_tab_free(tab); + isl_vec_free(bound); + return isl_stat_ok; +error: + isl_tab_free(tab); + isl_vec_free(bound); + return isl_stat_error; +} + +isl_stat isl_basic_set_dims_get_sign(__isl_keep isl_basic_set *bset, + enum isl_dim_type type, unsigned first, unsigned n, int *signs) +{ + if (!bset || !signs) + return isl_stat_error; + if (isl_basic_set_check_range(bset, type, first, n) < 0) + return isl_stat_error; + + first += pos(bset->dim, type) - 1; + return isl_basic_set_vars_get_sign(bset, first, n, signs); +} + +/* Is it possible for the integer division "div" to depend (possibly + * indirectly) on any output dimensions? + * + * If the div is undefined, then we conservatively assume that it + * may depend on them. + * Otherwise, we check if it actually depends on them or on any integer + * divisions that may depend on them. + */ +static isl_bool div_may_involve_output(__isl_keep isl_basic_map *bmap, int div) +{ + int i; + isl_size n_out, n_div; + unsigned o_out, o_div; + + if (isl_int_is_zero(bmap->div[div][0])) + return isl_bool_true; + + n_out = isl_basic_map_dim(bmap, isl_dim_out); + if (n_out < 0) + return isl_bool_error; + o_out = isl_basic_map_offset(bmap, isl_dim_out); + + if (isl_seq_first_non_zero(bmap->div[div] + 1 + o_out, n_out) != -1) + return isl_bool_true; + + n_div = isl_basic_map_dim(bmap, isl_dim_div); + if (n_div < 0) + return isl_bool_error; + o_div = isl_basic_map_offset(bmap, isl_dim_div); + + for (i = 0; i < n_div; ++i) { + isl_bool may_involve; + + if (isl_int_is_zero(bmap->div[div][1 + o_div + i])) + continue; + may_involve = div_may_involve_output(bmap, i); + if (may_involve < 0 || may_involve) + return may_involve; + } + + return isl_bool_false; +} + +/* Return the first integer division of "bmap" in the range + * [first, first + n[ that may depend on any output dimensions and + * that has a non-zero coefficient in "c" (where the first coefficient + * in "c" corresponds to integer division "first"). + */ +static int first_div_may_involve_output(__isl_keep isl_basic_map *bmap, + isl_int *c, int first, int n) +{ + int k; + + if (!bmap) + return -1; + + for (k = first; k < first + n; ++k) { + isl_bool may_involve; + + if (isl_int_is_zero(c[k])) + continue; + may_involve = div_may_involve_output(bmap, k); + if (may_involve < 0) + return -1; + if (may_involve) + return k; + } + + return first + n; +} + +/* Look for a pair of inequality constraints in "bmap" of the form + * + * -l + i >= 0 or i >= l + * and + * n + l - i >= 0 or i <= l + n + * + * with n < "m" and i the output dimension at position "pos". + * (Note that n >= 0 as otherwise the two constraints would conflict.) + * Furthermore, "l" is only allowed to involve parameters, input dimensions + * and earlier output dimensions, as well as integer divisions that do + * not involve any of the output dimensions. + * + * Return the index of the first inequality constraint or bmap->n_ineq + * if no such pair can be found. + */ +static int find_modulo_constraint_pair(__isl_keep isl_basic_map *bmap, + int pos, isl_int m) +{ + int i, j; + isl_ctx *ctx; + isl_size total; + isl_size n_div, n_out; + unsigned o_div, o_out; + int less; + + total = isl_basic_map_dim(bmap, isl_dim_all); + n_out = isl_basic_map_dim(bmap, isl_dim_out); + n_div = isl_basic_map_dim(bmap, isl_dim_div); + if (total < 0 || n_out < 0 || n_div < 0) + return -1; + + ctx = isl_basic_map_get_ctx(bmap); + o_out = isl_basic_map_offset(bmap, isl_dim_out); + o_div = isl_basic_map_offset(bmap, isl_dim_div); + for (i = 0; i < bmap->n_ineq; ++i) { + if (!isl_int_abs_eq(bmap->ineq[i][o_out + pos], ctx->one)) + continue; + if (isl_seq_first_non_zero(bmap->ineq[i] + o_out + pos + 1, + n_out - (pos + 1)) != -1) + continue; + if (first_div_may_involve_output(bmap, bmap->ineq[i] + o_div, + 0, n_div) < n_div) + continue; + for (j = i + 1; j < bmap->n_ineq; ++j) { + if (!isl_int_abs_eq(bmap->ineq[j][o_out + pos], + ctx->one)) + continue; + if (!isl_seq_is_neg(bmap->ineq[i] + 1, + bmap->ineq[j] + 1, total)) + continue; + break; + } + if (j >= bmap->n_ineq) + continue; + isl_int_add(bmap->ineq[i][0], + bmap->ineq[i][0], bmap->ineq[j][0]); + less = isl_int_abs_lt(bmap->ineq[i][0], m); + isl_int_sub(bmap->ineq[i][0], + bmap->ineq[i][0], bmap->ineq[j][0]); + if (!less) + continue; + if (isl_int_is_one(bmap->ineq[i][o_out + pos])) + return i; + else + return j; + } + + return bmap->n_ineq; +} + +/* Return the index of the equality of "bmap" that defines + * the output dimension "pos" in terms of earlier dimensions. + * The equality may also involve integer divisions, as long + * as those integer divisions are defined in terms of + * parameters or input dimensions. + * In this case, *div is set to the number of integer divisions and + * *ineq is set to the number of inequality constraints (provided + * div and ineq are not NULL). + * + * The equality may also involve a single integer division involving + * the output dimensions (typically only output dimension "pos") as + * long as the coefficient of output dimension "pos" is 1 or -1 and + * there is a pair of constraints i >= l and i <= l + n, with i referring + * to output dimension "pos", l an expression involving only earlier + * dimensions and n smaller than the coefficient of the integer division + * in the equality. In this case, the output dimension can be defined + * in terms of a modulo expression that does not involve the integer division. + * *div is then set to this single integer division and + * *ineq is set to the index of constraint i >= l. + * + * Return bmap->n_eq if there is no such equality. + * Return -1 on error. + */ +int isl_basic_map_output_defining_equality(__isl_keep isl_basic_map *bmap, + int pos, int *div, int *ineq) +{ + int j, k, l; + isl_size n_div, n_out; + unsigned o_div, o_out; + + n_out = isl_basic_map_dim(bmap, isl_dim_out); + n_div = isl_basic_map_dim(bmap, isl_dim_div); + if (n_out < 0 || n_div < 0) + return -1; + + o_out = isl_basic_map_offset(bmap, isl_dim_out); + o_div = isl_basic_map_offset(bmap, isl_dim_div); + + if (ineq) + *ineq = bmap->n_ineq; + if (div) + *div = n_div; + for (j = 0; j < bmap->n_eq; ++j) { + if (isl_int_is_zero(bmap->eq[j][o_out + pos])) + continue; + if (isl_seq_first_non_zero(bmap->eq[j] + o_out + pos + 1, + n_out - (pos + 1)) != -1) + continue; + k = first_div_may_involve_output(bmap, bmap->eq[j] + o_div, + 0, n_div); + if (k >= n_div) + return j; + if (!isl_int_is_one(bmap->eq[j][o_out + pos]) && + !isl_int_is_negone(bmap->eq[j][o_out + pos])) + continue; + if (first_div_may_involve_output(bmap, bmap->eq[j] + o_div, + k + 1, n_div - (k+1)) < n_div) + continue; + l = find_modulo_constraint_pair(bmap, pos, + bmap->eq[j][o_div + k]); + if (l < 0) + return -1; + if (l >= bmap->n_ineq) + continue; + if (div) + *div = k; + if (ineq) + *ineq = l; + return j; + } + + return bmap->n_eq; +} + +/* Check if the given basic map is obviously single-valued. + * In particular, for each output dimension, check that there is + * an equality that defines the output dimension in terms of + * earlier dimensions. + */ +isl_bool isl_basic_map_plain_is_single_valued(__isl_keep isl_basic_map *bmap) +{ + int i; + isl_size n_out; + + n_out = isl_basic_map_dim(bmap, isl_dim_out); + if (n_out < 0) + return isl_bool_error; + + for (i = 0; i < n_out; ++i) { + int eq; + + eq = isl_basic_map_output_defining_equality(bmap, i, + NULL, NULL); + if (eq < 0) + return isl_bool_error; + if (eq >= bmap->n_eq) + return isl_bool_false; + } + + return isl_bool_true; +} + +/* Check if the given basic map is single-valued. + * We simply compute + * + * M \circ M^-1 + * + * and check if the result is a subset of the identity mapping. + */ +isl_bool isl_basic_map_is_single_valued(__isl_keep isl_basic_map *bmap) +{ + isl_space *space; + isl_basic_map *test; + isl_basic_map *id; + isl_bool sv; + + sv = isl_basic_map_plain_is_single_valued(bmap); + if (sv < 0 || sv) + return sv; + + test = isl_basic_map_reverse(isl_basic_map_copy(bmap)); + test = isl_basic_map_apply_range(test, isl_basic_map_copy(bmap)); + + space = isl_basic_map_get_space(bmap); + space = isl_space_map_from_set(isl_space_range(space)); + id = isl_basic_map_identity(space); + + sv = isl_basic_map_is_subset(test, id); + + isl_basic_map_free(test); + isl_basic_map_free(id); + + return sv; +} + +/* Check if the given map is obviously single-valued. + */ +isl_bool isl_map_plain_is_single_valued(__isl_keep isl_map *map) +{ + if (!map) + return isl_bool_error; + if (map->n == 0) + return isl_bool_true; + if (map->n >= 2) + return isl_bool_false; + + return isl_basic_map_plain_is_single_valued(map->p[0]); +} + +/* Check if the given map is single-valued. + * We simply compute + * + * M \circ M^-1 + * + * and check if the result is a subset of the identity mapping. + */ +isl_bool isl_map_is_single_valued(__isl_keep isl_map *map) +{ + isl_space *space; + isl_map *test; + isl_map *id; + isl_bool sv; + + sv = isl_map_plain_is_single_valued(map); + if (sv < 0 || sv) + return sv; + + test = isl_map_reverse(isl_map_copy(map)); + test = isl_map_apply_range(test, isl_map_copy(map)); + + space = isl_space_map_from_set(isl_space_range(isl_map_get_space(map))); + id = isl_map_identity(space); + + sv = isl_map_is_subset(test, id); + + isl_map_free(test); + isl_map_free(id); + + return sv; +} + +isl_bool isl_map_is_injective(__isl_keep isl_map *map) +{ + isl_bool in; + + map = isl_map_copy(map); + map = isl_map_reverse(map); + in = isl_map_is_single_valued(map); + isl_map_free(map); + + return in; +} + +/* Check if the given map is obviously injective. + */ +isl_bool isl_map_plain_is_injective(__isl_keep isl_map *map) +{ + isl_bool in; + + map = isl_map_copy(map); + map = isl_map_reverse(map); + in = isl_map_plain_is_single_valued(map); + isl_map_free(map); + + return in; +} + +isl_bool isl_map_is_bijective(__isl_keep isl_map *map) +{ + isl_bool sv; + + sv = isl_map_is_single_valued(map); + if (sv < 0 || !sv) + return sv; + + return isl_map_is_injective(map); +} + +isl_bool isl_set_is_singleton(__isl_keep isl_set *set) +{ + return isl_map_is_single_valued(set_to_map(set)); +} + +/* Does "map" only map elements to themselves? + * + * If the domain and range spaces are different, then "map" + * is considered not to be an identity relation, even if it is empty. + * Otherwise, construct the maximal identity relation and + * check whether "map" is a subset of this relation. + */ +isl_bool isl_map_is_identity(__isl_keep isl_map *map) +{ + isl_map *id; + isl_bool equal, is_identity; + + equal = isl_map_tuple_is_equal(map, isl_dim_in, map, isl_dim_out); + if (equal < 0 || !equal) + return equal; + + id = isl_map_identity(isl_map_get_space(map)); + is_identity = isl_map_is_subset(map, id); + isl_map_free(id); + + return is_identity; +} + +int isl_map_is_translation(__isl_keep isl_map *map) +{ + int ok; + isl_set *delta; + + delta = isl_map_deltas(isl_map_copy(map)); + ok = isl_set_is_singleton(delta); + isl_set_free(delta); + + return ok; +} + +static int unique(isl_int *p, unsigned pos, unsigned len) +{ + if (isl_seq_first_non_zero(p, pos) != -1) + return 0; + if (isl_seq_first_non_zero(p + pos + 1, len - pos - 1) != -1) + return 0; + return 1; +} + +isl_bool isl_basic_set_is_box(__isl_keep isl_basic_set *bset) +{ + int i, j; + isl_size nvar, ovar, n_div; + + n_div = isl_basic_set_dim(bset, isl_dim_div); + if (n_div < 0) + return isl_bool_error; + if (n_div != 0) + return isl_bool_false; + + nvar = isl_basic_set_dim(bset, isl_dim_set); + ovar = isl_space_offset(bset->dim, isl_dim_set); + if (nvar < 0 || ovar < 0) + return isl_bool_error; + for (j = 0; j < nvar; ++j) { + int lower = 0, upper = 0; + for (i = 0; i < bset->n_eq; ++i) { + if (isl_int_is_zero(bset->eq[i][1 + ovar + j])) + continue; + if (!unique(bset->eq[i] + 1 + ovar, j, nvar)) + return isl_bool_false; + break; + } + if (i < bset->n_eq) + continue; + for (i = 0; i < bset->n_ineq; ++i) { + if (isl_int_is_zero(bset->ineq[i][1 + ovar + j])) + continue; + if (!unique(bset->ineq[i] + 1 + ovar, j, nvar)) + return isl_bool_false; + if (isl_int_is_pos(bset->ineq[i][1 + ovar + j])) + lower = 1; + else + upper = 1; + } + if (!lower || !upper) + return isl_bool_false; + } + + return isl_bool_true; +} + +isl_bool isl_set_is_box(__isl_keep isl_set *set) +{ + if (!set) + return isl_bool_error; + if (set->n != 1) + return isl_bool_false; + + return isl_basic_set_is_box(set->p[0]); +} + +isl_bool isl_basic_set_is_wrapping(__isl_keep isl_basic_set *bset) +{ + if (!bset) + return isl_bool_error; + + return isl_space_is_wrapping(bset->dim); +} + +isl_bool isl_set_is_wrapping(__isl_keep isl_set *set) +{ + if (!set) + return isl_bool_error; + + return isl_space_is_wrapping(set->dim); +} + +/* Modify the space of "map" through a call to "change". + * If "can_change" is set (not NULL), then first call it to check + * if the modification is allowed, printing the error message "cannot_change" + * if it is not. + */ +static __isl_give isl_map *isl_map_change_space(__isl_take isl_map *map, + isl_bool (*can_change)(__isl_keep isl_map *map), + const char *cannot_change, + __isl_give isl_space *(*change)(__isl_take isl_space *space)) +{ + isl_bool ok; + isl_space *space; + + if (!map) + return NULL; + + ok = can_change ? can_change(map) : isl_bool_true; + if (ok < 0) + return isl_map_free(map); + if (!ok) + isl_die(isl_map_get_ctx(map), isl_error_invalid, cannot_change, + return isl_map_free(map)); + + space = change(isl_map_get_space(map)); + map = isl_map_reset_space(map, space); + + return map; +} + +/* Is the domain of "map" a wrapped relation? + */ +isl_bool isl_map_domain_is_wrapping(__isl_keep isl_map *map) +{ + if (!map) + return isl_bool_error; + + return isl_space_domain_is_wrapping(map->dim); +} + +/* Does "map" have a wrapped relation in both domain and range? + */ +isl_bool isl_map_is_product(__isl_keep isl_map *map) +{ + return isl_space_is_product(isl_map_peek_space(map)); +} + +/* Is the range of "map" a wrapped relation? + */ +isl_bool isl_map_range_is_wrapping(__isl_keep isl_map *map) +{ + if (!map) + return isl_bool_error; + + return isl_space_range_is_wrapping(map->dim); +} + +__isl_give isl_basic_set *isl_basic_map_wrap(__isl_take isl_basic_map *bmap) +{ + isl_space *space; + + space = isl_basic_map_take_space(bmap); + space = isl_space_wrap(space); + bmap = isl_basic_map_restore_space(bmap, space); + + bmap = isl_basic_map_finalize(bmap); + + return bset_from_bmap(bmap); +} + +/* Given a map A -> B, return the set (A -> B). + */ +__isl_give isl_set *isl_map_wrap(__isl_take isl_map *map) +{ + return isl_map_change_space(map, NULL, NULL, &isl_space_wrap); +} + +__isl_give isl_basic_map *isl_basic_set_unwrap(__isl_take isl_basic_set *bset) +{ + bset = isl_basic_set_cow(bset); + if (!bset) + return NULL; + + bset->dim = isl_space_unwrap(bset->dim); + if (!bset->dim) + goto error; + + bset = isl_basic_set_finalize(bset); + + return bset_to_bmap(bset); +error: + isl_basic_set_free(bset); + return NULL; +} + +/* Given a set (A -> B), return the map A -> B. + * Error out if "set" is not of the form (A -> B). + */ +__isl_give isl_map *isl_set_unwrap(__isl_take isl_set *set) +{ + return isl_map_change_space(set, &isl_set_is_wrapping, + "not a wrapping set", &isl_space_unwrap); +} + +__isl_give isl_basic_map *isl_basic_map_reset(__isl_take isl_basic_map *bmap, + enum isl_dim_type type) +{ + isl_space *space; + + space = isl_basic_map_take_space(bmap); + space = isl_space_reset(space, type); + bmap = isl_basic_map_restore_space(bmap, space); + + bmap = isl_basic_map_mark_final(bmap); + + return bmap; +} + +__isl_give isl_map *isl_map_reset(__isl_take isl_map *map, + enum isl_dim_type type) +{ + int i; + isl_space *space; + + if (!map) + return NULL; + + if (!isl_space_is_named_or_nested(map->dim, type)) + return map; + + map = isl_map_cow(map); + if (!map) + return NULL; + + for (i = 0; i < map->n; ++i) { + map->p[i] = isl_basic_map_reset(map->p[i], type); + if (!map->p[i]) + goto error; + } + + space = isl_map_take_space(map); + space = isl_space_reset(space, type); + map = isl_map_restore_space(map, space); + + return map; +error: + isl_map_free(map); + return NULL; +} + +__isl_give isl_basic_map *isl_basic_map_flatten(__isl_take isl_basic_map *bmap) +{ + isl_space *space; + + space = isl_basic_map_take_space(bmap); + space = isl_space_flatten(space); + bmap = isl_basic_map_restore_space(bmap, space); + + bmap = isl_basic_map_mark_final(bmap); + + return bmap; +} + +__isl_give isl_basic_set *isl_basic_set_flatten(__isl_take isl_basic_set *bset) +{ + return bset_from_bmap(isl_basic_map_flatten(bset_to_bmap(bset))); +} + +__isl_give isl_basic_map *isl_basic_map_flatten_domain( + __isl_take isl_basic_map *bmap) +{ + isl_space *space; + + space = isl_basic_map_take_space(bmap); + space = isl_space_flatten_domain(space); + bmap = isl_basic_map_restore_space(bmap, space); + + bmap = isl_basic_map_mark_final(bmap); + + return bmap; +} + +__isl_give isl_basic_map *isl_basic_map_flatten_range( + __isl_take isl_basic_map *bmap) +{ + isl_space *space; + + space = isl_basic_map_take_space(bmap); + space = isl_space_flatten_range(space); + bmap = isl_basic_map_restore_space(bmap, space); + + bmap = isl_basic_map_mark_final(bmap); + + return bmap; +} + +/* Remove any internal structure from the spaces of domain and range of "map". + */ +__isl_give isl_map *isl_map_flatten(__isl_take isl_map *map) +{ + if (!map) + return NULL; + + if (!map->dim->nested[0] && !map->dim->nested[1]) + return map; + + return isl_map_change_space(map, NULL, NULL, &isl_space_flatten); +} + +__isl_give isl_set *isl_set_flatten(__isl_take isl_set *set) +{ + return set_from_map(isl_map_flatten(set_to_map(set))); +} + +__isl_give isl_map *isl_set_flatten_map(__isl_take isl_set *set) +{ + isl_space *space, *flat_space; + isl_map *map; + + space = isl_set_get_space(set); + flat_space = isl_space_flatten(isl_space_copy(space)); + map = isl_map_identity(isl_space_join(isl_space_reverse(space), + flat_space)); + map = isl_map_intersect_domain(map, set); + + return map; +} + +/* Remove any internal structure from the space of the domain of "map". + */ +__isl_give isl_map *isl_map_flatten_domain(__isl_take isl_map *map) +{ + if (!map) + return NULL; + + if (!map->dim->nested[0]) + return map; + + return isl_map_change_space(map, NULL, NULL, &isl_space_flatten_domain); +} + +/* Remove any internal structure from the space of the range of "map". + */ +__isl_give isl_map *isl_map_flatten_range(__isl_take isl_map *map) +{ + if (!map) + return NULL; + + if (!map->dim->nested[1]) + return map; + + return isl_map_change_space(map, NULL, NULL, &isl_space_flatten_range); +} + +/* Reorder the dimensions of "bmap" according to the given dim_map + * and set the dimension specification to "space" and + * perform Gaussian elimination on the result. + */ +__isl_give isl_basic_map *isl_basic_map_realign(__isl_take isl_basic_map *bmap, + __isl_take isl_space *space, __isl_take struct isl_dim_map *dim_map) +{ + isl_basic_map *res; + unsigned flags; + isl_size n_div; + + n_div = isl_basic_map_dim(bmap, isl_dim_div); + if (n_div < 0 || !space || !dim_map) + goto error; + + flags = bmap->flags; + ISL_FL_CLR(flags, ISL_BASIC_MAP_FINAL); + ISL_FL_CLR(flags, ISL_BASIC_MAP_SORTED); + ISL_FL_CLR(flags, ISL_BASIC_MAP_NORMALIZED_DIVS); + res = isl_basic_map_alloc_space(space, n_div, bmap->n_eq, bmap->n_ineq); + res = isl_basic_map_add_constraints_dim_map(res, bmap, dim_map); + if (res) + res->flags = flags; + res = isl_basic_map_gauss(res, NULL); + res = isl_basic_map_finalize(res); + return res; +error: + isl_dim_map_free(dim_map); + isl_basic_map_free(bmap); + isl_space_free(space); + return NULL; +} + +/* Reorder the dimensions of "map" according to given reordering. + */ +__isl_give isl_map *isl_map_realign(__isl_take isl_map *map, + __isl_take isl_reordering *r) +{ + int i; + struct isl_dim_map *dim_map; + + map = isl_map_cow(map); + dim_map = isl_dim_map_from_reordering(r); + if (!map || !r || !dim_map) + goto error; + + for (i = 0; i < map->n; ++i) { + struct isl_dim_map *dim_map_i; + isl_space *space; + + dim_map_i = isl_dim_map_extend(dim_map, map->p[i]); + + space = isl_reordering_get_space(r); + map->p[i] = isl_basic_map_realign(map->p[i], space, dim_map_i); + + if (!map->p[i]) + goto error; + } + + map = isl_map_reset_space(map, isl_reordering_get_space(r)); + map = isl_map_unmark_normalized(map); + + isl_reordering_free(r); + isl_dim_map_free(dim_map); + return map; +error: + isl_dim_map_free(dim_map); + isl_map_free(map); + isl_reordering_free(r); + return NULL; +} + +__isl_give isl_set *isl_set_realign(__isl_take isl_set *set, + __isl_take isl_reordering *r) +{ + return set_from_map(isl_map_realign(set_to_map(set), r)); +} + +__isl_give isl_map *isl_map_align_params(__isl_take isl_map *map, + __isl_take isl_space *model) +{ + isl_ctx *ctx; + isl_bool aligned; + + if (!map || !model) + goto error; + + ctx = isl_space_get_ctx(model); + if (!isl_space_has_named_params(model)) + isl_die(ctx, isl_error_invalid, + "model has unnamed parameters", goto error); + if (isl_map_check_named_params(map) < 0) + goto error; + aligned = isl_map_space_has_equal_params(map, model); + if (aligned < 0) + goto error; + if (!aligned) { + isl_space *space; + isl_reordering *exp; + + space = isl_map_peek_space(map); + exp = isl_parameter_alignment_reordering(space, model); + map = isl_map_realign(map, exp); + } + + isl_space_free(model); + return map; +error: + isl_space_free(model); + isl_map_free(map); + return NULL; +} + +__isl_give isl_set *isl_set_align_params(__isl_take isl_set *set, + __isl_take isl_space *model) +{ + return isl_map_align_params(set, model); +} + +/* Align the parameters of "bmap" to those of "model", introducing + * additional parameters if needed. + */ +__isl_give isl_basic_map *isl_basic_map_align_params( + __isl_take isl_basic_map *bmap, __isl_take isl_space *model) +{ + isl_ctx *ctx; + isl_bool equal_params; + isl_space *bmap_space; + + if (!bmap || !model) + goto error; + + ctx = isl_space_get_ctx(model); + if (!isl_space_has_named_params(model)) + isl_die(ctx, isl_error_invalid, + "model has unnamed parameters", goto error); + if (isl_basic_map_check_named_params(bmap) < 0) + goto error; + bmap_space = isl_basic_map_peek_space(bmap); + equal_params = isl_space_has_equal_params(bmap_space, model); + if (equal_params < 0) + goto error; + if (!equal_params) { + isl_reordering *exp; + struct isl_dim_map *dim_map; + + exp = isl_parameter_alignment_reordering(bmap_space, model); + dim_map = isl_dim_map_from_reordering(exp); + bmap = isl_basic_map_realign(bmap, + isl_reordering_get_space(exp), + isl_dim_map_extend(dim_map, bmap)); + isl_reordering_free(exp); + isl_dim_map_free(dim_map); + } + + isl_space_free(model); + return bmap; +error: + isl_space_free(model); + isl_basic_map_free(bmap); + return NULL; +} + +/* Do "bset" and "space" have the same parameters? + */ +isl_bool isl_basic_set_space_has_equal_params(__isl_keep isl_basic_set *bset, + __isl_keep isl_space *space) +{ + isl_space *bset_space; + + bset_space = isl_basic_set_peek_space(bset); + return isl_space_has_equal_params(bset_space, space); +} + +/* Do "map" and "space" have the same parameters? + */ +isl_bool isl_map_space_has_equal_params(__isl_keep isl_map *map, + __isl_keep isl_space *space) +{ + isl_space *map_space; + + map_space = isl_map_peek_space(map); + return isl_space_has_equal_params(map_space, space); +} + +/* Do "set" and "space" have the same parameters? + */ +isl_bool isl_set_space_has_equal_params(__isl_keep isl_set *set, + __isl_keep isl_space *space) +{ + return isl_map_space_has_equal_params(set_to_map(set), space); +} + +/* Align the parameters of "bset" to those of "model", introducing + * additional parameters if needed. + */ +__isl_give isl_basic_set *isl_basic_set_align_params( + __isl_take isl_basic_set *bset, __isl_take isl_space *model) +{ + return isl_basic_map_align_params(bset, model); +} + +#undef TYPE +#define TYPE isl_map +#define isl_map_drop_dims isl_map_drop +#include "isl_drop_unused_params_templ.c" + +/* Drop all parameters not referenced by "set". + */ +__isl_give isl_set *isl_set_drop_unused_params( + __isl_take isl_set *set) +{ + return set_from_map(isl_map_drop_unused_params(set_to_map(set))); +} + +#undef TYPE +#define TYPE isl_basic_map +#define isl_basic_map_drop_dims isl_basic_map_drop +#include "isl_drop_unused_params_templ.c" + +/* Drop all parameters not referenced by "bset". + */ +__isl_give isl_basic_set *isl_basic_set_drop_unused_params( + __isl_take isl_basic_set *bset) +{ + return bset_from_bmap(isl_basic_map_drop_unused_params( + bset_to_bmap(bset))); +} + +/* Given a tuple of identifiers "tuple" in a space that corresponds + * to that of "set", if any of those identifiers appear as parameters + * in "set", then equate those parameters with the corresponding + * set dimensions and project out the parameters. + * The result therefore has no such parameters. + */ +static __isl_give isl_set *equate_params(__isl_take isl_set *set, + __isl_keep isl_multi_id *tuple) +{ + int i; + isl_size n; + isl_space *set_space, *tuple_space; + + set_space = isl_set_peek_space(set); + tuple_space = isl_multi_id_peek_space(tuple); + if (isl_space_check_equal_tuples(tuple_space, set_space) < 0) + return isl_set_free(set); + n = isl_multi_id_size(tuple); + if (n < 0) + return isl_set_free(set); + for (i = 0; i < n; ++i) { + isl_id *id; + int pos; + + id = isl_multi_id_get_at(tuple, i); + if (!id) + return isl_set_free(set); + pos = isl_set_find_dim_by_id(set, isl_dim_param, id); + isl_id_free(id); + if (pos < 0) + continue; + set = isl_set_equate(set, isl_dim_param, pos, isl_dim_set, i); + set = isl_set_project_out(set, isl_dim_param, pos, 1); + } + return set; +} + +/* Bind the set dimensions of "set" to parameters with identifiers + * specified by "tuple", living in the same space as "set". + * + * If no parameters with these identifiers appear in "set" already, + * then the set dimensions are simply reinterpreted as parameters. + * Otherwise, the parameters are first equated to the corresponding + * set dimensions. + */ +__isl_give isl_set *isl_set_bind(__isl_take isl_set *set, + __isl_take isl_multi_id *tuple) +{ + isl_space *space; + + set = equate_params(set, tuple); + space = isl_set_get_space(set); + space = isl_space_bind_set(space, tuple); + isl_multi_id_free(tuple); + set = isl_set_reset_space(set, space); + + return set; +} + +/* Given a tuple of identifiers "tuple" in a space that corresponds + * to the domain of "map", if any of those identifiers appear as parameters + * in "map", then equate those parameters with the corresponding + * input dimensions and project out the parameters. + * The result therefore has no such parameters. + */ +static __isl_give isl_map *map_equate_params(__isl_take isl_map *map, + __isl_keep isl_multi_id *tuple) +{ + int i; + isl_size n; + isl_space *map_space, *tuple_space; + + map_space = isl_map_peek_space(map); + tuple_space = isl_multi_id_peek_space(tuple); + if (isl_space_check_domain_tuples(tuple_space, map_space) < 0) + return isl_map_free(map); + n = isl_multi_id_size(tuple); + if (n < 0) + return isl_map_free(map); + for (i = 0; i < n; ++i) { + isl_id *id; + int pos; + + id = isl_multi_id_get_at(tuple, i); + if (!id) + return isl_map_free(map); + pos = isl_map_find_dim_by_id(map, isl_dim_param, id); + isl_id_free(id); + if (pos < 0) + continue; + map = isl_map_equate(map, isl_dim_param, pos, isl_dim_in, i); + map = isl_map_project_out(map, isl_dim_param, pos, 1); + } + return map; +} + +/* Bind the input dimensions of "map" to parameters with identifiers + * specified by "tuple", living in the domain space of "map". + * + * If no parameters with these identifiers appear in "map" already, + * then the input dimensions are simply reinterpreted as parameters. + * Otherwise, the parameters are first equated to the corresponding + * input dimensions. + */ +__isl_give isl_set *isl_map_bind_domain(__isl_take isl_map *map, + __isl_take isl_multi_id *tuple) +{ + isl_space *space; + isl_set *set; + + map = map_equate_params(map, tuple); + space = isl_map_get_space(map); + space = isl_space_bind_map_domain(space, tuple); + isl_multi_id_free(tuple); + set = set_from_map(isl_map_reset_space(map, space)); + + return set; +} + +/* Bind the output dimensions of "map" to parameters with identifiers + * specified by "tuple", living in the range space of "map". + * + * Since binding is more easily implemented on the domain, + * bind the input dimensions of the inverse of "map". + */ +__isl_give isl_set *isl_map_bind_range(__isl_take isl_map *map, + __isl_take isl_multi_id *tuple) +{ + return isl_map_bind_domain(isl_map_reverse(map), tuple); +} + +/* Insert a domain corresponding to "tuple" + * into the nullary or unary relation "set". + * The result has an extra initial tuple and is therefore + * either a unary or binary relation. + * Any parameters with identifiers in "tuple" are reinterpreted + * as the corresponding domain dimensions. + */ +static __isl_give isl_map *unbind_params_insert_domain( + __isl_take isl_set *set, __isl_take isl_multi_id *tuple) +{ + isl_space *space; + isl_reordering *r; + + space = isl_set_peek_space(set); + r = isl_reordering_unbind_params_insert_domain(space, tuple); + isl_multi_id_free(tuple); + + return isl_map_realign(set_to_map(set), r); +} + +/* Construct a set with "tuple" as domain from the parameter domain "set". + * Any parameters with identifiers in "tuple" are reinterpreted + * as the corresponding set dimensions. + */ +__isl_give isl_set *isl_set_unbind_params(__isl_take isl_set *set, + __isl_take isl_multi_id *tuple) +{ + isl_bool is_params; + + is_params = isl_set_is_params(set); + if (is_params < 0) + set = isl_set_free(set); + else if (!is_params) + isl_die(isl_set_get_ctx(set), isl_error_invalid, + "expecting parameter domain", set = isl_set_free(set)); + return set_from_map(unbind_params_insert_domain(set, tuple)); +} + +/* Check that "set" is a proper set, i.e., that it is not a parameter domain. + */ +static isl_stat isl_set_check_is_set(__isl_keep isl_set *set) +{ + isl_bool is_params; + + is_params = isl_set_is_params(set); + if (is_params < 0) + return isl_stat_error; + else if (is_params) + isl_die(isl_set_get_ctx(set), isl_error_invalid, + "expecting proper set", return isl_stat_error); + + return isl_stat_ok; +} + +/* Construct a map with "domain" as domain and "set" as range. + * Any parameters with identifiers in "domain" are reinterpreted + * as the corresponding domain dimensions. + */ +__isl_give isl_map *isl_set_unbind_params_insert_domain( + __isl_take isl_set *set, __isl_take isl_multi_id *domain) +{ + if (isl_set_check_is_set(set) < 0) + set = isl_set_free(set); + return unbind_params_insert_domain(set, domain); +} + +/* Construct a map with "domain" as domain and "set" as range. + */ +__isl_give isl_map *isl_set_insert_domain(__isl_take isl_set *set, + __isl_take isl_space *domain) +{ + isl_size dim; + isl_space *space; + isl_map *map; + + if (isl_set_check_is_set(set) < 0 || isl_space_check_is_set(domain) < 0) + domain = isl_space_free(domain); + dim = isl_space_dim(domain, isl_dim_set); + if (dim < 0) + domain = isl_space_free(domain); + space = isl_set_get_space(set); + domain = isl_space_replace_params(domain, space); + space = isl_space_map_from_domain_and_range(domain, space); + + map = isl_map_from_range(set); + map = isl_map_add_dims(map, isl_dim_in, dim); + map = isl_map_reset_space(map, space); + + return map; +} + +__isl_give isl_mat *isl_basic_map_equalities_matrix( + __isl_keep isl_basic_map *bmap, enum isl_dim_type c1, + enum isl_dim_type c2, enum isl_dim_type c3, + enum isl_dim_type c4, enum isl_dim_type c5) +{ + enum isl_dim_type c[5] = { c1, c2, c3, c4, c5 }; + struct isl_mat *mat; + int i, j, k; + int pos; + isl_size total; + + total = isl_basic_map_dim(bmap, isl_dim_all); + if (total < 0) + return NULL; + mat = isl_mat_alloc(bmap->ctx, bmap->n_eq, total + 1); + if (!mat) + return NULL; + for (i = 0; i < bmap->n_eq; ++i) + for (j = 0, pos = 0; j < 5; ++j) { + int off = isl_basic_map_offset(bmap, c[j]); + isl_size dim = isl_basic_map_dim(bmap, c[j]); + if (dim < 0) + return isl_mat_free(mat); + for (k = 0; k < dim; ++k) { + isl_int_set(mat->row[i][pos], + bmap->eq[i][off + k]); + ++pos; + } + } + + return mat; +} + +__isl_give isl_mat *isl_basic_map_inequalities_matrix( + __isl_keep isl_basic_map *bmap, enum isl_dim_type c1, + enum isl_dim_type c2, enum isl_dim_type c3, + enum isl_dim_type c4, enum isl_dim_type c5) +{ + enum isl_dim_type c[5] = { c1, c2, c3, c4, c5 }; + struct isl_mat *mat; + int i, j, k; + int pos; + isl_size total; + + total = isl_basic_map_dim(bmap, isl_dim_all); + if (total < 0) + return NULL; + mat = isl_mat_alloc(bmap->ctx, bmap->n_ineq, total + 1); + if (!mat) + return NULL; + for (i = 0; i < bmap->n_ineq; ++i) + for (j = 0, pos = 0; j < 5; ++j) { + int off = isl_basic_map_offset(bmap, c[j]); + isl_size dim = isl_basic_map_dim(bmap, c[j]); + if (dim < 0) + return isl_mat_free(mat); + for (k = 0; k < dim; ++k) { + isl_int_set(mat->row[i][pos], + bmap->ineq[i][off + k]); + ++pos; + } + } + + return mat; +} + +__isl_give isl_basic_map *isl_basic_map_from_constraint_matrices( + __isl_take isl_space *space, + __isl_take isl_mat *eq, __isl_take isl_mat *ineq, enum isl_dim_type c1, + enum isl_dim_type c2, enum isl_dim_type c3, + enum isl_dim_type c4, enum isl_dim_type c5) +{ + enum isl_dim_type c[5] = { c1, c2, c3, c4, c5 }; + isl_basic_map *bmap = NULL; + isl_size dim; + unsigned total; + unsigned extra; + int i, j, k, l; + int pos; + + dim = isl_space_dim(space, isl_dim_all); + if (dim < 0 || !eq || !ineq) + goto error; + + if (eq->n_col != ineq->n_col) + isl_die(space->ctx, isl_error_invalid, + "equalities and inequalities matrices should have " + "same number of columns", goto error); + + total = 1 + dim; + + if (eq->n_col < total) + isl_die(space->ctx, isl_error_invalid, + "number of columns too small", goto error); + + extra = eq->n_col - total; + + bmap = isl_basic_map_alloc_space(isl_space_copy(space), extra, + eq->n_row, ineq->n_row); + if (!bmap) + goto error; + for (i = 0; i < extra; ++i) { + k = isl_basic_map_alloc_div(bmap); + if (k < 0) + goto error; + isl_int_set_si(bmap->div[k][0], 0); + } + for (i = 0; i < eq->n_row; ++i) { + l = isl_basic_map_alloc_equality(bmap); + if (l < 0) + goto error; + for (j = 0, pos = 0; j < 5; ++j) { + int off = isl_basic_map_offset(bmap, c[j]); + isl_size dim = isl_basic_map_dim(bmap, c[j]); + if (dim < 0) + goto error; + for (k = 0; k < dim; ++k) { + isl_int_set(bmap->eq[l][off + k], + eq->row[i][pos]); + ++pos; + } + } + } + for (i = 0; i < ineq->n_row; ++i) { + l = isl_basic_map_alloc_inequality(bmap); + if (l < 0) + goto error; + for (j = 0, pos = 0; j < 5; ++j) { + int off = isl_basic_map_offset(bmap, c[j]); + isl_size dim = isl_basic_map_dim(bmap, c[j]); + if (dim < 0) + goto error; + for (k = 0; k < dim; ++k) { + isl_int_set(bmap->ineq[l][off + k], + ineq->row[i][pos]); + ++pos; + } + } + } + + isl_space_free(space); + isl_mat_free(eq); + isl_mat_free(ineq); + + bmap = isl_basic_map_simplify(bmap); + return isl_basic_map_finalize(bmap); +error: + isl_space_free(space); + isl_mat_free(eq); + isl_mat_free(ineq); + isl_basic_map_free(bmap); + return NULL; +} + +__isl_give isl_mat *isl_basic_set_equalities_matrix( + __isl_keep isl_basic_set *bset, enum isl_dim_type c1, + enum isl_dim_type c2, enum isl_dim_type c3, enum isl_dim_type c4) +{ + return isl_basic_map_equalities_matrix(bset_to_bmap(bset), + c1, c2, c3, c4, isl_dim_in); +} + +__isl_give isl_mat *isl_basic_set_inequalities_matrix( + __isl_keep isl_basic_set *bset, enum isl_dim_type c1, + enum isl_dim_type c2, enum isl_dim_type c3, enum isl_dim_type c4) +{ + return isl_basic_map_inequalities_matrix(bset_to_bmap(bset), + c1, c2, c3, c4, isl_dim_in); +} + +__isl_give isl_basic_set *isl_basic_set_from_constraint_matrices( + __isl_take isl_space *space, + __isl_take isl_mat *eq, __isl_take isl_mat *ineq, enum isl_dim_type c1, + enum isl_dim_type c2, enum isl_dim_type c3, enum isl_dim_type c4) +{ + isl_basic_map *bmap; + bmap = isl_basic_map_from_constraint_matrices(space, eq, ineq, + c1, c2, c3, c4, isl_dim_in); + return bset_from_bmap(bmap); +} + +isl_bool isl_basic_map_can_zip(__isl_keep isl_basic_map *bmap) +{ + if (!bmap) + return isl_bool_error; + + return isl_space_can_zip(bmap->dim); +} + +isl_bool isl_map_can_zip(__isl_keep isl_map *map) +{ + if (!map) + return isl_bool_error; + + return isl_space_can_zip(map->dim); +} + +/* Given a basic map (A -> B) -> (C -> D), return the corresponding basic map + * (A -> C) -> (B -> D). + */ +__isl_give isl_basic_map *isl_basic_map_zip(__isl_take isl_basic_map *bmap) +{ + unsigned pos; + isl_size n_in; + isl_size n1; + isl_size n2; + + if (!bmap) + return NULL; + + if (!isl_basic_map_can_zip(bmap)) + isl_die(bmap->ctx, isl_error_invalid, + "basic map cannot be zipped", goto error); + n_in = isl_space_dim(bmap->dim->nested[0], isl_dim_in); + n1 = isl_space_dim(bmap->dim->nested[0], isl_dim_out); + n2 = isl_space_dim(bmap->dim->nested[1], isl_dim_in); + if (n_in < 0 || n1 < 0 || n2 < 0) + return isl_basic_map_free(bmap); + pos = isl_basic_map_offset(bmap, isl_dim_in) + n_in; + bmap = isl_basic_map_cow(bmap); + bmap = isl_basic_map_swap_vars(bmap, pos, n1, n2); + if (!bmap) + return NULL; + bmap->dim = isl_space_zip(bmap->dim); + if (!bmap->dim) + goto error; + bmap = isl_basic_map_mark_final(bmap); + return bmap; +error: + isl_basic_map_free(bmap); + return NULL; +} + +/* Given a map (A -> B) -> (C -> D), return the corresponding map + * (A -> C) -> (B -> D). + */ +__isl_give isl_map *isl_map_zip(__isl_take isl_map *map) +{ + if (!map) + return NULL; + + if (!isl_map_can_zip(map)) + isl_die(map->ctx, isl_error_invalid, "map cannot be zipped", + goto error); + + return isl_map_transform(map, &isl_space_zip, &isl_basic_map_zip); +error: + isl_map_free(map); + return NULL; +} + +/* Can we apply isl_basic_map_curry to "bmap"? + * That is, does it have a nested relation in its domain? + */ +isl_bool isl_basic_map_can_curry(__isl_keep isl_basic_map *bmap) +{ + if (!bmap) + return isl_bool_error; + + return isl_space_can_curry(bmap->dim); +} + +/* Can we apply isl_map_curry to "map"? + * That is, does it have a nested relation in its domain? + */ +isl_bool isl_map_can_curry(__isl_keep isl_map *map) +{ + if (!map) + return isl_bool_error; + + return isl_space_can_curry(map->dim); +} + +/* Given a basic map (A -> B) -> C, return the corresponding basic map + * A -> (B -> C). + */ +__isl_give isl_basic_map *isl_basic_map_curry(__isl_take isl_basic_map *bmap) +{ + + if (!bmap) + return NULL; + + if (!isl_basic_map_can_curry(bmap)) + isl_die(bmap->ctx, isl_error_invalid, + "basic map cannot be curried", goto error); + bmap = isl_basic_map_cow(bmap); + if (!bmap) + return NULL; + bmap->dim = isl_space_curry(bmap->dim); + if (!bmap->dim) + goto error; + bmap = isl_basic_map_mark_final(bmap); + return bmap; +error: + isl_basic_map_free(bmap); + return NULL; +} + +/* Given a map (A -> B) -> C, return the corresponding map + * A -> (B -> C). + */ +__isl_give isl_map *isl_map_curry(__isl_take isl_map *map) +{ + return isl_map_change_space(map, &isl_map_can_curry, + "map cannot be curried", &isl_space_curry); +} + +/* Can isl_map_range_curry be applied to "map"? + * That is, does it have a nested relation in its range, + * the domain of which is itself a nested relation? + */ +isl_bool isl_map_can_range_curry(__isl_keep isl_map *map) +{ + if (!map) + return isl_bool_error; + + return isl_space_can_range_curry(map->dim); +} + +/* Given a map A -> ((B -> C) -> D), return the corresponding map + * A -> (B -> (C -> D)). + */ +__isl_give isl_map *isl_map_range_curry(__isl_take isl_map *map) +{ + return isl_map_change_space(map, &isl_map_can_range_curry, + "map range cannot be curried", + &isl_space_range_curry); +} + +/* Can we apply isl_basic_map_uncurry to "bmap"? + * That is, does it have a nested relation in its domain? + */ +isl_bool isl_basic_map_can_uncurry(__isl_keep isl_basic_map *bmap) +{ + if (!bmap) + return isl_bool_error; + + return isl_space_can_uncurry(bmap->dim); +} + +/* Can we apply isl_map_uncurry to "map"? + * That is, does it have a nested relation in its domain? + */ +isl_bool isl_map_can_uncurry(__isl_keep isl_map *map) +{ + if (!map) + return isl_bool_error; + + return isl_space_can_uncurry(map->dim); +} + +/* Given a basic map A -> (B -> C), return the corresponding basic map + * (A -> B) -> C. + */ +__isl_give isl_basic_map *isl_basic_map_uncurry(__isl_take isl_basic_map *bmap) +{ + + if (!bmap) + return NULL; + + if (!isl_basic_map_can_uncurry(bmap)) + isl_die(bmap->ctx, isl_error_invalid, + "basic map cannot be uncurried", + return isl_basic_map_free(bmap)); + bmap = isl_basic_map_cow(bmap); + if (!bmap) + return NULL; + bmap->dim = isl_space_uncurry(bmap->dim); + if (!bmap->dim) + return isl_basic_map_free(bmap); + bmap = isl_basic_map_mark_final(bmap); + return bmap; +} + +/* Given a map A -> (B -> C), return the corresponding map + * (A -> B) -> C. + */ +__isl_give isl_map *isl_map_uncurry(__isl_take isl_map *map) +{ + return isl_map_change_space(map, &isl_map_can_uncurry, + "map cannot be uncurried", &isl_space_uncurry); +} + +__isl_give isl_set *isl_set_equate(__isl_take isl_set *set, + enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2) +{ + return isl_map_equate(set, type1, pos1, type2, pos2); +} + +/* Construct a basic map where the given dimensions are equal to each other. + */ +static __isl_give isl_basic_map *equator(__isl_take isl_space *space, + enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2) +{ + isl_basic_map *bmap = NULL; + int i; + isl_size total; + + total = isl_space_dim(space, isl_dim_all); + if (total < 0 || + isl_space_check_range(space, type1, pos1, 1) < 0 || + isl_space_check_range(space, type2, pos2, 1) < 0) + goto error; + + if (type1 == type2 && pos1 == pos2) + return isl_basic_map_universe(space); + + bmap = isl_basic_map_alloc_space(isl_space_copy(space), 0, 1, 0); + i = isl_basic_map_alloc_equality(bmap); + if (i < 0) + goto error; + isl_seq_clr(bmap->eq[i], 1 + total); + pos1 += isl_basic_map_offset(bmap, type1); + pos2 += isl_basic_map_offset(bmap, type2); + isl_int_set_si(bmap->eq[i][pos1], -1); + isl_int_set_si(bmap->eq[i][pos2], 1); + bmap = isl_basic_map_finalize(bmap); + isl_space_free(space); + return bmap; +error: + isl_space_free(space); + isl_basic_map_free(bmap); + return NULL; +} + +/* Add a constraint imposing that the given two dimensions are equal. + */ +__isl_give isl_basic_map *isl_basic_map_equate(__isl_take isl_basic_map *bmap, + enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2) +{ + isl_basic_map *eq; + + eq = equator(isl_basic_map_get_space(bmap), type1, pos1, type2, pos2); + + bmap = isl_basic_map_intersect(bmap, eq); + + return bmap; +} + +/* Add a constraint imposing that the given two dimensions are equal. + */ +__isl_give isl_map *isl_map_equate(__isl_take isl_map *map, + enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2) +{ + isl_basic_map *bmap; + + bmap = equator(isl_map_get_space(map), type1, pos1, type2, pos2); + + map = isl_map_intersect(map, isl_map_from_basic_map(bmap)); + + return map; +} + +/* Add a constraint imposing that the given two dimensions have opposite values. + */ +__isl_give isl_map *isl_map_oppose(__isl_take isl_map *map, + enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2) +{ + isl_basic_map *bmap = NULL; + int i; + isl_size total; + + if (isl_map_check_range(map, type1, pos1, 1) < 0) + return isl_map_free(map); + if (isl_map_check_range(map, type2, pos2, 1) < 0) + return isl_map_free(map); + + total = isl_map_dim(map, isl_dim_all); + if (total < 0) + return isl_map_free(map); + bmap = isl_basic_map_alloc_space(isl_map_get_space(map), 0, 1, 0); + i = isl_basic_map_alloc_equality(bmap); + if (i < 0) + goto error; + isl_seq_clr(bmap->eq[i], 1 + total); + pos1 += isl_basic_map_offset(bmap, type1); + pos2 += isl_basic_map_offset(bmap, type2); + isl_int_set_si(bmap->eq[i][pos1], 1); + isl_int_set_si(bmap->eq[i][pos2], 1); + bmap = isl_basic_map_finalize(bmap); + + map = isl_map_intersect(map, isl_map_from_basic_map(bmap)); + + return map; +error: + isl_basic_map_free(bmap); + isl_map_free(map); + return NULL; +} + +/* Construct a constraint imposing that the value of the first dimension is + * greater than or equal to that of the second. + */ +static __isl_give isl_constraint *constraint_order_ge( + __isl_take isl_space *space, enum isl_dim_type type1, int pos1, + enum isl_dim_type type2, int pos2) +{ + isl_constraint *c; + + if (isl_space_check_range(space, type1, pos1, 1) < 0 || + isl_space_check_range(space, type2, pos2, 1) < 0) + space = isl_space_free(space); + if (!space) + return NULL; + + c = isl_constraint_alloc_inequality(isl_local_space_from_space(space)); + + if (type1 == type2 && pos1 == pos2) + return c; + + c = isl_constraint_set_coefficient_si(c, type1, pos1, 1); + c = isl_constraint_set_coefficient_si(c, type2, pos2, -1); + + return c; +} + +/* Add a constraint imposing that the value of the first dimension is + * greater than or equal to that of the second. + */ +__isl_give isl_basic_map *isl_basic_map_order_ge(__isl_take isl_basic_map *bmap, + enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2) +{ + isl_constraint *c; + isl_space *space; + + if (type1 == type2 && pos1 == pos2) + return bmap; + space = isl_basic_map_get_space(bmap); + c = constraint_order_ge(space, type1, pos1, type2, pos2); + bmap = isl_basic_map_add_constraint(bmap, c); + + return bmap; +} + +/* Add a constraint imposing that the value of the first dimension is + * greater than or equal to that of the second. + */ +__isl_give isl_map *isl_map_order_ge(__isl_take isl_map *map, + enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2) +{ + isl_constraint *c; + isl_space *space; + + if (type1 == type2 && pos1 == pos2) + return map; + space = isl_map_get_space(map); + c = constraint_order_ge(space, type1, pos1, type2, pos2); + map = isl_map_add_constraint(map, c); + + return map; +} + +/* Add a constraint imposing that the value of the first dimension is + * less than or equal to that of the second. + */ +__isl_give isl_map *isl_map_order_le(__isl_take isl_map *map, + enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2) +{ + return isl_map_order_ge(map, type2, pos2, type1, pos1); +} + +/* Construct a basic map where the value of the first dimension is + * greater than that of the second. + */ +static __isl_give isl_basic_map *greator(__isl_take isl_space *space, + enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2) +{ + isl_basic_map *bmap = NULL; + int i; + isl_size total; + + if (isl_space_check_range(space, type1, pos1, 1) < 0 || + isl_space_check_range(space, type2, pos2, 1) < 0) + goto error; + + if (type1 == type2 && pos1 == pos2) + return isl_basic_map_empty(space); + + bmap = isl_basic_map_alloc_space(space, 0, 0, 1); + total = isl_basic_map_dim(bmap, isl_dim_all); + i = isl_basic_map_alloc_inequality(bmap); + if (total < 0 || i < 0) + return isl_basic_map_free(bmap); + isl_seq_clr(bmap->ineq[i], 1 + total); + pos1 += isl_basic_map_offset(bmap, type1); + pos2 += isl_basic_map_offset(bmap, type2); + isl_int_set_si(bmap->ineq[i][pos1], 1); + isl_int_set_si(bmap->ineq[i][pos2], -1); + isl_int_set_si(bmap->ineq[i][0], -1); + bmap = isl_basic_map_finalize(bmap); + + return bmap; +error: + isl_space_free(space); + isl_basic_map_free(bmap); + return NULL; +} + +/* Add a constraint imposing that the value of the first dimension is + * greater than that of the second. + */ +__isl_give isl_basic_map *isl_basic_map_order_gt(__isl_take isl_basic_map *bmap, + enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2) +{ + isl_basic_map *gt; + + gt = greator(isl_basic_map_get_space(bmap), type1, pos1, type2, pos2); + + bmap = isl_basic_map_intersect(bmap, gt); + + return bmap; +} + +/* Add a constraint imposing that the value of the first dimension is + * greater than that of the second. + */ +__isl_give isl_map *isl_map_order_gt(__isl_take isl_map *map, + enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2) +{ + isl_basic_map *bmap; + + bmap = greator(isl_map_get_space(map), type1, pos1, type2, pos2); + + map = isl_map_intersect(map, isl_map_from_basic_map(bmap)); + + return map; +} + +/* Add a constraint imposing that the value of the first dimension is + * smaller than that of the second. + */ +__isl_give isl_map *isl_map_order_lt(__isl_take isl_map *map, + enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2) +{ + return isl_map_order_gt(map, type2, pos2, type1, pos1); +} + +__isl_give isl_aff *isl_basic_map_get_div(__isl_keep isl_basic_map *bmap, + int pos) +{ + isl_aff *div; + isl_local_space *ls; + + if (!bmap) + return NULL; + + if (!isl_basic_map_divs_known(bmap)) + isl_die(isl_basic_map_get_ctx(bmap), isl_error_invalid, + "some divs are unknown", return NULL); + + ls = isl_basic_map_get_local_space(bmap); + div = isl_local_space_get_div(ls, pos); + isl_local_space_free(ls); + + return div; +} + +__isl_give isl_aff *isl_basic_set_get_div(__isl_keep isl_basic_set *bset, + int pos) +{ + return isl_basic_map_get_div(bset, pos); +} + +/* Plug in "subs" for set dimension "pos" of "set". + */ +__isl_give isl_set *isl_set_substitute(__isl_take isl_set *set, + unsigned pos, __isl_keep isl_aff *subs) +{ + isl_multi_aff *ma; + + if (set && isl_set_plain_is_empty(set)) + return set; + + ma = isl_multi_aff_identity_on_domain_space(isl_set_get_space(set)); + ma = isl_multi_aff_set_aff(ma, pos, isl_aff_copy(subs)); + return isl_set_preimage_multi_aff(set, ma); +} + +/* Check if the range of "ma" is compatible with the domain or range + * (depending on "type") of "bmap". + */ +static isl_stat check_basic_map_compatible_range_multi_aff( + __isl_keep isl_basic_map *bmap, enum isl_dim_type type, + __isl_keep isl_multi_aff *ma) +{ + isl_bool m; + isl_space *ma_space; + + ma_space = isl_multi_aff_get_space(ma); + + m = isl_space_has_equal_params(bmap->dim, ma_space); + if (m < 0) + goto error; + if (!m) + isl_die(isl_basic_map_get_ctx(bmap), isl_error_invalid, + "parameters don't match", goto error); + m = isl_space_tuple_is_equal(bmap->dim, type, ma_space, isl_dim_out); + if (m < 0) + goto error; + if (!m) + isl_die(isl_basic_map_get_ctx(bmap), isl_error_invalid, + "spaces don't match", goto error); + + isl_space_free(ma_space); + return isl_stat_ok; +error: + isl_space_free(ma_space); + return isl_stat_error; +} + +/* Copy the divs from "ma" to "bmap", adding zeros for the "n_before" + * coefficients before the transformed range of dimensions, + * the "n_after" coefficients after the transformed range of dimensions + * and the coefficients of the other divs in "bmap". + */ +static __isl_give isl_basic_map *set_ma_divs(__isl_take isl_basic_map *bmap, + __isl_keep isl_multi_aff *ma, int n_before, int n_after, int n_div) +{ + int i; + isl_size n_param; + isl_size n_set; + isl_local_space *ls; + + if (n_div == 0) + return bmap; + + ls = isl_aff_get_domain_local_space(ma->u.p[0]); + n_param = isl_local_space_dim(ls, isl_dim_param); + n_set = isl_local_space_dim(ls, isl_dim_set); + if (n_param < 0 || n_set < 0) + return isl_basic_map_free(bmap); + + for (i = 0; i < n_div; ++i) { + int o_bmap = 0, o_ls = 0; + + isl_seq_cpy(bmap->div[i], ls->div->row[i], 1 + 1 + n_param); + o_bmap += 1 + 1 + n_param; + o_ls += 1 + 1 + n_param; + isl_seq_clr(bmap->div[i] + o_bmap, n_before); + o_bmap += n_before; + isl_seq_cpy(bmap->div[i] + o_bmap, + ls->div->row[i] + o_ls, n_set); + o_bmap += n_set; + o_ls += n_set; + isl_seq_clr(bmap->div[i] + o_bmap, n_after); + o_bmap += n_after; + isl_seq_cpy(bmap->div[i] + o_bmap, + ls->div->row[i] + o_ls, n_div); + o_bmap += n_div; + o_ls += n_div; + isl_seq_clr(bmap->div[i] + o_bmap, bmap->n_div - n_div); + bmap = isl_basic_map_add_div_constraints(bmap, i); + if (!bmap) + goto error; + } + + isl_local_space_free(ls); + return bmap; +error: + isl_local_space_free(ls); + return isl_basic_map_free(bmap); +} + +/* How many stride constraints does "ma" enforce? + * That is, how many of the affine expressions have a denominator + * different from one? + */ +static int multi_aff_strides(__isl_keep isl_multi_aff *ma) +{ + int i; + int strides = 0; + + for (i = 0; i < ma->n; ++i) + if (!isl_int_is_one(ma->u.p[i]->v->el[0])) + strides++; + + return strides; +} + +/* For each affine expression in ma of the form + * + * x_i = (f_i y + h_i)/m_i + * + * with m_i different from one, add a constraint to "bmap" + * of the form + * + * f_i y + h_i = m_i alpha_i + * + * with alpha_i an additional existentially quantified variable. + * + * The input variables of "ma" correspond to a subset of the variables + * of "bmap". There are "n_before" variables in "bmap" before this + * subset and "n_after" variables after this subset. + * The integer divisions of the affine expressions in "ma" are assumed + * to have been aligned. There are "n_div_ma" of them and + * they appear first in "bmap", straight after the "n_after" variables. + */ +static __isl_give isl_basic_map *add_ma_strides( + __isl_take isl_basic_map *bmap, __isl_keep isl_multi_aff *ma, + int n_before, int n_after, int n_div_ma) +{ + int i, k; + int div; + isl_size total; + isl_size n_param; + isl_size n_in; + + total = isl_basic_map_dim(bmap, isl_dim_all); + n_param = isl_multi_aff_dim(ma, isl_dim_param); + n_in = isl_multi_aff_dim(ma, isl_dim_in); + if (total < 0 || n_param < 0 || n_in < 0) + return isl_basic_map_free(bmap); + for (i = 0; i < ma->n; ++i) { + int o_bmap = 0, o_ma = 1; + + if (isl_int_is_one(ma->u.p[i]->v->el[0])) + continue; + div = isl_basic_map_alloc_div(bmap); + k = isl_basic_map_alloc_equality(bmap); + if (div < 0 || k < 0) + goto error; + isl_int_set_si(bmap->div[div][0], 0); + isl_seq_cpy(bmap->eq[k] + o_bmap, + ma->u.p[i]->v->el + o_ma, 1 + n_param); + o_bmap += 1 + n_param; + o_ma += 1 + n_param; + isl_seq_clr(bmap->eq[k] + o_bmap, n_before); + o_bmap += n_before; + isl_seq_cpy(bmap->eq[k] + o_bmap, + ma->u.p[i]->v->el + o_ma, n_in); + o_bmap += n_in; + o_ma += n_in; + isl_seq_clr(bmap->eq[k] + o_bmap, n_after); + o_bmap += n_after; + isl_seq_cpy(bmap->eq[k] + o_bmap, + ma->u.p[i]->v->el + o_ma, n_div_ma); + o_bmap += n_div_ma; + o_ma += n_div_ma; + isl_seq_clr(bmap->eq[k] + o_bmap, 1 + total - o_bmap); + isl_int_neg(bmap->eq[k][1 + total], ma->u.p[i]->v->el[0]); + total++; + } + + return bmap; +error: + isl_basic_map_free(bmap); + return NULL; +} + +/* Replace the domain or range space (depending on "type) of "space" by "set". + */ +static __isl_give isl_space *isl_space_set(__isl_take isl_space *space, + enum isl_dim_type type, __isl_take isl_space *set) +{ + if (type == isl_dim_in) { + space = isl_space_range(space); + space = isl_space_map_from_domain_and_range(set, space); + } else { + space = isl_space_domain(space); + space = isl_space_map_from_domain_and_range(space, set); + } + + return space; +} + +/* Compute the preimage of the domain or range (depending on "type") + * of "bmap" under the function represented by "ma". + * In other words, plug in "ma" in the domain or range of "bmap". + * The result is a basic map that lives in the same space as "bmap" + * except that the domain or range has been replaced by + * the domain space of "ma". + * + * If bmap is represented by + * + * A(p) + S u + B x + T v + C(divs) >= 0, + * + * where u and x are input and output dimensions if type == isl_dim_out + * while x and v are input and output dimensions if type == isl_dim_in, + * and ma is represented by + * + * x = D(p) + F(y) + G(divs') + * + * then the result is + * + * A(p) + B D(p) + S u + B F(y) + T v + B G(divs') + C(divs) >= 0 + * + * The divs in the input set are similarly adjusted. + * In particular + * + * floor((a_i(p) + s u + b_i x + t v + c_i(divs))/n_i) + * + * becomes + * + * floor((a_i(p) + b_i D(p) + s u + b_i F(y) + t v + + * B_i G(divs') + c_i(divs))/n_i) + * + * If bmap is not a rational map and if F(y) involves any denominators + * + * x_i = (f_i y + h_i)/m_i + * + * then additional constraints are added to ensure that we only + * map back integer points. That is we enforce + * + * f_i y + h_i = m_i alpha_i + * + * with alpha_i an additional existentially quantified variable. + * + * We first copy over the divs from "ma". + * Then we add the modified constraints and divs from "bmap". + * Finally, we add the stride constraints, if needed. + */ +__isl_give isl_basic_map *isl_basic_map_preimage_multi_aff( + __isl_take isl_basic_map *bmap, enum isl_dim_type type, + __isl_take isl_multi_aff *ma) +{ + int i, k; + isl_space *space; + isl_basic_map *res = NULL; + isl_size n_before, n_after, n_div_bmap, n_div_ma; + isl_int f, c1, c2, g; + isl_bool rational; + int strides; + + isl_int_init(f); + isl_int_init(c1); + isl_int_init(c2); + isl_int_init(g); + + ma = isl_multi_aff_align_divs(ma); + if (!bmap || !ma) + goto error; + if (check_basic_map_compatible_range_multi_aff(bmap, type, ma) < 0) + goto error; + + if (type == isl_dim_in) { + n_before = 0; + n_after = isl_basic_map_dim(bmap, isl_dim_out); + } else { + n_before = isl_basic_map_dim(bmap, isl_dim_in); + n_after = 0; + } + n_div_bmap = isl_basic_map_dim(bmap, isl_dim_div); + n_div_ma = ma->n ? isl_aff_dim(ma->u.p[0], isl_dim_div) : 0; + if (n_before < 0 || n_after < 0 || n_div_bmap < 0 || n_div_ma < 0) + goto error; + + space = isl_multi_aff_get_domain_space(ma); + space = isl_space_set(isl_basic_map_get_space(bmap), type, space); + rational = isl_basic_map_is_rational(bmap); + strides = rational ? 0 : multi_aff_strides(ma); + res = isl_basic_map_alloc_space(space, n_div_ma + n_div_bmap + strides, + bmap->n_eq + strides, bmap->n_ineq + 2 * n_div_ma); + if (rational) + res = isl_basic_map_set_rational(res); + + for (i = 0; i < n_div_ma + n_div_bmap; ++i) + if (isl_basic_map_alloc_div(res) < 0) + goto error; + + res = set_ma_divs(res, ma, n_before, n_after, n_div_ma); + if (!res) + goto error; + + for (i = 0; i < bmap->n_eq; ++i) { + k = isl_basic_map_alloc_equality(res); + if (k < 0) + goto error; + if (isl_seq_preimage(res->eq[k], bmap->eq[i], ma, n_before, + n_after, n_div_ma, n_div_bmap, + f, c1, c2, g, 0) < 0) + goto error; + } + + for (i = 0; i < bmap->n_ineq; ++i) { + k = isl_basic_map_alloc_inequality(res); + if (k < 0) + goto error; + if (isl_seq_preimage(res->ineq[k], bmap->ineq[i], ma, n_before, + n_after, n_div_ma, n_div_bmap, + f, c1, c2, g, 0) < 0) + goto error; + } + + for (i = 0; i < bmap->n_div; ++i) { + if (isl_int_is_zero(bmap->div[i][0])) { + isl_int_set_si(res->div[n_div_ma + i][0], 0); + continue; + } + if (isl_seq_preimage(res->div[n_div_ma + i], bmap->div[i], ma, + n_before, n_after, n_div_ma, n_div_bmap, + f, c1, c2, g, 1) < 0) + goto error; + } + + if (strides) + res = add_ma_strides(res, ma, n_before, n_after, n_div_ma); + + isl_int_clear(f); + isl_int_clear(c1); + isl_int_clear(c2); + isl_int_clear(g); + isl_basic_map_free(bmap); + isl_multi_aff_free(ma); + res = isl_basic_map_simplify(res); + return isl_basic_map_finalize(res); +error: + isl_int_clear(f); + isl_int_clear(c1); + isl_int_clear(c2); + isl_int_clear(g); + isl_basic_map_free(bmap); + isl_multi_aff_free(ma); + isl_basic_map_free(res); + return NULL; +} + +/* Compute the preimage of "bset" under the function represented by "ma". + * In other words, plug in "ma" in "bset". The result is a basic set + * that lives in the domain space of "ma". + */ +__isl_give isl_basic_set *isl_basic_set_preimage_multi_aff( + __isl_take isl_basic_set *bset, __isl_take isl_multi_aff *ma) +{ + return isl_basic_map_preimage_multi_aff(bset, isl_dim_set, ma); +} + +/* Compute the preimage of the domain of "bmap" under the function + * represented by "ma". + * In other words, plug in "ma" in the domain of "bmap". + * The result is a basic map that lives in the same space as "bmap" + * except that the domain has been replaced by the domain space of "ma". + */ +__isl_give isl_basic_map *isl_basic_map_preimage_domain_multi_aff( + __isl_take isl_basic_map *bmap, __isl_take isl_multi_aff *ma) +{ + return isl_basic_map_preimage_multi_aff(bmap, isl_dim_in, ma); +} + +/* Compute the preimage of the range of "bmap" under the function + * represented by "ma". + * In other words, plug in "ma" in the range of "bmap". + * The result is a basic map that lives in the same space as "bmap" + * except that the range has been replaced by the domain space of "ma". + */ +__isl_give isl_basic_map *isl_basic_map_preimage_range_multi_aff( + __isl_take isl_basic_map *bmap, __isl_take isl_multi_aff *ma) +{ + return isl_basic_map_preimage_multi_aff(bmap, isl_dim_out, ma); +} + +/* Check if the range of "ma" is compatible with the domain or range + * (depending on "type") of "map". + * Return isl_stat_error if anything is wrong. + */ +static isl_stat check_map_compatible_range_multi_aff( + __isl_keep isl_map *map, enum isl_dim_type type, + __isl_keep isl_multi_aff *ma) +{ + isl_bool m; + isl_space *ma_space; + + ma_space = isl_multi_aff_get_space(ma); + m = isl_map_space_tuple_is_equal(map, type, ma_space, isl_dim_out); + isl_space_free(ma_space); + if (m < 0) + return isl_stat_error; + if (!m) + isl_die(isl_map_get_ctx(map), isl_error_invalid, + "spaces don't match", return isl_stat_error); + return isl_stat_ok; +} + +/* Compute the preimage of the domain or range (depending on "type") + * of "map" under the function represented by "ma". + * In other words, plug in "ma" in the domain or range of "map". + * The result is a map that lives in the same space as "map" + * except that the domain or range has been replaced by + * the domain space of "ma". + * + * The parameters are assumed to have been aligned. + */ +static __isl_give isl_map *map_preimage_multi_aff(__isl_take isl_map *map, + enum isl_dim_type type, __isl_take isl_multi_aff *ma) +{ + int i; + isl_space *space; + + map = isl_map_cow(map); + ma = isl_multi_aff_align_divs(ma); + if (!map || !ma) + goto error; + if (check_map_compatible_range_multi_aff(map, type, ma) < 0) + goto error; + + for (i = 0; i < map->n; ++i) { + map->p[i] = isl_basic_map_preimage_multi_aff(map->p[i], type, + isl_multi_aff_copy(ma)); + if (!map->p[i]) + goto error; + } + + space = isl_multi_aff_get_domain_space(ma); + space = isl_space_set(isl_map_get_space(map), type, space); + + isl_space_free(isl_map_take_space(map)); + map = isl_map_restore_space(map, space); + if (!map) + goto error; + + isl_multi_aff_free(ma); + if (map->n > 1) + ISL_F_CLR(map, ISL_MAP_DISJOINT); + ISL_F_CLR(map, ISL_SET_NORMALIZED); + return map; +error: + isl_multi_aff_free(ma); + isl_map_free(map); + return NULL; +} + +/* Compute the preimage of the domain or range (depending on "type") + * of "map" under the function represented by "ma". + * In other words, plug in "ma" in the domain or range of "map". + * The result is a map that lives in the same space as "map" + * except that the domain or range has been replaced by + * the domain space of "ma". + */ +__isl_give isl_map *isl_map_preimage_multi_aff(__isl_take isl_map *map, + enum isl_dim_type type, __isl_take isl_multi_aff *ma) +{ + isl_bool aligned; + + if (!map || !ma) + goto error; + + aligned = isl_map_space_has_equal_params(map, ma->space); + if (aligned < 0) + goto error; + if (aligned) + return map_preimage_multi_aff(map, type, ma); + + if (isl_map_check_named_params(map) < 0) + goto error; + if (!isl_space_has_named_params(ma->space)) + isl_die(map->ctx, isl_error_invalid, + "unaligned unnamed parameters", goto error); + map = isl_map_align_params(map, isl_multi_aff_get_space(ma)); + ma = isl_multi_aff_align_params(ma, isl_map_get_space(map)); + + return map_preimage_multi_aff(map, type, ma); +error: + isl_multi_aff_free(ma); + return isl_map_free(map); +} + +/* Compute the preimage of "set" under the function represented by "ma". + * In other words, plug in "ma" in "set". The result is a set + * that lives in the domain space of "ma". + */ +__isl_give isl_set *isl_set_preimage_multi_aff(__isl_take isl_set *set, + __isl_take isl_multi_aff *ma) +{ + return isl_map_preimage_multi_aff(set, isl_dim_set, ma); +} + +/* Compute the preimage of the domain of "map" under the function + * represented by "ma". + * In other words, plug in "ma" in the domain of "map". + * The result is a map that lives in the same space as "map" + * except that the domain has been replaced by the domain space of "ma". + */ +__isl_give isl_map *isl_map_preimage_domain_multi_aff(__isl_take isl_map *map, + __isl_take isl_multi_aff *ma) +{ + return isl_map_preimage_multi_aff(map, isl_dim_in, ma); +} + +/* Compute the preimage of the range of "map" under the function + * represented by "ma". + * In other words, plug in "ma" in the range of "map". + * The result is a map that lives in the same space as "map" + * except that the range has been replaced by the domain space of "ma". + */ +__isl_give isl_map *isl_map_preimage_range_multi_aff(__isl_take isl_map *map, + __isl_take isl_multi_aff *ma) +{ + return isl_map_preimage_multi_aff(map, isl_dim_out, ma); +} + +/* Compute the preimage of "map" under the function represented by "pma". + * In other words, plug in "pma" in the domain or range of "map". + * The result is a map that lives in the same space as "map", + * except that the space of type "type" has been replaced by + * the domain space of "pma". + * + * The parameters of "map" and "pma" are assumed to have been aligned. + */ +static __isl_give isl_map *isl_map_preimage_pw_multi_aff_aligned( + __isl_take isl_map *map, enum isl_dim_type type, + __isl_take isl_pw_multi_aff *pma) +{ + int i; + isl_map *res; + + if (!pma) + goto error; + + if (pma->n == 0) { + isl_space *space; + + space = isl_pw_multi_aff_get_domain_space(pma); + isl_pw_multi_aff_free(pma); + space = isl_space_set(isl_map_get_space(map), type, space); + isl_map_free(map); + return isl_map_empty(space); + } + + res = isl_map_preimage_multi_aff(isl_map_copy(map), type, + isl_multi_aff_copy(pma->p[0].maff)); + if (type == isl_dim_in) + res = isl_map_intersect_domain(res, + isl_map_copy(pma->p[0].set)); + else + res = isl_map_intersect_range(res, + isl_map_copy(pma->p[0].set)); + + for (i = 1; i < pma->n; ++i) { + isl_map *res_i; + + res_i = isl_map_preimage_multi_aff(isl_map_copy(map), type, + isl_multi_aff_copy(pma->p[i].maff)); + if (type == isl_dim_in) + res_i = isl_map_intersect_domain(res_i, + isl_map_copy(pma->p[i].set)); + else + res_i = isl_map_intersect_range(res_i, + isl_map_copy(pma->p[i].set)); + res = isl_map_union(res, res_i); + } + + isl_pw_multi_aff_free(pma); + isl_map_free(map); + return res; +error: + isl_pw_multi_aff_free(pma); + isl_map_free(map); + return NULL; +} + +/* Compute the preimage of "map" under the function represented by "pma". + * In other words, plug in "pma" in the domain or range of "map". + * The result is a map that lives in the same space as "map", + * except that the space of type "type" has been replaced by + * the domain space of "pma". + */ +__isl_give isl_map *isl_map_preimage_pw_multi_aff(__isl_take isl_map *map, + enum isl_dim_type type, __isl_take isl_pw_multi_aff *pma) +{ + isl_bool aligned; + + if (!map || !pma) + goto error; + + aligned = isl_map_space_has_equal_params(map, pma->dim); + if (aligned < 0) + goto error; + if (aligned) + return isl_map_preimage_pw_multi_aff_aligned(map, type, pma); + + if (isl_map_check_named_params(map) < 0) + goto error; + if (isl_pw_multi_aff_check_named_params(pma) < 0) + goto error; + map = isl_map_align_params(map, isl_pw_multi_aff_get_space(pma)); + pma = isl_pw_multi_aff_align_params(pma, isl_map_get_space(map)); + + return isl_map_preimage_pw_multi_aff_aligned(map, type, pma); +error: + isl_pw_multi_aff_free(pma); + return isl_map_free(map); +} + +/* Compute the preimage of "set" under the function represented by "pma". + * In other words, plug in "pma" in "set". The result is a set + * that lives in the domain space of "pma". + */ +__isl_give isl_set *isl_set_preimage_pw_multi_aff(__isl_take isl_set *set, + __isl_take isl_pw_multi_aff *pma) +{ + return isl_map_preimage_pw_multi_aff(set, isl_dim_set, pma); +} + +/* Compute the preimage of the domain of "map" under the function + * represented by "pma". + * In other words, plug in "pma" in the domain of "map". + * The result is a map that lives in the same space as "map", + * except that domain space has been replaced by the domain space of "pma". + */ +__isl_give isl_map *isl_map_preimage_domain_pw_multi_aff( + __isl_take isl_map *map, __isl_take isl_pw_multi_aff *pma) +{ + return isl_map_preimage_pw_multi_aff(map, isl_dim_in, pma); +} + +/* Compute the preimage of the range of "map" under the function + * represented by "pma". + * In other words, plug in "pma" in the range of "map". + * The result is a map that lives in the same space as "map", + * except that range space has been replaced by the domain space of "pma". + */ +__isl_give isl_map *isl_map_preimage_range_pw_multi_aff( + __isl_take isl_map *map, __isl_take isl_pw_multi_aff *pma) +{ + return isl_map_preimage_pw_multi_aff(map, isl_dim_out, pma); +} + +/* Compute the preimage of "map" under the function represented by "mpa". + * In other words, plug in "mpa" in the domain or range of "map". + * The result is a map that lives in the same space as "map", + * except that the space of type "type" has been replaced by + * the domain space of "mpa". + * + * If the map does not involve any constraints that refer to the + * dimensions of the substituted space, then the only possible + * effect of "mpa" on the map is to map the space to a different space. + * We create a separate isl_multi_aff to effectuate this change + * in order to avoid spurious splitting of the map along the pieces + * of "mpa". + * If "mpa" has a non-trivial explicit domain, however, + * then the full substitution should be performed. + */ +__isl_give isl_map *isl_map_preimage_multi_pw_aff(__isl_take isl_map *map, + enum isl_dim_type type, __isl_take isl_multi_pw_aff *mpa) +{ + isl_size n; + isl_bool full; + isl_pw_multi_aff *pma; + + n = isl_map_dim(map, type); + if (n < 0 || !mpa) + goto error; + + full = isl_map_involves_dims(map, type, 0, n); + if (full >= 0 && !full) + full = isl_multi_pw_aff_has_non_trivial_domain(mpa); + if (full < 0) + goto error; + if (!full) { + isl_space *space; + isl_multi_aff *ma; + + space = isl_multi_pw_aff_get_space(mpa); + isl_multi_pw_aff_free(mpa); + ma = isl_multi_aff_zero(space); + return isl_map_preimage_multi_aff(map, type, ma); + } + + pma = isl_pw_multi_aff_from_multi_pw_aff(mpa); + return isl_map_preimage_pw_multi_aff(map, type, pma); +error: + isl_map_free(map); + isl_multi_pw_aff_free(mpa); + return NULL; +} + +/* Compute the preimage of "map" under the function represented by "mpa". + * In other words, plug in "mpa" in the domain "map". + * The result is a map that lives in the same space as "map", + * except that domain space has been replaced by the domain space of "mpa". + */ +__isl_give isl_map *isl_map_preimage_domain_multi_pw_aff( + __isl_take isl_map *map, __isl_take isl_multi_pw_aff *mpa) +{ + return isl_map_preimage_multi_pw_aff(map, isl_dim_in, mpa); +} + +/* Compute the preimage of "set" by the function represented by "mpa". + * In other words, plug in "mpa" in "set". + */ +__isl_give isl_set *isl_set_preimage_multi_pw_aff(__isl_take isl_set *set, + __isl_take isl_multi_pw_aff *mpa) +{ + return isl_map_preimage_multi_pw_aff(set, isl_dim_set, mpa); +} + +/* Given that inequality "ineq" of "bmap" expresses an upper bound + * on the output dimension "pos" in terms of the parameters, + * the input dimensions and possibly some integer divisions, + * but not any other output dimensions, extract this upper bound + * as a function of all dimensions (with zero coefficients + * for the output dimensions). + * + * That is, the inequality is of the form + * + * e(...) + c - m x >= 0 + * + * where e does not depend on any other output dimensions. + * Return (e(...) + c) / m, with the denominator m in the first position. + */ +__isl_give isl_vec *isl_basic_map_inequality_extract_output_upper_bound( + __isl_keep isl_basic_map *bmap, int ineq, int pos) +{ + isl_ctx *ctx; + isl_vec *v; + isl_size v_out, total; + + v_out = isl_basic_map_var_offset(bmap, isl_dim_out); + total = isl_basic_map_dim(bmap, isl_dim_all); + if (v_out < 0 || total < 0) + return NULL; + ctx = isl_basic_map_get_ctx(bmap); + v = isl_vec_alloc(ctx, 1 + 1 + total); + if (!v) + return NULL; + isl_int_neg(v->el[0], bmap->ineq[ineq][1 + v_out + pos]); + isl_seq_cpy(v->el + 1, bmap->ineq[ineq], 1 + total); + isl_int_set_si(v->el[1 + 1 + v_out + pos], 0); + + return v; +} + +/* Is constraint "c" of "bmap" of the form + * + * e(...) + c1 - m x >= 0 + * + * or + * + * -e(...) + c2 + m x >= 0 + * + * where m > 1 and e does not involve any other output variables? + * + * "v_out" is the offset to the output variables. + * "d" is the position of x among the output variables. + * "v_div" is the offset to the local variables. + * "total" is the total number of variables. + * + * Since the purpose of this function is to use the constraint + * to express the output variable as an integer division, + * do not allow the constraint to involve any local variables + * that do not have an explicit representation. + */ +static isl_bool is_potential_div_constraint(__isl_keep isl_basic_map *bmap, + isl_int *c, int v_out, int d, int v_div, int total) +{ + int i = 0; + + if (isl_int_is_zero(c[1 + v_out + d])) + return isl_bool_false; + if (isl_int_is_one(c[1 + v_out + d])) + return isl_bool_false; + if (isl_int_is_negone(c[1 + v_out + d])) + return isl_bool_false; + if (isl_seq_first_non_zero(c + 1 + v_out, d) != -1) + return isl_bool_false; + if (isl_seq_first_non_zero(c + 1 + v_out + d + 1, + v_div - (v_out + d + 1)) != -1) + return isl_bool_false; + for (i = 0; v_div + i < total; ++i) { + isl_bool known, involves; + + if (isl_int_is_zero(c[1 + v_div + i])) + continue; + known = isl_basic_map_div_is_known(bmap, i); + if (known < 0 || !known) + return known; + involves = div_involves_vars(bmap, i, v_out, v_div - v_out); + if (involves < 0 || involves) + return isl_bool_not(involves); + } + return isl_bool_true; +} + +/* Look for a pair of constraints + * + * e(...) + c1 - m x >= 0 i.e., m x <= e(...) + c1 + * + * and + * + * -e(...) + c2 + m x >= 0 i.e., m x >= e(...) - c2 + * + * that express that the output dimension x at position "pos" + * is some integer division of an expression in terms of the parameters, + * input dimensions and integer divisions. + * If such a pair can be found, then return the index + * of the upper bound constraint, m x <= e(...) + c1. + * Otherwise, return an index beyond the number of constraints. + * + * In order for the constraints above to express an integer division, + * m needs to be greater than 1 and such that + * + * c1 + c2 < m i.e., -c2 >= c1 - (m - 1) + * + * In particular, this ensures that + * + * x = floor((e(...) + c1) / m) + */ +isl_size isl_basic_map_find_output_upper_div_constraint( + __isl_keep isl_basic_map *bmap, int pos) +{ + int i, j; + isl_size n_ineq; + isl_size v_out, v_div; + isl_size total; + isl_int sum; + + total = isl_basic_map_dim(bmap, isl_dim_all); + v_out = isl_basic_map_var_offset(bmap, isl_dim_out); + v_div = isl_basic_map_var_offset(bmap, isl_dim_div); + n_ineq = isl_basic_map_n_inequality(bmap); + if (total < 0 || v_out < 0 || v_div < 0 || n_ineq < 0) + return isl_size_error; + + isl_int_init(sum); + for (i = 0; i < n_ineq; ++i) { + isl_bool potential; + + potential = is_potential_div_constraint(bmap, bmap->ineq[i], + v_out, pos, v_div, total); + if (potential < 0) + goto error; + if (!potential) + continue; + for (j = i + 1; j < n_ineq; ++j) { + if (!isl_seq_is_neg(bmap->ineq[i] + 1, + bmap->ineq[j] + 1, total)) + continue; + isl_int_add(sum, bmap->ineq[i][0], bmap->ineq[j][0]); + if (isl_int_abs_lt(sum, bmap->ineq[i][1 + v_out + pos])) + break; + } + if (j < n_ineq) + break; + } + isl_int_clear(sum); + + if (i >= n_ineq) + return n_ineq; + if (isl_int_is_pos(bmap->ineq[j][1 + v_out + pos])) + return i; + else + return j; +error: + isl_int_clear(sum); + return isl_size_error; +} + +/* Return a copy of the equality constraints of "bset" as a matrix. + */ +__isl_give isl_mat *isl_basic_set_extract_equalities( + __isl_keep isl_basic_set *bset) +{ + isl_ctx *ctx; + isl_size total; + + total = isl_basic_set_dim(bset, isl_dim_all); + if (total < 0) + return NULL; + + ctx = isl_basic_set_get_ctx(bset); + return isl_mat_sub_alloc6(ctx, bset->eq, 0, bset->n_eq, 0, 1 + total); +} + +/* Are the "n" "coefficients" starting at "first" of the integer division + * expressions at position "pos1" in "bmap1" and "pos2" in "bmap2" equal + * to each other? + * The "coefficient" at position 0 is the denominator. + * The "coefficient" at position 1 is the constant term. + */ +isl_bool isl_basic_map_equal_div_expr_part(__isl_keep isl_basic_map *bmap1, + int pos1, __isl_keep isl_basic_map *bmap2, int pos2, + unsigned first, unsigned n) +{ + if (isl_basic_map_check_range(bmap1, isl_dim_div, pos1, 1) < 0) + return isl_bool_error; + if (isl_basic_map_check_range(bmap2, isl_dim_div, pos2, 1) < 0) + return isl_bool_error; + return isl_seq_eq(bmap1->div[pos1] + first, + bmap2->div[pos2] + first, n); +} + +/* Are the integer division expressions at position "pos1" in "bmap1" and + * "pos2" in "bmap2" equal to each other, except that the constant terms + * are different? + */ +isl_bool isl_basic_map_equal_div_expr_except_constant( + __isl_keep isl_basic_map *bmap1, int pos1, + __isl_keep isl_basic_map *bmap2, int pos2) +{ + isl_bool equal; + isl_size total, total2; + + total = isl_basic_map_dim(bmap1, isl_dim_all); + total2 = isl_basic_map_dim(bmap2, isl_dim_all); + if (total < 0 || total2 < 0) + return isl_bool_error; + if (total != total2) + isl_die(isl_basic_map_get_ctx(bmap1), isl_error_invalid, + "incomparable div expressions", return isl_bool_error); + equal = isl_basic_map_equal_div_expr_part(bmap1, pos1, bmap2, pos2, + 0, 1); + if (equal < 0 || !equal) + return equal; + equal = isl_basic_map_equal_div_expr_part(bmap1, pos1, bmap2, pos2, + 1, 1); + if (equal < 0 || equal) + return isl_bool_not(equal); + return isl_basic_map_equal_div_expr_part(bmap1, pos1, bmap2, pos2, + 2, total); +} + +/* Replace the numerator of the constant term of the integer division + * expression at position "div" in "bmap" by "value". + * The caller guarantees that this does not change the meaning + * of the input. + */ +__isl_give isl_basic_map *isl_basic_map_set_div_expr_constant_num_si_inplace( + __isl_take isl_basic_map *bmap, int div, int value) +{ + if (isl_basic_map_check_range(bmap, isl_dim_div, div, 1) < 0) + return isl_basic_map_free(bmap); + + isl_int_set_si(bmap->div[div][1], value); + + return bmap; +} + +/* Is the point "inner" internal to inequality constraint "ineq" + * of "bset"? + * The point is considered to be internal to the inequality constraint, + * if it strictly lies on the positive side of the inequality constraint, + * or if it lies on the constraint and the constraint is lexico-positive. + */ +static isl_bool is_internal(__isl_keep isl_vec *inner, + __isl_keep isl_basic_set *bset, int ineq) +{ + isl_ctx *ctx; + int pos; + isl_size total; + + if (!inner || !bset) + return isl_bool_error; + + ctx = isl_basic_set_get_ctx(bset); + isl_seq_inner_product(inner->el, bset->ineq[ineq], inner->size, + &ctx->normalize_gcd); + if (!isl_int_is_zero(ctx->normalize_gcd)) + return isl_int_is_nonneg(ctx->normalize_gcd); + + total = isl_basic_set_dim(bset, isl_dim_all); + if (total < 0) + return isl_bool_error; + pos = isl_seq_first_non_zero(bset->ineq[ineq] + 1, total); + return isl_int_is_pos(bset->ineq[ineq][1 + pos]); +} + +/* Tighten the inequality constraints of "bset" that are outward with respect + * to the point "vec". + * That is, tighten the constraints that are not satisfied by "vec". + * + * "vec" is a point internal to some superset S of "bset" that is used + * to make the subsets of S disjoint, by tightening one half of the constraints + * that separate two subsets. In particular, the constraints of S + * are all satisfied by "vec" and should not be tightened. + * Of the internal constraints, those that have "vec" on the outside + * are tightened. The shared facet is included in the adjacent subset + * with the opposite constraint. + * For constraints that saturate "vec", this criterion cannot be used + * to determine which of the two sides should be tightened. + * Instead, the sign of the first non-zero coefficient is used + * to make this choice. Note that this second criterion is never used + * on the constraints of S since "vec" is interior to "S". + */ +__isl_give isl_basic_set *isl_basic_set_tighten_outward( + __isl_take isl_basic_set *bset, __isl_keep isl_vec *vec) +{ + int j; + + bset = isl_basic_set_cow(bset); + if (!bset) + return NULL; + for (j = 0; j < bset->n_ineq; ++j) { + isl_bool internal; + + internal = is_internal(vec, bset, j); + if (internal < 0) + return isl_basic_set_free(bset); + if (internal) + continue; + isl_int_sub_ui(bset->ineq[j][0], bset->ineq[j][0], 1); + } + + return bset; +} + +/* Replace the variables x of type "type" starting at "first" in "bmap" + * by x' with x = M x' with M the matrix trans. + * That is, replace the corresponding coefficients c by c M. + * + * The transformation matrix should be a square matrix. + */ +__isl_give isl_basic_map *isl_basic_map_transform_dims( + __isl_take isl_basic_map *bmap, enum isl_dim_type type, unsigned first, + __isl_take isl_mat *trans) +{ + unsigned pos; + + bmap = isl_basic_map_cow(bmap); + if (!bmap || !trans) + goto error; + + if (trans->n_row != trans->n_col) + isl_die(trans->ctx, isl_error_invalid, + "expecting square transformation matrix", goto error); + if (isl_basic_map_check_range(bmap, type, first, trans->n_row) < 0) + goto error; + + pos = isl_basic_map_offset(bmap, type) + first; + + if (isl_mat_sub_transform(bmap->eq, bmap->n_eq, pos, + isl_mat_copy(trans)) < 0) + goto error; + if (isl_mat_sub_transform(bmap->ineq, bmap->n_ineq, pos, + isl_mat_copy(trans)) < 0) + goto error; + if (isl_mat_sub_transform(bmap->div, bmap->n_div, 1 + pos, + isl_mat_copy(trans)) < 0) + goto error; + + ISL_F_CLR(bmap, ISL_BASIC_MAP_SORTED); + ISL_F_CLR(bmap, ISL_BASIC_MAP_NORMALIZED_DIVS); + + isl_mat_free(trans); + return bmap; +error: + isl_mat_free(trans); + isl_basic_map_free(bmap); + return NULL; +} + +/* Replace the variables x of type "type" starting at "first" in "bset" + * by x' with x = M x' with M the matrix trans. + * That is, replace the corresponding coefficients c by c M. + * + * The transformation matrix should be a square matrix. + */ +__isl_give isl_basic_set *isl_basic_set_transform_dims( + __isl_take isl_basic_set *bset, enum isl_dim_type type, unsigned first, + __isl_take isl_mat *trans) +{ + return isl_basic_map_transform_dims(bset, type, first, trans); +} diff --git a/external/mit/isl/dist/isl_map_bound_templ.c b/external/mit/isl/dist/isl_map_bound_templ.c new file mode 100644 index 000000000000..7e1bcf2e0633 --- /dev/null +++ b/external/mit/isl/dist/isl_map_bound_templ.c @@ -0,0 +1,57 @@ +/* + * Copyright 2018 Cerebras Systems + * + * Use of this software is governed by the MIT license + * + * Written by Sven Verdoolaege, + * Cerebras Systems, 175 S San Antonio Rd, Los Altos, CA, USA + */ + +#include "isl_multi_macro.h" +#undef TYPE +#define TYPE CAT(isl_,BASE) + +/* Check that "map" and "multi" live in the same space, ignoring parameters. + */ +static isl_stat FN(check_map_equal_tuples_multi,BASE)(__isl_keep isl_map *map, + __isl_keep MULTI(BASE) *multi) +{ + isl_space *map_space, *multi_space; + + map_space = isl_map_peek_space(map); + multi_space = FN(MULTI(BASE),peek_space)(multi); + return isl_space_check_equal_tuples(map_space, multi_space); +} + +/* Apply "map_bound" to "map" with the corresponding value in "bound" + * for each output dimension. + * If "bound" has an explicit domain (which implies that "bound" + * is zero-dimensional), then intersect the domain of "map" + * with this explicit domain instead. + */ +static __isl_give isl_map *FN(map_bound_multi,BASE)(__isl_take isl_map *map, + __isl_take MULTI(BASE) *bound, + __isl_give isl_map *map_bound(__isl_take isl_map *map, + unsigned pos, __isl_take TYPE *value)) +{ + int i; + isl_size dim; + + dim = isl_map_dim(map, isl_dim_out); + if (dim < 0 || FN(check_map_equal_tuples_multi,BASE)(map, bound) < 0) + goto error; + + for (i = 0; i < dim; ++i) { + TYPE *el; + + el = FN(MULTI(BASE),get_at)(bound, i); + map = map_bound(map, i, el); + } + map = FN(FN(isl_map_intersect_multi,BASE),explicit_domain)(map, bound); + FN(MULTI(BASE),free)(bound); + return map; +error: + isl_map_free(map); + FN(MULTI(BASE),free)(bound); + return NULL; +} diff --git a/external/mit/isl/dist/isl_map_lexopt_templ.c b/external/mit/isl/dist/isl_map_lexopt_templ.c new file mode 100644 index 000000000000..780a54f3b20e --- /dev/null +++ b/external/mit/isl/dist/isl_map_lexopt_templ.c @@ -0,0 +1,229 @@ +/* + * Copyright 2010 INRIA Saclay + * Copyright 2012 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 + */ + +/* Function for computing the lexicographic optimum of a map + * in the form of either an isl_map or an isl_pw_multi_aff. + */ + +#define xSF(TYPE,SUFFIX) TYPE ## SUFFIX +#define SF(TYPE,SUFFIX) xSF(TYPE,SUFFIX) + +/* Compute the lexicographic minimum (or maximum if "flags" includes + * ISL_OPT_MAX) of "bmap" over the domain "dom" and return the result. + * If "empty" is not NULL, then *empty is assigned a set that + * contains those parts of the domain where there is no solution. + * If "flags" includes ISL_OPT_FULL, then "dom" is NULL and the optimum + * should be computed over the domain of "bmap". "empty" is also NULL + * in this case. + * If "bmap" is marked as rational (ISL_BASIC_MAP_RATIONAL), + * then the rational optimum is computed. Otherwise, the integral optimum + * is computed. + */ +static __isl_give TYPE *SF(isl_basic_map_partial_lexopt,SUFFIX)( + __isl_take isl_basic_map *bmap, __isl_take isl_basic_set *dom, + __isl_give isl_set **empty, unsigned flags) +{ + return SF(isl_tab_basic_map_partial_lexopt,SUFFIX)(bmap, dom, empty, + flags); +} + +__isl_give TYPE *SF(isl_basic_map_partial_lexmax,SUFFIX)( + __isl_take isl_basic_map *bmap, __isl_take isl_basic_set *dom, + __isl_give isl_set **empty) +{ + unsigned flags = ISL_OPT_MAX; + return SF(isl_basic_map_partial_lexopt,SUFFIX)(bmap, dom, empty, flags); +} + +__isl_give TYPE *SF(isl_basic_map_partial_lexmin,SUFFIX)( + __isl_take isl_basic_map *bmap, __isl_take isl_basic_set *dom, + __isl_give isl_set **empty) +{ + unsigned flags = 0; + return SF(isl_basic_map_partial_lexopt,SUFFIX)(bmap, dom, empty, flags); +} + +__isl_give TYPE *SF(isl_basic_set_partial_lexmin,SUFFIX)( + __isl_take isl_basic_set *bset, __isl_take isl_basic_set *dom, + __isl_give isl_set **empty) +{ + return SF(isl_basic_map_partial_lexmin,SUFFIX)(bset, dom, empty); +} + +__isl_give TYPE *SF(isl_basic_set_partial_lexmax,SUFFIX)( + __isl_take isl_basic_set *bset, __isl_take isl_basic_set *dom, + __isl_give isl_set **empty) +{ + return SF(isl_basic_map_partial_lexmax,SUFFIX)(bset, dom, empty); +} + +/* Given a basic map "bmap", compute the lexicographically minimal + * (or maximal) image element for each domain element in dom. + * If empty is not NULL, then set *empty to those elements in dom + * that do not have an image element. + * If "flags" includes ISL_OPT_FULL, then "dom" is NULL and the optimum + * should be computed over the domain of "bmap". "empty" is also NULL + * in this case. + * + * We first make sure the basic sets in dom are disjoint and then + * simply collect the results over each of the basic sets separately. + * We could probably improve the efficiency a bit by moving the union + * domain down into the parametric integer programming. + * + * If a full optimum is being computed (i.e., "flags" includes ISL_OPT_FULL), + * then no domain is given and there is then also no need to consider + * the disjuncts of the domain. + */ +static __isl_give TYPE *SF(basic_map_partial_lexopt,SUFFIX)( + __isl_take isl_basic_map *bmap, __isl_take isl_set *dom, + __isl_give isl_set **empty, unsigned flags) +{ + int i; + TYPE *res; + isl_set *all_empty; + + if (ISL_FL_ISSET(flags, ISL_OPT_FULL)) + return SF(isl_basic_map_partial_lexopt,SUFFIX)(bmap, NULL, + empty, flags); + + dom = isl_set_make_disjoint(dom); + if (!dom) + goto error; + + if (isl_set_plain_is_empty(dom)) { + isl_space *space = isl_basic_map_get_space(bmap); + if (empty) + *empty = dom; + else + isl_set_free(dom); + isl_basic_map_free(bmap); + return EMPTY(space); + } + + res = SF(isl_basic_map_partial_lexopt,SUFFIX)(isl_basic_map_copy(bmap), + isl_basic_set_copy(dom->p[0]), empty, flags); + + if (empty) + all_empty = *empty; + for (i = 1; i < dom->n; ++i) { + TYPE *res_i; + + res_i = SF(isl_basic_map_partial_lexopt,SUFFIX)( + isl_basic_map_copy(bmap), + isl_basic_set_copy(dom->p[i]), empty, flags); + + res = ADD(res, res_i); + if (empty) + all_empty = isl_set_union_disjoint(all_empty, *empty); + } + + if (empty) + *empty = all_empty; + isl_set_free(dom); + isl_basic_map_free(bmap); + return res; +error: + if (empty) + *empty = NULL; + isl_set_free(dom); + isl_basic_map_free(bmap); + return NULL; +} + +/* Compute the lexicographic minimum (or maximum if "flags" includes + * ISL_OPT_MAX) of "bmap" over its domain. + */ +__isl_give TYPE *SF(isl_basic_map_lexopt,SUFFIX)( + __isl_take isl_basic_map *bmap, unsigned flags) +{ + ISL_FL_SET(flags, ISL_OPT_FULL); + return SF(isl_basic_map_partial_lexopt,SUFFIX)(bmap, NULL, NULL, flags); +} + +__isl_give TYPE *SF(isl_basic_map_lexmin,SUFFIX)(__isl_take isl_basic_map *bmap) +{ + return SF(isl_basic_map_lexopt,SUFFIX)(bmap, 0); +} + +static __isl_give TYPE *SF(isl_map_partial_lexopt_aligned,SUFFIX)( + __isl_take isl_map *map, __isl_take isl_set *dom, + __isl_give isl_set **empty, unsigned flags); +/* This function is currently only used when TYPE is defined as isl_map. */ +static __isl_give TYPE *SF(isl_map_partial_lexopt,SUFFIX)( + __isl_take isl_map *map, __isl_take isl_set *dom, + __isl_give isl_set **empty, unsigned flags) + __attribute__ ((unused)); + +/* Given a map "map", compute the lexicographically minimal + * (or maximal) image element for each domain element in dom. + * Set *empty to those elements in dom that do not have an image element. + * + * Align parameters if needed and then call isl_map_partial_lexopt_aligned. + */ +static __isl_give TYPE *SF(isl_map_partial_lexopt,SUFFIX)( + __isl_take isl_map *map, __isl_take isl_set *dom, + __isl_give isl_set **empty, unsigned flags) +{ + isl_bool aligned; + + aligned = isl_map_set_has_equal_params(map, dom); + if (aligned < 0) + goto error; + if (aligned) + return SF(isl_map_partial_lexopt_aligned,SUFFIX)(map, dom, + empty, flags); + if (!isl_space_has_named_params(map->dim) || + !isl_space_has_named_params(dom->dim)) + isl_die(map->ctx, isl_error_invalid, + "unaligned unnamed parameters", goto error); + map = isl_map_align_params(map, isl_map_get_space(dom)); + dom = isl_map_align_params(dom, isl_map_get_space(map)); + return SF(isl_map_partial_lexopt_aligned,SUFFIX)(map, dom, empty, + flags); +error: + if (empty) + *empty = NULL; + isl_set_free(dom); + isl_map_free(map); + return NULL; +} + +/* Compute the lexicographic minimum (or maximum if "flags" includes + * ISL_OPT_MAX) of "map" over its domain. + */ +__isl_give TYPE *SF(isl_map_lexopt,SUFFIX)(__isl_take isl_map *map, + unsigned flags) +{ + ISL_FL_SET(flags, ISL_OPT_FULL); + return SF(isl_map_partial_lexopt_aligned,SUFFIX)(map, NULL, NULL, + flags); +} + +__isl_give TYPE *SF(isl_map_lexmin,SUFFIX)(__isl_take isl_map *map) +{ + return SF(isl_map_lexopt,SUFFIX)(map, 0); +} + +__isl_give TYPE *SF(isl_map_lexmax,SUFFIX)(__isl_take isl_map *map) +{ + return SF(isl_map_lexopt,SUFFIX)(map, ISL_OPT_MAX); +} + +__isl_give TYPE *SF(isl_set_lexmin,SUFFIX)(__isl_take isl_set *set) +{ + return SF(isl_map_lexmin,SUFFIX)(set); +} + +__isl_give TYPE *SF(isl_set_lexmax,SUFFIX)(__isl_take isl_set *set) +{ + return SF(isl_map_lexmax,SUFFIX)(set); +} diff --git a/external/mit/isl/dist/isl_map_list.c b/external/mit/isl/dist/isl_map_list.c new file mode 100644 index 000000000000..3314fa70a9ab --- /dev/null +++ b/external/mit/isl/dist/isl_map_list.c @@ -0,0 +1,33 @@ +#include +#include + +#undef EL +#define EL isl_basic_map + +#include + +#undef EL_BASE +#define EL_BASE basic_map + +#include + +#undef EL +#define EL isl_map + +#include + +#undef EL_BASE +#define EL_BASE map + +#include +#include + +#undef EL +#define EL isl_union_map + +#include + +#undef EL_BASE +#define EL_BASE union_map + +#include diff --git a/external/mit/isl/dist/isl_map_private.h b/external/mit/isl/dist/isl_map_private.h new file mode 100644 index 000000000000..47364bc9c715 --- /dev/null +++ b/external/mit/isl/dist/isl_map_private.h @@ -0,0 +1,604 @@ +/* + * 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_MAP_PRIVATE_H +#define ISL_MAP_PRIVATE_H + +#define isl_basic_set isl_basic_map +#define isl_maybe_isl_basic_set isl_maybe_isl_basic_map +#define isl_set isl_map +#define isl_basic_set_list isl_basic_map_list +#define isl_set_list isl_map_list +#include +#include +#include +#include +#include +#include +#include + +/* A "basic map" is a relation between two sets of variables, + * called the "in" and "out" variables. + * A "basic set" is a basic map with a zero-dimensional + * domain. + * + * It is implemented as a set with two extra fields: + * n_in is the number of in variables + * n_out is the number of out variables + * n_in + n_out should be equal to set.dim + */ +struct isl_basic_map { + int ref; +#define ISL_BASIC_MAP_FINAL (1 << 0) +#define ISL_BASIC_MAP_EMPTY (1 << 1) +#define ISL_BASIC_MAP_NO_IMPLICIT (1 << 2) +#define ISL_BASIC_MAP_NO_REDUNDANT (1 << 3) +#define ISL_BASIC_MAP_RATIONAL (1 << 4) +#define ISL_BASIC_MAP_SORTED (1 << 5) +#define ISL_BASIC_MAP_NORMALIZED_DIVS (1 << 6) +#define ISL_BASIC_MAP_ALL_EQUALITIES (1 << 7) +#define ISL_BASIC_MAP_REDUCED_COEFFICIENTS (1 << 8) +#define ISL_BASIC_SET_FINAL (1 << 0) +#define ISL_BASIC_SET_EMPTY (1 << 1) +#define ISL_BASIC_SET_NO_IMPLICIT (1 << 2) +#define ISL_BASIC_SET_NO_REDUNDANT (1 << 3) +#define ISL_BASIC_SET_RATIONAL (1 << 4) +#define ISL_BASIC_SET_SORTED (1 << 5) +#define ISL_BASIC_SET_NORMALIZED_DIVS (1 << 6) +#define ISL_BASIC_SET_ALL_EQUALITIES (1 << 7) +#define ISL_BASIC_SET_REDUCED_COEFFICIENTS (1 << 8) + unsigned flags; + + struct isl_ctx *ctx; + + isl_space *dim; + unsigned extra; + + unsigned n_eq; + unsigned n_ineq; + + size_t c_size; + isl_int **eq; + isl_int **ineq; + + unsigned n_div; + + isl_int **div; + + struct isl_vec *sample; + + struct isl_blk block; + struct isl_blk block2; +}; + +#undef EL +#define EL isl_basic_set + +#include + +/* A "map" is a (possibly disjoint) union of basic maps. + * A "set" is a (possibly disjoint) union of basic sets. + * + * Currently, the isl_set structure is identical to the isl_map structure + * and the library depends on this correspondence internally. + * However, users should not depend on this correspondence. + * + * "cached_simple_hull" contains copies of the unshifted and shifted + * simple hulls, if they have already been computed. Otherwise, + * the entries are NULL. + */ +struct isl_map { + int ref; +#define ISL_MAP_DISJOINT (1 << 0) +#define ISL_MAP_NORMALIZED (1 << 1) +#define ISL_SET_DISJOINT (1 << 0) +#define ISL_SET_NORMALIZED (1 << 1) + unsigned flags; + isl_basic_map *cached_simple_hull[2]; + + struct isl_ctx *ctx; + + isl_space *dim; + + int n; + + size_t size; + struct isl_basic_map *p[1]; +}; + +#undef EL +#define EL isl_set + +#include + +__isl_give isl_basic_set *isl_basic_set_alloc(isl_ctx *ctx, + unsigned nparam, unsigned dim, unsigned extra, + unsigned n_eq, unsigned n_ineq); +__isl_give isl_basic_set *isl_basic_set_extend_constraints( + __isl_take isl_basic_set *base, unsigned n_eq, unsigned n_ineq); +__isl_give isl_basic_set *isl_basic_set_finalize( + __isl_take isl_basic_set *bset); +__isl_give isl_basic_set *isl_basic_set_dup(__isl_keep isl_basic_set *bset); +__isl_give isl_basic_set *isl_basic_set_simplify( + __isl_take isl_basic_set *bset); + +__isl_give isl_basic_map *isl_basic_map_alloc(isl_ctx *ctx, + unsigned nparam, unsigned in, unsigned out, unsigned extra, + unsigned n_eq, unsigned n_ineq); +__isl_give isl_basic_map *isl_basic_map_mark_final( + __isl_take isl_basic_map *bmap); +__isl_give isl_basic_map *isl_basic_map_finalize( + __isl_take isl_basic_map *bmap); +__isl_give isl_basic_map *isl_basic_map_extend_constraints( + __isl_take isl_basic_map *base, unsigned n_eq, unsigned n_ineq); +__isl_give isl_basic_map *isl_basic_map_simplify( + __isl_take isl_basic_map *bmap); + +__isl_give isl_set *isl_set_add_basic_set(__isl_take isl_set *set, + __isl_take isl_basic_set *bset); + +__isl_give isl_map *isl_map_add_basic_map(__isl_take isl_map *map, + __isl_take isl_basic_map *bmap); +__isl_give isl_map *isl_map_dup(__isl_keep isl_map *map); + +__isl_give isl_basic_set *isl_basic_set_from_underlying_set( + __isl_take isl_basic_set *bset, __isl_take isl_basic_set *like); + +__isl_give isl_map *isl_map_realign(__isl_take isl_map *map, + __isl_take isl_reordering *r); +__isl_give isl_set *isl_set_realign(__isl_take isl_set *set, + __isl_take isl_reordering *r); + +__isl_give isl_basic_map *isl_basic_map_reset(__isl_take isl_basic_map *bmap, + enum isl_dim_type type); +__isl_give isl_map *isl_map_reset(__isl_take isl_map *map, + enum isl_dim_type type); + +__isl_keep isl_space *isl_basic_map_peek_space( + __isl_keep const isl_basic_map *bmap); +__isl_keep isl_space *isl_basic_set_peek_space(__isl_keep isl_basic_set *bset); +__isl_keep isl_space *isl_map_peek_space(__isl_keep const isl_map *map); +__isl_keep isl_space *isl_set_peek_space(__isl_keep isl_set *set); + +__isl_give isl_basic_set *isl_basic_set_reset_space( + __isl_take isl_basic_set *bset, __isl_take isl_space *space); +__isl_give isl_basic_map *isl_basic_map_reset_space( + __isl_take isl_basic_map *bmap, __isl_take isl_space *space); +__isl_give isl_map *isl_map_reset_space(__isl_take isl_map *map, + __isl_take isl_space *space); +__isl_give isl_map *isl_map_reset_equal_dim_space(__isl_take isl_map *map, + __isl_take isl_space *space); + +isl_size isl_basic_map_var_offset(__isl_keep isl_basic_map *bmap, + enum isl_dim_type type); +isl_size isl_basic_set_var_offset(__isl_keep isl_basic_set *bset, + enum isl_dim_type type); +unsigned isl_basic_map_offset(__isl_keep isl_basic_map *bmap, + enum isl_dim_type type); +unsigned isl_basic_set_offset(__isl_keep isl_basic_set *bset, + enum isl_dim_type type); + +isl_bool isl_basic_map_may_be_set(__isl_keep isl_basic_map *bmap); +int isl_map_may_be_set(__isl_keep isl_map *map); +isl_bool isl_map_compatible_domain(__isl_keep isl_map *map, + __isl_keep isl_set *set); +isl_bool isl_basic_map_compatible_domain(__isl_keep isl_basic_map *bmap, + __isl_keep isl_basic_set *bset); +isl_bool isl_basic_map_compatible_range(__isl_keep isl_basic_map *bmap, + __isl_keep isl_basic_set *bset); + +__isl_give isl_basic_map *isl_basic_map_extend(__isl_take isl_basic_map *base, + unsigned extra, unsigned n_eq, unsigned n_ineq); +__isl_give isl_basic_set *isl_basic_set_extend(__isl_take isl_basic_set *base, + unsigned extra, unsigned n_eq, unsigned n_ineq); + +__isl_give isl_map *isl_map_grow(__isl_take isl_map *map, int n); +__isl_give isl_set *isl_set_grow(__isl_take isl_set *set, int n); + +isl_bool isl_basic_set_contains(__isl_keep isl_basic_set *bset, + __isl_keep isl_vec *vec); +isl_bool isl_basic_map_contains(__isl_keep isl_basic_map *bmap, + __isl_keep isl_vec *vec); + +__isl_give isl_basic_set *isl_basic_set_alloc_space(__isl_take isl_space *space, + unsigned extra, unsigned n_eq, unsigned n_ineq); +__isl_give isl_set *isl_set_alloc_space(__isl_take isl_space *space, int n, + unsigned flags); +__isl_give isl_basic_map *isl_basic_map_alloc_space(__isl_take isl_space *space, + unsigned extra, unsigned n_eq, unsigned n_ineq); +__isl_give isl_map *isl_map_alloc_space(__isl_take isl_space *space, int n, + unsigned flags); + +int isl_basic_map_alloc_equality(__isl_keep isl_basic_map *bmap); +int isl_basic_set_alloc_equality(__isl_keep isl_basic_set *bset); +__isl_give isl_basic_set *isl_basic_set_free_inequality( + __isl_take isl_basic_set *bset, unsigned n); +__isl_give isl_basic_map *isl_basic_map_free_equality( + __isl_take isl_basic_map *bmap, unsigned n); +__isl_give isl_basic_set *isl_basic_set_free_equality( + __isl_take isl_basic_set *bset, unsigned n); +int isl_basic_set_alloc_inequality(__isl_keep isl_basic_set *bset); +int isl_basic_map_alloc_inequality(__isl_keep isl_basic_map *bmap); +__isl_give isl_basic_map *isl_basic_map_free_inequality( + __isl_take isl_basic_map *bmap, unsigned n); +int isl_basic_map_alloc_div(__isl_keep isl_basic_map *bmap); +__isl_give isl_basic_map *isl_basic_map_insert_div( + __isl_take isl_basic_map *bmap, int pos, __isl_keep isl_vec *div); +int isl_basic_set_alloc_div(__isl_keep isl_basic_set *bset); +isl_stat isl_basic_map_free_div(__isl_keep isl_basic_map *bmap, unsigned n); +__isl_give isl_basic_map *isl_basic_map_drop_div( + __isl_take isl_basic_map *bmap, unsigned div); +void isl_basic_map_inequality_to_equality( + __isl_keep isl_basic_map *bmap, unsigned pos); +int isl_basic_map_drop_equality(__isl_keep isl_basic_map *bmap, unsigned pos); +int isl_basic_set_drop_inequality(__isl_keep isl_basic_set *bset, unsigned pos); +int isl_basic_map_drop_inequality(__isl_keep isl_basic_map *bmap, unsigned pos); +__isl_give isl_basic_set *isl_basic_set_add_eq(__isl_take isl_basic_set *bset, + isl_int *eq); +__isl_give isl_basic_map *isl_basic_map_add_eq(__isl_take isl_basic_map *bmap, + isl_int *eq); +__isl_give isl_basic_set *isl_basic_set_add_ineq(__isl_take isl_basic_set *bset, + isl_int *ineq); +__isl_give isl_basic_map *isl_basic_map_add_ineq(__isl_take isl_basic_map *bmap, + isl_int *ineq); + +__isl_give isl_basic_set *isl_basic_set_tighten_outward( + __isl_take isl_basic_set *bset, __isl_keep isl_vec *vec); + +__isl_give isl_basic_map *isl_inequality_negate(__isl_take isl_basic_map *bmap, + unsigned pos); + +isl_bool isl_basic_map_has_single_reference(__isl_keep isl_basic_map *bmap); +__isl_give isl_basic_set *isl_basic_set_cow(__isl_take isl_basic_set *bset); +__isl_give isl_basic_map *isl_basic_map_cow(__isl_take isl_basic_map *bmap); +__isl_give isl_set *isl_set_cow(__isl_take isl_set *set); +__isl_give isl_map *isl_map_cow(__isl_take isl_map *map); + +uint32_t isl_basic_map_get_hash(__isl_keep isl_basic_map *bmap); + +__isl_give isl_set *isl_basic_set_list_union( + __isl_take isl_basic_set_list *list); + +__isl_give isl_basic_map *isl_basic_map_set_to_empty( + __isl_take isl_basic_map *bmap); +__isl_give isl_basic_set *isl_basic_set_set_to_empty( + __isl_take isl_basic_set *bset); +__isl_give isl_basic_map *isl_basic_map_swap_div(__isl_take isl_basic_map *bmap, + int a, int b); +__isl_give isl_basic_map *isl_basic_map_order_divs( + __isl_take isl_basic_map *bmap); +__isl_give isl_map *isl_map_order_divs(__isl_take isl_map *map); +__isl_give isl_basic_map *isl_basic_map_align_divs( + __isl_take isl_basic_map *dst, __isl_keep isl_basic_map *src); +__isl_give isl_map *isl_map_align_divs_to_basic_map_list( + __isl_take isl_map *map, __isl_keep isl_basic_map_list *list); +__isl_give isl_basic_map_list *isl_basic_map_list_align_divs_to_basic_map( + __isl_take isl_basic_map_list *list, __isl_keep isl_basic_map *bmap); +__isl_give isl_map *isl_map_align_divs_internal(__isl_take isl_map *map); +__isl_give isl_basic_set *isl_basic_set_sort_divs( + __isl_take isl_basic_set *bset); +__isl_give isl_basic_map *isl_basic_map_sort_divs( + __isl_take isl_basic_map *bmap); +__isl_give isl_map *isl_map_sort_divs(__isl_take isl_map *map); +__isl_give isl_basic_map *isl_basic_map_gauss5(__isl_take isl_basic_map *bmap, + int *progress, + isl_stat (*swap)(unsigned a, unsigned b, void *user), + isl_stat (*drop)(unsigned n, void *user), void *user); +__isl_give isl_basic_map *isl_basic_map_gauss(__isl_take isl_basic_map *bmap, + int *progress); +__isl_give isl_basic_set *isl_basic_set_gauss( + __isl_take isl_basic_set *bset, int *progress); +int isl_basic_map_constraint_cmp(__isl_keep isl_basic_map *bmap, + isl_int *c1, isl_int *c2); +__isl_give isl_basic_map *isl_basic_map_sort_constraints( + __isl_take isl_basic_map *bmap); +__isl_give isl_basic_set *isl_basic_set_sort_constraints( + __isl_take isl_basic_set *bset); +int isl_basic_map_plain_cmp(__isl_keep isl_basic_map *bmap1, + __isl_keep isl_basic_map *bmap2); +isl_bool isl_basic_map_plain_is_equal(__isl_keep isl_basic_map *bmap1, + __isl_keep isl_basic_map *bmap2); +__isl_give isl_basic_map *isl_basic_map_normalize_constraints( + __isl_take isl_basic_map *bmap); +__isl_give isl_basic_set *isl_basic_set_normalize_constraints( + __isl_take isl_basic_set *bset); +__isl_give isl_basic_map *isl_basic_map_implicit_equalities( + __isl_take isl_basic_map *bmap); +__isl_give isl_basic_set *isl_basic_map_underlying_set( + __isl_take isl_basic_map *bmap); +__isl_give isl_basic_set *isl_basic_set_underlying_set( + __isl_take isl_basic_set *bset); +__isl_give isl_basic_set_list *isl_basic_map_list_underlying_set( + __isl_take isl_basic_map_list *list); +__isl_give isl_set *isl_map_underlying_set(__isl_take isl_map *map); +__isl_give isl_basic_map *isl_basic_map_overlying_set( + __isl_take isl_basic_set *bset, __isl_take isl_basic_map *like); +__isl_give isl_basic_set *isl_basic_set_drop_constraints_involving_unknown_divs( + __isl_take isl_basic_set *bset); +__isl_give isl_basic_map *isl_basic_map_drop_constraints_involving_unknown_divs( + __isl_take isl_basic_map *bmap); +__isl_give isl_map *isl_map_drop_constraints_involving_unknown_divs( + __isl_take isl_map *map); +__isl_give isl_basic_map *isl_basic_map_drop_constraints_involving( + __isl_take isl_basic_map *bmap, unsigned first, unsigned n); +__isl_give isl_basic_set *isl_basic_set_drop_constraints_involving( + __isl_take isl_basic_set *bset, unsigned first, unsigned n); +__isl_give isl_basic_set *isl_basic_set_drop(__isl_take isl_basic_set *bset, + enum isl_dim_type type, unsigned first, unsigned n); +__isl_give isl_basic_map *isl_basic_map_drop(__isl_take isl_basic_map *bmap, + enum isl_dim_type type, unsigned first, unsigned n); +__isl_give isl_set *isl_set_drop(__isl_take isl_set *set, + enum isl_dim_type type, unsigned first, unsigned n); +__isl_give isl_basic_set *isl_basic_set_drop_dims( + __isl_take isl_basic_set *bset, unsigned first, unsigned n); +__isl_give isl_map *isl_map_drop(__isl_take isl_map *map, + enum isl_dim_type type, unsigned first, unsigned n); +__isl_give isl_basic_map *isl_basic_map_drop_unrelated_constraints( + __isl_take isl_basic_map *bmap, __isl_take int *group); + +__isl_give isl_basic_map *isl_basic_map_eliminate_pure_unit_divs( + __isl_take isl_basic_map *bmap); +__isl_give isl_basic_map *isl_basic_map_remove_duplicate_constraints( + __isl_take isl_basic_map *bmap, int *progress, int detect_divs); +__isl_give isl_basic_map *isl_basic_map_detect_inequality_pairs( + __isl_take isl_basic_map *bmap, int *progress); + +__isl_give isl_map *isl_map_remove_empty_parts(__isl_take isl_map *map); +__isl_give isl_set *isl_set_remove_empty_parts(__isl_take isl_set *set); +__isl_give isl_map *isl_map_remove_obvious_duplicates(__isl_take isl_map *map); + +__isl_give isl_set *isl_set_normalize(__isl_take isl_set *set); + +__isl_give isl_basic_map *isl_basic_map_eliminate_vars( + __isl_take isl_basic_map *bmap, unsigned pos, unsigned n); +__isl_give isl_basic_set *isl_basic_set_eliminate_vars( + __isl_take isl_basic_set *bset, unsigned pos, unsigned n); + +__isl_give isl_map *isl_map_eliminate(__isl_take isl_map *map, + enum isl_dim_type type, unsigned first, unsigned n); +__isl_give isl_set *isl_set_eliminate(__isl_take isl_set *set, + enum isl_dim_type type, unsigned first, unsigned n); +__isl_give isl_map *isl_map_project_onto(__isl_take isl_map *map, + enum isl_dim_type type, unsigned first, unsigned n); + +__isl_give isl_basic_map *isl_basic_map_add_div_constraint( + __isl_take isl_basic_map *bmap, unsigned div, int sign); +__isl_give isl_basic_map *isl_basic_map_add_div_constraints( + __isl_take isl_basic_map *bmap, unsigned div); +__isl_give isl_basic_map *isl_basic_map_add_known_div_constraints( + __isl_take isl_basic_map *bmap); +__isl_give isl_basic_map *isl_basic_map_drop_redundant_divs( + __isl_take isl_basic_map *bmap); + +__isl_give isl_basic_set *isl_basic_set_recession_cone( + __isl_take isl_basic_set *bset); +__isl_give isl_basic_set *isl_basic_set_lineality_space( + __isl_take isl_basic_set *bset); +__isl_give isl_basic_set *isl_set_combined_lineality_space( + __isl_take isl_set *set); + +__isl_give isl_basic_set *isl_basic_set_set_integral( + __isl_take isl_basic_set *bset); +__isl_give isl_basic_set *isl_basic_set_set_rational( + __isl_take isl_basic_set *bset); +__isl_give isl_set *isl_set_set_rational(__isl_take isl_set *set); +__isl_give isl_basic_map *isl_basic_map_set_rational( + __isl_take isl_basic_map *bmap); +__isl_give isl_map *isl_map_set_rational(__isl_take isl_map *map); + +isl_bool isl_map_is_rational(__isl_keep isl_map *map); +isl_bool isl_set_is_rational(__isl_keep isl_set *set); + +isl_bool isl_map_has_rational(__isl_keep isl_map *map); +isl_bool isl_set_has_rational(__isl_keep isl_set *set); + +__isl_give isl_basic_map *isl_basic_map_from_multi_aff2( + __isl_take isl_multi_aff *maff, int rational); +__isl_give isl_map *isl_map_from_multi_aff_internal( + __isl_take isl_multi_aff *ma); +__isl_give isl_map *isl_map_from_pw_aff_internal(__isl_take isl_pw_aff *pa); +__isl_give isl_map *isl_map_from_pw_multi_aff_internal( + __isl_take isl_pw_multi_aff *pma); + +struct isl_mat; + +__isl_give isl_basic_set *isl_basic_set_preimage( + __isl_take isl_basic_set *bset, __isl_take isl_mat *mat); +__isl_give isl_set *isl_set_preimage( + __isl_take isl_set *set, __isl_take isl_mat *mat); + +__isl_give isl_basic_map *isl_basic_map_transform_dims( + __isl_take isl_basic_map *bmap, enum isl_dim_type type, unsigned first, + __isl_take isl_mat *trans); +__isl_give isl_basic_set *isl_basic_set_transform_dims( + __isl_take isl_basic_set *bset, enum isl_dim_type type, unsigned first, + __isl_take isl_mat *trans); + +isl_int *isl_set_wrap_facet(__isl_keep isl_set *set, + isl_int *facet, isl_int *ridge); + +isl_bool isl_basic_map_contains_point(__isl_keep isl_basic_map *bmap, + __isl_keep isl_point *point); +isl_bool isl_set_contains_point(__isl_keep isl_set *set, + __isl_keep isl_point *point); + +isl_stat isl_basic_set_vars_get_sign(__isl_keep isl_basic_set *bset, + unsigned first, unsigned n, int *signs); +isl_stat isl_set_foreach_orthant(__isl_keep isl_set *set, + isl_stat (*fn)(__isl_take isl_set *orthant, int *signs, void *user), + void *user); + +isl_bool isl_basic_set_eq_is_stride(__isl_keep isl_basic_set *bset, int i); + +isl_bool isl_basic_map_is_div_constraint(__isl_keep isl_basic_map *bmap, + isl_int *constraint, unsigned div); + +__isl_give isl_basic_set *isl_basic_set_from_local_space( + __isl_take isl_local_space *ls); +__isl_give isl_basic_map *isl_basic_map_from_local_space( + __isl_take isl_local_space *ls); +__isl_give isl_basic_set *isl_basic_set_expand_divs( + __isl_take isl_basic_set *bset, __isl_take isl_mat *div, int *exp); +__isl_give isl_basic_map *isl_basic_map_expand_divs( + __isl_take isl_basic_set *bmap, __isl_take isl_mat *div, int *exp); + +isl_size isl_basic_set_n_equality(__isl_keep isl_basic_set *bset); +isl_size isl_basic_map_n_equality(__isl_keep isl_basic_map *bmap); +isl_size isl_basic_set_n_inequality(__isl_keep isl_basic_set *bset); +isl_size isl_basic_map_n_inequality(__isl_keep isl_basic_map *bmap); + +__isl_give isl_basic_map *isl_basic_map_mark_div_unknown( + __isl_take isl_basic_map *bmap, int div); +isl_bool isl_basic_map_div_is_marked_unknown(__isl_keep isl_basic_map *bmap, + int div); +isl_bool isl_basic_map_div_is_known(__isl_keep isl_basic_map *bmap, int div); +int isl_basic_set_first_unknown_div(__isl_keep isl_basic_set *bset); +int isl_basic_map_first_unknown_div(__isl_keep isl_basic_map *bmap); +isl_bool isl_basic_map_divs_known(__isl_keep isl_basic_map *bmap); +isl_bool isl_map_divs_known(__isl_keep isl_map *map); +__isl_give isl_mat *isl_basic_set_get_divs(__isl_keep isl_basic_set *bset); +__isl_give isl_mat *isl_basic_map_get_divs(__isl_keep isl_basic_map *bmap); + +isl_bool isl_set_every_basic_set(__isl_keep isl_set *set, + isl_bool (*test)(__isl_keep isl_basic_set *bset, void *user), + void *user); +__isl_give isl_map *isl_map_inline_foreach_basic_map(__isl_take isl_map *map, + __isl_give isl_basic_map *(*fn)(__isl_take isl_basic_map *bmap)); + +isl_stat isl_basic_set_check_no_params(__isl_keep isl_basic_set *bset); +isl_stat isl_basic_set_check_no_locals(__isl_keep isl_basic_set *bset); + +isl_stat isl_basic_set_check_range(__isl_keep isl_basic_set *bset, + enum isl_dim_type type, unsigned first, unsigned n); +isl_stat isl_set_check_range(__isl_keep isl_set *set, + enum isl_dim_type type, unsigned first, unsigned n); +isl_stat isl_basic_map_check_range(__isl_keep isl_basic_map *bmap, + enum isl_dim_type type, unsigned first, unsigned n); +isl_stat isl_map_check_named_params(__isl_keep isl_map *map); + +isl_bool isl_map_has_equal_params(__isl_keep isl_map *map1, + __isl_keep isl_map *map2); +isl_bool isl_basic_set_space_has_equal_params(__isl_keep isl_basic_set *bset, + __isl_keep isl_space *space); +isl_bool isl_set_space_has_equal_params(__isl_keep isl_set *set, + __isl_keep isl_space *space); +isl_bool isl_map_space_has_equal_params(__isl_keep isl_map *map, + __isl_keep isl_space *space); + +isl_stat isl_map_align_params_bin(__isl_keep isl_map **map1, + __isl_keep isl_map **map2); +isl_stat isl_map_align_params_set(__isl_keep isl_map **map, + __isl_keep isl_set **set); +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_give isl_set *isl_set_substitute(__isl_take isl_set *set, + unsigned pos, __isl_keep isl_aff *subs); + +__isl_give isl_set *isl_set_gist_params_basic_set(__isl_take isl_set *set, + __isl_take isl_basic_set *context); + +isl_bool isl_map_compatible_range(__isl_keep isl_map *map, + __isl_keep isl_set *set); + +isl_bool isl_basic_map_plain_is_non_empty(__isl_keep isl_basic_map *bmap); +isl_bool isl_basic_map_plain_is_single_valued(__isl_keep isl_basic_map *bmap); + +isl_bool isl_map_is_set(__isl_keep isl_map *map); +isl_bool isl_map_is_params(__isl_keep isl_map *map); + +isl_bool isl_basic_set_plain_dim_is_fixed(__isl_keep isl_basic_set *bset, + unsigned dim, isl_int *val); + +__isl_give isl_set *isl_set_plain_gist_basic_set(__isl_take isl_set *set, + __isl_take isl_basic_set *context); +__isl_give isl_map *isl_map_plain_gist_basic_map(__isl_take isl_map *map, + __isl_take isl_basic_map *context); +__isl_give isl_map *isl_map_plain_gist(__isl_take isl_map *map, + __isl_take isl_map *context); + +__isl_give isl_basic_set *isl_basic_set_plain_affine_hull( + __isl_take isl_basic_set *bset); +__isl_give isl_basic_map *isl_basic_map_plain_affine_hull( + __isl_take isl_basic_map *bmap); + +isl_stat isl_basic_set_dim_residue_class(__isl_keep isl_basic_set *bset, + int pos, isl_int *modulo, isl_int *residue); +isl_stat isl_set_dim_residue_class(__isl_keep isl_set *set, + int pos, isl_int *modulo, isl_int *residue); + +__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_basic_map *isl_basic_map_fix(__isl_take isl_basic_map *bmap, + 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_map_plain_is_fixed(__isl_keep isl_map *map, + enum isl_dim_type type, unsigned pos, isl_int *val); + +int isl_basic_map_output_defining_equality(__isl_keep isl_basic_map *bmap, + int pos, int *div, int *ineq); + +__isl_give isl_basic_map *isl_basic_map_reduce_coefficients( + __isl_take isl_basic_map *bmap); + +__isl_give isl_basic_map *isl_basic_map_shift_div( + __isl_take isl_basic_map *bmap, int div, int pos, isl_int shift); + +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); + +isl_bool isl_map_space_tuple_is_equal(__isl_keep isl_map *map, + enum isl_dim_type type1, __isl_keep isl_space *space, + enum isl_dim_type type2); +isl_bool isl_map_tuple_is_equal(__isl_keep isl_map *map1, + enum isl_dim_type type1, __isl_keep isl_map *map2, + enum isl_dim_type type2); +isl_bool isl_map_has_space(__isl_keep isl_map *map, + __isl_keep isl_space *space); +isl_bool isl_map_has_space_tuples(__isl_keep isl_map *map, + __isl_keep isl_space *space); + +isl_bool isl_basic_map_is_transformation(__isl_keep isl_basic_map *bmap); +isl_stat isl_map_check_transformation(__isl_keep isl_map *map); +isl_stat isl_basic_set_check_equal_space(__isl_keep isl_basic_set *bset1, + __isl_keep isl_basic_set *bset2); +isl_stat isl_basic_map_check_equal_space(__isl_keep isl_basic_map *bmap1, + __isl_keep isl_basic_map *bmap2); +isl_stat isl_set_basic_set_check_equal_space(__isl_keep isl_set *set, + __isl_keep isl_basic_set *bset); +isl_stat isl_map_basic_map_check_equal_space(__isl_keep isl_map *map, + __isl_keep isl_basic_map *bmap); +isl_stat isl_map_check_equal_space(__isl_keep isl_map *map1, + __isl_keep isl_map *map2); + +isl_bool isl_basic_map_applies_range(__isl_keep isl_basic_map *bmap1, + __isl_keep isl_basic_map *bmap2); + +__isl_give isl_vec *isl_basic_map_inequality_extract_output_upper_bound( + __isl_keep isl_basic_map *bmap, int ineq, int pos); + +isl_size isl_basic_map_find_output_upper_div_constraint( + __isl_keep isl_basic_map *bmap, int pos); + +__isl_give isl_mat *isl_basic_set_extract_equalities( + __isl_keep isl_basic_set *bset); + +isl_bool isl_basic_map_equal_div_expr_part(__isl_keep isl_basic_map *bmap1, + int pos1, __isl_keep isl_basic_map *bmap2, int pos2, + unsigned first, unsigned n); +isl_bool isl_basic_map_equal_div_expr_except_constant( + __isl_keep isl_basic_map *bmap1, int pos1, + __isl_keep isl_basic_map *bmap2, int pos2); +__isl_give isl_basic_map *isl_basic_map_set_div_expr_constant_num_si_inplace( + __isl_take isl_basic_map *bmap, int div, int value); + +#endif diff --git a/external/mit/isl/dist/isl_map_simplify.c b/external/mit/isl/dist/isl_map_simplify.c new file mode 100644 index 000000000000..72e0e9bb7630 --- /dev/null +++ b/external/mit/isl/dist/isl_map_simplify.c @@ -0,0 +1,5544 @@ +/* + * Copyright 2008-2009 Katholieke Universiteit Leuven + * Copyright 2012-2013 Ecole Normale Superieure + * Copyright 2014-2015 INRIA Rocquencourt + * Copyright 2016 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 Ecole Normale Superieure, 45 rue d’Ulm, 75230 Paris, France + * and Inria Paris - Rocquencourt, Domaine de Voluceau - Rocquencourt, + * B.P. 105 - 78153 Le Chesnay, France + */ + +#include +#include +#include "isl_equalities.h" +#include +#include +#include "isl_tab.h" +#include +#include +#include + +#include +#include +#include +#include + +static void swap_equality(__isl_keep isl_basic_map *bmap, int a, int b) +{ + isl_int *t = bmap->eq[a]; + bmap->eq[a] = bmap->eq[b]; + bmap->eq[b] = t; +} + +static void swap_inequality(__isl_keep isl_basic_map *bmap, int a, int b) +{ + if (a != b) { + isl_int *t = bmap->ineq[a]; + bmap->ineq[a] = bmap->ineq[b]; + bmap->ineq[b] = t; + } +} + +__isl_give isl_basic_map *isl_basic_map_normalize_constraints( + __isl_take isl_basic_map *bmap) +{ + int i; + isl_int gcd; + isl_size total = isl_basic_map_dim(bmap, isl_dim_all); + + if (total < 0) + return isl_basic_map_free(bmap); + + isl_int_init(gcd); + for (i = bmap->n_eq - 1; i >= 0; --i) { + isl_seq_gcd(bmap->eq[i]+1, total, &gcd); + if (isl_int_is_zero(gcd)) { + if (!isl_int_is_zero(bmap->eq[i][0])) { + bmap = isl_basic_map_set_to_empty(bmap); + break; + } + if (isl_basic_map_drop_equality(bmap, i) < 0) + goto error; + continue; + } + if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_RATIONAL)) + isl_int_gcd(gcd, gcd, bmap->eq[i][0]); + if (isl_int_is_one(gcd)) + continue; + if (!isl_int_is_divisible_by(bmap->eq[i][0], gcd)) { + bmap = isl_basic_map_set_to_empty(bmap); + break; + } + isl_seq_scale_down(bmap->eq[i], bmap->eq[i], gcd, 1+total); + } + + for (i = bmap->n_ineq - 1; i >= 0; --i) { + isl_seq_gcd(bmap->ineq[i]+1, total, &gcd); + if (isl_int_is_zero(gcd)) { + if (isl_int_is_neg(bmap->ineq[i][0])) { + bmap = isl_basic_map_set_to_empty(bmap); + break; + } + if (isl_basic_map_drop_inequality(bmap, i) < 0) + goto error; + continue; + } + if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_RATIONAL)) + isl_int_gcd(gcd, gcd, bmap->ineq[i][0]); + if (isl_int_is_one(gcd)) + continue; + isl_int_fdiv_q(bmap->ineq[i][0], bmap->ineq[i][0], gcd); + isl_seq_scale_down(bmap->ineq[i]+1, bmap->ineq[i]+1, gcd, total); + } + isl_int_clear(gcd); + + return bmap; +error: + isl_int_clear(gcd); + isl_basic_map_free(bmap); + return NULL; +} + +__isl_give isl_basic_set *isl_basic_set_normalize_constraints( + __isl_take isl_basic_set *bset) +{ + isl_basic_map *bmap = bset_to_bmap(bset); + return bset_from_bmap(isl_basic_map_normalize_constraints(bmap)); +} + +/* Reduce the coefficient of the variable at position "pos" + * in integer division "div", such that it lies in the half-open + * interval (1/2,1/2], extracting any excess value from this integer division. + * "pos" is as determined by isl_basic_map_offset, i.e., pos == 0 + * corresponds to the constant term. + * + * That is, the integer division is of the form + * + * floor((... + (c * d + r) * x_pos + ...)/d) + * + * with -d < 2 * r <= d. + * Replace it by + * + * floor((... + r * x_pos + ...)/d) + c * x_pos + * + * If 2 * ((c * d + r) % d) <= d, then c = floor((c * d + r)/d). + * Otherwise, c = floor((c * d + r)/d) + 1. + * + * This is the same normalization that is performed by isl_aff_floor. + */ +static __isl_give isl_basic_map *reduce_coefficient_in_div( + __isl_take isl_basic_map *bmap, int div, int pos) +{ + isl_int shift; + int add_one; + + isl_int_init(shift); + isl_int_fdiv_r(shift, bmap->div[div][1 + pos], bmap->div[div][0]); + isl_int_mul_ui(shift, shift, 2); + add_one = isl_int_gt(shift, bmap->div[div][0]); + isl_int_fdiv_q(shift, bmap->div[div][1 + pos], bmap->div[div][0]); + if (add_one) + isl_int_add_ui(shift, shift, 1); + isl_int_neg(shift, shift); + bmap = isl_basic_map_shift_div(bmap, div, pos, shift); + isl_int_clear(shift); + + return bmap; +} + +/* Does the coefficient of the variable at position "pos" + * in integer division "div" need to be reduced? + * That is, does it lie outside the half-open interval (1/2,1/2]? + * The coefficient c/d lies outside this interval if abs(2 * c) >= d and + * 2 * c != d. + */ +static isl_bool needs_reduction(__isl_keep isl_basic_map *bmap, int div, + int pos) +{ + isl_bool r; + + if (isl_int_is_zero(bmap->div[div][1 + pos])) + return isl_bool_false; + + isl_int_mul_ui(bmap->div[div][1 + pos], bmap->div[div][1 + pos], 2); + r = isl_int_abs_ge(bmap->div[div][1 + pos], bmap->div[div][0]) && + !isl_int_eq(bmap->div[div][1 + pos], bmap->div[div][0]); + isl_int_divexact_ui(bmap->div[div][1 + pos], + bmap->div[div][1 + pos], 2); + + return r; +} + +/* Reduce the coefficients (including the constant term) of + * integer division "div", if needed. + * In particular, make sure all coefficients lie in + * the half-open interval (1/2,1/2]. + */ +static __isl_give isl_basic_map *reduce_div_coefficients_of_div( + __isl_take isl_basic_map *bmap, int div) +{ + int i; + isl_size total; + + total = isl_basic_map_dim(bmap, isl_dim_all); + if (total < 0) + return isl_basic_map_free(bmap); + for (i = 0; i < 1 + total; ++i) { + isl_bool reduce; + + reduce = needs_reduction(bmap, div, i); + if (reduce < 0) + return isl_basic_map_free(bmap); + if (!reduce) + continue; + bmap = reduce_coefficient_in_div(bmap, div, i); + if (!bmap) + break; + } + + return bmap; +} + +/* Reduce the coefficients (including the constant term) of + * the known integer divisions, if needed + * In particular, make sure all coefficients lie in + * the half-open interval (1/2,1/2]. + */ +static __isl_give isl_basic_map *reduce_div_coefficients( + __isl_take isl_basic_map *bmap) +{ + int i; + + if (!bmap) + return NULL; + if (bmap->n_div == 0) + return bmap; + + for (i = 0; i < bmap->n_div; ++i) { + if (isl_int_is_zero(bmap->div[i][0])) + continue; + bmap = reduce_div_coefficients_of_div(bmap, i); + if (!bmap) + break; + } + + return bmap; +} + +/* Remove any common factor in numerator and denominator of the div expression, + * not taking into account the constant term. + * That is, if the div is of the form + * + * floor((a + m f(x))/(m d)) + * + * then replace it by + * + * floor((floor(a/m) + f(x))/d) + * + * The difference {a/m}/d in the argument satisfies 0 <= {a/m}/d < 1/d + * and can therefore not influence the result of the floor. + */ +static __isl_give isl_basic_map *normalize_div_expression( + __isl_take isl_basic_map *bmap, int div) +{ + isl_size total = isl_basic_map_dim(bmap, isl_dim_all); + isl_ctx *ctx = bmap->ctx; + + if (total < 0) + return isl_basic_map_free(bmap); + if (isl_int_is_zero(bmap->div[div][0])) + return bmap; + isl_seq_gcd(bmap->div[div] + 2, total, &ctx->normalize_gcd); + isl_int_gcd(ctx->normalize_gcd, ctx->normalize_gcd, bmap->div[div][0]); + if (isl_int_is_one(ctx->normalize_gcd)) + return bmap; + isl_int_fdiv_q(bmap->div[div][1], bmap->div[div][1], + ctx->normalize_gcd); + isl_int_divexact(bmap->div[div][0], bmap->div[div][0], + ctx->normalize_gcd); + isl_seq_scale_down(bmap->div[div] + 2, bmap->div[div] + 2, + ctx->normalize_gcd, total); + + return bmap; +} + +/* Remove any common factor in numerator and denominator of a div expression, + * not taking into account the constant term. + * That is, look for any div of the form + * + * floor((a + m f(x))/(m d)) + * + * and replace it by + * + * floor((floor(a/m) + f(x))/d) + * + * The difference {a/m}/d in the argument satisfies 0 <= {a/m}/d < 1/d + * and can therefore not influence the result of the floor. + */ +static __isl_give isl_basic_map *normalize_div_expressions( + __isl_take isl_basic_map *bmap) +{ + int i; + + if (!bmap) + return NULL; + if (bmap->n_div == 0) + return bmap; + + for (i = 0; i < bmap->n_div; ++i) + bmap = normalize_div_expression(bmap, i); + + return bmap; +} + +/* Assumes divs have been ordered if keep_divs is set. + */ +static __isl_give isl_basic_map *eliminate_var_using_equality( + __isl_take isl_basic_map *bmap, + unsigned pos, isl_int *eq, int keep_divs, int *progress) +{ + isl_size total; + isl_size v_div; + int k; + int last_div; + + total = isl_basic_map_dim(bmap, isl_dim_all); + v_div = isl_basic_map_var_offset(bmap, isl_dim_div); + if (total < 0 || v_div < 0) + return isl_basic_map_free(bmap); + last_div = isl_seq_last_non_zero(eq + 1 + v_div, bmap->n_div); + for (k = 0; k < bmap->n_eq; ++k) { + if (bmap->eq[k] == eq) + continue; + if (isl_int_is_zero(bmap->eq[k][1+pos])) + continue; + if (progress) + *progress = 1; + isl_seq_elim(bmap->eq[k], eq, 1+pos, 1+total, NULL); + isl_seq_normalize(bmap->ctx, bmap->eq[k], 1 + total); + } + + for (k = 0; k < bmap->n_ineq; ++k) { + if (isl_int_is_zero(bmap->ineq[k][1+pos])) + continue; + if (progress) + *progress = 1; + isl_seq_elim(bmap->ineq[k], eq, 1+pos, 1+total, NULL); + isl_seq_normalize(bmap->ctx, bmap->ineq[k], 1 + total); + ISL_F_CLR(bmap, ISL_BASIC_MAP_NO_REDUNDANT); + ISL_F_CLR(bmap, ISL_BASIC_MAP_SORTED); + } + + for (k = 0; k < bmap->n_div; ++k) { + if (isl_int_is_zero(bmap->div[k][0])) + continue; + if (isl_int_is_zero(bmap->div[k][1+1+pos])) + continue; + if (progress) + *progress = 1; + /* We need to be careful about circular definitions, + * so for now we just remove the definition of div k + * if the equality contains any divs. + * If keep_divs is set, then the divs have been ordered + * and we can keep the definition as long as the result + * is still ordered. + */ + if (last_div == -1 || (keep_divs && last_div < k)) { + isl_seq_elim(bmap->div[k]+1, eq, + 1+pos, 1+total, &bmap->div[k][0]); + bmap = normalize_div_expression(bmap, k); + if (!bmap) + return NULL; + } else + isl_seq_clr(bmap->div[k], 1 + total); + } + + return bmap; +} + +/* Assumes divs have been ordered if keep_divs is set. + */ +static __isl_give isl_basic_map *eliminate_div(__isl_take isl_basic_map *bmap, + isl_int *eq, unsigned div, int keep_divs) +{ + isl_size v_div; + unsigned pos; + + v_div = isl_basic_map_var_offset(bmap, isl_dim_div); + if (v_div < 0) + return isl_basic_map_free(bmap); + pos = v_div + div; + bmap = eliminate_var_using_equality(bmap, pos, eq, keep_divs, NULL); + + bmap = isl_basic_map_drop_div(bmap, div); + + return bmap; +} + +/* Check if elimination of div "div" using equality "eq" would not + * result in a div depending on a later div. + */ +static isl_bool ok_to_eliminate_div(__isl_keep isl_basic_map *bmap, isl_int *eq, + unsigned div) +{ + int k; + int last_div; + isl_size v_div; + unsigned pos; + + v_div = isl_basic_map_var_offset(bmap, isl_dim_div); + if (v_div < 0) + return isl_bool_error; + pos = v_div + div; + + last_div = isl_seq_last_non_zero(eq + 1 + v_div, bmap->n_div); + if (last_div < 0 || last_div <= div) + return isl_bool_true; + + for (k = 0; k <= last_div; ++k) { + if (isl_int_is_zero(bmap->div[k][0])) + continue; + if (!isl_int_is_zero(bmap->div[k][1 + 1 + pos])) + return isl_bool_false; + } + + return isl_bool_true; +} + +/* Eliminate divs based on equalities + */ +static __isl_give isl_basic_map *eliminate_divs_eq( + __isl_take isl_basic_map *bmap, int *progress) +{ + int d; + int i; + int modified = 0; + unsigned off; + + bmap = isl_basic_map_order_divs(bmap); + + if (!bmap) + return NULL; + + off = isl_basic_map_offset(bmap, isl_dim_div); + + for (d = bmap->n_div - 1; d >= 0 ; --d) { + for (i = 0; i < bmap->n_eq; ++i) { + isl_bool ok; + + if (!isl_int_is_one(bmap->eq[i][off + d]) && + !isl_int_is_negone(bmap->eq[i][off + d])) + continue; + ok = ok_to_eliminate_div(bmap, bmap->eq[i], d); + if (ok < 0) + return isl_basic_map_free(bmap); + if (!ok) + continue; + modified = 1; + *progress = 1; + bmap = eliminate_div(bmap, bmap->eq[i], d, 1); + if (isl_basic_map_drop_equality(bmap, i) < 0) + return isl_basic_map_free(bmap); + break; + } + } + if (modified) + return eliminate_divs_eq(bmap, progress); + return bmap; +} + +/* Eliminate divs based on inequalities + */ +static __isl_give isl_basic_map *eliminate_divs_ineq( + __isl_take isl_basic_map *bmap, int *progress) +{ + int d; + int i; + unsigned off; + struct isl_ctx *ctx; + + if (!bmap) + return NULL; + + ctx = bmap->ctx; + off = isl_basic_map_offset(bmap, isl_dim_div); + + for (d = bmap->n_div - 1; d >= 0 ; --d) { + for (i = 0; i < bmap->n_eq; ++i) + if (!isl_int_is_zero(bmap->eq[i][off + d])) + break; + if (i < bmap->n_eq) + continue; + for (i = 0; i < bmap->n_ineq; ++i) + if (isl_int_abs_gt(bmap->ineq[i][off + d], ctx->one)) + break; + if (i < bmap->n_ineq) + continue; + *progress = 1; + bmap = isl_basic_map_eliminate_vars(bmap, (off-1)+d, 1); + if (!bmap || ISL_F_ISSET(bmap, ISL_BASIC_MAP_EMPTY)) + break; + bmap = isl_basic_map_drop_div(bmap, d); + if (!bmap) + break; + } + return bmap; +} + +/* Does the equality constraint at position "eq" in "bmap" involve + * any local variables in the range [first, first + n) + * that are not marked as having an explicit representation? + */ +static isl_bool bmap_eq_involves_unknown_divs(__isl_keep isl_basic_map *bmap, + int eq, unsigned first, unsigned n) +{ + unsigned o_div; + int i; + + if (!bmap) + return isl_bool_error; + + o_div = isl_basic_map_offset(bmap, isl_dim_div); + for (i = 0; i < n; ++i) { + isl_bool unknown; + + if (isl_int_is_zero(bmap->eq[eq][o_div + first + i])) + continue; + unknown = isl_basic_map_div_is_marked_unknown(bmap, first + i); + if (unknown < 0) + return isl_bool_error; + if (unknown) + return isl_bool_true; + } + + return isl_bool_false; +} + +/* The last local variable involved in the equality constraint + * at position "eq" in "bmap" is the local variable at position "div". + * It can therefore be used to extract an explicit representation + * for that variable. + * Do so unless the local variable already has an explicit representation or + * the explicit representation would involve any other local variables + * that in turn do not have an explicit representation. + * An equality constraint involving local variables without an explicit + * representation can be used in isl_basic_map_drop_redundant_divs + * to separate out an independent local variable. Introducing + * an explicit representation here would block this transformation, + * while the partial explicit representation in itself is not very useful. + * Set *progress if anything is changed. + * + * The equality constraint is of the form + * + * f(x) + n e >= 0 + * + * with n a positive number. The explicit representation derived from + * this constraint is + * + * floor((-f(x))/n) + */ +static __isl_give isl_basic_map *set_div_from_eq(__isl_take isl_basic_map *bmap, + int div, int eq, int *progress) +{ + isl_size total; + unsigned o_div; + isl_bool involves; + + if (!bmap) + return NULL; + + if (!isl_int_is_zero(bmap->div[div][0])) + return bmap; + + involves = bmap_eq_involves_unknown_divs(bmap, eq, 0, div); + if (involves < 0) + return isl_basic_map_free(bmap); + if (involves) + return bmap; + + total = isl_basic_map_dim(bmap, isl_dim_all); + if (total < 0) + return isl_basic_map_free(bmap); + o_div = isl_basic_map_offset(bmap, isl_dim_div); + isl_seq_neg(bmap->div[div] + 1, bmap->eq[eq], 1 + total); + isl_int_set_si(bmap->div[div][1 + o_div + div], 0); + isl_int_set(bmap->div[div][0], bmap->eq[eq][o_div + div]); + if (progress) + *progress = 1; + + return bmap; +} + +/* Perform fangcheng (Gaussian elimination) on the equality + * constraints of "bmap". + * That is, put them into row-echelon form, starting from the last column + * backward and use them to eliminate the corresponding coefficients + * from all constraints. + * + * If "progress" is not NULL, then it gets set if the elimination + * results in any changes. + * The elimination process may result in some equality constraints + * getting interchanged or removed. + * If "swap" or "drop" are not NULL, then they get called when + * two equality constraints get interchanged or + * when a number of final equality constraints get removed. + * As a special case, if the input turns out to be empty, + * then drop gets called with the number of removed equality + * constraints set to the total number of equality constraints. + * If "swap" or "drop" are not NULL, then the local variables (if any) + * are assumed to be in a valid order. + */ +__isl_give isl_basic_map *isl_basic_map_gauss5(__isl_take isl_basic_map *bmap, + int *progress, + isl_stat (*swap)(unsigned a, unsigned b, void *user), + isl_stat (*drop)(unsigned n, void *user), void *user) +{ + int k; + int done; + int last_var; + unsigned total_var; + isl_size total; + unsigned n_drop; + + if (!swap && !drop) + bmap = isl_basic_map_order_divs(bmap); + + total = isl_basic_map_dim(bmap, isl_dim_all); + if (total < 0) + return isl_basic_map_free(bmap); + + total_var = total - bmap->n_div; + + last_var = total - 1; + for (done = 0; done < bmap->n_eq; ++done) { + for (; last_var >= 0; --last_var) { + for (k = done; k < bmap->n_eq; ++k) + if (!isl_int_is_zero(bmap->eq[k][1+last_var])) + break; + if (k < bmap->n_eq) + break; + } + if (last_var < 0) + break; + if (k != done) { + swap_equality(bmap, k, done); + if (swap && swap(k, done, user) < 0) + return isl_basic_map_free(bmap); + } + if (isl_int_is_neg(bmap->eq[done][1+last_var])) + isl_seq_neg(bmap->eq[done], bmap->eq[done], 1+total); + + bmap = eliminate_var_using_equality(bmap, last_var, + bmap->eq[done], 1, progress); + + if (last_var >= total_var) + bmap = set_div_from_eq(bmap, last_var - total_var, + done, progress); + if (!bmap) + return NULL; + } + if (done == bmap->n_eq) + return bmap; + for (k = done; k < bmap->n_eq; ++k) { + if (isl_int_is_zero(bmap->eq[k][0])) + continue; + if (drop && drop(bmap->n_eq, user) < 0) + return isl_basic_map_free(bmap); + return isl_basic_map_set_to_empty(bmap); + } + n_drop = bmap->n_eq - done; + bmap = isl_basic_map_free_equality(bmap, n_drop); + if (drop && drop(n_drop, user) < 0) + return isl_basic_map_free(bmap); + return bmap; +} + +__isl_give isl_basic_map *isl_basic_map_gauss(__isl_take isl_basic_map *bmap, + int *progress) +{ + return isl_basic_map_gauss5(bmap, progress, NULL, NULL, NULL); +} + +__isl_give isl_basic_set *isl_basic_set_gauss( + __isl_take isl_basic_set *bset, int *progress) +{ + return bset_from_bmap(isl_basic_map_gauss(bset_to_bmap(bset), + progress)); +} + + +static unsigned int round_up(unsigned int v) +{ + int old_v = v; + + while (v) { + old_v = v; + v ^= v & -v; + } + return old_v << 1; +} + +/* Hash table of inequalities in a basic map. + * "index" is an array of addresses of inequalities in the basic map, some + * of which are NULL. The inequalities are hashed on the coefficients + * except the constant term. + * "size" is the number of elements in the array and is always a power of two + * "bits" is the number of bits need to represent an index into the array. + * "total" is the total dimension of the basic map. + */ +struct isl_constraint_index { + unsigned int size; + int bits; + isl_int ***index; + isl_size total; +}; + +/* Fill in the "ci" data structure for holding the inequalities of "bmap". + */ +static isl_stat create_constraint_index(struct isl_constraint_index *ci, + __isl_keep isl_basic_map *bmap) +{ + isl_ctx *ctx; + + ci->index = NULL; + if (!bmap) + return isl_stat_error; + ci->total = isl_basic_map_dim(bmap, isl_dim_all); + if (ci->total < 0) + return isl_stat_error; + if (bmap->n_ineq == 0) + return isl_stat_ok; + ci->size = round_up(4 * (bmap->n_ineq + 1) / 3 - 1); + ci->bits = ffs(ci->size) - 1; + ctx = isl_basic_map_get_ctx(bmap); + ci->index = isl_calloc_array(ctx, isl_int **, ci->size); + if (!ci->index) + return isl_stat_error; + + return isl_stat_ok; +} + +/* Free the memory allocated by create_constraint_index. + */ +static void constraint_index_free(struct isl_constraint_index *ci) +{ + free(ci->index); +} + +/* Return the position in ci->index that contains the address of + * an inequality that is equal to *ineq up to the constant term, + * provided this address is not identical to "ineq". + * If there is no such inequality, then return the position where + * such an inequality should be inserted. + */ +static int hash_index_ineq(struct isl_constraint_index *ci, isl_int **ineq) +{ + int h; + uint32_t hash = isl_seq_get_hash_bits((*ineq) + 1, ci->total, ci->bits); + for (h = hash; ci->index[h]; h = (h+1) % ci->size) + if (ineq != ci->index[h] && + isl_seq_eq((*ineq) + 1, ci->index[h][0]+1, ci->total)) + break; + return h; +} + +/* Return the position in ci->index that contains the address of + * an inequality that is equal to the k'th inequality of "bmap" + * up to the constant term, provided it does not point to the very + * same inequality. + * If there is no such inequality, then return the position where + * such an inequality should be inserted. + */ +static int hash_index(struct isl_constraint_index *ci, + __isl_keep isl_basic_map *bmap, int k) +{ + return hash_index_ineq(ci, &bmap->ineq[k]); +} + +static int set_hash_index(struct isl_constraint_index *ci, + __isl_keep isl_basic_set *bset, int k) +{ + return hash_index(ci, bset, k); +} + +/* Fill in the "ci" data structure with the inequalities of "bset". + */ +static isl_stat setup_constraint_index(struct isl_constraint_index *ci, + __isl_keep isl_basic_set *bset) +{ + int k, h; + + if (create_constraint_index(ci, bset) < 0) + return isl_stat_error; + + for (k = 0; k < bset->n_ineq; ++k) { + h = set_hash_index(ci, bset, k); + ci->index[h] = &bset->ineq[k]; + } + + return isl_stat_ok; +} + +/* Is the inequality ineq (obviously) redundant with respect + * to the constraints in "ci"? + * + * Look for an inequality in "ci" with the same coefficients and then + * check if the contant term of "ineq" is greater than or equal + * to the constant term of that inequality. If so, "ineq" is clearly + * redundant. + * + * Note that hash_index_ineq ignores a stored constraint if it has + * the same address as the passed inequality. It is ok to pass + * the address of a local variable here since it will never be + * the same as the address of a constraint in "ci". + */ +static isl_bool constraint_index_is_redundant(struct isl_constraint_index *ci, + isl_int *ineq) +{ + int h; + + h = hash_index_ineq(ci, &ineq); + if (!ci->index[h]) + return isl_bool_false; + return isl_int_ge(ineq[0], (*ci->index[h])[0]); +} + +/* If we can eliminate more than one div, then we need to make + * sure we do it from last div to first div, in order not to + * change the position of the other divs that still need to + * be removed. + */ +static __isl_give isl_basic_map *remove_duplicate_divs( + __isl_take isl_basic_map *bmap, int *progress) +{ + unsigned int size; + int *index; + int *elim_for; + int k, l, h; + int bits; + struct isl_blk eq; + isl_size v_div; + unsigned total; + struct isl_ctx *ctx; + + bmap = isl_basic_map_order_divs(bmap); + if (!bmap || bmap->n_div <= 1) + return bmap; + + v_div = isl_basic_map_var_offset(bmap, isl_dim_div); + if (v_div < 0) + return isl_basic_map_free(bmap); + total = v_div + bmap->n_div; + + ctx = bmap->ctx; + for (k = bmap->n_div - 1; k >= 0; --k) + if (!isl_int_is_zero(bmap->div[k][0])) + break; + if (k <= 0) + return bmap; + + size = round_up(4 * bmap->n_div / 3 - 1); + if (size == 0) + return bmap; + elim_for = isl_calloc_array(ctx, int, bmap->n_div); + bits = ffs(size) - 1; + index = isl_calloc_array(ctx, int, size); + if (!elim_for || !index) + goto out; + eq = isl_blk_alloc(ctx, 1+total); + if (isl_blk_is_error(eq)) + goto out; + + isl_seq_clr(eq.data, 1+total); + index[isl_seq_get_hash_bits(bmap->div[k], 2+total, bits)] = k + 1; + for (--k; k >= 0; --k) { + uint32_t hash; + + if (isl_int_is_zero(bmap->div[k][0])) + continue; + + hash = isl_seq_get_hash_bits(bmap->div[k], 2+total, bits); + for (h = hash; index[h]; h = (h+1) % size) + if (isl_seq_eq(bmap->div[k], + bmap->div[index[h]-1], 2+total)) + break; + if (index[h]) { + *progress = 1; + l = index[h] - 1; + elim_for[l] = k + 1; + } + index[h] = k+1; + } + for (l = bmap->n_div - 1; l >= 0; --l) { + if (!elim_for[l]) + continue; + k = elim_for[l] - 1; + isl_int_set_si(eq.data[1 + v_div + k], -1); + isl_int_set_si(eq.data[1 + v_div + l], 1); + bmap = eliminate_div(bmap, eq.data, l, 1); + if (!bmap) + break; + isl_int_set_si(eq.data[1 + v_div + k], 0); + isl_int_set_si(eq.data[1 + v_div + l], 0); + } + + isl_blk_free(ctx, eq); +out: + free(index); + free(elim_for); + return bmap; +} + +static int n_pure_div_eq(__isl_keep isl_basic_map *bmap) +{ + int i, j; + isl_size v_div; + + v_div = isl_basic_map_var_offset(bmap, isl_dim_div); + if (v_div < 0) + return -1; + for (i = 0, j = bmap->n_div-1; i < bmap->n_eq; ++i) { + while (j >= 0 && isl_int_is_zero(bmap->eq[i][1 + v_div + j])) + --j; + if (j < 0) + break; + if (isl_seq_first_non_zero(bmap->eq[i] + 1 + v_div, j) != -1) + return 0; + } + return i; +} + +/* Normalize divs that appear in equalities. + * + * In particular, we assume that bmap contains some equalities + * of the form + * + * a x = m * e_i + * + * and we want to replace the set of e_i by a minimal set and + * such that the new e_i have a canonical representation in terms + * of the vector x. + * If any of the equalities involves more than one divs, then + * we currently simply bail out. + * + * Let us first additionally assume that all equalities involve + * a div. The equalities then express modulo constraints on the + * remaining variables and we can use "parameter compression" + * to find a minimal set of constraints. The result is a transformation + * + * x = T(x') = x_0 + G x' + * + * with G a lower-triangular matrix with all elements below the diagonal + * non-negative and smaller than the diagonal element on the same row. + * We first normalize x_0 by making the same property hold in the affine + * T matrix. + * The rows i of G with a 1 on the diagonal do not impose any modulo + * constraint and simply express x_i = x'_i. + * For each of the remaining rows i, we introduce a div and a corresponding + * equality. In particular + * + * g_ii e_j = x_i - g_i(x') + * + * where each x'_k is replaced either by x_k (if g_kk = 1) or the + * corresponding div (if g_kk != 1). + * + * If there are any equalities not involving any div, then we + * first apply a variable compression on the variables x: + * + * x = C x'' x'' = C_2 x + * + * and perform the above parameter compression on A C instead of on A. + * The resulting compression is then of the form + * + * x'' = T(x') = x_0 + G x' + * + * and in constructing the new divs and the corresponding equalities, + * we have to replace each x'', i.e., the x'_k with (g_kk = 1), + * by the corresponding row from C_2. + */ +static __isl_give isl_basic_map *normalize_divs(__isl_take isl_basic_map *bmap, + int *progress) +{ + int i, j, k; + isl_size v_div; + int div_eq; + struct isl_mat *B; + struct isl_vec *d; + struct isl_mat *T = NULL; + struct isl_mat *C = NULL; + struct isl_mat *C2 = NULL; + isl_int v; + int *pos = NULL; + int dropped, needed; + + if (!bmap) + return NULL; + + if (bmap->n_div == 0) + return bmap; + + if (bmap->n_eq == 0) + return bmap; + + if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_NORMALIZED_DIVS)) + return bmap; + + v_div = isl_basic_map_var_offset(bmap, isl_dim_div); + div_eq = n_pure_div_eq(bmap); + if (v_div < 0 || div_eq < 0) + return isl_basic_map_free(bmap); + if (div_eq == 0) + return bmap; + + if (div_eq < bmap->n_eq) { + B = isl_mat_sub_alloc6(bmap->ctx, bmap->eq, div_eq, + bmap->n_eq - div_eq, 0, 1 + v_div); + C = isl_mat_variable_compression(B, &C2); + if (!C || !C2) + goto error; + if (C->n_col == 0) { + bmap = isl_basic_map_set_to_empty(bmap); + isl_mat_free(C); + isl_mat_free(C2); + goto done; + } + } + + d = isl_vec_alloc(bmap->ctx, div_eq); + if (!d) + goto error; + for (i = 0, j = bmap->n_div-1; i < div_eq; ++i) { + while (j >= 0 && isl_int_is_zero(bmap->eq[i][1 + v_div + j])) + --j; + isl_int_set(d->block.data[i], bmap->eq[i][1 + v_div + j]); + } + B = isl_mat_sub_alloc6(bmap->ctx, bmap->eq, 0, div_eq, 0, 1 + v_div); + + if (C) { + B = isl_mat_product(B, C); + C = NULL; + } + + T = isl_mat_parameter_compression(B, d); + if (!T) + goto error; + if (T->n_col == 0) { + bmap = isl_basic_map_set_to_empty(bmap); + isl_mat_free(C2); + isl_mat_free(T); + goto done; + } + isl_int_init(v); + for (i = 0; i < T->n_row - 1; ++i) { + isl_int_fdiv_q(v, T->row[1 + i][0], T->row[1 + i][1 + i]); + if (isl_int_is_zero(v)) + continue; + isl_mat_col_submul(T, 0, v, 1 + i); + } + isl_int_clear(v); + pos = isl_alloc_array(bmap->ctx, int, T->n_row); + if (!pos) + goto error; + /* We have to be careful because dropping equalities may reorder them */ + dropped = 0; + for (j = bmap->n_div - 1; j >= 0; --j) { + for (i = 0; i < bmap->n_eq; ++i) + if (!isl_int_is_zero(bmap->eq[i][1 + v_div + j])) + break; + if (i < bmap->n_eq) { + bmap = isl_basic_map_drop_div(bmap, j); + if (isl_basic_map_drop_equality(bmap, i) < 0) + goto error; + ++dropped; + } + } + pos[0] = 0; + needed = 0; + for (i = 1; i < T->n_row; ++i) { + if (isl_int_is_one(T->row[i][i])) + pos[i] = i; + else + needed++; + } + if (needed > dropped) { + bmap = isl_basic_map_extend(bmap, needed, needed, 0); + if (!bmap) + goto error; + } + for (i = 1; i < T->n_row; ++i) { + if (isl_int_is_one(T->row[i][i])) + continue; + k = isl_basic_map_alloc_div(bmap); + pos[i] = 1 + v_div + k; + isl_seq_clr(bmap->div[k] + 1, 1 + v_div + bmap->n_div); + isl_int_set(bmap->div[k][0], T->row[i][i]); + if (C2) + isl_seq_cpy(bmap->div[k] + 1, C2->row[i], 1 + v_div); + else + isl_int_set_si(bmap->div[k][1 + i], 1); + for (j = 0; j < i; ++j) { + if (isl_int_is_zero(T->row[i][j])) + continue; + if (pos[j] < T->n_row && C2) + isl_seq_submul(bmap->div[k] + 1, T->row[i][j], + C2->row[pos[j]], 1 + v_div); + else + isl_int_neg(bmap->div[k][1 + pos[j]], + T->row[i][j]); + } + j = isl_basic_map_alloc_equality(bmap); + isl_seq_neg(bmap->eq[j], bmap->div[k]+1, 1+v_div+bmap->n_div); + isl_int_set(bmap->eq[j][pos[i]], bmap->div[k][0]); + } + free(pos); + isl_mat_free(C2); + isl_mat_free(T); + + if (progress) + *progress = 1; +done: + ISL_F_SET(bmap, ISL_BASIC_MAP_NORMALIZED_DIVS); + + return bmap; +error: + free(pos); + isl_mat_free(C); + isl_mat_free(C2); + isl_mat_free(T); + isl_basic_map_free(bmap); + return NULL; +} + +static __isl_give isl_basic_map *set_div_from_lower_bound( + __isl_take isl_basic_map *bmap, int div, int ineq) +{ + unsigned total = isl_basic_map_offset(bmap, isl_dim_div); + + isl_seq_neg(bmap->div[div] + 1, bmap->ineq[ineq], total + bmap->n_div); + isl_int_set(bmap->div[div][0], bmap->ineq[ineq][total + div]); + isl_int_add(bmap->div[div][1], bmap->div[div][1], bmap->div[div][0]); + isl_int_sub_ui(bmap->div[div][1], bmap->div[div][1], 1); + isl_int_set_si(bmap->div[div][1 + total + div], 0); + + return bmap; +} + +/* Check whether it is ok to define a div based on an inequality. + * To avoid the introduction of circular definitions of divs, we + * do not allow such a definition if the resulting expression would refer to + * any other undefined divs or if any known div is defined in + * terms of the unknown div. + */ +static isl_bool ok_to_set_div_from_bound(__isl_keep isl_basic_map *bmap, + int div, int ineq) +{ + int j; + unsigned total = isl_basic_map_offset(bmap, isl_dim_div); + + /* Not defined in terms of unknown divs */ + for (j = 0; j < bmap->n_div; ++j) { + if (div == j) + continue; + if (isl_int_is_zero(bmap->ineq[ineq][total + j])) + continue; + if (isl_int_is_zero(bmap->div[j][0])) + return isl_bool_false; + } + + /* No other div defined in terms of this one => avoid loops */ + for (j = 0; j < bmap->n_div; ++j) { + if (div == j) + continue; + if (isl_int_is_zero(bmap->div[j][0])) + continue; + if (!isl_int_is_zero(bmap->div[j][1 + total + div])) + return isl_bool_false; + } + + return isl_bool_true; +} + +/* Would an expression for div "div" based on inequality "ineq" of "bmap" + * be a better expression than the current one? + * + * If we do not have any expression yet, then any expression would be better. + * Otherwise we check if the last variable involved in the inequality + * (disregarding the div that it would define) is in an earlier position + * than the last variable involved in the current div expression. + */ +static isl_bool better_div_constraint(__isl_keep isl_basic_map *bmap, + int div, int ineq) +{ + unsigned total = isl_basic_map_offset(bmap, isl_dim_div); + int last_div; + int last_ineq; + + if (isl_int_is_zero(bmap->div[div][0])) + return isl_bool_true; + + if (isl_seq_last_non_zero(bmap->ineq[ineq] + total + div + 1, + bmap->n_div - (div + 1)) >= 0) + return isl_bool_false; + + last_ineq = isl_seq_last_non_zero(bmap->ineq[ineq], total + div); + last_div = isl_seq_last_non_zero(bmap->div[div] + 1, + total + bmap->n_div); + + return last_ineq < last_div; +} + +/* Given two constraints "k" and "l" that are opposite to each other, + * except for the constant term, check if we can use them + * to obtain an expression for one of the hitherto unknown divs or + * a "better" expression for a div for which we already have an expression. + * "sum" is the sum of the constant terms of the constraints. + * If this sum is strictly smaller than the coefficient of one + * of the divs, then this pair can be used to define the div. + * To avoid the introduction of circular definitions of divs, we + * do not use the pair if the resulting expression would refer to + * any other undefined divs or if any known div is defined in + * terms of the unknown div. + */ +static __isl_give isl_basic_map *check_for_div_constraints( + __isl_take isl_basic_map *bmap, int k, int l, isl_int sum, + int *progress) +{ + int i; + unsigned total = isl_basic_map_offset(bmap, isl_dim_div); + + for (i = 0; i < bmap->n_div; ++i) { + isl_bool set_div; + + if (isl_int_is_zero(bmap->ineq[k][total + i])) + continue; + if (isl_int_abs_ge(sum, bmap->ineq[k][total + i])) + continue; + set_div = better_div_constraint(bmap, i, k); + if (set_div >= 0 && set_div) + set_div = ok_to_set_div_from_bound(bmap, i, k); + if (set_div < 0) + return isl_basic_map_free(bmap); + if (!set_div) + break; + if (isl_int_is_pos(bmap->ineq[k][total + i])) + bmap = set_div_from_lower_bound(bmap, i, k); + else + bmap = set_div_from_lower_bound(bmap, i, l); + if (progress) + *progress = 1; + break; + } + return bmap; +} + +__isl_give isl_basic_map *isl_basic_map_remove_duplicate_constraints( + __isl_take isl_basic_map *bmap, int *progress, int detect_divs) +{ + struct isl_constraint_index ci; + int k, l, h; + isl_size total = isl_basic_map_dim(bmap, isl_dim_all); + isl_int sum; + + if (total < 0 || bmap->n_ineq <= 1) + return bmap; + + if (create_constraint_index(&ci, bmap) < 0) + return bmap; + + h = isl_seq_get_hash_bits(bmap->ineq[0] + 1, total, ci.bits); + ci.index[h] = &bmap->ineq[0]; + for (k = 1; k < bmap->n_ineq; ++k) { + h = hash_index(&ci, bmap, k); + if (!ci.index[h]) { + ci.index[h] = &bmap->ineq[k]; + continue; + } + if (progress) + *progress = 1; + l = ci.index[h] - &bmap->ineq[0]; + if (isl_int_lt(bmap->ineq[k][0], bmap->ineq[l][0])) + swap_inequality(bmap, k, l); + isl_basic_map_drop_inequality(bmap, k); + --k; + } + isl_int_init(sum); + for (k = 0; bmap && k < bmap->n_ineq-1; ++k) { + isl_seq_neg(bmap->ineq[k]+1, bmap->ineq[k]+1, total); + h = hash_index(&ci, bmap, k); + isl_seq_neg(bmap->ineq[k]+1, bmap->ineq[k]+1, total); + if (!ci.index[h]) + continue; + l = ci.index[h] - &bmap->ineq[0]; + isl_int_add(sum, bmap->ineq[k][0], bmap->ineq[l][0]); + if (isl_int_is_pos(sum)) { + if (detect_divs) + bmap = check_for_div_constraints(bmap, k, l, + sum, progress); + continue; + } + if (isl_int_is_zero(sum)) { + /* We need to break out of the loop after these + * changes since the contents of the hash + * will no longer be valid. + * Plus, we probably we want to regauss first. + */ + if (progress) + *progress = 1; + isl_basic_map_drop_inequality(bmap, l); + isl_basic_map_inequality_to_equality(bmap, k); + } else + bmap = isl_basic_map_set_to_empty(bmap); + break; + } + isl_int_clear(sum); + + constraint_index_free(&ci); + return bmap; +} + +/* Detect all pairs of inequalities that form an equality. + * + * isl_basic_map_remove_duplicate_constraints detects at most one such pair. + * Call it repeatedly while it is making progress. + */ +__isl_give isl_basic_map *isl_basic_map_detect_inequality_pairs( + __isl_take isl_basic_map *bmap, int *progress) +{ + int duplicate; + + do { + duplicate = 0; + bmap = isl_basic_map_remove_duplicate_constraints(bmap, + &duplicate, 0); + if (progress && duplicate) + *progress = 1; + } while (duplicate); + + return bmap; +} + +/* Given a known integer division "div" that is not integral + * (with denominator 1), eliminate it from the constraints in "bmap" + * where it appears with a (positive or negative) unit coefficient. + * If "progress" is not NULL, then it gets set if the elimination + * results in any changes. + * + * That is, replace + * + * floor(e/m) + f >= 0 + * + * by + * + * e + m f >= 0 + * + * and + * + * -floor(e/m) + f >= 0 + * + * by + * + * -e + m f + m - 1 >= 0 + * + * The first conversion is valid because floor(e/m) >= -f is equivalent + * to e/m >= -f because -f is an integral expression. + * The second conversion follows from the fact that + * + * -floor(e/m) = ceil(-e/m) = floor((-e + m - 1)/m) + * + * + * Note that one of the div constraints may have been eliminated + * due to being redundant with respect to the constraint that is + * being modified by this function. The modified constraint may + * no longer imply this div constraint, so we add it back to make + * sure we do not lose any information. + */ +static __isl_give isl_basic_map *eliminate_unit_div( + __isl_take isl_basic_map *bmap, int div, int *progress) +{ + int j; + isl_size v_div, dim; + isl_ctx *ctx; + + v_div = isl_basic_map_var_offset(bmap, isl_dim_div); + dim = isl_basic_map_dim(bmap, isl_dim_all); + if (v_div < 0 || dim < 0) + return isl_basic_map_free(bmap); + + ctx = isl_basic_map_get_ctx(bmap); + + for (j = 0; j < bmap->n_ineq; ++j) { + int s; + + if (!isl_int_is_one(bmap->ineq[j][1 + v_div + div]) && + !isl_int_is_negone(bmap->ineq[j][1 + v_div + div])) + continue; + + if (progress) + *progress = 1; + + s = isl_int_sgn(bmap->ineq[j][1 + v_div + div]); + isl_int_set_si(bmap->ineq[j][1 + v_div + div], 0); + if (s < 0) + isl_seq_combine(bmap->ineq[j], + ctx->negone, bmap->div[div] + 1, + bmap->div[div][0], bmap->ineq[j], 1 + dim); + else + isl_seq_combine(bmap->ineq[j], + ctx->one, bmap->div[div] + 1, + bmap->div[div][0], bmap->ineq[j], 1 + dim); + if (s < 0) { + isl_int_add(bmap->ineq[j][0], + bmap->ineq[j][0], bmap->div[div][0]); + isl_int_sub_ui(bmap->ineq[j][0], + bmap->ineq[j][0], 1); + } + + bmap = isl_basic_map_extend_constraints(bmap, 0, 1); + bmap = isl_basic_map_add_div_constraint(bmap, div, s); + if (!bmap) + return NULL; + } + + return bmap; +} + +/* Eliminate selected known divs from constraints where they appear with + * a (positive or negative) unit coefficient. + * In particular, only handle those for which "select" returns isl_bool_true. + * If "progress" is not NULL, then it gets set if the elimination + * results in any changes. + * + * We skip integral divs, i.e., those with denominator 1, as we would + * risk eliminating the div from the div constraints. We do not need + * to handle those divs here anyway since the div constraints will turn + * out to form an equality and this equality can then be used to eliminate + * the div from all constraints. + */ +static __isl_give isl_basic_map *eliminate_selected_unit_divs( + __isl_take isl_basic_map *bmap, + isl_bool (*select)(__isl_keep isl_basic_map *bmap, int div), + int *progress) +{ + int i; + + if (!bmap) + return NULL; + + for (i = 0; i < bmap->n_div; ++i) { + isl_bool selected; + + if (isl_int_is_zero(bmap->div[i][0])) + continue; + if (isl_int_is_one(bmap->div[i][0])) + continue; + selected = select(bmap, i); + if (selected < 0) + return isl_basic_map_free(bmap); + if (!selected) + continue; + bmap = eliminate_unit_div(bmap, i, progress); + if (!bmap) + return NULL; + } + + return bmap; +} + +/* eliminate_selected_unit_divs callback that selects every + * integer division. + */ +static isl_bool is_any_div(__isl_keep isl_basic_map *bmap, int div) +{ + return isl_bool_true; +} + +/* Eliminate known divs from constraints where they appear with + * a (positive or negative) unit coefficient. + * If "progress" is not NULL, then it gets set if the elimination + * results in any changes. + */ +static __isl_give isl_basic_map *eliminate_unit_divs( + __isl_take isl_basic_map *bmap, int *progress) +{ + return eliminate_selected_unit_divs(bmap, &is_any_div, progress); +} + +/* eliminate_selected_unit_divs callback that selects + * integer divisions that only appear with + * a (positive or negative) unit coefficient + * (outside their div constraints). + */ +static isl_bool is_pure_unit_div(__isl_keep isl_basic_map *bmap, int div) +{ + int i; + isl_size v_div, n_ineq; + + v_div = isl_basic_map_var_offset(bmap, isl_dim_div); + n_ineq = isl_basic_map_n_inequality(bmap); + if (v_div < 0 || n_ineq < 0) + return isl_bool_error; + + for (i = 0; i < n_ineq; ++i) { + isl_bool skip; + + if (isl_int_is_zero(bmap->ineq[i][1 + v_div + div])) + continue; + skip = isl_basic_map_is_div_constraint(bmap, + bmap->ineq[i], div); + if (skip < 0) + return isl_bool_error; + if (skip) + continue; + if (!isl_int_is_one(bmap->ineq[i][1 + v_div + div]) && + !isl_int_is_negone(bmap->ineq[i][1 + v_div + div])) + return isl_bool_false; + } + + return isl_bool_true; +} + +/* Eliminate known divs from constraints where they appear with + * a (positive or negative) unit coefficient, + * but only if they do not appear in any other constraints + * (other than the div constraints). + */ +__isl_give isl_basic_map *isl_basic_map_eliminate_pure_unit_divs( + __isl_take isl_basic_map *bmap) +{ + return eliminate_selected_unit_divs(bmap, &is_pure_unit_div, NULL); +} + +__isl_give isl_basic_map *isl_basic_map_simplify(__isl_take isl_basic_map *bmap) +{ + int progress = 1; + if (!bmap) + return NULL; + while (progress) { + isl_bool empty; + + progress = 0; + empty = isl_basic_map_plain_is_empty(bmap); + if (empty < 0) + return isl_basic_map_free(bmap); + if (empty) + break; + bmap = isl_basic_map_normalize_constraints(bmap); + bmap = reduce_div_coefficients(bmap); + bmap = normalize_div_expressions(bmap); + bmap = remove_duplicate_divs(bmap, &progress); + bmap = eliminate_unit_divs(bmap, &progress); + bmap = eliminate_divs_eq(bmap, &progress); + bmap = eliminate_divs_ineq(bmap, &progress); + bmap = isl_basic_map_gauss(bmap, &progress); + /* requires equalities in normal form */ + bmap = normalize_divs(bmap, &progress); + bmap = isl_basic_map_remove_duplicate_constraints(bmap, + &progress, 1); + if (bmap && progress) + ISL_F_CLR(bmap, ISL_BASIC_MAP_REDUCED_COEFFICIENTS); + } + return bmap; +} + +__isl_give isl_basic_set *isl_basic_set_simplify( + __isl_take isl_basic_set *bset) +{ + return bset_from_bmap(isl_basic_map_simplify(bset_to_bmap(bset))); +} + + +isl_bool isl_basic_map_is_div_constraint(__isl_keep isl_basic_map *bmap, + isl_int *constraint, unsigned div) +{ + unsigned pos; + + if (!bmap) + return isl_bool_error; + + pos = isl_basic_map_offset(bmap, isl_dim_div) + div; + + if (isl_int_eq(constraint[pos], bmap->div[div][0])) { + int neg; + isl_int_sub(bmap->div[div][1], + bmap->div[div][1], bmap->div[div][0]); + isl_int_add_ui(bmap->div[div][1], bmap->div[div][1], 1); + neg = isl_seq_is_neg(constraint, bmap->div[div]+1, pos); + isl_int_sub_ui(bmap->div[div][1], bmap->div[div][1], 1); + isl_int_add(bmap->div[div][1], + bmap->div[div][1], bmap->div[div][0]); + if (!neg) + return isl_bool_false; + if (isl_seq_first_non_zero(constraint+pos+1, + bmap->n_div-div-1) != -1) + return isl_bool_false; + } else if (isl_int_abs_eq(constraint[pos], bmap->div[div][0])) { + if (!isl_seq_eq(constraint, bmap->div[div]+1, pos)) + return isl_bool_false; + if (isl_seq_first_non_zero(constraint+pos+1, + bmap->n_div-div-1) != -1) + return isl_bool_false; + } else + return isl_bool_false; + + return isl_bool_true; +} + +/* If the only constraints a div d=floor(f/m) + * appears in are its two defining constraints + * + * f - m d >=0 + * -(f - (m - 1)) + m d >= 0 + * + * then it can safely be removed. + */ +static isl_bool div_is_redundant(__isl_keep isl_basic_map *bmap, int div) +{ + int i; + isl_size v_div = isl_basic_map_var_offset(bmap, isl_dim_div); + unsigned pos = 1 + v_div + div; + + if (v_div < 0) + return isl_bool_error; + + for (i = 0; i < bmap->n_eq; ++i) + if (!isl_int_is_zero(bmap->eq[i][pos])) + return isl_bool_false; + + for (i = 0; i < bmap->n_ineq; ++i) { + isl_bool red; + + if (isl_int_is_zero(bmap->ineq[i][pos])) + continue; + red = isl_basic_map_is_div_constraint(bmap, bmap->ineq[i], div); + if (red < 0 || !red) + return red; + } + + for (i = 0; i < bmap->n_div; ++i) { + if (isl_int_is_zero(bmap->div[i][0])) + continue; + if (!isl_int_is_zero(bmap->div[i][1+pos])) + return isl_bool_false; + } + + return isl_bool_true; +} + +/* + * Remove divs that don't occur in any of the constraints or other divs. + * These can arise when dropping constraints from a basic map or + * when the divs of a basic map have been temporarily aligned + * with the divs of another basic map. + */ +static __isl_give isl_basic_map *remove_redundant_divs( + __isl_take isl_basic_map *bmap) +{ + int i; + isl_size v_div; + + v_div = isl_basic_map_var_offset(bmap, isl_dim_div); + if (v_div < 0) + return isl_basic_map_free(bmap); + + for (i = bmap->n_div-1; i >= 0; --i) { + isl_bool redundant; + + redundant = div_is_redundant(bmap, i); + if (redundant < 0) + return isl_basic_map_free(bmap); + if (!redundant) + continue; + bmap = isl_basic_map_drop_constraints_involving(bmap, + v_div + i, 1); + bmap = isl_basic_map_drop_div(bmap, i); + } + return bmap; +} + +/* Mark "bmap" as final, without checking for obviously redundant + * integer divisions. This function should be used when "bmap" + * is known not to involve any such integer divisions. + */ +__isl_give isl_basic_map *isl_basic_map_mark_final( + __isl_take isl_basic_map *bmap) +{ + if (!bmap) + return NULL; + ISL_F_SET(bmap, ISL_BASIC_SET_FINAL); + return bmap; +} + +/* Mark "bmap" as final, after removing obviously redundant integer divisions. + */ +__isl_give isl_basic_map *isl_basic_map_finalize(__isl_take isl_basic_map *bmap) +{ + bmap = remove_redundant_divs(bmap); + bmap = isl_basic_map_mark_final(bmap); + return bmap; +} + +__isl_give isl_basic_set *isl_basic_set_finalize( + __isl_take isl_basic_set *bset) +{ + return bset_from_bmap(isl_basic_map_finalize(bset_to_bmap(bset))); +} + +/* Remove definition of any div that is defined in terms of the given variable. + * The div itself is not removed. Functions such as + * eliminate_divs_ineq depend on the other divs remaining in place. + */ +static __isl_give isl_basic_map *remove_dependent_vars( + __isl_take isl_basic_map *bmap, int pos) +{ + int i; + + if (!bmap) + return NULL; + + for (i = 0; i < bmap->n_div; ++i) { + if (isl_int_is_zero(bmap->div[i][0])) + continue; + if (isl_int_is_zero(bmap->div[i][1+1+pos])) + continue; + bmap = isl_basic_map_mark_div_unknown(bmap, i); + if (!bmap) + return NULL; + } + return bmap; +} + +/* Eliminate the specified variables from the constraints using + * Fourier-Motzkin. The variables themselves are not removed. + */ +__isl_give isl_basic_map *isl_basic_map_eliminate_vars( + __isl_take isl_basic_map *bmap, unsigned pos, unsigned n) +{ + int d; + int i, j, k; + isl_size total; + int need_gauss = 0; + + if (n == 0) + return bmap; + total = isl_basic_map_dim(bmap, isl_dim_all); + if (total < 0) + return isl_basic_map_free(bmap); + + bmap = isl_basic_map_cow(bmap); + for (d = pos + n - 1; d >= 0 && d >= pos; --d) + bmap = remove_dependent_vars(bmap, d); + if (!bmap) + return NULL; + + for (d = pos + n - 1; + d >= 0 && d >= total - bmap->n_div && d >= pos; --d) + isl_seq_clr(bmap->div[d-(total-bmap->n_div)], 2+total); + for (d = pos + n - 1; d >= 0 && d >= pos; --d) { + int n_lower, n_upper; + if (!bmap) + return NULL; + for (i = 0; i < bmap->n_eq; ++i) { + if (isl_int_is_zero(bmap->eq[i][1+d])) + continue; + bmap = eliminate_var_using_equality(bmap, d, + bmap->eq[i], 0, NULL); + if (isl_basic_map_drop_equality(bmap, i) < 0) + return isl_basic_map_free(bmap); + need_gauss = 1; + break; + } + if (i < bmap->n_eq) + continue; + n_lower = 0; + n_upper = 0; + for (i = 0; i < bmap->n_ineq; ++i) { + if (isl_int_is_pos(bmap->ineq[i][1+d])) + n_lower++; + else if (isl_int_is_neg(bmap->ineq[i][1+d])) + n_upper++; + } + bmap = isl_basic_map_extend_constraints(bmap, + 0, n_lower * n_upper); + if (!bmap) + goto error; + for (i = bmap->n_ineq - 1; i >= 0; --i) { + int last; + if (isl_int_is_zero(bmap->ineq[i][1+d])) + continue; + last = -1; + for (j = 0; j < i; ++j) { + if (isl_int_is_zero(bmap->ineq[j][1+d])) + continue; + last = j; + if (isl_int_sgn(bmap->ineq[i][1+d]) == + isl_int_sgn(bmap->ineq[j][1+d])) + continue; + k = isl_basic_map_alloc_inequality(bmap); + if (k < 0) + goto error; + isl_seq_cpy(bmap->ineq[k], bmap->ineq[i], + 1+total); + isl_seq_elim(bmap->ineq[k], bmap->ineq[j], + 1+d, 1+total, NULL); + } + isl_basic_map_drop_inequality(bmap, i); + i = last + 1; + } + if (n_lower > 0 && n_upper > 0) { + bmap = isl_basic_map_normalize_constraints(bmap); + bmap = isl_basic_map_remove_duplicate_constraints(bmap, + NULL, 0); + bmap = isl_basic_map_gauss(bmap, NULL); + bmap = isl_basic_map_remove_redundancies(bmap); + need_gauss = 0; + if (!bmap) + goto error; + if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_EMPTY)) + break; + } + } + if (need_gauss) + bmap = isl_basic_map_gauss(bmap, NULL); + return bmap; +error: + isl_basic_map_free(bmap); + return NULL; +} + +__isl_give isl_basic_set *isl_basic_set_eliminate_vars( + __isl_take isl_basic_set *bset, unsigned pos, unsigned n) +{ + return bset_from_bmap(isl_basic_map_eliminate_vars(bset_to_bmap(bset), + pos, n)); +} + +/* Eliminate the specified n dimensions starting at first from the + * constraints, without removing the dimensions from the space. + * If the set is rational, the dimensions are eliminated using Fourier-Motzkin. + * Otherwise, they are projected out and the original space is restored. + */ +__isl_give isl_basic_map *isl_basic_map_eliminate( + __isl_take isl_basic_map *bmap, + enum isl_dim_type type, unsigned first, unsigned n) +{ + isl_space *space; + + if (!bmap) + return NULL; + if (n == 0) + return bmap; + + if (isl_basic_map_check_range(bmap, type, first, n) < 0) + return isl_basic_map_free(bmap); + + if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_RATIONAL)) { + first += isl_basic_map_offset(bmap, type) - 1; + bmap = isl_basic_map_eliminate_vars(bmap, first, n); + return isl_basic_map_finalize(bmap); + } + + space = isl_basic_map_get_space(bmap); + bmap = isl_basic_map_project_out(bmap, type, first, n); + bmap = isl_basic_map_insert_dims(bmap, type, first, n); + bmap = isl_basic_map_reset_space(bmap, space); + return bmap; +} + +__isl_give isl_basic_set *isl_basic_set_eliminate( + __isl_take isl_basic_set *bset, + enum isl_dim_type type, unsigned first, unsigned n) +{ + return isl_basic_map_eliminate(bset, type, first, n); +} + +/* Remove all constraints from "bmap" that reference any unknown local + * variables (directly or indirectly). + * + * Dropping all constraints on a local variable will make it redundant, + * so it will get removed implicitly by + * isl_basic_map_drop_constraints_involving_dims. Some other local + * variables may also end up becoming redundant if they only appear + * in constraints together with the unknown local variable. + * Therefore, start over after calling + * isl_basic_map_drop_constraints_involving_dims. + */ +__isl_give isl_basic_map *isl_basic_map_drop_constraints_involving_unknown_divs( + __isl_take isl_basic_map *bmap) +{ + isl_bool known; + isl_size n_div; + int i, o_div; + + known = isl_basic_map_divs_known(bmap); + if (known < 0) + return isl_basic_map_free(bmap); + if (known) + return bmap; + + n_div = isl_basic_map_dim(bmap, isl_dim_div); + if (n_div < 0) + return isl_basic_map_free(bmap); + o_div = isl_basic_map_offset(bmap, isl_dim_div) - 1; + + for (i = 0; i < n_div; ++i) { + known = isl_basic_map_div_is_known(bmap, i); + if (known < 0) + return isl_basic_map_free(bmap); + if (known) + continue; + bmap = remove_dependent_vars(bmap, o_div + i); + bmap = isl_basic_map_drop_constraints_involving_dims(bmap, + isl_dim_div, i, 1); + n_div = isl_basic_map_dim(bmap, isl_dim_div); + if (n_div < 0) + return isl_basic_map_free(bmap); + i = -1; + } + + return bmap; +} + +/* Remove all constraints from "bset" that reference any unknown local + * variables (directly or indirectly). + */ +__isl_give isl_basic_set *isl_basic_set_drop_constraints_involving_unknown_divs( + __isl_take isl_basic_set *bset) +{ + isl_basic_map *bmap; + + bmap = bset_to_bmap(bset); + bmap = isl_basic_map_drop_constraints_involving_unknown_divs(bmap); + return bset_from_bmap(bmap); +} + +/* Remove all constraints from "map" that reference any unknown local + * variables (directly or indirectly). + * + * Since constraints may get dropped from the basic maps, + * they may no longer be disjoint from each other. + */ +__isl_give isl_map *isl_map_drop_constraints_involving_unknown_divs( + __isl_take isl_map *map) +{ + int i; + isl_bool known; + + known = isl_map_divs_known(map); + if (known < 0) + return isl_map_free(map); + if (known) + return map; + + map = isl_map_cow(map); + if (!map) + return NULL; + + for (i = 0; i < map->n; ++i) { + map->p[i] = + isl_basic_map_drop_constraints_involving_unknown_divs( + map->p[i]); + if (!map->p[i]) + return isl_map_free(map); + } + + if (map->n > 1) + ISL_F_CLR(map, ISL_MAP_DISJOINT); + + return map; +} + +/* Don't assume equalities are in order, because align_divs + * may have changed the order of the divs. + */ +static void compute_elimination_index(__isl_keep isl_basic_map *bmap, int *elim, + unsigned len) +{ + int d, i; + + for (d = 0; d < len; ++d) + elim[d] = -1; + for (i = 0; i < bmap->n_eq; ++i) { + for (d = len - 1; d >= 0; --d) { + if (isl_int_is_zero(bmap->eq[i][1+d])) + continue; + elim[d] = i; + break; + } + } +} + +static void set_compute_elimination_index(__isl_keep isl_basic_set *bset, + int *elim, unsigned len) +{ + compute_elimination_index(bset_to_bmap(bset), elim, len); +} + +static int reduced_using_equalities(isl_int *dst, isl_int *src, + __isl_keep isl_basic_map *bmap, int *elim, unsigned total) +{ + int d; + int copied = 0; + + for (d = total - 1; d >= 0; --d) { + if (isl_int_is_zero(src[1+d])) + continue; + if (elim[d] == -1) + continue; + if (!copied) { + isl_seq_cpy(dst, src, 1 + total); + copied = 1; + } + isl_seq_elim(dst, bmap->eq[elim[d]], 1 + d, 1 + total, NULL); + } + return copied; +} + +static int set_reduced_using_equalities(isl_int *dst, isl_int *src, + __isl_keep isl_basic_set *bset, int *elim, unsigned total) +{ + return reduced_using_equalities(dst, src, + bset_to_bmap(bset), elim, total); +} + +static __isl_give isl_basic_set *isl_basic_set_reduce_using_equalities( + __isl_take isl_basic_set *bset, __isl_take isl_basic_set *context) +{ + int i; + int *elim; + isl_size dim; + + if (!bset || !context) + goto error; + + if (context->n_eq == 0) { + isl_basic_set_free(context); + return bset; + } + + bset = isl_basic_set_cow(bset); + dim = isl_basic_set_dim(bset, isl_dim_set); + if (dim < 0) + goto error; + + elim = isl_alloc_array(bset->ctx, int, dim); + if (!elim) + goto error; + set_compute_elimination_index(context, elim, dim); + for (i = 0; i < bset->n_eq; ++i) + set_reduced_using_equalities(bset->eq[i], bset->eq[i], + context, elim, dim); + for (i = 0; i < bset->n_ineq; ++i) + set_reduced_using_equalities(bset->ineq[i], bset->ineq[i], + context, elim, dim); + isl_basic_set_free(context); + free(elim); + bset = isl_basic_set_simplify(bset); + bset = isl_basic_set_finalize(bset); + return bset; +error: + isl_basic_set_free(bset); + isl_basic_set_free(context); + return NULL; +} + +/* For each inequality in "ineq" that is a shifted (more relaxed) + * copy of an inequality in "context", mark the corresponding entry + * in "row" with -1. + * If an inequality only has a non-negative constant term, then + * mark it as well. + */ +static isl_stat mark_shifted_constraints(__isl_keep isl_mat *ineq, + __isl_keep isl_basic_set *context, int *row) +{ + struct isl_constraint_index ci; + isl_size n_ineq, cols; + unsigned total; + int k; + + if (!ineq || !context) + return isl_stat_error; + if (context->n_ineq == 0) + return isl_stat_ok; + if (setup_constraint_index(&ci, context) < 0) + return isl_stat_error; + + n_ineq = isl_mat_rows(ineq); + cols = isl_mat_cols(ineq); + if (n_ineq < 0 || cols < 0) + return isl_stat_error; + total = cols - 1; + for (k = 0; k < n_ineq; ++k) { + int l; + isl_bool redundant; + + l = isl_seq_first_non_zero(ineq->row[k] + 1, total); + if (l < 0 && isl_int_is_nonneg(ineq->row[k][0])) { + row[k] = -1; + continue; + } + redundant = constraint_index_is_redundant(&ci, ineq->row[k]); + if (redundant < 0) + goto error; + if (!redundant) + continue; + row[k] = -1; + } + constraint_index_free(&ci); + return isl_stat_ok; +error: + constraint_index_free(&ci); + return isl_stat_error; +} + +static __isl_give isl_basic_set *remove_shifted_constraints( + __isl_take isl_basic_set *bset, __isl_keep isl_basic_set *context) +{ + struct isl_constraint_index ci; + int k; + + if (!bset || !context) + return bset; + + if (context->n_ineq == 0) + return bset; + if (setup_constraint_index(&ci, context) < 0) + return bset; + + for (k = 0; k < bset->n_ineq; ++k) { + isl_bool redundant; + + redundant = constraint_index_is_redundant(&ci, bset->ineq[k]); + if (redundant < 0) + goto error; + if (!redundant) + continue; + bset = isl_basic_set_cow(bset); + if (!bset) + goto error; + isl_basic_set_drop_inequality(bset, k); + --k; + } + constraint_index_free(&ci); + return bset; +error: + constraint_index_free(&ci); + return bset; +} + +/* Remove constraints from "bmap" that are identical to constraints + * in "context" or that are more relaxed (greater constant term). + * + * We perform the test for shifted copies on the pure constraints + * in remove_shifted_constraints. + */ +static __isl_give isl_basic_map *isl_basic_map_remove_shifted_constraints( + __isl_take isl_basic_map *bmap, __isl_take isl_basic_map *context) +{ + isl_basic_set *bset, *bset_context; + + if (!bmap || !context) + goto error; + + if (bmap->n_ineq == 0 || context->n_ineq == 0) { + isl_basic_map_free(context); + return bmap; + } + + bmap = isl_basic_map_order_divs(bmap); + context = isl_basic_map_align_divs(context, bmap); + bmap = isl_basic_map_align_divs(bmap, context); + + bset = isl_basic_map_underlying_set(isl_basic_map_copy(bmap)); + bset_context = isl_basic_map_underlying_set(context); + bset = remove_shifted_constraints(bset, bset_context); + isl_basic_set_free(bset_context); + + bmap = isl_basic_map_overlying_set(bset, bmap); + + return bmap; +error: + isl_basic_map_free(bmap); + isl_basic_map_free(context); + return NULL; +} + +/* Does the (linear part of a) constraint "c" involve any of the "len" + * "relevant" dimensions? + */ +static int is_related(isl_int *c, int len, int *relevant) +{ + int i; + + for (i = 0; i < len; ++i) { + if (!relevant[i]) + continue; + if (!isl_int_is_zero(c[i])) + return 1; + } + + return 0; +} + +/* Drop constraints from "bmap" that do not involve any of + * the dimensions marked "relevant". + */ +static __isl_give isl_basic_map *drop_unrelated_constraints( + __isl_take isl_basic_map *bmap, int *relevant) +{ + int i; + isl_size dim; + + dim = isl_basic_map_dim(bmap, isl_dim_all); + if (dim < 0) + return isl_basic_map_free(bmap); + for (i = 0; i < dim; ++i) + if (!relevant[i]) + break; + if (i >= dim) + return bmap; + + for (i = bmap->n_eq - 1; i >= 0; --i) + if (!is_related(bmap->eq[i] + 1, dim, relevant)) { + bmap = isl_basic_map_cow(bmap); + if (isl_basic_map_drop_equality(bmap, i) < 0) + return isl_basic_map_free(bmap); + } + + for (i = bmap->n_ineq - 1; i >= 0; --i) + if (!is_related(bmap->ineq[i] + 1, dim, relevant)) { + bmap = isl_basic_map_cow(bmap); + if (isl_basic_map_drop_inequality(bmap, i) < 0) + return isl_basic_map_free(bmap); + } + + return bmap; +} + +/* Update the groups in "group" based on the (linear part of a) constraint "c". + * + * In particular, for any variable involved in the constraint, + * find the actual group id from before and replace the group + * of the corresponding variable by the minimal group of all + * the variables involved in the constraint considered so far + * (if this minimum is smaller) or replace the minimum by this group + * (if the minimum is larger). + * + * At the end, all the variables in "c" will (indirectly) point + * to the minimal of the groups that they referred to originally. + */ +static void update_groups(int dim, int *group, isl_int *c) +{ + int j; + int min = dim; + + for (j = 0; j < dim; ++j) { + if (isl_int_is_zero(c[j])) + continue; + while (group[j] >= 0 && group[group[j]] != group[j]) + group[j] = group[group[j]]; + if (group[j] == min) + continue; + if (group[j] < min) { + if (min >= 0 && min < dim) + group[min] = group[j]; + min = group[j]; + } else + group[group[j]] = min; + } +} + +/* Allocate an array of groups of variables, one for each variable + * in "context", initialized to zero. + */ +static int *alloc_groups(__isl_keep isl_basic_set *context) +{ + isl_ctx *ctx; + isl_size dim; + + dim = isl_basic_set_dim(context, isl_dim_set); + if (dim < 0) + return NULL; + ctx = isl_basic_set_get_ctx(context); + return isl_calloc_array(ctx, int, dim); +} + +/* Drop constraints from "bmap" that only involve variables that are + * not related to any of the variables marked with a "-1" in "group". + * + * We construct groups of variables that collect variables that + * (indirectly) appear in some common constraint of "bmap". + * Each group is identified by the first variable in the group, + * except for the special group of variables that was already identified + * in the input as -1 (or are related to those variables). + * If group[i] is equal to i (or -1), then the group of i is i (or -1), + * otherwise the group of i is the group of group[i]. + * + * We first initialize groups for the remaining variables. + * Then we iterate over the constraints of "bmap" and update the + * group of the variables in the constraint by the smallest group. + * Finally, we resolve indirect references to groups by running over + * the variables. + * + * After computing the groups, we drop constraints that do not involve + * any variables in the -1 group. + */ +__isl_give isl_basic_map *isl_basic_map_drop_unrelated_constraints( + __isl_take isl_basic_map *bmap, __isl_take int *group) +{ + isl_size dim; + int i; + int last; + + dim = isl_basic_map_dim(bmap, isl_dim_all); + if (dim < 0) + return isl_basic_map_free(bmap); + + last = -1; + for (i = 0; i < dim; ++i) + if (group[i] >= 0) + last = group[i] = i; + if (last < 0) { + free(group); + return bmap; + } + + for (i = 0; i < bmap->n_eq; ++i) + update_groups(dim, group, bmap->eq[i] + 1); + for (i = 0; i < bmap->n_ineq; ++i) + update_groups(dim, group, bmap->ineq[i] + 1); + + for (i = 0; i < dim; ++i) + if (group[i] >= 0) + group[i] = group[group[i]]; + + for (i = 0; i < dim; ++i) + group[i] = group[i] == -1; + + bmap = drop_unrelated_constraints(bmap, group); + + free(group); + return bmap; +} + +/* Drop constraints from "context" that are irrelevant for computing + * the gist of "bset". + * + * In particular, drop constraints in variables that are not related + * to any of the variables involved in the constraints of "bset" + * in the sense that there is no sequence of constraints that connects them. + * + * We first mark all variables that appear in "bset" as belonging + * to a "-1" group and then continue with group_and_drop_irrelevant_constraints. + */ +static __isl_give isl_basic_set *drop_irrelevant_constraints( + __isl_take isl_basic_set *context, __isl_keep isl_basic_set *bset) +{ + int *group; + isl_size dim; + int i, j; + + dim = isl_basic_set_dim(bset, isl_dim_set); + if (!context || dim < 0) + return isl_basic_set_free(context); + + group = alloc_groups(context); + + if (!group) + return isl_basic_set_free(context); + + for (i = 0; i < dim; ++i) { + for (j = 0; j < bset->n_eq; ++j) + if (!isl_int_is_zero(bset->eq[j][1 + i])) + break; + if (j < bset->n_eq) { + group[i] = -1; + continue; + } + for (j = 0; j < bset->n_ineq; ++j) + if (!isl_int_is_zero(bset->ineq[j][1 + i])) + break; + if (j < bset->n_ineq) + group[i] = -1; + } + + return isl_basic_map_drop_unrelated_constraints(context, group); +} + +/* Drop constraints from "context" that are irrelevant for computing + * the gist of the inequalities "ineq". + * Inequalities in "ineq" for which the corresponding element of row + * is set to -1 have already been marked for removal and should be ignored. + * + * In particular, drop constraints in variables that are not related + * to any of the variables involved in "ineq" + * in the sense that there is no sequence of constraints that connects them. + * + * We first mark all variables that appear in "bset" as belonging + * to a "-1" group and then continue with group_and_drop_irrelevant_constraints. + */ +static __isl_give isl_basic_set *drop_irrelevant_constraints_marked( + __isl_take isl_basic_set *context, __isl_keep isl_mat *ineq, int *row) +{ + int *group; + isl_size dim; + int i, j; + isl_size n; + + dim = isl_basic_set_dim(context, isl_dim_set); + n = isl_mat_rows(ineq); + if (dim < 0 || n < 0) + return isl_basic_set_free(context); + + group = alloc_groups(context); + + if (!group) + return isl_basic_set_free(context); + + for (i = 0; i < dim; ++i) { + for (j = 0; j < n; ++j) { + if (row[j] < 0) + continue; + if (!isl_int_is_zero(ineq->row[j][1 + i])) + break; + } + if (j < n) + group[i] = -1; + } + + return isl_basic_map_drop_unrelated_constraints(context, group); +} + +/* Do all "n" entries of "row" contain a negative value? + */ +static int all_neg(int *row, int n) +{ + int i; + + for (i = 0; i < n; ++i) + if (row[i] >= 0) + return 0; + + return 1; +} + +/* Update the inequalities in "bset" based on the information in "row" + * and "tab". + * + * In particular, the array "row" contains either -1, meaning that + * the corresponding inequality of "bset" is redundant, or the index + * of an inequality in "tab". + * + * If the row entry is -1, then drop the inequality. + * Otherwise, if the constraint is marked redundant in the tableau, + * then drop the inequality. Similarly, if it is marked as an equality + * in the tableau, then turn the inequality into an equality and + * perform Gaussian elimination. + */ +static __isl_give isl_basic_set *update_ineq(__isl_take isl_basic_set *bset, + __isl_keep int *row, struct isl_tab *tab) +{ + int i; + unsigned n_ineq; + unsigned n_eq; + int found_equality = 0; + + if (!bset) + return NULL; + if (tab && tab->empty) + return isl_basic_set_set_to_empty(bset); + + n_ineq = bset->n_ineq; + for (i = n_ineq - 1; i >= 0; --i) { + if (row[i] < 0) { + if (isl_basic_set_drop_inequality(bset, i) < 0) + return isl_basic_set_free(bset); + continue; + } + if (!tab) + continue; + n_eq = tab->n_eq; + if (isl_tab_is_equality(tab, n_eq + row[i])) { + isl_basic_map_inequality_to_equality(bset, i); + found_equality = 1; + } else if (isl_tab_is_redundant(tab, n_eq + row[i])) { + if (isl_basic_set_drop_inequality(bset, i) < 0) + return isl_basic_set_free(bset); + } + } + + if (found_equality) + bset = isl_basic_set_gauss(bset, NULL); + bset = isl_basic_set_finalize(bset); + return bset; +} + +/* Update the inequalities in "bset" based on the information in "row" + * and "tab" and free all arguments (other than "bset"). + */ +static __isl_give isl_basic_set *update_ineq_free( + __isl_take isl_basic_set *bset, __isl_take isl_mat *ineq, + __isl_take isl_basic_set *context, __isl_take int *row, + struct isl_tab *tab) +{ + isl_mat_free(ineq); + isl_basic_set_free(context); + + bset = update_ineq(bset, row, tab); + + free(row); + isl_tab_free(tab); + return bset; +} + +/* Remove all information from bset that is redundant in the context + * of context. + * "ineq" contains the (possibly transformed) inequalities of "bset", + * in the same order. + * The (explicit) equalities of "bset" are assumed to have been taken + * into account by the transformation such that only the inequalities + * are relevant. + * "context" is assumed not to be empty. + * + * "row" keeps track of the constraint index of a "bset" inequality in "tab". + * A value of -1 means that the inequality is obviously redundant and may + * not even appear in "tab". + * + * We first mark the inequalities of "bset" + * that are obviously redundant with respect to some inequality in "context". + * Then we remove those constraints from "context" that have become + * irrelevant for computing the gist of "bset". + * Note that this removal of constraints cannot be replaced by + * a factorization because factors in "bset" may still be connected + * to each other through constraints in "context". + * + * If there are any inequalities left, we construct a tableau for + * the context and then add the inequalities of "bset". + * Before adding these inequalities, we freeze all constraints such that + * they won't be considered redundant in terms of the constraints of "bset". + * Then we detect all redundant constraints (among the + * constraints that weren't frozen), first by checking for redundancy in the + * the tableau and then by checking if replacing a constraint by its negation + * would lead to an empty set. This last step is fairly expensive + * and could be optimized by more reuse of the tableau. + * Finally, we update bset according to the results. + */ +static __isl_give isl_basic_set *uset_gist_full(__isl_take isl_basic_set *bset, + __isl_take isl_mat *ineq, __isl_take isl_basic_set *context) +{ + int i, r; + int *row = NULL; + isl_ctx *ctx; + isl_basic_set *combined = NULL; + struct isl_tab *tab = NULL; + unsigned n_eq, context_ineq; + + if (!bset || !ineq || !context) + goto error; + + if (bset->n_ineq == 0 || isl_basic_set_plain_is_universe(context)) { + isl_basic_set_free(context); + isl_mat_free(ineq); + return bset; + } + + ctx = isl_basic_set_get_ctx(context); + row = isl_calloc_array(ctx, int, bset->n_ineq); + if (!row) + goto error; + + if (mark_shifted_constraints(ineq, context, row) < 0) + goto error; + if (all_neg(row, bset->n_ineq)) + return update_ineq_free(bset, ineq, context, row, NULL); + + context = drop_irrelevant_constraints_marked(context, ineq, row); + if (!context) + goto error; + if (isl_basic_set_plain_is_universe(context)) + return update_ineq_free(bset, ineq, context, row, NULL); + + n_eq = context->n_eq; + context_ineq = context->n_ineq; + combined = isl_basic_set_cow(isl_basic_set_copy(context)); + combined = isl_basic_set_extend_constraints(combined, 0, bset->n_ineq); + tab = isl_tab_from_basic_set(combined, 0); + for (i = 0; i < context_ineq; ++i) + if (isl_tab_freeze_constraint(tab, n_eq + i) < 0) + goto error; + if (isl_tab_extend_cons(tab, bset->n_ineq) < 0) + goto error; + r = context_ineq; + for (i = 0; i < bset->n_ineq; ++i) { + if (row[i] < 0) + continue; + combined = isl_basic_set_add_ineq(combined, ineq->row[i]); + if (isl_tab_add_ineq(tab, ineq->row[i]) < 0) + goto error; + row[i] = r++; + } + if (isl_tab_detect_implicit_equalities(tab) < 0) + goto error; + if (isl_tab_detect_redundant(tab) < 0) + goto error; + for (i = bset->n_ineq - 1; i >= 0; --i) { + isl_basic_set *test; + int is_empty; + + if (row[i] < 0) + continue; + r = row[i]; + if (tab->con[n_eq + r].is_redundant) + continue; + test = isl_basic_set_dup(combined); + test = isl_inequality_negate(test, r); + test = isl_basic_set_update_from_tab(test, tab); + is_empty = isl_basic_set_is_empty(test); + isl_basic_set_free(test); + if (is_empty < 0) + goto error; + if (is_empty) + tab->con[n_eq + r].is_redundant = 1; + } + bset = update_ineq_free(bset, ineq, context, row, tab); + if (bset) { + ISL_F_SET(bset, ISL_BASIC_SET_NO_IMPLICIT); + ISL_F_SET(bset, ISL_BASIC_SET_NO_REDUNDANT); + } + + isl_basic_set_free(combined); + return bset; +error: + free(row); + isl_mat_free(ineq); + isl_tab_free(tab); + isl_basic_set_free(combined); + isl_basic_set_free(context); + isl_basic_set_free(bset); + return NULL; +} + +/* Extract the inequalities of "bset" as an isl_mat. + */ +static __isl_give isl_mat *extract_ineq(__isl_keep isl_basic_set *bset) +{ + isl_size total; + isl_ctx *ctx; + isl_mat *ineq; + + total = isl_basic_set_dim(bset, isl_dim_all); + if (total < 0) + return NULL; + + ctx = isl_basic_set_get_ctx(bset); + ineq = isl_mat_sub_alloc6(ctx, bset->ineq, 0, bset->n_ineq, + 0, 1 + total); + + return ineq; +} + +/* Remove all information from "bset" that is redundant in the context + * of "context", for the case where both "bset" and "context" are + * full-dimensional. + */ +static __isl_give isl_basic_set *uset_gist_uncompressed( + __isl_take isl_basic_set *bset, __isl_take isl_basic_set *context) +{ + isl_mat *ineq; + + ineq = extract_ineq(bset); + return uset_gist_full(bset, ineq, context); +} + +/* Replace "bset" by an empty basic set in the same space. + */ +static __isl_give isl_basic_set *replace_by_empty( + __isl_take isl_basic_set *bset) +{ + isl_space *space; + + space = isl_basic_set_get_space(bset); + isl_basic_set_free(bset); + return isl_basic_set_empty(space); +} + +/* Remove all information from "bset" that is redundant in the context + * of "context", for the case where the combined equalities of + * "bset" and "context" allow for a compression that can be obtained + * by preapplication of "T". + * If the compression of "context" is empty, meaning that "bset" and + * "context" do not intersect, then return the empty set. + * + * "bset" itself is not transformed by "T". Instead, the inequalities + * are extracted from "bset" and those are transformed by "T". + * uset_gist_full then determines which of the transformed inequalities + * are redundant with respect to the transformed "context" and removes + * the corresponding inequalities from "bset". + * + * After preapplying "T" to the inequalities, any common factor is + * removed from the coefficients. If this results in a tightening + * of the constant term, then the same tightening is applied to + * the corresponding untransformed inequality in "bset". + * That is, if after plugging in T, a constraint f(x) >= 0 is of the form + * + * g f'(x) + r >= 0 + * + * with 0 <= r < g, then it is equivalent to + * + * f'(x) >= 0 + * + * This means that f(x) >= 0 is equivalent to f(x) - r >= 0 in the affine + * subspace compressed by T since the latter would be transformed to + * + * g f'(x) >= 0 + */ +static __isl_give isl_basic_set *uset_gist_compressed( + __isl_take isl_basic_set *bset, __isl_take isl_basic_set *context, + __isl_take isl_mat *T) +{ + isl_ctx *ctx; + isl_mat *ineq; + int i; + isl_size n_row, n_col; + isl_int rem; + + ineq = extract_ineq(bset); + ineq = isl_mat_product(ineq, isl_mat_copy(T)); + context = isl_basic_set_preimage(context, T); + + if (!ineq || !context) + goto error; + if (isl_basic_set_plain_is_empty(context)) { + isl_mat_free(ineq); + isl_basic_set_free(context); + return replace_by_empty(bset); + } + + ctx = isl_mat_get_ctx(ineq); + n_row = isl_mat_rows(ineq); + n_col = isl_mat_cols(ineq); + if (n_row < 0 || n_col < 0) + goto error; + isl_int_init(rem); + for (i = 0; i < n_row; ++i) { + isl_seq_gcd(ineq->row[i] + 1, n_col - 1, &ctx->normalize_gcd); + if (isl_int_is_zero(ctx->normalize_gcd)) + continue; + if (isl_int_is_one(ctx->normalize_gcd)) + continue; + isl_seq_scale_down(ineq->row[i] + 1, ineq->row[i] + 1, + ctx->normalize_gcd, n_col - 1); + isl_int_fdiv_r(rem, ineq->row[i][0], ctx->normalize_gcd); + isl_int_fdiv_q(ineq->row[i][0], + ineq->row[i][0], ctx->normalize_gcd); + if (isl_int_is_zero(rem)) + continue; + bset = isl_basic_set_cow(bset); + if (!bset) + break; + isl_int_sub(bset->ineq[i][0], bset->ineq[i][0], rem); + } + isl_int_clear(rem); + + return uset_gist_full(bset, ineq, context); +error: + isl_mat_free(ineq); + isl_basic_set_free(context); + isl_basic_set_free(bset); + return NULL; +} + +/* Project "bset" onto the variables that are involved in "template". + */ +static __isl_give isl_basic_set *project_onto_involved( + __isl_take isl_basic_set *bset, __isl_keep isl_basic_set *template) +{ + int i; + isl_size n; + + n = isl_basic_set_dim(template, isl_dim_set); + if (n < 0 || !template) + return isl_basic_set_free(bset); + + for (i = 0; i < n; ++i) { + isl_bool involved; + + involved = isl_basic_set_involves_dims(template, + isl_dim_set, i, 1); + if (involved < 0) + return isl_basic_set_free(bset); + if (involved) + continue; + bset = isl_basic_set_eliminate_vars(bset, i, 1); + } + + return bset; +} + +/* Remove all information from bset that is redundant in the context + * of context. In particular, equalities that are linear combinations + * of those in context are removed. Then the inequalities that are + * redundant in the context of the equalities and inequalities of + * context are removed. + * + * First of all, we drop those constraints from "context" + * that are irrelevant for computing the gist of "bset". + * Alternatively, we could factorize the intersection of "context" and "bset". + * + * We first compute the intersection of the integer affine hulls + * of "bset" and "context", + * compute the gist inside this intersection and then reduce + * the constraints with respect to the equalities of the context + * that only involve variables already involved in the input. + * If the intersection of the affine hulls turns out to be empty, + * then return the empty set. + * + * If two constraints are mutually redundant, then uset_gist_full + * will remove the second of those constraints. We therefore first + * sort the constraints so that constraints not involving existentially + * quantified variables are given precedence over those that do. + * We have to perform this sorting before the variable compression, + * because that may effect the order of the variables. + */ +static __isl_give isl_basic_set *uset_gist(__isl_take isl_basic_set *bset, + __isl_take isl_basic_set *context) +{ + isl_mat *eq; + isl_mat *T; + isl_basic_set *aff; + isl_basic_set *aff_context; + isl_size total; + + total = isl_basic_set_dim(bset, isl_dim_all); + if (total < 0 || !context) + goto error; + + context = drop_irrelevant_constraints(context, bset); + + bset = isl_basic_set_detect_equalities(bset); + aff = isl_basic_set_copy(bset); + aff = isl_basic_set_plain_affine_hull(aff); + context = isl_basic_set_detect_equalities(context); + aff_context = isl_basic_set_copy(context); + aff_context = isl_basic_set_plain_affine_hull(aff_context); + aff = isl_basic_set_intersect(aff, aff_context); + if (!aff) + goto error; + if (isl_basic_set_plain_is_empty(aff)) { + isl_basic_set_free(bset); + isl_basic_set_free(context); + return aff; + } + bset = isl_basic_set_sort_constraints(bset); + if (aff->n_eq == 0) { + isl_basic_set_free(aff); + return uset_gist_uncompressed(bset, context); + } + eq = isl_mat_sub_alloc6(bset->ctx, aff->eq, 0, aff->n_eq, 0, 1 + total); + eq = isl_mat_cow(eq); + T = isl_mat_variable_compression(eq, NULL); + isl_basic_set_free(aff); + if (T && T->n_col == 0) { + isl_mat_free(T); + isl_basic_set_free(context); + return replace_by_empty(bset); + } + + aff_context = isl_basic_set_affine_hull(isl_basic_set_copy(context)); + aff_context = project_onto_involved(aff_context, bset); + + bset = uset_gist_compressed(bset, context, T); + bset = isl_basic_set_reduce_using_equalities(bset, aff_context); + + if (bset) { + ISL_F_SET(bset, ISL_BASIC_SET_NO_IMPLICIT); + ISL_F_SET(bset, ISL_BASIC_SET_NO_REDUNDANT); + } + + return bset; +error: + isl_basic_set_free(bset); + isl_basic_set_free(context); + return NULL; +} + +/* Return the number of equality constraints in "bmap" that involve + * local variables. This function assumes that Gaussian elimination + * has been applied to the equality constraints. + */ +static int n_div_eq(__isl_keep isl_basic_map *bmap) +{ + int i; + isl_size total, n_div; + + if (!bmap) + return -1; + + if (bmap->n_eq == 0) + return 0; + + total = isl_basic_map_dim(bmap, isl_dim_all); + n_div = isl_basic_map_dim(bmap, isl_dim_div); + if (total < 0 || n_div < 0) + return -1; + total -= n_div; + + for (i = 0; i < bmap->n_eq; ++i) + if (isl_seq_first_non_zero(bmap->eq[i] + 1 + total, + n_div) == -1) + return i; + + return bmap->n_eq; +} + +/* Construct a basic map in "space" defined by the equality constraints in "eq". + * The constraints are assumed not to involve any local variables. + */ +static __isl_give isl_basic_map *basic_map_from_equalities( + __isl_take isl_space *space, __isl_take isl_mat *eq) +{ + int i, k; + isl_size total; + isl_basic_map *bmap = NULL; + + total = isl_space_dim(space, isl_dim_all); + if (total < 0 || !eq) + goto error; + + if (1 + total != eq->n_col) + isl_die(isl_space_get_ctx(space), isl_error_internal, + "unexpected number of columns", goto error); + + bmap = isl_basic_map_alloc_space(isl_space_copy(space), + 0, eq->n_row, 0); + for (i = 0; i < eq->n_row; ++i) { + k = isl_basic_map_alloc_equality(bmap); + if (k < 0) + goto error; + isl_seq_cpy(bmap->eq[k], eq->row[i], eq->n_col); + } + + isl_space_free(space); + isl_mat_free(eq); + return bmap; +error: + isl_space_free(space); + isl_mat_free(eq); + isl_basic_map_free(bmap); + return NULL; +} + +/* Construct and return a variable compression based on the equality + * constraints in "bmap1" and "bmap2" that do not involve the local variables. + * "n1" is the number of (initial) equality constraints in "bmap1" + * that do involve local variables. + * "n2" is the number of (initial) equality constraints in "bmap2" + * that do involve local variables. + * "total" is the total number of other variables. + * This function assumes that Gaussian elimination + * has been applied to the equality constraints in both "bmap1" and "bmap2" + * such that the equality constraints not involving local variables + * are those that start at "n1" or "n2". + * + * If either of "bmap1" and "bmap2" does not have such equality constraints, + * then simply compute the compression based on the equality constraints + * in the other basic map. + * Otherwise, combine the equality constraints from both into a new + * basic map such that Gaussian elimination can be applied to this combination + * and then construct a variable compression from the resulting + * equality constraints. + */ +static __isl_give isl_mat *combined_variable_compression( + __isl_keep isl_basic_map *bmap1, int n1, + __isl_keep isl_basic_map *bmap2, int n2, int total) +{ + isl_ctx *ctx; + isl_mat *E1, *E2, *V; + isl_basic_map *bmap; + + ctx = isl_basic_map_get_ctx(bmap1); + if (bmap1->n_eq == n1) { + E2 = isl_mat_sub_alloc6(ctx, bmap2->eq, + n2, bmap2->n_eq - n2, 0, 1 + total); + return isl_mat_variable_compression(E2, NULL); + } + if (bmap2->n_eq == n2) { + E1 = isl_mat_sub_alloc6(ctx, bmap1->eq, + n1, bmap1->n_eq - n1, 0, 1 + total); + return isl_mat_variable_compression(E1, NULL); + } + E1 = isl_mat_sub_alloc6(ctx, bmap1->eq, + n1, bmap1->n_eq - n1, 0, 1 + total); + E2 = isl_mat_sub_alloc6(ctx, bmap2->eq, + n2, bmap2->n_eq - n2, 0, 1 + total); + E1 = isl_mat_concat(E1, E2); + bmap = basic_map_from_equalities(isl_basic_map_get_space(bmap1), E1); + bmap = isl_basic_map_gauss(bmap, NULL); + if (!bmap) + return NULL; + E1 = isl_mat_sub_alloc6(ctx, bmap->eq, 0, bmap->n_eq, 0, 1 + total); + V = isl_mat_variable_compression(E1, NULL); + isl_basic_map_free(bmap); + + return V; +} + +/* Extract the stride constraints from "bmap", compressed + * with respect to both the stride constraints in "context" and + * the remaining equality constraints in both "bmap" and "context". + * "bmap_n_eq" is the number of (initial) stride constraints in "bmap". + * "context_n_eq" is the number of (initial) stride constraints in "context". + * + * Let x be all variables in "bmap" (and "context") other than the local + * variables. First compute a variable compression + * + * x = V x' + * + * based on the non-stride equality constraints in "bmap" and "context". + * Consider the stride constraints of "context", + * + * A(x) + B(y) = 0 + * + * with y the local variables and plug in the variable compression, + * resulting in + * + * A(V x') + B(y) = 0 + * + * Use these constraints to compute a parameter compression on x' + * + * x' = T x'' + * + * Now consider the stride constraints of "bmap" + * + * C(x) + D(y) = 0 + * + * and plug in x = V*T x''. + * That is, return A = [C*V*T D]. + */ +static __isl_give isl_mat *extract_compressed_stride_constraints( + __isl_keep isl_basic_map *bmap, int bmap_n_eq, + __isl_keep isl_basic_map *context, int context_n_eq) +{ + isl_size total, n_div; + isl_ctx *ctx; + isl_mat *A, *B, *T, *V; + + total = isl_basic_map_dim(context, isl_dim_all); + n_div = isl_basic_map_dim(context, isl_dim_div); + if (total < 0 || n_div < 0) + return NULL; + total -= n_div; + + ctx = isl_basic_map_get_ctx(bmap); + + V = combined_variable_compression(bmap, bmap_n_eq, + context, context_n_eq, total); + + A = isl_mat_sub_alloc6(ctx, context->eq, 0, context_n_eq, 0, 1 + total); + B = isl_mat_sub_alloc6(ctx, context->eq, + 0, context_n_eq, 1 + total, n_div); + A = isl_mat_product(A, isl_mat_copy(V)); + T = isl_mat_parameter_compression_ext(A, B); + T = isl_mat_product(V, T); + + n_div = isl_basic_map_dim(bmap, isl_dim_div); + if (n_div < 0) + T = isl_mat_free(T); + else + T = isl_mat_diagonal(T, isl_mat_identity(ctx, n_div)); + + A = isl_mat_sub_alloc6(ctx, bmap->eq, + 0, bmap_n_eq, 0, 1 + total + n_div); + A = isl_mat_product(A, T); + + return A; +} + +/* Remove the prime factors from *g that have an exponent that + * is strictly smaller than the exponent in "c". + * All exponents in *g are known to be smaller than or equal + * to those in "c". + * + * That is, if *g is equal to + * + * p_1^{e_1} p_2^{e_2} ... p_n^{e_n} + * + * and "c" is equal to + * + * p_1^{f_1} p_2^{f_2} ... p_n^{f_n} + * + * then update *g to + * + * p_1^{e_1 * (e_1 = f_1)} p_2^{e_2 * (e_2 = f_2)} ... + * p_n^{e_n * (e_n = f_n)} + * + * If e_i = f_i, then c / *g does not have any p_i factors and therefore + * neither does the gcd of *g and c / *g. + * If e_i < f_i, then the gcd of *g and c / *g has a positive + * power min(e_i, s_i) of p_i with s_i = f_i - e_i among its factors. + * Dividing *g by this gcd therefore strictly reduces the exponent + * of the prime factors that need to be removed, while leaving the + * other prime factors untouched. + * Repeating this process until gcd(*g, c / *g) = 1 therefore + * removes all undesired factors, without removing any others. + */ +static void remove_incomplete_powers(isl_int *g, isl_int c) +{ + isl_int t; + + isl_int_init(t); + for (;;) { + isl_int_divexact(t, c, *g); + isl_int_gcd(t, t, *g); + if (isl_int_is_one(t)) + break; + isl_int_divexact(*g, *g, t); + } + isl_int_clear(t); +} + +/* Reduce the "n" stride constraints in "bmap" based on a copy "A" + * of the same stride constraints in a compressed space that exploits + * all equalities in the context and the other equalities in "bmap". + * + * If the stride constraints of "bmap" are of the form + * + * C(x) + D(y) = 0 + * + * then A is of the form + * + * B(x') + D(y) = 0 + * + * If any of these constraints involves only a single local variable y, + * then the constraint appears as + * + * f(x) + m y_i = 0 + * + * in "bmap" and as + * + * h(x') + m y_i = 0 + * + * in "A". + * + * Let g be the gcd of m and the coefficients of h. + * Then, in particular, g is a divisor of the coefficients of h and + * + * f(x) = h(x') + * + * is known to be a multiple of g. + * If some prime factor in m appears with the same exponent in g, + * then it can be removed from m because f(x) is already known + * to be a multiple of g and therefore in particular of this power + * of the prime factors. + * Prime factors that appear with a smaller exponent in g cannot + * be removed from m. + * Let g' be the divisor of g containing all prime factors that + * appear with the same exponent in m and g, then + * + * f(x) + m y_i = 0 + * + * can be replaced by + * + * f(x) + m/g' y_i' = 0 + * + * Note that (if g' != 1) this changes the explicit representation + * of y_i to that of y_i', so the integer division at position i + * is marked unknown and later recomputed by a call to + * isl_basic_map_gauss. + */ +static __isl_give isl_basic_map *reduce_stride_constraints( + __isl_take isl_basic_map *bmap, int n, __isl_keep isl_mat *A) +{ + int i; + isl_size total, n_div; + int any = 0; + isl_int gcd; + + total = isl_basic_map_dim(bmap, isl_dim_all); + n_div = isl_basic_map_dim(bmap, isl_dim_div); + if (total < 0 || n_div < 0 || !A) + return isl_basic_map_free(bmap); + total -= n_div; + + isl_int_init(gcd); + for (i = 0; i < n; ++i) { + int div; + + div = isl_seq_first_non_zero(bmap->eq[i] + 1 + total, n_div); + if (div < 0) + isl_die(isl_basic_map_get_ctx(bmap), isl_error_internal, + "equality constraints modified unexpectedly", + goto error); + if (isl_seq_first_non_zero(bmap->eq[i] + 1 + total + div + 1, + n_div - div - 1) != -1) + continue; + if (isl_mat_row_gcd(A, i, &gcd) < 0) + goto error; + if (isl_int_is_one(gcd)) + continue; + remove_incomplete_powers(&gcd, bmap->eq[i][1 + total + div]); + if (isl_int_is_one(gcd)) + continue; + isl_int_divexact(bmap->eq[i][1 + total + div], + bmap->eq[i][1 + total + div], gcd); + bmap = isl_basic_map_mark_div_unknown(bmap, div); + if (!bmap) + goto error; + any = 1; + } + isl_int_clear(gcd); + + if (any) + bmap = isl_basic_map_gauss(bmap, NULL); + + return bmap; +error: + isl_int_clear(gcd); + isl_basic_map_free(bmap); + return NULL; +} + +/* Simplify the stride constraints in "bmap" based on + * the remaining equality constraints in "bmap" and all equality + * constraints in "context". + * Only do this if both "bmap" and "context" have stride constraints. + * + * First extract a copy of the stride constraints in "bmap" in a compressed + * space exploiting all the other equality constraints and then + * use this compressed copy to simplify the original stride constraints. + */ +static __isl_give isl_basic_map *gist_strides(__isl_take isl_basic_map *bmap, + __isl_keep isl_basic_map *context) +{ + int bmap_n_eq, context_n_eq; + isl_mat *A; + + if (!bmap || !context) + return isl_basic_map_free(bmap); + + bmap_n_eq = n_div_eq(bmap); + context_n_eq = n_div_eq(context); + + if (bmap_n_eq < 0 || context_n_eq < 0) + return isl_basic_map_free(bmap); + if (bmap_n_eq == 0 || context_n_eq == 0) + return bmap; + + A = extract_compressed_stride_constraints(bmap, bmap_n_eq, + context, context_n_eq); + bmap = reduce_stride_constraints(bmap, bmap_n_eq, A); + + isl_mat_free(A); + + return bmap; +} + +/* Return a basic map that has the same intersection with "context" as "bmap" + * and that is as "simple" as possible. + * + * The core computation is performed on the pure constraints. + * When we add back the meaning of the integer divisions, we need + * to (re)introduce the div constraints. If we happen to have + * discovered that some of these integer divisions are equal to + * some affine combination of other variables, then these div + * constraints may end up getting simplified in terms of the equalities, + * resulting in extra inequalities on the other variables that + * may have been removed already or that may not even have been + * part of the input. We try and remove those constraints of + * this form that are most obviously redundant with respect to + * the context. We also remove those div constraints that are + * redundant with respect to the other constraints in the result. + * + * The stride constraints among the equality constraints in "bmap" are + * also simplified with respecting to the other equality constraints + * in "bmap" and with respect to all equality constraints in "context". + */ +__isl_give isl_basic_map *isl_basic_map_gist(__isl_take isl_basic_map *bmap, + __isl_take isl_basic_map *context) +{ + isl_basic_set *bset, *eq; + isl_basic_map *eq_bmap; + isl_size total, n_div, n_div_bmap; + unsigned extra, n_eq, n_ineq; + + if (!bmap || !context) + goto error; + + if (isl_basic_map_plain_is_universe(bmap)) { + isl_basic_map_free(context); + return bmap; + } + if (isl_basic_map_plain_is_empty(context)) { + isl_space *space = isl_basic_map_get_space(bmap); + isl_basic_map_free(bmap); + isl_basic_map_free(context); + return isl_basic_map_universe(space); + } + if (isl_basic_map_plain_is_empty(bmap)) { + isl_basic_map_free(context); + return bmap; + } + + bmap = isl_basic_map_remove_redundancies(bmap); + context = isl_basic_map_remove_redundancies(context); + bmap = isl_basic_map_order_divs(bmap); + context = isl_basic_map_align_divs(context, bmap); + + n_div = isl_basic_map_dim(context, isl_dim_div); + total = isl_basic_map_dim(bmap, isl_dim_all); + n_div_bmap = isl_basic_map_dim(bmap, isl_dim_div); + if (n_div < 0 || total < 0 || n_div_bmap < 0) + goto error; + extra = n_div - n_div_bmap; + + bset = isl_basic_map_underlying_set(isl_basic_map_copy(bmap)); + bset = isl_basic_set_add_dims(bset, isl_dim_set, extra); + bset = uset_gist(bset, + isl_basic_map_underlying_set(isl_basic_map_copy(context))); + bset = isl_basic_set_project_out(bset, isl_dim_set, total, extra); + + if (!bset || bset->n_eq == 0 || n_div == 0 || + isl_basic_set_plain_is_empty(bset)) { + isl_basic_map_free(context); + return isl_basic_map_overlying_set(bset, bmap); + } + + n_eq = bset->n_eq; + n_ineq = bset->n_ineq; + eq = isl_basic_set_copy(bset); + eq = isl_basic_set_cow(eq); + eq = isl_basic_set_free_inequality(eq, n_ineq); + bset = isl_basic_set_free_equality(bset, n_eq); + + eq_bmap = isl_basic_map_overlying_set(eq, isl_basic_map_copy(bmap)); + eq_bmap = gist_strides(eq_bmap, context); + eq_bmap = isl_basic_map_remove_shifted_constraints(eq_bmap, context); + bmap = isl_basic_map_overlying_set(bset, bmap); + bmap = isl_basic_map_intersect(bmap, eq_bmap); + bmap = isl_basic_map_remove_redundancies(bmap); + + return bmap; +error: + isl_basic_map_free(bmap); + isl_basic_map_free(context); + return NULL; +} + +/* + * Assumes context has no implicit divs. + */ +__isl_give isl_map *isl_map_gist_basic_map(__isl_take isl_map *map, + __isl_take isl_basic_map *context) +{ + int i; + + if (!map || !context) + goto error; + + if (isl_basic_map_plain_is_empty(context)) { + isl_space *space = isl_map_get_space(map); + isl_map_free(map); + isl_basic_map_free(context); + return isl_map_universe(space); + } + + context = isl_basic_map_remove_redundancies(context); + map = isl_map_cow(map); + if (isl_map_basic_map_check_equal_space(map, context) < 0) + goto error; + map = isl_map_compute_divs(map); + if (!map) + goto error; + for (i = map->n - 1; i >= 0; --i) { + map->p[i] = isl_basic_map_gist(map->p[i], + isl_basic_map_copy(context)); + if (!map->p[i]) + goto error; + if (isl_basic_map_plain_is_empty(map->p[i])) { + isl_basic_map_free(map->p[i]); + if (i != map->n - 1) + map->p[i] = map->p[map->n - 1]; + map->n--; + } + } + isl_basic_map_free(context); + ISL_F_CLR(map, ISL_MAP_NORMALIZED); + return map; +error: + isl_map_free(map); + isl_basic_map_free(context); + return NULL; +} + +/* Drop all inequalities from "bmap" that also appear in "context". + * "context" is assumed to have only known local variables and + * the initial local variables of "bmap" are assumed to be the same + * as those of "context". + * The constraints of both "bmap" and "context" are assumed + * to have been sorted using isl_basic_map_sort_constraints. + * + * Run through the inequality constraints of "bmap" and "context" + * in sorted order. + * If a constraint of "bmap" involves variables not in "context", + * then it cannot appear in "context". + * If a matching constraint is found, it is removed from "bmap". + */ +static __isl_give isl_basic_map *drop_inequalities( + __isl_take isl_basic_map *bmap, __isl_keep isl_basic_map *context) +{ + int i1, i2; + isl_size total, bmap_total; + unsigned extra; + + total = isl_basic_map_dim(context, isl_dim_all); + bmap_total = isl_basic_map_dim(bmap, isl_dim_all); + if (total < 0 || bmap_total < 0) + return isl_basic_map_free(bmap); + + extra = bmap_total - total; + + i1 = bmap->n_ineq - 1; + i2 = context->n_ineq - 1; + while (bmap && i1 >= 0 && i2 >= 0) { + int cmp; + + if (isl_seq_first_non_zero(bmap->ineq[i1] + 1 + total, + extra) != -1) { + --i1; + continue; + } + cmp = isl_basic_map_constraint_cmp(context, bmap->ineq[i1], + context->ineq[i2]); + if (cmp < 0) { + --i2; + continue; + } + if (cmp > 0) { + --i1; + continue; + } + if (isl_int_eq(bmap->ineq[i1][0], context->ineq[i2][0])) { + bmap = isl_basic_map_cow(bmap); + if (isl_basic_map_drop_inequality(bmap, i1) < 0) + bmap = isl_basic_map_free(bmap); + } + --i1; + --i2; + } + + return bmap; +} + +/* Drop all equalities from "bmap" that also appear in "context". + * "context" is assumed to have only known local variables and + * the initial local variables of "bmap" are assumed to be the same + * as those of "context". + * + * Run through the equality constraints of "bmap" and "context" + * in sorted order. + * If a constraint of "bmap" involves variables not in "context", + * then it cannot appear in "context". + * If a matching constraint is found, it is removed from "bmap". + */ +static __isl_give isl_basic_map *drop_equalities( + __isl_take isl_basic_map *bmap, __isl_keep isl_basic_map *context) +{ + int i1, i2; + isl_size total, bmap_total; + unsigned extra; + + total = isl_basic_map_dim(context, isl_dim_all); + bmap_total = isl_basic_map_dim(bmap, isl_dim_all); + if (total < 0 || bmap_total < 0) + return isl_basic_map_free(bmap); + + extra = bmap_total - total; + + i1 = bmap->n_eq - 1; + i2 = context->n_eq - 1; + + while (bmap && i1 >= 0 && i2 >= 0) { + int last1, last2; + + if (isl_seq_first_non_zero(bmap->eq[i1] + 1 + total, + extra) != -1) + break; + last1 = isl_seq_last_non_zero(bmap->eq[i1] + 1, total); + last2 = isl_seq_last_non_zero(context->eq[i2] + 1, total); + if (last1 > last2) { + --i2; + continue; + } + if (last1 < last2) { + --i1; + continue; + } + if (isl_seq_eq(bmap->eq[i1], context->eq[i2], 1 + total)) { + bmap = isl_basic_map_cow(bmap); + if (isl_basic_map_drop_equality(bmap, i1) < 0) + bmap = isl_basic_map_free(bmap); + } + --i1; + --i2; + } + + return bmap; +} + +/* Remove the constraints in "context" from "bmap". + * "context" is assumed to have explicit representations + * for all local variables. + * + * First align the divs of "bmap" to those of "context" and + * sort the constraints. Then drop all constraints from "bmap" + * that appear in "context". + */ +__isl_give isl_basic_map *isl_basic_map_plain_gist( + __isl_take isl_basic_map *bmap, __isl_take isl_basic_map *context) +{ + isl_bool done, known; + + done = isl_basic_map_plain_is_universe(context); + if (done == isl_bool_false) + done = isl_basic_map_plain_is_universe(bmap); + if (done == isl_bool_false) + done = isl_basic_map_plain_is_empty(context); + if (done == isl_bool_false) + done = isl_basic_map_plain_is_empty(bmap); + if (done < 0) + goto error; + if (done) { + isl_basic_map_free(context); + return bmap; + } + known = isl_basic_map_divs_known(context); + if (known < 0) + goto error; + if (!known) + isl_die(isl_basic_map_get_ctx(bmap), isl_error_invalid, + "context has unknown divs", goto error); + + context = isl_basic_map_order_divs(context); + bmap = isl_basic_map_align_divs(bmap, context); + bmap = isl_basic_map_gauss(bmap, NULL); + bmap = isl_basic_map_sort_constraints(bmap); + context = isl_basic_map_sort_constraints(context); + + bmap = drop_inequalities(bmap, context); + bmap = drop_equalities(bmap, context); + + isl_basic_map_free(context); + bmap = isl_basic_map_finalize(bmap); + return bmap; +error: + isl_basic_map_free(bmap); + isl_basic_map_free(context); + return NULL; +} + +/* Replace "map" by the disjunct at position "pos" and free "context". + */ +static __isl_give isl_map *replace_by_disjunct(__isl_take isl_map *map, + int pos, __isl_take isl_basic_map *context) +{ + isl_basic_map *bmap; + + bmap = isl_basic_map_copy(map->p[pos]); + isl_map_free(map); + isl_basic_map_free(context); + return isl_map_from_basic_map(bmap); +} + +/* Remove the constraints in "context" from "map". + * If any of the disjuncts in the result turns out to be the universe, + * then return this universe. + * "context" is assumed to have explicit representations + * for all local variables. + */ +__isl_give isl_map *isl_map_plain_gist_basic_map(__isl_take isl_map *map, + __isl_take isl_basic_map *context) +{ + int i; + isl_bool univ, known; + + univ = isl_basic_map_plain_is_universe(context); + if (univ < 0) + goto error; + if (univ) { + isl_basic_map_free(context); + return map; + } + known = isl_basic_map_divs_known(context); + if (known < 0) + goto error; + if (!known) + isl_die(isl_map_get_ctx(map), isl_error_invalid, + "context has unknown divs", goto error); + + map = isl_map_cow(map); + if (!map) + goto error; + for (i = 0; i < map->n; ++i) { + map->p[i] = isl_basic_map_plain_gist(map->p[i], + isl_basic_map_copy(context)); + univ = isl_basic_map_plain_is_universe(map->p[i]); + if (univ < 0) + goto error; + if (univ && map->n > 1) + return replace_by_disjunct(map, i, context); + } + + isl_basic_map_free(context); + ISL_F_CLR(map, ISL_MAP_NORMALIZED); + if (map->n > 1) + ISL_F_CLR(map, ISL_MAP_DISJOINT); + return map; +error: + isl_map_free(map); + isl_basic_map_free(context); + return NULL; +} + +/* Remove the constraints in "context" from "set". + * If any of the disjuncts in the result turns out to be the universe, + * then return this universe. + * "context" is assumed to have explicit representations + * for all local variables. + */ +__isl_give isl_set *isl_set_plain_gist_basic_set(__isl_take isl_set *set, + __isl_take isl_basic_set *context) +{ + return set_from_map(isl_map_plain_gist_basic_map(set_to_map(set), + bset_to_bmap(context))); +} + +/* Remove the constraints in "context" from "map". + * If any of the disjuncts in the result turns out to be the universe, + * then return this universe. + * "context" is assumed to consist of a single disjunct and + * to have explicit representations for all local variables. + */ +__isl_give isl_map *isl_map_plain_gist(__isl_take isl_map *map, + __isl_take isl_map *context) +{ + isl_basic_map *hull; + + hull = isl_map_unshifted_simple_hull(context); + return isl_map_plain_gist_basic_map(map, hull); +} + +/* Replace "map" by a universe map in the same space and free "drop". + */ +static __isl_give isl_map *replace_by_universe(__isl_take isl_map *map, + __isl_take isl_map *drop) +{ + isl_map *res; + + res = isl_map_universe(isl_map_get_space(map)); + isl_map_free(map); + isl_map_free(drop); + return res; +} + +/* Return a map that has the same intersection with "context" as "map" + * and that is as "simple" as possible. + * + * If "map" is already the universe, then we cannot make it any simpler. + * Similarly, if "context" is the universe, then we cannot exploit it + * to simplify "map" + * If "map" and "context" are identical to each other, then we can + * return the corresponding universe. + * + * If either "map" or "context" consists of multiple disjuncts, + * then check if "context" happens to be a subset of "map", + * in which case all constraints can be removed. + * In case of multiple disjuncts, the standard procedure + * may not be able to detect that all constraints can be removed. + * + * If none of these cases apply, we have to work a bit harder. + * During this computation, we make use of a single disjunct context, + * so if the original context consists of more than one disjunct + * then we need to approximate the context by a single disjunct set. + * Simply taking the simple hull may drop constraints that are + * only implicitly available in each disjunct. We therefore also + * look for constraints among those defining "map" that are valid + * for the context. These can then be used to simplify away + * the corresponding constraints in "map". + */ +__isl_give isl_map *isl_map_gist(__isl_take isl_map *map, + __isl_take isl_map *context) +{ + int equal; + int is_universe; + isl_size n_disjunct_map, n_disjunct_context; + isl_bool subset; + isl_basic_map *hull; + + is_universe = isl_map_plain_is_universe(map); + if (is_universe >= 0 && !is_universe) + is_universe = isl_map_plain_is_universe(context); + if (is_universe < 0) + goto error; + if (is_universe) { + isl_map_free(context); + return map; + } + + isl_map_align_params_bin(&map, &context); + equal = isl_map_plain_is_equal(map, context); + if (equal < 0) + goto error; + if (equal) + return replace_by_universe(map, context); + + n_disjunct_map = isl_map_n_basic_map(map); + n_disjunct_context = isl_map_n_basic_map(context); + if (n_disjunct_map < 0 || n_disjunct_context < 0) + goto error; + if (n_disjunct_map != 1 || n_disjunct_context != 1) { + subset = isl_map_is_subset(context, map); + if (subset < 0) + goto error; + if (subset) + return replace_by_universe(map, context); + } + + context = isl_map_compute_divs(context); + if (!context) + goto error; + if (n_disjunct_context == 1) { + hull = isl_map_simple_hull(context); + } else { + isl_ctx *ctx; + isl_map_list *list; + + ctx = isl_map_get_ctx(map); + list = isl_map_list_alloc(ctx, 2); + list = isl_map_list_add(list, isl_map_copy(context)); + list = isl_map_list_add(list, isl_map_copy(map)); + hull = isl_map_unshifted_simple_hull_from_map_list(context, + list); + } + return isl_map_gist_basic_map(map, hull); +error: + isl_map_free(map); + isl_map_free(context); + return NULL; +} + +__isl_give isl_basic_set *isl_basic_set_gist(__isl_take isl_basic_set *bset, + __isl_take isl_basic_set *context) +{ + return bset_from_bmap(isl_basic_map_gist(bset_to_bmap(bset), + bset_to_bmap(context))); +} + +__isl_give isl_set *isl_set_gist_basic_set(__isl_take isl_set *set, + __isl_take isl_basic_set *context) +{ + return set_from_map(isl_map_gist_basic_map(set_to_map(set), + bset_to_bmap(context))); +} + +__isl_give isl_set *isl_set_gist_params_basic_set(__isl_take isl_set *set, + __isl_take isl_basic_set *context) +{ + isl_space *space = isl_set_get_space(set); + isl_basic_set *dom_context = isl_basic_set_universe(space); + dom_context = isl_basic_set_intersect_params(dom_context, context); + return isl_set_gist_basic_set(set, dom_context); +} + +__isl_give isl_set *isl_set_gist(__isl_take isl_set *set, + __isl_take isl_set *context) +{ + return set_from_map(isl_map_gist(set_to_map(set), set_to_map(context))); +} + +/* Compute the gist of "bmap" with respect to the constraints "context" + * on the domain. + */ +__isl_give isl_basic_map *isl_basic_map_gist_domain( + __isl_take isl_basic_map *bmap, __isl_take isl_basic_set *context) +{ + isl_space *space = isl_basic_map_get_space(bmap); + isl_basic_map *bmap_context = isl_basic_map_universe(space); + + bmap_context = isl_basic_map_intersect_domain(bmap_context, context); + return isl_basic_map_gist(bmap, bmap_context); +} + +__isl_give isl_map *isl_map_gist_domain(__isl_take isl_map *map, + __isl_take isl_set *context) +{ + isl_map *map_context = isl_map_universe(isl_map_get_space(map)); + map_context = isl_map_intersect_domain(map_context, context); + return isl_map_gist(map, map_context); +} + +__isl_give isl_map *isl_map_gist_range(__isl_take isl_map *map, + __isl_take isl_set *context) +{ + isl_map *map_context = isl_map_universe(isl_map_get_space(map)); + map_context = isl_map_intersect_range(map_context, context); + return isl_map_gist(map, map_context); +} + +__isl_give isl_map *isl_map_gist_params(__isl_take isl_map *map, + __isl_take isl_set *context) +{ + isl_map *map_context = isl_map_universe(isl_map_get_space(map)); + map_context = isl_map_intersect_params(map_context, context); + return isl_map_gist(map, map_context); +} + +__isl_give isl_set *isl_set_gist_params(__isl_take isl_set *set, + __isl_take isl_set *context) +{ + return isl_map_gist_params(set, context); +} + +/* Quick check to see if two basic maps are disjoint. + * In particular, we reduce the equalities and inequalities of + * one basic map in the context of the equalities of the other + * basic map and check if we get a contradiction. + */ +isl_bool isl_basic_map_plain_is_disjoint(__isl_keep isl_basic_map *bmap1, + __isl_keep isl_basic_map *bmap2) +{ + struct isl_vec *v = NULL; + int *elim = NULL; + isl_size total; + int i; + + if (isl_basic_map_check_equal_space(bmap1, bmap2) < 0) + return isl_bool_error; + if (bmap1->n_div || bmap2->n_div) + return isl_bool_false; + if (!bmap1->n_eq && !bmap2->n_eq) + return isl_bool_false; + + total = isl_space_dim(bmap1->dim, isl_dim_all); + if (total < 0) + return isl_bool_error; + if (total == 0) + return isl_bool_false; + v = isl_vec_alloc(bmap1->ctx, 1 + total); + if (!v) + goto error; + elim = isl_alloc_array(bmap1->ctx, int, total); + if (!elim) + goto error; + compute_elimination_index(bmap1, elim, total); + for (i = 0; i < bmap2->n_eq; ++i) { + int reduced; + reduced = reduced_using_equalities(v->block.data, bmap2->eq[i], + bmap1, elim, total); + if (reduced && !isl_int_is_zero(v->block.data[0]) && + isl_seq_first_non_zero(v->block.data + 1, total) == -1) + goto disjoint; + } + for (i = 0; i < bmap2->n_ineq; ++i) { + int reduced; + reduced = reduced_using_equalities(v->block.data, + bmap2->ineq[i], bmap1, elim, total); + if (reduced && isl_int_is_neg(v->block.data[0]) && + isl_seq_first_non_zero(v->block.data + 1, total) == -1) + goto disjoint; + } + compute_elimination_index(bmap2, elim, total); + for (i = 0; i < bmap1->n_ineq; ++i) { + int reduced; + reduced = reduced_using_equalities(v->block.data, + bmap1->ineq[i], bmap2, elim, total); + if (reduced && isl_int_is_neg(v->block.data[0]) && + isl_seq_first_non_zero(v->block.data + 1, total) == -1) + goto disjoint; + } + isl_vec_free(v); + free(elim); + return isl_bool_false; +disjoint: + isl_vec_free(v); + free(elim); + return isl_bool_true; +error: + isl_vec_free(v); + free(elim); + return isl_bool_error; +} + +int isl_basic_set_plain_is_disjoint(__isl_keep isl_basic_set *bset1, + __isl_keep isl_basic_set *bset2) +{ + return isl_basic_map_plain_is_disjoint(bset_to_bmap(bset1), + bset_to_bmap(bset2)); +} + +/* Does "test" hold for all pairs of basic maps in "map1" and "map2"? + */ +static isl_bool all_pairs(__isl_keep isl_map *map1, __isl_keep isl_map *map2, + isl_bool (*test)(__isl_keep isl_basic_map *bmap1, + __isl_keep isl_basic_map *bmap2)) +{ + int i, j; + + if (!map1 || !map2) + return isl_bool_error; + + for (i = 0; i < map1->n; ++i) { + for (j = 0; j < map2->n; ++j) { + isl_bool d = test(map1->p[i], map2->p[j]); + if (d != isl_bool_true) + return d; + } + } + + return isl_bool_true; +} + +/* Are "map1" and "map2" obviously disjoint, based on information + * that can be derived without looking at the individual basic maps? + * + * In particular, if one of them is empty or if they live in different spaces + * (ignoring parameters), then they are clearly disjoint. + */ +static isl_bool isl_map_plain_is_disjoint_global(__isl_keep isl_map *map1, + __isl_keep isl_map *map2) +{ + isl_bool disjoint; + isl_bool match; + + if (!map1 || !map2) + return isl_bool_error; + + disjoint = isl_map_plain_is_empty(map1); + if (disjoint < 0 || disjoint) + return disjoint; + + disjoint = isl_map_plain_is_empty(map2); + if (disjoint < 0 || disjoint) + return disjoint; + + match = isl_map_tuple_is_equal(map1, isl_dim_in, map2, isl_dim_in); + if (match < 0 || !match) + return match < 0 ? isl_bool_error : isl_bool_true; + + match = isl_map_tuple_is_equal(map1, isl_dim_out, map2, isl_dim_out); + if (match < 0 || !match) + return match < 0 ? isl_bool_error : isl_bool_true; + + return isl_bool_false; +} + +/* Are "map1" and "map2" obviously disjoint? + * + * If one of them is empty or if they live in different spaces (ignoring + * parameters), then they are clearly disjoint. + * This is checked by isl_map_plain_is_disjoint_global. + * + * If they have different parameters, then we skip any further tests. + * + * If they are obviously equal, but not obviously empty, then we will + * not be able to detect if they are disjoint. + * + * Otherwise we check if each basic map in "map1" is obviously disjoint + * from each basic map in "map2". + */ +isl_bool isl_map_plain_is_disjoint(__isl_keep isl_map *map1, + __isl_keep isl_map *map2) +{ + isl_bool disjoint; + isl_bool intersect; + isl_bool match; + + disjoint = isl_map_plain_is_disjoint_global(map1, map2); + if (disjoint < 0 || disjoint) + return disjoint; + + match = isl_map_has_equal_params(map1, map2); + if (match < 0 || !match) + return match < 0 ? isl_bool_error : isl_bool_false; + + intersect = isl_map_plain_is_equal(map1, map2); + if (intersect < 0 || intersect) + return intersect < 0 ? isl_bool_error : isl_bool_false; + + return all_pairs(map1, map2, &isl_basic_map_plain_is_disjoint); +} + +/* Are "map1" and "map2" disjoint? + * The parameters are assumed to have been aligned. + * + * In particular, check whether all pairs of basic maps are disjoint. + */ +static isl_bool isl_map_is_disjoint_aligned(__isl_keep isl_map *map1, + __isl_keep isl_map *map2) +{ + return all_pairs(map1, map2, &isl_basic_map_is_disjoint); +} + +/* Are "map1" and "map2" disjoint? + * + * They are disjoint if they are "obviously disjoint" or if one of them + * is empty. Otherwise, they are not disjoint if one of them is universal. + * If the two inputs are (obviously) equal and not empty, then they are + * not disjoint. + * If none of these cases apply, then check if all pairs of basic maps + * are disjoint after aligning the parameters. + */ +isl_bool isl_map_is_disjoint(__isl_keep isl_map *map1, __isl_keep isl_map *map2) +{ + isl_bool disjoint; + isl_bool intersect; + + disjoint = isl_map_plain_is_disjoint_global(map1, map2); + if (disjoint < 0 || disjoint) + return disjoint; + + disjoint = isl_map_is_empty(map1); + if (disjoint < 0 || disjoint) + return disjoint; + + disjoint = isl_map_is_empty(map2); + if (disjoint < 0 || disjoint) + return disjoint; + + intersect = isl_map_plain_is_universe(map1); + if (intersect < 0 || intersect) + return isl_bool_not(intersect); + + intersect = isl_map_plain_is_universe(map2); + if (intersect < 0 || intersect) + return isl_bool_not(intersect); + + intersect = isl_map_plain_is_equal(map1, map2); + if (intersect < 0 || intersect) + return isl_bool_not(intersect); + + return isl_map_align_params_map_map_and_test(map1, map2, + &isl_map_is_disjoint_aligned); +} + +/* Are "bmap1" and "bmap2" disjoint? + * + * They are disjoint if they are "obviously disjoint" or if one of them + * is empty. Otherwise, they are not disjoint if one of them is universal. + * If none of these cases apply, we compute the intersection and see if + * the result is empty. + */ +isl_bool isl_basic_map_is_disjoint(__isl_keep isl_basic_map *bmap1, + __isl_keep isl_basic_map *bmap2) +{ + isl_bool disjoint; + isl_bool intersect; + isl_basic_map *test; + + disjoint = isl_basic_map_plain_is_disjoint(bmap1, bmap2); + if (disjoint < 0 || disjoint) + return disjoint; + + disjoint = isl_basic_map_is_empty(bmap1); + if (disjoint < 0 || disjoint) + return disjoint; + + disjoint = isl_basic_map_is_empty(bmap2); + if (disjoint < 0 || disjoint) + return disjoint; + + intersect = isl_basic_map_plain_is_universe(bmap1); + if (intersect < 0 || intersect) + return isl_bool_not(intersect); + + intersect = isl_basic_map_plain_is_universe(bmap2); + if (intersect < 0 || intersect) + return isl_bool_not(intersect); + + test = isl_basic_map_intersect(isl_basic_map_copy(bmap1), + isl_basic_map_copy(bmap2)); + disjoint = isl_basic_map_is_empty(test); + isl_basic_map_free(test); + + return disjoint; +} + +/* Are "bset1" and "bset2" disjoint? + */ +isl_bool isl_basic_set_is_disjoint(__isl_keep isl_basic_set *bset1, + __isl_keep isl_basic_set *bset2) +{ + return isl_basic_map_is_disjoint(bset1, bset2); +} + +isl_bool isl_set_plain_is_disjoint(__isl_keep isl_set *set1, + __isl_keep isl_set *set2) +{ + return isl_map_plain_is_disjoint(set_to_map(set1), set_to_map(set2)); +} + +/* Are "set1" and "set2" disjoint? + */ +isl_bool isl_set_is_disjoint(__isl_keep isl_set *set1, __isl_keep isl_set *set2) +{ + return isl_map_is_disjoint(set1, set2); +} + +/* Is "v" equal to 0, 1 or -1? + */ +static int is_zero_or_one(isl_int v) +{ + return isl_int_is_zero(v) || isl_int_is_one(v) || isl_int_is_negone(v); +} + +/* Are the "n" coefficients starting at "first" of inequality constraints + * "i" and "j" of "bmap" opposite to each other? + */ +static int is_opposite_part(__isl_keep isl_basic_map *bmap, int i, int j, + int first, int n) +{ + return isl_seq_is_neg(bmap->ineq[i] + first, bmap->ineq[j] + first, n); +} + +/* Are inequality constraints "i" and "j" of "bmap" opposite to each other, + * apart from the constant term? + */ +static isl_bool is_opposite(__isl_keep isl_basic_map *bmap, int i, int j) +{ + isl_size total; + + total = isl_basic_map_dim(bmap, isl_dim_all); + if (total < 0) + return isl_bool_error; + return is_opposite_part(bmap, i, j, 1, total); +} + +/* Check if we can combine a given div with lower bound l and upper + * bound u with some other div and if so return that other div. + * Otherwise, return a position beyond the integer divisions. + * Return -1 on error. + * + * We first check that + * - the bounds are opposites of each other (except for the constant + * term) + * - the bounds do not reference any other div + * - no div is defined in terms of this div + * + * Let m be the size of the range allowed on the div by the bounds. + * That is, the bounds are of the form + * + * e <= a <= e + m - 1 + * + * with e some expression in the other variables. + * We look for another div b such that no third div is defined in terms + * of this second div b and such that in any constraint that contains + * a (except for the given lower and upper bound), also contains b + * with a coefficient that is m times that of b. + * That is, all constraints (except for the lower and upper bound) + * are of the form + * + * e + f (a + m b) >= 0 + * + * Furthermore, in the constraints that only contain b, the coefficient + * of b should be equal to 1 or -1. + * If so, we return b so that "a + m b" can be replaced by + * a single div "c = a + m b". + */ +static int div_find_coalesce(__isl_keep isl_basic_map *bmap, int *pairs, + unsigned div, unsigned l, unsigned u) +{ + int i, j; + unsigned n_div; + isl_size v_div; + int coalesce; + isl_bool opp; + + n_div = isl_basic_map_dim(bmap, isl_dim_div); + if (n_div <= 1) + return n_div; + v_div = isl_basic_map_var_offset(bmap, isl_dim_div); + if (v_div < 0) + return -1; + if (isl_seq_first_non_zero(bmap->ineq[l] + 1 + v_div, div) != -1) + return n_div; + if (isl_seq_first_non_zero(bmap->ineq[l] + 1 + v_div + div + 1, + n_div - div - 1) != -1) + return n_div; + opp = is_opposite(bmap, l, u); + if (opp < 0 || !opp) + return opp < 0 ? -1 : n_div; + + for (i = 0; i < n_div; ++i) { + if (isl_int_is_zero(bmap->div[i][0])) + continue; + if (!isl_int_is_zero(bmap->div[i][1 + 1 + v_div + div])) + return n_div; + } + + isl_int_add(bmap->ineq[l][0], bmap->ineq[l][0], bmap->ineq[u][0]); + if (isl_int_is_neg(bmap->ineq[l][0])) { + isl_int_sub(bmap->ineq[l][0], + bmap->ineq[l][0], bmap->ineq[u][0]); + bmap = isl_basic_map_copy(bmap); + bmap = isl_basic_map_set_to_empty(bmap); + isl_basic_map_free(bmap); + return n_div; + } + isl_int_add_ui(bmap->ineq[l][0], bmap->ineq[l][0], 1); + coalesce = n_div; + for (i = 0; i < n_div; ++i) { + if (i == div) + continue; + if (!pairs[i]) + continue; + for (j = 0; j < n_div; ++j) { + if (isl_int_is_zero(bmap->div[j][0])) + continue; + if (!isl_int_is_zero(bmap->div[j][1 + 1 + v_div + i])) + break; + } + if (j < n_div) + continue; + for (j = 0; j < bmap->n_ineq; ++j) { + int valid; + if (j == l || j == u) + continue; + if (isl_int_is_zero(bmap->ineq[j][1 + v_div + div])) { + if (is_zero_or_one(bmap->ineq[j][1 + v_div + i])) + continue; + break; + } + if (isl_int_is_zero(bmap->ineq[j][1 + v_div + i])) + break; + isl_int_mul(bmap->ineq[j][1 + v_div + div], + bmap->ineq[j][1 + v_div + div], + bmap->ineq[l][0]); + valid = isl_int_eq(bmap->ineq[j][1 + v_div + div], + bmap->ineq[j][1 + v_div + i]); + isl_int_divexact(bmap->ineq[j][1 + v_div + div], + bmap->ineq[j][1 + v_div + div], + bmap->ineq[l][0]); + if (!valid) + break; + } + if (j < bmap->n_ineq) + continue; + coalesce = i; + break; + } + isl_int_sub_ui(bmap->ineq[l][0], bmap->ineq[l][0], 1); + isl_int_sub(bmap->ineq[l][0], bmap->ineq[l][0], bmap->ineq[u][0]); + return coalesce; +} + +/* Internal data structure used during the construction and/or evaluation of + * an inequality that ensures that a pair of bounds always allows + * for an integer value. + * + * "tab" is the tableau in which the inequality is evaluated. It may + * be NULL until it is actually needed. + * "v" contains the inequality coefficients. + * "g", "fl" and "fu" are temporary scalars used during the construction and + * evaluation. + */ +struct test_ineq_data { + struct isl_tab *tab; + isl_vec *v; + isl_int g; + isl_int fl; + isl_int fu; +}; + +/* Free all the memory allocated by the fields of "data". + */ +static void test_ineq_data_clear(struct test_ineq_data *data) +{ + isl_tab_free(data->tab); + isl_vec_free(data->v); + isl_int_clear(data->g); + isl_int_clear(data->fl); + isl_int_clear(data->fu); +} + +/* Is the inequality stored in data->v satisfied by "bmap"? + * That is, does it only attain non-negative values? + * data->tab is a tableau corresponding to "bmap". + */ +static isl_bool test_ineq_is_satisfied(__isl_keep isl_basic_map *bmap, + struct test_ineq_data *data) +{ + isl_ctx *ctx; + enum isl_lp_result res; + + ctx = isl_basic_map_get_ctx(bmap); + if (!data->tab) + data->tab = isl_tab_from_basic_map(bmap, 0); + res = isl_tab_min(data->tab, data->v->el, ctx->one, &data->g, NULL, 0); + if (res == isl_lp_error) + return isl_bool_error; + return res == isl_lp_ok && isl_int_is_nonneg(data->g); +} + +/* Given a lower and an upper bound on div i, do they always allow + * for an integer value of the given div? + * Determine this property by constructing an inequality + * such that the property is guaranteed when the inequality is nonnegative. + * The lower bound is inequality l, while the upper bound is inequality u. + * The constructed inequality is stored in data->v. + * + * Let the upper bound be + * + * -n_u a + e_u >= 0 + * + * and the lower bound + * + * n_l a + e_l >= 0 + * + * Let n_u = f_u g and n_l = f_l g, with g = gcd(n_u, n_l). + * We have + * + * - f_u e_l <= f_u f_l g a <= f_l e_u + * + * Since all variables are integer valued, this is equivalent to + * + * - f_u e_l - (f_u - 1) <= f_u f_l g a <= f_l e_u + (f_l - 1) + * + * If this interval is at least f_u f_l g, then it contains at least + * one integer value for a. + * That is, the test constraint is + * + * f_l e_u + f_u e_l + f_l - 1 + f_u - 1 + 1 >= f_u f_l g + * + * or + * + * f_l e_u + f_u e_l + f_l - 1 + f_u - 1 + 1 - f_u f_l g >= 0 + * + * If the coefficients of f_l e_u + f_u e_l have a common divisor g', + * then the constraint can be scaled down by a factor g', + * with the constant term replaced by + * floor((f_l e_{u,0} + f_u e_{l,0} + f_l - 1 + f_u - 1 + 1 - f_u f_l g)/g'). + * Note that the result of applying Fourier-Motzkin to this pair + * of constraints is + * + * f_l e_u + f_u e_l >= 0 + * + * If the constant term of the scaled down version of this constraint, + * i.e., floor((f_l e_{u,0} + f_u e_{l,0})/g') is equal to the constant + * term of the scaled down test constraint, then the test constraint + * is known to hold and no explicit evaluation is required. + * This is essentially the Omega test. + * + * If the test constraint consists of only a constant term, then + * it is sufficient to look at the sign of this constant term. + */ +static isl_bool int_between_bounds(__isl_keep isl_basic_map *bmap, int i, + int l, int u, struct test_ineq_data *data) +{ + unsigned offset; + isl_size n_div; + + offset = isl_basic_map_offset(bmap, isl_dim_div); + n_div = isl_basic_map_dim(bmap, isl_dim_div); + if (n_div < 0) + return isl_bool_error; + + isl_int_gcd(data->g, + bmap->ineq[l][offset + i], bmap->ineq[u][offset + i]); + isl_int_divexact(data->fl, bmap->ineq[l][offset + i], data->g); + isl_int_divexact(data->fu, bmap->ineq[u][offset + i], data->g); + isl_int_neg(data->fu, data->fu); + isl_seq_combine(data->v->el, data->fl, bmap->ineq[u], + data->fu, bmap->ineq[l], offset + n_div); + isl_int_mul(data->g, data->g, data->fl); + isl_int_mul(data->g, data->g, data->fu); + isl_int_sub(data->g, data->g, data->fl); + isl_int_sub(data->g, data->g, data->fu); + isl_int_add_ui(data->g, data->g, 1); + isl_int_sub(data->fl, data->v->el[0], data->g); + + isl_seq_gcd(data->v->el + 1, offset - 1 + n_div, &data->g); + if (isl_int_is_zero(data->g)) + return isl_int_is_nonneg(data->fl); + if (isl_int_is_one(data->g)) { + isl_int_set(data->v->el[0], data->fl); + return test_ineq_is_satisfied(bmap, data); + } + isl_int_fdiv_q(data->fl, data->fl, data->g); + isl_int_fdiv_q(data->v->el[0], data->v->el[0], data->g); + if (isl_int_eq(data->fl, data->v->el[0])) + return isl_bool_true; + isl_int_set(data->v->el[0], data->fl); + isl_seq_scale_down(data->v->el + 1, data->v->el + 1, data->g, + offset - 1 + n_div); + + return test_ineq_is_satisfied(bmap, data); +} + +/* Remove more kinds of divs that are not strictly needed. + * In particular, if all pairs of lower and upper bounds on a div + * are such that they allow at least one integer value of the div, + * then we can eliminate the div using Fourier-Motzkin without + * introducing any spurious solutions. + * + * If at least one of the two constraints has a unit coefficient for the div, + * then the presence of such a value is guaranteed so there is no need to check. + * In particular, the value attained by the bound with unit coefficient + * can serve as this intermediate value. + */ +static __isl_give isl_basic_map *drop_more_redundant_divs( + __isl_take isl_basic_map *bmap, __isl_take int *pairs, int n) +{ + isl_ctx *ctx; + struct test_ineq_data data = { NULL, NULL }; + unsigned off; + isl_size n_div; + int remove = -1; + + isl_int_init(data.g); + isl_int_init(data.fl); + isl_int_init(data.fu); + + n_div = isl_basic_map_dim(bmap, isl_dim_div); + if (n_div < 0) + goto error; + + ctx = isl_basic_map_get_ctx(bmap); + off = isl_basic_map_offset(bmap, isl_dim_div); + data.v = isl_vec_alloc(ctx, off + n_div); + if (!data.v) + goto error; + + while (n > 0) { + int i, l, u; + int best = -1; + isl_bool has_int; + + for (i = 0; i < n_div; ++i) { + if (!pairs[i]) + continue; + if (best >= 0 && pairs[best] <= pairs[i]) + continue; + best = i; + } + + i = best; + for (l = 0; l < bmap->n_ineq; ++l) { + if (!isl_int_is_pos(bmap->ineq[l][off + i])) + continue; + if (isl_int_is_one(bmap->ineq[l][off + i])) + continue; + for (u = 0; u < bmap->n_ineq; ++u) { + if (!isl_int_is_neg(bmap->ineq[u][off + i])) + continue; + if (isl_int_is_negone(bmap->ineq[u][off + i])) + continue; + has_int = int_between_bounds(bmap, i, l, u, + &data); + if (has_int < 0) + goto error; + if (data.tab && data.tab->empty) + break; + if (!has_int) + break; + } + if (u < bmap->n_ineq) + break; + } + if (data.tab && data.tab->empty) { + bmap = isl_basic_map_set_to_empty(bmap); + break; + } + if (l == bmap->n_ineq) { + remove = i; + break; + } + pairs[i] = 0; + --n; + } + + test_ineq_data_clear(&data); + + free(pairs); + + if (remove < 0) + return bmap; + + bmap = isl_basic_map_remove_dims(bmap, isl_dim_div, remove, 1); + return isl_basic_map_drop_redundant_divs(bmap); +error: + free(pairs); + isl_basic_map_free(bmap); + test_ineq_data_clear(&data); + return NULL; +} + +/* Given a pair of divs div1 and div2 such that, except for the lower bound l + * and the upper bound u, div1 always occurs together with div2 in the form + * (div1 + m div2), where m is the constant range on the variable div1 + * allowed by l and u, replace the pair div1 and div2 by a single + * div that is equal to div1 + m div2. + * + * The new div will appear in the location that contains div2. + * We need to modify all constraints that contain + * div2 = (div - div1) / m + * The coefficient of div2 is known to be equal to 1 or -1. + * (If a constraint does not contain div2, it will also not contain div1.) + * If the constraint also contains div1, then we know they appear + * as f (div1 + m div2) and we can simply replace (div1 + m div2) by div, + * i.e., the coefficient of div is f. + * + * Otherwise, we first need to introduce div1 into the constraint. + * Let l be + * + * div1 + f >=0 + * + * and u + * + * -div1 + f' >= 0 + * + * A lower bound on div2 + * + * div2 + t >= 0 + * + * can be replaced by + * + * m div2 + div1 + m t + f >= 0 + * + * An upper bound + * + * -div2 + t >= 0 + * + * can be replaced by + * + * -(m div2 + div1) + m t + f' >= 0 + * + * These constraint are those that we would obtain from eliminating + * div1 using Fourier-Motzkin. + * + * After all constraints have been modified, we drop the lower and upper + * bound and then drop div1. + * Since the new div is only placed in the same location that used + * to store div2, but otherwise has a different meaning, any possible + * explicit representation of the original div2 is removed. + */ +static __isl_give isl_basic_map *coalesce_divs(__isl_take isl_basic_map *bmap, + unsigned div1, unsigned div2, unsigned l, unsigned u) +{ + isl_ctx *ctx; + isl_int m; + isl_size v_div; + unsigned total; + int i; + + ctx = isl_basic_map_get_ctx(bmap); + + v_div = isl_basic_map_var_offset(bmap, isl_dim_div); + if (v_div < 0) + return isl_basic_map_free(bmap); + total = 1 + v_div + bmap->n_div; + + isl_int_init(m); + isl_int_add(m, bmap->ineq[l][0], bmap->ineq[u][0]); + isl_int_add_ui(m, m, 1); + + for (i = 0; i < bmap->n_ineq; ++i) { + if (i == l || i == u) + continue; + if (isl_int_is_zero(bmap->ineq[i][1 + v_div + div2])) + continue; + if (isl_int_is_zero(bmap->ineq[i][1 + v_div + div1])) { + if (isl_int_is_pos(bmap->ineq[i][1 + v_div + div2])) + isl_seq_combine(bmap->ineq[i], m, bmap->ineq[i], + ctx->one, bmap->ineq[l], total); + else + isl_seq_combine(bmap->ineq[i], m, bmap->ineq[i], + ctx->one, bmap->ineq[u], total); + } + isl_int_set(bmap->ineq[i][1 + v_div + div2], + bmap->ineq[i][1 + v_div + div1]); + isl_int_set_si(bmap->ineq[i][1 + v_div + div1], 0); + } + + isl_int_clear(m); + if (l > u) { + isl_basic_map_drop_inequality(bmap, l); + isl_basic_map_drop_inequality(bmap, u); + } else { + isl_basic_map_drop_inequality(bmap, u); + isl_basic_map_drop_inequality(bmap, l); + } + bmap = isl_basic_map_mark_div_unknown(bmap, div2); + bmap = isl_basic_map_drop_div(bmap, div1); + return bmap; +} + +/* First check if we can coalesce any pair of divs and + * then continue with dropping more redundant divs. + * + * We loop over all pairs of lower and upper bounds on a div + * with coefficient 1 and -1, respectively, check if there + * is any other div "c" with which we can coalesce the div + * and if so, perform the coalescing. + */ +static __isl_give isl_basic_map *coalesce_or_drop_more_redundant_divs( + __isl_take isl_basic_map *bmap, int *pairs, int n) +{ + int i, l, u; + isl_size v_div; + isl_size n_div; + + v_div = isl_basic_map_var_offset(bmap, isl_dim_div); + n_div = isl_basic_map_dim(bmap, isl_dim_div); + if (v_div < 0 || n_div < 0) + return isl_basic_map_free(bmap); + + for (i = 0; i < n_div; ++i) { + if (!pairs[i]) + continue; + for (l = 0; l < bmap->n_ineq; ++l) { + if (!isl_int_is_one(bmap->ineq[l][1 + v_div + i])) + continue; + for (u = 0; u < bmap->n_ineq; ++u) { + int c; + + if (!isl_int_is_negone(bmap->ineq[u][1+v_div+i])) + continue; + c = div_find_coalesce(bmap, pairs, i, l, u); + if (c < 0) + goto error; + if (c >= n_div) + continue; + free(pairs); + bmap = coalesce_divs(bmap, i, c, l, u); + return isl_basic_map_drop_redundant_divs(bmap); + } + } + } + + if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_EMPTY)) { + free(pairs); + return bmap; + } + + return drop_more_redundant_divs(bmap, pairs, n); +error: + free(pairs); + isl_basic_map_free(bmap); + return NULL; +} + +/* Are the "n" coefficients starting at "first" of inequality constraints + * "i" and "j" of "bmap" equal to each other? + */ +static int is_parallel_part(__isl_keep isl_basic_map *bmap, int i, int j, + int first, int n) +{ + return isl_seq_eq(bmap->ineq[i] + first, bmap->ineq[j] + first, n); +} + +/* Are inequality constraints "i" and "j" of "bmap" equal to each other, + * apart from the constant term and the coefficient at position "pos"? + */ +static isl_bool is_parallel_except(__isl_keep isl_basic_map *bmap, int i, int j, + int pos) +{ + isl_size total; + + total = isl_basic_map_dim(bmap, isl_dim_all); + if (total < 0) + return isl_bool_error; + return is_parallel_part(bmap, i, j, 1, pos - 1) && + is_parallel_part(bmap, i, j, pos + 1, total - pos); +} + +/* Are inequality constraints "i" and "j" of "bmap" opposite to each other, + * apart from the constant term and the coefficient at position "pos"? + */ +static isl_bool is_opposite_except(__isl_keep isl_basic_map *bmap, int i, int j, + int pos) +{ + isl_size total; + + total = isl_basic_map_dim(bmap, isl_dim_all); + if (total < 0) + return isl_bool_error; + return is_opposite_part(bmap, i, j, 1, pos - 1) && + is_opposite_part(bmap, i, j, pos + 1, total - pos); +} + +/* Restart isl_basic_map_drop_redundant_divs after "bmap" has + * been modified, simplying it if "simplify" is set. + * Free the temporary data structure "pairs" that was associated + * to the old version of "bmap". + */ +static __isl_give isl_basic_map *drop_redundant_divs_again( + __isl_take isl_basic_map *bmap, __isl_take int *pairs, int simplify) +{ + if (simplify) + bmap = isl_basic_map_simplify(bmap); + free(pairs); + return isl_basic_map_drop_redundant_divs(bmap); +} + +/* Is "div" the single unknown existentially quantified variable + * in inequality constraint "ineq" of "bmap"? + * "div" is known to have a non-zero coefficient in "ineq". + */ +static isl_bool single_unknown(__isl_keep isl_basic_map *bmap, int ineq, + int div) +{ + int i; + isl_size n_div; + unsigned o_div; + isl_bool known; + + known = isl_basic_map_div_is_known(bmap, div); + if (known < 0 || known) + return isl_bool_not(known); + n_div = isl_basic_map_dim(bmap, isl_dim_div); + if (n_div < 0) + return isl_bool_error; + if (n_div == 1) + return isl_bool_true; + o_div = isl_basic_map_offset(bmap, isl_dim_div); + for (i = 0; i < n_div; ++i) { + isl_bool known; + + if (i == div) + continue; + if (isl_int_is_zero(bmap->ineq[ineq][o_div + i])) + continue; + known = isl_basic_map_div_is_known(bmap, i); + if (known < 0 || !known) + return known; + } + + return isl_bool_true; +} + +/* Does integer division "div" have coefficient 1 in inequality constraint + * "ineq" of "map"? + */ +static isl_bool has_coef_one(__isl_keep isl_basic_map *bmap, int div, int ineq) +{ + unsigned o_div; + + o_div = isl_basic_map_offset(bmap, isl_dim_div); + if (isl_int_is_one(bmap->ineq[ineq][o_div + div])) + return isl_bool_true; + + return isl_bool_false; +} + +/* Turn inequality constraint "ineq" of "bmap" into an equality and + * then try and drop redundant divs again, + * freeing the temporary data structure "pairs" that was associated + * to the old version of "bmap". + */ +static __isl_give isl_basic_map *set_eq_and_try_again( + __isl_take isl_basic_map *bmap, int ineq, __isl_take int *pairs) +{ + bmap = isl_basic_map_cow(bmap); + isl_basic_map_inequality_to_equality(bmap, ineq); + return drop_redundant_divs_again(bmap, pairs, 1); +} + +/* Drop the integer division at position "div", along with the two + * inequality constraints "ineq1" and "ineq2" in which it appears + * from "bmap" and then try and drop redundant divs again, + * freeing the temporary data structure "pairs" that was associated + * to the old version of "bmap". + */ +static __isl_give isl_basic_map *drop_div_and_try_again( + __isl_take isl_basic_map *bmap, int div, int ineq1, int ineq2, + __isl_take int *pairs) +{ + if (ineq1 > ineq2) { + isl_basic_map_drop_inequality(bmap, ineq1); + isl_basic_map_drop_inequality(bmap, ineq2); + } else { + isl_basic_map_drop_inequality(bmap, ineq2); + isl_basic_map_drop_inequality(bmap, ineq1); + } + bmap = isl_basic_map_drop_div(bmap, div); + return drop_redundant_divs_again(bmap, pairs, 0); +} + +/* Given two inequality constraints + * + * f(x) + n d + c >= 0, (ineq) + * + * with d the variable at position "pos", and + * + * f(x) + c0 >= 0, (lower) + * + * compute the maximal value of the lower bound ceil((-f(x) - c)/n) + * determined by the first constraint. + * That is, store + * + * ceil((c0 - c)/n) + * + * in *l. + */ +static void lower_bound_from_parallel(__isl_keep isl_basic_map *bmap, + int ineq, int lower, int pos, isl_int *l) +{ + isl_int_neg(*l, bmap->ineq[ineq][0]); + isl_int_add(*l, *l, bmap->ineq[lower][0]); + isl_int_cdiv_q(*l, *l, bmap->ineq[ineq][pos]); +} + +/* Given two inequality constraints + * + * f(x) + n d + c >= 0, (ineq) + * + * with d the variable at position "pos", and + * + * -f(x) - c0 >= 0, (upper) + * + * compute the minimal value of the lower bound ceil((-f(x) - c)/n) + * determined by the first constraint. + * That is, store + * + * ceil((-c1 - c)/n) + * + * in *u. + */ +static void lower_bound_from_opposite(__isl_keep isl_basic_map *bmap, + int ineq, int upper, int pos, isl_int *u) +{ + isl_int_neg(*u, bmap->ineq[ineq][0]); + isl_int_sub(*u, *u, bmap->ineq[upper][0]); + isl_int_cdiv_q(*u, *u, bmap->ineq[ineq][pos]); +} + +/* Given a lower bound constraint "ineq" on "div" in "bmap", + * does the corresponding lower bound have a fixed value in "bmap"? + * + * In particular, "ineq" is of the form + * + * f(x) + n d + c >= 0 + * + * with n > 0, c the constant term and + * d the existentially quantified variable "div". + * That is, the lower bound is + * + * ceil((-f(x) - c)/n) + * + * Look for a pair of constraints + * + * f(x) + c0 >= 0 + * -f(x) + c1 >= 0 + * + * i.e., -c1 <= -f(x) <= c0, that fix ceil((-f(x) - c)/n) to a constant value. + * That is, check that + * + * ceil((-c1 - c)/n) = ceil((c0 - c)/n) + * + * If so, return the index of inequality f(x) + c0 >= 0. + * Otherwise, return bmap->n_ineq. + * Return -1 on error. + */ +static int lower_bound_is_cst(__isl_keep isl_basic_map *bmap, int div, int ineq) +{ + int i; + int lower = -1, upper = -1; + unsigned o_div; + isl_int l, u; + int equal; + + o_div = isl_basic_map_offset(bmap, isl_dim_div); + for (i = 0; i < bmap->n_ineq && (lower < 0 || upper < 0); ++i) { + isl_bool par, opp; + + if (i == ineq) + continue; + if (!isl_int_is_zero(bmap->ineq[i][o_div + div])) + continue; + par = isl_bool_false; + if (lower < 0) + par = is_parallel_except(bmap, ineq, i, o_div + div); + if (par < 0) + return -1; + if (par) { + lower = i; + continue; + } + opp = isl_bool_false; + if (upper < 0) + opp = is_opposite_except(bmap, ineq, i, o_div + div); + if (opp < 0) + return -1; + if (opp) + upper = i; + } + + if (lower < 0 || upper < 0) + return bmap->n_ineq; + + isl_int_init(l); + isl_int_init(u); + + lower_bound_from_parallel(bmap, ineq, lower, o_div + div, &l); + lower_bound_from_opposite(bmap, ineq, upper, o_div + div, &u); + + equal = isl_int_eq(l, u); + + isl_int_clear(l); + isl_int_clear(u); + + return equal ? lower : bmap->n_ineq; +} + +/* Given a lower bound constraint "ineq" on the existentially quantified + * variable "div", such that the corresponding lower bound has + * a fixed value in "bmap", assign this fixed value to the variable and + * then try and drop redundant divs again, + * freeing the temporary data structure "pairs" that was associated + * to the old version of "bmap". + * "lower" determines the constant value for the lower bound. + * + * In particular, "ineq" is of the form + * + * f(x) + n d + c >= 0, + * + * while "lower" is of the form + * + * f(x) + c0 >= 0 + * + * The lower bound is ceil((-f(x) - c)/n) and its constant value + * is ceil((c0 - c)/n). + */ +static __isl_give isl_basic_map *fix_cst_lower(__isl_take isl_basic_map *bmap, + int div, int ineq, int lower, int *pairs) +{ + isl_int c; + unsigned o_div; + + isl_int_init(c); + + o_div = isl_basic_map_offset(bmap, isl_dim_div); + lower_bound_from_parallel(bmap, ineq, lower, o_div + div, &c); + bmap = isl_basic_map_fix(bmap, isl_dim_div, div, c); + free(pairs); + + isl_int_clear(c); + + return isl_basic_map_drop_redundant_divs(bmap); +} + +/* Do any of the integer divisions of "bmap" involve integer division "div"? + * + * The integer division "div" could only ever appear in any later + * integer division (with an explicit representation). + */ +static isl_bool any_div_involves_div(__isl_keep isl_basic_map *bmap, int div) +{ + int i; + isl_size v_div, n_div; + + v_div = isl_basic_map_var_offset(bmap, isl_dim_div); + n_div = isl_basic_map_dim(bmap, isl_dim_div); + if (v_div < 0 || n_div < 0) + return isl_bool_error; + + for (i = div + 1; i < n_div; ++i) { + isl_bool unknown; + + unknown = isl_basic_map_div_is_marked_unknown(bmap, i); + if (unknown < 0) + return isl_bool_error; + if (unknown) + continue; + if (!isl_int_is_zero(bmap->div[i][1 + 1 + v_div + div])) + return isl_bool_true; + } + + return isl_bool_false; +} + +/* Remove divs that are not strictly needed based on the inequality + * constraints. + * In particular, if a div only occurs positively (or negatively) + * in constraints, then it can simply be dropped. + * Also, if a div occurs in only two constraints and if moreover + * those two constraints are opposite to each other, except for the constant + * term and if the sum of the constant terms is such that for any value + * of the other values, there is always at least one integer value of the + * div, i.e., if one plus this sum is greater than or equal to + * the (absolute value) of the coefficient of the div in the constraints, + * then we can also simply drop the div. + * + * If an existentially quantified variable does not have an explicit + * representation, appears in only a single lower bound that does not + * involve any other such existentially quantified variables and appears + * in this lower bound with coefficient 1, + * then fix the variable to the value of the lower bound. That is, + * turn the inequality into an equality. + * If for any value of the other variables, there is any value + * for the existentially quantified variable satisfying the constraints, + * then this lower bound also satisfies the constraints. + * It is therefore safe to pick this lower bound. + * + * The same reasoning holds even if the coefficient is not one. + * However, fixing the variable to the value of the lower bound may + * in general introduce an extra integer division, in which case + * it may be better to pick another value. + * If this integer division has a known constant value, then plugging + * in this constant value removes the existentially quantified variable + * completely. In particular, if the lower bound is of the form + * ceil((-f(x) - c)/n) and there are two constraints, f(x) + c0 >= 0 and + * -f(x) + c1 >= 0 such that ceil((-c1 - c)/n) = ceil((c0 - c)/n), + * then the existentially quantified variable can be assigned this + * shared value. + * + * We skip divs that appear in equalities or in the definition of other divs. + * Divs that appear in the definition of other divs usually occur in at least + * 4 constraints, but the constraints may have been simplified. + * + * If any divs are left after these simple checks then we move on + * to more complicated cases in drop_more_redundant_divs. + */ +static __isl_give isl_basic_map *isl_basic_map_drop_redundant_divs_ineq( + __isl_take isl_basic_map *bmap) +{ + int i, j; + isl_size off; + int *pairs = NULL; + int n = 0; + isl_size n_ineq; + + if (!bmap) + goto error; + if (bmap->n_div == 0) + return bmap; + + off = isl_basic_map_var_offset(bmap, isl_dim_div); + if (off < 0) + return isl_basic_map_free(bmap); + pairs = isl_calloc_array(bmap->ctx, int, bmap->n_div); + if (!pairs) + goto error; + + n_ineq = isl_basic_map_n_inequality(bmap); + if (n_ineq < 0) + goto error; + for (i = 0; i < bmap->n_div; ++i) { + int pos, neg; + int last_pos, last_neg; + int redundant; + int defined; + isl_bool involves, opp, set_div; + + defined = !isl_int_is_zero(bmap->div[i][0]); + involves = any_div_involves_div(bmap, i); + if (involves < 0) + goto error; + if (involves) + continue; + for (j = 0; j < bmap->n_eq; ++j) + if (!isl_int_is_zero(bmap->eq[j][1 + off + i])) + break; + if (j < bmap->n_eq) + continue; + ++n; + pos = neg = 0; + for (j = 0; j < bmap->n_ineq; ++j) { + if (isl_int_is_pos(bmap->ineq[j][1 + off + i])) { + last_pos = j; + ++pos; + } + if (isl_int_is_neg(bmap->ineq[j][1 + off + i])) { + last_neg = j; + ++neg; + } + } + pairs[i] = pos * neg; + if (pairs[i] == 0) { + for (j = bmap->n_ineq - 1; j >= 0; --j) + if (!isl_int_is_zero(bmap->ineq[j][1+off+i])) + isl_basic_map_drop_inequality(bmap, j); + bmap = isl_basic_map_drop_div(bmap, i); + return drop_redundant_divs_again(bmap, pairs, 0); + } + if (pairs[i] != 1) + opp = isl_bool_false; + else + opp = is_opposite(bmap, last_pos, last_neg); + if (opp < 0) + goto error; + if (!opp) { + int lower; + isl_bool single, one; + + if (pos != 1) + continue; + single = single_unknown(bmap, last_pos, i); + if (single < 0) + goto error; + if (!single) + continue; + one = has_coef_one(bmap, i, last_pos); + if (one < 0) + goto error; + if (one) + return set_eq_and_try_again(bmap, last_pos, + pairs); + lower = lower_bound_is_cst(bmap, i, last_pos); + if (lower < 0) + goto error; + if (lower < n_ineq) + return fix_cst_lower(bmap, i, last_pos, lower, + pairs); + continue; + } + + isl_int_add(bmap->ineq[last_pos][0], + bmap->ineq[last_pos][0], bmap->ineq[last_neg][0]); + isl_int_add_ui(bmap->ineq[last_pos][0], + bmap->ineq[last_pos][0], 1); + redundant = isl_int_ge(bmap->ineq[last_pos][0], + bmap->ineq[last_pos][1+off+i]); + isl_int_sub_ui(bmap->ineq[last_pos][0], + bmap->ineq[last_pos][0], 1); + isl_int_sub(bmap->ineq[last_pos][0], + bmap->ineq[last_pos][0], bmap->ineq[last_neg][0]); + if (redundant) + return drop_div_and_try_again(bmap, i, + last_pos, last_neg, pairs); + if (defined) + set_div = isl_bool_false; + else + set_div = ok_to_set_div_from_bound(bmap, i, last_pos); + if (set_div < 0) + return isl_basic_map_free(bmap); + if (set_div) { + bmap = set_div_from_lower_bound(bmap, i, last_pos); + return drop_redundant_divs_again(bmap, pairs, 1); + } + pairs[i] = 0; + --n; + } + + if (n > 0) + return coalesce_or_drop_more_redundant_divs(bmap, pairs, n); + + free(pairs); + return bmap; +error: + free(pairs); + isl_basic_map_free(bmap); + return NULL; +} + +/* Consider the coefficients at "c" as a row vector and replace + * them with their product with "T". "T" is assumed to be a square matrix. + */ +static isl_stat preimage(isl_int *c, __isl_keep isl_mat *T) +{ + isl_size n; + isl_ctx *ctx; + isl_vec *v; + + n = isl_mat_rows(T); + if (n < 0) + return isl_stat_error; + if (isl_seq_first_non_zero(c, n) == -1) + return isl_stat_ok; + ctx = isl_mat_get_ctx(T); + v = isl_vec_alloc(ctx, n); + if (!v) + return isl_stat_error; + isl_seq_swp_or_cpy(v->el, c, n); + v = isl_vec_mat_product(v, isl_mat_copy(T)); + if (!v) + return isl_stat_error; + isl_seq_swp_or_cpy(c, v->el, n); + isl_vec_free(v); + + return isl_stat_ok; +} + +/* Plug in T for the variables in "bmap" starting at "pos". + * T is a linear unimodular matrix, i.e., without constant term. + */ +static __isl_give isl_basic_map *isl_basic_map_preimage_vars( + __isl_take isl_basic_map *bmap, unsigned pos, __isl_take isl_mat *T) +{ + int i; + isl_size n_row, n_col; + + bmap = isl_basic_map_cow(bmap); + n_row = isl_mat_rows(T); + n_col = isl_mat_cols(T); + if (!bmap || n_row < 0 || n_col < 0) + goto error; + + if (n_col != n_row) + isl_die(isl_mat_get_ctx(T), isl_error_invalid, + "expecting square matrix", goto error); + + if (isl_basic_map_check_range(bmap, isl_dim_all, pos, n_col) < 0) + goto error; + + for (i = 0; i < bmap->n_eq; ++i) + if (preimage(bmap->eq[i] + 1 + pos, T) < 0) + goto error; + for (i = 0; i < bmap->n_ineq; ++i) + if (preimage(bmap->ineq[i] + 1 + pos, T) < 0) + goto error; + for (i = 0; i < bmap->n_div; ++i) { + if (isl_basic_map_div_is_marked_unknown(bmap, i)) + continue; + if (preimage(bmap->div[i] + 1 + 1 + pos, T) < 0) + goto error; + } + + isl_mat_free(T); + return bmap; +error: + isl_basic_map_free(bmap); + isl_mat_free(T); + return NULL; +} + +/* Remove divs that are not strictly needed. + * + * First look for an equality constraint involving two or more + * existentially quantified variables without an explicit + * representation. Replace the combination that appears + * in the equality constraint by a single existentially quantified + * variable such that the equality can be used to derive + * an explicit representation for the variable. + * If there are no more such equality constraints, then continue + * with isl_basic_map_drop_redundant_divs_ineq. + * + * In particular, if the equality constraint is of the form + * + * f(x) + \sum_i c_i a_i = 0 + * + * with a_i existentially quantified variable without explicit + * representation, then apply a transformation on the existentially + * quantified variables to turn the constraint into + * + * f(x) + g a_1' = 0 + * + * with g the gcd of the c_i. + * In order to easily identify which existentially quantified variables + * have a complete explicit representation, i.e., without being defined + * in terms of other existentially quantified variables without + * an explicit representation, the existentially quantified variables + * are first sorted. + * + * The variable transformation is computed by extending the row + * [c_1/g ... c_n/g] to a unimodular matrix, obtaining the transformation + * + * [a_1'] [c_1/g ... c_n/g] [ a_1 ] + * [a_2'] [ a_2 ] + * ... = U .... + * [a_n'] [ a_n ] + * + * with [c_1/g ... c_n/g] representing the first row of U. + * The inverse of U is then plugged into the original constraints. + * The call to isl_basic_map_simplify makes sure the explicit + * representation for a_1' is extracted from the equality constraint. + */ +__isl_give isl_basic_map *isl_basic_map_drop_redundant_divs( + __isl_take isl_basic_map *bmap) +{ + int first; + int i; + unsigned o_div; + isl_size n_div; + int l; + isl_ctx *ctx; + isl_mat *T; + + if (!bmap) + return NULL; + if (isl_basic_map_divs_known(bmap)) + return isl_basic_map_drop_redundant_divs_ineq(bmap); + if (bmap->n_eq == 0) + return isl_basic_map_drop_redundant_divs_ineq(bmap); + bmap = isl_basic_map_sort_divs(bmap); + if (!bmap) + return NULL; + + first = isl_basic_map_first_unknown_div(bmap); + if (first < 0) + return isl_basic_map_free(bmap); + + o_div = isl_basic_map_offset(bmap, isl_dim_div); + n_div = isl_basic_map_dim(bmap, isl_dim_div); + if (n_div < 0) + return isl_basic_map_free(bmap); + + for (i = 0; i < bmap->n_eq; ++i) { + l = isl_seq_first_non_zero(bmap->eq[i] + o_div + first, + n_div - (first)); + if (l < 0) + continue; + l += first; + if (isl_seq_first_non_zero(bmap->eq[i] + o_div + l + 1, + n_div - (l + 1)) == -1) + continue; + break; + } + if (i >= bmap->n_eq) + return isl_basic_map_drop_redundant_divs_ineq(bmap); + + ctx = isl_basic_map_get_ctx(bmap); + T = isl_mat_alloc(ctx, n_div - l, n_div - l); + if (!T) + return isl_basic_map_free(bmap); + isl_seq_cpy(T->row[0], bmap->eq[i] + o_div + l, n_div - l); + T = isl_mat_normalize_row(T, 0); + T = isl_mat_unimodular_complete(T, 1); + T = isl_mat_right_inverse(T); + + for (i = l; i < n_div; ++i) + bmap = isl_basic_map_mark_div_unknown(bmap, i); + bmap = isl_basic_map_preimage_vars(bmap, o_div - 1 + l, T); + bmap = isl_basic_map_simplify(bmap); + + return isl_basic_map_drop_redundant_divs(bmap); +} + +/* Does "bmap" satisfy any equality that involves more than 2 variables + * and/or has coefficients different from -1 and 1? + */ +static isl_bool has_multiple_var_equality(__isl_keep isl_basic_map *bmap) +{ + int i; + isl_size total; + + total = isl_basic_map_dim(bmap, isl_dim_all); + if (total < 0) + return isl_bool_error; + + for (i = 0; i < bmap->n_eq; ++i) { + int j, k; + + j = isl_seq_first_non_zero(bmap->eq[i] + 1, total); + if (j < 0) + continue; + if (!isl_int_is_one(bmap->eq[i][1 + j]) && + !isl_int_is_negone(bmap->eq[i][1 + j])) + return isl_bool_true; + + j += 1; + k = isl_seq_first_non_zero(bmap->eq[i] + 1 + j, total - j); + if (k < 0) + continue; + j += k; + if (!isl_int_is_one(bmap->eq[i][1 + j]) && + !isl_int_is_negone(bmap->eq[i][1 + j])) + return isl_bool_true; + + j += 1; + k = isl_seq_first_non_zero(bmap->eq[i] + 1 + j, total - j); + if (k >= 0) + return isl_bool_true; + } + + return isl_bool_false; +} + +/* Remove any common factor g from the constraint coefficients in "v". + * The constant term is stored in the first position and is replaced + * by floor(c/g). If any common factor is removed and if this results + * in a tightening of the constraint, then set *tightened. + */ +static __isl_give isl_vec *normalize_constraint(__isl_take isl_vec *v, + int *tightened) +{ + isl_ctx *ctx; + + if (!v) + return NULL; + ctx = isl_vec_get_ctx(v); + isl_seq_gcd(v->el + 1, v->size - 1, &ctx->normalize_gcd); + if (isl_int_is_zero(ctx->normalize_gcd)) + return v; + if (isl_int_is_one(ctx->normalize_gcd)) + return v; + v = isl_vec_cow(v); + if (!v) + return NULL; + if (tightened && !isl_int_is_divisible_by(v->el[0], ctx->normalize_gcd)) + *tightened = 1; + isl_int_fdiv_q(v->el[0], v->el[0], ctx->normalize_gcd); + isl_seq_scale_down(v->el + 1, v->el + 1, ctx->normalize_gcd, + v->size - 1); + return v; +} + +/* If "bmap" is an integer set that satisfies any equality involving + * more than 2 variables and/or has coefficients different from -1 and 1, + * then use variable compression to reduce the coefficients by removing + * any (hidden) common factor. + * In particular, apply the variable compression to each constraint, + * factor out any common factor in the non-constant coefficients and + * then apply the inverse of the compression. + * At the end, we mark the basic map as having reduced constants. + * If this flag is still set on the next invocation of this function, + * then we skip the computation. + * + * Removing a common factor may result in a tightening of some of + * the constraints. If this happens, then we may end up with two + * opposite inequalities that can be replaced by an equality. + * We therefore call isl_basic_map_detect_inequality_pairs, + * which checks for such pairs of inequalities as well as eliminate_divs_eq + * and isl_basic_map_gauss if such a pair was found. + * + * Tightening may also result in some other constraints becoming + * (rationally) redundant with respect to the tightened constraint + * (in combination with other constraints). The basic map may + * therefore no longer be assumed to have no redundant constraints. + * + * Note that this function may leave the result in an inconsistent state. + * In particular, the constraints may not be gaussed. + * Unfortunately, isl_map_coalesce actually depends on this inconsistent state + * for some of the test cases to pass successfully. + * Any potential modification of the representation is therefore only + * performed on a single copy of the basic map. + */ +__isl_give isl_basic_map *isl_basic_map_reduce_coefficients( + __isl_take isl_basic_map *bmap) +{ + isl_size total; + isl_bool multi; + isl_ctx *ctx; + isl_vec *v; + isl_mat *eq, *T, *T2; + int i; + int tightened; + + if (!bmap) + return NULL; + if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_REDUCED_COEFFICIENTS)) + return bmap; + if (isl_basic_map_is_rational(bmap)) + return bmap; + if (bmap->n_eq == 0) + return bmap; + multi = has_multiple_var_equality(bmap); + if (multi < 0) + return isl_basic_map_free(bmap); + if (!multi) + return bmap; + + total = isl_basic_map_dim(bmap, isl_dim_all); + if (total < 0) + return isl_basic_map_free(bmap); + ctx = isl_basic_map_get_ctx(bmap); + v = isl_vec_alloc(ctx, 1 + total); + if (!v) + return isl_basic_map_free(bmap); + + eq = isl_mat_sub_alloc6(ctx, bmap->eq, 0, bmap->n_eq, 0, 1 + total); + T = isl_mat_variable_compression(eq, &T2); + if (!T || !T2) + goto error; + if (T->n_col == 0) { + isl_mat_free(T); + isl_mat_free(T2); + isl_vec_free(v); + return isl_basic_map_set_to_empty(bmap); + } + + bmap = isl_basic_map_cow(bmap); + if (!bmap) + goto error; + + tightened = 0; + for (i = 0; i < bmap->n_ineq; ++i) { + isl_seq_cpy(v->el, bmap->ineq[i], 1 + total); + v = isl_vec_mat_product(v, isl_mat_copy(T)); + v = normalize_constraint(v, &tightened); + v = isl_vec_mat_product(v, isl_mat_copy(T2)); + if (!v) + goto error; + isl_seq_cpy(bmap->ineq[i], v->el, 1 + total); + } + + isl_mat_free(T); + isl_mat_free(T2); + isl_vec_free(v); + + ISL_F_SET(bmap, ISL_BASIC_MAP_REDUCED_COEFFICIENTS); + + if (tightened) { + int progress = 0; + + ISL_F_CLR(bmap, ISL_BASIC_MAP_NO_REDUNDANT); + bmap = isl_basic_map_detect_inequality_pairs(bmap, &progress); + if (progress) { + bmap = eliminate_divs_eq(bmap, &progress); + bmap = isl_basic_map_gauss(bmap, NULL); + } + } + + return bmap; +error: + isl_mat_free(T); + isl_mat_free(T2); + isl_vec_free(v); + return isl_basic_map_free(bmap); +} + +/* Shift the integer division at position "div" of "bmap" + * by "shift" times the variable at position "pos". + * "pos" is as determined by isl_basic_map_offset, i.e., pos == 0 + * corresponds to the constant term. + * + * That is, if the integer division has the form + * + * floor(f(x)/d) + * + * then replace it by + * + * floor((f(x) + shift * d * x_pos)/d) - shift * x_pos + */ +__isl_give isl_basic_map *isl_basic_map_shift_div( + __isl_take isl_basic_map *bmap, int div, int pos, isl_int shift) +{ + int i; + isl_size total, n_div; + + if (isl_int_is_zero(shift)) + return bmap; + total = isl_basic_map_dim(bmap, isl_dim_all); + n_div = isl_basic_map_dim(bmap, isl_dim_div); + total -= n_div; + if (total < 0 || n_div < 0) + return isl_basic_map_free(bmap); + + isl_int_addmul(bmap->div[div][1 + pos], shift, bmap->div[div][0]); + + for (i = 0; i < bmap->n_eq; ++i) { + if (isl_int_is_zero(bmap->eq[i][1 + total + div])) + continue; + isl_int_submul(bmap->eq[i][pos], + shift, bmap->eq[i][1 + total + div]); + } + for (i = 0; i < bmap->n_ineq; ++i) { + if (isl_int_is_zero(bmap->ineq[i][1 + total + div])) + continue; + isl_int_submul(bmap->ineq[i][pos], + shift, bmap->ineq[i][1 + total + div]); + } + for (i = 0; i < bmap->n_div; ++i) { + if (isl_int_is_zero(bmap->div[i][0])) + continue; + if (isl_int_is_zero(bmap->div[i][1 + 1 + total + div])) + continue; + isl_int_submul(bmap->div[i][1 + pos], + shift, bmap->div[i][1 + 1 + total + div]); + } + + return bmap; +} diff --git a/external/mit/isl/dist/isl_map_subtract.c b/external/mit/isl/dist/isl_map_subtract.c new file mode 100644 index 000000000000..68ce54fff067 --- /dev/null +++ b/external/mit/isl/dist/isl_map_subtract.c @@ -0,0 +1,944 @@ +/* + * 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 + */ + +#include +#include +#include +#include +#include "isl_tab.h" +#include +#include + +#include +#include + +/* Expand the constraint "c" into "v". The initial "dim" dimensions + * are the same, but "v" may have more divs than "c" and the divs of "c" + * may appear in different positions in "v". + * The number of divs in "c" is given by "n_div" and the mapping + * of divs in "c" to divs in "v" is given by "div_map". + * + * Although it shouldn't happen in practice, it is theoretically + * possible that two or more divs in "c" are mapped to the same div in "v". + * These divs are then necessarily the same, so we simply add their + * coefficients. + */ +static void expand_constraint(isl_vec *v, unsigned dim, + isl_int *c, int *div_map, unsigned n_div) +{ + int i; + + isl_seq_cpy(v->el, c, 1 + dim); + isl_seq_clr(v->el + 1 + dim, v->size - (1 + dim)); + + for (i = 0; i < n_div; ++i) { + int pos = 1 + dim + div_map[i]; + isl_int_add(v->el[pos], v->el[pos], c[1 + dim + i]); + } +} + +/* Add all constraints of bmap to tab. The equalities of bmap + * are added as a pair of inequalities. + */ +static isl_stat tab_add_constraints(struct isl_tab *tab, + __isl_keep isl_basic_map *bmap, int *div_map) +{ + int i; + unsigned dim; + isl_size tab_total; + isl_size bmap_n_div; + isl_size bmap_total; + isl_vec *v; + + if (!tab || !bmap) + return isl_stat_error; + + tab_total = isl_basic_map_dim(tab->bmap, isl_dim_all); + bmap_total = isl_basic_map_dim(bmap, isl_dim_all); + bmap_n_div = isl_basic_map_dim(bmap, isl_dim_div); + dim = bmap_total - bmap_n_div; + if (tab_total < 0 || bmap_total < 0 || bmap_n_div < 0) + return isl_stat_error; + + if (isl_tab_extend_cons(tab, 2 * bmap->n_eq + bmap->n_ineq) < 0) + return isl_stat_error; + + v = isl_vec_alloc(bmap->ctx, 1 + tab_total); + if (!v) + return isl_stat_error; + + for (i = 0; i < bmap->n_eq; ++i) { + expand_constraint(v, dim, bmap->eq[i], div_map, bmap_n_div); + if (isl_tab_add_ineq(tab, v->el) < 0) + goto error; + isl_seq_neg(bmap->eq[i], bmap->eq[i], 1 + bmap_total); + expand_constraint(v, dim, bmap->eq[i], div_map, bmap_n_div); + if (isl_tab_add_ineq(tab, v->el) < 0) + goto error; + isl_seq_neg(bmap->eq[i], bmap->eq[i], 1 + bmap_total); + if (tab->empty) + break; + } + + for (i = 0; i < bmap->n_ineq; ++i) { + expand_constraint(v, dim, bmap->ineq[i], div_map, bmap_n_div); + if (isl_tab_add_ineq(tab, v->el) < 0) + goto error; + if (tab->empty) + break; + } + + isl_vec_free(v); + return isl_stat_ok; +error: + isl_vec_free(v); + return isl_stat_error; +} + +/* Add a specific constraint of bmap (or its opposite) to tab. + * The position of the constraint is specified by "c", where + * the equalities of bmap are counted twice, once for the inequality + * that is equal to the equality, and once for its negation. + * + * Each of these constraints has been added to "tab" before by + * tab_add_constraints (and later removed again), so there should + * already be a row available for the constraint. + */ +static isl_stat tab_add_constraint(struct isl_tab *tab, + __isl_keep isl_basic_map *bmap, int *div_map, int c, int oppose) +{ + unsigned dim; + isl_size tab_total; + isl_size bmap_n_div; + isl_size bmap_total; + isl_vec *v; + isl_stat r; + + if (!tab || !bmap) + return isl_stat_error; + + tab_total = isl_basic_map_dim(tab->bmap, isl_dim_all); + bmap_total = isl_basic_map_dim(bmap, isl_dim_all); + bmap_n_div = isl_basic_map_dim(bmap, isl_dim_div); + dim = bmap_total - bmap_n_div; + if (tab_total < 0 || bmap_total < 0 || bmap_n_div < 0) + return isl_stat_error; + + v = isl_vec_alloc(bmap->ctx, 1 + tab_total); + if (!v) + return isl_stat_error; + + if (c < 2 * bmap->n_eq) { + if ((c % 2) != oppose) + isl_seq_neg(bmap->eq[c/2], bmap->eq[c/2], + 1 + bmap_total); + if (oppose) + isl_int_sub_ui(bmap->eq[c/2][0], bmap->eq[c/2][0], 1); + expand_constraint(v, dim, bmap->eq[c/2], div_map, bmap_n_div); + r = isl_tab_add_ineq(tab, v->el); + if (oppose) + isl_int_add_ui(bmap->eq[c/2][0], bmap->eq[c/2][0], 1); + if ((c % 2) != oppose) + isl_seq_neg(bmap->eq[c/2], bmap->eq[c/2], + 1 + bmap_total); + } else { + c -= 2 * bmap->n_eq; + if (oppose) { + isl_seq_neg(bmap->ineq[c], bmap->ineq[c], + 1 + bmap_total); + isl_int_sub_ui(bmap->ineq[c][0], bmap->ineq[c][0], 1); + } + expand_constraint(v, dim, bmap->ineq[c], div_map, bmap_n_div); + r = isl_tab_add_ineq(tab, v->el); + if (oppose) { + isl_int_add_ui(bmap->ineq[c][0], bmap->ineq[c][0], 1); + isl_seq_neg(bmap->ineq[c], bmap->ineq[c], + 1 + bmap_total); + } + } + + isl_vec_free(v); + return r; +} + +static isl_stat tab_add_divs(struct isl_tab *tab, + __isl_keep isl_basic_map *bmap, int **div_map) +{ + int i, j; + struct isl_vec *vec; + isl_size total; + unsigned dim; + + if (!bmap) + return isl_stat_error; + if (!bmap->n_div) + return isl_stat_ok; + + if (!*div_map) + *div_map = isl_alloc_array(bmap->ctx, int, bmap->n_div); + if (!*div_map) + return isl_stat_error; + + total = isl_basic_map_dim(tab->bmap, isl_dim_all); + if (total < 0) + return isl_stat_error; + dim = total - tab->bmap->n_div; + vec = isl_vec_alloc(bmap->ctx, 2 + total + bmap->n_div); + if (!vec) + return isl_stat_error; + + for (i = 0; i < bmap->n_div; ++i) { + isl_seq_cpy(vec->el, bmap->div[i], 2 + dim); + isl_seq_clr(vec->el + 2 + dim, tab->bmap->n_div); + for (j = 0; j < i; ++j) + isl_int_add(vec->el[2 + dim + (*div_map)[j]], + vec->el[2 + dim + (*div_map)[j]], + bmap->div[i][2 + dim + j]); + for (j = 0; j < tab->bmap->n_div; ++j) + if (isl_seq_eq(tab->bmap->div[j], + vec->el, 2 + dim + tab->bmap->n_div)) + break; + (*div_map)[i] = j; + if (j == tab->bmap->n_div) { + vec->size = 2 + dim + tab->bmap->n_div; + if (isl_tab_add_div(tab, vec) < 0) + goto error; + } + } + + isl_vec_free(vec); + + return isl_stat_ok; +error: + isl_vec_free(vec); + + return isl_stat_error; +} + +/* Freeze all constraints of tableau tab. + */ +static int tab_freeze_constraints(struct isl_tab *tab) +{ + int i; + + for (i = 0; i < tab->n_con; ++i) + if (isl_tab_freeze_constraint(tab, i) < 0) + return -1; + + return 0; +} + +/* Check for redundant constraints starting at offset. + * Put the indices of the non-redundant constraints in index + * and return the number of non-redundant constraints. + */ +static int n_non_redundant(isl_ctx *ctx, struct isl_tab *tab, + int offset, int **index) +{ + int i, n; + int n_test = tab->n_con - offset; + + if (isl_tab_detect_redundant(tab) < 0) + return -1; + + if (n_test == 0) + return 0; + if (!*index) + *index = isl_alloc_array(ctx, int, n_test); + if (!*index) + return -1; + + for (n = 0, i = 0; i < n_test; ++i) { + int r; + r = isl_tab_is_redundant(tab, offset + i); + if (r < 0) + return -1; + if (r) + continue; + (*index)[n++] = i; + } + + return n; +} + +/* basic_map_collect_diff calls add on each of the pieces of + * the set difference between bmap and map until the add method + * return a negative value. + */ +struct isl_diff_collector { + isl_stat (*add)(struct isl_diff_collector *dc, + __isl_take isl_basic_map *bmap); +}; + +/* Compute the set difference between bmap and map and call + * dc->add on each of the piece until this function returns + * a negative value. + * Return 0 on success and -1 on error. dc->add returning + * a negative value is treated as an error, but the calling + * function can interpret the results based on the state of dc. + * + * Assumes that map has known divs. + * + * The difference is computed by a backtracking algorithm. + * Each level corresponds to a basic map in "map". + * When a node in entered for the first time, we check + * if the corresonding basic map intersects the current piece + * of "bmap". If not, we move to the next level. + * Otherwise, we split the current piece into as many + * pieces as there are non-redundant constraints of the current + * basic map in the intersection. Each of these pieces is + * handled by a child of the current node. + * In particular, if there are n non-redundant constraints, + * then for each 0 <= i < n, a piece is cut off by adding + * constraints 0 <= j < i and adding the opposite of constraint i. + * If there are no non-redundant constraints, meaning that the current + * piece is a subset of the current basic map, then we simply backtrack. + * + * In the leaves, we check if the remaining piece has any integer points + * and if so, pass it along to dc->add. As a special case, if nothing + * has been removed when we end up in a leaf, we simply pass along + * the original basic map. + */ +static isl_stat basic_map_collect_diff(__isl_take isl_basic_map *bmap, + __isl_take isl_map *map, struct isl_diff_collector *dc) +{ + int i; + int modified; + int level; + int init; + isl_bool empty; + isl_ctx *ctx; + struct isl_tab *tab = NULL; + struct isl_tab_undo **snap = NULL; + int *k = NULL; + int *n = NULL; + int **index = NULL; + int **div_map = NULL; + + empty = isl_basic_map_is_empty(bmap); + if (empty) { + isl_basic_map_free(bmap); + isl_map_free(map); + return empty < 0 ? isl_stat_error : isl_stat_ok; + } + + bmap = isl_basic_map_cow(bmap); + map = isl_map_cow(map); + + if (!bmap || !map) + goto error; + + ctx = map->ctx; + snap = isl_alloc_array(map->ctx, struct isl_tab_undo *, map->n); + k = isl_alloc_array(map->ctx, int, map->n); + n = isl_alloc_array(map->ctx, int, map->n); + index = isl_calloc_array(map->ctx, int *, map->n); + div_map = isl_calloc_array(map->ctx, int *, map->n); + if (!snap || !k || !n || !index || !div_map) + goto error; + + bmap = isl_basic_map_order_divs(bmap); + map = isl_map_order_divs(map); + + tab = isl_tab_from_basic_map(bmap, 1); + if (!tab) + goto error; + + modified = 0; + level = 0; + init = 1; + + while (level >= 0) { + if (level >= map->n) { + int empty; + struct isl_basic_map *bm; + if (!modified) { + if (dc->add(dc, isl_basic_map_copy(bmap)) < 0) + goto error; + break; + } + bm = isl_basic_map_copy(tab->bmap); + bm = isl_basic_map_cow(bm); + bm = isl_basic_map_update_from_tab(bm, tab); + bm = isl_basic_map_simplify(bm); + bm = isl_basic_map_finalize(bm); + empty = isl_basic_map_is_empty(bm); + if (empty) + isl_basic_map_free(bm); + else if (dc->add(dc, bm) < 0) + goto error; + if (empty < 0) + goto error; + level--; + init = 0; + continue; + } + if (init) { + int offset; + struct isl_tab_undo *snap2; + snap2 = isl_tab_snap(tab); + if (tab_add_divs(tab, map->p[level], + &div_map[level]) < 0) + goto error; + offset = tab->n_con; + snap[level] = isl_tab_snap(tab); + if (tab_freeze_constraints(tab) < 0) + goto error; + if (tab_add_constraints(tab, map->p[level], + div_map[level]) < 0) + goto error; + k[level] = 0; + n[level] = 0; + if (tab->empty) { + if (isl_tab_rollback(tab, snap2) < 0) + goto error; + level++; + continue; + } + modified = 1; + n[level] = n_non_redundant(ctx, tab, offset, + &index[level]); + if (n[level] < 0) + goto error; + if (n[level] == 0) { + level--; + init = 0; + continue; + } + if (isl_tab_rollback(tab, snap[level]) < 0) + goto error; + if (tab_add_constraint(tab, map->p[level], + div_map[level], index[level][0], 1) < 0) + goto error; + level++; + continue; + } else { + if (k[level] + 1 >= n[level]) { + level--; + continue; + } + if (isl_tab_rollback(tab, snap[level]) < 0) + goto error; + if (tab_add_constraint(tab, map->p[level], + div_map[level], + index[level][k[level]], 0) < 0) + goto error; + snap[level] = isl_tab_snap(tab); + k[level]++; + if (tab_add_constraint(tab, map->p[level], + div_map[level], + index[level][k[level]], 1) < 0) + goto error; + level++; + init = 1; + continue; + } + } + + isl_tab_free(tab); + free(snap); + free(n); + free(k); + for (i = 0; index && i < map->n; ++i) + free(index[i]); + free(index); + for (i = 0; div_map && i < map->n; ++i) + free(div_map[i]); + free(div_map); + + isl_basic_map_free(bmap); + isl_map_free(map); + + return isl_stat_ok; +error: + isl_tab_free(tab); + free(snap); + free(n); + free(k); + for (i = 0; index && i < map->n; ++i) + free(index[i]); + free(index); + for (i = 0; div_map && i < map->n; ++i) + free(div_map[i]); + free(div_map); + isl_basic_map_free(bmap); + isl_map_free(map); + return isl_stat_error; +} + +/* A diff collector that actually collects all parts of the + * set difference in the field diff. + */ +struct isl_subtract_diff_collector { + struct isl_diff_collector dc; + struct isl_map *diff; +}; + +/* isl_subtract_diff_collector callback. + */ +static isl_stat basic_map_subtract_add(struct isl_diff_collector *dc, + __isl_take isl_basic_map *bmap) +{ + struct isl_subtract_diff_collector *sdc; + sdc = (struct isl_subtract_diff_collector *)dc; + + sdc->diff = isl_map_union_disjoint(sdc->diff, + isl_map_from_basic_map(bmap)); + + return sdc->diff ? isl_stat_ok : isl_stat_error; +} + +/* Return the set difference between bmap and map. + */ +static __isl_give isl_map *basic_map_subtract(__isl_take isl_basic_map *bmap, + __isl_take isl_map *map) +{ + struct isl_subtract_diff_collector sdc; + sdc.dc.add = &basic_map_subtract_add; + sdc.diff = isl_map_empty(isl_basic_map_get_space(bmap)); + if (basic_map_collect_diff(bmap, map, &sdc.dc) < 0) { + isl_map_free(sdc.diff); + sdc.diff = NULL; + } + return sdc.diff; +} + +/* Return an empty map living in the same space as "map1" and "map2". + */ +static __isl_give isl_map *replace_pair_by_empty( __isl_take isl_map *map1, + __isl_take isl_map *map2) +{ + isl_space *space; + + space = isl_map_get_space(map1); + isl_map_free(map1); + isl_map_free(map2); + return isl_map_empty(space); +} + +/* Return the set difference between map1 and map2. + * (U_i A_i) \ (U_j B_j) is computed as U_i (A_i \ (U_j B_j)) + * + * If "map1" and "map2" are obviously equal to each other, + * then return an empty map in the same space. + * + * If "map1" and "map2" are disjoint, then simply return "map1". + */ +__isl_give isl_map *isl_map_subtract( __isl_take isl_map *map1, + __isl_take isl_map *map2) +{ + int i; + int equal, disjoint; + struct isl_map *diff; + + if (isl_map_align_params_bin(&map1, &map2) < 0) + goto error; + if (isl_map_check_equal_space(map1, map2) < 0) + goto error; + + equal = isl_map_plain_is_equal(map1, map2); + if (equal < 0) + goto error; + if (equal) + return replace_pair_by_empty(map1, map2); + + disjoint = isl_map_is_disjoint(map1, map2); + if (disjoint < 0) + goto error; + if (disjoint) { + isl_map_free(map2); + return map1; + } + + map1 = isl_map_compute_divs(map1); + map2 = isl_map_compute_divs(map2); + if (!map1 || !map2) + goto error; + + map1 = isl_map_remove_empty_parts(map1); + map2 = isl_map_remove_empty_parts(map2); + + diff = isl_map_empty(isl_map_get_space(map1)); + for (i = 0; i < map1->n; ++i) { + struct isl_map *d; + d = basic_map_subtract(isl_basic_map_copy(map1->p[i]), + isl_map_copy(map2)); + if (ISL_F_ISSET(map1, ISL_MAP_DISJOINT)) + diff = isl_map_union_disjoint(diff, d); + else + diff = isl_map_union(diff, d); + } + + isl_map_free(map1); + isl_map_free(map2); + + return diff; +error: + isl_map_free(map1); + isl_map_free(map2); + return NULL; +} + +__isl_give isl_set *isl_set_subtract(__isl_take isl_set *set1, + __isl_take isl_set *set2) +{ + return set_from_map(isl_map_subtract(set_to_map(set1), + set_to_map(set2))); +} + +/* Remove the elements of "dom" from the domain of "map". + */ +__isl_give isl_map *isl_map_subtract_domain(__isl_take isl_map *map, + __isl_take isl_set *dom) +{ + isl_bool ok; + isl_map *ext_dom; + + isl_map_align_params_set(&map, &dom); + ok = isl_map_compatible_domain(map, dom); + if (ok < 0) + goto error; + if (!ok) + isl_die(isl_set_get_ctx(dom), isl_error_invalid, + "incompatible spaces", goto error); + + ext_dom = isl_map_universe(isl_map_get_space(map)); + ext_dom = isl_map_intersect_domain(ext_dom, dom); + return isl_map_subtract(map, ext_dom); +error: + isl_map_free(map); + isl_set_free(dom); + return NULL; +} + +/* Remove the elements of "dom" from the range of "map". + */ +__isl_give isl_map *isl_map_subtract_range(__isl_take isl_map *map, + __isl_take isl_set *dom) +{ + isl_bool ok; + isl_map *ext_dom; + + isl_map_align_params_set(&map, &dom); + ok = isl_map_compatible_range(map, dom); + if (ok < 0) + goto error; + if (!ok) + isl_die(isl_set_get_ctx(dom), isl_error_invalid, + "incompatible spaces", goto error); + + ext_dom = isl_map_universe(isl_map_get_space(map)); + ext_dom = isl_map_intersect_range(ext_dom, dom); + return isl_map_subtract(map, ext_dom); +error: + isl_map_free(map); + isl_set_free(dom); + return NULL; +} + +/* A diff collector that aborts as soon as its add function is called, + * setting empty to isl_false. + */ +struct isl_is_empty_diff_collector { + struct isl_diff_collector dc; + isl_bool empty; +}; + +/* isl_is_empty_diff_collector callback. + */ +static isl_stat basic_map_is_empty_add(struct isl_diff_collector *dc, + __isl_take isl_basic_map *bmap) +{ + struct isl_is_empty_diff_collector *edc; + edc = (struct isl_is_empty_diff_collector *)dc; + + edc->empty = isl_bool_false; + + isl_basic_map_free(bmap); + return isl_stat_error; +} + +/* Check if bmap \ map is empty by computing this set difference + * and breaking off as soon as the difference is known to be non-empty. + */ +static isl_bool basic_map_diff_is_empty(__isl_keep isl_basic_map *bmap, + __isl_keep isl_map *map) +{ + isl_bool empty; + isl_stat r; + struct isl_is_empty_diff_collector edc; + + empty = isl_basic_map_plain_is_empty(bmap); + if (empty) + return empty; + + edc.dc.add = &basic_map_is_empty_add; + edc.empty = isl_bool_true; + r = basic_map_collect_diff(isl_basic_map_copy(bmap), + isl_map_copy(map), &edc.dc); + if (!edc.empty) + return isl_bool_false; + + return r < 0 ? isl_bool_error : isl_bool_true; +} + +/* Check if map1 \ map2 is empty by checking if the set difference is empty + * for each of the basic maps in map1. + */ +static isl_bool map_diff_is_empty(__isl_keep isl_map *map1, + __isl_keep isl_map *map2) +{ + int i; + isl_bool is_empty = isl_bool_true; + + if (!map1 || !map2) + return isl_bool_error; + + for (i = 0; i < map1->n; ++i) { + is_empty = basic_map_diff_is_empty(map1->p[i], map2); + if (is_empty < 0 || !is_empty) + break; + } + + return is_empty; +} + +/* Return true if "bmap" contains a single element. + */ +isl_bool isl_basic_map_plain_is_singleton(__isl_keep isl_basic_map *bmap) +{ + isl_size total; + + if (!bmap) + return isl_bool_error; + if (bmap->n_div) + return isl_bool_false; + if (bmap->n_ineq) + return isl_bool_false; + total = isl_basic_map_dim(bmap, isl_dim_all); + if (total < 0) + return isl_bool_error; + return bmap->n_eq == total; +} + +/* Return true if "map" contains a single element. + */ +isl_bool isl_map_plain_is_singleton(__isl_keep isl_map *map) +{ + if (!map) + return isl_bool_error; + if (map->n != 1) + return isl_bool_false; + + return isl_basic_map_plain_is_singleton(map->p[0]); +} + +/* Given a singleton basic map, extract the single element + * as an isl_point. + */ +static __isl_give isl_point *singleton_extract_point( + __isl_keep isl_basic_map *bmap) +{ + int j; + isl_size dim; + struct isl_vec *point; + isl_int m; + + dim = isl_basic_map_dim(bmap, isl_dim_all); + if (dim < 0) + return NULL; + + isl_assert(bmap->ctx, bmap->n_eq == dim, return NULL); + point = isl_vec_alloc(bmap->ctx, 1 + dim); + if (!point) + return NULL; + + isl_int_init(m); + + isl_int_set_si(point->el[0], 1); + for (j = 0; j < bmap->n_eq; ++j) { + int i = dim - 1 - j; + isl_assert(bmap->ctx, + isl_seq_first_non_zero(bmap->eq[j] + 1, i) == -1, + goto error); + isl_assert(bmap->ctx, + isl_int_is_one(bmap->eq[j][1 + i]) || + isl_int_is_negone(bmap->eq[j][1 + i]), + goto error); + isl_assert(bmap->ctx, + isl_seq_first_non_zero(bmap->eq[j]+1+i+1, dim-i-1) == -1, + goto error); + + isl_int_gcd(m, point->el[0], bmap->eq[j][1 + i]); + isl_int_divexact(m, bmap->eq[j][1 + i], m); + isl_int_abs(m, m); + isl_seq_scale(point->el, point->el, m, 1 + i); + isl_int_divexact(m, point->el[0], bmap->eq[j][1 + i]); + isl_int_neg(m, m); + isl_int_mul(point->el[1 + i], m, bmap->eq[j][0]); + } + + isl_int_clear(m); + return isl_point_alloc(isl_basic_map_get_space(bmap), point); +error: + isl_int_clear(m); + isl_vec_free(point); + return NULL; +} + +/* Return isl_bool_true if the singleton map "map1" is a subset of "map2", + * i.e., if the single element of "map1" is also an element of "map2". + * Assumes "map2" has known divs. + */ +static isl_bool map_is_singleton_subset(__isl_keep isl_map *map1, + __isl_keep isl_map *map2) +{ + int i; + isl_bool is_subset = isl_bool_false; + struct isl_point *point; + + if (!map1 || !map2) + return isl_bool_error; + if (map1->n != 1) + isl_die(isl_map_get_ctx(map1), isl_error_invalid, + "expecting single-disjunct input", + return isl_bool_error); + + point = singleton_extract_point(map1->p[0]); + if (!point) + return isl_bool_error; + + for (i = 0; i < map2->n; ++i) { + is_subset = isl_basic_map_contains_point(map2->p[i], point); + if (is_subset) + break; + } + + isl_point_free(point); + return is_subset; +} + +static isl_bool map_is_subset(__isl_keep isl_map *map1, + __isl_keep isl_map *map2) +{ + isl_bool is_subset = isl_bool_false; + isl_bool empty, single; + isl_bool rat1, rat2; + + if (!map1 || !map2) + return isl_bool_error; + + if (!isl_map_has_equal_space(map1, map2)) + return isl_bool_false; + + empty = isl_map_is_empty(map1); + if (empty < 0) + return isl_bool_error; + if (empty) + return isl_bool_true; + + empty = isl_map_is_empty(map2); + if (empty < 0) + return isl_bool_error; + if (empty) + return isl_bool_false; + + rat1 = isl_map_has_rational(map1); + rat2 = isl_map_has_rational(map2); + if (rat1 < 0 || rat2 < 0) + return isl_bool_error; + if (rat1 && !rat2) + return isl_bool_false; + + if (isl_map_plain_is_universe(map2)) + return isl_bool_true; + + single = isl_map_plain_is_singleton(map1); + if (single < 0) + return isl_bool_error; + map2 = isl_map_compute_divs(isl_map_copy(map2)); + if (single) { + is_subset = map_is_singleton_subset(map1, map2); + isl_map_free(map2); + return is_subset; + } + is_subset = map_diff_is_empty(map1, map2); + isl_map_free(map2); + + return is_subset; +} + +isl_bool isl_map_is_subset(__isl_keep isl_map *map1, __isl_keep isl_map *map2) +{ + return isl_map_align_params_map_map_and_test(map1, map2, + &map_is_subset); +} + +isl_bool isl_set_is_subset(__isl_keep isl_set *set1, __isl_keep isl_set *set2) +{ + return isl_map_is_subset(set_to_map(set1), set_to_map(set2)); +} + +__isl_give isl_map *isl_map_make_disjoint(__isl_take isl_map *map) +{ + int i; + struct isl_subtract_diff_collector sdc; + sdc.dc.add = &basic_map_subtract_add; + + if (!map) + return NULL; + if (ISL_F_ISSET(map, ISL_MAP_DISJOINT)) + return map; + if (map->n <= 1) + return map; + + map = isl_map_compute_divs(map); + map = isl_map_remove_empty_parts(map); + + if (!map || map->n <= 1) + return map; + + sdc.diff = isl_map_from_basic_map(isl_basic_map_copy(map->p[0])); + + for (i = 1; i < map->n; ++i) { + struct isl_basic_map *bmap = isl_basic_map_copy(map->p[i]); + struct isl_map *copy = isl_map_copy(sdc.diff); + if (basic_map_collect_diff(bmap, copy, &sdc.dc) < 0) { + isl_map_free(sdc.diff); + sdc.diff = NULL; + break; + } + } + + isl_map_free(map); + + return sdc.diff; +} + +__isl_give isl_set *isl_set_make_disjoint(__isl_take isl_set *set) +{ + return set_from_map(isl_map_make_disjoint(set_to_map(set))); +} + +__isl_give isl_map *isl_map_complement(__isl_take isl_map *map) +{ + isl_map *universe; + + if (!map) + return NULL; + + universe = isl_map_universe(isl_map_get_space(map)); + + return isl_map_subtract(universe, map); +} + +__isl_give isl_set *isl_set_complement(__isl_take isl_set *set) +{ + return isl_map_complement(set); +} diff --git a/external/mit/isl/dist/isl_map_to_basic_set.c b/external/mit/isl/dist/isl_map_to_basic_set.c new file mode 100644 index 000000000000..9e96e6074639 --- /dev/null +++ b/external/mit/isl/dist/isl_map_to_basic_set.c @@ -0,0 +1,18 @@ +#include +#include +#include + +#define ISL_KEY isl_map +#define ISL_VAL isl_basic_set +#define ISL_HMAP_SUFFIX map_to_basic_set +#define ISL_HMAP isl_map_to_basic_set +#define ISL_HMAP_IS_EQUAL isl_map_to_basic_set_plain_is_equal +#define ISL_KEY_IS_EQUAL isl_map_plain_is_equal +#define ISL_VAL_IS_EQUAL isl_basic_set_plain_is_equal +#define ISL_KEY_PRINT isl_printer_print_map +#define ISL_VAL_PRINT isl_printer_print_basic_set +#define ISL_HMAP_HAVE_READ_FROM_STR +#define ISL_KEY_READ isl_stream_read_map +#define ISL_VAL_READ isl_stream_read_basic_set + +#include diff --git a/external/mit/isl/dist/isl_mat.c b/external/mit/isl/dist/isl_mat.c new file mode 100644 index 000000000000..37468ee30efa --- /dev/null +++ b/external/mit/isl/dist/isl_mat.c @@ -0,0 +1,2110 @@ +/* + * 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 + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +isl_ctx *isl_mat_get_ctx(__isl_keep isl_mat *mat) +{ + return mat ? mat->ctx : NULL; +} + +/* Return a hash value that digests "mat". + */ +uint32_t isl_mat_get_hash(__isl_keep isl_mat *mat) +{ + int i; + uint32_t hash; + + if (!mat) + return 0; + + hash = isl_hash_init(); + isl_hash_byte(hash, mat->n_row & 0xFF); + isl_hash_byte(hash, mat->n_col & 0xFF); + for (i = 0; i < mat->n_row; ++i) { + uint32_t row_hash; + + row_hash = isl_seq_get_hash(mat->row[i], mat->n_col); + isl_hash_hash(hash, row_hash); + } + + return hash; +} + +__isl_give isl_mat *isl_mat_alloc(isl_ctx *ctx, + unsigned n_row, unsigned n_col) +{ + int i; + struct isl_mat *mat; + + mat = isl_alloc_type(ctx, struct isl_mat); + if (!mat) + return NULL; + + mat->row = NULL; + mat->block = isl_blk_alloc(ctx, n_row * n_col); + if (isl_blk_is_error(mat->block)) + goto error; + mat->row = isl_calloc_array(ctx, isl_int *, n_row); + if (n_row && !mat->row) + goto error; + + if (n_col != 0) { + for (i = 0; i < n_row; ++i) + mat->row[i] = mat->block.data + i * n_col; + } + + mat->ctx = ctx; + isl_ctx_ref(ctx); + mat->ref = 1; + mat->n_row = n_row; + mat->n_col = n_col; + mat->max_col = n_col; + mat->flags = 0; + + return mat; +error: + isl_blk_free(ctx, mat->block); + free(mat); + return NULL; +} + +__isl_give isl_mat *isl_mat_extend(__isl_take isl_mat *mat, + unsigned n_row, unsigned n_col) +{ + int i; + isl_int *old; + isl_int **row; + + if (!mat) + return NULL; + + if (mat->max_col >= n_col && mat->n_row >= n_row) { + if (mat->n_col < n_col) + mat->n_col = n_col; + return mat; + } + + if (mat->max_col < n_col) { + struct isl_mat *new_mat; + + if (n_row < mat->n_row) + n_row = mat->n_row; + new_mat = isl_mat_alloc(mat->ctx, n_row, n_col); + if (!new_mat) + goto error; + for (i = 0; i < mat->n_row; ++i) + isl_seq_cpy(new_mat->row[i], mat->row[i], mat->n_col); + isl_mat_free(mat); + return new_mat; + } + + mat = isl_mat_cow(mat); + if (!mat) + goto error; + + old = mat->block.data; + mat->block = isl_blk_extend(mat->ctx, mat->block, n_row * mat->max_col); + if (isl_blk_is_error(mat->block)) + goto error; + row = isl_realloc_array(mat->ctx, mat->row, isl_int *, n_row); + if (n_row && !row) + goto error; + mat->row = row; + + for (i = 0; i < mat->n_row; ++i) + mat->row[i] = mat->block.data + (mat->row[i] - old); + for (i = mat->n_row; i < n_row; ++i) + mat->row[i] = mat->block.data + i * mat->max_col; + mat->n_row = n_row; + if (mat->n_col < n_col) + mat->n_col = n_col; + + return mat; +error: + isl_mat_free(mat); + return NULL; +} + +__isl_give isl_mat *isl_mat_sub_alloc6(isl_ctx *ctx, isl_int **row, + unsigned first_row, unsigned n_row, unsigned first_col, unsigned n_col) +{ + int i; + struct isl_mat *mat; + + mat = isl_alloc_type(ctx, struct isl_mat); + if (!mat) + return NULL; + mat->row = isl_alloc_array(ctx, isl_int *, n_row); + if (n_row && !mat->row) + goto error; + for (i = 0; i < n_row; ++i) + mat->row[i] = row[first_row+i] + first_col; + mat->ctx = ctx; + isl_ctx_ref(ctx); + mat->ref = 1; + mat->n_row = n_row; + mat->n_col = n_col; + mat->block = isl_blk_empty(); + mat->flags = ISL_MAT_BORROWED; + return mat; +error: + free(mat); + return NULL; +} + +__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) +{ + if (!mat) + return NULL; + return isl_mat_sub_alloc6(mat->ctx, mat->row, first_row, n_row, + first_col, n_col); +} + +void isl_mat_sub_copy(struct isl_ctx *ctx, isl_int **dst, isl_int **src, + unsigned n_row, unsigned dst_col, unsigned src_col, unsigned n_col) +{ + int i; + + for (i = 0; i < n_row; ++i) + isl_seq_cpy(dst[i]+dst_col, src[i]+src_col, n_col); +} + +void isl_mat_sub_neg(struct isl_ctx *ctx, isl_int **dst, isl_int **src, + unsigned n_row, unsigned dst_col, unsigned src_col, unsigned n_col) +{ + int i; + + for (i = 0; i < n_row; ++i) + isl_seq_neg(dst[i]+dst_col, src[i]+src_col, n_col); +} + +__isl_give isl_mat *isl_mat_copy(__isl_keep isl_mat *mat) +{ + if (!mat) + return NULL; + + mat->ref++; + return mat; +} + +__isl_give isl_mat *isl_mat_dup(__isl_keep isl_mat *mat) +{ + int i; + struct isl_mat *mat2; + + if (!mat) + return NULL; + mat2 = isl_mat_alloc(mat->ctx, mat->n_row, mat->n_col); + if (!mat2) + return NULL; + for (i = 0; i < mat->n_row; ++i) + isl_seq_cpy(mat2->row[i], mat->row[i], mat->n_col); + return mat2; +} + +__isl_give isl_mat *isl_mat_cow(__isl_take isl_mat *mat) +{ + struct isl_mat *mat2; + if (!mat) + return NULL; + + if (mat->ref == 1 && !ISL_F_ISSET(mat, ISL_MAT_BORROWED)) + return mat; + + mat2 = isl_mat_dup(mat); + isl_mat_free(mat); + return mat2; +} + +__isl_null isl_mat *isl_mat_free(__isl_take isl_mat *mat) +{ + if (!mat) + return NULL; + + if (--mat->ref > 0) + return NULL; + + if (!ISL_F_ISSET(mat, ISL_MAT_BORROWED)) + isl_blk_free(mat->ctx, mat->block); + isl_ctx_deref(mat->ctx); + free(mat->row); + free(mat); + + return NULL; +} + +isl_size isl_mat_rows(__isl_keep isl_mat *mat) +{ + return mat ? mat->n_row : isl_size_error; +} + +isl_size isl_mat_cols(__isl_keep isl_mat *mat) +{ + return mat ? mat->n_col : isl_size_error; +} + +/* Check that "col" is a valid column position for "mat". + */ +static isl_stat check_col(__isl_keep isl_mat *mat, int col) +{ + if (!mat) + return isl_stat_error; + if (col < 0 || col >= mat->n_col) + isl_die(isl_mat_get_ctx(mat), isl_error_invalid, + "column out of range", return isl_stat_error); + return isl_stat_ok; +} + +/* Check that "row" is a valid row position for "mat". + */ +static isl_stat check_row(__isl_keep isl_mat *mat, int row) +{ + if (!mat) + return isl_stat_error; + if (row < 0 || row >= mat->n_row) + isl_die(isl_mat_get_ctx(mat), isl_error_invalid, + "row out of range", return isl_stat_error); + 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) + return -1; + if (check_col(mat, col) < 0) + return -1; + isl_int_set(*v, mat->row[row][col]); + return 0; +} + +/* Extract the element at row "row", oolumn "col" of "mat". + */ +__isl_give isl_val *isl_mat_get_element_val(__isl_keep isl_mat *mat, + int row, int col) +{ + isl_ctx *ctx; + + if (check_row(mat, row) < 0) + return NULL; + if (check_col(mat, col) < 0) + return NULL; + ctx = isl_mat_get_ctx(mat); + return isl_val_int_from_isl_int(ctx, mat->row[row][col]); +} + +__isl_give isl_mat *isl_mat_set_element(__isl_take isl_mat *mat, + int row, int col, isl_int v) +{ + mat = isl_mat_cow(mat); + if (check_row(mat, row) < 0) + return isl_mat_free(mat); + if (check_col(mat, col) < 0) + return isl_mat_free(mat); + isl_int_set(mat->row[row][col], v); + return mat; +} + +__isl_give isl_mat *isl_mat_set_element_si(__isl_take isl_mat *mat, + int row, int col, int v) +{ + mat = isl_mat_cow(mat); + if (check_row(mat, row) < 0) + return isl_mat_free(mat); + if (check_col(mat, col) < 0) + return isl_mat_free(mat); + isl_int_set_si(mat->row[row][col], v); + return mat; +} + +/* Replace the element at row "row", column "col" of "mat" by "v". + */ +__isl_give isl_mat *isl_mat_set_element_val(__isl_take isl_mat *mat, + int row, int col, __isl_take isl_val *v) +{ + if (!v) + return isl_mat_free(mat); + if (!isl_val_is_int(v)) + isl_die(isl_val_get_ctx(v), isl_error_invalid, + "expecting integer value", goto error); + mat = isl_mat_set_element(mat, row, col, v->n); + isl_val_free(v); + return mat; +error: + isl_val_free(v); + return isl_mat_free(mat); +} + +__isl_give isl_mat *isl_mat_diag(isl_ctx *ctx, unsigned n_row, isl_int d) +{ + int i; + struct isl_mat *mat; + + mat = isl_mat_alloc(ctx, n_row, n_row); + if (!mat) + return NULL; + for (i = 0; i < n_row; ++i) { + isl_seq_clr(mat->row[i], i); + isl_int_set(mat->row[i][i], d); + isl_seq_clr(mat->row[i]+i+1, n_row-(i+1)); + } + + return mat; +} + +/* Create an "n_row" by "n_col" matrix with zero elements. + */ +__isl_give isl_mat *isl_mat_zero(isl_ctx *ctx, unsigned n_row, unsigned n_col) +{ + int i; + isl_mat *mat; + + mat = isl_mat_alloc(ctx, n_row, n_col); + if (!mat) + return NULL; + for (i = 0; i < n_row; ++i) + isl_seq_clr(mat->row[i], n_col); + + return mat; +} + +__isl_give isl_mat *isl_mat_identity(isl_ctx *ctx, unsigned n_row) +{ + if (!ctx) + return NULL; + return isl_mat_diag(ctx, n_row, ctx->one); +} + +/* Is "mat" a (possibly scaled) identity matrix? + */ +isl_bool isl_mat_is_scaled_identity(__isl_keep isl_mat *mat) +{ + int i; + + if (!mat) + return isl_bool_error; + if (mat->n_row != mat->n_col) + return isl_bool_false; + + for (i = 0; i < mat->n_row; ++i) { + if (isl_seq_first_non_zero(mat->row[i], i) != -1) + return isl_bool_false; + if (isl_int_ne(mat->row[0][0], mat->row[i][i])) + return isl_bool_false; + if (isl_seq_first_non_zero(mat->row[i] + i + 1, + mat->n_col - (i + 1)) != -1) + return isl_bool_false; + } + + return isl_bool_true; +} + +__isl_give isl_vec *isl_mat_vec_product(__isl_take isl_mat *mat, + __isl_take isl_vec *vec) +{ + int i; + struct isl_vec *prod; + + if (!mat || !vec) + goto error; + + isl_assert(mat->ctx, mat->n_col == vec->size, goto error); + + prod = isl_vec_alloc(mat->ctx, mat->n_row); + if (!prod) + goto error; + + for (i = 0; i < prod->size; ++i) + isl_seq_inner_product(mat->row[i], vec->el, vec->size, + &prod->block.data[i]); + isl_mat_free(mat); + isl_vec_free(vec); + return prod; +error: + isl_mat_free(mat); + isl_vec_free(vec); + return NULL; +} + +__isl_give isl_vec *isl_mat_vec_inverse_product(__isl_take isl_mat *mat, + __isl_take isl_vec *vec) +{ + struct isl_mat *vec_mat; + int i; + + if (!mat || !vec) + goto error; + vec_mat = isl_mat_alloc(vec->ctx, vec->size, 1); + if (!vec_mat) + goto error; + for (i = 0; i < vec->size; ++i) + isl_int_set(vec_mat->row[i][0], vec->el[i]); + vec_mat = isl_mat_inverse_product(mat, vec_mat); + isl_vec_free(vec); + if (!vec_mat) + return NULL; + vec = isl_vec_alloc(vec_mat->ctx, vec_mat->n_row); + if (vec) + for (i = 0; i < vec->size; ++i) + isl_int_set(vec->el[i], vec_mat->row[i][0]); + isl_mat_free(vec_mat); + return vec; +error: + isl_mat_free(mat); + isl_vec_free(vec); + return NULL; +} + +__isl_give isl_vec *isl_vec_mat_product(__isl_take isl_vec *vec, + __isl_take isl_mat *mat) +{ + int i, j; + struct isl_vec *prod; + + if (!mat || !vec) + goto error; + + isl_assert(mat->ctx, mat->n_row == vec->size, goto error); + + prod = isl_vec_alloc(mat->ctx, mat->n_col); + if (!prod) + goto error; + + for (i = 0; i < prod->size; ++i) { + isl_int_set_si(prod->el[i], 0); + for (j = 0; j < vec->size; ++j) + isl_int_addmul(prod->el[i], vec->el[j], mat->row[j][i]); + } + isl_mat_free(mat); + isl_vec_free(vec); + return prod; +error: + isl_mat_free(mat); + isl_vec_free(vec); + return NULL; +} + +__isl_give isl_mat *isl_mat_aff_direct_sum(__isl_take isl_mat *left, + __isl_take isl_mat *right) +{ + int i; + struct isl_mat *sum; + + if (!left || !right) + goto error; + + isl_assert(left->ctx, left->n_row == right->n_row, goto error); + isl_assert(left->ctx, left->n_row >= 1, goto error); + isl_assert(left->ctx, left->n_col >= 1, goto error); + isl_assert(left->ctx, right->n_col >= 1, goto error); + isl_assert(left->ctx, + isl_seq_first_non_zero(left->row[0]+1, left->n_col-1) == -1, + goto error); + isl_assert(left->ctx, + isl_seq_first_non_zero(right->row[0]+1, right->n_col-1) == -1, + goto error); + + sum = isl_mat_alloc(left->ctx, left->n_row, left->n_col + right->n_col - 1); + if (!sum) + goto error; + isl_int_lcm(sum->row[0][0], left->row[0][0], right->row[0][0]); + isl_int_divexact(left->row[0][0], sum->row[0][0], left->row[0][0]); + isl_int_divexact(right->row[0][0], sum->row[0][0], right->row[0][0]); + + isl_seq_clr(sum->row[0]+1, sum->n_col-1); + for (i = 1; i < sum->n_row; ++i) { + isl_int_mul(sum->row[i][0], left->row[0][0], left->row[i][0]); + isl_int_addmul(sum->row[i][0], + right->row[0][0], right->row[i][0]); + isl_seq_scale(sum->row[i]+1, left->row[i]+1, left->row[0][0], + left->n_col-1); + isl_seq_scale(sum->row[i]+left->n_col, + right->row[i]+1, right->row[0][0], + right->n_col-1); + } + + isl_int_divexact(left->row[0][0], sum->row[0][0], left->row[0][0]); + isl_int_divexact(right->row[0][0], sum->row[0][0], right->row[0][0]); + isl_mat_free(left); + isl_mat_free(right); + return sum; +error: + isl_mat_free(left); + isl_mat_free(right); + return NULL; +} + +static void exchange(__isl_keep isl_mat *M, __isl_keep isl_mat **U, + __isl_keep isl_mat **Q, unsigned row, unsigned i, unsigned j) +{ + int r; + for (r = row; r < M->n_row; ++r) + isl_int_swap(M->row[r][i], M->row[r][j]); + if (U) { + for (r = 0; r < (*U)->n_row; ++r) + isl_int_swap((*U)->row[r][i], (*U)->row[r][j]); + } + if (Q) + isl_mat_swap_rows(*Q, i, j); +} + +static void subtract(__isl_keep isl_mat *M, __isl_keep isl_mat **U, + __isl_keep isl_mat **Q, unsigned row, unsigned i, unsigned j, isl_int m) +{ + int r; + for (r = row; r < M->n_row; ++r) + isl_int_submul(M->row[r][j], m, M->row[r][i]); + if (U) { + for (r = 0; r < (*U)->n_row; ++r) + isl_int_submul((*U)->row[r][j], m, (*U)->row[r][i]); + } + if (Q) { + for (r = 0; r < (*Q)->n_col; ++r) + isl_int_addmul((*Q)->row[i][r], m, (*Q)->row[j][r]); + } +} + +static void oppose(__isl_keep isl_mat *M, __isl_keep isl_mat **U, + __isl_keep isl_mat **Q, unsigned row, unsigned col) +{ + int r; + for (r = row; r < M->n_row; ++r) + isl_int_neg(M->row[r][col], M->row[r][col]); + if (U) { + for (r = 0; r < (*U)->n_row; ++r) + isl_int_neg((*U)->row[r][col], (*U)->row[r][col]); + } + if (Q) + isl_seq_neg((*Q)->row[col], (*Q)->row[col], (*Q)->n_col); +} + +/* Given matrix M, compute + * + * M U = H + * M = H Q + * + * with U and Q unimodular matrices and H a matrix in column echelon form + * such that on each echelon row the entries in the non-echelon column + * are non-negative (if neg == 0) or non-positive (if neg == 1) + * and strictly smaller (in absolute value) than the entries in the echelon + * column. + * If U or Q are NULL, then these matrices are not computed. + */ +__isl_give isl_mat *isl_mat_left_hermite(__isl_take isl_mat *M, int neg, + __isl_give isl_mat **U, __isl_give isl_mat **Q) +{ + isl_int c; + int row, col; + + if (U) + *U = NULL; + if (Q) + *Q = NULL; + if (!M) + goto error; + if (U) { + *U = isl_mat_identity(M->ctx, M->n_col); + if (!*U) + goto error; + } + if (Q) { + *Q = isl_mat_identity(M->ctx, M->n_col); + if (!*Q) + goto error; + } + + if (M->n_col == 0) + return M; + + M = isl_mat_cow(M); + if (!M) + goto error; + + col = 0; + isl_int_init(c); + for (row = 0; row < M->n_row; ++row) { + int first, i, off; + first = isl_seq_abs_min_non_zero(M->row[row]+col, M->n_col-col); + if (first == -1) + continue; + first += col; + if (first != col) + exchange(M, U, Q, row, first, col); + if (isl_int_is_neg(M->row[row][col])) + oppose(M, U, Q, row, col); + first = col+1; + while ((off = isl_seq_first_non_zero(M->row[row]+first, + M->n_col-first)) != -1) { + first += off; + isl_int_fdiv_q(c, M->row[row][first], M->row[row][col]); + subtract(M, U, Q, row, col, first, c); + if (!isl_int_is_zero(M->row[row][first])) + exchange(M, U, Q, row, first, col); + else + ++first; + } + for (i = 0; i < col; ++i) { + if (isl_int_is_zero(M->row[row][i])) + continue; + if (neg) + isl_int_cdiv_q(c, M->row[row][i], M->row[row][col]); + else + isl_int_fdiv_q(c, M->row[row][i], M->row[row][col]); + if (isl_int_is_zero(c)) + continue; + subtract(M, U, Q, row, col, i, c); + } + ++col; + } + isl_int_clear(c); + + return M; +error: + if (Q) { + isl_mat_free(*Q); + *Q = NULL; + } + if (U) { + isl_mat_free(*U); + *U = NULL; + } + isl_mat_free(M); + return NULL; +} + +/* Use row "row" of "mat" to eliminate column "col" from all other rows. + */ +static __isl_give isl_mat *eliminate(__isl_take isl_mat *mat, int row, int col) +{ + int k; + isl_size nr, nc; + isl_ctx *ctx; + + nr = isl_mat_rows(mat); + nc = isl_mat_cols(mat); + if (nr < 0 || nc < 0) + return isl_mat_free(mat); + + ctx = isl_mat_get_ctx(mat); + + for (k = 0; k < nr; ++k) { + if (k == row) + continue; + if (isl_int_is_zero(mat->row[k][col])) + continue; + mat = isl_mat_cow(mat); + if (!mat) + return NULL; + isl_seq_elim(mat->row[k], mat->row[row], col, nc, NULL); + isl_seq_normalize(ctx, mat->row[k], nc); + } + + return mat; +} + +/* Perform Gaussian elimination on the rows of "mat", but start + * from the final row and the final column. + * Any zero rows that result from the elimination are removed. + * + * In particular, for each column from last to first, + * look for the last row with a non-zero coefficient in that column, + * move it last (but before other rows moved last in previous steps) and + * use it to eliminate the column from the other rows. + */ +__isl_give isl_mat *isl_mat_reverse_gauss(__isl_take isl_mat *mat) +{ + int k, row, last; + isl_size nr, nc; + + nr = isl_mat_rows(mat); + nc = isl_mat_cols(mat); + if (nr < 0 || nc < 0) + return isl_mat_free(mat); + + last = nc - 1; + for (row = nr - 1; row >= 0; --row) { + for (; last >= 0; --last) { + for (k = row; k >= 0; --k) + if (!isl_int_is_zero(mat->row[k][last])) + break; + if (k >= 0) + break; + } + if (last < 0) + break; + if (k != row) + mat = isl_mat_swap_rows(mat, k, row); + if (!mat) + return NULL; + if (isl_int_is_neg(mat->row[row][last])) + mat = isl_mat_row_neg(mat, row); + mat = eliminate(mat, row, last); + if (!mat) + return NULL; + } + mat = isl_mat_drop_rows(mat, 0, row + 1); + + return mat; +} + +/* Negate the lexicographically negative rows of "mat" such that + * all rows in the result are lexicographically non-negative. + */ +__isl_give isl_mat *isl_mat_lexnonneg_rows(__isl_take isl_mat *mat) +{ + int i; + isl_size nr, nc; + + nr = isl_mat_rows(mat); + nc = isl_mat_cols(mat); + if (nr < 0 || nc < 0) + return isl_mat_free(mat); + + for (i = 0; i < nr; ++i) { + int pos; + + pos = isl_seq_first_non_zero(mat->row[i], nc); + if (pos < 0) + continue; + if (isl_int_is_nonneg(mat->row[i][pos])) + continue; + mat = isl_mat_row_neg(mat, i); + if (!mat) + return NULL; + } + + return 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 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 isl_size_error in case of error. + */ +isl_size 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 isl_size_error; + + 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; + + mat = isl_mat_left_hermite(mat, 0, &U, NULL); + if (!mat || !U) + goto error; + + 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; + isl_mat_sub_copy(K->ctx, K->row, U->row, U->n_row, 0, rank, U->n_col-rank); + isl_mat_free(mat); + isl_mat_free(U); + return K; +error: + isl_mat_free(mat); + isl_mat_free(U); + return NULL; +} + +__isl_give isl_mat *isl_mat_lin_to_aff(__isl_take isl_mat *mat) +{ + int i; + struct isl_mat *mat2; + + if (!mat) + return NULL; + mat2 = isl_mat_alloc(mat->ctx, 1+mat->n_row, 1+mat->n_col); + if (!mat2) + goto error; + isl_int_set_si(mat2->row[0][0], 1); + isl_seq_clr(mat2->row[0]+1, mat->n_col); + for (i = 0; i < mat->n_row; ++i) { + isl_int_set_si(mat2->row[1+i][0], 0); + isl_seq_cpy(mat2->row[1+i]+1, mat->row[i], mat->n_col); + } + isl_mat_free(mat); + return mat2; +error: + isl_mat_free(mat); + return NULL; +} + +/* Given two matrices M1 and M2, return the block matrix + * + * [ M1 0 ] + * [ 0 M2 ] + */ +__isl_give isl_mat *isl_mat_diagonal(__isl_take isl_mat *mat1, + __isl_take isl_mat *mat2) +{ + int i; + isl_mat *mat; + + if (!mat1 || !mat2) + goto error; + + mat = isl_mat_alloc(mat1->ctx, mat1->n_row + mat2->n_row, + mat1->n_col + mat2->n_col); + if (!mat) + goto error; + for (i = 0; i < mat1->n_row; ++i) { + isl_seq_cpy(mat->row[i], mat1->row[i], mat1->n_col); + isl_seq_clr(mat->row[i] + mat1->n_col, mat2->n_col); + } + for (i = 0; i < mat2->n_row; ++i) { + isl_seq_clr(mat->row[mat1->n_row + i], mat1->n_col); + isl_seq_cpy(mat->row[mat1->n_row + i] + mat1->n_col, + mat2->row[i], mat2->n_col); + } + isl_mat_free(mat1); + isl_mat_free(mat2); + return mat; +error: + isl_mat_free(mat1); + isl_mat_free(mat2); + return NULL; +} + +static int row_first_non_zero(isl_int **row, unsigned n_row, unsigned col) +{ + int i; + + for (i = 0; i < n_row; ++i) + if (!isl_int_is_zero(row[i][col])) + return i; + return -1; +} + +static int row_abs_min_non_zero(isl_int **row, unsigned n_row, unsigned col) +{ + int i, min = row_first_non_zero(row, n_row, col); + if (min < 0) + return -1; + for (i = min + 1; i < n_row; ++i) { + if (isl_int_is_zero(row[i][col])) + continue; + if (isl_int_abs_lt(row[i][col], row[min][col])) + min = i; + } + return min; +} + +static isl_stat inv_exchange(__isl_keep isl_mat **left, + __isl_keep isl_mat **right, unsigned i, unsigned j) +{ + *left = isl_mat_swap_rows(*left, i, j); + *right = isl_mat_swap_rows(*right, i, j); + + if (!*left || !*right) + return isl_stat_error; + return isl_stat_ok; +} + +static void inv_oppose( + __isl_keep isl_mat *left, __isl_keep isl_mat *right, unsigned row) +{ + isl_seq_neg(left->row[row]+row, left->row[row]+row, left->n_col-row); + isl_seq_neg(right->row[row], right->row[row], right->n_col); +} + +static void inv_subtract(__isl_keep isl_mat *left, __isl_keep isl_mat *right, + unsigned row, unsigned i, isl_int m) +{ + isl_int_neg(m, m); + isl_seq_combine(left->row[i]+row, + left->ctx->one, left->row[i]+row, + m, left->row[row]+row, + left->n_col-row); + isl_seq_combine(right->row[i], right->ctx->one, right->row[i], + m, right->row[row], right->n_col); +} + +/* Compute inv(left)*right + */ +__isl_give isl_mat *isl_mat_inverse_product(__isl_take isl_mat *left, + __isl_take isl_mat *right) +{ + int row; + isl_int a, b; + + if (!left || !right) + goto error; + + isl_assert(left->ctx, left->n_row == left->n_col, goto error); + isl_assert(left->ctx, left->n_row == right->n_row, goto error); + + if (left->n_row == 0) { + isl_mat_free(left); + return right; + } + + left = isl_mat_cow(left); + right = isl_mat_cow(right); + if (!left || !right) + goto error; + + isl_int_init(a); + isl_int_init(b); + for (row = 0; row < left->n_row; ++row) { + int pivot, first, i, off; + pivot = row_abs_min_non_zero(left->row+row, left->n_row-row, row); + if (pivot < 0) { + isl_int_clear(a); + isl_int_clear(b); + isl_assert(left->ctx, pivot >= 0, goto error); + } + pivot += row; + if (pivot != row) + if (inv_exchange(&left, &right, pivot, row) < 0) + goto error; + if (isl_int_is_neg(left->row[row][row])) + inv_oppose(left, right, row); + first = row+1; + while ((off = row_first_non_zero(left->row+first, + left->n_row-first, row)) != -1) { + first += off; + isl_int_fdiv_q(a, left->row[first][row], + left->row[row][row]); + inv_subtract(left, right, row, first, a); + if (!isl_int_is_zero(left->row[first][row])) { + if (inv_exchange(&left, &right, row, first) < 0) + goto error; + } else { + ++first; + } + } + for (i = 0; i < row; ++i) { + if (isl_int_is_zero(left->row[i][row])) + continue; + isl_int_gcd(a, left->row[row][row], left->row[i][row]); + isl_int_divexact(b, left->row[i][row], a); + isl_int_divexact(a, left->row[row][row], a); + isl_int_neg(b, b); + isl_seq_combine(left->row[i] + i, + a, left->row[i] + i, + b, left->row[row] + i, + left->n_col - i); + isl_seq_combine(right->row[i], a, right->row[i], + b, right->row[row], right->n_col); + } + } + isl_int_clear(b); + + isl_int_set(a, left->row[0][0]); + for (row = 1; row < left->n_row; ++row) + isl_int_lcm(a, a, left->row[row][row]); + if (isl_int_is_zero(a)){ + isl_int_clear(a); + isl_assert(left->ctx, 0, goto error); + } + for (row = 0; row < left->n_row; ++row) { + isl_int_divexact(left->row[row][row], a, left->row[row][row]); + if (isl_int_is_one(left->row[row][row])) + continue; + isl_seq_scale(right->row[row], right->row[row], + left->row[row][row], right->n_col); + } + isl_int_clear(a); + + isl_mat_free(left); + return right; +error: + isl_mat_free(left); + isl_mat_free(right); + return NULL; +} + +void isl_mat_col_scale(__isl_keep isl_mat *mat, unsigned col, isl_int m) +{ + int i; + + for (i = 0; i < mat->n_row; ++i) + isl_int_mul(mat->row[i][col], mat->row[i][col], m); +} + +void isl_mat_col_combine(__isl_keep isl_mat *mat, unsigned dst, + isl_int m1, unsigned src1, isl_int m2, unsigned src2) +{ + int i; + isl_int tmp; + + isl_int_init(tmp); + for (i = 0; i < mat->n_row; ++i) { + isl_int_mul(tmp, m1, mat->row[i][src1]); + isl_int_addmul(tmp, m2, mat->row[i][src2]); + isl_int_set(mat->row[i][dst], tmp); + } + isl_int_clear(tmp); +} + +__isl_give isl_mat *isl_mat_right_inverse(__isl_take isl_mat *mat) +{ + struct isl_mat *inv; + int row; + isl_int a, b; + + mat = isl_mat_cow(mat); + if (!mat) + return NULL; + + inv = isl_mat_identity(mat->ctx, mat->n_col); + inv = isl_mat_cow(inv); + if (!inv) + goto error; + + isl_int_init(a); + isl_int_init(b); + for (row = 0; row < mat->n_row; ++row) { + int pivot, first, i, off; + pivot = isl_seq_abs_min_non_zero(mat->row[row]+row, mat->n_col-row); + if (pivot < 0) { + isl_int_clear(a); + isl_int_clear(b); + isl_assert(mat->ctx, pivot >= 0, goto error); + } + pivot += row; + if (pivot != row) + exchange(mat, &inv, NULL, row, pivot, row); + if (isl_int_is_neg(mat->row[row][row])) + oppose(mat, &inv, NULL, row, row); + first = row+1; + while ((off = isl_seq_first_non_zero(mat->row[row]+first, + mat->n_col-first)) != -1) { + first += off; + isl_int_fdiv_q(a, mat->row[row][first], + mat->row[row][row]); + subtract(mat, &inv, NULL, row, row, first, a); + if (!isl_int_is_zero(mat->row[row][first])) + exchange(mat, &inv, NULL, row, row, first); + else + ++first; + } + for (i = 0; i < row; ++i) { + if (isl_int_is_zero(mat->row[row][i])) + continue; + isl_int_gcd(a, mat->row[row][row], mat->row[row][i]); + isl_int_divexact(b, mat->row[row][i], a); + isl_int_divexact(a, mat->row[row][row], a); + isl_int_neg(a, a); + isl_mat_col_combine(mat, i, a, i, b, row); + isl_mat_col_combine(inv, i, a, i, b, row); + } + } + isl_int_clear(b); + + isl_int_set(a, mat->row[0][0]); + for (row = 1; row < mat->n_row; ++row) + isl_int_lcm(a, a, mat->row[row][row]); + if (isl_int_is_zero(a)){ + isl_int_clear(a); + goto error; + } + for (row = 0; row < mat->n_row; ++row) { + isl_int_divexact(mat->row[row][row], a, mat->row[row][row]); + if (isl_int_is_one(mat->row[row][row])) + continue; + isl_mat_col_scale(inv, row, mat->row[row][row]); + } + isl_int_clear(a); + + isl_mat_free(mat); + + return inv; +error: + isl_mat_free(mat); + isl_mat_free(inv); + return NULL; +} + +__isl_give isl_mat *isl_mat_transpose(__isl_take isl_mat *mat) +{ + struct isl_mat *transpose = NULL; + int i, j; + + if (!mat) + return NULL; + + if (mat->n_col == mat->n_row) { + mat = isl_mat_cow(mat); + if (!mat) + return NULL; + for (i = 0; i < mat->n_row; ++i) + for (j = i + 1; j < mat->n_col; ++j) + isl_int_swap(mat->row[i][j], mat->row[j][i]); + return mat; + } + transpose = isl_mat_alloc(mat->ctx, mat->n_col, mat->n_row); + if (!transpose) + goto error; + for (i = 0; i < mat->n_row; ++i) + for (j = 0; j < mat->n_col; ++j) + isl_int_set(transpose->row[j][i], mat->row[i][j]); + isl_mat_free(mat); + return transpose; +error: + isl_mat_free(mat); + return NULL; +} + +__isl_give isl_mat *isl_mat_swap_cols(__isl_take isl_mat *mat, + unsigned i, unsigned j) +{ + int r; + + mat = isl_mat_cow(mat); + 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; +} + +__isl_give isl_mat *isl_mat_swap_rows(__isl_take isl_mat *mat, + unsigned i, unsigned j) +{ + isl_int *t; + + if (!mat) + return NULL; + mat = isl_mat_cow(mat); + 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; + return mat; +} + +/* Calculate the product of two matrices. + * + * This function is optimized for operand matrices that contain many zeros and + * skips multiplications where we know one of the operands is zero. + */ +__isl_give isl_mat *isl_mat_product(__isl_take isl_mat *left, + __isl_take isl_mat *right) +{ + int i, j, k; + struct isl_mat *prod; + + if (!left || !right) + goto error; + isl_assert(left->ctx, left->n_col == right->n_row, goto error); + prod = isl_mat_alloc(left->ctx, left->n_row, right->n_col); + if (!prod) + goto error; + if (left->n_col == 0) { + for (i = 0; i < prod->n_row; ++i) + isl_seq_clr(prod->row[i], prod->n_col); + isl_mat_free(left); + isl_mat_free(right); + return prod; + } + for (i = 0; i < prod->n_row; ++i) { + for (j = 0; j < prod->n_col; ++j) + isl_int_mul(prod->row[i][j], + left->row[i][0], right->row[0][j]); + for (k = 1; k < left->n_col; ++k) { + if (isl_int_is_zero(left->row[i][k])) + continue; + for (j = 0; j < prod->n_col; ++j) + isl_int_addmul(prod->row[i][j], + left->row[i][k], right->row[k][j]); + } + } + isl_mat_free(left); + isl_mat_free(right); + return prod; +error: + isl_mat_free(left); + isl_mat_free(right); + return NULL; +} + +/* Replace the variables x in the rows q by x' given by x = M x', + * with M the matrix mat. + * + * If the number of new variables is greater than the original + * number of variables, then the rows q have already been + * preextended. If the new number is smaller, then the coefficients + * of the divs, which are not changed, need to be shifted down. + * The row q may be the equalities, the inequalities or the + * div expressions. In the latter case, has_div is true and + * we need to take into account the extra denominator column. + */ +static int preimage(struct isl_ctx *ctx, isl_int **q, unsigned n, + unsigned n_div, int has_div, struct isl_mat *mat) +{ + int i; + struct isl_mat *t; + int e; + + if (mat->n_col >= mat->n_row) + e = 0; + else + e = mat->n_row - mat->n_col; + if (has_div) + for (i = 0; i < n; ++i) + isl_int_mul(q[i][0], q[i][0], mat->row[0][0]); + t = isl_mat_sub_alloc6(mat->ctx, q, 0, n, has_div, mat->n_row); + t = isl_mat_product(t, mat); + if (!t) + return -1; + for (i = 0; i < n; ++i) { + isl_seq_swp_or_cpy(q[i] + has_div, t->row[i], t->n_col); + isl_seq_cpy(q[i] + has_div + t->n_col, + q[i] + has_div + t->n_col + e, n_div); + isl_seq_clr(q[i] + has_div + t->n_col + n_div, e); + } + isl_mat_free(t); + return 0; +} + +/* Replace the variables x in bset by x' given by x = M x', with + * M the matrix mat. + * + * If there are fewer variables x' then there are x, then we perform + * the transformation in place, which means that, in principle, + * this frees up some extra variables as the number + * of columns remains constant, but we would have to extend + * the div array too as the number of rows in this array is assumed + * to be equal to extra. + */ +__isl_give isl_basic_set *isl_basic_set_preimage( + __isl_take isl_basic_set *bset, __isl_take isl_mat *mat) +{ + struct isl_ctx *ctx; + + if (!bset || !mat) + goto error; + + ctx = bset->ctx; + bset = isl_basic_set_cow(bset); + if (isl_basic_set_check_no_params(bset) < 0) + goto error; + + isl_assert(ctx, 1+bset->dim->n_out == mat->n_row, goto error); + isl_assert(ctx, mat->n_col > 0, goto error); + + if (mat->n_col > mat->n_row) { + bset = isl_basic_set_add_dims(bset, isl_dim_set, + mat->n_col - mat->n_row); + if (!bset) + goto error; + } else if (mat->n_col < mat->n_row) { + bset->dim = isl_space_cow(bset->dim); + if (!bset->dim) + goto error; + bset->dim->n_out -= mat->n_row - mat->n_col; + } + + if (preimage(ctx, bset->eq, bset->n_eq, bset->n_div, 0, + isl_mat_copy(mat)) < 0) + goto error; + + if (preimage(ctx, bset->ineq, bset->n_ineq, bset->n_div, 0, + isl_mat_copy(mat)) < 0) + goto error; + + if (preimage(ctx, bset->div, bset->n_div, bset->n_div, 1, mat) < 0) + goto error2; + + ISL_F_CLR(bset, ISL_BASIC_SET_NO_IMPLICIT); + ISL_F_CLR(bset, ISL_BASIC_SET_NO_REDUNDANT); + ISL_F_CLR(bset, ISL_BASIC_SET_SORTED); + ISL_F_CLR(bset, ISL_BASIC_SET_NORMALIZED_DIVS); + ISL_F_CLR(bset, ISL_BASIC_SET_ALL_EQUALITIES); + + bset = isl_basic_set_simplify(bset); + bset = isl_basic_set_finalize(bset); + + return bset; +error: + isl_mat_free(mat); +error2: + isl_basic_set_free(bset); + return NULL; +} + +__isl_give isl_set *isl_set_preimage( + __isl_take isl_set *set, __isl_take isl_mat *mat) +{ + int i; + + set = isl_set_cow(set); + if (!set) + goto error; + + for (i = 0; i < set->n; ++i) { + set->p[i] = isl_basic_set_preimage(set->p[i], + isl_mat_copy(mat)); + if (!set->p[i]) + goto error; + } + if (mat->n_col != mat->n_row) { + set->dim = isl_space_cow(set->dim); + if (!set->dim) + goto error; + set->dim->n_out += mat->n_col; + set->dim->n_out -= mat->n_row; + } + isl_mat_free(mat); + ISL_F_CLR(set, ISL_SET_NORMALIZED); + return set; +error: + isl_set_free(set); + isl_mat_free(mat); + return NULL; +} + +/* Replace the variables x starting at "first_col" in the rows "rows" + * of some coefficient matrix by x' with x = M x' with M the matrix mat. + * That is, replace the corresponding coefficients c by c M. + */ +isl_stat isl_mat_sub_transform(isl_int **row, unsigned n_row, + unsigned first_col, __isl_take isl_mat *mat) +{ + int i; + isl_ctx *ctx; + isl_mat *t; + + if (!mat) + return isl_stat_error; + ctx = isl_mat_get_ctx(mat); + t = isl_mat_sub_alloc6(ctx, row, 0, n_row, first_col, mat->n_row); + t = isl_mat_product(t, mat); + if (!t) + return isl_stat_error; + for (i = 0; i < n_row; ++i) + isl_seq_swp_or_cpy(row[i] + first_col, t->row[i], t->n_col); + isl_mat_free(t); + return isl_stat_ok; +} + +void isl_mat_print_internal(__isl_keep isl_mat *mat, FILE *out, int indent) +{ + int i, j; + + if (!mat) { + fprintf(out, "%*snull mat\n", indent, ""); + return; + } + + if (mat->n_row == 0) + fprintf(out, "%*s[]\n", indent, ""); + + for (i = 0; i < mat->n_row; ++i) { + if (!i) + fprintf(out, "%*s[[", indent, ""); + else + fprintf(out, "%*s[", indent+1, ""); + for (j = 0; j < mat->n_col; ++j) { + if (j) + fprintf(out, ","); + isl_int_print(out, mat->row[i][j], 0); + } + if (i == mat->n_row-1) + fprintf(out, "]]\n"); + else + fprintf(out, "]\n"); + } +} + +void isl_mat_dump(__isl_keep isl_mat *mat) +{ + isl_mat_print_internal(mat, stderr, 0); +} + +__isl_give isl_mat *isl_mat_drop_cols(__isl_take isl_mat *mat, + unsigned col, unsigned n) +{ + int r; + + if (n == 0) + return mat; + + mat = isl_mat_cow(mat); + 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) + isl_seq_cpy(mat->row[r]+col, mat->row[r]+col+n, + mat->n_col - col - n); + } + mat->n_col -= n; + return mat; +} + +__isl_give isl_mat *isl_mat_drop_rows(__isl_take isl_mat *mat, + unsigned row, unsigned n) +{ + int r; + + mat = isl_mat_cow(mat); + 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]; + + mat->n_row -= n; + return mat; +} + +__isl_give isl_mat *isl_mat_insert_cols(__isl_take isl_mat *mat, + unsigned col, unsigned n) +{ + isl_mat *ext; + + if (check_col_range(mat, col, 0) < 0) + return isl_mat_free(mat); + if (n == 0) + return mat; + + ext = isl_mat_alloc(mat->ctx, mat->n_row, mat->n_col + n); + if (!ext) + goto error; + + isl_mat_sub_copy(mat->ctx, ext->row, mat->row, mat->n_row, 0, 0, col); + isl_mat_sub_copy(mat->ctx, ext->row, mat->row, mat->n_row, + col + n, col, mat->n_col - col); + + isl_mat_free(mat); + return ext; +error: + isl_mat_free(mat); + return NULL; +} + +__isl_give isl_mat *isl_mat_insert_zero_cols(__isl_take isl_mat *mat, + unsigned first, unsigned n) +{ + int i; + + if (!mat) + return NULL; + mat = isl_mat_insert_cols(mat, first, n); + if (!mat) + return NULL; + + for (i = 0; i < mat->n_row; ++i) + isl_seq_clr(mat->row[i] + first, n); + + return mat; +} + +__isl_give isl_mat *isl_mat_add_zero_cols(__isl_take isl_mat *mat, unsigned n) +{ + if (!mat) + return NULL; + + return isl_mat_insert_zero_cols(mat, mat->n_col, n); +} + +__isl_give isl_mat *isl_mat_insert_rows(__isl_take isl_mat *mat, + unsigned row, unsigned n) +{ + isl_mat *ext; + + if (check_row_range(mat, row, 0) < 0) + return isl_mat_free(mat); + if (n == 0) + return mat; + + ext = isl_mat_alloc(mat->ctx, mat->n_row + n, mat->n_col); + if (!ext) + goto error; + + isl_mat_sub_copy(mat->ctx, ext->row, mat->row, row, 0, 0, mat->n_col); + isl_mat_sub_copy(mat->ctx, ext->row + row + n, mat->row + row, + mat->n_row - row, 0, 0, mat->n_col); + + isl_mat_free(mat); + return ext; +error: + isl_mat_free(mat); + return NULL; +} + +__isl_give isl_mat *isl_mat_add_rows(__isl_take isl_mat *mat, unsigned n) +{ + if (!mat) + return NULL; + + return isl_mat_insert_rows(mat, mat->n_row, n); +} + +__isl_give isl_mat *isl_mat_insert_zero_rows(__isl_take isl_mat *mat, + unsigned row, unsigned n) +{ + int i; + + mat = isl_mat_insert_rows(mat, row, n); + if (!mat) + return NULL; + + for (i = 0; i < n; ++i) + isl_seq_clr(mat->row[row + i], mat->n_col); + + return mat; +} + +__isl_give isl_mat *isl_mat_add_zero_rows(__isl_take isl_mat *mat, unsigned n) +{ + if (!mat) + return NULL; + + return isl_mat_insert_zero_rows(mat, mat->n_row, n); +} + +void isl_mat_col_submul(__isl_keep isl_mat *mat, + int dst_col, isl_int f, int src_col) +{ + int i; + + for (i = 0; i < mat->n_row; ++i) + isl_int_submul(mat->row[i][dst_col], f, mat->row[i][src_col]); +} + +void isl_mat_col_add(__isl_keep isl_mat *mat, int dst_col, int src_col) +{ + int i; + + if (!mat) + return; + + for (i = 0; i < mat->n_row; ++i) + isl_int_add(mat->row[i][dst_col], + mat->row[i][dst_col], mat->row[i][src_col]); +} + +void isl_mat_col_mul(__isl_keep isl_mat *mat, int dst_col, isl_int f, + int src_col) +{ + int i; + + for (i = 0; i < mat->n_row; ++i) + isl_int_mul(mat->row[i][dst_col], f, mat->row[i][src_col]); +} + +/* Add "f" times column "src_col" to column "dst_col" of "mat" and + * return the result. + */ +__isl_give isl_mat *isl_mat_col_addmul(__isl_take isl_mat *mat, int dst_col, + isl_int f, int src_col) +{ + int i; + + if (check_col(mat, dst_col) < 0 || check_col(mat, src_col) < 0) + return isl_mat_free(mat); + + for (i = 0; i < mat->n_row; ++i) { + if (isl_int_is_zero(mat->row[i][src_col])) + continue; + mat = isl_mat_cow(mat); + if (!mat) + return NULL; + isl_int_addmul(mat->row[i][dst_col], f, mat->row[i][src_col]); + } + + return mat; +} + +/* Negate column "col" of "mat" and return the result. + */ +__isl_give isl_mat *isl_mat_col_neg(__isl_take isl_mat *mat, int col) +{ + int i; + + if (check_col(mat, col) < 0) + return isl_mat_free(mat); + + for (i = 0; i < mat->n_row; ++i) { + if (isl_int_is_zero(mat->row[i][col])) + continue; + mat = isl_mat_cow(mat); + if (!mat) + return NULL; + isl_int_neg(mat->row[i][col], mat->row[i][col]); + } + + return mat; +} + +/* Negate row "row" of "mat" and return the result. + */ +__isl_give isl_mat *isl_mat_row_neg(__isl_take isl_mat *mat, int row) +{ + if (check_row(mat, row) < 0) + return isl_mat_free(mat); + if (isl_seq_first_non_zero(mat->row[row], mat->n_col) == -1) + return mat; + mat = isl_mat_cow(mat); + if (!mat) + return NULL; + isl_seq_neg(mat->row[row], mat->row[row], mat->n_col); + return mat; +} + +__isl_give isl_mat *isl_mat_unimodular_complete(__isl_take isl_mat *M, int row) +{ + int r; + struct isl_mat *H = NULL, *Q = NULL; + + if (!M) + return NULL; + + isl_assert(M->ctx, M->n_row == M->n_col, goto error); + M->n_row = row; + H = isl_mat_left_hermite(isl_mat_copy(M), 0, NULL, &Q); + M->n_row = M->n_col; + if (!H) + goto error; + for (r = 0; r < row; ++r) + isl_assert(M->ctx, isl_int_is_one(H->row[r][r]), goto error); + for (r = row; r < M->n_row; ++r) + isl_seq_cpy(M->row[r], Q->row[r], M->n_col); + isl_mat_free(H); + isl_mat_free(Q); + return M; +error: + isl_mat_free(H); + isl_mat_free(Q); + isl_mat_free(M); + return NULL; +} + +__isl_give isl_mat *isl_mat_concat(__isl_take isl_mat *top, + __isl_take isl_mat *bot) +{ + struct isl_mat *mat; + + if (!top || !bot) + goto error; + + isl_assert(top->ctx, top->n_col == bot->n_col, goto error); + if (top->n_row == 0) { + isl_mat_free(top); + return bot; + } + if (bot->n_row == 0) { + isl_mat_free(bot); + return top; + } + + mat = isl_mat_alloc(top->ctx, top->n_row + bot->n_row, top->n_col); + if (!mat) + goto error; + isl_mat_sub_copy(mat->ctx, mat->row, top->row, top->n_row, + 0, 0, mat->n_col); + isl_mat_sub_copy(mat->ctx, mat->row + top->n_row, bot->row, bot->n_row, + 0, 0, mat->n_col); + isl_mat_free(top); + isl_mat_free(bot); + return mat; +error: + isl_mat_free(top); + isl_mat_free(bot); + return NULL; +} + +isl_bool isl_mat_is_equal(__isl_keep isl_mat *mat1, __isl_keep isl_mat *mat2) +{ + int i; + + if (!mat1 || !mat2) + return isl_bool_error; + + if (mat1->n_row != mat2->n_row) + return isl_bool_false; + + if (mat1->n_col != mat2->n_col) + return isl_bool_false; + + for (i = 0; i < mat1->n_row; ++i) + if (!isl_seq_eq(mat1->row[i], mat2->row[i], mat1->n_col)) + return isl_bool_false; + + return isl_bool_true; +} + +__isl_give isl_mat *isl_mat_from_row_vec(__isl_take isl_vec *vec) +{ + struct isl_mat *mat; + + if (!vec) + return NULL; + mat = isl_mat_alloc(vec->ctx, 1, vec->size); + if (!mat) + goto error; + + isl_seq_cpy(mat->row[0], vec->el, vec->size); + + isl_vec_free(vec); + return mat; +error: + isl_vec_free(vec); + return NULL; +} + +/* Return a copy of row "row" of "mat" as an isl_vec. + */ +__isl_give isl_vec *isl_mat_get_row(__isl_keep isl_mat *mat, unsigned row) +{ + isl_vec *v; + + if (!mat) + return NULL; + if (row >= mat->n_row) + isl_die(mat->ctx, isl_error_invalid, "row out of range", + return NULL); + + v = isl_vec_alloc(isl_mat_get_ctx(mat), mat->n_col); + if (!v) + return NULL; + isl_seq_cpy(v->el, mat->row[row], mat->n_col); + + return v; +} + +__isl_give isl_mat *isl_mat_vec_concat(__isl_take isl_mat *top, + __isl_take isl_vec *bot) +{ + return isl_mat_concat(top, isl_mat_from_row_vec(bot)); +} + +__isl_give isl_mat *isl_mat_move_cols(__isl_take isl_mat *mat, + unsigned dst_col, unsigned src_col, unsigned n) +{ + isl_mat *res; + + if (!mat) + return NULL; + if (n == 0 || dst_col == src_col) + return mat; + + res = isl_mat_alloc(mat->ctx, mat->n_row, mat->n_col); + if (!res) + goto error; + + if (dst_col < src_col) { + isl_mat_sub_copy(res->ctx, res->row, mat->row, mat->n_row, + 0, 0, dst_col); + isl_mat_sub_copy(res->ctx, res->row, mat->row, mat->n_row, + dst_col, src_col, n); + isl_mat_sub_copy(res->ctx, res->row, mat->row, mat->n_row, + dst_col + n, dst_col, src_col - dst_col); + isl_mat_sub_copy(res->ctx, res->row, mat->row, mat->n_row, + src_col + n, src_col + n, + res->n_col - src_col - n); + } else { + isl_mat_sub_copy(res->ctx, res->row, mat->row, mat->n_row, + 0, 0, src_col); + isl_mat_sub_copy(res->ctx, res->row, mat->row, mat->n_row, + src_col, src_col + n, dst_col - src_col); + isl_mat_sub_copy(res->ctx, res->row, mat->row, mat->n_row, + dst_col, src_col, n); + isl_mat_sub_copy(res->ctx, res->row, mat->row, mat->n_row, + dst_col + n, dst_col + n, + res->n_col - dst_col - n); + } + isl_mat_free(mat); + + return res; +error: + isl_mat_free(mat); + return NULL; +} + +/* Return the gcd of the elements in row "row" of "mat" in *gcd. + * Return isl_stat_ok on success and isl_stat_error on failure. + */ +isl_stat isl_mat_row_gcd(__isl_keep isl_mat *mat, int row, isl_int *gcd) +{ + if (check_row(mat, row) < 0) + return isl_stat_error; + + isl_seq_gcd(mat->row[row], mat->n_col, gcd); + + return isl_stat_ok; +} + +void isl_mat_gcd(__isl_keep isl_mat *mat, isl_int *gcd) +{ + int i; + isl_int g; + + isl_int_set_si(*gcd, 0); + if (!mat) + return; + + isl_int_init(g); + for (i = 0; i < mat->n_row; ++i) { + isl_seq_gcd(mat->row[i], mat->n_col, &g); + isl_int_gcd(*gcd, *gcd, g); + } + isl_int_clear(g); +} + +/* Return the result of scaling "mat" by a factor of "m". + */ +__isl_give isl_mat *isl_mat_scale(__isl_take isl_mat *mat, isl_int m) +{ + int i; + + if (isl_int_is_one(m)) + return mat; + + mat = isl_mat_cow(mat); + if (!mat) + return NULL; + + for (i = 0; i < mat->n_row; ++i) + isl_seq_scale(mat->row[i], mat->row[i], m, mat->n_col); + + return mat; +} + +__isl_give isl_mat *isl_mat_scale_down(__isl_take isl_mat *mat, isl_int m) +{ + int i; + + if (isl_int_is_one(m)) + return mat; + + mat = isl_mat_cow(mat); + if (!mat) + return NULL; + + for (i = 0; i < mat->n_row; ++i) + isl_seq_scale_down(mat->row[i], mat->row[i], m, mat->n_col); + + return mat; +} + +__isl_give isl_mat *isl_mat_scale_down_row(__isl_take isl_mat *mat, int row, + isl_int m) +{ + if (isl_int_is_one(m)) + return mat; + + mat = isl_mat_cow(mat); + if (!mat) + return NULL; + + isl_seq_scale_down(mat->row[row], mat->row[row], m, mat->n_col); + + return mat; +} + +__isl_give isl_mat *isl_mat_normalize(__isl_take isl_mat *mat) +{ + isl_int gcd; + + if (!mat) + return NULL; + + isl_int_init(gcd); + isl_mat_gcd(mat, &gcd); + mat = isl_mat_scale_down(mat, gcd); + isl_int_clear(gcd); + + return mat; +} + +__isl_give isl_mat *isl_mat_normalize_row(__isl_take isl_mat *mat, int row) +{ + mat = isl_mat_cow(mat); + if (!mat) + return NULL; + + isl_seq_normalize(mat->ctx, mat->row[row], mat->n_col); + + return mat; +} + +/* Number of initial non-zero columns. + */ +int isl_mat_initial_non_zero_cols(__isl_keep isl_mat *mat) +{ + int i; + + if (!mat) + return -1; + + for (i = 0; i < mat->n_col; ++i) + if (row_first_non_zero(mat->row, mat->n_row, i) < 0) + break; + + 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) +{ + isl_size n_row; + int r1, r; + isl_size 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 (n1 < 0 || !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); + if (n_row < 0) + goto error; + 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) +{ + isl_size 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 isl_bool_ok(r == r1 + r2); +} diff --git a/external/mit/isl/dist/isl_mat_private.h b/external/mit/isl/dist/isl_mat_private.h new file mode 100644 index 000000000000..af760a2ee9da --- /dev/null +++ b/external/mit/isl/dist/isl_mat_private.h @@ -0,0 +1,70 @@ +#ifndef ISL_MAT_PRIVATE_H +#define ISL_MAT_PRIVATE_H + +#include +#include + +struct isl_mat { + int ref; + + struct isl_ctx *ctx; + +#define ISL_MAT_BORROWED (1 << 0) + unsigned flags; + + unsigned n_row; + unsigned n_col; + + isl_int **row; + + /* actual size of the rows in memory; n_col <= max_col */ + unsigned max_col; + + struct isl_blk block; +}; + +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, + unsigned first_row, unsigned n_row, unsigned first_col, unsigned n_col); +void isl_mat_sub_copy(struct isl_ctx *ctx, isl_int **dst, isl_int **src, + unsigned n_row, unsigned dst_col, unsigned src_col, unsigned n_col); +void isl_mat_sub_neg(struct isl_ctx *ctx, isl_int **dst, isl_int **src, + unsigned n_row, unsigned dst_col, unsigned src_col, unsigned n_col); +isl_stat isl_mat_sub_transform(isl_int **row, unsigned n_row, + unsigned first_col, __isl_take isl_mat *mat); +__isl_give isl_mat *isl_mat_diag(isl_ctx *ctx, unsigned n_row, isl_int d); + +__isl_give isl_mat *isl_mat_reverse_gauss(__isl_take isl_mat *mat); + +__isl_give isl_mat *isl_mat_scale(__isl_take isl_mat *mat, isl_int m); +__isl_give isl_mat *isl_mat_scale_down_row(__isl_take isl_mat *mat, int row, + isl_int m); + +__isl_give isl_vec *isl_mat_get_row(__isl_keep isl_mat *mat, unsigned row); + +__isl_give isl_mat *isl_mat_lexnonneg_rows(__isl_take isl_mat *mat); + +isl_bool isl_mat_is_scaled_identity(__isl_keep isl_mat *mat); + +isl_stat isl_mat_row_gcd(__isl_keep isl_mat *mat, int row, isl_int *gcd); + +void isl_mat_col_mul(__isl_keep isl_mat *mat, int dst_col, isl_int f, + int src_col); +void isl_mat_col_submul(__isl_keep isl_mat *mat, + int dst_col, isl_int f, int src_col); +__isl_give isl_mat *isl_mat_col_addmul(__isl_take isl_mat *mat, int dst_col, + isl_int f, int src_col); +__isl_give isl_mat *isl_mat_col_neg(__isl_take isl_mat *mat, int col); +__isl_give isl_mat *isl_mat_row_neg(__isl_take isl_mat *mat, int row); + +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); + +#endif diff --git a/external/mit/isl/dist/isl_maybe_ast_graft_list.h b/external/mit/isl/dist/isl_maybe_ast_graft_list.h new file mode 100644 index 000000000000..14466918aac7 --- /dev/null +++ b/external/mit/isl/dist/isl_maybe_ast_graft_list.h @@ -0,0 +1,10 @@ +#ifndef ISL_MAYBE_AST_GRAFT_LIST_H +#define ISL_MAYBE_AST_GRAFT_LIST_H + +#include "isl_ast_graft_private.h" + +#define ISL_TYPE isl_ast_graft_list +#include +#undef ISL_TYPE + +#endif diff --git a/external/mit/isl/dist/isl_maybe_map.h b/external/mit/isl/dist/isl_maybe_map.h new file mode 100644 index 000000000000..460a89e8a8bf --- /dev/null +++ b/external/mit/isl/dist/isl_maybe_map.h @@ -0,0 +1,10 @@ +#ifndef ISL_MAYBE_MAP_H +#define ISL_MAYBE_MAP_H + +#include + +#define ISL_TYPE isl_map +#include +#undef ISL_TYPE + +#endif diff --git a/external/mit/isl/dist/isl_morph.c b/external/mit/isl/dist/isl_morph.c new file mode 100644 index 000000000000..2b3a3001b36e --- /dev/null +++ b/external/mit/isl/dist/isl_morph.c @@ -0,0 +1,808 @@ +/* + * Copyright 2010-2011 INRIA Saclay + * Copyright 2014 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +isl_ctx *isl_morph_get_ctx(__isl_keep isl_morph *morph) +{ + if (!morph) + return NULL; + return isl_basic_set_get_ctx(morph->dom); +} + +__isl_give isl_morph *isl_morph_alloc( + __isl_take isl_basic_set *dom, __isl_take isl_basic_set *ran, + __isl_take isl_mat *map, __isl_take isl_mat *inv) +{ + isl_morph *morph; + + if (!dom || !ran || !map || !inv) + goto error; + + morph = isl_alloc_type(dom->ctx, struct isl_morph); + if (!morph) + goto error; + + morph->ref = 1; + morph->dom = dom; + morph->ran = ran; + morph->map = map; + morph->inv = inv; + + return morph; +error: + isl_basic_set_free(dom); + isl_basic_set_free(ran); + isl_mat_free(map); + isl_mat_free(inv); + return NULL; +} + +__isl_give isl_morph *isl_morph_copy(__isl_keep isl_morph *morph) +{ + if (!morph) + return NULL; + + morph->ref++; + return morph; +} + +__isl_give isl_morph *isl_morph_dup(__isl_keep isl_morph *morph) +{ + if (!morph) + return NULL; + + return isl_morph_alloc(isl_basic_set_copy(morph->dom), + isl_basic_set_copy(morph->ran), + isl_mat_copy(morph->map), isl_mat_copy(morph->inv)); +} + +__isl_give isl_morph *isl_morph_cow(__isl_take isl_morph *morph) +{ + if (!morph) + return NULL; + + if (morph->ref == 1) + return morph; + morph->ref--; + return isl_morph_dup(morph); +} + +__isl_null isl_morph *isl_morph_free(__isl_take isl_morph *morph) +{ + if (!morph) + return NULL; + + if (--morph->ref > 0) + return NULL; + + isl_basic_set_free(morph->dom); + isl_basic_set_free(morph->ran); + isl_mat_free(morph->map); + isl_mat_free(morph->inv); + free(morph); + + return NULL; +} + +/* Is "morph" an identity on the parameters? + */ +static isl_bool identity_on_parameters(__isl_keep isl_morph *morph) +{ + isl_bool is_identity; + isl_size nparam, nparam_ran; + isl_mat *sub; + + nparam = isl_morph_dom_dim(morph, isl_dim_param); + nparam_ran = isl_morph_ran_dim(morph, isl_dim_param); + if (nparam < 0 || nparam_ran < 0) + return isl_bool_error; + if (nparam != nparam_ran) + return isl_bool_false; + if (nparam == 0) + return isl_bool_true; + sub = isl_mat_sub_alloc(morph->map, 0, 1 + nparam, 0, 1 + nparam); + is_identity = isl_mat_is_scaled_identity(sub); + isl_mat_free(sub); + + return is_identity; +} + +/* Return an affine expression of the variables of the range of "morph" + * in terms of the parameters and the variables of the domain on "morph". + * + * In order for the space manipulations to make sense, we require + * that the parameters are not modified by "morph". + */ +__isl_give isl_multi_aff *isl_morph_get_var_multi_aff( + __isl_keep isl_morph *morph) +{ + isl_space *dom, *ran, *space; + isl_local_space *ls; + isl_multi_aff *ma; + isl_size nparam, nvar; + int i; + isl_bool is_identity; + + if (!morph) + return NULL; + + is_identity = identity_on_parameters(morph); + if (is_identity < 0) + return NULL; + if (!is_identity) + isl_die(isl_morph_get_ctx(morph), isl_error_invalid, + "cannot handle parameter compression", return NULL); + + dom = isl_morph_get_dom_space(morph); + ls = isl_local_space_from_space(isl_space_copy(dom)); + ran = isl_morph_get_ran_space(morph); + space = isl_space_map_from_domain_and_range(dom, ran); + ma = isl_multi_aff_zero(space); + + nparam = isl_multi_aff_dim(ma, isl_dim_param); + nvar = isl_multi_aff_dim(ma, isl_dim_out); + if (nparam < 0 || nvar < 0) + ma = isl_multi_aff_free(ma); + for (i = 0; i < nvar; ++i) { + isl_val *val; + isl_vec *v; + isl_aff *aff; + + v = isl_mat_get_row(morph->map, 1 + nparam + i); + v = isl_vec_insert_els(v, 0, 1); + val = isl_mat_get_element_val(morph->map, 0, 0); + v = isl_vec_set_element_val(v, 0, val); + aff = isl_aff_alloc_vec(isl_local_space_copy(ls), v); + ma = isl_multi_aff_set_aff(ma, i, aff); + } + + isl_local_space_free(ls); + return ma; +} + +/* Return the domain space of "morph". + */ +static __isl_keep isl_space *isl_morph_peek_dom_space( + __isl_keep isl_morph *morph) +{ + if (!morph) + return NULL; + + return isl_basic_set_peek_space(morph->dom); +} + +/* Return a copy of the domain space of "morph". + */ +__isl_give isl_space *isl_morph_get_dom_space(__isl_keep isl_morph *morph) +{ + return isl_space_copy(isl_morph_peek_dom_space(morph)); +} + +/* Check that the match against "space" with result "match" was successful. + */ +static isl_stat check_space_match(__isl_keep isl_space *space, isl_bool match) +{ + if (match < 0) + return isl_stat_error; + if (!match) + isl_die(isl_space_get_ctx(space), isl_error_invalid, + "spaces don't match", return isl_stat_error); + + return isl_stat_ok; +} + +/* Check that "morph" can be applied to the "space". + */ +isl_stat isl_morph_check_applies(__isl_keep isl_morph *morph, + __isl_keep isl_space *space) +{ + isl_space *dom_space; + isl_bool applies; + + dom_space = isl_morph_peek_dom_space(morph); + applies = isl_space_is_equal(dom_space, space); + return check_space_match(space, applies); +} + +__isl_give isl_space *isl_morph_get_ran_space(__isl_keep isl_morph *morph) +{ + if (!morph) + return NULL; + + return isl_space_copy(morph->ran->dim); +} + +isl_size isl_morph_dom_dim(__isl_keep isl_morph *morph, enum isl_dim_type type) +{ + if (!morph) + return isl_size_error; + + return isl_basic_set_dim(morph->dom, type); +} + +isl_size isl_morph_ran_dim(__isl_keep isl_morph *morph, enum isl_dim_type type) +{ + if (!morph) + return isl_size_error; + + return isl_basic_set_dim(morph->ran, type); +} + +__isl_give isl_morph *isl_morph_remove_dom_dims(__isl_take isl_morph *morph, + enum isl_dim_type type, unsigned first, unsigned n) +{ + isl_size dom_offset; + + if (n == 0) + return morph; + + morph = isl_morph_cow(morph); + if (!morph) + return NULL; + + dom_offset = isl_space_offset(morph->dom->dim, type); + if (dom_offset < 0) + return isl_morph_free(morph); + + morph->dom = isl_basic_set_remove_dims(morph->dom, type, first, n); + + morph->map = isl_mat_drop_cols(morph->map, 1 + dom_offset + first, n); + + morph->inv = isl_mat_drop_rows(morph->inv, 1 + dom_offset + first, n); + + if (morph->dom && morph->ran && morph->map && morph->inv) + return morph; + + isl_morph_free(morph); + return NULL; +} + +__isl_give isl_morph *isl_morph_remove_ran_dims(__isl_take isl_morph *morph, + enum isl_dim_type type, unsigned first, unsigned n) +{ + isl_size ran_offset; + + if (n == 0) + return morph; + + morph = isl_morph_cow(morph); + if (!morph) + return NULL; + + ran_offset = isl_space_offset(morph->ran->dim, type); + if (ran_offset < 0) + return isl_morph_free(morph); + + morph->ran = isl_basic_set_remove_dims(morph->ran, type, first, n); + + morph->map = isl_mat_drop_rows(morph->map, 1 + ran_offset + first, n); + + morph->inv = isl_mat_drop_cols(morph->inv, 1 + ran_offset + first, n); + + if (morph->dom && morph->ran && morph->map && morph->inv) + return morph; + + isl_morph_free(morph); + return NULL; +} + +/* Project domain of morph onto its parameter domain. + */ +__isl_give isl_morph *isl_morph_dom_params(__isl_take isl_morph *morph) +{ + isl_size n; + + morph = isl_morph_cow(morph); + if (!morph) + return NULL; + n = isl_basic_set_dim(morph->dom, isl_dim_set); + if (n < 0) + return isl_morph_free(morph); + morph = isl_morph_remove_dom_dims(morph, isl_dim_set, 0, n); + if (!morph) + return NULL; + morph->dom = isl_basic_set_params(morph->dom); + if (morph->dom) + return morph; + + isl_morph_free(morph); + return NULL; +} + +/* Project range of morph onto its parameter domain. + */ +__isl_give isl_morph *isl_morph_ran_params(__isl_take isl_morph *morph) +{ + isl_size n; + + morph = isl_morph_cow(morph); + if (!morph) + return NULL; + n = isl_basic_set_dim(morph->ran, isl_dim_set); + if (n < 0) + return isl_morph_free(morph); + morph = isl_morph_remove_ran_dims(morph, isl_dim_set, 0, n); + if (!morph) + return NULL; + morph->ran = isl_basic_set_params(morph->ran); + if (morph->ran) + return morph; + + isl_morph_free(morph); + return NULL; +} + +/* Replace the identifier of the tuple of the range of the morph by "id". + */ +static __isl_give isl_morph *isl_morph_set_ran_tuple_id( + __isl_take isl_morph *morph, __isl_keep isl_id *id) +{ + morph = isl_morph_cow(morph); + if (!morph) + return NULL; + morph->ran = isl_basic_set_set_tuple_id(morph->ran, isl_id_copy(id)); + if (!morph->ran) + return isl_morph_free(morph); + return morph; +} + +void isl_morph_print_internal(__isl_take isl_morph *morph, FILE *out) +{ + if (!morph) + return; + + isl_basic_set_dump(morph->dom); + isl_basic_set_dump(morph->ran); + isl_mat_print_internal(morph->map, out, 4); + isl_mat_print_internal(morph->inv, out, 4); +} + +void isl_morph_dump(__isl_take isl_morph *morph) +{ + isl_morph_print_internal(morph, stderr); +} + +__isl_give isl_morph *isl_morph_identity(__isl_keep isl_basic_set *bset) +{ + isl_mat *id; + isl_basic_set *universe; + isl_size total; + + total = isl_basic_set_dim(bset, isl_dim_all); + if (total < 0) + return NULL; + + id = isl_mat_identity(bset->ctx, 1 + total); + universe = isl_basic_set_universe(isl_space_copy(bset->dim)); + + return isl_morph_alloc(universe, isl_basic_set_copy(universe), + id, isl_mat_copy(id)); +} + +/* Create a(n identity) morphism between empty sets of the same dimension + * a "bset". + */ +__isl_give isl_morph *isl_morph_empty(__isl_keep isl_basic_set *bset) +{ + isl_mat *id; + isl_basic_set *empty; + isl_size total; + + total = isl_basic_set_dim(bset, isl_dim_all); + if (total < 0) + return NULL; + + id = isl_mat_identity(bset->ctx, 1 + total); + empty = isl_basic_set_empty(isl_space_copy(bset->dim)); + + return isl_morph_alloc(empty, isl_basic_set_copy(empty), + id, isl_mat_copy(id)); +} + +/* Construct a basic set described by the "n" equalities of "bset" starting + * at "first". + */ +static __isl_give isl_basic_set *copy_equalities(__isl_keep isl_basic_set *bset, + unsigned first, unsigned n) +{ + int i, k; + isl_basic_set *eq; + isl_size total; + + total = isl_basic_set_dim(bset, isl_dim_all); + if (total < 0 || isl_basic_set_check_no_locals(bset) < 0) + return NULL; + + eq = isl_basic_set_alloc_space(isl_basic_set_get_space(bset), 0, n, 0); + if (!eq) + return NULL; + for (i = 0; i < n; ++i) { + k = isl_basic_set_alloc_equality(eq); + if (k < 0) + goto error; + isl_seq_cpy(eq->eq[k], bset->eq[first + i], 1 + total); + } + + return eq; +error: + isl_basic_set_free(eq); + return NULL; +} + +/* Given a basic set, exploit the equalities in the basic set to construct + * a morphism that maps the basic set to a lower-dimensional space. + * Specifically, the morphism reduces the number of dimensions of type "type". + * + * We first select the equalities of interest, that is those that involve + * variables of type "type" and no later variables. + * Denote those equalities as + * + * -C(p) + M x = 0 + * + * where C(p) depends on the parameters if type == isl_dim_set and + * is a constant if type == isl_dim_param. + * + * Use isl_mat_final_variable_compression to construct a compression + * + * x = T x' + * + * x' = Q x + * + * If T is a zero-column matrix, then the set of equality constraints + * do not admit a solution. In this case, an empty morphism is returned. + * + * Both matrices are extended to map the full original space to the full + * compressed space. + */ +__isl_give isl_morph *isl_basic_set_variable_compression( + __isl_keep isl_basic_set *bset, enum isl_dim_type type) +{ + unsigned otype; + isl_size ntype; + unsigned orest; + unsigned nrest; + isl_size total; + int f_eq, n_eq; + isl_space *space; + isl_mat *E, *Q, *C; + isl_basic_set *dom, *ran; + + if (!bset) + return NULL; + + if (isl_basic_set_plain_is_empty(bset)) + return isl_morph_empty(bset); + + if (isl_basic_set_check_no_locals(bset) < 0) + return NULL; + + ntype = isl_basic_set_dim(bset, type); + total = isl_basic_set_dim(bset, isl_dim_all); + if (ntype < 0 || total < 0) + return NULL; + otype = isl_basic_set_offset(bset, type); + orest = otype + ntype; + nrest = total - (orest - 1); + + for (f_eq = 0; f_eq < bset->n_eq; ++f_eq) + if (isl_seq_first_non_zero(bset->eq[f_eq] + orest, nrest) == -1) + break; + for (n_eq = 0; f_eq + n_eq < bset->n_eq; ++n_eq) + if (isl_seq_first_non_zero(bset->eq[f_eq + n_eq] + otype, ntype) == -1) + break; + if (n_eq == 0) + return isl_morph_identity(bset); + + E = isl_mat_sub_alloc6(bset->ctx, bset->eq, f_eq, n_eq, 0, orest); + C = isl_mat_final_variable_compression(E, otype - 1, &Q); + if (!Q) + C = isl_mat_free(C); + if (C && C->n_col == 0) { + isl_mat_free(C); + isl_mat_free(Q); + return isl_morph_empty(bset); + } + + Q = isl_mat_diagonal(Q, isl_mat_identity(bset->ctx, nrest)); + C = isl_mat_diagonal(C, isl_mat_identity(bset->ctx, nrest)); + + space = isl_space_copy(bset->dim); + space = isl_space_drop_dims(space, type, 0, ntype); + space = isl_space_add_dims(space, type, ntype - n_eq); + ran = isl_basic_set_universe(space); + dom = copy_equalities(bset, f_eq, n_eq); + + return isl_morph_alloc(dom, ran, Q, C); +} + +/* Given a basic set, exploit the equalities in the basic set to construct + * a morphism that maps the basic set to a lower-dimensional space + * with identifier "id". + * Specifically, the morphism reduces the number of set dimensions. + */ +__isl_give isl_morph *isl_basic_set_variable_compression_with_id( + __isl_keep isl_basic_set *bset, __isl_keep isl_id *id) +{ + isl_morph *morph; + + morph = isl_basic_set_variable_compression(bset, isl_dim_set); + morph = isl_morph_set_ran_tuple_id(morph, id); + return morph; +} + +/* Construct a parameter compression for "bset". + * We basically just call isl_mat_parameter_compression with the right input + * and then extend the resulting matrix to include the variables. + * + * The implementation assumes that "bset" does not have any equalities + * that only involve the parameters and that isl_basic_set_gauss has + * been applied to "bset". + * + * Let the equalities be given as + * + * B(p) + A x = 0. + * + * We use isl_mat_parameter_compression_ext to compute the compression + * + * p = T p'. + */ +__isl_give isl_morph *isl_basic_set_parameter_compression( + __isl_keep isl_basic_set *bset) +{ + isl_size nparam; + isl_size nvar; + isl_size n_div; + int n_eq; + isl_mat *H, *B; + isl_mat *map, *inv; + isl_basic_set *dom, *ran; + + if (!bset) + return NULL; + + if (isl_basic_set_plain_is_empty(bset)) + return isl_morph_empty(bset); + if (bset->n_eq == 0) + return isl_morph_identity(bset); + + n_eq = bset->n_eq; + nparam = isl_basic_set_dim(bset, isl_dim_param); + nvar = isl_basic_set_dim(bset, isl_dim_set); + n_div = isl_basic_set_dim(bset, isl_dim_div); + if (nparam < 0 || nvar < 0 || n_div < 0) + return NULL; + + if (isl_seq_first_non_zero(bset->eq[bset->n_eq - 1] + 1 + nparam, + nvar + n_div) == -1) + isl_die(isl_basic_set_get_ctx(bset), isl_error_invalid, + "input not allowed to have parameter equalities", + return NULL); + if (n_eq > nvar + n_div) + isl_die(isl_basic_set_get_ctx(bset), isl_error_invalid, + "input not gaussed", return NULL); + + B = isl_mat_sub_alloc6(bset->ctx, bset->eq, 0, n_eq, 0, 1 + nparam); + H = isl_mat_sub_alloc6(bset->ctx, bset->eq, + 0, n_eq, 1 + nparam, nvar + n_div); + inv = isl_mat_parameter_compression_ext(B, H); + inv = isl_mat_diagonal(inv, isl_mat_identity(bset->ctx, nvar)); + map = isl_mat_right_inverse(isl_mat_copy(inv)); + + dom = isl_basic_set_universe(isl_space_copy(bset->dim)); + ran = isl_basic_set_universe(isl_space_copy(bset->dim)); + + return isl_morph_alloc(dom, ran, map, inv); +} + +/* Construct an isl_multi_aff that corresponds + * to the affine transformation matrix "mat" and + * that lives in an anonymous space. + */ +static __isl_give isl_multi_aff *isl_multi_aff_from_aff_mat_anonymous( + __isl_take isl_mat *mat) +{ + isl_size n_row, n_col; + isl_ctx *ctx; + isl_space *space; + + ctx = isl_mat_get_ctx(mat); + n_row = isl_mat_rows(mat); + n_col = isl_mat_cols(mat); + if (n_row < 0 || n_col < 0) + space = NULL; + else + space = isl_space_alloc(ctx, 0, n_col - 1, n_row - 1); + + return isl_multi_aff_from_aff_mat(space, mat); +} + +/* Apply the morphism to the basic set. + * In particular, compute the preimage of "bset" under the inverse mapping + * in morph and intersect with the range of the morphism. + * Note that the mapping in morph applies to both parameters and set dimensions, + * so the parameters need to be treated as set dimensions during the call + * to isl_basic_set_preimage_multi_aff. + */ +__isl_give isl_basic_set *isl_morph_basic_set(__isl_take isl_morph *morph, + __isl_take isl_basic_set *bset) +{ + isl_size n_param; + isl_space *space; + isl_multi_aff *ma; + + if (!morph || isl_basic_set_check_equal_space(bset, morph->dom) < 0) + goto error; + n_param = isl_basic_set_dim(morph->dom, isl_dim_param); + if (n_param < 0) + goto error; + + ma = isl_multi_aff_from_aff_mat_anonymous(isl_mat_copy(morph->inv)); + + bset = isl_basic_set_move_dims(bset, isl_dim_set, 0, + isl_dim_param, 0, n_param); + bset = isl_basic_set_preimage_multi_aff(bset, ma); + space = isl_basic_set_get_space(morph->ran); + bset = isl_basic_set_reset_space(bset, space); + bset = isl_basic_set_intersect(bset, isl_basic_set_copy(morph->ran)); + + isl_morph_free(morph); + return bset; +error: + isl_morph_free(morph); + isl_basic_set_free(bset); + return NULL; +} + +/* Apply the morphism to the set. + * In particular, compute the preimage of "set" under the inverse mapping + * in morph and intersect with the range of the morphism. + * Note that the mapping in morph applies to both parameters and set dimensions, + * so the parameters need to be treated as set dimensions during the call + * to isl_set_preimage_multi_aff. + */ +__isl_give isl_set *isl_morph_set(__isl_take isl_morph *morph, + __isl_take isl_set *set) +{ + isl_size n_param; + isl_space *space; + isl_multi_aff *ma; + isl_basic_set *ran; + + if (!morph || isl_set_basic_set_check_equal_space(set, morph->dom) < 0) + goto error; + n_param = isl_basic_set_dim(morph->dom, isl_dim_param); + if (n_param < 0) + goto error; + + ma = isl_multi_aff_from_aff_mat_anonymous(isl_mat_copy(morph->inv)); + + set = isl_set_move_dims(set, isl_dim_set, 0, isl_dim_param, 0, n_param); + set = isl_set_preimage_multi_aff(set, ma); + space = isl_basic_set_get_space(morph->ran); + set = isl_set_reset_space(set, space); + ran = isl_basic_set_copy(morph->ran); + set = isl_set_intersect(set, isl_set_from_basic_set(ran)); + + isl_morph_free(morph); + return set; +error: + isl_set_free(set); + isl_morph_free(morph); + return NULL; +} + +/* Construct a morphism that first does morph2 and then morph1. + */ +__isl_give isl_morph *isl_morph_compose(__isl_take isl_morph *morph1, + __isl_take isl_morph *morph2) +{ + isl_mat *map, *inv; + isl_basic_set *dom, *ran; + + if (!morph1 || !morph2) + goto error; + + map = isl_mat_product(isl_mat_copy(morph1->map), isl_mat_copy(morph2->map)); + inv = isl_mat_product(isl_mat_copy(morph2->inv), isl_mat_copy(morph1->inv)); + dom = isl_morph_basic_set(isl_morph_inverse(isl_morph_copy(morph2)), + isl_basic_set_copy(morph1->dom)); + dom = isl_basic_set_intersect(dom, isl_basic_set_copy(morph2->dom)); + ran = isl_morph_basic_set(isl_morph_copy(morph1), + isl_basic_set_copy(morph2->ran)); + ran = isl_basic_set_intersect(ran, isl_basic_set_copy(morph1->ran)); + + isl_morph_free(morph1); + isl_morph_free(morph2); + + return isl_morph_alloc(dom, ran, map, inv); +error: + isl_morph_free(morph1); + isl_morph_free(morph2); + return NULL; +} + +__isl_give isl_morph *isl_morph_inverse(__isl_take isl_morph *morph) +{ + isl_basic_set *bset; + isl_mat *mat; + + morph = isl_morph_cow(morph); + if (!morph) + return NULL; + + bset = morph->dom; + morph->dom = morph->ran; + morph->ran = bset; + + mat = morph->map; + morph->map = morph->inv; + morph->inv = mat; + + return morph; +} + +/* We detect all the equalities first to avoid implicit equalities + * being discovered during the computations. In particular, + * the compression on the variables could expose additional stride + * constraints on the parameters. This would result in existentially + * quantified variables after applying the resulting morph, which + * in turn could break invariants of the calling functions. + */ +__isl_give isl_morph *isl_basic_set_full_compression( + __isl_keep isl_basic_set *bset) +{ + isl_morph *morph, *morph2; + + bset = isl_basic_set_copy(bset); + bset = isl_basic_set_detect_equalities(bset); + + morph = isl_basic_set_variable_compression(bset, isl_dim_param); + bset = isl_morph_basic_set(isl_morph_copy(morph), bset); + + morph2 = isl_basic_set_parameter_compression(bset); + bset = isl_morph_basic_set(isl_morph_copy(morph2), bset); + + morph = isl_morph_compose(morph2, morph); + + morph2 = isl_basic_set_variable_compression(bset, isl_dim_set); + isl_basic_set_free(bset); + + morph = isl_morph_compose(morph2, morph); + + return morph; +} + +__isl_give isl_vec *isl_morph_vec(__isl_take isl_morph *morph, + __isl_take isl_vec *vec) +{ + if (!morph) + goto error; + + vec = isl_mat_vec_product(isl_mat_copy(morph->map), vec); + + isl_morph_free(morph); + return vec; +error: + isl_morph_free(morph); + isl_vec_free(vec); + return NULL; +} diff --git a/external/mit/isl/dist/isl_morph.h b/external/mit/isl/dist/isl_morph.h new file mode 100644 index 000000000000..004e148946dc --- /dev/null +++ b/external/mit/isl/dist/isl_morph.h @@ -0,0 +1,92 @@ +/* + * Copyright 2010 INRIA Saclay + * + * 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 + */ + +#ifndef ISL_MORHP_H +#define ISL_MORHP_H + +#include +#include +#include +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +/* An isl_morph is a "morphism" on (basic) sets. + * "map" is an affine mapping from "dom" to "ran" + * and "inv" is the inverse mapping. + */ +struct isl_morph { + int ref; + + isl_basic_set *dom; + isl_basic_set *ran; + + isl_mat *map; + isl_mat *inv; +}; +typedef struct isl_morph isl_morph; + +isl_ctx *isl_morph_get_ctx(__isl_keep isl_morph *morph); + +__isl_give isl_morph *isl_morph_alloc( + __isl_take isl_basic_set *dom, __isl_take isl_basic_set *ran, + __isl_take isl_mat *map, __isl_take isl_mat *inv); +__isl_give isl_morph *isl_morph_copy(__isl_keep isl_morph *morph); +__isl_give isl_morph *isl_morph_identity(__isl_keep isl_basic_set *bset); +__isl_null isl_morph *isl_morph_free(__isl_take isl_morph *morph); + +isl_stat isl_morph_check_applies(__isl_keep isl_morph *morph, + __isl_keep isl_space *space); + +__isl_give isl_space *isl_morph_get_dom_space(__isl_keep isl_morph *morph); +__isl_give isl_space *isl_morph_get_ran_space(__isl_keep isl_morph *morph); +__isl_give isl_multi_aff *isl_morph_get_var_multi_aff( + __isl_keep isl_morph *morph); +isl_size isl_morph_dom_dim(__isl_keep isl_morph *morph, enum isl_dim_type type); +isl_size isl_morph_ran_dim(__isl_keep isl_morph *morph, enum isl_dim_type type); + +__isl_give isl_morph *isl_morph_remove_dom_dims(__isl_take isl_morph *morph, + enum isl_dim_type type, unsigned first, unsigned n); +__isl_give isl_morph *isl_morph_remove_ran_dims(__isl_take isl_morph *morph, + enum isl_dim_type type, unsigned first, unsigned n); +__isl_give isl_morph *isl_morph_dom_params(__isl_take isl_morph *morph); +__isl_give isl_morph *isl_morph_ran_params(__isl_take isl_morph *morph); + +__isl_give isl_morph *isl_morph_compose(__isl_take isl_morph *morph1, + __isl_take isl_morph *morph2); +__isl_give isl_morph *isl_morph_inverse(__isl_take isl_morph *morph); + +void isl_morph_print_internal(__isl_take isl_morph *morph, FILE *out); +void isl_morph_dump(__isl_take isl_morph *morph); + +__isl_give isl_morph *isl_basic_set_variable_compression( + __isl_keep isl_basic_set *bset, enum isl_dim_type type); +__isl_give isl_morph *isl_basic_set_variable_compression_with_id( + __isl_keep isl_basic_set *bset, __isl_keep isl_id *id); +__isl_give isl_morph *isl_basic_set_parameter_compression( + __isl_keep isl_basic_set *bset); +__isl_give isl_morph *isl_basic_set_full_compression( + __isl_keep isl_basic_set *bset); + +__isl_give isl_basic_set *isl_morph_basic_set(__isl_take isl_morph *morph, + __isl_take isl_basic_set *bset); +__isl_give isl_set *isl_morph_set(__isl_take isl_morph *morph, + __isl_take isl_set *set); +__isl_give isl_vec *isl_morph_vec(__isl_take isl_morph *morph, + __isl_take isl_vec *vec); + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/external/mit/isl/dist/isl_multi_add_constant_templ.c b/external/mit/isl/dist/isl_multi_add_constant_templ.c new file mode 100644 index 000000000000..a54f3fa72011 --- /dev/null +++ b/external/mit/isl/dist/isl_multi_add_constant_templ.c @@ -0,0 +1,57 @@ +/* + * Copyright 2019 Cerebras Systems + * + * Use of this software is governed by the MIT license + * + * Written by Sven Verdoolaege, + * Cerebras Systems, 175 S San Antonio Rd, Los Altos, CA, USA + */ + +#include + +/* Add "v" to the constant terms of all the base expressions of "multi". + */ +__isl_give MULTI(BASE) *FN(MULTI(BASE),add_constant_val)( + __isl_take MULTI(BASE) *multi, __isl_take isl_val *v) +{ + isl_bool zero; + + zero = isl_val_is_zero(v); + if (zero < 0) + goto error; + if (zero) { + isl_val_free(v); + return multi; + } + + return FN(MULTI(BASE),fn_val)(multi, &FN(EL,add_constant_val), v); +error: + FN(MULTI(BASE),free)(multi); + isl_val_free(v); + return NULL; +} + +/* Add the elements of "mv" to the constant terms of + * the corresponding base expressions of "multi". + */ +__isl_give MULTI(BASE) *FN(MULTI(BASE),add_constant_multi_val)( + __isl_take MULTI(BASE) *multi, __isl_take isl_multi_val *mv) +{ + isl_bool zero; + + zero = isl_multi_val_is_zero(mv); + if (zero < 0) + goto error; + if (zero) { + isl_multi_val_free(mv); + return multi; + } + + return FN(MULTI(BASE),fn_multi_val)(multi, &FN(EL,add_constant_val), + mv); + +error: + FN(MULTI(BASE),free)(multi); + isl_multi_val_free(mv); + return NULL; +} diff --git a/external/mit/isl/dist/isl_multi_align_set.c b/external/mit/isl/dist/isl_multi_align_set.c new file mode 100644 index 000000000000..e57b8ad44625 --- /dev/null +++ b/external/mit/isl/dist/isl_multi_align_set.c @@ -0,0 +1,8 @@ +#undef SUFFIX +#define SUFFIX set +#undef ARG1 +#define ARG1 MULTI(BASE) +#undef ARG2 +#define ARG2 isl_set + +#include "isl_align_params_templ.c" diff --git a/external/mit/isl/dist/isl_multi_align_union_set.c b/external/mit/isl/dist/isl_multi_align_union_set.c new file mode 100644 index 000000000000..ac42fa715908 --- /dev/null +++ b/external/mit/isl/dist/isl_multi_align_union_set.c @@ -0,0 +1,8 @@ +#undef SUFFIX +#define SUFFIX union_set +#undef ARG1 +#define ARG1 MULTI(BASE) +#undef ARG2 +#define ARG2 isl_union_set + +#include "isl_align_params_templ.c" diff --git a/external/mit/isl/dist/isl_multi_apply_explicit_domain_templ.c b/external/mit/isl/dist/isl_multi_apply_explicit_domain_templ.c new file mode 100644 index 000000000000..094329862f5f --- /dev/null +++ b/external/mit/isl/dist/isl_multi_apply_explicit_domain_templ.c @@ -0,0 +1,38 @@ +/* + * Copyright 2017 Sven Verdoolaege + * + * Use of this software is governed by the MIT license + * + * Written by Sven Verdoolaege. + */ + +/* Transform the explicit domain of "multi" by applying "fn_domain" or + * "fn_params" to it with extra argument "domain". + * In particular, if the explicit domain is a parameter set, + * then apply "fn_params". Otherwise, apply "fn_domain". + * + * The parameters of "multi" and "domain" are assumed to have been aligned. + */ +static __isl_give MULTI(BASE) *FN(FN(MULTI(BASE),apply_domain),APPLY_DOMBASE)( + __isl_take MULTI(BASE) *multi, __isl_take APPLY_DOM *domain, + __isl_give DOM *(*fn_domain)(DOM *domain, __isl_take APPLY_DOM *set), + __isl_give DOM *(*fn_params)(DOM *domain, __isl_take APPLY_DOM *set)) +{ + isl_bool is_params; + DOM *multi_dom; + + multi_dom = FN(MULTI(BASE),get_explicit_domain)(multi); + is_params = FN(DOM,is_params)(multi_dom); + if (is_params < 0) { + FN(APPLY_DOM,free)(domain); + multi_dom = FN(DOM,free)(multi_dom); + } else if (!is_params) { + multi_dom = fn_domain(multi_dom, domain); + } else { + multi_dom = fn_params(multi_dom, domain); + } + multi = FN(MULTI(BASE),set_explicit_domain)(multi, multi_dom); + return multi; +} + +#include diff --git a/external/mit/isl/dist/isl_multi_apply_no_explicit_domain_templ.c b/external/mit/isl/dist/isl_multi_apply_no_explicit_domain_templ.c new file mode 100644 index 000000000000..56876efab63e --- /dev/null +++ b/external/mit/isl/dist/isl_multi_apply_no_explicit_domain_templ.c @@ -0,0 +1,29 @@ +/* + * Copyright 2022 Cerebras Systems + * + * Use of this software is governed by the MIT license + * + * Written by Sven Verdoolaege, + * Cerebras Systems, 1237 E Arques Ave, Sunnyvale, CA, USA + */ + +/* Transform the explicit domain of "multi" by applying "fn_domain" or + * "fn_params" to it with extra argument "domain". + * In particular, if the explicit domain is a parameter set, + * then apply "fn_params". Otherwise, apply "fn_domain". + * + * Do this for a type MULTI(BASE) that cannot have an explicit domain. + * That is, this function is never called. + */ + +static __isl_give MULTI(BASE) *FN(FN(MULTI(BASE),apply_domain),APPLY_DOMBASE)( + __isl_take MULTI(BASE) *multi, __isl_take isl_set *domain, + __isl_give DOM *(*fn_domain)(DOM *domain, __isl_take APPLY_DOM *set), + __isl_give DOM *(*fn_params)(DOM *domain, __isl_take isl_set *set)) +{ + isl_set_free(domain); + + return multi; +} + +#include diff --git a/external/mit/isl/dist/isl_multi_apply_set_explicit_domain_templ.c b/external/mit/isl/dist/isl_multi_apply_set_explicit_domain_templ.c new file mode 100644 index 000000000000..7a28bca65abf --- /dev/null +++ b/external/mit/isl/dist/isl_multi_apply_set_explicit_domain_templ.c @@ -0,0 +1,7 @@ +#define APPLY_DOMBASE set +#define APPLY_DOM isl_set + +#include + +#undef APPLY_DOMBASE +#undef APPLY_DOM diff --git a/external/mit/isl/dist/isl_multi_apply_set_no_explicit_domain_templ.c b/external/mit/isl/dist/isl_multi_apply_set_no_explicit_domain_templ.c new file mode 100644 index 000000000000..374f7b0feb86 --- /dev/null +++ b/external/mit/isl/dist/isl_multi_apply_set_no_explicit_domain_templ.c @@ -0,0 +1,7 @@ +#define APPLY_DOMBASE set +#define APPLY_DOM isl_set + +#include + +#undef APPLY_DOMBASE +#undef APPLY_DOM diff --git a/external/mit/isl/dist/isl_multi_apply_templ.c b/external/mit/isl/dist/isl_multi_apply_templ.c new file mode 100644 index 000000000000..9eecfbcc3ed1 --- /dev/null +++ b/external/mit/isl/dist/isl_multi_apply_templ.c @@ -0,0 +1,53 @@ +/* + * 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 + +/* Transform the elements of "multi" by applying "fn" to them + * with extra argument "set". + * If "multi" has an explicit domain, then apply "fn_domain" or + * "fn_params" to this explicit domain instead. + * In particular, if the explicit domain is a parameter set, + * then apply "fn_params". Otherwise, apply "fn_domain". + */ +static __isl_give MULTI(BASE) *FN(FN(MULTI(BASE),apply),APPLY_DOMBASE)( + __isl_take MULTI(BASE) *multi, __isl_take APPLY_DOM *set, + __isl_give EL *(*fn)(EL *el, __isl_take APPLY_DOM *set), + __isl_give DOM *(*fn_domain)(DOM *domain, __isl_take APPLY_DOM *set), + __isl_give DOM *(*fn_params)(DOM *domain, __isl_take APPLY_DOM *set)) +{ + isl_size n; + int i; + + FN(FN(MULTI(BASE),align_params),APPLY_DOMBASE)(&multi, &set); + + if (FN(MULTI(BASE),has_explicit_domain)(multi)) + return FN(FN(MULTI(BASE),apply_domain),APPLY_DOMBASE)(multi, + set, fn_domain, fn_params); + + n = FN(MULTI(BASE),size)(multi); + if (n < 0 || !set) + goto error; + + for (i = 0; i < n; ++i) { + EL *el; + + el = FN(MULTI(BASE),take_at)(multi, i); + el = fn(el, FN(APPLY_DOM,copy)(set)); + multi = FN(MULTI(BASE),restore_at)(multi, i, el); + } + + FN(APPLY_DOM,free)(set); + return multi; +error: + FN(APPLY_DOM,free)(set); + FN(MULTI(BASE),free)(multi); + return NULL; +} diff --git a/external/mit/isl/dist/isl_multi_apply_union_set_explicit_domain_templ.c b/external/mit/isl/dist/isl_multi_apply_union_set_explicit_domain_templ.c new file mode 100644 index 000000000000..6d5f3b8e9f2a --- /dev/null +++ b/external/mit/isl/dist/isl_multi_apply_union_set_explicit_domain_templ.c @@ -0,0 +1,7 @@ +#define APPLY_DOMBASE union_set +#define APPLY_DOM isl_union_set + +#include + +#undef APPLY_DOMBASE +#undef APPLY_DOM diff --git a/external/mit/isl/dist/isl_multi_arith_templ.c b/external/mit/isl/dist/isl_multi_arith_templ.c new file mode 100644 index 000000000000..4e61051fd445 --- /dev/null +++ b/external/mit/isl/dist/isl_multi_arith_templ.c @@ -0,0 +1,114 @@ +/* + * 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 +#include + +#include + +/* Add "multi2" to "multi1" and return the result. + */ +__isl_give MULTI(BASE) *FN(MULTI(BASE),add)(__isl_take MULTI(BASE) *multi1, + __isl_take MULTI(BASE) *multi2) +{ + return FN(MULTI(BASE),bin_op)(multi1, multi2, &FN(EL,add)); +} + +/* Subtract "multi2" from "multi1" and return the result. + */ +__isl_give MULTI(BASE) *FN(MULTI(BASE),sub)(__isl_take MULTI(BASE) *multi1, + __isl_take MULTI(BASE) *multi2) +{ + return FN(MULTI(BASE),bin_op)(multi1, multi2, &FN(EL,sub)); +} + +/* Depending on "fn", multiply or divide the elements of "multi" by "v" and + * return the result. + */ +static __isl_give MULTI(BASE) *FN(MULTI(BASE),scale_val_fn)( + __isl_take MULTI(BASE) *multi, __isl_take isl_val *v, + __isl_give EL *(*fn)(__isl_take EL *el, __isl_take isl_val *v)) +{ + if (!multi || !v) + goto error; + + if (isl_val_is_one(v)) { + isl_val_free(v); + return multi; + } + + if (!isl_val_is_rat(v)) + isl_die(isl_val_get_ctx(v), isl_error_invalid, + "expecting rational factor", goto error); + + return FN(MULTI(BASE),fn_val)(multi, fn, v); +error: + isl_val_free(v); + return FN(MULTI(BASE),free)(multi); +} + +/* Multiply the elements of "multi" by "v" and return the result. + */ +__isl_give MULTI(BASE) *FN(MULTI(BASE),scale_val)(__isl_take MULTI(BASE) *multi, + __isl_take isl_val *v) +{ + return FN(MULTI(BASE),scale_val_fn)(multi, v, &FN(EL,scale_val)); +} + +/* Divide the elements of "multi" by "v" and return the result. + */ +__isl_give MULTI(BASE) *FN(MULTI(BASE),scale_down_val)( + __isl_take MULTI(BASE) *multi, __isl_take isl_val *v) +{ + if (!v) + goto error; + if (isl_val_is_zero(v)) + isl_die(isl_val_get_ctx(v), isl_error_invalid, + "cannot scale down by zero", goto error); + return FN(MULTI(BASE),scale_val_fn)(multi, v, &FN(EL,scale_down_val)); +error: + isl_val_free(v); + return FN(MULTI(BASE),free)(multi); +} + +/* Multiply the elements of "multi" by the corresponding element of "mv" + * and return the result. + */ +__isl_give MULTI(BASE) *FN(MULTI(BASE),scale_multi_val)( + __isl_take MULTI(BASE) *multi, __isl_take isl_multi_val *mv) +{ + return FN(MULTI(BASE),fn_multi_val)(multi, &FN(EL,scale_val), mv); +} + +/* Divide the elements of "multi" by the corresponding element of "mv" + * and return the result. + */ +__isl_give MULTI(BASE) *FN(MULTI(BASE),scale_down_multi_val)( + __isl_take MULTI(BASE) *multi, __isl_take isl_multi_val *mv) +{ + return FN(MULTI(BASE),fn_multi_val)(multi, &FN(EL,scale_down_val), mv); +} + +/* Compute the residues of the elements of "multi" modulo + * the corresponding element of "mv" and return the result. + */ +__isl_give MULTI(BASE) *FN(MULTI(BASE),mod_multi_val)( + __isl_take MULTI(BASE) *multi, __isl_take isl_multi_val *mv) +{ + return FN(MULTI(BASE),fn_multi_val)(multi, &FN(EL,mod_val), mv); +} + +/* Return the opposite of "multi". + */ +__isl_give MULTI(BASE) *FN(MULTI(BASE),neg)(__isl_take MULTI(BASE) *multi) +{ + S(MULTI(BASE),un_op_control) control = { .fn_el = &FN(EL,neg) }; + return FN(MULTI(BASE),un_op)(multi, &control); +} diff --git a/external/mit/isl/dist/isl_multi_bin_val_templ.c b/external/mit/isl/dist/isl_multi_bin_val_templ.c new file mode 100644 index 000000000000..a7a3913da9b1 --- /dev/null +++ b/external/mit/isl/dist/isl_multi_bin_val_templ.c @@ -0,0 +1,73 @@ +/* + * Copyright 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 + */ + +/* Apply "fn" to each of the elements of "multi" with as second argument "v". + */ +static __isl_give MULTI(BASE) *FN(MULTI(BASE),fn_val)( + __isl_take MULTI(BASE) *multi, + __isl_give EL *(*fn)(__isl_take EL *el, __isl_take isl_val *v), + __isl_take isl_val *v) +{ + isl_size n; + int i; + + n = FN(MULTI(BASE),size)(multi); + if (n < 0 || !v) + goto error; + + for (i = 0; i < n; ++i) { + EL *el; + + el = FN(MULTI(BASE),take_at)(multi, i); + el = fn(el, isl_val_copy(v)); + multi = FN(MULTI(BASE),restore_at)(multi, i, el); + } + + isl_val_free(v); + return multi; +error: + isl_val_free(v); + FN(MULTI(BASE),free)(multi); + return NULL; +} + +#undef TYPE +#define TYPE MULTI(BASE) +#include "isl_type_check_match_range_multi_val.c" + +/* Elementwise apply "fn" to "multi" and "mv". + */ +static __isl_give MULTI(BASE) *FN(MULTI(BASE),fn_multi_val)( + __isl_take MULTI(BASE) *multi, + __isl_give EL *(*fn)(__isl_take EL *el, __isl_take isl_val *v), + __isl_take isl_multi_val *mv) +{ + isl_size n; + int i; + + n = FN(MULTI(BASE),size)(multi); + if (n < 0 || FN(MULTI(BASE),check_match_range_multi_val)(multi, mv) < 0) + goto error; + + for (i = 0; i < n; ++i) { + isl_val *v; + EL *el; + + v = isl_multi_val_get_val(mv, i); + el = FN(MULTI(BASE),take_at)(multi, i); + el = fn(el, v); + multi = FN(MULTI(BASE),restore_at)(multi, i, el); + } + + isl_multi_val_free(mv); + return multi; +error: + isl_multi_val_free(mv); + return FN(MULTI(BASE),free)(multi); +} diff --git a/external/mit/isl/dist/isl_multi_bind_domain_templ.c b/external/mit/isl/dist/isl_multi_bind_domain_templ.c new file mode 100644 index 000000000000..d7eec37cad26 --- /dev/null +++ b/external/mit/isl/dist/isl_multi_bind_domain_templ.c @@ -0,0 +1,14 @@ +/* + * Copyright 2018 Cerebras Systems + * + * Use of this software is governed by the MIT license + * + * Written by Sven Verdoolaege, + * Cerebras Systems, 175 S San Antonio Rd, Los Altos, CA, USA + */ + +#include + +#undef TYPE +#define TYPE MULTI(BASE) +#include diff --git a/external/mit/isl/dist/isl_multi_bind_templ.c b/external/mit/isl/dist/isl_multi_bind_templ.c new file mode 100644 index 000000000000..ce2508c4517f --- /dev/null +++ b/external/mit/isl/dist/isl_multi_bind_templ.c @@ -0,0 +1,65 @@ +/* + * Copyright 2018 Cerebras Systems + * + * Use of this software is governed by the MIT license + * + * Written by Sven Verdoolaege, + * Cerebras Systems, 175 S San Antonio Rd, Los Altos, CA, USA + */ + +/* Bind the expressions of "multi" to parameters with identifiers + * specified by "tuple", living in the same space as + * (the target space of) "multi", + * returning the elements in the domain where the expressions + * are equal to the parameters. + */ +__isl_give DOM *FN(MULTI(BASE),bind)(__isl_take MULTI(BASE) *multi, + __isl_take isl_multi_id *tuple) +{ + int i; + isl_id *id; + isl_stat r; + isl_size n; + isl_space *multi_space, *tuple_space; + EL *el; + DOM *bnd; + + multi_space = isl_space_range(FN(MULTI(BASE),get_space)(multi)); + tuple_space = isl_multi_id_peek_space(tuple); + r = isl_space_check_equal_tuples(multi_space, tuple_space); + isl_space_free(multi_space); + if (r < 0) + goto error; + n = FN(MULTI(BASE),dim)(multi, isl_dim_set); + if (n < 0) + goto error; + + if (n == 0) { + isl_multi_id_free(tuple); + return FN(MULTI(BASE),domain)(multi); + } + + el = FN(MULTI(BASE),get_at)(multi, 0); + id = isl_multi_id_get_at(tuple, 0); + bnd = FN(EL,bind_id)(el, id); + + for (i = 1; i < n; ++i) { + DOM *bnd_i; + + el = FN(MULTI(BASE),get_at)(multi, i); + id = isl_multi_id_get_at(tuple, i); + bnd_i = FN(EL,bind_id)(el, id); + + bnd_i = FN(DOM,align_params)(bnd_i, FN(DOM,get_space)(bnd)); + bnd = FN(DOM,align_params)(bnd, FN(DOM,get_space)(bnd_i)); + bnd = FN(DOM,intersect)(bnd, bnd_i); + } + + FN(MULTI(BASE),free)(multi); + isl_multi_id_free(tuple); + return bnd; +error: + FN(MULTI(BASE),free)(multi); + isl_multi_id_free(tuple); + return NULL; +} diff --git a/external/mit/isl/dist/isl_multi_check_domain_templ.c b/external/mit/isl/dist/isl_multi_check_domain_templ.c new file mode 100644 index 000000000000..3a6c4e678636 --- /dev/null +++ b/external/mit/isl/dist/isl_multi_check_domain_templ.c @@ -0,0 +1,45 @@ +/* + * Copyright 2017 Sven Verdoolaege + * + * Use of this software is governed by the MIT license + * + * Written by Sven Verdoolaege. + */ + +#include + +/* Does the space of "domain" correspond to that of the domain of "multi"? + * The parameters do not need to be aligned. + */ +static isl_bool FN(MULTI(BASE),compatible_domain)( + __isl_keep MULTI(BASE) *multi, __isl_keep DOM *domain) +{ + isl_bool ok; + isl_space *space, *domain_space; + + domain_space = FN(DOM,get_space)(domain); + space = FN(MULTI(BASE),get_space)(multi); + ok = isl_space_has_domain_tuples(domain_space, space); + isl_space_free(space); + isl_space_free(domain_space); + + return ok; +} + +/* Check that the space of "domain" corresponds to + * that of the domain of "multi", ignoring parameters. + */ +static isl_stat FN(MULTI(BASE),check_compatible_domain)( + __isl_keep MULTI(BASE) *multi, __isl_keep DOM *domain) +{ + isl_bool ok; + + ok = FN(MULTI(BASE),compatible_domain)(multi, domain); + if (ok < 0) + return isl_stat_error; + if (!ok) + isl_die(FN(DOM,get_ctx)(domain), isl_error_invalid, + "incompatible spaces", return isl_stat_error); + + return isl_stat_ok; +} diff --git a/external/mit/isl/dist/isl_multi_cmp.c b/external/mit/isl/dist/isl_multi_cmp.c new file mode 100644 index 000000000000..27ab6dcb22f5 --- /dev/null +++ b/external/mit/isl/dist/isl_multi_cmp.c @@ -0,0 +1,40 @@ +/* + * Copyright 2016 Sven Verdoolaege + * + * Use of this software is governed by the MIT license + * + * Written by Sven Verdoolaege + */ + +#include + +/* Compare two multi expressions. + * + * Return -1 if "multi1" is "smaller" than "multi2", 1 if "multi1" is "greater" + * than "multi2" and 0 if they are equal. + */ +int FN(MULTI(BASE),plain_cmp)(__isl_keep MULTI(BASE) *multi1, + __isl_keep MULTI(BASE) *multi2) +{ + int i; + int cmp; + + if (multi1 == multi2) + return 0; + if (!multi1) + return -1; + if (!multi2) + return 1; + + cmp = isl_space_cmp(multi1->space, multi2->space); + if (cmp != 0) + return cmp; + + for (i = 0; i < multi1->n; ++i) { + cmp = FN(EL,plain_cmp)(multi1->u.p[i], multi2->u.p[i]); + if (cmp != 0) + return cmp; + } + + return 0; +} diff --git a/external/mit/isl/dist/isl_multi_coalesce.c b/external/mit/isl/dist/isl_multi_coalesce.c new file mode 100644 index 000000000000..588e107f4ca5 --- /dev/null +++ b/external/mit/isl/dist/isl_multi_coalesce.c @@ -0,0 +1,35 @@ +/* + * Copyright 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 + +/* Coalesce the elements of "multi". + * + * Note that such coalescing does not change the meaning of "multi" + * so there is no need to cow. We do need to be careful not to + * destroy any other copies of "multi" in case of failure. + */ +__isl_give MULTI(BASE) *FN(MULTI(BASE),coalesce)(__isl_take MULTI(BASE) *multi) +{ + int i; + + if (!multi) + return NULL; + + for (i = 0; i < multi->n; ++i) { + EL *el = FN(EL,copy)(multi->u.p[i]); + el = FN(EL,coalesce)(el); + if (!el) + return FN(MULTI(BASE),free)(multi); + FN(EL,free)(multi->u.p[i]); + multi->u.p[i] = el; + } + + return multi; +} diff --git a/external/mit/isl/dist/isl_multi_dim_id_templ.c b/external/mit/isl/dist/isl_multi_dim_id_templ.c new file mode 100644 index 000000000000..5103edf866c8 --- /dev/null +++ b/external/mit/isl/dist/isl_multi_dim_id_templ.c @@ -0,0 +1,70 @@ +/* + * Copyright 2011 Sven Verdoolaege + * Copyright 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 + +#include + +/* Return the position of the dimension of the given type and name + * in "multi". + * Return -1 if no such dimension can be found. + */ +int FN(MULTI(BASE),find_dim_by_name)(__isl_keep MULTI(BASE) *multi, + enum isl_dim_type type, const char *name) +{ + if (!multi) + return -1; + return isl_space_find_dim_by_name(multi->space, type, name); +} + +/* Return the position of the first dimension of "type" with id "id". + * Return -1 if there is no such dimension. + */ +int FN(MULTI(BASE),find_dim_by_id)(__isl_keep MULTI(BASE) *multi, + enum isl_dim_type type, __isl_keep isl_id *id) +{ + if (!multi) + return -1; + return isl_space_find_dim_by_id(multi->space, type, id); +} + +/* Return the id of the given dimension. + */ +__isl_give isl_id *FN(MULTI(BASE),get_dim_id)(__isl_keep MULTI(BASE) *multi, + enum isl_dim_type type, unsigned pos) +{ + return multi ? isl_space_get_dim_id(multi->space, type, pos) : NULL; +} + +__isl_give MULTI(BASE) *FN(MULTI(BASE),set_dim_name)( + __isl_take MULTI(BASE) *multi, + enum isl_dim_type type, unsigned pos, const char *s) +{ + isl_space *space; + + space = FN(MULTI(BASE),get_space)(multi); + space = isl_space_set_dim_name(space, type, pos, s); + + return FN(MULTI(BASE),reset_space)(multi, space); +} + +/* Set the id of the given dimension of "multi" to "id". + */ +__isl_give MULTI(BASE) *FN(MULTI(BASE),set_dim_id)( + __isl_take MULTI(BASE) *multi, + enum isl_dim_type type, unsigned pos, __isl_take isl_id *id) +{ + isl_space *space; + + space = FN(MULTI(BASE),get_space)(multi); + space = isl_space_set_dim_id(space, type, pos, id); + + return FN(MULTI(BASE),reset_space)(multi, space); +} diff --git a/external/mit/isl/dist/isl_multi_dims.c b/external/mit/isl/dist/isl_multi_dims.c new file mode 100644 index 000000000000..fb5cb1147b95 --- /dev/null +++ b/external/mit/isl/dist/isl_multi_dims.c @@ -0,0 +1,118 @@ +/* + * 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 + +#include + +/* 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 (n == 0) + return isl_bool_false; + + for (i = 0; i < multi->n; ++i) { + isl_bool involves; + + involves = FN(EL,involves_dims)(multi->u.p[i], type, first, n); + if (involves < 0 || involves) + return involves; + } + + if (FN(MULTI(BASE),has_explicit_domain)(multi)) + return FN(MULTI(BASE),involves_explicit_domain_dims)(multi, + type, first, n); + + 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) +{ + isl_space *space; + isl_size size; + int i; + + size = FN(MULTI(BASE),size)(multi); + if (size < 0) + return FN(MULTI(BASE),free)(multi); + 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; + + space = FN(MULTI(BASE),take_space)(multi); + space = isl_space_insert_dims(space, type, first, n); + multi = FN(MULTI(BASE),restore_space)(multi, space); + + if (FN(MULTI(BASE),has_explicit_domain)(multi)) + multi = FN(MULTI(BASE),insert_explicit_domain_dims)(multi, + type, first, n); + + for (i = 0; i < size; ++i) { + EL *el; + + el = FN(MULTI(BASE),take_at)(multi, i); + el = FN(EL,insert_dims)(el, type, first, n); + multi = FN(MULTI(BASE),restore_at)(multi, i, el); + } + + return multi; +} + +__isl_give MULTI(BASE) *FN(MULTI(BASE),add_dims)(__isl_take MULTI(BASE) *multi, + enum isl_dim_type type, unsigned n) +{ + isl_size pos; + + pos = FN(MULTI(BASE),dim)(multi, type); + if (pos < 0) + return FN(MULTI(BASE),free)(multi); + + 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) +{ + isl_size n; + isl_bool involves; + isl_space *space; + + n = FN(MULTI(BASE),dim)(multi, isl_dim_in); + if (n < 0) + return FN(MULTI(BASE),free)(multi); + 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; +} diff --git a/external/mit/isl/dist/isl_multi_domain_reverse_templ.c b/external/mit/isl/dist/isl_multi_domain_reverse_templ.c new file mode 100644 index 000000000000..312aa8740c95 --- /dev/null +++ b/external/mit/isl/dist/isl_multi_domain_reverse_templ.c @@ -0,0 +1,26 @@ +/* + * Copyright 2019 Cerebras Systems + * + * Use of this software is governed by the MIT license + * + * Written by Sven Verdoolaege, + * Cerebras Systems, 175 S San Antonio Rd, Los Altos, CA, USA + */ + +#include + +#include + +/* Given a multi expression on a domain (A -> B), + * interchange A and B in the wrapped domain + * to obtain a multi expression on the domain (B -> A). + */ +__isl_give MULTI(BASE) *FN(MULTI(BASE),domain_reverse)( + __isl_take MULTI(BASE) *multi) +{ + S(MULTI(BASE),un_op_control) control = { + .fn_space = &isl_space_domain_reverse, + .fn_el = &FN(EL,domain_reverse), + }; + return FN(MULTI(BASE),un_op)(multi, &control); +} diff --git a/external/mit/isl/dist/isl_multi_domain_templ.c b/external/mit/isl/dist/isl_multi_domain_templ.c new file mode 100644 index 000000000000..6aa97fe32017 --- /dev/null +++ b/external/mit/isl/dist/isl_multi_domain_templ.c @@ -0,0 +1,42 @@ +/* + * Copyright 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 + +#include + +/* Return the shared domain of the elements of "multi". + * + * If "multi" has an explicit domain, then return this domain. + */ +__isl_give isl_set *FN(MULTI(BASE),domain)(__isl_take MULTI(BASE) *multi) +{ + int i; + isl_set *dom; + + if (!multi) + return NULL; + + if (FN(MULTI(BASE),has_explicit_domain)(multi)) { + dom = FN(MULTI(BASE),get_explicit_domain)(multi); + FN(MULTI(BASE),free)(multi); + return dom; + } + + dom = isl_set_universe(FN(MULTI(BASE),get_domain_space)(multi)); + for (i = 0; i < multi->n; ++i) { + isl_set *dom_i; + + dom_i = FN(EL,domain)(FN(FN(MULTI(BASE),get),BASE)(multi, i)); + dom = isl_set_intersect(dom, dom_i); + } + + FN(MULTI(BASE),free)(multi); + return dom; +} diff --git a/external/mit/isl/dist/isl_multi_explicit_domain.c b/external/mit/isl/dist/isl_multi_explicit_domain.c new file mode 100644 index 000000000000..bb65823835f4 --- /dev/null +++ b/external/mit/isl/dist/isl_multi_explicit_domain.c @@ -0,0 +1,205 @@ +/* + * Copyright 2017 Sven Verdoolaege + * + * Use of this software is governed by the MIT license + * + * Written by Sven Verdoolaege. + */ + +/* These versions of the explicit domain functions are used + * when the multi expression may have an explicit domain. + */ + +#include + +__isl_give MULTI(BASE) *FN(MULTI(BASE),cow)(__isl_take MULTI(BASE) *multi); + +/* Does "multi" have an explicit domain? + * + * An explicit domain is only available if "multi" is zero-dimensional. + */ +static int FN(MULTI(BASE),has_explicit_domain)(__isl_keep MULTI(BASE) *multi) +{ + return multi && multi->n == 0; +} + +/* Check that "multi" has an explicit domain. + */ +static isl_stat FN(MULTI(BASE),check_has_explicit_domain)( + __isl_keep MULTI(BASE) *multi) +{ + if (!multi) + return isl_stat_error; + if (!FN(MULTI(BASE),has_explicit_domain)(multi)) + isl_die(FN(MULTI(BASE),get_ctx)(multi), isl_error_internal, + "expression does not have an explicit domain", + return isl_stat_error); + return isl_stat_ok; +} + +/* Return the explicit domain of "multi", assuming it has one. + */ +static __isl_keep DOM *FN(MULTI(BASE),peek_explicit_domain)( + __isl_keep MULTI(BASE) *multi) +{ + if (FN(MULTI(BASE),check_has_explicit_domain)(multi) < 0) + return NULL; + return multi->u.dom; +} + +/* Return a copy of the explicit domain of "multi", assuming it has one. + */ +static __isl_give DOM *FN(MULTI(BASE),get_explicit_domain)( + __isl_keep MULTI(BASE) *multi) +{ + return FN(DOM,copy)(FN(MULTI(BASE),peek_explicit_domain)(multi)); +} + +/* Replace the explicit domain of "multi" by "dom", assuming it has one. + */ +static __isl_give MULTI(BASE) *FN(MULTI(BASE),set_explicit_domain)( + __isl_take MULTI(BASE) *multi, __isl_take DOM *dom) +{ + if (FN(MULTI(BASE),check_has_explicit_domain)(multi) < 0) + goto error; + multi = FN(MULTI(BASE),cow)(multi); + if (!multi || !dom) + goto error; + FN(DOM,free)(multi->u.dom); + multi->u.dom = dom; + if (!multi->u.dom) + return FN(MULTI(BASE),free)(multi); + return multi; +error: + FN(MULTI(BASE),free)(multi); + FN(DOM,free)(dom); + return NULL; +} + +/* Intersect the domain of "dst" with the explicit domain of "src". + * + * In the case of isl_multi_union_pw_aff objects, the explicit domain + * of "src" is allowed to have only constraints on the parameters, even + * if the domain of "dst" contains actual domain elements. In this case, + * the domain of "dst" is intersected with those parameter constraints. + */ +static __isl_give MULTI(BASE) *FN(MULTI(BASE),intersect_explicit_domain)( + __isl_take MULTI(BASE) *dst, __isl_keep MULTI(BASE) *src) +{ + isl_bool is_params; + DOM *dom; + + dom = FN(MULTI(BASE),peek_explicit_domain)(src); + is_params = FN(DOM,is_params)(dom); + if (is_params < 0) + return FN(MULTI(BASE),free)(dst); + + dom = FN(DOM,copy)(dom); + if (!is_params) { + dst = FN(MULTI(BASE),intersect_domain)(dst, dom); + } else { + isl_set *params; + + params = FN(DOM,params)(dom); + dst = FN(MULTI(BASE),intersect_params)(dst, params); + } + + return dst; +} + +/* Set the explicit domain of "dst" to that of "src". + */ +static __isl_give MULTI(BASE) *FN(MULTI(BASE),copy_explicit_domain)( + __isl_take MULTI(BASE) *dst, __isl_keep MULTI(BASE) *src) +{ + DOM *dom; + + dom = FN(MULTI(BASE),get_explicit_domain)(src); + dst = FN(MULTI(BASE),set_explicit_domain)(dst, dom); + + return dst; +} + +/* Align the parameters of the explicit domain of "multi" to those of "space". + */ +static __isl_give MULTI(BASE) *FN(MULTI(BASE),align_explicit_domain_params)( + __isl_take MULTI(BASE) *multi, __isl_take isl_space *space) +{ + DOM *dom; + + dom = FN(MULTI(BASE),get_explicit_domain)(multi); + dom = FN(DOM,align_params)(dom, space); + multi = FN(MULTI(BASE),set_explicit_domain)(multi, dom); + + return multi; +} + +/* Replace the space of the explicit domain of "multi" by "space", + * without modifying its dimension. + */ +static __isl_give MULTI(BASE) *FN(MULTI(BASE),reset_explicit_domain_space)( + __isl_take MULTI(BASE) *multi, __isl_take isl_space *space) +{ + DOM *dom; + + dom = FN(MULTI(BASE),get_explicit_domain)(multi); + dom = FN(DOM,reset_equal_dim_space)(dom, space); + multi = FN(MULTI(BASE),set_explicit_domain)(multi, dom); + + return multi; +} + +/* Free the explicit domain of "multi". + */ +static void FN(MULTI(BASE),free_explicit_domain)(__isl_keep MULTI(BASE) *multi) +{ + if (FN(MULTI(BASE),check_has_explicit_domain)(multi) < 0) + return; + FN(DOM,free)(multi->u.dom); +} + +/* Do "multi1" and "multi2" have the same explicit domain? + */ +static isl_bool FN(MULTI(BASE),equal_explicit_domain)( + __isl_keep MULTI(BASE) *multi1, __isl_keep MULTI(BASE) *multi2) +{ + DOM *dom1, *dom2; + isl_bool equal; + + if (FN(MULTI(BASE),check_has_explicit_domain)(multi1) < 0 || + FN(MULTI(BASE),check_has_explicit_domain)(multi2) < 0) + return isl_bool_error; + dom1 = FN(MULTI(BASE),get_explicit_domain)(multi1); + dom2 = FN(MULTI(BASE),get_explicit_domain)(multi2); + equal = FN(DOM,is_equal)(dom1, dom2); + FN(DOM,free)(dom1); + FN(DOM,free)(dom2); + + return equal; +} + +static isl_stat FN(MULTI(BASE),check_explicit_domain)( + __isl_keep MULTI(BASE) *multi) __attribute__ ((unused)); + +/* Debugging function to check that the explicit domain of "multi" + * has the correct space. + */ +isl_stat FN(MULTI(BASE),check_explicit_domain)(__isl_keep MULTI(BASE) *multi) +{ + isl_space *space1, *space2; + isl_bool equal; + + if (FN(MULTI(BASE),check_has_explicit_domain)(multi) < 0) + return isl_stat_error; + space1 = isl_space_domain(isl_space_copy(multi->space)); + space2 = FN(DOM,get_space)(multi->u.dom); + equal = isl_space_is_equal(space1, space2); + isl_space_free(space1); + isl_space_free(space2); + if (equal < 0) + return isl_stat_error; + if (!equal) + isl_die(FN(MULTI(BASE),get_ctx)(multi), isl_error_internal, + "check failed", return isl_stat_error); + return isl_stat_ok; +} diff --git a/external/mit/isl/dist/isl_multi_floor.c b/external/mit/isl/dist/isl_multi_floor.c new file mode 100644 index 000000000000..f13ea9a7744e --- /dev/null +++ b/external/mit/isl/dist/isl_multi_floor.c @@ -0,0 +1,18 @@ +/* + * Copyright 2014 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 + +/* Given f, return floor(f). + */ +__isl_give MULTI(BASE) *FN(MULTI(BASE),floor)(__isl_take MULTI(BASE) *multi) +{ + S(MULTI(BASE),un_op_control) control = { .fn_el = &FN(EL,floor) }; + return FN(MULTI(BASE),un_op)(multi, &control); +} diff --git a/external/mit/isl/dist/isl_multi_from_base_templ.c b/external/mit/isl/dist/isl_multi_from_base_templ.c new file mode 100644 index 000000000000..2a2a6b1ecfe8 --- /dev/null +++ b/external/mit/isl/dist/isl_multi_from_base_templ.c @@ -0,0 +1,37 @@ +/* + * Copyright 2012,2014 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 + +#include + +/* Create a multiple expression with a single output/set dimension + * equal to "el". + * For most multiple expression types, the base type has a single + * output/set dimension and the space of the result is therefore + * the same as the space of the input. + * In the case of isl_multi_union_pw_aff, however, the base type + * lives in a parameter space and we therefore need to add + * a single set dimension. + */ +__isl_give MULTI(BASE) *FN(FN(MULTI(BASE),from),BASE)(__isl_take EL *el) +{ + isl_space *space; + MULTI(BASE) *multi; + + space = FN(EL,get_space(el)); + if (isl_space_is_params(space)) { + space = isl_space_set_from_params(space); + space = isl_space_add_dims(space, isl_dim_set, 1); + } + multi = FN(MULTI(BASE),alloc)(space); + multi = FN(FN(MULTI(BASE),set),BASE)(multi, 0, el); + + return multi; +} diff --git a/external/mit/isl/dist/isl_multi_from_tuple_templ.c b/external/mit/isl/dist/isl_multi_from_tuple_templ.c new file mode 100644 index 000000000000..46d35cc224af --- /dev/null +++ b/external/mit/isl/dist/isl_multi_from_tuple_templ.c @@ -0,0 +1,46 @@ +/* + * Copyright 2011 Sven Verdoolaege + * Copyright 2012 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 + +/* Extract a multi expression with domain space "dom_space" + * from a tuple "tuple" that was read by read_tuple. + * + * Check that none of the expressions depend on any other output/set dimensions. + */ +static MULTI(BASE) *FN(MULTI(BASE),from_tuple)( + __isl_take isl_space *dom_space, __isl_take isl_multi_pw_aff *tuple) +{ + int i; + isl_size dim, n; + isl_space *space; + MULTI(BASE) *multi; + + n = isl_multi_pw_aff_dim(tuple, isl_dim_out); + dim = isl_space_dim(dom_space, isl_dim_all); + if (n < 0 || dim < 0) + dom_space = isl_space_free(dom_space); + space = isl_space_range(isl_multi_pw_aff_get_space(tuple)); + space = isl_space_align_params(space, isl_space_copy(dom_space)); + if (!isl_space_is_params(dom_space)) + space = isl_space_map_from_domain_and_range( + isl_space_copy(dom_space), space); + isl_space_free(dom_space); + multi = FN(MULTI(BASE),alloc)(space); + + for (i = 0; i < n; ++i) { + isl_pw_aff *pa; + pa = isl_multi_pw_aff_get_pw_aff(tuple, i); + multi = FN(MULTI(BASE),set_tuple_entry)(multi, pa, i, dim, n); + } + + isl_multi_pw_aff_free(tuple); + return multi; +} diff --git a/external/mit/isl/dist/isl_multi_gist.c b/external/mit/isl/dist/isl_multi_gist.c new file mode 100644 index 000000000000..68f927970e89 --- /dev/null +++ b/external/mit/isl/dist/isl_multi_gist.c @@ -0,0 +1,50 @@ +/* + * 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 + +/* Compute the gist of the parameter domain "dom1" with respect to "dom2". + * + * Since "dom2" may not be a parameter domain, explicitly convert it + * to a parameter domain first. + */ +static __isl_give DOM *FN(MULTI(BASE),domain_gist_params)(DOM *dom1, + __isl_take DOM *dom2) +{ + isl_set *params; + + params = FN(DOM,params)(dom2); + dom1 = FN(DOM,gist_params)(dom1, params); + + return dom1; +} + +/* Compute the gist of "multi" with respect to the domain constraints + * of "context". + */ +__isl_give MULTI(BASE) *FN(MULTI(BASE),gist)(__isl_take MULTI(BASE) *multi, + __isl_take DOM *context) +{ + if (FN(MULTI(BASE),check_compatible_domain)(multi, context) < 0) + context = FN(DOM,free)(context); + return FN(FN(MULTI(BASE),apply),DOMBASE)(multi, context, &FN(EL,gist), + &FN(DOM,gist), + &FN(MULTI(BASE),domain_gist_params)); +} + +/* Compute the gist of "multi" with respect to the parameter constraints + * of "context". + */ +__isl_give MULTI(BASE) *FN(MULTI(BASE),gist_params)( + __isl_take MULTI(BASE) *multi, __isl_take isl_set *context) +{ + return FN(MULTI(BASE),apply_set)(multi, context, &FN(EL,gist_params), + &FN(DOM,gist_params), &FN(DOM,gist_params)); +} diff --git a/external/mit/isl/dist/isl_multi_hash.c b/external/mit/isl/dist/isl_multi_hash.c new file mode 100644 index 000000000000..0c7ebdf7e56b --- /dev/null +++ b/external/mit/isl/dist/isl_multi_hash.c @@ -0,0 +1,30 @@ +/* + * Copyright 2016 Sven Verdoolaege + * + * Use of this software is governed by the MIT license + * + * Written by Sven Verdoolaege + */ + +#include +#include + +/* Return a hash value that digests "multi". + */ +uint32_t FN(MULTI(BASE),get_hash)(__isl_keep MULTI(BASE) *multi) +{ + int i; + uint32_t hash; + + if (!multi) + return 0; + + hash = isl_hash_init(); + for (i = 0; i < multi->n; ++i) { + uint32_t el_hash; + el_hash = FN(EL,get_hash)(multi->u.p[i]); + isl_hash_hash(hash, el_hash); + } + + return hash; +} diff --git a/external/mit/isl/dist/isl_multi_identity_templ.c b/external/mit/isl/dist/isl_multi_identity_templ.c new file mode 100644 index 000000000000..1ffeadf57a46 --- /dev/null +++ b/external/mit/isl/dist/isl_multi_identity_templ.c @@ -0,0 +1,96 @@ +/* + * Copyright 2012 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 +#include + +#include + +/* Create a multi expression in the given space that maps each + * input dimension to the corresponding output dimension. + */ +__isl_give MULTI(BASE) *FN(MULTI(BASE),identity)(__isl_take isl_space *space) +{ + int i; + isl_size n_in, n_out; + isl_local_space *ls; + MULTI(BASE) *multi; + + if (!space) + return NULL; + + if (isl_space_is_set(space)) + isl_die(isl_space_get_ctx(space), isl_error_invalid, + "expecting map space", goto error); + + n_in = isl_space_dim(space, isl_dim_in); + n_out = isl_space_dim(space, isl_dim_out); + if (n_in < 0 || n_out < 0) + goto error; + if (n_in != n_out) + isl_die(isl_space_get_ctx(space), isl_error_invalid, + "number of input and output dimensions needs to be " + "the same", goto error); + + multi = FN(MULTI(BASE),alloc)(isl_space_copy(space)); + + if (!n_out) { + isl_space_free(space); + return multi; + } + + space = isl_space_domain(space); + ls = isl_local_space_from_space(space); + + for (i = 0; i < n_out; ++i) { + EL *el; + el = FN(EL,var_on_domain)(isl_local_space_copy(ls), + isl_dim_set, i); + multi = FN(FN(MULTI(BASE),set),BASE)(multi, i, el); + } + + isl_local_space_free(ls); + + return multi; +error: + isl_space_free(space); + return NULL; +} + +/* Create a multi expression that maps elements in the given space + * to themselves. + */ +__isl_give MULTI(BASE) *FN(MULTI(BASE),identity_on_domain_space)( + __isl_take isl_space *space) +{ + return FN(MULTI(BASE),identity)(isl_space_map_from_set(space)); +} + +/* This function performs the same operation as + * isl_multi_*_identity_on_domain_space, + * but is considered as a function on an isl_space when exported. + */ +__isl_give MULTI(BASE) *FN(FN(isl_space_identity_multi,BASE),on_domain)( + __isl_take isl_space *space) +{ + return FN(MULTI(BASE),identity_on_domain_space)(space); +} + +/* Create a multi expression in the same space as "multi" that maps each + * input dimension to the corresponding output dimension. + */ +__isl_give MULTI(BASE) *FN(FN(MULTI(BASE),identity_multi),BASE)( + __isl_take MULTI(BASE) *multi) +{ + isl_space *space; + + space = FN(MULTI(BASE),get_space)(multi); + FN(MULTI(BASE),free)(multi); + return FN(MULTI(BASE),identity)(space); +} diff --git a/external/mit/isl/dist/isl_multi_insert_domain_templ.c b/external/mit/isl/dist/isl_multi_insert_domain_templ.c new file mode 100644 index 000000000000..e4e403cd3ab3 --- /dev/null +++ b/external/mit/isl/dist/isl_multi_insert_domain_templ.c @@ -0,0 +1,14 @@ +/* + * Copyright 2019 Cerebras Systems + * + * Use of this software is governed by the MIT license + * + * Written by Sven Verdoolaege, + * Cerebras Systems, 175 S San Antonio Rd, Los Altos, CA, USA + */ + +#include + +#undef TYPE +#define TYPE MULTI(BASE) +#include diff --git a/external/mit/isl/dist/isl_multi_intersect.c b/external/mit/isl/dist/isl_multi_intersect.c new file mode 100644 index 000000000000..f8f643077501 --- /dev/null +++ b/external/mit/isl/dist/isl_multi_intersect.c @@ -0,0 +1,59 @@ +/* + * 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 + +/* Intersect the parameter domain "dom1" with "dom2". + * That is, intersect the parameters of "dom2" with "dom1". + * + * Even though "dom1" is known to only involve parameter constraints, + * it may be of type isl_union_set, so explicitly convert it + * to an isl_set first. + */ +static __isl_give DOM *FN(MULTI(BASE),params_domain_intersect)(DOM *dom1, + __isl_take DOM *dom2) +{ + isl_set *params; + + params = FN(DOM,params)(dom1); + dom2 = FN(DOM,intersect_params)(dom2, params); + + return dom2; +} + +/* Intersect the domain of "multi" with "domain". + * + * If "multi" has an explicit domain, then only this domain + * needs to be intersected. + */ +__isl_give MULTI(BASE) *FN(MULTI(BASE),intersect_domain)( + __isl_take MULTI(BASE) *multi, __isl_take DOM *domain) +{ + if (FN(MULTI(BASE),check_compatible_domain)(multi, domain) < 0) + domain = FN(DOM,free)(domain); + return FN(FN(MULTI(BASE),apply),DOMBASE)(multi, domain, + &FN(EL,intersect_domain), + &FN(DOM,intersect), + &FN(MULTI(BASE),params_domain_intersect)); +} + +/* Intersect the parameter domain of "multi" with "domain". + * + * If "multi" has an explicit domain, then only this domain + * needs to be intersected. + */ +__isl_give MULTI(BASE) *FN(MULTI(BASE),intersect_params)( + __isl_take MULTI(BASE) *multi, __isl_take isl_set *domain) +{ + return FN(MULTI(BASE),apply_set)(multi, domain, + &FN(EL,intersect_params), + &FN(DOM,intersect_params), + &FN(DOM,intersect_params)); +} diff --git a/external/mit/isl/dist/isl_multi_locals_templ.c b/external/mit/isl/dist/isl_multi_locals_templ.c new file mode 100644 index 000000000000..3cfb0a33c35a --- /dev/null +++ b/external/mit/isl/dist/isl_multi_locals_templ.c @@ -0,0 +1,17 @@ +/* + * Copyright 2019 Cerebras Systems + * + * Use of this software is governed by the MIT license + * + * Written by Sven Verdoolaege, + * Cerebras Systems, 175 S San Antonio Rd, Los Altos, CA, USA + */ + +#include + +/* Does "multi" involve any local variables? + */ +isl_bool FN(MULTI(BASE),involves_locals)(__isl_keep MULTI(BASE) *multi) +{ + return FN(MULTI(BASE),any)(multi, FN(EL,involves_locals)); +} diff --git a/external/mit/isl/dist/isl_multi_macro.h b/external/mit/isl/dist/isl_multi_macro.h new file mode 100644 index 000000000000..394494b06e68 --- /dev/null +++ b/external/mit/isl/dist/isl_multi_macro.h @@ -0,0 +1,8 @@ +#undef EL_BASE +#define EL_BASE BASE +#include + +#define xMULTI(BASE) isl_multi_ ## BASE +#define MULTI(BASE) xMULTI(BASE) +#undef DOM +#define DOM CAT(isl_,DOMBASE) diff --git a/external/mit/isl/dist/isl_multi_min_max_templ.c b/external/mit/isl/dist/isl_multi_min_max_templ.c new file mode 100644 index 000000000000..5a1959290e94 --- /dev/null +++ b/external/mit/isl/dist/isl_multi_min_max_templ.c @@ -0,0 +1,24 @@ +/* + * Copyright 2019 Cerebras Systems + * + * Use of this software is governed by the MIT license + * + * Written by Sven Verdoolaege, + * Cerebras Systems, 175 S San Antonio Rd, Los Altos, CA, USA + */ + +/* Return the (elementwise) minimum of "multi1" and "multi2". + */ +__isl_give MULTI(BASE) *FN(MULTI(BASE),min)(__isl_take MULTI(BASE) *multi1, + __isl_take MULTI(BASE) *multi2) +{ + return FN(MULTI(BASE),bin_op)(multi1, multi2, &FN(EL,min)); +} + +/* Return the (elementwise) maximum of "multi1" and "multi2". + */ +__isl_give MULTI(BASE) *FN(MULTI(BASE),max)(__isl_take MULTI(BASE) *multi1, + __isl_take MULTI(BASE) *multi2) +{ + return FN(MULTI(BASE),bin_op)(multi1, multi2, &FN(EL,max)); +} diff --git a/external/mit/isl/dist/isl_multi_move_dims_templ.c b/external/mit/isl/dist/isl_multi_move_dims_templ.c new file mode 100644 index 000000000000..ba9830e2b6df --- /dev/null +++ b/external/mit/isl/dist/isl_multi_move_dims_templ.c @@ -0,0 +1,70 @@ +/* + * Copyright 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 + +#include + +/* Move the "n" dimensions of "src_type" starting at "src_pos" of "multi" + * to dimensions of "dst_type" at "dst_pos". + * + * We only support moving input dimensions to parameters and vice versa. + */ +__isl_give MULTI(BASE) *FN(MULTI(BASE),move_dims)(__isl_take MULTI(BASE) *multi, + enum isl_dim_type dst_type, unsigned dst_pos, + enum isl_dim_type src_type, unsigned src_pos, unsigned n) +{ + isl_space *space; + isl_size size; + int i; + + size = FN(MULTI(BASE),size)(multi); + if (size < 0) + return FN(MULTI(BASE),free)(multi); + + if (n == 0 && + !isl_space_is_named_or_nested(multi->space, src_type) && + !isl_space_is_named_or_nested(multi->space, dst_type)) + return multi; + + if (dst_type == isl_dim_out || src_type == isl_dim_out) + isl_die(FN(MULTI(BASE),get_ctx)(multi), isl_error_invalid, + "cannot move output/set dimension", + return FN(MULTI(BASE),free)(multi)); + if (dst_type == isl_dim_div || src_type == isl_dim_div) + isl_die(FN(MULTI(BASE),get_ctx)(multi), isl_error_invalid, + "cannot move divs", + return FN(MULTI(BASE),free)(multi)); + if (FN(MULTI(BASE),check_range)(multi, src_type, src_pos, n) < 0) + return FN(MULTI(BASE),free)(multi); + if (dst_type == src_type) + isl_die(FN(MULTI(BASE),get_ctx)(multi), isl_error_unsupported, + "moving dims within the same type not supported", + return FN(MULTI(BASE),free)(multi)); + + space = FN(MULTI(BASE),take_space)(multi); + space = isl_space_move_dims(space, dst_type, dst_pos, + src_type, src_pos, n); + multi = FN(MULTI(BASE),restore_space)(multi, space); + + if (FN(MULTI(BASE),has_explicit_domain)(multi)) + multi = FN(MULTI(BASE),move_explicit_domain_dims)(multi, + dst_type, dst_pos, src_type, src_pos, n); + + for (i = 0; i < size; ++i) { + EL *el; + + el = FN(MULTI(BASE),take_at)(multi, i); + el = FN(EL,move_dims)(el, dst_type, dst_pos, + src_type, src_pos, n); + multi = FN(MULTI(BASE),restore_at)(multi, i, el); + } + + return multi; +} diff --git a/external/mit/isl/dist/isl_multi_nan_templ.c b/external/mit/isl/dist/isl_multi_nan_templ.c new file mode 100644 index 000000000000..2ea73a8140bb --- /dev/null +++ b/external/mit/isl/dist/isl_multi_nan_templ.c @@ -0,0 +1,17 @@ +/* + * Copyright 2014 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 + +/* Does "multi" involve any NaNs? + */ +isl_bool FN(MULTI(BASE),involves_nan)(__isl_keep MULTI(BASE) *multi) +{ + return FN(MULTI(BASE),any)(multi, &FN(EL,involves_nan)); +} diff --git a/external/mit/isl/dist/isl_multi_no_domain_templ.c b/external/mit/isl/dist/isl_multi_no_domain_templ.c new file mode 100644 index 000000000000..1c98ac452452 --- /dev/null +++ b/external/mit/isl/dist/isl_multi_no_domain_templ.c @@ -0,0 +1,118 @@ +/* + * Copyright 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 +#include +#include + +#include + +/* The functions in this file are meant for base object types + * that do not have any associated space. They are only meant to be used + * in the generic isl_multi_* functions which have to deal with base objects + * that do have an associated space. + */ + + +/* Drop the "n" first dimensions of type "type" at position "first". + * + * For a base expression without an associated space, this function + * does not do anything. + */ +static __isl_give EL *FN(EL,drop_dims)(__isl_take EL *el, + enum isl_dim_type type, unsigned first, unsigned n) +{ + return el; +} + +/* Return the space of "el". + * + * For a base expression without an associated space, + * the conditions surrounding the call to this function make sure + * that this function will never actually get called. We return a valid + * space anyway, just in case. + */ +static __isl_give isl_space *FN(EL,get_space)(__isl_keep EL *el) +{ + if (!el) + return NULL; + + return isl_space_params_alloc(FN(EL,get_ctx)(el), 0); +} + +/* Reset the domain space of "el" to "space". + * + * For a base expression without an associated space, this function + * does not do anything, apart from error handling and cleaning up memory. + */ +static __isl_give EL *FN(EL,reset_domain_space)(__isl_take EL *el, + __isl_take isl_space *space) +{ + if (!space) + return FN(EL,free)(el); + isl_space_free(space); + return el; +} + +/* Align the parameters of "el" to those of "space". + * + * For a base expression without an associated space, this function + * does not do anything, apart from error handling and cleaning up memory. + * Note that the conditions surrounding the call to this function make sure + * that this function will never actually get called. + */ +static __isl_give EL *FN(EL,align_params)(__isl_take EL *el, + __isl_take isl_space *space) +{ + if (!space) + return FN(EL,free)(el); + isl_space_free(space); + return el; +} + +/* Reorder the dimensions of the domain of "el" according + * to the given reordering. + * + * For a base expression without an associated space, this function + * does not do anything, apart from error handling and cleaning up memory. + */ +static __isl_give EL *FN(EL,realign_domain)(__isl_take EL *el, + __isl_take isl_reordering *r) +{ + if (!r) + return FN(EL,free)(el); + isl_reordering_free(r); + return el; +} + +/* Do the parameters of "el" match those of "space"? + * + * For a base expression without an associated space, this function + * simply returns true, except if "el" or "space" are NULL. + */ +static isl_bool FN(EL,matching_params)(__isl_keep EL *el, + __isl_keep isl_space *space) +{ + if (!el || !space) + return isl_bool_error; + return isl_bool_true; +} + +/* Check that the domain space of "el" matches "space". + * + * For a base expression without an associated space, this function + * simply returns isl_stat_ok, except if "el" or "space" are NULL. + */ +static isl_stat FN(EL,check_match_domain_space)(__isl_keep EL *el, + __isl_keep isl_space *space) +{ + if (!el || !space) + return isl_stat_error; + return isl_stat_ok; +} diff --git a/external/mit/isl/dist/isl_multi_no_explicit_domain.c b/external/mit/isl/dist/isl_multi_no_explicit_domain.c new file mode 100644 index 000000000000..cba4387ab58e --- /dev/null +++ b/external/mit/isl/dist/isl_multi_no_explicit_domain.c @@ -0,0 +1,172 @@ +/* + * Copyright 2017 Sven Verdoolaege + * + * Use of this software is governed by the MIT license + * + * Written by Sven Verdoolaege. + */ + +/* These versions of the explicit domain functions are used + * when the multi expression cannot have an explicit domain. + */ + +#include + +#include + +/* Does "multi" have an explicit domain? + * + * No. + */ +static int FN(MULTI(BASE),has_explicit_domain)(__isl_keep MULTI(BASE) *multi) +{ + return 0; +} + +/* Initialize the explicit domain of "multi". + * "multi" cannot have an explicit domain, so this function is never called. + */ +static __isl_give MULTI(BASE) *FN(MULTI(BASE),init_explicit_domain)( + __isl_take MULTI(BASE) *multi) +{ + return multi; +} + +/* Intersect the domain of "dst" with the explicit domain of "src". + * "src" cannot have an explicit domain, so this function is never called. + */ +static __isl_give MULTI(BASE) *FN(MULTI(BASE),intersect_explicit_domain)( + __isl_take MULTI(BASE) *dst, __isl_keep MULTI(BASE) *src) +{ + return dst; +} + +/* Set the explicit domain of "dst" to that of "src". + * "src" and "dst" cannot have an explicit domain, + * so this function is never called. + */ +static __isl_give MULTI(BASE) *FN(MULTI(BASE),copy_explicit_domain)( + __isl_take MULTI(BASE) *dst, __isl_keep MULTI(BASE) *src) +{ + return dst; +} + +/* Only used by multi-expressions that include "isl_multi_product_templ.c". + */ +static __isl_give MULTI(BASE) * +FN(MULTI(BASE),intersect_explicit_domain_product)( + __isl_take MULTI(BASE) *dst, __isl_keep MULTI(BASE) *src1, + __isl_keep MULTI(BASE) *src2) __attribute__ ((unused)); + +/* Intersect the domain of "dst" with the domain product + * of the explicit domains of "src1" and "src2". + * This function is only called if at least one of "src1" or "src2" + * has an explicit domain. + * "src1", "src2" and "dst" cannot have an explicit domain, + * so this function is never called. + */ +static __isl_give MULTI(BASE) * +FN(MULTI(BASE),intersect_explicit_domain_product)( + __isl_take MULTI(BASE) *dst, __isl_keep MULTI(BASE) *src1, + __isl_keep MULTI(BASE) *src2) +{ + return dst; +} + +/* Align the parameters of the explicit domain of "multi" to those of "space". + * "multi" cannot have an explicit domain, so this function is never called. + */ +static __isl_give MULTI(BASE) *FN(MULTI(BASE),align_explicit_domain_params)( + __isl_take MULTI(BASE) *multi, __isl_take isl_space *space) +{ + isl_space_free(space); + return multi; +} + +/* Replace the space of the explicit domain of "multi" by "space", + * without modifying its dimension. + * "multi" cannot have an explicit domain, so this function is never called. + */ +static __isl_give MULTI(BASE) *FN(MULTI(BASE),reset_explicit_domain_space)( + __isl_take MULTI(BASE) *multi, __isl_take isl_space *space) +{ + isl_space_free(space); + return multi; +} + +/* Check whether the explicit domain of "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. + * "multi" cannot have an explicit domain, so this function is never called. + */ +isl_bool FN(MULTI(BASE),involves_explicit_domain_dims)( + __isl_keep MULTI(BASE) *multi, + enum isl_dim_type type, unsigned pos, unsigned n) +{ + return isl_bool_false; +} + +/* Insert "n" dimensions of type "type" at position "pos" + * of the explicit domain of "multi". + * "multi" cannot have an explicit domain, so this function is never called. + */ +__isl_give MULTI(BASE) *FN(MULTI(BASE),insert_explicit_domain_dims)( + __isl_take MULTI(BASE) *multi, + enum isl_dim_type type, unsigned pos, unsigned n) +{ + return multi; +} + +/* Drop the "n" dimensions of type "type" starting at position "pos" + * of the explicit domain of "multi". + * "multi" cannot have an explicit domain, so this function is never called. + */ +__isl_give MULTI(BASE) *FN(MULTI(BASE),drop_explicit_domain_dims)( + __isl_take MULTI(BASE) *multi, + enum isl_dim_type type, unsigned pos, unsigned n) +{ + return multi; +} + +/* Move the "n" dimensions of "src_type" starting at "src_pos" of + * of the explicit domain of "multi" to dimensions of "dst_type" at "dst_pos". + * "multi" cannot have an explicit domain, so this function is never called. + */ +__isl_give MULTI(BASE) *FN(MULTI(BASE),move_explicit_domain_dims)( + __isl_take MULTI(BASE) *multi, + enum isl_dim_type dst_type, unsigned dst_pos, + enum isl_dim_type src_type, unsigned src_pos, unsigned n) +{ + return multi; +} + +/* Free the explicit domain of "multi". + * "multi" cannot have an explicit domain, so this function is never called. + */ +static void FN(MULTI(BASE),free_explicit_domain)(__isl_keep MULTI(BASE) *multi) +{ +} + +/* Do "multi1" and "multi2" have the same explicit domain? + * "multi1" and "multi2" cannot have an explicit domain, + * so this function is never called. + */ +static isl_bool FN(MULTI(BASE),equal_explicit_domain)( + __isl_keep MULTI(BASE) *multi1, __isl_keep MULTI(BASE) *multi2) +{ + return isl_bool_true; +} + +static isl_stat FN(MULTI(BASE),check_explicit_domain)( + __isl_keep MULTI(BASE) *multi) __attribute__ ((unused)); + +/* Debugging function to check that the explicit domain of "multi" + * has the correct space. + * "multi" cannot have an explicit domain, + * so this function should never be called. + */ +static isl_stat FN(MULTI(BASE),check_explicit_domain)( + __isl_keep MULTI(BASE) *multi) +{ + return isl_stat_ok; +} diff --git a/external/mit/isl/dist/isl_multi_param_templ.c b/external/mit/isl/dist/isl_multi_param_templ.c new file mode 100644 index 000000000000..eab93548933f --- /dev/null +++ b/external/mit/isl/dist/isl_multi_param_templ.c @@ -0,0 +1,60 @@ +/* + * Use of this software is governed by the MIT license + * + * Written by Sven Verdoolaege + */ + +#include + +/* Does the multiple expression "multi" depend in any way + * on the parameter with identifier "id"? + */ +isl_bool FN(MULTI(BASE),involves_param_id)(__isl_keep MULTI(BASE) *multi, + __isl_keep isl_id *id) +{ + int i; + int pos; + + if (!multi || !id) + return isl_bool_error; + if (multi->n == 0) + return isl_bool_false; + pos = FN(MULTI(BASE),find_dim_by_id)(multi, isl_dim_param, id); + if (pos < 0) + return isl_bool_false; + + for (i = 0; i < multi->n; ++i) { + isl_bool involved = FN(EL,involves_param_id)(multi->u.p[i], id); + if (involved < 0 || involved) + return involved; + } + + return isl_bool_false; +} + +/* Does the multiple expression "multi" depend in any way + * on any of the parameters with identifiers in "list"? + */ +isl_bool FN(MULTI(BASE),involves_param_id_list)(__isl_keep MULTI(BASE) *multi, + __isl_keep isl_id_list *list) +{ + int i; + isl_size n; + + n = isl_id_list_size(list); + if (n < 0) + return isl_bool_error; + for (i = 0; i < n; ++i) { + isl_bool involves; + isl_id *id; + + id = isl_id_list_get_at(list, i); + involves = FN(MULTI(BASE),involves_param_id)(multi, id); + isl_id_free(id); + + if (involves < 0 || involves) + return involves; + } + + return isl_bool_false; +} diff --git a/external/mit/isl/dist/isl_multi_product_templ.c b/external/mit/isl/dist/isl_multi_product_templ.c new file mode 100644 index 000000000000..5640326fd826 --- /dev/null +++ b/external/mit/isl/dist/isl_multi_product_templ.c @@ -0,0 +1,68 @@ +/* + * Copyright 2012 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 + +#include + +/* Given two MULTI(BASE)s A -> B and C -> D, + * construct a MULTI(BASE) [A -> C] -> [B -> D]. + * + * If "multi1" and/or "multi2" has an explicit domain, then + * intersect the domain of the result with these explicit domains. + */ +__isl_give MULTI(BASE) *FN(MULTI(BASE),product)( + __isl_take MULTI(BASE) *multi1, __isl_take MULTI(BASE) *multi2) +{ + int i; + EL *el; + isl_space *space; + MULTI(BASE) *res; + isl_size in1, in2, out1, out2; + + FN(MULTI(BASE),align_params_bin)(&multi1, &multi2); + in1 = FN(MULTI(BASE),dim)(multi1, isl_dim_in); + in2 = FN(MULTI(BASE),dim)(multi2, isl_dim_in); + out1 = FN(MULTI(BASE),dim)(multi1, isl_dim_out); + out2 = FN(MULTI(BASE),dim)(multi2, isl_dim_out); + if (in1 < 0 || in2 < 0 || out1 < 0 || out2 < 0) + goto error; + space = isl_space_product(FN(MULTI(BASE),get_space)(multi1), + FN(MULTI(BASE),get_space)(multi2)); + res = FN(MULTI(BASE),alloc)(isl_space_copy(space)); + space = isl_space_domain(space); + + for (i = 0; i < out1; ++i) { + el = FN(FN(MULTI(BASE),get),BASE)(multi1, i); + el = FN(EL,insert_dims)(el, isl_dim_in, in1, in2); + el = FN(EL,reset_domain_space)(el, isl_space_copy(space)); + res = FN(FN(MULTI(BASE),set),BASE)(res, i, el); + } + + for (i = 0; i < out2; ++i) { + el = FN(FN(MULTI(BASE),get),BASE)(multi2, i); + el = FN(EL,insert_dims)(el, isl_dim_in, 0, in1); + el = FN(EL,reset_domain_space)(el, isl_space_copy(space)); + res = FN(FN(MULTI(BASE),set),BASE)(res, out1 + i, el); + } + + if (FN(MULTI(BASE),has_explicit_domain)(multi1) || + FN(MULTI(BASE),has_explicit_domain)(multi2)) + res = FN(MULTI(BASE),intersect_explicit_domain_product)(res, + multi1, multi2); + + isl_space_free(space); + FN(MULTI(BASE),free)(multi1); + FN(MULTI(BASE),free)(multi2); + return res; +error: + FN(MULTI(BASE),free)(multi1); + FN(MULTI(BASE),free)(multi2); + return NULL; +} diff --git a/external/mit/isl/dist/isl_multi_pw_aff_explicit_domain.c b/external/mit/isl/dist/isl_multi_pw_aff_explicit_domain.c new file mode 100644 index 000000000000..e9efea0bd001 --- /dev/null +++ b/external/mit/isl/dist/isl_multi_pw_aff_explicit_domain.c @@ -0,0 +1,134 @@ +/* + * Copyright 2017 Sven Verdoolaege + * + * Use of this software is governed by the MIT license + * + * Written by Sven Verdoolaege. + */ + +/* Initialize the explicit domain of "mpa". + * + * The explicit domain is initialized to a universe set + * in the domain space. + */ +static __isl_give isl_multi_pw_aff *isl_multi_pw_aff_init_explicit_domain( + __isl_take isl_multi_pw_aff *mpa) +{ + if (isl_multi_pw_aff_check_has_explicit_domain(mpa) < 0) + return isl_multi_pw_aff_free(mpa); + mpa->u.dom = isl_set_universe(isl_multi_pw_aff_get_domain_space(mpa)); + if (!mpa->u.dom) + return isl_multi_pw_aff_free(mpa); + return mpa; +} + +/* Intersect the domain of "dst" with the domain product + * of the explicit domains of "src1" and "src2". + * This function is only called if at least one of "src1" or "src2" + * has an explicit domain. + */ +static __isl_give isl_multi_pw_aff * +isl_multi_pw_aff_intersect_explicit_domain_product( + __isl_take isl_multi_pw_aff *dst, __isl_keep isl_multi_pw_aff *src1, + __isl_keep isl_multi_pw_aff *src2) +{ + isl_space *space; + isl_set *dom; + isl_map *map; + + if (!src1 || !src2) + return FN(isl_multi_pw_aff,free)(dst); + space = isl_multi_pw_aff_get_domain_space(dst); + dom = isl_set_universe(space); + map = isl_set_unwrap(dom); + if (isl_multi_pw_aff_has_explicit_domain(src1)) { + dom = isl_set_copy(src1->u.dom); + map = isl_map_intersect_domain(map, dom); + } + if (isl_multi_pw_aff_has_explicit_domain(src2)) { + dom = isl_set_copy(src2->u.dom); + map = isl_map_intersect_range(map, dom); + } + dom = isl_map_wrap(map); + dst = isl_multi_pw_aff_intersect_domain(dst, dom); + return dst; +} + +/* Check whether the explicit domain of "mpa" 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 isl_multi_pw_aff_involves_explicit_domain_dims( + __isl_keep isl_multi_pw_aff *mpa, + enum isl_dim_type type, unsigned pos, unsigned n) +{ + if (isl_multi_pw_aff_check_has_explicit_domain(mpa) < 0) + return isl_bool_error; + if (type == isl_dim_in) + type = isl_dim_set; + return isl_set_involves_dims(mpa->u.dom, type, pos, n); +} + +/* Insert "n" dimensions of type "type" at position "pos" + * of the explicit domain of "mpa". + */ +static __isl_give isl_multi_pw_aff * +isl_multi_pw_aff_insert_explicit_domain_dims(__isl_take isl_multi_pw_aff *mpa, + enum isl_dim_type type, unsigned pos, unsigned n) +{ + if (isl_multi_pw_aff_check_has_explicit_domain(mpa) < 0) + return isl_multi_pw_aff_free(mpa); + mpa = isl_multi_pw_aff_cow(mpa); + if (!mpa) + return NULL; + if (type == isl_dim_in) + type = isl_dim_set; + mpa->u.dom = isl_set_insert_dims(mpa->u.dom, type, pos, n); + if (!mpa->u.dom) + return isl_multi_pw_aff_free(mpa); + return mpa; +} + +/* Drop the "n" dimensions of type "type" starting at position "pos" + * of the explicit domain of "mpa". + */ +static __isl_give isl_multi_pw_aff * +isl_multi_pw_aff_drop_explicit_domain_dims(__isl_take isl_multi_pw_aff *mpa, + enum isl_dim_type type, unsigned pos, unsigned n) +{ + if (isl_multi_pw_aff_check_has_explicit_domain(mpa) < 0) + return isl_multi_pw_aff_free(mpa); + mpa = isl_multi_pw_aff_cow(mpa); + if (!mpa) + return NULL; + if (type == isl_dim_in) + type = isl_dim_set; + mpa->u.dom = isl_set_drop(mpa->u.dom, type, pos, n); + if (!mpa->u.dom) + return isl_multi_pw_aff_free(mpa); + return mpa; +} + +/* Move the "n" dimensions of "src_type" starting at "src_pos" of + * of the explicit domain of "mpa" to dimensions of "dst_type" at "dst_pos". + */ +static __isl_give isl_multi_pw_aff *isl_multi_pw_aff_move_explicit_domain_dims( + __isl_take isl_multi_pw_aff *mpa, + enum isl_dim_type dst_type, unsigned dst_pos, + enum isl_dim_type src_type, unsigned src_pos, unsigned n) +{ + if (isl_multi_pw_aff_check_has_explicit_domain(mpa) < 0) + return isl_multi_pw_aff_free(mpa); + mpa = isl_multi_pw_aff_cow(mpa); + if (!mpa) + return NULL; + if (dst_type == isl_dim_in) + dst_type = isl_dim_set; + if (src_type == isl_dim_in) + src_type = isl_dim_set; + mpa->u.dom = isl_set_move_dims(mpa->u.dom, dst_type, dst_pos, + src_type, src_pos, n); + if (!mpa->u.dom) + return isl_multi_pw_aff_free(mpa); + return mpa; +} diff --git a/external/mit/isl/dist/isl_multi_pw_aff_pullback_templ.c b/external/mit/isl/dist/isl_multi_pw_aff_pullback_templ.c new file mode 100644 index 000000000000..fc5aed2b3ffd --- /dev/null +++ b/external/mit/isl/dist/isl_multi_pw_aff_pullback_templ.c @@ -0,0 +1,73 @@ +/* + * Copyright 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 + */ + +#define xCAT(A,B) A ## B +#define CAT(A,B) xCAT(A,B) +#undef TYPE +#define TYPE CAT(isl_,BASE) +#define xFN(TYPE,NAME) TYPE ## _ ## NAME +#define FN(TYPE,NAME) xFN(TYPE,NAME) + +#undef SUFFIX +#define SUFFIX BASE +#undef ARG1 +#define ARG1 isl_multi_pw_aff +#undef ARG2 +#define ARG2 TYPE + +static +#include "isl_align_params_templ.c" + +/* Compute the pullback of "mpa" by the function represented by "fn". + * In other words, plug in "fn" in "mpa". + * + * If "mpa" has an explicit domain, then it is this domain + * that needs to undergo a pullback, i.e., a preimage. + */ +__isl_give isl_multi_pw_aff *FN(isl_multi_pw_aff_pullback,BASE)( + __isl_take isl_multi_pw_aff *mpa, __isl_take TYPE *fn) +{ + int i; + isl_size n; + isl_space *space = NULL; + + FN(isl_multi_pw_aff_align_params,BASE)(&mpa, &fn); + mpa = isl_multi_pw_aff_cow(mpa); + n = isl_multi_pw_aff_size(mpa); + if (n < 0 || !fn) + goto error; + + space = isl_space_join(FN(TYPE,get_space)(fn), + isl_multi_pw_aff_get_space(mpa)); + + for (i = 0; i < n; ++i) { + isl_pw_aff *pa; + + pa = isl_multi_pw_aff_take_at(mpa, i); + pa = FN(isl_pw_aff_pullback,BASE)(pa, FN(TYPE,copy)(fn)); + mpa = isl_multi_pw_aff_restore_at(mpa, i, pa); + if (!mpa) + goto error; + } + if (isl_multi_pw_aff_has_explicit_domain(mpa)) { + mpa->u.dom = FN(isl_set_preimage,BASE)(mpa->u.dom, + FN(TYPE,copy)(fn)); + if (!mpa->u.dom) + goto error; + } + + FN(TYPE,free)(fn); + isl_multi_pw_aff_restore_space(mpa, space); + return mpa; +error: + isl_space_free(space); + isl_multi_pw_aff_free(mpa); + FN(TYPE,free)(fn); + return NULL; +} diff --git a/external/mit/isl/dist/isl_multi_read_no_explicit_domain_templ.c b/external/mit/isl/dist/isl_multi_read_no_explicit_domain_templ.c new file mode 100644 index 000000000000..b6ec27f688c8 --- /dev/null +++ b/external/mit/isl/dist/isl_multi_read_no_explicit_domain_templ.c @@ -0,0 +1,84 @@ +/* + * Copyright 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 +#include + +#include + +/* This function is called for each element in a tuple inside + * isl_stream_read_multi_*. + * Read an EL from "s" and add it to *list. + */ +static __isl_give isl_space *FN(read_el,BASE)(__isl_keep isl_stream *s, + struct vars *v, __isl_take isl_space *space, int rational, void *user) +{ + LIST(EL) **list = (LIST(EL) **) user; + EL *el; + + el = FN(isl_stream_read,BASE)(s); + *list = FN(LIST(EL),add)(*list, el); + if (!*list) + return isl_space_free(space); + + return space; +} + +/* Read a multi expression from "s". + * + * We first read a tuple space, collecting the element values in a list. + * Then we create an isl_multi_* from the space and the isl_*_list. + */ +__isl_give MULTI(BASE) *FN(isl_stream_read_multi,BASE)( + __isl_keep isl_stream *s) +{ + struct vars *v; + isl_set *dom = NULL; + isl_space *space; + MULTI(BASE) *multi = NULL; + LIST(EL) *list; + + v = vars_new(s->ctx); + if (!v) + return NULL; + + dom = isl_set_universe(isl_space_params_alloc(s->ctx, 0)); + if (next_is_tuple(s)) { + dom = read_map_tuple(s, dom, isl_dim_param, v, 0); + if (isl_stream_eat(s, ISL_TOKEN_TO)) + goto error; + } + if (!isl_set_plain_is_universe(dom)) + isl_die(s->ctx, isl_error_invalid, + "expecting universe parameter domain", goto error); + if (isl_stream_eat(s, '{')) + goto error; + + space = isl_set_get_space(dom); + + list = FN(LIST(EL),alloc)(s->ctx, 0); + space = read_tuple_space(s, v, space, 1, 0, &FN(read_el,BASE), &list); + multi = FN(FN(MULTI(BASE),from),LIST(BASE))(space, list); + + if (isl_stream_eat(s, '}')) + goto error; + + vars_free(v); + isl_set_free(dom); + return multi; +error: + vars_free(v); + isl_set_free(dom); + FN(MULTI(BASE),free)(multi); + return NULL; +} + +#undef TYPE_BASE +#define TYPE_BASE CAT(multi_,BASE) +#include "isl_read_from_str_templ.c" diff --git a/external/mit/isl/dist/isl_multi_splice_templ.c b/external/mit/isl/dist/isl_multi_splice_templ.c new file mode 100644 index 000000000000..8dca62089b72 --- /dev/null +++ b/external/mit/isl/dist/isl_multi_splice_templ.c @@ -0,0 +1,63 @@ +/* + * Copyright 2012 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 +#include + +#include + +/* Given two multi expressions, "multi1" + * + * [A1 A2] -> [B1 B2] + * + * where A2 starts at position "in_pos" and B2 starts at position "out_pos", + * and "multi2" + * + * [C] -> [D] + * + * return the multi expression + * + * [A1 C A2] -> [B1 D B2] + * + * We first insert input dimensions to obtain + * + * [A1 C A2] -> [B1 B2] + * + * and + * + * [A1 C A2] -> [D] + * + * and then apply range_splice. + */ +__isl_give MULTI(BASE) *FN(MULTI(BASE),splice)( + __isl_take MULTI(BASE) *multi1, unsigned in_pos, unsigned out_pos, + __isl_take MULTI(BASE) *multi2) +{ + isl_size n_in1; + isl_size n_in2; + + n_in1 = FN(MULTI(BASE),dim)(multi1, isl_dim_in); + n_in2 = FN(MULTI(BASE),dim)(multi2, isl_dim_in); + if (n_in1 < 0 || n_in2 < 0) + goto error; + + if (FN(MULTI(BASE),check_range)(multi1, isl_dim_in, in_pos, 0) < 0) + goto error; + + multi1 = FN(MULTI(BASE),insert_dims)(multi1, isl_dim_in, in_pos, n_in2); + multi2 = FN(MULTI(BASE),insert_dims)(multi2, isl_dim_in, n_in2, + n_in1 - in_pos); + multi2 = FN(MULTI(BASE),insert_dims)(multi2, isl_dim_in, 0, in_pos); + + return FN(MULTI(BASE),range_splice)(multi1, out_pos, multi2); +error: + FN(MULTI(BASE),free)(multi1); + FN(MULTI(BASE),free)(multi2); + return NULL; +} diff --git a/external/mit/isl/dist/isl_multi_templ.c b/external/mit/isl/dist/isl_multi_templ.c new file mode 100644 index 000000000000..6e0a6ed5bc3a --- /dev/null +++ b/external/mit/isl/dist/isl_multi_templ.c @@ -0,0 +1,990 @@ +/* + * Copyright 2011 Sven Verdoolaege + * Copyright 2012-2014 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 +#include +#include +#include + +#include + +#define MULTI_NAME(BASE) "isl_multi_" #BASE + +isl_ctx *FN(MULTI(BASE),get_ctx)(__isl_keep MULTI(BASE) *multi) +{ + return multi ? isl_space_get_ctx(multi->space) : NULL; +} + +/* Return the space of "multi". + */ +__isl_keep isl_space *FN(MULTI(BASE),peek_space)(__isl_keep MULTI(BASE) *multi) +{ + return multi ? multi->space : NULL; +} + +__isl_give isl_space *FN(MULTI(BASE),get_space)(__isl_keep MULTI(BASE) *multi) +{ + return isl_space_copy(FN(MULTI(BASE),peek_space)(multi)); +} + +__isl_give isl_space *FN(MULTI(BASE),get_domain_space)( + __isl_keep MULTI(BASE) *multi) +{ + return multi ? isl_space_domain(isl_space_copy(multi->space)) : NULL; +} + +/* Allocate a multi expression living in "space". + * + * If the number of base expressions is zero, then make sure + * there is enough room in the structure for the explicit domain, + * in case the type supports such an explicit domain. + */ +__isl_give MULTI(BASE) *FN(MULTI(BASE),alloc)(__isl_take isl_space *space) +{ + isl_ctx *ctx; + isl_size n; + MULTI(BASE) *multi; + + n = isl_space_dim(space, isl_dim_out); + if (n < 0) + goto error; + + ctx = isl_space_get_ctx(space); + if (n > 0) + multi = isl_calloc(ctx, MULTI(BASE), + sizeof(MULTI(BASE)) + (n - 1) * sizeof(struct EL *)); + else + multi = isl_calloc(ctx, MULTI(BASE), sizeof(MULTI(BASE))); + if (!multi) + goto error; + + multi->space = space; + multi->n = n; + multi->ref = 1; + if (FN(MULTI(BASE),has_explicit_domain)(multi)) + multi = FN(MULTI(BASE),init_explicit_domain)(multi); + return multi; +error: + isl_space_free(space); + return NULL; +} + +__isl_give MULTI(BASE) *FN(MULTI(BASE),dup)(__isl_keep MULTI(BASE) *multi) +{ + int i; + MULTI(BASE) *dup; + + if (!multi) + return NULL; + + dup = FN(MULTI(BASE),alloc)(isl_space_copy(multi->space)); + if (!dup) + return NULL; + + for (i = 0; i < multi->n; ++i) + dup = FN(FN(MULTI(BASE),set),BASE)(dup, i, + FN(EL,copy)(multi->u.p[i])); + if (FN(MULTI(BASE),has_explicit_domain)(multi)) + dup = FN(MULTI(BASE),copy_explicit_domain)(dup, multi); + + return dup; +} + +__isl_give MULTI(BASE) *FN(MULTI(BASE),cow)(__isl_take MULTI(BASE) *multi) +{ + if (!multi) + return NULL; + + if (multi->ref == 1) + return multi; + + multi->ref--; + return FN(MULTI(BASE),dup)(multi); +} + +__isl_give MULTI(BASE) *FN(MULTI(BASE),copy)(__isl_keep MULTI(BASE) *multi) +{ + if (!multi) + return NULL; + + multi->ref++; + return multi; +} + +__isl_null MULTI(BASE) *FN(MULTI(BASE),free)(__isl_take MULTI(BASE) *multi) +{ + int i; + + if (!multi) + return NULL; + + if (--multi->ref > 0) + return NULL; + + isl_space_free(multi->space); + for (i = 0; i < multi->n; ++i) + FN(EL,free)(multi->u.p[i]); + if (FN(MULTI(BASE),has_explicit_domain)(multi)) + FN(MULTI(BASE),free_explicit_domain)(multi); + free(multi); + + return NULL; +} + +/* Return the space of "multi". + * The caller is not allowed to modify "multi" between this call + * and the call to *_restore_space because the number + * of references needs to stay the same. + * The only exception is that isl_multi_*_free can be called instead. + * No copy is taken of multi->space if "multi" has only one reference + * such that it can be modified inplace if both have only a single reference. + */ +__isl_give isl_space *FN(MULTI(BASE),take_space)(__isl_keep MULTI(BASE) *multi) +{ + isl_space *space; + + if (!multi) + return NULL; + if (multi->ref != 1) + return FN(MULTI(BASE),get_space)(multi); + space = multi->space; + multi->space = NULL; + return space; +} + +/* Set the space of "multi" to "space", where the space of "multi" + * may be missing due to a preceding call to isl_multi_*_take_space. + * However, in this case, "multi" only has a single reference and + * then the call to isl_multi_*_cow has no effect. + */ +__isl_give MULTI(BASE) *FN(MULTI(BASE),restore_space)( + __isl_take MULTI(BASE) *multi, __isl_take isl_space *space) +{ + if (!multi || !space) + goto error; + + if (multi->space == space) { + isl_space_free(space); + return multi; + } + + multi = FN(MULTI(BASE),cow)(multi); + if (!multi) + goto error; + isl_space_free(multi->space); + multi->space = space; + + return multi; +error: + FN(MULTI(BASE),free)(multi); + isl_space_free(space); + return NULL; +} + +isl_size FN(MULTI(BASE),dim)(__isl_keep MULTI(BASE) *multi, + enum isl_dim_type type) +{ + return isl_space_dim(FN(MULTI(BASE),peek_space)(multi), type); +} + +/* Return the number of base expressions in "multi". + */ +isl_size FN(MULTI(BASE),size)(__isl_keep MULTI(BASE) *multi) +{ + return multi ? multi->n : isl_size_error; +} + +#undef TYPE +#define TYPE MULTI(BASE) +static +#include "check_type_range_templ.c" + +/* Return the base expression at position "pos" in "multi". + */ +static __isl_give EL *FN(MULTI(BASE),peek_at)(__isl_keep MULTI(BASE) *multi, + int pos) +{ + if (FN(MULTI(BASE),check_range)(multi, isl_dim_out, pos, 1) < 0) + return NULL; + return multi->u.p[pos]; +} + +/* Return a copy of the base expression at position "pos" in "multi". + */ +__isl_give EL *FN(MULTI(BASE),get_at)(__isl_keep MULTI(BASE) *multi, int pos) +{ + return FN(EL,copy)(FN(MULTI(BASE),peek_at)(multi, pos)); +} + +/* This is an alternative name for the function above. + */ +__isl_give EL *FN(FN(MULTI(BASE),get),BASE)(__isl_keep MULTI(BASE) *multi, + int pos) +{ + return FN(MULTI(BASE),get_at)(multi, pos); +} + +/* Return the base expression at position "pos" in "multi". + * This may be either a copy or the base expression itself + * if there is only one reference to "multi". + * This allows the base expression to be modified inplace + * if both the multi expression and this base expression + * have only a single reference. + * The caller is not allowed to modify "multi" between this call and + * the subsequent call to isl_multi_*_restore_at_*. + * The only exception is that isl_multi_*_free can be called instead. + */ +static __isl_give EL *FN(MULTI(BASE),take_at)(__isl_keep MULTI(BASE) *multi, + int pos) +{ + EL *el; + + if (!multi) + return NULL; + if (multi->ref != 1) + return FN(MULTI(BASE),get_at)(multi, pos); + if (FN(MULTI(BASE),check_range)(multi, isl_dim_out, pos, 1) < 0) + return NULL; + el = multi->u.p[pos]; + multi->u.p[pos] = NULL; + return el; +} + +/* Set the element at position "pos" of "multi" to "el", + * where the position may be empty if "multi" has only a single reference. + */ +static __isl_give MULTI(BASE) *FN(MULTI(BASE),restore_at)( + __isl_take MULTI(BASE) *multi, int pos, __isl_take EL *el) +{ + if (FN(MULTI(BASE),check_range)(multi, isl_dim_out, pos, 1) < 0 || !el) + goto error; + + if (multi->u.p[pos] == el) { + FN(EL,free)(el); + return multi; + } + + multi = FN(MULTI(BASE),cow)(multi); + if (!multi) + goto error; + + FN(EL,free)(multi->u.p[pos]); + multi->u.p[pos] = el; + + return multi; +error: + FN(MULTI(BASE),free)(multi); + FN(EL,free)(el); + return NULL; +} + +/* Set the element at position "pos" of "multi" to "el", + * where the position may be empty if "multi" has only a single reference. + * However, the space of "multi" is available and is checked + * for compatibility with "el". + */ +static __isl_give MULTI(BASE) *FN(MULTI(BASE),restore_check_space)( + __isl_take MULTI(BASE) *multi, int pos, __isl_take EL *el) +{ + isl_space *space; + + space = FN(MULTI(BASE),peek_space)(multi); + if (FN(EL,check_match_domain_space)(el, space) < 0) + multi = FN(MULTI(BASE),free)(multi); + return FN(MULTI(BASE),restore_at)(multi, pos, el); +} + +/* Replace the base expression at position "pos" in "multi" with "el". + */ +__isl_give MULTI(BASE) *FN(MULTI(BASE),set_at)( + __isl_take MULTI(BASE) *multi, int pos, __isl_take EL *el) +{ + isl_space *multi_space = NULL; + isl_space *el_space = NULL; + isl_bool match; + + multi_space = FN(MULTI(BASE),get_space)(multi); + match = FN(EL,matching_params)(el, multi_space); + if (match < 0) + goto error; + if (!match) { + multi = FN(MULTI(BASE),align_params)(multi, + FN(EL,get_space)(el)); + isl_space_free(multi_space); + multi_space = FN(MULTI(BASE),get_space)(multi); + el = FN(EL,align_params)(el, isl_space_copy(multi_space)); + } + + multi = FN(MULTI(BASE),restore_check_space)(multi, pos, el); + + isl_space_free(multi_space); + isl_space_free(el_space); + + return multi; +error: + FN(MULTI(BASE),free)(multi); + FN(EL,free)(el); + isl_space_free(multi_space); + isl_space_free(el_space); + return NULL; +} + +/* This is an alternative name for the function above. + */ +__isl_give MULTI(BASE) *FN(FN(MULTI(BASE),set),BASE)( + __isl_take MULTI(BASE) *multi, int pos, __isl_take EL *el) +{ + return FN(MULTI(BASE),set_at)(multi, pos, el); +} + +/* Return the base expressions of "multi" as a list. + */ +__isl_give LIST(EL) *FN(MULTI(BASE),get_list)( + __isl_keep MULTI(BASE) *multi) +{ + isl_size n; + int i; + LIST(EL) *list; + + n = FN(MULTI(BASE),size)(multi); + if (n < 0) + return NULL; + list = FN(LIST(EL),alloc)(FN(MULTI(BASE),get_ctx(multi)), n); + for (i = 0; i < n; ++i) { + EL *el = FN(MULTI(BASE),get_at)(multi, i); + list = FN(LIST(EL),add)(list, el); + } + + return list; +} + +/* Reset the space of "multi". This function is called from isl_pw_templ.c + * and doesn't know if the space of an element object is represented + * directly or through its domain. It therefore passes along both, + * which we pass along to the element function since we don't know how + * that is represented either. + * + * If "multi" has an explicit domain, then the caller is expected + * to make sure that any modification that would change the dimensions + * of the explicit domain has bee applied before this function is called. + */ +__isl_give MULTI(BASE) *FN(MULTI(BASE),reset_space_and_domain)( + __isl_take MULTI(BASE) *multi, __isl_take isl_space *space, + __isl_take isl_space *domain) +{ + isl_size n; + int i; + + n = FN(MULTI(BASE),size)(multi); + if (n < 0 || !space || !domain) + goto error; + + for (i = 0; i < n; ++i) { + EL *el; + + el = FN(MULTI(BASE),take_at)(multi, i); + el = FN(EL,reset_domain_space)(el, isl_space_copy(domain)); + multi = FN(MULTI(BASE),restore_at)(multi, i, el); + } + if (FN(MULTI(BASE),has_explicit_domain)(multi)) + multi = FN(MULTI(BASE),reset_explicit_domain_space)(multi, + isl_space_copy(domain)); + isl_space_free(domain); + + multi = FN(MULTI(BASE),restore_space)(multi, space); + + return multi; +error: + isl_space_free(domain); + isl_space_free(space); + FN(MULTI(BASE),free)(multi); + return NULL; +} + +__isl_give MULTI(BASE) *FN(MULTI(BASE),reset_domain_space)( + __isl_take MULTI(BASE) *multi, __isl_take isl_space *domain) +{ + isl_space *space, *multi_space; + + multi_space = FN(MULTI(BASE),get_space)(multi); + space = isl_space_extend_domain_with_range(isl_space_copy(domain), + multi_space); + return FN(MULTI(BASE),reset_space_and_domain)(multi, space, domain); +} + +__isl_give MULTI(BASE) *FN(MULTI(BASE),reset_space)( + __isl_take MULTI(BASE) *multi, __isl_take isl_space *space) +{ + isl_space *domain; + + domain = isl_space_domain(isl_space_copy(space)); + return FN(MULTI(BASE),reset_space_and_domain)(multi, space, domain); +} + +/* Reset the user pointer on all identifiers of parameters and tuples + * of the space of "multi". + */ +__isl_give MULTI(BASE) *FN(MULTI(BASE),reset_user)( + __isl_take MULTI(BASE) *multi) +{ + isl_space *space; + + space = FN(MULTI(BASE),get_space)(multi); + space = isl_space_reset_user(space); + + return FN(MULTI(BASE),reset_space)(multi, space); +} + +__isl_give MULTI(BASE) *FN(MULTI(BASE),realign_domain)( + __isl_take MULTI(BASE) *multi, __isl_take isl_reordering *exp) +{ + int i; + isl_size n; + isl_space *space; + + n = FN(MULTI(BASE),size)(multi); + if (n < 0 || !exp) + goto error; + + for (i = 0; i < n; ++i) { + EL *el; + + el = FN(MULTI(BASE),take_at)(multi, i); + el = FN(EL,realign_domain)(el, isl_reordering_copy(exp)); + multi = FN(MULTI(BASE),restore_at)(multi, i, el); + } + + space = isl_reordering_get_space(exp); + multi = FN(MULTI(BASE),reset_domain_space)(multi, space); + + isl_reordering_free(exp); + return multi; +error: + isl_reordering_free(exp); + FN(MULTI(BASE),free)(multi); + return NULL; +} + +/* Align the parameters of "multi" to those of "model". + * + * If "multi" has an explicit domain, then align the parameters + * of the domain first. + */ +__isl_give MULTI(BASE) *FN(MULTI(BASE),align_params)( + __isl_take MULTI(BASE) *multi, __isl_take isl_space *model) +{ + isl_ctx *ctx; + isl_bool equal_params; + isl_space *domain_space; + isl_reordering *exp; + + if (!multi || !model) + goto error; + + equal_params = isl_space_has_equal_params(multi->space, model); + if (equal_params < 0) + goto error; + if (equal_params) { + isl_space_free(model); + return multi; + } + + ctx = isl_space_get_ctx(model); + if (!isl_space_has_named_params(model)) + isl_die(ctx, isl_error_invalid, + "model has unnamed parameters", goto error); + if (!isl_space_has_named_params(multi->space)) + isl_die(ctx, isl_error_invalid, + "input has unnamed parameters", goto error); + + if (FN(MULTI(BASE),has_explicit_domain)(multi)) { + multi = FN(MULTI(BASE),align_explicit_domain_params)(multi, + isl_space_copy(model)); + if (!multi) + goto error; + } + domain_space = FN(MULTI(BASE),get_domain_space)(multi); + exp = isl_parameter_alignment_reordering(domain_space, model); + isl_space_free(domain_space); + multi = FN(MULTI(BASE),realign_domain)(multi, exp); + + isl_space_free(model); + return multi; +error: + isl_space_free(model); + FN(MULTI(BASE),free)(multi); + return NULL; +} + +/* Create a multi expression in the given space with the elements of "list" + * as base expressions. + * + * Since isl_multi_*_restore_* assumes that the element and + * the multi expression have matching spaces, the alignment + * (if any) needs to be performed beforehand. + */ +__isl_give MULTI(BASE) *FN(FN(MULTI(BASE),from),LIST(BASE))( + __isl_take isl_space *space, __isl_take LIST(EL) *list) +{ + int i; + isl_size n, dim; + isl_ctx *ctx; + MULTI(BASE) *multi; + + dim = isl_space_dim(space, isl_dim_out); + n = FN(FN(LIST(EL),n),BASE)(list); + if (dim < 0 || n < 0) + goto error; + + ctx = isl_space_get_ctx(space); + if (n != dim) + isl_die(ctx, isl_error_invalid, + "invalid number of elements in list", goto error); + + for (i = 0; i < n; ++i) { + EL *el = FN(LIST(EL),peek)(list, i); + space = isl_space_align_params(space, FN(EL,get_space)(el)); + } + multi = FN(MULTI(BASE),alloc)(isl_space_copy(space)); + for (i = 0; i < n; ++i) { + EL *el = FN(FN(LIST(EL),get),BASE)(list, i); + el = FN(EL,align_params)(el, isl_space_copy(space)); + multi = FN(MULTI(BASE),restore_check_space)(multi, i, el); + } + + isl_space_free(space); + FN(LIST(EL),free)(list); + return multi; +error: + isl_space_free(space); + FN(LIST(EL),free)(list); + return NULL; +} + +/* This function performs the same operation as isl_multi_*_from_*_list, + * but is considered as a function on an isl_space when exported. + */ +__isl_give MULTI(BASE) *FN(isl_space_multi,BASE)(__isl_take isl_space *space, + __isl_take LIST(EL) *list) +{ + return FN(FN(MULTI(BASE),from),LIST(BASE))(space, list); +} + +/* Drop the "n" output dimensions of "multi" starting at "first", + * where the space is assumed to have been adjusted already. + */ +static __isl_give MULTI(BASE) *FN(MULTI(BASE),drop_output_dims)( + __isl_take MULTI(BASE) *multi, unsigned first, unsigned n) +{ + int i; + + multi = FN(MULTI(BASE),cow)(multi); + if (!multi) + return NULL; + + for (i = 0; i < n; ++i) + FN(EL,free)(multi->u.p[first + i]); + for (i = first; i + n < multi->n; ++i) + multi->u.p[i] = multi->u.p[i + n]; + multi->n -= n; + if (n > 0 && FN(MULTI(BASE),has_explicit_domain)(multi)) + multi = FN(MULTI(BASE),init_explicit_domain)(multi); + + return multi; +} + +__isl_give MULTI(BASE) *FN(MULTI(BASE),drop_dims)( + __isl_take MULTI(BASE) *multi, + enum isl_dim_type type, unsigned first, unsigned n) +{ + isl_space *space; + isl_size size; + int i; + + if (FN(MULTI(BASE),check_range)(multi, type, first, n) < 0) + return FN(MULTI(BASE),free)(multi); + + space = FN(MULTI(BASE),take_space)(multi); + space = isl_space_drop_dims(space, type, first, n); + multi = FN(MULTI(BASE),restore_space)(multi, space); + + if (type == isl_dim_out) + return FN(MULTI(BASE),drop_output_dims)(multi, first, n); + + if (FN(MULTI(BASE),has_explicit_domain)(multi)) + multi = FN(MULTI(BASE),drop_explicit_domain_dims)(multi, + type, first, n); + + size = FN(MULTI(BASE),size)(multi); + if (size < 0) + return FN(MULTI(BASE),free)(multi); + for (i = 0; i < size; ++i) { + EL *el; + + el = FN(MULTI(BASE),take_at)(multi, i); + el = FN(EL,drop_dims)(el, type, first, n); + multi = FN(MULTI(BASE),restore_at)(multi, i, el); + } + + return multi; +} + +#undef TYPE +#define TYPE MULTI(BASE) + +#include "isl_check_named_params_templ.c" +static +#include "isl_align_params_bin_templ.c" + +/* Given two MULTI(BASE)s A -> B and C -> D, + * construct a MULTI(BASE) (A * C) -> [B -> D]. + * + * If "multi1" and/or "multi2" has an explicit domain, then + * intersect the domain of the result with these explicit domains. + */ +__isl_give MULTI(BASE) *FN(MULTI(BASE),range_product)( + __isl_take MULTI(BASE) *multi1, __isl_take MULTI(BASE) *multi2) +{ + int i; + isl_size n1, n2; + EL *el; + isl_space *space; + MULTI(BASE) *res; + + FN(MULTI(BASE),align_params_bin)(&multi1, &multi2); + n1 = FN(MULTI(BASE),size)(multi1); + n2 = FN(MULTI(BASE),size)(multi2); + if (n1 < 0 || n2 < 0) + goto error; + + space = isl_space_range_product(FN(MULTI(BASE),get_space)(multi1), + FN(MULTI(BASE),get_space)(multi2)); + res = FN(MULTI(BASE),alloc)(space); + + for (i = 0; i < n1; ++i) { + el = FN(FN(MULTI(BASE),get),BASE)(multi1, i); + res = FN(FN(MULTI(BASE),set),BASE)(res, i, el); + } + + for (i = 0; i < n2; ++i) { + el = FN(FN(MULTI(BASE),get),BASE)(multi2, i); + res = FN(FN(MULTI(BASE),set),BASE)(res, n1 + i, el); + } + + if (FN(MULTI(BASE),has_explicit_domain)(multi1)) + res = FN(MULTI(BASE),intersect_explicit_domain)(res, multi1); + if (FN(MULTI(BASE),has_explicit_domain)(multi2)) + res = FN(MULTI(BASE),intersect_explicit_domain)(res, multi2); + + FN(MULTI(BASE),free)(multi1); + FN(MULTI(BASE),free)(multi2); + return res; +error: + FN(MULTI(BASE),free)(multi1); + FN(MULTI(BASE),free)(multi2); + return NULL; +} + +/* Is the range of "multi" a wrapped relation? + */ +isl_bool FN(MULTI(BASE),range_is_wrapping)(__isl_keep MULTI(BASE) *multi) +{ + if (!multi) + return isl_bool_error; + return isl_space_range_is_wrapping(multi->space); +} + +/* Given a function A -> [B -> C], extract the function A -> B. + */ +__isl_give MULTI(BASE) *FN(MULTI(BASE),range_factor_domain)( + __isl_take MULTI(BASE) *multi) +{ + isl_space *space; + isl_size total, keep; + + total = FN(MULTI(BASE),dim)(multi, isl_dim_out); + if (total < 0) + return FN(MULTI(BASE),free)(multi); + if (!isl_space_range_is_wrapping(multi->space)) + isl_die(FN(MULTI(BASE),get_ctx)(multi), isl_error_invalid, + "range is not a product", + return FN(MULTI(BASE),free)(multi)); + + space = FN(MULTI(BASE),get_space)(multi); + space = isl_space_range_factor_domain(space); + keep = isl_space_dim(space, isl_dim_out); + if (keep < 0) + multi = FN(MULTI(BASE),free)(multi); + multi = FN(MULTI(BASE),drop_dims)(multi, + isl_dim_out, keep, total - keep); + multi = FN(MULTI(BASE),reset_space)(multi, space); + + return multi; +} + +/* Given a function A -> [B -> C], extract the function A -> C. + */ +__isl_give MULTI(BASE) *FN(MULTI(BASE),range_factor_range)( + __isl_take MULTI(BASE) *multi) +{ + isl_space *space; + isl_size total, keep; + + total = FN(MULTI(BASE),dim)(multi, isl_dim_out); + if (total < 0) + return FN(MULTI(BASE),free)(multi); + if (!isl_space_range_is_wrapping(multi->space)) + isl_die(FN(MULTI(BASE),get_ctx)(multi), isl_error_invalid, + "range is not a product", + return FN(MULTI(BASE),free)(multi)); + + space = FN(MULTI(BASE),get_space)(multi); + space = isl_space_range_factor_range(space); + keep = isl_space_dim(space, isl_dim_out); + if (keep < 0) + multi = FN(MULTI(BASE),free)(multi); + multi = FN(MULTI(BASE),drop_dims)(multi, isl_dim_out, 0, total - keep); + multi = FN(MULTI(BASE),reset_space)(multi, space); + + return multi; +} + +/* Given a function [B -> C], extract the function C. + */ +__isl_give MULTI(BASE) *FN(MULTI(BASE),factor_range)( + __isl_take MULTI(BASE) *multi) +{ + isl_space *space; + isl_size total, keep; + + total = FN(MULTI(BASE),dim)(multi, isl_dim_set); + if (total < 0) + return FN(MULTI(BASE),free)(multi); + if (!isl_space_is_wrapping(multi->space)) + isl_die(FN(MULTI(BASE),get_ctx)(multi), isl_error_invalid, + "not a product", return FN(MULTI(BASE),free)(multi)); + + space = FN(MULTI(BASE),get_space)(multi); + space = isl_space_factor_range(space); + keep = isl_space_dim(space, isl_dim_set); + if (keep < 0) + multi = FN(MULTI(BASE),free)(multi); + multi = FN(MULTI(BASE),drop_dims)(multi, isl_dim_set, 0, total - keep); + multi = FN(MULTI(BASE),reset_space)(multi, space); + + return multi; +} + +__isl_give MULTI(BASE) *FN(MULTI(BASE),flatten_range)( + __isl_take MULTI(BASE) *multi) +{ + isl_space *space; + + space = FN(MULTI(BASE),take_space)(multi); + space = isl_space_flatten_range(space); + multi = FN(MULTI(BASE),restore_space)(multi, space); + + return multi; +} + +/* Given two MULTI(BASE)s A -> B and C -> D, + * construct a MULTI(BASE) (A * C) -> (B, D). + */ +__isl_give MULTI(BASE) *FN(MULTI(BASE),flat_range_product)( + __isl_take MULTI(BASE) *multi1, __isl_take MULTI(BASE) *multi2) +{ + MULTI(BASE) *multi; + + multi = FN(MULTI(BASE),range_product)(multi1, multi2); + multi = FN(MULTI(BASE),flatten_range)(multi); + return multi; +} + +/* Given two multi expressions, "multi1" + * + * [A] -> [B1 B2] + * + * where B2 starts at position "pos", and "multi2" + * + * [A] -> [D] + * + * return the multi expression + * + * [A] -> [B1 D B2] + */ +__isl_give MULTI(BASE) *FN(MULTI(BASE),range_splice)( + __isl_take MULTI(BASE) *multi1, unsigned pos, + __isl_take MULTI(BASE) *multi2) +{ + MULTI(BASE) *res; + isl_size dim; + + dim = FN(MULTI(BASE),size)(multi1); + if (dim < 0 || !multi2) + goto error; + + if (FN(MULTI(BASE),check_range)(multi1, isl_dim_out, pos, 0) < 0) + goto error; + + res = FN(MULTI(BASE),copy)(multi1); + res = FN(MULTI(BASE),drop_dims)(res, isl_dim_out, pos, dim - pos); + multi1 = FN(MULTI(BASE),drop_dims)(multi1, isl_dim_out, 0, pos); + + res = FN(MULTI(BASE),flat_range_product)(res, multi2); + res = FN(MULTI(BASE),flat_range_product)(res, multi1); + + return res; +error: + FN(MULTI(BASE),free)(multi1); + FN(MULTI(BASE),free)(multi2); + return NULL; +} + +#undef TYPE +#define TYPE MULTI(BASE) + +static +#include "isl_type_has_equal_space_bin_templ.c" +static +#include "isl_type_check_equal_space_templ.c" + +/* This function is currently only used from isl_aff.c + */ +static __isl_give MULTI(BASE) *FN(MULTI(BASE),bin_op)( + __isl_take MULTI(BASE) *multi1, __isl_take MULTI(BASE) *multi2, + __isl_give EL *(*fn)(__isl_take EL *, __isl_take EL *)) + __attribute__ ((unused)); + +/* Pairwise perform "fn" to the elements of "multi1" and "multi2" and + * return the result. + * + * If "multi2" has an explicit domain, then + * intersect the domain of the result with this explicit domain. + */ +static __isl_give MULTI(BASE) *FN(MULTI(BASE),bin_op)( + __isl_take MULTI(BASE) *multi1, __isl_take MULTI(BASE) *multi2, + __isl_give EL *(*fn)(__isl_take EL *, __isl_take EL *)) +{ + isl_size n; + int i; + + FN(MULTI(BASE),align_params_bin)(&multi1, &multi2); + n = FN(MULTI(BASE),size)(multi1); + if (n < 0 || FN(MULTI(BASE),check_equal_space)(multi1, multi2) < 0) + goto error; + + for (i = 0; i < n; ++i) { + EL *el1, *el2; + + el2 = FN(MULTI(BASE),get_at)(multi2, i); + el1 = FN(MULTI(BASE),take_at)(multi1, i); + el1 = fn(el1, el2); + multi1 = FN(MULTI(BASE),restore_at)(multi1, i, el1); + } + + if (FN(MULTI(BASE),has_explicit_domain)(multi2)) + multi1 = FN(MULTI(BASE),intersect_explicit_domain)(multi1, + multi2); + + FN(MULTI(BASE),free)(multi2); + return multi1; +error: + FN(MULTI(BASE),free)(multi1); + FN(MULTI(BASE),free)(multi2); + return NULL; +} + +/* Only used on some multi-expressions. + */ +static isl_bool FN(MULTI(BASE),any)(__isl_keep MULTI(BASE) *multi, + isl_bool (*test)(__isl_keep EL *)) __attribute__ ((unused)); + +/* Does "test" succeed on any base expression of "multi"? + */ +static isl_bool FN(MULTI(BASE),any)(__isl_keep MULTI(BASE) *multi, + isl_bool (*test)(__isl_keep EL *)) +{ + isl_size n; + int i; + + n = FN(MULTI(BASE),size)(multi); + if (n < 0) + return isl_bool_error; + + for (i = 0; i < n; ++i) { + isl_bool any = test(multi->u.p[i]); + if (any < 0 || any) + return any; + } + + return isl_bool_false; +} + +/* Only used on some multi-expressions. + */ +static isl_bool FN(MULTI(BASE),every)(__isl_keep MULTI(BASE) *multi, + isl_bool (*test)(__isl_keep EL *)) __attribute__ ((unused)); + +/* Does "test" succeed on every base expression of "multi"? + */ +static isl_bool FN(MULTI(BASE),every)(__isl_keep MULTI(BASE) *multi, + isl_bool (*test)(__isl_keep EL *)) +{ + isl_size n; + int i; + + n = FN(MULTI(BASE),size)(multi); + if (n < 0) + return isl_bool_error; + + for (i = 0; i < n; ++i) { + isl_bool every = test(multi->u.p[i]); + if (every < 0 || !every) + return every; + } + + return isl_bool_true; +} + +#undef TYPE +#define TYPE MULTI(BASE) +#include "isl_from_range_templ.c" + +/* Are "multi1" and "multi2" obviously equal? + */ +isl_bool FN(MULTI(BASE),plain_is_equal)(__isl_keep MULTI(BASE) *multi1, + __isl_keep MULTI(BASE) *multi2) +{ + int i; + isl_bool equal; + + if (!multi1 || !multi2) + return isl_bool_error; + if (multi1->n != multi2->n) + return isl_bool_false; + equal = isl_space_is_equal(multi1->space, multi2->space); + if (equal < 0 || !equal) + return equal; + + for (i = 0; i < multi1->n; ++i) { + equal = FN(EL,plain_is_equal)(multi1->u.p[i], multi2->u.p[i]); + if (equal < 0 || !equal) + return equal; + } + + if (FN(MULTI(BASE),has_explicit_domain)(multi1) || + FN(MULTI(BASE),has_explicit_domain)(multi2)) { + equal = FN(MULTI(BASE),equal_explicit_domain)(multi1, multi2); + if (equal < 0 || !equal) + return equal; + } + + return isl_bool_true; +} diff --git a/external/mit/isl/dist/isl_multi_templ.h b/external/mit/isl/dist/isl_multi_templ.h new file mode 100644 index 000000000000..c5049adcc43b --- /dev/null +++ b/external/mit/isl/dist/isl_multi_templ.h @@ -0,0 +1,34 @@ +#include + +#include + +/* A multiple expression with base expressions of type EL. + * + * "space" is the space in which the multiple expression lives. + * "n" is the number of base expression and is equal + * to the output or set dimension of "space". + * "p" is an array of size "n" of base expressions. + * The array is only accessible when n > 0. + * "dom" is the explicit domain, if present + * The explicit domain is only accessible when n == 0. + */ +struct MULTI(BASE) { + int ref; + isl_space *space; + + int n; + struct { +#ifdef EXPLICIT_DOMAIN + DOM *dom; +#endif + EL *p[1]; + } u; +}; + +__isl_give MULTI(BASE) *CAT(MULTI(BASE),_alloc)(__isl_take isl_space *space); +__isl_keep isl_space *FN(MULTI(BASE),peek_space)(__isl_keep MULTI(BASE) *multi); + +#ifdef EXPLICIT_DOMAIN +isl_bool CAT(MULTI(BASE),_has_non_trivial_domain)( + __isl_keep MULTI(BASE) *multi); +#endif diff --git a/external/mit/isl/dist/isl_multi_tuple_id_templ.c b/external/mit/isl/dist/isl_multi_tuple_id_templ.c new file mode 100644 index 000000000000..87f9fe6b71d8 --- /dev/null +++ b/external/mit/isl/dist/isl_multi_tuple_id_templ.c @@ -0,0 +1,145 @@ +/* + * 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 + +#include + +const char *FN(MULTI(BASE),get_tuple_name)(__isl_keep MULTI(BASE) *multi, + enum isl_dim_type type) +{ + return multi ? isl_space_get_tuple_name(multi->space, type) : NULL; +} + +/* Does the specified tuple have an id? + */ +isl_bool FN(MULTI(BASE),has_tuple_id)(__isl_keep MULTI(BASE) *multi, + enum isl_dim_type type) +{ + if (!multi) + return isl_bool_error; + return isl_space_has_tuple_id(multi->space, type); +} + +/* Does the (range) tuple of "multi" have an identifier? + * + * Technically, the implementation should use isl_dim_set if "multi" + * lives in a set space and isl_dim_out if it lives in a map space. + * Internally, however, it can be assumed that isl_dim_set is equal + * to isl_dim_out. + */ +isl_bool FN(MULTI(BASE),has_range_tuple_id)(__isl_keep MULTI(BASE) *multi) +{ + return FN(MULTI(BASE),has_tuple_id)(multi, isl_dim_out); +} + +/* Return the id of the specified tuple. + */ +__isl_give isl_id *FN(MULTI(BASE),get_tuple_id)(__isl_keep MULTI(BASE) *multi, + enum isl_dim_type type) +{ + return multi ? isl_space_get_tuple_id(multi->space, type) : NULL; +} + +/* Return the identifier of the (range) tuple of "multi", assuming it has one. + * + * Technically, the implementation should use isl_dim_set if "multi" + * lives in a set space and isl_dim_out if it lives in a map space. + * Internally, however, it can be assumed that isl_dim_set is equal + * to isl_dim_out. + */ +__isl_give isl_id *FN(MULTI(BASE),get_range_tuple_id)( + __isl_keep MULTI(BASE) *multi) +{ + return FN(MULTI(BASE),get_tuple_id)(multi, isl_dim_out); +} + +__isl_give MULTI(BASE) *FN(MULTI(BASE),set_tuple_name)( + __isl_keep MULTI(BASE) *multi, enum isl_dim_type type, + const char *s) +{ + isl_space *space; + + multi = FN(MULTI(BASE),cow)(multi); + if (!multi) + return NULL; + + space = FN(MULTI(BASE),get_space)(multi); + space = isl_space_set_tuple_name(space, type, s); + + return FN(MULTI(BASE),reset_space)(multi, space); +} + +__isl_give MULTI(BASE) *FN(MULTI(BASE),set_tuple_id)( + __isl_take MULTI(BASE) *multi, enum isl_dim_type type, + __isl_take isl_id *id) +{ + isl_space *space; + + multi = FN(MULTI(BASE),cow)(multi); + if (!multi) + goto error; + + space = FN(MULTI(BASE),get_space)(multi); + space = isl_space_set_tuple_id(space, type, id); + + return FN(MULTI(BASE),reset_space)(multi, space); +error: + isl_id_free(id); + return NULL; +} + +/* Replace the identifier of the (range) tuple of "multi" by "id". + * + * Technically, the implementation should use isl_dim_set if "multi" + * lives in a set space and isl_dim_out if it lives in a map space. + * Internally, however, it can be assumed that isl_dim_set is equal + * to isl_dim_out. + */ +__isl_give MULTI(BASE) *FN(MULTI(BASE),set_range_tuple_id)( + __isl_take MULTI(BASE) *multi, __isl_take isl_id *id) +{ + return FN(MULTI(BASE),set_tuple_id)(multi, isl_dim_out, id); +} + +/* Drop the id on the specified tuple. + */ +__isl_give MULTI(BASE) *FN(MULTI(BASE),reset_tuple_id)( + __isl_take MULTI(BASE) *multi, enum isl_dim_type type) +{ + isl_space *space; + + if (!multi) + return NULL; + if (!FN(MULTI(BASE),has_tuple_id)(multi, type)) + return multi; + + multi = FN(MULTI(BASE),cow)(multi); + if (!multi) + return NULL; + + space = FN(MULTI(BASE),get_space)(multi); + space = isl_space_reset_tuple_id(space, type); + + return FN(MULTI(BASE),reset_space)(multi, space); +} + +/* Drop the identifier of the (range) tuple of "multi". + * + * Technically, the implementation should use isl_dim_set if "multi" + * lives in a set space and isl_dim_out if it lives in a map space. + * Internally, however, it can be assumed that isl_dim_set is equal + * to isl_dim_out. + */ +__isl_give MULTI(BASE) *FN(MULTI(BASE),reset_range_tuple_id)( + __isl_take MULTI(BASE) *multi) +{ + return FN(MULTI(BASE),reset_tuple_id)(multi, isl_dim_out); +} diff --git a/external/mit/isl/dist/isl_multi_un_op_templ.c b/external/mit/isl/dist/isl_multi_un_op_templ.c new file mode 100644 index 000000000000..cdee6182496e --- /dev/null +++ b/external/mit/isl/dist/isl_multi_un_op_templ.c @@ -0,0 +1,53 @@ +/* + * Copyright 2014 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 + +/* Data structure that specifies how isl_multi_*_un_op should + * modify its input. + * + * If "fn_space" is set, then it is applied to the space. + * + * "fn_el" is applied to each base expression. + */ +S(MULTI(BASE),un_op_control) { + __isl_give isl_space *(*fn_space)(__isl_take isl_space *space); + __isl_give EL *(*fn_el)(__isl_take EL *el); +}; + +/* Modify "multi" based on "control". + */ +static __isl_give MULTI(BASE) *FN(MULTI(BASE),un_op)( + __isl_take MULTI(BASE) *multi, S(MULTI(BASE),un_op_control) *control) +{ + int i; + isl_size n; + isl_space *space; + + n = FN(MULTI(BASE),size)(multi); + if (n < 0) + return FN(MULTI(BASE),free)(multi); + + for (i = 0; i < n; ++i) { + EL *el; + + el = FN(MULTI(BASE),take_at)(multi, i); + el = control->fn_el(el); + multi = FN(MULTI(BASE),restore_at)(multi, i, el); + } + + if (!control->fn_space) + return multi; + + space = FN(MULTI(BASE),take_space)(multi); + space = control->fn_space(space); + multi = FN(MULTI(BASE),restore_space)(multi, space); + + return multi; +} diff --git a/external/mit/isl/dist/isl_multi_unbind_params_templ.c b/external/mit/isl/dist/isl_multi_unbind_params_templ.c new file mode 100644 index 000000000000..474331954012 --- /dev/null +++ b/external/mit/isl/dist/isl_multi_unbind_params_templ.c @@ -0,0 +1,14 @@ +/* + * Copyright 2019 Cerebras Systems + * + * Use of this software is governed by the MIT license + * + * Written by Sven Verdoolaege, + * Cerebras Systems, 175 S San Antonio Rd, Los Altos, CA, USA + */ + +#include + +#undef TYPE +#define TYPE MULTI(BASE) +#include "isl_unbind_params_templ.c" diff --git a/external/mit/isl/dist/isl_multi_union_add_templ.c b/external/mit/isl/dist/isl_multi_union_add_templ.c new file mode 100644 index 000000000000..3178998d3250 --- /dev/null +++ b/external/mit/isl/dist/isl_multi_union_add_templ.c @@ -0,0 +1,81 @@ +/* + * Copyright 2017 Sven Verdoolaege + * + * Use of this software is governed by the MIT license + * + * Written by Sven Verdoolaege. + */ + +#include + +/* Compute the sum of "multi1" and "multi2" on the union of their domains, + * with the actual sum on the shared domain and + * the defined expression on the symmetric difference of the domains. + * + * We simply iterate over the elements in both arguments and + * call isl_union_pw_aff_union_add on each of them, if there is + * at least one element. + * + * Otherwise, the two expressions have an explicit domain and + * the union of these explicit domains is computed. + * This assumes that the explicit domains are either both in terms + * of specific domains elements or both in terms of parameters. + * However, if one of the expressions does not have any constraints + * on its explicit domain, then this is allowed as well and the result + * is the expression with no constraints on its explicit domain. + */ +__isl_give MULTI(BASE) *FN(MULTI(BASE),union_add)( + __isl_take MULTI(BASE) *multi1, __isl_take MULTI(BASE) *multi2) +{ + isl_bool has_domain, is_params1, is_params2; + + if (!multi1) + goto error; + if (multi1->n > 0) + return FN(MULTI(BASE),bin_op)(multi1, multi2, + &FN(EL,union_add)); + FN(MULTI(BASE),align_params_bin)(&multi1, &multi2); + if (FN(MULTI(BASE),check_equal_space)(multi1, multi2) < 0) + goto error; + if (FN(MULTI(BASE),check_has_explicit_domain)(multi1) < 0 || + FN(MULTI(BASE),check_has_explicit_domain)(multi2) < 0) + goto error; + + has_domain = FN(MULTI(BASE),has_non_trivial_domain)(multi1); + if (has_domain < 0) + goto error; + if (!has_domain) { + FN(MULTI(BASE),free)(multi2); + return multi1; + } + has_domain = FN(MULTI(BASE),has_non_trivial_domain)(multi2); + if (has_domain < 0) + goto error; + if (!has_domain) { + FN(MULTI(BASE),free)(multi1); + return multi2; + } + + is_params1 = FN(DOM,is_params)(multi1->u.dom); + is_params2 = FN(DOM,is_params)(multi2->u.dom); + if (is_params1 < 0 || is_params2 < 0) + goto error; + if (is_params1 != is_params2) + isl_die(FN(MULTI(BASE),get_ctx)(multi1), + isl_error_invalid, + "cannot compute union of concrete domain and " + "parameter constraints", goto error); + multi1 = FN(MULTI(BASE),cow)(multi1); + if (!multi1) + goto error; + multi1->u.dom = FN(DOM,union)(multi1->u.dom, + FN(DOM,copy)(multi2->u.dom)); + if (!multi1->u.dom) + goto error; + FN(MULTI(BASE),free)(multi2); + return multi1; +error: + FN(MULTI(BASE),free)(multi1); + FN(MULTI(BASE),free)(multi2); + return NULL; +} diff --git a/external/mit/isl/dist/isl_multi_union_pw_aff_explicit_domain.c b/external/mit/isl/dist/isl_multi_union_pw_aff_explicit_domain.c new file mode 100644 index 000000000000..7ff9b12bb644 --- /dev/null +++ b/external/mit/isl/dist/isl_multi_union_pw_aff_explicit_domain.c @@ -0,0 +1,51 @@ +/* + * Copyright 2017 Sven Verdoolaege + * + * Use of this software is governed by the MIT license + * + * Written by Sven Verdoolaege. + */ + +/* Initialize the explicit domain of "mupa". + * + * The explicit domain is initialized to a universe parameter set. + * It may later be specialized with constraints on the parameter or + * specific domain instances. + */ +static __isl_give isl_multi_union_pw_aff * +isl_multi_union_pw_aff_init_explicit_domain( + __isl_take isl_multi_union_pw_aff *mupa) +{ + isl_space *space; + + if (isl_multi_union_pw_aff_check_has_explicit_domain(mupa) < 0) + return isl_multi_union_pw_aff_free(mupa); + space = isl_space_params(isl_multi_union_pw_aff_get_space(mupa)); + mupa->u.dom = isl_union_set_from_set(isl_set_universe(space)); + if (!mupa->u.dom) + return isl_multi_union_pw_aff_free(mupa); + return mupa; +} + +/* Drop the "n" dimensions of type "type" starting at position "pos" + * of the explicit domain of "mupa". + */ +static __isl_give isl_multi_union_pw_aff * +isl_multi_union_pw_aff_drop_explicit_domain_dims( + __isl_take isl_multi_union_pw_aff *mupa, + enum isl_dim_type type, unsigned pos, unsigned n) +{ + if (isl_multi_union_pw_aff_check_has_explicit_domain(mupa) < 0) + return isl_multi_union_pw_aff_free(mupa); + if (type != isl_dim_param) + isl_die(isl_multi_union_pw_aff_get_ctx(mupa), isl_error_invalid, + "can only drop parameters", + return isl_multi_union_pw_aff_free(mupa)); + mupa = isl_multi_union_pw_aff_cow(mupa); + if (!mupa) + return NULL; + mupa->u.dom = isl_union_set_project_out(mupa->u.dom, type, pos, n); + if (!mupa->u.dom) + return isl_multi_union_pw_aff_free(mupa); + return mupa; +} diff --git a/external/mit/isl/dist/isl_multi_zero_space_templ.c b/external/mit/isl/dist/isl_multi_zero_space_templ.c new file mode 100644 index 000000000000..8bd027b2ef53 --- /dev/null +++ b/external/mit/isl/dist/isl_multi_zero_space_templ.c @@ -0,0 +1,21 @@ +/* + * Copyright 2020 Cerebras Systems + * + * Use of this software is governed by the MIT license + * + * Written by Sven Verdoolaege, + * Cerebras Systems, 175 S San Antonio Rd, Los Altos, CA, USA + */ + +#include + +#include "isl_multi_macro.h" + +/* This function performs the same operation as isl_multi_*_zero, + * but is considered as a function on an isl_space when exported. + */ +__isl_give MULTI(BASE) *FN(isl_space_zero_multi,BASE)( + __isl_take isl_space *space) +{ + return FN(MULTI(BASE),zero)(space); +} diff --git a/external/mit/isl/dist/isl_multi_zero_templ.c b/external/mit/isl/dist/isl_multi_zero_templ.c new file mode 100644 index 000000000000..dee3a8fb2646 --- /dev/null +++ b/external/mit/isl/dist/isl_multi_zero_templ.c @@ -0,0 +1,53 @@ +/* + * Copyright 2012 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 +#include + +#include + +/* Construct a multi expression in the given space with value zero in + * each of the output dimensions. + */ +__isl_give MULTI(BASE) *FN(MULTI(BASE),zero)(__isl_take isl_space *space) +{ + isl_size n; + MULTI(BASE) *multi; + + n = isl_space_dim(space , isl_dim_out); + if (n < 0) + goto error; + + multi = FN(MULTI(BASE),alloc)(isl_space_copy(space)); + + if (!n) + isl_space_free(space); + else { + int i; + isl_local_space *ls; + EL *el; + + space = isl_space_domain(space); + ls = isl_local_space_from_space(space); + el = FN(EL,zero_on_domain)(ls); + + for (i = 0; i < n; ++i) + multi = FN(FN(MULTI(BASE),set),BASE)(multi, i, + FN(EL,copy)(el)); + + FN(EL,free)(el); + } + + return multi; +error: + isl_space_free(space); + return NULL; +} + +#include "isl_multi_zero_space_templ.c" diff --git a/external/mit/isl/dist/isl_obj.c b/external/mit/isl/dist/isl_obj.c new file mode 100644 index 000000000000..da593d3ffc1b --- /dev/null +++ b/external/mit/isl/dist/isl_obj.c @@ -0,0 +1,365 @@ +/* + * Copyright 2010 INRIA Saclay + * Copyright 2014 Ecole Normale Superieure + * Copyright 2014 INRIA Rocquencourt + * + * 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 + * and Inria Paris - Rocquencourt, Domaine de Voluceau - Rocquencourt, + * B.P. 105 - 78153 Le Chesnay, France + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static void *isl_obj_val_copy(void *v) +{ + return isl_val_copy((isl_val *)v); +} + +static void isl_obj_val_free(void *v) +{ + isl_val_free((isl_val *)v); +} + +static __isl_give isl_printer *isl_obj_val_print(__isl_take isl_printer *p, + void *v) +{ + return isl_printer_print_val(p, (isl_val *)v); +} + +static void *isl_obj_val_add(void *v1, void *v2) +{ + return isl_val_add((isl_val *) v1, (isl_val *) v2); +} + +struct isl_obj_vtable isl_obj_val_vtable = { + isl_obj_val_copy, + isl_obj_val_add, + isl_obj_val_print, + isl_obj_val_free +}; + +static void *isl_obj_map_copy(void *v) +{ + return isl_map_copy((struct isl_map *)v); +} + +static void isl_obj_map_free(void *v) +{ + isl_map_free((struct isl_map *)v); +} + +static __isl_give isl_printer *isl_obj_map_print(__isl_take isl_printer *p, + void *v) +{ + return isl_printer_print_map(p, (struct isl_map *)v); +} + +static void *isl_obj_map_add(void *v1, void *v2) +{ + return isl_map_union((struct isl_map *)v1, (struct isl_map *)v2); +} + +struct isl_obj_vtable isl_obj_map_vtable = { + isl_obj_map_copy, + isl_obj_map_add, + isl_obj_map_print, + isl_obj_map_free +}; + +static void *isl_obj_union_map_copy(void *v) +{ + return isl_union_map_copy((isl_union_map *)v); +} + +static void isl_obj_union_map_free(void *v) +{ + isl_union_map_free((isl_union_map *)v); +} + +static __isl_give isl_printer *isl_obj_union_map_print(__isl_take isl_printer *p, + void *v) +{ + return isl_printer_print_union_map(p, (isl_union_map *)v); +} + +static void *isl_obj_union_map_add(void *v1, void *v2) +{ + return isl_union_map_union((isl_union_map *)v1, (isl_union_map *)v2); +} + +struct isl_obj_vtable isl_obj_union_map_vtable = { + isl_obj_union_map_copy, + isl_obj_union_map_add, + isl_obj_union_map_print, + isl_obj_union_map_free +}; + +static void *isl_obj_set_copy(void *v) +{ + return isl_set_copy((struct isl_set *)v); +} + +static void isl_obj_set_free(void *v) +{ + isl_set_free((struct isl_set *)v); +} + +static __isl_give isl_printer *isl_obj_set_print(__isl_take isl_printer *p, + void *v) +{ + return isl_printer_print_set(p, (struct isl_set *)v); +} + +static void *isl_obj_set_add(void *v1, void *v2) +{ + return isl_set_union((struct isl_set *)v1, (struct isl_set *)v2); +} + +struct isl_obj_vtable isl_obj_set_vtable = { + isl_obj_set_copy, + isl_obj_set_add, + isl_obj_set_print, + isl_obj_set_free +}; + +static void *isl_obj_union_set_copy(void *v) +{ + return isl_union_set_copy((isl_union_set *)v); +} + +static void isl_obj_union_set_free(void *v) +{ + isl_union_set_free((isl_union_set *)v); +} + +static __isl_give isl_printer *isl_obj_union_set_print(__isl_take isl_printer *p, + void *v) +{ + return isl_printer_print_union_set(p, (isl_union_set *)v); +} + +static void *isl_obj_union_set_add(void *v1, void *v2) +{ + return isl_union_set_union((isl_union_set *)v1, (isl_union_set *)v2); +} + +struct isl_obj_vtable isl_obj_union_set_vtable = { + isl_obj_union_set_copy, + isl_obj_union_set_add, + isl_obj_union_set_print, + isl_obj_union_set_free +}; + +static void *isl_obj_pw_multi_aff_copy(void *v) +{ + return isl_pw_multi_aff_copy((isl_pw_multi_aff *) v); +} + +static void isl_obj_pw_multi_aff_free(void *v) +{ + isl_pw_multi_aff_free((isl_pw_multi_aff *) v); +} + +static __isl_give isl_printer *isl_obj_pw_multi_aff_print( + __isl_take isl_printer *p, void *v) +{ + return isl_printer_print_pw_multi_aff(p, (isl_pw_multi_aff *) v); +} + +static void *isl_obj_pw_multi_aff_add(void *v1, void *v2) +{ + return isl_pw_multi_aff_add((isl_pw_multi_aff *) v1, + (isl_pw_multi_aff *) v2); +} + +struct isl_obj_vtable isl_obj_pw_multi_aff_vtable = { + isl_obj_pw_multi_aff_copy, + isl_obj_pw_multi_aff_add, + isl_obj_pw_multi_aff_print, + isl_obj_pw_multi_aff_free +}; + +static void *isl_obj_none_copy(void *v) +{ + return v; +} + +static void isl_obj_none_free(void *v) +{ +} + +static __isl_give isl_printer *isl_obj_none_print(__isl_take isl_printer *p, + void *v) +{ + return p; +} + +static void *isl_obj_none_add(void *v1, void *v2) +{ + return NULL; +} + +struct isl_obj_vtable isl_obj_none_vtable = { + isl_obj_none_copy, + isl_obj_none_add, + isl_obj_none_print, + isl_obj_none_free +}; + +static void *isl_obj_pw_qp_copy(void *v) +{ + return isl_pw_qpolynomial_copy((struct isl_pw_qpolynomial *)v); +} + +static void isl_obj_pw_qp_free(void *v) +{ + isl_pw_qpolynomial_free((struct isl_pw_qpolynomial *)v); +} + +static __isl_give isl_printer *isl_obj_pw_qp_print(__isl_take isl_printer *p, + void *v) +{ + return isl_printer_print_pw_qpolynomial(p, + (struct isl_pw_qpolynomial *)v); +} + +static void *isl_obj_pw_qp_add(void *v1, void *v2) +{ + return isl_pw_qpolynomial_add((struct isl_pw_qpolynomial *)v1, + (struct isl_pw_qpolynomial *)v2); +} + +struct isl_obj_vtable isl_obj_pw_qpolynomial_vtable = { + isl_obj_pw_qp_copy, + isl_obj_pw_qp_add, + isl_obj_pw_qp_print, + isl_obj_pw_qp_free +}; + +static void *isl_obj_union_pw_qp_copy(void *v) +{ + return isl_union_pw_qpolynomial_copy((struct isl_union_pw_qpolynomial *)v); +} + +static void isl_obj_union_pw_qp_free(void *v) +{ + isl_union_pw_qpolynomial_free((struct isl_union_pw_qpolynomial *)v); +} + +static __isl_give isl_printer *isl_obj_union_pw_qp_print( + __isl_take isl_printer *p, void *v) +{ + return isl_printer_print_union_pw_qpolynomial(p, + (struct isl_union_pw_qpolynomial *)v); +} + +static void *isl_obj_union_pw_qp_add(void *v1, void *v2) +{ + return isl_union_pw_qpolynomial_add( + (struct isl_union_pw_qpolynomial *)v1, + (struct isl_union_pw_qpolynomial *)v2); +} + +struct isl_obj_vtable isl_obj_union_pw_qpolynomial_vtable = { + isl_obj_union_pw_qp_copy, + isl_obj_union_pw_qp_add, + isl_obj_union_pw_qp_print, + isl_obj_union_pw_qp_free +}; + +static void *isl_obj_pw_qpf_copy(void *v) +{ + return isl_pw_qpolynomial_fold_copy((struct isl_pw_qpolynomial_fold *)v); +} + +static void isl_obj_pw_qpf_free(void *v) +{ + isl_pw_qpolynomial_fold_free((struct isl_pw_qpolynomial_fold *)v); +} + +static __isl_give isl_printer *isl_obj_pw_qpf_print(__isl_take isl_printer *p, + void *v) +{ + return isl_printer_print_pw_qpolynomial_fold(p, + (struct isl_pw_qpolynomial_fold *)v); +} + +static void *isl_obj_pw_qpf_add(void *v1, void *v2) +{ + return isl_pw_qpolynomial_fold_fold((struct isl_pw_qpolynomial_fold *)v1, + (struct isl_pw_qpolynomial_fold *)v2); +} + +struct isl_obj_vtable isl_obj_pw_qpolynomial_fold_vtable = { + isl_obj_pw_qpf_copy, + isl_obj_pw_qpf_add, + isl_obj_pw_qpf_print, + isl_obj_pw_qpf_free +}; + +static void *isl_obj_union_pw_qpf_copy(void *v) +{ + return isl_union_pw_qpolynomial_fold_copy((struct isl_union_pw_qpolynomial_fold *)v); +} + +static void isl_obj_union_pw_qpf_free(void *v) +{ + isl_union_pw_qpolynomial_fold_free((struct isl_union_pw_qpolynomial_fold *)v); +} + +static __isl_give isl_printer *isl_obj_union_pw_qpf_print( + __isl_take isl_printer *p, void *v) +{ + return isl_printer_print_union_pw_qpolynomial_fold(p, + (struct isl_union_pw_qpolynomial_fold *)v); +} + +static void *isl_obj_union_pw_qpf_add(void *v1, void *v2) +{ + return isl_union_pw_qpolynomial_fold_fold( + (struct isl_union_pw_qpolynomial_fold *)v1, + (struct isl_union_pw_qpolynomial_fold *)v2); +} + +struct isl_obj_vtable isl_obj_union_pw_qpolynomial_fold_vtable = { + isl_obj_union_pw_qpf_copy, + isl_obj_union_pw_qpf_add, + isl_obj_union_pw_qpf_print, + isl_obj_union_pw_qpf_free +}; + +static void *isl_obj_schedule_copy(void *v) +{ + return isl_schedule_copy((isl_schedule *) v); +} + +static void isl_obj_schedule_free(void *v) +{ + isl_schedule_free((isl_schedule *) v); +} + +static __isl_give isl_printer *isl_obj_schedule_print( + __isl_take isl_printer *p, void *v) +{ + return isl_printer_print_schedule(p, (isl_schedule *) v); +} + +struct isl_obj_vtable isl_obj_schedule_vtable = { + isl_obj_schedule_copy, + NULL, + isl_obj_schedule_print, + isl_obj_schedule_free +}; diff --git a/external/mit/isl/dist/isl_opt_mpa_templ.c b/external/mit/isl/dist/isl_opt_mpa_templ.c new file mode 100644 index 000000000000..e4245435d496 --- /dev/null +++ b/external/mit/isl/dist/isl_opt_mpa_templ.c @@ -0,0 +1,51 @@ +/* + * Copyright 2018 Cerebras Systems + * + * Use of this software is governed by the MIT license + * + * Written by Sven Verdoolaege, + * Cerebras Systems, 175 S San Antonio Rd, Los Altos, CA, USA + */ + +#undef TYPE +#define TYPE CAT(isl_,BASE) +#define xFN(TYPE,NAME) TYPE ## _ ## NAME +#define FN(TYPE,NAME) xFN(TYPE,NAME) + +/* Compute the optima of the set or output dimensions as a function of the + * parameters (and input dimensions), but independently of + * the other set or output dimensions, + * given a function "opt" that computes this optimum + * for a single dimension. + * + * If the resulting multi piecewise affine expression has + * an explicit domain, then assign it the (parameter) domain of the input. + * In other cases, the (parameter) domain is stored in the individual elements. + */ +static __isl_give isl_multi_pw_aff *FN(BASE,opt_mpa)(__isl_take TYPE *obj, + __isl_give isl_pw_aff *(*opt)(__isl_take TYPE *obj, int pos)) +{ + int i; + isl_size n; + isl_multi_pw_aff *mpa; + + mpa = isl_multi_pw_aff_alloc(FN(TYPE,get_space)(obj)); + n = isl_multi_pw_aff_size(mpa); + if (n < 0) + mpa = isl_multi_pw_aff_free(mpa); + for (i = 0; i < n; ++i) { + isl_pw_aff *pa; + + pa = opt(FN(TYPE,copy)(obj), i); + mpa = isl_multi_pw_aff_set_pw_aff(mpa, i, pa); + } + if (isl_multi_pw_aff_has_explicit_domain(mpa)) { + isl_set *dom; + + dom = FN(TYPE,domain)(FN(TYPE,copy)(obj)); + mpa = isl_multi_pw_aff_intersect_domain(mpa, dom); + } + FN(TYPE,free)(obj); + + return mpa; +} diff --git a/external/mit/isl/dist/isl_options.c b/external/mit/isl/dist/isl_options.c new file mode 100644 index 000000000000..a9b59c59345b --- /dev/null +++ b/external/mit/isl/dist/isl_options.c @@ -0,0 +1,392 @@ +/* + * 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 + */ + +#include +#include +#include + +#include +#include +#include +#include +#include + +struct isl_arg_choice isl_pip_context_choice[] = { + {"gbr", ISL_CONTEXT_GBR}, + {"lexmin", ISL_CONTEXT_LEXMIN}, + {0} +}; + +struct isl_arg_choice isl_gbr_choice[] = { + {"never", ISL_GBR_NEVER}, + {"once", ISL_GBR_ONCE}, + {"always", ISL_GBR_ALWAYS}, + {0} +}; + +struct isl_arg_choice isl_closure_choice[] = { + {"isl", ISL_CLOSURE_ISL}, + {"box", ISL_CLOSURE_BOX}, + {0} +}; + +static struct isl_arg_choice bound[] = { + {"bernstein", ISL_BOUND_BERNSTEIN}, + {"range", ISL_BOUND_RANGE}, + {0} +}; + +static struct isl_arg_choice on_error[] = { + {"warn", ISL_ON_ERROR_WARN}, + {"continue", ISL_ON_ERROR_CONTINUE}, + {"abort", ISL_ON_ERROR_ABORT}, + {0} +}; + +static struct isl_arg_choice isl_schedule_algorithm_choice[] = { + {"isl", ISL_SCHEDULE_ALGORITHM_ISL}, + {"feautrier", ISL_SCHEDULE_ALGORITHM_FEAUTRIER}, + {0} +}; + +static struct isl_arg_flags bernstein_recurse[] = { + {"none", ISL_BERNSTEIN_FACTORS | ISL_BERNSTEIN_INTERVALS, 0}, + {"factors", ISL_BERNSTEIN_FACTORS | ISL_BERNSTEIN_INTERVALS, + ISL_BERNSTEIN_FACTORS}, + {"intervals", ISL_BERNSTEIN_FACTORS | ISL_BERNSTEIN_INTERVALS, + ISL_BERNSTEIN_INTERVALS}, + {"full", ISL_BERNSTEIN_FACTORS | ISL_BERNSTEIN_INTERVALS, + ISL_BERNSTEIN_FACTORS | ISL_BERNSTEIN_INTERVALS}, + {0} +}; + +static struct isl_arg_choice convex[] = { + {"wrap", ISL_CONVEX_HULL_WRAP}, + {"fm", ISL_CONVEX_HULL_FM}, + {0} +}; + +#define ISL_SCHEDULE_FUSE_MAX 0 +#define ISL_SCHEDULE_FUSE_MIN 1 + +static struct isl_arg_choice fuse[] = { + {"max", ISL_SCHEDULE_FUSE_MAX}, + {"min", ISL_SCHEDULE_FUSE_MIN}, + {0} +}; + +/* Callback for setting the "schedule-fuse" option. + * This (now hidden) option tries to mimic an option that was + * replaced by the schedule-serialize-sccs option. + * Setting the old option to ISL_SCHEDULE_FUSE_MIN is now + * expressed by turning on the schedule-serialize-sccs option. + */ +static int set_fuse(void *opt, unsigned val) +{ + struct isl_options *options = opt; + + options->schedule_serialize_sccs = (val == ISL_SCHEDULE_FUSE_MIN); + + return 0; +} + +static struct isl_arg_choice separation_bounds[] = { + {"explicit", ISL_AST_BUILD_SEPARATION_BOUNDS_EXPLICIT}, + {"implicit", ISL_AST_BUILD_SEPARATION_BOUNDS_IMPLICIT}, + {0} +}; + +static void print_version(void) +{ + printf("%s", isl_version()); +} + +ISL_ARGS_START(struct isl_options, isl_options_args) +ISL_ARG_CHOICE(struct isl_options, context, 0, "context", \ + isl_pip_context_choice, ISL_CONTEXT_GBR, + "how to handle the pip context tableau") +ISL_ARG_CHOICE(struct isl_options, gbr, 0, "gbr", \ + isl_gbr_choice, ISL_GBR_ALWAYS, + "how often to use generalized basis reduction") +ISL_ARG_CHOICE(struct isl_options, closure, 0, "closure", \ + isl_closure_choice, ISL_CLOSURE_ISL, + "closure operation to use") +ISL_ARG_BOOL(struct isl_options, gbr_only_first, 0, "gbr-only-first", 0, + "only perform basis reduction in first direction") +ISL_ARG_CHOICE(struct isl_options, bound, 0, "bound", bound, + ISL_BOUND_BERNSTEIN, "algorithm to use for computing bounds") +ISL_ARG_CHOICE(struct isl_options, on_error, 0, "on-error", on_error, + ISL_ON_ERROR_WARN, "how to react if an error is detected") +ISL_ARG_FLAGS(struct isl_options, bernstein_recurse, 0, + "bernstein-recurse", bernstein_recurse, ISL_BERNSTEIN_FACTORS, NULL) +ISL_ARG_BOOL(struct isl_options, bernstein_triangulate, 0, + "bernstein-triangulate", 1, + "triangulate domains during Bernstein expansion") +ISL_ARG_BOOL(struct isl_options, pip_symmetry, 0, "pip-symmetry", 1, + "detect simple symmetries in PIP input") +ISL_ARG_CHOICE(struct isl_options, convex, 0, "convex-hull", \ + convex, ISL_CONVEX_HULL_WRAP, "convex hull algorithm to use") +ISL_ARG_BOOL(struct isl_options, coalesce_bounded_wrapping, 0, + "coalesce-bounded-wrapping", 1, "bound wrapping during coalescing") +ISL_ARG_BOOL(struct isl_options, coalesce_preserve_locals, 0, + "coalesce-preserve-locals", 0, + "preserve local variables during coalescing") +ISL_ARG_INT(struct isl_options, schedule_max_coefficient, 0, + "schedule-max-coefficient", "limit", -1, "Only consider schedules " + "where the coefficients of the variable and parameter dimensions " + "do not exceed . A value of -1 allows arbitrary coefficients.") +ISL_ARG_INT(struct isl_options, schedule_max_constant_term, 0, + "schedule-max-constant-term", "limit", -1, "Only consider schedules " + "where the coefficients of the constant dimension do not exceed " + ". A value of -1 allows arbitrary coefficients.") +ISL_ARG_BOOL(struct isl_options, schedule_parametric, 0, + "schedule-parametric", 1, "construct possibly parametric schedules") +ISL_ARG_BOOL(struct isl_options, schedule_outer_coincidence, 0, + "schedule-outer-coincidence", 0, + "try to construct schedules where the outer member of each band " + "satisfies the coincidence constraints") +ISL_ARG_BOOL(struct isl_options, schedule_maximize_band_depth, 0, + "schedule-maximize-band-depth", 0, + "maximize the number of scheduling dimensions in a band") +ISL_ARG_BOOL(struct isl_options, schedule_maximize_coincidence, 0, + "schedule-maximize-coincidence", 0, + "maximize the number of coincident dimensions in a band") +ISL_ARG_BOOL(struct isl_options, schedule_split_scaled, 0, + "schedule-split-scaled", 1, + "split non-tilable bands with scaled schedules") +ISL_ARG_BOOL(struct isl_options, schedule_treat_coalescing, 0, + "schedule-treat-coalescing", 1, + "try and prevent or adjust schedules that perform loop coalescing") +ISL_ARG_BOOL(struct isl_options, schedule_separate_components, 0, + "schedule-separate-components", 1, + "separate components in dependence graph") +ISL_ARG_BOOL(struct isl_options, schedule_whole_component, 0, + "schedule-whole-component", 0, + "try and compute schedule for entire component first") +ISL_ARG_CHOICE(struct isl_options, schedule_algorithm, 0, + "schedule-algorithm", isl_schedule_algorithm_choice, + ISL_SCHEDULE_ALGORITHM_ISL, "scheduling algorithm to use") +ISL_ARG_BOOL(struct isl_options, schedule_carry_self_first, 0, + "schedule-carry-self-first", 1, "try and carry self-dependences first") +ISL_ARG_BOOL(struct isl_options, schedule_serialize_sccs, 0, + "schedule-serialize-sccs", 0, + "serialize strongly connected components in dependence graph") +ISL_ARG_PHANTOM_USER_CHOICE_F(0, "schedule-fuse", fuse, &set_fuse, + ISL_SCHEDULE_FUSE_MAX, "level of fusion during scheduling", + ISL_ARG_HIDDEN) +ISL_ARG_BOOL(struct isl_options, tile_scale_tile_loops, 0, + "tile-scale-tile-loops", 1, "scale tile loops") +ISL_ARG_BOOL(struct isl_options, tile_shift_point_loops, 0, + "tile-shift-point-loops", 1, "shift point loops to start at zero") +ISL_ARG_STR(struct isl_options, ast_iterator_type, 0, + "ast-iterator-type", "type", "int", + "type used for iterators during printing of AST") +ISL_ARG_BOOL(struct isl_options, ast_always_print_block, 0, + "ast-always-print-block", 0, "print for and if bodies as a block " + "regardless of the number of statements in the body") +ISL_ARG_BOOL(struct isl_options, ast_print_outermost_block, 0, + "ast-print-outermost-block", 1, "print outermost block node as a block") +ISL_ARG_BOOL(struct isl_options, ast_print_macro_once, 0, + "ast-print-macro-once", 0, "only print macro definitions once") +ISL_ARG_BOOL(struct isl_options, ast_build_atomic_upper_bound, 0, + "ast-build-atomic-upper-bound", 1, "generate atomic upper bounds") +ISL_ARG_BOOL(struct isl_options, ast_build_prefer_pdiv, 0, + "ast-build-prefer-pdiv", 1, "prefer pdiv operation over fdiv") +ISL_ARG_BOOL(struct isl_options, ast_build_detect_min_max, 0, + "ast-build-detect-min-max", 0, "detect min/max expressions") +ISL_ARG_BOOL(struct isl_options, ast_build_exploit_nested_bounds, 0, + "ast-build-exploit-nested-bounds", 1, + "simplify conditions based on bounds of nested for loops") +ISL_ARG_BOOL(struct isl_options, ast_build_group_coscheduled, 0, + "ast-build-group-coscheduled", 0, + "keep coscheduled domain elements together") +ISL_ARG_CHOICE(struct isl_options, ast_build_separation_bounds, 0, + "ast-build-separation-bounds", separation_bounds, + ISL_AST_BUILD_SEPARATION_BOUNDS_EXPLICIT, + "bounds to use during separation") +ISL_ARG_BOOL(struct isl_options, ast_build_scale_strides, 0, + "ast-build-scale-strides", 1, + "allow iterators of strided loops to be scaled down") +ISL_ARG_BOOL(struct isl_options, ast_build_allow_else, 0, + "ast-build-allow-else", 1, "generate if statements with else branches") +ISL_ARG_BOOL(struct isl_options, ast_build_allow_or, 0, + "ast-build-allow-or", 1, "generate if conditions with disjunctions") +ISL_ARG_BOOL(struct isl_options, print_stats, 0, "print-stats", 0, + "print statistics for every isl_ctx") +ISL_ARG_ULONG(struct isl_options, max_operations, 0, + "max-operations", 0, "default number of maximal operations per isl_ctx") +ISL_ARG_VERSION(print_version) +ISL_ARGS_END + +ISL_ARG_DEF(isl_options, struct isl_options, isl_options_args) + +ISL_ARG_CTX_DEF(isl_options, struct isl_options, isl_options_args) + +ISL_CTX_SET_CHOICE_DEF(isl_options, struct isl_options, isl_options_args, bound) +ISL_CTX_GET_CHOICE_DEF(isl_options, struct isl_options, isl_options_args, bound) + +ISL_CTX_SET_CHOICE_DEF(isl_options, struct isl_options, isl_options_args, + on_error) +ISL_CTX_GET_CHOICE_DEF(isl_options, struct isl_options, isl_options_args, + on_error) + +ISL_CTX_SET_BOOL_DEF(isl_options, struct isl_options, isl_options_args, + pip_symmetry) +ISL_CTX_GET_BOOL_DEF(isl_options, struct isl_options, isl_options_args, + pip_symmetry) + +ISL_CTX_SET_BOOL_DEF(isl_options, struct isl_options, isl_options_args, + coalesce_bounded_wrapping) +ISL_CTX_GET_BOOL_DEF(isl_options, struct isl_options, isl_options_args, + coalesce_bounded_wrapping) + +ISL_CTX_SET_BOOL_DEF(isl_options, struct isl_options, isl_options_args, + coalesce_preserve_locals) +ISL_CTX_GET_BOOL_DEF(isl_options, struct isl_options, isl_options_args, + coalesce_preserve_locals) + +ISL_CTX_SET_BOOL_DEF(isl_options, struct isl_options, isl_options_args, + gbr_only_first) +ISL_CTX_GET_BOOL_DEF(isl_options, struct isl_options, isl_options_args, + gbr_only_first) + +ISL_CTX_SET_INT_DEF(isl_options, struct isl_options, isl_options_args, + schedule_max_coefficient) +ISL_CTX_GET_INT_DEF(isl_options, struct isl_options, isl_options_args, + schedule_max_coefficient) + +ISL_CTX_SET_INT_DEF(isl_options, struct isl_options, isl_options_args, + schedule_max_constant_term) +ISL_CTX_GET_INT_DEF(isl_options, struct isl_options, isl_options_args, + schedule_max_constant_term) + +ISL_CTX_SET_BOOL_DEF(isl_options, struct isl_options, isl_options_args, + schedule_maximize_band_depth) +ISL_CTX_GET_BOOL_DEF(isl_options, struct isl_options, isl_options_args, + schedule_maximize_band_depth) + +ISL_CTX_SET_BOOL_DEF(isl_options, struct isl_options, isl_options_args, + schedule_maximize_coincidence) +ISL_CTX_GET_BOOL_DEF(isl_options, struct isl_options, isl_options_args, + schedule_maximize_coincidence) + +ISL_CTX_SET_BOOL_DEF(isl_options, struct isl_options, isl_options_args, + schedule_split_scaled) +ISL_CTX_GET_BOOL_DEF(isl_options, struct isl_options, isl_options_args, + schedule_split_scaled) + +ISL_CTX_SET_BOOL_DEF(isl_options, struct isl_options, isl_options_args, + schedule_treat_coalescing) +ISL_CTX_GET_BOOL_DEF(isl_options, struct isl_options, isl_options_args, + schedule_treat_coalescing) + +ISL_CTX_SET_BOOL_DEF(isl_options, struct isl_options, isl_options_args, + schedule_separate_components) +ISL_CTX_GET_BOOL_DEF(isl_options, struct isl_options, isl_options_args, + schedule_separate_components) + +ISL_CTX_SET_BOOL_DEF(isl_options, struct isl_options, isl_options_args, + schedule_whole_component) +ISL_CTX_GET_BOOL_DEF(isl_options, struct isl_options, isl_options_args, + schedule_whole_component) + +ISL_CTX_SET_BOOL_DEF(isl_options, struct isl_options, isl_options_args, + schedule_outer_coincidence) +ISL_CTX_GET_BOOL_DEF(isl_options, struct isl_options, isl_options_args, + schedule_outer_coincidence) + +ISL_CTX_SET_CHOICE_DEF(isl_options, struct isl_options, isl_options_args, + schedule_algorithm) +ISL_CTX_GET_CHOICE_DEF(isl_options, struct isl_options, isl_options_args, + schedule_algorithm) + +ISL_CTX_SET_BOOL_DEF(isl_options, struct isl_options, isl_options_args, + schedule_carry_self_first) +ISL_CTX_GET_BOOL_DEF(isl_options, struct isl_options, isl_options_args, + schedule_carry_self_first) + +ISL_CTX_SET_BOOL_DEF(isl_options, struct isl_options, isl_options_args, + schedule_serialize_sccs) +ISL_CTX_GET_BOOL_DEF(isl_options, struct isl_options, isl_options_args, + schedule_serialize_sccs) + +ISL_CTX_SET_BOOL_DEF(isl_options, struct isl_options, isl_options_args, + tile_scale_tile_loops) +ISL_CTX_GET_BOOL_DEF(isl_options, struct isl_options, isl_options_args, + tile_scale_tile_loops) + +ISL_CTX_SET_BOOL_DEF(isl_options, struct isl_options, isl_options_args, + tile_shift_point_loops) +ISL_CTX_GET_BOOL_DEF(isl_options, struct isl_options, isl_options_args, + tile_shift_point_loops) + +ISL_CTX_SET_BOOL_DEF(isl_options, struct isl_options, isl_options_args, + ast_build_atomic_upper_bound) +ISL_CTX_GET_BOOL_DEF(isl_options, struct isl_options, isl_options_args, + ast_build_atomic_upper_bound) + +ISL_CTX_SET_BOOL_DEF(isl_options, struct isl_options, isl_options_args, + ast_build_prefer_pdiv) +ISL_CTX_GET_BOOL_DEF(isl_options, struct isl_options, isl_options_args, + ast_build_prefer_pdiv) + +ISL_CTX_SET_BOOL_DEF(isl_options, struct isl_options, isl_options_args, + ast_build_detect_min_max) +ISL_CTX_GET_BOOL_DEF(isl_options, struct isl_options, isl_options_args, + ast_build_detect_min_max) + +ISL_CTX_SET_BOOL_DEF(isl_options, struct isl_options, isl_options_args, + ast_build_exploit_nested_bounds) +ISL_CTX_GET_BOOL_DEF(isl_options, struct isl_options, isl_options_args, + ast_build_exploit_nested_bounds) + +ISL_CTX_SET_BOOL_DEF(isl_options, struct isl_options, isl_options_args, + ast_build_group_coscheduled) +ISL_CTX_GET_BOOL_DEF(isl_options, struct isl_options, isl_options_args, + ast_build_group_coscheduled) + +ISL_CTX_SET_STR_DEF(isl_options, struct isl_options, isl_options_args, + ast_iterator_type) +ISL_CTX_GET_STR_DEF(isl_options, struct isl_options, isl_options_args, + ast_iterator_type) + +ISL_CTX_SET_BOOL_DEF(isl_options, struct isl_options, isl_options_args, + ast_always_print_block) +ISL_CTX_GET_BOOL_DEF(isl_options, struct isl_options, isl_options_args, + ast_always_print_block) + +ISL_CTX_SET_BOOL_DEF(isl_options, struct isl_options, isl_options_args, + ast_print_outermost_block) +ISL_CTX_GET_BOOL_DEF(isl_options, struct isl_options, isl_options_args, + ast_print_outermost_block) + +ISL_CTX_SET_BOOL_DEF(isl_options, struct isl_options, isl_options_args, + ast_print_macro_once) +ISL_CTX_GET_BOOL_DEF(isl_options, struct isl_options, isl_options_args, + ast_print_macro_once) + +ISL_CTX_SET_CHOICE_DEF(isl_options, struct isl_options, isl_options_args, + ast_build_separation_bounds) +ISL_CTX_GET_CHOICE_DEF(isl_options, struct isl_options, isl_options_args, + ast_build_separation_bounds) + +ISL_CTX_SET_BOOL_DEF(isl_options, struct isl_options, isl_options_args, + ast_build_scale_strides) +ISL_CTX_GET_BOOL_DEF(isl_options, struct isl_options, isl_options_args, + ast_build_scale_strides) + +ISL_CTX_SET_BOOL_DEF(isl_options, struct isl_options, isl_options_args, + ast_build_allow_else) +ISL_CTX_GET_BOOL_DEF(isl_options, struct isl_options, isl_options_args, + ast_build_allow_else) + +ISL_CTX_SET_BOOL_DEF(isl_options, struct isl_options, isl_options_args, + ast_build_allow_or) +ISL_CTX_GET_BOOL_DEF(isl_options, struct isl_options, isl_options_args, + ast_build_allow_or) diff --git a/external/mit/isl/dist/isl_options_private.h b/external/mit/isl/dist/isl_options_private.h new file mode 100644 index 000000000000..97297d8063c4 --- /dev/null +++ b/external/mit/isl/dist/isl_options_private.h @@ -0,0 +1,75 @@ +#ifndef ISL_OPTIONS_PRIVATE_H +#define ISL_OPTIONS_PRIVATE_H + +#include + +struct isl_options { + #define ISL_CONTEXT_GBR 0 + #define ISL_CONTEXT_LEXMIN 1 + unsigned context; + + #define ISL_GBR_NEVER 0 + #define ISL_GBR_ONCE 1 + #define ISL_GBR_ALWAYS 2 + unsigned gbr; + unsigned gbr_only_first; + + #define ISL_CLOSURE_ISL 0 + #define ISL_CLOSURE_BOX 1 + unsigned closure; + + int bound; + unsigned on_error; + + #define ISL_BERNSTEIN_FACTORS 1 + #define ISL_BERNSTEIN_INTERVALS 2 + int bernstein_recurse; + + int bernstein_triangulate; + + int pip_symmetry; + + #define ISL_CONVEX_HULL_WRAP 0 + #define ISL_CONVEX_HULL_FM 1 + int convex; + + int coalesce_bounded_wrapping; + int coalesce_preserve_locals; + + int schedule_max_coefficient; + int schedule_max_constant_term; + int schedule_parametric; + int schedule_outer_coincidence; + int schedule_maximize_band_depth; + int schedule_maximize_coincidence; + int schedule_split_scaled; + int schedule_treat_coalescing; + int schedule_separate_components; + int schedule_whole_component; + unsigned schedule_algorithm; + int schedule_carry_self_first; + int schedule_serialize_sccs; + + int tile_scale_tile_loops; + int tile_shift_point_loops; + + char *ast_iterator_type; + int ast_always_print_block; + int ast_print_outermost_block; + int ast_print_macro_once; + + int ast_build_atomic_upper_bound; + int ast_build_prefer_pdiv; + int ast_build_detect_min_max; + int ast_build_exploit_nested_bounds; + int ast_build_group_coscheduled; + int ast_build_separation_bounds; + int ast_build_scale_strides; + int ast_build_allow_else; + int ast_build_allow_or; + + int print_stats; + unsigned long max_operations; +}; + +#endif diff --git a/external/mit/isl/dist/isl_output.c b/external/mit/isl/dist/isl_output.c new file mode 100644 index 000000000000..546e43d785f0 --- /dev/null +++ b/external/mit/isl/dist/isl_output.c @@ -0,0 +1,3397 @@ +/* + * Copyright 2008-2009 Katholieke Universiteit Leuven + * Copyright 2010 INRIA Saclay + * Copyright 2012-2013 Ecole Normale Superieure + * Copyright 2019 Cerebras Systems + * + * 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 + * and Cerebras Systems, 175 S San Antonio Rd, Los Altos, CA, USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +static const char *s_to[2] = { " -> ", " \\to " }; +static const char *s_and[2] = { " and ", " \\wedge " }; +static const char *s_or[2] = { " or ", " \\vee " }; +static const char *s_le[2] = { "<=", "\\le" }; +static const char *s_ge[2] = { ">=", "\\ge" }; +static const char *s_open_set[2] = { "{ ", "\\{\\, " }; +static const char *s_close_set[2] = { " }", " \\,\\}" }; +static const char *s_open_list[2] = { "[", "(" }; +static const char *s_close_list[2] = { "]", ")" }; +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_" }; + +static __isl_give isl_printer *print_constraint_polylib( + struct isl_basic_map *bmap, int ineq, int n, __isl_take isl_printer *p) +{ + int i; + isl_size n_in = isl_basic_map_dim(bmap, isl_dim_in); + isl_size n_out = isl_basic_map_dim(bmap, isl_dim_out); + isl_size nparam = isl_basic_map_dim(bmap, isl_dim_param); + isl_int *c = ineq ? bmap->ineq[n] : bmap->eq[n]; + + if (n_in < 0 || n_out < 0 || nparam < 0) + return isl_printer_free(p); + + p = isl_printer_start_line(p); + p = isl_printer_print_int(p, ineq); + for (i = 0; i < n_out; ++i) { + p = isl_printer_print_str(p, " "); + p = isl_printer_print_isl_int(p, c[1+nparam+n_in+i]); + } + for (i = 0; i < n_in; ++i) { + p = isl_printer_print_str(p, " "); + p = isl_printer_print_isl_int(p, c[1+nparam+i]); + } + for (i = 0; i < bmap->n_div; ++i) { + p = isl_printer_print_str(p, " "); + p = isl_printer_print_isl_int(p, c[1+nparam+n_in+n_out+i]); + } + for (i = 0; i < nparam; ++i) { + p = isl_printer_print_str(p, " "); + p = isl_printer_print_isl_int(p, c[1+i]); + } + p = isl_printer_print_str(p, " "); + p = isl_printer_print_isl_int(p, c[0]); + p = isl_printer_end_line(p); + return p; +} + +static __isl_give isl_printer *print_constraints_polylib( + struct isl_basic_map *bmap, __isl_take isl_printer *p) +{ + int i; + + p = isl_printer_set_isl_int_width(p, 5); + + for (i = 0; i < bmap->n_eq; ++i) + p = print_constraint_polylib(bmap, 0, i, p); + for (i = 0; i < bmap->n_ineq; ++i) + p = print_constraint_polylib(bmap, 1, i, p); + + return p; +} + +static __isl_give isl_printer *bset_print_constraints_polylib( + struct isl_basic_set *bset, __isl_take isl_printer *p) +{ + return print_constraints_polylib(bset_to_bmap(bset), p); +} + +static __isl_give isl_printer *isl_basic_map_print_polylib( + __isl_keep isl_basic_map *bmap, __isl_take isl_printer *p, int ext) +{ + isl_size total; + + total = isl_basic_map_dim(bmap, isl_dim_all); + if (total < 0) + return isl_printer_free(p); + p = isl_printer_start_line(p); + p = isl_printer_print_int(p, bmap->n_eq + bmap->n_ineq); + p = isl_printer_print_str(p, " "); + p = isl_printer_print_int(p, 1 + total + 1); + if (ext) { + isl_size n_in = isl_basic_map_dim(bmap, isl_dim_in); + isl_size n_out = isl_basic_map_dim(bmap, isl_dim_out); + isl_size n_div = isl_basic_map_dim(bmap, isl_dim_div); + isl_size nparam = isl_basic_map_dim(bmap, isl_dim_param); + + if (n_in < 0 || n_out < 0 || n_div < 0 || nparam < 0) + return isl_printer_free(p); + + p = isl_printer_print_str(p, " "); + p = isl_printer_print_int(p, n_out); + p = isl_printer_print_str(p, " "); + p = isl_printer_print_int(p, n_in); + p = isl_printer_print_str(p, " "); + p = isl_printer_print_int(p, n_div); + p = isl_printer_print_str(p, " "); + p = isl_printer_print_int(p, nparam); + } + p = isl_printer_end_line(p); + return print_constraints_polylib(bmap, p); +} + +static __isl_give isl_printer *isl_basic_set_print_polylib( + __isl_keep isl_basic_set *bset, __isl_take isl_printer *p, int ext) +{ + return isl_basic_map_print_polylib(bset_to_bmap(bset), p, ext); +} + +static __isl_give isl_printer *isl_map_print_polylib(__isl_keep isl_map *map, + __isl_take isl_printer *p, int ext) +{ + int i; + + p = isl_printer_start_line(p); + p = isl_printer_print_int(p, map->n); + p = isl_printer_end_line(p); + for (i = 0; i < map->n; ++i) { + p = isl_printer_start_line(p); + p = isl_printer_end_line(p); + p = isl_basic_map_print_polylib(map->p[i], p, ext); + } + return p; +} + +static __isl_give isl_printer *isl_set_print_polylib(__isl_keep isl_set *set, + __isl_take isl_printer *p, int ext) +{ + return isl_map_print_polylib(set_to_map(set), p, ext); +} + +static isl_size count_same_name(__isl_keep isl_space *space, + enum isl_dim_type type, unsigned pos, const char *name) +{ + enum isl_dim_type t; + int p; + isl_size s; + int count = 0; + + for (t = isl_dim_param; t <= type && t <= isl_dim_out; ++t) { + s = t == type ? pos : isl_space_dim(space, t); + if (s < 0) + return isl_size_error; + for (p = 0; p < s; ++p) { + const char *n = isl_space_get_dim_name(space, t, p); + if (n && !strcmp(n, name)) + count++; + } + } + return count; +} + +/* Print the name of the variable of type "type" and position "pos" + * in "space" to "p". + */ +static __isl_give isl_printer *print_name(__isl_keep isl_space *space, + __isl_take isl_printer *p, enum isl_dim_type type, unsigned pos, + int latex) +{ + const char *name; + char buffer[20]; + isl_size primes; + + name = type == isl_dim_div ? NULL + : isl_space_get_dim_name(space, type, pos); + + if (!name) { + const char *prefix; + if (type == isl_dim_param) + prefix = s_param_prefix[latex]; + else if (type == isl_dim_div) + prefix = s_div_prefix[latex]; + else if (isl_space_is_set(space) || type == isl_dim_in) + prefix = s_input_prefix[latex]; + else + prefix = s_output_prefix[latex]; + snprintf(buffer, sizeof(buffer), "%s%d", prefix, pos); + name = buffer; + } + primes = count_same_name(space, name == buffer ? isl_dim_div : type, + pos, name); + if (primes < 0) + return isl_printer_free(p); + p = isl_printer_print_str(p, name); + while (primes-- > 0) + p = isl_printer_print_str(p, "'"); + return p; +} + +static isl_stat pos2type(__isl_keep isl_space *space, + enum isl_dim_type *type, unsigned *pos) +{ + isl_size n_in = isl_space_dim(space, isl_dim_in); + isl_size n_out = isl_space_dim(space, isl_dim_out); + isl_size nparam = isl_space_dim(space, isl_dim_param); + + if (n_in < 0 || n_out < 0 || nparam < 0) + return isl_stat_error; + + if (*pos < 1 + nparam) { + *type = isl_dim_param; + *pos -= 1; + } else if (*pos < 1 + nparam + n_in) { + *type = isl_dim_in; + *pos -= 1 + nparam; + } else if (*pos < 1 + nparam + n_in + n_out) { + *type = isl_dim_out; + *pos -= 1 + nparam + n_in; + } else { + *type = isl_dim_div; + *pos -= 1 + nparam + n_in + n_out; + } + + return isl_stat_ok; +} + +/* Can the div expression of the integer division at position "row" of "div" + * be printed? + * In particular, are the div expressions available and does the selected + * variable have a known explicit representation? + * Furthermore, the Omega format does not allow any div expressions + * to be printed. + */ +static isl_bool can_print_div_expr(__isl_keep isl_printer *p, + __isl_keep isl_mat *div, int pos) +{ + if (p->output_format == ISL_FORMAT_OMEGA) + return isl_bool_false; + if (!div) + return isl_bool_false; + return isl_bool_not(isl_local_div_is_marked_unknown(div, pos)); +} + +static __isl_give isl_printer *print_div(__isl_keep isl_space *space, + __isl_keep isl_mat *div, int pos, __isl_take isl_printer *p); + +static __isl_give isl_printer *print_term(__isl_keep isl_space *space, + __isl_keep isl_mat *div, + isl_int c, unsigned pos, __isl_take isl_printer *p, int latex) +{ + enum isl_dim_type type; + int print_div_def; + + if (!p || !space) + return isl_printer_free(p); + + if (pos == 0) + return isl_printer_print_isl_int(p, c); + + if (pos2type(space, &type, &pos) < 0) + return isl_printer_free(p); + print_div_def = type == isl_dim_div && can_print_div_expr(p, div, pos); + + if (isl_int_is_one(c)) + ; + else if (isl_int_is_negone(c)) + p = isl_printer_print_str(p, "-"); + else { + p = isl_printer_print_isl_int(p, c); + if (p->output_format == ISL_FORMAT_C || print_div_def) + p = isl_printer_print_str(p, "*"); + } + if (print_div_def) + p = print_div(space, div, pos, p); + else + p = print_name(space, p, type, pos, latex); + return p; +} + +static __isl_give isl_printer *print_affine_of_len(__isl_keep isl_space *space, + __isl_keep isl_mat *div, + __isl_take isl_printer *p, isl_int *c, int len) +{ + int i; + int first; + + for (i = 0, first = 1; i < len; ++i) { + int flip = 0; + if (isl_int_is_zero(c[i])) + continue; + if (!first) { + if (isl_int_is_neg(c[i])) { + flip = 1; + isl_int_neg(c[i], c[i]); + p = isl_printer_print_str(p, " - "); + } else + p = isl_printer_print_str(p, " + "); + } + first = 0; + p = print_term(space, div, c[i], i, p, 0); + if (flip) + isl_int_neg(c[i], c[i]); + } + if (first) + p = isl_printer_print_str(p, "0"); + return p; +} + +/* 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_take isl_printer *p, + __isl_keep isl_space *space, __isl_keep isl_mat *div, isl_int *c) +{ + isl_size n_div, total; + unsigned len; + + total = isl_space_dim(space, isl_dim_all); + n_div = isl_mat_rows(div); + if (total < 0 || n_div < 0) + return isl_printer_free(p); + len = 1 + total + n_div; + return print_affine_of_len(space, div, p, c, len); +} + +/* offset is the offset of local_space inside data->type of data->space. + */ +static __isl_give isl_printer *print_nested_var_list(__isl_take isl_printer *p, + __isl_keep isl_space *local_space, enum isl_dim_type local_type, + struct isl_print_space_data *data, int offset) +{ + int i; + isl_size dim; + + if (data->space != local_space && local_type == isl_dim_out) + offset += local_space->n_in; + + dim = isl_space_dim(local_space, local_type); + if (dim < 0) + return isl_printer_free(p); + for (i = 0; i < dim; ++i) { + if (i) + p = isl_printer_print_str(p, ", "); + if (data->print_dim) + p = data->print_dim(p, data, offset + i); + else + p = print_name(data->space, p, data->type, offset + i, + data->latex); + } + return p; +} + +static __isl_give isl_printer *print_var_list(__isl_take isl_printer *p, + __isl_keep isl_space *space, enum isl_dim_type type) +{ + struct isl_print_space_data data = { .space = space, .type = type }; + + return print_nested_var_list(p, space, type, &data, 0); +} + +static __isl_give isl_printer *print_nested_map_dim(__isl_take isl_printer *p, + __isl_keep isl_space *local_dim, + struct isl_print_space_data *data, int offset); + +static __isl_give isl_printer *print_nested_tuple(__isl_take isl_printer *p, + __isl_keep isl_space *local_space, enum isl_dim_type local_type, + struct isl_print_space_data *data, int offset) +{ + const char *name = NULL; + isl_size n = isl_space_dim(local_space, local_type); + + if (n < 0) + return isl_printer_free(p); + if ((local_type == isl_dim_in || local_type == isl_dim_out)) { + name = isl_space_get_tuple_name(local_space, local_type); + if (name) { + if (data->latex) + p = isl_printer_print_str(p, "\\mathrm{"); + p = isl_printer_print_str(p, name); + if (data->latex) + p = isl_printer_print_str(p, "}"); + } + } + if (!data->latex || n != 1 || name) + p = isl_printer_print_str(p, s_open_list[data->latex]); + if ((local_type == isl_dim_in || local_type == isl_dim_out) && + local_space->nested[local_type - isl_dim_in]) { + if (data->space != local_space && local_type == isl_dim_out) + offset += local_space->n_in; + p = print_nested_map_dim(p, + local_space->nested[local_type - isl_dim_in], + data, offset); + } else + p = print_nested_var_list(p, local_space, local_type, data, + offset); + if (!data->latex || n != 1 || name) + p = isl_printer_print_str(p, s_close_list[data->latex]); + return p; +} + +static __isl_give isl_printer *print_tuple(__isl_keep isl_space *space, + __isl_take isl_printer *p, enum isl_dim_type type, + struct isl_print_space_data *data) +{ + data->space = space; + data->type = type; + return print_nested_tuple(p, space, type, data, 0); +} + +static __isl_give isl_printer *print_nested_map_dim(__isl_take isl_printer *p, + __isl_keep isl_space *local_dim, + struct isl_print_space_data *data, int offset) +{ + p = print_nested_tuple(p, local_dim, isl_dim_in, data, offset); + p = isl_printer_print_str(p, s_to[data->latex]); + p = print_nested_tuple(p, local_dim, isl_dim_out, data, offset); + + return p; +} + +__isl_give isl_printer *isl_print_space(__isl_keep isl_space *space, + __isl_take isl_printer *p, int rational, + struct isl_print_space_data *data) +{ + if (rational && !data->latex) + p = isl_printer_print_str(p, "rat: "); + if (isl_space_is_params(space)) + ; + else if (isl_space_is_set(space)) + p = print_tuple(space, p, isl_dim_set, data); + else { + p = print_tuple(space, p, isl_dim_in, data); + p = isl_printer_print_str(p, s_to[data->latex]); + p = print_tuple(space, p, isl_dim_out, data); + } + + return p; +} + +static __isl_give isl_printer *print_omega_parameters( + __isl_keep isl_space *space, __isl_take isl_printer *p) +{ + isl_size nparam = isl_space_dim(space, isl_dim_param); + + if (nparam < 0) + return isl_printer_free(p); + if (nparam == 0) + return p; + + p = isl_printer_start_line(p); + p = isl_printer_print_str(p, "symbolic "); + p = print_var_list(p, space, isl_dim_param); + p = isl_printer_print_str(p, ";"); + p = isl_printer_end_line(p); + return p; +} + +/* Does the inequality constraint following "i" in "bmap" + * have an opposite value for the same last coefficient? + * "last" is the position of the last coefficient of inequality "i". + * If the next constraint is a div constraint, then it is ignored + * since div constraints are not printed. + */ +static isl_bool next_is_opposite(__isl_keep isl_basic_map *bmap, int i, + int last) +{ + int r; + isl_size total = isl_basic_map_dim(bmap, isl_dim_all); + unsigned o_div = isl_basic_map_offset(bmap, isl_dim_div); + + if (total < 0) + return isl_bool_error; + if (i + 1 >= bmap->n_ineq) + return isl_bool_false; + if (isl_seq_last_non_zero(bmap->ineq[i + 1], 1 + total) != last) + return isl_bool_false; + if (last >= o_div) { + isl_bool is_div; + is_div = isl_basic_map_is_div_constraint(bmap, + bmap->ineq[i + 1], last - o_div); + if (is_div < 0) + return isl_bool_error; + if (is_div) + return isl_bool_false; + } + r = isl_int_abs_eq(bmap->ineq[i][last], bmap->ineq[i + 1][last]) && + !isl_int_eq(bmap->ineq[i][last], bmap->ineq[i + 1][last]); + return isl_bool_ok(r); +} + +/* Return a string representation of the operator used when + * printing a constraint where the LHS is greater than or equal to the LHS + * (sign > 0) or smaller than or equal to the LHS (sign < 0). + * If "strict" is set, then return the strict version of the comparison + * operator. + */ +static const char *constraint_op(int sign, int strict, int latex) +{ + if (strict) + return sign < 0 ? "<" : ">"; + if (sign < 0) + return s_le[latex]; + else + return s_ge[latex]; +} + +/* 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. + * Let c' be the result of zeroing out this coefficient, then + * the partial constraint + * + * c' op + * + * is printed. + */ +static __isl_give isl_printer *print_half_constraint(__isl_take isl_printer *p, + __isl_keep isl_space *space, __isl_keep isl_mat *div, + isl_int *c, int last, const char *op, int latex) +{ + isl_int_set_si(c[last], 0); + p = print_affine(p, space, div, c); + + p = isl_printer_print_str(p, " "); + p = isl_printer_print_str(p, op); + p = isl_printer_print_str(p, " "); + + return p; +} + +/* 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. + * Let c' be the result of zeroing out this coefficient, then + * the constraint is printed in the form + * + * -c[last] op c' + */ +static __isl_give isl_printer *print_constraint(__isl_take isl_printer *p, + __isl_keep isl_space *space, __isl_keep isl_mat *div, + isl_int *c, int last, const char *op, int latex) +{ + isl_int_abs(c[last], c[last]); + + p = print_term(space, div, c[last], last, p, latex); + + p = isl_printer_print_str(p, " "); + p = isl_printer_print_str(p, op); + p = isl_printer_print_str(p, " "); + + isl_int_set_si(c[last], 0); + 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; +} + +/* Given an equality constraint with a non-zero coefficient "c" + * in position "pos", is this term of the form + * + * a m floor(g/m), + * + * with c = a m? + * Return the position of the corresponding integer division if so. + * Return the number of integer divisions if not. + * Return isl_size_error 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 isl_size 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; + isl_size n_div; + enum isl_dim_type type; + + n_div = isl_mat_rows(div); + if (!p || !space || n_div < 0) + return isl_size_error; + if (p->output_format == ISL_FORMAT_C) + return n_div; + if (pos2type(space, &type, &pos) < 0) + return isl_size_error; + if (type != isl_dim_div) + return n_div; + can_print = can_print_div_expr(p, div, pos); + if (can_print < 0) + return isl_size_error; + 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) +{ + isl_size n_div; + isl_size div_pos; + + n_div = isl_mat_rows(div); + div_pos = print_as_modulo_pos(p, space, div, last, c[last]); + if (n_div < 0 || 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". + * Div constraints are only printed in "dump" mode. + * The constraints are sorted prior to printing (except in "dump" mode). + * + * If x is the last variable with a non-zero coefficient, + * then a lower bound + * + * f - a x >= 0 + * + * is printed as + * + * a x <= f + * + * while an upper bound + * + * f + a x >= 0 + * + * is printed as + * + * a x >= -f + * + * If the next constraint has an opposite sign for the same last coefficient, + * then it is printed as + * + * f >= a x + * + * or + * + * -f <= a x + * + * instead. In fact, the "a x" part is not printed explicitly, but + * reused from the next constraint, which is therefore treated as + * a first constraint in the conjunction. + * + * If the constant term of "f" is -1, then "f" is replaced by "f + 1" and + * the comparison operator is replaced by the strict variant. + * Essentially, ">= 1" is replaced by "> 0". + */ +static __isl_give isl_printer *print_constraints(__isl_keep isl_basic_map *bmap, + __isl_keep isl_space *space, __isl_keep isl_mat *div, + __isl_take isl_printer *p, int latex) +{ + int i; + isl_vec *c = NULL; + int rational = ISL_F_ISSET(bmap, ISL_BASIC_MAP_RATIONAL); + isl_size total = isl_basic_map_dim(bmap, isl_dim_all); + unsigned o_div = isl_basic_map_offset(bmap, isl_dim_div); + int first = 1; + int dump; + + if (total < 0 || !p) + return isl_printer_free(p); + bmap = isl_basic_map_copy(bmap); + dump = p->dump; + if (!dump) + bmap = isl_basic_map_sort_constraints(bmap); + if (!bmap) + goto error; + + c = isl_vec_alloc(bmap->ctx, 1 + total); + if (!c) + goto error; + + for (i = bmap->n_eq - 1; i >= 0; --i) { + int l = isl_seq_last_non_zero(bmap->eq[i], 1 + total); + if (l < 0) { + if (i != bmap->n_eq - 1) + p = isl_printer_print_str(p, s_and[latex]); + 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_eq_constraint(p, space, div, c->el, l, latex); + first = 0; + } + for (i = 0; i < bmap->n_ineq; ++i) { + isl_bool combine; + int l = isl_seq_last_non_zero(bmap->ineq[i], 1 + total); + int strict; + int s; + const char *op; + if (l < 0) + continue; + if (!dump && l >= o_div && + can_print_div_expr(p, div, l - o_div)) { + isl_bool is_div; + is_div = isl_basic_map_is_div_constraint(bmap, + bmap->ineq[i], l - o_div); + if (is_div < 0) + goto error; + 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) + isl_seq_cpy(c->el, bmap->ineq[i], 1 + total); + else + isl_seq_neg(c->el, bmap->ineq[i], 1 + total); + if (strict) + isl_int_set_si(c->el[0], 0); + combine = dump ? isl_bool_false : next_is_opposite(bmap, i, l); + if (combine < 0) + goto error; + if (combine) { + op = constraint_op(-s, strict, 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(p, space, div, c->el, l, + op, latex); + first = 0; + } + } + + isl_basic_map_free(bmap); + isl_vec_free(c); + + return p; +error: + isl_basic_map_free(bmap); + isl_vec_free(c); + isl_printer_free(p); + return NULL; +} + +static __isl_give isl_printer *print_div(__isl_keep isl_space *space, + __isl_keep isl_mat *div, int pos, __isl_take isl_printer *p) +{ + int c; + + if (!p || !div) + return isl_printer_free(p); + + c = p->output_format == ISL_FORMAT_C; + p = isl_printer_print_str(p, c ? "floord(" : "floor(("); + p = print_affine_of_len(space, div, p, + div->row[pos] + 1, div->n_col - 1); + p = isl_printer_print_str(p, c ? ", " : ")/"); + p = isl_printer_print_isl_int(p, div->row[pos][0]); + p = isl_printer_print_str(p, ")"); + return p; +} + +/* Print a comma separated list of div names, except those that have + * a definition that can be printed. + * If "print_defined_divs" is set, then those div names are printed + * as well, along with their definitions. + */ +static __isl_give isl_printer *print_div_list(__isl_take isl_printer *p, + __isl_keep isl_space *space, __isl_keep isl_mat *div, int latex, + int print_defined_divs) +{ + int i; + int first = 1; + isl_size n_div; + + n_div = isl_mat_rows(div); + if (!p || !space || n_div < 0) + return isl_printer_free(p); + + for (i = 0; i < n_div; ++i) { + if (!print_defined_divs && can_print_div_expr(p, div, i)) + continue; + if (!first) + p = isl_printer_print_str(p, ", "); + p = print_name(space, p, isl_dim_div, i, latex); + first = 0; + if (!can_print_div_expr(p, div, i)) + continue; + p = isl_printer_print_str(p, " = "); + p = print_div(space, div, i, p); + } + + return p; +} + +/* Does printing an object with local variables described by "div" + * require an "exists" clause? + * That is, are there any local variables without an explicit representation? + * An exists clause is also needed in "dump" mode because + * explicit div representations are not printed inline in that case. + */ +static isl_bool need_exists(__isl_keep isl_printer *p, __isl_keep isl_mat *div) +{ + int i; + isl_size n; + + n = isl_mat_rows(div); + if (!p || n < 0) + return isl_bool_error; + if (n == 0) + return isl_bool_false; + if (p->dump) + return isl_bool_true; + for (i = 0; i < n; ++i) + if (!can_print_div_expr(p, div, i)) + return isl_bool_true; + return isl_bool_false; +} + +/* Print the start of an exists clause, i.e., + * + * (exists variables: + * + * In dump mode, local variables with an explicit definition are printed + * as well because they will not be printed inline. + */ +static __isl_give isl_printer *open_exists(__isl_take isl_printer *p, + __isl_keep isl_space *space, __isl_keep isl_mat *div, int latex) +{ + int dump; + + if (!p) + return NULL; + + dump = p->dump; + p = isl_printer_print_str(p, s_open_exists[latex]); + p = print_div_list(p, space, div, latex, dump); + p = isl_printer_print_str(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; + isl_size n_div; + + n_div = isl_mat_rows(div); + if (n_div < 0) + return isl_mat_free(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. + * Do not print inline explicit div representations in "dump" mode. + */ +static __isl_give isl_printer *print_disjunct(__isl_keep isl_basic_map *bmap, + __isl_keep isl_space *space, __isl_take isl_printer *p, int latex) +{ + int dump; + isl_mat *div; + isl_bool exists; + + if (!p) + return NULL; + dump = p->dump; + div = isl_basic_map_get_divs(bmap); + exists = need_exists(p, div); + if (exists >= 0 && exists) + p = open_exists(p, space, div, latex); + + if (dump) + div = mark_all_unknown(div); + p = print_constraints(bmap, space, div, p, latex); + isl_mat_free(div); + + if (exists >= 0 && exists) + p = isl_printer_print_str(p, s_close_exists[latex]); + return p; +} + +/* Print a colon followed by the constraints of "bmap" + * to "p", provided there are any constraints. + * The names of the variables are taken from "space". + * "latex" is set if the constraints should be printed in LaTeX format. + */ +static __isl_give isl_printer *print_optional_disjunct( + __isl_keep isl_basic_map *bmap, __isl_keep isl_space *space, + __isl_take isl_printer *p, int latex) +{ + if (isl_basic_map_plain_is_universe(bmap)) + return p; + + p = isl_printer_print_str(p, ": "); + p = print_disjunct(bmap, space, p, latex); + + return p; +} + +static __isl_give isl_printer *basic_map_print_omega( + __isl_keep isl_basic_map *bmap, __isl_take isl_printer *p) +{ + p = isl_printer_print_str(p, "{ ["); + p = print_var_list(p, bmap->dim, isl_dim_in); + p = isl_printer_print_str(p, "] -> ["); + p = print_var_list(p, bmap->dim, isl_dim_out); + p = isl_printer_print_str(p, "] "); + p = print_optional_disjunct(bmap, bmap->dim, p, 0); + p = isl_printer_print_str(p, " }"); + return p; +} + +static __isl_give isl_printer *basic_set_print_omega( + __isl_keep isl_basic_set *bset, __isl_take isl_printer *p) +{ + p = isl_printer_print_str(p, "{ ["); + p = print_var_list(p, bset->dim, isl_dim_set); + p = isl_printer_print_str(p, "] "); + p = print_optional_disjunct(bset, bset->dim, p, 0); + p = isl_printer_print_str(p, " }"); + return p; +} + +static __isl_give isl_printer *isl_map_print_omega(__isl_keep isl_map *map, + __isl_take isl_printer *p) +{ + int i; + + for (i = 0; i < map->n; ++i) { + if (i) + p = isl_printer_print_str(p, " union "); + p = basic_map_print_omega(map->p[i], p); + } + return p; +} + +static __isl_give isl_printer *isl_set_print_omega(__isl_keep isl_set *set, + __isl_take isl_printer *p) +{ + int i; + + for (i = 0; i < set->n; ++i) { + if (i) + p = isl_printer_print_str(p, " union "); + p = basic_set_print_omega(set->p[i], p); + } + return p; +} + +/* Print the list of parameters in "space", followed by an arrow, to "p", + * if there are any parameters. + */ +static __isl_give isl_printer *print_param_tuple(__isl_take isl_printer *p, + __isl_keep isl_space *space, struct isl_print_space_data *data) +{ + isl_size nparam; + + nparam = isl_space_dim(space, isl_dim_param); + if (!p || nparam < 0) + return isl_printer_free(p); + if (nparam == 0) + return p; + + p = print_tuple(space, p, isl_dim_param, data); + p = isl_printer_print_str(p, s_to[data->latex]); + + return p; +} + +static __isl_give isl_printer *isl_basic_map_print_isl( + __isl_keep isl_basic_map *bmap, __isl_take isl_printer *p, + int latex) +{ + struct isl_print_space_data data = { .latex = latex }; + int rational = ISL_F_ISSET(bmap, ISL_BASIC_MAP_RATIONAL); + + p = print_param_tuple(p, bmap->dim, &data); + p = isl_printer_print_str(p, "{ "); + p = isl_print_space(bmap->dim, p, rational, &data); + p = isl_printer_print_str(p, " : "); + p = print_disjunct(bmap, bmap->dim, p, latex); + p = isl_printer_print_str(p, " }"); + return p; +} + +/* Print the disjuncts of a map (or set) "map" to "p". + * The names of the variables are taken from "space". + * "latex" is set if the constraints should be printed in LaTeX format. + */ +static __isl_give isl_printer *print_disjuncts_core(__isl_keep isl_map *map, + __isl_keep isl_space *space, __isl_take isl_printer *p, int latex) +{ + int i; + + if (map->n == 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]); + if (map->n > 1 && map->p[i]->n_eq + map->p[i]->n_ineq > 1) + p = isl_printer_print_str(p, "("); + p = print_disjunct(map->p[i], space, p, latex); + if (map->n > 1 && map->p[i]->n_eq + map->p[i]->n_ineq > 1) + p = isl_printer_print_str(p, ")"); + } + return p; +} + +/* Print the disjuncts of a map (or set) "map" to "p". + * The names of the variables are taken from "space". + * "hull" describes constraints shared by all disjuncts of "map". + * "latex" is set if the constraints should be printed in LaTeX format. + * + * Print the disjuncts as a conjunction of "hull" and + * the result of removing the constraints of "hull" from "map". + * If this result turns out to be the universe, then simply print "hull". + */ +static __isl_give isl_printer *print_disjuncts_in_hull(__isl_keep isl_map *map, + __isl_keep isl_space *space, __isl_take isl_basic_map *hull, + __isl_take isl_printer *p, int latex) +{ + isl_bool is_universe; + + p = print_disjunct(hull, space, p, latex); + map = isl_map_plain_gist_basic_map(isl_map_copy(map), hull); + is_universe = isl_map_plain_is_universe(map); + if (is_universe < 0) + goto error; + if (!is_universe) { + p = isl_printer_print_str(p, s_and[latex]); + p = isl_printer_print_str(p, "("); + p = print_disjuncts_core(map, space, p, latex); + p = isl_printer_print_str(p, ")"); + } + isl_map_free(map); + + return p; +error: + isl_map_free(map); + isl_printer_free(p); + return NULL; +} + +/* Print the disjuncts of a map (or set) "map" to "p". + * The names of the variables are taken from "space". + * "latex" is set if the constraints should be printed in LaTeX format. + * + * If there are at least two disjuncts and "dump" mode is not turned out, + * check for any shared constraints among all disjuncts. + * If there are any, then print them separately in print_disjuncts_in_hull. + */ +static __isl_give isl_printer *print_disjuncts(__isl_keep isl_map *map, + __isl_keep isl_space *space, __isl_take isl_printer *p, int latex) +{ + if (isl_map_plain_is_universe(map)) + return p; + + p = isl_printer_print_str(p, s_such_that[latex]); + if (!p) + return NULL; + + if (!p->dump && map->n >= 2) { + isl_basic_map *hull; + isl_bool is_universe; + + hull = isl_map_plain_unshifted_simple_hull(isl_map_copy(map)); + is_universe = isl_basic_map_plain_is_universe(hull); + if (is_universe < 0) + p = isl_printer_free(p); + else if (!is_universe) + return print_disjuncts_in_hull(map, space, hull, + p, latex); + isl_basic_map_free(hull); + } + + return print_disjuncts_core(map, space, p, latex); +} + +/* Print the disjuncts of a map (or set). + * The names of the variables are taken from "space". + * "latex" is set if the constraints should be printed in LaTeX format. + * + * If the map turns out to be a universal parameter domain, then + * we need to print the colon. Otherwise, the output looks identical + * to the empty set. + */ +static __isl_give isl_printer *print_disjuncts_map(__isl_keep isl_map *map, + __isl_keep isl_space *space, __isl_take isl_printer *p, int latex) +{ + if (isl_map_plain_is_universe(map) && isl_space_is_params(map->dim)) + return isl_printer_print_str(p, s_such_that[latex]); + else + return print_disjuncts(map, space, p, latex); +} + +/* Print the disjuncts of a set. + * The names of the variables are taken from "space". + * "latex" is set if the constraints should be printed in LaTeX format. + */ +static __isl_give isl_printer *print_disjuncts_set(__isl_keep isl_set *set, + __isl_keep isl_space *space, __isl_take isl_printer *p, int latex) +{ + return print_disjuncts_map(set_to_map(set), space, p, latex); +} + +struct isl_aff_split { + isl_basic_map *aff; + isl_map *map; +}; + +static void free_split(__isl_take struct isl_aff_split *split, int n) +{ + int i; + + if (!split) + return; + + for (i = 0; i < n; ++i) { + isl_basic_map_free(split[i].aff); + isl_map_free(split[i].map); + } + + free(split); +} + +static __isl_give isl_basic_map *get_aff(__isl_take isl_basic_map *bmap) +{ + int i, j; + isl_size nparam, n_in, n_out, total; + + bmap = isl_basic_map_cow(bmap); + if (!bmap) + return NULL; + bmap = isl_basic_map_free_inequality(bmap, bmap->n_ineq); + + nparam = isl_basic_map_dim(bmap, isl_dim_param); + n_in = isl_basic_map_dim(bmap, isl_dim_in); + n_out = isl_basic_map_dim(bmap, isl_dim_out); + total = isl_basic_map_dim(bmap, isl_dim_all); + if (n_in < 0 || n_out < 0 || nparam < 0 || total < 0) + return isl_basic_map_free(bmap); + + for (i = bmap->n_eq - 1; i >= 0; --i) { + j = isl_seq_last_non_zero(bmap->eq[i] + 1, total); + if (j >= nparam && j < nparam + n_in + n_out && + (isl_int_is_one(bmap->eq[i][1 + j]) || + isl_int_is_negone(bmap->eq[i][1 + j]))) + continue; + if (isl_basic_map_drop_equality(bmap, i) < 0) + goto error; + } + + bmap = isl_basic_map_finalize(bmap); + + return bmap; +error: + isl_basic_map_free(bmap); + return NULL; +} + +static int aff_split_cmp(const void *p1, const void *p2, void *user) +{ + const struct isl_aff_split *s1, *s2; + s1 = (const struct isl_aff_split *) p1; + s2 = (const struct isl_aff_split *) p2; + + return isl_basic_map_plain_cmp(s1->aff, s2->aff); +} + +static __isl_give isl_basic_map *drop_aff(__isl_take isl_basic_map *bmap, + __isl_keep isl_basic_map *aff) +{ + int i, j; + isl_size v_div; + + v_div = isl_basic_map_var_offset(bmap, isl_dim_div); + if (v_div < 0 || !aff) + goto error; + + for (i = bmap->n_eq - 1; i >= 0; --i) { + if (isl_seq_first_non_zero(bmap->eq[i] + 1 + v_div, + bmap->n_div) != -1) + continue; + for (j = 0; j < aff->n_eq; ++j) { + if (!isl_seq_eq(bmap->eq[i], aff->eq[j], 1 + v_div) && + !isl_seq_is_neg(bmap->eq[i], aff->eq[j], 1 + v_div)) + continue; + if (isl_basic_map_drop_equality(bmap, i) < 0) + goto error; + break; + } + } + + return bmap; +error: + isl_basic_map_free(bmap); + return NULL; +} + +static __isl_give struct isl_aff_split *split_aff(__isl_keep isl_map *map) +{ + int i, n; + struct isl_aff_split *split; + isl_ctx *ctx; + + ctx = isl_map_get_ctx(map); + split = isl_calloc_array(ctx, struct isl_aff_split, map->n); + if (!split) + return NULL; + + for (i = 0; i < map->n; ++i) { + isl_basic_map *bmap; + split[i].aff = get_aff(isl_basic_map_copy(map->p[i])); + bmap = isl_basic_map_copy(map->p[i]); + bmap = isl_basic_map_cow(bmap); + bmap = drop_aff(bmap, split[i].aff); + split[i].map = isl_map_from_basic_map(bmap); + if (!split[i].aff || !split[i].map) + goto error; + } + + if (isl_sort(split, map->n, sizeof(struct isl_aff_split), + &aff_split_cmp, NULL) < 0) + goto error; + + n = map->n; + for (i = n - 1; i >= 1; --i) { + if (!isl_basic_map_plain_is_equal(split[i - 1].aff, + split[i].aff)) + continue; + isl_basic_map_free(split[i].aff); + split[i - 1].map = isl_map_union(split[i - 1].map, + split[i].map); + if (i != n - 1) + split[i] = split[n - 1]; + split[n - 1].aff = NULL; + split[n - 1].map = NULL; + --n; + } + + return split; +error: + free_split(split, map->n); + return NULL; +} + +/* Given a set of equality constraints "eq" obtained from get_aff, + * i.e., with a (positive or negative) unit coefficient in the last position, + * look for an equality constraint in "eq" that defines + * the "type" variable at position "pos" in "space", + * i.e., where that last coefficient corresponds to the given variable. + * If so, return the position of that equality constraint. + * Return a value beyond the number of equality constraints + * if no such constraint can be found. + * Return isl_size_error in case of error. + * + * If a suitable constraint is found, then also make sure + * it has a negative unit coefficient for the given variable. + */ +static isl_size defining_equality(__isl_keep isl_basic_map *eq, + __isl_keep isl_space *space, enum isl_dim_type type, int pos) +{ + int i; + isl_size total, off; + isl_size n_eq; + + total = isl_basic_map_dim(eq, isl_dim_all); + n_eq = isl_basic_map_n_equality(eq); + off = isl_space_offset(space, type); + if (total < 0 || n_eq < 0 || off < 0) + return isl_size_error; + + pos += off; + + for (i = 0; i < n_eq; ++i) { + if (isl_seq_last_non_zero(eq->eq[i] + 1, total) != pos) + continue; + if (isl_int_is_one(eq->eq[i][1 + pos])) + isl_seq_neg(eq->eq[i], eq->eq[i], 1 + total); + return i; + } + + return n_eq; +} + +/* Print dimension "pos" of data->space to "p". + * + * data->user is assumed to be an isl_basic_map keeping track of equalities. + * + * If the current dimension is defined by these equalities, then print + * the corresponding expression, assigned to the name of the dimension + * if there is any. Otherwise, print the name of the dimension. + */ +static __isl_give isl_printer *print_dim_eq(__isl_take isl_printer *p, + struct isl_print_space_data *data, unsigned pos) +{ + isl_basic_map *eq = data->user; + isl_size j, n_eq; + + n_eq = isl_basic_map_n_equality(eq); + j = defining_equality(eq, data->space, data->type, pos); + if (j < 0 || n_eq < 0) + return isl_printer_free(p); + if (j < n_eq) { + isl_size off; + + if (isl_space_has_dim_name(data->space, data->type, pos)) { + p = print_name(data->space, p, data->type, pos, + data->latex); + p = isl_printer_print_str(p, " = "); + } + off = isl_space_offset(data->space, data->type); + if (off < 0) + return isl_printer_free(p); + pos += 1 + off; + p = print_affine_of_len(data->space, NULL, p, eq->eq[j], pos); + } else { + p = print_name(data->space, p, data->type, pos, data->latex); + } + + return p; +} + +static __isl_give isl_printer *print_split_map(__isl_take isl_printer *p, + struct isl_aff_split *split, int n, __isl_keep isl_space *space) +{ + struct isl_print_space_data data = { 0 }; + int i; + int rational; + + data.print_dim = &print_dim_eq; + for (i = 0; i < n; ++i) { + if (!split[i].map) + break; + rational = split[i].map->n > 0 && + ISL_F_ISSET(split[i].map->p[0], ISL_BASIC_MAP_RATIONAL); + if (i) + p = isl_printer_print_str(p, "; "); + data.user = split[i].aff; + p = isl_print_space(space, p, rational, &data); + p = print_disjuncts_map(split[i].map, space, p, 0); + } + + return p; +} + +static __isl_give isl_printer *print_body_map(__isl_take isl_printer *p, + __isl_keep isl_map *map) +{ + struct isl_print_space_data data = { 0 }; + struct isl_aff_split *split = NULL; + int rational; + + if (!p || !map) + return isl_printer_free(p); + if (!p->dump && map->n > 0) + split = split_aff(map); + if (split) { + p = print_split_map(p, split, map->n, map->dim); + } else { + rational = map->n > 0 && + ISL_F_ISSET(map->p[0], ISL_BASIC_MAP_RATIONAL); + p = isl_print_space(map->dim, p, rational, &data); + p = print_disjuncts_map(map, map->dim, p, 0); + } + free_split(split, map->n); + return p; +} + +static __isl_give isl_printer *isl_map_print_isl(__isl_keep isl_map *map, + __isl_take isl_printer *p) +{ + struct isl_print_space_data data = { 0 }; + + p = print_param_tuple(p, map->dim, &data); + p = isl_printer_print_str(p, s_open_set[0]); + p = print_body_map(p, map); + p = isl_printer_print_str(p, s_close_set[0]); + return p; +} + +static __isl_give isl_printer *print_latex_map(__isl_keep isl_map *map, + __isl_take isl_printer *p, __isl_keep isl_basic_map *aff) +{ + struct isl_print_space_data data = { 0 }; + + data.latex = 1; + p = print_param_tuple(p, map->dim, &data); + p = isl_printer_print_str(p, s_open_set[1]); + data.print_dim = &print_dim_eq; + data.user = aff; + p = isl_print_space(map->dim, p, 0, &data); + p = print_disjuncts_map(map, map->dim, p, 1); + p = isl_printer_print_str(p, s_close_set[1]); + + return p; +} + +static __isl_give isl_printer *isl_map_print_latex(__isl_keep isl_map *map, + __isl_take isl_printer *p) +{ + int i; + struct isl_aff_split *split = NULL; + + if (map->n > 0) + split = split_aff(map); + + if (!split) + return print_latex_map(map, p, NULL); + + for (i = 0; i < map->n; ++i) { + if (!split[i].map) + break; + if (i) + p = isl_printer_print_str(p, " \\cup "); + p = print_latex_map(split[i].map, p, split[i].aff); + } + + free_split(split, map->n); + return p; +} + +__isl_give isl_printer *isl_printer_print_basic_map(__isl_take isl_printer *p, + __isl_keep isl_basic_map *bmap) +{ + if (!p || !bmap) + goto error; + if (p->output_format == ISL_FORMAT_ISL) + return isl_basic_map_print_isl(bmap, p, 0); + else if (p->output_format == ISL_FORMAT_OMEGA) + return basic_map_print_omega(bmap, p); + isl_assert(bmap->ctx, 0, goto error); +error: + isl_printer_free(p); + return NULL; +} + +__isl_give isl_printer *isl_printer_print_basic_set(__isl_take isl_printer *p, + __isl_keep isl_basic_set *bset) +{ + if (!p || !bset) + goto error; + + if (p->output_format == ISL_FORMAT_ISL) + return isl_basic_map_print_isl(bset, p, 0); + else if (p->output_format == ISL_FORMAT_POLYLIB) + return isl_basic_set_print_polylib(bset, p, 0); + else if (p->output_format == ISL_FORMAT_EXT_POLYLIB) + return isl_basic_set_print_polylib(bset, p, 1); + else if (p->output_format == ISL_FORMAT_POLYLIB_CONSTRAINTS) + return bset_print_constraints_polylib(bset, p); + else if (p->output_format == ISL_FORMAT_OMEGA) + return basic_set_print_omega(bset, p); + isl_assert(p->ctx, 0, goto error); +error: + isl_printer_free(p); + return NULL; +} + +__isl_give isl_printer *isl_printer_print_set(__isl_take isl_printer *p, + __isl_keep isl_set *set) +{ + if (!p || !set) + goto error; + if (p->output_format == ISL_FORMAT_ISL) + return isl_map_print_isl(set_to_map(set), p); + else if (p->output_format == ISL_FORMAT_POLYLIB) + return isl_set_print_polylib(set, p, 0); + else if (p->output_format == ISL_FORMAT_EXT_POLYLIB) + return isl_set_print_polylib(set, p, 1); + else if (p->output_format == ISL_FORMAT_OMEGA) + return isl_set_print_omega(set, p); + else if (p->output_format == ISL_FORMAT_LATEX) + return isl_map_print_latex(set_to_map(set), p); + isl_assert(set->ctx, 0, goto error); +error: + isl_printer_free(p); + return NULL; +} + +__isl_give isl_printer *isl_printer_print_map(__isl_take isl_printer *p, + __isl_keep isl_map *map) +{ + if (!p || !map) + goto error; + + if (p->output_format == ISL_FORMAT_ISL) + return isl_map_print_isl(map, p); + else if (p->output_format == ISL_FORMAT_POLYLIB) + return isl_map_print_polylib(map, p, 0); + else if (p->output_format == ISL_FORMAT_EXT_POLYLIB) + return isl_map_print_polylib(map, p, 1); + else if (p->output_format == ISL_FORMAT_OMEGA) + return isl_map_print_omega(map, p); + else if (p->output_format == ISL_FORMAT_LATEX) + return isl_map_print_latex(map, p); + isl_assert(map->ctx, 0, goto error); +error: + isl_printer_free(p); + return NULL; +} + +struct isl_union_print_data { + isl_printer *p; + int first; +}; + +#undef BASE +#define BASE map +#include "isl_union_print_templ.c" + +/* Print the body of "uset" (everything except the parameter declarations) + * to "p" in isl format. + */ +static __isl_give isl_printer *isl_printer_print_union_set_isl_body( + __isl_take isl_printer *p, __isl_keep isl_union_set *uset) +{ + return print_body_union_map(p, uset_to_umap(uset)); +} + +static isl_stat print_latex_map_body(__isl_take isl_map *map, void *user) +{ + struct isl_union_print_data *data; + data = (struct isl_union_print_data *)user; + + if (!data->first) + data->p = isl_printer_print_str(data->p, " \\cup "); + data->first = 0; + + data->p = isl_map_print_latex(map, data->p); + isl_map_free(map); + + return isl_stat_ok; +} + +static __isl_give isl_printer *isl_union_map_print_latex( + __isl_keep isl_union_map *umap, __isl_take isl_printer *p) +{ + struct isl_union_print_data data = { p, 1 }; + isl_union_map_foreach_map(umap, &print_latex_map_body, &data); + p = data.p; + return p; +} + +__isl_give isl_printer *isl_printer_print_union_map(__isl_take isl_printer *p, + __isl_keep isl_union_map *umap) +{ + if (!p || !umap) + goto error; + + if (p->output_format == ISL_FORMAT_ISL) + return print_union_map_isl(p, umap); + if (p->output_format == ISL_FORMAT_LATEX) + return isl_union_map_print_latex(umap, p); + + isl_die(p->ctx, isl_error_invalid, + "invalid output format for isl_union_map", goto error); +error: + isl_printer_free(p); + return NULL; +} + +__isl_give isl_printer *isl_printer_print_union_set(__isl_take isl_printer *p, + __isl_keep isl_union_set *uset) +{ + if (!p || !uset) + goto error; + + if (p->output_format == ISL_FORMAT_ISL) + return print_union_map_isl(p, uset_to_umap(uset)); + if (p->output_format == ISL_FORMAT_LATEX) + 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); +error: + isl_printer_free(p); + return NULL; +} + +static isl_size poly_rec_n_non_zero(__isl_keep isl_poly_rec *rec) +{ + int i; + int n; + + if (!rec) + return isl_size_error; + + for (i = 0, n = 0; i < rec->n; ++i) { + isl_bool is_zero = isl_poly_is_zero(rec->p[i]); + + if (is_zero < 0) + return isl_size_error; + if (!is_zero) + ++n; + } + + return n; +} + +static __isl_give isl_printer *poly_print_cst(__isl_keep isl_poly *poly, + __isl_take isl_printer *p, int first) +{ + isl_poly_cst *cst; + int neg; + + cst = isl_poly_as_cst(poly); + if (!cst) + goto error; + neg = !first && isl_int_is_neg(cst->n); + if (!first) + p = isl_printer_print_str(p, neg ? " - " : " + "); + if (neg) + isl_int_neg(cst->n, cst->n); + if (isl_int_is_zero(cst->d)) { + int sgn = isl_int_sgn(cst->n); + p = isl_printer_print_str(p, sgn < 0 ? "-infty" : + sgn == 0 ? "NaN" : "infty"); + } else + p = isl_printer_print_isl_int(p, cst->n); + if (neg) + isl_int_neg(cst->n, cst->n); + if (!isl_int_is_zero(cst->d) && !isl_int_is_one(cst->d)) { + p = isl_printer_print_str(p, "/"); + p = isl_printer_print_isl_int(p, cst->d); + } + return p; +error: + isl_printer_free(p); + return NULL; +} + +static __isl_give isl_printer *print_base(__isl_take isl_printer *p, + __isl_keep isl_space *space, __isl_keep isl_mat *div, int var) +{ + isl_size total; + + total = isl_space_dim(space, isl_dim_all); + if (total < 0) + return isl_printer_free(p); + if (var < total) + p = print_term(space, NULL, space->ctx->one, 1 + var, p, 0); + else + p = print_div(space, div, var - total, p); + return p; +} + +static __isl_give isl_printer *print_pow(__isl_take isl_printer *p, + __isl_keep isl_space *space, __isl_keep isl_mat *div, int var, int exp) +{ + p = print_base(p, space, div, var); + if (exp == 1) + return p; + if (p->output_format == ISL_FORMAT_C) { + int i; + for (i = 1; i < exp; ++i) { + p = isl_printer_print_str(p, "*"); + p = print_base(p, space, div, var); + } + } else { + p = isl_printer_print_str(p, "^"); + p = isl_printer_print_int(p, exp); + } + return p; +} + +/* Print the polynomial "poly" defined over the domain space "space" and + * local variables defined by "div" to "p". + */ +static __isl_give isl_printer *poly_print(__isl_keep isl_poly *poly, + __isl_keep isl_space *space, __isl_keep isl_mat *div, + __isl_take isl_printer *p) +{ + int i, first, print_parens; + isl_size n; + isl_bool is_cst; + isl_poly_rec *rec; + + is_cst = isl_poly_is_cst(poly); + if (!p || is_cst < 0 || !space || !div) + goto error; + + if (is_cst) + return poly_print_cst(poly, p, 1); + + rec = isl_poly_as_rec(poly); + n = poly_rec_n_non_zero(rec); + if (n < 0) + return isl_printer_free(p); + print_parens = n > 1; + if (print_parens) + p = isl_printer_print_str(p, "("); + for (i = 0, first = 1; i < rec->n; ++i) { + isl_bool is_zero = isl_poly_is_zero(rec->p[i]); + isl_bool is_one = isl_poly_is_one(rec->p[i]); + isl_bool is_negone = isl_poly_is_negone(rec->p[i]); + isl_bool is_cst = isl_poly_is_cst(rec->p[i]); + + if (is_zero < 0 || is_one < 0 || is_negone < 0) + return isl_printer_free(p); + if (is_zero) + continue; + if (is_negone) { + if (!i) + p = isl_printer_print_str(p, "-1"); + else if (first) + p = isl_printer_print_str(p, "-"); + else + p = isl_printer_print_str(p, " - "); + } else if (is_cst && !is_one) + p = poly_print_cst(rec->p[i], p, first); + else { + if (!first) + p = isl_printer_print_str(p, " + "); + if (i == 0 || !is_one) + p = poly_print(rec->p[i], space, div, p); + } + first = 0; + if (i == 0) + continue; + if (!is_one && !is_negone) + p = isl_printer_print_str(p, " * "); + p = print_pow(p, space, div, rec->poly.var, i); + } + if (print_parens) + p = isl_printer_print_str(p, ")"); + return p; +error: + isl_printer_free(p); + return NULL; +} + +static __isl_give isl_printer *print_qpolynomial(__isl_take isl_printer *p, + __isl_keep isl_qpolynomial *qp) +{ + if (!p || !qp) + goto error; + p = poly_print(qp->poly, qp->dim, qp->div, p); + return p; +error: + isl_printer_free(p); + return NULL; +} + +static __isl_give isl_printer *print_qpolynomial_isl(__isl_take isl_printer *p, + __isl_keep isl_qpolynomial *qp) +{ + struct isl_print_space_data data = { 0 }; + + if (!p || !qp) + goto error; + + p = print_param_tuple(p, qp->dim, &data); + p = isl_printer_print_str(p, "{ "); + if (!isl_space_is_params(qp->dim)) { + p = isl_print_space(qp->dim, p, 0, &data); + p = isl_printer_print_str(p, " -> "); + } + p = print_qpolynomial(p, qp); + p = isl_printer_print_str(p, " }"); + return p; +error: + isl_printer_free(p); + return NULL; +} + +/* Print the quasi-polynomial "qp" to "p" in C format, with the variable names + * taken from the domain space "space". + */ +static __isl_give isl_printer *print_qpolynomial_c(__isl_take isl_printer *p, + __isl_keep isl_space *space, __isl_keep isl_qpolynomial *qp) +{ + isl_bool is_one; + isl_val *den; + + den = isl_qpolynomial_get_den(qp); + qp = isl_qpolynomial_copy(qp); + qp = isl_qpolynomial_scale_val(qp, isl_val_copy(den)); + is_one = isl_val_is_one(den); + if (is_one < 0) + p = isl_printer_free(p); + if (!is_one) + p = isl_printer_print_str(p, "("); + if (qp) + p = poly_print(qp->poly, space, qp->div, p); + else + p = isl_printer_free(p); + if (!is_one) { + p = isl_printer_print_str(p, ")/"); + p = isl_printer_print_val(p, den); + } + isl_qpolynomial_free(qp); + isl_val_free(den); + return p; +} + +__isl_give isl_printer *isl_printer_print_qpolynomial( + __isl_take isl_printer *p, __isl_keep isl_qpolynomial *qp) +{ + if (!p || !qp) + goto error; + + if (p->output_format == ISL_FORMAT_ISL) + return print_qpolynomial_isl(p, qp); + else if (p->output_format == ISL_FORMAT_C) + return print_qpolynomial_c(p, qp->dim, qp); + else + isl_die(qp->dim->ctx, isl_error_unsupported, + "output format not supported for isl_qpolynomials", + goto error); +error: + isl_printer_free(p); + return NULL; +} + +void isl_qpolynomial_print(__isl_keep isl_qpolynomial *qp, FILE *out, + unsigned output_format) +{ + isl_printer *p; + + if (!qp) + return; + + isl_assert(qp->dim->ctx, output_format == ISL_FORMAT_ISL, return); + p = isl_printer_to_file(qp->dim->ctx, out); + p = isl_printer_print_qpolynomial(p, qp); + isl_printer_free(p); +} + +static __isl_give isl_printer *qpolynomial_fold_print( + __isl_keep isl_qpolynomial_fold *fold, __isl_take isl_printer *p) +{ + int i; + isl_qpolynomial_list *list; + isl_size n; + + list = isl_qpolynomial_fold_peek_list(fold); + n = isl_qpolynomial_list_size(list); + if (n < 0) + return isl_printer_free(p); + if (fold->type == isl_fold_min) + p = isl_printer_print_str(p, "min"); + else if (fold->type == isl_fold_max) + p = isl_printer_print_str(p, "max"); + p = isl_printer_print_str(p, "("); + for (i = 0; i < n; ++i) { + isl_qpolynomial *qp; + + if (i) + p = isl_printer_print_str(p, ", "); + qp = isl_qpolynomial_list_peek(list, i); + p = print_qpolynomial(p, qp); + } + p = isl_printer_print_str(p, ")"); + return p; +} + +void isl_qpolynomial_fold_print(__isl_keep isl_qpolynomial_fold *fold, + FILE *out, unsigned output_format) +{ + isl_printer *p; + + if (!fold) + return; + + isl_assert(fold->dim->ctx, output_format == ISL_FORMAT_ISL, return); + + p = isl_printer_to_file(fold->dim->ctx, out); + p = isl_printer_print_qpolynomial_fold(p, fold); + + isl_printer_free(p); +} + +static __isl_give isl_printer *print_body_pw_qpolynomial( + __isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial *pwqp) +{ + struct isl_print_space_data data = { 0 }; + int i = 0; + + for (i = 0; i < pwqp->n; ++i) { + isl_space *space; + + if (i) + p = isl_printer_print_str(p, "; "); + space = isl_qpolynomial_get_domain_space(pwqp->p[i].qp); + if (!isl_space_is_params(space)) { + p = isl_print_space(space, p, 0, &data); + p = isl_printer_print_str(p, " -> "); + } + p = print_qpolynomial(p, pwqp->p[i].qp); + p = print_disjuncts(set_to_map(pwqp->p[i].set), space, p, 0); + isl_space_free(space); + } + + return p; +} + +static __isl_give isl_printer *print_pw_qpolynomial_isl( + __isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial *pwqp) +{ + struct isl_print_space_data data = { 0 }; + + if (!p || !pwqp) + goto error; + + p = print_param_tuple(p, pwqp->dim, &data); + p = isl_printer_print_str(p, "{ "); + if (pwqp->n == 0) { + if (!isl_space_is_set(pwqp->dim)) { + p = print_tuple(pwqp->dim, p, isl_dim_in, &data); + p = isl_printer_print_str(p, " -> "); + } + p = isl_printer_print_str(p, "0"); + } + p = print_body_pw_qpolynomial(p, pwqp); + p = isl_printer_print_str(p, " }"); + return p; +error: + isl_printer_free(p); + return NULL; +} + +void isl_pw_qpolynomial_print(__isl_keep isl_pw_qpolynomial *pwqp, FILE *out, + unsigned output_format) +{ + isl_printer *p; + + if (!pwqp) + return; + + p = isl_printer_to_file(pwqp->dim->ctx, out); + p = isl_printer_set_output_format(p, output_format); + p = isl_printer_print_pw_qpolynomial(p, pwqp); + + isl_printer_free(p); +} + +static __isl_give isl_printer *print_body_pw_qpolynomial_fold( + __isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial_fold *pwf) +{ + struct isl_print_space_data data = { 0 }; + int i = 0; + + for (i = 0; i < pwf->n; ++i) { + isl_space *space; + + if (i) + p = isl_printer_print_str(p, "; "); + space = isl_qpolynomial_fold_get_domain_space(pwf->p[i].fold); + if (!isl_space_is_params(space)) { + p = isl_print_space(space, p, 0, &data); + p = isl_printer_print_str(p, " -> "); + } + p = qpolynomial_fold_print(pwf->p[i].fold, p); + p = print_disjuncts(set_to_map(pwf->p[i].set), space, p, 0); + isl_space_free(space); + } + + return p; +} + +static __isl_give isl_printer *print_pw_qpolynomial_fold_isl( + __isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial_fold *pwf) +{ + struct isl_print_space_data data = { 0 }; + + p = print_param_tuple(p, pwf->dim, &data); + p = isl_printer_print_str(p, "{ "); + if (pwf->n == 0) { + if (!isl_space_is_set(pwf->dim)) { + p = print_tuple(pwf->dim, p, isl_dim_in, &data); + p = isl_printer_print_str(p, " -> "); + } + p = isl_printer_print_str(p, "0"); + } + p = print_body_pw_qpolynomial_fold(p, pwf); + p = isl_printer_print_str(p, " }"); + return p; +} + +static __isl_give isl_printer *print_ls_affine_c(__isl_take isl_printer *p, + __isl_keep isl_local_space *ls, isl_int *c); + +/* We skip the constraint if it is implied by the div expression. + * + * *first indicates whether this is the first constraint in the conjunction and + * is updated if the constraint is actually printed. + */ +static __isl_give isl_printer *print_constraint_c(__isl_take isl_printer *p, + __isl_keep isl_local_space *ls, isl_int *c, const char *op, int *first) +{ + unsigned o_div; + isl_size n_div; + int div; + + o_div = isl_local_space_offset(ls, isl_dim_div); + n_div = isl_local_space_dim(ls, isl_dim_div); + if (n_div < 0) + return isl_printer_free(p); + div = isl_seq_last_non_zero(c + o_div, n_div); + if (div >= 0) { + isl_bool is_div = isl_local_space_is_div_constraint(ls, c, div); + if (is_div < 0) + return isl_printer_free(p); + if (is_div) + return p; + } + + if (!*first) + p = isl_printer_print_str(p, " && "); + + p = print_ls_affine_c(p, ls, c); + p = isl_printer_print_str(p, " "); + p = isl_printer_print_str(p, op); + p = isl_printer_print_str(p, " 0"); + + *first = 0; + + return p; +} + +static __isl_give isl_printer *print_ls_partial_affine_c( + __isl_take isl_printer *p, __isl_keep isl_local_space *ls, + isl_int *c, unsigned len); + +static __isl_give isl_printer *print_basic_set_c(__isl_take isl_printer *p, + __isl_keep isl_space *space, __isl_keep isl_basic_set *bset) +{ + int i, j; + int first = 1; + isl_size n_div = isl_basic_set_dim(bset, isl_dim_div); + isl_size total = isl_basic_set_dim(bset, isl_dim_all); + isl_mat *div; + isl_local_space *ls; + + if (n_div < 0 || total < 0) + return isl_printer_free(p); + + total -= n_div; + div = isl_basic_set_get_divs(bset); + ls = isl_local_space_alloc_div(isl_space_copy(space), div); + for (i = 0; i < bset->n_eq; ++i) { + j = isl_seq_last_non_zero(bset->eq[i] + 1 + total, n_div); + if (j < 0) + p = print_constraint_c(p, ls, + bset->eq[i], "==", &first); + else { + if (i) + p = isl_printer_print_str(p, " && "); + p = isl_printer_print_str(p, "("); + p = print_ls_partial_affine_c(p, ls, bset->eq[i], + 1 + total + j); + p = isl_printer_print_str(p, ") % "); + p = isl_printer_print_isl_int(p, + bset->eq[i][1 + total + j]); + p = isl_printer_print_str(p, " == 0"); + first = 0; + } + } + for (i = 0; i < bset->n_ineq; ++i) + p = print_constraint_c(p, ls, bset->ineq[i], ">=", &first); + isl_local_space_free(ls); + return p; +} + +static __isl_give isl_printer *print_set_c(__isl_take isl_printer *p, + __isl_keep isl_space *space, __isl_keep isl_set *set) +{ + int i; + + if (!set) + return isl_printer_free(p); + + if (set->n == 0) + p = isl_printer_print_str(p, "0"); + + for (i = 0; i < set->n; ++i) { + if (i) + p = isl_printer_print_str(p, " || "); + if (set->n > 1) + p = isl_printer_print_str(p, "("); + p = print_basic_set_c(p, space, set->p[i]); + if (set->n > 1) + p = isl_printer_print_str(p, ")"); + } + return p; +} + +/* Print the piecewise quasi-polynomial "pwqp" to "p" in C format. + */ +static __isl_give isl_printer *print_pw_qpolynomial_c( + __isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial *pwqp) +{ + int i; + isl_space *space; + + space = isl_pw_qpolynomial_get_domain_space(pwqp); + if (pwqp->n == 1 && isl_set_plain_is_universe(pwqp->p[0].set)) { + p = print_qpolynomial_c(p, space, pwqp->p[0].qp); + isl_space_free(space); + return p; + } + + for (i = 0; i < pwqp->n; ++i) { + p = isl_printer_print_str(p, "("); + p = print_set_c(p, space, pwqp->p[i].set); + p = isl_printer_print_str(p, ") ? ("); + p = print_qpolynomial_c(p, space, pwqp->p[i].qp); + p = isl_printer_print_str(p, ") : "); + } + + isl_space_free(space); + p = isl_printer_print_str(p, "0"); + return p; +} + +__isl_give isl_printer *isl_printer_print_pw_qpolynomial( + __isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial *pwqp) +{ + if (!p || !pwqp) + goto error; + + if (p->output_format == ISL_FORMAT_ISL) + return print_pw_qpolynomial_isl(p, pwqp); + else if (p->output_format == ISL_FORMAT_C) + return print_pw_qpolynomial_c(p, pwqp); + isl_assert(p->ctx, 0, goto error); +error: + isl_printer_free(p); + return NULL; +} + +#undef BASE +#define BASE pw_qpolynomial +#include "isl_union_print_templ.c" + +__isl_give isl_printer *isl_printer_print_union_pw_qpolynomial( + __isl_take isl_printer *p, __isl_keep isl_union_pw_qpolynomial *upwqp) +{ + if (!p || !upwqp) + goto error; + + if (p->output_format == ISL_FORMAT_ISL) + return print_union_pw_qpolynomial_isl(p, upwqp); + isl_die(p->ctx, isl_error_invalid, + "invalid output format for isl_union_pw_qpolynomial", + goto error); +error: + isl_printer_free(p); + return NULL; +} + +/* Print the quasi-polynomial reduction "fold" to "p" in C format, + * with the variable names taken from the domain space "space". + */ +static __isl_give isl_printer *print_qpolynomial_fold_c( + __isl_take isl_printer *p, __isl_keep isl_space *space, + __isl_keep isl_qpolynomial_fold *fold) +{ + int i; + isl_qpolynomial_list *list; + isl_size n; + + list = isl_qpolynomial_fold_peek_list(fold); + n = isl_qpolynomial_list_size(list); + if (n < 0) + return isl_printer_free(p); + for (i = 0; i < n - 1; ++i) + if (fold->type == isl_fold_min) + p = isl_printer_print_str(p, "min("); + else if (fold->type == isl_fold_max) + p = isl_printer_print_str(p, "max("); + + for (i = 0; i < n; ++i) { + isl_qpolynomial *qp; + + if (i) + p = isl_printer_print_str(p, ", "); + qp = isl_qpolynomial_list_peek(list, i); + p = print_qpolynomial_c(p, space, qp); + if (i) + p = isl_printer_print_str(p, ")"); + } + return p; +} + +__isl_give isl_printer *isl_printer_print_qpolynomial_fold( + __isl_take isl_printer *p, __isl_keep isl_qpolynomial_fold *fold) +{ + if (!p || !fold) + goto error; + if (p->output_format == ISL_FORMAT_ISL) + return qpolynomial_fold_print(fold, p); + else if (p->output_format == ISL_FORMAT_C) + return print_qpolynomial_fold_c(p, fold->dim, fold); + isl_die(p->ctx, isl_error_unsupported, "unsupported output format", + goto error); +error: + isl_printer_free(p); + return NULL; +} + +/* Print the piecewise quasi-polynomial reduction "pwf" to "p" in C format. + */ +static __isl_give isl_printer *print_pw_qpolynomial_fold_c( + __isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial_fold *pwf) +{ + int i; + isl_space *space; + + space = isl_pw_qpolynomial_fold_get_domain_space(pwf); + if (pwf->n == 1 && isl_set_plain_is_universe(pwf->p[0].set)) { + p = print_qpolynomial_fold_c(p, space, pwf->p[0].fold); + isl_space_free(space); + return p; + } + + for (i = 0; i < pwf->n; ++i) { + p = isl_printer_print_str(p, "("); + p = print_set_c(p, space, pwf->p[i].set); + p = isl_printer_print_str(p, ") ? ("); + p = print_qpolynomial_fold_c(p, space, pwf->p[i].fold); + p = isl_printer_print_str(p, ") : "); + } + + isl_space_free(space); + p = isl_printer_print_str(p, "0"); + return p; +} + +__isl_give isl_printer *isl_printer_print_pw_qpolynomial_fold( + __isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial_fold *pwf) +{ + if (!p || !pwf) + goto error; + + if (p->output_format == ISL_FORMAT_ISL) + return print_pw_qpolynomial_fold_isl(p, pwf); + else if (p->output_format == ISL_FORMAT_C) + return print_pw_qpolynomial_fold_c(p, pwf); + isl_assert(p->ctx, 0, goto error); +error: + isl_printer_free(p); + return NULL; +} + +void isl_pw_qpolynomial_fold_print(__isl_keep isl_pw_qpolynomial_fold *pwf, + FILE *out, unsigned output_format) +{ + isl_printer *p; + + if (!pwf) + return; + + p = isl_printer_to_file(pwf->dim->ctx, out); + p = isl_printer_set_output_format(p, output_format); + p = isl_printer_print_pw_qpolynomial_fold(p, pwf); + + isl_printer_free(p); +} + +#undef BASE +#define BASE pw_qpolynomial_fold +#include "isl_union_print_templ.c" + +__isl_give isl_printer *isl_printer_print_union_pw_qpolynomial_fold( + __isl_take isl_printer *p, + __isl_keep isl_union_pw_qpolynomial_fold *upwf) +{ + if (!p || !upwf) + goto error; + + if (p->output_format == ISL_FORMAT_ISL) + return print_union_pw_qpolynomial_fold_isl(p, upwf); + isl_die(p->ctx, isl_error_invalid, + "invalid output format for isl_union_pw_qpolynomial_fold", + goto error); +error: + isl_printer_free(p); + return NULL; +} + +/* Print the isl_constraint "c" to "p". + */ +__isl_give isl_printer *isl_printer_print_constraint(__isl_take isl_printer *p, + __isl_keep isl_constraint *c) +{ + struct isl_print_space_data data = { 0 }; + isl_local_space *ls; + isl_space *space; + isl_bool exists; + + if (!p || !c) + goto error; + + ls = isl_constraint_get_local_space(c); + if (!ls) + return isl_printer_free(p); + space = isl_local_space_get_space(ls); + p = print_param_tuple(p, space, &data); + p = isl_printer_print_str(p, "{ "); + p = isl_print_space(space, p, 0, &data); + p = isl_printer_print_str(p, " : "); + exists = need_exists(p, ls->div); + if (exists < 0) + p = isl_printer_free(p); + if (exists >= 0 && exists) + p = open_exists(p, space, ls->div, 0); + p = print_affine_of_len(space, ls->div, p, c->v->el, c->v->size); + if (isl_constraint_is_equality(c)) + p = isl_printer_print_str(p, " = 0"); + else + p = isl_printer_print_str(p, " >= 0"); + if (exists >= 0 && exists) + p = isl_printer_print_str(p, s_close_exists[0]); + p = isl_printer_print_str(p, " }"); + isl_space_free(space); + isl_local_space_free(ls); + + return p; +error: + isl_printer_free(p); + return NULL; +} + +static __isl_give isl_printer *isl_printer_print_space_isl( + __isl_take isl_printer *p, __isl_keep isl_space *space) +{ + struct isl_print_space_data data = { 0 }; + + if (!space) + goto error; + + p = print_param_tuple(p, space, &data); + + p = isl_printer_print_str(p, "{ "); + if (isl_space_is_params(space)) + p = isl_printer_print_str(p, s_such_that[0]); + else + p = isl_print_space(space, p, 0, &data); + p = isl_printer_print_str(p, " }"); + + return p; +error: + isl_printer_free(p); + return NULL; +} + +__isl_give isl_printer *isl_printer_print_space(__isl_take isl_printer *p, + __isl_keep isl_space *space) +{ + if (!p || !space) + return isl_printer_free(p); + if (p->output_format == ISL_FORMAT_ISL) + return isl_printer_print_space_isl(p, space); + else if (p->output_format == ISL_FORMAT_OMEGA) + return print_omega_parameters(space, p); + + isl_die(isl_space_get_ctx(space), isl_error_unsupported, + "output format not supported for space", + return isl_printer_free(p)); +} + +__isl_give isl_printer *isl_printer_print_local_space(__isl_take isl_printer *p, + __isl_keep isl_local_space *ls) +{ + struct isl_print_space_data data = { 0 }; + isl_size n_div; + + n_div = isl_local_space_dim(ls, isl_dim_div); + if (n_div < 0) + goto error; + + p = print_param_tuple(p, ls->dim, &data); + p = isl_printer_print_str(p, "{ "); + p = isl_print_space(ls->dim, p, 0, &data); + if (n_div > 0) { + p = isl_printer_print_str(p, " : "); + p = isl_printer_print_str(p, s_open_exists[0]); + p = print_div_list(p, ls->dim, ls->div, 0, 1); + p = isl_printer_print_str(p, s_close_exists[0]); + } else if (isl_space_is_params(ls->dim)) + p = isl_printer_print_str(p, s_such_that[0]); + p = isl_printer_print_str(p, " }"); + return p; +error: + isl_printer_free(p); + return NULL; +} + +/* Look for the last of the "n" integer divisions that is used in "aff" and + * that can be printed as a modulo and + * return the position of this integer division. + * Return "n" if no such integer division can be found. + * Return isl_size_error on error. + * + * In particular, look for an integer division that appears in "aff" + * with a coefficient that is a multiple of the denominator + * of the integer division. + * That is, check if the numerator of "aff" is of the form + * + * f(...) + a m floor(g/m) + * + * and return the position of "floor(g/m)". + * + * Note that, unlike print_as_modulo_pos, no check needs to be made + * for whether the integer division can be printed, since it will + * need to be printed as an integer division anyway if it is not printed + * as a modulo. + */ +static isl_size last_modulo(__isl_keep isl_printer *p, __isl_keep isl_aff *aff, + unsigned n) +{ + isl_size o_div; + int i; + + if (n == 0) + return n; + o_div = isl_aff_domain_offset(aff, isl_dim_div); + if (o_div < 0) + return isl_size_error; + for (i = n - 1; i >= 0; --i) { + if (isl_int_is_zero(aff->v->el[1 + o_div + i])) + continue; + if (isl_int_is_divisible_by(aff->v->el[1 + o_div + i], + aff->ls->div->row[i][0])) + return i; + } + + return n; +} + +/* Print the numerator of the affine expression "aff" to "p", + * with the variable names taken from "space". + */ +static __isl_give isl_printer *print_aff_num_base(__isl_take isl_printer *p, + __isl_keep isl_space *space, __isl_keep isl_aff *aff) +{ + isl_size total; + + total = isl_aff_domain_dim(aff, isl_dim_all); + if (total < 0) + return isl_printer_free(p); + p = print_affine_of_len(space, aff->ls->div, p, + aff->v->el + 1, 1 + total); + + return p; +} + +static __isl_give isl_printer *print_aff_num(__isl_take isl_printer *p, + __isl_keep isl_space *space, __isl_keep isl_aff *aff); + +/* Print the modulo term "c" * ("aff" mod "mod") to "p", + * with the variable names taken from "space". + * If "first" is set, then this is the first term of an expression. + */ +static __isl_give isl_printer *print_mod_term(__isl_take isl_printer *p, + __isl_keep isl_space *space, __isl_keep isl_aff *aff, int first, + __isl_take isl_val *c, __isl_keep isl_val *mod) +{ + isl_bool is_one, is_neg; + + is_neg = isl_val_is_neg(c); + if (is_neg < 0) + p = isl_printer_free(p); + if (!first) { + if (is_neg) + c = isl_val_neg(c); + p = isl_printer_print_str(p, is_neg ? " - " : " + "); + } + is_one = isl_val_is_one(c); + if (is_one < 0) + p = isl_printer_free(p); + if (!is_one) { + p = isl_printer_print_val(p, c); + p = isl_printer_print_str(p, "*("); + } + p = isl_printer_print_str(p, "("); + p = print_aff_num(p, space, aff); + p = isl_printer_print_str(p, ")"); + p = isl_printer_print_str(p, " mod "); + p = isl_printer_print_val(p, mod); + if (!is_one) + p = isl_printer_print_str(p, ")"); + + isl_val_free(c); + + return p; +} + +/* Print the numerator of the affine expression "aff" to "p", + * with the variable names taken from "space", + * given that the numerator of "aff" is of the form + * + * f(...) + a m floor(g/m) + * + * with "floor(g/m)" the integer division at position "last". + * + * First replace "aff" by its numerator and rewrite it as + * + * f(...) + a g - a (g mod m) + * + * Recursively write out (the numerator of) "f(...) + a g" + * (which may involve other modulo expressions) and + * then write out "- a (g mod m)". + */ +static __isl_give isl_printer *print_aff_num_mod(__isl_take isl_printer *p, + __isl_keep isl_space *space, __isl_keep isl_aff *aff, unsigned last) +{ + isl_bool is_zero; + isl_val *a, *m; + isl_aff *div, *term; + + aff = isl_aff_copy(aff); + aff = isl_aff_scale_val(aff, isl_aff_get_denominator_val(aff)); + a = isl_aff_get_coefficient_val(aff, isl_dim_div, last); + aff = isl_aff_set_coefficient_si(aff, isl_dim_div, last, 0); + div = isl_aff_get_div(aff, last); + m = isl_aff_get_denominator_val(div); + a = isl_val_div(a, isl_val_copy(m)); + div = isl_aff_scale_val(div, isl_val_copy(m)); + term = isl_aff_scale_val(isl_aff_copy(div), isl_val_copy(a)); + aff = isl_aff_add(aff, term); + + is_zero = isl_aff_plain_is_zero(aff); + if (is_zero < 0) { + p = isl_printer_free(p); + } else { + if (!is_zero) + p = print_aff_num(p, space, aff); + a = isl_val_neg(a); + p = print_mod_term(p, space, div, is_zero, isl_val_copy(a), m); + } + + isl_val_free(a); + isl_val_free(m); + isl_aff_free(aff); + isl_aff_free(div); + + return p; +} + +/* Print the numerator of the affine expression "aff" to "p", + * with the variable names taken from "space", + * separating out any (obvious) modulo expressions. + * + * In particular, look for modulo expressions in "aff", + * separating them out if found and simply printing out "aff" otherwise. + */ +static __isl_give isl_printer *print_aff_num(__isl_take isl_printer *p, + __isl_keep isl_space *space, __isl_keep isl_aff *aff) +{ + isl_size n_div, mod; + + n_div = isl_aff_dim(aff, isl_dim_div); + if (n_div < 0) + return isl_printer_free(p); + mod = last_modulo(p, aff, n_div); + if (mod < 0) + return isl_printer_free(p); + if (mod < n_div) + return print_aff_num_mod(p, space, aff, mod); + else + return print_aff_num_base(p, space, aff); +} + +/* Print the (potentially rational) affine expression "aff" to "p", + * with the variable names taken from "space". + */ +static __isl_give isl_printer *print_aff_body(__isl_take isl_printer *p, + __isl_keep isl_space *space, __isl_keep isl_aff *aff) +{ + if (isl_aff_is_nan(aff)) + return isl_printer_print_str(p, "NaN"); + + p = isl_printer_print_str(p, "("); + p = print_aff_num(p, space, aff); + if (isl_int_is_one(aff->v->el[0])) + p = isl_printer_print_str(p, ")"); + else { + p = isl_printer_print_str(p, ")/"); + p = isl_printer_print_isl_int(p, aff->v->el[0]); + } + + return p; +} + +static __isl_give isl_printer *print_body_aff(__isl_take isl_printer *p, + __isl_keep isl_aff *aff) +{ + struct isl_print_space_data data = { 0 }; + + if (isl_space_is_params(aff->ls->dim)) + ; + else { + p = print_tuple(aff->ls->dim, p, isl_dim_set, &data); + p = isl_printer_print_str(p, " -> "); + } + p = isl_printer_print_str(p, "["); + p = print_aff_body(p, aff->ls->dim, aff); + p = isl_printer_print_str(p, "]"); + + return p; +} + +static __isl_give isl_printer *print_aff_isl(__isl_take isl_printer *p, + __isl_keep isl_aff *aff) +{ + struct isl_print_space_data data = { 0 }; + + if (!aff) + goto error; + + p = print_param_tuple(p, aff->ls->dim, &data); + p = isl_printer_print_str(p, "{ "); + p = print_body_aff(p, aff); + p = isl_printer_print_str(p, " }"); + return p; +error: + isl_printer_free(p); + return NULL; +} + +#undef BASE +#define BASE aff +#include "isl_pw_print_templ.c" + +static __isl_give isl_printer *print_ls_name_c(__isl_take isl_printer *p, + __isl_keep isl_local_space *ls, enum isl_dim_type type, unsigned pos) +{ + if (type == isl_dim_div) { + p = isl_printer_print_str(p, "floord("); + p = print_ls_affine_c(p, ls, ls->div->row[pos] + 1); + p = isl_printer_print_str(p, ", "); + p = isl_printer_print_isl_int(p, ls->div->row[pos][0]); + p = isl_printer_print_str(p, ")"); + } else { + const char *name; + + name = isl_space_get_dim_name(ls->dim, type, pos); + if (!name) + name = "UNNAMED"; + p = isl_printer_print_str(p, name); + } + return p; +} + +static __isl_give isl_printer *print_ls_term_c(__isl_take isl_printer *p, + __isl_keep isl_local_space *ls, isl_int c, unsigned pos) +{ + enum isl_dim_type type; + + if (!p || !ls) + return isl_printer_free(p); + + if (pos == 0) + return isl_printer_print_isl_int(p, c); + + if (isl_int_is_one(c)) + ; + else if (isl_int_is_negone(c)) + p = isl_printer_print_str(p, "-"); + else { + p = isl_printer_print_isl_int(p, c); + p = isl_printer_print_str(p, "*"); + } + if (pos2type(ls->dim, &type, &pos) < 0) + return isl_printer_free(p); + p = print_ls_name_c(p, ls, type, pos); + return p; +} + +static __isl_give isl_printer *print_ls_partial_affine_c( + __isl_take isl_printer *p, __isl_keep isl_local_space *ls, + isl_int *c, unsigned len) +{ + int i; + int first; + + for (i = 0, first = 1; i < len; ++i) { + int flip = 0; + if (isl_int_is_zero(c[i])) + continue; + if (!first) { + if (isl_int_is_neg(c[i])) { + flip = 1; + isl_int_neg(c[i], c[i]); + p = isl_printer_print_str(p, " - "); + } else + p = isl_printer_print_str(p, " + "); + } + first = 0; + p = print_ls_term_c(p, ls, c[i], i); + if (flip) + isl_int_neg(c[i], c[i]); + } + if (first) + p = isl_printer_print_str(p, "0"); + return p; +} + +static __isl_give isl_printer *print_ls_affine_c(__isl_take isl_printer *p, + __isl_keep isl_local_space *ls, isl_int *c) +{ + isl_size total = isl_local_space_dim(ls, isl_dim_all); + + if (total < 0) + return isl_printer_free(p); + return print_ls_partial_affine_c(p, ls, c, 1 + total); +} + +static __isl_give isl_printer *print_aff_c(__isl_take isl_printer *p, + __isl_keep isl_aff *aff) +{ + isl_size total; + + total = isl_aff_domain_dim(aff, isl_dim_all); + if (total < 0) + return isl_printer_free(p); + if (!isl_int_is_one(aff->v->el[0])) + p = isl_printer_print_str(p, "("); + p = print_ls_partial_affine_c(p, aff->ls, aff->v->el + 1, 1 + total); + if (!isl_int_is_one(aff->v->el[0])) { + p = isl_printer_print_str(p, ")/"); + p = isl_printer_print_isl_int(p, aff->v->el[0]); + } + return p; +} + +/* In the C format, we cannot express that "pwaff" may be undefined + * on parts of the domain space. We therefore assume that the expression + * will only be evaluated on its definition domain and compute the gist + * of each cell with respect to this domain. + */ +static __isl_give isl_printer *print_pw_aff_c(__isl_take isl_printer *p, + __isl_keep isl_pw_aff *pwaff) +{ + isl_set *domain; + isl_ast_build *build; + isl_ast_expr *expr; + + if (pwaff->n < 1) + isl_die(p->ctx, isl_error_unsupported, + "cannot print empty isl_pw_aff in C format", + return isl_printer_free(p)); + + domain = isl_pw_aff_domain(isl_pw_aff_copy(pwaff)); + build = isl_ast_build_from_context(domain); + expr = isl_ast_build_expr_from_pw_aff(build, isl_pw_aff_copy(pwaff)); + p = isl_printer_print_ast_expr(p, expr); + isl_ast_expr_free(expr); + isl_ast_build_free(build); + + return p; +} + +__isl_give isl_printer *isl_printer_print_aff(__isl_take isl_printer *p, + __isl_keep isl_aff *aff) +{ + if (!p || !aff) + goto error; + + if (p->output_format == ISL_FORMAT_ISL) + return print_aff_isl(p, aff); + else if (p->output_format == ISL_FORMAT_C) + return print_aff_c(p, aff); + isl_die(p->ctx, isl_error_unsupported, "unsupported output format", + goto error); +error: + isl_printer_free(p); + return NULL; +} + +__isl_give isl_printer *isl_printer_print_pw_aff(__isl_take isl_printer *p, + __isl_keep isl_pw_aff *pwaff) +{ + if (!p || !pwaff) + goto error; + + if (p->output_format == ISL_FORMAT_ISL) + return print_pw_aff_isl(p, pwaff); + else if (p->output_format == ISL_FORMAT_C) + return print_pw_aff_c(p, pwaff); + isl_die(p->ctx, isl_error_unsupported, "unsupported output format", + goto error); +error: + isl_printer_free(p); + return NULL; +} + +#undef BASE +#define BASE pw_aff +#include "isl_union_print_templ.c" + +/* Print the isl_union_pw_aff "upa" to "p". + * + * We currently only support an isl format. + */ +__isl_give isl_printer *isl_printer_print_union_pw_aff( + __isl_take isl_printer *p, __isl_keep isl_union_pw_aff *upa) +{ + if (!p || !upa) + return isl_printer_free(p); + + if (p->output_format == ISL_FORMAT_ISL) + return print_union_pw_aff_isl(p, upa); + isl_die(isl_printer_get_ctx(p), isl_error_unsupported, + "unsupported output format", return isl_printer_free(p)); +} + +/* Print dimension "pos" of data->space to "p". + * + * data->user is assumed to be an isl_multi_aff. + * + * If the current dimension is an output dimension, then print + * the corresponding expression. Otherwise, print the name of the dimension. + * Make sure to use the domain space for printing names as + * that is the space that will be used for printing constraints (if any). + */ +static __isl_give isl_printer *print_dim_ma(__isl_take isl_printer *p, + struct isl_print_space_data *data, unsigned pos) +{ + isl_multi_aff *ma = data->user; + isl_space *space; + + space = isl_multi_aff_get_domain_space(ma); + if (data->type == isl_dim_out) { + p = print_aff_body(p, space, ma->u.p[pos]); + } else { + enum isl_dim_type type = data->type; + + if (type == isl_dim_in) + type = isl_dim_set; + p = print_name(space, p, type, pos, data->latex); + } + isl_space_free(space); + + return p; +} + +static __isl_give isl_printer *print_body_multi_aff(__isl_take isl_printer *p, + __isl_keep isl_multi_aff *maff) +{ + struct isl_print_space_data data = { 0 }; + + data.print_dim = &print_dim_ma; + data.user = maff; + return isl_print_space(maff->space, p, 0, &data); +} + +static __isl_give isl_printer *print_multi_aff_isl(__isl_take isl_printer *p, + __isl_keep isl_multi_aff *maff) +{ + struct isl_print_space_data data = { 0 }; + + if (!maff) + goto error; + + p = print_param_tuple(p, maff->space, &data); + p = isl_printer_print_str(p, "{ "); + p = print_body_multi_aff(p, maff); + p = isl_printer_print_str(p, " }"); + return p; +error: + isl_printer_free(p); + return NULL; +} + +__isl_give isl_printer *isl_printer_print_multi_aff(__isl_take isl_printer *p, + __isl_keep isl_multi_aff *maff) +{ + if (!p || !maff) + goto error; + + if (p->output_format == ISL_FORMAT_ISL) + return print_multi_aff_isl(p, maff); + isl_die(p->ctx, isl_error_unsupported, "unsupported output format", + goto error); +error: + isl_printer_free(p); + return NULL; +} + +#undef BASE +#define BASE multi_aff +#include "isl_pw_print_templ.c" + +/* Print the unnamed, single-dimensional piecewise multi affine expression "pma" + * to "p". + */ +static __isl_give isl_printer *print_unnamed_pw_multi_aff_c( + __isl_take isl_printer *p, __isl_keep isl_pw_multi_aff *pma) +{ + int i; + isl_space *space; + + space = isl_pw_multi_aff_get_domain_space(pma); + for (i = 0; i < pma->n - 1; ++i) { + p = isl_printer_print_str(p, "("); + p = print_set_c(p, space, pma->p[i].set); + p = isl_printer_print_str(p, ") ? ("); + p = print_aff_c(p, pma->p[i].maff->u.p[0]); + p = isl_printer_print_str(p, ") : "); + } + isl_space_free(space); + + return print_aff_c(p, pma->p[pma->n - 1].maff->u.p[0]); +} + +static __isl_give isl_printer *print_pw_multi_aff_c(__isl_take isl_printer *p, + __isl_keep isl_pw_multi_aff *pma) +{ + isl_size n; + const char *name; + + if (!pma) + goto error; + if (pma->n < 1) + isl_die(p->ctx, isl_error_unsupported, + "cannot print empty isl_pw_multi_aff in C format", + goto error); + n = isl_pw_multi_aff_dim(pma, isl_dim_out); + if (n < 0) + return isl_printer_free(p); + name = isl_pw_multi_aff_get_tuple_name(pma, isl_dim_out); + if (!name && n == 1) + return print_unnamed_pw_multi_aff_c(p, pma); + if (!name) + isl_die(p->ctx, isl_error_unsupported, + "cannot print unnamed isl_pw_multi_aff in C format", + goto error); + + p = isl_printer_print_str(p, name); + if (n != 0) + isl_die(p->ctx, isl_error_unsupported, + "not supported yet", goto error); + + return p; +error: + isl_printer_free(p); + return NULL; +} + +__isl_give isl_printer *isl_printer_print_pw_multi_aff( + __isl_take isl_printer *p, __isl_keep isl_pw_multi_aff *pma) +{ + if (!p || !pma) + goto error; + + if (p->output_format == ISL_FORMAT_ISL) + return print_pw_multi_aff_isl(p, pma); + if (p->output_format == ISL_FORMAT_C) + return print_pw_multi_aff_c(p, pma); + isl_die(p->ctx, isl_error_unsupported, "unsupported output format", + goto error); +error: + isl_printer_free(p); + return NULL; +} + +#undef BASE +#define BASE pw_multi_aff +#include "isl_union_print_templ.c" + +__isl_give isl_printer *isl_printer_print_union_pw_multi_aff( + __isl_take isl_printer *p, __isl_keep isl_union_pw_multi_aff *upma) +{ + if (!p || !upma) + goto error; + + if (p->output_format == ISL_FORMAT_ISL) + return print_union_pw_multi_aff_isl(p, upma); + isl_die(p->ctx, isl_error_unsupported, "unsupported output format", + goto error); +error: + isl_printer_free(p); + return NULL; +} + +/* Print dimension "pos" of data->space to "p". + * + * data->user is assumed to be an isl_multi_pw_aff. + * + * If the current dimension is an output dimension, then print + * the corresponding piecewise affine expression. + * Otherwise, print the name of the dimension. + * Make sure to use the same space in both cases. + * In particular, use the domain space for printing names as + * that is the space that is used for printing constraints. + */ +static __isl_give isl_printer *print_dim_mpa(__isl_take isl_printer *p, + struct isl_print_space_data *data, unsigned pos) +{ + int i; + int need_parens; + isl_space *space; + isl_multi_pw_aff *mpa = data->user; + isl_pw_aff *pa; + + if (data->type != isl_dim_out) { + enum isl_dim_type type = data->type; + + if (type == isl_dim_in) + type = isl_dim_set; + space = isl_multi_pw_aff_get_domain_space(mpa); + p = print_name(space, p, type, pos, data->latex); + isl_space_free(space); + return p; + } + + pa = mpa->u.p[pos]; + if (pa->n == 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) + p = isl_printer_print_str(p, "("); + space = isl_multi_pw_aff_get_domain_space(mpa); + for (i = 0; i < pa->n; ++i) { + + if (i) + p = isl_printer_print_str(p, "; "); + p = print_aff_body(p, space, pa->p[i].aff); + p = print_disjuncts(pa->p[i].set, space, p, 0); + } + isl_space_free(space); + if (need_parens) + p = isl_printer_print_str(p, ")"); + + return p; +} + +/* Print "mpa" to "p" in isl format. + * + * If "mpa" is zero-dimensional and has a non-trivial explicit domain, + * then it is printed after the tuple of affine expressions. + */ +static __isl_give isl_printer *print_multi_pw_aff_isl(__isl_take isl_printer *p, + __isl_keep isl_multi_pw_aff *mpa) +{ + struct isl_print_space_data data = { 0 }; + isl_bool has_domain; + + if (!mpa) + return isl_printer_free(p); + + p = print_param_tuple(p, mpa->space, &data); + p = isl_printer_print_str(p, "{ "); + data.print_dim = &print_dim_mpa; + data.user = mpa; + p = isl_print_space(mpa->space, p, 0, &data); + has_domain = isl_multi_pw_aff_has_non_trivial_domain(mpa); + if (has_domain < 0) + return isl_printer_free(p); + if (has_domain) { + isl_space *space; + + space = isl_space_domain(isl_space_copy(mpa->space)); + p = print_disjuncts_set(mpa->u.dom, space, p, 0); + isl_space_free(space); + } + p = isl_printer_print_str(p, " }"); + return p; +} + +__isl_give isl_printer *isl_printer_print_multi_pw_aff( + __isl_take isl_printer *p, __isl_keep isl_multi_pw_aff *mpa) +{ + if (!p || !mpa) + return isl_printer_free(p); + + if (p->output_format == ISL_FORMAT_ISL) + return print_multi_pw_aff_isl(p, mpa); + isl_die(p->ctx, isl_error_unsupported, "unsupported output format", + return isl_printer_free(p)); +} + +/* Print dimension "pos" of data->space to "p". + * + * data->user is assumed to be an isl_multi_val. + * + * If the current dimension is an output dimension, then print + * the corresponding value. Otherwise, print the name of the dimension. + */ +static __isl_give isl_printer *print_dim_mv(__isl_take isl_printer *p, + struct isl_print_space_data *data, unsigned pos) +{ + isl_multi_val *mv = data->user; + + if (data->type == isl_dim_out) + return isl_printer_print_val(p, mv->u.p[pos]); + else + return print_name(data->space, p, data->type, pos, data->latex); +} + +/* Print the isl_multi_val "mv" to "p" in isl format. + */ +static __isl_give isl_printer *print_multi_val_isl(__isl_take isl_printer *p, + __isl_keep isl_multi_val *mv) +{ + struct isl_print_space_data data = { 0 }; + + if (!mv) + return isl_printer_free(p); + + p = print_param_tuple(p, mv->space, &data); + p = isl_printer_print_str(p, "{ "); + data.print_dim = &print_dim_mv; + data.user = mv; + p = isl_print_space(mv->space, p, 0, &data); + p = isl_printer_print_str(p, " }"); + return p; +} + +/* Print the isl_multi_val "mv" to "p". + * + * Currently only supported in isl format. + */ +__isl_give isl_printer *isl_printer_print_multi_val( + __isl_take isl_printer *p, __isl_keep isl_multi_val *mv) +{ + if (!p || !mv) + return isl_printer_free(p); + + if (p->output_format == ISL_FORMAT_ISL) + return print_multi_val_isl(p, mv); + isl_die(p->ctx, isl_error_unsupported, "unsupported output format", + return isl_printer_free(p)); +} + +/* Print dimension "pos" of data->space to "p". + * + * data->user is assumed to be an isl_multi_id. + * + * If the current dimension is an output dimension, then print + * the corresponding identifier. Otherwise, print the name of the dimension. + */ +static __isl_give isl_printer *print_dim_mi(__isl_take isl_printer *p, + struct isl_print_space_data *data, unsigned pos) +{ + isl_multi_id *mi = data->user; + + if (data->type == isl_dim_out) + return isl_printer_print_id(p, mi->u.p[pos]); + else + return print_name(data->space, p, data->type, pos, data->latex); +} + +/* Print the isl_multi_id "mi" to "p" in isl format. + */ +static __isl_give isl_printer *print_multi_id_isl(__isl_take isl_printer *p, + __isl_keep isl_multi_id *mi) +{ + isl_space *space; + struct isl_print_space_data data = { 0 }; + + space = isl_multi_id_peek_space(mi); + p = print_param_tuple(p, space, &data); + p = isl_printer_print_str(p, "{ "); + data.print_dim = &print_dim_mi; + data.user = mi; + p = isl_print_space(space, p, 0, &data); + p = isl_printer_print_str(p, " }"); + return p; +} + +/* Print the isl_multi_id "mi" to "p". + * + * Currently only supported in isl format. + */ +__isl_give isl_printer *isl_printer_print_multi_id( + __isl_take isl_printer *p, __isl_keep isl_multi_id *mi) +{ + if (!p || !mi) + return isl_printer_free(p); + + if (p->output_format == ISL_FORMAT_ISL) + return print_multi_id_isl(p, mi); + isl_die(isl_printer_get_ctx(p), isl_error_unsupported, + "unsupported output format", return isl_printer_free(p)); +} + +/* Print dimension "pos" of data->space to "p". + * + * data->user is assumed to be an isl_multi_union_pw_aff. + * + * The current dimension is necessarily a set dimension, so + * we print the corresponding isl_union_pw_aff, including + * the braces. + */ +static __isl_give isl_printer *print_union_pw_aff_dim(__isl_take isl_printer *p, + struct isl_print_space_data *data, unsigned pos) +{ + isl_multi_union_pw_aff *mupa = data->user; + isl_union_pw_aff *upa; + + upa = isl_multi_union_pw_aff_get_union_pw_aff(mupa, pos); + p = print_body_union_pw_aff(p, upa); + isl_union_pw_aff_free(upa); + + return p; +} + +/* Print the isl_multi_union_pw_aff "mupa" to "p" in isl format. + * + * If "mupa" is zero-dimensional and has a non-trivial explicit domain, + * then it is printed after the tuple of affine expressions. + * In order to clarify that this domain belongs to the expression, + * the tuple along with the domain are placed inside parentheses. + * If "mupa" has any parameters, then the opening parenthesis + * appears after the parameter declarations. + */ +static __isl_give isl_printer *print_multi_union_pw_aff_isl( + __isl_take isl_printer *p, __isl_keep isl_multi_union_pw_aff *mupa) +{ + struct isl_print_space_data data = { 0 }; + isl_bool has_domain; + isl_space *space; + + if (!mupa) + return isl_printer_free(p); + has_domain = isl_multi_union_pw_aff_has_non_trivial_domain(mupa); + if (has_domain < 0) + return isl_printer_free(p); + + space = isl_multi_union_pw_aff_get_space(mupa); + p = print_param_tuple(p, space, &data); + + if (has_domain) + p = isl_printer_print_str(p, "("); + + data.print_dim = &print_union_pw_aff_dim; + data.user = mupa; + + p = isl_print_space(space, p, 0, &data); + isl_space_free(space); + + if (has_domain) { + p = isl_printer_print_str(p, " : "); + p = isl_printer_print_union_set_isl_body(p, mupa->u.dom); + p = isl_printer_print_str(p, ")"); + } + + return p; +} + +/* Print the isl_multi_union_pw_aff "mupa" to "p" in isl format. + * + * We currently only support an isl format. + */ +__isl_give isl_printer *isl_printer_print_multi_union_pw_aff( + __isl_take isl_printer *p, __isl_keep isl_multi_union_pw_aff *mupa) +{ + if (!p || !mupa) + return isl_printer_free(p); + + if (p->output_format == ISL_FORMAT_ISL) + return print_multi_union_pw_aff_isl(p, mupa); + isl_die(isl_printer_get_ctx(p), isl_error_unsupported, + "unsupported output format", return isl_printer_free(p)); +} diff --git a/external/mit/isl/dist/isl_output_private.h b/external/mit/isl/dist/isl_output_private.h new file mode 100644 index 000000000000..2e4701dda626 --- /dev/null +++ b/external/mit/isl/dist/isl_output_private.h @@ -0,0 +1,27 @@ +#include +#include + +/* Internal data structure for isl_print_space. + * + * latex is set if that is the output format. + * print_dim (if not NULL) is called on each dimension. + * user is set by the caller of print_space and may be used inside print_dim. + * + * space is the global space that is being printed. This field is set by + * print_space. + * type is the tuple of the global space that is currently being printed. + * This field is set by print_space. + */ +struct isl_print_space_data { + int latex; + __isl_give isl_printer *(*print_dim)(__isl_take isl_printer *p, + struct isl_print_space_data *data, unsigned pos); + void *user; + + isl_space *space; + enum isl_dim_type type; +}; + +__isl_give isl_printer *isl_print_space(__isl_keep isl_space *space, + __isl_take isl_printer *p, int rational, + struct isl_print_space_data *data); diff --git a/external/mit/isl/dist/isl_point.c b/external/mit/isl/dist/isl_point.c new file mode 100644 index 000000000000..4fe7594c0d61 --- /dev/null +++ b/external/mit/isl/dist/isl_point.c @@ -0,0 +1,885 @@ +/* + * Copyright 2010 INRIA Saclay + * Copyright 2013 Ecole Normale Superieure + * Copyright 2015 Sven Verdoolaege + * Copyright 2019,2022 Cerebras Systems + * + * 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 + * and Cerebras Systems, 175 S San Antonio Rd, Los Altos, CA, USA + * and Cerebras Systems, 1237 E Arques Ave, Sunnyvale, CA, USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +isl_ctx *isl_point_get_ctx(__isl_keep isl_point *pnt) +{ + return pnt ? isl_space_get_ctx(pnt->dim) : NULL; +} + +/* Return the space of "pnt". + */ +__isl_keep isl_space *isl_point_peek_space(__isl_keep isl_point *pnt) +{ + return pnt ? pnt->dim : NULL; +} + +__isl_give isl_space *isl_point_get_space(__isl_keep isl_point *pnt) +{ + return isl_space_copy(isl_point_peek_space(pnt)); +} + +#undef TYPE1 +#define TYPE1 isl_basic_map +#undef TYPE2 +#define TYPE2 isl_point +#undef TYPE_PAIR +#define TYPE_PAIR isl_basic_map_point + +static +#include "isl_type_has_equal_space_templ.c" +static +#include "isl_type_check_equal_space_templ.c" + +#undef TYPE +#define TYPE isl_point + +#include "isl_check_named_params_templ.c" + +__isl_give isl_point *isl_point_alloc(__isl_take isl_space *space, + __isl_take isl_vec *vec) +{ + struct isl_point *pnt; + isl_size dim; + + dim = isl_space_dim(space, isl_dim_all); + if (dim < 0 || !vec) + goto error; + + if (vec->size > 1 + dim) { + vec = isl_vec_cow(vec); + if (!vec) + goto error; + vec->size = 1 + dim; + } + + pnt = isl_alloc_type(space->ctx, struct isl_point); + if (!pnt) + goto error; + + pnt->ref = 1; + pnt->dim = space; + pnt->vec = vec; + + return pnt; +error: + isl_space_free(space); + isl_vec_free(vec); + return NULL; +} + +__isl_give isl_point *isl_point_zero(__isl_take isl_space *space) +{ + isl_vec *vec; + isl_size dim; + + dim = isl_space_dim(space, isl_dim_all); + if (dim < 0) + goto error; + vec = isl_vec_alloc(space->ctx, 1 + dim); + if (!vec) + goto error; + isl_int_set_si(vec->el[0], 1); + isl_seq_clr(vec->el + 1, vec->size - 1); + return isl_point_alloc(space, vec); +error: + isl_space_free(space); + return NULL; +} + +__isl_give isl_point *isl_point_dup(__isl_keep isl_point *pnt) +{ + struct isl_point *pnt2; + + if (!pnt) + return NULL; + pnt2 = isl_point_alloc(isl_space_copy(pnt->dim), isl_vec_copy(pnt->vec)); + return pnt2; +} + +__isl_give isl_point *isl_point_cow(__isl_take isl_point *pnt) +{ + struct isl_point *pnt2; + if (!pnt) + return NULL; + + if (pnt->ref == 1) + return pnt; + + pnt2 = isl_point_dup(pnt); + isl_point_free(pnt); + return pnt2; +} + +__isl_give isl_point *isl_point_copy(__isl_keep isl_point *pnt) +{ + if (!pnt) + return NULL; + + pnt->ref++; + return pnt; +} + +__isl_null isl_point *isl_point_free(__isl_take isl_point *pnt) +{ + if (!pnt) + return NULL; + + if (--pnt->ref > 0) + return NULL; + + isl_space_free(pnt->dim); + isl_vec_free(pnt->vec); + free(pnt); + return NULL; +} + +__isl_give isl_point *isl_point_void(__isl_take isl_space *space) +{ + if (!space) + return NULL; + + return isl_point_alloc(space, isl_vec_alloc(space->ctx, 0)); +} + +isl_bool isl_point_is_void(__isl_keep isl_point *pnt) +{ + if (!pnt) + return isl_bool_error; + + return isl_bool_ok(pnt->vec->size == 0); +} + +/* Return the space of "pnt". + * This may be either a copy or the space itself + * if there is only one reference to "pnt". + * This allows the space to be modified inplace + * if both the point and its space have only a single reference. + * The caller is not allowed to modify "pnt" between this call and + * a subsequent call to isl_point_restore_space. + * The only exception is that isl_point_free can be called instead. + */ +__isl_give isl_space *isl_point_take_space(__isl_keep isl_point *pnt) +{ + isl_space *space; + + if (!pnt) + return NULL; + if (pnt->ref != 1) + return isl_point_get_space(pnt); + space = pnt->dim; + pnt->dim = NULL; + return space; +} + +/* Set the space of "pnt" to "space", where the space of "pnt" may be missing + * due to a preceding call to isl_point_take_space. + * However, in this case, "pnt" only has a single reference and + * then the call to isl_point_cow has no effect. + */ +__isl_give isl_point *isl_point_restore_space(__isl_take isl_point *pnt, + __isl_take isl_space *space) +{ + if (!pnt || !space) + goto error; + + if (pnt->dim == space) { + isl_space_free(space); + return pnt; + } + + pnt = isl_point_cow(pnt); + if (!pnt) + goto error; + isl_space_free(pnt->dim); + pnt->dim = space; + + return pnt; +error: + isl_point_free(pnt); + isl_space_free(space); + return NULL; +} + +/* Return the coordinate vector of "pnt". + */ +__isl_keep isl_vec *isl_point_peek_vec(__isl_keep isl_point *pnt) +{ + return pnt ? pnt->vec : NULL; +} + +/* Return a copy of the coordinate vector of "pnt". + */ +__isl_give isl_vec *isl_point_get_vec(__isl_keep isl_point *pnt) +{ + return isl_vec_copy(isl_point_peek_vec(pnt)); +} + +/* Return the coordinate vector of "pnt". + * This may be either a copy or the coordinate vector itself + * if there is only one reference to "pnt". + * This allows the coordinate vector to be modified inplace + * if both the point and its coordinate vector have only a single reference. + * The caller is not allowed to modify "pnt" between this call and + * a subsequent call to isl_point_restore_vec. + * The only exception is that isl_point_free can be called instead. + */ +__isl_give isl_vec *isl_point_take_vec(__isl_keep isl_point *pnt) +{ + isl_vec *vec; + + if (!pnt) + return NULL; + if (pnt->ref != 1) + return isl_point_get_vec(pnt); + vec = pnt->vec; + pnt->vec = NULL; + return vec; +} + +/* Set the coordinate vector of "pnt" to "vec", + * where the coordinate vector of "pnt" may be missing + * due to a preceding call to isl_point_take_vec. + * However, in this case, "pnt" only has a single reference and + * then the call to isl_point_cow has no effect. + */ +__isl_give isl_point *isl_point_restore_vec(__isl_take isl_point *pnt, + __isl_take isl_vec *vec) +{ + if (!pnt || !vec) + goto error; + + if (pnt->vec == vec) { + isl_vec_free(vec); + return pnt; + } + + pnt = isl_point_cow(pnt); + if (!pnt) + goto error; + isl_vec_free(pnt->vec); + pnt->vec = vec; + + return pnt; +error: + isl_point_free(pnt); + isl_vec_free(vec); + return NULL; +} + +/* Return the number of variables of the given type. + */ +static isl_size isl_point_dim(__isl_keep isl_point *pnt, enum isl_dim_type type) +{ + return isl_space_dim(isl_point_peek_space(pnt), type); +} + +/* Return the position of the coordinates of the given type + * within the sequence of coordinates of "pnt". + */ +static isl_size isl_point_var_offset(__isl_keep isl_point *pnt, + enum isl_dim_type type) +{ + return pnt ? isl_space_offset(pnt->dim, type) : isl_size_error; +} + +/* Reorder the coordinates of "pnt" based on the given reordering. + */ +static __isl_give isl_point *isl_point_reorder(__isl_take isl_point *pnt, + __isl_take isl_reordering *r) +{ + isl_vec *vec; + + isl_space_free(isl_point_take_space(pnt)); + pnt = isl_point_restore_space(pnt, isl_reordering_get_space(r)); + + vec = isl_point_take_vec(pnt); + vec = isl_vec_reorder(vec, 1, isl_reordering_copy(r)); + pnt = isl_point_restore_vec(pnt, vec); + + return pnt; +} + +/* Align the parameters of "pnt" along those of "model". + * + * Note that "model" is not allowed to have any parameters + * that do not already appear in "pnt" since "pnt" does not specify + * any value for such parameters. + */ +__isl_give isl_point *isl_point_align_params(__isl_take isl_point *pnt, + __isl_take isl_space *model) +{ + isl_space *space; + isl_bool equal_params; + + space = isl_point_peek_space(pnt); + equal_params = isl_space_has_equal_params(space, model); + if (equal_params < 0) + goto error; + if (!equal_params) { + isl_reordering *r; + + r = isl_parameter_alignment_reordering(space, model); + if (!r) + goto error; + if (r->src_len != r->dst_len) + isl_die(isl_point_get_ctx(pnt), isl_error_invalid, + "no value specified for some parameters", + r = isl_reordering_free(r)); + pnt = isl_point_reorder(pnt, r); + } + + isl_space_free(model); + return pnt; +error: + isl_space_free(model); + isl_point_free(pnt); + return NULL; +} + +#undef TYPE +#define TYPE isl_point +static +#include "check_type_range_templ.c" + +/* 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, + enum isl_dim_type type, int pos) +{ + isl_ctx *ctx; + isl_val *v; + isl_size off; + + if (!pnt) + return NULL; + + ctx = isl_point_get_ctx(pnt); + if (isl_point_is_void(pnt)) + isl_die(ctx, isl_error_invalid, + "void point does not have coordinates", return NULL); + if (isl_point_check_range(pnt, type, pos, 1) < 0) + return NULL; + + off = isl_point_var_offset(pnt, type); + if (off < 0) + return NULL; + pos += off; + + v = isl_val_rat_from_isl_int(ctx, pnt->vec->el[1 + pos], + pnt->vec->el[0]); + return isl_val_normalize(v); +} + +/* Set all entries of "mv" to NaN. + */ +static __isl_give isl_multi_val *set_nan(__isl_take isl_multi_val *mv) +{ + int i; + isl_size n; + isl_val *v; + + n = isl_multi_val_size(mv); + if (n < 0) + return isl_multi_val_free(mv); + v = isl_val_nan(isl_multi_val_get_ctx(mv)); + for (i = 0; i < n; ++i) + mv = isl_multi_val_set_at(mv, i, isl_val_copy(v)); + isl_val_free(v); + + return mv; +} + +/* Return the values of the set dimensions of "pnt". + * Return a sequence of NaNs in case of a void point. + */ +__isl_give isl_multi_val *isl_point_get_multi_val(__isl_keep isl_point *pnt) +{ + int i; + isl_bool is_void; + isl_size n; + isl_multi_val *mv; + + is_void = isl_point_is_void(pnt); + if (is_void < 0) + return NULL; + + mv = isl_multi_val_alloc(isl_point_get_space(pnt)); + if (is_void) + return set_nan(mv); + n = isl_multi_val_size(mv); + if (n < 0) + return isl_multi_val_free(mv); + for (i = 0; i < n; ++i) { + isl_val *v; + + v = isl_point_get_coordinate_val(pnt, isl_dim_set, i); + mv = isl_multi_val_set_at(mv, i, v); + } + + return mv; +} + +/* Replace coordinate "pos" of type "type" of "pnt" by "v". + */ +__isl_give isl_point *isl_point_set_coordinate_val(__isl_take isl_point *pnt, + enum isl_dim_type type, int pos, __isl_take isl_val *v) +{ + isl_size off; + + off = isl_space_offset(isl_point_peek_space(pnt), type); + if (off < 0 || !v) + goto error; + if (isl_point_is_void(pnt)) + isl_die(isl_point_get_ctx(pnt), isl_error_invalid, + "void point does not have coordinates", goto error); + if (isl_point_check_range(pnt, type, pos, 1) < 0) + goto error; + if (!isl_val_is_rat(v)) + isl_die(isl_point_get_ctx(pnt), isl_error_invalid, + "expecting rational value", goto error); + + pos += off; + if (isl_int_eq(pnt->vec->el[1 + pos], v->n) && + isl_int_eq(pnt->vec->el[0], v->d)) { + isl_val_free(v); + return pnt; + } + + pnt = isl_point_cow(pnt); + if (!pnt) + goto error; + pnt->vec = isl_vec_cow(pnt->vec); + if (!pnt->vec) + goto error; + + if (isl_int_eq(pnt->vec->el[0], v->d)) { + isl_int_set(pnt->vec->el[1 + pos], v->n); + } else if (isl_int_is_one(v->d)) { + isl_int_mul(pnt->vec->el[1 + pos], pnt->vec->el[0], v->n); + } else { + isl_seq_scale(pnt->vec->el + 1, + pnt->vec->el + 1, v->d, pnt->vec->size - 1); + isl_int_mul(pnt->vec->el[1 + pos], pnt->vec->el[0], v->n); + isl_int_mul(pnt->vec->el[0], pnt->vec->el[0], v->d); + pnt->vec = isl_vec_normalize(pnt->vec); + if (!pnt->vec) + goto error; + } + + isl_val_free(v); + return pnt; +error: + isl_val_free(v); + isl_point_free(pnt); + return NULL; +} + +__isl_give isl_point *isl_point_add_ui(__isl_take isl_point *pnt, + enum isl_dim_type type, int pos, unsigned val) +{ + isl_size off; + + 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; + + off = isl_point_var_offset(pnt, type); + if (off < 0) + goto error; + pos += off; + + isl_int_add_ui(pnt->vec->el[1 + pos], pnt->vec->el[1 + pos], val); + + return pnt; +error: + isl_point_free(pnt); + return NULL; +} + +__isl_give isl_point *isl_point_sub_ui(__isl_take isl_point *pnt, + enum isl_dim_type type, int pos, unsigned val) +{ + isl_size off; + + 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; + + off = isl_point_var_offset(pnt, type); + if (off < 0) + goto error; + pos += off; + + isl_int_sub_ui(pnt->vec->el[1 + pos], pnt->vec->el[1 + pos], val); + + return pnt; +error: + isl_point_free(pnt); + return NULL; +} + +struct isl_foreach_point { + struct isl_scan_callback callback; + isl_stat (*fn)(__isl_take isl_point *pnt, void *user); + void *user; + isl_space *dim; +}; + +static isl_stat foreach_point(struct isl_scan_callback *cb, + __isl_take isl_vec *sample) +{ + struct isl_foreach_point *fp = (struct isl_foreach_point *)cb; + isl_point *pnt; + + pnt = isl_point_alloc(isl_space_copy(fp->dim), sample); + + return fp->fn(pnt, fp->user); +} + +isl_stat isl_set_foreach_point(__isl_keep isl_set *set, + isl_stat (*fn)(__isl_take isl_point *pnt, void *user), void *user) +{ + struct isl_foreach_point fp = { { &foreach_point }, fn, user }; + int i; + + if (!set) + return isl_stat_error; + + fp.dim = isl_set_get_space(set); + if (!fp.dim) + return isl_stat_error; + + set = isl_set_copy(set); + set = isl_set_cow(set); + set = isl_set_make_disjoint(set); + set = isl_set_compute_divs(set); + if (!set) + goto error; + + for (i = 0; i < set->n; ++i) + if (isl_basic_set_scan(isl_basic_set_copy(set->p[i]), + &fp.callback) < 0) + goto error; + + isl_set_free(set); + isl_space_free(fp.dim); + + return isl_stat_ok; +error: + isl_set_free(set); + isl_space_free(fp.dim); + return isl_stat_error; +} + +/* Return 1 if "bmap" contains the point "point". + * "bmap" is assumed to have known divs. + * The point is first extended with the divs and then passed + * to basic_map_contains. + */ +isl_bool isl_basic_map_contains_point(__isl_keep isl_basic_map *bmap, + __isl_keep isl_point *point) +{ + isl_local *local; + isl_vec *vec; + isl_bool contains; + + if (isl_basic_map_point_check_equal_space(bmap, point) < 0) + return isl_bool_error; + if (bmap->n_div == 0) + return isl_basic_map_contains(bmap, point->vec); + + local = isl_local_alloc_from_mat(isl_basic_map_get_divs(bmap)); + vec = isl_point_get_vec(point); + vec = isl_local_extend_point_vec(local, vec); + isl_local_free(local); + + contains = isl_basic_map_contains(bmap, vec); + + isl_vec_free(vec); + return contains; +} + +isl_bool isl_map_contains_point(__isl_keep isl_map *map, + __isl_keep isl_point *point) +{ + int i; + isl_bool found = isl_bool_false; + + if (!map || !point) + return isl_bool_error; + + map = isl_map_copy(map); + map = isl_map_compute_divs(map); + if (!map) + return isl_bool_error; + + for (i = 0; i < map->n; ++i) { + found = isl_basic_map_contains_point(map->p[i], point); + if (found < 0) + goto error; + if (found) + break; + } + isl_map_free(map); + + return found; +error: + isl_map_free(map); + return isl_bool_error; +} + +isl_bool isl_set_contains_point(__isl_keep isl_set *set, + __isl_keep isl_point *point) +{ + return isl_map_contains_point(set_to_map(set), point); +} + +__isl_give isl_basic_set *isl_basic_set_from_point(__isl_take isl_point *pnt) +{ + isl_basic_set *bset; + isl_basic_set *model; + + if (!pnt) + return NULL; + + model = isl_basic_set_empty(isl_space_copy(pnt->dim)); + bset = isl_basic_set_from_vec(isl_vec_copy(pnt->vec)); + bset = isl_basic_set_from_underlying_set(bset, model); + isl_point_free(pnt); + + return bset; +} + +__isl_give isl_set *isl_set_from_point(__isl_take isl_point *pnt) +{ + isl_basic_set *bset; + bset = isl_basic_set_from_point(pnt); + return isl_set_from_basic_set(bset); +} + +/* This function performs the same operation as isl_set_from_point, + * but is considered as a function on an isl_point when exported. + */ +__isl_give isl_set *isl_point_to_set(__isl_take isl_point *pnt) +{ + return isl_set_from_point(pnt); +} + +/* Construct a union set, containing the single element "pnt". + * If "pnt" is void, then return an empty union set. + */ +__isl_give isl_union_set *isl_union_set_from_point(__isl_take isl_point *pnt) +{ + if (!pnt) + return NULL; + if (isl_point_is_void(pnt)) { + isl_space *space; + + space = isl_point_get_space(pnt); + isl_point_free(pnt); + return isl_union_set_empty(space); + } + + return isl_union_set_from_set(isl_set_from_point(pnt)); +} + +__isl_give isl_basic_set *isl_basic_set_box_from_points( + __isl_take isl_point *pnt1, __isl_take isl_point *pnt2) +{ + isl_basic_set *bset = NULL; + isl_size total; + int i; + int k; + isl_int t; + + isl_int_init(t); + + if (!pnt1 || !pnt2) + goto error; + + isl_assert(pnt1->dim->ctx, + isl_space_is_equal(pnt1->dim, pnt2->dim), goto error); + + if (isl_point_is_void(pnt1) && isl_point_is_void(pnt2)) { + isl_space *space = isl_space_copy(pnt1->dim); + isl_point_free(pnt1); + isl_point_free(pnt2); + isl_int_clear(t); + return isl_basic_set_empty(space); + } + if (isl_point_is_void(pnt1)) { + isl_point_free(pnt1); + isl_int_clear(t); + return isl_basic_set_from_point(pnt2); + } + if (isl_point_is_void(pnt2)) { + isl_point_free(pnt2); + isl_int_clear(t); + return isl_basic_set_from_point(pnt1); + } + + total = isl_point_dim(pnt1, isl_dim_all); + if (total < 0) + goto error; + bset = isl_basic_set_alloc_space(isl_space_copy(pnt1->dim), 0, 0, 2 * total); + + for (i = 0; i < total; ++i) { + isl_int_mul(t, pnt1->vec->el[1 + i], pnt2->vec->el[0]); + isl_int_submul(t, pnt2->vec->el[1 + i], pnt1->vec->el[0]); + + k = isl_basic_set_alloc_inequality(bset); + if (k < 0) + goto error; + isl_seq_clr(bset->ineq[k] + 1, total); + if (isl_int_is_pos(t)) { + isl_int_set_si(bset->ineq[k][1 + i], -1); + isl_int_set(bset->ineq[k][0], pnt1->vec->el[1 + i]); + } else { + isl_int_set_si(bset->ineq[k][1 + i], 1); + isl_int_neg(bset->ineq[k][0], pnt1->vec->el[1 + i]); + } + isl_int_fdiv_q(bset->ineq[k][0], bset->ineq[k][0], pnt1->vec->el[0]); + + k = isl_basic_set_alloc_inequality(bset); + if (k < 0) + goto error; + isl_seq_clr(bset->ineq[k] + 1, total); + if (isl_int_is_pos(t)) { + isl_int_set_si(bset->ineq[k][1 + i], 1); + isl_int_neg(bset->ineq[k][0], pnt2->vec->el[1 + i]); + } else { + isl_int_set_si(bset->ineq[k][1 + i], -1); + isl_int_set(bset->ineq[k][0], pnt2->vec->el[1 + i]); + } + isl_int_fdiv_q(bset->ineq[k][0], bset->ineq[k][0], pnt2->vec->el[0]); + } + + bset = isl_basic_set_finalize(bset); + + isl_point_free(pnt1); + isl_point_free(pnt2); + + isl_int_clear(t); + + return bset; +error: + isl_point_free(pnt1); + isl_point_free(pnt2); + isl_int_clear(t); + isl_basic_set_free(bset); + return NULL; +} + +__isl_give isl_set *isl_set_box_from_points(__isl_take isl_point *pnt1, + __isl_take isl_point *pnt2) +{ + isl_basic_set *bset; + bset = isl_basic_set_box_from_points(pnt1, pnt2); + return isl_set_from_basic_set(bset); +} + +/* Print the coordinate at position "pos" of the point "pnt". + */ +static __isl_give isl_printer *print_coordinate(__isl_take isl_printer *p, + struct isl_print_space_data *data, unsigned pos) +{ + isl_point *pnt = data->user; + isl_size off; + + off = isl_space_offset(data->space, data->type); + if (off < 0) + return isl_printer_free(p); + pos += off; + p = isl_printer_print_isl_int(p, pnt->vec->el[1 + pos]); + if (!isl_int_is_one(pnt->vec->el[0])) { + p = isl_printer_print_str(p, "/"); + p = isl_printer_print_isl_int(p, pnt->vec->el[0]); + } + + return p; +} + +__isl_give isl_printer *isl_printer_print_point( + __isl_take isl_printer *p, __isl_keep isl_point *pnt) +{ + struct isl_print_space_data data = { 0 }; + int i; + isl_size nparam; + + if (!pnt) + return p; + if (isl_point_is_void(pnt)) { + p = isl_printer_print_str(p, "void"); + return p; + } + + nparam = isl_point_dim(pnt, isl_dim_param); + if (nparam < 0) + return isl_printer_free(p); + if (nparam > 0) { + p = isl_printer_print_str(p, "["); + for (i = 0; i < nparam; ++i) { + const char *name; + if (i) + p = isl_printer_print_str(p, ", "); + name = isl_space_get_dim_name(pnt->dim, isl_dim_param, i); + if (name) { + p = isl_printer_print_str(p, name); + p = isl_printer_print_str(p, " = "); + } + p = isl_printer_print_isl_int(p, pnt->vec->el[1 + i]); + if (!isl_int_is_one(pnt->vec->el[0])) { + p = isl_printer_print_str(p, "/"); + p = isl_printer_print_isl_int(p, pnt->vec->el[0]); + } + } + p = isl_printer_print_str(p, "]"); + p = isl_printer_print_str(p, " -> "); + } + data.print_dim = &print_coordinate; + data.user = pnt; + p = isl_printer_print_str(p, "{ "); + p = isl_print_space(pnt->dim, p, 0, &data); + p = isl_printer_print_str(p, " }"); + return p; +} diff --git a/external/mit/isl/dist/isl_point_private.h b/external/mit/isl/dist/isl_point_private.h new file mode 100644 index 000000000000..f8f9d835ed9f --- /dev/null +++ b/external/mit/isl/dist/isl_point_private.h @@ -0,0 +1,31 @@ +#ifndef ISL_POINT_PRIVATE_H +#define ISL_POINT_PRIVATE_H + +#include +#include +#include + +struct isl_point { + int ref; + isl_space *dim; + struct isl_vec *vec; +}; + +__isl_give isl_point *isl_point_alloc(__isl_take isl_space *space, + __isl_take isl_vec *vec); + +__isl_keep isl_space *isl_point_peek_space(__isl_keep isl_point *pnt); +__isl_give isl_space *isl_point_take_space(__isl_keep isl_point *pnt); +__isl_give isl_point *isl_point_restore_space(__isl_take isl_point *pnt, + __isl_take isl_space *space); +__isl_keep isl_vec *isl_point_peek_vec(__isl_keep isl_point *pnt); +__isl_give isl_vec *isl_point_get_vec(__isl_keep isl_point *pnt); +__isl_give isl_vec *isl_point_take_vec(__isl_keep isl_point *pnt); +__isl_give isl_point *isl_point_restore_vec(__isl_take isl_point *pnt, + __isl_take isl_vec *vec); + +isl_stat isl_point_check_named_params(__isl_keep isl_point *pnt); +__isl_give isl_point *isl_point_align_params(__isl_take isl_point *pnt, + __isl_take isl_space *model); + +#endif diff --git a/external/mit/isl/dist/isl_polynomial.c b/external/mit/isl/dist/isl_polynomial.c new file mode 100644 index 000000000000..300f6bc785e1 --- /dev/null +++ b/external/mit/isl/dist/isl_polynomial.c @@ -0,0 +1,5417 @@ +/* + * Copyright 2010 INRIA Saclay + * + * 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 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#undef EL_BASE +#define EL_BASE qpolynomial + +#include + +#undef EL_BASE +#define EL_BASE pw_qpolynomial + +#include + +static unsigned pos(__isl_keep isl_space *space, enum isl_dim_type type) +{ + switch (type) { + case isl_dim_param: return 0; + case isl_dim_in: return space->nparam; + case isl_dim_out: return space->nparam + space->n_in; + default: return 0; + } +} + +isl_bool isl_poly_is_cst(__isl_keep isl_poly *poly) +{ + if (!poly) + return isl_bool_error; + + return isl_bool_ok(poly->var < 0); +} + +__isl_keep isl_poly_cst *isl_poly_as_cst(__isl_keep isl_poly *poly) +{ + if (!poly) + return NULL; + + isl_assert(poly->ctx, poly->var < 0, return NULL); + + return (isl_poly_cst *) poly; +} + +__isl_keep isl_poly_rec *isl_poly_as_rec(__isl_keep isl_poly *poly) +{ + if (!poly) + return NULL; + + isl_assert(poly->ctx, poly->var >= 0, return NULL); + + return (isl_poly_rec *) poly; +} + +/* Compare two polynomials. + * + * Return -1 if "poly1" is "smaller" than "poly2", 1 if "poly1" is "greater" + * than "poly2" and 0 if they are equal. + */ +static int isl_poly_plain_cmp(__isl_keep isl_poly *poly1, + __isl_keep isl_poly *poly2) +{ + int i; + isl_bool is_cst1; + isl_poly_rec *rec1, *rec2; + + if (poly1 == poly2) + return 0; + is_cst1 = isl_poly_is_cst(poly1); + if (is_cst1 < 0) + return -1; + if (!poly2) + return 1; + if (poly1->var != poly2->var) + return poly1->var - poly2->var; + + if (is_cst1) { + isl_poly_cst *cst1, *cst2; + int cmp; + + cst1 = isl_poly_as_cst(poly1); + cst2 = isl_poly_as_cst(poly2); + if (!cst1 || !cst2) + return 0; + cmp = isl_int_cmp(cst1->n, cst2->n); + if (cmp != 0) + return cmp; + return isl_int_cmp(cst1->d, cst2->d); + } + + rec1 = isl_poly_as_rec(poly1); + rec2 = isl_poly_as_rec(poly2); + if (!rec1 || !rec2) + return 0; + + if (rec1->n != rec2->n) + return rec1->n - rec2->n; + + for (i = 0; i < rec1->n; ++i) { + int cmp = isl_poly_plain_cmp(rec1->p[i], rec2->p[i]); + if (cmp != 0) + return cmp; + } + + return 0; +} + +isl_bool isl_poly_is_equal(__isl_keep isl_poly *poly1, + __isl_keep isl_poly *poly2) +{ + int i; + isl_bool is_cst1; + isl_poly_rec *rec1, *rec2; + + is_cst1 = isl_poly_is_cst(poly1); + if (is_cst1 < 0 || !poly2) + return isl_bool_error; + if (poly1 == poly2) + return isl_bool_true; + if (poly1->var != poly2->var) + return isl_bool_false; + if (is_cst1) { + isl_poly_cst *cst1, *cst2; + int r; + cst1 = isl_poly_as_cst(poly1); + cst2 = isl_poly_as_cst(poly2); + if (!cst1 || !cst2) + return isl_bool_error; + r = isl_int_eq(cst1->n, cst2->n) && + isl_int_eq(cst1->d, cst2->d); + return isl_bool_ok(r); + } + + rec1 = isl_poly_as_rec(poly1); + rec2 = isl_poly_as_rec(poly2); + if (!rec1 || !rec2) + return isl_bool_error; + + if (rec1->n != rec2->n) + return isl_bool_false; + + for (i = 0; i < rec1->n; ++i) { + isl_bool eq = isl_poly_is_equal(rec1->p[i], rec2->p[i]); + if (eq < 0 || !eq) + return eq; + } + + return isl_bool_true; +} + +isl_bool isl_poly_is_zero(__isl_keep isl_poly *poly) +{ + isl_bool is_cst; + isl_poly_cst *cst; + + is_cst = isl_poly_is_cst(poly); + if (is_cst < 0 || !is_cst) + return is_cst; + + cst = isl_poly_as_cst(poly); + if (!cst) + return isl_bool_error; + + return isl_bool_ok(isl_int_is_zero(cst->n) && isl_int_is_pos(cst->d)); +} + +int isl_poly_sgn(__isl_keep isl_poly *poly) +{ + isl_bool is_cst; + isl_poly_cst *cst; + + is_cst = isl_poly_is_cst(poly); + if (is_cst < 0 || !is_cst) + return 0; + + cst = isl_poly_as_cst(poly); + if (!cst) + return 0; + + return isl_int_sgn(cst->n); +} + +isl_bool isl_poly_is_nan(__isl_keep isl_poly *poly) +{ + isl_bool is_cst; + isl_poly_cst *cst; + + is_cst = isl_poly_is_cst(poly); + if (is_cst < 0 || !is_cst) + return is_cst; + + cst = isl_poly_as_cst(poly); + if (!cst) + return isl_bool_error; + + return isl_bool_ok(isl_int_is_zero(cst->n) && isl_int_is_zero(cst->d)); +} + +isl_bool isl_poly_is_infty(__isl_keep isl_poly *poly) +{ + isl_bool is_cst; + isl_poly_cst *cst; + + is_cst = isl_poly_is_cst(poly); + if (is_cst < 0 || !is_cst) + return is_cst; + + cst = isl_poly_as_cst(poly); + if (!cst) + return isl_bool_error; + + return isl_bool_ok(isl_int_is_pos(cst->n) && isl_int_is_zero(cst->d)); +} + +isl_bool isl_poly_is_neginfty(__isl_keep isl_poly *poly) +{ + isl_bool is_cst; + isl_poly_cst *cst; + + is_cst = isl_poly_is_cst(poly); + if (is_cst < 0 || !is_cst) + return is_cst; + + cst = isl_poly_as_cst(poly); + if (!cst) + return isl_bool_error; + + return isl_bool_ok(isl_int_is_neg(cst->n) && isl_int_is_zero(cst->d)); +} + +isl_bool isl_poly_is_one(__isl_keep isl_poly *poly) +{ + isl_bool is_cst; + isl_poly_cst *cst; + int r; + + is_cst = isl_poly_is_cst(poly); + if (is_cst < 0 || !is_cst) + return is_cst; + + cst = isl_poly_as_cst(poly); + if (!cst) + return isl_bool_error; + + r = isl_int_eq(cst->n, cst->d) && isl_int_is_pos(cst->d); + return isl_bool_ok(r); +} + +isl_bool isl_poly_is_negone(__isl_keep isl_poly *poly) +{ + isl_bool is_cst; + isl_poly_cst *cst; + + is_cst = isl_poly_is_cst(poly); + if (is_cst < 0 || !is_cst) + return is_cst; + + cst = isl_poly_as_cst(poly); + if (!cst) + return isl_bool_error; + + return isl_bool_ok(isl_int_is_negone(cst->n) && isl_int_is_one(cst->d)); +} + +__isl_give isl_poly_cst *isl_poly_cst_alloc(isl_ctx *ctx) +{ + isl_poly_cst *cst; + + cst = isl_alloc_type(ctx, struct isl_poly_cst); + if (!cst) + return NULL; + + cst->poly.ref = 1; + cst->poly.ctx = ctx; + isl_ctx_ref(ctx); + cst->poly.var = -1; + + isl_int_init(cst->n); + isl_int_init(cst->d); + + return cst; +} + +__isl_give isl_poly *isl_poly_zero(isl_ctx *ctx) +{ + isl_poly_cst *cst; + + cst = isl_poly_cst_alloc(ctx); + if (!cst) + return NULL; + + isl_int_set_si(cst->n, 0); + isl_int_set_si(cst->d, 1); + + return &cst->poly; +} + +__isl_give isl_poly *isl_poly_one(isl_ctx *ctx) +{ + isl_poly_cst *cst; + + cst = isl_poly_cst_alloc(ctx); + if (!cst) + return NULL; + + isl_int_set_si(cst->n, 1); + isl_int_set_si(cst->d, 1); + + return &cst->poly; +} + +__isl_give isl_poly *isl_poly_infty(isl_ctx *ctx) +{ + isl_poly_cst *cst; + + cst = isl_poly_cst_alloc(ctx); + if (!cst) + return NULL; + + isl_int_set_si(cst->n, 1); + isl_int_set_si(cst->d, 0); + + return &cst->poly; +} + +__isl_give isl_poly *isl_poly_neginfty(isl_ctx *ctx) +{ + isl_poly_cst *cst; + + cst = isl_poly_cst_alloc(ctx); + if (!cst) + return NULL; + + isl_int_set_si(cst->n, -1); + isl_int_set_si(cst->d, 0); + + return &cst->poly; +} + +__isl_give isl_poly *isl_poly_nan(isl_ctx *ctx) +{ + isl_poly_cst *cst; + + cst = isl_poly_cst_alloc(ctx); + if (!cst) + return NULL; + + isl_int_set_si(cst->n, 0); + isl_int_set_si(cst->d, 0); + + return &cst->poly; +} + +__isl_give isl_poly *isl_poly_rat_cst(isl_ctx *ctx, isl_int n, isl_int d) +{ + isl_poly_cst *cst; + + cst = isl_poly_cst_alloc(ctx); + if (!cst) + return NULL; + + isl_int_set(cst->n, n); + isl_int_set(cst->d, d); + + return &cst->poly; +} + +__isl_give isl_poly_rec *isl_poly_alloc_rec(isl_ctx *ctx, int var, int size) +{ + isl_poly_rec *rec; + + isl_assert(ctx, var >= 0, return NULL); + isl_assert(ctx, size >= 0, return NULL); + rec = isl_calloc(ctx, struct isl_poly_rec, + sizeof(struct isl_poly_rec) + + size * sizeof(struct isl_poly *)); + if (!rec) + return NULL; + + rec->poly.ref = 1; + rec->poly.ctx = ctx; + isl_ctx_ref(ctx); + rec->poly.var = var; + + rec->n = 0; + rec->size = size; + + return rec; +} + +/* Return the domain space of "qp". + * This may be either a copy or the space itself + * if there is only one reference to "qp". + * This allows the space to be modified inplace + * if both the quasi-polynomial and its domain space + * have only a single reference. + * The caller is not allowed to modify "qp" between this call and + * a subsequent call to isl_qpolynomial_restore_domain_space. + * The only exception is that isl_qpolynomial_free can be called instead. + */ +static __isl_give isl_space *isl_qpolynomial_take_domain_space( + __isl_keep isl_qpolynomial *qp) +{ + isl_space *space; + + if (!qp) + return NULL; + if (qp->ref != 1) + return isl_qpolynomial_get_domain_space(qp); + space = qp->dim; + qp->dim = NULL; + return space; +} + +/* Set the domain space of "qp" to "space", + * where the domain space of "qp" may be missing + * due to a preceding call to isl_qpolynomial_take_domain_space. + * However, in this case, "qp" only has a single reference and + * then the call to isl_qpolynomial_cow has no effect. + */ +static __isl_give isl_qpolynomial *isl_qpolynomial_restore_domain_space( + __isl_take isl_qpolynomial *qp, __isl_take isl_space *space) +{ + if (!qp || !space) + goto error; + + if (qp->dim == space) { + isl_space_free(space); + return qp; + } + + qp = isl_qpolynomial_cow(qp); + if (!qp) + goto error; + isl_space_free(qp->dim); + qp->dim = space; + + return qp; +error: + isl_qpolynomial_free(qp); + isl_space_free(space); + return NULL; +} + +__isl_give isl_qpolynomial *isl_qpolynomial_reset_domain_space( + __isl_take isl_qpolynomial *qp, __isl_take isl_space *space) +{ + return isl_qpolynomial_restore_domain_space(qp, space); +} + +/* Reset the space of "qp". 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. + */ +__isl_give isl_qpolynomial *isl_qpolynomial_reset_space_and_domain( + __isl_take isl_qpolynomial *qp, __isl_take isl_space *space, + __isl_take isl_space *domain) +{ + isl_space_free(space); + return isl_qpolynomial_reset_domain_space(qp, domain); +} + +isl_ctx *isl_qpolynomial_get_ctx(__isl_keep isl_qpolynomial *qp) +{ + return qp ? qp->dim->ctx : NULL; +} + +/* Return the domain space of "qp". + */ +static __isl_keep isl_space *isl_qpolynomial_peek_domain_space( + __isl_keep isl_qpolynomial *qp) +{ + return qp ? qp->dim : NULL; +} + +/* Return a copy of the domain space of "qp". + */ +__isl_give isl_space *isl_qpolynomial_get_domain_space( + __isl_keep isl_qpolynomial *qp) +{ + return isl_space_copy(isl_qpolynomial_peek_domain_space(qp)); +} + +#undef TYPE +#define TYPE isl_qpolynomial +#undef PEEK_SPACE +#define PEEK_SPACE peek_domain_space + +static +#include "isl_type_has_equal_space_bin_templ.c" +static +#include "isl_type_check_equal_space_templ.c" + +#undef PEEK_SPACE + +/* Return a copy of the local variables of "qp". + */ +__isl_keep isl_local *isl_qpolynomial_get_local( + __isl_keep isl_qpolynomial *qp) +{ + return qp ? isl_local_copy(qp->div) : NULL; +} + +/* Return the local variables of "qp". + * This may be either a copy or the local variables themselves + * if there is only one reference to "qp". + * This allows the local variables to be modified in-place + * if both the quasi-polynomial and its local variables + * have only a single reference. + * The caller is not allowed to modify "qp" between this call and + * the subsequent call to isl_qpolynomial_restore_local. + * The only exception is that isl_qpolynomial_free can be called instead. + */ +static __isl_give isl_local *isl_qpolynomial_take_local( + __isl_keep isl_qpolynomial *qp) +{ + isl_local *local; + + if (!qp) + return NULL; + if (qp->ref != 1) + return isl_qpolynomial_get_local(qp); + local = qp->div; + qp->div = NULL; + return local; +} + +/* Set the local variables of "qp" to "local", + * where the local variables of "qp" may be missing + * due to a preceding call to isl_qpolynomial_take_local. + * However, in this case, "qp" only has a single reference and + * then the call to isl_qpolynomial_cow has no effect. + */ +static __isl_give isl_qpolynomial *isl_qpolynomial_restore_local( + __isl_keep isl_qpolynomial *qp, __isl_take isl_local *local) +{ + if (!qp || !local) + goto error; + + if (qp->div == local) { + isl_local_free(local); + return qp; + } + + qp = isl_qpolynomial_cow(qp); + if (!qp) + goto error; + isl_local_free(qp->div); + qp->div = local; + + return qp; +error: + isl_qpolynomial_free(qp); + isl_local_free(local); + return NULL; +} + +/* Return a copy of the local space on which "qp" is defined. + */ +static __isl_give isl_local_space *isl_qpolynomial_get_domain_local_space( + __isl_keep isl_qpolynomial *qp) +{ + isl_space *space; + isl_local *local; + + if (!qp) + return NULL; + + space = isl_qpolynomial_get_domain_space(qp); + local = isl_qpolynomial_get_local(qp); + return isl_local_space_alloc_div(space, local); +} + +__isl_give isl_space *isl_qpolynomial_get_space(__isl_keep isl_qpolynomial *qp) +{ + isl_space *space; + if (!qp) + return NULL; + space = isl_space_copy(qp->dim); + space = isl_space_from_domain(space); + space = isl_space_add_dims(space, isl_dim_out, 1); + return space; +} + +/* Return the number of variables of the given type in the domain of "qp". + */ +isl_size isl_qpolynomial_domain_dim(__isl_keep isl_qpolynomial *qp, + enum isl_dim_type type) +{ + isl_space *space; + isl_size dim; + + space = isl_qpolynomial_peek_domain_space(qp); + + if (!space) + return isl_size_error; + if (type == isl_dim_div) + return qp->div->n_row; + dim = isl_space_dim(space, type); + if (dim < 0) + return isl_size_error; + if (type == isl_dim_all) { + isl_size n_div; + + n_div = isl_qpolynomial_domain_dim(qp, isl_dim_div); + if (n_div < 0) + return isl_size_error; + dim += n_div; + } + return dim; +} + +/* Given the type of a dimension of an isl_qpolynomial, + * return the type of the corresponding dimension in its domain. + * This function is only called for "type" equal to isl_dim_in or + * isl_dim_param. + */ +static enum isl_dim_type domain_type(enum isl_dim_type type) +{ + return type == isl_dim_in ? isl_dim_set : type; +} + +/* Externally, an isl_qpolynomial has a map space, but internally, the + * ls field corresponds to the domain of that space. + */ +isl_size isl_qpolynomial_dim(__isl_keep isl_qpolynomial *qp, + enum isl_dim_type type) +{ + if (!qp) + return isl_size_error; + if (type == isl_dim_out) + return 1; + type = domain_type(type); + return isl_qpolynomial_domain_dim(qp, type); +} + +/* Return the offset of the first variable of type "type" within + * the variables of the domain of "qp". + */ +static isl_size isl_qpolynomial_domain_var_offset( + __isl_keep isl_qpolynomial *qp, enum isl_dim_type type) +{ + isl_space *space; + + space = isl_qpolynomial_peek_domain_space(qp); + + switch (type) { + case isl_dim_param: + case isl_dim_set: return isl_space_offset(space, type); + case isl_dim_div: return isl_space_dim(space, isl_dim_all); + case isl_dim_cst: + default: + isl_die(isl_qpolynomial_get_ctx(qp), isl_error_invalid, + "invalid dimension type", return isl_size_error); + } +} + +/* Return the offset of the first coefficient of type "type" in + * the domain of "qp". + */ +unsigned isl_qpolynomial_domain_offset(__isl_keep isl_qpolynomial *qp, + enum isl_dim_type type) +{ + switch (type) { + case isl_dim_cst: + return 0; + case isl_dim_param: + case isl_dim_set: + case isl_dim_div: + return 1 + isl_qpolynomial_domain_var_offset(qp, type); + default: + return 0; + } +} + +isl_bool isl_qpolynomial_is_zero(__isl_keep isl_qpolynomial *qp) +{ + return qp ? isl_poly_is_zero(qp->poly) : isl_bool_error; +} + +isl_bool isl_qpolynomial_is_one(__isl_keep isl_qpolynomial *qp) +{ + return qp ? isl_poly_is_one(qp->poly) : isl_bool_error; +} + +isl_bool isl_qpolynomial_is_nan(__isl_keep isl_qpolynomial *qp) +{ + return qp ? isl_poly_is_nan(qp->poly) : isl_bool_error; +} + +isl_bool isl_qpolynomial_is_infty(__isl_keep isl_qpolynomial *qp) +{ + return qp ? isl_poly_is_infty(qp->poly) : isl_bool_error; +} + +isl_bool isl_qpolynomial_is_neginfty(__isl_keep isl_qpolynomial *qp) +{ + return qp ? isl_poly_is_neginfty(qp->poly) : isl_bool_error; +} + +int isl_qpolynomial_sgn(__isl_keep isl_qpolynomial *qp) +{ + return qp ? isl_poly_sgn(qp->poly) : 0; +} + +static void poly_free_cst(__isl_take isl_poly_cst *cst) +{ + isl_int_clear(cst->n); + isl_int_clear(cst->d); +} + +static void poly_free_rec(__isl_take isl_poly_rec *rec) +{ + int i; + + for (i = 0; i < rec->n; ++i) + isl_poly_free(rec->p[i]); +} + +__isl_give isl_poly *isl_poly_copy(__isl_keep isl_poly *poly) +{ + if (!poly) + return NULL; + + poly->ref++; + return poly; +} + +__isl_give isl_poly *isl_poly_dup_cst(__isl_keep isl_poly *poly) +{ + isl_poly_cst *cst; + isl_poly_cst *dup; + + cst = isl_poly_as_cst(poly); + if (!cst) + return NULL; + + dup = isl_poly_as_cst(isl_poly_zero(poly->ctx)); + if (!dup) + return NULL; + isl_int_set(dup->n, cst->n); + isl_int_set(dup->d, cst->d); + + return &dup->poly; +} + +__isl_give isl_poly *isl_poly_dup_rec(__isl_keep isl_poly *poly) +{ + int i; + isl_poly_rec *rec; + isl_poly_rec *dup; + + rec = isl_poly_as_rec(poly); + if (!rec) + return NULL; + + dup = isl_poly_alloc_rec(poly->ctx, poly->var, rec->n); + if (!dup) + return NULL; + + for (i = 0; i < rec->n; ++i) { + dup->p[i] = isl_poly_copy(rec->p[i]); + if (!dup->p[i]) + goto error; + dup->n++; + } + + return &dup->poly; +error: + isl_poly_free(&dup->poly); + return NULL; +} + +__isl_give isl_poly *isl_poly_dup(__isl_keep isl_poly *poly) +{ + isl_bool is_cst; + + is_cst = isl_poly_is_cst(poly); + if (is_cst < 0) + return NULL; + if (is_cst) + return isl_poly_dup_cst(poly); + else + return isl_poly_dup_rec(poly); +} + +__isl_give isl_poly *isl_poly_cow(__isl_take isl_poly *poly) +{ + if (!poly) + return NULL; + + if (poly->ref == 1) + return poly; + poly->ref--; + return isl_poly_dup(poly); +} + +__isl_null isl_poly *isl_poly_free(__isl_take isl_poly *poly) +{ + if (!poly) + return NULL; + + if (--poly->ref > 0) + return NULL; + + if (poly->var < 0) + poly_free_cst((isl_poly_cst *) poly); + else + poly_free_rec((isl_poly_rec *) poly); + + isl_ctx_deref(poly->ctx); + free(poly); + return NULL; +} + +static void isl_poly_cst_reduce(__isl_keep isl_poly_cst *cst) +{ + isl_int gcd; + + isl_int_init(gcd); + isl_int_gcd(gcd, cst->n, cst->d); + if (!isl_int_is_zero(gcd) && !isl_int_is_one(gcd)) { + isl_int_divexact(cst->n, cst->n, gcd); + isl_int_divexact(cst->d, cst->d, gcd); + } + isl_int_clear(gcd); +} + +__isl_give isl_poly *isl_poly_sum_cst(__isl_take isl_poly *poly1, + __isl_take isl_poly *poly2) +{ + isl_poly_cst *cst1; + isl_poly_cst *cst2; + + poly1 = isl_poly_cow(poly1); + if (!poly1 || !poly2) + goto error; + + cst1 = isl_poly_as_cst(poly1); + cst2 = isl_poly_as_cst(poly2); + + if (isl_int_eq(cst1->d, cst2->d)) + isl_int_add(cst1->n, cst1->n, cst2->n); + else { + isl_int_mul(cst1->n, cst1->n, cst2->d); + isl_int_addmul(cst1->n, cst2->n, cst1->d); + isl_int_mul(cst1->d, cst1->d, cst2->d); + } + + isl_poly_cst_reduce(cst1); + + isl_poly_free(poly2); + return poly1; +error: + isl_poly_free(poly1); + isl_poly_free(poly2); + return NULL; +} + +static __isl_give isl_poly *replace_by_zero(__isl_take isl_poly *poly) +{ + struct isl_ctx *ctx; + + if (!poly) + return NULL; + ctx = poly->ctx; + isl_poly_free(poly); + return isl_poly_zero(ctx); +} + +static __isl_give isl_poly *replace_by_constant_term(__isl_take isl_poly *poly) +{ + isl_poly_rec *rec; + isl_poly *cst; + + if (!poly) + return NULL; + + rec = isl_poly_as_rec(poly); + if (!rec) + goto error; + cst = isl_poly_copy(rec->p[0]); + isl_poly_free(poly); + return cst; +error: + isl_poly_free(poly); + return NULL; +} + +__isl_give isl_poly *isl_poly_sum(__isl_take isl_poly *poly1, + __isl_take isl_poly *poly2) +{ + int i; + isl_bool is_zero, is_nan, is_cst; + isl_poly_rec *rec1, *rec2; + + if (!poly1 || !poly2) + goto error; + + is_nan = isl_poly_is_nan(poly1); + if (is_nan < 0) + goto error; + if (is_nan) { + isl_poly_free(poly2); + return poly1; + } + + is_nan = isl_poly_is_nan(poly2); + if (is_nan < 0) + goto error; + if (is_nan) { + isl_poly_free(poly1); + return poly2; + } + + is_zero = isl_poly_is_zero(poly1); + if (is_zero < 0) + goto error; + if (is_zero) { + isl_poly_free(poly1); + return poly2; + } + + is_zero = isl_poly_is_zero(poly2); + if (is_zero < 0) + goto error; + if (is_zero) { + isl_poly_free(poly2); + return poly1; + } + + if (poly1->var < poly2->var) + return isl_poly_sum(poly2, poly1); + + if (poly2->var < poly1->var) { + isl_poly_rec *rec; + isl_bool is_infty; + + is_infty = isl_poly_is_infty(poly2); + if (is_infty >= 0 && !is_infty) + is_infty = isl_poly_is_neginfty(poly2); + if (is_infty < 0) + goto error; + if (is_infty) { + isl_poly_free(poly1); + return poly2; + } + poly1 = isl_poly_cow(poly1); + rec = isl_poly_as_rec(poly1); + if (!rec) + goto error; + rec->p[0] = isl_poly_sum(rec->p[0], poly2); + if (rec->n == 1) + poly1 = replace_by_constant_term(poly1); + return poly1; + } + + is_cst = isl_poly_is_cst(poly1); + if (is_cst < 0) + goto error; + if (is_cst) + return isl_poly_sum_cst(poly1, poly2); + + rec1 = isl_poly_as_rec(poly1); + rec2 = isl_poly_as_rec(poly2); + if (!rec1 || !rec2) + goto error; + + if (rec1->n < rec2->n) + return isl_poly_sum(poly2, poly1); + + poly1 = isl_poly_cow(poly1); + rec1 = isl_poly_as_rec(poly1); + if (!rec1) + goto error; + + for (i = rec2->n - 1; i >= 0; --i) { + isl_bool is_zero; + + rec1->p[i] = isl_poly_sum(rec1->p[i], + isl_poly_copy(rec2->p[i])); + if (!rec1->p[i]) + goto error; + if (i != rec1->n - 1) + continue; + is_zero = isl_poly_is_zero(rec1->p[i]); + if (is_zero < 0) + goto error; + if (is_zero) { + isl_poly_free(rec1->p[i]); + rec1->n--; + } + } + + if (rec1->n == 0) + poly1 = replace_by_zero(poly1); + else if (rec1->n == 1) + poly1 = replace_by_constant_term(poly1); + + isl_poly_free(poly2); + + return poly1; +error: + isl_poly_free(poly1); + isl_poly_free(poly2); + return NULL; +} + +__isl_give isl_poly *isl_poly_cst_add_isl_int(__isl_take isl_poly *poly, + isl_int v) +{ + isl_poly_cst *cst; + + poly = isl_poly_cow(poly); + if (!poly) + return NULL; + + cst = isl_poly_as_cst(poly); + + isl_int_addmul(cst->n, cst->d, v); + + return poly; +} + +__isl_give isl_poly *isl_poly_add_isl_int(__isl_take isl_poly *poly, isl_int v) +{ + isl_bool is_cst; + isl_poly_rec *rec; + + is_cst = isl_poly_is_cst(poly); + if (is_cst < 0) + return isl_poly_free(poly); + if (is_cst) + return isl_poly_cst_add_isl_int(poly, v); + + poly = isl_poly_cow(poly); + rec = isl_poly_as_rec(poly); + if (!rec) + goto error; + + rec->p[0] = isl_poly_add_isl_int(rec->p[0], v); + if (!rec->p[0]) + goto error; + + return poly; +error: + isl_poly_free(poly); + return NULL; +} + +__isl_give isl_poly *isl_poly_cst_mul_isl_int(__isl_take isl_poly *poly, + isl_int v) +{ + isl_bool is_zero; + isl_poly_cst *cst; + + is_zero = isl_poly_is_zero(poly); + if (is_zero < 0) + return isl_poly_free(poly); + if (is_zero) + return poly; + + poly = isl_poly_cow(poly); + if (!poly) + return NULL; + + cst = isl_poly_as_cst(poly); + + isl_int_mul(cst->n, cst->n, v); + + return poly; +} + +__isl_give isl_poly *isl_poly_mul_isl_int(__isl_take isl_poly *poly, isl_int v) +{ + int i; + isl_bool is_cst; + isl_poly_rec *rec; + + is_cst = isl_poly_is_cst(poly); + if (is_cst < 0) + return isl_poly_free(poly); + if (is_cst) + return isl_poly_cst_mul_isl_int(poly, v); + + poly = isl_poly_cow(poly); + rec = isl_poly_as_rec(poly); + if (!rec) + goto error; + + for (i = 0; i < rec->n; ++i) { + rec->p[i] = isl_poly_mul_isl_int(rec->p[i], v); + if (!rec->p[i]) + goto error; + } + + return poly; +error: + isl_poly_free(poly); + return NULL; +} + +/* Multiply the constant polynomial "poly" by "v". + */ +static __isl_give isl_poly *isl_poly_cst_scale_val(__isl_take isl_poly *poly, + __isl_keep isl_val *v) +{ + isl_bool is_zero; + isl_poly_cst *cst; + + is_zero = isl_poly_is_zero(poly); + if (is_zero < 0) + return isl_poly_free(poly); + if (is_zero) + return poly; + + poly = isl_poly_cow(poly); + if (!poly) + return NULL; + + cst = isl_poly_as_cst(poly); + + isl_int_mul(cst->n, cst->n, v->n); + isl_int_mul(cst->d, cst->d, v->d); + isl_poly_cst_reduce(cst); + + return poly; +} + +/* Multiply the polynomial "poly" by "v". + */ +static __isl_give isl_poly *isl_poly_scale_val(__isl_take isl_poly *poly, + __isl_keep isl_val *v) +{ + int i; + isl_bool is_cst; + isl_poly_rec *rec; + + is_cst = isl_poly_is_cst(poly); + if (is_cst < 0) + return isl_poly_free(poly); + if (is_cst) + return isl_poly_cst_scale_val(poly, v); + + poly = isl_poly_cow(poly); + rec = isl_poly_as_rec(poly); + if (!rec) + goto error; + + for (i = 0; i < rec->n; ++i) { + rec->p[i] = isl_poly_scale_val(rec->p[i], v); + if (!rec->p[i]) + goto error; + } + + return poly; +error: + isl_poly_free(poly); + return NULL; +} + +__isl_give isl_poly *isl_poly_mul_cst(__isl_take isl_poly *poly1, + __isl_take isl_poly *poly2) +{ + isl_poly_cst *cst1; + isl_poly_cst *cst2; + + poly1 = isl_poly_cow(poly1); + if (!poly1 || !poly2) + goto error; + + cst1 = isl_poly_as_cst(poly1); + cst2 = isl_poly_as_cst(poly2); + + isl_int_mul(cst1->n, cst1->n, cst2->n); + isl_int_mul(cst1->d, cst1->d, cst2->d); + + isl_poly_cst_reduce(cst1); + + isl_poly_free(poly2); + return poly1; +error: + isl_poly_free(poly1); + isl_poly_free(poly2); + return NULL; +} + +__isl_give isl_poly *isl_poly_mul_rec(__isl_take isl_poly *poly1, + __isl_take isl_poly *poly2) +{ + isl_poly_rec *rec1; + isl_poly_rec *rec2; + isl_poly_rec *res = NULL; + int i, j; + int size; + + rec1 = isl_poly_as_rec(poly1); + rec2 = isl_poly_as_rec(poly2); + if (!rec1 || !rec2) + goto error; + size = rec1->n + rec2->n - 1; + res = isl_poly_alloc_rec(poly1->ctx, poly1->var, size); + if (!res) + goto error; + + for (i = 0; i < rec1->n; ++i) { + res->p[i] = isl_poly_mul(isl_poly_copy(rec2->p[0]), + isl_poly_copy(rec1->p[i])); + if (!res->p[i]) + goto error; + res->n++; + } + for (; i < size; ++i) { + res->p[i] = isl_poly_zero(poly1->ctx); + if (!res->p[i]) + goto error; + res->n++; + } + for (i = 0; i < rec1->n; ++i) { + for (j = 1; j < rec2->n; ++j) { + isl_poly *poly; + poly = isl_poly_mul(isl_poly_copy(rec2->p[j]), + isl_poly_copy(rec1->p[i])); + res->p[i + j] = isl_poly_sum(res->p[i + j], poly); + if (!res->p[i + j]) + goto error; + } + } + + isl_poly_free(poly1); + isl_poly_free(poly2); + + return &res->poly; +error: + isl_poly_free(poly1); + isl_poly_free(poly2); + isl_poly_free(&res->poly); + return NULL; +} + +__isl_give isl_poly *isl_poly_mul(__isl_take isl_poly *poly1, + __isl_take isl_poly *poly2) +{ + isl_bool is_zero, is_nan, is_one, is_cst; + + if (!poly1 || !poly2) + goto error; + + is_nan = isl_poly_is_nan(poly1); + if (is_nan < 0) + goto error; + if (is_nan) { + isl_poly_free(poly2); + return poly1; + } + + is_nan = isl_poly_is_nan(poly2); + if (is_nan < 0) + goto error; + if (is_nan) { + isl_poly_free(poly1); + return poly2; + } + + is_zero = isl_poly_is_zero(poly1); + if (is_zero < 0) + goto error; + if (is_zero) { + isl_poly_free(poly2); + return poly1; + } + + is_zero = isl_poly_is_zero(poly2); + if (is_zero < 0) + goto error; + if (is_zero) { + isl_poly_free(poly1); + return poly2; + } + + is_one = isl_poly_is_one(poly1); + if (is_one < 0) + goto error; + if (is_one) { + isl_poly_free(poly1); + return poly2; + } + + is_one = isl_poly_is_one(poly2); + if (is_one < 0) + goto error; + if (is_one) { + isl_poly_free(poly2); + return poly1; + } + + if (poly1->var < poly2->var) + return isl_poly_mul(poly2, poly1); + + if (poly2->var < poly1->var) { + int i; + isl_poly_rec *rec; + isl_bool is_infty; + + is_infty = isl_poly_is_infty(poly2); + if (is_infty >= 0 && !is_infty) + is_infty = isl_poly_is_neginfty(poly2); + if (is_infty < 0) + goto error; + if (is_infty) { + isl_ctx *ctx = poly1->ctx; + isl_poly_free(poly1); + isl_poly_free(poly2); + return isl_poly_nan(ctx); + } + poly1 = isl_poly_cow(poly1); + rec = isl_poly_as_rec(poly1); + if (!rec) + goto error; + + for (i = 0; i < rec->n; ++i) { + rec->p[i] = isl_poly_mul(rec->p[i], + isl_poly_copy(poly2)); + if (!rec->p[i]) + goto error; + } + isl_poly_free(poly2); + return poly1; + } + + is_cst = isl_poly_is_cst(poly1); + if (is_cst < 0) + goto error; + if (is_cst) + return isl_poly_mul_cst(poly1, poly2); + + return isl_poly_mul_rec(poly1, poly2); +error: + isl_poly_free(poly1); + isl_poly_free(poly2); + return NULL; +} + +__isl_give isl_poly *isl_poly_pow(__isl_take isl_poly *poly, unsigned power) +{ + isl_poly *res; + + if (!poly) + return NULL; + if (power == 1) + return poly; + + if (power % 2) + res = isl_poly_copy(poly); + else + res = isl_poly_one(poly->ctx); + + while (power >>= 1) { + poly = isl_poly_mul(poly, isl_poly_copy(poly)); + if (power % 2) + res = isl_poly_mul(res, isl_poly_copy(poly)); + } + + isl_poly_free(poly); + return res; +} + +__isl_give isl_qpolynomial *isl_qpolynomial_alloc(__isl_take isl_space *space, + unsigned n_div, __isl_take isl_poly *poly) +{ + struct isl_qpolynomial *qp = NULL; + isl_size total; + + total = isl_space_dim(space, isl_dim_all); + if (total < 0 || !poly) + goto error; + + if (!isl_space_is_set(space)) + isl_die(isl_space_get_ctx(space), isl_error_invalid, + "domain of polynomial should be a set", goto error); + + qp = isl_calloc_type(space->ctx, struct isl_qpolynomial); + if (!qp) + goto error; + + qp->ref = 1; + qp->div = isl_mat_alloc(space->ctx, n_div, 1 + 1 + total + n_div); + if (!qp->div) + goto error; + + qp->dim = space; + qp->poly = poly; + + return qp; +error: + isl_space_free(space); + isl_poly_free(poly); + isl_qpolynomial_free(qp); + return NULL; +} + +__isl_give isl_qpolynomial *isl_qpolynomial_copy(__isl_keep isl_qpolynomial *qp) +{ + if (!qp) + return NULL; + + qp->ref++; + return qp; +} + +/* Return a copy of the polynomial expression of "qp". + */ +__isl_give isl_poly *isl_qpolynomial_get_poly(__isl_keep isl_qpolynomial *qp) +{ + return qp ? isl_poly_copy(qp->poly) : NULL; +} + +/* Return the polynomial expression of "qp". + * This may be either a copy or the polynomial expression itself + * if there is only one reference to "qp". + * This allows the polynomial expression to be modified inplace + * if both the quasi-polynomial and its polynomial expression + * have only a single reference. + * The caller is not allowed to modify "qp" between this call and + * a subsequent call to isl_qpolynomial_restore_poly. + * The only exception is that isl_qpolynomial_free can be called instead. + */ +static __isl_give isl_poly *isl_qpolynomial_take_poly( + __isl_keep isl_qpolynomial *qp) +{ + isl_poly *poly; + + if (!qp) + return NULL; + if (qp->ref != 1) + return isl_qpolynomial_get_poly(qp); + poly = qp->poly; + qp->poly = NULL; + return poly; +} + +/* Set the polynomial expression of "qp" to "space", + * where the polynomial expression of "qp" may be missing + * due to a preceding call to isl_qpolynomial_take_poly. + * However, in this case, "qp" only has a single reference and + * then the call to isl_qpolynomial_cow has no effect. + */ +static __isl_give isl_qpolynomial *isl_qpolynomial_restore_poly( + __isl_keep isl_qpolynomial *qp, __isl_take isl_poly *poly) +{ + if (!qp || !poly) + goto error; + + if (qp->poly == poly) { + isl_poly_free(poly); + return qp; + } + + qp = isl_qpolynomial_cow(qp); + if (!qp) + goto error; + isl_poly_free(qp->poly); + qp->poly = poly; + + return qp; +error: + isl_qpolynomial_free(qp); + isl_poly_free(poly); + return NULL; +} + +__isl_give isl_qpolynomial *isl_qpolynomial_dup(__isl_keep isl_qpolynomial *qp) +{ + isl_poly *poly; + struct isl_qpolynomial *dup; + + if (!qp) + return NULL; + + poly = isl_qpolynomial_get_poly(qp); + dup = isl_qpolynomial_alloc(isl_space_copy(qp->dim), qp->div->n_row, + poly); + if (!dup) + return NULL; + isl_mat_free(dup->div); + dup->div = isl_qpolynomial_get_local(qp); + if (!dup->div) + goto error; + + return dup; +error: + isl_qpolynomial_free(dup); + return NULL; +} + +__isl_give isl_qpolynomial *isl_qpolynomial_cow(__isl_take isl_qpolynomial *qp) +{ + if (!qp) + return NULL; + + if (qp->ref == 1) + return qp; + qp->ref--; + return isl_qpolynomial_dup(qp); +} + +__isl_null isl_qpolynomial *isl_qpolynomial_free( + __isl_take isl_qpolynomial *qp) +{ + if (!qp) + return NULL; + + if (--qp->ref > 0) + return NULL; + + isl_space_free(qp->dim); + isl_mat_free(qp->div); + isl_poly_free(qp->poly); + + free(qp); + return NULL; +} + +__isl_give isl_poly *isl_poly_var_pow(isl_ctx *ctx, int pos, int power) +{ + int i; + isl_poly_rec *rec; + isl_poly_cst *cst; + + rec = isl_poly_alloc_rec(ctx, pos, 1 + power); + if (!rec) + return NULL; + for (i = 0; i < 1 + power; ++i) { + rec->p[i] = isl_poly_zero(ctx); + if (!rec->p[i]) + goto error; + rec->n++; + } + cst = isl_poly_as_cst(rec->p[power]); + isl_int_set_si(cst->n, 1); + + return &rec->poly; +error: + isl_poly_free(&rec->poly); + return NULL; +} + +/* r array maps original positions to new positions. + */ +static __isl_give isl_poly *reorder(__isl_take isl_poly *poly, int *r) +{ + int i; + isl_bool is_cst; + isl_poly_rec *rec; + isl_poly *base; + isl_poly *res; + + is_cst = isl_poly_is_cst(poly); + if (is_cst < 0) + return isl_poly_free(poly); + if (is_cst) + return poly; + + rec = isl_poly_as_rec(poly); + if (!rec) + goto error; + + isl_assert(poly->ctx, rec->n >= 1, goto error); + + base = isl_poly_var_pow(poly->ctx, r[poly->var], 1); + res = reorder(isl_poly_copy(rec->p[rec->n - 1]), r); + + for (i = rec->n - 2; i >= 0; --i) { + res = isl_poly_mul(res, isl_poly_copy(base)); + res = isl_poly_sum(res, reorder(isl_poly_copy(rec->p[i]), r)); + } + + isl_poly_free(base); + isl_poly_free(poly); + + return res; +error: + isl_poly_free(poly); + return NULL; +} + +static isl_bool compatible_divs(__isl_keep isl_mat *div1, + __isl_keep isl_mat *div2) +{ + int n_row, n_col; + isl_bool equal; + + isl_assert(div1->ctx, div1->n_row >= div2->n_row && + div1->n_col >= div2->n_col, + return isl_bool_error); + + if (div1->n_row == div2->n_row) + return isl_mat_is_equal(div1, div2); + + n_row = div1->n_row; + n_col = div1->n_col; + div1->n_row = div2->n_row; + div1->n_col = div2->n_col; + + equal = isl_mat_is_equal(div1, div2); + + div1->n_row = n_row; + div1->n_col = n_col; + + return equal; +} + +static int cmp_row(__isl_keep isl_mat *div, int i, int j) +{ + int li, lj; + + li = isl_seq_last_non_zero(div->row[i], div->n_col); + lj = isl_seq_last_non_zero(div->row[j], div->n_col); + + if (li != lj) + return li - lj; + + return isl_seq_cmp(div->row[i], div->row[j], div->n_col); +} + +struct isl_div_sort_info { + isl_mat *div; + int row; +}; + +static int div_sort_cmp(const void *p1, const void *p2) +{ + const struct isl_div_sort_info *i1, *i2; + i1 = (const struct isl_div_sort_info *) p1; + i2 = (const struct isl_div_sort_info *) p2; + + return cmp_row(i1->div, i1->row, i2->row); +} + +/* Sort divs and remove duplicates. + */ +static __isl_give isl_qpolynomial *sort_divs(__isl_take isl_qpolynomial *qp) +{ + int i; + int skip; + int len; + struct isl_div_sort_info *array = NULL; + int *pos = NULL, *at = NULL; + int *reordering = NULL; + isl_size div_pos; + + if (!qp) + return NULL; + if (qp->div->n_row <= 1) + return qp; + + div_pos = isl_qpolynomial_domain_var_offset(qp, isl_dim_div); + if (div_pos < 0) + return isl_qpolynomial_free(qp); + + array = isl_alloc_array(qp->div->ctx, struct isl_div_sort_info, + qp->div->n_row); + pos = isl_alloc_array(qp->div->ctx, int, qp->div->n_row); + at = isl_alloc_array(qp->div->ctx, int, qp->div->n_row); + len = qp->div->n_col - 2; + reordering = isl_alloc_array(qp->div->ctx, int, len); + if (!array || !pos || !at || !reordering) + goto error; + + for (i = 0; i < qp->div->n_row; ++i) { + array[i].div = qp->div; + array[i].row = i; + pos[i] = i; + at[i] = i; + } + + qsort(array, qp->div->n_row, sizeof(struct isl_div_sort_info), + div_sort_cmp); + + for (i = 0; i < div_pos; ++i) + reordering[i] = i; + + for (i = 0; i < qp->div->n_row; ++i) { + if (pos[array[i].row] == i) + continue; + qp->div = isl_mat_swap_rows(qp->div, i, pos[array[i].row]); + pos[at[i]] = pos[array[i].row]; + at[pos[array[i].row]] = at[i]; + at[i] = array[i].row; + pos[array[i].row] = i; + } + + skip = 0; + for (i = 0; i < len - div_pos; ++i) { + if (i > 0 && + isl_seq_eq(qp->div->row[i - skip - 1], + qp->div->row[i - skip], qp->div->n_col)) { + qp->div = isl_mat_drop_rows(qp->div, i - skip, 1); + isl_mat_col_add(qp->div, 2 + div_pos + i - skip - 1, + 2 + div_pos + i - skip); + qp->div = isl_mat_drop_cols(qp->div, + 2 + div_pos + i - skip, 1); + skip++; + } + reordering[div_pos + array[i].row] = div_pos + i - skip; + } + + qp->poly = reorder(qp->poly, reordering); + + if (!qp->poly || !qp->div) + goto error; + + free(at); + free(pos); + free(array); + free(reordering); + + return qp; +error: + free(at); + free(pos); + free(array); + free(reordering); + isl_qpolynomial_free(qp); + return NULL; +} + +static __isl_give isl_poly *expand(__isl_take isl_poly *poly, int *exp, + int first) +{ + int i; + isl_bool is_cst; + isl_poly_rec *rec; + + is_cst = isl_poly_is_cst(poly); + if (is_cst < 0) + return isl_poly_free(poly); + if (is_cst) + return poly; + + if (poly->var < first) + return poly; + + if (exp[poly->var - first] == poly->var - first) + return poly; + + poly = isl_poly_cow(poly); + if (!poly) + goto error; + + poly->var = exp[poly->var - first] + first; + + rec = isl_poly_as_rec(poly); + if (!rec) + goto error; + + for (i = 0; i < rec->n; ++i) { + rec->p[i] = expand(rec->p[i], exp, first); + if (!rec->p[i]) + goto error; + } + + return poly; +error: + isl_poly_free(poly); + return NULL; +} + +static __isl_give isl_qpolynomial *with_merged_divs( + __isl_give isl_qpolynomial *(*fn)(__isl_take isl_qpolynomial *qp1, + __isl_take isl_qpolynomial *qp2), + __isl_take isl_qpolynomial *qp1, __isl_take isl_qpolynomial *qp2) +{ + int *exp1 = NULL; + int *exp2 = NULL; + isl_mat *div = NULL; + int n_div1, n_div2; + + qp1 = isl_qpolynomial_cow(qp1); + qp2 = isl_qpolynomial_cow(qp2); + + if (!qp1 || !qp2) + goto error; + + isl_assert(qp1->div->ctx, qp1->div->n_row >= qp2->div->n_row && + qp1->div->n_col >= qp2->div->n_col, goto error); + + n_div1 = qp1->div->n_row; + n_div2 = qp2->div->n_row; + exp1 = isl_alloc_array(qp1->div->ctx, int, n_div1); + exp2 = isl_alloc_array(qp2->div->ctx, int, n_div2); + if ((n_div1 && !exp1) || (n_div2 && !exp2)) + goto error; + + div = isl_merge_divs(qp1->div, qp2->div, exp1, exp2); + if (!div) + goto error; + + isl_mat_free(qp1->div); + qp1->div = isl_mat_copy(div); + isl_mat_free(qp2->div); + qp2->div = isl_mat_copy(div); + + qp1->poly = expand(qp1->poly, exp1, div->n_col - div->n_row - 2); + qp2->poly = expand(qp2->poly, exp2, div->n_col - div->n_row - 2); + + if (!qp1->poly || !qp2->poly) + goto error; + + isl_mat_free(div); + free(exp1); + free(exp2); + + return fn(qp1, qp2); +error: + isl_mat_free(div); + free(exp1); + free(exp2); + isl_qpolynomial_free(qp1); + isl_qpolynomial_free(qp2); + return NULL; +} + +__isl_give isl_qpolynomial *isl_qpolynomial_add(__isl_take isl_qpolynomial *qp1, + __isl_take isl_qpolynomial *qp2) +{ + isl_bool compatible; + isl_poly *poly; + + if (isl_qpolynomial_check_equal_space(qp1, qp2) < 0) + goto error; + + if (qp1->div->n_row < qp2->div->n_row) + return isl_qpolynomial_add(qp2, qp1); + + compatible = compatible_divs(qp1->div, qp2->div); + if (compatible < 0) + goto error; + if (!compatible) + return with_merged_divs(isl_qpolynomial_add, qp1, qp2); + + poly = isl_qpolynomial_take_poly(qp1); + poly = isl_poly_sum(poly, isl_qpolynomial_get_poly(qp2)); + qp1 = isl_qpolynomial_restore_poly(qp1, poly); + + isl_qpolynomial_free(qp2); + + return qp1; +error: + isl_qpolynomial_free(qp1); + isl_qpolynomial_free(qp2); + return NULL; +} + +__isl_give isl_qpolynomial *isl_qpolynomial_add_on_domain( + __isl_keep isl_set *dom, + __isl_take isl_qpolynomial *qp1, + __isl_take isl_qpolynomial *qp2) +{ + qp1 = isl_qpolynomial_add(qp1, qp2); + qp1 = isl_qpolynomial_gist(qp1, isl_set_copy(dom)); + return qp1; +} + +__isl_give isl_qpolynomial *isl_qpolynomial_sub(__isl_take isl_qpolynomial *qp1, + __isl_take isl_qpolynomial *qp2) +{ + return isl_qpolynomial_add(qp1, isl_qpolynomial_neg(qp2)); +} + +__isl_give isl_qpolynomial *isl_qpolynomial_add_isl_int( + __isl_take isl_qpolynomial *qp, isl_int v) +{ + isl_poly *poly; + + if (isl_int_is_zero(v)) + return qp; + + poly = isl_qpolynomial_take_poly(qp); + poly = isl_poly_add_isl_int(poly, v); + qp = isl_qpolynomial_restore_poly(qp, poly); + + return qp; +} + +__isl_give isl_qpolynomial *isl_qpolynomial_neg(__isl_take isl_qpolynomial *qp) +{ + if (!qp) + return NULL; + + return isl_qpolynomial_mul_isl_int(qp, qp->dim->ctx->negone); +} + +__isl_give isl_qpolynomial *isl_qpolynomial_mul_isl_int( + __isl_take isl_qpolynomial *qp, isl_int v) +{ + isl_poly *poly; + + if (isl_int_is_one(v)) + return qp; + + if (qp && isl_int_is_zero(v)) { + isl_qpolynomial *zero; + zero = isl_qpolynomial_zero_on_domain(isl_space_copy(qp->dim)); + isl_qpolynomial_free(qp); + return zero; + } + + poly = isl_qpolynomial_take_poly(qp); + poly = isl_poly_mul_isl_int(poly, v); + qp = isl_qpolynomial_restore_poly(qp, poly); + + return qp; +} + +__isl_give isl_qpolynomial *isl_qpolynomial_scale( + __isl_take isl_qpolynomial *qp, isl_int v) +{ + return isl_qpolynomial_mul_isl_int(qp, v); +} + +/* Multiply "qp" by "v". + */ +__isl_give isl_qpolynomial *isl_qpolynomial_scale_val( + __isl_take isl_qpolynomial *qp, __isl_take isl_val *v) +{ + isl_poly *poly; + + if (!qp || !v) + goto error; + + if (!isl_val_is_rat(v)) + isl_die(isl_qpolynomial_get_ctx(qp), isl_error_invalid, + "expecting rational factor", goto error); + + if (isl_val_is_one(v)) { + isl_val_free(v); + return qp; + } + + if (isl_val_is_zero(v)) { + isl_space *space; + + space = isl_qpolynomial_get_domain_space(qp); + isl_qpolynomial_free(qp); + isl_val_free(v); + return isl_qpolynomial_zero_on_domain(space); + } + + poly = isl_qpolynomial_take_poly(qp); + poly = isl_poly_scale_val(poly, v); + qp = isl_qpolynomial_restore_poly(qp, poly); + + isl_val_free(v); + return qp; +error: + isl_val_free(v); + isl_qpolynomial_free(qp); + return NULL; +} + +/* Divide "qp" by "v". + */ +__isl_give isl_qpolynomial *isl_qpolynomial_scale_down_val( + __isl_take isl_qpolynomial *qp, __isl_take isl_val *v) +{ + if (!qp || !v) + goto error; + + if (!isl_val_is_rat(v)) + isl_die(isl_qpolynomial_get_ctx(qp), isl_error_invalid, + "expecting rational factor", goto error); + if (isl_val_is_zero(v)) + isl_die(isl_val_get_ctx(v), isl_error_invalid, + "cannot scale down by zero", goto error); + + return isl_qpolynomial_scale_val(qp, isl_val_inv(v)); +error: + isl_val_free(v); + isl_qpolynomial_free(qp); + return NULL; +} + +__isl_give isl_qpolynomial *isl_qpolynomial_mul(__isl_take isl_qpolynomial *qp1, + __isl_take isl_qpolynomial *qp2) +{ + isl_bool compatible; + isl_poly *poly; + + if (isl_qpolynomial_check_equal_space(qp1, qp2) < 0) + goto error; + + if (qp1->div->n_row < qp2->div->n_row) + return isl_qpolynomial_mul(qp2, qp1); + + compatible = compatible_divs(qp1->div, qp2->div); + if (compatible < 0) + goto error; + if (!compatible) + return with_merged_divs(isl_qpolynomial_mul, qp1, qp2); + + poly = isl_qpolynomial_take_poly(qp1); + poly = isl_poly_mul(poly, isl_qpolynomial_get_poly(qp2)); + qp1 = isl_qpolynomial_restore_poly(qp1, poly); + + isl_qpolynomial_free(qp2); + + return qp1; +error: + isl_qpolynomial_free(qp1); + isl_qpolynomial_free(qp2); + return NULL; +} + +__isl_give isl_qpolynomial *isl_qpolynomial_pow(__isl_take isl_qpolynomial *qp, + unsigned power) +{ + isl_poly *poly; + + poly = isl_qpolynomial_take_poly(qp); + poly = isl_poly_pow(poly, power); + qp = isl_qpolynomial_restore_poly(qp, poly); + + return qp; +} + +__isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_pow( + __isl_take isl_pw_qpolynomial *pwqp, unsigned power) +{ + int i; + + if (power == 1) + return pwqp; + + pwqp = isl_pw_qpolynomial_cow(pwqp); + if (!pwqp) + return NULL; + + for (i = 0; i < pwqp->n; ++i) { + pwqp->p[i].qp = isl_qpolynomial_pow(pwqp->p[i].qp, power); + if (!pwqp->p[i].qp) + return isl_pw_qpolynomial_free(pwqp); + } + + return pwqp; +} + +__isl_give isl_qpolynomial *isl_qpolynomial_zero_on_domain( + __isl_take isl_space *domain) +{ + if (!domain) + return NULL; + return isl_qpolynomial_alloc(domain, 0, isl_poly_zero(domain->ctx)); +} + +__isl_give isl_qpolynomial *isl_qpolynomial_one_on_domain( + __isl_take isl_space *domain) +{ + if (!domain) + return NULL; + return isl_qpolynomial_alloc(domain, 0, isl_poly_one(domain->ctx)); +} + +__isl_give isl_qpolynomial *isl_qpolynomial_infty_on_domain( + __isl_take isl_space *domain) +{ + if (!domain) + return NULL; + return isl_qpolynomial_alloc(domain, 0, isl_poly_infty(domain->ctx)); +} + +__isl_give isl_qpolynomial *isl_qpolynomial_neginfty_on_domain( + __isl_take isl_space *domain) +{ + if (!domain) + return NULL; + return isl_qpolynomial_alloc(domain, 0, isl_poly_neginfty(domain->ctx)); +} + +__isl_give isl_qpolynomial *isl_qpolynomial_nan_on_domain( + __isl_take isl_space *domain) +{ + if (!domain) + return NULL; + return isl_qpolynomial_alloc(domain, 0, isl_poly_nan(domain->ctx)); +} + +__isl_give isl_qpolynomial *isl_qpolynomial_cst_on_domain( + __isl_take isl_space *domain, + isl_int v) +{ + struct isl_qpolynomial *qp; + isl_poly_cst *cst; + + qp = isl_qpolynomial_zero_on_domain(domain); + if (!qp) + return NULL; + + cst = isl_poly_as_cst(qp->poly); + isl_int_set(cst->n, v); + + return qp; +} + +isl_bool isl_qpolynomial_is_cst(__isl_keep isl_qpolynomial *qp, + isl_int *n, isl_int *d) +{ + isl_bool is_cst; + isl_poly_cst *cst; + + if (!qp) + return isl_bool_error; + + is_cst = isl_poly_is_cst(qp->poly); + if (is_cst < 0 || !is_cst) + return is_cst; + + cst = isl_poly_as_cst(qp->poly); + if (!cst) + return isl_bool_error; + + if (n) + isl_int_set(*n, cst->n); + if (d) + isl_int_set(*d, cst->d); + + return isl_bool_true; +} + +/* Return the constant term of "poly". + */ +static __isl_give isl_val *isl_poly_get_constant_val(__isl_keep isl_poly *poly) +{ + isl_bool is_cst; + isl_poly_cst *cst; + + if (!poly) + return NULL; + + while ((is_cst = isl_poly_is_cst(poly)) == isl_bool_false) { + isl_poly_rec *rec; + + rec = isl_poly_as_rec(poly); + if (!rec) + return NULL; + poly = rec->p[0]; + } + if (is_cst < 0) + return NULL; + + cst = isl_poly_as_cst(poly); + if (!cst) + return NULL; + return isl_val_rat_from_isl_int(cst->poly.ctx, cst->n, cst->d); +} + +/* Return the constant term of "qp". + */ +__isl_give isl_val *isl_qpolynomial_get_constant_val( + __isl_keep isl_qpolynomial *qp) +{ + if (!qp) + return NULL; + + return isl_poly_get_constant_val(qp->poly); +} + +isl_bool isl_poly_is_affine(__isl_keep isl_poly *poly) +{ + isl_bool is_cst; + isl_poly_rec *rec; + + if (!poly) + return isl_bool_error; + + if (poly->var < 0) + return isl_bool_true; + + rec = isl_poly_as_rec(poly); + if (!rec) + return isl_bool_error; + + if (rec->n > 2) + return isl_bool_false; + + isl_assert(poly->ctx, rec->n > 1, return isl_bool_error); + + is_cst = isl_poly_is_cst(rec->p[1]); + if (is_cst < 0 || !is_cst) + return is_cst; + + return isl_poly_is_affine(rec->p[0]); +} + +isl_bool isl_qpolynomial_is_affine(__isl_keep isl_qpolynomial *qp) +{ + if (!qp) + return isl_bool_error; + + if (qp->div->n_row > 0) + return isl_bool_false; + + return isl_poly_is_affine(qp->poly); +} + +static void update_coeff(__isl_keep isl_vec *aff, + __isl_keep isl_poly_cst *cst, int pos) +{ + isl_int gcd; + isl_int f; + + if (isl_int_is_zero(cst->n)) + return; + + isl_int_init(gcd); + isl_int_init(f); + isl_int_gcd(gcd, cst->d, aff->el[0]); + isl_int_divexact(f, cst->d, gcd); + isl_int_divexact(gcd, aff->el[0], gcd); + isl_seq_scale(aff->el, aff->el, f, aff->size); + isl_int_mul(aff->el[1 + pos], gcd, cst->n); + isl_int_clear(gcd); + isl_int_clear(f); +} + +int isl_poly_update_affine(__isl_keep isl_poly *poly, __isl_keep isl_vec *aff) +{ + isl_poly_cst *cst; + isl_poly_rec *rec; + + if (!poly || !aff) + return -1; + + if (poly->var < 0) { + isl_poly_cst *cst; + + cst = isl_poly_as_cst(poly); + if (!cst) + return -1; + update_coeff(aff, cst, 0); + return 0; + } + + rec = isl_poly_as_rec(poly); + if (!rec) + return -1; + isl_assert(poly->ctx, rec->n == 2, return -1); + + cst = isl_poly_as_cst(rec->p[1]); + if (!cst) + return -1; + update_coeff(aff, cst, 1 + poly->var); + + return isl_poly_update_affine(rec->p[0], aff); +} + +__isl_give isl_vec *isl_qpolynomial_extract_affine( + __isl_keep isl_qpolynomial *qp) +{ + isl_vec *aff; + isl_size d; + + d = isl_qpolynomial_domain_dim(qp, isl_dim_all); + if (d < 0) + return NULL; + + aff = isl_vec_alloc(qp->div->ctx, 2 + d); + if (!aff) + return NULL; + + isl_seq_clr(aff->el + 1, 1 + d); + isl_int_set_si(aff->el[0], 1); + + if (isl_poly_update_affine(qp->poly, aff) < 0) + goto error; + + return aff; +error: + isl_vec_free(aff); + return NULL; +} + +/* Compare two quasi-polynomials. + * + * Return -1 if "qp1" is "smaller" than "qp2", 1 if "qp1" is "greater" + * than "qp2" and 0 if they are equal. + */ +int isl_qpolynomial_plain_cmp(__isl_keep isl_qpolynomial *qp1, + __isl_keep isl_qpolynomial *qp2) +{ + int cmp; + + if (qp1 == qp2) + return 0; + if (!qp1) + return -1; + if (!qp2) + return 1; + + cmp = isl_space_cmp(qp1->dim, qp2->dim); + if (cmp != 0) + return cmp; + + cmp = isl_local_cmp(qp1->div, qp2->div); + if (cmp != 0) + return cmp; + + return isl_poly_plain_cmp(qp1->poly, qp2->poly); +} + +/* Is "qp1" obviously equal to "qp2"? + * + * NaN is not equal to anything, not even to another NaN. + */ +isl_bool isl_qpolynomial_plain_is_equal(__isl_keep isl_qpolynomial *qp1, + __isl_keep isl_qpolynomial *qp2) +{ + isl_bool equal; + + if (!qp1 || !qp2) + return isl_bool_error; + + if (isl_qpolynomial_is_nan(qp1) || isl_qpolynomial_is_nan(qp2)) + return isl_bool_false; + + equal = isl_space_is_equal(qp1->dim, qp2->dim); + if (equal < 0 || !equal) + return equal; + + equal = isl_mat_is_equal(qp1->div, qp2->div); + if (equal < 0 || !equal) + return equal; + + return isl_poly_is_equal(qp1->poly, qp2->poly); +} + +static isl_stat poly_update_den(__isl_keep isl_poly *poly, isl_int *d) +{ + int i; + isl_bool is_cst; + isl_poly_rec *rec; + + is_cst = isl_poly_is_cst(poly); + if (is_cst < 0) + return isl_stat_error; + if (is_cst) { + isl_poly_cst *cst; + cst = isl_poly_as_cst(poly); + if (!cst) + return isl_stat_error; + isl_int_lcm(*d, *d, cst->d); + return isl_stat_ok; + } + + rec = isl_poly_as_rec(poly); + if (!rec) + return isl_stat_error; + + for (i = 0; i < rec->n; ++i) + poly_update_den(rec->p[i], d); + + return isl_stat_ok; +} + +__isl_give isl_val *isl_qpolynomial_get_den(__isl_keep isl_qpolynomial *qp) +{ + isl_val *d; + + if (!qp) + return NULL; + d = isl_val_one(isl_qpolynomial_get_ctx(qp)); + if (!d) + return NULL; + if (poly_update_den(qp->poly, &d->n) < 0) + return isl_val_free(d); + return d; +} + +__isl_give isl_qpolynomial *isl_qpolynomial_var_pow_on_domain( + __isl_take isl_space *domain, int pos, int power) +{ + struct isl_ctx *ctx; + + if (!domain) + return NULL; + + ctx = domain->ctx; + + return isl_qpolynomial_alloc(domain, 0, + isl_poly_var_pow(ctx, pos, power)); +} + +__isl_give isl_qpolynomial *isl_qpolynomial_var_on_domain( + __isl_take isl_space *domain, enum isl_dim_type type, unsigned pos) +{ + isl_size off; + + if (isl_space_check_is_set(domain ) < 0) + goto error; + if (isl_space_check_range(domain, type, pos, 1) < 0) + goto error; + + off = isl_space_offset(domain, type); + if (off < 0) + goto error; + + return isl_qpolynomial_var_pow_on_domain(domain, off + pos, 1); +error: + isl_space_free(domain); + return NULL; +} + +__isl_give isl_poly *isl_poly_subs(__isl_take isl_poly *poly, + unsigned first, unsigned n, __isl_keep isl_poly **subs) +{ + int i; + isl_bool is_cst; + isl_poly_rec *rec; + isl_poly *base, *res; + + is_cst = isl_poly_is_cst(poly); + if (is_cst < 0) + return isl_poly_free(poly); + if (is_cst) + return poly; + + if (poly->var < first) + return poly; + + rec = isl_poly_as_rec(poly); + if (!rec) + goto error; + + isl_assert(poly->ctx, rec->n >= 1, goto error); + + if (poly->var >= first + n) + base = isl_poly_var_pow(poly->ctx, poly->var, 1); + else + base = isl_poly_copy(subs[poly->var - first]); + + res = isl_poly_subs(isl_poly_copy(rec->p[rec->n - 1]), first, n, subs); + for (i = rec->n - 2; i >= 0; --i) { + isl_poly *t; + t = isl_poly_subs(isl_poly_copy(rec->p[i]), first, n, subs); + res = isl_poly_mul(res, isl_poly_copy(base)); + res = isl_poly_sum(res, t); + } + + isl_poly_free(base); + isl_poly_free(poly); + + return res; +error: + isl_poly_free(poly); + return NULL; +} + +__isl_give isl_poly *isl_poly_from_affine(isl_ctx *ctx, isl_int *f, + isl_int denom, unsigned len) +{ + int i; + isl_poly *poly; + + isl_assert(ctx, len >= 1, return NULL); + + poly = isl_poly_rat_cst(ctx, f[0], denom); + for (i = 0; i < len - 1; ++i) { + isl_poly *t; + isl_poly *c; + + if (isl_int_is_zero(f[1 + i])) + continue; + + c = isl_poly_rat_cst(ctx, f[1 + i], denom); + t = isl_poly_var_pow(ctx, i, 1); + t = isl_poly_mul(c, t); + poly = isl_poly_sum(poly, t); + } + + return poly; +} + +/* Remove common factor of non-constant terms and denominator. + */ +static void normalize_div(__isl_keep isl_qpolynomial *qp, int div) +{ + isl_ctx *ctx = qp->div->ctx; + unsigned total = qp->div->n_col - 2; + + isl_seq_gcd(qp->div->row[div] + 2, total, &ctx->normalize_gcd); + isl_int_gcd(ctx->normalize_gcd, + ctx->normalize_gcd, qp->div->row[div][0]); + if (isl_int_is_one(ctx->normalize_gcd)) + return; + + isl_seq_scale_down(qp->div->row[div] + 2, qp->div->row[div] + 2, + ctx->normalize_gcd, total); + isl_int_divexact(qp->div->row[div][0], qp->div->row[div][0], + ctx->normalize_gcd); + isl_int_fdiv_q(qp->div->row[div][1], qp->div->row[div][1], + ctx->normalize_gcd); +} + +/* Replace the integer division identified by "div" by the polynomial "s". + * The integer division is assumed not to appear in the definition + * of any other integer divisions. + */ +static __isl_give isl_qpolynomial *substitute_div( + __isl_take isl_qpolynomial *qp, int div, __isl_take isl_poly *s) +{ + int i; + isl_size div_pos; + int *reordering; + isl_ctx *ctx; + + if (!qp || !s) + goto error; + + qp = isl_qpolynomial_cow(qp); + if (!qp) + goto error; + + div_pos = isl_qpolynomial_domain_var_offset(qp, isl_dim_div); + if (div_pos < 0) + goto error; + qp->poly = isl_poly_subs(qp->poly, div_pos + div, 1, &s); + if (!qp->poly) + goto error; + + ctx = isl_qpolynomial_get_ctx(qp); + reordering = isl_alloc_array(ctx, int, div_pos + qp->div->n_row); + if (!reordering) + goto error; + for (i = 0; i < div_pos + div; ++i) + reordering[i] = i; + for (i = div_pos + div + 1; i < div_pos + qp->div->n_row; ++i) + reordering[i] = i - 1; + qp->div = isl_mat_drop_rows(qp->div, div, 1); + qp->div = isl_mat_drop_cols(qp->div, 2 + div_pos + div, 1); + qp->poly = reorder(qp->poly, reordering); + free(reordering); + + if (!qp->poly || !qp->div) + goto error; + + isl_poly_free(s); + return qp; +error: + isl_qpolynomial_free(qp); + isl_poly_free(s); + return NULL; +} + +/* Replace all integer divisions [e/d] that turn out to not actually be integer + * divisions because d is equal to 1 by their definition, i.e., e. + */ +static __isl_give isl_qpolynomial *substitute_non_divs( + __isl_take isl_qpolynomial *qp) +{ + int i, j; + isl_size div_pos; + isl_poly *s; + + div_pos = isl_qpolynomial_domain_var_offset(qp, isl_dim_div); + if (div_pos < 0) + return isl_qpolynomial_free(qp); + + for (i = 0; qp && i < qp->div->n_row; ++i) { + if (!isl_int_is_one(qp->div->row[i][0])) + continue; + for (j = i + 1; j < qp->div->n_row; ++j) { + if (isl_int_is_zero(qp->div->row[j][2 + div_pos + i])) + continue; + isl_seq_combine(qp->div->row[j] + 1, + qp->div->ctx->one, qp->div->row[j] + 1, + qp->div->row[j][2 + div_pos + i], + qp->div->row[i] + 1, 1 + div_pos + i); + isl_int_set_si(qp->div->row[j][2 + div_pos + i], 0); + normalize_div(qp, j); + } + s = isl_poly_from_affine(qp->dim->ctx, qp->div->row[i] + 1, + qp->div->row[i][0], qp->div->n_col - 1); + qp = substitute_div(qp, i, s); + --i; + } + + return qp; +} + +/* Reduce the coefficients of div "div" to lie in the interval [0, d-1], + * with d the denominator. When replacing the coefficient e of x by + * d * frac(e/d) = e - d * floor(e/d), we are subtracting d * floor(e/d) * x + * inside the division, so we need to add floor(e/d) * x outside. + * That is, we replace q by q' + floor(e/d) * x and we therefore need + * to adjust the coefficient of x in each later div that depends on the + * current div "div" and also in the affine expressions in the rows of "mat" + * (if they too depend on "div"). + */ +static void reduce_div(__isl_keep isl_qpolynomial *qp, int div, + __isl_keep isl_mat **mat) +{ + int i, j; + isl_int v; + unsigned total = qp->div->n_col - qp->div->n_row - 2; + + isl_int_init(v); + for (i = 0; i < 1 + total + div; ++i) { + if (isl_int_is_nonneg(qp->div->row[div][1 + i]) && + isl_int_lt(qp->div->row[div][1 + i], qp->div->row[div][0])) + continue; + isl_int_fdiv_q(v, qp->div->row[div][1 + i], qp->div->row[div][0]); + isl_int_fdiv_r(qp->div->row[div][1 + i], + qp->div->row[div][1 + i], qp->div->row[div][0]); + *mat = isl_mat_col_addmul(*mat, i, v, 1 + total + div); + for (j = div + 1; j < qp->div->n_row; ++j) { + if (isl_int_is_zero(qp->div->row[j][2 + total + div])) + continue; + isl_int_addmul(qp->div->row[j][1 + i], + v, qp->div->row[j][2 + total + div]); + } + } + isl_int_clear(v); +} + +/* Check if the last non-zero coefficient is bigger that half of the + * denominator. If so, we will invert the div to further reduce the number + * of distinct divs that may appear. + * If the last non-zero coefficient is exactly half the denominator, + * then we continue looking for earlier coefficients that are bigger + * than half the denominator. + */ +static int needs_invert(__isl_keep isl_mat *div, int row) +{ + int i; + int cmp; + + for (i = div->n_col - 1; i >= 1; --i) { + if (isl_int_is_zero(div->row[row][i])) + continue; + isl_int_mul_ui(div->row[row][i], div->row[row][i], 2); + cmp = isl_int_cmp(div->row[row][i], div->row[row][0]); + isl_int_divexact_ui(div->row[row][i], div->row[row][i], 2); + if (cmp) + return cmp > 0; + if (i == 1) + return 1; + } + + return 0; +} + +/* Replace div "div" q = [e/d] by -[(-e+(d-1))/d]. + * We only invert the coefficients of e (and the coefficient of q in + * later divs and in the rows of "mat"). After calling this function, the + * coefficients of e should be reduced again. + */ +static void invert_div(__isl_keep isl_qpolynomial *qp, int div, + __isl_keep isl_mat **mat) +{ + unsigned total = qp->div->n_col - qp->div->n_row - 2; + + isl_seq_neg(qp->div->row[div] + 1, + qp->div->row[div] + 1, qp->div->n_col - 1); + isl_int_sub_ui(qp->div->row[div][1], qp->div->row[div][1], 1); + isl_int_add(qp->div->row[div][1], + qp->div->row[div][1], qp->div->row[div][0]); + *mat = isl_mat_col_neg(*mat, 1 + total + div); + isl_mat_col_mul(qp->div, 2 + total + div, + qp->div->ctx->negone, 2 + total + div); +} + +/* Reduce all divs of "qp" to have coefficients + * in the interval [0, d-1], with d the denominator and such that the + * last non-zero coefficient that is not equal to d/2 is smaller than d/2. + * The modifications to the integer divisions need to be reflected + * in the factors of the polynomial that refer to the original + * integer divisions. To this end, the modifications are collected + * as a set of affine expressions and then plugged into the polynomial. + * + * After the reduction, some divs may have become redundant or identical, + * so we call substitute_non_divs and sort_divs. If these functions + * eliminate divs or merge two or more divs into one, the coefficients + * of the enclosing divs may have to be reduced again, so we call + * ourselves recursively if the number of divs decreases. + */ +static __isl_give isl_qpolynomial *reduce_divs(__isl_take isl_qpolynomial *qp) +{ + int i; + isl_ctx *ctx; + isl_mat *mat; + isl_poly **s; + unsigned o_div; + isl_size n_div, total, new_n_div; + + total = isl_qpolynomial_domain_dim(qp, isl_dim_all); + n_div = isl_qpolynomial_domain_dim(qp, isl_dim_div); + o_div = isl_qpolynomial_domain_offset(qp, isl_dim_div); + if (total < 0 || n_div < 0) + return isl_qpolynomial_free(qp); + ctx = isl_qpolynomial_get_ctx(qp); + mat = isl_mat_zero(ctx, n_div, 1 + total); + + for (i = 0; i < n_div; ++i) + mat = isl_mat_set_element_si(mat, i, o_div + i, 1); + + for (i = 0; i < qp->div->n_row; ++i) { + normalize_div(qp, i); + reduce_div(qp, i, &mat); + if (needs_invert(qp->div, i)) { + invert_div(qp, i, &mat); + reduce_div(qp, i, &mat); + } + } + if (!mat) + goto error; + + s = isl_alloc_array(ctx, struct isl_poly *, n_div); + if (n_div && !s) + goto error; + for (i = 0; i < n_div; ++i) + s[i] = isl_poly_from_affine(ctx, mat->row[i], ctx->one, + 1 + total); + qp->poly = isl_poly_subs(qp->poly, o_div - 1, n_div, s); + for (i = 0; i < n_div; ++i) + isl_poly_free(s[i]); + free(s); + if (!qp->poly) + goto error; + + isl_mat_free(mat); + + qp = substitute_non_divs(qp); + qp = sort_divs(qp); + new_n_div = isl_qpolynomial_domain_dim(qp, isl_dim_div); + if (new_n_div < 0) + return isl_qpolynomial_free(qp); + if (new_n_div < n_div) + return reduce_divs(qp); + + return qp; +error: + isl_qpolynomial_free(qp); + isl_mat_free(mat); + return NULL; +} + +__isl_give isl_qpolynomial *isl_qpolynomial_rat_cst_on_domain( + __isl_take isl_space *domain, const isl_int n, const isl_int d) +{ + struct isl_qpolynomial *qp; + isl_poly_cst *cst; + + qp = isl_qpolynomial_zero_on_domain(domain); + if (!qp) + return NULL; + + cst = isl_poly_as_cst(qp->poly); + isl_int_set(cst->n, n); + isl_int_set(cst->d, d); + + return qp; +} + +/* Return an isl_qpolynomial that is equal to "val" on domain space "domain". + */ +__isl_give isl_qpolynomial *isl_qpolynomial_val_on_domain( + __isl_take isl_space *domain, __isl_take isl_val *val) +{ + isl_qpolynomial *qp; + isl_poly_cst *cst; + + qp = isl_qpolynomial_zero_on_domain(domain); + if (!qp || !val) + goto error; + + cst = isl_poly_as_cst(qp->poly); + isl_int_set(cst->n, val->n); + isl_int_set(cst->d, val->d); + + isl_val_free(val); + return qp; +error: + isl_val_free(val); + isl_qpolynomial_free(qp); + return NULL; +} + +static isl_stat poly_set_active(__isl_keep isl_poly *poly, int *active, int d) +{ + isl_bool is_cst; + isl_poly_rec *rec; + int i; + + is_cst = isl_poly_is_cst(poly); + if (is_cst < 0) + return isl_stat_error; + if (is_cst) + return isl_stat_ok; + + if (poly->var < d) + active[poly->var] = 1; + + rec = isl_poly_as_rec(poly); + for (i = 0; i < rec->n; ++i) + if (poly_set_active(rec->p[i], active, d) < 0) + return isl_stat_error; + + return isl_stat_ok; +} + +static isl_stat set_active(__isl_keep isl_qpolynomial *qp, int *active) +{ + int i, j; + isl_size d; + isl_space *space; + + space = isl_qpolynomial_peek_domain_space(qp); + d = isl_space_dim(space, isl_dim_all); + if (d < 0 || !active) + return isl_stat_error; + + for (i = 0; i < d; ++i) + for (j = 0; j < qp->div->n_row; ++j) { + if (isl_int_is_zero(qp->div->row[j][2 + i])) + continue; + active[i] = 1; + break; + } + + return poly_set_active(qp->poly, active, d); +} + +#undef TYPE +#define TYPE isl_qpolynomial +static +#include "check_type_range_templ.c" + +isl_bool isl_qpolynomial_involves_dims(__isl_keep isl_qpolynomial *qp, + enum isl_dim_type type, unsigned first, unsigned n) +{ + int i; + int *active = NULL; + isl_bool involves = isl_bool_false; + isl_size offset; + isl_size d; + isl_space *space; + + if (!qp) + return isl_bool_error; + if (n == 0) + return isl_bool_false; + + if (isl_qpolynomial_check_range(qp, type, first, n) < 0) + return isl_bool_error; + isl_assert(qp->dim->ctx, type == isl_dim_param || + type == isl_dim_in, return isl_bool_error); + + space = isl_qpolynomial_peek_domain_space(qp); + d = isl_space_dim(space, isl_dim_all); + if (d < 0) + return isl_bool_error; + active = isl_calloc_array(qp->dim->ctx, int, d); + if (set_active(qp, active) < 0) + goto error; + + offset = isl_qpolynomial_domain_var_offset(qp, domain_type(type)); + if (offset < 0) + goto error; + first += offset; + for (i = 0; i < n; ++i) + if (active[first + i]) { + involves = isl_bool_true; + break; + } + + free(active); + + return involves; +error: + free(active); + return isl_bool_error; +} + +/* Remove divs that do not appear in the quasi-polynomial, nor in any + * of the divs that do appear in the quasi-polynomial. + */ +static __isl_give isl_qpolynomial *remove_redundant_divs( + __isl_take isl_qpolynomial *qp) +{ + int i, j; + isl_size div_pos; + int len; + int skip; + int *active = NULL; + int *reordering = NULL; + int redundant = 0; + int n_div; + isl_ctx *ctx; + + if (!qp) + return NULL; + if (qp->div->n_row == 0) + return qp; + + div_pos = isl_qpolynomial_domain_var_offset(qp, isl_dim_div); + if (div_pos < 0) + return isl_qpolynomial_free(qp); + len = qp->div->n_col - 2; + ctx = isl_qpolynomial_get_ctx(qp); + active = isl_calloc_array(ctx, int, len); + if (!active) + goto error; + + if (poly_set_active(qp->poly, active, len) < 0) + goto error; + + for (i = qp->div->n_row - 1; i >= 0; --i) { + if (!active[div_pos + i]) { + redundant = 1; + continue; + } + for (j = 0; j < i; ++j) { + if (isl_int_is_zero(qp->div->row[i][2 + div_pos + j])) + continue; + active[div_pos + j] = 1; + break; + } + } + + if (!redundant) { + free(active); + return qp; + } + + reordering = isl_alloc_array(qp->div->ctx, int, len); + if (!reordering) + goto error; + + for (i = 0; i < div_pos; ++i) + reordering[i] = i; + + skip = 0; + n_div = qp->div->n_row; + for (i = 0; i < n_div; ++i) { + if (!active[div_pos + i]) { + qp->div = isl_mat_drop_rows(qp->div, i - skip, 1); + qp->div = isl_mat_drop_cols(qp->div, + 2 + div_pos + i - skip, 1); + skip++; + } + reordering[div_pos + i] = div_pos + i - skip; + } + + qp->poly = reorder(qp->poly, reordering); + + if (!qp->poly || !qp->div) + goto error; + + free(active); + free(reordering); + + return qp; +error: + free(active); + free(reordering); + isl_qpolynomial_free(qp); + return NULL; +} + +__isl_give isl_poly *isl_poly_drop(__isl_take isl_poly *poly, + unsigned first, unsigned n) +{ + int i; + isl_poly_rec *rec; + + if (!poly) + return NULL; + if (n == 0 || poly->var < 0 || poly->var < first) + return poly; + if (poly->var < first + n) { + poly = replace_by_constant_term(poly); + return isl_poly_drop(poly, first, n); + } + poly = isl_poly_cow(poly); + if (!poly) + return NULL; + poly->var -= n; + rec = isl_poly_as_rec(poly); + if (!rec) + goto error; + + for (i = 0; i < rec->n; ++i) { + rec->p[i] = isl_poly_drop(rec->p[i], first, n); + if (!rec->p[i]) + goto error; + } + + return poly; +error: + isl_poly_free(poly); + return NULL; +} + +__isl_give isl_qpolynomial *isl_qpolynomial_set_dim_name( + __isl_take isl_qpolynomial *qp, + enum isl_dim_type type, unsigned pos, const char *s) +{ + isl_space *space; + + if (!qp) + return NULL; + if (type == isl_dim_out) + isl_die(isl_qpolynomial_get_ctx(qp), isl_error_invalid, + "cannot set name of output/set dimension", + return isl_qpolynomial_free(qp)); + type = domain_type(type); + space = isl_qpolynomial_take_domain_space(qp); + space = isl_space_set_dim_name(space, type, pos, s); + qp = isl_qpolynomial_restore_domain_space(qp, space); + return qp; +} + +__isl_give isl_qpolynomial *isl_qpolynomial_drop_dims( + __isl_take isl_qpolynomial *qp, + enum isl_dim_type type, unsigned first, unsigned n) +{ + isl_space *space; + isl_size offset; + + if (!qp) + return NULL; + if (type == isl_dim_out) + isl_die(qp->dim->ctx, isl_error_invalid, + "cannot drop output/set dimension", + goto error); + if (isl_qpolynomial_check_range(qp, type, first, n) < 0) + return isl_qpolynomial_free(qp); + type = domain_type(type); + if (n == 0 && !isl_space_is_named_or_nested(qp->dim, type)) + return qp; + + + isl_assert(qp->dim->ctx, type == isl_dim_param || + type == isl_dim_set, goto error); + + space = isl_qpolynomial_take_domain_space(qp); + space = isl_space_drop_dims(space, type, first, n); + qp = isl_qpolynomial_restore_domain_space(qp, space); + + qp = isl_qpolynomial_cow(qp); + if (!qp) + return NULL; + + offset = isl_qpolynomial_domain_var_offset(qp, type); + if (offset < 0) + goto error; + first += offset; + + qp->div = isl_mat_drop_cols(qp->div, 2 + first, n); + if (!qp->div) + goto error; + + qp->poly = isl_poly_drop(qp->poly, first, n); + if (!qp->poly) + goto error; + + return qp; +error: + isl_qpolynomial_free(qp); + return NULL; +} + +/* Project the domain of the quasi-polynomial onto its parameter space. + * The quasi-polynomial may not involve any of the domain dimensions. + */ +__isl_give isl_qpolynomial *isl_qpolynomial_project_domain_on_params( + __isl_take isl_qpolynomial *qp) +{ + isl_space *space; + isl_size n; + isl_bool involves; + + n = isl_qpolynomial_dim(qp, isl_dim_in); + if (n < 0) + return isl_qpolynomial_free(qp); + involves = isl_qpolynomial_involves_dims(qp, isl_dim_in, 0, n); + if (involves < 0) + return isl_qpolynomial_free(qp); + if (involves) + isl_die(isl_qpolynomial_get_ctx(qp), isl_error_invalid, + "polynomial involves some of the domain dimensions", + return isl_qpolynomial_free(qp)); + qp = isl_qpolynomial_drop_dims(qp, isl_dim_in, 0, n); + space = isl_qpolynomial_get_domain_space(qp); + space = isl_space_params(space); + qp = isl_qpolynomial_reset_domain_space(qp, space); + return qp; +} + +static __isl_give isl_qpolynomial *isl_qpolynomial_substitute_equalities_lifted( + __isl_take isl_qpolynomial *qp, __isl_take isl_basic_set *eq) +{ + int i, j, k; + isl_int denom; + unsigned total; + unsigned n_div; + isl_poly *poly; + + if (!eq) + goto error; + if (eq->n_eq == 0) { + isl_basic_set_free(eq); + return qp; + } + + qp = isl_qpolynomial_cow(qp); + if (!qp) + goto error; + qp->div = isl_mat_cow(qp->div); + if (!qp->div) + goto error; + + total = isl_basic_set_offset(eq, isl_dim_div); + n_div = eq->n_div; + isl_int_init(denom); + for (i = 0; i < eq->n_eq; ++i) { + j = isl_seq_last_non_zero(eq->eq[i], total + n_div); + if (j < 0 || j == 0 || j >= total) + continue; + + for (k = 0; k < qp->div->n_row; ++k) { + if (isl_int_is_zero(qp->div->row[k][1 + j])) + continue; + isl_seq_elim(qp->div->row[k] + 1, eq->eq[i], j, total, + &qp->div->row[k][0]); + normalize_div(qp, k); + } + + if (isl_int_is_pos(eq->eq[i][j])) + isl_seq_neg(eq->eq[i], eq->eq[i], total); + isl_int_abs(denom, eq->eq[i][j]); + isl_int_set_si(eq->eq[i][j], 0); + + poly = isl_poly_from_affine(qp->dim->ctx, + eq->eq[i], denom, total); + qp->poly = isl_poly_subs(qp->poly, j - 1, 1, &poly); + isl_poly_free(poly); + } + isl_int_clear(denom); + + if (!qp->poly) + goto error; + + isl_basic_set_free(eq); + + qp = substitute_non_divs(qp); + qp = sort_divs(qp); + + return qp; +error: + isl_basic_set_free(eq); + isl_qpolynomial_free(qp); + return NULL; +} + +/* Exploit the equalities in "eq" to simplify the quasi-polynomial. + */ +__isl_give isl_qpolynomial *isl_qpolynomial_substitute_equalities( + __isl_take isl_qpolynomial *qp, __isl_take isl_basic_set *eq) +{ + if (!qp || !eq) + goto error; + if (qp->div->n_row > 0) + eq = isl_basic_set_add_dims(eq, isl_dim_set, qp->div->n_row); + return isl_qpolynomial_substitute_equalities_lifted(qp, eq); +error: + isl_basic_set_free(eq); + isl_qpolynomial_free(qp); + return NULL; +} + +/* Look for equalities among the variables shared by context and qp + * and the integer divisions of qp, if any. + * The equalities are then used to eliminate variables and/or integer + * divisions from qp. + */ +__isl_give isl_qpolynomial *isl_qpolynomial_gist( + __isl_take isl_qpolynomial *qp, __isl_take isl_set *context) +{ + isl_local_space *ls; + isl_basic_set *aff; + + ls = isl_qpolynomial_get_domain_local_space(qp); + context = isl_local_space_lift_set(ls, context); + + aff = isl_set_affine_hull(context); + return isl_qpolynomial_substitute_equalities_lifted(qp, aff); +} + +__isl_give isl_qpolynomial *isl_qpolynomial_gist_params( + __isl_take isl_qpolynomial *qp, __isl_take isl_set *context) +{ + isl_space *space = isl_qpolynomial_get_domain_space(qp); + isl_set *dom_context = isl_set_universe(space); + dom_context = isl_set_intersect_params(dom_context, context); + return isl_qpolynomial_gist(qp, dom_context); +} + +/* Return a zero isl_qpolynomial in the given space. + * + * This is a helper function for isl_pw_*_as_* that ensures a uniform + * interface over all piecewise types. + */ +static __isl_give isl_qpolynomial *isl_qpolynomial_zero_in_space( + __isl_take isl_space *space) +{ + return isl_qpolynomial_zero_on_domain(isl_space_domain(space)); +} + +#define isl_qpolynomial_involves_nan isl_qpolynomial_is_nan + +#undef PW +#define PW isl_pw_qpolynomial +#undef BASE +#define BASE qpolynomial +#undef EL_IS_ZERO +#define EL_IS_ZERO is_zero +#undef ZERO +#define ZERO zero +#undef IS_ZERO +#define IS_ZERO is_zero +#undef FIELD +#define FIELD qp +#undef DEFAULT_IS_ZERO +#define DEFAULT_IS_ZERO 1 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#undef BASE +#define BASE pw_qpolynomial + +#include +#include +#include +#include +#include + +int isl_pw_qpolynomial_is_one(__isl_keep isl_pw_qpolynomial *pwqp) +{ + if (!pwqp) + return -1; + + if (pwqp->n != -1) + return 0; + + if (!isl_set_plain_is_universe(pwqp->p[0].set)) + return 0; + + return isl_qpolynomial_is_one(pwqp->p[0].qp); +} + +__isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_add( + __isl_take isl_pw_qpolynomial *pwqp1, + __isl_take isl_pw_qpolynomial *pwqp2) +{ + return isl_pw_qpolynomial_union_add_(pwqp1, pwqp2); +} + +__isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_mul( + __isl_take isl_pw_qpolynomial *pwqp1, + __isl_take isl_pw_qpolynomial *pwqp2) +{ + int i, j, n; + struct isl_pw_qpolynomial *res; + + if (!pwqp1 || !pwqp2) + goto error; + + isl_assert(pwqp1->dim->ctx, isl_space_is_equal(pwqp1->dim, pwqp2->dim), + goto error); + + if (isl_pw_qpolynomial_is_zero(pwqp1)) { + isl_pw_qpolynomial_free(pwqp2); + return pwqp1; + } + + if (isl_pw_qpolynomial_is_zero(pwqp2)) { + isl_pw_qpolynomial_free(pwqp1); + return pwqp2; + } + + if (isl_pw_qpolynomial_is_one(pwqp1)) { + isl_pw_qpolynomial_free(pwqp1); + return pwqp2; + } + + if (isl_pw_qpolynomial_is_one(pwqp2)) { + isl_pw_qpolynomial_free(pwqp2); + return pwqp1; + } + + n = pwqp1->n * pwqp2->n; + res = isl_pw_qpolynomial_alloc_size(isl_space_copy(pwqp1->dim), n); + + for (i = 0; i < pwqp1->n; ++i) { + for (j = 0; j < pwqp2->n; ++j) { + struct isl_set *common; + struct isl_qpolynomial *prod; + common = isl_set_intersect(isl_set_copy(pwqp1->p[i].set), + isl_set_copy(pwqp2->p[j].set)); + if (isl_set_plain_is_empty(common)) { + isl_set_free(common); + continue; + } + + prod = isl_qpolynomial_mul( + isl_qpolynomial_copy(pwqp1->p[i].qp), + isl_qpolynomial_copy(pwqp2->p[j].qp)); + + res = isl_pw_qpolynomial_add_piece(res, common, prod); + } + } + + isl_pw_qpolynomial_free(pwqp1); + isl_pw_qpolynomial_free(pwqp2); + + return res; +error: + isl_pw_qpolynomial_free(pwqp1); + isl_pw_qpolynomial_free(pwqp2); + return NULL; +} + +__isl_give isl_val *isl_poly_eval(__isl_take isl_poly *poly, + __isl_take isl_vec *vec) +{ + int i; + isl_bool is_cst; + isl_poly_rec *rec; + isl_val *res; + isl_val *base; + + is_cst = isl_poly_is_cst(poly); + if (is_cst < 0) + goto error; + if (is_cst) { + isl_vec_free(vec); + res = isl_poly_get_constant_val(poly); + isl_poly_free(poly); + return res; + } + + rec = isl_poly_as_rec(poly); + if (!rec || !vec) + goto error; + + isl_assert(poly->ctx, rec->n >= 1, goto error); + + base = isl_val_rat_from_isl_int(poly->ctx, + vec->el[1 + poly->var], vec->el[0]); + + res = isl_poly_eval(isl_poly_copy(rec->p[rec->n - 1]), + isl_vec_copy(vec)); + + for (i = rec->n - 2; i >= 0; --i) { + res = isl_val_mul(res, isl_val_copy(base)); + res = isl_val_add(res, isl_poly_eval(isl_poly_copy(rec->p[i]), + isl_vec_copy(vec))); + } + + isl_val_free(base); + isl_poly_free(poly); + isl_vec_free(vec); + return res; +error: + isl_poly_free(poly); + isl_vec_free(vec); + return NULL; +} + +/* Evaluate "qp" in the void point "pnt". + * In particular, return the value NaN. + */ +static __isl_give isl_val *eval_void(__isl_take isl_qpolynomial *qp, + __isl_take isl_point *pnt) +{ + isl_ctx *ctx; + + ctx = isl_point_get_ctx(pnt); + isl_qpolynomial_free(qp); + isl_point_free(pnt); + return isl_val_nan(ctx); +} + +__isl_give isl_val *isl_qpolynomial_eval(__isl_take isl_qpolynomial *qp, + __isl_take isl_point *pnt) +{ + isl_bool is_void; + isl_vec *ext; + isl_val *v; + + if (!qp || !pnt) + goto error; + isl_assert(pnt->dim->ctx, isl_space_is_equal(pnt->dim, qp->dim), goto error); + is_void = isl_point_is_void(pnt); + if (is_void < 0) + goto error; + if (is_void) + return eval_void(qp, pnt); + + ext = isl_local_extend_point_vec(qp->div, isl_vec_copy(pnt->vec)); + + v = isl_poly_eval(isl_qpolynomial_get_poly(qp), ext); + + isl_qpolynomial_free(qp); + isl_point_free(pnt); + + return v; +error: + isl_qpolynomial_free(qp); + isl_point_free(pnt); + return NULL; +} + +int isl_poly_cmp(__isl_keep isl_poly_cst *cst1, __isl_keep isl_poly_cst *cst2) +{ + int cmp; + isl_int t; + isl_int_init(t); + isl_int_mul(t, cst1->n, cst2->d); + isl_int_submul(t, cst2->n, cst1->d); + cmp = isl_int_sgn(t); + isl_int_clear(t); + return cmp; +} + +__isl_give isl_qpolynomial *isl_qpolynomial_insert_dims( + __isl_take isl_qpolynomial *qp, enum isl_dim_type type, + unsigned first, unsigned n) +{ + unsigned total; + unsigned g_pos; + int *exp; + isl_space *space; + + if (!qp) + return NULL; + if (type == isl_dim_out) + isl_die(qp->div->ctx, isl_error_invalid, + "cannot insert output/set dimensions", + goto error); + if (isl_qpolynomial_check_range(qp, type, first, 0) < 0) + return isl_qpolynomial_free(qp); + type = domain_type(type); + if (n == 0 && !isl_space_is_named_or_nested(qp->dim, type)) + return qp; + + qp = isl_qpolynomial_cow(qp); + if (!qp) + return NULL; + + g_pos = pos(qp->dim, type) + first; + + qp->div = isl_mat_insert_zero_cols(qp->div, 2 + g_pos, n); + if (!qp->div) + goto error; + + total = qp->div->n_col - 2; + if (total > g_pos) { + int i; + exp = isl_alloc_array(qp->div->ctx, int, total - g_pos); + if (!exp) + goto error; + for (i = 0; i < total - g_pos; ++i) + exp[i] = i + n; + qp->poly = expand(qp->poly, exp, g_pos); + free(exp); + if (!qp->poly) + goto error; + } + + space = isl_qpolynomial_take_domain_space(qp); + space = isl_space_insert_dims(space, type, first, n); + qp = isl_qpolynomial_restore_domain_space(qp, space); + + return qp; +error: + isl_qpolynomial_free(qp); + return NULL; +} + +__isl_give isl_qpolynomial *isl_qpolynomial_add_dims( + __isl_take isl_qpolynomial *qp, enum isl_dim_type type, unsigned n) +{ + isl_size pos; + + pos = isl_qpolynomial_dim(qp, type); + if (pos < 0) + return isl_qpolynomial_free(qp); + + return isl_qpolynomial_insert_dims(qp, type, pos, n); +} + +static int *reordering_move(isl_ctx *ctx, + unsigned len, unsigned dst, unsigned src, unsigned n) +{ + int i; + int *reordering; + + reordering = isl_alloc_array(ctx, int, len); + if (!reordering) + return NULL; + + if (dst <= src) { + for (i = 0; i < dst; ++i) + reordering[i] = i; + for (i = 0; i < n; ++i) + reordering[src + i] = dst + i; + for (i = 0; i < src - dst; ++i) + reordering[dst + i] = dst + n + i; + for (i = 0; i < len - src - n; ++i) + reordering[src + n + i] = src + n + i; + } else { + for (i = 0; i < src; ++i) + reordering[i] = i; + for (i = 0; i < n; ++i) + reordering[src + i] = dst + i; + for (i = 0; i < dst - src; ++i) + reordering[src + n + i] = src + i; + for (i = 0; i < len - dst - n; ++i) + reordering[dst + n + i] = dst + n + i; + } + + return reordering; +} + +/* Move the "n" variables starting at "src_pos" of "qp" to "dst_pos". + * Only modify the polynomial expression and the local variables of "qp". + * The caller is responsible for modifying the space accordingly. + */ +static __isl_give isl_qpolynomial *local_poly_move_dims( + __isl_take isl_qpolynomial *qp, + unsigned dst_pos, unsigned src_pos, unsigned n) +{ + isl_ctx *ctx; + isl_size total; + int *reordering; + isl_local *local; + isl_poly *poly; + + local = isl_qpolynomial_take_local(qp); + local = isl_local_move_vars(local, dst_pos, src_pos, n); + qp = isl_qpolynomial_restore_local(qp, local); + qp = sort_divs(qp); + + total = isl_qpolynomial_domain_dim(qp, isl_dim_all); + if (total < 0) + return isl_qpolynomial_free(qp); + ctx = isl_qpolynomial_get_ctx(qp); + reordering = reordering_move(ctx, total, dst_pos, src_pos, n); + if (!reordering) + return isl_qpolynomial_free(qp); + + poly = isl_qpolynomial_take_poly(qp); + poly = reorder(poly, reordering); + qp = isl_qpolynomial_restore_poly(qp, poly); + free(reordering); + + return qp; +} + +__isl_give isl_qpolynomial *isl_qpolynomial_move_dims( + __isl_take isl_qpolynomial *qp, + enum isl_dim_type dst_type, unsigned dst_pos, + enum isl_dim_type src_type, unsigned src_pos, unsigned n) +{ + isl_ctx *ctx; + unsigned g_dst_pos; + unsigned g_src_pos; + isl_size src_off, dst_off; + isl_space *space; + + if (!qp) + return NULL; + + ctx = isl_qpolynomial_get_ctx(qp); + if (dst_type == isl_dim_out || src_type == isl_dim_out) + isl_die(ctx, isl_error_invalid, + "cannot move output/set dimension", + return isl_qpolynomial_free(qp)); + if (src_type == isl_dim_div || dst_type == isl_dim_div) + isl_die(ctx, isl_error_invalid, "cannot move local variables", + return isl_qpolynomial_free(qp)); + if (isl_qpolynomial_check_range(qp, src_type, src_pos, n) < 0) + return isl_qpolynomial_free(qp); + if (dst_type == isl_dim_in) + dst_type = isl_dim_set; + if (src_type == isl_dim_in) + src_type = isl_dim_set; + + if (n == 0 && + !isl_space_is_named_or_nested(qp->dim, src_type) && + !isl_space_is_named_or_nested(qp->dim, dst_type)) + return qp; + + src_off = isl_qpolynomial_domain_var_offset(qp, src_type); + dst_off = isl_qpolynomial_domain_var_offset(qp, dst_type); + if (src_off < 0 || dst_off < 0) + return isl_qpolynomial_free(qp); + + g_dst_pos = dst_off + dst_pos; + g_src_pos = src_off + src_pos; + if (dst_type > src_type) + g_dst_pos -= n; + + qp = local_poly_move_dims(qp, g_dst_pos, g_src_pos, n); + + space = isl_qpolynomial_take_domain_space(qp); + space = isl_space_move_dims(space, dst_type, dst_pos, + src_type, src_pos, n); + qp = isl_qpolynomial_restore_domain_space(qp, space); + + return qp; +} + +/* Given a quasi-polynomial on a domain (A -> B), + * interchange A and B in the wrapped domain + * to obtain a quasi-polynomial on the domain (B -> A). + */ +__isl_give isl_qpolynomial *isl_qpolynomial_domain_reverse( + __isl_take isl_qpolynomial *qp) +{ + isl_space *space; + isl_size n_in, n_out, offset; + + space = isl_qpolynomial_peek_domain_space(qp); + offset = isl_space_offset(space, isl_dim_set); + n_in = isl_space_wrapped_dim(space, isl_dim_set, isl_dim_in); + n_out = isl_space_wrapped_dim(space, isl_dim_set, isl_dim_out); + if (offset < 0 || n_in < 0 || n_out < 0) + return isl_qpolynomial_free(qp); + + qp = local_poly_move_dims(qp, offset, offset + n_in, n_out); + + space = isl_qpolynomial_take_domain_space(qp); + space = isl_space_wrapped_reverse(space); + qp = isl_qpolynomial_restore_domain_space(qp, space); + + return qp; +} + +__isl_give isl_qpolynomial *isl_qpolynomial_from_affine( + __isl_take isl_space *space, isl_int *f, isl_int denom) +{ + isl_size d; + isl_poly *poly; + + space = isl_space_domain(space); + if (!space) + return NULL; + + d = isl_space_dim(space, isl_dim_all); + poly = d < 0 ? NULL : isl_poly_from_affine(space->ctx, f, denom, 1 + d); + + return isl_qpolynomial_alloc(space, 0, poly); +} + +__isl_give isl_qpolynomial *isl_qpolynomial_from_aff(__isl_take isl_aff *aff) +{ + isl_ctx *ctx; + isl_poly *poly; + isl_qpolynomial *qp; + + if (!aff) + return NULL; + + ctx = isl_aff_get_ctx(aff); + poly = isl_poly_from_affine(ctx, aff->v->el + 1, aff->v->el[0], + aff->v->size - 1); + + qp = isl_qpolynomial_alloc(isl_aff_get_domain_space(aff), + aff->ls->div->n_row, poly); + if (!qp) + goto error; + + isl_mat_free(qp->div); + qp->div = isl_mat_copy(aff->ls->div); + qp->div = isl_mat_cow(qp->div); + if (!qp->div) + goto error; + + isl_aff_free(aff); + qp = reduce_divs(qp); + qp = remove_redundant_divs(qp); + return qp; +error: + isl_aff_free(aff); + return isl_qpolynomial_free(qp); +} + +__isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_from_pw_aff( + __isl_take isl_pw_aff *pwaff) +{ + int i; + isl_pw_qpolynomial *pwqp; + + if (!pwaff) + return NULL; + + pwqp = isl_pw_qpolynomial_alloc_size(isl_pw_aff_get_space(pwaff), + pwaff->n); + + for (i = 0; i < pwaff->n; ++i) { + isl_set *dom; + isl_qpolynomial *qp; + + dom = isl_set_copy(pwaff->p[i].set); + qp = isl_qpolynomial_from_aff(isl_aff_copy(pwaff->p[i].aff)); + pwqp = isl_pw_qpolynomial_add_piece(pwqp, dom, qp); + } + + isl_pw_aff_free(pwaff); + return pwqp; +} + +__isl_give isl_qpolynomial *isl_qpolynomial_from_constraint( + __isl_take isl_constraint *c, enum isl_dim_type type, unsigned pos) +{ + isl_aff *aff; + + aff = isl_constraint_get_bound(c, type, pos); + isl_constraint_free(c); + return isl_qpolynomial_from_aff(aff); +} + +/* For each 0 <= i < "n", replace variable "first" + i of type "type" + * in "qp" by subs[i]. + */ +__isl_give isl_qpolynomial *isl_qpolynomial_substitute( + __isl_take isl_qpolynomial *qp, + enum isl_dim_type type, unsigned first, unsigned n, + __isl_keep isl_qpolynomial **subs) +{ + int i; + isl_poly *poly; + isl_poly **polys; + + if (n == 0) + return qp; + + if (!qp) + return NULL; + + if (type == isl_dim_out) + isl_die(qp->dim->ctx, isl_error_invalid, + "cannot substitute output/set dimension", + goto error); + if (isl_qpolynomial_check_range(qp, type, first, n) < 0) + return isl_qpolynomial_free(qp); + type = domain_type(type); + + for (i = 0; i < n; ++i) + if (!subs[i]) + goto error; + + for (i = 0; i < n; ++i) + if (isl_qpolynomial_check_equal_space(qp, subs[i]) < 0) + goto error; + + isl_assert(qp->dim->ctx, qp->div->n_row == 0, goto error); + for (i = 0; i < n; ++i) + isl_assert(qp->dim->ctx, subs[i]->div->n_row == 0, goto error); + + first += pos(qp->dim, type); + + polys = isl_alloc_array(qp->dim->ctx, struct isl_poly *, n); + if (!polys) + goto error; + for (i = 0; i < n; ++i) + polys[i] = subs[i]->poly; + + poly = isl_qpolynomial_take_poly(qp); + poly = isl_poly_subs(poly, first, n, polys); + qp = isl_qpolynomial_restore_poly(qp, poly); + + free(polys); + + return qp; +error: + isl_qpolynomial_free(qp); + return NULL; +} + +/* Extend "bset" with extra set dimensions for each integer division + * in "qp" and then call "fn" with the extended bset and the polynomial + * that results from replacing each of the integer divisions by the + * corresponding extra set dimension. + */ +isl_stat isl_qpolynomial_as_polynomial_on_domain(__isl_keep isl_qpolynomial *qp, + __isl_keep isl_basic_set *bset, + isl_stat (*fn)(__isl_take isl_basic_set *bset, + __isl_take isl_qpolynomial *poly, void *user), void *user) +{ + isl_space *space; + isl_local_space *ls; + isl_poly *poly; + isl_qpolynomial *polynomial; + + if (!qp || !bset) + return isl_stat_error; + if (qp->div->n_row == 0) + return fn(isl_basic_set_copy(bset), isl_qpolynomial_copy(qp), + user); + + space = isl_space_copy(qp->dim); + space = isl_space_add_dims(space, isl_dim_set, qp->div->n_row); + poly = isl_qpolynomial_get_poly(qp); + polynomial = isl_qpolynomial_alloc(space, 0, poly); + bset = isl_basic_set_copy(bset); + ls = isl_qpolynomial_get_domain_local_space(qp); + bset = isl_local_space_lift_basic_set(ls, bset); + + return fn(bset, polynomial, user); +} + +/* Return total degree in variables first (inclusive) up to last (exclusive). + */ +int isl_poly_degree(__isl_keep isl_poly *poly, int first, int last) +{ + int deg = -1; + int i; + isl_bool is_zero, is_cst; + isl_poly_rec *rec; + + is_zero = isl_poly_is_zero(poly); + if (is_zero < 0) + return -2; + if (is_zero) + return -1; + is_cst = isl_poly_is_cst(poly); + if (is_cst < 0) + return -2; + if (is_cst || poly->var < first) + return 0; + + rec = isl_poly_as_rec(poly); + if (!rec) + return -2; + + for (i = 0; i < rec->n; ++i) { + int d; + + is_zero = isl_poly_is_zero(rec->p[i]); + if (is_zero < 0) + return -2; + if (is_zero) + continue; + d = isl_poly_degree(rec->p[i], first, last); + if (poly->var < last) + d += i; + if (d > deg) + deg = d; + } + + return deg; +} + +/* Return total degree in set variables. + */ +int isl_qpolynomial_degree(__isl_keep isl_qpolynomial *poly) +{ + isl_size ovar; + isl_size nvar; + + if (!poly) + return -2; + + ovar = isl_space_offset(poly->dim, isl_dim_set); + nvar = isl_space_dim(poly->dim, isl_dim_set); + if (ovar < 0 || nvar < 0) + return -2; + return isl_poly_degree(poly->poly, ovar, ovar + nvar); +} + +__isl_give isl_poly *isl_poly_coeff(__isl_keep isl_poly *poly, + unsigned pos, int deg) +{ + int i; + isl_bool is_cst; + isl_poly_rec *rec; + + is_cst = isl_poly_is_cst(poly); + if (is_cst < 0) + return NULL; + if (is_cst || poly->var < pos) { + if (deg == 0) + return isl_poly_copy(poly); + else + return isl_poly_zero(poly->ctx); + } + + rec = isl_poly_as_rec(poly); + if (!rec) + return NULL; + + if (poly->var == pos) { + if (deg < rec->n) + return isl_poly_copy(rec->p[deg]); + else + return isl_poly_zero(poly->ctx); + } + + poly = isl_poly_copy(poly); + poly = isl_poly_cow(poly); + rec = isl_poly_as_rec(poly); + if (!rec) + goto error; + + for (i = 0; i < rec->n; ++i) { + isl_poly *t; + t = isl_poly_coeff(rec->p[i], pos, deg); + if (!t) + goto error; + isl_poly_free(rec->p[i]); + rec->p[i] = t; + } + + return poly; +error: + isl_poly_free(poly); + return NULL; +} + +/* Return coefficient of power "deg" of variable "t_pos" of type "type". + */ +__isl_give isl_qpolynomial *isl_qpolynomial_coeff( + __isl_keep isl_qpolynomial *qp, + enum isl_dim_type type, unsigned t_pos, int deg) +{ + unsigned g_pos; + isl_poly *poly; + isl_qpolynomial *c; + + if (!qp) + return NULL; + + if (type == isl_dim_out) + isl_die(qp->div->ctx, isl_error_invalid, + "output/set dimension does not have a coefficient", + return NULL); + if (isl_qpolynomial_check_range(qp, type, t_pos, 1) < 0) + return NULL; + type = domain_type(type); + + g_pos = pos(qp->dim, type) + t_pos; + poly = isl_poly_coeff(qp->poly, g_pos, deg); + + c = isl_qpolynomial_alloc(isl_space_copy(qp->dim), + qp->div->n_row, poly); + if (!c) + return NULL; + isl_mat_free(c->div); + c->div = isl_qpolynomial_get_local(qp); + if (!c->div) + goto error; + return c; +error: + isl_qpolynomial_free(c); + return NULL; +} + +/* Homogenize the polynomial in the variables first (inclusive) up to + * last (exclusive) by inserting powers of variable first. + * Variable first is assumed not to appear in the input. + */ +__isl_give isl_poly *isl_poly_homogenize(__isl_take isl_poly *poly, int deg, + int target, int first, int last) +{ + int i; + isl_bool is_zero, is_cst; + isl_poly_rec *rec; + + is_zero = isl_poly_is_zero(poly); + if (is_zero < 0) + return isl_poly_free(poly); + if (is_zero) + return poly; + if (deg == target) + return poly; + is_cst = isl_poly_is_cst(poly); + if (is_cst < 0) + return isl_poly_free(poly); + if (is_cst || poly->var < first) { + isl_poly *hom; + + hom = isl_poly_var_pow(poly->ctx, first, target - deg); + if (!hom) + goto error; + rec = isl_poly_as_rec(hom); + rec->p[target - deg] = isl_poly_mul(rec->p[target - deg], poly); + + return hom; + } + + poly = isl_poly_cow(poly); + rec = isl_poly_as_rec(poly); + if (!rec) + goto error; + + for (i = 0; i < rec->n; ++i) { + is_zero = isl_poly_is_zero(rec->p[i]); + if (is_zero < 0) + return isl_poly_free(poly); + if (is_zero) + continue; + rec->p[i] = isl_poly_homogenize(rec->p[i], + poly->var < last ? deg + i : i, target, + first, last); + if (!rec->p[i]) + goto error; + } + + return poly; +error: + isl_poly_free(poly); + return NULL; +} + +/* Homogenize the polynomial in the set variables by introducing + * powers of an extra set variable at position 0. + */ +__isl_give isl_qpolynomial *isl_qpolynomial_homogenize( + __isl_take isl_qpolynomial *poly) +{ + isl_size ovar; + isl_size nvar; + int deg = isl_qpolynomial_degree(poly); + + if (deg < -1) + goto error; + + poly = isl_qpolynomial_insert_dims(poly, isl_dim_in, 0, 1); + poly = isl_qpolynomial_cow(poly); + if (!poly) + goto error; + + ovar = isl_space_offset(poly->dim, isl_dim_set); + nvar = isl_space_dim(poly->dim, isl_dim_set); + if (ovar < 0 || nvar < 0) + return isl_qpolynomial_free(poly); + poly->poly = isl_poly_homogenize(poly->poly, 0, deg, ovar, ovar + nvar); + if (!poly->poly) + goto error; + + return poly; +error: + isl_qpolynomial_free(poly); + return NULL; +} + +__isl_give isl_term *isl_term_alloc(__isl_take isl_space *space, + __isl_take isl_mat *div) +{ + isl_term *term; + isl_size d; + int n; + + d = isl_space_dim(space, isl_dim_all); + if (d < 0 || !div) + goto error; + + n = d + div->n_row; + + term = isl_calloc(space->ctx, struct isl_term, + sizeof(struct isl_term) + (n - 1) * sizeof(int)); + if (!term) + goto error; + + term->ref = 1; + term->dim = space; + term->div = div; + isl_int_init(term->n); + isl_int_init(term->d); + + return term; +error: + isl_space_free(space); + isl_mat_free(div); + return NULL; +} + +__isl_give isl_term *isl_term_copy(__isl_keep isl_term *term) +{ + if (!term) + return NULL; + + term->ref++; + return term; +} + +__isl_give isl_term *isl_term_dup(__isl_keep isl_term *term) +{ + int i; + isl_term *dup; + isl_size total; + + total = isl_term_dim(term, isl_dim_all); + if (total < 0) + return NULL; + + dup = isl_term_alloc(isl_space_copy(term->dim), isl_mat_copy(term->div)); + if (!dup) + return NULL; + + isl_int_set(dup->n, term->n); + isl_int_set(dup->d, term->d); + + for (i = 0; i < total; ++i) + dup->pow[i] = term->pow[i]; + + return dup; +} + +__isl_give isl_term *isl_term_cow(__isl_take isl_term *term) +{ + if (!term) + return NULL; + + if (term->ref == 1) + return term; + term->ref--; + return isl_term_dup(term); +} + +__isl_null isl_term *isl_term_free(__isl_take isl_term *term) +{ + if (!term) + return NULL; + + if (--term->ref > 0) + return NULL; + + isl_space_free(term->dim); + isl_mat_free(term->div); + isl_int_clear(term->n); + isl_int_clear(term->d); + free(term); + + return NULL; +} + +isl_size isl_term_dim(__isl_keep isl_term *term, enum isl_dim_type type) +{ + isl_size dim; + + if (!term) + return isl_size_error; + + switch (type) { + case isl_dim_param: + case isl_dim_in: + case isl_dim_out: return isl_space_dim(term->dim, type); + case isl_dim_div: return term->div->n_row; + case isl_dim_all: dim = isl_space_dim(term->dim, isl_dim_all); + if (dim < 0) + return isl_size_error; + return dim + term->div->n_row; + default: return isl_size_error; + } +} + +/* Return the space of "term". + */ +static __isl_keep isl_space *isl_term_peek_space(__isl_keep isl_term *term) +{ + return term ? term->dim : NULL; +} + +/* Return the offset of the first variable of type "type" within + * the variables of "term". + */ +static isl_size isl_term_offset(__isl_keep isl_term *term, + enum isl_dim_type type) +{ + isl_space *space; + + space = isl_term_peek_space(term); + if (!space) + return isl_size_error; + + switch (type) { + case isl_dim_param: + case isl_dim_set: return isl_space_offset(space, type); + case isl_dim_div: return isl_space_dim(space, isl_dim_all); + default: + isl_die(isl_term_get_ctx(term), isl_error_invalid, + "invalid dimension type", return isl_size_error); + } +} + +isl_ctx *isl_term_get_ctx(__isl_keep isl_term *term) +{ + return term ? term->dim->ctx : NULL; +} + +void isl_term_get_num(__isl_keep isl_term *term, isl_int *n) +{ + if (!term) + return; + isl_int_set(*n, term->n); +} + +/* Return the coefficient of the term "term". + */ +__isl_give isl_val *isl_term_get_coefficient_val(__isl_keep isl_term *term) +{ + if (!term) + return NULL; + + return isl_val_rat_from_isl_int(isl_term_get_ctx(term), + term->n, term->d); +} + +#undef TYPE +#define TYPE isl_term +static +#include "check_type_range_templ.c" + +isl_size isl_term_get_exp(__isl_keep isl_term *term, + enum isl_dim_type type, unsigned pos) +{ + isl_size offset; + + if (isl_term_check_range(term, type, pos, 1) < 0) + return isl_size_error; + offset = isl_term_offset(term, type); + if (offset < 0) + return isl_size_error; + + return term->pow[offset + pos]; +} + +__isl_give isl_aff *isl_term_get_div(__isl_keep isl_term *term, unsigned pos) +{ + isl_local_space *ls; + isl_aff *aff; + + if (isl_term_check_range(term, isl_dim_div, pos, 1) < 0) + return NULL; + + ls = isl_local_space_alloc_div(isl_space_copy(term->dim), + isl_mat_copy(term->div)); + aff = isl_aff_alloc(ls); + if (!aff) + return NULL; + + isl_seq_cpy(aff->v->el, term->div->row[pos], aff->v->size); + + aff = isl_aff_normalize(aff); + + return aff; +} + +__isl_give isl_term *isl_poly_foreach_term(__isl_keep isl_poly *poly, + isl_stat (*fn)(__isl_take isl_term *term, void *user), + __isl_take isl_term *term, void *user) +{ + int i; + isl_bool is_zero, is_bad, is_cst; + isl_poly_rec *rec; + + is_zero = isl_poly_is_zero(poly); + if (is_zero < 0 || !term) + goto error; + + if (is_zero) + return term; + + is_cst = isl_poly_is_cst(poly); + is_bad = isl_poly_is_nan(poly); + if (is_bad >= 0 && !is_bad) + is_bad = isl_poly_is_infty(poly); + if (is_bad >= 0 && !is_bad) + is_bad = isl_poly_is_neginfty(poly); + if (is_cst < 0 || is_bad < 0) + return isl_term_free(term); + if (is_bad) + isl_die(isl_term_get_ctx(term), isl_error_invalid, + "cannot handle NaN/infty polynomial", + return isl_term_free(term)); + + if (is_cst) { + isl_poly_cst *cst; + cst = isl_poly_as_cst(poly); + if (!cst) + goto error; + term = isl_term_cow(term); + if (!term) + goto error; + isl_int_set(term->n, cst->n); + isl_int_set(term->d, cst->d); + if (fn(isl_term_copy(term), user) < 0) + goto error; + return term; + } + + rec = isl_poly_as_rec(poly); + if (!rec) + goto error; + + for (i = 0; i < rec->n; ++i) { + term = isl_term_cow(term); + if (!term) + goto error; + term->pow[poly->var] = i; + term = isl_poly_foreach_term(rec->p[i], fn, term, user); + if (!term) + goto error; + } + term = isl_term_cow(term); + if (!term) + return NULL; + term->pow[poly->var] = 0; + + return term; +error: + isl_term_free(term); + return NULL; +} + +isl_stat isl_qpolynomial_foreach_term(__isl_keep isl_qpolynomial *qp, + isl_stat (*fn)(__isl_take isl_term *term, void *user), void *user) +{ + isl_local *local; + isl_term *term; + + if (!qp) + return isl_stat_error; + + local = isl_qpolynomial_get_local(qp); + term = isl_term_alloc(isl_space_copy(qp->dim), local); + if (!term) + return isl_stat_error; + + term = isl_poly_foreach_term(qp->poly, fn, term, user); + + isl_term_free(term); + + return term ? isl_stat_ok : isl_stat_error; +} + +__isl_give isl_qpolynomial *isl_qpolynomial_from_term(__isl_take isl_term *term) +{ + isl_poly *poly; + isl_qpolynomial *qp; + int i; + isl_size n; + + n = isl_term_dim(term, isl_dim_all); + if (n < 0) + term = isl_term_free(term); + if (!term) + return NULL; + + poly = isl_poly_rat_cst(term->dim->ctx, term->n, term->d); + for (i = 0; i < n; ++i) { + if (!term->pow[i]) + continue; + poly = isl_poly_mul(poly, + isl_poly_var_pow(term->dim->ctx, i, term->pow[i])); + } + + qp = isl_qpolynomial_alloc(isl_space_copy(term->dim), + term->div->n_row, poly); + if (!qp) + goto error; + isl_mat_free(qp->div); + qp->div = isl_mat_copy(term->div); + if (!qp->div) + goto error; + + isl_term_free(term); + return qp; +error: + isl_qpolynomial_free(qp); + isl_term_free(term); + return NULL; +} + +__isl_give isl_qpolynomial *isl_qpolynomial_lift(__isl_take isl_qpolynomial *qp, + __isl_take isl_space *space) +{ + int i; + int extra; + isl_size total, d_set, d_qp; + + if (!qp || !space) + goto error; + + if (isl_space_is_equal(qp->dim, space)) { + isl_space_free(space); + return qp; + } + + qp = isl_qpolynomial_cow(qp); + if (!qp) + goto error; + + d_set = isl_space_dim(space, isl_dim_set); + d_qp = isl_qpolynomial_domain_dim(qp, isl_dim_set); + extra = d_set - d_qp; + total = isl_space_dim(qp->dim, isl_dim_all); + if (d_set < 0 || d_qp < 0 || total < 0) + goto error; + if (qp->div->n_row) { + int *exp; + + exp = isl_alloc_array(qp->div->ctx, int, qp->div->n_row); + if (!exp) + goto error; + for (i = 0; i < qp->div->n_row; ++i) + exp[i] = extra + i; + qp->poly = expand(qp->poly, exp, total); + free(exp); + if (!qp->poly) + goto error; + } + qp->div = isl_mat_insert_cols(qp->div, 2 + total, extra); + if (!qp->div) + goto error; + for (i = 0; i < qp->div->n_row; ++i) + isl_seq_clr(qp->div->row[i] + 2 + total, extra); + + isl_space_free(isl_qpolynomial_take_domain_space(qp)); + qp = isl_qpolynomial_restore_domain_space(qp, space); + + return qp; +error: + isl_space_free(space); + isl_qpolynomial_free(qp); + return NULL; +} + +/* For each parameter or variable that does not appear in qp, + * first eliminate the variable from all constraints and then set it to zero. + */ +static __isl_give isl_set *fix_inactive(__isl_take isl_set *set, + __isl_keep isl_qpolynomial *qp) +{ + int *active = NULL; + int i; + isl_size d; + isl_size nparam; + isl_size nvar; + + d = isl_set_dim(set, isl_dim_all); + if (d < 0 || !qp) + goto error; + + active = isl_calloc_array(set->ctx, int, d); + if (set_active(qp, active) < 0) + goto error; + + for (i = 0; i < d; ++i) + if (!active[i]) + break; + + if (i == d) { + free(active); + return set; + } + + nparam = isl_set_dim(set, isl_dim_param); + nvar = isl_set_dim(set, isl_dim_set); + if (nparam < 0 || nvar < 0) + goto error; + for (i = 0; i < nparam; ++i) { + if (active[i]) + continue; + set = isl_set_eliminate(set, isl_dim_param, i, 1); + set = isl_set_fix_si(set, isl_dim_param, i, 0); + } + for (i = 0; i < nvar; ++i) { + if (active[nparam + i]) + continue; + set = isl_set_eliminate(set, isl_dim_set, i, 1); + set = isl_set_fix_si(set, isl_dim_set, i, 0); + } + + free(active); + + return set; +error: + free(active); + isl_set_free(set); + return NULL; +} + +struct isl_opt_data { + isl_qpolynomial *qp; + int first; + isl_val *opt; + int max; +}; + +static isl_stat opt_fn(__isl_take isl_point *pnt, void *user) +{ + struct isl_opt_data *data = (struct isl_opt_data *)user; + isl_val *val; + + val = isl_qpolynomial_eval(isl_qpolynomial_copy(data->qp), pnt); + if (data->first) { + data->first = 0; + data->opt = val; + } else if (data->max) { + data->opt = isl_val_max(data->opt, val); + } else { + data->opt = isl_val_min(data->opt, val); + } + + return isl_stat_ok; +} + +__isl_give isl_val *isl_qpolynomial_opt_on_domain( + __isl_take isl_qpolynomial *qp, __isl_take isl_set *set, int max) +{ + struct isl_opt_data data = { NULL, 1, NULL, max }; + isl_bool is_cst; + + if (!set || !qp) + goto error; + + is_cst = isl_poly_is_cst(qp->poly); + if (is_cst < 0) + goto error; + if (is_cst) { + isl_set_free(set); + data.opt = isl_qpolynomial_get_constant_val(qp); + isl_qpolynomial_free(qp); + return data.opt; + } + + set = fix_inactive(set, qp); + + data.qp = qp; + if (isl_set_foreach_point(set, opt_fn, &data) < 0) + goto error; + + if (data.first) + data.opt = isl_val_zero(isl_set_get_ctx(set)); + + isl_set_free(set); + isl_qpolynomial_free(qp); + return data.opt; +error: + isl_set_free(set); + isl_qpolynomial_free(qp); + isl_val_free(data.opt); + return NULL; +} + +__isl_give isl_qpolynomial *isl_qpolynomial_morph_domain( + __isl_take isl_qpolynomial *qp, __isl_take isl_morph *morph) +{ + int i; + int n_sub; + isl_ctx *ctx; + isl_space *space; + isl_poly **subs; + isl_mat *mat, *diag; + + qp = isl_qpolynomial_cow(qp); + + space = isl_qpolynomial_peek_domain_space(qp); + if (isl_morph_check_applies(morph, space) < 0) + goto error; + + ctx = isl_qpolynomial_get_ctx(qp); + n_sub = morph->inv->n_row - 1; + if (morph->inv->n_row != morph->inv->n_col) + n_sub += qp->div->n_row; + subs = isl_calloc_array(ctx, struct isl_poly *, n_sub); + if (n_sub && !subs) + goto error; + + for (i = 0; 1 + i < morph->inv->n_row; ++i) + subs[i] = isl_poly_from_affine(ctx, morph->inv->row[1 + i], + morph->inv->row[0][0], morph->inv->n_col); + if (morph->inv->n_row != morph->inv->n_col) + for (i = 0; i < qp->div->n_row; ++i) + subs[morph->inv->n_row - 1 + i] = + isl_poly_var_pow(ctx, morph->inv->n_col - 1 + i, 1); + + qp->poly = isl_poly_subs(qp->poly, 0, n_sub, subs); + + for (i = 0; i < n_sub; ++i) + isl_poly_free(subs[i]); + free(subs); + + diag = isl_mat_diag(ctx, 1, morph->inv->row[0][0]); + mat = isl_mat_diagonal(diag, isl_mat_copy(morph->inv)); + diag = isl_mat_diag(ctx, qp->div->n_row, morph->inv->row[0][0]); + mat = isl_mat_diagonal(mat, diag); + qp->div = isl_mat_product(qp->div, mat); + + if (!qp->poly || !qp->div) + goto error; + + isl_space_free(isl_qpolynomial_take_domain_space(qp)); + space = isl_space_copy(morph->ran->dim); + qp = isl_qpolynomial_restore_domain_space(qp, space); + + isl_morph_free(morph); + + return qp; +error: + isl_qpolynomial_free(qp); + isl_morph_free(morph); + return NULL; +} + +__isl_give isl_union_pw_qpolynomial *isl_union_pw_qpolynomial_mul( + __isl_take isl_union_pw_qpolynomial *upwqp1, + __isl_take isl_union_pw_qpolynomial *upwqp2) +{ + return isl_union_pw_qpolynomial_match_bin_op(upwqp1, upwqp2, + &isl_pw_qpolynomial_mul); +} + +/* Reorder the dimension of "qp" according to the given reordering. + */ +__isl_give isl_qpolynomial *isl_qpolynomial_realign_domain( + __isl_take isl_qpolynomial *qp, __isl_take isl_reordering *r) +{ + isl_space *space; + isl_poly *poly; + isl_local *local; + + if (!qp) + goto error; + + r = isl_reordering_extend(r, qp->div->n_row); + if (!r) + goto error; + + local = isl_qpolynomial_take_local(qp); + local = isl_local_reorder(local, isl_reordering_copy(r)); + qp = isl_qpolynomial_restore_local(qp, local); + + poly = isl_qpolynomial_take_poly(qp); + poly = reorder(poly, r->pos); + qp = isl_qpolynomial_restore_poly(qp, poly); + + space = isl_reordering_get_space(r); + qp = isl_qpolynomial_reset_domain_space(qp, space); + + isl_reordering_free(r); + return qp; +error: + isl_qpolynomial_free(qp); + isl_reordering_free(r); + return NULL; +} + +__isl_give isl_qpolynomial *isl_qpolynomial_align_params( + __isl_take isl_qpolynomial *qp, __isl_take isl_space *model) +{ + isl_space *domain_space; + isl_bool equal_params; + + domain_space = isl_qpolynomial_peek_domain_space(qp); + equal_params = isl_space_has_equal_params(domain_space, model); + if (equal_params < 0) + goto error; + if (!equal_params) { + isl_reordering *exp; + + exp = isl_parameter_alignment_reordering(domain_space, model); + qp = isl_qpolynomial_realign_domain(qp, exp); + } + + isl_space_free(model); + return qp; +error: + isl_space_free(model); + isl_qpolynomial_free(qp); + return NULL; +} + +struct isl_split_periods_data { + int max_periods; + isl_pw_qpolynomial *res; +}; + +/* Create a slice where the integer division "div" has the fixed value "v". + * In particular, if "div" refers to floor(f/m), then create a slice + * + * m v <= f <= m v + (m - 1) + * + * or + * + * f - m v >= 0 + * -f + m v + (m - 1) >= 0 + */ +static __isl_give isl_set *set_div_slice(__isl_take isl_space *space, + __isl_keep isl_qpolynomial *qp, int div, isl_int v) +{ + isl_size total; + isl_basic_set *bset = NULL; + int k; + + total = isl_space_dim(space, isl_dim_all); + if (total < 0 || !qp) + goto error; + + bset = isl_basic_set_alloc_space(isl_space_copy(space), 0, 0, 2); + + k = isl_basic_set_alloc_inequality(bset); + if (k < 0) + goto error; + isl_seq_cpy(bset->ineq[k], qp->div->row[div] + 1, 1 + total); + isl_int_submul(bset->ineq[k][0], v, qp->div->row[div][0]); + + k = isl_basic_set_alloc_inequality(bset); + if (k < 0) + goto error; + isl_seq_neg(bset->ineq[k], qp->div->row[div] + 1, 1 + total); + isl_int_addmul(bset->ineq[k][0], v, qp->div->row[div][0]); + isl_int_add(bset->ineq[k][0], bset->ineq[k][0], qp->div->row[div][0]); + isl_int_sub_ui(bset->ineq[k][0], bset->ineq[k][0], 1); + + isl_space_free(space); + return isl_set_from_basic_set(bset); +error: + isl_basic_set_free(bset); + isl_space_free(space); + return NULL; +} + +static isl_stat split_periods(__isl_take isl_set *set, + __isl_take isl_qpolynomial *qp, void *user); + +/* Create a slice of the domain "set" such that integer division "div" + * has the fixed value "v" and add the results to data->res, + * replacing the integer division by "v" in "qp". + */ +static isl_stat set_div(__isl_take isl_set *set, + __isl_take isl_qpolynomial *qp, int div, isl_int v, + struct isl_split_periods_data *data) +{ + int i; + isl_size div_pos; + isl_set *slice; + isl_poly *cst; + + slice = set_div_slice(isl_set_get_space(set), qp, div, v); + set = isl_set_intersect(set, slice); + + div_pos = isl_qpolynomial_domain_var_offset(qp, isl_dim_div); + if (div_pos < 0) + goto error; + + for (i = div + 1; i < qp->div->n_row; ++i) { + if (isl_int_is_zero(qp->div->row[i][2 + div_pos + div])) + continue; + isl_int_addmul(qp->div->row[i][1], + qp->div->row[i][2 + div_pos + div], v); + isl_int_set_si(qp->div->row[i][2 + div_pos + div], 0); + } + + cst = isl_poly_rat_cst(qp->dim->ctx, v, qp->dim->ctx->one); + qp = substitute_div(qp, div, cst); + + return split_periods(set, qp, data); +error: + isl_set_free(set); + isl_qpolynomial_free(qp); + return isl_stat_error; +} + +/* Split the domain "set" such that integer division "div" + * has a fixed value (ranging from "min" to "max") on each slice + * and add the results to data->res. + */ +static isl_stat split_div(__isl_take isl_set *set, + __isl_take isl_qpolynomial *qp, int div, isl_int min, isl_int max, + struct isl_split_periods_data *data) +{ + for (; isl_int_le(min, max); isl_int_add_ui(min, min, 1)) { + isl_set *set_i = isl_set_copy(set); + isl_qpolynomial *qp_i = isl_qpolynomial_copy(qp); + + if (set_div(set_i, qp_i, div, min, data) < 0) + goto error; + } + isl_set_free(set); + isl_qpolynomial_free(qp); + return isl_stat_ok; +error: + isl_set_free(set); + isl_qpolynomial_free(qp); + return isl_stat_error; +} + +/* If "qp" refers to any integer division + * that can only attain "max_periods" distinct values on "set" + * then split the domain along those distinct values. + * Add the results (or the original if no splitting occurs) + * to data->res. + */ +static isl_stat split_periods(__isl_take isl_set *set, + __isl_take isl_qpolynomial *qp, void *user) +{ + int i; + isl_pw_qpolynomial *pwqp; + struct isl_split_periods_data *data; + isl_int min, max; + isl_size div_pos; + isl_stat r = isl_stat_ok; + + data = (struct isl_split_periods_data *)user; + + if (!set || !qp) + goto error; + + if (qp->div->n_row == 0) { + pwqp = isl_pw_qpolynomial_alloc(set, qp); + data->res = isl_pw_qpolynomial_add_disjoint(data->res, pwqp); + return isl_stat_ok; + } + + div_pos = isl_qpolynomial_domain_var_offset(qp, isl_dim_div); + if (div_pos < 0) + goto error; + + isl_int_init(min); + isl_int_init(max); + for (i = 0; i < qp->div->n_row; ++i) { + enum isl_lp_result lp_res; + + if (isl_seq_first_non_zero(qp->div->row[i] + 2 + div_pos, + qp->div->n_row) != -1) + continue; + + lp_res = isl_set_solve_lp(set, 0, qp->div->row[i] + 1, + set->ctx->one, &min, NULL, NULL); + if (lp_res == isl_lp_error) + goto error2; + if (lp_res == isl_lp_unbounded || lp_res == isl_lp_empty) + continue; + isl_int_fdiv_q(min, min, qp->div->row[i][0]); + + lp_res = isl_set_solve_lp(set, 1, qp->div->row[i] + 1, + set->ctx->one, &max, NULL, NULL); + if (lp_res == isl_lp_error) + goto error2; + if (lp_res == isl_lp_unbounded || lp_res == isl_lp_empty) + continue; + isl_int_fdiv_q(max, max, qp->div->row[i][0]); + + isl_int_sub(max, max, min); + if (isl_int_cmp_si(max, data->max_periods) < 0) { + isl_int_add(max, max, min); + break; + } + } + + if (i < qp->div->n_row) { + r = split_div(set, qp, i, min, max, data); + } else { + pwqp = isl_pw_qpolynomial_alloc(set, qp); + data->res = isl_pw_qpolynomial_add_disjoint(data->res, pwqp); + } + + isl_int_clear(max); + isl_int_clear(min); + + return r; +error2: + isl_int_clear(max); + isl_int_clear(min); +error: + isl_set_free(set); + isl_qpolynomial_free(qp); + return isl_stat_error; +} + +/* If any quasi-polynomial in pwqp refers to any integer division + * that can only attain "max_periods" distinct values on its domain + * then split the domain along those distinct values. + */ +__isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_split_periods( + __isl_take isl_pw_qpolynomial *pwqp, int max_periods) +{ + struct isl_split_periods_data data; + + data.max_periods = max_periods; + data.res = isl_pw_qpolynomial_zero(isl_pw_qpolynomial_get_space(pwqp)); + + if (isl_pw_qpolynomial_foreach_piece(pwqp, &split_periods, &data) < 0) + goto error; + + isl_pw_qpolynomial_free(pwqp); + + return data.res; +error: + isl_pw_qpolynomial_free(data.res); + isl_pw_qpolynomial_free(pwqp); + return NULL; +} + +/* Construct a piecewise quasipolynomial that is constant on the given + * domain. In particular, it is + * 0 if cst == 0 + * 1 if cst == 1 + * infinity if cst == -1 + * + * If cst == -1, then explicitly check whether the domain is empty and, + * if so, return 0 instead. + */ +static __isl_give isl_pw_qpolynomial *constant_on_domain( + __isl_take isl_basic_set *bset, int cst) +{ + isl_space *space; + isl_qpolynomial *qp; + + if (cst < 0 && isl_basic_set_is_empty(bset) == isl_bool_true) + cst = 0; + if (!bset) + return NULL; + + bset = isl_basic_set_params(bset); + space = isl_basic_set_get_space(bset); + if (cst < 0) + qp = isl_qpolynomial_infty_on_domain(space); + else if (cst == 0) + qp = isl_qpolynomial_zero_on_domain(space); + else + qp = isl_qpolynomial_one_on_domain(space); + return isl_pw_qpolynomial_alloc(isl_set_from_basic_set(bset), qp); +} + +/* Internal data structure for multiplicative_call_factor_pw_qpolynomial. + * "fn" is the function that is called on each factor. + * "pwpq" collects the results. + */ +struct isl_multiplicative_call_data_pw_qpolynomial { + __isl_give isl_pw_qpolynomial *(*fn)(__isl_take isl_basic_set *bset); + isl_pw_qpolynomial *pwqp; +}; + +/* Call "fn" on "bset" and return the result, + * but first check if "bset" has any redundant constraints or + * implicit equality constraints. + * If so, there may be further opportunities for detecting factors or + * removing equality constraints, so recursively call + * the top-level isl_basic_set_multiplicative_call. + */ +static __isl_give isl_pw_qpolynomial *multiplicative_call_base( + __isl_take isl_basic_set *bset, + __isl_give isl_pw_qpolynomial *(*fn)(__isl_take isl_basic_set *bset)) +{ + isl_size n1, n2, n_eq; + + n1 = isl_basic_set_n_constraint(bset); + if (n1 < 0) + bset = isl_basic_set_free(bset); + bset = isl_basic_set_remove_redundancies(bset); + bset = isl_basic_set_detect_equalities(bset); + n2 = isl_basic_set_n_constraint(bset); + n_eq = isl_basic_set_n_equality(bset); + if (n2 < 0 || n_eq < 0) + bset = isl_basic_set_free(bset); + else if (n2 < n1 || n_eq > 0) + return isl_basic_set_multiplicative_call(bset, fn); + return fn(bset); +} + +/* isl_factorizer_every_factor_basic_set callback that applies + * data->fn to the factor "bset" and multiplies in the result + * in data->pwqp. + */ +static isl_bool multiplicative_call_factor_pw_qpolynomial( + __isl_keep isl_basic_set *bset, void *user) +{ + struct isl_multiplicative_call_data_pw_qpolynomial *data = user; + isl_pw_qpolynomial *res; + + bset = isl_basic_set_copy(bset); + res = multiplicative_call_base(bset, data->fn); + data->pwqp = isl_pw_qpolynomial_mul(data->pwqp, res); + if (!data->pwqp) + return isl_bool_error; + + return isl_bool_true; +} + +/* Factor bset, call fn on each of the factors and return the product. + * + * If no factors can be found, simply call fn on the input. + * Otherwise, construct the factors based on the factorizer, + * call fn on each factor and compute the product. + */ +static __isl_give isl_pw_qpolynomial *compressed_multiplicative_call( + __isl_take isl_basic_set *bset, + __isl_give isl_pw_qpolynomial *(*fn)(__isl_take isl_basic_set *bset)) +{ + struct isl_multiplicative_call_data_pw_qpolynomial data = { fn }; + isl_space *space; + isl_set *set; + isl_factorizer *f; + isl_qpolynomial *qp; + isl_bool every; + + f = isl_basic_set_factorizer(bset); + if (!f) + goto error; + if (f->n_group == 0) { + isl_factorizer_free(f); + return multiplicative_call_base(bset, fn); + } + + space = isl_basic_set_get_space(bset); + space = isl_space_params(space); + set = isl_set_universe(isl_space_copy(space)); + qp = isl_qpolynomial_one_on_domain(space); + data.pwqp = isl_pw_qpolynomial_alloc(set, qp); + + every = isl_factorizer_every_factor_basic_set(f, + &multiplicative_call_factor_pw_qpolynomial, &data); + if (every < 0) + data.pwqp = isl_pw_qpolynomial_free(data.pwqp); + + isl_basic_set_free(bset); + isl_factorizer_free(f); + + return data.pwqp; +error: + isl_basic_set_free(bset); + return NULL; +} + +/* Factor bset, call fn on each of the factors and return the product. + * The function is assumed to evaluate to zero on empty domains, + * to one on zero-dimensional domains and to infinity on unbounded domains + * and will not be called explicitly on zero-dimensional or unbounded domains. + * + * We first check for some special cases and remove all equalities. + * Then we hand over control to compressed_multiplicative_call. + */ +__isl_give isl_pw_qpolynomial *isl_basic_set_multiplicative_call( + __isl_take isl_basic_set *bset, + __isl_give isl_pw_qpolynomial *(*fn)(__isl_take isl_basic_set *bset)) +{ + isl_bool bounded; + isl_size dim; + isl_morph *morph; + isl_pw_qpolynomial *pwqp; + + if (!bset) + return NULL; + + if (isl_basic_set_plain_is_empty(bset)) + return constant_on_domain(bset, 0); + + dim = isl_basic_set_dim(bset, isl_dim_set); + if (dim < 0) + goto error; + if (dim == 0) + return constant_on_domain(bset, 1); + + bounded = isl_basic_set_is_bounded(bset); + if (bounded < 0) + goto error; + if (!bounded) + return constant_on_domain(bset, -1); + + if (bset->n_eq == 0) + return compressed_multiplicative_call(bset, fn); + + morph = isl_basic_set_full_compression(bset); + bset = isl_morph_basic_set(isl_morph_copy(morph), bset); + + pwqp = compressed_multiplicative_call(bset, fn); + + morph = isl_morph_dom_params(morph); + morph = isl_morph_ran_params(morph); + morph = isl_morph_inverse(morph); + + pwqp = isl_pw_qpolynomial_morph_domain(pwqp, morph); + + return pwqp; +error: + isl_basic_set_free(bset); + return NULL; +} + +/* Drop all floors in "qp", turning each integer division [a/m] into + * a rational division a/m. If "down" is set, then the integer division + * is replaced by (a-(m-1))/m instead. + */ +static __isl_give isl_qpolynomial *qp_drop_floors( + __isl_take isl_qpolynomial *qp, int down) +{ + int i; + isl_poly *s; + + if (!qp) + return NULL; + if (qp->div->n_row == 0) + return qp; + + qp = isl_qpolynomial_cow(qp); + if (!qp) + return NULL; + + for (i = qp->div->n_row - 1; i >= 0; --i) { + if (down) { + isl_int_sub(qp->div->row[i][1], + qp->div->row[i][1], qp->div->row[i][0]); + isl_int_add_ui(qp->div->row[i][1], + qp->div->row[i][1], 1); + } + s = isl_poly_from_affine(qp->dim->ctx, qp->div->row[i] + 1, + qp->div->row[i][0], qp->div->n_col - 1); + qp = substitute_div(qp, i, s); + if (!qp) + return NULL; + } + + return qp; +} + +/* Drop all floors in "pwqp", turning each integer division [a/m] into + * a rational division a/m. + */ +static __isl_give isl_pw_qpolynomial *pwqp_drop_floors( + __isl_take isl_pw_qpolynomial *pwqp) +{ + int i; + + if (!pwqp) + return NULL; + + if (isl_pw_qpolynomial_is_zero(pwqp)) + return pwqp; + + pwqp = isl_pw_qpolynomial_cow(pwqp); + if (!pwqp) + return NULL; + + for (i = 0; i < pwqp->n; ++i) { + pwqp->p[i].qp = qp_drop_floors(pwqp->p[i].qp, 0); + if (!pwqp->p[i].qp) + goto error; + } + + return pwqp; +error: + isl_pw_qpolynomial_free(pwqp); + return NULL; +} + +/* Adjust all the integer divisions in "qp" such that they are at least + * one over the given orthant (identified by "signs"). This ensures + * that they will still be non-negative even after subtracting (m-1)/m. + * + * In particular, f is replaced by f' + v, changing f = [a/m] + * to f' = [(a - m v)/m]. + * If the constant term k in a is smaller than m, + * the constant term of v is set to floor(k/m) - 1. + * For any other term, if the coefficient c and the variable x have + * the same sign, then no changes are needed. + * Otherwise, if the variable is positive (and c is negative), + * then the coefficient of x in v is set to floor(c/m). + * If the variable is negative (and c is positive), + * then the coefficient of x in v is set to ceil(c/m). + */ +static __isl_give isl_qpolynomial *make_divs_pos(__isl_take isl_qpolynomial *qp, + int *signs) +{ + int i, j; + isl_size div_pos; + isl_vec *v = NULL; + isl_poly *s; + + qp = isl_qpolynomial_cow(qp); + div_pos = isl_qpolynomial_domain_var_offset(qp, isl_dim_div); + if (div_pos < 0) + return isl_qpolynomial_free(qp); + qp->div = isl_mat_cow(qp->div); + if (!qp->div) + goto error; + + v = isl_vec_alloc(qp->div->ctx, qp->div->n_col - 1); + + for (i = 0; i < qp->div->n_row; ++i) { + isl_int *row = qp->div->row[i]; + v = isl_vec_clr(v); + if (!v) + goto error; + if (isl_int_lt(row[1], row[0])) { + isl_int_fdiv_q(v->el[0], row[1], row[0]); + isl_int_sub_ui(v->el[0], v->el[0], 1); + isl_int_submul(row[1], row[0], v->el[0]); + } + for (j = 0; j < div_pos; ++j) { + if (isl_int_sgn(row[2 + j]) * signs[j] >= 0) + continue; + if (signs[j] < 0) + isl_int_cdiv_q(v->el[1 + j], row[2 + j], row[0]); + else + isl_int_fdiv_q(v->el[1 + j], row[2 + j], row[0]); + isl_int_submul(row[2 + j], row[0], v->el[1 + j]); + } + for (j = 0; j < i; ++j) { + if (isl_int_sgn(row[2 + div_pos + j]) >= 0) + continue; + isl_int_fdiv_q(v->el[1 + div_pos + j], + row[2 + div_pos + j], row[0]); + isl_int_submul(row[2 + div_pos + j], + row[0], v->el[1 + div_pos + j]); + } + for (j = i + 1; j < qp->div->n_row; ++j) { + if (isl_int_is_zero(qp->div->row[j][2 + div_pos + i])) + continue; + isl_seq_combine(qp->div->row[j] + 1, + qp->div->ctx->one, qp->div->row[j] + 1, + qp->div->row[j][2 + div_pos + i], v->el, + v->size); + } + isl_int_set_si(v->el[1 + div_pos + i], 1); + s = isl_poly_from_affine(qp->dim->ctx, v->el, + qp->div->ctx->one, v->size); + qp->poly = isl_poly_subs(qp->poly, div_pos + i, 1, &s); + isl_poly_free(s); + if (!qp->poly) + goto error; + } + + isl_vec_free(v); + return qp; +error: + isl_vec_free(v); + isl_qpolynomial_free(qp); + return NULL; +} + +struct isl_to_poly_data { + int sign; + isl_pw_qpolynomial *res; + isl_qpolynomial *qp; +}; + +/* Appoximate data->qp by a polynomial on the orthant identified by "signs". + * We first make all integer divisions positive and then split the + * quasipolynomials into terms with sign data->sign (the direction + * of the requested approximation) and terms with the opposite sign. + * In the first set of terms, each integer division [a/m] is + * overapproximated by a/m, while in the second it is underapproximated + * by (a-(m-1))/m. + */ +static isl_stat to_polynomial_on_orthant(__isl_take isl_set *orthant, + int *signs, void *user) +{ + struct isl_to_poly_data *data = user; + isl_pw_qpolynomial *t; + isl_qpolynomial *qp, *up, *down; + + qp = isl_qpolynomial_copy(data->qp); + qp = make_divs_pos(qp, signs); + + up = isl_qpolynomial_terms_of_sign(qp, signs, data->sign); + up = qp_drop_floors(up, 0); + down = isl_qpolynomial_terms_of_sign(qp, signs, -data->sign); + down = qp_drop_floors(down, 1); + + isl_qpolynomial_free(qp); + qp = isl_qpolynomial_add(up, down); + + t = isl_pw_qpolynomial_alloc(orthant, qp); + data->res = isl_pw_qpolynomial_add_disjoint(data->res, t); + + return isl_stat_ok; +} + +/* Approximate each quasipolynomial by a polynomial. If "sign" is positive, + * the polynomial will be an overapproximation. If "sign" is negative, + * it will be an underapproximation. If "sign" is zero, the approximation + * will lie somewhere in between. + * + * In particular, is sign == 0, we simply drop the floors, turning + * the integer divisions into rational divisions. + * Otherwise, we split the domains into orthants, make all integer divisions + * positive and then approximate each [a/m] by either a/m or (a-(m-1))/m, + * depending on the requested sign and the sign of the term in which + * the integer division appears. + */ +__isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_to_polynomial( + __isl_take isl_pw_qpolynomial *pwqp, int sign) +{ + int i; + struct isl_to_poly_data data; + + if (sign == 0) + return pwqp_drop_floors(pwqp); + + if (!pwqp) + return NULL; + + data.sign = sign; + data.res = isl_pw_qpolynomial_zero(isl_pw_qpolynomial_get_space(pwqp)); + + for (i = 0; i < pwqp->n; ++i) { + if (pwqp->p[i].qp->div->n_row == 0) { + isl_pw_qpolynomial *t; + t = isl_pw_qpolynomial_alloc( + isl_set_copy(pwqp->p[i].set), + isl_qpolynomial_copy(pwqp->p[i].qp)); + data.res = isl_pw_qpolynomial_add_disjoint(data.res, t); + continue; + } + data.qp = pwqp->p[i].qp; + if (isl_set_foreach_orthant(pwqp->p[i].set, + &to_polynomial_on_orthant, &data) < 0) + goto error; + } + + isl_pw_qpolynomial_free(pwqp); + + return data.res; +error: + isl_pw_qpolynomial_free(pwqp); + isl_pw_qpolynomial_free(data.res); + return NULL; +} + +static __isl_give isl_pw_qpolynomial *poly_entry( + __isl_take isl_pw_qpolynomial *pwqp, void *user) +{ + int *sign = user; + + return isl_pw_qpolynomial_to_polynomial(pwqp, *sign); +} + +__isl_give isl_union_pw_qpolynomial *isl_union_pw_qpolynomial_to_polynomial( + __isl_take isl_union_pw_qpolynomial *upwqp, int sign) +{ + return isl_union_pw_qpolynomial_transform_inplace(upwqp, + &poly_entry, &sign); +} + +__isl_give isl_basic_map *isl_basic_map_from_qpolynomial( + __isl_take isl_qpolynomial *qp) +{ + isl_local_space *ls; + isl_vec *vec; + isl_aff *aff; + isl_basic_map *bmap; + isl_bool is_affine; + + if (!qp) + return NULL; + is_affine = isl_poly_is_affine(qp->poly); + if (is_affine < 0) + goto error; + if (!is_affine) + isl_die(qp->dim->ctx, isl_error_invalid, + "input quasi-polynomial not affine", goto error); + ls = isl_qpolynomial_get_domain_local_space(qp); + vec = isl_qpolynomial_extract_affine(qp); + aff = isl_aff_alloc_vec(ls, vec); + bmap = isl_basic_map_from_aff(aff); + isl_qpolynomial_free(qp); + return bmap; +error: + isl_qpolynomial_free(qp); + return NULL; +} diff --git a/external/mit/isl/dist/isl_polynomial_private.h b/external/mit/isl/dist/isl_polynomial_private.h new file mode 100644 index 000000000000..2f782655b790 --- /dev/null +++ b/external/mit/isl/dist/isl_polynomial_private.h @@ -0,0 +1,295 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include "isl_list_private.h" + +struct isl_poly { + int ref; + struct isl_ctx *ctx; + + int var; +}; +typedef struct isl_poly isl_poly; + +struct isl_poly_cst { + struct isl_poly poly; + isl_int n; + isl_int d; +}; +typedef struct isl_poly_cst isl_poly_cst; + +struct isl_poly_rec { + struct isl_poly poly; + int n; + + size_t size; + isl_poly *p[]; +}; +typedef struct isl_poly_rec isl_poly_rec; + +/* dim represents the domain space. + */ +struct isl_qpolynomial { + int ref; + + isl_space *dim; + struct isl_mat *div; + isl_poly *poly; +}; + +#undef EL +#define EL isl_qpolynomial + +#include + +struct isl_term { + int ref; + + isl_int n; + isl_int d; + + isl_space *dim; + struct isl_mat *div; + + int pow[1]; +}; + +struct isl_pw_qpolynomial_piece { + struct isl_set *set; + struct isl_qpolynomial *qp; +}; + +struct isl_pw_qpolynomial { + int ref; + + isl_space *dim; + + int n; + + size_t size; + struct isl_pw_qpolynomial_piece p[1]; +}; + +#undef PW +#define PW isl_pw_qpolynomial + +#include + +#undef EL +#define EL isl_pw_qpolynomial + +#include + +/* dim represents the domain space. + */ +struct isl_qpolynomial_fold { + int ref; + + enum isl_fold type; + isl_space *dim; + + isl_qpolynomial_list *list; +}; + +struct isl_pw_qpolynomial_fold_piece { + struct isl_set *set; + struct isl_qpolynomial_fold *fold; +}; + +struct isl_pw_qpolynomial_fold { + int ref; + + enum isl_fold type; + isl_space *dim; + + int n; + + size_t size; + struct isl_pw_qpolynomial_fold_piece p[1]; +}; + +#undef PW +#define PW isl_pw_qpolynomial_fold + +#include + +#undef EL +#define EL isl_pw_qpolynomial_fold + +#include + +void isl_term_get_num(__isl_keep isl_term *term, isl_int *n); + +__isl_give isl_poly *isl_poly_zero(struct isl_ctx *ctx); +__isl_give isl_poly *isl_poly_copy(__isl_keep isl_poly *poly); +__isl_give isl_poly *isl_poly_cow(__isl_take isl_poly *poly); +__isl_give isl_poly *isl_poly_dup(__isl_keep isl_poly *poly); +__isl_null isl_poly *isl_poly_free(__isl_take isl_poly *poly); +__isl_give struct isl_poly *isl_poly_mul(__isl_take struct isl_poly *poly1, + __isl_take struct isl_poly *poly2); + +isl_bool isl_poly_is_cst(__isl_keep isl_poly *poly); +isl_bool isl_poly_is_zero(__isl_keep isl_poly *poly); +isl_bool isl_poly_is_one(__isl_keep isl_poly *poly); +isl_bool isl_poly_is_negone(__isl_keep isl_poly *poly); +__isl_keep isl_poly_cst *isl_poly_as_cst(__isl_keep isl_poly *poly); +__isl_keep isl_poly_rec *isl_poly_as_rec(__isl_keep isl_poly *poly); + +__isl_give isl_poly *isl_poly_sum(__isl_take isl_poly *poly1, + __isl_take isl_poly *poly2); +__isl_give struct isl_poly *isl_poly_mul_isl_int( + __isl_take isl_poly *poly, isl_int v); + +__isl_give isl_qpolynomial *isl_qpolynomial_alloc(__isl_take isl_space *space, + unsigned n_div, __isl_take isl_poly *poly); +__isl_give isl_qpolynomial *isl_qpolynomial_cow(__isl_take isl_qpolynomial *qp); +__isl_give isl_qpolynomial *isl_qpolynomial_dup(__isl_keep isl_qpolynomial *qp); + +__isl_give isl_qpolynomial *isl_qpolynomial_cst_on_domain( + __isl_take isl_space *domain, + isl_int v); +__isl_give isl_qpolynomial *isl_qpolynomial_rat_cst_on_domain( + __isl_take isl_space *domain, const isl_int n, const isl_int d); +__isl_give isl_qpolynomial *isl_qpolynomial_var_pow_on_domain( + __isl_take isl_space *domain, + int pos, int power); +isl_bool isl_qpolynomial_is_one(__isl_keep isl_qpolynomial *qp); +isl_bool isl_qpolynomial_is_affine(__isl_keep isl_qpolynomial *qp); +isl_bool isl_qpolynomial_is_cst(__isl_keep isl_qpolynomial *qp, + isl_int *n, isl_int *d); + +unsigned isl_qpolynomial_domain_offset(__isl_keep isl_qpolynomial *qp, + enum isl_dim_type type); +__isl_give isl_local *isl_qpolynomial_get_local( + __isl_keep isl_qpolynomial *qp); + +__isl_give isl_qpolynomial *isl_qpolynomial_add_on_domain( + __isl_keep isl_set *dom, + __isl_take isl_qpolynomial *qp1, + __isl_take isl_qpolynomial *qp2); + +int isl_qpolynomial_plain_cmp(__isl_keep isl_qpolynomial *qp1, + __isl_keep isl_qpolynomial *qp2); + +int isl_qpolynomial_degree(__isl_keep isl_qpolynomial *poly); +__isl_give isl_qpolynomial *isl_qpolynomial_coeff( + __isl_keep isl_qpolynomial *poly, + enum isl_dim_type type, unsigned pos, int deg); + +__isl_give isl_vec *isl_qpolynomial_extract_affine( + __isl_keep isl_qpolynomial *qp); +__isl_give isl_qpolynomial *isl_qpolynomial_from_affine( + __isl_take isl_space *space, isl_int *f, isl_int denom); + +__isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_cow( + __isl_take isl_pw_qpolynomial *pwqp); + +__isl_keep isl_qpolynomial *isl_pw_qpolynomial_peek_base_at( + __isl_keep isl_pw_qpolynomial *pwqp, int pos); + +__isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_add_piece( + __isl_take isl_pw_qpolynomial *pwqp, + __isl_take isl_set *set, __isl_take isl_qpolynomial *qp); +int isl_pw_qpolynomial_is_one(__isl_keep isl_pw_qpolynomial *pwqp); + +__isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_project_out( + __isl_take isl_pw_qpolynomial *pwqp, + enum isl_dim_type type, unsigned first, unsigned n); + +__isl_give isl_val *isl_qpolynomial_opt_on_domain( + __isl_take isl_qpolynomial *qp, __isl_take isl_set *set, int max); + +enum isl_fold isl_fold_type_negate(enum isl_fold type); + +__isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_cow( + __isl_take isl_qpolynomial_fold *fold); +__isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_dup( + __isl_keep isl_qpolynomial_fold *fold); + +__isl_keep isl_qpolynomial_list *isl_qpolynomial_fold_peek_list( + __isl_keep isl_qpolynomial_fold *fold); + +__isl_give isl_pw_qpolynomial_fold *isl_pw_qpolynomial_fold_cow( + __isl_take isl_pw_qpolynomial_fold *pwf); + +__isl_keep isl_qpolynomial_fold *isl_pw_qpolynomial_fold_peek_base_at( + __isl_keep isl_pw_qpolynomial_fold *pwf, int pos); + +__isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_add_on_domain( + __isl_keep isl_set *set, + __isl_take isl_qpolynomial_fold *fold1, + __isl_take isl_qpolynomial_fold *fold2); +__isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_fold_on_domain( + __isl_keep isl_set *set, + __isl_take isl_qpolynomial_fold *fold1, + __isl_take isl_qpolynomial_fold *fold2); + +int isl_qpolynomial_fold_plain_cmp(__isl_keep isl_qpolynomial_fold *fold1, + __isl_keep isl_qpolynomial_fold *fold2); + +__isl_give isl_val *isl_qpolynomial_fold_opt_on_domain( + __isl_take isl_qpolynomial_fold *fold, __isl_take isl_set *set, int max); + +isl_bool isl_pw_qpolynomial_fold_covers( + __isl_keep isl_pw_qpolynomial_fold *pwf1, + __isl_keep isl_pw_qpolynomial_fold *pwf2); + +__isl_give isl_qpolynomial *isl_qpolynomial_morph_domain( + __isl_take isl_qpolynomial *qp, __isl_take isl_morph *morph); +__isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_morph_domain( + __isl_take isl_pw_qpolynomial *pwqp, __isl_take isl_morph *morph); +__isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_morph_domain( + __isl_take isl_qpolynomial_fold *fold, __isl_take isl_morph *morph); +__isl_give isl_pw_qpolynomial_fold *isl_pw_qpolynomial_fold_morph_domain( + __isl_take isl_pw_qpolynomial_fold *pwf, __isl_take isl_morph *morph); + +__isl_give isl_qpolynomial *isl_qpolynomial_lift(__isl_take isl_qpolynomial *qp, + __isl_take isl_space *space); +__isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_lift( + __isl_take isl_qpolynomial_fold *fold, __isl_take isl_space *space); + +__isl_give isl_qpolynomial *isl_qpolynomial_substitute_equalities( + __isl_take isl_qpolynomial *qp, __isl_take isl_basic_set *eq); +__isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_substitute_equalities( + __isl_take isl_qpolynomial_fold *fold, __isl_take isl_basic_set *eq); +__isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_gist( + __isl_take isl_qpolynomial_fold *fold, __isl_take isl_set *context); + +__isl_give isl_qpolynomial *isl_qpolynomial_realign_domain( + __isl_take isl_qpolynomial *qp, __isl_take isl_reordering *r); +__isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_realign_domain( + __isl_take isl_qpolynomial_fold *fold, __isl_take isl_reordering *r); + +__isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_reset_space( + __isl_take isl_pw_qpolynomial *pwqp, __isl_take isl_space *space); +__isl_give isl_qpolynomial *isl_qpolynomial_reset_domain_space( + __isl_take isl_qpolynomial *qp, __isl_take isl_space *space); +__isl_give isl_qpolynomial *isl_qpolynomial_reset_space_and_domain( + __isl_take isl_qpolynomial *qp, __isl_take isl_space *space, + __isl_take isl_space *domain); +__isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_reset_domain_space( + __isl_take isl_qpolynomial_fold *fold, __isl_take isl_space *space); +__isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_reset_space_and_domain( + __isl_take isl_qpolynomial_fold *fold, __isl_take isl_space *space, + __isl_take isl_space *domain); +__isl_give isl_pw_qpolynomial_fold *isl_pw_qpolynomial_fold_reset_domain_space( + __isl_take isl_pw_qpolynomial_fold *pwf, __isl_take isl_space *space); + +__isl_give isl_val *isl_qpolynomial_get_den(__isl_keep isl_qpolynomial *qp); +__isl_give isl_qpolynomial *isl_qpolynomial_add_isl_int( + __isl_take isl_qpolynomial *qp, isl_int v); +__isl_give isl_qpolynomial *isl_qpolynomial_mul_isl_int( + __isl_take isl_qpolynomial *qp, 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_DECLARE_LIST_FN_PRIVATE(qpolynomial) diff --git a/external/mit/isl/dist/isl_power_templ.c b/external/mit/isl/dist/isl_power_templ.c new file mode 100644 index 000000000000..26f0fe5573bf --- /dev/null +++ b/external/mit/isl/dist/isl_power_templ.c @@ -0,0 +1,98 @@ +#include + +#define xFN(TYPE,NAME) TYPE ## _ ## NAME +#define FN(TYPE,NAME) xFN(TYPE,NAME) + +/* Helper function for isl_*_fixed_power that applies (a copy of) "map2" + * to the range of "map1" and returns the result. + * + * The result is coalesced in an attempt to reduce the number of disjuncts + * that result from repeated applications. + * Similarly, look for implicit equality constraints in an attempt + * to reduce the number of local variables that get introduced + * during the repeated applications. + */ +static __isl_give TYPE *FN(TYPE,fixed_power_apply)(__isl_take TYPE *map1, + __isl_keep TYPE *map2) +{ + TYPE *res; + + res = FN(TYPE,apply_range)(map1, FN(TYPE,copy)(map2)); + res = FN(TYPE,detect_equalities)(res); + res = FN(TYPE,coalesce)(res); + + return res; +} + +/* Compute the given non-zero power of "map" and return the result. + * If the exponent "exp" is negative, then the -exp th power of the inverse + * relation is computed. + */ +__isl_give TYPE *FN(TYPE,fixed_power)(__isl_take TYPE *map, isl_int exp) +{ + isl_ctx *ctx; + TYPE *res = NULL; + isl_int r; + + if (!map) + return NULL; + + ctx = FN(TYPE,get_ctx)(map); + if (isl_int_is_zero(exp)) + isl_die(ctx, isl_error_invalid, + "expecting non-zero exponent", goto error); + + if (isl_int_is_neg(exp)) { + isl_int_neg(exp, exp); + map = FN(TYPE,reverse)(map); + return FN(TYPE,fixed_power)(map, exp); + } + + isl_int_init(r); + for (;;) { + isl_int_fdiv_r(r, exp, ctx->two); + + if (!isl_int_is_zero(r)) { + if (!res) + res = FN(TYPE,copy)(map); + else + res = FN(TYPE,fixed_power_apply)(res, map); + if (!res) + break; + } + + isl_int_fdiv_q(exp, exp, ctx->two); + if (isl_int_is_zero(exp)) + break; + + map = FN(TYPE,fixed_power_apply)(map, map); + } + isl_int_clear(r); + + FN(TYPE,free)(map); + return res; +error: + FN(TYPE,free)(map); + return NULL; +} + +/* Compute the given non-zero power of "map" and return the result. + * If the exponent "exp" is negative, then the -exp th power of the inverse + * relation is computed. + */ +__isl_give TYPE *FN(TYPE,fixed_power_val)(__isl_take TYPE *map, + __isl_take isl_val *exp) +{ + if (!map || !exp) + goto error; + if (!isl_val_is_int(exp)) + isl_die(FN(TYPE,get_ctx)(map), isl_error_invalid, + "expecting integer exponent", goto error); + map = FN(TYPE,fixed_power)(map, exp->n); + isl_val_free(exp); + return map; +error: + FN(TYPE,free)(map); + isl_val_free(exp); + return NULL; +} diff --git a/external/mit/isl/dist/isl_printer.c b/external/mit/isl/dist/isl_printer.c new file mode 100644 index 000000000000..f58a8a7aaa72 --- /dev/null +++ b/external/mit/isl/dist/isl_printer.c @@ -0,0 +1,851 @@ +#include +#include +#include +#include +#include + +static __isl_give isl_printer *file_start_line(__isl_take isl_printer *p) +{ + fprintf(p->file, "%s%*s%s", p->indent_prefix ? p->indent_prefix : "", + p->indent, "", p->prefix ? p->prefix : ""); + return p; +} + +static __isl_give isl_printer *file_end_line(__isl_take isl_printer *p) +{ + fprintf(p->file, "%s\n", p->suffix ? p->suffix : ""); + return p; +} + +static __isl_give isl_printer *file_flush(__isl_take isl_printer *p) +{ + fflush(p->file); + return p; +} + +static __isl_give isl_printer *file_print_str(__isl_take isl_printer *p, + const char *s) +{ + fprintf(p->file, "%s", s); + return p; +} + +static __isl_give isl_printer *file_print_double(__isl_take isl_printer *p, + double d) +{ + fprintf(p->file, "%g", d); + return p; +} + +static __isl_give isl_printer *file_print_int(__isl_take isl_printer *p, int i) +{ + fprintf(p->file, "%d", i); + return p; +} + +static __isl_give isl_printer *file_print_isl_int(__isl_take isl_printer *p, isl_int i) +{ + isl_int_print(p->file, i, p->width); + return p; +} + +static int grow_buf(__isl_keep isl_printer *p, int extra) +{ + int new_size; + char *new_buf; + + if (p->buf_size == 0) + return -1; + + new_size = ((p->buf_n + extra + 1) * 3) / 2; + new_buf = isl_realloc_array(p->ctx, p->buf, char, new_size); + if (!new_buf) { + p->buf_size = 0; + return -1; + } + p->buf = new_buf; + p->buf_size = new_size; + + return 0; +} + +static __isl_give isl_printer *str_print(__isl_take isl_printer *p, + const char *s, int len) +{ + if (p->buf_n + len + 1 >= p->buf_size && grow_buf(p, len)) + goto error; + memcpy(p->buf + p->buf_n, s, len); + p->buf_n += len; + + p->buf[p->buf_n] = '\0'; + return p; +error: + isl_printer_free(p); + return NULL; +} + +static __isl_give isl_printer *str_print_indent(__isl_take isl_printer *p, + int indent) +{ + int i; + + if (p->buf_n + indent + 1 >= p->buf_size && grow_buf(p, indent)) + goto error; + for (i = 0; i < indent; ++i) + p->buf[p->buf_n++] = ' '; + p->buf[p->buf_n] = '\0'; + return p; +error: + isl_printer_free(p); + return NULL; +} + +static __isl_give isl_printer *str_start_line(__isl_take isl_printer *p) +{ + if (p->indent_prefix) + p = str_print(p, p->indent_prefix, strlen(p->indent_prefix)); + p = str_print_indent(p, p->indent); + if (p->prefix) + p = str_print(p, p->prefix, strlen(p->prefix)); + return p; +} + +static __isl_give isl_printer *str_end_line(__isl_take isl_printer *p) +{ + if (p->suffix) + p = str_print(p, p->suffix, strlen(p->suffix)); + p = str_print(p, "\n", strlen("\n")); + return p; +} + +static __isl_give isl_printer *str_flush(__isl_take isl_printer *p) +{ + p->buf_n = 0; + p->buf[p->buf_n] = '\0'; + return p; +} + +static __isl_give isl_printer *str_print_str(__isl_take isl_printer *p, + const char *s) +{ + return str_print(p, s, strlen(s)); +} + +static __isl_give isl_printer *str_print_double(__isl_take isl_printer *p, + double d) +{ + int left = p->buf_size - p->buf_n; + int need = snprintf(p->buf + p->buf_n, left, "%g", d); + if (need >= left) { + if (grow_buf(p, need)) + goto error; + left = p->buf_size - p->buf_n; + need = snprintf(p->buf + p->buf_n, left, "%g", d); + } + p->buf_n += need; + return p; +error: + isl_printer_free(p); + return NULL; +} + +static __isl_give isl_printer *str_print_int(__isl_take isl_printer *p, int i) +{ + int left = p->buf_size - p->buf_n; + int need = snprintf(p->buf + p->buf_n, left, "%d", i); + if (need >= left) { + if (grow_buf(p, need)) + goto error; + left = p->buf_size - p->buf_n; + need = snprintf(p->buf + p->buf_n, left, "%d", i); + } + p->buf_n += need; + return p; +error: + isl_printer_free(p); + return NULL; +} + +static __isl_give isl_printer *str_print_isl_int(__isl_take isl_printer *p, + isl_int i) +{ + char *s; + int len; + + s = isl_int_get_str(i); + len = strlen(s); + if (len < p->width) + p = str_print_indent(p, p->width - len); + p = str_print(p, s, len); + isl_int_free_str(s); + return p; +} + +struct isl_printer_ops { + __isl_give isl_printer *(*start_line)(__isl_take isl_printer *p); + __isl_give isl_printer *(*end_line)(__isl_take isl_printer *p); + __isl_give isl_printer *(*print_double)(__isl_take isl_printer *p, + double d); + __isl_give isl_printer *(*print_int)(__isl_take isl_printer *p, int i); + __isl_give isl_printer *(*print_isl_int)(__isl_take isl_printer *p, + isl_int i); + __isl_give isl_printer *(*print_str)(__isl_take isl_printer *p, + const char *s); + __isl_give isl_printer *(*flush)(__isl_take isl_printer *p); +}; + +static struct isl_printer_ops file_ops = { + file_start_line, + file_end_line, + file_print_double, + file_print_int, + file_print_isl_int, + file_print_str, + file_flush +}; + +static struct isl_printer_ops str_ops = { + str_start_line, + str_end_line, + str_print_double, + str_print_int, + str_print_isl_int, + str_print_str, + str_flush +}; + +__isl_give isl_printer *isl_printer_to_file(isl_ctx *ctx, FILE *file) +{ + struct isl_printer *p = isl_calloc_type(ctx, struct isl_printer); + if (!p) + return NULL; + p->ctx = ctx; + isl_ctx_ref(p->ctx); + p->ops = &file_ops; + p->file = file; + p->buf = NULL; + p->buf_n = 0; + p->buf_size = 0; + p->indent = 0; + p->output_format = ISL_FORMAT_ISL; + p->indent_prefix = NULL; + p->prefix = NULL; + p->suffix = NULL; + p->width = 0; + p->yaml_style = ISL_YAML_STYLE_FLOW; + + return p; +} + +__isl_give isl_printer *isl_printer_to_str(isl_ctx *ctx) +{ + struct isl_printer *p = isl_calloc_type(ctx, struct isl_printer); + if (!p) + return NULL; + p->ctx = ctx; + isl_ctx_ref(p->ctx); + p->ops = &str_ops; + p->file = NULL; + p->buf = isl_alloc_array(ctx, char, 256); + if (!p->buf) + goto error; + p->buf_n = 0; + p->buf[0] = '\0'; + p->buf_size = 256; + p->indent = 0; + p->output_format = ISL_FORMAT_ISL; + p->indent_prefix = NULL; + p->prefix = NULL; + p->suffix = NULL; + p->width = 0; + p->yaml_style = ISL_YAML_STYLE_FLOW; + + return p; +error: + isl_printer_free(p); + return NULL; +} + +__isl_null isl_printer *isl_printer_free(__isl_take isl_printer *p) +{ + if (!p) + return NULL; + free(p->buf); + free(p->indent_prefix); + free(p->prefix); + free(p->suffix); + free(p->yaml_state); + isl_id_to_id_free(p->notes); + isl_ctx_deref(p->ctx); + free(p); + + return NULL; +} + +isl_ctx *isl_printer_get_ctx(__isl_keep isl_printer *printer) +{ + return printer ? printer->ctx : NULL; +} + +FILE *isl_printer_get_file(__isl_keep isl_printer *printer) +{ + if (!printer) + return NULL; + if (!printer->file) + isl_die(isl_printer_get_ctx(printer), isl_error_invalid, + "not a file printer", return NULL); + return printer->file; +} + +__isl_give isl_printer *isl_printer_set_isl_int_width(__isl_take isl_printer *p, + int width) +{ + if (!p) + return NULL; + + p->width = width; + + return p; +} + +__isl_give isl_printer *isl_printer_set_indent(__isl_take isl_printer *p, + int indent) +{ + if (!p) + return NULL; + + p->indent = indent; + + return p; +} + +__isl_give isl_printer *isl_printer_indent(__isl_take isl_printer *p, + int indent) +{ + if (!p) + return NULL; + + p->indent += indent; + if (p->indent < 0) + p->indent = 0; + + return p; +} + +/* Replace the indent prefix of "p" by "prefix". + */ +__isl_give isl_printer *isl_printer_set_indent_prefix(__isl_take isl_printer *p, + const char *prefix) +{ + if (!p) + return NULL; + + free(p->indent_prefix); + p->indent_prefix = prefix ? strdup(prefix) : NULL; + + return p; +} + +__isl_give isl_printer *isl_printer_set_prefix(__isl_take isl_printer *p, + const char *prefix) +{ + if (!p) + return NULL; + + free(p->prefix); + p->prefix = prefix ? strdup(prefix) : NULL; + + return p; +} + +__isl_give isl_printer *isl_printer_set_suffix(__isl_take isl_printer *p, + const char *suffix) +{ + if (!p) + return NULL; + + free(p->suffix); + p->suffix = suffix ? strdup(suffix) : NULL; + + return p; +} + +__isl_give isl_printer *isl_printer_set_output_format(__isl_take isl_printer *p, + int output_format) +{ + if (!p) + return NULL; + + p->output_format = output_format; + + return p; +} + +int isl_printer_get_output_format(__isl_keep isl_printer *p) +{ + if (!p) + return -1; + return p->output_format; +} + +/* Does "p" have a note with identifier "id"? + */ +isl_bool isl_printer_has_note(__isl_keep isl_printer *p, + __isl_keep isl_id *id) +{ + if (!p || !id) + return isl_bool_error; + if (!p->notes) + return isl_bool_false; + return isl_id_to_id_has(p->notes, id); +} + +/* Retrieve the note identified by "id" from "p". + * The note is assumed to exist. + */ +__isl_give isl_id *isl_printer_get_note(__isl_keep isl_printer *p, + __isl_take isl_id *id) +{ + isl_bool has_note; + + has_note = isl_printer_has_note(p, id); + if (has_note < 0) + goto error; + if (!has_note) + isl_die(isl_printer_get_ctx(p), isl_error_invalid, + "no such note", goto error); + + return isl_id_to_id_get(p->notes, id); +error: + isl_id_free(id); + return NULL; +} + +/* Associate "note" to the identifier "id" in "p", + * replacing the previous note associated to the identifier, if any. + */ +__isl_give isl_printer *isl_printer_set_note(__isl_take isl_printer *p, + __isl_take isl_id *id, __isl_take isl_id *note) +{ + if (!p || !id || !note) + goto error; + if (!p->notes) { + p->notes = isl_id_to_id_alloc(isl_printer_get_ctx(p), 1); + if (!p->notes) + goto error; + } + p->notes = isl_id_to_id_set(p->notes, id, note); + if (!p->notes) + return isl_printer_free(p); + return p; +error: + isl_printer_free(p); + isl_id_free(id); + isl_id_free(note); + return NULL; +} + +/* Keep track of whether the printing to "p" is being performed from + * an isl_*_dump function as specified by "dump". + */ +__isl_give isl_printer *isl_printer_set_dump(__isl_take isl_printer *p, + int dump) +{ + if (!p) + return NULL; + + p->dump = dump; + + return p; +} + +/* Set the YAML style of "p" to "yaml_style" and return the updated printer. + */ +__isl_give isl_printer *isl_printer_set_yaml_style(__isl_take isl_printer *p, + int yaml_style) +{ + if (!p) + return NULL; + + p->yaml_style = yaml_style; + + return p; +} + +/* Return the YAML style of "p" or -1 on error. + */ +int isl_printer_get_yaml_style(__isl_keep isl_printer *p) +{ + if (!p) + return -1; + return p->yaml_style; +} + +/* Push "state" onto the stack of currently active YAML elements and + * return the updated printer. + */ +static __isl_give isl_printer *push_state(__isl_take isl_printer *p, + enum isl_yaml_state state) +{ + if (!p) + return NULL; + + if (p->yaml_size < p->yaml_depth + 1) { + enum isl_yaml_state *state; + state = isl_realloc_array(p->ctx, p->yaml_state, + enum isl_yaml_state, p->yaml_depth + 1); + if (!state) + return isl_printer_free(p); + p->yaml_state = state; + p->yaml_size = p->yaml_depth + 1; + } + + p->yaml_state[p->yaml_depth] = state; + p->yaml_depth++; + + return p; +} + +/* Remove the innermost active YAML element from the stack and + * return the updated printer. + */ +static __isl_give isl_printer *pop_state(__isl_take isl_printer *p) +{ + if (!p) + return NULL; + p->yaml_depth--; + return p; +} + +/* Set the state of the innermost active YAML element to "state" and + * return the updated printer. + */ +static __isl_give isl_printer *update_state(__isl_take isl_printer *p, + enum isl_yaml_state state) +{ + if (!p) + return NULL; + if (p->yaml_depth < 1) + isl_die(isl_printer_get_ctx(p), isl_error_invalid, + "not in YAML construct", return isl_printer_free(p)); + + p->yaml_state[p->yaml_depth - 1] = state; + + return p; +} + +/* Return the state of the innermost active YAML element. + * Return isl_yaml_none if we are not inside any YAML element. + */ +static enum isl_yaml_state current_state(__isl_keep isl_printer *p) +{ + if (!p) + return isl_yaml_none; + if (p->yaml_depth < 1) + return isl_yaml_none; + return p->yaml_state[p->yaml_depth - 1]; +} + +/* If we are printing a YAML document and we are at the start of an element, + * print whatever is needed before we can print the actual element and + * keep track of the fact that we are now printing the element. + * If "eol" is set, then whatever we print is going to be the last + * thing that gets printed on this line. + * + * If we are about the print the first key of a mapping, then nothing + * extra needs to be printed. For any other key, however, we need + * to either move to the next line (in block format) or print a comma + * (in flow format). + * Before printing a value in a mapping, we need to print a colon. + * + * For sequences, in flow format, we only need to print a comma + * for each element except the first. + * In block format, before the first element in the sequence, + * we move to a new line, print a dash and increase the indentation. + * Before any other element, we print a dash on a new line, + * temporarily moving the indentation back. + */ +static __isl_give isl_printer *enter_state(__isl_take isl_printer *p, + int eol) +{ + enum isl_yaml_state state; + + if (!p) + return NULL; + + state = current_state(p); + if (state == isl_yaml_mapping_val_start) { + if (eol) + p = p->ops->print_str(p, ":"); + else + p = p->ops->print_str(p, ": "); + p = update_state(p, isl_yaml_mapping_val); + } else if (state == isl_yaml_mapping_first_key_start) { + p = update_state(p, isl_yaml_mapping_key); + } else if (state == isl_yaml_mapping_key_start) { + if (p->yaml_style == ISL_YAML_STYLE_FLOW) + p = p->ops->print_str(p, ", "); + else { + p = p->ops->end_line(p); + p = p->ops->start_line(p); + } + p = update_state(p, isl_yaml_mapping_key); + } else if (state == isl_yaml_sequence_first_start) { + if (p->yaml_style != ISL_YAML_STYLE_FLOW) { + p = p->ops->end_line(p); + p = p->ops->start_line(p); + p = p->ops->print_str(p, "- "); + p = isl_printer_indent(p, 2); + } + p = update_state(p, isl_yaml_sequence); + } else if (state == isl_yaml_sequence_start) { + if (p->yaml_style == ISL_YAML_STYLE_FLOW) + p = p->ops->print_str(p, ", "); + else { + p = p->ops->end_line(p); + p = isl_printer_indent(p, -2); + p = p->ops->start_line(p); + p = p->ops->print_str(p, "- "); + p = isl_printer_indent(p, 2); + } + p = update_state(p, isl_yaml_sequence); + } + + return p; +} + +__isl_give isl_printer *isl_printer_print_str(__isl_take isl_printer *p, + const char *s) +{ + if (!p) + return NULL; + if (!s) + return isl_printer_free(p); + p = enter_state(p, 0); + if (!p) + return NULL; + return p->ops->print_str(p, s); +} + +__isl_give isl_printer *isl_printer_print_double(__isl_take isl_printer *p, + double d) +{ + p = enter_state(p, 0); + if (!p) + return NULL; + + return p->ops->print_double(p, d); +} + +__isl_give isl_printer *isl_printer_print_int(__isl_take isl_printer *p, int i) +{ + p = enter_state(p, 0); + if (!p) + return NULL; + + return p->ops->print_int(p, i); +} + +__isl_give isl_printer *isl_printer_print_isl_int(__isl_take isl_printer *p, + isl_int i) +{ + p = enter_state(p, 0); + if (!p) + return NULL; + + return p->ops->print_isl_int(p, i); +} + +__isl_give isl_printer *isl_printer_start_line(__isl_take isl_printer *p) +{ + if (!p) + return NULL; + + return p->ops->start_line(p); +} + +__isl_give isl_printer *isl_printer_end_line(__isl_take isl_printer *p) +{ + if (!p) + return NULL; + + return p->ops->end_line(p); +} + +/* Return a copy of the string constructed by the string printer "printer". + */ +__isl_give char *isl_printer_get_str(__isl_keep isl_printer *printer) +{ + if (!printer) + return NULL; + if (printer->ops != &str_ops) + isl_die(isl_printer_get_ctx(printer), isl_error_invalid, + "isl_printer_get_str can only be called on a string " + "printer", return NULL); + if (!printer->buf) + return NULL; + return strdup(printer->buf); +} + +__isl_give isl_printer *isl_printer_flush(__isl_take isl_printer *p) +{ + if (!p) + return NULL; + + return p->ops->flush(p); +} + +/* Start a YAML mapping and push a new state to reflect that we + * are about to print the first key in a mapping. + * + * In flow style, print the opening brace. + * In block style, move to the next line with an increased indentation, + * except if this is the outer mapping or if we are inside a sequence + * (in which case we have already increased the indentation and we want + * to print the first key on the same line as the dash). + */ +__isl_give isl_printer *isl_printer_yaml_start_mapping( + __isl_take isl_printer *p) +{ + enum isl_yaml_state state; + + if (!p) + return NULL; + p = enter_state(p, p->yaml_style == ISL_YAML_STYLE_BLOCK); + if (!p) + return NULL; + state = current_state(p); + if (p->yaml_style == ISL_YAML_STYLE_FLOW) + p = p->ops->print_str(p, "{ "); + else if (state != isl_yaml_none && state != isl_yaml_sequence) { + p = p->ops->end_line(p); + p = isl_printer_indent(p, 2); + p = p->ops->start_line(p); + } + p = push_state(p, isl_yaml_mapping_first_key_start); + return p; +} + +/* Finish a YAML mapping and pop it from the state stack. + * + * In flow style, print the closing brace. + * + * In block style, first check if we are still in the + * isl_yaml_mapping_first_key_start state. If so, we have not printed + * anything yet, so print "{}" to indicate an empty mapping. + * If we increased the indentation in isl_printer_yaml_start_mapping, + * then decrease it again. + * If this is the outer mapping then print a newline. + */ +__isl_give isl_printer *isl_printer_yaml_end_mapping( + __isl_take isl_printer *p) +{ + enum isl_yaml_state state; + + state = current_state(p); + p = pop_state(p); + if (!p) + return NULL; + if (p->yaml_style == ISL_YAML_STYLE_FLOW) + return p->ops->print_str(p, " }"); + if (state == isl_yaml_mapping_first_key_start) + p = p->ops->print_str(p, "{}"); + if (!p) + return NULL; + state = current_state(p); + if (state != isl_yaml_none && state != isl_yaml_sequence) + p = isl_printer_indent(p, -2); + if (state == isl_yaml_none) + p = p->ops->end_line(p); + return p; +} + +/* Start a YAML sequence and push a new state to reflect that we + * are about to print the first element in a sequence. + * + * In flow style, print the opening bracket. + */ +__isl_give isl_printer *isl_printer_yaml_start_sequence( + __isl_take isl_printer *p) +{ + if (!p) + return NULL; + p = enter_state(p, p->yaml_style == ISL_YAML_STYLE_BLOCK); + p = push_state(p, isl_yaml_sequence_first_start); + if (!p) + return NULL; + if (p->yaml_style == ISL_YAML_STYLE_FLOW) + p = p->ops->print_str(p, "[ "); + return p; +} + +/* Finish a YAML sequence and pop it from the state stack. + * + * In flow style, print the closing bracket. + * + * In block style, check if we are still in the + * isl_yaml_sequence_first_start state. If so, we have not printed + * anything yet, so print "[]" or " []" to indicate an empty sequence. + * We print the extra space when we instructed enter_state not + * to print a space at the end of the line. + * Otherwise, undo the increase in indentation performed by + * enter_state when moving away from the isl_yaml_sequence_first_start + * state. + * If this is the outer sequence then print a newline. + */ +__isl_give isl_printer *isl_printer_yaml_end_sequence( + __isl_take isl_printer *p) +{ + enum isl_yaml_state state, up; + + state = current_state(p); + p = pop_state(p); + if (!p) + return NULL; + if (p->yaml_style == ISL_YAML_STYLE_FLOW) + return p->ops->print_str(p, " ]"); + up = current_state(p); + if (state == isl_yaml_sequence_first_start) { + if (up == isl_yaml_mapping_val) + p = p->ops->print_str(p, " []"); + else + p = p->ops->print_str(p, "[]"); + } else { + p = isl_printer_indent(p, -2); + } + if (!p) + return NULL; + state = current_state(p); + if (state == isl_yaml_none) + p = p->ops->end_line(p); + return p; +} + +/* Mark the fact that the current element is finished and that + * the next output belongs to the next element. + * In particular, if we are printing a key, then prepare for + * printing the subsequent value. If we are printing a value, + * prepare for printing the next key. If we are printing an + * element in a sequence, prepare for printing the next element. + */ +__isl_give isl_printer *isl_printer_yaml_next(__isl_take isl_printer *p) +{ + enum isl_yaml_state state; + + if (!p) + return NULL; + if (p->yaml_depth < 1) + isl_die(isl_printer_get_ctx(p), isl_error_invalid, + "not in YAML construct", return isl_printer_free(p)); + + state = current_state(p); + if (state == isl_yaml_mapping_key) + state = isl_yaml_mapping_val_start; + else if (state == isl_yaml_mapping_val) + state = isl_yaml_mapping_key_start; + else if (state == isl_yaml_sequence) + state = isl_yaml_sequence_start; + p = update_state(p, state); + + return p; +} diff --git a/external/mit/isl/dist/isl_printer_private.h b/external/mit/isl/dist/isl_printer_private.h new file mode 100644 index 000000000000..6b852e8bc47c --- /dev/null +++ b/external/mit/isl/dist/isl_printer_private.h @@ -0,0 +1,52 @@ +#ifndef ISL_PRINTER_PRIVATE_H +#define ISL_PRINTER_PRIVATE_H + +#include +#include +#include + +struct isl_printer_ops; + +/* A printer to a file or a string. + * + * "dump" is set if the printing is performed from an isl_*_dump function. + * + * yaml_style is the YAML style in which the next elements should + * be printed and may be either ISL_YAML_STYLE_BLOCK or ISL_YAML_STYLE_FLOW, + * with ISL_YAML_STYLE_FLOW being the default. + * yaml_state keeps track of the currently active YAML elements. + * yaml_size is the size of this arrays, while yaml_depth + * is the number of elements currently in use. + * yaml_state may be NULL if no YAML printing is being performed. + * + * notes keeps track of arbitrary notes as a mapping between + * name identifiers and note identifiers. It may be NULL + * if there are no notes yet. + */ +struct isl_printer { + struct isl_ctx *ctx; + struct isl_printer_ops *ops; + FILE *file; + int buf_n; + int buf_size; + char *buf; + int indent; + int output_format; + int dump; + char *indent_prefix; + char *prefix; + char *suffix; + int width; + + int yaml_style; + int yaml_depth; + int yaml_size; + enum isl_yaml_state *yaml_state; + + isl_id_to_id *notes; +}; + +__isl_give isl_printer *isl_printer_set_dump(__isl_take isl_printer *p, + int dump); + +#endif diff --git a/external/mit/isl/dist/isl_project_out_all_params_templ.c b/external/mit/isl/dist/isl_project_out_all_params_templ.c new file mode 100644 index 000000000000..73f9a8fa4d8f --- /dev/null +++ b/external/mit/isl/dist/isl_project_out_all_params_templ.c @@ -0,0 +1,21 @@ +/* + * Use of this software is governed by the MIT license + * + * Written by Sven Verdoolaege + */ + +#define xFN(TYPE,NAME) TYPE ## _ ## NAME +#define FN(TYPE,NAME) xFN(TYPE,NAME) + +/* Project out all parameters from "obj" by existentially quantifying + * over them. + */ +__isl_give TYPE *FN(TYPE,project_out_all_params)(__isl_take TYPE *obj) +{ + isl_size n; + + n = FN(TYPE,dim)(obj, isl_dim_param); + if (n < 0) + return FN(TYPE,free)(obj); + return FN(TYPE,project_out)(obj, isl_dim_param, 0, n); +} diff --git a/external/mit/isl/dist/isl_project_out_param_templ.c b/external/mit/isl/dist/isl_project_out_param_templ.c new file mode 100644 index 000000000000..f277b7c6c15f --- /dev/null +++ b/external/mit/isl/dist/isl_project_out_param_templ.c @@ -0,0 +1,59 @@ +/* + * Copyright 2019 Cerebras Systems + * + * Use of this software is governed by the MIT license + * + * Written by Sven Verdoolaege, + * Cerebras Systems, 175 S San Antonio Rd, Los Altos, CA, USA + */ + +#define xFN(TYPE,NAME) TYPE ## _ ## NAME +#define FN(TYPE,NAME) xFN(TYPE,NAME) + +/* If "obj" involves a parameter with identifier "id", + * then turn it into an existentially quantified variable. + */ +__isl_give TYPE *FN(TYPE,project_out_param_id)(__isl_take TYPE *obj, + __isl_take isl_id *id) +{ + int pos; + + if (!obj || !id) + goto error; + pos = FN(TYPE,find_dim_by_id)(obj, isl_dim_param, id); + isl_id_free(id); + if (pos < 0) + return obj; + return FN(TYPE,project_out)(obj, isl_dim_param, pos, 1); +error: + FN(TYPE,free)(obj); + isl_id_free(id); + return NULL; +} + +/* If "obj" involves any of the parameters with identifiers in "list", + * then turn them into existentially quantified variables. + */ +__isl_give TYPE *FN(TYPE,project_out_param_id_list)(__isl_take TYPE *obj, + __isl_take isl_id_list *list) +{ + int i; + isl_size n; + + n = isl_id_list_size(list); + if (n < 0) + goto error; + for (i = 0; i < n; ++i) { + isl_id *id; + + id = isl_id_list_get_at(list, i); + obj = FN(TYPE,project_out_param_id)(obj, id); + } + + isl_id_list_free(list); + return obj; +error: + isl_id_list_free(list); + FN(TYPE,free)(obj); + return NULL; +} diff --git a/external/mit/isl/dist/isl_pw_add_constant_multi_val_templ.c b/external/mit/isl/dist/isl_pw_add_constant_multi_val_templ.c new file mode 100644 index 000000000000..eccc356cb147 --- /dev/null +++ b/external/mit/isl/dist/isl_pw_add_constant_multi_val_templ.c @@ -0,0 +1,13 @@ +/* + * Copyright 2019 Cerebras Systems + * + * Use of this software is governed by the MIT license + * + * Written by Sven Verdoolaege, + * Cerebras Systems, 175 S San Antonio Rd, Los Altos, CA, USA + */ + +#undef VAL_BASE +#define VAL_BASE multi_val + +#include diff --git a/external/mit/isl/dist/isl_pw_add_constant_templ.c b/external/mit/isl/dist/isl_pw_add_constant_templ.c new file mode 100644 index 000000000000..db60e4f7ab7f --- /dev/null +++ b/external/mit/isl/dist/isl_pw_add_constant_templ.c @@ -0,0 +1,47 @@ +/* + * Copyright 2019 Cerebras Systems + * + * Use of this software is governed by the MIT license + * + * Written by Sven Verdoolaege, + * Cerebras Systems, 175 S San Antonio Rd, Los Altos, CA, USA + */ + +#include + +#undef VAL +#define VAL CAT(isl_,VAL_BASE) + +/* Add "v" to the constant term of "pw" over its entire definition domain. + */ +__isl_give PW *FN(FN(PW,add_constant),VAL_BASE)(__isl_take PW *pw, + __isl_take VAL *v) +{ + isl_bool zero; + isl_size n; + int i; + + zero = FN(VAL,is_zero)(v); + n = FN(PW,n_piece)(pw); + if (zero < 0 || n < 0) + goto error; + if (zero || n == 0) { + FN(VAL,free)(v); + return pw; + } + + for (i = 0; i < n; ++i) { + EL *el; + + el = FN(PW,take_base_at)(pw, i); + el = FN(FN(EL,add_constant),VAL_BASE)(el, FN(VAL,copy)(v)); + pw = FN(PW,restore_base_at)(pw, i, el); + } + + FN(VAL,free)(v); + return pw; +error: + FN(PW,free)(pw); + FN(VAL,free)(v); + return NULL; +} diff --git a/external/mit/isl/dist/isl_pw_add_constant_val_templ.c b/external/mit/isl/dist/isl_pw_add_constant_val_templ.c new file mode 100644 index 000000000000..d63ec04936e7 --- /dev/null +++ b/external/mit/isl/dist/isl_pw_add_constant_val_templ.c @@ -0,0 +1,13 @@ +/* + * Copyright 2019 Cerebras Systems + * + * Use of this software is governed by the MIT license + * + * Written by Sven Verdoolaege, + * Cerebras Systems, 175 S San Antonio Rd, Los Altos, CA, USA + */ + +#undef VAL_BASE +#define VAL_BASE val + +#include diff --git a/external/mit/isl/dist/isl_pw_add_disjoint_templ.c b/external/mit/isl/dist/isl_pw_add_disjoint_templ.c new file mode 100644 index 000000000000..160b9b5ef31e --- /dev/null +++ b/external/mit/isl/dist/isl_pw_add_disjoint_templ.c @@ -0,0 +1,93 @@ +/* + * Copyright 2010 INRIA Saclay + * Copyright 2011 Sven Verdoolaege + * + * 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 + */ + +#include + +/* Make sure "pw" has room for at least "n" more pieces. + * + * If there is only one reference to pw, we extend it in place. + * Otherwise, we create a new PW and copy the pieces. + */ +static __isl_give PW *FN(PW,grow)(__isl_take PW *pw, int n) +{ + int i; + isl_ctx *ctx; + PW *res; + + if (!pw) + return NULL; + if (pw->n + n <= pw->size) + return pw; + ctx = FN(PW,get_ctx)(pw); + n += pw->n; + if (pw->ref == 1) { + res = isl_realloc(ctx, pw, struct PW, + sizeof(struct PW) + (n - 1) * sizeof(S(PW,piece))); + if (!res) + return FN(PW,free)(pw); + res->size = n; + return res; + } + res = FN(PW,alloc_size)(isl_space_copy(pw->dim) OPT_TYPE_ARG(pw->), n); + if (!res) + return FN(PW,free)(pw); + for (i = 0; i < pw->n; ++i) + res = FN(PW,add_piece)(res, isl_set_copy(pw->p[i].set), + FN(EL,copy)(pw->p[i].FIELD)); + FN(PW,free)(pw); + return res; +} + +__isl_give PW *FN(PW,add_disjoint)(__isl_take PW *pw1, __isl_take PW *pw2) +{ + int i; + isl_ctx *ctx; + + if (FN(PW,align_params_bin)(&pw1, &pw2) < 0) + goto error; + + if (pw1->size < pw1->n + pw2->n && pw1->n < pw2->n) + return FN(PW,add_disjoint)(pw2, pw1); + + ctx = isl_space_get_ctx(pw1->dim); + if (!OPT_EQUAL_TYPES(pw1->, pw2->)) + isl_die(ctx, isl_error_invalid, + "fold types don't match", goto error); + if (FN(PW,check_equal_space)(pw1, pw2) < 0) + goto error; + + if (FN(PW,IS_ZERO)(pw1)) { + FN(PW,free)(pw1); + return pw2; + } + + if (FN(PW,IS_ZERO)(pw2)) { + FN(PW,free)(pw2); + return pw1; + } + + pw1 = FN(PW,grow)(pw1, pw2->n); + if (!pw1) + goto error; + + for (i = 0; i < pw2->n; ++i) + pw1 = FN(PW,add_piece)(pw1, + isl_set_copy(pw2->p[i].set), + FN(EL,copy)(pw2->p[i].FIELD)); + + FN(PW,free)(pw2); + + return pw1; +error: + FN(PW,free)(pw1); + FN(PW,free)(pw2); + return NULL; +} diff --git a/external/mit/isl/dist/isl_pw_bind_domain_templ.c b/external/mit/isl/dist/isl_pw_bind_domain_templ.c new file mode 100644 index 000000000000..2a01495b8168 --- /dev/null +++ b/external/mit/isl/dist/isl_pw_bind_domain_templ.c @@ -0,0 +1,14 @@ +/* + * Copyright 2018 Cerebras Systems + * + * Use of this software is governed by the MIT license + * + * Written by Sven Verdoolaege, + * Cerebras Systems, 175 S San Antonio Rd, Los Altos, CA, USA + */ + +#include + +#undef TYPE +#define TYPE PW +#include diff --git a/external/mit/isl/dist/isl_pw_domain_reverse_templ.c b/external/mit/isl/dist/isl_pw_domain_reverse_templ.c new file mode 100644 index 000000000000..54700025c398 --- /dev/null +++ b/external/mit/isl/dist/isl_pw_domain_reverse_templ.c @@ -0,0 +1,25 @@ +/* + * Copyright 2019 Cerebras Systems + * + * Use of this software is governed by the MIT license + * + * Written by Sven Verdoolaege, + * Cerebras Systems, 175 S San Antonio Rd, Los Altos, CA, USA + */ + +#include +#include + +/* Given a piecewise function on a domain (A -> B), + * interchange A and B in the wrapped domain + * to obtain a function on the domain (B -> A). + */ +__isl_give PW *FN(PW,domain_reverse)(__isl_take PW *pw) +{ + S(PW,un_op_control) control = { + .fn_space = &isl_space_domain_reverse, + .fn_domain = &isl_set_wrapped_reverse, + .fn_base = &FN(EL,domain_reverse), + }; + return FN(PW,un_op)(pw, &control); +} diff --git a/external/mit/isl/dist/isl_pw_eval.c b/external/mit/isl/dist/isl_pw_eval.c new file mode 100644 index 000000000000..40396b602ada --- /dev/null +++ b/external/mit/isl/dist/isl_pw_eval.c @@ -0,0 +1,101 @@ +/* + * Copyright 2010 INRIA Saclay + * Copyright 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 +#include +#include + +#include + +#undef SUFFIX +#define SUFFIX point +#undef ARG1 +#define ARG1 PW +#undef ARG2 +#define ARG2 isl_point + +static +#include "isl_align_params_templ.c" + +/* Evaluate "pw" in the void point "pnt". + * In particular, return the value NaN. + */ +static __isl_give isl_val *FN(PW,eval_void)(__isl_take PW *pw, + __isl_take isl_point *pnt) +{ + isl_ctx *ctx; + + ctx = isl_point_get_ctx(pnt); + FN(PW,free)(pw); + isl_point_free(pnt); + return isl_val_nan(ctx); +} + +/* Evaluate the piecewise function "pw" in "pnt". + * If the point is void, then return NaN. + * If the point lies outside the domain of "pw", then return 0 or NaN + * depending on whether 0 is the default value for this type of function. + * + * Align the parameters if needed, but "pnt" should specify a value + * for all parameters in "pw". + */ +__isl_give isl_val *FN(PW,eval)(__isl_take PW *pw, __isl_take isl_point *pnt) +{ + int i; + isl_bool is_void; + isl_bool found; + isl_ctx *ctx; + isl_bool ok; + isl_space *pnt_space, *pw_space; + isl_val *v; + + FN(PW,align_params_point)(&pw, &pnt); + + pnt_space = isl_point_peek_space(pnt); + pw_space = FN(PW,peek_space)(pw); + ok = isl_space_is_domain_internal(pnt_space, pw_space); + if (ok < 0) + goto error; + ctx = isl_point_get_ctx(pnt); + if (!ok) + isl_die(ctx, isl_error_invalid, + "incompatible spaces", goto error); + is_void = isl_point_is_void(pnt); + if (is_void < 0) + goto error; + if (is_void) + return FN(PW,eval_void)(pw, pnt); + + found = isl_bool_false; + for (i = 0; i < pw->n; ++i) { + found = isl_set_contains_point(pw->p[i].set, pnt); + if (found < 0) + goto error; + if (found) + break; + } + if (found) { + v = FN(EL,eval)(FN(EL,copy)(pw->p[i].FIELD), + isl_point_copy(pnt)); + } else if (DEFAULT_IS_ZERO) { + v = isl_val_zero(ctx); + } else { + v = isl_val_nan(ctx); + } + FN(PW,free)(pw); + isl_point_free(pnt); + return v; +error: + FN(PW,free)(pw); + isl_point_free(pnt); + return NULL; +} diff --git a/external/mit/isl/dist/isl_pw_fix_templ.c b/external/mit/isl/dist/isl_pw_fix_templ.c new file mode 100644 index 000000000000..36a50bc12a2b --- /dev/null +++ b/external/mit/isl/dist/isl_pw_fix_templ.c @@ -0,0 +1,71 @@ +#include + +/* Fix the value of the given parameter or domain dimension of "pw" + * to be equal to "value". + */ +__isl_give PW *FN(PW,fix_si)(__isl_take PW *pw, enum isl_dim_type type, + unsigned pos, int value) +{ + int i; + isl_size n; + + n = FN(PW,n_piece)(pw); + if (n < 0) + return FN(PW,free)(pw); + + if (type == isl_dim_out) + isl_die(FN(PW,get_ctx)(pw), isl_error_invalid, + "cannot fix output dimension", return FN(PW,free)(pw)); + + if (type == isl_dim_in) + type = isl_dim_set; + + for (i = n - 1; i >= 0; --i) { + isl_set *domain; + + domain = FN(PW,take_domain_at)(pw, i); + domain = isl_set_fix_si(domain, type, pos, value); + pw = FN(PW,restore_domain_at)(pw, i, domain); + pw = FN(PW,exploit_equalities_and_remove_if_empty)(pw, i); + } + + return pw; +} + +/* Fix the value of the variable at position "pos" of type "type" of "pw" + * to be equal to "v". + */ +__isl_give PW *FN(PW,fix_val)(__isl_take PW *pw, + enum isl_dim_type type, unsigned pos, __isl_take isl_val *v) +{ + int i; + isl_size n; + + if (!v) + return FN(PW,free)(pw); + if (!isl_val_is_int(v)) + isl_die(FN(PW,get_ctx)(pw), isl_error_invalid, + "expecting integer value", goto error); + + n = FN(PW,n_piece)(pw); + if (n < 0) + goto error; + + if (type == isl_dim_in) + type = isl_dim_set; + + for (i = 0; i < n; ++i) { + isl_set *domain; + + domain = FN(PW,take_domain_at)(pw, i); + domain = isl_set_fix(domain, type, pos, v->n); + pw = FN(PW,restore_domain_at)(pw, i, domain); + pw = FN(PW,exploit_equalities_and_remove_if_empty)(pw, i); + } + + isl_val_free(v); + return pw; +error: + isl_val_free(v); + return FN(PW,free)(pw); +} diff --git a/external/mit/isl/dist/isl_pw_from_range_templ.c b/external/mit/isl/dist/isl_pw_from_range_templ.c new file mode 100644 index 000000000000..c9394bd60b90 --- /dev/null +++ b/external/mit/isl/dist/isl_pw_from_range_templ.c @@ -0,0 +1,14 @@ +/* + * Copyright 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 + +#undef TYPE +#define TYPE PW +#include "isl_from_range_templ.c" diff --git a/external/mit/isl/dist/isl_pw_hash.c b/external/mit/isl/dist/isl_pw_hash.c new file mode 100644 index 000000000000..4d121c079866 --- /dev/null +++ b/external/mit/isl/dist/isl_pw_hash.c @@ -0,0 +1,33 @@ +/* + * Copyright 2016 Sven Verdoolaege + * + * Use of this software is governed by the MIT license + * + * Written by Sven Verdoolaege + */ + +#include +#include + +/* Return a hash value that digests "pw". + */ +uint32_t FN(PW,get_hash)(__isl_keep PW *pw) +{ + int i; + uint32_t hash; + + if (!pw) + return 0; + + hash = isl_hash_init(); + for (i = 0; i < pw->n; ++i) { + uint32_t set_hash, el_hash; + + set_hash = isl_set_get_hash(pw->p[i].set); + isl_hash_hash(hash, set_hash); + el_hash = FN(EL,get_hash)(pw->p[i].FIELD); + isl_hash_hash(hash, el_hash); + } + + return hash; +} diff --git a/external/mit/isl/dist/isl_pw_insert_dims_templ.c b/external/mit/isl/dist/isl_pw_insert_dims_templ.c new file mode 100644 index 000000000000..df5bfb45bceb --- /dev/null +++ b/external/mit/isl/dist/isl_pw_insert_dims_templ.c @@ -0,0 +1,56 @@ +/* + * Copyright 2010 INRIA Saclay + * + * 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 + */ + +__isl_give PW *FN(PW,insert_dims)(__isl_take PW *pw, enum isl_dim_type type, + unsigned first, unsigned n) +{ + int i; + isl_size n_piece; + enum isl_dim_type set_type; + isl_space *space; + + n_piece = FN(PW,n_piece)(pw); + if (n_piece < 0) + return FN(PW,free)(pw); + if (n == 0 && !isl_space_is_named_or_nested(pw->dim, type)) + return pw; + + set_type = type == isl_dim_in ? isl_dim_set : type; + + space = FN(PW,take_space)(pw); + space = isl_space_insert_dims(space, type, first, n); + pw = FN(PW,restore_space)(pw, space); + + for (i = 0; i < n_piece; ++i) { + isl_set *domain; + EL *el; + + domain = FN(PW,take_domain_at)(pw, i); + domain = isl_set_insert_dims(domain, set_type, first, n); + pw = FN(PW,restore_domain_at)(pw, i, domain); + el = FN(PW,take_base_at)(pw, i); + el = FN(EL,insert_dims)(el, type, first, n); + pw = FN(PW,restore_base_at)(pw, i, el); + } + + return pw; +} + +__isl_give PW *FN(PW,add_dims)(__isl_take PW *pw, enum isl_dim_type type, + unsigned n) +{ + isl_size pos; + + pos = FN(PW,dim)(pw, type); + if (pos < 0) + return FN(PW,free)(pw); + + return FN(PW,insert_dims)(pw, type, pos, n); +} diff --git a/external/mit/isl/dist/isl_pw_insert_domain_templ.c b/external/mit/isl/dist/isl_pw_insert_domain_templ.c new file mode 100644 index 000000000000..bd02d2682cbf --- /dev/null +++ b/external/mit/isl/dist/isl_pw_insert_domain_templ.c @@ -0,0 +1,14 @@ +/* + * Copyright 2019 Cerebras Systems + * + * Use of this software is governed by the MIT license + * + * Written by Sven Verdoolaege, + * Cerebras Systems, 175 S San Antonio Rd, Los Altos, CA, USA + */ + +#include + +#undef TYPE +#define TYPE PW +#include diff --git a/external/mit/isl/dist/isl_pw_lift_templ.c b/external/mit/isl/dist/isl_pw_lift_templ.c new file mode 100644 index 000000000000..0ffe09afd87b --- /dev/null +++ b/external/mit/isl/dist/isl_pw_lift_templ.c @@ -0,0 +1,76 @@ +/* + * Copyright 2010 INRIA Saclay + * + * 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 + */ + +#include + +static isl_stat foreach_lifted_subset(__isl_take isl_set *set, + __isl_take EL *el, + isl_stat (*fn)(__isl_take isl_set *set, __isl_take EL *el, + void *user), void *user) +{ + int i; + + if (!set || !el) + goto error; + + for (i = 0; i < set->n; ++i) { + isl_set *lift; + EL *copy; + + lift = isl_set_from_basic_set(isl_basic_set_copy(set->p[i])); + lift = isl_set_lift(lift); + + copy = FN(EL,copy)(el); + copy = FN(EL,lift)(copy, isl_set_get_space(lift)); + + if (fn(lift, copy, user) < 0) + goto error; + } + + isl_set_free(set); + FN(EL,free)(el); + + return isl_stat_ok; +error: + isl_set_free(set); + FN(EL,free)(el); + return isl_stat_error; +} + +isl_stat FN(PW,foreach_lifted_piece)(__isl_keep PW *pw, + isl_stat (*fn)(__isl_take isl_set *set, __isl_take EL *el, + void *user), void *user) +{ + int i; + + if (!pw) + return isl_stat_error; + + for (i = 0; i < pw->n; ++i) { + isl_bool any; + isl_set *set; + EL *el; + + any = isl_set_involves_locals(pw->p[i].set); + if (any < 0) + return isl_stat_error; + set = isl_set_copy(pw->p[i].set); + el = FN(EL,copy)(pw->p[i].FIELD); + if (!any) { + if (fn(set, el, user) < 0) + return isl_stat_error; + continue; + } + if (foreach_lifted_subset(set, el, fn, user) < 0) + return isl_stat_error; + } + + return isl_stat_ok; +} diff --git a/external/mit/isl/dist/isl_pw_locals_templ.c b/external/mit/isl/dist/isl_pw_locals_templ.c new file mode 100644 index 000000000000..ecd3aefe31ca --- /dev/null +++ b/external/mit/isl/dist/isl_pw_locals_templ.c @@ -0,0 +1,35 @@ +/* + * Copyright 2020 Cerebras Systems + * + * Use of this software is governed by the MIT license + * + * Written by Sven Verdoolaege, + * Cerebras Systems, 175 S San Antonio Rd, Los Altos, CA, USA + */ + +#include + +/* isl_pw_*_every_piece callback that checks whether "set" and "el" + * are free of local variables. + */ +static isl_bool FN(PW,piece_no_local)(__isl_keep isl_set *set, + __isl_keep EL *el, void *user) +{ + isl_bool involves; + + involves = isl_set_involves_locals(set); + if (involves >= 0 && !involves) + involves = FN(EL,involves_locals)(el); + + return isl_bool_not(involves); +} + +/* Does "pw" involve any local variables, i.e., integer divisions? + */ +isl_bool FN(PW,involves_locals)(__isl_keep PW *pw) +{ + isl_bool no_locals; + + no_locals = FN(PW,every_piece)(pw, &FN(PW,piece_no_local), NULL); + return isl_bool_not(no_locals); +} diff --git a/external/mit/isl/dist/isl_pw_macro.h b/external/mit/isl/dist/isl_pw_macro.h new file mode 100644 index 000000000000..4f74978f4bb7 --- /dev/null +++ b/external/mit/isl/dist/isl_pw_macro.h @@ -0,0 +1,8 @@ +#define xCAT(A,B) A ## B +#define CAT(A,B) xCAT(A,B) +#undef EL +#define EL CAT(isl_,BASE) +#define xFN(TYPE,NAME) TYPE ## _ ## NAME +#define FN(TYPE,NAME) xFN(TYPE,NAME) +#define xS(TYPE,NAME) struct TYPE ## _ ## NAME +#define S(TYPE,NAME) xS(TYPE,NAME) diff --git a/external/mit/isl/dist/isl_pw_morph_templ.c b/external/mit/isl/dist/isl_pw_morph_templ.c new file mode 100644 index 000000000000..3c08698a9a98 --- /dev/null +++ b/external/mit/isl/dist/isl_pw_morph_templ.c @@ -0,0 +1,51 @@ +/* + * Copyright 2010 INRIA Saclay + * + * 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 + */ + +__isl_give PW *FN(PW,morph_domain)(__isl_take PW *pw, + __isl_take isl_morph *morph) +{ + int i; + isl_size n; + isl_ctx *ctx; + isl_space *space; + + n = FN(PW,n_piece)(pw); + if (n < 0 || !morph) + goto error; + + ctx = isl_space_get_ctx(pw->dim); + isl_assert(ctx, isl_space_is_domain_internal(morph->dom->dim, pw->dim), + goto error); + + space = FN(PW,take_space)(pw); + space = isl_space_extend_domain_with_range( + isl_space_copy(morph->ran->dim), space); + pw = FN(PW,restore_space)(pw, space); + + for (i = 0; i < n; ++i) { + isl_set *domain; + EL *el; + + domain = FN(PW,take_domain_at)(pw, i); + domain = isl_morph_set(isl_morph_copy(morph), domain); + pw = FN(PW,restore_domain_at)(pw, i, domain); + el = FN(PW,take_base_at)(pw, i); + el = FN(EL,morph_domain)(el, isl_morph_copy(morph)); + pw = FN(PW,restore_base_at)(pw, i, el); + } + + isl_morph_free(morph); + + return pw; +error: + FN(PW,free)(pw); + isl_morph_free(morph); + return NULL; +} diff --git a/external/mit/isl/dist/isl_pw_move_dims_templ.c b/external/mit/isl/dist/isl_pw_move_dims_templ.c new file mode 100644 index 000000000000..a68a9476fc65 --- /dev/null +++ b/external/mit/isl/dist/isl_pw_move_dims_templ.c @@ -0,0 +1,52 @@ +/* + * Copyright 2010 INRIA Saclay + * + * 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 + */ + +__isl_give PW *FN(PW,move_dims)(__isl_take PW *pw, + enum isl_dim_type dst_type, unsigned dst_pos, + enum isl_dim_type src_type, unsigned src_pos, unsigned n) +{ + int i; + isl_size n_piece; + isl_space *space; + + space = FN(PW,take_space)(pw); + space = isl_space_move_dims(space, dst_type, dst_pos, + src_type, src_pos, n); + pw = FN(PW,restore_space)(pw, space); + + n_piece = FN(PW,n_piece)(pw); + if (n_piece < 0) + return FN(PW,free)(pw); + + for (i = 0; i < n_piece; ++i) { + EL *el; + + el = FN(PW,take_base_at)(pw, i); + el = FN(EL,move_dims)(el, + dst_type, dst_pos, src_type, src_pos, n); + pw = FN(PW,restore_base_at)(pw, i, el); + } + + if (dst_type == isl_dim_in) + dst_type = isl_dim_set; + if (src_type == isl_dim_in) + src_type = isl_dim_set; + + for (i = 0; i < n_piece; ++i) { + isl_set *domain; + + domain = FN(PW,take_domain_at)(pw, i); + domain = isl_set_move_dims(domain, dst_type, dst_pos, + src_type, src_pos, n); + pw = FN(PW,restore_domain_at)(pw, i, domain); + } + + return pw; +} diff --git a/external/mit/isl/dist/isl_pw_neg_templ.c b/external/mit/isl/dist/isl_pw_neg_templ.c new file mode 100644 index 000000000000..0f5b52178782 --- /dev/null +++ b/external/mit/isl/dist/isl_pw_neg_templ.c @@ -0,0 +1,17 @@ +/* + * Copyright 2010 INRIA Saclay + * + * 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 + */ + +#include + +__isl_give PW *FN(PW,neg)(__isl_take PW *pw) +{ + S(PW,un_op_control) control = { .fn_base = &FN(EL,neg) }; + return FN(PW,un_op)(pw, &control); +} diff --git a/external/mit/isl/dist/isl_pw_opt_templ.c b/external/mit/isl/dist/isl_pw_opt_templ.c new file mode 100644 index 000000000000..421b4d52e222 --- /dev/null +++ b/external/mit/isl/dist/isl_pw_opt_templ.c @@ -0,0 +1,54 @@ +/* + * Copyright 2010 INRIA Saclay + * + * 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 + */ + +/* Compute the maximal value attained by the piecewise quasipolynomial + * on its domain or zero if the domain is empty. + * In the worst case, the domain is scanned completely, + * so the domain is assumed to be bounded. + */ +__isl_give isl_val *FN(PW,opt)(__isl_take PW *pw, int max) +{ + int i; + isl_val *opt; + + if (!pw) + return NULL; + + if (pw->n == 0) { + opt = isl_val_zero(FN(PW,get_ctx)(pw)); + FN(PW,free)(pw); + return opt; + } + + opt = FN(EL,opt_on_domain)(FN(EL,copy)(pw->p[0].FIELD), + isl_set_copy(pw->p[0].set), max); + for (i = 1; i < pw->n; ++i) { + isl_val *opt_i; + opt_i = FN(EL,opt_on_domain)(FN(EL,copy)(pw->p[i].FIELD), + isl_set_copy(pw->p[i].set), max); + if (max) + opt = isl_val_max(opt, opt_i); + else + opt = isl_val_min(opt, opt_i); + } + + FN(PW,free)(pw); + return opt; +} + +__isl_give isl_val *FN(PW,max)(__isl_take PW *pw) +{ + return FN(PW,opt)(pw, 1); +} + +__isl_give isl_val *FN(PW,min)(__isl_take PW *pw) +{ + return FN(PW,opt)(pw, 0); +} diff --git a/external/mit/isl/dist/isl_pw_print_templ.c b/external/mit/isl/dist/isl_pw_print_templ.c new file mode 100644 index 000000000000..77f62c61f9d3 --- /dev/null +++ b/external/mit/isl/dist/isl_pw_print_templ.c @@ -0,0 +1,55 @@ +/* + * Copyright 2011 Sven Verdoolaege + * + * Use of this software is governed by the MIT license + * + * Written by Sven Verdoolaege. + */ + +#undef EL +#define EL CAT(isl_,BASE) +#undef PW +#define PW CAT(isl_pw_,BASE) + +/* Print the body of a piecewise expression, i.e., a semicolon delimited + * sequence of expressions, each followed by constraints. + */ +static __isl_give isl_printer *FN(print_body_pw,BASE)( + __isl_take isl_printer *p, __isl_keep PW *pw) +{ + int i; + + if (!pw) + return isl_printer_free(p); + + for (i = 0; i < pw->n; ++i) { + EL *el; + isl_space *space; + + if (i) + p = isl_printer_print_str(p, "; "); + el = FN(PW,peek_base_at)(pw, i); + p = FN(print_body,BASE)(p, el); + space = FN(EL,get_domain_space)(el); + p = print_disjuncts(set_to_map(pw->p[i].set), space, p, 0); + isl_space_free(space); + } + return p; +} + +/* Print a piecewise expression in isl format. + */ +static __isl_give isl_printer *FN(FN(print_pw,BASE),isl)( + __isl_take isl_printer *p, __isl_keep PW *pw) +{ + struct isl_print_space_data data = { 0 }; + + if (!pw) + return isl_printer_free(p); + + p = print_param_tuple(p, pw->dim, &data); + p = isl_printer_print_str(p, "{ "); + p = FN(print_body_pw,BASE)(p, pw); + p = isl_printer_print_str(p, " }"); + return p; +} diff --git a/external/mit/isl/dist/isl_pw_pullback_templ.c b/external/mit/isl/dist/isl_pw_pullback_templ.c new file mode 100644 index 000000000000..5486061edd72 --- /dev/null +++ b/external/mit/isl/dist/isl_pw_pullback_templ.c @@ -0,0 +1,124 @@ +/* + * Copyright 2012 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 + +#undef SUFFIX +#define SUFFIX multi_aff +#undef ARG1 +#define ARG1 PW +#undef ARG2 +#define ARG2 isl_multi_aff + +static +#include "isl_align_params_templ.c" + +#undef SUFFIX +#define SUFFIX pw_multi_aff +#undef ARG1 +#define ARG1 PW +#undef ARG2 +#define ARG2 isl_pw_multi_aff + +static +#include "isl_align_params_templ.c" + +/* Compute the pullback of "pw" by the function represented by "ma". + * In other words, plug in "ma" in "pw". + */ +__isl_give PW *FN(PW,pullback_multi_aff)(__isl_take PW *pw, + __isl_take isl_multi_aff *ma) +{ + int i; + isl_size n; + isl_space *space = NULL; + + FN(PW,align_params_multi_aff)(&pw, &ma); + ma = isl_multi_aff_align_divs(ma); + n = FN(PW,n_piece)(pw); + if (n < 0 || !ma) + goto error; + + space = isl_space_join(isl_multi_aff_get_space(ma), + FN(PW,get_space)(pw)); + + for (i = 0; i < n; ++i) { + isl_set *domain; + EL *el; + + domain = FN(PW,take_domain_at)(pw, i); + domain = isl_set_preimage_multi_aff(domain, + isl_multi_aff_copy(ma)); + pw = FN(PW,restore_domain_at)(pw, i, domain); + el = FN(PW,take_base_at)(pw, i); + el = FN(EL,pullback_multi_aff)(el, isl_multi_aff_copy(ma)); + pw = FN(PW,restore_base_at)(pw, i, el); + } + + pw = FN(PW,reset_space)(pw, space); + isl_multi_aff_free(ma); + return pw; +error: + isl_space_free(space); + isl_multi_aff_free(ma); + FN(PW,free)(pw); + return NULL; +} + +/* Compute the pullback of "pw" by the function represented by "pma". + * In other words, plug in "pma" in "pw". + */ +static __isl_give PW *FN(PW,pullback_pw_multi_aff_aligned)(__isl_take PW *pw, + __isl_take isl_pw_multi_aff *pma) +{ + int i; + PW *res; + + if (!pma) + goto error; + + if (pma->n == 0) { + isl_space *space; + space = isl_space_join(isl_pw_multi_aff_get_space(pma), + FN(PW,get_space)(pw)); + isl_pw_multi_aff_free(pma); + res = FN(PW,empty)(space); + FN(PW,free)(pw); + return res; + } + + res = FN(PW,pullback_multi_aff)(FN(PW,copy)(pw), + isl_multi_aff_copy(pma->p[0].maff)); + res = FN(PW,intersect_domain)(res, isl_set_copy(pma->p[0].set)); + + for (i = 1; i < pma->n; ++i) { + PW *res_i; + + res_i = FN(PW,pullback_multi_aff)(FN(PW,copy)(pw), + isl_multi_aff_copy(pma->p[i].maff)); + res_i = FN(PW,intersect_domain)(res_i, + isl_set_copy(pma->p[i].set)); + res = FN(PW,add_disjoint)(res, res_i); + } + + isl_pw_multi_aff_free(pma); + FN(PW,free)(pw); + return res; +error: + isl_pw_multi_aff_free(pma); + FN(PW,free)(pw); + return NULL; +} + +__isl_give PW *FN(PW,pullback_pw_multi_aff)(__isl_take PW *pw, + __isl_take isl_pw_multi_aff *pma) +{ + FN(PW,align_params_pw_multi_aff)(&pw, &pma); + return FN(PW,pullback_pw_multi_aff_aligned)(pw, pma); +} diff --git a/external/mit/isl/dist/isl_pw_range_tuple_id_templ.c b/external/mit/isl/dist/isl_pw_range_tuple_id_templ.c new file mode 100644 index 000000000000..37392f5e9344 --- /dev/null +++ b/external/mit/isl/dist/isl_pw_range_tuple_id_templ.c @@ -0,0 +1,46 @@ +/* + * Copyright 2018 Sven Verdoolaege + * Copyright 2019 Cerebras Systems + * + * Use of this software is governed by the MIT license + * + * Written by Sven Verdoolaege, + * Cerebras Systems, 175 S San Antonio Rd, Los Altos, CA, USA + */ + +/* Does the (range) tuple of "pw" have an identifier? + * + * Technically, the implementation should use isl_dim_set if "pw" + * lives in a set space and isl_dim_out if it lives in a map space. + * Internally, however, it can be assumed that isl_dim_set is equal + * to isl_dim_out. + */ +isl_bool FN(PW,has_range_tuple_id)(__isl_keep PW *pw) +{ + return FN(PW,has_tuple_id)(pw, isl_dim_out); +} + +/* Return the identifier of the (range) tuple of "pw", assuming it has one. + * + * Technically, the implementation should use isl_dim_set if "pw" + * lives in a set space and isl_dim_out if it lives in a map space. + * Internally, however, it can be assumed that isl_dim_set is equal + * to isl_dim_out. + */ +__isl_give isl_id *FN(PW,get_range_tuple_id)(__isl_keep PW *pw) +{ + return FN(PW,get_tuple_id)(pw, isl_dim_out); +} + +/* Replace the identifier of the (range) tuple of "pw" by "id". + * + * Technically, the implementation should use isl_dim_set if "pw" + * lives in a set space and isl_dim_out if it lives in a map space. + * Internally, however, it can be assumed that isl_dim_set is equal + * to isl_dim_out. + */ +__isl_give PW *FN(PW,set_range_tuple_id)(__isl_take PW *pw, + __isl_take isl_id *id) +{ + return FN(PW,set_tuple_id)(pw, isl_dim_out, id); +} diff --git a/external/mit/isl/dist/isl_pw_scale_templ.c b/external/mit/isl/dist/isl_pw_scale_templ.c new file mode 100644 index 000000000000..81c8495e9cb7 --- /dev/null +++ b/external/mit/isl/dist/isl_pw_scale_templ.c @@ -0,0 +1,42 @@ +/* + * Copyright 2010 INRIA Saclay + * + * 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 + */ + +#include + +__isl_give PW *FN(PW,scale)(__isl_take PW *pw, isl_int v) +{ + int i; + isl_size n; + + if (isl_int_is_one(v)) + return pw; + if (pw && DEFAULT_IS_ZERO && isl_int_is_zero(v)) { + PW *zero; + isl_space *space = FN(PW,get_space)(pw); + zero = FN(PW,ZERO)(space OPT_TYPE_ARG(pw->)); + FN(PW,free)(pw); + return zero; + } + if (isl_int_is_neg(v)) + pw = FN(PW,negate_type)(pw); + + n = FN(PW,n_piece)(pw); + if (n < 0) + return FN(PW,free)(pw); + for (i = 0; i < n; ++i) { + EL *el; + + el = FN(PW,take_base_at)(pw, i); + el = FN(EL,scale)(el, v); + pw = FN(PW,restore_base_at)(pw, i, el); + } + + return pw; +} diff --git a/external/mit/isl/dist/isl_pw_split_dims_templ.c b/external/mit/isl/dist/isl_pw_split_dims_templ.c new file mode 100644 index 000000000000..68e9165b6169 --- /dev/null +++ b/external/mit/isl/dist/isl_pw_split_dims_templ.c @@ -0,0 +1,37 @@ +/* + * Copyright 2010 INRIA Saclay + * + * 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 + */ + +#include + +__isl_give PW *FN(PW,split_dims)(__isl_take PW *pw, + enum isl_dim_type type, unsigned first, unsigned n) +{ + int i; + isl_size n_piece; + + n_piece = FN(PW,n_piece)(pw); + if (n_piece < 0) + return FN(PW,free)(pw); + if (n == 0) + return pw; + + if (type == isl_dim_in) + type = isl_dim_set; + + for (i = 0; i < n; ++i) { + isl_set *domain; + + domain = FN(PW,take_domain_at)(pw, i); + domain = isl_set_split_dims(domain, type, first, n); + pw = FN(PW,restore_domain_at)(pw, i, domain); + } + + return pw; +} diff --git a/external/mit/isl/dist/isl_pw_sub_templ.c b/external/mit/isl/dist/isl_pw_sub_templ.c new file mode 100644 index 000000000000..34107948f778 --- /dev/null +++ b/external/mit/isl/dist/isl_pw_sub_templ.c @@ -0,0 +1,16 @@ +/* + * Copyright 2010 INRIA Saclay + * + * 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 + */ + +#include + +__isl_give PW *FN(PW,sub)(__isl_take PW *pw1, __isl_take PW *pw2) +{ + return FN(PW,add)(pw1, FN(PW,neg)(pw2)); +} diff --git a/external/mit/isl/dist/isl_pw_templ.c b/external/mit/isl/dist/isl_pw_templ.c new file mode 100644 index 000000000000..c431677df319 --- /dev/null +++ b/external/mit/isl/dist/isl_pw_templ.c @@ -0,0 +1,1886 @@ +/* + * Copyright 2010-2011 INRIA Saclay + * Copyright 2011 Sven Verdoolaege + * Copyright 2012-2014 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 +#include +#include +#include + +#include + +#include "opt_type.h" + +__isl_give PW *FN(PW,alloc_size)(__isl_take isl_space *space + OPT_TYPE_PARAM, int n) +{ + isl_ctx *ctx; + struct PW *pw; + + if (!space) + return NULL; + ctx = isl_space_get_ctx(space); + isl_assert(ctx, n >= 0, goto error); + pw = isl_alloc(ctx, struct PW, + sizeof(struct PW) + (n - 1) * sizeof(S(PW,piece))); + if (!pw) + goto error; + + pw->ref = 1; + OPT_SET_TYPE(pw->, type); + pw->size = n; + pw->n = 0; + pw->dim = space; + return pw; +error: + isl_space_free(space); + return NULL; +} + +__isl_give PW *FN(PW,ZERO)(__isl_take isl_space *space OPT_TYPE_PARAM) +{ + return FN(PW,alloc_size)(space OPT_TYPE_ARG(NO_LOC), 0); +} + +/* Add a piece with domain "set" and base expression "el" + * to the piecewise expression "pw". + * + * Do this independently of the values of "set" and "el", + * such that this function can be used by isl_pw_*_dup. + */ +static __isl_give PW *FN(PW,add_dup_piece)(__isl_take PW *pw, + __isl_take isl_set *set, __isl_take EL *el) +{ + isl_ctx *ctx; + isl_space *el_dim = NULL; + + if (!pw || !set || !el) + goto error; + + ctx = isl_set_get_ctx(set); + if (!OPT_EQUAL_TYPES(pw->, el->)) + isl_die(ctx, isl_error_invalid, "fold types don't match", + goto error); + el_dim = FN(EL,get_space(el)); + isl_assert(ctx, isl_space_is_equal(pw->dim, el_dim), goto error); + isl_assert(ctx, pw->n < pw->size, goto error); + + pw->p[pw->n].set = set; + pw->p[pw->n].FIELD = el; + pw->n++; + + isl_space_free(el_dim); + return pw; +error: + isl_space_free(el_dim); + FN(PW,free)(pw); + isl_set_free(set); + FN(EL,free)(el); + return NULL; +} + +/* Add a piece with domain "set" and base expression "el" + * to the piecewise expression "pw", provided the domain + * is not obviously empty and the base expression + * is not equal to the default value. + */ +__isl_give PW *FN(PW,add_piece)(__isl_take PW *pw, + __isl_take isl_set *set, __isl_take EL *el) +{ + isl_bool skip; + + skip = isl_set_plain_is_empty(set); + if (skip >= 0 && !skip) + skip = FN(EL,EL_IS_ZERO)(el); + if (skip >= 0 && !skip) + return FN(PW,add_dup_piece)(pw, set, el); + + isl_set_free(set); + FN(EL,free)(el); + if (skip < 0) + return FN(PW,free)(pw); + return pw; +} + +/* 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; +} + +__isl_give PW *FN(PW,alloc)(OPT_TYPE_PARAM_FIRST + __isl_take isl_set *set, __isl_take EL *el) +{ + PW *pw; + + if (FN(PW,check_compatible_domain)(el, set) < 0) + goto error; + + pw = FN(PW,alloc_size)(FN(EL,get_space)(el) OPT_TYPE_ARG(NO_LOC), 1); + + return FN(PW,add_piece)(pw, set, el); +error: + isl_set_free(set); + FN(EL,free)(el); + return NULL; +} + +__isl_give PW *FN(PW,dup)(__isl_keep PW *pw) +{ + int i; + PW *dup; + + if (!pw) + return NULL; + + dup = FN(PW,alloc_size)(isl_space_copy(pw->dim) + OPT_TYPE_ARG(pw->), pw->n); + if (!dup) + return NULL; + + for (i = 0; i < pw->n; ++i) + dup = FN(PW,add_dup_piece)(dup, isl_set_copy(pw->p[i].set), + FN(EL,copy)(pw->p[i].FIELD)); + + return dup; +} + +__isl_give PW *FN(PW,cow)(__isl_take PW *pw) +{ + if (!pw) + return NULL; + + if (pw->ref == 1) + return pw; + pw->ref--; + return FN(PW,dup)(pw); +} + +__isl_give PW *FN(PW,copy)(__isl_keep PW *pw) +{ + if (!pw) + return NULL; + + pw->ref++; + return pw; +} + +__isl_null PW *FN(PW,free)(__isl_take PW *pw) +{ + int i; + + if (!pw) + return NULL; + if (--pw->ref > 0) + return NULL; + + for (i = 0; i < pw->n; ++i) { + isl_set_free(pw->p[i].set); + FN(EL,free)(pw->p[i].FIELD); + } + isl_space_free(pw->dim); + free(pw); + + return NULL; +} + +/* 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 isl_space_copy(FN(PW,peek_space)(pw)); +} + +/* Return the space of "pw". + * This may be either a copy or the space itself + * if there is only one reference to "pw". + * This allows the space to be modified inplace + * if both the piecewise expression and its space have only a single reference. + * The caller is not allowed to modify "pw" between this call and + * a subsequent call to isl_pw_*_restore_*. + * The only exception is that isl_pw_*_free can be called instead. + */ +static __isl_give isl_space *FN(PW,take_space)(__isl_keep PW *pw) +{ + isl_space *space; + + if (!pw) + return NULL; + if (pw->ref != 1) + return FN(PW,get_space)(pw); + space = pw->dim; + pw->dim = NULL; + return space; +} + +/* Set the space of "pw" to "space", where the space of "pw" may be missing + * due to a preceding call to isl_pw_*_take_space. + * However, in this case, "pw" only has a single reference and + * then the call to isl_pw_*_cow has no effect. + */ +static __isl_give PW *FN(PW,restore_space)(__isl_take PW *pw, + __isl_take isl_space *space) +{ + if (!pw || !space) + goto error; + + if (pw->dim == space) { + isl_space_free(space); + return pw; + } + + pw = FN(PW,cow)(pw); + if (!pw) + goto error; + isl_space_free(pw->dim); + pw->dim = space; + + return pw; +error: + FN(PW,free)(pw); + isl_space_free(space); + return NULL; +} + +/* Check that "pos" is a valid position for a cell in "pw". + */ +static isl_stat FN(PW,check_pos)(__isl_keep PW *pw, int pos) +{ + if (!pw) + return isl_stat_error; + if (pos < 0 || pos >= pw->n) + isl_die(FN(PW,get_ctx)(pw), isl_error_internal, + "position out of bounds", return isl_stat_error); + return isl_stat_ok; +} + +/* Return the cell at position "pos" in "pw". + */ +static __isl_keep isl_set *FN(PW,peek_domain_at)(__isl_keep PW *pw, int pos) +{ + if (FN(PW,check_pos)(pw, pos) < 0) + return NULL; + return pw->p[pos].set; +} + +/* Return a copy of the cell at position "pos" in "pw". + */ +static __isl_give isl_set *FN(PW,get_domain_at)(__isl_keep PW *pw, int pos) +{ + return isl_set_copy(FN(PW,peek_domain_at)(pw, pos)); +} + +/* Return the cell at position "pos" in "pw". + * This may be either a copy or the cell itself + * if there is only one reference to "pw". + * This allows the cell to be modified inplace + * if both the piecewise expression and this cell + * have only a single reference. + * The caller is not allowed to modify "pw" between this call and + * the subsequent call to isl_pw_*_restore_domain_at. + * The only exception is that isl_pw_*_free can be called instead. + */ +static __isl_give isl_set *FN(PW,take_domain_at)(__isl_keep PW *pw, int pos) +{ + isl_set *domain; + + if (!pw) + return NULL; + if (pw->ref != 1) + return FN(PW,get_domain_at)(pw, pos); + if (FN(PW,check_pos)(pw, pos) < 0) + return NULL; + domain = pw->p[pos].set; + pw->p[pos].set = NULL; + return domain; +} + +/* Set the cell at position "pos" in "pw" to "el", + * where this cell may be missing + * due to a preceding call to isl_pw_*_take_domain_at. + * However, in this case, "pw" only has a single reference and + * then the call to isl_pw_*_cow has no effect. + */ +static __isl_give PW *FN(PW,restore_domain_at)(__isl_take PW *pw, int pos, + __isl_take isl_set *domain) +{ + if (FN(PW,check_pos)(pw, pos) < 0 || !domain) + goto error; + + if (pw->p[pos].set == domain) { + isl_set_free(domain); + return pw; + } + + pw = FN(PW,cow)(pw); + if (!pw) + goto error; + isl_set_free(pw->p[pos].set); + pw->p[pos].set = domain; + + return pw; +error: + FN(PW,free)(pw); + isl_set_free(domain); + return NULL; +} + +/* Return the base expression associated to + * the cell at position "pos" in "pw". + */ +__isl_keep EL *FN(PW,peek_base_at)(__isl_keep PW *pw, int pos) +{ + if (FN(PW,check_pos)(pw, pos) < 0) + return NULL; + return pw->p[pos].FIELD; +} + +/* Return a copy of the base expression associated to + * the cell at position "pos" in "pw". + */ +static __isl_give EL *FN(PW,get_base_at)(__isl_keep PW *pw, int pos) +{ + return FN(EL,copy)(FN(PW,peek_base_at)(pw, pos)); +} + +/* Return the base expression associated to + * the cell at position "pos" in "pw". + * This may be either a copy or the base expression itself + * if there is only one reference to "pw". + * This allows the base expression to be modified inplace + * if both the piecewise expression and this base expression + * have only a single reference. + * The caller is not allowed to modify "pw" between this call and + * a subsequent call to isl_pw_*_restore_*. + * The only exception is that isl_pw_*_free can be called instead. + */ +static __isl_give EL *FN(PW,take_base_at)(__isl_keep PW *pw, int pos) +{ + EL *el; + + if (!pw) + return NULL; + if (pw->ref != 1) + return FN(PW,get_base_at)(pw, pos); + if (FN(PW,check_pos)(pw, pos) < 0) + return NULL; + el = pw->p[pos].FIELD; + pw->p[pos].FIELD = NULL; + return el; +} + +/* Set the base expression associated to + * the cell at position "pos" in "pw" to "el", + * where this base expression may be missing + * due to a preceding call to isl_pw_*_take_base_at. + * However, in this case, "pw" only has a single reference and + * then the call to isl_pw_*_cow has no effect. + * If "inplace" is set, then replacing the base expression by "el" + * is known not to change the meaning of "pw". It can therefore be replaced + * in all references to "pw". + */ +static __isl_give PW *FN(PW,restore_base_at_)(__isl_take PW *pw, int pos, + __isl_take EL *el, int inplace) +{ + if (FN(PW,check_pos)(pw, pos) < 0 || !el) + goto error; + + if (pw->p[pos].FIELD == el) { + FN(EL,free)(el); + return pw; + } + + if (!inplace) + pw = FN(PW,cow)(pw); + if (!pw) + goto error; + FN(EL,free)(pw->p[pos].FIELD); + pw->p[pos].FIELD = el; + + return pw; +error: + FN(PW,free)(pw); + FN(EL,free)(el); + return NULL; +} + +/* Set the base expression associated to + * the cell at position "pos" in "pw" to "el", + * where this base expression may be missing + * due to a preceding call to isl_pw_*_take_base_at. + */ +static __isl_give PW *FN(PW,restore_base_at)(__isl_take PW *pw, int pos, + __isl_take EL *el) +{ + return FN(PW,restore_base_at_)(pw, pos, el, 0); +} + +/* Set the base expression associated to + * the cell at position "pos" in "pw" to "el", + * where this base expression may be missing + * due to a preceding call to isl_pw_*_take_base_at. + * Furthermore, replacing the base expression by "el" + * is known not to change the meaning of "pw". + */ +static __isl_give PW *FN(PW,restore_base_at_inplace)(__isl_take PW *pw, int pos, + __isl_take EL *el) +{ + return FN(PW,restore_base_at_)(pw, pos, el, 1); +} + +/* Create a piecewise expression with the given base expression on a universe + * domain. + */ +static __isl_give PW *FN(FN(FN(PW,from),BASE),type_base)(__isl_take EL *el + OPT_TYPE_PARAM) +{ + isl_set *dom = isl_set_universe(FN(EL,get_domain_space)(el)); + return FN(PW,alloc)(OPT_TYPE_ARG_FIRST(NO_LOC) dom, el); +} + +/* Create a piecewise expression with the given base expression on a universe + * domain. + * + * If the default value of this piecewise type is zero and + * if "el" is effectively zero, then create an empty piecewise expression + * instead. + */ +static __isl_give PW *FN(FN(FN(PW,from),BASE),type)(__isl_take EL *el + OPT_TYPE_PARAM) +{ + isl_bool is_zero; + isl_space *space; + + if (!DEFAULT_IS_ZERO) + return FN(FN(FN(PW,from),BASE),type_base)(el + OPT_TYPE_ARG(NO_LOC)); + is_zero = FN(EL,EL_IS_ZERO)(el); + if (is_zero < 0) + goto error; + if (!is_zero) + return FN(FN(FN(PW,from),BASE),type_base)(el + OPT_TYPE_ARG(NO_LOC)); + space = FN(EL,get_space)(el); + FN(EL,free)(el); + return FN(PW,ZERO)(space OPT_TYPE_ARG(NO_LOC)); +error: + FN(EL,free)(el); + return NULL; +} + +#ifdef HAS_TYPE +/* Create a piecewise expression with the given base expression on a universe + * domain. + * + * Pass along the type as an extra argument for improved uniformity + * with piecewise types that do not have a fold type. + */ +__isl_give PW *FN(FN(PW,from),BASE)(__isl_take EL *el) +{ + enum isl_fold type = FN(EL,get_type)(el); + return FN(FN(FN(PW,from),BASE),type)(el, type); +} +#else +__isl_give PW *FN(FN(PW,from),BASE)(__isl_take EL *el) +{ + return FN(FN(FN(PW,from),BASE),type)(el); +} +#endif + +const char *FN(PW,get_dim_name)(__isl_keep PW *pw, enum isl_dim_type type, + unsigned pos) +{ + return pw ? isl_space_get_dim_name(pw->dim, type, pos) : NULL; +} + +isl_bool FN(PW,has_dim_id)(__isl_keep PW *pw, enum isl_dim_type type, + unsigned pos) +{ + return pw ? isl_space_has_dim_id(pw->dim, type, pos) : isl_bool_error; +} + +__isl_give isl_id *FN(PW,get_dim_id)(__isl_keep PW *pw, enum isl_dim_type type, + unsigned pos) +{ + return pw ? isl_space_get_dim_id(pw->dim, type, pos) : NULL; +} + +isl_bool FN(PW,has_tuple_name)(__isl_keep PW *pw, enum isl_dim_type type) +{ + return pw ? isl_space_has_tuple_name(pw->dim, type) : isl_bool_error; +} + +const char *FN(PW,get_tuple_name)(__isl_keep PW *pw, enum isl_dim_type type) +{ + return pw ? isl_space_get_tuple_name(pw->dim, type) : NULL; +} + +isl_bool FN(PW,has_tuple_id)(__isl_keep PW *pw, enum isl_dim_type type) +{ + return pw ? isl_space_has_tuple_id(pw->dim, type) : isl_bool_error; +} + +__isl_give isl_id *FN(PW,get_tuple_id)(__isl_keep PW *pw, enum isl_dim_type type) +{ + return pw ? isl_space_get_tuple_id(pw->dim, type) : NULL; +} + +isl_bool FN(PW,IS_ZERO)(__isl_keep PW *pw) +{ + if (!pw) + return isl_bool_error; + + return isl_bool_ok(pw->n == 0); +} + +static __isl_give PW *FN(PW,realign_domain)(__isl_take PW *pw, + __isl_take isl_reordering *exp) +{ + int i; + isl_size n; + + n = FN(PW,n_piece)(pw); + if (n < 0 || !exp) + goto error; + + for (i = 0; i < n; ++i) { + isl_set *domain; + EL *el; + + domain = FN(PW,take_domain_at)(pw, i); + domain = isl_set_realign(domain, isl_reordering_copy(exp)); + pw = FN(PW,restore_domain_at)(pw, i, domain); + + el = FN(PW,take_base_at)(pw, i); + el = FN(EL,realign_domain)(el, isl_reordering_copy(exp)); + pw = FN(PW,restore_base_at)(pw, i, el); + } + + pw = FN(PW,reset_domain_space)(pw, isl_reordering_get_space(exp)); + + isl_reordering_free(exp); + return pw; +error: + isl_reordering_free(exp); + FN(PW,free)(pw); + return NULL; +} + +#undef TYPE +#define TYPE PW + +#include "isl_check_named_params_templ.c" + +/* Align the parameters of "pw" to those of "model". + */ +__isl_give PW *FN(PW,align_params)(__isl_take PW *pw, __isl_take isl_space *model) +{ + isl_ctx *ctx; + isl_bool equal_params; + + if (!pw || !model) + goto error; + + ctx = isl_space_get_ctx(model); + if (!isl_space_has_named_params(model)) + isl_die(ctx, isl_error_invalid, + "model has unnamed parameters", goto error); + if (FN(PW,check_named_params)(pw) < 0) + goto error; + equal_params = isl_space_has_equal_params(pw->dim, model); + if (equal_params < 0) + goto error; + if (!equal_params) { + isl_space *space; + isl_reordering *exp; + + space = FN(PW,get_domain_space)(pw); + exp = isl_parameter_alignment_reordering(space, model); + isl_space_free(space); + pw = FN(PW,realign_domain)(pw, exp); + } + + isl_space_free(model); + return pw; +error: + isl_space_free(model); + FN(PW,free)(pw); + return NULL; +} + +#undef TYPE +#define TYPE PW + +static +#include "isl_align_params_bin_templ.c" + +#undef SUFFIX +#define SUFFIX set +#undef ARG1 +#define ARG1 PW +#undef ARG2 +#define ARG2 isl_set + +static +#include "isl_align_params_templ.c" + +#undef TYPE +#define TYPE PW + +#include "isl_type_has_equal_space_bin_templ.c" +#include "isl_type_check_equal_space_templ.c" + +/* Private version of "union_add". For isl_pw_qpolynomial and + * isl_pw_qpolynomial_fold, we prefer to simply call it "add". + */ +static __isl_give PW *FN(PW,union_add_)(__isl_take PW *pw1, __isl_take PW *pw2) +{ + int i, j, n; + struct PW *res; + isl_ctx *ctx; + isl_set *set; + + if (FN(PW,align_params_bin)(&pw1, &pw2) < 0) + goto error; + + ctx = isl_space_get_ctx(pw1->dim); + if (!OPT_EQUAL_TYPES(pw1->, pw2->)) + isl_die(ctx, isl_error_invalid, + "fold types don't match", goto error); + if (FN(PW,check_equal_space)(pw1, pw2) < 0) + goto error; + + if (FN(PW,IS_ZERO)(pw1)) { + FN(PW,free)(pw1); + return pw2; + } + + if (FN(PW,IS_ZERO)(pw2)) { + FN(PW,free)(pw2); + return pw1; + } + + n = (pw1->n + 1) * (pw2->n + 1); + res = FN(PW,alloc_size)(isl_space_copy(pw1->dim) + OPT_TYPE_ARG(pw1->), n); + + for (i = 0; i < pw1->n; ++i) { + set = isl_set_copy(pw1->p[i].set); + for (j = 0; j < pw2->n; ++j) { + struct isl_set *common; + EL *sum; + common = isl_set_intersect(isl_set_copy(pw1->p[i].set), + isl_set_copy(pw2->p[j].set)); + if (isl_set_plain_is_empty(common)) { + isl_set_free(common); + continue; + } + set = isl_set_subtract(set, + isl_set_copy(pw2->p[j].set)); + + sum = FN(EL,add_on_domain)(common, + FN(EL,copy)(pw1->p[i].FIELD), + FN(EL,copy)(pw2->p[j].FIELD)); + + res = FN(PW,add_piece)(res, common, sum); + } + res = FN(PW,add_piece)(res, set, FN(EL,copy)(pw1->p[i].FIELD)); + } + + for (j = 0; j < pw2->n; ++j) { + set = isl_set_copy(pw2->p[j].set); + for (i = 0; i < pw1->n; ++i) + set = isl_set_subtract(set, + isl_set_copy(pw1->p[i].set)); + res = FN(PW,add_piece)(res, set, FN(EL,copy)(pw2->p[j].FIELD)); + } + + FN(PW,free)(pw1); + FN(PW,free)(pw2); + + return res; +error: + FN(PW,free)(pw1); + FN(PW,free)(pw2); + return NULL; +} + +#if !DEFAULT_IS_ZERO + +/* Compute the sum of "pw1" and "pw2 on the union of their domains, + * with the actual sum on the shared domain and + * the defined expression on the symmetric difference of the domains. + * + * This function is only defined for object types that do not have + * a default zero value. For other object types, this function + * is simply called "add". + */ +__isl_give PW *FN(PW,union_add)(__isl_take PW *pw1, __isl_take PW *pw2) +{ + return FN(PW,union_add_)(pw1, pw2); +} + +#endif + +/* This function is currently only used from isl_aff.c + */ +static __isl_give PW *FN(PW,on_shared_domain_in)(__isl_take PW *pw1, + __isl_take PW *pw2, __isl_take isl_space *space, + __isl_give EL *(*fn)(__isl_take EL *el1, __isl_take EL *el2)) + __attribute__ ((unused)); + +/* Apply "fn" to pairs of elements from pw1 and pw2 on shared domains. + * The result of "fn" (and therefore also of this function) lives in "space". + */ +static __isl_give PW *FN(PW,on_shared_domain_in)(__isl_take PW *pw1, + __isl_take PW *pw2, __isl_take isl_space *space, + __isl_give EL *(*fn)(__isl_take EL *el1, __isl_take EL *el2)) +{ + int i, j, n; + PW *res = NULL; + + if (!pw1 || !pw2) + goto error; + + n = pw1->n * pw2->n; + res = FN(PW,alloc_size)(isl_space_copy(space) OPT_TYPE_ARG(pw1->), n); + + for (i = 0; i < pw1->n; ++i) { + for (j = 0; j < pw2->n; ++j) { + isl_set *common; + EL *res_ij; + int empty; + + common = isl_set_intersect( + isl_set_copy(pw1->p[i].set), + isl_set_copy(pw2->p[j].set)); + empty = isl_set_plain_is_empty(common); + if (empty < 0 || empty) { + isl_set_free(common); + if (empty < 0) + goto error; + continue; + } + + res_ij = fn(FN(EL,copy)(pw1->p[i].FIELD), + FN(EL,copy)(pw2->p[j].FIELD)); + res_ij = FN(EL,gist)(res_ij, isl_set_copy(common)); + + res = FN(PW,add_piece)(res, common, res_ij); + } + } + + isl_space_free(space); + FN(PW,free)(pw1); + FN(PW,free)(pw2); + return res; +error: + isl_space_free(space); + FN(PW,free)(pw1); + FN(PW,free)(pw2); + FN(PW,free)(res); + return NULL; +} + +/* This function is currently only used from isl_aff.c + */ +static __isl_give PW *FN(PW,on_shared_domain)(__isl_take PW *pw1, + __isl_take PW *pw2, + __isl_give EL *(*fn)(__isl_take EL *el1, __isl_take EL *el2)) + __attribute__ ((unused)); + +/* Apply "fn" to pairs of elements from pw1 and pw2 on shared domains. + * The result of "fn" is assumed to live in the same space as "pw1" and "pw2". + */ +static __isl_give PW *FN(PW,on_shared_domain)(__isl_take PW *pw1, + __isl_take PW *pw2, + __isl_give EL *(*fn)(__isl_take EL *el1, __isl_take EL *el2)) +{ + isl_space *space; + + if (FN(PW,check_equal_space)(pw1, pw2) < 0) + goto error; + + space = isl_space_copy(pw1->dim); + return FN(PW,on_shared_domain_in)(pw1, pw2, space, fn); +error: + FN(PW,free)(pw1); + FN(PW,free)(pw2); + return NULL; +} + +/* Return the parameter domain of "pw". + */ +__isl_give isl_set *FN(PW,params)(__isl_take PW *pw) +{ + return isl_set_params(FN(PW,domain)(pw)); +} + +__isl_give isl_set *FN(PW,domain)(__isl_take PW *pw) +{ + int i; + isl_set *dom; + + if (!pw) + return NULL; + + dom = isl_set_empty(FN(PW,get_domain_space)(pw)); + for (i = 0; i < pw->n; ++i) + dom = isl_set_union_disjoint(dom, isl_set_copy(pw->p[i].set)); + + FN(PW,free)(pw); + + return dom; +} + +/* Exploit the equalities in the domain of piece "i" of "pw" + * to simplify the associated function. + * If the domain of piece "i" is empty, then remove it entirely, + * replacing it with the final piece. + */ +static __isl_give PW *FN(PW,exploit_equalities_and_remove_if_empty)( + __isl_take PW *pw, int i) +{ + EL *el; + isl_set *domain; + isl_basic_set *aff; + int empty; + + domain = FN(PW,peek_domain_at)(pw, i); + empty = isl_set_plain_is_empty(domain); + if (empty < 0) + return FN(PW,free)(pw); + if (empty) { + isl_set_free(pw->p[i].set); + FN(EL,free)(pw->p[i].FIELD); + if (i != pw->n - 1) + pw->p[i] = pw->p[pw->n - 1]; + pw->n--; + + return pw; + } + + aff = isl_set_affine_hull(FN(PW,get_domain_at)(pw, i)); + el = FN(PW,take_base_at)(pw, i); + el = FN(EL,substitute_equalities)(el, aff); + pw = FN(PW,restore_base_at_inplace)(pw, i, el); + + return pw; +} + +/* Restrict the domain of "pw" by combining each cell + * with "set" through a call to "fn", where "fn" may be + * isl_set_intersect, isl_set_intersect_params, isl_set_intersect_factor_domain, + * isl_set_intersect_factor_range or isl_set_subtract. + */ +static __isl_give PW *FN(PW,restrict_domain)(__isl_take PW *pw, + __isl_take isl_set *set, + __isl_give isl_set *(*fn)(__isl_take isl_set *set1, + __isl_take isl_set *set2)) +{ + int i; + isl_size n; + + FN(PW,align_params_set)(&pw, &set); + n = FN(PW,n_piece)(pw); + if (n < 0 || !set) + goto error; + + for (i = n - 1; i >= 0; --i) { + isl_set *domain; + + domain = FN(PW,take_domain_at)(pw, i); + domain = fn(domain, isl_set_copy(set)); + pw = FN(PW,restore_domain_at)(pw, i, domain); + pw = FN(PW,exploit_equalities_and_remove_if_empty)(pw, i); + } + + isl_set_free(set); + return pw; +error: + isl_set_free(set); + FN(PW,free)(pw); + return NULL; +} + +__isl_give PW *FN(PW,intersect_domain)(__isl_take PW *pw, + __isl_take isl_set *context) +{ + return FN(PW,restrict_domain)(pw, context, &isl_set_intersect); +} + +/* Intersect the domain of "pw" with the parameter domain "context". + */ +__isl_give PW *FN(PW,intersect_params)(__isl_take PW *pw, + __isl_take isl_set *context) +{ + return FN(PW,restrict_domain)(pw, context, &isl_set_intersect_params); +} + +/* Given a piecewise expression "pw" with domain in a space [A -> B] and + * a set in the space A, intersect the domain with the set. + */ +__isl_give PW *FN(PW,intersect_domain_wrapped_domain)(__isl_take PW *pw, + __isl_take isl_set *set) +{ + return FN(PW,restrict_domain)(pw, set, + &isl_set_intersect_factor_domain); +} + +/* Given a piecewise expression "pw" with domain in a space [A -> B] and + * a set in the space B, intersect the domain with the set. + */ +__isl_give PW *FN(PW,intersect_domain_wrapped_range)(__isl_take PW *pw, + __isl_take isl_set *set) +{ + return FN(PW,restrict_domain)(pw, set, &isl_set_intersect_factor_range); +} + +/* Subtract "domain' from the domain of "pw". + */ +__isl_give PW *FN(PW,subtract_domain)(__isl_take PW *pw, + __isl_take isl_set *domain) +{ + return FN(PW,restrict_domain)(pw, domain, &isl_set_subtract); +} + +/* Return -1 if the piece "p1" should be sorted before "p2" + * and 1 if it should be sorted after "p2". + * Return 0 if they do not need to be sorted in a specific order. + * + * The two pieces are compared on the basis of their function value expressions. + */ +static int FN(PW,sort_field_cmp)(const void *p1, const void *p2, void *arg) +{ + struct FN(PW,piece) const *pc1 = p1; + struct FN(PW,piece) const *pc2 = p2; + + return FN(EL,plain_cmp)(pc1->FIELD, pc2->FIELD); +} + +/* Sort the pieces of "pw" according to their function value + * expressions and then combine pairs of adjacent pieces with + * the same such expression. + * + * The sorting is performed in place because it does not + * change the meaning of "pw", but care needs to be + * taken not to change any possible other copies of "pw" + * in case anything goes wrong. + */ +static __isl_give PW *FN(PW,sort_unique)(__isl_take PW *pw) +{ + int i, j; + isl_set *set; + + if (!pw) + return NULL; + if (pw->n <= 1) + return pw; + if (isl_sort(pw->p, pw->n, sizeof(pw->p[0]), + &FN(PW,sort_field_cmp), NULL) < 0) + return FN(PW,free)(pw); + for (i = pw->n - 1; i >= 1; --i) { + isl_bool equal; + EL *el, *el_prev; + isl_set *set_prev; + + el = FN(PW,peek_base_at)(pw, i); + el_prev = FN(PW,peek_base_at)(pw, i - 1); + equal = FN(EL,plain_is_equal)(el, el_prev); + if (equal < 0) + return FN(PW,free)(pw); + if (!equal) + continue; + set = FN(PW,get_domain_at)(pw, i); + set_prev = FN(PW,get_domain_at)(pw, i - 1); + set = isl_set_union(set_prev, set); + if (!set) + return FN(PW,free)(pw); + isl_set_free(pw->p[i].set); + FN(EL,free)(pw->p[i].FIELD); + isl_set_free(pw->p[i - 1].set); + pw->p[i - 1].set = set; + for (j = i + 1; j < pw->n; ++j) + pw->p[j - 1] = pw->p[j]; + pw->n--; + } + + return pw; +} + +/* Compute the gist of "pw" with respect to the domain constraints + * of "context" for the case where the domain of the last element + * of "pw" is equal to "context". + * Compute the gist of this element, replace + * its domain by the universe and drop all other elements + * as their domains are necessarily disjoint from "context". + */ +static __isl_give PW *FN(PW,gist_last)(__isl_take PW *pw, + __isl_take isl_set *context) +{ + int i; + isl_space *space; + EL *el; + + for (i = 0; i < pw->n - 1; ++i) { + isl_set_free(pw->p[i].set); + FN(EL,free)(pw->p[i].FIELD); + } + pw->p[0].FIELD = pw->p[pw->n - 1].FIELD; + pw->p[0].set = pw->p[pw->n - 1].set; + pw->n = 1; + + space = isl_set_get_space(context); + el = FN(PW,take_base_at)(pw, 0); + el = FN(EL,gist)(el, context); + pw = FN(PW,restore_base_at)(pw, 0, el); + context = isl_set_universe(space); + pw = FN(PW,restore_domain_at)(pw, 0, context); + + return pw; +} + +/* Compute the gist of "pw" with respect to the domain constraints + * of "context". + * Call "fn_dom" to compute the gist of the domains and + * "intersect_context" to intersect the domain with the context. + * + * If the piecewise expression is empty or the context is the universe, + * then nothing can be simplified. + * If "pw" has a single domain and it is equal to "context", + * then simply replace the domain by the universe. + * Combine duplicate function value expressions first + * to increase the chance of "pw" having a single domain. + */ +static __isl_give PW *FN(PW,gist_fn)(__isl_take PW *pw, + __isl_take isl_set *context, + __isl_give isl_set *(*fn_dom)(__isl_take isl_set *set, + __isl_take isl_set *context), + __isl_give isl_set *intersect_context(__isl_take isl_set *set, + __isl_take isl_set *context)) +{ + int i; + int is_universe; + + pw = FN(PW,sort_unique)(pw); + if (!pw || !context) + goto error; + + if (pw->n == 0) { + isl_set_free(context); + return pw; + } + + is_universe = isl_set_plain_is_universe(context); + if (is_universe < 0) + goto error; + if (is_universe) { + isl_set_free(context); + return pw; + } + + FN(PW,align_params_set)(&pw, &context); + + pw = FN(PW,cow)(pw); + if (!pw) + goto error; + + if (pw->n == 1) { + int equal; + + equal = isl_set_plain_is_equal(pw->p[0].set, context); + if (equal < 0) + goto error; + if (equal) + return FN(PW,gist_last)(pw, context); + } + + context = isl_set_compute_divs(context); + + for (i = pw->n - 1; i >= 0; --i) { + isl_set *set_i; + EL *el; + int empty; + + if (i == pw->n - 1) { + int equal; + equal = isl_set_plain_is_equal(pw->p[i].set, context); + if (equal < 0) + goto error; + if (equal) + return FN(PW,gist_last)(pw, context); + } + set_i = FN(PW,get_domain_at)(pw, i); + set_i = intersect_context(set_i, isl_set_copy(context)); + empty = isl_set_plain_is_empty(set_i); + el = FN(PW,take_base_at)(pw, i); + el = FN(EL,gist)(el, set_i); + pw = FN(PW,restore_base_at)(pw, i, el); + set_i = FN(PW,take_domain_at)(pw, i); + set_i = fn_dom(set_i, isl_set_copy(context)); + pw = FN(PW,restore_domain_at)(pw, i, set_i); + if (empty < 0 || !pw) + goto error; + if (empty) { + isl_set_free(pw->p[i].set); + FN(EL,free)(pw->p[i].FIELD); + if (i != pw->n - 1) + pw->p[i] = pw->p[pw->n - 1]; + pw->n--; + } + } + + isl_set_free(context); + + return pw; +error: + FN(PW,free)(pw); + isl_set_free(context); + return NULL; +} + +__isl_give PW *FN(PW,gist)(__isl_take PW *pw, __isl_take isl_set *context) +{ + return FN(PW,gist_fn)(pw, context, &isl_set_gist, + &isl_set_intersect); +} + +__isl_give PW *FN(PW,gist_params)(__isl_take PW *pw, + __isl_take isl_set *context) +{ + return FN(PW,gist_fn)(pw, context, &isl_set_gist_params, + &isl_set_intersect_params); +} + +/* Coalesce the domains of "pw". + * + * Prior to the actual coalescing, first sort the pieces such that + * pieces with the same function value expression are combined + * into a single piece, the combined domain of which can then + * be coalesced. + */ +__isl_give PW *FN(PW,coalesce)(__isl_take PW *pw) +{ + int i; + isl_size n; + + pw = FN(PW,sort_unique)(pw); + n = FN(PW,n_piece)(pw); + if (n < 0) + return FN(PW,free)(pw); + + for (i = 0; i < n; ++i) { + pw->p[i].set = isl_set_coalesce(pw->p[i].set); + if (!pw->p[i].set) + goto error; + } + + return pw; +error: + FN(PW,free)(pw); + return NULL; +} + +isl_ctx *FN(PW,get_ctx)(__isl_keep PW *pw) +{ + return pw ? isl_space_get_ctx(pw->dim) : NULL; +} + +isl_bool FN(PW,involves_dims)(__isl_keep PW *pw, enum isl_dim_type type, + unsigned first, unsigned n) +{ + int i; + enum isl_dim_type set_type; + + if (!pw) + return isl_bool_error; + if (pw->n == 0 || n == 0) + return isl_bool_false; + + set_type = type == isl_dim_in ? isl_dim_set : type; + + for (i = 0; i < pw->n; ++i) { + isl_bool involves = FN(EL,involves_dims)(pw->p[i].FIELD, + type, first, n); + if (involves < 0 || involves) + return involves; + involves = isl_set_involves_dims(pw->p[i].set, + set_type, first, n); + if (involves < 0 || involves) + return involves; + } + return isl_bool_false; +} + +__isl_give PW *FN(PW,set_dim_name)(__isl_take PW *pw, + enum isl_dim_type type, unsigned pos, const char *s) +{ + isl_space *space; + + space = FN(PW,get_space)(pw); + space = isl_space_set_dim_name(space, type, pos, s); + return FN(PW,reset_space)(pw, space); +} + +__isl_give PW *FN(PW,drop_dims)(__isl_take PW *pw, + enum isl_dim_type type, unsigned first, unsigned n) +{ + int i; + isl_size n_piece; + enum isl_dim_type set_type; + isl_space *space; + + n_piece = FN(PW,n_piece)(pw); + if (n_piece < 0) + return FN(PW,free)(pw); + if (n == 0 && !isl_space_get_tuple_name(pw->dim, type)) + return pw; + + set_type = type == isl_dim_in ? isl_dim_set : type; + + space = FN(PW,take_space)(pw); + space = isl_space_drop_dims(space, type, first, n); + pw = FN(PW,restore_space)(pw, space); + for (i = 0; i < n_piece; ++i) { + isl_set *domain; + EL *el; + + el = FN(PW,take_base_at)(pw, i); + el = FN(EL,drop_dims)(el, type, first, n); + pw = FN(PW,restore_base_at)(pw, i, el); + if (type == isl_dim_out) + continue; + domain = FN(PW,take_domain_at)(pw, i); + domain = isl_set_drop(domain, set_type, first, n); + pw = FN(PW,restore_domain_at)(pw, i, domain); + } + + return pw; +} + +/* This function is very similar to drop_dims. + * The only difference is that the cells may still involve + * the specified dimensions. They are removed using + * isl_set_project_out instead of isl_set_drop. + */ +__isl_give PW *FN(PW,project_out)(__isl_take PW *pw, + enum isl_dim_type type, unsigned first, unsigned n) +{ + int i; + isl_size n_piece; + enum isl_dim_type set_type; + isl_space *space; + + n_piece = FN(PW,n_piece)(pw); + if (n_piece < 0) + return FN(PW,free)(pw); + if (n == 0 && !isl_space_get_tuple_name(pw->dim, type)) + return pw; + + set_type = type == isl_dim_in ? isl_dim_set : type; + + space = FN(PW,take_space)(pw); + space = isl_space_drop_dims(space, type, first, n); + pw = FN(PW,restore_space)(pw, space); + for (i = 0; i < n_piece; ++i) { + isl_set *domain; + EL *el; + + domain = FN(PW,take_domain_at)(pw, i); + domain = isl_set_project_out(domain, set_type, first, n); + pw = FN(PW,restore_domain_at)(pw, i, domain); + el = FN(PW,take_base_at)(pw, i); + el = FN(EL,drop_dims)(el, type, first, n); + pw = FN(PW,restore_base_at)(pw, i, el); + } + + return pw; +} + +/* Project the domain of pw onto its parameter space. + */ +__isl_give PW *FN(PW,project_domain_on_params)(__isl_take PW *pw) +{ + isl_space *space; + isl_size n; + + n = FN(PW,dim)(pw, isl_dim_in); + if (n < 0) + return FN(PW,free)(pw); + pw = FN(PW,project_out)(pw, isl_dim_in, 0, n); + space = FN(PW,get_domain_space)(pw); + space = isl_space_params(space); + pw = FN(PW,reset_domain_space)(pw, space); + return pw; +} + +#undef TYPE +#define TYPE PW +#include "isl_drop_unused_params_templ.c" + +isl_size FN(PW,dim)(__isl_keep PW *pw, enum isl_dim_type type) +{ + return isl_space_dim(FN(PW,peek_space)(pw), type); +} + +__isl_give isl_space *FN(PW,get_domain_space)(__isl_keep PW *pw) +{ + return pw ? isl_space_domain(isl_space_copy(pw->dim)) : NULL; +} + +/* Return the position of the dimension of the given type and name + * in "pw". + * Return -1 if no such dimension can be found. + */ +int FN(PW,find_dim_by_name)(__isl_keep PW *pw, + enum isl_dim_type type, const char *name) +{ + if (!pw) + return -1; + return isl_space_find_dim_by_name(pw->dim, type, name); +} + +/* Return the position of the dimension of the given type and identifier + * in "pw". + * Return -1 if no such dimension can be found. + */ +static int FN(PW,find_dim_by_id)(__isl_keep PW *pw, + enum isl_dim_type type, __isl_keep isl_id *id) +{ + isl_space *space; + + space = FN(PW,peek_space)(pw); + return isl_space_find_dim_by_id(space, type, id); +} + +/* Does the piecewise expression "pw" depend in any way + * on the parameter with identifier "id"? + */ +isl_bool FN(PW,involves_param_id)(__isl_keep PW *pw, __isl_keep isl_id *id) +{ + int pos; + + if (!pw || !id) + return isl_bool_error; + if (pw->n == 0) + return isl_bool_false; + + pos = FN(PW,find_dim_by_id)(pw, isl_dim_param, id); + if (pos < 0) + return isl_bool_false; + return FN(PW,involves_dims)(pw, isl_dim_param, pos, 1); +} + +/* Reset the space of "pw". Since we don't know if the elements + * represent the spaces themselves or their domains, we pass along + * both when we call their reset_space_and_domain. + */ +static __isl_give PW *FN(PW,reset_space_and_domain)(__isl_take PW *pw, + __isl_take isl_space *space, __isl_take isl_space *domain) +{ + int i; + isl_size n; + + n = FN(PW,n_piece)(pw); + if (n < 0 || !space || !domain) + goto error; + + for (i = 0; i < n; ++i) { + isl_set *set; + EL *el; + + set = FN(PW,take_domain_at)(pw, i); + set = isl_set_reset_space(set, isl_space_copy(domain)); + pw = FN(PW,restore_domain_at)(pw, i, set); + el = FN(PW,take_base_at)(pw, i); + el = FN(EL,reset_space_and_domain)(el, + isl_space_copy(space), isl_space_copy(domain)); + pw = FN(PW,restore_base_at)(pw, i, el); + } + + isl_space_free(domain); + + pw = FN(PW,restore_space)(pw, space); + + return pw; +error: + isl_space_free(domain); + isl_space_free(space); + FN(PW,free)(pw); + return NULL; +} + +__isl_give PW *FN(PW,reset_domain_space)(__isl_take PW *pw, + __isl_take isl_space *domain) +{ + isl_space *space; + + space = isl_space_extend_domain_with_range(isl_space_copy(domain), + FN(PW,get_space)(pw)); + return FN(PW,reset_space_and_domain)(pw, space, domain); +} + +__isl_give PW *FN(PW,reset_space)(__isl_take PW *pw, + __isl_take isl_space *space) +{ + isl_space *domain; + + domain = isl_space_domain(isl_space_copy(space)); + return FN(PW,reset_space_and_domain)(pw, space, domain); +} + +__isl_give PW *FN(PW,set_tuple_id)(__isl_take PW *pw, enum isl_dim_type type, + __isl_take isl_id *id) +{ + isl_space *space; + + pw = FN(PW,cow)(pw); + if (!pw) + goto error; + + space = FN(PW,get_space)(pw); + space = isl_space_set_tuple_id(space, type, id); + + return FN(PW,reset_space)(pw, space); +error: + isl_id_free(id); + return FN(PW,free)(pw); +} + +/* Drop the id on the specified tuple. + */ +__isl_give PW *FN(PW,reset_tuple_id)(__isl_take PW *pw, enum isl_dim_type type) +{ + isl_space *space; + + if (!pw) + return NULL; + if (!FN(PW,has_tuple_id)(pw, type)) + return pw; + + pw = FN(PW,cow)(pw); + if (!pw) + return NULL; + + space = FN(PW,get_space)(pw); + space = isl_space_reset_tuple_id(space, type); + + return FN(PW,reset_space)(pw, space); +} + +__isl_give PW *FN(PW,set_dim_id)(__isl_take PW *pw, + enum isl_dim_type type, unsigned pos, __isl_take isl_id *id) +{ + isl_space *space; + + space = FN(PW,get_space)(pw); + space = isl_space_set_dim_id(space, type, pos, id); + return FN(PW,reset_space)(pw, space); +} + +/* Reset the user pointer on all identifiers of parameters and tuples + * of the space of "pw". + */ +__isl_give PW *FN(PW,reset_user)(__isl_take PW *pw) +{ + isl_space *space; + + space = FN(PW,get_space)(pw); + space = isl_space_reset_user(space); + + return FN(PW,reset_space)(pw, space); +} + +isl_size FN(PW,n_piece)(__isl_keep PW *pw) +{ + return pw ? pw->n : isl_size_error; +} + +isl_stat FN(PW,foreach_piece)(__isl_keep PW *pw, + isl_stat (*fn)(__isl_take isl_set *set, __isl_take EL *el, void *user), + void *user) +{ + int i; + + if (!pw) + return isl_stat_error; + + for (i = 0; i < pw->n; ++i) + if (fn(isl_set_copy(pw->p[i].set), + FN(EL,copy)(pw->p[i].FIELD), user) < 0) + return isl_stat_error; + + return isl_stat_ok; +} + +/* Does "test" succeed on every cell of "pw"? + */ +isl_bool FN(PW,every_piece)(__isl_keep PW *pw, + isl_bool (*test)(__isl_keep isl_set *set, + __isl_keep EL *el, void *user), void *user) +{ + int i; + + if (!pw) + return isl_bool_error; + + for (i = 0; i < pw->n; ++i) { + isl_bool r; + + r = test(pw->p[i].set, pw->p[i].FIELD, user); + if (r < 0 || !r) + return r; + } + + return isl_bool_true; +} + +/* Is "pw" defined over a single universe domain? + * + * If the default value of this piecewise type is zero, + * then a "pw" with a zero number of cells is also accepted + * as it represents the default zero value. + */ +isl_bool FN(FN(PW,isa),BASE)(__isl_keep PW *pw) +{ + isl_size n; + + n = FN(PW,n_piece)(pw); + if (n < 0) + return isl_bool_error; + if (DEFAULT_IS_ZERO && n == 0) + return isl_bool_true; + if (n != 1) + return isl_bool_false; + return isl_set_plain_is_universe(FN(PW,peek_domain_at)(pw, 0)); +} + +/* Return a zero base expression in the same space (and of the same type) + * as "pw". + */ +static __isl_give EL *FN(EL,zero_like_type)(__isl_take PW *pw OPT_TYPE_PARAM) +{ + isl_space *space; + + space = FN(PW,get_space)(pw); + FN(PW,free)(pw); + return FN(EL,zero_in_space)(space OPT_TYPE_ARG(NO_LOC)); +} + +#ifndef HAS_TYPE +/* Return a zero base expression in the same space as "pw". + */ +static __isl_give EL *FN(EL,zero_like)(__isl_take PW *pw) +{ + return FN(EL,zero_like_type)(pw); +} +#else +/* Return a zero base expression in the same space and of the same type + * as "pw". + * + * Pass along the type as an explicit argument for uniform handling + * in isl_*_zero_like_type. + */ +static __isl_give EL *FN(EL,zero_like)(__isl_take PW *pw) +{ + enum isl_fold type; + + type = FN(PW,get_type)(pw); + if (type < 0) + goto error; + return FN(EL,zero_like_type)(pw, type); +error: + FN(PW,free)(pw); + return NULL; +} +#endif + +/* Given that "pw" is defined over a single universe domain, + * return the base expression associated to this domain. + * + * If the number of cells is zero, then "pw" is of a piecewise type + * with a default zero value and effectively represents zero. + * In this case, create a zero base expression in the same space + * (and with the same type). + * Otherwise, simply extract the associated base expression. + */ +__isl_give EL *FN(FN(PW,as),BASE)(__isl_take PW *pw) +{ + isl_bool is_total; + isl_size n; + EL *el; + + is_total = FN(FN(PW,isa),BASE)(pw); + if (is_total < 0) + goto error; + if (!is_total) + isl_die(FN(PW,get_ctx)(pw), isl_error_invalid, + "expecting single total function", goto error); + n = FN(PW,n_piece)(pw); + if (n < 0) + goto error; + if (n == 0) + return FN(EL,zero_like)(pw); + el = FN(PW,take_base_at)(pw, 0); + FN(PW,free)(pw); + return el; +error: + FN(PW,free)(pw); + return NULL; +} + +#ifdef HAS_TYPE +/* Negate the type of "pw". + */ +static __isl_give PW *FN(PW,negate_type)(__isl_take PW *pw) +{ + pw = FN(PW,cow)(pw); + if (!pw) + return NULL; + pw->type = isl_fold_type_negate(pw->type); + return pw; +} +#else +/* Negate the type of "pw". + * Since "pw" does not have a type, do nothing. + */ +static __isl_give PW *FN(PW,negate_type)(__isl_take PW *pw) +{ + return pw; +} +#endif + +/* Multiply the pieces of "pw" by "v" and return the result. + */ +__isl_give PW *FN(PW,scale_val)(__isl_take PW *pw, __isl_take isl_val *v) +{ + int i; + isl_size n; + + if (!pw || !v) + goto error; + + if (isl_val_is_one(v)) { + isl_val_free(v); + return pw; + } + if (pw && DEFAULT_IS_ZERO && isl_val_is_zero(v)) { + PW *zero; + isl_space *space = FN(PW,get_space)(pw); + zero = FN(PW,ZERO)(space OPT_TYPE_ARG(pw->)); + FN(PW,free)(pw); + isl_val_free(v); + return zero; + } + if (isl_val_is_neg(v)) + pw = FN(PW,negate_type)(pw); + n = FN(PW,n_piece)(pw); + if (n < 0) + goto error; + + for (i = 0; i < n; ++i) { + EL *el; + + el = FN(PW,take_base_at)(pw, i); + el = FN(EL,scale_val)(el, isl_val_copy(v)); + pw = FN(PW,restore_base_at)(pw, i, el); + } + + isl_val_free(v); + return pw; +error: + isl_val_free(v); + FN(PW,free)(pw); + return NULL; +} + +/* Divide the pieces of "pw" by "v" and return the result. + */ +__isl_give PW *FN(PW,scale_down_val)(__isl_take PW *pw, __isl_take isl_val *v) +{ + int i; + isl_size n; + + if (!pw || !v) + goto error; + + if (isl_val_is_one(v)) { + isl_val_free(v); + return pw; + } + + if (!isl_val_is_rat(v)) + isl_die(isl_val_get_ctx(v), isl_error_invalid, + "expecting rational factor", goto error); + if (isl_val_is_zero(v)) + isl_die(isl_val_get_ctx(v), isl_error_invalid, + "cannot scale down by zero", goto error); + + if (isl_val_is_neg(v)) + pw = FN(PW,negate_type)(pw); + n = FN(PW,n_piece)(pw); + if (n < 0) + goto error; + + for (i = 0; i < n; ++i) { + EL *el; + + el = FN(PW,take_base_at)(pw, i); + el = FN(EL,scale_down_val)(el, isl_val_copy(v)); + pw = FN(PW,restore_base_at)(pw, i, el); + } + + isl_val_free(v); + return pw; +error: + isl_val_free(v); + FN(PW,free)(pw); + return NULL; +} + +/* Apply some normalization to "pw". + * In particular, sort the pieces according to their function value + * expressions, combining pairs of adjacent pieces with + * the same such expression, and then normalize the domains of the pieces. + * + * We normalize in place, but if anything goes wrong we need + * to return NULL, so we need to make sure we don't change the + * meaning of any possible other copies of "pw". + */ +static __isl_give PW *FN(PW,normalize)(__isl_take PW *pw) +{ + int i; + isl_set *set; + + pw = FN(PW,sort_unique)(pw); + if (!pw) + return NULL; + for (i = 0; i < pw->n; ++i) { + set = isl_set_normalize(isl_set_copy(pw->p[i].set)); + if (!set) + return FN(PW,free)(pw); + isl_set_free(pw->p[i].set); + pw->p[i].set = set; + } + + return pw; +} + +/* Is pw1 obviously equal to pw2? + * That is, do they have obviously identical cells and obviously identical + * elements on each cell? + * + * If "pw1" or "pw2" contain any NaNs, then they are considered + * not to be the same. A NaN is not equal to anything, not even + * to another NaN. + */ +isl_bool FN(PW,plain_is_equal)(__isl_keep PW *pw1, __isl_keep PW *pw2) +{ + int i; + isl_bool equal, has_nan; + + if (!pw1 || !pw2) + return isl_bool_error; + + has_nan = FN(PW,involves_nan)(pw1); + if (has_nan >= 0 && !has_nan) + has_nan = FN(PW,involves_nan)(pw2); + if (has_nan < 0 || has_nan) + return isl_bool_not(has_nan); + + if (pw1 == pw2) + return isl_bool_true; + equal = FN(PW,has_equal_space)(pw1, pw2); + if (equal < 0 || !equal) + return equal; + + pw1 = FN(PW,copy)(pw1); + pw2 = FN(PW,copy)(pw2); + pw1 = FN(PW,normalize)(pw1); + pw2 = FN(PW,normalize)(pw2); + if (!pw1 || !pw2) + goto error; + + equal = isl_bool_ok(pw1->n == pw2->n); + for (i = 0; equal && i < pw1->n; ++i) { + equal = isl_set_plain_is_equal(pw1->p[i].set, pw2->p[i].set); + if (equal < 0) + goto error; + if (!equal) + break; + equal = FN(EL,plain_is_equal)(pw1->p[i].FIELD, pw2->p[i].FIELD); + if (equal < 0) + goto error; + } + + FN(PW,free)(pw1); + FN(PW,free)(pw2); + return equal; +error: + FN(PW,free)(pw1); + FN(PW,free)(pw2); + return isl_bool_error; +} + +/* Does "pw" involve any NaNs? + */ +isl_bool FN(PW,involves_nan)(__isl_keep PW *pw) +{ + int i; + + if (!pw) + return isl_bool_error; + if (pw->n == 0) + return isl_bool_false; + + for (i = 0; i < pw->n; ++i) { + isl_bool has_nan = FN(EL,involves_nan)(pw->p[i].FIELD); + if (has_nan < 0 || has_nan) + return has_nan; + } + + return isl_bool_false; +} diff --git a/external/mit/isl/dist/isl_pw_templ.h b/external/mit/isl/dist/isl_pw_templ.h new file mode 100644 index 000000000000..98db44af2ff1 --- /dev/null +++ b/external/mit/isl/dist/isl_pw_templ.h @@ -0,0 +1,5 @@ +#include + +#include + +__isl_keep isl_space *FN(PW,peek_space)(__isl_keep PW *pw); diff --git a/external/mit/isl/dist/isl_pw_un_op_templ.c b/external/mit/isl/dist/isl_pw_un_op_templ.c new file mode 100644 index 000000000000..5b9a0550a67f --- /dev/null +++ b/external/mit/isl/dist/isl_pw_un_op_templ.c @@ -0,0 +1,72 @@ +/* + * Copyright 2010 INRIA Saclay + * + * 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 + */ + +#include + +/* Data structure that specifies how isl_pw_*_un_op should + * modify its input. + * + * If "fn_space" is set, then it is applied to the space. + * + * If "fn_domain" is set, then it is applied to the cells. + * + * "fn_base" is applied to each base expression. + * This function is assumed to have no effect on the default value + * (i.e., zero for those objects with a default value). + */ +S(PW,un_op_control) { + __isl_give isl_space *(*fn_space)(__isl_take isl_space *space); + __isl_give isl_set *(*fn_domain)(__isl_take isl_set *domain); + __isl_give EL *(*fn_base)(__isl_take EL *el); +}; + +/* Modify "pw" based on "control". + * + * If the cells are modified, then the corresponding base expressions + * may need to be adjusted to the possibly modified equality constraints. + */ +static __isl_give PW *FN(PW,un_op)(__isl_take PW *pw, + S(PW,un_op_control) *control) +{ + isl_space *space; + isl_size n; + int i; + + n = FN(PW,n_piece)(pw); + if (n < 0) + return FN(PW,free)(pw); + + for (i = n - 1; i >= 0; --i) { + EL *el; + isl_set *domain; + + el = FN(PW,take_base_at)(pw, i); + el = control->fn_base(el); + pw = FN(PW,restore_base_at)(pw, i, el); + + if (!control->fn_domain) + continue; + + domain = FN(PW,take_domain_at)(pw, i); + domain = control->fn_domain(domain); + pw = FN(PW,restore_domain_at)(pw, i, domain); + + pw = FN(PW,exploit_equalities_and_remove_if_empty)(pw, i); + } + + if (!control->fn_space) + return pw; + + space = FN(PW,take_space)(pw); + space = control->fn_space(space); + pw = FN(PW,restore_space)(pw, space); + + return pw; +} diff --git a/external/mit/isl/dist/isl_pw_union_opt.c b/external/mit/isl/dist/isl_pw_union_opt.c new file mode 100644 index 000000000000..99b0045960f2 --- /dev/null +++ b/external/mit/isl/dist/isl_pw_union_opt.c @@ -0,0 +1,359 @@ +/* + * Copyright 2011 INRIA Saclay + * Copyright 2012 Ecole Normale Superieure + * Copyright 2020 Cerebras Systems + * + * 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 + * and Cerebras Systems, 175 S San Antonio Rd, Los Altos, CA, USA + */ + +#include + +/* Given a function "cmp" that returns the set of elements where + * "el1" is "better" than "el2", return this set. + */ +static __isl_give isl_set *FN(PW,better)(__isl_keep EL *el1, __isl_keep EL *el2, + __isl_give isl_set *(*cmp)(__isl_take EL *el1, __isl_take EL *el2)) +{ + return cmp(FN(EL,copy)(el1), FN(EL,copy)(el2)); +} + +/* Return a list containing the domains of the pieces of "pw". + */ +static __isl_give isl_set_list *FN(PW,extract_domains)(__isl_keep PW *pw) +{ + int i; + isl_ctx *ctx; + isl_set_list *list; + + if (!pw) + return NULL; + ctx = FN(PW,get_ctx)(pw); + list = isl_set_list_alloc(ctx, pw->n); + for (i = 0; i < pw->n; ++i) + list = isl_set_list_add(list, isl_set_copy(pw->p[i].set)); + + return list; +} + +/* Given sets B ("set"), C ("better") and A' ("out"), return + * + * (B \cap C) \cup ((B \setminus C) \setminus A') + */ +static __isl_give isl_set *FN(PW,better_or_out)(__isl_take isl_set *set, + __isl_take isl_set *better, __isl_take isl_set *out) +{ + isl_set *set_better, *set_out; + + set_better = isl_set_intersect(isl_set_copy(set), isl_set_copy(better)); + set_out = isl_set_subtract(isl_set_subtract(set, better), out); + + return isl_set_union(set_better, set_out); +} + +/* Given sets A ("set"), C ("better") and B' ("out"), return + * + * (A \setminus C) \cup ((A \cap C) \setminus B') + */ +static __isl_give isl_set *FN(PW,worse_or_out)(__isl_take isl_set *set, + __isl_take isl_set *better, __isl_take isl_set *out) +{ + isl_set *set_worse, *set_out; + + set_worse = isl_set_subtract(isl_set_copy(set), isl_set_copy(better)); + set_out = isl_set_subtract(isl_set_intersect(set, better), out); + + return isl_set_union(set_worse, set_out); +} + +/* Internal data structure used by isl_pw_*_union_opt_cmp + * that keeps track of a piecewise expression with updated cells. + * "pw" holds the original piecewise expression. + * "list" holds the updated cells. + */ +S(PW,union_opt_cmp_data) { + PW *pw; + isl_set_list *cell; +}; + +/* Free all memory allocated for "data". + */ +static void FN(PW,union_opt_cmp_data_clear)(S(PW,union_opt_cmp_data) *data) +{ + isl_set_list_free(data->cell); + FN(PW,free)(data->pw); +} + +/* Given (potentially) updated cells "i" of data_i->pw and "j" of data_j->pw and + * a set "better" where the piece from data_j->pw is better + * than the piece from data_i->pw, + * (further) update the specified cells such that only the better elements + * remain on the (non-empty) intersection. + * + * Let C be the set "better". + * Let A be the cell data_i->cell[i] and B the cell data_j->cell[j]. + * + * The elements in C need to be removed from A, except for those parts + * that lie outside of B. That is, + * + * A <- (A \setminus C) \cup ((A \cap C) \setminus B') + * + * Conversely, the elements in B need to be restricted to C, except + * for those parts that lie outside of A. That is + * + * B <- (B \cap C) \cup ((B \setminus C) \setminus A') + * + * Since all pairs of pieces are considered, the domains are updated + * several times. A and B refer to these updated domains + * (kept track of in data_i->cell[i] and data_j->cell[j]), while A' and B' refer + * to the original domains of the pieces. It is safe to use these + * original domains because the difference between, say, A' and A is + * the domains of pw2-pieces that have been removed before and + * those domains are disjoint from B. A' is used instead of A + * because the continued updating of A may result in this domain + * getting broken up into more disjuncts. + */ +static isl_stat FN(PW,union_opt_cmp_split)(S(PW,union_opt_cmp_data) *data_i, + int i, S(PW,union_opt_cmp_data) *data_j, int j, + __isl_take isl_set *better) +{ + isl_set *set_i, *set_j; + + set_i = isl_set_list_get_set(data_i->cell, i); + set_j = FN(PW,get_domain_at)(data_j->pw, j); + set_i = FN(PW,worse_or_out)(set_i, isl_set_copy(better), set_j); + data_i->cell = isl_set_list_set_set(data_i->cell, i, set_i); + set_i = FN(PW,get_domain_at)(data_i->pw, i); + set_j = isl_set_list_get_set(data_j->cell, j); + set_j = FN(PW,better_or_out)(set_j, better, set_i); + data_j->cell = isl_set_list_set_set(data_j->cell, j, set_j); + + return isl_stat_ok; +} + +/* Given (potentially) updated cells "i" of data_i->pw and "j" of data_j->pw and + * a function "cmp" that returns the set of elements where + * "el1" is "better" than "el2", + * (further) update the specified cells such that only the "better" elements + * remain on the (non-empty) intersection. + */ +static isl_stat FN(PW,union_opt_cmp_pair)(S(PW,union_opt_cmp_data) *data_i, + int i, S(PW,union_opt_cmp_data) *data_j, int j, + __isl_give isl_set *(*cmp)(__isl_take EL *el1, __isl_take EL *el2)) +{ + isl_set *better; + EL *el_i, *el_j; + + el_i = FN(PW,peek_base_at)(data_i->pw, i); + el_j = FN(PW,peek_base_at)(data_j->pw, j); + better = FN(PW,better)(el_j, el_i, cmp); + return FN(PW,union_opt_cmp_split)(data_i, i, data_j, j, better); +} + +/* Given (potentially) updated cells "i" of data_i->pw and "j" of data_j->pw and + * a function "cmp" that returns the set of elements where + * "el1" is "better" than "el2", + * (further) update the specified cells such that only the "better" elements + * remain on the (non-empty) intersection. + * + * The base computation is performed by isl_pw_*_union_opt_cmp_pair, + * which splits the cells according to the set of elements + * where the piece from data_j->pw is better than the piece from data_i->pw. + * + * In some cases, there may be a subset of the intersection + * where both pieces have the same value and can therefore + * both be considered to be "better" than the other. + * This can result in unnecessary splitting on this subset. + * Avoid some of these cases by checking whether + * data_i->pw is always better than data_j->pw on the intersection. + * In particular, do this for the special case where this intersection + * is equal to the cell "j" and data_i->pw is better on its entire cell. + * + * Similarly, if data_i->pw is never better than data_j->pw, + * then no splitting will occur and there is no need to check + * where data_j->pw is better than data_i->pw. + */ +static isl_stat FN(PW,union_opt_cmp_two)(S(PW,union_opt_cmp_data) *data_i, + int i, S(PW,union_opt_cmp_data) *data_j, int j, + __isl_give isl_set *(*cmp)(__isl_take EL *el1, __isl_take EL *el2)) +{ + isl_bool is_subset, is_empty; + isl_set *better, *set_i, *set_j; + EL *el_i, *el_j; + + set_i = FN(PW,peek_domain_at)(data_i->pw, i); + set_j = FN(PW,peek_domain_at)(data_j->pw, j); + is_subset = isl_set_is_subset(set_j, set_i); + if (is_subset < 0) + return isl_stat_error; + if (!is_subset) + return FN(PW,union_opt_cmp_pair)(data_i, i, data_j, j, cmp); + + el_i = FN(PW,peek_base_at)(data_i->pw, i); + el_j = FN(PW,peek_base_at)(data_j->pw, j); + better = FN(PW,better)(el_i, el_j, cmp); + is_empty = isl_set_is_empty(better); + if (is_empty >= 0 && is_empty) + return FN(PW,union_opt_cmp_split)(data_j, j, data_i, i, better); + is_subset = isl_set_is_subset(set_i, better); + if (is_subset >= 0 && is_subset) + return FN(PW,union_opt_cmp_split)(data_j, j, data_i, i, better); + isl_set_free(better); + if (is_empty < 0 || is_subset < 0) + return isl_stat_error; + + return FN(PW,union_opt_cmp_pair)(data_i, i, data_j, j, cmp); +} + +/* Given two piecewise expressions data1->pw and data2->pw, replace + * their domains + * by the sets in data1->cell and data2->cell and combine the results into + * a single piecewise expression. + * The pieces of data1->pw and data2->pw are assumed to have been sorted + * according to the function value expressions. + * The pieces of the result are also sorted in this way. + * + * Run through the pieces of data1->pw and data2->pw in order until they + * have both been exhausted, picking the piece from data1->pw or data2->pw + * depending on which should come first, together with the corresponding + * domain from data1->cell or data2->cell. In cases where the next pieces + * in both data1->pw and data2->pw have the same function value expression, + * construct only a single piece in the result with as domain + * the union of the domains in data1->cell and data2->cell. + */ +static __isl_give PW *FN(PW,merge)(S(PW,union_opt_cmp_data) *data1, + S(PW,union_opt_cmp_data) *data2) +{ + int i, j; + PW *res; + PW *pw1 = data1->pw; + PW *pw2 = data2->pw; + isl_set_list *list1 = data1->cell; + isl_set_list *list2 = data2->cell; + + if (!pw1 || !pw2) + return NULL; + + res = FN(PW,alloc_size)(isl_space_copy(pw1->dim), pw1->n + pw2->n); + + i = 0; j = 0; + while (i < pw1->n || j < pw2->n) { + int cmp; + isl_set *set; + EL *el; + + if (i < pw1->n && j < pw2->n) + cmp = FN(EL,plain_cmp)(pw1->p[i].FIELD, + pw2->p[j].FIELD); + else + cmp = i < pw1->n ? -1 : 1; + + if (cmp < 0) { + set = isl_set_list_get_set(list1, i); + el = FN(EL,copy)(pw1->p[i].FIELD); + ++i; + } else if (cmp > 0) { + set = isl_set_list_get_set(list2, j); + el = FN(EL,copy)(pw2->p[j].FIELD); + ++j; + } else { + set = isl_set_union(isl_set_list_get_set(list1, i), + isl_set_list_get_set(list2, j)); + el = FN(EL,copy)(pw1->p[i].FIELD); + ++i; + ++j; + } + res = FN(PW,add_piece)(res, set, el); + } + + return res; +} + +/* Given a function "cmp" that returns the set of elements where + * "el1" is "better" than "el2", return a piecewise + * expression defined on the union of the definition domains + * of "pw1" and "pw2" that maps to the "best" of "pw1" and + * "pw2" on each cell. If only one of the two input functions + * is defined on a given cell, then it is considered the best. + * + * Run through all pairs of pieces in "pw1" and "pw2". + * If the domains of these pieces intersect, then the intersection + * needs to be distributed over the two pieces based on "cmp". + * + * After the updated domains have been computed, the result is constructed + * from "pw1", "pw2", data[0].cell and data[1].cell. If there are any pieces + * in "pw1" and "pw2" with the same function value expression, then + * they are combined into a single piece in the result. + * In order to be able to do this efficiently, the pieces of "pw1" and + * "pw2" are first sorted according to their function value expressions. + */ +static __isl_give PW *FN(PW,union_opt_cmp)( + __isl_take PW *pw1, __isl_take PW *pw2, + __isl_give isl_set *(*cmp)(__isl_take EL *el1, __isl_take EL *el2)) +{ + S(PW,union_opt_cmp_data) data[2] = { { pw1, NULL }, { pw2, NULL } }; + int i, j; + isl_size n1, n2; + PW *res = NULL; + isl_ctx *ctx; + + if (!pw1 || !pw2) + goto error; + + ctx = isl_space_get_ctx(pw1->dim); + if (!isl_space_is_equal(pw1->dim, pw2->dim)) + isl_die(ctx, isl_error_invalid, + "arguments should live in the same space", goto error); + + if (FN(PW,is_empty)(pw1)) { + FN(PW,free)(pw1); + return pw2; + } + + if (FN(PW,is_empty)(pw2)) { + FN(PW,free)(pw2); + return pw1; + } + + for (i = 0; i < 2; ++i) { + data[i].pw = FN(PW,sort_unique)(data[i].pw); + data[i].cell = FN(PW,extract_domains)(data[i].pw); + } + + n1 = FN(PW,n_piece)(data[0].pw); + n2 = FN(PW,n_piece)(data[1].pw); + if (n1 < 0 || n2 < 0) + goto error; + for (i = 0; i < n1; ++i) { + for (j = 0; j < n2; ++j) { + isl_bool disjoint; + isl_set *set_i, *set_j; + + set_i = FN(PW,peek_domain_at)(data[0].pw, i); + set_j = FN(PW,peek_domain_at)(data[1].pw, j); + disjoint = isl_set_is_disjoint(set_i, set_j); + if (disjoint < 0) + goto error; + if (disjoint) + continue; + if (FN(PW,union_opt_cmp_two)(&data[0], i, + &data[1], j, cmp) < 0) + goto error; + } + } + + res = FN(PW,merge)(&data[0], &data[1]); + for (i = 0; i < 2; ++i) + FN(PW,union_opt_cmp_data_clear)(&data[i]); + + return res; +error: + for (i = 0; i < 2; ++i) + FN(PW,union_opt_cmp_data_clear)(&data[i]); + return FN(PW,free)(res); +} diff --git a/external/mit/isl/dist/isl_range.c b/external/mit/isl/dist/isl_range.c new file mode 100644 index 000000000000..5bcfcffb7f44 --- /dev/null +++ b/external/mit/isl/dist/isl_range.c @@ -0,0 +1,562 @@ +#include +#include +#include +#include +#include +#include +#include + +struct range_data { + struct isl_bound *bound; + int *signs; + int sign; + int test_monotonicity; + int monotonicity; + int tight; + isl_qpolynomial *poly; + isl_pw_qpolynomial_fold *pwf; + isl_pw_qpolynomial_fold *pwf_tight; +}; + +static isl_stat propagate_on_domain(__isl_take isl_basic_set *bset, + __isl_take isl_qpolynomial *poly, struct range_data *data); + +/* Check whether the polynomial "poly" has sign "sign" over "bset", + * i.e., if sign == 1, check that the lower bound on the polynomial + * is non-negative and if sign == -1, check that the upper bound on + * the polynomial is non-positive. + */ +static isl_bool has_sign(__isl_keep isl_basic_set *bset, + __isl_keep isl_qpolynomial *poly, int sign, int *signs) +{ + struct range_data data_m; + isl_size nparam; + isl_space *space; + isl_val *opt; + isl_bool r; + enum isl_fold type; + + nparam = isl_basic_set_dim(bset, isl_dim_param); + if (nparam < 0) + return isl_bool_error; + + bset = isl_basic_set_copy(bset); + poly = isl_qpolynomial_copy(poly); + + bset = isl_basic_set_move_dims(bset, isl_dim_set, 0, + isl_dim_param, 0, nparam); + poly = isl_qpolynomial_move_dims(poly, isl_dim_in, 0, + isl_dim_param, 0, nparam); + + space = isl_qpolynomial_get_space(poly); + space = isl_space_params(space); + space = isl_space_from_domain(space); + space = isl_space_add_dims(space, isl_dim_out, 1); + + data_m.test_monotonicity = 0; + data_m.signs = signs; + data_m.sign = -sign; + type = data_m.sign < 0 ? isl_fold_min : isl_fold_max; + data_m.pwf = isl_pw_qpolynomial_fold_zero(space, type); + data_m.tight = 0; + data_m.pwf_tight = NULL; + + if (propagate_on_domain(bset, poly, &data_m) < 0) + goto error; + + if (sign > 0) + opt = isl_pw_qpolynomial_fold_min(data_m.pwf); + else + opt = isl_pw_qpolynomial_fold_max(data_m.pwf); + + if (!opt) + r = isl_bool_error; + else if (isl_val_is_nan(opt) || + isl_val_is_infty(opt) || + isl_val_is_neginfty(opt)) + r = isl_bool_false; + else + r = isl_bool_ok(sign * isl_val_sgn(opt) >= 0); + + isl_val_free(opt); + + return r; +error: + isl_pw_qpolynomial_fold_free(data_m.pwf); + return isl_bool_error; +} + +/* Return 1 if poly is monotonically increasing in the last set variable, + * -1 if poly is monotonically decreasing in the last set variable, + * 0 if no conclusion, + * -2 on error. + * + * We simply check the sign of p(x+1)-p(x) + */ +static int monotonicity(__isl_keep isl_basic_set *bset, + __isl_keep isl_qpolynomial *poly, struct range_data *data) +{ + isl_ctx *ctx; + isl_space *space; + isl_qpolynomial *sub = NULL; + isl_qpolynomial *diff = NULL; + int result = 0; + isl_bool s; + isl_size nvar; + + nvar = isl_basic_set_dim(bset, isl_dim_set); + if (nvar < 0) + return -2; + + ctx = isl_qpolynomial_get_ctx(poly); + space = isl_qpolynomial_get_domain_space(poly); + + sub = isl_qpolynomial_var_on_domain(isl_space_copy(space), + isl_dim_set, nvar - 1); + sub = isl_qpolynomial_add(sub, + isl_qpolynomial_rat_cst_on_domain(space, ctx->one, ctx->one)); + + diff = isl_qpolynomial_substitute(isl_qpolynomial_copy(poly), + isl_dim_in, nvar - 1, 1, &sub); + diff = isl_qpolynomial_sub(diff, isl_qpolynomial_copy(poly)); + + s = has_sign(bset, diff, 1, data->signs); + if (s < 0) + goto error; + if (s) + result = 1; + else { + s = has_sign(bset, diff, -1, data->signs); + if (s < 0) + goto error; + if (s) + result = -1; + } + + isl_qpolynomial_free(diff); + isl_qpolynomial_free(sub); + + return result; +error: + isl_qpolynomial_free(diff); + isl_qpolynomial_free(sub); + return -2; +} + +/* Return a positive ("sign" > 0) or negative ("sign" < 0) infinite polynomial + * with domain space "space". + */ +static __isl_give isl_qpolynomial *signed_infty(__isl_take isl_space *space, + int sign) +{ + if (sign > 0) + return isl_qpolynomial_infty_on_domain(space); + else + return isl_qpolynomial_neginfty_on_domain(space); +} + +static __isl_give isl_qpolynomial *bound2poly(__isl_take isl_constraint *bound, + __isl_take isl_space *space, unsigned pos, int sign) +{ + if (!bound) + return signed_infty(space, sign); + isl_space_free(space); + return isl_qpolynomial_from_constraint(bound, isl_dim_set, pos); +} + +static int bound_is_integer(__isl_keep isl_constraint *bound, unsigned pos) +{ + isl_int c; + int is_int; + + if (!bound) + return 1; + + isl_int_init(c); + isl_constraint_get_coefficient(bound, isl_dim_set, pos, &c); + is_int = isl_int_is_one(c) || isl_int_is_negone(c); + isl_int_clear(c); + + return is_int; +} + +struct isl_fixed_sign_data { + int *signs; + int sign; + isl_qpolynomial *poly; +}; + +/* Add term "term" to data->poly if it has sign data->sign. + * The sign is determined based on the signs of the parameters + * and variables in data->signs. The integer divisions, if + * any, are assumed to be non-negative. + */ +static isl_stat collect_fixed_sign_terms(__isl_take isl_term *term, void *user) +{ + struct isl_fixed_sign_data *data = (struct isl_fixed_sign_data *)user; + isl_int n; + int i; + int sign; + isl_size nparam; + isl_size nvar; + isl_size exp; + + nparam = isl_term_dim(term, isl_dim_param); + nvar = isl_term_dim(term, isl_dim_set); + if (nparam < 0 || nvar < 0) + return isl_stat_error; + + isl_int_init(n); + isl_term_get_num(term, &n); + sign = isl_int_sgn(n); + isl_int_clear(n); + + for (i = 0; i < nparam; ++i) { + if (data->signs[i] > 0) + continue; + exp = isl_term_get_exp(term, isl_dim_param, i); + if (exp < 0) + return isl_stat_error; + if (exp % 2) + sign = -sign; + } + for (i = 0; i < nvar; ++i) { + if (data->signs[nparam + i] > 0) + continue; + exp = isl_term_get_exp(term, isl_dim_set, i); + if (exp < 0) + return isl_stat_error; + if (exp % 2) + sign = -sign; + } + + if (sign == data->sign) { + isl_qpolynomial *t = isl_qpolynomial_from_term(term); + + data->poly = isl_qpolynomial_add(data->poly, t); + } else + isl_term_free(term); + + return isl_stat_ok; +} + +/* Construct and return a polynomial that consists of the terms + * in "poly" that have sign "sign". The integer divisions, if + * any, are assumed to be non-negative. + */ +__isl_give isl_qpolynomial *isl_qpolynomial_terms_of_sign( + __isl_keep isl_qpolynomial *poly, int *signs, int sign) +{ + isl_space *space; + struct isl_fixed_sign_data data = { signs, sign }; + + space = isl_qpolynomial_get_domain_space(poly); + data.poly = isl_qpolynomial_zero_on_domain(space); + + if (isl_qpolynomial_foreach_term(poly, collect_fixed_sign_terms, &data) < 0) + goto error; + + return data.poly; +error: + isl_qpolynomial_free(data.poly); + return NULL; +} + +/* Helper function to add a guarded polynomial to either pwf_tight or pwf, + * depending on whether the result has been determined to be tight. + */ +static isl_stat add_guarded_poly(__isl_take isl_basic_set *bset, + __isl_take isl_qpolynomial *poly, struct range_data *data) +{ + enum isl_fold type = data->sign < 0 ? isl_fold_min : isl_fold_max; + isl_set *set; + isl_qpolynomial_fold *fold; + isl_pw_qpolynomial_fold *pwf; + + bset = isl_basic_set_params(bset); + poly = isl_qpolynomial_project_domain_on_params(poly); + + fold = isl_qpolynomial_fold_alloc(type, poly); + set = isl_set_from_basic_set(bset); + pwf = isl_pw_qpolynomial_fold_alloc(type, set, fold); + if (data->tight) + data->pwf_tight = isl_pw_qpolynomial_fold_fold( + data->pwf_tight, pwf); + else + data->pwf = isl_pw_qpolynomial_fold_fold(data->pwf, pwf); + + return isl_stat_ok; +} + +/* Plug in "sub" for the variable at position "pos" in "poly". + * + * If "sub" is an infinite polynomial and if the variable actually + * appears in "poly", then calling isl_qpolynomial_substitute + * to perform the substitution may result in a NaN result. + * In such cases, return positive or negative infinity instead, + * depending on whether an upper bound or a lower bound is being computed, + * and mark the result as not being tight. + */ +static __isl_give isl_qpolynomial *plug_in_at_pos( + __isl_take isl_qpolynomial *poly, int pos, + __isl_take isl_qpolynomial *sub, struct range_data *data) +{ + isl_bool involves, infty; + + involves = isl_qpolynomial_involves_dims(poly, isl_dim_in, pos, 1); + if (involves < 0) + goto error; + if (!involves) { + isl_qpolynomial_free(sub); + return poly; + } + + infty = isl_qpolynomial_is_infty(sub); + if (infty >= 0 && !infty) + infty = isl_qpolynomial_is_neginfty(sub); + if (infty < 0) + goto error; + if (infty) { + isl_space *space = isl_qpolynomial_get_domain_space(poly); + data->tight = 0; + isl_qpolynomial_free(poly); + isl_qpolynomial_free(sub); + return signed_infty(space, data->sign); + } + + poly = isl_qpolynomial_substitute(poly, isl_dim_in, pos, 1, &sub); + isl_qpolynomial_free(sub); + + return poly; +error: + isl_qpolynomial_free(poly); + isl_qpolynomial_free(sub); + return NULL; +} + +/* Given a lower and upper bound on the final variable and constraints + * on the remaining variables where these bounds are active, + * eliminate the variable from data->poly based on these bounds. + * If the polynomial has been determined to be monotonic + * in the variable, then simply plug in the appropriate bound. + * If the current polynomial is tight and if this bound is integer, + * then the result is still tight. In all other cases, the results + * may not be tight. + * Otherwise, plug in the largest bound (in absolute value) in + * the positive terms (if an upper bound is wanted) or the negative terms + * (if a lower bounded is wanted) and the other bound in the other terms. + * + * If all variables have been eliminated, then record the result. + * Ohterwise, recurse on the next variable. + */ +static isl_stat propagate_on_bound_pair(__isl_take isl_constraint *lower, + __isl_take isl_constraint *upper, __isl_take isl_basic_set *bset, + void *user) +{ + struct range_data *data = (struct range_data *)user; + int save_tight = data->tight; + isl_qpolynomial *poly; + isl_stat r; + isl_size nvar, nparam; + + nvar = isl_basic_set_dim(bset, isl_dim_set); + nparam = isl_basic_set_dim(bset, isl_dim_param); + if (nvar < 0 || nparam < 0) + goto error; + + if (data->monotonicity) { + isl_qpolynomial *sub; + isl_space *space = isl_qpolynomial_get_domain_space(data->poly); + if (data->monotonicity * data->sign > 0) { + if (data->tight) + data->tight = bound_is_integer(upper, nvar); + sub = bound2poly(upper, space, nvar, 1); + isl_constraint_free(lower); + } else { + if (data->tight) + data->tight = bound_is_integer(lower, nvar); + sub = bound2poly(lower, space, nvar, -1); + isl_constraint_free(upper); + } + poly = isl_qpolynomial_copy(data->poly); + poly = plug_in_at_pos(poly, nvar, sub, data); + poly = isl_qpolynomial_drop_dims(poly, isl_dim_in, nvar, 1); + } else { + isl_qpolynomial *l, *u; + isl_qpolynomial *pos, *neg; + isl_space *space = isl_qpolynomial_get_domain_space(data->poly); + int sign = data->sign * data->signs[nparam + nvar]; + + data->tight = 0; + + u = bound2poly(upper, isl_space_copy(space), nvar, 1); + l = bound2poly(lower, space, nvar, -1); + + pos = isl_qpolynomial_terms_of_sign(data->poly, data->signs, sign); + neg = isl_qpolynomial_terms_of_sign(data->poly, data->signs, -sign); + + pos = plug_in_at_pos(pos, nvar, u, data); + neg = plug_in_at_pos(neg, nvar, l, data); + + poly = isl_qpolynomial_add(pos, neg); + poly = isl_qpolynomial_drop_dims(poly, isl_dim_in, nvar, 1); + } + + if (nvar == 0) + r = add_guarded_poly(bset, poly, data); + else + r = propagate_on_domain(bset, poly, data); + + data->tight = save_tight; + + return r; +error: + isl_constraint_free(lower); + isl_constraint_free(upper); + isl_basic_set_free(bset); + return isl_stat_error; +} + +/* Recursively perform range propagation on the polynomial "poly" + * defined over the basic set "bset" and collect the results in "data". + */ +static isl_stat propagate_on_domain(__isl_take isl_basic_set *bset, + __isl_take isl_qpolynomial *poly, struct range_data *data) +{ + isl_bool is_cst; + isl_ctx *ctx; + isl_qpolynomial *save_poly = data->poly; + int save_monotonicity = data->monotonicity; + isl_size d; + + d = isl_basic_set_dim(bset, isl_dim_set); + is_cst = isl_qpolynomial_is_cst(poly, NULL, NULL); + if (d < 0 || is_cst < 0) + goto error; + + ctx = isl_basic_set_get_ctx(bset); + isl_assert(ctx, d >= 1, goto error); + + if (is_cst) { + bset = isl_basic_set_project_out(bset, isl_dim_set, 0, d); + poly = isl_qpolynomial_drop_dims(poly, isl_dim_in, 0, d); + return add_guarded_poly(bset, poly, data); + } + + if (data->test_monotonicity) + data->monotonicity = monotonicity(bset, poly, data); + else + data->monotonicity = 0; + if (data->monotonicity < -1) + goto error; + + data->poly = poly; + if (isl_basic_set_foreach_bound_pair(bset, isl_dim_set, d - 1, + &propagate_on_bound_pair, data) < 0) + goto error; + + isl_basic_set_free(bset); + isl_qpolynomial_free(poly); + data->monotonicity = save_monotonicity; + data->poly = save_poly; + + return isl_stat_ok; +error: + isl_basic_set_free(bset); + isl_qpolynomial_free(poly); + data->monotonicity = save_monotonicity; + data->poly = save_poly; + return isl_stat_error; +} + +static isl_stat basic_guarded_poly_bound(__isl_take isl_basic_set *bset, + void *user) +{ + struct range_data *data = (struct range_data *)user; + isl_ctx *ctx; + isl_size nparam = isl_basic_set_dim(bset, isl_dim_param); + isl_size dim = isl_basic_set_dim(bset, isl_dim_set); + isl_size total = isl_basic_set_dim(bset, isl_dim_all); + isl_stat r; + + data->signs = NULL; + + if (nparam < 0 || dim < 0 || total < 0) + goto error; + + ctx = isl_basic_set_get_ctx(bset); + data->signs = isl_alloc_array(ctx, int, total); + + if (isl_basic_set_dims_get_sign(bset, isl_dim_set, 0, dim, + data->signs + nparam) < 0) + goto error; + if (isl_basic_set_dims_get_sign(bset, isl_dim_param, 0, nparam, + data->signs) < 0) + goto error; + + r = propagate_on_domain(bset, isl_qpolynomial_copy(data->poly), data); + + free(data->signs); + + return r; +error: + free(data->signs); + isl_basic_set_free(bset); + return isl_stat_error; +} + +static isl_stat qpolynomial_bound_on_domain_range( + __isl_take isl_basic_set *bset, __isl_take isl_qpolynomial *poly, + struct range_data *data) +{ + isl_size nparam = isl_basic_set_dim(bset, isl_dim_param); + isl_size nvar = isl_basic_set_dim(bset, isl_dim_set); + isl_set *set = NULL; + + if (nparam < 0 || nvar < 0) + goto error; + + if (nvar == 0) + return add_guarded_poly(bset, poly, data); + + set = isl_set_from_basic_set(bset); + set = isl_set_split_dims(set, isl_dim_param, 0, nparam); + set = isl_set_split_dims(set, isl_dim_set, 0, nvar); + + data->poly = poly; + + data->test_monotonicity = 1; + if (isl_set_foreach_basic_set(set, &basic_guarded_poly_bound, data) < 0) + goto error; + + isl_set_free(set); + isl_qpolynomial_free(poly); + + return isl_stat_ok; +error: + isl_set_free(set); + isl_qpolynomial_free(poly); + return isl_stat_error; +} + +isl_stat isl_qpolynomial_bound_on_domain_range(__isl_take isl_basic_set *bset, + __isl_take isl_qpolynomial *poly, struct isl_bound *bound) +{ + struct range_data data; + isl_stat r; + + data.pwf = bound->pwf; + data.pwf_tight = bound->pwf_tight; + data.tight = bound->check_tight; + if (bound->type == isl_fold_min) + data.sign = -1; + else + data.sign = 1; + + r = qpolynomial_bound_on_domain_range(bset, poly, &data); + + bound->pwf = data.pwf; + bound->pwf_tight = data.pwf_tight; + + return r; +} diff --git a/external/mit/isl/dist/isl_range.h b/external/mit/isl/dist/isl_range.h new file mode 100644 index 000000000000..6a5dd4a42e36 --- /dev/null +++ b/external/mit/isl/dist/isl_range.h @@ -0,0 +1,6 @@ +#include + +isl_stat isl_qpolynomial_bound_on_domain_range(__isl_take isl_basic_set *bset, + __isl_take isl_qpolynomial *poly, struct isl_bound *bound); +__isl_give isl_qpolynomial *isl_qpolynomial_terms_of_sign( + __isl_keep isl_qpolynomial *poly, int *signs, int sign); diff --git a/external/mit/isl/dist/isl_read_from_str_templ.c b/external/mit/isl/dist/isl_read_from_str_templ.c new file mode 100644 index 000000000000..51fa8ed12810 --- /dev/null +++ b/external/mit/isl/dist/isl_read_from_str_templ.c @@ -0,0 +1,27 @@ +/* + * Copyright 2008 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 + */ + +#define xCAT(A,B) A ## B +#define CAT(A,B) xCAT(A,B) +#undef TYPE +#define TYPE CAT(isl_,TYPE_BASE) + +/* Read an object of type TYPE from "str" (using an isl_stream). + */ +__isl_give TYPE *FN(isl,FN(TYPE_BASE,read_from_str))(isl_ctx *ctx, + const char *str) +{ + TYPE *obj; + isl_stream *s = isl_stream_new_str(ctx, str); + if (!s) + return NULL; + obj = FN(isl_stream_read,TYPE_BASE)(s); + isl_stream_free(s); + return obj; +} diff --git a/external/mit/isl/dist/isl_reordering.c b/external/mit/isl/dist/isl_reordering.c new file mode 100644 index 000000000000..bfbdd9e0c6c1 --- /dev/null +++ b/external/mit/isl/dist/isl_reordering.c @@ -0,0 +1,353 @@ +/* + * Copyright 2010 INRIA Saclay + * + * 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 + */ + +#include +#include +#include +#include + +/* Create a new reordering description based on + * the number of source dimensions "src_len" and + * (an initial value for) the number of target dimensions "dst_len". + * + * The caller still needs to fill in the space field and + * possibly adjust the target dimensionality if this is not known yet + * when this function is called. + */ +__isl_give isl_reordering *isl_reordering_alloc(isl_ctx *ctx, int src_len, + int dst_len) +{ + isl_reordering *exp; + + exp = isl_alloc(ctx, struct isl_reordering, + sizeof(struct isl_reordering) + (src_len - 1) * sizeof(int)); + if (!exp) + return NULL; + + exp->ref = 1; + exp->src_len = src_len; + exp->dst_len = dst_len; + exp->space = NULL; + + return exp; +} + +/* Set r->dst_len to the total dimensionality of r->space. + */ +static __isl_give isl_reordering *isl_reordering_set_dst_len_from_space( + __isl_take isl_reordering *r) +{ + isl_size n; + + if (!r) + return NULL; + + n = isl_space_dim(r->space, isl_dim_all); + if (n < 0) + return isl_reordering_free(r); + r->dst_len = n; + return r; +} + +__isl_give isl_reordering *isl_reordering_copy(__isl_keep isl_reordering *exp) +{ + if (!exp) + return NULL; + + exp->ref++; + return exp; +} + +__isl_give isl_reordering *isl_reordering_dup(__isl_keep isl_reordering *r) +{ + int i; + isl_reordering *dup; + + if (!r) + return NULL; + + dup = isl_reordering_alloc(isl_reordering_get_ctx(r), + r->src_len, r->dst_len); + if (!dup) + return NULL; + + dup->space = isl_reordering_get_space(r); + if (!dup->space) + return isl_reordering_free(dup); + for (i = 0; i < dup->src_len; ++i) + dup->pos[i] = r->pos[i]; + + return dup; +} + +__isl_give isl_reordering *isl_reordering_cow(__isl_take isl_reordering *r) +{ + if (!r) + return NULL; + + if (r->ref == 1) + return r; + r->ref--; + return isl_reordering_dup(r); +} + +__isl_null isl_reordering *isl_reordering_free(__isl_take isl_reordering *exp) +{ + if (!exp) + return NULL; + + if (--exp->ref > 0) + return NULL; + + isl_space_free(exp->space); + free(exp); + return NULL; +} + +/* Return the isl_ctx to which "r" belongs. + */ +isl_ctx *isl_reordering_get_ctx(__isl_keep isl_reordering *r) +{ + return isl_space_get_ctx(isl_reordering_peek_space(r)); +} + +/* Return the space of "r". + */ +__isl_keep isl_space *isl_reordering_peek_space(__isl_keep isl_reordering *r) +{ + if (!r) + return NULL; + return r->space; +} + +/* Return a copy of the space of "r". + */ +__isl_give isl_space *isl_reordering_get_space(__isl_keep isl_reordering *r) +{ + return isl_space_copy(isl_reordering_peek_space(r)); +} + +/* Construct a reordering that maps the parameters of "alignee" + * to the corresponding parameters in a new dimension specification + * that has the parameters of "aligner" first, followed by + * any remaining parameters of "alignee" that do not occur in "aligner". + * The other dimensions of "alignee" are mapped to subsequent positions + * in order. + */ +__isl_give isl_reordering *isl_parameter_alignment_reordering( + __isl_keep isl_space *alignee, __isl_keep isl_space *aligner) +{ + int i, j, offset; + isl_ctx *ctx; + isl_reordering *exp; + isl_size dim, n_alignee, n_aligner; + + dim = isl_space_dim(alignee, isl_dim_all); + n_alignee = isl_space_dim(alignee, isl_dim_param); + n_aligner = isl_space_dim(aligner, isl_dim_param); + if (dim < 0 || n_alignee < 0 || n_aligner < 0) + return NULL; + + ctx = isl_space_get_ctx(alignee); + exp = isl_reordering_alloc(ctx, dim, dim); + if (!exp) + return NULL; + + exp->space = isl_space_replace_params(isl_space_copy(alignee), aligner); + + for (i = 0; i < n_alignee; ++i) { + isl_id *id_i; + id_i = isl_space_get_dim_id(alignee, isl_dim_param, i); + if (!id_i) + isl_die(ctx, isl_error_invalid, + "cannot align unnamed parameters", goto error); + for (j = 0; j < n_aligner; ++j) { + isl_id *id_j; + id_j = isl_space_get_dim_id(aligner, isl_dim_param, j); + isl_id_free(id_j); + if (id_i == id_j) + break; + } + if (j < n_aligner) { + exp->pos[i] = j; + isl_id_free(id_i); + } else { + isl_size pos; + pos = isl_space_dim(exp->space, isl_dim_param); + if (pos < 0) + exp->space = isl_space_free(exp->space); + exp->space = isl_space_add_dims(exp->space, + isl_dim_param, 1); + exp->space = isl_space_set_dim_id(exp->space, + isl_dim_param, pos, id_i); + exp->pos[i] = pos; + } + } + + exp = isl_reordering_set_dst_len_from_space(exp); + if (!exp) + return NULL; + + offset = exp->dst_len - exp->src_len; + for (i = n_alignee; i < dim; ++i) + exp->pos[i] = offset + i; + + return exp; +error: + isl_reordering_free(exp); + return NULL; +} + +/* Return a reordering that moves the parameters identified by + * the elements of "tuple" to a domain tuple inserted into "space". + * The parameters that remain, are moved from their original positions + * in the list of parameters to their new positions in this list. + * The parameters that get removed, are moved to the corresponding + * positions in the new domain. Note that these set dimensions + * do not necessarily need to appear as parameters in "space". + * Any other dimensions are shifted by the number of extra dimensions + * introduced, i.e., the number of dimensions in the new domain + * that did not appear as parameters in "space". + */ +__isl_give isl_reordering *isl_reordering_unbind_params_insert_domain( + __isl_keep isl_space *space, __isl_keep isl_multi_id *tuple) +{ + int i, n; + int offset, first; + isl_size dim; + isl_ctx *ctx; + isl_reordering *r; + + dim = isl_space_dim(space, isl_dim_all); + if (dim < 0 || !tuple) + return NULL; + + ctx = isl_space_get_ctx(space); + r = isl_reordering_alloc(ctx, dim, dim); + if (!r) + return NULL; + + r->space = isl_space_copy(space); + r->space = isl_space_unbind_params_insert_domain(r->space, tuple); + if (!r->space) + return isl_reordering_free(r); + + n = isl_space_dim(r->space, isl_dim_param); + for (i = 0; i < n; ++i) { + int pos; + isl_id *id; + + id = isl_space_get_dim_id(r->space, isl_dim_param, i); + if (!id) + return isl_reordering_free(r); + pos = isl_space_find_dim_by_id(space, isl_dim_param, id); + isl_id_free(id); + r->pos[pos] = i; + } + + offset = isl_space_dim(r->space, isl_dim_param); + n = isl_multi_id_size(tuple); + for (i = 0; i < n; ++i) { + int pos; + isl_id *id; + + id = isl_multi_id_get_id(tuple, i); + if (!id) + return isl_reordering_free(r); + pos = isl_space_find_dim_by_id(space, isl_dim_param, id); + isl_id_free(id); + if (pos < 0) + continue; + r->pos[pos] = offset + i; + } + + offset = isl_space_dim(r->space, isl_dim_all) - dim; + first = isl_space_dim(space, isl_dim_param); + n = dim - first; + for (i = 0; i < n; ++i) + r->pos[first + i] = first + offset + i; + + return isl_reordering_set_dst_len_from_space(r); +} + +__isl_give isl_reordering *isl_reordering_extend(__isl_take isl_reordering *exp, + unsigned extra) +{ + int i; + isl_ctx *ctx; + isl_reordering *res; + int offset; + + if (!exp) + return NULL; + if (extra == 0) + return exp; + + ctx = isl_reordering_get_ctx(exp); + offset = exp->dst_len - exp->src_len; + res = isl_reordering_alloc(ctx, exp->src_len + extra, + exp->dst_len + extra); + if (!res) + goto error; + res->space = isl_reordering_get_space(exp); + for (i = 0; i < exp->src_len; ++i) + res->pos[i] = exp->pos[i]; + for (i = exp->src_len; i < res->src_len; ++i) + res->pos[i] = offset + i; + + isl_reordering_free(exp); + + return res; +error: + isl_reordering_free(exp); + return NULL; +} + +__isl_give isl_reordering *isl_reordering_extend_space( + __isl_take isl_reordering *exp, __isl_take isl_space *space) +{ + isl_space *exp_space; + isl_reordering *res; + isl_size dim; + + dim = isl_space_dim(space, isl_dim_all); + if (!exp || dim < 0) + goto error; + + res = isl_reordering_extend(isl_reordering_copy(exp), + dim - exp->src_len); + res = isl_reordering_cow(res); + if (!res) + goto error; + isl_space_free(res->space); + exp_space = isl_reordering_peek_space(exp); + res->space = isl_space_replace_params(space, exp_space); + + isl_reordering_free(exp); + + if (!res->space) + return isl_reordering_free(res); + + return res; +error: + isl_reordering_free(exp); + isl_space_free(space); + return NULL; +} + +void isl_reordering_dump(__isl_keep isl_reordering *exp) +{ + int i; + + isl_space_dump(exp->space); + for (i = 0; i < exp->src_len; ++i) + fprintf(stderr, "%d -> %d; ", i, exp->pos[i]); + fprintf(stderr, "\n"); +} diff --git a/external/mit/isl/dist/isl_reordering.h b/external/mit/isl/dist/isl_reordering.h new file mode 100644 index 000000000000..be56cf863057 --- /dev/null +++ b/external/mit/isl/dist/isl_reordering.h @@ -0,0 +1,37 @@ +#ifndef ISL_REORDERING_H +#define ISL_REORDERING_H + +#include + +/* "pos" has "src_len" entries and maps original dimensions to new dimensions. + * The final space is given by "space". + * The number of dimensions (i.e., the range of values) in the result + * may be larger than the number of dimensions in the input. + * In particular, the possible values of the entries in "pos" ranges from 0 to + * to "dst_len" - 1, where "dst_len" is equal to the total dimension of "space", + * unless isl_reordering_extend has been called. + */ +struct isl_reordering { + int ref; + isl_space *space; + unsigned src_len; + unsigned dst_len; + int pos[1]; +}; +typedef struct isl_reordering isl_reordering; + +isl_ctx *isl_reordering_get_ctx(__isl_keep isl_reordering *r); +__isl_keep isl_space *isl_reordering_peek_space(__isl_keep isl_reordering *r); +__isl_give isl_space *isl_reordering_get_space(__isl_keep isl_reordering *r); +__isl_give isl_reordering *isl_parameter_alignment_reordering( + __isl_keep isl_space *alignee, __isl_keep isl_space *aligner); +__isl_give isl_reordering *isl_reordering_unbind_params_insert_domain( + __isl_keep isl_space *space, __isl_keep isl_multi_id *tuple); +__isl_give isl_reordering *isl_reordering_copy(__isl_keep isl_reordering *exp); +__isl_null isl_reordering *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 *space); +__isl_give isl_reordering *isl_reordering_extend(__isl_take isl_reordering *exp, + unsigned extra); + +#endif diff --git a/external/mit/isl/dist/isl_sample.c b/external/mit/isl/dist/isl_sample.c new file mode 100644 index 000000000000..2e26190bf293 --- /dev/null +++ b/external/mit/isl/dist/isl_sample.c @@ -0,0 +1,1336 @@ +/* + * 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 + */ + +#include +#include +#include "isl_sample.h" +#include +#include +#include +#include "isl_equalities.h" +#include "isl_tab.h" +#include "isl_basis_reduction.h" +#include +#include +#include +#include + +#include +#include + +static __isl_give isl_vec *isl_basic_set_sample_bounded( + __isl_take isl_basic_set *bset); + +static __isl_give isl_vec *empty_sample(__isl_take isl_basic_set *bset) +{ + struct isl_vec *vec; + + vec = isl_vec_alloc(bset->ctx, 0); + isl_basic_set_free(bset); + return vec; +} + +/* Construct a zero sample of the same dimension as bset. + * As a special case, if bset is zero-dimensional, this + * function creates a zero-dimensional sample point. + */ +static __isl_give isl_vec *zero_sample(__isl_take isl_basic_set *bset) +{ + isl_size dim; + struct isl_vec *sample; + + dim = isl_basic_set_dim(bset, isl_dim_all); + if (dim < 0) + goto error; + sample = isl_vec_alloc(bset->ctx, 1 + dim); + if (sample) { + isl_int_set_si(sample->el[0], 1); + isl_seq_clr(sample->el + 1, dim); + } + isl_basic_set_free(bset); + return sample; +error: + isl_basic_set_free(bset); + return NULL; +} + +static __isl_give isl_vec *interval_sample(__isl_take isl_basic_set *bset) +{ + int i; + isl_int t; + struct isl_vec *sample; + + bset = isl_basic_set_simplify(bset); + if (!bset) + return NULL; + if (isl_basic_set_plain_is_empty(bset)) + return empty_sample(bset); + if (bset->n_eq == 0 && bset->n_ineq == 0) + return zero_sample(bset); + + sample = isl_vec_alloc(bset->ctx, 2); + if (!sample) + goto error; + if (!bset) + return NULL; + isl_int_set_si(sample->block.data[0], 1); + + if (bset->n_eq > 0) { + isl_assert(bset->ctx, bset->n_eq == 1, goto error); + isl_assert(bset->ctx, bset->n_ineq == 0, goto error); + if (isl_int_is_one(bset->eq[0][1])) + isl_int_neg(sample->el[1], bset->eq[0][0]); + else { + isl_assert(bset->ctx, isl_int_is_negone(bset->eq[0][1]), + goto error); + isl_int_set(sample->el[1], bset->eq[0][0]); + } + isl_basic_set_free(bset); + return sample; + } + + isl_int_init(t); + if (isl_int_is_one(bset->ineq[0][1])) + isl_int_neg(sample->block.data[1], bset->ineq[0][0]); + else + isl_int_set(sample->block.data[1], bset->ineq[0][0]); + for (i = 1; i < bset->n_ineq; ++i) { + isl_seq_inner_product(sample->block.data, + bset->ineq[i], 2, &t); + if (isl_int_is_neg(t)) + break; + } + isl_int_clear(t); + if (i < bset->n_ineq) { + isl_vec_free(sample); + return empty_sample(bset); + } + + isl_basic_set_free(bset); + return sample; +error: + isl_basic_set_free(bset); + isl_vec_free(sample); + return NULL; +} + +/* Find a sample integer point, if any, in bset, which is known + * to have equalities. If bset contains no integer points, then + * return a zero-length vector. + * We simply remove the known equalities, compute a sample + * in the resulting bset, using the specified recurse function, + * and then transform the sample back to the original space. + */ +static __isl_give isl_vec *sample_eq(__isl_take isl_basic_set *bset, + __isl_give isl_vec *(*recurse)(__isl_take isl_basic_set *)) +{ + struct isl_mat *T; + struct isl_vec *sample; + + if (!bset) + return NULL; + + bset = isl_basic_set_remove_equalities(bset, &T, NULL); + sample = recurse(bset); + if (!sample || sample->size == 0) + isl_mat_free(T); + else + sample = isl_mat_vec_product(T, sample); + return sample; +} + +/* Return a matrix containing the equalities of the tableau + * in constraint form. The tableau is assumed to have + * an associated bset that has been kept up-to-date. + */ +static struct isl_mat *tab_equalities(struct isl_tab *tab) +{ + int i, j; + int n_eq; + struct isl_mat *eq; + struct isl_basic_set *bset; + + if (!tab) + return NULL; + + bset = isl_tab_peek_bset(tab); + isl_assert(tab->mat->ctx, bset, return NULL); + + n_eq = tab->n_var - tab->n_col + tab->n_dead; + if (tab->empty || n_eq == 0) + return isl_mat_alloc(tab->mat->ctx, 0, tab->n_var); + if (n_eq == tab->n_var) + return isl_mat_identity(tab->mat->ctx, tab->n_var); + + eq = isl_mat_alloc(tab->mat->ctx, n_eq, tab->n_var); + if (!eq) + return NULL; + for (i = 0, j = 0; i < tab->n_con; ++i) { + if (tab->con[i].is_row) + continue; + if (tab->con[i].index >= 0 && tab->con[i].index >= tab->n_dead) + continue; + if (i < bset->n_eq) + isl_seq_cpy(eq->row[j], bset->eq[i] + 1, tab->n_var); + else + isl_seq_cpy(eq->row[j], + bset->ineq[i - bset->n_eq] + 1, tab->n_var); + ++j; + } + isl_assert(bset->ctx, j == n_eq, goto error); + return eq; +error: + isl_mat_free(eq); + return NULL; +} + +/* Compute and return an initial basis for the bounded tableau "tab". + * + * If the tableau is either full-dimensional or zero-dimensional, + * the we simply return an identity matrix. + * Otherwise, we construct a basis whose first directions correspond + * to equalities. + */ +static struct isl_mat *initial_basis(struct isl_tab *tab) +{ + int n_eq; + struct isl_mat *eq; + struct isl_mat *Q; + + tab->n_unbounded = 0; + tab->n_zero = n_eq = tab->n_var - tab->n_col + tab->n_dead; + if (tab->empty || n_eq == 0 || n_eq == tab->n_var) + return isl_mat_identity(tab->mat->ctx, 1 + tab->n_var); + + eq = tab_equalities(tab); + eq = isl_mat_left_hermite(eq, 0, NULL, &Q); + if (!eq) + return NULL; + isl_mat_free(eq); + + Q = isl_mat_lin_to_aff(Q); + return Q; +} + +/* Compute the minimum of the current ("level") basis row over "tab" + * and store the result in position "level" of "min". + * + * This function assumes that at least one more row and at least + * one more element in the constraint array are available in the tableau. + */ +static enum isl_lp_result compute_min(isl_ctx *ctx, struct isl_tab *tab, + __isl_keep isl_vec *min, int level) +{ + return isl_tab_min(tab, tab->basis->row[1 + level], + ctx->one, &min->el[level], NULL, 0); +} + +/* Compute the maximum of the current ("level") basis row over "tab" + * and store the result in position "level" of "max". + * + * This function assumes that at least one more row and at least + * one more element in the constraint array are available in the tableau. + */ +static enum isl_lp_result compute_max(isl_ctx *ctx, struct isl_tab *tab, + __isl_keep isl_vec *max, int level) +{ + enum isl_lp_result res; + unsigned dim = tab->n_var; + + isl_seq_neg(tab->basis->row[1 + level] + 1, + tab->basis->row[1 + level] + 1, dim); + res = isl_tab_min(tab, tab->basis->row[1 + level], + ctx->one, &max->el[level], NULL, 0); + isl_seq_neg(tab->basis->row[1 + level] + 1, + tab->basis->row[1 + level] + 1, dim); + isl_int_neg(max->el[level], max->el[level]); + + return res; +} + +/* Perform a greedy search for an integer point in the set represented + * by "tab", given that the minimal rational value (rounded up to the + * nearest integer) at "level" is smaller than the maximal rational + * value (rounded down to the nearest integer). + * + * Return 1 if we have found an integer point (if tab->n_unbounded > 0 + * then we may have only found integer values for the bounded dimensions + * and it is the responsibility of the caller to extend this solution + * to the unbounded dimensions). + * Return 0 if greedy search did not result in a solution. + * Return -1 if some error occurred. + * + * We assign a value half-way between the minimum and the maximum + * to the current dimension and check if the minimal value of the + * next dimension is still smaller than (or equal) to the maximal value. + * We continue this process until either + * - the minimal value (rounded up) is greater than the maximal value + * (rounded down). In this case, greedy search has failed. + * - we have exhausted all bounded dimensions, meaning that we have + * found a solution. + * - the sample value of the tableau is integral. + * - some error has occurred. + */ +static int greedy_search(isl_ctx *ctx, struct isl_tab *tab, + __isl_keep isl_vec *min, __isl_keep isl_vec *max, int level) +{ + struct isl_tab_undo *snap; + enum isl_lp_result res; + + snap = isl_tab_snap(tab); + + do { + isl_int_add(tab->basis->row[1 + level][0], + min->el[level], max->el[level]); + isl_int_fdiv_q_ui(tab->basis->row[1 + level][0], + tab->basis->row[1 + level][0], 2); + isl_int_neg(tab->basis->row[1 + level][0], + tab->basis->row[1 + level][0]); + if (isl_tab_add_valid_eq(tab, tab->basis->row[1 + level]) < 0) + return -1; + isl_int_set_si(tab->basis->row[1 + level][0], 0); + + if (++level >= tab->n_var - tab->n_unbounded) + return 1; + if (isl_tab_sample_is_integer(tab)) + return 1; + + res = compute_min(ctx, tab, min, level); + if (res == isl_lp_error) + return -1; + if (res != isl_lp_ok) + isl_die(ctx, isl_error_internal, + "expecting bounded rational solution", + return -1); + res = compute_max(ctx, tab, max, level); + if (res == isl_lp_error) + return -1; + if (res != isl_lp_ok) + isl_die(ctx, isl_error_internal, + "expecting bounded rational solution", + return -1); + } while (isl_int_le(min->el[level], max->el[level])); + + if (isl_tab_rollback(tab, snap) < 0) + return -1; + + return 0; +} + +/* Given a tableau representing a set, find and return + * an integer point in the set, if there is any. + * + * We perform a depth first search + * for an integer point, by scanning all possible values in the range + * attained by a basis vector, where an initial basis may have been set + * by the calling function. Otherwise an initial basis that exploits + * the equalities in the tableau is created. + * tab->n_zero is currently ignored and is clobbered by this function. + * + * The tableau is allowed to have unbounded direction, but then + * the calling function needs to set an initial basis, with the + * unbounded directions last and with tab->n_unbounded set + * to the number of unbounded directions. + * Furthermore, the calling functions needs to add shifted copies + * of all constraints involving unbounded directions to ensure + * that any feasible rational value in these directions can be rounded + * up to yield a feasible integer value. + * In particular, let B define the given basis x' = B x + * and let T be the inverse of B, i.e., X = T x'. + * Let a x + c >= 0 be a constraint of the set represented by the tableau, + * or a T x' + c >= 0 in terms of the given basis. Assume that + * the bounded directions have an integer value, then we can safely + * round up the values for the unbounded directions if we make sure + * that x' not only satisfies the original constraint, but also + * the constraint "a T x' + c + s >= 0" with s the sum of all + * negative values in the last n_unbounded entries of "a T". + * The calling function therefore needs to add the constraint + * a x + c + s >= 0. The current function then scans the first + * directions for an integer value and once those have been found, + * it can compute "T ceil(B x)" to yield an integer point in the set. + * Note that during the search, the first rows of B may be changed + * by a basis reduction, but the last n_unbounded rows of B remain + * unaltered and are also not mixed into the first rows. + * + * The search is implemented iteratively. "level" identifies the current + * basis vector. "init" is true if we want the first value at the current + * level and false if we want the next value. + * + * At the start of each level, we first check if we can find a solution + * using greedy search. If not, we continue with the exhaustive search. + * + * The initial basis is the identity matrix. If the range in some direction + * contains more than one integer value, we perform basis reduction based + * on the value of ctx->opt->gbr + * - ISL_GBR_NEVER: never perform basis reduction + * - ISL_GBR_ONCE: only perform basis reduction the first + * time such a range is encountered + * - ISL_GBR_ALWAYS: always perform basis reduction when + * such a range is encountered + * + * When ctx->opt->gbr is set to ISL_GBR_ALWAYS, then we allow the basis + * reduction computation to return early. That is, as soon as it + * finds a reasonable first direction. + */ +__isl_give isl_vec *isl_tab_sample(struct isl_tab *tab) +{ + unsigned dim; + unsigned gbr; + struct isl_ctx *ctx; + struct isl_vec *sample; + struct isl_vec *min; + struct isl_vec *max; + enum isl_lp_result res; + int level; + int init; + int reduced; + struct isl_tab_undo **snap; + + if (!tab) + return NULL; + if (tab->empty) + return isl_vec_alloc(tab->mat->ctx, 0); + + if (!tab->basis) + tab->basis = initial_basis(tab); + if (!tab->basis) + return NULL; + isl_assert(tab->mat->ctx, tab->basis->n_row == tab->n_var + 1, + return NULL); + isl_assert(tab->mat->ctx, tab->basis->n_col == tab->n_var + 1, + return NULL); + + ctx = tab->mat->ctx; + dim = tab->n_var; + gbr = ctx->opt->gbr; + + if (tab->n_unbounded == tab->n_var) { + sample = isl_tab_get_sample_value(tab); + sample = isl_mat_vec_product(isl_mat_copy(tab->basis), sample); + sample = isl_vec_ceil(sample); + sample = isl_mat_vec_inverse_product(isl_mat_copy(tab->basis), + sample); + return sample; + } + + if (isl_tab_extend_cons(tab, dim + 1) < 0) + return NULL; + + min = isl_vec_alloc(ctx, dim); + max = isl_vec_alloc(ctx, dim); + snap = isl_alloc_array(ctx, struct isl_tab_undo *, dim); + + if (!min || !max || !snap) + goto error; + + level = 0; + init = 1; + reduced = 0; + + while (level >= 0) { + if (init) { + int choice; + + res = compute_min(ctx, tab, min, level); + if (res == isl_lp_error) + goto error; + if (res != isl_lp_ok) + isl_die(ctx, isl_error_internal, + "expecting bounded rational solution", + goto error); + if (isl_tab_sample_is_integer(tab)) + break; + res = compute_max(ctx, tab, max, level); + if (res == isl_lp_error) + goto error; + if (res != isl_lp_ok) + isl_die(ctx, isl_error_internal, + "expecting bounded rational solution", + goto error); + if (isl_tab_sample_is_integer(tab)) + break; + choice = isl_int_lt(min->el[level], max->el[level]); + if (choice) { + int g; + g = greedy_search(ctx, tab, min, max, level); + if (g < 0) + goto error; + if (g) + break; + } + if (!reduced && choice && + ctx->opt->gbr != ISL_GBR_NEVER) { + unsigned gbr_only_first; + if (ctx->opt->gbr == ISL_GBR_ONCE) + ctx->opt->gbr = ISL_GBR_NEVER; + tab->n_zero = level; + gbr_only_first = ctx->opt->gbr_only_first; + ctx->opt->gbr_only_first = + ctx->opt->gbr == ISL_GBR_ALWAYS; + tab = isl_tab_compute_reduced_basis(tab); + ctx->opt->gbr_only_first = gbr_only_first; + if (!tab || !tab->basis) + goto error; + reduced = 1; + continue; + } + reduced = 0; + snap[level] = isl_tab_snap(tab); + } else + isl_int_add_ui(min->el[level], min->el[level], 1); + + if (isl_int_gt(min->el[level], max->el[level])) { + level--; + init = 0; + if (level >= 0) + if (isl_tab_rollback(tab, snap[level]) < 0) + goto error; + continue; + } + isl_int_neg(tab->basis->row[1 + level][0], min->el[level]); + if (isl_tab_add_valid_eq(tab, tab->basis->row[1 + level]) < 0) + goto error; + isl_int_set_si(tab->basis->row[1 + level][0], 0); + if (level + tab->n_unbounded < dim - 1) { + ++level; + init = 1; + continue; + } + break; + } + + if (level >= 0) { + sample = isl_tab_get_sample_value(tab); + if (!sample) + goto error; + if (tab->n_unbounded && !isl_int_is_one(sample->el[0])) { + sample = isl_mat_vec_product(isl_mat_copy(tab->basis), + sample); + sample = isl_vec_ceil(sample); + sample = isl_mat_vec_inverse_product( + isl_mat_copy(tab->basis), sample); + } + } else + sample = isl_vec_alloc(ctx, 0); + + ctx->opt->gbr = gbr; + isl_vec_free(min); + isl_vec_free(max); + free(snap); + return sample; +error: + ctx->opt->gbr = gbr; + isl_vec_free(min); + isl_vec_free(max); + free(snap); + return NULL; +} + +static __isl_give isl_vec *sample_bounded(__isl_take isl_basic_set *bset); + +/* Internal data for factored_sample. + * "sample" collects the sample and may get reset to a zero-length vector + * signaling the absence of a sample vector. + * "pos" is the position of the contribution of the next factor. + */ +struct isl_factored_sample_data { + isl_vec *sample; + int pos; +}; + +/* isl_factorizer_every_factor_basic_set callback that extends + * the sample in data->sample with the contribution + * of the factor "bset". + * If "bset" turns out to be empty, then the product is empty too and + * no further factors need to be considered. + */ +static isl_bool factor_sample(__isl_keep isl_basic_set *bset, void *user) +{ + struct isl_factored_sample_data *data = user; + isl_vec *sample; + isl_size n; + + n = isl_basic_set_dim(bset, isl_dim_set); + if (n < 0) + return isl_bool_error; + + sample = sample_bounded(isl_basic_set_copy(bset)); + if (!sample) + return isl_bool_error; + if (sample->size == 0) { + isl_vec_free(data->sample); + data->sample = sample; + return isl_bool_false; + } + isl_seq_cpy(data->sample->el + data->pos, sample->el + 1, n); + isl_vec_free(sample); + data->pos += n; + + return isl_bool_true; +} + +/* Compute a sample point of the given basic set, based on the given, + * non-trivial factorization. + */ +static __isl_give isl_vec *factored_sample(__isl_take isl_basic_set *bset, + __isl_take isl_factorizer *f) +{ + struct isl_factored_sample_data data = { NULL }; + isl_ctx *ctx; + isl_size total; + isl_bool every; + + ctx = isl_basic_set_get_ctx(bset); + total = isl_basic_set_dim(bset, isl_dim_all); + if (!ctx || total < 0) + goto error; + + data.sample = isl_vec_alloc(ctx, 1 + total); + if (!data.sample) + goto error; + isl_int_set_si(data.sample->el[0], 1); + data.pos = 1; + + every = isl_factorizer_every_factor_basic_set(f, &factor_sample, &data); + if (every < 0) { + data.sample = isl_vec_free(data.sample); + } else if (every) { + isl_morph *morph; + + morph = isl_morph_inverse(isl_morph_copy(f->morph)); + data.sample = isl_morph_vec(morph, data.sample); + } + + isl_basic_set_free(bset); + isl_factorizer_free(f); + return data.sample; +error: + isl_basic_set_free(bset); + isl_factorizer_free(f); + isl_vec_free(data.sample); + return NULL; +} + +/* Given a basic set that is known to be bounded, find and return + * an integer point in the basic set, if there is any. + * + * After handling some trivial cases, we construct a tableau + * and then use isl_tab_sample to find a sample, passing it + * the identity matrix as initial basis. + */ +static __isl_give isl_vec *sample_bounded(__isl_take isl_basic_set *bset) +{ + isl_size dim; + struct isl_vec *sample; + struct isl_tab *tab = NULL; + isl_factorizer *f; + + if (!bset) + return NULL; + + if (isl_basic_set_plain_is_empty(bset)) + return empty_sample(bset); + + dim = isl_basic_set_dim(bset, isl_dim_all); + if (dim < 0) + bset = isl_basic_set_free(bset); + if (dim == 0) + return zero_sample(bset); + if (dim == 1) + return interval_sample(bset); + if (bset->n_eq > 0) + return sample_eq(bset, sample_bounded); + + f = isl_basic_set_factorizer(bset); + if (!f) + goto error; + if (f->n_group != 0) + return factored_sample(bset, f); + isl_factorizer_free(f); + + tab = isl_tab_from_basic_set(bset, 1); + if (tab && tab->empty) { + isl_tab_free(tab); + ISL_F_SET(bset, ISL_BASIC_SET_EMPTY); + sample = isl_vec_alloc(isl_basic_set_get_ctx(bset), 0); + isl_basic_set_free(bset); + return sample; + } + + if (!ISL_F_ISSET(bset, ISL_BASIC_SET_NO_IMPLICIT)) + if (isl_tab_detect_implicit_equalities(tab) < 0) + goto error; + + sample = isl_tab_sample(tab); + if (!sample) + goto error; + + if (sample->size > 0) { + isl_vec_free(bset->sample); + bset->sample = isl_vec_copy(sample); + } + + isl_basic_set_free(bset); + isl_tab_free(tab); + return sample; +error: + isl_basic_set_free(bset); + isl_tab_free(tab); + return NULL; +} + +/* Given a basic set "bset" and a value "sample" for the first coordinates + * of bset, plug in these values and drop the corresponding coordinates. + * + * We do this by computing the preimage of the transformation + * + * [ 1 0 ] + * x = [ s 0 ] x' + * [ 0 I ] + * + * where [1 s] is the sample value and I is the identity matrix of the + * appropriate dimension. + */ +static __isl_give isl_basic_set *plug_in(__isl_take isl_basic_set *bset, + __isl_take isl_vec *sample) +{ + int i; + isl_size total; + struct isl_mat *T; + + total = isl_basic_set_dim(bset, isl_dim_all); + if (total < 0 || !sample) + goto error; + + T = isl_mat_alloc(bset->ctx, 1 + total, 1 + total - (sample->size - 1)); + if (!T) + goto error; + + for (i = 0; i < sample->size; ++i) { + isl_int_set(T->row[i][0], sample->el[i]); + isl_seq_clr(T->row[i] + 1, T->n_col - 1); + } + for (i = 0; i < T->n_col - 1; ++i) { + isl_seq_clr(T->row[sample->size + i], T->n_col); + isl_int_set_si(T->row[sample->size + i][1 + i], 1); + } + isl_vec_free(sample); + + bset = isl_basic_set_preimage(bset, T); + return bset; +error: + isl_basic_set_free(bset); + isl_vec_free(sample); + return NULL; +} + +/* Given a basic set "bset", return any (possibly non-integer) point + * in the basic set. + */ +static __isl_give isl_vec *rational_sample(__isl_take isl_basic_set *bset) +{ + struct isl_tab *tab; + struct isl_vec *sample; + + if (!bset) + return NULL; + + tab = isl_tab_from_basic_set(bset, 0); + sample = isl_tab_get_sample_value(tab); + isl_tab_free(tab); + + isl_basic_set_free(bset); + + return sample; +} + +/* Given a linear cone "cone" and a rational point "vec", + * construct a polyhedron with shifted copies of the constraints in "cone", + * i.e., a polyhedron with "cone" as its recession cone, such that each + * point x in this polyhedron is such that the unit box positioned at x + * lies entirely inside the affine cone 'vec + cone'. + * Any rational point in this polyhedron may therefore be rounded up + * to yield an integer point that lies inside said affine cone. + * + * Denote the constraints of cone by " >= 0" and the rational + * point "vec" by v/d. + * Let b_i = . Then the affine cone 'vec + cone' is given + * by - b/d >= 0. + * The polyhedron - ceil{b/d} >= 0 is a subset of this affine cone. + * We prefer this polyhedron over the actual affine cone because it doesn't + * require a scaling of the constraints. + * If each of the vertices of the unit cube positioned at x lies inside + * this polyhedron, then the whole unit cube at x lies inside the affine cone. + * We therefore impose that x' = x + \sum e_i, for any selection of unit + * vectors lies inside the polyhedron, i.e., + * + * - ceil{b/d} = + sum a_i - ceil{b/d} >= 0 + * + * The most stringent of these constraints is the one that selects + * all negative a_i, so the polyhedron we are looking for has constraints + * + * + sum_{a_i < 0} a_i - ceil{b/d} >= 0 + * + * Note that if cone were known to have only non-negative rays + * (which can be accomplished by a unimodular transformation), + * then we would only have to check the points x' = x + e_i + * and we only have to add the smallest negative a_i (if any) + * instead of the sum of all negative a_i. + */ +static __isl_give isl_basic_set *shift_cone(__isl_take isl_basic_set *cone, + __isl_take isl_vec *vec) +{ + int i, j, k; + isl_size total; + + struct isl_basic_set *shift = NULL; + + total = isl_basic_set_dim(cone, isl_dim_all); + if (total < 0 || !vec) + goto error; + + isl_assert(cone->ctx, cone->n_eq == 0, goto error); + + shift = isl_basic_set_alloc_space(isl_basic_set_get_space(cone), + 0, 0, cone->n_ineq); + + for (i = 0; i < cone->n_ineq; ++i) { + k = isl_basic_set_alloc_inequality(shift); + if (k < 0) + goto error; + isl_seq_cpy(shift->ineq[k] + 1, cone->ineq[i] + 1, total); + isl_seq_inner_product(shift->ineq[k] + 1, vec->el + 1, total, + &shift->ineq[k][0]); + isl_int_cdiv_q(shift->ineq[k][0], + shift->ineq[k][0], vec->el[0]); + isl_int_neg(shift->ineq[k][0], shift->ineq[k][0]); + for (j = 0; j < total; ++j) { + if (isl_int_is_nonneg(shift->ineq[k][1 + j])) + continue; + isl_int_add(shift->ineq[k][0], + shift->ineq[k][0], shift->ineq[k][1 + j]); + } + } + + isl_basic_set_free(cone); + isl_vec_free(vec); + + return isl_basic_set_finalize(shift); +error: + isl_basic_set_free(shift); + isl_basic_set_free(cone); + isl_vec_free(vec); + return NULL; +} + +/* Given a rational point vec in a (transformed) basic set, + * such that cone is the recession cone of the original basic set, + * "round up" the rational point to an integer point. + * + * We first check if the rational point just happens to be integer. + * If not, we transform the cone in the same way as the basic set, + * pick a point x in this cone shifted to the rational point such that + * the whole unit cube at x is also inside this affine cone. + * Then we simply round up the coordinates of x and return the + * resulting integer point. + */ +static __isl_give isl_vec *round_up_in_cone(__isl_take isl_vec *vec, + __isl_take isl_basic_set *cone, __isl_take isl_mat *U) +{ + isl_size total; + + if (!vec || !cone || !U) + goto error; + + isl_assert(vec->ctx, vec->size != 0, goto error); + if (isl_int_is_one(vec->el[0])) { + isl_mat_free(U); + isl_basic_set_free(cone); + return vec; + } + + total = isl_basic_set_dim(cone, isl_dim_all); + if (total < 0) + goto error; + cone = isl_basic_set_preimage(cone, U); + cone = isl_basic_set_remove_dims(cone, isl_dim_set, + 0, total - (vec->size - 1)); + + cone = shift_cone(cone, vec); + + vec = rational_sample(cone); + vec = isl_vec_ceil(vec); + return vec; +error: + isl_mat_free(U); + isl_vec_free(vec); + isl_basic_set_free(cone); + return NULL; +} + +/* Concatenate two integer vectors, i.e., two vectors with denominator + * (stored in element 0) equal to 1. + */ +static __isl_give isl_vec *vec_concat(__isl_take isl_vec *vec1, + __isl_take isl_vec *vec2) +{ + struct isl_vec *vec; + + if (!vec1 || !vec2) + goto error; + isl_assert(vec1->ctx, vec1->size > 0, goto error); + isl_assert(vec2->ctx, vec2->size > 0, goto error); + isl_assert(vec1->ctx, isl_int_is_one(vec1->el[0]), goto error); + isl_assert(vec2->ctx, isl_int_is_one(vec2->el[0]), goto error); + + vec = isl_vec_alloc(vec1->ctx, vec1->size + vec2->size - 1); + if (!vec) + goto error; + + isl_seq_cpy(vec->el, vec1->el, vec1->size); + isl_seq_cpy(vec->el + vec1->size, vec2->el + 1, vec2->size - 1); + + isl_vec_free(vec1); + isl_vec_free(vec2); + + return vec; +error: + isl_vec_free(vec1); + isl_vec_free(vec2); + return NULL; +} + +/* Give a basic set "bset" with recession cone "cone", compute and + * return an integer point in bset, if any. + * + * If the recession cone is full-dimensional, then we know that + * bset contains an infinite number of integer points and it is + * fairly easy to pick one of them. + * If the recession cone is not full-dimensional, then we first + * transform bset such that the bounded directions appear as + * the first dimensions of the transformed basic set. + * We do this by using a unimodular transformation that transforms + * the equalities in the recession cone to equalities on the first + * dimensions. + * + * The transformed set is then projected onto its bounded dimensions. + * Note that to compute this projection, we can simply drop all constraints + * involving any of the unbounded dimensions since these constraints + * cannot be combined to produce a constraint on the bounded dimensions. + * To see this, assume that there is such a combination of constraints + * that produces a constraint on the bounded dimensions. This means + * that some combination of the unbounded dimensions has both an upper + * bound and a lower bound in terms of the bounded dimensions, but then + * this combination would be a bounded direction too and would have been + * transformed into a bounded dimensions. + * + * We then compute a sample value in the bounded dimensions. + * If no such value can be found, then the original set did not contain + * any integer points and we are done. + * Otherwise, we plug in the value we found in the bounded dimensions, + * project out these bounded dimensions and end up with a set with + * a full-dimensional recession cone. + * A sample point in this set is computed by "rounding up" any + * rational point in the set. + * + * The sample points in the bounded and unbounded dimensions are + * then combined into a single sample point and transformed back + * to the original space. + */ +__isl_give isl_vec *isl_basic_set_sample_with_cone( + __isl_take isl_basic_set *bset, __isl_take isl_basic_set *cone) +{ + isl_size total; + unsigned cone_dim; + struct isl_mat *M, *U; + struct isl_vec *sample; + struct isl_vec *cone_sample; + struct isl_ctx *ctx; + struct isl_basic_set *bounded; + + total = isl_basic_set_dim(cone, isl_dim_all); + if (!bset || total < 0) + goto error; + + ctx = isl_basic_set_get_ctx(bset); + cone_dim = total - cone->n_eq; + + M = isl_mat_sub_alloc6(ctx, cone->eq, 0, cone->n_eq, 1, total); + M = isl_mat_left_hermite(M, 0, &U, NULL); + if (!M) + goto error; + isl_mat_free(M); + + U = isl_mat_lin_to_aff(U); + bset = isl_basic_set_preimage(bset, isl_mat_copy(U)); + + bounded = isl_basic_set_copy(bset); + bounded = isl_basic_set_drop_constraints_involving(bounded, + total - cone_dim, cone_dim); + bounded = isl_basic_set_drop_dims(bounded, total - cone_dim, cone_dim); + sample = sample_bounded(bounded); + if (!sample || sample->size == 0) { + isl_basic_set_free(bset); + isl_basic_set_free(cone); + isl_mat_free(U); + return sample; + } + bset = plug_in(bset, isl_vec_copy(sample)); + cone_sample = rational_sample(bset); + cone_sample = round_up_in_cone(cone_sample, cone, isl_mat_copy(U)); + sample = vec_concat(sample, cone_sample); + sample = isl_mat_vec_product(U, sample); + return sample; +error: + isl_basic_set_free(cone); + isl_basic_set_free(bset); + return NULL; +} + +static void vec_sum_of_neg(__isl_keep isl_vec *v, isl_int *s) +{ + int i; + + isl_int_set_si(*s, 0); + + for (i = 0; i < v->size; ++i) + if (isl_int_is_neg(v->el[i])) + isl_int_add(*s, *s, v->el[i]); +} + +/* Given a tableau "tab", a tableau "tab_cone" that corresponds + * to the recession cone and the inverse of a new basis U = inv(B), + * with the unbounded directions in B last, + * add constraints to "tab" that ensure any rational value + * in the unbounded directions can be rounded up to an integer value. + * + * The new basis is given by x' = B x, i.e., x = U x'. + * For any rational value of the last tab->n_unbounded coordinates + * in the update tableau, the value that is obtained by rounding + * up this value should be contained in the original tableau. + * For any constraint "a x + c >= 0", we therefore need to add + * a constraint "a x + c + s >= 0", with s the sum of all negative + * entries in the last elements of "a U". + * + * Since we are not interested in the first entries of any of the "a U", + * we first drop the columns of U that correpond to bounded directions. + */ +static int tab_shift_cone(struct isl_tab *tab, + struct isl_tab *tab_cone, struct isl_mat *U) +{ + int i; + isl_int v; + struct isl_basic_set *bset = NULL; + + if (tab && tab->n_unbounded == 0) { + isl_mat_free(U); + return 0; + } + isl_int_init(v); + if (!tab || !tab_cone || !U) + goto error; + bset = isl_tab_peek_bset(tab_cone); + U = isl_mat_drop_cols(U, 0, tab->n_var - tab->n_unbounded); + for (i = 0; i < bset->n_ineq; ++i) { + int ok; + struct isl_vec *row = NULL; + if (isl_tab_is_equality(tab_cone, tab_cone->n_eq + i)) + continue; + row = isl_vec_alloc(bset->ctx, tab_cone->n_var); + if (!row) + goto error; + isl_seq_cpy(row->el, bset->ineq[i] + 1, tab_cone->n_var); + row = isl_vec_mat_product(row, isl_mat_copy(U)); + if (!row) + goto error; + vec_sum_of_neg(row, &v); + isl_vec_free(row); + if (isl_int_is_zero(v)) + continue; + if (isl_tab_extend_cons(tab, 1) < 0) + goto error; + isl_int_add(bset->ineq[i][0], bset->ineq[i][0], v); + ok = isl_tab_add_ineq(tab, bset->ineq[i]) >= 0; + isl_int_sub(bset->ineq[i][0], bset->ineq[i][0], v); + if (!ok) + goto error; + } + + isl_mat_free(U); + isl_int_clear(v); + return 0; +error: + isl_mat_free(U); + isl_int_clear(v); + return -1; +} + +/* Compute and return an initial basis for the possibly + * unbounded tableau "tab". "tab_cone" is a tableau + * for the corresponding recession cone. + * Additionally, add constraints to "tab" that ensure + * that any rational value for the unbounded directions + * can be rounded up to an integer value. + * + * If the tableau is bounded, i.e., if the recession cone + * is zero-dimensional, then we just use inital_basis. + * Otherwise, we construct a basis whose first directions + * correspond to equalities, followed by bounded directions, + * i.e., equalities in the recession cone. + * The remaining directions are then unbounded. + */ +int isl_tab_set_initial_basis_with_cone(struct isl_tab *tab, + struct isl_tab *tab_cone) +{ + struct isl_mat *eq; + struct isl_mat *cone_eq; + struct isl_mat *U, *Q; + + if (!tab || !tab_cone) + return -1; + + if (tab_cone->n_col == tab_cone->n_dead) { + tab->basis = initial_basis(tab); + return tab->basis ? 0 : -1; + } + + eq = tab_equalities(tab); + if (!eq) + return -1; + tab->n_zero = eq->n_row; + cone_eq = tab_equalities(tab_cone); + eq = isl_mat_concat(eq, cone_eq); + if (!eq) + return -1; + tab->n_unbounded = tab->n_var - (eq->n_row - tab->n_zero); + eq = isl_mat_left_hermite(eq, 0, &U, &Q); + if (!eq) + return -1; + isl_mat_free(eq); + tab->basis = isl_mat_lin_to_aff(Q); + if (tab_shift_cone(tab, tab_cone, U) < 0) + return -1; + if (!tab->basis) + return -1; + return 0; +} + +/* Compute and return a sample point in bset using generalized basis + * reduction. We first check if the input set has a non-trivial + * recession cone. If so, we perform some extra preprocessing in + * sample_with_cone. Otherwise, we directly perform generalized basis + * reduction. + */ +static __isl_give isl_vec *gbr_sample(__isl_take isl_basic_set *bset) +{ + isl_size dim; + struct isl_basic_set *cone; + + dim = isl_basic_set_dim(bset, isl_dim_all); + if (dim < 0) + goto error; + + cone = isl_basic_set_recession_cone(isl_basic_set_copy(bset)); + if (!cone) + goto error; + + if (cone->n_eq < dim) + return isl_basic_set_sample_with_cone(bset, cone); + + isl_basic_set_free(cone); + return sample_bounded(bset); +error: + isl_basic_set_free(bset); + return NULL; +} + +static __isl_give isl_vec *basic_set_sample(__isl_take isl_basic_set *bset, + int bounded) +{ + isl_size dim; + if (!bset) + return NULL; + + if (isl_basic_set_plain_is_empty(bset)) + return empty_sample(bset); + + dim = isl_basic_set_dim(bset, isl_dim_set); + if (dim < 0 || + isl_basic_set_check_no_params(bset) < 0 || + isl_basic_set_check_no_locals(bset) < 0) + goto error; + + if (bset->sample && bset->sample->size == 1 + dim) { + int contains = isl_basic_set_contains(bset, bset->sample); + if (contains < 0) + goto error; + if (contains) { + struct isl_vec *sample = isl_vec_copy(bset->sample); + isl_basic_set_free(bset); + return sample; + } + } + isl_vec_free(bset->sample); + bset->sample = NULL; + + if (bset->n_eq > 0) + return sample_eq(bset, bounded ? isl_basic_set_sample_bounded + : isl_basic_set_sample_vec); + if (dim == 0) + return zero_sample(bset); + if (dim == 1) + return interval_sample(bset); + + return bounded ? sample_bounded(bset) : gbr_sample(bset); +error: + isl_basic_set_free(bset); + return NULL; +} + +__isl_give isl_vec *isl_basic_set_sample_vec(__isl_take isl_basic_set *bset) +{ + return basic_set_sample(bset, 0); +} + +/* Compute an integer sample in "bset", where the caller guarantees + * that "bset" is bounded. + */ +__isl_give isl_vec *isl_basic_set_sample_bounded(__isl_take isl_basic_set *bset) +{ + return basic_set_sample(bset, 1); +} + +__isl_give isl_basic_set *isl_basic_set_from_vec(__isl_take isl_vec *vec) +{ + int i; + int k; + struct isl_basic_set *bset = NULL; + struct isl_ctx *ctx; + isl_size dim; + + if (!vec) + return NULL; + ctx = vec->ctx; + isl_assert(ctx, vec->size != 0, goto error); + + bset = isl_basic_set_alloc(ctx, 0, vec->size - 1, 0, vec->size - 1, 0); + dim = isl_basic_set_dim(bset, isl_dim_set); + if (dim < 0) + goto error; + for (i = dim - 1; i >= 0; --i) { + k = isl_basic_set_alloc_equality(bset); + if (k < 0) + goto error; + isl_seq_clr(bset->eq[k], 1 + dim); + isl_int_neg(bset->eq[k][0], vec->el[1 + i]); + isl_int_set(bset->eq[k][1 + i], vec->el[0]); + } + bset->sample = vec; + + return bset; +error: + isl_basic_set_free(bset); + isl_vec_free(vec); + return NULL; +} + +__isl_give isl_basic_map *isl_basic_map_sample(__isl_take isl_basic_map *bmap) +{ + struct isl_basic_set *bset; + struct isl_vec *sample_vec; + + bset = isl_basic_map_underlying_set(isl_basic_map_copy(bmap)); + sample_vec = isl_basic_set_sample_vec(bset); + if (!sample_vec) + goto error; + if (sample_vec->size == 0) { + isl_vec_free(sample_vec); + return isl_basic_map_set_to_empty(bmap); + } + isl_vec_free(bmap->sample); + bmap->sample = isl_vec_copy(sample_vec); + bset = isl_basic_set_from_vec(sample_vec); + return isl_basic_map_overlying_set(bset, bmap); +error: + isl_basic_map_free(bmap); + return NULL; +} + +__isl_give isl_basic_set *isl_basic_set_sample(__isl_take isl_basic_set *bset) +{ + return isl_basic_map_sample(bset); +} + +__isl_give isl_basic_map *isl_map_sample(__isl_take isl_map *map) +{ + int i; + isl_basic_map *sample = NULL; + + if (!map) + goto error; + + for (i = 0; i < map->n; ++i) { + sample = isl_basic_map_sample(isl_basic_map_copy(map->p[i])); + if (!sample) + goto error; + if (!ISL_F_ISSET(sample, ISL_BASIC_MAP_EMPTY)) + break; + isl_basic_map_free(sample); + } + if (i == map->n) + sample = isl_basic_map_empty(isl_map_get_space(map)); + isl_map_free(map); + return sample; +error: + isl_map_free(map); + return NULL; +} + +__isl_give isl_basic_set *isl_set_sample(__isl_take isl_set *set) +{ + return bset_from_bmap(isl_map_sample(set_to_map(set))); +} + +__isl_give isl_point *isl_basic_set_sample_point(__isl_take isl_basic_set *bset) +{ + isl_vec *vec; + isl_space *space; + + space = isl_basic_set_get_space(bset); + bset = isl_basic_set_underlying_set(bset); + vec = isl_basic_set_sample_vec(bset); + + return isl_point_alloc(space, vec); +} + +__isl_give isl_point *isl_set_sample_point(__isl_take isl_set *set) +{ + int i; + isl_point *pnt; + + if (!set) + return NULL; + + for (i = 0; i < set->n; ++i) { + pnt = isl_basic_set_sample_point(isl_basic_set_copy(set->p[i])); + if (!pnt) + goto error; + if (!isl_point_is_void(pnt)) + break; + isl_point_free(pnt); + } + if (i == set->n) + pnt = isl_point_void(isl_set_get_space(set)); + + isl_set_free(set); + return pnt; +error: + isl_set_free(set); + return NULL; +} diff --git a/external/mit/isl/dist/isl_sample.h b/external/mit/isl/dist/isl_sample.h new file mode 100644 index 000000000000..6ffdad8a0a93 --- /dev/null +++ b/external/mit/isl/dist/isl_sample.h @@ -0,0 +1,34 @@ +/* + * 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_SAMPLE_H +#define ISL_SAMPLE_H + +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +__isl_give isl_vec *isl_basic_set_sample_vec(__isl_take isl_basic_set *bset); +__isl_give isl_vec *isl_basic_set_sample_with_cone( + __isl_take isl_basic_set *bset, __isl_take isl_basic_set *cone); + +__isl_give isl_basic_set *isl_basic_set_from_vec(__isl_take isl_vec *vec); + +int isl_tab_set_initial_basis_with_cone(struct isl_tab *tab, + struct isl_tab *tab_cone); +__isl_give isl_vec *isl_tab_sample(struct isl_tab *tab); + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/external/mit/isl/dist/isl_scan.c b/external/mit/isl/dist/isl_scan.c new file mode 100644 index 000000000000..c4666ed1b463 --- /dev/null +++ b/external/mit/isl/dist/isl_scan.c @@ -0,0 +1,327 @@ +/* + * 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 + */ + +#include +#include +#include "isl_basis_reduction.h" +#include "isl_scan.h" +#include +#include "isl_tab.h" +#include +#include + +struct isl_counter { + struct isl_scan_callback callback; + isl_int count; + isl_int max; +}; + +static isl_stat increment_counter(struct isl_scan_callback *cb, + __isl_take isl_vec *sample) +{ + struct isl_counter *cnt = (struct isl_counter *)cb; + + isl_int_add_ui(cnt->count, cnt->count, 1); + + isl_vec_free(sample); + + if (isl_int_is_zero(cnt->max) || isl_int_lt(cnt->count, cnt->max)) + return isl_stat_ok; + return isl_stat_error; +} + +static int increment_range(struct isl_scan_callback *cb, isl_int min, isl_int max) +{ + struct isl_counter *cnt = (struct isl_counter *)cb; + + isl_int_add(cnt->count, cnt->count, max); + isl_int_sub(cnt->count, cnt->count, min); + isl_int_add_ui(cnt->count, cnt->count, 1); + + if (isl_int_is_zero(cnt->max) || isl_int_lt(cnt->count, cnt->max)) + return 0; + isl_int_set(cnt->count, cnt->max); + return -1; +} + +/* Call callback->add with the current sample value of the tableau "tab". + */ +static int add_solution(struct isl_tab *tab, struct isl_scan_callback *callback) +{ + struct isl_vec *sample; + + if (!tab) + return -1; + sample = isl_tab_get_sample_value(tab); + if (!sample) + return -1; + + return callback->add(callback, sample); +} + +static isl_stat scan_0D(__isl_take isl_basic_set *bset, + struct isl_scan_callback *callback) +{ + struct isl_vec *sample; + + sample = isl_vec_alloc(bset->ctx, 1); + isl_basic_set_free(bset); + + if (!sample) + return isl_stat_error; + + isl_int_set_si(sample->el[0], 1); + + return callback->add(callback, sample); +} + +/* Look for all integer points in "bset", which is assumed to be bounded, + * and call callback->add on each of them. + * + * We first compute a reduced basis for the set and then scan + * the set in the directions of this basis. + * We basically perform a depth first search, where in each level i + * we compute the range in the i-th basis vector direction, given + * fixed values in the directions of the previous basis vector. + * We then add an equality to the tableau fixing the value in the + * direction of the current basis vector to each value in the range + * in turn and then continue to the next level. + * + * The search is implemented iteratively. "level" identifies the current + * basis vector. "init" is true if we want the first value at the current + * level and false if we want the next value. + * Solutions are added in the leaves of the search tree, i.e., after + * we have fixed a value in each direction of the basis. + */ +isl_stat isl_basic_set_scan(__isl_take isl_basic_set *bset, + struct isl_scan_callback *callback) +{ + isl_size dim; + struct isl_mat *B = NULL; + struct isl_tab *tab = NULL; + struct isl_vec *min; + struct isl_vec *max; + struct isl_tab_undo **snap; + int level; + int init; + enum isl_lp_result res; + + dim = isl_basic_set_dim(bset, isl_dim_all); + if (dim < 0) { + bset = isl_basic_set_free(bset); + return isl_stat_error; + } + + if (dim == 0) + return scan_0D(bset, callback); + + min = isl_vec_alloc(bset->ctx, dim); + max = isl_vec_alloc(bset->ctx, dim); + snap = isl_alloc_array(bset->ctx, struct isl_tab_undo *, dim); + + if (!min || !max || !snap) + goto error; + + tab = isl_tab_from_basic_set(bset, 0); + if (!tab) + goto error; + if (isl_tab_extend_cons(tab, dim + 1) < 0) + goto error; + + tab->basis = isl_mat_identity(bset->ctx, 1 + dim); + if (1) + tab = isl_tab_compute_reduced_basis(tab); + if (!tab) + goto error; + B = isl_mat_copy(tab->basis); + if (!B) + goto error; + + level = 0; + init = 1; + + while (level >= 0) { + int empty = 0; + if (init) { + res = isl_tab_min(tab, B->row[1 + level], + bset->ctx->one, &min->el[level], NULL, 0); + if (res == isl_lp_empty) + empty = 1; + if (res == isl_lp_error || res == isl_lp_unbounded) + goto error; + isl_seq_neg(B->row[1 + level] + 1, + B->row[1 + level] + 1, dim); + res = isl_tab_min(tab, B->row[1 + level], + bset->ctx->one, &max->el[level], NULL, 0); + isl_seq_neg(B->row[1 + level] + 1, + B->row[1 + level] + 1, dim); + isl_int_neg(max->el[level], max->el[level]); + if (res == isl_lp_empty) + empty = 1; + if (res == isl_lp_error || res == isl_lp_unbounded) + goto error; + snap[level] = isl_tab_snap(tab); + } else + isl_int_add_ui(min->el[level], min->el[level], 1); + + if (empty || isl_int_gt(min->el[level], max->el[level])) { + level--; + init = 0; + if (level >= 0) + if (isl_tab_rollback(tab, snap[level]) < 0) + goto error; + continue; + } + if (level == dim - 1 && callback->add == increment_counter) { + if (increment_range(callback, + min->el[level], max->el[level])) + goto error; + level--; + init = 0; + if (level >= 0) + if (isl_tab_rollback(tab, snap[level]) < 0) + goto error; + continue; + } + isl_int_neg(B->row[1 + level][0], min->el[level]); + if (isl_tab_add_valid_eq(tab, B->row[1 + level]) < 0) + goto error; + isl_int_set_si(B->row[1 + level][0], 0); + if (level < dim - 1) { + ++level; + init = 1; + continue; + } + if (add_solution(tab, callback) < 0) + goto error; + init = 0; + if (isl_tab_rollback(tab, snap[level]) < 0) + goto error; + } + + isl_tab_free(tab); + free(snap); + isl_vec_free(min); + isl_vec_free(max); + isl_basic_set_free(bset); + isl_mat_free(B); + return isl_stat_ok; +error: + isl_tab_free(tab); + free(snap); + isl_vec_free(min); + isl_vec_free(max); + isl_basic_set_free(bset); + isl_mat_free(B); + return isl_stat_error; +} + +isl_stat isl_set_scan(__isl_take isl_set *set, + struct isl_scan_callback *callback) +{ + int i; + + if (!set || !callback) + goto error; + + set = isl_set_cow(set); + set = isl_set_make_disjoint(set); + set = isl_set_compute_divs(set); + if (!set) + goto error; + + for (i = 0; i < set->n; ++i) + if (isl_basic_set_scan(isl_basic_set_copy(set->p[i]), + callback) < 0) + goto error; + + isl_set_free(set); + return isl_stat_ok; +error: + isl_set_free(set); + return isl_stat_error; +} + +int isl_basic_set_count_upto(__isl_keep isl_basic_set *bset, + isl_int max, isl_int *count) +{ + struct isl_counter cnt = { { &increment_counter } }; + + if (!bset) + return -1; + + isl_int_init(cnt.count); + isl_int_init(cnt.max); + + isl_int_set_si(cnt.count, 0); + isl_int_set(cnt.max, max); + if (isl_basic_set_scan(isl_basic_set_copy(bset), &cnt.callback) < 0 && + isl_int_lt(cnt.count, cnt.max)) + goto error; + + isl_int_set(*count, cnt.count); + isl_int_clear(cnt.max); + isl_int_clear(cnt.count); + + return 0; +error: + isl_int_clear(cnt.count); + return -1; +} + +int isl_set_count_upto(__isl_keep isl_set *set, isl_int max, isl_int *count) +{ + struct isl_counter cnt = { { &increment_counter } }; + + if (!set) + return -1; + + isl_int_init(cnt.count); + isl_int_init(cnt.max); + + isl_int_set_si(cnt.count, 0); + isl_int_set(cnt.max, max); + if (isl_set_scan(isl_set_copy(set), &cnt.callback) < 0 && + isl_int_lt(cnt.count, cnt.max)) + goto error; + + isl_int_set(*count, cnt.count); + isl_int_clear(cnt.max); + isl_int_clear(cnt.count); + + return 0; +error: + isl_int_clear(cnt.count); + return -1; +} + +int isl_set_count(__isl_keep isl_set *set, isl_int *count) +{ + if (!set) + return -1; + return isl_set_count_upto(set, set->ctx->zero, count); +} + +/* Count the total number of elements in "set" (in an inefficient way) and + * return the result. + */ +__isl_give isl_val *isl_set_count_val(__isl_keep isl_set *set) +{ + isl_val *v; + + if (!set) + return NULL; + v = isl_val_zero(isl_set_get_ctx(set)); + v = isl_val_cow(v); + if (!v) + return NULL; + if (isl_set_count(set, &v->n) < 0) + v = isl_val_free(v); + return v; +} diff --git a/external/mit/isl/dist/isl_scan.h b/external/mit/isl/dist/isl_scan.h new file mode 100644 index 000000000000..f2a5100e4c02 --- /dev/null +++ b/external/mit/isl/dist/isl_scan.h @@ -0,0 +1,26 @@ +/* + * 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_SCAN_H +#define ISL_SCAN_H + +#include +#include + +struct isl_scan_callback { + isl_stat (*add)(struct isl_scan_callback *cb, + __isl_take isl_vec *sample); +}; + +isl_stat isl_basic_set_scan(__isl_take isl_basic_set *bset, + struct isl_scan_callback *callback); +isl_stat isl_set_scan(__isl_take isl_set *set, + struct isl_scan_callback *callback); + +#endif diff --git a/external/mit/isl/dist/isl_schedule.c b/external/mit/isl/dist/isl_schedule.c new file mode 100644 index 000000000000..bdeeaba001bd --- /dev/null +++ b/external/mit/isl/dist/isl_schedule.c @@ -0,0 +1,684 @@ +/* + * Copyright 2011 INRIA Saclay + * Copyright 2012-2014 Ecole Normale Superieure + * Copyright 2016 Sven Verdoolaege + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Return a schedule encapsulating the given schedule tree. + * + * We currently only allow schedule trees with a domain or extension as root. + * + * The leaf field is initialized as a leaf node so that it can be + * used to represent leaves in the constructed schedule. + * The reference count is set to -1 since the isl_schedule_tree + * should never be freed. It is up to the (internal) users of + * these leaves to ensure that they are only used while the schedule + * is still alive. + */ +__isl_give isl_schedule *isl_schedule_from_schedule_tree(isl_ctx *ctx, + __isl_take isl_schedule_tree *tree) +{ + enum isl_schedule_node_type type; + isl_schedule *schedule; + + if (!tree) + return NULL; + type = isl_schedule_tree_get_type(tree); + if (type != isl_schedule_node_domain && + type != isl_schedule_node_extension) + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_unsupported, + "root of schedule tree should be a domain or extension", + goto error); + + schedule = isl_calloc_type(ctx, isl_schedule); + if (!schedule) + goto error; + + schedule->ref = 1; + schedule->root = tree; + schedule->leaf = isl_schedule_tree_leaf(ctx); + + if (!schedule->leaf) + return isl_schedule_free(schedule); + return schedule; +error: + isl_schedule_tree_free(tree); + return NULL; +} + +/* Return a pointer to a schedule with as single node + * a domain node with the given domain. + */ +__isl_give isl_schedule *isl_schedule_from_domain( + __isl_take isl_union_set *domain) +{ + isl_ctx *ctx; + isl_schedule_tree *tree; + + ctx = isl_union_set_get_ctx(domain); + tree = isl_schedule_tree_from_domain(domain); + return isl_schedule_from_schedule_tree(ctx, tree); +} + +/* Return a pointer to a schedule with as single node + * a domain node with an empty domain. + */ +__isl_give isl_schedule *isl_schedule_empty(__isl_take isl_space *space) +{ + return isl_schedule_from_domain(isl_union_set_empty(space)); +} + +/* Return a new reference to "sched". + */ +__isl_give isl_schedule *isl_schedule_copy(__isl_keep isl_schedule *sched) +{ + if (!sched) + return NULL; + + sched->ref++; + return sched; +} + +/* Return an isl_schedule that is equal to "schedule" and that has only + * a single reference. + */ +__isl_give isl_schedule *isl_schedule_cow(__isl_take isl_schedule *schedule) +{ + isl_ctx *ctx; + isl_schedule_tree *tree; + + if (!schedule) + return NULL; + if (schedule->ref == 1) + return schedule; + + ctx = isl_schedule_get_ctx(schedule); + schedule->ref--; + tree = isl_schedule_tree_copy(schedule->root); + return isl_schedule_from_schedule_tree(ctx, tree); +} + +__isl_null isl_schedule *isl_schedule_free(__isl_take isl_schedule *sched) +{ + if (!sched) + return NULL; + + if (--sched->ref > 0) + return NULL; + + isl_schedule_tree_free(sched->root); + isl_schedule_tree_free(sched->leaf); + free(sched); + return NULL; +} + +/* Replace the root of "schedule" by "tree". + */ +__isl_give isl_schedule *isl_schedule_set_root( + __isl_take isl_schedule *schedule, __isl_take isl_schedule_tree *tree) +{ + if (!schedule || !tree) + goto error; + if (schedule->root == tree) { + isl_schedule_tree_free(tree); + return schedule; + } + + schedule = isl_schedule_cow(schedule); + if (!schedule) + goto error; + isl_schedule_tree_free(schedule->root); + schedule->root = tree; + + return schedule; +error: + isl_schedule_free(schedule); + isl_schedule_tree_free(tree); + return NULL; +} + +isl_ctx *isl_schedule_get_ctx(__isl_keep isl_schedule *schedule) +{ + return schedule ? isl_schedule_tree_get_ctx(schedule->leaf) : NULL; +} + +/* Return a pointer to the leaf of "schedule". + */ +__isl_keep isl_schedule_tree *isl_schedule_peek_leaf( + __isl_keep isl_schedule *schedule) +{ + return schedule ? schedule->leaf : NULL; +} + +/* Are "schedule1" and "schedule2" obviously equal to each other? + */ +isl_bool isl_schedule_plain_is_equal(__isl_keep isl_schedule *schedule1, + __isl_keep isl_schedule *schedule2) +{ + if (!schedule1 || !schedule2) + return isl_bool_error; + if (schedule1 == schedule2) + return isl_bool_true; + return isl_schedule_tree_plain_is_equal(schedule1->root, + schedule2->root); +} + +/* Return the (parameter) space of the schedule, i.e., the space + * of the root domain. + */ +__isl_give isl_space *isl_schedule_get_space( + __isl_keep isl_schedule *schedule) +{ + enum isl_schedule_node_type type; + isl_space *space; + isl_union_set *domain; + + if (!schedule) + 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, + "root node not a domain node", return NULL); + + domain = isl_schedule_tree_domain_get_domain(schedule->root); + space = isl_union_set_get_space(domain); + isl_union_set_free(domain); + + return space; +} + +/* Return a pointer to the root of "schedule". + */ +__isl_give isl_schedule_node *isl_schedule_get_root( + __isl_keep isl_schedule *schedule) +{ + isl_ctx *ctx; + isl_schedule_tree *tree; + isl_schedule_tree_list *ancestors; + + if (!schedule) + return NULL; + + ctx = isl_schedule_get_ctx(schedule); + tree = isl_schedule_tree_copy(schedule->root); + schedule = isl_schedule_copy(schedule); + ancestors = isl_schedule_tree_list_alloc(ctx, 0); + return isl_schedule_node_alloc(schedule, tree, ancestors, NULL); +} + +/* Return the domain of the root domain node of "schedule". + */ +__isl_give isl_union_set *isl_schedule_get_domain( + __isl_keep isl_schedule *schedule) +{ + if (!schedule) + return NULL; + return isl_schedule_tree_domain_get_domain(schedule->root); +} + +/* Traverse all nodes of "sched" 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 + * at that node is skipped. + * + * Return 0 on success and -1 on failure. + */ +isl_stat isl_schedule_foreach_schedule_node_top_down( + __isl_keep isl_schedule *sched, + isl_bool (*fn)(__isl_keep isl_schedule_node *node, void *user), + void *user) +{ + isl_schedule_node *node; + isl_stat r; + + if (!sched) + return isl_stat_error; + + node = isl_schedule_get_root(sched); + r = isl_schedule_node_foreach_descendant_top_down(node, fn, user); + isl_schedule_node_free(node); + + return r; +} + +/* Traverse the node of "sched" in depth first postorder, + * allowing the user to modify the visited node. + * The traversal continues from the node returned by the callback function. + * It is the responsibility of the user to ensure that this does not + * lead to an infinite loop. It is safest to always return a pointer + * to the same position (same ancestors and child positions) as the input node. + */ +__isl_give isl_schedule *isl_schedule_map_schedule_node_bottom_up( + __isl_take isl_schedule *schedule, + __isl_give isl_schedule_node *(*fn)( + __isl_take isl_schedule_node *node, void *user), void *user) +{ + isl_schedule_node *node; + + node = isl_schedule_get_root(schedule); + isl_schedule_free(schedule); + + node = isl_schedule_node_map_descendant_bottom_up(node, fn, user); + schedule = isl_schedule_node_get_schedule(node); + isl_schedule_node_free(node); + + return schedule; +} + +/* Wrapper around isl_schedule_node_reset_user for use as + * an isl_schedule_map_schedule_node_bottom_up callback. + */ +static __isl_give isl_schedule_node *reset_user( + __isl_take isl_schedule_node *node, void *user) +{ + return isl_schedule_node_reset_user(node); +} + +/* Reset the user pointer on all identifiers of parameters and tuples + * in the schedule "schedule". + */ +__isl_give isl_schedule *isl_schedule_reset_user( + __isl_take isl_schedule *schedule) +{ + return isl_schedule_map_schedule_node_bottom_up(schedule, &reset_user, + NULL); +} + +/* Wrapper around isl_schedule_node_align_params for use as + * an isl_schedule_map_schedule_node_bottom_up callback. + */ +static __isl_give isl_schedule_node *align_params( + __isl_take isl_schedule_node *node, void *user) +{ + isl_space *space = user; + + return isl_schedule_node_align_params(node, isl_space_copy(space)); +} + +/* Align the parameters of all nodes in schedule "schedule" + * to those of "space". + */ +__isl_give isl_schedule *isl_schedule_align_params( + __isl_take isl_schedule *schedule, __isl_take isl_space *space) +{ + schedule = isl_schedule_map_schedule_node_bottom_up(schedule, + &align_params, space); + isl_space_free(space); + return schedule; +} + +/* Wrapper around isl_schedule_node_pullback_union_pw_multi_aff for use as + * an isl_schedule_map_schedule_node_bottom_up callback. + */ +static __isl_give isl_schedule_node *pullback_upma( + __isl_take isl_schedule_node *node, void *user) +{ + isl_union_pw_multi_aff *upma = user; + + return isl_schedule_node_pullback_union_pw_multi_aff(node, + isl_union_pw_multi_aff_copy(upma)); +} + +/* Compute the pullback of "schedule" by the function represented by "upma". + * In other words, plug in "upma" in the iteration domains of "schedule". + * + * The schedule tree is not allowed to contain any expansion nodes. + */ +__isl_give isl_schedule *isl_schedule_pullback_union_pw_multi_aff( + __isl_take isl_schedule *schedule, + __isl_take isl_union_pw_multi_aff *upma) +{ + schedule = isl_schedule_map_schedule_node_bottom_up(schedule, + &pullback_upma, upma); + isl_union_pw_multi_aff_free(upma); + return schedule; +} + +/* Expand the schedule "schedule" by extending all leaves + * with an expansion node with as subtree the tree of "expansion". + * The expansion of the expansion node is determined by "contraction" + * and the domain of "expansion". That is, the domain of "expansion" + * is contracted according to "contraction". + * + * Call isl_schedule_node_expand after extracting the required + * information from "expansion". + */ +__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_union_set *domain; + isl_schedule_node *node; + isl_schedule_tree *tree; + + domain = isl_schedule_get_domain(expansion); + + node = isl_schedule_get_root(expansion); + node = isl_schedule_node_child(node, 0); + tree = isl_schedule_node_get_tree(node); + isl_schedule_node_free(node); + isl_schedule_free(expansion); + + node = isl_schedule_get_root(schedule); + isl_schedule_free(schedule); + node = isl_schedule_node_expand(node, contraction, domain, tree); + schedule = isl_schedule_node_get_schedule(node); + isl_schedule_node_free(node); + + return schedule; +} + +/* Intersect the domain of the schedule "schedule" with "domain". + * The root of "schedule" is required to be a domain node. + */ +__isl_give isl_schedule *isl_schedule_intersect_domain( + __isl_take isl_schedule *schedule, __isl_take isl_union_set *domain) +{ + enum isl_schedule_node_type root_type; + isl_schedule_node *node; + + if (!schedule || !domain) + goto error; + + root_type = isl_schedule_tree_get_type(schedule->root); + if (root_type != isl_schedule_node_domain) + isl_die(isl_schedule_get_ctx(schedule), isl_error_invalid, + "root node must be a domain node", goto error); + + node = isl_schedule_get_root(schedule); + isl_schedule_free(schedule); + node = isl_schedule_node_domain_intersect_domain(node, domain); + schedule = isl_schedule_node_get_schedule(node); + isl_schedule_node_free(node); + + return schedule; +error: + isl_schedule_free(schedule); + isl_union_set_free(domain); + return NULL; +} + +/* Replace the domain of the schedule "schedule" with the gist + * of the original domain with respect to the parameter domain "context". + */ +__isl_give isl_schedule *isl_schedule_gist_domain_params( + __isl_take isl_schedule *schedule, __isl_take isl_set *context) +{ + enum isl_schedule_node_type root_type; + isl_schedule_node *node; + + if (!schedule || !context) + goto error; + + root_type = isl_schedule_tree_get_type(schedule->root); + if (root_type != isl_schedule_node_domain) + isl_die(isl_schedule_get_ctx(schedule), isl_error_invalid, + "root node must be a domain node", goto error); + + node = isl_schedule_get_root(schedule); + isl_schedule_free(schedule); + node = isl_schedule_node_domain_gist_params(node, context); + schedule = isl_schedule_node_get_schedule(node); + isl_schedule_node_free(node); + + return schedule; +error: + isl_schedule_free(schedule); + isl_set_free(context); + return NULL; +} + +/* 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. + */ +__isl_give isl_union_map *isl_schedule_get_map(__isl_keep isl_schedule *sched) +{ + enum isl_schedule_node_type type; + isl_schedule_node *node; + isl_union_map *umap; + + 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); + + 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; +} + +/* Insert a band node with partial schedule "partial" between the domain + * root node of "schedule" and its single child. + * Return a pointer to the updated schedule. + * + * If any of the nodes in the tree depend on the set of outer band nodes + * then we refuse to insert the band node. + */ +__isl_give isl_schedule *isl_schedule_insert_partial_schedule( + __isl_take isl_schedule *schedule, + __isl_take isl_multi_union_pw_aff *partial) +{ + isl_schedule_node *node; + int anchored; + + node = isl_schedule_get_root(schedule); + isl_schedule_free(schedule); + if (!node) + goto error; + if (isl_schedule_node_get_type(node) != isl_schedule_node_domain) + isl_die(isl_schedule_node_get_ctx(node), isl_error_internal, + "root node not a domain node", goto error); + + node = isl_schedule_node_child(node, 0); + anchored = isl_schedule_node_is_subtree_anchored(node); + if (anchored < 0) + goto error; + if (anchored) + isl_die(isl_schedule_node_get_ctx(node), isl_error_invalid, + "cannot insert band node in anchored subtree", + goto error); + node = isl_schedule_node_insert_partial_schedule(node, partial); + + schedule = isl_schedule_node_get_schedule(node); + isl_schedule_node_free(node); + + return schedule; +error: + isl_schedule_node_free(node); + isl_multi_union_pw_aff_free(partial); + return NULL; +} + +/* Insert a context node with constraints "context" between the domain + * root node of "schedule" and its single child. + * Return a pointer to the updated schedule. + */ +__isl_give isl_schedule *isl_schedule_insert_context( + __isl_take isl_schedule *schedule, __isl_take isl_set *context) +{ + isl_schedule_node *node; + + node = isl_schedule_get_root(schedule); + isl_schedule_free(schedule); + node = isl_schedule_node_child(node, 0); + node = isl_schedule_node_insert_context(node, context); + schedule = isl_schedule_node_get_schedule(node); + isl_schedule_node_free(node); + + return schedule; +} + +/* Insert a guard node with constraints "guard" between the domain + * root node of "schedule" and its single child. + * Return a pointer to the updated schedule. + */ +__isl_give isl_schedule *isl_schedule_insert_guard( + __isl_take isl_schedule *schedule, __isl_take isl_set *guard) +{ + isl_schedule_node *node; + + node = isl_schedule_get_root(schedule); + isl_schedule_free(schedule); + node = isl_schedule_node_child(node, 0); + node = isl_schedule_node_insert_guard(node, guard); + schedule = isl_schedule_node_get_schedule(node); + isl_schedule_node_free(node); + + return schedule; +} + +/* Return a tree with as top-level node a filter corresponding to "filter" and + * as child, the (single) child of "tree". + * However, if this single child is of type "type", then the filter is inserted + * in the children of this single child instead. + */ +static __isl_give isl_schedule_tree *insert_filter_in_child_of_type( + __isl_take isl_schedule_tree *tree, __isl_take isl_union_set *filter, + enum isl_schedule_node_type type) +{ + if (!isl_schedule_tree_has_children(tree)) { + isl_schedule_tree_free(tree); + return isl_schedule_tree_from_filter(filter); + } else { + tree = isl_schedule_tree_child(tree, 0); + } + + if (isl_schedule_tree_get_type(tree) == type) + tree = isl_schedule_tree_children_insert_filter(tree, filter); + else + tree = isl_schedule_tree_insert_filter(tree, filter); + + return tree; +} + +/* Construct a schedule that combines the schedules "schedule1" and "schedule2" + * with a top-level node (underneath the domain node) of type "type", + * either isl_schedule_node_sequence or isl_schedule_node_set. + * The domains of the two schedules are assumed to be disjoint. + * + * The new schedule has as domain the union of the domains of the two + * schedules. The child of the domain node is a node of type "type" + * with two filters corresponding to the domains of the input schedules. + * If one (or both) of the top-level nodes of the two schedules is itself + * of type "type", then the filter is pushed into the children of that + * node and the sequence or set is flattened. + */ +__isl_give isl_schedule *isl_schedule_pair(enum isl_schedule_node_type type, + __isl_take isl_schedule *schedule1, __isl_take isl_schedule *schedule2) +{ + int disjoint; + isl_ctx *ctx; + enum isl_schedule_node_type root_type; + isl_schedule_tree *tree1, *tree2; + isl_union_set *filter1, *filter2, *domain; + + if (!schedule1 || !schedule2) + goto error; + + root_type = isl_schedule_tree_get_type(schedule1->root); + if (root_type != isl_schedule_node_domain) + isl_die(isl_schedule_get_ctx(schedule1), isl_error_internal, + "root node not a domain node", goto error); + root_type = isl_schedule_tree_get_type(schedule2->root); + if (root_type != isl_schedule_node_domain) + isl_die(isl_schedule_get_ctx(schedule1), isl_error_internal, + "root node not a domain node", goto error); + + ctx = isl_schedule_get_ctx(schedule1); + tree1 = isl_schedule_tree_copy(schedule1->root); + filter1 = isl_schedule_tree_domain_get_domain(tree1); + tree2 = isl_schedule_tree_copy(schedule2->root); + filter2 = isl_schedule_tree_domain_get_domain(tree2); + + isl_schedule_free(schedule1); + isl_schedule_free(schedule2); + + disjoint = isl_union_set_is_disjoint(filter1, filter2); + if (disjoint < 0) + filter1 = isl_union_set_free(filter1); + if (!disjoint) + isl_die(ctx, isl_error_invalid, + "schedule domains not disjoint", + filter1 = isl_union_set_free(filter1)); + + domain = isl_union_set_union(isl_union_set_copy(filter1), + isl_union_set_copy(filter2)); + filter1 = isl_union_set_gist(filter1, isl_union_set_copy(domain)); + filter2 = isl_union_set_gist(filter2, isl_union_set_copy(domain)); + + tree1 = insert_filter_in_child_of_type(tree1, filter1, type); + tree2 = insert_filter_in_child_of_type(tree2, filter2, type); + + tree1 = isl_schedule_tree_from_pair(type, tree1, tree2); + tree1 = isl_schedule_tree_insert_domain(tree1, domain); + + return isl_schedule_from_schedule_tree(ctx, tree1); +error: + isl_schedule_free(schedule1); + isl_schedule_free(schedule2); + return NULL; +} + +/* Construct a schedule that combines the schedules "schedule1" and "schedule2" + * through a sequence node. + * The domains of the input schedules are assumed to be disjoint. + */ +__isl_give isl_schedule *isl_schedule_sequence( + __isl_take isl_schedule *schedule1, __isl_take isl_schedule *schedule2) +{ + return isl_schedule_pair(isl_schedule_node_sequence, + schedule1, schedule2); +} + +/* Construct a schedule that combines the schedules "schedule1" and "schedule2" + * through a set node. + * The domains of the input schedules are assumed to be disjoint. + */ +__isl_give isl_schedule *isl_schedule_set( + __isl_take isl_schedule *schedule1, __isl_take isl_schedule *schedule2) +{ + return isl_schedule_pair(isl_schedule_node_set, schedule1, schedule2); +} + +/* Print "schedule" to "p". + */ +__isl_give isl_printer *isl_printer_print_schedule(__isl_take isl_printer *p, + __isl_keep isl_schedule *schedule) +{ + if (!schedule) + return isl_printer_free(p); + + return isl_printer_print_schedule_tree(p, schedule->root); +} + +#undef BASE +#define BASE schedule +#include diff --git a/external/mit/isl/dist/isl_schedule_band.c b/external/mit/isl/dist/isl_schedule_band.c new file mode 100644 index 000000000000..668579a42d78 --- /dev/null +++ b/external/mit/isl/dist/isl_schedule_band.c @@ -0,0 +1,1310 @@ +/* + * Copyright 2013-2014 Ecole Normale Superieure + * Copyright 2014 INRIA Rocquencourt + * + * Use of this software is governed by the MIT license + * + * Written by Sven Verdoolaege, + * Ecole Normale Superieure, 45 rue d'Ulm, 75230 Paris, France + * and Inria Paris - Rocquencourt, Domaine de Voluceau - Rocquencourt, + * B.P. 105 - 78153 Le Chesnay, France + */ + +#include +#include +#include +#include +#include +#include +#include + +isl_ctx *isl_schedule_band_get_ctx(__isl_keep isl_schedule_band *band) +{ + return band ? isl_multi_union_pw_aff_get_ctx(band->mupa) : NULL; +} + +/* Return a new uninitialized isl_schedule_band. + */ +static __isl_give isl_schedule_band *isl_schedule_band_alloc(isl_ctx *ctx) +{ + isl_schedule_band *band; + + band = isl_calloc_type(ctx, isl_schedule_band); + if (!band) + return NULL; + + band->ref = 1; + + return band; +} + +/* Return a new isl_schedule_band with partial schedule "mupa". + * First replace "mupa" by its greatest integer part to ensure + * that the schedule is always integral. + * The band is not marked permutable, the dimensions are not + * marked coincident and the AST build options are empty. + * Since there are no build options, the node is not anchored. + */ +__isl_give isl_schedule_band *isl_schedule_band_from_multi_union_pw_aff( + __isl_take isl_multi_union_pw_aff *mupa) +{ + isl_size dim; + isl_ctx *ctx; + isl_schedule_band *band; + isl_space *space; + + mupa = isl_multi_union_pw_aff_floor(mupa); + dim = isl_multi_union_pw_aff_size(mupa); + if (dim < 0) + goto error; + ctx = isl_multi_union_pw_aff_get_ctx(mupa); + band = isl_schedule_band_alloc(ctx); + if (!band) + goto error; + + band->n = dim; + band->coincident = isl_calloc_array(ctx, int, band->n); + band->mupa = mupa; + space = isl_space_params_alloc(ctx, 0); + band->ast_build_options = isl_union_set_empty(space); + band->anchored = 0; + + if ((band->n && !band->coincident) || !band->ast_build_options) + return isl_schedule_band_free(band); + + return band; +error: + isl_multi_union_pw_aff_free(mupa); + return NULL; +} + +/* Create a duplicate of the given isl_schedule_band. + */ +__isl_give isl_schedule_band *isl_schedule_band_dup( + __isl_keep isl_schedule_band *band) +{ + int i; + isl_ctx *ctx; + isl_schedule_band *dup; + + if (!band) + return NULL; + + ctx = isl_schedule_band_get_ctx(band); + dup = isl_schedule_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) + return isl_schedule_band_free(dup); + + for (i = 0; i < band->n; ++i) + dup->coincident[i] = band->coincident[i]; + dup->permutable = band->permutable; + + dup->mupa = isl_multi_union_pw_aff_copy(band->mupa); + dup->ast_build_options = isl_union_set_copy(band->ast_build_options); + if (!dup->mupa || !dup->ast_build_options) + return isl_schedule_band_free(dup); + + if (band->loop_type) { + dup->loop_type = isl_alloc_array(ctx, + enum isl_ast_loop_type, band->n); + if (band->n && !dup->loop_type) + return isl_schedule_band_free(dup); + for (i = 0; i < band->n; ++i) + dup->loop_type[i] = band->loop_type[i]; + } + if (band->isolate_loop_type) { + dup->isolate_loop_type = isl_alloc_array(ctx, + enum isl_ast_loop_type, band->n); + if (band->n && !dup->isolate_loop_type) + return isl_schedule_band_free(dup); + for (i = 0; i < band->n; ++i) + dup->isolate_loop_type[i] = band->isolate_loop_type[i]; + } + + return dup; +} + +/* Return an isl_schedule_band that is equal to "band" and that has only + * a single reference. + */ +__isl_give isl_schedule_band *isl_schedule_band_cow( + __isl_take isl_schedule_band *band) +{ + if (!band) + return NULL; + + if (band->ref == 1) + return band; + band->ref--; + return isl_schedule_band_dup(band); +} + +/* Return a new reference to "band". + */ +__isl_give isl_schedule_band *isl_schedule_band_copy( + __isl_keep isl_schedule_band *band) +{ + if (!band) + return NULL; + + band->ref++; + return band; +} + +/* Free a reference to "band" and return NULL. + */ +__isl_null isl_schedule_band *isl_schedule_band_free( + __isl_take isl_schedule_band *band) +{ + if (!band) + return NULL; + + if (--band->ref > 0) + return NULL; + + isl_multi_union_pw_aff_free(band->mupa); + isl_union_set_free(band->ast_build_options); + free(band->loop_type); + free(band->isolate_loop_type); + free(band->coincident); + free(band); + + return NULL; +} + +/* Are "band1" and "band2" obviously equal? + */ +isl_bool isl_schedule_band_plain_is_equal(__isl_keep isl_schedule_band *band1, + __isl_keep isl_schedule_band *band2) +{ + int i; + isl_bool equal; + + if (!band1 || !band2) + return isl_bool_error; + if (band1 == band2) + return isl_bool_true; + + if (band1->n != band2->n) + return isl_bool_false; + for (i = 0; i < band1->n; ++i) + if (band1->coincident[i] != band2->coincident[i]) + return isl_bool_false; + if (band1->permutable != band2->permutable) + return isl_bool_false; + + equal = isl_multi_union_pw_aff_plain_is_equal(band1->mupa, band2->mupa); + if (equal < 0 || !equal) + return equal; + + if (!band1->loop_type != !band2->loop_type) + return isl_bool_false; + if (band1->loop_type) + for (i = 0; i < band1->n; ++i) + if (band1->loop_type[i] != band2->loop_type[i]) + return isl_bool_false; + + if (!band1->isolate_loop_type != !band2->isolate_loop_type) + return isl_bool_false; + if (band1->isolate_loop_type) + for (i = 0; i < band1->n; ++i) + if (band1->isolate_loop_type[i] != + band2->isolate_loop_type[i]) + return isl_bool_false; + + return isl_union_set_is_equal(band1->ast_build_options, + band2->ast_build_options); +} + +/* Return the number of scheduling dimensions in the band. + */ +isl_size isl_schedule_band_n_member(__isl_keep isl_schedule_band *band) +{ + return band ? band->n : isl_size_error; +} + +/* Is the given scheduling dimension coincident within the band and + * with respect to the coincidence constraints? + */ +isl_bool isl_schedule_band_member_get_coincident( + __isl_keep isl_schedule_band *band, int pos) +{ + if (!band) + return isl_bool_error; + + if (pos < 0 || pos >= band->n) + isl_die(isl_schedule_band_get_ctx(band), isl_error_invalid, + "invalid member position", return isl_bool_error); + + return isl_bool_ok(band->coincident[pos]); +} + +/* Mark the given scheduling dimension as being coincident or not + * according to "coincident". + */ +__isl_give isl_schedule_band *isl_schedule_band_member_set_coincident( + __isl_take isl_schedule_band *band, int pos, int coincident) +{ + if (!band) + return NULL; + if (isl_schedule_band_member_get_coincident(band, pos) == coincident) + return band; + band = isl_schedule_band_cow(band); + if (!band) + return NULL; + + if (pos < 0 || pos >= band->n) + isl_die(isl_schedule_band_get_ctx(band), isl_error_invalid, + "invalid member position", + return isl_schedule_band_free(band)); + + band->coincident[pos] = coincident; + + return band; +} + +/* Is the schedule band mark permutable? + */ +isl_bool isl_schedule_band_get_permutable(__isl_keep isl_schedule_band *band) +{ + if (!band) + return isl_bool_error; + return isl_bool_ok(band->permutable); +} + +/* Mark the schedule band permutable or not according to "permutable"? + */ +__isl_give isl_schedule_band *isl_schedule_band_set_permutable( + __isl_take isl_schedule_band *band, int permutable) +{ + if (!band) + return NULL; + if (band->permutable == permutable) + return band; + band = isl_schedule_band_cow(band); + if (!band) + return NULL; + + band->permutable = permutable; + + return band; +} + +/* Is the band node "node" anchored? That is, does it reference + * the outer band nodes? + */ +int isl_schedule_band_is_anchored(__isl_keep isl_schedule_band *band) +{ + return band ? band->anchored : -1; +} + +/* Return the schedule space of the band. + */ +__isl_give isl_space *isl_schedule_band_get_space( + __isl_keep isl_schedule_band *band) +{ + if (!band) + return NULL; + return isl_multi_union_pw_aff_get_space(band->mupa); +} + +/* Intersect the domain of the band schedule of "band" with "domain". + */ +__isl_give isl_schedule_band *isl_schedule_band_intersect_domain( + __isl_take isl_schedule_band *band, __isl_take isl_union_set *domain) +{ + band = isl_schedule_band_cow(band); + if (!band || !domain) + goto error; + + band->mupa = isl_multi_union_pw_aff_intersect_domain(band->mupa, + domain); + if (!band->mupa) + return isl_schedule_band_free(band); + + return band; +error: + isl_schedule_band_free(band); + isl_union_set_free(domain); + return NULL; +} + +/* Return the schedule of the band in isolation. + */ +__isl_give isl_multi_union_pw_aff *isl_schedule_band_get_partial_schedule( + __isl_keep isl_schedule_band *band) +{ + return band ? isl_multi_union_pw_aff_copy(band->mupa) : NULL; +} + +/* Replace the schedule of "band" by "schedule". + */ +__isl_give isl_schedule_band *isl_schedule_band_set_partial_schedule( + __isl_take isl_schedule_band *band, + __isl_take isl_multi_union_pw_aff *schedule) +{ + band = isl_schedule_band_cow(band); + if (!band || !schedule) + goto error; + + isl_multi_union_pw_aff_free(band->mupa); + band->mupa = schedule; + + return band; +error: + isl_schedule_band_free(band); + isl_multi_union_pw_aff_free(schedule); + return NULL; +} + +/* Return the loop AST generation type for the band member of "band" + * at position "pos". + */ +enum isl_ast_loop_type isl_schedule_band_member_get_ast_loop_type( + __isl_keep isl_schedule_band *band, int pos) +{ + if (!band) + return isl_ast_loop_error; + + if (pos < 0 || pos >= band->n) + isl_die(isl_schedule_band_get_ctx(band), isl_error_invalid, + "invalid member position", return isl_ast_loop_error); + + if (!band->loop_type) + return isl_ast_loop_default; + + return band->loop_type[pos]; +} + +/* Set the loop AST generation type for the band member of "band" + * at position "pos" to "type". + */ +__isl_give isl_schedule_band *isl_schedule_band_member_set_ast_loop_type( + __isl_take isl_schedule_band *band, int pos, + enum isl_ast_loop_type type) +{ + if (!band) + return NULL; + if (isl_schedule_band_member_get_ast_loop_type(band, pos) == type) + return band; + + if (pos < 0 || pos >= band->n) + isl_die(isl_schedule_band_get_ctx(band), isl_error_invalid, + "invalid member position", + return isl_schedule_band_free(band)); + + band = isl_schedule_band_cow(band); + if (!band) + return isl_schedule_band_free(band); + + if (!band->loop_type) { + isl_ctx *ctx; + + ctx = isl_schedule_band_get_ctx(band); + band->loop_type = isl_calloc_array(ctx, + enum isl_ast_loop_type, band->n); + if (band->n && !band->loop_type) + return isl_schedule_band_free(band); + } + + band->loop_type[pos] = type; + + return band; +} + +/* Return the loop AST generation type for the band member of "band" + * at position "pos" for the part that has been isolated by the isolate option. + */ +enum isl_ast_loop_type isl_schedule_band_member_get_isolate_ast_loop_type( + __isl_keep isl_schedule_band *band, int pos) +{ + if (!band) + return isl_ast_loop_error; + + if (pos < 0 || pos >= band->n) + isl_die(isl_schedule_band_get_ctx(band), isl_error_invalid, + "invalid member position", return isl_ast_loop_error); + + if (!band->isolate_loop_type) + return isl_ast_loop_default; + + return band->isolate_loop_type[pos]; +} + +/* Set the loop AST generation type for the band member of "band" + * at position "pos" to "type" for the part that has been isolated + * by the isolate option. + */ +__isl_give isl_schedule_band * +isl_schedule_band_member_set_isolate_ast_loop_type( + __isl_take isl_schedule_band *band, int pos, + enum isl_ast_loop_type type) +{ + if (!band) + return NULL; + if (isl_schedule_band_member_get_isolate_ast_loop_type(band, pos) == + type) + return band; + + if (pos < 0 || pos >= band->n) + isl_die(isl_schedule_band_get_ctx(band), isl_error_invalid, + "invalid member position", + return isl_schedule_band_free(band)); + + band = isl_schedule_band_cow(band); + if (!band) + return isl_schedule_band_free(band); + + if (!band->isolate_loop_type) { + isl_ctx *ctx; + + ctx = isl_schedule_band_get_ctx(band); + band->isolate_loop_type = isl_calloc_array(ctx, + enum isl_ast_loop_type, band->n); + if (band->n && !band->isolate_loop_type) + return isl_schedule_band_free(band); + } + + band->isolate_loop_type[pos] = type; + + return band; +} + +static const char *option_str[] = { + [isl_ast_loop_atomic] = "atomic", + [isl_ast_loop_unroll] = "unroll", + [isl_ast_loop_separate] = "separate" +}; + +/* Given a parameter space "space", extend it to a set space + * + * { type[x] } + * + * or + * + * { [isolate[] -> type[x]] } + * + * depending on whether "isolate" is set. + * These can be used to encode loop AST generation options of the given type. + */ +static __isl_give isl_space *loop_type_space(__isl_take isl_space *space, + enum isl_ast_loop_type type, int isolate) +{ + const char *name; + + name = option_str[type]; + space = isl_space_set_from_params(space); + space = isl_space_add_dims(space, isl_dim_set, 1); + space = isl_space_set_tuple_name(space, isl_dim_set, name); + if (!isolate) + return space; + space = isl_space_from_range(space); + space = isl_space_set_tuple_name(space, isl_dim_in, "isolate"); + space = isl_space_wrap(space); + + return space; +} + +/* Add encodings of the "n" loop AST generation options "type" to "options". + * If "isolate" is set, then these options refer to the isolated part. + * + * In particular, for each sequence of consecutive identical types "t", + * different from the default, add an option + * + * { t[x] : first <= x <= last } + * + * or + * + * { [isolate[] -> t[x]] : first <= x <= last } + */ +static __isl_give isl_union_set *add_loop_types( + __isl_take isl_union_set *options, int n, enum isl_ast_loop_type *type, + int isolate) +{ + int i; + + if (!type) + return options; + if (!options) + return NULL; + + for (i = 0; i < n; ++i) { + int first; + isl_space *space; + isl_set *option; + + if (type[i] == isl_ast_loop_default) + continue; + + first = i; + while (i + 1 < n && type[i + 1] == type[i]) + ++i; + + space = isl_union_set_get_space(options); + space = loop_type_space(space, type[i], isolate); + option = isl_set_universe(space); + option = isl_set_lower_bound_si(option, isl_dim_set, 0, first); + option = isl_set_upper_bound_si(option, isl_dim_set, 0, i); + options = isl_union_set_add_set(options, option); + } + + return options; +} + +/* Return the AST build options associated to "band". + */ +__isl_give isl_union_set *isl_schedule_band_get_ast_build_options( + __isl_keep isl_schedule_band *band) +{ + isl_union_set *options; + + if (!band) + return NULL; + + options = isl_union_set_copy(band->ast_build_options); + options = add_loop_types(options, band->n, band->loop_type, 0); + options = add_loop_types(options, band->n, band->isolate_loop_type, 1); + + return options; +} + +/* Internal data structure for not(). + */ +struct isl_not_data { + isl_bool (*is)(__isl_keep isl_set *set); +}; + +/* Does "set" not satisfy data->is()? + */ +static isl_bool not(__isl_keep isl_set *set, void *user) +{ + struct isl_not_data *data = user; + + return isl_bool_not(data->is(set)); +} + +/* Does "uset" contain any set that satisfies "is"? + * In other words, is it not the case that all of them do not satisfy "is"? + */ +static isl_bool has_any(__isl_keep isl_union_set *uset, + isl_bool (*is)(__isl_keep isl_set *set)) +{ + struct isl_not_data data = { is }; + + return isl_bool_not(isl_union_set_every_set(uset, ¬, &data)); +} + +/* Does "set" live in a space of the form + * + * isolate[[...] -> [...]] + * + * ? + */ +static isl_bool is_isolate(__isl_keep isl_set *set) +{ + if (isl_set_has_tuple_name(set)) { + const char *name; + name = isl_set_get_tuple_name(set); + if (isl_set_is_wrapping(set) && !strcmp(name, "isolate")) + return isl_bool_true; + } + + return isl_bool_false; +} + +/* Does "options" include an option of the ofrm + * + * isolate[[...] -> [...]] + * + * ? + */ +static isl_bool has_isolate_option(__isl_keep isl_union_set *options) +{ + return has_any(options, &is_isolate); +} + +/* Does "set" encode a loop AST generation option? + */ +static isl_bool is_loop_type_option(__isl_keep isl_set *set) +{ + isl_size dim; + + dim = isl_set_dim(set, isl_dim_set); + if (dim < 0) + return isl_bool_error; + if (dim == 1 && isl_set_has_tuple_name(set)) { + const char *name; + enum isl_ast_loop_type type; + name = isl_set_get_tuple_name(set); + for (type = isl_ast_loop_atomic; + type <= isl_ast_loop_separate; ++type) { + if (strcmp(name, option_str[type])) + continue; + return isl_bool_true; + } + } + + return isl_bool_false; +} + +/* Does "set" encode a loop AST generation option for the isolated part? + * That is, is of the form + * + * { [isolate[] -> t[x]] } + * + * with t equal to "atomic", "unroll" or "separate"? + */ +static isl_bool is_isolate_loop_type_option(__isl_keep isl_set *set) +{ + const char *name; + enum isl_ast_loop_type type; + isl_map *map; + + if (!isl_set_is_wrapping(set)) + return isl_bool_false; + map = isl_set_unwrap(isl_set_copy(set)); + if (!isl_map_has_tuple_name(map, isl_dim_in) || + !isl_map_has_tuple_name(map, isl_dim_out)) { + isl_map_free(map); + return isl_bool_false; + } + name = isl_map_get_tuple_name(map, isl_dim_in); + if (!strcmp(name, "isolate")) { + name = isl_map_get_tuple_name(map, isl_dim_out); + for (type = isl_ast_loop_atomic; + type <= isl_ast_loop_separate; ++type) { + if (strcmp(name, option_str[type])) + continue; + isl_map_free(map); + return isl_bool_true; + } + } + isl_map_free(map); + + return isl_bool_false; +} + +/* Does "options" encode any loop AST generation options + * for the isolated part? + */ +static isl_bool has_isolate_loop_type_options(__isl_keep isl_union_set *options) +{ + return has_any(options, &is_isolate_loop_type_option); +} + +/* Does "options" encode any loop AST generation options? + */ +static isl_bool has_loop_type_options(__isl_keep isl_union_set *options) +{ + return has_any(options, &is_loop_type_option); +} + +/* Extract the loop AST generation type for the band member + * at position "pos" from "options". + * If "isolate" is set, then extract the loop types for the isolated part. + */ +static enum isl_ast_loop_type extract_loop_type( + __isl_keep isl_union_set *options, int pos, int isolate) +{ + isl_ctx *ctx; + enum isl_ast_loop_type type, res = isl_ast_loop_default; + + ctx = isl_union_set_get_ctx(options); + for (type = isl_ast_loop_atomic; + type <= isl_ast_loop_separate; ++type) { + isl_space *space; + isl_set *option; + int empty; + + space = isl_union_set_get_space(options); + space = loop_type_space(space, type, isolate); + option = isl_union_set_extract_set(options, space); + option = isl_set_fix_si(option, isl_dim_set, 0, pos); + empty = isl_set_is_empty(option); + isl_set_free(option); + + if (empty < 0) + return isl_ast_loop_error; + if (empty) + continue; + if (res != isl_ast_loop_default) + isl_die(ctx, isl_error_invalid, + "conflicting loop type options", + return isl_ast_loop_error); + res = type; + } + + return res; +} + +/* Extract the loop AST generation types for the members of "band" + * from "options" and store them in band->loop_type. + * Return -1 on error. + */ +static int extract_loop_types(__isl_keep isl_schedule_band *band, + __isl_keep isl_union_set *options) +{ + int i; + + if (!band->loop_type) { + isl_ctx *ctx = isl_schedule_band_get_ctx(band); + band->loop_type = isl_alloc_array(ctx, + enum isl_ast_loop_type, band->n); + if (band->n && !band->loop_type) + return -1; + } + for (i = 0; i < band->n; ++i) { + band->loop_type[i] = extract_loop_type(options, i, 0); + if (band->loop_type[i] == isl_ast_loop_error) + return -1; + } + + return 0; +} + +/* Extract the loop AST generation types for the members of "band" + * from "options" for the isolated part and + * store them in band->isolate_loop_type. + * Return -1 on error. + */ +static int extract_isolate_loop_types(__isl_keep isl_schedule_band *band, + __isl_keep isl_union_set *options) +{ + int i; + + if (!band->isolate_loop_type) { + isl_ctx *ctx = isl_schedule_band_get_ctx(band); + band->isolate_loop_type = isl_alloc_array(ctx, + enum isl_ast_loop_type, band->n); + if (band->n && !band->isolate_loop_type) + return -1; + } + for (i = 0; i < band->n; ++i) { + band->isolate_loop_type[i] = extract_loop_type(options, i, 1); + if (band->isolate_loop_type[i] == isl_ast_loop_error) + return -1; + } + + return 0; +} + +/* Construct universe sets of the spaces that encode loop AST generation + * types (for the isolated part if "isolate" is set). That is, construct + * + * { atomic[x]; separate[x]; unroll[x] } + * + * or + * + * { [isolate[] -> atomic[x]]; [isolate[] -> separate[x]]; + * [isolate[] -> unroll[x]] } + */ +static __isl_give isl_union_set *loop_types(__isl_take isl_space *space, + int isolate) +{ + enum isl_ast_loop_type type; + isl_union_set *types; + + types = isl_union_set_empty(space); + for (type = isl_ast_loop_atomic; + type <= isl_ast_loop_separate; ++type) { + isl_set *set; + + space = isl_union_set_get_space(types); + space = loop_type_space(space, type, isolate); + set = isl_set_universe(space); + types = isl_union_set_add_set(types, set); + } + + return types; +} + +/* Remove all elements from spaces that encode loop AST generation types + * from "options". + */ +static __isl_give isl_union_set *clear_loop_types( + __isl_take isl_union_set *options) +{ + isl_union_set *types; + + types = loop_types(isl_union_set_get_space(options), 0); + options = isl_union_set_subtract(options, types); + + return options; +} + +/* Remove all elements from spaces that encode loop AST generation types + * for the isolated part from "options". + */ +static __isl_give isl_union_set *clear_isolate_loop_types( + __isl_take isl_union_set *options) +{ + isl_union_set *types; + + types = loop_types(isl_union_set_get_space(options), 1); + options = isl_union_set_subtract(options, types); + + return options; +} + +/* Replace the AST build options associated to "band" by "options". + * If there are any loop AST generation type options, then they + * are extracted and stored in band->loop_type. Otherwise, + * band->loop_type is removed to indicate that the default applies + * to all members. Similarly for the loop AST generation type options + * for the isolated part, which are stored in band->isolate_loop_type. + * The remaining options are stored in band->ast_build_options. + * + * Set anchored if the options include an isolate option since the + * domain of the wrapped map references the outer band node schedules. + */ +__isl_give isl_schedule_band *isl_schedule_band_set_ast_build_options( + __isl_take isl_schedule_band *band, __isl_take isl_union_set *options) +{ + isl_bool has_isolate, has_loop_type, has_isolate_loop_type; + + band = isl_schedule_band_cow(band); + if (!band || !options) + goto error; + has_isolate = has_isolate_option(options); + if (has_isolate < 0) + goto error; + has_loop_type = has_loop_type_options(options); + if (has_loop_type < 0) + goto error; + has_isolate_loop_type = has_isolate_loop_type_options(options); + if (has_isolate_loop_type < 0) + goto error; + + if (!has_loop_type) { + free(band->loop_type); + band->loop_type = NULL; + } else { + if (extract_loop_types(band, options) < 0) + goto error; + options = clear_loop_types(options); + if (!options) + goto error; + } + + if (!has_isolate_loop_type) { + free(band->isolate_loop_type); + band->isolate_loop_type = NULL; + } else { + if (extract_isolate_loop_types(band, options) < 0) + goto error; + options = clear_isolate_loop_types(options); + if (!options) + goto error; + } + + isl_union_set_free(band->ast_build_options); + band->ast_build_options = options; + band->anchored = has_isolate; + + return band; +error: + isl_schedule_band_free(band); + isl_union_set_free(options); + return NULL; +} + +/* Return the "isolate" option associated to "band", assuming + * it at appears at schedule depth "depth". + * + * The isolate option is of the form + * + * isolate[[flattened outer bands] -> band] + */ +__isl_give isl_set *isl_schedule_band_get_ast_isolate_option( + __isl_keep isl_schedule_band *band, int depth) +{ + isl_space *space; + isl_set *isolate; + + if (!band) + return NULL; + + space = isl_schedule_band_get_space(band); + space = isl_space_from_range(space); + space = isl_space_add_dims(space, isl_dim_in, depth); + space = isl_space_wrap(space); + space = isl_space_set_tuple_name(space, isl_dim_set, "isolate"); + + isolate = isl_union_set_extract_set(band->ast_build_options, space); + + return isolate; +} + +/* Replace the option "drop" in the AST build options by "add". + * That is, remove "drop" and add "add". + */ +__isl_give isl_schedule_band *isl_schedule_band_replace_ast_build_option( + __isl_take isl_schedule_band *band, __isl_take isl_set *drop, + __isl_take isl_set *add) +{ + isl_union_set *options; + + band = isl_schedule_band_cow(band); + if (!band) + goto error; + + options = band->ast_build_options; + options = isl_union_set_subtract(options, isl_union_set_from_set(drop)); + options = isl_union_set_union(options, isl_union_set_from_set(add)); + band->ast_build_options = options; + + if (!band->ast_build_options) + return isl_schedule_band_free(band); + + return band; +error: + isl_schedule_band_free(band); + isl_set_free(drop); + isl_set_free(add); + return NULL; +} + +/* Multiply the partial schedule of "band" with the factors in "mv". + * Replace the result by its greatest integer part to ensure + * that the schedule is always integral. + */ +__isl_give isl_schedule_band *isl_schedule_band_scale( + __isl_take isl_schedule_band *band, __isl_take isl_multi_val *mv) +{ + band = isl_schedule_band_cow(band); + if (!band || !mv) + goto error; + band->mupa = isl_multi_union_pw_aff_scale_multi_val(band->mupa, mv); + band->mupa = isl_multi_union_pw_aff_floor(band->mupa); + if (!band->mupa) + return isl_schedule_band_free(band); + return band; +error: + isl_schedule_band_free(band); + isl_multi_val_free(mv); + return NULL; +} + +/* Divide the partial schedule of "band" by the factors in "mv". + * Replace the result by its greatest integer part to ensure + * that the schedule is always integral. + */ +__isl_give isl_schedule_band *isl_schedule_band_scale_down( + __isl_take isl_schedule_band *band, __isl_take isl_multi_val *mv) +{ + band = isl_schedule_band_cow(band); + if (!band || !mv) + goto error; + band->mupa = isl_multi_union_pw_aff_scale_down_multi_val(band->mupa, + mv); + band->mupa = isl_multi_union_pw_aff_floor(band->mupa); + if (!band->mupa) + return isl_schedule_band_free(band); + return band; +error: + isl_schedule_band_free(band); + isl_multi_val_free(mv); + return NULL; +} + +/* Reduce the partial schedule of "band" modulo the factors in "mv". + */ +__isl_give isl_schedule_band *isl_schedule_band_mod( + __isl_take isl_schedule_band *band, __isl_take isl_multi_val *mv) +{ + band = isl_schedule_band_cow(band); + if (!band || !mv) + goto error; + band->mupa = isl_multi_union_pw_aff_mod_multi_val(band->mupa, mv); + if (!band->mupa) + return isl_schedule_band_free(band); + return band; +error: + isl_schedule_band_free(band); + isl_multi_val_free(mv); + return NULL; +} + +/* Shift the partial schedule of "band" by "shift" after checking + * that the domain of the partial schedule would not be affected + * by this shift. + */ +__isl_give isl_schedule_band *isl_schedule_band_shift( + __isl_take isl_schedule_band *band, + __isl_take isl_multi_union_pw_aff *shift) +{ + isl_union_set *dom1, *dom2; + isl_bool subset; + + band = isl_schedule_band_cow(band); + if (!band || !shift) + goto error; + dom1 = isl_multi_union_pw_aff_domain( + isl_multi_union_pw_aff_copy(band->mupa)); + dom2 = isl_multi_union_pw_aff_domain( + isl_multi_union_pw_aff_copy(shift)); + subset = isl_union_set_is_subset(dom1, dom2); + isl_union_set_free(dom1); + isl_union_set_free(dom2); + if (subset < 0) + goto error; + if (!subset) + isl_die(isl_schedule_band_get_ctx(band), isl_error_invalid, + "domain of shift needs to include domain of " + "partial schedule", goto error); + band->mupa = isl_multi_union_pw_aff_add(band->mupa, shift); + if (!band->mupa) + return isl_schedule_band_free(band); + return band; +error: + isl_schedule_band_free(band); + isl_multi_union_pw_aff_free(shift); + return NULL; +} + +/* Given the schedule of a band, construct the corresponding + * schedule for the tile loops based on the given tile sizes + * and return the result. + * + * If the scale tile loops options is set, then the tile loops + * are scaled by the tile sizes. + * + * That is replace each schedule dimension "i" by either + * "floor(i/s)" or "s * floor(i/s)". + */ +static isl_multi_union_pw_aff *isl_multi_union_pw_aff_tile( + __isl_take isl_multi_union_pw_aff *sched, + __isl_take isl_multi_val *sizes) +{ + isl_ctx *ctx; + int i; + isl_size n; + isl_val *v; + int scale; + + ctx = isl_multi_val_get_ctx(sizes); + scale = isl_options_get_tile_scale_tile_loops(ctx); + + n = isl_multi_union_pw_aff_size(sched); + if (n < 0) + sched = isl_multi_union_pw_aff_free(sched); + for (i = 0; i < n; ++i) { + isl_union_pw_aff *upa; + + upa = isl_multi_union_pw_aff_get_union_pw_aff(sched, i); + v = isl_multi_val_get_val(sizes, i); + + upa = isl_union_pw_aff_scale_down_val(upa, isl_val_copy(v)); + upa = isl_union_pw_aff_floor(upa); + if (scale) + upa = isl_union_pw_aff_scale_val(upa, isl_val_copy(v)); + isl_val_free(v); + + sched = isl_multi_union_pw_aff_set_union_pw_aff(sched, i, upa); + } + + isl_multi_val_free(sizes); + return sched; +} + +/* Replace "band" by a band corresponding to the tile loops of a tiling + * with the given tile sizes. + */ +__isl_give isl_schedule_band *isl_schedule_band_tile( + __isl_take isl_schedule_band *band, __isl_take isl_multi_val *sizes) +{ + band = isl_schedule_band_cow(band); + if (!band || !sizes) + goto error; + band->mupa = isl_multi_union_pw_aff_tile(band->mupa, sizes); + if (!band->mupa) + return isl_schedule_band_free(band); + return band; +error: + isl_schedule_band_free(band); + isl_multi_val_free(sizes); + return NULL; +} + +/* Replace "band" by a band corresponding to the point loops of a tiling + * with the given tile sizes. + * "tile" is the corresponding tile loop band. + * + * If the shift point loops option is set, then the point loops + * are shifted to start at zero. That is, each schedule dimension "i" + * is replaced by "i - s * floor(i/s)". + * The expression "floor(i/s)" (or "s * floor(i/s)") is extracted from + * the tile band. + * + * Otherwise, the band is left untouched. + */ +__isl_give isl_schedule_band *isl_schedule_band_point( + __isl_take isl_schedule_band *band, __isl_keep isl_schedule_band *tile, + __isl_take isl_multi_val *sizes) +{ + isl_ctx *ctx; + isl_multi_union_pw_aff *scaled; + + if (!band || !sizes) + goto error; + + ctx = isl_schedule_band_get_ctx(band); + if (!isl_options_get_tile_shift_point_loops(ctx)) { + isl_multi_val_free(sizes); + return band; + } + band = isl_schedule_band_cow(band); + if (!band) + goto error; + + scaled = isl_schedule_band_get_partial_schedule(tile); + if (!isl_options_get_tile_scale_tile_loops(ctx)) + scaled = isl_multi_union_pw_aff_scale_multi_val(scaled, sizes); + else + isl_multi_val_free(sizes); + band->mupa = isl_multi_union_pw_aff_sub(band->mupa, scaled); + if (!band->mupa) + return isl_schedule_band_free(band); + return band; +error: + isl_schedule_band_free(band); + isl_multi_val_free(sizes); + return NULL; +} + +/* Drop the "n" dimensions starting at "pos" from "band". + * + * We apply the transformation even if "n" is zero to ensure consistent + * behavior with respect to changes in the schedule space. + * + * The caller is responsible for updating the isolate option. + */ +__isl_give isl_schedule_band *isl_schedule_band_drop( + __isl_take isl_schedule_band *band, int pos, int n) +{ + int i; + + if (pos < 0 || n < 0 || pos + n > band->n) + isl_die(isl_schedule_band_get_ctx(band), isl_error_internal, + "range out of bounds", + return isl_schedule_band_free(band)); + + band = isl_schedule_band_cow(band); + if (!band) + return NULL; + + band->mupa = isl_multi_union_pw_aff_drop_dims(band->mupa, + isl_dim_set, pos, n); + if (!band->mupa) + return isl_schedule_band_free(band); + + for (i = pos + n; i < band->n; ++i) + band->coincident[i - n] = band->coincident[i]; + if (band->loop_type) + for (i = pos + n; i < band->n; ++i) + band->loop_type[i - n] = band->loop_type[i]; + if (band->isolate_loop_type) + for (i = pos + n; i < band->n; ++i) + band->isolate_loop_type[i - n] = + band->isolate_loop_type[i]; + + band->n -= n; + + return band; +} + +/* Reset the user pointer on all identifiers of parameters and tuples + * in "band". + */ +__isl_give isl_schedule_band *isl_schedule_band_reset_user( + __isl_take isl_schedule_band *band) +{ + band = isl_schedule_band_cow(band); + if (!band) + return NULL; + + band->mupa = isl_multi_union_pw_aff_reset_user(band->mupa); + band->ast_build_options = + isl_union_set_reset_user(band->ast_build_options); + if (!band->mupa || !band->ast_build_options) + return isl_schedule_band_free(band); + + return band; +} + +/* Align the parameters of "band" to those of "space". + */ +__isl_give isl_schedule_band *isl_schedule_band_align_params( + __isl_take isl_schedule_band *band, __isl_take isl_space *space) +{ + band = isl_schedule_band_cow(band); + if (!band || !space) + goto error; + + band->mupa = isl_multi_union_pw_aff_align_params(band->mupa, + isl_space_copy(space)); + band->ast_build_options = + isl_union_set_align_params(band->ast_build_options, space); + if (!band->mupa || !band->ast_build_options) + return isl_schedule_band_free(band); + + return band; +error: + isl_space_free(space); + isl_schedule_band_free(band); + return NULL; +} + +/* Compute the pullback of "band" by the function represented by "upma". + * In other words, plug in "upma" in the iteration domains of "band". + */ +__isl_give isl_schedule_band *isl_schedule_band_pullback_union_pw_multi_aff( + __isl_take isl_schedule_band *band, + __isl_take isl_union_pw_multi_aff *upma) +{ + band = isl_schedule_band_cow(band); + if (!band || !upma) + goto error; + + band->mupa = + isl_multi_union_pw_aff_pullback_union_pw_multi_aff(band->mupa, + upma); + if (!band->mupa) + return isl_schedule_band_free(band); + + return band; +error: + isl_union_pw_multi_aff_free(upma); + isl_schedule_band_free(band); + return NULL; +} + +/* Compute the gist of "band" with respect to "context". + * In particular, compute the gist of the associated partial schedule. + */ +__isl_give isl_schedule_band *isl_schedule_band_gist( + __isl_take isl_schedule_band *band, __isl_take isl_union_set *context) +{ + if (!band || !context) + goto error; + if (band->n == 0) { + isl_union_set_free(context); + return band; + } + band = isl_schedule_band_cow(band); + if (!band) + goto error; + band->mupa = isl_multi_union_pw_aff_gist(band->mupa, context); + if (!band->mupa) + return isl_schedule_band_free(band); + return band; +error: + isl_union_set_free(context); + isl_schedule_band_free(band); + return NULL; +} diff --git a/external/mit/isl/dist/isl_schedule_band.h b/external/mit/isl/dist/isl_schedule_band.h new file mode 100644 index 000000000000..fa4e5ca3f6e2 --- /dev/null +++ b/external/mit/isl/dist/isl_schedule_band.h @@ -0,0 +1,125 @@ +#ifndef ISL_SCHEDULE_BAND_H +#define ISL_SCHEDULE_BAND_H + +#include +#include +#include + +/* 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. + * permutable is set if the band is permutable. + * mupa is the partial schedule corresponding to this band. The dimension + * of mupa is equal to n. + * loop_type contains the loop AST generation types for the members + * in the band. It may be NULL, if all members are + * of type isl_ast_loop_default. + * isolate_loop_type contains the loop AST generation types for the members + * in the band for the isolated part. It may be NULL, if all members are + * of type isl_ast_loop_default. + * ast_build_options are the remaining AST build options associated + * to the band. + * anchored is set if the node depends on its position in the schedule tree. + * In particular, it is set if the AST build options include + * an isolate option. + */ +struct isl_schedule_band { + int ref; + + int n; + int *coincident; + int permutable; + + isl_multi_union_pw_aff *mupa; + + int anchored; + isl_union_set *ast_build_options; + enum isl_ast_loop_type *loop_type; + enum isl_ast_loop_type *isolate_loop_type; +}; +typedef struct isl_schedule_band isl_schedule_band; + +__isl_give isl_schedule_band *isl_schedule_band_from_multi_union_pw_aff( + __isl_take isl_multi_union_pw_aff *mupa); +__isl_give isl_schedule_band *isl_schedule_band_copy( + __isl_keep isl_schedule_band *band); +__isl_null isl_schedule_band *isl_schedule_band_free( + __isl_take isl_schedule_band *band); + +isl_ctx *isl_schedule_band_get_ctx(__isl_keep isl_schedule_band *band); + +isl_bool isl_schedule_band_plain_is_equal(__isl_keep isl_schedule_band *band1, + __isl_keep isl_schedule_band *band2); + +int isl_schedule_band_is_anchored(__isl_keep isl_schedule_band *band); + +__isl_give isl_space *isl_schedule_band_get_space( + __isl_keep isl_schedule_band *band); +__isl_give isl_schedule_band *isl_schedule_band_intersect_domain( + __isl_take isl_schedule_band *band, __isl_take isl_union_set *domain); +__isl_give isl_multi_union_pw_aff *isl_schedule_band_get_partial_schedule( + __isl_keep isl_schedule_band *band); +__isl_give isl_schedule_band *isl_schedule_band_set_partial_schedule( + __isl_take isl_schedule_band *band, + __isl_take isl_multi_union_pw_aff *schedule); +enum isl_ast_loop_type isl_schedule_band_member_get_ast_loop_type( + __isl_keep isl_schedule_band *band, int pos); +__isl_give isl_schedule_band *isl_schedule_band_member_set_ast_loop_type( + __isl_take isl_schedule_band *band, int pos, + enum isl_ast_loop_type type); +enum isl_ast_loop_type isl_schedule_band_member_get_isolate_ast_loop_type( + __isl_keep isl_schedule_band *band, int pos); +__isl_give isl_schedule_band * +isl_schedule_band_member_set_isolate_ast_loop_type( + __isl_take isl_schedule_band *band, int pos, + enum isl_ast_loop_type type); +__isl_give isl_union_set *isl_schedule_band_get_ast_build_options( + __isl_keep isl_schedule_band *band); +__isl_give isl_schedule_band *isl_schedule_band_set_ast_build_options( + __isl_take isl_schedule_band *band, __isl_take isl_union_set *options); +__isl_give isl_set *isl_schedule_band_get_ast_isolate_option( + __isl_keep isl_schedule_band *band, int depth); +__isl_give isl_schedule_band *isl_schedule_band_replace_ast_build_option( + __isl_take isl_schedule_band *band, __isl_take isl_set *drop, + __isl_take isl_set *add); + +isl_size isl_schedule_band_n_member(__isl_keep isl_schedule_band *band); +isl_bool isl_schedule_band_member_get_coincident( + __isl_keep isl_schedule_band *band, int pos); +__isl_give isl_schedule_band *isl_schedule_band_member_set_coincident( + __isl_take isl_schedule_band *band, int pos, int coincident); +isl_bool isl_schedule_band_get_permutable(__isl_keep isl_schedule_band *band); +__isl_give isl_schedule_band *isl_schedule_band_set_permutable( + __isl_take isl_schedule_band *band, int permutable); + +__isl_give isl_schedule_band *isl_schedule_band_scale( + __isl_take isl_schedule_band *band, __isl_take isl_multi_val *mv); +__isl_give isl_schedule_band *isl_schedule_band_scale_down( + __isl_take isl_schedule_band *band, __isl_take isl_multi_val *mv); +__isl_give isl_schedule_band *isl_schedule_band_mod( + __isl_take isl_schedule_band *band, __isl_take isl_multi_val *mv); +__isl_give isl_schedule_band *isl_schedule_band_tile( + __isl_take isl_schedule_band *band, __isl_take isl_multi_val *sizes); +__isl_give isl_schedule_band *isl_schedule_band_point( + __isl_take isl_schedule_band *band, __isl_keep isl_schedule_band *tile, + __isl_take isl_multi_val *sizes); +__isl_give isl_schedule_band *isl_schedule_band_shift( + __isl_take isl_schedule_band *band, + __isl_take isl_multi_union_pw_aff *shift); +__isl_give isl_schedule_band *isl_schedule_band_drop( + __isl_take isl_schedule_band *band, int pos, int n); +__isl_give isl_schedule_band *isl_schedule_band_gist( + __isl_take isl_schedule_band *band, __isl_take isl_union_set *context); + +__isl_give isl_schedule_band *isl_schedule_band_reset_user( + __isl_take isl_schedule_band *band); +__isl_give isl_schedule_band *isl_schedule_band_align_params( + __isl_take isl_schedule_band *band, __isl_take isl_space *space); +__isl_give isl_schedule_band *isl_schedule_band_pullback_union_pw_multi_aff( + __isl_take isl_schedule_band *band, + __isl_take isl_union_pw_multi_aff *upma); + +#endif diff --git a/external/mit/isl/dist/isl_schedule_constraints.c b/external/mit/isl/dist/isl_schedule_constraints.c new file mode 100644 index 000000000000..c35ac66dfa68 --- /dev/null +++ b/external/mit/isl/dist/isl_schedule_constraints.c @@ -0,0 +1,762 @@ +/* + * Copyright 2012 Ecole Normale Superieure + * Copyright 2015-2016 Sven Verdoolaege + * + * 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 +#include +#include +#include +#include +#include +#include +#include + +/* The constraints that need to be satisfied by a schedule on "domain". + * + * "context" specifies extra constraints on the parameters. + * + * "validity" constraints map domain elements i to domain elements + * that should be scheduled after i. (Hard constraint) + * "proximity" constraints map domain elements i to domains elements + * that should be scheduled as early as possible after i (or before i). + * (Soft constraint) + * + * "condition" and "conditional_validity" constraints map possibly "tagged" + * domain elements i -> s to "tagged" domain elements j -> t. + * The elements of the "conditional_validity" constraints, but without the + * tags (i.e., the elements i -> j) are treated as validity constraints, + * except that during the construction of a tilable band, + * the elements of the "conditional_validity" constraints may be violated + * provided that all adjacent elements of the "condition" constraints + * are local within the band. + * A dependence is local within a band if domain and range are mapped + * to the same schedule point by the band. + */ +struct isl_schedule_constraints { + isl_union_set *domain; + isl_set *context; + + isl_union_map *constraint[isl_edge_last + 1]; +}; + +__isl_give isl_schedule_constraints *isl_schedule_constraints_copy( + __isl_keep isl_schedule_constraints *sc) +{ + isl_ctx *ctx; + isl_schedule_constraints *sc_copy; + enum isl_edge_type i; + + ctx = isl_union_set_get_ctx(sc->domain); + sc_copy = isl_calloc_type(ctx, struct isl_schedule_constraints); + if (!sc_copy) + return NULL; + + sc_copy->domain = isl_union_set_copy(sc->domain); + sc_copy->context = isl_set_copy(sc->context); + if (!sc_copy->domain || !sc_copy->context) + return isl_schedule_constraints_free(sc_copy); + + for (i = isl_edge_first; i <= isl_edge_last; ++i) { + sc_copy->constraint[i] = isl_union_map_copy(sc->constraint[i]); + if (!sc_copy->constraint[i]) + return isl_schedule_constraints_free(sc_copy); + } + + return sc_copy; +} + +/* Construct an empty (invalid) isl_schedule_constraints object. + * The caller is responsible for setting the domain and initializing + * all the other fields, e.g., by calling isl_schedule_constraints_init. + */ +static __isl_give isl_schedule_constraints *isl_schedule_constraints_alloc( + isl_ctx *ctx) +{ + return isl_calloc_type(ctx, struct isl_schedule_constraints); +} + +/* Initialize all the fields of "sc", except domain, which is assumed + * to have been set by the caller. + */ +static __isl_give isl_schedule_constraints *isl_schedule_constraints_init( + __isl_take isl_schedule_constraints *sc) +{ + isl_space *space; + isl_union_map *empty; + enum isl_edge_type i; + + if (!sc) + return NULL; + if (!sc->domain) + return isl_schedule_constraints_free(sc); + space = isl_union_set_get_space(sc->domain); + if (!sc->context) + sc->context = isl_set_universe(isl_space_copy(space)); + empty = isl_union_map_empty(space); + for (i = isl_edge_first; i <= isl_edge_last; ++i) { + if (sc->constraint[i]) + continue; + sc->constraint[i] = isl_union_map_copy(empty); + if (!sc->constraint[i]) + sc->domain = isl_union_set_free(sc->domain); + } + isl_union_map_free(empty); + + if (!sc->domain || !sc->context) + return isl_schedule_constraints_free(sc); + + return sc; +} + +/* Construct an isl_schedule_constraints object for computing a schedule + * on "domain". The initial object does not impose any constraints. + */ +__isl_give isl_schedule_constraints *isl_schedule_constraints_on_domain( + __isl_take isl_union_set *domain) +{ + isl_ctx *ctx; + isl_schedule_constraints *sc; + + if (!domain) + return NULL; + + ctx = isl_union_set_get_ctx(domain); + sc = isl_schedule_constraints_alloc(ctx); + if (!sc) + goto error; + + sc->domain = domain; + return isl_schedule_constraints_init(sc); +error: + isl_union_set_free(domain); + return NULL; +} + +/* Replace the domain of "sc" by "domain". + */ +static __isl_give isl_schedule_constraints *isl_schedule_constraints_set_domain( + __isl_take isl_schedule_constraints *sc, + __isl_take isl_union_set *domain) +{ + if (!sc || !domain) + goto error; + + isl_union_set_free(sc->domain); + sc->domain = domain; + + return sc; +error: + isl_schedule_constraints_free(sc); + isl_union_set_free(domain); + return NULL; +} + +/* Replace the context of "sc" by "context". + */ +__isl_give isl_schedule_constraints *isl_schedule_constraints_set_context( + __isl_take isl_schedule_constraints *sc, __isl_take isl_set *context) +{ + if (!sc || !context) + goto error; + + isl_set_free(sc->context); + sc->context = context; + + return sc; +error: + isl_schedule_constraints_free(sc); + isl_set_free(context); + return NULL; +} + +/* Replace the constraints of type "type" in "sc" by "c". + * + * First detect any equality constraints that may be implicit in "c" + * in order to try and improve the accuracy of the input (and therefore + * also the output) of the isl_set_coefficients calls + * that are eventually performed on (some of) these constraints. + */ +static __isl_give isl_schedule_constraints *isl_schedule_constraints_set( + __isl_take isl_schedule_constraints *sc, enum isl_edge_type type, + __isl_take isl_union_map *c) +{ + c = isl_union_map_detect_equalities(c); + if (!sc || !c) + goto error; + + isl_union_map_free(sc->constraint[type]); + sc->constraint[type] = c; + + return sc; +error: + isl_schedule_constraints_free(sc); + isl_union_map_free(c); + return NULL; +} + +/* Replace the validity constraints of "sc" by "validity". + */ +__isl_give isl_schedule_constraints *isl_schedule_constraints_set_validity( + __isl_take isl_schedule_constraints *sc, + __isl_take isl_union_map *validity) +{ + return isl_schedule_constraints_set(sc, isl_edge_validity, validity); +} + +/* Replace the coincidence constraints of "sc" by "coincidence". + */ +__isl_give isl_schedule_constraints *isl_schedule_constraints_set_coincidence( + __isl_take isl_schedule_constraints *sc, + __isl_take isl_union_map *coincidence) +{ + return isl_schedule_constraints_set(sc, isl_edge_coincidence, + coincidence); +} + +/* Replace the proximity constraints of "sc" by "proximity". + */ +__isl_give isl_schedule_constraints *isl_schedule_constraints_set_proximity( + __isl_take isl_schedule_constraints *sc, + __isl_take isl_union_map *proximity) +{ + return isl_schedule_constraints_set(sc, isl_edge_proximity, proximity); +} + +/* Replace the conditional validity constraints of "sc" by "condition" + * and "validity". + */ +__isl_give isl_schedule_constraints * +isl_schedule_constraints_set_conditional_validity( + __isl_take isl_schedule_constraints *sc, + __isl_take isl_union_map *condition, + __isl_take isl_union_map *validity) +{ + sc = isl_schedule_constraints_set(sc, isl_edge_condition, condition); + sc = isl_schedule_constraints_set(sc, isl_edge_conditional_validity, + validity); + return sc; +} + +__isl_null isl_schedule_constraints *isl_schedule_constraints_free( + __isl_take isl_schedule_constraints *sc) +{ + enum isl_edge_type i; + + if (!sc) + return NULL; + + isl_union_set_free(sc->domain); + isl_set_free(sc->context); + for (i = isl_edge_first; i <= isl_edge_last; ++i) + isl_union_map_free(sc->constraint[i]); + + free(sc); + + return NULL; +} + +isl_ctx *isl_schedule_constraints_get_ctx( + __isl_keep isl_schedule_constraints *sc) +{ + return sc ? isl_union_set_get_ctx(sc->domain) : NULL; +} + +/* Return the domain of "sc". + */ +__isl_give isl_union_set *isl_schedule_constraints_get_domain( + __isl_keep isl_schedule_constraints *sc) +{ + if (!sc) + return NULL; + + return isl_union_set_copy(sc->domain); +} + +/* Return the context of "sc". + */ +__isl_give isl_set *isl_schedule_constraints_get_context( + __isl_keep isl_schedule_constraints *sc) +{ + if (!sc) + return NULL; + + return isl_set_copy(sc->context); +} + +/* Return the constraints of type "type" in "sc". + */ +__isl_give isl_union_map *isl_schedule_constraints_get( + __isl_keep isl_schedule_constraints *sc, enum isl_edge_type type) +{ + if (!sc) + return NULL; + + return isl_union_map_copy(sc->constraint[type]); +} + +/* Return the validity constraints of "sc". + */ +__isl_give isl_union_map *isl_schedule_constraints_get_validity( + __isl_keep isl_schedule_constraints *sc) +{ + return isl_schedule_constraints_get(sc, isl_edge_validity); +} + +/* Return the coincidence constraints of "sc". + */ +__isl_give isl_union_map *isl_schedule_constraints_get_coincidence( + __isl_keep isl_schedule_constraints *sc) +{ + return isl_schedule_constraints_get(sc, isl_edge_coincidence); +} + +/* Return the proximity constraints of "sc". + */ +__isl_give isl_union_map *isl_schedule_constraints_get_proximity( + __isl_keep isl_schedule_constraints *sc) +{ + return isl_schedule_constraints_get(sc, isl_edge_proximity); +} + +/* Return the conditional validity constraints of "sc". + */ +__isl_give isl_union_map *isl_schedule_constraints_get_conditional_validity( + __isl_keep isl_schedule_constraints *sc) +{ + return isl_schedule_constraints_get(sc, isl_edge_conditional_validity); +} + +/* Return the conditions for the conditional validity constraints of "sc". + */ +__isl_give isl_union_map * +isl_schedule_constraints_get_conditional_validity_condition( + __isl_keep isl_schedule_constraints *sc) +{ + return isl_schedule_constraints_get(sc, isl_edge_condition); +} + +/* Add "c" to the constraints of type "type" in "sc". + */ +__isl_give isl_schedule_constraints *isl_schedule_constraints_add( + __isl_take isl_schedule_constraints *sc, enum isl_edge_type type, + __isl_take isl_union_map *c) +{ + if (!sc || !c) + goto error; + + c = isl_union_map_union(sc->constraint[type], c); + sc->constraint[type] = c; + if (!c) + return isl_schedule_constraints_free(sc); + + return sc; +error: + isl_schedule_constraints_free(sc); + isl_union_map_free(c); + return NULL; +} + +/* Can a schedule constraint of type "type" be tagged? + */ +static int may_be_tagged(enum isl_edge_type type) +{ + if (type == isl_edge_condition || type == isl_edge_conditional_validity) + return 1; + return 0; +} + +/* Apply "umap" to the domains of the wrapped relations + * inside the domain and range of "c". + * + * That is, for each map of the form + * + * [D -> S] -> [E -> T] + * + * in "c", apply "umap" to D and E. + * + * D is exposed by currying the relation to + * + * D -> [S -> [E -> T]] + * + * E is exposed by doing the same to the inverse of "c". + */ +static __isl_give isl_union_map *apply_factor_domain( + __isl_take isl_union_map *c, __isl_keep isl_union_map *umap) +{ + c = isl_union_map_curry(c); + c = isl_union_map_apply_domain(c, isl_union_map_copy(umap)); + c = isl_union_map_uncurry(c); + + c = isl_union_map_reverse(c); + c = isl_union_map_curry(c); + c = isl_union_map_apply_domain(c, isl_union_map_copy(umap)); + c = isl_union_map_uncurry(c); + c = isl_union_map_reverse(c); + + return c; +} + +/* Apply "umap" to domain and range of "c". + * If "tag" is set, then "c" may contain tags and then "umap" + * needs to be applied to the domains of the wrapped relations + * inside the domain and range of "c". + */ +static __isl_give isl_union_map *apply(__isl_take isl_union_map *c, + __isl_keep isl_union_map *umap, int tag) +{ + isl_union_map *t; + + if (tag) + t = isl_union_map_copy(c); + c = isl_union_map_apply_domain(c, isl_union_map_copy(umap)); + c = isl_union_map_apply_range(c, isl_union_map_copy(umap)); + if (!tag) + return c; + t = apply_factor_domain(t, umap); + c = isl_union_map_union(c, t); + return c; +} + +/* Apply "umap" to the domain of the schedule constraints "sc". + * + * The two sides of the various schedule constraints are adjusted + * accordingly. + */ +__isl_give isl_schedule_constraints *isl_schedule_constraints_apply( + __isl_take isl_schedule_constraints *sc, + __isl_take isl_union_map *umap) +{ + enum isl_edge_type i; + + if (!sc || !umap) + goto error; + + for (i = isl_edge_first; i <= isl_edge_last; ++i) { + int tag = may_be_tagged(i); + + sc->constraint[i] = apply(sc->constraint[i], umap, tag); + if (!sc->constraint[i]) + goto error; + } + sc->domain = isl_union_set_apply(sc->domain, umap); + if (!sc->domain) + return isl_schedule_constraints_free(sc); + + return sc; +error: + isl_schedule_constraints_free(sc); + isl_union_map_free(umap); + return NULL; +} + +/* An enumeration of the various keys that may appear in a YAML mapping + * of an isl_schedule_constraints object. + * The keys for the edge types are assumed to have the same values + * as the edge types in isl_edge_type. + */ +enum isl_sc_key { + isl_sc_key_error = -1, + isl_sc_key_validity = isl_edge_validity, + isl_sc_key_coincidence = isl_edge_coincidence, + isl_sc_key_condition = isl_edge_condition, + isl_sc_key_conditional_validity = isl_edge_conditional_validity, + isl_sc_key_proximity = isl_edge_proximity, + isl_sc_key_domain, + isl_sc_key_context, + isl_sc_key_end +}; + +/* Textual representations of the YAML keys for an isl_schedule_constraints + * object. + */ +static char *key_str[] = { + [isl_sc_key_validity] = "validity", + [isl_sc_key_coincidence] = "coincidence", + [isl_sc_key_condition] = "condition", + [isl_sc_key_conditional_validity] = "conditional_validity", + [isl_sc_key_proximity] = "proximity", + [isl_sc_key_domain] = "domain", + [isl_sc_key_context] = "context", +}; + +#undef BASE +#define BASE set +#include "print_yaml_field_templ.c" + +#undef BASE +#define BASE union_set +#include "print_yaml_field_templ.c" + +#undef BASE +#define BASE union_map +#include "print_yaml_field_templ.c" + +/* 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 = print_yaml_field_union_map(p, key_str[type], sc->constraint[type]); + + return 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); + + p = isl_printer_yaml_start_mapping(p); + p = print_yaml_field_union_set(p, key_str[isl_sc_key_domain], + sc->domain); + universe = isl_set_plain_is_universe(sc->context); + if (universe < 0) + return isl_printer_free(p); + if (!universe) + p = print_yaml_field_set(p, key_str[isl_sc_key_context], + sc->context); + p = print_constraint(p, sc, isl_edge_validity); + p = print_constraint(p, sc, isl_edge_proximity); + p = print_constraint(p, sc, isl_edge_coincidence); + p = print_constraint(p, sc, isl_edge_condition); + p = print_constraint(p, sc, isl_edge_conditional_validity); + p = isl_printer_yaml_end_mapping(p); + + return p; +} + +#undef BASE +#define BASE schedule_constraints +#include + +#undef KEY +#define KEY enum isl_sc_key +#undef KEY_ERROR +#define KEY_ERROR isl_sc_key_error +#undef KEY_END +#define KEY_END isl_sc_key_end +#undef KEY_STR +#define KEY_STR key_str +#undef KEY_EXTRACT +#define KEY_EXTRACT extract_key +#undef KEY_GET +#define KEY_GET get_key +#include "extract_key.c" + +#undef BASE +#define BASE set +#include "read_in_string_templ.c" + +#undef BASE +#define BASE union_set +#include "read_in_string_templ.c" + +#undef BASE +#define BASE union_map +#include "read_in_string_templ.c" + +/* Read an isl_schedule_constraints object from "s". + * + * Start off with an empty (invalid) isl_schedule_constraints object and + * then fill up the fields based on the input. + * The input needs to contain at least a description of the domain. + * The other fields are set to defaults by isl_schedule_constraints_init + * if they are not specified in the input. + */ +__isl_give isl_schedule_constraints *isl_stream_read_schedule_constraints( + isl_stream *s) +{ + isl_ctx *ctx; + isl_schedule_constraints *sc; + isl_bool more; + int domain_set = 0; + + if (isl_stream_yaml_read_start_mapping(s) < 0) + return NULL; + + ctx = isl_stream_get_ctx(s); + sc = isl_schedule_constraints_alloc(ctx); + while ((more = isl_stream_yaml_next(s)) == isl_bool_true) { + enum isl_sc_key key; + enum isl_edge_type type; + isl_set *context; + isl_union_set *domain; + isl_union_map *constraints; + + key = get_key(s); + if (isl_stream_yaml_next(s) < 0) + return isl_schedule_constraints_free(sc); + switch (key) { + case isl_sc_key_end: + case isl_sc_key_error: + return isl_schedule_constraints_free(sc); + case isl_sc_key_domain: + domain_set = 1; + domain = read_union_set(s); + sc = isl_schedule_constraints_set_domain(sc, domain); + if (!sc) + return NULL; + break; + case isl_sc_key_context: + context = read_set(s); + sc = isl_schedule_constraints_set_context(sc, context); + if (!sc) + return NULL; + break; + 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: + type = (enum isl_edge_type) key; + constraints = read_union_map(s); + sc = isl_schedule_constraints_set(sc, type, + constraints); + if (!sc) + return NULL; + break; + } + } + if (more < 0) + return isl_schedule_constraints_free(sc); + + if (isl_stream_yaml_read_end_mapping(s) < 0) + return isl_schedule_constraints_free(sc); + + if (!domain_set) { + isl_stream_error(s, NULL, "no domain specified"); + return isl_schedule_constraints_free(sc); + } + + return isl_schedule_constraints_init(sc); +} + +/* Read an isl_schedule_constraints object from the file "input". + */ +__isl_give isl_schedule_constraints *isl_schedule_constraints_read_from_file( + isl_ctx *ctx, FILE *input) +{ + struct isl_stream *s; + isl_schedule_constraints *sc; + + s = isl_stream_new_file(ctx, input); + if (!s) + return NULL; + sc = isl_stream_read_schedule_constraints(s); + isl_stream_free(s); + + return sc; +} + +#undef TYPE_BASE +#define TYPE_BASE schedule_constraints +#include "isl_read_from_str_templ.c" + +/* Align the parameters of the fields of "sc". + */ +__isl_give isl_schedule_constraints * +isl_schedule_constraints_align_params(__isl_take isl_schedule_constraints *sc) +{ + isl_space *space; + enum isl_edge_type i; + + if (!sc) + return NULL; + + space = isl_union_set_get_space(sc->domain); + space = isl_space_align_params(space, isl_set_get_space(sc->context)); + for (i = isl_edge_first; i <= isl_edge_last; ++i) + space = isl_space_align_params(space, + isl_union_map_get_space(sc->constraint[i])); + + for (i = isl_edge_first; i <= isl_edge_last; ++i) { + sc->constraint[i] = isl_union_map_align_params( + sc->constraint[i], isl_space_copy(space)); + if (!sc->constraint[i]) + space = isl_space_free(space); + } + sc->context = isl_set_align_params(sc->context, isl_space_copy(space)); + sc->domain = isl_union_set_align_params(sc->domain, space); + if (!sc->context || !sc->domain) + return isl_schedule_constraints_free(sc); + + return sc; +} + +/* Add the number of basic maps in "map" to *n. + */ +static isl_stat add_n_basic_map(__isl_take isl_map *map, void *user) +{ + int *n = user; + isl_size n_basic_map; + + n_basic_map = isl_map_n_basic_map(map); + *n += n_basic_map; + isl_map_free(map); + + return n_basic_map < 0 ? isl_stat_error : isl_stat_ok; +} + +/* Return the total number of isl_basic_maps in the constraints of "sc". + * Return -1 on error. + */ +int isl_schedule_constraints_n_basic_map( + __isl_keep isl_schedule_constraints *sc) +{ + enum isl_edge_type i; + int n = 0; + + if (!sc) + return -1; + for (i = isl_edge_first; i <= isl_edge_last; ++i) + if (isl_union_map_foreach_map(sc->constraint[i], + &add_n_basic_map, &n) < 0) + return -1; + + return n; +} + +/* Return the total number of isl_maps in the constraints of "sc". + */ +isl_size isl_schedule_constraints_n_map(__isl_keep isl_schedule_constraints *sc) +{ + enum isl_edge_type i; + int n = 0; + + for (i = isl_edge_first; i <= isl_edge_last; ++i) { + isl_size n_i; + + n_i = isl_union_map_n_map(sc->constraint[i]); + if (n_i < 0) + return isl_size_error; + n += n_i; + } + + return n; +} diff --git a/external/mit/isl/dist/isl_schedule_constraints.h b/external/mit/isl/dist/isl_schedule_constraints.h new file mode 100644 index 000000000000..8ec3864d5f4a --- /dev/null +++ b/external/mit/isl/dist/isl_schedule_constraints.h @@ -0,0 +1,31 @@ +#ifndef ISL_SCHEDULE_CONSTRAINTS_H +#define ISL_SCHEDULE_CONSTRAINTS_H + +#include + +enum isl_edge_type { + isl_edge_validity = 0, + isl_edge_first = isl_edge_validity, + isl_edge_coincidence, + isl_edge_condition, + isl_edge_conditional_validity, + isl_edge_proximity, + isl_edge_last = isl_edge_proximity, + isl_edge_local +}; + +__isl_give isl_schedule_constraints * +isl_schedule_constraints_align_params(__isl_take isl_schedule_constraints *sc); + +__isl_give isl_union_map *isl_schedule_constraints_get( + __isl_keep isl_schedule_constraints *sc, enum isl_edge_type type); +__isl_give isl_schedule_constraints *isl_schedule_constraints_add( + __isl_take isl_schedule_constraints *sc, enum isl_edge_type type, + __isl_take isl_union_map *c); + +int isl_schedule_constraints_n_basic_map( + __isl_keep isl_schedule_constraints *sc); +isl_size isl_schedule_constraints_n_map( + __isl_keep isl_schedule_constraints *sc); + +#endif diff --git a/external/mit/isl/dist/isl_schedule_node.c b/external/mit/isl/dist/isl_schedule_node.c new file mode 100644 index 000000000000..9d140e56e7d9 --- /dev/null +++ b/external/mit/isl/dist/isl_schedule_node.c @@ -0,0 +1,4964 @@ +/* + * Copyright 2013-2014 Ecole Normale Superieure + * Copyright 2014 INRIA Rocquencourt + * Copyright 2016 Sven Verdoolaege + * + * Use of this software is governed by the MIT license + * + * Written by Sven Verdoolaege, + * Ecole Normale Superieure, 45 rue d'Ulm, 75230 Paris, France + * and Inria Paris - Rocquencourt, Domaine de Voluceau - Rocquencourt, + * B.P. 105 - 78153 Le Chesnay, France + */ + +#include +#include +#include +#include +#include +#include +#include + +/* Create a new schedule node in the given schedule, point at the given + * tree with given ancestors and child positions. + * "child_pos" may be NULL if there are no ancestors. + */ +__isl_give isl_schedule_node *isl_schedule_node_alloc( + __isl_take isl_schedule *schedule, __isl_take isl_schedule_tree *tree, + __isl_take isl_schedule_tree_list *ancestors, int *child_pos) +{ + isl_ctx *ctx; + isl_schedule_node *node; + int i; + isl_size n; + + n = isl_schedule_tree_list_n_schedule_tree(ancestors); + if (!schedule || !tree || n < 0) + goto error; + if (n > 0 && !child_pos) + goto error; + ctx = isl_schedule_get_ctx(schedule); + node = isl_calloc_type(ctx, isl_schedule_node); + if (!node) + goto error; + node->ref = 1; + node->schedule = schedule; + node->tree = tree; + node->ancestors = ancestors; + node->child_pos = isl_alloc_array(ctx, int, n); + if (n && !node->child_pos) + return isl_schedule_node_free(node); + for (i = 0; i < n; ++i) + node->child_pos[i] = child_pos[i]; + + return node; +error: + isl_schedule_free(schedule); + isl_schedule_tree_free(tree); + isl_schedule_tree_list_free(ancestors); + return NULL; +} + +/* Return a pointer to the root of a schedule tree with as single + * node a domain node with the given domain. + */ +__isl_give isl_schedule_node *isl_schedule_node_from_domain( + __isl_take isl_union_set *domain) +{ + isl_schedule *schedule; + isl_schedule_node *node; + + schedule = isl_schedule_from_domain(domain); + node = isl_schedule_get_root(schedule); + isl_schedule_free(schedule); + + return node; +} + +/* Return a pointer to the root of a schedule tree with as single + * node a extension node with the given extension. + */ +__isl_give isl_schedule_node *isl_schedule_node_from_extension( + __isl_take isl_union_map *extension) +{ + isl_ctx *ctx; + isl_schedule *schedule; + isl_schedule_tree *tree; + isl_schedule_node *node; + + if (!extension) + return NULL; + + ctx = isl_union_map_get_ctx(extension); + tree = isl_schedule_tree_from_extension(extension); + schedule = isl_schedule_from_schedule_tree(ctx, tree); + node = isl_schedule_get_root(schedule); + isl_schedule_free(schedule); + + return node; +} + +/* Return the isl_ctx to which "node" belongs. + */ +isl_ctx *isl_schedule_node_get_ctx(__isl_keep isl_schedule_node *node) +{ + return node ? isl_schedule_get_ctx(node->schedule) : NULL; +} + +/* Return a pointer to the leaf of the schedule into which "node" points. + */ +__isl_keep isl_schedule_tree *isl_schedule_node_peek_leaf( + __isl_keep isl_schedule_node *node) +{ + return node ? isl_schedule_peek_leaf(node->schedule) : NULL; +} + +/* Return a copy of the leaf of the schedule into which "node" points. + */ +__isl_give isl_schedule_tree *isl_schedule_node_get_leaf( + __isl_keep isl_schedule_node *node) +{ + return isl_schedule_tree_copy(isl_schedule_node_peek_leaf(node)); +} + +/* Return the type of the node or isl_schedule_node_error on error. + */ +enum isl_schedule_node_type isl_schedule_node_get_type( + __isl_keep isl_schedule_node *node) +{ + return node ? isl_schedule_tree_get_type(node->tree) + : isl_schedule_node_error; +} + +/* Return the type of the parent of "node" or isl_schedule_node_error on error. + */ +enum isl_schedule_node_type isl_schedule_node_get_parent_type( + __isl_keep isl_schedule_node *node) +{ + isl_size n; + int pos; + int has_parent; + isl_schedule_tree *parent; + enum isl_schedule_node_type type; + + if (!node) + return isl_schedule_node_error; + has_parent = isl_schedule_node_has_parent(node); + if (has_parent < 0) + return isl_schedule_node_error; + if (!has_parent) + isl_die(isl_schedule_node_get_ctx(node), isl_error_invalid, + "node has no parent", return isl_schedule_node_error); + n = isl_schedule_tree_list_n_schedule_tree(node->ancestors); + if (n < 0) + return isl_schedule_node_error; + + pos = n - 1; + parent = isl_schedule_tree_list_get_schedule_tree(node->ancestors, pos); + type = isl_schedule_tree_get_type(parent); + isl_schedule_tree_free(parent); + + return type; +} + +/* Return a copy of the subtree that this node points to. + */ +__isl_give isl_schedule_tree *isl_schedule_node_get_tree( + __isl_keep isl_schedule_node *node) +{ + if (!node) + return NULL; + + return isl_schedule_tree_copy(node->tree); +} + +/* Return a copy of the schedule into which "node" points. + */ +__isl_give isl_schedule *isl_schedule_node_get_schedule( + __isl_keep isl_schedule_node *node) +{ + if (!node) + return NULL; + return isl_schedule_copy(node->schedule); +} + +/* Return a fresh copy of "node". + */ +__isl_give isl_schedule_node *isl_schedule_node_dup( + __isl_keep isl_schedule_node *node) +{ + if (!node) + return NULL; + + return isl_schedule_node_alloc(isl_schedule_copy(node->schedule), + isl_schedule_tree_copy(node->tree), + isl_schedule_tree_list_copy(node->ancestors), + node->child_pos); +} + +/* Return an isl_schedule_node that is equal to "node" and that has only + * a single reference. + */ +__isl_give isl_schedule_node *isl_schedule_node_cow( + __isl_take isl_schedule_node *node) +{ + if (!node) + return NULL; + + if (node->ref == 1) + return node; + node->ref--; + return isl_schedule_node_dup(node); +} + +/* Return a new reference to "node". + */ +__isl_give isl_schedule_node *isl_schedule_node_copy( + __isl_keep isl_schedule_node *node) +{ + if (!node) + return NULL; + + node->ref++; + return node; +} + +/* Free "node" and return NULL. + */ +__isl_null isl_schedule_node *isl_schedule_node_free( + __isl_take isl_schedule_node *node) +{ + if (!node) + return NULL; + if (--node->ref > 0) + return NULL; + + isl_schedule_tree_list_free(node->ancestors); + free(node->child_pos); + isl_schedule_tree_free(node->tree); + isl_schedule_free(node->schedule); + free(node); + + return NULL; +} + +/* Do "node1" and "node2" point to the same position in the same + * schedule? + */ +isl_bool isl_schedule_node_is_equal(__isl_keep isl_schedule_node *node1, + __isl_keep isl_schedule_node *node2) +{ + int i; + isl_size n1, n2; + + if (!node1 || !node2) + return isl_bool_error; + if (node1 == node2) + return isl_bool_true; + if (node1->schedule != node2->schedule) + return isl_bool_false; + + n1 = isl_schedule_node_get_tree_depth(node1); + n2 = isl_schedule_node_get_tree_depth(node2); + if (n1 < 0 || n2 < 0) + return isl_bool_error; + if (n1 != n2) + return isl_bool_false; + for (i = 0; i < n1; ++i) + if (node1->child_pos[i] != node2->child_pos[i]) + return isl_bool_false; + + return isl_bool_true; +} + +/* Return the number of outer schedule dimensions of "node" + * in its schedule tree. + * + * Return isl_size_error on error. + */ +isl_size isl_schedule_node_get_schedule_depth( + __isl_keep isl_schedule_node *node) +{ + int i; + isl_size n; + int depth = 0; + + if (!node) + return isl_size_error; + + n = isl_schedule_tree_list_n_schedule_tree(node->ancestors); + if (n < 0) + return isl_size_error; + for (i = n - 1; i >= 0; --i) { + isl_schedule_tree *tree; + isl_size n; + + tree = isl_schedule_tree_list_get_schedule_tree( + node->ancestors, i); + if (!tree) + return isl_size_error; + n = 0; + if (tree->type == isl_schedule_node_band) + n = isl_schedule_tree_band_n_member(tree); + depth += n; + isl_schedule_tree_free(tree); + if (n < 0) + return isl_size_error; + } + + return depth; +} + +/* Internal data structure for + * isl_schedule_node_get_prefix_schedule_union_pw_multi_aff + * + * "initialized" is set if the filter field has been initialized. + * If "universe_domain" is not set, then the collected filter is intersected + * 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. + * "prefix" collects all outer band partial schedules (if "collect_prefix" + * is set). If it is used, then it is initialized by the caller + * of collect_filter_prefix to a zero-dimensional function. + */ +struct isl_schedule_node_get_filter_prefix_data { + int initialized; + int universe_domain; + int universe_filter; + int collect_prefix; + isl_union_set *filter; + isl_multi_union_pw_aff *prefix; +}; + +static isl_stat collect_filter_prefix(__isl_keep isl_schedule_tree_list *list, + int n, struct isl_schedule_node_get_filter_prefix_data *data); + +/* Update the filter and prefix information in "data" based on the first "n" + * elements in "list" and the expansion tree root "tree". + * + * We first collect the information from the elements in "list", + * initializing the filter based on the domain of the expansion. + * Then we map the results to the expanded space and combined them + * with the results already in "data". + */ +static isl_stat collect_filter_prefix_expansion( + __isl_take isl_schedule_tree *tree, + __isl_keep isl_schedule_tree_list *list, int n, + struct isl_schedule_node_get_filter_prefix_data *data) +{ + struct isl_schedule_node_get_filter_prefix_data contracted; + isl_union_pw_multi_aff *c; + isl_union_map *exp, *universe; + isl_union_set *filter; + + c = isl_schedule_tree_expansion_get_contraction(tree); + exp = isl_schedule_tree_expansion_get_expansion(tree); + + contracted.initialized = 1; + contracted.universe_domain = data->universe_domain; + contracted.universe_filter = data->universe_filter; + contracted.collect_prefix = data->collect_prefix; + universe = isl_union_map_universe(isl_union_map_copy(exp)); + filter = isl_union_map_domain(universe); + if (data->collect_prefix) { + isl_space *space = isl_union_set_get_space(filter); + space = isl_space_set_from_params(space); + contracted.prefix = isl_multi_union_pw_aff_zero(space); + } + contracted.filter = filter; + + if (collect_filter_prefix(list, n, &contracted) < 0) + contracted.filter = isl_union_set_free(contracted.filter); + if (data->collect_prefix) { + isl_multi_union_pw_aff *prefix; + + prefix = contracted.prefix; + prefix = + isl_multi_union_pw_aff_pullback_union_pw_multi_aff(prefix, + isl_union_pw_multi_aff_copy(c)); + data->prefix = isl_multi_union_pw_aff_flat_range_product( + prefix, data->prefix); + } + filter = contracted.filter; + if (data->universe_domain) + filter = isl_union_set_preimage_union_pw_multi_aff(filter, + isl_union_pw_multi_aff_copy(c)); + else + filter = isl_union_set_apply(filter, isl_union_map_copy(exp)); + if (!data->initialized) + data->filter = filter; + else + data->filter = isl_union_set_intersect(filter, data->filter); + data->initialized = 1; + + isl_union_pw_multi_aff_free(c); + isl_union_map_free(exp); + isl_schedule_tree_free(tree); + + return isl_stat_ok; +} + +/* Update the filter information in "data" based on the first "n" + * elements in "list" and the extension tree root "tree", in case + * data->universe_domain is set and data->collect_prefix is not. + * + * We collect the universe domain of the elements in "list" and + * add it to the universe range of the extension (intersected + * with the already collected filter, if any). + */ +static isl_stat collect_universe_domain_extension( + __isl_take isl_schedule_tree *tree, + __isl_keep isl_schedule_tree_list *list, int n, + struct isl_schedule_node_get_filter_prefix_data *data) +{ + struct isl_schedule_node_get_filter_prefix_data data_outer; + isl_union_map *extension; + isl_union_set *filter; + + data_outer.initialized = 0; + data_outer.universe_domain = 1; + data_outer.universe_filter = data->universe_filter; + data_outer.collect_prefix = 0; + data_outer.filter = NULL; + data_outer.prefix = NULL; + + if (collect_filter_prefix(list, n, &data_outer) < 0) + data_outer.filter = isl_union_set_free(data_outer.filter); + + extension = isl_schedule_tree_extension_get_extension(tree); + extension = isl_union_map_universe(extension); + filter = isl_union_map_range(extension); + if (data_outer.initialized) + filter = isl_union_set_union(filter, data_outer.filter); + if (data->initialized) + filter = isl_union_set_intersect(filter, data->filter); + + data->filter = filter; + + isl_schedule_tree_free(tree); + + return isl_stat_ok; +} + +/* Update "data" based on the tree node "tree" in case "data" has + * not been initialized yet. + * + * Return 0 on success and -1 on error. + * + * If "tree" is a filter, then we set data->filter to this filter + * (or its universe). + * If "tree" is a domain, then this means we have reached the root + * of the schedule tree without being able to extract any information. + * We therefore initialize data->filter to the universe of the domain, + * or the domain itself if data->universe_domain is not set. + * If "tree" is a band with at least one member, then we set data->filter + * to the universe of the schedule domain and replace the zero-dimensional + * data->prefix by the band schedule (if data->collect_prefix is set). + */ +static isl_stat collect_filter_prefix_init(__isl_keep isl_schedule_tree *tree, + struct isl_schedule_node_get_filter_prefix_data *data) +{ + enum isl_schedule_node_type type; + isl_multi_union_pw_aff *mupa; + isl_union_set *filter; + isl_size n; + + type = isl_schedule_tree_get_type(tree); + switch (type) { + case isl_schedule_node_error: + return isl_stat_error; + case isl_schedule_node_expansion: + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_internal, + "should be handled by caller", return isl_stat_error); + case isl_schedule_node_extension: + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid, + "cannot handle extension nodes", return isl_stat_error); + case isl_schedule_node_context: + case isl_schedule_node_leaf: + case isl_schedule_node_guard: + case isl_schedule_node_mark: + case isl_schedule_node_sequence: + case isl_schedule_node_set: + return isl_stat_ok; + case isl_schedule_node_domain: + filter = isl_schedule_tree_domain_get_domain(tree); + if (data->universe_domain) + filter = isl_union_set_universe(filter); + data->filter = filter; + break; + case isl_schedule_node_band: + n = isl_schedule_tree_band_n_member(tree); + if (n < 0) + return isl_stat_error; + if (n == 0) + return isl_stat_ok; + mupa = isl_schedule_tree_band_get_partial_schedule(tree); + if (data->collect_prefix) { + isl_multi_union_pw_aff_free(data->prefix); + mupa = isl_multi_union_pw_aff_reset_tuple_id(mupa, + isl_dim_set); + data->prefix = isl_multi_union_pw_aff_copy(mupa); + } + filter = isl_multi_union_pw_aff_domain(mupa); + filter = isl_union_set_universe(filter); + data->filter = filter; + break; + case isl_schedule_node_filter: + filter = isl_schedule_tree_filter_get_filter(tree); + if (data->universe_filter) + filter = isl_union_set_universe(filter); + data->filter = filter; + break; + } + + if ((data->collect_prefix && !data->prefix) || !data->filter) + return isl_stat_error; + + data->initialized = 1; + + return isl_stat_ok; +} + +/* Update "data" based on the tree node "tree" in case "data" has + * already been initialized. + * + * Return 0 on success and -1 on error. + * + * If "tree" is a domain and data->universe_domain is not set, then + * intersect data->filter with the domain. + * If "tree" is a filter, then we intersect data->filter with this filter + * (or its universe). + * If "tree" is a band with at least one member and data->collect_prefix + * is set, then we extend data->prefix with the band schedule. + * If "tree" is an extension, then we make sure that we are not collecting + * information on any extended domain elements. + */ +static isl_stat collect_filter_prefix_update(__isl_keep isl_schedule_tree *tree, + struct isl_schedule_node_get_filter_prefix_data *data) +{ + enum isl_schedule_node_type type; + isl_multi_union_pw_aff *mupa; + isl_union_set *filter; + isl_union_map *extension; + isl_bool empty; + isl_size n; + + type = isl_schedule_tree_get_type(tree); + switch (type) { + case isl_schedule_node_error: + return isl_stat_error; + case isl_schedule_node_expansion: + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_internal, + "should be handled by caller", return isl_stat_error); + case isl_schedule_node_extension: + extension = isl_schedule_tree_extension_get_extension(tree); + extension = isl_union_map_intersect_range(extension, + isl_union_set_copy(data->filter)); + empty = isl_union_map_is_empty(extension); + isl_union_map_free(extension); + if (empty < 0) + return isl_stat_error; + if (empty) + break; + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid, + "cannot handle extension nodes", return isl_stat_error); + case isl_schedule_node_context: + case isl_schedule_node_leaf: + case isl_schedule_node_guard: + case isl_schedule_node_mark: + case isl_schedule_node_sequence: + case isl_schedule_node_set: + break; + case isl_schedule_node_domain: + if (data->universe_domain) + break; + filter = isl_schedule_tree_domain_get_domain(tree); + data->filter = isl_union_set_intersect(data->filter, filter); + break; + case isl_schedule_node_band: + n = isl_schedule_tree_band_n_member(tree); + if (n < 0) + return isl_stat_error; + if (n == 0) + break; + if (!data->collect_prefix) + break; + mupa = isl_schedule_tree_band_get_partial_schedule(tree); + data->prefix = isl_multi_union_pw_aff_flat_range_product(mupa, + data->prefix); + if (!data->prefix) + return isl_stat_error; + break; + case isl_schedule_node_filter: + filter = isl_schedule_tree_filter_get_filter(tree); + if (data->universe_filter) + filter = isl_union_set_universe(filter); + data->filter = isl_union_set_intersect(data->filter, filter); + if (!data->filter) + return isl_stat_error; + break; + } + + return isl_stat_ok; +} + +/* Collect filter and/or prefix information from the first "n" + * elements in "list" (which represent the ancestors of a node). + * Store the results in "data". + * + * Extension nodes are only supported if they do not affect the outcome, + * i.e., if we are collecting information on non-extended domain elements, + * or if we are collecting the universe domain (without prefix). + * + * Return 0 on success and -1 on error. + * + * We traverse the list from innermost ancestor (last element) + * to outermost ancestor (first element), calling collect_filter_prefix_init + * on each node as long as we have not been able to extract any information + * yet and collect_filter_prefix_update afterwards. + * If we come across an expansion node, then we interrupt the traversal + * and call collect_filter_prefix_expansion to restart the traversal + * over the remaining ancestors and to combine the results with those + * that have already been collected. + * If we come across an extension node and we are only computing + * the universe domain, then we interrupt the traversal and call + * collect_universe_domain_extension to restart the traversal + * over the remaining ancestors and to combine the results with those + * that have already been collected. + * On successful return, data->initialized will be set since the outermost + * ancestor is a domain node, which always results in an initialization. + */ +static isl_stat collect_filter_prefix(__isl_keep isl_schedule_tree_list *list, + int n, struct isl_schedule_node_get_filter_prefix_data *data) +{ + int i; + + if (!list) + return isl_stat_error; + + for (i = n - 1; i >= 0; --i) { + isl_schedule_tree *tree; + enum isl_schedule_node_type type; + isl_stat r; + + tree = isl_schedule_tree_list_get_schedule_tree(list, i); + if (!tree) + return isl_stat_error; + type = isl_schedule_tree_get_type(tree); + if (type == isl_schedule_node_expansion) + return collect_filter_prefix_expansion(tree, list, i, + data); + if (type == isl_schedule_node_extension && + data->universe_domain && !data->collect_prefix) + return collect_universe_domain_extension(tree, list, i, + data); + if (!data->initialized) + r = collect_filter_prefix_init(tree, data); + else + r = collect_filter_prefix_update(tree, data); + isl_schedule_tree_free(tree); + if (r < 0) + return isl_stat_error; + } + + return isl_stat_ok; +} + +/* Return the concatenation of the partial schedules of all outer band + * nodes of "node" interesected with all outer filters + * as an isl_multi_union_pw_aff. + * None of the ancestors of "node" may be an extension node, unless + * there is also a filter ancestor that filters out all the extended + * domain elements. + * + * If "node" is pointing at the root of the schedule tree, then + * there are no domain elements reaching the current node, so + * we return an empty result. + * + * We collect all the filters and partial schedules in collect_filter_prefix + * and intersect the domain of the combined schedule with the combined filter. + */ +__isl_give isl_multi_union_pw_aff * +isl_schedule_node_get_prefix_schedule_multi_union_pw_aff( + __isl_keep isl_schedule_node *node) +{ + isl_size n; + isl_space *space; + struct isl_schedule_node_get_filter_prefix_data data; + + if (!node) + return NULL; + + space = isl_schedule_get_space(node->schedule); + space = isl_space_set_from_params(space); + if (node->tree == node->schedule->root) + return isl_multi_union_pw_aff_zero(space); + + data.initialized = 0; + data.universe_domain = 1; + data.universe_filter = 0; + data.collect_prefix = 1; + data.filter = NULL; + data.prefix = isl_multi_union_pw_aff_zero(space); + + n = isl_schedule_tree_list_n_schedule_tree(node->ancestors); + if (n < 0 || collect_filter_prefix(node->ancestors, n, &data) < 0) + data.prefix = isl_multi_union_pw_aff_free(data.prefix); + + data.prefix = isl_multi_union_pw_aff_intersect_domain(data.prefix, + data.filter); + + return data.prefix; +} + +/* Return the concatenation of the partial schedules of all outer band + * nodes of "node" interesected with all outer filters + * as an isl_union_pw_multi_aff. + * None of the ancestors of "node" may be an extension node, unless + * there is also a filter ancestor that filters out all the extended + * domain elements. + * + * If "node" is pointing at the root of the schedule tree, then + * there are no domain elements reaching the current node, so + * we return an empty result. + * + * We collect all the filters and partial schedules in collect_filter_prefix. + * The partial schedules are collected as an isl_multi_union_pw_aff. + * If this isl_multi_union_pw_aff is zero-dimensional, then it does not + * contain any domain information, so we construct the isl_union_pw_multi_aff + * result as a zero-dimensional function on the collected filter. + * Otherwise, we convert the isl_multi_union_pw_aff to + * an isl_multi_union_pw_aff and intersect the domain with the filter. + */ +__isl_give isl_union_pw_multi_aff * +isl_schedule_node_get_prefix_schedule_union_pw_multi_aff( + __isl_keep isl_schedule_node *node) +{ + isl_size n, dim; + isl_space *space; + isl_union_pw_multi_aff *prefix; + struct isl_schedule_node_get_filter_prefix_data data; + + if (!node) + return NULL; + + space = isl_schedule_get_space(node->schedule); + if (node->tree == node->schedule->root) + return isl_union_pw_multi_aff_empty(space); + + space = isl_space_set_from_params(space); + data.initialized = 0; + data.universe_domain = 1; + data.universe_filter = 0; + data.collect_prefix = 1; + data.filter = NULL; + data.prefix = isl_multi_union_pw_aff_zero(space); + + n = isl_schedule_tree_list_n_schedule_tree(node->ancestors); + if (n < 0 || collect_filter_prefix(node->ancestors, n, &data) < 0) + data.prefix = isl_multi_union_pw_aff_free(data.prefix); + + dim = isl_multi_union_pw_aff_dim(data.prefix, isl_dim_set); + if (dim < 0) + data.prefix = isl_multi_union_pw_aff_free(data.prefix); + if (data.prefix && dim == 0) { + isl_multi_union_pw_aff_free(data.prefix); + prefix = isl_union_pw_multi_aff_from_domain(data.filter); + } else { + prefix = + isl_union_pw_multi_aff_from_multi_union_pw_aff(data.prefix); + prefix = isl_union_pw_multi_aff_intersect_domain(prefix, + data.filter); + } + + return prefix; +} + +/* Return the concatenation of the partial schedules of all outer band + * nodes of "node" interesected with all outer filters + * as an isl_union_map. + */ +__isl_give isl_union_map *isl_schedule_node_get_prefix_schedule_union_map( + __isl_keep isl_schedule_node *node) +{ + isl_union_pw_multi_aff *upma; + + upma = isl_schedule_node_get_prefix_schedule_union_pw_multi_aff(node); + return isl_union_map_from_union_pw_multi_aff(upma); +} + +/* Return the concatenation of the partial schedules of all outer band + * nodes of "node" intersected with all outer domain constraints. + * None of the ancestors of "node" may be an extension node, unless + * there is also a filter ancestor that filters out all the extended + * domain elements. + * + * Essentially, this function intersects the domain of the output + * of isl_schedule_node_get_prefix_schedule_union_map with the output + * of isl_schedule_node_get_domain, except that it only traverses + * the ancestors of "node" once. + */ +__isl_give isl_union_map *isl_schedule_node_get_prefix_schedule_relation( + __isl_keep isl_schedule_node *node) +{ + isl_size n, dim; + isl_space *space; + isl_union_map *prefix; + struct isl_schedule_node_get_filter_prefix_data data; + + if (!node) + return NULL; + + space = isl_schedule_get_space(node->schedule); + if (node->tree == node->schedule->root) + return isl_union_map_empty(space); + + space = isl_space_set_from_params(space); + data.initialized = 0; + data.universe_domain = 0; + data.universe_filter = 0; + data.collect_prefix = 1; + data.filter = NULL; + data.prefix = isl_multi_union_pw_aff_zero(space); + + n = isl_schedule_tree_list_n_schedule_tree(node->ancestors); + if (n < 0 || collect_filter_prefix(node->ancestors, n, &data) < 0) + data.prefix = isl_multi_union_pw_aff_free(data.prefix); + + dim = isl_multi_union_pw_aff_dim(data.prefix, isl_dim_set); + if (dim < 0) + data.prefix = isl_multi_union_pw_aff_free(data.prefix); + if (data.prefix && dim == 0) { + isl_multi_union_pw_aff_free(data.prefix); + prefix = isl_union_map_from_domain(data.filter); + } else { + prefix = isl_union_map_from_multi_union_pw_aff(data.prefix); + prefix = isl_union_map_intersect_domain(prefix, data.filter); + } + + return prefix; +} + +/* Return the domain elements that reach "node". + * + * If "node" is pointing at the root of the schedule tree, then + * there are no domain elements reaching the current node, so + * we return an empty result. + * None of the ancestors of "node" may be an extension node, unless + * there is also a filter ancestor that filters out all the extended + * domain elements. + * + * Otherwise, we collect all filters reaching the node, + * intersected with the root domain in collect_filter_prefix. + */ +__isl_give isl_union_set *isl_schedule_node_get_domain( + __isl_keep isl_schedule_node *node) +{ + isl_size n; + struct isl_schedule_node_get_filter_prefix_data data; + + if (!node) + return NULL; + + if (node->tree == node->schedule->root) { + isl_space *space; + + space = isl_schedule_get_space(node->schedule); + return isl_union_set_empty(space); + } + + data.initialized = 0; + data.universe_domain = 0; + data.universe_filter = 0; + data.collect_prefix = 0; + data.filter = NULL; + data.prefix = NULL; + + n = isl_schedule_tree_list_n_schedule_tree(node->ancestors); + if (n < 0 || collect_filter_prefix(node->ancestors, n, &data) < 0) + data.filter = isl_union_set_free(data.filter); + + return data.filter; +} + +/* Return the union of universe sets of the domain elements that reach "node". + * + * If "node" is pointing at the root of the schedule tree, then + * there are no domain elements reaching the current node, so + * we return an empty result. + * + * Otherwise, we collect the universes of all filters reaching the node + * in collect_filter_prefix. + */ +__isl_give isl_union_set *isl_schedule_node_get_universe_domain( + __isl_keep isl_schedule_node *node) +{ + isl_size n; + struct isl_schedule_node_get_filter_prefix_data data; + + if (!node) + return NULL; + + if (node->tree == node->schedule->root) { + isl_space *space; + + space = isl_schedule_get_space(node->schedule); + return isl_union_set_empty(space); + } + + data.initialized = 0; + data.universe_domain = 1; + data.universe_filter = 1; + data.collect_prefix = 0; + data.filter = NULL; + data.prefix = NULL; + + n = isl_schedule_tree_list_n_schedule_tree(node->ancestors); + if (n < 0 || collect_filter_prefix(node->ancestors, n, &data) < 0) + data.filter = isl_union_set_free(data.filter); + + return data.filter; +} + +/* Return the subtree schedule of "node". + * + * Since isl_schedule_tree_get_subtree_schedule_union_map does not handle + * trees that do not contain any schedule information, we first + * move down to the first relevant descendant and handle leaves ourselves. + * + * If the subtree rooted at "node" contains any expansion nodes, then + * the returned subtree schedule is formulated in terms of the expanded + * domains. + * The subtree is not allowed to contain any extension nodes. + */ +__isl_give isl_union_map *isl_schedule_node_get_subtree_schedule_union_map( + __isl_keep isl_schedule_node *node) +{ + isl_schedule_tree *tree, *leaf; + isl_union_map *umap; + + tree = isl_schedule_node_get_tree(node); + leaf = isl_schedule_node_peek_leaf(node); + tree = isl_schedule_tree_first_schedule_descendant(tree, leaf); + if (!tree) + return NULL; + if (tree == leaf) { + isl_union_set *domain; + domain = isl_schedule_node_get_universe_domain(node); + isl_schedule_tree_free(tree); + return isl_union_map_from_domain(domain); + } + + umap = isl_schedule_tree_get_subtree_schedule_union_map(tree); + isl_schedule_tree_free(tree); + return umap; +} + +/* Return the number of ancestors of "node" in its schedule tree. + */ +isl_size isl_schedule_node_get_tree_depth(__isl_keep isl_schedule_node *node) +{ + if (!node) + return isl_size_error; + return isl_schedule_tree_list_n_schedule_tree(node->ancestors); +} + +/* Does "node" have a parent? + * + * That is, does it point to any node of the schedule other than the root? + */ +isl_bool isl_schedule_node_has_parent(__isl_keep isl_schedule_node *node) +{ + isl_size depth; + + depth = isl_schedule_node_get_tree_depth(node); + if (depth < 0) + return isl_bool_error; + return isl_bool_ok(depth != 0); +} + +/* Return the position of "node" among the children of its parent. + */ +isl_size isl_schedule_node_get_child_position( + __isl_keep isl_schedule_node *node) +{ + isl_size n; + isl_bool has_parent; + + if (!node) + return isl_size_error; + has_parent = isl_schedule_node_has_parent(node); + if (has_parent < 0) + return isl_size_error; + if (!has_parent) + isl_die(isl_schedule_node_get_ctx(node), isl_error_invalid, + "node has no parent", return isl_size_error); + + n = isl_schedule_tree_list_n_schedule_tree(node->ancestors); + return n < 0 ? isl_size_error : node->child_pos[n - 1]; +} + +/* Does the parent (if any) of "node" have any children with a smaller child + * position than this one? + */ +isl_bool isl_schedule_node_has_previous_sibling( + __isl_keep isl_schedule_node *node) +{ + isl_size n; + isl_bool has_parent; + + if (!node) + return isl_bool_error; + has_parent = isl_schedule_node_has_parent(node); + if (has_parent < 0 || !has_parent) + return has_parent; + + n = isl_schedule_tree_list_n_schedule_tree(node->ancestors); + if (n < 0) + return isl_bool_error; + + return isl_bool_ok(node->child_pos[n - 1] > 0); +} + +/* Does the parent (if any) of "node" have any children with a greater child + * position than this one? + */ +isl_bool isl_schedule_node_has_next_sibling(__isl_keep isl_schedule_node *node) +{ + isl_size n, n_child; + isl_bool has_parent; + isl_schedule_tree *tree; + + if (!node) + return isl_bool_error; + has_parent = isl_schedule_node_has_parent(node); + if (has_parent < 0 || !has_parent) + return has_parent; + + n = isl_schedule_tree_list_n_schedule_tree(node->ancestors); + if (n < 0) + return isl_bool_error; + tree = isl_schedule_tree_list_get_schedule_tree(node->ancestors, n - 1); + n_child = isl_schedule_tree_n_children(tree); + isl_schedule_tree_free(tree); + if (n_child < 0) + return isl_bool_error; + + return isl_bool_ok(node->child_pos[n - 1] + 1 < n_child); +} + +/* Does "node" have any children? + * + * Any node other than the leaf nodes is considered to have at least + * one child, even if the corresponding isl_schedule_tree does not + * have any children. + */ +isl_bool isl_schedule_node_has_children(__isl_keep isl_schedule_node *node) +{ + if (!node) + return isl_bool_error; + return isl_bool_ok(!isl_schedule_tree_is_leaf(node->tree)); +} + +/* Return the number of children of "node"? + * + * Any node other than the leaf nodes is considered to have at least + * one child, even if the corresponding isl_schedule_tree does not + * have any children. That is, the number of children of "node" is + * only zero if its tree is the explicit empty tree. Otherwise, + * if the isl_schedule_tree has any children, then it is equal + * to the number of children of "node". If it has zero children, + * then "node" still has a leaf node as child. + */ +isl_size isl_schedule_node_n_children(__isl_keep isl_schedule_node *node) +{ + isl_size n; + + if (!node) + return isl_size_error; + + if (isl_schedule_tree_is_leaf(node->tree)) + return 0; + + n = isl_schedule_tree_n_children(node->tree); + if (n < 0) + return isl_size_error; + if (n == 0) + return 1; + + return n; +} + +/* Move the "node" pointer to the ancestor of the given generation + * of the node it currently points to, where generation 0 is the node + * itself and generation 1 is its parent. + */ +__isl_give isl_schedule_node *isl_schedule_node_ancestor( + __isl_take isl_schedule_node *node, int generation) +{ + isl_size n; + isl_schedule_tree *tree; + + if (!node) + return NULL; + if (generation == 0) + return node; + n = isl_schedule_node_get_tree_depth(node); + if (n < 0) + return isl_schedule_node_free(node); + if (generation < 0 || generation > n) + isl_die(isl_schedule_node_get_ctx(node), isl_error_invalid, + "generation out of bounds", + return isl_schedule_node_free(node)); + node = isl_schedule_node_cow(node); + if (!node) + return NULL; + + tree = isl_schedule_tree_list_get_schedule_tree(node->ancestors, + n - generation); + isl_schedule_tree_free(node->tree); + node->tree = tree; + node->ancestors = isl_schedule_tree_list_drop(node->ancestors, + n - generation, generation); + if (!node->ancestors || !node->tree) + return isl_schedule_node_free(node); + + return node; +} + +/* Move the "node" pointer to the parent of the node it currently points to. + */ +__isl_give isl_schedule_node *isl_schedule_node_parent( + __isl_take isl_schedule_node *node) +{ + if (!node) + return NULL; + if (!isl_schedule_node_has_parent(node)) + isl_die(isl_schedule_node_get_ctx(node), isl_error_invalid, + "node has no parent", + return isl_schedule_node_free(node)); + return isl_schedule_node_ancestor(node, 1); +} + +/* Move the "node" pointer to the parent of its parent. + */ +__isl_give isl_schedule_node *isl_schedule_node_grandparent( + __isl_take isl_schedule_node *node) +{ + return isl_schedule_node_ancestor(node, 2); +} + +/* Move the "node" pointer to the root of its schedule tree. + */ +__isl_give isl_schedule_node *isl_schedule_node_root( + __isl_take isl_schedule_node *node) +{ + isl_size n; + + if (!node) + return NULL; + n = isl_schedule_node_get_tree_depth(node); + if (n < 0) + return isl_schedule_node_free(node); + return isl_schedule_node_ancestor(node, n); +} + +/* Move the "node" pointer to the child at position "pos" of the node + * it currently points to. + */ +__isl_give isl_schedule_node *isl_schedule_node_child( + __isl_take isl_schedule_node *node, int pos) +{ + isl_size n; + isl_ctx *ctx; + isl_schedule_tree *tree; + int *child_pos; + + node = isl_schedule_node_cow(node); + if (!node) + return NULL; + if (!isl_schedule_node_has_children(node)) + isl_die(isl_schedule_node_get_ctx(node), isl_error_invalid, + "node has no children", + return isl_schedule_node_free(node)); + + ctx = isl_schedule_node_get_ctx(node); + n = isl_schedule_tree_list_n_schedule_tree(node->ancestors); + if (n < 0) + return isl_schedule_node_free(node); + child_pos = isl_realloc_array(ctx, node->child_pos, int, n + 1); + if (!child_pos) + return isl_schedule_node_free(node); + node->child_pos = child_pos; + node->child_pos[n] = pos; + + node->ancestors = isl_schedule_tree_list_add(node->ancestors, + isl_schedule_tree_copy(node->tree)); + tree = node->tree; + if (isl_schedule_tree_has_children(tree)) + tree = isl_schedule_tree_get_child(tree, pos); + else + tree = isl_schedule_node_get_leaf(node); + isl_schedule_tree_free(node->tree); + node->tree = tree; + + if (!node->tree || !node->ancestors) + return isl_schedule_node_free(node); + + return node; +} + +/* Move the "node" pointer to the child at position "pos2" of the child + * at position "pos1". + */ +__isl_give isl_schedule_node *isl_schedule_node_grandchild( + __isl_take isl_schedule_node *node, int pos1, int pos2) +{ + node = isl_schedule_node_child(node, pos1); + node = isl_schedule_node_child(node, pos2); + return node; +} + +/* Move the "node" pointer to the first child of the node + * it currently points to. + */ +__isl_give isl_schedule_node *isl_schedule_node_first_child( + __isl_take isl_schedule_node *node) +{ + return isl_schedule_node_child(node, 0); +} + +/* Move the "node" pointer to the child of this node's parent in + * the previous child position. + */ +__isl_give isl_schedule_node *isl_schedule_node_previous_sibling( + __isl_take isl_schedule_node *node) +{ + isl_size n; + isl_schedule_tree *parent, *tree; + + node = isl_schedule_node_cow(node); + if (!node) + return NULL; + if (!isl_schedule_node_has_previous_sibling(node)) + isl_die(isl_schedule_node_get_ctx(node), isl_error_invalid, + "node has no previous sibling", + return isl_schedule_node_free(node)); + + n = isl_schedule_tree_list_n_schedule_tree(node->ancestors); + if (n < 0) + return isl_schedule_node_free(node); + parent = isl_schedule_tree_list_get_schedule_tree(node->ancestors, + n - 1); + if (!parent) + return isl_schedule_node_free(node); + node->child_pos[n - 1]--; + tree = isl_schedule_tree_list_get_schedule_tree(parent->children, + node->child_pos[n - 1]); + isl_schedule_tree_free(parent); + if (!tree) + return isl_schedule_node_free(node); + isl_schedule_tree_free(node->tree); + node->tree = tree; + + return node; +} + +/* Move the "node" pointer to the child of this node's parent in + * the next child position. + */ +__isl_give isl_schedule_node *isl_schedule_node_next_sibling( + __isl_take isl_schedule_node *node) +{ + isl_size n; + isl_schedule_tree *parent, *tree; + + node = isl_schedule_node_cow(node); + if (!node) + return NULL; + if (!isl_schedule_node_has_next_sibling(node)) + isl_die(isl_schedule_node_get_ctx(node), isl_error_invalid, + "node has no next sibling", + return isl_schedule_node_free(node)); + + n = isl_schedule_tree_list_n_schedule_tree(node->ancestors); + if (n < 0) + return isl_schedule_node_free(node); + parent = isl_schedule_tree_list_get_schedule_tree(node->ancestors, + n - 1); + if (!parent) + return isl_schedule_node_free(node); + node->child_pos[n - 1]++; + tree = isl_schedule_tree_list_get_schedule_tree(parent->children, + node->child_pos[n - 1]); + isl_schedule_tree_free(parent); + if (!tree) + return isl_schedule_node_free(node); + isl_schedule_tree_free(node->tree); + node->tree = tree; + + return node; +} + +/* Return a copy to the child at position "pos" of "node". + */ +__isl_give isl_schedule_node *isl_schedule_node_get_child( + __isl_keep isl_schedule_node *node, int pos) +{ + return isl_schedule_node_child(isl_schedule_node_copy(node), pos); +} + +/* Traverse the descendant of "node" in depth-first order, including + * "node" itself. Call "enter" whenever a node is entered and "leave" + * whenever a node is left. The callback "enter" is responsible + * for moving to the deepest initial subtree of its argument that + * should be traversed. + */ +static __isl_give isl_schedule_node *traverse( + __isl_take isl_schedule_node *node, + __isl_give isl_schedule_node *(*enter)( + __isl_take isl_schedule_node *node, void *user), + __isl_give isl_schedule_node *(*leave)( + __isl_take isl_schedule_node *node, void *user), + void *user) +{ + isl_size depth; + isl_size node_depth; + + depth = isl_schedule_node_get_tree_depth(node); + if (depth < 0) + return isl_schedule_node_free(node); + + do { + node = enter(node, user); + node = leave(node, user); + while ((node_depth = isl_schedule_node_get_tree_depth(node)) > + depth && + !isl_schedule_node_has_next_sibling(node)) { + node = isl_schedule_node_parent(node); + node = leave(node, user); + } + if (node_depth < 0) + return isl_schedule_node_free(node); + if (node_depth > depth) + node = isl_schedule_node_next_sibling(node); + } while (node_depth > depth); + + return node; +} + +/* Internal data structure for isl_schedule_node_foreach_descendant_top_down. + * + * "fn" is the user-specified callback function. + * "user" is the user-specified argument for the callback. + */ +struct isl_schedule_node_preorder_data { + isl_bool (*fn)(__isl_keep isl_schedule_node *node, void *user); + void *user; +}; + +/* Callback for "traverse" to enter a node and to move + * to the deepest initial subtree that should be traversed + * for use in a preorder visit. + * + * If the user callback returns a negative value, then we abort + * the traversal. If this callback returns zero, then we skip + * the subtree rooted at the current node. Otherwise, we move + * down to the first child and repeat the process until a leaf + * is reached. + */ +static __isl_give isl_schedule_node *preorder_enter( + __isl_take isl_schedule_node *node, void *user) +{ + struct isl_schedule_node_preorder_data *data = user; + + if (!node) + return NULL; + + do { + isl_bool r; + + r = data->fn(node, data->user); + if (r < 0) + return isl_schedule_node_free(node); + if (r == isl_bool_false) + return node; + } while (isl_schedule_node_has_children(node) && + (node = isl_schedule_node_first_child(node)) != NULL); + + return node; +} + +/* Callback for "traverse" to leave a node + * for use in a preorder visit. + * Since we already visited the node when we entered it, + * we do not need to do anything here. + */ +static __isl_give isl_schedule_node *preorder_leave( + __isl_take isl_schedule_node *node, void *user) +{ + return node; +} + +/* Traverse the descendants of "node" (including the node itself) + * in depth first preorder. + * + * 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 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, + isl_bool (*fn)(__isl_keep isl_schedule_node *node, void *user), + void *user) +{ + struct isl_schedule_node_preorder_data data = { fn, user }; + + node = isl_schedule_node_copy(node); + node = traverse(node, &preorder_enter, &preorder_leave, &data); + isl_schedule_node_free(node); + + 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. + * "user" is the user-specified argument for the callback. + */ +struct isl_schedule_node_postorder_data { + __isl_give isl_schedule_node *(*fn)(__isl_take isl_schedule_node *node, + void *user); + void *user; +}; + +/* Callback for "traverse" to enter a node and to move + * to the deepest initial subtree that should be traversed + * for use in a postorder visit. + * + * Since we are performing a postorder visit, we only need + * to move to the deepest initial leaf here. + */ +static __isl_give isl_schedule_node *postorder_enter( + __isl_take isl_schedule_node *node, void *user) +{ + while (node && isl_schedule_node_has_children(node)) + node = isl_schedule_node_first_child(node); + + return node; +} + +/* Callback for "traverse" to leave a node + * for use in a postorder visit. + * + * Since we are performing a postorder visit, we need + * to call the user callback here. + */ +static __isl_give isl_schedule_node *postorder_leave( + __isl_take isl_schedule_node *node, void *user) +{ + struct isl_schedule_node_postorder_data *data = user; + + return data->fn(node, data->user); +} + +/* Traverse the descendants of "node" (including the node itself) + * in depth first postorder, allowing the user to modify the visited node. + * The traversal continues from the node returned by the callback function. + * It is the responsibility of the user to ensure that this does not + * lead to an infinite loop. It is safest to always return a pointer + * to the same position (same ancestors and child positions) as the input node. + */ +__isl_give isl_schedule_node *isl_schedule_node_map_descendant_bottom_up( + __isl_take isl_schedule_node *node, + __isl_give isl_schedule_node *(*fn)(__isl_take isl_schedule_node *node, + void *user), void *user) +{ + struct isl_schedule_node_postorder_data data = { fn, user }; + + return traverse(node, &postorder_enter, &postorder_leave, &data); +} + +/* Traverse the ancestors of "node" from the root down to and including + * the parent of "node", calling "fn" on each of them. + * + * If "fn" returns -1 on any of the nodes, then the traversal is aborted. + * + * Return 0 on success and -1 on failure. + */ +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), + void *user) +{ + int i; + isl_size n; + + n = isl_schedule_node_get_tree_depth(node); + if (n < 0) + return isl_stat_error; + + for (i = 0; i < n; ++i) { + isl_schedule_node *ancestor; + isl_stat r; + + ancestor = isl_schedule_node_copy(node); + ancestor = isl_schedule_node_ancestor(ancestor, n - i); + r = fn(ancestor, user); + isl_schedule_node_free(ancestor); + if (r < 0) + return isl_stat_error; + } + + return isl_stat_ok; +} + +/* Is any node in the subtree rooted at "node" anchored? + * That is, do any of these nodes reference the outer band nodes? + */ +isl_bool isl_schedule_node_is_subtree_anchored( + __isl_keep isl_schedule_node *node) +{ + if (!node) + return isl_bool_error; + return isl_schedule_tree_is_subtree_anchored(node->tree); +} + +/* Return the number of members in the given band node. + */ +isl_size isl_schedule_node_band_n_member(__isl_keep isl_schedule_node *node) +{ + if (!node) + return isl_size_error; + return isl_schedule_tree_band_n_member(node->tree); +} + +/* Is the band member at position "pos" of the band node "node" + * marked coincident? + */ +isl_bool isl_schedule_node_band_member_get_coincident( + __isl_keep isl_schedule_node *node, int pos) +{ + if (!node) + return isl_bool_error; + return isl_schedule_tree_band_member_get_coincident(node->tree, pos); +} + +/* Mark the band member at position "pos" the band node "node" + * as being coincident or not according to "coincident". + */ +__isl_give isl_schedule_node *isl_schedule_node_band_member_set_coincident( + __isl_take isl_schedule_node *node, int pos, int coincident) +{ + int c; + isl_schedule_tree *tree; + + if (!node) + return NULL; + c = isl_schedule_node_band_member_get_coincident(node, pos); + if (c == coincident) + return node; + + tree = isl_schedule_tree_copy(node->tree); + tree = isl_schedule_tree_band_member_set_coincident(tree, pos, + coincident); + node = isl_schedule_node_graft_tree(node, tree); + + return node; +} + +/* Is the band node "node" marked permutable? + */ +isl_bool isl_schedule_node_band_get_permutable( + __isl_keep isl_schedule_node *node) +{ + if (!node) + return isl_bool_error; + + return isl_schedule_tree_band_get_permutable(node->tree); +} + +/* Mark the band node "node" permutable or not according to "permutable"? + */ +__isl_give isl_schedule_node *isl_schedule_node_band_set_permutable( + __isl_take isl_schedule_node *node, int permutable) +{ + isl_schedule_tree *tree; + + if (!node) + return NULL; + if (isl_schedule_node_band_get_permutable(node) == permutable) + return node; + + tree = isl_schedule_tree_copy(node->tree); + tree = isl_schedule_tree_band_set_permutable(tree, permutable); + node = isl_schedule_node_graft_tree(node, tree); + + return node; +} + +/* Return the schedule space of the band node. + */ +__isl_give isl_space *isl_schedule_node_band_get_space( + __isl_keep isl_schedule_node *node) +{ + if (!node) + return NULL; + + return isl_schedule_tree_band_get_space(node->tree); +} + +/* Return the schedule of the band node in isolation. + */ +__isl_give isl_multi_union_pw_aff *isl_schedule_node_band_get_partial_schedule( + __isl_keep isl_schedule_node *node) +{ + if (!node) + return NULL; + + return isl_schedule_tree_band_get_partial_schedule(node->tree); +} + +/* Return the schedule of the band node in isolation in the form of + * an isl_union_map. + * + * If the band does not have any members, then we construct a universe map + * with the universe of the domain elements reaching the node as domain. + * Otherwise, we extract an isl_multi_union_pw_aff representation and + * convert that to an isl_union_map. + */ +__isl_give isl_union_map *isl_schedule_node_band_get_partial_schedule_union_map( + __isl_keep isl_schedule_node *node) +{ + isl_size n; + isl_multi_union_pw_aff *mupa; + + if (!node) + return NULL; + + if (isl_schedule_node_get_type(node) != isl_schedule_node_band) + isl_die(isl_schedule_node_get_ctx(node), isl_error_invalid, + "not a band node", return NULL); + n = isl_schedule_node_band_n_member(node); + if (n < 0) + return NULL; + if (n == 0) { + isl_union_set *domain; + + domain = isl_schedule_node_get_universe_domain(node); + return isl_union_map_from_domain(domain); + } + + mupa = isl_schedule_node_band_get_partial_schedule(node); + return isl_union_map_from_multi_union_pw_aff(mupa); +} + +/* Return the loop AST generation type for the band member of band node "node" + * at position "pos". + */ +enum isl_ast_loop_type isl_schedule_node_band_member_get_ast_loop_type( + __isl_keep isl_schedule_node *node, int pos) +{ + if (!node) + return isl_ast_loop_error; + + return isl_schedule_tree_band_member_get_ast_loop_type(node->tree, pos); +} + +/* Set the loop AST generation type for the band member of band node "node" + * at position "pos" to "type". + */ +__isl_give isl_schedule_node *isl_schedule_node_band_member_set_ast_loop_type( + __isl_take isl_schedule_node *node, int pos, + enum isl_ast_loop_type type) +{ + isl_schedule_tree *tree; + + if (!node) + return NULL; + + tree = isl_schedule_tree_copy(node->tree); + tree = isl_schedule_tree_band_member_set_ast_loop_type(tree, pos, type); + return isl_schedule_node_graft_tree(node, tree); +} + +/* Return the loop AST generation type for the band member of band node "node" + * at position "pos" for the isolated part. + */ +enum isl_ast_loop_type isl_schedule_node_band_member_get_isolate_ast_loop_type( + __isl_keep isl_schedule_node *node, int pos) +{ + if (!node) + return isl_ast_loop_error; + + return isl_schedule_tree_band_member_get_isolate_ast_loop_type( + node->tree, pos); +} + +/* Set the loop AST generation type for the band member of band node "node" + * at position "pos" for the isolated part to "type". + */ +__isl_give isl_schedule_node * +isl_schedule_node_band_member_set_isolate_ast_loop_type( + __isl_take isl_schedule_node *node, int pos, + enum isl_ast_loop_type type) +{ + isl_schedule_tree *tree; + + if (!node) + return NULL; + + tree = isl_schedule_tree_copy(node->tree); + tree = isl_schedule_tree_band_member_set_isolate_ast_loop_type(tree, + pos, type); + return isl_schedule_node_graft_tree(node, tree); +} + +/* Return the AST build options associated to band node "node". + */ +__isl_give isl_union_set *isl_schedule_node_band_get_ast_build_options( + __isl_keep isl_schedule_node *node) +{ + if (!node) + return NULL; + + return isl_schedule_tree_band_get_ast_build_options(node->tree); +} + +/* Replace the AST build options associated to band node "node" by "options". + */ +__isl_give isl_schedule_node *isl_schedule_node_band_set_ast_build_options( + __isl_take isl_schedule_node *node, __isl_take isl_union_set *options) +{ + isl_schedule_tree *tree; + + if (!node || !options) + goto error; + + tree = isl_schedule_tree_copy(node->tree); + tree = isl_schedule_tree_band_set_ast_build_options(tree, options); + return isl_schedule_node_graft_tree(node, tree); +error: + isl_schedule_node_free(node); + isl_union_set_free(options); + return NULL; +} + +/* Return the "isolate" option associated to band node "node". + */ +__isl_give isl_set *isl_schedule_node_band_get_ast_isolate_option( + __isl_keep isl_schedule_node *node) +{ + isl_size depth; + + depth = isl_schedule_node_get_schedule_depth(node); + if (depth < 0) + return NULL; + + return isl_schedule_tree_band_get_ast_isolate_option(node->tree, depth); +} + +/* Make sure that that spaces of "node" and "mv" are the same. + * Return -1 on error, reporting the error to the user. + */ +static int check_space_multi_val(__isl_keep isl_schedule_node *node, + __isl_keep isl_multi_val *mv) +{ + isl_space *node_space, *mv_space; + int equal; + + node_space = isl_schedule_node_band_get_space(node); + mv_space = isl_multi_val_get_space(mv); + equal = isl_space_tuple_is_equal(node_space, isl_dim_set, + mv_space, isl_dim_set); + isl_space_free(mv_space); + isl_space_free(node_space); + if (equal < 0) + return -1; + if (!equal) + isl_die(isl_schedule_node_get_ctx(node), isl_error_invalid, + "spaces don't match", return -1); + + return 0; +} + +/* Multiply the partial schedule of the band node "node" + * with the factors in "mv". + */ +__isl_give isl_schedule_node *isl_schedule_node_band_scale( + __isl_take isl_schedule_node *node, __isl_take isl_multi_val *mv) +{ + isl_schedule_tree *tree; + int anchored; + + if (!node || !mv) + goto error; + if (check_space_multi_val(node, mv) < 0) + goto error; + anchored = isl_schedule_node_is_subtree_anchored(node); + if (anchored < 0) + goto error; + if (anchored) + isl_die(isl_schedule_node_get_ctx(node), isl_error_invalid, + "cannot scale band node with anchored subtree", + goto error); + + tree = isl_schedule_node_get_tree(node); + tree = isl_schedule_tree_band_scale(tree, mv); + return isl_schedule_node_graft_tree(node, tree); +error: + isl_multi_val_free(mv); + isl_schedule_node_free(node); + return NULL; +} + +/* Divide the partial schedule of the band node "node" + * by the factors in "mv". + */ +__isl_give isl_schedule_node *isl_schedule_node_band_scale_down( + __isl_take isl_schedule_node *node, __isl_take isl_multi_val *mv) +{ + isl_schedule_tree *tree; + int anchored; + + if (!node || !mv) + goto error; + if (check_space_multi_val(node, mv) < 0) + goto error; + anchored = isl_schedule_node_is_subtree_anchored(node); + if (anchored < 0) + goto error; + if (anchored) + isl_die(isl_schedule_node_get_ctx(node), isl_error_invalid, + "cannot scale down band node with anchored subtree", + goto error); + + tree = isl_schedule_node_get_tree(node); + tree = isl_schedule_tree_band_scale_down(tree, mv); + return isl_schedule_node_graft_tree(node, tree); +error: + isl_multi_val_free(mv); + isl_schedule_node_free(node); + return NULL; +} + +/* Reduce the partial schedule of the band node "node" + * modulo the factors in "mv". + */ +__isl_give isl_schedule_node *isl_schedule_node_band_mod( + __isl_take isl_schedule_node *node, __isl_take isl_multi_val *mv) +{ + isl_schedule_tree *tree; + isl_bool anchored; + + if (!node || !mv) + goto error; + if (check_space_multi_val(node, mv) < 0) + goto error; + anchored = isl_schedule_node_is_subtree_anchored(node); + if (anchored < 0) + goto error; + if (anchored) + isl_die(isl_schedule_node_get_ctx(node), isl_error_invalid, + "cannot perform mod on band node with anchored subtree", + goto error); + + tree = isl_schedule_node_get_tree(node); + tree = isl_schedule_tree_band_mod(tree, mv); + return isl_schedule_node_graft_tree(node, tree); +error: + isl_multi_val_free(mv); + isl_schedule_node_free(node); + return NULL; +} + +/* Make sure that that spaces of "node" and "mupa" are the same. + * Return isl_stat_error on error, reporting the error to the user. + */ +static isl_stat check_space_multi_union_pw_aff( + __isl_keep isl_schedule_node *node, + __isl_keep isl_multi_union_pw_aff *mupa) +{ + isl_space *node_space, *mupa_space; + isl_bool equal; + + node_space = isl_schedule_node_band_get_space(node); + mupa_space = isl_multi_union_pw_aff_get_space(mupa); + equal = isl_space_tuple_is_equal(node_space, isl_dim_set, + mupa_space, isl_dim_set); + isl_space_free(mupa_space); + isl_space_free(node_space); + if (equal < 0) + return isl_stat_error; + if (!equal) + isl_die(isl_schedule_node_get_ctx(node), isl_error_invalid, + "spaces don't match", return isl_stat_error); + + return isl_stat_ok; +} + +/* Shift the partial schedule of the band node "node" by "shift". + */ +__isl_give isl_schedule_node *isl_schedule_node_band_shift( + __isl_take isl_schedule_node *node, + __isl_take isl_multi_union_pw_aff *shift) +{ + isl_schedule_tree *tree; + int anchored; + + if (!node || !shift) + goto error; + if (check_space_multi_union_pw_aff(node, shift) < 0) + goto error; + anchored = isl_schedule_node_is_subtree_anchored(node); + if (anchored < 0) + goto error; + if (anchored) + isl_die(isl_schedule_node_get_ctx(node), isl_error_invalid, + "cannot shift band node with anchored subtree", + goto error); + + tree = isl_schedule_node_get_tree(node); + tree = isl_schedule_tree_band_shift(tree, shift); + return isl_schedule_node_graft_tree(node, tree); +error: + isl_multi_union_pw_aff_free(shift); + isl_schedule_node_free(node); + return NULL; +} + +/* Tile "node" with tile sizes "sizes". + * + * The current node is replaced by two nested nodes corresponding + * to the tile dimensions and the point dimensions. + * + * Return a pointer to the outer (tile) node. + * + * If any of the descendants of "node" depend on the set of outer band nodes, + * then we refuse to tile the node. + * + * 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) + */ +__isl_give isl_schedule_node *isl_schedule_node_band_tile( + __isl_take isl_schedule_node *node, __isl_take isl_multi_val *sizes) +{ + isl_schedule_tree *tree; + int anchored; + + if (!node || !sizes) + goto error; + anchored = isl_schedule_node_is_subtree_anchored(node); + if (anchored < 0) + goto error; + if (anchored) + isl_die(isl_schedule_node_get_ctx(node), isl_error_invalid, + "cannot tile band node with anchored subtree", + goto error); + + if (check_space_multi_val(node, sizes) < 0) + goto error; + + tree = isl_schedule_node_get_tree(node); + tree = isl_schedule_tree_band_tile(tree, sizes); + return isl_schedule_node_graft_tree(node, tree); +error: + isl_multi_val_free(sizes); + isl_schedule_node_free(node); + return NULL; +} + +/* Move the band node "node" down to all the leaves in the subtree + * rooted at "node". + * Return a pointer to the node in the resulting tree that is in the same + * position as the node pointed to by "node" in the original tree. + * + * If the node only has a leaf child, then nothing needs to be done. + * Otherwise, the child of the node is removed and the result is + * appended to all the leaves in the subtree rooted at the original child. + * Since the node is moved to the leaves, it needs to be expanded + * according to the expansion, if any, defined by that subtree. + * In the end, the original node is replaced by the result of + * attaching copies of the expanded node to the leaves. + * + * If any of the nodes in the subtree rooted at "node" depend on + * the set of outer band nodes then we refuse to sink the band node. + */ +__isl_give isl_schedule_node *isl_schedule_node_band_sink( + __isl_take isl_schedule_node *node) +{ + enum isl_schedule_node_type type; + isl_schedule_tree *tree, *child; + isl_union_pw_multi_aff *contraction; + isl_bool anchored; + isl_size n; + + if (!node) + return NULL; + + type = isl_schedule_node_get_type(node); + if (type != isl_schedule_node_band) + isl_die(isl_schedule_node_get_ctx(node), isl_error_invalid, + "not a band node", return isl_schedule_node_free(node)); + anchored = isl_schedule_node_is_subtree_anchored(node); + if (anchored < 0) + return isl_schedule_node_free(node); + if (anchored) + isl_die(isl_schedule_node_get_ctx(node), isl_error_invalid, + "cannot sink band node in anchored subtree", + return isl_schedule_node_free(node)); + n = isl_schedule_tree_n_children(node->tree); + if (n < 0) + return isl_schedule_node_free(node); + if (n == 0) + return node; + + contraction = isl_schedule_node_get_subtree_contraction(node); + + tree = isl_schedule_node_get_tree(node); + child = isl_schedule_tree_get_child(tree, 0); + tree = isl_schedule_tree_reset_children(tree); + tree = isl_schedule_tree_pullback_union_pw_multi_aff(tree, contraction); + tree = isl_schedule_tree_append_to_leaves(child, tree); + + return isl_schedule_node_graft_tree(node, tree); +} + +/* Split "node" into two nested band nodes, one with the first "pos" + * 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 two band nodes. + */ +__isl_give isl_schedule_node *isl_schedule_node_band_split( + __isl_take isl_schedule_node *node, int pos) +{ + isl_size depth; + isl_schedule_tree *tree; + + depth = isl_schedule_node_get_schedule_depth(node); + if (depth < 0) + return isl_schedule_node_free(node); + tree = isl_schedule_node_get_tree(node); + tree = isl_schedule_tree_band_split(tree, pos, depth); + return isl_schedule_node_graft_tree(node, tree); +} + +/* Return the context of the context node "node". + */ +__isl_give isl_set *isl_schedule_node_context_get_context( + __isl_keep isl_schedule_node *node) +{ + if (!node) + return NULL; + + return isl_schedule_tree_context_get_context(node->tree); +} + +/* Return the domain of the domain node "node". + */ +__isl_give isl_union_set *isl_schedule_node_domain_get_domain( + __isl_keep isl_schedule_node *node) +{ + if (!node) + return NULL; + + return isl_schedule_tree_domain_get_domain(node->tree); +} + +/* Return the expansion map of expansion node "node". + */ +__isl_give isl_union_map *isl_schedule_node_expansion_get_expansion( + __isl_keep isl_schedule_node *node) +{ + if (!node) + return NULL; + + return isl_schedule_tree_expansion_get_expansion(node->tree); +} + +/* Return the contraction of expansion node "node". + */ +__isl_give isl_union_pw_multi_aff *isl_schedule_node_expansion_get_contraction( + __isl_keep isl_schedule_node *node) +{ + if (!node) + return NULL; + + return isl_schedule_tree_expansion_get_contraction(node->tree); +} + +/* Replace the contraction and the expansion of the expansion node "node" + * by "contraction" and "expansion". + */ +__isl_give isl_schedule_node * +isl_schedule_node_expansion_set_contraction_and_expansion( + __isl_take isl_schedule_node *node, + __isl_take isl_union_pw_multi_aff *contraction, + __isl_take isl_union_map *expansion) +{ + isl_schedule_tree *tree; + + if (!node || !contraction || !expansion) + goto error; + + tree = isl_schedule_tree_copy(node->tree); + tree = isl_schedule_tree_expansion_set_contraction_and_expansion(tree, + contraction, expansion); + return isl_schedule_node_graft_tree(node, tree); +error: + isl_schedule_node_free(node); + isl_union_pw_multi_aff_free(contraction); + isl_union_map_free(expansion); + return NULL; +} + +/* Return the extension of the extension node "node". + */ +__isl_give isl_union_map *isl_schedule_node_extension_get_extension( + __isl_keep isl_schedule_node *node) +{ + if (!node) + return NULL; + + return isl_schedule_tree_extension_get_extension(node->tree); +} + +/* Replace the extension of extension node "node" by "extension". + */ +__isl_give isl_schedule_node *isl_schedule_node_extension_set_extension( + __isl_take isl_schedule_node *node, __isl_take isl_union_map *extension) +{ + isl_schedule_tree *tree; + + if (!node || !extension) + goto error; + + tree = isl_schedule_tree_copy(node->tree); + tree = isl_schedule_tree_extension_set_extension(tree, extension); + return isl_schedule_node_graft_tree(node, tree); +error: + isl_schedule_node_free(node); + isl_union_map_free(extension); + return NULL; +} + +/* Return the filter of the filter node "node". + */ +__isl_give isl_union_set *isl_schedule_node_filter_get_filter( + __isl_keep isl_schedule_node *node) +{ + if (!node) + return NULL; + + return isl_schedule_tree_filter_get_filter(node->tree); +} + +/* Replace the filter of filter node "node" by "filter". + */ +__isl_give isl_schedule_node *isl_schedule_node_filter_set_filter( + __isl_take isl_schedule_node *node, __isl_take isl_union_set *filter) +{ + isl_schedule_tree *tree; + + if (!node || !filter) + goto error; + + tree = isl_schedule_tree_copy(node->tree); + tree = isl_schedule_tree_filter_set_filter(tree, filter); + return isl_schedule_node_graft_tree(node, tree); +error: + isl_schedule_node_free(node); + isl_union_set_free(filter); + return NULL; +} + +/* Intersect the filter of filter node "node" with "filter". + * + * If the filter of the node is already a subset of "filter", + * then leave the node unchanged. + */ +__isl_give isl_schedule_node *isl_schedule_node_filter_intersect_filter( + __isl_take isl_schedule_node *node, __isl_take isl_union_set *filter) +{ + isl_union_set *node_filter = NULL; + isl_bool subset; + + if (!node || !filter) + goto error; + + node_filter = isl_schedule_node_filter_get_filter(node); + subset = isl_union_set_is_subset(node_filter, filter); + if (subset < 0) + goto error; + if (subset) { + isl_union_set_free(node_filter); + isl_union_set_free(filter); + return node; + } + node_filter = isl_union_set_intersect(node_filter, filter); + node = isl_schedule_node_filter_set_filter(node, node_filter); + return node; +error: + isl_schedule_node_free(node); + isl_union_set_free(node_filter); + isl_union_set_free(filter); + return NULL; +} + +/* Return the guard of the guard node "node". + */ +__isl_give isl_set *isl_schedule_node_guard_get_guard( + __isl_keep isl_schedule_node *node) +{ + if (!node) + return NULL; + + return isl_schedule_tree_guard_get_guard(node->tree); +} + +/* Return the mark identifier of the mark node "node". + */ +__isl_give isl_id *isl_schedule_node_mark_get_id( + __isl_keep isl_schedule_node *node) +{ + if (!node) + return NULL; + + return isl_schedule_tree_mark_get_id(node->tree); +} + +/* Check that "node" is a sequence node. + */ +static isl_stat check_is_sequence(__isl_keep isl_schedule_node *node) +{ + if (!node) + return isl_stat_error; + + if (isl_schedule_node_get_type(node) != isl_schedule_node_sequence) + isl_die(isl_schedule_node_get_ctx(node), isl_error_invalid, + "not a sequence node", return isl_stat_error); + + return isl_stat_ok; +} + +/* Replace the child at position "pos" of the sequence node "node" + * by the children of sequence root node of "tree". + */ +__isl_give isl_schedule_node *isl_schedule_node_sequence_splice( + __isl_take isl_schedule_node *node, int pos, + __isl_take isl_schedule_tree *tree) +{ + isl_schedule_tree *node_tree; + + if (check_is_sequence(node) < 0 || !tree) + goto error; + if (isl_schedule_tree_get_type(tree) != isl_schedule_node_sequence) + isl_die(isl_schedule_node_get_ctx(node), isl_error_invalid, + "not a sequence node", goto error); + node_tree = isl_schedule_node_get_tree(node); + node_tree = isl_schedule_tree_sequence_splice(node_tree, pos, tree); + node = isl_schedule_node_graft_tree(node, node_tree); + + return node; +error: + isl_schedule_node_free(node); + isl_schedule_tree_free(tree); + return NULL; +} + +/* Given a sequence node "node", with a child at position "pos" that + * is also a sequence node, attach the children of that node directly + * as children of "node" at that position, replacing the original child. + * + * The filters of these children are intersected with the filter + * of the child at position "pos". + */ +__isl_give isl_schedule_node *isl_schedule_node_sequence_splice_child( + __isl_take isl_schedule_node *node, int pos) +{ + int i; + isl_size n; + isl_union_set *filter; + isl_schedule_node *child; + isl_schedule_tree *tree; + + if (check_is_sequence(node) < 0) + return isl_schedule_node_free(node); + node = isl_schedule_node_grandchild(node, pos, 0); + if (check_is_sequence(node) < 0) + return isl_schedule_node_free(node); + n = isl_schedule_node_n_children(node); + if (n < 0) + return isl_schedule_node_free(node); + child = isl_schedule_node_copy(node); + node = isl_schedule_node_parent(node); + filter = isl_schedule_node_filter_get_filter(node); + for (i = 0; i < n; ++i) { + child = isl_schedule_node_child(child, i); + child = isl_schedule_node_filter_intersect_filter(child, + isl_union_set_copy(filter)); + child = isl_schedule_node_parent(child); + } + isl_union_set_free(filter); + tree = isl_schedule_node_get_tree(child); + isl_schedule_node_free(child); + node = isl_schedule_node_parent(node); + node = isl_schedule_node_sequence_splice(node, pos, tree); + + return node; +} + +/* Given a sequence node "node", for each child that is also + * (the parent of) a sequence node, attach the children of that node directly + * as children of "node" at the position of the child, + * replacing this original child. + * + * Since splicing in a child may change the positions of later children, + * iterate through the children from last to first. + */ +__isl_give isl_schedule_node *isl_schedule_node_sequence_splice_children( + __isl_take isl_schedule_node *node) +{ + int i; + isl_size n; + + if (check_is_sequence(node) < 0) + return isl_schedule_node_free(node); + n = isl_schedule_node_n_children(node); + if (n < 0) + return isl_schedule_node_free(node); + + for (i = n - 1; i >= 0; --i) { + enum isl_schedule_node_type type; + int is_seq; + + node = isl_schedule_node_grandchild(node, i, 0); + type = isl_schedule_node_get_type(node); + if (type < 0) + return isl_schedule_node_free(node); + is_seq = type == isl_schedule_node_sequence; + node = isl_schedule_node_grandparent(node); + + if (!is_seq) + continue; + + node = isl_schedule_node_sequence_splice_child(node, i); + } + + return node; +} + +/* Update the ancestors of "node" to point to the tree that "node" + * now points to. + * That is, replace the child in the original parent that corresponds + * to the current tree position by node->tree and continue updating + * the ancestors in the same way until the root is reached. + * + * If "fn" is not NULL, then it is called on each ancestor as we move up + * the tree so that it can modify the ancestor before it is added + * to the list of ancestors of the modified node. + * The additional "pos" argument records the position + * of the "tree" argument in the original schedule tree. + * + * If "node" originally points to a leaf of the schedule tree, then make sure + * that in the end it points to a leaf in the updated schedule tree. + */ +static __isl_give isl_schedule_node *update_ancestors( + __isl_take isl_schedule_node *node, + __isl_give isl_schedule_tree *(*fn)(__isl_take isl_schedule_tree *tree, + __isl_keep isl_schedule_node *pos, void *user), void *user) +{ + int i; + isl_size n; + int is_leaf; + isl_schedule_tree *tree; + isl_schedule_node *pos = NULL; + + if (fn) + pos = isl_schedule_node_copy(node); + + node = isl_schedule_node_cow(node); + if (!node) + return isl_schedule_node_free(pos); + + n = isl_schedule_tree_list_n_schedule_tree(node->ancestors); + if (n < 0) + return isl_schedule_node_free(pos); + tree = isl_schedule_tree_copy(node->tree); + + for (i = n - 1; i >= 0; --i) { + isl_schedule_tree *parent; + + parent = isl_schedule_tree_list_get_schedule_tree( + node->ancestors, i); + parent = isl_schedule_tree_replace_child(parent, + node->child_pos[i], tree); + if (fn) { + pos = isl_schedule_node_parent(pos); + parent = fn(parent, pos, user); + } + node->ancestors = isl_schedule_tree_list_set_schedule_tree( + node->ancestors, i, isl_schedule_tree_copy(parent)); + + tree = parent; + } + + if (fn) + isl_schedule_node_free(pos); + + is_leaf = isl_schedule_tree_is_leaf(node->tree); + node->schedule = isl_schedule_set_root(node->schedule, tree); + if (is_leaf) { + isl_schedule_tree_free(node->tree); + node->tree = isl_schedule_node_get_leaf(node); + } + + if (!node->schedule || !node->ancestors) + return isl_schedule_node_free(node); + + return node; +} + +/* Replace the subtree that "pos" points to by "tree", updating + * the ancestors to maintain a consistent state. + */ +__isl_give isl_schedule_node *isl_schedule_node_graft_tree( + __isl_take isl_schedule_node *pos, __isl_take isl_schedule_tree *tree) +{ + if (!tree || !pos) + goto error; + if (pos->tree == tree) { + isl_schedule_tree_free(tree); + return pos; + } + + pos = isl_schedule_node_cow(pos); + if (!pos) + goto error; + + isl_schedule_tree_free(pos->tree); + pos->tree = tree; + + return update_ancestors(pos, NULL, NULL); +error: + isl_schedule_node_free(pos); + isl_schedule_tree_free(tree); + return NULL; +} + +/* Make sure we can insert a node between "node" and its parent. + * Return -1 on error, reporting the reason why we cannot insert a node. + */ +static int check_insert(__isl_keep isl_schedule_node *node) +{ + int has_parent; + enum isl_schedule_node_type type; + + has_parent = isl_schedule_node_has_parent(node); + if (has_parent < 0) + return -1; + if (!has_parent) + isl_die(isl_schedule_node_get_ctx(node), isl_error_invalid, + "cannot insert node outside of root", return -1); + + type = isl_schedule_node_get_parent_type(node); + if (type == isl_schedule_node_error) + return -1; + if (type == isl_schedule_node_set || type == isl_schedule_node_sequence) + isl_die(isl_schedule_node_get_ctx(node), isl_error_invalid, + "cannot insert node between set or sequence node " + "and its filter children", return -1); + + return 0; +} + +/* Insert a band node with partial schedule "mupa" between "node" and + * its parent. + * Return a pointer to the new band node. + * + * If any of the nodes in the subtree rooted at "node" depend on + * the set of outer band nodes then we refuse to insert the band node. + */ +__isl_give isl_schedule_node *isl_schedule_node_insert_partial_schedule( + __isl_take isl_schedule_node *node, + __isl_take isl_multi_union_pw_aff *mupa) +{ + int anchored; + isl_schedule_band *band; + isl_schedule_tree *tree; + + if (check_insert(node) < 0) + node = isl_schedule_node_free(node); + anchored = isl_schedule_node_is_subtree_anchored(node); + if (anchored < 0) + goto error; + if (anchored) + isl_die(isl_schedule_node_get_ctx(node), isl_error_invalid, + "cannot insert band node in anchored subtree", + goto error); + + tree = isl_schedule_node_get_tree(node); + band = isl_schedule_band_from_multi_union_pw_aff(mupa); + tree = isl_schedule_tree_insert_band(tree, band); + node = isl_schedule_node_graft_tree(node, tree); + + return node; +error: + isl_schedule_node_free(node); + isl_multi_union_pw_aff_free(mupa); + return NULL; +} + +/* Insert a context node with context "context" between "node" and its parent. + * Return a pointer to the new context node. + */ +__isl_give isl_schedule_node *isl_schedule_node_insert_context( + __isl_take isl_schedule_node *node, __isl_take isl_set *context) +{ + isl_schedule_tree *tree; + + if (check_insert(node) < 0) + node = isl_schedule_node_free(node); + + tree = isl_schedule_node_get_tree(node); + tree = isl_schedule_tree_insert_context(tree, context); + node = isl_schedule_node_graft_tree(node, tree); + + return node; +} + +/* Insert an expansion node with the given "contraction" and "expansion" + * between "node" and its parent. + * Return a pointer to the new expansion node. + * + * Typically the domain and range spaces of the expansion are different. + * This means that only one of them can refer to the current domain space + * in a consistent tree. It is up to the caller to ensure that the tree + * returns to a consistent state. + */ +__isl_give isl_schedule_node *isl_schedule_node_insert_expansion( + __isl_take isl_schedule_node *node, + __isl_take isl_union_pw_multi_aff *contraction, + __isl_take isl_union_map *expansion) +{ + isl_schedule_tree *tree; + + if (check_insert(node) < 0) + node = isl_schedule_node_free(node); + + tree = isl_schedule_node_get_tree(node); + tree = isl_schedule_tree_insert_expansion(tree, contraction, expansion); + node = isl_schedule_node_graft_tree(node, tree); + + return node; +} + +/* Insert an extension node with extension "extension" between "node" and + * its parent. + * Return a pointer to the new extension node. + */ +__isl_give isl_schedule_node *isl_schedule_node_insert_extension( + __isl_take isl_schedule_node *node, + __isl_take isl_union_map *extension) +{ + isl_schedule_tree *tree; + + tree = isl_schedule_node_get_tree(node); + tree = isl_schedule_tree_insert_extension(tree, extension); + node = isl_schedule_node_graft_tree(node, tree); + + return node; +} + +/* Insert a filter node with filter "filter" between "node" and its parent. + * Return a pointer to the new filter node. + */ +__isl_give isl_schedule_node *isl_schedule_node_insert_filter( + __isl_take isl_schedule_node *node, __isl_take isl_union_set *filter) +{ + isl_schedule_tree *tree; + + if (check_insert(node) < 0) + node = isl_schedule_node_free(node); + + tree = isl_schedule_node_get_tree(node); + tree = isl_schedule_tree_insert_filter(tree, filter); + node = isl_schedule_node_graft_tree(node, tree); + + return node; +} + +/* Insert a guard node with guard "guard" between "node" and its parent. + * Return a pointer to the new guard node. + */ +__isl_give isl_schedule_node *isl_schedule_node_insert_guard( + __isl_take isl_schedule_node *node, __isl_take isl_set *guard) +{ + isl_schedule_tree *tree; + + if (check_insert(node) < 0) + node = isl_schedule_node_free(node); + + tree = isl_schedule_node_get_tree(node); + tree = isl_schedule_tree_insert_guard(tree, guard); + node = isl_schedule_node_graft_tree(node, tree); + + return node; +} + +/* Insert a mark node with mark identifier "mark" between "node" and + * its parent. + * Return a pointer to the new mark node. + */ +__isl_give isl_schedule_node *isl_schedule_node_insert_mark( + __isl_take isl_schedule_node *node, __isl_take isl_id *mark) +{ + isl_schedule_tree *tree; + + if (check_insert(node) < 0) + node = isl_schedule_node_free(node); + + tree = isl_schedule_node_get_tree(node); + tree = isl_schedule_tree_insert_mark(tree, mark); + node = isl_schedule_node_graft_tree(node, tree); + + return node; +} + +/* Attach the current subtree of "node" to a sequence of filter tree nodes + * with filters described by "filters", attach this sequence + * of filter tree nodes as children to a new tree of type "type" and + * replace the original subtree of "node" by this new tree. + * Each copy of the original subtree is simplified with respect + * to the corresponding filter. + */ +static __isl_give isl_schedule_node *isl_schedule_node_insert_children( + __isl_take isl_schedule_node *node, + enum isl_schedule_node_type type, + __isl_take isl_union_set_list *filters) +{ + int i; + isl_size n; + isl_ctx *ctx; + isl_schedule_tree *tree; + isl_schedule_tree_list *list; + + if (check_insert(node) < 0) + node = isl_schedule_node_free(node); + + n = isl_union_set_list_n_union_set(filters); + if (!node || n < 0) + goto error; + + ctx = isl_schedule_node_get_ctx(node); + list = isl_schedule_tree_list_alloc(ctx, n); + for (i = 0; i < n; ++i) { + isl_schedule_node *node_i; + isl_schedule_tree *tree; + isl_union_set *filter; + + filter = isl_union_set_list_get_union_set(filters, i); + node_i = isl_schedule_node_copy(node); + node_i = isl_schedule_node_gist(node_i, + isl_union_set_copy(filter)); + tree = isl_schedule_node_get_tree(node_i); + isl_schedule_node_free(node_i); + tree = isl_schedule_tree_insert_filter(tree, filter); + list = isl_schedule_tree_list_add(list, tree); + } + tree = isl_schedule_tree_from_children(type, list); + node = isl_schedule_node_graft_tree(node, tree); + + isl_union_set_list_free(filters); + return node; +error: + isl_union_set_list_free(filters); + isl_schedule_node_free(node); + return NULL; +} + +/* Insert a sequence node with child filters "filters" between "node" and + * its parent. That is, the tree that "node" points to is attached + * to each of the child nodes of the filter nodes. + * Return a pointer to the new sequence node. + */ +__isl_give isl_schedule_node *isl_schedule_node_insert_sequence( + __isl_take isl_schedule_node *node, + __isl_take isl_union_set_list *filters) +{ + return isl_schedule_node_insert_children(node, + isl_schedule_node_sequence, filters); +} + +/* Insert a set node with child filters "filters" between "node" and + * its parent. That is, the tree that "node" points to is attached + * to each of the child nodes of the filter nodes. + * Return a pointer to the new set node. + */ +__isl_give isl_schedule_node *isl_schedule_node_insert_set( + __isl_take isl_schedule_node *node, + __isl_take isl_union_set_list *filters) +{ + return isl_schedule_node_insert_children(node, + isl_schedule_node_set, filters); +} + +/* Remove "node" from its schedule tree and return a pointer + * to the leaf at the same position in the updated schedule tree. + * + * It is not allowed to remove the root of a schedule tree or + * a child of a set or sequence node. + */ +__isl_give isl_schedule_node *isl_schedule_node_cut( + __isl_take isl_schedule_node *node) +{ + isl_schedule_tree *leaf; + enum isl_schedule_node_type parent_type; + + if (!node) + return NULL; + if (!isl_schedule_node_has_parent(node)) + isl_die(isl_schedule_node_get_ctx(node), isl_error_invalid, + "cannot cut root", return isl_schedule_node_free(node)); + + parent_type = isl_schedule_node_get_parent_type(node); + if (parent_type == isl_schedule_node_set || + parent_type == isl_schedule_node_sequence) + isl_die(isl_schedule_node_get_ctx(node), isl_error_invalid, + "cannot cut child of set or sequence", + return isl_schedule_node_free(node)); + + leaf = isl_schedule_node_get_leaf(node); + return isl_schedule_node_graft_tree(node, leaf); +} + +/* Remove a single node from the schedule tree, attaching the child + * of "node" directly to its parent. + * Return a pointer to this former child or to the leaf the position + * of the original node if there was no child. + * It is not allowed to remove the root of a schedule tree, + * a set or sequence node, a child of a set or sequence node or + * a band node with an anchored subtree. + */ +__isl_give isl_schedule_node *isl_schedule_node_delete( + __isl_take isl_schedule_node *node) +{ + isl_size n, depth; + isl_schedule_tree *tree; + enum isl_schedule_node_type type; + + depth = isl_schedule_node_get_tree_depth(node); + n = isl_schedule_node_n_children(node); + if (depth < 0 || n < 0) + return isl_schedule_node_free(node); + + if (depth == 0) + isl_die(isl_schedule_node_get_ctx(node), isl_error_invalid, + "cannot delete root node", + return isl_schedule_node_free(node)); + if (n != 1) + isl_die(isl_schedule_node_get_ctx(node), isl_error_invalid, + "can only delete node with a single child", + return isl_schedule_node_free(node)); + type = isl_schedule_node_get_parent_type(node); + if (type == isl_schedule_node_sequence || type == isl_schedule_node_set) + isl_die(isl_schedule_node_get_ctx(node), isl_error_invalid, + "cannot delete child of set or sequence", + return isl_schedule_node_free(node)); + if (isl_schedule_node_get_type(node) == isl_schedule_node_band) { + int anchored; + + anchored = isl_schedule_node_is_subtree_anchored(node); + if (anchored < 0) + return isl_schedule_node_free(node); + if (anchored) + isl_die(isl_schedule_node_get_ctx(node), + isl_error_invalid, + "cannot delete band node with anchored subtree", + return isl_schedule_node_free(node)); + } + + tree = isl_schedule_node_get_tree(node); + if (!tree || isl_schedule_tree_has_children(tree)) { + tree = isl_schedule_tree_child(tree, 0); + } else { + isl_schedule_tree_free(tree); + tree = isl_schedule_node_get_leaf(node); + } + node = isl_schedule_node_graft_tree(node, tree); + + return node; +} + +/* Internal data structure for the group_ancestor callback. + * + * If "finished" is set, then we no longer need to modify + * any further ancestors. + * + * "contraction" and "expansion" represent the expansion + * that reflects the grouping. + * + * "domain" contains the domain elements that reach the position + * where the grouping is performed. That is, it is the range + * of the resulting expansion. + * "domain_universe" is the universe of "domain". + * "group" is the set of group elements, i.e., the domain + * of the resulting expansion. + * "group_universe" is the universe of "group". + * + * "sched" is the schedule for the group elements, in pratice + * an identity mapping on "group_universe". + * "dim" is the dimension of "sched". + */ +struct isl_schedule_group_data { + int finished; + + isl_union_map *expansion; + isl_union_pw_multi_aff *contraction; + + isl_union_set *domain; + isl_union_set *domain_universe; + isl_union_set *group; + isl_union_set *group_universe; + + int dim; + isl_multi_aff *sched; +}; + +/* Is domain covered by data->domain within data->domain_universe? + */ +static isl_bool locally_covered_by_domain(__isl_keep isl_union_set *domain, + struct isl_schedule_group_data *data) +{ + isl_bool is_subset; + isl_union_set *test; + + test = isl_union_set_copy(domain); + test = isl_union_set_intersect(test, + isl_union_set_copy(data->domain_universe)); + is_subset = isl_union_set_is_subset(test, data->domain); + isl_union_set_free(test); + + return is_subset; +} + +/* Update the band tree root "tree" to refer to the group instances + * in data->group rather than the original domain elements in data->domain. + * "pos" is the position in the original schedule tree where the modified + * "tree" will be attached. + * + * Add the part of the identity schedule on the group instances data->sched + * that corresponds to this band node to the band schedule. + * If the domain elements that reach the node and that are part + * of data->domain_universe are all elements of data->domain (and therefore + * replaced by the group instances) then this data->domain_universe + * is removed from the domain of the band schedule. + */ +static __isl_give isl_schedule_tree *group_band( + __isl_take isl_schedule_tree *tree, __isl_keep isl_schedule_node *pos, + struct isl_schedule_group_data *data) +{ + isl_union_set *domain; + isl_multi_aff *ma; + isl_multi_union_pw_aff *mupa, *partial; + isl_bool is_covered; + isl_size depth, n; + isl_bool has_id; + + domain = isl_schedule_node_get_domain(pos); + is_covered = locally_covered_by_domain(domain, data); + if (is_covered >= 0 && is_covered) { + domain = isl_union_set_universe(domain); + domain = isl_union_set_subtract(domain, + isl_union_set_copy(data->domain_universe)); + tree = isl_schedule_tree_band_intersect_domain(tree, domain); + } else + isl_union_set_free(domain); + if (is_covered < 0) + return isl_schedule_tree_free(tree); + depth = isl_schedule_node_get_schedule_depth(pos); + n = isl_schedule_tree_band_n_member(tree); + if (depth < 0 || n < 0) + return isl_schedule_tree_free(tree); + ma = isl_multi_aff_copy(data->sched); + ma = isl_multi_aff_drop_dims(ma, isl_dim_out, 0, depth); + ma = isl_multi_aff_drop_dims(ma, isl_dim_out, n, data->dim - depth - n); + mupa = isl_multi_union_pw_aff_from_multi_aff(ma); + partial = isl_schedule_tree_band_get_partial_schedule(tree); + has_id = isl_multi_union_pw_aff_has_tuple_id(partial, isl_dim_set); + if (has_id < 0) { + partial = isl_multi_union_pw_aff_free(partial); + } else if (has_id) { + isl_id *id; + id = isl_multi_union_pw_aff_get_tuple_id(partial, isl_dim_set); + mupa = isl_multi_union_pw_aff_set_tuple_id(mupa, + isl_dim_set, id); + } + partial = isl_multi_union_pw_aff_union_add(partial, mupa); + tree = isl_schedule_tree_band_set_partial_schedule(tree, partial); + + return tree; +} + +/* Drop the parameters in "uset" that are not also in "space". + * "n" is the number of parameters in "space". + */ +static __isl_give isl_union_set *union_set_drop_extra_params( + __isl_take isl_union_set *uset, __isl_keep isl_space *space, int n) +{ + isl_size n2; + + uset = isl_union_set_align_params(uset, isl_space_copy(space)); + n2 = isl_union_set_dim(uset, isl_dim_param); + if (n2 < 0) + return isl_union_set_free(uset); + uset = isl_union_set_project_out(uset, isl_dim_param, n, n2 - n); + + return uset; +} + +/* Update the context tree root "tree" to refer to the group instances + * in data->group rather than the original domain elements in data->domain. + * "pos" is the position in the original schedule tree where the modified + * "tree" will be attached. + * + * We do not actually need to update "tree" since a context node only + * refers to the schedule space. However, we may need to update "data" + * to not refer to any parameters introduced by the context node. + */ +static __isl_give isl_schedule_tree *group_context( + __isl_take isl_schedule_tree *tree, __isl_keep isl_schedule_node *pos, + struct isl_schedule_group_data *data) +{ + isl_space *space; + isl_union_set *domain; + isl_size n1, n2; + isl_bool involves; + isl_size depth; + + depth = isl_schedule_node_get_tree_depth(pos); + if (depth < 0) + return isl_schedule_tree_free(tree); + if (depth == 1) + return tree; + + domain = isl_schedule_node_get_universe_domain(pos); + space = isl_union_set_get_space(domain); + isl_union_set_free(domain); + + n1 = isl_space_dim(space, isl_dim_param); + data->expansion = isl_union_map_align_params(data->expansion, space); + n2 = isl_union_map_dim(data->expansion, isl_dim_param); + + if (n1 < 0 || n2 < 0) + return isl_schedule_tree_free(tree); + if (n1 == n2) + return tree; + + involves = isl_union_map_involves_dims(data->expansion, + isl_dim_param, n1, n2 - n1); + if (involves < 0) + return isl_schedule_tree_free(tree); + if (involves) + isl_die(isl_schedule_node_get_ctx(pos), isl_error_invalid, + "grouping cannot only refer to global parameters", + return isl_schedule_tree_free(tree)); + + data->expansion = isl_union_map_project_out(data->expansion, + isl_dim_param, n1, n2 - n1); + space = isl_union_map_get_space(data->expansion); + + data->contraction = isl_union_pw_multi_aff_align_params( + data->contraction, isl_space_copy(space)); + n2 = isl_union_pw_multi_aff_dim(data->contraction, isl_dim_param); + if (n2 < 0) + data->contraction = + isl_union_pw_multi_aff_free(data->contraction); + data->contraction = isl_union_pw_multi_aff_drop_dims(data->contraction, + isl_dim_param, n1, n2 - n1); + + data->domain = union_set_drop_extra_params(data->domain, space, n1); + data->domain_universe = + union_set_drop_extra_params(data->domain_universe, space, n1); + data->group = union_set_drop_extra_params(data->group, space, n1); + data->group_universe = + union_set_drop_extra_params(data->group_universe, space, n1); + + data->sched = isl_multi_aff_align_params(data->sched, + isl_space_copy(space)); + n2 = isl_multi_aff_dim(data->sched, isl_dim_param); + if (n2 < 0) + data->sched = isl_multi_aff_free(data->sched); + data->sched = isl_multi_aff_drop_dims(data->sched, + isl_dim_param, n1, n2 - n1); + + isl_space_free(space); + + return tree; +} + +/* Update the domain tree root "tree" to refer to the group instances + * in data->group rather than the original domain elements in data->domain. + * "pos" is the position in the original schedule tree where the modified + * "tree" will be attached. + * + * We first double-check that all grouped domain elements are actually + * part of the root domain and then replace those elements by the group + * instances. + */ +static __isl_give isl_schedule_tree *group_domain( + __isl_take isl_schedule_tree *tree, __isl_keep isl_schedule_node *pos, + struct isl_schedule_group_data *data) +{ + isl_union_set *domain; + isl_bool is_subset; + + domain = isl_schedule_tree_domain_get_domain(tree); + is_subset = isl_union_set_is_subset(data->domain, domain); + isl_union_set_free(domain); + if (is_subset < 0) + return isl_schedule_tree_free(tree); + if (!is_subset) + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_internal, + "grouped domain should be part of outer domain", + return isl_schedule_tree_free(tree)); + domain = isl_schedule_tree_domain_get_domain(tree); + domain = isl_union_set_subtract(domain, + isl_union_set_copy(data->domain)); + domain = isl_union_set_union(domain, isl_union_set_copy(data->group)); + tree = isl_schedule_tree_domain_set_domain(tree, domain); + + return tree; +} + +/* Update the expansion tree root "tree" to refer to the group instances + * in data->group rather than the original domain elements in data->domain. + * "pos" is the position in the original schedule tree where the modified + * "tree" will be attached. + * + * Let G_1 -> D_1 be the expansion of "tree" and G_2 -> D_2 the newly + * introduced expansion in a descendant of "tree". + * We first double-check that D_2 is a subset of D_1. + * Then we remove D_2 from the range of G_1 -> D_1 and add the mapping + * G_1 -> D_1 . D_2 -> G_2. + * Simmilarly, we restrict the domain of the contraction to the universe + * of the range of the updated expansion and add G_2 -> D_2 . D_1 -> G_1, + * attempting to remove the domain constraints of this additional part. + */ +static __isl_give isl_schedule_tree *group_expansion( + __isl_take isl_schedule_tree *tree, __isl_keep isl_schedule_node *pos, + struct isl_schedule_group_data *data) +{ + isl_union_set *domain; + isl_union_map *expansion, *umap; + isl_union_pw_multi_aff *contraction, *upma; + int is_subset; + + expansion = isl_schedule_tree_expansion_get_expansion(tree); + domain = isl_union_map_range(expansion); + is_subset = isl_union_set_is_subset(data->domain, domain); + isl_union_set_free(domain); + if (is_subset < 0) + return isl_schedule_tree_free(tree); + if (!is_subset) + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_internal, + "grouped domain should be part " + "of outer expansion domain", + return isl_schedule_tree_free(tree)); + expansion = isl_schedule_tree_expansion_get_expansion(tree); + umap = isl_union_map_from_union_pw_multi_aff( + isl_union_pw_multi_aff_copy(data->contraction)); + umap = isl_union_map_apply_range(expansion, umap); + expansion = isl_schedule_tree_expansion_get_expansion(tree); + expansion = isl_union_map_subtract_range(expansion, + isl_union_set_copy(data->domain)); + expansion = isl_union_map_union(expansion, umap); + umap = isl_union_map_universe(isl_union_map_copy(expansion)); + domain = isl_union_map_range(umap); + contraction = isl_schedule_tree_expansion_get_contraction(tree); + umap = isl_union_map_from_union_pw_multi_aff(contraction); + umap = isl_union_map_apply_range(isl_union_map_copy(data->expansion), + umap); + upma = isl_union_pw_multi_aff_from_union_map(umap); + contraction = isl_schedule_tree_expansion_get_contraction(tree); + contraction = isl_union_pw_multi_aff_intersect_domain(contraction, + domain); + domain = isl_union_pw_multi_aff_domain( + isl_union_pw_multi_aff_copy(upma)); + upma = isl_union_pw_multi_aff_gist(upma, domain); + contraction = isl_union_pw_multi_aff_union_add(contraction, upma); + tree = isl_schedule_tree_expansion_set_contraction_and_expansion(tree, + contraction, expansion); + + return tree; +} + +/* Update the tree root "tree" to refer to the group instances + * in data->group rather than the original domain elements in data->domain. + * "pos" is the position in the original schedule tree where the modified + * "tree" will be attached. + * + * If we have come across a domain or expansion node before (data->finished + * is set), then we no longer need perform any modifications. + * + * If "tree" is a filter, then we add data->group_universe to the filter. + * We also remove data->domain_universe from the filter if all the domain + * elements in this universe that reach the filter node are part of + * the elements that are being grouped by data->expansion. + * If "tree" is a band, domain or expansion, then it is handled + * in a separate function. + */ +static __isl_give isl_schedule_tree *group_ancestor( + __isl_take isl_schedule_tree *tree, __isl_keep isl_schedule_node *pos, + void *user) +{ + struct isl_schedule_group_data *data = user; + isl_union_set *domain; + isl_bool is_covered; + + if (!tree || !pos) + return isl_schedule_tree_free(tree); + + if (data->finished) + return tree; + + switch (isl_schedule_tree_get_type(tree)) { + case isl_schedule_node_error: + return isl_schedule_tree_free(tree); + case isl_schedule_node_extension: + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_unsupported, + "grouping not allowed in extended tree", + return isl_schedule_tree_free(tree)); + case isl_schedule_node_band: + tree = group_band(tree, pos, data); + break; + case isl_schedule_node_context: + tree = group_context(tree, pos, data); + break; + case isl_schedule_node_domain: + tree = group_domain(tree, pos, data); + data->finished = 1; + break; + case isl_schedule_node_filter: + domain = isl_schedule_node_get_domain(pos); + is_covered = locally_covered_by_domain(domain, data); + isl_union_set_free(domain); + if (is_covered < 0) + return isl_schedule_tree_free(tree); + domain = isl_schedule_tree_filter_get_filter(tree); + if (is_covered) + domain = isl_union_set_subtract(domain, + isl_union_set_copy(data->domain_universe)); + domain = isl_union_set_union(domain, + isl_union_set_copy(data->group_universe)); + tree = isl_schedule_tree_filter_set_filter(tree, domain); + break; + case isl_schedule_node_expansion: + tree = group_expansion(tree, pos, data); + data->finished = 1; + break; + case isl_schedule_node_leaf: + case isl_schedule_node_guard: + case isl_schedule_node_mark: + case isl_schedule_node_sequence: + case isl_schedule_node_set: + break; + } + + return tree; +} + +/* Group the domain elements that reach "node" into instances + * of a single statement with identifier "group_id". + * In particular, group the domain elements according to their + * prefix schedule. + * + * That is, introduce an expansion node with as contraction + * the prefix schedule (with the target space replaced by "group_id") + * and as expansion the inverse of this contraction (with its range + * intersected with the domain elements that reach "node"). + * The outer nodes are then modified to refer to the group instances + * instead of the original domain elements. + * + * No instance of "group_id" is allowed to reach "node" prior + * to the grouping. + * No ancestor of "node" is allowed to be an extension node. + * + * Return a pointer to original node in tree, i.e., the child + * of the newly introduced expansion node. + */ +__isl_give isl_schedule_node *isl_schedule_node_group( + __isl_take isl_schedule_node *node, __isl_take isl_id *group_id) +{ + struct isl_schedule_group_data data = { 0 }; + isl_space *space; + isl_union_set *domain; + isl_union_pw_multi_aff *contraction; + isl_union_map *expansion; + isl_bool disjoint; + isl_size depth; + + depth = isl_schedule_node_get_schedule_depth(node); + if (depth < 0 || !group_id) + goto error; + if (check_insert(node) < 0) + goto error; + + domain = isl_schedule_node_get_domain(node); + data.domain = isl_union_set_copy(domain); + data.domain_universe = isl_union_set_copy(domain); + data.domain_universe = isl_union_set_universe(data.domain_universe); + + data.dim = depth; + if (data.dim == 0) { + isl_ctx *ctx; + isl_set *set; + isl_union_set *group; + isl_union_map *univ; + + ctx = isl_schedule_node_get_ctx(node); + space = isl_space_set_alloc(ctx, 0, 0); + space = isl_space_set_tuple_id(space, isl_dim_set, group_id); + set = isl_set_universe(isl_space_copy(space)); + group = isl_union_set_from_set(set); + expansion = isl_union_map_from_domain_and_range(domain, group); + univ = isl_union_map_universe(isl_union_map_copy(expansion)); + contraction = isl_union_pw_multi_aff_from_union_map(univ); + expansion = isl_union_map_reverse(expansion); + } else { + isl_multi_union_pw_aff *prefix; + isl_union_set *univ; + + prefix = + isl_schedule_node_get_prefix_schedule_multi_union_pw_aff(node); + prefix = isl_multi_union_pw_aff_set_tuple_id(prefix, + isl_dim_set, group_id); + space = isl_multi_union_pw_aff_get_space(prefix); + contraction = isl_union_pw_multi_aff_from_multi_union_pw_aff( + prefix); + univ = isl_union_set_universe(isl_union_set_copy(domain)); + contraction = + isl_union_pw_multi_aff_intersect_domain(contraction, univ); + expansion = isl_union_map_from_union_pw_multi_aff( + isl_union_pw_multi_aff_copy(contraction)); + expansion = isl_union_map_reverse(expansion); + expansion = isl_union_map_intersect_range(expansion, domain); + } + space = isl_space_map_from_set(space); + data.sched = isl_multi_aff_identity(space); + data.group = isl_union_map_domain(isl_union_map_copy(expansion)); + data.group = isl_union_set_coalesce(data.group); + data.group_universe = isl_union_set_copy(data.group); + data.group_universe = isl_union_set_universe(data.group_universe); + data.expansion = isl_union_map_copy(expansion); + data.contraction = isl_union_pw_multi_aff_copy(contraction); + node = isl_schedule_node_insert_expansion(node, contraction, expansion); + + disjoint = isl_union_set_is_disjoint(data.domain_universe, + data.group_universe); + + node = update_ancestors(node, &group_ancestor, &data); + + isl_union_set_free(data.domain); + isl_union_set_free(data.domain_universe); + isl_union_set_free(data.group); + isl_union_set_free(data.group_universe); + isl_multi_aff_free(data.sched); + isl_union_map_free(data.expansion); + isl_union_pw_multi_aff_free(data.contraction); + + node = isl_schedule_node_child(node, 0); + + if (!node || disjoint < 0) + return isl_schedule_node_free(node); + if (!disjoint) + isl_die(isl_schedule_node_get_ctx(node), isl_error_invalid, + "group instances already reach node", + return isl_schedule_node_free(node)); + + return node; +error: + isl_schedule_node_free(node); + isl_id_free(group_id); + return NULL; +} + +/* Compute the gist of the given band node with respect to "context". + */ +__isl_give isl_schedule_node *isl_schedule_node_band_gist( + __isl_take isl_schedule_node *node, __isl_take isl_union_set *context) +{ + isl_schedule_tree *tree; + + tree = isl_schedule_node_get_tree(node); + tree = isl_schedule_tree_band_gist(tree, context); + return isl_schedule_node_graft_tree(node, tree); +} + +/* Internal data structure for isl_schedule_node_gist. + * "n_expansion" is the number of outer expansion nodes + * with respect to the current position + * "filters" contains an element for each outer filter, expansion or + * extension node with respect to the current position, each representing + * the intersection of the previous element and the filter on the filter node + * or the expansion/extension of the previous element. + * The first element in the original context passed to isl_schedule_node_gist. + */ +struct isl_node_gist_data { + int n_expansion; + isl_union_set_list *filters; +}; + +/* Enter the expansion node "node" during a isl_schedule_node_gist traversal. + * + * In particular, add an extra element to data->filters containing + * the expansion of the previous element and replace the expansion + * and contraction on "node" by the gist with respect to these filters. + * Also keep track of the fact that we have entered another expansion. + */ +static __isl_give isl_schedule_node *gist_enter_expansion( + __isl_take isl_schedule_node *node, struct isl_node_gist_data *data) +{ + isl_size n; + isl_union_set *inner; + isl_union_map *expansion; + isl_union_pw_multi_aff *contraction; + + data->n_expansion++; + + n = isl_union_set_list_n_union_set(data->filters); + if (n < 0) + return isl_schedule_node_free(node); + inner = isl_union_set_list_get_union_set(data->filters, n - 1); + expansion = isl_schedule_node_expansion_get_expansion(node); + inner = isl_union_set_apply(inner, expansion); + + contraction = isl_schedule_node_expansion_get_contraction(node); + contraction = isl_union_pw_multi_aff_gist(contraction, + isl_union_set_copy(inner)); + + data->filters = isl_union_set_list_add(data->filters, inner); + + inner = isl_union_set_list_get_union_set(data->filters, n - 1); + expansion = isl_schedule_node_expansion_get_expansion(node); + expansion = isl_union_map_gist_domain(expansion, inner); + node = isl_schedule_node_expansion_set_contraction_and_expansion(node, + contraction, expansion); + + return node; +} + +/* Leave the expansion node "node" during a isl_schedule_node_gist traversal. + * + * In particular, remove the element in data->filters that was added by + * gist_enter_expansion and decrement the number of outer expansions. + * + * The expansion has already been simplified in gist_enter_expansion. + * If this simplification results in an identity expansion, then + * it is removed here. + */ +static __isl_give isl_schedule_node *gist_leave_expansion( + __isl_take isl_schedule_node *node, struct isl_node_gist_data *data) +{ + isl_size n; + isl_bool identity; + isl_union_map *expansion; + + expansion = isl_schedule_node_expansion_get_expansion(node); + identity = isl_union_map_is_identity(expansion); + isl_union_map_free(expansion); + + if (identity < 0) + node = isl_schedule_node_free(node); + else if (identity) + node = isl_schedule_node_delete(node); + + n = isl_union_set_list_n_union_set(data->filters); + if (n < 0) + return isl_schedule_node_free(node); + data->filters = isl_union_set_list_drop(data->filters, n - 1, 1); + + data->n_expansion--; + + return node; +} + +/* Enter the extension node "node" during a isl_schedule_node_gist traversal. + * + * In particular, add an extra element to data->filters containing + * the union of the previous element with the additional domain elements + * introduced by the extension. + */ +static __isl_give isl_schedule_node *gist_enter_extension( + __isl_take isl_schedule_node *node, struct isl_node_gist_data *data) +{ + isl_size n; + isl_union_set *inner, *extra; + isl_union_map *extension; + + n = isl_union_set_list_n_union_set(data->filters); + if (n < 0) + return isl_schedule_node_free(node); + inner = isl_union_set_list_get_union_set(data->filters, n - 1); + extension = isl_schedule_node_extension_get_extension(node); + extra = isl_union_map_range(extension); + inner = isl_union_set_union(inner, extra); + + data->filters = isl_union_set_list_add(data->filters, inner); + + return node; +} + +/* Can we finish gisting at this node? + * That is, is the filter on the current filter node a subset of + * the original context passed to isl_schedule_node_gist? + * If we have gone through any expansions, then we cannot perform + * this test since the current domain elements are incomparable + * to the domain elements in the original context. + */ +static isl_bool gist_done(__isl_keep isl_schedule_node *node, + struct isl_node_gist_data *data) +{ + isl_union_set *filter, *outer; + isl_bool subset; + + if (data->n_expansion != 0) + return isl_bool_false; + + filter = isl_schedule_node_filter_get_filter(node); + outer = isl_union_set_list_get_union_set(data->filters, 0); + subset = isl_union_set_is_subset(filter, outer); + isl_union_set_free(outer); + isl_union_set_free(filter); + + return subset; +} + +/* Callback for "traverse" to enter a node and to move + * to the deepest initial subtree that should be traversed + * by isl_schedule_node_gist. + * + * The "filters" list is extended by one element each time + * we come across a filter node by the result of intersecting + * the last element in the list with the filter on the filter node. + * + * If the filter on the current filter node is a subset of + * the original context passed to isl_schedule_node_gist, + * then there is no need to go into its subtree since it cannot + * be further simplified by the context. The "filters" list is + * still extended for consistency, but the actual value of the + * added element is immaterial since it will not be used. + * + * Otherwise, the filter on the current filter node is replaced by + * the gist of the original filter with respect to the intersection + * of the original context with the intermediate filters. + * + * If the new element in the "filters" list is empty, then no elements + * can reach the descendants of the current filter node. The subtree + * underneath the filter node is therefore removed. + * + * Each expansion node we come across is handled by + * gist_enter_expansion. + * + * Each extension node we come across is handled by + * gist_enter_extension. + */ +static __isl_give isl_schedule_node *gist_enter( + __isl_take isl_schedule_node *node, void *user) +{ + struct isl_node_gist_data *data = user; + + do { + isl_union_set *filter, *inner; + isl_bool done, empty; + isl_size n; + + switch (isl_schedule_node_get_type(node)) { + case isl_schedule_node_error: + return isl_schedule_node_free(node); + case isl_schedule_node_expansion: + node = gist_enter_expansion(node, data); + continue; + case isl_schedule_node_extension: + node = gist_enter_extension(node, data); + continue; + case isl_schedule_node_band: + case isl_schedule_node_context: + case isl_schedule_node_domain: + case isl_schedule_node_guard: + case isl_schedule_node_leaf: + case isl_schedule_node_mark: + case isl_schedule_node_sequence: + case isl_schedule_node_set: + continue; + case isl_schedule_node_filter: + break; + } + done = gist_done(node, data); + filter = isl_schedule_node_filter_get_filter(node); + n = isl_union_set_list_n_union_set(data->filters); + if (n < 0 || done < 0 || done) { + data->filters = isl_union_set_list_add(data->filters, + filter); + if (n < 0 || done < 0) + return isl_schedule_node_free(node); + return node; + } + inner = isl_union_set_list_get_union_set(data->filters, n - 1); + filter = isl_union_set_gist(filter, isl_union_set_copy(inner)); + node = isl_schedule_node_filter_set_filter(node, + isl_union_set_copy(filter)); + filter = isl_union_set_intersect(filter, inner); + empty = isl_union_set_is_empty(filter); + data->filters = isl_union_set_list_add(data->filters, filter); + if (empty < 0) + return isl_schedule_node_free(node); + if (!empty) + continue; + node = isl_schedule_node_child(node, 0); + node = isl_schedule_node_cut(node); + node = isl_schedule_node_parent(node); + return node; + } while (isl_schedule_node_has_children(node) && + (node = isl_schedule_node_first_child(node)) != NULL); + + return node; +} + +/* Callback for "traverse" to leave a node for isl_schedule_node_gist. + * + * In particular, if the current node is a filter node, then we remove + * the element on the "filters" list that was added when we entered + * the node. There is no need to compute any gist here, since we + * already did that when we entered the node. + * + * Expansion nodes are handled by gist_leave_expansion. + * + * If the current node is an extension, then remove the element + * in data->filters that was added by gist_enter_extension. + * + * If the current node is a band node, then we compute the gist of + * the band node with respect to the intersection of the original context + * and the intermediate filters. + * + * If the current node is a sequence or set node, then some of + * the filter children may have become empty and so they are removed. + * If only one child is left, then the set or sequence node along with + * the single remaining child filter is removed. The filter can be + * removed because the filters on a sequence or set node are supposed + * to partition the incoming domain instances. + * In principle, it should then be impossible for there to be zero + * remaining children, but should this happen, we replace the entire + * subtree with an empty filter. + */ +static __isl_give isl_schedule_node *gist_leave( + __isl_take isl_schedule_node *node, void *user) +{ + struct isl_node_gist_data *data = user; + isl_schedule_tree *tree; + int i; + isl_size n; + isl_union_set *filter; + + switch (isl_schedule_node_get_type(node)) { + case isl_schedule_node_error: + return isl_schedule_node_free(node); + case isl_schedule_node_expansion: + node = gist_leave_expansion(node, data); + break; + case isl_schedule_node_extension: + case isl_schedule_node_filter: + n = isl_union_set_list_n_union_set(data->filters); + if (n < 0) + return isl_schedule_node_free(node); + data->filters = isl_union_set_list_drop(data->filters, + n - 1, 1); + break; + case isl_schedule_node_band: + n = isl_union_set_list_n_union_set(data->filters); + if (n < 0) + return isl_schedule_node_free(node); + filter = isl_union_set_list_get_union_set(data->filters, n - 1); + node = isl_schedule_node_band_gist(node, filter); + break; + case isl_schedule_node_set: + case isl_schedule_node_sequence: + tree = isl_schedule_node_get_tree(node); + n = isl_schedule_tree_n_children(tree); + if (n < 0) + tree = isl_schedule_tree_free(tree); + for (i = n - 1; i >= 0; --i) { + isl_schedule_tree *child; + isl_union_set *filter; + isl_bool empty; + + child = isl_schedule_tree_get_child(tree, i); + filter = isl_schedule_tree_filter_get_filter(child); + empty = isl_union_set_is_empty(filter); + isl_union_set_free(filter); + isl_schedule_tree_free(child); + if (empty < 0) + tree = isl_schedule_tree_free(tree); + else if (empty) + tree = isl_schedule_tree_drop_child(tree, i); + } + n = isl_schedule_tree_n_children(tree); + if (n < 0) + tree = isl_schedule_tree_free(tree); + node = isl_schedule_node_graft_tree(node, tree); + if (n == 1) { + node = isl_schedule_node_delete(node); + node = isl_schedule_node_delete(node); + } else if (n == 0) { + isl_space *space; + + filter = + isl_union_set_list_get_union_set(data->filters, 0); + space = isl_union_set_get_space(filter); + isl_union_set_free(filter); + filter = isl_union_set_empty(space); + node = isl_schedule_node_cut(node); + node = isl_schedule_node_insert_filter(node, filter); + } + break; + case isl_schedule_node_context: + case isl_schedule_node_domain: + case isl_schedule_node_guard: + case isl_schedule_node_leaf: + case isl_schedule_node_mark: + break; + } + + return node; +} + +/* Compute the gist of the subtree at "node" with respect to + * the reaching domain elements in "context". + * In particular, compute the gist of all band and filter nodes + * in the subtree with respect to "context". Children of set or sequence + * nodes that end up with an empty filter are removed completely. + * + * We keep track of the intersection of "context" with all outer filters + * of the current node within the subtree in the final element of "filters". + * Initially, this list contains the single element "context" and it is + * extended or shortened each time we enter or leave a filter node. + */ +__isl_give isl_schedule_node *isl_schedule_node_gist( + __isl_take isl_schedule_node *node, __isl_take isl_union_set *context) +{ + struct isl_node_gist_data data; + + data.n_expansion = 0; + data.filters = isl_union_set_list_from_union_set(context); + node = traverse(node, &gist_enter, &gist_leave, &data); + isl_union_set_list_free(data.filters); + return node; +} + +/* Intersect the domain of domain node "node" with "domain". + * + * If the domain of "node" is already a subset of "domain", + * then nothing needs to be changed. + * + * Otherwise, we replace the domain of the domain node by the intersection + * and simplify the subtree rooted at "node" with respect to this intersection. + */ +__isl_give isl_schedule_node *isl_schedule_node_domain_intersect_domain( + __isl_take isl_schedule_node *node, __isl_take isl_union_set *domain) +{ + isl_schedule_tree *tree; + isl_union_set *uset; + int is_subset; + + if (!node || !domain) + goto error; + + uset = isl_schedule_tree_domain_get_domain(node->tree); + is_subset = isl_union_set_is_subset(uset, domain); + isl_union_set_free(uset); + if (is_subset < 0) + goto error; + if (is_subset) { + isl_union_set_free(domain); + return node; + } + + tree = isl_schedule_tree_copy(node->tree); + uset = isl_schedule_tree_domain_get_domain(tree); + uset = isl_union_set_intersect(uset, domain); + tree = isl_schedule_tree_domain_set_domain(tree, + isl_union_set_copy(uset)); + node = isl_schedule_node_graft_tree(node, tree); + + node = isl_schedule_node_child(node, 0); + node = isl_schedule_node_gist(node, uset); + node = isl_schedule_node_parent(node); + + return node; +error: + isl_schedule_node_free(node); + isl_union_set_free(domain); + return NULL; +} + +/* Replace the domain of domain node "node" with the gist + * of the original domain with respect to the parameter domain "context". + */ +__isl_give isl_schedule_node *isl_schedule_node_domain_gist_params( + __isl_take isl_schedule_node *node, __isl_take isl_set *context) +{ + isl_union_set *domain; + isl_schedule_tree *tree; + + if (!node || !context) + goto error; + + tree = isl_schedule_tree_copy(node->tree); + domain = isl_schedule_tree_domain_get_domain(node->tree); + domain = isl_union_set_gist_params(domain, context); + tree = isl_schedule_tree_domain_set_domain(tree, domain); + node = isl_schedule_node_graft_tree(node, tree); + + return node; +error: + isl_schedule_node_free(node); + isl_set_free(context); + return NULL; +} + +/* Internal data structure for isl_schedule_node_get_subtree_expansion. + * "expansions" contains a list of accumulated expansions + * for each outer expansion, set or sequence node. The first element + * in the list is an identity mapping on the reaching domain elements. + * "res" collects the results. + */ +struct isl_subtree_expansion_data { + isl_union_map_list *expansions; + isl_union_map *res; +}; + +/* Callback for "traverse" to enter a node and to move + * to the deepest initial subtree that should be traversed + * by isl_schedule_node_get_subtree_expansion. + * + * Whenever we come across an expansion node, the last element + * of data->expansions is combined with the expansion + * on the expansion node. + * + * Whenever we come across a filter node that is the child + * of a set or sequence node, data->expansions is extended + * with a new element that restricts the previous element + * to the elements selected by the filter. + * The previous element can then be reused while backtracking. + */ +static __isl_give isl_schedule_node *subtree_expansion_enter( + __isl_take isl_schedule_node *node, void *user) +{ + struct isl_subtree_expansion_data *data = user; + + do { + enum isl_schedule_node_type type; + isl_union_set *filter; + isl_union_map *inner, *expansion; + isl_size n; + + switch (isl_schedule_node_get_type(node)) { + case isl_schedule_node_error: + return isl_schedule_node_free(node); + case isl_schedule_node_filter: + type = isl_schedule_node_get_parent_type(node); + if (type != isl_schedule_node_set && + type != isl_schedule_node_sequence) + break; + filter = isl_schedule_node_filter_get_filter(node); + n = isl_union_map_list_n_union_map(data->expansions); + if (n < 0) + data->expansions = + isl_union_map_list_free(data->expansions); + inner = + isl_union_map_list_get_union_map(data->expansions, + n - 1); + inner = isl_union_map_intersect_range(inner, filter); + data->expansions = + isl_union_map_list_add(data->expansions, inner); + break; + case isl_schedule_node_expansion: + n = isl_union_map_list_n_union_map(data->expansions); + if (n < 0) + data->expansions = + isl_union_map_list_free(data->expansions); + expansion = + isl_schedule_node_expansion_get_expansion(node); + inner = + isl_union_map_list_get_union_map(data->expansions, + n - 1); + inner = isl_union_map_apply_range(inner, expansion); + data->expansions = + isl_union_map_list_set_union_map(data->expansions, + n - 1, inner); + break; + case isl_schedule_node_band: + case isl_schedule_node_context: + case isl_schedule_node_domain: + case isl_schedule_node_extension: + case isl_schedule_node_guard: + case isl_schedule_node_leaf: + case isl_schedule_node_mark: + case isl_schedule_node_sequence: + case isl_schedule_node_set: + break; + } + } while (isl_schedule_node_has_children(node) && + (node = isl_schedule_node_first_child(node)) != NULL); + + return node; +} + +/* Callback for "traverse" to leave a node for + * isl_schedule_node_get_subtree_expansion. + * + * If we come across a filter node that is the child + * of a set or sequence node, then we remove the element + * of data->expansions that was added in subtree_expansion_enter. + * + * If we reach a leaf node, then the accumulated expansion is + * added to data->res. + */ +static __isl_give isl_schedule_node *subtree_expansion_leave( + __isl_take isl_schedule_node *node, void *user) +{ + struct isl_subtree_expansion_data *data = user; + isl_size n; + isl_union_map *inner; + enum isl_schedule_node_type type; + + switch (isl_schedule_node_get_type(node)) { + case isl_schedule_node_error: + return isl_schedule_node_free(node); + case isl_schedule_node_filter: + type = isl_schedule_node_get_parent_type(node); + if (type != isl_schedule_node_set && + type != isl_schedule_node_sequence) + break; + n = isl_union_map_list_n_union_map(data->expansions); + if (n < 0) + data->expansions = + isl_union_map_list_free(data->expansions); + data->expansions = isl_union_map_list_drop(data->expansions, + n - 1, 1); + break; + case isl_schedule_node_leaf: + n = isl_union_map_list_n_union_map(data->expansions); + if (n < 0) + data->expansions = + isl_union_map_list_free(data->expansions); + inner = isl_union_map_list_get_union_map(data->expansions, + n - 1); + data->res = isl_union_map_union(data->res, inner); + break; + case isl_schedule_node_band: + case isl_schedule_node_context: + case isl_schedule_node_domain: + case isl_schedule_node_expansion: + case isl_schedule_node_extension: + case isl_schedule_node_guard: + case isl_schedule_node_mark: + case isl_schedule_node_sequence: + case isl_schedule_node_set: + break; + } + + return node; +} + +/* Return a mapping from the domain elements that reach "node" + * to the corresponding domain elements in the leaves of the subtree + * rooted at "node" obtained by composing the intermediate expansions. + * + * We start out with an identity mapping between the domain elements + * that reach "node" and compose it with all the expansions + * on a path from "node" to a leaf while traversing the subtree. + * Within the children of an a sequence or set node, the + * accumulated expansion is restricted to the elements selected + * by the filter child. + */ +__isl_give isl_union_map *isl_schedule_node_get_subtree_expansion( + __isl_keep isl_schedule_node *node) +{ + struct isl_subtree_expansion_data data; + isl_space *space; + isl_union_set *domain; + isl_union_map *expansion; + + if (!node) + return NULL; + + domain = isl_schedule_node_get_universe_domain(node); + space = isl_union_set_get_space(domain); + expansion = isl_union_set_identity(domain); + data.res = isl_union_map_empty(space); + data.expansions = isl_union_map_list_from_union_map(expansion); + + node = isl_schedule_node_copy(node); + node = traverse(node, &subtree_expansion_enter, + &subtree_expansion_leave, &data); + if (!node) + data.res = isl_union_map_free(data.res); + isl_schedule_node_free(node); + + isl_union_map_list_free(data.expansions); + + return data.res; +} + +/* Internal data structure for isl_schedule_node_get_subtree_contraction. + * "contractions" contains a list of accumulated contractions + * for each outer expansion, set or sequence node. The first element + * in the list is an identity mapping on the reaching domain elements. + * "res" collects the results. + */ +struct isl_subtree_contraction_data { + isl_union_pw_multi_aff_list *contractions; + isl_union_pw_multi_aff *res; +}; + +/* Callback for "traverse" to enter a node and to move + * to the deepest initial subtree that should be traversed + * by isl_schedule_node_get_subtree_contraction. + * + * Whenever we come across an expansion node, the last element + * of data->contractions is combined with the contraction + * on the expansion node. + * + * Whenever we come across a filter node that is the child + * of a set or sequence node, data->contractions is extended + * with a new element that restricts the previous element + * to the elements selected by the filter. + * The previous element can then be reused while backtracking. + */ +static __isl_give isl_schedule_node *subtree_contraction_enter( + __isl_take isl_schedule_node *node, void *user) +{ + struct isl_subtree_contraction_data *data = user; + + do { + enum isl_schedule_node_type type; + isl_union_set *filter; + isl_union_pw_multi_aff *inner, *contraction; + isl_size n; + + switch (isl_schedule_node_get_type(node)) { + case isl_schedule_node_error: + return isl_schedule_node_free(node); + case isl_schedule_node_filter: + type = isl_schedule_node_get_parent_type(node); + if (type != isl_schedule_node_set && + type != isl_schedule_node_sequence) + break; + filter = isl_schedule_node_filter_get_filter(node); + n = isl_union_pw_multi_aff_list_n_union_pw_multi_aff( + data->contractions); + if (n < 0) + data->contractions = + isl_union_pw_multi_aff_list_free( + data->contractions); + inner = + isl_union_pw_multi_aff_list_get_union_pw_multi_aff( + data->contractions, n - 1); + inner = isl_union_pw_multi_aff_intersect_domain(inner, + filter); + data->contractions = + isl_union_pw_multi_aff_list_add(data->contractions, + inner); + break; + case isl_schedule_node_expansion: + n = isl_union_pw_multi_aff_list_n_union_pw_multi_aff( + data->contractions); + if (n < 0) + data->contractions = + isl_union_pw_multi_aff_list_free( + data->contractions); + contraction = + isl_schedule_node_expansion_get_contraction(node); + inner = + isl_union_pw_multi_aff_list_get_union_pw_multi_aff( + data->contractions, n - 1); + inner = + isl_union_pw_multi_aff_pullback_union_pw_multi_aff( + inner, contraction); + data->contractions = + isl_union_pw_multi_aff_list_set_union_pw_multi_aff( + data->contractions, n - 1, inner); + break; + case isl_schedule_node_band: + case isl_schedule_node_context: + case isl_schedule_node_domain: + case isl_schedule_node_extension: + case isl_schedule_node_guard: + case isl_schedule_node_leaf: + case isl_schedule_node_mark: + case isl_schedule_node_sequence: + case isl_schedule_node_set: + break; + } + } while (isl_schedule_node_has_children(node) && + (node = isl_schedule_node_first_child(node)) != NULL); + + return node; +} + +/* Callback for "traverse" to leave a node for + * isl_schedule_node_get_subtree_contraction. + * + * If we come across a filter node that is the child + * of a set or sequence node, then we remove the element + * of data->contractions that was added in subtree_contraction_enter. + * + * If we reach a leaf node, then the accumulated contraction is + * added to data->res. + */ +static __isl_give isl_schedule_node *subtree_contraction_leave( + __isl_take isl_schedule_node *node, void *user) +{ + struct isl_subtree_contraction_data *data = user; + isl_size n; + isl_union_pw_multi_aff *inner; + enum isl_schedule_node_type type; + + switch (isl_schedule_node_get_type(node)) { + case isl_schedule_node_error: + return isl_schedule_node_free(node); + case isl_schedule_node_filter: + type = isl_schedule_node_get_parent_type(node); + if (type != isl_schedule_node_set && + type != isl_schedule_node_sequence) + break; + n = isl_union_pw_multi_aff_list_n_union_pw_multi_aff( + data->contractions); + if (n < 0) + data->contractions = isl_union_pw_multi_aff_list_free( + data->contractions); + data->contractions = + isl_union_pw_multi_aff_list_drop(data->contractions, + n - 1, 1); + break; + case isl_schedule_node_leaf: + n = isl_union_pw_multi_aff_list_n_union_pw_multi_aff( + data->contractions); + if (n < 0) + data->contractions = isl_union_pw_multi_aff_list_free( + data->contractions); + inner = isl_union_pw_multi_aff_list_get_union_pw_multi_aff( + data->contractions, n - 1); + data->res = isl_union_pw_multi_aff_union_add(data->res, inner); + break; + case isl_schedule_node_band: + case isl_schedule_node_context: + case isl_schedule_node_domain: + case isl_schedule_node_expansion: + case isl_schedule_node_extension: + case isl_schedule_node_guard: + case isl_schedule_node_mark: + case isl_schedule_node_sequence: + case isl_schedule_node_set: + break; + } + + return node; +} + +/* Return a mapping from the domain elements in the leaves of the subtree + * rooted at "node" to the corresponding domain elements that reach "node" + * obtained by composing the intermediate contractions. + * + * We start out with an identity mapping between the domain elements + * that reach "node" and compose it with all the contractions + * on a path from "node" to a leaf while traversing the subtree. + * Within the children of an a sequence or set node, the + * accumulated contraction is restricted to the elements selected + * by the filter child. + */ +__isl_give isl_union_pw_multi_aff *isl_schedule_node_get_subtree_contraction( + __isl_keep isl_schedule_node *node) +{ + struct isl_subtree_contraction_data data; + isl_space *space; + isl_union_set *domain; + isl_union_pw_multi_aff *contraction; + + if (!node) + return NULL; + + domain = isl_schedule_node_get_universe_domain(node); + space = isl_union_set_get_space(domain); + contraction = isl_union_set_identity_union_pw_multi_aff(domain); + data.res = isl_union_pw_multi_aff_empty(space); + data.contractions = + isl_union_pw_multi_aff_list_from_union_pw_multi_aff(contraction); + + node = isl_schedule_node_copy(node); + node = traverse(node, &subtree_contraction_enter, + &subtree_contraction_leave, &data); + if (!node) + data.res = isl_union_pw_multi_aff_free(data.res); + isl_schedule_node_free(node); + + isl_union_pw_multi_aff_list_free(data.contractions); + + return data.res; +} + +/* Do the nearest "n" ancestors of "node" have the types given in "types" + * (starting at the parent of "node")? + */ +static isl_bool has_ancestors(__isl_keep isl_schedule_node *node, + int n, enum isl_schedule_node_type *types) +{ + int i; + isl_size n_ancestor; + + if (!node) + return isl_bool_error; + + n_ancestor = isl_schedule_tree_list_n_schedule_tree(node->ancestors); + if (n_ancestor < 0) + return isl_bool_error; + if (n_ancestor < n) + return isl_bool_false; + + for (i = 0; i < n; ++i) { + isl_schedule_tree *tree; + int correct_type; + + tree = isl_schedule_tree_list_get_schedule_tree(node->ancestors, + n_ancestor - 1 - i); + if (!tree) + return isl_bool_error; + correct_type = isl_schedule_tree_get_type(tree) == types[i]; + isl_schedule_tree_free(tree); + if (!correct_type) + return isl_bool_false; + } + + return isl_bool_true; +} + +/* Given a node "node" that appears in an extension (i.e., it is the child + * of a filter in a sequence inside an extension node), are the spaces + * of the extension specified by "extension" disjoint from those + * of both the original extension and the domain elements that reach + * that original extension? + */ +static isl_bool is_disjoint_extension(__isl_keep isl_schedule_node *node, + __isl_keep isl_union_map *extension) +{ + isl_union_map *old; + isl_union_set *domain; + isl_bool empty; + + node = isl_schedule_node_copy(node); + node = isl_schedule_node_ancestor(node, 3); + old = isl_schedule_node_extension_get_extension(node); + domain = isl_schedule_node_get_universe_domain(node); + isl_schedule_node_free(node); + old = isl_union_map_universe(old); + domain = isl_union_set_union(domain, isl_union_map_range(old)); + extension = isl_union_map_copy(extension); + extension = isl_union_map_intersect_range(extension, domain); + empty = isl_union_map_is_empty(extension); + isl_union_map_free(extension); + + return empty; +} + +/* Given a node "node" that is governed by an extension node, extend + * that extension node with "extension". + * + * In particular, "node" is the child of a filter in a sequence that + * is in turn a child of an extension node. Extend that extension node + * with "extension". + * + * Return a pointer to the parent of the original node (i.e., a filter). + */ +static __isl_give isl_schedule_node *extend_extension( + __isl_take isl_schedule_node *node, __isl_take isl_union_map *extension) +{ + isl_size pos; + isl_bool disjoint; + isl_union_map *node_extension; + + node = isl_schedule_node_parent(node); + pos = isl_schedule_node_get_child_position(node); + if (pos < 0) + node = isl_schedule_node_free(node); + node = isl_schedule_node_grandparent(node); + node_extension = isl_schedule_node_extension_get_extension(node); + disjoint = isl_union_map_is_disjoint(extension, node_extension); + extension = isl_union_map_union(extension, node_extension); + node = isl_schedule_node_extension_set_extension(node, extension); + node = isl_schedule_node_grandchild(node, 0, pos); + + if (disjoint < 0) + return isl_schedule_node_free(node); + if (!node) + return NULL; + if (!disjoint) + isl_die(isl_schedule_node_get_ctx(node), isl_error_invalid, + "extension domain should be disjoint from earlier " + "extensions", return isl_schedule_node_free(node)); + + return node; +} + +/* Return the universe of "uset" if this universe is disjoint from "ref". + * Otherwise, return "uset". + * + * Also check if "uset" itself is disjoint from "ref", reporting + * an error if it is not. + */ +static __isl_give isl_union_set *replace_by_universe_if_disjoint( + __isl_take isl_union_set *uset, __isl_keep isl_union_set *ref) +{ + int disjoint; + isl_union_set *universe; + + disjoint = isl_union_set_is_disjoint(uset, ref); + if (disjoint < 0) + return isl_union_set_free(uset); + if (!disjoint) + isl_die(isl_union_set_get_ctx(uset), isl_error_invalid, + "extension domain should be disjoint from " + "current domain", return isl_union_set_free(uset)); + + universe = isl_union_set_universe(isl_union_set_copy(uset)); + disjoint = isl_union_set_is_disjoint(universe, ref); + if (disjoint >= 0 && disjoint) { + isl_union_set_free(uset); + return universe; + } + isl_union_set_free(universe); + + if (disjoint < 0) + return isl_union_set_free(uset); + return uset; +} + +/* Insert an extension node on top of "node" with extension "extension". + * In addition, insert a filter that separates node from the extension + * between the extension node and "node". + * Return a pointer to the inserted filter node. + * + * If "node" already appears in an extension (i.e., if it is the child + * of a filter in a sequence inside an extension node), then extend that + * extension with "extension" instead. + * In this case, a pointer to the original filter node is returned. + * Note that if some of the elements in the new extension live in the + * same space as those of the original extension or the domain elements + * reaching the original extension, then we insert a new extension anyway. + * Otherwise, we would have to adjust the filters in the sequence child + * of the extension to ensure that the elements in the new extension + * are filtered out. + */ +static __isl_give isl_schedule_node *insert_extension( + __isl_take isl_schedule_node *node, __isl_take isl_union_map *extension) +{ + enum isl_schedule_node_type ancestors[] = + { isl_schedule_node_filter, isl_schedule_node_sequence, + isl_schedule_node_extension }; + isl_union_set *domain; + isl_union_set *filter; + isl_bool in_ext; + + in_ext = has_ancestors(node, 3, ancestors); + if (in_ext < 0) + goto error; + if (in_ext) { + isl_bool disjoint; + + disjoint = is_disjoint_extension(node, extension); + if (disjoint < 0) + goto error; + if (disjoint) + return extend_extension(node, extension); + } + + filter = isl_schedule_node_get_domain(node); + domain = isl_union_map_range(isl_union_map_copy(extension)); + filter = replace_by_universe_if_disjoint(filter, domain); + isl_union_set_free(domain); + + node = isl_schedule_node_insert_filter(node, filter); + node = isl_schedule_node_insert_extension(node, extension); + node = isl_schedule_node_child(node, 0); + return node; +error: + isl_schedule_node_free(node); + isl_union_map_free(extension); + return NULL; +} + +/* Replace the subtree that "node" points to by "tree" (which has + * a sequence root with two children), except if the parent of "node" + * is a sequence as well, in which case "tree" is spliced at the position + * of "node" in its parent. + * Return a pointer to the child of the "tree_pos" (filter) child of "tree" + * in the updated schedule tree. + */ +static __isl_give isl_schedule_node *graft_or_splice( + __isl_take isl_schedule_node *node, __isl_take isl_schedule_tree *tree, + int tree_pos) +{ + isl_size pos; + + if (isl_schedule_node_get_parent_type(node) == + isl_schedule_node_sequence) { + pos = isl_schedule_node_get_child_position(node); + if (pos < 0) + node = isl_schedule_node_free(node); + node = isl_schedule_node_parent(node); + node = isl_schedule_node_sequence_splice(node, pos, tree); + } else { + pos = 0; + node = isl_schedule_node_graft_tree(node, tree); + } + node = isl_schedule_node_grandchild(node, pos + tree_pos, 0); + + return node; +} + +/* Insert a node "graft" into the schedule tree of "node" such that it + * is executed before (if "before" is set) or after (if "before" is not set) + * the node that "node" points to. + * The root of "graft" is an extension node. + * Return a pointer to the node that "node" pointed to. + * + * We first insert an extension node on top of "node" (or extend + * the extension node if there already is one), with a filter on "node" + * separating it from the extension. + * We then insert a filter in the graft to separate it from the original + * domain elements and combine the original and new tree in a sequence. + * If we have extended an extension node, then the children of this + * sequence are spliced in the sequence of the extended extension + * at the position where "node" appears in the original extension. + * Otherwise, the sequence pair is attached to the new extension node. + */ +static __isl_give isl_schedule_node *graft_extension( + __isl_take isl_schedule_node *node, __isl_take isl_schedule_node *graft, + int before) +{ + isl_union_map *extension; + isl_union_set *graft_domain; + isl_union_set *node_domain; + isl_schedule_tree *tree, *tree_graft; + + extension = isl_schedule_node_extension_get_extension(graft); + graft_domain = isl_union_map_range(isl_union_map_copy(extension)); + node_domain = isl_schedule_node_get_universe_domain(node); + node = insert_extension(node, extension); + + graft_domain = replace_by_universe_if_disjoint(graft_domain, + node_domain); + isl_union_set_free(node_domain); + + tree = isl_schedule_node_get_tree(node); + if (!isl_schedule_node_has_children(graft)) { + tree_graft = isl_schedule_tree_from_filter(graft_domain); + } else { + graft = isl_schedule_node_child(graft, 0); + tree_graft = isl_schedule_node_get_tree(graft); + tree_graft = isl_schedule_tree_insert_filter(tree_graft, + graft_domain); + } + if (before) + tree = isl_schedule_tree_sequence_pair(tree_graft, tree); + else + tree = isl_schedule_tree_sequence_pair(tree, tree_graft); + node = graft_or_splice(node, tree, before); + + isl_schedule_node_free(graft); + + return node; +} + +/* Replace the root domain node of "node" by an extension node suitable + * for insertion at "pos". + * That is, create an extension node that maps the outer band nodes + * at "pos" to the domain of the root node of "node" and attach + * the child of this root node to the extension node. + */ +static __isl_give isl_schedule_node *extension_from_domain( + __isl_take isl_schedule_node *node, __isl_keep isl_schedule_node *pos) +{ + isl_union_set *universe; + isl_union_set *domain; + isl_union_map *ext; + isl_size depth; + isl_bool anchored; + isl_space *space; + isl_schedule_node *res; + isl_schedule_tree *tree; + + depth = isl_schedule_node_get_schedule_depth(pos); + anchored = isl_schedule_node_is_subtree_anchored(node); + if (depth < 0 || anchored < 0) + return isl_schedule_node_free(node); + if (anchored) + isl_die(isl_schedule_node_get_ctx(node), isl_error_unsupported, + "cannot graft anchored tree with domain root", + return isl_schedule_node_free(node)); + + domain = isl_schedule_node_domain_get_domain(node); + space = isl_union_set_get_space(domain); + space = isl_space_set_from_params(space); + space = isl_space_add_dims(space, isl_dim_set, depth); + universe = isl_union_set_from_set(isl_set_universe(space)); + ext = isl_union_map_from_domain_and_range(universe, domain); + res = isl_schedule_node_from_extension(ext); + node = isl_schedule_node_child(node, 0); + if (!node) + return isl_schedule_node_free(res); + if (!isl_schedule_tree_is_leaf(node->tree)) { + tree = isl_schedule_node_get_tree(node); + res = isl_schedule_node_child(res, 0); + res = isl_schedule_node_graft_tree(res, tree); + res = isl_schedule_node_parent(res); + } + isl_schedule_node_free(node); + + return res; +} + +/* Insert a node "graft" into the schedule tree of "node" such that it + * is executed before (if "before" is set) or after (if "before" is not set) + * the node that "node" points to. + * The root of "graft" may be either a domain or an extension node. + * In the latter case, the domain of the extension needs to correspond + * to the outer band nodes of "node". + * The elements of the domain or the range of the extension may not + * intersect with the domain elements that reach "node". + * The schedule tree of "graft" may not be anchored. + * + * The schedule tree of "node" is modified to include an extension node + * corresponding to the root node of "graft" as a child of the original + * parent of "node". The original node that "node" points to and the + * child of the root node of "graft" are attached to this extension node + * through a sequence, with appropriate filters and with the child + * of "graft" appearing before or after the original "node". + * + * If "node" already appears inside a sequence that is the child of + * an extension node and if the spaces of the new domain elements + * do not overlap with those of the original domain elements, + * then that extension node is extended with the new extension + * rather than introducing a new segment of extension and sequence nodes. + * + * Return a pointer to the same node in the modified tree that + * "node" pointed to in the original tree. + */ +static __isl_give isl_schedule_node *isl_schedule_node_graft_before_or_after( + __isl_take isl_schedule_node *node, __isl_take isl_schedule_node *graft, + int before) +{ + if (!node || !graft) + goto error; + if (check_insert(node) < 0) + goto error; + + 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", + goto error); + + return graft_extension(node, graft, before); +error: + isl_schedule_node_free(node); + isl_schedule_node_free(graft); + return NULL; +} + +/* Insert a node "graft" into the schedule tree of "node" such that it + * is executed before the node that "node" points to. + * The root of "graft" may be either a domain or an extension node. + * In the latter case, the domain of the extension needs to correspond + * to the outer band nodes of "node". + * The elements of the domain or the range of the extension may not + * intersect with the domain elements that reach "node". + * The schedule tree of "graft" may not be anchored. + * + * Return a pointer to the same node in the modified tree that + * "node" pointed to in the original tree. + */ +__isl_give isl_schedule_node *isl_schedule_node_graft_before( + __isl_take isl_schedule_node *node, __isl_take isl_schedule_node *graft) +{ + return isl_schedule_node_graft_before_or_after(node, graft, 1); +} + +/* Insert a node "graft" into the schedule tree of "node" such that it + * is executed after the node that "node" points to. + * The root of "graft" may be either a domain or an extension node. + * In the latter case, the domain of the extension needs to correspond + * to the outer band nodes of "node". + * The elements of the domain or the range of the extension may not + * intersect with the domain elements that reach "node". + * The schedule tree of "graft" may not be anchored. + * + * Return a pointer to the same node in the modified tree that + * "node" pointed to in the original tree. + */ +__isl_give isl_schedule_node *isl_schedule_node_graft_after( + __isl_take isl_schedule_node *node, + __isl_take isl_schedule_node *graft) +{ + return isl_schedule_node_graft_before_or_after(node, graft, 0); +} + +/* Split the domain elements that reach "node" into those that satisfy + * "filter" and those that do not. Arrange for the first subset to be + * executed before or after the second subset, depending on the value + * of "before". + * Return a pointer to the tree corresponding to the second subset, + * except when this subset is empty in which case the original pointer + * is returned. + * If both subsets are non-empty, then a sequence node is introduced + * to impose the order. If the grandparent of the original node was + * itself a sequence, then the original child is replaced by two children + * in this sequence instead. + * The children in the sequence are copies of the original subtree, + * simplified with respect to their filters. + */ +static __isl_give isl_schedule_node *isl_schedule_node_order_before_or_after( + __isl_take isl_schedule_node *node, __isl_take isl_union_set *filter, + int before) +{ + enum isl_schedule_node_type ancestors[] = + { isl_schedule_node_filter, isl_schedule_node_sequence }; + isl_union_set *node_domain, *node_filter = NULL, *parent_filter; + isl_schedule_node *node2; + isl_schedule_tree *tree1, *tree2; + isl_bool empty1, empty2; + isl_bool in_seq; + + if (!node || !filter) + goto error; + if (check_insert(node) < 0) + goto error; + + in_seq = has_ancestors(node, 2, ancestors); + if (in_seq < 0) + goto error; + node_domain = isl_schedule_node_get_domain(node); + filter = isl_union_set_gist(filter, isl_union_set_copy(node_domain)); + node_filter = isl_union_set_copy(node_domain); + node_filter = isl_union_set_subtract(node_filter, + isl_union_set_copy(filter)); + node_filter = isl_union_set_gist(node_filter, node_domain); + empty1 = isl_union_set_is_empty(filter); + empty2 = isl_union_set_is_empty(node_filter); + if (empty1 < 0 || empty2 < 0) + goto error; + if (empty1 || empty2) { + isl_union_set_free(filter); + isl_union_set_free(node_filter); + return node; + } + + if (in_seq) { + node = isl_schedule_node_parent(node); + parent_filter = isl_schedule_node_filter_get_filter(node); + node_filter = isl_union_set_intersect(node_filter, + isl_union_set_copy(parent_filter)); + filter = isl_union_set_intersect(filter, parent_filter); + } + + node2 = isl_schedule_node_copy(node); + node = isl_schedule_node_gist(node, isl_union_set_copy(node_filter)); + node2 = isl_schedule_node_gist(node2, isl_union_set_copy(filter)); + tree1 = isl_schedule_node_get_tree(node); + tree2 = isl_schedule_node_get_tree(node2); + tree1 = isl_schedule_tree_insert_filter(tree1, node_filter); + tree2 = isl_schedule_tree_insert_filter(tree2, filter); + isl_schedule_node_free(node2); + + if (before) { + tree1 = isl_schedule_tree_sequence_pair(tree2, tree1); + node = graft_or_splice(node, tree1, 1); + } else { + tree1 = isl_schedule_tree_sequence_pair(tree1, tree2); + node = graft_or_splice(node, tree1, 0); + } + + return node; +error: + isl_schedule_node_free(node); + isl_union_set_free(filter); + isl_union_set_free(node_filter); + return NULL; +} + +/* Split the domain elements that reach "node" into those that satisfy + * "filter" and those that do not. Arrange for the first subset to be + * executed before the second subset. + * Return a pointer to the tree corresponding to the second subset, + * except when this subset is empty in which case the original pointer + * is returned. + */ +__isl_give isl_schedule_node *isl_schedule_node_order_before( + __isl_take isl_schedule_node *node, __isl_take isl_union_set *filter) +{ + return isl_schedule_node_order_before_or_after(node, filter, 1); +} + +/* Split the domain elements that reach "node" into those that satisfy + * "filter" and those that do not. Arrange for the first subset to be + * executed after the second subset. + * Return a pointer to the tree corresponding to the second subset, + * except when this subset is empty in which case the original pointer + * is returned. + */ +__isl_give isl_schedule_node *isl_schedule_node_order_after( + __isl_take isl_schedule_node *node, __isl_take isl_union_set *filter) +{ + return isl_schedule_node_order_before_or_after(node, filter, 0); +} + +/* Reset the user pointer on all identifiers of parameters and tuples + * in the schedule node "node". + */ +__isl_give isl_schedule_node *isl_schedule_node_reset_user( + __isl_take isl_schedule_node *node) +{ + isl_schedule_tree *tree; + + tree = isl_schedule_node_get_tree(node); + tree = isl_schedule_tree_reset_user(tree); + node = isl_schedule_node_graft_tree(node, tree); + + return node; +} + +/* Align the parameters of the schedule node "node" to those of "space". + */ +__isl_give isl_schedule_node *isl_schedule_node_align_params( + __isl_take isl_schedule_node *node, __isl_take isl_space *space) +{ + isl_schedule_tree *tree; + + tree = isl_schedule_node_get_tree(node); + tree = isl_schedule_tree_align_params(tree, space); + node = isl_schedule_node_graft_tree(node, tree); + + return node; +} + +/* Compute the pullback of schedule node "node" + * by the function represented by "upma". + * In other words, plug in "upma" in the iteration domains + * of schedule node "node". + * We currently do not handle expansion nodes. + * + * Note that this is only a helper function for + * isl_schedule_pullback_union_pw_multi_aff. In order to maintain consistency, + * this function should not be called on a single node without also + * calling it on all the other nodes. + */ +__isl_give isl_schedule_node *isl_schedule_node_pullback_union_pw_multi_aff( + __isl_take isl_schedule_node *node, + __isl_take isl_union_pw_multi_aff *upma) +{ + isl_schedule_tree *tree; + + tree = isl_schedule_node_get_tree(node); + tree = isl_schedule_tree_pullback_union_pw_multi_aff(tree, upma); + node = isl_schedule_node_graft_tree(node, tree); + + return node; +} + +/* Internal data structure for isl_schedule_node_expand. + * "tree" is the tree that needs to be plugged in in all the leaves. + * "domain" is the set of domain elements in the original leaves + * to which the tree applies. + */ +struct isl_schedule_expand_data { + isl_schedule_tree *tree; + isl_union_set *domain; +}; + +/* If "node" is a leaf, then plug in data->tree, simplifying it + * within its new context. + * + * If there are any domain elements at the leaf where the tree + * should not be plugged in (i.e., there are elements not in data->domain) + * then first extend the tree to only apply to the elements in data->domain + * by constructing a set node that selects data->tree for elements + * in data->domain and a leaf for the other elements. + */ +static __isl_give isl_schedule_node *expand(__isl_take isl_schedule_node *node, + void *user) +{ + struct isl_schedule_expand_data *data = user; + isl_schedule_tree *tree, *leaf; + isl_union_set *domain, *left; + isl_bool empty; + + if (isl_schedule_node_get_type(node) != isl_schedule_node_leaf) + return node; + + domain = isl_schedule_node_get_domain(node); + tree = isl_schedule_tree_copy(data->tree); + + left = isl_union_set_copy(domain); + left = isl_union_set_subtract(left, isl_union_set_copy(data->domain)); + empty = isl_union_set_is_empty(left); + if (empty >= 0 && !empty) { + leaf = isl_schedule_node_get_leaf(node); + leaf = isl_schedule_tree_insert_filter(leaf, left); + left = isl_union_set_copy(data->domain); + tree = isl_schedule_tree_insert_filter(tree, left); + tree = isl_schedule_tree_set_pair(tree, leaf); + } else { + if (empty < 0) + node = isl_schedule_node_free(node); + isl_union_set_free(left); + } + + node = isl_schedule_node_graft_tree(node, tree); + node = isl_schedule_node_gist(node, domain); + + return node; +} + +/* Expand the tree rooted at "node" by extending all leaves + * with an expansion node with as child "tree". + * The expansion is determined by "contraction" and "domain". + * That is, the elements of "domain" are contracted according + * to "contraction". The expansion relation is then the inverse + * of "contraction" with its range intersected with "domain". + * + * Insert the appropriate expansion node on top of "tree" and + * then plug in the result in all leaves of "node". + */ +__isl_give isl_schedule_node *isl_schedule_node_expand( + __isl_take isl_schedule_node *node, + __isl_take isl_union_pw_multi_aff *contraction, + __isl_take isl_union_set *domain, + __isl_take isl_schedule_tree *tree) +{ + struct isl_schedule_expand_data data; + isl_union_map *expansion; + isl_union_pw_multi_aff *copy; + + if (!node || !contraction || !tree) + node = isl_schedule_node_free(node); + + copy = isl_union_pw_multi_aff_copy(contraction); + expansion = isl_union_map_from_union_pw_multi_aff(copy); + expansion = isl_union_map_reverse(expansion); + expansion = isl_union_map_intersect_range(expansion, domain); + data.domain = isl_union_map_domain(isl_union_map_copy(expansion)); + + tree = isl_schedule_tree_insert_expansion(tree, contraction, expansion); + data.tree = tree; + + node = isl_schedule_node_map_descendant_bottom_up(node, &expand, &data); + isl_union_set_free(data.domain); + isl_schedule_tree_free(data.tree); + return node; +} + +/* Return the position of the subtree containing "node" among the children + * of "ancestor". "node" is assumed to be a descendant of "ancestor". + * In particular, both nodes should point to the same schedule tree. + * + * Return isl_size_error on error. + */ +isl_size isl_schedule_node_get_ancestor_child_position( + __isl_keep isl_schedule_node *node, + __isl_keep isl_schedule_node *ancestor) +{ + isl_size n1, n2; + isl_schedule_tree *tree; + + n1 = isl_schedule_node_get_tree_depth(ancestor); + n2 = isl_schedule_node_get_tree_depth(node); + if (n1 < 0 || n2 < 0) + return isl_size_error; + + if (node->schedule != ancestor->schedule) + isl_die(isl_schedule_node_get_ctx(node), isl_error_invalid, + "not a descendant", return isl_size_error); + + if (n1 >= n2) + isl_die(isl_schedule_node_get_ctx(node), isl_error_invalid, + "not a descendant", return isl_size_error); + tree = isl_schedule_tree_list_get_schedule_tree(node->ancestors, n1); + isl_schedule_tree_free(tree); + if (tree != ancestor->tree) + isl_die(isl_schedule_node_get_ctx(node), isl_error_invalid, + "not a descendant", return isl_size_error); + + return node->child_pos[n1]; +} + +/* Given two nodes that point to the same schedule tree, return their + * closest shared ancestor. + * + * Since the two nodes point to the same schedule, they share at least + * one ancestor, the root of the schedule. We move down from the root + * to the first ancestor where the respective children have a different + * child position. This is the requested ancestor. + * If there is no ancestor where the children have a different position, + * then one node is an ancestor of the other and then this node is + * the requested ancestor. + */ +__isl_give isl_schedule_node *isl_schedule_node_get_shared_ancestor( + __isl_keep isl_schedule_node *node1, + __isl_keep isl_schedule_node *node2) +{ + int i; + isl_size n1, n2; + + n1 = isl_schedule_node_get_tree_depth(node1); + n2 = isl_schedule_node_get_tree_depth(node2); + if (n1 < 0 || n2 < 0) + return NULL; + if (node1->schedule != node2->schedule) + isl_die(isl_schedule_node_get_ctx(node1), isl_error_invalid, + "not part of same schedule", return NULL); + if (n2 < n1) + return isl_schedule_node_get_shared_ancestor(node2, node1); + if (n1 == 0) + return isl_schedule_node_copy(node1); + if (isl_schedule_node_is_equal(node1, node2)) + return isl_schedule_node_copy(node1); + + for (i = 0; i < n1; ++i) + if (node1->child_pos[i] != node2->child_pos[i]) + break; + + node1 = isl_schedule_node_copy(node1); + return isl_schedule_node_ancestor(node1, n1 - i); +} + +/* Print "node" to "p". + */ +__isl_give isl_printer *isl_printer_print_schedule_node( + __isl_take isl_printer *p, __isl_keep isl_schedule_node *node) +{ + isl_size n; + + if (!node) + return isl_printer_free(p); + n = isl_schedule_tree_list_n_schedule_tree(node->ancestors); + if (n < 0) + return isl_printer_free(p); + return isl_printer_print_schedule_tree_mark(p, node->schedule->root, n, + node->child_pos); +} + +void isl_schedule_node_dump(__isl_keep isl_schedule_node *node) +{ + isl_ctx *ctx; + isl_printer *printer; + + if (!node) + return; + + ctx = isl_schedule_node_get_ctx(node); + printer = isl_printer_to_file(ctx, stderr); + printer = isl_printer_set_yaml_style(printer, ISL_YAML_STYLE_BLOCK); + printer = isl_printer_print_schedule_node(printer, node); + + isl_printer_free(printer); +} + +/* Return a string representation of "node". + * Print the schedule node in block format as it would otherwise + * look identical to the entire schedule. + */ +__isl_give char *isl_schedule_node_to_str(__isl_keep isl_schedule_node *node) +{ + isl_printer *printer; + char *s; + + if (!node) + return NULL; + + printer = isl_printer_to_str(isl_schedule_node_get_ctx(node)); + printer = isl_printer_set_yaml_style(printer, ISL_YAML_STYLE_BLOCK); + printer = isl_printer_print_schedule_node(printer, node); + s = isl_printer_get_str(printer); + isl_printer_free(printer); + + return s; +} diff --git a/external/mit/isl/dist/isl_schedule_node_private.h b/external/mit/isl/dist/isl_schedule_node_private.h new file mode 100644 index 000000000000..c4ad6ef61cb3 --- /dev/null +++ b/external/mit/isl/dist/isl_schedule_node_private.h @@ -0,0 +1,68 @@ +#ifndef ISL_SCHEDLUE_NODE_PRIVATE_H +#define ISL_SCHEDLUE_NODE_PRIVATE_H + +#include +#include +#include + +/* An isl_schedule_node points to a particular location in a schedule tree. + * + * "schedule" is the schedule that the node is pointing to. + * "ancestors" is a list of the n ancestors of the node + * that is being pointed to. + * The first ancestor is the root of "schedule", while the last ancestor + * is the parent of the specified location. + * "child_pos" is an array of child positions of the same length as "ancestors", + * where ancestor i (i > 0) appears in child_pos[i - 1] of ancestor i - 1 and + * "tree" appears in child_pos[n - 1] of ancestor n - 1. + * "tree" is the subtree at the specified location. + * + * Note that the same isl_schedule_tree object may appear several times + * in a schedule tree and therefore does not uniquely identify a position + * in the schedule tree. + */ +struct isl_schedule_node { + int ref; + + isl_schedule *schedule; + isl_schedule_tree_list *ancestors; + int *child_pos; + isl_schedule_tree *tree; +}; + +__isl_give isl_schedule_node *isl_schedule_node_alloc( + __isl_take isl_schedule *schedule, __isl_take isl_schedule_tree *tree, + __isl_take isl_schedule_tree_list *ancestors, int *child_pos); +__isl_give isl_schedule_node *isl_schedule_node_graft_tree( + __isl_take isl_schedule_node *pos, __isl_take isl_schedule_tree *tree); + +__isl_give isl_schedule_tree *isl_schedule_node_get_tree( + __isl_keep isl_schedule_node *node); + +__isl_give isl_schedule_node *isl_schedule_node_pullback_union_pw_multi_aff( + __isl_take isl_schedule_node *node, + __isl_take isl_union_pw_multi_aff *upma); + +__isl_give isl_schedule_node *isl_schedule_node_expand( + __isl_take isl_schedule_node *node, + __isl_take isl_union_pw_multi_aff *contraction, + __isl_take isl_union_set *domain, + __isl_take isl_schedule_tree *tree); + +__isl_give isl_schedule_node *isl_schedule_node_gist( + __isl_take isl_schedule_node *node, __isl_take isl_union_set *context); + +__isl_give isl_schedule_node *isl_schedule_node_domain_intersect_domain( + __isl_take isl_schedule_node *node, __isl_take isl_union_set *domain); +__isl_give isl_schedule_node *isl_schedule_node_domain_gist_params( + __isl_take isl_schedule_node *node, __isl_take isl_set *context); + +__isl_give isl_schedule_node *isl_schedule_node_insert_expansion( + __isl_take isl_schedule_node *node, + __isl_take isl_union_pw_multi_aff *contraction, + __isl_take isl_union_map *expansion); +__isl_give isl_schedule_node *isl_schedule_node_insert_extension( + __isl_take isl_schedule_node *node, + __isl_take isl_union_map *extension); + +#endif diff --git a/external/mit/isl/dist/isl_schedule_private.h b/external/mit/isl/dist/isl_schedule_private.h new file mode 100644 index 000000000000..dcf15de2d9e8 --- /dev/null +++ b/external/mit/isl/dist/isl_schedule_private.h @@ -0,0 +1,36 @@ +#ifndef ISL_SCHEDLUE_PRIVATE_H +#define ISL_SCHEDLUE_PRIVATE_H + +#include +#include +#include + +/* A complete schedule tree. + * + * "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, + * but an isl_schedule_node may have "leaf" as its tree if it refers to + * a leaf of this schedule tree. + */ +struct isl_schedule { + int ref; + + isl_schedule_tree *root; + + struct isl_schedule_tree *leaf; +}; + +__isl_give isl_schedule *isl_schedule_from_schedule_tree(isl_ctx *ctx, + __isl_take isl_schedule_tree *tree); +__isl_give isl_schedule *isl_schedule_set_root( + __isl_take isl_schedule *schedule, __isl_take isl_schedule_tree *tree); +__isl_give isl_space *isl_schedule_get_space( + __isl_keep isl_schedule *schedule); +__isl_give isl_union_set *isl_schedule_get_domain( + __isl_keep isl_schedule *schedule); +__isl_keep isl_schedule_tree *isl_schedule_peek_leaf( + __isl_keep isl_schedule *schedule); + +#endif diff --git a/external/mit/isl/dist/isl_schedule_read.c b/external/mit/isl/dist/isl_schedule_read.c new file mode 100644 index 000000000000..b98b72b7dc76 --- /dev/null +++ b/external/mit/isl/dist/isl_schedule_read.c @@ -0,0 +1,744 @@ +#include +#include +#include +#include +#include +#include + +/* An enumeration of the various keys that may appear in a YAML mapping + * of a schedule. + */ +enum isl_schedule_key { + isl_schedule_key_error = -1, + isl_schedule_key_child, + isl_schedule_key_coincident, + isl_schedule_key_context, + isl_schedule_key_contraction, + isl_schedule_key_domain, + isl_schedule_key_expansion, + isl_schedule_key_extension, + isl_schedule_key_filter, + isl_schedule_key_guard, + isl_schedule_key_leaf, + isl_schedule_key_mark, + isl_schedule_key_options, + isl_schedule_key_permutable, + isl_schedule_key_schedule, + isl_schedule_key_sequence, + isl_schedule_key_set, + isl_schedule_key_end +}; + +/* Textual representations of the YAML keys for an isl_schedule object. + */ +static char *key_str[] = { + [isl_schedule_key_child] = "child", + [isl_schedule_key_coincident] = "coincident", + [isl_schedule_key_context] = "context", + [isl_schedule_key_contraction] = "contraction", + [isl_schedule_key_domain] = "domain", + [isl_schedule_key_expansion] = "expansion", + [isl_schedule_key_extension] = "extension", + [isl_schedule_key_filter] = "filter", + [isl_schedule_key_guard] = "guard", + [isl_schedule_key_leaf] = "leaf", + [isl_schedule_key_mark] = "mark", + [isl_schedule_key_options] = "options", + [isl_schedule_key_permutable] = "permutable", + [isl_schedule_key_schedule] = "schedule", + [isl_schedule_key_sequence] = "sequence", + [isl_schedule_key_set] = "set", +}; + +#undef KEY +#define KEY enum isl_schedule_key +#undef KEY_ERROR +#define KEY_ERROR isl_schedule_key_error +#undef KEY_END +#define KEY_END isl_schedule_key_end +#undef KEY_STR +#define KEY_STR key_str +#undef KEY_EXTRACT +#define KEY_EXTRACT extract_key +#undef KEY_GET +#define KEY_GET get_key +#include "extract_key.c" + +static __isl_give isl_schedule_tree *isl_stream_read_schedule_tree( + __isl_keep isl_stream *s); + +/* Read a subtree with context root node from "s". + */ +static __isl_give isl_schedule_tree *read_context(__isl_keep isl_stream *s) +{ + isl_set *context = NULL; + isl_schedule_tree *tree; + isl_ctx *ctx; + struct isl_token *tok; + enum isl_schedule_key key; + char *str; + isl_bool more; + + ctx = isl_stream_get_ctx(s); + + key = get_key(s); + + if (isl_stream_yaml_next(s) < 0) + return NULL; + + tok = isl_stream_next_token(s); + if (!tok) { + isl_stream_error(s, NULL, "unexpected EOF"); + return NULL; + } + str = isl_token_get_str(ctx, tok); + context = isl_set_read_from_str(ctx, str); + free(str); + isl_token_free(tok); + + more = isl_stream_yaml_next(s); + if (more < 0) + goto error; + if (!more) { + tree = isl_schedule_tree_from_context(context); + } else { + key = get_key(s); + if (key != isl_schedule_key_child) + isl_die(ctx, isl_error_invalid, "expecting child", + goto error); + if (isl_stream_yaml_next(s) < 0) + goto error; + tree = isl_stream_read_schedule_tree(s); + tree = isl_schedule_tree_insert_context(tree, context); + } + + return tree; +error: + isl_set_free(context); + return NULL; +} + +/* Read a subtree with domain root node from "s". + */ +static __isl_give isl_schedule_tree *read_domain(__isl_keep isl_stream *s) +{ + isl_union_set *domain = NULL; + isl_schedule_tree *tree; + isl_ctx *ctx; + struct isl_token *tok; + enum isl_schedule_key key; + char *str; + isl_bool more; + + ctx = isl_stream_get_ctx(s); + + key = get_key(s); + + if (isl_stream_yaml_next(s) < 0) + return NULL; + + tok = isl_stream_next_token(s); + if (!tok) { + isl_stream_error(s, NULL, "unexpected EOF"); + return NULL; + } + str = isl_token_get_str(ctx, tok); + domain = isl_union_set_read_from_str(ctx, str); + free(str); + isl_token_free(tok); + + more = isl_stream_yaml_next(s); + if (more < 0) + goto error; + if (!more) { + tree = isl_schedule_tree_from_domain(domain); + } else { + key = get_key(s); + if (key != isl_schedule_key_child) + isl_die(ctx, isl_error_invalid, "expecting child", + goto error); + if (isl_stream_yaml_next(s) < 0) + goto error; + tree = isl_stream_read_schedule_tree(s); + tree = isl_schedule_tree_insert_domain(tree, domain); + } + + return tree; +error: + isl_union_set_free(domain); + return NULL; +} + +/* Read a subtree with expansion root node from "s". + */ +static __isl_give isl_schedule_tree *read_expansion(isl_stream *s) +{ + isl_ctx *ctx; + isl_union_pw_multi_aff *contraction = NULL; + isl_union_map *expansion = NULL; + isl_schedule_tree *tree = NULL; + isl_bool more; + + ctx = isl_stream_get_ctx(s); + + do { + struct isl_token *tok; + enum isl_schedule_key key; + char *str; + + key = get_key(s); + if (isl_stream_yaml_next(s) < 0) + goto error; + + switch (key) { + case isl_schedule_key_contraction: + isl_union_pw_multi_aff_free(contraction); + tok = isl_stream_next_token(s); + str = isl_token_get_str(ctx, tok); + contraction = isl_union_pw_multi_aff_read_from_str(ctx, + str); + free(str); + isl_token_free(tok); + if (!contraction) + goto error; + break; + case isl_schedule_key_expansion: + isl_union_map_free(expansion); + tok = isl_stream_next_token(s); + str = isl_token_get_str(ctx, tok); + expansion = isl_union_map_read_from_str(ctx, str); + free(str); + isl_token_free(tok); + if (!expansion) + goto error; + break; + case isl_schedule_key_child: + isl_schedule_tree_free(tree); + tree = isl_stream_read_schedule_tree(s); + if (!tree) + goto error; + break; + default: + isl_die(ctx, isl_error_invalid, "unexpected key", + goto error); + } + } while ((more = isl_stream_yaml_next(s)) == isl_bool_true); + + if (more < 0) + goto error; + + if (!contraction) + isl_die(ctx, isl_error_invalid, "missing contraction", + goto error); + if (!expansion) + isl_die(ctx, isl_error_invalid, "missing expansion", + goto error); + + if (!tree) + return isl_schedule_tree_from_expansion(contraction, expansion); + return isl_schedule_tree_insert_expansion(tree, contraction, expansion); +error: + isl_schedule_tree_free(tree); + isl_union_pw_multi_aff_free(contraction); + isl_union_map_free(expansion); + return NULL; +} + +/* Read a subtree with extension root node from "s". + */ +static __isl_give isl_schedule_tree *read_extension(isl_stream *s) +{ + isl_union_map *extension = NULL; + isl_schedule_tree *tree; + isl_ctx *ctx; + struct isl_token *tok; + enum isl_schedule_key key; + char *str; + isl_bool more; + + ctx = isl_stream_get_ctx(s); + + key = get_key(s); + + if (isl_stream_yaml_next(s) < 0) + return NULL; + + tok = isl_stream_next_token(s); + if (!tok) { + isl_stream_error(s, NULL, "unexpected EOF"); + return NULL; + } + str = isl_token_get_str(ctx, tok); + extension = isl_union_map_read_from_str(ctx, str); + free(str); + isl_token_free(tok); + + more = isl_stream_yaml_next(s); + if (more < 0) + goto error; + if (!more) { + tree = isl_schedule_tree_from_extension(extension); + } else { + key = get_key(s); + if (key != isl_schedule_key_child) + isl_die(ctx, isl_error_invalid, "expecting child", + goto error); + if (isl_stream_yaml_next(s) < 0) + goto error; + tree = isl_stream_read_schedule_tree(s); + tree = isl_schedule_tree_insert_extension(tree, extension); + } + + return tree; +error: + isl_union_map_free(extension); + return NULL; +} + +/* Read a subtree with filter root node from "s". + */ +static __isl_give isl_schedule_tree *read_filter(__isl_keep isl_stream *s) +{ + isl_union_set *filter = NULL; + isl_schedule_tree *tree; + isl_ctx *ctx; + struct isl_token *tok; + enum isl_schedule_key key; + char *str; + isl_bool more; + + ctx = isl_stream_get_ctx(s); + + key = get_key(s); + + if (isl_stream_yaml_next(s) < 0) + return NULL; + + tok = isl_stream_next_token(s); + if (!tok) { + isl_stream_error(s, NULL, "unexpected EOF"); + return NULL; + } + str = isl_token_get_str(ctx, tok); + filter = isl_union_set_read_from_str(ctx, str); + free(str); + isl_token_free(tok); + + more = isl_stream_yaml_next(s); + if (more < 0) + goto error; + if (!more) { + tree = isl_schedule_tree_from_filter(filter); + } else { + key = get_key(s); + if (key != isl_schedule_key_child) + isl_die(ctx, isl_error_invalid, "expecting child", + goto error); + if (isl_stream_yaml_next(s) < 0) + goto error; + tree = isl_stream_read_schedule_tree(s); + tree = isl_schedule_tree_insert_filter(tree, filter); + } + + return tree; +error: + isl_union_set_free(filter); + return NULL; +} + +/* Read a subtree with guard root node from "s". + */ +static __isl_give isl_schedule_tree *read_guard(isl_stream *s) +{ + isl_set *guard = NULL; + isl_schedule_tree *tree; + isl_ctx *ctx; + struct isl_token *tok; + enum isl_schedule_key key; + char *str; + isl_bool more; + + ctx = isl_stream_get_ctx(s); + + key = get_key(s); + + if (isl_stream_yaml_next(s) < 0) + return NULL; + + tok = isl_stream_next_token(s); + if (!tok) { + isl_stream_error(s, NULL, "unexpected EOF"); + return NULL; + } + str = isl_token_get_str(ctx, tok); + guard = isl_set_read_from_str(ctx, str); + free(str); + isl_token_free(tok); + + more = isl_stream_yaml_next(s); + if (more < 0) + goto error; + if (!more) { + tree = isl_schedule_tree_from_guard(guard); + } else { + key = get_key(s); + if (key != isl_schedule_key_child) + isl_die(ctx, isl_error_invalid, "expecting child", + goto error); + if (isl_stream_yaml_next(s) < 0) + goto error; + tree = isl_stream_read_schedule_tree(s); + tree = isl_schedule_tree_insert_guard(tree, guard); + } + + return tree; +error: + isl_set_free(guard); + return NULL; +} + +/* Read a subtree with mark root node from "s". + */ +static __isl_give isl_schedule_tree *read_mark(isl_stream *s) +{ + isl_id *mark; + isl_schedule_tree *tree; + isl_ctx *ctx; + struct isl_token *tok; + enum isl_schedule_key key; + char *str; + isl_bool more; + + ctx = isl_stream_get_ctx(s); + + key = get_key(s); + + if (isl_stream_yaml_next(s) < 0) + return NULL; + + tok = isl_stream_next_token(s); + if (!tok) { + isl_stream_error(s, NULL, "unexpected EOF"); + return NULL; + } + str = isl_token_get_str(ctx, tok); + mark = isl_id_alloc(ctx, str, NULL); + free(str); + isl_token_free(tok); + + more = isl_stream_yaml_next(s); + if (more < 0) + goto error; + if (!more) { + isl_die(ctx, isl_error_invalid, "expecting child", + goto error); + } else { + key = get_key(s); + if (key != isl_schedule_key_child) + isl_die(ctx, isl_error_invalid, "expecting child", + goto error); + if (isl_stream_yaml_next(s) < 0) + goto error; + tree = isl_stream_read_schedule_tree(s); + tree = isl_schedule_tree_insert_mark(tree, mark); + } + + return tree; +error: + isl_id_free(mark); + return NULL; +} + +#undef EL_BASE +#define EL_BASE val + +#include + +/* Read a sequence of integers from "s" (representing the coincident + * property of a band node). + */ +static __isl_give isl_val_list *read_coincident(__isl_keep isl_stream *s) +{ + return isl_stream_yaml_read_val_list(s); +} + +/* Set the (initial) coincident properties of "band" according to + * the (initial) elements of "coincident". + */ +static __isl_give isl_schedule_band *set_coincident( + __isl_take isl_schedule_band *band, __isl_take isl_val_list *coincident) +{ + int i; + isl_size n, m; + + n = isl_schedule_band_n_member(band); + m = isl_val_list_n_val(coincident); + if (n < 0 || m < 0) + band = isl_schedule_band_free(band); + + for (i = 0; i < n && i < m; ++i) { + isl_val *v; + + v = isl_val_list_get_val(coincident, i); + if (!v) + band = isl_schedule_band_free(band); + band = isl_schedule_band_member_set_coincident(band, i, + !isl_val_is_zero(v)); + isl_val_free(v); + } + isl_val_list_free(coincident); + return band; +} + +/* Read a subtree with band root node from "s". + */ +static __isl_give isl_schedule_tree *read_band(isl_stream *s) +{ + isl_multi_union_pw_aff *schedule = NULL; + isl_schedule_tree *tree = NULL; + isl_val_list *coincident = NULL; + isl_union_set *options = NULL; + isl_ctx *ctx; + isl_schedule_band *band; + int permutable = 0; + isl_bool more; + + ctx = isl_stream_get_ctx(s); + + do { + struct isl_token *tok; + enum isl_schedule_key key; + char *str; + isl_val *v; + + key = get_key(s); + if (isl_stream_yaml_next(s) < 0) + goto error; + + switch (key) { + case isl_schedule_key_schedule: + schedule = isl_multi_union_pw_aff_free(schedule); + tok = isl_stream_next_token(s); + if (!tok) { + isl_stream_error(s, NULL, "unexpected EOF"); + goto error; + } + str = isl_token_get_str(ctx, tok); + schedule = isl_multi_union_pw_aff_read_from_str(ctx, + str); + free(str); + isl_token_free(tok); + if (!schedule) + goto error; + break; + case isl_schedule_key_coincident: + coincident = read_coincident(s); + if (!coincident) + goto error; + break; + case isl_schedule_key_permutable: + v = isl_stream_read_val(s); + permutable = !isl_val_is_zero(v); + isl_val_free(v); + break; + case isl_schedule_key_options: + isl_union_set_free(options); + tok = isl_stream_next_token(s); + str = isl_token_get_str(ctx, tok); + options = isl_union_set_read_from_str(ctx, str); + free(str); + isl_token_free(tok); + if (!options) + goto error; + break; + case isl_schedule_key_child: + isl_schedule_tree_free(tree); + tree = isl_stream_read_schedule_tree(s); + if (!tree) + goto error; + break; + default: + isl_die(ctx, isl_error_invalid, "unexpected key", + goto error); + } + } while ((more = isl_stream_yaml_next(s)) == isl_bool_true); + + if (more < 0) + goto error; + + if (!schedule) + isl_die(ctx, isl_error_invalid, "missing schedule", goto error); + + band = isl_schedule_band_from_multi_union_pw_aff(schedule); + band = isl_schedule_band_set_permutable(band, permutable); + if (coincident) + band = set_coincident(band, coincident); + if (options) + band = isl_schedule_band_set_ast_build_options(band, options); + if (tree) + tree = isl_schedule_tree_insert_band(tree, band); + else + tree = isl_schedule_tree_from_band(band); + + return tree; +error: + isl_val_list_free(coincident); + isl_union_set_free(options); + isl_schedule_tree_free(tree); + isl_multi_union_pw_aff_free(schedule); + return NULL; +} + +#undef EL_BASE +#define EL_BASE schedule_tree + +#include + +/* Read a subtree with root node of type "type" from "s". + * The node is represented by a sequence of children. + */ +static __isl_give isl_schedule_tree *read_children(isl_stream *s, + enum isl_schedule_node_type type) +{ + isl_schedule_tree_list *list; + + isl_token_free(isl_stream_next_token(s)); + + if (isl_stream_yaml_next(s) < 0) + return NULL; + + list = isl_stream_yaml_read_schedule_tree_list(s); + + return isl_schedule_tree_from_children(type, list); +} + +/* Read a subtree with sequence root node from "s". + */ +static __isl_give isl_schedule_tree *read_sequence(isl_stream *s) +{ + return read_children(s, isl_schedule_node_sequence); +} + +/* Read a subtree with set root node from "s". + */ +static __isl_give isl_schedule_tree *read_set(isl_stream *s) +{ + return read_children(s, isl_schedule_node_set); +} + +/* Read a schedule (sub)tree from "s". + * + * We first determine the type of the root node based on the first + * mapping key and then hand over to a function tailored to reading + * nodes of this type. + */ +static __isl_give isl_schedule_tree *isl_stream_read_schedule_tree( + struct isl_stream *s) +{ + enum isl_schedule_key key; + struct isl_token *tok; + isl_schedule_tree *tree = NULL; + isl_bool more; + + if (isl_stream_yaml_read_start_mapping(s) < 0) + return NULL; + more = isl_stream_yaml_next(s); + if (more < 0) + return NULL; + if (!more) { + isl_stream_error(s, NULL, "missing key"); + return NULL; + } + + tok = isl_stream_next_token(s); + key = extract_key(s, tok); + isl_stream_push_token(s, tok); + if (key < 0) + return NULL; + switch (key) { + case isl_schedule_key_context: + tree = read_context(s); + break; + case isl_schedule_key_domain: + tree = read_domain(s); + break; + case isl_schedule_key_contraction: + case isl_schedule_key_expansion: + tree = read_expansion(s); + break; + case isl_schedule_key_extension: + tree = read_extension(s); + break; + case isl_schedule_key_filter: + tree = read_filter(s); + break; + case isl_schedule_key_guard: + tree = read_guard(s); + break; + case isl_schedule_key_leaf: + isl_token_free(isl_stream_next_token(s)); + tree = isl_schedule_tree_leaf(isl_stream_get_ctx(s)); + break; + case isl_schedule_key_mark: + tree = read_mark(s); + break; + case isl_schedule_key_sequence: + tree = read_sequence(s); + break; + case isl_schedule_key_set: + tree = read_set(s); + break; + case isl_schedule_key_schedule: + case isl_schedule_key_coincident: + case isl_schedule_key_options: + case isl_schedule_key_permutable: + tree = read_band(s); + break; + case isl_schedule_key_child: + isl_die(isl_stream_get_ctx(s), isl_error_unsupported, + "cannot identify node type", return NULL); + case isl_schedule_key_end: + case isl_schedule_key_error: + return NULL; + } + + if (isl_stream_yaml_read_end_mapping(s) < 0) + return isl_schedule_tree_free(tree); + + return tree; +} + +/* Read an isl_schedule from "s". + */ +__isl_give isl_schedule *isl_stream_read_schedule(isl_stream *s) +{ + isl_ctx *ctx; + isl_schedule_tree *tree; + + if (!s) + return NULL; + + ctx = isl_stream_get_ctx(s); + tree = isl_stream_read_schedule_tree(s); + return isl_schedule_from_schedule_tree(ctx, tree); +} + +/* Read an isl_schedule from "input". + */ +__isl_give isl_schedule *isl_schedule_read_from_file(isl_ctx *ctx, FILE *input) +{ + struct isl_stream *s; + isl_schedule *schedule; + + s = isl_stream_new_file(ctx, input); + if (!s) + return NULL; + schedule = isl_stream_read_schedule(s); + isl_stream_free(s); + + return schedule; +} + +#undef TYPE_BASE +#define TYPE_BASE schedule +#include "isl_read_from_str_templ.c" diff --git a/external/mit/isl/dist/isl_schedule_tree.c b/external/mit/isl/dist/isl_schedule_tree.c new file mode 100644 index 000000000000..8dfe1d728b65 --- /dev/null +++ b/external/mit/isl/dist/isl_schedule_tree.c @@ -0,0 +1,2906 @@ +/* + * Copyright 2013-2014 Ecole Normale Superieure + * Copyright 2014 INRIA Rocquencourt + * Copyright 2016 INRIA Paris + * + * Use of this software is governed by the MIT license + * + * Written by Sven Verdoolaege, + * Ecole Normale Superieure, 45 rue d'Ulm, 75230 Paris, France + * and Inria Paris - Rocquencourt, Domaine de Voluceau - Rocquencourt, + * B.P. 105 - 78153 Le Chesnay, France + * and Centre de Recherche Inria de Paris, 2 rue Simone Iff - Voie DQ12, + * CS 42112, 75589 Paris Cedex 12, France + */ + +#include +#include +#include +#include +#include +#include + +#undef EL +#define EL isl_schedule_tree + +#include + +#undef EL_BASE +#define EL_BASE schedule_tree + +#include + +/* Is "tree" the leaf of a schedule tree? + */ +int isl_schedule_tree_is_leaf(__isl_keep isl_schedule_tree *tree) +{ + return isl_schedule_tree_get_type(tree) == isl_schedule_node_leaf; +} + +/* Create a new schedule tree of type "type". + * The caller is responsible for filling in the type specific fields and + * the children. + * + * By default, the single node tree does not have any anchored nodes. + * The caller is responsible for updating the anchored field if needed. + */ +static __isl_give isl_schedule_tree *isl_schedule_tree_alloc(isl_ctx *ctx, + enum isl_schedule_node_type type) +{ + isl_schedule_tree *tree; + + if (type == isl_schedule_node_error) + return NULL; + + tree = isl_calloc_type(ctx, isl_schedule_tree); + if (!tree) + return NULL; + + tree->ref = 1; + tree->ctx = ctx; + isl_ctx_ref(ctx); + tree->type = type; + tree->anchored = 0; + + return tree; +} + +/* Return a fresh copy of "tree". + */ +__isl_give isl_schedule_tree *isl_schedule_tree_dup( + __isl_keep isl_schedule_tree *tree) +{ + isl_ctx *ctx; + isl_schedule_tree *dup; + + if (!tree) + return NULL; + + ctx = isl_schedule_tree_get_ctx(tree); + dup = isl_schedule_tree_alloc(ctx, tree->type); + if (!dup) + return NULL; + + switch (tree->type) { + case isl_schedule_node_error: + isl_die(ctx, isl_error_internal, + "allocation should have failed", + return isl_schedule_tree_free(dup)); + case isl_schedule_node_band: + dup->band = isl_schedule_band_copy(tree->band); + if (!dup->band) + return isl_schedule_tree_free(dup); + break; + case isl_schedule_node_context: + dup->context = isl_set_copy(tree->context); + if (!dup->context) + return isl_schedule_tree_free(dup); + break; + case isl_schedule_node_domain: + dup->domain = isl_union_set_copy(tree->domain); + if (!dup->domain) + return isl_schedule_tree_free(dup); + break; + case isl_schedule_node_expansion: + dup->contraction = + isl_union_pw_multi_aff_copy(tree->contraction); + dup->expansion = isl_union_map_copy(tree->expansion); + if (!dup->contraction || !dup->expansion) + return isl_schedule_tree_free(dup); + break; + case isl_schedule_node_extension: + dup->extension = isl_union_map_copy(tree->extension); + if (!dup->extension) + return isl_schedule_tree_free(dup); + break; + case isl_schedule_node_filter: + dup->filter = isl_union_set_copy(tree->filter); + if (!dup->filter) + return isl_schedule_tree_free(dup); + break; + case isl_schedule_node_guard: + dup->guard = isl_set_copy(tree->guard); + if (!dup->guard) + return isl_schedule_tree_free(dup); + break; + case isl_schedule_node_mark: + dup->mark = isl_id_copy(tree->mark); + if (!dup->mark) + return isl_schedule_tree_free(dup); + break; + case isl_schedule_node_leaf: + case isl_schedule_node_sequence: + case isl_schedule_node_set: + break; + } + + if (tree->children) { + dup->children = isl_schedule_tree_list_copy(tree->children); + if (!dup->children) + return isl_schedule_tree_free(dup); + } + dup->anchored = tree->anchored; + + return dup; +} + +/* Return an isl_schedule_tree that is equal to "tree" and that has only + * a single reference. + */ +__isl_give isl_schedule_tree *isl_schedule_tree_cow( + __isl_take isl_schedule_tree *tree) +{ + if (!tree) + return NULL; + + if (tree->ref == 1) + return tree; + tree->ref--; + return isl_schedule_tree_dup(tree); +} + +/* Return a new reference to "tree". + */ +__isl_give isl_schedule_tree *isl_schedule_tree_copy( + __isl_keep isl_schedule_tree *tree) +{ + if (!tree) + return NULL; + + tree->ref++; + return tree; +} + +/* Free "tree" and return NULL. + */ +__isl_null isl_schedule_tree *isl_schedule_tree_free( + __isl_take isl_schedule_tree *tree) +{ + if (!tree) + return NULL; + if (--tree->ref > 0) + return NULL; + + switch (tree->type) { + case isl_schedule_node_band: + isl_schedule_band_free(tree->band); + break; + case isl_schedule_node_context: + isl_set_free(tree->context); + break; + case isl_schedule_node_domain: + isl_union_set_free(tree->domain); + break; + case isl_schedule_node_expansion: + isl_union_pw_multi_aff_free(tree->contraction); + isl_union_map_free(tree->expansion); + break; + case isl_schedule_node_extension: + isl_union_map_free(tree->extension); + break; + case isl_schedule_node_filter: + isl_union_set_free(tree->filter); + break; + case isl_schedule_node_guard: + isl_set_free(tree->guard); + break; + case isl_schedule_node_mark: + isl_id_free(tree->mark); + break; + case isl_schedule_node_sequence: + case isl_schedule_node_set: + case isl_schedule_node_error: + case isl_schedule_node_leaf: + break; + } + isl_schedule_tree_list_free(tree->children); + isl_ctx_deref(tree->ctx); + free(tree); + + return NULL; +} + +/* Create and return a new leaf schedule tree. + */ +__isl_give isl_schedule_tree *isl_schedule_tree_leaf(isl_ctx *ctx) +{ + return isl_schedule_tree_alloc(ctx, isl_schedule_node_leaf); +} + +/* Create a new band schedule tree referring to "band" + * with no children. + */ +__isl_give isl_schedule_tree *isl_schedule_tree_from_band( + __isl_take isl_schedule_band *band) +{ + isl_ctx *ctx; + isl_schedule_tree *tree; + + if (!band) + return NULL; + + ctx = isl_schedule_band_get_ctx(band); + tree = isl_schedule_tree_alloc(ctx, isl_schedule_node_band); + if (!tree) + goto error; + + tree->band = band; + tree->anchored = isl_schedule_band_is_anchored(band); + + return tree; +error: + isl_schedule_band_free(band); + return NULL; +} + +/* Create a new context schedule tree with the given context and no children. + * Since the context references the outer schedule dimension, + * the tree is anchored. + */ +__isl_give isl_schedule_tree *isl_schedule_tree_from_context( + __isl_take isl_set *context) +{ + isl_ctx *ctx; + isl_schedule_tree *tree; + + if (!context) + return NULL; + + ctx = isl_set_get_ctx(context); + tree = isl_schedule_tree_alloc(ctx, isl_schedule_node_context); + if (!tree) + goto error; + + tree->context = context; + tree->anchored = 1; + + return tree; +error: + isl_set_free(context); + return NULL; +} + +/* Create a new domain schedule tree with the given domain and no children. + */ +__isl_give isl_schedule_tree *isl_schedule_tree_from_domain( + __isl_take isl_union_set *domain) +{ + isl_ctx *ctx; + isl_schedule_tree *tree; + + if (!domain) + return NULL; + + ctx = isl_union_set_get_ctx(domain); + tree = isl_schedule_tree_alloc(ctx, isl_schedule_node_domain); + if (!tree) + goto error; + + tree->domain = domain; + + return tree; +error: + isl_union_set_free(domain); + return NULL; +} + +/* Create a new expansion schedule tree with the given contraction and + * expansion and no children. + */ +__isl_give isl_schedule_tree *isl_schedule_tree_from_expansion( + __isl_take isl_union_pw_multi_aff *contraction, + __isl_take isl_union_map *expansion) +{ + isl_ctx *ctx; + isl_schedule_tree *tree; + + if (!contraction || !expansion) + goto error; + + ctx = isl_union_map_get_ctx(expansion); + tree = isl_schedule_tree_alloc(ctx, isl_schedule_node_expansion); + if (!tree) + goto error; + + tree->contraction = contraction; + tree->expansion = expansion; + + return tree; +error: + isl_union_pw_multi_aff_free(contraction); + isl_union_map_free(expansion); + return NULL; +} + +/* Create a new extension schedule tree with the given extension and + * no children. + * Since the domain of the extension refers to the outer schedule dimension, + * the tree is anchored. + */ +__isl_give isl_schedule_tree *isl_schedule_tree_from_extension( + __isl_take isl_union_map *extension) +{ + isl_ctx *ctx; + isl_schedule_tree *tree; + + if (!extension) + return NULL; + + ctx = isl_union_map_get_ctx(extension); + tree = isl_schedule_tree_alloc(ctx, isl_schedule_node_extension); + if (!tree) + goto error; + + tree->extension = extension; + tree->anchored = 1; + + return tree; +error: + isl_union_map_free(extension); + return NULL; +} + +/* Create a new filter schedule tree with the given filter and no children. + */ +__isl_give isl_schedule_tree *isl_schedule_tree_from_filter( + __isl_take isl_union_set *filter) +{ + isl_ctx *ctx; + isl_schedule_tree *tree; + + if (!filter) + return NULL; + + ctx = isl_union_set_get_ctx(filter); + tree = isl_schedule_tree_alloc(ctx, isl_schedule_node_filter); + if (!tree) + goto error; + + tree->filter = filter; + + return tree; +error: + isl_union_set_free(filter); + return NULL; +} + +/* Create a new guard schedule tree with the given guard and no children. + * Since the guard references the outer schedule dimension, + * the tree is anchored. + */ +__isl_give isl_schedule_tree *isl_schedule_tree_from_guard( + __isl_take isl_set *guard) +{ + isl_ctx *ctx; + isl_schedule_tree *tree; + + if (!guard) + return NULL; + + ctx = isl_set_get_ctx(guard); + tree = isl_schedule_tree_alloc(ctx, isl_schedule_node_guard); + if (!tree) + goto error; + + tree->guard = guard; + tree->anchored = 1; + + return tree; +error: + isl_set_free(guard); + return NULL; +} + +/* Create a new mark schedule tree with the given mark identifier and + * no children. + */ +__isl_give isl_schedule_tree *isl_schedule_tree_from_mark( + __isl_take isl_id *mark) +{ + isl_ctx *ctx; + isl_schedule_tree *tree; + + if (!mark) + return NULL; + + ctx = isl_id_get_ctx(mark); + tree = isl_schedule_tree_alloc(ctx, isl_schedule_node_mark); + if (!tree) + goto error; + + tree->mark = mark; + + return tree; +error: + isl_id_free(mark); + return NULL; +} + +/* Does "tree" have any node that depends on its position + * in the complete schedule tree? + */ +isl_bool isl_schedule_tree_is_subtree_anchored( + __isl_keep isl_schedule_tree *tree) +{ + return tree ? isl_bool_ok(tree->anchored) : isl_bool_error; +} + +/* Does the root node of "tree" depend on its position in the complete + * schedule tree? + * Band nodes may be anchored depending on the associated AST build options. + * Context, extension and guard nodes are always anchored. + */ +int isl_schedule_tree_is_anchored(__isl_keep isl_schedule_tree *tree) +{ + if (!tree) + return -1; + + switch (isl_schedule_tree_get_type(tree)) { + case isl_schedule_node_error: + return -1; + case isl_schedule_node_band: + return isl_schedule_band_is_anchored(tree->band); + case isl_schedule_node_context: + case isl_schedule_node_extension: + case isl_schedule_node_guard: + return 1; + case isl_schedule_node_domain: + case isl_schedule_node_expansion: + case isl_schedule_node_filter: + case isl_schedule_node_leaf: + case isl_schedule_node_mark: + case isl_schedule_node_sequence: + case isl_schedule_node_set: + return 0; + } + + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_internal, + "unhandled case", return -1); +} + +/* Update the anchored field of "tree" based on whether the root node + * itself in anchored and the anchored fields of the children. + * + * This function should be called whenever the children of a tree node + * are changed or the anchoredness of the tree root itself changes. + */ +__isl_give isl_schedule_tree *isl_schedule_tree_update_anchored( + __isl_take isl_schedule_tree *tree) +{ + int i; + isl_size n; + int anchored; + + anchored = isl_schedule_tree_is_anchored(tree); + n = isl_schedule_tree_n_children(tree); + if (anchored < 0 || n < 0) + return isl_schedule_tree_free(tree); + + for (i = 0; !anchored && i < n; ++i) { + isl_schedule_tree *child; + + child = isl_schedule_tree_get_child(tree, i); + if (!child) + return isl_schedule_tree_free(tree); + anchored = child->anchored; + isl_schedule_tree_free(child); + } + + if (anchored == tree->anchored) + return tree; + tree = isl_schedule_tree_cow(tree); + if (!tree) + return NULL; + tree->anchored = anchored; + return tree; +} + +/* Create a new tree of the given type (isl_schedule_node_sequence or + * isl_schedule_node_set) with the given children. + */ +__isl_give isl_schedule_tree *isl_schedule_tree_from_children( + enum isl_schedule_node_type type, + __isl_take isl_schedule_tree_list *list) +{ + isl_ctx *ctx; + isl_schedule_tree *tree; + + if (!list) + return NULL; + + ctx = isl_schedule_tree_list_get_ctx(list); + tree = isl_schedule_tree_alloc(ctx, type); + if (!tree) + goto error; + + tree->children = list; + tree = isl_schedule_tree_update_anchored(tree); + + return tree; +error: + isl_schedule_tree_list_free(list); + return NULL; +} + +/* Construct a tree with a root node of type "type" and as children + * "tree1" and "tree2". + * If the root of one (or both) of the input trees is itself of type "type", + * then the tree is replaced by its children. + */ +__isl_give isl_schedule_tree *isl_schedule_tree_from_pair( + enum isl_schedule_node_type type, __isl_take isl_schedule_tree *tree1, + __isl_take isl_schedule_tree *tree2) +{ + isl_ctx *ctx; + isl_schedule_tree_list *list; + + if (!tree1 || !tree2) + goto error; + + ctx = isl_schedule_tree_get_ctx(tree1); + if (isl_schedule_tree_get_type(tree1) == type) { + list = isl_schedule_tree_list_copy(tree1->children); + isl_schedule_tree_free(tree1); + } else { + list = isl_schedule_tree_list_alloc(ctx, 2); + list = isl_schedule_tree_list_add(list, tree1); + } + if (isl_schedule_tree_get_type(tree2) == type) { + isl_schedule_tree_list *children; + + children = isl_schedule_tree_list_copy(tree2->children); + list = isl_schedule_tree_list_concat(list, children); + isl_schedule_tree_free(tree2); + } else { + list = isl_schedule_tree_list_add(list, tree2); + } + + return isl_schedule_tree_from_children(type, list); +error: + isl_schedule_tree_free(tree1); + isl_schedule_tree_free(tree2); + return NULL; +} + +/* Construct a tree with a sequence root node and as children + * "tree1" and "tree2". + * If the root of one (or both) of the input trees is itself a sequence, + * then the tree is replaced by its children. + */ +__isl_give isl_schedule_tree *isl_schedule_tree_sequence_pair( + __isl_take isl_schedule_tree *tree1, + __isl_take isl_schedule_tree *tree2) +{ + return isl_schedule_tree_from_pair(isl_schedule_node_sequence, + tree1, tree2); +} + +/* Construct a tree with a set root node and as children + * "tree1" and "tree2". + * If the root of one (or both) of the input trees is itself a set, + * then the tree is replaced by its children. + */ +__isl_give isl_schedule_tree *isl_schedule_tree_set_pair( + __isl_take isl_schedule_tree *tree1, + __isl_take isl_schedule_tree *tree2) +{ + return isl_schedule_tree_from_pair(isl_schedule_node_set, tree1, tree2); +} + +/* Return the isl_ctx to which "tree" belongs. + */ +isl_ctx *isl_schedule_tree_get_ctx(__isl_keep isl_schedule_tree *tree) +{ + return tree ? tree->ctx : NULL; +} + +/* Return the type of the root of the tree or isl_schedule_node_error + * on error. + */ +enum isl_schedule_node_type isl_schedule_tree_get_type( + __isl_keep isl_schedule_tree *tree) +{ + return tree ? tree->type : isl_schedule_node_error; +} + +/* Are "tree1" and "tree2" obviously equal to each other? + */ +isl_bool isl_schedule_tree_plain_is_equal(__isl_keep isl_schedule_tree *tree1, + __isl_keep isl_schedule_tree *tree2) +{ + isl_bool equal; + int i; + isl_size n1, n2; + + if (!tree1 || !tree2) + return isl_bool_error; + if (tree1 == tree2) + return isl_bool_true; + if (tree1->type != tree2->type) + return isl_bool_false; + + switch (tree1->type) { + case isl_schedule_node_band: + equal = isl_schedule_band_plain_is_equal(tree1->band, + tree2->band); + break; + case isl_schedule_node_context: + equal = isl_set_is_equal(tree1->context, tree2->context); + break; + case isl_schedule_node_domain: + equal = isl_union_set_is_equal(tree1->domain, tree2->domain); + break; + case isl_schedule_node_expansion: + equal = isl_union_map_is_equal(tree1->expansion, + tree2->expansion); + if (equal >= 0 && equal) + equal = isl_union_pw_multi_aff_plain_is_equal( + tree1->contraction, tree2->contraction); + break; + case isl_schedule_node_extension: + equal = isl_union_map_is_equal(tree1->extension, + tree2->extension); + break; + case isl_schedule_node_filter: + equal = isl_union_set_is_equal(tree1->filter, tree2->filter); + break; + case isl_schedule_node_guard: + equal = isl_set_is_equal(tree1->guard, tree2->guard); + break; + case isl_schedule_node_mark: + equal = isl_bool_ok(tree1->mark == tree2->mark); + break; + case isl_schedule_node_leaf: + case isl_schedule_node_sequence: + case isl_schedule_node_set: + equal = isl_bool_true; + break; + case isl_schedule_node_error: + equal = isl_bool_error; + break; + } + + if (equal < 0 || !equal) + return equal; + + n1 = isl_schedule_tree_n_children(tree1); + n2 = isl_schedule_tree_n_children(tree2); + if (n1 < 0 || n2 < 0) + return isl_bool_error; + if (n1 != n2) + return isl_bool_false; + for (i = 0; i < n1; ++i) { + isl_schedule_tree *child1, *child2; + + child1 = isl_schedule_tree_get_child(tree1, i); + child2 = isl_schedule_tree_get_child(tree2, i); + equal = isl_schedule_tree_plain_is_equal(child1, child2); + isl_schedule_tree_free(child1); + isl_schedule_tree_free(child2); + + if (equal < 0 || !equal) + return equal; + } + + return isl_bool_true; +} + +/* Does "tree" have any children, other than an implicit leaf. + */ +int isl_schedule_tree_has_children(__isl_keep isl_schedule_tree *tree) +{ + if (!tree) + return -1; + + return tree->children != NULL; +} + +/* Return the number of children of "tree", excluding implicit leaves. + * The "children" field is NULL if there are + * no children (except for the implicit leaves). + */ +isl_size isl_schedule_tree_n_children(__isl_keep isl_schedule_tree *tree) +{ + if (!tree) + return isl_size_error; + + if (!tree->children) + return 0; + return isl_schedule_tree_list_n_schedule_tree(tree->children); +} + +/* Return a copy of the (explicit) child at position "pos" of "tree". + */ +__isl_give isl_schedule_tree *isl_schedule_tree_get_child( + __isl_keep isl_schedule_tree *tree, int pos) +{ + if (!tree) + return NULL; + if (!tree->children) + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_internal, + "schedule tree has no explicit children", return NULL); + return isl_schedule_tree_list_get_schedule_tree(tree->children, pos); +} + +/* Return a copy of the (explicit) child at position "pos" of "tree" and + * free "tree". + */ +__isl_give isl_schedule_tree *isl_schedule_tree_child( + __isl_take isl_schedule_tree *tree, int pos) +{ + isl_schedule_tree *child; + + child = isl_schedule_tree_get_child(tree, pos); + isl_schedule_tree_free(tree); + return child; +} + +/* Remove all (explicit) children from "tree". + */ +__isl_give isl_schedule_tree *isl_schedule_tree_reset_children( + __isl_take isl_schedule_tree *tree) +{ + tree = isl_schedule_tree_cow(tree); + if (!tree) + return NULL; + tree->children = isl_schedule_tree_list_free(tree->children); + return tree; +} + +/* Remove the child at position "pos" from the children of "tree". + * If there was only one child to begin with, then remove all children. + */ +__isl_give isl_schedule_tree *isl_schedule_tree_drop_child( + __isl_take isl_schedule_tree *tree, int pos) +{ + isl_size n; + + tree = isl_schedule_tree_cow(tree); + + n = isl_schedule_tree_n_children(tree); + if (n < 0) + return isl_schedule_tree_free(tree); + if (n == 0) + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid, + "tree does not have any explicit children", + return isl_schedule_tree_free(tree)); + if (pos < 0 || pos >= n) + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid, + "position out of bounds", + return isl_schedule_tree_free(tree)); + if (n == 1) + return isl_schedule_tree_reset_children(tree); + + tree->children = isl_schedule_tree_list_drop(tree->children, pos, 1); + if (!tree->children) + return isl_schedule_tree_free(tree); + + return tree; +} + +/* Replace the child at position "pos" of "tree" by "child". + * + * If the new child is a leaf, then it is not explicitly + * recorded in the list of children. Instead, the list of children + * (which is assumed to have only one element) is removed. + * Note that the children of set and sequence nodes are always + * filters, so they cannot be replaced by empty trees. + */ +__isl_give isl_schedule_tree *isl_schedule_tree_replace_child( + __isl_take isl_schedule_tree *tree, int pos, + __isl_take isl_schedule_tree *child) +{ + tree = isl_schedule_tree_cow(tree); + if (!tree || !child) + goto error; + + if (isl_schedule_tree_is_leaf(child)) { + isl_size n; + + isl_schedule_tree_free(child); + if (!tree->children && pos == 0) + return tree; + n = isl_schedule_tree_n_children(tree); + if (n < 0) + return isl_schedule_tree_free(tree); + if (n != 1) + isl_die(isl_schedule_tree_get_ctx(tree), + isl_error_internal, + "can only replace single child by leaf", + goto error); + return isl_schedule_tree_reset_children(tree); + } + + if (!tree->children && pos == 0) + tree->children = + isl_schedule_tree_list_from_schedule_tree(child); + else + tree->children = isl_schedule_tree_list_set_schedule_tree( + tree->children, pos, child); + + if (!tree->children) + return isl_schedule_tree_free(tree); + tree = isl_schedule_tree_update_anchored(tree); + + return tree; +error: + isl_schedule_tree_free(tree); + isl_schedule_tree_free(child); + return NULL; +} + +/* Replace the (explicit) children of "tree" by "children"? + */ +__isl_give isl_schedule_tree *isl_schedule_tree_set_children( + __isl_take isl_schedule_tree *tree, + __isl_take isl_schedule_tree_list *children) +{ + tree = isl_schedule_tree_cow(tree); + if (!tree || !children) + goto error; + isl_schedule_tree_list_free(tree->children); + tree->children = children; + return tree; +error: + isl_schedule_tree_free(tree); + isl_schedule_tree_list_free(children); + return NULL; +} + +/* Create a new band schedule tree referring to "band" + * with "tree" as single child. + */ +__isl_give isl_schedule_tree *isl_schedule_tree_insert_band( + __isl_take isl_schedule_tree *tree, __isl_take isl_schedule_band *band) +{ + isl_schedule_tree *res; + + res = isl_schedule_tree_from_band(band); + return isl_schedule_tree_replace_child(res, 0, tree); +} + +/* Create a new context schedule tree with the given context and + * with "tree" as single child. + */ +__isl_give isl_schedule_tree *isl_schedule_tree_insert_context( + __isl_take isl_schedule_tree *tree, __isl_take isl_set *context) +{ + isl_schedule_tree *res; + + res = isl_schedule_tree_from_context(context); + return isl_schedule_tree_replace_child(res, 0, tree); +} + +/* Create a new domain schedule tree with the given domain and + * with "tree" as single child. + */ +__isl_give isl_schedule_tree *isl_schedule_tree_insert_domain( + __isl_take isl_schedule_tree *tree, __isl_take isl_union_set *domain) +{ + isl_schedule_tree *res; + + res = isl_schedule_tree_from_domain(domain); + return isl_schedule_tree_replace_child(res, 0, tree); +} + +/* Create a new expansion schedule tree with the given contraction and + * expansion and with "tree" as single child. + */ +__isl_give isl_schedule_tree *isl_schedule_tree_insert_expansion( + __isl_take isl_schedule_tree *tree, + __isl_take isl_union_pw_multi_aff *contraction, + __isl_take isl_union_map *expansion) +{ + isl_schedule_tree *res; + + res = isl_schedule_tree_from_expansion(contraction, expansion); + return isl_schedule_tree_replace_child(res, 0, tree); +} + +/* Create a new extension schedule tree with the given extension and + * with "tree" as single child. + */ +__isl_give isl_schedule_tree *isl_schedule_tree_insert_extension( + __isl_take isl_schedule_tree *tree, __isl_take isl_union_map *extension) +{ + isl_schedule_tree *res; + + res = isl_schedule_tree_from_extension(extension); + return isl_schedule_tree_replace_child(res, 0, tree); +} + +/* Create a new filter schedule tree with the given filter and single child. + * + * If the root of "tree" is itself a filter node, then the two + * filter nodes are merged into one node. + */ +__isl_give isl_schedule_tree *isl_schedule_tree_insert_filter( + __isl_take isl_schedule_tree *tree, __isl_take isl_union_set *filter) +{ + isl_schedule_tree *res; + + if (isl_schedule_tree_get_type(tree) == isl_schedule_node_filter) { + isl_union_set *tree_filter; + + tree_filter = isl_schedule_tree_filter_get_filter(tree); + tree_filter = isl_union_set_intersect(tree_filter, filter); + tree = isl_schedule_tree_filter_set_filter(tree, tree_filter); + return tree; + } + + res = isl_schedule_tree_from_filter(filter); + return isl_schedule_tree_replace_child(res, 0, tree); +} + +/* Insert a filter node with filter set "filter" + * in each of the children of "tree". + */ +__isl_give isl_schedule_tree *isl_schedule_tree_children_insert_filter( + __isl_take isl_schedule_tree *tree, __isl_take isl_union_set *filter) +{ + int i; + isl_size n; + + n = isl_schedule_tree_n_children(tree); + if (n < 0 || !filter) + goto error; + + for (i = 0; i < n; ++i) { + isl_schedule_tree *child; + + child = isl_schedule_tree_get_child(tree, i); + child = isl_schedule_tree_insert_filter(child, + isl_union_set_copy(filter)); + tree = isl_schedule_tree_replace_child(tree, i, child); + } + + isl_union_set_free(filter); + return tree; +error: + isl_union_set_free(filter); + isl_schedule_tree_free(tree); + return NULL; +} + +/* Create a new guard schedule tree with the given guard and + * with "tree" as single child. + */ +__isl_give isl_schedule_tree *isl_schedule_tree_insert_guard( + __isl_take isl_schedule_tree *tree, __isl_take isl_set *guard) +{ + isl_schedule_tree *res; + + res = isl_schedule_tree_from_guard(guard); + return isl_schedule_tree_replace_child(res, 0, tree); +} + +/* Create a new mark schedule tree with the given mark identifier and + * single child. + */ +__isl_give isl_schedule_tree *isl_schedule_tree_insert_mark( + __isl_take isl_schedule_tree *tree, __isl_take isl_id *mark) +{ + isl_schedule_tree *res; + + res = isl_schedule_tree_from_mark(mark); + return isl_schedule_tree_replace_child(res, 0, tree); +} + +/* Return the number of members in the band tree root. + */ +isl_size isl_schedule_tree_band_n_member(__isl_keep isl_schedule_tree *tree) +{ + if (!tree) + return isl_size_error; + + if (tree->type != isl_schedule_node_band) + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid, + "not a band node", return isl_size_error); + + return isl_schedule_band_n_member(tree->band); +} + +/* Is the band member at position "pos" of the band tree root + * marked coincident? + */ +isl_bool isl_schedule_tree_band_member_get_coincident( + __isl_keep isl_schedule_tree *tree, int pos) +{ + if (!tree) + return isl_bool_error; + + if (tree->type != isl_schedule_node_band) + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid, + "not a band node", return isl_bool_error); + + return isl_schedule_band_member_get_coincident(tree->band, pos); +} + +/* Mark the given band member as being coincident or not + * according to "coincident". + */ +__isl_give isl_schedule_tree *isl_schedule_tree_band_member_set_coincident( + __isl_take isl_schedule_tree *tree, int pos, int coincident) +{ + if (!tree) + return NULL; + if (tree->type != isl_schedule_node_band) + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid, + "not a band node", return isl_schedule_tree_free(tree)); + if (isl_schedule_tree_band_member_get_coincident(tree, pos) == + coincident) + return tree; + tree = isl_schedule_tree_cow(tree); + if (!tree) + return NULL; + + tree->band = isl_schedule_band_member_set_coincident(tree->band, pos, + coincident); + if (!tree->band) + return isl_schedule_tree_free(tree); + return tree; +} + +/* Is the band tree root marked permutable? + */ +isl_bool isl_schedule_tree_band_get_permutable( + __isl_keep isl_schedule_tree *tree) +{ + if (!tree) + return isl_bool_error; + + if (tree->type != isl_schedule_node_band) + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid, + "not a band node", return isl_bool_error); + + return isl_schedule_band_get_permutable(tree->band); +} + +/* Mark the band tree root permutable or not according to "permutable"? + */ +__isl_give isl_schedule_tree *isl_schedule_tree_band_set_permutable( + __isl_take isl_schedule_tree *tree, int permutable) +{ + if (!tree) + return NULL; + if (tree->type != isl_schedule_node_band) + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid, + "not a band node", return isl_schedule_tree_free(tree)); + if (isl_schedule_tree_band_get_permutable(tree) == permutable) + return tree; + tree = isl_schedule_tree_cow(tree); + if (!tree) + return NULL; + + tree->band = isl_schedule_band_set_permutable(tree->band, permutable); + if (!tree->band) + return isl_schedule_tree_free(tree); + return tree; +} + +/* Return the schedule space of the band tree root. + */ +__isl_give isl_space *isl_schedule_tree_band_get_space( + __isl_keep isl_schedule_tree *tree) +{ + if (!tree) + return NULL; + + if (tree->type != isl_schedule_node_band) + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid, + "not a band node", return NULL); + + return isl_schedule_band_get_space(tree->band); +} + +/* Intersect the domain of the band schedule of the band tree root + * with "domain". + */ +__isl_give isl_schedule_tree *isl_schedule_tree_band_intersect_domain( + __isl_take isl_schedule_tree *tree, __isl_take isl_union_set *domain) +{ + if (!tree || !domain) + goto error; + + if (tree->type != isl_schedule_node_band) + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid, + "not a band node", goto error); + + tree->band = isl_schedule_band_intersect_domain(tree->band, domain); + if (!tree->band) + return isl_schedule_tree_free(tree); + + return tree; +error: + isl_schedule_tree_free(tree); + isl_union_set_free(domain); + return NULL; +} + +/* Return the schedule of the band tree root in isolation. + */ +__isl_give isl_multi_union_pw_aff *isl_schedule_tree_band_get_partial_schedule( + __isl_keep isl_schedule_tree *tree) +{ + if (!tree) + return NULL; + + if (tree->type != isl_schedule_node_band) + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid, + "not a band node", return NULL); + + return isl_schedule_band_get_partial_schedule(tree->band); +} + +/* Replace the schedule of the band tree root by "schedule". + */ +__isl_give isl_schedule_tree *isl_schedule_tree_band_set_partial_schedule( + __isl_take isl_schedule_tree *tree, + __isl_take isl_multi_union_pw_aff *schedule) +{ + tree = isl_schedule_tree_cow(tree); + if (!tree || !schedule) + goto error; + + if (tree->type != isl_schedule_node_band) + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid, + "not a band node", return NULL); + tree->band = isl_schedule_band_set_partial_schedule(tree->band, + schedule); + + return tree; +error: + isl_schedule_tree_free(tree); + isl_multi_union_pw_aff_free(schedule); + return NULL; +} + +/* Return the loop AST generation type for the band member + * of the band tree root at position "pos". + */ +enum isl_ast_loop_type isl_schedule_tree_band_member_get_ast_loop_type( + __isl_keep isl_schedule_tree *tree, int pos) +{ + if (!tree) + return isl_ast_loop_error; + + if (tree->type != isl_schedule_node_band) + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid, + "not a band node", return isl_ast_loop_error); + + return isl_schedule_band_member_get_ast_loop_type(tree->band, pos); +} + +/* Set the loop AST generation type for the band member of the band tree root + * at position "pos" to "type". + */ +__isl_give isl_schedule_tree *isl_schedule_tree_band_member_set_ast_loop_type( + __isl_take isl_schedule_tree *tree, int pos, + enum isl_ast_loop_type type) +{ + tree = isl_schedule_tree_cow(tree); + if (!tree) + return NULL; + + if (tree->type != isl_schedule_node_band) + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid, + "not a band node", return isl_schedule_tree_free(tree)); + + tree->band = isl_schedule_band_member_set_ast_loop_type(tree->band, + pos, type); + if (!tree->band) + return isl_schedule_tree_free(tree); + + return tree; +} + +/* Return the loop AST generation type for the band member + * of the band tree root at position "pos" for the isolated part. + */ +enum isl_ast_loop_type isl_schedule_tree_band_member_get_isolate_ast_loop_type( + __isl_keep isl_schedule_tree *tree, int pos) +{ + if (!tree) + return isl_ast_loop_error; + + if (tree->type != isl_schedule_node_band) + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid, + "not a band node", return isl_ast_loop_error); + + return isl_schedule_band_member_get_isolate_ast_loop_type(tree->band, + pos); +} + +/* Set the loop AST generation type for the band member of the band tree root + * at position "pos" for the isolated part to "type". + */ +__isl_give isl_schedule_tree * +isl_schedule_tree_band_member_set_isolate_ast_loop_type( + __isl_take isl_schedule_tree *tree, int pos, + enum isl_ast_loop_type type) +{ + tree = isl_schedule_tree_cow(tree); + if (!tree) + return NULL; + + if (tree->type != isl_schedule_node_band) + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid, + "not a band node", return isl_schedule_tree_free(tree)); + + tree->band = isl_schedule_band_member_set_isolate_ast_loop_type( + tree->band, pos, type); + if (!tree->band) + return isl_schedule_tree_free(tree); + + return tree; +} + +/* Return the AST build options associated to the band tree root. + */ +__isl_give isl_union_set *isl_schedule_tree_band_get_ast_build_options( + __isl_keep isl_schedule_tree *tree) +{ + if (!tree) + return NULL; + + if (tree->type != isl_schedule_node_band) + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid, + "not a band node", return NULL); + + return isl_schedule_band_get_ast_build_options(tree->band); +} + +/* Replace the AST build options associated to band tree root by "options". + * Updated the anchored field if the anchoredness of the root node itself + * changes. + */ +__isl_give isl_schedule_tree *isl_schedule_tree_band_set_ast_build_options( + __isl_take isl_schedule_tree *tree, __isl_take isl_union_set *options) +{ + int was_anchored; + + tree = isl_schedule_tree_cow(tree); + if (!tree || !options) + goto error; + + if (tree->type != isl_schedule_node_band) + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid, + "not a band node", goto error); + + was_anchored = isl_schedule_tree_is_anchored(tree); + tree->band = isl_schedule_band_set_ast_build_options(tree->band, + options); + if (!tree->band) + return isl_schedule_tree_free(tree); + if (isl_schedule_tree_is_anchored(tree) != was_anchored) + tree = isl_schedule_tree_update_anchored(tree); + + return tree; +error: + isl_schedule_tree_free(tree); + isl_union_set_free(options); + return NULL; +} + +/* Return the "isolate" option associated to the band tree root of "tree", + * which is assumed to appear at schedule depth "depth". + */ +__isl_give isl_set *isl_schedule_tree_band_get_ast_isolate_option( + __isl_keep isl_schedule_tree *tree, int depth) +{ + if (!tree) + return NULL; + + if (tree->type != isl_schedule_node_band) + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid, + "not a band node", return NULL); + + return isl_schedule_band_get_ast_isolate_option(tree->band, depth); +} + +/* Return the context of the context tree root. + */ +__isl_give isl_set *isl_schedule_tree_context_get_context( + __isl_keep isl_schedule_tree *tree) +{ + if (!tree) + return NULL; + + if (tree->type != isl_schedule_node_context) + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid, + "not a context node", return NULL); + + return isl_set_copy(tree->context); +} + +/* Return the domain of the domain tree root. + */ +__isl_give isl_union_set *isl_schedule_tree_domain_get_domain( + __isl_keep isl_schedule_tree *tree) +{ + if (!tree) + return NULL; + + if (tree->type != isl_schedule_node_domain) + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid, + "not a domain node", return NULL); + + return isl_union_set_copy(tree->domain); +} + +/* Replace the domain of domain tree root "tree" by "domain". + */ +__isl_give isl_schedule_tree *isl_schedule_tree_domain_set_domain( + __isl_take isl_schedule_tree *tree, __isl_take isl_union_set *domain) +{ + tree = isl_schedule_tree_cow(tree); + if (!tree || !domain) + goto error; + + if (tree->type != isl_schedule_node_domain) + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid, + "not a domain node", goto error); + + isl_union_set_free(tree->domain); + tree->domain = domain; + + return tree; +error: + isl_schedule_tree_free(tree); + isl_union_set_free(domain); + return NULL; +} + +/* Return the contraction of the expansion tree root. + */ +__isl_give isl_union_pw_multi_aff *isl_schedule_tree_expansion_get_contraction( + __isl_keep isl_schedule_tree *tree) +{ + if (!tree) + return NULL; + + if (tree->type != isl_schedule_node_expansion) + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid, + "not an expansion node", return NULL); + + return isl_union_pw_multi_aff_copy(tree->contraction); +} + +/* Return the expansion of the expansion tree root. + */ +__isl_give isl_union_map *isl_schedule_tree_expansion_get_expansion( + __isl_keep isl_schedule_tree *tree) +{ + if (!tree) + return NULL; + + if (tree->type != isl_schedule_node_expansion) + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid, + "not an expansion node", return NULL); + + return isl_union_map_copy(tree->expansion); +} + +/* Replace the contraction and the expansion of the expansion tree root "tree" + * by "contraction" and "expansion". + */ +__isl_give isl_schedule_tree * +isl_schedule_tree_expansion_set_contraction_and_expansion( + __isl_take isl_schedule_tree *tree, + __isl_take isl_union_pw_multi_aff *contraction, + __isl_take isl_union_map *expansion) +{ + tree = isl_schedule_tree_cow(tree); + if (!tree || !contraction || !expansion) + goto error; + + if (tree->type != isl_schedule_node_expansion) + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid, + "not an expansion node", return NULL); + + isl_union_pw_multi_aff_free(tree->contraction); + tree->contraction = contraction; + isl_union_map_free(tree->expansion); + tree->expansion = expansion; + + return tree; +error: + isl_schedule_tree_free(tree); + isl_union_pw_multi_aff_free(contraction); + isl_union_map_free(expansion); + return NULL; +} + +/* Return the extension of the extension tree root. + */ +__isl_give isl_union_map *isl_schedule_tree_extension_get_extension( + __isl_take isl_schedule_tree *tree) +{ + if (!tree) + return NULL; + + if (tree->type != isl_schedule_node_extension) + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid, + "not an extension node", return NULL); + + return isl_union_map_copy(tree->extension); +} + +/* Replace the extension of extension tree root "tree" by "extension". + */ +__isl_give isl_schedule_tree *isl_schedule_tree_extension_set_extension( + __isl_take isl_schedule_tree *tree, __isl_take isl_union_map *extension) +{ + tree = isl_schedule_tree_cow(tree); + if (!tree || !extension) + goto error; + + if (tree->type != isl_schedule_node_extension) + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid, + "not an extension node", return NULL); + isl_union_map_free(tree->extension); + tree->extension = extension; + + return tree; +error: + isl_schedule_tree_free(tree); + isl_union_map_free(extension); + return NULL; +} + +/* Return the filter of the filter tree root. + */ +__isl_give isl_union_set *isl_schedule_tree_filter_get_filter( + __isl_keep isl_schedule_tree *tree) +{ + if (!tree) + return NULL; + + if (tree->type != isl_schedule_node_filter) + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid, + "not a filter node", return NULL); + + return isl_union_set_copy(tree->filter); +} + +/* Replace the filter of the filter tree root by "filter". + */ +__isl_give isl_schedule_tree *isl_schedule_tree_filter_set_filter( + __isl_take isl_schedule_tree *tree, __isl_take isl_union_set *filter) +{ + tree = isl_schedule_tree_cow(tree); + if (!tree || !filter) + goto error; + + if (tree->type != isl_schedule_node_filter) + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid, + "not a filter node", return NULL); + + isl_union_set_free(tree->filter); + tree->filter = filter; + + return tree; +error: + isl_schedule_tree_free(tree); + isl_union_set_free(filter); + return NULL; +} + +/* Return the guard of the guard tree root. + */ +__isl_give isl_set *isl_schedule_tree_guard_get_guard( + __isl_take isl_schedule_tree *tree) +{ + if (!tree) + return NULL; + + if (tree->type != isl_schedule_node_guard) + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid, + "not a guard node", return NULL); + + return isl_set_copy(tree->guard); +} + +/* Return the mark identifier of the mark tree root "tree". + */ +__isl_give isl_id *isl_schedule_tree_mark_get_id( + __isl_keep isl_schedule_tree *tree) +{ + if (!tree) + return NULL; + + if (tree->type != isl_schedule_node_mark) + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid, + "not a mark node", return NULL); + + return isl_id_copy(tree->mark); +} + +/* Set dim to the range dimension of "map" and abort the search. + */ +static isl_stat set_range_dim(__isl_take isl_map *map, void *user) +{ + isl_size *dim = user; + + *dim = isl_map_dim(map, isl_dim_out); + isl_map_free(map); + + return isl_stat_error; +} + +/* Return the dimension of the range of "umap". + * "umap" is assumed not to be empty and + * all maps inside "umap" are assumed to have the same range. + * + * We extract the range dimension from the first map in "umap". + */ +static isl_size range_dim(__isl_keep isl_union_map *umap) +{ + isl_size dim = isl_size_error; + isl_size n; + + n = isl_union_map_n_map(umap); + if (n < 0) + return isl_size_error; + if (n == 0) + isl_die(isl_union_map_get_ctx(umap), isl_error_internal, + "unexpected empty input", return isl_size_error); + + isl_union_map_foreach_map(umap, &set_range_dim, &dim); + + return dim; +} + +/* Append an "extra" number of zeros to the range of "umap" and + * return the result. + */ +static __isl_give isl_union_map *append_range(__isl_take isl_union_map *umap, + int extra) +{ + isl_union_set *dom; + isl_space *space; + isl_multi_val *mv; + isl_union_pw_multi_aff *suffix; + isl_union_map *universe; + isl_union_map *suffix_umap; + + universe = isl_union_map_universe(isl_union_map_copy(umap)); + dom = isl_union_map_domain(universe); + space = isl_union_set_get_space(dom); + space = isl_space_set_from_params(space); + space = isl_space_add_dims(space, isl_dim_set, extra); + mv = isl_multi_val_zero(space); + + suffix = isl_union_pw_multi_aff_multi_val_on_domain(dom, mv); + suffix_umap = isl_union_map_from_union_pw_multi_aff(suffix); + umap = isl_union_map_flat_range_product(umap, suffix_umap); + + return umap; +} + +/* Should we skip the root of "tree" while looking for the first + * descendant with schedule information? + * That is, is it impossible to derive any information about + * the iteration domain from this node? + * + * We do not want to skip leaf or error nodes because there is + * no point in looking any deeper from these nodes. + * We can only extract partial iteration domain information + * from an extension node, but extension nodes are not supported + * by the caller and it will error out on them. + */ +static isl_bool domain_less(__isl_keep isl_schedule_tree *tree) +{ + enum isl_schedule_node_type type; + isl_size n; + + type = isl_schedule_tree_get_type(tree); + switch (type) { + case isl_schedule_node_band: + n = isl_schedule_tree_band_n_member(tree); + return n < 0 ? isl_bool_error : isl_bool_ok(n == 0); + case isl_schedule_node_context: + case isl_schedule_node_guard: + case isl_schedule_node_mark: + return isl_bool_true; + case isl_schedule_node_leaf: + case isl_schedule_node_error: + case isl_schedule_node_domain: + case isl_schedule_node_expansion: + case isl_schedule_node_extension: + case isl_schedule_node_filter: + case isl_schedule_node_set: + case isl_schedule_node_sequence: + return isl_bool_false; + } + + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_internal, + "unhandled case", return isl_bool_error); +} + +/* Move down to the first descendant of "tree" that contains any schedule + * information or return "leaf" if there is no such descendant. + */ +__isl_give isl_schedule_tree *isl_schedule_tree_first_schedule_descendant( + __isl_take isl_schedule_tree *tree, __isl_keep isl_schedule_tree *leaf) +{ + isl_bool down; + + while ((down = domain_less(tree)) == isl_bool_true) { + if (!isl_schedule_tree_has_children(tree)) { + isl_schedule_tree_free(tree); + return isl_schedule_tree_copy(leaf); + } + tree = isl_schedule_tree_child(tree, 0); + } + + if (down < 0) + return isl_schedule_tree_free(tree); + + return tree; +} + +static __isl_give isl_union_map *subtree_schedule_extend( + __isl_keep isl_schedule_tree *tree, __isl_take isl_union_map *outer); + +/* Extend the schedule map "outer" with the subtree schedule + * of the (single) child of "tree", if any. + * + * If "tree" does not have any descendants (apart from those that + * do not carry any schedule information), then we simply return "outer". + * Otherwise, we extend the schedule map "outer" with the subtree schedule + * of the single child. + */ +static __isl_give isl_union_map *subtree_schedule_extend_child( + __isl_keep isl_schedule_tree *tree, __isl_take isl_union_map *outer) +{ + isl_schedule_tree *child; + isl_union_map *res; + + if (!tree) + return isl_union_map_free(outer); + if (!isl_schedule_tree_has_children(tree)) + return outer; + child = isl_schedule_tree_get_child(tree, 0); + if (!child) + return isl_union_map_free(outer); + res = subtree_schedule_extend(child, outer); + isl_schedule_tree_free(child); + return res; +} + +/* Extract the parameter space from one of the children of "tree", + * which are assumed to be filters. + */ +static __isl_give isl_space *extract_space_from_filter_child( + __isl_keep isl_schedule_tree *tree) +{ + isl_space *space; + isl_union_set *dom; + isl_schedule_tree *child; + + child = isl_schedule_tree_list_get_schedule_tree(tree->children, 0); + dom = isl_schedule_tree_filter_get_filter(child); + space = isl_union_set_get_space(dom); + isl_union_set_free(dom); + isl_schedule_tree_free(child); + + return space; +} + +/* Extend the schedule map "outer" with the subtree schedule + * of a set or sequence node. + * + * The schedule for the set or sequence node itself is composed of + * pieces of the form + * + * filter -> [] + * + * or + * + * filter -> [index] + * + * The first form is used if there is only a single child or + * if the current node is a set node and the schedule_separate_components + * option is not set. + * + * Each of the pieces above is extended with the subtree schedule of + * the child of the corresponding filter, if any, padded with zeros + * to ensure that all pieces have the same range dimension. + */ +static __isl_give isl_union_map *subtree_schedule_extend_from_children( + __isl_keep isl_schedule_tree *tree, __isl_take isl_union_map *outer) +{ + int i; + isl_size n; + isl_size dim; + int separate; + isl_ctx *ctx; + isl_val *v = NULL; + isl_multi_val *mv; + isl_space *space; + isl_union_map *umap; + + n = isl_schedule_tree_n_children(tree); + if (n < 0) + return isl_union_map_free(outer); + if (n == 0) + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_internal, + "missing children", return isl_union_map_free(outer)); + + ctx = isl_schedule_tree_get_ctx(tree); + separate = n > 1 && (tree->type == isl_schedule_node_sequence || + isl_options_get_schedule_separate_components(ctx)); + + space = isl_space_params_alloc(ctx, 0); + + umap = isl_union_map_empty(isl_space_copy(space)); + space = isl_space_set_from_params(space); + if (separate) { + space = isl_space_add_dims(space, isl_dim_set, 1); + v = isl_val_zero(ctx); + } + mv = isl_multi_val_zero(space); + + dim = isl_multi_val_dim(mv, isl_dim_set); + if (dim < 0) + umap = isl_union_map_free(umap); + for (i = 0; i < n; ++i) { + isl_multi_val *mv_copy; + isl_union_pw_multi_aff *upma; + isl_union_map *umap_i; + isl_union_set *dom; + isl_schedule_tree *child; + isl_size dim_i; + isl_bool empty; + + child = isl_schedule_tree_list_get_schedule_tree( + tree->children, i); + dom = isl_schedule_tree_filter_get_filter(child); + + if (separate) { + mv = isl_multi_val_set_val(mv, 0, isl_val_copy(v)); + v = isl_val_add_ui(v, 1); + } + mv_copy = isl_multi_val_copy(mv); + space = isl_union_set_get_space(dom); + mv_copy = isl_multi_val_align_params(mv_copy, space); + upma = isl_union_pw_multi_aff_multi_val_on_domain(dom, mv_copy); + umap_i = isl_union_map_from_union_pw_multi_aff(upma); + umap_i = isl_union_map_flat_range_product( + isl_union_map_copy(outer), umap_i); + umap_i = subtree_schedule_extend_child(child, umap_i); + isl_schedule_tree_free(child); + + empty = isl_union_map_is_empty(umap_i); + if (empty < 0) + umap_i = isl_union_map_free(umap_i); + else if (empty) { + isl_union_map_free(umap_i); + continue; + } + + dim_i = range_dim(umap_i); + if (dim_i < 0) { + umap = isl_union_map_free(umap); + } else if (dim < dim_i) { + umap = append_range(umap, dim_i - dim); + dim = dim_i; + } else if (dim_i < dim) { + umap_i = append_range(umap_i, dim - dim_i); + } + umap = isl_union_map_union(umap, umap_i); + } + + isl_val_free(v); + isl_multi_val_free(mv); + isl_union_map_free(outer); + + return umap; +} + +/* Extend the schedule map "outer" with the subtree schedule of "tree". + * + * If the root of the tree is a set or a sequence, then we extend + * the schedule map in subtree_schedule_extend_from_children. + * Otherwise, we extend the schedule map with the partial schedule + * corresponding to the root of the tree and then continue with + * the single child of this root. + * In the special case of an expansion, the schedule map is "extended" + * by applying the expansion to the domain of the schedule map. + */ +static __isl_give isl_union_map *subtree_schedule_extend( + __isl_keep isl_schedule_tree *tree, __isl_take isl_union_map *outer) +{ + isl_multi_union_pw_aff *mupa; + isl_union_map *umap; + isl_union_set *domain; + isl_size n; + + if (!tree) + return NULL; + + switch (tree->type) { + case isl_schedule_node_error: + return isl_union_map_free(outer); + case isl_schedule_node_extension: + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid, + "cannot construct subtree schedule of tree " + "with extension nodes", + return isl_union_map_free(outer)); + case isl_schedule_node_context: + case isl_schedule_node_guard: + case isl_schedule_node_mark: + return subtree_schedule_extend_child(tree, outer); + case isl_schedule_node_band: + n = isl_schedule_tree_band_n_member(tree); + if (n < 0) + return isl_union_map_free(outer); + if (n == 0) + return subtree_schedule_extend_child(tree, outer); + mupa = isl_schedule_band_get_partial_schedule(tree->band); + umap = isl_union_map_from_multi_union_pw_aff(mupa); + outer = isl_union_map_flat_range_product(outer, umap); + umap = subtree_schedule_extend_child(tree, outer); + break; + case isl_schedule_node_domain: + domain = isl_schedule_tree_domain_get_domain(tree); + umap = isl_union_map_from_domain(domain); + outer = isl_union_map_flat_range_product(outer, umap); + umap = subtree_schedule_extend_child(tree, outer); + break; + case isl_schedule_node_expansion: + umap = isl_schedule_tree_expansion_get_expansion(tree); + outer = isl_union_map_apply_domain(outer, umap); + umap = subtree_schedule_extend_child(tree, outer); + break; + case isl_schedule_node_filter: + domain = isl_schedule_tree_filter_get_filter(tree); + umap = isl_union_map_from_domain(domain); + outer = isl_union_map_flat_range_product(outer, umap); + umap = subtree_schedule_extend_child(tree, outer); + break; + case isl_schedule_node_leaf: + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_internal, + "leaf node should be handled by caller", return NULL); + case isl_schedule_node_set: + case isl_schedule_node_sequence: + umap = subtree_schedule_extend_from_children(tree, outer); + break; + } + + return umap; +} + +static __isl_give isl_union_set *initial_domain( + __isl_keep isl_schedule_tree *tree); + +/* Extract a universe domain from the children of the tree root "tree", + * which is a set or sequence, meaning that its children are filters. + * In particular, return the union of the universes of the filters. + */ +static __isl_give isl_union_set *initial_domain_from_children( + __isl_keep isl_schedule_tree *tree) +{ + int i; + isl_size n; + isl_space *space; + isl_union_set *domain; + + n = isl_schedule_tree_n_children(tree); + if (n < 0) + return NULL; + if (n == 0) + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_internal, + "missing children", return NULL); + + space = extract_space_from_filter_child(tree); + domain = isl_union_set_empty(space); + + for (i = 0; i < n; ++i) { + isl_schedule_tree *child; + isl_union_set *domain_i; + + child = isl_schedule_tree_get_child(tree, i); + domain_i = initial_domain(child); + domain = isl_union_set_union(domain, domain_i); + isl_schedule_tree_free(child); + } + + return domain; +} + +/* Extract a universe domain from the tree root "tree". + * The caller is responsible for making sure that this node + * would not be skipped by isl_schedule_tree_first_schedule_descendant + * and that it is not a leaf node. + */ +static __isl_give isl_union_set *initial_domain( + __isl_keep isl_schedule_tree *tree) +{ + isl_multi_union_pw_aff *mupa; + isl_union_set *domain; + isl_union_map *exp; + isl_size n; + + if (!tree) + return NULL; + + switch (tree->type) { + case isl_schedule_node_error: + return NULL; + case isl_schedule_node_context: + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_internal, + "context node should be handled by caller", + return NULL); + case isl_schedule_node_guard: + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_internal, + "guard node should be handled by caller", + return NULL); + case isl_schedule_node_mark: + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_internal, + "mark node should be handled by caller", + return NULL); + case isl_schedule_node_extension: + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid, + "cannot construct subtree schedule of tree " + "with extension nodes", return NULL); + case isl_schedule_node_band: + n = isl_schedule_tree_band_n_member(tree); + if (n < 0) + return NULL; + if (n == 0) + isl_die(isl_schedule_tree_get_ctx(tree), + isl_error_internal, + "0D band should be handled by caller", + return NULL); + mupa = isl_schedule_band_get_partial_schedule(tree->band); + domain = isl_multi_union_pw_aff_domain(mupa); + domain = isl_union_set_universe(domain); + break; + case isl_schedule_node_domain: + domain = isl_schedule_tree_domain_get_domain(tree); + domain = isl_union_set_universe(domain); + break; + case isl_schedule_node_expansion: + exp = isl_schedule_tree_expansion_get_expansion(tree); + exp = isl_union_map_universe(exp); + domain = isl_union_map_domain(exp); + break; + case isl_schedule_node_filter: + domain = isl_schedule_tree_filter_get_filter(tree); + domain = isl_union_set_universe(domain); + break; + case isl_schedule_node_leaf: + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_internal, + "leaf node should be handled by caller", return NULL); + case isl_schedule_node_set: + case isl_schedule_node_sequence: + domain = initial_domain_from_children(tree); + break; + } + + return domain; +} + +/* Return the subtree schedule of a node that contains some schedule + * information, i.e., a node that would not be skipped by + * isl_schedule_tree_first_schedule_descendant and that is not a leaf. + * + * If the tree contains any expansions, then the returned subtree + * schedule is formulated in terms of the expanded domains. + * The tree is not allowed to contain any extension nodes. + * + * We start with an initial zero-dimensional subtree schedule based + * on the domain information in the root node and then extend it + * based on the schedule information in the root node and its descendants. + */ +__isl_give isl_union_map *isl_schedule_tree_get_subtree_schedule_union_map( + __isl_keep isl_schedule_tree *tree) +{ + isl_union_set *domain; + isl_union_map *umap; + + domain = initial_domain(tree); + umap = isl_union_map_from_domain(domain); + return subtree_schedule_extend(tree, umap); +} + +/* Multiply the partial schedule of the band root node of "tree" + * with the factors in "mv". + */ +__isl_give isl_schedule_tree *isl_schedule_tree_band_scale( + __isl_take isl_schedule_tree *tree, __isl_take isl_multi_val *mv) +{ + if (!tree || !mv) + goto error; + if (tree->type != isl_schedule_node_band) + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid, + "not a band node", goto error); + + tree = isl_schedule_tree_cow(tree); + if (!tree) + goto error; + + tree->band = isl_schedule_band_scale(tree->band, mv); + if (!tree->band) + return isl_schedule_tree_free(tree); + + return tree; +error: + isl_schedule_tree_free(tree); + isl_multi_val_free(mv); + return NULL; +} + +/* Divide the partial schedule of the band root node of "tree" + * by the factors in "mv". + */ +__isl_give isl_schedule_tree *isl_schedule_tree_band_scale_down( + __isl_take isl_schedule_tree *tree, __isl_take isl_multi_val *mv) +{ + if (!tree || !mv) + goto error; + if (tree->type != isl_schedule_node_band) + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid, + "not a band node", goto error); + + tree = isl_schedule_tree_cow(tree); + if (!tree) + goto error; + + tree->band = isl_schedule_band_scale_down(tree->band, mv); + if (!tree->band) + return isl_schedule_tree_free(tree); + + return tree; +error: + isl_schedule_tree_free(tree); + isl_multi_val_free(mv); + return NULL; +} + +/* Reduce the partial schedule of the band root node of "tree" + * modulo the factors in "mv". + */ +__isl_give isl_schedule_tree *isl_schedule_tree_band_mod( + __isl_take isl_schedule_tree *tree, __isl_take isl_multi_val *mv) +{ + if (!tree || !mv) + goto error; + if (tree->type != isl_schedule_node_band) + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid, + "not a band node", goto error); + + tree = isl_schedule_tree_cow(tree); + if (!tree) + goto error; + + tree->band = isl_schedule_band_mod(tree->band, mv); + if (!tree->band) + return isl_schedule_tree_free(tree); + + return tree; +error: + isl_schedule_tree_free(tree); + isl_multi_val_free(mv); + return NULL; +} + +/* Shift the partial schedule of the band root node of "tree" by "shift". + */ +__isl_give isl_schedule_tree *isl_schedule_tree_band_shift( + __isl_take isl_schedule_tree *tree, + __isl_take isl_multi_union_pw_aff *shift) +{ + if (!tree || !shift) + goto error; + if (tree->type != isl_schedule_node_band) + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid, + "not a band node", goto error); + + tree = isl_schedule_tree_cow(tree); + if (!tree) + goto error; + + tree->band = isl_schedule_band_shift(tree->band, shift); + if (!tree->band) + return isl_schedule_tree_free(tree); + + return tree; +error: + isl_schedule_tree_free(tree); + isl_multi_union_pw_aff_free(shift); + return NULL; +} + +/* Given two trees with sequence roots, replace the child at position + * "pos" of "tree" with the children of "child". + */ +__isl_give isl_schedule_tree *isl_schedule_tree_sequence_splice( + __isl_take isl_schedule_tree *tree, int pos, + __isl_take isl_schedule_tree *child) +{ + isl_size n; + isl_schedule_tree_list *list1, *list2; + + tree = isl_schedule_tree_cow(tree); + if (!tree || !child) + goto error; + if (isl_schedule_tree_get_type(tree) != isl_schedule_node_sequence) + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid, + "not a sequence node", goto error); + n = isl_schedule_tree_n_children(tree); + if (n < 0) + goto error; + if (pos < 0 || pos >= n) + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid, + "position out of bounds", goto error); + if (isl_schedule_tree_get_type(child) != isl_schedule_node_sequence) + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid, + "not a sequence node", goto error); + + list1 = isl_schedule_tree_list_copy(tree->children); + list1 = isl_schedule_tree_list_drop(list1, pos, n - pos); + list2 = isl_schedule_tree_list_copy(tree->children); + list2 = isl_schedule_tree_list_drop(list2, 0, pos + 1); + list1 = isl_schedule_tree_list_concat(list1, + isl_schedule_tree_list_copy(child->children)); + list1 = isl_schedule_tree_list_concat(list1, list2); + + isl_schedule_tree_free(tree); + isl_schedule_tree_free(child); + return isl_schedule_tree_from_children(isl_schedule_node_sequence, + list1); +error: + isl_schedule_tree_free(tree); + isl_schedule_tree_free(child); + return NULL; +} + +/* Tile the band root node of "tree" with tile sizes "sizes". + * + * We duplicate the band node, change the schedule of one of them + * to the tile schedule and the other to the point schedule and then + * attach the point band as a child to the tile band. + */ +__isl_give isl_schedule_tree *isl_schedule_tree_band_tile( + __isl_take isl_schedule_tree *tree, __isl_take isl_multi_val *sizes) +{ + isl_schedule_tree *child = NULL; + + if (!tree || !sizes) + goto error; + if (tree->type != isl_schedule_node_band) + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid, + "not a band node", goto error); + + child = isl_schedule_tree_copy(tree); + tree = isl_schedule_tree_cow(tree); + child = isl_schedule_tree_cow(child); + if (!tree || !child) + goto error; + + tree->band = isl_schedule_band_tile(tree->band, + isl_multi_val_copy(sizes)); + if (!tree->band) + goto error; + child->band = isl_schedule_band_point(child->band, tree->band, sizes); + if (!child->band) + child = isl_schedule_tree_free(child); + + tree = isl_schedule_tree_replace_child(tree, 0, child); + + return tree; +error: + isl_schedule_tree_free(child); + isl_schedule_tree_free(tree); + isl_multi_val_free(sizes); + return NULL; +} + +/* Given an isolate AST generation option "isolate" for a band of size pos + n, + * return the corresponding option for a band covering the first "pos" + * members. + * + * The input isolate option is of the form + * + * isolate[[flattened outer bands] -> [pos; n]] + * + * The output isolate option is of the form + * + * isolate[[flattened outer bands] -> [pos]] + */ +static __isl_give isl_set *isolate_initial(__isl_keep isl_set *isolate, + int pos, int n) +{ + isl_id *id; + isl_map *map; + + isolate = isl_set_copy(isolate); + id = isl_set_get_tuple_id(isolate); + map = isl_set_unwrap(isolate); + map = isl_map_project_out(map, isl_dim_out, pos, n); + isolate = isl_map_wrap(map); + isolate = isl_set_set_tuple_id(isolate, id); + + return isolate; +} + +/* Given an isolate AST generation option "isolate" for a band of size pos + n, + * return the corresponding option for a band covering the final "n" + * members within a band covering the first "pos" members. + * + * The input isolate option is of the form + * + * isolate[[flattened outer bands] -> [pos; n]] + * + * The output isolate option is of the form + * + * isolate[[flattened outer bands; pos] -> [n]] + * + * + * The range is first split into + * + * isolate[[flattened outer bands] -> [[pos] -> [n]]] + * + * and then the first pos members are moved to the domain + * + * isolate[[[flattened outer bands] -> [pos]] -> [n]] + * + * after which the domain is flattened to obtain the desired output. + */ +static __isl_give isl_set *isolate_final(__isl_keep isl_set *isolate, + int pos, int n) +{ + isl_id *id; + isl_space *space; + isl_multi_aff *ma1, *ma2; + isl_map *map; + + isolate = isl_set_copy(isolate); + id = isl_set_get_tuple_id(isolate); + map = isl_set_unwrap(isolate); + space = isl_space_range(isl_map_get_space(map)); + ma1 = isl_multi_aff_project_out_map(isl_space_copy(space), + isl_dim_set, pos, n); + ma2 = isl_multi_aff_project_out_map(space, isl_dim_set, 0, pos); + ma1 = isl_multi_aff_range_product(ma1, ma2); + map = isl_map_apply_range(map, isl_map_from_multi_aff(ma1)); + map = isl_map_uncurry(map); + map = isl_map_flatten_domain(map); + isolate = isl_map_wrap(map); + isolate = isl_set_set_tuple_id(isolate, id); + + return isolate; +} + +/* Split the band root node of "tree" into two nested band nodes, + * one with the first "pos" dimensions and + * one with the remaining dimensions. + * The tree is itself positioned at schedule depth "depth". + * + * The loop AST generation type options and the isolate option + * 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) +{ + isl_size n; + isl_set *isolate, *tree_isolate, *child_isolate; + isl_schedule_tree *child; + + if (!tree) + return NULL; + if (tree->type != isl_schedule_node_band) + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid, + "not a band node", return isl_schedule_tree_free(tree)); + + n = isl_schedule_tree_band_n_member(tree); + if (n < 0) + return isl_schedule_tree_free(tree); + if (pos < 0 || pos > n) + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid, + "position out of bounds", + return isl_schedule_tree_free(tree)); + + child = isl_schedule_tree_copy(tree); + tree = isl_schedule_tree_cow(tree); + child = isl_schedule_tree_cow(child); + if (!tree || !child) + goto error; + + isolate = isl_schedule_tree_band_get_ast_isolate_option(tree, depth); + tree_isolate = isolate_initial(isolate, pos, n - pos); + child_isolate = isolate_final(isolate, pos, n - pos); + child->band = isl_schedule_band_drop(child->band, 0, pos); + child->band = isl_schedule_band_replace_ast_build_option(child->band, + isl_set_copy(isolate), child_isolate); + tree->band = isl_schedule_band_drop(tree->band, pos, n - pos); + tree->band = isl_schedule_band_replace_ast_build_option(tree->band, + isl_set_copy(isolate), tree_isolate); + isl_set_free(isolate); + if (!child->band || !tree->band) + goto error; + + tree = isl_schedule_tree_replace_child(tree, 0, child); + + return tree; +error: + isl_schedule_tree_free(child); + isl_schedule_tree_free(tree); + return NULL; +} + +/* Attach "tree2" at each of the leaves of "tree1". + * + * If "tree1" does not have any explicit children, then make "tree2" + * its single child. Otherwise, attach "tree2" to the leaves of + * each of the children of "tree1". + */ +__isl_give isl_schedule_tree *isl_schedule_tree_append_to_leaves( + __isl_take isl_schedule_tree *tree1, + __isl_take isl_schedule_tree *tree2) +{ + int i; + isl_size n; + + n = isl_schedule_tree_n_children(tree1); + if (n < 0 || !tree2) + goto error; + if (n == 0) { + isl_schedule_tree_list *list; + list = isl_schedule_tree_list_from_schedule_tree(tree2); + tree1 = isl_schedule_tree_set_children(tree1, list); + return tree1; + } + for (i = 0; i < n; ++i) { + isl_schedule_tree *child; + + child = isl_schedule_tree_get_child(tree1, i); + child = isl_schedule_tree_append_to_leaves(child, + isl_schedule_tree_copy(tree2)); + tree1 = isl_schedule_tree_replace_child(tree1, i, child); + } + + isl_schedule_tree_free(tree2); + return tree1; +error: + isl_schedule_tree_free(tree1); + isl_schedule_tree_free(tree2); + return NULL; +} + +/* Reset the user pointer on all identifiers of parameters and tuples + * in the root of "tree". + */ +__isl_give isl_schedule_tree *isl_schedule_tree_reset_user( + __isl_take isl_schedule_tree *tree) +{ + if (isl_schedule_tree_is_leaf(tree)) + return tree; + + tree = isl_schedule_tree_cow(tree); + if (!tree) + return NULL; + + switch (tree->type) { + case isl_schedule_node_error: + return isl_schedule_tree_free(tree); + case isl_schedule_node_band: + tree->band = isl_schedule_band_reset_user(tree->band); + if (!tree->band) + return isl_schedule_tree_free(tree); + break; + case isl_schedule_node_context: + tree->context = isl_set_reset_user(tree->context); + if (!tree->context) + return isl_schedule_tree_free(tree); + break; + case isl_schedule_node_domain: + tree->domain = isl_union_set_reset_user(tree->domain); + if (!tree->domain) + return isl_schedule_tree_free(tree); + break; + case isl_schedule_node_expansion: + tree->contraction = + isl_union_pw_multi_aff_reset_user(tree->contraction); + tree->expansion = isl_union_map_reset_user(tree->expansion); + if (!tree->contraction || !tree->expansion) + return isl_schedule_tree_free(tree); + break; + case isl_schedule_node_extension: + tree->extension = isl_union_map_reset_user(tree->extension); + if (!tree->extension) + return isl_schedule_tree_free(tree); + break; + case isl_schedule_node_filter: + tree->filter = isl_union_set_reset_user(tree->filter); + if (!tree->filter) + return isl_schedule_tree_free(tree); + break; + case isl_schedule_node_guard: + tree->guard = isl_set_reset_user(tree->guard); + if (!tree->guard) + return isl_schedule_tree_free(tree); + break; + case isl_schedule_node_leaf: + case isl_schedule_node_mark: + case isl_schedule_node_sequence: + case isl_schedule_node_set: + break; + } + + return tree; +} + +/* Align the parameters of the root of "tree" to those of "space". + */ +__isl_give isl_schedule_tree *isl_schedule_tree_align_params( + __isl_take isl_schedule_tree *tree, __isl_take isl_space *space) +{ + if (!space) + goto error; + + if (isl_schedule_tree_is_leaf(tree)) { + isl_space_free(space); + return tree; + } + + tree = isl_schedule_tree_cow(tree); + if (!tree) + goto error; + + switch (tree->type) { + case isl_schedule_node_error: + goto error; + case isl_schedule_node_band: + tree->band = isl_schedule_band_align_params(tree->band, space); + if (!tree->band) + return isl_schedule_tree_free(tree); + break; + case isl_schedule_node_context: + tree->context = isl_set_align_params(tree->context, space); + if (!tree->context) + return isl_schedule_tree_free(tree); + break; + case isl_schedule_node_domain: + tree->domain = isl_union_set_align_params(tree->domain, space); + if (!tree->domain) + return isl_schedule_tree_free(tree); + break; + case isl_schedule_node_expansion: + tree->contraction = + isl_union_pw_multi_aff_align_params(tree->contraction, + isl_space_copy(space)); + tree->expansion = isl_union_map_align_params(tree->expansion, + space); + if (!tree->contraction || !tree->expansion) + return isl_schedule_tree_free(tree); + break; + case isl_schedule_node_extension: + tree->extension = isl_union_map_align_params(tree->extension, + space); + if (!tree->extension) + return isl_schedule_tree_free(tree); + break; + case isl_schedule_node_filter: + tree->filter = isl_union_set_align_params(tree->filter, space); + if (!tree->filter) + return isl_schedule_tree_free(tree); + break; + case isl_schedule_node_guard: + tree->guard = isl_set_align_params(tree->guard, space); + if (!tree->guard) + return isl_schedule_tree_free(tree); + break; + case isl_schedule_node_leaf: + case isl_schedule_node_mark: + case isl_schedule_node_sequence: + case isl_schedule_node_set: + isl_space_free(space); + break; + } + + return tree; +error: + isl_space_free(space); + isl_schedule_tree_free(tree); + return NULL; +} + +/* Does "tree" involve the iteration domain? + * That is, does it need to be modified + * by isl_schedule_tree_pullback_union_pw_multi_aff? + */ +static int involves_iteration_domain(__isl_keep isl_schedule_tree *tree) +{ + if (!tree) + return -1; + + switch (tree->type) { + case isl_schedule_node_error: + return -1; + case isl_schedule_node_band: + case isl_schedule_node_domain: + case isl_schedule_node_expansion: + case isl_schedule_node_extension: + case isl_schedule_node_filter: + return 1; + case isl_schedule_node_context: + case isl_schedule_node_leaf: + case isl_schedule_node_guard: + case isl_schedule_node_mark: + case isl_schedule_node_sequence: + case isl_schedule_node_set: + return 0; + } + + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_internal, + "unhandled case", return -1); +} + +/* Compute the pullback of the root node of "tree" by the function + * represented by "upma". + * In other words, plug in "upma" in the iteration domains of + * the root node of "tree". + * We currently do not handle expansion nodes. + * + * We first check if the root node involves any iteration domains. + * If so, we handle the specific cases. + */ +__isl_give isl_schedule_tree *isl_schedule_tree_pullback_union_pw_multi_aff( + __isl_take isl_schedule_tree *tree, + __isl_take isl_union_pw_multi_aff *upma) +{ + int involves; + + if (!tree || !upma) + goto error; + + involves = involves_iteration_domain(tree); + if (involves < 0) + goto error; + if (!involves) { + isl_union_pw_multi_aff_free(upma); + return tree; + } + + tree = isl_schedule_tree_cow(tree); + if (!tree) + goto error; + + if (tree->type == isl_schedule_node_band) { + tree->band = isl_schedule_band_pullback_union_pw_multi_aff( + tree->band, upma); + if (!tree->band) + return isl_schedule_tree_free(tree); + } else if (tree->type == isl_schedule_node_domain) { + tree->domain = + isl_union_set_preimage_union_pw_multi_aff(tree->domain, + upma); + if (!tree->domain) + return isl_schedule_tree_free(tree); + } else if (tree->type == isl_schedule_node_expansion) { + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_unsupported, + "cannot pullback expansion node", goto error); + } else if (tree->type == isl_schedule_node_extension) { + tree->extension = + isl_union_map_preimage_range_union_pw_multi_aff( + tree->extension, upma); + if (!tree->extension) + return isl_schedule_tree_free(tree); + } else if (tree->type == isl_schedule_node_filter) { + tree->filter = + isl_union_set_preimage_union_pw_multi_aff(tree->filter, + upma); + if (!tree->filter) + return isl_schedule_tree_free(tree); + } + + return tree; +error: + isl_union_pw_multi_aff_free(upma); + isl_schedule_tree_free(tree); + return NULL; +} + +/* Compute the gist of the band tree root with respect to "context". + */ +__isl_give isl_schedule_tree *isl_schedule_tree_band_gist( + __isl_take isl_schedule_tree *tree, __isl_take isl_union_set *context) +{ + if (!tree) + return NULL; + if (tree->type != isl_schedule_node_band) + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid, + "not a band node", goto error); + tree = isl_schedule_tree_cow(tree); + if (!tree) + goto error; + + tree->band = isl_schedule_band_gist(tree->band, context); + if (!tree->band) + return isl_schedule_tree_free(tree); + return tree; +error: + isl_union_set_free(context); + isl_schedule_tree_free(tree); + return NULL; +} + +/* Are any members in "band" marked coincident? + */ +static isl_bool any_coincident(__isl_keep isl_schedule_band *band) +{ + int i; + isl_size n; + + n = isl_schedule_band_n_member(band); + if (n < 0) + return isl_bool_error; + for (i = 0; i < n; ++i) { + isl_bool coincident; + + coincident = isl_schedule_band_member_get_coincident(band, i); + if (coincident < 0 || coincident) + return coincident; + } + + return isl_bool_false; +} + +/* Print the band node "band" to "p". + * + * The permutable and coincident properties are only printed if they + * are different from the defaults. + * The coincident property is always printed in YAML flow style. + */ +static __isl_give isl_printer *print_tree_band(__isl_take isl_printer *p, + __isl_keep isl_schedule_band *band) +{ + isl_union_set *options; + isl_bool empty; + isl_bool coincident; + + p = isl_printer_print_str(p, "schedule"); + p = isl_printer_yaml_next(p); + p = isl_printer_print_str(p, "\""); + p = isl_printer_print_multi_union_pw_aff(p, band->mupa); + p = isl_printer_print_str(p, "\""); + if (isl_schedule_band_get_permutable(band)) { + p = isl_printer_yaml_next(p); + p = isl_printer_print_str(p, "permutable"); + p = isl_printer_yaml_next(p); + p = isl_printer_print_int(p, 1); + } + coincident = any_coincident(band); + if (coincident < 0) + return isl_printer_free(p); + if (coincident) { + int i; + isl_size n; + int style; + + p = isl_printer_yaml_next(p); + p = isl_printer_print_str(p, "coincident"); + p = isl_printer_yaml_next(p); + style = isl_printer_get_yaml_style(p); + p = isl_printer_set_yaml_style(p, ISL_YAML_STYLE_FLOW); + p = isl_printer_yaml_start_sequence(p); + n = isl_schedule_band_n_member(band); + if (n < 0) + return isl_printer_free(p); + for (i = 0; i < n; ++i) { + p = isl_printer_print_int(p, + isl_schedule_band_member_get_coincident(band, i)); + p = isl_printer_yaml_next(p); + } + p = isl_printer_yaml_end_sequence(p); + p = isl_printer_set_yaml_style(p, style); + } + options = isl_schedule_band_get_ast_build_options(band); + empty = isl_union_set_is_empty(options); + if (empty < 0) + p = isl_printer_free(p); + if (!empty) { + p = isl_printer_yaml_next(p); + p = isl_printer_print_str(p, "options"); + p = isl_printer_yaml_next(p); + p = isl_printer_print_str(p, "\""); + p = isl_printer_print_union_set(p, options); + p = isl_printer_print_str(p, "\""); + } + isl_union_set_free(options); + + return p; +} + +#undef BASE +#define BASE str +#define isl_str const char +#include "print_yaml_field_templ.c" + +#undef BASE +#define BASE set +#include "print_yaml_field_templ.c" + +#undef BASE +#define BASE union_set +#include "print_yaml_field_templ.c" + +#undef BASE +#define BASE union_map +#include "print_yaml_field_templ.c" + +#undef BASE +#define BASE union_pw_multi_aff +#include "print_yaml_field_templ.c" + +/* Print "tree" to "p". + * + * If "n_ancestor" is non-negative, then "child_pos" contains the child + * positions of a descendant of the current node that should be marked + * (by the comment "YOU ARE HERE"). In particular, if "n_ancestor" + * is zero, then the current node should be marked. + * The marking is only printed in YAML block format. + * + * Implicit leaf nodes are not printed, except if they correspond + * to the node that should be marked. + */ +__isl_give isl_printer *isl_printer_print_schedule_tree_mark( + __isl_take isl_printer *p, __isl_keep isl_schedule_tree *tree, + int n_ancestor, int *child_pos) +{ + int i; + isl_size n; + int sequence = 0; + int block; + + block = isl_printer_get_yaml_style(p) == ISL_YAML_STYLE_BLOCK; + + p = isl_printer_yaml_start_mapping(p); + if (n_ancestor == 0 && block) { + p = isl_printer_print_str(p, "# YOU ARE HERE"); + p = isl_printer_end_line(p); + p = isl_printer_start_line(p); + } + switch (tree->type) { + case isl_schedule_node_error: + p = isl_printer_print_str(p, "ERROR"); + p = isl_printer_yaml_next(p); + break; + case isl_schedule_node_leaf: + p = isl_printer_print_str(p, "leaf"); + p = isl_printer_yaml_next(p); + break; + case isl_schedule_node_sequence: + p = isl_printer_print_str(p, "sequence"); + p = isl_printer_yaml_next(p); + sequence = 1; + break; + case isl_schedule_node_set: + p = isl_printer_print_str(p, "set"); + p = isl_printer_yaml_next(p); + sequence = 1; + break; + case isl_schedule_node_context: + p = print_yaml_field_set(p, "context", tree->context); + break; + case isl_schedule_node_domain: + p = print_yaml_field_union_set(p, "domain", tree->domain); + break; + case isl_schedule_node_expansion: + p = print_yaml_field_union_pw_multi_aff(p, "contraction", + tree->contraction); + p = print_yaml_field_union_map(p, "expansion", tree->expansion); + break; + case isl_schedule_node_extension: + p = print_yaml_field_union_map(p, "extension", tree->extension); + break; + case isl_schedule_node_filter: + p = print_yaml_field_union_set(p, "filter", tree->filter); + break; + case isl_schedule_node_guard: + p = print_yaml_field_set(p, "guard", tree->guard); + break; + case isl_schedule_node_mark: + p = print_yaml_field_str(p, "mark", + isl_id_get_name(tree->mark)); + break; + case isl_schedule_node_band: + p = print_tree_band(p, tree->band); + p = isl_printer_yaml_next(p); + break; + } + + n = isl_schedule_tree_n_children(tree); + if (n < 0) + return isl_printer_free(p); + if (n == 0) { + if (n_ancestor > 0 && block) { + isl_schedule_tree *leaf; + + p = isl_printer_print_str(p, "child"); + p = isl_printer_yaml_next(p); + leaf = isl_schedule_tree_leaf(isl_printer_get_ctx(p)); + p = isl_printer_print_schedule_tree_mark(p, + leaf, 0, NULL); + isl_schedule_tree_free(leaf); + p = isl_printer_yaml_next(p); + } + return isl_printer_yaml_end_mapping(p); + } + + if (sequence) { + p = isl_printer_yaml_start_sequence(p); + } else { + p = isl_printer_print_str(p, "child"); + p = isl_printer_yaml_next(p); + } + + for (i = 0; i < n; ++i) { + isl_schedule_tree *t; + + t = isl_schedule_tree_get_child(tree, i); + if (n_ancestor > 0 && child_pos[0] == i) + p = isl_printer_print_schedule_tree_mark(p, t, + n_ancestor - 1, child_pos + 1); + else + p = isl_printer_print_schedule_tree_mark(p, t, + -1, NULL); + isl_schedule_tree_free(t); + + p = isl_printer_yaml_next(p); + } + + if (sequence) + p = isl_printer_yaml_end_sequence(p); + p = isl_printer_yaml_end_mapping(p); + + return p; +} + +/* Print "tree" to "p". + */ +__isl_give isl_printer *isl_printer_print_schedule_tree( + __isl_take isl_printer *p, __isl_keep isl_schedule_tree *tree) +{ + return isl_printer_print_schedule_tree_mark(p, tree, -1, NULL); +} + +void isl_schedule_tree_dump(__isl_keep isl_schedule_tree *tree) +{ + isl_ctx *ctx; + isl_printer *printer; + + if (!tree) + return; + + ctx = isl_schedule_tree_get_ctx(tree); + printer = isl_printer_to_file(ctx, stderr); + printer = isl_printer_set_yaml_style(printer, ISL_YAML_STYLE_BLOCK); + printer = isl_printer_print_schedule_tree(printer, tree); + + isl_printer_free(printer); +} diff --git a/external/mit/isl/dist/isl_schedule_tree.h b/external/mit/isl/dist/isl_schedule_tree.h new file mode 100644 index 000000000000..a1ecfadda52a --- /dev/null +++ b/external/mit/isl/dist/isl_schedule_tree.h @@ -0,0 +1,266 @@ +#ifndef ISL_SCHEDLUE_TREE_H +#define ISL_SCHEDLUE_TREE_H + +#include +#include +#include +#include + +struct isl_schedule_tree; +typedef struct isl_schedule_tree isl_schedule_tree; + +ISL_DECLARE_LIST(schedule_tree) + +/* A schedule (sub)tree. + * + * The leaves of a tree are not explicitly represented inside + * the isl_schedule_tree, except when the tree consists of only a leaf. + * + * The "band" field is valid when type is isl_schedule_node_band. + * The "context" field is valid when type is isl_schedule_node_context + * and represents constraints on the flat product of the outer band nodes, + * possibly introducing additional parameters. + * The "domain" field is valid when type is isl_schedule_node_domain + * and introduces the statement instances scheduled by the tree. + * + * The "contraction" and "expansion" fields are valid when type + * is isl_schedule_node_expansion. + * "expansion" expands the reaching domain elements to one or more + * domain elements for the subtree. + * "contraction" maps these elements back to the corresponding + * 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 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 + * and represents the statement instances selected by the node. + * + * The "guard" field is valid when type is isl_schedule_node_guard + * and represents constraints on the flat product of the outer band nodes + * that need to be enforced by the outer nodes in the generated AST. + * + * The "mark" field is valid when type is isl_schedule_node_mark and + * identifies the mark. + * + * The "children" field is valid for all types except + * isl_schedule_node_leaf. This field is NULL if there are + * no children (except for the implicit leaves). + * + * anchored is set if the node or any of its descendants depends + * on its position in the schedule tree. + */ +struct isl_schedule_tree { + int ref; + isl_ctx *ctx; + int anchored; + enum isl_schedule_node_type type; + union { + isl_schedule_band *band; + isl_set *context; + isl_union_set *domain; + struct { + isl_union_pw_multi_aff *contraction; + isl_union_map *expansion; + }; + isl_union_map *extension; + isl_union_set *filter; + isl_set *guard; + isl_id *mark; + }; + isl_schedule_tree_list *children; +}; + +isl_ctx *isl_schedule_tree_get_ctx(__isl_keep isl_schedule_tree *tree); +enum isl_schedule_node_type isl_schedule_tree_get_type( + __isl_keep isl_schedule_tree *tree); + +__isl_give isl_schedule_tree *isl_schedule_tree_leaf(isl_ctx *ctx); +int isl_schedule_tree_is_leaf(__isl_keep isl_schedule_tree *tree); + +isl_bool isl_schedule_tree_plain_is_equal(__isl_keep isl_schedule_tree *tree1, + __isl_keep isl_schedule_tree *tree2); + +__isl_give isl_schedule_tree *isl_schedule_tree_copy( + __isl_keep isl_schedule_tree *tree); +__isl_null isl_schedule_tree *isl_schedule_tree_free( + __isl_take isl_schedule_tree *tree); + +__isl_give isl_schedule_tree *isl_schedule_tree_from_band( + __isl_take isl_schedule_band *band); +__isl_give isl_schedule_tree *isl_schedule_tree_from_context( + __isl_take isl_set *context); +__isl_give isl_schedule_tree *isl_schedule_tree_from_domain( + __isl_take isl_union_set *domain); +__isl_give isl_schedule_tree *isl_schedule_tree_from_expansion( + __isl_take isl_union_pw_multi_aff *contraction, + __isl_take isl_union_map *expansion); +__isl_give isl_schedule_tree *isl_schedule_tree_from_extension( + __isl_take isl_union_map *extension); +__isl_give isl_schedule_tree *isl_schedule_tree_from_filter( + __isl_take isl_union_set *filter); +__isl_give isl_schedule_tree *isl_schedule_tree_from_guard( + __isl_take isl_set *guard); +__isl_give isl_schedule_tree *isl_schedule_tree_from_children( + enum isl_schedule_node_type type, + __isl_take isl_schedule_tree_list *list); +__isl_give isl_schedule_tree *isl_schedule_tree_from_pair( + enum isl_schedule_node_type type, __isl_take isl_schedule_tree *tree1, + __isl_take isl_schedule_tree *tree2); +__isl_give isl_schedule_tree *isl_schedule_tree_sequence_pair( + __isl_take isl_schedule_tree *tree1, + __isl_take isl_schedule_tree *tree2); +__isl_give isl_schedule_tree *isl_schedule_tree_set_pair( + __isl_take isl_schedule_tree *tree1, + __isl_take isl_schedule_tree *tree2); + +isl_bool isl_schedule_tree_is_subtree_anchored( + __isl_keep isl_schedule_tree *tree); + +__isl_give isl_space *isl_schedule_tree_band_get_space( + __isl_keep isl_schedule_tree *tree); +__isl_give isl_schedule_tree *isl_schedule_tree_band_intersect_domain( + __isl_take isl_schedule_tree *tree, __isl_take isl_union_set *domain); +__isl_give isl_multi_union_pw_aff *isl_schedule_tree_band_get_partial_schedule( + __isl_keep isl_schedule_tree *tree); +__isl_give isl_schedule_tree *isl_schedule_tree_band_set_partial_schedule( + __isl_take isl_schedule_tree *tree, + __isl_take isl_multi_union_pw_aff *schedule); +enum isl_ast_loop_type isl_schedule_tree_band_member_get_ast_loop_type( + __isl_keep isl_schedule_tree *tree, int pos); +__isl_give isl_schedule_tree *isl_schedule_tree_band_member_set_ast_loop_type( + __isl_take isl_schedule_tree *tree, int pos, + enum isl_ast_loop_type type); +enum isl_ast_loop_type isl_schedule_tree_band_member_get_isolate_ast_loop_type( + __isl_keep isl_schedule_tree *tree, int pos); +__isl_give isl_schedule_tree * +isl_schedule_tree_band_member_set_isolate_ast_loop_type( + __isl_take isl_schedule_tree *tree, int pos, + enum isl_ast_loop_type type); +__isl_give isl_union_set *isl_schedule_tree_band_get_ast_build_options( + __isl_keep isl_schedule_tree *tree); +__isl_give isl_schedule_tree *isl_schedule_tree_band_set_ast_build_options( + __isl_take isl_schedule_tree *tree, __isl_take isl_union_set *options); +__isl_give isl_set *isl_schedule_tree_band_get_ast_isolate_option( + __isl_keep isl_schedule_tree *tree, int depth); +__isl_give isl_set *isl_schedule_tree_context_get_context( + __isl_keep isl_schedule_tree *tree); +__isl_give isl_union_set *isl_schedule_tree_domain_get_domain( + __isl_keep isl_schedule_tree *tree); +__isl_give isl_schedule_tree *isl_schedule_tree_domain_set_domain( + __isl_take isl_schedule_tree *tree, __isl_take isl_union_set *domain); +__isl_give isl_union_pw_multi_aff *isl_schedule_tree_expansion_get_contraction( + __isl_keep isl_schedule_tree *tree); +__isl_give isl_union_map *isl_schedule_tree_expansion_get_expansion( + __isl_keep isl_schedule_tree *tree); +__isl_give isl_schedule_tree * +isl_schedule_tree_expansion_set_contraction_and_expansion( + __isl_take isl_schedule_tree *tree, + __isl_take isl_union_pw_multi_aff *contraction, + __isl_take isl_union_map *expansion); +__isl_give isl_union_map *isl_schedule_tree_extension_get_extension( + __isl_keep isl_schedule_tree *tree); +__isl_give isl_schedule_tree *isl_schedule_tree_extension_set_extension( + __isl_take isl_schedule_tree *tree, + __isl_take isl_union_map *extension); +__isl_give isl_union_set *isl_schedule_tree_filter_get_filter( + __isl_keep isl_schedule_tree *tree); +__isl_give isl_schedule_tree *isl_schedule_tree_filter_set_filter( + __isl_take isl_schedule_tree *tree, __isl_take isl_union_set *filter); +__isl_give isl_set *isl_schedule_tree_guard_get_guard( + __isl_keep isl_schedule_tree *tree); +__isl_give isl_id *isl_schedule_tree_mark_get_id( + __isl_keep isl_schedule_tree *tree); + +__isl_give isl_schedule_tree *isl_schedule_tree_first_schedule_descendant( + __isl_take isl_schedule_tree *tree, __isl_keep isl_schedule_tree *leaf); +__isl_give isl_union_map *isl_schedule_tree_get_subtree_schedule_union_map( + __isl_keep isl_schedule_tree *tree); + +isl_size isl_schedule_tree_band_n_member(__isl_keep isl_schedule_tree *tree); + +isl_bool isl_schedule_tree_band_member_get_coincident( + __isl_keep isl_schedule_tree *tree, int pos); +__isl_give isl_schedule_tree *isl_schedule_tree_band_member_set_coincident( + __isl_take isl_schedule_tree *tree, int pos, int coincident); +isl_bool isl_schedule_tree_band_get_permutable( + __isl_keep isl_schedule_tree *tree); +__isl_give isl_schedule_tree *isl_schedule_tree_band_set_permutable( + __isl_take isl_schedule_tree *tree, int permutable); + +int isl_schedule_tree_has_children(__isl_keep isl_schedule_tree *tree); +isl_size isl_schedule_tree_n_children(__isl_keep isl_schedule_tree *tree); +__isl_give isl_schedule_tree *isl_schedule_tree_get_child( + __isl_keep isl_schedule_tree *tree, int pos); + +__isl_give isl_schedule_tree *isl_schedule_tree_insert_band( + __isl_take isl_schedule_tree *tree, __isl_take isl_schedule_band *band); +__isl_give isl_schedule_tree *isl_schedule_tree_insert_context( + __isl_take isl_schedule_tree *tree, __isl_take isl_set *context); +__isl_give isl_schedule_tree *isl_schedule_tree_insert_domain( + __isl_take isl_schedule_tree *tree, __isl_take isl_union_set *domain); +__isl_give isl_schedule_tree *isl_schedule_tree_insert_expansion( + __isl_take isl_schedule_tree *tree, + __isl_take isl_union_pw_multi_aff *contraction, + __isl_take isl_union_map *expansion); +__isl_give isl_schedule_tree *isl_schedule_tree_insert_extension( + __isl_take isl_schedule_tree *tree, + __isl_take isl_union_map *extension); +__isl_give isl_schedule_tree *isl_schedule_tree_insert_filter( + __isl_take isl_schedule_tree *tree, __isl_take isl_union_set *filter); +__isl_give isl_schedule_tree *isl_schedule_tree_children_insert_filter( + __isl_take isl_schedule_tree *tree, __isl_take isl_union_set *filter); +__isl_give isl_schedule_tree *isl_schedule_tree_insert_guard( + __isl_take isl_schedule_tree *tree, __isl_take isl_set *guard); +__isl_give isl_schedule_tree *isl_schedule_tree_insert_mark( + __isl_take isl_schedule_tree *tree, __isl_take isl_id *mark); + +__isl_give isl_schedule_tree *isl_schedule_tree_append_to_leaves( + __isl_take isl_schedule_tree *tree1, + __isl_take isl_schedule_tree *tree2); + +__isl_give isl_schedule_tree *isl_schedule_tree_band_scale( + __isl_take isl_schedule_tree *tree, __isl_take isl_multi_val *mv); +__isl_give isl_schedule_tree *isl_schedule_tree_band_scale_down( + __isl_take isl_schedule_tree *tree, __isl_take isl_multi_val *mv); +__isl_give isl_schedule_tree *isl_schedule_tree_band_mod( + __isl_take isl_schedule_tree *tree, __isl_take isl_multi_val *mv); +__isl_give isl_schedule_tree *isl_schedule_tree_band_tile( + __isl_take isl_schedule_tree *tree, __isl_take isl_multi_val *sizes); +__isl_give isl_schedule_tree *isl_schedule_tree_band_shift( + __isl_take isl_schedule_tree *tree, + __isl_take isl_multi_union_pw_aff *shift); +__isl_give isl_schedule_tree *isl_schedule_tree_band_split( + __isl_take isl_schedule_tree *tree, int pos, int depth); +__isl_give isl_schedule_tree *isl_schedule_tree_band_gist( + __isl_take isl_schedule_tree *tree, __isl_take isl_union_set *context); + +__isl_give isl_schedule_tree *isl_schedule_tree_child( + __isl_take isl_schedule_tree *tree, int pos); +__isl_give isl_schedule_tree *isl_schedule_tree_reset_children( + __isl_take isl_schedule_tree *tree); +__isl_give isl_schedule_tree *isl_schedule_tree_drop_child( + __isl_take isl_schedule_tree *tree, int pos); +__isl_give isl_schedule_tree *isl_schedule_tree_replace_child( + __isl_take isl_schedule_tree *tree, int pos, + __isl_take isl_schedule_tree *new_child); +__isl_give isl_schedule_tree *isl_schedule_tree_sequence_splice( + __isl_take isl_schedule_tree *tree, int pos, + __isl_take isl_schedule_tree *child); + +__isl_give isl_schedule_tree *isl_schedule_tree_reset_user( + __isl_take isl_schedule_tree *tree); +__isl_give isl_schedule_tree *isl_schedule_tree_align_params( + __isl_take isl_schedule_tree *tree, __isl_take isl_space *space); +__isl_give isl_schedule_tree *isl_schedule_tree_pullback_union_pw_multi_aff( + __isl_take isl_schedule_tree *tree, + __isl_take isl_union_pw_multi_aff *upma); + +__isl_give isl_printer *isl_printer_print_schedule_tree( + __isl_take isl_printer *p, __isl_keep isl_schedule_tree *tree); +__isl_give isl_printer *isl_printer_print_schedule_tree_mark( + __isl_take isl_printer *p, __isl_keep isl_schedule_tree *tree, + int n_ancestor, int *child_pos); + +#endif diff --git a/external/mit/isl/dist/isl_scheduler.c b/external/mit/isl/dist/isl_scheduler.c new file mode 100644 index 000000000000..25a59144a7df --- /dev/null +++ b/external/mit/isl/dist/isl_scheduler.c @@ -0,0 +1,5939 @@ +/* + * Copyright 2011 INRIA Saclay + * Copyright 2012-2014 Ecole Normale Superieure + * Copyright 2015-2016 Sven Verdoolaege + * Copyright 2016 INRIA Paris + * Copyright 2017 Sven Verdoolaege + * + * 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 + * and Centre de Recherche Inria de Paris, 2 rue Simone Iff - Voie DQ12, + * CS 42112, 75589 Paris Cedex 12, France + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "isl_scheduler.h" +#include "isl_scheduler_clustering.h" + +/* + * 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). + */ + + +static isl_bool node_has_tuples(const void *entry, const void *val) +{ + struct isl_sched_node *node = (struct isl_sched_node *)entry; + isl_space *space = (isl_space *) val; + + return isl_space_has_equal_tuples(node->space, space); +} + +int isl_sched_node_scc_exactly(struct isl_sched_node *node, int scc) +{ + return node->scc == scc; +} + +static int node_scc_at_most(struct isl_sched_node *node, int scc) +{ + return node->scc <= scc; +} + +static int node_scc_at_least(struct isl_sched_node *node, int scc) +{ + return node->scc >= scc; +} + +/* Is "edge" marked as being of type "type"? + */ +int isl_sched_edge_has_type(struct isl_sched_edge *edge, + enum isl_edge_type type) +{ + return ISL_FL_ISSET(edge->types, 1 << type); +} + +/* Mark "edge" as being of type "type". + */ +static void set_type(struct isl_sched_edge *edge, enum isl_edge_type type) +{ + ISL_FL_SET(edge->types, 1 << type); +} + +/* No longer mark "edge" as being of type "type"? + */ +static void clear_type(struct isl_sched_edge *edge, enum isl_edge_type type) +{ + ISL_FL_CLR(edge->types, 1 << type); +} + +/* Is "edge" marked as a validity edge? + */ +static int is_validity(struct isl_sched_edge *edge) +{ + return isl_sched_edge_has_type(edge, isl_edge_validity); +} + +/* Mark "edge" as a validity edge. + */ +static void set_validity(struct isl_sched_edge *edge) +{ + set_type(edge, isl_edge_validity); +} + +/* Is "edge" marked as a proximity edge? + */ +int isl_sched_edge_is_proximity(struct isl_sched_edge *edge) +{ + return isl_sched_edge_has_type(edge, isl_edge_proximity); +} + +/* Is "edge" marked as a local edge? + */ +static int is_local(struct isl_sched_edge *edge) +{ + return isl_sched_edge_has_type(edge, isl_edge_local); +} + +/* Mark "edge" as a local edge. + */ +static void set_local(struct isl_sched_edge *edge) +{ + set_type(edge, isl_edge_local); +} + +/* No longer mark "edge" as a local edge. + */ +static void clear_local(struct isl_sched_edge *edge) +{ + clear_type(edge, isl_edge_local); +} + +/* Is "edge" marked as a coincidence edge? + */ +static int is_coincidence(struct isl_sched_edge *edge) +{ + return isl_sched_edge_has_type(edge, isl_edge_coincidence); +} + +/* Is "edge" marked as a condition edge? + */ +int isl_sched_edge_is_condition(struct isl_sched_edge *edge) +{ + return isl_sched_edge_has_type(edge, isl_edge_condition); +} + +/* Is "edge" marked as a conditional validity edge? + */ +int isl_sched_edge_is_conditional_validity(struct isl_sched_edge *edge) +{ + return isl_sched_edge_has_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 isl_sched_edge_is_condition(edge) || + isl_sched_edge_is_conditional_validity(edge); +} + +/* Initialize node_table based on the list of nodes. + */ +static int graph_init_table(isl_ctx *ctx, struct isl_sched_graph *graph) +{ + int i; + + graph->node_table = isl_hash_table_alloc(ctx, graph->n); + if (!graph->node_table) + return -1; + + for (i = 0; i < graph->n; ++i) { + struct isl_hash_table_entry *entry; + uint32_t hash; + + hash = isl_space_get_tuple_hash(graph->node[i].space); + entry = isl_hash_table_find(ctx, graph->node_table, hash, + &node_has_tuples, + graph->node[i].space, 1); + if (!entry) + return -1; + entry->data = &graph->node[i]; + } + + return 0; +} + +/* Return a pointer to the node that lives within the given space, + * an invalid node if there is no such node, or NULL in case of error. + */ +struct isl_sched_node *isl_sched_graph_find_node(isl_ctx *ctx, + struct isl_sched_graph *graph, __isl_keep isl_space *space) +{ + 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); + if (!entry) + return NULL; + if (entry == isl_hash_table_entry_none) + return graph->node + graph->n; + + return entry->data; +} + +/* Is "node" a node in "graph"? + */ +int isl_sched_graph_is_node(struct isl_sched_graph *graph, + struct isl_sched_node *node) +{ + return node && node >= &graph->node[0] && node < &graph->node[graph->n]; +} + +static isl_bool edge_has_src_and_dst(const void *entry, const void *val) +{ + const struct isl_sched_edge *edge = entry; + const struct isl_sched_edge *temp = val; + + return isl_bool_ok(edge->src == temp->src && edge->dst == temp->dst); +} + +/* Add the given edge to graph->edge_table[type]. + */ +static isl_stat graph_edge_table_add(isl_ctx *ctx, + struct isl_sched_graph *graph, enum isl_edge_type type, + struct isl_sched_edge *edge) +{ + struct isl_hash_table_entry *entry; + uint32_t hash; + + hash = isl_hash_init(); + hash = isl_hash_builtin(hash, edge->src); + hash = isl_hash_builtin(hash, edge->dst); + entry = isl_hash_table_find(ctx, graph->edge_table[type], hash, + &edge_has_src_and_dst, edge, 1); + if (!entry) + return isl_stat_error; + entry->data = edge; + + 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 (!isl_sched_edge_has_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. + */ +static int graph_init_edge_tables(isl_ctx *ctx, struct isl_sched_graph *graph) +{ + int i; + + for (i = 0; i <= isl_edge_last; ++i) { + graph->edge_table[i] = isl_hash_table_alloc(ctx, + graph->max_edge[i]); + if (!graph->edge_table[i]) + return -1; + } + + return 0; +} + +/* If graph->edge_table[type] contains an edge from the given source + * to the given destination, then return the hash table entry of this edge. + * Otherwise, return NULL. + */ +static struct isl_hash_table_entry *graph_find_edge_entry( + struct isl_sched_graph *graph, + enum isl_edge_type type, + struct isl_sched_node *src, struct isl_sched_node *dst) +{ + isl_ctx *ctx = isl_space_get_ctx(src->space); + uint32_t hash; + struct isl_sched_edge temp = { .src = src, .dst = dst }; + + hash = isl_hash_init(); + hash = isl_hash_builtin(hash, temp.src); + hash = isl_hash_builtin(hash, temp.dst); + return isl_hash_table_find(ctx, graph->edge_table[type], hash, + &edge_has_src_and_dst, &temp, 0); +} + + +/* If graph->edge_table[type] contains an edge from the given source + * to the given destination, then return this edge. + * Return "none" if no such edge can be found. + * Return NULL on error. + */ +static struct isl_sched_edge *graph_find_edge(struct isl_sched_graph *graph, + enum isl_edge_type type, + struct isl_sched_node *src, struct isl_sched_node *dst, + struct isl_sched_edge *none) +{ + struct isl_hash_table_entry *entry; + + entry = graph_find_edge_entry(graph, type, src, dst); + if (!entry) + return NULL; + if (entry == isl_hash_table_entry_none) + return none; + + return entry->data; +} + +/* Check whether the dependence graph has an edge of the given type + * between the given two nodes. + */ +static isl_bool graph_has_edge(struct isl_sched_graph *graph, + enum isl_edge_type type, + struct isl_sched_node *src, struct isl_sched_node *dst) +{ + struct isl_sched_edge dummy; + struct isl_sched_edge *edge; + isl_bool empty; + + edge = graph_find_edge(graph, type, src, dst, &dummy); + if (!edge) + return isl_bool_error; + if (edge == &dummy) + return isl_bool_false; + + empty = isl_map_plain_is_empty(edge->map); + + return isl_bool_not(empty); +} + +/* Look for any edge with the same src, dst and map fields as "model". + * + * Return the matching edge if one can be found. + * Return "model" if no matching edge is found. + * Return NULL on error. + */ +static struct isl_sched_edge *graph_find_matching_edge( + struct isl_sched_graph *graph, struct isl_sched_edge *model) +{ + enum isl_edge_type i; + struct isl_sched_edge *edge; + + for (i = isl_edge_first; i <= isl_edge_last; ++i) { + int is_equal; + + edge = graph_find_edge(graph, i, model->src, model->dst, model); + if (!edge) + return NULL; + if (edge == model) + continue; + is_equal = isl_map_plain_is_equal(model->map, edge->map); + if (is_equal < 0) + return NULL; + if (is_equal) + return edge; + } + + return model; +} + +/* Remove the given edge from all the edge_tables that refer to it. + */ +static isl_stat graph_remove_edge(struct isl_sched_graph *graph, + struct isl_sched_edge *edge) +{ + isl_ctx *ctx = isl_map_get_ctx(edge->map); + enum isl_edge_type i; + + for (i = isl_edge_first; i <= isl_edge_last; ++i) { + struct isl_hash_table_entry *entry; + + entry = graph_find_edge_entry(graph, i, edge->src, edge->dst); + if (!entry) + return isl_stat_error; + if (entry == isl_hash_table_entry_none) + continue; + if (entry->data != edge) + continue; + isl_hash_table_remove(ctx, graph->edge_table[i], entry); + } + + return isl_stat_ok; +} + +/* Check whether the dependence graph has any edge + * between the given two nodes. + */ +static isl_bool graph_has_any_edge(struct isl_sched_graph *graph, + struct isl_sched_node *src, struct isl_sched_node *dst) +{ + enum isl_edge_type i; + isl_bool r; + + for (i = isl_edge_first; i <= isl_edge_last; ++i) { + r = graph_has_edge(graph, i, src, dst); + if (r < 0 || r) + return r; + } + + return r; +} + +/* Check whether the dependence graph has a validity edge + * between the given two nodes. + * + * Conditional validity edges are essentially validity edges that + * can be ignored if the corresponding condition edges are iteration private. + * Here, we are only checking for the presence of validity + * edges, so we need to consider the conditional validity edges too. + * In particular, this function is used during the detection + * of strongly connected components and we cannot ignore + * conditional validity edges during this detection. + */ +isl_bool isl_sched_graph_has_validity_edge(struct isl_sched_graph *graph, + struct isl_sched_node *src, struct isl_sched_node *dst) +{ + isl_bool r; + + r = graph_has_edge(graph, isl_edge_validity, src, dst); + if (r < 0 || r) + return r; + + return graph_has_edge(graph, isl_edge_conditional_validity, src, dst); +} + +/* 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; + + graph->n = n_node; + graph->n_edge = n_edge; + graph->node = isl_calloc_array(ctx, struct isl_sched_node, graph->n); + graph->sorted = isl_calloc_array(ctx, int, graph->n); + graph->region = isl_alloc_array(ctx, + struct isl_trivial_region, graph->n); + graph->edge = isl_calloc_array(ctx, + struct isl_sched_edge, graph->n_edge); + + graph->intra_hmap = isl_map_to_basic_set_alloc(ctx, 2 * n_edge); + graph->intra_hmap_param = isl_map_to_basic_set_alloc(ctx, 2 * n_edge); + graph->inter_hmap = isl_map_to_basic_set_alloc(ctx, 2 * n_edge); + + if (!graph->node || !graph->region || (graph->n_edge && !graph->edge) || + !graph->sorted) + return isl_stat_error; + + for(i = 0; i < graph->n; ++i) + graph->sorted[i] = i; + + 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_pw_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); +} + +void isl_sched_graph_free(isl_ctx *ctx, struct isl_sched_graph *graph) +{ + int i; + + isl_map_to_basic_set_free(graph->intra_hmap); + isl_map_to_basic_set_free(graph->intra_hmap_param); + isl_map_to_basic_set_free(graph->inter_hmap); + + if (graph->node) + for (i = 0; i < graph->n; ++i) + clear_node(graph, &graph->node[i]); + free(graph->node); + free(graph->sorted); + if (graph->edge) + for (i = 0; i < graph->n_edge; ++i) { + isl_map_free(graph->edge[i].map); + isl_union_map_free(graph->edge[i].tagged_condition); + isl_union_map_free(graph->edge[i].tagged_validity); + } + free(graph->edge); + free(graph->region); + for (i = 0; i <= isl_edge_last; ++i) + isl_hash_table_free(ctx, graph->edge_table[i]); + isl_hash_table_free(ctx, graph->node_table); + isl_basic_set_free(graph->lp); +} + +/* For each "set" on which this function is called, increment + * graph->n by one and update graph->maxvar. + */ +static isl_stat init_n_maxvar(__isl_take isl_set *set, void *user) +{ + struct isl_sched_graph *graph = user; + isl_size nvar = isl_set_dim(set, isl_dim_set); + + graph->n++; + if (nvar > graph->maxvar) + graph->maxvar = nvar; + + isl_set_free(set); + + if (nvar < 0) + return isl_stat_error; + return isl_stat_ok; +} + +/* Compute the number of rows that should be allocated for the schedule. + * In particular, we need one row for each variable or one row + * for each basic map in the dependences. + * Note that it is practically impossible to exhaust both + * the number of dependences and the number of variables. + */ +static isl_stat compute_max_row(struct isl_sched_graph *graph, + __isl_keep isl_schedule_constraints *sc) +{ + int n_edge; + isl_stat r; + isl_union_set *domain; + + graph->n = 0; + graph->maxvar = 0; + domain = isl_schedule_constraints_get_domain(sc); + r = isl_union_set_foreach_set(domain, &init_n_maxvar, graph); + isl_union_set_free(domain); + if (r < 0) + return isl_stat_error; + n_edge = isl_schedule_constraints_n_basic_map(sc); + if (n_edge < 0) + return isl_stat_error; + graph->max_row = n_edge + graph->maxvar; + + return isl_stat_ok; +} + +/* Does "bset" have any defining equalities for its set variables? + */ +static isl_bool has_any_defining_equality(__isl_keep isl_basic_set *bset) +{ + int i; + isl_size n; + + n = isl_basic_set_dim(bset, isl_dim_set); + if (n < 0) + return isl_bool_error; + + for (i = 0; i < n; ++i) { + isl_bool has; + + has = isl_basic_set_has_defining_equality(bset, isl_dim_set, i, + NULL); + if (has < 0 || has) + return has; + } + + return isl_bool_false; +} + +/* Set the entries of node->max to the value of the schedule_max_coefficient + * option, if set. + */ +static isl_stat set_max_coefficient(isl_ctx *ctx, struct isl_sched_node *node) +{ + int max; + + max = isl_options_get_schedule_max_coefficient(ctx); + if (max == -1) + return isl_stat_ok; + + node->max = isl_vec_alloc(ctx, node->nvar); + node->max = isl_vec_set_si(node->max, max); + if (!node->max) + return isl_stat_error; + + return isl_stat_ok; +} + +/* Set the entries of node->max to the minimum of the schedule_max_coefficient + * option (if set) and half of the minimum of the sizes in the other + * dimensions. Round up when computing the half such that + * if the minimum of the sizes is one, half of the size is taken to be one + * rather than zero. + * If the global minimum is unbounded (i.e., if both + * the schedule_max_coefficient is not set and the sizes in the other + * dimensions are unbounded), then store a negative value. + * If the schedule coefficient is close to the size of the instance set + * in another dimension, then the schedule may represent a loop + * coalescing transformation (especially if the coefficient + * in that other dimension is one). Forcing the coefficient to be + * smaller than or equal to half the minimal size should avoid this + * situation. + */ +static isl_stat compute_max_coefficient(isl_ctx *ctx, + struct isl_sched_node *node) +{ + int max; + int i, j; + isl_vec *v; + + max = isl_options_get_schedule_max_coefficient(ctx); + v = isl_vec_alloc(ctx, node->nvar); + if (!v) + return isl_stat_error; + + for (i = 0; i < node->nvar; ++i) { + isl_int_set_si(v->el[i], max); + isl_int_mul_si(v->el[i], v->el[i], 2); + } + + for (i = 0; i < node->nvar; ++i) { + isl_val *size; + + size = isl_multi_val_get_val(node->sizes, i); + if (!size) + goto error; + if (!isl_val_is_int(size)) { + isl_val_free(size); + continue; + } + for (j = 0; j < node->nvar; ++j) { + if (j == i) + continue; + if (isl_int_is_neg(v->el[j]) || + isl_int_gt(v->el[j], size->n)) + isl_int_set(v->el[j], size->n); + } + isl_val_free(size); + } + + for (i = 0; i < node->nvar; ++i) + isl_int_cdiv_q_ui(v->el[i], v->el[i], 2); + + node->max = v; + return isl_stat_ok; +error: + isl_vec_free(v); + return isl_stat_error; +} + +/* Construct an identifier for node "node", which will represent "set". + * The name of the identifier is either "compressed" or + * "compressed_", with the name of the space of "set". + * The user pointer of the identifier points to "node". + */ +static __isl_give isl_id *construct_compressed_id(__isl_keep isl_set *set, + struct isl_sched_node *node) +{ + isl_bool has_name; + isl_ctx *ctx; + isl_id *id; + isl_printer *p; + const char *name; + char *id_name; + + has_name = isl_set_has_tuple_name(set); + if (has_name < 0) + return NULL; + + ctx = isl_set_get_ctx(set); + if (!has_name) + return isl_id_alloc(ctx, "compressed", node); + + p = isl_printer_to_str(ctx); + name = isl_set_get_tuple_name(set); + p = isl_printer_print_str(p, "compressed_"); + p = isl_printer_print_str(p, name); + id_name = isl_printer_get_str(p); + isl_printer_free(p); + + id = isl_id_alloc(ctx, id_name, node); + free(id_name); + + return id; +} + +/* Construct a map that isolates the variable in position "pos" in "set". + * + * That is, construct + * + * [i_0, ..., i_pos-1, i_pos+1, ...] -> [i_pos] + */ +static __isl_give isl_map *isolate(__isl_take isl_set *set, int pos) +{ + isl_map *map; + + map = isl_set_project_onto_map(set, isl_dim_set, pos, 1); + map = isl_map_project_out(map, isl_dim_in, pos, 1); + return map; +} + +/* 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 + * + * [i_0, ..., i_dim-1, i_dim+1, ...] -> [i_dim] + * + * and then duplicated + * + * [i_0, ..., i_dim-1, i_dim+1, ...] -> [[i_dim] -> [i_dim']] + * + * The shared variables are then projected out and the maximal value + * of i_dim' - i_dim is computed. + */ +static __isl_give isl_val *compute_size(__isl_take isl_set *set, int dim) +{ + isl_map *map; + isl_local_space *ls; + isl_aff *obj; + isl_val *v; + + map = isolate(set, dim); + map = isl_map_range_product(map, isl_map_copy(map)); + map = isl_set_unwrap(isl_map_range(map)); + set = isl_map_deltas(map); + ls = isl_local_space_from_space(isl_set_get_space(set)); + obj = isl_aff_var_on_domain(ls, isl_dim_set, 0); + v = isl_set_max_val(set, obj); + isl_aff_free(obj); + isl_set_free(set); + + return v; +} + +/* Perform a compression on "node" where "hull" represents the constraints + * that were used to derive the compression, while "compress" and + * "decompress" map the original space to the compressed space and + * vice versa. + * + * If "node" was not compressed already, then simply store + * the compression information. + * Otherwise the "original" space is actually the result + * of a previous compression, which is then combined + * with the present compression. + * + * The dimensionality of the compressed domain is also adjusted. + * Other information, such as the sizes and the maximal coefficient values, + * has not been computed yet and therefore does not need to be adjusted. + */ +static isl_stat compress_node(struct isl_sched_node *node, + __isl_take isl_set *hull, __isl_take isl_multi_aff *compress, + __isl_take isl_pw_multi_aff *decompress) +{ + node->nvar = isl_multi_aff_dim(compress, isl_dim_out); + if (!node->compressed) { + node->compressed = 1; + node->hull = hull; + node->compress = compress; + node->decompress = decompress; + } else { + hull = isl_set_preimage_multi_aff(hull, + isl_multi_aff_copy(node->compress)); + node->hull = isl_set_intersect(node->hull, hull); + node->compress = isl_multi_aff_pullback_multi_aff( + compress, node->compress); + node->decompress = isl_pw_multi_aff_pullback_pw_multi_aff( + node->decompress, decompress); + } + + if (!node->hull || !node->compress || !node->decompress) + return isl_stat_error; + + return isl_stat_ok; +} + +/* Given that dimension "pos" in "set" has a fixed value + * in terms of the other dimensions, (further) compress "node" + * by projecting out this dimension. + * "set" may be the result of a previous compression. + * "uncompressed" is the original domain (without compression). + * + * The compression function simply projects out the dimension. + * The decompression function adds back the dimension + * in the right position as an expression of the other dimensions + * derived from "set". + * As in extract_node, the compressed space has an identifier + * that references "node" such that each compressed space is unique and + * such that the node can be recovered from the compressed space. + * + * The constraint removed through the compression is added to the "hull" + * such that only edges that relate to the original domains + * are taken into account. + * In particular, it is obtained by composing compression and decompression and + * taking the relation among the variables in the range. + */ +static isl_stat project_out_fixed(struct isl_sched_node *node, + __isl_keep isl_set *uncompressed, __isl_take isl_set *set, int pos) +{ + isl_id *id; + isl_space *space; + isl_set *domain; + isl_map *map; + isl_multi_aff *compress; + isl_pw_multi_aff *decompress, *pma; + isl_multi_pw_aff *mpa; + isl_set *hull; + + map = isolate(isl_set_copy(set), pos); + pma = isl_pw_multi_aff_from_map(map); + domain = isl_pw_multi_aff_domain(isl_pw_multi_aff_copy(pma)); + pma = isl_pw_multi_aff_gist(pma, domain); + space = isl_pw_multi_aff_get_domain_space(pma); + mpa = isl_multi_pw_aff_identity(isl_space_map_from_set(space)); + mpa = isl_multi_pw_aff_range_splice(mpa, pos, + isl_multi_pw_aff_from_pw_multi_aff(pma)); + decompress = isl_pw_multi_aff_from_multi_pw_aff(mpa); + space = isl_set_get_space(set); + compress = isl_multi_aff_project_out_map(space, isl_dim_set, pos, 1); + id = construct_compressed_id(uncompressed, node); + compress = isl_multi_aff_set_tuple_id(compress, isl_dim_out, id); + space = isl_space_reverse(isl_multi_aff_get_space(compress)); + decompress = isl_pw_multi_aff_reset_space(decompress, space); + pma = isl_pw_multi_aff_pullback_multi_aff( + isl_pw_multi_aff_copy(decompress), isl_multi_aff_copy(compress)); + hull = isl_map_range(isl_map_from_pw_multi_aff(pma)); + + isl_set_free(set); + + return compress_node(node, hull, compress, decompress); +} + +/* Compute the size of the compressed domain in each dimension and + * store the results in node->sizes. + * "uncompressed" is the original domain (without compression). + * + * First compress the domain if needed and then compute the size + * in each direction. + * 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. + * + * If any of the sizes turns out to be zero, then this means + * that this dimension has a fixed value in terms of + * the other dimensions. Perform an (extra) compression + * to remove this dimension. + */ +static isl_stat compute_sizes(struct isl_sched_node *node, + __isl_keep isl_set *uncompressed) +{ + int j; + isl_size n; + isl_multi_val *mv; + isl_set *set = isl_set_copy(uncompressed); + + if (node->compressed) + set = isl_set_preimage_pw_multi_aff(set, + isl_pw_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); + if (n < 0) + mv = isl_multi_val_free(mv); + for (j = 0; j < n; ++j) { + isl_bool is_zero; + isl_val *v; + + v = compute_size(isl_set_copy(set), j); + is_zero = isl_val_is_zero(v); + mv = isl_multi_val_set_val(mv, j, v); + if (is_zero >= 0 && is_zero) { + isl_multi_val_free(mv); + if (project_out_fixed(node, uncompressed, set, j) < 0) + return isl_stat_error; + return compute_sizes(node, uncompressed); + } + } + node->sizes = mv; + isl_set_free(set); + if (!node->sizes) + return isl_stat_error; + return isl_stat_ok; +} + +/* Compute the size of the instance set "set" of "node", after compression, + * as well as bounds on the corresponding coefficients, if needed. + * + * The sizes are needed when the schedule_treat_coalescing option is set. + * The bounds are needed when the schedule_treat_coalescing option or + * the schedule_max_coefficient option is set. + * + * If the schedule_treat_coalescing option is not set, then at most + * the bounds need to be set and this is done in set_max_coefficient. + * Otherwise, compute the size of the compressed domain + * in each direction and store the results in node->size. + * Finally, set the bounds on the coefficients based on the sizes + * and the schedule_max_coefficient option in compute_max_coefficient. + */ +static isl_stat compute_sizes_and_max(isl_ctx *ctx, struct isl_sched_node *node, + __isl_take isl_set *set) +{ + isl_stat r; + + if (!isl_options_get_schedule_treat_coalescing(ctx)) { + isl_set_free(set); + return set_max_coefficient(ctx, node); + } + + r = compute_sizes(node, set); + isl_set_free(set); + if (r < 0) + return isl_stat_error; + return compute_max_coefficient(ctx, node); +} + +/* Add a new node to the graph representing the given instance set. + * "nvar" is the (possibly compressed) number of variables and + * may be smaller than then number of set variables in "set" + * if "compressed" is set. + * If "compressed" is set, then "hull" represents the constraints + * that were used to derive the compression, while "compress" and + * "decompress" map the original space to the compressed space and + * vice versa. + * If "compressed" is not set, then "hull", "compress" and "decompress" + * should be NULL. + * + * Compute the size of the instance set and bounds on the coefficients, + * if needed. + */ +static isl_stat add_node(struct isl_sched_graph *graph, + __isl_take isl_set *set, int nvar, int compressed, + __isl_take isl_set *hull, __isl_take isl_multi_aff *compress, + __isl_take isl_pw_multi_aff *decompress) +{ + isl_size nparam; + isl_ctx *ctx; + isl_mat *sched; + isl_space *space; + int *coincident; + struct isl_sched_node *node; + + nparam = isl_set_dim(set, isl_dim_param); + if (nparam < 0) + goto error; + + ctx = isl_set_get_ctx(set); + if (!ctx->opt->schedule_parametric) + nparam = 0; + sched = isl_mat_alloc(ctx, 0, 1 + nparam + nvar); + node = &graph->node[graph->n]; + graph->n++; + space = isl_set_get_space(set); + node->space = space; + node->nvar = nvar; + node->nparam = nparam; + node->sched = sched; + node->sched_map = NULL; + coincident = isl_calloc_array(ctx, int, graph->max_row); + node->coincident = coincident; + node->compressed = compressed; + node->hull = hull; + node->compress = compress; + node->decompress = decompress; + if (compute_sizes_and_max(ctx, node, set) < 0) + return isl_stat_error; + + if (!space || !sched || (graph->max_row && !coincident)) + return isl_stat_error; + if (compressed && (!hull || !compress || !decompress)) + return isl_stat_error; + + return isl_stat_ok; +error: + isl_set_free(set); + isl_set_free(hull); + isl_multi_aff_free(compress); + isl_pw_multi_aff_free(decompress); + return isl_stat_error; +} + +/* Add a new node to the graph representing the given set. + * + * If any of the set variables is defined by an equality, then + * we perform variable compression such that we can perform + * the scheduling on the compressed domain. + * In this case, an identifier is used that references the new node + * such that each compressed space is unique and + * such that the node can be recovered from the compressed space. + */ +static isl_stat extract_node(__isl_take isl_set *set, void *user) +{ + isl_size nvar; + isl_bool has_equality; + isl_id *id; + isl_basic_set *hull; + isl_set *hull_set; + isl_morph *morph; + isl_multi_aff *compress, *decompress_ma; + isl_pw_multi_aff *decompress; + struct isl_sched_graph *graph = user; + + hull = isl_set_affine_hull(isl_set_copy(set)); + hull = isl_basic_set_remove_divs(hull); + nvar = isl_set_dim(set, isl_dim_set); + has_equality = has_any_defining_equality(hull); + + if (nvar < 0 || has_equality < 0) + goto error; + if (!has_equality) { + isl_basic_set_free(hull); + return add_node(graph, set, nvar, 0, NULL, NULL, NULL); + } + + id = construct_compressed_id(set, &graph->node[graph->n]); + morph = isl_basic_set_variable_compression_with_id(hull, id); + isl_id_free(id); + nvar = isl_morph_ran_dim(morph, isl_dim_set); + if (nvar < 0) + set = isl_set_free(set); + compress = isl_morph_get_var_multi_aff(morph); + morph = isl_morph_inverse(morph); + decompress_ma = isl_morph_get_var_multi_aff(morph); + decompress = isl_pw_multi_aff_from_multi_aff(decompress_ma); + isl_morph_free(morph); + + hull_set = isl_set_from_basic_set(hull); + return add_node(graph, set, nvar, 1, hull_set, compress, decompress); +error: + isl_basic_set_free(hull); + isl_set_free(set); + return isl_stat_error; +} + +struct isl_extract_edge_data { + isl_schedule_constraints *sc; + enum isl_edge_type type; + struct isl_sched_graph *graph; +}; + +/* Merge edge2 into edge1, freeing the contents of edge2. + * Return 0 on success and -1 on failure. + * + * edge1 and edge2 are assumed to have the same value for the map field. + */ +static int merge_edge(struct isl_sched_edge *edge1, + struct isl_sched_edge *edge2) +{ + edge1->types |= edge2->types; + isl_map_free(edge2->map); + + if (isl_sched_edge_is_condition(edge2)) { + if (!edge1->tagged_condition) + edge1->tagged_condition = edge2->tagged_condition; + else + edge1->tagged_condition = + isl_union_map_union(edge1->tagged_condition, + edge2->tagged_condition); + } + + if (isl_sched_edge_is_conditional_validity(edge2)) { + if (!edge1->tagged_validity) + edge1->tagged_validity = edge2->tagged_validity; + else + edge1->tagged_validity = + isl_union_map_union(edge1->tagged_validity, + edge2->tagged_validity); + } + + if (isl_sched_edge_is_condition(edge2) && !edge1->tagged_condition) + return -1; + if (isl_sched_edge_is_conditional_validity(edge2) && + !edge1->tagged_validity) + return -1; + + return 0; +} + +/* Insert dummy tags in domain and range of "map". + * + * In particular, if "map" is of the form + * + * A -> B + * + * then return + * + * [A -> dummy_tag] -> [B -> dummy_tag] + * + * where the dummy_tags are identical and equal to any dummy tags + * introduced by any other call to this function. + */ +static __isl_give isl_map *insert_dummy_tags(__isl_take isl_map *map) +{ + static char dummy; + isl_ctx *ctx; + isl_id *id; + isl_space *space; + isl_set *domain, *range; + + ctx = isl_map_get_ctx(map); + + id = isl_id_alloc(ctx, NULL, &dummy); + space = isl_space_params(isl_map_get_space(map)); + space = isl_space_set_from_params(space); + space = isl_space_set_tuple_id(space, isl_dim_set, id); + space = isl_space_map_from_set(space); + + domain = isl_map_wrap(map); + range = isl_map_wrap(isl_map_universe(space)); + map = isl_map_from_domain_and_range(domain, range); + map = isl_map_zip(map); + + return map; +} + +/* Given that at least one of "src" or "dst" is compressed, return + * a map between the spaces of these nodes restricted to the affine + * hull that was used in the compression. + */ +static __isl_give isl_map *extract_hull(struct isl_sched_node *src, + struct isl_sched_node *dst) +{ + isl_set *dom, *ran; + + if (src->compressed) + dom = isl_set_copy(src->hull); + else + dom = isl_set_universe(isl_space_copy(src->space)); + if (dst->compressed) + ran = isl_set_copy(dst->hull); + else + ran = isl_set_universe(isl_space_copy(dst->space)); + + return isl_map_from_domain_and_range(dom, ran); +} + +/* Intersect the domains of the nested relations in domain and range + * of "tagged" with "map". + */ +static __isl_give isl_map *map_intersect_domains(__isl_take isl_map *tagged, + __isl_keep isl_map *map) +{ + isl_set *set; + + tagged = isl_map_zip(tagged); + set = isl_map_wrap(isl_map_copy(map)); + tagged = isl_map_intersect_domain(tagged, set); + tagged = isl_map_zip(tagged); + return tagged; +} + +/* 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) +{ + struct isl_sched_node *node; + isl_space *space; + + space = isl_space_domain(isl_map_get_space(map)); + node = isl_sched_graph_find_node(ctx, graph, space); + isl_space_free(space); + + return 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) +{ + struct isl_sched_node *node; + isl_space *space; + + space = isl_space_range(isl_map_get_space(map)); + node = isl_sched_graph_find_node(ctx, graph, space); + isl_space_free(space); + + 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 + * to one of the dependence relations of a type that was added before, + * then we don't create a new edge, but instead mark the original edge + * as also representing a dependence of the current type. + * + * Edges of type isl_edge_condition or isl_edge_conditional_validity + * may be specified as "tagged" dependence relations. That is, "map" + * may contain elements (i -> a) -> (j -> b), where i -> j denotes + * the dependence on iterations and a and b are tags. + * edge->map is set to the relation containing the elements i -> j, + * while edge->tagged_condition and edge->tagged_validity contain + * the union of all the "map" relations + * for which extract_edge is called that result in the same edge->map. + * + * Compute the gist with respect to the context. + * This may remove some constraints on the parameters or + * eliminate some parts of the dependence relation + * that are not relevant on the context. + * + * If the source or the destination node is compressed, then + * intersect both "map" and "tagged" with the constraints that + * were used to construct the compression. + * This ensures that there are no schedule constraints defined + * outside of these domains, while the scheduler no longer has + * any control over those outside parts. + */ +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; + struct isl_sched_node *src, *dst; + struct isl_sched_edge *edge; + isl_set *context; + isl_map *tagged = NULL; + isl_schedule_constraints *sc = data->sc; + + if (data->type == isl_edge_condition || + data->type == isl_edge_conditional_validity) { + if (isl_map_can_zip(map)) { + tagged = isl_map_copy(map); + map = isl_set_unwrap(isl_map_domain(isl_map_zip(map))); + } else { + tagged = insert_dummy_tags(isl_map_copy(map)); + } + } + + src = find_domain_node(ctx, graph, map); + dst = find_range_node(ctx, graph, map); + + if (!src || !dst) + goto error; + if (!isl_sched_graph_is_node(graph, src) || + !isl_sched_graph_is_node(graph, dst)) + return skip_edge(map, tagged); + + context = isl_schedule_constraints_get_context(sc); + map = isl_map_gist_params(map, context); + + if (src->compressed || dst->compressed) { + isl_map *hull; + hull = extract_hull(src, dst); + if (tagged) + tagged = map_intersect_domains(tagged, hull); + 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; + graph->edge[graph->n_edge].types = 0; + graph->edge[graph->n_edge].tagged_condition = NULL; + graph->edge[graph->n_edge].tagged_validity = NULL; + set_type(&graph->edge[graph->n_edge], data->type); + if (data->type == isl_edge_condition) + graph->edge[graph->n_edge].tagged_condition = + isl_union_map_from_map(tagged); + if (data->type == isl_edge_conditional_validity) + graph->edge[graph->n_edge].tagged_validity = + isl_union_map_from_map(tagged); + + edge = graph_find_matching_edge(graph, &graph->edge[graph->n_edge]); + if (!edge) { + graph->n_edge++; + return isl_stat_error; + } + if (edge == &graph->edge[graph->n_edge]) + return graph_edge_table_add(ctx, graph, data->type, + &graph->edge[graph->n_edge++]); + + if (merge_edge(edge, &graph->edge[graph->n_edge]) < 0) + 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". + * + * The context is included in the domain before the nodes of + * the graphs are extracted in order to be able to exploit + * any possible additional equalities. + * Note that this intersection is only performed locally here. + */ +isl_stat isl_sched_graph_init(struct isl_sched_graph *graph, + __isl_keep isl_schedule_constraints *sc) +{ + isl_ctx *ctx; + isl_union_set *domain; + isl_union_map *c; + struct isl_extract_edge_data data = { sc }; + enum isl_edge_type i; + isl_stat r; + isl_size n; + + if (!sc) + return isl_stat_error; + + ctx = isl_schedule_constraints_get_ctx(sc); + + domain = isl_schedule_constraints_get_domain(sc); + n = isl_union_set_n_set(domain); + graph->n = n; + isl_union_set_free(domain); + if (n < 0) + return isl_stat_error; + + n = isl_schedule_constraints_n_map(sc); + if (n < 0 || graph_alloc(ctx, graph, graph->n, n) < 0) + return isl_stat_error; + + if (compute_max_row(graph, sc) < 0) + return isl_stat_error; + graph->root = graph; + graph->n = 0; + domain = isl_schedule_constraints_get_domain(sc); + domain = isl_union_set_intersect_params(domain, + isl_schedule_constraints_get_context(sc)); + r = isl_union_set_foreach_set(domain, &extract_node, graph); + isl_union_set_free(domain); + if (r < 0) + return isl_stat_error; + if (graph_init_table(ctx, graph) < 0) + return isl_stat_error; + for (i = isl_edge_first; i <= isl_edge_last; ++i) { + isl_size n; + + c = isl_schedule_constraints_get(sc, i); + n = isl_union_map_n_map(c); + graph->max_edge[i] = n; + isl_union_map_free(c); + if (n < 0) + return isl_stat_error; + } + if (graph_init_edge_tables(ctx, graph) < 0) + return isl_stat_error; + graph->n_edge = 0; + data.graph = graph; + for (i = isl_edge_first; i <= isl_edge_last; ++i) { + isl_stat r; + + data.type = i; + c = isl_schedule_constraints_get(sc, i); + r = isl_union_map_foreach_map(c, &extract_edge, &data); + isl_union_map_free(c); + if (r < 0) + return isl_stat_error; + } + + return isl_stat_ok; +} + +/* Check whether there is any dependence from node[j] to node[i] + * or from node[i] to node[j]. + */ +static isl_bool node_follows_weak(int i, int j, void *user) +{ + isl_bool f; + struct isl_sched_graph *graph = user; + + f = graph_has_any_edge(graph, &graph->node[j], &graph->node[i]); + if (f < 0 || f) + return f; + return graph_has_any_edge(graph, &graph->node[i], &graph->node[j]); +} + +/* Check whether there is a (conditional) validity dependence from node[j] + * to node[i], forcing node[i] to follow node[j]. + */ +static isl_bool node_follows_strong(int i, int j, void *user) +{ + struct isl_sched_graph *graph = user; + + return isl_sched_graph_has_validity_edge(graph, &graph->node[j], + &graph->node[i]); +} + +/* Use Tarjan's algorithm for computing the strongly connected components + * in the dependence graph only considering those edges defined by "follows". + */ +isl_stat isl_sched_graph_detect_ccs(isl_ctx *ctx, + struct isl_sched_graph *graph, + isl_bool (*follows)(int i, int j, void *user)) +{ + int i, n; + struct isl_tarjan_graph *g = NULL; + + g = isl_tarjan_graph_init(ctx, graph->n, follows, graph); + if (!g) + return isl_stat_error; + + graph->scc = 0; + i = 0; + n = graph->n; + while (n) { + while (g->order[i] != -1) { + graph->node[g->order[i]].scc = graph->scc; + --n; + ++i; + } + ++i; + graph->scc++; + } + + isl_tarjan_graph_free(g); + + 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 isl_stat detect_sccs(isl_ctx *ctx, struct isl_sched_graph *graph) +{ + graph->weak = 0; + return isl_sched_graph_detect_ccs(ctx, graph, &node_follows_strong); +} + +/* Apply Tarjan's algorithm to detect the (weakly) connected components + * in the dependence graph. + * Consider all dependences and set "weak". + */ +static isl_stat detect_wccs(isl_ctx *ctx, struct isl_sched_graph *graph) +{ + graph->weak = 1; + return isl_sched_graph_detect_ccs(ctx, graph, &node_follows_weak); +} + +static int cmp_scc(const void *a, const void *b, void *data) +{ + struct isl_sched_graph *graph = data; + const int *i1 = a; + const int *i2 = b; + + return graph->node[*i1].scc - graph->node[*i2].scc; +} + +/* Sort the elements of graph->sorted according to the corresponding SCCs. + */ +static int sort_sccs(struct isl_sched_graph *graph) +{ + return isl_sort(graph->sorted, graph->n, sizeof(int), &cmp_scc, graph); +} + +/* Return a non-parametric set in the compressed space of "node" that is + * bounded by the size in each direction + * + * { [x] : -S_i <= x_i <= S_i } + * + * If S_i is infinity in direction i, then there are no constraints + * in that direction. + * + * Cache the result in node->bounds. + */ +static __isl_give isl_basic_set *get_size_bounds(struct isl_sched_node *node) +{ + isl_space *space; + isl_basic_set *bounds; + int i; + + if (node->bounds) + return isl_basic_set_copy(node->bounds); + + if (node->compressed) + space = isl_pw_multi_aff_get_domain_space(node->decompress); + else + space = isl_space_copy(node->space); + space = isl_space_drop_all_params(space); + bounds = isl_basic_set_universe(space); + + for (i = 0; i < node->nvar; ++i) { + isl_val *size; + + size = isl_multi_val_get_val(node->sizes, i); + if (!size) + return isl_basic_set_free(bounds); + if (!isl_val_is_int(size)) { + isl_val_free(size); + continue; + } + bounds = isl_basic_set_upper_bound_val(bounds, isl_dim_set, i, + isl_val_copy(size)); + bounds = isl_basic_set_lower_bound_val(bounds, isl_dim_set, i, + isl_val_neg(size)); + } + + node->bounds = isl_basic_set_copy(bounds); + return bounds; +} + +/* Compress the dependence relation "map", if needed, i.e., + * when the source node "src" and/or the destination node "dst" + * has been compressed. + */ +static __isl_give isl_map *compress(__isl_take isl_map *map, + struct isl_sched_node *src, struct isl_sched_node *dst) +{ + if (src->compressed) + map = isl_map_preimage_domain_pw_multi_aff(map, + isl_pw_multi_aff_copy(src->decompress)); + if (dst->compressed) + map = isl_map_preimage_range_pw_multi_aff(map, + isl_pw_multi_aff_copy(dst->decompress)); + return map; +} + +/* Drop some constraints from "delta" that could be exploited + * to construct loop coalescing schedules. + * In particular, drop those constraint that bound the difference + * to the size of the domain. + * First project out the parameters to improve the effectiveness. + */ +static __isl_give isl_set *drop_coalescing_constraints( + __isl_take isl_set *delta, struct isl_sched_node *node) +{ + isl_size nparam; + isl_basic_set *bounds; + + nparam = isl_set_dim(delta, isl_dim_param); + if (nparam < 0) + return isl_set_free(delta); + + bounds = get_size_bounds(node); + + delta = isl_set_project_out(delta, isl_dim_param, 0, nparam); + delta = isl_set_remove_divs(delta); + delta = isl_set_plain_gist_basic_set(delta, bounds); + return delta; +} + +/* Given a dependence relation R from "node" to itself, + * construct the set of coefficients of valid constraints for elements + * in that dependence relation. + * In particular, the result contains tuples of coefficients + * c_0, c_n, c_x such that + * + * c_0 + c_n n + c_x y - c_x x >= 0 for each (x,y) in R + * + * or, equivalently, + * + * c_0 + c_n n + c_x d >= 0 for each d in delta R = { y - x | (x,y) in R } + * + * We choose here to compute the dual of delta R. + * Alternatively, we could have computed the dual of R, resulting + * in a set of tuples c_0, c_n, c_x, c_y, and then + * plugged in (c_0, c_n, c_x, -c_x). + * + * If "need_param" is set, then the resulting coefficients effectively + * include coefficients for the parameters c_n. Otherwise, they may + * have been projected out already. + * Since the constraints may be different for these two cases, + * they are stored in separate caches. + * In particular, if no parameter coefficients are required and + * the schedule_treat_coalescing option is set, then the parameters + * are projected out and some constraints that could be exploited + * to construct coalescing schedules are removed before the dual + * is computed. + * + * If "node" has been compressed, then the dependence relation + * is also compressed before the set of coefficients is computed. + */ +static __isl_give isl_basic_set *intra_coefficients( + struct isl_sched_graph *graph, struct isl_sched_node *node, + __isl_take isl_map *map, int need_param) +{ + isl_ctx *ctx; + isl_set *delta; + isl_map *key; + isl_basic_set *coef; + isl_maybe_isl_basic_set m; + isl_map_to_basic_set **hmap = &graph->intra_hmap; + int treat; + + if (!map) + return NULL; + + ctx = isl_map_get_ctx(map); + treat = !need_param && isl_options_get_schedule_treat_coalescing(ctx); + if (!treat) + hmap = &graph->intra_hmap_param; + m = isl_map_to_basic_set_try_get(*hmap, map); + if (m.valid < 0 || m.valid) { + isl_map_free(map); + return m.value; + } + + key = isl_map_copy(map); + map = compress(map, node, node); + delta = isl_map_deltas(map); + if (treat) + delta = drop_coalescing_constraints(delta, node); + delta = isl_set_remove_divs(delta); + coef = isl_set_coefficients(delta); + *hmap = isl_map_to_basic_set_set(*hmap, key, isl_basic_set_copy(coef)); + + return coef; +} + +/* Given a dependence relation R, construct the set of coefficients + * of valid constraints for elements in that dependence relation. + * In particular, the result contains tuples of coefficients + * c_0, c_n, c_x, c_y such that + * + * c_0 + c_n n + c_x x + c_y y >= 0 for each (x,y) in R + * + * If the source or destination nodes of "edge" have been compressed, + * then the dependence relation is also compressed before + * the set of coefficients is computed. + */ +static __isl_give isl_basic_set *inter_coefficients( + struct isl_sched_graph *graph, struct isl_sched_edge *edge, + __isl_take isl_map *map) +{ + isl_set *set; + isl_map *key; + isl_basic_set *coef; + isl_maybe_isl_basic_set m; + + m = isl_map_to_basic_set_try_get(graph->inter_hmap, map); + if (m.valid < 0 || m.valid) { + isl_map_free(map); + return m.value; + } + + key = isl_map_copy(map); + map = compress(map, edge->src, edge->dst); + set = isl_map_wrap(isl_map_remove_divs(map)); + coef = isl_set_coefficients(set); + graph->inter_hmap = isl_map_to_basic_set_set(graph->inter_hmap, key, + isl_basic_set_copy(coef)); + + return coef; +} + +/* Return the position of the coefficients of the variables in + * the coefficients constraints "coef". + * + * The space of "coef" is of the form + * + * { coefficients[[cst, params] -> S] } + * + * Return the position of S. + */ +static isl_size coef_var_offset(__isl_keep isl_basic_set *coef) +{ + isl_size offset; + isl_space *space; + + space = isl_space_unwrap(isl_basic_set_get_space(coef)); + offset = isl_space_dim(space, isl_dim_in); + isl_space_free(space); + + return offset; +} + +/* Return the offset of the coefficient of the constant term of "node" + * within the (I)LP. + * + * Within each node, the coefficients have the following order: + * - positive and negative parts of c_i_x + * - c_i_n (if parametric) + * - c_i_0 + */ +static int node_cst_coef_offset(struct isl_sched_node *node) +{ + return node->start + 2 * node->nvar + node->nparam; +} + +/* Return the offset of the coefficients of the parameters of "node" + * within the (I)LP. + * + * Within each node, the coefficients have the following order: + * - positive and negative parts of c_i_x + * - c_i_n (if parametric) + * - c_i_0 + */ +static int node_par_coef_offset(struct isl_sched_node *node) +{ + return node->start + 2 * node->nvar; +} + +/* Return the offset of the coefficients of the variables of "node" + * within the (I)LP. + * + * Within each node, the coefficients have the following order: + * - positive and negative parts of c_i_x + * - c_i_n (if parametric) + * - c_i_0 + */ +static int node_var_coef_offset(struct isl_sched_node *node) +{ + return node->start; +} + +/* Return the position of the pair of variables encoding + * coefficient "i" of "node". + * + * The order of these variable pairs is the opposite of + * that of the coefficients, with 2 variables per coefficient. + */ +static int node_var_coef_pos(struct isl_sched_node *node, int i) +{ + return node_var_coef_offset(node) + 2 * (node->nvar - 1 - i); +} + +/* Construct an isl_dim_map for mapping constraints on coefficients + * for "node" to the corresponding positions in graph->lp. + * "offset" is the offset of the coefficients for the variables + * in the input constraints. + * "s" is the sign of the mapping. + * + * The input constraints are given in terms of the coefficients + * (c_0, c_x) or (c_0, c_n, c_x). + * The mapping produced by this function essentially plugs in + * (0, c_i_x^+ - c_i_x^-) if s = 1 and + * (0, -c_i_x^+ + c_i_x^-) if s = -1 or + * (0, 0, c_i_x^+ - c_i_x^-) if s = 1 and + * (0, 0, -c_i_x^+ + c_i_x^-) if s = -1. + * In graph->lp, the c_i_x^- appear before their c_i_x^+ counterpart. + * Furthermore, the order of these pairs is the opposite of that + * of the corresponding coefficients. + * + * The caller can extend the mapping to also map the other coefficients + * (and therefore not plug in 0). + */ +static __isl_give isl_dim_map *intra_dim_map(isl_ctx *ctx, + struct isl_sched_graph *graph, struct isl_sched_node *node, + int offset, int s) +{ + int pos; + isl_size total; + isl_dim_map *dim_map; + + total = isl_basic_set_dim(graph->lp, isl_dim_all); + if (!node || total < 0) + return NULL; + + pos = node_var_coef_pos(node, 0); + dim_map = isl_dim_map_alloc(ctx, total); + isl_dim_map_range(dim_map, pos, -2, offset, 1, node->nvar, -s); + isl_dim_map_range(dim_map, pos + 1, -2, offset, 1, node->nvar, s); + + return dim_map; +} + +/* Construct an isl_dim_map for mapping constraints on coefficients + * for "src" (node i) and "dst" (node j) to the corresponding positions + * in graph->lp. + * "offset" is the offset of the coefficients for the variables of "src" + * in the input constraints. + * "s" is the sign of the mapping. + * + * The input constraints are given in terms of the coefficients + * (c_0, c_n, c_x, c_y). + * The mapping produced by this function essentially plugs in + * (c_j_0 - c_i_0, c_j_n - c_i_n, + * -(c_i_x^+ - c_i_x^-), c_j_x^+ - c_j_x^-) if s = 1 and + * (-c_j_0 + c_i_0, -c_j_n + c_i_n, + * c_i_x^+ - c_i_x^-, -(c_j_x^+ - c_j_x^-)) if s = -1. + * In graph->lp, the c_*^- appear before their c_*^+ counterpart. + * Furthermore, the order of these pairs is the opposite of that + * of the corresponding coefficients. + * + * The caller can further extend the mapping. + */ +static __isl_give isl_dim_map *inter_dim_map(isl_ctx *ctx, + struct isl_sched_graph *graph, struct isl_sched_node *src, + struct isl_sched_node *dst, int offset, int s) +{ + int pos; + isl_size total; + isl_dim_map *dim_map; + + total = isl_basic_set_dim(graph->lp, isl_dim_all); + if (!src || !dst || total < 0) + return NULL; + + dim_map = isl_dim_map_alloc(ctx, total); + + pos = node_cst_coef_offset(dst); + isl_dim_map_range(dim_map, pos, 0, 0, 0, 1, s); + pos = node_par_coef_offset(dst); + isl_dim_map_range(dim_map, pos, 1, 1, 1, dst->nparam, s); + pos = node_var_coef_pos(dst, 0); + isl_dim_map_range(dim_map, pos, -2, offset + src->nvar, 1, + dst->nvar, -s); + isl_dim_map_range(dim_map, pos + 1, -2, offset + src->nvar, 1, + dst->nvar, s); + + pos = node_cst_coef_offset(src); + isl_dim_map_range(dim_map, pos, 0, 0, 0, 1, -s); + pos = node_par_coef_offset(src); + isl_dim_map_range(dim_map, pos, 1, 1, 1, src->nparam, -s); + pos = node_var_coef_pos(src, 0); + isl_dim_map_range(dim_map, pos, -2, offset, 1, src->nvar, s); + isl_dim_map_range(dim_map, pos + 1, -2, offset, 1, src->nvar, -s); + + return dim_map; +} + +/* Add the constraints from "src" to "dst" using "dim_map", + * after making sure there is enough room in "dst" for the extra constraints. + */ +static __isl_give isl_basic_set *add_constraints_dim_map( + __isl_take isl_basic_set *dst, __isl_take isl_basic_set *src, + __isl_take isl_dim_map *dim_map) +{ + isl_size n_eq, n_ineq; + + n_eq = isl_basic_set_n_equality(src); + n_ineq = isl_basic_set_n_inequality(src); + if (n_eq < 0 || n_ineq < 0) + dst = isl_basic_set_free(dst); + dst = isl_basic_set_extend_constraints(dst, n_eq, n_ineq); + dst = isl_basic_set_add_constraints_dim_map(dst, src, dim_map); + return dst; +} + +/* Add constraints to graph->lp that force validity for the given + * dependence from a node i to itself. + * That is, add constraints that enforce + * + * (c_i_0 + c_i_n n + c_i_x y) - (c_i_0 + c_i_n n + c_i_x x) + * = c_i_x (y - x) >= 0 + * + * for each (x,y) in R. + * We obtain general constraints on coefficients (c_0, c_x) + * of valid constraints for (y - x) and then plug in (0, c_i_x^+ - c_i_x^-), + * where c_i_x = c_i_x^+ - c_i_x^-, with c_i_x^+ and c_i_x^- non-negative. + * In graph->lp, the c_i_x^- appear before their c_i_x^+ counterpart. + * Note that the result of intra_coefficients may also contain + * parameter coefficients c_n, in which case 0 is plugged in for them as well. + */ +static isl_stat add_intra_validity_constraints(struct isl_sched_graph *graph, + struct isl_sched_edge *edge) +{ + isl_size offset; + isl_map *map = isl_map_copy(edge->map); + isl_ctx *ctx = isl_map_get_ctx(map); + isl_dim_map *dim_map; + isl_basic_set *coef; + struct isl_sched_node *node = edge->src; + + coef = intra_coefficients(graph, node, map, 0); + + offset = coef_var_offset(coef); + if (offset < 0) + coef = isl_basic_set_free(coef); + if (!coef) + return isl_stat_error; + + dim_map = intra_dim_map(ctx, graph, node, offset, 1); + graph->lp = add_constraints_dim_map(graph->lp, coef, dim_map); + + return isl_stat_ok; +} + +/* Add constraints to graph->lp that force validity for the given + * dependence from node i to node j. + * That is, add constraints that enforce + * + * (c_j_0 + c_j_n n + c_j_x y) - (c_i_0 + c_i_n n + c_i_x x) >= 0 + * + * for each (x,y) in R. + * We obtain general constraints on coefficients (c_0, c_n, c_x, c_y) + * of valid constraints for R and then plug in + * (c_j_0 - c_i_0, c_j_n - c_i_n, -(c_i_x^+ - c_i_x^-), c_j_x^+ - c_j_x^-), + * where c_* = c_*^+ - c_*^-, with c_*^+ and c_*^- non-negative. + * In graph->lp, the c_*^- appear before their c_*^+ counterpart. + */ +static isl_stat add_inter_validity_constraints(struct isl_sched_graph *graph, + struct isl_sched_edge *edge) +{ + isl_size offset; + isl_map *map; + isl_ctx *ctx; + isl_dim_map *dim_map; + isl_basic_set *coef; + struct isl_sched_node *src = edge->src; + struct isl_sched_node *dst = edge->dst; + + if (!graph->lp) + return isl_stat_error; + + map = isl_map_copy(edge->map); + ctx = isl_map_get_ctx(map); + coef = inter_coefficients(graph, edge, map); + + offset = coef_var_offset(coef); + if (offset < 0) + coef = isl_basic_set_free(coef); + if (!coef) + return isl_stat_error; + + dim_map = inter_dim_map(ctx, graph, src, dst, offset, 1); + + edge->start = graph->lp->n_ineq; + graph->lp = add_constraints_dim_map(graph->lp, coef, dim_map); + if (!graph->lp) + return isl_stat_error; + edge->end = graph->lp->n_ineq; + + return isl_stat_ok; +} + +/* Add constraints to graph->lp that bound the dependence distance for the given + * dependence from a node i to itself. + * If s = 1, we add the constraint + * + * c_i_x (y - x) <= m_0 + m_n n + * + * or + * + * -c_i_x (y - x) + m_0 + m_n n >= 0 + * + * for each (x,y) in R. + * If s = -1, we add the constraint + * + * -c_i_x (y - x) <= m_0 + m_n n + * + * or + * + * c_i_x (y - x) + m_0 + m_n n >= 0 + * + * for each (x,y) in R. + * We obtain general constraints on coefficients (c_0, c_n, c_x) + * of valid constraints for (y - x) and then plug in (m_0, m_n, -s * c_i_x), + * with each coefficient (except m_0) represented as a pair of non-negative + * coefficients. + * + * + * If "local" is set, then we add constraints + * + * c_i_x (y - x) <= 0 + * + * or + * + * -c_i_x (y - x) <= 0 + * + * instead, forcing the dependence distance to be (less than or) equal to 0. + * That is, we plug in (0, 0, -s * c_i_x), + * intra_coefficients is not required to have c_n in its result when + * "local" is set. If they are missing, then (0, -s * c_i_x) is plugged in. + * Note that dependences marked local are treated as validity constraints + * by add_all_validity_constraints and therefore also have + * their distances bounded by 0 from below. + */ +static isl_stat add_intra_proximity_constraints(struct isl_sched_graph *graph, + struct isl_sched_edge *edge, int s, int local) +{ + isl_size offset; + isl_size nparam; + isl_map *map = isl_map_copy(edge->map); + isl_ctx *ctx = isl_map_get_ctx(map); + isl_dim_map *dim_map; + isl_basic_set *coef; + struct isl_sched_node *node = edge->src; + + coef = intra_coefficients(graph, node, map, !local); + nparam = isl_space_dim(node->space, isl_dim_param); + + offset = coef_var_offset(coef); + if (nparam < 0 || offset < 0) + coef = isl_basic_set_free(coef); + if (!coef) + return isl_stat_error; + + dim_map = intra_dim_map(ctx, graph, node, offset, -s); + + if (!local) { + isl_dim_map_range(dim_map, 1, 0, 0, 0, 1, 1); + isl_dim_map_range(dim_map, 4, 2, 1, 1, nparam, -1); + isl_dim_map_range(dim_map, 5, 2, 1, 1, nparam, 1); + } + graph->lp = add_constraints_dim_map(graph->lp, coef, dim_map); + + return isl_stat_ok; +} + +/* Add constraints to graph->lp that bound the dependence distance for the given + * dependence from node i to node j. + * If s = 1, we add the constraint + * + * (c_j_0 + c_j_n n + c_j_x y) - (c_i_0 + c_i_n n + c_i_x x) + * <= m_0 + m_n n + * + * or + * + * -(c_j_0 + c_j_n n + c_j_x y) + (c_i_0 + c_i_n n + c_i_x x) + + * m_0 + m_n n >= 0 + * + * for each (x,y) in R. + * If s = -1, we add the constraint + * + * -((c_j_0 + c_j_n n + c_j_x y) - (c_i_0 + c_i_n n + c_i_x x)) + * <= m_0 + m_n n + * + * or + * + * (c_j_0 + c_j_n n + c_j_x y) - (c_i_0 + c_i_n n + c_i_x x) + + * m_0 + m_n n >= 0 + * + * for each (x,y) in R. + * We obtain general constraints on coefficients (c_0, c_n, c_x, c_y) + * of valid constraints for R and then plug in + * (m_0 - s*c_j_0 + s*c_i_0, m_n - s*c_j_n + s*c_i_n, + * s*c_i_x, -s*c_j_x) + * with each coefficient (except m_0, c_*_0 and c_*_n) + * represented as a pair of non-negative coefficients. + * + * + * If "local" is set (and s = 1), then we add constraints + * + * (c_j_0 + c_j_n n + c_j_x y) - (c_i_0 + c_i_n n + c_i_x x) <= 0 + * + * or + * + * -((c_j_0 + c_j_n n + c_j_x y) + (c_i_0 + c_i_n n + c_i_x x)) >= 0 + * + * instead, forcing the dependence distance to be (less than or) equal to 0. + * That is, we plug in + * (-s*c_j_0 + s*c_i_0, -s*c_j_n + s*c_i_n, s*c_i_x, -s*c_j_x). + * Note that dependences marked local are treated as validity constraints + * by add_all_validity_constraints and therefore also have + * their distances bounded by 0 from below. + */ +static isl_stat add_inter_proximity_constraints(struct isl_sched_graph *graph, + struct isl_sched_edge *edge, int s, int local) +{ + isl_size offset; + isl_size nparam; + isl_map *map = isl_map_copy(edge->map); + isl_ctx *ctx = isl_map_get_ctx(map); + isl_dim_map *dim_map; + isl_basic_set *coef; + struct isl_sched_node *src = edge->src; + struct isl_sched_node *dst = edge->dst; + + coef = inter_coefficients(graph, edge, map); + nparam = isl_space_dim(src->space, isl_dim_param); + + offset = coef_var_offset(coef); + if (nparam < 0 || offset < 0) + coef = isl_basic_set_free(coef); + if (!coef) + return isl_stat_error; + + dim_map = inter_dim_map(ctx, graph, src, dst, offset, -s); + + if (!local) { + isl_dim_map_range(dim_map, 1, 0, 0, 0, 1, 1); + isl_dim_map_range(dim_map, 4, 2, 1, 1, nparam, -1); + isl_dim_map_range(dim_map, 5, 2, 1, 1, nparam, 1); + } + + graph->lp = add_constraints_dim_map(graph->lp, coef, dim_map); + + return isl_stat_ok; +} + +/* Should the distance over "edge" be forced to zero? + * That is, is it marked as a local edge? + * If "use_coincidence" is set, then coincidence edges are treated + * as local edges. + */ +static int force_zero(struct isl_sched_edge *edge, int use_coincidence) +{ + return is_local(edge) || (use_coincidence && is_coincidence(edge)); +} + +/* Add all validity constraints to graph->lp. + * + * An edge that is forced to be local needs to have its dependence + * distances equal to zero. We take care of bounding them by 0 from below + * here. add_all_proximity_constraints takes care of bounding them by 0 + * from above. + * + * If "use_coincidence" is set, then we treat coincidence edges as local edges. + * Otherwise, we ignore them. + */ +static int add_all_validity_constraints(struct isl_sched_graph *graph, + int use_coincidence) +{ + int i; + + for (i = 0; i < graph->n_edge; ++i) { + struct isl_sched_edge *edge = &graph->edge[i]; + int zero; + + zero = force_zero(edge, use_coincidence); + if (!is_validity(edge) && !zero) + continue; + if (edge->src != edge->dst) + continue; + if (add_intra_validity_constraints(graph, edge) < 0) + return -1; + } + + for (i = 0; i < graph->n_edge; ++i) { + struct isl_sched_edge *edge = &graph->edge[i]; + int zero; + + zero = force_zero(edge, use_coincidence); + if (!is_validity(edge) && !zero) + continue; + if (edge->src == edge->dst) + continue; + if (add_inter_validity_constraints(graph, edge) < 0) + return -1; + } + + return 0; +} + +/* Add constraints to graph->lp that bound the dependence distance + * for all dependence relations. + * If a given proximity dependence is identical to a validity + * dependence, then the dependence distance is already bounded + * from below (by zero), so we only need to bound the distance + * from above. (This includes the case of "local" dependences + * which are treated as validity dependence by add_all_validity_constraints.) + * Otherwise, we need to bound the distance both from above and from below. + * + * If "use_coincidence" is set, then we treat coincidence edges as local edges. + * Otherwise, we ignore them. + */ +static int add_all_proximity_constraints(struct isl_sched_graph *graph, + int use_coincidence) +{ + int i; + + for (i = 0; i < graph->n_edge; ++i) { + struct isl_sched_edge *edge = &graph->edge[i]; + int zero; + + zero = force_zero(edge, use_coincidence); + if (!isl_sched_edge_is_proximity(edge) && !zero) + continue; + if (edge->src == edge->dst && + add_intra_proximity_constraints(graph, edge, 1, zero) < 0) + return -1; + if (edge->src != edge->dst && + add_inter_proximity_constraints(graph, edge, 1, zero) < 0) + return -1; + if (is_validity(edge) || zero) + continue; + if (edge->src == edge->dst && + add_intra_proximity_constraints(graph, edge, -1, 0) < 0) + return -1; + if (edge->src != edge->dst && + add_inter_proximity_constraints(graph, edge, -1, 0) < 0) + return -1; + } + + return 0; +} + +/* Normalize the rows of "indep" such that all rows are lexicographically + * positive and such that each row contains as many final zeros as possible, + * given the choice for the previous rows. + * Do this by performing elementary row operations. + */ +static __isl_give isl_mat *normalize_independent(__isl_take isl_mat *indep) +{ + indep = isl_mat_reverse_gauss(indep); + indep = isl_mat_lexnonneg_rows(indep); + return indep; +} + +/* Extract the linear part of the current schedule for node "node". + */ +static __isl_give isl_mat *extract_linear_schedule(struct isl_sched_node *node) +{ + isl_size n_row = isl_mat_rows(node->sched); + + if (n_row < 0) + return NULL; + return isl_mat_sub_alloc(node->sched, 0, n_row, + 1 + node->nparam, node->nvar); +} + +/* Compute a basis for the rows in the linear part of the schedule + * and extend this basis to a full basis. The remaining rows + * can then be used to force linear independence from the rows + * in the schedule. + * + * In particular, given the schedule rows S, we compute + * + * S = H Q + * S U = H + * + * with H the Hermite normal form of S. That is, all but the + * first rank columns of H are zero and so each row in S is + * a linear combination of the first rank rows of Q. + * The matrix Q can be used as a variable transformation + * that isolates the directions of S in the first rank rows. + * Transposing S U = H yields + * + * U^T S^T = H^T + * + * with all but the first rank rows of H^T zero. + * The last rows of U^T are therefore linear combinations + * of schedule coefficients that are all zero on schedule + * coefficients that are linearly dependent on the rows of S. + * At least one of these combinations is non-zero on + * linearly independent schedule coefficients. + * The rows are normalized to involve as few of the last + * coefficients as possible and to have a positive initial value. + */ +isl_stat isl_sched_node_update_vmap(struct isl_sched_node *node) +{ + isl_mat *H, *U, *Q; + + H = extract_linear_schedule(node); + + H = isl_mat_left_hermite(H, 0, &U, &Q); + isl_mat_free(node->indep); + isl_mat_free(node->vmap); + node->vmap = Q; + node->indep = isl_mat_transpose(U); + node->rank = isl_mat_initial_non_zero_cols(H); + node->indep = isl_mat_drop_rows(node->indep, 0, node->rank); + node->indep = normalize_independent(node->indep); + isl_mat_free(H); + + if (!node->indep || !node->vmap || node->rank < 0) + return isl_stat_error; + return isl_stat_ok; +} + +/* Is "edge" marked as a validity or a conditional validity edge? + */ +static int is_any_validity(struct isl_sched_edge *edge) +{ + return is_validity(edge) || + isl_sched_edge_is_conditional_validity(edge); +} + +/* How many times should we count the constraints in "edge"? + * + * We count as follows + * validity -> 1 (>= 0) + * validity+proximity -> 2 (>= 0 and upper bound) + * proximity -> 2 (lower and upper bound) + * local(+any) -> 2 (>= 0 and <= 0) + * + * If an edge is only marked conditional_validity then it counts + * as zero since it is only checked afterwards. + * + * If "use_coincidence" is set, then we treat coincidence edges as local edges. + * Otherwise, we ignore them. + */ +static int edge_multiplicity(struct isl_sched_edge *edge, int use_coincidence) +{ + if (isl_sched_edge_is_proximity(edge) || + force_zero(edge, use_coincidence)) + return 2; + if (is_validity(edge)) + return 1; + return 0; +} + +/* How many times should the constraints in "edge" be counted + * as a parametric intra-node constraint? + * + * Only proximity edges that are not forced zero need + * coefficient constraints that include coefficients for parameters. + * If the edge is also a validity edge, then only + * an upper bound is introduced. Otherwise, both lower and upper bounds + * are introduced. + */ +static int parametric_intra_edge_multiplicity(struct isl_sched_edge *edge, + int use_coincidence) +{ + if (edge->src != edge->dst) + return 0; + if (!isl_sched_edge_is_proximity(edge)) + return 0; + if (force_zero(edge, use_coincidence)) + return 0; + if (is_validity(edge)) + return 1; + else + return 2; +} + +/* Add "f" times the number of equality and inequality constraints of "bset" + * to "n_eq" and "n_ineq" and free "bset". + */ +static isl_stat update_count(__isl_take isl_basic_set *bset, + int f, int *n_eq, int *n_ineq) +{ + isl_size eq, ineq; + + eq = isl_basic_set_n_equality(bset); + ineq = isl_basic_set_n_inequality(bset); + isl_basic_set_free(bset); + + if (eq < 0 || ineq < 0) + return isl_stat_error; + + *n_eq += eq; + *n_ineq += ineq; + + return isl_stat_ok; +} + +/* Count the number of equality and inequality constraints + * that will be added for the given map. + * + * The edges that require parameter coefficients are counted separately. + * + * "use_coincidence" is set if we should take into account coincidence edges. + */ +static isl_stat count_map_constraints(struct isl_sched_graph *graph, + struct isl_sched_edge *edge, __isl_take isl_map *map, + int *n_eq, int *n_ineq, int use_coincidence) +{ + isl_map *copy; + isl_basic_set *coef; + int f = edge_multiplicity(edge, use_coincidence); + int fp = parametric_intra_edge_multiplicity(edge, use_coincidence); + + if (f == 0) { + isl_map_free(map); + return isl_stat_ok; + } + + if (edge->src != edge->dst) { + coef = inter_coefficients(graph, edge, map); + return update_count(coef, f, n_eq, n_ineq); + } + + if (fp > 0) { + copy = isl_map_copy(map); + coef = intra_coefficients(graph, edge->src, copy, 1); + if (update_count(coef, fp, n_eq, n_ineq) < 0) + goto error; + } + + if (f > fp) { + copy = isl_map_copy(map); + coef = intra_coefficients(graph, edge->src, copy, 0); + if (update_count(coef, f - fp, n_eq, n_ineq) < 0) + goto error; + } + + isl_map_free(map); + return isl_stat_ok; +error: + isl_map_free(map); + return isl_stat_error; +} + +/* Count the number of equality and inequality constraints + * that will be added to the main lp problem. + * We count as follows + * validity -> 1 (>= 0) + * validity+proximity -> 2 (>= 0 and upper bound) + * proximity -> 2 (lower and upper bound) + * local(+any) -> 2 (>= 0 and <= 0) + * + * If "use_coincidence" is set, then we treat coincidence edges as local edges. + * Otherwise, we ignore them. + */ +static int count_constraints(struct isl_sched_graph *graph, + int *n_eq, int *n_ineq, int use_coincidence) +{ + int i; + + *n_eq = *n_ineq = 0; + for (i = 0; i < graph->n_edge; ++i) { + struct isl_sched_edge *edge = &graph->edge[i]; + isl_map *map = isl_map_copy(edge->map); + + if (count_map_constraints(graph, edge, map, n_eq, n_ineq, + use_coincidence) < 0) + return -1; + } + + return 0; +} + +/* Count the number of constraints that will be added by + * add_bound_constant_constraints to bound the values of the constant terms + * and increment *n_eq and *n_ineq accordingly. + * + * In practice, add_bound_constant_constraints only adds inequalities. + */ +static isl_stat count_bound_constant_constraints(isl_ctx *ctx, + struct isl_sched_graph *graph, int *n_eq, int *n_ineq) +{ + if (isl_options_get_schedule_max_constant_term(ctx) == -1) + return isl_stat_ok; + + *n_ineq += graph->n; + + return isl_stat_ok; +} + +/* Add constraints to bound the values of the constant terms in the schedule, + * if requested by the user. + * + * The maximal value of the constant terms is defined by the option + * "schedule_max_constant_term". + */ +static isl_stat add_bound_constant_constraints(isl_ctx *ctx, + struct isl_sched_graph *graph) +{ + int i, k; + int max; + isl_size total; + + max = isl_options_get_schedule_max_constant_term(ctx); + if (max == -1) + return isl_stat_ok; + + total = isl_basic_set_dim(graph->lp, isl_dim_set); + if (total < 0) + return isl_stat_error; + + for (i = 0; i < graph->n; ++i) { + struct isl_sched_node *node = &graph->node[i]; + int pos; + + k = isl_basic_set_alloc_inequality(graph->lp); + if (k < 0) + return isl_stat_error; + isl_seq_clr(graph->lp->ineq[k], 1 + total); + pos = node_cst_coef_offset(node); + isl_int_set_si(graph->lp->ineq[k][1 + pos], -1); + isl_int_set_si(graph->lp->ineq[k][0], max); + } + + return isl_stat_ok; +} + +/* Count the number of constraints that will be added by + * add_bound_coefficient_constraints and increment *n_eq and *n_ineq + * accordingly. + * + * In practice, add_bound_coefficient_constraints only adds inequalities. + */ +static int count_bound_coefficient_constraints(isl_ctx *ctx, + struct isl_sched_graph *graph, int *n_eq, int *n_ineq) +{ + int i; + + if (isl_options_get_schedule_max_coefficient(ctx) == -1 && + !isl_options_get_schedule_treat_coalescing(ctx)) + return 0; + + for (i = 0; i < graph->n; ++i) + *n_ineq += graph->node[i].nparam + 2 * graph->node[i].nvar; + + return 0; +} + +/* Add constraints to graph->lp that bound the values of + * the parameter schedule coefficients of "node" to "max" and + * the variable schedule coefficients to the corresponding entry + * in node->max. + * In either case, a negative value means that no bound needs to be imposed. + * + * For parameter coefficients, this amounts to adding a constraint + * + * c_n <= max + * + * i.e., + * + * -c_n + max >= 0 + * + * The variables coefficients are, however, not represented directly. + * Instead, the variable coefficients c_x are written as differences + * c_x = c_x^+ - c_x^-. + * That is, + * + * -max_i <= c_x_i <= max_i + * + * is encoded as + * + * -max_i <= c_x_i^+ - c_x_i^- <= max_i + * + * or + * + * -(c_x_i^+ - c_x_i^-) + max_i >= 0 + * c_x_i^+ - c_x_i^- + max_i >= 0 + */ +static isl_stat node_add_coefficient_constraints(isl_ctx *ctx, + struct isl_sched_graph *graph, struct isl_sched_node *node, int max) +{ + int i, j, k; + isl_size total; + isl_vec *ineq; + + total = isl_basic_set_dim(graph->lp, isl_dim_set); + if (total < 0) + return isl_stat_error; + + for (j = 0; j < node->nparam; ++j) { + int dim; + + if (max < 0) + continue; + + k = isl_basic_set_alloc_inequality(graph->lp); + if (k < 0) + return isl_stat_error; + dim = 1 + node_par_coef_offset(node) + j; + isl_seq_clr(graph->lp->ineq[k], 1 + total); + isl_int_set_si(graph->lp->ineq[k][dim], -1); + isl_int_set_si(graph->lp->ineq[k][0], max); + } + + ineq = isl_vec_alloc(ctx, 1 + total); + ineq = isl_vec_clr(ineq); + if (!ineq) + return isl_stat_error; + for (i = 0; i < node->nvar; ++i) { + int pos = 1 + node_var_coef_pos(node, i); + + if (isl_int_is_neg(node->max->el[i])) + continue; + + isl_int_set_si(ineq->el[pos], 1); + isl_int_set_si(ineq->el[pos + 1], -1); + isl_int_set(ineq->el[0], node->max->el[i]); + + k = isl_basic_set_alloc_inequality(graph->lp); + if (k < 0) + goto error; + isl_seq_cpy(graph->lp->ineq[k], ineq->el, 1 + total); + + isl_seq_neg(ineq->el + pos, ineq->el + pos, 2); + k = isl_basic_set_alloc_inequality(graph->lp); + if (k < 0) + goto error; + isl_seq_cpy(graph->lp->ineq[k], ineq->el, 1 + total); + + isl_seq_clr(ineq->el + pos, 2); + } + isl_vec_free(ineq); + + return isl_stat_ok; +error: + isl_vec_free(ineq); + return isl_stat_error; +} + +/* Add constraints that bound the values of the variable and parameter + * coefficients of the schedule. + * + * The maximal value of the coefficients is defined by the option + * 'schedule_max_coefficient' and the entries in node->max. + * These latter entries are only set if either the schedule_max_coefficient + * option or the schedule_treat_coalescing option is set. + */ +static isl_stat add_bound_coefficient_constraints(isl_ctx *ctx, + struct isl_sched_graph *graph) +{ + int i; + int max; + + max = isl_options_get_schedule_max_coefficient(ctx); + + if (max == -1 && !isl_options_get_schedule_treat_coalescing(ctx)) + return isl_stat_ok; + + for (i = 0; i < graph->n; ++i) { + struct isl_sched_node *node = &graph->node[i]; + + if (node_add_coefficient_constraints(ctx, graph, node, max) < 0) + return isl_stat_error; + } + + return isl_stat_ok; +} + +/* Add a constraint to graph->lp that equates the value at position + * "sum_pos" to the sum of the "n" values starting at "first". + */ +static isl_stat add_sum_constraint(struct isl_sched_graph *graph, + int sum_pos, int first, int n) +{ + int i, k; + isl_size total; + + total = isl_basic_set_dim(graph->lp, isl_dim_set); + if (total < 0) + return isl_stat_error; + + k = isl_basic_set_alloc_equality(graph->lp); + if (k < 0) + return isl_stat_error; + isl_seq_clr(graph->lp->eq[k], 1 + total); + isl_int_set_si(graph->lp->eq[k][1 + sum_pos], -1); + for (i = 0; i < n; ++i) + isl_int_set_si(graph->lp->eq[k][1 + first + i], 1); + + return isl_stat_ok; +} + +/* Add a constraint to graph->lp that equates the value at position + * "sum_pos" to the sum of the parameter coefficients of all nodes. + */ +static isl_stat add_param_sum_constraint(struct isl_sched_graph *graph, + int sum_pos) +{ + int i, j, k; + isl_size total; + + total = isl_basic_set_dim(graph->lp, isl_dim_set); + if (total < 0) + return isl_stat_error; + + k = isl_basic_set_alloc_equality(graph->lp); + if (k < 0) + return isl_stat_error; + isl_seq_clr(graph->lp->eq[k], 1 + total); + isl_int_set_si(graph->lp->eq[k][1 + sum_pos], -1); + for (i = 0; i < graph->n; ++i) { + int pos = 1 + node_par_coef_offset(&graph->node[i]); + + for (j = 0; j < graph->node[i].nparam; ++j) + isl_int_set_si(graph->lp->eq[k][pos + j], 1); + } + + return isl_stat_ok; +} + +/* Add a constraint to graph->lp that equates the value at position + * "sum_pos" to the sum of the variable coefficients of all nodes. + */ +static isl_stat add_var_sum_constraint(struct isl_sched_graph *graph, + int sum_pos) +{ + int i, j, k; + isl_size total; + + total = isl_basic_set_dim(graph->lp, isl_dim_set); + if (total < 0) + return isl_stat_error; + + k = isl_basic_set_alloc_equality(graph->lp); + if (k < 0) + return isl_stat_error; + isl_seq_clr(graph->lp->eq[k], 1 + total); + isl_int_set_si(graph->lp->eq[k][1 + sum_pos], -1); + for (i = 0; i < graph->n; ++i) { + struct isl_sched_node *node = &graph->node[i]; + int pos = 1 + node_var_coef_offset(node); + + for (j = 0; j < 2 * node->nvar; ++j) + isl_int_set_si(graph->lp->eq[k][pos + j], 1); + } + + return isl_stat_ok; +} + +/* Construct an ILP problem for finding schedule coefficients + * that result in non-negative, but small dependence distances + * over all dependences. + * In particular, the dependence distances over proximity edges + * are bounded by m_0 + m_n n and we compute schedule coefficients + * with small values (preferably zero) of m_n and m_0. + * + * All variables of the ILP are non-negative. The actual coefficients + * may be negative, so each coefficient is represented as the difference + * of two non-negative variables. The negative part always appears + * immediately before the positive part. + * Other than that, the variables have the following order + * + * - sum of positive and negative parts of m_n coefficients + * - m_0 + * - sum of all c_n coefficients + * (unconstrained when computing non-parametric schedules) + * - sum of positive and negative parts of all c_x coefficients + * - positive and negative parts of m_n coefficients + * - for each node + * - positive and negative parts of c_i_x, in opposite order + * - c_i_n (if parametric) + * - c_i_0 + * + * The constraints are those from the edges plus two or three equalities + * to express the sums. + * + * If "use_coincidence" is set, then we treat coincidence edges as local edges. + * Otherwise, we ignore them. + */ +static isl_stat setup_lp(isl_ctx *ctx, struct isl_sched_graph *graph, + int use_coincidence) +{ + int i; + isl_size nparam; + unsigned total; + isl_space *space; + int parametric; + int param_pos; + int n_eq, n_ineq; + + parametric = ctx->opt->schedule_parametric; + nparam = isl_space_dim(graph->node[0].space, isl_dim_param); + if (nparam < 0) + return isl_stat_error; + param_pos = 4; + total = param_pos + 2 * nparam; + for (i = 0; i < graph->n; ++i) { + struct isl_sched_node *node = &graph->node[graph->sorted[i]]; + if (isl_sched_node_update_vmap(node) < 0) + return isl_stat_error; + node->start = total; + total += 1 + node->nparam + 2 * node->nvar; + } + + if (count_constraints(graph, &n_eq, &n_ineq, use_coincidence) < 0) + return isl_stat_error; + if (count_bound_constant_constraints(ctx, graph, &n_eq, &n_ineq) < 0) + return isl_stat_error; + if (count_bound_coefficient_constraints(ctx, graph, &n_eq, &n_ineq) < 0) + return isl_stat_error; + + space = isl_space_set_alloc(ctx, 0, total); + isl_basic_set_free(graph->lp); + n_eq += 2 + parametric; + + graph->lp = isl_basic_set_alloc_space(space, 0, n_eq, n_ineq); + + if (add_sum_constraint(graph, 0, param_pos, 2 * nparam) < 0) + return isl_stat_error; + if (parametric && add_param_sum_constraint(graph, 2) < 0) + return isl_stat_error; + if (add_var_sum_constraint(graph, 3) < 0) + return isl_stat_error; + if (add_bound_constant_constraints(ctx, graph) < 0) + return isl_stat_error; + if (add_bound_coefficient_constraints(ctx, graph) < 0) + return isl_stat_error; + if (add_all_validity_constraints(graph, use_coincidence) < 0) + return isl_stat_error; + if (add_all_proximity_constraints(graph, use_coincidence) < 0) + return isl_stat_error; + + return isl_stat_ok; +} + +/* Analyze the conflicting constraint found by + * isl_tab_basic_set_non_trivial_lexmin. If it corresponds to the validity + * constraint of one of the edges between distinct nodes, living, moreover + * in distinct SCCs, then record the source and sink SCC as this may + * be a good place to cut between SCCs. + */ +static int check_conflict(int con, void *user) +{ + int i; + struct isl_sched_graph *graph = user; + + if (graph->src_scc >= 0) + return 0; + + con -= graph->lp->n_eq; + + if (con >= graph->lp->n_ineq) + return 0; + + for (i = 0; i < graph->n_edge; ++i) { + if (!is_validity(&graph->edge[i])) + continue; + if (graph->edge[i].src == graph->edge[i].dst) + continue; + if (graph->edge[i].src->scc == graph->edge[i].dst->scc) + continue; + if (graph->edge[i].start > con) + continue; + if (graph->edge[i].end <= con) + continue; + graph->src_scc = graph->edge[i].src->scc; + graph->dst_scc = graph->edge[i].dst->scc; + } + + return 0; +} + +/* Check whether the next schedule row of the given node needs to be + * non-trivial. Lower-dimensional domains may have some trivial rows, + * but as soon as the number of remaining required non-trivial rows + * is as large as the number or remaining rows to be computed, + * all remaining rows need to be non-trivial. + */ +static int needs_row(struct isl_sched_graph *graph, struct isl_sched_node *node) +{ + return node->nvar - node->rank >= graph->maxvar - graph->n_row; +} + +/* Construct a non-triviality region with triviality directions + * corresponding to the rows of "indep". + * The rows of "indep" are expressed in terms of the schedule coefficients c_i, + * while the triviality directions are expressed in terms of + * pairs of non-negative variables c^+_i - c^-_i, with c^-_i appearing + * before c^+_i. Furthermore, + * the pairs of non-negative variables representing the coefficients + * are stored in the opposite order. + */ +static __isl_give isl_mat *construct_trivial(__isl_keep isl_mat *indep) +{ + isl_ctx *ctx; + isl_mat *mat; + int i, j; + isl_size n, n_var; + + n = isl_mat_rows(indep); + n_var = isl_mat_cols(indep); + if (n < 0 || n_var < 0) + return NULL; + + ctx = isl_mat_get_ctx(indep); + mat = isl_mat_alloc(ctx, n, 2 * n_var); + if (!mat) + return NULL; + for (i = 0; i < n; ++i) { + for (j = 0; j < n_var; ++j) { + int nj = n_var - 1 - j; + isl_int_neg(mat->row[i][2 * nj], indep->row[i][j]); + isl_int_set(mat->row[i][2 * nj + 1], indep->row[i][j]); + } + } + + return mat; +} + +/* Solve the ILP problem constructed in setup_lp. + * For each node such that all the remaining rows of its schedule + * need to be non-trivial, we construct a non-triviality region. + * This region imposes that the next row is independent of previous rows. + * In particular, the non-triviality region enforces that at least + * one of the linear combinations in the rows of node->indep is non-zero. + */ +static __isl_give isl_vec *solve_lp(isl_ctx *ctx, struct isl_sched_graph *graph) +{ + int i; + isl_vec *sol; + isl_basic_set *lp; + + for (i = 0; i < graph->n; ++i) { + struct isl_sched_node *node = &graph->node[i]; + isl_mat *trivial; + + graph->region[i].pos = node_var_coef_offset(node); + if (needs_row(graph, node)) + trivial = construct_trivial(node->indep); + else + trivial = isl_mat_zero(ctx, 0, 0); + graph->region[i].trivial = trivial; + } + lp = isl_basic_set_copy(graph->lp); + sol = isl_tab_basic_set_non_trivial_lexmin(lp, 2, graph->n, + graph->region, &check_conflict, graph); + for (i = 0; i < graph->n; ++i) + isl_mat_free(graph->region[i].trivial); + return sol; +} + +/* Extract the coefficients for the variables of "node" from "sol". + * + * Each schedule coefficient c_i_x is represented as the difference + * between two non-negative variables c_i_x^+ - c_i_x^-. + * The c_i_x^- appear before their c_i_x^+ counterpart. + * Furthermore, the order of these pairs is the opposite of that + * of the corresponding coefficients. + * + * Return c_i_x = c_i_x^+ - c_i_x^- + */ +static __isl_give isl_vec *extract_var_coef(struct isl_sched_node *node, + __isl_keep isl_vec *sol) +{ + int i; + int pos; + isl_vec *csol; + + if (!sol) + return NULL; + csol = isl_vec_alloc(isl_vec_get_ctx(sol), node->nvar); + if (!csol) + return NULL; + + pos = 1 + node_var_coef_offset(node); + for (i = 0; i < node->nvar; ++i) + isl_int_sub(csol->el[node->nvar - 1 - i], + sol->el[pos + 2 * i + 1], sol->el[pos + 2 * i]); + + return csol; +} + +/* Update the schedules of all nodes based on the given solution + * of the LP problem. + * The new row is added to the current band. + * All possibly negative coefficients are encoded as a difference + * of two non-negative variables, so we need to perform the subtraction + * here. + * + * If coincident is set, then the caller guarantees that the new + * row satisfies the coincidence constraints. + */ +static int update_schedule(struct isl_sched_graph *graph, + __isl_take isl_vec *sol, int coincident) +{ + int i, j; + isl_vec *csol = NULL; + + if (!sol) + goto error; + if (sol->size == 0) + isl_die(sol->ctx, isl_error_internal, + "no solution found", goto error); + if (graph->n_total_row >= graph->max_row) + isl_die(sol->ctx, isl_error_internal, + "too many schedule rows", goto error); + + for (i = 0; i < graph->n; ++i) { + struct isl_sched_node *node = &graph->node[i]; + int pos; + isl_size row = isl_mat_rows(node->sched); + + isl_vec_free(csol); + csol = extract_var_coef(node, sol); + if (row < 0 || !csol) + goto error; + + isl_map_free(node->sched_map); + node->sched_map = NULL; + node->sched = isl_mat_add_rows(node->sched, 1); + if (!node->sched) + goto error; + pos = node_cst_coef_offset(node); + node->sched = isl_mat_set_element(node->sched, + row, 0, sol->el[1 + pos]); + pos = node_par_coef_offset(node); + for (j = 0; j < node->nparam; ++j) + node->sched = isl_mat_set_element(node->sched, + row, 1 + j, sol->el[1 + pos + j]); + for (j = 0; j < node->nvar; ++j) + node->sched = isl_mat_set_element(node->sched, + row, 1 + node->nparam + j, csol->el[j]); + node->coincident[graph->n_total_row] = coincident; + } + isl_vec_free(sol); + isl_vec_free(csol); + + graph->n_row++; + graph->n_total_row++; + + return 0; +error: + isl_vec_free(sol); + isl_vec_free(csol); + return -1; +} + +/* Convert row "row" of node->sched into an isl_aff living in "ls" + * and return this isl_aff. + */ +static __isl_give isl_aff *extract_schedule_row(__isl_take isl_local_space *ls, + struct isl_sched_node *node, int row) +{ + int j; + isl_int v; + isl_aff *aff; + + isl_int_init(v); + + aff = isl_aff_zero_on_domain(ls); + 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) { + 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) { + 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 + * and return this multi_aff. + * + * The result is defined over the uncompressed node domain. + */ +__isl_give isl_multi_aff *isl_sched_node_extract_partial_schedule_multi_aff( + struct isl_sched_node *node, int first, int n) +{ + int i; + isl_space *space; + isl_local_space *ls; + isl_aff *aff; + isl_multi_aff *ma; + isl_size nrow; + + if (!node) + return NULL; + nrow = isl_mat_rows(node->sched); + if (nrow < 0) + return NULL; + if (node->compressed) + space = isl_pw_multi_aff_get_domain_space(node->decompress); + else + space = isl_space_copy(node->space); + ls = isl_local_space_from_space(isl_space_copy(space)); + space = isl_space_from_domain(space); + space = isl_space_add_dims(space, isl_dim_out, n); + ma = isl_multi_aff_zero(space); + + for (i = first; i < first + n; ++i) { + aff = extract_schedule_row(isl_local_space_copy(ls), node, i); + ma = isl_multi_aff_set_aff(ma, i - first, aff); + } + + isl_local_space_free(ls); + + if (node->compressed) + ma = isl_multi_aff_pullback_multi_aff(ma, + isl_multi_aff_copy(node->compress)); + + return ma; +} + +/* Convert node->sched into a multi_aff and return this multi_aff. + * + * The result is defined over the uncompressed node domain. + */ +static __isl_give isl_multi_aff *node_extract_schedule_multi_aff( + struct isl_sched_node *node) +{ + isl_size nrow; + + nrow = isl_mat_rows(node->sched); + if (nrow < 0) + return NULL; + return isl_sched_node_extract_partial_schedule_multi_aff(node, 0, nrow); +} + +/* Convert node->sched into a map and return this map. + * + * The result is cached in node->sched_map, which needs to be released + * whenever node->sched is updated. + * It is defined over the uncompressed node domain. + */ +static __isl_give isl_map *node_extract_schedule(struct isl_sched_node *node) +{ + if (!node->sched_map) { + isl_multi_aff *ma; + + ma = node_extract_schedule_multi_aff(node); + node->sched_map = isl_map_from_multi_aff(ma); + } + + return isl_map_copy(node->sched_map); +} + +/* Construct a map that can be used to update a dependence relation + * based on the current schedule. + * That is, construct a map expressing that source and sink + * are executed within the same iteration of the current schedule. + * This map can then be intersected with the dependence relation. + * This is not the most efficient way, but this shouldn't be a critical + * operation. + */ +static __isl_give isl_map *specializer(struct isl_sched_node *src, + struct isl_sched_node *dst) +{ + isl_map *src_sched, *dst_sched; + + src_sched = node_extract_schedule(src); + dst_sched = node_extract_schedule(dst); + return isl_map_apply_range(src_sched, isl_map_reverse(dst_sched)); +} + +/* Intersect the domains of the nested relations in domain and range + * of "umap" with "map". + */ +static __isl_give isl_union_map *intersect_domains( + __isl_take isl_union_map *umap, __isl_keep isl_map *map) +{ + isl_union_set *uset; + + umap = isl_union_map_zip(umap); + uset = isl_union_set_from_set(isl_map_wrap(isl_map_copy(map))); + umap = isl_union_map_intersect_domain(umap, uset); + umap = isl_union_map_zip(umap); + return umap; +} + +/* Update the dependence relation of the given edge based + * on the current schedule. + * 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 isl_stat update_edge(isl_ctx *ctx, struct isl_sched_graph *graph, + struct isl_sched_edge *edge) +{ + int empty; + isl_map *id; + + id = specializer(edge->src, edge->dst); + edge->map = isl_map_intersect(edge->map, isl_map_copy(id)); + if (!edge->map) + goto error; + + if (edge->tagged_condition) { + edge->tagged_condition = + intersect_domains(edge->tagged_condition, id); + if (!edge->tagged_condition) + goto error; + } + if (edge->tagged_validity) { + edge->tagged_validity = + intersect_domains(edge->tagged_validity, id); + if (!edge->tagged_validity) + goto error; + } + + empty = isl_map_plain_is_empty(edge->map); + if (empty < 0) + goto error; + if (empty) { + if (graph_remove_edge(graph, edge) < 0) + goto error; + } else if (is_multi_edge_type(edge)) { + if (graph_edge_tables_add(ctx, graph, edge) < 0) + goto error; + } + + isl_map_free(id); + return isl_stat_ok; +error: + isl_map_free(id); + return isl_stat_error; +} + +/* Does the domain of "umap" intersect "uset"? + */ +static int domain_intersects(__isl_keep isl_union_map *umap, + __isl_keep isl_union_set *uset) +{ + int empty; + + umap = isl_union_map_copy(umap); + umap = isl_union_map_intersect_domain(umap, isl_union_set_copy(uset)); + empty = isl_union_map_is_empty(umap); + isl_union_map_free(umap); + + return empty < 0 ? -1 : !empty; +} + +/* Does the range of "umap" intersect "uset"? + */ +static int range_intersects(__isl_keep isl_union_map *umap, + __isl_keep isl_union_set *uset) +{ + int empty; + + umap = isl_union_map_copy(umap); + umap = isl_union_map_intersect_range(umap, isl_union_set_copy(uset)); + empty = isl_union_map_is_empty(umap); + isl_union_map_free(umap); + + return empty < 0 ? -1 : !empty; +} + +/* Are the condition dependences of "edge" local with respect to + * the current schedule? + * + * That is, are domain and range of the condition dependences mapped + * to the same point? + * + * In other words, is the condition false? + */ +static int is_condition_false(struct isl_sched_edge *edge) +{ + isl_union_map *umap; + isl_map *map, *sched, *test; + int empty, local; + + empty = isl_union_map_is_empty(edge->tagged_condition); + if (empty < 0 || empty) + return empty; + + umap = isl_union_map_copy(edge->tagged_condition); + umap = isl_union_map_zip(umap); + umap = isl_union_set_unwrap(isl_union_map_domain(umap)); + map = isl_map_from_union_map(umap); + + sched = node_extract_schedule(edge->src); + map = isl_map_apply_domain(map, sched); + sched = node_extract_schedule(edge->dst); + map = isl_map_apply_range(map, sched); + + test = isl_map_identity(isl_map_get_space(map)); + local = isl_map_is_subset(map, test); + isl_map_free(map); + isl_map_free(test); + + return local; +} + +/* For each conditional validity constraint that is adjacent + * to a condition with domain in condition_source or range in condition_sink, + * turn it into an unconditional validity constraint. + */ +static int unconditionalize_adjacent_validity(struct isl_sched_graph *graph, + __isl_take isl_union_set *condition_source, + __isl_take isl_union_set *condition_sink) +{ + int i; + + condition_source = isl_union_set_coalesce(condition_source); + condition_sink = isl_union_set_coalesce(condition_sink); + + for (i = 0; i < graph->n_edge; ++i) { + int adjacent; + isl_union_map *validity; + + if (!isl_sched_edge_is_conditional_validity(&graph->edge[i])) + continue; + if (is_validity(&graph->edge[i])) + continue; + + validity = graph->edge[i].tagged_validity; + adjacent = domain_intersects(validity, condition_sink); + if (adjacent >= 0 && !adjacent) + adjacent = range_intersects(validity, condition_source); + if (adjacent < 0) + goto error; + if (!adjacent) + continue; + + set_validity(&graph->edge[i]); + } + + isl_union_set_free(condition_source); + isl_union_set_free(condition_sink); + return 0; +error: + isl_union_set_free(condition_source); + isl_union_set_free(condition_sink); + return -1; +} + +/* Update the dependence relations of all edges based on the current schedule + * and enforce conditional validity constraints that are adjacent + * to satisfied condition constraints. + * + * First check if any of the condition constraints are satisfied + * (i.e., not local to the outer schedule) and keep track of + * their domain and range. + * Then update all dependence relations (which removes the non-local + * constraints). + * Finally, if any condition constraints turned out to be satisfied, + * then turn all adjacent conditional validity constraints into + * unconditional validity constraints. + */ +static int update_edges(isl_ctx *ctx, struct isl_sched_graph *graph) +{ + int i; + int any = 0; + isl_union_set *source, *sink; + + source = isl_union_set_empty(isl_space_params_alloc(ctx, 0)); + sink = isl_union_set_empty(isl_space_params_alloc(ctx, 0)); + for (i = 0; i < graph->n_edge; ++i) { + int local; + isl_union_set *uset; + isl_union_map *umap; + + if (!isl_sched_edge_is_condition(&graph->edge[i])) + continue; + if (is_local(&graph->edge[i])) + continue; + local = is_condition_false(&graph->edge[i]); + if (local < 0) + goto error; + if (local) + continue; + + any = 1; + + umap = isl_union_map_copy(graph->edge[i].tagged_condition); + uset = isl_union_map_domain(umap); + source = isl_union_set_union(source, uset); + + umap = isl_union_map_copy(graph->edge[i].tagged_condition); + uset = isl_union_map_range(umap); + sink = isl_union_set_union(sink, uset); + } + + for (i = 0; i < graph->n_edge; ++i) { + if (update_edge(ctx, graph, &graph->edge[i]) < 0) + goto error; + } + + if (any) + return unconditionalize_adjacent_validity(graph, source, sink); + + isl_union_set_free(source); + isl_union_set_free(sink); + return 0; +error: + isl_union_set_free(source); + isl_union_set_free(sink); + return -1; +} + +static void next_band(struct isl_sched_graph *graph) +{ + graph->band_start = graph->n_total_row; +} + +/* Return the union of the universe domains of the nodes in "graph" + * that satisfy "pred". + */ +static __isl_give isl_union_set *isl_sched_graph_domain(isl_ctx *ctx, + struct isl_sched_graph *graph, + int (*pred)(struct isl_sched_node *node, int data), int data) +{ + int i; + isl_set *set; + isl_union_set *dom; + + for (i = 0; i < graph->n; ++i) + if (pred(&graph->node[i], data)) + break; + + if (i >= graph->n) + isl_die(ctx, isl_error_internal, + "empty component", return NULL); + + set = isl_set_universe(isl_space_copy(graph->node[i].space)); + dom = isl_union_set_from_set(set); + + for (i = i + 1; i < graph->n; ++i) { + if (!pred(&graph->node[i], data)) + continue; + set = isl_set_universe(isl_space_copy(graph->node[i].space)); + dom = isl_union_set_union(dom, isl_union_set_from_set(set)); + } + + return dom; +} + +/* Return a union of universe domains corresponding to the nodes + * in the SCC with index "scc". + */ +__isl_give isl_union_set *isl_sched_graph_extract_scc(isl_ctx *ctx, + struct isl_sched_graph *graph, int scc) +{ + return isl_sched_graph_domain(ctx, graph, + &isl_sched_node_scc_exactly, scc); +} + +/* Return a list of unions of universe domains, where each element + * in the list corresponds to an SCC (or WCC) indexed by node->scc. + */ +__isl_give isl_union_set_list *isl_sched_graph_extract_sccs(isl_ctx *ctx, + struct isl_sched_graph *graph) +{ + int i; + isl_union_set_list *filters; + + filters = isl_union_set_list_alloc(ctx, graph->scc); + for (i = 0; i < graph->scc; ++i) { + isl_union_set *dom; + + dom = isl_sched_graph_extract_scc(ctx, graph, i); + filters = isl_union_set_list_add(filters, dom); + } + + return filters; +} + +/* Return a list of two unions of universe domains, one for the SCCs up + * to and including graph->src_scc and another for the other SCCs. + */ +static __isl_give isl_union_set_list *extract_split(isl_ctx *ctx, + struct isl_sched_graph *graph) +{ + isl_union_set *dom; + isl_union_set_list *filters; + + filters = isl_union_set_list_alloc(ctx, 2); + dom = isl_sched_graph_domain(ctx, graph, + &node_scc_at_most, graph->src_scc); + filters = isl_union_set_list_add(filters, dom); + dom = isl_sched_graph_domain(ctx, graph, + &node_scc_at_least, graph->src_scc + 1); + filters = isl_union_set_list_add(filters, dom); + + return filters; +} + +/* Copy nodes that satisfy node_pred from the src dependence graph + * to the dst dependence graph. + */ +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; + + dst->n = 0; + for (i = 0; i < src->n; ++i) { + int j; + + if (!node_pred(&src->node[i], data)) + continue; + + j = dst->n; + dst->node[j].space = isl_space_copy(src->node[i].space); + dst->node[j].compressed = src->node[i].compressed; + dst->node[j].hull = isl_set_copy(src->node[i].hull); + dst->node[j].compress = + isl_multi_aff_copy(src->node[i].compress); + dst->node[j].decompress = + isl_pw_multi_aff_copy(src->node[i].decompress); + dst->node[j].nvar = src->node[i].nvar; + dst->node[j].nparam = src->node[i].nparam; + dst->node[j].sched = isl_mat_copy(src->node[i].sched); + dst->node[j].sched_map = isl_map_copy(src->node[i].sched_map); + dst->node[j].coincident = src->node[i].coincident; + dst->node[j].sizes = isl_multi_val_copy(src->node[i].sizes); + dst->node[j].bounds = isl_basic_set_copy(src->node[i].bounds); + dst->node[j].max = isl_vec_copy(src->node[i].max); + dst->n++; + + if (!dst->node[j].space || !dst->node[j].sched) + return isl_stat_error; + if (dst->node[j].compressed && + (!dst->node[j].hull || !dst->node[j].compress || + !dst->node[j].decompress)) + return isl_stat_error; + } + + return isl_stat_ok; +} + +/* Copy non-empty edges that satisfy edge_pred from the src dependence graph + * to the dst dependence graph. + * If the source or destination node of the edge is not in the destination + * graph, then it must be a backward proximity edge and it should simply + * be ignored. + */ +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; + + dst->n_edge = 0; + for (i = 0; i < src->n_edge; ++i) { + struct isl_sched_edge *edge = &src->edge[i]; + isl_map *map; + isl_union_map *tagged_condition; + isl_union_map *tagged_validity; + struct isl_sched_node *dst_src, *dst_dst; + + if (!edge_pred(edge, data)) + continue; + + if (isl_map_plain_is_empty(edge->map)) + continue; + + dst_src = isl_sched_graph_find_node(ctx, dst, edge->src->space); + dst_dst = isl_sched_graph_find_node(ctx, dst, edge->dst->space); + if (!dst_src || !dst_dst) + return isl_stat_error; + if (!isl_sched_graph_is_node(dst, dst_src) || + !isl_sched_graph_is_node(dst, dst_dst)) { + if (is_validity(edge) || + isl_sched_edge_is_conditional_validity(edge)) + isl_die(ctx, isl_error_internal, + "backward (conditional) validity edge", + return isl_stat_error); + continue; + } + + map = isl_map_copy(edge->map); + tagged_condition = isl_union_map_copy(edge->tagged_condition); + tagged_validity = isl_union_map_copy(edge->tagged_validity); + + dst->edge[dst->n_edge].src = dst_src; + dst->edge[dst->n_edge].dst = dst_dst; + dst->edge[dst->n_edge].map = map; + dst->edge[dst->n_edge].tagged_condition = tagged_condition; + dst->edge[dst->n_edge].tagged_validity = tagged_validity; + dst->edge[dst->n_edge].types = edge->types; + dst->n_edge++; + + if (edge->tagged_condition && !tagged_condition) + return isl_stat_error; + if (edge->tagged_validity && !tagged_validity) + return isl_stat_error; + + if (graph_edge_tables_add(ctx, dst, + &dst->edge[dst->n_edge - 1]) < 0) + return isl_stat_error; + } + + return isl_stat_ok; +} + +/* Compute the maximal number of variables over all nodes. + * This is the maximal number of linearly independent schedule + * rows that we need to compute. + * Just in case we end up in a part of the dependence graph + * with only lower-dimensional domains, we make sure we will + * compute the required amount of extra linearly independent rows. + */ +isl_stat isl_sched_graph_compute_maxvar(struct isl_sched_graph *graph) +{ + int i; + + graph->maxvar = 0; + for (i = 0; i < graph->n; ++i) { + struct isl_sched_node *node = &graph->node[i]; + int nvar; + + if (isl_sched_node_update_vmap(node) < 0) + return isl_stat_error; + nvar = node->nvar + graph->n_row - node->rank; + if (nvar > graph->maxvar) + graph->maxvar = nvar; + } + + return isl_stat_ok; +} + +/* 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". + */ +isl_stat isl_sched_graph_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) +{ + int i, n = 0, n_edge = 0; + int t; + + for (i = 0; i < graph->n; ++i) + if (node_pred(&graph->node[i], data)) + ++n; + for (i = 0; i < graph->n_edge; ++i) + if (edge_pred(&graph->edge[i], data)) + ++n_edge; + if (graph_alloc(ctx, sub, n, n_edge) < 0) + return isl_stat_error; + sub->root = graph->root; + if (copy_nodes(sub, graph, node_pred, data) < 0) + return isl_stat_error; + if (graph_init_table(ctx, sub) < 0) + 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 isl_stat_error; + if (copy_edges(ctx, sub, graph, edge_pred, data) < 0) + 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 isl_stat_ok; +} + +static __isl_give isl_schedule_node *compute_schedule(isl_schedule_node *node, + struct isl_sched_graph *graph); +static __isl_give isl_schedule_node *compute_schedule_wcc( + isl_schedule_node *node, struct isl_sched_graph *graph); + +/* Compute a schedule for a subgraph of "graph". In particular, for + * the graph composed of nodes that satisfy node_pred and edges that + * that satisfy edge_pred. + * If the subgraph is known to consist of a single component, then wcc should + * be set and then we call compute_schedule_wcc on the constructed subgraph. + * Otherwise, we call compute_schedule, which will check whether the subgraph + * is connected. + * + * The schedule is inserted at "node" and the updated schedule node + * is returned. + */ +static __isl_give isl_schedule_node *compute_sub_schedule( + __isl_take isl_schedule_node *node, 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, int wcc) +{ + struct isl_sched_graph split = { 0 }; + + if (isl_sched_graph_extract_sub_graph(ctx, graph, node_pred, edge_pred, + data, &split) < 0) + goto error; + + if (wcc) + node = compute_schedule_wcc(node, &split); + else + node = compute_schedule(node, &split); + + isl_sched_graph_free(ctx, &split); + return node; +error: + isl_sched_graph_free(ctx, &split); + return isl_schedule_node_free(node); +} + +int isl_sched_edge_scc_exactly(struct isl_sched_edge *edge, int scc) +{ + return edge->src->scc == scc && edge->dst->scc == scc; +} + +static int edge_dst_scc_at_most(struct isl_sched_edge *edge, int scc) +{ + return edge->dst->scc <= scc; +} + +static int edge_src_scc_at_least(struct isl_sched_edge *edge, int scc) +{ + return edge->src->scc >= scc; +} + +/* Reset the current band by dropping all its schedule rows. + */ +static isl_stat reset_band(struct isl_sched_graph *graph) +{ + int i; + int drop; + + drop = graph->n_total_row - graph->band_start; + graph->n_total_row -= drop; + graph->n_row -= drop; + + for (i = 0; i < graph->n; ++i) { + struct isl_sched_node *node = &graph->node[i]; + + isl_map_free(node->sched_map); + node->sched_map = NULL; + + node->sched = isl_mat_drop_rows(node->sched, + graph->band_start, drop); + + if (!node->sched) + return isl_stat_error; + } + + return isl_stat_ok; +} + +/* Split the current graph into two parts and compute a schedule for each + * part individually. In particular, one part consists of all SCCs up + * to and including graph->src_scc, while the other part contains the other + * SCCs. The split is enforced by a sequence node inserted at position "node" + * in the schedule tree. Return the updated schedule node. + * If either of these two parts consists of a sequence, then it is spliced + * into the sequence containing the two parts. + * + * The current band is reset. It would be possible to reuse + * the previously computed rows as the first rows in the next + * band, but recomputing them may result in better rows as we are looking + * at a smaller part of the dependence graph. + */ +static __isl_give isl_schedule_node *compute_split_schedule( + __isl_take isl_schedule_node *node, struct isl_sched_graph *graph) +{ + isl_ctx *ctx; + isl_union_set_list *filters; + + if (!node) + return NULL; + + if (reset_band(graph) < 0) + return isl_schedule_node_free(node); + + next_band(graph); + + ctx = isl_schedule_node_get_ctx(node); + filters = extract_split(ctx, graph); + node = isl_schedule_node_insert_sequence(node, filters); + node = isl_schedule_node_grandchild(node, 1, 0); + + node = compute_sub_schedule(node, ctx, graph, + &node_scc_at_least, &edge_src_scc_at_least, + graph->src_scc + 1, 0); + node = isl_schedule_node_grandparent(node); + node = isl_schedule_node_grandchild(node, 0, 0); + node = compute_sub_schedule(node, ctx, graph, + &node_scc_at_most, &edge_dst_scc_at_most, + graph->src_scc, 0); + node = isl_schedule_node_grandparent(node); + + node = isl_schedule_node_sequence_splice_children(node); + + return node; +} + +/* Insert a band node at position "node" in the schedule tree corresponding + * to the current band in "graph". Mark the band node permutable + * if "permutable" is set. + * The partial schedules and the coincidence property are extracted + * from the graph nodes. + * Return the updated schedule node. + */ +static __isl_give isl_schedule_node *insert_current_band( + __isl_take isl_schedule_node *node, struct isl_sched_graph *graph, + int permutable) +{ + int i; + int start, end, n; + isl_multi_aff *ma; + isl_multi_pw_aff *mpa; + isl_multi_union_pw_aff *mupa; + + if (!node) + return NULL; + + if (graph->n < 1) + isl_die(isl_schedule_node_get_ctx(node), isl_error_internal, + "graph should have at least one node", + return isl_schedule_node_free(node)); + + start = graph->band_start; + end = graph->n_total_row; + n = end - start; + + ma = isl_sched_node_extract_partial_schedule_multi_aff(&graph->node[0], + start, n); + mpa = isl_multi_pw_aff_from_multi_aff(ma); + mupa = isl_multi_union_pw_aff_from_multi_pw_aff(mpa); + + for (i = 1; i < graph->n; ++i) { + isl_multi_union_pw_aff *mupa_i; + + ma = isl_sched_node_extract_partial_schedule_multi_aff( + &graph->node[i], start, n); + mpa = isl_multi_pw_aff_from_multi_aff(ma); + mupa_i = isl_multi_union_pw_aff_from_multi_pw_aff(mpa); + mupa = isl_multi_union_pw_aff_union_add(mupa, mupa_i); + } + node = isl_schedule_node_insert_partial_schedule(node, mupa); + + for (i = 0; i < n; ++i) + node = isl_schedule_node_band_member_set_coincident(node, i, + graph->node[0].coincident[start + i]); + node = isl_schedule_node_band_set_permutable(node, permutable); + + return node; +} + +/* Update the dependence relations based on the current schedule, + * add the current band to "node" and then continue with the computation + * of the next band. + * Return the updated schedule node. + */ +static __isl_give isl_schedule_node *compute_next_band( + __isl_take isl_schedule_node *node, + struct isl_sched_graph *graph, int permutable) +{ + isl_ctx *ctx; + + if (!node) + return NULL; + + ctx = isl_schedule_node_get_ctx(node); + if (update_edges(ctx, graph) < 0) + return isl_schedule_node_free(node); + node = insert_current_band(node, graph, permutable); + next_band(graph); + + node = isl_schedule_node_child(node, 0); + node = compute_schedule(node, graph); + node = isl_schedule_node_parent(node); + + return node; +} + +/* Add the constraints "coef" derived from an edge from "node" to itself + * to graph->lp in order to respect the dependences and to try and carry them. + * "pos" is the sequence number of the edge that needs to be carried. + * "coef" represents general constraints on coefficients (c_0, c_x) + * of valid constraints for (y - x) with x and y instances of the node. + * + * The constraints added to graph->lp need to enforce + * + * (c_j_0 + c_j_x y) - (c_j_0 + c_j_x x) + * = c_j_x (y - x) >= e_i + * + * for each (x,y) in the dependence relation of the edge. + * That is, (-e_i, c_j_x) needs to be plugged in for (c_0, c_x), + * taking into account that each coefficient in c_j_x is represented + * as a pair of non-negative coefficients. + */ +static isl_stat add_intra_constraints(struct isl_sched_graph *graph, + struct isl_sched_node *node, __isl_take isl_basic_set *coef, int pos) +{ + isl_size offset; + isl_ctx *ctx; + isl_dim_map *dim_map; + + offset = coef_var_offset(coef); + if (offset < 0) + coef = isl_basic_set_free(coef); + if (!coef) + return isl_stat_error; + + ctx = isl_basic_set_get_ctx(coef); + dim_map = intra_dim_map(ctx, graph, node, offset, 1); + isl_dim_map_range(dim_map, 3 + pos, 0, 0, 0, 1, -1); + graph->lp = add_constraints_dim_map(graph->lp, coef, dim_map); + + return isl_stat_ok; +} + +/* Add the constraints "coef" derived from an edge from "src" to "dst" + * to graph->lp in order to respect the dependences and to try and carry them. + * "pos" is the sequence number of the edge that needs to be carried or + * -1 if no attempt should be made to carry the dependences. + * "coef" represents general constraints on coefficients (c_0, c_n, c_x, c_y) + * of valid constraints for (x, y) with x and y instances of "src" and "dst". + * + * The constraints added to graph->lp need to enforce + * + * (c_k_0 + c_k_n n + c_k_x y) - (c_j_0 + c_j_n n + c_j_x x) >= e_i + * + * for each (x,y) in the dependence relation of the edge or + * + * (c_k_0 + c_k_n n + c_k_x y) - (c_j_0 + c_j_n n + c_j_x x) >= 0 + * + * if pos is -1. + * That is, + * (-e_i + c_k_0 - c_j_0, c_k_n - c_j_n, -c_j_x, c_k_x) + * or + * (c_k_0 - c_j_0, c_k_n - c_j_n, -c_j_x, c_k_x) + * needs to be plugged in for (c_0, c_n, c_x, c_y), + * taking into account that each coefficient in c_j_x and c_k_x is represented + * as a pair of non-negative coefficients. + */ +static isl_stat add_inter_constraints(struct isl_sched_graph *graph, + struct isl_sched_node *src, struct isl_sched_node *dst, + __isl_take isl_basic_set *coef, int pos) +{ + isl_size offset; + isl_ctx *ctx; + isl_dim_map *dim_map; + + offset = coef_var_offset(coef); + if (offset < 0) + coef = isl_basic_set_free(coef); + if (!coef) + return isl_stat_error; + + ctx = isl_basic_set_get_ctx(coef); + dim_map = inter_dim_map(ctx, graph, src, dst, offset, 1); + if (pos >= 0) + isl_dim_map_range(dim_map, 3 + pos, 0, 0, 0, 1, -1); + graph->lp = add_constraints_dim_map(graph->lp, coef, dim_map); + + return isl_stat_ok; +} + +/* Data structure for keeping track of the data needed + * to exploit non-trivial lineality spaces. + * + * "any_non_trivial" is true if there are any non-trivial lineality spaces. + * If "any_non_trivial" is not true, then "equivalent" and "mask" may be NULL. + * "equivalent" connects instances to other instances on the same line(s). + * "mask" contains the domain spaces of "equivalent". + * Any instance set not in "mask" does not have a non-trivial lineality space. + */ +struct isl_exploit_lineality_data { + isl_bool any_non_trivial; + isl_union_map *equivalent; + isl_union_set *mask; +}; + +/* Data structure collecting information used during the construction + * of an LP for carrying dependences. + * + * "intra" is a sequence of coefficient constraints for intra-node edges. + * "inter" is a sequence of coefficient constraints for inter-node edges. + * "lineality" contains data used to exploit non-trivial lineality spaces. + */ +struct isl_carry { + isl_basic_set_list *intra; + isl_basic_set_list *inter; + struct isl_exploit_lineality_data lineality; +}; + +/* Free all the data stored in "carry". + */ +static void isl_carry_clear(struct isl_carry *carry) +{ + isl_basic_set_list_free(carry->intra); + isl_basic_set_list_free(carry->inter); + isl_union_map_free(carry->lineality.equivalent); + isl_union_set_free(carry->lineality.mask); +} + +/* 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. + * Otherwise, "space" was constructed by construct_compressed_id and + * contains a user pointer pointing to the node in the tuple id. + * However, this node belongs to the original dependence graph. + * If "graph" is a subgraph of this original dependence graph, + * then the node with the same space still needs to be looked up + * in the current graph. + */ +static struct isl_sched_node *graph_find_compressed_node(isl_ctx *ctx, + struct isl_sched_graph *graph, __isl_keep isl_space *space) +{ + isl_id *id; + struct isl_sched_node *node; + + if (!space) + return NULL; + + node = isl_sched_graph_find_node(ctx, graph, space); + if (!node) + return NULL; + if (isl_sched_graph_is_node(graph, node)) + return node; + + id = isl_space_get_tuple_id(space, isl_dim_set); + node = isl_id_get_user(id); + isl_id_free(id); + + if (!node) + return NULL; + + if (!isl_sched_graph_is_node(graph->root, node)) + isl_die(ctx, isl_error_internal, + "space points to invalid node", return NULL); + if (graph != graph->root) + node = isl_sched_graph_find_node(ctx, graph, node->space); + if (!isl_sched_graph_is_node(graph, node)) + isl_die(ctx, isl_error_internal, + "unable to find node", return NULL); + + return node; +} + +/* Internal data structure for add_all_constraints. + * + * "graph" is the schedule constraint graph for which an LP problem + * is being constructed. + * "carry_inter" indicates whether inter-node edges should be carried. + * "pos" is the position of the next edge that needs to be carried. + */ +struct isl_add_all_constraints_data { + isl_ctx *ctx; + struct isl_sched_graph *graph; + int carry_inter; + int pos; +}; + +/* Add the constraints "coef" derived from an edge from a node to itself + * to data->graph->lp in order to respect the dependences and + * to try and carry them. + * + * The space of "coef" is of the form + * + * coefficients[[c_cst] -> S[c_x]] + * + * with S[c_x] the (compressed) space of the node. + * Extract the node from the space and call add_intra_constraints. + */ +static isl_stat lp_add_intra(__isl_take isl_basic_set *coef, void *user) +{ + struct isl_add_all_constraints_data *data = user; + isl_space *space; + struct isl_sched_node *node; + + space = isl_basic_set_get_space(coef); + space = isl_space_range(isl_space_unwrap(space)); + node = graph_find_compressed_node(data->ctx, data->graph, space); + isl_space_free(space); + return add_intra_constraints(data->graph, node, coef, data->pos++); +} + +/* Add the constraints "coef" derived from an edge from a node j + * to a node k to data->graph->lp in order to respect the dependences and + * to try and carry them (provided data->carry_inter is set). + * + * The space of "coef" is of the form + * + * coefficients[[c_cst, c_n] -> [S_j[c_x] -> S_k[c_y]]] + * + * with S_j[c_x] and S_k[c_y] the (compressed) spaces of the nodes. + * Extract the nodes from the space and call add_inter_constraints. + */ +static isl_stat lp_add_inter(__isl_take isl_basic_set *coef, void *user) +{ + struct isl_add_all_constraints_data *data = user; + isl_space *space, *dom; + struct isl_sched_node *src, *dst; + int pos; + + space = isl_basic_set_get_space(coef); + space = isl_space_unwrap(isl_space_range(isl_space_unwrap(space))); + dom = isl_space_domain(isl_space_copy(space)); + src = graph_find_compressed_node(data->ctx, data->graph, dom); + isl_space_free(dom); + space = isl_space_range(space); + dst = graph_find_compressed_node(data->ctx, data->graph, space); + isl_space_free(space); + + pos = data->carry_inter ? data->pos++ : -1; + return add_inter_constraints(data->graph, src, dst, coef, pos); +} + +/* Add constraints to graph->lp that force all (conditional) validity + * dependences to be respected and attempt to carry them. + * "intra" is the sequence of coefficient constraints for intra-node edges. + * "inter" is the sequence of coefficient constraints for inter-node edges. + * "carry_inter" indicates whether inter-node edges should be carried or + * only respected. + */ +static isl_stat add_all_constraints(isl_ctx *ctx, struct isl_sched_graph *graph, + __isl_keep isl_basic_set_list *intra, + __isl_keep isl_basic_set_list *inter, int carry_inter) +{ + struct isl_add_all_constraints_data data = { ctx, graph, carry_inter }; + + data.pos = 0; + if (isl_basic_set_list_foreach(intra, &lp_add_intra, &data) < 0) + return isl_stat_error; + if (isl_basic_set_list_foreach(inter, &lp_add_inter, &data) < 0) + return isl_stat_error; + return isl_stat_ok; +} + +/* Internal data structure for count_all_constraints + * for keeping track of the number of equality and inequality constraints. + */ +struct isl_sched_count { + int n_eq; + int n_ineq; +}; + +/* Add the number of equality and inequality constraints of "bset" + * to data->n_eq and data->n_ineq. + */ +static isl_stat bset_update_count(__isl_take isl_basic_set *bset, void *user) +{ + struct isl_sched_count *data = user; + + return update_count(bset, 1, &data->n_eq, &data->n_ineq); +} + +/* Count the number of equality and inequality constraints + * that will be added to the carry_lp problem. + * We count each edge exactly once. + * "intra" is the sequence of coefficient constraints for intra-node edges. + * "inter" is the sequence of coefficient constraints for inter-node edges. + */ +static isl_stat count_all_constraints(__isl_keep isl_basic_set_list *intra, + __isl_keep isl_basic_set_list *inter, int *n_eq, int *n_ineq) +{ + struct isl_sched_count data; + + data.n_eq = data.n_ineq = 0; + if (isl_basic_set_list_foreach(inter, &bset_update_count, &data) < 0) + return isl_stat_error; + if (isl_basic_set_list_foreach(intra, &bset_update_count, &data) < 0) + return isl_stat_error; + + *n_eq = data.n_eq; + *n_ineq = data.n_ineq; + + return isl_stat_ok; +} + +/* Construct an LP problem for finding schedule coefficients + * such that the schedule carries as many validity dependences as possible. + * In particular, for each dependence i, we bound the dependence distance + * from below by e_i, with 0 <= e_i <= 1 and then maximize the sum + * of all e_i's. Dependences with e_i = 0 in the solution are simply + * respected, while those with e_i > 0 (in practice e_i = 1) are carried. + * "intra" is the sequence of coefficient constraints for intra-node edges. + * "inter" is the sequence of coefficient constraints for inter-node edges. + * "n_edge" is the total number of edges. + * "carry_inter" indicates whether inter-node edges should be carried or + * only respected. That is, if "carry_inter" is not set, then + * no e_i variables are introduced for the inter-node edges. + * + * All variables of the LP are non-negative. The actual coefficients + * may be negative, so each coefficient is represented as the difference + * of two non-negative variables. The negative part always appears + * immediately before the positive part. + * Other than that, the variables have the following order + * + * - sum of (1 - e_i) over all edges + * - sum of all c_n coefficients + * (unconstrained when computing non-parametric schedules) + * - sum of positive and negative parts of all c_x coefficients + * - for each edge + * - e_i + * - for each node + * - positive and negative parts of c_i_x, in opposite order + * - c_i_n (if parametric) + * - c_i_0 + * + * The constraints are those from the (validity) edges plus three equalities + * to express the sums and n_edge inequalities to express e_i <= 1. + */ +static isl_stat setup_carry_lp(isl_ctx *ctx, struct isl_sched_graph *graph, + int n_edge, __isl_keep isl_basic_set_list *intra, + __isl_keep isl_basic_set_list *inter, int carry_inter) +{ + int i; + int k; + isl_space *space; + unsigned total; + int n_eq, n_ineq; + + total = 3 + n_edge; + for (i = 0; i < graph->n; ++i) { + struct isl_sched_node *node = &graph->node[graph->sorted[i]]; + node->start = total; + total += 1 + node->nparam + 2 * node->nvar; + } + + if (count_all_constraints(intra, inter, &n_eq, &n_ineq) < 0) + return isl_stat_error; + + space = isl_space_set_alloc(ctx, 0, total); + isl_basic_set_free(graph->lp); + n_eq += 3; + n_ineq += n_edge; + graph->lp = isl_basic_set_alloc_space(space, 0, n_eq, n_ineq); + graph->lp = isl_basic_set_set_rational(graph->lp); + + k = isl_basic_set_alloc_equality(graph->lp); + if (k < 0) + return isl_stat_error; + isl_seq_clr(graph->lp->eq[k], 1 + total); + isl_int_set_si(graph->lp->eq[k][0], -n_edge); + isl_int_set_si(graph->lp->eq[k][1], 1); + for (i = 0; i < n_edge; ++i) + isl_int_set_si(graph->lp->eq[k][4 + i], 1); + + if (add_param_sum_constraint(graph, 1) < 0) + return isl_stat_error; + if (add_var_sum_constraint(graph, 2) < 0) + return isl_stat_error; + + for (i = 0; i < n_edge; ++i) { + k = isl_basic_set_alloc_inequality(graph->lp); + if (k < 0) + return isl_stat_error; + isl_seq_clr(graph->lp->ineq[k], 1 + total); + isl_int_set_si(graph->lp->ineq[k][4 + i], -1); + isl_int_set_si(graph->lp->ineq[k][0], 1); + } + + if (add_all_constraints(ctx, graph, intra, inter, carry_inter) < 0) + return isl_stat_error; + + return isl_stat_ok; +} + +static __isl_give isl_schedule_node *compute_component_schedule( + __isl_take isl_schedule_node *node, struct isl_sched_graph *graph, + int wcc); + +/* If the schedule_split_scaled option is set and if the linear + * parts of the scheduling rows for all nodes in the graphs have + * a non-trivial common divisor, then remove this + * common divisor from the linear part. + * Otherwise, insert a band node directly and continue with + * the construction of the schedule. + * + * If a non-trivial common divisor is found, then + * the linear part is reduced and the remainder is ignored. + * The pieces of the graph that are assigned different remainders + * form (groups of) strongly connected components within + * the scaled down band. If needed, they can therefore + * be ordered along this remainder in a sequence node. + * However, this ordering is not enforced here in order to allow + * the scheduler to combine some of the strongly connected components. + */ +static __isl_give isl_schedule_node *split_scaled( + __isl_take isl_schedule_node *node, struct isl_sched_graph *graph) +{ + int i; + int row; + isl_ctx *ctx; + isl_int gcd, gcd_i; + isl_size n_row; + + if (!node) + return NULL; + + ctx = isl_schedule_node_get_ctx(node); + if (!ctx->opt->schedule_split_scaled) + return compute_next_band(node, graph, 0); + if (graph->n <= 1) + return compute_next_band(node, graph, 0); + n_row = isl_mat_rows(graph->node[0].sched); + if (n_row < 0) + return isl_schedule_node_free(node); + + isl_int_init(gcd); + isl_int_init(gcd_i); + + isl_int_set_si(gcd, 0); + + row = n_row - 1; + + for (i = 0; i < graph->n; ++i) { + struct isl_sched_node *node = &graph->node[i]; + isl_size cols = isl_mat_cols(node->sched); + + if (cols < 0) + break; + isl_seq_gcd(node->sched->row[row] + 1, cols - 1, &gcd_i); + isl_int_gcd(gcd, gcd, gcd_i); + } + + isl_int_clear(gcd_i); + if (i < graph->n) + goto error; + + if (isl_int_cmp_si(gcd, 1) <= 0) { + isl_int_clear(gcd); + return compute_next_band(node, graph, 0); + } + + for (i = 0; i < graph->n; ++i) { + struct isl_sched_node *node = &graph->node[i]; + + isl_int_fdiv_q(node->sched->row[row][0], + node->sched->row[row][0], gcd); + isl_int_mul(node->sched->row[row][0], + node->sched->row[row][0], gcd); + node->sched = isl_mat_scale_down_row(node->sched, row, gcd); + if (!node->sched) + goto error; + } + + isl_int_clear(gcd); + + return compute_next_band(node, graph, 0); +error: + isl_int_clear(gcd); + return isl_schedule_node_free(node); +} + +/* Is the schedule row "sol" trivial on node "node"? + * That is, is the solution zero on the dimensions linearly independent of + * the previously found solutions? + * Return 1 if the solution is trivial, 0 if it is not and -1 on error. + * + * Each coefficient is represented as the difference between + * two non-negative values in "sol". + * We construct the schedule row s and check if it is linearly + * independent of previously computed schedule rows + * by computing T s, with T the linear combinations that are zero + * on linearly dependent schedule rows. + * If the result consists of all zeros, then the solution is trivial. + */ +static int is_trivial(struct isl_sched_node *node, __isl_keep isl_vec *sol) +{ + int trivial; + isl_vec *node_sol; + + if (!sol) + return -1; + if (node->nvar == node->rank) + return 0; + + node_sol = extract_var_coef(node, sol); + node_sol = isl_mat_vec_product(isl_mat_copy(node->indep), node_sol); + if (!node_sol) + return -1; + + trivial = isl_seq_first_non_zero(node_sol->el, + node->nvar - node->rank) == -1; + + isl_vec_free(node_sol); + + return trivial; +} + +/* Is the schedule row "sol" trivial on any node where it should + * not be trivial? + * Return 1 if any solution is trivial, 0 if they are not and -1 on error. + */ +static int is_any_trivial(struct isl_sched_graph *graph, + __isl_keep isl_vec *sol) +{ + int i; + + for (i = 0; i < graph->n; ++i) { + struct isl_sched_node *node = &graph->node[i]; + int trivial; + + if (!needs_row(graph, node)) + continue; + trivial = is_trivial(node, sol); + if (trivial < 0 || trivial) + return trivial; + } + + return 0; +} + +/* Does the schedule represented by "sol" perform loop coalescing on "node"? + * If so, return the position of the coalesced dimension. + * Otherwise, return node->nvar or -1 on error. + * + * In particular, look for pairs of coefficients c_i and c_j such that + * |c_j/c_i| > ceil(size_i/2), i.e., |c_j| > |c_i * ceil(size_i/2)|. + * If any such pair is found, then return i. + * If size_i is infinity, then no check on c_i needs to be performed. + */ +static int find_node_coalescing(struct isl_sched_node *node, + __isl_keep isl_vec *sol) +{ + int i, j; + isl_int max; + isl_vec *csol; + + if (node->nvar <= 1) + return node->nvar; + + csol = extract_var_coef(node, sol); + if (!csol) + return -1; + isl_int_init(max); + for (i = 0; i < node->nvar; ++i) { + isl_val *v; + + if (isl_int_is_zero(csol->el[i])) + continue; + v = isl_multi_val_get_val(node->sizes, i); + if (!v) + goto error; + if (!isl_val_is_int(v)) { + isl_val_free(v); + continue; + } + v = isl_val_div_ui(v, 2); + v = isl_val_ceil(v); + if (!v) + goto error; + isl_int_mul(max, v->n, csol->el[i]); + isl_val_free(v); + + for (j = 0; j < node->nvar; ++j) { + if (j == i) + continue; + if (isl_int_abs_gt(csol->el[j], max)) + break; + } + if (j < node->nvar) + break; + } + + isl_int_clear(max); + isl_vec_free(csol); + return i; +error: + isl_int_clear(max); + isl_vec_free(csol); + return -1; +} + +/* Force the schedule coefficient at position "pos" of "node" to be zero + * in "tl". + * The coefficient is encoded as the difference between two non-negative + * variables. Force these two variables to have the same value. + */ +static __isl_give isl_tab_lexmin *zero_out_node_coef( + __isl_take isl_tab_lexmin *tl, struct isl_sched_node *node, int pos) +{ + int dim; + isl_ctx *ctx; + isl_vec *eq; + + ctx = isl_space_get_ctx(node->space); + dim = isl_tab_lexmin_dim(tl); + if (dim < 0) + return isl_tab_lexmin_free(tl); + eq = isl_vec_alloc(ctx, 1 + dim); + eq = isl_vec_clr(eq); + if (!eq) + return isl_tab_lexmin_free(tl); + + pos = 1 + node_var_coef_pos(node, pos); + isl_int_set_si(eq->el[pos], 1); + isl_int_set_si(eq->el[pos + 1], -1); + tl = isl_tab_lexmin_add_eq(tl, eq->el); + isl_vec_free(eq); + + return tl; +} + +/* Return the lexicographically smallest rational point in the basic set + * from which "tl" was constructed, double checking that this input set + * was not empty. + */ +static __isl_give isl_vec *non_empty_solution(__isl_keep isl_tab_lexmin *tl) +{ + isl_vec *sol; + + sol = isl_tab_lexmin_get_solution(tl); + if (!sol) + return NULL; + if (sol->size == 0) + isl_die(isl_vec_get_ctx(sol), isl_error_internal, + "error in schedule construction", + return isl_vec_free(sol)); + return sol; +} + +/* Does the solution "sol" of the LP problem constructed by setup_carry_lp + * carry any of the "n_edge" groups of dependences? + * The value in the first position is the sum of (1 - e_i) over all "n_edge" + * edges, with 0 <= e_i <= 1 equal to 1 when the dependences represented + * by the edge are carried by the solution. + * If the sum of the (1 - e_i) is smaller than "n_edge" then at least + * one of those is carried. + * + * Note that despite the fact that the problem is solved using a rational + * solver, the solution is guaranteed to be integral. + * Specifically, the dependence distance lower bounds e_i (and therefore + * also their sum) are integers. See Lemma 5 of [1]. + * + * Any potential denominator of the sum is cleared by this function. + * The denominator is not relevant for any of the other elements + * in the solution. + * + * [1] P. Feautrier, Some Efficient Solutions to the Affine Scheduling + * Problem, Part II: Multi-Dimensional Time. + * In Intl. Journal of Parallel Programming, 1992. + */ +static int carries_dependences(__isl_keep isl_vec *sol, int n_edge) +{ + isl_int_divexact(sol->el[1], sol->el[1], sol->el[0]); + isl_int_set_si(sol->el[0], 1); + return isl_int_cmp_si(sol->el[1], n_edge) < 0; +} + +/* Return the lexicographically smallest rational point in "lp", + * assuming that all variables are non-negative and performing some + * additional sanity checks. + * If "want_integral" is set, then compute the lexicographically smallest + * integer point instead. + * In particular, "lp" should not be empty by construction. + * Double check that this is the case. + * If dependences are not carried for any of the "n_edge" edges, + * then return an empty vector. + * + * If the schedule_treat_coalescing option is set and + * if the computed schedule performs loop coalescing on a given node, + * i.e., if it is of the form + * + * c_i i + c_j j + ... + * + * with |c_j/c_i| >= size_i, then force the coefficient c_i to be zero + * to cut out this solution. Repeat this process until no more loop + * coalescing occurs or until no more dependences can be carried. + * In the latter case, revert to the previously computed solution. + * + * If the caller requests an integral solution and if coalescing should + * be treated, then perform the coalescing treatment first as + * an integral solution computed before coalescing treatment + * would carry the same number of edges and would therefore probably + * also be coalescing. + * + * To allow the coalescing treatment to be performed first, + * the initial solution is allowed to be rational and it is only + * cut out (if needed) in the next iteration, if no coalescing measures + * were taken. + */ +static __isl_give isl_vec *non_neg_lexmin(struct isl_sched_graph *graph, + __isl_take isl_basic_set *lp, int n_edge, int want_integral) +{ + int i, pos, cut; + isl_ctx *ctx; + isl_tab_lexmin *tl; + isl_vec *sol = NULL, *prev; + int treat_coalescing; + int try_again; + + if (!lp) + return NULL; + ctx = isl_basic_set_get_ctx(lp); + treat_coalescing = isl_options_get_schedule_treat_coalescing(ctx); + tl = isl_tab_lexmin_from_basic_set(lp); + + cut = 0; + 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; + + integral = isl_int_is_one(sol->el[0]); + if (!carries_dependences(sol, n_edge)) { + if (!prev) + prev = isl_vec_alloc(ctx, 0); + isl_vec_free(sol); + sol = prev; + break; + } + prev = isl_vec_free(prev); + cut = want_integral && !integral; + if (cut) + try_again = 1; + if (!treat_coalescing) + continue; + for (i = 0; i < graph->n; ++i) { + struct isl_sched_node *node = &graph->node[i]; + + pos = find_node_coalescing(node, sol); + if (pos < 0) + goto error; + if (pos < node->nvar) + break; + } + if (i < graph->n) { + try_again = 1; + tl = zero_out_node_coef(tl, &graph->node[i], pos); + cut = 0; + } + } while (try_again); + + isl_tab_lexmin_free(tl); + + return sol; +error: + isl_tab_lexmin_free(tl); + isl_vec_free(prev); + isl_vec_free(sol); + return NULL; +} + +/* If "edge" is an edge from a node to itself, then add the corresponding + * dependence relation to "umap". + * If "node" has been compressed, then the dependence relation + * is also compressed first. + */ +static __isl_give isl_union_map *add_intra(__isl_take isl_union_map *umap, + struct isl_sched_edge *edge) +{ + isl_map *map; + struct isl_sched_node *node = edge->src; + + if (edge->src != edge->dst) + return umap; + + map = isl_map_copy(edge->map); + map = compress(map, node, node); + umap = isl_union_map_add_map(umap, map); + return umap; +} + +/* If "edge" is an edge from a node to another node, then add the corresponding + * dependence relation to "umap". + * If the source or destination nodes of "edge" have been compressed, + * then the dependence relation is also compressed first. + */ +static __isl_give isl_union_map *add_inter(__isl_take isl_union_map *umap, + struct isl_sched_edge *edge) +{ + isl_map *map; + + if (edge->src == edge->dst) + return umap; + + map = isl_map_copy(edge->map); + map = compress(map, edge->src, edge->dst); + umap = isl_union_map_add_map(umap, map); + return umap; +} + +/* Internal data structure used by union_drop_coalescing_constraints + * to collect bounds on all relevant statements. + * + * "graph" is the schedule constraint graph for which an LP problem + * is being constructed. + * "bounds" collects the bounds. + */ +struct isl_collect_bounds_data { + isl_ctx *ctx; + struct isl_sched_graph *graph; + isl_union_set *bounds; +}; + +/* Add the size bounds for the node with instance deltas in "set" + * to data->bounds. + */ +static isl_stat collect_bounds(__isl_take isl_set *set, void *user) +{ + struct isl_collect_bounds_data *data = user; + struct isl_sched_node *node; + isl_space *space; + isl_set *bounds; + + space = isl_set_get_space(set); + isl_set_free(set); + + node = graph_find_compressed_node(data->ctx, data->graph, space); + isl_space_free(space); + + bounds = isl_set_from_basic_set(get_size_bounds(node)); + data->bounds = isl_union_set_add_set(data->bounds, bounds); + + return isl_stat_ok; +} + +/* Drop some constraints from "delta" that could be exploited + * to construct loop coalescing schedules. + * In particular, drop those constraint that bound the difference + * to the size of the domain. + * Do this for each set/node in "delta" separately. + * The parameters are assumed to have been projected out by the caller. + */ +static __isl_give isl_union_set *union_drop_coalescing_constraints(isl_ctx *ctx, + struct isl_sched_graph *graph, __isl_take isl_union_set *delta) +{ + struct isl_collect_bounds_data data = { ctx, graph }; + + data.bounds = isl_union_set_empty(isl_space_params_alloc(ctx, 0)); + if (isl_union_set_foreach_set(delta, &collect_bounds, &data) < 0) + data.bounds = isl_union_set_free(data.bounds); + delta = isl_union_set_plain_gist(delta, data.bounds); + + return delta; +} + +/* Given a non-trivial lineality space "lineality", add the corresponding + * universe set to data->mask and add a map from elements to + * other elements along the lines in "lineality" to data->equivalent. + * If this is the first time this function gets called + * (data->any_non_trivial is still false), then set data->any_non_trivial and + * initialize data->mask and data->equivalent. + * + * In particular, if the lineality space is defined by equality constraints + * + * E x = 0 + * + * then construct an affine mapping + * + * f : x -> E x + * + * and compute the equivalence relation of having the same image under f: + * + * { x -> x' : E x = E x' } + */ +static isl_stat add_non_trivial_lineality(__isl_take isl_basic_set *lineality, + struct isl_exploit_lineality_data *data) +{ + isl_mat *eq; + isl_space *space; + isl_set *univ; + isl_multi_aff *ma; + isl_multi_pw_aff *mpa; + isl_map *map; + isl_size n; + + if (isl_basic_set_check_no_locals(lineality) < 0) + goto error; + + space = isl_basic_set_get_space(lineality); + if (!data->any_non_trivial) { + data->equivalent = isl_union_map_empty(isl_space_copy(space)); + data->mask = isl_union_set_empty(isl_space_copy(space)); + } + data->any_non_trivial = isl_bool_true; + + univ = isl_set_universe(isl_space_copy(space)); + data->mask = isl_union_set_add_set(data->mask, univ); + + eq = isl_basic_set_extract_equalities(lineality); + n = isl_mat_rows(eq); + if (n < 0) + space = isl_space_free(space); + eq = isl_mat_insert_zero_rows(eq, 0, 1); + eq = isl_mat_set_element_si(eq, 0, 0, 1); + space = isl_space_from_domain(space); + space = isl_space_add_dims(space, isl_dim_out, n); + ma = isl_multi_aff_from_aff_mat(space, eq); + mpa = isl_multi_pw_aff_from_multi_aff(ma); + map = isl_multi_pw_aff_eq_map(mpa, isl_multi_pw_aff_copy(mpa)); + data->equivalent = isl_union_map_add_map(data->equivalent, map); + + isl_basic_set_free(lineality); + return isl_stat_ok; +error: + isl_basic_set_free(lineality); + return isl_stat_error; +} + +/* Check if the lineality space "set" is non-trivial (i.e., is not just + * the origin or, in other words, satisfies a number of equality constraints + * that is smaller than the dimension of the set). + * If so, extend data->mask and data->equivalent accordingly. + * + * The input should not have any local variables already, but + * isl_set_remove_divs is called to make sure it does not. + */ +static isl_stat add_lineality(__isl_take isl_set *set, void *user) +{ + struct isl_exploit_lineality_data *data = user; + isl_basic_set *hull; + isl_size dim; + isl_size n_eq; + + set = isl_set_remove_divs(set); + hull = isl_set_unshifted_simple_hull(set); + dim = isl_basic_set_dim(hull, isl_dim_set); + n_eq = isl_basic_set_n_equality(hull); + if (dim < 0 || n_eq < 0) + goto error; + if (dim != n_eq) + return add_non_trivial_lineality(hull, data); + isl_basic_set_free(hull); + return isl_stat_ok; +error: + isl_basic_set_free(hull); + return isl_stat_error; +} + +/* Check if the difference set on intra-node schedule constraints "intra" + * has any non-trivial lineality space. + * If so, then extend the difference set to a difference set + * on equivalent elements. That is, if "intra" is + * + * { y - x : (x,y) \in V } + * + * and elements are equivalent if they have the same image under f, + * then return + * + * { y' - x' : (x,y) \in V and f(x) = f(x') and f(y) = f(y') } + * + * or, since f is linear, + * + * { y' - x' : (x,y) \in V and f(y - x) = f(y' - x') } + * + * The results of the search for non-trivial lineality spaces is stored + * in "data". + */ +static __isl_give isl_union_set *exploit_intra_lineality( + __isl_take isl_union_set *intra, + struct isl_exploit_lineality_data *data) +{ + isl_union_set *lineality; + isl_union_set *uset; + + data->any_non_trivial = isl_bool_false; + lineality = isl_union_set_copy(intra); + lineality = isl_union_set_combined_lineality_space(lineality); + if (isl_union_set_foreach_set(lineality, &add_lineality, data) < 0) + data->any_non_trivial = isl_bool_error; + isl_union_set_free(lineality); + + if (data->any_non_trivial < 0) + return isl_union_set_free(intra); + if (!data->any_non_trivial) + return intra; + + uset = isl_union_set_copy(intra); + intra = isl_union_set_subtract(intra, isl_union_set_copy(data->mask)); + uset = isl_union_set_apply(uset, isl_union_map_copy(data->equivalent)); + intra = isl_union_set_union(intra, uset); + + intra = isl_union_set_remove_divs(intra); + + return intra; +} + +/* If the difference set on intra-node schedule constraints was found to have + * any non-trivial lineality space by exploit_intra_lineality, + * as recorded in "data", then extend the inter-node + * schedule constraints "inter" to schedule constraints on equivalent elements. + * That is, if "inter" is V and + * elements are equivalent if they have the same image under f, then return + * + * { (x', y') : (x,y) \in V and f(x) = f(x') and f(y) = f(y') } + */ +static __isl_give isl_union_map *exploit_inter_lineality( + __isl_take isl_union_map *inter, + struct isl_exploit_lineality_data *data) +{ + isl_union_map *umap; + + if (data->any_non_trivial < 0) + return isl_union_map_free(inter); + if (!data->any_non_trivial) + return inter; + + umap = isl_union_map_copy(inter); + inter = isl_union_map_subtract_range(inter, + isl_union_set_copy(data->mask)); + umap = isl_union_map_apply_range(umap, + isl_union_map_copy(data->equivalent)); + inter = isl_union_map_union(inter, umap); + umap = isl_union_map_copy(inter); + inter = isl_union_map_subtract_domain(inter, + isl_union_set_copy(data->mask)); + umap = isl_union_map_apply_range(isl_union_map_copy(data->equivalent), + umap); + inter = isl_union_map_union(inter, umap); + + inter = isl_union_map_remove_divs(inter); + + return inter; +} + +/* For each (conditional) validity edge in "graph", + * add the corresponding dependence relation using "add" + * to a collection of dependence relations and return the result. + * If "coincidence" is set, then coincidence edges are considered as well. + */ +static __isl_give isl_union_map *collect_validity(struct isl_sched_graph *graph, + __isl_give isl_union_map *(*add)(__isl_take isl_union_map *umap, + struct isl_sched_edge *edge), int coincidence) +{ + int i; + isl_space *space; + isl_union_map *umap; + + space = isl_space_copy(graph->node[0].space); + umap = isl_union_map_empty(space); + + for (i = 0; i < graph->n_edge; ++i) { + struct isl_sched_edge *edge = &graph->edge[i]; + + if (!is_any_validity(edge) && + (!coincidence || !is_coincidence(edge))) + continue; + + umap = add(umap, edge); + } + + return umap; +} + +/* For each dependence relation on a (conditional) validity edge + * from a node to itself, + * construct the set of coefficients of valid constraints for elements + * in that dependence relation and collect the results. + * If "coincidence" is set, then coincidence edges are considered as well. + * + * In particular, for each dependence relation R, constraints + * on coefficients (c_0, c_x) are constructed such that + * + * c_0 + c_x d >= 0 for each d in delta R = { y - x | (x,y) in R } + * + * If the schedule_treat_coalescing option is set, then some constraints + * that could be exploited to construct coalescing schedules + * are removed before the dual is computed, but after the parameters + * have been projected out. + * The entire computation is essentially the same as that performed + * by intra_coefficients, except that it operates on multiple + * edges together and that the parameters are always projected out. + * + * Additionally, exploit any non-trivial lineality space + * in the difference set after removing coalescing constraints and + * store the results of the non-trivial lineality space detection in "data". + * The procedure is currently run unconditionally, but it is unlikely + * to find any non-trivial lineality spaces if no coalescing constraints + * have been removed. + * + * Note that if a dependence relation is a union of basic maps, + * then each basic map needs to be treated individually as it may only + * be possible to carry the dependences expressed by some of those + * basic maps and not all of them. + * The collected validity constraints are therefore not coalesced and + * it is assumed that they are not coalesced automatically. + * Duplicate basic maps can be removed, however. + * In particular, if the same basic map appears as a disjunct + * in multiple edges, then it only needs to be carried once. + */ +static __isl_give isl_basic_set_list *collect_intra_validity(isl_ctx *ctx, + struct isl_sched_graph *graph, int coincidence, + struct isl_exploit_lineality_data *data) +{ + isl_union_map *intra; + isl_union_set *delta; + isl_basic_set_list *list; + + intra = collect_validity(graph, &add_intra, coincidence); + delta = isl_union_map_deltas(intra); + delta = isl_union_set_project_out_all_params(delta); + delta = isl_union_set_remove_divs(delta); + if (isl_options_get_schedule_treat_coalescing(ctx)) + delta = union_drop_coalescing_constraints(ctx, graph, delta); + delta = exploit_intra_lineality(delta, data); + list = isl_union_set_get_basic_set_list(delta); + isl_union_set_free(delta); + + return isl_basic_set_list_coefficients(list); +} + +/* For each dependence relation on a (conditional) validity edge + * from a node to some other node, + * construct the set of coefficients of valid constraints for elements + * in that dependence relation and collect the results. + * If "coincidence" is set, then coincidence edges are considered as well. + * + * In particular, for each dependence relation R, constraints + * on coefficients (c_0, c_n, c_x, c_y) are constructed such that + * + * c_0 + c_n n + c_x x + c_y y >= 0 for each (x,y) in R + * + * This computation is essentially the same as that performed + * by inter_coefficients, except that it operates on multiple + * edges together. + * + * Additionally, exploit any non-trivial lineality space + * that may have been discovered by collect_intra_validity + * (as stored in "data"). + * + * Note that if a dependence relation is a union of basic maps, + * then each basic map needs to be treated individually as it may only + * be possible to carry the dependences expressed by some of those + * basic maps and not all of them. + * The collected validity constraints are therefore not coalesced and + * it is assumed that they are not coalesced automatically. + * Duplicate basic maps can be removed, however. + * In particular, if the same basic map appears as a disjunct + * in multiple edges, then it only needs to be carried once. + */ +static __isl_give isl_basic_set_list *collect_inter_validity( + struct isl_sched_graph *graph, int coincidence, + struct isl_exploit_lineality_data *data) +{ + isl_union_map *inter; + isl_union_set *wrap; + isl_basic_set_list *list; + + inter = collect_validity(graph, &add_inter, coincidence); + inter = exploit_inter_lineality(inter, data); + inter = isl_union_map_remove_divs(inter); + wrap = isl_union_map_wrap(inter); + list = isl_union_set_get_basic_set_list(wrap); + isl_union_set_free(wrap); + return isl_basic_set_list_coefficients(list); +} + +/* Construct an LP problem for finding schedule coefficients + * such that the schedule carries as many of the "n_edge" groups of + * dependences as possible based on the corresponding coefficient + * constraints and return the lexicographically smallest non-trivial solution. + * "intra" is the sequence of coefficient constraints for intra-node edges. + * "inter" is the sequence of coefficient constraints for inter-node edges. + * If "want_integral" is set, then compute an integral solution + * for the coefficients rather than using the numerators + * of a rational solution. + * "carry_inter" indicates whether inter-node edges should be carried or + * only respected. + * + * If none of the "n_edge" groups can be carried + * then return an empty vector. + */ +static __isl_give isl_vec *compute_carrying_sol_coef(isl_ctx *ctx, + struct isl_sched_graph *graph, int n_edge, + __isl_keep isl_basic_set_list *intra, + __isl_keep isl_basic_set_list *inter, int want_integral, + int carry_inter) +{ + isl_basic_set *lp; + + if (setup_carry_lp(ctx, graph, n_edge, intra, inter, carry_inter) < 0) + return NULL; + + lp = isl_basic_set_copy(graph->lp); + return non_neg_lexmin(graph, lp, n_edge, want_integral); +} + +/* Construct an LP problem for finding schedule coefficients + * such that the schedule carries as many of the validity dependences + * as possible and + * return the lexicographically smallest non-trivial solution. + * If "fallback" is set, then the carrying is performed as a fallback + * for the Pluto-like scheduler. + * If "coincidence" is set, then try and carry coincidence edges as well. + * + * The variable "n_edge" stores the number of groups that should be carried. + * If none of the "n_edge" groups can be carried + * then return an empty vector. + * If, moreover, "n_edge" is zero, then the LP problem does not even + * need to be constructed. + * + * If a fallback solution is being computed, then compute an integral solution + * for the coefficients rather than using the numerators + * of a rational solution. + * + * If a fallback solution is being computed, if there are any intra-node + * dependences, and if requested by the user, then first try + * to only carry those intra-node dependences. + * If this fails to carry any dependences, then try again + * with the inter-node dependences included. + */ +static __isl_give isl_vec *compute_carrying_sol(isl_ctx *ctx, + struct isl_sched_graph *graph, int fallback, int coincidence) +{ + isl_size n_intra, n_inter; + int n_edge; + struct isl_carry carry = { 0 }; + isl_vec *sol; + + carry.intra = collect_intra_validity(ctx, graph, coincidence, + &carry.lineality); + carry.inter = collect_inter_validity(graph, coincidence, + &carry.lineality); + n_intra = isl_basic_set_list_n_basic_set(carry.intra); + n_inter = isl_basic_set_list_n_basic_set(carry.inter); + if (n_intra < 0 || n_inter < 0) + goto error; + + if (fallback && n_intra > 0 && + isl_options_get_schedule_carry_self_first(ctx)) { + sol = compute_carrying_sol_coef(ctx, graph, n_intra, + carry.intra, carry.inter, fallback, 0); + if (!sol || sol->size != 0 || n_inter == 0) { + isl_carry_clear(&carry); + return sol; + } + isl_vec_free(sol); + } + + n_edge = n_intra + n_inter; + if (n_edge == 0) { + isl_carry_clear(&carry); + return isl_vec_alloc(ctx, 0); + } + + sol = compute_carrying_sol_coef(ctx, graph, n_edge, + carry.intra, carry.inter, fallback, 1); + isl_carry_clear(&carry); + return sol; +error: + isl_carry_clear(&carry); + return NULL; +} + +/* Construct a schedule row for each node such that as many validity dependences + * as possible are carried and then continue with the next band. + * If "fallback" is set, then the carrying is performed as a fallback + * for the Pluto-like scheduler. + * If "coincidence" is set, then try and carry coincidence edges as well. + * + * If there are no validity dependences, then no dependence can be carried and + * the procedure is guaranteed to fail. If there is more than one component, + * then try computing a schedule on each component separately + * to prevent or at least postpone this failure. + * + * If a schedule row is computed, then check that dependences are carried + * for at least one of the edges. + * + * If the computed schedule row turns out to be trivial on one or + * more nodes where it should not be trivial, then we throw it away + * and try again on each component separately. + * + * If there is only one component, then we accept the schedule row anyway, + * but we do not consider it as a complete row and therefore do not + * increment graph->n_row. Note that the ranks of the nodes that + * do get a non-trivial schedule part will get updated regardless and + * graph->maxvar is computed based on these ranks. The test for + * whether more schedule rows are required in compute_schedule_wcc + * is therefore not affected. + * + * Insert a band corresponding to the schedule row at position "node" + * of the schedule tree and continue with the construction of the schedule. + * This insertion and the continued construction is performed by split_scaled + * after optionally checking for non-trivial common divisors. + */ +static __isl_give isl_schedule_node *carry(__isl_take isl_schedule_node *node, + struct isl_sched_graph *graph, int fallback, int coincidence) +{ + int trivial; + isl_ctx *ctx; + isl_vec *sol; + + if (!node) + return NULL; + + ctx = isl_schedule_node_get_ctx(node); + sol = compute_carrying_sol(ctx, graph, fallback, coincidence); + if (!sol) + return isl_schedule_node_free(node); + if (sol->size == 0) { + isl_vec_free(sol); + if (graph->scc > 1) + return compute_component_schedule(node, graph, 1); + isl_die(ctx, isl_error_unknown, "unable to carry dependences", + return isl_schedule_node_free(node)); + } + + trivial = is_any_trivial(graph, sol); + if (trivial < 0) { + sol = isl_vec_free(sol); + } else if (trivial && graph->scc > 1) { + isl_vec_free(sol); + return compute_component_schedule(node, graph, 1); + } + + if (update_schedule(graph, sol, 0) < 0) + return isl_schedule_node_free(node); + if (trivial) + graph->n_row--; + + return split_scaled(node, graph); +} + +/* Construct a schedule row for each node such that as many validity dependences + * as possible are carried and then continue with the next band. + * Do so as a fallback for the Pluto-like scheduler. + * If "coincidence" is set, then try and carry coincidence edges as well. + */ +static __isl_give isl_schedule_node *carry_fallback( + __isl_take isl_schedule_node *node, struct isl_sched_graph *graph, + int coincidence) +{ + return carry(node, graph, 1, coincidence); +} + +/* Construct a schedule row for each node such that as many validity dependences + * as possible are carried and then continue with the next band. + * Do so for the case where the Feautrier scheduler was selected + * by the user. + */ +static __isl_give isl_schedule_node *carry_feautrier( + __isl_take isl_schedule_node *node, struct isl_sched_graph *graph) +{ + return carry(node, graph, 0, 0); +} + +/* Construct a schedule row for each node such that as many validity dependences + * as possible are carried and then continue with the next band. + * Do so as a fallback for the Pluto-like scheduler. + */ +static __isl_give isl_schedule_node *carry_dependences( + __isl_take isl_schedule_node *node, struct isl_sched_graph *graph) +{ + return carry_fallback(node, graph, 0); +} + +/* Construct a schedule row for each node such that as many validity or + * coincidence dependences as possible are carried and + * then continue with the next band. + * Do so as a fallback for the Pluto-like scheduler. + */ +static __isl_give isl_schedule_node *carry_coincidence( + __isl_take isl_schedule_node *node, struct isl_sched_graph *graph) +{ + return carry_fallback(node, graph, 1); +} + +/* Topologically sort statements mapped to the same schedule iteration + * and add insert a sequence node in front of "node" + * corresponding to this order. + * If "initialized" is set, then it may be assumed that + * isl_sched_graph_compute_maxvar + * has been called on the current band. Otherwise, call + * isl_sched_graph_compute_maxvar if and before carry_dependences gets called. + * + * If it turns out to be impossible to sort the statements apart, + * because different dependences impose different orderings + * on the statements, then we extend the schedule such that + * it carries at least one more dependence. + */ +static __isl_give isl_schedule_node *sort_statements( + __isl_take isl_schedule_node *node, struct isl_sched_graph *graph, + int initialized) +{ + isl_ctx *ctx; + isl_union_set_list *filters; + + if (!node) + return NULL; + + ctx = isl_schedule_node_get_ctx(node); + if (graph->n < 1) + isl_die(ctx, isl_error_internal, + "graph should have at least one node", + return isl_schedule_node_free(node)); + + if (graph->n == 1) + return node; + + if (update_edges(ctx, graph) < 0) + return isl_schedule_node_free(node); + + if (graph->n_edge == 0) + return node; + + if (detect_sccs(ctx, graph) < 0) + return isl_schedule_node_free(node); + + next_band(graph); + if (graph->scc < graph->n) { + if (!initialized && isl_sched_graph_compute_maxvar(graph) < 0) + return isl_schedule_node_free(node); + return carry_dependences(node, graph); + } + + filters = isl_sched_graph_extract_sccs(ctx, graph); + node = isl_schedule_node_insert_sequence(node, filters); + + return node; +} + +/* Are there any (non-empty) (conditional) validity edges in the graph? + */ +static int has_validity_edges(struct isl_sched_graph *graph) +{ + int i; + + for (i = 0; i < graph->n_edge; ++i) { + int empty; + + empty = isl_map_plain_is_empty(graph->edge[i].map); + if (empty < 0) + return -1; + if (empty) + continue; + if (is_any_validity(&graph->edge[i])) + return 1; + } + + return 0; +} + +/* Should we apply a Feautrier step? + * That is, did the user request the Feautrier algorithm and are + * there any validity dependences (left)? + */ +static int need_feautrier_step(isl_ctx *ctx, struct isl_sched_graph *graph) +{ + if (ctx->opt->schedule_algorithm != ISL_SCHEDULE_ALGORITHM_FEAUTRIER) + return 0; + + return has_validity_edges(graph); +} + +/* Compute a schedule for a connected dependence graph using Feautrier's + * multi-dimensional scheduling algorithm and return the updated schedule node. + * + * The original algorithm is described in [1]. + * The main idea is to minimize the number of scheduling dimensions, by + * trying to satisfy as many dependences as possible per scheduling dimension. + * + * [1] P. Feautrier, Some Efficient Solutions to the Affine Scheduling + * Problem, Part II: Multi-Dimensional Time. + * In Intl. Journal of Parallel Programming, 1992. + */ +static __isl_give isl_schedule_node *compute_schedule_wcc_feautrier( + isl_schedule_node *node, struct isl_sched_graph *graph) +{ + return carry_feautrier(node, graph); +} + +/* Turn off the "local" bit on all (condition) edges. + */ +static void clear_local_edges(struct isl_sched_graph *graph) +{ + int i; + + for (i = 0; i < graph->n_edge; ++i) + if (isl_sched_edge_is_condition(&graph->edge[i])) + clear_local(&graph->edge[i]); +} + +/* Does "graph" have both condition and conditional validity edges? + */ +static int need_condition_check(struct isl_sched_graph *graph) +{ + int i; + int any_condition = 0; + int any_conditional_validity = 0; + + for (i = 0; i < graph->n_edge; ++i) { + if (isl_sched_edge_is_condition(&graph->edge[i])) + any_condition = 1; + if (isl_sched_edge_is_conditional_validity(&graph->edge[i])) + any_conditional_validity = 1; + } + + return any_condition && any_conditional_validity; +} + +/* Does "graph" contain any coincidence edge? + */ +static int has_any_coincidence(struct isl_sched_graph *graph) +{ + int i; + + for (i = 0; i < graph->n_edge; ++i) + if (is_coincidence(&graph->edge[i])) + return 1; + + return 0; +} + +/* Extract the final schedule row as a map with the iteration domain + * of "node" as domain. + */ +static __isl_give isl_map *final_row(struct isl_sched_node *node) +{ + isl_multi_aff *ma; + isl_size n_row; + + n_row = isl_mat_rows(node->sched); + if (n_row < 0) + return NULL; + ma = isl_sched_node_extract_partial_schedule_multi_aff(node, + n_row - 1, 1); + return isl_map_from_multi_aff(ma); +} + +/* Is the conditional validity dependence in the edge with index "edge_index" + * violated by the latest (i.e., final) row of the schedule? + * That is, is i scheduled after j + * for any conditional validity dependence i -> j? + */ +static int is_violated(struct isl_sched_graph *graph, int edge_index) +{ + isl_map *src_sched, *dst_sched, *map; + struct isl_sched_edge *edge = &graph->edge[edge_index]; + int empty; + + src_sched = final_row(edge->src); + dst_sched = final_row(edge->dst); + map = isl_map_copy(edge->map); + map = isl_map_apply_domain(map, src_sched); + map = isl_map_apply_range(map, dst_sched); + map = isl_map_order_gt(map, isl_dim_in, 0, isl_dim_out, 0); + empty = isl_map_is_empty(map); + isl_map_free(map); + + if (empty < 0) + return -1; + + return !empty; +} + +/* Does "graph" have any satisfied condition edges that + * are adjacent to the conditional validity constraint with + * domain "conditional_source" and range "conditional_sink"? + * + * A satisfied condition is one that is not local. + * If a condition was forced to be local already (i.e., marked as local) + * then there is no need to check if it is in fact local. + * + * Additionally, mark all adjacent condition edges found as local. + */ +static int has_adjacent_true_conditions(struct isl_sched_graph *graph, + __isl_keep isl_union_set *conditional_source, + __isl_keep isl_union_set *conditional_sink) +{ + int i; + int any = 0; + + for (i = 0; i < graph->n_edge; ++i) { + int adjacent, local; + isl_union_map *condition; + + if (!isl_sched_edge_is_condition(&graph->edge[i])) + continue; + if (is_local(&graph->edge[i])) + continue; + + condition = graph->edge[i].tagged_condition; + adjacent = domain_intersects(condition, conditional_sink); + if (adjacent >= 0 && !adjacent) + adjacent = range_intersects(condition, + conditional_source); + if (adjacent < 0) + return -1; + if (!adjacent) + continue; + + set_local(&graph->edge[i]); + + local = is_condition_false(&graph->edge[i]); + if (local < 0) + return -1; + if (!local) + any = 1; + } + + return any; +} + +/* Are there any violated conditional validity dependences with + * adjacent condition dependences that are not local with respect + * to the current schedule? + * That is, is the conditional validity constraint violated? + * + * Additionally, mark all those adjacent condition dependences as local. + * We also mark those adjacent condition dependences that were not marked + * as local before, but just happened to be local already. This ensures + * that they remain local if the schedule is recomputed. + * + * We first collect domain and range of all violated conditional validity + * dependences and then check if there are any adjacent non-local + * condition dependences. + */ +static int has_violated_conditional_constraint(isl_ctx *ctx, + struct isl_sched_graph *graph) +{ + int i; + int any = 0; + isl_union_set *source, *sink; + + source = isl_union_set_empty(isl_space_params_alloc(ctx, 0)); + sink = isl_union_set_empty(isl_space_params_alloc(ctx, 0)); + for (i = 0; i < graph->n_edge; ++i) { + isl_union_set *uset; + isl_union_map *umap; + int violated; + + if (!isl_sched_edge_is_conditional_validity(&graph->edge[i])) + continue; + + violated = is_violated(graph, i); + if (violated < 0) + goto error; + if (!violated) + continue; + + any = 1; + + umap = isl_union_map_copy(graph->edge[i].tagged_validity); + uset = isl_union_map_domain(umap); + source = isl_union_set_union(source, uset); + source = isl_union_set_coalesce(source); + + umap = isl_union_map_copy(graph->edge[i].tagged_validity); + uset = isl_union_map_range(umap); + sink = isl_union_set_union(sink, uset); + sink = isl_union_set_coalesce(sink); + } + + if (any) + any = has_adjacent_true_conditions(graph, source, sink); + + isl_union_set_free(source); + isl_union_set_free(sink); + return any; +error: + isl_union_set_free(source); + isl_union_set_free(sink); + return -1; +} + +/* Examine the current band (the rows between graph->band_start and + * graph->n_total_row), deciding whether to drop it or add it to "node" + * and then continue with the computation of the next band, if any. + * If "initialized" is set, then it may be assumed that + * isl_sched_graph_compute_maxvar + * has been called on the current band. Otherwise, call + * isl_sched_graph_compute_maxvar if and before carry_dependences gets called. + * + * The caller keeps looking for a new row as long as + * graph->n_row < graph->maxvar. If the latest attempt to find + * such a row failed (i.e., we still have graph->n_row < graph->maxvar), + * then we either + * - split between SCCs and start over (assuming we found an interesting + * pair of SCCs between which to split) + * - continue with the next band (assuming the current band has at least + * one row) + * - if there is more than one SCC left, then split along all SCCs + * - if outer coincidence needs to be enforced, then try to carry as many + * validity or coincidence dependences as possible and + * continue with the next band + * - try to carry as many validity dependences as possible and + * continue with the next band + * 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 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. + */ +__isl_give isl_schedule_node *isl_schedule_node_compute_finish_band( + __isl_take isl_schedule_node *node, struct isl_sched_graph *graph, + int initialized) +{ + int empty; + + if (!node) + return NULL; + + empty = graph->n_total_row == graph->band_start; + if (graph->n_row < graph->maxvar) { + isl_ctx *ctx; + + ctx = isl_schedule_node_get_ctx(node); + if (!ctx->opt->schedule_maximize_band_depth && !empty) + return compute_next_band(node, graph, 1); + if (graph->src_scc >= 0) + return compute_split_schedule(node, graph); + if (!empty) + return compute_next_band(node, graph, 1); + if (graph->scc > 1) + return compute_component_schedule(node, graph, 1); + if (!initialized && isl_sched_graph_compute_maxvar(graph) < 0) + return isl_schedule_node_free(node); + if (isl_options_get_schedule_outer_coincidence(ctx)) + return carry_coincidence(node, graph); + return carry_dependences(node, graph); + } + + 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. + * The caller is responsible for determining the strongly connected + * components and calling isl_sched_graph_compute_maxvar first. + * + * We try to find a sequence of as many schedule rows as possible that result + * in non-negative dependence distances (independent of the previous rows + * in the sequence, i.e., such that the sequence is tilable), with as + * many of the initial rows as possible satisfying the coincidence constraints. + * The computation stops if we can't find any more rows or if we have found + * all the rows we wanted to find. + * + * If ctx->opt->schedule_outer_coincidence is set, then we force the + * outermost dimension to satisfy the coincidence constraints. If this + * turns out to be impossible, we fall back on the general scheme above + * and try to carry as many dependences as possible. + * + * If "graph" contains both condition and conditional validity dependences, + * then we need to check that that the conditional schedule constraint + * is satisfied, i.e., there are no violated conditional validity dependences + * that are adjacent to any non-local condition dependences. + * If there are, then we mark all those adjacent condition dependences + * as local and recompute the current band. Those dependences that + * are marked local will then be forced to be local. + * The initial computation is performed with no dependences marked as local. + * If we are lucky, then there will be no violated conditional validity + * dependences adjacent to any non-local condition dependences. + * Otherwise, we mark some additional condition dependences as local and + * recompute. We continue this process until there are no violations left or + * until we are no longer able to compute a schedule. + * Since there are only a finite number of dependences, + * there will only be a finite number of iterations. + */ +isl_stat isl_schedule_node_compute_wcc_band(isl_ctx *ctx, + struct isl_sched_graph *graph) +{ + int has_coincidence; + int use_coincidence; + int force_coincidence = 0; + int check_conditional; + + if (sort_sccs(graph) < 0) + return isl_stat_error; + + clear_local_edges(graph); + check_conditional = need_condition_check(graph); + has_coincidence = has_any_coincidence(graph); + + if (ctx->opt->schedule_outer_coincidence) + force_coincidence = 1; + + use_coincidence = has_coincidence; + while (graph->n_row < graph->maxvar) { + isl_vec *sol; + int violated; + int coincident; + + graph->src_scc = -1; + graph->dst_scc = -1; + + if (setup_lp(ctx, graph, use_coincidence) < 0) + return isl_stat_error; + sol = solve_lp(ctx, graph); + if (!sol) + return isl_stat_error; + if (sol->size == 0) { + int empty = graph->n_total_row == graph->band_start; + + isl_vec_free(sol); + if (use_coincidence && (!force_coincidence || !empty)) { + use_coincidence = 0; + continue; + } + return isl_stat_ok; + } + coincident = !has_coincidence || use_coincidence; + if (update_schedule(graph, sol, coincident) < 0) + return isl_stat_error; + + if (!check_conditional) + continue; + violated = has_violated_conditional_constraint(ctx, graph); + if (violated < 0) + return isl_stat_error; + if (!violated) + continue; + if (reset_band(graph) < 0) + return isl_stat_error; + use_coincidence = has_coincidence; + } + + return isl_stat_ok; +} + +/* Compute a schedule for a connected dependence graph by considering + * the graph as a whole and return the updated schedule node. + * + * The actual schedule rows of the current band are computed by + * isl_schedule_node_compute_wcc_band. isl_schedule_node_compute_finish_band + * takes care of integrating the band into "node" and continuing + * the computation. + */ +static __isl_give isl_schedule_node *compute_schedule_wcc_whole( + __isl_take isl_schedule_node *node, struct isl_sched_graph *graph) +{ + isl_ctx *ctx; + + if (!node) + return NULL; + + ctx = isl_schedule_node_get_ctx(node); + if (isl_schedule_node_compute_wcc_band(ctx, graph) < 0) + return isl_schedule_node_free(node); + + return isl_schedule_node_compute_finish_band(node, graph, 1); +} + +/* Compute a schedule for a connected dependence graph and return + * the updated schedule node. + * + * If Feautrier's algorithm is selected, we first recursively try to satisfy + * as many validity dependences as possible. When all validity dependences + * are satisfied we extend the schedule to a full-dimensional schedule. + * + * Call compute_schedule_wcc_whole or isl_schedule_node_compute_wcc_clustering + * depending on whether the user has selected the option to try and + * compute a schedule for the entire (weakly connected) component first. + * If there is only a single strongly connected component (SCC), then + * there is no point in trying to combine SCCs + * in isl_schedule_node_compute_wcc_clustering, so compute_schedule_wcc_whole + * is called instead. + */ +static __isl_give isl_schedule_node *compute_schedule_wcc( + __isl_take isl_schedule_node *node, struct isl_sched_graph *graph) +{ + isl_ctx *ctx; + + if (!node) + return NULL; + + ctx = isl_schedule_node_get_ctx(node); + if (detect_sccs(ctx, graph) < 0) + return isl_schedule_node_free(node); + + if (isl_sched_graph_compute_maxvar(graph) < 0) + return isl_schedule_node_free(node); + + if (need_feautrier_step(ctx, graph)) + return compute_schedule_wcc_feautrier(node, graph); + + if (graph->scc <= 1 || isl_options_get_schedule_whole_component(ctx)) + return compute_schedule_wcc_whole(node, graph); + else + return isl_schedule_node_compute_wcc_clustering(node, graph); +} + +/* Compute a schedule for each group of nodes identified by node->scc + * separately and then combine them in a sequence node (or as set node + * if graph->weak is set) inserted at position "node" of the schedule tree. + * Return the updated schedule node. + * + * If "wcc" is set then each of the groups belongs to a single + * 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, + int wcc) +{ + int component; + isl_ctx *ctx; + isl_union_set_list *filters; + + if (!node) + return NULL; + + if (graph->weak && graph->scc == graph->n) { + if (isl_sched_graph_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 = isl_sched_graph_extract_sccs(ctx, graph); + if (graph->weak) + node = isl_schedule_node_insert_set(node, filters); + else + node = isl_schedule_node_insert_sequence(node, filters); + + for (component = 0; component < graph->scc; ++component) { + node = isl_schedule_node_grandchild(node, component, 0); + node = compute_sub_schedule(node, ctx, graph, + &isl_sched_node_scc_exactly, + &isl_sched_edge_scc_exactly, + component, wcc); + node = isl_schedule_node_grandparent(node); + } + + return node; +} + +/* Compute a schedule for the given dependence graph and insert it at "node". + * Return the updated schedule node. + * + * We first check if the graph is connected (through validity and conditional + * validity dependences) and, if not, compute a schedule + * for each component separately. + * If the schedule_serialize_sccs option is set, then we check for strongly + * connected components instead and compute a separate schedule for + * each such strongly connected component. + */ +static __isl_give isl_schedule_node *compute_schedule(isl_schedule_node *node, + struct isl_sched_graph *graph) +{ + isl_ctx *ctx; + + if (!node) + return NULL; + + ctx = isl_schedule_node_get_ctx(node); + if (isl_options_get_schedule_serialize_sccs(ctx)) { + if (detect_sccs(ctx, graph) < 0) + return isl_schedule_node_free(node); + } else { + if (detect_wccs(ctx, graph) < 0) + return isl_schedule_node_free(node); + } + + if (graph->scc > 1) + return compute_component_schedule(node, graph, 1); + + return compute_schedule_wcc(node, graph); +} + +/* Compute a schedule on sc->domain that respects the given schedule + * constraints. + * + * In particular, the schedule respects all the validity dependences. + * If the default isl scheduling algorithm is used, it tries to minimize + * the dependence distances over the proximity dependences. + * If Feautrier's scheduling algorithm is used, the proximity dependence + * distances are only minimized during the extension to a full-dimensional + * schedule. + * + * If there are any condition and conditional validity dependences, + * then the conditional validity dependences may be violated inside + * a tilable band, provided they have no adjacent non-local + * condition dependences. + */ +__isl_give isl_schedule *isl_schedule_constraints_compute_schedule( + __isl_take isl_schedule_constraints *sc) +{ + isl_ctx *ctx = isl_schedule_constraints_get_ctx(sc); + struct isl_sched_graph graph = { 0 }; + isl_schedule *sched; + isl_schedule_node *node; + isl_union_set *domain; + isl_size n; + + sc = isl_schedule_constraints_align_params(sc); + + domain = isl_schedule_constraints_get_domain(sc); + n = isl_union_set_n_set(domain); + if (n == 0) { + isl_schedule_constraints_free(sc); + return isl_schedule_from_domain(domain); + } + + if (n < 0 || isl_sched_graph_init(&graph, sc) < 0) + domain = isl_union_set_free(domain); + + node = isl_schedule_node_from_domain(domain); + node = isl_schedule_node_child(node, 0); + if (graph.n > 0) + node = compute_schedule(node, &graph); + sched = isl_schedule_node_get_schedule(node); + isl_schedule_node_free(node); + + isl_sched_graph_free(ctx, &graph); + isl_schedule_constraints_free(sc); + + return sched; +} + +/* Compute a schedule for the given union of domains that respects + * all the validity dependences and minimizes + * the dependence distances over the proximity dependences. + * + * This function is kept for backward compatibility. + */ +__isl_give isl_schedule *isl_union_set_compute_schedule( + __isl_take isl_union_set *domain, + __isl_take isl_union_map *validity, + __isl_take isl_union_map *proximity) +{ + isl_schedule_constraints *sc; + + sc = isl_schedule_constraints_on_domain(domain); + sc = isl_schedule_constraints_set_validity(sc, validity); + sc = isl_schedule_constraints_set_proximity(sc, proximity); + + return isl_schedule_constraints_compute_schedule(sc); +} diff --git a/external/mit/isl/dist/isl_scheduler.h b/external/mit/isl/dist/isl_scheduler.h new file mode 100644 index 000000000000..d5d68e484c48 --- /dev/null +++ b/external/mit/isl/dist/isl_scheduler.h @@ -0,0 +1,289 @@ +#ifndef ISL_SCHEDULER_H +#define ISL_SCHEDULER_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "isl_schedule_constraints.h" +#include "isl_tab.h" + +/* Internal information about a node that is used during the construction + * of a schedule. + * space represents the original space in which the domain lives; + * that is, the space is not affected by compression + * sched is a matrix representation of the schedule being constructed + * for this node; if compressed is set, then this schedule is + * defined over the compressed domain space + * sched_map is an isl_map representation of the same (partial) schedule + * sched_map may be NULL; if compressed is set, then this map + * is defined over the uncompressed domain space + * rank is the number of linearly independent rows in the linear part + * of sched + * the rows of "vmap" represent a change of basis for the node + * variables; the first rank rows span the linear part of + * the schedule rows; the remaining rows are linearly independent + * the rows of "indep" represent linear combinations of the schedule + * coefficients that are non-zero when the schedule coefficients are + * 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 (compressed) domain + * nparam is the number of parameters or 0 if we are not constructing + * a parametric schedule + * + * If compressed is set, then hull represents the constraints + * that were used to derive the compression, while compress and + * decompress map the original space to the compressed space and + * vice versa. + * + * scc is the index of SCC (or WCC) this node belongs to + * + * "cluster" is only used inside extract_clusters and identifies + * the cluster of SCCs that the node belongs to. + * + * coincident contains a boolean for each of the rows of the schedule, + * indicating whether the corresponding scheduling dimension satisfies + * the coincidence constraints in the sense that the corresponding + * dependence distances are zero. + * + * If the schedule_treat_coalescing option is set, then + * "sizes" contains the sizes of the (compressed) instance set + * in each direction. If there is no fixed size in a given direction, + * then the corresponding size value is set to infinity. + * If the schedule_treat_coalescing option or the schedule_max_coefficient + * option is set, then "max" contains the maximal values for + * schedule coefficients of the (compressed) variables. If no bound + * needs to be imposed on a particular variable, then the corresponding + * value is negative. + * If not NULL, then "bounds" contains a non-parametric set + * in the compressed space that is bounded by the size in each direction. + */ +struct isl_sched_node { + isl_space *space; + int compressed; + isl_set *hull; + isl_multi_aff *compress; + isl_pw_multi_aff *decompress; + isl_mat *sched; + isl_map *sched_map; + int rank; + isl_mat *indep; + isl_mat *vmap; + int start; + int nvar; + int nparam; + + int scc; + int cluster; + + int *coincident; + + isl_multi_val *sizes; + isl_basic_set *bounds; + isl_vec *max; +}; + +int isl_sched_node_scc_exactly(struct isl_sched_node *node, int scc); + +isl_stat isl_sched_node_update_vmap(struct isl_sched_node *node); +__isl_give isl_multi_aff *isl_sched_node_extract_partial_schedule_multi_aff( + struct isl_sched_node *node, int first, int n); + +/* An edge in the dependence graph. An edge may be used to + * ensure validity of the generated schedule, to minimize the dependence + * distance or both + * + * map is the dependence relation, with i -> j in the map if j depends on i + * tagged_condition and tagged_validity contain the union of all tagged + * condition or conditional validity dependence relations that + * specialize the dependence relation "map"; that is, + * if (i -> a) -> (j -> b) is an element of "tagged_condition" + * or "tagged_validity", then i -> j is an element of "map". + * If these fields are NULL, then they represent the empty relation. + * src is the source node + * dst is the sink node + * + * types is a bit vector containing the types of this edge. + * validity is set if the edge is used to ensure correctness + * coincidence is used to enforce zero dependence distances + * proximity is set if the edge is used to minimize dependence distances + * condition is set if the edge represents a condition + * for a conditional validity schedule constraint + * local can only be set for condition edges and indicates that + * the dependence distance over the edge should be zero + * conditional_validity is set if the edge is used to conditionally + * ensure correctness + * + * For validity edges, start and end mark the sequence of inequality + * constraints in the LP problem that encode the validity constraint + * corresponding to this edge. + * + * During clustering, an edge may be marked "no_merge" if it should + * not be used to merge clusters. + * The weight is also only used during clustering and it is + * an indication of how many schedule dimensions on either side + * of the schedule constraints can be aligned. + * If the weight is negative, then this means that this edge was postponed + * by has_bounded_distances or any_no_merge. The original weight can + * be retrieved by adding 1 + graph->max_weight, with "graph" + * the graph containing this edge. + */ +struct isl_sched_edge { + isl_map *map; + isl_union_map *tagged_condition; + isl_union_map *tagged_validity; + + struct isl_sched_node *src; + struct isl_sched_node *dst; + + unsigned types; + + int start; + int end; + + int no_merge; + int weight; +}; + +int isl_sched_edge_has_type(struct isl_sched_edge *edge, + enum isl_edge_type type); +int isl_sched_edge_is_condition(struct isl_sched_edge *edge); +int isl_sched_edge_is_conditional_validity(struct isl_sched_edge *edge); +int isl_sched_edge_scc_exactly(struct isl_sched_edge *edge, int scc); +int isl_sched_edge_is_proximity(struct isl_sched_edge *edge); + +/* Internal information about the dependence graph used during + * the construction of the schedule. + * + * intra_hmap is a cache, mapping dependence relations to their dual, + * for dependences from a node to itself, possibly without + * coefficients for the parameters + * intra_hmap_param is a cache, mapping dependence relations to their dual, + * for dependences from a node to itself, including coefficients + * for the parameters + * inter_hmap is a cache, mapping dependence relations to their dual, + * for dependences between distinct nodes + * if compression is involved then the key for these maps + * is the original, uncompressed dependence relation, while + * the value is the dual of the compressed dependence relation. + * + * n is the number of nodes + * node is the list of nodes + * maxvar is the maximal number of variables over all nodes + * max_row is the allocated number of rows in the schedule + * n_row is the current (maximal) number of linearly independent + * 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 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. + * + * sorted contains a list of node indices sorted according to the + * SCC to which a node belongs + * + * n_edge is the number of edges + * edge is the list of edges + * max_edge contains the maximal number of edges of each type; + * in particular, it contains the number of edges in the inital graph. + * edge_table contains pointers into the edge array, hashed on the source + * and sink spaces; there is one such table for each type; + * a given edge may be referenced from more than one table + * if the corresponding relation appears in more than one of the + * sets of dependences; however, for each type there is only + * a single edge between a given pair of source and sink space + * in the entire graph + * + * node_table contains pointers into the node array, hashed on the space tuples + * + * region contains a list of variable sequences that should be non-trivial + * + * lp contains the (I)LP problem used to obtain new schedule rows + * + * src_scc and dst_scc are the source and sink SCCs of an edge with + * conflicting constraints + * + * scc represents the number of components + * weak is set if the components are weakly connected + * + * max_weight is used during clustering and represents the maximal + * weight of the relevant proximity edges. + */ +struct isl_sched_graph { + isl_map_to_basic_set *intra_hmap; + isl_map_to_basic_set *intra_hmap_param; + isl_map_to_basic_set *inter_hmap; + + struct isl_sched_node *node; + int n; + int maxvar; + int max_row; + int n_row; + + int *sorted; + + int n_total_row; + int band_start; + + struct isl_sched_graph *root; + + struct isl_sched_edge *edge; + int n_edge; + int max_edge[isl_edge_last + 1]; + struct isl_hash_table *edge_table[isl_edge_last + 1]; + + struct isl_hash_table *node_table; + struct isl_trivial_region *region; + + isl_basic_set *lp; + + int src_scc; + int dst_scc; + + int scc; + int weak; + + int max_weight; +}; + +isl_stat isl_sched_graph_init(struct isl_sched_graph *graph, + __isl_keep isl_schedule_constraints *sc); +void isl_sched_graph_free(isl_ctx *ctx, struct isl_sched_graph *graph); + +int isl_sched_graph_is_node(struct isl_sched_graph *graph, + struct isl_sched_node *node); +isl_bool isl_sched_graph_has_validity_edge(struct isl_sched_graph *graph, + struct isl_sched_node *src, struct isl_sched_node *dst); + +struct isl_sched_node *isl_sched_graph_find_node(isl_ctx *ctx, + struct isl_sched_graph *graph, __isl_keep isl_space *space); + +isl_stat isl_sched_graph_detect_ccs(isl_ctx *ctx, struct isl_sched_graph *graph, + isl_bool (*follows)(int i, int j, void *user)); + +__isl_give isl_union_set *isl_sched_graph_extract_scc(isl_ctx *ctx, + struct isl_sched_graph *graph, int scc); +__isl_give isl_union_set_list *isl_sched_graph_extract_sccs(isl_ctx *ctx, + struct isl_sched_graph *graph); +isl_stat isl_sched_graph_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); +isl_stat isl_sched_graph_compute_maxvar(struct isl_sched_graph *graph); +isl_stat isl_schedule_node_compute_wcc_band(isl_ctx *ctx, + struct isl_sched_graph *graph); +__isl_give isl_schedule_node *isl_schedule_node_compute_finish_band( + __isl_take isl_schedule_node *node, struct isl_sched_graph *graph, + int initialized); + +#endif diff --git a/external/mit/isl/dist/isl_scheduler_clustering.c b/external/mit/isl/dist/isl_scheduler_clustering.c new file mode 100644 index 000000000000..c2e91c90546a --- /dev/null +++ b/external/mit/isl/dist/isl_scheduler_clustering.c @@ -0,0 +1,1565 @@ +/* + * Copyright 2015 Sven Verdoolaege + * + * Use of this software is governed by the MIT license + * + * Written by Sven Verdoolaege + */ + +#include "isl_map_private.h" + +#include +#include +#include + +#include "isl_mat_private.h" +#include "isl_scheduler_clustering.h" +#include "isl_scheduler_scc.h" +#include "isl_seq.h" +#include "isl_tarjan.h" + +/* Initialize the clustering data structure "c" from "graph". + * + * In particular, allocate memory, extract the SCCs from "graph" + * into c->scc, initialize scc_cluster and construct + * a band of schedule rows for each SCC. + * Within each SCC, there is only one SCC by definition. + * Each SCC initially belongs to a cluster containing only that SCC. + */ +static isl_stat clustering_init(isl_ctx *ctx, struct isl_clustering *c, + struct isl_sched_graph *graph) +{ + int i; + + c->n = graph->scc; + c->scc = isl_calloc_array(ctx, struct isl_sched_graph, c->n); + c->cluster = isl_calloc_array(ctx, struct isl_sched_graph, c->n); + c->scc_cluster = isl_calloc_array(ctx, int, c->n); + c->scc_node = isl_calloc_array(ctx, int, c->n); + c->scc_in_merge = isl_calloc_array(ctx, int, c->n); + if (!c->scc || !c->cluster || + !c->scc_cluster || !c->scc_node || !c->scc_in_merge) + return isl_stat_error; + + for (i = 0; i < c->n; ++i) { + if (isl_sched_graph_extract_sub_graph(ctx, graph, + &isl_sched_node_scc_exactly, + &isl_sched_edge_scc_exactly, + i, &c->scc[i]) < 0) + return isl_stat_error; + c->scc[i].scc = 1; + if (isl_sched_graph_compute_maxvar(&c->scc[i]) < 0) + return isl_stat_error; + if (isl_schedule_node_compute_wcc_band(ctx, &c->scc[i]) < 0) + return isl_stat_error; + c->scc_cluster[i] = i; + } + + return isl_stat_ok; +} + +/* Free all memory allocated for "c". + */ +static void clustering_free(isl_ctx *ctx, struct isl_clustering *c) +{ + int i; + + if (c->scc) + for (i = 0; i < c->n; ++i) + isl_sched_graph_free(ctx, &c->scc[i]); + free(c->scc); + if (c->cluster) + for (i = 0; i < c->n; ++i) + isl_sched_graph_free(ctx, &c->cluster[i]); + free(c->cluster); + free(c->scc_cluster); + free(c->scc_node); + free(c->scc_in_merge); +} + +/* Should we refrain from merging the cluster in "graph" with + * any other cluster? + * In particular, is its current schedule band empty and incomplete. + */ +static int bad_cluster(struct isl_sched_graph *graph) +{ + return graph->n_row < graph->maxvar && + graph->n_total_row == graph->band_start; +} + +/* Is "edge" a proximity edge with a non-empty dependence relation? + */ +static isl_bool is_non_empty_proximity(struct isl_sched_edge *edge) +{ + if (!isl_sched_edge_is_proximity(edge)) + return isl_bool_false; + return isl_bool_not(isl_map_plain_is_empty(edge->map)); +} + +/* Return the index of an edge in "graph" that can be used to merge + * two clusters in "c". + * Return graph->n_edge if no such edge can be found. + * Return -1 on error. + * + * In particular, return a proximity edge between two clusters + * that is not marked "no_merge" and such that neither of the + * two clusters has an incomplete, empty band. + * + * If there are multiple such edges, then try and find the most + * appropriate edge to use for merging. In particular, pick the edge + * with the greatest weight. If there are multiple of those, + * then pick one with the shortest distance between + * the two cluster representatives. + */ +static int find_proximity(struct isl_sched_graph *graph, + struct isl_clustering *c) +{ + int i, best = graph->n_edge, best_dist, best_weight; + + for (i = 0; i < graph->n_edge; ++i) { + struct isl_sched_edge *edge = &graph->edge[i]; + int dist, weight; + isl_bool prox; + + prox = is_non_empty_proximity(edge); + if (prox < 0) + return -1; + if (!prox) + continue; + if (edge->no_merge) + continue; + if (bad_cluster(&c->scc[edge->src->scc]) || + bad_cluster(&c->scc[edge->dst->scc])) + continue; + dist = c->scc_cluster[edge->dst->scc] - + c->scc_cluster[edge->src->scc]; + if (dist == 0) + continue; + weight = edge->weight; + if (best < graph->n_edge) { + if (best_weight > weight) + continue; + if (best_weight == weight && best_dist <= dist) + continue; + } + best = i; + best_dist = dist; + best_weight = weight; + } + + return best; +} + +/* Internal data structure used in mark_merge_sccs. + * + * "graph" is the dependence graph in which a strongly connected + * component is constructed. + * "scc_cluster" maps each SCC index to the cluster to which it belongs. + * "src" and "dst" are the indices of the nodes that are being merged. + */ +struct isl_mark_merge_sccs_data { + struct isl_sched_graph *graph; + int *scc_cluster; + int src; + int dst; +}; + +/* Check whether the cluster containing node "i" depends on the cluster + * containing node "j". If "i" and "j" belong to the same cluster, + * then they are taken to depend on each other to ensure that + * the resulting strongly connected component consists of complete + * clusters. Furthermore, if "i" and "j" are the two nodes that + * are being merged, then they are taken to depend on each other as well. + * Otherwise, check if there is a (conditional) validity dependence + * from node[j] to node[i], forcing node[i] to follow node[j]. + */ +static isl_bool cluster_follows(int i, int j, void *user) +{ + struct isl_mark_merge_sccs_data *data = user; + struct isl_sched_graph *graph = data->graph; + int *scc_cluster = data->scc_cluster; + + if (data->src == i && data->dst == j) + return isl_bool_true; + if (data->src == j && data->dst == i) + return isl_bool_true; + if (scc_cluster[graph->node[i].scc] == scc_cluster[graph->node[j].scc]) + return isl_bool_true; + + return isl_sched_graph_has_validity_edge(graph, &graph->node[j], + &graph->node[i]); +} + +/* Mark all SCCs that belong to either of the two clusters in "c" + * connected by the edge in "graph" with index "edge", or to any + * of the intermediate clusters. + * The marking is recorded in c->scc_in_merge. + * + * The given edge has been selected for merging two clusters, + * meaning that there is at least a proximity edge between the two nodes. + * However, there may also be (indirect) validity dependences + * between the two nodes. When merging the two clusters, all clusters + * containing one or more of the intermediate nodes along the + * indirect validity dependences need to be merged in as well. + * + * First collect all such nodes by computing the strongly connected + * component (SCC) containing the two nodes connected by the edge, where + * the two nodes are considered to depend on each other to make + * sure they end up in the same SCC. Similarly, each node is considered + * to depend on every other node in the same cluster to ensure + * that the SCC consists of complete clusters. + * + * Then the original SCCs that contain any of these nodes are marked + * in c->scc_in_merge. + */ +static isl_stat mark_merge_sccs(isl_ctx *ctx, struct isl_sched_graph *graph, + int edge, struct isl_clustering *c) +{ + struct isl_mark_merge_sccs_data data; + struct isl_tarjan_graph *g; + int i; + + for (i = 0; i < c->n; ++i) + c->scc_in_merge[i] = 0; + + data.graph = graph; + data.scc_cluster = c->scc_cluster; + data.src = graph->edge[edge].src - graph->node; + data.dst = graph->edge[edge].dst - graph->node; + + g = isl_tarjan_graph_component(ctx, graph->n, data.dst, + &cluster_follows, &data); + if (!g) + goto error; + + i = g->op; + if (i < 3) + isl_die(ctx, isl_error_internal, + "expecting at least two nodes in component", + goto error); + if (g->order[--i] != -1) + isl_die(ctx, isl_error_internal, + "expecting end of component marker", goto error); + + for (--i; i >= 0 && g->order[i] != -1; --i) { + int scc = graph->node[g->order[i]].scc; + c->scc_in_merge[scc] = 1; + } + + isl_tarjan_graph_free(g); + return isl_stat_ok; +error: + isl_tarjan_graph_free(g); + return isl_stat_error; +} + +/* Construct the identifier "cluster_i". + */ +static __isl_give isl_id *cluster_id(isl_ctx *ctx, int i) +{ + char name[40]; + + snprintf(name, sizeof(name), "cluster_%d", i); + return isl_id_alloc(ctx, name, NULL); +} + +/* Construct the space of the cluster with index "i" containing + * the strongly connected component "scc". + * + * In particular, construct a space called cluster_i with dimension equal + * to the number of schedule rows in the current band of "scc". + */ +static __isl_give isl_space *cluster_space(struct isl_sched_graph *scc, int i) +{ + int nvar; + isl_space *space; + isl_id *id; + + nvar = scc->n_total_row - scc->band_start; + space = isl_space_copy(scc->node[0].space); + space = isl_space_params(space); + space = isl_space_set_from_params(space); + space = isl_space_add_dims(space, isl_dim_set, nvar); + id = cluster_id(isl_space_get_ctx(space), i); + space = isl_space_set_tuple_id(space, isl_dim_set, id); + + return space; +} + +/* Collect the domain of the graph for merging clusters. + * + * In particular, for each cluster with first SCC "i", construct + * a set in the space called cluster_i with dimension equal + * to the number of schedule rows in the current band of the cluster. + */ +static __isl_give isl_union_set *collect_domain(isl_ctx *ctx, + struct isl_sched_graph *graph, struct isl_clustering *c) +{ + int i; + isl_space *space; + isl_union_set *domain; + + space = isl_space_params_alloc(ctx, 0); + domain = isl_union_set_empty(space); + + for (i = 0; i < graph->scc; ++i) { + isl_space *space; + + if (!c->scc_in_merge[i]) + continue; + if (c->scc_cluster[i] != i) + continue; + space = cluster_space(&c->scc[i], i); + domain = isl_union_set_add_set(domain, isl_set_universe(space)); + } + + return domain; +} + +/* Construct a map from the original instances to the corresponding + * cluster instance in the current bands of the clusters in "c". + */ +static __isl_give isl_union_map *collect_cluster_map(isl_ctx *ctx, + struct isl_sched_graph *graph, struct isl_clustering *c) +{ + int i, j; + isl_space *space; + isl_union_map *cluster_map; + + space = isl_space_params_alloc(ctx, 0); + cluster_map = isl_union_map_empty(space); + for (i = 0; i < graph->scc; ++i) { + int start, n; + isl_id *id; + + if (!c->scc_in_merge[i]) + continue; + + id = cluster_id(ctx, c->scc_cluster[i]); + start = c->scc[i].band_start; + n = c->scc[i].n_total_row - start; + for (j = 0; j < c->scc[i].n; ++j) { + isl_multi_aff *ma; + isl_map *map; + struct isl_sched_node *node = &c->scc[i].node[j]; + + ma = isl_sched_node_extract_partial_schedule_multi_aff( + node, start, n); + ma = isl_multi_aff_set_tuple_id(ma, isl_dim_out, + isl_id_copy(id)); + map = isl_map_from_multi_aff(ma); + cluster_map = isl_union_map_add_map(cluster_map, map); + } + isl_id_free(id); + } + + return cluster_map; +} + +/* Add "umap" to the schedule constraints "sc" of all types of "edge" + * that are not isl_edge_condition or isl_edge_conditional_validity. + */ +static __isl_give isl_schedule_constraints *add_non_conditional_constraints( + struct isl_sched_edge *edge, __isl_keep isl_union_map *umap, + __isl_take isl_schedule_constraints *sc) +{ + enum isl_edge_type t; + + if (!sc) + return NULL; + + for (t = isl_edge_first; t <= isl_edge_last; ++t) { + if (t == isl_edge_condition || + t == isl_edge_conditional_validity) + continue; + if (!isl_sched_edge_has_type(edge, t)) + continue; + sc = isl_schedule_constraints_add(sc, t, + isl_union_map_copy(umap)); + } + + return sc; +} + +/* Add schedule constraints of types isl_edge_condition and + * isl_edge_conditional_validity to "sc" by applying "umap" to + * the domains of the wrapped relations in domain and range + * of the corresponding tagged constraints of "edge". + */ +static __isl_give isl_schedule_constraints *add_conditional_constraints( + struct isl_sched_edge *edge, __isl_keep isl_union_map *umap, + __isl_take isl_schedule_constraints *sc) +{ + enum isl_edge_type t; + isl_union_map *tagged; + + for (t = isl_edge_condition; t <= isl_edge_conditional_validity; ++t) { + if (!isl_sched_edge_has_type(edge, t)) + continue; + if (t == isl_edge_condition) + tagged = isl_union_map_copy(edge->tagged_condition); + else + tagged = isl_union_map_copy(edge->tagged_validity); + tagged = isl_union_map_zip(tagged); + tagged = isl_union_map_apply_domain(tagged, + isl_union_map_copy(umap)); + tagged = isl_union_map_zip(tagged); + sc = isl_schedule_constraints_add(sc, t, tagged); + if (!sc) + return NULL; + } + + return sc; +} + +/* Given a mapping "cluster_map" from the original instances to + * the cluster instances, add schedule constraints on the clusters + * to "sc" corresponding to the original constraints represented by "edge". + * + * For non-tagged dependence constraints, the cluster constraints + * are obtained by applying "cluster_map" to the edge->map. + * + * For tagged dependence constraints, "cluster_map" needs to be applied + * to the domains of the wrapped relations in domain and range + * of the tagged dependence constraints. Pick out the mappings + * from these domains from "cluster_map" and construct their product. + * This mapping can then be applied to the pair of domains. + */ +static __isl_give isl_schedule_constraints *collect_edge_constraints( + struct isl_sched_edge *edge, __isl_keep isl_union_map *cluster_map, + __isl_take isl_schedule_constraints *sc) +{ + isl_union_map *umap; + isl_space *space; + isl_union_set *uset; + isl_union_map *umap1, *umap2; + + if (!sc) + return NULL; + + umap = isl_union_map_from_map(isl_map_copy(edge->map)); + umap = isl_union_map_apply_domain(umap, + isl_union_map_copy(cluster_map)); + umap = isl_union_map_apply_range(umap, + isl_union_map_copy(cluster_map)); + sc = add_non_conditional_constraints(edge, umap, sc); + isl_union_map_free(umap); + + if (!sc || + (!isl_sched_edge_is_condition(edge) && + !isl_sched_edge_is_conditional_validity(edge))) + return sc; + + space = isl_space_domain(isl_map_get_space(edge->map)); + uset = isl_union_set_from_set(isl_set_universe(space)); + umap1 = isl_union_map_copy(cluster_map); + umap1 = isl_union_map_intersect_domain(umap1, uset); + space = isl_space_range(isl_map_get_space(edge->map)); + uset = isl_union_set_from_set(isl_set_universe(space)); + umap2 = isl_union_map_copy(cluster_map); + umap2 = isl_union_map_intersect_domain(umap2, uset); + umap = isl_union_map_product(umap1, umap2); + + sc = add_conditional_constraints(edge, umap, sc); + + isl_union_map_free(umap); + return sc; +} + +/* Given a mapping "cluster_map" from the original instances to + * the cluster instances, add schedule constraints on the clusters + * to "sc" corresponding to all edges in "graph" between nodes that + * belong to SCCs that are marked for merging in "scc_in_merge". + */ +static __isl_give isl_schedule_constraints *collect_constraints( + struct isl_sched_graph *graph, int *scc_in_merge, + __isl_keep isl_union_map *cluster_map, + __isl_take isl_schedule_constraints *sc) +{ + int i; + + for (i = 0; i < graph->n_edge; ++i) { + struct isl_sched_edge *edge = &graph->edge[i]; + + if (!scc_in_merge[edge->src->scc]) + continue; + if (!scc_in_merge[edge->dst->scc]) + continue; + sc = collect_edge_constraints(edge, cluster_map, sc); + } + + return sc; +} + +/* Construct a dependence graph for scheduling clusters with respect + * to each other and store the result in "merge_graph". + * In particular, the nodes of the graph correspond to the schedule + * dimensions of the current bands of those clusters that have been + * marked for merging in "c". + * + * First construct an isl_schedule_constraints object for this domain + * by transforming the edges in "graph" to the domain. + * Then initialize a dependence graph for scheduling from these + * constraints. + */ +static isl_stat init_merge_graph(isl_ctx *ctx, struct isl_sched_graph *graph, + struct isl_clustering *c, struct isl_sched_graph *merge_graph) +{ + isl_union_set *domain; + isl_union_map *cluster_map; + isl_schedule_constraints *sc; + isl_stat r; + + domain = collect_domain(ctx, graph, c); + sc = isl_schedule_constraints_on_domain(domain); + if (!sc) + return isl_stat_error; + cluster_map = collect_cluster_map(ctx, graph, c); + sc = collect_constraints(graph, c->scc_in_merge, cluster_map, sc); + isl_union_map_free(cluster_map); + + r = isl_sched_graph_init(merge_graph, sc); + + isl_schedule_constraints_free(sc); + + return r; +} + +/* Compute the maximal number of remaining schedule rows that still need + * to be computed for the nodes that belong to clusters with the maximal + * dimension for the current band (i.e., the band that is to be merged). + * Only clusters that are about to be merged are considered. + * "maxvar" is the maximal dimension for the current band. + * "c" contains information about the clusters. + * + * Return the maximal number of remaining schedule rows or + * isl_size_error on error. + */ +static isl_size compute_maxvar_max_slack(int maxvar, struct isl_clustering *c) +{ + int i, j; + int max_slack; + + max_slack = 0; + for (i = 0; i < c->n; ++i) { + int nvar; + struct isl_sched_graph *scc; + + if (!c->scc_in_merge[i]) + continue; + scc = &c->scc[i]; + nvar = scc->n_total_row - scc->band_start; + if (nvar != maxvar) + continue; + for (j = 0; j < scc->n; ++j) { + struct isl_sched_node *node = &scc->node[j]; + int slack; + + if (isl_sched_node_update_vmap(node) < 0) + return isl_size_error; + slack = node->nvar - node->rank; + if (slack > max_slack) + max_slack = slack; + } + } + + return max_slack; +} + +/* If there are any clusters where the dimension of the current band + * (i.e., the band that is to be merged) is smaller than "maxvar" and + * if there are any nodes in such a cluster where the number + * of remaining schedule rows that still need to be computed + * is greater than "max_slack", then return the smallest current band + * dimension of all these clusters. Otherwise return the original value + * of "maxvar". Return isl_size_error in case of any error. + * Only clusters that are about to be merged are considered. + * "c" contains information about the clusters. + */ +static isl_size limit_maxvar_to_slack(int maxvar, int max_slack, + struct isl_clustering *c) +{ + int i, j; + + for (i = 0; i < c->n; ++i) { + int nvar; + struct isl_sched_graph *scc; + + if (!c->scc_in_merge[i]) + continue; + scc = &c->scc[i]; + nvar = scc->n_total_row - scc->band_start; + if (nvar >= maxvar) + continue; + for (j = 0; j < scc->n; ++j) { + struct isl_sched_node *node = &scc->node[j]; + int slack; + + if (isl_sched_node_update_vmap(node) < 0) + return isl_size_error; + slack = node->nvar - node->rank; + if (slack > max_slack) { + maxvar = nvar; + break; + } + } + } + + return maxvar; +} + +/* Adjust merge_graph->maxvar based on the number of remaining schedule rows + * that still need to be computed. In particular, if there is a node + * in a cluster where the dimension of the current band is smaller + * than merge_graph->maxvar, but the number of remaining schedule rows + * is greater than that of any node in a cluster with the maximal + * dimension for the current band (i.e., merge_graph->maxvar), + * then adjust merge_graph->maxvar to the (smallest) current band dimension + * of those clusters. Without this adjustment, the total number of + * schedule dimensions would be increased, resulting in a skewed view + * of the number of coincident dimensions. + * "c" contains information about the clusters. + * + * If the maximize_band_depth option is set and merge_graph->maxvar is reduced, + * then there is no point in attempting any merge since it will be rejected + * anyway. Set merge_graph->maxvar to zero in such cases. + */ +static isl_stat adjust_maxvar_to_slack(isl_ctx *ctx, + struct isl_sched_graph *merge_graph, struct isl_clustering *c) +{ + isl_size max_slack, maxvar; + + max_slack = compute_maxvar_max_slack(merge_graph->maxvar, c); + if (max_slack < 0) + return isl_stat_error; + maxvar = limit_maxvar_to_slack(merge_graph->maxvar, max_slack, c); + if (maxvar < 0) + return isl_stat_error; + + if (maxvar < merge_graph->maxvar) { + if (isl_options_get_schedule_maximize_band_depth(ctx)) + merge_graph->maxvar = 0; + else + merge_graph->maxvar = maxvar; + } + + return isl_stat_ok; +} + +/* Return the number of coincident dimensions in the current band of "graph", + * where the nodes of "graph" are assumed to be scheduled by a single band. + */ +static int get_n_coincident(struct isl_sched_graph *graph) +{ + int i; + + for (i = graph->band_start; i < graph->n_total_row; ++i) + if (!graph->node[0].coincident[i]) + break; + + return i - graph->band_start; +} + +/* Should the clusters be merged based on the cluster schedule + * in the current (and only) band of "merge_graph", given that + * coincidence should be maximized? + * + * If the number of coincident schedule dimensions in the merged band + * would be less than the maximal number of coincident schedule dimensions + * in any of the merged clusters, then the clusters should not be merged. + */ +static isl_bool ok_to_merge_coincident(struct isl_clustering *c, + struct isl_sched_graph *merge_graph) +{ + int i; + int n_coincident; + int max_coincident; + + max_coincident = 0; + for (i = 0; i < c->n; ++i) { + if (!c->scc_in_merge[i]) + continue; + n_coincident = get_n_coincident(&c->scc[i]); + if (n_coincident > max_coincident) + max_coincident = n_coincident; + } + + n_coincident = get_n_coincident(merge_graph); + + return isl_bool_ok(n_coincident >= max_coincident); +} + +/* Return the transformation on "node" expressed by the current (and only) + * band of "merge_graph" applied to the clusters in "c". + * + * First find the representation of "node" in its SCC in "c" and + * extract the transformation expressed by the current band. + * Then extract the transformation applied by "merge_graph" + * to the cluster to which this SCC belongs. + * Combine the two to obtain the complete transformation on the node. + * + * Note that the range of the first transformation is an anonymous space, + * while the domain of the second is named "cluster_X". The range + * of the former therefore needs to be adjusted before the two + * can be combined. + */ +static __isl_give isl_map *extract_node_transformation(isl_ctx *ctx, + struct isl_sched_node *node, struct isl_clustering *c, + struct isl_sched_graph *merge_graph) +{ + struct isl_sched_node *scc_node, *cluster_node; + int start, n; + isl_id *id; + isl_space *space; + isl_multi_aff *ma, *ma2; + + scc_node = isl_sched_graph_find_node(ctx, &c->scc[node->scc], + node->space); + if (scc_node && !isl_sched_graph_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 = isl_sched_node_extract_partial_schedule_multi_aff(scc_node, + start, n); + space = cluster_space(&c->scc[node->scc], c->scc_cluster[node->scc]); + cluster_node = isl_sched_graph_find_node(ctx, merge_graph, space); + if (cluster_node && !isl_sched_graph_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); + ma = isl_multi_aff_set_tuple_id(ma, isl_dim_out, id); + isl_space_free(space); + n = merge_graph->n_total_row; + ma2 = isl_sched_node_extract_partial_schedule_multi_aff(cluster_node, + 0, n); + ma = isl_multi_aff_pullback_multi_aff(ma2, ma); + + return isl_map_from_multi_aff(ma); +} + +/* Give a set of distances "set", are they bounded by a small constant + * in direction "pos"? + * In practice, check if they are bounded by 2 by checking that there + * are no elements with a value greater than or equal to 3 or + * smaller than or equal to -3. + */ +static isl_bool distance_is_bounded(__isl_keep isl_set *set, int pos) +{ + isl_bool bounded; + isl_set *test; + + if (!set) + return isl_bool_error; + + test = isl_set_copy(set); + test = isl_set_lower_bound_si(test, isl_dim_set, pos, 3); + bounded = isl_set_is_empty(test); + isl_set_free(test); + + if (bounded < 0 || !bounded) + return bounded; + + test = isl_set_copy(set); + test = isl_set_upper_bound_si(test, isl_dim_set, pos, -3); + bounded = isl_set_is_empty(test); + isl_set_free(test); + + return bounded; +} + +/* Does the set "set" have a fixed (but possible parametric) value + * at dimension "pos"? + */ +static isl_bool has_single_value(__isl_keep isl_set *set, int pos) +{ + isl_size n; + isl_bool single; + + n = isl_set_dim(set, isl_dim_set); + if (n < 0) + return isl_bool_error; + set = isl_set_copy(set); + set = isl_set_project_out(set, isl_dim_set, pos + 1, n - (pos + 1)); + set = isl_set_project_out(set, isl_dim_set, 0, pos); + single = isl_set_is_singleton(set); + isl_set_free(set); + + return single; +} + +/* Does "map" have a fixed (but possible parametric) value + * at dimension "pos" of either its domain or its range? + */ +static isl_bool has_singular_src_or_dst(__isl_keep isl_map *map, int pos) +{ + isl_set *set; + isl_bool single; + + set = isl_map_domain(isl_map_copy(map)); + single = has_single_value(set, pos); + isl_set_free(set); + + if (single < 0 || single) + return single; + + set = isl_map_range(isl_map_copy(map)); + single = has_single_value(set, pos); + isl_set_free(set); + + return single; +} + +/* Does the edge "edge" from "graph" have bounded dependence distances + * in the merged graph "merge_graph" of a selection of clusters in "c"? + * + * Extract the complete transformations of the source and destination + * nodes of the edge, apply them to the edge constraints and + * compute the differences. Finally, check if these differences are bounded + * in each direction. + * + * If the dimension of the band is greater than the number of + * dimensions that can be expected to be optimized by the edge + * (based on its weight), then also allow the differences to be unbounded + * in the remaining dimensions, but only if either the source or + * the destination has a fixed value in that direction. + * This allows a statement that produces values that are used by + * several instances of another statement to be merged with that + * other statement. + * However, merging such clusters will introduce an inherently + * large proximity distance inside the merged cluster, meaning + * that proximity distances will no longer be optimized in + * subsequent merges. These merges are therefore only allowed + * after all other possible merges have been tried. + * The first time such a merge is encountered, the weight of the edge + * is replaced by a negative weight. The second time (i.e., after + * all merges over edges with a non-negative weight have been tried), + * the merge is allowed. + */ +static isl_bool has_bounded_distances(isl_ctx *ctx, struct isl_sched_edge *edge, + struct isl_sched_graph *graph, struct isl_clustering *c, + struct isl_sched_graph *merge_graph) +{ + int i, n_slack; + isl_size n; + isl_bool bounded; + isl_map *map, *t; + isl_set *dist; + + map = isl_map_copy(edge->map); + t = extract_node_transformation(ctx, edge->src, c, merge_graph); + map = isl_map_apply_domain(map, t); + t = extract_node_transformation(ctx, edge->dst, c, merge_graph); + map = isl_map_apply_range(map, t); + dist = isl_map_deltas(isl_map_copy(map)); + + bounded = isl_bool_true; + n = isl_set_dim(dist, isl_dim_set); + if (n < 0) + goto error; + n_slack = n - edge->weight; + if (edge->weight < 0) + n_slack -= graph->max_weight + 1; + for (i = 0; i < n; ++i) { + isl_bool bounded_i, singular_i; + + bounded_i = distance_is_bounded(dist, i); + if (bounded_i < 0) + goto error; + if (bounded_i) + continue; + if (edge->weight >= 0) + bounded = isl_bool_false; + n_slack--; + if (n_slack < 0) + break; + singular_i = has_singular_src_or_dst(map, i); + if (singular_i < 0) + goto error; + if (singular_i) + continue; + bounded = isl_bool_false; + break; + } + if (!bounded && i >= n && edge->weight >= 0) + edge->weight -= graph->max_weight + 1; + isl_map_free(map); + isl_set_free(dist); + + return bounded; +error: + isl_map_free(map); + isl_set_free(dist); + return isl_bool_error; +} + +/* Should the clusters be merged based on the cluster schedule + * in the current (and only) band of "merge_graph"? + * "graph" is the original dependence graph, while "c" records + * which SCCs are involved in the latest merge. + * + * In particular, is there at least one proximity constraint + * that is optimized by the merge? + * + * A proximity constraint is considered to be optimized + * if the dependence distances are small. + */ +static isl_bool ok_to_merge_proximity(isl_ctx *ctx, + struct isl_sched_graph *graph, struct isl_clustering *c, + struct isl_sched_graph *merge_graph) +{ + int i; + + for (i = 0; i < graph->n_edge; ++i) { + struct isl_sched_edge *edge = &graph->edge[i]; + isl_bool bounded; + + if (!isl_sched_edge_is_proximity(edge)) + continue; + if (!c->scc_in_merge[edge->src->scc]) + continue; + if (!c->scc_in_merge[edge->dst->scc]) + continue; + if (c->scc_cluster[edge->dst->scc] == + c->scc_cluster[edge->src->scc]) + continue; + bounded = has_bounded_distances(ctx, edge, graph, c, + merge_graph); + if (bounded < 0 || bounded) + return bounded; + } + + return isl_bool_false; +} + +/* Should the clusters be merged based on the cluster schedule + * in the current (and only) band of "merge_graph"? + * "graph" is the original dependence graph, while "c" records + * which SCCs are involved in the latest merge. + * + * If the current band is empty, then the clusters should not be merged. + * + * If the band depth should be maximized and the merge schedule + * is incomplete (meaning that the dimension of some of the schedule + * bands in the original schedule will be reduced), then the clusters + * should not be merged. + * + * If the schedule_maximize_coincidence option is set, then check that + * the number of coincident schedule dimensions is not reduced. + * + * Finally, only allow the merge if at least one proximity + * constraint is optimized. + */ +static isl_bool ok_to_merge(isl_ctx *ctx, struct isl_sched_graph *graph, + struct isl_clustering *c, struct isl_sched_graph *merge_graph) +{ + if (merge_graph->n_total_row == merge_graph->band_start) + return isl_bool_false; + + if (isl_options_get_schedule_maximize_band_depth(ctx) && + merge_graph->n_total_row < merge_graph->maxvar) + return isl_bool_false; + + if (isl_options_get_schedule_maximize_coincidence(ctx)) { + isl_bool ok; + + ok = ok_to_merge_coincident(c, merge_graph); + if (ok < 0 || !ok) + return ok; + } + + return ok_to_merge_proximity(ctx, graph, c, merge_graph); +} + +/* Apply the schedule in "t_node" to the "n" rows starting at "first" + * of the schedule in "node" and return the result. + * + * That is, essentially compute + * + * T * N(first:first+n-1) + * + * taking into account the constant term and the parameter coefficients + * in "t_node". + */ +static __isl_give isl_mat *node_transformation(isl_ctx *ctx, + struct isl_sched_node *t_node, struct isl_sched_node *node, + int first, int n) +{ + int i, j; + isl_mat *t; + isl_size n_row, n_col; + int n_param, n_var; + + n_param = node->nparam; + n_var = node->nvar; + n_row = isl_mat_rows(t_node->sched); + n_col = isl_mat_cols(node->sched); + if (n_row < 0 || n_col < 0) + return NULL; + t = isl_mat_alloc(ctx, n_row, n_col); + if (!t) + return NULL; + for (i = 0; i < n_row; ++i) { + isl_seq_cpy(t->row[i], t_node->sched->row[i], 1 + n_param); + isl_seq_clr(t->row[i] + 1 + n_param, n_var); + for (j = 0; j < n; ++j) + isl_seq_addmul(t->row[i], + t_node->sched->row[i][1 + n_param + j], + node->sched->row[first + j], + 1 + n_param + n_var); + } + return t; +} + +/* Apply the cluster schedule in "t_node" to the current band + * schedule of the nodes in "graph". + * + * In particular, replace the rows starting at band_start + * by the result of applying the cluster schedule in "t_node" + * to the original rows. + * + * The coincidence of the schedule is determined by the coincidence + * of the cluster schedule. + */ +static isl_stat transform(isl_ctx *ctx, struct isl_sched_graph *graph, + struct isl_sched_node *t_node) +{ + int i, j; + isl_size n_new; + int start, n; + + start = graph->band_start; + n = graph->n_total_row - start; + + n_new = isl_mat_rows(t_node->sched); + if (n_new < 0) + return isl_stat_error; + for (i = 0; i < graph->n; ++i) { + struct isl_sched_node *node = &graph->node[i]; + isl_mat *t; + + t = node_transformation(ctx, t_node, node, start, n); + node->sched = isl_mat_drop_rows(node->sched, start, n); + node->sched = isl_mat_concat(node->sched, t); + node->sched_map = isl_map_free(node->sched_map); + if (!node->sched) + return isl_stat_error; + for (j = 0; j < n_new; ++j) + node->coincident[start + j] = t_node->coincident[j]; + } + graph->n_total_row -= n; + graph->n_row -= n; + graph->n_total_row += n_new; + graph->n_row += n_new; + + return isl_stat_ok; +} + +/* Merge the clusters marked for merging in "c" into a single + * cluster using the cluster schedule in the current band of "merge_graph". + * The representative SCC for the new cluster is the SCC with + * the smallest index. + * + * The current band schedule of each SCC in the new cluster is obtained + * by applying the schedule of the corresponding original cluster + * to the original band schedule. + * All SCCs in the new cluster have the same number of schedule rows. + */ +static isl_stat merge(isl_ctx *ctx, struct isl_clustering *c, + struct isl_sched_graph *merge_graph) +{ + int i; + int cluster = -1; + isl_space *space; + + for (i = 0; i < c->n; ++i) { + struct isl_sched_node *node; + + if (!c->scc_in_merge[i]) + continue; + if (cluster < 0) + cluster = i; + space = cluster_space(&c->scc[i], c->scc_cluster[i]); + node = isl_sched_graph_find_node(ctx, merge_graph, space); + isl_space_free(space); + if (!node) + return isl_stat_error; + if (!isl_sched_graph_is_node(merge_graph, node)) + isl_die(ctx, isl_error_internal, + "unable to find cluster", + return isl_stat_error); + if (transform(ctx, &c->scc[i], node) < 0) + return isl_stat_error; + c->scc_cluster[i] = cluster; + } + + return isl_stat_ok; +} + +/* Try and merge the clusters of SCCs marked in c->scc_in_merge + * by scheduling the current cluster bands with respect to each other. + * + * Construct a dependence graph with a space for each cluster and + * with the coordinates of each space corresponding to the schedule + * dimensions of the current band of that cluster. + * Construct a cluster schedule in this cluster dependence graph and + * apply it to the current cluster bands if it is applicable + * according to ok_to_merge. + * + * If the number of remaining schedule dimensions in a cluster + * with a non-maximal current schedule dimension is greater than + * the number of remaining schedule dimensions in clusters + * with a maximal current schedule dimension, then restrict + * the number of rows to be computed in the cluster schedule + * to the minimal such non-maximal current schedule dimension. + * Do this by adjusting merge_graph.maxvar. + * + * Return isl_bool_true if the clusters have effectively been merged + * into a single cluster. + * + * Note that since the standard scheduling algorithm minimizes the maximal + * distance over proximity constraints, the proximity constraints between + * the merged clusters may not be optimized any further than what is + * sufficient to bring the distances within the limits of the internal + * proximity constraints inside the individual clusters. + * It may therefore make sense to perform an additional translation step + * to bring the clusters closer to each other, while maintaining + * the linear part of the merging schedule found using the standard + * scheduling algorithm. + */ +static isl_bool try_merge(isl_ctx *ctx, struct isl_sched_graph *graph, + struct isl_clustering *c) +{ + struct isl_sched_graph merge_graph = { 0 }; + isl_bool merged; + + if (init_merge_graph(ctx, graph, c, &merge_graph) < 0) + goto error; + + if (isl_sched_graph_compute_maxvar(&merge_graph) < 0) + goto error; + if (adjust_maxvar_to_slack(ctx, &merge_graph,c) < 0) + goto error; + if (isl_schedule_node_compute_wcc_band(ctx, &merge_graph) < 0) + goto error; + merged = ok_to_merge(ctx, graph, c, &merge_graph); + if (merged && merge(ctx, c, &merge_graph) < 0) + goto error; + + isl_sched_graph_free(ctx, &merge_graph); + return merged; +error: + isl_sched_graph_free(ctx, &merge_graph); + return isl_bool_error; +} + +/* Is there any edge marked "no_merge" between two SCCs that are + * about to be merged (i.e., that are set in "scc_in_merge")? + * "merge_edge" is the proximity edge along which the clusters of SCCs + * are going to be merged. + * + * If there is any edge between two SCCs with a negative weight, + * while the weight of "merge_edge" is non-negative, then this + * means that the edge was postponed. "merge_edge" should then + * also be postponed since merging along the edge with negative weight should + * be postponed until all edges with non-negative weight have been tried. + * Replace the weight of "merge_edge" by a negative weight as well and + * tell the caller not to attempt a merge. + */ +static int any_no_merge(struct isl_sched_graph *graph, int *scc_in_merge, + struct isl_sched_edge *merge_edge) +{ + int i; + + for (i = 0; i < graph->n_edge; ++i) { + struct isl_sched_edge *edge = &graph->edge[i]; + + if (!scc_in_merge[edge->src->scc]) + continue; + if (!scc_in_merge[edge->dst->scc]) + continue; + if (edge->no_merge) + return 1; + if (merge_edge->weight >= 0 && edge->weight < 0) { + merge_edge->weight -= graph->max_weight + 1; + return 1; + } + } + + return 0; +} + +/* Merge the two clusters in "c" connected by the edge in "graph" + * with index "edge" into a single cluster. + * If it turns out to be impossible to merge these two clusters, + * then mark the edge as "no_merge" such that it will not be + * considered again. + * + * First mark all SCCs that need to be merged. This includes the SCCs + * in the two clusters, but it may also include the SCCs + * of intermediate clusters. + * If there is already a no_merge edge between any pair of such SCCs, + * then simply mark the current edge as no_merge as well. + * Likewise, if any of those edges was postponed by has_bounded_distances, + * then postpone the current edge as well. + * Otherwise, try and merge the clusters and mark "edge" as "no_merge" + * if the clusters did not end up getting merged, unless the non-merge + * is due to the fact that the edge was postponed. This postponement + * can be recognized by a change in weight (from non-negative to negative). + */ +static isl_stat merge_clusters_along_edge(isl_ctx *ctx, + struct isl_sched_graph *graph, int edge, struct isl_clustering *c) +{ + isl_bool merged; + int edge_weight = graph->edge[edge].weight; + + if (mark_merge_sccs(ctx, graph, edge, c) < 0) + return isl_stat_error; + + if (any_no_merge(graph, c->scc_in_merge, &graph->edge[edge])) + merged = isl_bool_false; + else + merged = try_merge(ctx, graph, c); + if (merged < 0) + return isl_stat_error; + if (!merged && edge_weight == graph->edge[edge].weight) + graph->edge[edge].no_merge = 1; + + return isl_stat_ok; +} + +/* Does "node" belong to the cluster identified by "cluster"? + */ +static int node_cluster_exactly(struct isl_sched_node *node, int cluster) +{ + return node->cluster == cluster; +} + +/* Does "edge" connect two nodes belonging to the cluster + * identified by "cluster"? + */ +static int edge_cluster_exactly(struct isl_sched_edge *edge, int cluster) +{ + return edge->src->cluster == cluster && edge->dst->cluster == cluster; +} + +/* Swap the schedule of "node1" and "node2". + * Both nodes have been derived from the same node in a common parent graph. + * Since the "coincident" field is shared with that node + * in the parent graph, there is no need to also swap this field. + */ +static void swap_sched(struct isl_sched_node *node1, + struct isl_sched_node *node2) +{ + isl_mat *sched; + isl_map *sched_map; + + sched = node1->sched; + node1->sched = node2->sched; + node2->sched = sched; + + sched_map = node1->sched_map; + node1->sched_map = node2->sched_map; + node2->sched_map = sched_map; +} + +/* Copy the current band schedule from the SCCs that form the cluster + * with index "pos" to the actual cluster at position "pos". + * By construction, the index of the first SCC that belongs to the cluster + * is also "pos". + * + * The order of the nodes inside both the SCCs and the cluster + * is assumed to be same as the order in the original "graph". + * + * Since the SCC graphs will no longer be used after this function, + * the schedules are actually swapped rather than copied. + */ +static isl_stat copy_partial(struct isl_sched_graph *graph, + struct isl_clustering *c, int pos) +{ + int i, j; + + c->cluster[pos].n_total_row = c->scc[pos].n_total_row; + c->cluster[pos].n_row = c->scc[pos].n_row; + c->cluster[pos].maxvar = c->scc[pos].maxvar; + j = 0; + for (i = 0; i < graph->n; ++i) { + int k; + int s; + + if (graph->node[i].cluster != pos) + continue; + s = graph->node[i].scc; + k = c->scc_node[s]++; + swap_sched(&c->cluster[pos].node[j], &c->scc[s].node[k]); + if (c->scc[s].maxvar > c->cluster[pos].maxvar) + c->cluster[pos].maxvar = c->scc[s].maxvar; + ++j; + } + + return isl_stat_ok; +} + +/* Is there a (conditional) validity dependence from node[j] to node[i], + * forcing node[i] to follow node[j] or do the nodes belong to the same + * cluster? + */ +static isl_bool node_follows_strong_or_same_cluster(int i, int j, void *user) +{ + struct isl_sched_graph *graph = user; + + if (graph->node[i].cluster == graph->node[j].cluster) + return isl_bool_true; + return isl_sched_graph_has_validity_edge(graph, &graph->node[j], + &graph->node[i]); +} + +/* Extract the merged clusters of SCCs in "graph", sort them, and + * store them in c->clusters. Update c->scc_cluster accordingly. + * + * First keep track of the cluster containing the SCC to which a node + * belongs in the node itself. + * Then extract the clusters into c->clusters, copying the current + * band schedule from the SCCs that belong to the cluster. + * Do this only once per cluster. + * + * Finally, topologically sort the clusters and update c->scc_cluster + * to match the new scc numbering. While the SCCs were originally + * sorted already, some SCCs that depend on some other SCCs may + * have been merged with SCCs that appear before these other SCCs. + * A reordering may therefore be required. + */ +static isl_stat extract_clusters(isl_ctx *ctx, struct isl_sched_graph *graph, + struct isl_clustering *c) +{ + int i; + + for (i = 0; i < graph->n; ++i) + graph->node[i].cluster = c->scc_cluster[graph->node[i].scc]; + + for (i = 0; i < graph->scc; ++i) { + if (c->scc_cluster[i] != i) + continue; + if (isl_sched_graph_extract_sub_graph(ctx, graph, + &node_cluster_exactly, + &edge_cluster_exactly, i, &c->cluster[i]) < 0) + return isl_stat_error; + c->cluster[i].src_scc = -1; + c->cluster[i].dst_scc = -1; + if (copy_partial(graph, c, i) < 0) + return isl_stat_error; + } + + if (isl_sched_graph_detect_ccs(ctx, graph, + &node_follows_strong_or_same_cluster) < 0) + return isl_stat_error; + for (i = 0; i < graph->n; ++i) + c->scc_cluster[graph->node[i].scc] = graph->node[i].cluster; + + return isl_stat_ok; +} + +/* Compute weights on the proximity edges of "graph" that can + * be used by find_proximity to find the most appropriate + * proximity edge to use to merge two clusters in "c". + * The weights are also used by has_bounded_distances to determine + * whether the merge should be allowed. + * Store the maximum of the computed weights in graph->max_weight. + * + * The computed weight is a measure for the number of remaining schedule + * dimensions that can still be completely aligned. + * In particular, compute the number of equalities between + * input dimensions and output dimensions in the proximity constraints. + * The directions that are already handled by outer schedule bands + * are projected out prior to determining this number. + * + * Edges that will never be considered by find_proximity are ignored. + */ +static isl_stat compute_weights(struct isl_sched_graph *graph, + struct isl_clustering *c) +{ + int i; + + graph->max_weight = 0; + + for (i = 0; i < graph->n_edge; ++i) { + struct isl_sched_edge *edge = &graph->edge[i]; + struct isl_sched_node *src = edge->src; + struct isl_sched_node *dst = edge->dst; + isl_basic_map *hull; + isl_bool prox; + isl_size n_in, n_out, n; + + prox = is_non_empty_proximity(edge); + if (prox < 0) + return isl_stat_error; + if (!prox) + continue; + if (bad_cluster(&c->scc[edge->src->scc]) || + bad_cluster(&c->scc[edge->dst->scc])) + continue; + if (c->scc_cluster[edge->dst->scc] == + c->scc_cluster[edge->src->scc]) + continue; + + hull = isl_map_affine_hull(isl_map_copy(edge->map)); + hull = isl_basic_map_transform_dims(hull, isl_dim_in, 0, + isl_mat_copy(src->vmap)); + hull = isl_basic_map_transform_dims(hull, isl_dim_out, 0, + isl_mat_copy(dst->vmap)); + hull = isl_basic_map_project_out(hull, + isl_dim_in, 0, src->rank); + hull = isl_basic_map_project_out(hull, + isl_dim_out, 0, dst->rank); + hull = isl_basic_map_remove_divs(hull); + n_in = isl_basic_map_dim(hull, isl_dim_in); + n_out = isl_basic_map_dim(hull, isl_dim_out); + if (n_in < 0 || n_out < 0) + hull = isl_basic_map_free(hull); + hull = isl_basic_map_drop_constraints_not_involving_dims(hull, + isl_dim_in, 0, n_in); + hull = isl_basic_map_drop_constraints_not_involving_dims(hull, + isl_dim_out, 0, n_out); + n = isl_basic_map_n_equality(hull); + isl_basic_map_free(hull); + if (n < 0) + return isl_stat_error; + edge->weight = n; + + if (edge->weight > graph->max_weight) + graph->max_weight = edge->weight; + } + + return isl_stat_ok; +} + +/* Call isl_schedule_node_compute_finish_band on each of the clusters in "c" and + * update "node" to arrange for them to be executed in an order + * possibly involving set nodes that generalizes the topological order + * determined by the scc fields of the nodes in "graph". + * + * Note that at this stage, there are graph->scc clusters and + * their positions in c->cluster are determined by the values + * of c->scc_cluster. + * + * Construct an isl_scc_graph and perform the decomposition + * using this graph. + */ +static __isl_give isl_schedule_node *finish_bands_decompose( + __isl_take isl_schedule_node *node, struct isl_sched_graph *graph, + struct isl_clustering *c) +{ + isl_ctx *ctx; + struct isl_scc_graph *scc_graph; + + ctx = isl_schedule_node_get_ctx(node); + + scc_graph = isl_scc_graph_from_sched_graph(ctx, graph, c); + node = isl_scc_graph_decompose(scc_graph, node); + isl_scc_graph_free(scc_graph); + + return node; +} + +/* Call isl_schedule_node_compute_finish_band on each of the clusters in "c" + * in their topological order. This order is determined by the scc + * fields of the nodes in "graph". + * Combine the results in a sequence expressing the topological order. + * + * If there is only one cluster left, then there is no need to introduce + * a sequence node. Also, in this case, the cluster necessarily contains + * the SCC at position 0 in the original graph and is therefore also + * stored in the first cluster of "c". + * + * If there are more than two clusters left, then some subsets of the clusters + * may still be independent of each other. These could then still + * be reordered with respect to each other. Call finish_bands_decompose + * to try and construct an ordering involving set and sequence nodes + * that generalizes the topological order. + * Note that at the outermost level there can be no independent components + * because isl_schedule_node_compute_wcc_clustering is called + * on a (weakly) connected component. + */ +static __isl_give isl_schedule_node *finish_bands_clustering( + __isl_take isl_schedule_node *node, struct isl_sched_graph *graph, + struct isl_clustering *c) +{ + int i; + isl_ctx *ctx; + isl_union_set_list *filters; + + if (graph->scc == 1) + return isl_schedule_node_compute_finish_band(node, + &c->cluster[0], 0); + if (graph->scc > 2) + return finish_bands_decompose(node, graph, c); + + ctx = isl_schedule_node_get_ctx(node); + + filters = isl_sched_graph_extract_sccs(ctx, graph); + node = isl_schedule_node_insert_sequence(node, filters); + + for (i = 0; i < graph->scc; ++i) { + int j = c->scc_cluster[i]; + node = isl_schedule_node_grandchild(node, i, 0); + node = isl_schedule_node_compute_finish_band(node, + &c->cluster[j], 0); + node = isl_schedule_node_grandparent(node); + } + + return node; +} + +/* Compute a schedule for a connected dependence graph by first considering + * each strongly connected component (SCC) in the graph separately and then + * incrementally combining them into clusters. + * Return the updated schedule node. + * + * Initially, each cluster consists of a single SCC, each with its + * own band schedule. The algorithm then tries to merge pairs + * of clusters along a proximity edge until no more suitable + * proximity edges can be found. During this merging, the schedule + * is maintained in the individual SCCs. + * After the merging is completed, the full resulting clusters + * are extracted and in finish_bands_clustering, + * isl_schedule_node_compute_finish_band is called on each of them to integrate + * the band into "node" and to continue the computation. + * + * compute_weights initializes the weights that are used by find_proximity. + */ +__isl_give isl_schedule_node *isl_schedule_node_compute_wcc_clustering( + __isl_take isl_schedule_node *node, struct isl_sched_graph *graph) +{ + isl_ctx *ctx; + struct isl_clustering c; + int i; + + ctx = isl_schedule_node_get_ctx(node); + + if (clustering_init(ctx, &c, graph) < 0) + goto error; + + if (compute_weights(graph, &c) < 0) + goto error; + + for (;;) { + i = find_proximity(graph, &c); + if (i < 0) + goto error; + if (i >= graph->n_edge) + break; + if (merge_clusters_along_edge(ctx, graph, i, &c) < 0) + goto error; + } + + if (extract_clusters(ctx, graph, &c) < 0) + goto error; + + node = finish_bands_clustering(node, graph, &c); + + clustering_free(ctx, &c); + return node; +error: + clustering_free(ctx, &c); + return isl_schedule_node_free(node); +} diff --git a/external/mit/isl/dist/isl_scheduler_clustering.h b/external/mit/isl/dist/isl_scheduler_clustering.h new file mode 100644 index 000000000000..bc003267ef59 --- /dev/null +++ b/external/mit/isl/dist/isl_scheduler_clustering.h @@ -0,0 +1,39 @@ +#ifndef ISL_SCHEDULER_CLUSTERING_H +#define ISL_SCHEDULER_CLUSTERING_H + +#include "isl_scheduler.h" + +/* Clustering information used by isl_schedule_node_compute_wcc_clustering. + * + * "n" is the number of SCCs in the original dependence graph + * "scc" is an array of "n" elements, each representing an SCC + * of the original dependence graph. All entries in the same cluster + * have the same number of schedule rows. + * "scc_cluster" maps each SCC index to the cluster to which it belongs, + * where each cluster is represented by the index of the first SCC + * in the cluster. Initially, each SCC belongs to a cluster containing + * only that SCC. + * + * "scc_in_merge" is used by merge_clusters_along_edge to keep + * track of which SCCs need to be merged. + * + * "cluster" contains the merged clusters of SCCs after the clustering + * has completed. + * + * "scc_node" is a temporary data structure used inside copy_partial. + * For each SCC, it keeps track of the number of nodes in the SCC + * that have already been copied. + */ +struct isl_clustering { + int n; + struct isl_sched_graph *scc; + struct isl_sched_graph *cluster; + int *scc_cluster; + int *scc_node; + int *scc_in_merge; +}; + +__isl_give isl_schedule_node *isl_schedule_node_compute_wcc_clustering( + __isl_take isl_schedule_node *node, struct isl_sched_graph *graph); + +#endif diff --git a/external/mit/isl/dist/isl_scheduler_scc.c b/external/mit/isl/dist/isl_scheduler_scc.c new file mode 100644 index 000000000000..ffbcfe25dea4 --- /dev/null +++ b/external/mit/isl/dist/isl_scheduler_scc.c @@ -0,0 +1,1209 @@ +/* + * Copyright 2021 Sven Verdoolaege + * + * Use of this software is governed by the MIT license + * + * Written by Sven Verdoolaege + */ + +#include + +#include +#include +#include + +#include "isl_hash_private.h" +#include "isl_scheduler_scc.h" +#include "isl_sort.h" + +/* Internal data structure for ordering the SCCs of "graph", + * where each SCC i consists of the single cluster determined + * by c->scc_cluster[i]. The nodes in this cluster all have + * their "scc" field set to i. + * + * "graph" is the original schedule graph. + * "c" contains the clustering information. + * + * "n" is the number of SCCs in the isl_scc_graph, which may be + * a subset of those in "graph". + * "graph_scc" maps the local index of an SCC in this isl_scc_graph + * to the corresponding index in "graph", i.e, the index of c->scc_cluster. + * The entries of "graph_scc" are kept in topological order. + * + * "component" contains the component to which an SCC belongs, + * where the component is represented by the index of the first SCC + * in the component. + * The index of this first SCC is always smaller than or equal + * to the index of the SCC itself. + * This field is initialized by isl_scc_graph_init_component and + * used by detect_components. + * During construction, "component" may also contain the index + * of some other SCC in the component, but then it is necessarily + * smaller than the index of the current SCC and the first SCC + * can be reached by recursively looking up "component". + * "size" contains the number of elements in the components + * indexed by a component sequence number. + * + * "pos" is used locally inside isl_scc_graph_sort_components + * to store the position of the next SCC within a component. + * It is also used inside isl_scc_graph_sub to map + * the position in the original graph to the position in the subgraph. + * + * "sorted" contains the (possibly) reordered local indices, + * sorted per component. Within each component, the original + * topological order is preserved. + * + * "edge_table" contains "n" edge tables, one for each SCC + * in this isl_scc_graph. Each table contains the local indices + * of the SCCs that depend on this SCC. These local indices + * are encoded as pointers to the corresponding entry in "graph_scc". + * The value stored at that location is the global SCC index. + * "reverse_edge_table" contains the inverse edges. + */ +struct isl_scc_graph { + isl_ctx *ctx; + struct isl_sched_graph *graph; + struct isl_clustering *c; + + int n; + int *graph_scc; + int *component; + int *size; + int *pos; + int *sorted; + struct isl_hash_table **edge_table; + struct isl_hash_table **reverse_edge_table; +}; + +/* The source SCC of a collection of edges. + * + * "scc_graph" is the SCC graph containing the edges. + * "src" is the local index of the source SCC. + */ +struct isl_edge_src { + struct isl_scc_graph *scc_graph; + int src; +}; + +/* isl_hash_table_foreach callback for printing an edge + * between "src" and the node identified by "entry". + * The edge is printed in terms of the global SCC indices. + */ +static isl_stat print_edge(void **entry, void *user) +{ + int *dst = *entry; + int *src = user; + + fprintf(stderr, "%d -> %d; ", *src, *dst); + + return isl_stat_ok; +} + +/* Print some debugging information about "scc_graph". + * + * In particular, print the nodes and the edges (both forward and backward). + */ +void isl_scc_graph_dump(struct isl_scc_graph *scc_graph) +{ + int i; + isl_ctx *ctx; + + if (!scc_graph) + return; + + ctx = scc_graph->ctx; + for (i = 0; i < scc_graph->n; ++i) { + if (i) + fprintf(stderr, ", "); + fprintf(stderr, "%d", scc_graph->graph_scc[i]); + } + fprintf(stderr, "\n"); + for (i = 0; i < scc_graph->n; ++i) { + isl_hash_table_foreach(ctx, scc_graph->edge_table[i], + &print_edge, &scc_graph->graph_scc[i]); + } + fprintf(stderr, "\n"); + for (i = 0; i < scc_graph->n; ++i) { + isl_hash_table_foreach(ctx, scc_graph->reverse_edge_table[i], + &print_edge, &scc_graph->graph_scc[i]); + } + fprintf(stderr, "\n"); +} + +/* Free all memory allocated for "scc_graph" and return NULL. + */ +struct isl_scc_graph *isl_scc_graph_free(struct isl_scc_graph *scc_graph) +{ + int i; + isl_ctx *ctx; + + if (!scc_graph) + return NULL; + + ctx = scc_graph->ctx; + if (scc_graph->edge_table) { + for (i = 0; i < scc_graph->n; ++i) + isl_hash_table_free(ctx, scc_graph->edge_table[i]); + } + if (scc_graph->reverse_edge_table) { + for (i = 0; i < scc_graph->n; ++i) + isl_hash_table_free(ctx, + scc_graph->reverse_edge_table[i]); + } + + free(scc_graph->graph_scc); + free(scc_graph->component); + free(scc_graph->size); + free(scc_graph->pos); + free(scc_graph->sorted); + free(scc_graph->edge_table); + free(scc_graph->reverse_edge_table); + isl_ctx_deref(scc_graph->ctx); + free(scc_graph); + return NULL; +} + +/* Return an encoding of the local SCC index "pos" in "scc_graph" + * as a pointer. + * In particular, return a pointer to the corresponding entry + * in scc_graph->graph_scc. + */ +static void *isl_scc_graph_encode_local_index(struct isl_scc_graph *scc_graph, + int pos) +{ + return &scc_graph->graph_scc[pos]; +} + +/* Return the local SCC index in "scc_graph" corresponding + * to the "data" encoding in the edge table. + */ +static int isl_scc_graph_local_index(struct isl_scc_graph *scc_graph, int *data) +{ + return data - &scc_graph->graph_scc[0]; +} + +/* isl_hash_table_find callback to check whether the given entry + * refers to an SCC encoded as "val". + */ +static isl_bool is_scc_node(const void *entry, const void *val) +{ + return entry == val; +} + +/* Return the edge from local SCC index "src" to local SCC index "dst" + * in "edge_table" of "scc_graph", creating one if "reserve" is set. + * If "reserve" is not set, then return isl_hash_table_entry_none + * if there is no such edge. + * + * The destination of the edge is encoded as a pointer + * to the corresponding entry in scc_graph->graph_scc. + */ +struct isl_hash_table_entry *isl_scc_graph_find_edge( + struct isl_scc_graph *scc_graph, struct isl_hash_table **edge_table, + int src, int dst, int reserve) +{ + isl_ctx *ctx; + uint32_t hash; + void *val; + + ctx = scc_graph->ctx; + hash = isl_hash_builtin(isl_hash_init(), dst); + val = isl_scc_graph_encode_local_index(scc_graph, dst); + return isl_hash_table_find(ctx, edge_table[src], hash, + &is_scc_node, val, reserve); +} + +/* Remove the edge between the SCCs with local indices "src" and + * "dst" in "scc_graph", if it exits. + * Return isl_bool_true if this is the case. + * + * The edge is only removed from scc_graph->edge_table. + * scc_graph->reverse_edge_table is assumed to be empty + * when this function is called. + */ +static isl_bool isl_scc_graph_remove_edge(struct isl_scc_graph *scc_graph, + int src, int dst) +{ + isl_ctx *ctx; + struct isl_hash_table_entry *edge_entry; + + edge_entry = isl_scc_graph_find_edge(scc_graph, scc_graph->edge_table, + src, dst, 0); + if (edge_entry == isl_hash_table_entry_none) + return isl_bool_false; + if (!edge_entry) + return isl_bool_error; + + ctx = scc_graph->ctx; + isl_hash_table_remove(ctx, scc_graph->edge_table[src], edge_entry); + + return isl_bool_true; +} + +/* Internal data structure used by next_nodes. + * + * "scc_graph" is the SCC graph. + * "next" collects the next nodes. + * "n" is the number of next nodes already collected. + */ +struct isl_extract_dst_data { + struct isl_scc_graph *scc_graph; + int *next; + int n; +}; + +/* Given an entry in the edge table, add the corresponding + * target local SCC index to data->next. + */ +static isl_stat extract_dst(void **entry, void *user) +{ + int *dst = *entry; + struct isl_extract_dst_data *data = user; + + data->next[data->n++] = isl_scc_graph_local_index(data->scc_graph, dst); + + return isl_stat_ok; +} + +/* isl_sort callback for sorting integers in increasing order. + */ +static int cmp_int(const void *a, const void *b, void *data) +{ + const int *i1 = a; + const int *i2 = b; + + return *i1 - *i2; +} + +/* Return the local indices of the SCCs in "scc_graph" + * for which there is an edge from the SCC with local index "i". + * The indices are returned in increasing order, + * i.e., in the original topological order. + */ +static int *next_nodes(struct isl_scc_graph *scc_graph, int i) +{ + struct isl_extract_dst_data data; + int n_next; + int *next; + + n_next = scc_graph->edge_table[i]->n; + next = isl_alloc_array(scc_graph->ctx, int, n_next); + if (!next) + return NULL; + data.scc_graph = scc_graph; + data.next = next; + data.n = 0; + if (isl_hash_table_foreach(scc_graph->ctx, scc_graph->edge_table[i], + &extract_dst, &data) < 0) + goto error; + if (isl_sort(next, n_next, sizeof(int), &cmp_int, NULL) < 0) + goto error; + return next; +error: + free(next); + return NULL; +} + +/* Internal data structure for foreach_reachable. + * + * "scc_graph" is the SCC graph being visited. + * "fn" is the function that needs to be called on each reachable node. + * "user" is the user argument to "fn". + */ +struct isl_foreach_reachable_data { + struct isl_scc_graph *scc_graph; + isl_bool (*fn)(int pos, void *user); + void *user; +}; + +static isl_stat foreach_reachable(struct isl_foreach_reachable_data *data, + int pos); + +/* isl_hash_table_foreach callback for calling data->fn on each SCC + * reachable from the SCC encoded in "entry", + * continuing from an SCC as long as data->fn returns isl_bool_true. + */ +static isl_stat recurse_foreach_reachable(void **entry, void *user) +{ + struct isl_foreach_reachable_data *data = user; + int pos; + isl_bool more; + + pos = isl_scc_graph_local_index(data->scc_graph, *entry); + more = data->fn(pos, data->user); + if (more < 0) + return isl_stat_error; + if (!more) + return isl_stat_ok; + + return foreach_reachable(data, pos); +} + +/* Call data->fn on each SCC reachable from the SCC with local index "pos", + * continuing from an SCC as long as data->fn returns isl_bool_true. + * + * Handle chains directly and recurse when an SCC has more than one + * outgoing edge. + */ +static isl_stat foreach_reachable(struct isl_foreach_reachable_data *data, + int pos) +{ + isl_ctx *ctx; + struct isl_hash_table **edge_table = data->scc_graph->edge_table; + + while (edge_table[pos]->n == 1) { + struct isl_hash_table_entry *entry; + isl_bool more; + + entry = isl_hash_table_first(edge_table[pos]); + pos = isl_scc_graph_local_index(data->scc_graph, entry->data); + more = data->fn(pos, data->user); + if (more < 0) + return isl_stat_error; + if (!more) + return isl_stat_ok; + } + + if (edge_table[pos]->n == 0) + return isl_stat_ok; + + ctx = data->scc_graph->ctx; + return isl_hash_table_foreach(ctx, edge_table[pos], + &recurse_foreach_reachable, data); +} + +/* If there is an edge from data->src to "pos", then remove it. + * Return isl_bool_true if descendants of "pos" still need to be considered. + * + * Descendants only need to be considered if no edge is removed. + */ +static isl_bool elim_or_next(int pos, void *user) +{ + struct isl_edge_src *data = user; + struct isl_scc_graph *scc_graph = data->scc_graph; + isl_bool removed; + + removed = isl_scc_graph_remove_edge(scc_graph, data->src, pos); + return isl_bool_not(removed); +} + +/* Remove transitive edges from "scc_graph". + * + * Consider the SCC nodes "i" in reverse topological order. + * If there is more than one edge emanating from a node, + * then eliminate the edges to those nodes that can also be reached + * through an edge to a node with a smaller index. + * In particular, consider all but the last next nodes "next[j]" + * in reverse topological order. If any node "k" can be reached + * from such a node for which there is also an edge from "i" + * then this edge can be removed because this node can also + * be reached from "i" through the edge to "next[j]". + * If such an edge is removed, then any further descendant of "k" + * does not need to be considered since these were already considered + * for a previous "next[j]" equal to "k", or "k" is the last next node, + * in which case there is no further node with an edge from "i". + */ +static struct isl_scc_graph *isl_scc_graph_reduce( + struct isl_scc_graph *scc_graph) +{ + struct isl_edge_src elim_data; + struct isl_foreach_reachable_data data = { + .scc_graph = scc_graph, + .fn = &elim_or_next, + .user = &elim_data, + }; + int i, j; + + elim_data.scc_graph = scc_graph; + for (i = scc_graph->n - 3; i >= 0; --i) { + int *next; + int n_next; + + n_next = scc_graph->edge_table[i]->n; + if (n_next <= 1) + continue; + next = next_nodes(scc_graph, i); + if (!next) + return isl_scc_graph_free(scc_graph); + + elim_data.src = i; + for (j = n_next - 2; j >= 0; --j) + if (foreach_reachable(&data, next[j]) < 0) + break; + free(next); + if (j >= 0) + return isl_scc_graph_free(scc_graph); + } + + return scc_graph; +} + +/* Add an edge to "edge_table" between the SCCs with local indices "src" and + * "dst" in "scc_graph". + * + * If the edge already appeared in the table, then it is simply overwritten + * with the same information. + */ +static isl_stat isl_scc_graph_add_edge(struct isl_scc_graph *scc_graph, + struct isl_hash_table **edge_table, int src, int dst) +{ + struct isl_hash_table_entry *edge_entry; + + edge_entry = + isl_scc_graph_find_edge(scc_graph, edge_table, src, dst, 1); + if (!edge_entry) + return isl_stat_error; + edge_entry->data = &scc_graph->graph_scc[dst]; + + return isl_stat_ok; +} + +/* Add an edge from "dst" to data->src + * to data->scc_graph->reverse_edge_table. + */ +static isl_stat add_reverse(void **entry, void *user) +{ + struct isl_edge_src *data = user; + int dst; + + dst = isl_scc_graph_local_index(data->scc_graph, *entry); + return isl_scc_graph_add_edge(data->scc_graph, + data->scc_graph->reverse_edge_table, dst, data->src); +} + +/* Add an (inverse) edge to scc_graph->reverse_edge_table + * for each edge in scc_graph->edge_table. + */ +static struct isl_scc_graph *isl_scc_graph_add_reverse_edges( + struct isl_scc_graph *scc_graph) +{ + struct isl_edge_src data; + isl_ctx *ctx; + + if (!scc_graph) + return NULL; + + ctx = scc_graph->ctx; + data.scc_graph = scc_graph; + for (data.src = 0; data.src < scc_graph->n; ++data.src) { + if (isl_hash_table_foreach(ctx, scc_graph->edge_table[data.src], + &add_reverse, &data) < 0) + return isl_scc_graph_free(scc_graph); + } + return scc_graph; +} + +/* Given an edge in the schedule graph, add an edge between + * the corresponding SCCs in "scc_graph", if they are distinct. + * + * This function is used to create edges in the original isl_scc_graph. + * where the local SCC indices are equal to the corresponding global + * indices. + */ +static isl_stat add_scc_edge(void **entry, void *user) +{ + struct isl_sched_edge *edge = *entry; + struct isl_scc_graph *scc_graph = user; + int src = edge->src->scc; + int dst = edge->dst->scc; + + if (src == dst) + return isl_stat_ok; + + return isl_scc_graph_add_edge(scc_graph, scc_graph->edge_table, + src, dst); +} + +/* Allocate an isl_scc_graph for ordering "n" SCCs of "graph" + * with clustering information in "c". + * + * The caller still needs to fill in the edges. + */ +static struct isl_scc_graph *isl_scc_graph_alloc(isl_ctx *ctx, int n, + struct isl_sched_graph *graph, struct isl_clustering *c) +{ + int i; + struct isl_scc_graph *scc_graph; + + scc_graph = isl_alloc_type(ctx, struct isl_scc_graph); + if (!scc_graph) + return NULL; + + scc_graph->ctx = ctx; + isl_ctx_ref(ctx); + scc_graph->graph = graph; + scc_graph->c = c; + + scc_graph->n = n; + scc_graph->graph_scc = isl_alloc_array(ctx, int, n); + scc_graph->component = isl_alloc_array(ctx, int, n); + scc_graph->size = isl_alloc_array(ctx, int, n); + scc_graph->pos = isl_alloc_array(ctx, int, n); + scc_graph->sorted = isl_alloc_array(ctx, int, n); + scc_graph->edge_table = + isl_calloc_array(ctx, struct isl_hash_table *, n); + scc_graph->reverse_edge_table = + isl_calloc_array(ctx, struct isl_hash_table *, n); + if (!scc_graph->graph_scc || !scc_graph->component || + !scc_graph->size || !scc_graph->pos || !scc_graph->sorted || + !scc_graph->edge_table || !scc_graph->reverse_edge_table) + return isl_scc_graph_free(scc_graph); + + for (i = 0; i < n; ++i) { + scc_graph->edge_table[i] = isl_hash_table_alloc(ctx, 2); + scc_graph->reverse_edge_table[i] = isl_hash_table_alloc(ctx, 2); + if (!scc_graph->edge_table[i] || + !scc_graph->reverse_edge_table[i]) + return isl_scc_graph_free(scc_graph); + } + + return scc_graph; +} + +/* Construct an isl_scc_graph for ordering the SCCs of "graph", + * where each SCC i consists of the single cluster determined + * by c->scc_cluster[i]. The nodes in this cluster all have + * their "scc" field set to i. + * + * The initial isl_scc_graph has as many SCCs as "graph" and + * their local indices are the same as their indices in "graph". + * + * Add edges between different SCCs for each (conditional) validity edge + * between nodes in those SCCs, remove transitive edges and + * construct the inverse edges from the remaining forward edges. + */ +struct isl_scc_graph *isl_scc_graph_from_sched_graph(isl_ctx *ctx, + struct isl_sched_graph *graph, struct isl_clustering *c) +{ + int i; + struct isl_scc_graph *scc_graph; + + scc_graph = isl_scc_graph_alloc(ctx, graph->scc, graph, c); + if (!scc_graph) + return NULL; + + for (i = 0; i < graph->scc; ++i) + scc_graph->graph_scc[i] = i; + + if (isl_hash_table_foreach(ctx, graph->edge_table[isl_edge_validity], + &add_scc_edge, scc_graph) < 0) + return isl_scc_graph_free(scc_graph); + if (isl_hash_table_foreach(ctx, + graph->edge_table[isl_edge_conditional_validity], + &add_scc_edge, scc_graph) < 0) + return isl_scc_graph_free(scc_graph); + + scc_graph = isl_scc_graph_reduce(scc_graph); + scc_graph = isl_scc_graph_add_reverse_edges(scc_graph); + + return scc_graph; +} + +/* Internal data structure for copy_edge. + * + * "scc_graph" is the original graph. + * "sub" is the subgraph to which edges are being copied. + * "src" is the local index in "scc_graph" of the source of the edges + * currently being copied. + */ +struct isl_copy_edge_data { + struct isl_scc_graph *scc_graph; + struct isl_scc_graph *sub; + int src; +}; + +/* isl_hash_table_foreach callback for copying the edge + * from data->src to the node identified by "entry" + * to data->sub, provided the two nodes belong to the same component. + * Note that by construction, there are no edges between different components + * in the region handled by detect_components, but there may + * be edges to nodes outside this region. + * The components therefore need to be initialized for all nodes + * in isl_scc_graph_init_component. + */ +static isl_stat copy_edge(void **entry, void *user) +{ + struct isl_copy_edge_data *data = user; + struct isl_scc_graph *scc_graph = data->scc_graph; + struct isl_scc_graph *sub = data->sub; + int dst, sub_dst, sub_src; + + dst = isl_scc_graph_local_index(data->scc_graph, *entry); + if (scc_graph->component[dst] != scc_graph->component[data->src]) + return isl_stat_ok; + + sub_src = scc_graph->pos[data->src]; + sub_dst = scc_graph->pos[dst]; + + return isl_scc_graph_add_edge(sub, sub->edge_table, sub_src, sub_dst); +} + +/* Construct a subgraph of "scc_graph" for the components + * consisting of the "n" SCCs with local indices in "pos". + * These SCCs have the same value in scc_graph->component and + * this value is different from that of any other SCC. + * + * The forward edges with source and destination in the component + * are copied from "scc_graph". + * The local index in the subgraph corresponding to a local index + * in "scc_graph" is stored in scc_graph->pos for use by copy_edge(). + * The inverse edges are constructed directly from the forward edges. + */ +static struct isl_scc_graph *isl_scc_graph_sub(struct isl_scc_graph *scc_graph, + int *pos, int n) +{ + int i; + isl_ctx *ctx; + struct isl_scc_graph *sub; + struct isl_copy_edge_data data; + + if (!scc_graph) + return NULL; + + ctx = scc_graph->ctx; + sub = isl_scc_graph_alloc(ctx, n, scc_graph->graph, scc_graph->c); + if (!sub) + return sub; + + for (i = 0; i < n; ++i) + sub->graph_scc[i] = scc_graph->graph_scc[pos[i]]; + + for (i = 0; i < n; ++i) + scc_graph->pos[pos[i]] = i; + + data.scc_graph = scc_graph; + data.sub = sub; + for (i = 0; i < n; ++i) { + data.src = pos[i]; + if (isl_hash_table_foreach(ctx, scc_graph->edge_table[pos[i]], + ©_edge, &data) < 0) + return isl_scc_graph_free(sub); + } + + sub = isl_scc_graph_add_reverse_edges(sub); + + return sub; +} + +/* Return a union of universe domains corresponding to the nodes + * in the SCC with local index "pos". + */ +static __isl_give isl_union_set *isl_scc_graph_extract_local_scc( + struct isl_scc_graph *scc_graph, int pos) +{ + return isl_sched_graph_extract_scc(scc_graph->ctx, scc_graph->graph, + scc_graph->graph_scc[pos]); +} + +/* Construct a filter corresponding to a sequence of "n" local SCC indices + * determined by successive calls to "el", + * add this filter to "list" and + * return the result. + */ +static __isl_give isl_union_set_list *add_scc_seq( + struct isl_scc_graph *scc_graph, + int (*el)(int i, void *user), void *user, int n, + __isl_take isl_union_set_list *list) +{ + int i; + isl_union_set *dom; + + dom = isl_union_set_empty_ctx(scc_graph->ctx); + for (i = 0; i < n; ++i) + dom = isl_union_set_union(dom, + isl_scc_graph_extract_local_scc(scc_graph, el(i, user))); + + return isl_union_set_list_add(list, dom); +} + +/* add_scc_seq callback that, on successive calls, returns a sequence + * of local SCC indices starting at "first". + */ +static int offset(int i, void *user) +{ + int *first = user; + + return *first + i; +} + +/* Construct a filter corresponding to a sequence of "n" local SCC indices + * starting at "first", add this filter to "list" and return the result. + */ +static __isl_give isl_union_set_list *isl_scc_graph_add_scc_seq( + struct isl_scc_graph *scc_graph, int first, int n, + __isl_take isl_union_set_list *list) +{ + return add_scc_seq(scc_graph, &offset, &first, n, list); +} + +/* add_scc_seq callback that, on successive calls, returns the sequence + * of local SCC indices in "seq". + */ +static int at(int i, void *user) +{ + int *seq = user; + + return seq[i]; +} + +/* Construct a filter corresponding to the sequence of "n" local SCC indices + * stored in "seq", add this filter to "list" and return the result. + */ +static __isl_give isl_union_set_list *isl_scc_graph_add_scc_indirect_seq( + struct isl_scc_graph *scc_graph, int *seq, int n, + __isl_take isl_union_set_list *list) +{ + return add_scc_seq(scc_graph, &at, seq, n, list); +} + +/* Extract out a list of filters for a sequence node that splits + * the graph along the SCC with local index "pos". + * + * The list contains (at most) three elements, + * the SCCs before "pos" (in the topological order), + * "pos" itself, and + * the SCCs after "pos". + */ +static __isl_give isl_union_set_list *extract_split_scc( + struct isl_scc_graph *scc_graph, int pos) +{ + isl_union_set *dom; + isl_union_set_list *filters; + + filters = isl_union_set_list_alloc(scc_graph->ctx, 3); + if (pos > 0) + filters = isl_scc_graph_add_scc_seq(scc_graph, 0, pos, filters); + dom = isl_scc_graph_extract_local_scc(scc_graph, pos); + filters = isl_union_set_list_add(filters, dom); + if (pos + 1 < scc_graph->n) + filters = isl_scc_graph_add_scc_seq(scc_graph, + pos + 1, scc_graph->n - (pos + 1), filters); + return filters; +} + +/* Call isl_schedule_node_compute_finish_band on the cluster + * corresponding to the SCC with local index "pos". + * + * First obtain the corresponding SCC index in scc_graph->graph and + * then obtain the corresponding cluster. + */ +static __isl_give isl_schedule_node *isl_scc_graph_finish_band( + struct isl_scc_graph *scc_graph, __isl_take isl_schedule_node *node, + int pos) +{ + struct isl_clustering *c = scc_graph->c; + int cluster; + + cluster = c->scc_cluster[scc_graph->graph_scc[pos]]; + return isl_schedule_node_compute_finish_band(node, + &c->cluster[cluster], 0); +} + +/* Given that the SCCs in "scc_graph" form a chain, + * call isl_schedule_node_compute_finish_band on each of the clusters + * in scc_graph->c and update "node" to arrange for them to be executed + * in topological order. + */ +static __isl_give isl_schedule_node *isl_scc_graph_chain( + struct isl_scc_graph *scc_graph, __isl_take isl_schedule_node *node) +{ + int i; + isl_union_set *dom; + isl_union_set_list *filters; + + filters = isl_union_set_list_alloc(scc_graph->ctx, scc_graph->n); + for (i = 0; i < scc_graph->n; ++i) { + dom = isl_scc_graph_extract_local_scc(scc_graph, i); + filters = isl_union_set_list_add(filters, dom); + } + + node = isl_schedule_node_insert_sequence(node, filters); + + for (i = 0; i < scc_graph->n; ++i) { + node = isl_schedule_node_grandchild(node, i, 0); + node = isl_scc_graph_finish_band(scc_graph, node, i); + node = isl_schedule_node_grandparent(node); + } + + return node; +} + +/* Recursively call isl_scc_graph_decompose on a subgraph + * consisting of the "n" SCCs with local indices in "pos". + * + * If this component contains only a single SCC, + * then there is no need for a further recursion and + * isl_schedule_node_compute_finish_band can be called directly. + */ +static __isl_give isl_schedule_node *recurse(struct isl_scc_graph *scc_graph, + int *pos, int n, __isl_take isl_schedule_node *node) +{ + struct isl_scc_graph *sub; + + if (n == 1) + return isl_scc_graph_finish_band(scc_graph, node, pos[0]); + + sub = isl_scc_graph_sub(scc_graph, pos, n); + if (!sub) + return isl_schedule_node_free(node); + node = isl_scc_graph_decompose(sub, node); + isl_scc_graph_free(sub); + + return node; +} + +/* Initialize the component field of "scc_graph". + * Initially, each SCC belongs to its own single-element component. + * + * Note that the SCC on which isl_scc_graph_decompose performs a split + * also needs to be assigned a component because the components + * are also used in copy_edge to extract a subgraph. + */ +static void isl_scc_graph_init_component(struct isl_scc_graph *scc_graph) +{ + int i; + + for (i = 0; i < scc_graph->n; ++i) + scc_graph->component[i] = i; +} + +/* Set the component of "a" to be the same as that of "b" and + * return the original component of "a". + */ +static int assign(int *component, int a, int b) +{ + int t; + + t = component[a]; + component[a] = component[b]; + return t; +} + +/* Merge the components containing the SCCs with indices "a" and "b". + * + * If "a" and "b" already belong to the same component, then nothing + * needs to be done. + * Otherwise, make sure both point to the same component. + * In particular, use the SCC in the component entries with the smallest index. + * If the other SCC was the first of its component then the entire + * component now (eventually) points to the other component. + * Otherwise, the earlier parts of the component still need + * to be merged with the other component. + * + * At each stage, either a or b is replaced by either a or b itself, + * in which case the merging terminates because a and b already + * point to the same component, or an SCC index with a smaller value. + * This ensures the merging terminates at some point. + */ +static void isl_scc_graph_merge_src_dst(struct isl_scc_graph *scc_graph, + int a, int b) +{ + int *component = scc_graph->component; + + while (component[a] != component[b]) { + if (component[a] < component[b]) + b = assign(component, b, a); + else + a = assign(component, a, b); + } +} + +/* Internal data structure for isl_scc_graph_merge_components. + * + * "scc_graph" is the SCC graph containing the edges. + * "src" is the local index of the source SCC. + * "end" is the local index beyond the sequence being considered. + */ +struct isl_merge_src_dst_data { + struct isl_scc_graph *scc_graph; + int src; + int end; +}; + +/* isl_hash_table_foreach callback for merging the components + * of data->src and the node represented by "entry", provided + * it is within the sequence being considered. + */ +static isl_stat merge_src_dst(void **entry, void *user) +{ + struct isl_merge_src_dst_data *data = user; + int dst; + + dst = isl_scc_graph_local_index(data->scc_graph, *entry); + if (dst >= data->end) + return isl_stat_ok; + + isl_scc_graph_merge_src_dst(data->scc_graph, data->src, dst); + + return isl_stat_ok; +} + +/* Merge components of the "n" SCCs starting at "first" that are connected + * by an edge. + */ +static isl_stat isl_scc_graph_merge_components(struct isl_scc_graph *scc_graph, + int first, int n) +{ + int i; + struct isl_merge_src_dst_data data; + isl_ctx *ctx = scc_graph->ctx; + + data.scc_graph = scc_graph; + data.end = first + n; + for (i = 0; i < n; ++i) { + data.src = first + i; + if (isl_hash_table_foreach(ctx, scc_graph->edge_table[data.src], + &merge_src_dst, &data) < 0) + return isl_stat_error; + } + + return isl_stat_ok; +} + +/* Sort the "n" local SCC indices starting at "first" according + * to component, store them in scc_graph->sorted and + * return the number of components. + * The sizes of the components are stored in scc_graph->size. + * Only positions starting at "first" are used within + * scc_graph->sorted and scc_graph->size. + * + * The representation of the components is first normalized. + * The normalization ensures that each SCC in a component + * points to the first SCC in the component, whereas + * before this function is called, some SCCs may only point + * to some other SCC in the component with a smaller index. + * + * Internally, the sizes of the components are first stored + * at indices corresponding to the first SCC in the component. + * They are subsequently moved into consecutive positions + * while reordering the local indices. + * This reordering is performed by first determining the position + * of the first SCC in each component and + * then putting the "n" local indices in the right position + * according to the component, preserving the topological order + * within each component. + */ +static int isl_scc_graph_sort_components(struct isl_scc_graph *scc_graph, + int first, int n) +{ + int i, j; + int sum; + int *component = scc_graph->component; + int *size = scc_graph->size; + int *pos = scc_graph->pos; + int *sorted = scc_graph->sorted; + int n_component; + + n_component = 0; + for (i = 0; i < n; ++i) { + size[first + i] = 0; + if (component[first + i] == first + i) + n_component++; + else + component[first + i] = component[component[first + i]]; + size[component[first + i]]++; + } + + sum = first; + i = 0; + for (j = 0; j < n_component; ++j) { + while (size[first + i] == 0) + ++i; + pos[first + i] = sum; + sum += size[first + i]; + size[first + j] = size[first + i++]; + } + for (i = 0; i < n; ++i) + sorted[pos[component[first + i]]++] = first + i; + + return n_component; +} + +/* Extract out a list of filters for a set node that splits up + * the graph into "n_component" components. + * "first" is the initial position in "scc_graph" where information + * about the components is stored. + * In particular, the first "n_component" entries of scc_graph->size + * at this position contain the number of SCCs in each component. + * The entries of scc_graph->sorted starting at "first" + * contain the local indices of the SCC in those components. + */ +static __isl_give isl_union_set_list *extract_components( + struct isl_scc_graph *scc_graph, int first, int n_component) +{ + int i; + int sum; + int *size = scc_graph->size; + int *sorted = scc_graph->sorted; + isl_ctx *ctx = scc_graph->ctx; + isl_union_set_list *filters; + + filters = isl_union_set_list_alloc(ctx, n_component); + sum = first; + for (i = 0; i < n_component; ++i) { + int n; + + n = size[first + i]; + filters = isl_scc_graph_add_scc_indirect_seq(scc_graph, + &sorted[sum], n, filters); + sum += n; + } + + return filters; +} + +/* Detect components in the subgraph consisting of the "n" SCCs + * with local index starting at "first" and further decompose them, + * calling isl_schedule_node_compute_finish_band on each + * of the corresponding clusters. + * + * If there is only one SCC, then isl_schedule_node_compute_finish_band + * can be called directly. + * Otherwise, determine the components and rearrange the local indices + * according to component, but preserving the topological order within + * each component, in scc_graph->sorted. The sizes of the components + * are stored in scc_graph->size. + * If there is only one component, it can be further decomposed + * directly by a call to recurse(). + * Otherwise, introduce a set node separating the components and + * call recurse() on each component separately. + */ +static __isl_give isl_schedule_node *detect_components( + struct isl_scc_graph *scc_graph, int first, int n, + __isl_take isl_schedule_node *node) +{ + int i; + int *size = scc_graph->size; + int *sorted = scc_graph->sorted; + int n_component; + int sum; + isl_union_set_list *filters; + + if (n == 1) + return isl_scc_graph_finish_band(scc_graph, node, first); + + if (isl_scc_graph_merge_components(scc_graph, first, n) < 0) + return isl_schedule_node_free(node); + + n_component = isl_scc_graph_sort_components(scc_graph, first, n); + if (n_component == 1) + return recurse(scc_graph, &sorted[first], n, node); + + filters = extract_components(scc_graph, first, n_component); + node = isl_schedule_node_insert_set(node, filters); + + sum = first; + for (i = 0; i < n_component; ++i) { + int n; + + n = size[first + i]; + node = isl_schedule_node_grandchild(node, i, 0); + node = recurse(scc_graph, &sorted[sum], n, node); + node = isl_schedule_node_grandparent(node); + sum += n; + } + + return node; +} + +/* Given a sequence node "node", where the filter at position "child" + * represents the "n" SCCs with local index starting at "first", + * detect components in this subgraph and further decompose them, + * calling isl_schedule_node_compute_finish_band on each + * of the corresponding clusters. + */ +static __isl_give isl_schedule_node *detect_components_at( + struct isl_scc_graph *scc_graph, int first, int n, + __isl_take isl_schedule_node *node, int child) +{ + node = isl_schedule_node_grandchild(node, child, 0); + node = detect_components(scc_graph, first, n, node); + node = isl_schedule_node_grandparent(node); + + return node; +} + +/* Return the local index of an SCC on which to split "scc_graph". + * Return scc_graph->n if no suitable split SCC can be found. + * + * In particular, look for an SCC that is involved in the largest number + * of edges. Splitting the graph on such an SCC has the highest chance + * of exposing independent SCCs in the remaining part(s). + * There is no point in splitting a chain of nodes, + * so return scc_graph->n if the entire graph forms a chain. + */ +static int best_split(struct isl_scc_graph *scc_graph) +{ + int i; + int split = scc_graph->n; + int split_score = -1; + + for (i = 0; i < scc_graph->n; ++i) { + int n_fwd, n_bwd; + + n_fwd = scc_graph->edge_table[i]->n; + n_bwd = scc_graph->reverse_edge_table[i]->n; + if (n_fwd <= 1 && n_bwd <= 1) + continue; + if (split_score >= n_fwd + n_bwd) + continue; + split = i; + split_score = n_fwd + n_bwd; + } + + return split; +} + +/* Call isl_schedule_node_compute_finish_band on each of the clusters + * in scc_graph->c and update "node" to arrange for them to be executed + * in an order possibly involving set nodes that generalizes + * the topological order determined by the scc fields of the nodes + * in scc_graph->graph. + * + * First try and find a suitable SCC on which to split the graph. + * If no such SCC can be found then the graph forms a chain and + * it is handled as such. + * Otherwise, break up the graph into (at most) three parts, + * the SCCs before the selected SCC (in the topological order), + * the selected SCC itself, and + * the SCCs after the selected SCC. + * The first and last part (if they exist) are decomposed recursively and + * the three parts are combined in a sequence. + * + * Since the outermost node of the recursive pieces may also be a sequence, + * these potential sequence nodes are spliced into the top-level sequence node. + */ +__isl_give isl_schedule_node *isl_scc_graph_decompose( + struct isl_scc_graph *scc_graph, __isl_take isl_schedule_node *node) +{ + int i; + int split; + isl_union_set_list *filters; + + if (!scc_graph) + return isl_schedule_node_free(node); + + split = best_split(scc_graph); + + if (split == scc_graph->n) + return isl_scc_graph_chain(scc_graph, node); + + filters = extract_split_scc(scc_graph, split); + node = isl_schedule_node_insert_sequence(node, filters); + + isl_scc_graph_init_component(scc_graph); + + i = 0; + if (split > 0) + node = detect_components_at(scc_graph, 0, split, node, i++); + node = isl_schedule_node_grandchild(node, i++, 0); + node = isl_scc_graph_finish_band(scc_graph, node, split); + node = isl_schedule_node_grandparent(node); + if (split + 1 < scc_graph->n) + node = detect_components_at(scc_graph, + split + 1, scc_graph->n - (split + 1), node, i++); + + node = isl_schedule_node_sequence_splice_children(node); + + return node; +} diff --git a/external/mit/isl/dist/isl_scheduler_scc.h b/external/mit/isl/dist/isl_scheduler_scc.h new file mode 100644 index 000000000000..e92c5e163f7e --- /dev/null +++ b/external/mit/isl/dist/isl_scheduler_scc.h @@ -0,0 +1,19 @@ +#ifndef ISL_SCHEDULER_SCC_H +#define ISL_SCHEDULER_SCC_H + +#include + +#include "isl_scheduler.h" +#include "isl_scheduler_clustering.h" + +struct isl_scc_graph; + +struct isl_scc_graph *isl_scc_graph_from_sched_graph(isl_ctx *ctx, + struct isl_sched_graph *graph, struct isl_clustering *c); +__isl_give isl_schedule_node *isl_scc_graph_decompose( + struct isl_scc_graph *scc_graph, __isl_take isl_schedule_node *node); +struct isl_scc_graph *isl_scc_graph_free(struct isl_scc_graph *scc_graph); + +void isl_scc_graph_dump(struct isl_scc_graph *scc_graph); + +#endif diff --git a/external/mit/isl/dist/isl_seq.c b/external/mit/isl/dist/isl_seq.c new file mode 100644 index 000000000000..fb2100edc9cc --- /dev/null +++ b/external/mit/isl/dist/isl_seq.c @@ -0,0 +1,363 @@ +/* + * Copyright 2008-2009 Katholieke Universiteit Leuven + * Copyright 2011 INRIA Saclay + * + * 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 + */ + +#include +#include + +void isl_seq_clr(isl_int *p, unsigned len) +{ + int i; + for (i = 0; i < len; ++i) + isl_int_set_si(p[i], 0); +} + +void isl_seq_set_si(isl_int *p, int v, unsigned len) +{ + int i; + for (i = 0; i < len; ++i) + isl_int_set_si(p[i], v); +} + +void isl_seq_set(isl_int *p, isl_int v, unsigned len) +{ + int i; + for (i = 0; i < len; ++i) + isl_int_set(p[i], v); +} + +void isl_seq_neg(isl_int *dst, isl_int *src, unsigned len) +{ + int i; + for (i = 0; i < len; ++i) + isl_int_neg(dst[i], src[i]); +} + +void isl_seq_cpy(isl_int *dst, isl_int *src, unsigned len) +{ + int i; + for (i = 0; i < len; ++i) + isl_int_set(dst[i], src[i]); +} + +void isl_seq_submul(isl_int *dst, isl_int f, isl_int *src, unsigned len) +{ + int i; + for (i = 0; i < len; ++i) + isl_int_submul(dst[i], f, src[i]); +} + +void isl_seq_addmul(isl_int *dst, isl_int f, isl_int *src, unsigned len) +{ + int i; + for (i = 0; i < len; ++i) + isl_int_addmul(dst[i], f, src[i]); +} + +void isl_seq_swp_or_cpy(isl_int *dst, isl_int *src, unsigned len) +{ + int i; + for (i = 0; i < len; ++i) + isl_int_swap_or_set(dst[i], src[i]); +} + +void isl_seq_scale(isl_int *dst, isl_int *src, isl_int m, unsigned len) +{ + int i; + for (i = 0; i < len; ++i) + isl_int_mul(dst[i], src[i], m); +} + +void isl_seq_scale_down(isl_int *dst, isl_int *src, isl_int m, unsigned len) +{ + int i; + for (i = 0; i < len; ++i) + isl_int_divexact(dst[i], src[i], m); +} + +void isl_seq_cdiv_q(isl_int *dst, isl_int *src, isl_int m, unsigned len) +{ + int i; + for (i = 0; i < len; ++i) + isl_int_cdiv_q(dst[i], src[i], m); +} + +void isl_seq_fdiv_q(isl_int *dst, isl_int *src, isl_int m, unsigned len) +{ + int i; + for (i = 0; i < len; ++i) + isl_int_fdiv_q(dst[i], src[i], m); +} + +void isl_seq_fdiv_r(isl_int *dst, isl_int *src, isl_int m, unsigned len) +{ + int i; + for (i = 0; i < len; ++i) + isl_int_fdiv_r(dst[i], src[i], m); +} + +void isl_seq_combine(isl_int *dst, isl_int m1, isl_int *src1, + isl_int m2, isl_int *src2, unsigned len) +{ + int i; + isl_int tmp; + + if (dst == src1 && isl_int_is_one(m1)) { + if (isl_int_is_zero(m2)) + return; + for (i = 0; i < len; ++i) + isl_int_addmul(src1[i], m2, src2[i]); + return; + } + + isl_int_init(tmp); + for (i = 0; i < len; ++i) { + isl_int_mul(tmp, m1, src1[i]); + isl_int_addmul(tmp, m2, src2[i]); + isl_int_set(dst[i], tmp); + } + isl_int_clear(tmp); +} + +/* Eliminate element "pos" from "dst" using "src". + * In particular, let d = dst[pos] and s = src[pos], then + * dst is replaced by (|s| dst - sgn(s)d src)/gcd(s,d), + * such that dst[pos] is zero after the elimination. + * If "m" is not NULL, then *m is multiplied by |s|/gcd(s,d). + * That is, it is multiplied by the same factor as "dst". + */ +void isl_seq_elim(isl_int *dst, isl_int *src, unsigned pos, unsigned len, + isl_int *m) +{ + isl_int a; + isl_int b; + + if (isl_int_is_zero(dst[pos])) + return; + + isl_int_init(a); + isl_int_init(b); + + isl_int_gcd(a, src[pos], dst[pos]); + isl_int_divexact(b, dst[pos], a); + if (isl_int_is_pos(src[pos])) + isl_int_neg(b, b); + isl_int_divexact(a, src[pos], a); + isl_int_abs(a, a); + isl_seq_combine(dst, a, dst, b, src, len); + + if (m) + isl_int_mul(*m, *m, a); + + isl_int_clear(a); + isl_int_clear(b); +} + +int isl_seq_eq(isl_int *p1, isl_int *p2, unsigned len) +{ + int i; + for (i = 0; i < len; ++i) + if (isl_int_ne(p1[i], p2[i])) + return 0; + return 1; +} + +int isl_seq_cmp(isl_int *p1, isl_int *p2, unsigned len) +{ + int i; + int cmp; + for (i = 0; i < len; ++i) + if ((cmp = isl_int_cmp(p1[i], p2[i])) != 0) + return cmp; + return 0; +} + +int isl_seq_is_neg(isl_int *p1, isl_int *p2, unsigned len) +{ + int i; + + for (i = 0; i < len; ++i) { + if (isl_int_abs_ne(p1[i], p2[i])) + return 0; + if (isl_int_is_zero(p1[i])) + continue; + if (isl_int_eq(p1[i], p2[i])) + return 0; + } + return 1; +} + +int isl_seq_first_non_zero(isl_int *p, unsigned len) +{ + int i; + + for (i = 0; i < len; ++i) + if (!isl_int_is_zero(p[i])) + return i; + return -1; +} + +int isl_seq_last_non_zero(isl_int *p, unsigned len) +{ + int i; + + for (i = len - 1; i >= 0; --i) + if (!isl_int_is_zero(p[i])) + return i; + return -1; +} + +void isl_seq_abs_max(isl_int *p, unsigned len, isl_int *max) +{ + int i; + + isl_int_set_si(*max, 0); + + for (i = 0; i < len; ++i) + if (isl_int_abs_gt(p[i], *max)) + isl_int_abs(*max, p[i]); +} + +int isl_seq_abs_min_non_zero(isl_int *p, unsigned len) +{ + int i, min = isl_seq_first_non_zero(p, len); + if (min < 0) + return -1; + for (i = min + 1; i < len; ++i) { + if (isl_int_is_zero(p[i])) + continue; + if (isl_int_abs_lt(p[i], p[min])) + min = i; + } + return min; +} + +void isl_seq_gcd(isl_int *p, unsigned len, isl_int *gcd) +{ + int i, min = isl_seq_abs_min_non_zero(p, len); + + if (min < 0) { + isl_int_set_si(*gcd, 0); + return; + } + isl_int_abs(*gcd, p[min]); + for (i = 0; isl_int_cmp_si(*gcd, 1) > 0 && i < len; ++i) { + if (i == min) + continue; + if (isl_int_is_zero(p[i])) + continue; + isl_int_gcd(*gcd, *gcd, p[i]); + } +} + +void isl_seq_normalize(struct isl_ctx *ctx, isl_int *p, unsigned len) +{ + if (len == 0) + return; + isl_seq_gcd(p, len, &ctx->normalize_gcd); + if (!isl_int_is_zero(ctx->normalize_gcd) && + !isl_int_is_one(ctx->normalize_gcd)) + isl_seq_scale_down(p, p, ctx->normalize_gcd, len); +} + +void isl_seq_lcm(isl_int *p, unsigned len, isl_int *lcm) +{ + int i; + + if (len == 0) { + isl_int_set_si(*lcm, 1); + return; + } + isl_int_set(*lcm, p[0]); + for (i = 1; i < len; ++i) + isl_int_lcm(*lcm, *lcm, p[i]); +} + +void isl_seq_inner_product(isl_int *p1, isl_int *p2, unsigned len, + isl_int *prod) +{ + int i; + if (len == 0) { + isl_int_set_si(*prod, 0); + return; + } + isl_int_mul(*prod, p1[0], p2[0]); + for (i = 1; i < len; ++i) + isl_int_addmul(*prod, p1[i], p2[i]); +} + +uint32_t isl_seq_hash(isl_int *p, unsigned len, uint32_t hash) +{ + int i; + for (i = 0; i < len; ++i) { + if (isl_int_is_zero(p[i])) + continue; + hash *= 16777619; + hash ^= (i & 0xFF); + hash = isl_int_hash(p[i], hash); + } + return hash; +} + +/* Given two affine expressions "p" of length p_len (including the + * denominator and the constant term) and "subs" of length subs_len, + * plug in "subs" for the variable at position "pos". + * The variables of "subs" and "p" are assumed to match up to subs_len, + * but "p" may have additional variables. + * "v" is an initialized isl_int that can be used internally. + * + * In particular, if "p" represents the expression + * + * (a i + g)/m + * + * with i the variable at position "pos" and "subs" represents the expression + * + * f/d + * + * then the result represents the expression + * + * (a f + d g)/(m d) + * + */ +void isl_seq_substitute(isl_int *p, int pos, isl_int *subs, + int p_len, int subs_len, isl_int v) +{ + isl_int_set(v, p[1 + pos]); + isl_int_set_si(p[1 + pos], 0); + isl_seq_combine(p + 1, subs[0], p + 1, v, subs + 1, subs_len - 1); + isl_seq_scale(p + subs_len, p + subs_len, subs[0], p_len - subs_len); + isl_int_mul(p[0], p[0], subs[0]); +} + +uint32_t isl_seq_get_hash(isl_int *p, unsigned len) +{ + uint32_t hash = isl_hash_init(); + + return isl_seq_hash(p, len, hash); +} + +uint32_t isl_seq_get_hash_bits(isl_int *p, unsigned len, unsigned bits) +{ + uint32_t hash; + + hash = isl_seq_get_hash(p, len); + return isl_hash_bits(hash, bits); +} + +void isl_seq_dump(isl_int *p, unsigned len) +{ + int i; + + for (i = 0; i < len; ++i) { + if (i) + fprintf(stderr, " "); + isl_int_print(stderr, p[i], 0); + } + fprintf(stderr, "\n"); +} diff --git a/external/mit/isl/dist/isl_seq.h b/external/mit/isl/dist/isl_seq.h new file mode 100644 index 000000000000..de0d2e6e0484 --- /dev/null +++ b/external/mit/isl/dist/isl_seq.h @@ -0,0 +1,63 @@ +/* + * 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_SEQ_H +#define ISL_SEQ_H + +#include +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +/* Some common operations on sequences of isl_int's */ + +void isl_seq_clr(isl_int *p, unsigned len); +void isl_seq_set(isl_int *p, isl_int v, unsigned len); +void isl_seq_set_si(isl_int *p, int v, unsigned len); +void isl_seq_neg(isl_int *dst, isl_int *src, unsigned len); +void isl_seq_cpy(isl_int *dst, isl_int *src, unsigned len); +void isl_seq_addmul(isl_int *dst, isl_int f, isl_int *src, unsigned len); +void isl_seq_submul(isl_int *dst, isl_int f, isl_int *src, unsigned len); +void isl_seq_swp_or_cpy(isl_int *dst, isl_int *src, unsigned len); +void isl_seq_scale(isl_int *dst, isl_int *src, isl_int f, unsigned len); +void isl_seq_scale_down(isl_int *dst, isl_int *src, isl_int f, unsigned len); +void isl_seq_cdiv_q(isl_int *dst, isl_int *src, isl_int m, unsigned len); +void isl_seq_fdiv_q(isl_int *dst, isl_int *src, isl_int m, unsigned len); +void isl_seq_fdiv_r(isl_int *dst, isl_int *src, isl_int m, unsigned len); +void isl_seq_combine(isl_int *dst, isl_int m1, isl_int *src1, + isl_int m2, isl_int *src2, unsigned len); +void isl_seq_elim(isl_int *dst, isl_int *src, unsigned pos, unsigned len, + isl_int *m); +void isl_seq_abs_max(isl_int *p, unsigned len, isl_int *max); +void isl_seq_gcd(isl_int *p, unsigned len, isl_int *gcd); +void isl_seq_lcm(isl_int *p, unsigned len, isl_int *lcm); +void isl_seq_normalize(struct isl_ctx *ctx, isl_int *p, unsigned len); +void isl_seq_inner_product(isl_int *p1, isl_int *p2, unsigned len, + isl_int *prod); +int isl_seq_first_non_zero(isl_int *p, unsigned len); +int isl_seq_last_non_zero(isl_int *p, unsigned len); +int isl_seq_abs_min_non_zero(isl_int *p, unsigned len); +int isl_seq_eq(isl_int *p1, isl_int *p2, unsigned len); +int isl_seq_cmp(isl_int *p1, isl_int *p2, unsigned len); +int isl_seq_is_neg(isl_int *p1, isl_int *p2, unsigned len); + +void isl_seq_substitute(isl_int *p, int pos, isl_int *subs, + int p_len, int subs_len, isl_int v); + +uint32_t isl_seq_get_hash(isl_int *p, unsigned len); +uint32_t isl_seq_get_hash_bits(isl_int *p, unsigned len, unsigned bits); + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/external/mit/isl/dist/isl_set_list.c b/external/mit/isl/dist/isl_set_list.c new file mode 100644 index 000000000000..e1bbcaf5685c --- /dev/null +++ b/external/mit/isl/dist/isl_set_list.c @@ -0,0 +1,34 @@ +#include +#include + +#undef EL +#define EL isl_basic_set + +#include + +#undef EL +#define EL isl_set + +#include + +#undef EL +#define EL isl_union_set + +#include + +#undef EL_BASE +#define EL_BASE basic_set + +#include + +#undef EL_BASE +#define EL_BASE set + +#include +#include + +#undef EL_BASE +#define EL_BASE union_set + +#include +#include diff --git a/external/mit/isl/dist/isl_set_to_ast_graft_list.c b/external/mit/isl/dist/isl_set_to_ast_graft_list.c new file mode 100644 index 000000000000..6067821ee29a --- /dev/null +++ b/external/mit/isl/dist/isl_set_to_ast_graft_list.c @@ -0,0 +1,21 @@ +#include +#include +#include "isl_ast_graft_private.h" +#include "isl_set_to_ast_graft_list.h" + +#define isl_ast_graft_list_is_identical(a, b) isl_bool_ok(a == b) + +#define ISL_KEY isl_set +#define ISL_VAL isl_ast_graft_list +#define ISL_HMAP_SUFFIX set_to_ast_graft_list +#define ISL_HMAP isl_set_to_ast_graft_list +#define ISL_HMAP_IS_EQUAL isl_set_to_ast_graft_list_plain_is_equal +#define ISL_KEY_IS_EQUAL isl_set_plain_is_equal +#define ISL_VAL_IS_EQUAL isl_ast_graft_list_is_identical +#define ISL_KEY_PRINT isl_printer_print_set +#define ISL_VAL_PRINT isl_printer_print_ast_graft_list +#define ISL_HMAP_HAVE_READ_FROM_STR +#define ISL_KEY_READ isl_stream_read_set +#define ISL_VAL_READ isl_stream_read_ast_graft_list + +#include diff --git a/external/mit/isl/dist/isl_set_to_ast_graft_list.h b/external/mit/isl/dist/isl_set_to_ast_graft_list.h new file mode 100644 index 000000000000..cca3cbb5c480 --- /dev/null +++ b/external/mit/isl/dist/isl_set_to_ast_graft_list.h @@ -0,0 +1,22 @@ +#ifndef ISL_SET_TO_GRAFT_LIST_H +#define ISL_SET_TO_GRAFT_LIST_H + +#include +#include "isl_ast_graft_private.h" +#include "isl_maybe_ast_graft_list.h" + +#define ISL_KEY isl_set +#define ISL_VAL isl_ast_graft_list +#define ISL_HMAP_SUFFIX set_to_ast_graft_list +#define ISL_HMAP isl_set_to_ast_graft_list +#define ISL_HMAP_HAVE_READ_FROM_STR +#define ISL_HMAP_IS_EQUAL isl_set_to_ast_graft_list_plain_is_equal +#include +#undef ISL_KEY +#undef ISL_VAL +#undef ISL_HMAP_SUFFIX +#undef ISL_HMAP +#undef ISL_HMAP_HAVE_READ_FROM_STR +#undef ISL_HMAP_IS_EQUAL + +#endif diff --git a/external/mit/isl/dist/isl_sort.c b/external/mit/isl/dist/isl_sort.c new file mode 100644 index 000000000000..9ed273caa18b --- /dev/null +++ b/external/mit/isl/dist/isl_sort.c @@ -0,0 +1,157 @@ +/* + * The code of this file was taken from http://jeffreystedfast.blogspot.be, + * where it was posted in 2011 by Jeffrey Stedfast under the MIT license. + * The MIT license text is as follows: + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include +#include +#include +#include + +#define MID(lo, hi) (lo + ((hi - lo) >> 1)) + +/* The code here is an optimized merge sort. Starting from a generic merge sort + * the following optimizations were applied: + * + * o Batching of memcpy() calls: Instead of calling memcpy() to copy each and + * every element into a temporary buffer, blocks of elements are copied + * at a time. + * + * o To reduce the number of memcpy() calls further, copying leading + * and trailing elements into our temporary buffer is avoided, in case it is + * not necessary to merge them. + * + * A further optimization could be to specialize memcpy calls based on the + * size of the types we compare. For now, this code does not include the + * relevant optimization, as clang e.g. inlines a very efficient memcpy() + * implementation. It is not clear, that the specialized version as provided in + * the blog post, is really superior to the one that will be inlined by + * default. So we decided to keep the code simple until this optimization was + * proven to be beneficial. + */ + +static void +msort (void *array, void *buf, size_t low, size_t high, size_t size, + int (* compare) (const void *, const void *, void *), void *arg) +{ + char *a1, *al, *am, *ah, *ls, *hs, *lo, *hi, *b; + size_t copied = 0; + size_t mid; + + mid = MID (low, high); + + if (mid + 1 < high) + msort (array, buf, mid + 1, high, size, compare, arg); + + if (mid > low) + msort (array, buf, low, mid, size, compare, arg); + + ah = ((char *) array) + ((high + 1) * size); + am = ((char *) array) + ((mid + 1) * size); + a1 = al = ((char *) array) + (low * size); + + b = (char *) buf; + lo = al; + hi = am; + + do { + ls = lo; + hs = hi; + + if (lo > al || hi > am) { + /* our last loop already compared lo & hi and found lo <= hi */ + lo += size; + } + + while (lo < am && compare (lo, hi, arg) <= 0) + lo += size; + + if (lo < am) { + if (copied == 0) { + /* avoid copying the leading items */ + a1 = lo; + ls = lo; + } + + /* our last compare tells us hi < lo */ + hi += size; + + while (hi < ah && compare (hi, lo, arg) < 0) + hi += size; + + if (lo > ls) { + memcpy (b, ls, lo - ls); + copied += (lo - ls); + b += (lo - ls); + } + + memcpy (b, hs, hi - hs); + copied += (hi - hs); + b += (hi - hs); + } else if (copied) { + memcpy (b, ls, lo - ls); + copied += (lo - ls); + b += (lo - ls); + + /* copy everything we needed to re-order back into array */ + memcpy (a1, buf, copied); + return; + } else { + /* everything already in order */ + return; + } + } while (hi < ah); + + if (lo < am) { + memcpy (b, lo, am - lo); + copied += (am - lo); + } + + memcpy (a1, buf, copied); +} + +static int +MergeSort (void *base, size_t nmemb, size_t size, + int (* compare) (const void *, const void *, void *), void *arg) +{ + void *tmp; + + if (nmemb < 2) + return 0; + + if (!(tmp = malloc (nmemb * size))) { + errno = ENOMEM; + return -1; + } + + msort (base, tmp, 0, nmemb - 1, size, compare, arg); + + free (tmp); + + return 0; +} + +int isl_sort(void *const pbase, size_t total_elems, size_t size, + int (*cmp)(const void *, const void *, void *arg), void *arg) +{ + return MergeSort (pbase, total_elems, size, cmp, arg); +} diff --git a/external/mit/isl/dist/isl_sort.h b/external/mit/isl/dist/isl_sort.h new file mode 100644 index 000000000000..b69fe01d9919 --- /dev/null +++ b/external/mit/isl/dist/isl_sort.h @@ -0,0 +1,9 @@ +#ifndef ISL_SORT_H +#define ISL_SORT_H + +#include + +int isl_sort(void *const pbase, size_t total_elems, size_t size, + int (*cmp)(const void *, const void *, void *arg), void *arg); + +#endif diff --git a/external/mit/isl/dist/isl_space.c b/external/mit/isl/dist/isl_space.c new file mode 100644 index 000000000000..f7d882d2b9f1 --- /dev/null +++ b/external/mit/isl/dist/isl_space.c @@ -0,0 +1,3476 @@ +/* + * Copyright 2008-2009 Katholieke Universiteit Leuven + * Copyright 2010 INRIA Saclay + * Copyright 2013-2014 Ecole Normale Superieure + * Copyright 2018-2019 Cerebras Systems + * + * 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 + * and Cerebras Systems, 175 S San Antonio Rd, Los Altos, CA, USA + */ + +#include +#include +#include +#include +#include + +isl_ctx *isl_space_get_ctx(__isl_keep isl_space *space) +{ + return space ? space->ctx : NULL; +} + +__isl_give isl_space *isl_space_alloc(isl_ctx *ctx, + unsigned nparam, unsigned n_in, unsigned n_out) +{ + isl_space *space; + + space = isl_alloc_type(ctx, struct isl_space); + if (!space) + return NULL; + + space->ctx = ctx; + isl_ctx_ref(ctx); + space->ref = 1; + space->nparam = nparam; + space->n_in = n_in; + space->n_out = n_out; + + space->tuple_id[0] = NULL; + space->tuple_id[1] = NULL; + + space->nested[0] = NULL; + space->nested[1] = NULL; + + space->n_id = 0; + space->ids = NULL; + + return space; +} + +/* Mark the space as being that of a set, by setting the domain tuple + * to isl_id_none. + */ +static __isl_give isl_space *mark_as_set(__isl_take isl_space *space) +{ + space = isl_space_cow(space); + if (!space) + return NULL; + space = isl_space_set_tuple_id(space, isl_dim_in, &isl_id_none); + return space; +} + +/* Is the space that of a set? + */ +isl_bool isl_space_is_set(__isl_keep isl_space *space) +{ + if (!space) + return isl_bool_error; + if (space->n_in != 0 || space->nested[0]) + return isl_bool_false; + if (space->tuple_id[0] != &isl_id_none) + return isl_bool_false; + return isl_bool_true; +} + +/* Check that "space" is a set space. + */ +isl_stat isl_space_check_is_set(__isl_keep isl_space *space) +{ + isl_bool is_set; + + is_set = isl_space_is_set(space); + if (is_set < 0) + return isl_stat_error; + if (!is_set) + isl_die(isl_space_get_ctx(space), isl_error_invalid, + "space is not a set", return isl_stat_error); + return isl_stat_ok; +} + +/* Is the given space that of a map? + */ +isl_bool isl_space_is_map(__isl_keep isl_space *space) +{ + int r; + + if (!space) + return isl_bool_error; + r = space->tuple_id[0] != &isl_id_none && + space->tuple_id[1] != &isl_id_none; + return isl_bool_ok(r); +} + +/* Check that "space" is the space of a map. + */ +static isl_stat isl_space_check_is_map(__isl_keep isl_space *space) +{ + isl_bool is_space; + + is_space = isl_space_is_map(space); + if (is_space < 0) + return isl_stat_error; + if (!is_space) + isl_die(isl_space_get_ctx(space), isl_error_invalid, + "expecting map space", return isl_stat_error); + return isl_stat_ok; +} + +/* Check that "space" is the space of a set wrapping a map space. + */ +isl_stat isl_space_check_is_wrapping(__isl_keep isl_space *space) +{ + isl_bool wrapping; + + wrapping = isl_space_is_wrapping(space); + if (wrapping < 0) + return isl_stat_error; + if (!wrapping) + isl_die(isl_space_get_ctx(space), isl_error_invalid, + "not a product", return isl_stat_error); + return isl_stat_ok; +} + +/* Check that "space" is the space of a map + * where the domain is a wrapped map space. + */ +isl_stat isl_space_check_domain_is_wrapping(__isl_keep isl_space *space) +{ + isl_bool wrapping; + + wrapping = isl_space_domain_is_wrapping(space); + if (wrapping < 0) + return isl_stat_error; + if (!wrapping) + isl_die(isl_space_get_ctx(space), isl_error_invalid, + "domain not a product", return isl_stat_error); + return isl_stat_ok; +} + +/* Check that "space" is the space of a map + * where the range is a wrapped map space. + */ +isl_stat isl_space_check_range_is_wrapping(__isl_keep isl_space *space) +{ + isl_bool wrapping; + + wrapping = isl_space_range_is_wrapping(space); + if (wrapping < 0) + return isl_stat_error; + if (!wrapping) + isl_die(isl_space_get_ctx(space), isl_error_invalid, + "range not a product", return isl_stat_error); + return isl_stat_ok; +} + +__isl_give isl_space *isl_space_set_alloc(isl_ctx *ctx, + unsigned nparam, unsigned dim) +{ + isl_space *space; + space = isl_space_alloc(ctx, nparam, 0, dim); + space = mark_as_set(space); + return space; +} + +/* Mark the space as being that of a parameter domain, by setting + * both tuples to isl_id_none. + */ +static __isl_give isl_space *mark_as_params(isl_space *space) +{ + if (!space) + return NULL; + space = isl_space_set_tuple_id(space, isl_dim_in, &isl_id_none); + space = isl_space_set_tuple_id(space, isl_dim_out, &isl_id_none); + return space; +} + +/* Is the space that of a parameter domain? + */ +isl_bool isl_space_is_params(__isl_keep isl_space *space) +{ + if (!space) + return isl_bool_error; + if (space->n_in != 0 || space->nested[0] || + space->n_out != 0 || space->nested[1]) + return isl_bool_false; + if (space->tuple_id[0] != &isl_id_none) + return isl_bool_false; + if (space->tuple_id[1] != &isl_id_none) + return isl_bool_false; + return isl_bool_true; +} + +/* Create a space for a parameter domain. + */ +__isl_give isl_space *isl_space_params_alloc(isl_ctx *ctx, unsigned nparam) +{ + isl_space *space; + space = isl_space_alloc(ctx, nparam, 0, 0); + space = mark_as_params(space); + return space; +} + +/* Create a space for a parameter domain, without any parameters. + */ +__isl_give isl_space *isl_space_unit(isl_ctx *ctx) +{ + return isl_space_params_alloc(ctx, 0); +} + +static isl_size global_pos(__isl_keep isl_space *space, + enum isl_dim_type type, unsigned pos) +{ + if (isl_space_check_range(space, type, pos, 1) < 0) + return isl_size_error; + + switch (type) { + case isl_dim_param: + return pos; + case isl_dim_in: + return pos + space->nparam; + case isl_dim_out: + return pos + space->nparam + space->n_in; + default: + isl_assert(isl_space_get_ctx(space), 0, return isl_size_error); + } + return isl_size_error; +} + +/* Extend length of ids array to the total number of dimensions. + */ +static __isl_give isl_space *extend_ids(__isl_take isl_space *space) +{ + isl_id **ids; + int i; + isl_size dim; + + dim = isl_space_dim(space, isl_dim_all); + if (dim < 0) + return isl_space_free(space); + if (dim <= space->n_id) + return space; + + if (!space->ids) { + space->ids = isl_calloc_array(space->ctx, isl_id *, dim); + if (!space->ids) + goto error; + } else { + ids = isl_realloc_array(space->ctx, space->ids, isl_id *, dim); + if (!ids) + goto error; + space->ids = ids; + for (i = space->n_id; i < dim; ++i) + space->ids[i] = NULL; + } + + space->n_id = dim; + + return space; +error: + isl_space_free(space); + return NULL; +} + +static __isl_give isl_space *set_id(__isl_take isl_space *space, + enum isl_dim_type type, unsigned pos, __isl_take isl_id *id) +{ + isl_size gpos; + + space = isl_space_cow(space); + + gpos = global_pos(space, type, pos); + if (gpos < 0) + goto error; + + if (gpos >= space->n_id) { + if (!id) + return space; + space = extend_ids(space); + if (!space) + goto error; + } + + space->ids[gpos] = id; + + return space; +error: + isl_id_free(id); + isl_space_free(space); + return NULL; +} + +static __isl_keep isl_id *get_id(__isl_keep isl_space *space, + enum isl_dim_type type, unsigned pos) +{ + isl_size gpos; + + gpos = global_pos(space, type, pos); + if (gpos < 0) + return NULL; + if (gpos >= space->n_id) + return NULL; + return space->ids[gpos]; +} + +/* Return the nested space at the given position. + */ +static __isl_keep isl_space *isl_space_peek_nested(__isl_keep isl_space *space, + int pos) +{ + if (!space) + return NULL; + if (!space->nested[pos]) + isl_die(isl_space_get_ctx(space), isl_error_invalid, + "no nested space", return NULL); + return space->nested[pos]; +} + +static unsigned offset(__isl_keep isl_space *space, enum isl_dim_type type) +{ + switch (type) { + case isl_dim_param: return 0; + case isl_dim_in: return space->nparam; + case isl_dim_out: return space->nparam + space->n_in; + default: return 0; + } +} + +static unsigned n(__isl_keep isl_space *space, enum isl_dim_type type) +{ + switch (type) { + case isl_dim_param: return space->nparam; + case isl_dim_in: return space->n_in; + case isl_dim_out: return space->n_out; + case isl_dim_all: + return space->nparam + space->n_in + space->n_out; + default: return 0; + } +} + +isl_size isl_space_dim(__isl_keep isl_space *space, enum isl_dim_type type) +{ + if (!space) + return isl_size_error; + return n(space, type); +} + +/* Return the dimensionality of tuple "inner" within the wrapped relation + * inside tuple "outer". + */ +isl_size isl_space_wrapped_dim(__isl_keep isl_space *space, + enum isl_dim_type outer, enum isl_dim_type inner) +{ + int pos; + + if (!space) + return isl_size_error; + if (outer != isl_dim_in && outer != isl_dim_out) + isl_die(isl_space_get_ctx(space), isl_error_invalid, + "only input, output and set tuples " + "can have nested relations", return isl_size_error); + pos = outer - isl_dim_in; + return isl_space_dim(isl_space_peek_nested(space, pos), inner); +} + +isl_size isl_space_offset(__isl_keep isl_space *space, enum isl_dim_type type) +{ + if (!space) + return isl_size_error; + return offset(space, type); +} + +static __isl_give isl_space *copy_ids(__isl_take isl_space *dst, + enum isl_dim_type dst_type, unsigned offset, __isl_keep isl_space *src, + enum isl_dim_type src_type) +{ + int i; + isl_id *id; + + if (!dst) + return NULL; + + for (i = 0; i < n(src, src_type); ++i) { + id = get_id(src, src_type, i); + if (!id) + continue; + isl_id_free(get_id(dst, dst_type, offset + i)); + dst = set_id(dst, dst_type, offset + i, isl_id_copy(id)); + if (!dst) + return NULL; + } + return dst; +} + +__isl_give isl_space *isl_space_dup(__isl_keep isl_space *space) +{ + isl_space *dup; + if (!space) + return NULL; + dup = isl_space_alloc(space->ctx, + space->nparam, space->n_in, space->n_out); + if (!dup) + return NULL; + if (space->tuple_id[0] && + !(dup->tuple_id[0] = isl_id_copy(space->tuple_id[0]))) + goto error; + if (space->tuple_id[1] && + !(dup->tuple_id[1] = isl_id_copy(space->tuple_id[1]))) + goto error; + if (space->nested[0] && + !(dup->nested[0] = isl_space_copy(space->nested[0]))) + goto error; + if (space->nested[1] && + !(dup->nested[1] = isl_space_copy(space->nested[1]))) + goto error; + if (!space->ids) + return dup; + dup = copy_ids(dup, isl_dim_param, 0, space, isl_dim_param); + dup = copy_ids(dup, isl_dim_in, 0, space, isl_dim_in); + dup = copy_ids(dup, isl_dim_out, 0, space, isl_dim_out); + return dup; +error: + isl_space_free(dup); + return NULL; +} + +__isl_give isl_space *isl_space_cow(__isl_take isl_space *space) +{ + if (!space) + return NULL; + + if (space->ref == 1) + return space; + space->ref--; + return isl_space_dup(space); +} + +__isl_give isl_space *isl_space_copy(__isl_keep isl_space *space) +{ + if (!space) + return NULL; + + space->ref++; + return space; +} + +__isl_null isl_space *isl_space_free(__isl_take isl_space *space) +{ + int i; + + if (!space) + return NULL; + + if (--space->ref > 0) + return NULL; + + isl_id_free(space->tuple_id[0]); + isl_id_free(space->tuple_id[1]); + + isl_space_free(space->nested[0]); + isl_space_free(space->nested[1]); + + for (i = 0; i < space->n_id; ++i) + isl_id_free(space->ids[i]); + free(space->ids); + isl_ctx_deref(space->ctx); + + free(space); + + return NULL; +} + +/* Check if "s" is a valid dimension or tuple name. + * We currently only forbid names that look like a number. + * + * s is assumed to be non-NULL. + */ +static int name_ok(isl_ctx *ctx, const char *s) +{ + char *p; + + strtol(s, &p, 0); + if (p != s) + isl_die(ctx, isl_error_invalid, "name looks like a number", + return 0); + + return 1; +} + +/* Return a copy of the nested space at the given position. + */ +static __isl_keep isl_space *isl_space_get_nested(__isl_keep isl_space *space, + int pos) +{ + return isl_space_copy(isl_space_peek_nested(space, pos)); +} + +/* Return the nested space at the given position. + * This may be either a copy or the nested space itself + * if there is only one reference to "space". + * This allows the nested space to be modified inplace + * if both "space" and the nested space have only a single reference. + * The caller is not allowed to modify "space" between this call and + * a subsequent call to isl_space_restore_nested. + * The only exception is that isl_space_free can be called instead. + */ +static __isl_give isl_space *isl_space_take_nested(__isl_keep isl_space *space, + int pos) +{ + isl_space *nested; + + if (!space) + return NULL; + if (space->ref != 1) + return isl_space_get_nested(space, pos); + nested = space->nested[pos]; + space->nested[pos] = NULL; + return nested; +} + +/* Replace the nested space at the given position by "nested", + * where this nested space of "space" may be missing + * due to a preceding call to isl_space_take_nested. + * However, in this case, "space" only has a single reference and + * then the call to isl_space_cow has no effect. + */ +static __isl_give isl_space *isl_space_restore_nested( + __isl_take isl_space *space, int pos, __isl_take isl_space *nested) +{ + if (!space || !nested) + goto error; + + if (space->nested[pos] == nested) { + isl_space_free(nested); + return space; + } + + space = isl_space_cow(space); + if (!space) + goto error; + isl_space_free(space->nested[pos]); + space->nested[pos] = nested; + + return space; +error: + isl_space_free(space); + isl_space_free(nested); + return NULL; +} + +/* Is it possible for the given dimension type to have a tuple id? + */ +static int space_can_have_id(__isl_keep isl_space *space, + enum isl_dim_type type) +{ + if (!space) + return 0; + if (isl_space_is_params(space)) + isl_die(space->ctx, isl_error_invalid, + "parameter spaces don't have tuple ids", return 0); + if (isl_space_is_set(space) && type != isl_dim_set) + isl_die(space->ctx, isl_error_invalid, + "set spaces can only have a set id", return 0); + if (type != isl_dim_in && type != isl_dim_out) + isl_die(space->ctx, isl_error_invalid, + "only input, output and set tuples can have ids", + return 0); + + return 1; +} + +/* Does the tuple have an id? + */ +isl_bool isl_space_has_tuple_id(__isl_keep isl_space *space, + enum isl_dim_type type) +{ + if (!space_can_have_id(space, type)) + return isl_bool_error; + return isl_bool_ok(space->tuple_id[type - isl_dim_in] != NULL); +} + +/* Does the domain tuple of the map space "space" have an identifier? + */ +isl_bool isl_space_has_domain_tuple_id(__isl_keep isl_space *space) +{ + if (isl_space_check_is_map(space) < 0) + return isl_bool_error; + return isl_space_has_tuple_id(space, isl_dim_in); +} + +/* Does the range tuple of the map space "space" have an identifier? + */ +isl_bool isl_space_has_range_tuple_id(__isl_keep isl_space *space) +{ + if (isl_space_check_is_map(space) < 0) + return isl_bool_error; + return isl_space_has_tuple_id(space, isl_dim_out); +} + +__isl_give isl_id *isl_space_get_tuple_id(__isl_keep isl_space *space, + enum isl_dim_type type) +{ + int has_id; + + if (!space) + return NULL; + has_id = isl_space_has_tuple_id(space, type); + if (has_id < 0) + return NULL; + if (!has_id) + isl_die(space->ctx, isl_error_invalid, + "tuple has no id", return NULL); + return isl_id_copy(space->tuple_id[type - isl_dim_in]); +} + +/* Return the identifier of the domain tuple of the map space "space", + * assuming it has one. + */ +__isl_give isl_id *isl_space_get_domain_tuple_id( + __isl_keep isl_space *space) +{ + if (isl_space_check_is_map(space) < 0) + return NULL; + return isl_space_get_tuple_id(space, isl_dim_in); +} + +/* Return the identifier of the range tuple of the map space "space", + * assuming it has one. + */ +__isl_give isl_id *isl_space_get_range_tuple_id( + __isl_keep isl_space *space) +{ + if (isl_space_check_is_map(space) < 0) + return NULL; + return isl_space_get_tuple_id(space, isl_dim_out); +} + +__isl_give isl_space *isl_space_set_tuple_id(__isl_take isl_space *space, + enum isl_dim_type type, __isl_take isl_id *id) +{ + space = isl_space_cow(space); + if (!space || !id) + goto error; + if (type != isl_dim_in && type != isl_dim_out) + isl_die(space->ctx, isl_error_invalid, + "only input, output and set tuples can have names", + goto error); + + isl_id_free(space->tuple_id[type - isl_dim_in]); + space->tuple_id[type - isl_dim_in] = id; + + return space; +error: + isl_id_free(id); + isl_space_free(space); + return NULL; +} + +/* Replace the identifier of the domain tuple of the map space "space" + * by "id". + */ +__isl_give isl_space *isl_space_set_domain_tuple_id( + __isl_take isl_space *space, __isl_take isl_id *id) +{ + if (isl_space_check_is_map(space) < 0) + space = isl_space_free(space); + return isl_space_set_tuple_id(space, isl_dim_in, id); +} + +/* Replace the identifier of the range tuple of the map space "space" + * by "id". + */ +__isl_give isl_space *isl_space_set_range_tuple_id( + __isl_take isl_space *space, __isl_take isl_id *id) +{ + if (isl_space_check_is_map(space) < 0) + space = isl_space_free(space); + return isl_space_set_tuple_id(space, isl_dim_out, id); +} + +__isl_give isl_space *isl_space_reset_tuple_id(__isl_take isl_space *space, + enum isl_dim_type type) +{ + space = isl_space_cow(space); + if (!space) + return NULL; + if (type != isl_dim_in && type != isl_dim_out) + isl_die(space->ctx, isl_error_invalid, + "only input, output and set tuples can have names", + goto error); + + isl_id_free(space->tuple_id[type - isl_dim_in]); + space->tuple_id[type - isl_dim_in] = NULL; + + return space; +error: + isl_space_free(space); + return NULL; +} + +/* Set the id of the given dimension of "space" to "id". + * If the dimension already has an id, then it is replaced. + * If the dimension is a parameter, then we need to change it + * in the nested spaces (if any) as well. + */ +__isl_give isl_space *isl_space_set_dim_id(__isl_take isl_space *space, + enum isl_dim_type type, unsigned pos, __isl_take isl_id *id) +{ + space = isl_space_cow(space); + if (!space || !id) + goto error; + + if (type == isl_dim_param) { + int i; + + for (i = 0; i < 2; ++i) { + if (!space->nested[i]) + continue; + space->nested[i] = + isl_space_set_dim_id(space->nested[i], + type, pos, isl_id_copy(id)); + if (!space->nested[i]) + goto error; + } + } + + isl_id_free(get_id(space, type, pos)); + return set_id(space, type, pos, id); +error: + isl_id_free(id); + isl_space_free(space); + return NULL; +} + +/* Reset the id of the given dimension of "space". + * If the dimension already has an id, then it is removed. + * If the dimension is a parameter, then we need to reset it + * in the nested spaces (if any) as well. + */ +__isl_give isl_space *isl_space_reset_dim_id(__isl_take isl_space *space, + enum isl_dim_type type, unsigned pos) +{ + space = isl_space_cow(space); + if (!space) + goto error; + + if (type == isl_dim_param) { + int i; + + for (i = 0; i < 2; ++i) { + if (!space->nested[i]) + continue; + space->nested[i] = + isl_space_reset_dim_id(space->nested[i], + type, pos); + if (!space->nested[i]) + goto error; + } + } + + isl_id_free(get_id(space, type, pos)); + return set_id(space, type, pos, NULL); +error: + isl_space_free(space); + return NULL; +} + +isl_bool isl_space_has_dim_id(__isl_keep isl_space *space, + enum isl_dim_type type, unsigned pos) +{ + if (!space) + return isl_bool_error; + return isl_bool_ok(get_id(space, type, pos) != NULL); +} + +__isl_give isl_id *isl_space_get_dim_id(__isl_keep isl_space *space, + enum isl_dim_type type, unsigned pos) +{ + if (!space) + return NULL; + if (!get_id(space, type, pos)) + isl_die(space->ctx, isl_error_invalid, + "dim has no id", return NULL); + return isl_id_copy(get_id(space, type, pos)); +} + +__isl_give isl_space *isl_space_set_tuple_name(__isl_take isl_space *space, + enum isl_dim_type type, const char *s) +{ + isl_id *id; + + if (!space) + return NULL; + + if (!s) + return isl_space_reset_tuple_id(space, type); + + if (!name_ok(space->ctx, s)) + goto error; + + id = isl_id_alloc(space->ctx, s, NULL); + return isl_space_set_tuple_id(space, type, id); +error: + isl_space_free(space); + return NULL; +} + +/* Does the tuple have a name? + */ +isl_bool isl_space_has_tuple_name(__isl_keep isl_space *space, + enum isl_dim_type type) +{ + isl_id *id; + + if (!space_can_have_id(space, type)) + return isl_bool_error; + id = space->tuple_id[type - isl_dim_in]; + return isl_bool_ok(id && id->name); +} + +__isl_keep const char *isl_space_get_tuple_name(__isl_keep isl_space *space, + enum isl_dim_type type) +{ + isl_id *id; + if (!space) + return NULL; + if (type != isl_dim_in && type != isl_dim_out) + return NULL; + id = space->tuple_id[type - isl_dim_in]; + return id ? id->name : NULL; +} + +__isl_give isl_space *isl_space_set_dim_name(__isl_take isl_space *space, + enum isl_dim_type type, unsigned pos, + const char *s) +{ + isl_id *id; + + if (!space) + return NULL; + if (!s) + return isl_space_reset_dim_id(space, type, pos); + if (!name_ok(space->ctx, s)) + goto error; + id = isl_id_alloc(space->ctx, s, NULL); + return isl_space_set_dim_id(space, type, pos, id); +error: + isl_space_free(space); + return NULL; +} + +/* Does the given dimension have a name? + */ +isl_bool isl_space_has_dim_name(__isl_keep isl_space *space, + enum isl_dim_type type, unsigned pos) +{ + isl_id *id; + + if (!space) + return isl_bool_error; + id = get_id(space, type, pos); + return isl_bool_ok(id && id->name); +} + +__isl_keep const char *isl_space_get_dim_name(__isl_keep isl_space *space, + enum isl_dim_type type, unsigned pos) +{ + isl_id *id = get_id(space, type, pos); + return id ? id->name : NULL; +} + +int isl_space_find_dim_by_id(__isl_keep isl_space *space, + enum isl_dim_type type, __isl_keep isl_id *id) +{ + int i; + isl_size offset; + isl_size n; + + n = isl_space_dim(space, type); + offset = isl_space_offset(space, type); + if (n < 0 || offset < 0 || !id) + return -1; + + for (i = 0; i < n && offset + i < space->n_id; ++i) + if (space->ids[offset + i] == id) + return i; + + return -1; +} + +int isl_space_find_dim_by_name(__isl_keep isl_space *space, + enum isl_dim_type type, const char *name) +{ + int i; + isl_size offset; + isl_size n; + + n = isl_space_dim(space, type); + offset = isl_space_offset(space, type); + if (n < 0 || offset < 0 || !name) + return -1; + + for (i = 0; i < n && offset + i < space->n_id; ++i) { + isl_id *id = get_id(space, type, i); + if (id && id->name && !strcmp(id->name, name)) + return i; + } + + return -1; +} + +/* Reset the user pointer on all identifiers of parameters and tuples + * of "space". + */ +__isl_give isl_space *isl_space_reset_user(__isl_take isl_space *space) +{ + int i; + isl_ctx *ctx; + isl_id *id; + const char *name; + + if (!space) + return NULL; + + ctx = isl_space_get_ctx(space); + + for (i = 0; i < space->nparam && i < space->n_id; ++i) { + if (!isl_id_get_user(space->ids[i])) + continue; + space = isl_space_cow(space); + if (!space) + return NULL; + name = isl_id_get_name(space->ids[i]); + id = isl_id_alloc(ctx, name, NULL); + isl_id_free(space->ids[i]); + space->ids[i] = id; + if (!id) + return isl_space_free(space); + } + + for (i = 0; i < 2; ++i) { + if (!space->tuple_id[i]) + continue; + if (!isl_id_get_user(space->tuple_id[i])) + continue; + space = isl_space_cow(space); + if (!space) + return NULL; + name = isl_id_get_name(space->tuple_id[i]); + id = isl_id_alloc(ctx, name, NULL); + isl_id_free(space->tuple_id[i]); + space->tuple_id[i] = id; + if (!id) + return isl_space_free(space); + } + + for (i = 0; i < 2; ++i) { + isl_space *nested; + + if (!space->nested[i]) + continue; + nested = isl_space_take_nested(space, i); + nested = isl_space_reset_user(nested); + space = isl_space_restore_nested(space, i, nested); + if (!space) + return NULL; + } + + return space; +} + +static __isl_keep isl_id *tuple_id(__isl_keep isl_space *space, + enum isl_dim_type type) +{ + if (!space) + return NULL; + if (type == isl_dim_in) + return space->tuple_id[0]; + if (type == isl_dim_out) + return space->tuple_id[1]; + return NULL; +} + +static __isl_keep isl_space *nested(__isl_keep isl_space *space, + enum isl_dim_type type) +{ + if (!space) + return NULL; + if (type == isl_dim_in) + return space->nested[0]; + if (type == isl_dim_out) + return space->nested[1]; + return NULL; +} + +/* Are the two spaces the same, apart from positions and names of parameters? + */ +isl_bool isl_space_has_equal_tuples(__isl_keep isl_space *space1, + __isl_keep isl_space *space2) +{ + if (!space1 || !space2) + return isl_bool_error; + if (space1 == space2) + return isl_bool_true; + return isl_space_tuple_is_equal(space1, isl_dim_in, + space2, isl_dim_in) && + isl_space_tuple_is_equal(space1, isl_dim_out, + space2, isl_dim_out); +} + +/* Check that a match involving "space" was successful. + * That is, check that "match" is equal to isl_bool_true. + */ +static isl_stat check_match(__isl_keep isl_space *space, isl_bool match) +{ + if (match < 0) + return isl_stat_error; + if (!match) + isl_die(isl_space_get_ctx(space), isl_error_invalid, + "incompatible spaces", return isl_stat_error); + + return isl_stat_ok; +} + +/* Check that the two spaces are the same, + * apart from positions and names of parameters. + */ +isl_stat isl_space_check_equal_tuples(__isl_keep isl_space *space1, + __isl_keep isl_space *space2) +{ + isl_bool is_equal; + + is_equal = isl_space_has_equal_tuples(space1, space2); + return check_match(space1, is_equal); +} + +/* Check if the tuple of type "type1" of "space1" is the same as + * the tuple of type "type2" of "space2". + * + * That is, check if the tuples have the same identifier, the same dimension + * and the same internal structure. + * The identifiers of the dimensions inside the tuples do not affect the result. + * + * Note that this function only checks the tuples themselves. + * If nested tuples are involved, then we need to be careful not + * to have result affected by possibly differing parameters + * in those nested tuples. + */ +isl_bool isl_space_tuple_is_equal(__isl_keep isl_space *space1, + enum isl_dim_type type1, __isl_keep isl_space *space2, + enum isl_dim_type type2) +{ + isl_id *id1, *id2; + isl_space *nested1, *nested2; + + if (!space1 || !space2) + return isl_bool_error; + + if (space1 == space2 && type1 == type2) + return isl_bool_true; + + if (n(space1, type1) != n(space2, type2)) + return isl_bool_false; + id1 = tuple_id(space1, type1); + id2 = tuple_id(space2, type2); + if (!id1 ^ !id2) + return isl_bool_false; + if (id1 && id1 != id2) + return isl_bool_false; + nested1 = nested(space1, type1); + nested2 = nested(space2, type2); + if (!nested1 ^ !nested2) + return isl_bool_false; + if (nested1 && !isl_space_has_equal_tuples(nested1, nested2)) + return isl_bool_false; + return isl_bool_true; +} + +/* Is the tuple "inner" within the wrapped relation inside tuple "outer" + * of "space1" equal to tuple "type2" of "space2"? + */ +isl_bool isl_space_wrapped_tuple_is_equal(__isl_keep isl_space *space1, + enum isl_dim_type outer, enum isl_dim_type inner, + __isl_keep isl_space *space2, enum isl_dim_type type2) +{ + int pos; + isl_space *nested; + + if (!space1) + return isl_bool_error; + if (outer != isl_dim_in && outer != isl_dim_out) + isl_die(isl_space_get_ctx(space1), isl_error_invalid, + "only input, output and set tuples " + "can have nested relations", return isl_bool_error); + pos = outer - isl_dim_in; + nested = isl_space_peek_nested(space1, pos); + return isl_space_tuple_is_equal(nested, inner, space2, type2); +} + +/* Check that the tuple "inner" within the wrapped relation inside tuple "outer" + * of "space1" is equal to tuple "type2" of "space2". + */ +isl_stat isl_space_check_wrapped_tuple_is_equal(__isl_keep isl_space *space1, + enum isl_dim_type outer, enum isl_dim_type inner, + __isl_keep isl_space *space2, enum isl_dim_type type2) +{ + isl_bool is_equal; + + is_equal = isl_space_wrapped_tuple_is_equal(space1, outer, inner, + space2, type2); + return check_match(space1, is_equal); +} + +static isl_bool match(__isl_keep isl_space *space1, enum isl_dim_type type1, + __isl_keep isl_space *space2, enum isl_dim_type type2) +{ + int i; + isl_bool equal; + + if (!space1 || !space2) + return isl_bool_error; + + if (space1 == space2 && type1 == type2) + return isl_bool_true; + + equal = isl_space_tuple_is_equal(space1, type1, space2, type2); + if (equal < 0 || !equal) + return equal; + + if (!space1->ids && !space2->ids) + return isl_bool_true; + + for (i = 0; i < n(space1, type1); ++i) { + if (get_id(space1, type1, i) != get_id(space2, type2, i)) + return isl_bool_false; + } + return isl_bool_true; +} + +/* Do "space1" and "space2" have the same parameters? + */ +isl_bool isl_space_has_equal_params(__isl_keep isl_space *space1, + __isl_keep isl_space *space2) +{ + return match(space1, isl_dim_param, space2, isl_dim_param); +} + +/* Do "space1" and "space2" have the same identifiers for all + * the tuple variables? + */ +isl_bool isl_space_has_equal_ids(__isl_keep isl_space *space1, + __isl_keep isl_space *space2) +{ + isl_bool equal; + + equal = match(space1, isl_dim_in, space2, isl_dim_in); + if (equal < 0 || !equal) + return equal; + return match(space1, isl_dim_out, space2, isl_dim_out); +} + +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) +{ + return match(space1, type1, space2, type2); +} + +static void get_ids(__isl_keep isl_space *space, enum isl_dim_type type, + unsigned first, unsigned n, __isl_keep isl_id **ids) +{ + int i; + + for (i = 0; i < n ; ++i) + ids[i] = get_id(space, type, first + i); +} + +static __isl_give isl_space *space_extend(__isl_take isl_space *space, + unsigned nparam, unsigned n_in, unsigned n_out) +{ + isl_id **ids = NULL; + + if (!space) + return NULL; + if (space->nparam == nparam && + space->n_in == n_in && space->n_out == n_out) + return space; + + isl_assert(space->ctx, space->nparam <= nparam, goto error); + isl_assert(space->ctx, space->n_in <= n_in, goto error); + isl_assert(space->ctx, space->n_out <= n_out, goto error); + + space = isl_space_cow(space); + if (!space) + goto error; + + if (space->ids) { + unsigned n; + n = nparam + n_in + n_out; + if (n < nparam || n < n_in || n < n_out) + isl_die(isl_space_get_ctx(space), isl_error_invalid, + "overflow in total number of dimensions", + goto error); + ids = isl_calloc_array(space->ctx, isl_id *, n); + if (!ids) + goto error; + get_ids(space, isl_dim_param, 0, space->nparam, ids); + get_ids(space, isl_dim_in, 0, space->n_in, ids + nparam); + get_ids(space, isl_dim_out, 0, space->n_out, + ids + nparam + n_in); + free(space->ids); + space->ids = ids; + space->n_id = nparam + n_in + n_out; + } + space->nparam = nparam; + space->n_in = n_in; + space->n_out = n_out; + + return space; +error: + free(ids); + isl_space_free(space); + return NULL; +} + +__isl_give isl_space *isl_space_extend(__isl_take isl_space *space, + unsigned nparam, unsigned n_in, unsigned n_out) +{ + return space_extend(space, nparam, n_in, n_out); +} + +__isl_give isl_space *isl_space_add_dims(__isl_take isl_space *space, + enum isl_dim_type type, unsigned n) +{ + space = isl_space_reset(space, type); + if (!space) + return NULL; + switch (type) { + case isl_dim_param: + space = space_extend(space, + space->nparam + n, space->n_in, space->n_out); + if (space && space->nested[0] && + !(space->nested[0] = isl_space_add_dims(space->nested[0], + isl_dim_param, n))) + goto error; + if (space && space->nested[1] && + !(space->nested[1] = isl_space_add_dims(space->nested[1], + isl_dim_param, n))) + goto error; + return space; + case isl_dim_in: + return space_extend(space, + space->nparam, space->n_in + n, space->n_out); + case isl_dim_out: + return space_extend(space, + space->nparam, space->n_in, space->n_out + n); + default: + isl_die(space->ctx, isl_error_invalid, + "cannot add dimensions of specified type", goto error); + } +error: + isl_space_free(space); + 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) +{ + isl_size 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); + if (pos < 0) + goto error; + 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) { + case isl_dim_param: + case isl_dim_in: + case isl_dim_out: + return 1; + default: + return 0; + } +} + +#undef TYPE +#define TYPE isl_space +#include "check_type_range_templ.c" + +/* Insert "n" dimensions of type "type" at position "pos". + * If we are inserting parameters, then they are also inserted in + * any nested spaces. + */ +__isl_give isl_space *isl_space_insert_dims(__isl_take isl_space *space, + enum isl_dim_type type, unsigned pos, unsigned n) +{ + isl_ctx *ctx; + isl_id **ids = NULL; + + if (!space) + return NULL; + if (n == 0) + return isl_space_reset(space, type); + + ctx = isl_space_get_ctx(space); + if (!valid_dim_type(type)) + isl_die(ctx, isl_error_invalid, + "cannot insert dimensions of specified type", + goto error); + + if (isl_space_check_range(space, type, pos, 0) < 0) + return isl_space_free(space); + + space = isl_space_cow(space); + if (!space) + return NULL; + + if (space->ids) { + enum isl_dim_type t, o = isl_dim_param; + int off; + int s[3]; + ids = isl_calloc_array(ctx, isl_id *, + space->nparam + space->n_in + space->n_out + n); + if (!ids) + goto error; + off = 0; + s[isl_dim_param - o] = space->nparam; + s[isl_dim_in - o] = space->n_in; + s[isl_dim_out - o] = space->n_out; + for (t = isl_dim_param; t <= isl_dim_out; ++t) { + if (t != type) { + get_ids(space, t, 0, s[t - o], ids + off); + off += s[t - o]; + } else { + get_ids(space, t, 0, pos, ids + off); + off += pos + n; + get_ids(space, t, pos, s[t - o] - pos, + ids + off); + off += s[t - o] - pos; + } + } + free(space->ids); + space->ids = ids; + space->n_id = space->nparam + space->n_in + space->n_out + n; + } + switch (type) { + case isl_dim_param: space->nparam += n; break; + case isl_dim_in: space->n_in += n; break; + case isl_dim_out: space->n_out += n; break; + default: ; + } + space = isl_space_reset(space, type); + + if (type == isl_dim_param) { + if (space && space->nested[0] && + !(space->nested[0] = isl_space_insert_dims(space->nested[0], + isl_dim_param, pos, n))) + goto error; + if (space && space->nested[1] && + !(space->nested[1] = isl_space_insert_dims(space->nested[1], + isl_dim_param, pos, n))) + goto error; + } + + return space; +error: + isl_space_free(space); + return NULL; +} + +__isl_give isl_space *isl_space_move_dims(__isl_take isl_space *space, + enum isl_dim_type dst_type, unsigned dst_pos, + enum isl_dim_type src_type, unsigned src_pos, unsigned n) +{ + int i; + + space = isl_space_reset(space, src_type); + space = isl_space_reset(space, dst_type); + if (!space) + return NULL; + if (n == 0) + return space; + + if (isl_space_check_range(space, src_type, src_pos, n) < 0) + return isl_space_free(space); + + if (dst_type == src_type && dst_pos == src_pos) + return space; + + isl_assert(space->ctx, dst_type != src_type, goto error); + + space = isl_space_cow(space); + if (!space) + return NULL; + + if (space->ids) { + isl_id **ids; + enum isl_dim_type t, o = isl_dim_param; + int off; + int s[3]; + ids = isl_calloc_array(space->ctx, isl_id *, + space->nparam + space->n_in + space->n_out); + if (!ids) + goto error; + off = 0; + s[isl_dim_param - o] = space->nparam; + s[isl_dim_in - o] = space->n_in; + s[isl_dim_out - o] = space->n_out; + for (t = isl_dim_param; t <= isl_dim_out; ++t) { + if (t == dst_type) { + get_ids(space, t, 0, dst_pos, ids + off); + off += dst_pos; + get_ids(space, src_type, src_pos, n, ids + off); + off += n; + get_ids(space, t, dst_pos, s[t - o] - dst_pos, + ids + off); + off += s[t - o] - dst_pos; + } else if (t == src_type) { + get_ids(space, t, 0, src_pos, ids + off); + off += src_pos; + get_ids(space, t, src_pos + n, + s[t - o] - src_pos - n, ids + off); + off += s[t - o] - src_pos - n; + } else { + get_ids(space, t, 0, s[t - o], ids + off); + off += s[t - o]; + } + } + free(space->ids); + space->ids = ids; + space->n_id = space->nparam + space->n_in + space->n_out; + } + + switch (dst_type) { + case isl_dim_param: space->nparam += n; break; + case isl_dim_in: space->n_in += n; break; + case isl_dim_out: space->n_out += n; break; + default: ; + } + + switch (src_type) { + case isl_dim_param: space->nparam -= n; break; + case isl_dim_in: space->n_in -= n; break; + case isl_dim_out: space->n_out -= n; break; + default: ; + } + + if (dst_type != isl_dim_param && src_type != isl_dim_param) + return space; + + for (i = 0; i < 2; ++i) { + isl_space *nested; + + if (!space->nested[i]) + continue; + nested = isl_space_take_nested(space, i); + nested = isl_space_replace_params(nested, space); + space = isl_space_restore_nested(space, i, nested); + if (!space) + return NULL; + } + + return space; +error: + isl_space_free(space); + return NULL; +} + +/* Check that "space1" and "space2" have the same parameters, + * reporting an error if they do not. + */ +isl_stat isl_space_check_equal_params(__isl_keep isl_space *space1, + __isl_keep isl_space *space2) +{ + isl_bool equal; + + equal = isl_space_has_equal_params(space1, space2); + if (equal < 0) + return isl_stat_error; + if (!equal) + isl_die(isl_space_get_ctx(space1), isl_error_invalid, + "parameters need to match", return isl_stat_error); + return isl_stat_ok; +} + +__isl_give isl_space *isl_space_join(__isl_take isl_space *left, + __isl_take isl_space *right) +{ + isl_space *space; + + if (isl_space_check_equal_params(left, right) < 0) + goto error; + + isl_assert(left->ctx, + isl_space_tuple_is_equal(left, isl_dim_out, right, isl_dim_in), + goto error); + + space = isl_space_alloc(left->ctx, + left->nparam, left->n_in, right->n_out); + if (!space) + goto error; + + space = copy_ids(space, isl_dim_param, 0, left, isl_dim_param); + space = copy_ids(space, isl_dim_in, 0, left, isl_dim_in); + space = copy_ids(space, isl_dim_out, 0, right, isl_dim_out); + + if (space && left->tuple_id[0] && + !(space->tuple_id[0] = isl_id_copy(left->tuple_id[0]))) + goto error; + if (space && right->tuple_id[1] && + !(space->tuple_id[1] = isl_id_copy(right->tuple_id[1]))) + goto error; + if (space && left->nested[0] && + !(space->nested[0] = isl_space_copy(left->nested[0]))) + goto error; + if (space && right->nested[1] && + !(space->nested[1] = isl_space_copy(right->nested[1]))) + goto error; + + isl_space_free(left); + isl_space_free(right); + + return space; +error: + isl_space_free(left); + isl_space_free(right); + return NULL; +} + +/* Given two map spaces { A -> C } and { B -> D }, construct the space + * { [A -> B] -> [C -> D] }. + * Given two set spaces { A } and { B }, construct the space { [A -> B] }. + */ +__isl_give isl_space *isl_space_product(__isl_take isl_space *left, + __isl_take isl_space *right) +{ + isl_space *dom1, *dom2, *nest1, *nest2; + int is_set; + + if (!left || !right) + goto error; + + is_set = isl_space_is_set(left); + if (is_set != isl_space_is_set(right)) + isl_die(isl_space_get_ctx(left), isl_error_invalid, + "expecting either two set spaces or two map spaces", + goto error); + if (is_set) + return isl_space_range_product(left, right); + + if (isl_space_check_equal_params(left, right) < 0) + goto error; + + dom1 = isl_space_domain(isl_space_copy(left)); + dom2 = isl_space_domain(isl_space_copy(right)); + nest1 = isl_space_wrap(isl_space_join(isl_space_reverse(dom1), dom2)); + + dom1 = isl_space_range(left); + dom2 = isl_space_range(right); + nest2 = isl_space_wrap(isl_space_join(isl_space_reverse(dom1), dom2)); + + return isl_space_join(isl_space_reverse(nest1), nest2); +error: + isl_space_free(left); + isl_space_free(right); + return NULL; +} + +/* Given two spaces { A -> C } and { B -> C }, construct the space + * { [A -> B] -> C } + */ +__isl_give isl_space *isl_space_domain_product(__isl_take isl_space *left, + __isl_take isl_space *right) +{ + isl_space *ran, *dom1, *dom2, *nest; + + if (isl_space_check_equal_params(left, right) < 0) + goto error; + + if (!isl_space_tuple_is_equal(left, isl_dim_out, right, isl_dim_out)) + isl_die(left->ctx, isl_error_invalid, + "ranges need to match", goto error); + + ran = isl_space_range(isl_space_copy(left)); + + dom1 = isl_space_domain(left); + dom2 = isl_space_domain(right); + nest = isl_space_wrap(isl_space_join(isl_space_reverse(dom1), dom2)); + + return isl_space_join(isl_space_reverse(nest), ran); +error: + isl_space_free(left); + isl_space_free(right); + return NULL; +} + +__isl_give isl_space *isl_space_range_product(__isl_take isl_space *left, + __isl_take isl_space *right) +{ + isl_space *dom, *ran1, *ran2, *nest; + + if (isl_space_check_equal_params(left, right) < 0) + goto error; + + if (!isl_space_tuple_is_equal(left, isl_dim_in, right, isl_dim_in)) + isl_die(left->ctx, isl_error_invalid, + "domains need to match", goto error); + + dom = isl_space_domain(isl_space_copy(left)); + + ran1 = isl_space_range(left); + ran2 = isl_space_range(right); + nest = isl_space_wrap(isl_space_join(isl_space_reverse(ran1), ran2)); + + return isl_space_join(isl_space_reverse(dom), nest); +error: + isl_space_free(left); + isl_space_free(right); + return NULL; +} + +/* Given a space of the form [A -> B] -> C, return the space A -> C. + */ +__isl_give isl_space *isl_space_domain_factor_domain( + __isl_take isl_space *space) +{ + isl_space *nested; + isl_space *domain; + + if (isl_space_check_domain_is_wrapping(space) < 0) + return isl_space_free(space); + + nested = space->nested[0]; + domain = isl_space_copy(space); + domain = isl_space_drop_dims(domain, isl_dim_in, + nested->n_in, nested->n_out); + if (!domain) + return isl_space_free(space); + if (nested->tuple_id[0]) { + domain->tuple_id[0] = isl_id_copy(nested->tuple_id[0]); + if (!domain->tuple_id[0]) + goto error; + } + if (nested->nested[0]) { + domain->nested[0] = isl_space_copy(nested->nested[0]); + if (!domain->nested[0]) + goto error; + } + + isl_space_free(space); + return domain; +error: + isl_space_free(space); + isl_space_free(domain); + return NULL; +} + +/* Given a space of the form [A -> B] -> C, return the space B -> C. + */ +__isl_give isl_space *isl_space_domain_factor_range( + __isl_take isl_space *space) +{ + isl_space *nested; + isl_space *range; + + if (isl_space_check_domain_is_wrapping(space) < 0) + return isl_space_free(space); + + nested = space->nested[0]; + range = isl_space_copy(space); + range = isl_space_drop_dims(range, isl_dim_in, 0, nested->n_in); + if (!range) + return isl_space_free(space); + if (nested->tuple_id[1]) { + range->tuple_id[0] = isl_id_copy(nested->tuple_id[1]); + if (!range->tuple_id[0]) + goto error; + } + if (nested->nested[1]) { + range->nested[0] = isl_space_copy(nested->nested[1]); + if (!range->nested[0]) + goto error; + } + + isl_space_free(space); + return range; +error: + isl_space_free(space); + isl_space_free(range); + return NULL; +} + +/* 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. + */ +static __isl_give isl_space *range_factor_domain(__isl_take isl_space *space) +{ + isl_space *nested; + isl_space *domain; + + if (!space) + return NULL; + + nested = space->nested[1]; + domain = isl_space_copy(space); + domain = isl_space_drop_dims(domain, isl_dim_out, + nested->n_in, nested->n_out); + if (!domain) + return isl_space_free(space); + if (nested->tuple_id[0]) { + domain->tuple_id[1] = isl_id_copy(nested->tuple_id[0]); + if (!domain->tuple_id[1]) + goto error; + } + if (nested->nested[0]) { + domain->nested[1] = isl_space_copy(nested->nested[0]); + if (!domain->nested[1]) + goto error; + } + + isl_space_free(space); + return domain; +error: + isl_space_free(space); + isl_space_free(domain); + 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 (isl_space_check_range_is_wrapping(space) < 0) + 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. + * Given a space of the form A -> [B -> C], return the space A -> C. + */ +static __isl_give isl_space *range_factor_range(__isl_take isl_space *space) +{ + isl_space *nested; + isl_space *range; + + if (!space) + return NULL; + + nested = space->nested[1]; + range = isl_space_copy(space); + range = isl_space_drop_dims(range, isl_dim_out, 0, nested->n_in); + if (!range) + return isl_space_free(space); + if (nested->tuple_id[1]) { + range->tuple_id[1] = isl_id_copy(nested->tuple_id[1]); + if (!range->tuple_id[1]) + goto error; + } + if (nested->nested[1]) { + range->nested[1] = isl_space_copy(nested->nested[1]); + if (!range->nested[1]) + goto error; + } + + isl_space_free(space); + return range; +error: + isl_space_free(space); + isl_space_free(range); + return NULL; +} + +/* Given a space of the form A -> [B -> C], return the space A -> C. + */ +__isl_give isl_space *isl_space_range_factor_range( + __isl_take isl_space *space) +{ + if (isl_space_check_range_is_wrapping(space) < 0) + return isl_space_free(space); + + return range_factor_range(space); +} + +/* Given a space of the form [A -> B], return the space B. + */ +static __isl_give isl_space *set_factor_range(__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_range(space); +} + +/* Given a space of the form [A -> B] -> [C -> D], return the space B -> D. + * Given a space of the form [A -> B], return the space B. + */ +__isl_give isl_space *isl_space_factor_range(__isl_take isl_space *space) +{ + if (!space) + return NULL; + if (isl_space_is_set(space)) + return set_factor_range(space); + space = isl_space_domain_factor_range(space); + space = isl_space_range_factor_range(space); + return space; +} + +/* Given a space of the form [A -> B] -> C, return the space A. + */ +__isl_give isl_space *isl_space_domain_wrapped_domain( + __isl_take isl_space *space) +{ + return isl_space_factor_domain(isl_space_domain(space)); +} + +/* Given a space of the form [A -> B] -> C, return the space B. + */ +__isl_give isl_space *isl_space_domain_wrapped_range( + __isl_take isl_space *space) +{ + return isl_space_factor_range(isl_space_domain(space)); +} + +/* Given a space of the form A -> [B -> C], return the space B. + */ +__isl_give isl_space *isl_space_range_wrapped_domain( + __isl_take isl_space *space) +{ + return isl_space_factor_domain(isl_space_range(space)); +} + +/* Given a space of the form A -> [B -> C], return the space C. + */ +__isl_give isl_space *isl_space_range_wrapped_range( + __isl_take isl_space *space) +{ + return isl_space_factor_range(isl_space_range(space)); +} + +__isl_give isl_space *isl_space_map_from_set(__isl_take isl_space *space) +{ + isl_ctx *ctx; + isl_id **ids = NULL; + int n_id; + + if (!space) + return NULL; + ctx = isl_space_get_ctx(space); + if (!isl_space_is_set(space)) + isl_die(ctx, isl_error_invalid, "not a set space", goto error); + space = isl_space_cow(space); + if (!space) + return NULL; + n_id = space->nparam + space->n_out + space->n_out; + if (n_id > 0 && space->ids) { + ids = isl_calloc_array(space->ctx, isl_id *, n_id); + if (!ids) + goto error; + get_ids(space, isl_dim_param, 0, space->nparam, ids); + get_ids(space, isl_dim_out, 0, space->n_out, + ids + space->nparam); + } + space->n_in = space->n_out; + if (ids) { + free(space->ids); + space->ids = ids; + space->n_id = n_id; + space = copy_ids(space, isl_dim_out, 0, space, isl_dim_in); + } + isl_id_free(space->tuple_id[0]); + space->tuple_id[0] = isl_id_copy(space->tuple_id[1]); + isl_space_free(space->nested[0]); + space->nested[0] = isl_space_copy(space->nested[1]); + return space; +error: + isl_space_free(space); + return NULL; +} + +__isl_give isl_space *isl_space_map_from_domain_and_range( + __isl_take isl_space *domain, __isl_take isl_space *range) +{ + if (!domain || !range) + goto error; + if (!isl_space_is_set(domain)) + isl_die(isl_space_get_ctx(domain), isl_error_invalid, + "domain is not a set space", goto error); + if (!isl_space_is_set(range)) + isl_die(isl_space_get_ctx(range), isl_error_invalid, + "range is not a set space", goto error); + return isl_space_join(isl_space_reverse(domain), range); +error: + isl_space_free(domain); + isl_space_free(range); + return NULL; +} + +static __isl_give isl_space *set_ids(__isl_take isl_space *space, + enum isl_dim_type type, + unsigned first, unsigned n, __isl_take isl_id **ids) +{ + int i; + + for (i = 0; i < n ; ++i) + space = set_id(space, type, first + i, ids[i]); + + return space; +} + +__isl_give isl_space *isl_space_reverse(__isl_take isl_space *space) +{ + unsigned t; + isl_bool equal; + isl_space *nested; + isl_id **ids = NULL; + isl_id *id; + + equal = match(space, isl_dim_in, space, isl_dim_out); + if (equal < 0) + return isl_space_free(space); + if (equal) + return space; + + space = isl_space_cow(space); + if (!space) + return NULL; + + id = space->tuple_id[0]; + space->tuple_id[0] = space->tuple_id[1]; + space->tuple_id[1] = id; + + nested = space->nested[0]; + space->nested[0] = space->nested[1]; + space->nested[1] = nested; + + if (space->ids) { + int n_id = space->n_in + space->n_out; + ids = isl_alloc_array(space->ctx, isl_id *, n_id); + if (n_id && !ids) + goto error; + get_ids(space, isl_dim_in, 0, space->n_in, ids); + get_ids(space, isl_dim_out, 0, space->n_out, ids + space->n_in); + } + + t = space->n_in; + space->n_in = space->n_out; + space->n_out = t; + + if (space->ids) { + space = set_ids(space, isl_dim_out, 0, space->n_out, ids); + space = set_ids(space, isl_dim_in, 0, space->n_in, + ids + space->n_out); + free(ids); + } + + return space; +error: + free(ids); + isl_space_free(space); + return NULL; +} + +/* Given a space where the tuple of type "type" is a wrapped map space, + * swap domain and range of that wrapped space. + * + * If the tuple is named, then the name is only preserved + * if the nested tuples are equal, in which case the output + * of this function is identical to the input, except possibly + * for the dimension identifiers. + * + * Make a reasonable attempt at moving the dimension identifiers + * along with the tuples. + */ +__isl_give isl_space *isl_space_reverse_wrapped(__isl_take isl_space *space, + enum isl_dim_type type) +{ + int pos = type - isl_dim_in; + isl_space *nested; + isl_bool equal; + isl_size n_in; + + nested = isl_space_peek_nested(space, pos); + equal = isl_space_tuple_is_equal(nested, isl_dim_in, + nested, isl_dim_out); + if (equal < 0) + return isl_space_free(space); + + nested = isl_space_take_nested(space, pos); + nested = isl_space_reverse(nested); + space = isl_space_restore_nested(space, pos, nested); + if (!equal) + space = isl_space_reset_tuple_id(space, type); + nested = isl_space_peek_nested(space, pos); + n_in = isl_space_dim(nested, isl_dim_in); + if (n_in < 0) + return isl_space_free(space); + space = copy_ids(space, type, 0, nested, isl_dim_in); + space = copy_ids(space, type, n_in, nested, isl_dim_out); + + return space; +} + +/* Given a space (A -> B), return the corresponding space + * (B -> A). + * + * If the domain tuple is named, then the name is only preserved + * if A and B are equal tuples, in which case the output + * of this function is identical to the input, except possibly + * for the dimension identifiers. + */ +__isl_give isl_space *isl_space_wrapped_reverse(__isl_take isl_space *space) +{ + if (isl_space_check_is_wrapping(space) < 0) + return isl_space_free(space); + space = isl_space_reverse_wrapped(space, isl_dim_set); + + return space; +} + +/* Given a space (A -> B) -> C, return the corresponding space + * (B -> A) -> C. + * + * If the domain tuple is named, then the name is only preserved + * if A and B are equal tuples, in which case the output + * of this function is identical to the input, except possibly + * for the dimension identifiers. + */ +__isl_give isl_space *isl_space_domain_reverse(__isl_take isl_space *space) +{ + if (isl_space_check_domain_is_wrapping(space) < 0) + return isl_space_free(space); + space = isl_space_reverse_wrapped(space, isl_dim_in); + + return space; +} + +/* Given a space A -> (B -> C), return the corresponding space + * A -> (C -> B). + * + * If the range tuple is named, then the name is only preserved + * if B and C are equal tuples, in which case the output + * of this function is identical to the input, except possibly + * for the dimension identifiers. + */ +__isl_give isl_space *isl_space_range_reverse(__isl_take isl_space *space) +{ + if (isl_space_check_range_is_wrapping(space) < 0) + return isl_space_free(space); + space = isl_space_reverse_wrapped(space, isl_dim_out); + + return space; +} + +__isl_give isl_space *isl_space_drop_dims(__isl_take isl_space *space, + enum isl_dim_type type, unsigned first, unsigned num) +{ + int i; + + if (!space) + return NULL; + + if (num == 0) + return isl_space_reset(space, type); + + if (!valid_dim_type(type)) + isl_die(space->ctx, isl_error_invalid, + "cannot drop dimensions of specified type", goto error); + + if (isl_space_check_range(space, type, first, num) < 0) + return isl_space_free(space); + space = isl_space_cow(space); + if (!space) + goto error; + if (space->ids) { + space = extend_ids(space); + if (!space) + goto error; + for (i = 0; i < num; ++i) + isl_id_free(get_id(space, type, first + i)); + for (i = first+num; i < n(space, type); ++i) + set_id(space, type, i - num, get_id(space, type, i)); + switch (type) { + case isl_dim_param: + get_ids(space, isl_dim_in, 0, space->n_in, + space->ids + offset(space, isl_dim_in) - num); + case isl_dim_in: + get_ids(space, isl_dim_out, 0, space->n_out, + space->ids + offset(space, isl_dim_out) - num); + default: + ; + } + space->n_id -= num; + } + switch (type) { + case isl_dim_param: space->nparam -= num; break; + case isl_dim_in: space->n_in -= num; break; + case isl_dim_out: space->n_out -= num; break; + default: ; + } + space = isl_space_reset(space, type); + if (type == isl_dim_param) { + if (space && space->nested[0] && + !(space->nested[0] = isl_space_drop_dims(space->nested[0], + isl_dim_param, first, num))) + goto error; + if (space && space->nested[1] && + !(space->nested[1] = isl_space_drop_dims(space->nested[1], + isl_dim_param, first, num))) + goto error; + } + return space; +error: + isl_space_free(space); + return NULL; +} + +__isl_give isl_space *isl_space_drop_inputs(__isl_take isl_space *space, + unsigned first, unsigned n) +{ + if (!space) + return NULL; + return isl_space_drop_dims(space, isl_dim_in, first, n); +} + +__isl_give isl_space *isl_space_drop_outputs(__isl_take isl_space *space, + unsigned first, unsigned n) +{ + if (!space) + return NULL; + return isl_space_drop_dims(space, isl_dim_out, first, n); +} + +/* Remove all parameters from "space". + */ +__isl_give isl_space *isl_space_drop_all_params(__isl_take isl_space *space) +{ + isl_size nparam; + + nparam = isl_space_dim(space, isl_dim_param); + if (nparam < 0) + return isl_space_free(space); + return isl_space_drop_dims(space, isl_dim_param, 0, nparam); +} + +__isl_give isl_space *isl_space_domain(__isl_take isl_space *space) +{ + if (!space) + return NULL; + space = isl_space_drop_dims(space, isl_dim_out, 0, space->n_out); + space = isl_space_reverse(space); + space = mark_as_set(space); + return space; +} + +__isl_give isl_space *isl_space_from_domain(__isl_take isl_space *space) +{ + if (!space) + return NULL; + if (!isl_space_is_set(space)) + isl_die(isl_space_get_ctx(space), isl_error_invalid, + "not a set space", goto error); + space = isl_space_reverse(space); + space = isl_space_reset(space, isl_dim_out); + return space; +error: + isl_space_free(space); + return NULL; +} + +__isl_give isl_space *isl_space_range(__isl_take isl_space *space) +{ + if (!space) + return NULL; + space = isl_space_drop_dims(space, isl_dim_in, 0, space->n_in); + space = mark_as_set(space); + return space; +} + +__isl_give isl_space *isl_space_from_range(__isl_take isl_space *space) +{ + if (!space) + return NULL; + if (!isl_space_is_set(space)) + isl_die(isl_space_get_ctx(space), isl_error_invalid, + "not a set space", goto error); + return isl_space_reset(space, isl_dim_in); +error: + isl_space_free(space); + return NULL; +} + +/* Given a map space A -> B, return the map space [A -> B] -> A. + */ +__isl_give isl_space *isl_space_domain_map(__isl_take isl_space *space) +{ + isl_space *domain; + + domain = isl_space_from_range(isl_space_domain(isl_space_copy(space))); + space = isl_space_from_domain(isl_space_wrap(space)); + space = isl_space_join(space, domain); + + return space; +} + +/* Given a map space A -> B, return the map space [A -> B] -> B. + */ +__isl_give isl_space *isl_space_range_map(__isl_take isl_space *space) +{ + isl_space *range; + + range = isl_space_from_range(isl_space_range(isl_space_copy(space))); + space = isl_space_from_domain(isl_space_wrap(space)); + space = isl_space_join(space, range); + + return space; +} + +__isl_give isl_space *isl_space_params(__isl_take isl_space *space) +{ + isl_size n_in, n_out; + + if (isl_space_is_params(space)) + return space; + n_in = isl_space_dim(space, isl_dim_in); + n_out = isl_space_dim(space, isl_dim_out); + if (n_in < 0 || n_out < 0) + return isl_space_free(space); + space = isl_space_drop_dims(space, isl_dim_in, 0, n_in); + space = isl_space_drop_dims(space, isl_dim_out, 0, n_out); + space = mark_as_params(space); + return space; +} + +__isl_give isl_space *isl_space_set_from_params(__isl_take isl_space *space) +{ + if (!space) + return NULL; + if (!isl_space_is_params(space)) + isl_die(isl_space_get_ctx(space), isl_error_invalid, + "not a parameter space", goto error); + return isl_space_reset(space, isl_dim_set); +error: + isl_space_free(space); + return NULL; +} + +/* Add an unnamed tuple of dimension "dim" to "space". + * This requires "space" to be a parameter or set space. + * + * In particular, if "space" is a parameter space, then return + * a set space with the given dimension. + * If "space" is a set space, then return a map space + * with "space" as domain and a range of the given dimension. + */ +__isl_give isl_space *isl_space_add_unnamed_tuple_ui( + __isl_take isl_space *space, unsigned dim) +{ + isl_bool is_params, is_set; + + is_params = isl_space_is_params(space); + is_set = isl_space_is_set(space); + if (is_params < 0 || is_set < 0) + return isl_space_free(space); + if (!is_params && !is_set) + isl_die(isl_space_get_ctx(space), isl_error_invalid, + "cannot add tuple to map space", + return isl_space_free(space)); + if (is_params) + space = isl_space_set_from_params(space); + else + space = isl_space_from_domain(space); + space = isl_space_add_dims(space, isl_dim_out, dim); + return space; +} + +/* Add a tuple of dimension "dim" and with tuple identifier "tuple_id" + * to "space". + * This requires "space" to be a parameter or set space. + */ +__isl_give isl_space *isl_space_add_named_tuple_id_ui( + __isl_take isl_space *space, __isl_take isl_id *tuple_id, unsigned dim) +{ + space = isl_space_add_unnamed_tuple_ui(space, dim); + space = isl_space_set_tuple_id(space, isl_dim_out, tuple_id); + return space; +} + +/* Check that the identifiers in "tuple" do not appear as parameters + * in "space". + */ +static isl_stat check_fresh_params(__isl_keep isl_space *space, + __isl_keep isl_multi_id *tuple) +{ + int i; + isl_size n; + + n = isl_multi_id_size(tuple); + if (n < 0) + return isl_stat_error; + for (i = 0; i < n; ++i) { + isl_id *id; + int pos; + + id = isl_multi_id_get_at(tuple, i); + if (!id) + return isl_stat_error; + pos = isl_space_find_dim_by_id(space, isl_dim_param, id); + isl_id_free(id); + if (pos >= 0) + isl_die(isl_space_get_ctx(space), isl_error_invalid, + "parameters not unique", return isl_stat_error); + } + + return isl_stat_ok; +} + +/* Add the identifiers in "tuple" as parameters of "space" + * that are known to be fresh. + */ +static __isl_give isl_space *add_bind_params(__isl_take isl_space *space, + __isl_keep isl_multi_id *tuple) +{ + int i; + isl_size first, n; + + first = isl_space_dim(space, isl_dim_param); + n = isl_multi_id_size(tuple); + if (first < 0 || n < 0) + return isl_space_free(space); + space = isl_space_add_dims(space, isl_dim_param, n); + for (i = 0; i < n; ++i) { + isl_id *id; + + id = isl_multi_id_get_at(tuple, i); + space = isl_space_set_dim_id(space, + isl_dim_param, first + i, id); + } + + return space; +} + +/* Internal function that removes the set tuple of "space", + * which is assumed to correspond to the range space of "tuple", and + * adds the identifiers in "tuple" as fresh parameters. + * In other words, the set dimensions of "space" are reinterpreted + * as parameters, but stay in the same global positions. + */ +__isl_give isl_space *isl_space_bind_set(__isl_take isl_space *space, + __isl_keep isl_multi_id *tuple) +{ + isl_space *tuple_space; + + if (isl_space_check_is_set(space) < 0) + return isl_space_free(space); + tuple_space = isl_multi_id_peek_space(tuple); + if (isl_space_check_equal_tuples(tuple_space, space) < 0) + return isl_space_free(space); + if (check_fresh_params(space, tuple) < 0) + return isl_space_free(space); + space = isl_space_params(space); + space = add_bind_params(space, tuple); + return space; +} + +/* Internal function that removes the domain tuple of the map space "space", + * which is assumed to correspond to the range space of "tuple", and + * adds the identifiers in "tuple" as fresh parameters. + * In other words, the domain dimensions of "space" are reinterpreted + * as parameters, but stay in the same global positions. + */ +__isl_give isl_space *isl_space_bind_map_domain(__isl_take isl_space *space, + __isl_keep isl_multi_id *tuple) +{ + isl_space *tuple_space; + + if (isl_space_check_is_map(space) < 0) + return isl_space_free(space); + tuple_space = isl_multi_id_peek_space(tuple); + if (isl_space_check_domain_tuples(tuple_space, space) < 0) + return isl_space_free(space); + if (check_fresh_params(space, tuple) < 0) + return isl_space_free(space); + space = isl_space_range(space); + space = add_bind_params(space, tuple); + return space; +} + +/* Internal function that, given a space of the form [A -> B] -> C and + * a tuple of identifiers in A, returns a space B -> C with + * the identifiers in "tuple" added as fresh parameters. + * In other words, the domain dimensions of the wrapped relation + * in the domain of "space" are reinterpreted + * as parameters, but stay in the same global positions. + */ +__isl_give isl_space *isl_space_bind_domain_wrapped_domain( + __isl_take isl_space *space, __isl_keep isl_multi_id *tuple) +{ + isl_space *tuple_space; + + if (isl_space_check_is_map(space) < 0) + return isl_space_free(space); + tuple_space = isl_multi_id_peek_space(tuple); + if (isl_space_check_domain_wrapped_domain_tuples(tuple_space, + space) < 0) + return isl_space_free(space); + if (check_fresh_params(space, tuple) < 0) + return isl_space_free(space); + space = isl_space_domain_factor_range(space); + space = add_bind_params(space, tuple); + return space; +} + +/* Insert a domain tuple in "space" corresponding to the set space "domain". + * In particular, if "space" is a parameter space, then the result + * is the set space "domain" combined with the parameters of "space". + * If "space" is a set space, then the result + * is a map space with "domain" as domain and the original space as range. + */ +static __isl_give isl_space *isl_space_insert_domain( + __isl_take isl_space *space, __isl_take isl_space *domain) +{ + isl_bool is_params; + + domain = isl_space_replace_params(domain, space); + + is_params = isl_space_is_params(space); + if (is_params < 0) { + isl_space_free(domain); + space = isl_space_free(space); + } else if (is_params) { + isl_space_free(space); + space = domain; + } else { + space = isl_space_map_from_domain_and_range(domain, space); + } + return space; +} + +/* Internal function that introduces a domain in "space" + * corresponding to the range space of "tuple". + * In particular, if "space" is a parameter space, then the result + * is a set space. If "space" is a set space, then the result + * is a map space with the original space as range. + * Parameters that correspond to the identifiers in "tuple" are removed. + * + * The parameters are removed in reverse order (under the assumption + * that they appear in the same order in "multi") because + * it is slightly more efficient to remove parameters at the end. + * + * For pretty-printing purposes, the identifiers of the set dimensions + * of the introduced domain are set to the identifiers in "tuple". + */ +__isl_give isl_space *isl_space_unbind_params_insert_domain( + __isl_take isl_space *space, __isl_keep isl_multi_id *tuple) +{ + int i; + isl_size n; + isl_space *tuple_space; + + n = isl_multi_id_size(tuple); + if (!space || n < 0) + return isl_space_free(space); + for (i = n - 1; i >= 0; --i) { + isl_id *id; + int pos; + + id = isl_multi_id_get_id(tuple, i); + if (!id) + return isl_space_free(space); + pos = isl_space_find_dim_by_id(space, isl_dim_param, id); + isl_id_free(id); + if (pos < 0) + continue; + space = isl_space_drop_dims(space, isl_dim_param, pos, 1); + } + tuple_space = isl_multi_id_get_space(tuple); + for (i = 0; i < n; ++i) { + isl_id *id; + + id = isl_multi_id_get_id(tuple, i); + tuple_space = isl_space_set_dim_id(tuple_space, + isl_dim_set, i, id); + } + return isl_space_insert_domain(space, tuple_space); +} + +__isl_give isl_space *isl_space_underlying(__isl_take isl_space *space, + unsigned n_div) +{ + int i; + isl_bool is_set; + + is_set = isl_space_is_set(space); + if (is_set < 0) + return isl_space_free(space); + if (n_div == 0 && is_set && + space->nparam == 0 && space->n_in == 0 && space->n_id == 0) + return isl_space_reset(space, isl_dim_out); + space = isl_space_cow(space); + if (!space) + return NULL; + space->n_out += space->nparam + space->n_in + n_div; + space->nparam = 0; + space->n_in = 0; + + for (i = 0; i < space->n_id; ++i) + isl_id_free(get_id(space, isl_dim_out, i)); + space->n_id = 0; + space = isl_space_reset(space, isl_dim_in); + space = isl_space_reset(space, isl_dim_out); + space = mark_as_set(space); + + return space; +} + +/* Are the two spaces the same, including positions and names of parameters? + */ +isl_bool isl_space_is_equal(__isl_keep isl_space *space1, + __isl_keep isl_space *space2) +{ + isl_bool equal; + + if (!space1 || !space2) + return isl_bool_error; + if (space1 == space2) + return isl_bool_true; + equal = isl_space_has_equal_params(space1, space2); + if (equal < 0 || !equal) + return equal; + return isl_space_has_equal_tuples(space1, space2); +} + +/* Do the tuples of "space1" correspond to those of the domain of "space2"? + * That is, is "space1" equal to the domain of "space2", ignoring parameters. + * + * "space2" is allowed to be a set space, in which case "space1" + * should be a parameter space. + */ +isl_bool isl_space_has_domain_tuples(__isl_keep isl_space *space1, + __isl_keep isl_space *space2) +{ + isl_bool is_set; + + is_set = isl_space_is_set(space1); + if (is_set < 0 || !is_set) + return is_set; + return isl_space_tuple_is_equal(space1, isl_dim_set, + space2, isl_dim_in); +} + +/* Do the tuples of "space1" correspond to those of the range of "space2"? + * That is, is "space1" equal to the range of "space2", ignoring parameters. + * + * "space2" is allowed to be the space of a set, + * in which case it should be equal to "space1", ignoring parameters. + */ +isl_bool isl_space_has_range_tuples(__isl_keep isl_space *space1, + __isl_keep isl_space *space2) +{ + isl_bool is_set; + + is_set = isl_space_is_set(space1); + if (is_set < 0 || !is_set) + return is_set; + return isl_space_tuple_is_equal(space1, isl_dim_set, + space2, isl_dim_out); +} + +/* Check that the tuples of "space1" correspond to those + * of the domain of "space2". + * That is, check that "space1" is equal to the domain of "space2", + * ignoring parameters. + */ +isl_stat isl_space_check_domain_tuples(__isl_keep isl_space *space1, + __isl_keep isl_space *space2) +{ + isl_bool is_equal; + + is_equal = isl_space_has_domain_tuples(space1, space2); + return check_match(space1, is_equal); +} + +/* Check that the tuples of "space1" correspond to those + * of the domain of the wrapped relation in the domain of "space2". + * That is, check that "space1" is equal to this domain, + * ignoring parameters. + */ +isl_stat isl_space_check_domain_wrapped_domain_tuples( + __isl_keep isl_space *space1, __isl_keep isl_space *space2) +{ + isl_space *domain; + isl_stat r; + + domain = isl_space_unwrap(isl_space_domain(isl_space_copy(space2))); + r = isl_space_check_domain_tuples(space1, domain); + isl_space_free(domain); + + return r; +} + +/* Is space1 equal to the domain of space2? + * + * In the internal version we also allow space2 to be the space of a set, + * provided space1 is a parameter space. + */ +isl_bool isl_space_is_domain_internal(__isl_keep isl_space *space1, + __isl_keep isl_space *space2) +{ + isl_bool equal_params; + + if (!space1 || !space2) + return isl_bool_error; + equal_params = isl_space_has_equal_params(space1, space2); + if (equal_params < 0 || !equal_params) + return equal_params; + return isl_space_has_domain_tuples(space1, space2); +} + +/* Is space1 equal to the domain of space2? + */ +isl_bool isl_space_is_domain(__isl_keep isl_space *space1, + __isl_keep isl_space *space2) +{ + if (!space2) + return isl_bool_error; + if (!isl_space_is_map(space2)) + return isl_bool_false; + return isl_space_is_domain_internal(space1, space2); +} + +/* Is space1 equal to the range of space2? + * + * In the internal version, space2 is allowed to be the space of a set, + * in which case it should be equal to space1. + */ +isl_bool isl_space_is_range_internal(__isl_keep isl_space *space1, + __isl_keep isl_space *space2) +{ + isl_bool equal_params; + + if (!space1 || !space2) + return isl_bool_error; + equal_params = isl_space_has_equal_params(space1, space2); + if (equal_params < 0 || !equal_params) + return equal_params; + return isl_space_has_range_tuples(space1, space2); +} + +/* Is space1 equal to the range of space2? + */ +isl_bool isl_space_is_range(__isl_keep isl_space *space1, + __isl_keep isl_space *space2) +{ + if (!space2) + return isl_bool_error; + if (!isl_space_is_map(space2)) + return isl_bool_false; + return isl_space_is_range_internal(space1, space2); +} + +/* Update "hash" by hashing in the parameters of "space". + */ +static uint32_t isl_hash_params(uint32_t hash, __isl_keep isl_space *space) +{ + int i; + isl_id *id; + + if (!space) + return hash; + + isl_hash_byte(hash, space->nparam % 256); + + for (i = 0; i < space->nparam; ++i) { + id = get_id(space, isl_dim_param, i); + hash = isl_hash_id(hash, id); + } + + return hash; +} + +/* Update "hash" by hashing in the tuples of "space". + * Changes in this function should be reflected in isl_hash_tuples_domain. + */ +static uint32_t isl_hash_tuples(uint32_t hash, __isl_keep isl_space *space) +{ + isl_id *id; + + if (!space) + return hash; + + isl_hash_byte(hash, space->n_in % 256); + isl_hash_byte(hash, space->n_out % 256); + + id = tuple_id(space, isl_dim_in); + hash = isl_hash_id(hash, id); + id = tuple_id(space, isl_dim_out); + hash = isl_hash_id(hash, id); + + hash = isl_hash_tuples(hash, space->nested[0]); + hash = isl_hash_tuples(hash, space->nested[1]); + + return hash; +} + +/* Update "hash" by hashing in the domain tuple of "space". + * The result of this function is equal to the result of applying + * isl_hash_tuples to the domain of "space". + */ +static uint32_t isl_hash_tuples_domain(uint32_t hash, + __isl_keep isl_space *space) +{ + isl_id *id; + + if (!space) + return hash; + + isl_hash_byte(hash, 0); + isl_hash_byte(hash, space->n_in % 256); + + hash = isl_hash_id(hash, &isl_id_none); + id = tuple_id(space, isl_dim_in); + hash = isl_hash_id(hash, id); + + hash = isl_hash_tuples(hash, space->nested[0]); + + return hash; +} + +/* Return a hash value that digests the tuples of "space", + * i.e., that ignores the parameters. + * Changes in this function should be reflected + * in isl_space_get_tuple_domain_hash. + */ +uint32_t isl_space_get_tuple_hash(__isl_keep isl_space *space) +{ + uint32_t hash; + + if (!space) + return 0; + + hash = isl_hash_init(); + hash = isl_hash_tuples(hash, space); + + return hash; +} + +/* Return the hash value of "space". + */ +uint32_t isl_space_get_full_hash(__isl_keep isl_space *space) +{ + uint32_t hash; + + if (!space) + return 0; + + hash = isl_hash_init(); + hash = isl_hash_params(hash, space); + hash = isl_hash_tuples(hash, space); + + return hash; +} + +/* Return the hash value of the domain tuple of "space". + * That is, isl_space_get_tuple_domain_hash(space) is equal to + * isl_space_get_tuple_hash(isl_space_domain(space)). + */ +uint32_t isl_space_get_tuple_domain_hash(__isl_keep isl_space *space) +{ + uint32_t hash; + + if (!space) + return 0; + + hash = isl_hash_init(); + hash = isl_hash_tuples_domain(hash, space); + + return hash; +} + +/* Is "space" the space of a set wrapping a map space? + */ +isl_bool isl_space_is_wrapping(__isl_keep isl_space *space) +{ + if (!space) + return isl_bool_error; + + if (!isl_space_is_set(space)) + return isl_bool_false; + + return isl_bool_ok(space->nested[1] != NULL); +} + +/* Is "space" the space of a map where the domain is a wrapped map space? + */ +isl_bool isl_space_domain_is_wrapping(__isl_keep isl_space *space) +{ + if (!space) + return isl_bool_error; + + if (isl_space_is_set(space)) + return isl_bool_false; + + return isl_bool_ok(space->nested[0] != NULL); +} + +/* Is "space" the space of a map where the range is a wrapped map space? + */ +isl_bool isl_space_range_is_wrapping(__isl_keep isl_space *space) +{ + if (!space) + return isl_bool_error; + + if (isl_space_is_set(space)) + return isl_bool_false; + + return isl_bool_ok(space->nested[1] != NULL); +} + +/* Is "space" a product of two spaces? + * That is, is it a wrapping set space or a map space + * with wrapping domain and range? + */ +isl_bool isl_space_is_product(__isl_keep isl_space *space) +{ + isl_bool is_set; + isl_bool is_product; + + is_set = isl_space_is_set(space); + if (is_set < 0) + return isl_bool_error; + if (is_set) + return isl_space_is_wrapping(space); + is_product = isl_space_domain_is_wrapping(space); + if (is_product < 0 || !is_product) + return is_product; + return isl_space_range_is_wrapping(space); +} + +__isl_give isl_space *isl_space_wrap(__isl_take isl_space *space) +{ + isl_space *wrap; + + if (!space) + return NULL; + + wrap = isl_space_set_alloc(space->ctx, + space->nparam, space->n_in + space->n_out); + + wrap = copy_ids(wrap, isl_dim_param, 0, space, isl_dim_param); + wrap = copy_ids(wrap, isl_dim_set, 0, space, isl_dim_in); + wrap = copy_ids(wrap, isl_dim_set, space->n_in, space, isl_dim_out); + + if (!wrap) + goto error; + + wrap->nested[1] = space; + + return wrap; +error: + isl_space_free(space); + return NULL; +} + +__isl_give isl_space *isl_space_unwrap(__isl_take isl_space *space) +{ + isl_space *unwrap; + + if (!space) + return NULL; + + if (!isl_space_is_wrapping(space)) + isl_die(space->ctx, isl_error_invalid, "not a wrapping space", + goto error); + + unwrap = isl_space_copy(space->nested[1]); + isl_space_free(space); + + return unwrap; +error: + isl_space_free(space); + return NULL; +} + +isl_bool isl_space_is_named_or_nested(__isl_keep isl_space *space, + enum isl_dim_type type) +{ + if (type != isl_dim_in && type != isl_dim_out) + return isl_bool_false; + if (!space) + return isl_bool_error; + if (space->tuple_id[type - isl_dim_in]) + return isl_bool_true; + if (space->nested[type - isl_dim_in]) + return isl_bool_true; + return isl_bool_false; +} + +isl_bool isl_space_may_be_set(__isl_keep isl_space *space) +{ + isl_bool nested; + isl_size n_in; + + if (!space) + return isl_bool_error; + if (isl_space_is_set(space)) + return isl_bool_true; + n_in = isl_space_dim(space, isl_dim_in); + if (n_in < 0) + return isl_bool_error; + if (n_in != 0) + return isl_bool_false; + nested = isl_space_is_named_or_nested(space, isl_dim_in); + if (nested < 0 || nested) + return isl_bool_not(nested); + return isl_bool_true; +} + +__isl_give isl_space *isl_space_reset(__isl_take isl_space *space, + enum isl_dim_type type) +{ + if (!isl_space_is_named_or_nested(space, type)) + return space; + + space = isl_space_cow(space); + if (!space) + return NULL; + + isl_id_free(space->tuple_id[type - isl_dim_in]); + space->tuple_id[type - isl_dim_in] = NULL; + isl_space_free(space->nested[type - isl_dim_in]); + space->nested[type - isl_dim_in] = NULL; + + return space; +} + +__isl_give isl_space *isl_space_flatten(__isl_take isl_space *space) +{ + if (!space) + return NULL; + if (!space->nested[0] && !space->nested[1]) + return space; + + if (space->nested[0]) + space = isl_space_reset(space, isl_dim_in); + if (space && space->nested[1]) + space = isl_space_reset(space, isl_dim_out); + + return space; +} + +__isl_give isl_space *isl_space_flatten_domain(__isl_take isl_space *space) +{ + if (!space) + return NULL; + if (!space->nested[0]) + return space; + + return isl_space_reset(space, isl_dim_in); +} + +__isl_give isl_space *isl_space_flatten_range(__isl_take isl_space *space) +{ + if (!space) + return NULL; + if (!space->nested[1]) + return space; + + return isl_space_reset(space, isl_dim_out); +} + +/* Replace the parameters of dst by those of src. + */ +__isl_give isl_space *isl_space_replace_params(__isl_take isl_space *dst, + __isl_keep isl_space *src) +{ + isl_size dst_dim, src_dim; + isl_bool equal_params; + enum isl_dim_type type = isl_dim_param; + + equal_params = isl_space_has_equal_params(dst, src); + if (equal_params < 0) + return isl_space_free(dst); + if (equal_params) + return dst; + + dst = isl_space_cow(dst); + + dst_dim = isl_space_dim(dst, type); + src_dim = isl_space_dim(src, type); + if (dst_dim < 0 || src_dim < 0) + goto error; + + dst = isl_space_drop_dims(dst, type, 0, dst_dim); + dst = isl_space_add_dims(dst, type, src_dim); + dst = copy_ids(dst, type, 0, src, type); + + if (dst) { + int i; + for (i = 0; i <= 1; ++i) { + isl_space *nested; + + if (!dst->nested[i]) + continue; + nested = isl_space_take_nested(dst, i); + nested = isl_space_replace_params(nested, src); + dst = isl_space_restore_nested(dst, i, nested); + if (!dst) + return NULL; + } + } + + return dst; +error: + isl_space_free(dst); + return NULL; +} + +/* Given two tuples ("dst_type" in "dst" and "src_type" in "src") + * of the same size, check if any of the dimensions in the "dst" tuple + * have no identifier, while the corresponding dimensions in "src" + * does have an identifier, + * If so, copy the identifier over to "dst". + */ +__isl_give isl_space *isl_space_copy_ids_if_unset(__isl_take isl_space *dst, + enum isl_dim_type dst_type, __isl_keep isl_space *src, + enum isl_dim_type src_type) +{ + int i; + isl_size n; + + n = isl_space_dim(dst, dst_type); + if (n < 0) + return isl_space_free(dst); + for (i = 0; i < n; ++i) { + isl_bool set; + isl_id *id; + + set = isl_space_has_dim_id(dst, dst_type, i); + if (set < 0) + return isl_space_free(dst); + if (set) + continue; + + set = isl_space_has_dim_id(src, src_type, i); + if (set < 0) + return isl_space_free(dst); + if (!set) + continue; + + id = isl_space_get_dim_id(src, src_type, i); + dst = isl_space_set_dim_id(dst, dst_type, i, id); + } + + return dst; +} + +/* Given a space "space" of a set, create a space + * for the lift of the set. In particular, the result + * is of the form lifted[space -> local[..]], with n_local variables in the + * range of the wrapped map. + */ +__isl_give isl_space *isl_space_lift(__isl_take isl_space *space, + unsigned n_local) +{ + isl_space *local_space; + + if (!space) + return NULL; + + local_space = isl_space_dup(space); + local_space = isl_space_drop_dims(local_space, isl_dim_set, 0, + space->n_out); + local_space = isl_space_add_dims(local_space, isl_dim_set, n_local); + local_space = isl_space_set_tuple_name(local_space, + isl_dim_set, "local"); + space = isl_space_join(isl_space_from_domain(space), + isl_space_from_range(local_space)); + space = isl_space_wrap(space); + space = isl_space_set_tuple_name(space, isl_dim_set, "lifted"); + + return space; +} + +isl_bool isl_space_can_zip(__isl_keep isl_space *space) +{ + isl_bool is_set; + + is_set = isl_space_is_set(space); + if (is_set < 0) + return isl_bool_error; + if (is_set) + return isl_bool_false; + return isl_space_is_product(space); +} + +__isl_give isl_space *isl_space_zip(__isl_take isl_space *space) +{ + isl_space *dom, *ran; + isl_space *dom_dom, *dom_ran, *ran_dom, *ran_ran; + + if (!isl_space_can_zip(space)) + isl_die(space->ctx, isl_error_invalid, "space cannot be zipped", + goto error); + + if (!space) + return NULL; + dom = isl_space_unwrap(isl_space_domain(isl_space_copy(space))); + ran = isl_space_unwrap(isl_space_range(space)); + dom_dom = isl_space_domain(isl_space_copy(dom)); + dom_ran = isl_space_range(dom); + ran_dom = isl_space_domain(isl_space_copy(ran)); + ran_ran = isl_space_range(ran); + dom = isl_space_join(isl_space_from_domain(dom_dom), + isl_space_from_range(ran_dom)); + ran = isl_space_join(isl_space_from_domain(dom_ran), + isl_space_from_range(ran_ran)); + return isl_space_join(isl_space_from_domain(isl_space_wrap(dom)), + isl_space_from_range(isl_space_wrap(ran))); +error: + isl_space_free(space); + return NULL; +} + +/* Can we apply isl_space_curry to "space"? + * That is, does is it have a map space with a nested relation in its domain? + */ +isl_bool isl_space_can_curry(__isl_keep isl_space *space) +{ + return isl_space_domain_is_wrapping(space); +} + +/* Given a space (A -> B) -> C, return the corresponding space + * A -> (B -> C). + */ +__isl_give isl_space *isl_space_curry(__isl_take isl_space *space) +{ + isl_space *dom, *ran; + isl_space *dom_dom, *dom_ran; + + if (!space) + return NULL; + + if (!isl_space_can_curry(space)) + isl_die(space->ctx, isl_error_invalid, + "space cannot be curried", goto error); + + dom = isl_space_unwrap(isl_space_domain(isl_space_copy(space))); + ran = isl_space_range(space); + dom_dom = isl_space_domain(isl_space_copy(dom)); + dom_ran = isl_space_range(dom); + ran = isl_space_join(isl_space_from_domain(dom_ran), + isl_space_from_range(ran)); + return isl_space_join(isl_space_from_domain(dom_dom), + isl_space_from_range(isl_space_wrap(ran))); +error: + isl_space_free(space); + return NULL; +} + +/* Can isl_space_range_curry be applied to "space"? + * That is, does it have a nested relation in its range, + * the domain of which is itself a nested relation? + */ +isl_bool isl_space_can_range_curry(__isl_keep isl_space *space) +{ + isl_bool can; + + if (!space) + return isl_bool_error; + can = isl_space_range_is_wrapping(space); + if (can < 0 || !can) + return can; + return isl_space_can_curry(space->nested[1]); +} + +/* Given a space A -> ((B -> C) -> D), return the corresponding space + * A -> (B -> (C -> D)). + */ +__isl_give isl_space *isl_space_range_curry(__isl_take isl_space *space) +{ + isl_space *nested; + + if (!space) + return NULL; + + if (!isl_space_can_range_curry(space)) + isl_die(isl_space_get_ctx(space), isl_error_invalid, + "space range cannot be curried", + return isl_space_free(space)); + + nested = isl_space_take_nested(space, 1); + nested = isl_space_curry(nested); + space = isl_space_restore_nested(space, 1, nested); + + return space; +} + +/* Can we apply isl_space_uncurry to "space"? + * That is, does it have a map space with a nested relation in its range? + */ +isl_bool isl_space_can_uncurry(__isl_keep isl_space *space) +{ + return isl_space_range_is_wrapping(space); +} + +/* Given a space A -> (B -> C), return the corresponding space + * (A -> B) -> C. + */ +__isl_give isl_space *isl_space_uncurry(__isl_take isl_space *space) +{ + isl_space *dom, *ran; + isl_space *ran_dom, *ran_ran; + + if (!space) + return NULL; + + if (!isl_space_can_uncurry(space)) + isl_die(space->ctx, isl_error_invalid, + "space cannot be uncurried", + return isl_space_free(space)); + + dom = isl_space_domain(isl_space_copy(space)); + ran = isl_space_unwrap(isl_space_range(space)); + ran_dom = isl_space_domain(isl_space_copy(ran)); + ran_ran = isl_space_range(ran); + dom = isl_space_join(isl_space_from_domain(dom), + isl_space_from_range(ran_dom)); + return isl_space_join(isl_space_from_domain(isl_space_wrap(dom)), + isl_space_from_range(ran_ran)); +} + +isl_bool isl_space_has_named_params(__isl_keep isl_space *space) +{ + int i; + isl_size off; + + if (!space) + return isl_bool_error; + if (space->nparam == 0) + return isl_bool_true; + off = isl_space_offset(space, isl_dim_param); + if (off < 0) + return isl_bool_error; + if (off + space->nparam > space->n_id) + return isl_bool_false; + for (i = 0; i < space->nparam; ++i) + if (!space->ids[off + i]) + return isl_bool_false; + return isl_bool_true; +} + +/* Check that "space" has only named parameters, reporting an error + * if it does not. + */ +isl_stat isl_space_check_named_params(__isl_keep isl_space *space) +{ + isl_bool named; + + named = isl_space_has_named_params(space); + if (named < 0) + return isl_stat_error; + if (!named) + isl_die(isl_space_get_ctx(space), isl_error_invalid, + "unexpected unnamed parameters", return isl_stat_error); + + return isl_stat_ok; +} + +/* Align the initial parameters of space1 to match the order in space2. + */ +__isl_give isl_space *isl_space_align_params(__isl_take isl_space *space1, + __isl_take isl_space *space2) +{ + isl_reordering *exp; + + if (isl_space_check_named_params(space1) < 0 || + isl_space_check_named_params(space2) < 0) + goto error; + + exp = isl_parameter_alignment_reordering(space1, space2); + isl_space_free(space1); + isl_space_free(space2); + space1 = isl_reordering_get_space(exp); + isl_reordering_free(exp); + return space1; +error: + isl_space_free(space1); + isl_space_free(space2); + return NULL; +} + +/* Given the space of set (domain), construct a space for a map + * with as domain the given space and as range the range of "model". + */ +__isl_give isl_space *isl_space_extend_domain_with_range( + __isl_take isl_space *space, __isl_take isl_space *model) +{ + isl_size n_out; + + if (!model) + goto error; + + space = isl_space_from_domain(space); + n_out = isl_space_dim(model, isl_dim_out); + if (n_out < 0) + goto error; + space = isl_space_add_dims(space, isl_dim_out, n_out); + if (isl_space_has_tuple_id(model, isl_dim_out)) + space = isl_space_set_tuple_id(space, isl_dim_out, + isl_space_get_tuple_id(model, isl_dim_out)); + if (!space) + goto error; + if (model->nested[1]) { + isl_space *nested = isl_space_copy(model->nested[1]); + isl_size n_nested, n_space; + nested = isl_space_align_params(nested, isl_space_copy(space)); + n_nested = isl_space_dim(nested, isl_dim_param); + n_space = isl_space_dim(space, isl_dim_param); + if (n_nested < 0 || n_space < 0) + goto error; + if (n_nested > n_space) + nested = isl_space_drop_dims(nested, isl_dim_param, + n_space, n_nested - n_space); + if (!nested) + goto error; + space->nested[1] = nested; + } + isl_space_free(model); + return space; +error: + isl_space_free(model); + isl_space_free(space); + return NULL; +} + +/* Compare the "type" dimensions of two isl_spaces. + * + * The order is fairly arbitrary. + */ +static int isl_space_cmp_type(__isl_keep isl_space *space1, + __isl_keep isl_space *space2, enum isl_dim_type type) +{ + int cmp; + isl_size dim1, dim2; + isl_space *nested1, *nested2; + + dim1 = isl_space_dim(space1, type); + dim2 = isl_space_dim(space2, type); + if (dim1 < 0 || dim2 < 0) + return 0; + if (dim1 != dim2) + return dim1 - dim2; + + cmp = isl_id_cmp(tuple_id(space1, type), tuple_id(space2, type)); + if (cmp != 0) + return cmp; + + nested1 = nested(space1, type); + nested2 = nested(space2, type); + if (!nested1 != !nested2) + return !nested1 - !nested2; + + if (nested1) + return isl_space_cmp(nested1, nested2); + + return 0; +} + +/* Compare two isl_spaces. + * + * The order is fairly arbitrary. + */ +int isl_space_cmp(__isl_keep isl_space *space1, __isl_keep isl_space *space2) +{ + int i; + int cmp; + + if (space1 == space2) + return 0; + if (!space1) + return -1; + if (!space2) + return 1; + + cmp = isl_space_cmp_type(space1, space2, isl_dim_param); + if (cmp != 0) + return cmp; + cmp = isl_space_cmp_type(space1, space2, isl_dim_in); + if (cmp != 0) + return cmp; + cmp = isl_space_cmp_type(space1, space2, isl_dim_out); + if (cmp != 0) + return cmp; + + if (!space1->ids && !space2->ids) + return 0; + + for (i = 0; i < n(space1, isl_dim_param); ++i) { + cmp = isl_id_cmp(get_id(space1, isl_dim_param, i), + get_id(space2, isl_dim_param, i)); + if (cmp != 0) + return cmp; + } + + return 0; +} diff --git a/external/mit/isl/dist/isl_space_private.h b/external/mit/isl/dist/isl_space_private.h new file mode 100644 index 000000000000..e34e769eb984 --- /dev/null +++ b/external/mit/isl/dist/isl_space_private.h @@ -0,0 +1,106 @@ +#ifndef ISL_SPACE_PRIVATE +#define ISL_SPACE_PRIVATE + +#include +#include +#include +#include + +struct isl_name; +struct isl_space { + int ref; + + struct isl_ctx *ctx; + + unsigned nparam; + unsigned n_in; /* zero for sets */ + unsigned n_out; /* dim for sets */ + + isl_id *tuple_id[2]; + isl_space *nested[2]; + + unsigned n_id; + isl_id **ids; +}; + +__isl_give isl_space *isl_space_cow(__isl_take isl_space *space); + +__isl_give isl_space *isl_space_underlying(__isl_take isl_space *space, + unsigned n_div); + +uint32_t isl_space_get_tuple_hash(__isl_keep isl_space *space); +uint32_t isl_space_get_tuple_domain_hash(__isl_keep isl_space *space); +uint32_t isl_space_get_full_hash(__isl_keep isl_space *space); + +isl_bool isl_space_has_domain_tuples(__isl_keep isl_space *space1, + __isl_keep isl_space *space2); +isl_bool isl_space_has_range_tuples(__isl_keep isl_space *space1, + __isl_keep isl_space *space2); +isl_stat isl_space_check_domain_tuples(__isl_keep isl_space *space1, + __isl_keep isl_space *space2); +isl_bool isl_space_is_domain_internal(__isl_keep isl_space *space1, + __isl_keep isl_space *space2); +isl_bool isl_space_is_range_internal(__isl_keep isl_space *space1, + __isl_keep isl_space *space2); +isl_stat isl_space_check_domain_wrapped_domain_tuples( + __isl_keep isl_space *space1, __isl_keep isl_space *space2); +isl_bool isl_space_wrapped_tuple_is_equal(__isl_keep isl_space *space1, + enum isl_dim_type outer, enum isl_dim_type inner, + __isl_keep isl_space *space2, enum isl_dim_type type2); +isl_stat isl_space_check_wrapped_tuple_is_equal(__isl_keep isl_space *space1, + enum isl_dim_type outer, enum isl_dim_type inner, + __isl_keep isl_space *space2, enum isl_dim_type type2); + +isl_size isl_space_wrapped_dim(__isl_keep isl_space *space, + enum isl_dim_type outer, enum isl_dim_type inner); +isl_size isl_space_offset(__isl_keep isl_space *space, enum isl_dim_type type); + +isl_stat isl_space_check_range(__isl_keep isl_space *space, + enum isl_dim_type type, unsigned first, unsigned n); +isl_stat isl_space_check_is_set(__isl_keep isl_space *space); +isl_bool isl_space_may_be_set(__isl_keep isl_space *space); +isl_bool isl_space_is_named_or_nested(__isl_keep isl_space *space, + enum isl_dim_type type); +isl_bool isl_space_has_equal_ids(__isl_keep isl_space *space1, + __isl_keep isl_space *space2); +isl_bool isl_space_has_named_params(__isl_keep isl_space *space); +isl_stat isl_space_check_named_params(__isl_keep isl_space *space); +isl_stat isl_space_check_equal_params(__isl_keep isl_space *space1, + __isl_keep isl_space *space2); +isl_stat isl_space_check_equal_tuples(__isl_keep isl_space *space1, + __isl_keep isl_space *space2); +__isl_give isl_space *isl_space_reset(__isl_take isl_space *space, + enum isl_dim_type type); +__isl_give isl_space *isl_space_flatten(__isl_take isl_space *space); + +isl_stat isl_space_check_is_wrapping(__isl_keep isl_space *space); +isl_stat isl_space_check_domain_is_wrapping(__isl_keep isl_space *space); +isl_stat isl_space_check_range_is_wrapping(__isl_keep isl_space *space); + +__isl_give isl_space *isl_space_replace_params(__isl_take isl_space *dst, + __isl_keep isl_space *src); +__isl_give isl_space *isl_space_copy_ids_if_unset(__isl_take isl_space *dst, + enum isl_dim_type dst_type, __isl_keep isl_space *src, + enum isl_dim_type src_type); + +__isl_give isl_space *isl_space_lift(__isl_take isl_space *space, + unsigned n_local); + +__isl_give isl_space *isl_space_extend_domain_with_range( + __isl_take isl_space *domain, __isl_take isl_space *model); +__isl_give isl_space *isl_space_bind_set(__isl_take isl_space *space, + __isl_keep isl_multi_id *tuple); +__isl_give isl_space *isl_space_bind_map_domain(__isl_take isl_space *space, + __isl_keep isl_multi_id *tuple); +__isl_give isl_space *isl_space_bind_domain_wrapped_domain( + __isl_take isl_space *space, __isl_keep isl_multi_id *tuple); +__isl_give isl_space *isl_space_unbind_params_insert_domain( + __isl_take isl_space *space, __isl_keep isl_multi_id *tuple); +__isl_give isl_space *isl_space_reverse_wrapped(__isl_take isl_space *space, + enum isl_dim_type type); + +int isl_space_cmp(__isl_keep isl_space *space1, __isl_keep isl_space *space2); + +__isl_give isl_space *isl_stream_read_space(__isl_keep isl_stream *s); + +#endif diff --git a/external/mit/isl/dist/isl_srcdir.c.in b/external/mit/isl/dist/isl_srcdir.c.in new file mode 100644 index 000000000000..7f39904074b5 --- /dev/null +++ b/external/mit/isl/dist/isl_srcdir.c.in @@ -0,0 +1 @@ +static const char *srcdir = "@OS_SRCDIR@"; diff --git a/external/mit/isl/dist/isl_stream.c b/external/mit/isl/dist/isl_stream.c new file mode 100644 index 000000000000..9fffd45bf152 --- /dev/null +++ b/external/mit/isl/dist/isl_stream.c @@ -0,0 +1,1197 @@ +/* + * 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 + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +struct isl_keyword { + char *name; + enum isl_token_type type; +}; + +static isl_bool same_name(const void *entry, const void *val) +{ + const struct isl_keyword *keyword = (const struct isl_keyword *)entry; + + return isl_bool_ok(!strcmp(keyword->name, val)); +} + +enum isl_token_type isl_stream_register_keyword(__isl_keep isl_stream *s, + const char *name) +{ + struct isl_hash_table_entry *entry; + struct isl_keyword *keyword; + uint32_t name_hash; + + if (!s->keywords) { + s->keywords = isl_hash_table_alloc(s->ctx, 10); + if (!s->keywords) + return ISL_TOKEN_ERROR; + s->next_type = ISL_TOKEN_LAST; + } + + name_hash = isl_hash_string(isl_hash_init(), name); + + entry = isl_hash_table_find(s->ctx, s->keywords, name_hash, + same_name, name, 1); + if (!entry) + return ISL_TOKEN_ERROR; + if (entry->data) { + keyword = entry->data; + return keyword->type; + } + + keyword = isl_calloc_type(s->ctx, struct isl_keyword); + if (!keyword) + return ISL_TOKEN_ERROR; + keyword->type = s->next_type++; + keyword->name = strdup(name); + if (!keyword->name) { + free(keyword); + return ISL_TOKEN_ERROR; + } + entry->data = keyword; + + return keyword->type; +} + +struct isl_token *isl_token_new(isl_ctx *ctx, + int line, int col, unsigned on_new_line) +{ + struct isl_token *tok = isl_alloc_type(ctx, struct isl_token); + if (!tok) + return NULL; + tok->line = line; + tok->col = col; + tok->on_new_line = on_new_line; + tok->is_keyword = 0; + tok->u.s = NULL; + return tok; +} + +/* Return the type of "tok". + */ +int isl_token_get_type(struct isl_token *tok) +{ + return tok ? tok->type : ISL_TOKEN_ERROR; +} + +/* Given a token of type ISL_TOKEN_VALUE, return the value it represents. + */ +__isl_give isl_val *isl_token_get_val(isl_ctx *ctx, struct isl_token *tok) +{ + if (!tok) + return NULL; + if (tok->type != ISL_TOKEN_VALUE) + isl_die(ctx, isl_error_invalid, "not a value token", + return NULL); + + return isl_val_int_from_isl_int(ctx, tok->u.v); +} + +/* Does the given token have a string representation? + */ +isl_bool isl_token_has_str(struct isl_token *tok) +{ + if (!tok) + return isl_bool_error; + return isl_bool_ok(tok->u.s != NULL); +} + +/* Given a token with a string representation, return a copy of this string. + */ +__isl_give char *isl_token_get_str(isl_ctx *ctx, struct isl_token *tok) +{ + if (!tok) + return NULL; + if (!tok->u.s) + isl_die(ctx, isl_error_invalid, + "token does not have a string representation", + return NULL); + + return strdup(tok->u.s); +} + +void isl_token_free(struct isl_token *tok) +{ + if (!tok) + return; + if (tok->type == ISL_TOKEN_VALUE) + isl_int_clear(tok->u.v); + else if (tok->type == ISL_TOKEN_MAP) + isl_map_free(tok->u.map); + else if (tok->type == ISL_TOKEN_AFF) + isl_pw_aff_free(tok->u.pwaff); + else + free(tok->u.s); + free(tok); +} + +void isl_stream_error(__isl_keep isl_stream *s, struct isl_token *tok, + char *msg) +{ + int line = tok ? tok->line : s->line; + int col = tok ? tok->col : s->col; + + isl_ctx_set_full_error(s->ctx, isl_error_invalid, "syntax error", + __FILE__, __LINE__); + + if (s->ctx->opt->on_error == ISL_ON_ERROR_CONTINUE) + return; + fprintf(stderr, "syntax error (%d, %d): %s\n", line, col, msg); + if (tok) { + if (tok->type < 256) + fprintf(stderr, "got '%c'\n", tok->type); + else if (tok->type == ISL_TOKEN_IDENT) + fprintf(stderr, "got ident '%s'\n", tok->u.s); + else if (tok->is_keyword) + fprintf(stderr, "got keyword '%s'\n", tok->u.s); + else if (tok->type == ISL_TOKEN_VALUE) { + fprintf(stderr, "got value '"); + isl_int_print(stderr, tok->u.v, 0); + fprintf(stderr, "'\n"); + } else if (tok->type == ISL_TOKEN_MAP) { + isl_printer *p; + fprintf(stderr, "got map '"); + p = isl_printer_to_file(s->ctx, stderr); + p = isl_printer_print_map(p, tok->u.map); + isl_printer_free(p); + fprintf(stderr, "'\n"); + } else if (tok->type == ISL_TOKEN_AFF) { + isl_printer *p; + fprintf(stderr, "got affine expression '"); + p = isl_printer_to_file(s->ctx, stderr); + p = isl_printer_print_pw_aff(p, tok->u.pwaff); + isl_printer_free(p); + fprintf(stderr, "'\n"); + } else if (tok->u.s) + fprintf(stderr, "got token '%s'\n", tok->u.s); + else + fprintf(stderr, "got token type %d\n", tok->type); + } + if (s->ctx->opt->on_error == ISL_ON_ERROR_ABORT) + abort(); +} + +static __isl_give isl_stream* isl_stream_new(struct isl_ctx *ctx) +{ + int i; + isl_stream *s = isl_calloc_type(ctx, struct isl_stream); + if (!s) + return NULL; + s->ctx = ctx; + isl_ctx_ref(s->ctx); + s->file = NULL; + s->str = NULL; + s->len = 0; + s->line = 1; + s->col = 1; + s->eof = 0; + s->last_line = 0; + s->c = -1; + s->n_un = 0; + for (i = 0; i < 5; ++i) + s->tokens[i] = NULL; + s->n_token = 0; + s->keywords = NULL; + s->size = 256; + s->buffer = isl_alloc_array(ctx, char, s->size); + if (!s->buffer) + goto error; + return s; +error: + isl_stream_free(s); + return NULL; +} + +__isl_give isl_stream* isl_stream_new_file(struct isl_ctx *ctx, FILE *file) +{ + isl_stream *s = isl_stream_new(ctx); + if (!s) + return NULL; + s->file = file; + return s; +} + +__isl_give isl_stream* isl_stream_new_str(struct isl_ctx *ctx, const char *str) +{ + isl_stream *s; + if (!str) + return NULL; + s = isl_stream_new(ctx); + if (!s) + return NULL; + s->str = str; + return s; +} + +/* Read a character from the stream and advance s->line and s->col + * to point to the next character. + */ +static int stream_getc(__isl_keep isl_stream *s) +{ + int c; + if (s->eof) + return -1; + if (s->n_un) + return s->c = s->un[--s->n_un]; + if (s->file) + c = fgetc(s->file); + else { + c = *s->str++; + if (c == '\0') + c = -1; + } + if (c == -1) + s->eof = 1; + else if (c == '\n') { + s->line++; + s->col = 1; + } else + s->col++; + s->c = c; + return c; +} + +static void isl_stream_ungetc(__isl_keep isl_stream *s, int c) +{ + isl_assert(s->ctx, s->n_un < 5, return); + s->un[s->n_un++] = c; + s->c = -1; +} + +/* Read a character from the stream, skipping pairs of '\\' and '\n'. + * Set s->start_line and s->start_col to the line and column + * of the returned character. + */ +static int isl_stream_getc(__isl_keep isl_stream *s) +{ + int c; + + do { + s->start_line = s->line; + s->start_col = s->col; + c = stream_getc(s); + if (c != '\\') + return c; + c = stream_getc(s); + } while (c == '\n'); + + isl_stream_ungetc(s, c); + + return '\\'; +} + +static int isl_stream_push_char(__isl_keep isl_stream *s, int c) +{ + if (s->len >= s->size) { + char *buffer; + s->size = (3*s->size)/2; + buffer = isl_realloc_array(s->ctx, s->buffer, char, s->size); + if (!buffer) + return -1; + s->buffer = buffer; + } + s->buffer[s->len++] = c; + return 0; +} + +void isl_stream_push_token(__isl_keep isl_stream *s, struct isl_token *tok) +{ + isl_assert(s->ctx, s->n_token < 5, return); + s->tokens[s->n_token++] = tok; +} + +static enum isl_token_type check_keywords(__isl_keep isl_stream *s) +{ + struct isl_hash_table_entry *entry; + struct isl_keyword *keyword; + uint32_t name_hash; + + if (!strcasecmp(s->buffer, "exists")) + return ISL_TOKEN_EXISTS; + if (!strcasecmp(s->buffer, "and")) + return ISL_TOKEN_AND; + if (!strcasecmp(s->buffer, "or")) + return ISL_TOKEN_OR; + if (!strcasecmp(s->buffer, "implies")) + return ISL_TOKEN_IMPLIES; + if (!strcasecmp(s->buffer, "not")) + return ISL_TOKEN_NOT; + if (!strcasecmp(s->buffer, "infty")) + return ISL_TOKEN_INFTY; + if (!strcasecmp(s->buffer, "infinity")) + return ISL_TOKEN_INFTY; + if (!strcasecmp(s->buffer, "NaN")) + return ISL_TOKEN_NAN; + if (!strcasecmp(s->buffer, "min")) + return ISL_TOKEN_MIN; + if (!strcasecmp(s->buffer, "max")) + return ISL_TOKEN_MAX; + if (!strcasecmp(s->buffer, "rat")) + return ISL_TOKEN_RAT; + if (!strcasecmp(s->buffer, "true")) + return ISL_TOKEN_TRUE; + if (!strcasecmp(s->buffer, "false")) + return ISL_TOKEN_FALSE; + if (!strcasecmp(s->buffer, "ceild")) + return ISL_TOKEN_CEILD; + if (!strcasecmp(s->buffer, "floord")) + return ISL_TOKEN_FLOORD; + if (!strcasecmp(s->buffer, "mod")) + return ISL_TOKEN_MOD; + if (!strcasecmp(s->buffer, "ceil")) + return ISL_TOKEN_CEIL; + if (!strcasecmp(s->buffer, "floor")) + return ISL_TOKEN_FLOOR; + + if (!s->keywords) + return ISL_TOKEN_IDENT; + + name_hash = isl_hash_string(isl_hash_init(), s->buffer); + entry = isl_hash_table_find(s->ctx, s->keywords, name_hash, same_name, + s->buffer, 0); + if (!entry) + return ISL_TOKEN_ERROR; + if (entry != isl_hash_table_entry_none) { + keyword = entry->data; + return keyword->type; + } + + return ISL_TOKEN_IDENT; +} + +int isl_stream_skip_line(__isl_keep isl_stream *s) +{ + int c; + + while ((c = isl_stream_getc(s)) != -1 && c != '\n') + /* nothing */ + ; + + return c == -1 ? -1 : 0; +} + +static struct isl_token *next_token(__isl_keep isl_stream *s, int same_line) +{ + int c; + struct isl_token *tok = NULL; + int line, col; + int old_line = s->last_line; + + if (s->n_token) { + if (same_line && s->tokens[s->n_token - 1]->on_new_line) + return NULL; + return s->tokens[--s->n_token]; + } + + if (same_line && s->c == '\n') + return NULL; + + s->len = 0; + + /* skip spaces and comment lines */ + while ((c = isl_stream_getc(s)) != -1) { + if (c == '#') { + if (isl_stream_skip_line(s) < 0) + break; + c = '\n'; + if (same_line) + break; + } else if (!isspace(c) || (same_line && c == '\n')) + break; + } + + line = s->start_line; + col = s->start_col; + + if (c == -1 || (same_line && c == '\n')) + return NULL; + s->last_line = line; + + if (c == '(' || + c == ')' || + c == '+' || + c == '*' || + c == '%' || + c == '?' || + c == '^' || + c == '@' || + c == '$' || + c == ',' || + c == '.' || + c == ';' || + c == '[' || + c == ']' || + c == '{' || + c == '}') { + tok = isl_token_new(s->ctx, line, col, old_line != line); + if (!tok) + return NULL; + tok->type = (enum isl_token_type)c; + return tok; + } + if (c == '-') { + int c; + if ((c = isl_stream_getc(s)) == '>') { + tok = isl_token_new(s->ctx, line, col, old_line != line); + if (!tok) + return NULL; + tok->u.s = strdup("->"); + tok->type = ISL_TOKEN_TO; + return tok; + } + if (c != -1) + isl_stream_ungetc(s, c); + tok = isl_token_new(s->ctx, line, col, old_line != line); + if (!tok) + return NULL; + tok->type = (enum isl_token_type) '-'; + return tok; + } + if (isdigit(c)) { + int minus = c == '-'; + tok = isl_token_new(s->ctx, line, col, old_line != line); + if (!tok) + return NULL; + tok->type = ISL_TOKEN_VALUE; + isl_int_init(tok->u.v); + if (isl_stream_push_char(s, c)) + goto error; + while ((c = isl_stream_getc(s)) != -1 && isdigit(c)) + if (isl_stream_push_char(s, c)) + goto error; + if (c != -1) + isl_stream_ungetc(s, c); + isl_stream_push_char(s, '\0'); + isl_int_read(tok->u.v, s->buffer); + if (minus && isl_int_is_zero(tok->u.v)) { + tok->col++; + tok->on_new_line = 0; + isl_stream_push_token(s, tok); + tok = isl_token_new(s->ctx, line, col, old_line != line); + if (!tok) + return NULL; + tok->type = (enum isl_token_type) '-'; + } + return tok; + } + if (isalpha(c) || c == '_') { + tok = isl_token_new(s->ctx, line, col, old_line != line); + if (!tok) + return NULL; + isl_stream_push_char(s, c); + while ((c = isl_stream_getc(s)) != -1 && + (isalnum(c) || c == '_')) + isl_stream_push_char(s, c); + if (c != -1) + isl_stream_ungetc(s, c); + while ((c = isl_stream_getc(s)) != -1 && c == '\'') + isl_stream_push_char(s, c); + if (c != -1) + isl_stream_ungetc(s, c); + isl_stream_push_char(s, '\0'); + tok->type = check_keywords(s); + if (tok->type != ISL_TOKEN_IDENT) + tok->is_keyword = 1; + tok->u.s = strdup(s->buffer); + if (!tok->u.s) + goto error; + return tok; + } + if (c == '"') { + tok = isl_token_new(s->ctx, line, col, old_line != line); + if (!tok) + return NULL; + tok->type = ISL_TOKEN_STRING; + tok->u.s = NULL; + while ((c = isl_stream_getc(s)) != -1 && c != '"' && c != '\n') + isl_stream_push_char(s, c); + if (c != '"') { + isl_stream_error(s, NULL, "unterminated string"); + goto error; + } + isl_stream_push_char(s, '\0'); + tok->u.s = strdup(s->buffer); + return tok; + } + if (c == '=') { + int c; + tok = isl_token_new(s->ctx, line, col, old_line != line); + if (!tok) + return NULL; + if ((c = isl_stream_getc(s)) == '=') { + tok->u.s = strdup("=="); + tok->type = ISL_TOKEN_EQ_EQ; + return tok; + } + if (c != -1) + isl_stream_ungetc(s, c); + tok->type = (enum isl_token_type) '='; + return tok; + } + if (c == ':') { + int c; + tok = isl_token_new(s->ctx, line, col, old_line != line); + if (!tok) + return NULL; + if ((c = isl_stream_getc(s)) == '=') { + tok->u.s = strdup(":="); + tok->type = ISL_TOKEN_DEF; + return tok; + } + if (c != -1) + isl_stream_ungetc(s, c); + tok->type = (enum isl_token_type) ':'; + return tok; + } + if (c == '>') { + int c; + tok = isl_token_new(s->ctx, line, col, old_line != line); + if (!tok) + return NULL; + if ((c = isl_stream_getc(s)) == '=') { + tok->u.s = strdup(">="); + tok->type = ISL_TOKEN_GE; + return tok; + } else if (c == '>') { + if ((c = isl_stream_getc(s)) == '=') { + tok->u.s = strdup(">>="); + tok->type = ISL_TOKEN_LEX_GE; + return tok; + } + tok->u.s = strdup(">>"); + tok->type = ISL_TOKEN_LEX_GT; + } else { + tok->u.s = strdup(">"); + tok->type = ISL_TOKEN_GT; + } + if (c != -1) + isl_stream_ungetc(s, c); + return tok; + } + if (c == '<') { + int c; + tok = isl_token_new(s->ctx, line, col, old_line != line); + if (!tok) + return NULL; + if ((c = isl_stream_getc(s)) == '=') { + tok->u.s = strdup("<="); + tok->type = ISL_TOKEN_LE; + return tok; + } else if (c == '<') { + if ((c = isl_stream_getc(s)) == '=') { + tok->u.s = strdup("<<="); + tok->type = ISL_TOKEN_LEX_LE; + return tok; + } + tok->u.s = strdup("<<"); + tok->type = ISL_TOKEN_LEX_LT; + } else { + tok->u.s = strdup("<"); + tok->type = ISL_TOKEN_LT; + } + if (c != -1) + isl_stream_ungetc(s, c); + return tok; + } + if (c == '&') { + tok = isl_token_new(s->ctx, line, col, old_line != line); + if (!tok) + return NULL; + tok->type = ISL_TOKEN_AND; + if ((c = isl_stream_getc(s)) != '&' && c != -1) { + tok->u.s = strdup("&"); + isl_stream_ungetc(s, c); + } else + tok->u.s = strdup("&&"); + return tok; + } + if (c == '|') { + tok = isl_token_new(s->ctx, line, col, old_line != line); + if (!tok) + return NULL; + tok->type = ISL_TOKEN_OR; + if ((c = isl_stream_getc(s)) != '|' && c != -1) { + tok->u.s = strdup("|"); + isl_stream_ungetc(s, c); + } else + tok->u.s = strdup("||"); + return tok; + } + if (c == '/') { + tok = isl_token_new(s->ctx, line, col, old_line != line); + if (!tok) + return NULL; + if ((c = isl_stream_getc(s)) == '\\') { + tok->u.s = strdup("/\\"); + tok->type = ISL_TOKEN_AND; + return tok; + } else if (c == '/') { + tok->u.s = strdup("//"); + tok->type = ISL_TOKEN_INT_DIV; + return tok; + } else { + tok->type = (enum isl_token_type) '/'; + } + if (c != -1) + isl_stream_ungetc(s, c); + return tok; + } + if (c == '\\') { + tok = isl_token_new(s->ctx, line, col, old_line != line); + if (!tok) + return NULL; + if ((c = isl_stream_getc(s)) != '/' && c != -1) { + tok->type = (enum isl_token_type) '\\'; + isl_stream_ungetc(s, c); + } else { + tok->u.s = strdup("\\/"); + tok->type = ISL_TOKEN_OR; + } + return tok; + } + if (c == '!') { + tok = isl_token_new(s->ctx, line, col, old_line != line); + if (!tok) + return NULL; + if ((c = isl_stream_getc(s)) == '=') { + tok->u.s = strdup("!="); + tok->type = ISL_TOKEN_NE; + return tok; + } else { + tok->type = ISL_TOKEN_NOT; + tok->u.s = strdup("!"); + } + if (c != -1) + isl_stream_ungetc(s, c); + return tok; + } + + tok = isl_token_new(s->ctx, line, col, old_line != line); + if (!tok) + return NULL; + tok->type = ISL_TOKEN_UNKNOWN; + return tok; +error: + isl_token_free(tok); + return NULL; +} + +struct isl_token *isl_stream_next_token(__isl_keep isl_stream *s) +{ + return next_token(s, 0); +} + +struct isl_token *isl_stream_next_token_on_same_line(__isl_keep isl_stream *s) +{ + return next_token(s, 1); +} + +int isl_stream_eat_if_available(__isl_keep isl_stream *s, int type) +{ + struct isl_token *tok; + + tok = isl_stream_next_token(s); + if (!tok) + return 0; + if (tok->type == type) { + isl_token_free(tok); + return 1; + } + isl_stream_push_token(s, tok); + return 0; +} + +int isl_stream_next_token_is(__isl_keep isl_stream *s, int type) +{ + struct isl_token *tok; + int r; + + tok = isl_stream_next_token(s); + if (!tok) + return 0; + r = tok->type == type; + isl_stream_push_token(s, tok); + return r; +} + +char *isl_stream_read_ident_if_available(__isl_keep isl_stream *s) +{ + struct isl_token *tok; + + tok = isl_stream_next_token(s); + if (!tok) + return NULL; + if (tok->type == ISL_TOKEN_IDENT) { + char *ident = strdup(tok->u.s); + isl_token_free(tok); + return ident; + } + isl_stream_push_token(s, tok); + return NULL; +} + +int isl_stream_eat(__isl_keep isl_stream *s, int type) +{ + struct isl_token *tok; + + tok = isl_stream_next_token(s); + if (!tok) { + if (s->eof) + isl_stream_error(s, NULL, "unexpected EOF"); + return -1; + } + if (tok->type == type) { + isl_token_free(tok); + return 0; + } + isl_stream_error(s, tok, "expecting other token"); + isl_token_free(tok); + return -1; +} + +int isl_stream_is_empty(__isl_keep isl_stream *s) +{ + struct isl_token *tok; + + tok = isl_stream_next_token(s); + + if (!tok) + return 1; + + isl_stream_push_token(s, tok); + return 0; +} + +static isl_stat free_keyword(void **p, void *user) +{ + struct isl_keyword *keyword = *p; + + free(keyword->name); + free(keyword); + + return isl_stat_ok; +} + +void isl_stream_flush_tokens(__isl_keep isl_stream *s) +{ + int i; + + if (!s) + return; + for (i = 0; i < s->n_token; ++i) + isl_token_free(s->tokens[i]); + s->n_token = 0; +} + +isl_ctx *isl_stream_get_ctx(__isl_keep isl_stream *s) +{ + return s ? s->ctx : NULL; +} + +void isl_stream_free(__isl_take isl_stream *s) +{ + if (!s) + return; + free(s->buffer); + if (s->n_token != 0) { + struct isl_token *tok = isl_stream_next_token(s); + isl_stream_error(s, tok, "unexpected token"); + isl_token_free(tok); + } + if (s->keywords) { + isl_hash_table_foreach(s->ctx, s->keywords, &free_keyword, NULL); + isl_hash_table_free(s->ctx, s->keywords); + } + free(s->yaml_state); + free(s->yaml_indent); + isl_ctx_deref(s->ctx); + free(s); +} + +/* Push "state" onto the stack of currently active YAML elements. + * The caller is responsible for setting the corresponding indentation. + * Return 0 on success and -1 on failure. + */ +static int push_state(__isl_keep isl_stream *s, enum isl_yaml_state state) +{ + if (s->yaml_size < s->yaml_depth + 1) { + int *indent; + enum isl_yaml_state *state; + + state = isl_realloc_array(s->ctx, s->yaml_state, + enum isl_yaml_state, s->yaml_depth + 1); + if (!state) + return -1; + s->yaml_state = state; + + indent = isl_realloc_array(s->ctx, s->yaml_indent, + int, s->yaml_depth + 1); + if (!indent) + return -1; + s->yaml_indent = indent; + + s->yaml_size = s->yaml_depth + 1; + } + + s->yaml_state[s->yaml_depth] = state; + s->yaml_depth++; + + return 0; +} + +/* Remove the innermost active YAML element from the stack. + * Return isl_stat_ok on success and isl_stat_error on failure. + */ +static isl_stat pop_state(__isl_keep isl_stream *s) +{ + if (!s) + return isl_stat_error; + if (s->yaml_depth < 1) + isl_die(isl_stream_get_ctx(s), isl_error_invalid, + "not in YAML construct", return isl_stat_error); + + s->yaml_depth--; + + return isl_stat_ok; +} + +/* Set the state of the innermost active YAML element to "state". + * Return 0 on success and -1 on failure. + */ +static int update_state(__isl_keep isl_stream *s, enum isl_yaml_state state) +{ + if (!s) + return -1; + if (s->yaml_depth < 1) + isl_die(isl_stream_get_ctx(s), isl_error_invalid, + "not in YAML construct", return -1); + + s->yaml_state[s->yaml_depth - 1] = state; + + return 0; +} + +/* Return the state of the innermost active YAML element. + * Return isl_yaml_none if we are not inside any YAML element. + */ +static enum isl_yaml_state current_state(__isl_keep isl_stream *s) +{ + if (!s) + return isl_yaml_none; + if (s->yaml_depth < 1) + return isl_yaml_none; + return s->yaml_state[s->yaml_depth - 1]; +} + +/* Set the indentation of the innermost active YAML element to "indent". + * If "indent" is equal to ISL_YAML_INDENT_FLOW, then this means + * that the current element is in flow format. + */ +static isl_stat set_yaml_indent(__isl_keep isl_stream *s, int indent) +{ + if (s->yaml_depth < 1) + isl_die(s->ctx, isl_error_internal, + "not in YAML element", return isl_stat_error); + + s->yaml_indent[s->yaml_depth - 1] = indent; + + return isl_stat_ok; +} + +/* Return the indentation of the innermost active YAML element + * of -1 on error. + */ +static int get_yaml_indent(__isl_keep isl_stream *s) +{ + if (s->yaml_depth < 1) + isl_die(s->ctx, isl_error_internal, + "not in YAML element", return -1); + + return s->yaml_indent[s->yaml_depth - 1]; +} + +/* Move to the next state at the innermost level. + * Return isl_bool_true if successful. + * Return isl_bool_false if we are at the end of the innermost level. + * Return isl_bool_error on error. + * + * If we are in state isl_yaml_mapping_key_start, then we have just + * started a mapping and we are expecting a key. If the mapping started + * with a '{', then we check if the next token is a '}'. If so, + * then the mapping is empty and there is no next state at this level. + * Otherwise, we assume that there is at least one key (the one from + * which we derived the indentation in isl_stream_yaml_read_start_mapping. + * + * If we are in state isl_yaml_mapping_key, then the we expect a colon + * followed by a value, so there is always a next state unless + * some error occurs. + * + * If we are in state isl_yaml_mapping_val, then there may or may + * not be a subsequent key in the same mapping. + * In flow format, the next key is preceded by a comma. + * In block format, the next key has the same indentation as the first key. + * If the first token has a smaller indentation, then we have reached + * the end of the current mapping. + * + * If we are in state isl_yaml_sequence_start, then we have just + * started a sequence. If the sequence started with a '[', + * then we check if the next token is a ']'. If so, then the sequence + * is empty and there is no next state at this level. + * Otherwise, we assume that there is at least one element in the sequence + * (the one from which we derived the indentation in + * isl_stream_yaml_read_start_sequence. + * + * If we are in state isl_yaml_sequence, then there may or may + * not be a subsequent element in the same sequence. + * In flow format, the next element is preceded by a comma. + * In block format, the next element is introduced by a dash with + * the same indentation as that of the first element. + * If the first token is not a dash or if it has a smaller indentation, + * then we have reached the end of the current sequence. + */ +isl_bool isl_stream_yaml_next(__isl_keep isl_stream *s) +{ + struct isl_token *tok; + enum isl_yaml_state state; + int indent; + + state = current_state(s); + if (state == isl_yaml_none) + isl_die(s->ctx, isl_error_invalid, + "not in YAML element", return isl_bool_error); + switch (state) { + case isl_yaml_mapping_key_start: + if (get_yaml_indent(s) == ISL_YAML_INDENT_FLOW && + isl_stream_next_token_is(s, '}')) + return isl_bool_false; + if (update_state(s, isl_yaml_mapping_key) < 0) + return isl_bool_error; + return isl_bool_true; + case isl_yaml_mapping_key: + tok = isl_stream_next_token(s); + if (!tok) { + if (s->eof) + isl_stream_error(s, NULL, "unexpected EOF"); + return isl_bool_error; + } + if (tok->type == ':') { + isl_token_free(tok); + if (update_state(s, isl_yaml_mapping_val) < 0) + return isl_bool_error; + return isl_bool_true; + } + isl_stream_error(s, tok, "expecting ':'"); + isl_stream_push_token(s, tok); + return isl_bool_error; + case isl_yaml_mapping_val: + if (get_yaml_indent(s) == ISL_YAML_INDENT_FLOW) { + if (!isl_stream_eat_if_available(s, ',')) + return isl_bool_false; + if (update_state(s, isl_yaml_mapping_key) < 0) + return isl_bool_error; + return isl_bool_true; + } + tok = isl_stream_next_token(s); + if (!tok) + return isl_bool_false; + indent = tok->col - 1; + isl_stream_push_token(s, tok); + if (indent < get_yaml_indent(s)) + return isl_bool_false; + if (update_state(s, isl_yaml_mapping_key) < 0) + return isl_bool_error; + return isl_bool_true; + case isl_yaml_sequence_start: + if (get_yaml_indent(s) == ISL_YAML_INDENT_FLOW) { + if (isl_stream_next_token_is(s, ']')) + return isl_bool_false; + if (update_state(s, isl_yaml_sequence) < 0) + return isl_bool_error; + return isl_bool_true; + } + tok = isl_stream_next_token(s); + if (!tok) { + if (s->eof) + isl_stream_error(s, NULL, "unexpected EOF"); + return isl_bool_error; + } + if (tok->type == '-') { + isl_token_free(tok); + if (update_state(s, isl_yaml_sequence) < 0) + return isl_bool_error; + return isl_bool_true; + } + isl_stream_error(s, tok, "expecting '-'"); + isl_stream_push_token(s, tok); + return isl_bool_false; + case isl_yaml_sequence: + if (get_yaml_indent(s) == ISL_YAML_INDENT_FLOW) + return isl_bool_ok(isl_stream_eat_if_available(s, ',')); + tok = isl_stream_next_token(s); + if (!tok) + return isl_bool_false; + indent = tok->col - 1; + if (indent < get_yaml_indent(s) || tok->type != '-') { + isl_stream_push_token(s, tok); + return isl_bool_false; + } + isl_token_free(tok); + return isl_bool_true; + default: + isl_die(s->ctx, isl_error_internal, + "unexpected state", return isl_bool_error); + } +} + +/* Start reading a YAML mapping. + * Return isl_stat_ok on success and isl_stat_error on error. + * + * If the first token on the stream is a '{' then we remove this token + * from the stream and keep track of the fact that the mapping + * is given in flow format. + * Otherwise, we assume the first token is the first key of the mapping and + * keep track of its indentation, but keep the token on the stream. + * In both cases, the next token we expect is the first key of the mapping. + */ +isl_stat isl_stream_yaml_read_start_mapping(__isl_keep isl_stream *s) +{ + struct isl_token *tok; + int indent; + + if (push_state(s, isl_yaml_mapping_key_start) < 0) + return isl_stat_error; + + tok = isl_stream_next_token(s); + if (!tok) { + if (s->eof) + isl_stream_error(s, NULL, "unexpected EOF"); + return isl_stat_error; + } + if (isl_token_get_type(tok) == '{') { + isl_token_free(tok); + return set_yaml_indent(s, ISL_YAML_INDENT_FLOW); + } + indent = tok->col - 1; + isl_stream_push_token(s, tok); + + return set_yaml_indent(s, indent); +} + +/* Finish reading a YAML mapping. + * Return isl_stat_ok on success and isl_stat_error on error. + * + * If the mapping started with a '{', then we expect a '}' to close + * the mapping. + * Otherwise, we double-check that the next token (if any) + * has a smaller indentation than that of the current mapping. + */ +isl_stat isl_stream_yaml_read_end_mapping(__isl_keep isl_stream *s) +{ + struct isl_token *tok; + int indent; + + if (get_yaml_indent(s) == ISL_YAML_INDENT_FLOW) { + if (isl_stream_eat(s, '}') < 0) + return isl_stat_error; + return pop_state(s); + } + + tok = isl_stream_next_token(s); + if (!tok) + return pop_state(s); + + indent = tok->col - 1; + isl_stream_push_token(s, tok); + + if (indent >= get_yaml_indent(s)) + isl_die(isl_stream_get_ctx(s), isl_error_invalid, + "mapping not finished", return isl_stat_error); + + return pop_state(s); +} + +/* Start reading a YAML sequence. + * Return isl_stat_ok on success and isl_stat_error on error. + * + * If the first token on the stream is a '[' then we remove this token + * from the stream and keep track of the fact that the sequence + * is given in flow format. + * Otherwise, we assume the first token is the dash that introduces + * the first element of the sequence and keep track of its indentation, + * but keep the token on the stream. + * In both cases, the next token we expect is the first element + * of the sequence. + */ +isl_stat isl_stream_yaml_read_start_sequence(__isl_keep isl_stream *s) +{ + struct isl_token *tok; + int indent; + + if (push_state(s, isl_yaml_sequence_start) < 0) + return isl_stat_error; + + tok = isl_stream_next_token(s); + if (!tok) { + if (s->eof) + isl_stream_error(s, NULL, "unexpected EOF"); + return isl_stat_error; + } + if (isl_token_get_type(tok) == '[') { + isl_token_free(tok); + return set_yaml_indent(s, ISL_YAML_INDENT_FLOW); + } + indent = tok->col - 1; + isl_stream_push_token(s, tok); + + return set_yaml_indent(s, indent); +} + +/* Finish reading a YAML sequence. + * Return isl_stat_ok on success and isl_stat_error on error. + * + * If the sequence started with a '[', then we expect a ']' to close + * the sequence. + * Otherwise, we double-check that the next token (if any) + * is not a dash or that it has a smaller indentation than + * that of the current sequence. + */ +isl_stat isl_stream_yaml_read_end_sequence(__isl_keep isl_stream *s) +{ + struct isl_token *tok; + int indent; + int dash; + + if (get_yaml_indent(s) == ISL_YAML_INDENT_FLOW) { + if (isl_stream_eat(s, ']') < 0) + return isl_stat_error; + return pop_state(s); + } + + tok = isl_stream_next_token(s); + if (!tok) + return pop_state(s); + + indent = tok->col - 1; + dash = tok->type == '-'; + isl_stream_push_token(s, tok); + + if (indent >= get_yaml_indent(s) && dash) + isl_die(isl_stream_get_ctx(s), isl_error_invalid, + "sequence not finished", return isl_stat_error); + + return pop_state(s); +} diff --git a/external/mit/isl/dist/isl_stream_private.h b/external/mit/isl/dist/isl_stream_private.h new file mode 100644 index 000000000000..b199ec64dc26 --- /dev/null +++ b/external/mit/isl/dist/isl_stream_private.h @@ -0,0 +1,69 @@ +#include +#include +#include + +struct isl_token { + int type; + + unsigned int on_new_line : 1; + unsigned is_keyword : 1; + int line; + int col; + + union { + isl_int v; + char *s; + isl_map *map; + isl_pw_aff *pwaff; + } u; +}; + +struct isl_token *isl_token_new(isl_ctx *ctx, + int line, int col, unsigned on_new_line); + +/* An input stream that may be either a file or a string. + * + * line and col are the line and column number of the next character (1-based). + * start_line and start_col are set by isl_stream_getc to point + * to the position of the returned character. + * last_line is the line number of the previous token. + * + * yaml_state and yaml_indent keep track of the currently active YAML + * elements. yaml_size is the size of these arrays, while yaml_depth + * is the number of elements currently in use. + * yaml_state and yaml_indent may be NULL if no YAML parsing is being + * performed. + * yaml_state keeps track of what is expected next at each level. + * yaml_indent keeps track of the indentation at each level, with + * ISL_YAML_INDENT_FLOW meaning that the element is in flow format + * (such that the indentation is not relevant). + */ +struct isl_stream { + struct isl_ctx *ctx; + FILE *file; + const char *str; + int line; + int col; + int start_line; + int start_col; + int last_line; + int eof; + + char *buffer; + size_t size; + size_t len; + int c; + int un[5]; + int n_un; + + struct isl_token *tokens[5]; + int n_token; + + struct isl_hash_table *keywords; + enum isl_token_type next_type; + + int yaml_depth; + int yaml_size; + enum isl_yaml_state *yaml_state; + int *yaml_indent; +}; diff --git a/external/mit/isl/dist/isl_stream_read_pw_with_params_templ.c b/external/mit/isl/dist/isl_stream_read_pw_with_params_templ.c new file mode 100644 index 000000000000..0e889989461f --- /dev/null +++ b/external/mit/isl/dist/isl_stream_read_pw_with_params_templ.c @@ -0,0 +1,30 @@ +/* + * Copyright 2011 Sven Verdoolaege + * + * Use of this software is governed by the MIT license + * + * Written by Sven Verdoolaege. + */ + +#undef TYPE +#define TYPE CAT(isl_pw_,BASE) + +/* Read an object of type "TYPE" from "s" with parameter domain "dom". + * "v" contains a description of the identifiers parsed so far. + */ +static __isl_give TYPE *FN(isl_stream_read_with_params_pw,BASE)( + __isl_keep isl_stream *s, __isl_keep isl_set *dom, struct vars *v) +{ + TYPE *obj; + + obj = FN(read_conditional,BASE)(s, isl_set_copy(dom), v); + + while (isl_stream_eat_if_available(s, ';')) { + TYPE *obj2; + + obj2 = FN(read_conditional,BASE)(s, isl_set_copy(dom), v); + obj = FN(TYPE,union_add)(obj, obj2); + } + + return obj; +} diff --git a/external/mit/isl/dist/isl_stream_read_with_params_templ.c b/external/mit/isl/dist/isl_stream_read_with_params_templ.c new file mode 100644 index 000000000000..e18c9ebc0a8e --- /dev/null +++ b/external/mit/isl/dist/isl_stream_read_with_params_templ.c @@ -0,0 +1,52 @@ +/* + * Copyright 2011 Sven Verdoolaege + * + * Use of this software is governed by the MIT license + * + * Written by Sven Verdoolaege. + */ + +#define xCAT(A,B) A ## B +#define CAT(A,B) xCAT(A,B) +#undef TYPE +#define TYPE CAT(isl_,TYPE_BASE) + +/* Read an object of type "TYPE" from "s". + * + * In particular, first read the parameters and the opening brace. + * Then read the body that is specific to the object type. + * Finally, read the closing brace. + */ +__isl_give TYPE *FN(isl_stream_read,TYPE_BASE)(__isl_keep isl_stream *s) +{ + struct vars *v; + isl_set *dom; + TYPE *obj = NULL; + + v = vars_new(s->ctx); + if (!v) + return NULL; + + dom = isl_set_universe(isl_space_params_alloc(s->ctx, 0)); + if (next_is_tuple(s)) { + dom = read_map_tuple(s, dom, isl_dim_param, v, 0); + if (isl_stream_eat(s, ISL_TOKEN_TO)) + goto error; + } + if (isl_stream_eat(s, '{')) + goto error; + + obj = FN(isl_stream_read_with_params,TYPE_BASE)(s, dom, v); + + if (isl_stream_eat(s, '}')) + goto error; + + vars_free(v); + isl_set_free(dom); + return obj; +error: + vars_free(v); + isl_set_free(dom); + FN(TYPE,free)(obj); + return NULL; +} diff --git a/external/mit/isl/dist/isl_stride.c b/external/mit/isl/dist/isl_stride.c new file mode 100644 index 000000000000..df5cacc34267 --- /dev/null +++ b/external/mit/isl/dist/isl_stride.c @@ -0,0 +1,389 @@ +/* + * 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 +#include +#include +#include +#include + +/* 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; +}; + +/* Return the ctx to which "si" belongs. + */ +isl_ctx *isl_stride_info_get_ctx(__isl_keep isl_stride_info *si) +{ + if (!si) + return NULL; + + return isl_val_get_ctx(si->stride); +} + +/* 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; +} + +/* Make a copy of "si" and return it. + */ +__isl_give isl_stride_info *isl_stride_info_copy( + __isl_keep isl_stride_info *si) +{ + if (!si) + return NULL; + + return isl_stride_info_alloc(isl_val_copy(si->stride), + isl_aff_copy(si->offset)); +} + +/* 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) +{ + if (!stride || !offset) + goto error; + + 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; + isl_size n_div; + isl_ctx *ctx; + isl_stat r = isl_stat_ok; + isl_val *v, *stride, *m; + isl_bool is_eq, relevant, has_stride; + + is_eq = isl_constraint_is_equality(c); + relevant = isl_constraint_involves_dims(c, isl_dim_set, data->pos, 1); + if (is_eq < 0 || relevant < 0) + goto error; + if (!is_eq || !relevant) { + isl_constraint_free(c); + return isl_stat_ok; + } + + n_div = isl_constraint_dim(c, isl_dim_div); + if (n_div < 0) + goto error; + ctx = isl_constraint_get_ctx(c); + stride = isl_val_zero(ctx); + 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)); + + has_stride = isl_val_gt_si(stride, 1); + if (has_stride >= 0 && has_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); + aff = isl_aff_remove_unused_divs(aff); + 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); + if (has_stride < 0) + return isl_stat_error; + return r; +error: + isl_constraint_free(c); + return isl_stat_error; +} + +/* 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; +} + +/* Check if the constraints in "map" imply any stride on output dimension "pos", + * independently of any other output dimensions, and + * return the results in the form of an offset and a stride. + * + * Convert the input to a set with only the input dimensions and + * the single output dimension such that it be passed to + * isl_set_get_stride_info and convert the result back to + * an expression defined over the domain of "map". + */ +__isl_give isl_stride_info *isl_map_get_range_stride_info( + __isl_keep isl_map *map, int pos) +{ + isl_stride_info *si; + isl_set *set; + isl_size n_in; + + n_in = isl_map_dim(map, isl_dim_in); + if (n_in < 0) + return NULL; + map = isl_map_copy(map); + map = isl_map_project_onto(map, isl_dim_out, pos, 1); + set = isl_map_wrap(map); + si = isl_set_get_stride_info(set, n_in); + isl_set_free(set); + if (!si) + return NULL; + si->offset = isl_aff_domain_factor_domain(si->offset); + if (!si->offset) + return isl_stride_info_free(si); + return si; +} diff --git a/external/mit/isl/dist/isl_tab.c b/external/mit/isl/dist/isl_tab.c new file mode 100644 index 000000000000..be7e4c81471f --- /dev/null +++ b/external/mit/isl/dist/isl_tab.c @@ -0,0 +1,4268 @@ +/* + * Copyright 2008-2009 Katholieke Universiteit Leuven + * Copyright 2013 Ecole Normale Superieure + * Copyright 2014 INRIA Rocquencourt + * Copyright 2016 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 Ecole Normale Superieure, 45 rue d'Ulm, 75230 Paris, France + * and Inria Paris - Rocquencourt, Domaine de Voluceau - Rocquencourt, + * B.P. 105 - 78153 Le Chesnay, France + */ + +#include +#include +#include +#include "isl_map_private.h" +#include "isl_tab.h" +#include +#include + +#include +#include + +/* + * The implementation of tableaus in this file was inspired by Section 8 + * of David Detlefs, Greg Nelson and James B. Saxe, "Simplify: a theorem + * prover for program checking". + */ + +struct isl_tab *isl_tab_alloc(struct isl_ctx *ctx, + unsigned n_row, unsigned n_var, unsigned M) +{ + int i; + struct isl_tab *tab; + unsigned off = 2 + M; + + tab = isl_calloc_type(ctx, struct isl_tab); + if (!tab) + return NULL; + tab->mat = isl_mat_alloc(ctx, n_row, off + n_var); + if (!tab->mat) + goto error; + tab->var = isl_alloc_array(ctx, struct isl_tab_var, n_var); + if (n_var && !tab->var) + goto error; + tab->con = isl_alloc_array(ctx, struct isl_tab_var, n_row); + if (n_row && !tab->con) + goto error; + tab->col_var = isl_alloc_array(ctx, int, n_var); + if (n_var && !tab->col_var) + goto error; + tab->row_var = isl_alloc_array(ctx, int, n_row); + if (n_row && !tab->row_var) + goto error; + for (i = 0; i < n_var; ++i) { + tab->var[i].index = i; + tab->var[i].is_row = 0; + tab->var[i].is_nonneg = 0; + tab->var[i].is_zero = 0; + tab->var[i].is_redundant = 0; + tab->var[i].frozen = 0; + tab->var[i].negated = 0; + tab->col_var[i] = i; + } + tab->n_row = 0; + tab->n_con = 0; + tab->n_eq = 0; + tab->max_con = n_row; + tab->n_col = n_var; + tab->n_var = n_var; + tab->max_var = n_var; + tab->n_param = 0; + tab->n_div = 0; + tab->n_dead = 0; + tab->n_redundant = 0; + tab->strict_redundant = 0; + tab->need_undo = 0; + tab->rational = 0; + tab->empty = 0; + tab->in_undo = 0; + tab->M = M; + tab->cone = 0; + tab->bottom.type = isl_tab_undo_bottom; + tab->bottom.next = NULL; + tab->top = &tab->bottom; + + tab->n_zero = 0; + tab->n_unbounded = 0; + tab->basis = NULL; + + return tab; +error: + isl_tab_free(tab); + return NULL; +} + +isl_ctx *isl_tab_get_ctx(struct isl_tab *tab) +{ + return tab ? isl_mat_get_ctx(tab->mat) : NULL; +} + +int isl_tab_extend_cons(struct isl_tab *tab, unsigned n_new) +{ + unsigned off; + + if (!tab) + return -1; + + off = 2 + tab->M; + + if (tab->max_con < tab->n_con + n_new) { + struct isl_tab_var *con; + + con = isl_realloc_array(tab->mat->ctx, tab->con, + struct isl_tab_var, tab->max_con + n_new); + if (!con) + return -1; + tab->con = con; + tab->max_con += n_new; + } + if (tab->mat->n_row < tab->n_row + n_new) { + int *row_var; + + tab->mat = isl_mat_extend(tab->mat, + tab->n_row + n_new, off + tab->n_col); + if (!tab->mat) + return -1; + row_var = isl_realloc_array(tab->mat->ctx, tab->row_var, + int, tab->mat->n_row); + if (!row_var) + return -1; + tab->row_var = row_var; + if (tab->row_sign) { + enum isl_tab_row_sign *s; + s = isl_realloc_array(tab->mat->ctx, tab->row_sign, + enum isl_tab_row_sign, tab->mat->n_row); + if (!s) + return -1; + tab->row_sign = s; + } + } + return 0; +} + +/* Make room for at least n_new extra variables. + * Return -1 if anything went wrong. + */ +int isl_tab_extend_vars(struct isl_tab *tab, unsigned n_new) +{ + struct isl_tab_var *var; + unsigned off = 2 + tab->M; + + if (tab->max_var < tab->n_var + n_new) { + var = isl_realloc_array(tab->mat->ctx, tab->var, + struct isl_tab_var, tab->n_var + n_new); + if (!var) + return -1; + tab->var = var; + tab->max_var = tab->n_var + n_new; + } + + if (tab->mat->n_col < off + tab->n_col + n_new) { + int *p; + + tab->mat = isl_mat_extend(tab->mat, + tab->mat->n_row, off + tab->n_col + n_new); + if (!tab->mat) + return -1; + p = isl_realloc_array(tab->mat->ctx, tab->col_var, + int, tab->n_col + n_new); + if (!p) + return -1; + tab->col_var = p; + } + + return 0; +} + +static void free_undo_record(struct isl_tab_undo *undo) +{ + switch (undo->type) { + case isl_tab_undo_saved_basis: + free(undo->u.col_var); + break; + default:; + } + free(undo); +} + +static void free_undo(struct isl_tab *tab) +{ + struct isl_tab_undo *undo, *next; + + for (undo = tab->top; undo && undo != &tab->bottom; undo = next) { + next = undo->next; + free_undo_record(undo); + } + tab->top = undo; +} + +void isl_tab_free(struct isl_tab *tab) +{ + if (!tab) + return; + free_undo(tab); + isl_mat_free(tab->mat); + isl_vec_free(tab->dual); + isl_basic_map_free(tab->bmap); + free(tab->var); + free(tab->con); + free(tab->row_var); + free(tab->col_var); + free(tab->row_sign); + isl_mat_free(tab->samples); + free(tab->sample_index); + isl_mat_free(tab->basis); + free(tab); +} + +struct isl_tab *isl_tab_dup(struct isl_tab *tab) +{ + int i; + struct isl_tab *dup; + unsigned off; + + if (!tab) + return NULL; + + off = 2 + tab->M; + dup = isl_calloc_type(tab->mat->ctx, struct isl_tab); + if (!dup) + return NULL; + dup->mat = isl_mat_dup(tab->mat); + if (!dup->mat) + goto error; + dup->var = isl_alloc_array(tab->mat->ctx, struct isl_tab_var, tab->max_var); + if (tab->max_var && !dup->var) + goto error; + for (i = 0; i < tab->n_var; ++i) + dup->var[i] = tab->var[i]; + dup->con = isl_alloc_array(tab->mat->ctx, struct isl_tab_var, tab->max_con); + if (tab->max_con && !dup->con) + goto error; + for (i = 0; i < tab->n_con; ++i) + dup->con[i] = tab->con[i]; + dup->col_var = isl_alloc_array(tab->mat->ctx, int, tab->mat->n_col - off); + if ((tab->mat->n_col - off) && !dup->col_var) + goto error; + for (i = 0; i < tab->n_col; ++i) + dup->col_var[i] = tab->col_var[i]; + dup->row_var = isl_alloc_array(tab->mat->ctx, int, tab->mat->n_row); + if (tab->mat->n_row && !dup->row_var) + goto error; + for (i = 0; i < tab->n_row; ++i) + dup->row_var[i] = tab->row_var[i]; + if (tab->row_sign) { + dup->row_sign = isl_alloc_array(tab->mat->ctx, enum isl_tab_row_sign, + tab->mat->n_row); + if (tab->mat->n_row && !dup->row_sign) + goto error; + for (i = 0; i < tab->n_row; ++i) + dup->row_sign[i] = tab->row_sign[i]; + } + if (tab->samples) { + dup->samples = isl_mat_dup(tab->samples); + if (!dup->samples) + goto error; + dup->sample_index = isl_alloc_array(tab->mat->ctx, int, + tab->samples->n_row); + if (tab->samples->n_row && !dup->sample_index) + goto error; + dup->n_sample = tab->n_sample; + dup->n_outside = tab->n_outside; + } + dup->n_row = tab->n_row; + dup->n_con = tab->n_con; + dup->n_eq = tab->n_eq; + dup->max_con = tab->max_con; + dup->n_col = tab->n_col; + dup->n_var = tab->n_var; + dup->max_var = tab->max_var; + dup->n_param = tab->n_param; + dup->n_div = tab->n_div; + dup->n_dead = tab->n_dead; + dup->n_redundant = tab->n_redundant; + dup->rational = tab->rational; + dup->empty = tab->empty; + dup->strict_redundant = 0; + dup->need_undo = 0; + dup->in_undo = 0; + dup->M = tab->M; + dup->cone = tab->cone; + dup->bottom.type = isl_tab_undo_bottom; + dup->bottom.next = NULL; + dup->top = &dup->bottom; + + dup->n_zero = tab->n_zero; + dup->n_unbounded = tab->n_unbounded; + dup->basis = isl_mat_dup(tab->basis); + + return dup; +error: + isl_tab_free(dup); + return NULL; +} + +/* Construct the coefficient matrix of the product tableau + * of two tableaus. + * mat{1,2} is the coefficient matrix of tableau {1,2} + * row{1,2} is the number of rows in tableau {1,2} + * col{1,2} is the number of columns in tableau {1,2} + * off is the offset to the coefficient column (skipping the + * denominator, the constant term and the big parameter if any) + * r{1,2} is the number of redundant rows in tableau {1,2} + * d{1,2} is the number of dead columns in tableau {1,2} + * + * The order of the rows and columns in the result is as explained + * in isl_tab_product. + */ +static __isl_give isl_mat *tab_mat_product(__isl_keep isl_mat *mat1, + __isl_keep isl_mat *mat2, unsigned row1, unsigned row2, + unsigned col1, unsigned col2, + unsigned off, unsigned r1, unsigned r2, unsigned d1, unsigned d2) +{ + int i; + struct isl_mat *prod; + unsigned n; + + prod = isl_mat_alloc(mat1->ctx, mat1->n_row + mat2->n_row, + off + col1 + col2); + if (!prod) + return NULL; + + n = 0; + for (i = 0; i < r1; ++i) { + isl_seq_cpy(prod->row[n + i], mat1->row[i], off + d1); + isl_seq_clr(prod->row[n + i] + off + d1, d2); + isl_seq_cpy(prod->row[n + i] + off + d1 + d2, + mat1->row[i] + off + d1, col1 - d1); + isl_seq_clr(prod->row[n + i] + off + col1 + d1, col2 - d2); + } + + n += r1; + for (i = 0; i < r2; ++i) { + isl_seq_cpy(prod->row[n + i], mat2->row[i], off); + isl_seq_clr(prod->row[n + i] + off, d1); + isl_seq_cpy(prod->row[n + i] + off + d1, + mat2->row[i] + off, d2); + isl_seq_clr(prod->row[n + i] + off + d1 + d2, col1 - d1); + isl_seq_cpy(prod->row[n + i] + off + col1 + d1, + mat2->row[i] + off + d2, col2 - d2); + } + + n += r2; + for (i = 0; i < row1 - r1; ++i) { + isl_seq_cpy(prod->row[n + i], mat1->row[r1 + i], off + d1); + isl_seq_clr(prod->row[n + i] + off + d1, d2); + isl_seq_cpy(prod->row[n + i] + off + d1 + d2, + mat1->row[r1 + i] + off + d1, col1 - d1); + isl_seq_clr(prod->row[n + i] + off + col1 + d1, col2 - d2); + } + + n += row1 - r1; + for (i = 0; i < row2 - r2; ++i) { + isl_seq_cpy(prod->row[n + i], mat2->row[r2 + i], off); + isl_seq_clr(prod->row[n + i] + off, d1); + isl_seq_cpy(prod->row[n + i] + off + d1, + mat2->row[r2 + i] + off, d2); + isl_seq_clr(prod->row[n + i] + off + d1 + d2, col1 - d1); + isl_seq_cpy(prod->row[n + i] + off + col1 + d1, + mat2->row[r2 + i] + off + d2, col2 - d2); + } + + return prod; +} + +/* Update the row or column index of a variable that corresponds + * to a variable in the first input tableau. + */ +static void update_index1(struct isl_tab_var *var, + unsigned r1, unsigned r2, unsigned d1, unsigned d2) +{ + if (var->index == -1) + return; + if (var->is_row && var->index >= r1) + var->index += r2; + if (!var->is_row && var->index >= d1) + var->index += d2; +} + +/* Update the row or column index of a variable that corresponds + * to a variable in the second input tableau. + */ +static void update_index2(struct isl_tab_var *var, + unsigned row1, unsigned col1, + unsigned r1, unsigned r2, unsigned d1, unsigned d2) +{ + if (var->index == -1) + return; + if (var->is_row) { + if (var->index < r2) + var->index += r1; + else + var->index += row1; + } else { + if (var->index < d2) + var->index += d1; + else + var->index += col1; + } +} + +/* Create a tableau that represents the Cartesian product of the sets + * represented by tableaus tab1 and tab2. + * The order of the rows in the product is + * - redundant rows of tab1 + * - redundant rows of tab2 + * - non-redundant rows of tab1 + * - non-redundant rows of tab2 + * The order of the columns is + * - denominator + * - constant term + * - coefficient of big parameter, if any + * - dead columns of tab1 + * - dead columns of tab2 + * - live columns of tab1 + * - live columns of tab2 + * The order of the variables and the constraints is a concatenation + * of order in the two input tableaus. + */ +struct isl_tab *isl_tab_product(struct isl_tab *tab1, struct isl_tab *tab2) +{ + int i; + struct isl_tab *prod; + unsigned off; + unsigned r1, r2, d1, d2; + + if (!tab1 || !tab2) + return NULL; + + isl_assert(tab1->mat->ctx, tab1->M == tab2->M, return NULL); + isl_assert(tab1->mat->ctx, tab1->rational == tab2->rational, return NULL); + isl_assert(tab1->mat->ctx, tab1->cone == tab2->cone, return NULL); + isl_assert(tab1->mat->ctx, !tab1->row_sign, return NULL); + isl_assert(tab1->mat->ctx, !tab2->row_sign, return NULL); + isl_assert(tab1->mat->ctx, tab1->n_param == 0, return NULL); + isl_assert(tab1->mat->ctx, tab2->n_param == 0, return NULL); + isl_assert(tab1->mat->ctx, tab1->n_div == 0, return NULL); + isl_assert(tab1->mat->ctx, tab2->n_div == 0, return NULL); + + off = 2 + tab1->M; + r1 = tab1->n_redundant; + r2 = tab2->n_redundant; + d1 = tab1->n_dead; + d2 = tab2->n_dead; + prod = isl_calloc_type(tab1->mat->ctx, struct isl_tab); + if (!prod) + return NULL; + prod->mat = tab_mat_product(tab1->mat, tab2->mat, + tab1->n_row, tab2->n_row, + tab1->n_col, tab2->n_col, off, r1, r2, d1, d2); + if (!prod->mat) + goto error; + prod->var = isl_alloc_array(tab1->mat->ctx, struct isl_tab_var, + tab1->max_var + tab2->max_var); + if ((tab1->max_var + tab2->max_var) && !prod->var) + goto error; + for (i = 0; i < tab1->n_var; ++i) { + prod->var[i] = tab1->var[i]; + update_index1(&prod->var[i], r1, r2, d1, d2); + } + for (i = 0; i < tab2->n_var; ++i) { + prod->var[tab1->n_var + i] = tab2->var[i]; + update_index2(&prod->var[tab1->n_var + i], + tab1->n_row, tab1->n_col, + r1, r2, d1, d2); + } + prod->con = isl_alloc_array(tab1->mat->ctx, struct isl_tab_var, + tab1->max_con + tab2->max_con); + if ((tab1->max_con + tab2->max_con) && !prod->con) + goto error; + for (i = 0; i < tab1->n_con; ++i) { + prod->con[i] = tab1->con[i]; + update_index1(&prod->con[i], r1, r2, d1, d2); + } + for (i = 0; i < tab2->n_con; ++i) { + prod->con[tab1->n_con + i] = tab2->con[i]; + update_index2(&prod->con[tab1->n_con + i], + tab1->n_row, tab1->n_col, + r1, r2, d1, d2); + } + prod->col_var = isl_alloc_array(tab1->mat->ctx, int, + tab1->n_col + tab2->n_col); + if ((tab1->n_col + tab2->n_col) && !prod->col_var) + goto error; + for (i = 0; i < tab1->n_col; ++i) { + int pos = i < d1 ? i : i + d2; + prod->col_var[pos] = tab1->col_var[i]; + } + for (i = 0; i < tab2->n_col; ++i) { + int pos = i < d2 ? d1 + i : tab1->n_col + i; + int t = tab2->col_var[i]; + if (t >= 0) + t += tab1->n_var; + else + t -= tab1->n_con; + prod->col_var[pos] = t; + } + prod->row_var = isl_alloc_array(tab1->mat->ctx, int, + tab1->mat->n_row + tab2->mat->n_row); + if ((tab1->mat->n_row + tab2->mat->n_row) && !prod->row_var) + goto error; + for (i = 0; i < tab1->n_row; ++i) { + int pos = i < r1 ? i : i + r2; + prod->row_var[pos] = tab1->row_var[i]; + } + for (i = 0; i < tab2->n_row; ++i) { + int pos = i < r2 ? r1 + i : tab1->n_row + i; + int t = tab2->row_var[i]; + if (t >= 0) + t += tab1->n_var; + else + t -= tab1->n_con; + prod->row_var[pos] = t; + } + prod->samples = NULL; + prod->sample_index = NULL; + prod->n_row = tab1->n_row + tab2->n_row; + prod->n_con = tab1->n_con + tab2->n_con; + prod->n_eq = 0; + prod->max_con = tab1->max_con + tab2->max_con; + prod->n_col = tab1->n_col + tab2->n_col; + prod->n_var = tab1->n_var + tab2->n_var; + prod->max_var = tab1->max_var + tab2->max_var; + prod->n_param = 0; + prod->n_div = 0; + prod->n_dead = tab1->n_dead + tab2->n_dead; + prod->n_redundant = tab1->n_redundant + tab2->n_redundant; + prod->rational = tab1->rational; + prod->empty = tab1->empty || tab2->empty; + prod->strict_redundant = tab1->strict_redundant || tab2->strict_redundant; + prod->need_undo = 0; + prod->in_undo = 0; + prod->M = tab1->M; + prod->cone = tab1->cone; + prod->bottom.type = isl_tab_undo_bottom; + prod->bottom.next = NULL; + prod->top = &prod->bottom; + + prod->n_zero = 0; + prod->n_unbounded = 0; + prod->basis = NULL; + + return prod; +error: + isl_tab_free(prod); + return NULL; +} + +static struct isl_tab_var *var_from_index(struct isl_tab *tab, int i) +{ + if (i >= 0) + return &tab->var[i]; + else + return &tab->con[~i]; +} + +struct isl_tab_var *isl_tab_var_from_row(struct isl_tab *tab, int i) +{ + return var_from_index(tab, tab->row_var[i]); +} + +static struct isl_tab_var *var_from_col(struct isl_tab *tab, int i) +{ + return var_from_index(tab, tab->col_var[i]); +} + +/* Check if there are any upper bounds on column variable "var", + * i.e., non-negative rows where var appears with a negative coefficient. + * Return 1 if there are no such bounds. + */ +static int max_is_manifestly_unbounded(struct isl_tab *tab, + struct isl_tab_var *var) +{ + int i; + unsigned off = 2 + tab->M; + + if (var->is_row) + return 0; + for (i = tab->n_redundant; i < tab->n_row; ++i) { + if (!isl_int_is_neg(tab->mat->row[i][off + var->index])) + continue; + if (isl_tab_var_from_row(tab, i)->is_nonneg) + return 0; + } + return 1; +} + +/* Check if there are any lower bounds on column variable "var", + * i.e., non-negative rows where var appears with a positive coefficient. + * Return 1 if there are no such bounds. + */ +static int min_is_manifestly_unbounded(struct isl_tab *tab, + struct isl_tab_var *var) +{ + int i; + unsigned off = 2 + tab->M; + + if (var->is_row) + return 0; + for (i = tab->n_redundant; i < tab->n_row; ++i) { + if (!isl_int_is_pos(tab->mat->row[i][off + var->index])) + continue; + if (isl_tab_var_from_row(tab, i)->is_nonneg) + return 0; + } + return 1; +} + +static int row_cmp(struct isl_tab *tab, int r1, int r2, int c, isl_int *t) +{ + unsigned off = 2 + tab->M; + + if (tab->M) { + int s; + isl_int_mul(*t, tab->mat->row[r1][2], tab->mat->row[r2][off+c]); + isl_int_submul(*t, tab->mat->row[r2][2], tab->mat->row[r1][off+c]); + s = isl_int_sgn(*t); + if (s) + return s; + } + isl_int_mul(*t, tab->mat->row[r1][1], tab->mat->row[r2][off + c]); + isl_int_submul(*t, tab->mat->row[r2][1], tab->mat->row[r1][off + c]); + return isl_int_sgn(*t); +} + +/* Given the index of a column "c", return the index of a row + * that can be used to pivot the column in, with either an increase + * (sgn > 0) or a decrease (sgn < 0) of the corresponding variable. + * If "var" is not NULL, then the row returned will be different from + * the one associated with "var". + * + * Each row in the tableau is of the form + * + * x_r = a_r0 + \sum_i a_ri x_i + * + * Only rows with x_r >= 0 and with the sign of a_ri opposite to "sgn" + * impose any limit on the increase or decrease in the value of x_c + * and this bound is equal to a_r0 / |a_rc|. We are therefore looking + * for the row with the smallest (most stringent) such bound. + * Note that the common denominator of each row drops out of the fraction. + * To check if row j has a smaller bound than row r, i.e., + * a_j0 / |a_jc| < a_r0 / |a_rc| or a_j0 |a_rc| < a_r0 |a_jc|, + * we check if -sign(a_jc) (a_j0 a_rc - a_r0 a_jc) < 0, + * where -sign(a_jc) is equal to "sgn". + */ +static int pivot_row(struct isl_tab *tab, + struct isl_tab_var *var, int sgn, int c) +{ + int j, r, tsgn; + isl_int t; + unsigned off = 2 + tab->M; + + isl_int_init(t); + r = -1; + for (j = tab->n_redundant; j < tab->n_row; ++j) { + if (var && j == var->index) + continue; + if (!isl_tab_var_from_row(tab, j)->is_nonneg) + continue; + if (sgn * isl_int_sgn(tab->mat->row[j][off + c]) >= 0) + continue; + if (r < 0) { + r = j; + continue; + } + tsgn = sgn * row_cmp(tab, r, j, c, &t); + if (tsgn < 0 || (tsgn == 0 && + tab->row_var[j] < tab->row_var[r])) + r = j; + } + isl_int_clear(t); + return r; +} + +/* Find a pivot (row and col) that will increase (sgn > 0) or decrease + * (sgn < 0) the value of row variable var. + * If not NULL, then skip_var is a row variable that should be ignored + * while looking for a pivot row. It is usually equal to var. + * + * As the given row in the tableau is of the form + * + * x_r = a_r0 + \sum_i a_ri x_i + * + * we need to find a column such that the sign of a_ri is equal to "sgn" + * (such that an increase in x_i will have the desired effect) or a + * column with a variable that may attain negative values. + * If a_ri is positive, then we need to move x_i in the same direction + * to obtain the desired effect. Otherwise, x_i has to move in the + * opposite direction. + */ +static void find_pivot(struct isl_tab *tab, + struct isl_tab_var *var, struct isl_tab_var *skip_var, + int sgn, int *row, int *col) +{ + int j, r, c; + isl_int *tr; + + *row = *col = -1; + + isl_assert(tab->mat->ctx, var->is_row, return); + tr = tab->mat->row[var->index] + 2 + tab->M; + + c = -1; + for (j = tab->n_dead; j < tab->n_col; ++j) { + if (isl_int_is_zero(tr[j])) + continue; + if (isl_int_sgn(tr[j]) != sgn && + var_from_col(tab, j)->is_nonneg) + continue; + if (c < 0 || tab->col_var[j] < tab->col_var[c]) + c = j; + } + if (c < 0) + return; + + sgn *= isl_int_sgn(tr[c]); + r = pivot_row(tab, skip_var, sgn, c); + *row = r < 0 ? var->index : r; + *col = c; +} + +/* Return 1 if row "row" represents an obviously redundant inequality. + * This means + * - it represents an inequality or a variable + * - that is the sum of a non-negative sample value and a positive + * combination of zero or more non-negative constraints. + */ +int isl_tab_row_is_redundant(struct isl_tab *tab, int row) +{ + int i; + unsigned off = 2 + tab->M; + + if (tab->row_var[row] < 0 && !isl_tab_var_from_row(tab, row)->is_nonneg) + return 0; + + if (isl_int_is_neg(tab->mat->row[row][1])) + return 0; + if (tab->strict_redundant && isl_int_is_zero(tab->mat->row[row][1])) + return 0; + if (tab->M && isl_int_is_neg(tab->mat->row[row][2])) + return 0; + + for (i = tab->n_dead; i < tab->n_col; ++i) { + if (isl_int_is_zero(tab->mat->row[row][off + i])) + continue; + if (tab->col_var[i] >= 0) + return 0; + if (isl_int_is_neg(tab->mat->row[row][off + i])) + return 0; + if (!var_from_col(tab, i)->is_nonneg) + return 0; + } + return 1; +} + +static void swap_rows(struct isl_tab *tab, int row1, int row2) +{ + int t; + enum isl_tab_row_sign s; + + t = tab->row_var[row1]; + tab->row_var[row1] = tab->row_var[row2]; + tab->row_var[row2] = t; + isl_tab_var_from_row(tab, row1)->index = row1; + isl_tab_var_from_row(tab, row2)->index = row2; + tab->mat = isl_mat_swap_rows(tab->mat, row1, row2); + + if (!tab->row_sign) + return; + s = tab->row_sign[row1]; + tab->row_sign[row1] = tab->row_sign[row2]; + tab->row_sign[row2] = s; +} + +static isl_stat push_union(struct isl_tab *tab, + enum isl_tab_undo_type type, union isl_tab_undo_val u) WARN_UNUSED; + +/* 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 isl_stat_error; + if (!tab->need_undo) + return isl_stat_ok; + + undo = isl_alloc_type(tab->mat->ctx, struct isl_tab_undo); + if (!undo) + goto error; + undo->type = type; + undo->u = u; + undo->next = tab->top; + tab->top = undo; + + return isl_stat_ok; +error: + free_undo(tab); + tab->top = NULL; + return isl_stat_error; +} + +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; + if (var->is_row) + u.var_index = tab->row_var[var->index]; + else + u.var_index = tab->col_var[var->index]; + return push_union(tab, type, u); +} + +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); +} + +/* Push a record on the undo stack describing the current basic + * variables, so that the this state can be restored during rollback. + */ +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 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); +} + +isl_stat isl_tab_push_callback(struct isl_tab *tab, + struct isl_tab_callback *callback) +{ + union isl_tab_undo_val u; + u.callback = callback; + return push_union(tab, isl_tab_undo_callback, u); +} + +struct isl_tab *isl_tab_init_samples(struct isl_tab *tab) +{ + if (!tab) + return NULL; + + tab->n_sample = 0; + tab->n_outside = 0; + tab->samples = isl_mat_alloc(tab->mat->ctx, 1, 1 + tab->n_var); + if (!tab->samples) + goto error; + tab->sample_index = isl_alloc_array(tab->mat->ctx, int, 1); + if (!tab->sample_index) + goto error; + return tab; +error: + isl_tab_free(tab); + return NULL; +} + +int isl_tab_add_sample(struct isl_tab *tab, __isl_take isl_vec *sample) +{ + if (!tab || !sample) + goto error; + + if (tab->n_sample + 1 > tab->samples->n_row) { + int *t = isl_realloc_array(tab->mat->ctx, + tab->sample_index, int, tab->n_sample + 1); + if (!t) + goto error; + tab->sample_index = t; + } + + tab->samples = isl_mat_extend(tab->samples, + tab->n_sample + 1, tab->samples->n_col); + if (!tab->samples) + goto error; + + isl_seq_cpy(tab->samples->row[tab->n_sample], sample->el, sample->size); + isl_vec_free(sample); + tab->sample_index[tab->n_sample] = tab->n_sample; + tab->n_sample++; + + return 0; +error: + isl_vec_free(sample); + return -1; +} + +struct isl_tab *isl_tab_drop_sample(struct isl_tab *tab, int s) +{ + if (s != tab->n_outside) { + int t = tab->sample_index[tab->n_outside]; + tab->sample_index[tab->n_outside] = tab->sample_index[s]; + tab->sample_index[s] = t; + isl_mat_swap_rows(tab->samples, tab->n_outside, s); + } + tab->n_outside++; + if (isl_tab_push(tab, isl_tab_undo_drop_sample) < 0) { + isl_tab_free(tab); + return NULL; + } + + return tab; +} + +/* Record the current number of samples so that we can remove newer + * samples during a rollback. + */ +isl_stat isl_tab_save_samples(struct isl_tab *tab) +{ + union isl_tab_undo_val u; + + if (!tab) + return isl_stat_error; + + u.n = tab->n_sample; + return push_union(tab, isl_tab_undo_saved_samples, u); +} + +/* Mark row with index "row" as being redundant. + * If we may need to undo the operation or if the row represents + * a variable of the original problem, the row is kept, + * but no longer considered when looking for a pivot row. + * Otherwise, the row is simply removed. + * + * The row may be interchanged with some other row. If it + * is interchanged with a later row, return 1. Otherwise return 0. + * If the rows are checked in order in the calling function, + * then a return value of 1 means that the row with the given + * row number may now contain a different row that hasn't been checked yet. + */ +int isl_tab_mark_redundant(struct isl_tab *tab, int row) +{ + struct isl_tab_var *var = isl_tab_var_from_row(tab, row); + var->is_redundant = 1; + isl_assert(tab->mat->ctx, row >= tab->n_redundant, return -1); + if (tab->preserve || tab->need_undo || tab->row_var[row] >= 0) { + if (tab->row_var[row] >= 0 && !var->is_nonneg) { + var->is_nonneg = 1; + if (isl_tab_push_var(tab, isl_tab_undo_nonneg, var) < 0) + return -1; + } + if (row != tab->n_redundant) + swap_rows(tab, row, tab->n_redundant); + tab->n_redundant++; + return isl_tab_push_var(tab, isl_tab_undo_redundant, var); + } else { + if (row != tab->n_row - 1) + swap_rows(tab, row, tab->n_row - 1); + isl_tab_var_from_row(tab, tab->n_row - 1)->index = -1; + tab->n_row--; + return 1; + } +} + +/* Mark "tab" as a rational tableau. + * If it wasn't marked as a rational tableau already and if we may + * need to undo changes, then arrange for the marking to be undone + * during the undo. + */ +int isl_tab_mark_rational(struct isl_tab *tab) +{ + if (!tab) + return -1; + if (!tab->rational && tab->need_undo) + if (isl_tab_push(tab, isl_tab_undo_rational) < 0) + return -1; + tab->rational = 1; + return 0; +} + +isl_stat isl_tab_mark_empty(struct isl_tab *tab) +{ + if (!tab) + return isl_stat_error; + if (!tab->empty && tab->need_undo) + if (isl_tab_push(tab, isl_tab_undo_empty) < 0) + return isl_stat_error; + tab->empty = 1; + return isl_stat_ok; +} + +int isl_tab_freeze_constraint(struct isl_tab *tab, int con) +{ + struct isl_tab_var *var; + + if (!tab) + return -1; + + var = &tab->con[con]; + if (var->frozen) + return 0; + if (var->index < 0) + return 0; + var->frozen = 1; + + if (tab->need_undo) + return isl_tab_push_var(tab, isl_tab_undo_freeze, var); + + return 0; +} + +/* Update the rows signs after a pivot of "row" and "col", with "row_sgn" + * the original sign of the pivot element. + * We only keep track of row signs during PILP solving and in this case + * we only pivot a row with negative sign (meaning the value is always + * non-positive) using a positive pivot element. + * + * For each row j, the new value of the parametric constant is equal to + * + * a_j0 - a_jc a_r0/a_rc + * + * where a_j0 is the original parametric constant, a_rc is the pivot element, + * a_r0 is the parametric constant of the pivot row and a_jc is the + * pivot column entry of the row j. + * Since a_r0 is non-positive and a_rc is positive, the sign of row j + * remains the same if a_jc has the same sign as the row j or if + * a_jc is zero. In all other cases, we reset the sign to "unknown". + */ +static void update_row_sign(struct isl_tab *tab, int row, int col, int row_sgn) +{ + int i; + struct isl_mat *mat = tab->mat; + unsigned off = 2 + tab->M; + + if (!tab->row_sign) + return; + + if (tab->row_sign[row] == 0) + return; + isl_assert(mat->ctx, row_sgn > 0, return); + isl_assert(mat->ctx, tab->row_sign[row] == isl_tab_row_neg, return); + tab->row_sign[row] = isl_tab_row_pos; + for (i = 0; i < tab->n_row; ++i) { + int s; + if (i == row) + continue; + s = isl_int_sgn(mat->row[i][off + col]); + if (!s) + continue; + if (!tab->row_sign[i]) + continue; + if (s < 0 && tab->row_sign[i] == isl_tab_row_neg) + continue; + if (s > 0 && tab->row_sign[i] == isl_tab_row_pos) + continue; + tab->row_sign[i] = isl_tab_row_unknown; + } +} + +/* Given a row number "row" and a column number "col", pivot the tableau + * such that the associated variables are interchanged. + * The given row in the tableau expresses + * + * x_r = a_r0 + \sum_i a_ri x_i + * + * or + * + * x_c = 1/a_rc x_r - a_r0/a_rc + sum_{i \ne r} -a_ri/a_rc + * + * Substituting this equality into the other rows + * + * x_j = a_j0 + \sum_i a_ji x_i + * + * with a_jc \ne 0, we obtain + * + * x_j = a_jc/a_rc x_r + a_j0 - a_jc a_r0/a_rc + sum a_ji - a_jc a_ri/a_rc + * + * The tableau + * + * n_rc/d_r n_ri/d_r + * n_jc/d_j n_ji/d_j + * + * where i is any other column and j is any other row, + * is therefore transformed into + * + * s(n_rc)d_r/|n_rc| -s(n_rc)n_ri/|n_rc| + * s(n_rc)d_r n_jc/(|n_rc| d_j) (n_ji |n_rc| - s(n_rc)n_jc n_ri)/(|n_rc| d_j) + * + * The transformation is performed along the following steps + * + * d_r/n_rc n_ri/n_rc + * n_jc/d_j n_ji/d_j + * + * s(n_rc)d_r/|n_rc| -s(n_rc)n_ri/|n_rc| + * n_jc/d_j n_ji/d_j + * + * s(n_rc)d_r/|n_rc| -s(n_rc)n_ri/|n_rc| + * n_jc/(|n_rc| d_j) n_ji/(|n_rc| d_j) + * + * s(n_rc)d_r/|n_rc| -s(n_rc)n_ri/|n_rc| + * n_jc/(|n_rc| d_j) (n_ji |n_rc|)/(|n_rc| d_j) + * + * s(n_rc)d_r/|n_rc| -s(n_rc)n_ri/|n_rc| + * n_jc/(|n_rc| d_j) (n_ji |n_rc| - s(n_rc)n_jc n_ri)/(|n_rc| d_j) + * + * s(n_rc)d_r/|n_rc| -s(n_rc)n_ri/|n_rc| + * s(n_rc)d_r n_jc/(|n_rc| d_j) (n_ji |n_rc| - s(n_rc)n_jc n_ri)/(|n_rc| d_j) + * + */ +int isl_tab_pivot(struct isl_tab *tab, int row, int col) +{ + int i, j; + int sgn; + int t; + isl_ctx *ctx; + struct isl_mat *mat = tab->mat; + struct isl_tab_var *var; + unsigned off = 2 + tab->M; + + ctx = isl_tab_get_ctx(tab); + if (isl_ctx_next_operation(ctx) < 0) + return -1; + + isl_int_swap(mat->row[row][0], mat->row[row][off + col]); + sgn = isl_int_sgn(mat->row[row][0]); + if (sgn < 0) { + isl_int_neg(mat->row[row][0], mat->row[row][0]); + isl_int_neg(mat->row[row][off + col], mat->row[row][off + col]); + } else + for (j = 0; j < off - 1 + tab->n_col; ++j) { + if (j == off - 1 + col) + continue; + isl_int_neg(mat->row[row][1 + j], mat->row[row][1 + j]); + } + if (!isl_int_is_one(mat->row[row][0])) + isl_seq_normalize(mat->ctx, mat->row[row], off + tab->n_col); + for (i = 0; i < tab->n_row; ++i) { + if (i == row) + continue; + if (isl_int_is_zero(mat->row[i][off + col])) + continue; + isl_int_mul(mat->row[i][0], mat->row[i][0], mat->row[row][0]); + for (j = 0; j < off - 1 + tab->n_col; ++j) { + if (j == off - 1 + col) + continue; + isl_int_mul(mat->row[i][1 + j], + mat->row[i][1 + j], mat->row[row][0]); + isl_int_addmul(mat->row[i][1 + j], + mat->row[i][off + col], mat->row[row][1 + j]); + } + isl_int_mul(mat->row[i][off + col], + mat->row[i][off + col], mat->row[row][off + col]); + if (!isl_int_is_one(mat->row[i][0])) + isl_seq_normalize(mat->ctx, mat->row[i], off + tab->n_col); + } + t = tab->row_var[row]; + tab->row_var[row] = tab->col_var[col]; + tab->col_var[col] = t; + var = isl_tab_var_from_row(tab, row); + var->is_row = 1; + var->index = row; + var = var_from_col(tab, col); + var->is_row = 0; + var->index = col; + update_row_sign(tab, row, col, sgn); + if (tab->in_undo) + return 0; + for (i = tab->n_redundant; i < tab->n_row; ++i) { + if (isl_int_is_zero(mat->row[i][off + col])) + continue; + if (!isl_tab_var_from_row(tab, i)->frozen && + isl_tab_row_is_redundant(tab, i)) { + int redo = isl_tab_mark_redundant(tab, i); + if (redo < 0) + return -1; + if (redo) + --i; + } + } + return 0; +} + +/* If "var" represents a column variable, then pivot is up (sgn > 0) + * or down (sgn < 0) to a row. The variable is assumed not to be + * unbounded in the specified direction. + * If sgn = 0, then the variable is unbounded in both directions, + * and we pivot with any row we can find. + */ +static int to_row(struct isl_tab *tab, struct isl_tab_var *var, int sign) WARN_UNUSED; +static int to_row(struct isl_tab *tab, struct isl_tab_var *var, int sign) +{ + int r; + unsigned off = 2 + tab->M; + + if (var->is_row) + return 0; + + if (sign == 0) { + for (r = tab->n_redundant; r < tab->n_row; ++r) + if (!isl_int_is_zero(tab->mat->row[r][off+var->index])) + break; + isl_assert(tab->mat->ctx, r < tab->n_row, return -1); + } else { + r = pivot_row(tab, NULL, sign, var->index); + isl_assert(tab->mat->ctx, r >= 0, return -1); + } + + return isl_tab_pivot(tab, r, var->index); +} + +/* Check whether all variables that are marked as non-negative + * also have a non-negative sample value. This function is not + * called from the current code but is useful during debugging. + */ +static void check_table(struct isl_tab *tab) __attribute__ ((unused)); +static void check_table(struct isl_tab *tab) +{ + int i; + + if (tab->empty) + return; + for (i = tab->n_redundant; i < tab->n_row; ++i) { + struct isl_tab_var *var; + var = isl_tab_var_from_row(tab, i); + if (!var->is_nonneg) + continue; + if (tab->M) { + isl_assert(tab->mat->ctx, + !isl_int_is_neg(tab->mat->row[i][2]), abort()); + if (isl_int_is_pos(tab->mat->row[i][2])) + continue; + } + isl_assert(tab->mat->ctx, !isl_int_is_neg(tab->mat->row[i][1]), + abort()); + } +} + +/* Return the sign of the maximal value of "var". + * If the sign is not negative, then on return from this function, + * the sample value will also be non-negative. + * + * If "var" is manifestly unbounded wrt positive values, we are done. + * Otherwise, we pivot the variable up to a row if needed. + * Then we continue pivoting up until either + * - no more up pivots can be performed + * - the sample value is positive + * - the variable is pivoted into a manifestly unbounded column + */ +static int sign_of_max(struct isl_tab *tab, struct isl_tab_var *var) +{ + int row, col; + + if (max_is_manifestly_unbounded(tab, var)) + return 1; + if (to_row(tab, var, 1) < 0) + return -2; + while (!isl_int_is_pos(tab->mat->row[var->index][1])) { + find_pivot(tab, var, var, 1, &row, &col); + if (row == -1) + return isl_int_sgn(tab->mat->row[var->index][1]); + if (isl_tab_pivot(tab, row, col) < 0) + return -2; + if (!var->is_row) /* manifestly unbounded */ + return 1; + } + return 1; +} + +int isl_tab_sign_of_max(struct isl_tab *tab, int con) +{ + struct isl_tab_var *var; + + if (!tab) + return -2; + + var = &tab->con[con]; + isl_assert(tab->mat->ctx, !var->is_redundant, return -2); + isl_assert(tab->mat->ctx, !var->is_zero, return -2); + + return sign_of_max(tab, var); +} + +static int row_is_neg(struct isl_tab *tab, int row) +{ + if (!tab->M) + return isl_int_is_neg(tab->mat->row[row][1]); + if (isl_int_is_pos(tab->mat->row[row][2])) + return 0; + if (isl_int_is_neg(tab->mat->row[row][2])) + return 1; + return isl_int_is_neg(tab->mat->row[row][1]); +} + +static int row_sgn(struct isl_tab *tab, int row) +{ + if (!tab->M) + return isl_int_sgn(tab->mat->row[row][1]); + if (!isl_int_is_zero(tab->mat->row[row][2])) + return isl_int_sgn(tab->mat->row[row][2]); + else + return isl_int_sgn(tab->mat->row[row][1]); +} + +/* Perform pivots until the row variable "var" has a non-negative + * sample value or until no more upward pivots can be performed. + * Return the sign of the sample value after the pivots have been + * performed. + */ +static int restore_row(struct isl_tab *tab, struct isl_tab_var *var) +{ + int row, col; + + while (row_is_neg(tab, var->index)) { + find_pivot(tab, var, var, 1, &row, &col); + if (row == -1) + break; + if (isl_tab_pivot(tab, row, col) < 0) + return -2; + if (!var->is_row) /* manifestly unbounded */ + return 1; + } + return row_sgn(tab, var->index); +} + +/* Perform pivots until we are sure that the row variable "var" + * can attain non-negative values. After return from this + * function, "var" is still a row variable, but its sample + * value may not be non-negative, even if the function returns 1. + */ +static int at_least_zero(struct isl_tab *tab, struct isl_tab_var *var) +{ + int row, col; + + while (isl_int_is_neg(tab->mat->row[var->index][1])) { + find_pivot(tab, var, var, 1, &row, &col); + if (row == -1) + break; + if (row == var->index) /* manifestly unbounded */ + return 1; + if (isl_tab_pivot(tab, row, col) < 0) + return -1; + } + return !isl_int_is_neg(tab->mat->row[var->index][1]); +} + +/* Return a negative value if "var" can attain negative values. + * Return a non-negative value otherwise. + * + * If "var" is manifestly unbounded wrt negative values, we are done. + * Otherwise, if var is in a column, we can pivot it down to a row. + * Then we continue pivoting down until either + * - the pivot would result in a manifestly unbounded column + * => we don't perform the pivot, but simply return -1 + * - no more down pivots can be performed + * - the sample value is negative + * If the sample value becomes negative and the variable is supposed + * to be nonnegative, then we undo the last pivot. + * However, if the last pivot has made the pivoting variable + * obviously redundant, then it may have moved to another row. + * In that case we look for upward pivots until we reach a non-negative + * value again. + */ +static int sign_of_min(struct isl_tab *tab, struct isl_tab_var *var) +{ + int row, col; + struct isl_tab_var *pivot_var = NULL; + + if (min_is_manifestly_unbounded(tab, var)) + return -1; + if (!var->is_row) { + col = var->index; + row = pivot_row(tab, NULL, -1, col); + pivot_var = var_from_col(tab, col); + if (isl_tab_pivot(tab, row, col) < 0) + return -2; + if (var->is_redundant) + return 0; + if (isl_int_is_neg(tab->mat->row[var->index][1])) { + if (var->is_nonneg) { + if (!pivot_var->is_redundant && + pivot_var->index == row) { + if (isl_tab_pivot(tab, row, col) < 0) + return -2; + } else + if (restore_row(tab, var) < -1) + return -2; + } + return -1; + } + } + if (var->is_redundant) + return 0; + while (!isl_int_is_neg(tab->mat->row[var->index][1])) { + find_pivot(tab, var, var, -1, &row, &col); + if (row == var->index) + return -1; + if (row == -1) + return isl_int_sgn(tab->mat->row[var->index][1]); + pivot_var = var_from_col(tab, col); + if (isl_tab_pivot(tab, row, col) < 0) + return -2; + if (var->is_redundant) + return 0; + } + if (pivot_var && var->is_nonneg) { + /* pivot back to non-negative value */ + if (!pivot_var->is_redundant && pivot_var->index == row) { + if (isl_tab_pivot(tab, row, col) < 0) + return -2; + } else + if (restore_row(tab, var) < -1) + return -2; + } + return -1; +} + +static int row_at_most_neg_one(struct isl_tab *tab, int row) +{ + if (tab->M) { + if (isl_int_is_pos(tab->mat->row[row][2])) + return 0; + if (isl_int_is_neg(tab->mat->row[row][2])) + return 1; + } + return isl_int_is_neg(tab->mat->row[row][1]) && + isl_int_abs_ge(tab->mat->row[row][1], + tab->mat->row[row][0]); +} + +/* Return 1 if "var" can attain values <= -1. + * Return 0 otherwise. + * + * If the variable "var" is supposed to be non-negative (is_nonneg is set), + * then the sample value of "var" is assumed to be non-negative when the + * the function is called. If 1 is returned then the constraint + * is not redundant and the sample value is made non-negative again before + * the function returns. + */ +int isl_tab_min_at_most_neg_one(struct isl_tab *tab, struct isl_tab_var *var) +{ + int row, col; + struct isl_tab_var *pivot_var; + + if (min_is_manifestly_unbounded(tab, var)) + return 1; + if (!var->is_row) { + col = var->index; + row = pivot_row(tab, NULL, -1, col); + pivot_var = var_from_col(tab, col); + if (isl_tab_pivot(tab, row, col) < 0) + return -1; + if (var->is_redundant) + return 0; + if (row_at_most_neg_one(tab, var->index)) { + if (var->is_nonneg) { + if (!pivot_var->is_redundant && + pivot_var->index == row) { + if (isl_tab_pivot(tab, row, col) < 0) + return -1; + } else + if (restore_row(tab, var) < -1) + return -1; + } + return 1; + } + } + if (var->is_redundant) + return 0; + do { + find_pivot(tab, var, var, -1, &row, &col); + if (row == var->index) { + if (var->is_nonneg && restore_row(tab, var) < -1) + return -1; + return 1; + } + if (row == -1) + return 0; + pivot_var = var_from_col(tab, col); + if (isl_tab_pivot(tab, row, col) < 0) + return -1; + if (var->is_redundant) + return 0; + } while (!row_at_most_neg_one(tab, var->index)); + if (var->is_nonneg) { + /* pivot back to non-negative value */ + if (!pivot_var->is_redundant && pivot_var->index == row) + if (isl_tab_pivot(tab, row, col) < 0) + return -1; + if (restore_row(tab, var) < -1) + return -1; + } + return 1; +} + +/* Return 1 if "var" can attain values >= 1. + * Return 0 otherwise. + */ +static int at_least_one(struct isl_tab *tab, struct isl_tab_var *var) +{ + int row, col; + isl_int *r; + + if (max_is_manifestly_unbounded(tab, var)) + return 1; + if (to_row(tab, var, 1) < 0) + return -1; + r = tab->mat->row[var->index]; + while (isl_int_lt(r[1], r[0])) { + find_pivot(tab, var, var, 1, &row, &col); + if (row == -1) + return isl_int_ge(r[1], r[0]); + if (row == var->index) /* manifestly unbounded */ + return 1; + if (isl_tab_pivot(tab, row, col) < 0) + return -1; + } + return 1; +} + +static void swap_cols(struct isl_tab *tab, int col1, int col2) +{ + int t; + unsigned off = 2 + tab->M; + t = tab->col_var[col1]; + tab->col_var[col1] = tab->col_var[col2]; + tab->col_var[col2] = t; + var_from_col(tab, col1)->index = col1; + var_from_col(tab, col2)->index = col2; + tab->mat = isl_mat_swap_cols(tab->mat, off + col1, off + col2); +} + +/* Mark column with index "col" as representing a zero variable. + * If we may need to undo the operation the column is kept, + * but no longer considered. + * Otherwise, the column is simply removed. + * + * The column may be interchanged with some other column. If it + * is interchanged with a later column, return 1. Otherwise return 0. + * If the columns are checked in order in the calling function, + * then a return value of 1 means that the column with the given + * column number may now contain a different column that + * hasn't been checked yet. + */ +int isl_tab_kill_col(struct isl_tab *tab, int col) +{ + var_from_col(tab, col)->is_zero = 1; + if (tab->need_undo) { + if (isl_tab_push_var(tab, isl_tab_undo_zero, + var_from_col(tab, col)) < 0) + return -1; + if (col != tab->n_dead) + swap_cols(tab, col, tab->n_dead); + tab->n_dead++; + return 0; + } else { + if (col != tab->n_col - 1) + swap_cols(tab, col, tab->n_col - 1); + var_from_col(tab, tab->n_col - 1)->index = -1; + tab->n_col--; + return 1; + } +} + +static int row_is_manifestly_non_integral(struct isl_tab *tab, int row) +{ + unsigned off = 2 + tab->M; + + if (tab->M && !isl_int_eq(tab->mat->row[row][2], + tab->mat->row[row][0])) + return 0; + if (isl_seq_first_non_zero(tab->mat->row[row] + off + tab->n_dead, + tab->n_col - tab->n_dead) != -1) + return 0; + + return !isl_int_is_divisible_by(tab->mat->row[row][1], + tab->mat->row[row][0]); +} + +/* For integer tableaus, check if any of the coordinates are stuck + * at a non-integral value. + */ +static int tab_is_manifestly_empty(struct isl_tab *tab) +{ + int i; + + if (tab->empty) + return 1; + if (tab->rational) + return 0; + + for (i = 0; i < tab->n_var; ++i) { + if (!tab->var[i].is_row) + continue; + if (row_is_manifestly_non_integral(tab, tab->var[i].index)) + return 1; + } + + return 0; +} + +/* Row variable "var" is non-negative and cannot attain any values + * larger than zero. This means that the coefficients of the unrestricted + * column variables are zero and that the coefficients of the non-negative + * column variables are zero or negative. + * Each of the non-negative variables with a negative coefficient can + * then also be written as the negative sum of non-negative variables + * and must therefore also be zero. + * + * If "temp_var" is set, then "var" is a temporary variable that + * will be removed after this function returns and for which + * no information is recorded on the undo stack. + * Do not add any undo records involving this variable in this case + * since the variable will have been removed before any future undo + * operations. Also avoid marking the variable as redundant, + * since that either adds an undo record or needlessly removes the row + * (the caller will take care of removing the row). + */ +static isl_stat close_row(struct isl_tab *tab, struct isl_tab_var *var, + int temp_var) WARN_UNUSED; +static isl_stat close_row(struct isl_tab *tab, struct isl_tab_var *var, + int temp_var) +{ + int j; + struct isl_mat *mat = tab->mat; + unsigned off = 2 + tab->M; + + if (!var->is_nonneg) + isl_die(isl_tab_get_ctx(tab), isl_error_internal, + "expecting non-negative variable", + return isl_stat_error); + var->is_zero = 1; + if (!temp_var && tab->need_undo) + if (isl_tab_push_var(tab, isl_tab_undo_zero, var) < 0) + return isl_stat_error; + for (j = tab->n_dead; j < tab->n_col; ++j) { + int recheck; + if (isl_int_is_zero(mat->row[var->index][off + j])) + continue; + if (isl_int_is_pos(mat->row[var->index][off + j])) + isl_die(isl_tab_get_ctx(tab), isl_error_internal, + "row cannot have positive coefficients", + return isl_stat_error); + recheck = isl_tab_kill_col(tab, j); + if (recheck < 0) + return isl_stat_error; + if (recheck) + --j; + } + if (!temp_var && isl_tab_mark_redundant(tab, var->index) < 0) + return isl_stat_error; + if (tab_is_manifestly_empty(tab) && isl_tab_mark_empty(tab) < 0) + return isl_stat_error; + return isl_stat_ok; +} + +/* Add a constraint to the tableau and allocate a row for it. + * Return the index into the constraint array "con". + * + * This function assumes that at least one more row and at least + * one more element in the constraint array are available in the tableau. + */ +int isl_tab_allocate_con(struct isl_tab *tab) +{ + int r; + + isl_assert(tab->mat->ctx, tab->n_row < tab->mat->n_row, return -1); + isl_assert(tab->mat->ctx, tab->n_con < tab->max_con, return -1); + + r = tab->n_con; + tab->con[r].index = tab->n_row; + tab->con[r].is_row = 1; + tab->con[r].is_nonneg = 0; + tab->con[r].is_zero = 0; + tab->con[r].is_redundant = 0; + tab->con[r].frozen = 0; + tab->con[r].negated = 0; + tab->row_var[tab->n_row] = ~r; + + tab->n_row++; + tab->n_con++; + if (isl_tab_push_var(tab, isl_tab_undo_allocate, &tab->con[r]) < 0) + return -1; + + return r; +} + +/* Move the entries in tab->var up one position, starting at "first", + * creating room for an extra entry at position "first". + * Since some of the entries of tab->row_var and tab->col_var contain + * indices into this array, they have to be updated accordingly. + */ +static int var_insert_entry(struct isl_tab *tab, int first) +{ + int i; + + if (tab->n_var >= tab->max_var) + isl_die(isl_tab_get_ctx(tab), isl_error_internal, + "not enough room for new variable", return -1); + if (first > tab->n_var) + isl_die(isl_tab_get_ctx(tab), isl_error_internal, + "invalid initial position", return -1); + + for (i = tab->n_var - 1; i >= first; --i) { + tab->var[i + 1] = tab->var[i]; + if (tab->var[i + 1].is_row) + tab->row_var[tab->var[i + 1].index]++; + else + tab->col_var[tab->var[i + 1].index]++; + } + + tab->n_var++; + + return 0; +} + +/* Drop the entry at position "first" in tab->var, moving all + * subsequent entries down. + * Since some of the entries of tab->row_var and tab->col_var contain + * indices into this array, they have to be updated accordingly. + */ +static int var_drop_entry(struct isl_tab *tab, int first) +{ + int i; + + if (first >= tab->n_var) + isl_die(isl_tab_get_ctx(tab), isl_error_internal, + "invalid initial position", return -1); + + tab->n_var--; + + for (i = first; i < tab->n_var; ++i) { + tab->var[i] = tab->var[i + 1]; + if (tab->var[i + 1].is_row) + tab->row_var[tab->var[i].index]--; + else + tab->col_var[tab->var[i].index]--; + } + + return 0; +} + +/* Add a variable to the tableau at position "r" and allocate a column for it. + * Return the index into the variable array "var", i.e., "r", + * or -1 on error. + */ +int isl_tab_insert_var(struct isl_tab *tab, int r) +{ + int i; + unsigned off = 2 + tab->M; + + isl_assert(tab->mat->ctx, tab->n_col < tab->mat->n_col, return -1); + + if (var_insert_entry(tab, r) < 0) + return -1; + + tab->var[r].index = tab->n_col; + tab->var[r].is_row = 0; + tab->var[r].is_nonneg = 0; + tab->var[r].is_zero = 0; + tab->var[r].is_redundant = 0; + tab->var[r].frozen = 0; + tab->var[r].negated = 0; + tab->col_var[tab->n_col] = r; + + for (i = 0; i < tab->n_row; ++i) + isl_int_set_si(tab->mat->row[i][off + tab->n_col], 0); + + tab->n_col++; + if (isl_tab_push_var(tab, isl_tab_undo_allocate, &tab->var[r]) < 0) + return -1; + + return r; +} + +/* Add a row to the tableau. The row is given as an affine combination + * of the original variables and needs to be expressed in terms of the + * column variables. + * + * This function assumes that at least one more row and at least + * one more element in the constraint array are available in the tableau. + * + * We add each term in turn. + * If r = n/d_r is the current sum and we need to add k x, then + * if x is a column variable, we increase the numerator of + * this column by k d_r + * if x = f/d_x is a row variable, then the new representation of r is + * + * n k f d_x/g n + d_r/g k f m/d_r n + m/d_g k f + * --- + --- = ------------------- = ------------------- + * d_r d_r d_r d_x/g m + * + * with g the gcd of d_r and d_x and m the lcm of d_r and d_x. + * + * If tab->M is set, then, internally, each variable x is represented + * as x' - M. We then also need no subtract k d_r from the coefficient of M. + */ +int isl_tab_add_row(struct isl_tab *tab, isl_int *line) +{ + int i; + int r; + isl_int *row; + isl_int a, b; + unsigned off = 2 + tab->M; + + r = isl_tab_allocate_con(tab); + if (r < 0) + return -1; + + isl_int_init(a); + isl_int_init(b); + row = tab->mat->row[tab->con[r].index]; + isl_int_set_si(row[0], 1); + isl_int_set(row[1], line[0]); + isl_seq_clr(row + 2, tab->M + tab->n_col); + for (i = 0; i < tab->n_var; ++i) { + if (tab->var[i].is_zero) + continue; + if (tab->var[i].is_row) { + isl_int_lcm(a, + row[0], tab->mat->row[tab->var[i].index][0]); + isl_int_swap(a, row[0]); + isl_int_divexact(a, row[0], a); + isl_int_divexact(b, + row[0], tab->mat->row[tab->var[i].index][0]); + isl_int_mul(b, b, line[1 + i]); + isl_seq_combine(row + 1, a, row + 1, + b, tab->mat->row[tab->var[i].index] + 1, + 1 + tab->M + tab->n_col); + } else + isl_int_addmul(row[off + tab->var[i].index], + line[1 + i], row[0]); + if (tab->M && i >= tab->n_param && i < tab->n_var - tab->n_div) + isl_int_submul(row[2], line[1 + i], row[0]); + } + isl_seq_normalize(tab->mat->ctx, row, off + tab->n_col); + isl_int_clear(a); + isl_int_clear(b); + + if (tab->row_sign) + tab->row_sign[tab->con[r].index] = isl_tab_row_unknown; + + return r; +} + +static isl_stat drop_row(struct isl_tab *tab, int row) +{ + isl_assert(tab->mat->ctx, ~tab->row_var[row] == tab->n_con - 1, + return isl_stat_error); + if (row != tab->n_row - 1) + swap_rows(tab, row, tab->n_row - 1); + tab->n_row--; + tab->n_con--; + return isl_stat_ok; +} + +/* Drop the variable in column "col" along with the column. + * The column is removed first because it may need to be moved + * into the last position and this process requires + * the contents of the col_var array in a state + * before the removal of the variable. + */ +static isl_stat drop_col(struct isl_tab *tab, int col) +{ + int var; + + var = tab->col_var[col]; + if (col != tab->n_col - 1) + swap_cols(tab, col, tab->n_col - 1); + tab->n_col--; + if (var_drop_entry(tab, var) < 0) + return isl_stat_error; + return isl_stat_ok; +} + +/* Add inequality "ineq" and check if it conflicts with the + * previously added constraints or if it is obviously redundant. + * + * This function assumes that at least one more row and at least + * one more element in the constraint array are available in the tableau. + */ +isl_stat isl_tab_add_ineq(struct isl_tab *tab, isl_int *ineq) +{ + int r; + int sgn; + isl_int cst; + + if (!tab) + return isl_stat_error; + if (tab->bmap) { + struct isl_basic_map *bmap = tab->bmap; + + isl_assert(tab->mat->ctx, tab->n_eq == bmap->n_eq, + return isl_stat_error); + isl_assert(tab->mat->ctx, + tab->n_con == bmap->n_eq + bmap->n_ineq, + return isl_stat_error); + tab->bmap = isl_basic_map_add_ineq(tab->bmap, ineq); + if (isl_tab_push(tab, isl_tab_undo_bmap_ineq) < 0) + return isl_stat_error; + if (!tab->bmap) + return isl_stat_error; + } + if (tab->cone) { + isl_int_init(cst); + isl_int_set_si(cst, 0); + isl_int_swap(ineq[0], cst); + } + r = isl_tab_add_row(tab, ineq); + if (tab->cone) { + isl_int_swap(ineq[0], cst); + isl_int_clear(cst); + } + if (r < 0) + return isl_stat_error; + tab->con[r].is_nonneg = 1; + if (isl_tab_push_var(tab, isl_tab_undo_nonneg, &tab->con[r]) < 0) + return isl_stat_error; + if (isl_tab_row_is_redundant(tab, tab->con[r].index)) { + if (isl_tab_mark_redundant(tab, tab->con[r].index) < 0) + return isl_stat_error; + return isl_stat_ok; + } + + sgn = restore_row(tab, &tab->con[r]); + if (sgn < -1) + return isl_stat_error; + if (sgn < 0) + return isl_tab_mark_empty(tab); + if (tab->con[r].is_row && isl_tab_row_is_redundant(tab, tab->con[r].index)) + if (isl_tab_mark_redundant(tab, tab->con[r].index) < 0) + return isl_stat_error; + return isl_stat_ok; +} + +/* Pivot a non-negative variable down until it reaches the value zero + * and then pivot the variable into a column position. + */ +static int to_col(struct isl_tab *tab, struct isl_tab_var *var) WARN_UNUSED; +static int to_col(struct isl_tab *tab, struct isl_tab_var *var) +{ + int i; + int row, col; + unsigned off = 2 + tab->M; + + if (!var->is_row) + return 0; + + while (isl_int_is_pos(tab->mat->row[var->index][1])) { + find_pivot(tab, var, NULL, -1, &row, &col); + isl_assert(tab->mat->ctx, row != -1, return -1); + if (isl_tab_pivot(tab, row, col) < 0) + return -1; + if (!var->is_row) + return 0; + } + + for (i = tab->n_dead; i < tab->n_col; ++i) + if (!isl_int_is_zero(tab->mat->row[var->index][off + i])) + break; + + isl_assert(tab->mat->ctx, i < tab->n_col, return -1); + if (isl_tab_pivot(tab, var->index, i) < 0) + return -1; + + return 0; +} + +/* We assume Gaussian elimination has been performed on the equalities. + * The equalities can therefore never conflict. + * Adding the equalities is currently only really useful for a later call + * to isl_tab_ineq_type. + * + * This function assumes that at least one more row and at least + * one more element in the constraint array are available in the tableau. + */ +static struct isl_tab *add_eq(struct isl_tab *tab, isl_int *eq) +{ + int i; + int r; + + if (!tab) + return NULL; + r = isl_tab_add_row(tab, eq); + if (r < 0) + goto error; + + r = tab->con[r].index; + i = isl_seq_first_non_zero(tab->mat->row[r] + 2 + tab->M + tab->n_dead, + tab->n_col - tab->n_dead); + isl_assert(tab->mat->ctx, i >= 0, goto error); + i += tab->n_dead; + if (isl_tab_pivot(tab, r, i) < 0) + goto error; + if (isl_tab_kill_col(tab, i) < 0) + goto error; + tab->n_eq++; + + return tab; +error: + isl_tab_free(tab); + return NULL; +} + +/* Does the sample value of row "row" of "tab" involve the big parameter, + * if any? + */ +static int row_is_big(struct isl_tab *tab, int row) +{ + return tab->M && !isl_int_is_zero(tab->mat->row[row][2]); +} + +static int row_is_manifestly_zero(struct isl_tab *tab, int row) +{ + unsigned off = 2 + tab->M; + + if (!isl_int_is_zero(tab->mat->row[row][1])) + return 0; + if (row_is_big(tab, row)) + return 0; + return isl_seq_first_non_zero(tab->mat->row[row] + off + tab->n_dead, + tab->n_col - tab->n_dead) == -1; +} + +/* Add an equality that is known to be valid for the given tableau. + * + * This function assumes that at least one more row and at least + * one more element in the constraint array are available in the tableau. + */ +int isl_tab_add_valid_eq(struct isl_tab *tab, isl_int *eq) +{ + struct isl_tab_var *var; + int r; + + if (!tab) + return -1; + r = isl_tab_add_row(tab, eq); + if (r < 0) + return -1; + + var = &tab->con[r]; + r = var->index; + if (row_is_manifestly_zero(tab, r)) { + var->is_zero = 1; + if (isl_tab_mark_redundant(tab, r) < 0) + return -1; + return 0; + } + + if (isl_int_is_neg(tab->mat->row[r][1])) { + isl_seq_neg(tab->mat->row[r] + 1, tab->mat->row[r] + 1, + 1 + tab->n_col); + var->negated = 1; + } + var->is_nonneg = 1; + if (to_col(tab, var) < 0) + return -1; + var->is_nonneg = 0; + if (isl_tab_kill_col(tab, var->index) < 0) + return -1; + + return 0; +} + +/* Add a zero row to "tab" and return the corresponding index + * in the constraint array. + * + * This function assumes that at least one more row and at least + * one more element in the constraint array are available in the tableau. + */ +static int add_zero_row(struct isl_tab *tab) +{ + int r; + isl_int *row; + + r = isl_tab_allocate_con(tab); + if (r < 0) + return -1; + + row = tab->mat->row[tab->con[r].index]; + isl_seq_clr(row + 1, 1 + tab->M + tab->n_col); + isl_int_set_si(row[0], 1); + + return r; +} + +/* Add equality "eq" and check if it conflicts with the + * previously added constraints or if it is obviously redundant. + * + * This function assumes that at least one more row and at least + * one more element in the constraint array are available in the tableau. + * If tab->bmap is set, then two rows are needed instead of one. + */ +isl_stat isl_tab_add_eq(struct isl_tab *tab, isl_int *eq) +{ + struct isl_tab_undo *snap = NULL; + struct isl_tab_var *var; + int r; + int row; + int sgn; + isl_int cst; + + if (!tab) + return isl_stat_error; + isl_assert(tab->mat->ctx, !tab->M, return isl_stat_error); + + if (tab->need_undo) + snap = isl_tab_snap(tab); + + if (tab->cone) { + isl_int_init(cst); + isl_int_set_si(cst, 0); + isl_int_swap(eq[0], cst); + } + r = isl_tab_add_row(tab, eq); + if (tab->cone) { + isl_int_swap(eq[0], cst); + isl_int_clear(cst); + } + if (r < 0) + return isl_stat_error; + + var = &tab->con[r]; + row = var->index; + if (row_is_manifestly_zero(tab, row)) { + if (snap) + return isl_tab_rollback(tab, snap); + return drop_row(tab, row); + } + + if (tab->bmap) { + tab->bmap = isl_basic_map_add_ineq(tab->bmap, eq); + if (isl_tab_push(tab, isl_tab_undo_bmap_ineq) < 0) + return isl_stat_error; + isl_seq_neg(eq, eq, 1 + tab->n_var); + tab->bmap = isl_basic_map_add_ineq(tab->bmap, eq); + isl_seq_neg(eq, eq, 1 + tab->n_var); + if (isl_tab_push(tab, isl_tab_undo_bmap_ineq) < 0) + return isl_stat_error; + if (!tab->bmap) + return isl_stat_error; + if (add_zero_row(tab) < 0) + return isl_stat_error; + } + + sgn = isl_int_sgn(tab->mat->row[row][1]); + + if (sgn > 0) { + isl_seq_neg(tab->mat->row[row] + 1, tab->mat->row[row] + 1, + 1 + tab->n_col); + var->negated = 1; + sgn = -1; + } + + if (sgn < 0) { + sgn = sign_of_max(tab, var); + if (sgn < -1) + return isl_stat_error; + if (sgn < 0) { + if (isl_tab_mark_empty(tab) < 0) + return isl_stat_error; + return isl_stat_ok; + } + } + + var->is_nonneg = 1; + if (to_col(tab, var) < 0) + return isl_stat_error; + var->is_nonneg = 0; + if (isl_tab_kill_col(tab, var->index) < 0) + return isl_stat_error; + + return isl_stat_ok; +} + +/* Construct and return an inequality that expresses an upper bound + * on the given div. + * In particular, if the div is given by + * + * d = floor(e/m) + * + * then the inequality expresses + * + * m d <= e + */ +static __isl_give isl_vec *ineq_for_div(__isl_keep isl_basic_map *bmap, + unsigned div) +{ + isl_size total; + unsigned div_pos; + struct isl_vec *ineq; + + total = isl_basic_map_dim(bmap, isl_dim_all); + if (total < 0) + return NULL; + + div_pos = 1 + total - bmap->n_div + div; + + ineq = isl_vec_alloc(bmap->ctx, 1 + total); + if (!ineq) + return NULL; + + isl_seq_cpy(ineq->el, bmap->div[div] + 1, 1 + total); + isl_int_neg(ineq->el[div_pos], bmap->div[div][0]); + return ineq; +} + +/* For a div d = floor(f/m), add the constraints + * + * f - m d >= 0 + * -(f-(m-1)) + m d >= 0 + * + * Note that the second constraint is the negation of + * + * f - m d >= m + * + * If add_ineq is not NULL, then this function is used + * instead of isl_tab_add_ineq to effectively add the inequalities. + * + * This function assumes that at least two more rows and at least + * two more elements in the constraint array are available in the tableau. + */ +static isl_stat add_div_constraints(struct isl_tab *tab, unsigned div, + isl_stat (*add_ineq)(void *user, isl_int *), void *user) +{ + isl_size total; + unsigned div_pos; + struct isl_vec *ineq; + + total = isl_basic_map_dim(tab->bmap, isl_dim_all); + if (total < 0) + return isl_stat_error; + div_pos = 1 + total - tab->bmap->n_div + div; + + ineq = ineq_for_div(tab->bmap, div); + if (!ineq) + goto error; + + if (add_ineq) { + if (add_ineq(user, ineq->el) < 0) + goto error; + } else { + if (isl_tab_add_ineq(tab, ineq->el) < 0) + goto error; + } + + isl_seq_neg(ineq->el, tab->bmap->div[div] + 1, 1 + total); + isl_int_set(ineq->el[div_pos], tab->bmap->div[div][0]); + isl_int_add(ineq->el[0], ineq->el[0], ineq->el[div_pos]); + isl_int_sub_ui(ineq->el[0], ineq->el[0], 1); + + if (add_ineq) { + if (add_ineq(user, ineq->el) < 0) + goto error; + } else { + if (isl_tab_add_ineq(tab, ineq->el) < 0) + goto error; + } + + isl_vec_free(ineq); + + return isl_stat_ok; +error: + isl_vec_free(ineq); + return isl_stat_error; +} + +/* Check whether the div described by "div" is obviously non-negative. + * If we are using a big parameter, then we will encode the div + * as div' = M + div, which is always non-negative. + * Otherwise, we check whether div is a non-negative affine combination + * of non-negative variables. + */ +static int div_is_nonneg(struct isl_tab *tab, __isl_keep isl_vec *div) +{ + int i; + + if (tab->M) + return 1; + + if (isl_int_is_neg(div->el[1])) + return 0; + + for (i = 0; i < tab->n_var; ++i) { + if (isl_int_is_neg(div->el[2 + i])) + return 0; + if (isl_int_is_zero(div->el[2 + i])) + continue; + if (!tab->var[i].is_nonneg) + return 0; + } + + return 1; +} + +/* Insert an extra div, prescribed by "div", to the tableau and + * the associated bmap (which is assumed to be non-NULL). + * The extra integer division is inserted at (tableau) position "pos". + * Return "pos" or -1 if an error occurred. + * + * If add_ineq is not NULL, then this function is used instead + * of isl_tab_add_ineq to add the div constraints. + * This complication is needed because the code in isl_tab_pip + * wants to perform some extra processing when an inequality + * is added to the tableau. + */ +int isl_tab_insert_div(struct isl_tab *tab, int pos, __isl_keep isl_vec *div, + isl_stat (*add_ineq)(void *user, isl_int *), void *user) +{ + int r; + int nonneg; + isl_size n_div; + int o_div; + + if (!tab || !div) + return -1; + + if (div->size != 1 + 1 + tab->n_var) + isl_die(isl_tab_get_ctx(tab), isl_error_invalid, + "unexpected size", return -1); + + n_div = isl_basic_map_dim(tab->bmap, isl_dim_div); + if (n_div < 0) + return -1; + o_div = tab->n_var - n_div; + if (pos < o_div || pos > tab->n_var) + isl_die(isl_tab_get_ctx(tab), isl_error_invalid, + "invalid position", return -1); + + nonneg = div_is_nonneg(tab, div); + + if (isl_tab_extend_cons(tab, 3) < 0) + return -1; + if (isl_tab_extend_vars(tab, 1) < 0) + return -1; + r = isl_tab_insert_var(tab, pos); + if (r < 0) + return -1; + + if (nonneg) + tab->var[r].is_nonneg = 1; + + tab->bmap = isl_basic_map_insert_div(tab->bmap, pos - o_div, div); + if (!tab->bmap) + return -1; + if (isl_tab_push_var(tab, isl_tab_undo_bmap_div, &tab->var[r]) < 0) + return -1; + + if (add_div_constraints(tab, pos - o_div, add_ineq, user) < 0) + return -1; + + return r; +} + +/* Add an extra div, prescribed by "div", to the tableau and + * the associated bmap (which is assumed to be non-NULL). + */ +int isl_tab_add_div(struct isl_tab *tab, __isl_keep isl_vec *div) +{ + if (!tab) + return -1; + return isl_tab_insert_div(tab, tab->n_var, div, NULL, NULL); +} + +/* If "track" is set, then we want to keep track of all constraints in tab + * in its bmap field. This field is initialized from a copy of "bmap", + * so we need to make sure that all constraints in "bmap" also appear + * in the constructed tab. + */ +__isl_give struct isl_tab *isl_tab_from_basic_map( + __isl_keep isl_basic_map *bmap, int track) +{ + int i; + struct isl_tab *tab; + isl_size total; + + total = isl_basic_map_dim(bmap, isl_dim_all); + if (total < 0) + return NULL; + tab = isl_tab_alloc(bmap->ctx, total + bmap->n_ineq + 1, total, 0); + if (!tab) + return NULL; + tab->preserve = track; + tab->rational = ISL_F_ISSET(bmap, ISL_BASIC_MAP_RATIONAL); + if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_EMPTY)) { + if (isl_tab_mark_empty(tab) < 0) + goto error; + goto done; + } + for (i = 0; i < bmap->n_eq; ++i) { + tab = add_eq(tab, bmap->eq[i]); + if (!tab) + return tab; + } + for (i = 0; i < bmap->n_ineq; ++i) { + if (isl_tab_add_ineq(tab, bmap->ineq[i]) < 0) + goto error; + if (tab->empty) + goto done; + } +done: + if (track && isl_tab_track_bmap(tab, isl_basic_map_copy(bmap)) < 0) + goto error; + return tab; +error: + isl_tab_free(tab); + return NULL; +} + +__isl_give struct isl_tab *isl_tab_from_basic_set( + __isl_keep isl_basic_set *bset, int track) +{ + return isl_tab_from_basic_map(bset, track); +} + +/* Construct a tableau corresponding to the recession cone of "bset". + */ +struct isl_tab *isl_tab_from_recession_cone(__isl_keep isl_basic_set *bset, + int parametric) +{ + isl_int cst; + int i; + struct isl_tab *tab; + isl_size offset = 0; + isl_size total; + + total = isl_basic_set_dim(bset, isl_dim_all); + if (parametric) + offset = isl_basic_set_dim(bset, isl_dim_param); + if (total < 0 || offset < 0) + return NULL; + tab = isl_tab_alloc(bset->ctx, bset->n_eq + bset->n_ineq, + total - offset, 0); + if (!tab) + return NULL; + tab->rational = ISL_F_ISSET(bset, ISL_BASIC_SET_RATIONAL); + tab->cone = 1; + + isl_int_init(cst); + isl_int_set_si(cst, 0); + for (i = 0; i < bset->n_eq; ++i) { + isl_int_swap(bset->eq[i][offset], cst); + if (offset > 0) { + if (isl_tab_add_eq(tab, bset->eq[i] + offset) < 0) + goto error; + } else + tab = add_eq(tab, bset->eq[i]); + isl_int_swap(bset->eq[i][offset], cst); + if (!tab) + goto done; + } + for (i = 0; i < bset->n_ineq; ++i) { + int r; + isl_int_swap(bset->ineq[i][offset], cst); + r = isl_tab_add_row(tab, bset->ineq[i] + offset); + isl_int_swap(bset->ineq[i][offset], cst); + if (r < 0) + goto error; + tab->con[r].is_nonneg = 1; + if (isl_tab_push_var(tab, isl_tab_undo_nonneg, &tab->con[r]) < 0) + goto error; + } +done: + isl_int_clear(cst); + return tab; +error: + isl_int_clear(cst); + isl_tab_free(tab); + return NULL; +} + +/* Assuming "tab" is the tableau of a cone, check if the cone is + * bounded, i.e., if it is empty or only contains the origin. + */ +isl_bool isl_tab_cone_is_bounded(struct isl_tab *tab) +{ + int i; + + if (!tab) + return isl_bool_error; + if (tab->empty) + return isl_bool_true; + if (tab->n_dead == tab->n_col) + return isl_bool_true; + + for (;;) { + for (i = tab->n_redundant; i < tab->n_row; ++i) { + struct isl_tab_var *var; + int sgn; + var = isl_tab_var_from_row(tab, i); + if (!var->is_nonneg) + continue; + sgn = sign_of_max(tab, var); + if (sgn < -1) + return isl_bool_error; + if (sgn != 0) + return isl_bool_false; + if (close_row(tab, var, 0) < 0) + return isl_bool_error; + break; + } + if (tab->n_dead == tab->n_col) + return isl_bool_true; + if (i == tab->n_row) + return isl_bool_false; + } +} + +int isl_tab_sample_is_integer(struct isl_tab *tab) +{ + int i; + + if (!tab) + return -1; + + for (i = 0; i < tab->n_var; ++i) { + int row; + if (!tab->var[i].is_row) + continue; + row = tab->var[i].index; + if (!isl_int_is_divisible_by(tab->mat->row[row][1], + tab->mat->row[row][0])) + return 0; + } + return 1; +} + +static struct isl_vec *extract_integer_sample(struct isl_tab *tab) +{ + int i; + struct isl_vec *vec; + + vec = isl_vec_alloc(tab->mat->ctx, 1 + tab->n_var); + if (!vec) + return NULL; + + isl_int_set_si(vec->block.data[0], 1); + for (i = 0; i < tab->n_var; ++i) { + if (!tab->var[i].is_row) + isl_int_set_si(vec->block.data[1 + i], 0); + else { + int row = tab->var[i].index; + isl_int_divexact(vec->block.data[1 + i], + tab->mat->row[row][1], tab->mat->row[row][0]); + } + } + + return vec; +} + +__isl_give isl_vec *isl_tab_get_sample_value(struct isl_tab *tab) +{ + int i; + struct isl_vec *vec; + isl_int m; + + if (!tab) + return NULL; + + vec = isl_vec_alloc(tab->mat->ctx, 1 + tab->n_var); + if (!vec) + return NULL; + + isl_int_init(m); + + isl_int_set_si(vec->block.data[0], 1); + for (i = 0; i < tab->n_var; ++i) { + int row; + if (!tab->var[i].is_row) { + isl_int_set_si(vec->block.data[1 + i], 0); + continue; + } + row = tab->var[i].index; + isl_int_gcd(m, vec->block.data[0], tab->mat->row[row][0]); + isl_int_divexact(m, tab->mat->row[row][0], m); + isl_seq_scale(vec->block.data, vec->block.data, m, 1 + i); + isl_int_divexact(m, vec->block.data[0], tab->mat->row[row][0]); + isl_int_mul(vec->block.data[1 + i], m, tab->mat->row[row][1]); + } + vec = isl_vec_normalize(vec); + + isl_int_clear(m); + return vec; +} + +/* Store the sample value of "var" of "tab" rounded up (if sgn > 0) + * or down (if sgn < 0) to the nearest integer in *v. + */ +static void get_rounded_sample_value(struct isl_tab *tab, + struct isl_tab_var *var, int sgn, isl_int *v) +{ + if (!var->is_row) + isl_int_set_si(*v, 0); + else if (sgn > 0) + isl_int_cdiv_q(*v, tab->mat->row[var->index][1], + tab->mat->row[var->index][0]); + else + isl_int_fdiv_q(*v, tab->mat->row[var->index][1], + tab->mat->row[var->index][0]); +} + +/* Update "bmap" based on the results of the tableau "tab". + * In particular, implicit equalities are made explicit, redundant constraints + * are removed and if the sample value happens to be integer, it is stored + * in "bmap" (unless "bmap" already had an integer sample). + * + * The tableau is assumed to have been created from "bmap" using + * isl_tab_from_basic_map. + */ +__isl_give isl_basic_map *isl_basic_map_update_from_tab( + __isl_take isl_basic_map *bmap, struct isl_tab *tab) +{ + int i; + unsigned n_eq; + + if (!bmap) + return NULL; + if (!tab) + return bmap; + + n_eq = tab->n_eq; + if (tab->empty) + bmap = isl_basic_map_set_to_empty(bmap); + else + for (i = bmap->n_ineq - 1; i >= 0; --i) { + if (isl_tab_is_equality(tab, n_eq + i)) + isl_basic_map_inequality_to_equality(bmap, i); + else if (isl_tab_is_redundant(tab, n_eq + i)) + isl_basic_map_drop_inequality(bmap, i); + } + if (bmap->n_eq != n_eq) + bmap = isl_basic_map_gauss(bmap, NULL); + if (!tab->rational && + bmap && !bmap->sample && isl_tab_sample_is_integer(tab)) + bmap->sample = extract_integer_sample(tab); + return bmap; +} + +__isl_give isl_basic_set *isl_basic_set_update_from_tab( + __isl_take isl_basic_set *bset, struct isl_tab *tab) +{ + return bset_from_bmap(isl_basic_map_update_from_tab(bset_to_bmap(bset), + tab)); +} + +/* Drop the last constraint added to "tab" in position "r". + * The constraint is expected to have remained in a row. + */ +static isl_stat drop_last_con_in_row(struct isl_tab *tab, int r) +{ + if (!tab->con[r].is_row) + isl_die(isl_tab_get_ctx(tab), isl_error_internal, + "row unexpectedly moved to column", + return isl_stat_error); + if (r + 1 != tab->n_con) + isl_die(isl_tab_get_ctx(tab), isl_error_internal, + "additional constraints added", return isl_stat_error); + if (drop_row(tab, tab->con[r].index) < 0) + return isl_stat_error; + + return isl_stat_ok; +} + +/* Given a non-negative variable "var", temporarily add a new non-negative + * variable that is the opposite of "var", ensuring that "var" can only attain + * the value zero. The new variable is removed again before this function + * returns. However, the effect of forcing "var" to be zero remains. + * If var = n/d is a row variable, then the new variable = -n/d. + * If var is a column variables, then the new variable = -var. + * If the new variable cannot attain non-negative values, then + * the resulting tableau is empty. + * Otherwise, we know the value will be zero and we close the row. + */ +static isl_stat cut_to_hyperplane(struct isl_tab *tab, struct isl_tab_var *var) +{ + unsigned r; + isl_int *row; + int sgn; + unsigned off = 2 + tab->M; + + if (var->is_zero) + return isl_stat_ok; + if (var->is_redundant || !var->is_nonneg) + isl_die(isl_tab_get_ctx(tab), isl_error_invalid, + "expecting non-redundant non-negative variable", + return isl_stat_error); + + if (isl_tab_extend_cons(tab, 1) < 0) + return isl_stat_error; + + r = tab->n_con; + tab->con[r].index = tab->n_row; + tab->con[r].is_row = 1; + tab->con[r].is_nonneg = 0; + tab->con[r].is_zero = 0; + tab->con[r].is_redundant = 0; + tab->con[r].frozen = 0; + tab->con[r].negated = 0; + tab->row_var[tab->n_row] = ~r; + row = tab->mat->row[tab->n_row]; + + if (var->is_row) { + isl_int_set(row[0], tab->mat->row[var->index][0]); + isl_seq_neg(row + 1, + tab->mat->row[var->index] + 1, 1 + tab->n_col); + } else { + isl_int_set_si(row[0], 1); + isl_seq_clr(row + 1, 1 + tab->n_col); + isl_int_set_si(row[off + var->index], -1); + } + + tab->n_row++; + tab->n_con++; + + sgn = sign_of_max(tab, &tab->con[r]); + if (sgn < -1) + return isl_stat_error; + if (sgn < 0) { + if (drop_last_con_in_row(tab, r) < 0) + return isl_stat_error; + if (isl_tab_mark_empty(tab) < 0) + return isl_stat_error; + return isl_stat_ok; + } + tab->con[r].is_nonneg = 1; + /* sgn == 0 */ + if (close_row(tab, &tab->con[r], 1) < 0) + return isl_stat_error; + if (drop_last_con_in_row(tab, r) < 0) + return isl_stat_error; + + return isl_stat_ok; +} + +/* Check that "con" is a valid constraint position for "tab". + */ +static isl_stat isl_tab_check_con(struct isl_tab *tab, int con) +{ + if (!tab) + return isl_stat_error; + if (con < 0 || con >= tab->n_con) + isl_die(isl_tab_get_ctx(tab), isl_error_invalid, + "position out of bounds", return isl_stat_error); + return isl_stat_ok; +} + +/* Given a tableau "tab" and an inequality constraint "con" of the tableau, + * relax the inequality by one. That is, the inequality r >= 0 is replaced + * by r' = r + 1 >= 0. + * If r is a row variable, we simply increase the constant term by one + * (taking into account the denominator). + * If r is a column variable, then we need to modify each row that + * refers to r = r' - 1 by substituting this equality, effectively + * subtracting the coefficient of the column from the constant. + * We should only do this if the minimum is manifestly unbounded, + * however. Otherwise, we may end up with negative sample values + * for non-negative variables. + * So, if r is a column variable with a minimum that is not + * manifestly unbounded, then we need to move it to a row. + * However, the sample value of this row may be negative, + * even after the relaxation, so we need to restore it. + * We therefore prefer to pivot a column up to a row, if possible. + */ +int isl_tab_relax(struct isl_tab *tab, int con) +{ + struct isl_tab_var *var; + + if (!tab) + return -1; + + var = &tab->con[con]; + + if (var->is_row && (var->index < 0 || var->index < tab->n_redundant)) + isl_die(tab->mat->ctx, isl_error_invalid, + "cannot relax redundant constraint", return -1); + if (!var->is_row && (var->index < 0 || var->index < tab->n_dead)) + isl_die(tab->mat->ctx, isl_error_invalid, + "cannot relax dead constraint", return -1); + + if (!var->is_row && !max_is_manifestly_unbounded(tab, var)) + if (to_row(tab, var, 1) < 0) + return -1; + if (!var->is_row && !min_is_manifestly_unbounded(tab, var)) + if (to_row(tab, var, -1) < 0) + return -1; + + if (var->is_row) { + isl_int_add(tab->mat->row[var->index][1], + tab->mat->row[var->index][1], tab->mat->row[var->index][0]); + if (restore_row(tab, var) < 0) + return -1; + } else { + int i; + unsigned off = 2 + tab->M; + + for (i = 0; i < tab->n_row; ++i) { + if (isl_int_is_zero(tab->mat->row[i][off + var->index])) + continue; + isl_int_sub(tab->mat->row[i][1], tab->mat->row[i][1], + tab->mat->row[i][off + var->index]); + } + + } + + if (isl_tab_push_var(tab, isl_tab_undo_relax, var) < 0) + return -1; + + return 0; +} + +/* Replace the variable v at position "pos" in the tableau "tab" + * by v' = v + shift. + * + * If the variable is in a column, then we first check if we can + * simply plug in v = v' - shift. The effect on a row with + * coefficient f/d for variable v is that the constant term c/d + * is replaced by (c - f * shift)/d. If shift is positive and + * f is negative for each row that needs to remain non-negative, + * then this is clearly safe. In other words, if the minimum of v + * is manifestly unbounded, then we can keep v in a column position. + * Otherwise, we can pivot it down to a row. + * Similarly, if shift is negative, we need to check if the maximum + * of is manifestly unbounded. + * + * If the variable is in a row (from the start or after pivoting), + * then the constant term c/d is replaced by (c + d * shift)/d. + */ +int isl_tab_shift_var(struct isl_tab *tab, int pos, isl_int shift) +{ + struct isl_tab_var *var; + + if (!tab) + return -1; + if (isl_int_is_zero(shift)) + return 0; + + var = &tab->var[pos]; + if (!var->is_row) { + if (isl_int_is_neg(shift)) { + if (!max_is_manifestly_unbounded(tab, var)) + if (to_row(tab, var, 1) < 0) + return -1; + } else { + if (!min_is_manifestly_unbounded(tab, var)) + if (to_row(tab, var, -1) < 0) + return -1; + } + } + + if (var->is_row) { + isl_int_addmul(tab->mat->row[var->index][1], + shift, tab->mat->row[var->index][0]); + } else { + int i; + unsigned off = 2 + tab->M; + + for (i = 0; i < tab->n_row; ++i) { + if (isl_int_is_zero(tab->mat->row[i][off + var->index])) + continue; + isl_int_submul(tab->mat->row[i][1], + shift, tab->mat->row[i][off + var->index]); + } + + } + + return 0; +} + +/* Remove the sign constraint from constraint "con". + * + * If the constraint variable was originally marked non-negative, + * then we make sure we mark it non-negative again during rollback. + */ +int isl_tab_unrestrict(struct isl_tab *tab, int con) +{ + struct isl_tab_var *var; + + if (!tab) + return -1; + + var = &tab->con[con]; + if (!var->is_nonneg) + return 0; + + var->is_nonneg = 0; + if (isl_tab_push_var(tab, isl_tab_undo_unrestrict, var) < 0) + return -1; + + return 0; +} + +int isl_tab_select_facet(struct isl_tab *tab, int con) +{ + if (!tab) + return -1; + + return cut_to_hyperplane(tab, &tab->con[con]); +} + +static int may_be_equality(struct isl_tab *tab, int row) +{ + return tab->rational ? isl_int_is_zero(tab->mat->row[row][1]) + : isl_int_lt(tab->mat->row[row][1], + tab->mat->row[row][0]); +} + +/* Return an isl_tab_var that has been marked or NULL if no such + * variable can be found. + * The marked field has only been set for variables that + * appear in non-redundant rows or non-dead columns. + * + * Pick the last constraint variable that is marked and + * that appears in either a non-redundant row or a non-dead columns. + * Since the returned variable is tested for being a redundant constraint or + * an implicit equality, there is no need to return any tab variable that + * corresponds to a variable. + */ +static struct isl_tab_var *select_marked(struct isl_tab *tab) +{ + int i; + struct isl_tab_var *var; + + for (i = tab->n_con - 1; i >= 0; --i) { + var = &tab->con[i]; + if (var->index < 0) + continue; + if (var->is_row && var->index < tab->n_redundant) + continue; + if (!var->is_row && var->index < tab->n_dead) + continue; + if (var->marked) + return var; + } + + return NULL; +} + +/* Check for (near) equalities among the constraints. + * A constraint is an equality if it is non-negative and if + * its maximal value is either + * - zero (in case of rational tableaus), or + * - strictly less than 1 (in case of integer tableaus) + * + * We first mark all non-redundant and non-dead variables that + * are not frozen and not obviously not an equality. + * Then we iterate over all marked variables if they can attain + * any values larger than zero or at least one. + * If the maximal value is zero, we mark any column variables + * that appear in the row as being zero and mark the row as being redundant. + * Otherwise, if the maximal value is strictly less than one (and the + * tableau is integer), then we restrict the value to being zero + * by adding an opposite non-negative variable. + * The order in which the variables are considered is not important. + */ +int isl_tab_detect_implicit_equalities(struct isl_tab *tab) +{ + int i; + unsigned n_marked; + + if (!tab) + return -1; + if (tab->empty) + return 0; + if (tab->n_dead == tab->n_col) + return 0; + + n_marked = 0; + for (i = tab->n_redundant; i < tab->n_row; ++i) { + struct isl_tab_var *var = isl_tab_var_from_row(tab, i); + var->marked = !var->frozen && var->is_nonneg && + may_be_equality(tab, i); + if (var->marked) + n_marked++; + } + for (i = tab->n_dead; i < tab->n_col; ++i) { + struct isl_tab_var *var = var_from_col(tab, i); + var->marked = !var->frozen && var->is_nonneg; + if (var->marked) + n_marked++; + } + while (n_marked) { + struct isl_tab_var *var; + int sgn; + var = select_marked(tab); + if (!var) + break; + var->marked = 0; + n_marked--; + sgn = sign_of_max(tab, var); + if (sgn < 0) + return -1; + if (sgn == 0) { + if (close_row(tab, var, 0) < 0) + return -1; + } else if (!tab->rational && !at_least_one(tab, var)) { + if (cut_to_hyperplane(tab, var) < 0) + return -1; + return isl_tab_detect_implicit_equalities(tab); + } + for (i = tab->n_redundant; i < tab->n_row; ++i) { + var = isl_tab_var_from_row(tab, i); + if (!var->marked) + continue; + if (may_be_equality(tab, i)) + continue; + var->marked = 0; + n_marked--; + } + } + + return 0; +} + +/* Update the element of row_var or col_var that corresponds to + * constraint tab->con[i] to a move from position "old" to position "i". + */ +static int update_con_after_move(struct isl_tab *tab, int i, int old) +{ + int *p; + int index; + + index = tab->con[i].index; + if (index == -1) + return 0; + p = tab->con[i].is_row ? tab->row_var : tab->col_var; + if (p[index] != ~old) + isl_die(tab->mat->ctx, isl_error_internal, + "broken internal state", return -1); + p[index] = ~i; + + return 0; +} + +/* Interchange constraints "con1" and "con2" in "tab". + * In particular, interchange the contents of these entries in tab->con. + * Since tab->col_var and tab->row_var point back into this array, + * they need to be updated accordingly. + */ +isl_stat isl_tab_swap_constraints(struct isl_tab *tab, int con1, int con2) +{ + struct isl_tab_var var; + + if (isl_tab_check_con(tab, con1) < 0 || + isl_tab_check_con(tab, con2) < 0) + return isl_stat_error; + + var = tab->con[con1]; + tab->con[con1] = tab->con[con2]; + if (update_con_after_move(tab, con1, con2) < 0) + return isl_stat_error; + tab->con[con2] = var; + if (update_con_after_move(tab, con2, con1) < 0) + return isl_stat_error; + + return isl_stat_ok; +} + +/* Rotate the "n" constraints starting at "first" to the right, + * putting the last constraint in the position of the first constraint. + */ +static int rotate_constraints(struct isl_tab *tab, int first, int n) +{ + int i, last; + struct isl_tab_var var; + + if (n <= 1) + return 0; + + last = first + n - 1; + var = tab->con[last]; + for (i = last; i > first; --i) { + tab->con[i] = tab->con[i - 1]; + if (update_con_after_move(tab, i, i - 1) < 0) + return -1; + } + tab->con[first] = var; + if (update_con_after_move(tab, first, last) < 0) + return -1; + + return 0; +} + +/* Drop the "n" entries starting at position "first" in tab->con, moving all + * subsequent entries down. + * Since some of the entries of tab->row_var and tab->col_var contain + * indices into this array, they have to be updated accordingly. + */ +static isl_stat con_drop_entries(struct isl_tab *tab, + unsigned first, unsigned n) +{ + int i; + + if (first + n > tab->n_con || first + n < first) + isl_die(isl_tab_get_ctx(tab), isl_error_internal, + "invalid range", return isl_stat_error); + + tab->n_con -= n; + + for (i = first; i < tab->n_con; ++i) { + tab->con[i] = tab->con[i + n]; + if (update_con_after_move(tab, i, i + n) < 0) + return isl_stat_error; + } + + return isl_stat_ok; +} + +/* isl_basic_map_gauss5 callback that gets called when + * two (equality) constraints "a" and "b" get interchanged + * in the basic map. Perform the same interchange in "tab". + */ +static isl_stat swap_eq(unsigned a, unsigned b, void *user) +{ + struct isl_tab *tab = user; + + return isl_tab_swap_constraints(tab, a, b); +} + +/* isl_basic_map_gauss5 callback that gets called when + * the final "n" equality constraints get removed. + * As a special case, if "n" is equal to the total number + * of equality constraints, then this means the basic map + * turned out to be empty. + * Drop the same number of equality constraints from "tab" or + * mark it empty in the special case. + */ +static isl_stat drop_eq(unsigned n, void *user) +{ + struct isl_tab *tab = user; + + if (tab->n_eq == n) + return isl_tab_mark_empty(tab); + + tab->n_eq -= n; + return con_drop_entries(tab, tab->n_eq, n); +} + +/* If "bmap" has more than a single reference, then call + * isl_basic_map_gauss on it, updating "tab" accordingly. + */ +static __isl_give isl_basic_map *gauss_if_shared(__isl_take isl_basic_map *bmap, + struct isl_tab *tab) +{ + isl_bool single; + + single = isl_basic_map_has_single_reference(bmap); + if (single < 0) + return isl_basic_map_free(bmap); + if (single) + return bmap; + return isl_basic_map_gauss5(bmap, NULL, &swap_eq, &drop_eq, tab); +} + +/* Make the equalities that are implicit in "bmap" but that have been + * detected in the corresponding "tab" explicit in "bmap" and update + * "tab" to reflect the new order of the constraints. + * + * In particular, if inequality i is an implicit equality then + * isl_basic_map_inequality_to_equality will move the inequality + * in front of the other equality and it will move the last inequality + * in the position of inequality i. + * In the tableau, the inequalities of "bmap" are stored after the equalities + * and so the original order + * + * E E E E E A A A I B B B B L + * + * is changed into + * + * I E E E E E A A A L B B B B + * + * where I is the implicit equality, the E are equalities, + * the A inequalities before I, the B inequalities after I and + * L the last inequality. + * We therefore need to rotate to the right two sets of constraints, + * those up to and including I and those after I. + * + * If "tab" contains any constraints that are not in "bmap" then they + * appear after those in "bmap" and they should be left untouched. + * + * Note that this function only calls isl_basic_map_gauss + * (in case some equality constraints got detected) + * if "bmap" has more than one reference. + * If it only has a single reference, then it is left in a temporary state, + * because the caller may require this state. + * Calling isl_basic_map_gauss is then the responsibility of the caller. + */ +__isl_give isl_basic_map *isl_tab_make_equalities_explicit(struct isl_tab *tab, + __isl_take isl_basic_map *bmap) +{ + int i; + unsigned n_eq; + + if (!tab || !bmap) + return isl_basic_map_free(bmap); + if (tab->empty) + return bmap; + + n_eq = tab->n_eq; + for (i = bmap->n_ineq - 1; i >= 0; --i) { + if (!isl_tab_is_equality(tab, bmap->n_eq + i)) + continue; + isl_basic_map_inequality_to_equality(bmap, i); + if (rotate_constraints(tab, 0, tab->n_eq + i + 1) < 0) + return isl_basic_map_free(bmap); + if (rotate_constraints(tab, tab->n_eq + i + 1, + bmap->n_ineq - i) < 0) + return isl_basic_map_free(bmap); + tab->n_eq++; + } + + if (n_eq != tab->n_eq) + bmap = gauss_if_shared(bmap, tab); + + return bmap; +} + +static int con_is_redundant(struct isl_tab *tab, struct isl_tab_var *var) +{ + if (!tab) + return -1; + if (tab->rational) { + int sgn = sign_of_min(tab, var); + if (sgn < -1) + return -1; + return sgn >= 0; + } else { + int irred = isl_tab_min_at_most_neg_one(tab, var); + if (irred < 0) + return -1; + return !irred; + } +} + +/* Check for (near) redundant constraints. + * A constraint is redundant if it is non-negative and if + * its minimal value (temporarily ignoring the non-negativity) is either + * - zero (in case of rational tableaus), or + * - strictly larger than -1 (in case of integer tableaus) + * + * We first mark all non-redundant and non-dead variables that + * are not frozen and not obviously negatively unbounded. + * Then we iterate over all marked variables if they can attain + * any values smaller than zero or at most negative one. + * If not, we mark the row as being redundant (assuming it hasn't + * been detected as being obviously redundant in the mean time). + */ +int isl_tab_detect_redundant(struct isl_tab *tab) +{ + int i; + unsigned n_marked; + + if (!tab) + return -1; + if (tab->empty) + return 0; + if (tab->n_redundant == tab->n_row) + return 0; + + n_marked = 0; + for (i = tab->n_redundant; i < tab->n_row; ++i) { + struct isl_tab_var *var = isl_tab_var_from_row(tab, i); + var->marked = !var->frozen && var->is_nonneg; + if (var->marked) + n_marked++; + } + for (i = tab->n_dead; i < tab->n_col; ++i) { + struct isl_tab_var *var = var_from_col(tab, i); + var->marked = !var->frozen && var->is_nonneg && + !min_is_manifestly_unbounded(tab, var); + if (var->marked) + n_marked++; + } + while (n_marked) { + struct isl_tab_var *var; + int red; + var = select_marked(tab); + if (!var) + break; + var->marked = 0; + n_marked--; + red = con_is_redundant(tab, var); + if (red < 0) + return -1; + if (red && !var->is_redundant) + if (isl_tab_mark_redundant(tab, var->index) < 0) + return -1; + for (i = tab->n_dead; i < tab->n_col; ++i) { + var = var_from_col(tab, i); + if (!var->marked) + continue; + if (!min_is_manifestly_unbounded(tab, var)) + continue; + var->marked = 0; + n_marked--; + } + } + + return 0; +} + +int isl_tab_is_equality(struct isl_tab *tab, int con) +{ + int row; + unsigned off; + + if (!tab) + return -1; + if (tab->con[con].is_zero) + return 1; + if (tab->con[con].is_redundant) + return 0; + if (!tab->con[con].is_row) + return tab->con[con].index < tab->n_dead; + + row = tab->con[con].index; + + off = 2 + tab->M; + return isl_int_is_zero(tab->mat->row[row][1]) && + !row_is_big(tab, row) && + isl_seq_first_non_zero(tab->mat->row[row] + off + tab->n_dead, + tab->n_col - tab->n_dead) == -1; +} + +/* Return the minimal value of the affine expression "f" with denominator + * "denom" in *opt, *opt_denom, assuming the tableau is not empty and + * the expression cannot attain arbitrarily small values. + * If opt_denom is NULL, then *opt is rounded up to the nearest integer. + * The return value reflects the nature of the result (empty, unbounded, + * minimal value returned in *opt). + * + * This function assumes that at least one more row and at least + * one more element in the constraint array are available in the tableau. + */ +enum isl_lp_result isl_tab_min(struct isl_tab *tab, + isl_int *f, isl_int denom, isl_int *opt, isl_int *opt_denom, + unsigned flags) +{ + int r; + enum isl_lp_result res = isl_lp_ok; + struct isl_tab_var *var; + struct isl_tab_undo *snap; + + if (!tab) + return isl_lp_error; + + if (tab->empty) + return isl_lp_empty; + + snap = isl_tab_snap(tab); + r = isl_tab_add_row(tab, f); + if (r < 0) + return isl_lp_error; + var = &tab->con[r]; + for (;;) { + int row, col; + find_pivot(tab, var, var, -1, &row, &col); + if (row == var->index) { + res = isl_lp_unbounded; + break; + } + if (row == -1) + break; + if (isl_tab_pivot(tab, row, col) < 0) + return isl_lp_error; + } + isl_int_mul(tab->mat->row[var->index][0], + tab->mat->row[var->index][0], denom); + if (ISL_FL_ISSET(flags, ISL_TAB_SAVE_DUAL)) { + int i; + + isl_vec_free(tab->dual); + tab->dual = isl_vec_alloc(tab->mat->ctx, 1 + tab->n_con); + if (!tab->dual) + return isl_lp_error; + isl_int_set(tab->dual->el[0], tab->mat->row[var->index][0]); + for (i = 0; i < tab->n_con; ++i) { + int pos; + if (tab->con[i].is_row) { + isl_int_set_si(tab->dual->el[1 + i], 0); + continue; + } + pos = 2 + tab->M + tab->con[i].index; + if (tab->con[i].negated) + isl_int_neg(tab->dual->el[1 + i], + tab->mat->row[var->index][pos]); + else + isl_int_set(tab->dual->el[1 + i], + tab->mat->row[var->index][pos]); + } + } + if (opt && res == isl_lp_ok) { + if (opt_denom) { + isl_int_set(*opt, tab->mat->row[var->index][1]); + isl_int_set(*opt_denom, tab->mat->row[var->index][0]); + } else + get_rounded_sample_value(tab, var, 1, opt); + } + if (isl_tab_rollback(tab, snap) < 0) + return isl_lp_error; + return res; +} + +/* Is the constraint at position "con" marked as being redundant? + * If it is marked as representing an equality, then it is not + * considered to be redundant. + * Note that isl_tab_mark_redundant marks both the isl_tab_var as + * redundant and moves the corresponding row into the first + * tab->n_redundant positions (or removes the row, assigning it index -1), + * so the final test is actually redundant itself. + */ +int isl_tab_is_redundant(struct isl_tab *tab, int con) +{ + if (isl_tab_check_con(tab, con) < 0) + return -1; + if (tab->con[con].is_zero) + return 0; + if (tab->con[con].is_redundant) + return 1; + return tab->con[con].is_row && tab->con[con].index < tab->n_redundant; +} + +/* Is variable "var" of "tab" fixed to a constant value by its row + * in the tableau? + * If so and if "value" is not NULL, then store this constant value + * in "value". + * + * That is, is it a row variable that only has non-zero coefficients + * for dead columns? + */ +static isl_bool is_constant(struct isl_tab *tab, struct isl_tab_var *var, + isl_int *value) +{ + unsigned off = 2 + tab->M; + isl_mat *mat = tab->mat; + int n; + int row; + int pos; + + if (!var->is_row) + return isl_bool_false; + row = var->index; + if (row_is_big(tab, row)) + return isl_bool_false; + n = tab->n_col - tab->n_dead; + pos = isl_seq_first_non_zero(mat->row[row] + off + tab->n_dead, n); + if (pos != -1) + return isl_bool_false; + if (value) + isl_int_divexact(*value, mat->row[row][1], mat->row[row][0]); + return isl_bool_true; +} + +/* Has the variable "var' of "tab" reached a value that is greater than + * or equal (if sgn > 0) or smaller than or equal (if sgn < 0) to "target"? + * "tmp" has been initialized by the caller and can be used + * to perform local computations. + * + * If the sample value involves the big parameter, then any value + * is reached. + * Otherwise check if n/d >= t, i.e., n >= d * t (if sgn > 0) + * or n/d <= t, i.e., n <= d * t (if sgn < 0). + */ +static int reached(struct isl_tab *tab, struct isl_tab_var *var, int sgn, + isl_int target, isl_int *tmp) +{ + if (row_is_big(tab, var->index)) + return 1; + isl_int_mul(*tmp, tab->mat->row[var->index][0], target); + if (sgn > 0) + return isl_int_ge(tab->mat->row[var->index][1], *tmp); + else + return isl_int_le(tab->mat->row[var->index][1], *tmp); +} + +/* Can variable "var" of "tab" attain the value "target" by + * pivoting up (if sgn > 0) or down (if sgn < 0)? + * If not, then pivot up [down] to the greatest [smallest] + * rational value. + * "tmp" has been initialized by the caller and can be used + * to perform local computations. + * + * If the variable is manifestly unbounded in the desired direction, + * then it can attain any value. + * Otherwise, it can be moved to a row. + * Continue pivoting until the target is reached. + * If no more pivoting can be performed, the maximal [minimal] + * rational value has been reached and the target cannot be reached. + * If the variable would be pivoted into a manifestly unbounded column, + * then the target can be reached. + */ +static isl_bool var_reaches(struct isl_tab *tab, struct isl_tab_var *var, + int sgn, isl_int target, isl_int *tmp) +{ + int row, col; + + if (sgn < 0 && min_is_manifestly_unbounded(tab, var)) + return isl_bool_true; + if (sgn > 0 && max_is_manifestly_unbounded(tab, var)) + return isl_bool_true; + if (to_row(tab, var, sgn) < 0) + return isl_bool_error; + while (!reached(tab, var, sgn, target, tmp)) { + find_pivot(tab, var, var, sgn, &row, &col); + if (row == -1) + return isl_bool_false; + if (row == var->index) + return isl_bool_true; + if (isl_tab_pivot(tab, row, col) < 0) + return isl_bool_error; + } + + return isl_bool_true; +} + +/* Check if variable "var" of "tab" can only attain a single (integer) + * value, and, if so, add an equality constraint to fix the variable + * to this single value and store the result in "target". + * "target" and "tmp" have been initialized by the caller. + * + * Given the current sample value, round it down and check + * whether it is possible to attain a strictly smaller integer value. + * If so, the variable is not restricted to a single integer value. + * Otherwise, the search stops at the smallest rational value. + * Round up this value and check whether it is possible to attain + * a strictly greater integer value. + * If so, the variable is not restricted to a single integer value. + * Otherwise, the search stops at the greatest rational value. + * If rounding down this value yields a value that is different + * from rounding up the smallest rational value, then the variable + * cannot attain any integer value. Mark the tableau empty. + * Otherwise, add an equality constraint that fixes the variable + * to the single integer value found. + */ +static isl_bool detect_constant_with_tmp(struct isl_tab *tab, + struct isl_tab_var *var, isl_int *target, isl_int *tmp) +{ + isl_bool reached; + isl_vec *eq; + int pos; + isl_stat r; + + get_rounded_sample_value(tab, var, -1, target); + isl_int_sub_ui(*target, *target, 1); + reached = var_reaches(tab, var, -1, *target, tmp); + if (reached < 0 || reached) + return isl_bool_not(reached); + get_rounded_sample_value(tab, var, 1, target); + isl_int_add_ui(*target, *target, 1); + reached = var_reaches(tab, var, 1, *target, tmp); + if (reached < 0 || reached) + return isl_bool_not(reached); + get_rounded_sample_value(tab, var, -1, tmp); + isl_int_sub_ui(*target, *target, 1); + if (isl_int_ne(*target, *tmp)) { + if (isl_tab_mark_empty(tab) < 0) + return isl_bool_error; + return isl_bool_false; + } + + if (isl_tab_extend_cons(tab, 1) < 0) + return isl_bool_error; + eq = isl_vec_alloc(isl_tab_get_ctx(tab), 1 + tab->n_var); + if (!eq) + return isl_bool_error; + pos = var - tab->var; + isl_seq_clr(eq->el + 1, tab->n_var); + isl_int_set_si(eq->el[1 + pos], -1); + isl_int_set(eq->el[0], *target); + r = isl_tab_add_eq(tab, eq->el); + isl_vec_free(eq); + + return r < 0 ? isl_bool_error : isl_bool_true; +} + +/* Check if variable "var" of "tab" can only attain a single (integer) + * value, and, if so, add an equality constraint to fix the variable + * to this single value and store the result in "value" (if "value" + * is not NULL). + * + * If the current sample value involves the big parameter, + * then the variable cannot have a fixed integer value. + * If the variable is already fixed to a single value by its row, then + * there is no need to add another equality constraint. + * + * Otherwise, allocate some temporary variables and continue + * with detect_constant_with_tmp. + */ +static isl_bool get_constant(struct isl_tab *tab, struct isl_tab_var *var, + isl_int *value) +{ + isl_int target, tmp; + isl_bool is_cst; + + if (var->is_row && row_is_big(tab, var->index)) + return isl_bool_false; + is_cst = is_constant(tab, var, value); + if (is_cst < 0 || is_cst) + return is_cst; + + if (!value) + isl_int_init(target); + isl_int_init(tmp); + + is_cst = detect_constant_with_tmp(tab, var, + value ? value : &target, &tmp); + + isl_int_clear(tmp); + if (!value) + isl_int_clear(target); + + return is_cst; +} + +/* Check if variable "var" of "tab" can only attain a single (integer) + * value, and, if so, add an equality constraint to fix the variable + * to this single value and store the result in "value" (if "value" + * is not NULL). + * + * For rational tableaus, nothing needs to be done. + */ +isl_bool isl_tab_is_constant(struct isl_tab *tab, int var, isl_int *value) +{ + if (!tab) + return isl_bool_error; + if (var < 0 || var >= tab->n_var) + isl_die(isl_tab_get_ctx(tab), isl_error_invalid, + "position out of bounds", return isl_bool_error); + if (tab->rational) + return isl_bool_false; + + return get_constant(tab, &tab->var[var], value); +} + +/* Check if any of the variables of "tab" can only attain a single (integer) + * value, and, if so, add equality constraints to fix those variables + * to these single values. + * + * For rational tableaus, nothing needs to be done. + */ +isl_stat isl_tab_detect_constants(struct isl_tab *tab) +{ + int i; + + if (!tab) + return isl_stat_error; + if (tab->rational) + return isl_stat_ok; + + for (i = 0; i < tab->n_var; ++i) { + if (get_constant(tab, &tab->var[i], NULL) < 0) + return isl_stat_error; + } + + return isl_stat_ok; +} + +/* Take a snapshot of the tableau that can be restored by a call to + * isl_tab_rollback. + */ +struct isl_tab_undo *isl_tab_snap(struct isl_tab *tab) +{ + if (!tab) + return NULL; + tab->need_undo = 1; + return tab->top; +} + +/* Does "tab" need to keep track of undo information? + * That is, was a snapshot taken that may need to be restored? + */ +isl_bool isl_tab_need_undo(struct isl_tab *tab) +{ + if (!tab) + return isl_bool_error; + + return isl_bool_ok(tab->need_undo); +} + +/* Remove all tracking of undo information from "tab", invalidating + * any snapshots that may have been taken of the tableau. + * Since all snapshots have been invalidated, there is also + * no need to start keeping track of undo information again. + */ +void isl_tab_clear_undo(struct isl_tab *tab) +{ + if (!tab) + return; + + free_undo(tab); + tab->need_undo = 0; +} + +/* Undo the operation performed by isl_tab_relax. + */ +static isl_stat unrelax(struct isl_tab *tab, struct isl_tab_var *var) + WARN_UNUSED; +static isl_stat unrelax(struct isl_tab *tab, struct isl_tab_var *var) +{ + unsigned off = 2 + tab->M; + + if (!var->is_row && !max_is_manifestly_unbounded(tab, var)) + if (to_row(tab, var, 1) < 0) + return isl_stat_error; + + if (var->is_row) { + isl_int_sub(tab->mat->row[var->index][1], + tab->mat->row[var->index][1], tab->mat->row[var->index][0]); + if (var->is_nonneg) { + int sgn = restore_row(tab, var); + isl_assert(tab->mat->ctx, sgn >= 0, + return isl_stat_error); + } + } else { + int i; + + for (i = 0; i < tab->n_row; ++i) { + if (isl_int_is_zero(tab->mat->row[i][off + var->index])) + continue; + isl_int_add(tab->mat->row[i][1], tab->mat->row[i][1], + tab->mat->row[i][off + var->index]); + } + + } + + return isl_stat_ok; +} + +/* Undo the operation performed by isl_tab_unrestrict. + * + * In particular, mark the variable as being non-negative and make + * sure the sample value respects this constraint. + */ +static isl_stat ununrestrict(struct isl_tab *tab, struct isl_tab_var *var) +{ + var->is_nonneg = 1; + + if (var->is_row && restore_row(tab, var) < -1) + return isl_stat_error; + + return isl_stat_ok; +} + +/* Unmark the last redundant row in "tab" as being redundant. + * This undoes part of the modifications performed by isl_tab_mark_redundant. + * In particular, remove the redundant mark and make + * sure the sample value respects the constraint again. + * A variable that is marked non-negative by isl_tab_mark_redundant + * is covered by a separate undo record. + */ +static isl_stat restore_last_redundant(struct isl_tab *tab) +{ + struct isl_tab_var *var; + + if (tab->n_redundant < 1) + isl_die(isl_tab_get_ctx(tab), isl_error_internal, + "no redundant rows", return isl_stat_error); + + var = isl_tab_var_from_row(tab, tab->n_redundant - 1); + var->is_redundant = 0; + tab->n_redundant--; + restore_row(tab, var); + + return isl_stat_ok; +} + +static isl_stat perform_undo_var(struct isl_tab *tab, struct isl_tab_undo *undo) + WARN_UNUSED; +static isl_stat perform_undo_var(struct isl_tab *tab, struct isl_tab_undo *undo) +{ + struct isl_tab_var *var = var_from_index(tab, undo->u.var_index); + switch (undo->type) { + case isl_tab_undo_nonneg: + var->is_nonneg = 0; + break; + case isl_tab_undo_redundant: + if (!var->is_row || var->index != tab->n_redundant - 1) + isl_die(isl_tab_get_ctx(tab), isl_error_internal, + "not undoing last redundant row", + return isl_stat_error); + return restore_last_redundant(tab); + case isl_tab_undo_freeze: + var->frozen = 0; + break; + case isl_tab_undo_zero: + var->is_zero = 0; + if (!var->is_row) + tab->n_dead--; + break; + case isl_tab_undo_allocate: + if (undo->u.var_index >= 0) { + isl_assert(tab->mat->ctx, !var->is_row, + return isl_stat_error); + return drop_col(tab, var->index); + } + if (!var->is_row) { + if (!max_is_manifestly_unbounded(tab, var)) { + if (to_row(tab, var, 1) < 0) + return isl_stat_error; + } else if (!min_is_manifestly_unbounded(tab, var)) { + if (to_row(tab, var, -1) < 0) + return isl_stat_error; + } else + if (to_row(tab, var, 0) < 0) + return isl_stat_error; + } + return drop_row(tab, var->index); + case isl_tab_undo_relax: + return unrelax(tab, var); + case isl_tab_undo_unrestrict: + return ununrestrict(tab, var); + default: + isl_die(tab->mat->ctx, isl_error_internal, + "perform_undo_var called on invalid undo record", + return isl_stat_error); + } + + return isl_stat_ok; +} + +/* Restore all rows that have been marked redundant by isl_tab_mark_redundant + * and that have been preserved in the tableau. + * Note that isl_tab_mark_redundant may also have marked some variables + * as being non-negative before marking them redundant. These need + * to be removed as well as otherwise some constraints could end up + * getting marked redundant with respect to the variable. + */ +isl_stat isl_tab_restore_redundant(struct isl_tab *tab) +{ + if (!tab) + return isl_stat_error; + + if (tab->need_undo) + isl_die(isl_tab_get_ctx(tab), isl_error_invalid, + "manually restoring redundant constraints " + "interferes with undo history", + return isl_stat_error); + + while (tab->n_redundant > 0) { + if (tab->row_var[tab->n_redundant - 1] >= 0) { + struct isl_tab_var *var; + + var = isl_tab_var_from_row(tab, tab->n_redundant - 1); + var->is_nonneg = 0; + } + restore_last_redundant(tab); + } + return isl_stat_ok; +} + +/* Undo the addition of an integer division to the basic map representation + * of "tab" in position "pos". + */ +static isl_stat drop_bmap_div(struct isl_tab *tab, int pos) +{ + int off; + isl_size n_div; + + n_div = isl_basic_map_dim(tab->bmap, isl_dim_div); + if (n_div < 0) + return isl_stat_error; + off = tab->n_var - n_div; + tab->bmap = isl_basic_map_drop_div(tab->bmap, pos - off); + if (!tab->bmap) + return isl_stat_error; + if (tab->samples) { + tab->samples = isl_mat_drop_cols(tab->samples, 1 + pos, 1); + if (!tab->samples) + return isl_stat_error; + } + + return isl_stat_ok; +} + +/* Restore the tableau to the state where the basic variables + * are those in "col_var". + * We first construct a list of variables that are currently in + * the basis, but shouldn't. Then we iterate over all variables + * that should be in the basis and for each one that is currently + * not in the basis, we exchange it with one of the elements of the + * list constructed before. + * We can always find an appropriate variable to pivot with because + * the current basis is mapped to the old basis by a non-singular + * matrix and so we can never end up with a zero row. + */ +static int restore_basis(struct isl_tab *tab, int *col_var) +{ + int i, j; + int n_extra = 0; + int *extra = NULL; /* current columns that contain bad stuff */ + unsigned off = 2 + tab->M; + + extra = isl_alloc_array(tab->mat->ctx, int, tab->n_col); + if (tab->n_col && !extra) + goto error; + for (i = 0; i < tab->n_col; ++i) { + for (j = 0; j < tab->n_col; ++j) + if (tab->col_var[i] == col_var[j]) + break; + if (j < tab->n_col) + continue; + extra[n_extra++] = i; + } + for (i = 0; i < tab->n_col && n_extra > 0; ++i) { + struct isl_tab_var *var; + int row; + + for (j = 0; j < tab->n_col; ++j) + if (col_var[i] == tab->col_var[j]) + break; + if (j < tab->n_col) + continue; + var = var_from_index(tab, col_var[i]); + row = var->index; + for (j = 0; j < n_extra; ++j) + if (!isl_int_is_zero(tab->mat->row[row][off+extra[j]])) + break; + isl_assert(tab->mat->ctx, j < n_extra, goto error); + if (isl_tab_pivot(tab, row, extra[j]) < 0) + goto error; + extra[j] = extra[--n_extra]; + } + + free(extra); + return 0; +error: + free(extra); + return -1; +} + +/* Remove all samples with index n or greater, i.e., those samples + * that were added since we saved this number of samples in + * isl_tab_save_samples. + */ +static void drop_samples_since(struct isl_tab *tab, int n) +{ + int i; + + for (i = tab->n_sample - 1; i >= 0 && tab->n_sample > n; --i) { + if (tab->sample_index[i] < n) + continue; + + if (i != tab->n_sample - 1) { + int t = tab->sample_index[tab->n_sample-1]; + tab->sample_index[tab->n_sample-1] = tab->sample_index[i]; + tab->sample_index[i] = t; + isl_mat_swap_rows(tab->samples, tab->n_sample-1, i); + } + tab->n_sample--; + } +} + +static isl_stat perform_undo(struct isl_tab *tab, struct isl_tab_undo *undo) + WARN_UNUSED; +static isl_stat perform_undo(struct isl_tab *tab, struct isl_tab_undo *undo) +{ + switch (undo->type) { + case isl_tab_undo_rational: + tab->rational = 0; + break; + case isl_tab_undo_empty: + tab->empty = 0; + break; + case isl_tab_undo_nonneg: + case isl_tab_undo_redundant: + case isl_tab_undo_freeze: + case isl_tab_undo_zero: + case isl_tab_undo_allocate: + case isl_tab_undo_relax: + case isl_tab_undo_unrestrict: + return perform_undo_var(tab, undo); + case isl_tab_undo_bmap_eq: + tab->bmap = isl_basic_map_free_equality(tab->bmap, 1); + return tab->bmap ? isl_stat_ok : isl_stat_error; + case isl_tab_undo_bmap_ineq: + tab->bmap = isl_basic_map_free_inequality(tab->bmap, 1); + return tab->bmap ? isl_stat_ok : isl_stat_error; + case isl_tab_undo_bmap_div: + return drop_bmap_div(tab, undo->u.var_index); + case isl_tab_undo_saved_basis: + if (restore_basis(tab, undo->u.col_var) < 0) + return isl_stat_error; + break; + case isl_tab_undo_drop_sample: + tab->n_outside--; + break; + case isl_tab_undo_saved_samples: + drop_samples_since(tab, undo->u.n); + break; + case isl_tab_undo_callback: + return undo->u.callback->run(undo->u.callback); + default: + isl_assert(tab->mat->ctx, 0, return isl_stat_error); + } + return isl_stat_ok; +} + +/* Return the tableau to the state it was in when the snapshot "snap" + * was taken. + */ +isl_stat isl_tab_rollback(struct isl_tab *tab, struct isl_tab_undo *snap) +{ + struct isl_tab_undo *undo, *next; + + if (!tab) + return isl_stat_error; + + tab->in_undo = 1; + for (undo = tab->top; undo && undo != &tab->bottom; undo = next) { + next = undo->next; + if (undo == snap) + break; + if (perform_undo(tab, undo) < 0) { + tab->top = undo; + free_undo(tab); + tab->in_undo = 0; + return isl_stat_error; + } + free_undo_record(undo); + } + tab->in_undo = 0; + tab->top = undo; + if (!undo) + return isl_stat_error; + return isl_stat_ok; +} + +/* The given row "row" represents an inequality violated by all + * points in the tableau. Check for some special cases of such + * separating constraints. + * In particular, if the row has been reduced to the constant -1, + * then we know the inequality is adjacent (but opposite) to + * an equality in the tableau. + * If the row has been reduced to r = c*(-1 -r'), with r' an inequality + * of the tableau and c a positive constant, then the inequality + * is adjacent (but opposite) to the inequality r'. + */ +static enum isl_ineq_type separation_type(struct isl_tab *tab, unsigned row) +{ + int pos; + unsigned off = 2 + tab->M; + + if (tab->rational) + return isl_ineq_separate; + + if (!isl_int_is_one(tab->mat->row[row][0])) + return isl_ineq_separate; + + pos = isl_seq_first_non_zero(tab->mat->row[row] + off + tab->n_dead, + tab->n_col - tab->n_dead); + if (pos == -1) { + if (isl_int_is_negone(tab->mat->row[row][1])) + return isl_ineq_adj_eq; + else + return isl_ineq_separate; + } + + if (!isl_int_eq(tab->mat->row[row][1], + tab->mat->row[row][off + tab->n_dead + pos])) + return isl_ineq_separate; + + pos = isl_seq_first_non_zero( + tab->mat->row[row] + off + tab->n_dead + pos + 1, + tab->n_col - tab->n_dead - pos - 1); + + return pos == -1 ? isl_ineq_adj_ineq : isl_ineq_separate; +} + +/* Check the effect of inequality "ineq" on the tableau "tab". + * The result may be + * isl_ineq_redundant: satisfied by all points in the tableau + * isl_ineq_separate: satisfied by no point in the tableau + * isl_ineq_cut: satisfied by some by not all points + * isl_ineq_adj_eq: adjacent to an equality + * isl_ineq_adj_ineq: adjacent to an inequality. + */ +enum isl_ineq_type isl_tab_ineq_type(struct isl_tab *tab, isl_int *ineq) +{ + enum isl_ineq_type type = isl_ineq_error; + struct isl_tab_undo *snap = NULL; + int con; + int row; + + if (!tab) + return isl_ineq_error; + + if (isl_tab_extend_cons(tab, 1) < 0) + return isl_ineq_error; + + snap = isl_tab_snap(tab); + + con = isl_tab_add_row(tab, ineq); + if (con < 0) + goto error; + + row = tab->con[con].index; + if (isl_tab_row_is_redundant(tab, row)) + type = isl_ineq_redundant; + else if (isl_int_is_neg(tab->mat->row[row][1]) && + (tab->rational || + isl_int_abs_ge(tab->mat->row[row][1], + tab->mat->row[row][0]))) { + int nonneg = at_least_zero(tab, &tab->con[con]); + if (nonneg < 0) + goto error; + if (nonneg) + type = isl_ineq_cut; + else + type = separation_type(tab, row); + } else { + int red = con_is_redundant(tab, &tab->con[con]); + if (red < 0) + goto error; + if (!red) + type = isl_ineq_cut; + else + type = isl_ineq_redundant; + } + + if (isl_tab_rollback(tab, snap)) + return isl_ineq_error; + return type; +error: + return isl_ineq_error; +} + +isl_stat isl_tab_track_bmap(struct isl_tab *tab, __isl_take isl_basic_map *bmap) +{ + bmap = isl_basic_map_cow(bmap); + if (!tab || !bmap) + goto error; + + if (tab->empty) { + bmap = isl_basic_map_set_to_empty(bmap); + if (!bmap) + goto error; + tab->bmap = bmap; + return isl_stat_ok; + } + + isl_assert(tab->mat->ctx, tab->n_eq == bmap->n_eq, goto error); + isl_assert(tab->mat->ctx, + tab->n_con == bmap->n_eq + bmap->n_ineq, goto error); + + tab->bmap = bmap; + + return isl_stat_ok; +error: + isl_basic_map_free(bmap); + return isl_stat_error; +} + +isl_stat isl_tab_track_bset(struct isl_tab *tab, __isl_take isl_basic_set *bset) +{ + return isl_tab_track_bmap(tab, bset_to_bmap(bset)); +} + +__isl_keep isl_basic_set *isl_tab_peek_bset(struct isl_tab *tab) +{ + if (!tab) + return NULL; + + return bset_from_bmap(tab->bmap); +} + +/* Print information about a tab variable representing a variable or + * a constraint. + * In particular, print its position (row or column) in the tableau and + * an indication of whether it is zero, redundant and/or frozen. + * Note that only constraints can be frozen. + */ +static void print_tab_var(FILE *out, struct isl_tab_var *var) +{ + fprintf(out, "%c%d%s%s", var->is_row ? 'r' : 'c', + var->index, + var->is_zero ? " [=0]" : + var->is_redundant ? " [R]" : "", + var->frozen ? " [F]" : ""); +} + +static void isl_tab_print_internal(__isl_keep struct isl_tab *tab, + FILE *out, int indent) +{ + unsigned r, c; + int i; + + if (!tab) { + fprintf(out, "%*snull tab\n", indent, ""); + return; + } + fprintf(out, "%*sn_redundant: %d, n_dead: %d", indent, "", + tab->n_redundant, tab->n_dead); + if (tab->rational) + fprintf(out, ", rational"); + if (tab->empty) + fprintf(out, ", empty"); + fprintf(out, "\n"); + fprintf(out, "%*s[", indent, ""); + for (i = 0; i < tab->n_var; ++i) { + if (i) + fprintf(out, (i == tab->n_param || + i == tab->n_var - tab->n_div) ? "; " + : ", "); + print_tab_var(out, &tab->var[i]); + } + fprintf(out, "]\n"); + fprintf(out, "%*s[", indent, ""); + for (i = 0; i < tab->n_con; ++i) { + if (i) + fprintf(out, ", "); + print_tab_var(out, &tab->con[i]); + } + fprintf(out, "]\n"); + fprintf(out, "%*s[", indent, ""); + for (i = 0; i < tab->n_row; ++i) { + const char *sign = ""; + if (i) + fprintf(out, ", "); + if (tab->row_sign) { + if (tab->row_sign[i] == isl_tab_row_unknown) + sign = "?"; + else if (tab->row_sign[i] == isl_tab_row_neg) + sign = "-"; + else if (tab->row_sign[i] == isl_tab_row_pos) + sign = "+"; + else + sign = "+-"; + } + fprintf(out, "r%d: %d%s%s", i, tab->row_var[i], + isl_tab_var_from_row(tab, i)->is_nonneg ? " [>=0]" : "", sign); + } + fprintf(out, "]\n"); + fprintf(out, "%*s[", indent, ""); + for (i = 0; i < tab->n_col; ++i) { + if (i) + fprintf(out, ", "); + fprintf(out, "c%d: %d%s", i, tab->col_var[i], + var_from_col(tab, i)->is_nonneg ? " [>=0]" : ""); + } + fprintf(out, "]\n"); + r = tab->mat->n_row; + tab->mat->n_row = tab->n_row; + c = tab->mat->n_col; + tab->mat->n_col = 2 + tab->M + tab->n_col; + isl_mat_print_internal(tab->mat, out, indent); + tab->mat->n_row = r; + tab->mat->n_col = c; + if (tab->bmap) + isl_basic_map_print_internal(tab->bmap, out, indent); +} + +void isl_tab_dump(__isl_keep struct isl_tab *tab) +{ + isl_tab_print_internal(tab, stderr, 0); +} diff --git a/external/mit/isl/dist/isl_tab.h b/external/mit/isl/dist/isl_tab.h new file mode 100644 index 000000000000..a7df7ab4452f --- /dev/null +++ b/external/mit/isl/dist/isl_tab.h @@ -0,0 +1,339 @@ +/* + * 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_TAB_H +#define ISL_TAB_H + +#include "isl_int.h" +#include +#include +#include +#include +#include + +struct isl_tab_var { + int index; + unsigned is_row : 1; + unsigned is_nonneg : 1; + unsigned is_zero : 1; + unsigned is_redundant : 1; + unsigned marked : 1; + unsigned frozen : 1; + unsigned negated : 1; +}; + +enum isl_tab_undo_type { + isl_tab_undo_bottom, + isl_tab_undo_rational, + isl_tab_undo_empty, + isl_tab_undo_nonneg, + isl_tab_undo_redundant, + isl_tab_undo_freeze, + isl_tab_undo_zero, + isl_tab_undo_allocate, + isl_tab_undo_relax, + isl_tab_undo_unrestrict, + isl_tab_undo_bmap_ineq, + isl_tab_undo_bmap_eq, + isl_tab_undo_bmap_div, + isl_tab_undo_saved_basis, + isl_tab_undo_drop_sample, + isl_tab_undo_saved_samples, + isl_tab_undo_callback, +}; + +struct isl_tab_callback { + isl_stat (*run)(struct isl_tab_callback *cb); +}; + +union isl_tab_undo_val { + int var_index; + int *col_var; + int n; + struct isl_tab_callback *callback; +}; + +struct isl_tab_undo { + enum isl_tab_undo_type type; + union isl_tab_undo_val u; + struct isl_tab_undo *next; +}; + +/* The tableau maintains equality relations. + * Each column and each row is associated to a variable or a constraint. + * The "value" of an inequality constraint is the value of the corresponding + * slack variable. + * The "row_var" and "col_var" arrays map column and row indices + * to indices in the "var" and "con" arrays. The elements of these + * arrays maintain extra information about the variables and the constraints. + * Each row expresses the corresponding row variable as an affine expression + * of the column variables. + * The first two columns in the matrix contain the common denominator of + * the row and the numerator of the constant term. + * If "M" is set, then the third column represents the "big parameter". + * The third (M = 0) or fourth (M = 1) column + * in the matrix is called column 0 with respect to the col_var array. + * The sample value of the tableau is the value that assigns zero + * to all the column variables and the constant term of each affine + * expression to the corresponding row variable. + * The operations on the tableau maintain the property that the sample + * value satisfies the non-negativity constraints (usually on the slack + * variables). + * + * The big parameter represents an arbitrarily big (and divisible) + * positive number. If present, then the sign of a row is determined + * lexicographically, with the sign of the big parameter coefficient + * considered first. The big parameter is only used while + * solving PILP problems. + * + * The first n_dead column variables have their values fixed to zero. + * The corresponding tab_vars are flagged "is_zero". + * Some of the rows that have have zero coefficients in all but + * the dead columns are also flagged "is_zero". + * + * The first n_redundant rows correspond to inequality constraints + * that are always satisfied for any value satisfying the non-redundant + * rows. The corresponding tab_vars are flagged "is_redundant". + * A row variable that is flagged "is_zero" is also flagged "is_redundant" + * since the constraint has been reduced to 0 = 0 and is therefore always + * satisfied. + * + * There are "n_var" variables in total. The first "n_param" of these + * are called parameters and the last "n_div" of these are called divs. + * The basic tableau operations makes no distinction between different + * kinds of variables. These special variables are only used while + * solving PILP problems. + * + * Dead columns and redundant rows are detected on the fly. + * However, the basic operations do not ensure that all dead columns + * or all redundant rows are detected. + * isl_tab_detect_implicit_equalities and isl_tab_detect_redundant can be used + * to perform an exhaustive search for dead columns and redundant rows. + * + * The samples matrix contains "n_sample" integer points that have at some + * point been elements satisfying the tableau. The first "n_outside" + * of them no longer satisfy the tableau. They are kept because they + * can be reinstated during rollback when the constraint that cut them + * out is removed. These samples are only maintained for the context + * tableau while solving PILP problems. + * + * If "preserve" is set, then we want to keep all constraints in the + * tableau, even if they turn out to be redundant. + */ +enum isl_tab_row_sign { + isl_tab_row_unknown = 0, + isl_tab_row_pos, + isl_tab_row_neg, + isl_tab_row_any, +}; +struct isl_tab { + struct isl_mat *mat; + + unsigned n_row; + unsigned n_col; + unsigned n_dead; + unsigned n_redundant; + + unsigned n_var; + unsigned n_param; + unsigned n_div; + unsigned max_var; + unsigned n_con; + unsigned n_eq; + unsigned max_con; + struct isl_tab_var *var; + struct isl_tab_var *con; + int *row_var; /* v >= 0 -> var v; v < 0 -> con ~v */ + int *col_var; /* v >= 0 -> var v; v < 0 -> con ~v */ + enum isl_tab_row_sign *row_sign; + + struct isl_tab_undo bottom; + struct isl_tab_undo *top; + + struct isl_vec *dual; + struct isl_basic_map *bmap; + + unsigned n_sample; + unsigned n_outside; + int *sample_index; + struct isl_mat *samples; + + int n_zero; + int n_unbounded; + struct isl_mat *basis; + + int (*conflict)(int con, void *user); + void *conflict_user; + + unsigned strict_redundant : 1; + unsigned need_undo : 1; + unsigned preserve : 1; + unsigned rational : 1; + unsigned empty : 1; + unsigned in_undo : 1; + unsigned M : 1; + unsigned cone : 1; +}; + +struct isl_tab *isl_tab_alloc(struct isl_ctx *ctx, + unsigned n_row, unsigned n_var, unsigned M); +void isl_tab_free(struct isl_tab *tab); + +isl_ctx *isl_tab_get_ctx(struct isl_tab *tab); + +__isl_give struct isl_tab *isl_tab_from_basic_map( + __isl_keep isl_basic_map *bmap, int track); +__isl_give struct isl_tab *isl_tab_from_basic_set( + __isl_keep isl_basic_set *bset, int track); +struct isl_tab *isl_tab_from_recession_cone(__isl_keep isl_basic_set *bset, + int parametric); +isl_bool isl_tab_cone_is_bounded(struct isl_tab *tab); +__isl_give isl_basic_map *isl_basic_map_update_from_tab( + __isl_take isl_basic_map *bmap, struct isl_tab *tab); +__isl_give isl_basic_set *isl_basic_set_update_from_tab( + __isl_take isl_basic_set *bset, struct isl_tab *tab); +int isl_tab_detect_implicit_equalities(struct isl_tab *tab) WARN_UNUSED; +__isl_give isl_basic_map *isl_tab_make_equalities_explicit(struct isl_tab *tab, + __isl_take isl_basic_map *bmap); +int isl_tab_detect_redundant(struct isl_tab *tab) WARN_UNUSED; +isl_stat isl_tab_restore_redundant(struct isl_tab *tab); +#define ISL_TAB_SAVE_DUAL (1 << 0) +enum isl_lp_result isl_tab_min(struct isl_tab *tab, + isl_int *f, isl_int denom, isl_int *opt, isl_int *opt_denom, + unsigned flags) WARN_UNUSED; + +isl_stat isl_tab_add_ineq(struct isl_tab *tab, isl_int *ineq) WARN_UNUSED; +isl_stat isl_tab_add_eq(struct isl_tab *tab, isl_int *eq) WARN_UNUSED; +int isl_tab_add_valid_eq(struct isl_tab *tab, isl_int *eq) WARN_UNUSED; + +int isl_tab_freeze_constraint(struct isl_tab *tab, int con) WARN_UNUSED; + +isl_stat isl_tab_track_bmap(struct isl_tab *tab, __isl_take isl_basic_map *bmap) + WARN_UNUSED; +isl_stat isl_tab_track_bset(struct isl_tab *tab, __isl_take isl_basic_set *bset) + WARN_UNUSED; +__isl_keep isl_basic_set *isl_tab_peek_bset(struct isl_tab *tab); + +int isl_tab_is_equality(struct isl_tab *tab, int con); +int isl_tab_is_redundant(struct isl_tab *tab, int con); + +int isl_tab_sample_is_integer(struct isl_tab *tab); +__isl_give isl_vec *isl_tab_get_sample_value(struct isl_tab *tab); + +enum isl_ineq_type { + isl_ineq_error = -1, + isl_ineq_redundant, + isl_ineq_separate, + isl_ineq_cut, + isl_ineq_adj_eq, + isl_ineq_adj_ineq, +}; + +enum isl_ineq_type isl_tab_ineq_type(struct isl_tab *tab, isl_int *ineq); + +struct isl_tab_undo *isl_tab_snap(struct isl_tab *tab); +isl_stat isl_tab_rollback(struct isl_tab *tab, struct isl_tab_undo *snap) WARN_UNUSED; +isl_bool isl_tab_need_undo(struct isl_tab *tab); +void isl_tab_clear_undo(struct isl_tab *tab); + +int isl_tab_relax(struct isl_tab *tab, int con) WARN_UNUSED; +int isl_tab_select_facet(struct isl_tab *tab, int con) WARN_UNUSED; +int isl_tab_unrestrict(struct isl_tab *tab, int con) WARN_UNUSED; + +void isl_tab_dump(__isl_keep struct isl_tab *tab); + +/* Compute maximum instead of minimum. */ +#define ISL_OPT_MAX (1 << 0) +/* Compute full instead of partial optimum; also, domain argument is NULL. */ +#define ISL_OPT_FULL (1 << 1) +/* Result should be free of (unknown) quantified variables. */ +#define ISL_OPT_QE (1 << 2) +__isl_give isl_map *isl_tab_basic_map_partial_lexopt( + __isl_take isl_basic_map *bmap, __isl_take isl_basic_set *dom, + __isl_give isl_set **empty, unsigned flags); +__isl_give isl_pw_multi_aff *isl_tab_basic_map_partial_lexopt_pw_multi_aff( + __isl_take isl_basic_map *bmap, __isl_take isl_basic_set *dom, + __isl_give isl_set **empty, unsigned flags); + +/* An isl_trivial_region represents a non-triviality region. + * The region is trivial if applying "trivial" to a given sequence + * of variables results in a zero vector. + * pos is the location (starting at 0) of the first variable in the sequence. + */ +struct isl_trivial_region { + int pos; + isl_mat *trivial; +}; + +__isl_give isl_vec *isl_tab_basic_set_non_trivial_lexmin( + __isl_take isl_basic_set *bset, int n_op, int n_region, + struct isl_trivial_region *region, + int (*conflict)(int con, void *user), void *user); + +struct isl_tab_lexmin; +typedef struct isl_tab_lexmin isl_tab_lexmin; + +__isl_give isl_tab_lexmin *isl_tab_lexmin_from_basic_set( + __isl_take isl_basic_set *bset); +int isl_tab_lexmin_dim(__isl_keep isl_tab_lexmin *tl); +__isl_give isl_tab_lexmin *isl_tab_lexmin_add_eq(__isl_take isl_tab_lexmin *tl, + isl_int *eq); +__isl_give isl_tab_lexmin *isl_tab_lexmin_cut_to_integer( + __isl_take isl_tab_lexmin *tl); +__isl_give isl_vec *isl_tab_lexmin_get_solution(__isl_keep isl_tab_lexmin *tl); +__isl_null isl_tab_lexmin *isl_tab_lexmin_free(__isl_take isl_tab_lexmin *tl); + +/* private */ + +struct isl_tab_var *isl_tab_var_from_row(struct isl_tab *tab, int i); +int isl_tab_mark_redundant(struct isl_tab *tab, int row) WARN_UNUSED; +int isl_tab_mark_rational(struct isl_tab *tab) WARN_UNUSED; +isl_stat isl_tab_mark_empty(struct isl_tab *tab) WARN_UNUSED; +struct isl_tab *isl_tab_dup(struct isl_tab *tab); +struct isl_tab *isl_tab_product(struct isl_tab *tab1, struct isl_tab *tab2); +int isl_tab_extend_cons(struct isl_tab *tab, unsigned n_new) WARN_UNUSED; +int isl_tab_allocate_con(struct isl_tab *tab) WARN_UNUSED; +int isl_tab_extend_vars(struct isl_tab *tab, unsigned n_new) WARN_UNUSED; +int isl_tab_insert_var(struct isl_tab *tab, int pos) WARN_UNUSED; +int isl_tab_pivot(struct isl_tab *tab, int row, int col) WARN_UNUSED; +int isl_tab_add_row(struct isl_tab *tab, isl_int *line) WARN_UNUSED; +int isl_tab_row_is_redundant(struct isl_tab *tab, int row); +int isl_tab_min_at_most_neg_one(struct isl_tab *tab, struct isl_tab_var *var); +int isl_tab_sign_of_max(struct isl_tab *tab, int con); +int isl_tab_kill_col(struct isl_tab *tab, int col) WARN_UNUSED; + +isl_stat isl_tab_push(struct isl_tab *tab, enum isl_tab_undo_type type) + WARN_UNUSED; +isl_stat isl_tab_push_var(struct isl_tab *tab, + enum isl_tab_undo_type type, struct isl_tab_var *var) WARN_UNUSED; +isl_stat isl_tab_push_basis(struct isl_tab *tab) WARN_UNUSED; + +struct isl_tab *isl_tab_init_samples(struct isl_tab *tab) WARN_UNUSED; +int isl_tab_add_sample(struct isl_tab *tab, + __isl_take isl_vec *sample) WARN_UNUSED; +struct isl_tab *isl_tab_drop_sample(struct isl_tab *tab, int s); +isl_stat isl_tab_save_samples(struct isl_tab *tab) WARN_UNUSED; + +struct isl_tab *isl_tab_detect_equalities(struct isl_tab *tab, + struct isl_tab *tab_cone) WARN_UNUSED; +isl_bool isl_tab_is_constant(struct isl_tab *tab, int var, isl_int *value); +isl_stat isl_tab_detect_constants(struct isl_tab *tab); + +isl_stat isl_tab_push_callback(struct isl_tab *tab, + struct isl_tab_callback *callback) WARN_UNUSED; + +int isl_tab_insert_div(struct isl_tab *tab, int pos, __isl_keep isl_vec *div, + isl_stat (*add_ineq)(void *user, isl_int *), void *user); +int isl_tab_add_div(struct isl_tab *tab, __isl_keep isl_vec *div); + +int isl_tab_shift_var(struct isl_tab *tab, int pos, isl_int shift) WARN_UNUSED; + +isl_stat isl_tab_swap_constraints(struct isl_tab *tab, int con1, int con2); + +#endif diff --git a/external/mit/isl/dist/isl_tab_lexopt_templ.c b/external/mit/isl/dist/isl_tab_lexopt_templ.c new file mode 100644 index 000000000000..45eba10631c5 --- /dev/null +++ b/external/mit/isl/dist/isl_tab_lexopt_templ.c @@ -0,0 +1,235 @@ +/* + * Copyright 2008-2009 Katholieke Universiteit Leuven + * Copyright 2010 INRIA Saclay + * Copyright 2011 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 + */ + +#define xSF(TYPE,SUFFIX) TYPE ## SUFFIX +#define SF(TYPE,SUFFIX) xSF(TYPE,SUFFIX) + +/* Given a basic map with at least two parallel constraints (as found + * by the function parallel_constraints), first look for more constraints + * parallel to the two constraint and replace the found list of parallel + * constraints by a single constraint with as "input" part the minimum + * of the input parts of the list of constraints. Then, recursively call + * basic_map_partial_lexopt (possibly finding more parallel constraints) + * and plug in the definition of the minimum in the result. + * + * As in parallel_constraints, only inequality constraints that only + * involve input variables that do not occur in any other inequality + * constraints are considered. + * + * More specifically, given a set of constraints + * + * a x + b_i(p) >= 0 + * + * Replace this set by a single constraint + * + * a x + u >= 0 + * + * with u a new parameter with constraints + * + * u <= b_i(p) + * + * Any solution to the new system is also a solution for the original system + * since + * + * a x >= -u >= -b_i(p) + * + * Moreover, m = min_i(b_i(p)) satisfies the constraints on u and can + * therefore be plugged into the solution. + */ +static TYPE *SF(basic_map_partial_lexopt_symm,SUFFIX)( + __isl_take isl_basic_map *bmap, __isl_take isl_basic_set *dom, + __isl_give isl_set **empty, int max, int first, int second) +{ + int i, n, k; + int *list = NULL; + isl_size bmap_in, bmap_param, bmap_all; + unsigned n_in, n_out, n_div; + isl_ctx *ctx; + isl_vec *var = NULL; + isl_mat *cst = NULL; + isl_space *map_space, *set_space; + + map_space = isl_basic_map_get_space(bmap); + set_space = empty ? isl_basic_set_get_space(dom) : NULL; + + bmap_in = isl_basic_map_dim(bmap, isl_dim_in); + bmap_param = isl_basic_map_dim(bmap, isl_dim_param); + bmap_all = isl_basic_map_dim(bmap, isl_dim_all); + if (bmap_in < 0 || bmap_param < 0 || bmap_all < 0) + goto error; + n_in = bmap_param + bmap_in; + n_out = bmap_all - n_in; + + ctx = isl_basic_map_get_ctx(bmap); + list = isl_alloc_array(ctx, int, bmap->n_ineq); + var = isl_vec_alloc(ctx, n_out); + if ((bmap->n_ineq && !list) || (n_out && !var)) + goto error; + + list[0] = first; + list[1] = second; + isl_seq_cpy(var->el, bmap->ineq[first] + 1 + n_in, n_out); + for (i = second + 1, n = 2; i < bmap->n_ineq; ++i) { + if (isl_seq_eq(var->el, bmap->ineq[i] + 1 + n_in, n_out) && + all_single_occurrence(bmap, i, n_in)) + list[n++] = i; + } + + cst = isl_mat_alloc(ctx, n, 1 + n_in); + if (!cst) + goto error; + + for (i = 0; i < n; ++i) + isl_seq_cpy(cst->row[i], bmap->ineq[list[i]], 1 + n_in); + + bmap = isl_basic_map_cow(bmap); + if (!bmap) + goto error; + for (i = n - 1; i >= 0; --i) + if (isl_basic_map_drop_inequality(bmap, list[i]) < 0) + goto error; + + bmap = isl_basic_map_add_dims(bmap, isl_dim_in, 1); + bmap = isl_basic_map_extend_constraints(bmap, 0, 1); + k = isl_basic_map_alloc_inequality(bmap); + if (k < 0) + goto error; + isl_seq_clr(bmap->ineq[k], 1 + n_in); + isl_int_set_si(bmap->ineq[k][1 + n_in], 1); + isl_seq_cpy(bmap->ineq[k] + 1 + n_in + 1, var->el, n_out); + bmap = isl_basic_map_finalize(bmap); + + n_div = isl_basic_set_dim(dom, isl_dim_div); + dom = isl_basic_set_add_dims(dom, isl_dim_set, 1); + dom = isl_basic_set_extend_constraints(dom, 0, n); + for (i = 0; i < n; ++i) { + k = isl_basic_set_alloc_inequality(dom); + if (k < 0) + goto error; + isl_seq_cpy(dom->ineq[k], cst->row[i], 1 + n_in); + isl_int_set_si(dom->ineq[k][1 + n_in], -1); + isl_seq_clr(dom->ineq[k] + 1 + n_in + 1, n_div); + } + + isl_vec_free(var); + free(list); + + return SF(basic_map_partial_lexopt_symm_core,SUFFIX)(bmap, dom, empty, + max, cst, map_space, set_space); +error: + isl_space_free(map_space); + isl_space_free(set_space); + isl_mat_free(cst); + isl_vec_free(var); + free(list); + isl_basic_set_free(dom); + isl_basic_map_free(bmap); + return NULL; +} + +/* Recursive part of isl_tab_basic_map_partial_lexopt*, after detecting + * equalities and removing redundant constraints. + * + * We first check if there are any parallel constraints (left). + * If not, we are in the base case. + * If there are parallel constraints, we replace them by a single + * constraint in basic_map_partial_lexopt_symm_pma and then call + * this function recursively to look for more parallel constraints. + */ +static __isl_give TYPE *SF(basic_map_partial_lexopt,SUFFIX)( + __isl_take isl_basic_map *bmap, __isl_take isl_basic_set *dom, + __isl_give isl_set **empty, int max) +{ + isl_bool par = isl_bool_false; + int first, second; + + if (!bmap) + goto error; + + if (bmap->ctx->opt->pip_symmetry) + par = parallel_constraints(bmap, &first, &second); + if (par < 0) + goto error; + if (!par) + return SF(basic_map_partial_lexopt_base,SUFFIX)(bmap, dom, + empty, max); + + return SF(basic_map_partial_lexopt_symm,SUFFIX)(bmap, dom, empty, max, + first, second); +error: + isl_basic_set_free(dom); + isl_basic_map_free(bmap); + return NULL; +} + +/* Compute the lexicographic minimum (or maximum if "flags" includes + * ISL_OPT_MAX) of "bmap" over the domain "dom" and return the result as + * either a map or a piecewise multi-affine expression depending on TYPE. + * If "empty" is not NULL, then *empty is assigned a set that + * contains those parts of the domain where there is no solution. + * If "flags" includes ISL_OPT_FULL, then "dom" is NULL and the optimum + * should be computed over the domain of "bmap". "empty" is also NULL + * in this case. + * If "bmap" is marked as rational (ISL_BASIC_MAP_RATIONAL), + * then we compute the rational optimum. Otherwise, we compute + * the integral optimum. + * + * We perform some preprocessing. As the PILP solver does not + * handle implicit equalities very well, we first make sure all + * the equalities are explicitly available. + * + * We also add context constraints to the basic map and remove + * redundant constraints. This is only needed because of the + * way we handle simple symmetries. In particular, we currently look + * for symmetries on the constraints, before we set up the main tableau. + * It is then no good to look for symmetries on possibly redundant constraints. + * If the domain was extracted from the basic map, then there is + * no need to add back those constraints again. + */ +__isl_give TYPE *SF(isl_tab_basic_map_partial_lexopt,SUFFIX)( + __isl_take isl_basic_map *bmap, __isl_take isl_basic_set *dom, + __isl_give isl_set **empty, unsigned flags) +{ + int max, full; + isl_bool compatible; + + if (empty) + *empty = NULL; + + full = ISL_FL_ISSET(flags, ISL_OPT_FULL); + if (full) + dom = extract_domain(bmap, flags); + compatible = isl_basic_map_compatible_domain(bmap, dom); + if (compatible < 0) + goto error; + if (!compatible) + isl_die(isl_basic_map_get_ctx(bmap), isl_error_invalid, + "domain does not match input", goto error); + + max = ISL_FL_ISSET(flags, ISL_OPT_MAX); + if (isl_basic_set_dim(dom, isl_dim_all) == 0) + return SF(basic_map_partial_lexopt,SUFFIX)(bmap, dom, empty, + max); + + if (!full) + bmap = isl_basic_map_intersect_domain(bmap, + isl_basic_set_copy(dom)); + bmap = isl_basic_map_detect_equalities(bmap); + bmap = isl_basic_map_remove_redundancies(bmap); + + return SF(basic_map_partial_lexopt,SUFFIX)(bmap, dom, empty, max); +error: + isl_basic_set_free(dom); + isl_basic_map_free(bmap); + return NULL; +} diff --git a/external/mit/isl/dist/isl_tab_pip.c b/external/mit/isl/dist/isl_tab_pip.c new file mode 100644 index 000000000000..c03e51fb93b2 --- /dev/null +++ b/external/mit/isl/dist/isl_tab_pip.c @@ -0,0 +1,6037 @@ +/* + * Copyright 2008-2009 Katholieke Universiteit Leuven + * Copyright 2010 INRIA Saclay + * Copyright 2016-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 + */ + +#include +#include "isl_map_private.h" +#include +#include "isl_tab.h" +#include "isl_sample.h" +#include +#include +#include +#include +#include +#include + +#include + +/* + * The implementation of parametric integer linear programming in this file + * was inspired by the paper "Parametric Integer Programming" and the + * report "Solving systems of affine (in)equalities" by Paul Feautrier + * (and others). + * + * The strategy used for obtaining a feasible solution is different + * from the one used in isl_tab.c. In particular, in isl_tab.c, + * upon finding a constraint that is not yet satisfied, we pivot + * in a row that increases the constant term of the row holding the + * constraint, making sure the sample solution remains feasible + * for all the constraints it already satisfied. + * Here, we always pivot in the row holding the constraint, + * choosing a column that induces the lexicographically smallest + * increment to the sample solution. + * + * By starting out from a sample value that is lexicographically + * smaller than any integer point in the problem space, the first + * feasible integer sample point we find will also be the lexicographically + * smallest. If all variables can be assumed to be non-negative, + * then the initial sample value may be chosen equal to zero. + * However, we will not make this assumption. Instead, we apply + * the "big parameter" trick. Any variable x is then not directly + * used in the tableau, but instead it is represented by another + * variable x' = M + x, where M is an arbitrarily large (positive) + * value. x' is therefore always non-negative, whatever the value of x. + * Taking as initial sample value x' = 0 corresponds to x = -M, + * which is always smaller than any possible value of x. + * + * The big parameter trick is used in the main tableau and + * also in the context tableau if isl_context_lex is used. + * In this case, each tableaus has its own big parameter. + * Before doing any real work, we check if all the parameters + * happen to be non-negative. If so, we drop the column corresponding + * to M from the initial context tableau. + * If isl_context_gbr is used, then the big parameter trick is only + * used in the main tableau. + */ + +struct isl_context; +struct isl_context_op { + /* detect nonnegative parameters in context and mark them in tab */ + struct isl_tab *(*detect_nonnegative_parameters)( + struct isl_context *context, struct isl_tab *tab); + /* return temporary reference to basic set representation of context */ + struct isl_basic_set *(*peek_basic_set)(struct isl_context *context); + /* return temporary reference to tableau representation of context */ + struct isl_tab *(*peek_tab)(struct isl_context *context); + /* add equality; check is 1 if eq may not be valid; + * update is 1 if we may want to call ineq_sign on context later. + */ + void (*add_eq)(struct isl_context *context, isl_int *eq, + int check, int update); + /* add inequality; check is 1 if ineq may not be valid; + * update is 1 if we may want to call ineq_sign on context later. + */ + void (*add_ineq)(struct isl_context *context, isl_int *ineq, + int check, int update); + /* check sign of ineq based on previous information. + * strict is 1 if saturation should be treated as a positive sign. + */ + enum isl_tab_row_sign (*ineq_sign)(struct isl_context *context, + isl_int *ineq, int strict); + /* check if inequality maintains feasibility */ + int (*test_ineq)(struct isl_context *context, isl_int *ineq); + /* return index of a div that corresponds to "div" */ + int (*get_div)(struct isl_context *context, struct isl_tab *tab, + struct isl_vec *div); + /* insert div "div" to context at "pos" and return non-negativity */ + isl_bool (*insert_div)(struct isl_context *context, int pos, + __isl_keep isl_vec *div); + int (*detect_equalities)(struct isl_context *context, + struct isl_tab *tab); + /* return row index of "best" split */ + int (*best_split)(struct isl_context *context, struct isl_tab *tab); + /* check if context has already been determined to be empty */ + int (*is_empty)(struct isl_context *context); + /* check if context is still usable */ + int (*is_ok)(struct isl_context *context); + /* save a copy/snapshot of context */ + void *(*save)(struct isl_context *context); + /* restore saved context */ + void (*restore)(struct isl_context *context, void *); + /* discard saved context */ + void (*discard)(void *); + /* invalidate context */ + void (*invalidate)(struct isl_context *context); + /* free context */ + __isl_null struct isl_context *(*free)(struct isl_context *context); +}; + +/* Shared parts of context representation. + * + * "n_unknown" is the number of final unknown integer divisions + * in the input domain. + */ +struct isl_context { + struct isl_context_op *op; + int n_unknown; +}; + +struct isl_context_lex { + struct isl_context context; + struct isl_tab *tab; +}; + +/* A stack (linked list) of solutions of subtrees of the search space. + * + * "ma" describes the solution as a function of "dom". + * In particular, the domain space of "ma" is equal to the space of "dom". + * + * If "ma" is NULL, then there is no solution on "dom". + */ +struct isl_partial_sol { + int level; + struct isl_basic_set *dom; + isl_multi_aff *ma; + + struct isl_partial_sol *next; +}; + +struct isl_sol; +struct isl_sol_callback { + struct isl_tab_callback callback; + struct isl_sol *sol; +}; + +/* isl_sol is an interface for constructing a solution to + * a parametric integer linear programming problem. + * Every time the algorithm reaches a state where a solution + * can be read off from the tableau, the function "add" is called + * on the isl_sol passed to find_solutions_main. In a state where + * the tableau is empty, "add_empty" is called instead. + * "free" is called to free the implementation specific fields, if any. + * + * "error" is set if some error has occurred. This flag invalidates + * the remainder of the data structure. + * If "rational" is set, then a rational optimization is being performed. + * "level" is the current level in the tree with nodes for each + * split in the context. + * If "max" is set, then a maximization problem is being solved, rather than + * a minimization problem, which means that the variables in the + * tableau have value "M - x" rather than "M + x". + * "n_out" is the number of output dimensions in the input. + * "space" is the space in which the solution (and also the input) lives. + * + * The context tableau is owned by isl_sol and is updated incrementally. + * + * There are currently two implementations of this interface, + * isl_sol_map, which simply collects the solutions in an isl_map + * and (optionally) the parts of the context where there is no solution + * in an isl_set, and + * isl_sol_pma, which collects an isl_pw_multi_aff instead. + */ +struct isl_sol { + int error; + int rational; + int level; + int max; + isl_size n_out; + isl_space *space; + struct isl_context *context; + struct isl_partial_sol *partial; + void (*add)(struct isl_sol *sol, + __isl_take isl_basic_set *dom, __isl_take isl_multi_aff *ma); + void (*add_empty)(struct isl_sol *sol, struct isl_basic_set *bset); + void (*free)(struct isl_sol *sol); + struct isl_sol_callback dec_level; +}; + +static void sol_free(struct isl_sol *sol) +{ + struct isl_partial_sol *partial, *next; + if (!sol) + return; + for (partial = sol->partial; partial; partial = next) { + next = partial->next; + isl_basic_set_free(partial->dom); + isl_multi_aff_free(partial->ma); + free(partial); + } + isl_space_free(sol->space); + if (sol->context) + sol->context->op->free(sol->context); + sol->free(sol); + free(sol); +} + +/* Add equality constraint "eq" to the context of "sol". + * "check" is set if "eq" is not known to be a valid constraint. + * "update" is set if ineq_sign() may still get called on the context. + */ +static void sol_context_add_eq(struct isl_sol *sol, isl_int *eq, int check, + int update) +{ + sol->context->op->add_eq(sol->context, eq, check, update); + if (!sol->context->op->is_ok(sol->context)) + sol->error = 1; +} + +/* Add inequality constraint "ineq" to the context of "sol". + * "check" is set if "ineq" is not known to be a valid constraint. + * "update" is set if ineq_sign() may still get called on the context. + */ +static void sol_context_add_ineq(struct isl_sol *sol, isl_int *ineq, int check, + int update) +{ + if (sol->error) + return; + sol->context->op->add_ineq(sol->context, ineq, check, update); + if (!sol->context->op->is_ok(sol->context)) + sol->error = 1; +} + +/* Push a partial solution represented by a domain and function "ma" + * onto the stack of partial solutions. + * If "ma" is NULL, then "dom" represents a part of the domain + * with no solution. + */ +static void sol_push_sol(struct isl_sol *sol, + __isl_take isl_basic_set *dom, __isl_take isl_multi_aff *ma) +{ + struct isl_partial_sol *partial; + + if (sol->error || !dom) + goto error; + + partial = isl_alloc_type(dom->ctx, struct isl_partial_sol); + if (!partial) + goto error; + + partial->level = sol->level; + partial->dom = dom; + partial->ma = ma; + partial->next = sol->partial; + + sol->partial = partial; + + return; +error: + isl_basic_set_free(dom); + isl_multi_aff_free(ma); + sol->error = 1; +} + +/* Check that the final columns of "M", starting at "first", are zero. + */ +static isl_stat check_final_columns_are_zero(__isl_keep isl_mat *M, + unsigned first) +{ + int i; + isl_size rows, cols; + unsigned n; + + rows = isl_mat_rows(M); + cols = isl_mat_cols(M); + if (rows < 0 || cols < 0) + return isl_stat_error; + n = cols - first; + for (i = 0; i < rows; ++i) + if (isl_seq_first_non_zero(M->row[i] + first, n) != -1) + isl_die(isl_mat_get_ctx(M), isl_error_internal, + "final columns should be zero", + return isl_stat_error); + return isl_stat_ok; +} + +/* Set the affine expressions in "ma" according to the rows in "M", which + * are defined over the local space "ls". + * The matrix "M" may have extra (zero) columns beyond the number + * of variables in "ls". + */ +static __isl_give isl_multi_aff *set_from_affine_matrix( + __isl_take isl_multi_aff *ma, __isl_take isl_local_space *ls, + __isl_take isl_mat *M) +{ + int i; + isl_size dim; + isl_aff *aff; + + dim = isl_local_space_dim(ls, isl_dim_all); + if (!ma || dim < 0 || !M) + goto error; + + if (check_final_columns_are_zero(M, 1 + dim) < 0) + goto error; + for (i = 1; i < M->n_row; ++i) { + aff = isl_aff_alloc(isl_local_space_copy(ls)); + if (aff) { + isl_int_set(aff->v->el[0], M->row[0][0]); + isl_seq_cpy(aff->v->el + 1, M->row[i], 1 + dim); + } + aff = isl_aff_normalize(aff); + ma = isl_multi_aff_set_aff(ma, i - 1, aff); + } + isl_local_space_free(ls); + isl_mat_free(M); + + return ma; +error: + isl_local_space_free(ls); + isl_mat_free(M); + isl_multi_aff_free(ma); + return NULL; +} + +/* Push a partial solution represented by a domain and mapping M + * onto the stack of partial solutions. + * + * The affine matrix "M" maps the dimensions of the context + * to the output variables. Convert it into an isl_multi_aff and + * then call sol_push_sol. + * + * Note that the description of the initial context may have involved + * existentially quantified variables, in which case they also appear + * in "dom". These need to be removed before creating the affine + * expression because an affine expression cannot be defined in terms + * of existentially quantified variables without a known representation. + * Since newly added integer divisions are inserted before these + * existentially quantified variables, they are still in the final + * positions and the corresponding final columns of "M" are zero + * because align_context_divs adds the existentially quantified + * variables of the context to the main tableau without any constraints and + * any equality constraints that are added later on can only serve + * to eliminate these existentially quantified variables. + */ +static void sol_push_sol_mat(struct isl_sol *sol, + __isl_take isl_basic_set *dom, __isl_take isl_mat *M) +{ + isl_local_space *ls; + isl_multi_aff *ma; + isl_size n_div; + int n_known; + + n_div = isl_basic_set_dim(dom, isl_dim_div); + if (n_div < 0) + goto error; + n_known = n_div - sol->context->n_unknown; + + ma = isl_multi_aff_alloc(isl_space_copy(sol->space)); + ls = isl_basic_set_get_local_space(dom); + ls = isl_local_space_drop_dims(ls, isl_dim_div, + n_known, n_div - n_known); + ma = set_from_affine_matrix(ma, ls, M); + + if (!ma) + dom = isl_basic_set_free(dom); + sol_push_sol(sol, dom, ma); + return; +error: + isl_basic_set_free(dom); + isl_mat_free(M); + sol_push_sol(sol, NULL, NULL); +} + +/* Pop one partial solution from the partial solution stack and + * pass it on to sol->add or sol->add_empty. + */ +static void sol_pop_one(struct isl_sol *sol) +{ + struct isl_partial_sol *partial; + + partial = sol->partial; + sol->partial = partial->next; + + if (partial->ma) + sol->add(sol, partial->dom, partial->ma); + else + sol->add_empty(sol, partial->dom); + free(partial); +} + +/* Return a fresh copy of the domain represented by the context tableau. + */ +static struct isl_basic_set *sol_domain(struct isl_sol *sol) +{ + struct isl_basic_set *bset; + + if (sol->error) + return NULL; + + bset = isl_basic_set_dup(sol->context->op->peek_basic_set(sol->context)); + bset = isl_basic_set_update_from_tab(bset, + sol->context->op->peek_tab(sol->context)); + + return bset; +} + +/* Check whether two partial solutions have the same affine expressions. + */ +static isl_bool same_solution(struct isl_partial_sol *s1, + struct isl_partial_sol *s2) +{ + if (!s1->ma != !s2->ma) + return isl_bool_false; + if (!s1->ma) + return isl_bool_true; + + return isl_multi_aff_plain_is_equal(s1->ma, s2->ma); +} + +/* Swap the initial two partial solutions in "sol". + * + * That is, go from + * + * sol->partial = p1; p1->next = p2; p2->next = p3 + * + * to + * + * sol->partial = p2; p2->next = p1; p1->next = p3 + */ +static void swap_initial(struct isl_sol *sol) +{ + struct isl_partial_sol *partial; + + partial = sol->partial; + sol->partial = partial->next; + partial->next = partial->next->next; + sol->partial->next = partial; +} + +/* Combine the initial two partial solution of "sol" into + * a partial solution with the current context domain of "sol" and + * the function description of the second partial solution in the list. + * The level of the new partial solution is set to the current level. + * + * That is, the first two partial solutions (D1,M1) and (D2,M2) are + * replaced by (D,M2), where D is the domain of "sol", which is assumed + * to be the union of D1 and D2, while M1 is assumed to be equal to M2 + * (at least on D1). + */ +static isl_stat combine_initial_into_second(struct isl_sol *sol) +{ + struct isl_partial_sol *partial; + isl_basic_set *bset; + + partial = sol->partial; + + bset = sol_domain(sol); + isl_basic_set_free(partial->next->dom); + partial->next->dom = bset; + partial->next->level = sol->level; + + if (!bset) + return isl_stat_error; + + sol->partial = partial->next; + isl_basic_set_free(partial->dom); + isl_multi_aff_free(partial->ma); + free(partial); + + return isl_stat_ok; +} + +/* Are "ma1" and "ma2" equal to each other on "dom"? + * + * Combine "ma1" and "ma2" with "dom" and check if the results are the same. + * "dom" may have existentially quantified variables. Eliminate them first + * as otherwise they would have to be eliminated twice, in a more complicated + * context. + */ +static isl_bool equal_on_domain(__isl_keep isl_multi_aff *ma1, + __isl_keep isl_multi_aff *ma2, __isl_keep isl_basic_set *dom) +{ + isl_set *set; + isl_pw_multi_aff *pma1, *pma2; + isl_bool equal; + + set = isl_basic_set_compute_divs(isl_basic_set_copy(dom)); + pma1 = isl_pw_multi_aff_alloc(isl_set_copy(set), + isl_multi_aff_copy(ma1)); + pma2 = isl_pw_multi_aff_alloc(set, isl_multi_aff_copy(ma2)); + equal = isl_pw_multi_aff_is_equal(pma1, pma2); + isl_pw_multi_aff_free(pma1); + isl_pw_multi_aff_free(pma2); + + return equal; +} + +/* The initial two partial solutions of "sol" are known to be at + * the same level. + * If they represent the same solution (on different parts of the domain), + * then combine them into a single solution at the current level. + * Otherwise, pop them both. + * + * Even if the two partial solution are not obviously the same, + * one may still be a simplification of the other over its own domain. + * Also check if the two sets of affine functions are equal when + * restricted to one of the domains. If so, combine the two + * using the set of affine functions on the other domain. + * That is, for two partial solutions (D1,M1) and (D2,M2), + * if M1 = M2 on D1, then the pair of partial solutions can + * be replaced by (D1+D2,M2) and similarly when M1 = M2 on D2. + */ +static isl_stat combine_initial_if_equal(struct isl_sol *sol) +{ + struct isl_partial_sol *partial; + isl_bool same; + + partial = sol->partial; + + same = same_solution(partial, partial->next); + if (same < 0) + return isl_stat_error; + if (same) + return combine_initial_into_second(sol); + if (partial->ma && partial->next->ma) { + same = equal_on_domain(partial->ma, partial->next->ma, + partial->dom); + if (same < 0) + return isl_stat_error; + if (same) + return combine_initial_into_second(sol); + same = equal_on_domain(partial->ma, partial->next->ma, + partial->next->dom); + if (same) { + swap_initial(sol); + return combine_initial_into_second(sol); + } + } + + sol_pop_one(sol); + sol_pop_one(sol); + + return isl_stat_ok; +} + +/* Pop all solutions from the partial solution stack that were pushed onto + * the stack at levels that are deeper than the current level. + * If the two topmost elements on the stack have the same level + * and represent the same solution, then their domains are combined. + * This combined domain is the same as the current context domain + * as sol_pop is called each time we move back to a higher level. + * If the outer level (0) has been reached, then all partial solutions + * at the current level are also popped off. + */ +static void sol_pop(struct isl_sol *sol) +{ + struct isl_partial_sol *partial; + + if (sol->error) + return; + + partial = sol->partial; + if (!partial) + return; + + if (partial->level == 0 && sol->level == 0) { + for (partial = sol->partial; partial; partial = sol->partial) + sol_pop_one(sol); + return; + } + + if (partial->level <= sol->level) + return; + + if (partial->next && partial->next->level == partial->level) { + if (combine_initial_if_equal(sol) < 0) + goto error; + } else + sol_pop_one(sol); + + if (sol->level == 0) { + for (partial = sol->partial; partial; partial = sol->partial) + sol_pop_one(sol); + return; + } + + if (0) +error: sol->error = 1; +} + +static void sol_dec_level(struct isl_sol *sol) +{ + if (sol->error) + return; + + sol->level--; + + sol_pop(sol); +} + +static isl_stat sol_dec_level_wrap(struct isl_tab_callback *cb) +{ + struct isl_sol_callback *callback = (struct isl_sol_callback *)cb; + + sol_dec_level(callback->sol); + + return callback->sol->error ? isl_stat_error : isl_stat_ok; +} + +/* Move down to next level and push callback onto context tableau + * to decrease the level again when it gets rolled back across + * the current state. That is, dec_level will be called with + * the context tableau in the same state as it is when inc_level + * is called. + */ +static void sol_inc_level(struct isl_sol *sol) +{ + struct isl_tab *tab; + + if (sol->error) + return; + + sol->level++; + tab = sol->context->op->peek_tab(sol->context); + if (isl_tab_push_callback(tab, &sol->dec_level.callback) < 0) + sol->error = 1; +} + +static void scale_rows(struct isl_mat *mat, isl_int m, int n_row) +{ + int i; + + if (isl_int_is_one(m)) + return; + + for (i = 0; i < n_row; ++i) + isl_seq_scale(mat->row[i], mat->row[i], m, mat->n_col); +} + +/* Add the solution identified by the tableau and the context tableau. + * + * The layout of the variables is as follows. + * tab->n_var is equal to the total number of variables in the input + * map (including divs that were copied from the context) + * + the number of extra divs constructed + * Of these, the first tab->n_param and the last tab->n_div variables + * correspond to the variables in the context, i.e., + * tab->n_param + tab->n_div = context_tab->n_var + * tab->n_param is equal to the number of parameters and input + * dimensions in the input map + * tab->n_div is equal to the number of divs in the context + * + * If there is no solution, then call add_empty with a basic set + * that corresponds to the context tableau. (If add_empty is NULL, + * then do nothing). + * + * If there is a solution, then first construct a matrix that maps + * all dimensions of the context to the output variables, i.e., + * the output dimensions in the input map. + * The divs in the input map (if any) that do not correspond to any + * div in the context do not appear in the solution. + * The algorithm will make sure that they have an integer value, + * but these values themselves are of no interest. + * We have to be careful not to drop or rearrange any divs in the + * context because that would change the meaning of the matrix. + * + * To extract the value of the output variables, it should be noted + * that we always use a big parameter M in the main tableau and so + * the variable stored in this tableau is not an output variable x itself, but + * x' = M + x (in case of minimization) + * or + * x' = M - x (in case of maximization) + * If x' appears in a column, then its optimal value is zero, + * which means that the optimal value of x is an unbounded number + * (-M for minimization and M for maximization). + * We currently assume that the output dimensions in the original map + * are bounded, so this cannot occur. + * Similarly, when x' appears in a row, then the coefficient of M in that + * row is necessarily 1. + * If the row in the tableau represents + * d x' = c + d M + e(y) + * then, in case of minimization, the corresponding row in the matrix + * will be + * a c + a e(y) + * with a d = m, the (updated) common denominator of the matrix. + * In case of maximization, the row will be + * -a c - a e(y) + */ +static void sol_add(struct isl_sol *sol, struct isl_tab *tab) +{ + struct isl_basic_set *bset = NULL; + struct isl_mat *mat = NULL; + unsigned off; + int row; + isl_int m; + + if (sol->error || !tab) + goto error; + + if (tab->empty && !sol->add_empty) + return; + if (sol->context->op->is_empty(sol->context)) + return; + + bset = sol_domain(sol); + + if (tab->empty) { + sol_push_sol(sol, bset, NULL); + return; + } + + off = 2 + tab->M; + + mat = isl_mat_alloc(tab->mat->ctx, 1 + sol->n_out, + 1 + tab->n_param + tab->n_div); + if (!mat) + goto error; + + isl_int_init(m); + + isl_seq_clr(mat->row[0] + 1, mat->n_col - 1); + isl_int_set_si(mat->row[0][0], 1); + for (row = 0; row < sol->n_out; ++row) { + int i = tab->n_param + row; + int r, j; + + isl_seq_clr(mat->row[1 + row], mat->n_col); + if (!tab->var[i].is_row) { + if (tab->M) + isl_die(mat->ctx, isl_error_invalid, + "unbounded optimum", goto error2); + continue; + } + + r = tab->var[i].index; + if (tab->M && + isl_int_ne(tab->mat->row[r][2], tab->mat->row[r][0])) + isl_die(mat->ctx, isl_error_invalid, + "unbounded optimum", goto error2); + isl_int_gcd(m, mat->row[0][0], tab->mat->row[r][0]); + isl_int_divexact(m, tab->mat->row[r][0], m); + scale_rows(mat, m, 1 + row); + isl_int_divexact(m, mat->row[0][0], tab->mat->row[r][0]); + isl_int_mul(mat->row[1 + row][0], m, tab->mat->row[r][1]); + for (j = 0; j < tab->n_param; ++j) { + int col; + if (tab->var[j].is_row) + continue; + col = tab->var[j].index; + isl_int_mul(mat->row[1 + row][1 + j], m, + tab->mat->row[r][off + col]); + } + for (j = 0; j < tab->n_div; ++j) { + int col; + if (tab->var[tab->n_var - tab->n_div+j].is_row) + continue; + col = tab->var[tab->n_var - tab->n_div+j].index; + isl_int_mul(mat->row[1 + row][1 + tab->n_param + j], m, + tab->mat->row[r][off + col]); + } + if (sol->max) + isl_seq_neg(mat->row[1 + row], mat->row[1 + row], + mat->n_col); + } + + isl_int_clear(m); + + sol_push_sol_mat(sol, bset, mat); + return; +error2: + isl_int_clear(m); +error: + isl_basic_set_free(bset); + isl_mat_free(mat); + sol->error = 1; +} + +struct isl_sol_map { + struct isl_sol sol; + struct isl_map *map; + struct isl_set *empty; +}; + +static void sol_map_free(struct isl_sol *sol) +{ + struct isl_sol_map *sol_map = (struct isl_sol_map *) sol; + isl_map_free(sol_map->map); + isl_set_free(sol_map->empty); +} + +/* This function is called for parts of the context where there is + * no solution, with "bset" corresponding to the context tableau. + * Simply add the basic set to the set "empty". + */ +static void sol_map_add_empty(struct isl_sol_map *sol, + struct isl_basic_set *bset) +{ + if (!bset || !sol->empty) + goto error; + + sol->empty = isl_set_grow(sol->empty, 1); + bset = isl_basic_set_simplify(bset); + bset = isl_basic_set_finalize(bset); + sol->empty = isl_set_add_basic_set(sol->empty, isl_basic_set_copy(bset)); + if (!sol->empty) + goto error; + isl_basic_set_free(bset); + return; +error: + isl_basic_set_free(bset); + sol->sol.error = 1; +} + +static void sol_map_add_empty_wrap(struct isl_sol *sol, + struct isl_basic_set *bset) +{ + sol_map_add_empty((struct isl_sol_map *)sol, bset); +} + +/* Given a basic set "dom" that represents the context and a tuple of + * affine expressions "ma" defined over this domain, construct a basic map + * that expresses this function on the domain. + */ +static void sol_map_add(struct isl_sol_map *sol, + __isl_take isl_basic_set *dom, __isl_take isl_multi_aff *ma) +{ + isl_basic_map *bmap; + + if (sol->sol.error || !dom || !ma) + goto error; + + bmap = isl_basic_map_from_multi_aff2(ma, sol->sol.rational); + bmap = isl_basic_map_intersect_domain(bmap, dom); + sol->map = isl_map_grow(sol->map, 1); + sol->map = isl_map_add_basic_map(sol->map, bmap); + if (!sol->map) + sol->sol.error = 1; + return; +error: + isl_basic_set_free(dom); + isl_multi_aff_free(ma); + sol->sol.error = 1; +} + +static void sol_map_add_wrap(struct isl_sol *sol, + __isl_take isl_basic_set *dom, __isl_take isl_multi_aff *ma) +{ + sol_map_add((struct isl_sol_map *)sol, dom, ma); +} + + +/* Store the "parametric constant" of row "row" of tableau "tab" in "line", + * i.e., the constant term and the coefficients of all variables that + * appear in the context tableau. + * Note that the coefficient of the big parameter M is NOT copied. + * The context tableau may not have a big parameter and even when it + * does, it is a different big parameter. + */ +static void get_row_parameter_line(struct isl_tab *tab, int row, isl_int *line) +{ + int i; + unsigned off = 2 + tab->M; + + isl_int_set(line[0], tab->mat->row[row][1]); + for (i = 0; i < tab->n_param; ++i) { + if (tab->var[i].is_row) + isl_int_set_si(line[1 + i], 0); + else { + int col = tab->var[i].index; + isl_int_set(line[1 + i], tab->mat->row[row][off + col]); + } + } + for (i = 0; i < tab->n_div; ++i) { + if (tab->var[tab->n_var - tab->n_div + i].is_row) + isl_int_set_si(line[1 + tab->n_param + i], 0); + else { + int col = tab->var[tab->n_var - tab->n_div + i].index; + isl_int_set(line[1 + tab->n_param + i], + tab->mat->row[row][off + col]); + } + } +} + +/* Check if rows "row1" and "row2" have identical "parametric constants", + * as explained above. + * In this case, we also insist that the coefficients of the big parameter + * be the same as the values of the constants will only be the same + * if these coefficients are also the same. + */ +static int identical_parameter_line(struct isl_tab *tab, int row1, int row2) +{ + int i; + unsigned off = 2 + tab->M; + + if (isl_int_ne(tab->mat->row[row1][1], tab->mat->row[row2][1])) + return 0; + + if (tab->M && isl_int_ne(tab->mat->row[row1][2], + tab->mat->row[row2][2])) + return 0; + + for (i = 0; i < tab->n_param + tab->n_div; ++i) { + int pos = i < tab->n_param ? i : + tab->n_var - tab->n_div + i - tab->n_param; + int col; + + if (tab->var[pos].is_row) + continue; + col = tab->var[pos].index; + if (isl_int_ne(tab->mat->row[row1][off + col], + tab->mat->row[row2][off + col])) + return 0; + } + return 1; +} + +/* Return an inequality that expresses that the "parametric constant" + * should be non-negative. + * This function is only called when the coefficient of the big parameter + * is equal to zero. + */ +static struct isl_vec *get_row_parameter_ineq(struct isl_tab *tab, int row) +{ + struct isl_vec *ineq; + + ineq = isl_vec_alloc(tab->mat->ctx, 1 + tab->n_param + tab->n_div); + if (!ineq) + return NULL; + + get_row_parameter_line(tab, row, ineq->el); + if (ineq) + ineq = isl_vec_normalize(ineq); + + return ineq; +} + +/* Normalize a div expression of the form + * + * [(g*f(x) + c)/(g * m)] + * + * with c the constant term and f(x) the remaining coefficients, to + * + * [(f(x) + [c/g])/m] + */ +static void normalize_div(__isl_keep isl_vec *div) +{ + isl_ctx *ctx = isl_vec_get_ctx(div); + int len = div->size - 2; + + isl_seq_gcd(div->el + 2, len, &ctx->normalize_gcd); + isl_int_gcd(ctx->normalize_gcd, ctx->normalize_gcd, div->el[0]); + + if (isl_int_is_one(ctx->normalize_gcd)) + return; + + isl_int_divexact(div->el[0], div->el[0], ctx->normalize_gcd); + isl_int_fdiv_q(div->el[1], div->el[1], ctx->normalize_gcd); + isl_seq_scale_down(div->el + 2, div->el + 2, ctx->normalize_gcd, len); +} + +/* Return an integer division for use in a parametric cut based + * on the given row. + * In particular, let the parametric constant of the row be + * + * \sum_i a_i y_i + * + * where y_0 = 1, but none of the y_i corresponds to the big parameter M. + * The div returned is equal to + * + * floor(\sum_i {-a_i} y_i) = floor((\sum_i (-a_i mod d) y_i)/d) + */ +static struct isl_vec *get_row_parameter_div(struct isl_tab *tab, int row) +{ + struct isl_vec *div; + + div = isl_vec_alloc(tab->mat->ctx, 1 + 1 + tab->n_param + tab->n_div); + if (!div) + return NULL; + + isl_int_set(div->el[0], tab->mat->row[row][0]); + get_row_parameter_line(tab, row, div->el + 1); + isl_seq_neg(div->el + 1, div->el + 1, div->size - 1); + normalize_div(div); + isl_seq_fdiv_r(div->el + 1, div->el + 1, div->el[0], div->size - 1); + + return div; +} + +/* Return an integer division for use in transferring an integrality constraint + * to the context. + * In particular, let the parametric constant of the row be + * + * \sum_i a_i y_i + * + * where y_0 = 1, but none of the y_i corresponds to the big parameter M. + * The the returned div is equal to + * + * floor(\sum_i {a_i} y_i) = floor((\sum_i (a_i mod d) y_i)/d) + */ +static struct isl_vec *get_row_split_div(struct isl_tab *tab, int row) +{ + struct isl_vec *div; + + div = isl_vec_alloc(tab->mat->ctx, 1 + 1 + tab->n_param + tab->n_div); + if (!div) + return NULL; + + isl_int_set(div->el[0], tab->mat->row[row][0]); + get_row_parameter_line(tab, row, div->el + 1); + normalize_div(div); + isl_seq_fdiv_r(div->el + 1, div->el + 1, div->el[0], div->size - 1); + + return div; +} + +/* Construct and return an inequality that expresses an upper bound + * on the given div. + * In particular, if the div is given by + * + * d = floor(e/m) + * + * then the inequality expresses + * + * m d <= e + */ +static __isl_give isl_vec *ineq_for_div(__isl_keep isl_basic_set *bset, + unsigned div) +{ + isl_size total; + unsigned div_pos; + struct isl_vec *ineq; + + total = isl_basic_set_dim(bset, isl_dim_all); + if (total < 0) + return NULL; + + div_pos = 1 + total - bset->n_div + div; + + ineq = isl_vec_alloc(bset->ctx, 1 + total); + if (!ineq) + return NULL; + + isl_seq_cpy(ineq->el, bset->div[div] + 1, 1 + total); + isl_int_neg(ineq->el[div_pos], bset->div[div][0]); + return ineq; +} + +/* Given a row in the tableau and a div that was created + * using get_row_split_div and that has been constrained to equality, i.e., + * + * d = floor(\sum_i {a_i} y_i) = \sum_i {a_i} y_i + * + * replace the expression "\sum_i {a_i} y_i" in the row by d, + * i.e., we subtract "\sum_i {a_i} y_i" and add 1 d. + * The coefficients of the non-parameters in the tableau have been + * verified to be integral. We can therefore simply replace coefficient b + * by floor(b). For the coefficients of the parameters we have + * floor(a_i) = a_i - {a_i}, while for the other coefficients, we have + * floor(b) = b. + */ +static struct isl_tab *set_row_cst_to_div(struct isl_tab *tab, int row, int div) +{ + isl_seq_fdiv_q(tab->mat->row[row] + 1, tab->mat->row[row] + 1, + tab->mat->row[row][0], 1 + tab->M + tab->n_col); + + isl_int_set_si(tab->mat->row[row][0], 1); + + if (tab->var[tab->n_var - tab->n_div + div].is_row) { + int drow = tab->var[tab->n_var - tab->n_div + div].index; + + isl_assert(tab->mat->ctx, + isl_int_is_one(tab->mat->row[drow][0]), goto error); + isl_seq_combine(tab->mat->row[row] + 1, + tab->mat->ctx->one, tab->mat->row[row] + 1, + tab->mat->ctx->one, tab->mat->row[drow] + 1, + 1 + tab->M + tab->n_col); + } else { + int dcol = tab->var[tab->n_var - tab->n_div + div].index; + + isl_int_add_ui(tab->mat->row[row][2 + tab->M + dcol], + tab->mat->row[row][2 + tab->M + dcol], 1); + } + + return tab; +error: + isl_tab_free(tab); + return NULL; +} + +/* Check if the (parametric) constant of the given row is obviously + * negative, meaning that we don't need to consult the context tableau. + * If there is a big parameter and its coefficient is non-zero, + * then this coefficient determines the outcome. + * Otherwise, we check whether the constant is negative and + * all non-zero coefficients of parameters are negative and + * belong to non-negative parameters. + */ +static int is_obviously_neg(struct isl_tab *tab, int row) +{ + int i; + int col; + unsigned off = 2 + tab->M; + + if (tab->M) { + if (isl_int_is_pos(tab->mat->row[row][2])) + return 0; + if (isl_int_is_neg(tab->mat->row[row][2])) + return 1; + } + + if (isl_int_is_nonneg(tab->mat->row[row][1])) + return 0; + for (i = 0; i < tab->n_param; ++i) { + /* Eliminated parameter */ + if (tab->var[i].is_row) + continue; + col = tab->var[i].index; + if (isl_int_is_zero(tab->mat->row[row][off + col])) + continue; + if (!tab->var[i].is_nonneg) + return 0; + if (isl_int_is_pos(tab->mat->row[row][off + col])) + return 0; + } + for (i = 0; i < tab->n_div; ++i) { + if (tab->var[tab->n_var - tab->n_div + i].is_row) + continue; + col = tab->var[tab->n_var - tab->n_div + i].index; + if (isl_int_is_zero(tab->mat->row[row][off + col])) + continue; + if (!tab->var[tab->n_var - tab->n_div + i].is_nonneg) + return 0; + if (isl_int_is_pos(tab->mat->row[row][off + col])) + return 0; + } + return 1; +} + +/* Check if the (parametric) constant of the given row is obviously + * non-negative, meaning that we don't need to consult the context tableau. + * If there is a big parameter and its coefficient is non-zero, + * then this coefficient determines the outcome. + * Otherwise, we check whether the constant is non-negative and + * all non-zero coefficients of parameters are positive and + * belong to non-negative parameters. + */ +static int is_obviously_nonneg(struct isl_tab *tab, int row) +{ + int i; + int col; + unsigned off = 2 + tab->M; + + if (tab->M) { + if (isl_int_is_pos(tab->mat->row[row][2])) + return 1; + if (isl_int_is_neg(tab->mat->row[row][2])) + return 0; + } + + if (isl_int_is_neg(tab->mat->row[row][1])) + return 0; + for (i = 0; i < tab->n_param; ++i) { + /* Eliminated parameter */ + if (tab->var[i].is_row) + continue; + col = tab->var[i].index; + if (isl_int_is_zero(tab->mat->row[row][off + col])) + continue; + if (!tab->var[i].is_nonneg) + return 0; + if (isl_int_is_neg(tab->mat->row[row][off + col])) + return 0; + } + for (i = 0; i < tab->n_div; ++i) { + if (tab->var[tab->n_var - tab->n_div + i].is_row) + continue; + col = tab->var[tab->n_var - tab->n_div + i].index; + if (isl_int_is_zero(tab->mat->row[row][off + col])) + continue; + if (!tab->var[tab->n_var - tab->n_div + i].is_nonneg) + return 0; + if (isl_int_is_neg(tab->mat->row[row][off + col])) + return 0; + } + return 1; +} + +/* Given a row r and two columns, return the column that would + * lead to the lexicographically smallest increment in the sample + * solution when leaving the basis in favor of the row. + * Pivoting with column c will increment the sample value by a non-negative + * constant times a_{V,c}/a_{r,c}, with a_{V,c} the elements of column c + * corresponding to the non-parametric variables. + * If variable v appears in a column c_v, then a_{v,c} = 1 iff c = c_v, + * with all other entries in this virtual row equal to zero. + * If variable v appears in a row, then a_{v,c} is the element in column c + * of that row. + * + * Let v be the first variable with a_{v,c1}/a_{r,c1} != a_{v,c2}/a_{r,c2}. + * Then if a_{v,c1}/a_{r,c1} < a_{v,c2}/a_{r,c2}, i.e., + * a_{v,c2} a_{r,c1} - a_{v,c1} a_{r,c2} > 0, c1 results in the minimal + * increment. Otherwise, it's c2. + */ +static int lexmin_col_pair(struct isl_tab *tab, + int row, int col1, int col2, isl_int tmp) +{ + int i; + isl_int *tr; + + tr = tab->mat->row[row] + 2 + tab->M; + + for (i = tab->n_param; i < tab->n_var - tab->n_div; ++i) { + int s1, s2; + isl_int *r; + + if (!tab->var[i].is_row) { + if (tab->var[i].index == col1) + return col2; + if (tab->var[i].index == col2) + return col1; + continue; + } + + if (tab->var[i].index == row) + continue; + + r = tab->mat->row[tab->var[i].index] + 2 + tab->M; + s1 = isl_int_sgn(r[col1]); + s2 = isl_int_sgn(r[col2]); + if (s1 == 0 && s2 == 0) + continue; + if (s1 < s2) + return col1; + if (s2 < s1) + return col2; + + isl_int_mul(tmp, r[col2], tr[col1]); + isl_int_submul(tmp, r[col1], tr[col2]); + if (isl_int_is_pos(tmp)) + return col1; + if (isl_int_is_neg(tmp)) + return col2; + } + return -1; +} + +/* Does the index into the tab->var or tab->con array "index" + * correspond to a variable in the context tableau? + * In particular, it needs to be an index into the tab->var array and + * it needs to refer to either one of the first tab->n_param variables or + * one of the last tab->n_div variables. + */ +static int is_parameter_var(struct isl_tab *tab, int index) +{ + if (index < 0) + return 0; + if (index < tab->n_param) + return 1; + if (index >= tab->n_var - tab->n_div) + return 1; + return 0; +} + +/* Does column "col" of "tab" refer to a variable in the context tableau? + */ +static int col_is_parameter_var(struct isl_tab *tab, int col) +{ + return is_parameter_var(tab, tab->col_var[col]); +} + +/* Does row "row" of "tab" refer to a variable in the context tableau? + */ +static int row_is_parameter_var(struct isl_tab *tab, int row) +{ + return is_parameter_var(tab, tab->row_var[row]); +} + +/* Given a row in the tableau, find and return the column that would + * result in the lexicographically smallest, but positive, increment + * in the sample point. + * If there is no such column, then return tab->n_col. + * If anything goes wrong, return -1. + */ +static int lexmin_pivot_col(struct isl_tab *tab, int row) +{ + int j; + int col = tab->n_col; + isl_int *tr; + isl_int tmp; + + tr = tab->mat->row[row] + 2 + tab->M; + + isl_int_init(tmp); + + for (j = tab->n_dead; j < tab->n_col; ++j) { + if (col_is_parameter_var(tab, j)) + continue; + + if (!isl_int_is_pos(tr[j])) + continue; + + if (col == tab->n_col) + col = j; + else + col = lexmin_col_pair(tab, row, col, j, tmp); + isl_assert(tab->mat->ctx, col >= 0, goto error); + } + + isl_int_clear(tmp); + return col; +error: + isl_int_clear(tmp); + return -1; +} + +/* Return the first known violated constraint, i.e., a non-negative + * constraint that currently has an either obviously negative value + * or a previously determined to be negative value. + * + * If any constraint has a negative coefficient for the big parameter, + * if any, then we return one of these first. + */ +static int first_neg(struct isl_tab *tab) +{ + int row; + + if (tab->M) + for (row = tab->n_redundant; row < tab->n_row; ++row) { + if (!isl_tab_var_from_row(tab, row)->is_nonneg) + continue; + if (!isl_int_is_neg(tab->mat->row[row][2])) + continue; + if (tab->row_sign) + tab->row_sign[row] = isl_tab_row_neg; + return row; + } + for (row = tab->n_redundant; row < tab->n_row; ++row) { + if (!isl_tab_var_from_row(tab, row)->is_nonneg) + continue; + if (tab->row_sign) { + if (tab->row_sign[row] == 0 && + is_obviously_neg(tab, row)) + tab->row_sign[row] = isl_tab_row_neg; + if (tab->row_sign[row] != isl_tab_row_neg) + continue; + } else if (!is_obviously_neg(tab, row)) + continue; + return row; + } + return -1; +} + +/* Check whether the invariant that all columns are lexico-positive + * is satisfied. This function is not called from the current code + * but is useful during debugging. + */ +static void check_lexpos(struct isl_tab *tab) __attribute__ ((unused)); +static void check_lexpos(struct isl_tab *tab) +{ + unsigned off = 2 + tab->M; + int col; + int var; + int row; + + for (col = tab->n_dead; col < tab->n_col; ++col) { + if (col_is_parameter_var(tab, col)) + continue; + for (var = tab->n_param; var < tab->n_var - tab->n_div; ++var) { + if (!tab->var[var].is_row) { + if (tab->var[var].index == col) + break; + else + continue; + } + row = tab->var[var].index; + if (isl_int_is_zero(tab->mat->row[row][off + col])) + continue; + if (isl_int_is_pos(tab->mat->row[row][off + col])) + break; + fprintf(stderr, "lexneg column %d (row %d)\n", + col, row); + } + if (var >= tab->n_var - tab->n_div) + fprintf(stderr, "zero column %d\n", col); + } +} + +/* Report to the caller that the given constraint is part of an encountered + * conflict. + */ +static int report_conflicting_constraint(struct isl_tab *tab, int con) +{ + return tab->conflict(con, tab->conflict_user); +} + +/* Given a conflicting row in the tableau, report all constraints + * involved in the row to the caller. That is, the row itself + * (if it represents a constraint) and all constraint columns with + * non-zero (and therefore negative) coefficients. + */ +static int report_conflict(struct isl_tab *tab, int row) +{ + int j; + isl_int *tr; + + if (!tab->conflict) + return 0; + + if (tab->row_var[row] < 0 && + report_conflicting_constraint(tab, ~tab->row_var[row]) < 0) + return -1; + + tr = tab->mat->row[row] + 2 + tab->M; + + for (j = tab->n_dead; j < tab->n_col; ++j) { + if (col_is_parameter_var(tab, j)) + continue; + + if (!isl_int_is_neg(tr[j])) + continue; + + if (tab->col_var[j] < 0 && + report_conflicting_constraint(tab, ~tab->col_var[j]) < 0) + return -1; + } + + return 0; +} + +/* Resolve all known or obviously violated constraints through pivoting. + * In particular, as long as we can find any violated constraint, we + * look for a pivoting column that would result in the lexicographically + * smallest increment in the sample point. If there is no such column + * then the tableau is infeasible. + */ +static int restore_lexmin(struct isl_tab *tab) WARN_UNUSED; +static int restore_lexmin(struct isl_tab *tab) +{ + int row, col; + + if (!tab) + return -1; + if (tab->empty) + return 0; + while ((row = first_neg(tab)) != -1) { + col = lexmin_pivot_col(tab, row); + if (col >= tab->n_col) { + if (report_conflict(tab, row) < 0) + return -1; + if (isl_tab_mark_empty(tab) < 0) + return -1; + return 0; + } + if (col < 0) + return -1; + if (isl_tab_pivot(tab, row, col) < 0) + return -1; + } + return 0; +} + +/* Given a row that represents an equality, look for an appropriate + * pivoting column. + * In particular, if there are any non-zero coefficients among + * the non-parameter variables, then we take the last of these + * variables. Eliminating this variable in terms of the other + * variables and/or parameters does not influence the property + * that all column in the initial tableau are lexicographically + * positive. The row corresponding to the eliminated variable + * will only have non-zero entries below the diagonal of the + * initial tableau. That is, we transform + * + * I I + * 1 into a + * I I + * + * If there is no such non-parameter variable, then we are dealing with + * pure parameter equality and we pick any parameter with coefficient 1 or -1 + * for elimination. This will ensure that the eliminated parameter + * always has an integer value whenever all the other parameters are integral. + * If there is no such parameter then we return -1. + */ +static int last_var_col_or_int_par_col(struct isl_tab *tab, int row) +{ + unsigned off = 2 + tab->M; + int i; + + for (i = tab->n_var - tab->n_div - 1; i >= 0 && i >= tab->n_param; --i) { + int col; + if (tab->var[i].is_row) + continue; + col = tab->var[i].index; + if (col <= tab->n_dead) + continue; + if (!isl_int_is_zero(tab->mat->row[row][off + col])) + return col; + } + for (i = tab->n_dead; i < tab->n_col; ++i) { + if (isl_int_is_one(tab->mat->row[row][off + i])) + return i; + if (isl_int_is_negone(tab->mat->row[row][off + i])) + return i; + } + return -1; +} + +/* Add an equality that is known to be valid to the tableau. + * We first check if we can eliminate a variable or a parameter. + * If not, we add the equality as two inequalities. + * In this case, the equality was a pure parameter equality and there + * is no need to resolve any constraint violations. + * + * This function assumes that at least two more rows and at least + * two more elements in the constraint array are available in the tableau. + */ +static struct isl_tab *add_lexmin_valid_eq(struct isl_tab *tab, isl_int *eq) +{ + int i; + int r; + + if (!tab) + return NULL; + r = isl_tab_add_row(tab, eq); + if (r < 0) + goto error; + + r = tab->con[r].index; + i = last_var_col_or_int_par_col(tab, r); + if (i < 0) { + tab->con[r].is_nonneg = 1; + if (isl_tab_push_var(tab, isl_tab_undo_nonneg, &tab->con[r]) < 0) + goto error; + isl_seq_neg(eq, eq, 1 + tab->n_var); + r = isl_tab_add_row(tab, eq); + if (r < 0) + goto error; + tab->con[r].is_nonneg = 1; + if (isl_tab_push_var(tab, isl_tab_undo_nonneg, &tab->con[r]) < 0) + goto error; + } else { + if (isl_tab_pivot(tab, r, i) < 0) + goto error; + if (isl_tab_kill_col(tab, i) < 0) + goto error; + tab->n_eq++; + } + + return tab; +error: + isl_tab_free(tab); + return NULL; +} + +/* Check if the given row is a pure constant. + */ +static int is_constant(struct isl_tab *tab, int row) +{ + unsigned off = 2 + tab->M; + + return isl_seq_first_non_zero(tab->mat->row[row] + off + tab->n_dead, + tab->n_col - tab->n_dead) == -1; +} + +/* Is the given row a parametric constant? + * That is, does it only involve variables that also appear in the context? + */ +static int is_parametric_constant(struct isl_tab *tab, int row) +{ + unsigned off = 2 + tab->M; + int col; + + for (col = tab->n_dead; col < tab->n_col; ++col) { + if (col_is_parameter_var(tab, col)) + continue; + if (isl_int_is_zero(tab->mat->row[row][off + col])) + continue; + return 0; + } + + return 1; +} + +/* Add an equality that may or may not be valid to the tableau. + * If the resulting row is a pure constant, then it must be zero. + * Otherwise, the resulting tableau is empty. + * + * If the row is not a pure constant, then we add two inequalities, + * each time checking that they can be satisfied. + * In the end we try to use one of the two constraints to eliminate + * a column. + * + * This function assumes that at least two more rows and at least + * two more elements in the constraint array are available in the tableau. + */ +static int add_lexmin_eq(struct isl_tab *tab, isl_int *eq) WARN_UNUSED; +static int add_lexmin_eq(struct isl_tab *tab, isl_int *eq) +{ + int r1, r2; + int row; + struct isl_tab_undo *snap; + + if (!tab) + return -1; + snap = isl_tab_snap(tab); + r1 = isl_tab_add_row(tab, eq); + if (r1 < 0) + return -1; + tab->con[r1].is_nonneg = 1; + if (isl_tab_push_var(tab, isl_tab_undo_nonneg, &tab->con[r1]) < 0) + return -1; + + row = tab->con[r1].index; + if (is_constant(tab, row)) { + if (!isl_int_is_zero(tab->mat->row[row][1]) || + (tab->M && !isl_int_is_zero(tab->mat->row[row][2]))) { + if (isl_tab_mark_empty(tab) < 0) + return -1; + return 0; + } + if (isl_tab_rollback(tab, snap) < 0) + return -1; + return 0; + } + + if (restore_lexmin(tab) < 0) + return -1; + if (tab->empty) + return 0; + + isl_seq_neg(eq, eq, 1 + tab->n_var); + + r2 = isl_tab_add_row(tab, eq); + if (r2 < 0) + return -1; + tab->con[r2].is_nonneg = 1; + if (isl_tab_push_var(tab, isl_tab_undo_nonneg, &tab->con[r2]) < 0) + return -1; + + if (restore_lexmin(tab) < 0) + return -1; + if (tab->empty) + return 0; + + if (!tab->con[r1].is_row) { + if (isl_tab_kill_col(tab, tab->con[r1].index) < 0) + return -1; + } else if (!tab->con[r2].is_row) { + if (isl_tab_kill_col(tab, tab->con[r2].index) < 0) + return -1; + } + + if (tab->bmap) { + tab->bmap = isl_basic_map_add_ineq(tab->bmap, eq); + if (isl_tab_push(tab, isl_tab_undo_bmap_ineq) < 0) + return -1; + isl_seq_neg(eq, eq, 1 + tab->n_var); + tab->bmap = isl_basic_map_add_ineq(tab->bmap, eq); + isl_seq_neg(eq, eq, 1 + tab->n_var); + if (isl_tab_push(tab, isl_tab_undo_bmap_ineq) < 0) + return -1; + if (!tab->bmap) + return -1; + } + + return 0; +} + +/* Add an inequality to the tableau, resolving violations using + * restore_lexmin. + * + * This function assumes that at least one more row and at least + * one more element in the constraint array are available in the tableau. + */ +static struct isl_tab *add_lexmin_ineq(struct isl_tab *tab, isl_int *ineq) +{ + int r; + + if (!tab) + return NULL; + if (tab->bmap) { + tab->bmap = isl_basic_map_add_ineq(tab->bmap, ineq); + if (isl_tab_push(tab, isl_tab_undo_bmap_ineq) < 0) + goto error; + if (!tab->bmap) + goto error; + } + r = isl_tab_add_row(tab, ineq); + if (r < 0) + goto error; + tab->con[r].is_nonneg = 1; + if (isl_tab_push_var(tab, isl_tab_undo_nonneg, &tab->con[r]) < 0) + goto error; + if (isl_tab_row_is_redundant(tab, tab->con[r].index)) { + if (isl_tab_mark_redundant(tab, tab->con[r].index) < 0) + goto error; + return tab; + } + + if (restore_lexmin(tab) < 0) + goto error; + if (!tab->empty && tab->con[r].is_row && + isl_tab_row_is_redundant(tab, tab->con[r].index)) + if (isl_tab_mark_redundant(tab, tab->con[r].index) < 0) + goto error; + return tab; +error: + isl_tab_free(tab); + return NULL; +} + +/* Check if the coefficients of the parameters are all integral. + */ +static int integer_parameter(struct isl_tab *tab, int row) +{ + int i; + int col; + unsigned off = 2 + tab->M; + + for (i = 0; i < tab->n_param; ++i) { + /* Eliminated parameter */ + if (tab->var[i].is_row) + continue; + col = tab->var[i].index; + if (!isl_int_is_divisible_by(tab->mat->row[row][off + col], + tab->mat->row[row][0])) + return 0; + } + for (i = 0; i < tab->n_div; ++i) { + if (tab->var[tab->n_var - tab->n_div + i].is_row) + continue; + col = tab->var[tab->n_var - tab->n_div + i].index; + if (!isl_int_is_divisible_by(tab->mat->row[row][off + col], + tab->mat->row[row][0])) + return 0; + } + return 1; +} + +/* Check if the coefficients of the non-parameter variables are all integral. + */ +static int integer_variable(struct isl_tab *tab, int row) +{ + int i; + unsigned off = 2 + tab->M; + + for (i = tab->n_dead; i < tab->n_col; ++i) { + if (col_is_parameter_var(tab, i)) + continue; + if (!isl_int_is_divisible_by(tab->mat->row[row][off + i], + tab->mat->row[row][0])) + return 0; + } + return 1; +} + +/* Check if the constant term is integral. + */ +static int integer_constant(struct isl_tab *tab, int row) +{ + return isl_int_is_divisible_by(tab->mat->row[row][1], + tab->mat->row[row][0]); +} + +#define I_CST 1 << 0 +#define I_PAR 1 << 1 +#define I_VAR 1 << 2 + +/* Check for next (non-parameter) variable after "var" (first if var == -1) + * that is non-integer and therefore requires a cut and return + * the index of the variable. + * For parametric tableaus, there are three parts in a row, + * the constant, the coefficients of the parameters and the rest. + * For each part, we check whether the coefficients in that part + * are all integral and if so, set the corresponding flag in *f. + * If the constant and the parameter part are integral, then the + * current sample value is integral and no cut is required + * (irrespective of whether the variable part is integral). + */ +static int next_non_integer_var(struct isl_tab *tab, int var, int *f) +{ + var = var < 0 ? tab->n_param : var + 1; + + for (; var < tab->n_var - tab->n_div; ++var) { + int flags = 0; + int row; + if (!tab->var[var].is_row) + continue; + row = tab->var[var].index; + if (integer_constant(tab, row)) + ISL_FL_SET(flags, I_CST); + if (integer_parameter(tab, row)) + ISL_FL_SET(flags, I_PAR); + if (ISL_FL_ISSET(flags, I_CST) && ISL_FL_ISSET(flags, I_PAR)) + continue; + if (integer_variable(tab, row)) + ISL_FL_SET(flags, I_VAR); + *f = flags; + return var; + } + return -1; +} + +/* Check for first (non-parameter) variable that is non-integer and + * therefore requires a cut and return the corresponding row. + * For parametric tableaus, there are three parts in a row, + * the constant, the coefficients of the parameters and the rest. + * For each part, we check whether the coefficients in that part + * are all integral and if so, set the corresponding flag in *f. + * If the constant and the parameter part are integral, then the + * current sample value is integral and no cut is required + * (irrespective of whether the variable part is integral). + */ +static int first_non_integer_row(struct isl_tab *tab, int *f) +{ + int var = next_non_integer_var(tab, -1, f); + + return var < 0 ? -1 : tab->var[var].index; +} + +/* Add a (non-parametric) cut to cut away the non-integral sample + * value of the given row. + * + * If the row is given by + * + * m r = f + \sum_i a_i y_i + * + * then the cut is + * + * c = - {-f/m} + \sum_i {a_i/m} y_i >= 0 + * + * The big parameter, if any, is ignored, since it is assumed to be big + * enough to be divisible by any integer. + * If the tableau is actually a parametric tableau, then this function + * is only called when all coefficients of the parameters are integral. + * The cut therefore has zero coefficients for the parameters. + * + * The current value is known to be negative, so row_sign, if it + * exists, is set accordingly. + * + * Return the row of the cut or -1. + */ +static int add_cut(struct isl_tab *tab, int row) +{ + int i; + int r; + isl_int *r_row; + unsigned off = 2 + tab->M; + + if (isl_tab_extend_cons(tab, 1) < 0) + return -1; + r = isl_tab_allocate_con(tab); + if (r < 0) + return -1; + + r_row = tab->mat->row[tab->con[r].index]; + isl_int_set(r_row[0], tab->mat->row[row][0]); + isl_int_neg(r_row[1], tab->mat->row[row][1]); + isl_int_fdiv_r(r_row[1], r_row[1], tab->mat->row[row][0]); + isl_int_neg(r_row[1], r_row[1]); + if (tab->M) + isl_int_set_si(r_row[2], 0); + for (i = 0; i < tab->n_col; ++i) + isl_int_fdiv_r(r_row[off + i], + tab->mat->row[row][off + i], tab->mat->row[row][0]); + + tab->con[r].is_nonneg = 1; + if (isl_tab_push_var(tab, isl_tab_undo_nonneg, &tab->con[r]) < 0) + return -1; + if (tab->row_sign) + tab->row_sign[tab->con[r].index] = isl_tab_row_neg; + + return tab->con[r].index; +} + +#define CUT_ALL 1 +#define CUT_ONE 0 + +/* Given a non-parametric tableau, add cuts until an integer + * sample point is obtained or until the tableau is determined + * to be integer infeasible. + * As long as there is any non-integer value in the sample point, + * we add appropriate cuts, if possible, for each of these + * non-integer values and then resolve the violated + * cut constraints using restore_lexmin. + * If one of the corresponding rows is equal to an integral + * combination of variables/constraints plus a non-integral constant, + * then there is no way to obtain an integer point and we return + * a tableau that is marked empty. + * The parameter cutting_strategy controls the strategy used when adding cuts + * to remove non-integer points. CUT_ALL adds all possible cuts + * before continuing the search. CUT_ONE adds only one cut at a time. + */ +static struct isl_tab *cut_to_integer_lexmin(struct isl_tab *tab, + int cutting_strategy) +{ + int var; + int row; + int flags; + + if (!tab) + return NULL; + if (tab->empty) + return tab; + + while ((var = next_non_integer_var(tab, -1, &flags)) != -1) { + do { + if (ISL_FL_ISSET(flags, I_VAR)) { + if (isl_tab_mark_empty(tab) < 0) + goto error; + return tab; + } + row = tab->var[var].index; + row = add_cut(tab, row); + if (row < 0) + goto error; + if (cutting_strategy == CUT_ONE) + break; + } while ((var = next_non_integer_var(tab, var, &flags)) != -1); + if (restore_lexmin(tab) < 0) + goto error; + if (tab->empty) + break; + } + return tab; +error: + isl_tab_free(tab); + return NULL; +} + +/* Check whether all the currently active samples also satisfy the inequality + * "ineq" (treated as an equality if eq is set). + * Remove those samples that do not. + */ +static struct isl_tab *check_samples(struct isl_tab *tab, isl_int *ineq, int eq) +{ + int i; + isl_int v; + + if (!tab) + return NULL; + + isl_assert(tab->mat->ctx, tab->bmap, goto error); + isl_assert(tab->mat->ctx, tab->samples, goto error); + isl_assert(tab->mat->ctx, tab->samples->n_col == 1 + tab->n_var, goto error); + + isl_int_init(v); + for (i = tab->n_outside; i < tab->n_sample; ++i) { + int sgn; + isl_seq_inner_product(ineq, tab->samples->row[i], + 1 + tab->n_var, &v); + sgn = isl_int_sgn(v); + if (eq ? (sgn == 0) : (sgn >= 0)) + continue; + tab = isl_tab_drop_sample(tab, i); + if (!tab) + break; + } + isl_int_clear(v); + + return tab; +error: + isl_tab_free(tab); + return NULL; +} + +/* Check whether the sample value of the tableau is finite, + * i.e., either the tableau does not use a big parameter, or + * all values of the variables are equal to the big parameter plus + * some constant. This constant is the actual sample value. + */ +static int sample_is_finite(struct isl_tab *tab) +{ + int i; + + if (!tab->M) + return 1; + + for (i = 0; i < tab->n_var; ++i) { + int row; + if (!tab->var[i].is_row) + return 0; + row = tab->var[i].index; + if (isl_int_ne(tab->mat->row[row][0], tab->mat->row[row][2])) + return 0; + } + return 1; +} + +/* Check if the context tableau of sol has any integer points. + * Leave tab in empty state if no integer point can be found. + * If an integer point can be found and if moreover it is finite, + * then it is added to the list of sample values. + * + * This function is only called when none of the currently active sample + * values satisfies the most recently added constraint. + */ +static struct isl_tab *check_integer_feasible(struct isl_tab *tab) +{ + struct isl_tab_undo *snap; + + if (!tab) + return NULL; + + snap = isl_tab_snap(tab); + if (isl_tab_push_basis(tab) < 0) + goto error; + + tab = cut_to_integer_lexmin(tab, CUT_ALL); + if (!tab) + goto error; + + if (!tab->empty && sample_is_finite(tab)) { + struct isl_vec *sample; + + sample = isl_tab_get_sample_value(tab); + + if (isl_tab_add_sample(tab, sample) < 0) + goto error; + } + + if (!tab->empty && isl_tab_rollback(tab, snap) < 0) + goto error; + + return tab; +error: + isl_tab_free(tab); + return NULL; +} + +/* Check if any of the currently active sample values satisfies + * the inequality "ineq" (an equality if eq is set). + */ +static int tab_has_valid_sample(struct isl_tab *tab, isl_int *ineq, int eq) +{ + int i; + isl_int v; + + if (!tab) + return -1; + + isl_assert(tab->mat->ctx, tab->bmap, return -1); + isl_assert(tab->mat->ctx, tab->samples, return -1); + isl_assert(tab->mat->ctx, tab->samples->n_col == 1 + tab->n_var, return -1); + + isl_int_init(v); + for (i = tab->n_outside; i < tab->n_sample; ++i) { + int sgn; + isl_seq_inner_product(ineq, tab->samples->row[i], + 1 + tab->n_var, &v); + sgn = isl_int_sgn(v); + if (eq ? (sgn == 0) : (sgn >= 0)) + break; + } + isl_int_clear(v); + + return i < tab->n_sample; +} + +/* Insert a div specified by "div" to the tableau "tab" at position "pos" and + * return isl_bool_true if the div is obviously non-negative. + */ +static isl_bool context_tab_insert_div(struct isl_tab *tab, int pos, + __isl_keep isl_vec *div, + isl_stat (*add_ineq)(void *user, isl_int *), void *user) +{ + int i; + int r; + struct isl_mat *samples; + int nonneg; + + r = isl_tab_insert_div(tab, pos, div, add_ineq, user); + if (r < 0) + return isl_bool_error; + nonneg = tab->var[r].is_nonneg; + tab->var[r].frozen = 1; + + samples = isl_mat_extend(tab->samples, + tab->n_sample, 1 + tab->n_var); + tab->samples = samples; + if (!samples) + return isl_bool_error; + for (i = tab->n_outside; i < samples->n_row; ++i) { + isl_seq_inner_product(div->el + 1, samples->row[i], + div->size - 1, &samples->row[i][samples->n_col - 1]); + isl_int_fdiv_q(samples->row[i][samples->n_col - 1], + samples->row[i][samples->n_col - 1], div->el[0]); + } + tab->samples = isl_mat_move_cols(tab->samples, 1 + pos, + 1 + tab->n_var - 1, 1); + if (!tab->samples) + return isl_bool_error; + + return isl_bool_ok(nonneg); +} + +/* Add a div specified by "div" to both the main tableau and + * the context tableau. In case of the main tableau, we only + * need to add an extra div. In the context tableau, we also + * need to express the meaning of the div. + * Return the index of the div or -1 if anything went wrong. + * + * The new integer division is added before any unknown integer + * divisions in the context to ensure that it does not get + * equated to some linear combination involving unknown integer + * divisions. + */ +static int add_div(struct isl_tab *tab, struct isl_context *context, + __isl_keep isl_vec *div) +{ + int r; + int pos; + isl_bool nonneg; + struct isl_tab *context_tab = context->op->peek_tab(context); + + if (!tab || !context_tab) + goto error; + + pos = context_tab->n_var - context->n_unknown; + if ((nonneg = context->op->insert_div(context, pos, div)) < 0) + goto error; + + if (!context->op->is_ok(context)) + goto error; + + pos = tab->n_var - context->n_unknown; + if (isl_tab_extend_vars(tab, 1) < 0) + goto error; + r = isl_tab_insert_var(tab, pos); + if (r < 0) + goto error; + if (nonneg) + tab->var[r].is_nonneg = 1; + tab->var[r].frozen = 1; + tab->n_div++; + + return tab->n_div - 1 - context->n_unknown; +error: + context->op->invalidate(context); + return -1; +} + +/* Return the position of the integer division that is equal to div/denom + * if there is one. Otherwise, return a position beyond the integer divisions. + */ +static int find_div(struct isl_tab *tab, isl_int *div, isl_int denom) +{ + int i; + isl_size total = isl_basic_map_dim(tab->bmap, isl_dim_all); + isl_size n_div; + + n_div = isl_basic_map_dim(tab->bmap, isl_dim_div); + if (total < 0 || n_div < 0) + return -1; + for (i = 0; i < n_div; ++i) { + if (isl_int_ne(tab->bmap->div[i][0], denom)) + continue; + if (!isl_seq_eq(tab->bmap->div[i] + 1, div, 1 + total)) + continue; + return i; + } + return n_div; +} + +/* Return the index of a div that corresponds to "div". + * We first check if we already have such a div and if not, we create one. + */ +static int get_div(struct isl_tab *tab, struct isl_context *context, + struct isl_vec *div) +{ + int d; + struct isl_tab *context_tab = context->op->peek_tab(context); + unsigned n_div; + + if (!context_tab) + return -1; + + n_div = isl_basic_map_dim(context_tab->bmap, isl_dim_div); + d = find_div(context_tab, div->el + 1, div->el[0]); + if (d < 0) + return -1; + if (d < n_div) + return d; + + return add_div(tab, context, div); +} + +/* Add a parametric cut to cut away the non-integral sample value + * of the given row. + * Let a_i be the coefficients of the constant term and the parameters + * and let b_i be the coefficients of the variables or constraints + * in basis of the tableau. + * Let q be the div q = floor(\sum_i {-a_i} y_i). + * + * The cut is expressed as + * + * c = \sum_i -{-a_i} y_i + \sum_i {b_i} x_i + q >= 0 + * + * If q did not already exist in the context tableau, then it is added first. + * If q is in a column of the main tableau then the "+ q" can be accomplished + * by setting the corresponding entry to the denominator of the constraint. + * If q happens to be in a row of the main tableau, then the corresponding + * row needs to be added instead (taking care of the denominators). + * Note that this is very unlikely, but perhaps not entirely impossible. + * + * The current value of the cut is known to be negative (or at least + * non-positive), so row_sign is set accordingly. + * + * Return the row of the cut or -1. + */ +static int add_parametric_cut(struct isl_tab *tab, int row, + struct isl_context *context) +{ + struct isl_vec *div; + int d; + int i; + int r; + isl_int *r_row; + int col; + int n; + unsigned off = 2 + tab->M; + + if (!context) + return -1; + + div = get_row_parameter_div(tab, row); + if (!div) + return -1; + + n = tab->n_div - context->n_unknown; + d = context->op->get_div(context, tab, div); + isl_vec_free(div); + if (d < 0) + return -1; + + if (isl_tab_extend_cons(tab, 1) < 0) + return -1; + r = isl_tab_allocate_con(tab); + if (r < 0) + return -1; + + r_row = tab->mat->row[tab->con[r].index]; + isl_int_set(r_row[0], tab->mat->row[row][0]); + isl_int_neg(r_row[1], tab->mat->row[row][1]); + isl_int_fdiv_r(r_row[1], r_row[1], tab->mat->row[row][0]); + isl_int_neg(r_row[1], r_row[1]); + if (tab->M) + isl_int_set_si(r_row[2], 0); + for (i = 0; i < tab->n_param; ++i) { + if (tab->var[i].is_row) + continue; + col = tab->var[i].index; + isl_int_neg(r_row[off + col], tab->mat->row[row][off + col]); + isl_int_fdiv_r(r_row[off + col], r_row[off + col], + tab->mat->row[row][0]); + isl_int_neg(r_row[off + col], r_row[off + col]); + } + for (i = 0; i < tab->n_div; ++i) { + if (tab->var[tab->n_var - tab->n_div + i].is_row) + continue; + col = tab->var[tab->n_var - tab->n_div + i].index; + isl_int_neg(r_row[off + col], tab->mat->row[row][off + col]); + isl_int_fdiv_r(r_row[off + col], r_row[off + col], + tab->mat->row[row][0]); + isl_int_neg(r_row[off + col], r_row[off + col]); + } + for (i = 0; i < tab->n_col; ++i) { + if (tab->col_var[i] >= 0 && + (tab->col_var[i] < tab->n_param || + tab->col_var[i] >= tab->n_var - tab->n_div)) + continue; + isl_int_fdiv_r(r_row[off + i], + tab->mat->row[row][off + i], tab->mat->row[row][0]); + } + if (tab->var[tab->n_var - tab->n_div + d].is_row) { + isl_int gcd; + int d_row = tab->var[tab->n_var - tab->n_div + d].index; + isl_int_init(gcd); + isl_int_gcd(gcd, tab->mat->row[d_row][0], r_row[0]); + isl_int_divexact(r_row[0], r_row[0], gcd); + isl_int_divexact(gcd, tab->mat->row[d_row][0], gcd); + isl_seq_combine(r_row + 1, gcd, r_row + 1, + r_row[0], tab->mat->row[d_row] + 1, + off - 1 + tab->n_col); + isl_int_mul(r_row[0], r_row[0], tab->mat->row[d_row][0]); + isl_int_clear(gcd); + } else { + col = tab->var[tab->n_var - tab->n_div + d].index; + isl_int_set(r_row[off + col], tab->mat->row[row][0]); + } + + tab->con[r].is_nonneg = 1; + if (isl_tab_push_var(tab, isl_tab_undo_nonneg, &tab->con[r]) < 0) + return -1; + if (tab->row_sign) + tab->row_sign[tab->con[r].index] = isl_tab_row_neg; + + row = tab->con[r].index; + + if (d >= n && context->op->detect_equalities(context, tab) < 0) + return -1; + + return row; +} + +/* Construct a tableau for bmap that can be used for computing + * the lexicographic minimum (or maximum) of bmap. + * If not NULL, then dom is the domain where the minimum + * should be computed. In this case, we set up a parametric + * tableau with row signs (initialized to "unknown"). + * If M is set, then the tableau will use a big parameter. + * If max is set, then a maximum should be computed instead of a minimum. + * This means that for each variable x, the tableau will contain the variable + * x' = M - x, rather than x' = M + x. This in turn means that the coefficient + * of the variables in all constraints are negated prior to adding them + * to the tableau. + */ +static __isl_give struct isl_tab *tab_for_lexmin(__isl_keep isl_basic_map *bmap, + __isl_keep isl_basic_set *dom, unsigned M, int max) +{ + int i; + struct isl_tab *tab; + unsigned n_var; + unsigned o_var; + isl_size total; + + total = isl_basic_map_dim(bmap, isl_dim_all); + if (total < 0) + return NULL; + tab = isl_tab_alloc(bmap->ctx, 2 * bmap->n_eq + bmap->n_ineq + 1, + total, M); + if (!tab) + return NULL; + + tab->rational = ISL_F_ISSET(bmap, ISL_BASIC_MAP_RATIONAL); + if (dom) { + isl_size dom_total; + dom_total = isl_basic_set_dim(dom, isl_dim_all); + if (dom_total < 0) + goto error; + tab->n_param = dom_total - dom->n_div; + tab->n_div = dom->n_div; + tab->row_sign = isl_calloc_array(bmap->ctx, + enum isl_tab_row_sign, tab->mat->n_row); + if (tab->mat->n_row && !tab->row_sign) + goto error; + } + if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_EMPTY)) { + if (isl_tab_mark_empty(tab) < 0) + goto error; + return tab; + } + + for (i = tab->n_param; i < tab->n_var - tab->n_div; ++i) { + tab->var[i].is_nonneg = 1; + tab->var[i].frozen = 1; + } + o_var = 1 + tab->n_param; + n_var = tab->n_var - tab->n_param - tab->n_div; + for (i = 0; i < bmap->n_eq; ++i) { + if (max) + isl_seq_neg(bmap->eq[i] + o_var, + bmap->eq[i] + o_var, n_var); + tab = add_lexmin_valid_eq(tab, bmap->eq[i]); + if (max) + isl_seq_neg(bmap->eq[i] + o_var, + bmap->eq[i] + o_var, n_var); + if (!tab || tab->empty) + return tab; + } + if (bmap->n_eq && restore_lexmin(tab) < 0) + goto error; + for (i = 0; i < bmap->n_ineq; ++i) { + if (max) + isl_seq_neg(bmap->ineq[i] + o_var, + bmap->ineq[i] + o_var, n_var); + tab = add_lexmin_ineq(tab, bmap->ineq[i]); + if (max) + isl_seq_neg(bmap->ineq[i] + o_var, + bmap->ineq[i] + o_var, n_var); + if (!tab || tab->empty) + return tab; + } + return tab; +error: + isl_tab_free(tab); + return NULL; +} + +/* Given a main tableau where more than one row requires a split, + * determine and return the "best" row to split on. + * + * If any of the rows requiring a split only involves + * variables that also appear in the context tableau, + * then the negative part is guaranteed not to have a solution. + * It is therefore best to split on any of these rows first. + * + * Otherwise, + * given two rows in the main tableau, if the inequality corresponding + * to the first row is redundant with respect to that of the second row + * in the current tableau, then it is better to split on the second row, + * since in the positive part, both rows will be positive. + * (In the negative part a pivot will have to be performed and just about + * anything can happen to the sign of the other row.) + * + * As a simple heuristic, we therefore select the row that makes the most + * of the other rows redundant. + * + * Perhaps it would also be useful to look at the number of constraints + * that conflict with any given constraint. + * + * best is the best row so far (-1 when we have not found any row yet). + * best_r is the number of other rows made redundant by row best. + * When best is still -1, bset_r is meaningless, but it is initialized + * to some arbitrary value (0) anyway. Without this redundant initialization + * valgrind may warn about uninitialized memory accesses when isl + * is compiled with some versions of gcc. + */ +static int best_split(struct isl_tab *tab, struct isl_tab *context_tab) +{ + struct isl_tab_undo *snap; + int split; + int row; + int best = -1; + int best_r = 0; + + if (isl_tab_extend_cons(context_tab, 2) < 0) + return -1; + + snap = isl_tab_snap(context_tab); + + for (split = tab->n_redundant; split < tab->n_row; ++split) { + struct isl_tab_undo *snap2; + struct isl_vec *ineq = NULL; + int r = 0; + int ok; + + if (!isl_tab_var_from_row(tab, split)->is_nonneg) + continue; + if (tab->row_sign[split] != isl_tab_row_any) + continue; + + if (is_parametric_constant(tab, split)) + return split; + + ineq = get_row_parameter_ineq(tab, split); + if (!ineq) + return -1; + ok = isl_tab_add_ineq(context_tab, ineq->el) >= 0; + isl_vec_free(ineq); + if (!ok) + return -1; + + snap2 = isl_tab_snap(context_tab); + + for (row = tab->n_redundant; row < tab->n_row; ++row) { + struct isl_tab_var *var; + + if (row == split) + continue; + if (!isl_tab_var_from_row(tab, row)->is_nonneg) + continue; + if (tab->row_sign[row] != isl_tab_row_any) + continue; + + ineq = get_row_parameter_ineq(tab, row); + if (!ineq) + return -1; + ok = isl_tab_add_ineq(context_tab, ineq->el) >= 0; + isl_vec_free(ineq); + if (!ok) + return -1; + var = &context_tab->con[context_tab->n_con - 1]; + if (!context_tab->empty && + !isl_tab_min_at_most_neg_one(context_tab, var)) + r++; + if (isl_tab_rollback(context_tab, snap2) < 0) + return -1; + } + if (best == -1 || r > best_r) { + best = split; + best_r = r; + } + if (isl_tab_rollback(context_tab, snap) < 0) + return -1; + } + + return best; +} + +static struct isl_basic_set *context_lex_peek_basic_set( + struct isl_context *context) +{ + struct isl_context_lex *clex = (struct isl_context_lex *)context; + if (!clex->tab) + return NULL; + return isl_tab_peek_bset(clex->tab); +} + +static struct isl_tab *context_lex_peek_tab(struct isl_context *context) +{ + struct isl_context_lex *clex = (struct isl_context_lex *)context; + return clex->tab; +} + +static void context_lex_add_eq(struct isl_context *context, isl_int *eq, + int check, int update) +{ + struct isl_context_lex *clex = (struct isl_context_lex *)context; + if (isl_tab_extend_cons(clex->tab, 2) < 0) + goto error; + if (add_lexmin_eq(clex->tab, eq) < 0) + goto error; + if (check) { + int v = tab_has_valid_sample(clex->tab, eq, 1); + if (v < 0) + goto error; + if (!v) + clex->tab = check_integer_feasible(clex->tab); + } + if (update) + clex->tab = check_samples(clex->tab, eq, 1); + return; +error: + isl_tab_free(clex->tab); + clex->tab = NULL; +} + +static void context_lex_add_ineq(struct isl_context *context, isl_int *ineq, + int check, int update) +{ + struct isl_context_lex *clex = (struct isl_context_lex *)context; + if (isl_tab_extend_cons(clex->tab, 1) < 0) + goto error; + clex->tab = add_lexmin_ineq(clex->tab, ineq); + if (check) { + int v = tab_has_valid_sample(clex->tab, ineq, 0); + if (v < 0) + goto error; + if (!v) + clex->tab = check_integer_feasible(clex->tab); + } + if (update) + clex->tab = check_samples(clex->tab, ineq, 0); + return; +error: + isl_tab_free(clex->tab); + clex->tab = NULL; +} + +static isl_stat context_lex_add_ineq_wrap(void *user, isl_int *ineq) +{ + struct isl_context *context = (struct isl_context *)user; + context_lex_add_ineq(context, ineq, 0, 0); + return context->op->is_ok(context) ? isl_stat_ok : isl_stat_error; +} + +/* Check which signs can be obtained by "ineq" on all the currently + * active sample values. See row_sign for more information. + */ +static enum isl_tab_row_sign tab_ineq_sign(struct isl_tab *tab, isl_int *ineq, + int strict) +{ + int i; + int sgn; + isl_int tmp; + enum isl_tab_row_sign res = isl_tab_row_unknown; + + isl_assert(tab->mat->ctx, tab->samples, return isl_tab_row_unknown); + isl_assert(tab->mat->ctx, tab->samples->n_col == 1 + tab->n_var, + return isl_tab_row_unknown); + + isl_int_init(tmp); + for (i = tab->n_outside; i < tab->n_sample; ++i) { + isl_seq_inner_product(tab->samples->row[i], ineq, + 1 + tab->n_var, &tmp); + sgn = isl_int_sgn(tmp); + if (sgn > 0 || (sgn == 0 && strict)) { + if (res == isl_tab_row_unknown) + res = isl_tab_row_pos; + if (res == isl_tab_row_neg) + res = isl_tab_row_any; + } + if (sgn < 0) { + if (res == isl_tab_row_unknown) + res = isl_tab_row_neg; + if (res == isl_tab_row_pos) + res = isl_tab_row_any; + } + if (res == isl_tab_row_any) + break; + } + isl_int_clear(tmp); + + return res; +} + +static enum isl_tab_row_sign context_lex_ineq_sign(struct isl_context *context, + isl_int *ineq, int strict) +{ + struct isl_context_lex *clex = (struct isl_context_lex *)context; + return tab_ineq_sign(clex->tab, ineq, strict); +} + +/* Check whether "ineq" can be added to the tableau without rendering + * it infeasible. + */ +static int context_lex_test_ineq(struct isl_context *context, isl_int *ineq) +{ + struct isl_context_lex *clex = (struct isl_context_lex *)context; + struct isl_tab_undo *snap; + int feasible; + + if (!clex->tab) + return -1; + + if (isl_tab_extend_cons(clex->tab, 1) < 0) + return -1; + + snap = isl_tab_snap(clex->tab); + if (isl_tab_push_basis(clex->tab) < 0) + return -1; + clex->tab = add_lexmin_ineq(clex->tab, ineq); + clex->tab = check_integer_feasible(clex->tab); + if (!clex->tab) + return -1; + feasible = !clex->tab->empty; + if (isl_tab_rollback(clex->tab, snap) < 0) + return -1; + + return feasible; +} + +static int context_lex_get_div(struct isl_context *context, struct isl_tab *tab, + struct isl_vec *div) +{ + return get_div(tab, context, div); +} + +/* Insert a div specified by "div" to the context tableau at position "pos" and + * return isl_bool_true if the div is obviously non-negative. + * context_tab_add_div will always return isl_bool_true, because all variables + * in a isl_context_lex tableau are non-negative. + * However, if we are using a big parameter in the context, then this only + * reflects the non-negativity of the variable used to _encode_ the + * div, i.e., div' = M + div, so we can't draw any conclusions. + */ +static isl_bool context_lex_insert_div(struct isl_context *context, int pos, + __isl_keep isl_vec *div) +{ + struct isl_context_lex *clex = (struct isl_context_lex *)context; + isl_bool nonneg; + nonneg = context_tab_insert_div(clex->tab, pos, div, + context_lex_add_ineq_wrap, context); + if (nonneg < 0) + return isl_bool_error; + if (clex->tab->M) + return isl_bool_false; + return nonneg; +} + +static int context_lex_detect_equalities(struct isl_context *context, + struct isl_tab *tab) +{ + return 0; +} + +static int context_lex_best_split(struct isl_context *context, + struct isl_tab *tab) +{ + struct isl_context_lex *clex = (struct isl_context_lex *)context; + struct isl_tab_undo *snap; + int r; + + snap = isl_tab_snap(clex->tab); + if (isl_tab_push_basis(clex->tab) < 0) + return -1; + r = best_split(tab, clex->tab); + + if (r >= 0 && isl_tab_rollback(clex->tab, snap) < 0) + return -1; + + return r; +} + +static int context_lex_is_empty(struct isl_context *context) +{ + struct isl_context_lex *clex = (struct isl_context_lex *)context; + if (!clex->tab) + return -1; + return clex->tab->empty; +} + +static void *context_lex_save(struct isl_context *context) +{ + struct isl_context_lex *clex = (struct isl_context_lex *)context; + struct isl_tab_undo *snap; + + snap = isl_tab_snap(clex->tab); + if (isl_tab_push_basis(clex->tab) < 0) + return NULL; + if (isl_tab_save_samples(clex->tab) < 0) + return NULL; + + return snap; +} + +static void context_lex_restore(struct isl_context *context, void *save) +{ + struct isl_context_lex *clex = (struct isl_context_lex *)context; + if (isl_tab_rollback(clex->tab, (struct isl_tab_undo *)save) < 0) { + isl_tab_free(clex->tab); + clex->tab = NULL; + } +} + +static void context_lex_discard(void *save) +{ +} + +static int context_lex_is_ok(struct isl_context *context) +{ + struct isl_context_lex *clex = (struct isl_context_lex *)context; + return !!clex->tab; +} + +/* For each variable in the context tableau, check if the variable can + * only attain non-negative values. If so, mark the parameter as non-negative + * in the main tableau. This allows for a more direct identification of some + * cases of violated constraints. + */ +static struct isl_tab *tab_detect_nonnegative_parameters(struct isl_tab *tab, + struct isl_tab *context_tab) +{ + int i; + struct isl_tab_undo *snap; + struct isl_vec *ineq = NULL; + struct isl_tab_var *var; + int n; + + if (context_tab->n_var == 0) + return tab; + + ineq = isl_vec_alloc(tab->mat->ctx, 1 + context_tab->n_var); + if (!ineq) + goto error; + + if (isl_tab_extend_cons(context_tab, 1) < 0) + goto error; + + snap = isl_tab_snap(context_tab); + + n = 0; + isl_seq_clr(ineq->el, ineq->size); + for (i = 0; i < context_tab->n_var; ++i) { + isl_int_set_si(ineq->el[1 + i], 1); + if (isl_tab_add_ineq(context_tab, ineq->el) < 0) + goto error; + var = &context_tab->con[context_tab->n_con - 1]; + if (!context_tab->empty && + !isl_tab_min_at_most_neg_one(context_tab, var)) { + int j = i; + if (i >= tab->n_param) + j = i - tab->n_param + tab->n_var - tab->n_div; + tab->var[j].is_nonneg = 1; + n++; + } + isl_int_set_si(ineq->el[1 + i], 0); + if (isl_tab_rollback(context_tab, snap) < 0) + goto error; + } + + if (context_tab->M && n == context_tab->n_var) { + context_tab->mat = isl_mat_drop_cols(context_tab->mat, 2, 1); + context_tab->M = 0; + } + + isl_vec_free(ineq); + return tab; +error: + isl_vec_free(ineq); + isl_tab_free(tab); + return NULL; +} + +static struct isl_tab *context_lex_detect_nonnegative_parameters( + struct isl_context *context, struct isl_tab *tab) +{ + struct isl_context_lex *clex = (struct isl_context_lex *)context; + struct isl_tab_undo *snap; + + if (!tab) + return NULL; + + snap = isl_tab_snap(clex->tab); + if (isl_tab_push_basis(clex->tab) < 0) + goto error; + + tab = tab_detect_nonnegative_parameters(tab, clex->tab); + + if (isl_tab_rollback(clex->tab, snap) < 0) + goto error; + + return tab; +error: + isl_tab_free(tab); + return NULL; +} + +static void context_lex_invalidate(struct isl_context *context) +{ + struct isl_context_lex *clex = (struct isl_context_lex *)context; + isl_tab_free(clex->tab); + clex->tab = NULL; +} + +static __isl_null struct isl_context *context_lex_free( + struct isl_context *context) +{ + struct isl_context_lex *clex = (struct isl_context_lex *)context; + isl_tab_free(clex->tab); + free(clex); + + return NULL; +} + +struct isl_context_op isl_context_lex_op = { + context_lex_detect_nonnegative_parameters, + context_lex_peek_basic_set, + context_lex_peek_tab, + context_lex_add_eq, + context_lex_add_ineq, + context_lex_ineq_sign, + context_lex_test_ineq, + context_lex_get_div, + context_lex_insert_div, + context_lex_detect_equalities, + context_lex_best_split, + context_lex_is_empty, + context_lex_is_ok, + context_lex_save, + context_lex_restore, + context_lex_discard, + context_lex_invalidate, + context_lex_free, +}; + +static struct isl_tab *context_tab_for_lexmin(__isl_take isl_basic_set *bset) +{ + struct isl_tab *tab; + + if (!bset) + return NULL; + tab = tab_for_lexmin(bset_to_bmap(bset), NULL, 1, 0); + if (isl_tab_track_bset(tab, bset) < 0) + goto error; + tab = isl_tab_init_samples(tab); + return tab; +error: + isl_tab_free(tab); + return NULL; +} + +static struct isl_context *isl_context_lex_alloc(struct isl_basic_set *dom) +{ + struct isl_context_lex *clex; + + if (!dom) + return NULL; + + clex = isl_alloc_type(dom->ctx, struct isl_context_lex); + if (!clex) + return NULL; + + clex->context.op = &isl_context_lex_op; + + clex->tab = context_tab_for_lexmin(isl_basic_set_copy(dom)); + if (restore_lexmin(clex->tab) < 0) + goto error; + clex->tab = check_integer_feasible(clex->tab); + if (!clex->tab) + goto error; + + return &clex->context; +error: + clex->context.op->free(&clex->context); + return NULL; +} + +/* Representation of the context when using generalized basis reduction. + * + * "shifted" contains the offsets of the unit hypercubes that lie inside the + * context. Any rational point in "shifted" can therefore be rounded + * up to an integer point in the context. + * If the context is constrained by any equality, then "shifted" is not used + * as it would be empty. + */ +struct isl_context_gbr { + struct isl_context context; + struct isl_tab *tab; + struct isl_tab *shifted; + struct isl_tab *cone; +}; + +static struct isl_tab *context_gbr_detect_nonnegative_parameters( + struct isl_context *context, struct isl_tab *tab) +{ + struct isl_context_gbr *cgbr = (struct isl_context_gbr *)context; + if (!tab) + return NULL; + return tab_detect_nonnegative_parameters(tab, cgbr->tab); +} + +static struct isl_basic_set *context_gbr_peek_basic_set( + struct isl_context *context) +{ + struct isl_context_gbr *cgbr = (struct isl_context_gbr *)context; + if (!cgbr->tab) + return NULL; + return isl_tab_peek_bset(cgbr->tab); +} + +static struct isl_tab *context_gbr_peek_tab(struct isl_context *context) +{ + struct isl_context_gbr *cgbr = (struct isl_context_gbr *)context; + return cgbr->tab; +} + +/* Initialize the "shifted" tableau of the context, which + * contains the constraints of the original tableau shifted + * by the sum of all negative coefficients. This ensures + * that any rational point in the shifted tableau can + * be rounded up to yield an integer point in the original tableau. + */ +static void gbr_init_shifted(struct isl_context_gbr *cgbr) +{ + int i, j; + struct isl_vec *cst; + struct isl_basic_set *bset = isl_tab_peek_bset(cgbr->tab); + isl_size dim = isl_basic_set_dim(bset, isl_dim_all); + + if (dim < 0) + return; + cst = isl_vec_alloc(cgbr->tab->mat->ctx, bset->n_ineq); + if (!cst) + return; + + for (i = 0; i < bset->n_ineq; ++i) { + isl_int_set(cst->el[i], bset->ineq[i][0]); + for (j = 0; j < dim; ++j) { + if (!isl_int_is_neg(bset->ineq[i][1 + j])) + continue; + isl_int_add(bset->ineq[i][0], bset->ineq[i][0], + bset->ineq[i][1 + j]); + } + } + + cgbr->shifted = isl_tab_from_basic_set(bset, 0); + + for (i = 0; i < bset->n_ineq; ++i) + isl_int_set(bset->ineq[i][0], cst->el[i]); + + isl_vec_free(cst); +} + +/* Check if the shifted tableau is non-empty, and if so + * use the sample point to construct an integer point + * of the context tableau. + */ +static struct isl_vec *gbr_get_shifted_sample(struct isl_context_gbr *cgbr) +{ + struct isl_vec *sample; + + if (!cgbr->shifted) + gbr_init_shifted(cgbr); + if (!cgbr->shifted) + return NULL; + if (cgbr->shifted->empty) + return isl_vec_alloc(cgbr->tab->mat->ctx, 0); + + sample = isl_tab_get_sample_value(cgbr->shifted); + sample = isl_vec_ceil(sample); + + return sample; +} + +static __isl_give isl_basic_set *drop_constant_terms( + __isl_take isl_basic_set *bset) +{ + int i; + + if (!bset) + return NULL; + + for (i = 0; i < bset->n_eq; ++i) + isl_int_set_si(bset->eq[i][0], 0); + + for (i = 0; i < bset->n_ineq; ++i) + isl_int_set_si(bset->ineq[i][0], 0); + + return bset; +} + +static int use_shifted(struct isl_context_gbr *cgbr) +{ + if (!cgbr->tab) + return 0; + return cgbr->tab->bmap->n_eq == 0 && cgbr->tab->bmap->n_div == 0; +} + +static struct isl_vec *gbr_get_sample(struct isl_context_gbr *cgbr) +{ + struct isl_basic_set *bset; + struct isl_basic_set *cone; + + if (isl_tab_sample_is_integer(cgbr->tab)) + return isl_tab_get_sample_value(cgbr->tab); + + if (use_shifted(cgbr)) { + struct isl_vec *sample; + + sample = gbr_get_shifted_sample(cgbr); + if (!sample || sample->size > 0) + return sample; + + isl_vec_free(sample); + } + + if (!cgbr->cone) { + bset = isl_tab_peek_bset(cgbr->tab); + cgbr->cone = isl_tab_from_recession_cone(bset, 0); + if (!cgbr->cone) + return NULL; + if (isl_tab_track_bset(cgbr->cone, + isl_basic_set_copy(bset)) < 0) + return NULL; + } + if (isl_tab_detect_implicit_equalities(cgbr->cone) < 0) + return NULL; + + if (cgbr->cone->n_dead == cgbr->cone->n_col) { + struct isl_vec *sample; + struct isl_tab_undo *snap; + + if (cgbr->tab->basis) { + if (cgbr->tab->basis->n_col != 1 + cgbr->tab->n_var) { + isl_mat_free(cgbr->tab->basis); + cgbr->tab->basis = NULL; + } + cgbr->tab->n_zero = 0; + cgbr->tab->n_unbounded = 0; + } + + snap = isl_tab_snap(cgbr->tab); + + sample = isl_tab_sample(cgbr->tab); + + if (!sample || isl_tab_rollback(cgbr->tab, snap) < 0) { + isl_vec_free(sample); + return NULL; + } + + return sample; + } + + cone = isl_basic_set_dup(isl_tab_peek_bset(cgbr->cone)); + cone = drop_constant_terms(cone); + cone = isl_basic_set_update_from_tab(cone, cgbr->cone); + cone = isl_basic_set_underlying_set(cone); + cone = isl_basic_set_gauss(cone, NULL); + + bset = isl_basic_set_dup(isl_tab_peek_bset(cgbr->tab)); + bset = isl_basic_set_update_from_tab(bset, cgbr->tab); + bset = isl_basic_set_underlying_set(bset); + bset = isl_basic_set_gauss(bset, NULL); + + return isl_basic_set_sample_with_cone(bset, cone); +} + +static void check_gbr_integer_feasible(struct isl_context_gbr *cgbr) +{ + struct isl_vec *sample; + + if (!cgbr->tab) + return; + + if (cgbr->tab->empty) + return; + + sample = gbr_get_sample(cgbr); + if (!sample) + goto error; + + if (sample->size == 0) { + isl_vec_free(sample); + if (isl_tab_mark_empty(cgbr->tab) < 0) + goto error; + return; + } + + if (isl_tab_add_sample(cgbr->tab, sample) < 0) + goto error; + + return; +error: + isl_tab_free(cgbr->tab); + cgbr->tab = NULL; +} + +static struct isl_tab *add_gbr_eq(struct isl_tab *tab, isl_int *eq) +{ + if (!tab) + return NULL; + + if (isl_tab_extend_cons(tab, 2) < 0) + goto error; + + if (isl_tab_add_eq(tab, eq) < 0) + goto error; + + return tab; +error: + isl_tab_free(tab); + return NULL; +} + +/* Add the equality described by "eq" to the context. + * If "check" is set, then we check if the context is empty after + * adding the equality. + * If "update" is set, then we check if the samples are still valid. + * + * We do not explicitly add shifted copies of the equality to + * cgbr->shifted since they would conflict with each other. + * Instead, we directly mark cgbr->shifted empty. + */ +static void context_gbr_add_eq(struct isl_context *context, isl_int *eq, + int check, int update) +{ + struct isl_context_gbr *cgbr = (struct isl_context_gbr *)context; + + cgbr->tab = add_gbr_eq(cgbr->tab, eq); + + if (cgbr->shifted && !cgbr->shifted->empty && use_shifted(cgbr)) { + if (isl_tab_mark_empty(cgbr->shifted) < 0) + goto error; + } + + if (cgbr->cone && cgbr->cone->n_col != cgbr->cone->n_dead) { + if (isl_tab_extend_cons(cgbr->cone, 2) < 0) + goto error; + if (isl_tab_add_eq(cgbr->cone, eq) < 0) + goto error; + } + + if (check) { + int v = tab_has_valid_sample(cgbr->tab, eq, 1); + if (v < 0) + goto error; + if (!v) + check_gbr_integer_feasible(cgbr); + } + if (update) + cgbr->tab = check_samples(cgbr->tab, eq, 1); + return; +error: + isl_tab_free(cgbr->tab); + cgbr->tab = NULL; +} + +static void add_gbr_ineq(struct isl_context_gbr *cgbr, isl_int *ineq) +{ + if (!cgbr->tab) + return; + + if (isl_tab_extend_cons(cgbr->tab, 1) < 0) + goto error; + + if (isl_tab_add_ineq(cgbr->tab, ineq) < 0) + goto error; + + if (cgbr->shifted && !cgbr->shifted->empty && use_shifted(cgbr)) { + int i; + isl_size dim; + dim = isl_basic_map_dim(cgbr->tab->bmap, isl_dim_all); + if (dim < 0) + goto error; + + if (isl_tab_extend_cons(cgbr->shifted, 1) < 0) + goto error; + + for (i = 0; i < dim; ++i) { + if (!isl_int_is_neg(ineq[1 + i])) + continue; + isl_int_add(ineq[0], ineq[0], ineq[1 + i]); + } + + if (isl_tab_add_ineq(cgbr->shifted, ineq) < 0) + goto error; + + for (i = 0; i < dim; ++i) { + if (!isl_int_is_neg(ineq[1 + i])) + continue; + isl_int_sub(ineq[0], ineq[0], ineq[1 + i]); + } + } + + if (cgbr->cone && cgbr->cone->n_col != cgbr->cone->n_dead) { + if (isl_tab_extend_cons(cgbr->cone, 1) < 0) + goto error; + if (isl_tab_add_ineq(cgbr->cone, ineq) < 0) + goto error; + } + + return; +error: + isl_tab_free(cgbr->tab); + cgbr->tab = NULL; +} + +static void context_gbr_add_ineq(struct isl_context *context, isl_int *ineq, + int check, int update) +{ + struct isl_context_gbr *cgbr = (struct isl_context_gbr *)context; + + add_gbr_ineq(cgbr, ineq); + if (!cgbr->tab) + return; + + if (check) { + int v = tab_has_valid_sample(cgbr->tab, ineq, 0); + if (v < 0) + goto error; + if (!v) + check_gbr_integer_feasible(cgbr); + } + if (update) + cgbr->tab = check_samples(cgbr->tab, ineq, 0); + return; +error: + isl_tab_free(cgbr->tab); + cgbr->tab = NULL; +} + +static isl_stat context_gbr_add_ineq_wrap(void *user, isl_int *ineq) +{ + struct isl_context *context = (struct isl_context *)user; + context_gbr_add_ineq(context, ineq, 0, 0); + return context->op->is_ok(context) ? isl_stat_ok : isl_stat_error; +} + +static enum isl_tab_row_sign context_gbr_ineq_sign(struct isl_context *context, + isl_int *ineq, int strict) +{ + struct isl_context_gbr *cgbr = (struct isl_context_gbr *)context; + return tab_ineq_sign(cgbr->tab, ineq, strict); +} + +/* Check whether "ineq" can be added to the tableau without rendering + * it infeasible. + */ +static int context_gbr_test_ineq(struct isl_context *context, isl_int *ineq) +{ + struct isl_context_gbr *cgbr = (struct isl_context_gbr *)context; + struct isl_tab_undo *snap; + struct isl_tab_undo *shifted_snap = NULL; + struct isl_tab_undo *cone_snap = NULL; + int feasible; + + if (!cgbr->tab) + return -1; + + if (isl_tab_extend_cons(cgbr->tab, 1) < 0) + return -1; + + snap = isl_tab_snap(cgbr->tab); + if (cgbr->shifted) + shifted_snap = isl_tab_snap(cgbr->shifted); + if (cgbr->cone) + cone_snap = isl_tab_snap(cgbr->cone); + add_gbr_ineq(cgbr, ineq); + check_gbr_integer_feasible(cgbr); + if (!cgbr->tab) + return -1; + feasible = !cgbr->tab->empty; + if (isl_tab_rollback(cgbr->tab, snap) < 0) + return -1; + if (shifted_snap) { + if (isl_tab_rollback(cgbr->shifted, shifted_snap)) + return -1; + } else if (cgbr->shifted) { + isl_tab_free(cgbr->shifted); + cgbr->shifted = NULL; + } + if (cone_snap) { + if (isl_tab_rollback(cgbr->cone, cone_snap)) + return -1; + } else if (cgbr->cone) { + isl_tab_free(cgbr->cone); + cgbr->cone = NULL; + } + + return feasible; +} + +/* Return the column of the last of the variables associated to + * a column that has a non-zero coefficient. + * This function is called in a context where only coefficients + * of parameters or divs can be non-zero. + */ +static int last_non_zero_var_col(struct isl_tab *tab, isl_int *p) +{ + int i; + int col; + + if (tab->n_var == 0) + return -1; + + for (i = tab->n_var - 1; i >= 0; --i) { + if (i >= tab->n_param && i < tab->n_var - tab->n_div) + continue; + if (tab->var[i].is_row) + continue; + col = tab->var[i].index; + if (!isl_int_is_zero(p[col])) + return col; + } + + return -1; +} + +/* Look through all the recently added equalities in the context + * to see if we can propagate any of them to the main tableau. + * + * The newly added equalities in the context are encoded as pairs + * of inequalities starting at inequality "first". + * + * We tentatively add each of these equalities to the main tableau + * and if this happens to result in a row with a final coefficient + * that is one or negative one, we use it to kill a column + * in the main tableau. Otherwise, we discard the tentatively + * added row. + * This tentative addition of equality constraints turns + * on the undo facility of the tableau. Turn it off again + * at the end, assuming it was turned off to begin with. + * + * Return 0 on success and -1 on failure. + */ +static int propagate_equalities(struct isl_context_gbr *cgbr, + struct isl_tab *tab, unsigned first) +{ + int i; + struct isl_vec *eq = NULL; + isl_bool needs_undo; + + needs_undo = isl_tab_need_undo(tab); + if (needs_undo < 0) + goto error; + eq = isl_vec_alloc(tab->mat->ctx, 1 + tab->n_var); + if (!eq) + goto error; + + if (isl_tab_extend_cons(tab, (cgbr->tab->bmap->n_ineq - first)/2) < 0) + goto error; + + isl_seq_clr(eq->el + 1 + tab->n_param, + tab->n_var - tab->n_param - tab->n_div); + for (i = first; i < cgbr->tab->bmap->n_ineq; i += 2) { + int j; + int r; + struct isl_tab_undo *snap; + snap = isl_tab_snap(tab); + + isl_seq_cpy(eq->el, cgbr->tab->bmap->ineq[i], 1 + tab->n_param); + isl_seq_cpy(eq->el + 1 + tab->n_var - tab->n_div, + cgbr->tab->bmap->ineq[i] + 1 + tab->n_param, + tab->n_div); + + r = isl_tab_add_row(tab, eq->el); + if (r < 0) + goto error; + r = tab->con[r].index; + j = last_non_zero_var_col(tab, tab->mat->row[r] + 2 + tab->M); + if (j < 0 || j < tab->n_dead || + !isl_int_is_one(tab->mat->row[r][0]) || + (!isl_int_is_one(tab->mat->row[r][2 + tab->M + j]) && + !isl_int_is_negone(tab->mat->row[r][2 + tab->M + j]))) { + if (isl_tab_rollback(tab, snap) < 0) + goto error; + continue; + } + if (isl_tab_pivot(tab, r, j) < 0) + goto error; + if (isl_tab_kill_col(tab, j) < 0) + goto error; + + if (restore_lexmin(tab) < 0) + goto error; + } + + if (!needs_undo) + isl_tab_clear_undo(tab); + isl_vec_free(eq); + + return 0; +error: + isl_vec_free(eq); + isl_tab_free(cgbr->tab); + cgbr->tab = NULL; + return -1; +} + +static int context_gbr_detect_equalities(struct isl_context *context, + struct isl_tab *tab) +{ + struct isl_context_gbr *cgbr = (struct isl_context_gbr *)context; + unsigned n_ineq; + + if (!cgbr->cone) { + struct isl_basic_set *bset = isl_tab_peek_bset(cgbr->tab); + cgbr->cone = isl_tab_from_recession_cone(bset, 0); + if (!cgbr->cone) + goto error; + if (isl_tab_track_bset(cgbr->cone, + isl_basic_set_copy(bset)) < 0) + goto error; + } + if (isl_tab_detect_implicit_equalities(cgbr->cone) < 0) + goto error; + + n_ineq = cgbr->tab->bmap->n_ineq; + cgbr->tab = isl_tab_detect_equalities(cgbr->tab, cgbr->cone); + if (!cgbr->tab) + return -1; + if (cgbr->tab->bmap->n_ineq > n_ineq && + propagate_equalities(cgbr, tab, n_ineq) < 0) + return -1; + + return 0; +error: + isl_tab_free(cgbr->tab); + cgbr->tab = NULL; + return -1; +} + +static int context_gbr_get_div(struct isl_context *context, struct isl_tab *tab, + struct isl_vec *div) +{ + return get_div(tab, context, div); +} + +static isl_bool context_gbr_insert_div(struct isl_context *context, int pos, + __isl_keep isl_vec *div) +{ + struct isl_context_gbr *cgbr = (struct isl_context_gbr *)context; + if (cgbr->cone) { + int r, o_div; + isl_size n_div; + + n_div = isl_basic_map_dim(cgbr->cone->bmap, isl_dim_div); + if (n_div < 0) + return isl_bool_error; + o_div = cgbr->cone->n_var - n_div; + + if (isl_tab_extend_cons(cgbr->cone, 3) < 0) + return isl_bool_error; + if (isl_tab_extend_vars(cgbr->cone, 1) < 0) + return isl_bool_error; + if ((r = isl_tab_insert_var(cgbr->cone, pos)) <0) + return isl_bool_error; + + cgbr->cone->bmap = isl_basic_map_insert_div(cgbr->cone->bmap, + r - o_div, div); + if (!cgbr->cone->bmap) + return isl_bool_error; + if (isl_tab_push_var(cgbr->cone, isl_tab_undo_bmap_div, + &cgbr->cone->var[r]) < 0) + return isl_bool_error; + } + return context_tab_insert_div(cgbr->tab, pos, div, + context_gbr_add_ineq_wrap, context); +} + +static int context_gbr_best_split(struct isl_context *context, + struct isl_tab *tab) +{ + struct isl_context_gbr *cgbr = (struct isl_context_gbr *)context; + struct isl_tab_undo *snap; + int r; + + snap = isl_tab_snap(cgbr->tab); + r = best_split(tab, cgbr->tab); + + if (r >= 0 && isl_tab_rollback(cgbr->tab, snap) < 0) + return -1; + + return r; +} + +static int context_gbr_is_empty(struct isl_context *context) +{ + struct isl_context_gbr *cgbr = (struct isl_context_gbr *)context; + if (!cgbr->tab) + return -1; + return cgbr->tab->empty; +} + +struct isl_gbr_tab_undo { + struct isl_tab_undo *tab_snap; + struct isl_tab_undo *shifted_snap; + struct isl_tab_undo *cone_snap; +}; + +static void *context_gbr_save(struct isl_context *context) +{ + struct isl_context_gbr *cgbr = (struct isl_context_gbr *)context; + struct isl_gbr_tab_undo *snap; + + if (!cgbr->tab) + return NULL; + + snap = isl_alloc_type(cgbr->tab->mat->ctx, struct isl_gbr_tab_undo); + if (!snap) + return NULL; + + snap->tab_snap = isl_tab_snap(cgbr->tab); + if (isl_tab_save_samples(cgbr->tab) < 0) + goto error; + + if (cgbr->shifted) + snap->shifted_snap = isl_tab_snap(cgbr->shifted); + else + snap->shifted_snap = NULL; + + if (cgbr->cone) + snap->cone_snap = isl_tab_snap(cgbr->cone); + else + snap->cone_snap = NULL; + + return snap; +error: + free(snap); + return NULL; +} + +static void context_gbr_restore(struct isl_context *context, void *save) +{ + struct isl_context_gbr *cgbr = (struct isl_context_gbr *)context; + struct isl_gbr_tab_undo *snap = (struct isl_gbr_tab_undo *)save; + if (!snap) + goto error; + if (isl_tab_rollback(cgbr->tab, snap->tab_snap) < 0) + goto error; + + if (snap->shifted_snap) { + if (isl_tab_rollback(cgbr->shifted, snap->shifted_snap) < 0) + goto error; + } else if (cgbr->shifted) { + isl_tab_free(cgbr->shifted); + cgbr->shifted = NULL; + } + + if (snap->cone_snap) { + if (isl_tab_rollback(cgbr->cone, snap->cone_snap) < 0) + goto error; + } else if (cgbr->cone) { + isl_tab_free(cgbr->cone); + cgbr->cone = NULL; + } + + free(snap); + + return; +error: + free(snap); + isl_tab_free(cgbr->tab); + cgbr->tab = NULL; +} + +static void context_gbr_discard(void *save) +{ + struct isl_gbr_tab_undo *snap = (struct isl_gbr_tab_undo *)save; + free(snap); +} + +static int context_gbr_is_ok(struct isl_context *context) +{ + struct isl_context_gbr *cgbr = (struct isl_context_gbr *)context; + return !!cgbr->tab; +} + +static void context_gbr_invalidate(struct isl_context *context) +{ + struct isl_context_gbr *cgbr = (struct isl_context_gbr *)context; + isl_tab_free(cgbr->tab); + cgbr->tab = NULL; +} + +static __isl_null struct isl_context *context_gbr_free( + struct isl_context *context) +{ + struct isl_context_gbr *cgbr = (struct isl_context_gbr *)context; + isl_tab_free(cgbr->tab); + isl_tab_free(cgbr->shifted); + isl_tab_free(cgbr->cone); + free(cgbr); + + return NULL; +} + +struct isl_context_op isl_context_gbr_op = { + context_gbr_detect_nonnegative_parameters, + context_gbr_peek_basic_set, + context_gbr_peek_tab, + context_gbr_add_eq, + context_gbr_add_ineq, + context_gbr_ineq_sign, + context_gbr_test_ineq, + context_gbr_get_div, + context_gbr_insert_div, + context_gbr_detect_equalities, + context_gbr_best_split, + context_gbr_is_empty, + context_gbr_is_ok, + context_gbr_save, + context_gbr_restore, + context_gbr_discard, + context_gbr_invalidate, + context_gbr_free, +}; + +static struct isl_context *isl_context_gbr_alloc(__isl_keep isl_basic_set *dom) +{ + struct isl_context_gbr *cgbr; + + if (!dom) + return NULL; + + cgbr = isl_calloc_type(dom->ctx, struct isl_context_gbr); + if (!cgbr) + return NULL; + + cgbr->context.op = &isl_context_gbr_op; + + cgbr->shifted = NULL; + cgbr->cone = NULL; + cgbr->tab = isl_tab_from_basic_set(dom, 1); + cgbr->tab = isl_tab_init_samples(cgbr->tab); + if (!cgbr->tab) + goto error; + check_gbr_integer_feasible(cgbr); + + return &cgbr->context; +error: + cgbr->context.op->free(&cgbr->context); + return NULL; +} + +/* Allocate a context corresponding to "dom". + * The representation specific fields are initialized by + * isl_context_lex_alloc or isl_context_gbr_alloc. + * The shared "n_unknown" field is initialized to the number + * of final unknown integer divisions in "dom". + */ +static struct isl_context *isl_context_alloc(__isl_keep isl_basic_set *dom) +{ + struct isl_context *context; + int first; + isl_size n_div; + + if (!dom) + return NULL; + + if (dom->ctx->opt->context == ISL_CONTEXT_LEXMIN) + context = isl_context_lex_alloc(dom); + else + context = isl_context_gbr_alloc(dom); + + if (!context) + return NULL; + + first = isl_basic_set_first_unknown_div(dom); + n_div = isl_basic_set_dim(dom, isl_dim_div); + if (first < 0 || n_div < 0) + return context->op->free(context); + context->n_unknown = n_div - first; + + return context; +} + +/* Initialize some common fields of "sol", which keeps track + * of the solution of an optimization problem on "bmap" over + * the domain "dom". + * If "max" is set, then a maximization problem is being solved, rather than + * a minimization problem, which means that the variables in the + * tableau have value "M - x" rather than "M + x". + */ +static isl_stat sol_init(struct isl_sol *sol, __isl_keep isl_basic_map *bmap, + __isl_keep isl_basic_set *dom, int max) +{ + sol->rational = ISL_F_ISSET(bmap, ISL_BASIC_MAP_RATIONAL); + sol->dec_level.callback.run = &sol_dec_level_wrap; + sol->dec_level.sol = sol; + sol->max = max; + sol->n_out = isl_basic_map_dim(bmap, isl_dim_out); + sol->space = isl_basic_map_get_space(bmap); + + sol->context = isl_context_alloc(dom); + if (sol->n_out < 0 || !sol->space || !sol->context) + return isl_stat_error; + + return isl_stat_ok; +} + +/* Construct an isl_sol_map structure for accumulating the solution. + * If track_empty is set, then we also keep track of the parts + * of the context where there is no solution. + * If max is set, then we are solving a maximization, rather than + * a minimization problem, which means that the variables in the + * tableau have value "M - x" rather than "M + x". + */ +static struct isl_sol *sol_map_init(__isl_keep isl_basic_map *bmap, + __isl_take isl_basic_set *dom, int track_empty, int max) +{ + struct isl_sol_map *sol_map = NULL; + isl_space *space; + + if (!bmap) + goto error; + + sol_map = isl_calloc_type(bmap->ctx, struct isl_sol_map); + if (!sol_map) + goto error; + + sol_map->sol.free = &sol_map_free; + if (sol_init(&sol_map->sol, bmap, dom, max) < 0) + goto error; + sol_map->sol.add = &sol_map_add_wrap; + sol_map->sol.add_empty = track_empty ? &sol_map_add_empty_wrap : NULL; + space = isl_space_copy(sol_map->sol.space); + sol_map->map = isl_map_alloc_space(space, 1, ISL_MAP_DISJOINT); + if (!sol_map->map) + goto error; + + if (track_empty) { + sol_map->empty = isl_set_alloc_space(isl_basic_set_get_space(dom), + 1, ISL_SET_DISJOINT); + if (!sol_map->empty) + goto error; + } + + isl_basic_set_free(dom); + return &sol_map->sol; +error: + isl_basic_set_free(dom); + sol_free(&sol_map->sol); + return NULL; +} + +/* Check whether all coefficients of (non-parameter) variables + * are non-positive, meaning that no pivots can be performed on the row. + */ +static int is_critical(struct isl_tab *tab, int row) +{ + int j; + unsigned off = 2 + tab->M; + + for (j = tab->n_dead; j < tab->n_col; ++j) { + if (col_is_parameter_var(tab, j)) + continue; + + if (isl_int_is_pos(tab->mat->row[row][off + j])) + return 0; + } + + return 1; +} + +/* Check whether the inequality represented by vec is strict over the integers, + * i.e., there are no integer values satisfying the constraint with + * equality. This happens if the gcd of the coefficients is not a divisor + * of the constant term. If so, scale the constraint down by the gcd + * of the coefficients. + */ +static int is_strict(struct isl_vec *vec) +{ + isl_int gcd; + int strict = 0; + + isl_int_init(gcd); + isl_seq_gcd(vec->el + 1, vec->size - 1, &gcd); + if (!isl_int_is_one(gcd)) { + strict = !isl_int_is_divisible_by(vec->el[0], gcd); + isl_int_fdiv_q(vec->el[0], vec->el[0], gcd); + isl_seq_scale_down(vec->el + 1, vec->el + 1, gcd, vec->size-1); + } + isl_int_clear(gcd); + + return strict; +} + +/* Determine the sign of the given row of the main tableau. + * The result is one of + * isl_tab_row_pos: always non-negative; no pivot needed + * isl_tab_row_neg: always non-positive; pivot + * isl_tab_row_any: can be both positive and negative; split + * + * We first handle some simple cases + * - the row sign may be known already + * - the row may be obviously non-negative + * - the parametric constant may be equal to that of another row + * for which we know the sign. This sign will be either "pos" or + * "any". If it had been "neg" then we would have pivoted before. + * + * If none of these cases hold, we check the value of the row for each + * of the currently active samples. Based on the signs of these values + * we make an initial determination of the sign of the row. + * + * all zero -> unk(nown) + * all non-negative -> pos + * all non-positive -> neg + * both negative and positive -> all + * + * If we end up with "all", we are done. + * Otherwise, we perform a check for positive and/or negative + * values as follows. + * + * samples neg unk pos + * <0 ? Y N Y N + * pos any pos + * >0 ? Y N Y N + * any neg any neg + * + * There is no special sign for "zero", because we can usually treat zero + * as either non-negative or non-positive, whatever works out best. + * However, if the row is "critical", meaning that pivoting is impossible + * then we don't want to limp zero with the non-positive case, because + * then we we would lose the solution for those values of the parameters + * where the value of the row is zero. Instead, we treat 0 as non-negative + * ensuring a split if the row can attain both zero and negative values. + * The same happens when the original constraint was one that could not + * be satisfied with equality by any integer values of the parameters. + * In this case, we normalize the constraint, but then a value of zero + * for the normalized constraint is actually a positive value for the + * original constraint, so again we need to treat zero as non-negative. + * In both these cases, we have the following decision tree instead: + * + * all non-negative -> pos + * all negative -> neg + * both negative and non-negative -> all + * + * samples neg pos + * <0 ? Y N + * any pos + * >=0 ? Y N + * any neg + */ +static enum isl_tab_row_sign row_sign(struct isl_tab *tab, + struct isl_sol *sol, int row) +{ + struct isl_vec *ineq = NULL; + enum isl_tab_row_sign res = isl_tab_row_unknown; + int critical; + int strict; + int row2; + + if (tab->row_sign[row] != isl_tab_row_unknown) + return tab->row_sign[row]; + if (is_obviously_nonneg(tab, row)) + return isl_tab_row_pos; + for (row2 = tab->n_redundant; row2 < tab->n_row; ++row2) { + if (tab->row_sign[row2] == isl_tab_row_unknown) + continue; + if (identical_parameter_line(tab, row, row2)) + return tab->row_sign[row2]; + } + + critical = is_critical(tab, row); + + ineq = get_row_parameter_ineq(tab, row); + if (!ineq) + goto error; + + strict = is_strict(ineq); + + res = sol->context->op->ineq_sign(sol->context, ineq->el, + critical || strict); + + if (res == isl_tab_row_unknown || res == isl_tab_row_pos) { + /* test for negative values */ + int feasible; + isl_seq_neg(ineq->el, ineq->el, ineq->size); + isl_int_sub_ui(ineq->el[0], ineq->el[0], 1); + + feasible = sol->context->op->test_ineq(sol->context, ineq->el); + if (feasible < 0) + goto error; + if (!feasible) + res = isl_tab_row_pos; + else + res = (res == isl_tab_row_unknown) ? isl_tab_row_neg + : isl_tab_row_any; + if (res == isl_tab_row_neg) { + isl_seq_neg(ineq->el, ineq->el, ineq->size); + isl_int_sub_ui(ineq->el[0], ineq->el[0], 1); + } + } + + if (res == isl_tab_row_neg) { + /* test for positive values */ + int feasible; + if (!critical && !strict) + isl_int_sub_ui(ineq->el[0], ineq->el[0], 1); + + feasible = sol->context->op->test_ineq(sol->context, ineq->el); + if (feasible < 0) + goto error; + if (feasible) + res = isl_tab_row_any; + } + + isl_vec_free(ineq); + return res; +error: + isl_vec_free(ineq); + return isl_tab_row_unknown; +} + +static void find_solutions(struct isl_sol *sol, struct isl_tab *tab); + +/* Find solutions for values of the parameters that satisfy the given + * inequality. + * + * We currently take a snapshot of the context tableau that is reset + * when we return from this function, while we make a copy of the main + * tableau, leaving the original main tableau untouched. + * These are fairly arbitrary choices. Making a copy also of the context + * tableau would obviate the need to undo any changes made to it later, + * while taking a snapshot of the main tableau could reduce memory usage. + * If we were to switch to taking a snapshot of the main tableau, + * we would have to keep in mind that we need to save the row signs + * and that we need to do this before saving the current basis + * such that the basis has been restore before we restore the row signs. + */ +static void find_in_pos(struct isl_sol *sol, struct isl_tab *tab, isl_int *ineq) +{ + void *saved; + + if (!sol->context) + goto error; + + tab = isl_tab_dup(tab); + if (!tab) + goto error; + + saved = sol->context->op->save(sol->context); + + sol_context_add_ineq(sol, ineq, 0, 1); + + find_solutions(sol, tab); + + if (!sol->error) + sol->context->op->restore(sol->context, saved); + else + sol->context->op->discard(saved); + return; +error: + sol->error = 1; +} + +/* Record the absence of solutions for those values of the parameters + * that do not satisfy the given inequality with equality. + */ +static void no_sol_in_strict(struct isl_sol *sol, + struct isl_tab *tab, struct isl_vec *ineq) +{ + int empty; + void *saved; + + if (!sol->context || sol->error) + goto error; + saved = sol->context->op->save(sol->context); + + isl_int_sub_ui(ineq->el[0], ineq->el[0], 1); + + sol_context_add_ineq(sol, ineq->el, 1, 0); + + empty = tab->empty; + tab->empty = 1; + sol_add(sol, tab); + tab->empty = empty; + + isl_int_add_ui(ineq->el[0], ineq->el[0], 1); + + sol->context->op->restore(sol->context, saved); + if (!sol->context->op->is_ok(sol->context)) + goto error; + return; +error: + sol->error = 1; +} + +/* Reset all row variables that are marked to have a sign that may + * be both positive and negative to have an unknown sign. + */ +static void reset_any_to_unknown(struct isl_tab *tab) +{ + int row; + + for (row = tab->n_redundant; row < tab->n_row; ++row) { + if (!isl_tab_var_from_row(tab, row)->is_nonneg) + continue; + if (tab->row_sign[row] == isl_tab_row_any) + tab->row_sign[row] = isl_tab_row_unknown; + } +} + +/* Compute the lexicographic minimum of the set represented by the main + * tableau "tab" within the context "sol->context_tab". + * On entry the sample value of the main tableau is lexicographically + * less than or equal to this lexicographic minimum. + * Pivots are performed until a feasible point is found, which is then + * necessarily equal to the minimum, or until the tableau is found to + * be infeasible. Some pivots may need to be performed for only some + * feasible values of the context tableau. If so, the context tableau + * is split into a part where the pivot is needed and a part where it is not. + * + * Whenever we enter the main loop, the main tableau is such that no + * "obvious" pivots need to be performed on it, where "obvious" means + * that the given row can be seen to be negative without looking at + * the context tableau. In particular, for non-parametric problems, + * no pivots need to be performed on the main tableau. + * The caller of find_solutions is responsible for making this property + * hold prior to the first iteration of the loop, while restore_lexmin + * is called before every other iteration. + * + * Inside the main loop, we first examine the signs of the rows of + * the main tableau within the context of the context tableau. + * If we find a row that is always non-positive for all values of + * the parameters satisfying the context tableau and negative for at + * least one value of the parameters, we perform the appropriate pivot + * and start over. An exception is the case where no pivot can be + * performed on the row. In this case, we require that the sign of + * the row is negative for all values of the parameters (rather than just + * non-positive). This special case is handled inside row_sign, which + * will say that the row can have any sign if it determines that it can + * attain both negative and zero values. + * + * If we can't find a row that always requires a pivot, but we can find + * one or more rows that require a pivot for some values of the parameters + * (i.e., the row can attain both positive and negative signs), then we split + * the context tableau into two parts, one where we force the sign to be + * non-negative and one where we force is to be negative. + * The non-negative part is handled by a recursive call (through find_in_pos). + * Upon returning from this call, we continue with the negative part and + * perform the required pivot. + * + * If no such rows can be found, all rows are non-negative and we have + * found a (rational) feasible point. If we only wanted a rational point + * then we are done. + * Otherwise, we check if all values of the sample point of the tableau + * are integral for the variables. If so, we have found the minimal + * integral point and we are done. + * If the sample point is not integral, then we need to make a distinction + * based on whether the constant term is non-integral or the coefficients + * of the parameters. Furthermore, in order to decide how to handle + * the non-integrality, we also need to know whether the coefficients + * of the other columns in the tableau are integral. This leads + * to the following table. The first two rows do not correspond + * to a non-integral sample point and are only mentioned for completeness. + * + * constant parameters other + * + * int int int | + * int int rat | -> no problem + * + * rat int int -> fail + * + * rat int rat -> cut + * + * int rat rat | + * rat rat rat | -> parametric cut + * + * int rat int | + * rat rat int | -> split context + * + * If the parametric constant is completely integral, then there is nothing + * to be done. If the constant term is non-integral, but all the other + * coefficient are integral, then there is nothing that can be done + * and the tableau has no integral solution. + * If, on the other hand, one or more of the other columns have rational + * coefficients, but the parameter coefficients are all integral, then + * we can perform a regular (non-parametric) cut. + * Finally, if there is any parameter coefficient that is non-integral, + * then we need to involve the context tableau. There are two cases here. + * If at least one other column has a rational coefficient, then we + * can perform a parametric cut in the main tableau by adding a new + * integer division in the context tableau. + * If all other columns have integral coefficients, then we need to + * enforce that the rational combination of parameters (c + \sum a_i y_i)/m + * is always integral. We do this by introducing an integer division + * q = floor((c + \sum a_i y_i)/m) and stipulating that its argument should + * always be integral in the context tableau, i.e., m q = c + \sum a_i y_i. + * Since q is expressed in the tableau as + * c + \sum a_i y_i - m q >= 0 + * -c - \sum a_i y_i + m q + m - 1 >= 0 + * it is sufficient to add the inequality + * -c - \sum a_i y_i + m q >= 0 + * In the part of the context where this inequality does not hold, the + * main tableau is marked as being empty. + */ +static void find_solutions(struct isl_sol *sol, struct isl_tab *tab) +{ + struct isl_context *context; + int r; + + if (!tab || sol->error) + goto error; + + context = sol->context; + + if (tab->empty) + goto done; + if (context->op->is_empty(context)) + goto done; + + for (r = 0; r >= 0 && tab && !tab->empty; r = restore_lexmin(tab)) { + int flags; + int row; + enum isl_tab_row_sign sgn; + int split = -1; + int n_split = 0; + + for (row = tab->n_redundant; row < tab->n_row; ++row) { + if (!isl_tab_var_from_row(tab, row)->is_nonneg) + continue; + sgn = row_sign(tab, sol, row); + if (!sgn) + goto error; + tab->row_sign[row] = sgn; + if (sgn == isl_tab_row_any) + n_split++; + if (sgn == isl_tab_row_any && split == -1) + split = row; + if (sgn == isl_tab_row_neg) + break; + } + if (row < tab->n_row) + continue; + if (split != -1) { + struct isl_vec *ineq; + if (n_split != 1) + split = context->op->best_split(context, tab); + if (split < 0) + goto error; + ineq = get_row_parameter_ineq(tab, split); + if (!ineq) + goto error; + is_strict(ineq); + reset_any_to_unknown(tab); + tab->row_sign[split] = isl_tab_row_pos; + sol_inc_level(sol); + find_in_pos(sol, tab, ineq->el); + tab->row_sign[split] = isl_tab_row_neg; + isl_seq_neg(ineq->el, ineq->el, ineq->size); + isl_int_sub_ui(ineq->el[0], ineq->el[0], 1); + sol_context_add_ineq(sol, ineq->el, 0, 1); + isl_vec_free(ineq); + if (sol->error) + goto error; + continue; + } + if (tab->rational) + break; + row = first_non_integer_row(tab, &flags); + if (row < 0) + break; + if (ISL_FL_ISSET(flags, I_PAR)) { + if (ISL_FL_ISSET(flags, I_VAR)) { + if (isl_tab_mark_empty(tab) < 0) + goto error; + break; + } + row = add_cut(tab, row); + } else if (ISL_FL_ISSET(flags, I_VAR)) { + struct isl_vec *div; + struct isl_vec *ineq; + int d; + div = get_row_split_div(tab, row); + if (!div) + goto error; + d = context->op->get_div(context, tab, div); + isl_vec_free(div); + if (d < 0) + goto error; + ineq = ineq_for_div(context->op->peek_basic_set(context), d); + if (!ineq) + goto error; + sol_inc_level(sol); + no_sol_in_strict(sol, tab, ineq); + isl_seq_neg(ineq->el, ineq->el, ineq->size); + sol_context_add_ineq(sol, ineq->el, 1, 1); + isl_vec_free(ineq); + if (sol->error || !context->op->is_ok(context)) + goto error; + tab = set_row_cst_to_div(tab, row, d); + if (context->op->is_empty(context)) + break; + } else + row = add_parametric_cut(tab, row, context); + if (row < 0) + goto error; + } + if (r < 0) + goto error; +done: + sol_add(sol, tab); + isl_tab_free(tab); + return; +error: + isl_tab_free(tab); + sol->error = 1; +} + +/* Does "sol" contain a pair of partial solutions that could potentially + * be merged? + * + * We currently only check that "sol" is not in an error state + * and that there are at least two partial solutions of which the final two + * are defined at the same level. + */ +static int sol_has_mergeable_solutions(struct isl_sol *sol) +{ + if (sol->error) + return 0; + if (!sol->partial) + return 0; + if (!sol->partial->next) + return 0; + return sol->partial->level == sol->partial->next->level; +} + +/* Compute the lexicographic minimum of the set represented by the main + * tableau "tab" within the context "sol->context_tab". + * + * As a preprocessing step, we first transfer all the purely parametric + * equalities from the main tableau to the context tableau, i.e., + * parameters that have been pivoted to a row. + * These equalities are ignored by the main algorithm, because the + * corresponding rows may not be marked as being non-negative. + * In parts of the context where the added equality does not hold, + * the main tableau is marked as being empty. + * + * Before we embark on the actual computation, we save a copy + * of the context. When we return, we check if there are any + * partial solutions that can potentially be merged. If so, + * we perform a rollback to the initial state of the context. + * The merging of partial solutions happens inside calls to + * sol_dec_level that are pushed onto the undo stack of the context. + * If there are no partial solutions that can potentially be merged + * then the rollback is skipped as it would just be wasted effort. + */ +static void find_solutions_main(struct isl_sol *sol, struct isl_tab *tab) +{ + int row; + void *saved; + + if (!tab) + goto error; + + sol->level = 0; + + for (row = tab->n_redundant; row < tab->n_row; ++row) { + int p; + struct isl_vec *eq; + + if (!row_is_parameter_var(tab, row)) + continue; + if (tab->row_var[row] < tab->n_param) + p = tab->row_var[row]; + else + p = tab->row_var[row] + + tab->n_param - (tab->n_var - tab->n_div); + + eq = isl_vec_alloc(tab->mat->ctx, 1+tab->n_param+tab->n_div); + if (!eq) + goto error; + get_row_parameter_line(tab, row, eq->el); + isl_int_neg(eq->el[1 + p], tab->mat->row[row][0]); + eq = isl_vec_normalize(eq); + + sol_inc_level(sol); + no_sol_in_strict(sol, tab, eq); + + isl_seq_neg(eq->el, eq->el, eq->size); + sol_inc_level(sol); + no_sol_in_strict(sol, tab, eq); + isl_seq_neg(eq->el, eq->el, eq->size); + + sol_context_add_eq(sol, eq->el, 1, 1); + + isl_vec_free(eq); + + if (isl_tab_mark_redundant(tab, row) < 0) + goto error; + + if (sol->context->op->is_empty(sol->context)) + break; + + row = tab->n_redundant - 1; + } + + saved = sol->context->op->save(sol->context); + + find_solutions(sol, tab); + + if (sol_has_mergeable_solutions(sol)) + sol->context->op->restore(sol->context, saved); + else + sol->context->op->discard(saved); + + sol->level = 0; + sol_pop(sol); + + return; +error: + isl_tab_free(tab); + sol->error = 1; +} + +/* Check if integer division "div" of "dom" also occurs in "bmap". + * If so, return its position within the divs. + * Otherwise, return a position beyond the integer divisions. + */ +static int find_context_div(__isl_keep isl_basic_map *bmap, + __isl_keep isl_basic_set *dom, unsigned div) +{ + int i; + isl_size b_v_div, d_v_div; + isl_size n_div; + + b_v_div = isl_basic_map_var_offset(bmap, isl_dim_div); + d_v_div = isl_basic_set_var_offset(dom, isl_dim_div); + n_div = isl_basic_map_dim(bmap, isl_dim_div); + if (b_v_div < 0 || d_v_div < 0 || n_div < 0) + return -1; + + if (isl_int_is_zero(dom->div[div][0])) + return n_div; + if (isl_seq_first_non_zero(dom->div[div] + 2 + d_v_div, + dom->n_div) != -1) + return n_div; + + for (i = 0; i < n_div; ++i) { + if (isl_int_is_zero(bmap->div[i][0])) + continue; + if (isl_seq_first_non_zero(bmap->div[i] + 2 + d_v_div, + (b_v_div - d_v_div) + n_div) != -1) + continue; + if (isl_seq_eq(bmap->div[i], dom->div[div], 2 + d_v_div)) + return i; + } + return n_div; +} + +/* The correspondence between the variables in the main tableau, + * the context tableau, and the input map and domain is as follows. + * The first n_param and the last n_div variables of the main tableau + * form the variables of the context tableau. + * In the basic map, these n_param variables correspond to the + * parameters and the input dimensions. In the domain, they correspond + * to the parameters and the set dimensions. + * The n_div variables correspond to the integer divisions in the domain. + * To ensure that everything lines up, we may need to copy some of the + * integer divisions of the domain to the map. These have to be placed + * in the same order as those in the context and they have to be placed + * after any other integer divisions that the map may have. + * This function performs the required reordering. + */ +static __isl_give isl_basic_map *align_context_divs( + __isl_take isl_basic_map *bmap, __isl_keep isl_basic_set *dom) +{ + int i; + int common = 0; + int other; + unsigned bmap_n_div; + + bmap_n_div = isl_basic_map_dim(bmap, isl_dim_div); + + for (i = 0; i < dom->n_div; ++i) { + int pos; + + pos = find_context_div(bmap, dom, i); + if (pos < 0) + return isl_basic_map_free(bmap); + if (pos < bmap_n_div) + common++; + } + other = bmap_n_div - common; + if (dom->n_div - common > 0) { + bmap = isl_basic_map_cow(bmap); + bmap = isl_basic_map_extend(bmap, dom->n_div - common, 0, 0); + if (!bmap) + return NULL; + } + for (i = 0; i < dom->n_div; ++i) { + int pos = find_context_div(bmap, dom, i); + if (pos < 0) + bmap = isl_basic_map_free(bmap); + if (pos >= bmap_n_div) { + pos = isl_basic_map_alloc_div(bmap); + if (pos < 0) + goto error; + isl_int_set_si(bmap->div[pos][0], 0); + bmap_n_div++; + } + if (pos != other + i) + bmap = isl_basic_map_swap_div(bmap, pos, other + i); + } + return bmap; +error: + isl_basic_map_free(bmap); + return NULL; +} + +/* Base case of isl_tab_basic_map_partial_lexopt, after removing + * some obvious symmetries. + * + * We make sure the divs in the domain are properly ordered, + * because they will be added one by one in the given order + * during the construction of the solution map. + * Furthermore, make sure that the known integer divisions + * appear before any unknown integer division because the solution + * may depend on the known integer divisions, while anything that + * depends on any variable starting from the first unknown integer + * division is ignored in sol_pma_add. + */ +static struct isl_sol *basic_map_partial_lexopt_base_sol( + __isl_take isl_basic_map *bmap, __isl_take isl_basic_set *dom, + __isl_give isl_set **empty, int max, + struct isl_sol *(*init)(__isl_keep isl_basic_map *bmap, + __isl_take isl_basic_set *dom, int track_empty, int max)) +{ + struct isl_tab *tab; + struct isl_sol *sol = NULL; + struct isl_context *context; + + if (dom->n_div) { + dom = isl_basic_set_sort_divs(dom); + bmap = align_context_divs(bmap, dom); + } + sol = init(bmap, dom, !!empty, max); + if (!sol) + goto error; + + context = sol->context; + if (isl_basic_set_plain_is_empty(context->op->peek_basic_set(context))) + /* nothing */; + else if (isl_basic_map_plain_is_empty(bmap)) { + if (sol->add_empty) + sol->add_empty(sol, + isl_basic_set_copy(context->op->peek_basic_set(context))); + } else { + tab = tab_for_lexmin(bmap, + context->op->peek_basic_set(context), 1, max); + tab = context->op->detect_nonnegative_parameters(context, tab); + find_solutions_main(sol, tab); + } + if (sol->error) + goto error; + + isl_basic_map_free(bmap); + return sol; +error: + sol_free(sol); + isl_basic_map_free(bmap); + return NULL; +} + +/* Base case of isl_tab_basic_map_partial_lexopt, after removing + * some obvious symmetries. + * + * We call basic_map_partial_lexopt_base_sol and extract the results. + */ +static __isl_give isl_map *basic_map_partial_lexopt_base( + __isl_take isl_basic_map *bmap, __isl_take isl_basic_set *dom, + __isl_give isl_set **empty, int max) +{ + isl_map *result = NULL; + struct isl_sol *sol; + struct isl_sol_map *sol_map; + + sol = basic_map_partial_lexopt_base_sol(bmap, dom, empty, max, + &sol_map_init); + if (!sol) + return NULL; + sol_map = (struct isl_sol_map *) sol; + + result = isl_map_copy(sol_map->map); + if (empty) + *empty = isl_set_copy(sol_map->empty); + sol_free(&sol_map->sol); + return result; +} + +/* Return a count of the number of occurrences of the "n" first + * variables in the inequality constraints of "bmap". + */ +static __isl_give int *count_occurrences(__isl_keep isl_basic_map *bmap, + int n) +{ + int i, j; + isl_ctx *ctx; + int *occurrences; + + if (!bmap) + return NULL; + ctx = isl_basic_map_get_ctx(bmap); + occurrences = isl_calloc_array(ctx, int, n); + if (!occurrences) + return NULL; + + for (i = 0; i < bmap->n_ineq; ++i) { + for (j = 0; j < n; ++j) { + if (!isl_int_is_zero(bmap->ineq[i][1 + j])) + occurrences[j]++; + } + } + + return occurrences; +} + +/* Do all of the "n" variables with non-zero coefficients in "c" + * occur in exactly a single constraint. + * "occurrences" is an array of length "n" containing the number + * of occurrences of each of the variables in the inequality constraints. + */ +static int single_occurrence(int n, isl_int *c, int *occurrences) +{ + int i; + + for (i = 0; i < n; ++i) { + if (isl_int_is_zero(c[i])) + continue; + if (occurrences[i] != 1) + return 0; + } + + return 1; +} + +/* Do all of the "n" initial variables that occur in inequality constraint + * "ineq" of "bmap" only occur in that constraint? + */ +static int all_single_occurrence(__isl_keep isl_basic_map *bmap, int ineq, + int n) +{ + int i, j; + + for (i = 0; i < n; ++i) { + if (isl_int_is_zero(bmap->ineq[ineq][1 + i])) + continue; + for (j = 0; j < bmap->n_ineq; ++j) { + if (j == ineq) + continue; + if (!isl_int_is_zero(bmap->ineq[j][1 + i])) + return 0; + } + } + + return 1; +} + +/* Structure used during detection of parallel constraints. + * n_in: number of "input" variables: isl_dim_param + isl_dim_in + * n_out: number of "output" variables: isl_dim_out + isl_dim_div + * val: the coefficients of the output variables + */ +struct isl_constraint_equal_info { + unsigned n_in; + unsigned n_out; + isl_int *val; +}; + +/* Check whether the coefficients of the output variables + * of the constraint in "entry" are equal to info->val. + */ +static isl_bool constraint_equal(const void *entry, const void *val) +{ + isl_int **row = (isl_int **)entry; + const struct isl_constraint_equal_info *info = val; + int eq; + + eq = isl_seq_eq((*row) + 1 + info->n_in, info->val, info->n_out); + return isl_bool_ok(eq); +} + +/* Check whether "bmap" has a pair of constraints that have + * the same coefficients for the output variables. + * Note that the coefficients of the existentially quantified + * variables need to be zero since the existentially quantified + * of the result are usually not the same as those of the input. + * Furthermore, check that each of the input variables that occur + * in those constraints does not occur in any other constraint. + * If so, return true and return the row indices of the two constraints + * in *first and *second. + */ +static isl_bool parallel_constraints(__isl_keep isl_basic_map *bmap, + int *first, int *second) +{ + int i; + isl_ctx *ctx; + int *occurrences = NULL; + struct isl_hash_table *table = NULL; + struct isl_hash_table_entry *entry; + struct isl_constraint_equal_info info; + isl_size nparam, n_in, n_out, n_div; + + ctx = isl_basic_map_get_ctx(bmap); + table = isl_hash_table_alloc(ctx, bmap->n_ineq); + if (!table) + goto error; + + nparam = isl_basic_map_dim(bmap, isl_dim_param); + n_in = isl_basic_map_dim(bmap, isl_dim_in); + n_out = isl_basic_map_dim(bmap, isl_dim_out); + n_div = isl_basic_map_dim(bmap, isl_dim_div); + if (nparam < 0 || n_in < 0 || n_out < 0 || n_div < 0) + goto error; + info.n_in = nparam + n_in; + occurrences = count_occurrences(bmap, info.n_in); + if (info.n_in && !occurrences) + goto error; + info.n_out = n_out + n_div; + for (i = 0; i < bmap->n_ineq; ++i) { + uint32_t hash; + + info.val = bmap->ineq[i] + 1 + info.n_in; + if (isl_seq_first_non_zero(info.val, n_out) < 0) + continue; + if (isl_seq_first_non_zero(info.val + n_out, n_div) >= 0) + continue; + if (!single_occurrence(info.n_in, bmap->ineq[i] + 1, + occurrences)) + continue; + hash = isl_seq_get_hash(info.val, info.n_out); + entry = isl_hash_table_find(ctx, table, hash, + constraint_equal, &info, 1); + if (!entry) + goto error; + if (entry->data) + break; + entry->data = &bmap->ineq[i]; + } + + if (i < bmap->n_ineq) { + *first = ((isl_int **)entry->data) - bmap->ineq; + *second = i; + } + + isl_hash_table_free(ctx, table); + free(occurrences); + + return isl_bool_ok(i < bmap->n_ineq); +error: + isl_hash_table_free(ctx, table); + free(occurrences); + return isl_bool_error; +} + +/* Given a set of upper bounds in "var", add constraints to "bset" + * that make the i-th bound smallest. + * + * In particular, if there are n bounds b_i, then add the constraints + * + * b_i <= b_j for j > i + * b_i < b_j for j < i + */ +static __isl_give isl_basic_set *select_minimum(__isl_take isl_basic_set *bset, + __isl_keep isl_mat *var, int i) +{ + isl_ctx *ctx; + int j, k; + + ctx = isl_mat_get_ctx(var); + + for (j = 0; j < var->n_row; ++j) { + if (j == i) + continue; + k = isl_basic_set_alloc_inequality(bset); + if (k < 0) + goto error; + isl_seq_combine(bset->ineq[k], ctx->one, var->row[j], + ctx->negone, var->row[i], var->n_col); + isl_int_set_si(bset->ineq[k][var->n_col], 0); + if (j < i) + isl_int_sub_ui(bset->ineq[k][0], bset->ineq[k][0], 1); + } + + bset = isl_basic_set_finalize(bset); + + return bset; +error: + isl_basic_set_free(bset); + return NULL; +} + +/* Given a set of upper bounds on the last "input" variable m, + * construct a set that assigns the minimal upper bound to m, i.e., + * construct a set that divides the space into cells where one + * of the upper bounds is smaller than all the others and assign + * this upper bound to m. + * + * In particular, if there are n bounds b_i, then the result + * consists of n basic sets, each one of the form + * + * m = b_i + * b_i <= b_j for j > i + * b_i < b_j for j < i + */ +static __isl_give isl_set *set_minimum(__isl_take isl_space *space, + __isl_take isl_mat *var) +{ + int i, k; + isl_basic_set *bset = NULL; + isl_set *set = NULL; + + if (!space || !var) + goto error; + + set = isl_set_alloc_space(isl_space_copy(space), + var->n_row, ISL_SET_DISJOINT); + + for (i = 0; i < var->n_row; ++i) { + bset = isl_basic_set_alloc_space(isl_space_copy(space), 0, + 1, var->n_row - 1); + k = isl_basic_set_alloc_equality(bset); + if (k < 0) + goto error; + isl_seq_cpy(bset->eq[k], var->row[i], var->n_col); + isl_int_set_si(bset->eq[k][var->n_col], -1); + bset = select_minimum(bset, var, i); + set = isl_set_add_basic_set(set, bset); + } + + isl_space_free(space); + isl_mat_free(var); + return set; +error: + isl_basic_set_free(bset); + isl_set_free(set); + isl_space_free(space); + isl_mat_free(var); + return NULL; +} + +/* Given that the last input variable of "bmap" represents the minimum + * of the bounds in "cst", check whether we need to split the domain + * based on which bound attains the minimum. + * + * A split is needed when the minimum appears in an integer division + * or in an equality. Otherwise, it is only needed if it appears in + * an upper bound that is different from the upper bounds on which it + * is defined. + */ +static isl_bool need_split_basic_map(__isl_keep isl_basic_map *bmap, + __isl_keep isl_mat *cst) +{ + int i, j; + isl_size total; + unsigned pos; + + pos = cst->n_col - 1; + total = isl_basic_map_dim(bmap, isl_dim_all); + if (total < 0) + return isl_bool_error; + + for (i = 0; i < bmap->n_div; ++i) + if (!isl_int_is_zero(bmap->div[i][2 + pos])) + return isl_bool_true; + + for (i = 0; i < bmap->n_eq; ++i) + if (!isl_int_is_zero(bmap->eq[i][1 + pos])) + return isl_bool_true; + + for (i = 0; i < bmap->n_ineq; ++i) { + if (isl_int_is_nonneg(bmap->ineq[i][1 + pos])) + continue; + if (!isl_int_is_negone(bmap->ineq[i][1 + pos])) + return isl_bool_true; + if (isl_seq_first_non_zero(bmap->ineq[i] + 1 + pos + 1, + total - pos - 1) >= 0) + return isl_bool_true; + + for (j = 0; j < cst->n_row; ++j) + if (isl_seq_eq(bmap->ineq[i], cst->row[j], cst->n_col)) + break; + if (j >= cst->n_row) + return isl_bool_true; + } + + return isl_bool_false; +} + +/* Given that the last set variable of "bset" represents the minimum + * of the bounds in "cst", check whether we need to split the domain + * based on which bound attains the minimum. + * + * We simply call need_split_basic_map here. This is safe because + * the position of the minimum is computed from "cst" and not + * from "bmap". + */ +static isl_bool need_split_basic_set(__isl_keep isl_basic_set *bset, + __isl_keep isl_mat *cst) +{ + return need_split_basic_map(bset_to_bmap(bset), cst); +} + +/* Given that the last set variable of "set" represents the minimum + * of the bounds in "cst", check whether we need to split the domain + * based on which bound attains the minimum. + */ +static isl_bool need_split_set(__isl_keep isl_set *set, __isl_keep isl_mat *cst) +{ + int i; + + for (i = 0; i < set->n; ++i) { + isl_bool split; + + split = need_split_basic_set(set->p[i], cst); + if (split < 0 || split) + return split; + } + + return isl_bool_false; +} + +/* Given a map of which the last input variable is the minimum + * of the bounds in "cst", split each basic set in the set + * in pieces where one of the bounds is (strictly) smaller than the others. + * This subdivision is given in "min_expr". + * The variable is subsequently projected out. + * + * We only do the split when it is needed. + * For example if the last input variable m = min(a,b) and the only + * constraints in the given basic set are lower bounds on m, + * i.e., l <= m = min(a,b), then we can simply project out m + * to obtain l <= a and l <= b, without having to split on whether + * m is equal to a or b. + */ +static __isl_give isl_map *split_domain(__isl_take isl_map *opt, + __isl_take isl_set *min_expr, __isl_take isl_mat *cst) +{ + isl_size n_in; + int i; + isl_space *space; + isl_map *res; + + n_in = isl_map_dim(opt, isl_dim_in); + if (n_in < 0 || !min_expr || !cst) + goto error; + + space = isl_map_get_space(opt); + space = isl_space_drop_dims(space, isl_dim_in, n_in - 1, 1); + res = isl_map_empty(space); + + for (i = 0; i < opt->n; ++i) { + isl_map *map; + isl_bool split; + + map = isl_map_from_basic_map(isl_basic_map_copy(opt->p[i])); + split = need_split_basic_map(opt->p[i], cst); + if (split < 0) + map = isl_map_free(map); + else if (split) + map = isl_map_intersect_domain(map, + isl_set_copy(min_expr)); + map = isl_map_remove_dims(map, isl_dim_in, n_in - 1, 1); + + res = isl_map_union_disjoint(res, map); + } + + isl_map_free(opt); + isl_set_free(min_expr); + isl_mat_free(cst); + return res; +error: + isl_map_free(opt); + isl_set_free(min_expr); + isl_mat_free(cst); + return NULL; +} + +/* Given a set of which the last set variable is the minimum + * of the bounds in "cst", split each basic set in the set + * in pieces where one of the bounds is (strictly) smaller than the others. + * This subdivision is given in "min_expr". + * The variable is subsequently projected out. + */ +static __isl_give isl_set *split(__isl_take isl_set *empty, + __isl_take isl_set *min_expr, __isl_take isl_mat *cst) +{ + isl_map *map; + + map = isl_map_from_domain(empty); + map = split_domain(map, min_expr, cst); + empty = isl_map_domain(map); + + return empty; +} + +static __isl_give isl_map *basic_map_partial_lexopt( + __isl_take isl_basic_map *bmap, __isl_take isl_basic_set *dom, + __isl_give isl_set **empty, int max); + +/* This function is called from basic_map_partial_lexopt_symm. + * The last variable of "bmap" and "dom" corresponds to the minimum + * of the bounds in "cst". "map_space" is the space of the original + * input relation (of basic_map_partial_lexopt_symm) and "set_space" + * is the space of the original domain. + * + * We recursively call basic_map_partial_lexopt and then plug in + * the definition of the minimum in the result. + */ +static __isl_give isl_map *basic_map_partial_lexopt_symm_core( + __isl_take isl_basic_map *bmap, __isl_take isl_basic_set *dom, + __isl_give isl_set **empty, int max, __isl_take isl_mat *cst, + __isl_take isl_space *map_space, __isl_take isl_space *set_space) +{ + isl_map *opt; + isl_set *min_expr; + + min_expr = set_minimum(isl_basic_set_get_space(dom), isl_mat_copy(cst)); + + opt = basic_map_partial_lexopt(bmap, dom, empty, max); + + if (empty) { + *empty = split(*empty, + isl_set_copy(min_expr), isl_mat_copy(cst)); + *empty = isl_set_reset_space(*empty, set_space); + } + + opt = split_domain(opt, min_expr, cst); + opt = isl_map_reset_space(opt, map_space); + + return opt; +} + +/* Extract a domain from "bmap" for the purpose of computing + * a lexicographic optimum. + * + * This function is only called when the caller wants to compute a full + * lexicographic optimum, i.e., without specifying a domain. In this case, + * the caller is not interested in the part of the domain space where + * there is no solution and the domain can be initialized to those constraints + * of "bmap" that only involve the parameters and the input dimensions. + * This relieves the parametric programming engine from detecting those + * inequalities and transferring them to the context. More importantly, + * it ensures that those inequalities are transferred first and not + * intermixed with inequalities that actually split the domain. + * + * If the caller does not require the absence of existentially quantified + * variables in the result (i.e., if ISL_OPT_QE is not set in "flags"), + * then the actual domain of "bmap" can be used. This ensures that + * the domain does not need to be split at all just to separate out + * pieces of the domain that do not have a solution from piece that do. + * This domain cannot be used in general because it may involve + * (unknown) existentially quantified variables which will then also + * appear in the solution. + */ +static __isl_give isl_basic_set *extract_domain(__isl_keep isl_basic_map *bmap, + unsigned flags) +{ + isl_size n_div; + isl_size n_out; + + n_div = isl_basic_map_dim(bmap, isl_dim_div); + n_out = isl_basic_map_dim(bmap, isl_dim_out); + if (n_div < 0 || n_out < 0) + return NULL; + bmap = isl_basic_map_copy(bmap); + if (ISL_FL_ISSET(flags, ISL_OPT_QE)) { + bmap = isl_basic_map_drop_constraints_involving_dims(bmap, + isl_dim_div, 0, n_div); + bmap = isl_basic_map_drop_constraints_involving_dims(bmap, + isl_dim_out, 0, n_out); + } + return isl_basic_map_domain(bmap); +} + +#undef TYPE +#define TYPE isl_map +#undef SUFFIX +#define SUFFIX +#include "isl_tab_lexopt_templ.c" + +/* Extract the subsequence of the sample value of "tab" + * starting at "pos" and of length "len". + */ +static __isl_give isl_vec *extract_sample_sequence(struct isl_tab *tab, + int pos, int len) +{ + int i; + isl_ctx *ctx; + isl_vec *v; + + ctx = isl_tab_get_ctx(tab); + v = isl_vec_alloc(ctx, len); + if (!v) + return NULL; + for (i = 0; i < len; ++i) { + if (!tab->var[pos + i].is_row) { + isl_int_set_si(v->el[i], 0); + } else { + int row; + + row = tab->var[pos + i].index; + isl_int_divexact(v->el[i], tab->mat->row[row][1], + tab->mat->row[row][0]); + } + } + + return v; +} + +/* Check if the sequence of variables starting at "pos" + * represents a trivial solution according to "trivial". + * That is, is the result of applying "trivial" to this sequence + * equal to the zero vector? + */ +static isl_bool region_is_trivial(struct isl_tab *tab, int pos, + __isl_keep isl_mat *trivial) +{ + isl_size n, len; + isl_vec *v; + isl_bool is_trivial; + + n = isl_mat_rows(trivial); + if (n < 0) + return isl_bool_error; + + if (n == 0) + return isl_bool_false; + + len = isl_mat_cols(trivial); + if (len < 0) + return isl_bool_error; + v = extract_sample_sequence(tab, pos, len); + v = isl_mat_vec_product(isl_mat_copy(trivial), v); + is_trivial = isl_vec_is_zero(v); + isl_vec_free(v); + + return is_trivial; +} + +/* Global internal data for isl_tab_basic_set_non_trivial_lexmin. + * + * "n_op" is the number of initial coordinates to optimize, + * as passed to isl_tab_basic_set_non_trivial_lexmin. + * "region" is the "n_region"-sized array of regions passed + * to isl_tab_basic_set_non_trivial_lexmin. + * + * "tab" is the tableau that corresponds to the ILP problem. + * "local" is an array of local data structure, one for each + * (potential) level of the backtracking procedure of + * isl_tab_basic_set_non_trivial_lexmin. + * "v" is a pre-allocated vector that can be used for adding + * constraints to the tableau. + * + * "sol" contains the best solution found so far. + * It is initialized to a vector of size zero. + */ +struct isl_lexmin_data { + int n_op; + int n_region; + struct isl_trivial_region *region; + + struct isl_tab *tab; + struct isl_local_region *local; + isl_vec *v; + + isl_vec *sol; +}; + +/* Return the index of the first trivial region, "n_region" if all regions + * are non-trivial or -1 in case of error. + */ +static int first_trivial_region(struct isl_lexmin_data *data) +{ + int i; + + for (i = 0; i < data->n_region; ++i) { + isl_bool trivial; + trivial = region_is_trivial(data->tab, data->region[i].pos, + data->region[i].trivial); + if (trivial < 0) + return -1; + if (trivial) + return i; + } + + return data->n_region; +} + +/* Check if the solution is optimal, i.e., whether the first + * n_op entries are zero. + */ +static int is_optimal(__isl_keep isl_vec *sol, int n_op) +{ + int i; + + for (i = 0; i < n_op; ++i) + if (!isl_int_is_zero(sol->el[1 + i])) + return 0; + return 1; +} + +/* Add constraints to "tab" that ensure that any solution is significantly + * better than that represented by "sol". That is, find the first + * relevant (within first n_op) non-zero coefficient and force it (along + * with all previous coefficients) to be zero. + * If the solution is already optimal (all relevant coefficients are zero), + * then just mark the table as empty. + * "n_zero" is the number of coefficients that have been forced zero + * by previous calls to this function at the same level. + * Return the updated number of forced zero coefficients or -1 on error. + * + * This function assumes that at least 2 * (n_op - n_zero) more rows and + * at least 2 * (n_op - n_zero) more elements in the constraint array + * are available in the tableau. + */ +static int force_better_solution(struct isl_tab *tab, + __isl_keep isl_vec *sol, int n_op, int n_zero) +{ + int i, n; + isl_ctx *ctx; + isl_vec *v = NULL; + + if (!sol) + return -1; + + for (i = n_zero; i < n_op; ++i) + if (!isl_int_is_zero(sol->el[1 + i])) + break; + + if (i == n_op) { + if (isl_tab_mark_empty(tab) < 0) + return -1; + return n_op; + } + + ctx = isl_vec_get_ctx(sol); + v = isl_vec_alloc(ctx, 1 + tab->n_var); + if (!v) + return -1; + + n = i + 1; + for (; i >= n_zero; --i) { + v = isl_vec_clr(v); + isl_int_set_si(v->el[1 + i], -1); + if (add_lexmin_eq(tab, v->el) < 0) + goto error; + } + + isl_vec_free(v); + return n; +error: + isl_vec_free(v); + return -1; +} + +/* Fix triviality direction "dir" of the given region to zero. + * + * This function assumes that at least two more rows and at least + * two more elements in the constraint array are available in the tableau. + */ +static isl_stat fix_zero(struct isl_tab *tab, struct isl_trivial_region *region, + int dir, struct isl_lexmin_data *data) +{ + isl_size len; + + data->v = isl_vec_clr(data->v); + if (!data->v) + return isl_stat_error; + len = isl_mat_cols(region->trivial); + if (len < 0) + return isl_stat_error; + isl_seq_cpy(data->v->el + 1 + region->pos, region->trivial->row[dir], + len); + if (add_lexmin_eq(tab, data->v->el) < 0) + return isl_stat_error; + + return isl_stat_ok; +} + +/* This function selects case "side" for non-triviality region "region", + * assuming all the equality constraints have been imposed already. + * In particular, the triviality direction side/2 is made positive + * if side is even and made negative if side is odd. + * + * This function assumes that at least one more row and at least + * one more element in the constraint array are available in the tableau. + */ +static struct isl_tab *pos_neg(struct isl_tab *tab, + struct isl_trivial_region *region, + int side, struct isl_lexmin_data *data) +{ + isl_size len; + + data->v = isl_vec_clr(data->v); + if (!data->v) + goto error; + isl_int_set_si(data->v->el[0], -1); + len = isl_mat_cols(region->trivial); + if (len < 0) + goto error; + if (side % 2 == 0) + isl_seq_cpy(data->v->el + 1 + region->pos, + region->trivial->row[side / 2], len); + else + isl_seq_neg(data->v->el + 1 + region->pos, + region->trivial->row[side / 2], len); + return add_lexmin_ineq(tab, data->v->el); +error: + isl_tab_free(tab); + return NULL; +} + +/* Local data at each level of the backtracking procedure of + * isl_tab_basic_set_non_trivial_lexmin. + * + * "update" is set if a solution has been found in the current case + * of this level, such that a better solution needs to be enforced + * in the next case. + * "n_zero" is the number of initial coordinates that have already + * been forced to be zero at this level. + * "region" is the non-triviality region considered at this level. + * "side" is the index of the current case at this level. + * "n" is the number of triviality directions. + * "snap" is a snapshot of the tableau holding a state that needs + * to be satisfied by all subsequent cases. + */ +struct isl_local_region { + int update; + int n_zero; + int region; + int side; + int n; + struct isl_tab_undo *snap; +}; + +/* Initialize the global data structure "data" used while solving + * the ILP problem "bset". + */ +static isl_stat init_lexmin_data(struct isl_lexmin_data *data, + __isl_keep isl_basic_set *bset) +{ + isl_ctx *ctx; + + ctx = isl_basic_set_get_ctx(bset); + + data->tab = tab_for_lexmin(bset, NULL, 0, 0); + if (!data->tab) + return isl_stat_error; + + data->v = isl_vec_alloc(ctx, 1 + data->tab->n_var); + if (!data->v) + return isl_stat_error; + data->local = isl_calloc_array(ctx, struct isl_local_region, + data->n_region); + if (data->n_region && !data->local) + return isl_stat_error; + + data->sol = isl_vec_alloc(ctx, 0); + + return isl_stat_ok; +} + +/* Mark all outer levels as requiring a better solution + * in the next cases. + */ +static void update_outer_levels(struct isl_lexmin_data *data, int level) +{ + int i; + + for (i = 0; i < level; ++i) + data->local[i].update = 1; +} + +/* Initialize "local" to refer to region "region" and + * to initiate processing at this level. + */ +static isl_stat init_local_region(struct isl_local_region *local, int region, + struct isl_lexmin_data *data) +{ + isl_size n = isl_mat_rows(data->region[region].trivial); + + if (n < 0) + return isl_stat_error; + local->n = n; + local->region = region; + local->side = 0; + local->update = 0; + local->n_zero = 0; + + return isl_stat_ok; +} + +/* What to do next after entering a level of the backtracking procedure. + * + * error: some error has occurred; abort + * done: an optimal solution has been found; stop search + * backtrack: backtrack to the previous level + * handle: add the constraints for the current level and + * move to the next level + */ +enum isl_next { + isl_next_error = -1, + isl_next_done, + isl_next_backtrack, + isl_next_handle, +}; + +/* Have all cases of the current region been considered? + * If there are n directions, then there are 2n cases. + * + * The constraints in the current tableau are imposed + * in all subsequent cases. This means that if the current + * tableau is empty, then none of those cases should be considered + * anymore and all cases have effectively been considered. + */ +static int finished_all_cases(struct isl_local_region *local, + struct isl_lexmin_data *data) +{ + if (data->tab->empty) + return 1; + return local->side >= 2 * local->n; +} + +/* Enter level "level" of the backtracking search and figure out + * what to do next. "init" is set if the level was entered + * from a higher level and needs to be initialized. + * Otherwise, the level is entered as a result of backtracking and + * the tableau needs to be restored to a position that can + * be used for the next case at this level. + * The snapshot is assumed to have been saved in the previous case, + * before the constraints specific to that case were added. + * + * In the initialization case, the local region is initialized + * to point to the first violated region. + * If the constraints of all regions are satisfied by the current + * sample of the tableau, then tell the caller to continue looking + * for a better solution or to stop searching if an optimal solution + * has been found. + * + * If the tableau is empty or if all cases at the current level + * have been considered, then the caller needs to backtrack as well. + */ +static enum isl_next enter_level(int level, int init, + struct isl_lexmin_data *data) +{ + struct isl_local_region *local = &data->local[level]; + + if (init) { + int r; + + data->tab = cut_to_integer_lexmin(data->tab, CUT_ONE); + if (!data->tab) + return isl_next_error; + if (data->tab->empty) + return isl_next_backtrack; + r = first_trivial_region(data); + if (r < 0) + return isl_next_error; + if (r == data->n_region) { + update_outer_levels(data, level); + isl_vec_free(data->sol); + data->sol = isl_tab_get_sample_value(data->tab); + if (!data->sol) + return isl_next_error; + if (is_optimal(data->sol, data->n_op)) + return isl_next_done; + return isl_next_backtrack; + } + if (level >= data->n_region) + isl_die(isl_vec_get_ctx(data->v), isl_error_internal, + "nesting level too deep", + return isl_next_error); + if (init_local_region(local, r, data) < 0) + return isl_next_error; + if (isl_tab_extend_cons(data->tab, + 2 * local->n + 2 * data->n_op) < 0) + return isl_next_error; + } else { + if (isl_tab_rollback(data->tab, local->snap) < 0) + return isl_next_error; + } + + if (finished_all_cases(local, data)) + return isl_next_backtrack; + return isl_next_handle; +} + +/* If a solution has been found in the previous case at this level + * (marked by local->update being set), then add constraints + * that enforce a better solution in the present and all following cases. + * The constraints only need to be imposed once because they are + * included in the snapshot (taken in pick_side) that will be used in + * subsequent cases. + */ +static isl_stat better_next_side(struct isl_local_region *local, + struct isl_lexmin_data *data) +{ + if (!local->update) + return isl_stat_ok; + + local->n_zero = force_better_solution(data->tab, + data->sol, data->n_op, local->n_zero); + if (local->n_zero < 0) + return isl_stat_error; + + local->update = 0; + + return isl_stat_ok; +} + +/* Add constraints to data->tab that select the current case (local->side) + * at the current level. + * + * If the linear combinations v should not be zero, then the cases are + * v_0 >= 1 + * v_0 <= -1 + * v_0 = 0 and v_1 >= 1 + * v_0 = 0 and v_1 <= -1 + * v_0 = 0 and v_1 = 0 and v_2 >= 1 + * v_0 = 0 and v_1 = 0 and v_2 <= -1 + * ... + * in this order. + * + * A snapshot is taken after the equality constraint (if any) has been added + * such that the next case can start off from this position. + * The rollback to this position is performed in enter_level. + */ +static isl_stat pick_side(struct isl_local_region *local, + struct isl_lexmin_data *data) +{ + struct isl_trivial_region *region; + int side, base; + + region = &data->region[local->region]; + side = local->side; + base = 2 * (side/2); + + if (side == base && base >= 2 && + fix_zero(data->tab, region, base / 2 - 1, data) < 0) + return isl_stat_error; + + local->snap = isl_tab_snap(data->tab); + if (isl_tab_push_basis(data->tab) < 0) + return isl_stat_error; + + data->tab = pos_neg(data->tab, region, side, data); + if (!data->tab) + return isl_stat_error; + return isl_stat_ok; +} + +/* Free the memory associated to "data". + */ +static void clear_lexmin_data(struct isl_lexmin_data *data) +{ + free(data->local); + isl_vec_free(data->v); + isl_tab_free(data->tab); +} + +/* Return the lexicographically smallest non-trivial solution of the + * given ILP problem. + * + * All variables are assumed to be non-negative. + * + * n_op is the number of initial coordinates to optimize. + * That is, once a solution has been found, we will only continue looking + * for solutions that result in significantly better values for those + * initial coordinates. That is, we only continue looking for solutions + * that increase the number of initial zeros in this sequence. + * + * A solution is non-trivial, if it is non-trivial on each of the + * specified regions. Each region represents a sequence of + * triviality directions on a sequence of variables that starts + * at a given position. A solution is non-trivial on such a region if + * at least one of the triviality directions is non-zero + * on that sequence of variables. + * + * Whenever a conflict is encountered, all constraints involved are + * reported to the caller through a call to "conflict". + * + * We perform a simple branch-and-bound backtracking search. + * Each level in the search represents an initially trivial region + * that is forced to be non-trivial. + * At each level we consider 2 * n cases, where n + * is the number of triviality directions. + * In terms of those n directions v_i, we consider the cases + * v_0 >= 1 + * v_0 <= -1 + * v_0 = 0 and v_1 >= 1 + * v_0 = 0 and v_1 <= -1 + * v_0 = 0 and v_1 = 0 and v_2 >= 1 + * v_0 = 0 and v_1 = 0 and v_2 <= -1 + * ... + * in this order. + */ +__isl_give isl_vec *isl_tab_basic_set_non_trivial_lexmin( + __isl_take isl_basic_set *bset, int n_op, int n_region, + struct isl_trivial_region *region, + int (*conflict)(int con, void *user), void *user) +{ + struct isl_lexmin_data data = { n_op, n_region, region }; + int level, init; + + if (!bset) + return NULL; + + if (init_lexmin_data(&data, bset) < 0) + goto error; + data.tab->conflict = conflict; + data.tab->conflict_user = user; + + level = 0; + init = 1; + + while (level >= 0) { + enum isl_next next; + struct isl_local_region *local = &data.local[level]; + + next = enter_level(level, init, &data); + if (next < 0) + goto error; + if (next == isl_next_done) + break; + if (next == isl_next_backtrack) { + level--; + init = 0; + continue; + } + + if (better_next_side(local, &data) < 0) + goto error; + if (pick_side(local, &data) < 0) + goto error; + + local->side++; + level++; + init = 1; + } + + clear_lexmin_data(&data); + isl_basic_set_free(bset); + + return data.sol; +error: + clear_lexmin_data(&data); + isl_basic_set_free(bset); + isl_vec_free(data.sol); + return NULL; +} + +/* Wrapper for a tableau that is used for computing + * the lexicographically smallest rational point of a non-negative set. + * This point is represented by the sample value of "tab", + * unless "tab" is empty. + */ +struct isl_tab_lexmin { + isl_ctx *ctx; + struct isl_tab *tab; +}; + +/* Free "tl" and return NULL. + */ +__isl_null isl_tab_lexmin *isl_tab_lexmin_free(__isl_take isl_tab_lexmin *tl) +{ + if (!tl) + return NULL; + isl_ctx_deref(tl->ctx); + isl_tab_free(tl->tab); + free(tl); + + return NULL; +} + +/* Construct an isl_tab_lexmin for computing + * the lexicographically smallest rational point in "bset", + * assuming that all variables are non-negative. + */ +__isl_give isl_tab_lexmin *isl_tab_lexmin_from_basic_set( + __isl_take isl_basic_set *bset) +{ + isl_ctx *ctx; + isl_tab_lexmin *tl; + + if (!bset) + return NULL; + + ctx = isl_basic_set_get_ctx(bset); + tl = isl_calloc_type(ctx, struct isl_tab_lexmin); + if (!tl) + goto error; + tl->ctx = ctx; + isl_ctx_ref(ctx); + tl->tab = tab_for_lexmin(bset, NULL, 0, 0); + isl_basic_set_free(bset); + if (!tl->tab) + return isl_tab_lexmin_free(tl); + return tl; +error: + isl_basic_set_free(bset); + isl_tab_lexmin_free(tl); + return NULL; +} + +/* Return the dimension of the set represented by "tl". + */ +int isl_tab_lexmin_dim(__isl_keep isl_tab_lexmin *tl) +{ + return tl ? tl->tab->n_var : -1; +} + +/* Add the equality with coefficients "eq" to "tl", updating the optimal + * solution if needed. + * The equality is added as two opposite inequality constraints. + */ +__isl_give isl_tab_lexmin *isl_tab_lexmin_add_eq(__isl_take isl_tab_lexmin *tl, + isl_int *eq) +{ + unsigned n_var; + + if (!tl || !eq) + return isl_tab_lexmin_free(tl); + + if (isl_tab_extend_cons(tl->tab, 2) < 0) + return isl_tab_lexmin_free(tl); + n_var = tl->tab->n_var; + isl_seq_neg(eq, eq, 1 + n_var); + tl->tab = add_lexmin_ineq(tl->tab, eq); + isl_seq_neg(eq, eq, 1 + n_var); + tl->tab = add_lexmin_ineq(tl->tab, eq); + + if (!tl->tab) + return isl_tab_lexmin_free(tl); + + return tl; +} + +/* Add cuts to "tl" until the sample value reaches an integer value or + * until the result becomes empty. + */ +__isl_give isl_tab_lexmin *isl_tab_lexmin_cut_to_integer( + __isl_take isl_tab_lexmin *tl) +{ + if (!tl) + return NULL; + tl->tab = cut_to_integer_lexmin(tl->tab, CUT_ONE); + if (!tl->tab) + return isl_tab_lexmin_free(tl); + return tl; +} + +/* Return the lexicographically smallest rational point in the basic set + * from which "tl" was constructed. + * If the original input was empty, then return a zero-length vector. + */ +__isl_give isl_vec *isl_tab_lexmin_get_solution(__isl_keep isl_tab_lexmin *tl) +{ + if (!tl) + return NULL; + if (tl->tab->empty) + return isl_vec_alloc(tl->ctx, 0); + else + return isl_tab_get_sample_value(tl->tab); +} + +struct isl_sol_pma { + struct isl_sol sol; + isl_pw_multi_aff *pma; + isl_set *empty; +}; + +static void sol_pma_free(struct isl_sol *sol) +{ + struct isl_sol_pma *sol_pma = (struct isl_sol_pma *) sol; + isl_pw_multi_aff_free(sol_pma->pma); + isl_set_free(sol_pma->empty); +} + +/* This function is called for parts of the context where there is + * no solution, with "bset" corresponding to the context tableau. + * Simply add the basic set to the set "empty". + */ +static void sol_pma_add_empty(struct isl_sol_pma *sol, + __isl_take isl_basic_set *bset) +{ + if (!bset || !sol->empty) + goto error; + + sol->empty = isl_set_grow(sol->empty, 1); + bset = isl_basic_set_simplify(bset); + bset = isl_basic_set_finalize(bset); + sol->empty = isl_set_add_basic_set(sol->empty, bset); + if (!sol->empty) + sol->sol.error = 1; + return; +error: + isl_basic_set_free(bset); + sol->sol.error = 1; +} + +/* Given a basic set "dom" that represents the context and a tuple of + * affine expressions "maff" defined over this domain, construct + * an isl_pw_multi_aff with a single cell corresponding to "dom" and + * the affine expressions in "maff". + */ +static void sol_pma_add(struct isl_sol_pma *sol, + __isl_take isl_basic_set *dom, __isl_take isl_multi_aff *maff) +{ + isl_pw_multi_aff *pma; + + dom = isl_basic_set_simplify(dom); + dom = isl_basic_set_finalize(dom); + pma = isl_pw_multi_aff_alloc(isl_set_from_basic_set(dom), maff); + sol->pma = isl_pw_multi_aff_add_disjoint(sol->pma, pma); + if (!sol->pma) + sol->sol.error = 1; +} + +static void sol_pma_add_empty_wrap(struct isl_sol *sol, + __isl_take isl_basic_set *bset) +{ + sol_pma_add_empty((struct isl_sol_pma *)sol, bset); +} + +static void sol_pma_add_wrap(struct isl_sol *sol, + __isl_take isl_basic_set *dom, __isl_take isl_multi_aff *ma) +{ + sol_pma_add((struct isl_sol_pma *)sol, dom, ma); +} + +/* Construct an isl_sol_pma structure for accumulating the solution. + * If track_empty is set, then we also keep track of the parts + * of the context where there is no solution. + * If max is set, then we are solving a maximization, rather than + * a minimization problem, which means that the variables in the + * tableau have value "M - x" rather than "M + x". + */ +static struct isl_sol *sol_pma_init(__isl_keep isl_basic_map *bmap, + __isl_take isl_basic_set *dom, int track_empty, int max) +{ + struct isl_sol_pma *sol_pma = NULL; + isl_space *space; + + if (!bmap) + goto error; + + sol_pma = isl_calloc_type(bmap->ctx, struct isl_sol_pma); + if (!sol_pma) + goto error; + + sol_pma->sol.free = &sol_pma_free; + if (sol_init(&sol_pma->sol, bmap, dom, max) < 0) + goto error; + sol_pma->sol.add = &sol_pma_add_wrap; + sol_pma->sol.add_empty = track_empty ? &sol_pma_add_empty_wrap : NULL; + space = isl_space_copy(sol_pma->sol.space); + sol_pma->pma = isl_pw_multi_aff_empty(space); + if (!sol_pma->pma) + goto error; + + if (track_empty) { + sol_pma->empty = isl_set_alloc_space(isl_basic_set_get_space(dom), + 1, ISL_SET_DISJOINT); + if (!sol_pma->empty) + goto error; + } + + isl_basic_set_free(dom); + return &sol_pma->sol; +error: + isl_basic_set_free(dom); + sol_free(&sol_pma->sol); + return NULL; +} + +/* Base case of isl_tab_basic_map_partial_lexopt, after removing + * some obvious symmetries. + * + * We call basic_map_partial_lexopt_base_sol and extract the results. + */ +static __isl_give isl_pw_multi_aff *basic_map_partial_lexopt_base_pw_multi_aff( + __isl_take isl_basic_map *bmap, __isl_take isl_basic_set *dom, + __isl_give isl_set **empty, int max) +{ + isl_pw_multi_aff *result = NULL; + struct isl_sol *sol; + struct isl_sol_pma *sol_pma; + + sol = basic_map_partial_lexopt_base_sol(bmap, dom, empty, max, + &sol_pma_init); + if (!sol) + return NULL; + sol_pma = (struct isl_sol_pma *) sol; + + result = isl_pw_multi_aff_copy(sol_pma->pma); + if (empty) + *empty = isl_set_copy(sol_pma->empty); + sol_free(&sol_pma->sol); + return result; +} + +/* Given that the last input variable of "maff" represents the minimum + * of some bounds, check whether we need to plug in the expression + * of the minimum. + * + * In particular, check if the last input variable appears in any + * of the expressions in "maff". + */ +static isl_bool need_substitution(__isl_keep isl_multi_aff *maff) +{ + int i; + isl_size n_in; + unsigned pos; + + n_in = isl_multi_aff_dim(maff, isl_dim_in); + if (n_in < 0) + return isl_bool_error; + pos = n_in - 1; + + for (i = 0; i < maff->n; ++i) { + isl_bool involves; + + involves = isl_aff_involves_dims(maff->u.p[i], + isl_dim_in, pos, 1); + if (involves < 0 || involves) + return involves; + } + + return isl_bool_false; +} + +/* Given a set of upper bounds on the last "input" variable m, + * construct a piecewise affine expression that selects + * the minimal upper bound to m, i.e., + * divide the space into cells where one + * of the upper bounds is smaller than all the others and select + * this upper bound on that cell. + * + * In particular, if there are n bounds b_i, then the result + * consists of n cell, each one of the form + * + * b_i <= b_j for j > i + * b_i < b_j for j < i + * + * The affine expression on this cell is + * + * b_i + */ +static __isl_give isl_pw_aff *set_minimum_pa(__isl_take isl_space *space, + __isl_take isl_mat *var) +{ + int i; + isl_aff *aff = NULL; + isl_basic_set *bset = NULL; + isl_pw_aff *paff = NULL; + isl_space *pw_space; + isl_local_space *ls = NULL; + + if (!space || !var) + goto error; + + ls = isl_local_space_from_space(isl_space_copy(space)); + pw_space = isl_space_copy(space); + pw_space = isl_space_from_domain(pw_space); + pw_space = isl_space_add_dims(pw_space, isl_dim_out, 1); + paff = isl_pw_aff_alloc_size(pw_space, var->n_row); + + for (i = 0; i < var->n_row; ++i) { + isl_pw_aff *paff_i; + + aff = isl_aff_alloc(isl_local_space_copy(ls)); + bset = isl_basic_set_alloc_space(isl_space_copy(space), 0, + 0, var->n_row - 1); + if (!aff || !bset) + goto error; + isl_int_set_si(aff->v->el[0], 1); + isl_seq_cpy(aff->v->el + 1, var->row[i], var->n_col); + isl_int_set_si(aff->v->el[1 + var->n_col], 0); + bset = select_minimum(bset, var, i); + paff_i = isl_pw_aff_alloc(isl_set_from_basic_set(bset), aff); + paff = isl_pw_aff_add_disjoint(paff, paff_i); + } + + isl_local_space_free(ls); + isl_space_free(space); + isl_mat_free(var); + return paff; +error: + isl_aff_free(aff); + isl_basic_set_free(bset); + isl_pw_aff_free(paff); + isl_local_space_free(ls); + isl_space_free(space); + isl_mat_free(var); + return NULL; +} + +/* Given a piecewise multi-affine expression of which the last input variable + * is the minimum of the bounds in "cst", plug in the value of the minimum. + * This minimum expression is given in "min_expr_pa". + * The set "min_expr" contains the same information, but in the form of a set. + * The variable is subsequently projected out. + * + * The implementation is similar to those of "split" and "split_domain". + * If the variable appears in a given expression, then minimum expression + * is plugged in. Otherwise, if the variable appears in the constraints + * and a split is required, then the domain is split. Otherwise, no split + * is performed. + */ +static __isl_give isl_pw_multi_aff *split_domain_pma( + __isl_take isl_pw_multi_aff *opt, __isl_take isl_pw_aff *min_expr_pa, + __isl_take isl_set *min_expr, __isl_take isl_mat *cst) +{ + isl_size n_in; + int i; + isl_space *space; + isl_pw_multi_aff *res; + + if (!opt || !min_expr || !cst) + goto error; + + n_in = isl_pw_multi_aff_dim(opt, isl_dim_in); + if (n_in < 0) + goto error; + space = isl_pw_multi_aff_get_space(opt); + space = isl_space_drop_dims(space, isl_dim_in, n_in - 1, 1); + res = isl_pw_multi_aff_empty(space); + + for (i = 0; i < opt->n; ++i) { + isl_bool subs; + isl_pw_multi_aff *pma; + + pma = isl_pw_multi_aff_alloc(isl_set_copy(opt->p[i].set), + isl_multi_aff_copy(opt->p[i].maff)); + subs = need_substitution(opt->p[i].maff); + if (subs < 0) { + pma = isl_pw_multi_aff_free(pma); + } else if (subs) { + pma = isl_pw_multi_aff_substitute(pma, + n_in - 1, min_expr_pa); + } else { + isl_bool split; + split = need_split_set(opt->p[i].set, cst); + if (split < 0) + pma = isl_pw_multi_aff_free(pma); + else if (split) + pma = isl_pw_multi_aff_intersect_domain(pma, + isl_set_copy(min_expr)); + } + pma = isl_pw_multi_aff_project_out(pma, + isl_dim_in, n_in - 1, 1); + + res = isl_pw_multi_aff_add_disjoint(res, pma); + } + + isl_pw_multi_aff_free(opt); + isl_pw_aff_free(min_expr_pa); + isl_set_free(min_expr); + isl_mat_free(cst); + return res; +error: + isl_pw_multi_aff_free(opt); + isl_pw_aff_free(min_expr_pa); + isl_set_free(min_expr); + isl_mat_free(cst); + return NULL; +} + +static __isl_give isl_pw_multi_aff *basic_map_partial_lexopt_pw_multi_aff( + __isl_take isl_basic_map *bmap, __isl_take isl_basic_set *dom, + __isl_give isl_set **empty, int max); + +/* This function is called from basic_map_partial_lexopt_symm. + * The last variable of "bmap" and "dom" corresponds to the minimum + * of the bounds in "cst". "map_space" is the space of the original + * input relation (of basic_map_partial_lexopt_symm) and "set_space" + * is the space of the original domain. + * + * We recursively call basic_map_partial_lexopt and then plug in + * the definition of the minimum in the result. + */ +static __isl_give isl_pw_multi_aff * +basic_map_partial_lexopt_symm_core_pw_multi_aff( + __isl_take isl_basic_map *bmap, __isl_take isl_basic_set *dom, + __isl_give isl_set **empty, int max, __isl_take isl_mat *cst, + __isl_take isl_space *map_space, __isl_take isl_space *set_space) +{ + isl_pw_multi_aff *opt; + isl_pw_aff *min_expr_pa; + isl_set *min_expr; + + min_expr = set_minimum(isl_basic_set_get_space(dom), isl_mat_copy(cst)); + min_expr_pa = set_minimum_pa(isl_basic_set_get_space(dom), + isl_mat_copy(cst)); + + opt = basic_map_partial_lexopt_pw_multi_aff(bmap, dom, empty, max); + + if (empty) { + *empty = split(*empty, + isl_set_copy(min_expr), isl_mat_copy(cst)); + *empty = isl_set_reset_space(*empty, set_space); + } + + opt = split_domain_pma(opt, min_expr_pa, min_expr, cst); + opt = isl_pw_multi_aff_reset_space(opt, map_space); + + return opt; +} + +#undef TYPE +#define TYPE isl_pw_multi_aff +#undef SUFFIX +#define SUFFIX _pw_multi_aff +#include "isl_tab_lexopt_templ.c" diff --git a/external/mit/isl/dist/isl_tarjan.c b/external/mit/isl/dist/isl_tarjan.c new file mode 100644 index 000000000000..a958c016e0be --- /dev/null +++ b/external/mit/isl/dist/isl_tarjan.c @@ -0,0 +1,159 @@ +/* + * Copyright 2010-2011 INRIA Saclay + * Copyright 2012 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 +#include +#include + +struct isl_tarjan_graph *isl_tarjan_graph_free(struct isl_tarjan_graph *g) +{ + if (!g) + return NULL; + free(g->node); + free(g->stack); + free(g->order); + free(g); + return NULL; +} + +static struct isl_tarjan_graph *isl_tarjan_graph_alloc(isl_ctx *ctx, int len) +{ + struct isl_tarjan_graph *g; + int i; + + g = isl_calloc_type(ctx, struct isl_tarjan_graph); + if (!g) + return NULL; + g->len = len; + g->node = isl_alloc_array(ctx, struct isl_tarjan_node, len); + if (len && !g->node) + goto error; + for (i = 0; i < len; ++i) + g->node[i].index = -1; + g->stack = isl_alloc_array(ctx, int, len); + if (len && !g->stack) + goto error; + g->order = isl_alloc_array(ctx, int, 2 * len); + if (len && !g->order) + goto error; + + g->sp = 0; + g->index = 0; + g->op = 0; + + return g; +error: + isl_tarjan_graph_free(g); + return NULL; +} + +/* Perform Tarjan's algorithm for computing the strongly connected components + * in the graph with g->len nodes and with edges defined by "follows". + */ +static isl_stat isl_tarjan_components(struct isl_tarjan_graph *g, int i, + isl_bool (*follows)(int i, int j, void *user), void *user) +{ + int j; + + g->node[i].index = g->index; + g->node[i].min_index = g->index; + g->node[i].on_stack = 1; + g->index++; + g->stack[g->sp++] = i; + + for (j = g->len - 1; j >= 0; --j) { + isl_bool f; + + if (j == i) + continue; + if (g->node[j].index >= 0 && + (!g->node[j].on_stack || + g->node[j].index > g->node[i].min_index)) + continue; + + f = follows(i, j, user); + if (f < 0) + return isl_stat_error; + if (!f) + continue; + + if (g->node[j].index < 0) { + isl_tarjan_components(g, j, follows, user); + if (g->node[j].min_index < g->node[i].min_index) + g->node[i].min_index = g->node[j].min_index; + } else if (g->node[j].index < g->node[i].min_index) + g->node[i].min_index = g->node[j].index; + } + + if (g->node[i].index != g->node[i].min_index) + return isl_stat_ok; + + do { + j = g->stack[--g->sp]; + g->node[j].on_stack = 0; + g->order[g->op++] = j; + } while (j != i); + g->order[g->op++] = -1; + + return isl_stat_ok; +} + +/* Decompose the graph with "len" nodes and edges defined by "follows" + * into strongly connected components (SCCs). + * follows(i, j, user) should return 1 if "i" follows "j" and 0 otherwise. + * It should return -1 on error. + * + * If SCC a contains a node i that follows a node j in another SCC b + * (i.e., follows(i, j, user) returns 1), then SCC a will appear after SCC b + * in the result. + */ +struct isl_tarjan_graph *isl_tarjan_graph_init(isl_ctx *ctx, int len, + isl_bool (*follows)(int i, int j, void *user), void *user) +{ + int i; + struct isl_tarjan_graph *g = NULL; + + g = isl_tarjan_graph_alloc(ctx, len); + if (!g) + return NULL; + for (i = len - 1; i >= 0; --i) { + if (g->node[i].index >= 0) + continue; + if (isl_tarjan_components(g, i, follows, user) < 0) + return isl_tarjan_graph_free(g); + } + + return g; +} + +/* Decompose the graph with "len" nodes and edges defined by "follows" + * into the strongly connected component (SCC) that contains "node" + * as well as all SCCs that are followed by this SCC. + * follows(i, j, user) should return 1 if "i" follows "j" and 0 otherwise. + * It should return -1 on error. + * + * The SCC containing "node" will appear as the last component + * in g->order. + */ +struct isl_tarjan_graph *isl_tarjan_graph_component(isl_ctx *ctx, int len, + int node, isl_bool (*follows)(int i, int j, void *user), void *user) +{ + struct isl_tarjan_graph *g; + + g = isl_tarjan_graph_alloc(ctx, len); + if (!g) + return NULL; + if (isl_tarjan_components(g, node, follows, user) < 0) + return isl_tarjan_graph_free(g); + + return g; +} diff --git a/external/mit/isl/dist/isl_tarjan.h b/external/mit/isl/dist/isl_tarjan.h new file mode 100644 index 000000000000..af3452cc8679 --- /dev/null +++ b/external/mit/isl/dist/isl_tarjan.h @@ -0,0 +1,42 @@ +#ifndef ISL_TARJAN_H +#define ISL_TARJAN_H + +/* Structure for representing the nodes in the graph being traversed + * using Tarjan's algorithm. + * index represents the order in which nodes are visited. + * min_index is the index of the root of a (sub)component. + * on_stack indicates whether the node is currently on the stack. + */ +struct isl_tarjan_node { + int index; + int min_index; + int on_stack; +}; + +/* Structure for representing the graph being traversed + * using Tarjan's algorithm. + * len is the number of nodes + * node is an array of nodes + * stack contains the nodes on the path from the root to the current node + * sp is the stack pointer + * index is the index of the last node visited + * order contains the elements of the components separated by -1 + * op represents the current position in order + */ +struct isl_tarjan_graph { + int len; + struct isl_tarjan_node *node; + int *stack; + int sp; + int index; + int *order; + int op; +}; + +struct isl_tarjan_graph *isl_tarjan_graph_init(isl_ctx *ctx, int len, + isl_bool (*follows)(int i, int j, void *user), void *user); +struct isl_tarjan_graph *isl_tarjan_graph_component(isl_ctx *ctx, int len, + int node, isl_bool (*follows)(int i, int j, void *user), void *user); +struct isl_tarjan_graph *isl_tarjan_graph_free(struct isl_tarjan_graph *g); + +#endif diff --git a/external/mit/isl/dist/isl_test.c b/external/mit/isl/dist/isl_test.c new file mode 100644 index 000000000000..bd81579c8910 --- /dev/null +++ b/external/mit/isl/dist/isl_test.c @@ -0,0 +1,11004 @@ +/* + * Copyright 2008-2009 Katholieke Universiteit Leuven + * Copyright 2010 INRIA Saclay + * Copyright 2012-2013 Ecole Normale Superieure + * Copyright 2014 INRIA Rocquencourt + * Copyright 2022 Cerebras Systems + * + * 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 + * and Inria Paris - Rocquencourt, Domaine de Voluceau - Rocquencourt, + * B.P. 105 - 78153 Le Chesnay, France + * and Cerebras Systems, 1237 E Arques Ave, Sunnyvale, CA, USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "isl_srcdir.c" + +#define ARRAY_SIZE(array) (sizeof(array)/sizeof(*array)) + +static char *get_filename(isl_ctx *ctx, const char *name, const char *suffix) { + char *filename; + int length; + char *pattern = "%s/test_inputs/%s.%s"; + + length = strlen(pattern) - 6 + strlen(srcdir) + strlen(name) + + strlen(suffix) + 1; + filename = isl_alloc_array(ctx, char, length); + + if (!filename) + return NULL; + + sprintf(filename, pattern, srcdir, name, suffix); + + return filename; +} + +void test_parse_map(isl_ctx *ctx, const char *str) +{ + isl_map *map; + + map = isl_map_read_from_str(ctx, str); + assert(map); + isl_map_free(map); +} + +int test_parse_map_equal(isl_ctx *ctx, const char *str, const char *str2) +{ + isl_map *map, *map2; + int equal; + + map = isl_map_read_from_str(ctx, str); + map2 = isl_map_read_from_str(ctx, str2); + equal = isl_map_is_equal(map, map2); + isl_map_free(map); + isl_map_free(map2); + + if (equal < 0) + return -1; + if (!equal) + isl_die(ctx, isl_error_unknown, "maps not equal", + return -1); + + return 0; +} + +void test_parse_pwqp(isl_ctx *ctx, const char *str) +{ + isl_pw_qpolynomial *pwqp; + + pwqp = isl_pw_qpolynomial_read_from_str(ctx, str); + assert(pwqp); + isl_pw_qpolynomial_free(pwqp); +} + +static void test_parse_pwaff(isl_ctx *ctx, const char *str) +{ + isl_pw_aff *pwaff; + + pwaff = isl_pw_aff_read_from_str(ctx, str); + assert(pwaff); + isl_pw_aff_free(pwaff); +} + +/* Check that we can read an isl_multi_val from "str" without errors. + */ +static int test_parse_multi_val(isl_ctx *ctx, const char *str) +{ + isl_multi_val *mv; + + mv = isl_multi_val_read_from_str(ctx, str); + isl_multi_val_free(mv); + + return mv ? 0 : -1; +} + +/* String descriptions of multi piecewise affine expressions + * that are used for testing printing and parsing. + */ +static const char *reparse_multi_pw_aff_tests[] = { + "{ A[x, y] -> [] : x + y >= 0 }", + "{ A[x, y] -> B[] : x + y >= 0 }", + "{ A[x, y] -> [x] : x + y >= 0 }", + "[N] -> { A[x, y] -> [x] : x + y <= N }", + "{ A[x, y] -> [x, y] : x + y >= 0 }", + "{ A[x, y] -> [(x : x >= 0), (y : y >= 0)] : x + y >= 0 }", + "[N] -> { [] : N >= 0 }", + "[N] -> { [] : N >= 0 }", + "[N] -> { [N] : N >= 0 }", + "[N] -> { [N, N + 1] : N >= 0 }", + "[N, M] -> { [(N : N >= 0), (M : M >= 0)] : N + M >= 0 }", + "{ [a] -> [b = a] }", + "{ [a] -> [b = a] : a >= 0 }", +}; + +#undef BASE +#define BASE multi_pw_aff + +#include "check_reparse_templ.c" +#include "check_reparse_test_templ.c" + +/* String descriptions that cannot be parsed + * as multi piecewise affine expressions. + */ +static const char *parse_multi_pw_aff_fail_tests[] = { + "{ [a] -> [b] : b = a }", + "{ [a] -> [b = a] : b >= 0 }", +}; + +#include "check_parse_fail_test_templ.c" + +/* String descriptions of piecewise multi affine expressions + * that are used for testing printing and parsing. + */ +static const char *reparse_pw_multi_aff_tests[] = { + "{ [x] -> [x] }", + "{ [x] -> [x % 4] }", + "{ [x] -> [x % 4] : x mod 3 = 1 }", + "{ [x, x] -> [x % 4] }", + "{ [x, x + 1] -> [x % 4] : x mod 3 = 1 }", + "{ [x, x mod 2] -> [x % 4] }", + "{ [a] -> [a//2] : exists (e0: 8*floor((-a + e0)/8) <= -8 - a + 8e0) }", + "{ [a, b] -> [(2*floor((a)/8) + floor((b)/6))] }", +}; + +#undef BASE +#define BASE pw_multi_aff + +#include "check_reparse_templ.c" +#include "check_reparse_test_templ.c" + +/* Test parsing of piecewise multi affine expressions by printing + * the expressions and checking that parsing the output results + * in the same expression. + * Do this for an expression converted from a map with an output + * dimension name that is equal to an automatically generated name, and + * a set of expressions parsed from strings. + */ +static isl_stat test_parse_pma(isl_ctx *ctx) +{ + isl_map *map; + isl_pw_multi_aff *pma; + + map = isl_map_read_from_str(ctx, "{ [a, a] -> [i1 = a + 1] }"); + pma = isl_pw_multi_aff_from_map(map); + if (check_reparse_pw_multi_aff(ctx, pma) < 0) + return isl_stat_error; + + if (check_reparse_pw_multi_aff_tests(ctx) < 0) + return isl_stat_error; + + return isl_stat_ok; +} + +/* String descriptions that cannot be parsed + * as union piecewise multi affine expressions. + */ +static const char *parse_union_pw_multi_aff_fail_tests[] = { + "{ [a] -> [b] : b = a }", + "{ [a] -> [b = a] : b >= 0 }", +}; + +#undef BASE +#define BASE union_pw_multi_aff + +#include "check_parse_fail_test_templ.c" + +/* Test parsing of union piecewise multi affine expressions. + * + * In particular, check some cases where parsing is supposed to fail. + */ +static isl_stat test_parse_upma(isl_ctx *ctx) +{ + if (check_parse_union_pw_multi_aff_fail_tests(ctx) < 0) + return isl_stat_error; + + return isl_stat_ok; +} + +/* Test parsing of multi piecewise affine expressions by printing + * the expressions and checking that parsing the output results + * in the same expression. + * Do this for a couple of manually constructed expressions, + * an expression converted from a map with an output dimension name + * that is equal to an automatically generated name, and + * a set of expressions parsed from strings. + * + * Additionally, check some cases where parsing is supposed to fail. + */ +static int test_parse_mpa(isl_ctx *ctx) +{ + isl_space *space; + isl_set *dom; + isl_map *map; + isl_pw_multi_aff *pma; + isl_multi_pw_aff *mpa; + isl_stat r; + + space = isl_space_set_alloc(ctx, 0, 0); + space = isl_space_set_tuple_name(space, isl_dim_set, "A"); + mpa = isl_multi_pw_aff_zero(space); + r = check_reparse_multi_pw_aff(ctx, mpa); + if (r < 0) + return -1; + + space = isl_space_set_alloc(ctx, 1, 0); + space = isl_space_set_dim_name(space, isl_dim_param, 0, "N"); + space = isl_space_set_tuple_name(space, isl_dim_set, "A"); + dom = isl_set_universe(isl_space_params(isl_space_copy(space))); + dom = isl_set_lower_bound_si(dom, isl_dim_param, 0, 5); + mpa = isl_multi_pw_aff_zero(space); + mpa = isl_multi_pw_aff_intersect_domain(mpa, dom); + r = check_reparse_multi_pw_aff(ctx, mpa); + if (r < 0) + return -1; + + map = isl_map_read_from_str(ctx, "{ [a, a] -> [i1 = a + 1] }"); + pma = isl_pw_multi_aff_from_map(map); + mpa = isl_multi_pw_aff_from_pw_multi_aff(pma); + if (check_reparse_multi_pw_aff(ctx, mpa) < 0) + return -1; + + if (check_reparse_multi_pw_aff_tests(ctx) < 0) + return -1; + if (check_parse_multi_pw_aff_fail_tests(ctx) < 0) + return -1; + + return 0; +} + +/* String descriptions of multi union piecewise affine expressions + * that are used for testing printing and parsing. + */ +static const char *reparse_multi_union_pw_aff_tests[] = { + "[]", + "A[]", + "A[B[] -> C[]]", + "(A[] : { S[x] : x > 0; T[y] : y >= 0 })", + "(A[] : { })", + "[N] -> (A[] : { })", + "[N] -> (A[] : { : N >= 0 })", + "[N] -> (A[] : { S[x] : x > N; T[y] : y >= 0 })", + "(A[] : [N] -> { S[x] : x > N; T[y] : y >= 0 })", + "A[{ S[x] -> [x + 1]; T[x] -> [x] }]", + "(A[{ S[x] -> [x + 1]; T[x] -> [x] }] : " + "{ S[x] : x > 0; T[y] : y >= 0 })", +}; + +#undef BASE +#define BASE multi_union_pw_aff + +#include "check_reparse_templ.c" +#include "check_reparse_test_templ.c" + +/* Test parsing of multi union piecewise affine expressions by printing + * the expressions and checking that parsing the output results + * in the same expression. + * Do this for a couple of manually constructed expressions and + * a set of expressions parsed from strings. + */ +static int test_parse_mupa(isl_ctx *ctx) +{ + isl_space *space; + isl_multi_union_pw_aff *mupa; + isl_set *dom; + isl_union_set *uset; + isl_stat r; + + space = isl_space_set_alloc(ctx, 0, 0); + space = isl_space_set_tuple_name(space, isl_dim_set, "A"); + mupa = isl_multi_union_pw_aff_zero(space); + r = check_reparse_multi_union_pw_aff(ctx, mupa); + if (r < 0) + return -1; + + space = isl_space_set_alloc(ctx, 1, 0); + space = isl_space_set_dim_name(space, isl_dim_param, 0, "N"); + space = isl_space_set_tuple_name(space, isl_dim_set, "A"); + dom = isl_set_universe(space); + dom = isl_set_lower_bound_si(dom, isl_dim_param, 0, 5); + uset = isl_union_set_from_set(dom); + space = isl_space_set_alloc(ctx, 1, 0); + space = isl_space_set_dim_name(space, isl_dim_param, 0, "N"); + space = isl_space_set_tuple_name(space, isl_dim_set, "B"); + mupa = isl_multi_union_pw_aff_zero(space); + mupa = isl_multi_union_pw_aff_intersect_domain(mupa, uset); + r = check_reparse_multi_union_pw_aff(ctx, mupa); + if (r < 0) + return -1; + + if (check_reparse_multi_union_pw_aff_tests(ctx) < 0) + return -1; + + return 0; +} + +/* Test parsing of multi expressions. + */ +static int test_parse_multi(isl_ctx *ctx) +{ + if (test_parse_mpa(ctx) < 0) + return -1; + if (test_parse_mupa(ctx) < 0) + return -1; + + return 0; +} + +/* Pairs of binary relation representations that should represent + * the same binary relations. + */ +struct { + const char *map1; + const char *map2; +} parse_map_equal_tests[] = { + { "{ [x,y] : [([x/2]+y)/3] >= 1 }", + "{ [x, y] : 2y >= 6 - x }" }, + { "{ [x,y] : x <= min(y, 2*y+3) }", + "{ [x,y] : x <= y, 2*y + 3 }" }, + { "{ [x,y] : x >= min(y, 2*y+3) }", + "{ [x, y] : (y <= x and y >= -3) or (2y <= -3 + x and y <= -4) }" }, + { "[n] -> { [c1] : c1>=0 and c1<=floord(n-4,3) }", + "[n] -> { [c1] : c1 >= 0 and 3c1 <= -4 + n }" }, + { "{ [i,j] -> [i] : i < j; [i,j] -> [j] : j <= i }", + "{ [i,j] -> [min(i,j)] }" }, + { "{ [i,j] : i != j }", + "{ [i,j] : i < j or i > j }" }, + { "{ [i,j] : (i+1)*2 >= j }", + "{ [i, j] : j <= 2 + 2i }" }, + { "{ [i] -> [i > 0 ? 4 : 5] }", + "{ [i] -> [5] : i <= 0; [i] -> [4] : i >= 1 }" }, + { "[N=2,M] -> { [i=[(M+N)/4]] }", + "[N, M] -> { [i] : N = 2 and 4i <= 2 + M and 4i >= -1 + M }" }, + { "{ [x] : x >= 0 }", + "{ [x] : x-0 >= 0 }" }, + { "{ [i] : ((i > 10)) }", + "{ [i] : i >= 11 }" }, + { "{ [i] -> [0] }", + "{ [i] -> [0 * i] }" }, + { "{ [a] -> [b] : (not false) }", + "{ [a] -> [b] : true }" }, + { "{ [i] : i/2 <= 5 }", + "{ [i] : i <= 10 }" }, + { "{Sym=[n] [i] : i <= n }", + "[n] -> { [i] : i <= n }" }, + { "{ [*] }", + "{ [a] }" }, + { "{ [i] : 2*floor(i/2) = i }", + "{ [i] : exists a : i = 2 a }" }, + { "{ [a] -> [b] : a = 5 implies b = 5 }", + "{ [a] -> [b] : a != 5 or b = 5 }" }, + { "{ [a] -> [a - 1 : a > 0] }", + "{ [a] -> [a - 1] : a > 0 }" }, + { "{ [a] -> [a - 1 : a > 0; a : a <= 0] }", + "{ [a] -> [a - 1] : a > 0; [a] -> [a] : a <= 0 }" }, + { "{ [a] -> [(a) * 2 : a >= 0; 0 : a < 0] }", + "{ [a] -> [2a] : a >= 0; [a] -> [0] : a < 0 }" }, + { "{ [a] -> [(a * 2) : a >= 0; 0 : a < 0] }", + "{ [a] -> [2a] : a >= 0; [a] -> [0] : a < 0 }" }, + { "{ [a] -> [(a * 2 : a >= 0); 0 : a < 0] }", + "{ [a] -> [2a] : a >= 0; [a] -> [0] : a < 0 }" }, + { "{ [a] -> [(a * 2 : a >= 0; 0 : a < 0)] }", + "{ [a] -> [2a] : a >= 0; [a] -> [0] : a < 0 }" }, + { "{ [a,b] -> [i,j] : a,b << i,j }", + "{ [a,b] -> [i,j] : a < i or (a = i and b < j) }" }, + { "{ [a,b] -> [i,j] : a,b <<= i,j }", + "{ [a,b] -> [i,j] : a < i or (a = i and b <= j) }" }, + { "{ [a,b] -> [i,j] : a,b >> i,j }", + "{ [a,b] -> [i,j] : a > i or (a = i and b > j) }" }, + { "{ [a,b] -> [i,j] : a,b >>= i,j }", + "{ [a,b] -> [i,j] : a > i or (a = i and b >= j) }" }, + { "{ [n] -> [i] : exists (a, b, c: 8b <= i - 32a and " + "8b >= -7 + i - 32 a and b >= 0 and b <= 3 and " + "8c < n - 32a and i < n and c >= 0 and " + "c <= 3 and c >= -4a) }", + "{ [n] -> [i] : 0 <= i < n }" }, + { "{ [x] -> [] : exists (a, b: 0 <= a <= 1 and 0 <= b <= 3 and " + "2b <= x - 8a and 2b >= -1 + x - 8a) }", + "{ [x] -> [] : 0 <= x <= 15 }" }, + { "{ [x] -> [x] : }", + "{ [x] -> [x] }" }, + { "{ [x=4:5] -> [x + 1] }", + "{ [x] -> [x + 1] : 4 <= x <= 5 }" }, + { "{ [x=4:5] -> [x + 1 : x + 1] }", + "{ [x=4:5] -> [x + 1] }" }, + { "{ [x] -> [x - 1 : x + 1] }", + "{ [x] -> [y] : x - 1 <= y <= x + 1 }" }, + { "{ [x=4:] -> [x + 1] }", + "{ [x] -> [x + 1] : 4 <= x }" }, + { "{ [x=:5] -> [x + 1] }", + "{ [x] -> [x + 1] : x <= 5 }" }, + { "{ [x=:] -> [x + 1] }", + "{ [x] -> [x + 1] }" }, + { "{ [:] -> [:] }", + "{ [x] -> [y] }" }, + { "{ [x, x//4] }", + "{ [x, floor(x/4)] }" }, + { "{ [10//4] }", + "{ [2] }" }, + { "{ [-1//4] }", + "{ [-1] }" }, + { "{ [0-1//4] }", + "{ [0] }" }, + { "{ [- 1//4] }", + "{ [-1] }" }, + { "{ [0 - 1//4] }", + "{ [0] }" }, + { "{ [0--1//4] }", + "{ [1] }" }, + { "{ [0 - -1//4] }", + "{ [1] }" }, + { "{ [-2^2:2^2-1] }", + "{ [-4:3] }" }, + { "{ [2*-2] }", + "{ [-4] }" }, + { "{ [i,i*-2] }", + "{ [i,-2i] }" }, + { "[a, b, c, d] -> { [max(a,b,c,d)] }", + "[a, b, c, d] -> { [a] : b < a and c < a and d < a; " + "[b] : b >= a and c < b and d < b; " + "[c] : c >= a and c >= b and d < c; " + "[d] : d >= a and d >= b and d >= c }" }, + { "[a, b, c, d] -> { [min(a,b,c,d)] }", + "[a, b, c, d] -> { [a] : b >= a and c >= a and d >= a; " + "[b] : b < a and c >= b and d >= b; " + "[c] : c < b and c < a and d >= c; " + "[d] : d < c and d < b and d < a }" }, +}; + +int test_parse(struct isl_ctx *ctx) +{ + int i; + isl_map *map, *map2; + const char *str, *str2; + + if (test_parse_multi_val(ctx, "{ A[B[2] -> C[5, 7]] }") < 0) + return -1; + if (test_parse_multi_val(ctx, "[n] -> { [2] }") < 0) + return -1; + if (test_parse_multi_val(ctx, "{ A[4, infty, NaN, -1/2, 2/3] }") < 0) + return -1; + if (test_parse_multi(ctx) < 0) + return -1; + if (test_parse_pma(ctx) < 0) + return -1; + if (test_parse_upma(ctx) < 0) + return -1; + + str = "{ [i] -> [-i] }"; + map = isl_map_read_from_str(ctx, str); + assert(map); + isl_map_free(map); + + str = "{ A[i] -> L[([i/3])] }"; + map = isl_map_read_from_str(ctx, str); + assert(map); + isl_map_free(map); + + test_parse_map(ctx, "{[[s] -> A[i]] -> [[s+1] -> A[i]]}"); + test_parse_map(ctx, "{ [p1, y1, y2] -> [2, y1, y2] : " + "p1 = 1 && (y1 <= y2 || y2 = 0) }"); + + for (i = 0; i < ARRAY_SIZE(parse_map_equal_tests); ++i) { + str = parse_map_equal_tests[i].map1; + str2 = parse_map_equal_tests[i].map2; + if (test_parse_map_equal(ctx, str, str2) < 0) + return -1; + } + + str = "{[new,old] -> [new+1-2*[(new+1)/2],old+1-2*[(old+1)/2]]}"; + map = isl_map_read_from_str(ctx, str); + str = "{ [new, old] -> [o0, o1] : " + "exists (e0 = [(-1 - new + o0)/2], e1 = [(-1 - old + o1)/2]: " + "2e0 = -1 - new + o0 and 2e1 = -1 - old + o1 and o0 >= 0 and " + "o0 <= 1 and o1 >= 0 and o1 <= 1) }"; + map2 = isl_map_read_from_str(ctx, str); + assert(isl_map_is_equal(map, map2)); + isl_map_free(map); + isl_map_free(map2); + + str = "{[new,old] -> [new+1-2*[(new+1)/2],old+1-2*[(old+1)/2]]}"; + map = isl_map_read_from_str(ctx, str); + str = "{[new,old] -> [(new+1)%2,(old+1)%2]}"; + map2 = isl_map_read_from_str(ctx, str); + assert(isl_map_is_equal(map, map2)); + isl_map_free(map); + isl_map_free(map2); + + test_parse_pwqp(ctx, "{ [i] -> i + [ (i + [i/3])/2 ] }"); + test_parse_map(ctx, "{ S1[i] -> [([i/10]),i%10] : 0 <= i <= 45 }"); + test_parse_pwaff(ctx, "{ [i] -> [i + 1] : i > 0; [a] -> [a] : a < 0 }"); + test_parse_pwqp(ctx, "{ [x] -> ([(x)/2] * [(x)/3]) }"); + test_parse_pwaff(ctx, "{ [] -> [(100)] }"); + + return 0; +} + +static int test_read(isl_ctx *ctx) +{ + char *filename; + FILE *input; + isl_basic_set *bset1, *bset2; + const char *str = "{[y]: Exists ( alpha : 2alpha = y)}"; + int equal; + + filename = get_filename(ctx, "set", "omega"); + assert(filename); + input = fopen(filename, "r"); + assert(input); + + bset1 = isl_basic_set_read_from_file(ctx, input); + bset2 = isl_basic_set_read_from_str(ctx, str); + + equal = isl_basic_set_is_equal(bset1, bset2); + + isl_basic_set_free(bset1); + isl_basic_set_free(bset2); + free(filename); + + fclose(input); + + if (equal < 0) + return -1; + if (!equal) + isl_die(ctx, isl_error_unknown, + "read sets not equal", return -1); + + return 0; +} + +static int test_bounded(isl_ctx *ctx) +{ + isl_set *set; + isl_bool bounded; + + set = isl_set_read_from_str(ctx, "[n] -> {[i] : 0 <= i <= n }"); + bounded = isl_set_is_bounded(set); + isl_set_free(set); + + if (bounded < 0) + return -1; + if (!bounded) + isl_die(ctx, isl_error_unknown, + "set not considered bounded", return -1); + + set = isl_set_read_from_str(ctx, "{[n, i] : 0 <= i <= n }"); + bounded = isl_set_is_bounded(set); + assert(!bounded); + isl_set_free(set); + + if (bounded < 0) + return -1; + if (bounded) + isl_die(ctx, isl_error_unknown, + "set considered bounded", return -1); + + set = isl_set_read_from_str(ctx, "[n] -> {[i] : i <= n }"); + bounded = isl_set_is_bounded(set); + isl_set_free(set); + + if (bounded < 0) + return -1; + if (bounded) + isl_die(ctx, isl_error_unknown, + "set considered bounded", return -1); + + return 0; +} + +/* Construct the basic set { [i] : 5 <= i <= N } */ +static int test_construction_1(isl_ctx *ctx) +{ + isl_space *space; + isl_local_space *ls; + isl_basic_set *bset; + isl_constraint *c; + + space = isl_space_set_alloc(ctx, 1, 1); + bset = isl_basic_set_universe(isl_space_copy(space)); + ls = isl_local_space_from_space(space); + + c = isl_constraint_alloc_inequality(isl_local_space_copy(ls)); + c = isl_constraint_set_coefficient_si(c, isl_dim_set, 0, -1); + c = isl_constraint_set_coefficient_si(c, isl_dim_param, 0, 1); + bset = isl_basic_set_add_constraint(bset, c); + + c = isl_constraint_alloc_inequality(isl_local_space_copy(ls)); + c = isl_constraint_set_coefficient_si(c, isl_dim_set, 0, 1); + c = isl_constraint_set_constant_si(c, -5); + bset = isl_basic_set_add_constraint(bset, c); + + isl_local_space_free(ls); + isl_basic_set_free(bset); + + return 0; +} + +/* Construct the basic set { [x] : -100 <= x <= 100 } + * using isl_basic_set_{lower,upper}_bound_val and + * check that it is equal the same basic set parsed from a string. + */ +static int test_construction_2(isl_ctx *ctx) +{ + isl_bool equal; + isl_val *v; + isl_space *space; + isl_basic_set *bset1, *bset2; + + v = isl_val_int_from_si(ctx, 100); + space = isl_space_set_alloc(ctx, 0, 1); + bset1 = isl_basic_set_universe(space); + bset1 = isl_basic_set_upper_bound_val(bset1, isl_dim_set, 0, + isl_val_copy(v)); + bset1 = isl_basic_set_lower_bound_val(bset1, isl_dim_set, 0, + isl_val_neg(v)); + bset2 = isl_basic_set_read_from_str(ctx, "{ [x] : -100 <= x <= 100 }"); + equal = isl_basic_set_is_equal(bset1, bset2); + isl_basic_set_free(bset1); + isl_basic_set_free(bset2); + + if (equal < 0) + return -1; + if (!equal) + isl_die(ctx, isl_error_unknown, + "failed construction", return -1); + + return 0; +} + +/* Basic tests for constructing basic sets. + */ +static int test_construction(isl_ctx *ctx) +{ + if (test_construction_1(ctx) < 0) + return -1; + if (test_construction_2(ctx) < 0) + return -1; + return 0; +} + +static int test_dim(isl_ctx *ctx) +{ + const char *str; + isl_map *map1, *map2; + int equal; + + map1 = isl_map_read_from_str(ctx, + "[n] -> { [i] -> [j] : exists (a = [i/10] : i - 10a <= n ) }"); + map1 = isl_map_add_dims(map1, isl_dim_in, 1); + map2 = isl_map_read_from_str(ctx, + "[n] -> { [i,k] -> [j] : exists (a = [i/10] : i - 10a <= n ) }"); + equal = isl_map_is_equal(map1, map2); + isl_map_free(map2); + + map1 = isl_map_project_out(map1, isl_dim_in, 0, 1); + map2 = isl_map_read_from_str(ctx, "[n] -> { [i] -> [j] : n >= 0 }"); + if (equal >= 0 && equal) + equal = isl_map_is_equal(map1, map2); + + isl_map_free(map1); + isl_map_free(map2); + + if (equal < 0) + return -1; + if (!equal) + isl_die(ctx, isl_error_unknown, + "unexpected result", return -1); + + str = "[n] -> { [i] -> [] : exists a : 0 <= i <= n and i = 2 a }"; + map1 = isl_map_read_from_str(ctx, str); + str = "{ [i] -> [j] : exists a : 0 <= i <= j and i = 2 a }"; + map2 = isl_map_read_from_str(ctx, str); + map1 = isl_map_move_dims(map1, isl_dim_out, 0, isl_dim_param, 0, 1); + equal = isl_map_is_equal(map1, map2); + isl_map_free(map1); + isl_map_free(map2); + + if (equal < 0) + return -1; + if (!equal) + isl_die(ctx, isl_error_unknown, + "unexpected result", return -1); + + return 0; +} + +#undef BASE +#define BASE multi_val +#include "isl_test_plain_equal_templ.c" + +#undef BASE +#define BASE multi_aff +#include "isl_test_plain_equal_templ.c" + +/* Check that "val" is equal to the value described by "str". + * If "str" is "NaN", then check for a NaN value explicitly. + */ +static isl_stat val_check_equal(__isl_keep isl_val *val, const char *str) +{ + isl_bool ok, is_nan; + isl_ctx *ctx; + isl_val *res; + + if (!val) + return isl_stat_error; + + ctx = isl_val_get_ctx(val); + res = isl_val_read_from_str(ctx, str); + is_nan = isl_val_is_nan(res); + if (is_nan < 0) + ok = isl_bool_error; + else if (is_nan) + ok = isl_val_is_nan(val); + else + ok = isl_val_eq(val, res); + isl_val_free(res); + if (ok < 0) + return isl_stat_error; + if (!ok) + isl_die(ctx, isl_error_unknown, + "unexpected result", return isl_stat_error); + return isl_stat_ok; +} + +struct { + __isl_give isl_val *(*op)(__isl_take isl_val *v); + const char *arg; + const char *res; +} val_un_tests[] = { + { &isl_val_neg, "0", "0" }, + { &isl_val_abs, "0", "0" }, + { &isl_val_pow2, "0", "1" }, + { &isl_val_floor, "0", "0" }, + { &isl_val_ceil, "0", "0" }, + { &isl_val_neg, "1", "-1" }, + { &isl_val_neg, "-1", "1" }, + { &isl_val_neg, "1/2", "-1/2" }, + { &isl_val_neg, "-1/2", "1/2" }, + { &isl_val_neg, "infty", "-infty" }, + { &isl_val_neg, "-infty", "infty" }, + { &isl_val_neg, "NaN", "NaN" }, + { &isl_val_abs, "1", "1" }, + { &isl_val_abs, "-1", "1" }, + { &isl_val_abs, "1/2", "1/2" }, + { &isl_val_abs, "-1/2", "1/2" }, + { &isl_val_abs, "infty", "infty" }, + { &isl_val_abs, "-infty", "infty" }, + { &isl_val_abs, "NaN", "NaN" }, + { &isl_val_floor, "1", "1" }, + { &isl_val_floor, "-1", "-1" }, + { &isl_val_floor, "1/2", "0" }, + { &isl_val_floor, "-1/2", "-1" }, + { &isl_val_floor, "infty", "infty" }, + { &isl_val_floor, "-infty", "-infty" }, + { &isl_val_floor, "NaN", "NaN" }, + { &isl_val_ceil, "1", "1" }, + { &isl_val_ceil, "-1", "-1" }, + { &isl_val_ceil, "1/2", "1" }, + { &isl_val_ceil, "-1/2", "0" }, + { &isl_val_ceil, "infty", "infty" }, + { &isl_val_ceil, "-infty", "-infty" }, + { &isl_val_ceil, "NaN", "NaN" }, + { &isl_val_pow2, "-3", "1/8" }, + { &isl_val_pow2, "-1", "1/2" }, + { &isl_val_pow2, "1", "2" }, + { &isl_val_pow2, "2", "4" }, + { &isl_val_pow2, "3", "8" }, + { &isl_val_inv, "1", "1" }, + { &isl_val_inv, "2", "1/2" }, + { &isl_val_inv, "1/2", "2" }, + { &isl_val_inv, "-2", "-1/2" }, + { &isl_val_inv, "-1/2", "-2" }, + { &isl_val_inv, "0", "NaN" }, + { &isl_val_inv, "NaN", "NaN" }, + { &isl_val_inv, "infty", "0" }, + { &isl_val_inv, "-infty", "0" }, +}; + +/* Perform some basic tests of unary operations on isl_val objects. + */ +static int test_un_val(isl_ctx *ctx) +{ + int i; + isl_val *v; + __isl_give isl_val *(*fn)(__isl_take isl_val *v); + + for (i = 0; i < ARRAY_SIZE(val_un_tests); ++i) { + isl_stat r; + + v = isl_val_read_from_str(ctx, val_un_tests[i].arg); + fn = val_un_tests[i].op; + v = fn(v); + r = val_check_equal(v, val_un_tests[i].res); + isl_val_free(v); + if (r < 0) + return -1; + } + + return 0; +} + +struct { + __isl_give isl_val *(*fn)(__isl_take isl_val *v1, + __isl_take isl_val *v2); +} val_bin_op[] = { + ['+'] = { &isl_val_add }, + ['-'] = { &isl_val_sub }, + ['*'] = { &isl_val_mul }, + ['/'] = { &isl_val_div }, + ['g'] = { &isl_val_gcd }, + ['m'] = { &isl_val_min }, + ['M'] = { &isl_val_max }, +}; + +struct { + const char *arg1; + unsigned char op; + const char *arg2; + const char *res; +} val_bin_tests[] = { + { "0", '+', "0", "0" }, + { "1", '+', "0", "1" }, + { "1", '+', "1", "2" }, + { "1", '-', "1", "0" }, + { "1", '*', "1", "1" }, + { "1", '/', "1", "1" }, + { "2", '*', "3", "6" }, + { "2", '*', "1/2", "1" }, + { "2", '*', "1/3", "2/3" }, + { "2/3", '*', "3/5", "2/5" }, + { "2/3", '*', "7/5", "14/15" }, + { "2", '/', "1/2", "4" }, + { "-2", '/', "-1/2", "4" }, + { "-2", '/', "1/2", "-4" }, + { "2", '/', "-1/2", "-4" }, + { "2", '/', "2", "1" }, + { "2", '/', "3", "2/3" }, + { "2/3", '/', "5/3", "2/5" }, + { "2/3", '/', "5/7", "14/15" }, + { "0", '/', "0", "NaN" }, + { "42", '/', "0", "NaN" }, + { "-42", '/', "0", "NaN" }, + { "infty", '/', "0", "NaN" }, + { "-infty", '/', "0", "NaN" }, + { "NaN", '/', "0", "NaN" }, + { "0", '/', "NaN", "NaN" }, + { "42", '/', "NaN", "NaN" }, + { "-42", '/', "NaN", "NaN" }, + { "infty", '/', "NaN", "NaN" }, + { "-infty", '/', "NaN", "NaN" }, + { "NaN", '/', "NaN", "NaN" }, + { "0", '/', "infty", "0" }, + { "42", '/', "infty", "0" }, + { "-42", '/', "infty", "0" }, + { "infty", '/', "infty", "NaN" }, + { "-infty", '/', "infty", "NaN" }, + { "NaN", '/', "infty", "NaN" }, + { "0", '/', "-infty", "0" }, + { "42", '/', "-infty", "0" }, + { "-42", '/', "-infty", "0" }, + { "infty", '/', "-infty", "NaN" }, + { "-infty", '/', "-infty", "NaN" }, + { "NaN", '/', "-infty", "NaN" }, + { "1", '-', "1/3", "2/3" }, + { "1/3", '+', "1/2", "5/6" }, + { "1/2", '+', "1/2", "1" }, + { "3/4", '-', "1/4", "1/2" }, + { "1/2", '-', "1/3", "1/6" }, + { "infty", '+', "42", "infty" }, + { "infty", '+', "infty", "infty" }, + { "42", '+', "infty", "infty" }, + { "infty", '-', "infty", "NaN" }, + { "infty", '*', "infty", "infty" }, + { "infty", '*', "-infty", "-infty" }, + { "-infty", '*', "infty", "-infty" }, + { "-infty", '*', "-infty", "infty" }, + { "0", '*', "infty", "NaN" }, + { "1", '*', "infty", "infty" }, + { "infty", '*', "0", "NaN" }, + { "infty", '*', "42", "infty" }, + { "42", '-', "infty", "-infty" }, + { "infty", '+', "-infty", "NaN" }, + { "4", 'g', "6", "2" }, + { "5", 'g', "6", "1" }, + { "42", 'm', "3", "3" }, + { "42", 'M', "3", "42" }, + { "3", 'm', "42", "3" }, + { "3", 'M', "42", "42" }, + { "42", 'm', "infty", "42" }, + { "42", 'M', "infty", "infty" }, + { "42", 'm', "-infty", "-infty" }, + { "42", 'M', "-infty", "42" }, + { "42", 'm', "NaN", "NaN" }, + { "42", 'M', "NaN", "NaN" }, + { "infty", 'm', "-infty", "-infty" }, + { "infty", 'M', "-infty", "infty" }, +}; + +/* Perform some basic tests of binary operations on isl_val objects. + */ +static int test_bin_val(isl_ctx *ctx) +{ + int i; + isl_val *v1, *v2, *res; + __isl_give isl_val *(*fn)(__isl_take isl_val *v1, + __isl_take isl_val *v2); + int ok; + + for (i = 0; i < ARRAY_SIZE(val_bin_tests); ++i) { + v1 = isl_val_read_from_str(ctx, val_bin_tests[i].arg1); + v2 = isl_val_read_from_str(ctx, val_bin_tests[i].arg2); + res = isl_val_read_from_str(ctx, val_bin_tests[i].res); + fn = val_bin_op[val_bin_tests[i].op].fn; + v1 = fn(v1, v2); + if (isl_val_is_nan(res)) + ok = isl_val_is_nan(v1); + else + ok = isl_val_eq(v1, res); + isl_val_free(v1); + isl_val_free(res); + if (ok < 0) + return -1; + if (!ok) + isl_die(ctx, isl_error_unknown, + "unexpected result", return -1); + } + + return 0; +} + +/* Perform some basic tests on isl_val objects. + */ +static int test_val(isl_ctx *ctx) +{ + if (test_un_val(ctx) < 0) + return -1; + if (test_bin_val(ctx) < 0) + return -1; + return 0; +} + +/* Sets described using existentially quantified variables that + * can also be described without. + */ +static const char *elimination_tests[] = { + "{ [i,j] : 2 * [i/2] + 3 * [j/4] <= 10 and 2 i = j }", + "{ [m, w] : exists a : w - 2m - 5 <= 3a <= m - 2w }", + "{ [m, w] : exists a : w >= 0 and a < m and -1 + w <= a <= 2m - w }", +}; + +/* Check that redundant existentially quantified variables are + * getting removed. + */ +static int test_elimination(isl_ctx *ctx) +{ + int i; + isl_size n; + isl_basic_set *bset; + + for (i = 0; i < ARRAY_SIZE(elimination_tests); ++i) { + bset = isl_basic_set_read_from_str(ctx, elimination_tests[i]); + n = isl_basic_set_dim(bset, isl_dim_div); + isl_basic_set_free(bset); + if (n < 0) + return -1; + if (n != 0) + isl_die(ctx, isl_error_unknown, + "expecting no existentials", return -1); + } + + return 0; +} + +static int test_div(isl_ctx *ctx) +{ + const char *str; + int empty; + isl_space *space; + isl_set *set; + isl_local_space *ls; + struct isl_basic_set *bset; + struct isl_constraint *c; + + /* test 1 */ + space = isl_space_set_alloc(ctx, 0, 3); + bset = isl_basic_set_universe(isl_space_copy(space)); + ls = isl_local_space_from_space(space); + + c = isl_constraint_alloc_equality(isl_local_space_copy(ls)); + c = isl_constraint_set_constant_si(c, -1); + c = isl_constraint_set_coefficient_si(c, isl_dim_set, 0, 1); + c = isl_constraint_set_coefficient_si(c, isl_dim_set, 1, 3); + bset = isl_basic_set_add_constraint(bset, c); + + c = isl_constraint_alloc_equality(isl_local_space_copy(ls)); + c = isl_constraint_set_constant_si(c, 1); + c = isl_constraint_set_coefficient_si(c, isl_dim_set, 0, -1); + c = isl_constraint_set_coefficient_si(c, isl_dim_set, 2, 3); + bset = isl_basic_set_add_constraint(bset, c); + + bset = isl_basic_set_project_out(bset, isl_dim_set, 1, 2); + + assert(bset && bset->n_div == 1); + isl_local_space_free(ls); + isl_basic_set_free(bset); + + /* test 2 */ + space = isl_space_set_alloc(ctx, 0, 3); + bset = isl_basic_set_universe(isl_space_copy(space)); + ls = isl_local_space_from_space(space); + + c = isl_constraint_alloc_equality(isl_local_space_copy(ls)); + c = isl_constraint_set_constant_si(c, 1); + c = isl_constraint_set_coefficient_si(c, isl_dim_set, 0, -1); + c = isl_constraint_set_coefficient_si(c, isl_dim_set, 1, 3); + bset = isl_basic_set_add_constraint(bset, c); + + c = isl_constraint_alloc_equality(isl_local_space_copy(ls)); + c = isl_constraint_set_constant_si(c, -1); + c = isl_constraint_set_coefficient_si(c, isl_dim_set, 0, 1); + c = isl_constraint_set_coefficient_si(c, isl_dim_set, 2, 3); + bset = isl_basic_set_add_constraint(bset, c); + + bset = isl_basic_set_project_out(bset, isl_dim_set, 1, 2); + + assert(bset && bset->n_div == 1); + isl_local_space_free(ls); + isl_basic_set_free(bset); + + /* test 3 */ + space = isl_space_set_alloc(ctx, 0, 3); + bset = isl_basic_set_universe(isl_space_copy(space)); + ls = isl_local_space_from_space(space); + + c = isl_constraint_alloc_equality(isl_local_space_copy(ls)); + c = isl_constraint_set_constant_si(c, 1); + c = isl_constraint_set_coefficient_si(c, isl_dim_set, 0, -1); + c = isl_constraint_set_coefficient_si(c, isl_dim_set, 1, 3); + bset = isl_basic_set_add_constraint(bset, c); + + c = isl_constraint_alloc_equality(isl_local_space_copy(ls)); + c = isl_constraint_set_constant_si(c, -3); + c = isl_constraint_set_coefficient_si(c, isl_dim_set, 0, 1); + c = isl_constraint_set_coefficient_si(c, isl_dim_set, 2, 4); + bset = isl_basic_set_add_constraint(bset, c); + + bset = isl_basic_set_project_out(bset, isl_dim_set, 1, 2); + + assert(bset && bset->n_div == 1); + isl_local_space_free(ls); + isl_basic_set_free(bset); + + /* test 4 */ + space = isl_space_set_alloc(ctx, 0, 3); + bset = isl_basic_set_universe(isl_space_copy(space)); + ls = isl_local_space_from_space(space); + + c = isl_constraint_alloc_equality(isl_local_space_copy(ls)); + c = isl_constraint_set_constant_si(c, 2); + c = isl_constraint_set_coefficient_si(c, isl_dim_set, 0, -1); + c = isl_constraint_set_coefficient_si(c, isl_dim_set, 1, 3); + bset = isl_basic_set_add_constraint(bset, c); + + c = isl_constraint_alloc_equality(isl_local_space_copy(ls)); + c = isl_constraint_set_constant_si(c, -1); + c = isl_constraint_set_coefficient_si(c, isl_dim_set, 0, 1); + c = isl_constraint_set_coefficient_si(c, isl_dim_set, 2, 6); + bset = isl_basic_set_add_constraint(bset, c); + + bset = isl_basic_set_project_out(bset, isl_dim_set, 1, 2); + + assert(isl_basic_set_is_empty(bset)); + isl_local_space_free(ls); + isl_basic_set_free(bset); + + /* test 5 */ + space = isl_space_set_alloc(ctx, 0, 3); + bset = isl_basic_set_universe(isl_space_copy(space)); + ls = isl_local_space_from_space(space); + + c = isl_constraint_alloc_equality(isl_local_space_copy(ls)); + c = isl_constraint_set_coefficient_si(c, isl_dim_set, 0, -1); + c = isl_constraint_set_coefficient_si(c, isl_dim_set, 2, 3); + bset = isl_basic_set_add_constraint(bset, c); + + c = isl_constraint_alloc_equality(isl_local_space_copy(ls)); + c = isl_constraint_set_coefficient_si(c, isl_dim_set, 0, 1); + c = isl_constraint_set_coefficient_si(c, isl_dim_set, 1, -3); + bset = isl_basic_set_add_constraint(bset, c); + + bset = isl_basic_set_project_out(bset, isl_dim_set, 2, 1); + + assert(bset && bset->n_div == 0); + isl_basic_set_free(bset); + isl_local_space_free(ls); + + /* test 6 */ + space = isl_space_set_alloc(ctx, 0, 3); + bset = isl_basic_set_universe(isl_space_copy(space)); + ls = isl_local_space_from_space(space); + + c = isl_constraint_alloc_equality(isl_local_space_copy(ls)); + c = isl_constraint_set_coefficient_si(c, isl_dim_set, 0, -1); + c = isl_constraint_set_coefficient_si(c, isl_dim_set, 2, 6); + bset = isl_basic_set_add_constraint(bset, c); + + c = isl_constraint_alloc_equality(isl_local_space_copy(ls)); + c = isl_constraint_set_coefficient_si(c, isl_dim_set, 0, 1); + c = isl_constraint_set_coefficient_si(c, isl_dim_set, 1, -3); + bset = isl_basic_set_add_constraint(bset, c); + + bset = isl_basic_set_project_out(bset, isl_dim_set, 2, 1); + + assert(bset && bset->n_div == 1); + isl_basic_set_free(bset); + isl_local_space_free(ls); + + /* test 7 */ + /* This test is a bit tricky. We set up an equality + * a + 3b + 3c = 6 e0 + * Normalization of divs creates _two_ divs + * a = 3 e0 + * c - b - e0 = 2 e1 + * Afterwards e0 is removed again because it has coefficient -1 + * and we end up with the original equality and div again. + * Perhaps we can avoid the introduction of this temporary div. + */ + space = isl_space_set_alloc(ctx, 0, 4); + bset = isl_basic_set_universe(isl_space_copy(space)); + ls = isl_local_space_from_space(space); + + c = isl_constraint_alloc_equality(isl_local_space_copy(ls)); + c = isl_constraint_set_coefficient_si(c, isl_dim_set, 0, -1); + c = isl_constraint_set_coefficient_si(c, isl_dim_set, 1, -3); + c = isl_constraint_set_coefficient_si(c, isl_dim_set, 2, -3); + c = isl_constraint_set_coefficient_si(c, isl_dim_set, 3, 6); + bset = isl_basic_set_add_constraint(bset, c); + + bset = isl_basic_set_project_out(bset, isl_dim_set, 3, 1); + + /* Test disabled for now */ + /* + assert(bset && bset->n_div == 1); + */ + isl_local_space_free(ls); + isl_basic_set_free(bset); + + /* test 8 */ + space = isl_space_set_alloc(ctx, 0, 5); + bset = isl_basic_set_universe(isl_space_copy(space)); + ls = isl_local_space_from_space(space); + + c = isl_constraint_alloc_equality(isl_local_space_copy(ls)); + c = isl_constraint_set_coefficient_si(c, isl_dim_set, 0, -1); + c = isl_constraint_set_coefficient_si(c, isl_dim_set, 1, -3); + c = isl_constraint_set_coefficient_si(c, isl_dim_set, 3, -3); + c = isl_constraint_set_coefficient_si(c, isl_dim_set, 4, 6); + bset = isl_basic_set_add_constraint(bset, c); + + c = isl_constraint_alloc_equality(isl_local_space_copy(ls)); + c = isl_constraint_set_coefficient_si(c, isl_dim_set, 0, -1); + c = isl_constraint_set_coefficient_si(c, isl_dim_set, 2, 1); + c = isl_constraint_set_constant_si(c, 1); + bset = isl_basic_set_add_constraint(bset, c); + + bset = isl_basic_set_project_out(bset, isl_dim_set, 4, 1); + + /* Test disabled for now */ + /* + assert(bset && bset->n_div == 1); + */ + isl_local_space_free(ls); + isl_basic_set_free(bset); + + /* test 9 */ + space = isl_space_set_alloc(ctx, 0, 4); + bset = isl_basic_set_universe(isl_space_copy(space)); + ls = isl_local_space_from_space(space); + + c = isl_constraint_alloc_equality(isl_local_space_copy(ls)); + c = isl_constraint_set_coefficient_si(c, isl_dim_set, 0, 1); + c = isl_constraint_set_coefficient_si(c, isl_dim_set, 1, -1); + c = isl_constraint_set_coefficient_si(c, isl_dim_set, 2, -2); + bset = isl_basic_set_add_constraint(bset, c); + + c = isl_constraint_alloc_equality(isl_local_space_copy(ls)); + c = isl_constraint_set_coefficient_si(c, isl_dim_set, 0, -1); + c = isl_constraint_set_coefficient_si(c, isl_dim_set, 3, 3); + c = isl_constraint_set_constant_si(c, 2); + bset = isl_basic_set_add_constraint(bset, c); + + bset = isl_basic_set_project_out(bset, isl_dim_set, 2, 2); + + bset = isl_basic_set_fix_si(bset, isl_dim_set, 0, 2); + + assert(!isl_basic_set_is_empty(bset)); + + isl_local_space_free(ls); + isl_basic_set_free(bset); + + /* test 10 */ + space = isl_space_set_alloc(ctx, 0, 3); + bset = isl_basic_set_universe(isl_space_copy(space)); + ls = isl_local_space_from_space(space); + + c = isl_constraint_alloc_equality(isl_local_space_copy(ls)); + c = isl_constraint_set_coefficient_si(c, isl_dim_set, 0, 1); + c = isl_constraint_set_coefficient_si(c, isl_dim_set, 2, -2); + bset = isl_basic_set_add_constraint(bset, c); + + bset = isl_basic_set_project_out(bset, isl_dim_set, 2, 1); + + bset = isl_basic_set_fix_si(bset, isl_dim_set, 0, 2); + + isl_local_space_free(ls); + isl_basic_set_free(bset); + + str = "{ [i] : exists (e0, e1: 3e1 >= 1 + 2e0 and " + "8e1 <= -1 + 5i - 5e0 and 2e1 >= 1 + 2i - 5e0) }"; + set = isl_set_read_from_str(ctx, str); + set = isl_set_compute_divs(set); + isl_set_free(set); + if (!set) + return -1; + + if (test_elimination(ctx) < 0) + return -1; + + str = "{ [i,j,k] : 3 + i + 2j >= 0 and 2 * [(i+2j)/4] <= k }"; + set = isl_set_read_from_str(ctx, str); + set = isl_set_remove_divs_involving_dims(set, isl_dim_set, 0, 2); + set = isl_set_fix_si(set, isl_dim_set, 2, -3); + empty = isl_set_is_empty(set); + isl_set_free(set); + if (empty < 0) + return -1; + if (!empty) + isl_die(ctx, isl_error_unknown, + "result not as accurate as expected", return -1); + + return 0; +} + +void test_application_case(struct isl_ctx *ctx, const char *name) +{ + char *filename; + FILE *input; + struct isl_basic_set *bset1, *bset2; + struct isl_basic_map *bmap; + + filename = get_filename(ctx, name, "omega"); + assert(filename); + input = fopen(filename, "r"); + assert(input); + + bset1 = isl_basic_set_read_from_file(ctx, input); + bmap = isl_basic_map_read_from_file(ctx, input); + + bset1 = isl_basic_set_apply(bset1, bmap); + + bset2 = isl_basic_set_read_from_file(ctx, input); + + assert(isl_basic_set_is_equal(bset1, bset2) == 1); + + isl_basic_set_free(bset1); + isl_basic_set_free(bset2); + free(filename); + + fclose(input); +} + +static int test_application(isl_ctx *ctx) +{ + test_application_case(ctx, "application"); + test_application_case(ctx, "application2"); + + return 0; +} + +void test_affine_hull_case(struct isl_ctx *ctx, const char *name) +{ + char *filename; + FILE *input; + struct isl_basic_set *bset1, *bset2; + + filename = get_filename(ctx, name, "polylib"); + assert(filename); + input = fopen(filename, "r"); + assert(input); + + bset1 = isl_basic_set_read_from_file(ctx, input); + bset2 = isl_basic_set_read_from_file(ctx, input); + + bset1 = isl_basic_set_affine_hull(bset1); + + assert(isl_basic_set_is_equal(bset1, bset2) == 1); + + isl_basic_set_free(bset1); + isl_basic_set_free(bset2); + free(filename); + + fclose(input); +} + +/* Pairs of sets and the corresponding expected results of + * isl_basic_set_recession_cone. + */ +struct { + const char *set; + const char *cone; +} recession_cone_tests[] = { + { "{ [i] : 0 <= i <= 10 }", "{ [0] }" }, + { "{ [i] : 0 <= i }", "{ [i] : 0 <= i }" }, + { "{ [i] : i <= 10 }", "{ [i] : i <= 0 }" }, + { "{ [i] : false }", "{ [i] : false }" }, +}; + +/* Perform some basic isl_basic_set_recession_cone tests. + */ +static int test_recession_cone(struct isl_ctx *ctx) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(recession_cone_tests); ++i) { + const char *str; + isl_basic_set *bset; + isl_basic_set *cone, *expected; + isl_bool equal; + + str = recession_cone_tests[i].set; + bset = isl_basic_set_read_from_str(ctx, str); + str = recession_cone_tests[i].cone; + expected = isl_basic_set_read_from_str(ctx, str); + cone = isl_basic_set_recession_cone(bset); + equal = isl_basic_set_is_equal(cone, expected); + isl_basic_set_free(cone); + isl_basic_set_free(expected); + if (equal < 0) + return -1; + if (!equal) + isl_die(ctx, isl_error_unknown, "unexpected cone", + return -1); + } + + return 0; +} + +int test_affine_hull(struct isl_ctx *ctx) +{ + const char *str; + isl_set *set; + isl_basic_set *bset, *bset2; + isl_size n; + isl_bool subset; + + test_affine_hull_case(ctx, "affine2"); + test_affine_hull_case(ctx, "affine"); + test_affine_hull_case(ctx, "affine3"); + + str = "[m] -> { [i0] : exists (e0, e1: e1 <= 1 + i0 and " + "m >= 3 and 4i0 <= 2 + m and e1 >= i0 and " + "e1 >= 0 and e1 <= 2 and e1 >= 1 + 2e0 and " + "2e1 <= 1 + m + 4e0 and 2e1 >= 2 - m + 4i0 - 4e0) }"; + set = isl_set_read_from_str(ctx, str); + bset = isl_set_affine_hull(set); + n = isl_basic_set_dim(bset, isl_dim_div); + isl_basic_set_free(bset); + if (n < 0) + return -1; + if (n != 0) + isl_die(ctx, isl_error_unknown, "not expecting any divs", + return -1); + + /* Check that isl_map_affine_hull is not confused by + * the reordering of divs in isl_map_align_divs. + */ + str = "{ [a, b, c, 0] : exists (e0 = [(b)/32], e1 = [(c)/32]: " + "32e0 = b and 32e1 = c); " + "[a, 0, c, 0] : exists (e0 = [(c)/32]: 32e0 = c) }"; + set = isl_set_read_from_str(ctx, str); + bset = isl_set_affine_hull(set); + isl_basic_set_free(bset); + if (!bset) + return -1; + + str = "{ [a] : exists e0, e1, e2: 32e1 = 31 + 31a + 31e0 and " + "32e2 = 31 + 31e0 }"; + set = isl_set_read_from_str(ctx, str); + bset = isl_set_affine_hull(set); + str = "{ [a] : exists e : a = 32 e }"; + bset2 = isl_basic_set_read_from_str(ctx, str); + subset = isl_basic_set_is_subset(bset, bset2); + isl_basic_set_free(bset); + isl_basic_set_free(bset2); + if (subset < 0) + return -1; + if (!subset) + isl_die(ctx, isl_error_unknown, "not as accurate as expected", + return -1); + + return 0; +} + +/* Test a special case of isl_set_plain_unshifted_simple_hull + * where older versions of isl would include a redundant constraint + * in the result. + * Check that the result does not have any constraints. + */ +static isl_stat test_plain_unshifted_simple_hull_special(isl_ctx *ctx) +{ + const char *str; + isl_bool is_universe; + isl_set *set; + isl_basic_set *bset; + + str = "{[x, y] : x = 0 or 2*((x+y)//2) <= y + 2 }"; + set = isl_set_read_from_str(ctx, str); + bset = isl_set_plain_unshifted_simple_hull(set); + is_universe = isl_basic_set_plain_is_universe(bset); + isl_basic_set_free(bset); + + if (is_universe < 0) + return isl_stat_error; + if (!is_universe) + isl_die(ctx, isl_error_unknown, + "hull should not have any constraints", + return isl_stat_error); + + return isl_stat_ok; +} + +/* Inputs for simple hull tests, consisting of + * the specific simple hull function, the input set and the expected result. + */ +struct { + __isl_give isl_basic_set *(*fn)(__isl_take isl_set *set); + const char *set; + const char *hull; +} simple_hull_tests[] = { + { &isl_set_plain_unshifted_simple_hull, + "{ [i,j] : i >= 1 and j >= 1 or i >= 2 and j <= 10 }", + "{ [i,j] : i >= 1 }" }, + { &isl_set_plain_unshifted_simple_hull, + "{ [n,i,j,k] : (i mod 3 = 2 and j mod 4 = 2) or " + "(j mod 4 = 2 and k mod 6 = n) }", + "{ [n,i,j,k] : j mod 4 = 2 }" }, + { &isl_set_unshifted_simple_hull, + "{ [0,x,y] : x <= -1; [1,x,y] : x <= y <= -x; [2,x,y] : x <= 1 }", + "{ [t,x,y] : 0 <= t <= 2 and x <= 1 }" }, + { &isl_set_simple_hull, + "{ [a, b] : b <= 0 and " + "2*floor((-2*floor((b)/2))/5) >= a - floor((b)/2); " + "[a, b] : a mod 2 = 0 }", + "{ [a, b] }" }, +}; + +/* Basic tests for various simple hull functions. + */ +static int test_various_simple_hull(isl_ctx *ctx) +{ + int i; + isl_set *set; + isl_basic_set *hull, *expected; + isl_bool equal; + + for (i = 0; i < ARRAY_SIZE(simple_hull_tests); ++i) { + const char *str; + str = simple_hull_tests[i].set; + set = isl_set_read_from_str(ctx, str); + str = simple_hull_tests[i].hull; + expected = isl_basic_set_read_from_str(ctx, str); + hull = simple_hull_tests[i].fn(set); + equal = isl_basic_set_is_equal(hull, expected); + isl_basic_set_free(hull); + isl_basic_set_free(expected); + if (equal < 0) + return -1; + if (!equal) + isl_die(ctx, isl_error_unknown, "unexpected hull", + return -1); + } + + return 0; +} + +static int test_simple_hull(struct isl_ctx *ctx) +{ + const char *str; + isl_set *set; + isl_basic_set *bset; + isl_bool is_empty; + + str = "{ [x, y] : 3y <= 2x and y >= -2 + 2x and 2y >= 2 - x;" + "[y, x] : 3y <= 2x and y >= -2 + 2x and 2y >= 2 - x }"; + set = isl_set_read_from_str(ctx, str); + bset = isl_set_simple_hull(set); + is_empty = isl_basic_set_is_empty(bset); + isl_basic_set_free(bset); + + if (is_empty == isl_bool_error) + return -1; + + if (is_empty == isl_bool_false) + isl_die(ctx, isl_error_unknown, "Empty set should be detected", + return -1); + + if (test_plain_unshifted_simple_hull_special(ctx) < 0) + return -1; + if (test_various_simple_hull(ctx) < 0) + return -1; + + return 0; +} + +/* Inputs for isl_set_get_simple_fixed_box_hull tests. + * "set" is the input set. + * "offset" is the expected box offset. + * "size" is the expected box size. + */ +static struct { + const char *set; + const char *offset; + const char *size; +} box_hull_tests[] = { + { "{ S[x, y] : 0 <= x, y < 10 }", "{ S[0, 0] }", "{ S[10, 10] }" }, + { "[N] -> { S[x, y] : N <= x, y < N + 10 }", + "[N] -> { S[N, N] }", "{ S[10, 10] }" }, + { "{ S[x, y] : 0 <= x + y, x - y < 10 }", + "{ S[0, -4] }", "{ S[10, 9] }" }, + { "{ [i=0:10] : exists (e0, e1: 3e1 >= 1 + 2e0 and " + "8e1 <= -1 + 5i - 5e0 and 2e1 >= 1 + 2i - 5e0) }", + "{ [3] }", "{ [8] }" }, + { "[N] -> { [w = 0:17] : exists (e0: w < 2N and " + "-1 + w <= e0 <= w and 2e0 >= N + w and w <= 2e0 <= 15 + w) }", + "[N] -> { [N] }", "{ [9] }" }, +}; + +/* Perform basic isl_set_get_simple_fixed_box_hull tests. + */ +static int test_box_hull(struct isl_ctx *ctx) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(box_hull_tests); ++i) { + const char *str; + isl_stat r; + isl_set *set; + isl_multi_aff *offset; + isl_multi_val *size; + isl_fixed_box *box; + + set = isl_set_read_from_str(ctx, box_hull_tests[i].set); + box = isl_set_get_simple_fixed_box_hull(set); + offset = isl_fixed_box_get_offset(box); + size = isl_fixed_box_get_size(box); + str = box_hull_tests[i].offset; + r = multi_aff_check_plain_equal(offset, str); + str = box_hull_tests[i].size; + if (r >= 0) + r = multi_val_check_plain_equal(size, str); + isl_multi_aff_free(offset); + isl_multi_val_free(size); + isl_fixed_box_free(box); + isl_set_free(set); + if (r < 0) + return -1; + } + + return 0; +} + +void test_convex_hull_case(struct isl_ctx *ctx, const char *name) +{ + char *filename; + FILE *input; + struct isl_basic_set *bset1, *bset2; + struct isl_set *set; + + filename = get_filename(ctx, name, "polylib"); + assert(filename); + input = fopen(filename, "r"); + assert(input); + + bset1 = isl_basic_set_read_from_file(ctx, input); + bset2 = isl_basic_set_read_from_file(ctx, input); + + set = isl_basic_set_union(bset1, bset2); + bset1 = isl_set_convex_hull(set); + + bset2 = isl_basic_set_read_from_file(ctx, input); + + assert(isl_basic_set_is_equal(bset1, bset2) == 1); + + isl_basic_set_free(bset1); + isl_basic_set_free(bset2); + free(filename); + + fclose(input); +} + +struct { + const char *set; + const char *hull; +} convex_hull_tests[] = { + { "{ [i0, i1, i2] : (i2 = 1 and i0 = 0 and i1 >= 0) or " + "(i0 = 1 and i1 = 0 and i2 = 1) or " + "(i0 = 0 and i1 = 0 and i2 = 0) }", + "{ [i0, i1, i2] : i0 >= 0 and i2 >= i0 and i2 <= 1 and i1 >= 0 }" }, + { "[n] -> { [i0, i1, i0] : i0 <= -4 + n; " + "[i0, i0, i2] : n = 6 and i0 >= 0 and i2 <= 7 - i0 and " + "i2 <= 5 and i2 >= 4; " + "[3, i1, 3] : n = 5 and i1 <= 2 and i1 >= 0 }", + "[n] -> { [i0, i1, i2] : i2 <= -1 + n and 2i2 <= -6 + 3n - i0 and " + "i2 <= 5 + i0 and i2 >= i0 }" }, + { "{ [x, y] : 3y <= 2x and y >= -2 + 2x and 2y >= 2 - x }", + "{ [x, y] : 1 = 0 }" }, + { "{ [x, y, z] : 0 <= x, y, z <= 10; [x, y, 0] : x >= 0 and y > 0; " + "[x, y, 0] : x >= 0 and y < 0 }", + "{ [x, y, z] : x >= 0 and 0 <= z <= 10 }" }, + { "{ [a, b, c] : a <= 1 and -a < b <= 1 and 0 <= c <= 2 - a - b and " + "c <= a; " + "[0, 2, 0]; [3, 1, 0] }", + "{ [a, b, c] : b > -a and 2b >= -1 + a and 0 <= c <= a and " + "5c <= 6 - a - 3b }" }, +}; + +static int test_convex_hull_algo(isl_ctx *ctx, int convex) +{ + int i; + int orig_convex = ctx->opt->convex; + ctx->opt->convex = convex; + + test_convex_hull_case(ctx, "convex0"); + test_convex_hull_case(ctx, "convex1"); + test_convex_hull_case(ctx, "convex2"); + test_convex_hull_case(ctx, "convex3"); + test_convex_hull_case(ctx, "convex4"); + test_convex_hull_case(ctx, "convex5"); + test_convex_hull_case(ctx, "convex6"); + test_convex_hull_case(ctx, "convex7"); + test_convex_hull_case(ctx, "convex8"); + test_convex_hull_case(ctx, "convex9"); + test_convex_hull_case(ctx, "convex10"); + test_convex_hull_case(ctx, "convex11"); + test_convex_hull_case(ctx, "convex12"); + test_convex_hull_case(ctx, "convex13"); + test_convex_hull_case(ctx, "convex14"); + test_convex_hull_case(ctx, "convex15"); + + for (i = 0; i < ARRAY_SIZE(convex_hull_tests); ++i) { + isl_set *set1, *set2; + int equal; + + set1 = isl_set_read_from_str(ctx, convex_hull_tests[i].set); + set2 = isl_set_read_from_str(ctx, convex_hull_tests[i].hull); + set1 = isl_set_from_basic_set(isl_set_convex_hull(set1)); + equal = isl_set_is_equal(set1, set2); + isl_set_free(set1); + isl_set_free(set2); + + if (equal < 0) + return -1; + if (!equal) + isl_die(ctx, isl_error_unknown, + "unexpected convex hull", return -1); + } + + ctx->opt->convex = orig_convex; + + return 0; +} + +static int test_convex_hull(isl_ctx *ctx) +{ + if (test_convex_hull_algo(ctx, ISL_CONVEX_HULL_FM) < 0) + return -1; + if (test_convex_hull_algo(ctx, ISL_CONVEX_HULL_WRAP) < 0) + return -1; + return 0; +} + +/* Check that computing the gist of "map" with respect to "context" + * does not make any copy of "map" get marked empty. + * Earlier versions of isl would end up doing that. + */ +static isl_stat test_gist_empty_pair(isl_ctx *ctx, const char *map, + const char *context) +{ + isl_map *m1, *m2, *m3; + isl_bool empty_before, empty_after; + + m1 = isl_map_read_from_str(ctx, map); + m2 = isl_map_read_from_str(ctx, context); + m3 = isl_map_copy(m1); + empty_before = isl_map_is_empty(m3); + m1 = isl_map_gist(m1, m2); + empty_after = isl_map_is_empty(m3); + isl_map_free(m1); + isl_map_free(m3); + + if (empty_before < 0 || empty_after < 0) + return isl_stat_error; + if (empty_before) + isl_die(ctx, isl_error_unknown, "map should not be empty", + return isl_stat_error); + if (empty_after) + isl_die(ctx, isl_error_unknown, "map should still not be empty", + return isl_stat_error); + + return isl_stat_ok; +} + +/* Check that computing a gist does not make any copy of the input + * get marked empty. + * Earlier versions of isl would end up doing that on some pairs of inputs. + */ +static isl_stat test_gist_empty(isl_ctx *ctx) +{ + const char *map, *context; + + map = "{ [] -> [a, b, c] : 2b = 1 + a }"; + context = "{ [] -> [a, b, c] : 2c = 2 + a }"; + if (test_gist_empty_pair(ctx, map, context) < 0) + return isl_stat_error; + map = "{ [] -> [0, 0] }"; + context = "{ [] -> [a, b] : a > b }"; + if (test_gist_empty_pair(ctx, map, context) < 0) + return isl_stat_error; + + return isl_stat_ok; +} + +/* Inputs to isl_map_plain_gist_basic_map, along with the expected output. + */ +struct { + const char *map; + const char *context; + const char *gist; +} plain_gist_tests[] = { + { "{ [i] -> [j] : i >= 1 and j >= 1 or i >= 2 and j <= 10 }", + "{ [i] -> [j] : i >= 1 }", + "{ [i] -> [j] : j >= 1 or i >= 2 and j <= 10 }" }, + { "{ [n] -> [i,j,k] : (i mod 3 = 2 and j mod 4 = 2) or " + "(j mod 4 = 2 and k mod 6 = n) }", + "{ [n] -> [i,j,k] : j mod 4 = 2 }", + "{ [n] -> [i,j,k] : (i mod 3 = 2) or (k mod 6 = n) }" }, + { "{ [i] -> [j] : i > j and (exists a,b : i <= 2a + 5b <= 2) }", + "{ [i] -> [j] : i > j }", + "{ [i] -> [j] : exists a,b : i <= 2a + 5b <= 2 }" }, +}; + +/* Basic tests for isl_map_plain_gist_basic_map. + */ +static int test_plain_gist(isl_ctx *ctx) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(plain_gist_tests); ++i) { + const char *str; + int equal; + isl_map *map, *gist; + isl_basic_map *context; + + map = isl_map_read_from_str(ctx, plain_gist_tests[i].map); + str = plain_gist_tests[i].context; + context = isl_basic_map_read_from_str(ctx, str); + map = isl_map_plain_gist_basic_map(map, context); + gist = isl_map_read_from_str(ctx, plain_gist_tests[i].gist); + equal = isl_map_is_equal(map, gist); + isl_map_free(map); + isl_map_free(gist); + if (equal < 0) + return -1; + if (!equal) + isl_die(ctx, isl_error_unknown, + "incorrect gist result", return -1); + } + + return 0; +} + +/* Inputs for isl_basic_set_gist tests that are expected to fail. + */ +struct { + const char *set; + const char *context; +} gist_fail_tests[] = { + { "{ [i] : exists (e0, e1: 3e1 >= 1 + 2e0 and " + "8e1 <= -1 + 5i - 5e0 and 2e1 >= 1 + 2i - 5e0) }", + "{ [i] : i >= 0 }" }, +}; + +/* Check that isl_basic_set_gist fails (gracefully) when expected. + * In particular, the user should be able to recover from the failure. + */ +static isl_stat test_gist_fail(struct isl_ctx *ctx) +{ + int i, n; + int on_error; + + on_error = isl_options_get_on_error(ctx); + isl_options_set_on_error(ctx, ISL_ON_ERROR_CONTINUE); + n = ARRAY_SIZE(gist_fail_tests); + for (i = 0; i < n; ++i) { + const char *str; + isl_basic_set *bset, *context; + + bset = isl_basic_set_read_from_str(ctx, gist_fail_tests[i].set); + str = gist_fail_tests[i].context; + context = isl_basic_set_read_from_str(ctx, str); + bset = isl_basic_set_gist(bset, context); + isl_basic_set_free(bset); + if (bset) + break; + } + isl_options_set_on_error(ctx, on_error); + if (i < n) + isl_die(ctx, isl_error_unknown, + "operation not expected to succeed", + return isl_stat_error); + + return isl_stat_ok; +} + +struct { + const char *set; + const char *context; + const char *gist; +} gist_tests[] = { + { "{ [1, -1, 3] }", + "{ [1, b, 2 - b] : -1 <= b <= 2 }", + "{ [a, -1, c] }" }, + { "{ [a, b, c] : a <= 15 and a >= 1 }", + "{ [a, b, c] : exists (e0 = floor((-1 + a)/16): a >= 1 and " + "c <= 30 and 32e0 >= -62 + 2a + 2b - c and b >= 0) }", + "{ [a, b, c] : a <= 15 }" }, + { "{ : }", "{ : 1 = 0 }", "{ : }" }, + { "{ : 1 = 0 }", "{ : 1 = 0 }", "{ : }" }, + { "[M] -> { [x] : exists (e0 = floor((-2 + x)/3): 3e0 = -2 + x) }", + "[M] -> { [3M] }" , "[M] -> { [x] : 1 = 0 }" }, + { "{ [m, n, a, b] : a <= 2147 + n }", + "{ [m, n, a, b] : (m >= 1 and n >= 1 and a <= 2148 - m and " + "b <= 2148 - n and b >= 0 and b >= 2149 - n - a) or " + "(n >= 1 and a >= 0 and b <= 2148 - n - a and " + "b >= 0) }", + "{ [m, n, ku, kl] }" }, + { "{ [a, a, b] : a >= 10 }", + "{ [a, b, c] : c >= a and c <= b and c >= 2 }", + "{ [a, a, b] : a >= 10 }" }, + { "{ [i, j] : i >= 0 and i + j >= 0 }", "{ [i, j] : i <= 0 }", + "{ [0, j] : j >= 0 }" }, + /* Check that no constraints on i6 are introduced in the gist */ + { "[t1] -> { [i4, i6] : exists (e0 = floor((1530 - 4t1 - 5i4)/20): " + "20e0 <= 1530 - 4t1 - 5i4 and 20e0 >= 1511 - 4t1 - 5i4 and " + "5e0 <= 381 - t1 and i4 <= 1) }", + "[t1] -> { [i4, i6] : exists (e0 = floor((-t1 + i6)/5): " + "5e0 = -t1 + i6 and i6 <= 6 and i6 >= 3) }", + "[t1] -> { [i4, i6] : exists (e0 = floor((1530 - 4t1 - 5i4)/20): " + "i4 <= 1 and 5e0 <= 381 - t1 and 20e0 <= 1530 - 4t1 - 5i4 and " + "20e0 >= 1511 - 4t1 - 5i4) }" }, + /* Check that no constraints on i6 are introduced in the gist */ + { "[t1, t2] -> { [i4, i5, i6] : exists (e0 = floor((1 + i4)/2), " + "e1 = floor((1530 - 4t1 - 5i4)/20), " + "e2 = floor((-4t1 - 5i4 + 10*floor((1 + i4)/2))/20), " + "e3 = floor((-1 + i4)/2): t2 = 0 and 2e3 = -1 + i4 and " + "20e2 >= -19 - 4t1 - 5i4 + 10e0 and 5e2 <= 1 - t1 and " + "2e0 <= 1 + i4 and 2e0 >= i4 and " + "20e1 <= 1530 - 4t1 - 5i4 and " + "20e1 >= 1511 - 4t1 - 5i4 and i4 <= 1 and " + "5e1 <= 381 - t1 and 20e2 <= -4t1 - 5i4 + 10e0) }", + "[t1, t2] -> { [i4, i5, i6] : exists (e0 = floor((-17 + i4)/2), " + "e1 = floor((-t1 + i6)/5): 5e1 = -t1 + i6 and " + "2e0 <= -17 + i4 and 2e0 >= -18 + i4 and " + "10e0 <= -91 + 5i4 + 4i6 and " + "10e0 >= -105 + 5i4 + 4i6) }", + "[t1, t2] -> { [i4, i5, i6] : exists (e0 = floor((381 - t1)/5), " + "e1 = floor((-1 + i4)/2): t2 = 0 and 2e1 = -1 + i4 and " + "i4 <= 1 and 5e0 <= 381 - t1 and 20e0 >= 1511 - 4t1 - 5i4) }" }, + { "{ [0, 0, q, p] : -5 <= q <= 5 and p >= 0 }", + "{ [a, b, q, p] : b >= 1 + a }", + "{ [a, b, q, p] : false }" }, + { "[n] -> { [x] : x = n && x mod 32 = 0 }", + "[n] -> { [x] : x mod 32 = 0 }", + "[n] -> { [x = n] }" }, + { "{ [x] : x mod 6 = 0 }", "{ [x] : x mod 3 = 0 }", + "{ [x] : x mod 2 = 0 }" }, + { "{ [x] : x mod 3200 = 0 }", "{ [x] : x mod 10000 = 0 }", + "{ [x] : x mod 128 = 0 }" }, + { "{ [x] : x mod 3200 = 0 }", "{ [x] : x mod 10 = 0 }", + "{ [x] : x mod 3200 = 0 }" }, + { "{ [a, b, c] : a mod 2 = 0 and a = c }", + "{ [a, b, c] : b mod 2 = 0 and b = c }", + "{ [a, b, c = a] }" }, + { "{ [a, b, c] : a mod 6 = 0 and a = c }", + "{ [a, b, c] : b mod 2 = 0 and b = c }", + "{ [a, b, c = a] : a mod 3 = 0 }" }, + { "{ [x] : 0 <= x <= 4 or 6 <= x <= 9 }", + "{ [x] : 1 <= x <= 3 or 7 <= x <= 8 }", + "{ [x] }" }, + { "{ [x,y] : x < 0 and 0 <= y <= 4 or x >= -2 and -x <= y <= 10 + x }", + "{ [x,y] : 1 <= y <= 3 }", + "{ [x,y] }" }, +}; + +/* Check that isl_set_gist behaves as expected. + * + * For the test cases in gist_tests, besides checking that the result + * is as expected, also check that applying the gist operation does + * not modify the input set (an earlier version of isl would do that) and + * that the test case is consistent, i.e., that the gist has the same + * intersection with the context as the input set. + */ +static int test_gist(struct isl_ctx *ctx) +{ + int i; + const char *str; + isl_basic_set *bset1, *bset2; + isl_map *map1, *map2; + isl_bool equal; + isl_size n_div; + + for (i = 0; i < ARRAY_SIZE(gist_tests); ++i) { + isl_bool equal_input, equal_intersection; + isl_set *set1, *set2, *copy, *context; + + set1 = isl_set_read_from_str(ctx, gist_tests[i].set); + context = isl_set_read_from_str(ctx, gist_tests[i].context); + copy = isl_set_copy(set1); + set1 = isl_set_gist(set1, isl_set_copy(context)); + set2 = isl_set_read_from_str(ctx, gist_tests[i].gist); + equal = isl_set_is_equal(set1, set2); + isl_set_free(set1); + set1 = isl_set_read_from_str(ctx, gist_tests[i].set); + equal_input = isl_set_is_equal(set1, copy); + isl_set_free(copy); + set1 = isl_set_intersect(set1, isl_set_copy(context)); + set2 = isl_set_intersect(set2, context); + equal_intersection = isl_set_is_equal(set1, set2); + isl_set_free(set2); + isl_set_free(set1); + if (equal < 0 || equal_input < 0 || equal_intersection < 0) + return -1; + if (!equal) + isl_die(ctx, isl_error_unknown, + "incorrect gist result", return -1); + if (!equal_input) + isl_die(ctx, isl_error_unknown, + "gist modified input", return -1); + if (!equal_input) + isl_die(ctx, isl_error_unknown, + "inconsistent gist test case", return -1); + } + + if (test_gist_fail(ctx) < 0) + return -1; + + str = "[p0, p2, p3, p5, p6, p10] -> { [] : " + "exists (e0 = [(15 + p0 + 15p6 + 15p10)/16], e1 = [(p5)/8], " + "e2 = [(p6)/128], e3 = [(8p2 - p5)/128], " + "e4 = [(128p3 - p6)/4096]: 8e1 = p5 and 128e2 = p6 and " + "128e3 = 8p2 - p5 and 4096e4 = 128p3 - p6 and p2 >= 0 and " + "16e0 >= 16 + 16p6 + 15p10 and p2 <= 15 and p3 >= 0 and " + "p3 <= 31 and p6 >= 128p3 and p5 >= 8p2 and p10 >= 0 and " + "16e0 <= 15 + p0 + 15p6 + 15p10 and 16e0 >= p0 + 15p6 + 15p10 and " + "p10 <= 15 and p10 <= -1 + p0 - p6) }"; + bset1 = isl_basic_set_read_from_str(ctx, str); + str = "[p0, p2, p3, p5, p6, p10] -> { [] : exists (e0 = [(p5)/8], " + "e1 = [(p6)/128], e2 = [(8p2 - p5)/128], " + "e3 = [(128p3 - p6)/4096]: 8e0 = p5 and 128e1 = p6 and " + "128e2 = 8p2 - p5 and 4096e3 = 128p3 - p6 and p5 >= -7 and " + "p2 >= 0 and 8p2 <= -1 + p0 and p2 <= 15 and p3 >= 0 and " + "p3 <= 31 and 128p3 <= -1 + p0 and p6 >= -127 and " + "p5 <= -1 + p0 and p6 <= -1 + p0 and p6 >= 128p3 and " + "p0 >= 1 and p5 >= 8p2 and p10 >= 0 and p10 <= 15 ) }"; + bset2 = isl_basic_set_read_from_str(ctx, str); + bset1 = isl_basic_set_gist(bset1, bset2); + assert(bset1 && bset1->n_div == 0); + isl_basic_set_free(bset1); + + /* Check that the integer divisions of the second disjunct + * do not spread to the first disjunct. + */ + str = "[t1] -> { S_0[] -> A[o0] : (exists (e0 = [(-t1 + o0)/16]: " + "16e0 = -t1 + o0 and o0 >= 0 and o0 <= 15 and t1 >= 0)) or " + "(exists (e0 = [(-1 + t1)/16], " + "e1 = [(-16 + t1 - 16e0)/4294967296]: " + "4294967296e1 = -16 + t1 - o0 - 16e0 and " + "16e0 <= -1 + t1 and 16e0 >= -16 + t1 and o0 >= 0 and " + "o0 <= 4294967295 and t1 <= -1)) }"; + map1 = isl_map_read_from_str(ctx, str); + str = "[t1] -> { S_0[] -> A[o0] : t1 >= 0 and t1 <= 4294967295 }"; + map2 = isl_map_read_from_str(ctx, str); + map1 = isl_map_gist(map1, map2); + if (!map1) + return -1; + if (map1->n != 1) + isl_die(ctx, isl_error_unknown, "expecting single disjunct", + isl_map_free(map1); return -1); + n_div = isl_basic_map_dim(map1->p[0], isl_dim_div); + isl_map_free(map1); + if (n_div < 0) + return -1; + if (n_div != 1) + isl_die(ctx, isl_error_unknown, "expecting single div", + return -1); + + if (test_gist_empty(ctx) < 0) + return -1; + if (test_plain_gist(ctx) < 0) + return -1; + + return 0; +} + +int test_coalesce_set(isl_ctx *ctx, const char *str, int check_one) +{ + isl_set *set, *set2; + int equal; + int one; + + set = isl_set_read_from_str(ctx, str); + set = isl_set_coalesce(set); + set2 = isl_set_read_from_str(ctx, str); + equal = isl_set_is_equal(set, set2); + one = set && set->n == 1; + isl_set_free(set); + isl_set_free(set2); + + if (equal < 0) + return -1; + if (!equal) + isl_die(ctx, isl_error_unknown, + "coalesced set not equal to input", return -1); + if (check_one && !one) + isl_die(ctx, isl_error_unknown, + "coalesced set should not be a union", return -1); + + return 0; +} + +/* Inputs for coalescing tests with unbounded wrapping. + * "str" is a string representation of the input set. + * "single_disjunct" is set if we expect the result to consist of + * a single disjunct. + */ +struct { + int single_disjunct; + const char *str; +} coalesce_unbounded_tests[] = { + { 1, "{ [x,y,z] : y + 2 >= 0 and x - y + 1 >= 0 and " + "-x - y + 1 >= 0 and -3 <= z <= 3;" + "[x,y,z] : -x+z + 20 >= 0 and -x-z + 20 >= 0 and " + "x-z + 20 >= 0 and x+z + 20 >= 0 and " + "-10 <= y <= 0}" }, + { 1, "{ [x,y] : 0 <= x,y <= 10; [5,y]: 4 <= y <= 11 }" }, + { 1, "{ [x,0,0] : -5 <= x <= 5; [0,y,1] : -5 <= y <= 5 }" }, + { 1, "{ [x,y] : 0 <= x <= 10 and 0 >= y >= -1 and x+y >= 0; [0,1] }" }, + { 1, "{ [x,y] : (0 <= x,y <= 4) or (2 <= x,y <= 5 and x + y <= 9) }" }, + { 0, "{ [x, y, z] : 0 <= x,y,z <= 100 and 0 < z <= 2 + 2x + 2y; " + "[x, y, 0] : x,y <= 100 and y <= 9 + 11x and x <= 9 + 11y }" }, + { 1, "{ [0:1, 0:1]; [0, 2:3] }" }, + { 1, "{ [0:1, 0:1]; [0, 2:3]; [1, -2:-1] }" }, + { 1, "{ [0:3, 0:1]; [1:2, 2:5] }" }, + { 1, "{ [0:3, 0:1]; [0:2, 2:5] }" }, + { 1, "{ [0:3, 0:1]; [1:3, 2:5] }" }, + { 0, "{ [0:3, 0:1]; [1:4, 2:5] }" }, + { 0, "{ [0:3, 0:1]; [1:5, 2:5] }" }, +}; + +/* Test the functionality of isl_set_coalesce with the bounded wrapping + * option turned off. + */ +int test_coalesce_unbounded_wrapping(isl_ctx *ctx) +{ + int i; + int r = 0; + int bounded; + + bounded = isl_options_get_coalesce_bounded_wrapping(ctx); + isl_options_set_coalesce_bounded_wrapping(ctx, 0); + + for (i = 0; i < ARRAY_SIZE(coalesce_unbounded_tests); ++i) { + const char *str = coalesce_unbounded_tests[i].str; + int check_one = coalesce_unbounded_tests[i].single_disjunct; + if (test_coalesce_set(ctx, str, check_one) >= 0) + continue; + r = -1; + break; + } + + isl_options_set_coalesce_bounded_wrapping(ctx, bounded); + + return r; +} + +/* Inputs for coalescing tests. + * "str" is a string representation of the input set. + * "single_disjunct" is set if we expect the result to consist of + * a single disjunct. + */ +struct { + int single_disjunct; + const char *str; +} coalesce_tests[] = { + { 1, "{[x,y]: x >= 0 & x <= 10 & y >= 0 & y <= 10 or " + "y >= x & x >= 2 & 5 >= y }" }, + { 1, "{[x,y]: y >= 0 & 2x + y <= 30 & y <= 10 & x >= 0 or " + "x + y >= 10 & y <= x & x + y <= 20 & y >= 0}" }, + { 0, "{[x,y]: y >= 0 & 2x + y <= 30 & y <= 10 & x >= 0 or " + "x + y >= 10 & y <= x & x + y <= 19 & y >= 0}" }, + { 1, "{[x,y]: y >= 0 & x <= 5 & y <= x or " + "y >= 0 & x >= 6 & x <= 10 & y <= x}" }, + { 0, "{[x,y]: y >= 0 & x <= 5 & y <= x or " + "y >= 0 & x >= 7 & x <= 10 & y <= x}" }, + { 0, "{[x,y]: y >= 0 & x <= 5 & y <= x or " + "y >= 0 & x >= 6 & x <= 10 & y + 1 <= x}" }, + { 1, "{[x,y]: y >= 0 & x <= 5 & y <= x or y >= 0 & x = 6 & y <= 6}" }, + { 0, "{[x,y]: y >= 0 & x <= 5 & y <= x or y >= 0 & x = 7 & y <= 6}" }, + { 1, "{[x,y]: y >= 0 & x <= 5 & y <= x or y >= 0 & x = 6 & y <= 5}" }, + { 0, "{[x,y]: y >= 0 & x <= 5 & y <= x or y >= 0 & x = 6 & y <= 7}" }, + { 1, "[n] -> { [i] : i = 1 and n >= 2 or 2 <= i and i <= n }" }, + { 0, "{[x,y] : x >= 0 and y >= 0 or 0 <= y and y <= 5 and x = -1}" }, + { 1, "[n] -> { [i] : 1 <= i and i <= n - 1 or 2 <= i and i <= n }" }, + { 0, "[n] -> { [[i0] -> [o0]] : exists (e0 = [(i0)/4], e1 = [(o0)/4], " + "e2 = [(n)/2], e3 = [(-2 + i0)/4], e4 = [(-2 + o0)/4], " + "e5 = [(-2n + i0)/4]: 2e2 = n and 4e3 = -2 + i0 and " + "4e4 = -2 + o0 and i0 >= 8 + 2n and o0 >= 2 + i0 and " + "o0 <= 56 + 2n and o0 <= -12 + 4n and i0 <= 57 + 2n and " + "i0 <= -11 + 4n and o0 >= 6 + 2n and 4e0 <= i0 and " + "4e0 >= -3 + i0 and 4e1 <= o0 and 4e1 >= -3 + o0 and " + "4e5 <= -2n + i0 and 4e5 >= -3 - 2n + i0);" + "[[i0] -> [o0]] : exists (e0 = [(i0)/4], e1 = [(o0)/4], " + "e2 = [(n)/2], e3 = [(-2 + i0)/4], e4 = [(-2 + o0)/4], " + "e5 = [(-2n + i0)/4]: 2e2 = n and 4e3 = -2 + i0 and " + "4e4 = -2 + o0 and 2e0 >= 3 + n and e0 <= -4 + n and " + "2e0 <= 27 + n and e1 <= -4 + n and 2e1 <= 27 + n and " + "2e1 >= 2 + n and e1 >= 1 + e0 and i0 >= 7 + 2n and " + "i0 <= -11 + 4n and i0 <= 57 + 2n and 4e0 <= -2 + i0 and " + "4e0 >= -3 + i0 and o0 >= 6 + 2n and o0 <= -11 + 4n and " + "o0 <= 57 + 2n and 4e1 <= -2 + o0 and 4e1 >= -3 + o0 and " + "4e5 <= -2n + i0 and 4e5 >= -3 - 2n + i0 ) }" }, + { 0, "[n, m] -> { [o0, o2, o3] : (o3 = 1 and o0 >= 1 + m and " + "o0 <= n + m and o2 <= m and o0 >= 2 + n and o2 >= 3) or " + "(o0 >= 2 + n and o0 >= 1 + m and o0 <= n + m and n >= 1 and " + "o3 <= -1 + o2 and o3 >= 1 - m + o2 and o3 >= 2 and o3 <= n) }" }, + { 0, "[M, N] -> { [[i0, i1, i2, i3, i4, i5, i6] -> " + "[o0, o1, o2, o3, o4, o5, o6]] : " + "(o6 <= -4 + 2M - 2N + i0 + i1 - i2 + i6 - o0 - o1 + o2 and " + "o3 <= -2 + i3 and o6 >= 2 + i0 + i3 + i6 - o0 - o3 and " + "o6 >= 2 - M + N + i3 + i4 + i6 - o3 - o4 and o0 <= -1 + i0 and " + "o4 >= 4 - 3M + 3N - i0 - i1 + i2 + 2i3 + i4 + o0 + o1 - o2 - 2o3 " + "and o6 <= -3 + 2M - 2N + i3 + i4 - i5 + i6 - o3 - o4 + o5 and " + "2o6 <= -5 + 5M - 5N + 2i0 + i1 - i2 - i5 + 2i6 - 2o0 - o1 + o2 + o5 " + "and o6 >= 2i0 + i1 + i6 - 2o0 - o1 and " + "3o6 <= -5 + 4M - 4N + 2i0 + i1 - i2 + 2i3 + i4 - i5 + 3i6 " + "- 2o0 - o1 + o2 - 2o3 - o4 + o5) or " + "(N >= 2 and o3 <= -1 + i3 and o0 <= -1 + i0 and " + "o6 >= i3 + i6 - o3 and M >= 0 and " + "2o6 >= 1 + i0 + i3 + 2i6 - o0 - o3 and " + "o6 >= 1 - M + i0 + i6 - o0 and N >= 2M and o6 >= i0 + i6 - o0) }" }, + { 0, "[M, N] -> { [o0] : (o0 = 0 and M >= 1 and N >= 2) or " + "(o0 = 0 and M >= 1 and N >= 2M and N >= 2 + M) or " + "(o0 = 0 and M >= 2 and N >= 3) or " + "(M = 0 and o0 = 0 and N >= 3) }" }, + { 0, "{ [i0, i1, i2, i3] : (i1 = 10i0 and i0 >= 1 and 10i0 <= 100 and " + "i3 <= 9 + 10 i2 and i3 >= 1 + 10i2 and i3 >= 0) or " + "(i1 <= 9 + 10i0 and i1 >= 1 + 10i0 and i2 >= 0 and " + "i0 >= 0 and i1 <= 100 and i3 <= 9 + 10i2 and i3 >= 1 + 10i2) }" }, + { 0, "[M] -> { [i1] : (i1 >= 2 and i1 <= M) or (i1 = M and M >= 1) }" }, + { 0, "{[x,y] : x,y >= 0; [x,y] : 10 <= x <= 20 and y >= -1 }" }, + { 1, "{ [x, y] : (x >= 1 and y >= 1 and x <= 2 and y <= 2) or " + "(y = 3 and x = 1) }" }, + { 1, "[M] -> { [i0, i1, i2, i3, i4] : (i1 >= 3 and i4 >= 2 + i2 and " + "i2 >= 2 and i0 >= 2 and i3 >= 1 + i2 and i0 <= M and " + "i1 <= M and i3 <= M and i4 <= M) or " + "(i1 >= 2 and i4 >= 1 + i2 and i2 >= 2 and i0 >= 2 and " + "i3 >= 1 + i2 and i0 <= M and i1 <= -1 + M and i3 <= M and " + "i4 <= -1 + M) }" }, + { 1, "{ [x, y] : (x >= 0 and y >= 0 and x <= 10 and y <= 10) or " + "(x >= 1 and y >= 1 and x <= 11 and y <= 11) }" }, + { 0, "{[x,0] : x >= 0; [x,1] : x <= 20}" }, + { 1, "{ [x, 1 - x] : 0 <= x <= 1; [0,0] }" }, + { 1, "{ [0,0]; [i,i] : 1 <= i <= 10 }" }, + { 0, "{ [0,0]; [i,j] : 1 <= i,j <= 10 }" }, + { 1, "{ [0,0]; [i,2i] : 1 <= i <= 10 }" }, + { 0, "{ [0,0]; [i,2i] : 2 <= i <= 10 }" }, + { 0, "{ [1,0]; [i,2i] : 1 <= i <= 10 }" }, + { 0, "{ [0,1]; [i,2i] : 1 <= i <= 10 }" }, + { 0, "{ [a, b] : exists e : 2e = a and " + "a >= 0 and (a <= 3 or (b <= 0 and b >= -4 + a)) }" }, + { 0, "{ [i, j, i', j'] : i <= 2 and j <= 2 and " + "j' >= -1 + 2i + j - 2i' and i' <= -1 + i and " + "j >= 1 and j' <= i + j - i' and i >= 1; " + "[1, 1, 1, 1] }" }, + { 1, "{ [i,j] : exists a,b : i = 2a and j = 3b; " + "[i,j] : exists a : j = 3a }" }, + { 1, "{ [a, b, c] : (c <= 7 - b and b <= 1 and b >= 0 and " + "c >= 3 + b and b <= 3 + 8a and b >= -26 + 8a and " + "a >= 3) or " + "(b <= 1 and c <= 7 and b >= 0 and c >= 4 + b and " + "b <= 3 + 8a and b >= -26 + 8a and a >= 3) }" }, + { 1, "{ [a, 0, c] : c >= 1 and c <= 29 and c >= -1 + 8a and " + "c <= 6 + 8a and a >= 3; " + "[a, -1, c] : c >= 1 and c <= 30 and c >= 8a and " + "c <= 7 + 8a and a >= 3 and a <= 4 }" }, + { 1, "{ [x,y] : 0 <= x <= 2 and y >= 0 and x + 2y <= 4; " + "[x,0] : 3 <= x <= 4 }" }, + { 1, "{ [x,y] : 0 <= x <= 3 and y >= 0 and x + 3y <= 6; " + "[x,0] : 4 <= x <= 5 }" }, + { 0, "{ [x,y] : 0 <= x <= 2 and y >= 0 and x + 2y <= 4; " + "[x,0] : 3 <= x <= 5 }" }, + { 0, "{ [x,y] : 0 <= x <= 2 and y >= 0 and x + y <= 4; " + "[x,0] : 3 <= x <= 4 }" }, + { 1, "{ [i0, i1] : i0 <= 122 and i0 >= 1 and 128i1 >= -249 + i0 and " + "i1 <= 0; " + "[i0, 0] : i0 >= 123 and i0 <= 124 }" }, + { 1, "{ [0,0]; [1,1] }" }, + { 1, "[n] -> { [k] : 16k <= -1 + n and k >= 1; [0] : n >= 2 }" }, + { 1, "{ [k, ii, k - ii] : ii >= -6 + k and ii <= 6 and ii >= 1 and " + "ii <= k;" + "[k, 0, k] : k <= 6 and k >= 1 }" }, + { 1, "{ [i,j] : i = 4 j and 0 <= i <= 100;" + "[i,j] : 1 <= i <= 100 and i >= 4j + 1 and i <= 4j + 2 }" }, + { 1, "{ [x,y] : x % 2 = 0 and y % 2 = 0; [x,x] : x % 2 = 0 }" }, + { 1, "[n] -> { [1] : n >= 0;" + "[x] : exists (e0 = floor((x)/2): x >= 2 and " + "2e0 >= -1 + x and 2e0 <= x and 2e0 <= n) }" }, + { 1, "[n] -> { [x, y] : exists (e0 = floor((x)/2), e1 = floor((y)/3): " + "3e1 = y and x >= 2 and 2e0 >= -1 + x and " + "2e0 <= x and 2e0 <= n);" + "[1, y] : exists (e0 = floor((y)/3): 3e0 = y and " + "n >= 0) }" }, + { 1, "[t1] -> { [i0] : (exists (e0 = floor((63t1)/64): " + "128e0 >= -134 + 127t1 and t1 >= 2 and " + "64e0 <= 63t1 and 64e0 >= -63 + 63t1)) or " + "t1 = 1 }" }, + { 1, "{ [i, i] : exists (e0 = floor((1 + 2i)/3): 3e0 <= 2i and " + "3e0 >= -1 + 2i and i <= 9 and i >= 1);" + "[0, 0] }" }, + { 1, "{ [t1] : exists (e0 = floor((-11 + t1)/2): 2e0 = -11 + t1 and " + "t1 >= 13 and t1 <= 16);" + "[t1] : t1 <= 15 and t1 >= 12 }" }, + { 1, "{ [x,y] : x = 3y and 0 <= y <= 2; [-3,-1] }" }, + { 1, "{ [x,y] : 2x = 3y and 0 <= y <= 4; [-3,-2] }" }, + { 0, "{ [x,y] : 2x = 3y and 0 <= y <= 4; [-2,-2] }" }, + { 0, "{ [x,y] : 2x = 3y and 0 <= y <= 4; [-3,-1] }" }, + { 1, "{ [i] : exists j : i = 4 j and 0 <= i <= 100;" + "[i] : exists j : 1 <= i <= 100 and i >= 4j + 1 and " + "i <= 4j + 2 }" }, + { 1, "{ [c0] : (exists (e0 : c0 - 1 <= 3e0 <= c0)) or " + "(exists (e0 : 3e0 = -2 + c0)) }" }, + { 0, "[n, b0, t0] -> " + "{ [i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12] : " + "(exists (e0 = floor((-32b0 + i4)/1048576), " + "e1 = floor((i8)/32): 1048576e0 = -32b0 + i4 and 32e1 = i8 and " + "n <= 2147483647 and b0 <= 32767 and b0 >= 0 and " + "32b0 <= -2 + n and t0 <= 31 and t0 >= 0 and i0 >= 8 + n and " + "3i4 <= -96 + 3t0 + i0 and 3i4 >= -95 - n + 3t0 + i0 and " + "i8 >= -157 + i0 - 4i4 and i8 >= 0 and " + "i8 <= -33 + i0 - 4i4 and 3i8 <= -91 + 4n - i0)) or " + "(exists (e0 = floor((-32b0 + i4)/1048576), " + "e1 = floor((i8)/32): 1048576e0 = -32b0 + i4 and 32e1 = i8 and " + "n <= 2147483647 and b0 <= 32767 and b0 >= 0 and " + "32b0 <= -2 + n and t0 <= 31 and t0 >= 0 and i0 <= 7 + n and " + "4i4 <= -3 + i0 and 3i4 <= -96 + 3t0 + i0 and " + "3i4 >= -95 - n + 3t0 + i0 and i8 >= -157 + i0 - 4i4 and " + "i8 >= 0 and i8 <= -4 + i0 - 3i4 and i8 <= -41 + i0));" + "[i0, i1, i2, i3, 0, i5, i6, i7, i8, i9, i10, i11, i12] : " + "(exists (e0 = floor((i8)/32): b0 = 0 and 32e0 = i8 and " + "n <= 2147483647 and t0 <= 31 and t0 >= 0 and i0 >= 11 and " + "i0 >= 96 - 3t0 and i0 <= 95 + n - 3t0 and i0 <= 7 + n and " + "i8 >= -40 + i0 and i8 <= -10 + i0)) }" }, + { 0, "{ [i0, i1, i2] : " + "(exists (e0, e1 = floor((i0)/32), e2 = floor((i1)/32): " + "32e1 = i0 and 32e2 = i1 and i1 >= -31 + i0 and " + "i1 <= 31 + i0 and i2 >= -30 + i0 and i2 >= -30 + i1 and " + "32e0 >= -30 + i0 and 32e0 >= -30 + i1 and " + "32e0 >= -31 + i2 and 32e0 <= 30 + i2 and 32e0 <= 31 + i1 and " + "32e0 <= 31 + i0)) or " + "i0 >= 0 }" }, + { 1, "{ [a, b, c] : 2b = 1 + a and 2c = 2 + a; [0, 0, 0] }" }, + { 1, "{ [a, a, b, c] : 32*floor((a)/32) = a and 2*floor((b)/2) = b and " + "2*floor((c)/2) = c and 0 <= a <= 192;" + "[224, 224, b, c] : 2*floor((b)/2) = b and 2*floor((c)/2) = c }" + }, + { 1, "[n] -> { [a,b] : (exists e : 1 <= a <= 7e and 9e <= b <= n) or " + "(0 <= a <= b <= n) }" }, + { 1, "{ [a, b] : 0 <= a <= 2 and b >= 0 and " + "((0 < b <= 13) or (2*floor((a + b)/2) >= -5 + a + 2b)) }" }, + { 1, "{ [a] : (2 <= a <= 5) or (a mod 2 = 1 and 1 <= a <= 5) }" }, + { 1, "{ [a, b, c] : (b = -1 + a and 0 < a <= 3 and " + "9*floor((-4a + 2c)/9) <= -3 - 4a + 2c) or " + "(exists (e0 = floor((-16 + 2c)/9): a = 4 and " + "b = 3 and 9e0 <= -19 + 2c)) }" }, + { 1, "{ [a, b, c] : (b = -1 + a and 0 < a <= 3 and " + "9*floor((-4a + 2c)/9) <= -3 - 4a + 2c) or " + "(a = 4 and b = 3 and " + "9*floor((-16 + 2c)/9) <= -19 + 2c) }" }, + { 0, "{ [a, b, c] : (b <= 2 and b <= -2 + a) or " + "(b = -1 + a and 0 < a <= 3 and " + "9*floor((-4a + 2c)/9) <= -3 - 4a + 2c) or " + "(exists (e0 = floor((-16 + 2c)/9): a = 4 and " + "b = 3 and 9e0 <= -19 + 2c)) }" }, + { 1, "{ [y, x] : (x - y) mod 3 = 2 and 2 <= y <= 200 and 0 <= x <= 2;" + "[1, 0] }" }, + { 1, "{ [x, y] : (x - y) mod 3 = 2 and 2 <= y <= 200 and 0 <= x <= 2;" + "[0, 1] }" }, + { 1, "{ [1, y] : -1 <= y <= 1; [x, -x] : 0 <= x <= 1 }" }, + { 1, "{ [1, y] : 0 <= y <= 1; [x, -x] : 0 <= x <= 1 }" }, + { 1, "{ [x, y] : 0 <= x <= 10 and x - 4*floor(x/4) <= 1 and y <= 0; " + "[x, y] : 0 <= x <= 10 and x - 4*floor(x/4) > 1 and y <= 0; " + "[x, y] : 0 <= x <= 10 and x - 5*floor(x/5) <= 1 and 0 < y; " + "[x, y] : 0 <= x <= 10 and x - 5*floor(x/5) > 1 and 0 < y }" }, + { 1, "{ [x, 0] : 0 <= x <= 10 and x mod 2 = 0; " + "[x, 0] : 0 <= x <= 10 and x mod 2 = 1; " + "[x, y] : 0 <= x <= 10 and 1 <= y <= 10 }" }, + { 1, "{ [a] : a <= 8 and " + "(a mod 10 = 7 or a mod 10 = 8 or a mod 10 = 9) }" }, + { 1, "{ [x, y] : 2y = -x and x <= 0 or " + "x <= -1 and 2y <= -x - 1 and 2y >= x - 1 }" }, + { 0, "{ [x, y] : 2y = -x and x <= 0 or " + "x <= -2 and 2y <= -x - 1 and 2y >= x - 1 }" }, + { 1, "{ [a] : (a <= 0 and 3*floor((a)/3) = a) or " + "(a < 0 and 3*floor((a)/3) < a) }" }, + { 1, "{ [a] : (a <= 0 and 3*floor((a)/3) = a) or " + "(a < -1 and 3*floor((a)/3) < a) }" }, + { 1, "{ [a, b] : a <= 1024 and b >= 0 and " + "((-31 - a + b <= 32*floor((-1 - a)/32) <= -33 + b and " + "32*floor((-1 - a)/32) <= -16 + b + 16*floor((-1 - a)/16))" + "or (2 <= a <= 15 and b < a)) }" }, + { 1, "{ [a] : a > 0 and ((16*floor((a)/16) < a and " + "32*floor((a)/32) < a) or a <= 15) }" }, + { 1, "{ [a, b, c, d] : (-a + d) mod 64 = 0 and a <= 8 and b <= 1 and " + "10 - a <= c <= 3 and d >= 5 and 9 - 64b <= d <= 70;" + "[a, b = 1, c, d] : (-a + d) mod 64 = 0 and a <= 8 and c >= 4 and " + "10 - a <= c <= 5 and 5 <= d <= 73 - c }" }, + { 1, "[n, m] -> { S_0[i] : (-n + i) mod 3 = 0 and m >= 3 + n and " + "i >= n and 3*floor((2 + n + 2m)/3) <= n + 3m - i; " + "S_0[n] : n <= m <= 2 + n }" }, + { 1, "{ [a, b] : exists (e0: 0 <= a <= 1 and b >= 0 and " + "2e0 >= -5 + a + 2b and 2e0 >= -1 + a + b and " + "2e0 <= a + b); " + "[a, b] : exists (e0: 0 <= a <= 1 and 2e0 >= -5 + a + 2b and " + "2e0 >= -1 - a + b and 2e0 <= -a + b and " + "2e0 < -a + 2b) }" }, + { 1, "{ [i, j, i - 8j] : 8 <= i <= 63 and -7 + i <= 8j <= i; " + "[i, 0, i] : 0 <= i <= 7 }" }, + { 1, "{ [a, b] : a >= 0 and 0 <= b <= 1 - a; [1, 1] }" }, + { 0, "{ [a, b] : a >= 0 and 0 <= b <= 1 - a; [0, 2] }" }, + { 0, "{ [a, b] : a >= 0 and 0 <= b <= 1 - a; [-1, 3] }" }, + { 1, "{ [a, b] : a, b >= 0 and a + 2b <= 2; [1, 1] }" }, + { 0, "{ [a, b] : a, b >= 0 and a + 2b <= 2; [2, 1] }" }, + { 0, "{ [a, c] : (2 + a) mod 4 = 0 or " + "(c = 4 + a and 4 * floor((a)/4) = a and a >= 0 and a <= 4) or " + "(c = 3 + a and 4 * floor((-1 + a)/4) = -1 + a and " + "a > 0 and a <= 5) }" }, + { 1, "{ [1, 0, 0]; [a, b, c] : -1 <= -a < b <= 0 and 2c > b }" }, + { 0, "{ [j, a, l] : a mod 2 = 0 and j <= 29 and a >= 2 and " + "2a <= -5 + j and 32j + 2a + 2 <= 4l < 33j; " + "[j, 0, l] : 4 <= j <= 29 and -3 + 33j <= 4l <= 33j }" }, + { 0, "{ [0:1, 0:1]; [0, 2:3] }" }, + { 1, "{ [a] : (a = 0 or ((1 + a) mod 2 = 0 and 0 < a <= 15) or " + "((a) mod 2 = 0 and 0 < a <= 15)) }" }, + { 1, "{ rat: [0:2]; rat: [1:3] }" }, +}; + +/* A specialized coalescing test case that would result + * in a segmentation fault or a failed assertion in earlier versions of isl. + */ +static int test_coalesce_special(struct isl_ctx *ctx) +{ + const char *str; + isl_map *map1, *map2; + + str = "[y] -> { [S_L220_OUT[] -> T7[]] -> " + "[[S_L309_IN[] -> T11[]] -> ce_imag2[1, o1]] : " + "(y = 201 and o1 <= 239 and o1 >= 212) or " + "(exists (e0 = [(y)/3]: 3e0 = y and y <= 198 and y >= 3 and " + "o1 <= 239 and o1 >= 212)) or " + "(exists (e0 = [(y)/3]: 3e0 = y and y <= 201 and y >= 3 and " + "o1 <= 241 and o1 >= 240));" + "[S_L220_OUT[] -> T7[]] -> " + "[[S_L309_IN[] -> T11[]] -> ce_imag2[0, o1]] : " + "(y = 2 and o1 <= 241 and o1 >= 212) or " + "(exists (e0 = [(-2 + y)/3]: 3e0 = -2 + y and y <= 200 and " + "y >= 5 and o1 <= 241 and o1 >= 212)) }"; + map1 = isl_map_read_from_str(ctx, str); + map1 = isl_map_align_divs_internal(map1); + map1 = isl_map_coalesce(map1); + str = "[y] -> { [S_L220_OUT[] -> T7[]] -> " + "[[S_L309_IN[] -> T11[]] -> ce_imag2[o0, o1]] : " + "exists (e0 = [(-1 - y + o0)/3]: 3e0 = -1 - y + o0 and " + "y <= 201 and o0 <= 2 and o1 >= 212 and o1 <= 241 and " + "o0 >= 3 - y and o0 <= -2 + y and o0 >= 0) }"; + map2 = isl_map_read_from_str(ctx, str); + map2 = isl_map_union(map2, map1); + map2 = isl_map_align_divs_internal(map2); + map2 = isl_map_coalesce(map2); + isl_map_free(map2); + if (!map2) + return -1; + + return 0; +} + +/* Check that the union of the basic sets described by "str1" and "str2" + * can be coalesced and that the result is equal to the union. + * The explicit call to isl_basic_set_union prevents the implicit + * equality constraints in the basic maps from being detected prior + * to the call to isl_set_coalesce, at least at the point + * where this function was introduced. + */ +static isl_stat test_coalesce_union(isl_ctx *ctx, const char *str1, + const char *str2) +{ + isl_basic_set *bset1, *bset2; + isl_set *set, *set2; + isl_bool equal; + + bset1 = isl_basic_set_read_from_str(ctx, str1); + bset2 = isl_basic_set_read_from_str(ctx, str2); + set = isl_basic_set_union(bset1, bset2); + set = isl_set_coalesce(set); + + bset1 = isl_basic_set_read_from_str(ctx, str1); + bset2 = isl_basic_set_read_from_str(ctx, str2); + set2 = isl_basic_set_union(bset1, bset2); + + equal = isl_set_is_equal(set, set2); + isl_set_free(set); + isl_set_free(set2); + + if (equal < 0) + return isl_stat_error; + if (!equal) + isl_die(ctx, isl_error_unknown, + "coalesced set not equal to input", + return isl_stat_error); + + return isl_stat_non_null(set); +} + +/* A specialized coalescing test case that would result in an assertion + * in an earlier version of isl. Use test_coalesce_union with + * an explicit call to isl_basic_set_union to prevent the implicit + * equality constraints in the first basic map from being detected prior + * to the call to isl_set_coalesce, at least at the point + * where this test case was introduced. + */ +static isl_stat test_coalesce_special2(struct isl_ctx *ctx) +{ + const char *str1; + const char *str2; + + str1 = "{ [x, y] : x, y >= 0 and x + 2y <= 1 and 2x + y <= 1 }"; + str2 = "{ [x,0] : -1 <= x <= 1 and x mod 2 = 1 }"; + return test_coalesce_union(ctx, str1, str2); +} + +/* Check that calling isl_set_coalesce does not leave other sets + * that may share some information with the input to isl_set_coalesce + * in an inconsistent state. + * In particular, older versions of isl would modify all copies + * of the basic sets in the isl_set_coalesce input in a way + * that could leave them in an inconsistent state. + * The result of printing any other set containing one of these + * basic sets would then result in an invalid set description. + */ +static int test_coalesce_special3(isl_ctx *ctx) +{ + const char *str; + char *s; + isl_set *set1, *set2; + isl_printer *p; + + set1 = isl_set_read_from_str(ctx, "{ [0, 0, 0] }"); + str = "{ [a, b, a + b] : a >= 0 and b >= 0 and 0 < a + b }"; + set2 = isl_set_read_from_str(ctx, str); + set1 = isl_set_union(set1, isl_set_copy(set2)); + set1 = isl_set_coalesce(set1); + isl_set_free(set1); + + p = isl_printer_to_str(ctx); + p = isl_printer_print_set(p, set2); + isl_set_free(set2); + s = isl_printer_get_str(p); + isl_printer_free(p); + set1 = isl_set_read_from_str(ctx, s); + free(s); + isl_set_free(set1); + + if (!set1) + return -1; + + return 0; +} + +/* Check that calling isl_set_coalesce on the intersection of + * the sets described by "s1" and "s2" does not leave other sets + * that may share some information with the input to isl_set_coalesce + * in an inconsistent state. + * In particular, when isl_set_coalesce detects equality constraints, + * it does not immediately perform Gaussian elimination on them, + * but then it needs to ensure that it is performed at some point. + * The input set has implicit equality constraints in the first disjunct. + * It is constructed as an intersection, because otherwise + * those equality constraints would already be detected during parsing. + */ +static isl_stat test_coalesce_intersection(isl_ctx *ctx, + const char *s1, const char *s2) +{ + isl_set *set1, *set2; + + set1 = isl_set_read_from_str(ctx, s1); + set2 = isl_set_read_from_str(ctx, s2); + set1 = isl_set_intersect(set1, set2); + isl_set_free(isl_set_coalesce(isl_set_copy(set1))); + set1 = isl_set_coalesce(set1); + isl_set_free(set1); + + if (!set1) + return isl_stat_error; + + return isl_stat_ok; +} + +/* Check that calling isl_set_coalesce does not leave other sets + * that may share some information with the input to isl_set_coalesce + * in an inconsistent state, for the case where one disjunct + * is a subset of the other. + */ +static isl_stat test_coalesce_special4(isl_ctx *ctx) +{ + const char *s1, *s2; + + s1 = "{ [a, b] : b <= 0 or a <= 1 }"; + s2 = "{ [a, b] : -1 <= -a < b }"; + return test_coalesce_intersection(ctx, s1, s2); +} + +/* Check that calling isl_set_coalesce does not leave other sets + * that may share some information with the input to isl_set_coalesce + * in an inconsistent state, for the case where two disjuncts + * can be fused. + */ +static isl_stat test_coalesce_special5(isl_ctx *ctx) +{ + const char *s1, *s2; + + s1 = "{ [a, b, c] : b <= 0 }"; + s2 = "{ [a, b, c] : -1 <= -a < b and (c >= 0 or c < 0) }"; + return test_coalesce_intersection(ctx, s1, s2); +} + +/* Check that calling isl_set_coalesce does not leave other sets + * that may share some information with the input to isl_set_coalesce + * in an inconsistent state, for the case where two disjuncts + * can be fused and where both disjuncts have implicit equality constraints. + */ +static isl_stat test_coalesce_special6(isl_ctx *ctx) +{ + const char *s1, *s2; + + s1 = "{ [a, b, c] : c <= 0 }"; + s2 = "{ [a, b, c] : 0 <= a <= b <= c or (0 <= b <= c and a > 0) }"; + return test_coalesce_intersection(ctx, s1, s2); +} + +/* A specialized coalescing test case that would result in an assertion failure + * in an earlier version of isl. Use test_coalesce_union with + * an explicit call to isl_basic_set_union to prevent the implicit + * equality constraints in the basic maps from being detected prior + * to the call to isl_set_coalesce, at least at the point + * where this test case was introduced. + */ +static isl_stat test_coalesce_special7(isl_ctx *ctx) +{ + const char *str1; + const char *str2; + + str1 = "{ [a, b, c=0:17] : a <= 7 and 2b <= 11 - a and " + "c <= -7 + 2a and 2c >= - 3 + 3a - 2b }"; + str2 = "{ [a, b, c] : c > -15a and c >= -7 + 2a and c < 0 and " + "3c <= -5 + 5a - 3b and 2b >= 11 - a }"; + return test_coalesce_union(ctx, str1, str2); +} + +/* A specialized coalescing test case that would result in a disjunct + * getting dropped in an earlier version of isl. Use test_coalesce_union with + * an explicit call to isl_basic_set_union to prevent the implicit + * equality constraints in the basic maps from being detected prior + * to the call to isl_set_coalesce, at least at the point + * where this test case was introduced. + */ +static isl_stat test_coalesce_special8(isl_ctx *ctx) +{ + const char *str1; + const char *str2; + + str1 = "{ [a, b, c] : 2c <= -a and b >= -a and b <= 5 and " + "6c > -7a and 11c >= -5a - b and a <= 3 }"; + str2 = "{ [a, b, c] : 6c > -7a and b >= -a and b <= 5 and " + "11c >= -5a - b and a >= 4 and 2b <= a and 2c <= -a }"; + return test_coalesce_union(ctx, str1, str2); +} + +/* Test the functionality of isl_set_coalesce. + * That is, check that the output is always equal to the input + * and in some cases that the result consists of a single disjunct. + */ +static int test_coalesce(struct isl_ctx *ctx) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(coalesce_tests); ++i) { + const char *str = coalesce_tests[i].str; + int check_one = coalesce_tests[i].single_disjunct; + if (test_coalesce_set(ctx, str, check_one) < 0) + return -1; + } + + if (test_coalesce_unbounded_wrapping(ctx) < 0) + return -1; + if (test_coalesce_special(ctx) < 0) + return -1; + if (test_coalesce_special2(ctx) < 0) + return -1; + if (test_coalesce_special3(ctx) < 0) + return -1; + if (test_coalesce_special4(ctx) < 0) + return -1; + if (test_coalesce_special5(ctx) < 0) + return -1; + if (test_coalesce_special6(ctx) < 0) + return -1; + if (test_coalesce_special7(ctx) < 0) + return -1; + if (test_coalesce_special8(ctx) < 0) + return -1; + + return 0; +} + +/* Construct a representation of the graph on the right of Figure 1 + * in "Computing the Transitive Closure of a Union of + * Affine Integer Tuple Relations". + */ +static __isl_give isl_map *cocoa_fig_1_right_graph(isl_ctx *ctx) +{ + isl_set *dom; + isl_map *up, *right; + + dom = isl_set_read_from_str(ctx, + "{ [x,y] : x >= 0 and -2 x + 3 y >= 0 and x <= 3 and " + "2 x - 3 y + 3 >= 0 }"); + right = isl_map_read_from_str(ctx, + "{ [x,y] -> [x2,y2] : x2 = x + 1 and y2 = y }"); + up = isl_map_read_from_str(ctx, + "{ [x,y] -> [x2,y2] : x2 = x and y2 = y + 1 }"); + right = isl_map_intersect_domain(right, isl_set_copy(dom)); + right = isl_map_intersect_range(right, isl_set_copy(dom)); + up = isl_map_intersect_domain(up, isl_set_copy(dom)); + up = isl_map_intersect_range(up, dom); + return isl_map_union(up, right); +} + +/* Construct a representation of the power of the graph + * on the right of Figure 1 in "Computing the Transitive Closure of + * a Union of Affine Integer Tuple Relations". + */ +static __isl_give isl_map *cocoa_fig_1_right_power(isl_ctx *ctx) +{ + return isl_map_read_from_str(ctx, + "{ [1] -> [[0,0] -> [0,1]]; [2] -> [[0,0] -> [1,1]]; " + " [1] -> [[0,1] -> [1,1]]; [1] -> [[2,2] -> [3,2]]; " + " [2] -> [[2,2] -> [3,3]]; [1] -> [[3,2] -> [3,3]] }"); +} + +/* Construct a representation of the transitive closure of the graph + * on the right of Figure 1 in "Computing the Transitive Closure of + * a Union of Affine Integer Tuple Relations". + */ +static __isl_give isl_map *cocoa_fig_1_right_tc(isl_ctx *ctx) +{ + return isl_set_unwrap(isl_map_range(cocoa_fig_1_right_power(ctx))); +} + +static int test_closure(isl_ctx *ctx) +{ + const char *str; + isl_map *map, *map2; + isl_bool exact, equal; + + /* COCOA example 1 */ + map = isl_map_read_from_str(ctx, + "[n] -> { [i,j] -> [i2,j2] : i2 = i + 1 and j2 = j + 1 and " + "1 <= i and i < n and 1 <= j and j < n or " + "i2 = i + 1 and j2 = j - 1 and " + "1 <= i and i < n and 2 <= j and j <= n }"); + map = isl_map_power(map, &exact); + assert(exact); + isl_map_free(map); + + /* COCOA example 1 */ + map = isl_map_read_from_str(ctx, + "[n] -> { [i,j] -> [i2,j2] : i2 = i + 1 and j2 = j + 1 and " + "1 <= i and i < n and 1 <= j and j < n or " + "i2 = i + 1 and j2 = j - 1 and " + "1 <= i and i < n and 2 <= j and j <= n }"); + map = isl_map_transitive_closure(map, &exact); + assert(exact); + map2 = isl_map_read_from_str(ctx, + "[n] -> { [i,j] -> [i2,j2] : exists (k1,k2,k : " + "1 <= i and i < n and 1 <= j and j <= n and " + "2 <= i2 and i2 <= n and 1 <= j2 and j2 <= n and " + "i2 = i + k1 + k2 and j2 = j + k1 - k2 and " + "k1 >= 0 and k2 >= 0 and k1 + k2 = k and k >= 1 )}"); + assert(isl_map_is_equal(map, map2)); + isl_map_free(map2); + isl_map_free(map); + + map = isl_map_read_from_str(ctx, + "[n] -> { [x] -> [y] : y = x + 1 and 0 <= x and x <= n and " + " 0 <= y and y <= n }"); + map = isl_map_transitive_closure(map, &exact); + map2 = isl_map_read_from_str(ctx, + "[n] -> { [x] -> [y] : y > x and 0 <= x and x <= n and " + " 0 <= y and y <= n }"); + assert(isl_map_is_equal(map, map2)); + isl_map_free(map2); + isl_map_free(map); + + /* COCOA example 2 */ + map = isl_map_read_from_str(ctx, + "[n] -> { [i,j] -> [i2,j2] : i2 = i + 2 and j2 = j + 2 and " + "1 <= i and i < n - 1 and 1 <= j and j < n - 1 or " + "i2 = i + 2 and j2 = j - 2 and " + "1 <= i and i < n - 1 and 3 <= j and j <= n }"); + map = isl_map_transitive_closure(map, &exact); + assert(exact); + map2 = isl_map_read_from_str(ctx, + "[n] -> { [i,j] -> [i2,j2] : exists (k1,k2,k : " + "1 <= i and i < n - 1 and 1 <= j and j <= n and " + "3 <= i2 and i2 <= n and 1 <= j2 and j2 <= n and " + "i2 = i + 2 k1 + 2 k2 and j2 = j + 2 k1 - 2 k2 and " + "k1 >= 0 and k2 >= 0 and k1 + k2 = k and k >= 1) }"); + assert(isl_map_is_equal(map, map2)); + isl_map_free(map); + isl_map_free(map2); + + /* COCOA Fig.2 left */ + map = isl_map_read_from_str(ctx, + "[n] -> { [i,j] -> [i2,j2] : i2 = i + 2 and j2 = j and " + "i <= 2 j - 3 and i <= n - 2 and j <= 2 i - 1 and " + "j <= n or " + "i2 = i and j2 = j + 2 and i <= 2 j - 1 and i <= n and " + "j <= 2 i - 3 and j <= n - 2 or " + "i2 = i + 1 and j2 = j + 1 and i <= 2 j - 1 and " + "i <= n - 1 and j <= 2 i - 1 and j <= n - 1 }"); + map = isl_map_transitive_closure(map, &exact); + assert(exact); + isl_map_free(map); + + /* COCOA Fig.2 right */ + map = isl_map_read_from_str(ctx, + "[n] -> { [i,j] -> [i2,j2] : i2 = i + 3 and j2 = j and " + "i <= 2 j - 4 and i <= n - 3 and j <= 2 i - 1 and " + "j <= n or " + "i2 = i and j2 = j + 3 and i <= 2 j - 1 and i <= n and " + "j <= 2 i - 4 and j <= n - 3 or " + "i2 = i + 1 and j2 = j + 1 and i <= 2 j - 1 and " + "i <= n - 1 and j <= 2 i - 1 and j <= n - 1 }"); + map = isl_map_power(map, &exact); + assert(exact); + isl_map_free(map); + + /* COCOA Fig.2 right */ + map = isl_map_read_from_str(ctx, + "[n] -> { [i,j] -> [i2,j2] : i2 = i + 3 and j2 = j and " + "i <= 2 j - 4 and i <= n - 3 and j <= 2 i - 1 and " + "j <= n or " + "i2 = i and j2 = j + 3 and i <= 2 j - 1 and i <= n and " + "j <= 2 i - 4 and j <= n - 3 or " + "i2 = i + 1 and j2 = j + 1 and i <= 2 j - 1 and " + "i <= n - 1 and j <= 2 i - 1 and j <= n - 1 }"); + map = isl_map_transitive_closure(map, &exact); + assert(exact); + map2 = isl_map_read_from_str(ctx, + "[n] -> { [i,j] -> [i2,j2] : exists (k1,k2,k3,k : " + "i <= 2 j - 1 and i <= n and j <= 2 i - 1 and " + "j <= n and 3 + i + 2 j <= 3 n and " + "3 + 2 i + j <= 3n and i2 <= 2 j2 -1 and i2 <= n and " + "i2 <= 3 j2 - 4 and j2 <= 2 i2 -1 and j2 <= n and " + "13 + 4 j2 <= 11 i2 and i2 = i + 3 k1 + k3 and " + "j2 = j + 3 k2 + k3 and k1 >= 0 and k2 >= 0 and " + "k3 >= 0 and k1 + k2 + k3 = k and k > 0) }"); + assert(isl_map_is_equal(map, map2)); + isl_map_free(map2); + isl_map_free(map); + + map = cocoa_fig_1_right_graph(ctx); + map = isl_map_transitive_closure(map, &exact); + assert(exact); + map2 = cocoa_fig_1_right_tc(ctx); + assert(isl_map_is_equal(map, map2)); + isl_map_free(map2); + isl_map_free(map); + + map = cocoa_fig_1_right_graph(ctx); + map = isl_map_power(map, &exact); + map2 = cocoa_fig_1_right_power(ctx); + equal = isl_map_is_equal(map, map2); + isl_map_free(map2); + isl_map_free(map); + if (equal < 0) + return -1; + if (!exact) + isl_die(ctx, isl_error_unknown, "power not exact", return -1); + if (!equal) + isl_die(ctx, isl_error_unknown, "unexpected power", return -1); + + /* COCOA Theorem 1 counter example */ + map = isl_map_read_from_str(ctx, + "{ [i,j] -> [i2,j2] : i = 0 and 0 <= j and j <= 1 and " + "i2 = 1 and j2 = j or " + "i = 0 and j = 0 and i2 = 0 and j2 = 1 }"); + map = isl_map_transitive_closure(map, &exact); + assert(exact); + isl_map_free(map); + + map = isl_map_read_from_str(ctx, + "[m,n] -> { [i,j] -> [i2,j2] : i2 = i and j2 = j + 2 and " + "1 <= i,i2 <= n and 1 <= j,j2 <= m or " + "i2 = i + 1 and 3 <= j2 - j <= 4 and " + "1 <= i,i2 <= n and 1 <= j,j2 <= m }"); + map = isl_map_transitive_closure(map, &exact); + assert(exact); + isl_map_free(map); + + /* Kelly et al 1996, fig 12 */ + map = isl_map_read_from_str(ctx, + "[n] -> { [i,j] -> [i2,j2] : i2 = i and j2 = j + 1 and " + "1 <= i,j,j+1 <= n or " + "j = n and j2 = 1 and i2 = i + 1 and " + "1 <= i,i+1 <= n }"); + map = isl_map_transitive_closure(map, &exact); + assert(exact); + map2 = isl_map_read_from_str(ctx, + "[n] -> { [i,j] -> [i2,j2] : 1 <= j < j2 <= n and " + "1 <= i <= n and i = i2 or " + "1 <= i < i2 <= n and 1 <= j <= n and " + "1 <= j2 <= n }"); + assert(isl_map_is_equal(map, map2)); + isl_map_free(map2); + isl_map_free(map); + + /* Omega's closure4 */ + map = isl_map_read_from_str(ctx, + "[m,n] -> { [x,y] -> [x2,y2] : x2 = x and y2 = y + 1 and " + "1 <= x,y <= 10 or " + "x2 = x + 1 and y2 = y and " + "1 <= x <= 20 && 5 <= y <= 15 }"); + map = isl_map_transitive_closure(map, &exact); + assert(exact); + isl_map_free(map); + + map = isl_map_read_from_str(ctx, + "[n] -> { [x] -> [y]: 1 <= n <= y - x <= 10 }"); + map = isl_map_transitive_closure(map, &exact); + assert(!exact); + map2 = isl_map_read_from_str(ctx, + "[n] -> { [x] -> [y] : 1 <= n <= 10 and y >= n + x }"); + assert(isl_map_is_equal(map, map2)); + isl_map_free(map); + isl_map_free(map2); + + str = "[n, m] -> { [i0, i1, i2, i3] -> [o0, o1, o2, o3] : " + "i3 = 1 and o0 = i0 and o1 = -1 + i1 and o2 = -1 + i2 and " + "o3 = -2 + i2 and i1 <= -1 + i0 and i1 >= 1 - m + i0 and " + "i1 >= 2 and i1 <= n and i2 >= 3 and i2 <= 1 + n and i2 <= m }"; + map = isl_map_read_from_str(ctx, str); + map = isl_map_transitive_closure(map, &exact); + assert(exact); + map2 = isl_map_read_from_str(ctx, str); + assert(isl_map_is_equal(map, map2)); + isl_map_free(map); + isl_map_free(map2); + + str = "{[0] -> [1]; [2] -> [3]}"; + map = isl_map_read_from_str(ctx, str); + map = isl_map_transitive_closure(map, &exact); + assert(exact); + map2 = isl_map_read_from_str(ctx, str); + assert(isl_map_is_equal(map, map2)); + isl_map_free(map); + isl_map_free(map2); + + str = "[n] -> { [[i0, i1, 1, 0, i0] -> [i5, 1]] -> " + "[[i0, -1 + i1, 2, 0, i0] -> [-1 + i5, 2]] : " + "exists (e0 = [(3 - n)/3]: i5 >= 2 and i1 >= 2 and " + "3i0 <= -1 + n and i1 <= -1 + n and i5 <= -1 + n and " + "3e0 >= 1 - n and 3e0 <= 2 - n and 3i0 >= -2 + n); " + "[[i0, i1, 2, 0, i0] -> [i5, 1]] -> " + "[[i0, i1, 1, 0, i0] -> [-1 + i5, 2]] : " + "exists (e0 = [(3 - n)/3]: i5 >= 2 and i1 >= 1 and " + "3i0 <= -1 + n and i1 <= -1 + n and i5 <= -1 + n and " + "3e0 >= 1 - n and 3e0 <= 2 - n and 3i0 >= -2 + n); " + "[[i0, i1, 1, 0, i0] -> [i5, 2]] -> " + "[[i0, -1 + i1, 2, 0, i0] -> [i5, 1]] : " + "exists (e0 = [(3 - n)/3]: i1 >= 2 and i5 >= 1 and " + "3i0 <= -1 + n and i1 <= -1 + n and i5 <= -1 + n and " + "3e0 >= 1 - n and 3e0 <= 2 - n and 3i0 >= -2 + n); " + "[[i0, i1, 2, 0, i0] -> [i5, 2]] -> " + "[[i0, i1, 1, 0, i0] -> [i5, 1]] : " + "exists (e0 = [(3 - n)/3]: i5 >= 1 and i1 >= 1 and " + "3i0 <= -1 + n and i1 <= -1 + n and i5 <= -1 + n and " + "3e0 >= 1 - n and 3e0 <= 2 - n and 3i0 >= -2 + n) }"; + map = isl_map_read_from_str(ctx, str); + map = isl_map_transitive_closure(map, NULL); + assert(map); + isl_map_free(map); + + return 0; +} + +/* Check that the actual result of a boolean operation is equal + * to the expected result. + */ +static isl_stat check_bool(isl_ctx *ctx, isl_bool actual, isl_bool expected) +{ + if (actual != expected) + isl_die(ctx, isl_error_unknown, + "incorrect boolean operation", return isl_stat_error); + return isl_stat_ok; +} + +/* Test operations on isl_bool values. + * + * This tests: + * + * isl_bool_not + * isl_bool_ok + */ +static int test_isl_bool(isl_ctx *ctx) +{ + if (check_bool(ctx, isl_bool_not(isl_bool_true), isl_bool_false) < 0) + return -1; + if (check_bool(ctx, isl_bool_not(isl_bool_false), isl_bool_true) < 0) + return -1; + if (check_bool(ctx, isl_bool_not(isl_bool_error), isl_bool_error) < 0) + return -1; + if (check_bool(ctx, isl_bool_ok(0), isl_bool_false) < 0) + return -1; + if (check_bool(ctx, isl_bool_ok(1), isl_bool_true) < 0) + return -1; + if (check_bool(ctx, isl_bool_ok(-1), isl_bool_true) < 0) + return -1; + if (check_bool(ctx, isl_bool_ok(2), isl_bool_true) < 0) + return -1; + if (check_bool(ctx, isl_bool_ok(-2), isl_bool_true) < 0) + return -1; + + return 0; +} + +static int test_lex(struct isl_ctx *ctx) +{ + isl_space *space; + isl_map *map; + int empty; + + space = isl_space_set_alloc(ctx, 0, 0); + map = isl_map_lex_le(space); + empty = isl_map_is_empty(map); + isl_map_free(map); + + if (empty < 0) + return -1; + if (empty) + isl_die(ctx, isl_error_unknown, + "expecting non-empty result", return -1); + + return 0; +} + +/* Inputs for isl_map_lexmin tests. + * "map" is the input and "lexmin" is the expected result. + */ +struct { + const char *map; + const char *lexmin; +} lexmin_tests [] = { + { "{ [x] -> [y] : x <= y <= 10; [x] -> [5] : -8 <= x <= 8 }", + "{ [x] -> [5] : 6 <= x <= 8; " + "[x] -> [x] : x <= 5 or (9 <= x <= 10) }" }, + { "{ [x] -> [y] : 4y = x or 4y = -1 + x or 4y = -2 + x }", + "{ [x] -> [y] : 4y = x or 4y = -1 + x or 4y = -2 + x }" }, + { "{ [x] -> [y] : x = 4y; [x] -> [y] : x = 2y }", + "{ [x] -> [y] : (4y = x and x >= 0) or " + "(exists (e0 = [(x)/4], e1 = [(-2 + x)/4]: 2y = x and " + "4e1 = -2 + x and 4e0 <= -1 + x and 4e0 >= -3 + x)) or " + "(exists (e0 = [(x)/4]: 2y = x and 4e0 = x and x <= -4)) }" }, + { "{ T[a] -> S[b, c] : a = 4b-2c and c >= b }", + "{ T[a] -> S[b, c] : 2b = a and 2c = a }" }, + /* Check that empty pieces are properly combined. */ + { "[K, N] -> { [x, y] -> [a, b] : K+2<=N<=K+4 and x>=4 and " + "2N-6<=x=N and a>=x+1 }", + "[K, N] -> { [x, y] -> [1 + x, N] : x >= -6 + 2N and " + "x <= -5 + 2N and x >= -1 + 3K - N and x <= -2 + K + N and " + "x >= 4 }" }, + { "{ [i, k, j] -> [a, b, c, d] : 8*floor((b)/8) = b and k <= 255 and " + "a <= 255 and c <= 255 and d <= 255 - j and " + "255 - j <= 7d <= 7 - i and 240d <= 239 + a and " + "247d <= 247 + k - j and 247d <= 247 + k - b and " + "247d <= 247 + i and 248 - b <= 248d <= c and " + "254d >= i - a + b and 254d >= -a + b and " + "255d >= -i + a - b and 1792d >= -63736 + 257b }", + "{ [i, k, j] -> " + "[-127762 + i + 502j, -62992 + 248j, 63240 - 248j, 255 - j] : " + "k <= 255 and 7j >= 1778 + i and 246j >= 62738 - k and " + "247j >= 62738 - i and 509j <= 129795 + i and " + "742j >= 188724 - i; " + "[0, k, j] -> [1, 0, 248, 1] : k <= 255 and 248 <= j <= 254, k }" }, + { "{ [a] -> [b] : 0 <= b <= 255 and -509 + a <= 512b < a and " + "16*floor((8 + b)/16) <= 7 + b; " + "[a] -> [1] }", + "{ [a] -> [b = 1] : a >= 510 or a <= 0; " + "[a] -> [b = 0] : 0 < a <= 509 }" }, + { "{ rat: [i] : 1 <= 2i <= 9 }", "{ rat: [i] : 2i = 1 }" }, + { "{ rat: [i] : 1 <= 2i <= 9 or i >= 10 }", "{ rat: [i] : 2i = 1 }" }, + { "{ rat: [i] : 21 <= 2i <= 29 or i = 5 }", "{ rat: [5] }" }, +}; + +static int test_lexmin(struct isl_ctx *ctx) +{ + int i; + int equal; + const char *str; + isl_basic_map *bmap; + isl_map *map, *map2; + isl_set *set; + isl_set *set2; + isl_pw_multi_aff *pma; + + str = "[p0, p1] -> { [] -> [] : " + "exists (e0 = [(2p1)/3], e1, e2, e3 = [(3 - p1 + 3e0)/3], " + "e4 = [(p1)/3], e5 = [(p1 + 3e4)/3]: " + "3e0 >= -2 + 2p1 and 3e0 >= p1 and 3e3 >= 1 - p1 + 3e0 and " + "3e0 <= 2p1 and 3e3 >= -2 + p1 and 3e3 <= -1 + p1 and p1 >= 3 and " + "3e5 >= -2 + 2p1 and 3e5 >= p1 and 3e5 <= -1 + p1 + 3e4 and " + "3e4 <= p1 and 3e4 >= -2 + p1 and e3 <= -1 + e0 and " + "3e4 >= 6 - p1 + 3e1 and 3e1 >= p1 and 3e5 >= -2 + p1 + 3e4 and " + "2e4 >= 3 - p1 + 2e1 and e4 <= e1 and 3e3 <= 2 - p1 + 3e0 and " + "e5 >= 1 + e1 and 3e4 >= 6 - 2p1 + 3e1 and " + "p0 >= 2 and p1 >= p0 and 3e2 >= p1 and 3e4 >= 6 - p1 + 3e2 and " + "e2 <= e1 and e3 >= 1 and e4 <= e2) }"; + map = isl_map_read_from_str(ctx, str); + map = isl_map_lexmin(map); + isl_map_free(map); + if (!map) + return -1; + + str = "[C] -> { [obj,a,b,c] : obj <= 38 a + 7 b + 10 c and " + "a + b <= 1 and c <= 10 b and c <= C and a,b,c,C >= 0 }"; + set = isl_set_read_from_str(ctx, str); + set = isl_set_lexmax(set); + str = "[C] -> { [obj,a,b,c] : C = 8 }"; + set2 = isl_set_read_from_str(ctx, str); + set = isl_set_intersect(set, set2); + assert(!isl_set_is_empty(set)); + isl_set_free(set); + + for (i = 0; i < ARRAY_SIZE(lexmin_tests); ++i) { + map = isl_map_read_from_str(ctx, lexmin_tests[i].map); + map = isl_map_lexmin(map); + map2 = isl_map_read_from_str(ctx, lexmin_tests[i].lexmin); + equal = isl_map_is_equal(map, map2); + isl_map_free(map); + isl_map_free(map2); + + if (equal < 0) + return -1; + if (!equal) + isl_die(ctx, isl_error_unknown, + "unexpected result", return -1); + } + + str = "{ [i] -> [i', j] : j = i - 8i' and i' >= 0 and i' <= 7 and " + " 8i' <= i and 8i' >= -7 + i }"; + bmap = isl_basic_map_read_from_str(ctx, str); + pma = isl_basic_map_lexmin_pw_multi_aff(isl_basic_map_copy(bmap)); + map2 = isl_map_from_pw_multi_aff(pma); + map = isl_map_from_basic_map(bmap); + assert(isl_map_is_equal(map, map2)); + isl_map_free(map); + isl_map_free(map2); + + str = "[i] -> { [i', j] : j = i - 8i' and i' >= 0 and i' <= 7 and " + " 8i' <= i and 8i' >= -7 + i }"; + set = isl_set_read_from_str(ctx, str); + pma = isl_set_lexmin_pw_multi_aff(isl_set_copy(set)); + set2 = isl_set_from_pw_multi_aff(pma); + equal = isl_set_is_equal(set, set2); + isl_set_free(set); + isl_set_free(set2); + if (equal < 0) + return -1; + if (!equal) + isl_die(ctx, isl_error_unknown, + "unexpected difference between set and " + "piecewise affine expression", return -1); + + return 0; +} + +/* Inputs for isl_pw_multi_aff_max_multi_val tests. + * "pma" is the input. + * "res" is the expected result. + */ +static struct { + const char *pma; + const char *res; +} opt_pw_tests[] = { + { "{ [-1] -> [-1]; [1] -> [1] }", "{ [1] }" }, + { "{ [a, b] -> [floor((b - 2*floor((-a)/4))/5)] : " + "0 <= a, b <= 100 and b mod 2 = 0}", "{ [30] }" }, + { "[N] -> { [i,j] -> A[i, -i, i + j] : 0 <= i,j <= N <= 10 }", + "{ A[10, 0, 20] }" }, + { "[N] -> {A[N, -N, 2N] : 0 <= N }", "{ A[infty, 0, infty] }" }, +}; + +/* Perform basic isl_pw_multi_aff_max_multi_val tests. + */ +static isl_stat test_pw_max(struct isl_ctx *ctx) +{ + int i; + isl_pw_multi_aff *pma; + isl_multi_val *mv; + isl_stat r; + + for (i = 0; i < ARRAY_SIZE(opt_pw_tests); ++i) { + pma = isl_pw_multi_aff_read_from_str(ctx, opt_pw_tests[i].pma); + mv = isl_pw_multi_aff_max_multi_val(pma); + r = multi_val_check_plain_equal(mv, opt_pw_tests[i].res); + isl_multi_val_free(mv); + + if (r < 0) + return isl_stat_error; + } + + return isl_stat_ok; +} + +/* A specialized isl_set_min_val test case that would return the wrong result + * in earlier versions of isl. + * The explicit call to isl_basic_set_union prevents the second basic set + * from being determined to be empty prior to the call to isl_set_min_val, + * at least at the point where this test case was introduced. + */ +static int test_min_special(isl_ctx *ctx) +{ + const char *str; + isl_basic_set *bset1, *bset2; + isl_set *set; + isl_aff *obj; + isl_val *res; + int ok; + + str = "{ [a, b] : a >= 2 and b >= 0 and 14 - a <= b <= 9 }"; + bset1 = isl_basic_set_read_from_str(ctx, str); + str = "{ [a, b] : 1 <= a, b and a + b <= 1 }"; + bset2 = isl_basic_set_read_from_str(ctx, str); + set = isl_basic_set_union(bset1, bset2); + obj = isl_aff_read_from_str(ctx, "{ [a, b] -> [a] }"); + + res = isl_set_min_val(set, obj); + ok = isl_val_cmp_si(res, 5) == 0; + + isl_aff_free(obj); + isl_set_free(set); + isl_val_free(res); + + if (!res) + return -1; + if (!ok) + isl_die(ctx, isl_error_unknown, "unexpected minimum", + return -1); + + return 0; +} + +/* A specialized isl_set_min_val test case that would return an error + * in earlier versions of isl. + */ +static int test_min_special2(isl_ctx *ctx) +{ + const char *str; + isl_basic_set *bset; + isl_aff *obj; + isl_val *res; + + str = "{ [i, j, k] : 2j = i and 2k = i + 1 and i >= 2 }"; + bset = isl_basic_set_read_from_str(ctx, str); + + obj = isl_aff_read_from_str(ctx, "{ [i, j, k] -> [i] }"); + + res = isl_basic_set_max_val(bset, obj); + + isl_basic_set_free(bset); + isl_aff_free(obj); + isl_val_free(res); + + if (!res) + return -1; + + return 0; +} + +/* Check that the result of isl_set_min_multi_pw_aff + * on the union of the sets with string descriptions "s1" and "s2" + * consists of a single expression (on a single cell). + */ +static isl_stat check_single_expr_min(isl_ctx *ctx, const char *s1, + const char *s2) +{ + isl_size n; + isl_set *set1, *set2; + isl_multi_pw_aff *mpa; + isl_pw_multi_aff *pma; + + set1 = isl_set_read_from_str(ctx, s1); + set2 = isl_set_read_from_str(ctx, s2); + set1 = isl_set_union(set1, set2); + mpa = isl_set_min_multi_pw_aff(set1); + pma = isl_pw_multi_aff_from_multi_pw_aff(mpa); + n = isl_pw_multi_aff_n_piece(pma); + isl_pw_multi_aff_free(pma); + + if (n < 0) + return isl_stat_error; + if (n != 1) + isl_die(ctx, isl_error_unknown, "expecting single expression", + return isl_stat_error); + return isl_stat_ok; +} + +/* A specialized isl_set_min_multi_pw_aff test that checks + * that the minimum of 2N and 3N for N >= 0 is represented + * by a single expression, without splitting off the special case N = 0. + * Do this for both orderings. + */ +static int test_min_mpa(isl_ctx *ctx) +{ + const char *s1, *s2; + + s1 = "[N=0:] -> { [1, 3N:] }"; + s2 = "[N=0:] -> { [10, 2N:] }"; + if (check_single_expr_min(ctx, s1, s2) < 0) + return -1; + if (check_single_expr_min(ctx, s2, s1) < 0) + return -1; + + return 0; +} + +struct { + const char *set; + const char *obj; + __isl_give isl_val *(*fn)(__isl_keep isl_set *set, + __isl_keep isl_aff *obj); + const char *res; +} opt_tests[] = { + { "{ [-1]; [1] }", "{ [x] -> [x] }", &isl_set_min_val, "-1" }, + { "{ [-1]; [1] }", "{ [x] -> [x] }", &isl_set_max_val, "1" }, + { "{ [a, b] : 0 <= a, b <= 100 and b mod 2 = 0}", + "{ [a, b] -> [floor((b - 2*floor((-a)/4))/5)] }", + &isl_set_max_val, "30" }, + +}; + +/* Perform basic isl_set_min_val and isl_set_max_val tests. + * In particular, check the results on non-convex inputs. + */ +static int test_min(struct isl_ctx *ctx) +{ + int i; + isl_set *set; + isl_aff *obj; + isl_val *val, *res; + isl_bool ok; + + for (i = 0; i < ARRAY_SIZE(opt_tests); ++i) { + set = isl_set_read_from_str(ctx, opt_tests[i].set); + obj = isl_aff_read_from_str(ctx, opt_tests[i].obj); + res = isl_val_read_from_str(ctx, opt_tests[i].res); + val = opt_tests[i].fn(set, obj); + ok = isl_val_eq(res, val); + isl_val_free(res); + isl_val_free(val); + isl_aff_free(obj); + isl_set_free(set); + + if (ok < 0) + return -1; + if (!ok) + isl_die(ctx, isl_error_unknown, + "unexpected optimum", return -1); + } + + if (test_pw_max(ctx) < 0) + return -1; + if (test_min_special(ctx) < 0) + return -1; + if (test_min_special2(ctx) < 0) + return -1; + + return 0; +} + +struct must_may { + isl_map *must; + isl_map *may; +}; + +static isl_stat collect_must_may(__isl_take isl_map *dep, int must, + void *dep_user, void *user) +{ + struct must_may *mm = (struct must_may *)user; + + if (must) + mm->must = isl_map_union(mm->must, dep); + else + mm->may = isl_map_union(mm->may, dep); + + return isl_stat_ok; +} + +static int common_space(void *first, void *second) +{ + int depth = *(int *)first; + return 2 * depth; +} + +static int map_is_equal(__isl_keep isl_map *map, const char *str) +{ + isl_map *map2; + int equal; + + if (!map) + return -1; + + map2 = isl_map_read_from_str(map->ctx, str); + equal = isl_map_is_equal(map, map2); + isl_map_free(map2); + + return equal; +} + +static int map_check_equal(__isl_keep isl_map *map, const char *str) +{ + int equal; + + equal = map_is_equal(map, str); + if (equal < 0) + return -1; + if (!equal) + isl_die(isl_map_get_ctx(map), isl_error_unknown, + "result not as expected", return -1); + return 0; +} + +/* Is "set" equal to the set described by "str"? + */ +static isl_bool set_is_equal(__isl_keep isl_set *set, const char *str) +{ + isl_set *set2; + isl_bool equal; + + if (!set) + return isl_bool_error; + + set2 = isl_set_read_from_str(isl_set_get_ctx(set), str); + equal = isl_set_is_equal(set, set2); + isl_set_free(set2); + + return equal; +} + +/* Check that "set" is equal to the set described by "str". + */ +static isl_stat set_check_equal(__isl_keep isl_set *set, const char *str) +{ + isl_bool equal; + + equal = set_is_equal(set, str); + if (equal < 0) + return isl_stat_error; + if (!equal) + isl_die(isl_set_get_ctx(set), isl_error_unknown, + "result not as expected", return isl_stat_error); + return isl_stat_ok; +} + +/* Is "uset" equal to the union set described by "str"? + */ +static isl_bool uset_is_equal(__isl_keep isl_union_set *uset, const char *str) +{ + isl_union_set *uset2; + isl_bool equal; + + if (!uset) + return isl_bool_error; + + uset2 = isl_union_set_read_from_str(isl_union_set_get_ctx(uset), str); + equal = isl_union_set_is_equal(uset, uset2); + isl_union_set_free(uset2); + + return equal; +} + +/* Check that "uset" is equal to the union set described by "str". + */ +static isl_stat uset_check_equal(__isl_keep isl_union_set *uset, + const char *str) +{ + isl_bool equal; + + equal = uset_is_equal(uset, str); + if (equal < 0) + return isl_stat_error; + if (!equal) + isl_die(isl_union_set_get_ctx(uset), isl_error_unknown, + "result not as expected", return isl_stat_error); + return isl_stat_ok; +} + +static int test_dep(struct isl_ctx *ctx) +{ + const char *str; + isl_space *space; + isl_map *map; + isl_access_info *ai; + isl_flow *flow; + int depth; + struct must_may mm; + + depth = 3; + + str = "{ [2,i,0] -> [i] : 0 <= i <= 10 }"; + map = isl_map_read_from_str(ctx, str); + ai = isl_access_info_alloc(map, &depth, &common_space, 2); + + str = "{ [0,i,0] -> [i] : 0 <= i <= 10 }"; + map = isl_map_read_from_str(ctx, str); + ai = isl_access_info_add_source(ai, map, 1, &depth); + + str = "{ [1,i,0] -> [5] : 0 <= i <= 10 }"; + map = isl_map_read_from_str(ctx, str); + ai = isl_access_info_add_source(ai, map, 1, &depth); + + flow = isl_access_info_compute_flow(ai); + space = isl_space_alloc(ctx, 0, 3, 3); + mm.must = isl_map_empty(isl_space_copy(space)); + mm.may = isl_map_empty(space); + + isl_flow_foreach(flow, collect_must_may, &mm); + + str = "{ [0,i,0] -> [2,i,0] : (0 <= i <= 4) or (6 <= i <= 10); " + " [1,10,0] -> [2,5,0] }"; + assert(map_is_equal(mm.must, str)); + str = "{ [i,j,k] -> [l,m,n] : 1 = 0 }"; + assert(map_is_equal(mm.may, str)); + + isl_map_free(mm.must); + isl_map_free(mm.may); + isl_flow_free(flow); + + + str = "{ [2,i,0] -> [i] : 0 <= i <= 10 }"; + map = isl_map_read_from_str(ctx, str); + ai = isl_access_info_alloc(map, &depth, &common_space, 2); + + str = "{ [0,i,0] -> [i] : 0 <= i <= 10 }"; + map = isl_map_read_from_str(ctx, str); + ai = isl_access_info_add_source(ai, map, 1, &depth); + + str = "{ [1,i,0] -> [5] : 0 <= i <= 10 }"; + map = isl_map_read_from_str(ctx, str); + ai = isl_access_info_add_source(ai, map, 0, &depth); + + flow = isl_access_info_compute_flow(ai); + space = isl_space_alloc(ctx, 0, 3, 3); + mm.must = isl_map_empty(isl_space_copy(space)); + mm.may = isl_map_empty(space); + + isl_flow_foreach(flow, collect_must_may, &mm); + + str = "{ [0,i,0] -> [2,i,0] : (0 <= i <= 4) or (6 <= i <= 10) }"; + assert(map_is_equal(mm.must, str)); + str = "{ [0,5,0] -> [2,5,0]; [1,i,0] -> [2,5,0] : 0 <= i <= 10 }"; + assert(map_is_equal(mm.may, str)); + + isl_map_free(mm.must); + isl_map_free(mm.may); + isl_flow_free(flow); + + + str = "{ [2,i,0] -> [i] : 0 <= i <= 10 }"; + map = isl_map_read_from_str(ctx, str); + ai = isl_access_info_alloc(map, &depth, &common_space, 2); + + str = "{ [0,i,0] -> [i] : 0 <= i <= 10 }"; + map = isl_map_read_from_str(ctx, str); + ai = isl_access_info_add_source(ai, map, 0, &depth); + + str = "{ [1,i,0] -> [5] : 0 <= i <= 10 }"; + map = isl_map_read_from_str(ctx, str); + ai = isl_access_info_add_source(ai, map, 0, &depth); + + flow = isl_access_info_compute_flow(ai); + space = isl_space_alloc(ctx, 0, 3, 3); + mm.must = isl_map_empty(isl_space_copy(space)); + mm.may = isl_map_empty(space); + + isl_flow_foreach(flow, collect_must_may, &mm); + + str = "{ [0,i,0] -> [2,i,0] : 0 <= i <= 10; " + " [1,i,0] -> [2,5,0] : 0 <= i <= 10 }"; + assert(map_is_equal(mm.may, str)); + str = "{ [i,j,k] -> [l,m,n] : 1 = 0 }"; + assert(map_is_equal(mm.must, str)); + + isl_map_free(mm.must); + isl_map_free(mm.may); + isl_flow_free(flow); + + + str = "{ [0,i,2] -> [i] : 0 <= i <= 10 }"; + map = isl_map_read_from_str(ctx, str); + ai = isl_access_info_alloc(map, &depth, &common_space, 2); + + str = "{ [0,i,0] -> [i] : 0 <= i <= 10 }"; + map = isl_map_read_from_str(ctx, str); + ai = isl_access_info_add_source(ai, map, 0, &depth); + + str = "{ [0,i,1] -> [5] : 0 <= i <= 10 }"; + map = isl_map_read_from_str(ctx, str); + ai = isl_access_info_add_source(ai, map, 0, &depth); + + flow = isl_access_info_compute_flow(ai); + space = isl_space_alloc(ctx, 0, 3, 3); + mm.must = isl_map_empty(isl_space_copy(space)); + mm.may = isl_map_empty(space); + + isl_flow_foreach(flow, collect_must_may, &mm); + + str = "{ [0,i,0] -> [0,i,2] : 0 <= i <= 10; " + " [0,i,1] -> [0,5,2] : 0 <= i <= 5 }"; + assert(map_is_equal(mm.may, str)); + str = "{ [i,j,k] -> [l,m,n] : 1 = 0 }"; + assert(map_is_equal(mm.must, str)); + + isl_map_free(mm.must); + isl_map_free(mm.may); + isl_flow_free(flow); + + + str = "{ [0,i,1] -> [i] : 0 <= i <= 10 }"; + map = isl_map_read_from_str(ctx, str); + ai = isl_access_info_alloc(map, &depth, &common_space, 2); + + str = "{ [0,i,0] -> [i] : 0 <= i <= 10 }"; + map = isl_map_read_from_str(ctx, str); + ai = isl_access_info_add_source(ai, map, 0, &depth); + + str = "{ [0,i,2] -> [5] : 0 <= i <= 10 }"; + map = isl_map_read_from_str(ctx, str); + ai = isl_access_info_add_source(ai, map, 0, &depth); + + flow = isl_access_info_compute_flow(ai); + space = isl_space_alloc(ctx, 0, 3, 3); + mm.must = isl_map_empty(isl_space_copy(space)); + mm.may = isl_map_empty(space); + + isl_flow_foreach(flow, collect_must_may, &mm); + + str = "{ [0,i,0] -> [0,i,1] : 0 <= i <= 10; " + " [0,i,2] -> [0,5,1] : 0 <= i <= 4 }"; + assert(map_is_equal(mm.may, str)); + str = "{ [i,j,k] -> [l,m,n] : 1 = 0 }"; + assert(map_is_equal(mm.must, str)); + + isl_map_free(mm.must); + isl_map_free(mm.may); + isl_flow_free(flow); + + + depth = 5; + + str = "{ [1,i,0,0,0] -> [i,j] : 0 <= i <= 10 and 0 <= j <= 10 }"; + map = isl_map_read_from_str(ctx, str); + ai = isl_access_info_alloc(map, &depth, &common_space, 1); + + str = "{ [0,i,0,j,0] -> [i,j] : 0 <= i <= 10 and 0 <= j <= 10 }"; + map = isl_map_read_from_str(ctx, str); + ai = isl_access_info_add_source(ai, map, 1, &depth); + + flow = isl_access_info_compute_flow(ai); + space = isl_space_alloc(ctx, 0, 5, 5); + mm.must = isl_map_empty(isl_space_copy(space)); + mm.may = isl_map_empty(space); + + isl_flow_foreach(flow, collect_must_may, &mm); + + str = "{ [0,i,0,j,0] -> [1,i,0,0,0] : 0 <= i,j <= 10 }"; + assert(map_is_equal(mm.must, str)); + str = "{ [0,0,0,0,0] -> [0,0,0,0,0] : 1 = 0 }"; + assert(map_is_equal(mm.may, str)); + + isl_map_free(mm.must); + isl_map_free(mm.may); + isl_flow_free(flow); + + return 0; +} + +/* Check that the dependence analysis proceeds without errors. + * Earlier versions of isl would break down during the analysis + * due to the use of the wrong spaces. + */ +static int test_flow(isl_ctx *ctx) +{ + const char *str; + isl_union_map *access, *schedule; + isl_union_map *must_dep, *may_dep; + int r; + + str = "{ S0[j] -> i[]; S1[j,i] -> i[]; S2[] -> i[]; S3[] -> i[] }"; + access = isl_union_map_read_from_str(ctx, str); + str = "{ S0[j] -> [0,j,0,0] : 0 <= j < 10; " + "S1[j,i] -> [0,j,1,i] : 0 <= j < i < 10; " + "S2[] -> [1,0,0,0]; " + "S3[] -> [-1,0,0,0] }"; + schedule = isl_union_map_read_from_str(ctx, str); + r = isl_union_map_compute_flow(access, isl_union_map_copy(access), + isl_union_map_copy(access), schedule, + &must_dep, &may_dep, NULL, NULL); + isl_union_map_free(may_dep); + isl_union_map_free(must_dep); + + return r; +} + +struct { + const char *map; + int sv; +} sv_tests[] = { + { "[N] -> { [i] -> [f] : 0 <= i <= N and 0 <= i - 10 f <= 9 }", 1 }, + { "[N] -> { [i] -> [f] : 0 <= i <= N and 0 <= i - 10 f <= 10 }", 0 }, + { "{ [i] -> [3*floor(i/2) + 5*floor(i/3)] }", 1 }, + { "{ S1[i] -> [i] : 0 <= i <= 9; S2[i] -> [i] : 0 <= i <= 9 }", 1 }, + { "{ [i] -> S1[i] : 0 <= i <= 9; [i] -> S2[i] : 0 <= i <= 9 }", 0 }, + { "{ A[i] -> [i]; B[i] -> [i]; B[i] -> [i + 1] }", 0 }, + { "{ A[i] -> [i]; B[i] -> [i] : i < 0; B[i] -> [i + 1] : i > 0 }", 1 }, + { "{ A[i] -> [i]; B[i] -> A[i] : i < 0; B[i] -> [i + 1] : i > 0 }", 1 }, + { "{ A[i] -> [i]; B[i] -> [j] : i - 1 <= j <= i }", 0 }, +}; + +int test_sv(isl_ctx *ctx) +{ + isl_union_map *umap; + int i; + int sv; + + for (i = 0; i < ARRAY_SIZE(sv_tests); ++i) { + umap = isl_union_map_read_from_str(ctx, sv_tests[i].map); + sv = isl_union_map_is_single_valued(umap); + isl_union_map_free(umap); + if (sv < 0) + return -1; + if (sv_tests[i].sv && !sv) + isl_die(ctx, isl_error_internal, + "map not detected as single valued", return -1); + if (!sv_tests[i].sv && sv) + isl_die(ctx, isl_error_internal, + "map detected as single valued", return -1); + } + + return 0; +} + +struct { + const char *str; + int bijective; +} bijective_tests[] = { + { "[N,M]->{[i,j] -> [i]}", 0 }, + { "[N,M]->{[i,j] -> [i] : j=i}", 1 }, + { "[N,M]->{[i,j] -> [i] : j=0}", 1 }, + { "[N,M]->{[i,j] -> [i] : j=N}", 1 }, + { "[N,M]->{[i,j] -> [j,i]}", 1 }, + { "[N,M]->{[i,j] -> [i+j]}", 0 }, + { "[N,M]->{[i,j] -> []}", 0 }, + { "[N,M]->{[i,j] -> [i,j,N]}", 1 }, + { "[N,M]->{[i,j] -> [2i]}", 0 }, + { "[N,M]->{[i,j] -> [i,i]}", 0 }, + { "[N,M]->{[i,j] -> [2i,i]}", 0 }, + { "[N,M]->{[i,j] -> [2i,j]}", 1 }, + { "[N,M]->{[i,j] -> [x,y] : 2x=i & y =j}", 1 }, +}; + +static int test_bijective(struct isl_ctx *ctx) +{ + isl_map *map; + int i; + int bijective; + + for (i = 0; i < ARRAY_SIZE(bijective_tests); ++i) { + map = isl_map_read_from_str(ctx, bijective_tests[i].str); + bijective = isl_map_is_bijective(map); + isl_map_free(map); + if (bijective < 0) + return -1; + if (bijective_tests[i].bijective && !bijective) + isl_die(ctx, isl_error_internal, + "map not detected as bijective", return -1); + if (!bijective_tests[i].bijective && bijective) + isl_die(ctx, isl_error_internal, + "map detected as bijective", return -1); + } + + return 0; +} + +/* Inputs for isl_pw_qpolynomial_gist tests. + * "pwqp" is the input, "set" is the context and "gist" is the expected result. + */ +struct { + const char *pwqp; + const char *set; + const char *gist; +} pwqp_gist_tests[] = { + { "{ [i] -> i }", "{ [k] : exists a : k = 2a }", "{ [i] -> i }" }, + { "{ [i] -> i + [ (i + [i/3])/2 ] }", "{ [10] }", "{ [i] -> 16 }" }, + { "{ [i] -> ([(i)/2]) }", "{ [k] : exists a : k = 2a+1 }", + "{ [i] -> -1/2 + 1/2 * i }" }, + { "{ [i] -> i^2 : i != 0 }", "{ [i] : i != 0 }", "{ [i] -> i^2 }" }, + { "{ [i] -> i^2 : i > 0; [i] -> i^2 : i < 0 }", "{ [i] : i != 0 }", + "{ [i] -> i^2 }" }, +}; + +/* Perform some basic isl_pw_qpolynomial_gist tests. + */ +static isl_stat test_pwqp_gist(isl_ctx *ctx) +{ + int i; + const char *str; + isl_set *set; + isl_pw_qpolynomial *pwqp1, *pwqp2; + isl_bool equal; + + for (i = 0; i < ARRAY_SIZE(pwqp_gist_tests); ++i) { + str = pwqp_gist_tests[i].pwqp; + pwqp1 = isl_pw_qpolynomial_read_from_str(ctx, str); + str = pwqp_gist_tests[i].set; + set = isl_set_read_from_str(ctx, str); + pwqp1 = isl_pw_qpolynomial_gist(pwqp1, set); + str = pwqp_gist_tests[i].gist; + pwqp2 = isl_pw_qpolynomial_read_from_str(ctx, str); + pwqp1 = isl_pw_qpolynomial_sub(pwqp1, pwqp2); + equal = isl_pw_qpolynomial_is_zero(pwqp1); + isl_pw_qpolynomial_free(pwqp1); + + if (equal < 0) + return isl_stat_error; + if (!equal) + isl_die(ctx, isl_error_unknown, + "unexpected result", return isl_stat_error); + } + + return isl_stat_ok; +} + +/* Perform a basic isl_pw_qpolynomial_max test. + */ +static isl_stat test_pwqp_max(isl_ctx *ctx) +{ + const char *str; + isl_pw_qpolynomial *pwqp; + isl_val *v; + int ok; + + str = "{ [x=2:9, y] -> floor((x + 1)/4)^3 - floor((2x)/3)^2 }"; + pwqp = isl_pw_qpolynomial_read_from_str(ctx, str); + v = isl_pw_qpolynomial_max(pwqp); + ok = isl_val_cmp_si(v, -1) == 0; + isl_val_free(v); + + if (!v) + return isl_stat_error; + if (!ok) + isl_die(ctx, isl_error_unknown, "unexpected maximum", + return isl_stat_error); + + return isl_stat_ok; +} + +static int test_pwqp(struct isl_ctx *ctx) +{ + const char *str; + isl_set *set; + isl_pw_qpolynomial *pwqp1, *pwqp2; + int equal; + + str = "{ [i,j,k] -> 1 + 9 * [i/5] + 7 * [j/11] + 4 * [k/13] }"; + pwqp1 = isl_pw_qpolynomial_read_from_str(ctx, str); + + pwqp1 = isl_pw_qpolynomial_move_dims(pwqp1, isl_dim_param, 0, + isl_dim_in, 1, 1); + + str = "[j] -> { [i,k] -> 1 + 9 * [i/5] + 7 * [j/11] + 4 * [k/13] }"; + pwqp2 = isl_pw_qpolynomial_read_from_str(ctx, str); + + pwqp1 = isl_pw_qpolynomial_sub(pwqp1, pwqp2); + + assert(isl_pw_qpolynomial_is_zero(pwqp1)); + + isl_pw_qpolynomial_free(pwqp1); + + if (test_pwqp_gist(ctx) < 0) + return -1; + + str = "{ [i] -> ([([i/2] + [i/2])/5]) }"; + pwqp1 = isl_pw_qpolynomial_read_from_str(ctx, str); + str = "{ [i] -> ([(2 * [i/2])/5]) }"; + pwqp2 = isl_pw_qpolynomial_read_from_str(ctx, str); + + pwqp1 = isl_pw_qpolynomial_sub(pwqp1, pwqp2); + + assert(isl_pw_qpolynomial_is_zero(pwqp1)); + + isl_pw_qpolynomial_free(pwqp1); + + str = "{ [x] -> ([x/2] + [(x+1)/2]) }"; + pwqp1 = isl_pw_qpolynomial_read_from_str(ctx, str); + str = "{ [x] -> x }"; + pwqp2 = isl_pw_qpolynomial_read_from_str(ctx, str); + + pwqp1 = isl_pw_qpolynomial_sub(pwqp1, pwqp2); + + assert(isl_pw_qpolynomial_is_zero(pwqp1)); + + isl_pw_qpolynomial_free(pwqp1); + + str = "{ [i] -> ([i/2]) : i >= 0; [i] -> ([i/3]) : i < 0 }"; + pwqp1 = isl_pw_qpolynomial_read_from_str(ctx, str); + pwqp2 = isl_pw_qpolynomial_read_from_str(ctx, str); + pwqp1 = isl_pw_qpolynomial_coalesce(pwqp1); + pwqp1 = isl_pw_qpolynomial_sub(pwqp1, pwqp2); + assert(isl_pw_qpolynomial_is_zero(pwqp1)); + isl_pw_qpolynomial_free(pwqp1); + + str = "{ [a,b,a] -> (([(2*[a/3]+b)/5]) * ([(2*[a/3]+b)/5])) }"; + pwqp2 = isl_pw_qpolynomial_read_from_str(ctx, str); + str = "{ [a,b,c] -> (([(2*[a/3]+b)/5]) * ([(2*[c/3]+b)/5])) }"; + pwqp1 = isl_pw_qpolynomial_read_from_str(ctx, str); + set = isl_set_read_from_str(ctx, "{ [a,b,a] }"); + pwqp1 = isl_pw_qpolynomial_intersect_domain(pwqp1, set); + equal = isl_pw_qpolynomial_plain_is_equal(pwqp1, pwqp2); + isl_pw_qpolynomial_free(pwqp1); + isl_pw_qpolynomial_free(pwqp2); + if (equal < 0) + return -1; + if (!equal) + isl_die(ctx, isl_error_unknown, "unexpected result", return -1); + + str = "{ [a,b,c] -> (([(2*[a/3]+1)/5]) * ([(2*[c/3]+1)/5])) : b = 1 }"; + pwqp2 = isl_pw_qpolynomial_read_from_str(ctx, str); + str = "{ [a,b,c] -> (([(2*[a/3]+b)/5]) * ([(2*[c/3]+b)/5])) }"; + pwqp1 = isl_pw_qpolynomial_read_from_str(ctx, str); + pwqp1 = isl_pw_qpolynomial_fix_val(pwqp1, isl_dim_set, 1, + isl_val_one(ctx)); + equal = isl_pw_qpolynomial_plain_is_equal(pwqp1, pwqp2); + isl_pw_qpolynomial_free(pwqp1); + isl_pw_qpolynomial_free(pwqp2); + if (equal < 0) + return -1; + if (!equal) + isl_die(ctx, isl_error_unknown, "unexpected result", return -1); + + if (test_pwqp_max(ctx) < 0) + return -1; + + return 0; +} + +static int test_split_periods(isl_ctx *ctx) +{ + const char *str; + isl_pw_qpolynomial *pwqp; + + str = "{ [U,V] -> 1/3 * U + 2/3 * V - [(U + 2V)/3] + [U/2] : " + "U + 2V + 3 >= 0 and - U -2V >= 0 and - U + 10 >= 0 and " + "U >= 0; [U,V] -> U^2 : U >= 100 }"; + pwqp = isl_pw_qpolynomial_read_from_str(ctx, str); + + pwqp = isl_pw_qpolynomial_split_periods(pwqp, 2); + + isl_pw_qpolynomial_free(pwqp); + + if (!pwqp) + return -1; + + return 0; +} + +static int test_union(isl_ctx *ctx) +{ + const char *str; + isl_union_set *uset1, *uset2; + isl_union_map *umap1, *umap2; + int equal; + + str = "{ [i] : 0 <= i <= 1 }"; + uset1 = isl_union_set_read_from_str(ctx, str); + str = "{ [1] -> [0] }"; + umap1 = isl_union_map_read_from_str(ctx, str); + + umap2 = isl_union_set_lex_gt_union_set(isl_union_set_copy(uset1), uset1); + equal = isl_union_map_is_equal(umap1, umap2); + + isl_union_map_free(umap1); + isl_union_map_free(umap2); + + if (equal < 0) + return -1; + if (!equal) + isl_die(ctx, isl_error_unknown, "union maps not equal", + return -1); + + str = "{ A[i] -> B[i]; B[i] -> C[i]; A[0] -> C[1] }"; + umap1 = isl_union_map_read_from_str(ctx, str); + str = "{ A[i]; B[i] }"; + uset1 = isl_union_set_read_from_str(ctx, str); + + uset2 = isl_union_map_domain(umap1); + + equal = isl_union_set_is_equal(uset1, uset2); + + isl_union_set_free(uset1); + isl_union_set_free(uset2); + + if (equal < 0) + return -1; + if (!equal) + isl_die(ctx, isl_error_unknown, "union sets not equal", + return -1); + + return 0; +} + +/* Inputs for basic isl_pw_qpolynomial_bound tests. + * "type" is the type of bound that should be computed. + * "poly" is a string representation of the input. + * "bound" is a string representation of the expected result. + * "tight" is set if the result is expected to be tight. + */ +static struct { + int tight; + enum isl_fold type; + const char *poly; + const char *bound; +} bound_tests[] = { + /* Check that computing a bound of a non-zero polynomial + * over an unbounded domain does not produce a rational value. + * In particular, check that the upper bound is infinity. + */ + { 0, isl_fold_max, "{ [m, n] -> -m * n }", "{ max(infty) }" }, + { 1, isl_fold_max, "{ [[a, b, c, d] -> [e]] -> 0 }", + "{ [a, b, c, d] -> max(0) }" }, + { 1, isl_fold_max, "{ [[x] -> [x]] -> 1 : exists a : x = 2 a }", + "{ [x] -> max(1) : x mod 2 = 0 }" }, + { 1, isl_fold_min, "{ [x=5:10] -> (x + 2)^2 }", "{ min(49) }" }, + { 1, isl_fold_max, "{ [0:10] -> 1 }", "{ max(1) }" }, + { 1, isl_fold_max, "{ [[m] -> [0:m]] -> m^2 }", + "{ [m] -> max(m^2) : m >= 0 }" }, +}; + +/* Check that the bound computation can handle differences + * in domain dimension names of the input polynomial and its domain. + */ +static isl_stat test_bound_space(isl_ctx *ctx) +{ + const char *str; + isl_set *set; + isl_pw_qpolynomial *pwqp; + isl_pw_qpolynomial_fold *pwf; + + str = "{ [[c] -> [c]] }"; + set = isl_set_read_from_str(ctx, str); + str = "{ [[a] -> [b]] -> 1 }"; + pwqp = isl_pw_qpolynomial_read_from_str(ctx, str); + pwqp = isl_pw_qpolynomial_intersect_domain(pwqp, set); + pwf = isl_pw_qpolynomial_bound(pwqp, isl_fold_max, NULL); + isl_pw_qpolynomial_fold_free(pwf); + + return isl_stat_non_null(pwf); +} + +/* Perform basic isl_pw_qpolynomial_bound tests. + */ +static int test_bound(isl_ctx *ctx) +{ + int i; + + if (test_bound_space(ctx) < 0) + return -1; + + for (i = 0; i < ARRAY_SIZE(bound_tests); ++i) { + const char *str; + enum isl_fold type; + isl_bool equal, tight; + isl_pw_qpolynomial *pwqp; + isl_pw_qpolynomial_fold *pwf1, *pwf2; + + str = bound_tests[i].poly; + pwqp = isl_pw_qpolynomial_read_from_str(ctx, str); + type = bound_tests[i].type; + pwf1 = isl_pw_qpolynomial_bound(pwqp, type, &tight); + str = bound_tests[i].bound; + pwf2 = isl_pw_qpolynomial_fold_read_from_str(ctx, str); + equal = isl_pw_qpolynomial_fold_plain_is_equal(pwf1, pwf2); + isl_pw_qpolynomial_fold_free(pwf2); + isl_pw_qpolynomial_fold_free(pwf1); + if (equal < 0) + return -1; + if (!equal) + isl_die(ctx, isl_error_unknown, + "incorrect bound result", return -1); + if (bound_tests[i].tight && !tight) + isl_die(ctx, isl_error_unknown, + "bound unexpectedly not tight", return -1); + } + + return 0; +} + +/* isl_set is defined to isl_map internally, so the corresponding elements + * are isl_basic_map objects. + */ +#undef EL_BASE +#undef SET_BASE +#define EL_BASE basic_map +#define SET_BASE set +#include "isl_test_list_templ.c" + +#undef EL_BASE +#undef SET_BASE +#define EL_BASE basic_set +#define SET_BASE union_set +#include "isl_test_list_templ.c" + +#undef EL_BASE +#undef SET_BASE +#define EL_BASE set +#define SET_BASE union_set +#include "isl_test_list_templ.c" + +#undef EL_BASE +#undef SET_BASE +#define EL_BASE basic_map +#define SET_BASE map +#include "isl_test_list_templ.c" + +#undef EL_BASE +#undef SET_BASE +#define EL_BASE map +#define SET_BASE union_map +#include "isl_test_list_templ.c" + +/* Check that the conversion from isl objects to lists works as expected. + */ +static int test_get_list(isl_ctx *ctx) +{ + if (test_get_list_basic_map_from_set(ctx, "{ [0]; [2]; [3] }")) + return -1; + if (test_get_list_basic_set_from_union_set(ctx, "{ A[0]; B[2]; B[3] }")) + return -1; + if (test_get_list_set_from_union_set(ctx, "{ A[0]; A[2]; B[3] }")) + return -1; + if (test_get_list_basic_map_from_map(ctx, + "{ [0] -> [0]; [2] -> [0]; [3] -> [0] }")) + return -1; + if (test_get_list_map_from_union_map(ctx, + "{ A[0] -> [0]; A[2] -> [0]; B[3] -> [0] }")) + return -1; + + return 0; +} + +static int test_lift(isl_ctx *ctx) +{ + const char *str; + isl_basic_map *bmap; + isl_basic_set *bset; + + str = "{ [i0] : exists e0 : i0 = 4e0 }"; + bset = isl_basic_set_read_from_str(ctx, str); + bset = isl_basic_set_lift(bset); + bmap = isl_basic_map_from_range(bset); + bset = isl_basic_map_domain(bmap); + isl_basic_set_free(bset); + + return 0; +} + +/* Check that isl_set_is_subset is not confused by identical + * integer divisions. + * The call to isl_set_normalize ensures that the equality constraints + * a = b = 0 are discovered, turning e0 and e1 into identical + * integer divisions. Any further simplification would remove + * the duplicate integer divisions. + */ +static isl_stat test_subset_duplicate_integer_divisions(isl_ctx *ctx) +{ + const char *str; + isl_bool is_subset; + isl_set *set1, *set2; + + str = "{ [a, b, c, d] : " + "exists (e0 = floor((a + d)/4), e1 = floor((d)/4), " + "e2 = floor((-a - d + 4 *floor((a + d)/4))/10), " + "e3 = floor((-d + 4*floor((d)/4))/10): " + "10e2 = -a - 2c - d + 4e0 and 10e3 = -2c - d + 4e1 and " + "b >= 0 and a <= 0 and b <= a) }"; + set1 = isl_set_read_from_str(ctx, str); + set2 = isl_set_read_from_str(ctx, str); + set2 = isl_set_normalize(set2); + + is_subset = isl_set_is_subset(set1, set2); + + isl_set_free(set1); + isl_set_free(set2); + + if (is_subset < 0) + return isl_stat_error; + if (!is_subset) + isl_die(ctx, isl_error_unknown, + "set is not considered to be a subset of itself", + return isl_stat_error); + + return isl_stat_ok; +} + +struct { + const char *set1; + const char *set2; + int subset; +} subset_tests[] = { + { "{ [112, 0] }", + "{ [i0, i1] : exists (e0 = [(i0 - i1)/16], e1: " + "16e0 <= i0 - i1 and 16e0 >= -15 + i0 - i1 and " + "16e1 <= i1 and 16e0 >= -i1 and 16e1 >= -i0 + i1) }", 1 }, + { "{ [65] }", + "{ [i] : exists (e0 = [(255i)/256], e1 = [(127i + 65e0)/191], " + "e2 = [(3i + 61e1)/65], e3 = [(52i + 12e2)/61], " + "e4 = [(2i + e3)/3], e5 = [(4i + e3)/4], e6 = [(8i + e3)/12]: " + "3e4 = 2i + e3 and 4e5 = 4i + e3 and 12e6 = 8i + e3 and " + "i <= 255 and 64e3 >= -45 + 67i and i >= 0 and " + "256e0 <= 255i and 256e0 >= -255 + 255i and " + "191e1 <= 127i + 65e0 and 191e1 >= -190 + 127i + 65e0 and " + "65e2 <= 3i + 61e1 and 65e2 >= -64 + 3i + 61e1 and " + "61e3 <= 52i + 12e2 and 61e3 >= -60 + 52i + 12e2) }", 1 }, + { "{ [i] : 0 <= i <= 10 }", "{ rat: [i] : 0 <= i <= 10 }", 1 }, + { "{ rat: [i] : 0 <= i <= 10 }", "{ [i] : 0 <= i <= 10 }", 0 }, + { "{ rat: [0] }", "{ [i] : 0 <= i <= 10 }", 1 }, + { "{ rat: [(1)/2] }", "{ [i] : 0 <= i <= 10 }", 0 }, + { "{ [t, i] : (exists (e0 = [(2 + t)/4]: 4e0 <= 2 + t and " + "4e0 >= -1 + t and i >= 57 and i <= 62 and " + "4e0 <= 62 + t - i and 4e0 >= -61 + t + i and " + "t >= 0 and t <= 511 and 4e0 <= -57 + t + i and " + "4e0 >= 58 + t - i and i >= 58 + t and i >= 62 - t)) }", + "{ [i0, i1] : (exists (e0 = [(4 + i0)/4]: 4e0 <= 62 + i0 - i1 and " + "4e0 >= 1 + i0 and i0 >= 0 and i0 <= 511 and " + "4e0 <= -57 + i0 + i1)) or " + "(exists (e0 = [(2 + i0)/4]: 4e0 <= i0 and " + "4e0 >= 58 + i0 - i1 and i0 >= 2 and i0 <= 511 and " + "4e0 >= -61 + i0 + i1)) or " + "(i1 <= 66 - i0 and i0 >= 2 and i1 >= 59 + i0) }", 1 }, + { "[a, b] -> { : a = 0 and b = -1 }", "[b, a] -> { : b >= -10 }", 1 }, +}; + +static int test_subset(isl_ctx *ctx) +{ + int i; + isl_set *set1, *set2; + int subset; + + if (test_subset_duplicate_integer_divisions(ctx) < 0) + return -1; + + for (i = 0; i < ARRAY_SIZE(subset_tests); ++i) { + set1 = isl_set_read_from_str(ctx, subset_tests[i].set1); + set2 = isl_set_read_from_str(ctx, subset_tests[i].set2); + subset = isl_set_is_subset(set1, set2); + isl_set_free(set1); + isl_set_free(set2); + if (subset < 0) + return -1; + if (subset != subset_tests[i].subset) + isl_die(ctx, isl_error_unknown, + "incorrect subset result", return -1); + } + + return 0; +} + +/* Perform a set subtraction with a set that has a non-obviously empty disjunct. + * Older versions of isl would fail on such cases. + */ +static isl_stat test_subtract_empty(isl_ctx *ctx) +{ + const char *str; + isl_set *s1, *s2; + + s1 = isl_set_read_from_str(ctx, "{ [0] }"); + str = "{ [a] : (exists (e0, e1, e2: 1056e1 <= 32 + a - 33e0 and " + "1089e1 >= a - 33e0 and 1089e1 <= 1 + a - 33e0 and " + "33e2 >= -a + 33e0 + 1056e1 and " + "33e2 < -2a + 66e0 + 2112e1)) or a = 0 }"; + s2 = isl_set_read_from_str(ctx, str); + s1 = isl_set_subtract(s1, s2); + isl_set_free(s1); + + return isl_stat_non_null(s1); +} + +struct { + const char *minuend; + const char *subtrahend; + const char *difference; +} subtract_domain_tests[] = { + { "{ A[i] -> B[i] }", "{ A[i] }", "{ }" }, + { "{ A[i] -> B[i] }", "{ B[i] }", "{ A[i] -> B[i] }" }, + { "{ A[i] -> B[i] }", "{ A[i] : i > 0 }", "{ A[i] -> B[i] : i <= 0 }" }, +}; + +static int test_subtract(isl_ctx *ctx) +{ + int i; + isl_union_map *umap1, *umap2; + isl_union_pw_multi_aff *upma1, *upma2; + isl_union_set *uset; + int equal; + + if (test_subtract_empty(ctx) < 0) + return -1; + + for (i = 0; i < ARRAY_SIZE(subtract_domain_tests); ++i) { + umap1 = isl_union_map_read_from_str(ctx, + subtract_domain_tests[i].minuend); + uset = isl_union_set_read_from_str(ctx, + subtract_domain_tests[i].subtrahend); + umap2 = isl_union_map_read_from_str(ctx, + subtract_domain_tests[i].difference); + umap1 = isl_union_map_subtract_domain(umap1, uset); + equal = isl_union_map_is_equal(umap1, umap2); + isl_union_map_free(umap1); + isl_union_map_free(umap2); + if (equal < 0) + return -1; + if (!equal) + isl_die(ctx, isl_error_unknown, + "incorrect subtract domain result", return -1); + } + + for (i = 0; i < ARRAY_SIZE(subtract_domain_tests); ++i) { + upma1 = isl_union_pw_multi_aff_read_from_str(ctx, + subtract_domain_tests[i].minuend); + uset = isl_union_set_read_from_str(ctx, + subtract_domain_tests[i].subtrahend); + upma2 = isl_union_pw_multi_aff_read_from_str(ctx, + subtract_domain_tests[i].difference); + upma1 = isl_union_pw_multi_aff_subtract_domain(upma1, uset); + equal = isl_union_pw_multi_aff_plain_is_equal(upma1, upma2); + isl_union_pw_multi_aff_free(upma1); + isl_union_pw_multi_aff_free(upma2); + if (equal < 0) + return -1; + if (!equal) + isl_die(ctx, isl_error_unknown, + "incorrect subtract domain result", return -1); + } + + return 0; +} + +/* Check that intersecting the empty basic set with another basic set + * does not increase the number of constraints. In particular, + * the empty basic set should maintain its canonical representation. + */ +static int test_intersect_1(isl_ctx *ctx) +{ + isl_size n1, n2; + isl_basic_set *bset1, *bset2; + + bset1 = isl_basic_set_read_from_str(ctx, "{ [a,b,c] : 1 = 0 }"); + bset2 = isl_basic_set_read_from_str(ctx, "{ [1,2,3] }"); + n1 = isl_basic_set_n_constraint(bset1); + bset1 = isl_basic_set_intersect(bset1, bset2); + n2 = isl_basic_set_n_constraint(bset1); + isl_basic_set_free(bset1); + if (n1 < 0 || n2 < 0) + return -1; + if (n1 != n2) + isl_die(ctx, isl_error_unknown, + "number of constraints of empty set changed", + return -1); + + return 0; +} + +/* Check that intersecting a set with itself does not cause + * an explosion in the number of disjuncts. + */ +static isl_stat test_intersect_2(isl_ctx *ctx) +{ + int i; + isl_set *set; + + set = isl_set_read_from_str(ctx, "{ [x,y] : x >= 0 or y >= 0 }"); + for (i = 0; i < 100; ++i) + set = isl_set_intersect(set, isl_set_copy(set)); + isl_set_free(set); + if (!set) + return isl_stat_error; + return isl_stat_ok; +} + +/* Perform some intersection tests. + */ +static int test_intersect(isl_ctx *ctx) +{ + if (test_intersect_1(ctx) < 0) + return -1; + if (test_intersect_2(ctx) < 0) + return -1; + + return 0; +} + +int test_factorize(isl_ctx *ctx) +{ + const char *str; + isl_basic_set *bset; + isl_factorizer *f; + + str = "{ [i0, i1, i2, i3, i4, i5, i6, i7] : 3i5 <= 2 - 2i0 and " + "i0 >= -2 and i6 >= 1 + i3 and i7 >= 0 and 3i5 >= -2i0 and " + "2i4 <= i2 and i6 >= 1 + 2i0 + 3i1 and i4 <= -1 and " + "i6 >= 1 + 2i0 + 3i5 and i6 <= 2 + 2i0 + 3i5 and " + "3i5 <= 2 - 2i0 - i2 + 3i4 and i6 <= 2 + 2i0 + 3i1 and " + "i0 <= -1 and i7 <= i2 + i3 - 3i4 - i6 and " + "3i5 >= -2i0 - i2 + 3i4 }"; + bset = isl_basic_set_read_from_str(ctx, str); + f = isl_basic_set_factorizer(bset); + isl_basic_set_free(bset); + isl_factorizer_free(f); + if (!f) + isl_die(ctx, isl_error_unknown, + "failed to construct factorizer", return -1); + + str = "{ [i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12] : " + "i12 <= 2 + i0 - i11 and 2i8 >= -i4 and i11 >= i1 and " + "3i5 <= -i2 and 2i11 >= -i4 - 2i7 and i11 <= 3 + i0 + 3i9 and " + "i11 <= -i4 - 2i7 and i12 >= -i10 and i2 >= -2 and " + "i11 >= i1 + 3i10 and i11 >= 1 + i0 + 3i9 and " + "i11 <= 1 - i4 - 2i8 and 6i6 <= 6 - i2 and 3i6 >= 1 - i2 and " + "i11 <= 2 + i1 and i12 <= i4 + i11 and i12 >= i0 - i11 and " + "3i5 >= -2 - i2 and i12 >= -1 + i4 + i11 and 3i3 <= 3 - i2 and " + "9i6 <= 11 - i2 + 6i5 and 3i3 >= 1 - i2 and " + "9i6 <= 5 - i2 + 6i3 and i12 <= -1 and i2 <= 0 }"; + bset = isl_basic_set_read_from_str(ctx, str); + f = isl_basic_set_factorizer(bset); + isl_basic_set_free(bset); + isl_factorizer_free(f); + if (!f) + isl_die(ctx, isl_error_unknown, + "failed to construct factorizer", return -1); + + return 0; +} + +static isl_stat check_injective(__isl_take isl_map *map, void *user) +{ + int *injective = user; + + *injective = isl_map_is_injective(map); + isl_map_free(map); + + if (*injective < 0 || !*injective) + return isl_stat_error; + + return isl_stat_ok; +} + +int test_one_schedule(isl_ctx *ctx, const char *d, const char *w, + const char *r, const char *s, int tilable, int parallel) +{ + int i; + isl_union_set *D; + isl_union_map *W, *R, *S; + isl_union_map *empty; + isl_union_map *dep_raw, *dep_war, *dep_waw, *dep; + isl_union_map *validity, *proximity, *coincidence; + isl_union_map *schedule; + isl_union_map *test; + isl_union_set *delta; + isl_union_set *domain; + isl_set *delta_set; + isl_set *slice; + isl_set *origin; + isl_schedule_constraints *sc; + isl_schedule *sched; + int is_nonneg, is_parallel, is_tilable, is_injection, is_complete; + isl_size n; + + D = isl_union_set_read_from_str(ctx, d); + W = isl_union_map_read_from_str(ctx, w); + R = isl_union_map_read_from_str(ctx, r); + S = isl_union_map_read_from_str(ctx, s); + + W = isl_union_map_intersect_domain(W, isl_union_set_copy(D)); + R = isl_union_map_intersect_domain(R, isl_union_set_copy(D)); + + empty = isl_union_map_empty(isl_union_map_get_space(S)); + isl_union_map_compute_flow(isl_union_map_copy(R), + isl_union_map_copy(W), empty, + isl_union_map_copy(S), + &dep_raw, NULL, NULL, NULL); + isl_union_map_compute_flow(isl_union_map_copy(W), + isl_union_map_copy(W), + isl_union_map_copy(R), + isl_union_map_copy(S), + &dep_waw, &dep_war, NULL, NULL); + + dep = isl_union_map_union(dep_waw, dep_war); + dep = isl_union_map_union(dep, dep_raw); + validity = isl_union_map_copy(dep); + coincidence = isl_union_map_copy(dep); + proximity = isl_union_map_copy(dep); + + sc = isl_schedule_constraints_on_domain(isl_union_set_copy(D)); + sc = isl_schedule_constraints_set_validity(sc, validity); + sc = isl_schedule_constraints_set_coincidence(sc, coincidence); + sc = isl_schedule_constraints_set_proximity(sc, proximity); + sched = isl_schedule_constraints_compute_schedule(sc); + schedule = isl_schedule_get_map(sched); + isl_schedule_free(sched); + isl_union_map_free(W); + isl_union_map_free(R); + isl_union_map_free(S); + + is_injection = 1; + isl_union_map_foreach_map(schedule, &check_injective, &is_injection); + + domain = isl_union_map_domain(isl_union_map_copy(schedule)); + is_complete = isl_union_set_is_subset(D, domain); + isl_union_set_free(D); + isl_union_set_free(domain); + + test = isl_union_map_reverse(isl_union_map_copy(schedule)); + test = isl_union_map_apply_range(test, dep); + test = isl_union_map_apply_range(test, schedule); + + delta = isl_union_map_deltas(test); + n = isl_union_set_n_set(delta); + if (n < 0) { + isl_union_set_free(delta); + return -1; + } + if (n == 0) { + is_tilable = 1; + is_parallel = 1; + is_nonneg = 1; + isl_union_set_free(delta); + } else { + isl_size dim; + + delta_set = isl_set_from_union_set(delta); + + slice = isl_set_universe(isl_set_get_space(delta_set)); + for (i = 0; i < tilable; ++i) + slice = isl_set_lower_bound_si(slice, isl_dim_set, i, 0); + is_tilable = isl_set_is_subset(delta_set, slice); + isl_set_free(slice); + + slice = isl_set_universe(isl_set_get_space(delta_set)); + for (i = 0; i < parallel; ++i) + slice = isl_set_fix_si(slice, isl_dim_set, i, 0); + is_parallel = isl_set_is_subset(delta_set, slice); + isl_set_free(slice); + + origin = isl_set_universe(isl_set_get_space(delta_set)); + dim = isl_set_dim(origin, isl_dim_set); + if (dim < 0) + origin = isl_set_free(origin); + for (i = 0; i < dim; ++i) + origin = isl_set_fix_si(origin, isl_dim_set, i, 0); + + delta_set = isl_set_union(delta_set, isl_set_copy(origin)); + delta_set = isl_set_lexmin(delta_set); + + is_nonneg = isl_set_is_equal(delta_set, origin); + + isl_set_free(origin); + isl_set_free(delta_set); + } + + if (is_nonneg < 0 || is_parallel < 0 || is_tilable < 0 || + is_injection < 0 || is_complete < 0) + return -1; + if (!is_complete) + isl_die(ctx, isl_error_unknown, + "generated schedule incomplete", return -1); + if (!is_injection) + isl_die(ctx, isl_error_unknown, + "generated schedule not injective on each statement", + return -1); + if (!is_nonneg) + isl_die(ctx, isl_error_unknown, + "negative dependences in generated schedule", + return -1); + if (!is_tilable) + isl_die(ctx, isl_error_unknown, + "generated schedule not as tilable as expected", + return -1); + if (!is_parallel) + isl_die(ctx, isl_error_unknown, + "generated schedule not as parallel as expected", + return -1); + + return 0; +} + +/* Compute a schedule for the given instance set, validity constraints, + * proximity constraints and context and return a corresponding union map + * representation. + */ +static __isl_give isl_union_map *compute_schedule_with_context(isl_ctx *ctx, + const char *domain, const char *validity, const char *proximity, + const char *context) +{ + isl_set *con; + isl_union_set *dom; + isl_union_map *dep; + isl_union_map *prox; + isl_schedule_constraints *sc; + isl_schedule *schedule; + isl_union_map *sched; + + con = isl_set_read_from_str(ctx, context); + dom = isl_union_set_read_from_str(ctx, domain); + dep = isl_union_map_read_from_str(ctx, validity); + prox = isl_union_map_read_from_str(ctx, proximity); + sc = isl_schedule_constraints_on_domain(dom); + sc = isl_schedule_constraints_set_context(sc, con); + sc = isl_schedule_constraints_set_validity(sc, dep); + sc = isl_schedule_constraints_set_proximity(sc, prox); + schedule = isl_schedule_constraints_compute_schedule(sc); + sched = isl_schedule_get_map(schedule); + isl_schedule_free(schedule); + + return sched; +} + +/* Compute a schedule for the given instance set, validity constraints and + * proximity constraints and return a corresponding union map representation. + */ +static __isl_give isl_union_map *compute_schedule(isl_ctx *ctx, + const char *domain, const char *validity, const char *proximity) +{ + return compute_schedule_with_context(ctx, domain, validity, proximity, + "{ : }"); +} + +/* Check that a schedule can be constructed on the given domain + * with the given validity and proximity constraints. + */ +static int test_has_schedule(isl_ctx *ctx, const char *domain, + const char *validity, const char *proximity) +{ + isl_union_map *sched; + + sched = compute_schedule(ctx, domain, validity, proximity); + if (!sched) + return -1; + + isl_union_map_free(sched); + return 0; +} + +int test_special_schedule(isl_ctx *ctx, const char *domain, + const char *validity, const char *proximity, const char *expected_sched) +{ + isl_union_map *sched1, *sched2; + int equal; + + sched1 = compute_schedule(ctx, domain, validity, proximity); + sched2 = isl_union_map_read_from_str(ctx, expected_sched); + + equal = isl_union_map_is_equal(sched1, sched2); + isl_union_map_free(sched1); + isl_union_map_free(sched2); + + if (equal < 0) + return -1; + if (!equal) + isl_die(ctx, isl_error_unknown, "unexpected schedule", + return -1); + + return 0; +} + +/* Check that the schedule map is properly padded, i.e., that the range + * lives in a single space. + */ +static int test_padded_schedule(isl_ctx *ctx) +{ + const char *str; + isl_union_set *D; + isl_union_map *validity, *proximity; + isl_schedule_constraints *sc; + isl_schedule *sched; + isl_union_map *umap; + isl_union_set *range; + isl_set *set; + + str = "[N] -> { S0[i] : 0 <= i <= N; S1[i, j] : 0 <= i, j <= N }"; + D = isl_union_set_read_from_str(ctx, str); + validity = isl_union_map_empty(isl_union_set_get_space(D)); + proximity = isl_union_map_copy(validity); + sc = isl_schedule_constraints_on_domain(D); + sc = isl_schedule_constraints_set_validity(sc, validity); + sc = isl_schedule_constraints_set_proximity(sc, proximity); + sched = isl_schedule_constraints_compute_schedule(sc); + umap = isl_schedule_get_map(sched); + isl_schedule_free(sched); + range = isl_union_map_range(umap); + set = isl_set_from_union_set(range); + isl_set_free(set); + + if (!set) + return -1; + + return 0; +} + +/* Check that conditional validity constraints are also taken into + * account across bands. + * In particular, try to make sure that live ranges D[1,0]->C[2,1] and + * D[2,0]->C[3,0] are not local in the outer band of the generated schedule + * and then check that the adjacent order constraint C[2,1]->D[2,0] + * is enforced by the rest of the schedule. + */ +static int test_special_conditional_schedule_constraints(isl_ctx *ctx) +{ + const char *str; + isl_union_set *domain; + isl_union_map *validity, *proximity, *condition; + isl_union_map *sink, *source, *dep; + isl_schedule_constraints *sc; + isl_schedule *schedule; + isl_union_access_info *access; + isl_union_flow *flow; + int empty; + + str = "[n] -> { C[k, i] : k <= -1 + n and i >= 0 and i <= -1 + k; " + "A[k] : k >= 1 and k <= -1 + n; " + "B[k, i] : k <= -1 + n and i >= 0 and i <= -1 + k; " + "D[k, i] : k <= -1 + n and i >= 0 and i <= -1 + k }"; + domain = isl_union_set_read_from_str(ctx, str); + sc = isl_schedule_constraints_on_domain(domain); + str = "[n] -> { D[k, i] -> C[1 + k, k - i] : " + "k <= -2 + n and i >= 1 and i <= -1 + k; " + "D[k, i] -> C[1 + k, i] : " + "k <= -2 + n and i >= 1 and i <= -1 + k; " + "D[k, 0] -> C[1 + k, k] : k >= 1 and k <= -2 + n; " + "D[k, 0] -> C[1 + k, 0] : k >= 1 and k <= -2 + n }"; + validity = isl_union_map_read_from_str(ctx, str); + sc = isl_schedule_constraints_set_validity(sc, validity); + str = "[n] -> { C[k, i] -> D[k, i] : " + "0 <= i <= -1 + k and k <= -1 + n }"; + proximity = isl_union_map_read_from_str(ctx, str); + sc = isl_schedule_constraints_set_proximity(sc, proximity); + str = "[n] -> { [D[k, i] -> a[]] -> [C[1 + k, k - i] -> b[]] : " + "i <= -1 + k and i >= 1 and k <= -2 + n; " + "[B[k, i] -> c[]] -> [B[k, 1 + i] -> c[]] : " + "k <= -1 + n and i >= 0 and i <= -2 + k }"; + condition = isl_union_map_read_from_str(ctx, str); + str = "[n] -> { [B[k, i] -> e[]] -> [D[k, i] -> a[]] : " + "i >= 0 and i <= -1 + k and k <= -1 + n; " + "[C[k, i] -> b[]] -> [D[k', -1 + k - i] -> a[]] : " + "i >= 0 and i <= -1 + k and k <= -1 + n and " + "k' <= -1 + n and k' >= k - i and k' >= 1 + k; " + "[C[k, i] -> b[]] -> [D[k, -1 + k - i] -> a[]] : " + "i >= 0 and i <= -1 + k and k <= -1 + n; " + "[B[k, i] -> c[]] -> [A[k'] -> d[]] : " + "k <= -1 + n and i >= 0 and i <= -1 + k and " + "k' >= 1 and k' <= -1 + n and k' >= 1 + k }"; + validity = isl_union_map_read_from_str(ctx, str); + sc = isl_schedule_constraints_set_conditional_validity(sc, condition, + validity); + schedule = isl_schedule_constraints_compute_schedule(sc); + str = "{ D[2,0] -> [] }"; + sink = isl_union_map_read_from_str(ctx, str); + access = isl_union_access_info_from_sink(sink); + str = "{ C[2,1] -> [] }"; + source = isl_union_map_read_from_str(ctx, str); + access = isl_union_access_info_set_must_source(access, source); + access = isl_union_access_info_set_schedule(access, schedule); + flow = isl_union_access_info_compute_flow(access); + dep = isl_union_flow_get_must_dependence(flow); + isl_union_flow_free(flow); + empty = isl_union_map_is_empty(dep); + isl_union_map_free(dep); + + if (empty < 0) + return -1; + if (empty) + isl_die(ctx, isl_error_unknown, + "conditional validity not respected", return -1); + + return 0; +} + +/* Check that the test for violated conditional validity constraints + * is not confused by domain compression. + * In particular, earlier versions of isl would apply + * a schedule on the compressed domains to the original domains, + * resulting in a failure to detect that the default schedule + * violates the conditional validity constraints. + */ +static int test_special_conditional_schedule_constraints_2(isl_ctx *ctx) +{ + const char *str; + isl_bool empty; + isl_union_set *domain; + isl_union_map *validity, *condition; + isl_schedule_constraints *sc; + isl_schedule *schedule; + isl_union_map *umap; + isl_map *map, *ge; + + str = "{ A[0, i] : 0 <= i <= 10; B[1, i] : 0 <= i <= 10 }"; + domain = isl_union_set_read_from_str(ctx, str); + sc = isl_schedule_constraints_on_domain(domain); + str = "{ B[1, i] -> A[0, i + 1] }"; + condition = isl_union_map_read_from_str(ctx, str); + str = "{ A[0, i] -> B[1, i - 1] }"; + validity = isl_union_map_read_from_str(ctx, str); + sc = isl_schedule_constraints_set_conditional_validity(sc, condition, + isl_union_map_copy(validity)); + schedule = isl_schedule_constraints_compute_schedule(sc); + umap = isl_schedule_get_map(schedule); + isl_schedule_free(schedule); + validity = isl_union_map_apply_domain(validity, + isl_union_map_copy(umap)); + validity = isl_union_map_apply_range(validity, umap); + map = isl_map_from_union_map(validity); + ge = isl_map_lex_ge(isl_space_domain(isl_map_get_space(map))); + map = isl_map_intersect(map, ge); + empty = isl_map_is_empty(map); + isl_map_free(map); + + if (empty < 0) + return -1; + if (!empty) + isl_die(ctx, isl_error_unknown, + "conditional validity constraints not satisfied", + return -1); + + return 0; +} + +/* Input for testing of schedule construction based on + * conditional constraints. + * + * domain is the iteration domain + * flow are the flow dependences, which determine the validity and + * proximity constraints + * condition are the conditions on the conditional validity constraints + * conditional_validity are the conditional validity constraints + * outer_band_n is the expected number of members in the outer band + */ +struct { + const char *domain; + const char *flow; + const char *condition; + const char *conditional_validity; + int outer_band_n; +} live_range_tests[] = { + /* Contrived example that illustrates that we need to keep + * track of tagged condition dependences and + * tagged conditional validity dependences + * in isl_sched_edge separately. + * In particular, the conditional validity constraints on A + * cannot be satisfied, + * but they can be ignored because there are no corresponding + * condition constraints. However, we do have an additional + * conditional validity constraint that maps to the same + * dependence relation + * as the condition constraint on B. If we did not make a distinction + * between tagged condition and tagged conditional validity + * dependences, then we + * could end up treating this shared dependence as an condition + * constraint on A, forcing a localization of the conditions, + * which is impossible. + */ + { "{ S[i] : 0 <= 1 < 100; T[i] : 0 <= 1 < 100 }", + "{ S[i] -> S[i+1] : 0 <= i < 99 }", + "{ [S[i] -> B[]] -> [S[i+1] -> B[]] : 0 <= i < 99 }", + "{ [S[i] -> A[]] -> [T[i'] -> A[]] : 0 <= i', i < 100 and i != i';" + "[T[i] -> A[]] -> [S[i'] -> A[]] : 0 <= i', i < 100 and i != i';" + "[S[i] -> A[]] -> [S[i+1] -> A[]] : 0 <= i < 99 }", + 1 + }, + /* TACO 2013 Fig. 7 */ + { "[n] -> { S1[i,j] : 0 <= i,j < n; S2[i,j] : 0 <= i,j < n }", + "[n] -> { S1[i,j] -> S2[i,j] : 0 <= i,j < n;" + "S2[i,j] -> S2[i,j+1] : 0 <= i < n and 0 <= j < n - 1 }", + "[n] -> { [S1[i,j] -> t[]] -> [S2[i,j] -> t[]] : 0 <= i,j < n;" + "[S2[i,j] -> x1[]] -> [S2[i,j+1] -> x1[]] : " + "0 <= i < n and 0 <= j < n - 1 }", + "[n] -> { [S2[i,j] -> t[]] -> [S1[i,j'] -> t[]] : " + "0 <= i < n and 0 <= j < j' < n;" + "[S2[i,j] -> t[]] -> [S1[i',j'] -> t[]] : " + "0 <= i < i' < n and 0 <= j,j' < n;" + "[S2[i,j] -> x1[]] -> [S2[i,j'] -> x1[]] : " + "0 <= i,j,j' < n and j < j' }", + 2 + }, + /* TACO 2013 Fig. 7, without tags */ + { "[n] -> { S1[i,j] : 0 <= i,j < n; S2[i,j] : 0 <= i,j < n }", + "[n] -> { S1[i,j] -> S2[i,j] : 0 <= i,j < n;" + "S2[i,j] -> S2[i,j+1] : 0 <= i < n and 0 <= j < n - 1 }", + "[n] -> { S1[i,j] -> S2[i,j] : 0 <= i,j < n;" + "S2[i,j] -> S2[i,j+1] : 0 <= i < n and 0 <= j < n - 1 }", + "[n] -> { S2[i,j] -> S1[i,j'] : 0 <= i < n and 0 <= j < j' < n;" + "S2[i,j] -> S1[i',j'] : 0 <= i < i' < n and 0 <= j,j' < n;" + "S2[i,j] -> S2[i,j'] : 0 <= i,j,j' < n and j < j' }", + 1 + }, + /* TACO 2013 Fig. 12 */ + { "{ S1[i,0] : 0 <= i <= 1; S2[i,j] : 0 <= i <= 1 and 1 <= j <= 2;" + "S3[i,3] : 0 <= i <= 1 }", + "{ S1[i,0] -> S2[i,1] : 0 <= i <= 1;" + "S2[i,1] -> S2[i,2] : 0 <= i <= 1;" + "S2[i,2] -> S3[i,3] : 0 <= i <= 1 }", + "{ [S1[i,0]->t[]] -> [S2[i,1]->t[]] : 0 <= i <= 1;" + "[S2[i,1]->t[]] -> [S2[i,2]->t[]] : 0 <= i <= 1;" + "[S2[i,2]->t[]] -> [S3[i,3]->t[]] : 0 <= i <= 1 }", + "{ [S2[i,1]->t[]] -> [S2[i,2]->t[]] : 0 <= i <= 1;" + "[S2[0,j]->t[]] -> [S2[1,j']->t[]] : 1 <= j,j' <= 2;" + "[S2[0,j]->t[]] -> [S1[1,0]->t[]] : 1 <= j <= 2;" + "[S3[0,3]->t[]] -> [S2[1,j]->t[]] : 1 <= j <= 2;" + "[S3[0,3]->t[]] -> [S1[1,0]->t[]] }", + 1 + } +}; + +/* Test schedule construction based on conditional constraints. + * In particular, check the number of members in the outer band node + * as an indication of whether tiling is possible or not. + */ +static int test_conditional_schedule_constraints(isl_ctx *ctx) +{ + int i; + isl_union_set *domain; + isl_union_map *condition; + isl_union_map *flow; + isl_union_map *validity; + isl_schedule_constraints *sc; + isl_schedule *schedule; + isl_schedule_node *node; + isl_size n_member; + + if (test_special_conditional_schedule_constraints(ctx) < 0) + return -1; + if (test_special_conditional_schedule_constraints_2(ctx) < 0) + return -1; + + for (i = 0; i < ARRAY_SIZE(live_range_tests); ++i) { + domain = isl_union_set_read_from_str(ctx, + live_range_tests[i].domain); + flow = isl_union_map_read_from_str(ctx, + live_range_tests[i].flow); + condition = isl_union_map_read_from_str(ctx, + live_range_tests[i].condition); + validity = isl_union_map_read_from_str(ctx, + live_range_tests[i].conditional_validity); + sc = isl_schedule_constraints_on_domain(domain); + sc = isl_schedule_constraints_set_validity(sc, + isl_union_map_copy(flow)); + sc = isl_schedule_constraints_set_proximity(sc, flow); + sc = isl_schedule_constraints_set_conditional_validity(sc, + condition, validity); + schedule = isl_schedule_constraints_compute_schedule(sc); + node = isl_schedule_get_root(schedule); + while (node && + isl_schedule_node_get_type(node) != isl_schedule_node_band) + node = isl_schedule_node_first_child(node); + n_member = isl_schedule_node_band_n_member(node); + isl_schedule_node_free(node); + isl_schedule_free(schedule); + + if (!schedule || n_member < 0) + return -1; + if (n_member != live_range_tests[i].outer_band_n) + isl_die(ctx, isl_error_unknown, + "unexpected number of members in outer band", + return -1); + } + return 0; +} + +/* Check that the schedule computed for the given instance set and + * dependence relation strongly satisfies the dependences. + * In particular, check that no instance is scheduled before + * or together with an instance on which it depends. + * Earlier versions of isl would produce a schedule that + * only weakly satisfies the dependences. + */ +static int test_strongly_satisfying_schedule(isl_ctx *ctx) +{ + const char *domain, *dep; + isl_union_map *D, *schedule; + isl_map *map, *ge; + int empty; + + domain = "{ B[i0, i1] : 0 <= i0 <= 1 and 0 <= i1 <= 11; " + "A[i0] : 0 <= i0 <= 1 }"; + dep = "{ B[i0, i1] -> B[i0, 1 + i1] : 0 <= i0 <= 1 and 0 <= i1 <= 10; " + "B[0, 11] -> A[1]; A[i0] -> B[i0, 0] : 0 <= i0 <= 1 }"; + schedule = compute_schedule(ctx, domain, dep, dep); + D = isl_union_map_read_from_str(ctx, dep); + D = isl_union_map_apply_domain(D, isl_union_map_copy(schedule)); + D = isl_union_map_apply_range(D, schedule); + map = isl_map_from_union_map(D); + ge = isl_map_lex_ge(isl_space_domain(isl_map_get_space(map))); + map = isl_map_intersect(map, ge); + empty = isl_map_is_empty(map); + isl_map_free(map); + + if (empty < 0) + return -1; + if (!empty) + isl_die(ctx, isl_error_unknown, + "dependences not strongly satisfied", return -1); + + return 0; +} + +/* Compute a schedule for input where the instance set constraints + * conflict with the context constraints. + * Earlier versions of isl did not properly handle this situation. + */ +static int test_conflicting_context_schedule(isl_ctx *ctx) +{ + isl_union_map *schedule; + const char *domain, *context; + + domain = "[n] -> { A[] : n >= 0 }"; + context = "[n] -> { : n < 0 }"; + schedule = compute_schedule_with_context(ctx, + domain, "{}", "{}", context); + isl_union_map_free(schedule); + + if (!schedule) + return -1; + + return 0; +} + +/* Check that a set of schedule constraints that only allow for + * a coalescing schedule still produces a schedule even if the user + * request a non-coalescing schedule. Earlier versions of isl + * would not handle this case correctly. + */ +static int test_coalescing_schedule(isl_ctx *ctx) +{ + const char *domain, *dep; + isl_union_set *I; + isl_union_map *D; + isl_schedule_constraints *sc; + isl_schedule *schedule; + int treat_coalescing; + + domain = "{ S[a, b] : 0 <= a <= 1 and 0 <= b <= 1 }"; + dep = "{ S[a, b] -> S[a + b, 1 - b] }"; + I = isl_union_set_read_from_str(ctx, domain); + D = isl_union_map_read_from_str(ctx, dep); + sc = isl_schedule_constraints_on_domain(I); + sc = isl_schedule_constraints_set_validity(sc, D); + treat_coalescing = isl_options_get_schedule_treat_coalescing(ctx); + isl_options_set_schedule_treat_coalescing(ctx, 1); + schedule = isl_schedule_constraints_compute_schedule(sc); + isl_options_set_schedule_treat_coalescing(ctx, treat_coalescing); + isl_schedule_free(schedule); + if (!schedule) + return -1; + return 0; +} + +/* Check that the scheduler does not perform any needless + * compound skewing. Earlier versions of isl would compute + * schedules in terms of transformed schedule coefficients and + * would not accurately keep track of the sum of the original + * schedule coefficients. It could then produce the schedule + * S[t,i,j,k] -> [t, 2t + i, 2t + i + j, 2t + i + j + k] + * for the input below instead of the schedule below. + */ +static int test_skewing_schedule(isl_ctx *ctx) +{ + const char *D, *V, *P, *S; + + D = "[n] -> { S[t,i,j,k] : 0 <= t,i,j,k < n }"; + V = "[n] -> { S[t,i,j,k] -> S[t+1,a,b,c] : 0 <= t,i,j,k,a,b,c < n and " + "-2 <= a-i <= 2 and -1 <= a-i + b-j <= 1 and " + "-1 <= a-i + b-j + c-k <= 1 }"; + P = "{ }"; + S = "{ S[t,i,j,k] -> [t, 2t + i, t + i + j, 2t + k] }"; + + return test_special_schedule(ctx, D, V, P, S); +} + +int test_schedule(isl_ctx *ctx) +{ + const char *D, *W, *R, *V, *P, *S; + int max_coincidence; + int treat_coalescing; + + /* Handle resulting schedule with zero bands. */ + if (test_one_schedule(ctx, "{[]}", "{}", "{}", "{[] -> []}", 0, 0) < 0) + return -1; + + /* Jacobi */ + D = "[T,N] -> { S1[t,i] : 1 <= t <= T and 2 <= i <= N - 1 }"; + W = "{ S1[t,i] -> a[t,i] }"; + R = "{ S1[t,i] -> a[t-1,i]; S1[t,i] -> a[t-1,i-1]; " + "S1[t,i] -> a[t-1,i+1] }"; + S = "{ S1[t,i] -> [t,i] }"; + if (test_one_schedule(ctx, D, W, R, S, 2, 0) < 0) + return -1; + + /* Fig. 5 of CC2008 */ + D = "[N] -> { S_0[i, j] : i >= 0 and i <= -1 + N and j >= 2 and " + "j <= -1 + N }"; + W = "[N] -> { S_0[i, j] -> a[i, j] : i >= 0 and i <= -1 + N and " + "j >= 2 and j <= -1 + N }"; + R = "[N] -> { S_0[i, j] -> a[j, i] : i >= 0 and i <= -1 + N and " + "j >= 2 and j <= -1 + N; " + "S_0[i, j] -> a[i, -1 + j] : i >= 0 and i <= -1 + N and " + "j >= 2 and j <= -1 + N }"; + S = "[N] -> { S_0[i, j] -> [0, i, 0, j, 0] }"; + if (test_one_schedule(ctx, D, W, R, S, 2, 0) < 0) + return -1; + + D = "{ S1[i] : 0 <= i <= 10; S2[i] : 0 <= i <= 9 }"; + W = "{ S1[i] -> a[i] }"; + R = "{ S2[i] -> a[i+1] }"; + S = "{ S1[i] -> [0,i]; S2[i] -> [1,i] }"; + if (test_one_schedule(ctx, D, W, R, S, 1, 1) < 0) + return -1; + + D = "{ S1[i] : 0 <= i < 10; S2[i] : 0 <= i < 10 }"; + W = "{ S1[i] -> a[i] }"; + R = "{ S2[i] -> a[9-i] }"; + S = "{ S1[i] -> [0,i]; S2[i] -> [1,i] }"; + if (test_one_schedule(ctx, D, W, R, S, 1, 1) < 0) + return -1; + + D = "[N] -> { S1[i] : 0 <= i < N; S2[i] : 0 <= i < N }"; + W = "{ S1[i] -> a[i] }"; + R = "[N] -> { S2[i] -> a[N-1-i] }"; + S = "{ S1[i] -> [0,i]; S2[i] -> [1,i] }"; + if (test_one_schedule(ctx, D, W, R, S, 1, 1) < 0) + return -1; + + D = "{ S1[i] : 0 < i < 10; S2[i] : 0 <= i < 10 }"; + W = "{ S1[i] -> a[i]; S2[i] -> b[i] }"; + R = "{ S2[i] -> a[i]; S1[i] -> b[i-1] }"; + S = "{ S1[i] -> [i,0]; S2[i] -> [i,1] }"; + if (test_one_schedule(ctx, D, W, R, S, 0, 0) < 0) + return -1; + + D = "[N] -> { S1[i] : 1 <= i <= N; S2[i,j] : 1 <= i,j <= N }"; + W = "{ S1[i] -> a[0,i]; S2[i,j] -> a[i,j] }"; + R = "{ S2[i,j] -> a[i-1,j] }"; + S = "{ S1[i] -> [0,i,0]; S2[i,j] -> [1,i,j] }"; + if (test_one_schedule(ctx, D, W, R, S, 2, 1) < 0) + return -1; + + D = "[N] -> { S1[i] : 1 <= i <= N; S2[i,j] : 1 <= i,j <= N }"; + W = "{ S1[i] -> a[i,0]; S2[i,j] -> a[i,j] }"; + R = "{ S2[i,j] -> a[i,j-1] }"; + S = "{ S1[i] -> [0,i,0]; S2[i,j] -> [1,i,j] }"; + if (test_one_schedule(ctx, D, W, R, S, 2, 1) < 0) + return -1; + + D = "[N] -> { S_0[]; S_1[i] : i >= 0 and i <= -1 + N; S_2[] }"; + W = "[N] -> { S_0[] -> a[0]; S_2[] -> b[0]; " + "S_1[i] -> a[1 + i] : i >= 0 and i <= -1 + N }"; + R = "[N] -> { S_2[] -> a[N]; S_1[i] -> a[i] : i >= 0 and i <= -1 + N }"; + S = "[N] -> { S_1[i] -> [1, i, 0]; S_2[] -> [2, 0, 1]; " + "S_0[] -> [0, 0, 0] }"; + if (test_one_schedule(ctx, D, W, R, S, 1, 0) < 0) + return -1; + ctx->opt->schedule_parametric = 0; + if (test_one_schedule(ctx, D, W, R, S, 0, 0) < 0) + return -1; + ctx->opt->schedule_parametric = 1; + + D = "[N] -> { S1[i] : 1 <= i <= N; S2[i] : 1 <= i <= N; " + "S3[i,j] : 1 <= i,j <= N; S4[i] : 1 <= i <= N }"; + W = "{ S1[i] -> a[i,0]; S2[i] -> a[0,i]; S3[i,j] -> a[i,j] }"; + R = "[N] -> { S3[i,j] -> a[i-1,j]; S3[i,j] -> a[i,j-1]; " + "S4[i] -> a[i,N] }"; + S = "{ S1[i] -> [0,i,0]; S2[i] -> [1,i,0]; S3[i,j] -> [2,i,j]; " + "S4[i] -> [4,i,0] }"; + max_coincidence = isl_options_get_schedule_maximize_coincidence(ctx); + isl_options_set_schedule_maximize_coincidence(ctx, 0); + if (test_one_schedule(ctx, D, W, R, S, 2, 0) < 0) + return -1; + isl_options_set_schedule_maximize_coincidence(ctx, max_coincidence); + + D = "[N] -> { S_0[i, j] : i >= 1 and i <= N and j >= 1 and j <= N }"; + W = "[N] -> { S_0[i, j] -> s[0] : i >= 1 and i <= N and j >= 1 and " + "j <= N }"; + R = "[N] -> { S_0[i, j] -> s[0] : i >= 1 and i <= N and j >= 1 and " + "j <= N; " + "S_0[i, j] -> a[i, j] : i >= 1 and i <= N and j >= 1 and " + "j <= N }"; + S = "[N] -> { S_0[i, j] -> [0, i, 0, j, 0] }"; + if (test_one_schedule(ctx, D, W, R, S, 0, 0) < 0) + return -1; + + D = "[N] -> { S_0[t] : t >= 0 and t <= -1 + N; " + " S_2[t] : t >= 0 and t <= -1 + N; " + " S_1[t, i] : t >= 0 and t <= -1 + N and i >= 0 and " + "i <= -1 + N }"; + W = "[N] -> { S_0[t] -> a[t, 0] : t >= 0 and t <= -1 + N; " + " S_2[t] -> b[t] : t >= 0 and t <= -1 + N; " + " S_1[t, i] -> a[t, 1 + i] : t >= 0 and t <= -1 + N and " + "i >= 0 and i <= -1 + N }"; + R = "[N] -> { S_1[t, i] -> a[t, i] : t >= 0 and t <= -1 + N and " + "i >= 0 and i <= -1 + N; " + " S_2[t] -> a[t, N] : t >= 0 and t <= -1 + N }"; + S = "[N] -> { S_2[t] -> [0, t, 2]; S_1[t, i] -> [0, t, 1, i, 0]; " + " S_0[t] -> [0, t, 0] }"; + + if (test_one_schedule(ctx, D, W, R, S, 2, 1) < 0) + return -1; + ctx->opt->schedule_parametric = 0; + if (test_one_schedule(ctx, D, W, R, S, 0, 0) < 0) + return -1; + ctx->opt->schedule_parametric = 1; + + D = "[N] -> { S1[i,j] : 0 <= i,j < N; S2[i,j] : 0 <= i,j < N }"; + S = "{ S1[i,j] -> [0,i,j]; S2[i,j] -> [1,i,j] }"; + if (test_one_schedule(ctx, D, "{}", "{}", S, 2, 2) < 0) + return -1; + + D = "[M, N] -> { S_1[i] : i >= 0 and i <= -1 + M; " + "S_0[i, j] : i >= 0 and i <= -1 + M and j >= 0 and j <= -1 + N }"; + W = "[M, N] -> { S_0[i, j] -> a[j] : i >= 0 and i <= -1 + M and " + "j >= 0 and j <= -1 + N; " + "S_1[i] -> b[0] : i >= 0 and i <= -1 + M }"; + R = "[M, N] -> { S_0[i, j] -> a[0] : i >= 0 and i <= -1 + M and " + "j >= 0 and j <= -1 + N; " + "S_1[i] -> b[0] : i >= 0 and i <= -1 + M }"; + S = "[M, N] -> { S_1[i] -> [1, i, 0]; S_0[i, j] -> [0, i, 0, j, 0] }"; + if (test_one_schedule(ctx, D, W, R, S, 0, 0) < 0) + return -1; + + D = "{ S_0[i] : i >= 0 }"; + W = "{ S_0[i] -> a[i] : i >= 0 }"; + R = "{ S_0[i] -> a[0] : i >= 0 }"; + S = "{ S_0[i] -> [0, i, 0] }"; + if (test_one_schedule(ctx, D, W, R, S, 0, 0) < 0) + return -1; + + D = "{ S_0[i] : i >= 0; S_1[i] : i >= 0 }"; + W = "{ S_0[i] -> a[i] : i >= 0; S_1[i] -> b[i] : i >= 0 }"; + R = "{ S_0[i] -> b[0] : i >= 0; S_1[i] -> a[i] : i >= 0 }"; + S = "{ S_1[i] -> [0, i, 1]; S_0[i] -> [0, i, 0] }"; + if (test_one_schedule(ctx, D, W, R, S, 0, 0) < 0) + return -1; + + D = "[n] -> { S_0[j, k] : j <= -1 + n and j >= 0 and " + "k <= -1 + n and k >= 0 }"; + W = "[n] -> { S_0[j, k] -> B[j] : j <= -1 + n and j >= 0 and " "k <= -1 + n and k >= 0 }"; + R = "[n] -> { S_0[j, k] -> B[j] : j <= -1 + n and j >= 0 and " + "k <= -1 + n and k >= 0; " + "S_0[j, k] -> B[k] : j <= -1 + n and j >= 0 and " + "k <= -1 + n and k >= 0; " + "S_0[j, k] -> A[k] : j <= -1 + n and j >= 0 and " + "k <= -1 + n and k >= 0 }"; + S = "[n] -> { S_0[j, k] -> [2, j, k] }"; + ctx->opt->schedule_outer_coincidence = 1; + if (test_one_schedule(ctx, D, W, R, S, 0, 0) < 0) + return -1; + ctx->opt->schedule_outer_coincidence = 0; + + D = "{Stmt_for_body24[i0, i1, i2, i3]:" + "i0 >= 0 and i0 <= 1 and i1 >= 0 and i1 <= 6 and i2 >= 2 and " + "i2 <= 6 - i1 and i3 >= 0 and i3 <= -1 + i2;" + "Stmt_for_body24[i0, i1, 1, 0]:" + "i0 >= 0 and i0 <= 1 and i1 >= 0 and i1 <= 5;" + "Stmt_for_body7[i0, i1, i2]:" + "i0 >= 0 and i0 <= 1 and i1 >= 0 and i1 <= 7 and i2 >= 0 and " + "i2 <= 7 }"; + + V = "{Stmt_for_body24[0, i1, i2, i3] -> " + "Stmt_for_body24[1, i1, i2, i3]:" + "i3 >= 0 and i3 <= -1 + i2 and i1 >= 0 and i2 <= 6 - i1 and " + "i2 >= 1;" + "Stmt_for_body24[0, i1, i2, i3] -> " + "Stmt_for_body7[1, 1 + i1 + i3, 1 + i1 + i2]:" + "i3 <= -1 + i2 and i2 <= 6 - i1 and i2 >= 1 and i1 >= 0 and " + "i3 >= 0;" + "Stmt_for_body24[0, i1, i2, i3] ->" + "Stmt_for_body7[1, i1, 1 + i1 + i3]:" + "i3 >= 0 and i2 <= 6 - i1 and i1 >= 0 and i3 <= -1 + i2;" + "Stmt_for_body7[0, i1, i2] -> Stmt_for_body7[1, i1, i2]:" + "(i2 >= 1 + i1 and i2 <= 6 and i1 >= 0 and i1 <= 4) or " + "(i2 >= 3 and i2 <= 7 and i1 >= 1 and i2 >= 1 + i1) or " + "(i2 >= 0 and i2 <= i1 and i2 >= -7 + i1 and i1 <= 7);" + "Stmt_for_body7[0, i1, 1 + i1] -> Stmt_for_body7[1, i1, 1 + i1]:" + "i1 <= 6 and i1 >= 0;" + "Stmt_for_body7[0, 0, 7] -> Stmt_for_body7[1, 0, 7];" + "Stmt_for_body7[i0, i1, i2] -> " + "Stmt_for_body24[i0, o1, -1 + i2 - o1, -1 + i1 - o1]:" + "i0 >= 0 and i0 <= 1 and o1 >= 0 and i2 >= 1 + i1 and " + "o1 <= -2 + i2 and i2 <= 7 and o1 <= -1 + i1;" + "Stmt_for_body7[i0, i1, i2] -> " + "Stmt_for_body24[i0, i1, o2, -1 - i1 + i2]:" + "i0 >= 0 and i0 <= 1 and i1 >= 0 and o2 >= -i1 + i2 and " + "o2 >= 1 and o2 <= 6 - i1 and i2 >= 1 + i1 }"; + P = V; + + treat_coalescing = isl_options_get_schedule_treat_coalescing(ctx); + isl_options_set_schedule_treat_coalescing(ctx, 0); + if (test_has_schedule(ctx, D, V, P) < 0) + return -1; + isl_options_set_schedule_treat_coalescing(ctx, treat_coalescing); + + D = "{ S_0[i, j] : i >= 1 and i <= 10 and j >= 1 and j <= 8 }"; + V = "{ S_0[i, j] -> S_0[i, 1 + j] : i >= 1 and i <= 10 and " + "j >= 1 and j <= 7;" + "S_0[i, j] -> S_0[1 + i, j] : i >= 1 and i <= 9 and " + "j >= 1 and j <= 8 }"; + P = "{ }"; + S = "{ S_0[i, j] -> [i + j, i] }"; + ctx->opt->schedule_algorithm = ISL_SCHEDULE_ALGORITHM_FEAUTRIER; + if (test_special_schedule(ctx, D, V, P, S) < 0) + return -1; + ctx->opt->schedule_algorithm = ISL_SCHEDULE_ALGORITHM_ISL; + + /* Fig. 1 from Feautrier's "Some Efficient Solutions..." pt. 2, 1992 */ + D = "[N] -> { S_0[i, j] : i >= 0 and i <= -1 + N and " + "j >= 0 and j <= -1 + i }"; + V = "[N] -> { S_0[i, j] -> S_0[i, 1 + j] : j <= -2 + i and " + "i <= -1 + N and j >= 0;" + "S_0[i, -1 + i] -> S_0[1 + i, 0] : i >= 1 and " + "i <= -2 + N }"; + P = "{ }"; + S = "{ S_0[i, j] -> [i, j] }"; + ctx->opt->schedule_algorithm = ISL_SCHEDULE_ALGORITHM_FEAUTRIER; + if (test_special_schedule(ctx, D, V, P, S) < 0) + return -1; + ctx->opt->schedule_algorithm = ISL_SCHEDULE_ALGORITHM_ISL; + + /* Test both algorithms on a case with only proximity dependences. */ + D = "{ S[i,j] : 0 <= i <= 10 }"; + V = "{ }"; + P = "{ S[i,j] -> S[i+1,j] : 0 <= i,j <= 10 }"; + S = "{ S[i, j] -> [j, i] }"; + ctx->opt->schedule_algorithm = ISL_SCHEDULE_ALGORITHM_FEAUTRIER; + if (test_special_schedule(ctx, D, V, P, S) < 0) + return -1; + ctx->opt->schedule_algorithm = ISL_SCHEDULE_ALGORITHM_ISL; + if (test_special_schedule(ctx, D, V, P, S) < 0) + return -1; + + D = "{ A[a]; B[] }"; + V = "{}"; + P = "{ A[a] -> B[] }"; + if (test_has_schedule(ctx, D, V, P) < 0) + return -1; + + if (test_padded_schedule(ctx) < 0) + return -1; + + /* Check that check for progress is not confused by rational + * solution. + */ + D = "[N] -> { S0[i, j] : i >= 0 and i <= N and j >= 0 and j <= N }"; + V = "[N] -> { S0[i0, -1 + N] -> S0[2 + i0, 0] : i0 >= 0 and " + "i0 <= -2 + N; " + "S0[i0, i1] -> S0[i0, 1 + i1] : i0 >= 0 and " + "i0 <= N and i1 >= 0 and i1 <= -1 + N }"; + P = "{}"; + ctx->opt->schedule_algorithm = ISL_SCHEDULE_ALGORITHM_FEAUTRIER; + if (test_has_schedule(ctx, D, V, P) < 0) + return -1; + ctx->opt->schedule_algorithm = ISL_SCHEDULE_ALGORITHM_ISL; + + /* Check that we allow schedule rows that are only non-trivial + * on some full-dimensional domains. + */ + D = "{ S1[j] : 0 <= j <= 1; S0[]; S2[k] : 0 <= k <= 1 }"; + V = "{ S0[] -> S1[j] : 0 <= j <= 1; S2[0] -> S0[];" + "S1[j] -> S2[1] : 0 <= j <= 1 }"; + P = "{}"; + ctx->opt->schedule_algorithm = ISL_SCHEDULE_ALGORITHM_FEAUTRIER; + if (test_has_schedule(ctx, D, V, P) < 0) + return -1; + ctx->opt->schedule_algorithm = ISL_SCHEDULE_ALGORITHM_ISL; + + if (test_conditional_schedule_constraints(ctx) < 0) + return -1; + + if (test_strongly_satisfying_schedule(ctx) < 0) + return -1; + + if (test_conflicting_context_schedule(ctx) < 0) + return -1; + + if (test_coalescing_schedule(ctx) < 0) + return -1; + if (test_skewing_schedule(ctx) < 0) + return -1; + + return 0; +} + +/* Perform scheduling tests using the whole component scheduler. + */ +static int test_schedule_whole(isl_ctx *ctx) +{ + int whole; + int r; + + whole = isl_options_get_schedule_whole_component(ctx); + isl_options_set_schedule_whole_component(ctx, 1); + r = test_schedule(ctx); + isl_options_set_schedule_whole_component(ctx, whole); + + return r; +} + +/* Perform scheduling tests using the incremental scheduler. + */ +static int test_schedule_incremental(isl_ctx *ctx) +{ + int whole; + int r; + + whole = isl_options_get_schedule_whole_component(ctx); + isl_options_set_schedule_whole_component(ctx, 0); + r = test_schedule(ctx); + isl_options_set_schedule_whole_component(ctx, whole); + + return r; +} + +int test_plain_injective(isl_ctx *ctx, const char *str, int injective) +{ + isl_union_map *umap; + int test; + + umap = isl_union_map_read_from_str(ctx, str); + test = isl_union_map_plain_is_injective(umap); + isl_union_map_free(umap); + if (test < 0) + return -1; + if (test == injective) + return 0; + if (injective) + isl_die(ctx, isl_error_unknown, + "map not detected as injective", return -1); + else + isl_die(ctx, isl_error_unknown, + "map detected as injective", return -1); +} + +int test_injective(isl_ctx *ctx) +{ + const char *str; + + if (test_plain_injective(ctx, "{S[i,j] -> A[0]; T[i,j] -> B[1]}", 0)) + return -1; + if (test_plain_injective(ctx, "{S[] -> A[0]; T[] -> B[0]}", 1)) + return -1; + if (test_plain_injective(ctx, "{S[] -> A[0]; T[] -> A[1]}", 1)) + return -1; + if (test_plain_injective(ctx, "{S[] -> A[0]; T[] -> A[0]}", 0)) + return -1; + if (test_plain_injective(ctx, "{S[i] -> A[i,0]; T[i] -> A[i,1]}", 1)) + return -1; + if (test_plain_injective(ctx, "{S[i] -> A[i]; T[i] -> A[i]}", 0)) + return -1; + if (test_plain_injective(ctx, "{S[] -> A[0,0]; T[] -> A[0,1]}", 1)) + return -1; + if (test_plain_injective(ctx, "{S[] -> A[0,0]; T[] -> A[1,0]}", 1)) + return -1; + + str = "{S[] -> A[0,0]; T[] -> A[0,1]; U[] -> A[1,0]}"; + if (test_plain_injective(ctx, str, 1)) + return -1; + str = "{S[] -> A[0,0]; T[] -> A[0,1]; U[] -> A[0,0]}"; + if (test_plain_injective(ctx, str, 0)) + return -1; + + return 0; +} + +#undef BASE +#define BASE aff +#include "isl_test_plain_equal_templ.c" + +#undef BASE +#define BASE pw_multi_aff +#include "isl_test_plain_equal_templ.c" + +#undef BASE +#define BASE union_pw_aff +#include "isl_test_plain_equal_templ.c" + +/* Basic tests on isl_union_pw_aff. + * + * In particular, check that isl_union_pw_aff_aff_on_domain + * aligns the parameters of the input objects and + * that isl_union_pw_aff_param_on_domain_id properly + * introduces the parameter. + */ +static int test_upa(isl_ctx *ctx) +{ + const char *str; + isl_id *id; + isl_aff *aff; + isl_union_set *domain; + isl_union_pw_aff *upa; + isl_stat ok; + + aff = isl_aff_read_from_str(ctx, "[N] -> { [N] }"); + str = "[M] -> { A[i] : 0 <= i < M; B[] }"; + domain = isl_union_set_read_from_str(ctx, str); + upa = isl_union_pw_aff_aff_on_domain(domain, aff); + str = "[N, M] -> { A[i] -> [N] : 0 <= i < M; B[] -> [N] }"; + ok = union_pw_aff_check_plain_equal(upa, str); + isl_union_pw_aff_free(upa); + if (ok < 0) + return -1; + + id = isl_id_alloc(ctx, "N", NULL); + str = "[M] -> { A[i] : 0 <= i < M; B[] }"; + domain = isl_union_set_read_from_str(ctx, str); + upa = isl_union_pw_aff_param_on_domain_id(domain, id); + str = "[N, M] -> { A[i] -> [N] : 0 <= i < M; B[] -> [N] }"; + ok = union_pw_aff_check_plain_equal(upa, str); + isl_union_pw_aff_free(upa); + if (ok < 0) + return -1; + + return 0; +} + +struct { + __isl_give isl_aff *(*fn)(__isl_take isl_aff *aff1, + __isl_take isl_aff *aff2); +} aff_bin_op[] = { + ['+'] = { &isl_aff_add }, + ['-'] = { &isl_aff_sub }, + ['*'] = { &isl_aff_mul }, + ['/'] = { &isl_aff_div }, +}; + +struct { + const char *arg1; + unsigned char op; + const char *arg2; + const char *res; +} aff_bin_tests[] = { + { "{ [i] -> [i] }", '+', "{ [i] -> [i] }", + "{ [i] -> [2i] }" }, + { "{ [i] -> [i] }", '-', "{ [i] -> [i] }", + "{ [i] -> [0] }" }, + { "{ [i] -> [i] }", '*', "{ [i] -> [2] }", + "{ [i] -> [2i] }" }, + { "{ [i] -> [2] }", '*', "{ [i] -> [i] }", + "{ [i] -> [2i] }" }, + { "{ [i] -> [i] }", '/', "{ [i] -> [2] }", + "{ [i] -> [i/2] }" }, + { "{ [i] -> [2i] }", '/', "{ [i] -> [2] }", + "{ [i] -> [i] }" }, + { "{ [i] -> [i] }", '+', "{ [i] -> [NaN] }", + "{ [i] -> [NaN] }" }, + { "{ [i] -> [i] }", '-', "{ [i] -> [NaN] }", + "{ [i] -> [NaN] }" }, + { "{ [i] -> [i] }", '*', "{ [i] -> [NaN] }", + "{ [i] -> [NaN] }" }, + { "{ [i] -> [2] }", '*', "{ [i] -> [NaN] }", + "{ [i] -> [NaN] }" }, + { "{ [i] -> [i] }", '/', "{ [i] -> [NaN] }", + "{ [i] -> [NaN] }" }, + { "{ [i] -> [2] }", '/', "{ [i] -> [NaN] }", + "{ [i] -> [NaN] }" }, + { "{ [i] -> [NaN] }", '+', "{ [i] -> [i] }", + "{ [i] -> [NaN] }" }, + { "{ [i] -> [NaN] }", '-', "{ [i] -> [i] }", + "{ [i] -> [NaN] }" }, + { "{ [i] -> [NaN] }", '*', "{ [i] -> [2] }", + "{ [i] -> [NaN] }" }, + { "{ [i] -> [NaN] }", '*', "{ [i] -> [i] }", + "{ [i] -> [NaN] }" }, + { "{ [i] -> [NaN] }", '/', "{ [i] -> [2] }", + "{ [i] -> [NaN] }" }, + { "{ [i] -> [NaN] }", '/', "{ [i] -> [i] }", + "{ [i] -> [NaN] }" }, + { "{ [i] -> [i] }", '/', "{ [i] -> [0] }", + "{ [i] -> [NaN] }" }, +}; + +/* Perform some basic tests of binary operations on isl_aff objects. + */ +static int test_bin_aff(isl_ctx *ctx) +{ + int i; + isl_aff *aff1, *aff2, *res; + __isl_give isl_aff *(*fn)(__isl_take isl_aff *aff1, + __isl_take isl_aff *aff2); + int ok; + + for (i = 0; i < ARRAY_SIZE(aff_bin_tests); ++i) { + aff1 = isl_aff_read_from_str(ctx, aff_bin_tests[i].arg1); + aff2 = isl_aff_read_from_str(ctx, aff_bin_tests[i].arg2); + res = isl_aff_read_from_str(ctx, aff_bin_tests[i].res); + fn = aff_bin_op[aff_bin_tests[i].op].fn; + aff1 = fn(aff1, aff2); + if (isl_aff_is_nan(res)) + ok = isl_aff_is_nan(aff1); + else + ok = isl_aff_plain_is_equal(aff1, res); + isl_aff_free(aff1); + isl_aff_free(res); + if (ok < 0) + return -1; + if (!ok) + isl_die(ctx, isl_error_unknown, + "unexpected result", return -1); + } + + return 0; +} + +struct { + __isl_give isl_pw_aff *(*fn)(__isl_take isl_pw_aff *pa1, + __isl_take isl_pw_aff *pa2); +} pw_aff_bin_op[] = { + ['m'] = { &isl_pw_aff_min }, + ['M'] = { &isl_pw_aff_max }, +}; + +/* Inputs for binary isl_pw_aff operation tests. + * "arg1" and "arg2" are the two arguments, "op" identifies the operation + * defined by pw_aff_bin_op, and "res" is the expected result. + */ +struct { + const char *arg1; + unsigned char op; + const char *arg2; + const char *res; +} pw_aff_bin_tests[] = { + { "{ [i] -> [i] }", 'm', "{ [i] -> [i] }", + "{ [i] -> [i] }" }, + { "{ [i] -> [i] }", 'M', "{ [i] -> [i] }", + "{ [i] -> [i] }" }, + { "{ [i] -> [i] }", 'm', "{ [i] -> [0] }", + "{ [i] -> [i] : i <= 0; [i] -> [0] : i > 0 }" }, + { "{ [i] -> [i] }", 'M', "{ [i] -> [0] }", + "{ [i] -> [i] : i >= 0; [i] -> [0] : i < 0 }" }, + { "{ [i] -> [i] }", 'm', "{ [i] -> [NaN] }", + "{ [i] -> [NaN] }" }, + { "{ [i] -> [NaN] }", 'm', "{ [i] -> [i] }", + "{ [i] -> [NaN] }" }, +}; + +/* Perform some basic tests of binary operations on isl_pw_aff objects. + */ +static int test_bin_pw_aff(isl_ctx *ctx) +{ + int i; + isl_bool ok; + isl_pw_aff *pa1, *pa2, *res; + + for (i = 0; i < ARRAY_SIZE(pw_aff_bin_tests); ++i) { + pa1 = isl_pw_aff_read_from_str(ctx, pw_aff_bin_tests[i].arg1); + pa2 = isl_pw_aff_read_from_str(ctx, pw_aff_bin_tests[i].arg2); + res = isl_pw_aff_read_from_str(ctx, pw_aff_bin_tests[i].res); + pa1 = pw_aff_bin_op[pw_aff_bin_tests[i].op].fn(pa1, pa2); + if (isl_pw_aff_involves_nan(res)) + ok = isl_pw_aff_involves_nan(pa1); + else + ok = isl_pw_aff_plain_is_equal(pa1, res); + isl_pw_aff_free(pa1); + isl_pw_aff_free(res); + if (ok < 0) + return -1; + if (!ok) + isl_die(ctx, isl_error_unknown, + "unexpected result", return -1); + } + + return 0; +} + +/* Inputs for basic tests of test operations on + * isl_union_pw_multi_aff objects. + * "fn" is the function that is being tested. + * "arg" is a string description of the input. + * "res" is the expected result. + */ +static struct { + isl_bool (*fn)(__isl_keep isl_union_pw_multi_aff *upma1); + const char *arg; + isl_bool res; +} upma_test_tests[] = { + { &isl_union_pw_multi_aff_involves_nan, "{ A[] -> [0]; B[0] -> [1] }", + isl_bool_false }, + { &isl_union_pw_multi_aff_involves_nan, "{ A[] -> [NaN]; B[0] -> [1] }", + isl_bool_true }, + { &isl_union_pw_multi_aff_involves_nan, "{ A[] -> [0]; B[0] -> [NaN] }", + isl_bool_true }, + { &isl_union_pw_multi_aff_involves_nan, + "{ A[] -> [0]; B[0] -> [1, NaN, 5] }", + isl_bool_true }, + { &isl_union_pw_multi_aff_involves_locals, + "{ A[] -> [0]; B[0] -> [1] }", + isl_bool_false }, + { &isl_union_pw_multi_aff_involves_locals, + "{ A[] -> [0]; B[x] -> [1] : x mod 2 = 0 }", + isl_bool_true }, + { &isl_union_pw_multi_aff_involves_locals, + "{ A[] -> [0]; B[x] -> [x // 2] }", + isl_bool_true }, + { &isl_union_pw_multi_aff_involves_locals, + "{ A[i] -> [i // 2]; B[0] -> [1] }", + isl_bool_true }, +}; + +/* Perform some basic tests of test operations on + * isl_union_pw_multi_aff objects. + */ +static isl_stat test_upma_test(isl_ctx *ctx) +{ + int i; + isl_union_pw_multi_aff *upma; + isl_bool res; + + for (i = 0; i < ARRAY_SIZE(upma_test_tests); ++i) { + const char *str; + + str = upma_test_tests[i].arg; + upma = isl_union_pw_multi_aff_read_from_str(ctx, str); + res = upma_test_tests[i].fn(upma); + isl_union_pw_multi_aff_free(upma); + if (res < 0) + return isl_stat_error; + if (res != upma_test_tests[i].res) + isl_die(ctx, isl_error_unknown, + "unexpected result", return isl_stat_error); + } + + return isl_stat_ok; +} + +struct { + __isl_give isl_union_pw_multi_aff *(*fn)( + __isl_take isl_union_pw_multi_aff *upma1, + __isl_take isl_union_pw_multi_aff *upma2); + const char *arg1; + const char *arg2; + const char *res; +} upma_bin_tests[] = { + { &isl_union_pw_multi_aff_add, "{ A[] -> [0]; B[0] -> [1] }", + "{ B[x] -> [2] : x >= 0 }", "{ B[0] -> [3] }" }, + { &isl_union_pw_multi_aff_union_add, "{ A[] -> [0]; B[0] -> [1] }", + "{ B[x] -> [2] : x >= 0 }", + "{ A[] -> [0]; B[0] -> [3]; B[x] -> [2] : x >= 1 }" }, + { &isl_union_pw_multi_aff_pullback_union_pw_multi_aff, + "{ A[] -> B[0]; C[x] -> B[1] : x < 10; C[y] -> B[2] : y >= 10 }", + "{ D[i] -> A[] : i < 0; D[i] -> C[i + 5] : i >= 0 }", + "{ D[i] -> B[0] : i < 0; D[i] -> B[1] : 0 <= i < 5; " + "D[i] -> B[2] : i >= 5 }" }, + { &isl_union_pw_multi_aff_union_add, "{ B[x] -> A[1] : x <= 0 }", + "{ B[x] -> C[2] : x > 0 }", + "{ B[x] -> A[1] : x <= 0; B[x] -> C[2] : x > 0 }" }, + { &isl_union_pw_multi_aff_union_add, "{ B[x] -> A[1] : x <= 0 }", + "{ B[x] -> A[2] : x >= 0 }", + "{ B[x] -> A[1] : x < 0; B[x] -> A[2] : x > 0; B[0] -> A[3] }" }, + { + &isl_union_pw_multi_aff_preimage_domain_wrapped_domain_union_pw_multi_aff, + "{ B[x] -> C[x + 2] }", + "{ D[y] -> B[2y] }", + "{ }" }, + { + &isl_union_pw_multi_aff_preimage_domain_wrapped_domain_union_pw_multi_aff, + "{ [A[x] -> B[x + 1]] -> C[x + 2] }", + "{ D[y] -> B[2y] }", + "{ }" }, + { + &isl_union_pw_multi_aff_preimage_domain_wrapped_domain_union_pw_multi_aff, + "{ [A[x] -> B[x + 1]] -> C[x + 2]; B[x] -> C[x + 2] }", + "{ D[y] -> A[2y] }", + "{ [D[y] -> B[2y + 1]] -> C[2y + 2] }" }, + { + &isl_union_pw_multi_aff_preimage_domain_wrapped_domain_union_pw_multi_aff, + "{ T[A[x] -> B[x + 1]] -> C[x + 2]; B[x] -> C[x + 2] }", + "{ D[y] -> A[2y] }", + "{ T[D[y] -> B[2y + 1]] -> C[2y + 2] }" }, +}; + +/* Perform some basic tests of binary operations on + * isl_union_pw_multi_aff objects. + */ +static int test_bin_upma(isl_ctx *ctx) +{ + int i; + isl_union_pw_multi_aff *upma1, *upma2, *res; + int ok; + + for (i = 0; i < ARRAY_SIZE(upma_bin_tests); ++i) { + upma1 = isl_union_pw_multi_aff_read_from_str(ctx, + upma_bin_tests[i].arg1); + upma2 = isl_union_pw_multi_aff_read_from_str(ctx, + upma_bin_tests[i].arg2); + res = isl_union_pw_multi_aff_read_from_str(ctx, + upma_bin_tests[i].res); + upma1 = upma_bin_tests[i].fn(upma1, upma2); + ok = isl_union_pw_multi_aff_plain_is_equal(upma1, res); + isl_union_pw_multi_aff_free(upma1); + isl_union_pw_multi_aff_free(res); + if (ok < 0) + return -1; + if (!ok) + isl_die(ctx, isl_error_unknown, + "unexpected result", return -1); + } + + return 0; +} + +struct { + __isl_give isl_union_pw_multi_aff *(*fn)( + __isl_take isl_union_pw_multi_aff *upma1, + __isl_take isl_union_pw_multi_aff *upma2); + const char *arg1; + const char *arg2; +} upma_bin_fail_tests[] = { + { &isl_union_pw_multi_aff_union_add, "{ B[x] -> A[1] : x <= 0 }", + "{ B[x] -> C[2] : x >= 0 }" }, +}; + +/* Perform some basic tests of binary operations on + * isl_union_pw_multi_aff objects that are expected to fail. + */ +static int test_bin_upma_fail(isl_ctx *ctx) +{ + int i, n; + isl_union_pw_multi_aff *upma1, *upma2; + int on_error; + + on_error = isl_options_get_on_error(ctx); + isl_options_set_on_error(ctx, ISL_ON_ERROR_CONTINUE); + n = ARRAY_SIZE(upma_bin_fail_tests); + for (i = 0; i < n; ++i) { + upma1 = isl_union_pw_multi_aff_read_from_str(ctx, + upma_bin_fail_tests[i].arg1); + upma2 = isl_union_pw_multi_aff_read_from_str(ctx, + upma_bin_fail_tests[i].arg2); + upma1 = upma_bin_fail_tests[i].fn(upma1, upma2); + isl_union_pw_multi_aff_free(upma1); + if (upma1) + break; + } + isl_options_set_on_error(ctx, on_error); + if (i < n) + isl_die(ctx, isl_error_unknown, + "operation not expected to succeed", return -1); + + return 0; +} + +/* Inputs for basic tests of binary operations on + * pairs of isl_union_pw_multi_aff and isl_union_set objects. + * "fn" is the function that is being tested. + * "arg1" and "arg2" are string descriptions of the inputs. + * "res" is a string description of the expected result. + */ +struct { + __isl_give isl_union_pw_multi_aff *(*fn)( + __isl_take isl_union_pw_multi_aff *upma, + __isl_take isl_union_set *uset); + const char *arg1; + const char *arg2; + const char *res; +} upma_uset_tests[] = { + { &isl_union_pw_multi_aff_intersect_domain_wrapped_range, + "{ A[i] -> B[i] }", "{ B[0] }", + "{ }" }, + { &isl_union_pw_multi_aff_intersect_domain_wrapped_domain, + "{ [A[i] -> B[i]] -> C[i + 1] }", "{ A[1]; B[0] }", + "{ [A[1] -> B[1]] -> C[2] }" }, + { &isl_union_pw_multi_aff_intersect_domain_wrapped_range, + "{ [A[i] -> B[i]] -> C[i + 1] }", "{ A[1]; B[0] }", + "{ [A[0] -> B[0]] -> C[1] }" }, + { &isl_union_pw_multi_aff_intersect_domain_wrapped_range, + "{ [A[i] -> B[i]] -> C[i + 1] }", "[N] -> { B[N] }", + "[N] -> { [A[N] -> B[N]] -> C[N + 1] }" }, + { &isl_union_pw_multi_aff_intersect_domain_wrapped_range, + "[M] -> { [A[M] -> B[M]] -> C[M + 1] }", "[N] -> { B[N] }", + "[N, M] -> { [A[N] -> B[N]] -> C[N + 1] : N = M }" }, + { &isl_union_pw_multi_aff_intersect_domain_wrapped_range, + "{ [A[] -> B[]] -> C[]; N[A[] -> B[]] -> D[]; [B[] -> A[]] -> E[] }", + "{ B[] }", + "{ [A[] -> B[]] -> C[]; N[A[] -> B[]] -> D[] }" }, +}; + +/* Perform some basic tests of binary operations on + * pairs of isl_union_pw_multi_aff and isl_union_set objects. + */ +static isl_stat test_upma_uset(isl_ctx *ctx) +{ + int i; + isl_bool ok; + isl_union_pw_multi_aff *upma, *res; + isl_union_set *uset; + + for (i = 0; i < ARRAY_SIZE(upma_uset_tests); ++i) { + upma = isl_union_pw_multi_aff_read_from_str(ctx, + upma_uset_tests[i].arg1); + uset = isl_union_set_read_from_str(ctx, + upma_uset_tests[i].arg2); + res = isl_union_pw_multi_aff_read_from_str(ctx, + upma_uset_tests[i].res); + upma = upma_uset_tests[i].fn(upma, uset); + ok = isl_union_pw_multi_aff_plain_is_equal(upma, res); + isl_union_pw_multi_aff_free(upma); + isl_union_pw_multi_aff_free(res); + if (ok < 0) + return isl_stat_error; + if (!ok) + isl_die(ctx, isl_error_unknown, + "unexpected result", return isl_stat_error); + } + + return isl_stat_ok; +} + +/* Inputs for basic tests of unary operations on isl_multi_pw_aff objects. + * "fn" is the function that is tested. + * "arg" is a string description of the input. + * "res" is a string description of the expected result. + */ +struct { + __isl_give isl_multi_pw_aff *(*fn)(__isl_take isl_multi_pw_aff *mpa); + const char *arg; + const char *res; +} mpa_un_tests[] = { + { &isl_multi_pw_aff_range_factor_domain, + "{ A[x] -> [B[(1 : x >= 5)] -> C[(2 : x <= 10)]] }", + "{ A[x] -> B[(1 : x >= 5)] }" }, + { &isl_multi_pw_aff_range_factor_range, + "{ A[x] -> [B[(1 : x >= 5)] -> C[(2 : x <= 10)]] }", + "{ A[y] -> C[(2 : y <= 10)] }" }, + { &isl_multi_pw_aff_range_factor_domain, + "{ A[x] -> [B[(1 : x >= 5)] -> C[]] }", + "{ A[x] -> B[(1 : x >= 5)] }" }, + { &isl_multi_pw_aff_range_factor_range, + "{ A[x] -> [B[(1 : x >= 5)] -> C[]] }", + "{ A[y] -> C[] }" }, + { &isl_multi_pw_aff_range_factor_domain, + "{ A[x] -> [B[] -> C[(2 : x <= 10)]] }", + "{ A[x] -> B[] }" }, + { &isl_multi_pw_aff_range_factor_range, + "{ A[x] -> [B[] -> C[(2 : x <= 10)]] }", + "{ A[y] -> C[(2 : y <= 10)] }" }, + { &isl_multi_pw_aff_range_factor_domain, + "{ A[x] -> [B[] -> C[]] }", + "{ A[x] -> B[] }" }, + { &isl_multi_pw_aff_range_factor_range, + "{ A[x] -> [B[] -> C[]] }", + "{ A[y] -> C[] }" }, + { &isl_multi_pw_aff_factor_range, + "{ [B[] -> C[]] }", + "{ C[] }" }, + { &isl_multi_pw_aff_range_factor_domain, + "{ A[x] -> [B[] -> C[]] : x >= 0 }", + "{ A[x] -> B[] : x >= 0 }" }, + { &isl_multi_pw_aff_range_factor_range, + "{ A[x] -> [B[] -> C[]] : x >= 0 }", + "{ A[y] -> C[] : y >= 0 }" }, + { &isl_multi_pw_aff_factor_range, + "[N] -> { [B[] -> C[]] : N >= 0 }", + "[N] -> { C[] : N >= 0 }" }, +}; + +/* Perform some basic tests of unary operations on isl_multi_pw_aff objects. + */ +static int test_un_mpa(isl_ctx *ctx) +{ + int i; + isl_bool ok; + isl_multi_pw_aff *mpa, *res; + + for (i = 0; i < ARRAY_SIZE(mpa_un_tests); ++i) { + mpa = isl_multi_pw_aff_read_from_str(ctx, mpa_un_tests[i].arg); + res = isl_multi_pw_aff_read_from_str(ctx, mpa_un_tests[i].res); + mpa = mpa_un_tests[i].fn(mpa); + ok = isl_multi_pw_aff_plain_is_equal(mpa, res); + isl_multi_pw_aff_free(mpa); + isl_multi_pw_aff_free(res); + if (ok < 0) + return -1; + if (!ok) + isl_die(ctx, isl_error_unknown, + "unexpected result", return -1); + } + + return 0; +} + +/* Inputs for basic tests of binary operations on isl_multi_pw_aff objects. + * "fn" is the function that is tested. + * "arg1" and "arg2" are string descriptions of the inputs. + * "res" is a string description of the expected result. + */ +struct { + __isl_give isl_multi_pw_aff *(*fn)( + __isl_take isl_multi_pw_aff *mpa1, + __isl_take isl_multi_pw_aff *mpa2); + const char *arg1; + const char *arg2; + const char *res; +} mpa_bin_tests[] = { + { &isl_multi_pw_aff_add, "{ A[] -> [1] }", "{ A[] -> [2] }", + "{ A[] -> [3] }" }, + { &isl_multi_pw_aff_add, "{ A[x] -> [(1 : x >= 5)] }", + "{ A[x] -> [(x : x <= 10)] }", + "{ A[x] -> [(1 + x : 5 <= x <= 10)] }" }, + { &isl_multi_pw_aff_add, "{ A[x] -> [] : x >= 5 }", + "{ A[x] -> [] : x <= 10 }", + "{ A[x] -> [] : 5 <= x <= 10 }" }, + { &isl_multi_pw_aff_add, "{ A[x] -> [] : x >= 5 }", + "[N] -> { A[x] -> [] : x <= N }", + "[N] -> { A[x] -> [] : 5 <= x <= N }" }, + { &isl_multi_pw_aff_add, + "[N] -> { A[x] -> [] : x <= N }", + "{ A[x] -> [] : x >= 5 }", + "[N] -> { A[x] -> [] : 5 <= x <= N }" }, + { &isl_multi_pw_aff_range_product, "{ A[x] -> B[(1 : x >= 5)] }", + "{ A[y] -> C[(2 : y <= 10)] }", + "{ A[x] -> [B[(1 : x >= 5)] -> C[(2 : x <= 10)]] }" }, + { &isl_multi_pw_aff_range_product, "{ A[x] -> B[1] : x >= 5 }", + "{ A[y] -> C[2] : y <= 10 }", + "{ A[x] -> [B[(1 : x >= 5)] -> C[(2 : x <= 10)]] }" }, + { &isl_multi_pw_aff_range_product, "{ A[x] -> B[1] : x >= 5 }", + "[N] -> { A[y] -> C[2] : y <= N }", + "[N] -> { A[x] -> [B[(1 : x >= 5)] -> C[(2 : x <= N)]] }" }, + { &isl_multi_pw_aff_range_product, "[N] -> { A[x] -> B[1] : x >= N }", + "{ A[y] -> C[2] : y <= 10 }", + "[N] -> { A[x] -> [B[(1 : x >= N)] -> C[(2 : x <= 10)]] }" }, + { &isl_multi_pw_aff_range_product, "{ A[] -> B[1] }", "{ A[] -> C[2] }", + "{ A[] -> [B[1] -> C[2]] }" }, + { &isl_multi_pw_aff_range_product, "{ A[] -> B[] }", "{ A[] -> C[] }", + "{ A[] -> [B[] -> C[]] }" }, + { &isl_multi_pw_aff_range_product, "{ A[x] -> B[(1 : x >= 5)] }", + "{ A[y] -> C[] : y <= 10 }", + "{ A[x] -> [B[(1 : x >= 5)] -> C[]] : x <= 10 }" }, + { &isl_multi_pw_aff_range_product, "{ A[y] -> C[] : y <= 10 }", + "{ A[x] -> B[(1 : x >= 5)] }", + "{ A[x] -> [C[] -> B[(1 : x >= 5)]] : x <= 10 }" }, + { &isl_multi_pw_aff_product, "{ A[x] -> B[(1 : x >= 5)] }", + "{ A[y] -> C[(2 : y <= 10)] }", + "{ [A[x] -> A[y]] -> [B[(1 : x >= 5)] -> C[(2 : y <= 10)]] }" }, + { &isl_multi_pw_aff_product, "{ A[x] -> B[(1 : x >= 5)] }", + "{ A[y] -> C[] : y <= 10 }", + "{ [A[x] -> A[y]] -> [B[(1 : x >= 5)] -> C[]] : y <= 10 }" }, + { &isl_multi_pw_aff_product, "{ A[y] -> C[] : y <= 10 }", + "{ A[x] -> B[(1 : x >= 5)] }", + "{ [A[y] -> A[x]] -> [C[] -> B[(1 : x >= 5)]] : y <= 10 }" }, + { &isl_multi_pw_aff_product, "{ A[x] -> B[(1 : x >= 5)] }", + "[N] -> { A[y] -> C[] : y <= N }", + "[N] -> { [A[x] -> A[y]] -> [B[(1 : x >= 5)] -> C[]] : y <= N }" }, + { &isl_multi_pw_aff_product, "[N] -> { A[y] -> C[] : y <= N }", + "{ A[x] -> B[(1 : x >= 5)] }", + "[N] -> { [A[y] -> A[x]] -> [C[] -> B[(1 : x >= 5)]] : y <= N }" }, + { &isl_multi_pw_aff_product, "{ A[x] -> B[] : x >= 5 }", + "{ A[y] -> C[] : y <= 10 }", + "{ [A[x] -> A[y]] -> [B[] -> C[]] : x >= 5 and y <= 10 }" }, + { &isl_multi_pw_aff_product, "{ A[] -> B[1] }", "{ A[] -> C[2] }", + "{ [A[] -> A[]] -> [B[1] -> C[2]] }" }, + { &isl_multi_pw_aff_product, "{ A[] -> B[] }", "{ A[] -> C[] }", + "{ [A[] -> A[]] -> [B[] -> C[]] }" }, + { &isl_multi_pw_aff_pullback_multi_pw_aff, + "{ B[i,j] -> C[i + 2j] }", "{ A[a,b] -> B[b,a] }", + "{ A[a,b] -> C[b + 2a] }" }, + { &isl_multi_pw_aff_pullback_multi_pw_aff, + "{ B[i,j] -> C[i + 2j] }", + "{ A[a,b] -> B[(b : b > a),(a : b > a)] }", + "{ A[a,b] -> C[(b + 2a : b > a)] }" }, + { &isl_multi_pw_aff_pullback_multi_pw_aff, + "{ B[i,j] -> C[(i + 2j : j > 4)] }", + "{ A[a,b] -> B[(b : b > a),(a : b > a)] }", + "{ A[a,b] -> C[(b + 2a : b > a > 4)] }" }, + { &isl_multi_pw_aff_pullback_multi_pw_aff, + "{ B[i,j] -> C[] }", + "{ A[a,b] -> B[(b : b > a),(a : b > a)] }", + "{ A[a,b] -> C[] }" }, + { &isl_multi_pw_aff_pullback_multi_pw_aff, + "{ B[i,j] -> C[] : i > j }", + "{ A[a,b] -> B[b,a] }", + "{ A[a,b] -> C[] : b > a }" }, + { &isl_multi_pw_aff_pullback_multi_pw_aff, + "{ B[i,j] -> C[] : j > 5 }", + "{ A[a,b] -> B[(b : b > a),(a : b > a)] }", + "{ A[a,b] -> C[] : b > a > 5 }" }, + { &isl_multi_pw_aff_pullback_multi_pw_aff, + "[N] -> { B[i,j] -> C[] : j > N }", + "{ A[a,b] -> B[(b : b > a),(a : b > a)] }", + "[N] -> { A[a,b] -> C[] : b > a > N }" }, + { &isl_multi_pw_aff_pullback_multi_pw_aff, + "[M,N] -> { B[] -> C[] : N > 5 }", + "[M,N] -> { A[] -> B[] : M > N }", + "[M,N] -> { A[] -> C[] : M > N > 5 }" }, +}; + +/* Perform some basic tests of binary operations on isl_multi_pw_aff objects. + */ +static int test_bin_mpa(isl_ctx *ctx) +{ + int i; + isl_bool ok; + isl_multi_pw_aff *mpa1, *mpa2, *res; + + for (i = 0; i < ARRAY_SIZE(mpa_bin_tests); ++i) { + mpa1 = isl_multi_pw_aff_read_from_str(ctx, + mpa_bin_tests[i].arg1); + mpa2 = isl_multi_pw_aff_read_from_str(ctx, + mpa_bin_tests[i].arg2); + res = isl_multi_pw_aff_read_from_str(ctx, + mpa_bin_tests[i].res); + mpa1 = mpa_bin_tests[i].fn(mpa1, mpa2); + ok = isl_multi_pw_aff_plain_is_equal(mpa1, res); + isl_multi_pw_aff_free(mpa1); + isl_multi_pw_aff_free(res); + if (ok < 0) + return -1; + if (!ok) + isl_die(ctx, isl_error_unknown, + "unexpected result", return -1); + } + + return 0; +} + +/* Inputs for basic tests of unary operations on + * isl_multi_union_pw_aff objects. + * "fn" is the function that is tested. + * "arg" is a string description of the input. + * "res" is a string description of the expected result. + */ +struct { + __isl_give isl_multi_union_pw_aff *(*fn)( + __isl_take isl_multi_union_pw_aff *mupa); + const char *arg; + const char *res; +} mupa_un_tests[] = { + { &isl_multi_union_pw_aff_factor_range, + "[B[{ A[] -> [1] }] -> C[{ A[] -> [2] }]]", + "C[{ A[] -> [2] }]" }, + { &isl_multi_union_pw_aff_factor_range, + "[B[] -> C[{ A[] -> [2] }]]", + "C[{ A[] -> [2] }]" }, + { &isl_multi_union_pw_aff_factor_range, + "[B[{ A[] -> [1] }] -> C[]]", + "C[]" }, + { &isl_multi_union_pw_aff_factor_range, + "[B[] -> C[]]", + "C[]" }, + { &isl_multi_union_pw_aff_factor_range, + "([B[] -> C[]] : { A[x] : x >= 0 })", + "(C[] : { A[x] : x >= 0 })" }, + { &isl_multi_union_pw_aff_factor_range, + "[N] -> ([B[] -> C[]] : { A[x] : x <= N })", + "[N] -> (C[] : { A[x] : x <= N })" }, + { &isl_multi_union_pw_aff_factor_range, + "[N] -> ([B[] -> C[]] : { : N >= 0 })", + "[N] -> (C[] : { : N >= 0 })" }, +}; + +/* Perform some basic tests of unary operations on + * isl_multi_union_pw_aff objects. + */ +static int test_un_mupa(isl_ctx *ctx) +{ + int i; + isl_bool ok; + isl_multi_union_pw_aff *mupa, *res; + + for (i = 0; i < ARRAY_SIZE(mupa_un_tests); ++i) { + mupa = isl_multi_union_pw_aff_read_from_str(ctx, + mupa_un_tests[i].arg); + res = isl_multi_union_pw_aff_read_from_str(ctx, + mupa_un_tests[i].res); + mupa = mupa_un_tests[i].fn(mupa); + ok = isl_multi_union_pw_aff_plain_is_equal(mupa, res); + isl_multi_union_pw_aff_free(mupa); + isl_multi_union_pw_aff_free(res); + if (ok < 0) + return -1; + if (!ok) + isl_die(ctx, isl_error_unknown, + "unexpected result", return -1); + } + + return 0; +} + +/* Inputs for basic tests of binary operations on + * isl_multi_union_pw_aff objects. + * "fn" is the function that is tested. + * "arg1" and "arg2" are string descriptions of the inputs. + * "res" is a string description of the expected result. + */ +struct { + __isl_give isl_multi_union_pw_aff *(*fn)( + __isl_take isl_multi_union_pw_aff *mupa1, + __isl_take isl_multi_union_pw_aff *mupa2); + const char *arg1; + const char *arg2; + const char *res; +} mupa_bin_tests[] = { + { &isl_multi_union_pw_aff_add, "[{ A[] -> [1] }]", "[{ A[] -> [2] }]", + "[{ A[] -> [3] }]" }, + { &isl_multi_union_pw_aff_sub, "[{ A[] -> [1] }]", "[{ A[] -> [2] }]", + "[{ A[] -> [-1] }]" }, + { &isl_multi_union_pw_aff_add, + "[{ A[] -> [1]; B[] -> [4] }]", + "[{ A[] -> [2]; C[] -> [5] }]", + "[{ A[] -> [3] }]" }, + { &isl_multi_union_pw_aff_union_add, + "[{ A[] -> [1]; B[] -> [4] }]", + "[{ A[] -> [2]; C[] -> [5] }]", + "[{ A[] -> [3]; B[] -> [4]; C[] -> [5] }]" }, + { &isl_multi_union_pw_aff_add, "[{ A[x] -> [(1)] : x >= 5 }]", + "[{ A[x] -> [(x)] : x <= 10 }]", + "[{ A[x] -> [(1 + x)] : 5 <= x <= 10 }]" }, + { &isl_multi_union_pw_aff_add, "([] : { A[x] : x >= 5 })", + "([] : { A[x] : x <= 10 })", + "([] : { A[x] : 5 <= x <= 10 })" }, + { &isl_multi_union_pw_aff_add, "([] : { A[x] : x >= 5 })", + "[N] -> ([] : { A[x] : x <= N })", + "[N] -> ([] : { A[x] : 5 <= x <= N })" }, + { &isl_multi_union_pw_aff_add, "[N] -> ([] : { A[x] : x >= N })", + "([] : { A[x] : x <= 10 })", + "[N] -> ([] : { A[x] : N <= x <= 10 })" }, + { &isl_multi_union_pw_aff_union_add, "[{ A[x] -> [(1)] : x >= 5 }]", + "[{ A[x] -> [(x)] : x <= 10 }]", + "[{ A[x] -> [(1 + x)] : 5 <= x <= 10; " + "A[x] -> [(1)] : x > 10; A[x] -> [(x)] : x < 5 }]" }, + { &isl_multi_union_pw_aff_union_add, "([] : { A[x] : x >= 5 })", + "([] : { A[x] : x <= 10 })", + "([] : { A[x] })" }, + { &isl_multi_union_pw_aff_union_add, "([] : { A[x] : x >= 0 })", + "[N] -> ([] : { A[x] : x >= N })", + "[N] -> ([] : { A[x] : x >= 0 or x >= N })" }, + { &isl_multi_union_pw_aff_union_add, + "[N] -> ([] : { A[] : N >= 0})", + "[N] -> ([] : { A[] : N <= 0})", + "[N] -> ([] : { A[] })" }, + { &isl_multi_union_pw_aff_union_add, + "[N] -> ([] : { A[] })", + "[N] -> ([] : { : })", + "[N] -> ([] : { : })" }, + { &isl_multi_union_pw_aff_union_add, + "[N] -> ([] : { : })", + "[N] -> ([] : { A[] })", + "[N] -> ([] : { : })" }, + { &isl_multi_union_pw_aff_union_add, + "[N] -> ([] : { : N >= 0})", + "[N] -> ([] : { : N <= 0})", + "[N] -> ([] : { : })" }, + { &isl_multi_union_pw_aff_range_product, + "B[{ A[] -> [1] }]", + "C[{ A[] -> [2] }]", + "[B[{ A[] -> [1] }] -> C[{ A[] -> [2] }]]" }, + { &isl_multi_union_pw_aff_range_product, + "(B[] : { A[x] : x >= 5 })", + "(C[] : { A[x] : x <= 10 })", + "([B[] -> C[]] : { A[x] : 5 <= x <= 10 })" }, + { &isl_multi_union_pw_aff_range_product, + "B[{ A[x] -> [x + 1] : x >= 5 }]", + "(C[] : { A[x] : x <= 10 })", + "[B[{ A[x] -> [x + 1] : 5 <= x <= 10 }] -> C[]]" }, + { &isl_multi_union_pw_aff_range_product, + "(C[] : { A[x] : x <= 10 })", + "B[{ A[x] -> [x + 1] : x >= 5 }]", + "[C[] -> B[{ A[x] -> [x + 1] : 5 <= x <= 10 }]]" }, + { &isl_multi_union_pw_aff_range_product, + "B[{ A[x] -> [x + 1] : x >= 5 }]", + "[N] -> (C[] : { A[x] : x <= N })", + "[N] -> [B[{ A[x] -> [x + 1] : 5 <= x <= N }] -> C[]]" }, + { &isl_multi_union_pw_aff_range_product, + "[N] -> (C[] : { A[x] : x <= N })", + "B[{ A[x] -> [x + 1] : x >= 5 }]", + "[N] -> [C[] -> B[{ A[x] -> [x + 1] : 5 <= x <= N }]]" }, + { &isl_multi_union_pw_aff_range_product, + "B[{ A[] -> [1]; D[] -> [3] }]", + "C[{ A[] -> [2] }]", + "[B[{ A[] -> [1]; D[] -> [3] }] -> C[{ A[] -> [2] }]]" }, + { &isl_multi_union_pw_aff_range_product, + "B[] }]", + "(C[] : { A[x] })", + "([B[] -> C[]] : { A[x] })" }, + { &isl_multi_union_pw_aff_range_product, + "(B[] : { A[x] })", + "C[] }]", + "([B[] -> C[]] : { A[x] })" }, +}; + +/* Perform some basic tests of binary operations on + * isl_multi_union_pw_aff objects. + */ +static int test_bin_mupa(isl_ctx *ctx) +{ + int i; + isl_bool ok; + isl_multi_union_pw_aff *mupa1, *mupa2, *res; + + for (i = 0; i < ARRAY_SIZE(mupa_bin_tests); ++i) { + mupa1 = isl_multi_union_pw_aff_read_from_str(ctx, + mupa_bin_tests[i].arg1); + mupa2 = isl_multi_union_pw_aff_read_from_str(ctx, + mupa_bin_tests[i].arg2); + res = isl_multi_union_pw_aff_read_from_str(ctx, + mupa_bin_tests[i].res); + mupa1 = mupa_bin_tests[i].fn(mupa1, mupa2); + ok = isl_multi_union_pw_aff_plain_is_equal(mupa1, res); + isl_multi_union_pw_aff_free(mupa1); + isl_multi_union_pw_aff_free(res); + if (ok < 0) + return -1; + if (!ok) + isl_die(ctx, isl_error_unknown, + "unexpected result", return -1); + } + + return 0; +} + +/* Inputs for basic tests of binary operations on + * pairs of isl_multi_union_pw_aff and isl_set objects. + * "fn" is the function that is tested. + * "arg1" and "arg2" are string descriptions of the inputs. + * "res" is a string description of the expected result. + */ +struct { + __isl_give isl_multi_union_pw_aff *(*fn)( + __isl_take isl_multi_union_pw_aff *mupa, + __isl_take isl_set *set); + const char *arg1; + const char *arg2; + const char *res; +} mupa_set_tests[] = { + { &isl_multi_union_pw_aff_intersect_range, + "C[{ B[i,j] -> [i + 2j] }]", "{ C[1] }", + "C[{ B[i,j] -> [i + 2j] : i + 2j = 1 }]" }, + { &isl_multi_union_pw_aff_intersect_range, + "C[{ B[i,j] -> [i + 2j] }]", "[N] -> { C[N] }", + "[N] -> C[{ B[i,j] -> [i + 2j] : i + 2j = N }]" }, + { &isl_multi_union_pw_aff_intersect_range, + "[N] -> C[{ B[i,j] -> [i + 2j + N] }]", "{ C[1] }", + "[N] -> C[{ B[i,j] -> [i + 2j + N] : i + 2j + N = 1 }]" }, + { &isl_multi_union_pw_aff_intersect_range, + "C[{ B[i,j] -> [i + 2j] }]", "[N] -> { C[x] : N >= 0 }", + "[N] -> C[{ B[i,j] -> [i + 2j] : N >= 0 }]" }, + { &isl_multi_union_pw_aff_intersect_range, + "C[]", "{ C[] }", "C[]" }, + { &isl_multi_union_pw_aff_intersect_range, + "[N] -> (C[] : { : N >= 0 })", + "{ C[] }", + "[N] -> (C[] : { : N >= 0 })" }, + { &isl_multi_union_pw_aff_intersect_range, + "(C[] : { A[a,b] })", + "{ C[] }", + "(C[] : { A[a,b] })" }, + { &isl_multi_union_pw_aff_intersect_range, + "[N] -> (C[] : { A[a,b] : a,b <= N })", + "{ C[] }", + "[N] -> (C[] : { A[a,b] : a,b <= N })" }, + { &isl_multi_union_pw_aff_intersect_range, + "C[]", + "[N] -> { C[] : N >= 0 }", + "[N] -> (C[] : { : N >= 0 })" }, + { &isl_multi_union_pw_aff_intersect_range, + "(C[] : { A[a,b] })", + "[N] -> { C[] : N >= 0 }", + "[N] -> (C[] : { A[a,b] : N >= 0 })" }, + { &isl_multi_union_pw_aff_intersect_range, + "[N] -> (C[] : { : N >= 0 })", + "[N] -> { C[] : N < 1024 }", + "[N] -> (C[] : { : 0 <= N < 1024 })" }, + { &isl_multi_union_pw_aff_intersect_params, + "C[{ B[i,j] -> [i + 2j] }]", "[N] -> { : N >= 0 }", + "[N] -> C[{ B[i,j] -> [i + 2j] : N >= 0}]" }, + { &isl_multi_union_pw_aff_intersect_params, + "[N] -> C[{ B[i,j] -> [i + 2j] : N <= 256 }]", "[N] -> { : N >= 0 }", + "[N] -> C[{ B[i,j] -> [i + 2j] : 0 <= N <= 256 }]" }, + { &isl_multi_union_pw_aff_intersect_params, + "[N] -> C[{ B[i,j] -> [i + 2j] : N <= 256 }]", "{ : }", + "[N] -> C[{ B[i,j] -> [i + 2j] : N <= 256 }]" }, + { &isl_multi_union_pw_aff_intersect_params, + "C[]", "[N] -> { : N >= 0 }", + "[N] -> (C[] : { : N >= 0 })" }, + { &isl_multi_union_pw_aff_intersect_params, + "(C[] : { A[a,b] })", "[N] -> { : N >= 0 }", + "[N] -> (C[] : { A[a,b] : N >= 0 })" }, + { &isl_multi_union_pw_aff_intersect_params, + "[N] -> (C[] : { A[a,N] })", "{ : }", + "[N] -> (C[] : { A[a,N] })" }, + { &isl_multi_union_pw_aff_intersect_params, + "[N] -> (C[] : { A[a,b] : N <= 256 })", "[N] -> { : N >= 0 }", + "[N] -> (C[] : { A[a,b] : 0 <= N <= 256 })" }, +}; + +/* Perform some basic tests of binary operations on + * pairs of isl_multi_union_pw_aff and isl_set objects. + */ +static int test_mupa_set(isl_ctx *ctx) +{ + int i; + isl_bool ok; + isl_multi_union_pw_aff *mupa, *res; + isl_set *set; + + for (i = 0; i < ARRAY_SIZE(mupa_set_tests); ++i) { + mupa = isl_multi_union_pw_aff_read_from_str(ctx, + mupa_set_tests[i].arg1); + set = isl_set_read_from_str(ctx, mupa_set_tests[i].arg2); + res = isl_multi_union_pw_aff_read_from_str(ctx, + mupa_set_tests[i].res); + mupa = mupa_set_tests[i].fn(mupa, set); + ok = isl_multi_union_pw_aff_plain_is_equal(mupa, res); + isl_multi_union_pw_aff_free(mupa); + isl_multi_union_pw_aff_free(res); + if (ok < 0) + return -1; + if (!ok) + isl_die(ctx, isl_error_unknown, + "unexpected result", return -1); + } + + return 0; +} + +/* Inputs for basic tests of binary operations on + * pairs of isl_multi_union_pw_aff and isl_union_set objects. + * "fn" is the function that is tested. + * "arg1" and "arg2" are string descriptions of the inputs. + * "res" is a string description of the expected result. + */ +struct { + __isl_give isl_multi_union_pw_aff *(*fn)( + __isl_take isl_multi_union_pw_aff *mupa, + __isl_take isl_union_set *uset); + const char *arg1; + const char *arg2; + const char *res; +} mupa_uset_tests[] = { + { &isl_multi_union_pw_aff_intersect_domain, + "C[{ B[i,j] -> [i + 2j] }]", "{ B[i,i] }", + "C[{ B[i,i] -> [3i] }]" }, + { &isl_multi_union_pw_aff_intersect_domain, + "(C[] : { B[i,j] })", "{ B[i,i] }", + "(C[] : { B[i,i] })" }, + { &isl_multi_union_pw_aff_intersect_domain, + "(C[] : { B[i,j] })", "[N] -> { B[N,N] }", + "[N] -> (C[] : { B[N,N] })" }, + { &isl_multi_union_pw_aff_intersect_domain, + "C[]", "{ B[i,i] }", + "(C[] : { B[i,i] })" }, + { &isl_multi_union_pw_aff_intersect_domain, + "[N] -> (C[] : { : N >= 0 })", "{ B[i,i] }", + "[N] -> (C[] : { B[i,i] : N >= 0 })" }, +}; + +/* Perform some basic tests of binary operations on + * pairs of isl_multi_union_pw_aff and isl_union_set objects. + */ +static int test_mupa_uset(isl_ctx *ctx) +{ + int i; + isl_bool ok; + isl_multi_union_pw_aff *mupa, *res; + isl_union_set *uset; + + for (i = 0; i < ARRAY_SIZE(mupa_uset_tests); ++i) { + mupa = isl_multi_union_pw_aff_read_from_str(ctx, + mupa_uset_tests[i].arg1); + uset = isl_union_set_read_from_str(ctx, + mupa_uset_tests[i].arg2); + res = isl_multi_union_pw_aff_read_from_str(ctx, + mupa_uset_tests[i].res); + mupa = mupa_uset_tests[i].fn(mupa, uset); + ok = isl_multi_union_pw_aff_plain_is_equal(mupa, res); + isl_multi_union_pw_aff_free(mupa); + isl_multi_union_pw_aff_free(res); + if (ok < 0) + return -1; + if (!ok) + isl_die(ctx, isl_error_unknown, + "unexpected result", return -1); + } + + return 0; +} + +/* Inputs for basic tests of binary operations on + * pairs of isl_multi_union_pw_aff and isl_multi_aff objects. + * "fn" is the function that is tested. + * "arg1" and "arg2" are string descriptions of the inputs. + * "res" is a string description of the expected result. + */ +struct { + __isl_give isl_multi_union_pw_aff *(*fn)( + __isl_take isl_multi_union_pw_aff *mupa, + __isl_take isl_multi_aff *ma); + const char *arg1; + const char *arg2; + const char *res; +} mupa_ma_tests[] = { + { &isl_multi_union_pw_aff_apply_multi_aff, + "C[{ A[i,j] -> [i]; B[i,j] -> [j] }, " + "{ A[i,j] -> [j]; B[i,j] -> [i] }]", + "{ C[a,b] -> D[b,a] }", + "D[{ A[i,j] -> [j]; B[i,j] -> [i] }, " + "{ A[i,j] -> [i]; B[i,j] -> [j] }]" }, + { &isl_multi_union_pw_aff_apply_multi_aff, + "C[{ A[i,j] -> [i] : i >= 0; B[i,j] -> [j] }, " + "{ A[i,j] -> [j]; B[i,j] -> [i] }]", + "{ C[a,b] -> D[b,a] }", + "D[{ A[i,j] -> [j] : i >= 0; B[i,j] -> [i] }, " + "{ A[i,j] -> [i] : i >= 0; B[i,j] -> [j] }]" }, + { &isl_multi_union_pw_aff_apply_multi_aff, + "C[{ A[i,j] -> [i]; B[i,j] -> [j] }]", + "[N] -> { C[a] -> D[a + N] }", + "[N] -> D[{ A[i,j] -> [i + N]; B[i,j] -> [j + N] }] " }, + { &isl_multi_union_pw_aff_apply_multi_aff, + "C[]", + "{ C[] -> D[] }", + "D[]" }, + { &isl_multi_union_pw_aff_apply_multi_aff, + "[N] -> (C[] : { : N >= 0 })", + "{ C[] -> D[] }", + "[N] -> (D[] : { : N >= 0 })" }, + { &isl_multi_union_pw_aff_apply_multi_aff, + "C[]", + "[N] -> { C[] -> D[N] }", + "[N] -> D[{ [N] }]" }, + { &isl_multi_union_pw_aff_apply_multi_aff, + "(C[] : { A[i,j] : i >= j })", + "{ C[] -> D[] }", + "(D[] : { A[i,j] : i >= j })" }, + { &isl_multi_union_pw_aff_apply_multi_aff, + "[N] -> (C[] : { A[i,j] : N >= 0 })", + "{ C[] -> D[] }", + "[N] -> (D[] : { A[i,j] : N >= 0 })" }, + { &isl_multi_union_pw_aff_apply_multi_aff, + "(C[] : { A[i,j] : i >= j })", + "[N] -> { C[] -> D[N] }", + "[N] -> (D[{ A[i,j] -> [N] : i >= j }])" }, +}; + +/* Perform some basic tests of binary operations on + * pairs of isl_multi_union_pw_aff and isl_multi_aff objects. + */ +static int test_mupa_ma(isl_ctx *ctx) +{ + int i; + isl_bool ok; + isl_multi_union_pw_aff *mupa, *res; + isl_multi_aff *ma; + + for (i = 0; i < ARRAY_SIZE(mupa_ma_tests); ++i) { + mupa = isl_multi_union_pw_aff_read_from_str(ctx, + mupa_ma_tests[i].arg1); + ma = isl_multi_aff_read_from_str(ctx, mupa_ma_tests[i].arg2); + res = isl_multi_union_pw_aff_read_from_str(ctx, + mupa_ma_tests[i].res); + mupa = mupa_ma_tests[i].fn(mupa, ma); + ok = isl_multi_union_pw_aff_plain_is_equal(mupa, res); + isl_multi_union_pw_aff_free(mupa); + isl_multi_union_pw_aff_free(res); + if (ok < 0) + return -1; + if (!ok) + isl_die(ctx, isl_error_unknown, + "unexpected result", return -1); + } + + return 0; +} + +/* Inputs for basic tests of binary operations on + * pairs of isl_multi_union_pw_aff and isl_pw_aff objects. + * "fn" is the function that is tested. + * "arg1" and "arg2" are string descriptions of the inputs. + * "res" is a string description of the expected result. + */ +struct { + __isl_give isl_union_pw_aff *(*fn)( + __isl_take isl_multi_union_pw_aff *mupa, + __isl_take isl_pw_aff *pa); + const char *arg1; + const char *arg2; + const char *res; +} mupa_pa_tests[] = { + { &isl_multi_union_pw_aff_apply_pw_aff, + "C[{ A[i,j] -> [i]; B[i,j] -> [j] }]", + "[N] -> { C[a] -> [a + N] }", + "[N] -> { A[i,j] -> [i + N]; B[i,j] -> [j + N] }" }, + { &isl_multi_union_pw_aff_apply_pw_aff, + "C[{ A[i,j] -> [i]; B[i,j] -> [j] }]", + "{ C[a] -> [a] : a >= 0; C[a] -> [-a] : a < 0 }", + "{ A[i,j] -> [i] : i >= 0; A[i,j] -> [-i] : i < 0; " + "B[i,j] -> [j] : j >= 0; B[i,j] -> [-j] : j < 0 }" }, + { &isl_multi_union_pw_aff_apply_pw_aff, + "C[]", + "[N] -> { C[] -> [N] }", + "[N] -> { [N] }" }, + { &isl_multi_union_pw_aff_apply_pw_aff, + "C[]", + "[N] -> { C[] -> [N] : N >= 0; C[] -> [-N] : N < 0 }", + "[N] -> { [N] : N >= 0; [-N] : N < 0 }" }, + { &isl_multi_union_pw_aff_apply_pw_aff, + "[N] -> (C[] : { : N >= 0 })", + "[N] -> { C[] -> [N] }", + "[N] -> { [N] : N >= 0 }" }, + { &isl_multi_union_pw_aff_apply_pw_aff, + "[N] -> (C[] : { : N >= 0 })", + "[N] -> { C[] -> [N] : N >= 0; C[] -> [-N] : N < 0 }", + "[N] -> { [N] : N >= 0 }" }, + { &isl_multi_union_pw_aff_apply_pw_aff, + "[N] -> (C[] : { : N >= 0 })", + "{ C[] -> [0] }", + "[N] -> { [0] : N >= 0 }" }, + { &isl_multi_union_pw_aff_apply_pw_aff, + "(C[] : { A[i,j] : i >= j })", + "[N] -> { C[] -> [N] }", + "[N] -> { A[i,j] -> [N] : i >= j }" }, + { &isl_multi_union_pw_aff_apply_pw_aff, + "(C[] : { A[i,j] : i >= j })", + "[N] -> { C[] -> [N] : N >= 0 }", + "[N] -> { A[i,j] -> [N] : i >= j and N >= 0 }" }, +}; + +/* Perform some basic tests of binary operations on + * pairs of isl_multi_union_pw_aff and isl_pw_aff objects. + */ +static int test_mupa_pa(isl_ctx *ctx) +{ + int i; + isl_bool ok; + isl_multi_union_pw_aff *mupa; + isl_union_pw_aff *upa, *res; + isl_pw_aff *pa; + + for (i = 0; i < ARRAY_SIZE(mupa_pa_tests); ++i) { + mupa = isl_multi_union_pw_aff_read_from_str(ctx, + mupa_pa_tests[i].arg1); + pa = isl_pw_aff_read_from_str(ctx, mupa_pa_tests[i].arg2); + res = isl_union_pw_aff_read_from_str(ctx, + mupa_pa_tests[i].res); + upa = mupa_pa_tests[i].fn(mupa, pa); + ok = isl_union_pw_aff_plain_is_equal(upa, res); + isl_union_pw_aff_free(upa); + isl_union_pw_aff_free(res); + if (ok < 0) + return -1; + if (!ok) + isl_die(ctx, isl_error_unknown, + "unexpected result", return -1); + } + + return 0; +} + +/* Inputs for basic tests of binary operations on + * pairs of isl_multi_union_pw_aff and isl_pw_multi_aff objects. + * "fn" is the function that is tested. + * "arg1" and "arg2" are string descriptions of the inputs. + * "res" is a string description of the expected result. + */ +struct { + __isl_give isl_multi_union_pw_aff *(*fn)( + __isl_take isl_multi_union_pw_aff *mupa, + __isl_take isl_pw_multi_aff *pma); + const char *arg1; + const char *arg2; + const char *res; +} mupa_pma_tests[] = { + { &isl_multi_union_pw_aff_apply_pw_multi_aff, + "C[{ A[i,j] -> [i]; B[i,j] -> [j] }, " + "{ A[i,j] -> [j]; B[i,j] -> [i] }]", + "{ C[a,b] -> D[b,a] }", + "D[{ A[i,j] -> [j]; B[i,j] -> [i] }, " + "{ A[i,j] -> [i]; B[i,j] -> [j] }]" }, + { &isl_multi_union_pw_aff_apply_pw_multi_aff, + "C[{ A[i,j] -> [i] : i >= 0; B[i,j] -> [j] }, " + "{ A[i,j] -> [j]; B[i,j] -> [i] }]", + "{ C[a,b] -> D[b,a] }", + "D[{ A[i,j] -> [j] : i >= 0; B[i,j] -> [i] }, " + "{ A[i,j] -> [i] : i >= 0; B[i,j] -> [j] }]" }, + { &isl_multi_union_pw_aff_apply_pw_multi_aff, + "C[{ A[i,j] -> [i]; B[i,j] -> [j] }]", + "[N] -> { C[a] -> D[a + N] }", + "[N] -> D[{ A[i,j] -> [i + N]; B[i,j] -> [j + N] }]" }, + { &isl_multi_union_pw_aff_apply_pw_multi_aff, + "C[{ A[i,j] -> [i]; B[i,j] -> [j] }]", + "{ C[a] -> D[a] : a >= 0; C[a] -> D[-a] : a < 0 }", + "D[{ A[i,j] -> [i] : i >= 0; A[i,j] -> [-i] : i < 0; " + "B[i,j] -> [j] : j >= 0; B[i,j] -> [-j] : j < 0 }]" }, + { &isl_multi_union_pw_aff_apply_pw_multi_aff, + "C[{ A[i,j] -> [i]; B[i,j] -> [j] }, " + "{ A[i,j] -> [j]; B[i,j] -> [i] }]", + "{ C[a,b] -> D[a,b] : a >= b; C[a,b] -> D[b,a] : a < b }", + "D[{ A[i,j] -> [i] : i >= j; A[i,j] -> [j] : i < j; " + "B[i,j] -> [j] : i <= j; B[i,j] -> [i] : i > j }, " + "{ A[i,j] -> [j] : i >= j; A[i,j] -> [i] : i < j; " + "B[i,j] -> [i] : i <= j; B[i,j] -> [j] : i > j }]" }, + { &isl_multi_union_pw_aff_apply_pw_multi_aff, + "C[]", + "{ C[] -> D[] }", + "D[]" }, + { &isl_multi_union_pw_aff_apply_pw_multi_aff, + "[N] -> (C[] : { : N >= 0 })", + "{ C[] -> D[] }", + "[N] -> (D[] : { : N >= 0 })" }, + { &isl_multi_union_pw_aff_apply_pw_multi_aff, + "C[]", + "[N] -> { C[] -> D[N] }", + "[N] -> D[{ [N] }]" }, + { &isl_multi_union_pw_aff_apply_pw_multi_aff, + "(C[] : { A[i,j] : i >= j })", + "{ C[] -> D[] }", + "(D[] : { A[i,j] : i >= j })" }, + { &isl_multi_union_pw_aff_apply_pw_multi_aff, + "[N] -> (C[] : { A[i,j] : N >= 0 })", + "{ C[] -> D[] }", + "[N] -> (D[] : { A[i,j] : N >= 0 })" }, + { &isl_multi_union_pw_aff_apply_pw_multi_aff, + "(C[] : { A[i,j] : i >= j })", + "[N] -> { C[] -> D[N] }", + "[N] -> (D[{ A[i,j] -> [N] : i >= j }])" }, + { &isl_multi_union_pw_aff_apply_pw_multi_aff, + "C[]", + "[N] -> { C[] -> D[N] : N >= 0; C[] -> D[-N] : N < 0 }", + "[N] -> D[{ [N] : N >= 0; [-N] : N < 0 }]" }, + { &isl_multi_union_pw_aff_apply_pw_multi_aff, + "[N] -> (C[] : { : N >= 0 })", + "[N] -> { C[] -> D[N] }", + "[N] -> D[{ [N] : N >= 0 }]" }, + { &isl_multi_union_pw_aff_apply_pw_multi_aff, + "[N] -> (C[] : { : N >= 0 })", + "[N] -> { C[] -> D[N] : N >= 0; C[] -> D[-N] : N < 0 }", + "[N] -> D[{ [N] : N >= 0 }]" }, + { &isl_multi_union_pw_aff_apply_pw_multi_aff, + "[N] -> (C[] : { : N >= 0 })", + "{ C[] -> D[0] }", + "[N] -> D[{ [0] : N >= 0 }]" }, + { &isl_multi_union_pw_aff_apply_pw_multi_aff, + "(C[] : { A[i,j] : i >= j })", + "[N] -> { C[] -> D[N] : N >= 0 }", + "[N] -> D[{ A[i,j] -> [N] : i >= j and N >= 0 }]" }, +}; + +/* Perform some basic tests of binary operations on + * pairs of isl_multi_union_pw_aff and isl_pw_multi_aff objects. + */ +static int test_mupa_pma(isl_ctx *ctx) +{ + int i; + isl_bool ok; + isl_multi_union_pw_aff *mupa, *res; + isl_pw_multi_aff *pma; + + for (i = 0; i < ARRAY_SIZE(mupa_pma_tests); ++i) { + mupa = isl_multi_union_pw_aff_read_from_str(ctx, + mupa_pma_tests[i].arg1); + pma = isl_pw_multi_aff_read_from_str(ctx, + mupa_pma_tests[i].arg2); + res = isl_multi_union_pw_aff_read_from_str(ctx, + mupa_pma_tests[i].res); + mupa = mupa_pma_tests[i].fn(mupa, pma); + ok = isl_multi_union_pw_aff_plain_is_equal(mupa, res); + isl_multi_union_pw_aff_free(mupa); + isl_multi_union_pw_aff_free(res); + if (ok < 0) + return -1; + if (!ok) + isl_die(ctx, isl_error_unknown, + "unexpected result", return -1); + } + + return 0; +} + +/* Inputs for basic tests of binary operations on + * pairs of isl_multi_union_pw_aff and isl_union_pw_multi_aff objects. + * "fn" is the function that is tested. + * "arg1" and "arg2" are string descriptions of the inputs. + * "res" is a string description of the expected result. + */ +struct { + __isl_give isl_multi_union_pw_aff *(*fn)( + __isl_take isl_multi_union_pw_aff *mupa, + __isl_take isl_union_pw_multi_aff *upma); + const char *arg1; + const char *arg2; + const char *res; +} mupa_upma_tests[] = { + { &isl_multi_union_pw_aff_pullback_union_pw_multi_aff, + "C[{ B[i,j] -> [i + 2j] }]", "{ A[a,b] -> B[b,a] }", + "C[{ A[a,b] -> [b + 2a] }]" }, + { &isl_multi_union_pw_aff_pullback_union_pw_multi_aff, + "C[{ B[i,j] -> [i + 2j] }]", + "{ A[a,b] -> B[b,a] : b > a }", + "C[{ A[a,b] -> [b + 2a] : b > a }]" }, + { &isl_multi_union_pw_aff_pullback_union_pw_multi_aff, + "C[{ B[i,j] -> [i + 2j] : j > 4 }]", + "{ A[a,b] -> B[b,a] : b > a }", + "C[{ A[a,b] -> [b + 2a] : b > a > 4 }]" }, + { &isl_multi_union_pw_aff_pullback_union_pw_multi_aff, + "C[{ B[i,j] -> [i + 2j] }]", + "{ A[a,b] -> B[b,a] : a > b; A[a,b] -> B[a,b] : a <= b }", + "C[{ A[a,b] -> [b + 2a] : a > b; A[a,b] -> [a + 2b] : a <= b }]" }, + { &isl_multi_union_pw_aff_pullback_union_pw_multi_aff, + "(C[] : { B[a,b] })", + "{ A[a,b] -> B[b,a] }", + "(C[] : { A[a,b] })" }, + { &isl_multi_union_pw_aff_pullback_union_pw_multi_aff, + "(C[] : { B[a,b] })", + "{ B[a,b] -> A[b,a] }", + "(C[] : { })" }, + { &isl_multi_union_pw_aff_pullback_union_pw_multi_aff, + "(C[] : { B[a,b] })", + "{ A[a,b] -> B[b,a] : a > b }", + "(C[] : { A[a,b] : a > b })" }, + { &isl_multi_union_pw_aff_pullback_union_pw_multi_aff, + "(C[] : { B[a,b] : a > b })", + "{ A[a,b] -> B[b,a] }", + "(C[] : { A[a,b] : b > a })" }, + { &isl_multi_union_pw_aff_pullback_union_pw_multi_aff, + "[N] -> (C[] : { B[a,b] : a > N })", + "{ A[a,b] -> B[b,a] : a > b }", + "[N] -> (C[] : { A[a,b] : a > b > N })" }, + { &isl_multi_union_pw_aff_pullback_union_pw_multi_aff, + "(C[] : { B[a,b] : a > b })", + "[N] -> { A[a,b] -> B[b,a] : a > N }", + "[N] -> (C[] : { A[a,b] : b > a > N })" }, + { &isl_multi_union_pw_aff_pullback_union_pw_multi_aff, + "C[]", + "{ A[a,b] -> B[b,a] }", + "C[]" }, + { &isl_multi_union_pw_aff_pullback_union_pw_multi_aff, + "[N] -> (C[] : { : N >= 0 })", + "{ A[a,b] -> B[b,a] }", + "[N] -> (C[] : { : N >= 0 })" }, + { &isl_multi_union_pw_aff_pullback_union_pw_multi_aff, + "C[]", + "[N] -> { A[a,b] -> B[b,a] : N >= 0 }", + "[N] -> (C[] : { : N >= 0 })" }, +}; + +/* Perform some basic tests of binary operations on + * pairs of isl_multi_union_pw_aff and isl_union_pw_multi_aff objects. + */ +static int test_mupa_upma(isl_ctx *ctx) +{ + int i; + isl_bool ok; + isl_multi_union_pw_aff *mupa, *res; + isl_union_pw_multi_aff *upma; + + for (i = 0; i < ARRAY_SIZE(mupa_upma_tests); ++i) { + mupa = isl_multi_union_pw_aff_read_from_str(ctx, + mupa_upma_tests[i].arg1); + upma = isl_union_pw_multi_aff_read_from_str(ctx, + mupa_upma_tests[i].arg2); + res = isl_multi_union_pw_aff_read_from_str(ctx, + mupa_upma_tests[i].res); + mupa = mupa_upma_tests[i].fn(mupa, upma); + ok = isl_multi_union_pw_aff_plain_is_equal(mupa, res); + isl_multi_union_pw_aff_free(mupa); + isl_multi_union_pw_aff_free(res); + if (ok < 0) + return -1; + if (!ok) + isl_die(ctx, isl_error_unknown, + "unexpected result", return -1); + } + + return 0; +} + +/* Check that the input tuple of an isl_aff can be set properly. + */ +static isl_stat test_aff_set_tuple_id(isl_ctx *ctx) +{ + isl_id *id; + isl_aff *aff; + isl_stat equal; + + aff = isl_aff_read_from_str(ctx, "{ [x] -> [x + 1] }"); + id = isl_id_alloc(ctx, "A", NULL); + aff = isl_aff_set_tuple_id(aff, isl_dim_in, id); + equal = aff_check_plain_equal(aff, "{ A[x] -> [x + 1] }"); + isl_aff_free(aff); + if (equal < 0) + return isl_stat_error; + + return isl_stat_ok; +} + +/* Check that affine expressions get normalized on addition/subtraction. + * In particular, check that (final) unused integer divisions get removed + * such that an expression derived from expressions with integer divisions + * is found to be obviously equal to one that is created directly. + */ +static isl_stat test_aff_normalize(isl_ctx *ctx) +{ + isl_aff *aff, *aff2; + isl_stat ok; + + aff = isl_aff_read_from_str(ctx, "{ [x] -> [x//2] }"); + aff2 = isl_aff_read_from_str(ctx, "{ [x] -> [1 + x//2] }"); + aff = isl_aff_sub(aff2, aff); + ok = aff_check_plain_equal(aff, "{ [x] -> [1] }"); + isl_aff_free(aff); + + return ok; +} + +int test_aff(isl_ctx *ctx) +{ + const char *str; + isl_set *set; + isl_space *space; + isl_local_space *ls; + isl_aff *aff; + int zero; + isl_stat equal; + + if (test_upa(ctx) < 0) + return -1; + if (test_bin_aff(ctx) < 0) + return -1; + if (test_bin_pw_aff(ctx) < 0) + return -1; + if (test_upma_test(ctx) < 0) + return -1; + if (test_bin_upma(ctx) < 0) + return -1; + if (test_bin_upma_fail(ctx) < 0) + return -1; + if (test_upma_uset(ctx) < 0) + return -1; + if (test_un_mpa(ctx) < 0) + return -1; + if (test_bin_mpa(ctx) < 0) + return -1; + if (test_un_mupa(ctx) < 0) + return -1; + if (test_bin_mupa(ctx) < 0) + return -1; + if (test_mupa_set(ctx) < 0) + return -1; + if (test_mupa_uset(ctx) < 0) + return -1; + if (test_mupa_ma(ctx) < 0) + return -1; + if (test_mupa_pa(ctx) < 0) + return -1; + if (test_mupa_pma(ctx) < 0) + return -1; + if (test_mupa_upma(ctx) < 0) + return -1; + + space = isl_space_set_alloc(ctx, 0, 1); + ls = isl_local_space_from_space(space); + aff = isl_aff_zero_on_domain(ls); + + aff = isl_aff_add_coefficient_si(aff, isl_dim_in, 0, 1); + aff = isl_aff_scale_down_ui(aff, 3); + aff = isl_aff_floor(aff); + aff = isl_aff_add_coefficient_si(aff, isl_dim_in, 0, 1); + aff = isl_aff_scale_down_ui(aff, 2); + aff = isl_aff_floor(aff); + aff = isl_aff_add_coefficient_si(aff, isl_dim_in, 0, 1); + + str = "{ [10] }"; + set = isl_set_read_from_str(ctx, str); + aff = isl_aff_gist(aff, set); + + aff = isl_aff_add_constant_si(aff, -16); + zero = isl_aff_plain_is_zero(aff); + isl_aff_free(aff); + + if (zero < 0) + return -1; + if (!zero) + isl_die(ctx, isl_error_unknown, "unexpected result", return -1); + + aff = isl_aff_read_from_str(ctx, "{ [-1] }"); + aff = isl_aff_scale_down_ui(aff, 64); + aff = isl_aff_floor(aff); + equal = aff_check_plain_equal(aff, "{ [-1] }"); + isl_aff_free(aff); + if (equal < 0) + return -1; + + if (test_aff_set_tuple_id(ctx) < 0) + return -1; + if (test_aff_normalize(ctx) < 0) + return -1; + + return 0; +} + +/* Inputs for isl_set_bind tests. + * "set" is the input set. + * "tuple" is the binding tuple. + * "res" is the expected result. + */ +static +struct { + const char *set; + const char *tuple; + const char *res; +} bind_set_tests[] = { + { "{ A[M, N] : M mod 2 = 0 and N mod 8 = 3 }", + "{ A[M, N] }", + "[M, N] -> { : M mod 2 = 0 and N mod 8 = 3 }" }, + { "{ B[N, M] : M mod 2 = 0 and N mod 8 = 3 }", + "{ B[N, M] }", + "[M, N] -> { : M mod 2 = 0 and N mod 8 = 3 }" }, + { "[M] -> { C[N] : M mod 2 = 0 and N mod 8 = 3 }", + "{ C[N] }", + "[M, N] -> { : M mod 2 = 0 and N mod 8 = 3 }" }, + { "[M] -> { D[x, N] : x mod 2 = 0 and N mod 8 = 3 and M >= 0 }", + "{ D[M, N] }", + "[M, N] -> { : M mod 2 = 0 and N mod 8 = 3 and M >= 0 }" }, +}; + +/* Perform basic isl_set_bind tests. + */ +static isl_stat test_bind_set(isl_ctx *ctx) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(bind_set_tests); ++i) { + const char *str; + isl_set *set; + isl_multi_id *tuple; + isl_stat r; + + set = isl_set_read_from_str(ctx, bind_set_tests[i].set); + str = bind_set_tests[i].tuple; + tuple = isl_multi_id_read_from_str(ctx, str); + set = isl_set_bind(set, tuple); + r = set_check_equal(set, bind_set_tests[i].res); + isl_set_free(set); + if (r < 0) + return isl_stat_error; + } + + return isl_stat_ok; +} + +/* Inputs for isl_map_bind_domain tests. + * "map" is the input map. + * "tuple" is the binding tuple. + * "res" is the expected result. + */ +struct { + const char *map; + const char *tuple; + const char *res; +} bind_map_domain_tests[] = { + { "{ A[M, N] -> [M + floor(N/2)] }", + "{ A[M, N] }", + "[M, N] -> { [M + floor(N/2)] }" }, + { "{ B[N, M] -> [M + floor(N/2)] }", + "{ B[N, M] }", + "[N, M] -> { [M + floor(N/2)] }" }, + { "[M] -> { C[N] -> [M + floor(N/2)] }", + "{ C[N] }", + "[M, N] -> { [M + floor(N/2)] }" }, + { "[M] -> { C[x, N] -> [x + floor(N/2)] }", + "{ C[M, N] }", + "[M, N] -> { [M + floor(N/2)] }" }, + { "[M] -> { C[x, N] -> [M + floor(N/2)] }", + "{ C[M, N] }", + "[M, N] -> { [M + floor(N/2)] }" }, + { "[A, M] -> { C[N, x] -> [x + floor(N/2)] }", + "{ C[N, M] }", + "[A, N, M] -> { [M + floor(N/2)] }" }, +}; + +/* Perform basic isl_map_bind_domain tests. + */ +static isl_stat test_bind_map_domain(isl_ctx *ctx) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(bind_map_domain_tests); ++i) { + const char *str; + isl_map *map; + isl_set *set; + isl_multi_id *tuple; + isl_stat r; + + str = bind_map_domain_tests[i].map; + map = isl_map_read_from_str(ctx, str); + str = bind_map_domain_tests[i].tuple; + tuple = isl_multi_id_read_from_str(ctx, str); + set = isl_map_bind_domain(map, tuple); + str = bind_map_domain_tests[i].res; + r = set_check_equal(set, str); + isl_set_free(set); + if (r < 0) + return isl_stat_error; + } + + return isl_stat_ok; +} + +/* Inputs for isl_union_map_bind_range tests. + * "map" is the input union map. + * "tuple" is the binding tuple. + * "res" is the expected result. + */ +struct { + const char *map; + const char *tuple; + const char *res; +} bind_umap_range_tests[] = { + { "{ B[N, M] -> A[M, N] : M mod 2 = 0 and N mod 8 = 3 }", + "{ A[M, N] }", + "[M, N] -> { B[N, M] : M mod 2 = 0 and N mod 8 = 3 }" }, + { "{ B[N, M] -> A[M, N] : M mod 2 = 0 and N mod 8 = 3 }", + "{ B[M, N] }", + "{ }" }, + { "{ A[] -> B[]; C[] -> D[]; E[] -> B[] }", + "{ B[] }", + "{ A[]; E[] }" }, +}; + +/* Perform basic isl_union_map_bind_range tests. + */ +static isl_stat test_bind_umap_range(isl_ctx *ctx) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(bind_umap_range_tests); ++i) { + const char *str; + isl_union_map *umap; + isl_union_set *uset; + isl_multi_id *tuple; + isl_stat r; + + str = bind_umap_range_tests[i].map; + umap = isl_union_map_read_from_str(ctx, str); + str = bind_umap_range_tests[i].tuple; + tuple = isl_multi_id_read_from_str(ctx, str); + uset = isl_union_map_bind_range(umap, tuple); + str = bind_umap_range_tests[i].res; + r = uset_check_equal(uset, str); + isl_union_set_free(uset); + if (r < 0) + return isl_stat_error; + } + + return isl_stat_ok; +} + +/* Inputs for isl_pw_multi_aff_bind_domain tests. + * "pma" is the input expression. + * "tuple" is the binding tuple. + * "res" is the expected result. + */ +struct { + const char *pma; + const char *tuple; + const char *res; +} bind_pma_domain_tests[] = { + { "{ A[M, N] -> [M + floor(N/2)] }", + "{ A[M, N] }", + "[M, N] -> { [M + floor(N/2)] }" }, + { "{ B[N, M] -> [M + floor(N/2)] }", + "{ B[N, M] }", + "[N, M] -> { [M + floor(N/2)] }" }, + { "[M] -> { C[N] -> [M + floor(N/2)] }", + "{ C[N] }", + "[M, N] -> { [M + floor(N/2)] }" }, + { "[M] -> { C[x, N] -> [x + floor(N/2)] }", + "{ C[M, N] }", + "[M, N] -> { [M + floor(N/2)] }" }, + { "[M] -> { C[x, N] -> [M + floor(N/2)] }", + "{ C[M, N] }", + "[M, N] -> { [M + floor(N/2)] }" }, + { "[A, M] -> { C[N, x] -> [x + floor(N/2)] }", + "{ C[N, M] }", + "[A, N, M] -> { [M + floor(N/2)] }" }, +}; + +/* Perform basic isl_pw_multi_aff_bind_domain tests. + */ +static isl_stat test_bind_pma_domain(isl_ctx *ctx) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(bind_pma_domain_tests); ++i) { + const char *str; + isl_pw_multi_aff *pma; + isl_multi_id *tuple; + isl_stat r; + + str = bind_pma_domain_tests[i].pma; + pma = isl_pw_multi_aff_read_from_str(ctx, str); + str = bind_pma_domain_tests[i].tuple; + tuple = isl_multi_id_read_from_str(ctx, str); + pma = isl_pw_multi_aff_bind_domain(pma, tuple); + str = bind_pma_domain_tests[i].res; + r = pw_multi_aff_check_plain_equal(pma, str); + isl_pw_multi_aff_free(pma); + if (r < 0) + return isl_stat_error; + } + + return isl_stat_ok; +} + +/* Inputs for isl_pw_multi_aff_bind_domain_wrapped_domain tests. + * "pma" is the input expression. + * "tuple" is the binding tuple. + * "res" is the expected result. + */ +struct { + const char *pma; + const char *tuple; + const char *res; +} bind_pma_domain_wrapped_tests[] = { + { "{ [A[M, N] -> B[]] -> [M + floor(N/2)] }", + "{ A[M, N] }", + "[M, N] -> { B[] -> [M + floor(N/2)] }" }, + { "{ [B[N, M] -> D[]] -> [M + floor(N/2)] }", + "{ B[N, M] }", + "[N, M] -> { D[] -> [M + floor(N/2)] }" }, + { "[M] -> { [C[N] -> B[x]] -> [x + M + floor(N/2)] }", + "{ C[N] }", + "[M, N] -> { B[x] -> [x + M + floor(N/2)] }" }, + { "[M] -> { [C[x, N] -> B[]] -> [x + floor(N/2)] }", + "{ C[M, N] }", + "[M, N] -> { B[] -> [M + floor(N/2)] }" }, + { "[M] -> { [C[x, N] -> B[]] -> [M + floor(N/2)] }", + "{ C[M, N] }", + "[M, N] -> { B[] -> [M + floor(N/2)] }" }, + { "[A, M] -> { [C[N, x] -> B[]] -> [x + floor(N/2)] }", + "{ C[N, M] }", + "[A, N, M] -> { B[] -> [M + floor(N/2)] }" }, +}; + +/* Perform basic isl_pw_multi_aff_bind_domain_wrapped_domain tests. + */ +static isl_stat test_bind_pma_domain_wrapped(isl_ctx *ctx) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(bind_pma_domain_wrapped_tests); ++i) { + const char *str; + isl_pw_multi_aff *pma; + isl_multi_id *tuple; + isl_stat r; + + str = bind_pma_domain_wrapped_tests[i].pma; + pma = isl_pw_multi_aff_read_from_str(ctx, str); + str = bind_pma_domain_wrapped_tests[i].tuple; + tuple = isl_multi_id_read_from_str(ctx, str); + pma = isl_pw_multi_aff_bind_domain_wrapped_domain(pma, tuple); + str = bind_pma_domain_wrapped_tests[i].res; + r = pw_multi_aff_check_plain_equal(pma, str); + isl_pw_multi_aff_free(pma); + if (r < 0) + return isl_stat_error; + } + + return isl_stat_ok; +} + +/* Inputs for isl_aff_bind_id tests. + * "aff" is the input expression. + * "id" is the binding id. + * "res" is the expected result. + */ +static +struct { + const char *aff; + const char *id; + const char *res; +} bind_aff_tests[] = { + { "{ [4] }", "M", "[M = 4] -> { : }" }, + { "{ B[x] -> [floor(x/2)] }", "M", "[M] -> { B[x] : M = floor(x/2) }" }, + { "[M] -> { [4] }", "M", "[M = 4] -> { : }" }, + { "[M] -> { [floor(M/2)] }", "M", "[M] -> { : floor(M/2) = M }" }, + { "{ [NaN] }", "M", "{ : false }" }, + { "{ A[x] -> [NaN] }", "M", "{ A[x] : false }" }, +}; + +/* Perform basic isl_aff_bind_id tests. + */ +static isl_stat test_bind_aff(isl_ctx *ctx) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(bind_aff_tests); ++i) { + isl_aff *aff; + isl_set *res; + isl_id *id; + isl_stat r; + + aff = isl_aff_read_from_str(ctx, bind_aff_tests[i].aff); + id = isl_id_read_from_str(ctx, bind_aff_tests[i].id); + res = isl_set_from_basic_set(isl_aff_bind_id(aff, id)); + r = set_check_equal(res, bind_aff_tests[i].res); + isl_set_free(res); + if (r < 0) + return isl_stat_error; + } + + return isl_stat_ok; +} + +/* Inputs for isl_pw_aff_bind_id tests. + * "pa" is the input expression. + * "id" is the binding id. + * "res" is the expected result. + */ +static +struct { + const char *pa; + const char *id; + const char *res; +} bind_pa_tests[] = { + { "{ [4] }", "M", "[M = 4] -> { : }" }, + { "{ B[x] -> [floor(x/2)] }", "M", "[M] -> { B[x] : M = floor(x/2) }" }, + { "[M] -> { [4] }", "M", "[M = 4] -> { : }" }, + { "[M] -> { [floor(M/2)] }", "M", "[M] -> { : floor(M/2) = M }" }, + { "[M] -> { [M] : M >= 0; [-M] : M < 0 }", "M", "[M] -> { : M >= 0 }" }, + { "{ [NaN] }", "M", "{ : false }" }, + { "{ A[x] -> [NaN] }", "M", "{ A[x] : false }" }, +}; + +/* Perform basic isl_pw_aff_bind_id tests. + */ +static isl_stat test_bind_pa(isl_ctx *ctx) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(bind_pa_tests); ++i) { + isl_pw_aff *pa; + isl_set *res; + isl_id *id; + isl_stat r; + + pa = isl_pw_aff_read_from_str(ctx, bind_pa_tests[i].pa); + id = isl_id_read_from_str(ctx, bind_pa_tests[i].id); + res = isl_pw_aff_bind_id(pa, id); + r = set_check_equal(res, bind_pa_tests[i].res); + isl_set_free(res); + if (r < 0) + return isl_stat_error; + } + + return isl_stat_ok; +} + +/* Inputs for isl_multi_union_pw_aff_bind tests. + * "mupa" is the input expression. + * "tuple" is the binding tuple. + * "res" is the expected result. + */ +static +struct { + const char *mupa; + const char *tuple; + const char *res; +} bind_mupa_tests[] = { + { "A[{ [4] }, { [5] }]", + "{ A[M, N] }", + "[M = 4, N = 5] -> { : }" }, + { "A[{ B[x] -> [floor(x/2)] }, { B[y] -> [y + 5] }]", + "{ A[M, N] }", + "[M, N] -> { B[x] : M = floor(x/2) and N = x + 5 }" }, + { "[M] -> A[{ [4] }, { [M + 1] }]", + "{ A[M, N] }", + "[M = 4, N = 5] -> { : }" }, +}; + +/* Perform basic isl_multi_union_pw_aff_bind tests. + */ +static isl_stat test_bind_mupa(isl_ctx *ctx) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(bind_mupa_tests); ++i) { + const char *str; + isl_multi_union_pw_aff *mupa; + isl_union_set *res; + isl_multi_id *tuple; + isl_stat r; + + str = bind_mupa_tests[i].mupa; + mupa = isl_multi_union_pw_aff_read_from_str(ctx, str); + str = bind_mupa_tests[i].tuple; + tuple = isl_multi_id_read_from_str(ctx, str); + res = isl_multi_union_pw_aff_bind(mupa, tuple); + r = uset_check_equal(res, bind_mupa_tests[i].res); + isl_union_set_free(res); + if (r < 0) + return isl_stat_error; + } + + return isl_stat_ok; +} + +/* Perform tests that reinterpret dimensions as parameters. + */ +static int test_bind(isl_ctx *ctx) +{ + if (test_bind_set(ctx) < 0) + return -1; + if (test_bind_map_domain(ctx) < 0) + return -1; + if (test_bind_umap_range(ctx) < 0) + return -1; + if (test_bind_pma_domain(ctx) < 0) + return -1; + if (test_bind_pma_domain_wrapped(ctx) < 0) + return -1; + if (test_bind_aff(ctx) < 0) + return -1; + if (test_bind_pa(ctx) < 0) + return -1; + if (test_bind_mupa(ctx) < 0) + return -1; + + return 0; +} + +/* Inputs for isl_set_unbind_params tests. + * "set" is the input parameter domain. + * "tuple" is the tuple of the constructed set. + * "res" is the expected result. + */ +struct { + const char *set; + const char *tuple; + const char *res; +} unbind_set_tests[] = { + { "[M, N] -> { : M mod 2 = 0 and N mod 8 = 3 }", + "{ A[M, N] }", + "{ A[M, N] : M mod 2 = 0 and N mod 8 = 3 }" }, + { "[M, N] -> { : M mod 2 = 0 and N mod 8 = 3 }", + "{ B[N, M] }", + "{ B[N, M] : M mod 2 = 0 and N mod 8 = 3 }" }, + { "[M, N] -> { : M mod 2 = 0 and N mod 8 = 3 }", + "{ C[N] }", + "[M] -> { C[N] : M mod 2 = 0 and N mod 8 = 3 }" }, + { "[M, N] -> { : M mod 2 = 0 and N mod 8 = 3 }", + "{ D[T, N] }", + "[M] -> { D[x, N] : M mod 2 = 0 and N mod 8 = 3 }" }, +}; + +/* Perform basic isl_set_unbind_params tests. + */ +static isl_stat test_unbind_set(isl_ctx *ctx) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(unbind_set_tests); ++i) { + const char *str; + isl_set *set; + isl_multi_id *tuple; + isl_stat r; + + set = isl_set_read_from_str(ctx, unbind_set_tests[i].set); + str = unbind_set_tests[i].tuple; + tuple = isl_multi_id_read_from_str(ctx, str); + set = isl_set_unbind_params(set, tuple); + r = set_check_equal(set, unbind_set_tests[i].res); + isl_set_free(set); + if (r < 0) + return isl_stat_error; + } + + return isl_stat_ok; +} + +/* Inputs for isl_aff_unbind_params_insert_domain tests. + * "aff" is the input affine expression defined over a parameter domain. + * "tuple" is the tuple of the domain that gets introduced. + * "res" is the expected result. + */ +struct { + const char *aff; + const char *tuple; + const char *res; +} unbind_aff_tests[] = { + { "[M, N] -> { [M + floor(N/2)] }", + "{ A[M, N] }", + "{ A[M, N] -> [M + floor(N/2)] }" }, + { "[M, N] -> { [M + floor(N/2)] }", + "{ B[N, M] }", + "{ B[N, M] -> [M + floor(N/2)] }" }, + { "[M, N] -> { [M + floor(N/2)] }", + "{ C[N] }", + "[M] -> { C[N] -> [M + floor(N/2)] }" }, + { "[M, N] -> { [M + floor(N/2)] }", + "{ D[A, B, C, N, Z] }", + "[M] -> { D[A, B, C, N, Z] -> [M + floor(N/2)] }" }, +}; + +/* Perform basic isl_aff_unbind_params_insert_domain tests. + */ +static isl_stat test_unbind_aff(isl_ctx *ctx) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(unbind_aff_tests); ++i) { + const char *str; + isl_aff *aff; + isl_multi_id *tuple; + isl_stat r; + + aff = isl_aff_read_from_str(ctx, unbind_aff_tests[i].aff); + str = unbind_aff_tests[i].tuple; + tuple = isl_multi_id_read_from_str(ctx, str); + aff = isl_aff_unbind_params_insert_domain(aff, tuple); + r = aff_check_plain_equal(aff, unbind_aff_tests[i].res); + isl_aff_free(aff); + if (r < 0) + return isl_stat_error; + } + + return isl_stat_ok; +} + +/* Inputs for isl_multi_aff_unbind_params_insert_domain tests. + * "ma" is the input multi affine expression defined over a parameter domain. + * "tuple" is the tuple of the domain that gets introduced. + * "res" is the expected result. + */ +static struct { + const char *ma; + const char *tuple; + const char *res; +} unbind_multi_aff_tests[] = { + { "[M, N] -> { T[M + floor(N/2)] }", + "{ A[M, N] }", + "{ A[M, N] -> T[M + floor(N/2)] }" }, + { "[M, N] -> { [M + floor(N/2)] }", + "{ B[N, M] }", + "{ B[N, M] -> [M + floor(N/2)] }" }, + { "[M, N] -> { [M + floor(N/2)] }", + "{ C[N] }", + "[M] -> { C[N] -> [M + floor(N/2)] }" }, + { "[M, N] -> { [M + floor(N/2)] }", + "{ D[A, B, C, N, Z] }", + "[M] -> { D[A, B, C, N, Z] -> [M + floor(N/2)] }" }, + { "[M, N] -> { T[M + floor(N/2), N + floor(M/3)] }", + "{ A[M, N] }", + "{ A[M, N] -> T[M + floor(N/2), N + floor(M/3)] }" }, +}; + +/* Perform basic isl_multi_aff_unbind_params_insert_domain tests. + */ +static isl_stat test_unbind_multi_aff(isl_ctx *ctx) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(unbind_multi_aff_tests); ++i) { + const char *str; + isl_multi_aff *ma; + isl_multi_id *tuple; + isl_stat r; + + str = unbind_multi_aff_tests[i].ma; + ma = isl_multi_aff_read_from_str(ctx, str); + str = unbind_multi_aff_tests[i].tuple; + tuple = isl_multi_id_read_from_str(ctx, str); + ma = isl_multi_aff_unbind_params_insert_domain(ma, tuple); + str = unbind_multi_aff_tests[i].res; + r = multi_aff_check_plain_equal(ma, str); + isl_multi_aff_free(ma); + if (r < 0) + return isl_stat_error; + } + + return isl_stat_ok; +} + +/* Perform tests that reinterpret parameters. + */ +static int test_unbind(isl_ctx *ctx) +{ + if (test_unbind_set(ctx) < 0) + return -1; + if (test_unbind_aff(ctx) < 0) + return -1; + if (test_unbind_multi_aff(ctx) < 0) + return -1; + + return 0; +} + +/* Check that "pa" consists of a single expression. + */ +static int check_single_piece(isl_ctx *ctx, __isl_take isl_pw_aff *pa) +{ + isl_size n; + + n = isl_pw_aff_n_piece(pa); + isl_pw_aff_free(pa); + + if (n < 0) + return -1; + if (n != 1) + isl_die(ctx, isl_error_unknown, "expecting single expression", + return -1); + + return 0; +} + +/* Check that the computation below results in a single expression. + * One or two expressions may result depending on which constraint + * ends up being considered as redundant with respect to the other + * constraints after the projection that is performed internally + * by isl_set_dim_min. + */ +static int test_dim_max_1(isl_ctx *ctx) +{ + const char *str; + isl_set *set; + isl_pw_aff *pa; + + str = "[n] -> { [a, b] : n >= 0 and 4a >= -4 + n and b >= 0 and " + "-4a <= b <= 3 and b < n - 4a }"; + set = isl_set_read_from_str(ctx, str); + pa = isl_set_dim_min(set, 0); + return check_single_piece(ctx, pa); +} + +/* Check that the computation below results in a single expression. + * The PIP problem corresponding to these constraints has a row + * that causes a split of the solution domain. The solver should + * first pick rows that split off empty parts such that the actual + * solution domain does not get split. + * Note that the description contains some redundant constraints. + * If these constraints get removed first, then the row mentioned + * above does not appear in the PIP problem. + */ +static int test_dim_max_2(isl_ctx *ctx) +{ + const char *str; + isl_set *set; + isl_pw_aff *pa; + + str = "[P, N] -> { [a] : a < N and a >= 0 and N > P and a <= P and " + "N > 0 and P >= 0 }"; + set = isl_set_read_from_str(ctx, str); + pa = isl_set_dim_max(set, 0); + return check_single_piece(ctx, pa); +} + +int test_dim_max(isl_ctx *ctx) +{ + int equal; + const char *str; + isl_set *set1, *set2; + isl_set *set; + isl_map *map; + isl_pw_aff *pwaff; + + if (test_dim_max_1(ctx) < 0) + return -1; + if (test_dim_max_2(ctx) < 0) + return -1; + + str = "[N] -> { [i] : 0 <= i <= min(N,10) }"; + set = isl_set_read_from_str(ctx, str); + pwaff = isl_set_dim_max(set, 0); + set1 = isl_set_from_pw_aff(pwaff); + str = "[N] -> { [10] : N >= 10; [N] : N <= 9 and N >= 0 }"; + set2 = isl_set_read_from_str(ctx, str); + equal = isl_set_is_equal(set1, set2); + isl_set_free(set1); + isl_set_free(set2); + if (equal < 0) + return -1; + if (!equal) + isl_die(ctx, isl_error_unknown, "unexpected result", return -1); + + str = "[N] -> { [i] : 0 <= i <= max(2N,N+6) }"; + set = isl_set_read_from_str(ctx, str); + pwaff = isl_set_dim_max(set, 0); + set1 = isl_set_from_pw_aff(pwaff); + str = "[N] -> { [6 + N] : -6 <= N <= 5; [2N] : N >= 6 }"; + set2 = isl_set_read_from_str(ctx, str); + equal = isl_set_is_equal(set1, set2); + isl_set_free(set1); + isl_set_free(set2); + if (equal < 0) + return -1; + if (!equal) + isl_die(ctx, isl_error_unknown, "unexpected result", return -1); + + str = "[N] -> { [i] : 0 <= i <= 2N or 0 <= i <= N+6 }"; + set = isl_set_read_from_str(ctx, str); + pwaff = isl_set_dim_max(set, 0); + set1 = isl_set_from_pw_aff(pwaff); + str = "[N] -> { [6 + N] : -6 <= N <= 5; [2N] : N >= 6 }"; + set2 = isl_set_read_from_str(ctx, str); + equal = isl_set_is_equal(set1, set2); + isl_set_free(set1); + isl_set_free(set2); + if (equal < 0) + return -1; + if (!equal) + isl_die(ctx, isl_error_unknown, "unexpected result", return -1); + + str = "[N,M] -> { [i,j] -> [([i/16]), i%16, ([j/16]), j%16] : " + "0 <= i < N and 0 <= j < M }"; + map = isl_map_read_from_str(ctx, str); + set = isl_map_range(map); + + pwaff = isl_set_dim_max(isl_set_copy(set), 0); + set1 = isl_set_from_pw_aff(pwaff); + str = "[N,M] -> { [([(N-1)/16])] : M,N > 0 }"; + set2 = isl_set_read_from_str(ctx, str); + equal = isl_set_is_equal(set1, set2); + isl_set_free(set1); + isl_set_free(set2); + + pwaff = isl_set_dim_max(isl_set_copy(set), 3); + set1 = isl_set_from_pw_aff(pwaff); + str = "[N,M] -> { [t] : t = min(M-1,15) and M,N > 0 }"; + set2 = isl_set_read_from_str(ctx, str); + if (equal >= 0 && equal) + equal = isl_set_is_equal(set1, set2); + isl_set_free(set1); + isl_set_free(set2); + + isl_set_free(set); + + if (equal < 0) + return -1; + if (!equal) + isl_die(ctx, isl_error_unknown, "unexpected result", return -1); + + /* Check that solutions are properly merged. */ + str = "[n] -> { [a, b, c] : c >= -4a - 2b and " + "c <= -1 + n - 4a - 2b and c >= -2b and " + "4a >= -4 + n and c >= 0 }"; + set = isl_set_read_from_str(ctx, str); + pwaff = isl_set_dim_min(set, 2); + set1 = isl_set_from_pw_aff(pwaff); + str = "[n] -> { [(0)] : n >= 1 }"; + set2 = isl_set_read_from_str(ctx, str); + equal = isl_set_is_equal(set1, set2); + isl_set_free(set1); + isl_set_free(set2); + + if (equal < 0) + return -1; + if (!equal) + isl_die(ctx, isl_error_unknown, "unexpected result", return -1); + + /* Check that empty solution lie in the right space. */ + str = "[n] -> { [t,a] : 1 = 0 }"; + set = isl_set_read_from_str(ctx, str); + pwaff = isl_set_dim_max(set, 0); + set1 = isl_set_from_pw_aff(pwaff); + str = "[n] -> { [t] : 1 = 0 }"; + set2 = isl_set_read_from_str(ctx, str); + equal = isl_set_is_equal(set1, set2); + isl_set_free(set1); + isl_set_free(set2); + + if (equal < 0) + return -1; + if (!equal) + isl_die(ctx, isl_error_unknown, "unexpected result", return -1); + + return 0; +} + +/* Basic test for isl_pw_multi_aff_product. + * + * Check that multiple pieces are properly handled. + */ +static int test_product_pma(isl_ctx *ctx) +{ + isl_stat equal; + const char *str; + isl_pw_multi_aff *pma1, *pma2; + + str = "{ A[i] -> B[1] : i < 0; A[i] -> B[2] : i >= 0 }"; + pma1 = isl_pw_multi_aff_read_from_str(ctx, str); + str = "{ C[] -> D[] }"; + pma2 = isl_pw_multi_aff_read_from_str(ctx, str); + pma1 = isl_pw_multi_aff_product(pma1, pma2); + str = "{ [A[i] -> C[]] -> [B[(1)] -> D[]] : i < 0;" + "[A[i] -> C[]] -> [B[(2)] -> D[]] : i >= 0 }"; + equal = pw_multi_aff_check_plain_equal(pma1, str); + isl_pw_multi_aff_free(pma1); + if (equal < 0) + return -1; + + return 0; +} + +int test_product(isl_ctx *ctx) +{ + const char *str; + isl_set *set; + isl_union_set *uset1, *uset2; + int ok; + + str = "{ A[i] }"; + set = isl_set_read_from_str(ctx, str); + set = isl_set_product(set, isl_set_copy(set)); + ok = isl_set_is_wrapping(set); + isl_set_free(set); + if (ok < 0) + return -1; + if (!ok) + isl_die(ctx, isl_error_unknown, "unexpected result", return -1); + + str = "{ [] }"; + uset1 = isl_union_set_read_from_str(ctx, str); + uset1 = isl_union_set_product(uset1, isl_union_set_copy(uset1)); + str = "{ [[] -> []] }"; + uset2 = isl_union_set_read_from_str(ctx, str); + ok = isl_union_set_is_equal(uset1, uset2); + isl_union_set_free(uset1); + isl_union_set_free(uset2); + if (ok < 0) + return -1; + if (!ok) + isl_die(ctx, isl_error_unknown, "unexpected result", return -1); + + if (test_product_pma(ctx) < 0) + return -1; + + return 0; +} + +/* Check that two sets are not considered disjoint just because + * they have a different set of (named) parameters. + */ +static int test_disjoint(isl_ctx *ctx) +{ + const char *str; + isl_set *set, *set2; + int disjoint; + + str = "[n] -> { [[]->[]] }"; + set = isl_set_read_from_str(ctx, str); + str = "{ [[]->[]] }"; + set2 = isl_set_read_from_str(ctx, str); + disjoint = isl_set_is_disjoint(set, set2); + isl_set_free(set); + isl_set_free(set2); + if (disjoint < 0) + return -1; + if (disjoint) + isl_die(ctx, isl_error_unknown, "unexpected result", return -1); + + return 0; +} + +/* Inputs for isl_pw_multi_aff_is_equal tests. + * "f1" and "f2" are the two function that need to be compared. + * "equal" is the expected result. + */ +struct { + int equal; + const char *f1; + const char *f2; +} pma_equal_tests[] = { + { 1, "[N] -> { [floor(N/2)] : 0 <= N <= 1 }", + "[N] -> { [0] : 0 <= N <= 1 }" }, + { 1, "[N] -> { [floor(N/2)] : 0 <= N <= 2 }", + "[N] -> { [0] : 0 <= N <= 1; [1] : N = 2 }" }, + { 0, "[N] -> { [floor(N/2)] : 0 <= N <= 2 }", + "[N] -> { [0] : 0 <= N <= 1 }" }, + { 0, "{ [NaN] }", "{ [NaN] }" }, +}; + +int test_equal(isl_ctx *ctx) +{ + int i; + const char *str; + isl_set *set, *set2; + int equal; + + str = "{ S_6[i] }"; + set = isl_set_read_from_str(ctx, str); + str = "{ S_7[i] }"; + set2 = isl_set_read_from_str(ctx, str); + equal = isl_set_is_equal(set, set2); + isl_set_free(set); + isl_set_free(set2); + if (equal < 0) + return -1; + if (equal) + isl_die(ctx, isl_error_unknown, "unexpected result", return -1); + + for (i = 0; i < ARRAY_SIZE(pma_equal_tests); ++i) { + int expected = pma_equal_tests[i].equal; + isl_pw_multi_aff *f1, *f2; + + f1 = isl_pw_multi_aff_read_from_str(ctx, pma_equal_tests[i].f1); + f2 = isl_pw_multi_aff_read_from_str(ctx, pma_equal_tests[i].f2); + equal = isl_pw_multi_aff_is_equal(f1, f2); + isl_pw_multi_aff_free(f1); + isl_pw_multi_aff_free(f2); + if (equal < 0) + return -1; + if (equal != expected) + isl_die(ctx, isl_error_unknown, + "unexpected equality result", return -1); + } + + return 0; +} + +static int test_plain_fixed(isl_ctx *ctx, __isl_take isl_map *map, + enum isl_dim_type type, unsigned pos, int fixed) +{ + isl_bool test; + + test = isl_map_plain_is_fixed(map, type, pos, NULL); + isl_map_free(map); + if (test < 0) + return -1; + if (test == fixed) + return 0; + if (fixed) + isl_die(ctx, isl_error_unknown, + "map not detected as fixed", return -1); + else + isl_die(ctx, isl_error_unknown, + "map detected as fixed", return -1); +} + +int test_fixed(isl_ctx *ctx) +{ + const char *str; + isl_map *map; + + str = "{ [i] -> [i] }"; + map = isl_map_read_from_str(ctx, str); + if (test_plain_fixed(ctx, map, isl_dim_out, 0, 0)) + return -1; + str = "{ [i] -> [1] }"; + map = isl_map_read_from_str(ctx, str); + if (test_plain_fixed(ctx, map, isl_dim_out, 0, 1)) + return -1; + str = "{ S_1[p1] -> [o0] : o0 = -2 and p1 >= 1 and p1 <= 7 }"; + map = isl_map_read_from_str(ctx, str); + if (test_plain_fixed(ctx, map, isl_dim_out, 0, 1)) + return -1; + map = isl_map_read_from_str(ctx, str); + map = isl_map_neg(map); + if (test_plain_fixed(ctx, map, isl_dim_out, 0, 1)) + return -1; + + return 0; +} + +struct isl_vertices_test_data { + const char *set; + int n; + const char *vertex[6]; +} vertices_tests[] = { + { "{ A[t, i] : t = 12 and i >= 4 and i <= 12 }", + 2, { "{ A[12, 4] }", "{ A[12, 12] }" } }, + { "{ A[t, i] : t = 14 and i = 1 }", + 1, { "{ A[14, 1] }" } }, + { "[n, m] -> { [a, b, c] : b <= a and a <= n and b > 0 and c >= b and " + "c <= m and m <= n and m > 0 }", + 6, { + "[n, m] -> { [n, m, m] : 0 < m <= n }", + "[n, m] -> { [n, 1, m] : 0 < m <= n }", + "[n, m] -> { [n, 1, 1] : 0 < m <= n }", + "[n, m] -> { [m, m, m] : 0 < m <= n }", + "[n, m] -> { [1, 1, m] : 0 < m <= n }", + "[n, m] -> { [1, 1, 1] : 0 < m <= n }" + } }, + /* An input with implicit equality constraints among the parameters. */ + { "[N, M] -> { [a, b] : M >= 3 and 9 + 3M <= a <= 29 + 2N + 11M and " + "2b >= M + a and 5 - 2N - M + a <= 2b <= 3 + a and " + "3b >= 15 + a }", + 2, { + "[N, M] -> { [(21), (12)] : M = 3 and N >= 0 }", + "[N, M] -> { [(61 + 2N), (32 + N)] : M = 3 and N >= 0 }", + } + }, +}; + +/* Check that "vertex" corresponds to one of the vertices in data->vertex. + */ +static isl_stat find_vertex(__isl_take isl_vertex *vertex, void *user) +{ + struct isl_vertices_test_data *data = user; + isl_ctx *ctx; + isl_multi_aff *ma; + isl_basic_set *bset; + isl_pw_multi_aff *pma; + int i; + isl_bool equal; + + ctx = isl_vertex_get_ctx(vertex); + bset = isl_vertex_get_domain(vertex); + ma = isl_vertex_get_expr(vertex); + pma = isl_pw_multi_aff_alloc(isl_set_from_basic_set(bset), ma); + + for (i = 0; i < data->n; ++i) { + isl_pw_multi_aff *pma_i; + + pma_i = isl_pw_multi_aff_read_from_str(ctx, data->vertex[i]); + equal = isl_pw_multi_aff_plain_is_equal(pma, pma_i); + isl_pw_multi_aff_free(pma_i); + + if (equal < 0 || equal) + break; + } + + isl_pw_multi_aff_free(pma); + isl_vertex_free(vertex); + + if (equal < 0) + return isl_stat_error; + + return equal ? isl_stat_ok : isl_stat_error; +} + +int test_vertices(isl_ctx *ctx) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(vertices_tests); ++i) { + isl_basic_set *bset; + isl_vertices *vertices; + int ok = 1; + isl_size n; + + bset = isl_basic_set_read_from_str(ctx, vertices_tests[i].set); + vertices = isl_basic_set_compute_vertices(bset); + n = isl_vertices_get_n_vertices(vertices); + if (vertices_tests[i].n != n) + ok = 0; + if (isl_vertices_foreach_vertex(vertices, &find_vertex, + &vertices_tests[i]) < 0) + ok = 0; + isl_vertices_free(vertices); + isl_basic_set_free(bset); + + if (n < 0) + return -1; + if (!ok) + isl_die(ctx, isl_error_unknown, "unexpected vertices", + return -1); + } + + return 0; +} + +/* Inputs for basic tests of binary operations on isl_union_map. + * "fn" is the function that is being tested. + * "arg1" and "arg2" are string descriptions of the inputs. + * "res" is a string description of the expected result. + */ +static struct { + __isl_give isl_union_map *(*fn)(__isl_take isl_union_map *umap1, + __isl_take isl_union_map *umap2); + const char *arg1; + const char *arg2; + const char *res; +} umap_bin_tests[] = { + { &isl_union_map_intersect, + "[n] -> { A[i] -> [] : 0 <= i <= n; B[] -> [] }", + "[m] -> { A[i] -> [] : 0 <= i <= m; C[] -> [] }", + "[m, n] -> { A[i] -> [] : 0 <= i <= n and i <= m }" }, + { &isl_union_map_intersect_domain_factor_domain, + "{ [A[i] -> B[i + 1]] -> C[i + 2] }", + "[N] -> { B[i] -> C[N] }", + "{ }" }, + { &isl_union_map_intersect_domain_factor_domain, + "{ [A[i] -> B[i + 1]] -> C[i + 2] }", + "[N] -> { A[i] -> C[N] }", + "[N] -> { [A[N - 2] -> B[N - 1]] -> C[N] }" }, + { &isl_union_map_intersect_domain_factor_domain, + "{ T[A[i] -> B[i + 1]] -> C[i + 2] }", + "[N] -> { A[i] -> C[N] }", + "[N] -> { T[A[N - 2] -> B[N - 1]] -> C[N] }" }, + { &isl_union_map_intersect_domain_factor_range, + "{ [A[i] -> B[i + 1]] -> C[i + 2] }", + "[N] -> { B[i] -> C[N] }", + "[N] -> { [A[N - 2] -> B[N - 1]] -> C[N] }" }, + { &isl_union_map_intersect_domain_factor_range, + "{ T[A[i] -> B[i + 1]] -> C[i + 2] }", + "[N] -> { B[i] -> C[N] }", + "[N] -> { T[A[N - 2] -> B[N - 1]] -> C[N] }" }, + { &isl_union_map_intersect_domain_factor_range, + "{ [A[i] -> B[i + 1]] -> C[i + 2] }", + "[N] -> { A[i] -> C[N] }", + "{ }" }, + { &isl_union_map_intersect_range_factor_domain, + "{ A[i] -> [B[i + 1] -> C[i + 2]] }", + "[N] -> { A[i] -> B[N] }", + "[N] -> { A[N - 1] -> [B[N] -> C[N + 1]] }" }, + { &isl_union_map_intersect_range_factor_domain, + "{ A[i] -> T[B[i + 1] -> C[i + 2]] }", + "[N] -> { A[i] -> B[N] }", + "[N] -> { A[N - 1] -> T[B[N] -> C[N + 1]] }" }, + { &isl_union_map_intersect_range_factor_domain, + "{ A[i] -> [B[i + 1] -> C[i + 2]] }", + "[N] -> { A[i] -> C[N] }", + "{ }" }, + { &isl_union_map_intersect_range_factor_range, + "{ A[i] -> [B[i + 1] -> C[i + 2]] }", + "[N] -> { A[i] -> C[N] }", + "[N] -> { A[N - 2] -> [B[N - 1] -> C[N]] }" }, + { &isl_union_map_intersect_range_factor_range, + "{ A[i] -> T[B[i + 1] -> C[i + 2]] }", + "[N] -> { A[i] -> C[N] }", + "[N] -> { A[N - 2] -> T[B[N - 1] -> C[N]] }" }, + { &isl_union_map_intersect_range_factor_range, + "{ A[i] -> [B[i + 1] -> C[i + 2]] }", + "[N] -> { A[i] -> B[N] }", + "{ }" }, +}; + +/* Perform basic tests of binary operations on isl_union_map. + */ +static isl_stat test_bin_union_map(isl_ctx *ctx) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(umap_bin_tests); ++i) { + const char *str; + isl_union_map *umap1, *umap2, *res; + isl_bool equal; + + str = umap_bin_tests[i].arg1; + umap1 = isl_union_map_read_from_str(ctx, str); + str = umap_bin_tests[i].arg2; + umap2 = isl_union_map_read_from_str(ctx, str); + str = umap_bin_tests[i].res; + res = isl_union_map_read_from_str(ctx, str); + umap1 = umap_bin_tests[i].fn(umap1, umap2); + equal = isl_union_map_is_equal(umap1, res); + isl_union_map_free(umap1); + isl_union_map_free(res); + if (equal < 0) + return isl_stat_error; + if (!equal) + isl_die(ctx, isl_error_unknown, + "unexpected result", return isl_stat_error); + } + + return isl_stat_ok; +} + +/* Check that isl_union_set_contains finds space independently + * of the parameters. + */ +static isl_stat test_union_set_contains(isl_ctx *ctx) +{ + const char *str; + isl_bool ok; + isl_space *space; + isl_id *id; + isl_union_set *uset; + + str = "[N] -> { A[0:N]; B[*,*] }"; + uset = isl_union_set_read_from_str(ctx, str); + space = isl_space_unit(ctx); + id = isl_id_alloc(ctx, "A", NULL); + space = isl_space_add_named_tuple_id_ui(space, id, 1); + ok = isl_union_set_contains(uset, space); + isl_space_free(space); + isl_union_set_free(uset); + + if (ok < 0) + return isl_stat_error; + if (!ok) + isl_die(ctx, isl_error_unknown, + "unexpected result", return isl_stat_error); + + return isl_stat_ok; +} + +/* Perform basic tests of operations on isl_union_map or isl_union_set. + */ +static int test_union_map(isl_ctx *ctx) +{ + if (test_bin_union_map(ctx) < 0) + return -1; + if (test_union_set_contains(ctx) < 0) + return -1; + return 0; +} + +#undef BASE +#define BASE union_pw_qpolynomial +#include "isl_test_plain_equal_templ.c" + +/* Check that the result of applying "fn" to "a" and "b" + * in (obviously) equal to "res". + */ +static isl_stat test_union_pw_op(isl_ctx *ctx, const char *a, const char *b, + __isl_give isl_union_pw_qpolynomial *(*fn)( + __isl_take isl_union_pw_qpolynomial *upwqp1, + __isl_take isl_union_pw_qpolynomial *upwqp2), + const char *res) +{ + isl_stat r; + isl_union_pw_qpolynomial *upwqp1, *upwqp2; + + upwqp1 = isl_union_pw_qpolynomial_read_from_str(ctx, a); + upwqp2 = isl_union_pw_qpolynomial_read_from_str(ctx, b); + upwqp1 = fn(upwqp1, upwqp2); + r = union_pw_qpolynomial_check_plain_equal(upwqp1, res); + isl_union_pw_qpolynomial_free(upwqp1); + + return r; +} + +int test_union_pw(isl_ctx *ctx) +{ + int equal; + isl_stat r; + const char *str; + isl_union_set *uset; + isl_union_pw_qpolynomial *upwqp1, *upwqp2; + const char *a, *b; + + str = "{ [x] -> x^2 }"; + upwqp1 = isl_union_pw_qpolynomial_read_from_str(ctx, str); + upwqp2 = isl_union_pw_qpolynomial_copy(upwqp1); + uset = isl_union_pw_qpolynomial_domain(upwqp1); + upwqp1 = isl_union_pw_qpolynomial_copy(upwqp2); + upwqp1 = isl_union_pw_qpolynomial_intersect_domain(upwqp1, uset); + equal = isl_union_pw_qpolynomial_plain_is_equal(upwqp1, upwqp2); + isl_union_pw_qpolynomial_free(upwqp1); + isl_union_pw_qpolynomial_free(upwqp2); + if (equal < 0) + return -1; + if (!equal) + isl_die(ctx, isl_error_unknown, "unexpected result", return -1); + + a = "{ A[x] -> x^2 : x >= 0; B[x] -> x }"; + b = "{ A[x] -> x }"; + str = "{ A[x] -> x^2 + x : x >= 0; A[x] -> x : x < 0; B[x] -> x }"; + if (test_union_pw_op(ctx, a, b, &isl_union_pw_qpolynomial_add, str) < 0) + return -1; + str = "{ A[x] -> x^2 - x : x >= 0; A[x] -> -x : x < 0; B[x] -> x }"; + if (test_union_pw_op(ctx, a, b, &isl_union_pw_qpolynomial_sub, str) < 0) + return -1; + + str = "{ A[x] -> 0 }"; + a = "{ A[x] -> 1 }"; + b = "{ A[x] -> -1 }"; + if (test_union_pw_op(ctx, a, b, &isl_union_pw_qpolynomial_add, str) < 0) + return -1; + a = "{ A[x] -> 1 }"; + b = "{ A[x] -> 1 }"; + if (test_union_pw_op(ctx, a, b, &isl_union_pw_qpolynomial_sub, str) < 0) + return -1; + + str = "{ [A[x] -> B[y,z]] -> x^2 + y * floor(x/4) * floor(z/2); " + "C[z] -> z^3 }"; + upwqp1 = isl_union_pw_qpolynomial_read_from_str(ctx, str); + upwqp1 = isl_union_pw_qpolynomial_domain_reverse(upwqp1); + str = "{ [B[y,z] -> A[x]] -> x^2 + y * floor(x/4) * floor(z/2) }"; + r = union_pw_qpolynomial_check_plain_equal(upwqp1, str); + isl_union_pw_qpolynomial_free(upwqp1); + if (r < 0) + return -1; + + return 0; +} + +/* Inputs for basic tests of functions that select + * subparts of the domain of an isl_multi_union_pw_aff. + * "fn" is the function that is tested. + * "arg" is a string description of the input. + * "res" is a string description of the expected result. + */ +struct { + __isl_give isl_union_set *(*fn)( + __isl_take isl_multi_union_pw_aff *mupa); + const char *arg; + const char *res; +} un_locus_tests[] = { + { &isl_multi_union_pw_aff_zero_union_set, + "F[{ A[i,j] -> [i]; B[i,j] -> [i] }]", + "{ A[0,j]; B[0,j] }" }, + { &isl_multi_union_pw_aff_zero_union_set, + "F[{ A[i,j] -> [i-j]; B[i,j] -> [i-j] : i >= 0 }]", + "{ A[i,i]; B[i,i] : i >= 0 }" }, + { &isl_multi_union_pw_aff_zero_union_set, + "(F[] : { A[i,j]; B[i,i] : i >= 0 })", + "{ A[i,j]; B[i,i] : i >= 0 }" }, +}; + +/* Perform some basic tests of functions that select + * subparts of the domain of an isl_multi_union_pw_aff. + */ +static int test_un_locus(isl_ctx *ctx) +{ + int i; + isl_bool ok; + isl_union_set *uset, *res; + isl_multi_union_pw_aff *mupa; + + for (i = 0; i < ARRAY_SIZE(un_locus_tests); ++i) { + mupa = isl_multi_union_pw_aff_read_from_str(ctx, + un_locus_tests[i].arg); + res = isl_union_set_read_from_str(ctx, un_locus_tests[i].res); + uset = un_locus_tests[i].fn(mupa); + ok = isl_union_set_is_equal(uset, res); + isl_union_set_free(uset); + isl_union_set_free(res); + if (ok < 0) + return -1; + if (!ok) + isl_die(ctx, isl_error_unknown, + "unexpected result", return -1); + } + + return 0; +} + +/* Inputs for basic tests of functions that select + * subparts of an isl_union_map based on a relation + * specified by an isl_multi_union_pw_aff. + * "fn" is the function that is tested. + * "arg1" and "arg2" are string descriptions of the inputs. + * "res" is a string description of the expected result. + */ +struct { + __isl_give isl_union_map *(*fn)( + __isl_take isl_union_map *umap, + __isl_take isl_multi_union_pw_aff *mupa); + const char *arg1; + const char *arg2; + const char *res; +} bin_locus_tests[] = { + { &isl_union_map_eq_at_multi_union_pw_aff, + "{ A[i,j] -> B[i',j'] }", + "F[{ A[i,j] -> [i]; B[i,j] -> [i] }]", + "{ A[i,j] -> B[i,j'] }" }, + { &isl_union_map_eq_at_multi_union_pw_aff, + "{ A[i,j] -> B[i',j'] }", + "F[{ A[i,j] -> [i]; B[i,j] -> [i] }, " + "{ A[i,j] -> [j]; B[i,j] -> [j] }]", + "{ A[i,j] -> B[i,j] }" }, + { &isl_union_map_eq_at_multi_union_pw_aff, + "{ A[i,j] -> B[i',j']; A[i,j] -> C[i',j'] }", + "F[{ A[i,j] -> [i]; B[i,j] -> [i] }]", + "{ A[i,j] -> B[i,j'] }" }, + { &isl_union_map_eq_at_multi_union_pw_aff, + "{ A[i,j] -> B[i',j']; A[i,j] -> C[i',j'] }", + "F[{ A[i,j] -> [i]; B[i,j] -> [i]; C[i,j] -> [0] }]", + "{ A[i,j] -> B[i,j']; A[0,j] -> C[i',j'] }" }, + { &isl_union_map_eq_at_multi_union_pw_aff, + "{ A[i,j] -> B[i',j'] }", + "F[{ A[i,j] -> [i] : i > j; B[i,j] -> [i] }]", + "{ A[i,j] -> B[i,j'] : i > j }" }, + { &isl_union_map_lex_le_at_multi_union_pw_aff, + "{ A[i,j] -> B[i',j'] }", + "F[{ A[i,j] -> [i]; B[i,j] -> [i] }, " + "{ A[i,j] -> [j]; B[i,j] -> [j] }]", + "{ A[i,j] -> B[i',j'] : i,j <<= i',j' }" }, + { &isl_union_map_lex_lt_at_multi_union_pw_aff, + "{ A[i,j] -> B[i',j'] }", + "F[{ A[i,j] -> [i]; B[i,j] -> [i] }, " + "{ A[i,j] -> [j]; B[i,j] -> [j] }]", + "{ A[i,j] -> B[i',j'] : i,j << i',j' }" }, + { &isl_union_map_lex_ge_at_multi_union_pw_aff, + "{ A[i,j] -> B[i',j'] }", + "F[{ A[i,j] -> [i]; B[i,j] -> [i] }, " + "{ A[i,j] -> [j]; B[i,j] -> [j] }]", + "{ A[i,j] -> B[i',j'] : i,j >>= i',j' }" }, + { &isl_union_map_lex_gt_at_multi_union_pw_aff, + "{ A[i,j] -> B[i',j'] }", + "F[{ A[i,j] -> [i]; B[i,j] -> [i] }, " + "{ A[i,j] -> [j]; B[i,j] -> [j] }]", + "{ A[i,j] -> B[i',j'] : i,j >> i',j' }" }, + { &isl_union_map_eq_at_multi_union_pw_aff, + "{ A[i,j] -> B[i',j']; A[i,j] -> C[i',j'] }", + "(F[] : { A[i,j]; B[i,j] })", + "{ A[i,j] -> B[i',j'] }" }, + { &isl_union_map_eq_at_multi_union_pw_aff, + "{ A[i,j] -> B[i',j'] }", + "(F[] : { A[i,j] : i > j; B[i,j] : i < j })", + "{ A[i,j] -> B[i',j'] : i > j and i' < j' }" }, + { &isl_union_map_eq_at_multi_union_pw_aff, + "[N] -> { A[i,j] -> B[i',j'] : i,i' <= N }", + "(F[] : { A[i,j] : i > j; B[i,j] : i < j })", + "[N] -> { A[i,j] -> B[i',j'] : i > j and i' < j' and i,i' <= N }" }, + { &isl_union_map_eq_at_multi_union_pw_aff, + "{ A[i,j] -> B[i',j'] }", + "[N] -> (F[] : { A[i,j] : i < N; B[i,j] : i < N })", + "[N] -> { A[i,j] -> B[i',j'] : i,i' < N }" }, + { &isl_union_map_eq_at_multi_union_pw_aff, + "{ A[i,j] -> B[i',j'] }", + "[N] -> (F[] : { : N >= 0 })", + "[N] -> { A[i,j] -> B[i',j'] : N >= 0 }" }, +}; + +/* Perform some basic tests of functions that select + * subparts of an isl_union_map based on a relation + * specified by an isl_multi_union_pw_aff. + */ +static int test_bin_locus(isl_ctx *ctx) +{ + int i; + isl_bool ok; + isl_union_map *umap, *res; + isl_multi_union_pw_aff *mupa; + + for (i = 0; i < ARRAY_SIZE(bin_locus_tests); ++i) { + umap = isl_union_map_read_from_str(ctx, + bin_locus_tests[i].arg1); + mupa = isl_multi_union_pw_aff_read_from_str(ctx, + bin_locus_tests[i].arg2); + res = isl_union_map_read_from_str(ctx, bin_locus_tests[i].res); + umap = bin_locus_tests[i].fn(umap, mupa); + ok = isl_union_map_is_equal(umap, res); + isl_union_map_free(umap); + isl_union_map_free(res); + if (ok < 0) + return -1; + if (!ok) + isl_die(ctx, isl_error_unknown, + "unexpected result", return -1); + } + + return 0; +} + +/* Inputs for basic tests of functions that determine + * the part of the domain where two isl_multi_aff objects + * related to each other in a specific way. + * "fn" is the function that is being tested. + * "arg1" and "arg2" are string descriptions of the inputs. + * "res" is a string description of the expected result. + */ +static struct { + __isl_give isl_set *(*fn)(__isl_take isl_multi_aff *ma1, + __isl_take isl_multi_aff *ma2); + const char *arg1; + const char *arg2; + const char *res; +} bin_locus_ma_tests[] = { + { &isl_multi_aff_lex_le_set, "{ [] }", "{ [] }", "{ : }" }, + { &isl_multi_aff_lex_lt_set, "{ [] }", "{ [] }", "{ : false }" }, + { &isl_multi_aff_lex_le_set, + "{ A[i] -> [i] }", "{ A[i] -> [0] }", + "{ A[i] : i <= 0 }" }, + { &isl_multi_aff_lex_lt_set, + "{ A[i] -> [i] }", "{ A[i] -> [0] }", + "{ A[i] : i < 0 }" }, + { &isl_multi_aff_lex_le_set, + "{ A[i] -> [i, i] }", "{ A[i] -> [0, 0] }", + "{ A[i] : i <= 0 }" }, + { &isl_multi_aff_lex_le_set, + "{ A[i] -> [i, 0] }", "{ A[i] -> [0, 0] }", + "{ A[i] : i <= 0 }" }, + { &isl_multi_aff_lex_le_set, + "{ A[i] -> [i, 1] }", "{ A[i] -> [0, 0] }", + "{ A[i] : i < 0 }" }, +}; + +/* Perform some basic tests of functions that determine + * the part of the domain where two isl_multi_aff objects + * related to each other in a specific way. + */ +static isl_stat test_bin_locus_ma(isl_ctx *ctx) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(bin_locus_ma_tests); ++i) { + const char *str; + isl_bool ok; + isl_multi_aff *ma1, *ma2; + isl_set *set, *res; + + str = bin_locus_ma_tests[i].arg1; + ma1 = isl_multi_aff_read_from_str(ctx, str); + str = bin_locus_ma_tests[i].arg2; + ma2 = isl_multi_aff_read_from_str(ctx, str); + res = isl_set_read_from_str(ctx, bin_locus_ma_tests[i].res); + set = bin_locus_ma_tests[i].fn(ma1, ma2); + ok = isl_set_is_equal(set, res); + isl_set_free(set); + isl_set_free(res); + if (ok < 0) + return isl_stat_error; + if (!ok) + isl_die(ctx, isl_error_unknown, + "unexpected result", return isl_stat_error); + } + + return isl_stat_ok; +} + +/* Perform basic locus tests. + */ +static int test_locus(isl_ctx *ctx) +{ + if (test_un_locus(ctx) < 0) + return -1; + if (test_bin_locus(ctx) < 0) + return -1; + if (test_bin_locus_ma(ctx) < 0) + return -1; + return 0; +} + +/* Test that isl_union_pw_qpolynomial_eval picks up the function + * defined over the correct domain space. + */ +static int test_eval_1(isl_ctx *ctx) +{ + const char *str; + isl_point *pnt; + isl_set *set; + isl_union_pw_qpolynomial *upwqp; + isl_val *v; + int cmp; + + str = "{ A[x] -> x^2; B[x] -> -x^2 }"; + upwqp = isl_union_pw_qpolynomial_read_from_str(ctx, str); + str = "{ A[6] }"; + set = isl_set_read_from_str(ctx, str); + pnt = isl_set_sample_point(set); + v = isl_union_pw_qpolynomial_eval(upwqp, pnt); + cmp = isl_val_cmp_si(v, 36); + isl_val_free(v); + + if (!v) + return -1; + if (cmp != 0) + isl_die(ctx, isl_error_unknown, "unexpected value", return -1); + + return 0; +} + +/* Check that isl_qpolynomial_eval handles getting called on a void point. + */ +static int test_eval_2(isl_ctx *ctx) +{ + const char *str; + isl_point *pnt; + isl_set *set; + isl_qpolynomial *qp; + isl_val *v; + isl_bool ok; + + str = "{ A[x] -> [x] }"; + qp = isl_qpolynomial_from_aff(isl_aff_read_from_str(ctx, str)); + str = "{ A[x] : false }"; + set = isl_set_read_from_str(ctx, str); + pnt = isl_set_sample_point(set); + v = isl_qpolynomial_eval(qp, pnt); + ok = isl_val_is_nan(v); + isl_val_free(v); + + if (ok < 0) + return -1; + if (!ok) + isl_die(ctx, isl_error_unknown, "expecting NaN", return -1); + + return 0; +} + +/* Check that a polynomial (without local variables) can be evaluated + * in a rational point. + */ +static isl_stat test_eval_3(isl_ctx *ctx) +{ + isl_pw_qpolynomial *pwqp; + isl_point *pnt; + isl_val *v; + isl_stat r; + + pwqp = isl_pw_qpolynomial_read_from_str(ctx, "{ [x] -> x^2 }"); + pnt = isl_point_zero(isl_pw_qpolynomial_get_domain_space(pwqp)); + v = isl_val_read_from_str(ctx, "1/2"); + pnt = isl_point_set_coordinate_val(pnt, isl_dim_set, 0, v); + v = isl_pw_qpolynomial_eval(pwqp, pnt); + r = val_check_equal(v, "1/4"); + isl_val_free(v); + + return r; +} + +/* Inputs for isl_pw_aff_eval test. + * "f" is the affine function. + * "p" is the point where the function should be evaluated. + * "res" is the expected result. + */ +struct { + const char *f; + const char *p; + const char *res; +} aff_eval_tests[] = { + { "{ [i] -> [2 * i] }", "{ [4] }", "8" }, + { "{ [i] -> [2 * i] }", "{ [x] : false }", "NaN" }, + { "{ [i] -> [i + floor(i/2) + floor(i/3)] }", "{ [0] }", "0" }, + { "{ [i] -> [i + floor(i/2) + floor(i/3)] }", "{ [1] }", "1" }, + { "{ [i] -> [i + floor(i/2) + floor(i/3)] }", "{ [2] }", "3" }, + { "{ [i] -> [i + floor(i/2) + floor(i/3)] }", "{ [3] }", "5" }, + { "{ [i] -> [i + floor(i/2) + floor(i/3)] }", "{ [4] }", "7" }, + { "{ [i] -> [floor((3 * floor(i/2))/5)] }", "{ [0] }", "0" }, + { "{ [i] -> [floor((3 * floor(i/2))/5)] }", "{ [1] }", "0" }, + { "{ [i] -> [floor((3 * floor(i/2))/5)] }", "{ [2] }", "0" }, + { "{ [i] -> [floor((3 * floor(i/2))/5)] }", "{ [3] }", "0" }, + { "{ [i] -> [floor((3 * floor(i/2))/5)] }", "{ [4] }", "1" }, + { "{ [i] -> [floor((3 * floor(i/2))/5)] }", "{ [6] }", "1" }, + { "{ [i] -> [floor((3 * floor(i/2))/5)] }", "{ [8] }", "2" }, + { "{ [i] -> [i] : i > 0; [i] -> [-i] : i < 0 }", "{ [4] }", "4" }, + { "{ [i] -> [i] : i > 0; [i] -> [-i] : i < 0 }", "{ [-2] }", "2" }, + { "{ [i] -> [i] : i > 0; [i] -> [-i] : i < 0 }", "{ [0] }", "NaN" }, + { "[N] -> { [2 * N] }", "[N] -> { : N = 4 }", "8" }, + { "{ [i, j] -> [(i + j)/2] }", "{ [1, 1] }", "1" }, + { "{ [i, j] -> [(i + j)/2] }", "{ [1, 2] }", "3/2" }, + { "{ [i] -> [i] : i mod 2 = 0 }", "{ [4] }", "4" }, + { "{ [i] -> [i] : i mod 2 = 0 }", "{ [3] }", "NaN" }, + { "{ [i] -> [i] : i mod 2 = 0 }", "{ [x] : false }", "NaN" }, + { "[m, n] -> { [2m + 3n] }", "[n=1, m=10] -> { : }", "23" }, +}; + +/* Perform basic isl_pw_aff_eval tests. + */ +static int test_eval_aff(isl_ctx *ctx) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(aff_eval_tests); ++i) { + isl_stat r; + isl_pw_aff *pa; + isl_set *set; + isl_point *pnt; + isl_val *v; + + pa = isl_pw_aff_read_from_str(ctx, aff_eval_tests[i].f); + set = isl_set_read_from_str(ctx, aff_eval_tests[i].p); + pnt = isl_set_sample_point(set); + v = isl_pw_aff_eval(pa, pnt); + r = val_check_equal(v, aff_eval_tests[i].res); + isl_val_free(v); + if (r < 0) + return -1; + } + return 0; +} + +/* Perform basic evaluation tests. + */ +static int test_eval(isl_ctx *ctx) +{ + if (test_eval_1(ctx) < 0) + return -1; + if (test_eval_2(ctx) < 0) + return -1; + if (test_eval_3(ctx) < 0) + return -1; + if (test_eval_aff(ctx) < 0) + return -1; + return 0; +} + +/* Descriptions of sets that are tested for reparsing after printing. + */ +const char *output_tests[] = { + "{ [1, y] : 0 <= y <= 1; [x, -x] : 0 <= x <= 1 }", + "{ [x] : 1 = 0 }", + "{ [x] : false }", + "{ [x] : x mod 2 = 0 }", + "{ [x] : x mod 2 = 1 }", + "{ [x, y] : x mod 2 = 0 and 3*floor(y/2) < x }", + "{ [y, x] : x mod 2 = 0 and 3*floor(y/2) < x }", + "{ [x, y] : x mod 2 = 0 and 3*floor(y/2) = x + y }", + "{ [y, x] : x mod 2 = 0 and 3*floor(y/2) = x + y }", + "[n] -> { [y, x] : 2*((x + 2y) mod 3) = n }", + "{ [x, y] : (2*floor(x/3) + 3*floor(y/4)) mod 5 = x }", +}; + +/* Check that printing a set and reparsing a set from the printed output + * results in the same set. + */ +static int test_output_set(isl_ctx *ctx) +{ + int i; + char *str; + isl_set *set1, *set2; + isl_bool equal; + + for (i = 0; i < ARRAY_SIZE(output_tests); ++i) { + set1 = isl_set_read_from_str(ctx, output_tests[i]); + str = isl_set_to_str(set1); + set2 = isl_set_read_from_str(ctx, str); + free(str); + equal = isl_set_is_equal(set1, set2); + isl_set_free(set1); + isl_set_free(set2); + if (equal < 0) + return -1; + if (!equal) + isl_die(ctx, isl_error_unknown, + "parsed output not the same", return -1); + } + + return 0; +} + +/* Check that an isl_multi_aff is printed using a consistent space. + */ +static isl_stat test_output_ma(isl_ctx *ctx) +{ + char *str; + isl_bool equal; + isl_aff *aff; + isl_multi_aff *ma, *ma2; + + ma = isl_multi_aff_read_from_str(ctx, "{ [a, b] -> [a + b] }"); + aff = isl_aff_read_from_str(ctx, "{ [c, d] -> [c + d] }"); + ma = isl_multi_aff_set_aff(ma, 0, aff); + str = isl_multi_aff_to_str(ma); + ma2 = isl_multi_aff_read_from_str(ctx, str); + free(str); + equal = isl_multi_aff_plain_is_equal(ma, ma2); + isl_multi_aff_free(ma2); + isl_multi_aff_free(ma); + + if (equal < 0) + return isl_stat_error; + if (!equal) + isl_die(ctx, isl_error_unknown, "bad conversion", + return isl_stat_error); + + return isl_stat_ok; +} + +/* Check that an isl_multi_pw_aff is printed using a consistent space. + */ +static isl_stat test_output_mpa(isl_ctx *ctx) +{ + char *str; + isl_bool equal; + isl_pw_aff *pa; + isl_multi_pw_aff *mpa, *mpa2; + + mpa = isl_multi_pw_aff_read_from_str(ctx, "{ [a, b] -> [a + b] }"); + pa = isl_pw_aff_read_from_str(ctx, "{ [c, d] -> [c + d] }"); + mpa = isl_multi_pw_aff_set_pw_aff(mpa, 0, pa); + str = isl_multi_pw_aff_to_str(mpa); + mpa2 = isl_multi_pw_aff_read_from_str(ctx, str); + free(str); + equal = isl_multi_pw_aff_plain_is_equal(mpa, mpa2); + isl_multi_pw_aff_free(mpa2); + isl_multi_pw_aff_free(mpa); + + if (equal < 0) + return isl_stat_error; + if (!equal) + isl_die(ctx, isl_error_unknown, "bad conversion", + return isl_stat_error); + + return isl_stat_ok; +} + +int test_output(isl_ctx *ctx) +{ + char *s; + const char *str; + isl_pw_aff *pa; + isl_printer *p; + int equal; + + if (test_output_set(ctx) < 0) + return -1; + if (test_output_ma(ctx) < 0) + return -1; + if (test_output_mpa(ctx) < 0) + return -1; + + str = "[x] -> { [1] : x % 4 <= 2; [2] : x = 3 }"; + pa = isl_pw_aff_read_from_str(ctx, str); + + p = isl_printer_to_str(ctx); + p = isl_printer_set_output_format(p, ISL_FORMAT_C); + p = isl_printer_print_pw_aff(p, pa); + s = isl_printer_get_str(p); + isl_printer_free(p); + isl_pw_aff_free(pa); + if (!s) + equal = -1; + else + equal = !strcmp(s, "4 * floord(x, 4) + 2 >= x ? 1 : 2"); + free(s); + if (equal < 0) + return -1; + if (!equal) + isl_die(ctx, isl_error_unknown, "unexpected result", return -1); + + return 0; +} + +int test_sample(isl_ctx *ctx) +{ + const char *str; + isl_basic_set *bset1, *bset2; + int empty, subset; + + str = "{ [a, b, c, d, e, f, g, h, i, j, k] : " + "3i >= 1073741823b - c - 1073741823e + f and c >= 0 and " + "3i >= -1 + 3221225466b + c + d - 3221225466e - f and " + "2e >= a - b and 3e <= 2a and 3k <= -a and f <= -1 + a and " + "3i <= 4 - a + 4b + 2c - e - 2f and 3k <= -a + c - f and " + "3h >= -2 + a and 3g >= -3 - a and 3k >= -2 - a and " + "3i >= -2 - a - 2c + 3e + 2f and 3h <= a + c - f and " + "3h >= a + 2147483646b + 2c - 2147483646e - 2f and " + "3g <= -1 - a and 3i <= 1 + c + d - f and a <= 1073741823 and " + "f >= 1 - a + 1073741822b + c + d - 1073741822e and " + "3i >= 1 + 2b - 2c + e + 2f + 3g and " + "1073741822f <= 1073741822 - a + 1073741821b + 1073741822c +" + "d - 1073741821e and " + "3j <= 3 - a + 3b and 3g <= -2 - 2b + c + d - e - f and " + "3j >= 1 - a + b + 2e and " + "3f >= -3 + a + 3221225462b + 3c + d - 3221225465e and " + "3i <= 4 - a + 4b - e and " + "f <= 1073741822 + 1073741822b - 1073741822e and 3h <= a and " + "f >= 0 and 2e <= 4 - a + 5b - d and 2e <= a - b + d and " + "c <= -1 + a and 3i >= -2 - a + 3e and " + "1073741822e <= 1073741823 - a + 1073741822b + c and " + "3g >= -4 + 3221225464b + 3c + d - 3221225467e - 3f and " + "3i >= -1 + 3221225466b + 3c + d - 3221225466e - 3f and " + "1073741823e >= 1 + 1073741823b - d and " + "3i >= 1073741823b + c - 1073741823e - f and " + "3i >= 1 + 2b + e + 3g }"; + bset1 = isl_basic_set_read_from_str(ctx, str); + bset2 = isl_basic_set_sample(isl_basic_set_copy(bset1)); + empty = isl_basic_set_is_empty(bset2); + subset = isl_basic_set_is_subset(bset2, bset1); + isl_basic_set_free(bset1); + isl_basic_set_free(bset2); + if (empty < 0 || subset < 0) + return -1; + if (empty) + isl_die(ctx, isl_error_unknown, "point not found", return -1); + if (!subset) + isl_die(ctx, isl_error_unknown, "bad point found", return -1); + + return 0; +} + +/* Perform a projection on a basic set that is known to be empty + * but that has not been assigned a canonical representation. + * Earlier versions of isl would run into a stack overflow + * on this example. + */ +static int test_empty_projection(isl_ctx *ctx) +{ + const char *str; + isl_bool empty; + isl_basic_set *bset; + + str = "{ [a, b, c, d, e, f, g, h] : 5f = 1 + 4a - b + 5c - d - 2e and " + "3h = 2 + b + c and 14c >= 9 - 3a + 25b and " + "4c <= 50 - 3a + 23b and 6b <= -39 + a and " + "9g >= -6 + 3a + b + c and e < a + b - 2d and " + "7d >= -5 + 2a + 2b and 5g >= -14 + a - 4b + d + 2e and " + "9g <= -28 - 5b - 2c + 3d + 6e }"; + bset = isl_basic_set_read_from_str(ctx, str); + empty = isl_basic_set_is_empty(bset); + bset = isl_basic_set_params(bset); + isl_basic_set_free(bset); + + if (empty < 0) + return -1; + + return 0; +} + +int test_slice(isl_ctx *ctx) +{ + const char *str; + isl_map *map; + int equal; + + str = "{ [i] -> [j] }"; + map = isl_map_read_from_str(ctx, str); + map = isl_map_equate(map, isl_dim_in, 0, isl_dim_out, 0); + equal = map_check_equal(map, "{ [i] -> [i] }"); + isl_map_free(map); + if (equal < 0) + return -1; + + str = "{ [i] -> [j] }"; + map = isl_map_read_from_str(ctx, str); + map = isl_map_equate(map, isl_dim_in, 0, isl_dim_in, 0); + equal = map_check_equal(map, "{ [i] -> [j] }"); + isl_map_free(map); + if (equal < 0) + return -1; + + str = "{ [i] -> [j] }"; + map = isl_map_read_from_str(ctx, str); + map = isl_map_oppose(map, isl_dim_in, 0, isl_dim_out, 0); + equal = map_check_equal(map, "{ [i] -> [-i] }"); + isl_map_free(map); + if (equal < 0) + return -1; + + str = "{ [i] -> [j] }"; + map = isl_map_read_from_str(ctx, str); + map = isl_map_oppose(map, isl_dim_in, 0, isl_dim_in, 0); + equal = map_check_equal(map, "{ [0] -> [j] }"); + isl_map_free(map); + if (equal < 0) + return -1; + + str = "{ [i] -> [j] }"; + map = isl_map_read_from_str(ctx, str); + map = isl_map_order_gt(map, isl_dim_in, 0, isl_dim_out, 0); + equal = map_check_equal(map, "{ [i] -> [j] : i > j }"); + isl_map_free(map); + if (equal < 0) + return -1; + + str = "{ [i] -> [j] }"; + map = isl_map_read_from_str(ctx, str); + map = isl_map_order_gt(map, isl_dim_in, 0, isl_dim_in, 0); + equal = map_check_equal(map, "{ [i] -> [j] : false }"); + isl_map_free(map); + if (equal < 0) + return -1; + + return 0; +} + +int test_eliminate(isl_ctx *ctx) +{ + const char *str; + isl_map *map; + int equal; + + str = "{ [i] -> [j] : i = 2j }"; + map = isl_map_read_from_str(ctx, str); + map = isl_map_eliminate(map, isl_dim_out, 0, 1); + equal = map_check_equal(map, "{ [i] -> [j] : exists a : i = 2a }"); + isl_map_free(map); + if (equal < 0) + return -1; + + return 0; +} + +/* Check basic functionality of isl_map_deltas_map. + */ +static int test_deltas_map(isl_ctx *ctx) +{ + const char *str; + isl_map *map; + int equal; + + str = "{ A[i] -> A[i + 1] }"; + map = isl_map_read_from_str(ctx, str); + map = isl_map_deltas_map(map); + equal = map_check_equal(map, "{ [A[i] -> A[i + 1]] -> A[1] }"); + isl_map_free(map); + if (equal < 0) + return -1; + + return 0; +} + +/* Check that isl_set_dim_residue_class detects that the values of j + * in the set below are all odd and that it does not detect any spurious + * strides. + */ +static int test_residue_class(isl_ctx *ctx) +{ + const char *str; + isl_set *set; + isl_int m, r; + isl_stat res; + + str = "{ [i,j] : j = 4 i + 1 and 0 <= i <= 100; " + "[i,j] : j = 4 i + 3 and 500 <= i <= 600 }"; + set = isl_set_read_from_str(ctx, str); + isl_int_init(m); + isl_int_init(r); + res = isl_set_dim_residue_class(set, 1, &m, &r); + if (res >= 0 && + (isl_int_cmp_si(m, 2) != 0 || isl_int_cmp_si(r, 1) != 0)) + isl_die(ctx, isl_error_unknown, "incorrect residue class", + res = isl_stat_error); + isl_int_clear(r); + isl_int_clear(m); + isl_set_free(set); + + return res; +} + +static int test_align_parameters_1(isl_ctx *ctx) +{ + const char *str; + isl_space *space; + isl_multi_aff *ma1, *ma2; + int equal; + + str = "{ A[B[] -> C[]] -> D[E[] -> F[]] }"; + ma1 = isl_multi_aff_read_from_str(ctx, str); + + space = isl_space_params_alloc(ctx, 1); + space = isl_space_set_dim_name(space, isl_dim_param, 0, "N"); + ma1 = isl_multi_aff_align_params(ma1, space); + + str = "[N] -> { A[B[] -> C[]] -> D[E[] -> F[]] }"; + ma2 = isl_multi_aff_read_from_str(ctx, str); + + equal = isl_multi_aff_plain_is_equal(ma1, ma2); + + isl_multi_aff_free(ma1); + isl_multi_aff_free(ma2); + + if (equal < 0) + return -1; + if (!equal) + isl_die(ctx, isl_error_unknown, + "result not as expected", return -1); + + return 0; +} + +/* Check the isl_multi_*_from_*_list operation in case inputs + * have unaligned parameters. + * In particular, older versions of isl would simply fail + * (without printing any error message). + */ +static isl_stat test_align_parameters_2(isl_ctx *ctx) +{ + isl_space *space; + isl_map *map; + isl_aff *aff; + isl_multi_aff *ma; + + map = isl_map_read_from_str(ctx, "{ A[] -> M[x] }"); + space = isl_map_get_space(map); + isl_map_free(map); + + aff = isl_aff_read_from_str(ctx, "[N] -> { A[] -> [N] }"); + ma = isl_multi_aff_from_aff_list(space, isl_aff_list_from_aff(aff)); + isl_multi_aff_free(ma); + + if (!ma) + return isl_stat_error; + return isl_stat_ok; +} + +/* Perform basic parameter alignment tests. + */ +static int test_align_parameters(isl_ctx *ctx) +{ + if (test_align_parameters_1(ctx) < 0) + return -1; + if (test_align_parameters_2(ctx) < 0) + return -1; + + return 0; +} + +/* Check that isl_*_drop_unused_params actually drops the unused parameters + * by comparing the result using isl_*_plain_is_equal. + * Note that this assumes that isl_*_plain_is_equal does not consider + * objects that only differ by unused parameters to be equal. + */ +int test_drop_unused_parameters(isl_ctx *ctx) +{ + const char *str_with, *str_without; + isl_basic_set *bset1, *bset2; + isl_set *set1, *set2; + isl_pw_aff *pwa1, *pwa2; + int equal; + + str_with = "[n, m, o] -> { [m] }"; + str_without = "[m] -> { [m] }"; + + bset1 = isl_basic_set_read_from_str(ctx, str_with); + bset2 = isl_basic_set_read_from_str(ctx, str_without); + bset1 = isl_basic_set_drop_unused_params(bset1); + equal = isl_basic_set_plain_is_equal(bset1, bset2); + isl_basic_set_free(bset1); + isl_basic_set_free(bset2); + + if (equal < 0) + return -1; + if (!equal) + isl_die(ctx, isl_error_unknown, + "result not as expected", return -1); + + set1 = isl_set_read_from_str(ctx, str_with); + set2 = isl_set_read_from_str(ctx, str_without); + set1 = isl_set_drop_unused_params(set1); + equal = isl_set_plain_is_equal(set1, set2); + isl_set_free(set1); + isl_set_free(set2); + + if (equal < 0) + return -1; + if (!equal) + isl_die(ctx, isl_error_unknown, + "result not as expected", return -1); + + pwa1 = isl_pw_aff_read_from_str(ctx, str_with); + pwa2 = isl_pw_aff_read_from_str(ctx, str_without); + pwa1 = isl_pw_aff_drop_unused_params(pwa1); + equal = isl_pw_aff_plain_is_equal(pwa1, pwa2); + isl_pw_aff_free(pwa1); + isl_pw_aff_free(pwa2); + + if (equal < 0) + return -1; + if (!equal) + isl_die(ctx, isl_error_unknown, + "result not as expected", return -1); + + return 0; +} + +static int test_list(isl_ctx *ctx) +{ + isl_id *a, *b, *c, *d, *id; + isl_id_list *list; + isl_size n; + int ok; + + a = isl_id_alloc(ctx, "a", NULL); + b = isl_id_alloc(ctx, "b", NULL); + c = isl_id_alloc(ctx, "c", NULL); + d = isl_id_alloc(ctx, "d", NULL); + + list = isl_id_list_alloc(ctx, 4); + list = isl_id_list_add(list, b); + list = isl_id_list_insert(list, 0, a); + list = isl_id_list_add(list, c); + list = isl_id_list_add(list, d); + list = isl_id_list_drop(list, 1, 1); + + n = isl_id_list_n_id(list); + if (n < 0) + return -1; + if (n != 3) { + isl_id_list_free(list); + isl_die(ctx, isl_error_unknown, + "unexpected number of elements in list", return -1); + } + + id = isl_id_list_get_id(list, 0); + ok = id == a; + isl_id_free(id); + id = isl_id_list_get_id(list, 1); + ok = ok && id == c; + isl_id_free(id); + id = isl_id_list_get_id(list, 2); + ok = ok && id == d; + isl_id_free(id); + + isl_id_list_free(list); + + if (!ok) + isl_die(ctx, isl_error_unknown, + "unexpected elements in list", return -1); + + return 0; +} + +/* Check the conversion from an isl_multi_aff to an isl_basic_set. + */ +static isl_stat test_ma_conversion(isl_ctx *ctx) +{ + const char *str; + isl_bool equal; + isl_multi_aff *ma; + isl_basic_set *bset1, *bset2; + + str = "[N] -> { A[0, N + 1] }"; + ma = isl_multi_aff_read_from_str(ctx, str); + bset1 = isl_basic_set_read_from_str(ctx, str); + bset2 = isl_basic_set_from_multi_aff(ma); + equal = isl_basic_set_is_equal(bset1, bset2); + isl_basic_set_free(bset1); + isl_basic_set_free(bset2); + if (equal < 0) + return isl_stat_error; + if (!equal) + isl_die(ctx, isl_error_unknown, "bad conversion", + return isl_stat_error); + return isl_stat_ok; +} + +const char *set_conversion_tests[] = { + "[N] -> { [i] : N - 1 <= 2 i <= N }", + "[N] -> { [i] : exists a : i = 4 a and N - 1 <= i <= N }", + "[N] -> { [i,j] : exists a : i = 4 a and N - 1 <= i, 2j <= N }", + "[N] -> { [[i]->[j]] : exists a : i = 4 a and N - 1 <= i, 2j <= N }", + "[N] -> { [3*floor(N/2) + 5*floor(N/3)] }", + "[a, b] -> { [c, d] : (4*floor((-a + c)/4) = -a + c and " + "32*floor((-b + d)/32) = -b + d and 5 <= c <= 8 and " + "-3 + c <= d <= 28 + c) }", +}; + +/* Check that converting from isl_set to isl_pw_multi_aff and back + * to isl_set produces the original isl_set. + */ +static int test_set_conversion(isl_ctx *ctx) +{ + int i; + const char *str; + isl_set *set1, *set2; + isl_pw_multi_aff *pma; + int equal; + + for (i = 0; i < ARRAY_SIZE(set_conversion_tests); ++i) { + str = set_conversion_tests[i]; + set1 = isl_set_read_from_str(ctx, str); + pma = isl_pw_multi_aff_from_set(isl_set_copy(set1)); + set2 = isl_set_from_pw_multi_aff(pma); + equal = isl_set_is_equal(set1, set2); + isl_set_free(set1); + isl_set_free(set2); + + if (equal < 0) + return -1; + if (!equal) + isl_die(ctx, isl_error_unknown, "bad conversion", + return -1); + } + + return 0; +} + +const char *conversion_tests[] = { + "{ [a, b, c, d] -> s0[a, b, e, f] : " + "exists (e0 = [(a - 2c)/3], e1 = [(-4 + b - 5d)/9], " + "e2 = [(-d + f)/9]: 3e0 = a - 2c and 9e1 = -4 + b - 5d and " + "9e2 = -d + f and f >= 0 and f <= 8 and 9e >= -5 - 2a and " + "9e <= -2 - 2a) }", + "{ [a, b] -> [c] : exists (e0 = floor((-a - b + c)/5): " + "5e0 = -a - b + c and c >= -a and c <= 4 - a) }", + "{ [a, b] -> [c] : exists d : 18 * d = -3 - a + 2c and 1 <= c <= 3 }", +}; + +/* Check that converting from isl_map to isl_pw_multi_aff and back + * to isl_map produces the original isl_map. + */ +static int test_map_conversion(isl_ctx *ctx) +{ + int i; + isl_map *map1, *map2; + isl_pw_multi_aff *pma; + int equal; + + for (i = 0; i < ARRAY_SIZE(conversion_tests); ++i) { + map1 = isl_map_read_from_str(ctx, conversion_tests[i]); + pma = isl_pw_multi_aff_from_map(isl_map_copy(map1)); + map2 = isl_map_from_pw_multi_aff(pma); + equal = isl_map_is_equal(map1, map2); + isl_map_free(map1); + isl_map_free(map2); + + if (equal < 0) + return -1; + if (!equal) + isl_die(ctx, isl_error_unknown, "bad conversion", + return -1); + } + + return 0; +} + +/* Descriptions of isl_pw_multi_aff objects for testing conversion + * to isl_multi_pw_aff and back. + */ +const char *mpa_conversion_tests[] = { + "{ [x] -> A[x] }", + "{ [x] -> A[x] : x >= 0 }", + "{ [x] -> A[x] : x >= 0; [x] -> A[-x] : x < 0 }", + "{ [x] -> A[x, x + 1] }", + "{ [x] -> A[] }", + "{ [x] -> A[] : x >= 0 }", +}; + +/* Check that conversion from isl_pw_multi_aff to isl_multi_pw_aff and + * back to isl_pw_multi_aff preserves the original meaning. + */ +static int test_mpa_conversion(isl_ctx *ctx) +{ + int i; + isl_pw_multi_aff *pma1, *pma2; + isl_multi_pw_aff *mpa; + int equal; + + for (i = 0; i < ARRAY_SIZE(mpa_conversion_tests); ++i) { + const char *str; + str = mpa_conversion_tests[i]; + pma1 = isl_pw_multi_aff_read_from_str(ctx, str); + pma2 = isl_pw_multi_aff_copy(pma1); + mpa = isl_multi_pw_aff_from_pw_multi_aff(pma1); + pma1 = isl_pw_multi_aff_from_multi_pw_aff(mpa); + equal = isl_pw_multi_aff_plain_is_equal(pma1, pma2); + isl_pw_multi_aff_free(pma1); + isl_pw_multi_aff_free(pma2); + + if (equal < 0) + return -1; + if (!equal) + isl_die(ctx, isl_error_unknown, "bad conversion", + return -1); + } + + return 0; +} + +/* Descriptions of union maps that should be convertible + * to an isl_multi_union_pw_aff. + */ +const char *umap_mupa_conversion_tests[] = { + "{ [a, b, c, d] -> s0[a, b, e, f] : " + "exists (e0 = [(a - 2c)/3], e1 = [(-4 + b - 5d)/9], " + "e2 = [(-d + f)/9]: 3e0 = a - 2c and 9e1 = -4 + b - 5d and " + "9e2 = -d + f and f >= 0 and f <= 8 and 9e >= -5 - 2a and " + "9e <= -2 - 2a) }", + "{ [a, b] -> [c] : exists (e0 = floor((-a - b + c)/5): " + "5e0 = -a - b + c and c >= -a and c <= 4 - a) }", + "{ [a, b] -> [c] : exists d : 18 * d = -3 - a + 2c and 1 <= c <= 3 }", + "{ A[] -> B[0]; C[] -> B[1] }", + "{ A[] -> B[]; C[] -> B[] }", +}; + +/* Check that converting from isl_union_map to isl_multi_union_pw_aff and back + * to isl_union_map produces the original isl_union_map. + */ +static int test_union_map_mupa_conversion(isl_ctx *ctx) +{ + int i; + isl_union_map *umap1, *umap2; + isl_multi_union_pw_aff *mupa; + int equal; + + for (i = 0; i < ARRAY_SIZE(umap_mupa_conversion_tests); ++i) { + const char *str; + str = umap_mupa_conversion_tests[i]; + umap1 = isl_union_map_read_from_str(ctx, str); + umap2 = isl_union_map_copy(umap1); + mupa = isl_multi_union_pw_aff_from_union_map(umap2); + umap2 = isl_union_map_from_multi_union_pw_aff(mupa); + equal = isl_union_map_is_equal(umap1, umap2); + isl_union_map_free(umap1); + isl_union_map_free(umap2); + + if (equal < 0) + return -1; + if (!equal) + isl_die(ctx, isl_error_unknown, "bad conversion", + return -1); + } + + return 0; +} + +static int test_conversion(isl_ctx *ctx) +{ + if (test_ma_conversion(ctx) < 0) + return -1; + if (test_set_conversion(ctx) < 0) + return -1; + if (test_map_conversion(ctx) < 0) + return -1; + if (test_mpa_conversion(ctx) < 0) + return -1; + if (test_union_map_mupa_conversion(ctx) < 0) + return -1; + return 0; +} + +/* Check that isl_basic_map_curry does not modify input. + */ +static int test_curry(isl_ctx *ctx) +{ + const char *str; + isl_basic_map *bmap1, *bmap2; + int equal; + + str = "{ [A[] -> B[]] -> C[] }"; + bmap1 = isl_basic_map_read_from_str(ctx, str); + bmap2 = isl_basic_map_curry(isl_basic_map_copy(bmap1)); + equal = isl_basic_map_is_equal(bmap1, bmap2); + isl_basic_map_free(bmap1); + isl_basic_map_free(bmap2); + + if (equal < 0) + return -1; + if (equal) + isl_die(ctx, isl_error_unknown, + "curried map should not be equal to original", + return -1); + + return 0; +} + +struct { + const char *ma1; + const char *ma; + const char *res; +} pullback_tests[] = { + { "{ B[i,j] -> C[i + 2j] }" , "{ A[a,b] -> B[b,a] }", + "{ A[a,b] -> C[b + 2a] }" }, + { "{ B[i] -> C[2i] }", "{ A[a] -> B[(a)/2] }", "{ A[a] -> C[a] }" }, + { "{ B[i] -> C[(i)/2] }", "{ A[a] -> B[2a] }", "{ A[a] -> C[a] }" }, + { "{ B[i] -> C[(i)/2] }", "{ A[a] -> B[(a)/3] }", + "{ A[a] -> C[(a)/6] }" }, + { "{ B[i] -> C[2i] }", "{ A[a] -> B[5a] }", "{ A[a] -> C[10a] }" }, + { "{ B[i] -> C[2i] }", "{ A[a] -> B[(a)/3] }", + "{ A[a] -> C[(2a)/3] }" }, + { "{ B[i,j] -> C[i + j] }", "{ A[a] -> B[a,a] }", "{ A[a] -> C[2a] }"}, + { "{ B[a] -> C[a,a] }", "{ A[i,j] -> B[i + j] }", + "{ A[i,j] -> C[i + j, i + j] }"}, + { "{ B[i] -> C[([i/2])] }", "{ B[5] }", "{ C[2] }" }, + { "[n] -> { B[i,j] -> C[([i/2]) + 2j] }", + "[n] -> { B[n,[n/3]] }", "[n] -> { C[([n/2]) + 2*[n/3]] }", }, + { "{ [i, j] -> [floor((i)/4) + floor((2*i+j)/5)] }", + "{ [i, j] -> [floor((i)/3), j] }", + "{ [i, j] -> [(floor((i)/12) + floor((j + 2*floor((i)/3))/5))] }" }, +}; + +static int test_pullback(isl_ctx *ctx) +{ + int i; + isl_multi_aff *ma1, *ma2; + isl_multi_aff *ma; + int equal; + + for (i = 0; i < ARRAY_SIZE(pullback_tests); ++i) { + ma1 = isl_multi_aff_read_from_str(ctx, pullback_tests[i].ma1); + ma = isl_multi_aff_read_from_str(ctx, pullback_tests[i].ma); + ma2 = isl_multi_aff_read_from_str(ctx, pullback_tests[i].res); + ma1 = isl_multi_aff_pullback_multi_aff(ma1, ma); + equal = isl_multi_aff_plain_is_equal(ma1, ma2); + isl_multi_aff_free(ma1); + isl_multi_aff_free(ma2); + if (equal < 0) + return -1; + if (!equal) + isl_die(ctx, isl_error_unknown, "bad pullback", + return -1); + } + + return 0; +} + +/* Check that negation is printed correctly and that equal expressions + * are correctly identified. + */ +static int test_ast(isl_ctx *ctx) +{ + isl_ast_expr *expr, *expr1, *expr2, *expr3; + char *str; + int ok, equal; + + expr1 = isl_ast_expr_from_id(isl_id_alloc(ctx, "A", NULL)); + expr2 = isl_ast_expr_from_id(isl_id_alloc(ctx, "B", NULL)); + expr = isl_ast_expr_add(expr1, expr2); + expr2 = isl_ast_expr_copy(expr); + expr = isl_ast_expr_neg(expr); + expr2 = isl_ast_expr_neg(expr2); + equal = isl_ast_expr_is_equal(expr, expr2); + str = isl_ast_expr_to_C_str(expr); + ok = str ? !strcmp(str, "-(A + B)") : -1; + free(str); + isl_ast_expr_free(expr); + isl_ast_expr_free(expr2); + + if (ok < 0 || equal < 0) + return -1; + if (!equal) + isl_die(ctx, isl_error_unknown, + "equal expressions not considered equal", return -1); + if (!ok) + isl_die(ctx, isl_error_unknown, + "isl_ast_expr printed incorrectly", return -1); + + expr1 = isl_ast_expr_from_id(isl_id_alloc(ctx, "A", NULL)); + expr2 = isl_ast_expr_from_id(isl_id_alloc(ctx, "B", NULL)); + expr = isl_ast_expr_add(expr1, expr2); + expr3 = isl_ast_expr_from_id(isl_id_alloc(ctx, "C", NULL)); + expr = isl_ast_expr_sub(expr3, expr); + str = isl_ast_expr_to_C_str(expr); + ok = str ? !strcmp(str, "C - (A + B)") : -1; + free(str); + isl_ast_expr_free(expr); + + if (ok < 0) + return -1; + if (!ok) + isl_die(ctx, isl_error_unknown, + "isl_ast_expr printed incorrectly", return -1); + + return 0; +} + +/* Check that isl_ast_build_expr_from_set returns a valid expression + * for an empty set. Note that isl_ast_build_expr_from_set getting + * called on an empty set probably indicates a bug in the caller. + */ +static int test_ast_build(isl_ctx *ctx) +{ + isl_set *set; + isl_ast_build *build; + isl_ast_expr *expr; + + set = isl_set_universe(isl_space_params_alloc(ctx, 0)); + build = isl_ast_build_from_context(set); + + set = isl_set_empty(isl_space_params_alloc(ctx, 0)); + expr = isl_ast_build_expr_from_set(build, set); + + isl_ast_expr_free(expr); + isl_ast_build_free(build); + + if (!expr) + return -1; + + return 0; +} + +/* Internal data structure for before_for and after_for callbacks. + * + * depth is the current depth + * before is the number of times before_for has been called + * after is the number of times after_for has been called + */ +struct isl_test_codegen_data { + int depth; + int before; + int after; +}; + +/* This function is called before each for loop in the AST generated + * from test_ast_gen1. + * + * Increment the number of calls and the depth. + * Check that the space returned by isl_ast_build_get_schedule_space + * matches the target space of the schedule returned by + * isl_ast_build_get_schedule. + * Return an isl_id that is checked by the corresponding call + * to after_for. + */ +static __isl_give isl_id *before_for(__isl_keep isl_ast_build *build, + void *user) +{ + struct isl_test_codegen_data *data = user; + isl_ctx *ctx; + isl_space *space; + isl_union_map *schedule; + isl_union_set *uset; + isl_set *set; + isl_bool empty; + isl_size n; + char name[] = "d0"; + + ctx = isl_ast_build_get_ctx(build); + + if (data->before >= 3) + isl_die(ctx, isl_error_unknown, + "unexpected number of for nodes", return NULL); + if (data->depth < 0 || data->depth >= 2) + isl_die(ctx, isl_error_unknown, + "unexpected depth", return NULL); + + snprintf(name, sizeof(name), "d%d", data->depth); + data->before++; + data->depth++; + + schedule = isl_ast_build_get_schedule(build); + uset = isl_union_map_range(schedule); + n = isl_union_set_n_set(uset); + if (n != 1) { + isl_union_set_free(uset); + if (n < 0) + return NULL; + isl_die(ctx, isl_error_unknown, + "expecting single range space", return NULL); + } + + space = isl_ast_build_get_schedule_space(build); + set = isl_union_set_extract_set(uset, space); + isl_union_set_free(uset); + empty = isl_set_is_empty(set); + isl_set_free(set); + + if (empty < 0) + return NULL; + if (empty) + isl_die(ctx, isl_error_unknown, + "spaces don't match", return NULL); + + return isl_id_alloc(ctx, name, NULL); +} + +/* This function is called after each for loop in the AST generated + * from test_ast_gen1. + * + * Increment the number of calls and decrement the depth. + * Check that the annotation attached to the node matches + * the isl_id returned by the corresponding call to before_for. + */ +static __isl_give isl_ast_node *after_for(__isl_take isl_ast_node *node, + __isl_keep isl_ast_build *build, void *user) +{ + struct isl_test_codegen_data *data = user; + isl_id *id; + const char *name; + int valid; + + data->after++; + data->depth--; + + if (data->after > data->before) + isl_die(isl_ast_node_get_ctx(node), isl_error_unknown, + "mismatch in number of for nodes", + return isl_ast_node_free(node)); + + id = isl_ast_node_get_annotation(node); + if (!id) + isl_die(isl_ast_node_get_ctx(node), isl_error_unknown, + "missing annotation", return isl_ast_node_free(node)); + + name = isl_id_get_name(id); + valid = name && atoi(name + 1) == data->depth; + isl_id_free(id); + + if (!valid) + isl_die(isl_ast_node_get_ctx(node), isl_error_unknown, + "wrong annotation", return isl_ast_node_free(node)); + + return node; +} + +/* This function is called after node in the AST generated + * from test_ast_gen1. + * + * Increment the count in "user" if this is a for node and + * return true to indicate that descendant should also be visited. + */ +static isl_bool count_for(__isl_keep isl_ast_node *node, void *user) +{ + int *count = user; + + if (isl_ast_node_get_type(node) == isl_ast_node_for) + ++*count; + + return isl_bool_true; +} + +/* If "node" is a block node, then replace it by its first child. + */ +static __isl_give isl_ast_node *select_first(__isl_take isl_ast_node *node, + void *user) +{ + isl_ast_node_list *children; + isl_ast_node *child; + + if (isl_ast_node_get_type(node) != isl_ast_node_block) + return node; + + children = isl_ast_node_block_get_children(node); + child = isl_ast_node_list_get_at(children, 0); + isl_ast_node_list_free(children); + isl_ast_node_free(node); + + return child; +} + +/* Check that the before_each_for and after_each_for callbacks + * are called for each for loop in the generated code, + * that they are called in the right order and that the isl_id + * returned from the before_each_for callback is attached to + * the isl_ast_node passed to the corresponding after_each_for call. + * + * Additionally, check the basic functionality of + * isl_ast_node_foreach_descendant_top_down by counting the number + * of for loops in the resulting AST, + * as well as that of isl_ast_node_map_descendant_bottom_up + * by replacing the block node by its first child and + * counting the number of for loops again. + */ +static isl_stat test_ast_gen1(isl_ctx *ctx) +{ + int count = 0; + int modified_count = 0; + const char *str; + isl_set *set; + isl_union_map *schedule; + isl_ast_build *build; + isl_ast_node *tree; + struct isl_test_codegen_data data; + + str = "[N] -> { : N >= 10 }"; + set = isl_set_read_from_str(ctx, str); + str = "[N] -> { A[i,j] -> S[8,i,3,j] : 0 <= i,j <= N; " + "B[i,j] -> S[8,j,9,i] : 0 <= i,j <= N }"; + schedule = isl_union_map_read_from_str(ctx, str); + + data.before = 0; + data.after = 0; + data.depth = 0; + build = isl_ast_build_from_context(set); + build = isl_ast_build_set_before_each_for(build, + &before_for, &data); + build = isl_ast_build_set_after_each_for(build, + &after_for, &data); + tree = isl_ast_build_node_from_schedule_map(build, schedule); + isl_ast_build_free(build); + + if (isl_ast_node_foreach_descendant_top_down(tree, + &count_for, &count) < 0) + tree = isl_ast_node_free(tree); + + tree = isl_ast_node_map_descendant_bottom_up(tree, &select_first, NULL); + + if (isl_ast_node_foreach_descendant_top_down(tree, &count_for, + &modified_count) < 0) + tree = isl_ast_node_free(tree); + + if (!tree) + return isl_stat_error; + + isl_ast_node_free(tree); + + if (data.before != 3 || data.after != 3 || count != 3) + isl_die(ctx, isl_error_unknown, + "unexpected number of for nodes", + return isl_stat_error); + + if (modified_count != 2) + isl_die(ctx, isl_error_unknown, + "unexpected number of for nodes after changes", + return isl_stat_error); + + return isl_stat_ok; +} + +/* Check that the AST generator handles domains that are integrally disjoint + * but not rationally disjoint. + */ +static int test_ast_gen2(isl_ctx *ctx) +{ + const char *str; + isl_set *set; + isl_union_map *schedule; + isl_union_map *options; + isl_ast_build *build; + isl_ast_node *tree; + + str = "{ A[i,j] -> [i,j] : 0 <= i,j <= 1 }"; + schedule = isl_union_map_read_from_str(ctx, str); + set = isl_set_universe(isl_space_params_alloc(ctx, 0)); + build = isl_ast_build_from_context(set); + + str = "{ [i,j] -> atomic[1] : i + j = 1; [i,j] -> unroll[1] : i = j }"; + options = isl_union_map_read_from_str(ctx, str); + build = isl_ast_build_set_options(build, options); + tree = isl_ast_build_node_from_schedule_map(build, schedule); + isl_ast_build_free(build); + if (!tree) + return -1; + isl_ast_node_free(tree); + + return 0; +} + +/* Increment *user on each call. + */ +static __isl_give isl_ast_node *count_domains(__isl_take isl_ast_node *node, + __isl_keep isl_ast_build *build, void *user) +{ + int *n = user; + + (*n)++; + + return node; +} + +/* Test that unrolling tries to minimize the number of instances. + * In particular, for the schedule given below, make sure it generates + * 3 nodes (rather than 101). + */ +static int test_ast_gen3(isl_ctx *ctx) +{ + const char *str; + isl_set *set; + isl_union_map *schedule; + isl_union_map *options; + isl_ast_build *build; + isl_ast_node *tree; + int n_domain = 0; + + str = "[n] -> { A[i] -> [i] : 0 <= i <= 100 and n <= i <= n + 2 }"; + schedule = isl_union_map_read_from_str(ctx, str); + set = isl_set_universe(isl_space_params_alloc(ctx, 0)); + + str = "{ [i] -> unroll[0] }"; + options = isl_union_map_read_from_str(ctx, str); + + build = isl_ast_build_from_context(set); + build = isl_ast_build_set_options(build, options); + build = isl_ast_build_set_at_each_domain(build, + &count_domains, &n_domain); + tree = isl_ast_build_node_from_schedule_map(build, schedule); + isl_ast_build_free(build); + if (!tree) + return -1; + + isl_ast_node_free(tree); + + if (n_domain != 3) + isl_die(ctx, isl_error_unknown, + "unexpected number of for nodes", return -1); + + return 0; +} + +/* Check that if the ast_build_exploit_nested_bounds options is set, + * we do not get an outer if node in the generated AST, + * while we do get such an outer if node if the options is not set. + */ +static int test_ast_gen4(isl_ctx *ctx) +{ + const char *str; + isl_set *set; + isl_union_map *schedule; + isl_ast_build *build; + isl_ast_node *tree; + enum isl_ast_node_type type; + int enb; + + enb = isl_options_get_ast_build_exploit_nested_bounds(ctx); + str = "[N,M] -> { A[i,j] -> [i,j] : 0 <= i <= N and 0 <= j <= M }"; + + isl_options_set_ast_build_exploit_nested_bounds(ctx, 1); + + schedule = isl_union_map_read_from_str(ctx, str); + set = isl_set_universe(isl_space_params_alloc(ctx, 0)); + build = isl_ast_build_from_context(set); + tree = isl_ast_build_node_from_schedule_map(build, schedule); + isl_ast_build_free(build); + if (!tree) + return -1; + + type = isl_ast_node_get_type(tree); + isl_ast_node_free(tree); + + if (type == isl_ast_node_if) + isl_die(ctx, isl_error_unknown, + "not expecting if node", return -1); + + isl_options_set_ast_build_exploit_nested_bounds(ctx, 0); + + schedule = isl_union_map_read_from_str(ctx, str); + set = isl_set_universe(isl_space_params_alloc(ctx, 0)); + build = isl_ast_build_from_context(set); + tree = isl_ast_build_node_from_schedule_map(build, schedule); + isl_ast_build_free(build); + if (!tree) + return -1; + + type = isl_ast_node_get_type(tree); + isl_ast_node_free(tree); + + if (type != isl_ast_node_if) + isl_die(ctx, isl_error_unknown, + "expecting if node", return -1); + + isl_options_set_ast_build_exploit_nested_bounds(ctx, enb); + + return 0; +} + +/* This function is called for each leaf in the AST generated + * from test_ast_gen5. + * + * We finalize the AST generation by extending the outer schedule + * with a zero-dimensional schedule. If this results in any for loops, + * then this means that we did not pass along enough information + * about the outer schedule to the inner AST generation. + */ +static __isl_give isl_ast_node *create_leaf(__isl_take isl_ast_build *build, + void *user) +{ + isl_union_map *schedule, *extra; + isl_ast_node *tree; + + schedule = isl_ast_build_get_schedule(build); + extra = isl_union_map_copy(schedule); + extra = isl_union_map_from_domain(isl_union_map_domain(extra)); + schedule = isl_union_map_range_product(schedule, extra); + tree = isl_ast_build_node_from_schedule_map(build, schedule); + isl_ast_build_free(build); + + if (!tree) + return NULL; + + if (isl_ast_node_get_type(tree) == isl_ast_node_for) + isl_die(isl_ast_node_get_ctx(tree), isl_error_unknown, + "code should not contain any for loop", + return isl_ast_node_free(tree)); + + return tree; +} + +/* Check that we do not lose any information when going back and + * forth between internal and external schedule. + * + * In particular, we create an AST where we unroll the only + * non-constant dimension in the schedule. We therefore do + * not expect any for loops in the AST. However, older versions + * of isl would not pass along enough information about the outer + * schedule when performing an inner code generation from a create_leaf + * callback, resulting in the inner code generation producing a for loop. + */ +static int test_ast_gen5(isl_ctx *ctx) +{ + const char *str; + isl_set *set; + isl_union_map *schedule, *options; + isl_ast_build *build; + isl_ast_node *tree; + + str = "{ A[] -> [1, 1, 2]; B[i] -> [1, i, 0] : i >= 1 and i <= 2 }"; + schedule = isl_union_map_read_from_str(ctx, str); + + str = "{ [a, b, c] -> unroll[1] : exists (e0 = [(a)/4]: " + "4e0 >= -1 + a - b and 4e0 <= -2 + a + b) }"; + options = isl_union_map_read_from_str(ctx, str); + + set = isl_set_universe(isl_space_params_alloc(ctx, 0)); + build = isl_ast_build_from_context(set); + build = isl_ast_build_set_options(build, options); + build = isl_ast_build_set_create_leaf(build, &create_leaf, NULL); + tree = isl_ast_build_node_from_schedule_map(build, schedule); + isl_ast_build_free(build); + isl_ast_node_free(tree); + if (!tree) + return -1; + + return 0; +} + +/* Check that the expression + * + * [n] -> { [n/2] : n <= 0 and n % 2 = 0; [0] : n > 0 } + * + * is not combined into + * + * min(n/2, 0) + * + * as this would result in n/2 being evaluated in parts of + * the definition domain where n is not a multiple of 2. + */ +static int test_ast_expr(isl_ctx *ctx) +{ + const char *str; + isl_pw_aff *pa; + isl_ast_build *build; + isl_ast_expr *expr; + int min_max; + int is_min; + + min_max = isl_options_get_ast_build_detect_min_max(ctx); + isl_options_set_ast_build_detect_min_max(ctx, 1); + + str = "[n] -> { [n/2] : n <= 0 and n % 2 = 0; [0] : n > 0 }"; + pa = isl_pw_aff_read_from_str(ctx, str); + build = isl_ast_build_alloc(ctx); + expr = isl_ast_build_expr_from_pw_aff(build, pa); + is_min = isl_ast_expr_get_type(expr) == isl_ast_expr_op && + isl_ast_expr_get_op_type(expr) == isl_ast_expr_op_min; + isl_ast_build_free(build); + isl_ast_expr_free(expr); + + isl_options_set_ast_build_detect_min_max(ctx, min_max); + + if (!expr) + return -1; + if (is_min) + isl_die(ctx, isl_error_unknown, + "expressions should not be combined", return -1); + + return 0; +} + +static int test_ast_gen(isl_ctx *ctx) +{ + if (test_ast_gen1(ctx) < 0) + return -1; + if (test_ast_gen2(ctx) < 0) + return -1; + if (test_ast_gen3(ctx) < 0) + return -1; + if (test_ast_gen4(ctx) < 0) + return -1; + if (test_ast_gen5(ctx) < 0) + return -1; + if (test_ast_expr(ctx) < 0) + return -1; + return 0; +} + +/* Check if dropping output dimensions from an isl_pw_multi_aff + * works properly. + */ +static int test_pw_multi_aff(isl_ctx *ctx) +{ + const char *str; + isl_pw_multi_aff *pma1, *pma2; + int equal; + + str = "{ [i,j] -> [i+j, 4i-j] }"; + pma1 = isl_pw_multi_aff_read_from_str(ctx, str); + str = "{ [i,j] -> [4i-j] }"; + pma2 = isl_pw_multi_aff_read_from_str(ctx, str); + + pma1 = isl_pw_multi_aff_drop_dims(pma1, isl_dim_out, 0, 1); + + equal = isl_pw_multi_aff_plain_is_equal(pma1, pma2); + + isl_pw_multi_aff_free(pma1); + isl_pw_multi_aff_free(pma2); + if (equal < 0) + return -1; + if (!equal) + isl_die(ctx, isl_error_unknown, + "expressions not equal", return -1); + + return 0; +} + +/* Check that we can properly parse multi piecewise affine expressions + * where the piecewise affine expressions have different domains. + */ +static int test_multi_pw_aff_1(isl_ctx *ctx) +{ + const char *str; + isl_set *dom, *dom2; + isl_multi_pw_aff *mpa1, *mpa2; + isl_pw_aff *pa; + int equal; + int equal_domain; + + mpa1 = isl_multi_pw_aff_read_from_str(ctx, "{ [i] -> [i] }"); + dom = isl_set_read_from_str(ctx, "{ [i] : i > 0 }"); + mpa1 = isl_multi_pw_aff_intersect_domain(mpa1, dom); + mpa2 = isl_multi_pw_aff_read_from_str(ctx, "{ [i] -> [2i] }"); + mpa2 = isl_multi_pw_aff_flat_range_product(mpa1, mpa2); + str = "{ [i] -> [(i : i > 0), 2i] }"; + mpa1 = isl_multi_pw_aff_read_from_str(ctx, str); + + equal = isl_multi_pw_aff_plain_is_equal(mpa1, mpa2); + + pa = isl_multi_pw_aff_get_pw_aff(mpa1, 0); + dom = isl_pw_aff_domain(pa); + pa = isl_multi_pw_aff_get_pw_aff(mpa1, 1); + dom2 = isl_pw_aff_domain(pa); + equal_domain = isl_set_is_equal(dom, dom2); + + isl_set_free(dom); + isl_set_free(dom2); + isl_multi_pw_aff_free(mpa1); + isl_multi_pw_aff_free(mpa2); + + if (equal < 0) + return -1; + if (!equal) + isl_die(ctx, isl_error_unknown, + "expressions not equal", return -1); + + if (equal_domain < 0) + return -1; + if (equal_domain) + isl_die(ctx, isl_error_unknown, + "domains unexpectedly equal", return -1); + + return 0; +} + +/* Check that the dimensions in the explicit domain + * of a multi piecewise affine expression are properly + * taken into account. + */ +static int test_multi_pw_aff_2(isl_ctx *ctx) +{ + const char *str; + isl_bool involves1, involves2, involves3, equal; + isl_multi_pw_aff *mpa, *mpa1, *mpa2; + + str = "{ A[x,y] -> B[] : x >= y }"; + mpa = isl_multi_pw_aff_read_from_str(ctx, str); + involves1 = isl_multi_pw_aff_involves_dims(mpa, isl_dim_in, 0, 2); + mpa1 = isl_multi_pw_aff_copy(mpa); + + mpa = isl_multi_pw_aff_insert_dims(mpa, isl_dim_in, 0, 1); + involves2 = isl_multi_pw_aff_involves_dims(mpa, isl_dim_in, 0, 1); + involves3 = isl_multi_pw_aff_involves_dims(mpa, isl_dim_in, 1, 2); + str = "{ [a,x,y] -> B[] : x >= y }"; + mpa2 = isl_multi_pw_aff_read_from_str(ctx, str); + equal = isl_multi_pw_aff_plain_is_equal(mpa, mpa2); + isl_multi_pw_aff_free(mpa2); + + mpa = isl_multi_pw_aff_drop_dims(mpa, isl_dim_in, 0, 1); + mpa = isl_multi_pw_aff_set_tuple_name(mpa, isl_dim_in, "A"); + if (equal >= 0 && equal) + equal = isl_multi_pw_aff_plain_is_equal(mpa, mpa1); + isl_multi_pw_aff_free(mpa1); + isl_multi_pw_aff_free(mpa); + + if (involves1 < 0 || involves2 < 0 || involves3 < 0 || equal < 0) + return -1; + if (!equal) + isl_die(ctx, isl_error_unknown, + "incorrect result of dimension insertion/removal", + return isl_stat_error); + if (!involves1 || involves2 || !involves3) + isl_die(ctx, isl_error_unknown, + "incorrect characterization of involved dimensions", + return isl_stat_error); + + return 0; +} + +/* Check that isl_multi_union_pw_aff_multi_val_on_domain + * sets the explicit domain of a zero-dimensional result, + * such that it can be converted to an isl_union_map. + */ +static isl_stat test_multi_pw_aff_3(isl_ctx *ctx) +{ + isl_space *space; + isl_union_set *dom; + isl_multi_val *mv; + isl_multi_union_pw_aff *mupa; + isl_union_map *umap; + + dom = isl_union_set_read_from_str(ctx, "{ A[]; B[] }"); + space = isl_union_set_get_space(dom); + mv = isl_multi_val_zero(isl_space_set_from_params(space)); + mupa = isl_multi_union_pw_aff_multi_val_on_domain(dom, mv); + umap = isl_union_map_from_multi_union_pw_aff(mupa); + isl_union_map_free(umap); + if (!umap) + return isl_stat_error; + + return isl_stat_ok; +} + +/* String descriptions of boxes that + * are used for reconstructing box maps from their lower and upper bounds. + */ +static const char *multi_pw_aff_box_tests[] = { + "{ A[x, y] -> [] : x + y >= 0 }", + "[N] -> { A[x, y] -> [x] : x + y <= N }", + "[N] -> { A[x, y] -> [x : y] : x + y <= N }", +}; + +/* Check that map representations of boxes can be reconstructed + * from their lower and upper bounds. + */ +static isl_stat test_multi_pw_aff_box(isl_ctx *ctx) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(multi_pw_aff_box_tests); ++i) { + const char *str; + isl_bool equal; + isl_map *map, *box; + isl_multi_pw_aff *min, *max; + + str = multi_pw_aff_box_tests[i]; + map = isl_map_read_from_str(ctx, str); + min = isl_map_min_multi_pw_aff(isl_map_copy(map)); + max = isl_map_max_multi_pw_aff(isl_map_copy(map)); + box = isl_map_universe(isl_map_get_space(map)); + box = isl_map_lower_bound_multi_pw_aff(box, min); + box = isl_map_upper_bound_multi_pw_aff(box, max); + equal = isl_map_is_equal(map, box); + isl_map_free(map); + isl_map_free(box); + if (equal < 0) + return isl_stat_error; + if (!equal) + isl_die(ctx, isl_error_unknown, + "unexpected result", return isl_stat_error); + } + + return isl_stat_ok; +} + +/* Perform some tests on multi piecewise affine expressions. + */ +static int test_multi_pw_aff(isl_ctx *ctx) +{ + if (test_multi_pw_aff_1(ctx) < 0) + return -1; + if (test_multi_pw_aff_2(ctx) < 0) + return -1; + if (test_multi_pw_aff_3(ctx) < 0) + return -1; + if (test_multi_pw_aff_box(ctx) < 0) + return -1; + return 0; +} + +/* This is a regression test for a bug where isl_basic_map_simplify + * would end up in an infinite loop. In particular, we construct + * an empty basic set that is not obviously empty. + * isl_basic_set_is_empty marks the basic set as empty. + * After projecting out i3, the variable can be dropped completely, + * but isl_basic_map_simplify refrains from doing so if the basic set + * is empty and would end up in an infinite loop if it didn't test + * explicitly for empty basic maps in the outer loop. + */ +static int test_simplify_1(isl_ctx *ctx) +{ + const char *str; + isl_basic_set *bset; + int empty; + + str = "{ [i0, i1, i2, i3] : i0 >= -2 and 6i2 <= 4 + i0 + 5i1 and " + "i2 <= 22 and 75i2 <= 111 + 13i0 + 60i1 and " + "25i2 >= 38 + 6i0 + 20i1 and i0 <= -1 and i2 >= 20 and " + "i3 >= i2 }"; + bset = isl_basic_set_read_from_str(ctx, str); + empty = isl_basic_set_is_empty(bset); + bset = isl_basic_set_project_out(bset, isl_dim_set, 3, 1); + isl_basic_set_free(bset); + if (!bset) + return -1; + if (!empty) + isl_die(ctx, isl_error_unknown, + "basic set should be empty", return -1); + + return 0; +} + +/* Check that the equality in the set description below + * is simplified away. + */ +static int test_simplify_2(isl_ctx *ctx) +{ + const char *str; + isl_basic_set *bset; + isl_bool universe; + + str = "{ [a] : exists e0, e1: 32e1 = 31 + 31a + 31e0 }"; + bset = isl_basic_set_read_from_str(ctx, str); + universe = isl_basic_set_plain_is_universe(bset); + isl_basic_set_free(bset); + + if (universe < 0) + return -1; + if (!universe) + isl_die(ctx, isl_error_unknown, + "equality not simplified away", return -1); + return 0; +} + +/* Some simplification tests. + */ +static int test_simplify(isl_ctx *ctx) +{ + if (test_simplify_1(ctx) < 0) + return -1; + if (test_simplify_2(ctx) < 0) + return -1; + return 0; +} + +/* This is a regression test for a bug where isl_tab_basic_map_partial_lexopt + * with gbr context would fail to disable the use of the shifted tableau + * when transferring equalities for the input to the context, resulting + * in invalid sample values. + */ +static int test_partial_lexmin(isl_ctx *ctx) +{ + const char *str; + isl_basic_set *bset; + isl_basic_map *bmap; + isl_map *map; + + str = "{ [1, b, c, 1 - c] -> [e] : 2e <= -c and 2e >= -3 + c }"; + bmap = isl_basic_map_read_from_str(ctx, str); + str = "{ [a, b, c, d] : c <= 1 and 2d >= 6 - 4b - c }"; + bset = isl_basic_set_read_from_str(ctx, str); + map = isl_basic_map_partial_lexmin(bmap, bset, NULL); + isl_map_free(map); + + if (!map) + return -1; + + return 0; +} + +/* Check that the variable compression performed on the existentially + * quantified variables inside isl_basic_set_compute_divs is not confused + * by the implicit equalities among the parameters. + */ +static int test_compute_divs(isl_ctx *ctx) +{ + const char *str; + isl_basic_set *bset; + isl_set *set; + + str = "[a, b, c, d, e] -> { [] : exists (e0: 2d = b and a <= 124 and " + "b <= 2046 and b >= 0 and b <= 60 + 64a and 2e >= b + 2c and " + "2e >= b and 2e <= 1 + b and 2e <= 1 + b + 2c and " + "32768e0 >= -124 + a and 2097152e0 <= 60 + 64a - b) }"; + bset = isl_basic_set_read_from_str(ctx, str); + set = isl_basic_set_compute_divs(bset); + isl_set_free(set); + if (!set) + return -1; + + return 0; +} + +/* Check that isl_schedule_get_map is not confused by a schedule tree + * with divergent filter node parameters, as can result from a call + * to isl_schedule_intersect_domain. + */ +static int test_schedule_tree(isl_ctx *ctx) +{ + const char *str; + isl_union_set *uset; + isl_schedule *sched1, *sched2; + isl_union_map *umap; + + uset = isl_union_set_read_from_str(ctx, "{ A[i] }"); + sched1 = isl_schedule_from_domain(uset); + uset = isl_union_set_read_from_str(ctx, "{ B[] }"); + sched2 = isl_schedule_from_domain(uset); + + sched1 = isl_schedule_sequence(sched1, sched2); + str = "[n] -> { A[i] : 0 <= i < n; B[] }"; + uset = isl_union_set_read_from_str(ctx, str); + sched1 = isl_schedule_intersect_domain(sched1, uset); + umap = isl_schedule_get_map(sched1); + isl_schedule_free(sched1); + isl_union_map_free(umap); + if (!umap) + return -1; + + return 0; +} + +/* Check that a zero-dimensional prefix schedule keeps track + * of the domain and outer filters. + */ +static int test_schedule_tree_prefix(isl_ctx *ctx) +{ + const char *str; + isl_bool equal; + isl_union_set *uset; + isl_union_set_list *filters; + isl_multi_union_pw_aff *mupa, *mupa2; + isl_schedule_node *node; + + str = "{ S1[i,j] : 0 <= i,j < 10; S2[i,j] : 0 <= i,j < 10 }"; + uset = isl_union_set_read_from_str(ctx, str); + node = isl_schedule_node_from_domain(uset); + node = isl_schedule_node_child(node, 0); + + str = "{ S1[i,j] : i > j }"; + uset = isl_union_set_read_from_str(ctx, str); + filters = isl_union_set_list_from_union_set(uset); + str = "{ S1[i,j] : i <= j; S2[i,j] }"; + uset = isl_union_set_read_from_str(ctx, str); + filters = isl_union_set_list_add(filters, uset); + node = isl_schedule_node_insert_sequence(node, filters); + + node = isl_schedule_node_grandchild(node, 0, 0); + mupa = isl_schedule_node_get_prefix_schedule_multi_union_pw_aff(node); + str = "([] : { S1[i,j] : i > j })"; + mupa2 = isl_multi_union_pw_aff_read_from_str(ctx, str); + equal = isl_multi_union_pw_aff_plain_is_equal(mupa, mupa2); + isl_multi_union_pw_aff_free(mupa2); + isl_multi_union_pw_aff_free(mupa); + isl_schedule_node_free(node); + + if (equal < 0) + return -1; + if (!equal) + isl_die(ctx, isl_error_unknown, "unexpected prefix schedule", + return -1); + + return 0; +} + +/* Check that the reaching domain elements and the prefix schedule + * at a leaf node are the same before and after grouping. + */ +static int test_schedule_tree_group_1(isl_ctx *ctx) +{ + int equal; + const char *str; + isl_id *id; + isl_union_set *uset; + isl_multi_union_pw_aff *mupa; + isl_union_pw_multi_aff *upma1, *upma2; + isl_union_set *domain1, *domain2; + isl_union_map *umap1, *umap2; + isl_schedule_node *node; + + str = "{ S1[i,j] : 0 <= i,j < 10; S2[i,j] : 0 <= i,j < 10 }"; + uset = isl_union_set_read_from_str(ctx, str); + node = isl_schedule_node_from_domain(uset); + node = isl_schedule_node_child(node, 0); + str = "[{ S1[i,j] -> [i]; S2[i,j] -> [9 - i] }]"; + mupa = isl_multi_union_pw_aff_read_from_str(ctx, str); + node = isl_schedule_node_insert_partial_schedule(node, mupa); + node = isl_schedule_node_child(node, 0); + str = "[{ S1[i,j] -> [j]; S2[i,j] -> [j] }]"; + mupa = isl_multi_union_pw_aff_read_from_str(ctx, str); + node = isl_schedule_node_insert_partial_schedule(node, mupa); + node = isl_schedule_node_child(node, 0); + umap1 = isl_schedule_node_get_prefix_schedule_union_map(node); + upma1 = isl_schedule_node_get_prefix_schedule_union_pw_multi_aff(node); + domain1 = isl_schedule_node_get_domain(node); + id = isl_id_alloc(ctx, "group", NULL); + node = isl_schedule_node_parent(node); + node = isl_schedule_node_group(node, id); + node = isl_schedule_node_child(node, 0); + umap2 = isl_schedule_node_get_prefix_schedule_union_map(node); + upma2 = isl_schedule_node_get_prefix_schedule_union_pw_multi_aff(node); + domain2 = isl_schedule_node_get_domain(node); + equal = isl_union_pw_multi_aff_plain_is_equal(upma1, upma2); + if (equal >= 0 && equal) + equal = isl_union_set_is_equal(domain1, domain2); + if (equal >= 0 && equal) + equal = isl_union_map_is_equal(umap1, umap2); + isl_union_map_free(umap1); + isl_union_map_free(umap2); + isl_union_set_free(domain1); + isl_union_set_free(domain2); + isl_union_pw_multi_aff_free(upma1); + isl_union_pw_multi_aff_free(upma2); + isl_schedule_node_free(node); + + if (equal < 0) + return -1; + if (!equal) + isl_die(ctx, isl_error_unknown, + "expressions not equal", return -1); + + return 0; +} + +/* Check that we can have nested groupings and that the union map + * schedule representation is the same before and after the grouping. + * Note that after the grouping, the union map representation contains + * the domain constraints from the ranges of the expansion nodes, + * while they are missing from the union map representation of + * the tree without expansion nodes. + * + * Also check that the global expansion is as expected. + */ +static int test_schedule_tree_group_2(isl_ctx *ctx) +{ + int equal, equal_expansion; + const char *str; + isl_id *id; + isl_union_set *uset; + isl_union_map *umap1, *umap2; + isl_union_map *expansion1, *expansion2; + isl_union_set_list *filters; + isl_multi_union_pw_aff *mupa; + isl_schedule *schedule; + isl_schedule_node *node; + + str = "{ S1[i,j] : 0 <= i,j < 10; S2[i,j] : 0 <= i,j < 10; " + "S3[i,j] : 0 <= i,j < 10 }"; + uset = isl_union_set_read_from_str(ctx, str); + node = isl_schedule_node_from_domain(uset); + node = isl_schedule_node_child(node, 0); + str = "[{ S1[i,j] -> [i]; S2[i,j] -> [i]; S3[i,j] -> [i] }]"; + mupa = isl_multi_union_pw_aff_read_from_str(ctx, str); + node = isl_schedule_node_insert_partial_schedule(node, mupa); + node = isl_schedule_node_child(node, 0); + str = "{ S1[i,j] }"; + uset = isl_union_set_read_from_str(ctx, str); + filters = isl_union_set_list_from_union_set(uset); + str = "{ S2[i,j]; S3[i,j] }"; + uset = isl_union_set_read_from_str(ctx, str); + filters = isl_union_set_list_add(filters, uset); + node = isl_schedule_node_insert_sequence(node, filters); + node = isl_schedule_node_grandchild(node, 1, 0); + str = "{ S2[i,j] }"; + uset = isl_union_set_read_from_str(ctx, str); + filters = isl_union_set_list_from_union_set(uset); + str = "{ S3[i,j] }"; + uset = isl_union_set_read_from_str(ctx, str); + filters = isl_union_set_list_add(filters, uset); + node = isl_schedule_node_insert_sequence(node, filters); + + schedule = isl_schedule_node_get_schedule(node); + umap1 = isl_schedule_get_map(schedule); + uset = isl_schedule_get_domain(schedule); + umap1 = isl_union_map_intersect_domain(umap1, uset); + isl_schedule_free(schedule); + + node = isl_schedule_node_grandparent(node); + id = isl_id_alloc(ctx, "group1", NULL); + node = isl_schedule_node_group(node, id); + node = isl_schedule_node_grandchild(node, 1, 0); + id = isl_id_alloc(ctx, "group2", NULL); + node = isl_schedule_node_group(node, id); + + schedule = isl_schedule_node_get_schedule(node); + umap2 = isl_schedule_get_map(schedule); + isl_schedule_free(schedule); + + node = isl_schedule_node_root(node); + node = isl_schedule_node_child(node, 0); + expansion1 = isl_schedule_node_get_subtree_expansion(node); + isl_schedule_node_free(node); + + str = "{ group1[i] -> S1[i,j] : 0 <= i,j < 10; " + "group1[i] -> S2[i,j] : 0 <= i,j < 10; " + "group1[i] -> S3[i,j] : 0 <= i,j < 10 }"; + + expansion2 = isl_union_map_read_from_str(ctx, str); + + equal = isl_union_map_is_equal(umap1, umap2); + equal_expansion = isl_union_map_is_equal(expansion1, expansion2); + + isl_union_map_free(umap1); + isl_union_map_free(umap2); + isl_union_map_free(expansion1); + isl_union_map_free(expansion2); + + if (equal < 0 || equal_expansion < 0) + return -1; + if (!equal) + isl_die(ctx, isl_error_unknown, + "expressions not equal", return -1); + if (!equal_expansion) + isl_die(ctx, isl_error_unknown, + "unexpected expansion", return -1); + + return 0; +} + +/* Some tests for the isl_schedule_node_group function. + */ +static int test_schedule_tree_group(isl_ctx *ctx) +{ + if (test_schedule_tree_group_1(ctx) < 0) + return -1; + if (test_schedule_tree_group_2(ctx) < 0) + return -1; + return 0; +} + +struct { + const char *set; + const char *dual; +} coef_tests[] = { + { "{ rat: [i] : 0 <= i <= 10 }", + "{ rat: coefficients[[cst] -> [a]] : cst >= 0 and 10a + cst >= 0 }" }, + { "{ rat: [i] : FALSE }", + "{ rat: coefficients[[cst] -> [a]] }" }, + { "{ rat: [i] : }", + "{ rat: coefficients[[cst] -> [0]] : cst >= 0 }" }, + { "{ [0:,1,2:3] }", + "{ rat: coefficients[[c_cst] -> [a, b, c]] : " + "a >= 0 and 2c >= -c_cst - b and 3c >= -c_cst - b }" }, + { "[M, N] -> { [x = (1 - N):-1, -4x:(M - 4x)] }", + "{ rat: coefficients[[c_cst, c_M = 0:, c_N = 0:] -> [a, b = -c_M:]] :" + "4b >= -c_N + a and 4b >= -c_cst - 2c_N + a }" }, + { "{ rat : [x, y] : 1 <= 2x <= 9 and 2 <= 3y <= 16 }", + "{ rat: coefficients[[c_cst] -> [c_x, c_y]] : " + "4c_y >= -6c_cst - 3c_x and 4c_y >= -6c_cst - 27c_x and " + "32c_y >= -6c_cst - 3c_x and 32c_y >= -6c_cst - 27c_x }" }, + { "{ [x, y, z] : 3y <= 2x - 2 and y >= -2 + 2x and 2y >= 2 - x }", + "{ rat: coefficients[[cst] -> [a, b, c]] }" }, +}; + +struct { + const char *set; + const char *dual; +} sol_tests[] = { + { "{ rat: coefficients[[cst] -> [a]] : cst >= 0 and 10a + cst >= 0 }", + "{ rat: [i] : 0 <= i <= 10 }" }, + { "{ rat: coefficients[[cst] -> [a]] : FALSE }", + "{ rat: [i] }" }, + { "{ rat: coefficients[[cst] -> [a]] }", + "{ rat: [i] : FALSE }" }, +}; + +/* Test the basic functionality of isl_basic_set_coefficients and + * isl_basic_set_solutions. + */ +static int test_dual(isl_ctx *ctx) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(coef_tests); ++i) { + int equal; + isl_basic_set *bset1, *bset2; + + bset1 = isl_basic_set_read_from_str(ctx, coef_tests[i].set); + bset2 = isl_basic_set_read_from_str(ctx, coef_tests[i].dual); + bset1 = isl_basic_set_coefficients(bset1); + equal = isl_basic_set_is_equal(bset1, bset2); + isl_basic_set_free(bset1); + isl_basic_set_free(bset2); + if (equal < 0) + return -1; + if (!equal) + isl_die(ctx, isl_error_unknown, + "incorrect dual", return -1); + } + + for (i = 0; i < ARRAY_SIZE(sol_tests); ++i) { + int equal; + isl_basic_set *bset1, *bset2; + + bset1 = isl_basic_set_read_from_str(ctx, sol_tests[i].set); + bset2 = isl_basic_set_read_from_str(ctx, sol_tests[i].dual); + bset1 = isl_basic_set_solutions(bset1); + equal = isl_basic_set_is_equal(bset1, bset2); + isl_basic_set_free(bset1); + isl_basic_set_free(bset2); + if (equal < 0) + return -1; + if (!equal) + isl_die(ctx, isl_error_unknown, + "incorrect dual", return -1); + } + + return 0; +} + +struct { + int scale_tile; + int shift_point; + const char *domain; + const char *schedule; + const char *sizes; + const char *tile; + const char *point; +} tile_tests[] = { + { 0, 0, "[n] -> { S[i,j] : 0 <= i,j < n }", + "[{ S[i,j] -> [i] }, { S[i,j] -> [j] }]", + "{ [32,32] }", + "[{ S[i,j] -> [floor(i/32)] }, { S[i,j] -> [floor(j/32)] }]", + "[{ S[i,j] -> [i] }, { S[i,j] -> [j] }]", + }, + { 1, 0, "[n] -> { S[i,j] : 0 <= i,j < n }", + "[{ S[i,j] -> [i] }, { S[i,j] -> [j] }]", + "{ [32,32] }", + "[{ S[i,j] -> [32*floor(i/32)] }, { S[i,j] -> [32*floor(j/32)] }]", + "[{ S[i,j] -> [i] }, { S[i,j] -> [j] }]", + }, + { 0, 1, "[n] -> { S[i,j] : 0 <= i,j < n }", + "[{ S[i,j] -> [i] }, { S[i,j] -> [j] }]", + "{ [32,32] }", + "[{ S[i,j] -> [floor(i/32)] }, { S[i,j] -> [floor(j/32)] }]", + "[{ S[i,j] -> [i%32] }, { S[i,j] -> [j%32] }]", + }, + { 1, 1, "[n] -> { S[i,j] : 0 <= i,j < n }", + "[{ S[i,j] -> [i] }, { S[i,j] -> [j] }]", + "{ [32,32] }", + "[{ S[i,j] -> [32*floor(i/32)] }, { S[i,j] -> [32*floor(j/32)] }]", + "[{ S[i,j] -> [i%32] }, { S[i,j] -> [j%32] }]", + }, +}; + +/* Basic tiling tests. Create a schedule tree with a domain and a band node, + * tile the band and then check if the tile and point bands have the + * expected partial schedule. + */ +static int test_tile(isl_ctx *ctx) +{ + int i; + int scale; + int shift; + + scale = isl_options_get_tile_scale_tile_loops(ctx); + shift = isl_options_get_tile_shift_point_loops(ctx); + + for (i = 0; i < ARRAY_SIZE(tile_tests); ++i) { + int opt; + int equal; + const char *str; + isl_union_set *domain; + isl_multi_union_pw_aff *mupa, *mupa2; + isl_schedule_node *node; + isl_multi_val *sizes; + + opt = tile_tests[i].scale_tile; + isl_options_set_tile_scale_tile_loops(ctx, opt); + opt = tile_tests[i].shift_point; + isl_options_set_tile_shift_point_loops(ctx, opt); + + str = tile_tests[i].domain; + domain = isl_union_set_read_from_str(ctx, str); + node = isl_schedule_node_from_domain(domain); + node = isl_schedule_node_child(node, 0); + str = tile_tests[i].schedule; + mupa = isl_multi_union_pw_aff_read_from_str(ctx, str); + node = isl_schedule_node_insert_partial_schedule(node, mupa); + str = tile_tests[i].sizes; + sizes = isl_multi_val_read_from_str(ctx, str); + node = isl_schedule_node_band_tile(node, sizes); + + str = tile_tests[i].tile; + mupa = isl_multi_union_pw_aff_read_from_str(ctx, str); + mupa2 = isl_schedule_node_band_get_partial_schedule(node); + equal = isl_multi_union_pw_aff_plain_is_equal(mupa, mupa2); + isl_multi_union_pw_aff_free(mupa); + isl_multi_union_pw_aff_free(mupa2); + + node = isl_schedule_node_child(node, 0); + + str = tile_tests[i].point; + mupa = isl_multi_union_pw_aff_read_from_str(ctx, str); + mupa2 = isl_schedule_node_band_get_partial_schedule(node); + if (equal >= 0 && equal) + equal = isl_multi_union_pw_aff_plain_is_equal(mupa, + mupa2); + isl_multi_union_pw_aff_free(mupa); + isl_multi_union_pw_aff_free(mupa2); + + isl_schedule_node_free(node); + + if (equal < 0) + return -1; + if (!equal) + isl_die(ctx, isl_error_unknown, + "unexpected result", return -1); + } + + isl_options_set_tile_scale_tile_loops(ctx, scale); + isl_options_set_tile_shift_point_loops(ctx, shift); + + return 0; +} + +/* Check that the domain hash of a space is equal to the hash + * of the domain of the space, both ignoring parameters. + */ +static int test_domain_hash(isl_ctx *ctx) +{ + isl_map *map; + isl_space *space; + uint32_t hash1, hash2; + + map = isl_map_read_from_str(ctx, "[n] -> { A[B[x] -> C[]] -> D[] }"); + space = isl_map_get_space(map); + isl_map_free(map); + hash1 = isl_space_get_tuple_domain_hash(space); + space = isl_space_domain(space); + hash2 = isl_space_get_tuple_hash(space); + isl_space_free(space); + + if (!space) + return -1; + if (hash1 != hash2) + isl_die(ctx, isl_error_unknown, + "domain hash not equal to hash of domain", return -1); + + return 0; +} + +/* Check that a universe basic set that is not obviously equal to the universe + * is still recognized as being equal to the universe. + */ +static int test_universe(isl_ctx *ctx) +{ + const char *s; + isl_basic_set *bset; + isl_bool is_univ; + + s = "{ [] : exists x, y : 3y <= 2x and y >= -3 + 2x and 2y >= 2 - x }"; + bset = isl_basic_set_read_from_str(ctx, s); + is_univ = isl_basic_set_is_universe(bset); + isl_basic_set_free(bset); + + if (is_univ < 0) + return -1; + if (!is_univ) + isl_die(ctx, isl_error_unknown, + "not recognized as universe set", return -1); + + return 0; +} + +/* Sets for which chambers are computed and checked. + */ +const char *chambers_tests[] = { + "[A, B, C] -> { [x, y, z] : x >= 0 and y >= 0 and y <= A - x and " + "z >= 0 and z <= C - y and z <= B - x - y }", +}; + +/* Add the domain of "cell" to "cells". + */ +static isl_stat add_cell(__isl_take isl_cell *cell, void *user) +{ + isl_basic_set_list **cells = user; + isl_basic_set *dom; + + dom = isl_cell_get_domain(cell); + isl_cell_free(cell); + *cells = isl_basic_set_list_add(*cells, dom); + + return *cells ? isl_stat_ok : isl_stat_error; +} + +/* Check that the elements of "list" are pairwise disjoint. + */ +static isl_stat check_pairwise_disjoint(__isl_keep isl_basic_set_list *list) +{ + int i, j; + isl_size n; + + n = isl_basic_set_list_n_basic_set(list); + if (n < 0) + return isl_stat_error; + + for (i = 0; i < n; ++i) { + isl_basic_set *bset_i; + + bset_i = isl_basic_set_list_get_basic_set(list, i); + for (j = i + 1; j < n; ++j) { + isl_basic_set *bset_j; + isl_bool disjoint; + + bset_j = isl_basic_set_list_get_basic_set(list, j); + disjoint = isl_basic_set_is_disjoint(bset_i, bset_j); + isl_basic_set_free(bset_j); + if (!disjoint) + isl_die(isl_basic_set_list_get_ctx(list), + isl_error_unknown, "not disjoint", + break); + if (disjoint < 0 || !disjoint) + break; + } + isl_basic_set_free(bset_i); + if (j < n) + return isl_stat_error; + } + + return isl_stat_ok; +} + +/* Check that the chambers computed by isl_vertices_foreach_disjoint_cell + * are pairwise disjoint. + */ +static int test_chambers(isl_ctx *ctx) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(chambers_tests); ++i) { + isl_basic_set *bset; + isl_vertices *vertices; + isl_basic_set_list *cells; + isl_stat ok; + + bset = isl_basic_set_read_from_str(ctx, chambers_tests[i]); + vertices = isl_basic_set_compute_vertices(bset); + cells = isl_basic_set_list_alloc(ctx, 0); + if (isl_vertices_foreach_disjoint_cell(vertices, &add_cell, + &cells) < 0) + cells = isl_basic_set_list_free(cells); + ok = check_pairwise_disjoint(cells); + isl_basic_set_list_free(cells); + isl_vertices_free(vertices); + isl_basic_set_free(bset); + + if (ok < 0) + return -1; + } + + return 0; +} + +struct { + const char *name; + int (*fn)(isl_ctx *ctx); +} tests [] = { + { "universe", &test_universe }, + { "domain hash", &test_domain_hash }, + { "dual", &test_dual }, + { "dependence analysis", &test_flow }, + { "val", &test_val }, + { "compute divs", &test_compute_divs }, + { "partial lexmin", &test_partial_lexmin }, + { "simplify", &test_simplify }, + { "curry", &test_curry }, + { "piecewise multi affine expressions", &test_pw_multi_aff }, + { "multi piecewise affine expressions", &test_multi_pw_aff }, + { "conversion", &test_conversion }, + { "list", &test_list }, + { "align parameters", &test_align_parameters }, + { "drop unused parameters", &test_drop_unused_parameters }, + { "pullback", &test_pullback }, + { "AST", &test_ast }, + { "AST build", &test_ast_build }, + { "AST generation", &test_ast_gen }, + { "eliminate", &test_eliminate }, + { "deltas_map", &test_deltas_map }, + { "residue class", &test_residue_class }, + { "div", &test_div }, + { "slice", &test_slice }, + { "sample", &test_sample }, + { "empty projection", &test_empty_projection }, + { "output", &test_output }, + { "vertices", &test_vertices }, + { "chambers", &test_chambers }, + { "fixed", &test_fixed }, + { "equal", &test_equal }, + { "disjoint", &test_disjoint }, + { "product", &test_product }, + { "dim_max", &test_dim_max }, + { "affine", &test_aff }, + { "injective", &test_injective }, + { "schedule (whole component)", &test_schedule_whole }, + { "schedule (incremental)", &test_schedule_incremental }, + { "schedule tree", &test_schedule_tree }, + { "schedule tree prefix", &test_schedule_tree_prefix }, + { "schedule tree grouping", &test_schedule_tree_group }, + { "tile", &test_tile }, + { "union map", &test_union_map }, + { "union_pw", &test_union_pw }, + { "locus", &test_locus }, + { "eval", &test_eval }, + { "parse", &test_parse }, + { "single-valued", &test_sv }, + { "recession cone", &test_recession_cone }, + { "affine hull", &test_affine_hull }, + { "simple_hull", &test_simple_hull }, + { "box hull", &test_box_hull }, + { "coalesce", &test_coalesce }, + { "factorize", &test_factorize }, + { "subset", &test_subset }, + { "subtract", &test_subtract }, + { "intersect", &test_intersect }, + { "lexmin", &test_lexmin }, + { "min", &test_min }, + { "set lower bounds", &test_min_mpa }, + { "gist", &test_gist }, + { "piecewise quasi-polynomials", &test_pwqp }, + { "lift", &test_lift }, + { "bind parameters", &test_bind }, + { "unbind parameters", &test_unbind }, + { "bound", &test_bound }, + { "get lists", &test_get_list }, + { "union", &test_union }, + { "split periods", &test_split_periods }, + { "lexicographic order", &test_lex }, + { "bijectivity", &test_bijective }, + { "dataflow analysis", &test_dep }, + { "reading", &test_read }, + { "bounded", &test_bounded }, + { "construction", &test_construction }, + { "dimension manipulation", &test_dim }, + { "map application", &test_application }, + { "convex hull", &test_convex_hull }, + { "transitive closure", &test_closure }, + { "isl_bool", &test_isl_bool}, +}; + +int main(int argc, char **argv) +{ + int i; + struct isl_ctx *ctx; + struct isl_options *options; + + options = isl_options_new_with_defaults(); + assert(options); + argc = isl_options_parse(options, argc, argv, ISL_ARG_ALL); + + ctx = isl_ctx_alloc_with_options(&isl_options_args, options); + for (i = 0; i < ARRAY_SIZE(tests); ++i) { + printf("%s\n", tests[i].name); + if (tests[i].fn(ctx) < 0) + goto error; + } + isl_ctx_free(ctx); + return 0; +error: + isl_ctx_free(ctx); + return -1; +} diff --git a/external/mit/isl/dist/isl_test2.cc b/external/mit/isl/dist/isl_test2.cc new file mode 100644 index 000000000000..a0f953723dda --- /dev/null +++ b/external/mit/isl/dist/isl_test2.cc @@ -0,0 +1,656 @@ +/* + * Copyright 2008-2009 Katholieke Universiteit Leuven + * Copyright 2010 INRIA Saclay + * Copyright 2012-2013 Ecole Normale Superieure + * Copyright 2014 INRIA Rocquencourt + * Copyright 2021-2022 Cerebras Systems + * + * 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 + * and Inria Paris - Rocquencourt, Domaine de Voluceau - Rocquencourt, + * B.P. 105 - 78153 Le Chesnay, France + * and Cerebras Systems, 1237 E Arques Ave, Sunnyvale, CA, USA + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +/* A binary isl function that appears in the C++ bindings + * as a unary method in a class T, taking an extra argument + * of type A1 and returning an object of type R. + */ +template +using binary_fn = R (T::*)(A1) const; + +/* A function for selecting an overload of a pointer to a unary C++ method + * based on the single argument type. + * The object type and the return type are meant to be deduced. + */ +template +static binary_fn const arg(const binary_fn &fn) +{ + return fn; +} + +/* A ternary isl function that appears in the C++ bindings + * as a binary method in a class T, taking extra arguments + * of type A1 and A2 and returning an object of type R. + */ +template +using ternary_fn = R (T::*)(A1, A2) const; + +/* A function for selecting an overload of a pointer to a binary C++ method + * based on the (first) argument type(s). + * The object type and the return type are meant to be deduced. + */ +template +static ternary_fn const arg(const ternary_fn &fn) +{ + return fn; +} + +/* A description of the input and the output of a unary operation. + */ +struct unary { + const char *arg; + const char *res; +}; + +/* A description of the inputs and the output of a binary operation. + */ +struct binary { + const char *arg1; + const char *arg2; + const char *res; +}; + +/* A description of the inputs and the output of a ternary operation. + */ +struct ternary { + const char *arg1; + const char *arg2; + const char *arg3; + const char *res; +}; + +/* A template function for checking whether two objects + * of the same (isl) type are (obviously) equal. + * The spelling depends on the isl type and + * in particular on whether an equality method is available or + * whether only obvious equality can be tested. + */ +template ().is_equal(std::declval()))>::type = true> +static bool is_equal(const T &a, const T &b) +{ + return a.is_equal(b); +} +template ().plain_is_equal(std::declval()))>::type = true> +static bool is_equal(const T &a, const T &b) +{ + return a.plain_is_equal(b); +} + +/* A helper macro for throwing an isl::exception_invalid with message "msg". + */ +#define THROW_INVALID(msg) \ + isl::exception::throw_error(isl_error_invalid, msg, __FILE__, __LINE__) + +/* Run a sequence of tests of method "fn" with stringification "name" and + * with input and output described by "test", + * throwing an exception when an unexpected result is produced. + */ +template +static void test(isl::ctx ctx, R (T::*fn)() const, const std::string &name, + const std::vector &tests) +{ + for (const auto &test : tests) { + T obj(ctx, test.arg); + R expected(ctx, test.res); + const auto &res = (obj.*fn)(); + std::ostringstream ss; + + if (is_equal(expected, res)) + continue; + + ss << name << "(" << test.arg << ") =\n" + << res << "\n" + << "expecting:\n" + << expected; + THROW_INVALID(ss.str().c_str()); + } +} + +/* Run a sequence of tests of method "fn" with stringification "name" and + * with inputs and output described by "test", + * throwing an exception when an unexpected result is produced. + */ +template +static void test(isl::ctx ctx, R (T::*fn)(A1) const, const std::string &name, + const std::vector &tests) +{ + for (const auto &test : tests) { + T obj(ctx, test.arg1); + A1 arg1(ctx, test.arg2); + R expected(ctx, test.res); + const auto &res = (obj.*fn)(arg1); + std::ostringstream ss; + + if (is_equal(expected, res)) + continue; + + ss << name << "(" << test.arg1 << ", " << test.arg2 << ") =\n" + << res << "\n" + << "expecting:\n" + << expected; + THROW_INVALID(ss.str().c_str()); + } +} + +/* Run a sequence of tests of method "fn" with stringification "name" and + * with inputs and output described by "test", + * throwing an exception when an unexpected result is produced. + */ +template +static void test(isl::ctx ctx, R (T::*fn)(A1, A2) const, + const std::string &name, const std::vector &tests) +{ + for (const auto &test : tests) { + T obj(ctx, test.arg1); + A1 arg1(ctx, test.arg2); + A2 arg2(ctx, test.arg3); + R expected(ctx, test.res); + const auto &res = (obj.*fn)(arg1, arg2); + std::ostringstream ss; + + if (is_equal(expected, res)) + continue; + + ss << name << "(" << test.arg1 << ", " << test.arg2 << ", " + << test.arg3 << ") =\n" + << res << "\n" + << "expecting:\n" + << expected; + THROW_INVALID(ss.str().c_str()); + } +} + +/* A helper macro that calls test with as implicit initial argument "ctx" and + * as extra argument a stringification of "FN". + */ +#define C(FN, ...) test(ctx, FN, #FN, __VA_ARGS__) + +/* Perform some basic isl::space tests. + */ +static void test_space(isl::ctx ctx) +{ + C(&isl::space::domain, { + { "{ A[] -> B[] }", "{ A[] }" }, + { "{ A[C[] -> D[]] -> B[E[] -> F[]] }", "{ A[C[] -> D[]] }" }, + }); + + C(&isl::space::range, { + { "{ A[] -> B[] }", "{ B[] }" }, + { "{ A[C[] -> D[]] -> B[E[] -> F[]] }", "{ B[E[] -> F[]] }" }, + }); + + C(&isl::space::params, { + { "{ A[] -> B[] }", "{ : }" }, + { "{ A[C[] -> D[]] -> B[E[] -> F[]] }", "{ : }" }, + }); +} + +/* Perform some basic conversion tests. + * + * In particular, check that a map with an output dimension + * that is equal to some integer division over a domain involving + * a local variable without a known integer division expression or + * to some linear combination of integer divisions + * can be converted to a function expressed in the same way. + */ +static void test_conversion(isl::ctx ctx) +{ + C(&isl::set::as_pw_multi_aff, { + { "[N=0:] -> { [] }", + "[N=0:] -> { [] }" }, + }); + + C(&isl::multi_pw_aff::as_set, { + { "[n] -> { [] : n >= 0 } ", + "[n] -> { [] : n >= 0 } " }, + }); + + C(&isl::map::as_pw_multi_aff, { + { "{ [a] -> [a//2] : " + "exists (e0: 8*floor((-a + e0)/8) <= -8 - a + 8e0) }", + "{ [a] -> [a//2] : " + "exists (e0: 8*floor((-a + e0)/8) <= -8 - a + 8e0) }" }, + { "{ [a, b] -> [(2*floor((a)/8) + floor((b)/6))] }", + "{ [a, b] -> [(2*floor((a)/8) + floor((b)/6))] }" }, + }); +} + +/* Perform some basic preimage tests. + */ +static void test_preimage(isl::ctx ctx) +{ + C(arg(&isl::set::preimage), { + { "{ B[i,j] : 0 <= i < 10 and 0 <= j < 100 }", + "{ A[j,i] -> B[i,j] }", + "{ A[j,i] : 0 <= i < 10 and 0 <= j < 100 }" }, + { "{ rat: B[i,j] : 0 <= i, j and 3 i + 5 j <= 100 }", + "{ A[a,b] -> B[a/2,b/6] }", + "{ rat: A[a,b] : 0 <= a, b and 9 a + 5 b <= 600 }" }, + { "{ B[i,j] : 0 <= i, j and 3 i + 5 j <= 100 }", + "{ A[a,b] -> B[a/2,b/6] }", + "{ A[a,b] : 0 <= a, b and 9 a + 5 b <= 600 and " + "exists i,j : a = 2 i and b = 6 j }" }, + { "[n] -> { S[i] : 0 <= i <= 100 }", "[n] -> { S[n] }", + "[n] -> { : 0 <= n <= 100 }" }, + { "{ B[i] : 0 <= i < 100 and exists a : i = 4 a }", + "{ A[a] -> B[2a] }", + "{ A[a] : 0 <= a < 50 and exists b : a = 2 b }" }, + { "{ B[i] : 0 <= i < 100 and exists a : i = 4 a }", + "{ A[a] -> B[([a/2])] }", + "{ A[a] : 0 <= a < 200 and exists b : [a/2] = 4 b }" }, + { "{ B[i,j,k] : 0 <= i,j,k <= 100 }", + "{ A[a] -> B[a,a,a/3] }", + "{ A[a] : 0 <= a <= 100 and exists b : a = 3 b }" }, + { "{ B[i,j] : j = [(i)/2] } ", "{ A[i,j] -> B[i/3,j] }", + "{ A[i,j] : j = [(i)/6] and exists a : i = 3 a }" }, + }); + + C(arg(&isl::set::preimage), { + { "{ B[i,j] : 0 <= i < 10 and 0 <= j < 100 }", + "{ A[j,i] -> B[i,j] : false }", + "{ A[j,i] : false }" }, + }); + + C(arg(&isl::union_map::preimage_domain), { + { "{ B[i,j] -> C[2i + 3j] : 0 <= i < 10 and 0 <= j < 100 }", + "{ A[j,i] -> B[i,j] }", + "{ A[j,i] -> C[2i + 3j] : 0 <= i < 10 and 0 <= j < 100 }" }, + { "{ B[i] -> C[i]; D[i] -> E[i] }", + "{ A[i] -> B[i + 1] }", + "{ A[i] -> C[i + 1] }" }, + { "{ B[i] -> C[i]; B[i] -> E[i] }", + "{ A[i] -> B[i + 1] }", + "{ A[i] -> C[i + 1]; A[i] -> E[i + 1] }" }, + { "{ B[i] -> C[([i/2])] }", + "{ A[i] -> B[2i] }", + "{ A[i] -> C[i] }" }, + { "{ B[i,j] -> C[([i/2]), ([(i+j)/3])] }", + "{ A[i] -> B[([i/5]), ([i/7])] }", + "{ A[i] -> C[([([i/5])/2]), ([(([i/5])+([i/7]))/3])] }" }, + { "[N] -> { B[i] -> C[([N/2]), i, ([N/3])] }", + "[N] -> { A[] -> B[([N/5])] }", + "[N] -> { A[] -> C[([N/2]), ([N/5]), ([N/3])] }" }, + { "{ B[i] -> C[i] : exists a : i = 5 a }", + "{ A[i] -> B[2i] }", + "{ A[i] -> C[2i] : exists a : 2i = 5 a }" }, + { "{ B[i] -> C[i] : exists a : i = 2 a; " + "B[i] -> D[i] : exists a : i = 2 a + 1 }", + "{ A[i] -> B[2i] }", + "{ A[i] -> C[2i] }" }, + { "{ A[i] -> B[i] }", "{ C[i] -> A[(i + floor(i/3))/2] }", + "{ C[i] -> B[j] : 2j = i + floor(i/3) }" }, + }); + + C(arg(&isl::union_map::preimage_range), { + { "[M] -> { A[a] -> B[a] }", "[M] -> { C[] -> B[floor(M/2)] }", + "[M] -> { A[floor(M/2)] -> C[] }" }, + }); +} + +/* Perform some basic fixed power tests. + */ +static void test_fixed_power(isl::ctx ctx) +{ + C(arg(&isl::map::fixed_power), { + { "{ [i] -> [i + 1] }", "23", + "{ [i] -> [i + 23] }" }, + { "{ [a = 0:1, b = 0:15, c = 0:1, d = 0:1, 0] -> [a, b, c, d, 1]; " + "[a = 0:1, b = 0:15, c = 0:1, 0, 1] -> [a, b, c, 1, 0]; " + "[a = 0:1, b = 0:15, 0, 1, 1] -> [a, b, 1, 0, 0]; " + "[a = 0:1, b = 0:14, 1, 1, 1] -> [a, 1 + b, 0, 0, 0]; " + "[0, 15, 1, 1, 1] -> [1, 0, 0, 0, 0] }", + "128", + "{ [0, b = 0:15, c = 0:1, d = 0:1, e = 0:1] -> [1, b, c, d, e] }" }, + }); +} + +/* Perform some basic intersection tests. + */ +static void test_intersect(isl::ctx ctx) +{ + C(&isl::union_map::intersect_domain_wrapped_domain, { + { "{ [A[x] -> B[y]] -> C[z]; [D[x] -> A[y]] -> E[z] }", + "{ A[0] }", + "{ [A[0] -> B[y]] -> C[z] }" }, + { "{ C[z] -> [A[x] -> B[y]]; E[z] -> [D[x] -> A[y]] }", + "{ A[0] }", + "{ }" }, + { "{ T[A[x] -> B[y]] -> C[z]; [D[x] -> A[y]] -> E[z] }", + "{ A[0] }", + "{ T[A[0] -> B[y]] -> C[z] }" }, + }); + + C(&isl::union_map::intersect_range_wrapped_domain, { + { "{ [A[x] -> B[y]] -> C[z]; [D[x] -> A[y]] -> E[z] }", + "{ A[0] }", + "{ }" }, + { "{ C[z] -> [A[x] -> B[y]]; E[z] -> [D[x] -> A[y]] }", + "{ A[0] }", + "{ C[z] -> [A[0] -> B[y]] }" }, + { "{ C[z] -> T[A[x] -> B[y]]; E[z] -> [D[x] -> A[y]] }", + "{ A[0] }", + "{ C[z] -> T[A[0] -> B[y]] }" }, + }); +} + +/* Perform some basic gist tests. + */ +static void test_gist(isl::ctx ctx) +{ + C(arg(&isl::pw_aff::gist), { + { "{ [x] -> [x] : x != 0 }", "{ [x] : x < -1 or x > 1 }", + "{ [x] -> [x] }" }, + }); + + C(&isl::pw_aff::gist_params, { + { "[N] -> { D[x] -> [x] : N >= 0; D[x] -> [0] : N < 0 }", + "[N] -> { : N >= 0 }", + "[N] -> { D[x] -> [x] }" }, + }); + + C(arg(&isl::multi_aff::gist), { + { "{ A[i] -> B[i, i] }", "{ A[0] }", + "{ A[i] -> B[0, 0] }" }, + { "[N] -> { A[i] -> B[i, N] }", "[N] -> { A[0] : N = 5 }", + "[N] -> { A[i] -> B[0, 5] }" }, + { "[N] -> { B[N + 1, N] }", "[N] -> { : N = 5 }", + "[N] -> { B[6, 5] }" }, + { "[N] -> { A[i] -> B[] }", "[N] -> { A[0] : N = 5 }", + "[N] -> { A[i] -> B[] }" }, + { "[N] -> { B[] }", "[N] -> { : N = 5 }", + "[N] -> { B[] }" }, + }); + + C(&isl::multi_aff::gist_params, { + { "[N] -> { A[i] -> B[i, N] }", "[N] -> { : N = 5 }", + "[N] -> { A[i] -> B[i, 5] }" }, + { "[N] -> { B[N + 1, N] }", "[N] -> { : N = 5 }", + "[N] -> { B[6, 5] }" }, + { "[N] -> { A[i] -> B[] }", "[N] -> { : N = 5 }", + "[N] -> { A[i] -> B[] }" }, + { "[N] -> { B[] }", "[N] -> { : N = 5 }", + "[N] -> { B[] }" }, + }); + + C(arg(&isl::multi_pw_aff::gist), { + { "{ A[i] -> B[i, i] : i >= 0 }", "{ A[0] }", + "{ A[i] -> B[0, 0] }" }, + { "[N] -> { A[i] -> B[i, N] : N >= 0 }", "[N] -> { A[0] : N = 5 }", + "[N] -> { A[i] -> B[0, 5] }" }, + { "[N] -> { B[N + 1, N] }", "[N] -> { : N = 5 }", + "[N] -> { B[6, 5] }" }, + { "[N] -> { A[i] -> B[] }", "[N] -> { A[0] : N = 5 }", + "[N] -> { A[i] -> B[] }" }, + { "[N] -> { B[] }", "[N] -> { : N = 5 }", + "[N] -> { B[] }" }, + { "{ A[i=0:10] -> B[i] }", "{ A[5] }", + "{ A[i] -> B[5] }" }, + { "{ A[0:10] -> B[] }", "{ A[0:10] }", + "{ A[i] -> B[] }" }, + { "[N] -> { A[i] -> B[] : N >= 0 }", "[N] -> { A[0] : N = 5 }", + "[N] -> { A[i] -> B[] }" }, + { "[N] -> { B[] : N >= 0 }", "[N] -> { : N = 5 }", + "[N] -> { B[] }" }, + { "[N] -> { B[] : N = 5 }", "[N] -> { : N >= 0 }", + "[N] -> { B[] : N = 5 }" }, + }); + + C(&isl::multi_pw_aff::gist_params, { + { "[N] -> { A[i] -> B[i, N] : N >= 0 }", "[N] -> { : N = 5 }", + "[N] -> { A[i] -> B[i, 5] }" }, + { "[N] -> { B[N + 1, N] }", "[N] -> { : N = 5 }", + "[N] -> { B[6, 5] }" }, + { "[N] -> { A[i] -> B[] : N >= 0 }", "[N] -> { : N = 5 }", + "[N] -> { A[i] -> B[] }" }, + { "[N] -> { B[] : N >= 0 }", "[N] -> { : N = 5 }", + "[N] -> { B[] }" }, + { "[N] -> { B[] : N >= 5 }", "[N] -> { : N >= 0 }", + "[N] -> { B[] : N >= 5 }" }, + }); + + C(&isl::multi_union_pw_aff::gist, { + { "C[{ B[i,i] -> [3i] }]", "{ B[i,i] }", + "C[{ B[i,j] -> [3i] }]" }, + { "(C[] : { B[i,i] })", "{ B[i,i] }", + "(C[] : { B[i,j] })" }, + { "[N] -> (C[] : { B[N,N] })", "[N] -> { B[N,N] }", + "[N] -> (C[] : { B[i,j] })" }, + { "C[]", "{ B[i,i] }", + "C[]" }, + { "[N] -> (C[] : { B[i,i] : N >= 0 })", "{ B[i,i] }", + "[N] -> (C[] : { B[i,j] : N >= 0 })" }, + { "[N] -> (C[] : { : N >= 0 })", "{ B[i,i] }", + "[N] -> (C[] : { : N >= 0 })" }, + { "[N] -> (C[] : { : N >= 0 })", "[N] -> { B[i,i] : N >= 0 }", + "[N] -> C[]" }, + }); + + C(&isl::multi_union_pw_aff::gist_params, { + { "[N] -> C[{ B[i,i] -> [3i + N] }]", "[N] -> { : N = 1 }", + "[N] -> C[{ B[i,i] -> [3i + 1] }]" }, + { "C[{ B[i,i] -> [3i] }]", "[N] -> { : N >= 0 }", + "[N] -> C[{ B[i,i] -> [3i] }]" }, + { "[N] -> C[{ B[i,i] -> [3i] : N >= 0 }]", "[N] -> { : N >= 0 }", + "[N] -> C[{ B[i,i] -> [3i] }]" }, + { "[N] -> C[{ B[i,i] -> [3i] : N >= 1 }]", "[N] -> { : N >= 0 }", + "[N] -> C[{ B[i,i] -> [3i] : N >= 1 }]" }, + { "[N] -> (C[] : { B[i,i] : N >= 0 })", "[N] -> { : N >= 0 }", + "[N] -> (C[] : { B[i,i] })" }, + { "[N] -> (C[] : { : N >= 0 })", "[N] -> { : N >= 0 }", + "[N] -> C[]" }, + { "C[{ B[i,i] -> [3i] }]", "[N] -> { : N >= 0 }", + "[N] -> C[{ B[i,i] -> [3i] }]" }, + }); +} + +/* Perform tests that project out parameters. + */ +static void test_project(isl::ctx ctx) +{ + C(arg(&isl::union_map::project_out_param), { + { "[N] -> { D[i] -> A[0:N-1]; D[i] -> B[i] }", "N", + "{ D[i] -> A[0:]; D[i] -> B[i] }" }, + { "[N] -> { D[i] -> A[0:N-1]; D[i] -> B[i] }", "M", + "[N] -> { D[i] -> A[0:N-1]; D[i] -> B[i] }" }, + }); + + C(arg(&isl::union_map::project_out_param), { + { "[M, N, O] -> { D[i] -> A[j] : i <= j < M, N, O }", "(M, N)", + "[O] -> { D[i] -> A[j] : i <= j < O }" }, + }); +} + +/* Perform some basic reverse tests. + */ +static void test_reverse(isl::ctx ctx) +{ + C(&isl::aff::domain_reverse, { + { "{ T[A[] -> B[*]] -> [0] }", + "{ [B[*] -> A[]] -> [0] }" }, + { "{ T[A[] -> A[]] -> [0] }", + "{ T[A[] -> A[]] -> [0] }" }, + { "{ [A[x] -> B[y]] -> [5*(x // 2) + 7*(y // 3)] }", + "{ [B[y] -> A[x]] -> [5*(x // 2) + 7*(y // 3)] }" }, + }); + + C(&isl::multi_aff::domain_reverse, { + { "{ [A[x] -> B[y]] -> [5*(x // 2) + 7*(y // 3)] }", + "{ [B[y] -> A[x]] -> [5*(x // 2) + 7*(y // 3)] }" }, + { "{ [A[x] -> B[y]] -> T[5*(x // 2) + 7*(y // 3), 0] }", + "{ [B[y] -> A[x]] -> T[5*(x // 2) + 7*(y // 3), 0] }" }, + }); + + C(&isl::set::wrapped_reverse, { + { "{ T[A[] -> B[*]] }", + "{ [B[*] -> A[]] }" }, + { "{ T[A[] -> A[]] }", + "{ T[A[] -> A[]] }" }, + { "{ [A[x] -> B[2x]] }", + "{ [B[y] -> A[x]] : y = 2x }" }, + }); + + C(&isl::pw_aff::domain_reverse, { + { "{ [A[x] -> B[y]] -> [5*(x // 2) + 7*(y // 3)] }", + "{ [B[y] -> A[x]] -> [5*(x // 2) + 7*(y // 3)] }" }, + { "{ [A[x] -> B[y]] -> [5*(x // 2) + 7*(y // 3)] : x > y }", + "{ [B[y] -> A[x]] -> [5*(x // 2) + 7*(y // 3)] : x > y }" }, + { "{ [A[i] -> B[i + 1]] -> [i + 2] }", + "{ [B[i] -> A[i - 1]] -> [i + 1] }" }, + }); + + C(&isl::pw_multi_aff::domain_reverse, { + { "{ [A[x] -> B[y]] -> T[5*(x // 2) + 7*(y // 3), 0] : x > y }", + "{ [B[y] -> A[x]] -> T[5*(x // 2) + 7*(y // 3), 0] : x > y }" }, + { "{ [A[i] -> B[i + 1]] -> T[0, i + 2] }", + "{ [B[i] -> A[i - 1]] -> T[0, i + 1] }" }, + }); + + C(&isl::multi_pw_aff::domain_reverse, { + { "{ [A[x] -> B[y]] -> T[5*(x // 2) + 7*(y // 3) : x > y, 0] }", + "{ [B[y] -> A[x]] -> T[5*(x // 2) + 7*(y // 3) : x > y, 0] }" }, + }); + + C(&isl::map::domain_reverse, { + { "{ [A[] -> B[]] -> [C[] -> D[]] }", + "{ [B[] -> A[]] -> [C[] -> D[]] }" }, + { "{ N[B[] -> C[]] -> A[] }", + "{ [C[] -> B[]] -> A[] }" }, + { "{ N[B[x] -> B[y]] -> A[] }", + "{ N[B[*] -> B[*]] -> A[] }" }, + }); + + C(&isl::union_map::domain_reverse, { + { "{ [A[] -> B[]] -> [C[] -> D[]] }", + "{ [B[] -> A[]] -> [C[] -> D[]] }" }, + { "{ A[] -> [B[] -> C[]]; A[] -> B[]; A[0] -> N[B[1] -> B[2]] }", + "{ }" }, + { "{ N[B[] -> C[]] -> A[] }", + "{ [C[] -> B[]] -> A[] }" }, + { "{ N[B[x] -> B[y]] -> A[] }", + "{ N[B[*] -> B[*]] -> A[] }" }, + }); + + C(&isl::union_map::range_reverse, { + { "{ A[] -> [B[] -> C[]]; A[] -> B[]; A[0] -> N[B[1] -> B[2]] }", + "{ A[] -> [C[] -> B[]]; A[0] -> N[B[2] -> B[1]] }" }, + { "{ A[] -> N[B[] -> C[]] }", + "{ A[] -> [C[] -> B[]] }" }, + { "{ A[] -> N[B[x] -> B[y]] }", + "{ A[] -> N[B[*] -> B[*]] }" }, + }); +} + +/* Perform some basic scaling tests. + */ +static void test_scale(isl::ctx ctx) +{ + C(arg(&isl::pw_multi_aff::scale), { + { "{ A[a] -> B[a, a + 1, a - 1] : a >= 0 }", "{ B[2, 7, 0] }", + "{ A[a] -> B[2a, 7a + 7, 0] : a >= 0 }" }, + }); + C(arg(&isl::pw_multi_aff::scale), { + { "{ A[a] -> B[1, a - 1] : a >= 0 }", "{ B[1/2, 7] }", + "{ A[a] -> B[1/2, 7a - 7] : a >= 0 }" }, + }); + + C(arg(&isl::pw_multi_aff::scale_down), { + { "{ A[a] -> B[a, a + 1] : a >= 0 }", "{ B[2, 7] }", + "{ A[a] -> B[a/2, (a + 1)/7] : a >= 0 }" }, + }); + C(arg(&isl::pw_multi_aff::scale_down), { + { "{ A[a] -> B[a, a - 1] : a >= 0 }", "{ B[2, 1/7] }", + "{ A[a] -> B[a/2, 7a - 7] : a >= 0 }" }, + }); +} + +/* Perform some basic isl::id_to_id tests. + */ +static void test_id_to_id(isl::ctx ctx) +{ + C((arg(&isl::id_to_id::set)), { + { "{ }", "a", "b", + "{ a: b }" }, + { "{ a: b }", "a", "b", + "{ a: b }" }, + { "{ a: c }", "a", "b", + "{ a: b }" }, + { "{ a: b }", "b", "a", + "{ a: b, b: a }" }, + { "{ a: b }", "b", "a", + "{ b: a, a: b }" }, + }); +} + +/* The list of tests to perform. + */ +static std::vector> tests = +{ + { "space", &test_space }, + { "conversion", &test_conversion }, + { "preimage", &test_preimage }, + { "fixed power", &test_fixed_power }, + { "intersect", &test_intersect }, + { "gist", &test_gist }, + { "project out parameters", &test_project }, + { "reverse", &test_reverse }, + { "scale", &test_scale }, + { "id-to-id", &test_id_to_id }, +}; + +/* Perform some basic checks by means of the C++ bindings. + */ +int main(int argc, char **argv) +{ + int ret = EXIT_SUCCESS; + struct isl_ctx *ctx; + struct isl_options *options; + + options = isl_options_new_with_defaults(); + assert(options); + argc = isl_options_parse(options, argc, argv, ISL_ARG_ALL); + ctx = isl_ctx_alloc_with_options(&isl_options_args, options); + + try { + for (const auto &f : tests) { + std::cout << f.first << "\n"; + f.second(ctx); + } + } catch (const isl::exception &e) { + std::cerr << e.what() << "\n"; + ret = EXIT_FAILURE; + } + + isl_ctx_free(ctx); + return ret; +} diff --git a/external/mit/isl/dist/isl_test_cpp-checked-conversion.cc b/external/mit/isl/dist/isl_test_cpp-checked-conversion.cc new file mode 100644 index 000000000000..a4aeaf5a0379 --- /dev/null +++ b/external/mit/isl/dist/isl_test_cpp-checked-conversion.cc @@ -0,0 +1,99 @@ +/* + * Copyright 2018 Sven Verdoolaege + * + * Use of this software is governed by the MIT license + * + * Written by Sven Verdoolaege. + */ + +#include + +#include +#include +#include + +/* Check that converting a NULL object from the checked C++ bindings + * (where the user is expected to check for NULL return values) + * to the default C++ bindings (where exceptions are raised + * instead of returning a NULL object) raises an exception. + */ +static void check_conversion_null(isl_ctx *ctx) +{ + isl::checked::set checked_set; + isl::set set; + + bool caught = false; + try { + set = isl::uncheck(checked_set); + isl_die(ctx, isl_error_unknown, "no exception raised", return); + } catch (const isl::exception &e) { + caught = true; + } + if (!caught) + isl_die(ctx, isl_error_unknown, "no exception raised", return); +} + +/* Dummy function on a set in the checked C++ bindings. + */ +static void f_checked(isl::checked::set set) +{ +} + +/* Dummy function on a set in the default C++ bindings. + */ +static void f_unchecked(isl::set set) +{ +} + +/* Check the conversion between C++ bindings in function calls. + * An incorrect call will result in a compiler error. + */ +static void check_conversion_call(isl_ctx *ctx) +{ + isl::set set(ctx, "{ S[i] : 0 <= i < 10 }"); + isl::checked::set checked_set(ctx, "{ S[i] : 0 <= i < 10 }"); + + f_unchecked(set); + f_checked(isl::check(set)); + f_unchecked(isl::uncheck(checked_set)); + f_checked(checked_set); +} + +/* Check that a double conversion results in the original set, + * or at least something that is equal to the original set. + */ +static void check_conversion_equal(isl_ctx *ctx) +{ + isl::set set(ctx, "{ S[i] : 0 <= i < 10 }"); + isl::set set2; + isl::checked::set checked_set; + + checked_set = isl::check(set); + set2 = isl::uncheck(checked_set); + + if (!set.is_equal(set2)) + isl_die(ctx, isl_error_unknown, "bad conversion", return); +} + +/* Perform some tests on the conversion between the default C++ bindings and + * the checked C++ bindings. + */ +static void check_conversion(isl_ctx *ctx) +{ + check_conversion_null(ctx); + check_conversion_call(ctx); + check_conversion_equal(ctx); +} + +int main() +{ + isl_ctx *ctx = isl_ctx_alloc(); + + isl_options_set_on_error(ctx, ISL_ON_ERROR_ABORT); + + check_conversion(ctx); + + isl_ctx_free(ctx); + + return EXIT_SUCCESS; +} diff --git a/external/mit/isl/dist/isl_test_cpp-checked.cc b/external/mit/isl/dist/isl_test_cpp-checked.cc new file mode 100644 index 000000000000..47c3468104d9 --- /dev/null +++ b/external/mit/isl/dist/isl_test_cpp-checked.cc @@ -0,0 +1,312 @@ +/* Copyright 2016-2017 Tobias Grosser + * + * Use of this software is governed by the MIT license + * + * Written by Tobias Grosser, Weststrasse 47, CH-8003, Zurich + */ + +#include +#include +#include +#include +#include + +#include +#include + +namespace isl { using namespace checked; } + +static void assert_impl(bool condition, const char *file, int line, + const char *message) +{ + if (condition) + return; + + fprintf(stderr, "Assertion failed in %s:%d %s\n", file, line, message); + exit(EXIT_FAILURE); +} + +static void assert_impl(isl::boolean condition, const char *file, int line, + const char *message) +{ + assert_impl(bool(condition), file, line, message); +} + +/* Return the value encapsulated by "s". + */ +static int size_val(isl::size s) +{ + return s.is_error() ? -1 : unsigned(s); +} + +#undef assert +#define assert(exp) assert_impl(exp, __FILE__, __LINE__, #exp) +#define IS_TRUE(b) (b).is_true() +#define SIZE_VAL(s) size_val(s) + +#include "isl_test_cpp-generic.cc" + +/* Test that isl_bool values are returned correctly. + * + * We check in detail the following parts of the isl::boolean class: + * - The is_true, is_false, and is_error functions return true in case they + * are called on a true, false, or error instance of isl::boolean, + * respectively + * - Explicit conversion to 'bool' + * - Implicit conversion to 'bool' + * - The complement operator + * - Explicit construction from 'true' and 'false' + * - Explicit construction form isl_bool + */ +void test_return_bool(isl::ctx ctx) +{ + isl::set empty(ctx, "{ : false }"); + isl::set univ(ctx, "{ : }"); + isl::set null; + + isl::boolean b_true = empty.is_empty(); + isl::boolean b_false = univ.is_empty(); + isl::boolean b_error = null.is_empty(); + + assert(b_true.is_true()); + assert(!b_true.is_false()); + assert(!b_true.is_error()); + + assert(!b_false.is_true()); + assert(b_false.is_false()); + assert(!b_false.is_error()); + + assert(!b_error.is_true()); + assert(!b_error.is_false()); + assert(b_error.is_error()); + + assert(bool(b_true) == true); + assert(bool(b_false) == false); + + assert(b_true); + + assert((!b_false).is_true()); + assert((!b_true).is_false()); + assert((!b_error).is_error()); + + assert(isl::boolean(true).is_true()); + assert(!isl::boolean(true).is_false()); + assert(!isl::boolean(true).is_error()); + + assert(isl::boolean(false).is_false()); + assert(!isl::boolean(false).is_true()); + assert(!isl::boolean(false).is_error()); + + assert(isl::manage(isl_bool_true).is_true()); + assert(!isl::manage(isl_bool_true).is_false()); + assert(!isl::manage(isl_bool_true).is_error()); + + assert(isl::manage(isl_bool_false).is_false()); + assert(!isl::manage(isl_bool_false).is_true()); + assert(!isl::manage(isl_bool_false).is_error()); + + assert(isl::manage(isl_bool_error).is_error()); + assert(!isl::manage(isl_bool_error).is_true()); + assert(!isl::manage(isl_bool_error).is_false()); +} + +/* Test that return values are handled correctly. + * + * Test that isl C++ objects, integers, boolean values, and strings are + * returned correctly. + */ +void test_return(isl::ctx ctx) +{ + test_return_obj(ctx); + test_return_int(ctx); + test_return_bool(ctx); + test_return_string(ctx); +} + +/* Test that foreach functions are modeled correctly. + * + * Verify that lambdas are correctly called as callback of a 'foreach' + * function and that variables captured by the lambda work correctly. Also + * check that the foreach function takes account of the return value of the + * lambda and aborts in case isl::stat::error is returned and then returns + * isl::stat::error itself. + */ +void test_foreach(isl::ctx ctx) +{ + isl::set s(ctx, "{ [0]; [1]; [2] }"); + + std::vector basic_sets; + + auto add_to_vector = [&] (isl::basic_set bs) { + basic_sets.push_back(bs); + return isl::stat::ok(); + }; + + isl::stat ret1 = s.foreach_basic_set(add_to_vector); + + assert(ret1.is_ok()); + assert(basic_sets.size() == 3); + assert(isl::set(basic_sets[0]).is_subset(s).is_true()); + assert(isl::set(basic_sets[1]).is_subset(s).is_true()); + assert(isl::set(basic_sets[2]).is_subset(s).is_true()); + assert(!basic_sets[0].is_equal(basic_sets[1]).is_true()); + + auto fail = [&] (isl::basic_set bs) { + return isl::stat::error(); + }; + + isl::stat ret2 = s.foreach_basic_set(fail); + + assert(ret2.is_error()); +} + +/* Test the functionality of "every" functions. + * + * In particular, test the generic functionality and + * test that error conditions are properly propagated. + */ +static void test_every(isl::ctx ctx) +{ + isl::union_set us(ctx, "{ A[i]; B[j] }"); + + test_every_generic(ctx); + + auto fail = [] (isl::set s){ + return isl::boolean::error(); + }; + assert(us.every_set(fail).is_error()); +} + +/* Test basic schedule tree functionality. + * + * In particular, create a simple schedule tree and + * - perform some generic tests + * - test map_descendant_bottom_up in the failing case + * - test foreach_descendant_top_down + * - test every_descendant + */ +static void test_schedule_tree(isl::ctx ctx) +{ + auto root = test_schedule_tree_generic(ctx); + + auto fail_map = [](isl::schedule_node node) { + return isl::schedule_node(); + }; + assert(root.map_descendant_bottom_up(fail_map).is_null()); + + int count = 0; + auto inc_count = [&count](isl::schedule_node node) { + count++; + return isl::boolean(true); + }; + assert(root.foreach_descendant_top_down(inc_count).is_ok()); + assert(count == 8); + + count = 0; + auto inc_count_once = [&count](isl::schedule_node node) { + count++; + return isl::boolean(false); + }; + assert(root.foreach_descendant_top_down(inc_count_once).is_ok()); + assert(count == 1); + + auto is_not_domain = [](isl::schedule_node node) { + return !node.isa(); + }; + assert(root.child(0).every_descendant(is_not_domain).is_true()); + assert(root.every_descendant(is_not_domain).is_false()); + + auto fail = [](isl::schedule_node node) { + return isl::boolean(); + }; + assert(root.every_descendant(fail).is_error()); + + auto domain = root.as().domain(); + auto filters = isl::union_set(ctx, "{}"); + auto collect_filters = [&filters](isl::schedule_node node) { + if (node.isa().is_true()) { + auto filter = node.as(); + filters = filters.unite(filter.filter()); + } + return isl::boolean(true); + }; + assert(!root.every_descendant(collect_filters).is_error()); + assert(domain.is_equal(filters).is_true()); +} + +/* Test basic AST generation from a schedule tree. + * + * In particular, create a simple schedule tree and + * - perform some generic tests + * - test at_each_domain in the failing case + */ +static void test_ast_build(isl::ctx ctx) +{ + auto schedule = test_ast_build_generic(ctx); + + bool do_fail = true; + int count_ast_fail = 0; + auto fail_inc_count_ast = + [&count_ast_fail, &do_fail](isl::ast_node node, + isl::ast_build build) { + count_ast_fail++; + return do_fail ? isl::ast_node() : node; + }; + auto build = isl::ast_build(ctx); + build = build.set_at_each_domain(fail_inc_count_ast); + auto ast = build.node_from(schedule); + assert(ast.is_null()); + assert(count_ast_fail > 0); + auto build_copy = build; + int count_ast = 0; + auto inc_count_ast = + [&count_ast](isl::ast_node node, isl::ast_build build) { + count_ast++; + return node; + }; + build_copy = build_copy.set_at_each_domain(inc_count_ast); + ast = build_copy.node_from(schedule); + assert(!ast.is_null()); + assert(count_ast == 2); + count_ast_fail = 0; + do_fail = false; + ast = build.node_from(schedule); + assert(!ast.is_null()); + assert(count_ast_fail == 2); +} + +/* Test the isl checked C++ interface + * + * This includes: + * - The isl C <-> C++ pointer interface + * - Object construction + * - Different parameter types + * - Different return types + * - Foreach functions + * - Every functions + * - Spaces + * - Schedule trees + * - AST generation + * - AST expression generation + */ +int main() +{ + isl_ctx *ctx = isl_ctx_alloc(); + + isl_options_set_on_error(ctx, ISL_ON_ERROR_ABORT); + + test_pointer(ctx); + test_constructors(ctx); + test_parameters(ctx); + test_return(ctx); + test_foreach(ctx); + test_every(ctx); + test_space(ctx); + test_schedule_tree(ctx); + test_ast_build(ctx); + test_ast_build_expr(ctx); + + isl_ctx_free(ctx); + + return EXIT_SUCCESS; +} diff --git a/external/mit/isl/dist/isl_test_cpp-generic.cc b/external/mit/isl/dist/isl_test_cpp-generic.cc new file mode 100644 index 000000000000..e225a71b06fc --- /dev/null +++ b/external/mit/isl/dist/isl_test_cpp-generic.cc @@ -0,0 +1,374 @@ +/* Copyright 2016-2017 Tobias Grosser + * + * Use of this software is governed by the MIT license + * + * Written by Tobias Grosser, Weststrasse 47, CH-8003, Zurich + */ + +#ifndef IS_TRUE +#define IS_TRUE(b) (b) +#endif +#ifndef SIZE_VAL +#define SIZE_VAL(s) (s) +#endif + +/* Test the pointer interface for interaction between isl C and C++ types. + * + * This tests: + * - construction from an isl C object + * - check that constructed objects are non-null + * - get a non-owned C pointer from an isl C++ object usable in __isl_keep + * methods + * - use copy to get an owned C pointer from an isl C++ object which is usable + * in __isl_take methods. Verify that the original C++ object retains a valid + * pointer. + * - use release to get an owned C pointer from an isl C++ object which is + * usable in __isl_take methods. Verify that the original C++ object gave up + * its pointer and now is null. + */ +void test_pointer(isl::ctx ctx) +{ + isl_set *c_empty = isl_set_read_from_str(ctx.get(), "{ : false }"); + isl::set empty = isl::manage(c_empty); + assert(IS_TRUE(empty.is_empty())); + assert(isl_set_is_empty(empty.get())); + + assert(!empty.is_null()); + isl_set_free(empty.copy()); + assert(!empty.is_null()); + isl_set_free(empty.release()); + assert(empty.is_null()); +} + +/* Test that isl objects can be constructed. + * + * This tests: + * - construction of a null object + * - construction from a string + * - construction from an integer + * - static constructor without a parameter + * - conversion construction (implicit) + * - conversion construction (explicit) + * - construction of empty union set + * + * The tests to construct from integers and strings cover functionality that + * is also tested in the parameter type tests, but here we verify that + * multiple overloaded constructors are available and that overload resolution + * works as expected. + * + * Construction from an isl C pointer is tested in test_pointer. + */ +void test_constructors(isl::ctx ctx) +{ + isl::val null; + assert(null.is_null()); + + isl::val zero_from_str = isl::val(ctx, "0"); + assert(IS_TRUE(zero_from_str.is_zero())); + + isl::val zero_int_con = isl::val(ctx, 0); + assert(IS_TRUE(zero_int_con.is_zero())); + + isl::val zero_static_con = isl::val::zero(ctx); + assert(IS_TRUE(zero_static_con.is_zero())); + + isl::basic_set bs(ctx, "{ [1] }"); + isl::set result(ctx, "{ [1] }"); + isl::set s = bs; + assert(IS_TRUE(s.is_equal(result))); + isl::set s2(bs); + assert(IS_TRUE(s.unite(s2).is_equal(result))); + + isl::union_set us(ctx, "{ A[1]; B[2, 3] }"); + isl::union_set empty = isl::union_set::empty(ctx); + assert(IS_TRUE(us.is_equal(us.unite(empty)))); +} + +/* Test integer function parameters. + * + * Verify that extreme values and zero work. + */ +void test_parameters_int(isl::ctx ctx) +{ + isl::val long_max_str(ctx, std::to_string(LONG_MAX)); + isl::val long_max_int(ctx, LONG_MAX); + assert(IS_TRUE(long_max_str.eq(long_max_int))); + + isl::val long_min_str(ctx, std::to_string(LONG_MIN)); + isl::val long_min_int(ctx, LONG_MIN); + assert(IS_TRUE(long_min_str.eq(long_min_int))); + + isl::val long_zero_str = isl::val(ctx, std::to_string(0)); + isl::val long_zero_int = isl::val(ctx, 0); + assert(IS_TRUE(long_zero_str.eq(long_zero_int))); +} + +/* 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. + */ +void test_parameters_obj(isl::ctx ctx) +{ + isl::set a(ctx, "{ [0] }"); + isl::set b(ctx, "{ [1] }"); + isl::set c(ctx, "{ [2] }"); + isl::set expected(ctx, "{ [i] : 0 <= i <= 2 }"); + + isl::set tmp = a.unite(b); + isl::set res_lvalue_param = tmp.unite(c); + assert(IS_TRUE(res_lvalue_param.is_equal(expected))); + + isl::set res_rvalue_param = a.unite(b).unite(c); + assert(IS_TRUE(res_rvalue_param.is_equal(expected))); + + isl::basic_set a2(ctx, "{ [0] }"); + assert(IS_TRUE(a.is_equal(a2))); + + isl::val two(ctx, 2); + isl::val half(ctx, "1/2"); + isl::val res_only_this_param = two.inv(); + assert(IS_TRUE(res_only_this_param.eq(half))); +} + +/* Test different kinds of parameters to be passed to functions. + * + * This includes integer and isl C++ object parameters. + */ +void test_parameters(isl::ctx ctx) +{ + test_parameters_int(ctx); + test_parameters_obj(ctx); +} + +/* Test that isl objects are returned correctly. + * + * This only tests that after combining two objects, the result is successfully + * returned. + */ +void test_return_obj(isl::ctx ctx) +{ + isl::val one(ctx, "1"); + isl::val two(ctx, "2"); + isl::val three(ctx, "3"); + + isl::val res = one.add(two); + + assert(IS_TRUE(res.eq(three))); +} + +/* Test that integer values are returned correctly. + */ +void test_return_int(isl::ctx ctx) +{ + isl::val one(ctx, "1"); + isl::val neg_one(ctx, "-1"); + isl::val zero(ctx, "0"); + + assert(one.sgn() > 0); + assert(neg_one.sgn() < 0); + assert(zero.sgn() == 0); +} + +/* Test that strings are returned correctly. + * Do so by calling overloaded isl::ast_build::from_expr methods. + */ +void test_return_string(isl::ctx ctx) +{ + isl::set context(ctx, "[n] -> { : }"); + isl::ast_build build = isl::ast_build::from_context(context); + isl::pw_aff pw_aff(ctx, "[n] -> { [n] }"); + isl::set set(ctx, "[n] -> { : n >= 0 }"); + + isl::ast_expr expr = build.expr_from(pw_aff); + const char *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 the functionality of "every" functions + * that does not depend on the type of C++ bindings. + */ +static void test_every_generic(isl::ctx ctx) +{ + isl::union_set us(ctx, "{ A[i]; B[j] }"); + + auto is_empty = [] (isl::set s) { + return s.is_empty(); + }; + assert(!IS_TRUE(us.every_set(is_empty))); + + auto is_non_empty = [] (isl::set s) { + return !s.is_empty(); + }; + assert(IS_TRUE(us.every_set(is_non_empty))); + + auto in_A = [] (isl::set s) { + return s.is_subset(isl::set(s.ctx(), "{ A[x] }")); + }; + assert(!IS_TRUE(us.every_set(in_A))); + + auto not_in_A = [] (isl::set s) { + return !s.is_subset(isl::set(s.ctx(), "{ A[x] }")); + }; + assert(!IS_TRUE(us.every_set(not_in_A))); +} + +/* Check basic construction of spaces. + */ +static void test_space(isl::ctx ctx) +{ + isl::space unit = isl::space::unit(ctx); + isl::space set_space = unit.add_named_tuple("A", 3); + isl::space map_space = set_space.add_named_tuple("B", 2); + + isl::set set = isl::set::universe(set_space); + isl::map map = isl::map::universe(map_space); + assert(IS_TRUE(set.is_equal(isl::set(ctx, "{ A[*,*,*] }")))); + assert(IS_TRUE(map.is_equal(isl::map(ctx, "{ A[*,*,*] -> B[*,*] }")))); +} + +/* Construct a simple schedule tree with an outer sequence node and + * a single-dimensional band node in each branch, with one of them + * marked coincident. + */ +static isl::schedule construct_schedule_tree(isl::ctx ctx) +{ + isl::union_set A(ctx, "{ A[i] : 0 <= i < 10 }"); + isl::union_set B(ctx, "{ B[i] : 0 <= i < 20 }"); + + auto node = isl::schedule_node::from_domain(A.unite(B)); + node = node.child(0); + + isl::union_set_list filters(ctx, 0); + filters = filters.add(A).add(B); + node = node.insert_sequence(filters); + + isl::multi_union_pw_aff f_A(ctx, "[ { A[i] -> [i] } ]"); + node = node.child(0); + node = node.child(0); + node = node.insert_partial_schedule(f_A); + auto band = node.as(); + band = band.member_set_coincident(0, true); + node = band.ancestor(2); + + isl::multi_union_pw_aff f_B(ctx, "[ { B[i] -> [i] } ]"); + node = node.child(1); + node = node.child(0); + node = node.insert_partial_schedule(f_B); + node = node.ancestor(2); + + return node.schedule(); +} + +/* Test basic schedule tree functionality that is independent + * of the type of bindings. + * + * In particular, create a simple schedule tree and + * - check that the root node is a domain node + * - check that an object of a subclass can be used as one of the superclass + * - test map_descendant_bottom_up in the successful case + */ +static isl::schedule_node test_schedule_tree_generic(isl::ctx ctx) +{ + auto schedule = construct_schedule_tree(ctx); + auto root = schedule.root(); + + assert(IS_TRUE(root.isa())); + root = root.as().child(0).parent(); + + int count = 0; + auto inc_count = [&count](isl::schedule_node node) { + count++; + return node; + }; + root = root.map_descendant_bottom_up(inc_count); + assert(count == 8); + + return root; +} + +/* Test marking band members for unrolling. + * "schedule" is the schedule created by construct_schedule_tree. + * It schedules two statements, with 10 and 20 instances, respectively. + * Unrolling all band members therefore results in 30 at-domain calls + * by the AST generator. + */ +static void test_ast_build_unroll(isl::schedule schedule) +{ + auto root = schedule.root(); + auto mark_unroll = [](isl::schedule_node node) { + if (IS_TRUE(node.isa())) { + auto band = node.as(); + node = band.member_set_ast_loop_unroll(0); + } + return node; + }; + root = root.map_descendant_bottom_up(mark_unroll); + schedule = root.schedule(); + + int count_ast = 0; + auto inc_count_ast = + [&count_ast](isl::ast_node node, isl::ast_build build) { + count_ast++; + return node; + }; + auto build = isl::ast_build(schedule.ctx()); + build = build.set_at_each_domain(inc_count_ast); + auto ast = build.node_from(schedule); + assert(count_ast == 30); +} + +/* Test basic AST generation from a schedule tree that is independent + * of the type of bindings. + * + * In particular, create a simple schedule tree and + * - generate an AST from the schedule tree + * - test at_each_domain in the successful case + * - test unrolling + */ +static isl::schedule test_ast_build_generic(isl::ctx ctx) +{ + auto schedule = construct_schedule_tree(ctx); + + int count_ast = 0; + auto inc_count_ast = + [&count_ast](isl::ast_node node, isl::ast_build build) { + count_ast++; + return node; + }; + auto build = isl::ast_build(ctx); + auto build_copy = build.set_at_each_domain(inc_count_ast); + auto ast = build.node_from(schedule); + assert(count_ast == 0); + count_ast = 0; + ast = build_copy.node_from(schedule); + assert(count_ast == 2); + build = build_copy; + count_ast = 0; + ast = build.node_from(schedule); + assert(count_ast == 2); + + test_ast_build_unroll(schedule); + + return schedule; +} + +/* Test basic AST expression generation from an affine expression. + */ +static void test_ast_build_expr(isl::ctx ctx) +{ + isl::pw_aff pa(ctx, "[n] -> { [n + 1] }"); + isl::ast_build build = isl::ast_build::from_context(pa.domain()); + + auto expr = build.expr_from(pa); + auto op = expr.as(); + assert(IS_TRUE(op.isa())); + assert(SIZE_VAL(op.n_arg()) == 2); +} diff --git a/external/mit/isl/dist/isl_test_cpp.cc b/external/mit/isl/dist/isl_test_cpp.cc new file mode 100644 index 000000000000..01308d171859 --- /dev/null +++ b/external/mit/isl/dist/isl_test_cpp.cc @@ -0,0 +1,381 @@ +/* Copyright 2016-2017 Tobias Grosser + * + * Use of this software is governed by the MIT license + * + * Written by Tobias Grosser, Weststrasse 47, CH-8003, Zurich + */ + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +static void die_impl(const char *file, int line, const char *message) +{ + fprintf(stderr, "Assertion failed in %s:%d %s\n", file, line, message); + exit(EXIT_FAILURE); +} + +static void assert_impl(bool condition, const char *file, int line, + const char *message) +{ + if (condition) + return; + + return die_impl(file, line, message); +} + +#define die(msg) die_impl(__FILE__, __LINE__, msg) +#undef assert +#define assert(exp) assert_impl(exp, __FILE__, __LINE__, #exp) + +#include "isl_test_cpp-generic.cc" + +/* Test that isl_bool values are returned correctly. + * + * In particular, check the conversion to bool in case of true and false, and + * exception throwing in case of error. + */ +static void test_return_bool(isl::ctx ctx) +{ + isl::set empty(ctx, "{ : false }"); + isl::set univ(ctx, "{ : }"); + isl::set null; + + bool b_true = empty.is_empty(); + bool b_false = univ.is_empty(); + bool caught = false; + try { + null.is_empty(); + die("no exception raised"); + } catch (const isl::exception_invalid &e) { + caught = true; + } + + assert(b_true); + assert(!b_false); + assert(caught); +} + +/* Test that return values are handled correctly. + * + * Test that isl C++ objects, integers, boolean values, and strings are + * returned correctly. + */ +static void test_return(isl::ctx ctx) +{ + test_return_obj(ctx); + test_return_int(ctx); + test_return_bool(ctx); + test_return_string(ctx); +} + +/* Test that foreach functions are modeled correctly. + * + * Verify that lambdas are correctly called as callback of a 'foreach' + * function and that variables captured by the lambda work correctly. Also + * check that the foreach function handles exceptions thrown from + * the lambda and that it propagates the exception. + */ +static void test_foreach(isl::ctx ctx) +{ + isl::set s(ctx, "{ [0]; [1]; [2] }"); + + std::vector basic_sets; + + auto add_to_vector = [&] (isl::basic_set bs) { + basic_sets.push_back(bs); + }; + + s.foreach_basic_set(add_to_vector); + + assert(basic_sets.size() == 3); + assert(isl::set(basic_sets[0]).is_subset(s)); + assert(isl::set(basic_sets[1]).is_subset(s)); + assert(isl::set(basic_sets[2]).is_subset(s)); + assert(!basic_sets[0].is_equal(basic_sets[1])); + + auto fail = [&] (isl::basic_set bs) { + throw "fail"; + }; + + bool caught = false; + try { + s.foreach_basic_set(fail); + die("no exception raised"); + } catch (char const *s) { + caught = true; + } + assert(caught); +} + +/* Test the functionality of "foreach_scc" functions. + * + * In particular, test it on a list of elements that can be completely sorted + * but where two of the elements ("a" and "b") are incomparable. + */ +static void test_foreach_scc(isl::ctx ctx) +{ + isl::multi_pw_aff id; + isl::id_list list(ctx, 3); + isl::id_list sorted(ctx, 3); + std::map data = { + { "a", isl::map(ctx, "{ [0] -> [1] }") }, + { "b", isl::map(ctx, "{ [1] -> [0] }") }, + { "c", isl::map(ctx, "{ [i = 0:1] -> [i] }") }, + }; + + for (const auto &kvp: data) + list = list.add(kvp.first); + id = data.at("a").space().domain().identity_multi_pw_aff_on_domain(); + list.foreach_scc([&data, &id] (isl::id a, isl::id b) { + auto map = data.at(b.name()).apply_domain(data.at(a.name())); + return !map.lex_ge_at(id).is_empty(); + }, [&sorted] (isl::id_list scc) { + assert(scc.size() == 1); + sorted = sorted.concat(scc); + }); + assert(sorted.size() == 3); + assert(sorted.at(0).name() == "b"); + assert(sorted.at(1).name() == "c"); + assert(sorted.at(2).name() == "a"); +} + +/* Test the functionality of "every" functions. + * + * In particular, test the generic functionality and + * test that exceptions are properly propagated. + */ +static void test_every(isl::ctx ctx) +{ + isl::union_set us(ctx, "{ A[i]; B[j] }"); + + test_every_generic(ctx); + + auto fail = [] (isl::set s) -> bool { + throw "fail"; + }; + bool caught = false; + try { + us.every_set(fail); + die("no exception raised"); + } catch (char const *s) { + caught = true; + } + assert(caught); +} + +/* Test that an exception is generated for an isl error and + * that the error message is captured by the exception. + * Also check that the exception can be copied and that copying + * does not throw any exceptions. + */ +static void test_exception(isl::ctx ctx) +{ + isl::multi_union_pw_aff mupa(ctx, "[]"); + isl::exception copy; + + static_assert(std::is_nothrow_copy_constructible::value, + "exceptions must be nothrow-copy-constructible"); + static_assert(std::is_nothrow_assignable::value, + "exceptions must be nothrow-assignable"); + + try { + auto umap = isl::union_map::from(mupa); + } catch (const isl::exception_unsupported &error) { + die("caught wrong exception"); + } catch (const isl::exception &error) { + assert(strstr(error.what(), "without explicit domain")); + copy = error; + } + assert(strstr(copy.what(), "without explicit domain")); +} + +/* Test basic schedule tree functionality. + * + * In particular, create a simple schedule tree and + * - perform some generic tests + * - test map_descendant_bottom_up in the failing case + * - test foreach_descendant_top_down + * - test every_descendant + */ +static void test_schedule_tree(isl::ctx ctx) +{ + auto root = test_schedule_tree_generic(ctx); + + auto fail_map = [](isl::schedule_node node) { + throw "fail"; + return node; + }; + auto caught = false; + try { + root.map_descendant_bottom_up(fail_map); + die("no exception raised"); + } catch (char const *s) { + caught = true; + } + assert(caught); + + int count = 0; + auto inc_count = [&count](isl::schedule_node node) { + count++; + return true; + }; + root.foreach_descendant_top_down(inc_count); + assert(count == 8); + + count = 0; + auto inc_count_once = [&count](isl::schedule_node node) { + count++; + return false; + }; + root.foreach_descendant_top_down(inc_count_once); + assert(count == 1); + + auto is_not_domain = [](isl::schedule_node node) { + return !node.isa(); + }; + assert(root.child(0).every_descendant(is_not_domain)); + assert(!root.every_descendant(is_not_domain)); + + auto fail = [](isl::schedule_node node) { + throw "fail"; + return true; + }; + caught = false; + try { + root.every_descendant(fail); + die("no exception raised"); + } catch (char const *s) { + caught = true; + } + assert(caught); + + auto domain = root.as().domain(); + auto filters = isl::union_set(ctx, "{}"); + auto collect_filters = [&filters](isl::schedule_node node) { + if (node.isa()) { + auto filter = node.as(); + filters = filters.unite(filter.filter()); + } + return true; + }; + root.every_descendant(collect_filters); + assert(domain.is_equal(filters)); +} + +/* Test basic AST generation from a schedule tree. + * + * In particular, create a simple schedule tree and + * - perform some generic tests + * - test at_each_domain in the failing case + */ +static void test_ast_build(isl::ctx ctx) +{ + auto schedule = test_ast_build_generic(ctx); + + bool do_fail = true; + int count_ast_fail = 0; + auto fail_inc_count_ast = + [&count_ast_fail, &do_fail](isl::ast_node node, + isl::ast_build build) { + count_ast_fail++; + if (do_fail) + throw "fail"; + return node; + }; + auto build = isl::ast_build(ctx); + build = build.set_at_each_domain(fail_inc_count_ast); + auto caught = false; + try { + auto ast = build.node_from(schedule); + } catch (char const *s) { + caught = true; + } + assert(caught); + assert(count_ast_fail > 0); + auto build_copy = build; + int count_ast = 0; + auto inc_count_ast = + [&count_ast](isl::ast_node node, isl::ast_build build) { + count_ast++; + return node; + }; + build_copy = build_copy.set_at_each_domain(inc_count_ast); + auto ast = build_copy.node_from(schedule); + assert(count_ast == 2); + count_ast_fail = 0; + do_fail = false; + ast = build.node_from(schedule); + assert(count_ast_fail == 2); +} + +/* Basic test of the templated interface. + * + * Intersecting the domain of an access relation + * with statement instances should be allowed, + * while intersecting the range with statement instances + * should result in a compile-time error. + */ +static void test_typed(isl::ctx ctx) +{ + struct ST {}; + struct AR {}; + isl::typed::map access(ctx, "{ S[i, j] -> A[i] }"); + isl::typed::set instances(ctx, "{ S[i, j] : 0 <= i, j < 10 }"); + +#ifndef COMPILE_ERROR + access.intersect_domain(instances); +#else + access.intersect_range(instances); +#endif +} + +/* Test the (unchecked) isl C++ interface + * + * This includes: + * - The isl C <-> C++ pointer interface + * - Object construction + * - Different parameter types + * - Different return types + * - Foreach functions + * - Foreach SCC function + * - Exceptions + * - Spaces + * - Schedule trees + * - AST generation + * - AST expression generation + * - Templated interface + */ +int main() +{ + isl_ctx *ctx = isl_ctx_alloc(); + + isl_options_set_on_error(ctx, ISL_ON_ERROR_ABORT); + + test_pointer(ctx); + test_constructors(ctx); + test_parameters(ctx); + test_return(ctx); + test_foreach(ctx); + test_foreach_scc(ctx); + test_every(ctx); + test_exception(ctx); + test_space(ctx); + test_schedule_tree(ctx); + test_ast_build(ctx); + test_ast_build_expr(ctx); + test_typed(ctx); + + isl_ctx_free(ctx); + + return EXIT_SUCCESS; +} diff --git a/external/mit/isl/dist/isl_test_cpp17-checked.cc b/external/mit/isl/dist/isl_test_cpp17-checked.cc new file mode 100644 index 000000000000..3c213987fe4d --- /dev/null +++ b/external/mit/isl/dist/isl_test_cpp17-checked.cc @@ -0,0 +1,41 @@ +#include + +#include +#include + +#include +#include + +/* Select the "checked" interface. + */ +namespace isl { using namespace checked; } + +/* Print an error message and abort. + */ +static void die_impl(const char *file, int line, const char *message) +{ + std::cerr << file << ":" << line << ": " << message << "\n"; + exit(EXIT_FAILURE); +} + +#define die(msg) die_impl(__FILE__, __LINE__, msg) + +#include "isl_test_cpp17-generic.cc" + +/* Test the C++17 specific features of the isl checked C++ interface + * + * In particular, test + * - id::try_user + */ +int main() +{ + isl_ctx *ctx = isl_ctx_alloc(); + + isl_options_set_on_error(ctx, ISL_ON_ERROR_ABORT); + + test_try_user(ctx); + + isl_ctx_free(ctx); + + return EXIT_SUCCESS; +} diff --git a/external/mit/isl/dist/isl_test_cpp17-generic.cc b/external/mit/isl/dist/isl_test_cpp17-generic.cc new file mode 100644 index 000000000000..c6b4bab7d439 --- /dev/null +++ b/external/mit/isl/dist/isl_test_cpp17-generic.cc @@ -0,0 +1,68 @@ +/* A class that sets a boolean when an object of the class gets destroyed. + */ +struct S { + S(bool *freed) : freed(freed) {} + ~S(); + + bool *freed; +}; + +/* S destructor. + * + * Set the boolean, a pointer to which was passed to the constructor. + */ +S::~S() +{ + *freed = true; +} + +/* Construct an isl::id with an S object attached that sets *freed + * when it gets destroyed. + */ +static isl::id construct_id(isl::ctx ctx, bool *freed) +{ + auto s = std::make_shared(freed); + isl::id id(ctx, "S", s); + return id; +} + +/* Test id::try_user. + * + * In particular, check that the object attached to an identifier + * can be retrieved again, that trying to retrieve an object of the wrong type + * or trying to retrieve an object when no object was attached fails. + * Furthermore, check that the object attached to an identifier + * gets properly freed. + */ +static void test_try_user(isl::ctx ctx) +{ + isl::id id(ctx, "test", 5); + isl::id id2(ctx, "test2"); + + auto maybe_int = id.try_user(); + auto maybe_s = id.try_user>(); + auto maybe_int2 = id2.try_user(); + + if (!maybe_int) + die("integer cannot be retrieved from isl::id"); + if (maybe_int.value() != 5) + die("wrong integer retrieved from isl::id"); + if (maybe_s) + die("structure unexpectedly retrieved from isl::id"); + if (maybe_int2) + die("integer unexpectedly retrieved from isl::id"); + + bool freed = false; + { + isl::id id = construct_id(ctx, &freed); + if (freed) + die("data structure freed prematurely"); + auto maybe_s = id.try_user>(); + if (!maybe_s) + die("structure cannot be retrieved from isl::id"); + if (maybe_s.value()->freed != &freed) + die("invalid structure retrieved from isl::id"); + } + if (!freed) + die("data structure not freed"); +} diff --git a/external/mit/isl/dist/isl_test_cpp17.cc b/external/mit/isl/dist/isl_test_cpp17.cc new file mode 100644 index 000000000000..5765a1f9ae0b --- /dev/null +++ b/external/mit/isl/dist/isl_test_cpp17.cc @@ -0,0 +1,78 @@ +#include + +#include +#include + +#include +#include + +/* Throw a runtime exception. + */ +static void die_impl(const char *file, int line, const char *message) +{ + std::ostringstream ss; + ss << file << ":" << line << ": " << message; + throw std::runtime_error(ss.str()); +} + +#define die(msg) die_impl(__FILE__, __LINE__, msg) + +#include "isl_test_cpp17-generic.cc" + +/* Check that an isl::exception_invalid gets thrown by "fn". + */ +static void check_invalid(const std::function &fn) +{ + bool caught = false; + try { + fn(); + } catch (const isl::exception_invalid &e) { + caught = true; + } + if (!caught) + die("no invalid exception was generated"); +} + +/* Test id::user. + * + * In particular, check that the object attached to an identifier + * can be retrieved again and that retrieving an object of the wrong type + * or retrieving an object when no object was attached results in an exception. + */ +static void test_user(isl::ctx ctx) +{ + isl::id id(ctx, "test", 5); + isl::id id2(ctx, "test2"); + isl::id id3(ctx, "test3", std::string("s")); + + auto int_user = id.user(); + if (int_user != 5) + die("wrong integer retrieved from isl::id"); + auto s_user = id3.user(); + if (s_user != "s") + die("wrong string retrieved from isl::id"); + check_invalid([&id] () { id.user(); }); + check_invalid([&id2] () { id2.user(); }); + check_invalid([&id2] () { id2.user(); }); + check_invalid([&id3] () { id3.user(); }); +} + +/* Test the C++17 specific features of the (unchecked) isl C++ interface + * + * In particular, test + * - id::try_user + * - id::user + */ +int main() +{ + isl_ctx *ctx = isl_ctx_alloc(); + + isl_options_set_on_error(ctx, ISL_ON_ERROR_ABORT); + + test_try_user(ctx); + test_user(ctx); + + isl_ctx_free(ctx); + + return EXIT_SUCCESS; +} diff --git a/external/mit/isl/dist/isl_test_cpp_failed.sh b/external/mit/isl/dist/isl_test_cpp_failed.sh new file mode 100755 index 000000000000..090a89ea842e --- /dev/null +++ b/external/mit/isl/dist/isl_test_cpp_failed.sh @@ -0,0 +1,8 @@ +#/bin/sh +# Check that isl_test_cpp_failed CANNOT be built. +# Note that the failed build may leave behind a temporary dependence +# tracking object, which should be removed. +make isl_test_cpp_failed +ret=$? +rm -f .deps/isl_test_cpp_failed-isl_test_cpp.Tpo +test $ret -ne 0 diff --git a/external/mit/isl/dist/isl_test_imath.c b/external/mit/isl/dist/isl_test_imath.c new file mode 100644 index 000000000000..2ac39ad32e5d --- /dev/null +++ b/external/mit/isl/dist/isl_test_imath.c @@ -0,0 +1,78 @@ +/* + * Copyright 2015 INRIA Paris-Rocquencourt + * + * Use of this software is governed by the MIT license + * + * Written by Michael Kruse, INRIA Paris-Rocquencourt, + * Domaine de Voluceau, Rocquenqourt, B.P. 105, + * 78153 Le Chesnay Cedex France + */ + +#include +#include +#include + +/* This constant is not defined in limits.h, but IMath uses it */ +#define ULONG_MIN 0ul + +/* Test the IMath internals assumed by the imath implementation of isl_int. + * + * In particular, we test the ranges of IMath-defined types. + * + * Also, isl uses the existence and function of imath's struct + * fields. The digits are stored with less significant digits at lower array + * indices. Where they are stored (on the heap or in the field 'single') does + * not matter. + */ +int test_imath_internals() +{ + mpz_t val; + mp_result retval; + + assert(sizeof(mp_small) == sizeof(long)); + assert(MP_SMALL_MIN == LONG_MIN); + assert(MP_SMALL_MAX == LONG_MAX); + + assert(sizeof(mp_usmall) == sizeof(unsigned long)); + assert(MP_USMALL_MAX == ULONG_MAX); + + retval = mp_int_init_value(&val, 0); + assert(retval == MP_OK); + assert(val.alloc >= val.used); + assert(val.used == 1); + assert(val.sign == MP_ZPOS); + assert(val.digits[0] == 0); + + retval = mp_int_set_value(&val, -1); + assert(retval == MP_OK); + assert(val.alloc >= val.used); + assert(val.used == 1); + assert(val.sign == MP_NEG); + assert(val.digits[0] == 1); + + retval = mp_int_set_value(&val, 1); + assert(retval == MP_OK); + assert(val.alloc >= val.used); + assert(val.used == 1); + assert(val.sign == MP_ZPOS); + assert(val.digits[0] == 1); + + retval = mp_int_mul_pow2(&val, sizeof(mp_digit) * CHAR_BIT, &val); + assert(retval == MP_OK); + assert(val.alloc >= val.used); + assert(val.used == 2); + assert(val.sign == MP_ZPOS); + assert(val.digits[0] == 0); + assert(val.digits[1] == 1); + + mp_int_clear(&val); + return 0; +} + +int main() +{ + if (test_imath_internals() < 0) + return -1; + + return 0; +} diff --git a/external/mit/isl/dist/isl_test_int.c b/external/mit/isl/dist/isl_test_int.c new file mode 100644 index 000000000000..a996411fd550 --- /dev/null +++ b/external/mit/isl/dist/isl_test_int.c @@ -0,0 +1,669 @@ +/* + * Copyright 2015 INRIA Paris-Rocquencourt + * + * Use of this software is governed by the MIT license + * + * Written by Michael Kruse, INRIA Paris-Rocquencourt, + * Domaine de Voluceau, Rocquenqourt, B.P. 105, + * 78153 Le Chesnay Cedex France + */ + +#include +#include +#include + +#define ARRAY_SIZE(array) (sizeof(array)/sizeof(*array)) + +#ifdef USE_SMALL_INT_OPT +/* Test whether small and big representation of the same number have the same + * hash. + */ +static void int_test_hash(isl_int val) +{ + uint32_t demotedhash, promotedhash; + isl_int demoted, promoted; + + isl_int_init(demoted); + isl_int_set(demoted, val); + + isl_int_init(promoted); + isl_int_set(promoted, val); + + isl_sioimath_try_demote(demoted); + isl_sioimath_promote(promoted); + + assert(isl_int_eq(demoted, promoted)); + + demotedhash = isl_int_hash(demoted, 0); + promotedhash = isl_int_hash(promoted, 0); + assert(demotedhash == promotedhash); + + isl_int_clear(demoted); + isl_int_clear(promoted); +} + +struct { + void (*fn)(isl_int); + char *val; +} int_single_value_tests[] = { + { &int_test_hash, "0" }, + { &int_test_hash, "1" }, + { &int_test_hash, "-1" }, + { &int_test_hash, "23" }, + { &int_test_hash, "-23" }, + { &int_test_hash, "107" }, + { &int_test_hash, "32768" }, + { &int_test_hash, "2147483647" }, + { &int_test_hash, "-2147483647" }, + { &int_test_hash, "2147483648" }, + { &int_test_hash, "-2147483648" }, +}; + +static void int_test_single_value() +{ + int i; + + for (i = 0; i < ARRAY_SIZE(int_single_value_tests); i += 1) { + isl_int val; + + isl_int_init(val); + isl_int_read(val, int_single_value_tests[i].val); + + (*int_single_value_tests[i].fn)(val); + + isl_int_clear(val); + } +} + +static void invoke_alternate_representations_2args(char *arg1, char *arg2, + void (*fn)(isl_int, isl_int)) +{ + int j; + isl_int int1, int2; + + isl_int_init(int1); + isl_int_init(int2); + + for (j = 0; j < 4; ++j) { + isl_int_read(int1, arg1); + isl_int_read(int2, arg2); + + if (j & 1) + isl_sioimath_promote(int1); + else + isl_sioimath_try_demote(int1); + + if (j & 2) + isl_sioimath_promote(int2); + else + isl_sioimath_try_demote(int2); + + (*fn)(int1, int2); + } + + isl_int_clear(int1); + isl_int_clear(int2); +} + +static void invoke_alternate_representations_3args(char *arg1, char *arg2, + char *arg3, void (*fn)(isl_int, isl_int, isl_int)) +{ + int j; + isl_int int1, int2, int3; + + isl_int_init(int1); + isl_int_init(int2); + isl_int_init(int3); + + for (j = 0; j < 8; ++j) { + isl_int_read(int1, arg1); + isl_int_read(int2, arg2); + isl_int_read(int3, arg3); + + if (j & 1) + isl_sioimath_promote(int1); + else + isl_sioimath_try_demote(int1); + + if (j & 2) + isl_sioimath_promote(int2); + else + isl_sioimath_try_demote(int2); + + if (j & 4) + isl_sioimath_promote(int3); + else + isl_sioimath_try_demote(int3); + + (*fn)(int1, int2, int3); + } + + isl_int_clear(int1); + isl_int_clear(int2); + isl_int_clear(int3); +} +#else /* USE_SMALL_INT_OPT */ + +static void int_test_single_value() +{ +} + +static void invoke_alternate_representations_2args(char *arg1, char *arg2, + void (*fn)(isl_int, isl_int)) +{ + isl_int int1, int2; + + isl_int_init(int1); + isl_int_init(int2); + + isl_int_read(int1, arg1); + isl_int_read(int2, arg2); + + (*fn)(int1, int2); + + isl_int_clear(int1); + isl_int_clear(int2); +} + +static void invoke_alternate_representations_3args(char *arg1, char *arg2, + char *arg3, void (*fn)(isl_int, isl_int, isl_int)) +{ + isl_int int1, int2, int3; + + isl_int_init(int1); + isl_int_init(int2); + isl_int_init(int3); + + isl_int_read(int1, arg1); + isl_int_read(int2, arg2); + isl_int_read(int3, arg3); + + (*fn)(int1, int2, int3); + + isl_int_clear(int1); + isl_int_clear(int2); + isl_int_clear(int3); +} +#endif /* USE_SMALL_INT_OPT */ + +static void int_test_neg(isl_int expected, isl_int arg) +{ + isl_int result; + isl_int_init(result); + + isl_int_neg(result, arg); + assert(isl_int_eq(result, expected)); + + isl_int_neg(result, expected); + assert(isl_int_eq(result, arg)); + + isl_int_clear(result); +} + +static void int_test_abs(isl_int expected, isl_int arg) +{ + isl_int result; + isl_int_init(result); + + isl_int_abs(result, arg); + assert(isl_int_eq(result, expected)); + + isl_int_clear(result); +} + +struct { + void (*fn)(isl_int, isl_int); + char *expected, *arg; +} int_unary_tests[] = { + { &int_test_neg, "0", "0" }, + { &int_test_neg, "-1", "1" }, + { &int_test_neg, "-2147483647", "2147483647" }, + { &int_test_neg, "-2147483648", "2147483648" }, + { &int_test_neg, "-9223372036854775807", "9223372036854775807" }, + { &int_test_neg, "-9223372036854775808", "9223372036854775808" }, + + { &int_test_abs, "0", "0" }, + { &int_test_abs, "1", "1" }, + { &int_test_abs, "1", "-1" }, + { &int_test_abs, "2147483647", "2147483647" }, + { &int_test_abs, "2147483648", "-2147483648" }, + { &int_test_abs, "9223372036854775807", "9223372036854775807" }, + { &int_test_abs, "9223372036854775808", "-9223372036854775808" }, +}; + +static void int_test_divexact(isl_int expected, isl_int lhs, isl_int rhs) +{ + isl_int result; + unsigned long rhsulong; + + if (isl_int_sgn(rhs) == 0) + return; + + isl_int_init(result); + + isl_int_divexact(result, lhs, rhs); + assert(isl_int_eq(expected, result)); + + isl_int_tdiv_q(result, lhs, rhs); + assert(isl_int_eq(expected, result)); + + isl_int_fdiv_q(result, lhs, rhs); + assert(isl_int_eq(expected, result)); + + isl_int_cdiv_q(result, lhs, rhs); + assert(isl_int_eq(expected, result)); + + if (isl_int_fits_ulong(rhs)) { + rhsulong = isl_int_get_ui(rhs); + + isl_int_divexact_ui(result, lhs, rhsulong); + assert(isl_int_eq(expected, result)); + + isl_int_fdiv_q_ui(result, lhs, rhsulong); + assert(isl_int_eq(expected, result)); + + isl_int_cdiv_q_ui(result, lhs, rhsulong); + assert(isl_int_eq(expected, result)); + } + + isl_int_clear(result); +} + +static void int_test_mul(isl_int expected, isl_int lhs, isl_int rhs) +{ + isl_int result; + isl_int_init(result); + + isl_int_mul(result, lhs, rhs); + assert(isl_int_eq(expected, result)); + + if (isl_int_fits_ulong(rhs)) { + unsigned long rhsulong = isl_int_get_ui(rhs); + + isl_int_mul_ui(result, lhs, rhsulong); + assert(isl_int_eq(expected, result)); + } + + if (isl_int_fits_slong(rhs)) { + unsigned long rhsslong = isl_int_get_si(rhs); + + isl_int_mul_si(result, lhs, rhsslong); + assert(isl_int_eq(expected, result)); + } + + isl_int_clear(result); +} + +/* Use a triple that satisfies 'product = factor1 * factor2' to check the + * operations mul, divexact, tdiv, fdiv and cdiv. + */ +static void int_test_product(isl_int product, isl_int factor1, isl_int factor2) +{ + int_test_divexact(factor1, product, factor2); + int_test_divexact(factor2, product, factor1); + + int_test_mul(product, factor1, factor2); + int_test_mul(product, factor2, factor1); +} + +static void int_test_add(isl_int expected, isl_int lhs, isl_int rhs) +{ + isl_int result; + isl_int_init(result); + + isl_int_add(result, lhs, rhs); + assert(isl_int_eq(expected, result)); + + isl_int_clear(result); +} + +static void int_test_sub(isl_int expected, isl_int lhs, isl_int rhs) +{ + isl_int result; + isl_int_init(result); + + isl_int_sub(result, lhs, rhs); + assert(isl_int_eq(expected, result)); + + isl_int_clear(result); +} + +/* Use a triple that satisfies 'sum = term1 + term2' to check the operations add + * and sub. + */ +static void int_test_sum(isl_int sum, isl_int term1, isl_int term2) +{ + int_test_sub(term1, sum, term2); + int_test_sub(term2, sum, term1); + + int_test_add(sum, term1, term2); + int_test_add(sum, term2, term1); +} + +static void int_test_fdiv(isl_int expected, isl_int lhs, isl_int rhs) +{ + unsigned long rhsulong; + isl_int result; + isl_int_init(result); + + isl_int_fdiv_q(result, lhs, rhs); + assert(isl_int_eq(expected, result)); + + if (isl_int_fits_ulong(rhs)) { + rhsulong = isl_int_get_ui(rhs); + + isl_int_fdiv_q_ui(result, lhs, rhsulong); + assert(isl_int_eq(expected, result)); + } + + isl_int_clear(result); +} + +static void int_test_cdiv(isl_int expected, isl_int lhs, isl_int rhs) +{ + unsigned long rhsulong; + isl_int result; + isl_int_init(result); + + isl_int_cdiv_q(result, lhs, rhs); + assert(isl_int_eq(expected, result)); + + if (isl_int_fits_ulong(rhs)) { + rhsulong = isl_int_get_ui(rhs); + + isl_int_cdiv_q_ui(result, lhs, rhsulong); + assert(isl_int_eq(expected, result)); + } + + isl_int_clear(result); +} + +static void int_test_tdiv(isl_int expected, isl_int lhs, isl_int rhs) +{ + isl_int result; + isl_int_init(result); + + isl_int_tdiv_q(result, lhs, rhs); + assert(isl_int_eq(expected, result)); + + isl_int_clear(result); +} + +static void int_test_fdiv_r(isl_int expected, isl_int lhs, isl_int rhs) +{ + isl_int result; + isl_int_init(result); + + isl_int_fdiv_r(result, lhs, rhs); + assert(isl_int_eq(expected, result)); + + isl_int_clear(result); +} + +static void int_test_gcd(isl_int expected, isl_int lhs, isl_int rhs) +{ + isl_int result; + isl_int_init(result); + + isl_int_gcd(result, lhs, rhs); + assert(isl_int_eq(expected, result)); + + isl_int_gcd(result, rhs, lhs); + assert(isl_int_eq(expected, result)); + + isl_int_clear(result); +} + +static void int_test_lcm(isl_int expected, isl_int lhs, isl_int rhs) +{ + isl_int result; + isl_int_init(result); + + isl_int_lcm(result, lhs, rhs); + assert(isl_int_eq(expected, result)); + + isl_int_lcm(result, rhs, lhs); + assert(isl_int_eq(expected, result)); + + isl_int_clear(result); +} + +static int sgn(int val) +{ + if (val > 0) + return 1; + if (val < 0) + return -1; + return 0; +} + +static void int_test_cmp(int exp, isl_int lhs, isl_int rhs) +{ + long rhslong; + + assert(exp == sgn(isl_int_cmp(lhs, rhs))); + + if (isl_int_fits_slong(rhs)) { + rhslong = isl_int_get_si(rhs); + assert(exp == sgn(isl_int_cmp_si(lhs, rhslong))); + } +} + +/* Test the comparison relations over two numbers. + * expected is the sign (1, 0 or -1) of 'lhs - rhs'. + */ +static void int_test_cmps(isl_int expected, isl_int lhs, isl_int rhs) +{ + int exp; + isl_int diff; + + exp = isl_int_get_si(expected); + + isl_int_init(diff); + isl_int_sub(diff, lhs, rhs); + assert(exp == isl_int_sgn(diff)); + isl_int_clear(diff); + + int_test_cmp(exp, lhs, rhs); + int_test_cmp(-exp, rhs, lhs); +} + +static void int_test_abs_cmp(isl_int expected, isl_int lhs, isl_int rhs) +{ + int exp; + + exp = isl_int_get_si(expected); + assert(exp == sgn(isl_int_abs_cmp(lhs, rhs))); + assert(-exp == sgn(isl_int_abs_cmp(rhs, lhs))); +} + +/* If "expected" is equal to 1, then check that "rhs" divides "lhs". + * If "expected" is equal to 0, then check that "rhs" does not divide "lhs". + */ +static void int_test_divisible(isl_int expected, isl_int lhs, isl_int rhs) +{ + int exp; + + exp = isl_int_get_si(expected); + assert(isl_int_is_divisible_by(lhs, rhs) == exp); +} + +struct { + void (*fn)(isl_int, isl_int, isl_int); + char *expected, *lhs, *rhs; +} int_binary_tests[] = { + { &int_test_sum, "0", "0", "0" }, + { &int_test_sum, "1", "1", "0" }, + { &int_test_sum, "2", "1", "1" }, + { &int_test_sum, "-1", "0", "-1" }, + { &int_test_sum, "-2", "-1", "-1" }, + + { &int_test_sum, "2147483647", "1073741823", "1073741824" }, + { &int_test_sum, "-2147483648", "-1073741824", "-1073741824" }, + + { &int_test_sum, "2147483648", "2147483647", "1" }, + { &int_test_sum, "-2147483648", "-2147483647", "-1" }, + + { &int_test_product, "0", "0", "0" }, + { &int_test_product, "0", "0", "1" }, + { &int_test_product, "1", "1", "1" }, + + { &int_test_product, "6", "2", "3" }, + { &int_test_product, "-6", "2", "-3" }, + { &int_test_product, "-6", "-2", "3" }, + { &int_test_product, "6", "-2", "-3" }, + + { &int_test_product, "2147483648", "65536", "32768" }, + { &int_test_product, "-2147483648", "65536", "-32768" }, + + { &int_test_product, + "4611686014132420609", "2147483647", "2147483647" }, + { &int_test_product, + "-4611686014132420609", "-2147483647", "2147483647" }, + + { &int_test_product, + "4611686016279904256", "2147483647", "2147483648" }, + { &int_test_product, + "-4611686016279904256", "-2147483647", "2147483648" }, + { &int_test_product, + "-4611686016279904256", "2147483647", "-2147483648" }, + { &int_test_product, + "4611686016279904256", "-2147483647", "-2147483648" }, + + { &int_test_product, "85070591730234615847396907784232501249", + "9223372036854775807", "9223372036854775807" }, + { &int_test_product, "-85070591730234615847396907784232501249", + "-9223372036854775807", "9223372036854775807" }, + + { &int_test_product, "85070591730234615856620279821087277056", + "9223372036854775807", "9223372036854775808" }, + { &int_test_product, "-85070591730234615856620279821087277056", + "-9223372036854775807", "9223372036854775808" }, + { &int_test_product, "-85070591730234615856620279821087277056", + "9223372036854775807", "-9223372036854775808" }, + { &int_test_product, "85070591730234615856620279821087277056", + "-9223372036854775807", "-9223372036854775808" }, + + { &int_test_product, "340282366920938463426481119284349108225", + "18446744073709551615", "18446744073709551615" }, + { &int_test_product, "-340282366920938463426481119284349108225", + "-18446744073709551615", "18446744073709551615" }, + + { &int_test_product, "340282366920938463444927863358058659840", + "18446744073709551615", "18446744073709551616" }, + { &int_test_product, "-340282366920938463444927863358058659840", + "-18446744073709551615", "18446744073709551616" }, + { &int_test_product, "-340282366920938463444927863358058659840", + "18446744073709551615", "-18446744073709551616" }, + { &int_test_product, "340282366920938463444927863358058659840", + "-18446744073709551615", "-18446744073709551616" }, + + { &int_test_fdiv, "0", "1", "2" }, + { &int_test_fdiv_r, "1", "1", "3" }, + { &int_test_fdiv, "-1", "-1", "2" }, + { &int_test_fdiv_r, "2", "-1", "3" }, + { &int_test_fdiv, "-1", "1", "-2" }, + { &int_test_fdiv_r, "-2", "1", "-3" }, + { &int_test_fdiv, "0", "-1", "-2" }, + { &int_test_fdiv_r, "-1", "-1", "-3" }, + + { &int_test_cdiv, "1", "1", "2" }, + { &int_test_cdiv, "0", "-1", "2" }, + { &int_test_cdiv, "0", "1", "-2" }, + { &int_test_cdiv, "1", "-1", "-2" }, + + { &int_test_cdiv, "1073741824", "2147483647", "2" }, + { &int_test_cdiv, "1073741824", "2147483648", "2" }, + { &int_test_cdiv, "-1073741824", "-2147483648", "2" }, + { &int_test_cdiv, "-1073741823", "-2147483647", "2" }, + + { &int_test_tdiv, "0", "1", "2" }, + { &int_test_tdiv, "0", "-1", "2" }, + { &int_test_tdiv, "0", "1", "-2" }, + { &int_test_tdiv, "0", "-1", "-2" }, + + { &int_test_gcd, "0", "0", "0" }, + { &int_test_lcm, "0", "0", "0" }, + { &int_test_gcd, "7", "0", "7" }, + { &int_test_lcm, "0", "0", "7" }, + { &int_test_gcd, "1", "1", "1" }, + { &int_test_lcm, "1", "1", "1" }, + { &int_test_gcd, "1", "1", "-1" }, + { &int_test_lcm, "1", "1", "-1" }, + { &int_test_gcd, "1", "-1", "-1" }, + { &int_test_lcm, "1", "-1", "-1" }, + { &int_test_gcd, "3", "6", "9" }, + { &int_test_lcm, "18", "6", "9" }, + { &int_test_gcd, "1", "14", "2147483647" }, + { &int_test_lcm, "15032385529", "7", "2147483647" }, + { &int_test_gcd, "2", "6", "-2147483648" }, + { &int_test_lcm, "6442450944", "6", "-2147483648" }, + { &int_test_gcd, "1", "6", "9223372036854775807" }, + { &int_test_lcm, "55340232221128654842", "6", "9223372036854775807" }, + { &int_test_gcd, "2", "6", "-9223372036854775808" }, + { &int_test_lcm, "27670116110564327424", "6", "-9223372036854775808" }, + { &int_test_gcd, "1", "18446744073709551616", "18446744073709551615" }, + { &int_test_lcm, "340282366920938463444927863358058659840", + "18446744073709551616", "18446744073709551615" }, + + { &int_test_cmps, "0", "0", "0" }, + { &int_test_abs_cmp, "0", "0", "0" }, + { &int_test_cmps, "1", "1", "0" }, + { &int_test_abs_cmp, "1", "1", "0" }, + { &int_test_cmps, "-1", "-1", "0" }, + { &int_test_abs_cmp, "1", "-1", "0" }, + { &int_test_cmps, "-1", "-1", "1" }, + { &int_test_abs_cmp, "0", "-1", "1" }, + + { &int_test_cmps, "-1", "5", "2147483647" }, + { &int_test_abs_cmp, "-1", "5", "2147483647" }, + { &int_test_cmps, "1", "5", "-2147483648" }, + { &int_test_abs_cmp, "-1", "5", "-2147483648" }, + { &int_test_cmps, "-1", "5", "9223372036854775807" }, + { &int_test_abs_cmp, "-1", "5", "9223372036854775807" }, + { &int_test_cmps, "1", "5", "-9223372036854775809" }, + { &int_test_abs_cmp, "-1", "5", "-9223372036854775809" }, + + { &int_test_divisible, "1", "0", "0" }, + { &int_test_divisible, "0", "1", "0" }, + { &int_test_divisible, "0", "2", "0" }, + { &int_test_divisible, "0", "2147483647", "0" }, + { &int_test_divisible, "0", "9223372036854775807", "0" }, + { &int_test_divisible, "1", "0", "1" }, + { &int_test_divisible, "1", "1", "1" }, + { &int_test_divisible, "1", "2", "1" }, + { &int_test_divisible, "1", "2147483647", "1" }, + { &int_test_divisible, "1", "9223372036854775807", "1" }, + { &int_test_divisible, "1", "0", "2" }, + { &int_test_divisible, "0", "1", "2" }, + { &int_test_divisible, "1", "2", "2" }, + { &int_test_divisible, "0", "2147483647", "2" }, + { &int_test_divisible, "0", "9223372036854775807", "2" }, +}; + +/* Tests the isl_int_* function to give the expected results. Tests are + * grouped by the number of arguments they take. + * + * If small integer optimization is enabled, we also test whether the results + * are the same in small and big representation. + */ +int main() +{ + int i; + + int_test_single_value(); + + for (i = 0; i < ARRAY_SIZE(int_unary_tests); i += 1) { + invoke_alternate_representations_2args( + int_unary_tests[i].expected, int_unary_tests[i].arg, + int_unary_tests[i].fn); + } + + for (i = 0; i < ARRAY_SIZE(int_binary_tests); i += 1) { + invoke_alternate_representations_3args( + int_binary_tests[i].expected, int_binary_tests[i].lhs, + int_binary_tests[i].rhs, int_binary_tests[i].fn); + } + + return 0; +} diff --git a/external/mit/isl/dist/isl_test_list_templ.c b/external/mit/isl/dist/isl_test_list_templ.c new file mode 100644 index 000000000000..fa5cb32ff638 --- /dev/null +++ b/external/mit/isl/dist/isl_test_list_templ.c @@ -0,0 +1,51 @@ +#define xCAT(A,B) A ## B +#define CAT(A,B) xCAT(A,B) +#define xFN(TYPE,NAME) TYPE ## _ ## NAME +#define FN(TYPE,NAME) xFN(TYPE,NAME) +#define xLIST(EL) EL ## _list +#define LIST(EL) xLIST(EL) + +#undef SET +#define SET CAT(isl_,SET_BASE) +#undef EL +#define EL CAT(isl_,EL_BASE) + +/* Check that the conversion from SET to list of EL works as expected, + * using input described by "str". + */ +static isl_stat FN(FN(FN(test_get_list,EL_BASE),from),SET_BASE)(isl_ctx *ctx, + const char *str) +{ + int i; + isl_size n; + isl_bool equal; + SET *set, *set2; + LIST(EL) *list; + + set = FN(SET,read_from_str)(ctx, str); + list = FN(FN(SET,get),LIST(EL_BASE))(set); + + set2 = FN(SET,empty)(FN(SET,get_space)(set)); + + n = FN(LIST(EL),size)(list); + for (i = 0; i < n; i++) { + EL *el; + el = FN(LIST(EL),get_at)(list, i); + set2 = FN(SET,union)(set2, FN(FN(SET,from),EL_BASE)(el)); + } + + equal = FN(SET,is_equal)(set, set2); + + FN(SET,free)(set); + FN(SET,free)(set2); + FN(LIST(EL),free)(list); + + if (n < 0 || equal < 0) + return isl_stat_error; + + if (!equal) + isl_die(ctx, isl_error_unknown, "collections are not equal", + return isl_stat_error); + + return isl_stat_ok; +} diff --git a/external/mit/isl/dist/isl_test_plain_equal_templ.c b/external/mit/isl/dist/isl_test_plain_equal_templ.c new file mode 100644 index 000000000000..5acbf1e85450 --- /dev/null +++ b/external/mit/isl/dist/isl_test_plain_equal_templ.c @@ -0,0 +1,50 @@ +/* + * Copyright 2012 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 + */ + +#define xCAT(A,B) A ## B +#define CAT(A,B) xCAT(A,B) +#undef TYPE +#define TYPE CAT(isl_,BASE) +#define xFN(TYPE,NAME) TYPE ## _ ## NAME +#define FN(TYPE,NAME) xFN(TYPE,NAME) + +/* Is "obj" obviously equal to the object represented by "str"? + */ +static isl_bool FN(BASE,plain_is_equal)(__isl_keep TYPE *obj, const char *str) +{ + isl_ctx *ctx; + TYPE *obj2; + isl_bool equal; + + if (!obj) + return isl_bool_error; + + ctx = FN(TYPE,get_ctx)(obj); + obj2 = FN(TYPE,read_from_str)(ctx, str); + equal = FN(TYPE,plain_is_equal)(obj, obj2); + FN(TYPE,free)(obj2); + + return equal; +} + +/* Check that "obj" is obviously equal to the object represented by "str". + */ +static isl_stat FN(BASE,check_plain_equal)(__isl_keep TYPE *obj, + const char *str) +{ + isl_bool equal; + + equal = FN(BASE,plain_is_equal)(obj, str); + if (equal < 0) + return isl_stat_error; + if (!equal) + isl_die(FN(TYPE,get_ctx)(obj), isl_error_unknown, + "result not as expected", return isl_stat_error); + return isl_stat_ok; +} diff --git a/external/mit/isl/dist/isl_test_python.py b/external/mit/isl/dist/isl_test_python.py new file mode 100755 index 000000000000..3894ad1cced9 --- /dev/null +++ b/external/mit/isl/dist/isl_test_python.py @@ -0,0 +1,504 @@ +# 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 +# - construction of empty union set +# +# 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)) + + us = isl.union_set("{ A[1]; B[2, 3] }") + empty = isl.union_set.empty() + assert(us.is_equal(us.union(empty))) + +# 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() + +# A class that is used to test isl.id.user. +# +class S: + def __init__(self): + self.value = 42 + +# Test isl.id.user. +# +# In particular, check that the object attached to an identifier +# can be retrieved again. +# +def test_user(): + id = isl.id("test", 5) + id2 = isl.id("test2") + id3 = isl.id("S", S()) + assert id.user() == 5, f"unexpected user object {id.user()}" + assert id2.user() is None, f"unexpected user object {id2.user()}" + s = id3.user() + assert isinstance(s, S), f"unexpected user object {s}" + assert s.value == 42, f"unexpected user object {s}" + +# 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 Exception("fail") + + caught = False + try: + s.foreach_basic_set(fail) + except: + caught = True + assert(caught) + +# Test the functionality of "foreach_scc" functions. +# +# In particular, test it on a list of elements that can be completely sorted +# but where two of the elements ("a" and "b") are incomparable. +# +def test_foreach_scc(): + list = isl.id_list(3) + sorted = [isl.id_list(3)] + data = { + 'a' : isl.map("{ [0] -> [1] }"), + 'b' : isl.map("{ [1] -> [0] }"), + 'c' : isl.map("{ [i = 0:1] -> [i] }"), + } + for k, v in data.items(): + list = list.add(k) + id = data['a'].space().domain().identity_multi_pw_aff_on_domain() + def follows(a, b): + map = data[b.name()].apply_domain(data[a.name()]) + return not map.lex_ge_at(id).is_empty() + + def add_single(scc): + assert(scc.size() == 1) + sorted[0] = sorted[0].concat(scc) + + list.foreach_scc(follows, add_single) + assert(sorted[0].size() == 3) + assert(sorted[0].at(0).name() == "b") + assert(sorted[0].at(1).name() == "c") + assert(sorted[0].at(2).name() == "a") + +# Test the functionality of "every" functions. +# +# In particular, test the generic functionality and +# test that exceptions are properly propagated. +# +def test_every(): + us = isl.union_set("{ A[i]; B[j] }") + + def is_empty(s): + return s.is_empty() + assert(not us.every_set(is_empty)) + + def is_non_empty(s): + return not s.is_empty() + assert(us.every_set(is_non_empty)) + + def in_A(s): + return s.is_subset(isl.set("{ A[x] }")) + assert(not us.every_set(in_A)) + + def not_in_A(s): + return not s.is_subset(isl.set("{ A[x] }")) + assert(not us.every_set(not_in_A)) + + def fail(s): + raise Exception("fail") + + caught = False + try: + us.ever_set(fail) + except: + caught = True + assert(caught) + +# Check basic construction of spaces. +# +def test_space(): + unit = isl.space.unit() + set_space = unit.add_named_tuple("A", 3) + map_space = set_space.add_named_tuple("B", 2) + + set = isl.set.universe(set_space) + map = isl.map.universe(map_space) + assert(set.is_equal(isl.set("{ A[*,*,*] }"))) + assert(map.is_equal(isl.map("{ A[*,*,*] -> B[*,*] }"))) + +# Construct a simple schedule tree with an outer sequence node and +# a single-dimensional band node in each branch, with one of them +# marked coincident. +# +def construct_schedule_tree(): + A = isl.union_set("{ A[i] : 0 <= i < 10 }") + B = isl.union_set("{ B[i] : 0 <= i < 20 }") + + node = isl.schedule_node.from_domain(A.union(B)) + node = node.child(0) + + filters = isl.union_set_list(A).add(B) + node = node.insert_sequence(filters) + + f_A = isl.multi_union_pw_aff("[ { A[i] -> [i] } ]") + node = node.child(0) + node = node.child(0) + node = node.insert_partial_schedule(f_A) + node = node.member_set_coincident(0, True) + node = node.ancestor(2) + + f_B = isl.multi_union_pw_aff("[ { B[i] -> [i] } ]") + node = node.child(1) + node = node.child(0) + node = node.insert_partial_schedule(f_B) + node = node.ancestor(2) + + return node.schedule() + +# Test basic schedule tree functionality. +# +# In particular, create a simple schedule tree and +# - check that the root node is a domain node +# - test map_descendant_bottom_up +# - test foreach_descendant_top_down +# - test every_descendant +# +def test_schedule_tree(): + schedule = construct_schedule_tree() + root = schedule.root() + + assert(type(root) == isl.schedule_node_domain) + + count = [0] + def inc_count(node): + count[0] += 1 + return node + root = root.map_descendant_bottom_up(inc_count) + assert(count[0] == 8) + + def fail_map(node): + raise Exception("fail") + return node + caught = False + try: + root.map_descendant_bottom_up(fail_map) + except: + caught = True + assert(caught) + + count = [0] + def inc_count(node): + count[0] += 1 + return True + root.foreach_descendant_top_down(inc_count) + assert(count[0] == 8) + + count = [0] + def inc_count(node): + count[0] += 1 + return False + root.foreach_descendant_top_down(inc_count) + assert(count[0] == 1) + + def is_not_domain(node): + return type(node) != isl.schedule_node_domain + assert(root.child(0).every_descendant(is_not_domain)) + assert(not root.every_descendant(is_not_domain)) + + def fail(node): + raise Exception("fail") + caught = False + try: + root.every_descendant(fail) + except: + caught = True + assert(caught) + + domain = root.domain() + filters = [isl.union_set("{}")] + def collect_filters(node): + if type(node) == isl.schedule_node_filter: + filters[0] = filters[0].union(node.filter()) + return True + root.every_descendant(collect_filters) + assert(domain.is_equal(filters[0])) + +# Test marking band members for unrolling. +# "schedule" is the schedule created by construct_schedule_tree. +# It schedules two statements, with 10 and 20 instances, respectively. +# Unrolling all band members therefore results in 30 at-domain calls +# by the AST generator. +# +def test_ast_build_unroll(schedule): + root = schedule.root() + def mark_unroll(node): + if type(node) == isl.schedule_node_band: + node = node.member_set_ast_loop_unroll(0) + return node + root = root.map_descendant_bottom_up(mark_unroll) + schedule = root.schedule() + + count_ast = [0] + def inc_count_ast(node, build): + count_ast[0] += 1 + return node + + build = isl.ast_build() + build = build.set_at_each_domain(inc_count_ast) + ast = build.node_from(schedule) + assert(count_ast[0] == 30) + +# Test basic AST generation from a schedule tree. +# +# In particular, create a simple schedule tree and +# - generate an AST from the schedule tree +# - test at_each_domain +# - test unrolling +# +def test_ast_build(): + schedule = construct_schedule_tree() + + count_ast = [0] + def inc_count_ast(node, build): + count_ast[0] += 1 + return node + + build = isl.ast_build() + build_copy = build.set_at_each_domain(inc_count_ast) + ast = build.node_from(schedule) + assert(count_ast[0] == 0) + count_ast[0] = 0 + ast = build_copy.node_from(schedule) + assert(count_ast[0] == 2) + build = build_copy + count_ast[0] = 0 + ast = build.node_from(schedule) + assert(count_ast[0] == 2) + + do_fail = True + count_ast_fail = [0] + def fail_inc_count_ast(node, build): + count_ast_fail[0] += 1 + if do_fail: + raise Exception("fail") + return node + build = isl.ast_build() + build = build.set_at_each_domain(fail_inc_count_ast) + caught = False + try: + ast = build.node_from(schedule) + except: + caught = True + assert(caught) + assert(count_ast_fail[0] > 0) + build_copy = build + build_copy = build_copy.set_at_each_domain(inc_count_ast) + count_ast[0] = 0 + ast = build_copy.node_from(schedule) + assert(count_ast[0] == 2) + count_ast_fail[0] = 0 + do_fail = False + ast = build.node_from(schedule) + assert(count_ast_fail[0] == 2) + + test_ast_build_unroll(schedule) + +# Test basic AST expression generation from an affine expression. +# +def test_ast_build_expr(): + pa = isl.pw_aff("[n] -> { [n + 1] }") + build = isl.ast_build.from_context(pa.domain()) + + op = build.expr_from(pa) + assert(type(op) == isl.ast_expr_op_add) + assert(op.n_arg() == 2) + +# Test the isl Python interface +# +# This includes: +# - Object construction +# - Different parameter types +# - Different return types +# - isl.id.user +# - Foreach functions +# - Foreach SCC function +# - Every functions +# - Spaces +# - Schedule trees +# - AST generation +# - AST expression generation +# +test_constructors() +test_parameters() +test_return() +test_user() +test_foreach() +test_foreach_scc() +test_every() +test_space() +test_schedule_tree() +test_ast_build() +test_ast_build_expr() diff --git a/external/mit/isl/dist/isl_transitive_closure.c b/external/mit/isl/dist/isl_transitive_closure.c new file mode 100644 index 000000000000..2733cee563d4 --- /dev/null +++ b/external/mit/isl/dist/isl_transitive_closure.c @@ -0,0 +1,2947 @@ +/* + * Copyright 2010 INRIA Saclay + * + * 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 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +isl_bool isl_map_is_transitively_closed(__isl_keep isl_map *map) +{ + isl_map *map2; + isl_bool closed; + + map2 = isl_map_apply_range(isl_map_copy(map), isl_map_copy(map)); + closed = isl_map_is_subset(map2, map); + isl_map_free(map2); + + return closed; +} + +isl_bool isl_union_map_is_transitively_closed(__isl_keep isl_union_map *umap) +{ + isl_union_map *umap2; + isl_bool closed; + + umap2 = isl_union_map_apply_range(isl_union_map_copy(umap), + isl_union_map_copy(umap)); + closed = isl_union_map_is_subset(umap2, umap); + isl_union_map_free(umap2); + + return closed; +} + +/* Given a map that represents a path with the length of the path + * encoded as the difference between the last output coordindate + * and the last input coordinate, set this length to either + * exactly "length" (if "exactly" is set) or at least "length" + * (if "exactly" is not set). + */ +static __isl_give isl_map *set_path_length(__isl_take isl_map *map, + int exactly, int length) +{ + isl_space *space; + struct isl_basic_map *bmap; + isl_size d; + isl_size nparam; + isl_size total; + int k; + isl_int *c; + + if (!map) + return NULL; + + space = isl_map_get_space(map); + d = isl_space_dim(space, isl_dim_in); + nparam = isl_space_dim(space, isl_dim_param); + total = isl_space_dim(space, isl_dim_all); + if (d < 0 || nparam < 0 || total < 0) + space = isl_space_free(space); + bmap = isl_basic_map_alloc_space(space, 0, 1, 1); + if (exactly) { + k = isl_basic_map_alloc_equality(bmap); + if (k < 0) + goto error; + c = bmap->eq[k]; + } else { + k = isl_basic_map_alloc_inequality(bmap); + if (k < 0) + goto error; + c = bmap->ineq[k]; + } + isl_seq_clr(c, 1 + total); + isl_int_set_si(c[0], -length); + isl_int_set_si(c[1 + nparam + d - 1], -1); + isl_int_set_si(c[1 + nparam + d + d - 1], 1); + + bmap = isl_basic_map_finalize(bmap); + map = isl_map_intersect(map, isl_map_from_basic_map(bmap)); + + return map; +error: + isl_basic_map_free(bmap); + isl_map_free(map); + return NULL; +} + +/* Check whether the overapproximation of the power of "map" is exactly + * the power of "map". Let R be "map" and A_k the overapproximation. + * The approximation is exact if + * + * A_1 = R + * A_k = A_{k-1} \circ R k >= 2 + * + * Since A_k is known to be an overapproximation, we only need to check + * + * A_1 \subset R + * A_k \subset A_{k-1} \circ R k >= 2 + * + * In practice, "app" has an extra input and output coordinate + * to encode the length of the path. So, we first need to add + * this coordinate to "map" and set the length of the path to + * one. + */ +static isl_bool check_power_exactness(__isl_take isl_map *map, + __isl_take isl_map *app) +{ + isl_bool exact; + isl_map *app_1; + isl_map *app_2; + + map = isl_map_add_dims(map, isl_dim_in, 1); + map = isl_map_add_dims(map, isl_dim_out, 1); + map = set_path_length(map, 1, 1); + + app_1 = set_path_length(isl_map_copy(app), 1, 1); + + exact = isl_map_is_subset(app_1, map); + isl_map_free(app_1); + + if (!exact || exact < 0) { + isl_map_free(app); + isl_map_free(map); + return exact; + } + + app_1 = set_path_length(isl_map_copy(app), 0, 1); + app_2 = set_path_length(app, 0, 2); + app_1 = isl_map_apply_range(map, app_1); + + exact = isl_map_is_subset(app_2, app_1); + + isl_map_free(app_1); + isl_map_free(app_2); + + return exact; +} + +/* Check whether the overapproximation of the power of "map" is exactly + * the power of "map", possibly after projecting out the power (if "project" + * is set). + * + * If "project" is set and if "steps" can only result in acyclic paths, + * then we check + * + * A = R \cup (A \circ R) + * + * where A is the overapproximation with the power projected out, i.e., + * an overapproximation of the transitive closure. + * More specifically, since A is known to be an overapproximation, we check + * + * A \subset R \cup (A \circ R) + * + * Otherwise, we check if the power is exact. + * + * Note that "app" has an extra input and output coordinate to encode + * the length of the part. If we are only interested in the transitive + * closure, then we can simply project out these coordinates first. + */ +static isl_bool check_exactness(__isl_take isl_map *map, + __isl_take isl_map *app, int project) +{ + isl_map *test; + isl_bool exact; + isl_size d; + + if (!project) + return check_power_exactness(map, app); + + d = isl_map_dim(map, isl_dim_in); + if (d < 0) + app = isl_map_free(app); + app = set_path_length(app, 0, 1); + app = isl_map_project_out(app, isl_dim_in, d, 1); + app = isl_map_project_out(app, isl_dim_out, d, 1); + + app = isl_map_reset_space(app, isl_map_get_space(map)); + + test = isl_map_apply_range(isl_map_copy(map), isl_map_copy(app)); + test = isl_map_union(test, isl_map_copy(map)); + + exact = isl_map_is_subset(app, test); + + isl_map_free(app); + isl_map_free(test); + + isl_map_free(map); + + return exact; +} + +/* + * The transitive closure implementation is based on the paper + * "Computing the Transitive Closure of a Union of Affine Integer + * Tuple Relations" by Anna Beletska, Denis Barthou, Wlodzimierz Bielecki and + * Albert Cohen. + */ + +/* Given a set of n offsets v_i (the rows of "steps"), construct a relation + * of the given dimension specification (Z^{n+1} -> Z^{n+1}) + * that maps an element x to any element that can be reached + * by taking a non-negative number of steps along any of + * the extended offsets v'_i = [v_i 1]. + * That is, construct + * + * { [x] -> [y] : exists k_i >= 0, y = x + \sum_i k_i v'_i } + * + * For any element in this relation, the number of steps taken + * is equal to the difference in the final coordinates. + */ +static __isl_give isl_map *path_along_steps(__isl_take isl_space *space, + __isl_keep isl_mat *steps) +{ + int i, j, k; + struct isl_basic_map *path = NULL; + isl_size d; + unsigned n; + isl_size nparam; + isl_size total; + + d = isl_space_dim(space, isl_dim_in); + nparam = isl_space_dim(space, isl_dim_param); + if (d < 0 || nparam < 0 || !steps) + goto error; + + n = steps->n_row; + + path = isl_basic_map_alloc_space(isl_space_copy(space), n, d, n); + + for (i = 0; i < n; ++i) { + k = isl_basic_map_alloc_div(path); + if (k < 0) + goto error; + isl_assert(steps->ctx, i == k, goto error); + isl_int_set_si(path->div[k][0], 0); + } + + total = isl_basic_map_dim(path, isl_dim_all); + if (total < 0) + goto error; + for (i = 0; i < d; ++i) { + k = isl_basic_map_alloc_equality(path); + if (k < 0) + goto error; + isl_seq_clr(path->eq[k], 1 + total); + isl_int_set_si(path->eq[k][1 + nparam + i], 1); + isl_int_set_si(path->eq[k][1 + nparam + d + i], -1); + if (i == d - 1) + for (j = 0; j < n; ++j) + isl_int_set_si(path->eq[k][1 + nparam + 2 * d + j], 1); + else + for (j = 0; j < n; ++j) + isl_int_set(path->eq[k][1 + nparam + 2 * d + j], + steps->row[j][i]); + } + + for (i = 0; i < n; ++i) { + k = isl_basic_map_alloc_inequality(path); + if (k < 0) + goto error; + isl_seq_clr(path->ineq[k], 1 + total); + isl_int_set_si(path->ineq[k][1 + nparam + 2 * d + i], 1); + } + + isl_space_free(space); + + path = isl_basic_map_simplify(path); + path = isl_basic_map_finalize(path); + return isl_map_from_basic_map(path); +error: + isl_space_free(space); + isl_basic_map_free(path); + return NULL; +} + +#define IMPURE 0 +#define PURE_PARAM 1 +#define PURE_VAR 2 +#define MIXED 3 + +/* Check whether the parametric constant term of constraint c is never + * positive in "bset". + */ +static isl_bool parametric_constant_never_positive( + __isl_keep isl_basic_set *bset, isl_int *c, int *div_purity) +{ + isl_size d; + isl_size n_div; + isl_size nparam; + isl_size total; + int i; + int k; + isl_bool empty; + + n_div = isl_basic_set_dim(bset, isl_dim_div); + d = isl_basic_set_dim(bset, isl_dim_set); + nparam = isl_basic_set_dim(bset, isl_dim_param); + total = isl_basic_set_dim(bset, isl_dim_all); + if (n_div < 0 || d < 0 || nparam < 0 || total < 0) + return isl_bool_error; + + bset = isl_basic_set_copy(bset); + bset = isl_basic_set_cow(bset); + bset = isl_basic_set_extend_constraints(bset, 0, 1); + k = isl_basic_set_alloc_inequality(bset); + if (k < 0) + goto error; + isl_seq_clr(bset->ineq[k], 1 + total); + isl_seq_cpy(bset->ineq[k], c, 1 + nparam); + for (i = 0; i < n_div; ++i) { + if (div_purity[i] != PURE_PARAM) + continue; + isl_int_set(bset->ineq[k][1 + nparam + d + i], + c[1 + nparam + d + i]); + } + isl_int_sub_ui(bset->ineq[k][0], bset->ineq[k][0], 1); + empty = isl_basic_set_is_empty(bset); + isl_basic_set_free(bset); + + return empty; +error: + isl_basic_set_free(bset); + return isl_bool_error; +} + +/* Return PURE_PARAM if only the coefficients of the parameters are non-zero. + * Return PURE_VAR if only the coefficients of the set variables are non-zero. + * Return MIXED if only the coefficients of the parameters and the set + * variables are non-zero and if moreover the parametric constant + * can never attain positive values. + * Return IMPURE otherwise. + */ +static int purity(__isl_keep isl_basic_set *bset, isl_int *c, int *div_purity, + int eq) +{ + isl_size d; + isl_size n_div; + isl_size nparam; + isl_bool empty; + int i; + int p = 0, v = 0; + + n_div = isl_basic_set_dim(bset, isl_dim_div); + d = isl_basic_set_dim(bset, isl_dim_set); + nparam = isl_basic_set_dim(bset, isl_dim_param); + if (n_div < 0 || d < 0 || nparam < 0) + return -1; + + for (i = 0; i < n_div; ++i) { + if (isl_int_is_zero(c[1 + nparam + d + i])) + continue; + switch (div_purity[i]) { + case PURE_PARAM: p = 1; break; + case PURE_VAR: v = 1; break; + default: return IMPURE; + } + } + if (!p && isl_seq_first_non_zero(c + 1, nparam) == -1) + return PURE_VAR; + if (!v && isl_seq_first_non_zero(c + 1 + nparam, d) == -1) + return PURE_PARAM; + + empty = parametric_constant_never_positive(bset, c, div_purity); + if (eq && empty >= 0 && !empty) { + isl_seq_neg(c, c, 1 + nparam + d + n_div); + empty = parametric_constant_never_positive(bset, c, div_purity); + } + + return empty < 0 ? -1 : empty ? MIXED : IMPURE; +} + +/* Return an array of integers indicating the type of each div in bset. + * If the div is (recursively) defined in terms of only the parameters, + * then the type is PURE_PARAM. + * If the div is (recursively) defined in terms of only the set variables, + * then the type is PURE_VAR. + * Otherwise, the type is IMPURE. + */ +static __isl_give int *get_div_purity(__isl_keep isl_basic_set *bset) +{ + int i, j; + int *div_purity; + isl_size d; + isl_size n_div; + isl_size nparam; + + n_div = isl_basic_set_dim(bset, isl_dim_div); + d = isl_basic_set_dim(bset, isl_dim_set); + nparam = isl_basic_set_dim(bset, isl_dim_param); + if (n_div < 0 || d < 0 || nparam < 0) + return NULL; + + div_purity = isl_alloc_array(bset->ctx, int, n_div); + if (n_div && !div_purity) + return NULL; + + for (i = 0; i < bset->n_div; ++i) { + int p = 0, v = 0; + if (isl_int_is_zero(bset->div[i][0])) { + div_purity[i] = IMPURE; + continue; + } + if (isl_seq_first_non_zero(bset->div[i] + 2, nparam) != -1) + p = 1; + if (isl_seq_first_non_zero(bset->div[i] + 2 + nparam, d) != -1) + v = 1; + for (j = 0; j < i; ++j) { + if (isl_int_is_zero(bset->div[i][2 + nparam + d + j])) + continue; + switch (div_purity[j]) { + case PURE_PARAM: p = 1; break; + case PURE_VAR: v = 1; break; + default: p = v = 1; break; + } + } + div_purity[i] = v ? p ? IMPURE : PURE_VAR : PURE_PARAM; + } + + return div_purity; +} + +/* Given a path with the as yet unconstrained length at div position "pos", + * check if setting the length to zero results in only the identity + * mapping. + */ +static isl_bool empty_path_is_identity(__isl_keep isl_basic_map *path, + unsigned pos) +{ + isl_basic_map *test = NULL; + isl_basic_map *id = NULL; + isl_bool is_id; + + test = isl_basic_map_copy(path); + test = isl_basic_map_fix_si(test, isl_dim_div, pos, 0); + id = isl_basic_map_identity(isl_basic_map_get_space(path)); + is_id = isl_basic_map_is_equal(test, id); + isl_basic_map_free(test); + isl_basic_map_free(id); + return is_id; +} + +/* If any of the constraints is found to be impure then this function + * sets *impurity to 1. + * + * If impurity is NULL then we are dealing with a non-parametric set + * and so the constraints are obviously PURE_VAR. + */ +static __isl_give isl_basic_map *add_delta_constraints( + __isl_take isl_basic_map *path, + __isl_keep isl_basic_set *delta, unsigned off, unsigned nparam, + unsigned d, int *div_purity, int eq, int *impurity) +{ + int i, k; + int n = eq ? delta->n_eq : delta->n_ineq; + isl_int **delta_c = eq ? delta->eq : delta->ineq; + isl_size n_div, total; + + n_div = isl_basic_set_dim(delta, isl_dim_div); + total = isl_basic_map_dim(path, isl_dim_all); + if (n_div < 0 || total < 0) + return isl_basic_map_free(path); + + for (i = 0; i < n; ++i) { + isl_int *path_c; + int p = PURE_VAR; + if (impurity) + p = purity(delta, delta_c[i], div_purity, eq); + if (p < 0) + goto error; + if (p != PURE_VAR && p != PURE_PARAM && !*impurity) + *impurity = 1; + if (p == IMPURE) + continue; + if (eq && p != MIXED) { + k = isl_basic_map_alloc_equality(path); + if (k < 0) + goto error; + path_c = path->eq[k]; + } else { + k = isl_basic_map_alloc_inequality(path); + if (k < 0) + goto error; + path_c = path->ineq[k]; + } + isl_seq_clr(path_c, 1 + total); + if (p == PURE_VAR) { + isl_seq_cpy(path_c + off, + delta_c[i] + 1 + nparam, d); + isl_int_set(path_c[off + d], delta_c[i][0]); + } else if (p == PURE_PARAM) { + isl_seq_cpy(path_c, delta_c[i], 1 + nparam); + } else { + isl_seq_cpy(path_c + off, + delta_c[i] + 1 + nparam, d); + isl_seq_cpy(path_c, delta_c[i], 1 + nparam); + } + isl_seq_cpy(path_c + off - n_div, + delta_c[i] + 1 + nparam + d, n_div); + } + + return path; +error: + isl_basic_map_free(path); + return NULL; +} + +/* Given a set of offsets "delta", construct a relation of the + * given dimension specification (Z^{n+1} -> Z^{n+1}) that + * is an overapproximation of the relations that + * maps an element x to any element that can be reached + * by taking a non-negative number of steps along any of + * the elements in "delta". + * That is, construct an approximation of + * + * { [x] -> [y] : exists f \in \delta, k \in Z : + * y = x + k [f, 1] and k >= 0 } + * + * For any element in this relation, the number of steps taken + * is equal to the difference in the final coordinates. + * + * In particular, let delta be defined as + * + * \delta = [p] -> { [x] : A x + a >= 0 and B p + b >= 0 and + * C x + C'p + c >= 0 and + * D x + D'p + d >= 0 } + * + * where the constraints C x + C'p + c >= 0 are such that the parametric + * constant term of each constraint j, "C_j x + C'_j p + c_j", + * can never attain positive values, then the relation is constructed as + * + * { [x] -> [y] : exists [f, k] \in Z^{n+1} : y = x + f and + * A f + k a >= 0 and B p + b >= 0 and + * C f + C'p + c >= 0 and k >= 1 } + * union { [x] -> [x] } + * + * If the zero-length paths happen to correspond exactly to the identity + * mapping, then we return + * + * { [x] -> [y] : exists [f, k] \in Z^{n+1} : y = x + f and + * A f + k a >= 0 and B p + b >= 0 and + * C f + C'p + c >= 0 and k >= 0 } + * + * instead. + * + * Existentially quantified variables in \delta are handled by + * classifying them as independent of the parameters, purely + * parameter dependent and others. Constraints containing + * any of the other existentially quantified variables are removed. + * This is safe, but leads to an additional overapproximation. + * + * If there are any impure constraints, then we also eliminate + * the parameters from \delta, resulting in a set + * + * \delta' = { [x] : E x + e >= 0 } + * + * and add the constraints + * + * E f + k e >= 0 + * + * to the constructed relation. + */ +static __isl_give isl_map *path_along_delta(__isl_take isl_space *space, + __isl_take isl_basic_set *delta) +{ + isl_basic_map *path = NULL; + isl_size d; + isl_size n_div; + isl_size nparam; + isl_size total; + unsigned off; + int i, k; + isl_bool is_id; + int *div_purity = NULL; + int impurity = 0; + + n_div = isl_basic_set_dim(delta, isl_dim_div); + d = isl_basic_set_dim(delta, isl_dim_set); + nparam = isl_basic_set_dim(delta, isl_dim_param); + if (n_div < 0 || d < 0 || nparam < 0) + goto error; + path = isl_basic_map_alloc_space(isl_space_copy(space), n_div + d + 1, + d + 1 + delta->n_eq, delta->n_eq + delta->n_ineq + 1); + off = 1 + nparam + 2 * (d + 1) + n_div; + + for (i = 0; i < n_div + d + 1; ++i) { + k = isl_basic_map_alloc_div(path); + if (k < 0) + goto error; + isl_int_set_si(path->div[k][0], 0); + } + + total = isl_basic_map_dim(path, isl_dim_all); + if (total < 0) + goto error; + for (i = 0; i < d + 1; ++i) { + k = isl_basic_map_alloc_equality(path); + if (k < 0) + goto error; + isl_seq_clr(path->eq[k], 1 + total); + isl_int_set_si(path->eq[k][1 + nparam + i], 1); + isl_int_set_si(path->eq[k][1 + nparam + d + 1 + i], -1); + isl_int_set_si(path->eq[k][off + i], 1); + } + + div_purity = get_div_purity(delta); + if (n_div && !div_purity) + goto error; + + path = add_delta_constraints(path, delta, off, nparam, d, + div_purity, 1, &impurity); + path = add_delta_constraints(path, delta, off, nparam, d, + div_purity, 0, &impurity); + if (impurity) { + isl_space *space = isl_basic_set_get_space(delta); + delta = isl_basic_set_project_out(delta, + isl_dim_param, 0, nparam); + delta = isl_basic_set_add_dims(delta, isl_dim_param, nparam); + delta = isl_basic_set_reset_space(delta, space); + if (!delta) + goto error; + path = isl_basic_map_extend_constraints(path, delta->n_eq, + delta->n_ineq + 1); + path = add_delta_constraints(path, delta, off, nparam, d, + NULL, 1, NULL); + path = add_delta_constraints(path, delta, off, nparam, d, + NULL, 0, NULL); + path = isl_basic_map_gauss(path, NULL); + } + + is_id = empty_path_is_identity(path, n_div + d); + if (is_id < 0) + goto error; + + k = isl_basic_map_alloc_inequality(path); + if (k < 0) + goto error; + isl_seq_clr(path->ineq[k], 1 + total); + if (!is_id) + isl_int_set_si(path->ineq[k][0], -1); + isl_int_set_si(path->ineq[k][off + d], 1); + + free(div_purity); + isl_basic_set_free(delta); + path = isl_basic_map_finalize(path); + if (is_id) { + isl_space_free(space); + return isl_map_from_basic_map(path); + } + return isl_basic_map_union(path, isl_basic_map_identity(space)); +error: + free(div_purity); + isl_space_free(space); + isl_basic_set_free(delta); + isl_basic_map_free(path); + return NULL; +} + +/* Given a dimension specification Z^{n+1} -> Z^{n+1} and a parameter "param", + * construct a map that equates the parameter to the difference + * in the final coordinates and imposes that this difference is positive. + * That is, construct + * + * { [x,x_s] -> [y,y_s] : k = y_s - x_s > 0 } + */ +static __isl_give isl_map *equate_parameter_to_length( + __isl_take isl_space *space, unsigned param) +{ + struct isl_basic_map *bmap; + isl_size d; + isl_size nparam; + isl_size total; + int k; + + d = isl_space_dim(space, isl_dim_in); + nparam = isl_space_dim(space, isl_dim_param); + total = isl_space_dim(space, isl_dim_all); + if (d < 0 || nparam < 0 || total < 0) + space = isl_space_free(space); + bmap = isl_basic_map_alloc_space(space, 0, 1, 1); + k = isl_basic_map_alloc_equality(bmap); + if (k < 0) + goto error; + isl_seq_clr(bmap->eq[k], 1 + total); + isl_int_set_si(bmap->eq[k][1 + param], -1); + isl_int_set_si(bmap->eq[k][1 + nparam + d - 1], -1); + isl_int_set_si(bmap->eq[k][1 + nparam + d + d - 1], 1); + + k = isl_basic_map_alloc_inequality(bmap); + if (k < 0) + goto error; + isl_seq_clr(bmap->ineq[k], 1 + total); + isl_int_set_si(bmap->ineq[k][1 + param], 1); + isl_int_set_si(bmap->ineq[k][0], -1); + + bmap = isl_basic_map_finalize(bmap); + return isl_map_from_basic_map(bmap); +error: + isl_basic_map_free(bmap); + return NULL; +} + +/* Check whether "path" is acyclic, where the last coordinates of domain + * and range of path encode the number of steps taken. + * That is, check whether + * + * { d | d = y - x and (x,y) in path } + * + * does not contain any element with positive last coordinate (positive length) + * and zero remaining coordinates (cycle). + */ +static isl_bool is_acyclic(__isl_take isl_map *path) +{ + int i; + isl_bool acyclic; + isl_size dim; + struct isl_set *delta; + + delta = isl_map_deltas(path); + dim = isl_set_dim(delta, isl_dim_set); + if (dim < 0) + delta = isl_set_free(delta); + for (i = 0; i < dim; ++i) { + if (i == dim -1) + delta = isl_set_lower_bound_si(delta, isl_dim_set, i, 1); + else + delta = isl_set_fix_si(delta, isl_dim_set, i, 0); + } + + acyclic = isl_set_is_empty(delta); + isl_set_free(delta); + + return acyclic; +} + +/* Given a union of basic maps R = \cup_i R_i \subseteq D \times D + * and a dimension specification (Z^{n+1} -> Z^{n+1}), + * construct a map that is an overapproximation of the map + * that takes an element from the space D \times Z to another + * element from the same space, such that the first n coordinates of the + * difference between them is a sum of differences between images + * and pre-images in one of the R_i and such that the last coordinate + * is equal to the number of steps taken. + * That is, let + * + * \Delta_i = { y - x | (x, y) in R_i } + * + * then the constructed map is an overapproximation of + * + * { (x) -> (x + d) | \exists k_i >= 0, \delta_i \in \Delta_i : + * d = (\sum_i k_i \delta_i, \sum_i k_i) } + * + * The elements of the singleton \Delta_i's are collected as the + * rows of the steps matrix. For all these \Delta_i's together, + * a single path is constructed. + * For each of the other \Delta_i's, we compute an overapproximation + * of the paths along elements of \Delta_i. + * Since each of these paths performs an addition, composition is + * symmetric and we can simply compose all resulting paths in any order. + */ +static __isl_give isl_map *construct_extended_path(__isl_take isl_space *space, + __isl_keep isl_map *map, int *project) +{ + struct isl_mat *steps = NULL; + struct isl_map *path = NULL; + isl_size d; + int i, j, n; + + d = isl_map_dim(map, isl_dim_in); + if (d < 0) + goto error; + + path = isl_map_identity(isl_space_copy(space)); + + steps = isl_mat_alloc(map->ctx, map->n, d); + if (!steps) + goto error; + + n = 0; + for (i = 0; i < map->n; ++i) { + struct isl_basic_set *delta; + + delta = isl_basic_map_deltas(isl_basic_map_copy(map->p[i])); + + for (j = 0; j < d; ++j) { + isl_bool fixed; + + fixed = isl_basic_set_plain_dim_is_fixed(delta, j, + &steps->row[n][j]); + if (fixed < 0) { + isl_basic_set_free(delta); + goto error; + } + if (!fixed) + break; + } + + + if (j < d) { + path = isl_map_apply_range(path, + path_along_delta(isl_space_copy(space), delta)); + path = isl_map_coalesce(path); + } else { + isl_basic_set_free(delta); + ++n; + } + } + + if (n > 0) { + steps->n_row = n; + path = isl_map_apply_range(path, + path_along_steps(isl_space_copy(space), steps)); + } + + if (project && *project) { + *project = is_acyclic(isl_map_copy(path)); + if (*project < 0) + goto error; + } + + isl_space_free(space); + isl_mat_free(steps); + return path; +error: + isl_space_free(space); + isl_mat_free(steps); + isl_map_free(path); + return NULL; +} + +static isl_bool isl_set_overlaps(__isl_keep isl_set *set1, + __isl_keep isl_set *set2) +{ + return isl_bool_not(isl_set_is_disjoint(set1, set2)); +} + +/* Given a union of basic maps R = \cup_i R_i \subseteq D \times D + * and a dimension specification (Z^{n+1} -> Z^{n+1}), + * construct a map that is an overapproximation of the map + * that takes an element from the dom R \times Z to an + * element from ran R \times Z, such that the first n coordinates of the + * difference between them is a sum of differences between images + * and pre-images in one of the R_i and such that the last coordinate + * is equal to the number of steps taken. + * That is, let + * + * \Delta_i = { y - x | (x, y) in R_i } + * + * then the constructed map is an overapproximation of + * + * { (x) -> (x + d) | \exists k_i >= 0, \delta_i \in \Delta_i : + * d = (\sum_i k_i \delta_i, \sum_i k_i) and + * x in dom R and x + d in ran R and + * \sum_i k_i >= 1 } + */ +static __isl_give isl_map *construct_component(__isl_take isl_space *space, + __isl_keep isl_map *map, isl_bool *exact, int project) +{ + struct isl_set *domain = NULL; + struct isl_set *range = NULL; + struct isl_map *app = NULL; + struct isl_map *path = NULL; + isl_bool overlaps; + int check; + + domain = isl_map_domain(isl_map_copy(map)); + domain = isl_set_coalesce(domain); + range = isl_map_range(isl_map_copy(map)); + range = isl_set_coalesce(range); + overlaps = isl_set_overlaps(domain, range); + if (overlaps < 0 || !overlaps) { + isl_set_free(domain); + isl_set_free(range); + isl_space_free(space); + + if (overlaps < 0) + map = NULL; + map = isl_map_copy(map); + map = isl_map_add_dims(map, isl_dim_in, 1); + map = isl_map_add_dims(map, isl_dim_out, 1); + map = set_path_length(map, 1, 1); + return map; + } + app = isl_map_from_domain_and_range(domain, range); + app = isl_map_add_dims(app, isl_dim_in, 1); + app = isl_map_add_dims(app, isl_dim_out, 1); + + check = exact && *exact == isl_bool_true; + path = construct_extended_path(isl_space_copy(space), map, + check ? &project : NULL); + app = isl_map_intersect(app, path); + + if (check && + (*exact = check_exactness(isl_map_copy(map), isl_map_copy(app), + project)) < 0) + goto error; + + isl_space_free(space); + app = set_path_length(app, 0, 1); + return app; +error: + isl_space_free(space); + isl_map_free(app); + return NULL; +} + +/* Call construct_component and, if "project" is set, project out + * the final coordinates. + */ +static __isl_give isl_map *construct_projected_component( + __isl_take isl_space *space, + __isl_keep isl_map *map, isl_bool *exact, int project) +{ + isl_map *app; + unsigned d; + + if (!space) + return NULL; + d = isl_space_dim(space, isl_dim_in); + + app = construct_component(space, map, exact, project); + if (project) { + app = isl_map_project_out(app, isl_dim_in, d - 1, 1); + app = isl_map_project_out(app, isl_dim_out, d - 1, 1); + } + return app; +} + +/* Compute an extended version, i.e., with path lengths, of + * an overapproximation of the transitive closure of "bmap" + * with path lengths greater than or equal to zero and with + * domain and range equal to "dom". + */ +static __isl_give isl_map *q_closure(__isl_take isl_space *space, + __isl_take isl_set *dom, __isl_keep isl_basic_map *bmap, + isl_bool *exact) +{ + int project = 1; + isl_map *path; + isl_map *map; + isl_map *app; + + dom = isl_set_add_dims(dom, isl_dim_set, 1); + app = isl_map_from_domain_and_range(dom, isl_set_copy(dom)); + map = isl_map_from_basic_map(isl_basic_map_copy(bmap)); + path = construct_extended_path(space, map, &project); + app = isl_map_intersect(app, path); + + if ((*exact = check_exactness(map, isl_map_copy(app), project)) < 0) + goto error; + + return app; +error: + isl_map_free(app); + return NULL; +} + +/* Check whether qc has any elements of length at least one + * with domain and/or range outside of dom and ran. + */ +static isl_bool has_spurious_elements(__isl_keep isl_map *qc, + __isl_keep isl_set *dom, __isl_keep isl_set *ran) +{ + isl_set *s; + isl_bool subset; + isl_size d; + + d = isl_map_dim(qc, isl_dim_in); + if (d < 0 || !dom || !ran) + return isl_bool_error; + + qc = isl_map_copy(qc); + qc = set_path_length(qc, 0, 1); + qc = isl_map_project_out(qc, isl_dim_in, d - 1, 1); + qc = isl_map_project_out(qc, isl_dim_out, d - 1, 1); + + s = isl_map_domain(isl_map_copy(qc)); + subset = isl_set_is_subset(s, dom); + isl_set_free(s); + if (subset < 0) + goto error; + if (!subset) { + isl_map_free(qc); + return isl_bool_true; + } + + s = isl_map_range(qc); + subset = isl_set_is_subset(s, ran); + isl_set_free(s); + + return isl_bool_not(subset); +error: + isl_map_free(qc); + return isl_bool_error; +} + +#define LEFT 2 +#define RIGHT 1 + +/* For each basic map in "map", except i, check whether it combines + * with the transitive closure that is reflexive on C combines + * to the left and to the right. + * + * In particular, if + * + * dom map_j \subseteq C + * + * then right[j] is set to 1. Otherwise, if + * + * ran map_i \cap dom map_j = \emptyset + * + * then right[j] is set to 0. Otherwise, composing to the right + * is impossible. + * + * Similar, for composing to the left, we have if + * + * ran map_j \subseteq C + * + * then left[j] is set to 1. Otherwise, if + * + * dom map_i \cap ran map_j = \emptyset + * + * then left[j] is set to 0. Otherwise, composing to the left + * is impossible. + * + * The return value is or'd with LEFT if composing to the left + * is possible and with RIGHT if composing to the right is possible. + */ +static int composability(__isl_keep isl_set *C, int i, + isl_set **dom, isl_set **ran, int *left, int *right, + __isl_keep isl_map *map) +{ + int j; + int ok; + + ok = LEFT | RIGHT; + for (j = 0; j < map->n && ok; ++j) { + isl_bool overlaps, subset; + if (j == i) + continue; + + if (ok & RIGHT) { + if (!dom[j]) + dom[j] = isl_set_from_basic_set( + isl_basic_map_domain( + isl_basic_map_copy(map->p[j]))); + if (!dom[j]) + return -1; + overlaps = isl_set_overlaps(ran[i], dom[j]); + if (overlaps < 0) + return -1; + if (!overlaps) + right[j] = 0; + else { + subset = isl_set_is_subset(dom[j], C); + if (subset < 0) + return -1; + if (subset) + right[j] = 1; + else + ok &= ~RIGHT; + } + } + + if (ok & LEFT) { + if (!ran[j]) + ran[j] = isl_set_from_basic_set( + isl_basic_map_range( + isl_basic_map_copy(map->p[j]))); + if (!ran[j]) + return -1; + overlaps = isl_set_overlaps(dom[i], ran[j]); + if (overlaps < 0) + return -1; + if (!overlaps) + left[j] = 0; + else { + subset = isl_set_is_subset(ran[j], C); + if (subset < 0) + return -1; + if (subset) + left[j] = 1; + else + ok &= ~LEFT; + } + } + } + + return ok; +} + +static __isl_give isl_map *anonymize(__isl_take isl_map *map) +{ + map = isl_map_reset(map, isl_dim_in); + map = isl_map_reset(map, isl_dim_out); + return map; +} + +/* Return a map that is a union of the basic maps in "map", except i, + * composed to left and right with qc based on the entries of "left" + * and "right". + */ +static __isl_give isl_map *compose(__isl_keep isl_map *map, int i, + __isl_take isl_map *qc, int *left, int *right) +{ + int j; + isl_map *comp; + + comp = isl_map_empty(isl_map_get_space(map)); + for (j = 0; j < map->n; ++j) { + isl_map *map_j; + + if (j == i) + continue; + + map_j = isl_map_from_basic_map(isl_basic_map_copy(map->p[j])); + map_j = anonymize(map_j); + if (left && left[j]) + map_j = isl_map_apply_range(map_j, isl_map_copy(qc)); + if (right && right[j]) + map_j = isl_map_apply_range(isl_map_copy(qc), map_j); + comp = isl_map_union(comp, map_j); + } + + comp = isl_map_compute_divs(comp); + comp = isl_map_coalesce(comp); + + isl_map_free(qc); + + return comp; +} + +/* Compute the transitive closure of "map" incrementally by + * computing + * + * map_i^+ \cup qc^+ + * + * or + * + * map_i^+ \cup ((id \cup map_i^) \circ qc^+) + * + * or + * + * map_i^+ \cup (qc^+ \circ (id \cup map_i^)) + * + * depending on whether left or right are NULL. + */ +static __isl_give isl_map *compute_incremental( + __isl_take isl_space *space, __isl_keep isl_map *map, + int i, __isl_take isl_map *qc, int *left, int *right, isl_bool *exact) +{ + isl_map *map_i; + isl_map *tc; + isl_map *rtc = NULL; + + if (!map) + goto error; + isl_assert(map->ctx, left || right, goto error); + + map_i = isl_map_from_basic_map(isl_basic_map_copy(map->p[i])); + tc = construct_projected_component(isl_space_copy(space), map_i, + exact, 1); + isl_map_free(map_i); + + if (*exact) + qc = isl_map_transitive_closure(qc, exact); + + if (!*exact) { + isl_space_free(space); + isl_map_free(tc); + isl_map_free(qc); + return isl_map_universe(isl_map_get_space(map)); + } + + if (!left || !right) + rtc = isl_map_union(isl_map_copy(tc), + isl_map_identity(isl_map_get_space(tc))); + if (!right) + qc = isl_map_apply_range(rtc, qc); + if (!left) + qc = isl_map_apply_range(qc, rtc); + qc = isl_map_union(tc, qc); + + isl_space_free(space); + + return qc; +error: + isl_space_free(space); + isl_map_free(qc); + return NULL; +} + +/* Given a map "map", try to find a basic map such that + * map^+ can be computed as + * + * map^+ = map_i^+ \cup + * \bigcup_j ((map_i^+ \cup Id_C)^+ \circ map_j \circ (map_i^+ \cup Id_C))^+ + * + * with C the simple hull of the domain and range of the input map. + * map_i^ \cup Id_C is computed by allowing the path lengths to be zero + * and by intersecting domain and range with C. + * Of course, we need to check that this is actually equal to map_i^ \cup Id_C. + * Also, we only use the incremental computation if all the transitive + * closures are exact and if the number of basic maps in the union, + * after computing the integer divisions, is smaller than the number + * of basic maps in the input map. + */ +static isl_bool incremental_on_entire_domain(__isl_keep isl_space *space, + __isl_keep isl_map *map, + isl_set **dom, isl_set **ran, int *left, int *right, + __isl_give isl_map **res) +{ + int i; + isl_set *C; + isl_size d; + + *res = NULL; + + d = isl_map_dim(map, isl_dim_in); + if (d < 0) + return isl_bool_error; + + C = isl_set_union(isl_map_domain(isl_map_copy(map)), + isl_map_range(isl_map_copy(map))); + C = isl_set_from_basic_set(isl_set_simple_hull(C)); + if (!C) + return isl_bool_error; + if (C->n != 1) { + isl_set_free(C); + return isl_bool_false; + } + + for (i = 0; i < map->n; ++i) { + isl_map *qc; + isl_bool exact_i; + isl_bool spurious; + int j; + dom[i] = isl_set_from_basic_set(isl_basic_map_domain( + isl_basic_map_copy(map->p[i]))); + ran[i] = isl_set_from_basic_set(isl_basic_map_range( + isl_basic_map_copy(map->p[i]))); + qc = q_closure(isl_space_copy(space), isl_set_copy(C), + map->p[i], &exact_i); + if (!qc) + goto error; + if (!exact_i) { + isl_map_free(qc); + continue; + } + spurious = has_spurious_elements(qc, dom[i], ran[i]); + if (spurious) { + isl_map_free(qc); + if (spurious < 0) + goto error; + continue; + } + qc = isl_map_project_out(qc, isl_dim_in, d, 1); + qc = isl_map_project_out(qc, isl_dim_out, d, 1); + qc = isl_map_compute_divs(qc); + for (j = 0; j < map->n; ++j) + left[j] = right[j] = 1; + qc = compose(map, i, qc, left, right); + if (!qc) + goto error; + if (qc->n >= map->n) { + isl_map_free(qc); + continue; + } + *res = compute_incremental(isl_space_copy(space), map, i, qc, + left, right, &exact_i); + if (!*res) + goto error; + if (exact_i) + break; + isl_map_free(*res); + *res = NULL; + } + + isl_set_free(C); + + return isl_bool_ok(*res != NULL); +error: + isl_set_free(C); + return isl_bool_error; +} + +/* Try and compute the transitive closure of "map" as + * + * map^+ = map_i^+ \cup + * \bigcup_j ((map_i^+ \cup Id_C)^+ \circ map_j \circ (map_i^+ \cup Id_C))^+ + * + * with C either the simple hull of the domain and range of the entire + * map or the simple hull of domain and range of map_i. + */ +static __isl_give isl_map *incremental_closure(__isl_take isl_space *space, + __isl_keep isl_map *map, isl_bool *exact, int project) +{ + int i; + isl_set **dom = NULL; + isl_set **ran = NULL; + int *left = NULL; + int *right = NULL; + isl_set *C; + isl_size d; + isl_map *res = NULL; + + if (!project) + return construct_projected_component(space, map, exact, + project); + + if (!map) + goto error; + if (map->n <= 1) + return construct_projected_component(space, map, exact, + project); + + d = isl_map_dim(map, isl_dim_in); + if (d < 0) + goto error; + + dom = isl_calloc_array(map->ctx, isl_set *, map->n); + ran = isl_calloc_array(map->ctx, isl_set *, map->n); + left = isl_calloc_array(map->ctx, int, map->n); + right = isl_calloc_array(map->ctx, int, map->n); + if (!ran || !dom || !left || !right) + goto error; + + if (incremental_on_entire_domain(space, map, dom, ran, left, right, + &res) < 0) + goto error; + + for (i = 0; !res && i < map->n; ++i) { + isl_map *qc; + int comp; + isl_bool exact_i, spurious; + if (!dom[i]) + dom[i] = isl_set_from_basic_set( + isl_basic_map_domain( + isl_basic_map_copy(map->p[i]))); + if (!dom[i]) + goto error; + if (!ran[i]) + ran[i] = isl_set_from_basic_set( + isl_basic_map_range( + isl_basic_map_copy(map->p[i]))); + if (!ran[i]) + goto error; + C = isl_set_union(isl_set_copy(dom[i]), + isl_set_copy(ran[i])); + C = isl_set_from_basic_set(isl_set_simple_hull(C)); + if (!C) + goto error; + if (C->n != 1) { + isl_set_free(C); + continue; + } + comp = composability(C, i, dom, ran, left, right, map); + if (!comp || comp < 0) { + isl_set_free(C); + if (comp < 0) + goto error; + continue; + } + qc = q_closure(isl_space_copy(space), C, map->p[i], &exact_i); + if (!qc) + goto error; + if (!exact_i) { + isl_map_free(qc); + continue; + } + spurious = has_spurious_elements(qc, dom[i], ran[i]); + if (spurious) { + isl_map_free(qc); + if (spurious < 0) + goto error; + continue; + } + qc = isl_map_project_out(qc, isl_dim_in, d, 1); + qc = isl_map_project_out(qc, isl_dim_out, d, 1); + qc = isl_map_compute_divs(qc); + qc = compose(map, i, qc, (comp & LEFT) ? left : NULL, + (comp & RIGHT) ? right : NULL); + if (!qc) + goto error; + if (qc->n >= map->n) { + isl_map_free(qc); + continue; + } + res = compute_incremental(isl_space_copy(space), map, i, qc, + (comp & LEFT) ? left : NULL, + (comp & RIGHT) ? right : NULL, &exact_i); + if (!res) + goto error; + if (exact_i) + break; + isl_map_free(res); + res = NULL; + } + + for (i = 0; i < map->n; ++i) { + isl_set_free(dom[i]); + isl_set_free(ran[i]); + } + free(dom); + free(ran); + free(left); + free(right); + + if (res) { + isl_space_free(space); + return res; + } + + return construct_projected_component(space, map, exact, project); +error: + if (dom) + for (i = 0; i < map->n; ++i) + isl_set_free(dom[i]); + free(dom); + if (ran) + for (i = 0; i < map->n; ++i) + isl_set_free(ran[i]); + free(ran); + free(left); + free(right); + isl_space_free(space); + return NULL; +} + +/* Given an array of sets "set", add "dom" at position "pos" + * and search for elements at earlier positions that overlap with "dom". + * If any can be found, then merge all of them, together with "dom", into + * a single set and assign the union to the first in the array, + * which becomes the new group leader for all groups involved in the merge. + * During the search, we only consider group leaders, i.e., those with + * group[i] = i, as the other sets have already been combined + * with one of the group leaders. + */ +static int merge(isl_set **set, int *group, __isl_take isl_set *dom, int pos) +{ + int i; + + group[pos] = pos; + set[pos] = isl_set_copy(dom); + + for (i = pos - 1; i >= 0; --i) { + isl_bool o; + + if (group[i] != i) + continue; + + o = isl_set_overlaps(set[i], dom); + if (o < 0) + goto error; + if (!o) + continue; + + set[i] = isl_set_union(set[i], set[group[pos]]); + set[group[pos]] = NULL; + if (!set[i]) + goto error; + group[group[pos]] = i; + group[pos] = i; + } + + isl_set_free(dom); + return 0; +error: + isl_set_free(dom); + return -1; +} + +/* Construct a map [x] -> [x+1], with parameters prescribed by "space". + */ +static __isl_give isl_map *increment(__isl_take isl_space *space) +{ + int k; + isl_basic_map *bmap; + isl_size total; + + space = isl_space_set_from_params(space); + space = isl_space_add_dims(space, isl_dim_set, 1); + space = isl_space_map_from_set(space); + bmap = isl_basic_map_alloc_space(space, 0, 1, 0); + total = isl_basic_map_dim(bmap, isl_dim_all); + k = isl_basic_map_alloc_equality(bmap); + if (total < 0 || k < 0) + goto error; + isl_seq_clr(bmap->eq[k], 1 + total); + isl_int_set_si(bmap->eq[k][0], 1); + isl_int_set_si(bmap->eq[k][isl_basic_map_offset(bmap, isl_dim_in)], 1); + isl_int_set_si(bmap->eq[k][isl_basic_map_offset(bmap, isl_dim_out)], -1); + return isl_map_from_basic_map(bmap); +error: + isl_basic_map_free(bmap); + return NULL; +} + +/* Replace each entry in the n by n grid of maps by the cross product + * with the relation { [i] -> [i + 1] }. + */ +static isl_stat add_length(__isl_keep isl_map *map, isl_map ***grid, int n) +{ + int i, j; + isl_space *space; + isl_map *step; + + space = isl_space_params(isl_map_get_space(map)); + step = increment(space); + + if (!step) + return isl_stat_error; + + for (i = 0; i < n; ++i) + for (j = 0; j < n; ++j) + grid[i][j] = isl_map_product(grid[i][j], + isl_map_copy(step)); + + isl_map_free(step); + + return isl_stat_ok; +} + +/* The core of the Floyd-Warshall algorithm. + * Updates the given n x x matrix of relations in place. + * + * The algorithm iterates over all vertices. In each step, the whole + * matrix is updated to include all paths that go to the current vertex, + * possibly stay there a while (including passing through earlier vertices) + * and then come back. At the start of each iteration, the diagonal + * element corresponding to the current vertex is replaced by its + * transitive closure to account for all indirect paths that stay + * in the current vertex. + */ +static void floyd_warshall_iterate(isl_map ***grid, int n, isl_bool *exact) +{ + int r, p, q; + + for (r = 0; r < n; ++r) { + isl_bool r_exact; + int check = exact && *exact == isl_bool_true; + grid[r][r] = isl_map_transitive_closure(grid[r][r], + check ? &r_exact : NULL); + if (check && !r_exact) + *exact = isl_bool_false; + + for (p = 0; p < n; ++p) + for (q = 0; q < n; ++q) { + isl_map *loop; + if (p == r && q == r) + continue; + loop = isl_map_apply_range( + isl_map_copy(grid[p][r]), + isl_map_copy(grid[r][q])); + grid[p][q] = isl_map_union(grid[p][q], loop); + loop = isl_map_apply_range( + isl_map_copy(grid[p][r]), + isl_map_apply_range( + isl_map_copy(grid[r][r]), + isl_map_copy(grid[r][q]))); + grid[p][q] = isl_map_union(grid[p][q], loop); + grid[p][q] = isl_map_coalesce(grid[p][q]); + } + } +} + +/* Given a partition of the domains and ranges of the basic maps in "map", + * apply the Floyd-Warshall algorithm with the elements in the partition + * as vertices. + * + * In particular, there are "n" elements in the partition and "group" is + * an array of length 2 * map->n with entries in [0,n-1]. + * + * We first construct a matrix of relations based on the partition information, + * apply Floyd-Warshall on this matrix of relations and then take the + * union of all entries in the matrix as the final result. + * + * If we are actually computing the power instead of the transitive closure, + * i.e., when "project" is not set, then the result should have the + * path lengths encoded as the difference between an extra pair of + * coordinates. We therefore apply the nested transitive closures + * to relations that include these lengths. In particular, we replace + * the input relation by the cross product with the unit length relation + * { [i] -> [i + 1] }. + */ +static __isl_give isl_map *floyd_warshall_with_groups( + __isl_take isl_space *space, __isl_keep isl_map *map, + isl_bool *exact, int project, int *group, int n) +{ + int i, j, k; + isl_map ***grid = NULL; + isl_map *app; + + if (!map) + goto error; + + if (n == 1) { + free(group); + return incremental_closure(space, map, exact, project); + } + + grid = isl_calloc_array(map->ctx, isl_map **, n); + if (!grid) + goto error; + for (i = 0; i < n; ++i) { + grid[i] = isl_calloc_array(map->ctx, isl_map *, n); + if (!grid[i]) + goto error; + for (j = 0; j < n; ++j) + grid[i][j] = isl_map_empty(isl_map_get_space(map)); + } + + for (k = 0; k < map->n; ++k) { + i = group[2 * k]; + j = group[2 * k + 1]; + grid[i][j] = isl_map_union(grid[i][j], + isl_map_from_basic_map( + isl_basic_map_copy(map->p[k]))); + } + + if (!project && add_length(map, grid, n) < 0) + goto error; + + floyd_warshall_iterate(grid, n, exact); + + app = isl_map_empty(isl_map_get_space(grid[0][0])); + + for (i = 0; i < n; ++i) { + for (j = 0; j < n; ++j) + app = isl_map_union(app, grid[i][j]); + free(grid[i]); + } + free(grid); + + free(group); + isl_space_free(space); + + return app; +error: + if (grid) + for (i = 0; i < n; ++i) { + if (!grid[i]) + continue; + for (j = 0; j < n; ++j) + isl_map_free(grid[i][j]); + free(grid[i]); + } + free(grid); + free(group); + isl_space_free(space); + return NULL; +} + +/* Partition the domains and ranges of the n basic relations in list + * into disjoint cells. + * + * To find the partition, we simply consider all of the domains + * and ranges in turn and combine those that overlap. + * "set" contains the partition elements and "group" indicates + * to which partition element a given domain or range belongs. + * The domain of basic map i corresponds to element 2 * i in these arrays, + * while the domain corresponds to element 2 * i + 1. + * During the construction group[k] is either equal to k, + * in which case set[k] contains the union of all the domains and + * ranges in the corresponding group, or is equal to some l < k, + * with l another domain or range in the same group. + */ +static int *setup_groups(isl_ctx *ctx, __isl_keep isl_basic_map **list, int n, + isl_set ***set, int *n_group) +{ + int i; + int *group = NULL; + int g; + + *set = isl_calloc_array(ctx, isl_set *, 2 * n); + group = isl_alloc_array(ctx, int, 2 * n); + + if (!*set || !group) + goto error; + + for (i = 0; i < n; ++i) { + isl_set *dom; + dom = isl_set_from_basic_set(isl_basic_map_domain( + isl_basic_map_copy(list[i]))); + if (merge(*set, group, dom, 2 * i) < 0) + goto error; + dom = isl_set_from_basic_set(isl_basic_map_range( + isl_basic_map_copy(list[i]))); + if (merge(*set, group, dom, 2 * i + 1) < 0) + goto error; + } + + g = 0; + for (i = 0; i < 2 * n; ++i) + if (group[i] == i) { + if (g != i) { + (*set)[g] = (*set)[i]; + (*set)[i] = NULL; + } + group[i] = g++; + } else + group[i] = group[group[i]]; + + *n_group = g; + + return group; +error: + if (*set) { + for (i = 0; i < 2 * n; ++i) + isl_set_free((*set)[i]); + free(*set); + *set = NULL; + } + free(group); + return NULL; +} + +/* Check if the domains and ranges of the basic maps in "map" can + * be partitioned, and if so, apply Floyd-Warshall on the elements + * of the partition. Note that we also apply this algorithm + * if we want to compute the power, i.e., when "project" is not set. + * However, the results are unlikely to be exact since the recursive + * calls inside the Floyd-Warshall algorithm typically result in + * non-linear path lengths quite quickly. + */ +static __isl_give isl_map *floyd_warshall(__isl_take isl_space *space, + __isl_keep isl_map *map, isl_bool *exact, int project) +{ + int i; + isl_set **set = NULL; + int *group = NULL; + int n; + + if (!map) + goto error; + if (map->n <= 1) + return incremental_closure(space, map, exact, project); + + group = setup_groups(map->ctx, map->p, map->n, &set, &n); + if (!group) + goto error; + + for (i = 0; i < 2 * map->n; ++i) + isl_set_free(set[i]); + + free(set); + + return floyd_warshall_with_groups(space, map, exact, project, group, n); +error: + isl_space_free(space); + return NULL; +} + +/* Structure for representing the nodes of the graph of which + * strongly connected components are being computed. + * + * list contains the actual nodes + * check_closed is set if we may have used the fact that + * a pair of basic maps can be interchanged + */ +struct isl_tc_follows_data { + isl_basic_map **list; + int check_closed; +}; + +/* Check whether in the computation of the transitive closure + * "list[i]" (R_1) should follow (or be part of the same component as) + * "list[j]" (R_2). + * + * That is check whether + * + * R_1 \circ R_2 + * + * is a subset of + * + * R_2 \circ R_1 + * + * If so, then there is no reason for R_1 to immediately follow R_2 + * in any path. + * + * *check_closed is set if the subset relation holds while + * R_1 \circ R_2 is not empty. + */ +static isl_bool basic_map_follows(int i, int j, void *user) +{ + struct isl_tc_follows_data *data = user; + struct isl_map *map12 = NULL; + struct isl_map *map21 = NULL; + isl_bool applies, subset; + + applies = isl_basic_map_applies_range(data->list[j], data->list[i]); + if (applies < 0) + return isl_bool_error; + if (!applies) + return isl_bool_false; + + map21 = isl_map_from_basic_map( + isl_basic_map_apply_range( + isl_basic_map_copy(data->list[j]), + isl_basic_map_copy(data->list[i]))); + subset = isl_map_is_empty(map21); + if (subset < 0) + goto error; + if (subset) { + isl_map_free(map21); + return isl_bool_false; + } + + if (!isl_basic_map_is_transformation(data->list[i]) || + !isl_basic_map_is_transformation(data->list[j])) { + isl_map_free(map21); + return isl_bool_true; + } + + map12 = isl_map_from_basic_map( + isl_basic_map_apply_range( + isl_basic_map_copy(data->list[i]), + isl_basic_map_copy(data->list[j]))); + + subset = isl_map_is_subset(map21, map12); + + isl_map_free(map12); + isl_map_free(map21); + + if (subset) + data->check_closed = 1; + + return isl_bool_not(subset); +error: + isl_map_free(map21); + return isl_bool_error; +} + +/* Given a union of basic maps R = \cup_i R_i \subseteq D \times D + * and a dimension specification (Z^{n+1} -> Z^{n+1}), + * construct a map that is an overapproximation of the map + * that takes an element from the dom R \times Z to an + * element from ran R \times Z, such that the first n coordinates of the + * difference between them is a sum of differences between images + * and pre-images in one of the R_i and such that the last coordinate + * is equal to the number of steps taken. + * If "project" is set, then these final coordinates are not included, + * i.e., a relation of type Z^n -> Z^n is returned. + * That is, let + * + * \Delta_i = { y - x | (x, y) in R_i } + * + * then the constructed map is an overapproximation of + * + * { (x) -> (x + d) | \exists k_i >= 0, \delta_i \in \Delta_i : + * d = (\sum_i k_i \delta_i, \sum_i k_i) and + * x in dom R and x + d in ran R } + * + * or + * + * { (x) -> (x + d) | \exists k_i >= 0, \delta_i \in \Delta_i : + * d = (\sum_i k_i \delta_i) and + * x in dom R and x + d in ran R } + * + * if "project" is set. + * + * We first split the map into strongly connected components, perform + * the above on each component and then join the results in the correct + * order, at each join also taking in the union of both arguments + * to allow for paths that do not go through one of the two arguments. + */ +static __isl_give isl_map *construct_power_components( + __isl_take isl_space *space, __isl_keep isl_map *map, isl_bool *exact, + int project) +{ + int i, n, c; + struct isl_map *path = NULL; + struct isl_tc_follows_data data; + struct isl_tarjan_graph *g = NULL; + isl_bool *orig_exact; + isl_bool local_exact; + + if (!map) + goto error; + if (map->n <= 1) + return floyd_warshall(space, map, exact, project); + + data.list = map->p; + data.check_closed = 0; + g = isl_tarjan_graph_init(map->ctx, map->n, &basic_map_follows, &data); + if (!g) + goto error; + + orig_exact = exact; + if (data.check_closed && !exact) + exact = &local_exact; + + c = 0; + i = 0; + n = map->n; + if (project) + path = isl_map_empty(isl_map_get_space(map)); + else + path = isl_map_empty(isl_space_copy(space)); + path = anonymize(path); + while (n) { + struct isl_map *comp; + isl_map *path_comp, *path_comb; + comp = isl_map_alloc_space(isl_map_get_space(map), n, 0); + while (g->order[i] != -1) { + comp = isl_map_add_basic_map(comp, + isl_basic_map_copy(map->p[g->order[i]])); + --n; + ++i; + } + path_comp = floyd_warshall(isl_space_copy(space), + comp, exact, project); + path_comp = anonymize(path_comp); + path_comb = isl_map_apply_range(isl_map_copy(path), + isl_map_copy(path_comp)); + path = isl_map_union(path, path_comp); + path = isl_map_union(path, path_comb); + isl_map_free(comp); + ++i; + ++c; + } + + if (c > 1 && data.check_closed && !*exact) { + isl_bool closed; + + closed = isl_map_is_transitively_closed(path); + if (closed < 0) + goto error; + if (!closed) { + isl_tarjan_graph_free(g); + isl_map_free(path); + return floyd_warshall(space, map, orig_exact, project); + } + } + + isl_tarjan_graph_free(g); + isl_space_free(space); + + return path; +error: + isl_tarjan_graph_free(g); + isl_space_free(space); + isl_map_free(path); + return NULL; +} + +/* Given a union of basic maps R = \cup_i R_i \subseteq D \times D, + * construct a map that is an overapproximation of the map + * that takes an element from the space D to another + * element from the same space, such that the difference between + * them is a strictly positive sum of differences between images + * and pre-images in one of the R_i. + * The number of differences in the sum is equated to parameter "param". + * That is, let + * + * \Delta_i = { y - x | (x, y) in R_i } + * + * then the constructed map is an overapproximation of + * + * { (x) -> (x + d) | \exists k_i >= 0, \delta_i \in \Delta_i : + * d = \sum_i k_i \delta_i and k = \sum_i k_i > 0 } + * or + * + * { (x) -> (x + d) | \exists k_i >= 0, \delta_i \in \Delta_i : + * d = \sum_i k_i \delta_i and \sum_i k_i > 0 } + * + * if "project" is set. + * + * If "project" is not set, then + * we construct an extended mapping with an extra coordinate + * that indicates the number of steps taken. In particular, + * the difference in the last coordinate is equal to the number + * of steps taken to move from a domain element to the corresponding + * image element(s). + */ +static __isl_give isl_map *construct_power(__isl_keep isl_map *map, + isl_bool *exact, int project) +{ + struct isl_map *app = NULL; + isl_space *space = NULL; + + if (!map) + return NULL; + + space = isl_map_get_space(map); + + space = isl_space_add_dims(space, isl_dim_in, 1); + space = isl_space_add_dims(space, isl_dim_out, 1); + + app = construct_power_components(isl_space_copy(space), map, + exact, project); + + isl_space_free(space); + + return app; +} + +/* Compute the positive powers of "map", or an overapproximation. + * If the result is exact, then *exact is set to 1. + * + * If project is set, then we are actually interested in the transitive + * closure, so we can use a more relaxed exactness check. + * The lengths of the paths are also projected out instead of being + * encoded as the difference between an extra pair of final coordinates. + */ +static __isl_give isl_map *map_power(__isl_take isl_map *map, + isl_bool *exact, int project) +{ + struct isl_map *app = NULL; + + if (exact) + *exact = isl_bool_true; + + if (isl_map_check_transformation(map) < 0) + return isl_map_free(map); + + app = construct_power(map, exact, project); + + isl_map_free(map); + return app; +} + +/* Compute the positive powers of "map", or an overapproximation. + * The result maps the exponent to a nested copy of the corresponding power. + * If the result is exact, then *exact is set to 1. + * map_power constructs an extended relation with the path lengths + * encoded as the difference between the final coordinates. + * In the final step, this difference is equated to an extra parameter + * and made positive. The extra coordinates are subsequently projected out + * and the parameter is turned into the domain of the result. + */ +__isl_give isl_map *isl_map_power(__isl_take isl_map *map, isl_bool *exact) +{ + isl_space *target_space; + isl_space *space; + isl_map *diff; + isl_size d; + isl_size param; + + d = isl_map_dim(map, isl_dim_in); + param = isl_map_dim(map, isl_dim_param); + if (d < 0 || param < 0) + return isl_map_free(map); + + map = isl_map_compute_divs(map); + map = isl_map_coalesce(map); + + if (isl_map_plain_is_empty(map)) { + map = isl_map_from_range(isl_map_wrap(map)); + map = isl_map_add_dims(map, isl_dim_in, 1); + map = isl_map_set_dim_name(map, isl_dim_in, 0, "k"); + return map; + } + + target_space = isl_map_get_space(map); + target_space = isl_space_from_range(isl_space_wrap(target_space)); + target_space = isl_space_add_dims(target_space, isl_dim_in, 1); + target_space = isl_space_set_dim_name(target_space, isl_dim_in, 0, "k"); + + map = map_power(map, exact, 0); + + map = isl_map_add_dims(map, isl_dim_param, 1); + space = isl_map_get_space(map); + diff = equate_parameter_to_length(space, param); + map = isl_map_intersect(map, diff); + map = isl_map_project_out(map, isl_dim_in, d, 1); + map = isl_map_project_out(map, isl_dim_out, d, 1); + map = isl_map_from_range(isl_map_wrap(map)); + map = isl_map_move_dims(map, isl_dim_in, 0, isl_dim_param, param, 1); + + map = isl_map_reset_space(map, target_space); + + return map; +} + +/* Compute a relation that maps each element in the range of the input + * relation to the lengths of all paths composed of edges in the input + * relation that end up in the given range element. + * The result may be an overapproximation, in which case *exact is set to 0. + * The resulting relation is very similar to the power relation. + * The difference are that the domain has been projected out, the + * range has become the domain and the exponent is the range instead + * of a parameter. + */ +__isl_give isl_map *isl_map_reaching_path_lengths(__isl_take isl_map *map, + isl_bool *exact) +{ + isl_space *space; + isl_map *diff; + isl_size d; + isl_size param; + + d = isl_map_dim(map, isl_dim_in); + param = isl_map_dim(map, isl_dim_param); + if (d < 0 || param < 0) + return isl_map_free(map); + + map = isl_map_compute_divs(map); + map = isl_map_coalesce(map); + + if (isl_map_plain_is_empty(map)) { + if (exact) + *exact = isl_bool_true; + map = isl_map_project_out(map, isl_dim_out, 0, d); + map = isl_map_add_dims(map, isl_dim_out, 1); + return map; + } + + map = map_power(map, exact, 0); + + map = isl_map_add_dims(map, isl_dim_param, 1); + space = isl_map_get_space(map); + diff = equate_parameter_to_length(space, param); + map = isl_map_intersect(map, diff); + map = isl_map_project_out(map, isl_dim_in, 0, d + 1); + map = isl_map_project_out(map, isl_dim_out, d, 1); + map = isl_map_reverse(map); + map = isl_map_move_dims(map, isl_dim_out, 0, isl_dim_param, param, 1); + + return map; +} + +/* Given a map, compute the smallest superset of this map that is of the form + * + * { i -> j : L <= j - i <= U and exists a_p: j_p - i_p = M_p a_p } + * + * (where p ranges over the (non-parametric) dimensions), + * compute the transitive closure of this map, i.e., + * + * { i -> j : exists k > 0: + * k L <= j - i <= k U and exists a: j_p - i_p = M_p a_p } + * + * and intersect domain and range of this transitive closure with + * the given domain and range. + * + * If with_id is set, then try to include as much of the identity mapping + * as possible, by computing + * + * { i -> j : exists k >= 0: + * k L <= j - i <= k U and exists a: j_p - i_p = M_p a_p } + * + * instead (i.e., allow k = 0). + * + * In practice, we compute the difference set + * + * delta = { j - i | i -> j in map }, + * + * look for stride constraint on the individual dimensions and compute + * (constant) lower and upper bounds for each individual dimension, + * adding a constraint for each bound not equal to infinity. + */ +static __isl_give isl_map *box_closure_on_domain(__isl_take isl_map *map, + __isl_take isl_set *dom, __isl_take isl_set *ran, int with_id) +{ + int i; + int k; + unsigned d; + unsigned nparam; + unsigned total; + isl_space *space; + isl_set *delta; + isl_map *app = NULL; + isl_basic_set *aff = NULL; + isl_basic_map *bmap = NULL; + isl_vec *obj = NULL; + isl_int opt; + + isl_int_init(opt); + + delta = isl_map_deltas(isl_map_copy(map)); + + aff = isl_set_affine_hull(isl_set_copy(delta)); + if (!aff) + goto error; + space = isl_map_get_space(map); + d = isl_space_dim(space, isl_dim_in); + nparam = isl_space_dim(space, isl_dim_param); + total = isl_space_dim(space, isl_dim_all); + bmap = isl_basic_map_alloc_space(space, + aff->n_div + 1, aff->n_div, 2 * d + 1); + for (i = 0; i < aff->n_div + 1; ++i) { + k = isl_basic_map_alloc_div(bmap); + if (k < 0) + goto error; + isl_int_set_si(bmap->div[k][0], 0); + } + for (i = 0; i < aff->n_eq; ++i) { + if (!isl_basic_set_eq_is_stride(aff, i)) + continue; + k = isl_basic_map_alloc_equality(bmap); + if (k < 0) + goto error; + isl_seq_clr(bmap->eq[k], 1 + nparam); + isl_seq_cpy(bmap->eq[k] + 1 + nparam + d, + aff->eq[i] + 1 + nparam, d); + isl_seq_neg(bmap->eq[k] + 1 + nparam, + aff->eq[i] + 1 + nparam, d); + isl_seq_cpy(bmap->eq[k] + 1 + nparam + 2 * d, + aff->eq[i] + 1 + nparam + d, aff->n_div); + isl_int_set_si(bmap->eq[k][1 + total + aff->n_div], 0); + } + obj = isl_vec_alloc(map->ctx, 1 + nparam + d); + if (!obj) + goto error; + isl_seq_clr(obj->el, 1 + nparam + d); + for (i = 0; i < d; ++ i) { + enum isl_lp_result res; + + isl_int_set_si(obj->el[1 + nparam + i], 1); + + res = isl_set_solve_lp(delta, 0, obj->el, map->ctx->one, &opt, + NULL, NULL); + if (res == isl_lp_error) + goto error; + if (res == isl_lp_ok) { + k = isl_basic_map_alloc_inequality(bmap); + if (k < 0) + goto error; + isl_seq_clr(bmap->ineq[k], + 1 + nparam + 2 * d + bmap->n_div); + isl_int_set_si(bmap->ineq[k][1 + nparam + i], -1); + isl_int_set_si(bmap->ineq[k][1 + nparam + d + i], 1); + isl_int_neg(bmap->ineq[k][1 + nparam + 2 * d + aff->n_div], opt); + } + + res = isl_set_solve_lp(delta, 1, obj->el, map->ctx->one, &opt, + NULL, NULL); + if (res == isl_lp_error) + goto error; + if (res == isl_lp_ok) { + k = isl_basic_map_alloc_inequality(bmap); + if (k < 0) + goto error; + isl_seq_clr(bmap->ineq[k], + 1 + nparam + 2 * d + bmap->n_div); + isl_int_set_si(bmap->ineq[k][1 + nparam + i], 1); + isl_int_set_si(bmap->ineq[k][1 + nparam + d + i], -1); + isl_int_set(bmap->ineq[k][1 + nparam + 2 * d + aff->n_div], opt); + } + + isl_int_set_si(obj->el[1 + nparam + i], 0); + } + k = isl_basic_map_alloc_inequality(bmap); + if (k < 0) + goto error; + isl_seq_clr(bmap->ineq[k], + 1 + nparam + 2 * d + bmap->n_div); + if (!with_id) + isl_int_set_si(bmap->ineq[k][0], -1); + isl_int_set_si(bmap->ineq[k][1 + nparam + 2 * d + aff->n_div], 1); + + app = isl_map_from_domain_and_range(dom, ran); + + isl_vec_free(obj); + isl_basic_set_free(aff); + isl_map_free(map); + bmap = isl_basic_map_finalize(bmap); + isl_set_free(delta); + isl_int_clear(opt); + + map = isl_map_from_basic_map(bmap); + map = isl_map_intersect(map, app); + + return map; +error: + isl_vec_free(obj); + isl_basic_map_free(bmap); + isl_basic_set_free(aff); + isl_set_free(dom); + isl_set_free(ran); + isl_map_free(map); + isl_set_free(delta); + isl_int_clear(opt); + return NULL; +} + +/* Given a map, compute the smallest superset of this map that is of the form + * + * { i -> j : L <= j - i <= U and exists a_p: j_p - i_p = M_p a_p } + * + * (where p ranges over the (non-parametric) dimensions), + * compute the transitive closure of this map, i.e., + * + * { i -> j : exists k > 0: + * k L <= j - i <= k U and exists a: j_p - i_p = M_p a_p } + * + * and intersect domain and range of this transitive closure with + * domain and range of the original map. + */ +static __isl_give isl_map *box_closure(__isl_take isl_map *map) +{ + isl_set *domain; + isl_set *range; + + domain = isl_map_domain(isl_map_copy(map)); + domain = isl_set_coalesce(domain); + range = isl_map_range(isl_map_copy(map)); + range = isl_set_coalesce(range); + + return box_closure_on_domain(map, domain, range, 0); +} + +/* Given a map, compute the smallest superset of this map that is of the form + * + * { i -> j : L <= j - i <= U and exists a_p: j_p - i_p = M_p a_p } + * + * (where p ranges over the (non-parametric) dimensions), + * compute the transitive and partially reflexive closure of this map, i.e., + * + * { i -> j : exists k >= 0: + * k L <= j - i <= k U and exists a: j_p - i_p = M_p a_p } + * + * and intersect domain and range of this transitive closure with + * the given domain. + */ +static __isl_give isl_map *box_closure_with_identity(__isl_take isl_map *map, + __isl_take isl_set *dom) +{ + return box_closure_on_domain(map, dom, isl_set_copy(dom), 1); +} + +/* Check whether app is the transitive closure of map. + * In particular, check that app is acyclic and, if so, + * check that + * + * app \subset (map \cup (map \circ app)) + */ +static isl_bool check_exactness_omega(__isl_keep isl_map *map, + __isl_keep isl_map *app) +{ + isl_set *delta; + int i; + isl_bool is_empty, is_exact; + isl_size d; + isl_map *test; + + delta = isl_map_deltas(isl_map_copy(app)); + d = isl_set_dim(delta, isl_dim_set); + if (d < 0) + delta = isl_set_free(delta); + for (i = 0; i < d; ++i) + delta = isl_set_fix_si(delta, isl_dim_set, i, 0); + is_empty = isl_set_is_empty(delta); + isl_set_free(delta); + if (is_empty < 0 || !is_empty) + return is_empty; + + test = isl_map_apply_range(isl_map_copy(app), isl_map_copy(map)); + test = isl_map_union(test, isl_map_copy(map)); + is_exact = isl_map_is_subset(app, test); + isl_map_free(test); + + return is_exact; +} + +/* Check if basic map M_i can be combined with all the other + * basic maps such that + * + * (\cup_j M_j)^+ + * + * can be computed as + * + * M_i \cup (\cup_{j \ne i} M_i^* \circ M_j \circ M_i^*)^+ + * + * In particular, check if we can compute a compact representation + * of + * + * M_i^* \circ M_j \circ M_i^* + * + * for each j != i. + * Let M_i^? be an extension of M_i^+ that allows paths + * of length zero, i.e., the result of box_closure(., 1). + * The criterion, as proposed by Kelly et al., is that + * id = M_i^? - M_i^+ can be represented as a basic map + * and that + * + * id \circ M_j \circ id = M_j + * + * for each j != i. + * + * If this function returns 1, then tc and qc are set to + * M_i^+ and M_i^?, respectively. + */ +static int can_be_split_off(__isl_keep isl_map *map, int i, + __isl_give isl_map **tc, __isl_give isl_map **qc) +{ + isl_map *map_i, *id = NULL; + int j = -1; + isl_set *C; + + *tc = NULL; + *qc = NULL; + + C = isl_set_union(isl_map_domain(isl_map_copy(map)), + isl_map_range(isl_map_copy(map))); + C = isl_set_from_basic_set(isl_set_simple_hull(C)); + if (!C) + goto error; + + map_i = isl_map_from_basic_map(isl_basic_map_copy(map->p[i])); + *tc = box_closure(isl_map_copy(map_i)); + *qc = box_closure_with_identity(map_i, C); + id = isl_map_subtract(isl_map_copy(*qc), isl_map_copy(*tc)); + + if (!id || !*qc) + goto error; + if (id->n != 1 || (*qc)->n != 1) + goto done; + + for (j = 0; j < map->n; ++j) { + isl_map *map_j, *test; + int is_ok; + + if (i == j) + continue; + map_j = isl_map_from_basic_map( + isl_basic_map_copy(map->p[j])); + test = isl_map_apply_range(isl_map_copy(id), + isl_map_copy(map_j)); + test = isl_map_apply_range(test, isl_map_copy(id)); + is_ok = isl_map_is_equal(test, map_j); + isl_map_free(map_j); + isl_map_free(test); + if (is_ok < 0) + goto error; + if (!is_ok) + break; + } + +done: + isl_map_free(id); + if (j == map->n) + return 1; + + isl_map_free(*qc); + isl_map_free(*tc); + *qc = NULL; + *tc = NULL; + + return 0; +error: + isl_map_free(id); + isl_map_free(*qc); + isl_map_free(*tc); + *qc = NULL; + *tc = NULL; + return -1; +} + +static __isl_give isl_map *box_closure_with_check(__isl_take isl_map *map, + isl_bool *exact) +{ + isl_map *app; + + app = box_closure(isl_map_copy(map)); + if (exact) { + isl_bool is_exact = check_exactness_omega(map, app); + + if (is_exact < 0) + app = isl_map_free(app); + else + *exact = is_exact; + } + + isl_map_free(map); + return app; +} + +/* Compute an overapproximation of the transitive closure of "map" + * using a variation of the algorithm from + * "Transitive Closure of Infinite Graphs and its Applications" + * by Kelly et al. + * + * We first check whether we can can split of any basic map M_i and + * compute + * + * (\cup_j M_j)^+ + * + * as + * + * M_i \cup (\cup_{j \ne i} M_i^* \circ M_j \circ M_i^*)^+ + * + * using a recursive call on the remaining map. + * + * If not, we simply call box_closure on the whole map. + */ +static __isl_give isl_map *transitive_closure_omega(__isl_take isl_map *map, + isl_bool *exact) +{ + int i, j; + isl_bool exact_i; + isl_map *app; + + if (!map) + return NULL; + if (map->n == 1) + return box_closure_with_check(map, exact); + + for (i = 0; i < map->n; ++i) { + int ok; + isl_map *qc, *tc; + ok = can_be_split_off(map, i, &tc, &qc); + if (ok < 0) + goto error; + if (!ok) + continue; + + app = isl_map_alloc_space(isl_map_get_space(map), map->n - 1, 0); + + for (j = 0; j < map->n; ++j) { + if (j == i) + continue; + app = isl_map_add_basic_map(app, + isl_basic_map_copy(map->p[j])); + } + + app = isl_map_apply_range(isl_map_copy(qc), app); + app = isl_map_apply_range(app, qc); + + app = isl_map_union(tc, transitive_closure_omega(app, NULL)); + exact_i = check_exactness_omega(map, app); + if (exact_i == isl_bool_true) { + if (exact) + *exact = exact_i; + isl_map_free(map); + return app; + } + isl_map_free(app); + if (exact_i < 0) + goto error; + } + + return box_closure_with_check(map, exact); +error: + isl_map_free(map); + return NULL; +} + +/* Compute the transitive closure of "map", or an overapproximation. + * If the result is exact, then *exact is set to 1. + * Simply use map_power to compute the powers of map, but tell + * it to project out the lengths of the paths instead of equating + * the length to a parameter. + */ +__isl_give isl_map *isl_map_transitive_closure(__isl_take isl_map *map, + isl_bool *exact) +{ + isl_space *target_dim; + isl_bool closed; + + if (!map) + goto error; + + if (map->ctx->opt->closure == ISL_CLOSURE_BOX) + return transitive_closure_omega(map, exact); + + map = isl_map_compute_divs(map); + map = isl_map_coalesce(map); + closed = isl_map_is_transitively_closed(map); + if (closed < 0) + goto error; + if (closed) { + if (exact) + *exact = isl_bool_true; + return map; + } + + target_dim = isl_map_get_space(map); + map = map_power(map, exact, 1); + map = isl_map_reset_space(map, target_dim); + + return map; +error: + isl_map_free(map); + return NULL; +} + +static isl_stat inc_count(__isl_take isl_map *map, void *user) +{ + int *n = user; + + *n += map->n; + + isl_map_free(map); + + return isl_stat_ok; +} + +static isl_stat collect_basic_map(__isl_take isl_map *map, void *user) +{ + int i; + isl_basic_map ***next = user; + + for (i = 0; i < map->n; ++i) { + **next = isl_basic_map_copy(map->p[i]); + if (!**next) + goto error; + (*next)++; + } + + isl_map_free(map); + return isl_stat_ok; +error: + isl_map_free(map); + return isl_stat_error; +} + +/* Perform Floyd-Warshall on the given list of basic relations. + * The basic relations may live in different dimensions, + * but basic relations that get assigned to the diagonal of the + * grid have domains and ranges of the same dimension and so + * the standard algorithm can be used because the nested transitive + * closures are only applied to diagonal elements and because all + * compositions are performed on relations with compatible domains and ranges. + */ +static __isl_give isl_union_map *union_floyd_warshall_on_list(isl_ctx *ctx, + __isl_keep isl_basic_map **list, int n, isl_bool *exact) +{ + int i, j, k; + int n_group; + int *group = NULL; + isl_set **set = NULL; + isl_map ***grid = NULL; + isl_union_map *app; + + group = setup_groups(ctx, list, n, &set, &n_group); + if (!group) + goto error; + + grid = isl_calloc_array(ctx, isl_map **, n_group); + if (!grid) + goto error; + for (i = 0; i < n_group; ++i) { + grid[i] = isl_calloc_array(ctx, isl_map *, n_group); + if (!grid[i]) + goto error; + for (j = 0; j < n_group; ++j) { + isl_space *space1, *space2, *space; + space1 = isl_space_reverse(isl_set_get_space(set[i])); + space2 = isl_set_get_space(set[j]); + space = isl_space_join(space1, space2); + grid[i][j] = isl_map_empty(space); + } + } + + for (k = 0; k < n; ++k) { + i = group[2 * k]; + j = group[2 * k + 1]; + grid[i][j] = isl_map_union(grid[i][j], + isl_map_from_basic_map( + isl_basic_map_copy(list[k]))); + } + + floyd_warshall_iterate(grid, n_group, exact); + + app = isl_union_map_empty(isl_map_get_space(grid[0][0])); + + for (i = 0; i < n_group; ++i) { + for (j = 0; j < n_group; ++j) + app = isl_union_map_add_map(app, grid[i][j]); + free(grid[i]); + } + free(grid); + + for (i = 0; i < 2 * n; ++i) + isl_set_free(set[i]); + free(set); + + free(group); + return app; +error: + if (grid) + for (i = 0; i < n_group; ++i) { + if (!grid[i]) + continue; + for (j = 0; j < n_group; ++j) + isl_map_free(grid[i][j]); + free(grid[i]); + } + free(grid); + if (set) { + for (i = 0; i < 2 * n; ++i) + isl_set_free(set[i]); + free(set); + } + free(group); + return NULL; +} + +/* Perform Floyd-Warshall on the given union relation. + * The implementation is very similar to that for non-unions. + * The main difference is that it is applied unconditionally. + * We first extract a list of basic maps from the union map + * and then perform the algorithm on this list. + */ +static __isl_give isl_union_map *union_floyd_warshall( + __isl_take isl_union_map *umap, isl_bool *exact) +{ + int i, n; + isl_ctx *ctx; + isl_basic_map **list = NULL; + isl_basic_map **next; + isl_union_map *res; + + n = 0; + if (isl_union_map_foreach_map(umap, inc_count, &n) < 0) + goto error; + + ctx = isl_union_map_get_ctx(umap); + list = isl_calloc_array(ctx, isl_basic_map *, n); + if (!list) + goto error; + + next = list; + if (isl_union_map_foreach_map(umap, collect_basic_map, &next) < 0) + goto error; + + res = union_floyd_warshall_on_list(ctx, list, n, exact); + + if (list) { + for (i = 0; i < n; ++i) + isl_basic_map_free(list[i]); + free(list); + } + + isl_union_map_free(umap); + return res; +error: + if (list) { + for (i = 0; i < n; ++i) + isl_basic_map_free(list[i]); + free(list); + } + isl_union_map_free(umap); + return NULL; +} + +/* Decompose the give union relation into strongly connected components. + * The implementation is essentially the same as that of + * construct_power_components with the major difference that all + * operations are performed on union maps. + */ +static __isl_give isl_union_map *union_components( + __isl_take isl_union_map *umap, isl_bool *exact) +{ + int i; + int n; + isl_ctx *ctx; + isl_basic_map **list = NULL; + isl_basic_map **next; + isl_union_map *path = NULL; + struct isl_tc_follows_data data; + struct isl_tarjan_graph *g = NULL; + int c, l; + int recheck = 0; + + n = 0; + if (isl_union_map_foreach_map(umap, inc_count, &n) < 0) + goto error; + + if (n == 0) + return umap; + if (n <= 1) + return union_floyd_warshall(umap, exact); + + ctx = isl_union_map_get_ctx(umap); + list = isl_calloc_array(ctx, isl_basic_map *, n); + if (!list) + goto error; + + next = list; + if (isl_union_map_foreach_map(umap, collect_basic_map, &next) < 0) + goto error; + + data.list = list; + data.check_closed = 0; + g = isl_tarjan_graph_init(ctx, n, &basic_map_follows, &data); + if (!g) + goto error; + + c = 0; + i = 0; + l = n; + path = isl_union_map_empty(isl_union_map_get_space(umap)); + while (l) { + isl_union_map *comp; + isl_union_map *path_comp, *path_comb; + comp = isl_union_map_empty(isl_union_map_get_space(umap)); + while (g->order[i] != -1) { + comp = isl_union_map_add_map(comp, + isl_map_from_basic_map( + isl_basic_map_copy(list[g->order[i]]))); + --l; + ++i; + } + path_comp = union_floyd_warshall(comp, exact); + path_comb = isl_union_map_apply_range(isl_union_map_copy(path), + isl_union_map_copy(path_comp)); + path = isl_union_map_union(path, path_comp); + path = isl_union_map_union(path, path_comb); + ++i; + ++c; + } + + if (c > 1 && data.check_closed && !*exact) { + isl_bool closed; + + closed = isl_union_map_is_transitively_closed(path); + if (closed < 0) + goto error; + recheck = !closed; + } + + isl_tarjan_graph_free(g); + + for (i = 0; i < n; ++i) + isl_basic_map_free(list[i]); + free(list); + + if (recheck) { + isl_union_map_free(path); + return union_floyd_warshall(umap, exact); + } + + isl_union_map_free(umap); + + return path; +error: + isl_tarjan_graph_free(g); + if (list) { + for (i = 0; i < n; ++i) + isl_basic_map_free(list[i]); + free(list); + } + isl_union_map_free(umap); + isl_union_map_free(path); + return NULL; +} + +/* Compute the transitive closure of "umap", or an overapproximation. + * If the result is exact, then *exact is set to 1. + */ +__isl_give isl_union_map *isl_union_map_transitive_closure( + __isl_take isl_union_map *umap, isl_bool *exact) +{ + isl_bool closed; + + if (!umap) + return NULL; + + if (exact) + *exact = isl_bool_true; + + umap = isl_union_map_compute_divs(umap); + umap = isl_union_map_coalesce(umap); + closed = isl_union_map_is_transitively_closed(umap); + if (closed < 0) + goto error; + if (closed) + return umap; + umap = union_components(umap, exact); + return umap; +error: + isl_union_map_free(umap); + return NULL; +} + +struct isl_union_power { + isl_union_map *pow; + isl_bool *exact; +}; + +static isl_stat power(__isl_take isl_map *map, void *user) +{ + struct isl_union_power *up = user; + + map = isl_map_power(map, up->exact); + up->pow = isl_union_map_from_map(map); + + return isl_stat_error; +} + +/* Construct a map [[x]->[y]] -> [y-x], with parameters prescribed by "space". + */ +static __isl_give isl_union_map *deltas_map(__isl_take isl_space *space) +{ + isl_basic_map *bmap; + + space = isl_space_add_dims(space, isl_dim_in, 1); + space = isl_space_add_dims(space, isl_dim_out, 1); + bmap = isl_basic_map_universe(space); + bmap = isl_basic_map_deltas_map(bmap); + + return isl_union_map_from_map(isl_map_from_basic_map(bmap)); +} + +/* Compute the positive powers of "map", or an overapproximation. + * The result maps the exponent to a nested copy of the corresponding power. + * If the result is exact, then *exact is set to 1. + */ +__isl_give isl_union_map *isl_union_map_power(__isl_take isl_union_map *umap, + isl_bool *exact) +{ + isl_size n; + isl_union_map *inc; + isl_union_map *dm; + + n = isl_union_map_n_map(umap); + if (n < 0) + return isl_union_map_free(umap); + if (n == 0) + return umap; + if (n == 1) { + struct isl_union_power up = { NULL, exact }; + isl_union_map_foreach_map(umap, &power, &up); + isl_union_map_free(umap); + return up.pow; + } + inc = isl_union_map_from_map(increment(isl_union_map_get_space(umap))); + umap = isl_union_map_product(inc, umap); + umap = isl_union_map_transitive_closure(umap, exact); + umap = isl_union_map_zip(umap); + dm = deltas_map(isl_union_map_get_space(umap)); + umap = isl_union_map_apply_domain(umap, dm); + + return umap; +} + +#undef TYPE +#define TYPE isl_map +#include "isl_power_templ.c" + +#undef TYPE +#define TYPE isl_union_map +#include "isl_power_templ.c" diff --git a/external/mit/isl/dist/isl_type_check_equal_space_templ.c b/external/mit/isl/dist/isl_type_check_equal_space_templ.c new file mode 100644 index 000000000000..97a0a354a071 --- /dev/null +++ b/external/mit/isl/dist/isl_type_check_equal_space_templ.c @@ -0,0 +1,25 @@ +/* + * Copyright 2011 Sven Verdoolaege + * + * Use of this software is governed by the MIT license + * + * Written by Sven Verdoolaege + */ + +/* Check that "obj1" and "obj2" live in the same space, + * reporting an error if they do not. + */ +isl_stat FN(TYPE_PAIR,check_equal_space)(__isl_keep TYPE1 *obj1, + __isl_keep TYPE2 *obj2) +{ + isl_bool equal; + + equal = FN(TYPE_PAIR,has_equal_space)(obj1, obj2); + if (equal < 0) + return isl_stat_error; + if (!equal) + isl_die(FN(TYPE1,get_ctx)(obj1), isl_error_invalid, + "spaces don't match", return isl_stat_error); + + return isl_stat_ok; +} diff --git a/external/mit/isl/dist/isl_type_check_match_range_multi_val.c b/external/mit/isl/dist/isl_type_check_match_range_multi_val.c new file mode 100644 index 000000000000..3b60e4db5b57 --- /dev/null +++ b/external/mit/isl/dist/isl_type_check_match_range_multi_val.c @@ -0,0 +1,32 @@ +#define xFN(TYPE,NAME) TYPE ## _ ## NAME +#define FN(TYPE,NAME) xFN(TYPE,NAME) + +/* Does the range space of "obj" match the space of "mv" (ignoring parameters)? + */ +static isl_bool FN(TYPE,match_range_multi_val)(__isl_keep TYPE *obj, + __isl_keep isl_multi_val *mv) +{ + isl_space *space, *mv_space; + + space = FN(TYPE,peek_space)(obj); + mv_space = isl_multi_val_peek_space(mv); + return isl_space_tuple_is_equal(space, isl_dim_out, + mv_space, isl_dim_set); +} + +/* Check that the range space of "obj" matches the space of "mv" + * (ignoring parameters). + */ +static isl_stat FN(TYPE,check_match_range_multi_val)(__isl_keep TYPE *obj, + __isl_keep isl_multi_val *mv) +{ + isl_bool equal; + + equal = FN(TYPE,match_range_multi_val)(obj, mv); + if (equal < 0) + return isl_stat_error; + if (!equal) + isl_die(isl_multi_val_get_ctx(mv), isl_error_invalid, + "spaces don't match", return isl_stat_error); + return isl_stat_ok; +} diff --git a/external/mit/isl/dist/isl_type_has_equal_space_bin_templ.c b/external/mit/isl/dist/isl_type_has_equal_space_bin_templ.c new file mode 100644 index 000000000000..f435753aec7c --- /dev/null +++ b/external/mit/isl/dist/isl_type_has_equal_space_bin_templ.c @@ -0,0 +1,8 @@ +#undef TYPE1 +#define TYPE1 TYPE +#undef TYPE2 +#define TYPE2 TYPE +#undef TYPE_PAIR +#define TYPE_PAIR TYPE + +#include "isl_type_has_equal_space_templ.c" diff --git a/external/mit/isl/dist/isl_type_has_equal_space_templ.c b/external/mit/isl/dist/isl_type_has_equal_space_templ.c new file mode 100644 index 000000000000..2753d4599a4c --- /dev/null +++ b/external/mit/isl/dist/isl_type_has_equal_space_templ.c @@ -0,0 +1,28 @@ +/* + * Copyright 2010 INRIA Saclay + * + * 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 + */ + +#define xFN(TYPE,NAME) TYPE ## _ ## NAME +#define FN(TYPE,NAME) xFN(TYPE,NAME) + +#ifndef PEEK_SPACE +#define PEEK_SPACE peek_space +#endif + +/* Do "obj1" and "obj2" have the same space? + */ +isl_bool FN(TYPE_PAIR,has_equal_space)(__isl_keep TYPE1 *obj1, + __isl_keep TYPE2 *obj2) +{ + isl_space *space1, *space2; + + space1 = FN(TYPE1,PEEK_SPACE)(obj1); + space2 = FN(TYPE2,PEEK_SPACE)(obj2); + return isl_space_is_equal(space1, space2); +} diff --git a/external/mit/isl/dist/isl_type_has_space_templ.c b/external/mit/isl/dist/isl_type_has_space_templ.c new file mode 100644 index 000000000000..313b27a47cce --- /dev/null +++ b/external/mit/isl/dist/isl_type_has_space_templ.c @@ -0,0 +1,18 @@ +/* + * Copyright 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 + */ + +#define xFN(TYPE,NAME) TYPE ## _ ## NAME +#define FN(TYPE,NAME) xFN(TYPE,NAME) + +/* Is the space of "obj" equal to "space"? + */ +isl_bool FN(TYPE,has_space)(__isl_keep TYPE *obj, __isl_keep isl_space *space) +{ + return isl_space_is_equal(FN(TYPE,peek_space)(obj), space); +} diff --git a/external/mit/isl/dist/isl_unbind_params_templ.c b/external/mit/isl/dist/isl_unbind_params_templ.c new file mode 100644 index 000000000000..3365c7a686c8 --- /dev/null +++ b/external/mit/isl/dist/isl_unbind_params_templ.c @@ -0,0 +1,35 @@ +/* + * Copyright 2018 Sven Verdoolaege + * + * Use of this software is governed by the MIT license + * + * Written by Sven Verdoolaege. + */ + +/* Given a function "obj" defined over a parameter domain, + * convert it to a function defined over a domain corresponding + * to "domain". + * Any parameters with identifiers in "domain" are reinterpreted + * as the corresponding domain dimensions. + */ +__isl_give TYPE *FN(TYPE,unbind_params_insert_domain)( + __isl_take TYPE *obj, __isl_take isl_multi_id *domain) +{ + isl_bool is_params; + isl_space *space; + isl_reordering *r; + + space = FN(TYPE,get_domain_space)(obj); + is_params = isl_space_is_params(space); + if (is_params < 0) + domain = isl_multi_id_free(domain); + else if (!is_params) + isl_die(FN(TYPE,get_ctx)(obj), isl_error_invalid, + "expecting function with parameter domain", + domain = isl_multi_id_free(domain)); + r = isl_reordering_unbind_params_insert_domain(space, domain); + isl_space_free(space); + isl_multi_id_free(domain); + + return FN(TYPE,realign_domain)(obj, r); +} diff --git a/external/mit/isl/dist/isl_union_domain_reverse_templ.c b/external/mit/isl/dist/isl_union_domain_reverse_templ.c new file mode 100644 index 000000000000..92d4d5344502 --- /dev/null +++ b/external/mit/isl/dist/isl_union_domain_reverse_templ.c @@ -0,0 +1,39 @@ +/* + * Copyright 2023 Sven Verdoolaege + * + * Use of this software is governed by the MIT license + * + * Written by Sven Verdoolaege + */ + +/* Is "part" defined over a domain wrapping a binary relation? + */ +static isl_bool FN(UNION,select_domain_is_wrapping_entry)(__isl_keep PART *part, + void *user) +{ + return isl_space_domain_is_wrapping(FN(PART,peek_space)(part)); +} + +/* Wrapper around PART_domain_reverse for use + * as an isl_union_*_transform callback. + */ +static __isl_give PART *FN(UNION,domain_reverse_entry)(__isl_take PART *part, + void *user) +{ + return FN(PART,domain_reverse)(part); +} + +/* For each base expression defined on a domain (A -> B), + * interchange A and B in the wrapped domain + * to obtain an expression on the domain (B -> A) and + * collect the results. + */ +__isl_give UNION *FN(UNION,domain_reverse)(__isl_keep UNION *u) +{ + S(UNION,transform_control) control = { + .filter = &FN(UNION,select_domain_is_wrapping_entry), + .fn = &FN(UNION,domain_reverse_entry), + }; + + return FN(UNION,transform)(u, &control); +} diff --git a/external/mit/isl/dist/isl_union_eval.c b/external/mit/isl/dist/isl_union_eval.c new file mode 100644 index 000000000000..050eb8af289c --- /dev/null +++ b/external/mit/isl/dist/isl_union_eval.c @@ -0,0 +1,82 @@ +/* + * Copyright 2010 INRIA Saclay + * + * 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 + */ + +#include + +/* Evaluate "u" in the void point "pnt". + * In particular, return the value NaN. + */ +static __isl_give isl_val *FN(UNION,eval_void)(__isl_take UNION *u, + __isl_take isl_point *pnt) +{ + isl_ctx *ctx; + + ctx = isl_point_get_ctx(pnt); + FN(UNION,free)(u); + isl_point_free(pnt); + return isl_val_nan(ctx); +} + +/* Internal data structure for isl_union_*_eval. + * + * "pnt" is the point in which the function is evaluated. + * "v" stores the result and is initialized to zero. + */ +S(UNION,eval_data) { + isl_point *pnt; + isl_val *v; +}; + +/* Update the evaluation in data->v based on the evaluation of "part". + * + * Only (at most) a single part on which this function is called + * is assumed to evaluate to anything other than zero. + * Since the value is initialized to zero, the evaluation of "part" + * can simply be added. + */ +static isl_stat FN(UNION,eval_entry)(__isl_take PART *part, void *user) +{ + S(UNION,eval_data) *data = user; + isl_val *v; + + v = FN(PART,eval)(part, isl_point_copy(data->pnt)); + data->v = isl_val_add(data->v, v); + + return isl_stat_non_null(data->v); +} + +/* Evaluate "u" in the point "pnt". + */ +__isl_give isl_val *FN(UNION,eval)(__isl_take UNION *u, + __isl_take isl_point *pnt) +{ + S(UNION,eval_data) data = { pnt }; + isl_bool is_void; + isl_space *space; + + is_void = isl_point_is_void(pnt); + if (is_void < 0) + goto error; + if (is_void) + return FN(UNION,eval_void)(u, pnt); + + data.v = isl_val_zero(isl_point_get_ctx(pnt)); + space = isl_point_peek_space(pnt); + if (FN(UNION,foreach_on_domain)(u, space, + &FN(UNION,eval_entry), &data) < 0) + data.v = isl_val_free(data.v); + FN(UNION,free)(u); + isl_point_free(pnt); + return data.v; +error: + FN(UNION,free)(u); + isl_point_free(pnt); + return NULL; +} diff --git a/external/mit/isl/dist/isl_union_locals_templ.c b/external/mit/isl/dist/isl_union_locals_templ.c new file mode 100644 index 000000000000..c7387bb26f7c --- /dev/null +++ b/external/mit/isl/dist/isl_union_locals_templ.c @@ -0,0 +1,27 @@ +/* + * Copyright 2020 Cerebras Systems + * + * Use of this software is governed by the MIT license + * + * Written by Sven Verdoolaege, + * Cerebras Systems, 175 S San Antonio Rd, Los Altos, CA, USA + */ + +/* isl_union_*_every_* callback that checks whether "pw" + * is free of local variables. + */ +static isl_bool FN(UNION,no_locals_el)(__isl_keep PW *pw, void *user) +{ + return isl_bool_not(FN(PW,involves_locals)(pw)); +} + +/* Does "u" involve any local variables, i.e., integer divisions? + */ +isl_bool FN(UNION,involves_locals)(__isl_keep UNION *u) +{ + isl_bool no_locals; + + no_locals = FN(FN(UNION,every),BASE)(u, &FN(UNION,no_locals_el), NULL); + + return isl_bool_not(no_locals); +} diff --git a/external/mit/isl/dist/isl_union_macro.h b/external/mit/isl/dist/isl_union_macro.h new file mode 100644 index 000000000000..2cc21a90a84c --- /dev/null +++ b/external/mit/isl/dist/isl_union_macro.h @@ -0,0 +1,10 @@ +#define xCAT(A,B) A ## B +#define CAT(A,B) xCAT(A,B) +#undef PART +#define PART CAT(isl_,BASE) +#undef UNION +#define UNION CAT(isl_union_,BASE) +#define xFN(TYPE,NAME) TYPE ## _ ## NAME +#define FN(TYPE,NAME) xFN(TYPE,NAME) +#define xS(TYPE,NAME) struct TYPE ## _ ## NAME +#define S(TYPE,NAME) xS(TYPE,NAME) diff --git a/external/mit/isl/dist/isl_union_map.c b/external/mit/isl/dist/isl_union_map.c new file mode 100644 index 000000000000..5a0f40ecc391 --- /dev/null +++ b/external/mit/isl/dist/isl_union_map.c @@ -0,0 +1,4658 @@ +/* + * Copyright 2010-2011 INRIA Saclay + * Copyright 2013-2014 Ecole Normale Superieure + * Copyright 2014 INRIA Rocquencourt + * Copyright 2016-2017 Sven Verdoolaege + * Copyright 2022 Cerebras Systems + * + * 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 Inria Paris - Rocquencourt, Domaine de Voluceau - Rocquencourt, + * B.P. 105 - 78153 Le Chesnay, France + * and Cerebras Systems, 1237 E Arques Ave, Sunnyvale, CA, USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#undef TYPE +#define TYPE isl_union_map +static +#include "has_single_reference_templ.c" +static +#include "check_single_reference_templ.c" + +/* Return the number of parameters of "umap", where "type" + * is required to be set to isl_dim_param. + */ +isl_size isl_union_map_dim(__isl_keep isl_union_map *umap, + enum isl_dim_type type) +{ + if (!umap) + return isl_size_error; + + if (type != isl_dim_param) + isl_die(isl_union_map_get_ctx(umap), isl_error_invalid, + "can only reference parameters", return isl_size_error); + + return isl_space_dim(umap->dim, type); +} + +/* Return the number of parameters of "uset", where "type" + * is required to be set to isl_dim_param. + */ +isl_size isl_union_set_dim(__isl_keep isl_union_set *uset, + enum isl_dim_type type) +{ + return isl_union_map_dim(uset, type); +} + +/* Return the id of the specified dimension. + */ +__isl_give isl_id *isl_union_map_get_dim_id(__isl_keep isl_union_map *umap, + enum isl_dim_type type, unsigned pos) +{ + if (!umap) + return NULL; + + if (type != isl_dim_param) + isl_die(isl_union_map_get_ctx(umap), isl_error_invalid, + "can only reference parameters", return NULL); + + return isl_space_get_dim_id(umap->dim, type, pos); +} + +/* Is this union set a parameter domain? + */ +isl_bool isl_union_set_is_params(__isl_keep isl_union_set *uset) +{ + isl_set *set; + isl_bool params; + + if (!uset) + return isl_bool_error; + if (uset->table.n != 1) + return isl_bool_false; + + set = isl_set_from_union_set(isl_union_set_copy(uset)); + params = isl_set_is_params(set); + isl_set_free(set); + return params; +} + +/* Is this union map actually a parameter domain? + * Users should never call this function. Outside of isl, + * a union map can never be a parameter domain. + */ +isl_bool isl_union_map_is_params(__isl_keep isl_union_map *umap) +{ + return isl_union_set_is_params(uset_from_umap(umap)); +} + +static __isl_give isl_union_map *isl_union_map_alloc( + __isl_take isl_space *space, int size) +{ + isl_union_map *umap; + + space = isl_space_params(space); + if (!space) + return NULL; + + umap = isl_calloc_type(space->ctx, isl_union_map); + if (!umap) { + isl_space_free(space); + return NULL; + } + + umap->ref = 1; + umap->dim = space; + if (isl_hash_table_init(space->ctx, &umap->table, size) < 0) + return isl_union_map_free(umap); + + return umap; +} + +/* Create an empty union map without specifying any parameters. + */ +__isl_give isl_union_map *isl_union_map_empty_ctx(isl_ctx *ctx) +{ + return isl_union_map_empty_space(isl_space_unit(ctx)); +} + +__isl_give isl_union_map *isl_union_map_empty_space(__isl_take isl_space *space) +{ + return isl_union_map_alloc(space, 16); +} + +/* This is an alternative name for the function above. + */ +__isl_give isl_union_map *isl_union_map_empty(__isl_take isl_space *space) +{ + return isl_union_map_empty_space(space); +} + +/* Create an empty union set without specifying any parameters. + */ +__isl_give isl_union_set *isl_union_set_empty_ctx(isl_ctx *ctx) +{ + return uset_from_umap(isl_union_map_empty_ctx(ctx)); +} + +__isl_give isl_union_set *isl_union_set_empty_space(__isl_take isl_space *space) +{ + return uset_from_umap(isl_union_map_empty_space(space)); +} + +/* This is an alternative name for the function above. + */ +__isl_give isl_union_set *isl_union_set_empty(__isl_take isl_space *space) +{ + return isl_union_set_empty_space(space); +} + +isl_ctx *isl_union_map_get_ctx(__isl_keep isl_union_map *umap) +{ + return umap ? umap->dim->ctx : NULL; +} + +isl_ctx *isl_union_set_get_ctx(__isl_keep isl_union_set *uset) +{ + return uset ? uset->dim->ctx : NULL; +} + +/* Return the space of "umap". + */ +__isl_keep isl_space *isl_union_map_peek_space(__isl_keep isl_union_map *umap) +{ + return umap ? umap->dim : NULL; +} + +/* Return the space of "uset". + */ +__isl_keep isl_space *isl_union_set_peek_space(__isl_keep isl_union_set *uset) +{ + return isl_union_map_peek_space(uset_to_umap(uset)); +} + +__isl_give isl_space *isl_union_map_get_space(__isl_keep isl_union_map *umap) +{ + return isl_space_copy(isl_union_map_peek_space(umap)); +} + +/* Return the position of the parameter with the given name + * in "umap". + * Return -1 if no such dimension can be found. + */ +int isl_union_map_find_dim_by_name(__isl_keep isl_union_map *umap, + enum isl_dim_type type, const char *name) +{ + if (!umap) + return -1; + return isl_space_find_dim_by_name(umap->dim, type, name); +} + +/* Return the position of the parameter with id "id" in "umap". + * Return -1 if no such dimension can be found. + */ +static int isl_union_map_find_dim_by_id(__isl_keep isl_union_map *umap, + enum isl_dim_type type, __isl_keep isl_id *id) +{ + isl_space *space; + + space = isl_union_map_peek_space(umap); + return isl_space_find_dim_by_id(space, type, id); +} + +__isl_give isl_space *isl_union_set_get_space(__isl_keep isl_union_set *uset) +{ + return isl_union_map_get_space(uset); +} + +static isl_stat free_umap_entry(void **entry, void *user) +{ + isl_map *map = *entry; + isl_map_free(map); + return isl_stat_ok; +} + +static isl_stat add_map(__isl_take isl_map *map, void *user) +{ + isl_union_map **umap = (isl_union_map **)user; + + *umap = isl_union_map_add_map(*umap, map); + + return isl_stat_ok; +} + +__isl_give isl_union_map *isl_union_map_dup(__isl_keep isl_union_map *umap) +{ + isl_union_map *dup; + + if (!umap) + return NULL; + + dup = isl_union_map_empty(isl_space_copy(umap->dim)); + if (isl_union_map_foreach_map(umap, &add_map, &dup) < 0) + goto error; + return dup; +error: + isl_union_map_free(dup); + return NULL; +} + +__isl_give isl_union_map *isl_union_map_cow(__isl_take isl_union_map *umap) +{ + if (!umap) + return NULL; + + if (umap->ref == 1) + return umap; + umap->ref--; + return isl_union_map_dup(umap); +} + +struct isl_union_align { + isl_reordering *exp; + isl_union_map *res; +}; + +static isl_stat align_entry(void **entry, void *user) +{ + isl_map *map = *entry; + isl_reordering *exp; + struct isl_union_align *data = user; + + exp = isl_reordering_extend_space(isl_reordering_copy(data->exp), + isl_map_get_space(map)); + + data->res = isl_union_map_add_map(data->res, + isl_map_realign(isl_map_copy(map), exp)); + + return isl_stat_ok; +} + +/* Align the parameters of umap along those of model. + * The result has the parameters of model first, in the same order + * as they appear in model, followed by any remaining parameters of + * umap that do not appear in model. + */ +__isl_give isl_union_map *isl_union_map_align_params( + __isl_take isl_union_map *umap, __isl_take isl_space *model) +{ + struct isl_union_align data = { NULL, NULL }; + isl_space *space; + isl_bool equal_params; + + space = isl_union_map_peek_space(umap); + equal_params = isl_space_has_equal_params(space, model); + if (equal_params < 0) + goto error; + if (equal_params) { + isl_space_free(model); + return umap; + } + + data.exp = isl_parameter_alignment_reordering(space, model); + if (!data.exp) + goto error; + + data.res = isl_union_map_alloc(isl_reordering_get_space(data.exp), + umap->table.n); + if (isl_hash_table_foreach(isl_union_map_get_ctx(umap), &umap->table, + &align_entry, &data) < 0) + goto error; + + isl_reordering_free(data.exp); + isl_union_map_free(umap); + isl_space_free(model); + return data.res; +error: + isl_reordering_free(data.exp); + isl_union_map_free(umap); + isl_union_map_free(data.res); + isl_space_free(model); + return NULL; +} + +__isl_give isl_union_set *isl_union_set_align_params( + __isl_take isl_union_set *uset, __isl_take isl_space *model) +{ + return isl_union_map_align_params(uset, model); +} + +/* This is a wrapper around isl_union_map_project_out for use + * by isl_union_map_drop_unused_params. + * + * In particular, this function is only called on parameters + * that are not involved in the description of "umap". + * Dropping those parameters is therefore equivalent + * to projecting them out. + */ +static __isl_give isl_union_map *isl_union_map_drop_dims( + __isl_take isl_union_map *umap, + enum isl_dim_type type, unsigned first, unsigned n) +{ + return isl_union_map_project_out(umap, type, first, n); +} + +#undef TYPE +#define TYPE isl_union_map +#include "isl_check_named_params_templ.c" +#include "isl_drop_unused_params_templ.c" + +/* Drop all parameters not referenced by "uset". + */ +__isl_give isl_union_set *isl_union_set_drop_unused_params( + __isl_take isl_union_set *uset) +{ + isl_union_map *umap; + + umap = isl_union_map_drop_unused_params(uset_to_umap(uset)); + return uset_from_umap(umap); +} + +__isl_give isl_union_map *isl_union_map_union(__isl_take isl_union_map *umap1, + __isl_take isl_union_map *umap2) +{ + umap1 = isl_union_map_align_params(umap1, isl_union_map_get_space(umap2)); + umap2 = isl_union_map_align_params(umap2, isl_union_map_get_space(umap1)); + + umap1 = isl_union_map_cow(umap1); + + if (!umap1 || !umap2) + goto error; + + if (isl_union_map_foreach_map(umap2, &add_map, &umap1) < 0) + goto error; + + isl_union_map_free(umap2); + + return umap1; +error: + isl_union_map_free(umap1); + isl_union_map_free(umap2); + return NULL; +} + +__isl_give isl_union_set *isl_union_set_union(__isl_take isl_union_set *uset1, + __isl_take isl_union_set *uset2) +{ + return isl_union_map_union(uset1, uset2); +} + +__isl_give isl_union_map *isl_union_map_copy(__isl_keep isl_union_map *umap) +{ + if (!umap) + return NULL; + + umap->ref++; + return umap; +} + +__isl_give isl_union_set *isl_union_set_copy(__isl_keep isl_union_set *uset) +{ + return isl_union_map_copy(uset); +} + +__isl_null isl_union_map *isl_union_map_free(__isl_take isl_union_map *umap) +{ + if (!umap) + return NULL; + + if (--umap->ref > 0) + return NULL; + + isl_hash_table_foreach(umap->dim->ctx, &umap->table, + &free_umap_entry, NULL); + isl_hash_table_clear(&umap->table); + isl_space_free(umap->dim); + free(umap); + return NULL; +} + +__isl_null isl_union_set *isl_union_set_free(__isl_take isl_union_set *uset) +{ + return isl_union_map_free(uset); +} + +/* Do "umap" and "space" have the same parameters? + */ +isl_bool isl_union_map_space_has_equal_params(__isl_keep isl_union_map *umap, + __isl_keep isl_space *space) +{ + isl_space *umap_space; + + umap_space = isl_union_map_peek_space(umap); + return isl_space_has_equal_params(umap_space, space); +} + +/* Do "uset" and "space" have the same parameters? + */ +isl_bool isl_union_set_space_has_equal_params(__isl_keep isl_union_set *uset, + __isl_keep isl_space *space) +{ + return isl_union_map_space_has_equal_params(uset_to_umap(uset), space); +} + +/* Is the space of the map at "entry" equal to "space", ignoring parameters? + */ +static isl_bool has_space_tuples(const void *entry, const void *val) +{ + isl_map *map = (isl_map *)entry; + isl_space *space = (isl_space *) val; + + return isl_map_has_space_tuples(map, space); +} + +/* Find the entry in "umap" with space "space" (ignoring parameters), + * returning isl_hash_table_entry_none if no such entry appears in "umap" and + * NULL on error. + * If "reserve" is set, then an entry is created if it does + * not exist already. Since this modifies the hash table in-place, + * this means "umap" must have a single reference when "reserve" is set. + */ +static struct isl_hash_table_entry *isl_union_map_find_entry( + __isl_keep isl_union_map *umap, __isl_keep isl_space *space, + int reserve) +{ + uint32_t hash; + + if (!umap || !space) + return NULL; + if (reserve && isl_union_map_check_single_reference(umap) < 0) + return NULL; + + hash = isl_space_get_tuple_hash(space); + return isl_hash_table_find(isl_union_map_get_ctx(umap), &umap->table, + hash, &has_space_tuples, space, reserve); +} + +/* Find the entry in "uset" with space "space" (ignoring parameters), + * returning isl_hash_table_entry_none if no such entry appears in "uset" and + * NULL on error. + * If "reserve" is set, then an entry is created if it does + * not exist already. In this case, a NULL return indicates an error. + */ +struct isl_hash_table_entry *isl_union_set_find_entry( + __isl_keep isl_union_set *uset, __isl_keep isl_space *space, + int reserve) +{ + return isl_union_map_find_entry(uset_to_umap(uset), space, reserve); +} + +__isl_give isl_union_map *isl_union_map_add_map(__isl_take isl_union_map *umap, + __isl_take isl_map *map) +{ + struct isl_hash_table_entry *entry; + isl_bool aligned; + isl_space *space; + + if (!map || !umap) + goto error; + + if (isl_map_plain_is_empty(map)) { + isl_map_free(map); + return umap; + } + + aligned = isl_map_space_has_equal_params(map, umap->dim); + if (aligned < 0) + goto error; + if (!aligned) { + umap = isl_union_map_align_params(umap, isl_map_get_space(map)); + map = isl_map_align_params(map, isl_union_map_get_space(umap)); + } + + umap = isl_union_map_cow(umap); + + space = isl_map_peek_space(map); + entry = isl_union_map_find_entry(umap, space, 1); + if (!entry) + goto error; + + if (!entry->data) + entry->data = map; + else { + entry->data = isl_map_union(entry->data, isl_map_copy(map)); + if (!entry->data) + goto error; + isl_map_free(map); + } + + return umap; +error: + isl_map_free(map); + isl_union_map_free(umap); + return NULL; +} + +__isl_give isl_union_set *isl_union_set_add_set(__isl_take isl_union_set *uset, + __isl_take isl_set *set) +{ + return isl_union_map_add_map(uset, set_to_map(set)); +} + +__isl_give isl_union_map *isl_union_map_from_map(__isl_take isl_map *map) +{ + isl_space *space; + isl_union_map *umap; + + if (!map) + return NULL; + + space = isl_map_get_space(map); + space = isl_space_params(space); + umap = isl_union_map_empty(space); + umap = isl_union_map_add_map(umap, map); + + return umap; +} + +/* This function performs the same operation as isl_union_map_from_map, + * but is considered as a function on an isl_map when exported. + */ +__isl_give isl_union_map *isl_map_to_union_map(__isl_take isl_map *map) +{ + return isl_union_map_from_map(map); +} + +__isl_give isl_union_set *isl_union_set_from_set(__isl_take isl_set *set) +{ + return isl_union_map_from_map(set_to_map(set)); +} + +/* This function performs the same operation as isl_union_set_from_set, + * but is considered as a function on an isl_set when exported. + */ +__isl_give isl_union_set *isl_set_to_union_set(__isl_take isl_set *set) +{ + return isl_union_set_from_set(set); +} + +__isl_give isl_union_map *isl_union_map_from_basic_map( + __isl_take isl_basic_map *bmap) +{ + return isl_union_map_from_map(isl_map_from_basic_map(bmap)); +} + +__isl_give isl_union_set *isl_union_set_from_basic_set( + __isl_take isl_basic_set *bset) +{ + return isl_union_map_from_basic_map(bset); +} + +struct isl_union_map_foreach_data +{ + isl_stat (*fn)(__isl_take isl_map *map, void *user); + void *user; +}; + +static isl_stat call_on_copy(void **entry, void *user) +{ + isl_map *map = *entry; + struct isl_union_map_foreach_data *data; + data = (struct isl_union_map_foreach_data *)user; + + return data->fn(isl_map_copy(map), data->user); +} + +isl_size isl_union_map_n_map(__isl_keep isl_union_map *umap) +{ + return umap ? umap->table.n : isl_size_error; +} + +isl_size isl_union_set_n_set(__isl_keep isl_union_set *uset) +{ + return uset ? uset->table.n : isl_size_error; +} + +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) +{ + struct isl_union_map_foreach_data data = { fn, user }; + + if (!umap) + return isl_stat_error; + + return isl_hash_table_foreach(umap->dim->ctx, &umap->table, + &call_on_copy, &data); +} + +/* Internal data structure for isl_union_map_every_map. + * + * "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 map. + */ +struct isl_union_map_every_data { + isl_bool (*test)(__isl_keep isl_map *map, void *user); + void *user; + int failed; +}; + +/* Call data->test on "map". + * If this fails, then set data->failed and abort. + */ +static isl_stat call_every(void **entry, void *user) +{ + isl_map *map = *entry; + struct isl_union_map_every_data *data = user; + isl_bool r; + + r = data->test(map, data->user); + if (r < 0) + return isl_stat_error; + if (r) + return isl_stat_ok; + data->failed = 1; + return isl_stat_error; +} + +/* Does "test" succeed on every map in "umap"? + */ +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) +{ + struct isl_union_map_every_data data = { test, user, 0 }; + isl_stat r; + + if (!umap) + return isl_bool_error; + + r = isl_hash_table_foreach(isl_union_map_get_ctx(umap), &umap->table, + &call_every, &data); + if (r >= 0) + return isl_bool_true; + if (data.failed) + return isl_bool_false; + return isl_bool_error; +} + +/* Add "map" to "list". + */ +static isl_stat add_list_map(__isl_take isl_map *map, void *user) +{ + isl_map_list **list = user; + + *list = isl_map_list_add(*list, map); + + if (!*list) + return isl_stat_error; + return isl_stat_ok; +} + +/* Return the maps in "umap" as a list. + * + * First construct a list of the appropriate size and then add all the + * elements. + */ +__isl_give isl_map_list *isl_union_map_get_map_list( + __isl_keep isl_union_map *umap) +{ + isl_size n_maps; + isl_ctx *ctx; + isl_map_list *list; + + n_maps = isl_union_map_n_map(umap); + if (n_maps < 0) + return NULL; + ctx = isl_union_map_get_ctx(umap); + list = isl_map_list_alloc(ctx, n_maps); + + if (isl_union_map_foreach_map(umap, &add_list_map, &list) < 0) + list = isl_map_list_free(list); + + return list; +} + +/* Return the sets in "uset" as a list. + */ +__isl_give isl_set_list *isl_union_set_get_set_list( + __isl_keep isl_union_set *uset) +{ + return set_list_from_map_list( + isl_union_map_get_map_list(uset_to_umap(uset))); +} + +/* Can "umap" be converted to an isl_map? + * That is, does it contain elements in exactly one space? + */ +isl_bool isl_union_map_isa_map(__isl_keep isl_union_map *umap) +{ + isl_size n; + + n = isl_union_map_n_map(umap); + if (n < 0) + return isl_bool_error; + return isl_bool_ok(n == 1); +} + +/* Can "uset" be converted to an isl_set? + * That is, does it contain elements in exactly one space? + */ +isl_bool isl_union_set_isa_set(__isl_keep isl_union_set *uset) +{ + return isl_union_map_isa_map(uset_to_umap(uset)); +} + +static isl_stat copy_map(void **entry, void *user) +{ + isl_map *map = *entry; + isl_map **map_p = user; + + *map_p = isl_map_copy(map); + + return isl_stat_error; +} + +__isl_give isl_map *isl_map_from_union_map(__isl_take isl_union_map *umap) +{ + isl_bool is_map; + isl_ctx *ctx; + isl_map *map = NULL; + + is_map = isl_union_map_isa_map(umap); + if (is_map < 0) + goto error; + ctx = isl_union_map_get_ctx(umap); + if (!is_map) + isl_die(ctx, isl_error_invalid, + "union map needs to contain elements in exactly " + "one space", goto error); + + isl_hash_table_foreach(ctx, &umap->table, ©_map, &map); + + isl_union_map_free(umap); + + return map; +error: + isl_union_map_free(umap); + return NULL; +} + +/* This function performs the same operation as isl_map_from_union_map, + * but is considered as a function on an isl_union_map when exported. + */ +__isl_give isl_map *isl_union_map_as_map(__isl_take isl_union_map *umap) +{ + return isl_map_from_union_map(umap); +} + +__isl_give isl_set *isl_set_from_union_set(__isl_take isl_union_set *uset) +{ + return isl_map_from_union_map(uset); +} + +/* This function performs the same operation as isl_set_from_union_set, + * but is considered as a function on an isl_union_set when exported. + */ +__isl_give isl_set *isl_union_set_as_set(__isl_take isl_union_set *uset) +{ + return isl_set_from_union_set(uset); +} + +/* Extract the map in "umap" that lives in the given space (ignoring + * parameters). + */ +__isl_give isl_map *isl_union_map_extract_map(__isl_keep isl_union_map *umap, + __isl_take isl_space *space) +{ + struct isl_hash_table_entry *entry; + + entry = isl_union_map_find_entry(umap, space, 0); + if (!entry) + goto error; + if (entry == isl_hash_table_entry_none) + return isl_map_empty(space); + isl_space_free(space); + return isl_map_copy(entry->data); +error: + isl_space_free(space); + return NULL; +} + +__isl_give isl_set *isl_union_set_extract_set(__isl_keep isl_union_set *uset, + __isl_take isl_space *space) +{ + return set_from_map(isl_union_map_extract_map(uset, space)); +} + +/* Check if umap contains a map in the given space (ignoring parameters). + */ +isl_bool isl_union_map_contains(__isl_keep isl_union_map *umap, + __isl_keep isl_space *space) +{ + struct isl_hash_table_entry *entry; + + space = isl_space_drop_all_params(isl_space_copy(space)); + space = isl_space_align_params(space, isl_union_map_get_space(umap)); + entry = isl_union_map_find_entry(umap, space, 0); + isl_space_free(space); + if (!entry) + return isl_bool_error; + return isl_bool_ok(entry != isl_hash_table_entry_none); +} + +isl_bool isl_union_set_contains(__isl_keep isl_union_set *uset, + __isl_keep isl_space *space) +{ + return isl_union_map_contains(uset, space); +} + +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) +{ + return isl_union_map_foreach_map(uset, + (isl_stat(*)(__isl_take isl_map *, void*))fn, user); +} + +/* Internal data structure for isl_union_set_every_set. + * + * "test" is the user-specified callback function. + * "user" is the user-specified callback function argument. + */ +struct isl_test_set_from_map_data { + isl_bool (*test)(__isl_keep isl_set *set, void *user); + void *user; +}; + +/* Call data->test on "map", which is part of an isl_union_set and + * therefore known to be an isl_set. + */ +static isl_bool test_set_from_map(__isl_keep isl_map *map, void *user) +{ + struct isl_test_set_from_map_data *data = user; + + return data->test(set_from_map(map), data->user); +} + +/* Does "test" succeed on every set in "uset"? + */ +isl_bool isl_union_set_every_set(__isl_keep isl_union_set *uset, + isl_bool (*test)(__isl_keep isl_set *set, void *user), void *user) +{ + struct isl_test_set_from_map_data data = { test, user }; + + return isl_union_map_every_map(uset_to_umap(uset), + &test_set_from_map, &data); +} + +struct isl_union_set_foreach_point_data { + isl_stat (*fn)(__isl_take isl_point *pnt, void *user); + void *user; +}; + +static isl_stat foreach_point(__isl_take isl_set *set, void *user) +{ + struct isl_union_set_foreach_point_data *data = user; + isl_stat r; + + r = isl_set_foreach_point(set, data->fn, data->user); + isl_set_free(set); + + return r; +} + +isl_stat isl_union_set_foreach_point(__isl_keep isl_union_set *uset, + isl_stat (*fn)(__isl_take isl_point *pnt, void *user), void *user) +{ + struct isl_union_set_foreach_point_data data = { fn, user }; + return isl_union_set_foreach_set(uset, &foreach_point, &data); +} + +/* Data structure that specifies how gen_bin_op should + * construct results from the inputs. + * + * If "subtract" is set, then a map in the first input is copied to the result + * if there is no corresponding map in the second input. + * Otherwise, a map in the first input with no corresponding map + * in the second input is ignored. + * If "filter" is not NULL, then it specifies which maps in the first + * input may have a matching map in the second input. + * In particular, it makes sure that "match_space" can be called + * on the space of the map. + * "match_space" specifies how to transform the space of a map + * in the first input to the space of the corresponding map + * in the second input. + * "fn_map" specifies how the matching maps, one from each input, + * should be combined to form a map in the result. + */ +struct isl_bin_op_control { + int subtract; + isl_bool (*filter)(__isl_keep isl_map *map); + __isl_give isl_space *(*match_space)(__isl_take isl_space *space); + __isl_give isl_map *(*fn_map)(__isl_take isl_map *map1, + __isl_take isl_map *map2); +}; + +/* Internal data structure for gen_bin_op. + * "control" specifies how the maps in the result should be constructed. + * "umap2" is a pointer to the second argument. + * "res" collects the results. + */ +struct isl_union_map_gen_bin_data { + struct isl_bin_op_control *control; + isl_union_map *umap2; + isl_union_map *res; +}; + +/* Add a copy of "map" to "res" and return the result. + */ +static __isl_give isl_union_map *bin_add_map(__isl_take isl_union_map *res, + __isl_keep isl_map *map) +{ + return isl_union_map_add_map(res, isl_map_copy(map)); +} + +/* Combine "map1" and "map2", add the result to "res" and return the result. + * Check whether the result is empty before adding it to "res". + */ +static __isl_give isl_union_map *bin_add_pair(__isl_take isl_union_map *res, + __isl_keep isl_map *map1, __isl_keep isl_map *map2, + struct isl_union_map_gen_bin_data *data) +{ + isl_bool empty; + isl_map *map; + + map = data->control->fn_map(isl_map_copy(map1), isl_map_copy(map2)); + empty = isl_map_is_empty(map); + if (empty < 0 || empty) { + isl_map_free(map); + if (empty < 0) + return isl_union_map_free(res); + return res; + } + return isl_union_map_add_map(res, map); +} + +/* Dummy match_space function that simply returns the input space. + */ +static __isl_give isl_space *identity(__isl_take isl_space *space) +{ + return space; +} + +/* Look for the map in data->umap2 that corresponds to "map", if any. + * Return (isl_bool_true, matching map) if there is one, + * (isl_bool_false, NULL) if there is no matching map and + * (isl_bool_error, NULL) on error. + * + * If not NULL, then data->control->filter specifies whether "map" + * can have any matching map. If so, + * data->control->match_space specifies which map in data->umap2 + * corresponds to "map". + */ +static __isl_keep isl_maybe_isl_map bin_try_get_match( + struct isl_union_map_gen_bin_data *data, __isl_keep isl_map *map) +{ + struct isl_hash_table_entry *entry2; + isl_space *space; + isl_maybe_isl_map res = { isl_bool_error, NULL }; + + if (data->control->filter) { + res.valid = data->control->filter(map); + if (res.valid < 0 || !res.valid) + return res; + res.valid = isl_bool_error; + } + + space = isl_map_get_space(map); + if (data->control->match_space != &identity) + space = data->control->match_space(space); + entry2 = isl_union_map_find_entry(data->umap2, space, 0); + isl_space_free(space); + if (entry2) + res.valid = isl_bool_ok(entry2 != isl_hash_table_entry_none); + if (res.valid >= 0 && res.valid) + res.value = entry2->data; + + return res; +} + +/* isl_hash_table_foreach callback for gen_bin_op. + * Look for the map in data->umap2 that corresponds + * to the map that "entry" points to, apply the binary operation and + * add the result to data->res. + * + * If no corresponding map can be found, then the effect depends + * on data->control->subtract. If it is set, then the current map + * is added directly to the result. Otherwise, it is ignored. + */ +static isl_stat gen_bin_entry(void **entry, void *user) +{ + struct isl_union_map_gen_bin_data *data = user; + isl_map *map = *entry; + isl_maybe_isl_map m; + + m = bin_try_get_match(data, map); + if (m.valid < 0) + return isl_stat_error; + if (!m.valid && !data->control->subtract) + return isl_stat_ok; + + if (!m.valid) + data->res = bin_add_map(data->res, map); + else + data->res = bin_add_pair(data->res, map, m.value, data); + if (!data->res) + return isl_stat_error; + + return isl_stat_ok; +} + +/* Apply a binary operation to "umap1" and "umap2" based on "control". + * Run over all maps in "umap1" and look for the corresponding map in "umap2" + * in gen_bin_entry. + */ +static __isl_give isl_union_map *gen_bin_op(__isl_take isl_union_map *umap1, + __isl_take isl_union_map *umap2, struct isl_bin_op_control *control) +{ + struct isl_union_map_gen_bin_data data = { control, NULL, NULL }; + + umap1 = isl_union_map_align_params(umap1, isl_union_map_get_space(umap2)); + umap2 = isl_union_map_align_params(umap2, isl_union_map_get_space(umap1)); + + if (!umap1 || !umap2) + goto error; + + data.umap2 = umap2; + data.res = isl_union_map_alloc(isl_space_copy(umap1->dim), + umap1->table.n); + if (isl_hash_table_foreach(umap1->dim->ctx, &umap1->table, + &gen_bin_entry, &data) < 0) + goto error; + + isl_union_map_free(umap1); + isl_union_map_free(umap2); + return data.res; +error: + isl_union_map_free(umap1); + isl_union_map_free(umap2); + isl_union_map_free(data.res); + return NULL; +} + +__isl_give isl_union_map *isl_union_map_subtract( + __isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2) +{ + struct isl_bin_op_control control = { + .subtract = 1, + .match_space = &identity, + .fn_map = &isl_map_subtract, + }; + + return gen_bin_op(umap1, umap2, &control); +} + +__isl_give isl_union_set *isl_union_set_subtract( + __isl_take isl_union_set *uset1, __isl_take isl_union_set *uset2) +{ + return isl_union_map_subtract(uset1, uset2); +} + +struct isl_union_map_gen_bin_set_data { + isl_set *set; + isl_union_map *res; +}; + +static isl_stat intersect_params_entry(void **entry, void *user) +{ + struct isl_union_map_gen_bin_set_data *data = user; + isl_map *map = *entry; + int empty; + + map = isl_map_copy(map); + map = isl_map_intersect_params(map, isl_set_copy(data->set)); + + empty = isl_map_is_empty(map); + if (empty < 0) { + isl_map_free(map); + return isl_stat_error; + } + + data->res = isl_union_map_add_map(data->res, map); + + return isl_stat_ok; +} + +static __isl_give isl_union_map *gen_bin_set_op(__isl_take isl_union_map *umap, + __isl_take isl_set *set, isl_stat (*fn)(void **, void *)) +{ + struct isl_union_map_gen_bin_set_data data = { NULL, NULL }; + + umap = isl_union_map_align_params(umap, isl_set_get_space(set)); + set = isl_set_align_params(set, isl_union_map_get_space(umap)); + + if (!umap || !set) + goto error; + + data.set = set; + data.res = isl_union_map_alloc(isl_space_copy(umap->dim), + umap->table.n); + if (isl_hash_table_foreach(umap->dim->ctx, &umap->table, + fn, &data) < 0) + goto error; + + isl_union_map_free(umap); + isl_set_free(set); + return data.res; +error: + isl_union_map_free(umap); + isl_set_free(set); + isl_union_map_free(data.res); + return NULL; +} + +/* Intersect "umap" with the parameter domain "set". + * + * If "set" does not have any constraints, then we can return immediately. + */ +__isl_give isl_union_map *isl_union_map_intersect_params( + __isl_take isl_union_map *umap, __isl_take isl_set *set) +{ + int is_universe; + + is_universe = isl_set_plain_is_universe(set); + if (is_universe < 0) + goto error; + if (is_universe) { + isl_set_free(set); + return umap; + } + + return gen_bin_set_op(umap, set, &intersect_params_entry); +error: + isl_union_map_free(umap); + isl_set_free(set); + return NULL; +} + +__isl_give isl_union_set *isl_union_set_intersect_params( + __isl_take isl_union_set *uset, __isl_take isl_set *set) +{ + return isl_union_map_intersect_params(uset, set); +} + +static __isl_give isl_union_map *union_map_intersect_params( + __isl_take isl_union_map *umap, __isl_take isl_union_set *uset) +{ + return isl_union_map_intersect_params(umap, + isl_set_from_union_set(uset)); +} + +static __isl_give isl_union_map *union_map_gist_params( + __isl_take isl_union_map *umap, __isl_take isl_union_set *uset) +{ + return isl_union_map_gist_params(umap, isl_set_from_union_set(uset)); +} + +struct isl_union_map_match_bin_data { + isl_union_map *umap2; + isl_union_map *res; + __isl_give isl_map *(*fn)(__isl_take isl_map*, __isl_take isl_map*); +}; + +static isl_stat match_bin_entry(void **entry, void *user) +{ + struct isl_union_map_match_bin_data *data = user; + struct isl_hash_table_entry *entry2; + isl_space *space; + isl_map *map = *entry; + int empty; + + space = isl_map_peek_space(map); + entry2 = isl_union_map_find_entry(data->umap2, space, 0); + if (!entry2) + return isl_stat_error; + if (entry2 == isl_hash_table_entry_none) + return isl_stat_ok; + + map = isl_map_copy(map); + map = data->fn(map, isl_map_copy(entry2->data)); + + empty = isl_map_is_empty(map); + if (empty < 0) { + isl_map_free(map); + return isl_stat_error; + } + if (empty) { + isl_map_free(map); + return isl_stat_ok; + } + + data->res = isl_union_map_add_map(data->res, map); + + return isl_stat_ok; +} + +static __isl_give isl_union_map *match_bin_op(__isl_take isl_union_map *umap1, + __isl_take isl_union_map *umap2, + __isl_give isl_map *(*fn)(__isl_take isl_map*, __isl_take isl_map*)) +{ + struct isl_union_map_match_bin_data data = { NULL, NULL, fn }; + + umap1 = isl_union_map_align_params(umap1, isl_union_map_get_space(umap2)); + umap2 = isl_union_map_align_params(umap2, isl_union_map_get_space(umap1)); + + if (!umap1 || !umap2) + goto error; + + data.umap2 = umap2; + data.res = isl_union_map_alloc(isl_space_copy(umap1->dim), + umap1->table.n); + if (isl_hash_table_foreach(umap1->dim->ctx, &umap1->table, + &match_bin_entry, &data) < 0) + goto error; + + isl_union_map_free(umap1); + isl_union_map_free(umap2); + return data.res; +error: + isl_union_map_free(umap1); + isl_union_map_free(umap2); + isl_union_map_free(data.res); + return NULL; +} + +__isl_give isl_union_map *isl_union_map_intersect( + __isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2) +{ + return match_bin_op(umap1, umap2, &isl_map_intersect); +} + +/* Compute the intersection of the two union_sets. + * As a special case, if exactly one of the two union_sets + * is a parameter domain, then intersect the parameter domain + * of the other one with this set. + */ +__isl_give isl_union_set *isl_union_set_intersect( + __isl_take isl_union_set *uset1, __isl_take isl_union_set *uset2) +{ + int p1, p2; + + p1 = isl_union_set_is_params(uset1); + p2 = isl_union_set_is_params(uset2); + if (p1 < 0 || p2 < 0) + goto error; + if (!p1 && p2) + return union_map_intersect_params(uset1, uset2); + if (p1 && !p2) + return union_map_intersect_params(uset2, uset1); + return isl_union_map_intersect(uset1, uset2); +error: + isl_union_set_free(uset1); + isl_union_set_free(uset2); + return NULL; +} + +static isl_stat gist_params_entry(void **entry, void *user) +{ + struct isl_union_map_gen_bin_set_data *data = user; + isl_map *map = *entry; + int empty; + + map = isl_map_copy(map); + map = isl_map_gist_params(map, isl_set_copy(data->set)); + + empty = isl_map_is_empty(map); + if (empty < 0) { + isl_map_free(map); + return isl_stat_error; + } + + data->res = isl_union_map_add_map(data->res, map); + + return isl_stat_ok; +} + +__isl_give isl_union_map *isl_union_map_gist_params( + __isl_take isl_union_map *umap, __isl_take isl_set *set) +{ + return gen_bin_set_op(umap, set, &gist_params_entry); +} + +__isl_give isl_union_set *isl_union_set_gist_params( + __isl_take isl_union_set *uset, __isl_take isl_set *set) +{ + return isl_union_map_gist_params(uset, set); +} + +__isl_give isl_union_map *isl_union_map_gist(__isl_take isl_union_map *umap, + __isl_take isl_union_map *context) +{ + return match_bin_op(umap, context, &isl_map_gist); +} + +__isl_give isl_union_set *isl_union_set_gist(__isl_take isl_union_set *uset, + __isl_take isl_union_set *context) +{ + if (isl_union_set_is_params(context)) + return union_map_gist_params(uset, context); + return isl_union_map_gist(uset, context); +} + +/* For each map in "umap", remove the constraints in the corresponding map + * of "context". + * Each map in "context" is assumed to consist of a single disjunct and + * to have explicit representations for all local variables. + */ +__isl_give isl_union_map *isl_union_map_plain_gist( + __isl_take isl_union_map *umap, __isl_take isl_union_map *context) +{ + return match_bin_op(umap, context, &isl_map_plain_gist); +} + +/* For each set in "uset", remove the constraints in the corresponding set + * of "context". + * Each set in "context" is assumed to consist of a single disjunct and + * to have explicit representations for all local variables. + */ +__isl_give isl_union_set *isl_union_set_plain_gist( + __isl_take isl_union_set *uset, __isl_take isl_union_set *context) +{ + return isl_union_map_plain_gist(uset, context); +} + +static __isl_give isl_map *lex_le_set(__isl_take isl_map *set1, + __isl_take isl_map *set2) +{ + return isl_set_lex_le_set(set_from_map(set1), set_from_map(set2)); +} + +static __isl_give isl_map *lex_lt_set(__isl_take isl_map *set1, + __isl_take isl_map *set2) +{ + return isl_set_lex_lt_set(set_from_map(set1), set_from_map(set2)); +} + +__isl_give isl_union_map *isl_union_set_lex_lt_union_set( + __isl_take isl_union_set *uset1, __isl_take isl_union_set *uset2) +{ + return match_bin_op(uset1, uset2, &lex_lt_set); +} + +__isl_give isl_union_map *isl_union_set_lex_le_union_set( + __isl_take isl_union_set *uset1, __isl_take isl_union_set *uset2) +{ + return match_bin_op(uset1, uset2, &lex_le_set); +} + +__isl_give isl_union_map *isl_union_set_lex_gt_union_set( + __isl_take isl_union_set *uset1, __isl_take isl_union_set *uset2) +{ + return isl_union_map_reverse(isl_union_set_lex_lt_union_set(uset2, uset1)); +} + +__isl_give isl_union_map *isl_union_set_lex_ge_union_set( + __isl_take isl_union_set *uset1, __isl_take isl_union_set *uset2) +{ + return isl_union_map_reverse(isl_union_set_lex_le_union_set(uset2, uset1)); +} + +__isl_give isl_union_map *isl_union_map_lex_gt_union_map( + __isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2) +{ + return isl_union_map_reverse(isl_union_map_lex_lt_union_map(umap2, umap1)); +} + +__isl_give isl_union_map *isl_union_map_lex_ge_union_map( + __isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2) +{ + return isl_union_map_reverse(isl_union_map_lex_le_union_map(umap2, umap1)); +} + +/* Intersect the domain of "umap" with "uset". + */ +static __isl_give isl_union_map *union_map_intersect_domain( + __isl_take isl_union_map *umap, __isl_take isl_union_set *uset) +{ + struct isl_bin_op_control control = { + .match_space = &isl_space_domain, + .fn_map = &isl_map_intersect_domain, + }; + + return gen_bin_op(umap, uset, &control); +} + +/* Intersect the domain of "umap" with "uset". + * If "uset" is a parameters domain, then intersect the parameter + * domain of "umap" with this set. + */ +__isl_give isl_union_map *isl_union_map_intersect_domain_union_set( + __isl_take isl_union_map *umap, __isl_take isl_union_set *uset) +{ + if (isl_union_set_is_params(uset)) + return union_map_intersect_params(umap, uset); + else + return union_map_intersect_domain(umap, uset); +} + +/* This is an alternative name for the function above. + */ +__isl_give isl_union_map *isl_union_map_intersect_domain( + __isl_take isl_union_map *umap, __isl_take isl_union_set *uset) +{ + return isl_union_map_intersect_domain_union_set(umap, uset); +} + +/* Remove the elements of "uset" from the domain of "umap". + */ +__isl_give isl_union_map *isl_union_map_subtract_domain( + __isl_take isl_union_map *umap, __isl_take isl_union_set *dom) +{ + struct isl_bin_op_control control = { + .subtract = 1, + .match_space = &isl_space_domain, + .fn_map = &isl_map_subtract_domain, + }; + + return gen_bin_op(umap, dom, &control); +} + +/* Remove the elements of "uset" from the range of "umap". + */ +__isl_give isl_union_map *isl_union_map_subtract_range( + __isl_take isl_union_map *umap, __isl_take isl_union_set *dom) +{ + struct isl_bin_op_control control = { + .subtract = 1, + .match_space = &isl_space_range, + .fn_map = &isl_map_subtract_range, + }; + + return gen_bin_op(umap, dom, &control); +} + +/* Compute the gist of "umap" with respect to the domain "uset". + */ +static __isl_give isl_union_map *union_map_gist_domain( + __isl_take isl_union_map *umap, __isl_take isl_union_set *uset) +{ + struct isl_bin_op_control control = { + .match_space = &isl_space_domain, + .fn_map = &isl_map_gist_domain, + }; + + return gen_bin_op(umap, uset, &control); +} + +/* Compute the gist of "umap" with respect to the domain "uset". + * If "uset" is a parameters domain, then compute the gist + * with respect to this parameter domain. + */ +__isl_give isl_union_map *isl_union_map_gist_domain( + __isl_take isl_union_map *umap, __isl_take isl_union_set *uset) +{ + if (isl_union_set_is_params(uset)) + return union_map_gist_params(umap, uset); + else + return union_map_gist_domain(umap, uset); +} + +/* Compute the gist of "umap" with respect to the range "uset". + */ +__isl_give isl_union_map *isl_union_map_gist_range( + __isl_take isl_union_map *umap, __isl_take isl_union_set *uset) +{ + struct isl_bin_op_control control = { + .match_space = &isl_space_range, + .fn_map = &isl_map_gist_range, + }; + + return gen_bin_op(umap, uset, &control); +} + +__isl_give isl_union_map *isl_union_map_intersect_range_union_set( + __isl_take isl_union_map *umap, __isl_take isl_union_set *uset) +{ + struct isl_bin_op_control control = { + .match_space = &isl_space_range, + .fn_map = &isl_map_intersect_range, + }; + + return gen_bin_op(umap, uset, &control); +} + +/* This is an alternative name for the function above. + */ +__isl_give isl_union_map *isl_union_map_intersect_range( + __isl_take isl_union_map *umap, __isl_take isl_union_set *uset) +{ + return isl_union_map_intersect_range_union_set(umap, uset); +} + +/* Intersect each map in "umap" in a space [A -> B] -> C + * with the corresponding map in "factor" in the space A -> C and + * collect the results. + */ +__isl_give isl_union_map *isl_union_map_intersect_domain_factor_domain( + __isl_take isl_union_map *umap, __isl_take isl_union_map *factor) +{ + struct isl_bin_op_control control = { + .filter = &isl_map_domain_is_wrapping, + .match_space = &isl_space_domain_factor_domain, + .fn_map = &isl_map_intersect_domain_factor_domain, + }; + + return gen_bin_op(umap, factor, &control); +} + +/* Intersect each map in "umap" in a space [A -> B] -> C + * with the corresponding map in "factor" in the space B -> C and + * collect the results. + */ +__isl_give isl_union_map *isl_union_map_intersect_domain_factor_range( + __isl_take isl_union_map *umap, __isl_take isl_union_map *factor) +{ + struct isl_bin_op_control control = { + .filter = &isl_map_domain_is_wrapping, + .match_space = &isl_space_domain_factor_range, + .fn_map = &isl_map_intersect_domain_factor_range, + }; + + return gen_bin_op(umap, factor, &control); +} + +/* Intersect each map in "umap" in a space A -> [B -> C] + * with the corresponding map in "factor" in the space A -> B and + * collect the results. + */ +__isl_give isl_union_map *isl_union_map_intersect_range_factor_domain( + __isl_take isl_union_map *umap, __isl_take isl_union_map *factor) +{ + struct isl_bin_op_control control = { + .filter = &isl_map_range_is_wrapping, + .match_space = &isl_space_range_factor_domain, + .fn_map = &isl_map_intersect_range_factor_domain, + }; + + return gen_bin_op(umap, factor, &control); +} + +/* Intersect each map in "umap" in a space A -> [B -> C] + * with the corresponding map in "factor" in the space A -> C and + * collect the results. + */ +__isl_give isl_union_map *isl_union_map_intersect_range_factor_range( + __isl_take isl_union_map *umap, __isl_take isl_union_map *factor) +{ + struct isl_bin_op_control control = { + .filter = &isl_map_range_is_wrapping, + .match_space = &isl_space_range_factor_range, + .fn_map = &isl_map_intersect_range_factor_range, + }; + + return gen_bin_op(umap, factor, &control); +} + +struct isl_union_map_bin_data { + isl_union_map *umap2; + isl_union_map *res; + isl_map *map; + isl_stat (*fn)(void **entry, void *user); +}; + +static isl_stat apply_range_entry(void **entry, void *user) +{ + struct isl_union_map_bin_data *data = user; + isl_map *map2 = *entry; + isl_bool empty, match; + + match = isl_map_tuple_is_equal(data->map, isl_dim_out, + map2, isl_dim_in); + if (match < 0) + return isl_stat_error; + if (!match) + return isl_stat_ok; + + map2 = isl_map_apply_range(isl_map_copy(data->map), isl_map_copy(map2)); + + empty = isl_map_is_empty(map2); + if (empty < 0) { + isl_map_free(map2); + return isl_stat_error; + } + if (empty) { + isl_map_free(map2); + return isl_stat_ok; + } + + data->res = isl_union_map_add_map(data->res, map2); + + return isl_stat_ok; +} + +static isl_stat bin_entry(void **entry, void *user) +{ + struct isl_union_map_bin_data *data = user; + isl_map *map = *entry; + + data->map = map; + if (isl_hash_table_foreach(data->umap2->dim->ctx, &data->umap2->table, + data->fn, data) < 0) + return isl_stat_error; + + return isl_stat_ok; +} + +static __isl_give isl_union_map *bin_op(__isl_take isl_union_map *umap1, + __isl_take isl_union_map *umap2, + isl_stat (*fn)(void **entry, void *user)) +{ + struct isl_union_map_bin_data data = { NULL, NULL, NULL, fn }; + + umap1 = isl_union_map_align_params(umap1, isl_union_map_get_space(umap2)); + umap2 = isl_union_map_align_params(umap2, isl_union_map_get_space(umap1)); + + if (!umap1 || !umap2) + goto error; + + data.umap2 = umap2; + data.res = isl_union_map_alloc(isl_space_copy(umap1->dim), + umap1->table.n); + if (isl_hash_table_foreach(umap1->dim->ctx, &umap1->table, + &bin_entry, &data) < 0) + goto error; + + isl_union_map_free(umap1); + isl_union_map_free(umap2); + return data.res; +error: + isl_union_map_free(umap1); + isl_union_map_free(umap2); + isl_union_map_free(data.res); + return NULL; +} + +/* Intersect each map in "umap" in a space [A -> B] -> C + * with the corresponding set in "domain" in the space A and + * collect the results. + */ +__isl_give isl_union_map * +isl_union_map_intersect_domain_wrapped_domain_union_set( + __isl_take isl_union_map *umap, __isl_take isl_union_set *domain) +{ + struct isl_bin_op_control control = { + .filter = &isl_map_domain_is_wrapping, + .match_space = &isl_space_domain_wrapped_domain, + .fn_map = &isl_map_intersect_domain_wrapped_domain, + }; + + return gen_bin_op(umap, domain, &control); +} + +/* Intersect each map in "umap" in a space A -> [B -> C] + * with the corresponding set in "domain" in the space B and + * collect the results. + */ +__isl_give isl_union_map * +isl_union_map_intersect_range_wrapped_domain_union_set( + __isl_take isl_union_map *umap, __isl_take isl_union_set *domain) +{ + struct isl_bin_op_control control = { + .filter = &isl_map_range_is_wrapping, + .match_space = &isl_space_range_wrapped_domain, + .fn_map = &isl_map_intersect_range_wrapped_domain, + }; + + return gen_bin_op(umap, domain, &control); +} + +__isl_give isl_union_map *isl_union_map_apply_range( + __isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2) +{ + return bin_op(umap1, umap2, &apply_range_entry); +} + +__isl_give isl_union_map *isl_union_map_apply_domain( + __isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2) +{ + umap1 = isl_union_map_reverse(umap1); + umap1 = isl_union_map_apply_range(umap1, umap2); + return isl_union_map_reverse(umap1); +} + +__isl_give isl_union_set *isl_union_set_apply( + __isl_take isl_union_set *uset, __isl_take isl_union_map *umap) +{ + return isl_union_map_apply_range(uset, umap); +} + +static isl_stat map_lex_lt_entry(void **entry, void *user) +{ + struct isl_union_map_bin_data *data = user; + isl_map *map2 = *entry; + isl_bool match; + + match = isl_map_tuple_is_equal(data->map, isl_dim_out, + map2, isl_dim_out); + if (match < 0) + return isl_stat_error; + if (!match) + return isl_stat_ok; + + map2 = isl_map_lex_lt_map(isl_map_copy(data->map), isl_map_copy(map2)); + + data->res = isl_union_map_add_map(data->res, map2); + + return isl_stat_ok; +} + +__isl_give isl_union_map *isl_union_map_lex_lt_union_map( + __isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2) +{ + return bin_op(umap1, umap2, &map_lex_lt_entry); +} + +static isl_stat map_lex_le_entry(void **entry, void *user) +{ + struct isl_union_map_bin_data *data = user; + isl_map *map2 = *entry; + isl_bool match; + + match = isl_map_tuple_is_equal(data->map, isl_dim_out, + map2, isl_dim_out); + if (match < 0) + return isl_stat_error; + if (!match) + return isl_stat_ok; + + map2 = isl_map_lex_le_map(isl_map_copy(data->map), isl_map_copy(map2)); + + data->res = isl_union_map_add_map(data->res, map2); + + return isl_stat_ok; +} + +__isl_give isl_union_map *isl_union_map_lex_le_union_map( + __isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2) +{ + return bin_op(umap1, umap2, &map_lex_le_entry); +} + +static isl_stat product_entry(void **entry, void *user) +{ + struct isl_union_map_bin_data *data = user; + isl_map *map2 = *entry; + + map2 = isl_map_product(isl_map_copy(data->map), isl_map_copy(map2)); + + data->res = isl_union_map_add_map(data->res, map2); + + return isl_stat_ok; +} + +__isl_give isl_union_map *isl_union_map_product(__isl_take isl_union_map *umap1, + __isl_take isl_union_map *umap2) +{ + return bin_op(umap1, umap2, &product_entry); +} + +static isl_stat set_product_entry(void **entry, void *user) +{ + struct isl_union_map_bin_data *data = user; + isl_set *set2 = *entry; + + set2 = isl_set_product(isl_set_copy(data->map), isl_set_copy(set2)); + + data->res = isl_union_set_add_set(data->res, set2); + + return isl_stat_ok; +} + +__isl_give isl_union_set *isl_union_set_product(__isl_take isl_union_set *uset1, + __isl_take isl_union_set *uset2) +{ + return bin_op(uset1, uset2, &set_product_entry); +} + +static isl_stat domain_product_entry(void **entry, void *user) +{ + struct isl_union_map_bin_data *data = user; + isl_map *map2 = *entry; + isl_bool match; + + match = isl_map_tuple_is_equal(data->map, isl_dim_out, + map2, isl_dim_out); + if (match < 0) + return isl_stat_error; + if (!match) + return isl_stat_ok; + + map2 = isl_map_domain_product(isl_map_copy(data->map), + isl_map_copy(map2)); + + data->res = isl_union_map_add_map(data->res, map2); + + return isl_stat_ok; +} + +/* Given two maps A -> B and C -> D, construct a map [A -> C] -> (B * D) + */ +__isl_give isl_union_map *isl_union_map_domain_product( + __isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2) +{ + return bin_op(umap1, umap2, &domain_product_entry); +} + +static isl_stat range_product_entry(void **entry, void *user) +{ + struct isl_union_map_bin_data *data = user; + isl_map *map2 = *entry; + isl_bool match; + + match = isl_map_tuple_is_equal(data->map, isl_dim_in, map2, isl_dim_in); + if (match < 0) + return isl_stat_error; + if (!match) + return isl_stat_ok; + + map2 = isl_map_range_product(isl_map_copy(data->map), + isl_map_copy(map2)); + + data->res = isl_union_map_add_map(data->res, map2); + + return isl_stat_ok; +} + +__isl_give isl_union_map *isl_union_map_range_product( + __isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2) +{ + return bin_op(umap1, umap2, &range_product_entry); +} + +/* If data->map A -> B and "map2" C -> D have the same range space, + * then add (A, C) -> (B * D) to data->res. + */ +static isl_stat flat_domain_product_entry(void **entry, void *user) +{ + struct isl_union_map_bin_data *data = user; + isl_map *map2 = *entry; + isl_bool match; + + match = isl_map_tuple_is_equal(data->map, isl_dim_out, + map2, isl_dim_out); + if (match < 0) + return isl_stat_error; + if (!match) + return isl_stat_ok; + + map2 = isl_map_flat_domain_product(isl_map_copy(data->map), + isl_map_copy(map2)); + + data->res = isl_union_map_add_map(data->res, map2); + + return isl_stat_ok; +} + +/* Given two maps A -> B and C -> D, construct a map (A, C) -> (B * D). + */ +__isl_give isl_union_map *isl_union_map_flat_domain_product( + __isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2) +{ + return bin_op(umap1, umap2, &flat_domain_product_entry); +} + +static isl_stat flat_range_product_entry(void **entry, void *user) +{ + struct isl_union_map_bin_data *data = user; + isl_map *map2 = *entry; + isl_bool match; + + match = isl_map_tuple_is_equal(data->map, isl_dim_in, map2, isl_dim_in); + if (match < 0) + return isl_stat_error; + if (!match) + return isl_stat_ok; + + map2 = isl_map_flat_range_product(isl_map_copy(data->map), + isl_map_copy(map2)); + + data->res = isl_union_map_add_map(data->res, map2); + + return isl_stat_ok; +} + +__isl_give isl_union_map *isl_union_map_flat_range_product( + __isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2) +{ + return bin_op(umap1, umap2, &flat_range_product_entry); +} + +/* Data structure that specifies how un_op should modify + * the maps in the union map. + * + * If "inplace" is set, then the maps in the input union map + * are modified in place. This means that "fn_map" should not + * change the meaning of the map or that the union map only + * has a single reference. + * If "total" is set, then all maps need to be modified and + * the results need to live in the same space. + * Otherwise, a new union map is constructed to store the results. + * If "filter" is not NULL, then only the input maps that satisfy "filter" + * are taken into account. "filter_user" is passed as the second argument + * to "filter". No filter can be set if "inplace" or + * "total" is set. + * At most one of "fn_map" or "fn_map2" can be set, specifying + * how the maps (selected by "filter") should be transformed. + * If "fn_map2" is set, then "fn_map2_user" is passed as the second argument. + */ +struct isl_un_op_control { + int inplace; + int total; + isl_bool (*filter)(__isl_keep isl_map *map, void *user); + void *filter_user; + __isl_give isl_map *(*fn_map)(__isl_take isl_map *map); + __isl_give isl_map *(*fn_map2)(__isl_take isl_map *map, void *user); + void *fn_map2_user; +}; + +/* Data structure for wrapping the data for un_op_filter_drop_user. + * "filter" is the function that is being wrapped. + */ +struct isl_un_op_drop_user_data { + isl_bool (*filter)(__isl_keep isl_map *map); +}; + +/* Wrapper for isl_un_op_control filters that do not require + * a second argument. + * Simply call data->filter without the second argument. + */ +static isl_bool un_op_filter_drop_user(__isl_keep isl_map *map, void *user) +{ + struct isl_un_op_drop_user_data *data = user; + return data->filter(map); +} + +/* Internal data structure for "un_op". + * "control" specifies how the maps in the union map should be modified. + * "res" collects the results. + */ +struct isl_union_map_un_data { + struct isl_un_op_control *control; + isl_union_map *res; +}; + +/* isl_hash_table_foreach callback for un_op. + * Handle the map that "entry" points to. + * + * If control->filter is set, then check if this map satisfies the filter. + * If so (or if control->filter is not set), modify the map + * by calling control->fn_map or control->fn_map2 (if set) and + * either add the result to data->res or + * replace the original entry by the result (if control->inplace is set). + */ +static isl_stat un_entry(void **entry, void *user) +{ + struct isl_union_map_un_data *data = user; + struct isl_un_op_control *control = data->control; + isl_map *map = *entry; + + if (control->filter) { + isl_bool ok; + + ok = control->filter(map, control->filter_user); + if (ok < 0) + return isl_stat_error; + if (!ok) + return isl_stat_ok; + } + + map = isl_map_copy(map); + if (control->fn_map2 != NULL) + map = control->fn_map2(map, control->fn_map2_user); + else if (control->fn_map != NULL) + map = control->fn_map(map); + if (!map) + return isl_stat_error; + if (control->inplace) { + isl_map_free(*entry); + *entry = map; + } else { + data->res = isl_union_map_add_map(data->res, map); + if (!data->res) + return isl_stat_error; + } + + return isl_stat_ok; +} + +/* Modify the maps in "umap" based on "control". + * If control->inplace is set, then modify the maps in "umap" in-place. + * Otherwise, create a new union map to hold the results. + * If control->total is set, then perform an inplace computation + * if "umap" is only referenced once. Otherwise, create a new union map + * to store the results. + */ +static __isl_give isl_union_map *un_op(__isl_take isl_union_map *umap, + struct isl_un_op_control *control) +{ + struct isl_union_map_un_data data = { control }; + + if (!umap) + return NULL; + if (!!control->fn_map && !!control->fn_map2) + isl_die(isl_union_map_get_ctx(umap), isl_error_internal, + "at most one mapping function can be specified", + return isl_union_map_free(umap)); + if ((control->inplace || control->total) && control->filter) + isl_die(isl_union_map_get_ctx(umap), isl_error_invalid, + "inplace/total modification cannot be filtered", + return isl_union_map_free(umap)); + + if (control->total && umap->ref == 1) + control->inplace = 1; + if (control->inplace) { + data.res = umap; + } else { + isl_space *space; + + space = isl_union_map_get_space(umap); + data.res = isl_union_map_alloc(space, umap->table.n); + } + if (isl_hash_table_foreach(isl_union_map_get_ctx(umap), + &umap->table, &un_entry, &data) < 0) + data.res = isl_union_map_free(data.res); + + if (control->inplace) + return data.res; + isl_union_map_free(umap); + return data.res; +} + +__isl_give isl_union_map *isl_union_map_from_range( + __isl_take isl_union_set *uset) +{ + struct isl_un_op_control control = { + .fn_map = &isl_map_from_range, + }; + return un_op(uset, &control); +} + +__isl_give isl_union_map *isl_union_map_from_domain( + __isl_take isl_union_set *uset) +{ + return isl_union_map_reverse(isl_union_map_from_range(uset)); +} + +__isl_give isl_union_map *isl_union_map_from_domain_and_range( + __isl_take isl_union_set *domain, __isl_take isl_union_set *range) +{ + return isl_union_map_apply_range(isl_union_map_from_domain(domain), + isl_union_map_from_range(range)); +} + +/* Modify the maps in "umap" by applying "fn" on them. + * "fn" should apply to all maps in "umap" and should not modify the space. + */ +static __isl_give isl_union_map *total(__isl_take isl_union_map *umap, + __isl_give isl_map *(*fn)(__isl_take isl_map *)) +{ + struct isl_un_op_control control = { + .total = 1, + .fn_map = fn, + }; + + return un_op(umap, &control); +} + +/* Compute the affine hull of "map" and return the result as an isl_map. + */ +static __isl_give isl_map *isl_map_affine_hull_map(__isl_take isl_map *map) +{ + return isl_map_from_basic_map(isl_map_affine_hull(map)); +} + +__isl_give isl_union_map *isl_union_map_affine_hull( + __isl_take isl_union_map *umap) +{ + return total(umap, &isl_map_affine_hull_map); +} + +__isl_give isl_union_set *isl_union_set_affine_hull( + __isl_take isl_union_set *uset) +{ + return isl_union_map_affine_hull(uset); +} + +/* Wrapper around isl_set_combined_lineality_space + * that returns the combined lineality space in the form of an isl_set + * instead of an isl_basic_set. + */ +static __isl_give isl_set *combined_lineality_space(__isl_take isl_set *set) +{ + return isl_set_from_basic_set(isl_set_combined_lineality_space(set)); +} + +/* For each set in "uset", compute the (linear) hull + * of the lineality spaces of its basic sets and + * collect and return the results. + */ +__isl_give isl_union_set *isl_union_set_combined_lineality_space( + __isl_take isl_union_set *uset) +{ + struct isl_un_op_control control = { + .fn_map = &combined_lineality_space, + }; + return un_op(uset, &control); +} + +/* Compute the polyhedral hull of "map" and return the result as an isl_map. + */ +static __isl_give isl_map *isl_map_polyhedral_hull_map(__isl_take isl_map *map) +{ + return isl_map_from_basic_map(isl_map_polyhedral_hull(map)); +} + +__isl_give isl_union_map *isl_union_map_polyhedral_hull( + __isl_take isl_union_map *umap) +{ + return total(umap, &isl_map_polyhedral_hull_map); +} + +__isl_give isl_union_set *isl_union_set_polyhedral_hull( + __isl_take isl_union_set *uset) +{ + return isl_union_map_polyhedral_hull(uset); +} + +/* Compute a superset of the convex hull of "map" that is described + * by only translates of the constraints in the constituents of "map" and + * return the result as an isl_map. + */ +static __isl_give isl_map *isl_map_simple_hull_map(__isl_take isl_map *map) +{ + return isl_map_from_basic_map(isl_map_simple_hull(map)); +} + +__isl_give isl_union_map *isl_union_map_simple_hull( + __isl_take isl_union_map *umap) +{ + return total(umap, &isl_map_simple_hull_map); +} + +__isl_give isl_union_set *isl_union_set_simple_hull( + __isl_take isl_union_set *uset) +{ + return isl_union_map_simple_hull(uset); +} + +static __isl_give isl_union_map *inplace(__isl_take isl_union_map *umap, + __isl_give isl_map *(*fn)(__isl_take isl_map *)) +{ + struct isl_un_op_control control = { + .inplace = 1, + .fn_map = fn, + }; + + return un_op(umap, &control); +} + +/* Remove redundant constraints in each of the basic maps of "umap". + * Since removing redundant constraints does not change the meaning + * or the space, the operation can be performed in-place. + */ +__isl_give isl_union_map *isl_union_map_remove_redundancies( + __isl_take isl_union_map *umap) +{ + return inplace(umap, &isl_map_remove_redundancies); +} + +/* Remove redundant constraints in each of the basic sets of "uset". + */ +__isl_give isl_union_set *isl_union_set_remove_redundancies( + __isl_take isl_union_set *uset) +{ + return isl_union_map_remove_redundancies(uset); +} + +__isl_give isl_union_map *isl_union_map_coalesce( + __isl_take isl_union_map *umap) +{ + return inplace(umap, &isl_map_coalesce); +} + +__isl_give isl_union_set *isl_union_set_coalesce( + __isl_take isl_union_set *uset) +{ + return isl_union_map_coalesce(uset); +} + +__isl_give isl_union_map *isl_union_map_detect_equalities( + __isl_take isl_union_map *umap) +{ + return inplace(umap, &isl_map_detect_equalities); +} + +__isl_give isl_union_set *isl_union_set_detect_equalities( + __isl_take isl_union_set *uset) +{ + return isl_union_map_detect_equalities(uset); +} + +__isl_give isl_union_map *isl_union_map_compute_divs( + __isl_take isl_union_map *umap) +{ + return inplace(umap, &isl_map_compute_divs); +} + +__isl_give isl_union_set *isl_union_set_compute_divs( + __isl_take isl_union_set *uset) +{ + return isl_union_map_compute_divs(uset); +} + +__isl_give isl_union_map *isl_union_map_lexmin( + __isl_take isl_union_map *umap) +{ + return total(umap, &isl_map_lexmin); +} + +__isl_give isl_union_set *isl_union_set_lexmin( + __isl_take isl_union_set *uset) +{ + return isl_union_map_lexmin(uset); +} + +__isl_give isl_union_map *isl_union_map_lexmax( + __isl_take isl_union_map *umap) +{ + return total(umap, &isl_map_lexmax); +} + +__isl_give isl_union_set *isl_union_set_lexmax( + __isl_take isl_union_set *uset) +{ + return isl_union_map_lexmax(uset); +} + +/* Return the universe in the space of "map". + */ +static __isl_give isl_map *universe(__isl_take isl_map *map) +{ + isl_space *space; + + space = isl_map_get_space(map); + isl_map_free(map); + return isl_map_universe(space); +} + +__isl_give isl_union_map *isl_union_map_universe(__isl_take isl_union_map *umap) +{ + struct isl_un_op_control control = { + .fn_map = &universe, + }; + return un_op(umap, &control); +} + +__isl_give isl_union_set *isl_union_set_universe(__isl_take isl_union_set *uset) +{ + return isl_union_map_universe(uset); +} + +__isl_give isl_union_map *isl_union_map_reverse(__isl_take isl_union_map *umap) +{ + struct isl_un_op_control control = { + .fn_map = &isl_map_reverse, + }; + return un_op(umap, &control); +} + +/* Given a union map, take the maps of the form (A -> B) -> C and + * return the union of the corresponding maps (B -> A) -> C. + */ +__isl_give isl_union_map *isl_union_map_domain_reverse( + __isl_take isl_union_map *umap) +{ + struct isl_un_op_drop_user_data data = { &isl_map_domain_is_wrapping }; + struct isl_un_op_control control = { + .filter = &un_op_filter_drop_user, + .filter_user = &data, + .fn_map = &isl_map_domain_reverse, + }; + return un_op(umap, &control); +} + +/* Given a union map, take the maps of the form A -> (B -> C) and + * return the union of the corresponding maps A -> (C -> B). + */ +__isl_give isl_union_map *isl_union_map_range_reverse( + __isl_take isl_union_map *umap) +{ + struct isl_un_op_drop_user_data data = { &isl_map_range_is_wrapping }; + struct isl_un_op_control control = { + .filter = &un_op_filter_drop_user, + .filter_user = &data, + .fn_map = &isl_map_range_reverse, + }; + return un_op(umap, &control); +} + +/* Compute the parameter domain of the given union map. + */ +__isl_give isl_set *isl_union_map_params(__isl_take isl_union_map *umap) +{ + struct isl_un_op_control control = { + .fn_map = &isl_map_params, + }; + int empty; + + empty = isl_union_map_is_empty(umap); + if (empty < 0) + goto error; + if (empty) { + isl_space *space; + space = isl_union_map_get_space(umap); + isl_union_map_free(umap); + return isl_set_empty(space); + } + return isl_set_from_union_set(un_op(umap, &control)); +error: + isl_union_map_free(umap); + return NULL; +} + +/* Compute the parameter domain of the given union set. + */ +__isl_give isl_set *isl_union_set_params(__isl_take isl_union_set *uset) +{ + return isl_union_map_params(uset); +} + +__isl_give isl_union_set *isl_union_map_domain(__isl_take isl_union_map *umap) +{ + struct isl_un_op_control control = { + .fn_map = &isl_map_domain, + }; + return un_op(umap, &control); +} + +__isl_give isl_union_set *isl_union_map_range(__isl_take isl_union_map *umap) +{ + struct isl_un_op_control control = { + .fn_map = &isl_map_range, + }; + return un_op(umap, &control); +} + +__isl_give isl_union_map *isl_union_map_domain_map( + __isl_take isl_union_map *umap) +{ + struct isl_un_op_control control = { + .fn_map = &isl_map_domain_map, + }; + return un_op(umap, &control); +} + +/* Construct an isl_pw_multi_aff that maps "map" to its domain and + * add the result to "res". + */ +static isl_stat domain_map_upma(__isl_take isl_map *map, void *user) +{ + isl_union_pw_multi_aff **res = user; + isl_multi_aff *ma; + isl_pw_multi_aff *pma; + + ma = isl_multi_aff_domain_map(isl_map_get_space(map)); + pma = isl_pw_multi_aff_alloc(isl_map_wrap(map), ma); + *res = isl_union_pw_multi_aff_add_pw_multi_aff(*res, pma); + + return *res ? isl_stat_ok : isl_stat_error; + +} + +/* Return an isl_union_pw_multi_aff that maps a wrapped copy of "umap" + * to its domain. + */ +__isl_give isl_union_pw_multi_aff *isl_union_map_domain_map_union_pw_multi_aff( + __isl_take isl_union_map *umap) +{ + isl_union_pw_multi_aff *res; + + res = isl_union_pw_multi_aff_empty(isl_union_map_get_space(umap)); + if (isl_union_map_foreach_map(umap, &domain_map_upma, &res) < 0) + res = isl_union_pw_multi_aff_free(res); + + isl_union_map_free(umap); + return res; +} + +__isl_give isl_union_map *isl_union_map_range_map( + __isl_take isl_union_map *umap) +{ + struct isl_un_op_control control = { + .fn_map = &isl_map_range_map, + }; + return un_op(umap, &control); +} + +/* Given a collection of wrapped maps of the form A[B -> C], + * return the collection of maps A[B -> C] -> B. + */ +__isl_give isl_union_map *isl_union_set_wrapped_domain_map( + __isl_take isl_union_set *uset) +{ + struct isl_un_op_drop_user_data data = { &isl_set_is_wrapping }; + struct isl_un_op_control control = { + .filter = &un_op_filter_drop_user, + .filter_user = &data, + .fn_map = &isl_set_wrapped_domain_map, + }; + return un_op(uset, &control); +} + +/* Does "map" relate elements from the same space? + */ +static isl_bool equal_tuples(__isl_keep isl_map *map, void *user) +{ + return isl_map_tuple_is_equal(map, isl_dim_in, map, isl_dim_out); +} + +__isl_give isl_union_set *isl_union_map_deltas(__isl_take isl_union_map *umap) +{ + struct isl_un_op_control control = { + .filter = &equal_tuples, + .fn_map = &isl_map_deltas, + }; + return un_op(umap, &control); +} + +__isl_give isl_union_map *isl_union_map_deltas_map( + __isl_take isl_union_map *umap) +{ + struct isl_un_op_control control = { + .filter = &equal_tuples, + .fn_map = &isl_map_deltas_map, + }; + return un_op(umap, &control); +} + +__isl_give isl_union_map *isl_union_set_identity(__isl_take isl_union_set *uset) +{ + struct isl_un_op_control control = { + .fn_map = &isl_set_identity, + }; + return un_op(uset, &control); +} + +/* Construct an identity isl_pw_multi_aff on "set" and add it to *res. + */ +static isl_stat identity_upma(__isl_take isl_set *set, void *user) +{ + isl_union_pw_multi_aff **res = user; + isl_space *space; + isl_pw_multi_aff *pma; + + space = isl_space_map_from_set(isl_set_get_space(set)); + pma = isl_pw_multi_aff_identity(space); + pma = isl_pw_multi_aff_intersect_domain(pma, set); + *res = isl_union_pw_multi_aff_add_pw_multi_aff(*res, pma); + + return *res ? isl_stat_ok : isl_stat_error; +} + +/* Return an identity function on "uset" in the form + * of an isl_union_pw_multi_aff. + */ +__isl_give isl_union_pw_multi_aff *isl_union_set_identity_union_pw_multi_aff( + __isl_take isl_union_set *uset) +{ + isl_union_pw_multi_aff *res; + + res = isl_union_pw_multi_aff_empty(isl_union_set_get_space(uset)); + if (isl_union_set_foreach_set(uset, &identity_upma, &res) < 0) + res = isl_union_pw_multi_aff_free(res); + + isl_union_set_free(uset); + return res; +} + +/* For each map in "umap" of the form [A -> B] -> C, + * construct the map A -> C and collect the results. + */ +__isl_give isl_union_map *isl_union_map_domain_factor_domain( + __isl_take isl_union_map *umap) +{ + struct isl_un_op_drop_user_data data = { &isl_map_domain_is_wrapping }; + struct isl_un_op_control control = { + .filter = &un_op_filter_drop_user, + .filter_user = &data, + .fn_map = &isl_map_domain_factor_domain, + }; + return un_op(umap, &control); +} + +/* For each map in "umap" of the form [A -> B] -> C, + * construct the map B -> C and collect the results. + */ +__isl_give isl_union_map *isl_union_map_domain_factor_range( + __isl_take isl_union_map *umap) +{ + struct isl_un_op_drop_user_data data = { &isl_map_domain_is_wrapping }; + struct isl_un_op_control control = { + .filter = &un_op_filter_drop_user, + .filter_user = &data, + .fn_map = &isl_map_domain_factor_range, + }; + return un_op(umap, &control); +} + +/* For each map in "umap" of the form A -> [B -> C], + * construct the map A -> B and collect the results. + */ +__isl_give isl_union_map *isl_union_map_range_factor_domain( + __isl_take isl_union_map *umap) +{ + struct isl_un_op_drop_user_data data = { &isl_map_range_is_wrapping }; + struct isl_un_op_control control = { + .filter = &un_op_filter_drop_user, + .filter_user = &data, + .fn_map = &isl_map_range_factor_domain, + }; + return un_op(umap, &control); +} + +/* For each map in "umap" of the form A -> [B -> C], + * construct the map A -> C and collect the results. + */ +__isl_give isl_union_map *isl_union_map_range_factor_range( + __isl_take isl_union_map *umap) +{ + struct isl_un_op_drop_user_data data = { &isl_map_range_is_wrapping }; + struct isl_un_op_control control = { + .filter = &un_op_filter_drop_user, + .filter_user = &data, + .fn_map = &isl_map_range_factor_range, + }; + return un_op(umap, &control); +} + +/* For each map in "umap" of the form [A -> B] -> [C -> D], + * construct the map A -> C and collect the results. + */ +__isl_give isl_union_map *isl_union_map_factor_domain( + __isl_take isl_union_map *umap) +{ + struct isl_un_op_drop_user_data data = { &isl_map_is_product }; + struct isl_un_op_control control = { + .filter = &un_op_filter_drop_user, + .filter_user = &data, + .fn_map = &isl_map_factor_domain, + }; + return un_op(umap, &control); +} + +/* For each map in "umap" of the form [A -> B] -> [C -> D], + * construct the map B -> D and collect the results. + */ +__isl_give isl_union_map *isl_union_map_factor_range( + __isl_take isl_union_map *umap) +{ + struct isl_un_op_drop_user_data data = { &isl_map_is_product }; + struct isl_un_op_control control = { + .filter = &un_op_filter_drop_user, + .filter_user = &data, + .fn_map = &isl_map_factor_range, + }; + return un_op(umap, &control); +} + +__isl_give isl_union_map *isl_union_set_unwrap(__isl_take isl_union_set *uset) +{ + struct isl_un_op_drop_user_data data = { &isl_set_is_wrapping }; + struct isl_un_op_control control = { + .filter = &un_op_filter_drop_user, + .filter_user = &data, + .fn_map = &isl_set_unwrap, + }; + return un_op(uset, &control); +} + +__isl_give isl_union_set *isl_union_map_wrap(__isl_take isl_union_map *umap) +{ + struct isl_un_op_control control = { + .fn_map = &isl_map_wrap, + }; + return un_op(umap, &control); +} + +struct isl_union_map_is_subset_data { + isl_union_map *umap2; + isl_bool is_subset; +}; + +static isl_stat is_subset_entry(void **entry, void *user) +{ + struct isl_union_map_is_subset_data *data = user; + struct isl_hash_table_entry *entry2; + isl_space *space; + isl_map *map = *entry; + + space = isl_map_peek_space(map); + entry2 = isl_union_map_find_entry(data->umap2, space, 0); + if (!entry2) + return isl_stat_error; + if (entry2 == isl_hash_table_entry_none) { + int empty = isl_map_is_empty(map); + if (empty < 0) + return isl_stat_error; + if (empty) + return isl_stat_ok; + data->is_subset = isl_bool_false; + return isl_stat_error; + } + + data->is_subset = isl_map_is_subset(map, entry2->data); + if (data->is_subset < 0 || !data->is_subset) + return isl_stat_error; + + return isl_stat_ok; +} + +isl_bool isl_union_map_is_subset(__isl_keep isl_union_map *umap1, + __isl_keep isl_union_map *umap2) +{ + struct isl_union_map_is_subset_data data = { NULL, isl_bool_true }; + + if (!umap1 || !umap2) + return isl_bool_error; + + data.umap2 = umap2; + if (isl_hash_table_foreach(umap1->dim->ctx, &umap1->table, + &is_subset_entry, &data) < 0 && + data.is_subset) + return isl_bool_error; + + return data.is_subset; +} + +isl_bool isl_union_set_is_subset(__isl_keep isl_union_set *uset1, + __isl_keep isl_union_set *uset2) +{ + return isl_union_map_is_subset(uset1, uset2); +} + +isl_bool isl_union_map_is_equal(__isl_keep isl_union_map *umap1, + __isl_keep isl_union_map *umap2) +{ + isl_bool is_subset; + + if (!umap1 || !umap2) + return isl_bool_error; + is_subset = isl_union_map_is_subset(umap1, umap2); + if (is_subset != isl_bool_true) + return is_subset; + is_subset = isl_union_map_is_subset(umap2, umap1); + return is_subset; +} + +isl_bool isl_union_set_is_equal(__isl_keep isl_union_set *uset1, + __isl_keep isl_union_set *uset2) +{ + return isl_union_map_is_equal(uset1, uset2); +} + +isl_bool isl_union_map_is_strict_subset(__isl_keep isl_union_map *umap1, + __isl_keep isl_union_map *umap2) +{ + isl_bool is_subset; + + if (!umap1 || !umap2) + return isl_bool_error; + is_subset = isl_union_map_is_subset(umap1, umap2); + if (is_subset != isl_bool_true) + return is_subset; + is_subset = isl_union_map_is_subset(umap2, umap1); + return isl_bool_not(is_subset); +} + +isl_bool isl_union_set_is_strict_subset(__isl_keep isl_union_set *uset1, + __isl_keep isl_union_set *uset2) +{ + return isl_union_map_is_strict_subset(uset1, uset2); +} + +/* Internal data structure for isl_union_map_is_disjoint. + * umap2 is the union map with which we are comparing. + * is_disjoint is initialized to 1 and is set to 0 as soon + * as the union maps turn out not to be disjoint. + */ +struct isl_union_map_is_disjoint_data { + isl_union_map *umap2; + isl_bool is_disjoint; +}; + +/* Check if "map" is disjoint from data->umap2 and abort + * the search if it is not. + */ +static isl_stat is_disjoint_entry(void **entry, void *user) +{ + struct isl_union_map_is_disjoint_data *data = user; + struct isl_hash_table_entry *entry2; + isl_space *space; + isl_map *map = *entry; + + space = isl_map_peek_space(map); + entry2 = isl_union_map_find_entry(data->umap2, space, 0); + if (!entry2) + return isl_stat_error; + if (entry2 == isl_hash_table_entry_none) + return isl_stat_ok; + + data->is_disjoint = isl_map_is_disjoint(map, entry2->data); + if (data->is_disjoint < 0 || !data->is_disjoint) + return isl_stat_error; + + return isl_stat_ok; +} + +/* Are "umap1" and "umap2" disjoint? + */ +isl_bool isl_union_map_is_disjoint(__isl_keep isl_union_map *umap1, + __isl_keep isl_union_map *umap2) +{ + struct isl_union_map_is_disjoint_data data = { NULL, isl_bool_true }; + + umap1 = isl_union_map_copy(umap1); + umap2 = isl_union_map_copy(umap2); + umap1 = isl_union_map_align_params(umap1, + isl_union_map_get_space(umap2)); + umap2 = isl_union_map_align_params(umap2, + isl_union_map_get_space(umap1)); + + if (!umap1 || !umap2) + goto error; + + data.umap2 = umap2; + if (isl_hash_table_foreach(umap1->dim->ctx, &umap1->table, + &is_disjoint_entry, &data) < 0 && + data.is_disjoint) + goto error; + + isl_union_map_free(umap1); + isl_union_map_free(umap2); + + return data.is_disjoint; +error: + isl_union_map_free(umap1); + isl_union_map_free(umap2); + return isl_bool_error; +} + +/* Are "uset1" and "uset2" disjoint? + */ +isl_bool isl_union_set_is_disjoint(__isl_keep isl_union_set *uset1, + __isl_keep isl_union_set *uset2) +{ + return isl_union_map_is_disjoint(uset1, uset2); +} + +static isl_stat sample_entry(void **entry, void *user) +{ + isl_basic_map **sample = (isl_basic_map **)user; + isl_map *map = *entry; + + *sample = isl_map_sample(isl_map_copy(map)); + if (!*sample) + return isl_stat_error; + if (!isl_basic_map_plain_is_empty(*sample)) + return isl_stat_error; + return isl_stat_ok; +} + +__isl_give isl_basic_map *isl_union_map_sample(__isl_take isl_union_map *umap) +{ + isl_basic_map *sample = NULL; + + if (!umap) + return NULL; + + if (isl_hash_table_foreach(umap->dim->ctx, &umap->table, + &sample_entry, &sample) < 0 && + !sample) + goto error; + + if (!sample) + sample = isl_basic_map_empty(isl_union_map_get_space(umap)); + + isl_union_map_free(umap); + + return sample; +error: + isl_union_map_free(umap); + return NULL; +} + +__isl_give isl_basic_set *isl_union_set_sample(__isl_take isl_union_set *uset) +{ + return bset_from_bmap(isl_union_map_sample(uset)); +} + +/* Return an element in "uset" in the form of an isl_point. + * Return a void isl_point if "uset" is empty. + */ +__isl_give isl_point *isl_union_set_sample_point(__isl_take isl_union_set *uset) +{ + return isl_basic_set_sample_point(isl_union_set_sample(uset)); +} + +struct isl_forall_data { + isl_bool res; + isl_bool (*fn)(__isl_keep isl_map *map); +}; + +static isl_stat forall_entry(void **entry, void *user) +{ + struct isl_forall_data *data = user; + isl_map *map = *entry; + + data->res = data->fn(map); + if (data->res < 0) + return isl_stat_error; + + if (!data->res) + return isl_stat_error; + + return isl_stat_ok; +} + +static isl_bool union_map_forall(__isl_keep isl_union_map *umap, + isl_bool (*fn)(__isl_keep isl_map *map)) +{ + struct isl_forall_data data = { isl_bool_true, fn }; + + if (!umap) + return isl_bool_error; + + if (isl_hash_table_foreach(umap->dim->ctx, &umap->table, + &forall_entry, &data) < 0 && data.res) + return isl_bool_error; + + return data.res; +} + +struct isl_forall_user_data { + isl_bool res; + isl_bool (*fn)(__isl_keep isl_map *map, void *user); + void *user; +}; + +static isl_stat forall_user_entry(void **entry, void *user) +{ + struct isl_forall_user_data *data = user; + isl_map *map = *entry; + + data->res = data->fn(map, data->user); + if (data->res < 0) + return isl_stat_error; + + if (!data->res) + return isl_stat_error; + + return isl_stat_ok; +} + +/* Check if fn(map, user) returns true for all maps "map" in umap. + */ +static isl_bool union_map_forall_user(__isl_keep isl_union_map *umap, + isl_bool (*fn)(__isl_keep isl_map *map, void *user), void *user) +{ + struct isl_forall_user_data data = { isl_bool_true, fn, user }; + + if (!umap) + return isl_bool_error; + + if (isl_hash_table_foreach(umap->dim->ctx, &umap->table, + &forall_user_entry, &data) < 0 && data.res) + return isl_bool_error; + + return data.res; +} + +/* Is "umap" obviously empty? + */ +isl_bool isl_union_map_plain_is_empty(__isl_keep isl_union_map *umap) +{ + isl_size n; + + n = isl_union_map_n_map(umap); + if (n < 0) + return isl_bool_error; + return n == 0; +} + +isl_bool isl_union_map_is_empty(__isl_keep isl_union_map *umap) +{ + return union_map_forall(umap, &isl_map_is_empty); +} + +isl_bool isl_union_set_is_empty(__isl_keep isl_union_set *uset) +{ + return isl_union_map_is_empty(uset); +} + +static isl_bool is_subset_of_identity(__isl_keep isl_map *map) +{ + isl_bool is_subset; + isl_space *space; + isl_map *id; + isl_bool match; + + match = isl_map_tuple_is_equal(map, isl_dim_in, map, isl_dim_out); + if (match < 0) + return isl_bool_error; + if (!match) + return isl_bool_false; + + space = isl_map_get_space(map); + id = isl_map_identity(space); + + is_subset = isl_map_is_subset(map, id); + + isl_map_free(id); + + return is_subset; +} + +/* Given an isl_union_map that consists of a single map, check + * if it is single-valued. + */ +static isl_bool single_map_is_single_valued(__isl_keep isl_union_map *umap) +{ + isl_map *map; + isl_bool sv; + + umap = isl_union_map_copy(umap); + map = isl_map_from_union_map(umap); + sv = isl_map_is_single_valued(map); + isl_map_free(map); + + return sv; +} + +/* Internal data structure for single_valued_on_domain. + * + * "umap" is the union map to be tested. + * "sv" is set to 1 as long as "umap" may still be single-valued. + */ +struct isl_union_map_is_sv_data { + isl_union_map *umap; + isl_bool sv; +}; + +/* Check if the data->umap is single-valued on "set". + * + * If data->umap consists of a single map on "set", then test it + * as an isl_map. + * + * Otherwise, compute + * + * M \circ M^-1 + * + * check if the result is a subset of the identity mapping and + * store the result in data->sv. + * + * Terminate as soon as data->umap has been determined not to + * be single-valued. + */ +static isl_stat single_valued_on_domain(__isl_take isl_set *set, void *user) +{ + struct isl_union_map_is_sv_data *data = user; + isl_union_map *umap, *test; + isl_size n; + + umap = isl_union_map_copy(data->umap); + umap = isl_union_map_intersect_domain(umap, + isl_union_set_from_set(set)); + + n = isl_union_map_n_map(umap); + if (n < 0) { + data->sv = isl_bool_error; + } else if (n == 1) { + data->sv = single_map_is_single_valued(umap); + isl_union_map_free(umap); + } else { + test = isl_union_map_reverse(isl_union_map_copy(umap)); + test = isl_union_map_apply_range(test, umap); + + data->sv = union_map_forall(test, &is_subset_of_identity); + + isl_union_map_free(test); + } + + if (data->sv < 0 || !data->sv) + return isl_stat_error; + return isl_stat_ok; +} + +/* Check if the given map is single-valued. + * + * If the union map consists of a single map, then test it as an isl_map. + * Otherwise, check if the union map is single-valued on each of its + * domain spaces. + */ +isl_bool isl_union_map_is_single_valued(__isl_keep isl_union_map *umap) +{ + isl_union_map *universe; + isl_union_set *domain; + struct isl_union_map_is_sv_data data; + isl_size n; + + n = isl_union_map_n_map(umap); + if (n < 0) + return isl_bool_error; + if (n == 1) + return single_map_is_single_valued(umap); + + universe = isl_union_map_universe(isl_union_map_copy(umap)); + domain = isl_union_map_domain(universe); + + data.sv = isl_bool_true; + data.umap = umap; + if (isl_union_set_foreach_set(domain, + &single_valued_on_domain, &data) < 0 && data.sv) + data.sv = isl_bool_error; + isl_union_set_free(domain); + + return data.sv; +} + +isl_bool isl_union_map_is_injective(__isl_keep isl_union_map *umap) +{ + isl_bool in; + + umap = isl_union_map_copy(umap); + umap = isl_union_map_reverse(umap); + in = isl_union_map_is_single_valued(umap); + isl_union_map_free(umap); + + return in; +} + +/* Is "map" obviously not an identity relation because + * it maps elements from one space to another space? + * Update *non_identity accordingly. + * + * In particular, if the domain and range spaces are the same, + * then the map is not considered to obviously not be an identity relation. + * Otherwise, the map is considered to obviously not be an identity relation + * if it is is non-empty. + * + * If "map" is determined to obviously not be an identity relation, + * then the search is aborted. + */ +static isl_stat map_plain_is_not_identity(__isl_take isl_map *map, void *user) +{ + isl_bool *non_identity = user; + isl_bool equal; + + equal = isl_map_tuple_is_equal(map, isl_dim_in, map, isl_dim_out); + if (equal >= 0 && !equal) + *non_identity = isl_bool_not(isl_map_is_empty(map)); + else + *non_identity = isl_bool_not(equal); + isl_map_free(map); + + if (*non_identity < 0 || *non_identity) + return isl_stat_error; + + return isl_stat_ok; +} + +/* Is "umap" obviously not an identity relation because + * it maps elements from one space to another space? + * + * As soon as a map has been found that maps elements to a different space, + * non_identity is changed and the search is aborted. + */ +static isl_bool isl_union_map_plain_is_not_identity( + __isl_keep isl_union_map *umap) +{ + isl_bool non_identity; + + non_identity = isl_bool_false; + if (isl_union_map_foreach_map(umap, &map_plain_is_not_identity, + &non_identity) < 0 && + non_identity == isl_bool_false) + return isl_bool_error; + + return non_identity; +} + +/* Does "map" only map elements to themselves? + * Update *identity accordingly. + * + * If "map" is determined not to be an identity relation, + * then the search is aborted. + */ +static isl_stat map_is_identity(__isl_take isl_map *map, void *user) +{ + isl_bool *identity = user; + + *identity = isl_map_is_identity(map); + isl_map_free(map); + + if (*identity < 0 || !*identity) + return isl_stat_error; + + return isl_stat_ok; +} + +/* Does "umap" only map elements to themselves? + * + * First check if there are any maps that map elements to different spaces. + * If not, then check that all the maps (between identical spaces) + * are identity relations. + */ +isl_bool isl_union_map_is_identity(__isl_keep isl_union_map *umap) +{ + isl_bool non_identity; + isl_bool identity; + + non_identity = isl_union_map_plain_is_not_identity(umap); + if (non_identity < 0 || non_identity) + return isl_bool_not(non_identity); + + identity = isl_bool_true; + if (isl_union_map_foreach_map(umap, &map_is_identity, &identity) < 0 && + identity == isl_bool_true) + return isl_bool_error; + + return identity; +} + +/* Represents a map that has a fixed value (v) for one of its + * range dimensions. + * The map in this structure is not reference counted, so it + * is only valid while the isl_union_map from which it was + * obtained is still alive. + */ +struct isl_fixed_map { + isl_int v; + isl_map *map; +}; + +static struct isl_fixed_map *alloc_isl_fixed_map_array(isl_ctx *ctx, + int n) +{ + int i; + struct isl_fixed_map *v; + + v = isl_calloc_array(ctx, struct isl_fixed_map, n); + if (!v) + return NULL; + for (i = 0; i < n; ++i) + isl_int_init(v[i].v); + return v; +} + +static void free_isl_fixed_map_array(struct isl_fixed_map *v, int n) +{ + int i; + + if (!v) + return; + for (i = 0; i < n; ++i) + isl_int_clear(v[i].v); + free(v); +} + +/* Compare the "v" field of two isl_fixed_map structs. + */ +static int qsort_fixed_map_cmp(const void *p1, const void *p2) +{ + const struct isl_fixed_map *e1 = (const struct isl_fixed_map *) p1; + const struct isl_fixed_map *e2 = (const struct isl_fixed_map *) p2; + + return isl_int_cmp(e1->v, e2->v); +} + +/* Internal data structure used while checking whether all maps + * in a union_map have a fixed value for a given output dimension. + * v is the list of maps, with the fixed value for the dimension + * n is the number of maps considered so far + * pos is the output dimension under investigation + */ +struct isl_fixed_dim_data { + struct isl_fixed_map *v; + int n; + int pos; +}; + +static isl_bool fixed_at_pos(__isl_keep isl_map *map, void *user) +{ + struct isl_fixed_dim_data *data = user; + + data->v[data->n].map = map; + return isl_map_plain_is_fixed(map, isl_dim_out, data->pos, + &data->v[data->n++].v); +} + +static isl_bool plain_injective_on_range(__isl_take isl_union_map *umap, + int first, int n_range); + +/* Given a list of the maps, with their fixed values at output dimension "pos", + * check whether the ranges of the maps form an obvious partition. + * + * We first sort the maps according to their fixed values. + * If all maps have a different value, then we know the ranges form + * a partition. + * Otherwise, we collect the maps with the same fixed value and + * check whether each such collection is obviously injective + * based on later dimensions. + */ +static int separates(struct isl_fixed_map *v, int n, + __isl_take isl_space *space, int pos, int n_range) +{ + int i; + + if (!v) + goto error; + + qsort(v, n, sizeof(*v), &qsort_fixed_map_cmp); + + for (i = 0; i + 1 < n; ++i) { + int j, k; + isl_union_map *part; + int injective; + + for (j = i + 1; j < n; ++j) + if (isl_int_ne(v[i].v, v[j].v)) + break; + + if (j == i + 1) + continue; + + part = isl_union_map_alloc(isl_space_copy(space), j - i); + for (k = i; k < j; ++k) + part = isl_union_map_add_map(part, + isl_map_copy(v[k].map)); + + injective = plain_injective_on_range(part, pos + 1, n_range); + if (injective < 0) + goto error; + if (!injective) + break; + + i = j - 1; + } + + isl_space_free(space); + free_isl_fixed_map_array(v, n); + return i + 1 >= n; +error: + isl_space_free(space); + free_isl_fixed_map_array(v, n); + return -1; +} + +/* Check whether the maps in umap have obviously distinct ranges. + * In particular, check for an output dimension in the range + * [first,n_range) for which all maps have a fixed value + * and then check if these values, possibly along with fixed values + * at later dimensions, entail distinct ranges. + */ +static isl_bool plain_injective_on_range(__isl_take isl_union_map *umap, + int first, int n_range) +{ + isl_ctx *ctx; + isl_size n; + struct isl_fixed_dim_data data = { NULL }; + + ctx = isl_union_map_get_ctx(umap); + + n = isl_union_map_n_map(umap); + if (n < 0) + goto error; + + if (n <= 1) { + isl_union_map_free(umap); + return isl_bool_true; + } + + if (first >= n_range) { + isl_union_map_free(umap); + return isl_bool_false; + } + + data.v = alloc_isl_fixed_map_array(ctx, n); + if (!data.v) + goto error; + + for (data.pos = first; data.pos < n_range; ++data.pos) { + isl_bool fixed; + int injective; + isl_space *space; + + data.n = 0; + fixed = union_map_forall_user(umap, &fixed_at_pos, &data); + if (fixed < 0) + goto error; + if (!fixed) + continue; + space = isl_union_map_get_space(umap); + injective = separates(data.v, n, space, data.pos, n_range); + isl_union_map_free(umap); + return injective; + } + + free_isl_fixed_map_array(data.v, n); + isl_union_map_free(umap); + + return isl_bool_false; +error: + free_isl_fixed_map_array(data.v, n); + isl_union_map_free(umap); + return isl_bool_error; +} + +/* Check whether the maps in umap that map to subsets of "ran" + * have obviously distinct ranges. + */ +static isl_bool plain_injective_on_range_wrap(__isl_keep isl_set *ran, + void *user) +{ + isl_size dim; + isl_union_map *umap = user; + + dim = isl_set_dim(ran, isl_dim_set); + if (dim < 0) + return isl_bool_error; + + umap = isl_union_map_copy(umap); + umap = isl_union_map_intersect_range(umap, + isl_union_set_from_set(isl_set_copy(ran))); + return plain_injective_on_range(umap, 0, dim); +} + +/* Check if the given union_map is obviously injective. + * + * In particular, we first check if all individual maps are obviously + * injective and then check if all the ranges of these maps are + * obviously disjoint. + */ +isl_bool isl_union_map_plain_is_injective(__isl_keep isl_union_map *umap) +{ + isl_bool in; + isl_union_map *univ; + isl_union_set *ran; + + in = union_map_forall(umap, &isl_map_plain_is_injective); + if (in < 0) + return isl_bool_error; + if (!in) + return isl_bool_false; + + univ = isl_union_map_universe(isl_union_map_copy(umap)); + ran = isl_union_map_range(univ); + + in = union_map_forall_user(ran, &plain_injective_on_range_wrap, umap); + + isl_union_set_free(ran); + + return in; +} + +isl_bool isl_union_map_is_bijective(__isl_keep isl_union_map *umap) +{ + isl_bool sv; + + sv = isl_union_map_is_single_valued(umap); + if (sv < 0 || !sv) + return sv; + + return isl_union_map_is_injective(umap); +} + +__isl_give isl_union_map *isl_union_map_zip(__isl_take isl_union_map *umap) +{ + struct isl_un_op_drop_user_data data = { &isl_map_can_zip }; + struct isl_un_op_control control = { + .filter = &un_op_filter_drop_user, + .filter_user = &data, + .fn_map = &isl_map_zip, + }; + return un_op(umap, &control); +} + +/* Given a union map, take the maps of the form A -> (B -> C) and + * return the union of the corresponding maps (A -> B) -> C. + */ +__isl_give isl_union_map *isl_union_map_uncurry(__isl_take isl_union_map *umap) +{ + struct isl_un_op_drop_user_data data = { &isl_map_can_uncurry }; + struct isl_un_op_control control = { + .filter = &un_op_filter_drop_user, + .filter_user = &data, + .fn_map = &isl_map_uncurry, + }; + return un_op(umap, &control); +} + +/* Given a union map, take the maps of the form (A -> B) -> C and + * return the union of the corresponding maps A -> (B -> C). + */ +__isl_give isl_union_map *isl_union_map_curry(__isl_take isl_union_map *umap) +{ + struct isl_un_op_drop_user_data data = { &isl_map_can_curry }; + struct isl_un_op_control control = { + .filter = &un_op_filter_drop_user, + .filter_user = &data, + .fn_map = &isl_map_curry, + }; + return un_op(umap, &control); +} + +/* Given a union map, take the maps of the form A -> ((B -> C) -> D) and + * return the union of the corresponding maps A -> (B -> (C -> D)). + */ +__isl_give isl_union_map *isl_union_map_range_curry( + __isl_take isl_union_map *umap) +{ + struct isl_un_op_drop_user_data data = { &isl_map_can_range_curry }; + struct isl_un_op_control control = { + .filter = &un_op_filter_drop_user, + .filter_user = &data, + .fn_map = &isl_map_range_curry, + }; + return un_op(umap, &control); +} + +__isl_give isl_union_set *isl_union_set_lift(__isl_take isl_union_set *uset) +{ + struct isl_un_op_control control = { + .fn_map = &isl_set_lift, + }; + return un_op(uset, &control); +} + +static isl_stat coefficients_entry(void **entry, void *user) +{ + isl_set *set = *entry; + isl_union_set **res = user; + + set = isl_set_copy(set); + set = isl_set_from_basic_set(isl_set_coefficients(set)); + *res = isl_union_set_add_set(*res, set); + + return isl_stat_ok; +} + +__isl_give isl_union_set *isl_union_set_coefficients( + __isl_take isl_union_set *uset) +{ + isl_ctx *ctx; + isl_space *space; + isl_union_set *res; + + if (!uset) + return NULL; + + ctx = isl_union_set_get_ctx(uset); + space = isl_space_set_alloc(ctx, 0, 0); + res = isl_union_map_alloc(space, uset->table.n); + if (isl_hash_table_foreach(uset->dim->ctx, &uset->table, + &coefficients_entry, &res) < 0) + goto error; + + isl_union_set_free(uset); + return res; +error: + isl_union_set_free(uset); + isl_union_set_free(res); + return NULL; +} + +static isl_stat solutions_entry(void **entry, void *user) +{ + isl_set *set = *entry; + isl_union_set **res = user; + + set = isl_set_copy(set); + set = isl_set_from_basic_set(isl_set_solutions(set)); + if (!*res) + *res = isl_union_set_from_set(set); + else + *res = isl_union_set_add_set(*res, set); + + if (!*res) + return isl_stat_error; + + return isl_stat_ok; +} + +__isl_give isl_union_set *isl_union_set_solutions( + __isl_take isl_union_set *uset) +{ + isl_union_set *res = NULL; + + if (!uset) + return NULL; + + if (uset->table.n == 0) { + res = isl_union_set_empty(isl_union_set_get_space(uset)); + isl_union_set_free(uset); + return res; + } + + if (isl_hash_table_foreach(uset->dim->ctx, &uset->table, + &solutions_entry, &res) < 0) + goto error; + + isl_union_set_free(uset); + return res; +error: + isl_union_set_free(uset); + isl_union_set_free(res); + return NULL; +} + +/* Is the domain space of "map" equal to "space"? + */ +static int domain_match(__isl_keep isl_map *map, __isl_keep isl_space *space) +{ + return isl_map_space_tuple_is_equal(map, isl_dim_in, + space, isl_dim_out); +} + +/* Is the range space of "map" equal to "space"? + */ +static int range_match(__isl_keep isl_map *map, __isl_keep isl_space *space) +{ + return isl_map_space_tuple_is_equal(map, isl_dim_out, + space, isl_dim_out); +} + +/* Is the set space of "map" equal to "space"? + */ +static int set_match(__isl_keep isl_map *map, __isl_keep isl_space *space) +{ + return isl_map_space_tuple_is_equal(map, isl_dim_set, + space, isl_dim_out); +} + +/* Internal data structure for preimage_pw_multi_aff. + * + * "pma" is the function under which the preimage should be taken. + * "space" is the space of "pma". + * "res" collects the results. + * "fn" computes the preimage for a given map. + * "match" returns true if "fn" can be called. + */ +struct isl_union_map_preimage_data { + isl_space *space; + isl_pw_multi_aff *pma; + isl_union_map *res; + int (*match)(__isl_keep isl_map *map, __isl_keep isl_space *space); + __isl_give isl_map *(*fn)(__isl_take isl_map *map, + __isl_take isl_pw_multi_aff *pma); +}; + +/* Call data->fn to compute the preimage of the domain or range of *entry + * under the function represented by data->pma, provided the domain/range + * space of *entry matches the target space of data->pma + * (as given by data->match), and add the result to data->res. + */ +static isl_stat preimage_entry(void **entry, void *user) +{ + int m; + isl_map *map = *entry; + struct isl_union_map_preimage_data *data = user; + isl_bool empty; + + m = data->match(map, data->space); + if (m < 0) + return isl_stat_error; + if (!m) + return isl_stat_ok; + + map = isl_map_copy(map); + map = data->fn(map, isl_pw_multi_aff_copy(data->pma)); + + empty = isl_map_is_empty(map); + if (empty < 0 || empty) { + isl_map_free(map); + return empty < 0 ? isl_stat_error : isl_stat_ok; + } + + data->res = isl_union_map_add_map(data->res, map); + + return isl_stat_ok; +} + +/* Compute the preimage of the domain or range of "umap" under the function + * represented by "pma". + * In other words, plug in "pma" in the domain or range of "umap". + * The function "fn" performs the actual preimage computation on a map, + * while "match" determines to which maps the function should be applied. + */ +static __isl_give isl_union_map *preimage_pw_multi_aff( + __isl_take isl_union_map *umap, __isl_take isl_pw_multi_aff *pma, + int (*match)(__isl_keep isl_map *map, __isl_keep isl_space *space), + __isl_give isl_map *(*fn)(__isl_take isl_map *map, + __isl_take isl_pw_multi_aff *pma)) +{ + isl_ctx *ctx; + isl_space *space; + struct isl_union_map_preimage_data data; + + umap = isl_union_map_align_params(umap, + isl_pw_multi_aff_get_space(pma)); + pma = isl_pw_multi_aff_align_params(pma, isl_union_map_get_space(umap)); + + if (!umap || !pma) + goto error; + + ctx = isl_union_map_get_ctx(umap); + space = isl_union_map_get_space(umap); + data.space = isl_pw_multi_aff_get_space(pma); + data.pma = pma; + data.res = isl_union_map_alloc(space, umap->table.n); + data.match = match; + data.fn = fn; + if (isl_hash_table_foreach(ctx, &umap->table, &preimage_entry, + &data) < 0) + data.res = isl_union_map_free(data.res); + + isl_space_free(data.space); + isl_union_map_free(umap); + isl_pw_multi_aff_free(pma); + return data.res; +error: + isl_union_map_free(umap); + isl_pw_multi_aff_free(pma); + return NULL; +} + +/* Compute the preimage of the domain of "umap" under the function + * represented by "pma". + * In other words, plug in "pma" in the domain of "umap". + * The result contains maps that live in the same spaces as the maps of "umap" + * with domain space equal to the target space of "pma", + * except that the domain has been replaced by the domain space of "pma". + */ +__isl_give isl_union_map *isl_union_map_preimage_domain_pw_multi_aff( + __isl_take isl_union_map *umap, __isl_take isl_pw_multi_aff *pma) +{ + return preimage_pw_multi_aff(umap, pma, &domain_match, + &isl_map_preimage_domain_pw_multi_aff); +} + +/* Compute the preimage of the range of "umap" under the function + * represented by "pma". + * In other words, plug in "pma" in the range of "umap". + * The result contains maps that live in the same spaces as the maps of "umap" + * with range space equal to the target space of "pma", + * except that the range has been replaced by the domain space of "pma". + */ +__isl_give isl_union_map *isl_union_map_preimage_range_pw_multi_aff( + __isl_take isl_union_map *umap, __isl_take isl_pw_multi_aff *pma) +{ + return preimage_pw_multi_aff(umap, pma, &range_match, + &isl_map_preimage_range_pw_multi_aff); +} + +/* Compute the preimage of "uset" under the function represented by "pma". + * In other words, plug in "pma" in "uset". + * The result contains sets that live in the same spaces as the sets of "uset" + * with space equal to the target space of "pma", + * except that the space has been replaced by the domain space of "pma". + */ +__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) +{ + return preimage_pw_multi_aff(uset, pma, &set_match, + &isl_set_preimage_pw_multi_aff); +} + +/* Compute the preimage of the domain of "umap" under the function + * represented by "ma". + * In other words, plug in "ma" in the domain of "umap". + * The result contains maps that live in the same spaces as the maps of "umap" + * with domain space equal to the target space of "ma", + * except that the domain has been replaced by the domain space of "ma". + */ +__isl_give isl_union_map *isl_union_map_preimage_domain_multi_aff( + __isl_take isl_union_map *umap, __isl_take isl_multi_aff *ma) +{ + return isl_union_map_preimage_domain_pw_multi_aff(umap, + isl_pw_multi_aff_from_multi_aff(ma)); +} + +/* Compute the preimage of the range of "umap" under the function + * represented by "ma". + * In other words, plug in "ma" in the range of "umap". + * The result contains maps that live in the same spaces as the maps of "umap" + * with range space equal to the target space of "ma", + * except that the range has been replaced by the domain space of "ma". + */ +__isl_give isl_union_map *isl_union_map_preimage_range_multi_aff( + __isl_take isl_union_map *umap, __isl_take isl_multi_aff *ma) +{ + return isl_union_map_preimage_range_pw_multi_aff(umap, + isl_pw_multi_aff_from_multi_aff(ma)); +} + +/* Compute the preimage of "uset" under the function represented by "ma". + * In other words, plug in "ma" in "uset". + * The result contains sets that live in the same spaces as the sets of "uset" + * with space equal to the target space of "ma", + * except that the space has been replaced by the domain space of "ma". + */ +__isl_give isl_union_map *isl_union_set_preimage_multi_aff( + __isl_take isl_union_set *uset, __isl_take isl_multi_aff *ma) +{ + return isl_union_set_preimage_pw_multi_aff(uset, + isl_pw_multi_aff_from_multi_aff(ma)); +} + +/* Internal data structure for preimage_multi_pw_aff. + * + * "mpa" is the function under which the preimage should be taken. + * "space" is the space of "mpa". + * "res" collects the results. + * "fn" computes the preimage for a given map. + * "match" returns true if "fn" can be called. + */ +struct isl_union_map_preimage_mpa_data { + isl_space *space; + isl_multi_pw_aff *mpa; + isl_union_map *res; + int (*match)(__isl_keep isl_map *map, __isl_keep isl_space *space); + __isl_give isl_map *(*fn)(__isl_take isl_map *map, + __isl_take isl_multi_pw_aff *mpa); +}; + +/* Call data->fn to compute the preimage of the domain or range of *entry + * under the function represented by data->mpa, provided the domain/range + * space of *entry matches the target space of data->mpa + * (as given by data->match), and add the result to data->res. + */ +static isl_stat preimage_mpa_entry(void **entry, void *user) +{ + int m; + isl_map *map = *entry; + struct isl_union_map_preimage_mpa_data *data = user; + isl_bool empty; + + m = data->match(map, data->space); + if (m < 0) + return isl_stat_error; + if (!m) + return isl_stat_ok; + + map = isl_map_copy(map); + map = data->fn(map, isl_multi_pw_aff_copy(data->mpa)); + + empty = isl_map_is_empty(map); + if (empty < 0 || empty) { + isl_map_free(map); + return empty < 0 ? isl_stat_error : isl_stat_ok; + } + + data->res = isl_union_map_add_map(data->res, map); + + return isl_stat_ok; +} + +/* Compute the preimage of the domain or range of "umap" under the function + * represented by "mpa". + * In other words, plug in "mpa" in the domain or range of "umap". + * The function "fn" performs the actual preimage computation on a map, + * while "match" determines to which maps the function should be applied. + */ +static __isl_give isl_union_map *preimage_multi_pw_aff( + __isl_take isl_union_map *umap, __isl_take isl_multi_pw_aff *mpa, + int (*match)(__isl_keep isl_map *map, __isl_keep isl_space *space), + __isl_give isl_map *(*fn)(__isl_take isl_map *map, + __isl_take isl_multi_pw_aff *mpa)) +{ + isl_ctx *ctx; + isl_space *space; + struct isl_union_map_preimage_mpa_data data; + + umap = isl_union_map_align_params(umap, + isl_multi_pw_aff_get_space(mpa)); + mpa = isl_multi_pw_aff_align_params(mpa, isl_union_map_get_space(umap)); + + if (!umap || !mpa) + goto error; + + ctx = isl_union_map_get_ctx(umap); + space = isl_union_map_get_space(umap); + data.space = isl_multi_pw_aff_get_space(mpa); + data.mpa = mpa; + data.res = isl_union_map_alloc(space, umap->table.n); + data.match = match; + data.fn = fn; + if (isl_hash_table_foreach(ctx, &umap->table, &preimage_mpa_entry, + &data) < 0) + data.res = isl_union_map_free(data.res); + + isl_space_free(data.space); + isl_union_map_free(umap); + isl_multi_pw_aff_free(mpa); + return data.res; +error: + isl_union_map_free(umap); + isl_multi_pw_aff_free(mpa); + return NULL; +} + +/* Compute the preimage of the domain of "umap" under the function + * represented by "mpa". + * In other words, plug in "mpa" in the domain of "umap". + * The result contains maps that live in the same spaces as the maps of "umap" + * with domain space equal to the target space of "mpa", + * except that the domain has been replaced by the domain space of "mpa". + */ +__isl_give isl_union_map *isl_union_map_preimage_domain_multi_pw_aff( + __isl_take isl_union_map *umap, __isl_take isl_multi_pw_aff *mpa) +{ + return preimage_multi_pw_aff(umap, mpa, &domain_match, + &isl_map_preimage_domain_multi_pw_aff); +} + +/* Internal data structure for preimage_upma. + * + * "umap" is the map of which the preimage should be computed. + * "res" collects the results. + * "fn" computes the preimage for a given piecewise multi-affine function. + */ +struct isl_union_map_preimage_upma_data { + isl_union_map *umap; + isl_union_map *res; + __isl_give isl_union_map *(*fn)(__isl_take isl_union_map *umap, + __isl_take isl_pw_multi_aff *pma); +}; + +/* Call data->fn to compute the preimage of the domain or range of data->umap + * under the function represented by pma and add the result to data->res. + */ +static isl_stat preimage_upma(__isl_take isl_pw_multi_aff *pma, void *user) +{ + struct isl_union_map_preimage_upma_data *data = user; + isl_union_map *umap; + + umap = isl_union_map_copy(data->umap); + umap = data->fn(umap, pma); + data->res = isl_union_map_union(data->res, umap); + + return data->res ? isl_stat_ok : isl_stat_error; +} + +/* Compute the preimage of the domain or range of "umap" under the function + * represented by "upma". + * In other words, plug in "upma" in the domain or range of "umap". + * The function "fn" performs the actual preimage computation + * on a piecewise multi-affine function. + */ +static __isl_give isl_union_map *preimage_union_pw_multi_aff( + __isl_take isl_union_map *umap, + __isl_take isl_union_pw_multi_aff *upma, + __isl_give isl_union_map *(*fn)(__isl_take isl_union_map *umap, + __isl_take isl_pw_multi_aff *pma)) +{ + struct isl_union_map_preimage_upma_data data; + + data.umap = umap; + data.res = isl_union_map_empty(isl_union_map_get_space(umap)); + data.fn = fn; + if (isl_union_pw_multi_aff_foreach_pw_multi_aff(upma, + &preimage_upma, &data) < 0) + data.res = isl_union_map_free(data.res); + + isl_union_map_free(umap); + isl_union_pw_multi_aff_free(upma); + + return data.res; +} + +/* Compute the preimage of the domain of "umap" under the function + * represented by "upma". + * In other words, plug in "upma" in the domain of "umap". + * The result contains maps that live in the same spaces as the maps of "umap" + * with domain space equal to one of the target spaces of "upma", + * except that the domain has been replaced by one of the domain spaces that + * correspond to that target space of "upma". + */ +__isl_give isl_union_map *isl_union_map_preimage_domain_union_pw_multi_aff( + __isl_take isl_union_map *umap, + __isl_take isl_union_pw_multi_aff *upma) +{ + return preimage_union_pw_multi_aff(umap, upma, + &isl_union_map_preimage_domain_pw_multi_aff); +} + +/* Compute the preimage of the range of "umap" under the function + * represented by "upma". + * In other words, plug in "upma" in the range of "umap". + * The result contains maps that live in the same spaces as the maps of "umap" + * with range space equal to one of the target spaces of "upma", + * except that the range has been replaced by one of the domain spaces that + * correspond to that target space of "upma". + */ +__isl_give isl_union_map *isl_union_map_preimage_range_union_pw_multi_aff( + __isl_take isl_union_map *umap, + __isl_take isl_union_pw_multi_aff *upma) +{ + return preimage_union_pw_multi_aff(umap, upma, + &isl_union_map_preimage_range_pw_multi_aff); +} + +/* Compute the preimage of "uset" under the function represented by "upma". + * In other words, plug in "upma" in the range of "uset". + * The result contains sets that live in the same spaces as the sets of "uset" + * with space equal to one of the target spaces of "upma", + * except that the space has been replaced by one of the domain spaces that + * correspond to that target space of "upma". + */ +__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) +{ + return preimage_union_pw_multi_aff(uset, upma, + &isl_union_set_preimage_pw_multi_aff); +} + +/* Reset the user pointer on all identifiers of parameters and tuples + * of the spaces of "umap". + */ +__isl_give isl_union_map *isl_union_map_reset_user( + __isl_take isl_union_map *umap) +{ + umap = isl_union_map_cow(umap); + if (!umap) + return NULL; + umap->dim = isl_space_reset_user(umap->dim); + if (!umap->dim) + return isl_union_map_free(umap); + return total(umap, &isl_map_reset_user); +} + +/* Reset the user pointer on all identifiers of parameters and tuples + * of the spaces of "uset". + */ +__isl_give isl_union_set *isl_union_set_reset_user( + __isl_take isl_union_set *uset) +{ + return isl_union_map_reset_user(uset); +} + +/* Remove all existentially quantified variables and integer divisions + * from "umap" using Fourier-Motzkin elimination. + */ +__isl_give isl_union_map *isl_union_map_remove_divs( + __isl_take isl_union_map *umap) +{ + return total(umap, &isl_map_remove_divs); +} + +/* Remove all existentially quantified variables and integer divisions + * from "uset" using Fourier-Motzkin elimination. + */ +__isl_give isl_union_set *isl_union_set_remove_divs( + __isl_take isl_union_set *uset) +{ + return isl_union_map_remove_divs(uset); +} + +/* Internal data structure for isl_union_map_project_out. + * "type", "first" and "n" are the arguments for the isl_map_project_out + * call. + * "res" collects the results. + */ +struct isl_union_map_project_out_data { + enum isl_dim_type type; + unsigned first; + unsigned n; + + isl_union_map *res; +}; + +/* Turn the data->n dimensions of type data->type, starting at data->first + * into existentially quantified variables and add the result to data->res. + */ +static isl_stat project_out(__isl_take isl_map *map, void *user) +{ + struct isl_union_map_project_out_data *data = user; + + map = isl_map_project_out(map, data->type, data->first, data->n); + data->res = isl_union_map_add_map(data->res, map); + + return isl_stat_ok; +} + +/* Turn the "n" dimensions of type "type", starting at "first" + * into existentially quantified variables. + * Since the space of an isl_union_map only contains parameters, + * type is required to be equal to isl_dim_param. + */ +__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_space *space; + struct isl_union_map_project_out_data data = { type, first, n }; + + if (!umap) + return NULL; + + if (type != isl_dim_param) + isl_die(isl_union_map_get_ctx(umap), isl_error_invalid, + "can only project out parameters", + return isl_union_map_free(umap)); + + space = isl_union_map_get_space(umap); + space = isl_space_drop_dims(space, type, first, n); + data.res = isl_union_map_empty(space); + if (isl_union_map_foreach_map(umap, &project_out, &data) < 0) + data.res = isl_union_map_free(data.res); + + isl_union_map_free(umap); + + return data.res; +} + +#undef TYPE +#define TYPE isl_union_map +#include "isl_project_out_all_params_templ.c" +#include "isl_project_out_param_templ.c" + +/* Turn the "n" dimensions of type "type", starting at "first" + * into existentially quantified variables. + * Since the space of an isl_union_set only contains parameters, + * "type" is required to be equal to isl_dim_param. + */ +__isl_give isl_union_set *isl_union_set_project_out( + __isl_take isl_union_set *uset, + enum isl_dim_type type, unsigned first, unsigned n) +{ + return isl_union_map_project_out(uset, type, first, n); +} + +/* Project out all parameters from "uset" by existentially quantifying + * over them. + */ +__isl_give isl_union_set *isl_union_set_project_out_all_params( + __isl_take isl_union_set *uset) +{ + return uset_from_umap( + isl_union_map_project_out_all_params(uset_to_umap(uset))); +} + +/* Internal data structure for isl_union_map_involves_dims. + * "first" and "n" are the arguments for the isl_map_involves_dims calls. + */ +struct isl_union_map_involves_dims_data { + unsigned first; + unsigned n; +}; + +/* Does "map" _not_ involve the data->n parameters starting at data->first? + */ +static isl_bool map_excludes(__isl_keep isl_map *map, void *user) +{ + struct isl_union_map_involves_dims_data *data = user; + isl_bool involves; + + involves = isl_map_involves_dims(map, + isl_dim_param, data->first, data->n); + return isl_bool_not(involves); +} + +/* Does "umap" involve any of the n parameters starting at first? + * "type" is required to be set to isl_dim_param. + * + * "umap" involves any of those parameters if any of its maps + * involve the parameters. In other words, "umap" does not + * involve any of the parameters if all its maps to not + * involve the parameters. + */ +isl_bool isl_union_map_involves_dims(__isl_keep isl_union_map *umap, + enum isl_dim_type type, unsigned first, unsigned n) +{ + struct isl_union_map_involves_dims_data data = { first, n }; + isl_bool excludes; + + if (type != isl_dim_param) + isl_die(isl_union_map_get_ctx(umap), isl_error_invalid, + "can only reference parameters", return isl_bool_error); + + excludes = union_map_forall_user(umap, &map_excludes, &data); + + return isl_bool_not(excludes); +} + +/* Internal data structure for isl_union_map_reset_range_space. + * "range" is the space from which to set the range space. + * "res" collects the results. + */ +struct isl_union_map_reset_range_space_data { + isl_space *range; + isl_union_map *res; +}; + +/* Replace the range space of "map" by the range space of data->range and + * add the result to data->res. + */ +static isl_stat reset_range_space(__isl_take isl_map *map, void *user) +{ + struct isl_union_map_reset_range_space_data *data = user; + isl_space *space; + + space = isl_map_get_space(map); + space = isl_space_domain(space); + space = isl_space_extend_domain_with_range(space, + isl_space_copy(data->range)); + map = isl_map_reset_space(map, space); + data->res = isl_union_map_add_map(data->res, map); + + return data->res ? isl_stat_ok : isl_stat_error; +} + +/* Replace the range space of all the maps in "umap" by + * the range space of "space". + * + * This assumes that all maps have the same output dimension. + * This function should therefore not be made publicly available. + * + * Since the spaces of the maps change, so do their hash value. + * We therefore need to create a new isl_union_map. + */ +__isl_give isl_union_map *isl_union_map_reset_range_space( + __isl_take isl_union_map *umap, __isl_take isl_space *space) +{ + struct isl_union_map_reset_range_space_data data = { space }; + + data.res = isl_union_map_empty(isl_union_map_get_space(umap)); + if (isl_union_map_foreach_map(umap, &reset_range_space, &data) < 0) + data.res = isl_union_map_free(data.res); + + isl_space_free(space); + isl_union_map_free(umap); + return data.res; +} + +/* Check that "umap" and "space" have the same number of parameters. + */ +static isl_stat check_union_map_space_equal_dim(__isl_keep isl_union_map *umap, + __isl_keep isl_space *space) +{ + isl_size dim1, dim2; + + dim1 = isl_union_map_dim(umap, isl_dim_param); + dim2 = isl_space_dim(space, isl_dim_param); + if (dim1 < 0 || dim2 < 0) + return isl_stat_error; + if (dim1 == dim2) + return isl_stat_ok; + isl_die(isl_union_map_get_ctx(umap), isl_error_invalid, + "number of parameters does not match", return isl_stat_error); +} + +/* Internal data structure for isl_union_map_reset_equal_dim_space. + * "space" is the target space. + * "res" collects the results. + */ +struct isl_union_map_reset_params_data { + isl_space *space; + isl_union_map *res; +}; + +/* Replace the parameters of "map" by those of data->space and + * add the result to data->res. + */ +static isl_stat reset_params(__isl_take isl_map *map, void *user) +{ + struct isl_union_map_reset_params_data *data = user; + isl_space *space; + + space = isl_map_get_space(map); + space = isl_space_replace_params(space, data->space); + map = isl_map_reset_equal_dim_space(map, space); + data->res = isl_union_map_add_map(data->res, map); + + return data->res ? isl_stat_ok : isl_stat_error; +} + +/* Replace the space of "umap" by "space", without modifying + * the dimension of "umap", i.e., the number of parameters of "umap". + * + * Since the hash values of the maps in the union map depend + * on the parameters, a new union map needs to be constructed. + */ +__isl_give isl_union_map *isl_union_map_reset_equal_dim_space( + __isl_take isl_union_map *umap, __isl_take isl_space *space) +{ + struct isl_union_map_reset_params_data data = { space }; + isl_bool equal; + isl_space *umap_space; + + umap_space = isl_union_map_peek_space(umap); + equal = isl_space_is_equal(umap_space, space); + if (equal < 0) + goto error; + if (equal) { + isl_space_free(space); + return umap; + } + if (check_union_map_space_equal_dim(umap, space) < 0) + goto error; + + data.res = isl_union_map_empty(isl_space_copy(space)); + if (isl_union_map_foreach_map(umap, &reset_params, &data) < 0) + data.res = isl_union_map_free(data.res); + + isl_space_free(space); + isl_union_map_free(umap); + return data.res; +error: + isl_union_map_free(umap); + isl_space_free(space); + return NULL; +} + +/* Internal data structure for isl_union_map_order_at_multi_union_pw_aff. + * "mupa" is the function from which the isl_multi_pw_affs are extracted. + * "order" is applied to the extracted isl_multi_pw_affs that correspond + * to the domain and the range of each map. + * "res" collects the results. + */ +struct isl_union_order_at_data { + isl_multi_union_pw_aff *mupa; + __isl_give isl_map *(*order)(__isl_take isl_multi_pw_aff *mpa1, + __isl_take isl_multi_pw_aff *mpa2); + isl_union_map *res; +}; + +/* Intersect "map" with the result of applying data->order to + * the functions in data->mupa that apply to the domain and the range + * of "map" and add the result to data->res. + */ +static isl_stat order_at(__isl_take isl_map *map, void *user) +{ + struct isl_union_order_at_data *data = user; + isl_space *space; + isl_multi_pw_aff *mpa1, *mpa2; + isl_map *order; + + space = isl_space_domain(isl_map_get_space(map)); + mpa1 = isl_multi_union_pw_aff_extract_multi_pw_aff(data->mupa, space); + space = isl_space_range(isl_map_get_space(map)); + mpa2 = isl_multi_union_pw_aff_extract_multi_pw_aff(data->mupa, space); + order = data->order(mpa1, mpa2); + map = isl_map_intersect(map, order); + data->res = isl_union_map_add_map(data->res, map); + + return data->res ? isl_stat_ok : isl_stat_error; +} + +/* If "mupa" has a non-trivial explicit domain, then intersect + * domain and range of "umap" with this explicit domain. + * If the explicit domain only describes constraints on the parameters, + * then the intersection only needs to be performed once. + */ +static __isl_give isl_union_map *intersect_explicit_domain( + __isl_take isl_union_map *umap, __isl_keep isl_multi_union_pw_aff *mupa) +{ + isl_bool non_trivial, is_params; + isl_union_set *dom; + + non_trivial = isl_multi_union_pw_aff_has_non_trivial_domain(mupa); + if (non_trivial < 0) + return isl_union_map_free(umap); + if (!non_trivial) + return umap; + mupa = isl_multi_union_pw_aff_copy(mupa); + dom = isl_multi_union_pw_aff_domain(mupa); + is_params = isl_union_set_is_params(dom); + if (is_params < 0) { + isl_union_set_free(dom); + return isl_union_map_free(umap); + } + if (is_params) { + isl_set *set; + + set = isl_union_set_params(dom); + umap = isl_union_map_intersect_params(umap, set); + return umap; + } + umap = isl_union_map_intersect_domain(umap, isl_union_set_copy(dom)); + umap = isl_union_map_intersect_range(umap, dom); + return umap; +} + +/* Intersect each map in "umap" with the result of calling "order" + * on the functions is "mupa" that apply to the domain and the range + * of the map. + */ +static __isl_give isl_union_map *isl_union_map_order_at_multi_union_pw_aff( + __isl_take isl_union_map *umap, __isl_take isl_multi_union_pw_aff *mupa, + __isl_give isl_map *(*order)(__isl_take isl_multi_pw_aff *mpa1, + __isl_take isl_multi_pw_aff *mpa2)) +{ + struct isl_union_order_at_data data; + + umap = isl_union_map_align_params(umap, + isl_multi_union_pw_aff_get_space(mupa)); + mupa = isl_multi_union_pw_aff_align_params(mupa, + isl_union_map_get_space(umap)); + umap = intersect_explicit_domain(umap, mupa); + data.mupa = mupa; + data.order = order; + data.res = isl_union_map_empty(isl_union_map_get_space(umap)); + if (isl_union_map_foreach_map(umap, &order_at, &data) < 0) + data.res = isl_union_map_free(data.res); + + isl_multi_union_pw_aff_free(mupa); + isl_union_map_free(umap); + return data.res; +} + +/* Return the subset of "umap" where the domain and the range + * have equal "mupa" values. + */ +__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) +{ + return isl_union_map_order_at_multi_union_pw_aff(umap, mupa, + &isl_multi_pw_aff_eq_map); +} + +#undef ORDER +#define ORDER le +#include "isl_union_map_lex_templ.c" + +#undef ORDER +#define ORDER lt +#include "isl_union_map_lex_templ.c" + +#undef ORDER +#define ORDER ge +#include "isl_union_map_lex_templ.c" + +#undef ORDER +#define ORDER gt +#include "isl_union_map_lex_templ.c" + +/* Return the union of the elements in the list "list". + */ +__isl_give isl_union_set *isl_union_set_list_union( + __isl_take isl_union_set_list *list) +{ + int i; + isl_size n; + isl_ctx *ctx; + isl_space *space; + isl_union_set *res; + + n = isl_union_set_list_n_union_set(list); + if (n < 0) + goto error; + + ctx = isl_union_set_list_get_ctx(list); + space = isl_space_params_alloc(ctx, 0); + res = isl_union_set_empty(space); + + for (i = 0; i < n; ++i) { + isl_union_set *uset_i; + + uset_i = isl_union_set_list_get_union_set(list, i); + res = isl_union_set_union(res, uset_i); + } + + isl_union_set_list_free(list); + return res; +error: + isl_union_set_list_free(list); + return NULL; +} + +/* Update *hash with the hash value of "map". + */ +static isl_stat add_hash(__isl_take isl_map *map, void *user) +{ + uint32_t *hash = user; + uint32_t map_hash; + + map_hash = isl_map_get_hash(map); + isl_hash_hash(*hash, map_hash); + + isl_map_free(map); + return isl_stat_ok; +} + +/* Return a hash value that digests "umap". + */ +uint32_t isl_union_map_get_hash(__isl_keep isl_union_map *umap) +{ + uint32_t hash; + + if (!umap) + return 0; + + hash = isl_hash_init(); + if (isl_union_map_foreach_map(umap, &add_hash, &hash) < 0) + return 0; + + return hash; +} + +/* Return a hash value that digests "uset". + */ +uint32_t isl_union_set_get_hash(__isl_keep isl_union_set *uset) +{ + return isl_union_map_get_hash(uset); +} + +/* Add the number of basic sets in "set" to "n". + */ +static isl_stat add_n(__isl_take isl_set *set, void *user) +{ + int *n = user; + isl_size set_n; + + set_n = isl_set_n_basic_set(set); + *n += set_n; + isl_set_free(set); + + return set_n < 0 ? isl_stat_error : isl_stat_ok; +} + +/* Return the total number of basic sets in "uset". + */ +int isl_union_set_n_basic_set(__isl_keep isl_union_set *uset) +{ + int n = 0; + + if (isl_union_set_foreach_set(uset, &add_n, &n) < 0) + return -1; + + return n; +} + +/* Add the basic sets in "set" to "list". + */ +static isl_stat add_list(__isl_take isl_set *set, void *user) +{ + isl_basic_set_list **list = user; + isl_basic_set_list *list_i; + + list_i = isl_set_get_basic_set_list(set); + *list = isl_basic_set_list_concat(*list, list_i); + isl_set_free(set); + + if (!*list) + return isl_stat_error; + return isl_stat_ok; +} + +/* Return a list containing all the basic sets in "uset". + * + * First construct a list of the appropriate size and + * then add all the elements. + */ +__isl_give isl_basic_set_list *isl_union_set_get_basic_set_list( + __isl_keep isl_union_set *uset) +{ + int n; + isl_ctx *ctx; + isl_basic_set_list *list; + + if (!uset) + return NULL; + ctx = isl_union_set_get_ctx(uset); + n = isl_union_set_n_basic_set(uset); + if (n < 0) + return NULL; + list = isl_basic_set_list_alloc(ctx, n); + if (isl_union_set_foreach_set(uset, &add_list, &list) < 0) + list = isl_basic_set_list_free(list); + + return list; +} + +/* Internal data structure for isl_union_map_remove_map_if. + * "fn" and "user" are the arguments to isl_union_map_remove_map_if. + */ +struct isl_union_map_remove_map_if_data { + isl_bool (*fn)(__isl_keep isl_map *map, void *user); + void *user; +}; + +/* isl_un_op_control filter that negates the result of data->fn + * called on "map". + */ +static isl_bool not(__isl_keep isl_map *map, void *user) +{ + struct isl_union_map_remove_map_if_data *data = user; + + return isl_bool_not(data->fn(map, data->user)); +} + +/* Dummy isl_un_op_control transformation callback that + * simply returns the input. + */ +static __isl_give isl_map *map_id(__isl_take isl_map *map) +{ + return map; +} + +/* Call "fn" on every map in "umap" and remove those maps + * for which the callback returns true. + * + * Use un_op to keep only those maps that are not filtered out, + * applying an identity transformation on them. + */ +__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) +{ + struct isl_union_map_remove_map_if_data data = { fn, user }; + struct isl_un_op_control control = { + .filter = ¬, + .filter_user = &data, + .fn_map = &map_id, + }; + return un_op(umap, &control); +} + +/* Does "map" have "space" as domain (ignoring parameters)? + */ +static isl_bool has_domain_space_tuples(__isl_keep isl_map *map, void *user) +{ + isl_space *space = user; + + return isl_space_has_domain_tuples(space, isl_map_peek_space(map)); +} + +/* Does "map" have "space" as range (ignoring parameters)? + */ +static isl_bool has_range_space_tuples(__isl_keep isl_map *map, void *user) +{ + isl_space *space = user; + + return isl_space_has_range_tuples(space, isl_map_peek_space(map)); +} + +/* Wrapper around isl_map_bind_range for use as a un_op callback. + */ +static __isl_give isl_map *bind_range(__isl_take isl_map *map, void *user) +{ + isl_multi_id *tuple = user; + + return isl_map_bind_range(map, isl_multi_id_copy(tuple)); +} + +/* Bind the output dimensions of "umap" to parameters with identifiers + * specified by "tuple", living in the range space of "umap", + * for those maps that have a matching range space. + */ +__isl_give isl_union_set *isl_union_map_bind_range( + __isl_take isl_union_map *umap, __isl_take isl_multi_id *tuple) +{ + struct isl_un_op_control control = { + .filter = &has_range_space_tuples, + .filter_user = isl_multi_id_peek_space(tuple), + .fn_map2 = &bind_range, + .fn_map2_user = tuple, + }; + isl_union_set *bound; + + bound = uset_from_umap(un_op(umap, &control)); + isl_multi_id_free(tuple); + return bound; +} + +/* Only keep those elements in "umap" that have a domain in "space". + */ +__isl_give isl_union_map *isl_union_map_intersect_domain_space( + __isl_take isl_union_map *umap, __isl_take isl_space *space) +{ + struct isl_un_op_control control = { + .filter = &has_domain_space_tuples, + .filter_user = space, + }; + + umap = un_op(umap, &control); + isl_space_free(space); + return umap; +} + +/* Only keep those elements in "umap" that have a range in "space". + */ +__isl_give isl_union_map *isl_union_map_intersect_range_space( + __isl_take isl_union_map *umap, __isl_take isl_space *space) +{ + struct isl_un_op_control control = { + .filter = &has_range_space_tuples, + .filter_user = space, + }; + + umap = un_op(umap, &control); + isl_space_free(space); + return umap; +} diff --git a/external/mit/isl/dist/isl_union_map_lex_templ.c b/external/mit/isl/dist/isl_union_map_lex_templ.c new file mode 100644 index 000000000000..b9df71261d27 --- /dev/null +++ b/external/mit/isl/dist/isl_union_map_lex_templ.c @@ -0,0 +1,23 @@ +/* + * Copyright 2014 INRIA Rocquencourt + * + * Use of this software is governed by the MIT license + * + * Written by Sven Verdoolaege, + * Inria Paris - Rocquencourt, Domaine de Voluceau - Rocquencourt, + * B.P. 105 - 78153 Le Chesnay, France + */ + +#define xFN(TYPE,NAME) TYPE ## _ ## NAME +#define FN(TYPE,NAME) xFN(TYPE,NAME) + +/* Return the subset of "umap" where the domain and the range + * have "mupa" values that lexicographically compare as "ORDER". + */ +__isl_give isl_union_map *FN(FN(isl_union_map_lex,ORDER),at_multi_union_pw_aff)( + __isl_take isl_union_map *umap, + __isl_take isl_multi_union_pw_aff *mupa) +{ + return isl_union_map_order_at_multi_union_pw_aff(umap, mupa, + &FN(FN(isl_multi_pw_aff_lex,ORDER),map)); +} diff --git a/external/mit/isl/dist/isl_union_map_private.h b/external/mit/isl/dist/isl_union_map_private.h new file mode 100644 index 000000000000..c675da82fb53 --- /dev/null +++ b/external/mit/isl/dist/isl_union_map_private.h @@ -0,0 +1,28 @@ +#define isl_union_set_list isl_union_map_list +#define isl_union_set isl_union_map +#include +#include + +struct isl_union_map { + int ref; + isl_space *dim; + + struct isl_hash_table table; +}; + +struct isl_hash_table_entry *isl_union_set_find_entry( + __isl_keep isl_union_set *uset, __isl_keep isl_space *space, + int reserve); + +__isl_keep isl_space *isl_union_map_peek_space(__isl_keep isl_union_map *umap); +__isl_keep isl_space *isl_union_set_peek_space(__isl_keep isl_union_set *uset); +isl_bool isl_union_map_is_params(__isl_keep isl_union_map *umap); +isl_bool isl_union_map_space_has_equal_params(__isl_keep isl_union_map *umap, + __isl_keep isl_space *space); +isl_bool isl_union_set_space_has_equal_params(__isl_keep isl_union_set *uset, + __isl_keep isl_space *space); +isl_stat isl_union_map_check_named_params(__isl_keep isl_union_map *umap); +__isl_give isl_union_map *isl_union_map_reset_range_space( + __isl_take isl_union_map *umap, __isl_take isl_space *space); +__isl_give isl_union_map *isl_union_map_reset_equal_dim_space( + __isl_take isl_union_map *umap, __isl_take isl_space *space); diff --git a/external/mit/isl/dist/isl_union_multi.c b/external/mit/isl/dist/isl_union_multi.c new file mode 100644 index 000000000000..b630b18b89e0 --- /dev/null +++ b/external/mit/isl/dist/isl_union_multi.c @@ -0,0 +1,549 @@ +/* + * Copyright 2010 INRIA Saclay + * Copyright 2013 Ecole Normale Superieure + * Copyright 2015 INRIA Paris-Rocquencourt + * + * 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 + * and INRIA Paris-Rocquencourt, Domaine de Voluceau, Rocquenqourt, B.P. 105, + * 78153 Le Chesnay Cedex France + */ + +#include +#include + +/* A group of expressions defined over the same domain space "domain_space". + * The entries of "part_table" are the individual expressions, + * keyed on the entire space of the expression (ignoring parameters). + * + * Each UNION has its own groups, so there can only ever be a single + * reference to each group. + */ +S(UNION,group) { + isl_space *domain_space; + struct isl_hash_table part_table; +}; + +/* A union of expressions defined over different disjoint domains. + * "space" describes the parameters. + * The entries of "table" are keyed on the domain space of the entry + * (ignoring parameters) and + * contain groups of expressions that are defined over the same domain space. + */ +struct UNION { + int ref; + isl_space *space; + + struct isl_hash_table table; +}; + +/* Internal data structure for isl_union_*_foreach_group. + * "fn" is the function that needs to be called on each group. + */ +S(UNION,foreach_group_data) +{ + isl_stat (*fn)(__isl_keep S(UNION,group) *group, void *user); + void *user; +}; + +/* Call data->fn on the group stored at *entry. + */ +static isl_stat FN(UNION,call_on_group)(void **entry, void *user) +{ + S(UNION,group) *group = *entry; + S(UNION,foreach_group_data) *data; + + data = (S(UNION,foreach_group_data) *) user; + return data->fn(group, data->user); +} + +/* Call "fn" on each group of expressions in "u". + */ +static isl_stat FN(UNION,foreach_group)(__isl_keep UNION *u, + isl_stat (*fn)(__isl_keep S(UNION,group) *group, void *user), + void *user) +{ + S(UNION,foreach_group_data) data = { fn, user }; + + if (!u) + return isl_stat_error; + + return isl_hash_table_foreach(u->space->ctx, &u->table, + &FN(UNION,call_on_group), &data); +} + +/* A isl_union_*_foreach_group callback for counting the total number + * of expressions in a UNION. Add the number of expressions in "group" + * to *n. + */ +static isl_stat FN(UNION,count_part)(__isl_keep S(UNION,group) *group, + void *user) +{ + int *n = user; + + if (!group) + return isl_stat_error; + + *n += group->part_table.n; + return isl_stat_ok; +} + +/* Return the number of base expressions in "u". + */ +isl_size FN(FN(UNION,n),BASE)(__isl_keep UNION *u) +{ + int n; + + n = 0; + if (FN(UNION,foreach_group)(u, &FN(UNION,count_part), &n) < 0) + return isl_size_error; + return n; +} + +/* Free an entry in a group of expressions. + * Each entry in such a group is a single expression. + */ +static isl_stat FN(UNION,free_group_entry)(void **entry, void *user) +{ + PART *part = *entry; + + FN(PART,free)(part); + return isl_stat_ok; +} + +/* Free all memory allocated for "group" and return NULL. + */ +static __isl_null S(UNION,group) *FN(UNION,group_free)( + __isl_take S(UNION,group) *group) +{ + isl_ctx *ctx; + + if (!group) + return NULL; + + ctx = isl_space_get_ctx(group->domain_space); + isl_hash_table_foreach(ctx, &group->part_table, + &FN(UNION,free_group_entry), NULL); + isl_hash_table_clear(&group->part_table); + isl_space_free(group->domain_space); + free(group); + return NULL; +} + +/* Allocate a group of expressions defined over the same domain space + * with domain space "domain_space" and initial size "size". + */ +static __isl_give S(UNION,group) *FN(UNION,group_alloc)( + __isl_take isl_space *domain_space, int size) +{ + isl_ctx *ctx; + S(UNION,group) *group; + + if (!domain_space) + return NULL; + ctx = isl_space_get_ctx(domain_space); + group = isl_calloc_type(ctx, S(UNION,group)); + if (!group) + goto error; + group->domain_space = domain_space; + if (isl_hash_table_init(ctx, &group->part_table, size) < 0) + return FN(UNION,group_free)(group); + + return group; +error: + isl_space_free(domain_space); + return NULL; +} + +/* Is the space of "entry" equal to "space", ignoring parameters? + */ +static isl_bool FN(UNION,has_space_tuples)(const void *entry, const void *val) +{ + PART *part = (PART *) entry; + isl_space *space = (isl_space *) val; + isl_space *part_space; + + part_space = FN(PART,peek_space)(part); + return isl_space_has_equal_tuples(part_space, space); +} + +/* Return a group equal to "group", but with a single reference. + * Since all groups have only a single reference, simply return "group". + */ +static __isl_give S(UNION,group) *FN(UNION,group_cow)( + __isl_take S(UNION,group) *group) +{ + return group; +} + +S(UNION,foreach_data) +{ + isl_stat (*fn)(__isl_take PART *part, void *user); + void *user; +}; + +static isl_stat FN(UNION,call_on_copy)(void **entry, void *user) +{ + PART *part = *entry; + S(UNION,foreach_data) *data = (S(UNION,foreach_data) *) user; + + part = FN(PART,copy)(part); + if (!part) + return isl_stat_error; + return data->fn(part, data->user); +} + +/* Call data->fn on a copy of each expression in "group". + */ +static isl_stat FN(UNION,group_call_on_copy)(__isl_keep S(UNION,group) *group, + void *user) +{ + isl_ctx *ctx; + + if (!group) + return isl_stat_error; + + ctx = isl_space_get_ctx(group->domain_space); + return isl_hash_table_foreach(ctx, &group->part_table, + &FN(UNION,call_on_copy), user); +} + +isl_stat FN(FN(UNION,foreach),BASE)(__isl_keep UNION *u, + isl_stat (*fn)(__isl_take PART *part, void *user), void *user) +{ + S(UNION,foreach_data) data = { fn, user }; + + if (!u) + return isl_stat_error; + + return FN(UNION,foreach_group)(u, &FN(UNION,group_call_on_copy), &data); +} + +/* Is the domain space of the group of expressions at "entry" + * equal to that of "space", ignoring parameters? + */ +static isl_bool FN(UNION,group_has_same_domain_space_tuples)(const void *entry, + const void *val) +{ + S(UNION,group) *group = (S(UNION,group) *) entry; + isl_space *space = (isl_space *) val; + + return isl_space_has_domain_tuples(group->domain_space, space); +} + +/* Return the entry, if any, in "u" that lives in "space". + * If "reserve" is set, then an entry is created if it does not exist yet. + * Return NULL on error and isl_hash_table_entry_none if no entry was found. + * Note that when "reserve" is set, the function will never return + * isl_hash_table_entry_none. + * + * First look for the group of expressions with the same domain space, + * creating one if needed. + * Then look for the expression living in the specified space in that group. + */ +static struct isl_hash_table_entry *FN(UNION,find_part_entry)( + __isl_keep UNION *u, __isl_keep isl_space *space, int reserve) +{ + isl_ctx *ctx; + uint32_t hash; + struct isl_hash_table_entry *group_entry; + S(UNION,group) *group; + + if (!u || !space) + return NULL; + + ctx = FN(UNION,get_ctx)(u); + hash = isl_space_get_tuple_domain_hash(space); + group_entry = isl_hash_table_find(ctx, &u->table, hash, + &FN(UNION,group_has_same_domain_space_tuples), space, reserve); + if (!group_entry || group_entry == isl_hash_table_entry_none) + return group_entry; + if (reserve && !group_entry->data) { + isl_space *domain = isl_space_domain(isl_space_copy(space)); + group = FN(UNION,group_alloc)(domain, 1); + group_entry->data = group; + } else { + group = group_entry->data; + if (reserve) + group = FN(UNION,group_cow)(group); + } + if (!group) + return NULL; + hash = isl_space_get_tuple_hash(space); + return isl_hash_table_find(ctx, &group->part_table, hash, + &FN(UNION,has_space_tuples), space, reserve); +} + +/* Remove "part_entry" from the hash table of "u". + * + * First look the group_entry in "u" holding the group that + * contains "part_entry". Remove "part_entry" from that group. + * If the group becomes empty, then also remove the group_entry from "u". + */ +static __isl_give UNION *FN(UNION,remove_part_entry)(__isl_take UNION *u, + struct isl_hash_table_entry *part_entry) +{ + isl_ctx *ctx; + uint32_t hash; + isl_space *space; + PART *part; + struct isl_hash_table_entry *group_entry; + S(UNION,group) *group; + + if (!u || !part_entry) + return FN(UNION,free)(u); + + part = part_entry->data; + ctx = FN(UNION,get_ctx)(u); + space = FN(PART,peek_space)(part); + hash = isl_space_get_tuple_domain_hash(space); + group_entry = isl_hash_table_find(ctx, &u->table, hash, + &FN(UNION,group_has_same_domain_space_tuples), space, 0); + if (!group_entry) + return FN(UNION,free)(u); + if (group_entry == isl_hash_table_entry_none) + isl_die(ctx, isl_error_internal, "missing group", + return FN(UNION,free)(u)); + group = group_entry->data; + isl_hash_table_remove(ctx, &group->part_table, part_entry); + FN(PART,free)(part); + + if (group->part_table.n != 0) + return u; + + isl_hash_table_remove(ctx, &u->table, group_entry); + FN(UNION,group_free)(group); + + return u; +} + +/* Are the domains of "part1" and "part2" disjoint? + */ +static isl_bool FN(UNION,disjoint_domain)(__isl_keep PART *part1, + __isl_keep PART *part2) +{ + isl_set *dom1, *dom2; + isl_bool disjoint; + + if (!part1 || !part2) + return isl_bool_error; + dom1 = FN(PART,domain)(FN(PART,copy)(part1)); + dom2 = FN(PART,domain)(FN(PART,copy)(part2)); + disjoint = isl_set_is_disjoint(dom1, dom2); + isl_set_free(dom1); + isl_set_free(dom2); + + return disjoint; +} + +/* Check that the expression at *entry has a domain that is disjoint + * from that of "part", unless they also have the same target space. + */ +static isl_stat FN(UNION,check_disjoint_domain_entry)(void **entry, void *user) +{ + PART *part = user; + PART *other = *entry; + isl_bool equal; + isl_bool disjoint; + + equal = isl_space_is_equal(part->dim, other->dim); + if (equal < 0) + return isl_stat_error; + if (equal) + return isl_stat_ok; + + disjoint = FN(UNION,disjoint_domain)(part, other); + if (disjoint < 0) + return isl_stat_error; + if (!disjoint) + isl_die(FN(PART,get_ctx)(part), isl_error_invalid, + "overlapping domain with other part", + return isl_stat_error); + return isl_stat_ok; +} + +/* Check that the domain of "part" is disjoint from the domain of the entries + * in "u" that are defined on the same domain space, but have a different + * target space. + * If there is no group of expressions in "u" with the same domain space, + * then everything is fine. Otherwise, check the individual expressions + * in that group. + */ +static isl_stat FN(UNION,check_disjoint_domain_other)(__isl_keep UNION *u, + __isl_keep PART *part) +{ + isl_ctx *ctx; + uint32_t hash; + isl_space *space; + struct isl_hash_table_entry *group_entry; + S(UNION,group) *group; + + if (!u || !part) + return isl_stat_error; + ctx = FN(UNION,get_ctx)(u); + space = FN(PART,peek_space)(part); + hash = isl_space_get_tuple_domain_hash(space); + group_entry = isl_hash_table_find(ctx, &u->table, hash, + &FN(UNION,group_has_same_domain_space_tuples), space, 0); + if (!group_entry) + return isl_stat_error; + if (group_entry == isl_hash_table_entry_none) + return isl_stat_ok; + group = group_entry->data; + return isl_hash_table_foreach(ctx, &group->part_table, + &FN(UNION,check_disjoint_domain_entry), part); +} + +/* Check that the domain of "part1" is disjoint from the domain of "part2". + * This check is performed before "part2" is added to a UNION to ensure + * that the UNION expression remains a function. + */ +static isl_stat FN(UNION,check_disjoint_domain)(__isl_keep PART *part1, + __isl_keep PART *part2) +{ + isl_bool disjoint; + + disjoint = FN(UNION,disjoint_domain)(part1, part2); + if (disjoint < 0) + return isl_stat_error; + if (!disjoint) + isl_die(FN(PART,get_ctx)(part1), isl_error_invalid, + "domain of additional part should be disjoint", + return isl_stat_error); + return isl_stat_ok; +} + +/* Internal data structure for isl_union_*_foreach_inplace. + * "fn" is the function that needs to be called on each entry. + */ +S(UNION,foreach_inplace_data) +{ + isl_stat (*fn)(void **entry, void *user); + void *user; +}; + +/* isl_union_*_foreach_group callback for calling data->fn on + * each part entry in the group. + */ +static isl_stat FN(UNION,group_call_inplace)(__isl_keep S(UNION,group) *group, + void *user) +{ + isl_ctx *ctx; + S(UNION,foreach_inplace_data) *data; + + if (!group) + return isl_stat_error; + + data = (S(UNION,foreach_inplace_data) *) user; + ctx = isl_space_get_ctx(group->domain_space); + return isl_hash_table_foreach(ctx, &group->part_table, + data->fn, data->user); +} + +/* Call "fn" on each part entry of "u". + */ +static isl_stat FN(UNION,foreach_inplace)(__isl_keep UNION *u, + isl_stat (*fn)(void **part, void *user), void *user) +{ + S(UNION,foreach_inplace_data) data = { fn, user }; + + return FN(UNION,foreach_group)(u, &FN(UNION,group_call_inplace), &data); +} + +static isl_stat FN(UNION,free_u_entry)(void **entry, void *user) +{ + S(UNION,group) *group = *entry; + FN(UNION,group_free)(group); + return isl_stat_ok; +} + +/* Does "u" have an obviously empty definition domain? + */ +isl_bool FN(UNION,plain_is_empty)(__isl_take UNION *u) +{ + if (!u) + return isl_bool_error; + return isl_bool_ok(u->table.n == 0); +} + +/* Set "single" to true if this group of expressions + * contains an expression living in exactly one space. + */ +static isl_stat FN(UNION,group_single_space)(__isl_keep S(UNION,group) *group, + void *user) +{ + isl_bool *single = user; + + if (!group) + return isl_stat_error; + *single = isl_bool_ok(group->part_table.n == 1); + return isl_stat_ok; +} + +/* Can this union expression be converted to a single base expression? + * That is, does it contain a base expression in exactly one space? + * In particular, is only one domain space involved and + * is only a single expression associated to that domain? + */ +isl_bool FN(FN(UNION,isa),BASE)(__isl_take UNION *u) +{ + isl_bool single; + + if (!u) + return isl_bool_error; + if (u->table.n != 1) + return isl_bool_false; + if (FN(UNION,foreach_group)(u, + &FN(UNION,group_single_space), &single) < 0) + return isl_bool_error; + return single; +} + +/* Callback for isl_union_*_foreach_inplace call + * on a union expression with a single base expression. + * Store that base expression in "user". + * This callback should only be called once + * for any given isl_union_*_foreach_inplace call. + */ +static isl_stat FN(UNION,extract_part)(void **entry, void *user) +{ + PART **part_p = user; + PART *part = *entry; + + if (*part_p) + isl_die(FN(PART,get_ctx)(part), isl_error_internal, + "more than one part", return isl_stat_error); + *part_p = FN(PART,copy)(part); + if (!*part_p) + return isl_stat_error; + return isl_stat_ok; +} + +/* Convert the union expression to its single base expression. + */ +__isl_give PART *FN(FN(UNION,as),BASE)(__isl_take UNION *u) +{ + isl_bool has_single_space; + PART *part = NULL; + + has_single_space = FN(FN(UNION,isa),BASE)(u); + if (has_single_space < 0) + goto error; + if (!has_single_space) + isl_die(FN(UNION,get_ctx)(u), isl_error_invalid, + "expecting elements in exactly one space", + goto error); + if (FN(UNION,foreach_inplace)(u, &FN(UNION,extract_part), &part) < 0) + part = FN(PART,free)(part); + FN(UNION,free)(u); + return part; +error: + FN(UNION,free)(u); + return NULL; +} + +#include diff --git a/external/mit/isl/dist/isl_union_neg.c b/external/mit/isl/dist/isl_union_neg.c new file mode 100644 index 000000000000..386b8dcd8014 --- /dev/null +++ b/external/mit/isl/dist/isl_union_neg.c @@ -0,0 +1,25 @@ +/* + * Copyright 2010 INRIA Saclay + * + * 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 + */ + +#include + +/* Return the opposite of "part". + */ +static __isl_give PART *FN(UNION,neg_entry)(__isl_take PART *part, void *user) +{ + return FN(PART,neg)(part); +} + +/* Return the opposite of "u". + */ +__isl_give UNION *FN(UNION,neg)(__isl_take UNION *u) +{ + return FN(UNION,transform_inplace)(u, &FN(UNION,neg_entry), NULL); +} diff --git a/external/mit/isl/dist/isl_union_print_templ.c b/external/mit/isl/dist/isl_union_print_templ.c new file mode 100644 index 000000000000..3995a129193a --- /dev/null +++ b/external/mit/isl/dist/isl_union_print_templ.c @@ -0,0 +1,69 @@ +/* + * Copyright 2010 INRIA Saclay + * + * 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 + */ + +#include "isl_union_macro.h" + +/* Print "pw" in a sequence of "PART" objects delimited by semicolons. + * Each "PART" object itself is also printed as a semicolon delimited + * sequence of pieces. + * If data->first = 1, then this is the first in the sequence. + * Update data->first to tell the next element that it is not the first. + */ +static isl_stat FN(print_body_wrap,BASE)(__isl_take PART *pw, + void *user) +{ + struct isl_union_print_data *data; + data = (struct isl_union_print_data *) user; + + if (!data->first) + data->p = isl_printer_print_str(data->p, "; "); + data->first = 0; + + data->p = FN(print_body,BASE)(data->p, pw); + FN(PART,free)(pw); + + return isl_stat_non_null(data->p); +} + +/* Print the body of "u" (everything except the parameter declarations) + * to "p" in isl format. + */ +static __isl_give isl_printer *FN(print_body_union,BASE)( + __isl_take isl_printer *p, __isl_keep UNION *u) +{ + struct isl_union_print_data data; + + p = isl_printer_print_str(p, s_open_set[0]); + data.p = p; + data.first = 1; + if (FN(FN(UNION,foreach),BASE)(u, &FN(print_body_wrap,BASE), &data) < 0) + data.p = isl_printer_free(data.p); + p = data.p; + p = isl_printer_print_str(p, s_close_set[0]); + + return p; +} + +/* Print the "UNION" object "u" to "p" in isl format. + */ +static __isl_give isl_printer *FN(FN(print_union,BASE),isl)( + __isl_take isl_printer *p, __isl_keep UNION *u) +{ + struct isl_print_space_data space_data = { 0 }; + isl_space *space; + + space = FN(UNION,get_space)(u); + p = print_param_tuple(p, space, &space_data); + isl_space_free(space); + + p = FN(print_body_union,BASE)(p, u); + + return p; +} diff --git a/external/mit/isl/dist/isl_union_pw_templ.c b/external/mit/isl/dist/isl_union_pw_templ.c new file mode 100644 index 000000000000..e226ad72dfd9 --- /dev/null +++ b/external/mit/isl/dist/isl_union_pw_templ.c @@ -0,0 +1,22 @@ +#define xCAT(A,B) A ## B +#define CAT(A,B) xCAT(A,B) +#undef EL +#define EL CAT(isl_,BASE) +#undef PW_BASE +#define PW_BASE CAT(pw_,BASE) +#undef PW +#define PW CAT(isl_,PW_BASE) +#undef UNION_BASE +#define UNION_BASE CAT(union_,PW_BASE) +#undef UNION +#define UNION CAT(isl_,UNION_BASE) +#define xFN(TYPE,NAME) TYPE ## _ ## NAME +#define FN(TYPE,NAME) xFN(TYPE,NAME) + +/* Create a union piecewise expression + * with the given base expression on a universe domain. + */ +__isl_give UNION *FN(FN(UNION,from),BASE)(__isl_take EL *el) +{ + return FN(FN(UNION,from),PW_BASE)(FN(FN(PW,from),BASE)(el)); +} diff --git a/external/mit/isl/dist/isl_union_set_private.h b/external/mit/isl/dist/isl_union_set_private.h new file mode 100644 index 000000000000..32a70732ae7c --- /dev/null +++ b/external/mit/isl/dist/isl_union_set_private.h @@ -0,0 +1,11 @@ +#ifndef ISL_UNION_SET_PRIVATE_H +#define ISL_UNION_SET_PRIVATE_H + +#include + +__isl_give isl_union_set *isl_union_set_combined_lineality_space( + __isl_take isl_union_set *uset); +__isl_give isl_union_set *isl_union_set_plain_gist( + __isl_take isl_union_set *uset, __isl_take isl_union_set *context); + +#endif diff --git a/external/mit/isl/dist/isl_union_single.c b/external/mit/isl/dist/isl_union_single.c new file mode 100644 index 000000000000..cf563422ccf4 --- /dev/null +++ b/external/mit/isl/dist/isl_union_single.c @@ -0,0 +1,231 @@ +/* + * Copyright 2010 INRIA Saclay + * Copyright 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 +#include + +/* A union of expressions defined over different domain spaces. + * "space" describes the parameters. + * The entries of "table" are keyed on the domain space of the entry + * (ignoring parameters). + */ +struct UNION { + int ref; +#ifdef HAS_TYPE + enum isl_fold type; +#endif + isl_space *space; + + struct isl_hash_table table; +}; + +/* Return the number of base expressions in "u". + */ +isl_size FN(FN(UNION,n),BASE)(__isl_keep UNION *u) +{ + return u ? u->table.n : isl_size_error; +} + +S(UNION,foreach_data) +{ + isl_stat (*fn)(__isl_take PART *part, void *user); + void *user; +}; + +static isl_stat FN(UNION,call_on_copy)(void **entry, void *user) +{ + PART *part = *entry; + S(UNION,foreach_data) *data = (S(UNION,foreach_data) *)user; + + part = FN(PART,copy)(part); + if (!part) + return isl_stat_error; + return data->fn(part, data->user); +} + +isl_stat FN(FN(UNION,foreach),BASE)(__isl_keep UNION *u, + isl_stat (*fn)(__isl_take PART *part, void *user), void *user) +{ + S(UNION,foreach_data) data = { fn, user }; + + if (!u) + return isl_stat_error; + + return isl_hash_table_foreach(u->space->ctx, &u->table, + &FN(UNION,call_on_copy), &data); +} + +/* Is the domain space of "entry" equal to the domain of "space", + * ignoring parameters? + */ +static isl_bool FN(UNION,has_same_domain_space_tuples)(const void *entry, + const void *val) +{ + PART *part = (PART *)entry; + isl_space *space = (isl_space *) val; + + if (isl_space_is_set(space)) + return isl_space_is_set(part->dim); + + return isl_space_tuple_is_equal(part->dim, isl_dim_in, + space, isl_dim_in); +} + +/* Return the entry, if any, in "u" that lives in "space". + * If "reserve" is set, then an entry is created if it does not exist yet. + * Return NULL on error and isl_hash_table_entry_none if no entry was found. + * Note that when "reserve" is set, the function will never return + * isl_hash_table_entry_none. + * + * First look for the entry (if any) with the same domain space. + * If it exists, then check if the range space also matches. + */ +static struct isl_hash_table_entry *FN(UNION,find_part_entry)( + __isl_keep UNION *u, __isl_keep isl_space *space, int reserve) +{ + isl_ctx *ctx; + uint32_t hash; + struct isl_hash_table_entry *entry; + isl_bool equal; + PART *part; + + if (!u || !space) + return NULL; + + ctx = FN(UNION,get_ctx)(u); + hash = isl_space_get_tuple_domain_hash(space); + entry = isl_hash_table_find(ctx, &u->table, hash, + &FN(UNION,has_same_domain_space_tuples), space, reserve); + if (!entry || entry == isl_hash_table_entry_none) + return entry; + if (reserve && !entry->data) + return entry; + part = entry->data; + equal = isl_space_tuple_is_equal(part->dim, isl_dim_out, + space, isl_dim_out); + if (equal < 0) + return NULL; + if (equal) + return entry; + if (!reserve) + return isl_hash_table_entry_none; + isl_die(FN(UNION,get_ctx)(u), isl_error_invalid, + "union expression can only contain a single " + "expression over a given domain", return NULL); +} + +/* Remove "part_entry" from the hash table of "u". + */ +static __isl_give UNION *FN(UNION,remove_part_entry)(__isl_take UNION *u, + struct isl_hash_table_entry *part_entry) +{ + isl_ctx *ctx; + + if (!u || !part_entry) + return FN(UNION,free)(u); + + FN(PART,free)(part_entry->data); + ctx = FN(UNION,get_ctx)(u); + isl_hash_table_remove(ctx, &u->table, part_entry); + + return u; +} + +/* Check that the domain of "part" is disjoint from the domain of the entries + * in "u" that are defined on the same domain space, but have a different + * target space. + * Since a UNION with a single entry per domain space is not allowed + * to contain two entries with the same domain space, there cannot be + * any such other entry. + */ +static isl_stat FN(UNION,check_disjoint_domain_other)(__isl_keep UNION *u, + __isl_keep PART *part) +{ + return isl_stat_ok; +} + +/* Check that the domain of "part1" is disjoint from the domain of "part2". + * This check is performed before "part2" is added to a UNION to ensure + * that the UNION expression remains a function. + * Since a UNION with a single entry per domain space is not allowed + * to contain two entries with the same domain space, fail unconditionally. + */ +static isl_stat FN(UNION,check_disjoint_domain)(__isl_keep PART *part1, + __isl_keep PART *part2) +{ + isl_die(FN(PART,get_ctx)(part1), isl_error_invalid, + "additional part should live on separate space", + return isl_stat_error); +} + +/* Call "fn" on each part entry of "u". + */ +static isl_stat FN(UNION,foreach_inplace)(__isl_keep UNION *u, + isl_stat (*fn)(void **part, void *user), void *user) +{ + isl_ctx *ctx; + + if (!u) + return isl_stat_error; + ctx = FN(UNION,get_ctx)(u); + return isl_hash_table_foreach(ctx, &u->table, fn, user); +} + +static isl_bool FN(PART,has_domain_space_tuples)(__isl_keep PART *part, + __isl_keep isl_space *space); + +/* Do the tuples of "space" correspond to those of the domain of "part"? + * That is, is the domain space of "part" equal to "space", ignoring parameters? + */ +static isl_bool FN(UNION,has_domain_space_tuples)(const void *entry, + const void *val) +{ + PART *part = (PART *)entry; + isl_space *space = (isl_space *) val; + + return FN(PART,has_domain_space_tuples)(part, space); +} + +/* Call "fn" on each part of "u" that has domain space "space". + * + * Since each entry is defined over a different domain space, + * simply look for an entry with the given domain space and + * call "fn" on the corresponding part if there is one. + */ +isl_stat FN(UNION,foreach_on_domain)(__isl_keep UNION *u, + __isl_keep isl_space *space, + isl_stat (*fn)(__isl_take PART *part, void *user), void *user) +{ + uint32_t hash; + struct isl_hash_table_entry *entry; + + if (!u || !space) + return isl_stat_error; + hash = isl_space_get_tuple_hash(space); + entry = isl_hash_table_find(FN(UNION,get_ctx)(u), &u->table, + hash, &FN(UNION,has_domain_space_tuples), + space, 0); + if (!entry) + return isl_stat_error; + if (entry == isl_hash_table_entry_none) + return isl_stat_ok; + return fn(FN(PART,copy)(entry->data), user); +} + +static isl_stat FN(UNION,free_u_entry)(void **entry, void *user) +{ + PART *part = *entry; + FN(PART,free)(part); + return isl_stat_ok; +} + +#include diff --git a/external/mit/isl/dist/isl_union_sub_templ.c b/external/mit/isl/dist/isl_union_sub_templ.c new file mode 100644 index 000000000000..0def7168a236 --- /dev/null +++ b/external/mit/isl/dist/isl_union_sub_templ.c @@ -0,0 +1,27 @@ +/* + * Copyright 2010 INRIA Saclay + * + * 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 + */ + +#include "isl_union_macro.h" + +/* Subtract "u2" from "u1" and return the result. + * + * If the base expressions have a default zero value, then + * reuse isl_union_*_add to ensure the result + * is computed on the union of the domains of "u1" and "u2". + * Otherwise, compute the result directly on their shared domain. + */ +__isl_give UNION *FN(UNION,sub)(__isl_take UNION *u1, __isl_take UNION *u2) +{ +#if DEFAULT_IS_ZERO + return FN(UNION,add)(u1, FN(UNION,neg)(u2)); +#else + return FN(UNION,match_bin_op)(u1, u2, &FN(PART,sub)); +#endif +} diff --git a/external/mit/isl/dist/isl_union_templ.c b/external/mit/isl/dist/isl_union_templ.c new file mode 100644 index 000000000000..07638f375e11 --- /dev/null +++ b/external/mit/isl/dist/isl_union_templ.c @@ -0,0 +1,1464 @@ +/* + * Copyright 2010 INRIA Saclay + * Copyright 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 + */ + +#undef TYPE +#define TYPE UNION +static +#include "has_single_reference_templ.c" + +__isl_give UNION *FN(UNION,cow)(__isl_take UNION *u); + +isl_ctx *FN(UNION,get_ctx)(__isl_keep UNION *u) +{ + return u ? u->space->ctx : NULL; +} + +/* Return the space of "u". + */ +static __isl_keep isl_space *FN(UNION,peek_space)(__isl_keep UNION *u) +{ + if (!u) + return NULL; + return u->space; +} + +/* Return a copy of the space of "u". + */ +__isl_give isl_space *FN(UNION,get_space)(__isl_keep UNION *u) +{ + return isl_space_copy(FN(UNION,peek_space)(u)); +} + +/* Return the number of parameters of "u", where "type" + * is required to be set to isl_dim_param. + */ +isl_size FN(UNION,dim)(__isl_keep UNION *u, enum isl_dim_type type) +{ + if (!u) + return isl_size_error; + + if (type != isl_dim_param) + isl_die(FN(UNION,get_ctx)(u), isl_error_invalid, + "can only reference parameters", return isl_size_error); + + return isl_space_dim(u->space, type); +} + +/* Return the position of the parameter with the given name + * in "u". + * Return -1 if no such dimension can be found. + */ +int FN(UNION,find_dim_by_name)(__isl_keep UNION *u, enum isl_dim_type type, + const char *name) +{ + if (!u) + return -1; + return isl_space_find_dim_by_name(u->space, type, name); +} + +#include "opt_type.h" + +static __isl_give UNION *FN(UNION,alloc)(__isl_take isl_space *space + OPT_TYPE_PARAM, int size) +{ + UNION *u; + + space = isl_space_params(space); + if (!space) + return NULL; + + u = isl_calloc_type(space->ctx, UNION); + if (!u) + goto error; + + u->ref = 1; + OPT_SET_TYPE(u->, type); + u->space = space; + if (isl_hash_table_init(space->ctx, &u->table, size) < 0) + return FN(UNION,free)(u); + + return u; +error: + isl_space_free(space); + return NULL; +} + +/* Create an empty/zero union without specifying any parameters. + */ +__isl_give UNION *FN(FN(UNION,ZERO),ctx)(isl_ctx *ctx OPT_TYPE_PARAM) +{ + isl_space *space; + + space = isl_space_unit(ctx); + return FN(FN(UNION,ZERO),space)(space OPT_TYPE_ARG(NO_LOC)); +} + +__isl_give UNION *FN(FN(UNION,ZERO),space)(__isl_take isl_space *space + OPT_TYPE_PARAM) +{ + return FN(UNION,alloc)(space OPT_TYPE_ARG(NO_LOC), 16); +} + +/* This is an alternative name for the function above. + */ +__isl_give UNION *FN(UNION,ZERO)(__isl_take isl_space *space OPT_TYPE_PARAM) +{ + return FN(FN(UNION,ZERO),space)(space OPT_TYPE_ARG(NO_LOC)); +} + +__isl_give UNION *FN(UNION,copy)(__isl_keep UNION *u) +{ + if (!u) + return NULL; + + u->ref++; + return u; +} + +/* Do the tuples of "space" correspond to those of the domain of "part"? + * That is, is the domain space of "part" equal to "space", ignoring parameters? + */ +static isl_bool FN(PART,has_domain_space_tuples)(__isl_keep PART *part, + __isl_keep isl_space *space) +{ + return isl_space_has_domain_tuples(space, FN(PART,peek_space)(part)); +} + +/* Extract the element of "u" living in "space" (ignoring parameters). + * + * Return the ZERO element if "u" does not contain any element + * living in "space". + */ +__isl_give PART *FN(FN(UNION,extract),BASE)(__isl_keep UNION *u, + __isl_take isl_space *space) +{ + struct isl_hash_table_entry *entry; + + entry = FN(UNION,find_part_entry)(u, space, 0); + if (!entry) + goto error; + if (entry == isl_hash_table_entry_none) + return FN(PART,ZERO)(space OPT_TYPE_ARG(u->)); + isl_space_free(space); + return FN(PART,copy)(entry->data); +error: + isl_space_free(space); + return NULL; +} + +/* Add "part" to "u". + * If "disjoint" is set, then "u" is not allowed to already have + * a part that is defined over a domain that overlaps with the domain + * of "part". + * Otherwise, compute the union sum of "part" and the part in "u" + * defined on the same space. + */ +static __isl_give UNION *FN(UNION,add_part_generic)(__isl_take UNION *u, + __isl_take PART *part, int disjoint) +{ + int empty; + struct isl_hash_table_entry *entry; + + if (!part) + goto error; + + empty = FN(PART,IS_ZERO)(part); + if (empty < 0) + goto error; + if (empty) { + FN(PART,free)(part); + return u; + } + + u = FN(UNION,align_params)(u, FN(PART,get_space)(part)); + part = FN(PART,align_params)(part, FN(UNION,get_space)(u)); + + u = FN(UNION,cow)(u); + + if (!u) + goto error; + + if (FN(UNION,check_disjoint_domain_other)(u, part) < 0) + goto error; + entry = FN(UNION,find_part_entry)(u, part->dim, 1); + if (!entry) + goto error; + + if (!entry->data) + entry->data = part; + else { + if (disjoint && + FN(UNION,check_disjoint_domain)(entry->data, part) < 0) + goto error; + entry->data = FN(PART,union_add_)(entry->data, + FN(PART,copy)(part)); + empty = FN(PART,IS_ZERO)(entry->data); + if (empty < 0) + goto error; + if (empty) + u = FN(UNION,remove_part_entry)(u, entry); + FN(PART,free)(part); + } + + return u; +error: + FN(PART,free)(part); + FN(UNION,free)(u); + return NULL; +} + +/* Add "part" to "u", where "u" is assumed not to already have + * a part that is defined on the same space as "part". + */ +__isl_give UNION *FN(FN(UNION,add),BASE)(__isl_take UNION *u, + __isl_take PART *part) +{ + return FN(UNION,add_part_generic)(u, part, 1); +} + +/* Allocate a UNION with the same type (if any) and the same size as "u" and + * with space "space". + */ +static __isl_give UNION *FN(UNION,alloc_same_size_on_space)(__isl_keep UNION *u, + __isl_take isl_space *space) +{ + if (!u) + goto error; + return FN(UNION,alloc)(space OPT_TYPE_ARG(u->), u->table.n); +error: + isl_space_free(space); + return NULL; +} + +/* Allocate a UNION with the same space, the same type (if any) and + * the same size as "u". + */ +static __isl_give UNION *FN(UNION,alloc_same_size)(__isl_keep UNION *u) +{ + return FN(UNION,alloc_same_size_on_space)(u, FN(UNION,get_space)(u)); +} + +/* Data structure that specifies how isl_union_*_transform + * should modify the base expressions in the union expression. + * + * If "inplace" is set, then the base expression in the input union + * are modified in place. This means that "fn" should not + * change the meaning of the union or that the union only + * has a single reference. + * If "space" is not NULL, then a new union is created in this space. + * If "filter" is not NULL, then only the base expressions that satisfy "filter" + * are taken into account. + * "filter_user" is passed as the second argument to "filter". + * If "fn" it not NULL, then it is applied to each entry in the input. + * "fn_user" is passed as the second argument to "fn". + */ +S(UNION,transform_control) { + int inplace; + isl_space *space; + isl_bool (*filter)(__isl_keep PART *part, void *user); + void *filter_user; + __isl_give PART *(*fn)(__isl_take PART *part, void *user); + void *fn_user; +}; + +/* Internal data structure for isl_union_*_transform_space. + * "control" specifies how the base expressions should be modified. + * "res" collects the results (if control->inplace is not set). + */ +S(UNION,transform_data) +{ + S(UNION,transform_control) *control; + UNION *res; +}; + +/* Apply control->fn to "part" and add the result to data->res or + * place it back into the input union if control->inplace is set. + */ +static isl_stat FN(UNION,transform_entry)(void **entry, void *user) +{ + S(UNION,transform_data) *data = (S(UNION,transform_data) *)user; + S(UNION,transform_control) *control = data->control; + PART *part = *entry; + + if (control->filter) { + isl_bool handle; + + handle = control->filter(part, control->filter_user); + if (handle < 0) + return isl_stat_error; + if (!handle) + return isl_stat_ok; + } + + if (!control->inplace) + part = FN(PART,copy)(part); + if (control->fn) + part = control->fn(part, control->fn_user); + if (control->inplace) + *entry = part; + else + data->res = FN(FN(UNION,add),BASE)(data->res, part); + if (!part || !data->res) + return isl_stat_error; + + return isl_stat_ok; +} + +/* Return a UNION that is obtained by modifying "u" according to "control". + */ +static __isl_give UNION *FN(UNION,transform)(__isl_take UNION *u, + S(UNION,transform_control) *control) +{ + S(UNION,transform_data) data = { control }; + isl_space *space; + + if (control->inplace) { + data.res = u; + } else { + if (control->space) + space = isl_space_copy(control->space); + else + space = FN(UNION,get_space)(u); + data.res = FN(UNION,alloc_same_size_on_space)(u, space); + } + if (FN(UNION,foreach_inplace)(u, &FN(UNION,transform_entry), &data) < 0) + data.res = FN(UNION,free)(data.res); + if (!control->inplace) + FN(UNION,free)(u); + return data.res; +} + +/* Return a UNION living in "space" that is otherwise obtained by modifying "u" + * according to "control". + */ +static __isl_give UNION *FN(UNION,transform_space)(__isl_take UNION *u, + __isl_take isl_space *space, S(UNION,transform_control) *control) +{ + if (!space) + return FN(UNION,free)(u); + control->space = space; + u = FN(UNION,transform)(u, control); + isl_space_free(space); + return u; +} + +/* Update "u" by applying "fn" to each entry. + * This operation is assumed not to change the number of entries nor + * the spaces of the entries. + * + * If there is only one reference to "u", then change "u" inplace. + * Otherwise, create a new UNION from "u" and discard the original. + */ +static __isl_give UNION *FN(UNION,transform_inplace)(__isl_take UNION *u, + __isl_give PART *(*fn)(__isl_take PART *part, void *user), void *user) +{ + S(UNION,transform_control) control = { .fn = fn, .fn_user = user }; + isl_bool single_ref; + + single_ref = FN(UNION,has_single_reference)(u); + if (single_ref < 0) + return FN(UNION,free)(u); + if (single_ref) + control.inplace = 1; + return FN(UNION,transform)(u, &control); +} + +/* An isl_union_*_transform callback for use in isl_union_*_dup + * that simply returns "part". + */ +static __isl_give PART *FN(UNION,copy_part)(__isl_take PART *part, void *user) +{ + return part; +} + +__isl_give UNION *FN(UNION,dup)(__isl_keep UNION *u) +{ + S(UNION,transform_control) control = { .fn = &FN(UNION,copy_part) }; + + u = FN(UNION,copy)(u); + return FN(UNION,transform)(u, &control); +} + +__isl_give UNION *FN(UNION,cow)(__isl_take UNION *u) +{ + if (!u) + return NULL; + + if (u->ref == 1) + return u; + u->ref--; + return FN(UNION,dup)(u); +} + +__isl_null UNION *FN(UNION,free)(__isl_take UNION *u) +{ + if (!u) + return NULL; + + if (--u->ref > 0) + return NULL; + + isl_hash_table_foreach(u->space->ctx, &u->table, + &FN(UNION,free_u_entry), NULL); + isl_hash_table_clear(&u->table); + isl_space_free(u->space); + free(u); + return NULL; +} + +static __isl_give PART *FN(UNION,align_entry)(__isl_take PART *part, void *user) +{ + isl_reordering *exp = user; + + exp = isl_reordering_extend_space(isl_reordering_copy(exp), + FN(PART,get_domain_space)(part)); + return FN(PART,realign_domain)(part, exp); +} + +/* Reorder the parameters of "u" according to the given reordering. + */ +static __isl_give UNION *FN(UNION,realign_domain)(__isl_take UNION *u, + __isl_take isl_reordering *r) +{ + S(UNION,transform_control) control = { + .fn = &FN(UNION,align_entry), + .fn_user = r, + }; + isl_space *space; + + if (!u || !r) + goto error; + + space = isl_reordering_get_space(r); + u = FN(UNION,transform_space)(u, space, &control); + isl_reordering_free(r); + return u; +error: + FN(UNION,free)(u); + isl_reordering_free(r); + return NULL; +} + +/* Align the parameters of "u" to those of "model". + */ +__isl_give UNION *FN(UNION,align_params)(__isl_take UNION *u, + __isl_take isl_space *model) +{ + isl_space *space; + isl_bool equal_params; + isl_reordering *r; + + space = FN(UNION,peek_space)(u); + equal_params = isl_space_has_equal_params(space, model); + if (equal_params < 0) + goto error; + if (equal_params) { + isl_space_free(model); + return u; + } + + r = isl_parameter_alignment_reordering(space, model); + isl_space_free(model); + + return FN(UNION,realign_domain)(u, r); +error: + isl_space_free(model); + FN(UNION,free)(u); + return NULL; +} + +/* Add "part" to *u, taking the union sum if "u" already has + * a part defined on the same space as "part". + */ +static isl_stat FN(UNION,union_add_part)(__isl_take PART *part, void *user) +{ + UNION **u = (UNION **)user; + + *u = FN(UNION,add_part_generic)(*u, part, 0); + + return isl_stat_ok; +} + +/* Compute the sum of "u1" and "u2" on the union of their domains, + * with the actual sum on the shared domain and + * the defined expression on the symmetric difference of the domains. + * + * This is an internal function that is exposed under different + * names depending on whether the base expressions have a zero default + * value. + * If they do, then this function is called "add". + * Otherwise, it is called "union_add". + */ +static __isl_give UNION *FN(UNION,union_add_)(__isl_take UNION *u1, + __isl_take UNION *u2) +{ + u1 = FN(UNION,align_params)(u1, FN(UNION,get_space)(u2)); + u2 = FN(UNION,align_params)(u2, FN(UNION,get_space)(u1)); + + u1 = FN(UNION,cow)(u1); + + if (!u1 || !u2) + goto error; + + if (FN(FN(UNION,foreach),BASE)(u2, &FN(UNION,union_add_part), &u1) < 0) + goto error; + + FN(UNION,free)(u2); + + return u1; +error: + FN(UNION,free)(u1); + FN(UNION,free)(u2); + return NULL; +} + +#if !DEFAULT_IS_ZERO + +/* Compute the sum of "u1" and "u2" on the union of their domains, + * with the actual sum on the shared domain and + * the defined expression on the symmetric difference of the domains. + */ +__isl_give UNION *FN(UNION,union_add)(__isl_take UNION *u1, + __isl_take UNION *u2) +{ + return FN(UNION,union_add_)(u1, u2); +} + +#endif + +__isl_give UNION *FN(FN(UNION,from),BASE)(__isl_take PART *part) +{ + isl_space *space; + UNION *u; + + if (!part) + return NULL; + + space = FN(PART,get_space)(part); + space = isl_space_drop_dims(space, isl_dim_in, 0, + isl_space_dim(space, isl_dim_in)); + space = isl_space_drop_dims(space, isl_dim_out, 0, + isl_space_dim(space, isl_dim_out)); + u = FN(UNION,ZERO)(space OPT_TYPE_ARG(part->)); + u = FN(FN(UNION,add),BASE)(u, part); + + return u; +} + +/* This function performs the same operation as isl_union_pw_*_from_pw_*, + * but is considered as a function on an isl_pw_* when exported. + */ +__isl_give UNION *FN(FN(PART,to_union),BASE)(__isl_take PART *part) +{ + return FN(FN(UNION,from),BASE)(part); +} + +S(UNION,match_bin_data) { + UNION *u2; + UNION *res; + __isl_give PART *(*fn)(__isl_take PART *, __isl_take PART *); +}; + +/* Check if data->u2 has an element living in the same space as "part". + * If so, call data->fn on the two elements and add the result to + * data->res. + */ +static isl_stat FN(UNION,match_bin_entry)(__isl_take PART *part, void *user) +{ + S(UNION,match_bin_data) *data = user; + struct isl_hash_table_entry *entry2; + isl_space *space; + PART *part2; + + space = FN(PART,get_space)(part); + entry2 = FN(UNION,find_part_entry)(data->u2, space, 0); + isl_space_free(space); + if (!entry2) + goto error; + if (entry2 == isl_hash_table_entry_none) { + FN(PART,free)(part); + return isl_stat_ok; + } + + part2 = entry2->data; + if (!isl_space_tuple_is_equal(part->dim, isl_dim_out, + part2->dim, isl_dim_out)) + isl_die(FN(UNION,get_ctx)(data->u2), isl_error_invalid, + "entries should have the same range space", + goto error); + + part = data->fn(part, FN(PART, copy)(entry2->data)); + + data->res = FN(FN(UNION,add),BASE)(data->res, part); + if (!data->res) + return isl_stat_error; + + return isl_stat_ok; +error: + FN(PART,free)(part); + return isl_stat_error; +} + +/* This function is currently only used from isl_polynomial.c + * and not from isl_fold.c. + */ +static __isl_give UNION *FN(UNION,match_bin_op)(__isl_take UNION *u1, + __isl_take UNION *u2, + __isl_give PART *(*fn)(__isl_take PART *, __isl_take PART *)) + __attribute__ ((unused)); +/* For each pair of elements in "u1" and "u2" living in the same space, + * call "fn" and collect the results. + */ +static __isl_give UNION *FN(UNION,match_bin_op)(__isl_take UNION *u1, + __isl_take UNION *u2, + __isl_give PART *(*fn)(__isl_take PART *, __isl_take PART *)) +{ + S(UNION,match_bin_data) data = { NULL, NULL, fn }; + + u1 = FN(UNION,align_params)(u1, FN(UNION,get_space)(u2)); + u2 = FN(UNION,align_params)(u2, FN(UNION,get_space)(u1)); + + if (!u1 || !u2) + goto error; + + data.u2 = u2; + data.res = FN(UNION,alloc_same_size)(u1); + if (FN(FN(UNION,foreach),BASE)(u1, + &FN(UNION,match_bin_entry), &data) < 0) + goto error; + + FN(UNION,free)(u1); + FN(UNION,free)(u2); + return data.res; +error: + FN(UNION,free)(u1); + FN(UNION,free)(u2); + FN(UNION,free)(data.res); + return NULL; +} + +/* Compute the sum of "u1" and "u2". + * + * If the base expressions have a default zero value, then the sum + * is computed on the union of the domains of "u1" and "u2". + * Otherwise, it is computed on their shared domains. + */ +__isl_give UNION *FN(UNION,add)(__isl_take UNION *u1, __isl_take UNION *u2) +{ +#if DEFAULT_IS_ZERO + return FN(UNION,union_add_)(u1, u2); +#else + return FN(UNION,match_bin_op)(u1, u2, &FN(PART,add)); +#endif +} + +S(UNION,any_set_data) { + isl_set *set; + __isl_give PW *(*fn)(__isl_take PW*, __isl_take isl_set*); +}; + +static __isl_give PART *FN(UNION,any_set_entry)(__isl_take PART *part, + void *user) +{ + S(UNION,any_set_data) *data = user; + + return data->fn(part, isl_set_copy(data->set)); +} + +/* Update each element of "u" by calling "fn" on the element and "set". + */ +static __isl_give UNION *FN(UNION,any_set_op)(__isl_take UNION *u, + __isl_take isl_set *set, + __isl_give PW *(*fn)(__isl_take PW*, __isl_take isl_set*)) +{ + S(UNION,any_set_data) data = { NULL, fn }; + S(UNION,transform_control) control = { + .fn = &FN(UNION,any_set_entry), + .fn_user = &data, + }; + + u = FN(UNION,align_params)(u, isl_set_get_space(set)); + set = isl_set_align_params(set, FN(UNION,get_space)(u)); + + if (!u || !set) + goto error; + + data.set = set; + u = FN(UNION,transform)(u, &control); + isl_set_free(set); + return u; +error: + FN(UNION,free)(u); + isl_set_free(set); + return NULL; +} + +/* Intersect the domain of "u" with the parameter domain "context". + */ +__isl_give UNION *FN(UNION,intersect_params)(__isl_take UNION *u, + __isl_take isl_set *set) +{ + return FN(UNION,any_set_op)(u, set, &FN(PW,intersect_params)); +} + +/* Compute the gist of the domain of "u" with respect to + * the parameter domain "context". + */ +__isl_give UNION *FN(UNION,gist_params)(__isl_take UNION *u, + __isl_take isl_set *set) +{ + return FN(UNION,any_set_op)(u, set, &FN(PW,gist_params)); +} + +/* Data structure that specifies how isl_union_*_match_domain_op + * should combine its arguments. + * + * If "filter" is not NULL, then only parts that pass the given + * filter are considered for matching. + * "fn" is applied to each part in the union and each corresponding + * set in the union set, i.e., such that the set lives in the same space + * as the domain of the part. + * If "match_space" is not NULL, then the set extracted from the union set + * does not live in the same space as the domain of the part, + * but rather in the space that results from calling "match_space" + * on this domain space. + */ +S(UNION,match_domain_control) { + isl_bool (*filter)(__isl_keep PART *part); + __isl_give isl_space *(*match_space)(__isl_take isl_space *space); + __isl_give PW *(*fn)(__isl_take PW*, __isl_take isl_set*); +}; + +S(UNION,match_domain_data) { + isl_union_set *uset; + UNION *res; + S(UNION,match_domain_control) *control; +}; + +/* Find the set in data->uset that lives in the same space as the domain + * of "part" (ignoring parameters), apply data->fn to *entry and this set + * (if any), and add the result to data->res. + */ +static isl_stat FN(UNION,match_domain_entry)(__isl_take PART *part, void *user) +{ + S(UNION,match_domain_data) *data = user; + struct isl_hash_table_entry *entry2; + isl_space *space; + + if (data->control->filter) { + isl_bool pass = data->control->filter(part); + if (pass < 0 || !pass) { + FN(PART,free)(part); + return pass < 0 ? isl_stat_error : isl_stat_ok; + } + } + + space = FN(PART,get_domain_space)(part); + if (data->control->match_space) + space = data->control->match_space(space); + entry2 = isl_union_set_find_entry(data->uset, space, 0); + isl_space_free(space); + if (!entry2 || entry2 == isl_hash_table_entry_none) { + FN(PART,free)(part); + return isl_stat_non_null(entry2); + } + + part = data->control->fn(part, isl_set_copy(entry2->data)); + + data->res = FN(FN(UNION,add),BASE)(data->res, part); + if (!data->res) + return isl_stat_error; + + return isl_stat_ok; +} + +/* Combine "u" and "uset" according to "control" + * and collect the results. + */ +static __isl_give UNION *FN(UNION,match_domain_op)(__isl_take UNION *u, + __isl_take isl_union_set *uset, S(UNION,match_domain_control) *control) +{ + S(UNION,match_domain_data) data = { NULL, NULL, control }; + + if (!u || !uset) + goto error; + + data.uset = uset; + data.res = FN(UNION,alloc_same_size)(u); + if (FN(FN(UNION,foreach),BASE)(u, + &FN(UNION,match_domain_entry), &data) < 0) + goto error; + + FN(UNION,free)(u); + isl_union_set_free(uset); + return data.res; +error: + FN(UNION,free)(u); + isl_union_set_free(uset); + FN(UNION,free)(data.res); + return NULL; +} + +/* Intersect the domain of "u" with "uset". + * If "uset" is a parameters domain, then intersect the parameter + * domain of "u" with this set. + */ +__isl_give UNION *FN(UNION,intersect_domain_union_set)(__isl_take UNION *u, + __isl_take isl_union_set *uset) +{ + S(UNION,match_domain_control) control = { + .fn = &FN(PW,intersect_domain), + }; + + if (isl_union_set_is_params(uset)) + return FN(UNION,intersect_params)(u, + isl_set_from_union_set(uset)); + return FN(UNION,match_domain_op)(u, uset, &control); +} + +/* This is an alternative name for the function above. + */ +__isl_give UNION *FN(UNION,intersect_domain)(__isl_take UNION *u, + __isl_take isl_union_set *uset) +{ + return FN(UNION,intersect_domain_union_set)(u, uset); +} + +/* Return true if this part should be kept. + * + * In particular, it should be kept if its domain space + * corresponds to "space". + */ +static isl_bool FN(UNION,select_entry)(__isl_keep PART *part, void *user) +{ + isl_space *space = user; + + return FN(PW,has_domain_space_tuples)(part, space); +} + +/* Remove any not element in "space" from the domain of "u". + * + * In particular, select any part of the function defined + * on this domain space. + */ +__isl_give UNION *FN(UNION,intersect_domain_space)(__isl_take UNION *u, + __isl_take isl_space *space) +{ + S(UNION,transform_control) control = { + .filter = &FN(UNION,select_entry), + .filter_user = space, + }; + + u = FN(UNION,transform)(u, &control); + isl_space_free(space); + return u; +} + +/* Is the domain of "pw" a wrapped relation? + */ +static isl_bool FN(PW,domain_is_wrapping)(__isl_keep PW *pw) +{ + return isl_space_domain_is_wrapping(FN(PW,peek_space)(pw)); +} + +/* Intersect the domain of the wrapped relation inside the domain of "u" + * with "uset". + */ +__isl_give UNION *FN(UNION,intersect_domain_wrapped_domain)(__isl_take UNION *u, + __isl_take isl_union_set *uset) +{ + S(UNION,match_domain_control) control = { + .filter = &FN(PART,domain_is_wrapping), + .match_space = &isl_space_factor_domain, + .fn = &FN(PW,intersect_domain_wrapped_domain), + }; + + return FN(UNION,match_domain_op)(u, uset, &control); +} + +/* Intersect the range of the wrapped relation inside the domain of "u" + * with "uset". + */ +__isl_give UNION *FN(UNION,intersect_domain_wrapped_range)(__isl_take UNION *u, + __isl_take isl_union_set *uset) +{ + S(UNION,match_domain_control) control = { + .filter = &FN(PART,domain_is_wrapping), + .match_space = &isl_space_factor_range, + .fn = &FN(PW,intersect_domain_wrapped_range), + }; + + return FN(UNION,match_domain_op)(u, uset, &control); +} + +/* Take the set (which may be empty) in data->uset that lives + * in the same space as the domain of "pw", subtract it from the domain + * of "part" and return the result. + */ +static __isl_give PART *FN(UNION,subtract_domain_entry)(__isl_take PART *part, + void *user) +{ + isl_union_set *uset = user; + isl_space *space; + isl_set *set; + + space = FN(PART,get_domain_space)(part); + set = isl_union_set_extract_set(uset, space); + return FN(PART,subtract_domain)(part, set); +} + +/* Subtract "uset" from the domain of "u". + */ +__isl_give UNION *FN(UNION,subtract_domain_union_set)(__isl_take UNION *u, + __isl_take isl_union_set *uset) +{ + S(UNION,transform_control) control = { + .fn = &FN(UNION,subtract_domain_entry), + .fn_user = uset, + }; + + u = FN(UNION,transform)(u, &control); + isl_union_set_free(uset); + return u; +} + +/* This is an alternative name for the function above. + */ +__isl_give UNION *FN(UNION,subtract_domain)(__isl_take UNION *u, + __isl_take isl_union_set *uset) +{ + return FN(UNION,subtract_domain_union_set)(u, uset); +} + +/* Return true if this part should be kept. + * + * In particular, it should be kept if its domain space + * does not correspond to "space". + */ +static isl_bool FN(UNION,filter_out_entry)(__isl_keep PART *part, void *user) +{ + isl_space *space = user; + + return isl_bool_not(FN(PW,has_domain_space_tuples)(part, space)); +} + +/* Remove any element in "space" from the domain of "u". + * + * In particular, filter out any part of the function defined + * on this domain space. + */ +__isl_give UNION *FN(UNION,subtract_domain_space)(__isl_take UNION *u, + __isl_take isl_space *space) +{ + S(UNION,transform_control) control = { + .filter = &FN(UNION,filter_out_entry), + .filter_user = space, + }; + + u = FN(UNION,transform)(u, &control); + isl_space_free(space); + return u; +} + +__isl_give UNION *FN(UNION,gist)(__isl_take UNION *u, + __isl_take isl_union_set *uset) +{ + S(UNION,match_domain_control) control = { + .fn = &FN(PW,gist), + }; + + if (isl_union_set_is_params(uset)) + return FN(UNION,gist_params)(u, isl_set_from_union_set(uset)); + return FN(UNION,match_domain_op)(u, uset, &control); +} + +/* Coalesce an entry in a UNION. Coalescing is performed in-place. + * Since the UNION may have several references, the entry is only + * replaced if the coalescing is successful. + */ +static isl_stat FN(UNION,coalesce_entry)(void **entry, void *user) +{ + PART **part_p = (PART **) entry; + PART *part; + + part = FN(PART,copy)(*part_p); + part = FN(PW,coalesce)(part); + if (!part) + return isl_stat_error; + FN(PART,free)(*part_p); + *part_p = part; + + return isl_stat_ok; +} + +__isl_give UNION *FN(UNION,coalesce)(__isl_take UNION *u) +{ + if (FN(UNION,foreach_inplace)(u, &FN(UNION,coalesce_entry), NULL) < 0) + goto error; + + return u; +error: + FN(UNION,free)(u); + return NULL; +} + +static isl_stat FN(UNION,domain_entry)(__isl_take PART *part, void *user) +{ + isl_union_set **uset = (isl_union_set **)user; + + *uset = isl_union_set_add_set(*uset, FN(PART,domain)(part)); + + return isl_stat_ok; +} + +__isl_give isl_union_set *FN(UNION,domain)(__isl_take UNION *u) +{ + isl_union_set *uset; + + uset = isl_union_set_empty(FN(UNION,get_space)(u)); + if (FN(FN(UNION,foreach),BASE)(u, &FN(UNION,domain_entry), &uset) < 0) + goto error; + + FN(UNION,free)(u); + + return uset; +error: + isl_union_set_free(uset); + FN(UNION,free)(u); + return NULL; +} + +#ifdef HAS_TYPE +/* Negate the type of "u". + */ +static __isl_give UNION *FN(UNION,negate_type)(__isl_take UNION *u) +{ + u = FN(UNION,cow)(u); + if (!u) + return NULL; + u->type = isl_fold_type_negate(u->type); + return u; +} +#else +/* Negate the type of "u". + * Since "u" does not have a type, do nothing. + */ +static __isl_give UNION *FN(UNION,negate_type)(__isl_take UNION *u) +{ + return u; +} +#endif + +/* Multiply "part" by the isl_val "user" and return the result. + */ +static __isl_give PART *FN(UNION,scale_val_entry)(__isl_take PART *part, + void *user) +{ + isl_val *v = user; + + return FN(PART,scale_val)(part, isl_val_copy(v)); +} + +/* Multiply "u" by "v" and return the result. + */ +__isl_give UNION *FN(UNION,scale_val)(__isl_take UNION *u, + __isl_take isl_val *v) +{ + if (!u || !v) + goto error; + if (isl_val_is_one(v)) { + isl_val_free(v); + return u; + } + + if (DEFAULT_IS_ZERO && u && isl_val_is_zero(v)) { + UNION *zero; + isl_space *space = FN(UNION,get_space)(u); + zero = FN(UNION,ZERO)(space OPT_TYPE_ARG(u->)); + FN(UNION,free)(u); + isl_val_free(v); + return zero; + } + + if (!isl_val_is_rat(v)) + isl_die(isl_val_get_ctx(v), isl_error_invalid, + "expecting rational factor", goto error); + + u = FN(UNION,transform_inplace)(u, &FN(UNION,scale_val_entry), v); + if (isl_val_is_neg(v)) + u = FN(UNION,negate_type)(u); + + isl_val_free(v); + return u; +error: + isl_val_free(v); + FN(UNION,free)(u); + return NULL; +} + +/* Divide "part" by the isl_val "user" and return the result. + */ +static __isl_give PART *FN(UNION,scale_down_val_entry)(__isl_take PART *part, + void *user) +{ + isl_val *v = user; + + return FN(PART,scale_down_val)(part, isl_val_copy(v)); +} + +/* Divide "u" by "v" and return the result. + */ +__isl_give UNION *FN(UNION,scale_down_val)(__isl_take UNION *u, + __isl_take isl_val *v) +{ + if (!u || !v) + goto error; + if (isl_val_is_one(v)) { + isl_val_free(v); + return u; + } + + if (!isl_val_is_rat(v)) + isl_die(isl_val_get_ctx(v), isl_error_invalid, + "expecting rational factor", goto error); + if (isl_val_is_zero(v)) + isl_die(isl_val_get_ctx(v), isl_error_invalid, + "cannot scale down by zero", goto error); + + u = FN(UNION,transform_inplace)(u, &FN(UNION,scale_down_val_entry), v); + if (isl_val_is_neg(v)) + u = FN(UNION,negate_type)(u); + + isl_val_free(v); + return u; +error: + isl_val_free(v); + FN(UNION,free)(u); + return NULL; +} + +/* Internal data structure for isl_union_*_every_*. + * + * "test" is the user-specified callback function. + * "user" is the user-specified callback function argument. + * + * "res" is the final result, initialized to isl_bool_true. + */ +S(UNION,every_data) { + isl_bool (*test)(__isl_keep PW *pw, void *user); + void *user; + + isl_bool res; +}; + +/* Call data->test on the piecewise expression at *entry, + * updating the result in data->res. + * Abort if this result is no longer isl_bool_true. + */ +static isl_stat FN(UNION,every_entry)(void **entry, void *user) +{ + S(UNION,every_data) *data = user; + PW *pw = *entry; + + data->res = data->test(pw, data->user); + if (data->res < 0 || !data->res) + return isl_stat_error; + + return isl_stat_ok; +} + +/* Does "test" succeed on every piecewise expression in "u"? + */ +isl_bool FN(FN(UNION,every),BASE)(__isl_keep UNION *u, + isl_bool (*test)(__isl_keep PW *pw, void *user), void *user) +{ + S(UNION,every_data) data = { test, user }; + + data.res = isl_bool_true; + if (FN(UNION,foreach_inplace)(u, &FN(UNION,every_entry), &data) < 0 && + data.res == isl_bool_true) + return isl_bool_error; + + return data.res; +} + +S(UNION,plain_is_equal_data) +{ + UNION *u2; +}; + +static isl_bool FN(UNION,plain_is_equal_el)(__isl_keep PW *pw, void *user) +{ + S(UNION,plain_is_equal_data) *data = user; + struct isl_hash_table_entry *entry; + + entry = FN(UNION,find_part_entry)(data->u2, pw->dim, 0); + if (!entry) + return isl_bool_error; + if (entry == isl_hash_table_entry_none) + return isl_bool_false; + + return FN(PW,plain_is_equal)(pw, entry->data); +} + +isl_bool FN(UNION,plain_is_equal)(__isl_keep UNION *u1, __isl_keep UNION *u2) +{ + S(UNION,plain_is_equal_data) data; + isl_size n1, n2; + isl_bool is_equal; + + if (!u1 || !u2) + return isl_bool_error; + if (u1 == u2) + return isl_bool_true; + if (u1->table.n != u2->table.n) + return isl_bool_false; + n1 = FN(FN(UNION,n),BASE)(u1); + n2 = FN(FN(UNION,n),BASE)(u2); + if (n1 < 0 || n2 < 0) + return isl_bool_error; + if (n1 != n2) + return isl_bool_false; + + u1 = FN(UNION,copy)(u1); + u2 = FN(UNION,copy)(u2); + u1 = FN(UNION,align_params)(u1, FN(UNION,get_space)(u2)); + u2 = FN(UNION,align_params)(u2, FN(UNION,get_space)(u1)); + if (!u1 || !u2) + goto error; + + data.u2 = u2; + is_equal = FN(FN(UNION,every),BASE)(u1, + &FN(UNION,plain_is_equal_el), &data); + + FN(UNION,free)(u1); + FN(UNION,free)(u2); + + return is_equal; +error: + FN(UNION,free)(u1); + FN(UNION,free)(u2); + return isl_bool_error; +} + +/* An isl_union_*_every_* callback that checks whether "pw" + * does not involve any NaNs. + */ +static isl_bool FN(UNION,no_nan_el)(__isl_keep PW *pw, void *user) +{ + return isl_bool_not(FN(PW,involves_nan)(pw)); +} + +/* Does "u" involve any NaNs? + */ +isl_bool FN(UNION,involves_nan)(__isl_keep UNION *u) +{ + isl_bool no_nan; + + no_nan = FN(FN(UNION,every),BASE)(u, &FN(UNION,no_nan_el), NULL); + + return isl_bool_not(no_nan); +} + +/* Internal data structure for isl_union_*_drop_dims. + * type, first and n are passed to isl_*_drop_dims. + */ +S(UNION,drop_dims_data) { + enum isl_dim_type type; + unsigned first; + unsigned n; +}; + +/* Drop the parameters specified by "data" from "part" and return the result. + */ +static __isl_give PART *FN(UNION,drop_dims_entry)(__isl_take PART *part, + void *user) +{ + S(UNION,drop_dims_data) *data = user; + + return FN(PART,drop_dims)(part, data->type, data->first, data->n); +} + +/* Drop the specified parameters from "u". + * That is, type is required to be isl_dim_param. + */ +__isl_give UNION *FN(UNION,drop_dims)( __isl_take UNION *u, + enum isl_dim_type type, unsigned first, unsigned n) +{ + isl_space *space; + S(UNION,drop_dims_data) data = { type, first, n }; + S(UNION,transform_control) control = { + .fn = &FN(UNION,drop_dims_entry), + .fn_user = &data, + }; + + if (!u) + return NULL; + + if (type != isl_dim_param) + isl_die(FN(UNION,get_ctx)(u), isl_error_invalid, + "can only project out parameters", + return FN(UNION,free)(u)); + + space = FN(UNION,get_space)(u); + space = isl_space_drop_dims(space, type, first, n); + return FN(UNION,transform_space)(u, space, &control); +} + +/* isl_union_*_every_* callback that checks whether "pw" + * does not involve the parameter at position "pos". + */ +static isl_bool FN(UNION,el_does_not_involve_param_at)(__isl_keep PW *pw, + void *user) +{ + unsigned *pos = user; + + return isl_bool_not(FN(PW,involves_dims)(pw, isl_dim_param, *pos, 1)); +} + +/* This is a specialized version of isl_union_*_involves_dims for use + * by isl_union_*_drop_unused_params. + * + * In particular, this function is only called on individual parameters, + * so only this case needs to be supported. + */ +static isl_bool FN(UNION,involves_dims)(__isl_take UNION *u, + enum isl_dim_type type, unsigned first, unsigned n) +{ + isl_bool none; + + if (type != isl_dim_param) + isl_die(FN(UNION,get_ctx)(u), isl_error_invalid, + "only parameters can be involved", + return isl_bool_error); + if (n != 1) + isl_die(FN(UNION,get_ctx)(u), isl_error_unsupported, + "only check for single parameter is supported", + return isl_bool_error); + + none = FN(FN(UNION,every),BASE)(u, + &FN(UNION,el_does_not_involve_param_at), &first); + + return isl_bool_not(none); +} + +#undef TYPE +#define TYPE UNION +static +#include "isl_check_named_params_templ.c" +#include "isl_drop_unused_params_templ.c" + +/* Internal data structure for isl_union_*_set_dim_name. + * pos is the position of the parameter that needs to be renamed. + * s is the new name. + */ +S(UNION,set_dim_name_data) { + unsigned pos; + const char *s; +}; + +/* Change the name of the parameter at position data->pos of "part" to data->s + * and return the result. + */ +static __isl_give PART *FN(UNION,set_dim_name_entry)(__isl_take PART *part, + void *user) +{ + S(UNION,set_dim_name_data) *data = user; + + return FN(PART,set_dim_name)(part, isl_dim_param, data->pos, data->s); +} + +/* Change the name of the parameter at position "pos" to "s". + * That is, type is required to be isl_dim_param. + */ +__isl_give UNION *FN(UNION,set_dim_name)(__isl_take UNION *u, + enum isl_dim_type type, unsigned pos, const char *s) +{ + S(UNION,set_dim_name_data) data = { pos, s }; + S(UNION,transform_control) control = { + .fn = &FN(UNION,set_dim_name_entry), + .fn_user = &data, + }; + isl_space *space; + + if (!u) + return NULL; + + if (type != isl_dim_param) + isl_die(FN(UNION,get_ctx)(u), isl_error_invalid, + "can only set parameter names", + return FN(UNION,free)(u)); + + space = FN(UNION,get_space)(u); + space = isl_space_set_dim_name(space, type, pos, s); + return FN(UNION,transform_space)(u, space, &control); +} + +/* Reset the user pointer on all identifiers of parameters and tuples + * of the space of "part" and return the result. + */ +static __isl_give PART *FN(UNION,reset_user_entry)(__isl_take PART *part, + void *user) +{ + return FN(PART,reset_user)(part); +} + +/* Reset the user pointer on all identifiers of parameters and tuples + * of the spaces of "u". + */ +__isl_give UNION *FN(UNION,reset_user)(__isl_take UNION *u) +{ + S(UNION,transform_control) control = { + .fn = &FN(UNION,reset_user_entry), + }; + isl_space *space; + + space = FN(UNION,get_space)(u); + space = isl_space_reset_user(space); + return FN(UNION,transform_space)(u, space, &control); +} + +/* Add the base expression held by "entry" to "list". + */ +static isl_stat FN(UNION,add_to_list)(void **entry, void *user) +{ + PW *pw = *entry; + LIST(PART) **list = user; + + *list = FN(LIST(PART),add)(*list, FN(PART,copy)(pw)); + if (!*list) + return isl_stat_error; + + return isl_stat_ok; +} + +/* Return a list containing all the base expressions in "u". + * + * First construct a list of the appropriate size and + * then add all the elements. + */ +__isl_give LIST(PART) *FN(FN(UNION,get),LIST(BASE))(__isl_keep UNION *u) +{ + isl_size n; + LIST(PART) *list; + + if (!u) + return NULL; + n = FN(FN(UNION,n),BASE)(u); + if (n < 0) + return NULL; + list = FN(LIST(PART),alloc)(FN(UNION,get_ctx(u)), n); + if (FN(UNION,foreach_inplace)(u, &FN(UNION,add_to_list), &list) < 0) + return FN(LIST(PART),free)(list); + + return list; +} diff --git a/external/mit/isl/dist/isl_val.c b/external/mit/isl/dist/isl_val.c new file mode 100644 index 000000000000..8b77622d7fb2 --- /dev/null +++ b/external/mit/isl/dist/isl_val.c @@ -0,0 +1,1619 @@ +/* + * Copyright 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 +#include +#include + +#undef EL_BASE +#define EL_BASE val + +#include +#include + +/* Allocate an isl_val object with indeterminate value. + */ +__isl_give isl_val *isl_val_alloc(isl_ctx *ctx) +{ + isl_val *v; + + v = isl_alloc_type(ctx, struct isl_val); + if (!v) + return NULL; + + v->ctx = ctx; + isl_ctx_ref(ctx); + v->ref = 1; + isl_int_init(v->n); + isl_int_init(v->d); + + return v; +} + +/* Return a reference to an isl_val representing zero. + */ +__isl_give isl_val *isl_val_zero(isl_ctx *ctx) +{ + return isl_val_int_from_si(ctx, 0); +} + +/* Return a reference to an isl_val representing one. + */ +__isl_give isl_val *isl_val_one(isl_ctx *ctx) +{ + return isl_val_int_from_si(ctx, 1); +} + +/* Return a reference to an isl_val representing negative one. + */ +__isl_give isl_val *isl_val_negone(isl_ctx *ctx) +{ + return isl_val_int_from_si(ctx, -1); +} + +/* Return a reference to an isl_val representing NaN. + */ +__isl_give isl_val *isl_val_nan(isl_ctx *ctx) +{ + isl_val *v; + + v = isl_val_alloc(ctx); + if (!v) + return NULL; + + isl_int_set_si(v->n, 0); + isl_int_set_si(v->d, 0); + + return v; +} + +/* Change "v" into a NaN. + */ +__isl_give isl_val *isl_val_set_nan(__isl_take isl_val *v) +{ + if (!v) + return NULL; + if (isl_val_is_nan(v)) + return v; + v = isl_val_cow(v); + if (!v) + return NULL; + + isl_int_set_si(v->n, 0); + isl_int_set_si(v->d, 0); + + return v; +} + +/* Return a reference to an isl_val representing +infinity. + */ +__isl_give isl_val *isl_val_infty(isl_ctx *ctx) +{ + isl_val *v; + + v = isl_val_alloc(ctx); + if (!v) + return NULL; + + isl_int_set_si(v->n, 1); + isl_int_set_si(v->d, 0); + + return v; +} + +/* Return a reference to an isl_val representing -infinity. + */ +__isl_give isl_val *isl_val_neginfty(isl_ctx *ctx) +{ + isl_val *v; + + v = isl_val_alloc(ctx); + if (!v) + return NULL; + + isl_int_set_si(v->n, -1); + isl_int_set_si(v->d, 0); + + return v; +} + +/* Return a reference to an isl_val representing the integer "i". + */ +__isl_give isl_val *isl_val_int_from_si(isl_ctx *ctx, long i) +{ + isl_val *v; + + v = isl_val_alloc(ctx); + if (!v) + return NULL; + + isl_int_set_si(v->n, i); + isl_int_set_si(v->d, 1); + + return v; +} + +/* Change the value of "v" to be equal to the integer "i". + */ +__isl_give isl_val *isl_val_set_si(__isl_take isl_val *v, long i) +{ + if (!v) + return NULL; + if (isl_val_is_int(v) && isl_int_cmp_si(v->n, i) == 0) + return v; + v = isl_val_cow(v); + if (!v) + return NULL; + + isl_int_set_si(v->n, i); + isl_int_set_si(v->d, 1); + + return v; +} + +/* Change the value of "v" to be equal to zero. + */ +__isl_give isl_val *isl_val_set_zero(__isl_take isl_val *v) +{ + return isl_val_set_si(v, 0); +} + +/* Return a reference to an isl_val representing the unsigned integer "u". + */ +__isl_give isl_val *isl_val_int_from_ui(isl_ctx *ctx, unsigned long u) +{ + isl_val *v; + + v = isl_val_alloc(ctx); + if (!v) + return NULL; + + isl_int_set_ui(v->n, u); + isl_int_set_si(v->d, 1); + + return v; +} + +/* Return a reference to an isl_val representing the integer "n". + */ +__isl_give isl_val *isl_val_int_from_isl_int(isl_ctx *ctx, isl_int n) +{ + isl_val *v; + + v = isl_val_alloc(ctx); + if (!v) + return NULL; + + isl_int_set(v->n, n); + isl_int_set_si(v->d, 1); + + return v; +} + +/* Return a reference to an isl_val representing the rational value "n"/"d". + * Normalizing the isl_val (if needed) is left to the caller. + */ +__isl_give isl_val *isl_val_rat_from_isl_int(isl_ctx *ctx, + isl_int n, isl_int d) +{ + isl_val *v; + + v = isl_val_alloc(ctx); + if (!v) + return NULL; + + isl_int_set(v->n, n); + isl_int_set(v->d, d); + + return v; +} + +/* Return a new reference to "v". + */ +__isl_give isl_val *isl_val_copy(__isl_keep isl_val *v) +{ + if (!v) + return NULL; + + v->ref++; + return v; +} + +/* Return a fresh copy of "val". + */ +__isl_give isl_val *isl_val_dup(__isl_keep isl_val *val) +{ + isl_val *dup; + + if (!val) + return NULL; + + dup = isl_val_alloc(isl_val_get_ctx(val)); + if (!dup) + return NULL; + + isl_int_set(dup->n, val->n); + isl_int_set(dup->d, val->d); + + return dup; +} + +/* Return an isl_val that is equal to "val" and that has only + * a single reference. + */ +__isl_give isl_val *isl_val_cow(__isl_take isl_val *val) +{ + if (!val) + return NULL; + + if (val->ref == 1) + return val; + val->ref--; + return isl_val_dup(val); +} + +/* Free "v" and return NULL. + */ +__isl_null isl_val *isl_val_free(__isl_take isl_val *v) +{ + if (!v) + return NULL; + + if (--v->ref > 0) + return NULL; + + isl_ctx_deref(v->ctx); + isl_int_clear(v->n); + isl_int_clear(v->d); + free(v); + return NULL; +} + +/* Extract the numerator of a rational value "v" as an integer. + * + * If "v" is not a rational value, then the result is undefined. + */ +long isl_val_get_num_si(__isl_keep isl_val *v) +{ + if (!v) + return 0; + if (!isl_val_is_rat(v)) + isl_die(isl_val_get_ctx(v), isl_error_invalid, + "expecting rational value", return 0); + if (!isl_int_fits_slong(v->n)) + isl_die(isl_val_get_ctx(v), isl_error_invalid, + "numerator too large", return 0); + return isl_int_get_si(v->n); +} + +/* Extract the numerator of a rational value "v" as an isl_int. + * + * If "v" is not a rational value, then the result is undefined. + */ +isl_stat isl_val_get_num_isl_int(__isl_keep isl_val *v, isl_int *n) +{ + if (!v) + return isl_stat_error; + if (!isl_val_is_rat(v)) + isl_die(isl_val_get_ctx(v), isl_error_invalid, + "expecting rational value", return isl_stat_error); + isl_int_set(*n, v->n); + return isl_stat_ok; +} + +/* Extract the denominator of a rational value "v" as an integer. + * + * If "v" is not a rational value, then the result is undefined. + */ +long isl_val_get_den_si(__isl_keep isl_val *v) +{ + if (!v) + return 0; + if (!isl_val_is_rat(v)) + isl_die(isl_val_get_ctx(v), isl_error_invalid, + "expecting rational value", return 0); + if (!isl_int_fits_slong(v->d)) + isl_die(isl_val_get_ctx(v), isl_error_invalid, + "denominator too large", return 0); + return isl_int_get_si(v->d); +} + +/* Extract the denominator of a rational value "v" as an isl_val. + * + * If "v" is not a rational value, then the result is undefined. + */ +__isl_give isl_val *isl_val_get_den_val(__isl_keep isl_val *v) +{ + if (!v) + return NULL; + if (!isl_val_is_rat(v)) + isl_die(isl_val_get_ctx(v), isl_error_invalid, + "expecting rational value", return NULL); + return isl_val_int_from_isl_int(isl_val_get_ctx(v), v->d); +} + +/* Return an approximation of "v" as a double. + */ +double isl_val_get_d(__isl_keep isl_val *v) +{ + if (!v) + return 0; + if (!isl_val_is_rat(v)) + isl_die(isl_val_get_ctx(v), isl_error_invalid, + "expecting rational value", return 0); + return isl_int_get_d(v->n) / isl_int_get_d(v->d); +} + +/* Return the isl_ctx to which "val" belongs. + */ +isl_ctx *isl_val_get_ctx(__isl_keep isl_val *val) +{ + return val ? val->ctx : NULL; +} + +/* Return a hash value that digests "val". + */ +uint32_t isl_val_get_hash(__isl_keep isl_val *val) +{ + uint32_t hash; + + if (!val) + return 0; + + hash = isl_hash_init(); + hash = isl_int_hash(val->n, hash); + hash = isl_int_hash(val->d, hash); + + return hash; +} + +/* Normalize "v". + * + * In particular, make sure that the denominator of a rational value + * is positive and the numerator and denominator do not have any + * common divisors. + * + * This function should not be called by an external user + * since it will only be given normalized values. + */ +__isl_give isl_val *isl_val_normalize(__isl_take isl_val *v) +{ + isl_ctx *ctx; + + if (!v) + return NULL; + if (isl_val_is_int(v)) + return v; + if (!isl_val_is_rat(v)) + return v; + if (isl_int_is_neg(v->d)) { + isl_int_neg(v->d, v->d); + isl_int_neg(v->n, v->n); + } + ctx = isl_val_get_ctx(v); + isl_int_gcd(ctx->normalize_gcd, v->n, v->d); + if (isl_int_is_one(ctx->normalize_gcd)) + return v; + isl_int_divexact(v->n, v->n, ctx->normalize_gcd); + isl_int_divexact(v->d, v->d, ctx->normalize_gcd); + return v; +} + +/* Return the opposite of "v". + */ +__isl_give isl_val *isl_val_neg(__isl_take isl_val *v) +{ + if (!v) + return NULL; + if (isl_val_is_nan(v)) + return v; + if (isl_val_is_zero(v)) + return v; + + v = isl_val_cow(v); + if (!v) + return NULL; + isl_int_neg(v->n, v->n); + + return v; +} + +/* Return the inverse of "v". + */ +__isl_give isl_val *isl_val_inv(__isl_take isl_val *v) +{ + if (!v) + return NULL; + if (isl_val_is_nan(v)) + return v; + if (isl_val_is_zero(v)) { + isl_ctx *ctx = isl_val_get_ctx(v); + isl_val_free(v); + return isl_val_nan(ctx); + } + if (isl_val_is_infty(v) || isl_val_is_neginfty(v)) { + isl_ctx *ctx = isl_val_get_ctx(v); + isl_val_free(v); + return isl_val_zero(ctx); + } + + v = isl_val_cow(v); + if (!v) + return NULL; + isl_int_swap(v->n, v->d); + + return isl_val_normalize(v); +} + +/* Return the absolute value of "v". + */ +__isl_give isl_val *isl_val_abs(__isl_take isl_val *v) +{ + if (!v) + return NULL; + if (isl_val_is_nan(v)) + return v; + if (isl_val_is_nonneg(v)) + return v; + return isl_val_neg(v); +} + +/* Return the "floor" (greatest integer part) of "v". + * That is, return the result of rounding towards -infinity. + */ +__isl_give isl_val *isl_val_floor(__isl_take isl_val *v) +{ + if (!v) + return NULL; + if (isl_val_is_int(v)) + return v; + if (!isl_val_is_rat(v)) + return v; + + v = isl_val_cow(v); + if (!v) + return NULL; + isl_int_fdiv_q(v->n, v->n, v->d); + isl_int_set_si(v->d, 1); + + return v; +} + +/* Return the "ceiling" of "v". + * That is, return the result of rounding towards +infinity. + */ +__isl_give isl_val *isl_val_ceil(__isl_take isl_val *v) +{ + if (!v) + return NULL; + if (isl_val_is_int(v)) + return v; + if (!isl_val_is_rat(v)) + return v; + + v = isl_val_cow(v); + if (!v) + return NULL; + isl_int_cdiv_q(v->n, v->n, v->d); + isl_int_set_si(v->d, 1); + + return v; +} + +/* Truncate "v". + * That is, return the result of rounding towards zero. + */ +__isl_give isl_val *isl_val_trunc(__isl_take isl_val *v) +{ + if (!v) + return NULL; + if (isl_val_is_int(v)) + return v; + if (!isl_val_is_rat(v)) + return v; + + v = isl_val_cow(v); + if (!v) + return NULL; + isl_int_tdiv_q(v->n, v->n, v->d); + isl_int_set_si(v->d, 1); + + return v; +} + +/* Return 2^v, where v is an integer (that is not too large). + */ +__isl_give isl_val *isl_val_pow2(__isl_take isl_val *v) +{ + unsigned long exp; + int neg; + + v = isl_val_cow(v); + if (!v) + return NULL; + if (!isl_val_is_int(v)) + isl_die(isl_val_get_ctx(v), isl_error_invalid, + "can only compute integer powers", + return isl_val_free(v)); + neg = isl_val_is_neg(v); + if (neg) + isl_int_neg(v->n, v->n); + if (!isl_int_fits_ulong(v->n)) + isl_die(isl_val_get_ctx(v), isl_error_invalid, + "exponent too large", return isl_val_free(v)); + exp = isl_int_get_ui(v->n); + if (neg) { + isl_int_mul_2exp(v->d, v->d, exp); + isl_int_set_si(v->n, 1); + } else { + isl_int_mul_2exp(v->n, v->d, exp); + } + + return v; +} + +/* This is an alternative name for the function above. + */ +__isl_give isl_val *isl_val_2exp(__isl_take isl_val *v) +{ + return isl_val_pow2(v); +} + +/* Return the minimum of "v1" and "v2". + */ +__isl_give isl_val *isl_val_min(__isl_take isl_val *v1, __isl_take isl_val *v2) +{ + if (!v1 || !v2) + goto error; + + if (isl_val_is_nan(v1)) { + isl_val_free(v2); + return v1; + } + if (isl_val_is_nan(v2)) { + isl_val_free(v1); + return v2; + } + if (isl_val_le(v1, v2)) { + isl_val_free(v2); + return v1; + } else { + isl_val_free(v1); + return v2; + } +error: + isl_val_free(v1); + isl_val_free(v2); + return NULL; +} + +/* Return the maximum of "v1" and "v2". + */ +__isl_give isl_val *isl_val_max(__isl_take isl_val *v1, __isl_take isl_val *v2) +{ + if (!v1 || !v2) + goto error; + + if (isl_val_is_nan(v1)) { + isl_val_free(v2); + return v1; + } + if (isl_val_is_nan(v2)) { + isl_val_free(v1); + return v2; + } + if (isl_val_ge(v1, v2)) { + isl_val_free(v2); + return v1; + } else { + isl_val_free(v1); + return v2; + } +error: + isl_val_free(v1); + isl_val_free(v2); + return NULL; +} + +/* Return the sum of "v1" and "v2". + */ +__isl_give isl_val *isl_val_add(__isl_take isl_val *v1, __isl_take isl_val *v2) +{ + if (!v1 || !v2) + goto error; + if (isl_val_is_nan(v1)) { + isl_val_free(v2); + return v1; + } + if (isl_val_is_nan(v2)) { + isl_val_free(v1); + return v2; + } + if ((isl_val_is_infty(v1) && isl_val_is_neginfty(v2)) || + (isl_val_is_neginfty(v1) && isl_val_is_infty(v2))) { + isl_val_free(v2); + return isl_val_set_nan(v1); + } + if (isl_val_is_infty(v1) || isl_val_is_neginfty(v1)) { + isl_val_free(v2); + return v1; + } + if (isl_val_is_infty(v2) || isl_val_is_neginfty(v2)) { + isl_val_free(v1); + return v2; + } + if (isl_val_is_zero(v1)) { + isl_val_free(v1); + return v2; + } + if (isl_val_is_zero(v2)) { + isl_val_free(v2); + return v1; + } + + v1 = isl_val_cow(v1); + if (!v1) + goto error; + if (isl_val_is_int(v1) && isl_val_is_int(v2)) + isl_int_add(v1->n, v1->n, v2->n); + else { + if (isl_int_eq(v1->d, v2->d)) + isl_int_add(v1->n, v1->n, v2->n); + else { + isl_int_mul(v1->n, v1->n, v2->d); + isl_int_addmul(v1->n, v2->n, v1->d); + isl_int_mul(v1->d, v1->d, v2->d); + } + v1 = isl_val_normalize(v1); + } + isl_val_free(v2); + return v1; +error: + isl_val_free(v1); + isl_val_free(v2); + return NULL; +} + +/* Return the sum of "v1" and "v2". + */ +__isl_give isl_val *isl_val_add_ui(__isl_take isl_val *v1, unsigned long v2) +{ + if (!v1) + return NULL; + if (!isl_val_is_rat(v1)) + return v1; + if (v2 == 0) + return v1; + v1 = isl_val_cow(v1); + if (!v1) + return NULL; + + isl_int_addmul_ui(v1->n, v1->d, v2); + + return v1; +} + +/* Subtract "v2" from "v1". + */ +__isl_give isl_val *isl_val_sub(__isl_take isl_val *v1, __isl_take isl_val *v2) +{ + if (!v1 || !v2) + goto error; + if (isl_val_is_nan(v1)) { + isl_val_free(v2); + return v1; + } + if (isl_val_is_nan(v2)) { + isl_val_free(v1); + return v2; + } + if ((isl_val_is_infty(v1) && isl_val_is_infty(v2)) || + (isl_val_is_neginfty(v1) && isl_val_is_neginfty(v2))) { + isl_val_free(v2); + return isl_val_set_nan(v1); + } + if (isl_val_is_infty(v1) || isl_val_is_neginfty(v1)) { + isl_val_free(v2); + return v1; + } + if (isl_val_is_infty(v2) || isl_val_is_neginfty(v2)) { + isl_val_free(v1); + return isl_val_neg(v2); + } + if (isl_val_is_zero(v2)) { + isl_val_free(v2); + return v1; + } + if (isl_val_is_zero(v1)) { + isl_val_free(v1); + return isl_val_neg(v2); + } + + v1 = isl_val_cow(v1); + if (!v1) + goto error; + if (isl_val_is_int(v1) && isl_val_is_int(v2)) + isl_int_sub(v1->n, v1->n, v2->n); + else { + if (isl_int_eq(v1->d, v2->d)) + isl_int_sub(v1->n, v1->n, v2->n); + else { + isl_int_mul(v1->n, v1->n, v2->d); + isl_int_submul(v1->n, v2->n, v1->d); + isl_int_mul(v1->d, v1->d, v2->d); + } + v1 = isl_val_normalize(v1); + } + isl_val_free(v2); + return v1; +error: + isl_val_free(v1); + isl_val_free(v2); + return NULL; +} + +/* Subtract "v2" from "v1". + */ +__isl_give isl_val *isl_val_sub_ui(__isl_take isl_val *v1, unsigned long v2) +{ + if (!v1) + return NULL; + if (!isl_val_is_rat(v1)) + return v1; + if (v2 == 0) + return v1; + v1 = isl_val_cow(v1); + if (!v1) + return NULL; + + isl_int_submul_ui(v1->n, v1->d, v2); + + return v1; +} + +/* Return the product of "v1" and "v2". + */ +__isl_give isl_val *isl_val_mul(__isl_take isl_val *v1, __isl_take isl_val *v2) +{ + if (!v1 || !v2) + goto error; + if (isl_val_is_nan(v1)) { + isl_val_free(v2); + return v1; + } + if (isl_val_is_nan(v2)) { + isl_val_free(v1); + return v2; + } + if ((!isl_val_is_rat(v1) && isl_val_is_zero(v2)) || + (isl_val_is_zero(v1) && !isl_val_is_rat(v2))) { + isl_val_free(v2); + return isl_val_set_nan(v1); + } + if (isl_val_is_zero(v1)) { + isl_val_free(v2); + return v1; + } + if (isl_val_is_zero(v2)) { + isl_val_free(v1); + return v2; + } + if (isl_val_is_infty(v1) || isl_val_is_neginfty(v1)) { + if (isl_val_is_neg(v2)) + v1 = isl_val_neg(v1); + isl_val_free(v2); + return v1; + } + if (isl_val_is_infty(v2) || isl_val_is_neginfty(v2)) { + if (isl_val_is_neg(v1)) + v2 = isl_val_neg(v2); + isl_val_free(v1); + return v2; + } + + v1 = isl_val_cow(v1); + if (!v1) + goto error; + if (isl_val_is_int(v1) && isl_val_is_int(v2)) + isl_int_mul(v1->n, v1->n, v2->n); + else { + isl_int_mul(v1->n, v1->n, v2->n); + isl_int_mul(v1->d, v1->d, v2->d); + v1 = isl_val_normalize(v1); + } + isl_val_free(v2); + return v1; +error: + isl_val_free(v1); + isl_val_free(v2); + return NULL; +} + +/* Return the product of "v1" and "v2". + * + * This is a private copy of isl_val_mul for use in the generic + * isl_multi_*_scale_val instantiated for isl_val. + */ +__isl_give isl_val *isl_val_scale_val(__isl_take isl_val *v1, + __isl_take isl_val *v2) +{ + return isl_val_mul(v1, v2); +} + +/* Return the product of "v1" and "v2". + */ +__isl_give isl_val *isl_val_mul_ui(__isl_take isl_val *v1, unsigned long v2) +{ + if (!v1) + return NULL; + if (isl_val_is_nan(v1)) + return v1; + if (!isl_val_is_rat(v1)) { + if (v2 == 0) + v1 = isl_val_set_nan(v1); + return v1; + } + if (v2 == 1) + return v1; + v1 = isl_val_cow(v1); + if (!v1) + return NULL; + + isl_int_mul_ui(v1->n, v1->n, v2); + + return isl_val_normalize(v1); +} + +/* Divide "v1" by "v2". + */ +__isl_give isl_val *isl_val_div(__isl_take isl_val *v1, __isl_take isl_val *v2) +{ + if (!v1 || !v2) + goto error; + if (isl_val_is_nan(v1)) { + isl_val_free(v2); + return v1; + } + if (isl_val_is_nan(v2)) { + isl_val_free(v1); + return v2; + } + if (isl_val_is_zero(v2) || + (!isl_val_is_rat(v1) && !isl_val_is_rat(v2))) { + isl_val_free(v2); + return isl_val_set_nan(v1); + } + if (isl_val_is_zero(v1)) { + isl_val_free(v2); + return v1; + } + if (isl_val_is_infty(v1) || isl_val_is_neginfty(v1)) { + if (isl_val_is_neg(v2)) + v1 = isl_val_neg(v1); + isl_val_free(v2); + return v1; + } + if (isl_val_is_infty(v2) || isl_val_is_neginfty(v2)) { + isl_val_free(v2); + return isl_val_set_zero(v1); + } + + v1 = isl_val_cow(v1); + if (!v1) + goto error; + if (isl_val_is_int(v2)) { + isl_int_mul(v1->d, v1->d, v2->n); + v1 = isl_val_normalize(v1); + } else { + isl_int_mul(v1->d, v1->d, v2->n); + isl_int_mul(v1->n, v1->n, v2->d); + v1 = isl_val_normalize(v1); + } + isl_val_free(v2); + return v1; +error: + isl_val_free(v1); + isl_val_free(v2); + return NULL; +} + +/* Divide "v1" by "v2". + */ +__isl_give isl_val *isl_val_div_ui(__isl_take isl_val *v1, unsigned long v2) +{ + if (!v1) + return NULL; + if (isl_val_is_nan(v1)) + return v1; + if (v2 == 0) + return isl_val_set_nan(v1); + if (v2 == 1) + return v1; + if (isl_val_is_zero(v1)) + return v1; + if (isl_val_is_infty(v1) || isl_val_is_neginfty(v1)) + return v1; + v1 = isl_val_cow(v1); + if (!v1) + return NULL; + + isl_int_mul_ui(v1->d, v1->d, v2); + + return isl_val_normalize(v1); +} + +/* Divide "v1" by "v2". + * + * This is a private copy of isl_val_div for use in the generic + * isl_multi_*_scale_down_val instantiated for isl_val. + */ +__isl_give isl_val *isl_val_scale_down_val(__isl_take isl_val *v1, + __isl_take isl_val *v2) +{ + return isl_val_div(v1, v2); +} + +/* Given two integer values "v1" and "v2", check if "v1" is divisible by "v2". + */ +isl_bool isl_val_is_divisible_by(__isl_keep isl_val *v1, __isl_keep isl_val *v2) +{ + if (!v1 || !v2) + return isl_bool_error; + + if (!isl_val_is_int(v1) || !isl_val_is_int(v2)) + isl_die(isl_val_get_ctx(v1), isl_error_invalid, + "expecting two integers", return isl_bool_error); + + return isl_bool_ok(isl_int_is_divisible_by(v1->n, v2->n)); +} + +/* Given two integer values "v1" and "v2", return the residue of "v1" + * modulo "v2". + */ +__isl_give isl_val *isl_val_mod(__isl_take isl_val *v1, __isl_take isl_val *v2) +{ + if (!v1 || !v2) + goto error; + if (!isl_val_is_int(v1) || !isl_val_is_int(v2)) + isl_die(isl_val_get_ctx(v1), isl_error_invalid, + "expecting two integers", goto error); + if (isl_val_is_nonneg(v1) && isl_val_lt(v1, v2)) { + isl_val_free(v2); + return v1; + } + v1 = isl_val_cow(v1); + if (!v1) + goto error; + isl_int_fdiv_r(v1->n, v1->n, v2->n); + isl_val_free(v2); + return v1; +error: + isl_val_free(v1); + isl_val_free(v2); + return NULL; +} + +/* Given two integer values "v1" and "v2", return the residue of "v1" + * modulo "v2". + * + * This is a private copy of isl_val_mod for use in the generic + * isl_multi_*_mod_multi_val instantiated for isl_val. + */ +__isl_give isl_val *isl_val_mod_val(__isl_take isl_val *v1, + __isl_take isl_val *v2) +{ + return isl_val_mod(v1, v2); +} + +/* Given two integer values, return their greatest common divisor. + */ +__isl_give isl_val *isl_val_gcd(__isl_take isl_val *v1, __isl_take isl_val *v2) +{ + if (!v1 || !v2) + goto error; + if (!isl_val_is_int(v1) || !isl_val_is_int(v2)) + isl_die(isl_val_get_ctx(v1), isl_error_invalid, + "expecting two integers", goto error); + if (isl_val_eq(v1, v2)) { + isl_val_free(v2); + return v1; + } + if (isl_val_is_one(v1)) { + isl_val_free(v2); + return v1; + } + if (isl_val_is_one(v2)) { + isl_val_free(v1); + return v2; + } + v1 = isl_val_cow(v1); + if (!v1) + goto error; + isl_int_gcd(v1->n, v1->n, v2->n); + isl_val_free(v2); + return v1; +error: + isl_val_free(v1); + isl_val_free(v2); + return NULL; +} + +/* Compute x, y and g such that g = gcd(a,b) and a*x+b*y = g. + */ +static void isl_int_gcdext(isl_int *g, isl_int *x, isl_int *y, + isl_int a, isl_int b) +{ + isl_int d, tmp; + isl_int a_copy, b_copy; + + isl_int_init(a_copy); + isl_int_init(b_copy); + isl_int_init(d); + isl_int_init(tmp); + isl_int_set(a_copy, a); + isl_int_set(b_copy, b); + isl_int_abs(*g, a_copy); + isl_int_abs(d, b_copy); + isl_int_set_si(*x, 1); + isl_int_set_si(*y, 0); + while (isl_int_is_pos(d)) { + isl_int_fdiv_q(tmp, *g, d); + isl_int_submul(*x, tmp, *y); + isl_int_submul(*g, tmp, d); + isl_int_swap(*g, d); + isl_int_swap(*x, *y); + } + if (isl_int_is_zero(a_copy)) + isl_int_set_si(*x, 0); + else if (isl_int_is_neg(a_copy)) + isl_int_neg(*x, *x); + if (isl_int_is_zero(b_copy)) + isl_int_set_si(*y, 0); + else { + isl_int_mul(tmp, a_copy, *x); + isl_int_sub(tmp, *g, tmp); + isl_int_divexact(*y, tmp, b_copy); + } + isl_int_clear(d); + isl_int_clear(tmp); + isl_int_clear(a_copy); + isl_int_clear(b_copy); +} + +/* Given two integer values v1 and v2, return their greatest common divisor g, + * as well as two integers x and y such that x * v1 + y * v2 = g. + */ +__isl_give isl_val *isl_val_gcdext(__isl_take isl_val *v1, + __isl_take isl_val *v2, __isl_give isl_val **x, __isl_give isl_val **y) +{ + isl_ctx *ctx; + isl_val *a = NULL, *b = NULL; + + if (!x && !y) + return isl_val_gcd(v1, v2); + + if (!v1 || !v2) + goto error; + + ctx = isl_val_get_ctx(v1); + if (!isl_val_is_int(v1) || !isl_val_is_int(v2)) + isl_die(ctx, isl_error_invalid, + "expecting two integers", goto error); + + v1 = isl_val_cow(v1); + a = isl_val_alloc(ctx); + b = isl_val_alloc(ctx); + if (!v1 || !a || !b) + goto error; + isl_int_gcdext(&v1->n, &a->n, &b->n, v1->n, v2->n); + if (x) { + isl_int_set_si(a->d, 1); + *x = a; + } else + isl_val_free(a); + if (y) { + isl_int_set_si(b->d, 1); + *y = b; + } else + isl_val_free(b); + isl_val_free(v2); + return v1; +error: + isl_val_free(v1); + isl_val_free(v2); + isl_val_free(a); + isl_val_free(b); + if (x) + *x = NULL; + if (y) + *y = NULL; + return NULL; +} + +/* Does "v" represent an integer value? + */ +isl_bool isl_val_is_int(__isl_keep isl_val *v) +{ + if (!v) + return isl_bool_error; + + return isl_bool_ok(isl_int_is_one(v->d)); +} + +/* Does "v" represent a rational value? + */ +isl_bool isl_val_is_rat(__isl_keep isl_val *v) +{ + if (!v) + return isl_bool_error; + + return isl_bool_ok(!isl_int_is_zero(v->d)); +} + +/* Does "v" represent NaN? + */ +isl_bool isl_val_is_nan(__isl_keep isl_val *v) +{ + if (!v) + return isl_bool_error; + + return isl_bool_ok(isl_int_is_zero(v->n) && isl_int_is_zero(v->d)); +} + +/* Does "v" represent +infinity? + */ +isl_bool isl_val_is_infty(__isl_keep isl_val *v) +{ + if (!v) + return isl_bool_error; + + return isl_bool_ok(isl_int_is_pos(v->n) && isl_int_is_zero(v->d)); +} + +/* Does "v" represent -infinity? + */ +isl_bool isl_val_is_neginfty(__isl_keep isl_val *v) +{ + if (!v) + return isl_bool_error; + + return isl_bool_ok(isl_int_is_neg(v->n) && isl_int_is_zero(v->d)); +} + +/* Does "v" represent the integer zero? + */ +isl_bool isl_val_is_zero(__isl_keep isl_val *v) +{ + if (!v) + return isl_bool_error; + + return isl_bool_ok(isl_int_is_zero(v->n) && !isl_int_is_zero(v->d)); +} + +/* Does "v" represent the integer one? + */ +isl_bool isl_val_is_one(__isl_keep isl_val *v) +{ + if (!v) + return isl_bool_error; + + if (isl_val_is_nan(v)) + return isl_bool_false; + + return isl_bool_ok(isl_int_eq(v->n, v->d)); +} + +/* Does "v" represent the integer negative one? + */ +isl_bool isl_val_is_negone(__isl_keep isl_val *v) +{ + if (!v) + return isl_bool_error; + + return isl_bool_ok(isl_int_is_neg(v->n) && isl_int_abs_eq(v->n, v->d)); +} + +/* Is "v" (strictly) positive? + */ +isl_bool isl_val_is_pos(__isl_keep isl_val *v) +{ + if (!v) + return isl_bool_error; + + return isl_bool_ok(isl_int_is_pos(v->n)); +} + +/* Is "v" (strictly) negative? + */ +isl_bool isl_val_is_neg(__isl_keep isl_val *v) +{ + if (!v) + return isl_bool_error; + + return isl_bool_ok(isl_int_is_neg(v->n)); +} + +/* Is "v" non-negative? + */ +isl_bool isl_val_is_nonneg(__isl_keep isl_val *v) +{ + if (!v) + return isl_bool_error; + + if (isl_val_is_nan(v)) + return isl_bool_false; + + return isl_bool_ok(isl_int_is_nonneg(v->n)); +} + +/* Is "v" non-positive? + */ +isl_bool isl_val_is_nonpos(__isl_keep isl_val *v) +{ + if (!v) + return isl_bool_error; + + if (isl_val_is_nan(v)) + return isl_bool_false; + + return isl_bool_ok(isl_int_is_nonpos(v->n)); +} + +/* Return the sign of "v". + * + * The sign of NaN is undefined. + */ +int isl_val_sgn(__isl_keep isl_val *v) +{ + if (!v) + return 0; + if (isl_val_is_zero(v)) + return 0; + if (isl_val_is_pos(v)) + return 1; + return -1; +} + +/* Is "v1" (strictly) less than "v2"? + */ +isl_bool isl_val_lt(__isl_keep isl_val *v1, __isl_keep isl_val *v2) +{ + isl_int t; + isl_bool lt; + + if (!v1 || !v2) + return isl_bool_error; + if (isl_val_is_int(v1) && isl_val_is_int(v2)) + return isl_bool_ok(isl_int_lt(v1->n, v2->n)); + if (isl_val_is_nan(v1) || isl_val_is_nan(v2)) + return isl_bool_false; + if (isl_val_eq(v1, v2)) + return isl_bool_false; + if (isl_val_is_infty(v2)) + return isl_bool_true; + if (isl_val_is_infty(v1)) + return isl_bool_false; + if (isl_val_is_neginfty(v1)) + return isl_bool_true; + if (isl_val_is_neginfty(v2)) + return isl_bool_false; + + isl_int_init(t); + isl_int_mul(t, v1->n, v2->d); + isl_int_submul(t, v2->n, v1->d); + lt = isl_bool_ok(isl_int_is_neg(t)); + isl_int_clear(t); + + return lt; +} + +/* Is "v1" (strictly) greater than "v2"? + */ +isl_bool isl_val_gt(__isl_keep isl_val *v1, __isl_keep isl_val *v2) +{ + return isl_val_lt(v2, v1); +} + +/* Is "v" (strictly) greater than "i"? + */ +isl_bool isl_val_gt_si(__isl_keep isl_val *v, long i) +{ + isl_val *vi; + isl_bool res; + + if (!v) + return isl_bool_error; + if (isl_val_is_int(v)) + return isl_bool_ok(isl_int_cmp_si(v->n, i) > 0); + if (isl_val_is_nan(v)) + return isl_bool_false; + if (isl_val_is_infty(v)) + return isl_bool_true; + if (isl_val_is_neginfty(v)) + return isl_bool_false; + + vi = isl_val_int_from_si(isl_val_get_ctx(v), i); + res = isl_bool_ok(isl_val_gt(v, vi)); + isl_val_free(vi); + + return res; +} + +/* Is "v1" less than or equal to "v2"? + */ +isl_bool isl_val_le(__isl_keep isl_val *v1, __isl_keep isl_val *v2) +{ + isl_int t; + isl_bool le; + + if (!v1 || !v2) + return isl_bool_error; + if (isl_val_is_int(v1) && isl_val_is_int(v2)) + return isl_bool_ok(isl_int_le(v1->n, v2->n)); + if (isl_val_is_nan(v1) || isl_val_is_nan(v2)) + return isl_bool_false; + if (isl_val_eq(v1, v2)) + return isl_bool_true; + if (isl_val_is_infty(v2)) + return isl_bool_true; + if (isl_val_is_infty(v1)) + return isl_bool_false; + if (isl_val_is_neginfty(v1)) + return isl_bool_true; + if (isl_val_is_neginfty(v2)) + return isl_bool_false; + + isl_int_init(t); + isl_int_mul(t, v1->n, v2->d); + isl_int_submul(t, v2->n, v1->d); + le = isl_bool_ok(isl_int_is_nonpos(t)); + isl_int_clear(t); + + return le; +} + +/* Is "v1" greater than or equal to "v2"? + */ +isl_bool isl_val_ge(__isl_keep isl_val *v1, __isl_keep isl_val *v2) +{ + return isl_val_le(v2, v1); +} + +/* How does "v" compare to "i"? + * + * Return 1 if v is greater, -1 if v is smaller and 0 if v is equal to i. + * + * If v is NaN (or NULL), then the result is undefined. + */ +int isl_val_cmp_si(__isl_keep isl_val *v, long i) +{ + isl_int t; + int cmp; + + if (!v) + return 0; + if (isl_val_is_int(v)) + return isl_int_cmp_si(v->n, i); + if (isl_val_is_nan(v)) + return 0; + if (isl_val_is_infty(v)) + return 1; + if (isl_val_is_neginfty(v)) + return -1; + + isl_int_init(t); + isl_int_mul_si(t, v->d, i); + isl_int_sub(t, v->n, t); + cmp = isl_int_sgn(t); + isl_int_clear(t); + + return cmp; +} + +/* Is "v1" equal to "v2"? + */ +isl_bool isl_val_eq(__isl_keep isl_val *v1, __isl_keep isl_val *v2) +{ + if (!v1 || !v2) + return isl_bool_error; + if (isl_val_is_nan(v1) || isl_val_is_nan(v2)) + return isl_bool_false; + + return isl_bool_ok(isl_int_eq(v1->n, v2->n) && + isl_int_eq(v1->d, v2->d)); +} + +/* Is "v" equal to "i"? + */ +isl_bool isl_val_eq_si(__isl_keep isl_val *v, long i) +{ + if (!v) + return isl_bool_error; + if (!isl_val_is_int(v)) + return isl_bool_false; + return isl_bool_ok(isl_int_cmp_si(v->n, i) == 0); +} + +/* Is "v1" equal to "v2" in absolute value? + */ +isl_bool isl_val_abs_eq(__isl_keep isl_val *v1, __isl_keep isl_val *v2) +{ + if (!v1 || !v2) + return isl_bool_error; + if (isl_val_is_nan(v1) || isl_val_is_nan(v2)) + return isl_bool_false; + + return isl_bool_ok(isl_int_abs_eq(v1->n, v2->n) && + isl_int_eq(v1->d, v2->d)); +} + +/* Is "v1" different from "v2"? + */ +isl_bool isl_val_ne(__isl_keep isl_val *v1, __isl_keep isl_val *v2) +{ + if (!v1 || !v2) + return isl_bool_error; + if (isl_val_is_nan(v1) || isl_val_is_nan(v2)) + return isl_bool_false; + + return isl_bool_ok(isl_int_ne(v1->n, v2->n) || + isl_int_ne(v1->d, v2->d)); +} + +/* Print a textual representation of "v" onto "p". + */ +__isl_give isl_printer *isl_printer_print_val(__isl_take isl_printer *p, + __isl_keep isl_val *v) +{ + int neg; + + if (!p || !v) + return isl_printer_free(p); + + neg = isl_int_is_neg(v->n); + if (neg) { + p = isl_printer_print_str(p, "-"); + isl_int_neg(v->n, v->n); + } + if (isl_int_is_zero(v->d)) { + int sgn = isl_int_sgn(v->n); + p = isl_printer_print_str(p, sgn < 0 ? "-infty" : + sgn == 0 ? "NaN" : "infty"); + } else + p = isl_printer_print_isl_int(p, v->n); + if (neg) + isl_int_neg(v->n, v->n); + if (!isl_int_is_zero(v->d) && !isl_int_is_one(v->d)) { + p = isl_printer_print_str(p, "/"); + p = isl_printer_print_isl_int(p, v->d); + } + + return p; +} + +/* Is "val1" (obviously) equal to "val2"? + * + * This is a private copy of isl_val_eq for use in the generic + * isl_multi_*_plain_is_equal instantiated for isl_val. + */ +isl_bool isl_val_plain_is_equal(__isl_keep isl_val *val1, + __isl_keep isl_val *val2) +{ + return isl_val_eq(val1, val2); +} + +/* Does "v" have any non-zero coefficients + * for any dimension in the given range? + * + * This function is only meant to be used in the generic isl_multi_* + * functions which have to deal with base objects that have an associated + * space. Since an isl_val does not have any coefficients, this function + * always returns isl_bool_false. + */ +isl_bool isl_val_involves_dims(__isl_keep isl_val *v, enum isl_dim_type type, + unsigned first, unsigned n) +{ + if (!v) + return isl_bool_error; + + return isl_bool_false; +} + +/* Insert "n" dimensions of type "type" at position "first". + * + * This function is only meant to be used in the generic isl_multi_* + * functions which have to deal with base objects that have an associated + * space. Since an isl_val does not have an associated space, this function + * does not do anything. + */ +__isl_give isl_val *isl_val_insert_dims(__isl_take isl_val *v, + enum isl_dim_type type, unsigned first, unsigned n) +{ + return v; +} + +/* Change the name of the dimension of type "type" at position "pos" to "s". + * + * This function is only meant to be used in the generic isl_multi_* + * functions which have to deal with base objects that have an associated + * space. Since an isl_val does not have an associated space, this function + * does not do anything. + */ +__isl_give isl_val *isl_val_set_dim_name(__isl_take isl_val *v, + enum isl_dim_type type, unsigned pos, const char *s) +{ + return v; +} + +/* Return an isl_val that is zero on "ls". + * + * This function is only meant to be used in the generic isl_multi_* + * functions which have to deal with base objects that have an associated + * space. Since an isl_val does not have an associated space, this function + * simply returns a zero isl_val in the same context as "ls". + */ +__isl_give isl_val *isl_val_zero_on_domain(__isl_take isl_local_space *ls) +{ + isl_ctx *ctx; + + if (!ls) + return NULL; + ctx = isl_local_space_get_ctx(ls); + isl_local_space_free(ls); + return isl_val_zero(ctx); +} + +#define isl_val_involves_nan isl_val_is_nan + +#undef BASE +#define BASE val + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Does "mv" consist of only zeros? + */ +isl_bool isl_multi_val_is_zero(__isl_keep isl_multi_val *mv) +{ + return isl_multi_val_every(mv, &isl_val_is_zero); +} + +/* Add "v" to each of the elements of "mv". + */ +__isl_give isl_multi_val *isl_multi_val_add_val(__isl_take isl_multi_val *mv, + __isl_take isl_val *v) +{ + if (!v) + return isl_multi_val_free(mv); + if (isl_val_is_zero(v)) { + isl_val_free(v); + return mv; + } + return isl_multi_val_fn_val(mv, &isl_val_add, v); +} + +/* Reduce the elements of "mv" modulo "v". + */ +__isl_give isl_multi_val *isl_multi_val_mod_val(__isl_take isl_multi_val *mv, + __isl_take isl_val *v) +{ + return isl_multi_val_fn_val(mv, &isl_val_mod, v); +} diff --git a/external/mit/isl/dist/isl_val_gmp.c b/external/mit/isl/dist/isl_val_gmp.c new file mode 100644 index 000000000000..cd74709a0fcd --- /dev/null +++ b/external/mit/isl/dist/isl_val_gmp.c @@ -0,0 +1,128 @@ +#include +#include +#include + +/* Return a reference to an isl_val representing the integer "z". + */ +__isl_give isl_val *isl_val_int_from_gmp(isl_ctx *ctx, mpz_t z) +{ + isl_val *v; + + v = isl_val_alloc(ctx); + if (!v) + return NULL; + + isl_int_set(v->n, z); + isl_int_set_si(v->d, 1); + + return v; +} + +/* Return a reference to an isl_val representing the rational value "n"/"d". + */ +__isl_give isl_val *isl_val_from_gmp(isl_ctx *ctx, const mpz_t n, const mpz_t d) +{ + isl_val *v; + + v = isl_val_alloc(ctx); + if (!v) + return NULL; + + isl_int_set(v->n, n); + isl_int_set(v->d, d); + + return isl_val_normalize(v); +} + +/* Extract the numerator of a rational value "v" in "z". + * + * If "v" is not a rational value, then the result is undefined. + */ +int isl_val_get_num_gmp(__isl_keep isl_val *v, mpz_t z) +{ + if (!v) + return -1; + if (!isl_val_is_rat(v)) + isl_die(isl_val_get_ctx(v), isl_error_invalid, + "expecting rational value", return -1); + mpz_set(z, v->n); + return 0; +} + +/* Extract the denominator of a rational value "v" in "z". + * + * If "v" is not a rational value, then the result is undefined. + */ +int isl_val_get_den_gmp(__isl_keep isl_val *v, mpz_t z) +{ + if (!v) + return -1; + if (!isl_val_is_rat(v)) + isl_die(isl_val_get_ctx(v), isl_error_invalid, + "expecting rational value", return -1); + mpz_set(z, v->d); + return 0; +} + +/* Return a reference to an isl_val representing the unsigned + * integer value stored in the "n" chunks of size "size" at "chunks". + * The least significant chunk is assumed to be stored first. + */ +__isl_give isl_val *isl_val_int_from_chunks(isl_ctx *ctx, size_t n, + size_t size, const void *chunks) +{ + isl_val *v; + + v = isl_val_alloc(ctx); + if (!v) + return NULL; + + mpz_import(v->n, n, -1, size, 0, 0, chunks); + isl_int_set_si(v->d, 1); + + return v; +} + +/* Return the number of chunks of size "size" required to + * store the absolute value of the numerator of "v". + */ +isl_size isl_val_n_abs_num_chunks(__isl_keep isl_val *v, size_t size) +{ + if (!v) + return isl_size_error; + + if (!isl_val_is_rat(v)) + isl_die(isl_val_get_ctx(v), isl_error_invalid, + "expecting rational value", return isl_size_error); + + size *= 8; + return (mpz_sizeinbase(v->n, 2) + size - 1) / size; +} + +/* Store a representation of the absolute value of the numerator of "v" + * in terms of chunks of size "size" at "chunks". + * The least significant chunk is stored first. + * The number of chunks in the result can be obtained by calling + * isl_val_n_abs_num_chunks. The user is responsible for allocating + * enough memory to store the results. + * + * In the special case of a zero value, isl_val_n_abs_num_chunks will + * return one, while mpz_export will not fill in any chunks. We therefore + * do it ourselves. + */ +isl_stat isl_val_get_abs_num_chunks(__isl_keep isl_val *v, size_t size, + void *chunks) +{ + if (!v || !chunks) + return isl_stat_error; + + if (!isl_val_is_rat(v)) + isl_die(isl_val_get_ctx(v), isl_error_invalid, + "expecting rational value", return isl_stat_error); + + mpz_export(chunks, NULL, -1, size, 0, 0, v->n); + if (isl_val_is_zero(v)) + memset(chunks, 0, size); + + return isl_stat_ok; +} diff --git a/external/mit/isl/dist/isl_val_imath.c b/external/mit/isl/dist/isl_val_imath.c new file mode 100644 index 000000000000..dc4acc1d8456 --- /dev/null +++ b/external/mit/isl/dist/isl_val_imath.c @@ -0,0 +1,64 @@ +#include + +/* Return a reference to an isl_val representing the unsigned + * integer value stored in the "n" chunks of size "size" at "chunks". + * The least significant chunk is assumed to be stored first. + */ +__isl_give isl_val *isl_val_int_from_chunks(isl_ctx *ctx, size_t n, + size_t size, const void *chunks) +{ + isl_val *v; + + v = isl_val_alloc(ctx); + if (!v) + return NULL; + + impz_import(v->n, n, -1, size, 0, 0, chunks); + isl_int_set_si(v->d, 1); + + return v; +} + +/* Store a representation of the absolute value of the numerator of "v" + * in terms of chunks of size "size" at "chunks". + * The least significant chunk is stored first. + * The number of chunks in the result can be obtained by calling + * isl_val_n_abs_num_chunks. The user is responsible for allocating + * enough memory to store the results. + * + * In the special case of a zero value, isl_val_n_abs_num_chunks will + * return one, while impz_export will not fill in any chunks. We therefore + * do it ourselves. + */ +isl_stat isl_val_get_abs_num_chunks(__isl_keep isl_val *v, size_t size, + void *chunks) +{ + if (!v || !chunks) + return isl_stat_error; + + if (!isl_val_is_rat(v)) + isl_die(isl_val_get_ctx(v), isl_error_invalid, + "expecting rational value", return isl_stat_error); + + impz_export(chunks, NULL, -1, size, 0, 0, v->n); + if (isl_val_is_zero(v)) + memset(chunks, 0, size); + + return isl_stat_ok; +} + +/* Return the number of chunks of size "size" required to + * store the absolute value of the numerator of "v". + */ +isl_size isl_val_n_abs_num_chunks(__isl_keep isl_val *v, size_t size) +{ + if (!v) + return isl_size_error; + + if (!isl_val_is_rat(v)) + isl_die(isl_val_get_ctx(v), isl_error_invalid, + "expecting rational value", return isl_size_error); + + size *= 8; + return (impz_sizeinbase(v->n, 2) + size - 1) / size; +} diff --git a/external/mit/isl/dist/isl_val_private.h b/external/mit/isl/dist/isl_val_private.h new file mode 100644 index 000000000000..59d851990507 --- /dev/null +++ b/external/mit/isl/dist/isl_val_private.h @@ -0,0 +1,61 @@ +#ifndef ISL_VAL_PRIVATE_H +#define ISL_VAL_PRIVATE_H + +#include +#include +#include +#include + +/* Represents a "value", which may be an integer value, a rational value, + * plus or minus infinity or "not a number". + * + * Internally, +infinity is represented as 1/0, + * -infinity as -1/0 and NaN as 0/0. + * + * A rational value is always normalized before it is passed to the user. + */ +struct isl_val { + int ref; + isl_ctx *ctx; + + isl_int n; + isl_int d; +}; + +#undef EL +#define EL isl_val + +#include + +__isl_give isl_val *isl_val_alloc(isl_ctx *ctx); +__isl_give isl_val *isl_val_normalize(__isl_take isl_val *v); +__isl_give isl_val *isl_val_int_from_isl_int(isl_ctx *ctx, isl_int n); +__isl_give isl_val *isl_val_rat_from_isl_int(isl_ctx *ctx, + isl_int n, isl_int d); +__isl_give isl_val *isl_val_cow(__isl_take isl_val *val); + +isl_stat isl_val_get_num_isl_int(__isl_keep isl_val *v, isl_int *n); + +isl_bool isl_val_involves_dims(__isl_keep isl_val *v, enum isl_dim_type type, + unsigned first, unsigned n); +__isl_give isl_val *isl_val_insert_dims(__isl_take isl_val *v, + enum isl_dim_type type, unsigned first, unsigned n); +__isl_give isl_val *isl_val_set_dim_name(__isl_take isl_val *v, + enum isl_dim_type type, unsigned pos, const char *s); + +__isl_give isl_val *isl_val_scale_val(__isl_take isl_val *v1, + __isl_take isl_val *v2); +__isl_give isl_val *isl_val_scale_down_val(__isl_take isl_val *v1, + __isl_take isl_val *v2); +__isl_give isl_val *isl_val_mod_val(__isl_take isl_val *v1, + __isl_take isl_val *v2); + +isl_bool isl_val_plain_is_equal(__isl_keep isl_val *val1, + __isl_keep isl_val *val2); + +#undef BASE +#define BASE val + +#include + +#endif diff --git a/external/mit/isl/dist/isl_val_sioimath.c b/external/mit/isl/dist/isl_val_sioimath.c new file mode 100644 index 000000000000..9b9e73d817a6 --- /dev/null +++ b/external/mit/isl/dist/isl_val_sioimath.c @@ -0,0 +1,68 @@ +#include + +/* Return a reference to an isl_val representing the unsigned + * integer value stored in the "n" chunks of size "size" at "chunks". + * The least significant chunk is assumed to be stored first. + */ +__isl_give isl_val *isl_val_int_from_chunks(isl_ctx *ctx, size_t n, + size_t size, const void *chunks) +{ + isl_val *v; + + v = isl_val_alloc(ctx); + if (!v) + return NULL; + + impz_import(isl_sioimath_reinit_big(v->n), n, -1, size, 0, 0, chunks); + isl_sioimath_try_demote(v->n); + isl_int_set_si(v->d, 1); + + return v; +} + +/* Store a representation of the absolute value of the numerator of "v" + * in terms of chunks of size "size" at "chunks". + * The least significant chunk is stored first. + * The number of chunks in the result can be obtained by calling + * isl_val_n_abs_num_chunks. The user is responsible for allocating + * enough memory to store the results. + * + * In the special case of a zero value, isl_val_n_abs_num_chunks will + * return one, while impz_export will not fill in any chunks. We therefore + * do it ourselves. + */ +isl_stat isl_val_get_abs_num_chunks(__isl_keep isl_val *v, size_t size, + void *chunks) +{ + isl_sioimath_scratchspace_t scratch; + + if (!v || !chunks) + return isl_stat_error; + + if (!isl_val_is_rat(v)) + isl_die(isl_val_get_ctx(v), isl_error_invalid, + "expecting rational value", return isl_stat_error); + + impz_export(chunks, NULL, -1, size, 0, 0, + isl_sioimath_bigarg_src(*v->n, &scratch)); + if (isl_val_is_zero(v)) + memset(chunks, 0, size); + + return isl_stat_ok; +} + +/* Return the number of chunks of size "size" required to + * store the absolute value of the numerator of "v". + */ +isl_size isl_val_n_abs_num_chunks(__isl_keep isl_val *v, size_t size) +{ + if (!v) + return isl_size_error; + + if (!isl_val_is_rat(v)) + isl_die(isl_val_get_ctx(v), isl_error_invalid, + "expecting rational value", return isl_size_error); + + size *= 8; + return (isl_sioimath_sizeinbase(*v->n, 2) + size - 1) / size; +} diff --git a/external/mit/isl/dist/isl_vec.c b/external/mit/isl/dist/isl_vec.c new file mode 100644 index 000000000000..323015b8269c --- /dev/null +++ b/external/mit/isl/dist/isl_vec.c @@ -0,0 +1,685 @@ +/* + * Copyright 2008-2009 Katholieke Universiteit Leuven + * Copyright 2011 Sven Verdoolaege + * Copyright 2013 Ecole Normale Superieure + * + * 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 Ecole Normale Superieure, 45 rue d’Ulm, 75230 Paris, France + */ + +#include +#include +#include +#include + +isl_ctx *isl_vec_get_ctx(__isl_keep isl_vec *vec) +{ + return vec ? vec->ctx : NULL; +} + +/* Return a hash value that digests "vec". + */ +uint32_t isl_vec_get_hash(__isl_keep isl_vec *vec) +{ + if (!vec) + return 0; + + return isl_seq_get_hash(vec->el, vec->size); +} + +__isl_give isl_vec *isl_vec_alloc(struct isl_ctx *ctx, unsigned size) +{ + struct isl_vec *vec; + + vec = isl_alloc_type(ctx, struct isl_vec); + if (!vec) + return NULL; + + vec->block = isl_blk_alloc(ctx, size); + if (isl_blk_is_error(vec->block)) + goto error; + + vec->ctx = ctx; + isl_ctx_ref(ctx); + vec->ref = 1; + vec->size = size; + vec->el = vec->block.data; + + return vec; +error: + isl_blk_free(ctx, vec->block); + free(vec); + return NULL; +} + +__isl_give isl_vec *isl_vec_extend(__isl_take isl_vec *vec, unsigned size) +{ + if (!vec) + return NULL; + if (size <= vec->size) + return vec; + + vec = isl_vec_cow(vec); + if (!vec) + return NULL; + + vec->block = isl_blk_extend(vec->ctx, vec->block, size); + if (!vec->block.data) + goto error; + + vec->size = size; + vec->el = vec->block.data; + + return vec; +error: + isl_vec_free(vec); + return NULL; +} + +/* Apply the expansion specified by "exp" to the "n" elements starting at "pos". + * "expanded" it the number of elements that need to replace those "n" + * elements. The entries in "exp" have increasing values between + * 0 and "expanded". + */ +__isl_give isl_vec *isl_vec_expand(__isl_take isl_vec *vec, int pos, int n, + int *exp, int expanded) +{ + int i, j; + int old_size, extra; + + if (!vec) + return NULL; + if (expanded < n) + isl_die(isl_vec_get_ctx(vec), isl_error_invalid, + "not an expansion", return isl_vec_free(vec)); + if (expanded == n) + return vec; + if (pos < 0 || n < 0 || pos + n > vec->size) + isl_die(isl_vec_get_ctx(vec), isl_error_invalid, + "position out of bounds", return isl_vec_free(vec)); + + old_size = vec->size; + extra = expanded - n; + vec = isl_vec_extend(vec, old_size + extra); + vec = isl_vec_cow(vec); + if (!vec) + return NULL; + + for (i = old_size - 1; i >= pos + n; --i) + isl_int_set(vec->el[i + extra], vec->el[i]); + + j = n - 1; + for (i = expanded - 1; i >= 0; --i) { + if (j >= 0 && exp[j] == i) { + if (i != j) + isl_int_swap(vec->el[pos + i], + vec->el[pos + j]); + j--; + } else { + isl_int_set_si(vec->el[pos + i], 0); + } + } + + return vec; +} + +/* Create a vector of size "size" with zero-valued elements. + */ +__isl_give isl_vec *isl_vec_zero(isl_ctx *ctx, unsigned size) +{ + isl_vec *vec; + + vec = isl_vec_alloc(ctx, size); + if (!vec) + return NULL; + isl_seq_clr(vec->el, size); + return vec; +} + +__isl_give isl_vec *isl_vec_zero_extend(__isl_take isl_vec *vec, unsigned size) +{ + int extra; + + if (!vec) + return NULL; + if (size <= vec->size) + return vec; + + vec = isl_vec_cow(vec); + if (!vec) + return NULL; + + extra = size - vec->size; + vec = isl_vec_extend(vec, size); + if (!vec) + return NULL; + + isl_seq_clr(vec->el + size - extra, extra); + + return vec; +} + +/* Return a vector containing the elements of "vec1" followed by + * those of "vec2". + */ +__isl_give isl_vec *isl_vec_concat(__isl_take isl_vec *vec1, + __isl_take isl_vec *vec2) +{ + if (!vec1 || !vec2) + goto error; + + if (vec2->size == 0) { + isl_vec_free(vec2); + return vec1; + } + + if (vec1->size == 0) { + isl_vec_free(vec1); + return vec2; + } + + vec1 = isl_vec_extend(vec1, vec1->size + vec2->size); + if (!vec1) + goto error; + + isl_seq_cpy(vec1->el + vec1->size - vec2->size, vec2->el, vec2->size); + + isl_vec_free(vec2); + return vec1; +error: + isl_vec_free(vec1); + isl_vec_free(vec2); + return NULL; +} + +__isl_give isl_vec *isl_vec_copy(__isl_keep isl_vec *vec) +{ + if (!vec) + return NULL; + + vec->ref++; + return vec; +} + +__isl_give isl_vec *isl_vec_dup(__isl_keep isl_vec *vec) +{ + struct isl_vec *vec2; + + if (!vec) + return NULL; + vec2 = isl_vec_alloc(vec->ctx, vec->size); + if (!vec2) + return NULL; + isl_seq_cpy(vec2->el, vec->el, vec->size); + return vec2; +} + +__isl_give isl_vec *isl_vec_cow(__isl_take isl_vec *vec) +{ + struct isl_vec *vec2; + if (!vec) + return NULL; + + if (vec->ref == 1) + return vec; + + vec2 = isl_vec_dup(vec); + isl_vec_free(vec); + return vec2; +} + +__isl_null isl_vec *isl_vec_free(__isl_take isl_vec *vec) +{ + if (!vec) + return NULL; + + if (--vec->ref > 0) + return NULL; + + isl_ctx_deref(vec->ctx); + isl_blk_free(vec->ctx, vec->block); + free(vec); + + return NULL; +} + +isl_size isl_vec_size(__isl_keep isl_vec *vec) +{ + return vec ? vec->size : isl_size_error; +} + +/* Extract the element at position "pos" of "vec". + */ +__isl_give isl_val *isl_vec_get_element_val(__isl_keep isl_vec *vec, int pos) +{ + isl_ctx *ctx; + + if (!vec) + return NULL; + ctx = isl_vec_get_ctx(vec); + if (pos < 0 || pos >= vec->size) + isl_die(ctx, isl_error_invalid, "position out of range", + return NULL); + return isl_val_int_from_isl_int(ctx, vec->el[pos]); +} + +__isl_give isl_vec *isl_vec_set_element(__isl_take isl_vec *vec, + int pos, isl_int v) +{ + vec = isl_vec_cow(vec); + if (!vec) + return NULL; + if (pos < 0 || pos >= vec->size) + isl_die(vec->ctx, isl_error_invalid, "position out of range", + goto error); + isl_int_set(vec->el[pos], v); + return vec; +error: + isl_vec_free(vec); + return NULL; +} + +__isl_give isl_vec *isl_vec_set_element_si(__isl_take isl_vec *vec, + int pos, int v) +{ + vec = isl_vec_cow(vec); + if (!vec) + return NULL; + if (pos < 0 || pos >= vec->size) + isl_die(vec->ctx, isl_error_invalid, "position out of range", + goto error); + isl_int_set_si(vec->el[pos], v); + return vec; +error: + isl_vec_free(vec); + return NULL; +} + +/* Replace the element at position "pos" of "vec" by "v". + */ +__isl_give isl_vec *isl_vec_set_element_val(__isl_take isl_vec *vec, + int pos, __isl_take isl_val *v) +{ + if (!v) + return isl_vec_free(vec); + if (!isl_val_is_int(v)) + isl_die(isl_val_get_ctx(v), isl_error_invalid, + "expecting integer value", goto error); + vec = isl_vec_set_element(vec, pos, v->n); + isl_val_free(v); + return vec; +error: + isl_val_free(v); + return isl_vec_free(vec); +} + +/* Compare the elements of "vec1" and "vec2" at position "pos". + */ +int isl_vec_cmp_element(__isl_keep isl_vec *vec1, __isl_keep isl_vec *vec2, + int pos) +{ + if (!vec1 || !vec2) + return 0; + if (pos < 0 || pos >= vec1->size || pos >= vec2->size) + isl_die(isl_vec_get_ctx(vec1), isl_error_invalid, + "position out of range", return 0); + return isl_int_cmp(vec1->el[pos], vec2->el[pos]); +} + +/* Does "vec" contain only zero elements? + */ +isl_bool isl_vec_is_zero(__isl_keep isl_vec *vec) +{ + if (!vec) + return isl_bool_error; + return isl_bool_ok(isl_seq_first_non_zero(vec->el, vec->size) < 0); +} + +isl_bool isl_vec_is_equal(__isl_keep isl_vec *vec1, __isl_keep isl_vec *vec2) +{ + if (!vec1 || !vec2) + return isl_bool_error; + + if (vec1->size != vec2->size) + return isl_bool_false; + + return isl_bool_ok(isl_seq_eq(vec1->el, vec2->el, vec1->size)); +} + +__isl_give isl_printer *isl_printer_print_vec(__isl_take isl_printer *printer, + __isl_keep isl_vec *vec) +{ + int i; + + if (!printer || !vec) + goto error; + + printer = isl_printer_print_str(printer, "["); + for (i = 0; i < vec->size; ++i) { + if (i) + printer = isl_printer_print_str(printer, ","); + printer = isl_printer_print_isl_int(printer, vec->el[i]); + } + printer = isl_printer_print_str(printer, "]"); + + return printer; +error: + isl_printer_free(printer); + return NULL; +} + +void isl_vec_dump(__isl_keep isl_vec *vec) +{ + isl_printer *printer; + + if (!vec) + return; + + printer = isl_printer_to_file(vec->ctx, stderr); + printer = isl_printer_print_vec(printer, vec); + printer = isl_printer_end_line(printer); + + isl_printer_free(printer); +} + +__isl_give isl_vec *isl_vec_set(__isl_take isl_vec *vec, isl_int v) +{ + vec = isl_vec_cow(vec); + if (!vec) + return NULL; + isl_seq_set(vec->el, v, vec->size); + return vec; +} + +__isl_give isl_vec *isl_vec_set_si(__isl_take isl_vec *vec, int v) +{ + vec = isl_vec_cow(vec); + if (!vec) + return NULL; + isl_seq_set_si(vec->el, v, vec->size); + return vec; +} + +/* Replace all elements of "vec" by "v". + */ +__isl_give isl_vec *isl_vec_set_val(__isl_take isl_vec *vec, + __isl_take isl_val *v) +{ + vec = isl_vec_cow(vec); + if (!vec || !v) + goto error; + if (!isl_val_is_int(v)) + isl_die(isl_val_get_ctx(v), isl_error_invalid, + "expecting integer value", goto error); + isl_seq_set(vec->el, v->n, vec->size); + isl_val_free(v); + return vec; +error: + isl_vec_free(vec); + isl_val_free(v); + return NULL; +} + +__isl_give isl_vec *isl_vec_clr(__isl_take isl_vec *vec) +{ + vec = isl_vec_cow(vec); + if (!vec) + return NULL; + isl_seq_clr(vec->el, vec->size); + return vec; +} + +void isl_vec_lcm(__isl_keep isl_vec *vec, isl_int *lcm) +{ + isl_seq_lcm(vec->block.data, vec->size, lcm); +} + +/* Given a rational vector, with the denominator in the first element + * of the vector, round up all coordinates. + */ +__isl_give isl_vec *isl_vec_ceil(__isl_take isl_vec *vec) +{ + vec = isl_vec_cow(vec); + if (!vec) + return NULL; + + isl_seq_cdiv_q(vec->el + 1, vec->el + 1, vec->el[0], vec->size - 1); + + isl_int_set_si(vec->el[0], 1); + + return vec; +} + +__isl_give isl_vec *isl_vec_normalize(__isl_take isl_vec *vec) +{ + if (!vec) + return NULL; + isl_seq_normalize(vec->ctx, vec->el, vec->size); + return vec; +} + +__isl_give isl_vec *isl_vec_neg(__isl_take isl_vec *vec) +{ + vec = isl_vec_cow(vec); + if (!vec) + return NULL; + isl_seq_neg(vec->el, vec->el, vec->size); + return vec; +} + +__isl_give isl_vec *isl_vec_scale(__isl_take isl_vec *vec, isl_int m) +{ + if (isl_int_is_one(m)) + return vec; + vec = isl_vec_cow(vec); + if (!vec) + return NULL; + isl_seq_scale(vec->el, vec->el, m, vec->size); + return vec; +} + +/* Reduce the elements of "vec" modulo "m". + */ +__isl_give isl_vec *isl_vec_fdiv_r(__isl_take isl_vec *vec, isl_int m) +{ + vec = isl_vec_cow(vec); + if (!vec) + return NULL; + + isl_seq_fdiv_r(vec->el, vec->el, m, vec->size); + + return vec; +} + +__isl_give isl_vec *isl_vec_add(__isl_take isl_vec *vec1, + __isl_take isl_vec *vec2) +{ + vec1 = isl_vec_cow(vec1); + if (!vec1 || !vec2) + goto error; + + isl_assert(vec1->ctx, vec1->size == vec2->size, goto error); + + isl_seq_combine(vec1->el, vec1->ctx->one, vec1->el, + vec1->ctx->one, vec2->el, vec1->size); + + isl_vec_free(vec2); + return vec1; +error: + isl_vec_free(vec1); + isl_vec_free(vec2); + return NULL; +} + +static int qsort_int_cmp(const void *p1, const void *p2) +{ + const isl_int *i1 = (const isl_int *) p1; + const isl_int *i2 = (const isl_int *) p2; + + return isl_int_cmp(*i1, *i2); +} + +__isl_give isl_vec *isl_vec_sort(__isl_take isl_vec *vec) +{ + if (!vec) + return NULL; + + qsort(vec->el, vec->size, sizeof(*vec->el), &qsort_int_cmp); + + return vec; +} + +__isl_give isl_vec *isl_vec_drop_els(__isl_take isl_vec *vec, + unsigned pos, unsigned n) +{ + if (n == 0) + return vec; + vec = isl_vec_cow(vec); + if (!vec) + return NULL; + + if (pos + n > vec->size) + isl_die(vec->ctx, isl_error_invalid, + "range out of bounds", goto error); + + if (pos + n != vec->size) + isl_seq_cpy(vec->el + pos, vec->el + pos + n, + vec->size - pos - n); + + vec->size -= n; + + return vec; +error: + isl_vec_free(vec); + return NULL; +} + +__isl_give isl_vec *isl_vec_insert_els(__isl_take isl_vec *vec, + unsigned pos, unsigned n) +{ + isl_vec *ext = NULL; + + if (n == 0) + return vec; + if (!vec) + return NULL; + + if (pos > vec->size) + isl_die(vec->ctx, isl_error_invalid, + "position out of bounds", goto error); + + ext = isl_vec_alloc(vec->ctx, vec->size + n); + if (!ext) + goto error; + + isl_seq_cpy(ext->el, vec->el, pos); + isl_seq_cpy(ext->el + pos + n, vec->el + pos, vec->size - pos); + + isl_vec_free(vec); + return ext; +error: + isl_vec_free(vec); + isl_vec_free(ext); + return NULL; +} + +/* Add "n" elements at the end of "vec". + */ +__isl_give isl_vec *isl_vec_add_els(__isl_take isl_vec *vec, unsigned n) +{ + if (!vec) + return NULL; + return isl_vec_insert_els(vec, vec->size, n); +} + +__isl_give isl_vec *isl_vec_insert_zero_els(__isl_take isl_vec *vec, + unsigned pos, unsigned n) +{ + vec = isl_vec_insert_els(vec, pos, n); + if (!vec) + return NULL; + + isl_seq_clr(vec->el + pos, n); + + return vec; +} + +/* Move the "n" elements starting as "src_pos" of "vec" + * to "dst_pos". The elements originally at "dst_pos" are moved + * up or down depending on whether "dst_pos" is smaller or greater + * than "src_pos". + */ +__isl_give isl_vec *isl_vec_move_els(__isl_take isl_vec *vec, + unsigned dst_pos, unsigned src_pos, unsigned n) +{ + isl_vec *res; + + if (!vec) + return NULL; + + if (src_pos + n > vec->size) + isl_die(vec->ctx, isl_error_invalid, + "source range out of bounds", return isl_vec_free(vec)); + if (dst_pos + n > vec->size) + isl_die(vec->ctx, isl_error_invalid, + "destination range out of bounds", + return isl_vec_free(vec)); + + if (n == 0 || dst_pos == src_pos) + return vec; + + res = isl_vec_alloc(vec->ctx, vec->size); + if (!res) + return isl_vec_free(vec); + + if (dst_pos < src_pos) { + isl_seq_cpy(res->el, vec->el, dst_pos); + isl_seq_cpy(res->el + dst_pos, vec->el + src_pos, n); + isl_seq_cpy(res->el + dst_pos + n, + vec->el + dst_pos, src_pos - dst_pos); + isl_seq_cpy(res->el + src_pos + n, + vec->el + src_pos + n, res->size - src_pos - n); + } else { + isl_seq_cpy(res->el, vec->el, src_pos); + isl_seq_cpy(res->el + src_pos, + vec->el + src_pos + n, dst_pos - src_pos); + isl_seq_cpy(res->el + dst_pos, vec->el + src_pos, n); + isl_seq_cpy(res->el + dst_pos + n, + vec->el + dst_pos + n, res->size - dst_pos - n); + } + + isl_vec_free(vec); + return res; +} + +/* Reorder the elements of "vec" starting at "offset" based + * on the given reordering. + */ +__isl_give isl_vec *isl_vec_reorder(__isl_take isl_vec *vec, + unsigned offset, __isl_take isl_reordering *r) +{ + isl_vec *res; + int i; + + if (!vec || !r) + goto error; + + res = isl_vec_alloc(vec->ctx, offset + r->dst_len); + if (!res) + goto error; + isl_seq_cpy(res->el, vec->el, offset); + isl_seq_clr(res->el + offset, res->size - offset); + for (i = 0; i < r->src_len; ++i) + isl_int_set(res->el[offset + r->pos[i]], vec->el[offset + i]); + + isl_reordering_free(r); + isl_vec_free(vec); + return res; +error: + isl_vec_free(vec); + isl_reordering_free(r); + return NULL; +} diff --git a/external/mit/isl/dist/isl_vec_private.h b/external/mit/isl/dist/isl_vec_private.h new file mode 100644 index 000000000000..a46f56f88b0b --- /dev/null +++ b/external/mit/isl/dist/isl_vec_private.h @@ -0,0 +1,34 @@ +#ifndef ISL_VEC_PRIVATE_H +#define ISL_VEC_PRIVATE_H + +#include +#include + +#include "isl_reordering.h" + +struct isl_vec { + int ref; + + struct isl_ctx *ctx; + + unsigned size; + isl_int *el; + + struct isl_blk block; +}; + +uint32_t isl_vec_get_hash(__isl_keep isl_vec *vec); + +__isl_give isl_vec *isl_vec_cow(__isl_take isl_vec *vec); + +void isl_vec_lcm(__isl_keep isl_vec *vec, isl_int *lcm); +__isl_give isl_vec *isl_vec_set(__isl_take isl_vec *vec, isl_int v); + +isl_bool isl_vec_is_zero(__isl_keep isl_vec *vec); + +__isl_give isl_vec *isl_vec_expand(__isl_take isl_vec *vec, int pos, int n, + int *exp, int expanded); +__isl_give isl_vec *isl_vec_reorder(__isl_take isl_vec *vec, + unsigned offset, __isl_take isl_reordering *r); + +#endif diff --git a/external/mit/isl/dist/isl_version.c b/external/mit/isl/dist/isl_version.c new file mode 100644 index 000000000000..114323d64f23 --- /dev/null +++ b/external/mit/isl/dist/isl_version.c @@ -0,0 +1,17 @@ +#include "isl_config.h" +#include "gitversion.h" + +const char *isl_version(void) +{ + return GIT_HEAD_ID +#ifdef USE_GMP_FOR_MP + "-GMP" +#endif +#ifdef USE_IMATH_FOR_MP + "-IMath" +#ifdef USE_SMALL_INT_OPT + "-32" +#endif +#endif + "\n"; +} diff --git a/external/mit/isl/dist/isl_vertices.c b/external/mit/isl/dist/isl_vertices.c new file mode 100644 index 000000000000..37f2864fbf9e --- /dev/null +++ b/external/mit/isl/dist/isl_vertices.c @@ -0,0 +1,1626 @@ +/* + * Copyright 2010 INRIA Saclay + * + * 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 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define SELECTED 1 +#define DESELECTED -1 +#define UNSELECTED 0 + +static __isl_give isl_vertices *compute_chambers(__isl_take isl_basic_set *bset, + __isl_take isl_vertices *vertices); + +__isl_give isl_vertices *isl_vertices_copy(__isl_keep isl_vertices *vertices) +{ + if (!vertices) + return NULL; + + vertices->ref++; + return vertices; +} + +__isl_null isl_vertices *isl_vertices_free(__isl_take isl_vertices *vertices) +{ + int i; + + if (!vertices) + return NULL; + + if (--vertices->ref > 0) + return NULL; + + for (i = 0; i < vertices->n_vertices; ++i) { + isl_basic_set_free(vertices->v[i].vertex); + isl_basic_set_free(vertices->v[i].dom); + } + free(vertices->v); + + for (i = 0; i < vertices->n_chambers; ++i) { + free(vertices->c[i].vertices); + isl_basic_set_free(vertices->c[i].dom); + } + free(vertices->c); + + isl_basic_set_free(vertices->bset); + free(vertices); + + return NULL; +} + +struct isl_vertex_list { + struct isl_vertex v; + struct isl_vertex_list *next; +}; + +static struct isl_vertex_list *free_vertex_list(struct isl_vertex_list *list) +{ + struct isl_vertex_list *next; + + for (; list; list = next) { + next = list->next; + isl_basic_set_free(list->v.vertex); + isl_basic_set_free(list->v.dom); + free(list); + } + + return NULL; +} + +static __isl_give isl_vertices *vertices_from_list(__isl_keep isl_basic_set *bset, + int n_vertices, struct isl_vertex_list *list) +{ + int i; + struct isl_vertex_list *next; + isl_vertices *vertices; + + vertices = isl_calloc_type(bset->ctx, isl_vertices); + if (!vertices) + goto error; + vertices->ref = 1; + vertices->bset = isl_basic_set_copy(bset); + vertices->v = isl_alloc_array(bset->ctx, struct isl_vertex, n_vertices); + if (n_vertices && !vertices->v) + goto error; + vertices->n_vertices = n_vertices; + + for (i = 0; list; list = next, i++) { + next = list->next; + vertices->v[i] = list->v; + free(list); + } + + return vertices; +error: + isl_vertices_free(vertices); + free_vertex_list(list); + return NULL; +} + +/* Prepend a vertex to the linked list "list" based on the equalities in "tab". + * Return isl_bool_true if the vertex was actually added and + * isl_bool_false otherwise. + * In particular, vertices with a lower-dimensional activity domain are + * not added to the list because they would not be included in any chamber. + * Return isl_bool_error on error. + */ +static isl_bool add_vertex(struct isl_vertex_list **list, + __isl_keep isl_basic_set *bset, struct isl_tab *tab) +{ + isl_size nvar; + struct isl_vertex_list *v = NULL; + + if (isl_tab_detect_implicit_equalities(tab) < 0) + return isl_bool_error; + + nvar = isl_basic_set_dim(bset, isl_dim_set); + if (nvar < 0) + return isl_bool_error; + + v = isl_calloc_type(tab->mat->ctx, struct isl_vertex_list); + if (!v) + goto error; + + v->v.vertex = isl_basic_set_copy(bset); + v->v.vertex = isl_basic_set_cow(v->v.vertex); + v->v.vertex = isl_basic_set_update_from_tab(v->v.vertex, tab); + v->v.vertex = isl_basic_set_simplify(v->v.vertex); + v->v.vertex = isl_basic_set_finalize(v->v.vertex); + if (!v->v.vertex) + goto error; + isl_assert(bset->ctx, v->v.vertex->n_eq >= nvar, goto error); + v->v.dom = isl_basic_set_copy(v->v.vertex); + v->v.dom = isl_basic_set_params(v->v.dom); + if (!v->v.dom) + goto error; + + if (v->v.dom->n_eq > 0) { + free_vertex_list(v); + return isl_bool_false; + } + + v->next = *list; + *list = v; + + return isl_bool_true; +error: + free_vertex_list(v); + return isl_bool_error; +} + +/* Compute the parametric vertices and the chamber decomposition + * of an empty parametric polytope. + */ +static __isl_give isl_vertices *vertices_empty(__isl_keep isl_basic_set *bset) +{ + isl_vertices *vertices; + + if (!bset) + return NULL; + + vertices = isl_calloc_type(bset->ctx, isl_vertices); + if (!vertices) + return NULL; + vertices->bset = isl_basic_set_copy(bset); + vertices->ref = 1; + + vertices->n_vertices = 0; + vertices->n_chambers = 0; + + return vertices; +} + +/* Compute the parametric vertices and the chamber decomposition + * of the parametric polytope defined using the same constraints + * as "bset" in the 0D case. + * There is exactly one 0D vertex and a single chamber containing + * the vertex. + */ +static __isl_give isl_vertices *vertices_0D(__isl_keep isl_basic_set *bset) +{ + isl_vertices *vertices; + + if (!bset) + return NULL; + + vertices = isl_calloc_type(bset->ctx, isl_vertices); + if (!vertices) + return NULL; + vertices->ref = 1; + vertices->bset = isl_basic_set_copy(bset); + + vertices->v = isl_calloc_array(bset->ctx, struct isl_vertex, 1); + if (!vertices->v) + goto error; + vertices->n_vertices = 1; + vertices->v[0].vertex = isl_basic_set_copy(bset); + vertices->v[0].dom = isl_basic_set_params(isl_basic_set_copy(bset)); + if (!vertices->v[0].vertex || !vertices->v[0].dom) + goto error; + + vertices->c = isl_calloc_array(bset->ctx, struct isl_chamber, 1); + if (!vertices->c) + goto error; + vertices->n_chambers = 1; + vertices->c[0].n_vertices = 1; + vertices->c[0].vertices = isl_calloc_array(bset->ctx, int, 1); + if (!vertices->c[0].vertices) + goto error; + vertices->c[0].dom = isl_basic_set_copy(vertices->v[0].dom); + if (!vertices->c[0].dom) + goto error; + + return vertices; +error: + isl_vertices_free(vertices); + return NULL; +} + +/* Is the row pointed to by "f" linearly independent of the "n" first + * rows in "facets"? + */ +static isl_bool is_independent(__isl_keep isl_mat *facets, int n, isl_int *f) +{ + isl_size rank; + + if (isl_seq_first_non_zero(f, facets->n_col) < 0) + return isl_bool_false; + + isl_seq_cpy(facets->row[n], f, facets->n_col); + facets->n_row = n + 1; + rank = isl_mat_rank(facets); + if (rank < 0) + return isl_bool_error; + + return isl_bool_ok(rank == n + 1); +} + +/* Check whether we can select constraint "level", given the current selection + * reflected by facets in "tab", the rows of "facets" and the earlier + * "selected" elements of "selection". + * + * If the constraint is (strictly) redundant in the tableau, selecting it would + * result in an empty tableau, so it can't be selected. + * If the set variable part of the constraint is not linearly independent + * of the set variable parts of the already selected constraints, + * the constraint cannot be selected. + * If selecting the constraint results in an empty tableau, the constraint + * cannot be selected. + * Finally, if selecting the constraint results in some explicitly + * deselected constraints turning into equalities, then the corresponding + * vertices have already been generated, so the constraint cannot be selected. + */ +static isl_bool can_select(__isl_keep isl_basic_set *bset, int level, + struct isl_tab *tab, __isl_keep isl_mat *facets, int selected, + int *selection) +{ + int i; + isl_bool indep; + isl_size ovar; + struct isl_tab_undo *snap; + + if (isl_tab_is_redundant(tab, level)) + return isl_bool_false; + + ovar = isl_space_offset(bset->dim, isl_dim_set); + if (ovar < 0) + return isl_bool_error; + + indep = is_independent(facets, selected, bset->ineq[level] + 1 + ovar); + if (indep < 0 || !indep) + return indep; + + snap = isl_tab_snap(tab); + if (isl_tab_select_facet(tab, level) < 0) + return isl_bool_error; + + if (tab->empty) { + if (isl_tab_rollback(tab, snap) < 0) + return isl_bool_error; + return isl_bool_false; + } + + for (i = 0; i < level; ++i) { + int sgn; + + if (selection[i] != DESELECTED) + continue; + + if (isl_tab_is_equality(tab, i)) + sgn = 0; + else if (isl_tab_is_redundant(tab, i)) + sgn = 1; + else + sgn = isl_tab_sign_of_max(tab, i); + if (sgn < -1) + return isl_bool_error; + if (sgn <= 0) { + if (isl_tab_rollback(tab, snap) < 0) + return isl_bool_error; + return isl_bool_false; + } + } + + return isl_bool_true; +} + +/* Compute the parametric vertices and the chamber decomposition + * of a parametric polytope that is not full-dimensional. + * + * Simply map the parametric polytope to a lower dimensional space + * and map the resulting vertices back. + */ +static __isl_give isl_vertices *lower_dim_vertices( + __isl_take isl_basic_set *bset) +{ + isl_morph *morph; + isl_vertices *vertices; + + morph = isl_basic_set_full_compression(bset); + bset = isl_morph_basic_set(isl_morph_copy(morph), bset); + + vertices = isl_basic_set_compute_vertices(bset); + isl_basic_set_free(bset); + + morph = isl_morph_inverse(morph); + + vertices = isl_morph_vertices(morph, vertices); + + return vertices; +} + +/* Compute the parametric vertices and the chamber decomposition + * of a parametric polytope "bset" that is not full-dimensional. + * Additionally, free both "copy" and "tab". + */ +static __isl_give isl_vertices *lower_dim_vertices_free( + __isl_take isl_basic_set *bset, __isl_take isl_basic_set *copy, + struct isl_tab *tab) +{ + isl_basic_set_free(copy); + isl_tab_free(tab); + return lower_dim_vertices(bset); +} + +/* Detect implicit equality constraints in "bset" using the tableau + * representation "tab". + * Return a copy of "bset" with the implicit equality constraints + * made explicit, leaving the original "bset" unmodified. + */ +static __isl_give isl_basic_set *detect_implicit_equality_constraints( + __isl_keep isl_basic_set *bset, struct isl_tab *tab) +{ + if (isl_tab_detect_implicit_equalities(tab) < 0) + return NULL; + + bset = isl_basic_set_copy(bset); + bset = isl_basic_set_cow(bset); + bset = isl_basic_set_update_from_tab(bset, tab); + + return bset; +} + +/* Compute the parametric vertices and the chamber decomposition + * of the parametric polytope defined using the same constraints + * as "bset". "bset" is assumed to have no existentially quantified + * variables. + * + * The vertices themselves are computed in a fairly simplistic way. + * We simply run through all combinations of d constraints, + * with d the number of set variables, and check if those d constraints + * define a vertex. To avoid the generation of duplicate vertices, + * which may happen if a vertex is defined by more than d constraints, + * we make sure we only generate the vertex for the d constraints with + * smallest index. + * + * Only potential vertices with a full-dimensional activity domain + * are considered. However, if the input has (implicit) equality + * constraints among the parameters, then activity domain + * should be considered full-dimensional if it does not satisfy + * any extra equality constraints beyond those of the input. + * The implicit equality constraints of the input are therefore first detected. + * If there are any, then the input is mapped to a lower dimensional space + * such that the check for full-dimensional activity domains + * can be performed with respect to a full-dimensional space. + * Note that it is important to leave "bset" unmodified while detecting + * equality constraints since the inequality constraints of "bset" + * are assumed to correspond to those of the tableau. + * + * We set up a tableau and keep track of which facets have been + * selected. The tableau is marked strict_redundant so that we can be + * sure that any constraint that is marked redundant (and that is not + * also marked zero) is not an equality. + * If a constraint is marked DESELECTED, it means the constraint was + * SELECTED before (in combination with the same selection of earlier + * constraints). If such a deselected constraint turns out to be an + * equality, then any vertex that may still be found with the current + * selection has already been generated when the constraint was selected. + * A constraint is marked UNSELECTED when there is no way selecting + * the constraint could lead to a vertex (in combination with the current + * selection of earlier constraints). + * + * The set variable coefficients of the selected constraints are stored + * in the facets matrix. + */ +__isl_give isl_vertices *isl_basic_set_compute_vertices( + __isl_keep isl_basic_set *bset) +{ + struct isl_tab *tab; + int level; + int init; + isl_size n_eq; + isl_size nvar; + int *selection = NULL; + int selected; + struct isl_tab_undo **snap = NULL; + isl_mat *facets = NULL; + struct isl_vertex_list *list = NULL; + int n_vertices = 0; + isl_vertices *vertices; + isl_basic_set *copy; + isl_basic_set *test; + + if (!bset) + return NULL; + + if (isl_basic_set_plain_is_empty(bset)) + return vertices_empty(bset); + + if (bset->n_eq != 0) + return lower_dim_vertices(isl_basic_set_copy(bset)); + + if (isl_basic_set_check_no_locals(bset) < 0) + return NULL; + + nvar = isl_basic_set_dim(bset, isl_dim_set); + if (nvar < 0) + return NULL; + if (nvar == 0) + return vertices_0D(bset); + + copy = isl_basic_set_copy(bset); + copy = isl_basic_set_set_rational(copy); + if (!copy) + return NULL; + + tab = isl_tab_from_basic_set(copy, 0); + if (!tab) + goto error; + tab->strict_redundant = 1; + + if (tab->empty) { + vertices = vertices_empty(copy); + isl_basic_set_free(copy); + isl_tab_free(tab); + return vertices; + } + + test = detect_implicit_equality_constraints(bset, tab); + n_eq = isl_basic_set_n_equality(test); + if (n_eq < 0) + test = isl_basic_set_free(test); + if (n_eq < 0 || n_eq > 0) + return lower_dim_vertices_free(test, copy, tab); + isl_basic_set_free(test); + + selection = isl_alloc_array(copy->ctx, int, copy->n_ineq); + snap = isl_alloc_array(copy->ctx, struct isl_tab_undo *, copy->n_ineq); + facets = isl_mat_alloc(copy->ctx, nvar, nvar); + if ((copy->n_ineq && (!selection || !snap)) || !facets) + goto error; + + level = 0; + init = 1; + selected = 0; + + while (level >= 0) { + if (level >= copy->n_ineq || + (!init && selection[level] != SELECTED)) { + --level; + init = 0; + continue; + } + if (init) { + isl_bool ok; + snap[level] = isl_tab_snap(tab); + ok = can_select(copy, level, tab, facets, selected, + selection); + if (ok < 0) + goto error; + if (ok) { + selection[level] = SELECTED; + selected++; + } else + selection[level] = UNSELECTED; + } else { + selection[level] = DESELECTED; + selected--; + if (isl_tab_rollback(tab, snap[level]) < 0) + goto error; + } + if (selected == nvar) { + if (tab->n_dead == nvar) { + isl_bool added = add_vertex(&list, copy, tab); + if (added < 0) + goto error; + if (added) + n_vertices++; + } + init = 0; + continue; + } + ++level; + init = 1; + } + + isl_mat_free(facets); + free(selection); + free(snap); + + isl_tab_free(tab); + + vertices = vertices_from_list(copy, n_vertices, list); + + vertices = compute_chambers(copy, vertices); + + return vertices; +error: + free_vertex_list(list); + isl_mat_free(facets); + free(selection); + free(snap); + isl_tab_free(tab); + isl_basic_set_free(copy); + return NULL; +} + +struct isl_chamber_list { + struct isl_chamber c; + struct isl_chamber_list *next; +}; + +static void free_chamber_list(struct isl_chamber_list *list) +{ + struct isl_chamber_list *next; + + for (; list; list = next) { + next = list->next; + isl_basic_set_free(list->c.dom); + free(list->c.vertices); + free(list); + } +} + +/* Check whether the basic set "bset" is a superset of the basic set described + * by "tab", i.e., check whether all constraints of "bset" are redundant. + */ +static isl_bool bset_covers_tab(__isl_keep isl_basic_set *bset, + struct isl_tab *tab) +{ + int i; + + if (!bset || !tab) + return isl_bool_error; + + for (i = 0; i < bset->n_ineq; ++i) { + enum isl_ineq_type type = isl_tab_ineq_type(tab, bset->ineq[i]); + switch (type) { + case isl_ineq_error: return isl_bool_error; + case isl_ineq_redundant: continue; + default: return isl_bool_false; + } + } + + return isl_bool_true; +} + +static __isl_give isl_vertices *vertices_add_chambers( + __isl_take isl_vertices *vertices, int n_chambers, + struct isl_chamber_list *list) +{ + int i; + isl_ctx *ctx; + struct isl_chamber_list *next; + + ctx = isl_vertices_get_ctx(vertices); + vertices->c = isl_alloc_array(ctx, struct isl_chamber, n_chambers); + if (!vertices->c) + goto error; + vertices->n_chambers = n_chambers; + + for (i = 0; list; list = next, i++) { + next = list->next; + vertices->c[i] = list->c; + free(list); + } + + return vertices; +error: + isl_vertices_free(vertices); + free_chamber_list(list); + return NULL; +} + +/* Can "tab" be intersected with "bset" without resulting in + * a lower-dimensional set. + * "bset" itself is assumed to be full-dimensional. + */ +static isl_bool can_intersect(struct isl_tab *tab, + __isl_keep isl_basic_set *bset) +{ + int i; + struct isl_tab_undo *snap; + + if (bset->n_eq > 0) + isl_die(isl_basic_set_get_ctx(bset), isl_error_internal, + "expecting full-dimensional input", + return isl_bool_error); + + if (isl_tab_extend_cons(tab, bset->n_ineq) < 0) + return isl_bool_error; + + snap = isl_tab_snap(tab); + + for (i = 0; i < bset->n_ineq; ++i) { + enum isl_ineq_type type; + + type = isl_tab_ineq_type(tab, bset->ineq[i]); + if (type < 0) + return isl_bool_error; + if (type == isl_ineq_redundant) + continue; + if (isl_tab_add_ineq(tab, bset->ineq[i]) < 0) + return isl_bool_error; + } + + if (isl_tab_detect_implicit_equalities(tab) < 0) + return isl_bool_error; + if (tab->n_dead) { + if (isl_tab_rollback(tab, snap) < 0) + return isl_bool_error; + return isl_bool_false; + } + + return isl_bool_true; +} + +static int add_chamber(struct isl_chamber_list **list, + __isl_keep isl_vertices *vertices, struct isl_tab *tab, int *selection) +{ + int n_frozen; + int i, j; + int n_vertices = 0; + struct isl_tab_undo *snap; + struct isl_chamber_list *c = NULL; + + for (i = 0; i < vertices->n_vertices; ++i) + if (selection[i]) + n_vertices++; + + snap = isl_tab_snap(tab); + + for (i = 0; i < tab->n_con && tab->con[i].frozen; ++i) + tab->con[i].frozen = 0; + n_frozen = i; + + if (isl_tab_detect_redundant(tab) < 0) + return -1; + + c = isl_calloc_type(tab->mat->ctx, struct isl_chamber_list); + if (!c) + goto error; + c->c.vertices = isl_alloc_array(tab->mat->ctx, int, n_vertices); + if (n_vertices && !c->c.vertices) + goto error; + c->c.dom = isl_basic_set_copy(isl_tab_peek_bset(tab)); + c->c.dom = isl_basic_set_set_rational(c->c.dom); + c->c.dom = isl_basic_set_cow(c->c.dom); + c->c.dom = isl_basic_set_update_from_tab(c->c.dom, tab); + c->c.dom = isl_basic_set_simplify(c->c.dom); + c->c.dom = isl_basic_set_finalize(c->c.dom); + if (!c->c.dom) + goto error; + + c->c.n_vertices = n_vertices; + + for (i = 0, j = 0; i < vertices->n_vertices; ++i) + if (selection[i]) { + c->c.vertices[j] = i; + j++; + } + + c->next = *list; + *list = c; + + for (i = 0; i < n_frozen; ++i) + tab->con[i].frozen = 1; + + if (isl_tab_rollback(tab, snap) < 0) + return -1; + + return 0; +error: + free_chamber_list(c); + return -1; +} + +struct isl_facet_todo { + struct isl_tab *tab; /* A tableau representation of the facet */ + isl_basic_set *bset; /* A normalized basic set representation */ + isl_vec *constraint; /* Constraint pointing to the other side */ + struct isl_facet_todo *next; +}; + +static void free_todo(struct isl_facet_todo *todo) +{ + while (todo) { + struct isl_facet_todo *next = todo->next; + + isl_tab_free(todo->tab); + isl_basic_set_free(todo->bset); + isl_vec_free(todo->constraint); + free(todo); + + todo = next; + } +} + +static struct isl_facet_todo *create_todo(struct isl_tab *tab, int con) +{ + int i; + int n_frozen; + struct isl_tab_undo *snap; + struct isl_facet_todo *todo; + + snap = isl_tab_snap(tab); + + for (i = 0; i < tab->n_con && tab->con[i].frozen; ++i) + tab->con[i].frozen = 0; + n_frozen = i; + + if (isl_tab_detect_redundant(tab) < 0) + return NULL; + + todo = isl_calloc_type(tab->mat->ctx, struct isl_facet_todo); + if (!todo) + return NULL; + + todo->constraint = isl_vec_alloc(tab->mat->ctx, 1 + tab->n_var); + if (!todo->constraint) + goto error; + isl_seq_neg(todo->constraint->el, tab->bmap->ineq[con], 1 + tab->n_var); + todo->bset = isl_basic_set_copy(isl_tab_peek_bset(tab)); + todo->bset = isl_basic_set_set_rational(todo->bset); + todo->bset = isl_basic_set_cow(todo->bset); + todo->bset = isl_basic_set_update_from_tab(todo->bset, tab); + todo->bset = isl_basic_set_simplify(todo->bset); + todo->bset = isl_basic_set_sort_constraints(todo->bset); + if (!todo->bset) + goto error; + ISL_F_SET(todo->bset, ISL_BASIC_SET_NO_REDUNDANT); + todo->tab = isl_tab_dup(tab); + if (!todo->tab) + goto error; + + for (i = 0; i < n_frozen; ++i) + tab->con[i].frozen = 1; + + if (isl_tab_rollback(tab, snap) < 0) + goto error; + + return todo; +error: + free_todo(todo); + return NULL; +} + +/* Create todo items for all interior facets of the chamber represented + * by "tab" and collect them in "next". + */ +static int init_todo(struct isl_facet_todo **next, struct isl_tab *tab) +{ + int i; + struct isl_tab_undo *snap; + struct isl_facet_todo *todo; + + snap = isl_tab_snap(tab); + + for (i = 0; i < tab->n_con; ++i) { + if (tab->con[i].frozen) + continue; + if (tab->con[i].is_redundant) + continue; + + if (isl_tab_select_facet(tab, i) < 0) + return -1; + + todo = create_todo(tab, i); + if (!todo) + return -1; + + todo->next = *next; + *next = todo; + + if (isl_tab_rollback(tab, snap) < 0) + return -1; + } + + return 0; +} + +/* Does the linked list contain a todo item that is the opposite of "todo". + * If so, return 1 and remove the opposite todo item. + */ +static int has_opposite(struct isl_facet_todo *todo, + struct isl_facet_todo **list) +{ + for (; *list; list = &(*list)->next) { + int eq; + eq = isl_basic_set_plain_is_equal(todo->bset, (*list)->bset); + if (eq < 0) + return -1; + if (!eq) + continue; + todo = *list; + *list = todo->next; + todo->next = NULL; + free_todo(todo); + return 1; + } + + return 0; +} + +/* Create todo items for all interior facets of the chamber represented + * by "tab" and collect them in first->next, taking care to cancel + * opposite todo items. + */ +static int update_todo(struct isl_facet_todo *first, struct isl_tab *tab) +{ + int i; + struct isl_tab_undo *snap; + struct isl_facet_todo *todo; + + snap = isl_tab_snap(tab); + + for (i = 0; i < tab->n_con; ++i) { + int drop; + + if (tab->con[i].frozen) + continue; + if (tab->con[i].is_redundant) + continue; + + if (isl_tab_select_facet(tab, i) < 0) + return -1; + + todo = create_todo(tab, i); + if (!todo) + return -1; + + drop = has_opposite(todo, &first->next); + if (drop < 0) + return -1; + + if (drop) + free_todo(todo); + else { + todo->next = first->next; + first->next = todo; + } + + if (isl_tab_rollback(tab, snap) < 0) + return -1; + } + + return 0; +} + +/* Compute the chamber decomposition of the parametric polytope respresented + * by "bset" given the parametric vertices and their activity domains. + * + * We are only interested in full-dimensional chambers. + * Each of these chambers is the intersection of the activity domains of + * one or more vertices and the union of all chambers is equal to the + * projection of the entire parametric polytope onto the parameter space. + * + * We first create an initial chamber by intersecting as many activity + * domains as possible without ending up with an empty or lower-dimensional + * set. As a minor optimization, we only consider those activity domains + * that contain some arbitrary point. + * + * For each of the interior facets of the chamber, we construct a todo item, + * containing the facet and a constraint containing the other side of the facet, + * for constructing the chamber on the other side. + * While their are any todo items left, we pick a todo item and + * create the required chamber by intersecting all activity domains + * that contain the facet and have a full-dimensional intersection with + * the other side of the facet. For each of the interior facets, we + * again create todo items, taking care to cancel opposite todo items. + */ +static __isl_give isl_vertices *compute_chambers(__isl_take isl_basic_set *bset, + __isl_take isl_vertices *vertices) +{ + int i; + isl_ctx *ctx; + isl_size n_eq; + isl_vec *sample = NULL; + struct isl_tab *tab = NULL; + struct isl_tab_undo *snap; + int *selection = NULL; + int n_chambers = 0; + struct isl_chamber_list *list = NULL; + struct isl_facet_todo *todo = NULL; + + if (!bset || !vertices) + goto error; + + ctx = isl_vertices_get_ctx(vertices); + selection = isl_alloc_array(ctx, int, vertices->n_vertices); + if (vertices->n_vertices && !selection) + goto error; + + bset = isl_basic_set_params(bset); + n_eq = isl_basic_set_n_equality(bset); + if (n_eq < 0) + goto error; + if (n_eq > 0) + isl_die(isl_basic_set_get_ctx(bset), isl_error_internal, + "expecting full-dimensional input", goto error); + + tab = isl_tab_from_basic_set(bset, 1); + if (!tab) + goto error; + for (i = 0; i < bset->n_ineq; ++i) + if (isl_tab_freeze_constraint(tab, i) < 0) + goto error; + isl_basic_set_free(bset); + + snap = isl_tab_snap(tab); + + sample = isl_tab_get_sample_value(tab); + + for (i = 0; i < vertices->n_vertices; ++i) { + selection[i] = isl_basic_set_contains(vertices->v[i].dom, sample); + if (selection[i] < 0) + goto error; + if (!selection[i]) + continue; + selection[i] = can_intersect(tab, vertices->v[i].dom); + if (selection[i] < 0) + goto error; + } + + if (isl_tab_detect_redundant(tab) < 0) + goto error; + + if (add_chamber(&list, vertices, tab, selection) < 0) + goto error; + n_chambers++; + + if (init_todo(&todo, tab) < 0) + goto error; + + while (todo) { + struct isl_facet_todo *next; + + if (isl_tab_rollback(tab, snap) < 0) + goto error; + + if (isl_tab_add_ineq(tab, todo->constraint->el) < 0) + goto error; + if (isl_tab_freeze_constraint(tab, tab->n_con - 1) < 0) + goto error; + + for (i = 0; i < vertices->n_vertices; ++i) { + selection[i] = bset_covers_tab(vertices->v[i].dom, + todo->tab); + if (selection[i] < 0) + goto error; + if (!selection[i]) + continue; + selection[i] = can_intersect(tab, vertices->v[i].dom); + if (selection[i] < 0) + goto error; + } + + if (isl_tab_detect_redundant(tab) < 0) + goto error; + + if (add_chamber(&list, vertices, tab, selection) < 0) + goto error; + n_chambers++; + + if (update_todo(todo, tab) < 0) + goto error; + + next = todo->next; + todo->next = NULL; + free_todo(todo); + todo = next; + } + + isl_vec_free(sample); + + isl_tab_free(tab); + free(selection); + + vertices = vertices_add_chambers(vertices, n_chambers, list); + + for (i = 0; vertices && i < vertices->n_vertices; ++i) { + isl_basic_set_free(vertices->v[i].dom); + vertices->v[i].dom = NULL; + } + + return vertices; +error: + free_chamber_list(list); + free_todo(todo); + isl_vec_free(sample); + isl_tab_free(tab); + free(selection); + if (!tab) + isl_basic_set_free(bset); + isl_vertices_free(vertices); + return NULL; +} + +isl_ctx *isl_vertex_get_ctx(__isl_keep isl_vertex *vertex) +{ + return vertex ? isl_vertices_get_ctx(vertex->vertices) : NULL; +} + +isl_size isl_vertex_get_id(__isl_keep isl_vertex *vertex) +{ + return vertex ? vertex->id : isl_size_error; +} + +/* Return the activity domain of the vertex "vertex". + */ +__isl_give isl_basic_set *isl_vertex_get_domain(__isl_keep isl_vertex *vertex) +{ + struct isl_vertex *v; + + if (!vertex) + return NULL; + + v = &vertex->vertices->v[vertex->id]; + if (!v->dom) { + v->dom = isl_basic_set_copy(v->vertex); + v->dom = isl_basic_set_params(v->dom); + v->dom = isl_basic_set_set_integral(v->dom); + } + + return isl_basic_set_copy(v->dom); +} + +/* Return a multiple quasi-affine expression describing the vertex "vertex" + * in terms of the parameters, + */ +__isl_give isl_multi_aff *isl_vertex_get_expr(__isl_keep isl_vertex *vertex) +{ + struct isl_vertex *v; + isl_basic_set *bset; + + if (!vertex) + return NULL; + + v = &vertex->vertices->v[vertex->id]; + + bset = isl_basic_set_copy(v->vertex); + return isl_multi_aff_from_basic_set_equalities(bset); +} + +static __isl_give isl_vertex *isl_vertex_alloc(__isl_take isl_vertices *vertices, + int id) +{ + isl_ctx *ctx; + isl_vertex *vertex; + + if (!vertices) + return NULL; + + ctx = isl_vertices_get_ctx(vertices); + vertex = isl_alloc_type(ctx, isl_vertex); + if (!vertex) + goto error; + + vertex->vertices = vertices; + vertex->id = id; + + return vertex; +error: + isl_vertices_free(vertices); + return NULL; +} + +__isl_null isl_vertex *isl_vertex_free(__isl_take isl_vertex *vertex) +{ + if (!vertex) + return NULL; + isl_vertices_free(vertex->vertices); + free(vertex); + + return NULL; +} + +isl_ctx *isl_cell_get_ctx(__isl_keep isl_cell *cell) +{ + return cell ? cell->dom->ctx : NULL; +} + +__isl_give isl_basic_set *isl_cell_get_domain(__isl_keep isl_cell *cell) +{ + return cell ? isl_basic_set_copy(cell->dom) : NULL; +} + +static __isl_give isl_cell *isl_cell_alloc(__isl_take isl_vertices *vertices, + __isl_take isl_basic_set *dom, int id) +{ + int i; + isl_cell *cell = NULL; + + if (!vertices || !dom) + goto error; + + cell = isl_calloc_type(dom->ctx, isl_cell); + if (!cell) + goto error; + + cell->n_vertices = vertices->c[id].n_vertices; + cell->ids = isl_alloc_array(dom->ctx, int, cell->n_vertices); + if (cell->n_vertices && !cell->ids) + goto error; + for (i = 0; i < cell->n_vertices; ++i) + cell->ids[i] = vertices->c[id].vertices[i]; + cell->vertices = vertices; + cell->dom = dom; + + return cell; +error: + isl_cell_free(cell); + isl_vertices_free(vertices); + isl_basic_set_free(dom); + return NULL; +} + +__isl_null isl_cell *isl_cell_free(__isl_take isl_cell *cell) +{ + if (!cell) + return NULL; + + isl_vertices_free(cell->vertices); + free(cell->ids); + isl_basic_set_free(cell->dom); + free(cell); + + return NULL; +} + +/* Create a tableau of the cone obtained by first homogenizing the given + * polytope and then making all inequalities strict by setting the + * constant term to -1. + */ +static struct isl_tab *tab_for_shifted_cone(__isl_keep isl_basic_set *bset) +{ + int i; + isl_vec *c = NULL; + struct isl_tab *tab; + isl_size total; + + total = isl_basic_set_dim(bset, isl_dim_all); + if (total < 0) + return NULL; + tab = isl_tab_alloc(bset->ctx, bset->n_eq + bset->n_ineq + 1, + 1 + total, 0); + if (!tab) + return NULL; + tab->rational = ISL_F_ISSET(bset, ISL_BASIC_SET_RATIONAL); + if (ISL_F_ISSET(bset, ISL_BASIC_MAP_EMPTY)) { + if (isl_tab_mark_empty(tab) < 0) + goto error; + return tab; + } + + c = isl_vec_alloc(bset->ctx, 1 + 1 + total); + if (!c) + goto error; + + isl_int_set_si(c->el[0], 0); + for (i = 0; i < bset->n_eq; ++i) { + isl_seq_cpy(c->el + 1, bset->eq[i], c->size - 1); + if (isl_tab_add_eq(tab, c->el) < 0) + goto error; + } + + isl_int_set_si(c->el[0], -1); + for (i = 0; i < bset->n_ineq; ++i) { + isl_seq_cpy(c->el + 1, bset->ineq[i], c->size - 1); + if (isl_tab_add_ineq(tab, c->el) < 0) + goto error; + if (tab->empty) { + isl_vec_free(c); + return tab; + } + } + + isl_seq_clr(c->el + 1, c->size - 1); + isl_int_set_si(c->el[1], 1); + if (isl_tab_add_ineq(tab, c->el) < 0) + goto error; + + isl_vec_free(c); + return tab; +error: + isl_vec_free(c); + isl_tab_free(tab); + return NULL; +} + +/* Compute an interior point of "bset" by selecting an interior + * point in homogeneous space and projecting the point back down. + */ +static __isl_give isl_vec *isl_basic_set_interior_point( + __isl_keep isl_basic_set *bset) +{ + isl_vec *vec; + struct isl_tab *tab; + + tab = tab_for_shifted_cone(bset); + vec = isl_tab_get_sample_value(tab); + isl_tab_free(tab); + if (!vec) + return NULL; + + isl_seq_cpy(vec->el, vec->el + 1, vec->size - 1); + vec->size--; + + return vec; +} + +/* Call "fn" on all chambers of the parametric polytope with the shared + * facets of neighboring chambers only appearing in one of the chambers. + * + * We pick an interior point from one of the chambers and then make + * all constraints that do not satisfy this point strict. + * For constraints that saturate the interior point, the sign + * of the first non-zero coefficient is used to determine which + * of the two (internal) constraints should be tightened. + */ +isl_stat isl_vertices_foreach_disjoint_cell(__isl_keep isl_vertices *vertices, + isl_stat (*fn)(__isl_take isl_cell *cell, void *user), void *user) +{ + int i; + isl_vec *vec; + isl_cell *cell; + + if (!vertices) + return isl_stat_error; + + if (vertices->n_chambers == 0) + return isl_stat_ok; + + if (vertices->n_chambers == 1) { + isl_basic_set *dom = isl_basic_set_copy(vertices->c[0].dom); + dom = isl_basic_set_set_integral(dom); + cell = isl_cell_alloc(isl_vertices_copy(vertices), dom, 0); + if (!cell) + return isl_stat_error; + return fn(cell, user); + } + + vec = isl_basic_set_interior_point(vertices->c[0].dom); + if (!vec) + return isl_stat_error; + + for (i = 0; i < vertices->n_chambers; ++i) { + int r; + isl_basic_set *dom = isl_basic_set_copy(vertices->c[i].dom); + if (i) + dom = isl_basic_set_tighten_outward(dom, vec); + dom = isl_basic_set_set_integral(dom); + cell = isl_cell_alloc(isl_vertices_copy(vertices), dom, i); + if (!cell) + goto error; + r = fn(cell, user); + if (r < 0) + goto error; + } + + isl_vec_free(vec); + + return isl_stat_ok; +error: + isl_vec_free(vec); + return isl_stat_error; +} + +isl_stat isl_vertices_foreach_cell(__isl_keep isl_vertices *vertices, + isl_stat (*fn)(__isl_take isl_cell *cell, void *user), void *user) +{ + int i; + isl_cell *cell; + + if (!vertices) + return isl_stat_error; + + if (vertices->n_chambers == 0) + return isl_stat_ok; + + for (i = 0; i < vertices->n_chambers; ++i) { + isl_stat r; + isl_basic_set *dom = isl_basic_set_copy(vertices->c[i].dom); + + cell = isl_cell_alloc(isl_vertices_copy(vertices), dom, i); + if (!cell) + return isl_stat_error; + + r = fn(cell, user); + if (r < 0) + return isl_stat_error; + } + + return isl_stat_ok; +} + +isl_stat isl_vertices_foreach_vertex(__isl_keep isl_vertices *vertices, + isl_stat (*fn)(__isl_take isl_vertex *vertex, void *user), void *user) +{ + int i; + isl_vertex *vertex; + + if (!vertices) + return isl_stat_error; + + if (vertices->n_vertices == 0) + return isl_stat_ok; + + for (i = 0; i < vertices->n_vertices; ++i) { + isl_stat r; + + vertex = isl_vertex_alloc(isl_vertices_copy(vertices), i); + if (!vertex) + return isl_stat_error; + + r = fn(vertex, user); + if (r < 0) + return isl_stat_error; + } + + return isl_stat_ok; +} + +isl_stat isl_cell_foreach_vertex(__isl_keep isl_cell *cell, + isl_stat (*fn)(__isl_take isl_vertex *vertex, void *user), void *user) +{ + int i; + isl_vertex *vertex; + + if (!cell) + return isl_stat_error; + + if (cell->n_vertices == 0) + return isl_stat_ok; + + for (i = 0; i < cell->n_vertices; ++i) { + isl_stat r; + + vertex = isl_vertex_alloc(isl_vertices_copy(cell->vertices), + cell->ids[i]); + if (!vertex) + return isl_stat_error; + + r = fn(vertex, user); + if (r < 0) + return isl_stat_error; + } + + return isl_stat_ok; +} + +isl_ctx *isl_vertices_get_ctx(__isl_keep isl_vertices *vertices) +{ + return vertices ? vertices->bset->ctx : NULL; +} + +isl_size isl_vertices_get_n_vertices(__isl_keep isl_vertices *vertices) +{ + return vertices ? vertices->n_vertices : isl_size_error; +} + +__isl_give isl_vertices *isl_morph_vertices(__isl_take isl_morph *morph, + __isl_take isl_vertices *vertices) +{ + int i; + isl_morph *param_morph = NULL; + + if (!morph || !vertices) + goto error; + + isl_assert(vertices->bset->ctx, vertices->ref == 1, goto error); + + param_morph = isl_morph_copy(morph); + param_morph = isl_morph_dom_params(param_morph); + param_morph = isl_morph_ran_params(param_morph); + + for (i = 0; i < vertices->n_vertices; ++i) { + vertices->v[i].dom = isl_morph_basic_set( + isl_morph_copy(param_morph), vertices->v[i].dom); + vertices->v[i].vertex = isl_morph_basic_set( + isl_morph_copy(morph), vertices->v[i].vertex); + if (!vertices->v[i].vertex) + goto error; + } + + for (i = 0; i < vertices->n_chambers; ++i) { + vertices->c[i].dom = isl_morph_basic_set( + isl_morph_copy(param_morph), vertices->c[i].dom); + if (!vertices->c[i].dom) + goto error; + } + + isl_morph_free(param_morph); + isl_morph_free(morph); + return vertices; +error: + isl_morph_free(param_morph); + isl_morph_free(morph); + isl_vertices_free(vertices); + return NULL; +} + +/* Construct a simplex isl_cell spanned by the vertices with indices in + * "simplex_ids" and "other_ids" and call "fn" on this isl_cell. + */ +static isl_stat call_on_simplex(__isl_keep isl_cell *cell, + int *simplex_ids, int n_simplex, int *other_ids, int n_other, + isl_stat (*fn)(__isl_take isl_cell *simplex, void *user), void *user) +{ + int i; + isl_ctx *ctx; + struct isl_cell *simplex; + + ctx = isl_cell_get_ctx(cell); + + simplex = isl_calloc_type(ctx, struct isl_cell); + if (!simplex) + return isl_stat_error; + simplex->vertices = isl_vertices_copy(cell->vertices); + if (!simplex->vertices) + goto error; + simplex->dom = isl_basic_set_copy(cell->dom); + if (!simplex->dom) + goto error; + simplex->n_vertices = n_simplex + n_other; + simplex->ids = isl_alloc_array(ctx, int, simplex->n_vertices); + if (!simplex->ids) + goto error; + + for (i = 0; i < n_simplex; ++i) + simplex->ids[i] = simplex_ids[i]; + for (i = 0; i < n_other; ++i) + simplex->ids[n_simplex + i] = other_ids[i]; + + return fn(simplex, user); +error: + isl_cell_free(simplex); + return isl_stat_error; +} + +/* Check whether the parametric vertex described by "vertex" + * lies on the facet corresponding to constraint "facet" of "bset". + * The isl_vec "v" is a temporary vector than can be used by this function. + * + * We eliminate the variables from the facet constraint using the + * equalities defining the vertex and check if the result is identical + * to zero. + * + * It would probably be better to keep track of the constraints defining + * a vertex during the vertex construction so that we could simply look + * it up here. + */ +static int vertex_on_facet(__isl_keep isl_basic_set *vertex, + __isl_keep isl_basic_set *bset, int facet, __isl_keep isl_vec *v) +{ + int i; + isl_int m; + + isl_seq_cpy(v->el, bset->ineq[facet], v->size); + + isl_int_init(m); + for (i = 0; i < vertex->n_eq; ++i) { + int k = isl_seq_last_non_zero(vertex->eq[i], v->size); + isl_seq_elim(v->el, vertex->eq[i], k, v->size, &m); + } + isl_int_clear(m); + + return isl_seq_first_non_zero(v->el, v->size) == -1; +} + +/* Triangulate the polytope spanned by the vertices with ids + * in "simplex_ids" and "other_ids" and call "fn" on each of + * the resulting simplices. + * If the input polytope is already a simplex, we simply call "fn". + * Otherwise, we pick a point from "other_ids" and add it to "simplex_ids". + * Then we consider each facet of "bset" that does not contain the point + * we just picked, but does contain some of the other points in "other_ids" + * and call ourselves recursively on the polytope spanned by the new + * "simplex_ids" and those points in "other_ids" that lie on the facet. + */ +static isl_stat triangulate(__isl_keep isl_cell *cell, __isl_keep isl_vec *v, + int *simplex_ids, int n_simplex, int *other_ids, int n_other, + isl_stat (*fn)(__isl_take isl_cell *simplex, void *user), void *user) +{ + int i, j, k; + isl_size d, nparam; + int *ids; + isl_ctx *ctx; + isl_basic_set *vertex; + isl_basic_set *bset; + + ctx = isl_cell_get_ctx(cell); + d = isl_basic_set_dim(cell->vertices->bset, isl_dim_set); + nparam = isl_basic_set_dim(cell->vertices->bset, isl_dim_param); + if (d < 0 || nparam < 0) + return isl_stat_error; + + if (n_simplex + n_other == d + 1) + return call_on_simplex(cell, simplex_ids, n_simplex, + other_ids, n_other, fn, user); + + simplex_ids[n_simplex] = other_ids[0]; + vertex = cell->vertices->v[other_ids[0]].vertex; + bset = cell->vertices->bset; + + ids = isl_alloc_array(ctx, int, n_other - 1); + if (!ids) + goto error; + for (i = 0; i < bset->n_ineq; ++i) { + if (isl_seq_first_non_zero(bset->ineq[i] + 1 + nparam, d) == -1) + continue; + if (vertex_on_facet(vertex, bset, i, v)) + continue; + + for (j = 1, k = 0; j < n_other; ++j) { + isl_basic_set *ov; + ov = cell->vertices->v[other_ids[j]].vertex; + if (vertex_on_facet(ov, bset, i, v)) + ids[k++] = other_ids[j]; + } + if (k == 0) + continue; + + if (triangulate(cell, v, simplex_ids, n_simplex + 1, + ids, k, fn, user) < 0) + goto error; + } + free(ids); + + return isl_stat_ok; +error: + free(ids); + return isl_stat_error; +} + +/* Triangulate the given cell and call "fn" on each of the resulting + * simplices. + */ +isl_stat isl_cell_foreach_simplex(__isl_take isl_cell *cell, + isl_stat (*fn)(__isl_take isl_cell *simplex, void *user), void *user) +{ + isl_size d, total; + isl_stat r; + isl_ctx *ctx; + isl_vec *v = NULL; + int *simplex_ids = NULL; + + if (!cell) + return isl_stat_error; + + d = isl_basic_set_dim(cell->vertices->bset, isl_dim_set); + total = isl_basic_set_dim(cell->vertices->bset, isl_dim_all); + if (d < 0 || total < 0) + return isl_stat_error; + + if (cell->n_vertices == d + 1) + return fn(cell, user); + + ctx = isl_cell_get_ctx(cell); + simplex_ids = isl_alloc_array(ctx, int, d + 1); + if (!simplex_ids) + goto error; + + v = isl_vec_alloc(ctx, 1 + total); + if (!v) + goto error; + + r = triangulate(cell, v, simplex_ids, 0, + cell->ids, cell->n_vertices, fn, user); + + isl_vec_free(v); + free(simplex_ids); + + isl_cell_free(cell); + + return r; +error: + free(simplex_ids); + isl_vec_free(v); + isl_cell_free(cell); + return isl_stat_error; +} diff --git a/external/mit/isl/dist/isl_vertices_private.h b/external/mit/isl/dist/isl_vertices_private.h new file mode 100644 index 000000000000..37e640755087 --- /dev/null +++ b/external/mit/isl/dist/isl_vertices_private.h @@ -0,0 +1,71 @@ +#ifndef ISL_VERTICES_PRIVATE_H +#define ISL_VERTICES_PRIVATE_H + +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +struct isl_morph; + +/* A parametric vertex. "vertex" contains the actual description + * of the vertex as a singleton parametric set. "dom" is the projection + * of "vertex" onto the parameter space, i.e., the activity domain + * of the vertex. + * During the construction of vertices and chambers, the activity domain + * of every parametric vertex is full-dimensional. + */ +struct isl_vertex { + isl_basic_set *dom; + isl_basic_set *vertex; +}; + +/* A chamber in the chamber decomposition. The indices of the "n_vertices" + * active vertices are stored in "vertices". + */ +struct isl_chamber { + int n_vertices; + int *vertices; + isl_basic_set *dom; +}; + +struct isl_vertices { + int ref; + + /* The rational basic set spanned by the vertices. */ + isl_basic_set *bset; + + int n_vertices; + struct isl_vertex *v; + + int n_chambers; + struct isl_chamber *c; +}; + +struct isl_cell { + int n_vertices; + int *ids; + isl_vertices *vertices; + isl_basic_set *dom; +}; + +struct isl_external_vertex { + isl_vertices *vertices; + int id; +}; + +isl_stat isl_vertices_foreach_disjoint_cell(__isl_keep isl_vertices *vertices, + isl_stat (*fn)(__isl_take isl_cell *cell, void *user), void *user); +isl_stat isl_cell_foreach_simplex(__isl_take isl_cell *cell, + isl_stat (*fn)(__isl_take isl_cell *simplex, void *user), void *user); + +__isl_give isl_vertices *isl_morph_vertices(__isl_take struct isl_morph *morph, + __isl_take isl_vertices *vertices); + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/external/mit/isl/dist/isl_yaml.h b/external/mit/isl/dist/isl_yaml.h new file mode 100644 index 000000000000..4d2c442ac505 --- /dev/null +++ b/external/mit/isl/dist/isl_yaml.h @@ -0,0 +1,18 @@ +#ifndef ISL_YAML_H +#define ISL_YAML_H + +#define ISL_YAML_INDENT_FLOW -1 + +enum isl_yaml_state { + isl_yaml_none, + isl_yaml_mapping_first_key_start, + isl_yaml_mapping_key_start, + isl_yaml_mapping_key, + isl_yaml_mapping_val_start, + isl_yaml_mapping_val, + isl_yaml_sequence_first_start, + isl_yaml_sequence_start, + isl_yaml_sequence +}; + +#endif diff --git a/external/mit/isl/dist/libisl-gdb.py b/external/mit/isl/dist/libisl-gdb.py new file mode 100644 index 000000000000..fd15626c7739 --- /dev/null +++ b/external/mit/isl/dist/libisl-gdb.py @@ -0,0 +1,100 @@ +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) diff --git a/external/mit/isl/dist/ltmain.sh b/external/mit/isl/dist/ltmain.sh new file mode 100755 index 000000000000..540a92ab5476 --- /dev/null +++ b/external/mit/isl/dist/ltmain.sh @@ -0,0 +1,11251 @@ +#! /bin/sh +## DO NOT EDIT - This file generated from ./build-aux/ltmain.in +## by inline-source v2014-01-03.01 + +# libtool (GNU libtool) 2.4.6 +# Provide generalized library-building support services. +# Written by Gordon Matzigkeit , 1996 + +# Copyright (C) 1996-2015 Free Software Foundation, Inc. +# This is free software; see the source for copying conditions. There is NO +# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +# GNU Libtool is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# As a special exception to the GNU General Public License, +# if you distribute this file as part of a program or library that +# is built using GNU Libtool, you may include this file under the +# same distribution terms that you use for the rest of that program. +# +# GNU Libtool is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + + +PROGRAM=libtool +PACKAGE=libtool +VERSION="2.4.6 Debian-2.4.6-15build2" +package_revision=2.4.6 + + +## ------ ## +## Usage. ## +## ------ ## + +# Run './libtool --help' for help with using this script from the +# command line. + + +## ------------------------------- ## +## User overridable command paths. ## +## ------------------------------- ## + +# After configure completes, it has a better idea of some of the +# shell tools we need than the defaults used by the functions shared +# with bootstrap, so set those here where they can still be over- +# ridden by the user, but otherwise take precedence. + +: ${AUTOCONF="autoconf"} +: ${AUTOMAKE="automake"} + + +## -------------------------- ## +## Source external libraries. ## +## -------------------------- ## + +# Much of our low-level functionality needs to be sourced from external +# libraries, which are installed to $pkgauxdir. + +# Set a version string for this script. +scriptversion=2015-01-20.17; # UTC + +# General shell script boiler plate, and helper functions. +# Written by Gary V. Vaughan, 2004 + +# Copyright (C) 2004-2015 Free Software Foundation, Inc. +# This is free software; see the source for copying conditions. There is NO +# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. + +# As a special exception to the GNU General Public License, if you distribute +# this file as part of a program or library that is built using GNU Libtool, +# you may include this file under the same distribution terms that you use +# for the rest of that program. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNES FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# Please report bugs or propose patches to gary@gnu.org. + + +## ------ ## +## Usage. ## +## ------ ## + +# Evaluate this file near the top of your script to gain access to +# the functions and variables defined here: +# +# . `echo "$0" | ${SED-sed} 's|[^/]*$||'`/build-aux/funclib.sh +# +# If you need to override any of the default environment variable +# settings, do that before evaluating this file. + + +## -------------------- ## +## Shell normalisation. ## +## -------------------- ## + +# Some shells need a little help to be as Bourne compatible as possible. +# Before doing anything else, make sure all that help has been provided! + +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in *posix*) set -o posix ;; esac +fi + +# NLS nuisances: We save the old values in case they are required later. +_G_user_locale= +_G_safe_locale= +for _G_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES +do + eval "if test set = \"\${$_G_var+set}\"; then + save_$_G_var=\$$_G_var + $_G_var=C + export $_G_var + _G_user_locale=\"$_G_var=\\\$save_\$_G_var; \$_G_user_locale\" + _G_safe_locale=\"$_G_var=C; \$_G_safe_locale\" + fi" +done + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +# Make sure IFS has a sensible default +sp=' ' +nl=' +' +IFS="$sp $nl" + +# There are apparently some retarded systems that use ';' as a PATH separator! +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + + +## ------------------------- ## +## Locate command utilities. ## +## ------------------------- ## + + +# func_executable_p FILE +# ---------------------- +# Check that FILE is an executable regular file. +func_executable_p () +{ + test -f "$1" && test -x "$1" +} + + +# func_path_progs PROGS_LIST CHECK_FUNC [PATH] +# -------------------------------------------- +# Search for either a program that responds to --version with output +# containing "GNU", or else returned by CHECK_FUNC otherwise, by +# trying all the directories in PATH with each of the elements of +# PROGS_LIST. +# +# CHECK_FUNC should accept the path to a candidate program, and +# set $func_check_prog_result if it truncates its output less than +# $_G_path_prog_max characters. +func_path_progs () +{ + _G_progs_list=$1 + _G_check_func=$2 + _G_PATH=${3-"$PATH"} + + _G_path_prog_max=0 + _G_path_prog_found=false + _G_save_IFS=$IFS; IFS=${PATH_SEPARATOR-:} + for _G_dir in $_G_PATH; do + IFS=$_G_save_IFS + test -z "$_G_dir" && _G_dir=. + for _G_prog_name in $_G_progs_list; do + for _exeext in '' .EXE; do + _G_path_prog=$_G_dir/$_G_prog_name$_exeext + func_executable_p "$_G_path_prog" || continue + case `"$_G_path_prog" --version 2>&1` in + *GNU*) func_path_progs_result=$_G_path_prog _G_path_prog_found=: ;; + *) $_G_check_func $_G_path_prog + func_path_progs_result=$func_check_prog_result + ;; + esac + $_G_path_prog_found && break 3 + done + done + done + IFS=$_G_save_IFS + test -z "$func_path_progs_result" && { + echo "no acceptable sed could be found in \$PATH" >&2 + exit 1 + } +} + + +# We want to be able to use the functions in this file before configure +# has figured out where the best binaries are kept, which means we have +# to search for them ourselves - except when the results are already set +# where we skip the searches. + +# Unless the user overrides by setting SED, search the path for either GNU +# sed, or the sed that truncates its output the least. +test -z "$SED" && { + _G_sed_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ + for _G_i in 1 2 3 4 5 6 7; do + _G_sed_script=$_G_sed_script$nl$_G_sed_script + done + echo "$_G_sed_script" 2>/dev/null | sed 99q >conftest.sed + _G_sed_script= + + func_check_prog_sed () + { + _G_path_prog=$1 + + _G_count=0 + printf 0123456789 >conftest.in + while : + do + cat conftest.in conftest.in >conftest.tmp + mv conftest.tmp conftest.in + cp conftest.in conftest.nl + echo '' >> conftest.nl + "$_G_path_prog" -f conftest.sed conftest.out 2>/dev/null || break + diff conftest.out conftest.nl >/dev/null 2>&1 || break + _G_count=`expr $_G_count + 1` + if test "$_G_count" -gt "$_G_path_prog_max"; then + # Best one so far, save it but keep looking for a better one + func_check_prog_result=$_G_path_prog + _G_path_prog_max=$_G_count + fi + # 10*(2^10) chars as input seems more than enough + test 10 -lt "$_G_count" && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out + } + + func_path_progs "sed gsed" func_check_prog_sed $PATH:/usr/xpg4/bin + rm -f conftest.sed + SED=$func_path_progs_result +} + + +# Unless the user overrides by setting GREP, search the path for either GNU +# grep, or the grep that truncates its output the least. +test -z "$GREP" && { + func_check_prog_grep () + { + _G_path_prog=$1 + + _G_count=0 + _G_path_prog_max=0 + printf 0123456789 >conftest.in + while : + do + cat conftest.in conftest.in >conftest.tmp + mv conftest.tmp conftest.in + cp conftest.in conftest.nl + echo 'GREP' >> conftest.nl + "$_G_path_prog" -e 'GREP$' -e '-(cannot match)-' conftest.out 2>/dev/null || break + diff conftest.out conftest.nl >/dev/null 2>&1 || break + _G_count=`expr $_G_count + 1` + if test "$_G_count" -gt "$_G_path_prog_max"; then + # Best one so far, save it but keep looking for a better one + func_check_prog_result=$_G_path_prog + _G_path_prog_max=$_G_count + fi + # 10*(2^10) chars as input seems more than enough + test 10 -lt "$_G_count" && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out + } + + func_path_progs "grep ggrep" func_check_prog_grep $PATH:/usr/xpg4/bin + GREP=$func_path_progs_result +} + + +## ------------------------------- ## +## User overridable command paths. ## +## ------------------------------- ## + +# All uppercase variable names are used for environment variables. These +# variables can be overridden by the user before calling a script that +# uses them if a suitable command of that name is not already available +# in the command search PATH. + +: ${CP="cp -f"} +: ${ECHO="printf %s\n"} +: ${EGREP="$GREP -E"} +: ${FGREP="$GREP -F"} +: ${LN_S="ln -s"} +: ${MAKE="make"} +: ${MKDIR="mkdir"} +: ${MV="mv -f"} +: ${RM="rm -f"} +: ${SHELL="${CONFIG_SHELL-/bin/sh}"} + + +## -------------------- ## +## Useful sed snippets. ## +## -------------------- ## + +sed_dirname='s|/[^/]*$||' +sed_basename='s|^.*/||' + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +sed_quote_subst='s|\([`"$\\]\)|\\\1|g' + +# Same as above, but do not quote variable references. +sed_double_quote_subst='s/\(["`\\]\)/\\\1/g' + +# Sed substitution that turns a string into a regex matching for the +# string literally. +sed_make_literal_regex='s|[].[^$\\*\/]|\\&|g' + +# Sed substitution that converts a w32 file name or path +# that contains forward slashes, into one that contains +# (escaped) backslashes. A very naive implementation. +sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g' + +# Re-'\' parameter expansions in output of sed_double_quote_subst that +# were '\'-ed in input to the same. If an odd number of '\' preceded a +# '$' in input to sed_double_quote_subst, that '$' was protected from +# expansion. Since each input '\' is now two '\'s, look for any number +# of runs of four '\'s followed by two '\'s and then a '$'. '\' that '$'. +_G_bs='\\' +_G_bs2='\\\\' +_G_bs4='\\\\\\\\' +_G_dollar='\$' +sed_double_backslash="\ + s/$_G_bs4/&\\ +/g + s/^$_G_bs2$_G_dollar/$_G_bs&/ + s/\\([^$_G_bs]\\)$_G_bs2$_G_dollar/\\1$_G_bs2$_G_bs$_G_dollar/g + s/\n//g" + + +## ----------------- ## +## Global variables. ## +## ----------------- ## + +# Except for the global variables explicitly listed below, the following +# functions in the '^func_' namespace, and the '^require_' namespace +# variables initialised in the 'Resource management' section, sourcing +# this file will not pollute your global namespace with anything +# else. There's no portable way to scope variables in Bourne shell +# though, so actually running these functions will sometimes place +# results into a variable named after the function, and often use +# temporary variables in the '^_G_' namespace. If you are careful to +# avoid using those namespaces casually in your sourcing script, things +# should continue to work as you expect. And, of course, you can freely +# overwrite any of the functions or variables defined here before +# calling anything to customize them. + +EXIT_SUCCESS=0 +EXIT_FAILURE=1 +EXIT_MISMATCH=63 # $? = 63 is used to indicate version mismatch to missing. +EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake. + +# Allow overriding, eg assuming that you follow the convention of +# putting '$debug_cmd' at the start of all your functions, you can get +# bash to show function call trace with: +# +# debug_cmd='echo "${FUNCNAME[0]} $*" >&2' bash your-script-name +debug_cmd=${debug_cmd-":"} +exit_cmd=: + +# By convention, finish your script with: +# +# exit $exit_status +# +# so that you can set exit_status to non-zero if you want to indicate +# something went wrong during execution without actually bailing out at +# the point of failure. +exit_status=$EXIT_SUCCESS + +# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh +# is ksh but when the shell is invoked as "sh" and the current value of +# the _XPG environment variable is not equal to 1 (one), the special +# positional parameter $0, within a function call, is the name of the +# function. +progpath=$0 + +# The name of this program. +progname=`$ECHO "$progpath" |$SED "$sed_basename"` + +# Make sure we have an absolute progpath for reexecution: +case $progpath in + [\\/]*|[A-Za-z]:\\*) ;; + *[\\/]*) + progdir=`$ECHO "$progpath" |$SED "$sed_dirname"` + progdir=`cd "$progdir" && pwd` + progpath=$progdir/$progname + ;; + *) + _G_IFS=$IFS + IFS=${PATH_SEPARATOR-:} + for progdir in $PATH; do + IFS=$_G_IFS + test -x "$progdir/$progname" && break + done + IFS=$_G_IFS + test -n "$progdir" || progdir=`pwd` + progpath=$progdir/$progname + ;; +esac + + +## ----------------- ## +## Standard options. ## +## ----------------- ## + +# The following options affect the operation of the functions defined +# below, and should be set appropriately depending on run-time para- +# meters passed on the command line. + +opt_dry_run=false +opt_quiet=false +opt_verbose=false + +# Categories 'all' and 'none' are always available. Append any others +# you will pass as the first argument to func_warning from your own +# code. +warning_categories= + +# By default, display warnings according to 'opt_warning_types'. Set +# 'warning_func' to ':' to elide all warnings, or func_fatal_error to +# treat the next displayed warning as a fatal error. +warning_func=func_warn_and_continue + +# Set to 'all' to display all warnings, 'none' to suppress all +# warnings, or a space delimited list of some subset of +# 'warning_categories' to display only the listed warnings. +opt_warning_types=all + + +## -------------------- ## +## Resource management. ## +## -------------------- ## + +# This section contains definitions for functions that each ensure a +# particular resource (a file, or a non-empty configuration variable for +# example) is available, and if appropriate to extract default values +# from pertinent package files. Call them using their associated +# 'require_*' variable to ensure that they are executed, at most, once. +# +# It's entirely deliberate that calling these functions can set +# variables that don't obey the namespace limitations obeyed by the rest +# of this file, in order that that they be as useful as possible to +# callers. + + +# require_term_colors +# ------------------- +# Allow display of bold text on terminals that support it. +require_term_colors=func_require_term_colors +func_require_term_colors () +{ + $debug_cmd + + test -t 1 && { + # COLORTERM and USE_ANSI_COLORS environment variables take + # precedence, because most terminfo databases neglect to describe + # whether color sequences are supported. + test -n "${COLORTERM+set}" && : ${USE_ANSI_COLORS="1"} + + if test 1 = "$USE_ANSI_COLORS"; then + # Standard ANSI escape sequences + tc_reset='' + tc_bold=''; tc_standout='' + tc_red=''; tc_green='' + tc_blue=''; tc_cyan='' + else + # Otherwise trust the terminfo database after all. + test -n "`tput sgr0 2>/dev/null`" && { + tc_reset=`tput sgr0` + test -n "`tput bold 2>/dev/null`" && tc_bold=`tput bold` + tc_standout=$tc_bold + test -n "`tput smso 2>/dev/null`" && tc_standout=`tput smso` + test -n "`tput setaf 1 2>/dev/null`" && tc_red=`tput setaf 1` + test -n "`tput setaf 2 2>/dev/null`" && tc_green=`tput setaf 2` + test -n "`tput setaf 4 2>/dev/null`" && tc_blue=`tput setaf 4` + test -n "`tput setaf 5 2>/dev/null`" && tc_cyan=`tput setaf 5` + } + fi + } + + require_term_colors=: +} + + +## ----------------- ## +## Function library. ## +## ----------------- ## + +# This section contains a variety of useful functions to call in your +# scripts. Take note of the portable wrappers for features provided by +# some modern shells, which will fall back to slower equivalents on +# less featureful shells. + + +# func_append VAR VALUE +# --------------------- +# Append VALUE onto the existing contents of VAR. + + # We should try to minimise forks, especially on Windows where they are + # unreasonably slow, so skip the feature probes when bash or zsh are + # being used: + if test set = "${BASH_VERSION+set}${ZSH_VERSION+set}"; then + : ${_G_HAVE_ARITH_OP="yes"} + : ${_G_HAVE_XSI_OPS="yes"} + # The += operator was introduced in bash 3.1 + case $BASH_VERSION in + [12].* | 3.0 | 3.0*) ;; + *) + : ${_G_HAVE_PLUSEQ_OP="yes"} + ;; + esac + fi + + # _G_HAVE_PLUSEQ_OP + # Can be empty, in which case the shell is probed, "yes" if += is + # useable or anything else if it does not work. + test -z "$_G_HAVE_PLUSEQ_OP" \ + && (eval 'x=a; x+=" b"; test "a b" = "$x"') 2>/dev/null \ + && _G_HAVE_PLUSEQ_OP=yes + +if test yes = "$_G_HAVE_PLUSEQ_OP" +then + # This is an XSI compatible shell, allowing a faster implementation... + eval 'func_append () + { + $debug_cmd + + eval "$1+=\$2" + }' +else + # ...otherwise fall back to using expr, which is often a shell builtin. + func_append () + { + $debug_cmd + + eval "$1=\$$1\$2" + } +fi + + +# func_append_quoted VAR VALUE +# ---------------------------- +# Quote VALUE and append to the end of shell variable VAR, separated +# by a space. +if test yes = "$_G_HAVE_PLUSEQ_OP"; then + eval 'func_append_quoted () + { + $debug_cmd + + func_quote_for_eval "$2" + eval "$1+=\\ \$func_quote_for_eval_result" + }' +else + func_append_quoted () + { + $debug_cmd + + func_quote_for_eval "$2" + eval "$1=\$$1\\ \$func_quote_for_eval_result" + } +fi + + +# func_append_uniq VAR VALUE +# -------------------------- +# Append unique VALUE onto the existing contents of VAR, assuming +# entries are delimited by the first character of VALUE. For example: +# +# func_append_uniq options " --another-option option-argument" +# +# will only append to $options if " --another-option option-argument " +# is not already present somewhere in $options already (note spaces at +# each end implied by leading space in second argument). +func_append_uniq () +{ + $debug_cmd + + eval _G_current_value='`$ECHO $'$1'`' + _G_delim=`expr "$2" : '\(.\)'` + + case $_G_delim$_G_current_value$_G_delim in + *"$2$_G_delim"*) ;; + *) func_append "$@" ;; + esac +} + + +# func_arith TERM... +# ------------------ +# Set func_arith_result to the result of evaluating TERMs. + test -z "$_G_HAVE_ARITH_OP" \ + && (eval 'test 2 = $(( 1 + 1 ))') 2>/dev/null \ + && _G_HAVE_ARITH_OP=yes + +if test yes = "$_G_HAVE_ARITH_OP"; then + eval 'func_arith () + { + $debug_cmd + + func_arith_result=$(( $* )) + }' +else + func_arith () + { + $debug_cmd + + func_arith_result=`expr "$@"` + } +fi + + +# func_basename FILE +# ------------------ +# Set func_basename_result to FILE with everything up to and including +# the last / stripped. +if test yes = "$_G_HAVE_XSI_OPS"; then + # If this shell supports suffix pattern removal, then use it to avoid + # forking. Hide the definitions single quotes in case the shell chokes + # on unsupported syntax... + _b='func_basename_result=${1##*/}' + _d='case $1 in + */*) func_dirname_result=${1%/*}$2 ;; + * ) func_dirname_result=$3 ;; + esac' + +else + # ...otherwise fall back to using sed. + _b='func_basename_result=`$ECHO "$1" |$SED "$sed_basename"`' + _d='func_dirname_result=`$ECHO "$1" |$SED "$sed_dirname"` + if test "X$func_dirname_result" = "X$1"; then + func_dirname_result=$3 + else + func_append func_dirname_result "$2" + fi' +fi + +eval 'func_basename () +{ + $debug_cmd + + '"$_b"' +}' + + +# func_dirname FILE APPEND NONDIR_REPLACEMENT +# ------------------------------------------- +# Compute the dirname of FILE. If nonempty, add APPEND to the result, +# otherwise set result to NONDIR_REPLACEMENT. +eval 'func_dirname () +{ + $debug_cmd + + '"$_d"' +}' + + +# func_dirname_and_basename FILE APPEND NONDIR_REPLACEMENT +# -------------------------------------------------------- +# Perform func_basename and func_dirname in a single function +# call: +# dirname: Compute the dirname of FILE. If nonempty, +# add APPEND to the result, otherwise set result +# to NONDIR_REPLACEMENT. +# value returned in "$func_dirname_result" +# basename: Compute filename of FILE. +# value retuned in "$func_basename_result" +# For efficiency, we do not delegate to the functions above but instead +# duplicate the functionality here. +eval 'func_dirname_and_basename () +{ + $debug_cmd + + '"$_b"' + '"$_d"' +}' + + +# func_echo ARG... +# ---------------- +# Echo program name prefixed message. +func_echo () +{ + $debug_cmd + + _G_message=$* + + func_echo_IFS=$IFS + IFS=$nl + for _G_line in $_G_message; do + IFS=$func_echo_IFS + $ECHO "$progname: $_G_line" + done + IFS=$func_echo_IFS +} + + +# func_echo_all ARG... +# -------------------- +# Invoke $ECHO with all args, space-separated. +func_echo_all () +{ + $ECHO "$*" +} + + +# func_echo_infix_1 INFIX ARG... +# ------------------------------ +# Echo program name, followed by INFIX on the first line, with any +# additional lines not showing INFIX. +func_echo_infix_1 () +{ + $debug_cmd + + $require_term_colors + + _G_infix=$1; shift + _G_indent=$_G_infix + _G_prefix="$progname: $_G_infix: " + _G_message=$* + + # Strip color escape sequences before counting printable length + for _G_tc in "$tc_reset" "$tc_bold" "$tc_standout" "$tc_red" "$tc_green" "$tc_blue" "$tc_cyan" + do + test -n "$_G_tc" && { + _G_esc_tc=`$ECHO "$_G_tc" | $SED "$sed_make_literal_regex"` + _G_indent=`$ECHO "$_G_indent" | $SED "s|$_G_esc_tc||g"` + } + done + _G_indent="$progname: "`echo "$_G_indent" | $SED 's|.| |g'`" " ## exclude from sc_prohibit_nested_quotes + + func_echo_infix_1_IFS=$IFS + IFS=$nl + for _G_line in $_G_message; do + IFS=$func_echo_infix_1_IFS + $ECHO "$_G_prefix$tc_bold$_G_line$tc_reset" >&2 + _G_prefix=$_G_indent + done + IFS=$func_echo_infix_1_IFS +} + + +# func_error ARG... +# ----------------- +# Echo program name prefixed message to standard error. +func_error () +{ + $debug_cmd + + $require_term_colors + + func_echo_infix_1 " $tc_standout${tc_red}error$tc_reset" "$*" >&2 +} + + +# func_fatal_error ARG... +# ----------------------- +# Echo program name prefixed message to standard error, and exit. +func_fatal_error () +{ + $debug_cmd + + func_error "$*" + exit $EXIT_FAILURE +} + + +# func_grep EXPRESSION FILENAME +# ----------------------------- +# Check whether EXPRESSION matches any line of FILENAME, without output. +func_grep () +{ + $debug_cmd + + $GREP "$1" "$2" >/dev/null 2>&1 +} + + +# func_len STRING +# --------------- +# Set func_len_result to the length of STRING. STRING may not +# start with a hyphen. + test -z "$_G_HAVE_XSI_OPS" \ + && (eval 'x=a/b/c; + test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \ + && _G_HAVE_XSI_OPS=yes + +if test yes = "$_G_HAVE_XSI_OPS"; then + eval 'func_len () + { + $debug_cmd + + func_len_result=${#1} + }' +else + func_len () + { + $debug_cmd + + func_len_result=`expr "$1" : ".*" 2>/dev/null || echo $max_cmd_len` + } +fi + + +# func_mkdir_p DIRECTORY-PATH +# --------------------------- +# Make sure the entire path to DIRECTORY-PATH is available. +func_mkdir_p () +{ + $debug_cmd + + _G_directory_path=$1 + _G_dir_list= + + if test -n "$_G_directory_path" && test : != "$opt_dry_run"; then + + # Protect directory names starting with '-' + case $_G_directory_path in + -*) _G_directory_path=./$_G_directory_path ;; + esac + + # While some portion of DIR does not yet exist... + while test ! -d "$_G_directory_path"; do + # ...make a list in topmost first order. Use a colon delimited + # list incase some portion of path contains whitespace. + _G_dir_list=$_G_directory_path:$_G_dir_list + + # If the last portion added has no slash in it, the list is done + case $_G_directory_path in */*) ;; *) break ;; esac + + # ...otherwise throw away the child directory and loop + _G_directory_path=`$ECHO "$_G_directory_path" | $SED -e "$sed_dirname"` + done + _G_dir_list=`$ECHO "$_G_dir_list" | $SED 's|:*$||'` + + func_mkdir_p_IFS=$IFS; IFS=: + for _G_dir in $_G_dir_list; do + IFS=$func_mkdir_p_IFS + # mkdir can fail with a 'File exist' error if two processes + # try to create one of the directories concurrently. Don't + # stop in that case! + $MKDIR "$_G_dir" 2>/dev/null || : + done + IFS=$func_mkdir_p_IFS + + # Bail out if we (or some other process) failed to create a directory. + test -d "$_G_directory_path" || \ + func_fatal_error "Failed to create '$1'" + fi +} + + +# func_mktempdir [BASENAME] +# ------------------------- +# Make a temporary directory that won't clash with other running +# libtool processes, and avoids race conditions if possible. If +# given, BASENAME is the basename for that directory. +func_mktempdir () +{ + $debug_cmd + + _G_template=${TMPDIR-/tmp}/${1-$progname} + + if test : = "$opt_dry_run"; then + # Return a directory name, but don't create it in dry-run mode + _G_tmpdir=$_G_template-$$ + else + + # If mktemp works, use that first and foremost + _G_tmpdir=`mktemp -d "$_G_template-XXXXXXXX" 2>/dev/null` + + if test ! -d "$_G_tmpdir"; then + # Failing that, at least try and use $RANDOM to avoid a race + _G_tmpdir=$_G_template-${RANDOM-0}$$ + + func_mktempdir_umask=`umask` + umask 0077 + $MKDIR "$_G_tmpdir" + umask $func_mktempdir_umask + fi + + # If we're not in dry-run mode, bomb out on failure + test -d "$_G_tmpdir" || \ + func_fatal_error "cannot create temporary directory '$_G_tmpdir'" + fi + + $ECHO "$_G_tmpdir" +} + + +# func_normal_abspath PATH +# ------------------------ +# Remove doubled-up and trailing slashes, "." path components, +# and cancel out any ".." path components in PATH after making +# it an absolute path. +func_normal_abspath () +{ + $debug_cmd + + # These SED scripts presuppose an absolute path with a trailing slash. + _G_pathcar='s|^/\([^/]*\).*$|\1|' + _G_pathcdr='s|^/[^/]*||' + _G_removedotparts=':dotsl + s|/\./|/|g + t dotsl + s|/\.$|/|' + _G_collapseslashes='s|/\{1,\}|/|g' + _G_finalslash='s|/*$|/|' + + # Start from root dir and reassemble the path. + func_normal_abspath_result= + func_normal_abspath_tpath=$1 + func_normal_abspath_altnamespace= + case $func_normal_abspath_tpath in + "") + # Empty path, that just means $cwd. + func_stripname '' '/' "`pwd`" + func_normal_abspath_result=$func_stripname_result + return + ;; + # The next three entries are used to spot a run of precisely + # two leading slashes without using negated character classes; + # we take advantage of case's first-match behaviour. + ///*) + # Unusual form of absolute path, do nothing. + ;; + //*) + # Not necessarily an ordinary path; POSIX reserves leading '//' + # and for example Cygwin uses it to access remote file shares + # over CIFS/SMB, so we conserve a leading double slash if found. + func_normal_abspath_altnamespace=/ + ;; + /*) + # Absolute path, do nothing. + ;; + *) + # Relative path, prepend $cwd. + func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath + ;; + esac + + # Cancel out all the simple stuff to save iterations. We also want + # the path to end with a slash for ease of parsing, so make sure + # there is one (and only one) here. + func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ + -e "$_G_removedotparts" -e "$_G_collapseslashes" -e "$_G_finalslash"` + while :; do + # Processed it all yet? + if test / = "$func_normal_abspath_tpath"; then + # If we ascended to the root using ".." the result may be empty now. + if test -z "$func_normal_abspath_result"; then + func_normal_abspath_result=/ + fi + break + fi + func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \ + -e "$_G_pathcar"` + func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ + -e "$_G_pathcdr"` + # Figure out what to do with it + case $func_normal_abspath_tcomponent in + "") + # Trailing empty path component, ignore it. + ;; + ..) + # Parent dir; strip last assembled component from result. + func_dirname "$func_normal_abspath_result" + func_normal_abspath_result=$func_dirname_result + ;; + *) + # Actual path component, append it. + func_append func_normal_abspath_result "/$func_normal_abspath_tcomponent" + ;; + esac + done + # Restore leading double-slash if one was found on entry. + func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result +} + + +# func_notquiet ARG... +# -------------------- +# Echo program name prefixed message only when not in quiet mode. +func_notquiet () +{ + $debug_cmd + + $opt_quiet || func_echo ${1+"$@"} + + # A bug in bash halts the script if the last line of a function + # fails when set -e is in force, so we need another command to + # work around that: + : +} + + +# func_relative_path SRCDIR DSTDIR +# -------------------------------- +# Set func_relative_path_result to the relative path from SRCDIR to DSTDIR. +func_relative_path () +{ + $debug_cmd + + func_relative_path_result= + func_normal_abspath "$1" + func_relative_path_tlibdir=$func_normal_abspath_result + func_normal_abspath "$2" + func_relative_path_tbindir=$func_normal_abspath_result + + # Ascend the tree starting from libdir + while :; do + # check if we have found a prefix of bindir + case $func_relative_path_tbindir in + $func_relative_path_tlibdir) + # found an exact match + func_relative_path_tcancelled= + break + ;; + $func_relative_path_tlibdir*) + # found a matching prefix + func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir" + func_relative_path_tcancelled=$func_stripname_result + if test -z "$func_relative_path_result"; then + func_relative_path_result=. + fi + break + ;; + *) + func_dirname $func_relative_path_tlibdir + func_relative_path_tlibdir=$func_dirname_result + if test -z "$func_relative_path_tlibdir"; then + # Have to descend all the way to the root! + func_relative_path_result=../$func_relative_path_result + func_relative_path_tcancelled=$func_relative_path_tbindir + break + fi + func_relative_path_result=../$func_relative_path_result + ;; + esac + done + + # Now calculate path; take care to avoid doubling-up slashes. + func_stripname '' '/' "$func_relative_path_result" + func_relative_path_result=$func_stripname_result + func_stripname '/' '/' "$func_relative_path_tcancelled" + if test -n "$func_stripname_result"; then + func_append func_relative_path_result "/$func_stripname_result" + fi + + # Normalisation. If bindir is libdir, return '.' else relative path. + if test -n "$func_relative_path_result"; then + func_stripname './' '' "$func_relative_path_result" + func_relative_path_result=$func_stripname_result + fi + + test -n "$func_relative_path_result" || func_relative_path_result=. + + : +} + + +# func_quote_for_eval ARG... +# -------------------------- +# Aesthetically quote ARGs to be evaled later. +# This function returns two values: +# i) func_quote_for_eval_result +# double-quoted, suitable for a subsequent eval +# ii) func_quote_for_eval_unquoted_result +# has all characters that are still active within double +# quotes backslashified. +func_quote_for_eval () +{ + $debug_cmd + + func_quote_for_eval_unquoted_result= + func_quote_for_eval_result= + while test 0 -lt $#; do + case $1 in + *[\\\`\"\$]*) + _G_unquoted_arg=`printf '%s\n' "$1" |$SED "$sed_quote_subst"` ;; + *) + _G_unquoted_arg=$1 ;; + esac + if test -n "$func_quote_for_eval_unquoted_result"; then + func_append func_quote_for_eval_unquoted_result " $_G_unquoted_arg" + else + func_append func_quote_for_eval_unquoted_result "$_G_unquoted_arg" + fi + + case $_G_unquoted_arg in + # Double-quote args containing shell metacharacters to delay + # word splitting, command substitution and variable expansion + # for a subsequent eval. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + _G_quoted_arg=\"$_G_unquoted_arg\" + ;; + *) + _G_quoted_arg=$_G_unquoted_arg + ;; + esac + + if test -n "$func_quote_for_eval_result"; then + func_append func_quote_for_eval_result " $_G_quoted_arg" + else + func_append func_quote_for_eval_result "$_G_quoted_arg" + fi + shift + done +} + + +# func_quote_for_expand ARG +# ------------------------- +# Aesthetically quote ARG to be evaled later; same as above, +# but do not quote variable references. +func_quote_for_expand () +{ + $debug_cmd + + case $1 in + *[\\\`\"]*) + _G_arg=`$ECHO "$1" | $SED \ + -e "$sed_double_quote_subst" -e "$sed_double_backslash"` ;; + *) + _G_arg=$1 ;; + esac + + case $_G_arg in + # Double-quote args containing shell metacharacters to delay + # word splitting and command substitution for a subsequent eval. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + _G_arg=\"$_G_arg\" + ;; + esac + + func_quote_for_expand_result=$_G_arg +} + + +# func_stripname PREFIX SUFFIX NAME +# --------------------------------- +# strip PREFIX and SUFFIX from NAME, and store in func_stripname_result. +# PREFIX and SUFFIX must not contain globbing or regex special +# characters, hashes, percent signs, but SUFFIX may contain a leading +# dot (in which case that matches only a dot). +if test yes = "$_G_HAVE_XSI_OPS"; then + eval 'func_stripname () + { + $debug_cmd + + # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are + # positional parameters, so assign one to ordinary variable first. + func_stripname_result=$3 + func_stripname_result=${func_stripname_result#"$1"} + func_stripname_result=${func_stripname_result%"$2"} + }' +else + func_stripname () + { + $debug_cmd + + case $2 in + .*) func_stripname_result=`$ECHO "$3" | $SED -e "s%^$1%%" -e "s%\\\\$2\$%%"`;; + *) func_stripname_result=`$ECHO "$3" | $SED -e "s%^$1%%" -e "s%$2\$%%"`;; + esac + } +fi + + +# func_show_eval CMD [FAIL_EXP] +# ----------------------------- +# Unless opt_quiet is true, then output CMD. Then, if opt_dryrun is +# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP +# is given, then evaluate it. +func_show_eval () +{ + $debug_cmd + + _G_cmd=$1 + _G_fail_exp=${2-':'} + + func_quote_for_expand "$_G_cmd" + eval "func_notquiet $func_quote_for_expand_result" + + $opt_dry_run || { + eval "$_G_cmd" + _G_status=$? + if test 0 -ne "$_G_status"; then + eval "(exit $_G_status); $_G_fail_exp" + fi + } +} + + +# func_show_eval_locale CMD [FAIL_EXP] +# ------------------------------------ +# Unless opt_quiet is true, then output CMD. Then, if opt_dryrun is +# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP +# is given, then evaluate it. Use the saved locale for evaluation. +func_show_eval_locale () +{ + $debug_cmd + + _G_cmd=$1 + _G_fail_exp=${2-':'} + + $opt_quiet || { + func_quote_for_expand "$_G_cmd" + eval "func_echo $func_quote_for_expand_result" + } + + $opt_dry_run || { + eval "$_G_user_locale + $_G_cmd" + _G_status=$? + eval "$_G_safe_locale" + if test 0 -ne "$_G_status"; then + eval "(exit $_G_status); $_G_fail_exp" + fi + } +} + + +# func_tr_sh +# ---------- +# Turn $1 into a string suitable for a shell variable name. +# Result is stored in $func_tr_sh_result. All characters +# not in the set a-zA-Z0-9_ are replaced with '_'. Further, +# if $1 begins with a digit, a '_' is prepended as well. +func_tr_sh () +{ + $debug_cmd + + case $1 in + [0-9]* | *[!a-zA-Z0-9_]*) + func_tr_sh_result=`$ECHO "$1" | $SED -e 's/^\([0-9]\)/_\1/' -e 's/[^a-zA-Z0-9_]/_/g'` + ;; + * ) + func_tr_sh_result=$1 + ;; + esac +} + + +# func_verbose ARG... +# ------------------- +# Echo program name prefixed message in verbose mode only. +func_verbose () +{ + $debug_cmd + + $opt_verbose && func_echo "$*" + + : +} + + +# func_warn_and_continue ARG... +# ----------------------------- +# Echo program name prefixed warning message to standard error. +func_warn_and_continue () +{ + $debug_cmd + + $require_term_colors + + func_echo_infix_1 "${tc_red}warning$tc_reset" "$*" >&2 +} + + +# func_warning CATEGORY ARG... +# ---------------------------- +# Echo program name prefixed warning message to standard error. Warning +# messages can be filtered according to CATEGORY, where this function +# elides messages where CATEGORY is not listed in the global variable +# 'opt_warning_types'. +func_warning () +{ + $debug_cmd + + # CATEGORY must be in the warning_categories list! + case " $warning_categories " in + *" $1 "*) ;; + *) func_internal_error "invalid warning category '$1'" ;; + esac + + _G_category=$1 + shift + + case " $opt_warning_types " in + *" $_G_category "*) $warning_func ${1+"$@"} ;; + esac +} + + +# func_sort_ver VER1 VER2 +# ----------------------- +# 'sort -V' is not generally available. +# Note this deviates from the version comparison in automake +# in that it treats 1.5 < 1.5.0, and treats 1.4.4a < 1.4-p3a +# but this should suffice as we won't be specifying old +# version formats or redundant trailing .0 in bootstrap.conf. +# If we did want full compatibility then we should probably +# use m4_version_compare from autoconf. +func_sort_ver () +{ + $debug_cmd + + printf '%s\n%s\n' "$1" "$2" \ + | sort -t. -k 1,1n -k 2,2n -k 3,3n -k 4,4n -k 5,5n -k 6,6n -k 7,7n -k 8,8n -k 9,9n +} + +# func_lt_ver PREV CURR +# --------------------- +# Return true if PREV and CURR are in the correct order according to +# func_sort_ver, otherwise false. Use it like this: +# +# func_lt_ver "$prev_ver" "$proposed_ver" || func_fatal_error "..." +func_lt_ver () +{ + $debug_cmd + + test "x$1" = x`func_sort_ver "$1" "$2" | $SED 1q` +} + + +# Local variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'before-save-hook 'time-stamp) +# time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC" +# time-stamp-time-zone: "UTC" +# End: +#! /bin/sh + +# Set a version string for this script. +scriptversion=2015-10-07.11; # UTC + +# A portable, pluggable option parser for Bourne shell. +# Written by Gary V. Vaughan, 2010 + +# Copyright (C) 2010-2015 Free Software Foundation, Inc. +# This is free software; see the source for copying conditions. There is NO +# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# Please report bugs or propose patches to gary@gnu.org. + + +## ------ ## +## Usage. ## +## ------ ## + +# This file is a library for parsing options in your shell scripts along +# with assorted other useful supporting features that you can make use +# of too. +# +# For the simplest scripts you might need only: +# +# #!/bin/sh +# . relative/path/to/funclib.sh +# . relative/path/to/options-parser +# scriptversion=1.0 +# func_options ${1+"$@"} +# eval set dummy "$func_options_result"; shift +# ...rest of your script... +# +# In order for the '--version' option to work, you will need to have a +# suitably formatted comment like the one at the top of this file +# starting with '# Written by ' and ending with '# warranty; '. +# +# For '-h' and '--help' to work, you will also need a one line +# description of your script's purpose in a comment directly above the +# '# Written by ' line, like the one at the top of this file. +# +# The default options also support '--debug', which will turn on shell +# execution tracing (see the comment above debug_cmd below for another +# use), and '--verbose' and the func_verbose function to allow your script +# to display verbose messages only when your user has specified +# '--verbose'. +# +# After sourcing this file, you can plug processing for additional +# options by amending the variables from the 'Configuration' section +# below, and following the instructions in the 'Option parsing' +# section further down. + +## -------------- ## +## Configuration. ## +## -------------- ## + +# You should override these variables in your script after sourcing this +# file so that they reflect the customisations you have added to the +# option parser. + +# The usage line for option parsing errors and the start of '-h' and +# '--help' output messages. You can embed shell variables for delayed +# expansion at the time the message is displayed, but you will need to +# quote other shell meta-characters carefully to prevent them being +# expanded when the contents are evaled. +usage='$progpath [OPTION]...' + +# Short help message in response to '-h' and '--help'. Add to this or +# override it after sourcing this library to reflect the full set of +# options your script accepts. +usage_message="\ + --debug enable verbose shell tracing + -W, --warnings=CATEGORY + report the warnings falling in CATEGORY [all] + -v, --verbose verbosely report processing + --version print version information and exit + -h, --help print short or long help message and exit +" + +# Additional text appended to 'usage_message' in response to '--help'. +long_help_message=" +Warning categories include: + 'all' show all warnings + 'none' turn off all the warnings + 'error' warnings are treated as fatal errors" + +# Help message printed before fatal option parsing errors. +fatal_help="Try '\$progname --help' for more information." + + + +## ------------------------- ## +## Hook function management. ## +## ------------------------- ## + +# This section contains functions for adding, removing, and running hooks +# to the main code. A hook is just a named list of of function, that can +# be run in order later on. + +# func_hookable FUNC_NAME +# ----------------------- +# Declare that FUNC_NAME will run hooks added with +# 'func_add_hook FUNC_NAME ...'. +func_hookable () +{ + $debug_cmd + + func_append hookable_fns " $1" +} + + +# func_add_hook FUNC_NAME HOOK_FUNC +# --------------------------------- +# Request that FUNC_NAME call HOOK_FUNC before it returns. FUNC_NAME must +# first have been declared "hookable" by a call to 'func_hookable'. +func_add_hook () +{ + $debug_cmd + + case " $hookable_fns " in + *" $1 "*) ;; + *) func_fatal_error "'$1' does not accept hook functions." ;; + esac + + eval func_append ${1}_hooks '" $2"' +} + + +# func_remove_hook FUNC_NAME HOOK_FUNC +# ------------------------------------ +# Remove HOOK_FUNC from the list of functions called by FUNC_NAME. +func_remove_hook () +{ + $debug_cmd + + eval ${1}_hooks='`$ECHO "\$'$1'_hooks" |$SED "s| '$2'||"`' +} + + +# func_run_hooks FUNC_NAME [ARG]... +# --------------------------------- +# Run all hook functions registered to FUNC_NAME. +# It is assumed that the list of hook functions contains nothing more +# than a whitespace-delimited list of legal shell function names, and +# no effort is wasted trying to catch shell meta-characters or preserve +# whitespace. +func_run_hooks () +{ + $debug_cmd + + _G_rc_run_hooks=false + + case " $hookable_fns " in + *" $1 "*) ;; + *) func_fatal_error "'$1' does not support hook funcions.n" ;; + esac + + eval _G_hook_fns=\$$1_hooks; shift + + for _G_hook in $_G_hook_fns; do + if eval $_G_hook '"$@"'; then + # store returned options list back into positional + # parameters for next 'cmd' execution. + eval _G_hook_result=\$${_G_hook}_result + eval set dummy "$_G_hook_result"; shift + _G_rc_run_hooks=: + fi + done + + $_G_rc_run_hooks && func_run_hooks_result=$_G_hook_result +} + + + +## --------------- ## +## Option parsing. ## +## --------------- ## + +# In order to add your own option parsing hooks, you must accept the +# full positional parameter list in your hook function, you may remove/edit +# any options that you action, and then pass back the remaining unprocessed +# options in '_result', escaped suitably for +# 'eval'. In this case you also must return $EXIT_SUCCESS to let the +# hook's caller know that it should pay attention to +# '_result'. Returning $EXIT_FAILURE signalizes that +# arguments are left untouched by the hook and therefore caller will ignore the +# result variable. +# +# Like this: +# +# my_options_prep () +# { +# $debug_cmd +# +# # Extend the existing usage message. +# usage_message=$usage_message' +# -s, --silent don'\''t print informational messages +# ' +# # No change in '$@' (ignored completely by this hook). There is +# # no need to do the equivalent (but slower) action: +# # func_quote_for_eval ${1+"$@"} +# # my_options_prep_result=$func_quote_for_eval_result +# false +# } +# func_add_hook func_options_prep my_options_prep +# +# +# my_silent_option () +# { +# $debug_cmd +# +# args_changed=false +# +# # Note that for efficiency, we parse as many options as we can +# # recognise in a loop before passing the remainder back to the +# # caller on the first unrecognised argument we encounter. +# while test $# -gt 0; do +# opt=$1; shift +# case $opt in +# --silent|-s) opt_silent=: +# args_changed=: +# ;; +# # Separate non-argument short options: +# -s*) func_split_short_opt "$_G_opt" +# set dummy "$func_split_short_opt_name" \ +# "-$func_split_short_opt_arg" ${1+"$@"} +# shift +# args_changed=: +# ;; +# *) # Make sure the first unrecognised option "$_G_opt" +# # is added back to "$@", we could need that later +# # if $args_changed is true. +# set dummy "$_G_opt" ${1+"$@"}; shift; break ;; +# esac +# done +# +# if $args_changed; then +# func_quote_for_eval ${1+"$@"} +# my_silent_option_result=$func_quote_for_eval_result +# fi +# +# $args_changed +# } +# func_add_hook func_parse_options my_silent_option +# +# +# my_option_validation () +# { +# $debug_cmd +# +# $opt_silent && $opt_verbose && func_fatal_help "\ +# '--silent' and '--verbose' options are mutually exclusive." +# +# false +# } +# func_add_hook func_validate_options my_option_validation +# +# You'll also need to manually amend $usage_message to reflect the extra +# options you parse. It's preferable to append if you can, so that +# multiple option parsing hooks can be added safely. + + +# func_options_finish [ARG]... +# ---------------------------- +# Finishing the option parse loop (call 'func_options' hooks ATM). +func_options_finish () +{ + $debug_cmd + + _G_func_options_finish_exit=false + if func_run_hooks func_options ${1+"$@"}; then + func_options_finish_result=$func_run_hooks_result + _G_func_options_finish_exit=: + fi + + $_G_func_options_finish_exit +} + + +# func_options [ARG]... +# --------------------- +# All the functions called inside func_options are hookable. See the +# individual implementations for details. +func_hookable func_options +func_options () +{ + $debug_cmd + + _G_rc_options=false + + for my_func in options_prep parse_options validate_options options_finish + do + if eval func_$my_func '${1+"$@"}'; then + eval _G_res_var='$'"func_${my_func}_result" + eval set dummy "$_G_res_var" ; shift + _G_rc_options=: + fi + done + + # Save modified positional parameters for caller. As a top-level + # options-parser function we always need to set the 'func_options_result' + # variable (regardless the $_G_rc_options value). + if $_G_rc_options; then + func_options_result=$_G_res_var + else + func_quote_for_eval ${1+"$@"} + func_options_result=$func_quote_for_eval_result + fi + + $_G_rc_options +} + + +# func_options_prep [ARG]... +# -------------------------- +# All initialisations required before starting the option parse loop. +# Note that when calling hook functions, we pass through the list of +# positional parameters. If a hook function modifies that list, and +# needs to propagate that back to rest of this script, then the complete +# modified list must be put in 'func_run_hooks_result' before +# returning $EXIT_SUCCESS (otherwise $EXIT_FAILURE is returned). +func_hookable func_options_prep +func_options_prep () +{ + $debug_cmd + + # Option defaults: + opt_verbose=false + opt_warning_types= + + _G_rc_options_prep=false + if func_run_hooks func_options_prep ${1+"$@"}; then + _G_rc_options_prep=: + # save modified positional parameters for caller + func_options_prep_result=$func_run_hooks_result + fi + + $_G_rc_options_prep +} + + +# func_parse_options [ARG]... +# --------------------------- +# The main option parsing loop. +func_hookable func_parse_options +func_parse_options () +{ + $debug_cmd + + func_parse_options_result= + + _G_rc_parse_options=false + # this just eases exit handling + while test $# -gt 0; do + # Defer to hook functions for initial option parsing, so they + # get priority in the event of reusing an option name. + if func_run_hooks func_parse_options ${1+"$@"}; then + eval set dummy "$func_run_hooks_result"; shift + _G_rc_parse_options=: + fi + + # Break out of the loop if we already parsed every option. + test $# -gt 0 || break + + _G_match_parse_options=: + _G_opt=$1 + shift + case $_G_opt in + --debug|-x) debug_cmd='set -x' + func_echo "enabling shell trace mode" + $debug_cmd + ;; + + --no-warnings|--no-warning|--no-warn) + set dummy --warnings none ${1+"$@"} + shift + ;; + + --warnings|--warning|-W) + if test $# = 0 && func_missing_arg $_G_opt; then + _G_rc_parse_options=: + break + fi + case " $warning_categories $1" in + *" $1 "*) + # trailing space prevents matching last $1 above + func_append_uniq opt_warning_types " $1" + ;; + *all) + opt_warning_types=$warning_categories + ;; + *none) + opt_warning_types=none + warning_func=: + ;; + *error) + opt_warning_types=$warning_categories + warning_func=func_fatal_error + ;; + *) + func_fatal_error \ + "unsupported warning category: '$1'" + ;; + esac + shift + ;; + + --verbose|-v) opt_verbose=: ;; + --version) func_version ;; + -\?|-h) func_usage ;; + --help) func_help ;; + + # Separate optargs to long options (plugins may need this): + --*=*) func_split_equals "$_G_opt" + set dummy "$func_split_equals_lhs" \ + "$func_split_equals_rhs" ${1+"$@"} + shift + ;; + + # Separate optargs to short options: + -W*) + func_split_short_opt "$_G_opt" + set dummy "$func_split_short_opt_name" \ + "$func_split_short_opt_arg" ${1+"$@"} + shift + ;; + + # Separate non-argument short options: + -\?*|-h*|-v*|-x*) + func_split_short_opt "$_G_opt" + set dummy "$func_split_short_opt_name" \ + "-$func_split_short_opt_arg" ${1+"$@"} + shift + ;; + + --) _G_rc_parse_options=: ; break ;; + -*) func_fatal_help "unrecognised option: '$_G_opt'" ;; + *) set dummy "$_G_opt" ${1+"$@"}; shift + _G_match_parse_options=false + break + ;; + esac + + $_G_match_parse_options && _G_rc_parse_options=: + done + + + if $_G_rc_parse_options; then + # save modified positional parameters for caller + func_quote_for_eval ${1+"$@"} + func_parse_options_result=$func_quote_for_eval_result + fi + + $_G_rc_parse_options +} + + +# func_validate_options [ARG]... +# ------------------------------ +# Perform any sanity checks on option settings and/or unconsumed +# arguments. +func_hookable func_validate_options +func_validate_options () +{ + $debug_cmd + + _G_rc_validate_options=false + + # Display all warnings if -W was not given. + test -n "$opt_warning_types" || opt_warning_types=" $warning_categories" + + if func_run_hooks func_validate_options ${1+"$@"}; then + # save modified positional parameters for caller + func_validate_options_result=$func_run_hooks_result + _G_rc_validate_options=: + fi + + # Bail if the options were screwed! + $exit_cmd $EXIT_FAILURE + + $_G_rc_validate_options +} + + + +## ----------------- ## +## Helper functions. ## +## ----------------- ## + +# This section contains the helper functions used by the rest of the +# hookable option parser framework in ascii-betical order. + + +# func_fatal_help ARG... +# ---------------------- +# Echo program name prefixed message to standard error, followed by +# a help hint, and exit. +func_fatal_help () +{ + $debug_cmd + + eval \$ECHO \""Usage: $usage"\" + eval \$ECHO \""$fatal_help"\" + func_error ${1+"$@"} + exit $EXIT_FAILURE +} + + +# func_help +# --------- +# Echo long help message to standard output and exit. +func_help () +{ + $debug_cmd + + func_usage_message + $ECHO "$long_help_message" + exit 0 +} + + +# func_missing_arg ARGNAME +# ------------------------ +# Echo program name prefixed message to standard error and set global +# exit_cmd. +func_missing_arg () +{ + $debug_cmd + + func_error "Missing argument for '$1'." + exit_cmd=exit +} + + +# func_split_equals STRING +# ------------------------ +# Set func_split_equals_lhs and func_split_equals_rhs shell variables after +# splitting STRING at the '=' sign. +test -z "$_G_HAVE_XSI_OPS" \ + && (eval 'x=a/b/c; + test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \ + && _G_HAVE_XSI_OPS=yes + +if test yes = "$_G_HAVE_XSI_OPS" +then + # This is an XSI compatible shell, allowing a faster implementation... + eval 'func_split_equals () + { + $debug_cmd + + func_split_equals_lhs=${1%%=*} + func_split_equals_rhs=${1#*=} + test "x$func_split_equals_lhs" = "x$1" \ + && func_split_equals_rhs= + }' +else + # ...otherwise fall back to using expr, which is often a shell builtin. + func_split_equals () + { + $debug_cmd + + func_split_equals_lhs=`expr "x$1" : 'x\([^=]*\)'` + func_split_equals_rhs= + test "x$func_split_equals_lhs" = "x$1" \ + || func_split_equals_rhs=`expr "x$1" : 'x[^=]*=\(.*\)$'` + } +fi #func_split_equals + + +# func_split_short_opt SHORTOPT +# ----------------------------- +# Set func_split_short_opt_name and func_split_short_opt_arg shell +# variables after splitting SHORTOPT after the 2nd character. +if test yes = "$_G_HAVE_XSI_OPS" +then + # This is an XSI compatible shell, allowing a faster implementation... + eval 'func_split_short_opt () + { + $debug_cmd + + func_split_short_opt_arg=${1#??} + func_split_short_opt_name=${1%"$func_split_short_opt_arg"} + }' +else + # ...otherwise fall back to using expr, which is often a shell builtin. + func_split_short_opt () + { + $debug_cmd + + func_split_short_opt_name=`expr "x$1" : 'x-\(.\)'` + func_split_short_opt_arg=`expr "x$1" : 'x-.\(.*\)$'` + } +fi #func_split_short_opt + + +# func_usage +# ---------- +# Echo short help message to standard output and exit. +func_usage () +{ + $debug_cmd + + func_usage_message + $ECHO "Run '$progname --help |${PAGER-more}' for full usage" + exit 0 +} + + +# func_usage_message +# ------------------ +# Echo short help message to standard output. +func_usage_message () +{ + $debug_cmd + + eval \$ECHO \""Usage: $usage"\" + echo + $SED -n 's|^# || + /^Written by/{ + x;p;x + } + h + /^Written by/q' < "$progpath" + echo + eval \$ECHO \""$usage_message"\" +} + + +# func_version +# ------------ +# Echo version message to standard output and exit. +func_version () +{ + $debug_cmd + + printf '%s\n' "$progname $scriptversion" + $SED -n ' + /(C)/!b go + :more + /\./!{ + N + s|\n# | | + b more + } + :go + /^# Written by /,/# warranty; / { + s|^# || + s|^# *$|| + s|\((C)\)[ 0-9,-]*[ ,-]\([1-9][0-9]* \)|\1 \2| + p + } + /^# Written by / { + s|^# || + p + } + /^warranty; /q' < "$progpath" + + exit $? +} + + +# Local variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'before-save-hook 'time-stamp) +# time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC" +# time-stamp-time-zone: "UTC" +# End: + +# Set a version string. +scriptversion='(GNU libtool) 2.4.6' + + +# func_echo ARG... +# ---------------- +# Libtool also displays the current mode in messages, so override +# funclib.sh func_echo with this custom definition. +func_echo () +{ + $debug_cmd + + _G_message=$* + + func_echo_IFS=$IFS + IFS=$nl + for _G_line in $_G_message; do + IFS=$func_echo_IFS + $ECHO "$progname${opt_mode+: $opt_mode}: $_G_line" + done + IFS=$func_echo_IFS +} + + +# func_warning ARG... +# ------------------- +# Libtool warnings are not categorized, so override funclib.sh +# func_warning with this simpler definition. +func_warning () +{ + $debug_cmd + + $warning_func ${1+"$@"} +} + + +## ---------------- ## +## Options parsing. ## +## ---------------- ## + +# Hook in the functions to make sure our own options are parsed during +# the option parsing loop. + +usage='$progpath [OPTION]... [MODE-ARG]...' + +# Short help message in response to '-h'. +usage_message="Options: + --config show all configuration variables + --debug enable verbose shell tracing + -n, --dry-run display commands without modifying any files + --features display basic configuration information and exit + --mode=MODE use operation mode MODE + --no-warnings equivalent to '-Wnone' + --preserve-dup-deps don't remove duplicate dependency libraries + --quiet, --silent don't print informational messages + --tag=TAG use configuration variables from tag TAG + -v, --verbose print more informational messages than default + --version print version information + -W, --warnings=CATEGORY report the warnings falling in CATEGORY [all] + -h, --help, --help-all print short, long, or detailed help message +" + +# Additional text appended to 'usage_message' in response to '--help'. +func_help () +{ + $debug_cmd + + func_usage_message + $ECHO "$long_help_message + +MODE must be one of the following: + + clean remove files from the build directory + compile compile a source file into a libtool object + execute automatically set library path, then run a program + finish complete the installation of libtool libraries + install install libraries or executables + link create a library or an executable + uninstall remove libraries from an installed directory + +MODE-ARGS vary depending on the MODE. When passed as first option, +'--mode=MODE' may be abbreviated as 'MODE' or a unique abbreviation of that. +Try '$progname --help --mode=MODE' for a more detailed description of MODE. + +When reporting a bug, please describe a test case to reproduce it and +include the following information: + + host-triplet: $host + shell: $SHELL + compiler: $LTCC + compiler flags: $LTCFLAGS + linker: $LD (gnu? $with_gnu_ld) + version: $progname $scriptversion Debian-2.4.6-15build2 + automake: `($AUTOMAKE --version) 2>/dev/null |$SED 1q` + autoconf: `($AUTOCONF --version) 2>/dev/null |$SED 1q` + +Report bugs to . +GNU libtool home page: . +General help using GNU software: ." + exit 0 +} + + +# func_lo2o OBJECT-NAME +# --------------------- +# Transform OBJECT-NAME from a '.lo' suffix to the platform specific +# object suffix. + +lo2o=s/\\.lo\$/.$objext/ +o2lo=s/\\.$objext\$/.lo/ + +if test yes = "$_G_HAVE_XSI_OPS"; then + eval 'func_lo2o () + { + case $1 in + *.lo) func_lo2o_result=${1%.lo}.$objext ;; + * ) func_lo2o_result=$1 ;; + esac + }' + + # func_xform LIBOBJ-OR-SOURCE + # --------------------------- + # Transform LIBOBJ-OR-SOURCE from a '.o' or '.c' (or otherwise) + # suffix to a '.lo' libtool-object suffix. + eval 'func_xform () + { + func_xform_result=${1%.*}.lo + }' +else + # ...otherwise fall back to using sed. + func_lo2o () + { + func_lo2o_result=`$ECHO "$1" | $SED "$lo2o"` + } + + func_xform () + { + func_xform_result=`$ECHO "$1" | $SED 's|\.[^.]*$|.lo|'` + } +fi + + +# func_fatal_configuration ARG... +# ------------------------------- +# Echo program name prefixed message to standard error, followed by +# a configuration failure hint, and exit. +func_fatal_configuration () +{ + func__fatal_error ${1+"$@"} \ + "See the $PACKAGE documentation for more information." \ + "Fatal configuration error." +} + + +# func_config +# ----------- +# Display the configuration for all the tags in this script. +func_config () +{ + re_begincf='^# ### BEGIN LIBTOOL' + re_endcf='^# ### END LIBTOOL' + + # Default configuration. + $SED "1,/$re_begincf CONFIG/d;/$re_endcf CONFIG/,\$d" < "$progpath" + + # Now print the configurations for the tags. + for tagname in $taglist; do + $SED -n "/$re_begincf TAG CONFIG: $tagname\$/,/$re_endcf TAG CONFIG: $tagname\$/p" < "$progpath" + done + + exit $? +} + + +# func_features +# ------------- +# Display the features supported by this script. +func_features () +{ + echo "host: $host" + if test yes = "$build_libtool_libs"; then + echo "enable shared libraries" + else + echo "disable shared libraries" + fi + if test yes = "$build_old_libs"; then + echo "enable static libraries" + else + echo "disable static libraries" + fi + + exit $? +} + + +# func_enable_tag TAGNAME +# ----------------------- +# Verify that TAGNAME is valid, and either flag an error and exit, or +# enable the TAGNAME tag. We also add TAGNAME to the global $taglist +# variable here. +func_enable_tag () +{ + # Global variable: + tagname=$1 + + re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$" + re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$" + sed_extractcf=/$re_begincf/,/$re_endcf/p + + # Validate tagname. + case $tagname in + *[!-_A-Za-z0-9,/]*) + func_fatal_error "invalid tag name: $tagname" + ;; + esac + + # Don't test for the "default" C tag, as we know it's + # there but not specially marked. + case $tagname in + CC) ;; + *) + if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then + taglist="$taglist $tagname" + + # Evaluate the configuration. Be careful to quote the path + # and the sed script, to avoid splitting on whitespace, but + # also don't use non-portable quotes within backquotes within + # quotes we have to do it in 2 steps: + extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"` + eval "$extractedcf" + else + func_error "ignoring unknown tag $tagname" + fi + ;; + esac +} + + +# func_check_version_match +# ------------------------ +# Ensure that we are using m4 macros, and libtool script from the same +# release of libtool. +func_check_version_match () +{ + if test "$package_revision" != "$macro_revision"; then + if test "$VERSION" != "$macro_version"; then + if test -z "$macro_version"; then + cat >&2 <<_LT_EOF +$progname: Version mismatch error. This is $PACKAGE $VERSION, but the +$progname: definition of this LT_INIT comes from an older release. +$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION +$progname: and run autoconf again. +_LT_EOF + else + cat >&2 <<_LT_EOF +$progname: Version mismatch error. This is $PACKAGE $VERSION, but the +$progname: definition of this LT_INIT comes from $PACKAGE $macro_version. +$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION +$progname: and run autoconf again. +_LT_EOF + fi + else + cat >&2 <<_LT_EOF +$progname: Version mismatch error. This is $PACKAGE $VERSION, revision $package_revision, +$progname: but the definition of this LT_INIT comes from revision $macro_revision. +$progname: You should recreate aclocal.m4 with macros from revision $package_revision +$progname: of $PACKAGE $VERSION and run autoconf again. +_LT_EOF + fi + + exit $EXIT_MISMATCH + fi +} + + +# libtool_options_prep [ARG]... +# ----------------------------- +# Preparation for options parsed by libtool. +libtool_options_prep () +{ + $debug_mode + + # Option defaults: + opt_config=false + opt_dlopen= + opt_dry_run=false + opt_help=false + opt_mode= + opt_preserve_dup_deps=false + opt_quiet=false + + nonopt= + preserve_args= + + _G_rc_lt_options_prep=: + + # Shorthand for --mode=foo, only valid as the first argument + case $1 in + clean|clea|cle|cl) + shift; set dummy --mode clean ${1+"$@"}; shift + ;; + compile|compil|compi|comp|com|co|c) + shift; set dummy --mode compile ${1+"$@"}; shift + ;; + execute|execut|execu|exec|exe|ex|e) + shift; set dummy --mode execute ${1+"$@"}; shift + ;; + finish|finis|fini|fin|fi|f) + shift; set dummy --mode finish ${1+"$@"}; shift + ;; + install|instal|insta|inst|ins|in|i) + shift; set dummy --mode install ${1+"$@"}; shift + ;; + link|lin|li|l) + shift; set dummy --mode link ${1+"$@"}; shift + ;; + uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u) + shift; set dummy --mode uninstall ${1+"$@"}; shift + ;; + *) + _G_rc_lt_options_prep=false + ;; + esac + + if $_G_rc_lt_options_prep; then + # Pass back the list of options. + func_quote_for_eval ${1+"$@"} + libtool_options_prep_result=$func_quote_for_eval_result + fi + + $_G_rc_lt_options_prep +} +func_add_hook func_options_prep libtool_options_prep + + +# libtool_parse_options [ARG]... +# --------------------------------- +# Provide handling for libtool specific options. +libtool_parse_options () +{ + $debug_cmd + + _G_rc_lt_parse_options=false + + # Perform our own loop to consume as many options as possible in + # each iteration. + while test $# -gt 0; do + _G_match_lt_parse_options=: + _G_opt=$1 + shift + case $_G_opt in + --dry-run|--dryrun|-n) + opt_dry_run=: + ;; + + --config) func_config ;; + + --dlopen|-dlopen) + opt_dlopen="${opt_dlopen+$opt_dlopen +}$1" + shift + ;; + + --preserve-dup-deps) + opt_preserve_dup_deps=: ;; + + --features) func_features ;; + + --finish) set dummy --mode finish ${1+"$@"}; shift ;; + + --help) opt_help=: ;; + + --help-all) opt_help=': help-all' ;; + + --mode) test $# = 0 && func_missing_arg $_G_opt && break + opt_mode=$1 + case $1 in + # Valid mode arguments: + clean|compile|execute|finish|install|link|relink|uninstall) ;; + + # Catch anything else as an error + *) func_error "invalid argument for $_G_opt" + exit_cmd=exit + break + ;; + esac + shift + ;; + + --no-silent|--no-quiet) + opt_quiet=false + func_append preserve_args " $_G_opt" + ;; + + --no-warnings|--no-warning|--no-warn) + opt_warning=false + func_append preserve_args " $_G_opt" + ;; + + --no-verbose) + opt_verbose=false + func_append preserve_args " $_G_opt" + ;; + + --silent|--quiet) + opt_quiet=: + opt_verbose=false + func_append preserve_args " $_G_opt" + ;; + + --tag) test $# = 0 && func_missing_arg $_G_opt && break + opt_tag=$1 + func_append preserve_args " $_G_opt $1" + func_enable_tag "$1" + shift + ;; + + --verbose|-v) opt_quiet=false + opt_verbose=: + func_append preserve_args " $_G_opt" + ;; + + # An option not handled by this hook function: + *) set dummy "$_G_opt" ${1+"$@"} ; shift + _G_match_lt_parse_options=false + break + ;; + esac + $_G_match_lt_parse_options && _G_rc_lt_parse_options=: + done + + if $_G_rc_lt_parse_options; then + # save modified positional parameters for caller + func_quote_for_eval ${1+"$@"} + libtool_parse_options_result=$func_quote_for_eval_result + fi + + $_G_rc_lt_parse_options +} +func_add_hook func_parse_options libtool_parse_options + + + +# libtool_validate_options [ARG]... +# --------------------------------- +# Perform any sanity checks on option settings and/or unconsumed +# arguments. +libtool_validate_options () +{ + # save first non-option argument + if test 0 -lt $#; then + nonopt=$1 + shift + fi + + # preserve --debug + test : = "$debug_cmd" || func_append preserve_args " --debug" + + case $host in + # Solaris2 added to fix http://debbugs.gnu.org/cgi/bugreport.cgi?bug=16452 + # see also: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59788 + *cygwin* | *mingw* | *pw32* | *cegcc* | *solaris2* | *os2*) + # don't eliminate duplications in $postdeps and $predeps + opt_duplicate_compiler_generated_deps=: + ;; + *) + opt_duplicate_compiler_generated_deps=$opt_preserve_dup_deps + ;; + esac + + $opt_help || { + # Sanity checks first: + func_check_version_match + + test yes != "$build_libtool_libs" \ + && test yes != "$build_old_libs" \ + && func_fatal_configuration "not configured to build any kind of library" + + # Darwin sucks + eval std_shrext=\"$shrext_cmds\" + + # Only execute mode is allowed to have -dlopen flags. + if test -n "$opt_dlopen" && test execute != "$opt_mode"; then + func_error "unrecognized option '-dlopen'" + $ECHO "$help" 1>&2 + exit $EXIT_FAILURE + fi + + # Change the help message to a mode-specific one. + generic_help=$help + help="Try '$progname --help --mode=$opt_mode' for more information." + } + + # Pass back the unparsed argument list + func_quote_for_eval ${1+"$@"} + libtool_validate_options_result=$func_quote_for_eval_result +} +func_add_hook func_validate_options libtool_validate_options + + +# Process options as early as possible so that --help and --version +# can return quickly. +func_options ${1+"$@"} +eval set dummy "$func_options_result"; shift + + + +## ----------- ## +## Main. ## +## ----------- ## + +magic='%%%MAGIC variable%%%' +magic_exe='%%%MAGIC EXE variable%%%' + +# Global variables. +extracted_archives= +extracted_serial=0 + +# If this variable is set in any of the actions, the command in it +# will be execed at the end. This prevents here-documents from being +# left over by shells. +exec_cmd= + + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +$1 +_LTECHO_EOF' +} + +# func_generated_by_libtool +# True iff stdin has been generated by Libtool. This function is only +# a basic sanity check; it will hardly flush out determined imposters. +func_generated_by_libtool_p () +{ + $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1 +} + +# func_lalib_p file +# True iff FILE is a libtool '.la' library or '.lo' object file. +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_lalib_p () +{ + test -f "$1" && + $SED -e 4q "$1" 2>/dev/null | func_generated_by_libtool_p +} + +# func_lalib_unsafe_p file +# True iff FILE is a libtool '.la' library or '.lo' object file. +# This function implements the same check as func_lalib_p without +# resorting to external programs. To this end, it redirects stdin and +# closes it afterwards, without saving the original file descriptor. +# As a safety measure, use it only where a negative result would be +# fatal anyway. Works if 'file' does not exist. +func_lalib_unsafe_p () +{ + lalib_p=no + if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then + for lalib_p_l in 1 2 3 4 + do + read lalib_p_line + case $lalib_p_line in + \#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;; + esac + done + exec 0<&5 5<&- + fi + test yes = "$lalib_p" +} + +# func_ltwrapper_script_p file +# True iff FILE is a libtool wrapper script +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_ltwrapper_script_p () +{ + test -f "$1" && + $lt_truncate_bin < "$1" 2>/dev/null | func_generated_by_libtool_p +} + +# func_ltwrapper_executable_p file +# True iff FILE is a libtool wrapper executable +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_ltwrapper_executable_p () +{ + func_ltwrapper_exec_suffix= + case $1 in + *.exe) ;; + *) func_ltwrapper_exec_suffix=.exe ;; + esac + $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1 +} + +# func_ltwrapper_scriptname file +# Assumes file is an ltwrapper_executable +# uses $file to determine the appropriate filename for a +# temporary ltwrapper_script. +func_ltwrapper_scriptname () +{ + func_dirname_and_basename "$1" "" "." + func_stripname '' '.exe' "$func_basename_result" + func_ltwrapper_scriptname_result=$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper +} + +# func_ltwrapper_p file +# True iff FILE is a libtool wrapper script or wrapper executable +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_ltwrapper_p () +{ + func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1" +} + + +# func_execute_cmds commands fail_cmd +# Execute tilde-delimited COMMANDS. +# If FAIL_CMD is given, eval that upon failure. +# FAIL_CMD may read-access the current command in variable CMD! +func_execute_cmds () +{ + $debug_cmd + + save_ifs=$IFS; IFS='~' + for cmd in $1; do + IFS=$sp$nl + eval cmd=\"$cmd\" + IFS=$save_ifs + func_show_eval "$cmd" "${2-:}" + done + IFS=$save_ifs +} + + +# func_source file +# Source FILE, adding directory component if necessary. +# Note that it is not necessary on cygwin/mingw to append a dot to +# FILE even if both FILE and FILE.exe exist: automatic-append-.exe +# behavior happens only for exec(3), not for open(2)! Also, sourcing +# 'FILE.' does not work on cygwin managed mounts. +func_source () +{ + $debug_cmd + + case $1 in + */* | *\\*) . "$1" ;; + *) . "./$1" ;; + esac +} + + +# func_resolve_sysroot PATH +# Replace a leading = in PATH with a sysroot. Store the result into +# func_resolve_sysroot_result +func_resolve_sysroot () +{ + func_resolve_sysroot_result=$1 + case $func_resolve_sysroot_result in + =*) + func_stripname '=' '' "$func_resolve_sysroot_result" + func_resolve_sysroot_result=$lt_sysroot$func_stripname_result + ;; + esac +} + +# func_replace_sysroot PATH +# If PATH begins with the sysroot, replace it with = and +# store the result into func_replace_sysroot_result. +func_replace_sysroot () +{ + case $lt_sysroot:$1 in + ?*:"$lt_sysroot"*) + func_stripname "$lt_sysroot" '' "$1" + func_replace_sysroot_result='='$func_stripname_result + ;; + *) + # Including no sysroot. + func_replace_sysroot_result=$1 + ;; + esac +} + +# func_infer_tag arg +# Infer tagged configuration to use if any are available and +# if one wasn't chosen via the "--tag" command line option. +# Only attempt this if the compiler in the base compile +# command doesn't match the default compiler. +# arg is usually of the form 'gcc ...' +func_infer_tag () +{ + $debug_cmd + + if test -n "$available_tags" && test -z "$tagname"; then + CC_quoted= + for arg in $CC; do + func_append_quoted CC_quoted "$arg" + done + CC_expanded=`func_echo_all $CC` + CC_quoted_expanded=`func_echo_all $CC_quoted` + case $@ in + # Blanks in the command may have been stripped by the calling shell, + # but not from the CC environment variable when configure was run. + " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ + " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) ;; + # Blanks at the start of $base_compile will cause this to fail + # if we don't check for them as well. + *) + for z in $available_tags; do + if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then + # Evaluate the configuration. + eval "`$SED -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`" + CC_quoted= + for arg in $CC; do + # Double-quote args containing other shell metacharacters. + func_append_quoted CC_quoted "$arg" + done + CC_expanded=`func_echo_all $CC` + CC_quoted_expanded=`func_echo_all $CC_quoted` + case "$@ " in + " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ + " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) + # The compiler in the base compile command matches + # the one in the tagged configuration. + # Assume this is the tagged configuration we want. + tagname=$z + break + ;; + esac + fi + done + # If $tagname still isn't set, then no tagged configuration + # was found and let the user know that the "--tag" command + # line option must be used. + if test -z "$tagname"; then + func_echo "unable to infer tagged configuration" + func_fatal_error "specify a tag with '--tag'" +# else +# func_verbose "using $tagname tagged configuration" + fi + ;; + esac + fi +} + + + +# func_write_libtool_object output_name pic_name nonpic_name +# Create a libtool object file (analogous to a ".la" file), +# but don't create it if we're doing a dry run. +func_write_libtool_object () +{ + write_libobj=$1 + if test yes = "$build_libtool_libs"; then + write_lobj=\'$2\' + else + write_lobj=none + fi + + if test yes = "$build_old_libs"; then + write_oldobj=\'$3\' + else + write_oldobj=none + fi + + $opt_dry_run || { + cat >${write_libobj}T </dev/null` + if test "$?" -eq 0 && test -n "$func_convert_core_file_wine_to_w32_tmp"; then + func_convert_core_file_wine_to_w32_result=`$ECHO "$func_convert_core_file_wine_to_w32_tmp" | + $SED -e "$sed_naive_backslashify"` + else + func_convert_core_file_wine_to_w32_result= + fi + fi +} +# end: func_convert_core_file_wine_to_w32 + + +# func_convert_core_path_wine_to_w32 ARG +# Helper function used by path conversion functions when $build is *nix, and +# $host is mingw, cygwin, or some other w32 environment. Relies on a correctly +# configured wine environment available, with the winepath program in $build's +# $PATH. Assumes ARG has no leading or trailing path separator characters. +# +# ARG is path to be converted from $build format to win32. +# Result is available in $func_convert_core_path_wine_to_w32_result. +# Unconvertible file (directory) names in ARG are skipped; if no directory names +# are convertible, then the result may be empty. +func_convert_core_path_wine_to_w32 () +{ + $debug_cmd + + # unfortunately, winepath doesn't convert paths, only file names + func_convert_core_path_wine_to_w32_result= + if test -n "$1"; then + oldIFS=$IFS + IFS=: + for func_convert_core_path_wine_to_w32_f in $1; do + IFS=$oldIFS + func_convert_core_file_wine_to_w32 "$func_convert_core_path_wine_to_w32_f" + if test -n "$func_convert_core_file_wine_to_w32_result"; then + if test -z "$func_convert_core_path_wine_to_w32_result"; then + func_convert_core_path_wine_to_w32_result=$func_convert_core_file_wine_to_w32_result + else + func_append func_convert_core_path_wine_to_w32_result ";$func_convert_core_file_wine_to_w32_result" + fi + fi + done + IFS=$oldIFS + fi +} +# end: func_convert_core_path_wine_to_w32 + + +# func_cygpath ARGS... +# Wrapper around calling the cygpath program via LT_CYGPATH. This is used when +# when (1) $build is *nix and Cygwin is hosted via a wine environment; or (2) +# $build is MSYS and $host is Cygwin, or (3) $build is Cygwin. In case (1) or +# (2), returns the Cygwin file name or path in func_cygpath_result (input +# file name or path is assumed to be in w32 format, as previously converted +# from $build's *nix or MSYS format). In case (3), returns the w32 file name +# or path in func_cygpath_result (input file name or path is assumed to be in +# Cygwin format). Returns an empty string on error. +# +# ARGS are passed to cygpath, with the last one being the file name or path to +# be converted. +# +# Specify the absolute *nix (or w32) name to cygpath in the LT_CYGPATH +# environment variable; do not put it in $PATH. +func_cygpath () +{ + $debug_cmd + + if test -n "$LT_CYGPATH" && test -f "$LT_CYGPATH"; then + func_cygpath_result=`$LT_CYGPATH "$@" 2>/dev/null` + if test "$?" -ne 0; then + # on failure, ensure result is empty + func_cygpath_result= + fi + else + func_cygpath_result= + func_error "LT_CYGPATH is empty or specifies non-existent file: '$LT_CYGPATH'" + fi +} +#end: func_cygpath + + +# func_convert_core_msys_to_w32 ARG +# Convert file name or path ARG from MSYS format to w32 format. Return +# result in func_convert_core_msys_to_w32_result. +func_convert_core_msys_to_w32 () +{ + $debug_cmd + + # awkward: cmd appends spaces to result + func_convert_core_msys_to_w32_result=`( cmd //c echo "$1" ) 2>/dev/null | + $SED -e 's/[ ]*$//' -e "$sed_naive_backslashify"` +} +#end: func_convert_core_msys_to_w32 + + +# func_convert_file_check ARG1 ARG2 +# Verify that ARG1 (a file name in $build format) was converted to $host +# format in ARG2. Otherwise, emit an error message, but continue (resetting +# func_to_host_file_result to ARG1). +func_convert_file_check () +{ + $debug_cmd + + if test -z "$2" && test -n "$1"; then + func_error "Could not determine host file name corresponding to" + func_error " '$1'" + func_error "Continuing, but uninstalled executables may not work." + # Fallback: + func_to_host_file_result=$1 + fi +} +# end func_convert_file_check + + +# func_convert_path_check FROM_PATHSEP TO_PATHSEP FROM_PATH TO_PATH +# Verify that FROM_PATH (a path in $build format) was converted to $host +# format in TO_PATH. Otherwise, emit an error message, but continue, resetting +# func_to_host_file_result to a simplistic fallback value (see below). +func_convert_path_check () +{ + $debug_cmd + + if test -z "$4" && test -n "$3"; then + func_error "Could not determine the host path corresponding to" + func_error " '$3'" + func_error "Continuing, but uninstalled executables may not work." + # Fallback. This is a deliberately simplistic "conversion" and + # should not be "improved". See libtool.info. + if test "x$1" != "x$2"; then + lt_replace_pathsep_chars="s|$1|$2|g" + func_to_host_path_result=`echo "$3" | + $SED -e "$lt_replace_pathsep_chars"` + else + func_to_host_path_result=$3 + fi + fi +} +# end func_convert_path_check + + +# func_convert_path_front_back_pathsep FRONTPAT BACKPAT REPL ORIG +# Modifies func_to_host_path_result by prepending REPL if ORIG matches FRONTPAT +# and appending REPL if ORIG matches BACKPAT. +func_convert_path_front_back_pathsep () +{ + $debug_cmd + + case $4 in + $1 ) func_to_host_path_result=$3$func_to_host_path_result + ;; + esac + case $4 in + $2 ) func_append func_to_host_path_result "$3" + ;; + esac +} +# end func_convert_path_front_back_pathsep + + +################################################## +# $build to $host FILE NAME CONVERSION FUNCTIONS # +################################################## +# invoked via '$to_host_file_cmd ARG' +# +# In each case, ARG is the path to be converted from $build to $host format. +# Result will be available in $func_to_host_file_result. + + +# func_to_host_file ARG +# Converts the file name ARG from $build format to $host format. Return result +# in func_to_host_file_result. +func_to_host_file () +{ + $debug_cmd + + $to_host_file_cmd "$1" +} +# end func_to_host_file + + +# func_to_tool_file ARG LAZY +# converts the file name ARG from $build format to toolchain format. Return +# result in func_to_tool_file_result. If the conversion in use is listed +# in (the comma separated) LAZY, no conversion takes place. +func_to_tool_file () +{ + $debug_cmd + + case ,$2, in + *,"$to_tool_file_cmd",*) + func_to_tool_file_result=$1 + ;; + *) + $to_tool_file_cmd "$1" + func_to_tool_file_result=$func_to_host_file_result + ;; + esac +} +# end func_to_tool_file + + +# func_convert_file_noop ARG +# Copy ARG to func_to_host_file_result. +func_convert_file_noop () +{ + func_to_host_file_result=$1 +} +# end func_convert_file_noop + + +# func_convert_file_msys_to_w32 ARG +# Convert file name ARG from (mingw) MSYS to (mingw) w32 format; automatic +# conversion to w32 is not available inside the cwrapper. Returns result in +# func_to_host_file_result. +func_convert_file_msys_to_w32 () +{ + $debug_cmd + + func_to_host_file_result=$1 + if test -n "$1"; then + func_convert_core_msys_to_w32 "$1" + func_to_host_file_result=$func_convert_core_msys_to_w32_result + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_msys_to_w32 + + +# func_convert_file_cygwin_to_w32 ARG +# Convert file name ARG from Cygwin to w32 format. Returns result in +# func_to_host_file_result. +func_convert_file_cygwin_to_w32 () +{ + $debug_cmd + + func_to_host_file_result=$1 + if test -n "$1"; then + # because $build is cygwin, we call "the" cygpath in $PATH; no need to use + # LT_CYGPATH in this case. + func_to_host_file_result=`cygpath -m "$1"` + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_cygwin_to_w32 + + +# func_convert_file_nix_to_w32 ARG +# Convert file name ARG from *nix to w32 format. Requires a wine environment +# and a working winepath. Returns result in func_to_host_file_result. +func_convert_file_nix_to_w32 () +{ + $debug_cmd + + func_to_host_file_result=$1 + if test -n "$1"; then + func_convert_core_file_wine_to_w32 "$1" + func_to_host_file_result=$func_convert_core_file_wine_to_w32_result + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_nix_to_w32 + + +# func_convert_file_msys_to_cygwin ARG +# Convert file name ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. +# Returns result in func_to_host_file_result. +func_convert_file_msys_to_cygwin () +{ + $debug_cmd + + func_to_host_file_result=$1 + if test -n "$1"; then + func_convert_core_msys_to_w32 "$1" + func_cygpath -u "$func_convert_core_msys_to_w32_result" + func_to_host_file_result=$func_cygpath_result + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_msys_to_cygwin + + +# func_convert_file_nix_to_cygwin ARG +# Convert file name ARG from *nix to Cygwin format. Requires Cygwin installed +# in a wine environment, working winepath, and LT_CYGPATH set. Returns result +# in func_to_host_file_result. +func_convert_file_nix_to_cygwin () +{ + $debug_cmd + + func_to_host_file_result=$1 + if test -n "$1"; then + # convert from *nix to w32, then use cygpath to convert from w32 to cygwin. + func_convert_core_file_wine_to_w32 "$1" + func_cygpath -u "$func_convert_core_file_wine_to_w32_result" + func_to_host_file_result=$func_cygpath_result + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_nix_to_cygwin + + +############################################# +# $build to $host PATH CONVERSION FUNCTIONS # +############################################# +# invoked via '$to_host_path_cmd ARG' +# +# In each case, ARG is the path to be converted from $build to $host format. +# The result will be available in $func_to_host_path_result. +# +# Path separators are also converted from $build format to $host format. If +# ARG begins or ends with a path separator character, it is preserved (but +# converted to $host format) on output. +# +# All path conversion functions are named using the following convention: +# file name conversion function : func_convert_file_X_to_Y () +# path conversion function : func_convert_path_X_to_Y () +# where, for any given $build/$host combination the 'X_to_Y' value is the +# same. If conversion functions are added for new $build/$host combinations, +# the two new functions must follow this pattern, or func_init_to_host_path_cmd +# will break. + + +# func_init_to_host_path_cmd +# Ensures that function "pointer" variable $to_host_path_cmd is set to the +# appropriate value, based on the value of $to_host_file_cmd. +to_host_path_cmd= +func_init_to_host_path_cmd () +{ + $debug_cmd + + if test -z "$to_host_path_cmd"; then + func_stripname 'func_convert_file_' '' "$to_host_file_cmd" + to_host_path_cmd=func_convert_path_$func_stripname_result + fi +} + + +# func_to_host_path ARG +# Converts the path ARG from $build format to $host format. Return result +# in func_to_host_path_result. +func_to_host_path () +{ + $debug_cmd + + func_init_to_host_path_cmd + $to_host_path_cmd "$1" +} +# end func_to_host_path + + +# func_convert_path_noop ARG +# Copy ARG to func_to_host_path_result. +func_convert_path_noop () +{ + func_to_host_path_result=$1 +} +# end func_convert_path_noop + + +# func_convert_path_msys_to_w32 ARG +# Convert path ARG from (mingw) MSYS to (mingw) w32 format; automatic +# conversion to w32 is not available inside the cwrapper. Returns result in +# func_to_host_path_result. +func_convert_path_msys_to_w32 () +{ + $debug_cmd + + func_to_host_path_result=$1 + if test -n "$1"; then + # Remove leading and trailing path separator characters from ARG. MSYS + # behavior is inconsistent here; cygpath turns them into '.;' and ';.'; + # and winepath ignores them completely. + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" + func_to_host_path_result=$func_convert_core_msys_to_w32_result + func_convert_path_check : ";" \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" + fi +} +# end func_convert_path_msys_to_w32 + + +# func_convert_path_cygwin_to_w32 ARG +# Convert path ARG from Cygwin to w32 format. Returns result in +# func_to_host_file_result. +func_convert_path_cygwin_to_w32 () +{ + $debug_cmd + + func_to_host_path_result=$1 + if test -n "$1"; then + # See func_convert_path_msys_to_w32: + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_to_host_path_result=`cygpath -m -p "$func_to_host_path_tmp1"` + func_convert_path_check : ";" \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" + fi +} +# end func_convert_path_cygwin_to_w32 + + +# func_convert_path_nix_to_w32 ARG +# Convert path ARG from *nix to w32 format. Requires a wine environment and +# a working winepath. Returns result in func_to_host_file_result. +func_convert_path_nix_to_w32 () +{ + $debug_cmd + + func_to_host_path_result=$1 + if test -n "$1"; then + # See func_convert_path_msys_to_w32: + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" + func_to_host_path_result=$func_convert_core_path_wine_to_w32_result + func_convert_path_check : ";" \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" + fi +} +# end func_convert_path_nix_to_w32 + + +# func_convert_path_msys_to_cygwin ARG +# Convert path ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. +# Returns result in func_to_host_file_result. +func_convert_path_msys_to_cygwin () +{ + $debug_cmd + + func_to_host_path_result=$1 + if test -n "$1"; then + # See func_convert_path_msys_to_w32: + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" + func_cygpath -u -p "$func_convert_core_msys_to_w32_result" + func_to_host_path_result=$func_cygpath_result + func_convert_path_check : : \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" : "$1" + fi +} +# end func_convert_path_msys_to_cygwin + + +# func_convert_path_nix_to_cygwin ARG +# Convert path ARG from *nix to Cygwin format. Requires Cygwin installed in a +# a wine environment, working winepath, and LT_CYGPATH set. Returns result in +# func_to_host_file_result. +func_convert_path_nix_to_cygwin () +{ + $debug_cmd + + func_to_host_path_result=$1 + if test -n "$1"; then + # Remove leading and trailing path separator characters from + # ARG. msys behavior is inconsistent here, cygpath turns them + # into '.;' and ';.', and winepath ignores them completely. + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" + func_cygpath -u -p "$func_convert_core_path_wine_to_w32_result" + func_to_host_path_result=$func_cygpath_result + func_convert_path_check : : \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" : "$1" + fi +} +# end func_convert_path_nix_to_cygwin + + +# func_dll_def_p FILE +# True iff FILE is a Windows DLL '.def' file. +# Keep in sync with _LT_DLL_DEF_P in libtool.m4 +func_dll_def_p () +{ + $debug_cmd + + func_dll_def_p_tmp=`$SED -n \ + -e 's/^[ ]*//' \ + -e '/^\(;.*\)*$/d' \ + -e 's/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p' \ + -e q \ + "$1"` + test DEF = "$func_dll_def_p_tmp" +} + + +# func_mode_compile arg... +func_mode_compile () +{ + $debug_cmd + + # Get the compilation command and the source file. + base_compile= + srcfile=$nonopt # always keep a non-empty value in "srcfile" + suppress_opt=yes + suppress_output= + arg_mode=normal + libobj= + later= + pie_flag= + + for arg + do + case $arg_mode in + arg ) + # do not "continue". Instead, add this to base_compile + lastarg=$arg + arg_mode=normal + ;; + + target ) + libobj=$arg + arg_mode=normal + continue + ;; + + normal ) + # Accept any command-line options. + case $arg in + -o) + test -n "$libobj" && \ + func_fatal_error "you cannot specify '-o' more than once" + arg_mode=target + continue + ;; + + -pie | -fpie | -fPIE) + func_append pie_flag " $arg" + continue + ;; + + -shared | -static | -prefer-pic | -prefer-non-pic) + func_append later " $arg" + continue + ;; + + -no-suppress) + suppress_opt=no + continue + ;; + + -Xcompiler) + arg_mode=arg # the next one goes into the "base_compile" arg list + continue # The current "srcfile" will either be retained or + ;; # replaced later. I would guess that would be a bug. + + -Wc,*) + func_stripname '-Wc,' '' "$arg" + args=$func_stripname_result + lastarg= + save_ifs=$IFS; IFS=, + for arg in $args; do + IFS=$save_ifs + func_append_quoted lastarg "$arg" + done + IFS=$save_ifs + func_stripname ' ' '' "$lastarg" + lastarg=$func_stripname_result + + # Add the arguments to base_compile. + func_append base_compile " $lastarg" + continue + ;; + + *) + # Accept the current argument as the source file. + # The previous "srcfile" becomes the current argument. + # + lastarg=$srcfile + srcfile=$arg + ;; + esac # case $arg + ;; + esac # case $arg_mode + + # Aesthetically quote the previous argument. + func_append_quoted base_compile "$lastarg" + done # for arg + + case $arg_mode in + arg) + func_fatal_error "you must specify an argument for -Xcompile" + ;; + target) + func_fatal_error "you must specify a target with '-o'" + ;; + *) + # Get the name of the library object. + test -z "$libobj" && { + func_basename "$srcfile" + libobj=$func_basename_result + } + ;; + esac + + # Recognize several different file suffixes. + # If the user specifies -o file.o, it is replaced with file.lo + case $libobj in + *.[cCFSifmso] | \ + *.ada | *.adb | *.ads | *.asm | \ + *.c++ | *.cc | *.ii | *.class | *.cpp | *.cxx | \ + *.[fF][09]? | *.for | *.java | *.go | *.obj | *.sx | *.cu | *.cup) + func_xform "$libobj" + libobj=$func_xform_result + ;; + esac + + case $libobj in + *.lo) func_lo2o "$libobj"; obj=$func_lo2o_result ;; + *) + func_fatal_error "cannot determine name of library object from '$libobj'" + ;; + esac + + func_infer_tag $base_compile + + for arg in $later; do + case $arg in + -shared) + test yes = "$build_libtool_libs" \ + || func_fatal_configuration "cannot build a shared library" + build_old_libs=no + continue + ;; + + -static) + build_libtool_libs=no + build_old_libs=yes + continue + ;; + + -prefer-pic) + pic_mode=yes + continue + ;; + + -prefer-non-pic) + pic_mode=no + continue + ;; + esac + done + + func_quote_for_eval "$libobj" + test "X$libobj" != "X$func_quote_for_eval_result" \ + && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"' &()|`$[]' \ + && func_warning "libobj name '$libobj' may not contain shell special characters." + func_dirname_and_basename "$obj" "/" "" + objname=$func_basename_result + xdir=$func_dirname_result + lobj=$xdir$objdir/$objname + + test -z "$base_compile" && \ + func_fatal_help "you must specify a compilation command" + + # Delete any leftover library objects. + if test yes = "$build_old_libs"; then + removelist="$obj $lobj $libobj ${libobj}T" + else + removelist="$lobj $libobj ${libobj}T" + fi + + # On Cygwin there's no "real" PIC flag so we must build both object types + case $host_os in + cygwin* | mingw* | pw32* | os2* | cegcc*) + pic_mode=default + ;; + esac + if test no = "$pic_mode" && test pass_all != "$deplibs_check_method"; then + # non-PIC code in shared libraries is not supported + pic_mode=default + fi + + # Calculate the filename of the output object if compiler does + # not support -o with -c + if test no = "$compiler_c_o"; then + output_obj=`$ECHO "$srcfile" | $SED 's%^.*/%%; s%\.[^.]*$%%'`.$objext + lockfile=$output_obj.lock + else + output_obj= + need_locks=no + lockfile= + fi + + # Lock this critical section if it is needed + # We use this script file to make the link, it avoids creating a new file + if test yes = "$need_locks"; then + until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do + func_echo "Waiting for $lockfile to be removed" + sleep 2 + done + elif test warn = "$need_locks"; then + if test -f "$lockfile"; then + $ECHO "\ +*** ERROR, $lockfile exists and contains: +`cat $lockfile 2>/dev/null` + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support '-c' and '-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $opt_dry_run || $RM $removelist + exit $EXIT_FAILURE + fi + func_append removelist " $output_obj" + $ECHO "$srcfile" > "$lockfile" + fi + + $opt_dry_run || $RM $removelist + func_append removelist " $lockfile" + trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15 + + func_to_tool_file "$srcfile" func_convert_file_msys_to_w32 + srcfile=$func_to_tool_file_result + func_quote_for_eval "$srcfile" + qsrcfile=$func_quote_for_eval_result + + # Only build a PIC object if we are building libtool libraries. + if test yes = "$build_libtool_libs"; then + # Without this assignment, base_compile gets emptied. + fbsd_hideous_sh_bug=$base_compile + + if test no != "$pic_mode"; then + command="$base_compile $qsrcfile $pic_flag" + else + # Don't build PIC code + command="$base_compile $qsrcfile" + fi + + func_mkdir_p "$xdir$objdir" + + if test -z "$output_obj"; then + # Place PIC objects in $objdir + func_append command " -o $lobj" + fi + + func_show_eval_locale "$command" \ + 'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE' + + if test warn = "$need_locks" && + test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then + $ECHO "\ +*** ERROR, $lockfile contains: +`cat $lockfile 2>/dev/null` + +but it should contain: +$srcfile + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support '-c' and '-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $opt_dry_run || $RM $removelist + exit $EXIT_FAILURE + fi + + # Just move the object if needed, then go on to compile the next one + if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then + func_show_eval '$MV "$output_obj" "$lobj"' \ + 'error=$?; $opt_dry_run || $RM $removelist; exit $error' + fi + + # Allow error messages only from the first compilation. + if test yes = "$suppress_opt"; then + suppress_output=' >/dev/null 2>&1' + fi + fi + + # Only build a position-dependent object if we build old libraries. + if test yes = "$build_old_libs"; then + if test yes != "$pic_mode"; then + # Don't build PIC code + command="$base_compile $qsrcfile$pie_flag" + else + command="$base_compile $qsrcfile $pic_flag" + fi + if test yes = "$compiler_c_o"; then + func_append command " -o $obj" + fi + + # Suppress compiler output if we already did a PIC compilation. + func_append command "$suppress_output" + func_show_eval_locale "$command" \ + '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' + + if test warn = "$need_locks" && + test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then + $ECHO "\ +*** ERROR, $lockfile contains: +`cat $lockfile 2>/dev/null` + +but it should contain: +$srcfile + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support '-c' and '-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $opt_dry_run || $RM $removelist + exit $EXIT_FAILURE + fi + + # Just move the object if needed + if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then + func_show_eval '$MV "$output_obj" "$obj"' \ + 'error=$?; $opt_dry_run || $RM $removelist; exit $error' + fi + fi + + $opt_dry_run || { + func_write_libtool_object "$libobj" "$objdir/$objname" "$objname" + + # Unlock the critical section if it was locked + if test no != "$need_locks"; then + removelist=$lockfile + $RM "$lockfile" + fi + } + + exit $EXIT_SUCCESS +} + +$opt_help || { + test compile = "$opt_mode" && func_mode_compile ${1+"$@"} +} + +func_mode_help () +{ + # We need to display help for each of the modes. + case $opt_mode in + "") + # Generic help is extracted from the usage comments + # at the start of this file. + func_help + ;; + + clean) + $ECHO \ +"Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE... + +Remove files from the build directory. + +RM is the name of the program to use to delete files associated with each FILE +(typically '/bin/rm'). RM-OPTIONS are options (such as '-f') to be passed +to RM. + +If FILE is a libtool library, object or program, all the files associated +with it are deleted. Otherwise, only FILE itself is deleted using RM." + ;; + + compile) + $ECHO \ +"Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE + +Compile a source file into a libtool library object. + +This mode accepts the following additional options: + + -o OUTPUT-FILE set the output file name to OUTPUT-FILE + -no-suppress do not suppress compiler output for multiple passes + -prefer-pic try to build PIC objects only + -prefer-non-pic try to build non-PIC objects only + -shared do not build a '.o' file suitable for static linking + -static only build a '.o' file suitable for static linking + -Wc,FLAG pass FLAG directly to the compiler + +COMPILE-COMMAND is a command to be used in creating a 'standard' object file +from the given SOURCEFILE. + +The output file name is determined by removing the directory component from +SOURCEFILE, then substituting the C source code suffix '.c' with the +library object suffix, '.lo'." + ;; + + execute) + $ECHO \ +"Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]... + +Automatically set library path, then run a program. + +This mode accepts the following additional options: + + -dlopen FILE add the directory containing FILE to the library path + +This mode sets the library path environment variable according to '-dlopen' +flags. + +If any of the ARGS are libtool executable wrappers, then they are translated +into their corresponding uninstalled binary, and any of their required library +directories are added to the library path. + +Then, COMMAND is executed, with ARGS as arguments." + ;; + + finish) + $ECHO \ +"Usage: $progname [OPTION]... --mode=finish [LIBDIR]... + +Complete the installation of libtool libraries. + +Each LIBDIR is a directory that contains libtool libraries. + +The commands that this mode executes may require superuser privileges. Use +the '--dry-run' option if you just want to see what would be executed." + ;; + + install) + $ECHO \ +"Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND... + +Install executables or libraries. + +INSTALL-COMMAND is the installation command. The first component should be +either the 'install' or 'cp' program. + +The following components of INSTALL-COMMAND are treated specially: + + -inst-prefix-dir PREFIX-DIR Use PREFIX-DIR as a staging area for installation + +The rest of the components are interpreted as arguments to that command (only +BSD-compatible install options are recognized)." + ;; + + link) + $ECHO \ +"Usage: $progname [OPTION]... --mode=link LINK-COMMAND... + +Link object files or libraries together to form another library, or to +create an executable program. + +LINK-COMMAND is a command using the C compiler that you would use to create +a program from several object files. + +The following components of LINK-COMMAND are treated specially: + + -all-static do not do any dynamic linking at all + -avoid-version do not add a version suffix if possible + -bindir BINDIR specify path to binaries directory (for systems where + libraries must be found in the PATH setting at runtime) + -dlopen FILE '-dlpreopen' FILE if it cannot be dlopened at runtime + -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols + -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) + -export-symbols SYMFILE + try to export only the symbols listed in SYMFILE + -export-symbols-regex REGEX + try to export only the symbols matching REGEX + -LLIBDIR search LIBDIR for required installed libraries + -lNAME OUTPUT-FILE requires the installed library libNAME + -module build a library that can dlopened + -no-fast-install disable the fast-install mode + -no-install link a not-installable executable + -no-undefined declare that a library does not refer to external symbols + -o OUTPUT-FILE create OUTPUT-FILE from the specified objects + -objectlist FILE use a list of object files found in FILE to specify objects + -os2dllname NAME force a short DLL name on OS/2 (no effect on other OSes) + -precious-files-regex REGEX + don't remove output files matching REGEX + -release RELEASE specify package release information + -rpath LIBDIR the created library will eventually be installed in LIBDIR + -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries + -shared only do dynamic linking of libtool libraries + -shrext SUFFIX override the standard shared library file extension + -static do not do any dynamic linking of uninstalled libtool libraries + -static-libtool-libs + do not do any dynamic linking of libtool libraries + -version-info CURRENT[:REVISION[:AGE]] + specify library version info [each variable defaults to 0] + -weak LIBNAME declare that the target provides the LIBNAME interface + -Wc,FLAG + -Xcompiler FLAG pass linker-specific FLAG directly to the compiler + -Wl,FLAG + -Xlinker FLAG pass linker-specific FLAG directly to the linker + -XCClinker FLAG pass link-specific FLAG to the compiler driver (CC) + +All other options (arguments beginning with '-') are ignored. + +Every other argument is treated as a filename. Files ending in '.la' are +treated as uninstalled libtool libraries, other files are standard or library +object files. + +If the OUTPUT-FILE ends in '.la', then a libtool library is created, +only library objects ('.lo' files) may be specified, and '-rpath' is +required, except when creating a convenience library. + +If OUTPUT-FILE ends in '.a' or '.lib', then a standard library is created +using 'ar' and 'ranlib', or on Windows using 'lib'. + +If OUTPUT-FILE ends in '.lo' or '.$objext', then a reloadable object file +is created, otherwise an executable program is created." + ;; + + uninstall) + $ECHO \ +"Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... + +Remove libraries from an installation directory. + +RM is the name of the program to use to delete files associated with each FILE +(typically '/bin/rm'). RM-OPTIONS are options (such as '-f') to be passed +to RM. + +If FILE is a libtool library, all the files associated with it are deleted. +Otherwise, only FILE itself is deleted using RM." + ;; + + *) + func_fatal_help "invalid operation mode '$opt_mode'" + ;; + esac + + echo + $ECHO "Try '$progname --help' for more information about other modes." +} + +# Now that we've collected a possible --mode arg, show help if necessary +if $opt_help; then + if test : = "$opt_help"; then + func_mode_help + else + { + func_help noexit + for opt_mode in compile link execute install finish uninstall clean; do + func_mode_help + done + } | $SED -n '1p; 2,$s/^Usage:/ or: /p' + { + func_help noexit + for opt_mode in compile link execute install finish uninstall clean; do + echo + func_mode_help + done + } | + $SED '1d + /^When reporting/,/^Report/{ + H + d + } + $x + /information about other modes/d + /more detailed .*MODE/d + s/^Usage:.*--mode=\([^ ]*\) .*/Description of \1 mode:/' + fi + exit $? +fi + + +# func_mode_execute arg... +func_mode_execute () +{ + $debug_cmd + + # The first argument is the command name. + cmd=$nonopt + test -z "$cmd" && \ + func_fatal_help "you must specify a COMMAND" + + # Handle -dlopen flags immediately. + for file in $opt_dlopen; do + test -f "$file" \ + || func_fatal_help "'$file' is not a file" + + dir= + case $file in + *.la) + func_resolve_sysroot "$file" + file=$func_resolve_sysroot_result + + # Check to see that this really is a libtool archive. + func_lalib_unsafe_p "$file" \ + || func_fatal_help "'$lib' is not a valid libtool archive" + + # Read the libtool library. + dlname= + library_names= + func_source "$file" + + # Skip this library if it cannot be dlopened. + if test -z "$dlname"; then + # Warn if it was a shared library. + test -n "$library_names" && \ + func_warning "'$file' was not linked with '-export-dynamic'" + continue + fi + + func_dirname "$file" "" "." + dir=$func_dirname_result + + if test -f "$dir/$objdir/$dlname"; then + func_append dir "/$objdir" + else + if test ! -f "$dir/$dlname"; then + func_fatal_error "cannot find '$dlname' in '$dir' or '$dir/$objdir'" + fi + fi + ;; + + *.lo) + # Just add the directory containing the .lo file. + func_dirname "$file" "" "." + dir=$func_dirname_result + ;; + + *) + func_warning "'-dlopen' is ignored for non-libtool libraries and objects" + continue + ;; + esac + + # Get the absolute pathname. + absdir=`cd "$dir" && pwd` + test -n "$absdir" && dir=$absdir + + # Now add the directory to shlibpath_var. + if eval "test -z \"\$$shlibpath_var\""; then + eval "$shlibpath_var=\"\$dir\"" + else + eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" + fi + done + + # This variable tells wrapper scripts just to set shlibpath_var + # rather than running their programs. + libtool_execute_magic=$magic + + # Check if any of the arguments is a wrapper script. + args= + for file + do + case $file in + -* | *.la | *.lo ) ;; + *) + # Do a test to see if this is really a libtool program. + if func_ltwrapper_script_p "$file"; then + func_source "$file" + # Transform arg to wrapped name. + file=$progdir/$program + elif func_ltwrapper_executable_p "$file"; then + func_ltwrapper_scriptname "$file" + func_source "$func_ltwrapper_scriptname_result" + # Transform arg to wrapped name. + file=$progdir/$program + fi + ;; + esac + # Quote arguments (to preserve shell metacharacters). + func_append_quoted args "$file" + done + + if $opt_dry_run; then + # Display what would be done. + if test -n "$shlibpath_var"; then + eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\"" + echo "export $shlibpath_var" + fi + $ECHO "$cmd$args" + exit $EXIT_SUCCESS + else + if test -n "$shlibpath_var"; then + # Export the shlibpath_var. + eval "export $shlibpath_var" + fi + + # Restore saved environment variables + for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES + do + eval "if test \"\${save_$lt_var+set}\" = set; then + $lt_var=\$save_$lt_var; export $lt_var + else + $lt_unset $lt_var + fi" + done + + # Now prepare to actually exec the command. + exec_cmd=\$cmd$args + fi +} + +test execute = "$opt_mode" && func_mode_execute ${1+"$@"} + + +# func_mode_finish arg... +func_mode_finish () +{ + $debug_cmd + + libs= + libdirs= + admincmds= + + for opt in "$nonopt" ${1+"$@"} + do + if test -d "$opt"; then + func_append libdirs " $opt" + + elif test -f "$opt"; then + if func_lalib_unsafe_p "$opt"; then + func_append libs " $opt" + else + func_warning "'$opt' is not a valid libtool archive" + fi + + else + func_fatal_error "invalid argument '$opt'" + fi + done + + if test -n "$libs"; then + if test -n "$lt_sysroot"; then + sysroot_regex=`$ECHO "$lt_sysroot" | $SED "$sed_make_literal_regex"` + sysroot_cmd="s/\([ ']\)$sysroot_regex/\1/g;" + else + sysroot_cmd= + fi + + # Remove sysroot references + if $opt_dry_run; then + for lib in $libs; do + echo "removing references to $lt_sysroot and '=' prefixes from $lib" + done + else + tmpdir=`func_mktempdir` + for lib in $libs; do + $SED -e "$sysroot_cmd s/\([ ']-[LR]\)=/\1/g; s/\([ ']\)=/\1/g" $lib \ + > $tmpdir/tmp-la + mv -f $tmpdir/tmp-la $lib + done + ${RM}r "$tmpdir" + fi + fi + + if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then + for libdir in $libdirs; do + if test -n "$finish_cmds"; then + # Do each command in the finish commands. + func_execute_cmds "$finish_cmds" 'admincmds="$admincmds +'"$cmd"'"' + fi + if test -n "$finish_eval"; then + # Do the single finish_eval. + eval cmds=\"$finish_eval\" + $opt_dry_run || eval "$cmds" || func_append admincmds " + $cmds" + fi + done + fi + + # Exit here if they wanted silent mode. + $opt_quiet && exit $EXIT_SUCCESS + + if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then + echo "----------------------------------------------------------------------" + echo "Libraries have been installed in:" + for libdir in $libdirs; do + $ECHO " $libdir" + done + echo + echo "If you ever happen to want to link against installed libraries" + echo "in a given directory, LIBDIR, you must either use libtool, and" + echo "specify the full pathname of the library, or use the '-LLIBDIR'" + echo "flag during linking and do at least one of the following:" + if test -n "$shlibpath_var"; then + echo " - add LIBDIR to the '$shlibpath_var' environment variable" + echo " during execution" + fi + if test -n "$runpath_var"; then + echo " - add LIBDIR to the '$runpath_var' environment variable" + echo " during linking" + fi + if test -n "$hardcode_libdir_flag_spec"; then + libdir=LIBDIR + eval flag=\"$hardcode_libdir_flag_spec\" + + $ECHO " - use the '$flag' linker flag" + fi + if test -n "$admincmds"; then + $ECHO " - have your system administrator run these commands:$admincmds" + fi + if test -f /etc/ld.so.conf; then + echo " - have your system administrator add LIBDIR to '/etc/ld.so.conf'" + fi + echo + + echo "See any operating system documentation about shared libraries for" + case $host in + solaris2.[6789]|solaris2.1[0-9]) + echo "more information, such as the ld(1), crle(1) and ld.so(8) manual" + echo "pages." + ;; + *) + echo "more information, such as the ld(1) and ld.so(8) manual pages." + ;; + esac + echo "----------------------------------------------------------------------" + fi + exit $EXIT_SUCCESS +} + +test finish = "$opt_mode" && func_mode_finish ${1+"$@"} + + +# func_mode_install arg... +func_mode_install () +{ + $debug_cmd + + # There may be an optional sh(1) argument at the beginning of + # install_prog (especially on Windows NT). + if test "$SHELL" = "$nonopt" || test /bin/sh = "$nonopt" || + # Allow the use of GNU shtool's install command. + case $nonopt in *shtool*) :;; *) false;; esac + then + # Aesthetically quote it. + func_quote_for_eval "$nonopt" + install_prog="$func_quote_for_eval_result " + arg=$1 + shift + else + install_prog= + arg=$nonopt + fi + + # The real first argument should be the name of the installation program. + # Aesthetically quote it. + func_quote_for_eval "$arg" + func_append install_prog "$func_quote_for_eval_result" + install_shared_prog=$install_prog + case " $install_prog " in + *[\\\ /]cp\ *) install_cp=: ;; + *) install_cp=false ;; + esac + + # We need to accept at least all the BSD install flags. + dest= + files= + opts= + prev= + install_type= + isdir=false + stripme= + no_mode=: + for arg + do + arg2= + if test -n "$dest"; then + func_append files " $dest" + dest=$arg + continue + fi + + case $arg in + -d) isdir=: ;; + -f) + if $install_cp; then :; else + prev=$arg + fi + ;; + -g | -m | -o) + prev=$arg + ;; + -s) + stripme=" -s" + continue + ;; + -*) + ;; + *) + # If the previous option needed an argument, then skip it. + if test -n "$prev"; then + if test X-m = "X$prev" && test -n "$install_override_mode"; then + arg2=$install_override_mode + no_mode=false + fi + prev= + else + dest=$arg + continue + fi + ;; + esac + + # Aesthetically quote the argument. + func_quote_for_eval "$arg" + func_append install_prog " $func_quote_for_eval_result" + if test -n "$arg2"; then + func_quote_for_eval "$arg2" + fi + func_append install_shared_prog " $func_quote_for_eval_result" + done + + test -z "$install_prog" && \ + func_fatal_help "you must specify an install program" + + test -n "$prev" && \ + func_fatal_help "the '$prev' option requires an argument" + + if test -n "$install_override_mode" && $no_mode; then + if $install_cp; then :; else + func_quote_for_eval "$install_override_mode" + func_append install_shared_prog " -m $func_quote_for_eval_result" + fi + fi + + if test -z "$files"; then + if test -z "$dest"; then + func_fatal_help "no file or destination specified" + else + func_fatal_help "you must specify a destination" + fi + fi + + # Strip any trailing slash from the destination. + func_stripname '' '/' "$dest" + dest=$func_stripname_result + + # Check to see that the destination is a directory. + test -d "$dest" && isdir=: + if $isdir; then + destdir=$dest + destname= + else + func_dirname_and_basename "$dest" "" "." + destdir=$func_dirname_result + destname=$func_basename_result + + # Not a directory, so check to see that there is only one file specified. + set dummy $files; shift + test "$#" -gt 1 && \ + func_fatal_help "'$dest' is not a directory" + fi + case $destdir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + for file in $files; do + case $file in + *.lo) ;; + *) + func_fatal_help "'$destdir' must be an absolute directory name" + ;; + esac + done + ;; + esac + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic=$magic + + staticlibs= + future_libdirs= + current_libdirs= + for file in $files; do + + # Do each installation. + case $file in + *.$libext) + # Do the static libraries later. + func_append staticlibs " $file" + ;; + + *.la) + func_resolve_sysroot "$file" + file=$func_resolve_sysroot_result + + # Check to see that this really is a libtool archive. + func_lalib_unsafe_p "$file" \ + || func_fatal_help "'$file' is not a valid libtool archive" + + library_names= + old_library= + relink_command= + func_source "$file" + + # Add the libdir to current_libdirs if it is the destination. + if test "X$destdir" = "X$libdir"; then + case "$current_libdirs " in + *" $libdir "*) ;; + *) func_append current_libdirs " $libdir" ;; + esac + else + # Note the libdir as a future libdir. + case "$future_libdirs " in + *" $libdir "*) ;; + *) func_append future_libdirs " $libdir" ;; + esac + fi + + func_dirname "$file" "/" "" + dir=$func_dirname_result + func_append dir "$objdir" + + if test -n "$relink_command"; then + # Determine the prefix the user has applied to our future dir. + inst_prefix_dir=`$ECHO "$destdir" | $SED -e "s%$libdir\$%%"` + + # Don't allow the user to place us outside of our expected + # location b/c this prevents finding dependent libraries that + # are installed to the same prefix. + # At present, this check doesn't affect windows .dll's that + # are installed into $libdir/../bin (currently, that works fine) + # but it's something to keep an eye on. + test "$inst_prefix_dir" = "$destdir" && \ + func_fatal_error "error: cannot install '$file' to a directory not ending in $libdir" + + if test -n "$inst_prefix_dir"; then + # Stick the inst_prefix_dir data into the link command. + relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"` + else + relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%%"` + fi + + func_warning "relinking '$file'" + func_show_eval "$relink_command" \ + 'func_fatal_error "error: relink '\''$file'\'' with the above command before installing it"' + fi + + # See the names of the shared library. + set dummy $library_names; shift + if test -n "$1"; then + realname=$1 + shift + + srcname=$realname + test -n "$relink_command" && srcname=${realname}T + + # Install the shared library and build the symlinks. + func_show_eval "$install_shared_prog $dir/$srcname $destdir/$realname" \ + 'exit $?' + tstripme=$stripme + case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + case $realname in + *.dll.a) + tstripme= + ;; + esac + ;; + os2*) + case $realname in + *_dll.a) + tstripme= + ;; + esac + ;; + esac + if test -n "$tstripme" && test -n "$striplib"; then + func_show_eval "$striplib $destdir/$realname" 'exit $?' + fi + + if test "$#" -gt 0; then + # Delete the old symlinks, and create new ones. + # Try 'ln -sf' first, because the 'ln' binary might depend on + # the symlink we replace! Solaris /bin/ln does not understand -f, + # so we also need to try rm && ln -s. + for linkname + do + test "$linkname" != "$realname" \ + && func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })" + done + fi + + # Do each command in the postinstall commands. + lib=$destdir/$realname + func_execute_cmds "$postinstall_cmds" 'exit $?' + fi + + # Install the pseudo-library for information purposes. + func_basename "$file" + name=$func_basename_result + instname=$dir/${name}i + func_show_eval "$install_prog $instname $destdir/$name" 'exit $?' + + # Maybe install the static library, too. + test -n "$old_library" && func_append staticlibs " $dir/$old_library" + ;; + + *.lo) + # Install (i.e. copy) a libtool object. + + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile=$destdir/$destname + else + func_basename "$file" + destfile=$func_basename_result + destfile=$destdir/$destfile + fi + + # Deduce the name of the destination old-style object file. + case $destfile in + *.lo) + func_lo2o "$destfile" + staticdest=$func_lo2o_result + ;; + *.$objext) + staticdest=$destfile + destfile= + ;; + *) + func_fatal_help "cannot copy a libtool object to '$destfile'" + ;; + esac + + # Install the libtool object if requested. + test -n "$destfile" && \ + func_show_eval "$install_prog $file $destfile" 'exit $?' + + # Install the old object if enabled. + if test yes = "$build_old_libs"; then + # Deduce the name of the old-style object file. + func_lo2o "$file" + staticobj=$func_lo2o_result + func_show_eval "$install_prog \$staticobj \$staticdest" 'exit $?' + fi + exit $EXIT_SUCCESS + ;; + + *) + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile=$destdir/$destname + else + func_basename "$file" + destfile=$func_basename_result + destfile=$destdir/$destfile + fi + + # If the file is missing, and there is a .exe on the end, strip it + # because it is most likely a libtool script we actually want to + # install + stripped_ext= + case $file in + *.exe) + if test ! -f "$file"; then + func_stripname '' '.exe' "$file" + file=$func_stripname_result + stripped_ext=.exe + fi + ;; + esac + + # Do a test to see if this is really a libtool program. + case $host in + *cygwin* | *mingw*) + if func_ltwrapper_executable_p "$file"; then + func_ltwrapper_scriptname "$file" + wrapper=$func_ltwrapper_scriptname_result + else + func_stripname '' '.exe' "$file" + wrapper=$func_stripname_result + fi + ;; + *) + wrapper=$file + ;; + esac + if func_ltwrapper_script_p "$wrapper"; then + notinst_deplibs= + relink_command= + + func_source "$wrapper" + + # Check the variables that should have been set. + test -z "$generated_by_libtool_version" && \ + func_fatal_error "invalid libtool wrapper script '$wrapper'" + + finalize=: + for lib in $notinst_deplibs; do + # Check to see that each library is installed. + libdir= + if test -f "$lib"; then + func_source "$lib" + fi + libfile=$libdir/`$ECHO "$lib" | $SED 's%^.*/%%g'` + if test -n "$libdir" && test ! -f "$libfile"; then + func_warning "'$lib' has not been installed in '$libdir'" + finalize=false + fi + done + + relink_command= + func_source "$wrapper" + + outputname= + if test no = "$fast_install" && test -n "$relink_command"; then + $opt_dry_run || { + if $finalize; then + tmpdir=`func_mktempdir` + func_basename "$file$stripped_ext" + file=$func_basename_result + outputname=$tmpdir/$file + # Replace the output file specification. + relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'` + + $opt_quiet || { + func_quote_for_expand "$relink_command" + eval "func_echo $func_quote_for_expand_result" + } + if eval "$relink_command"; then : + else + func_error "error: relink '$file' with the above command before installing it" + $opt_dry_run || ${RM}r "$tmpdir" + continue + fi + file=$outputname + else + func_warning "cannot relink '$file'" + fi + } + else + # Install the binary that we compiled earlier. + file=`$ECHO "$file$stripped_ext" | $SED "s%\([^/]*\)$%$objdir/\1%"` + fi + fi + + # remove .exe since cygwin /usr/bin/install will append another + # one anyway + case $install_prog,$host in + */usr/bin/install*,*cygwin*) + case $file:$destfile in + *.exe:*.exe) + # this is ok + ;; + *.exe:*) + destfile=$destfile.exe + ;; + *:*.exe) + func_stripname '' '.exe' "$destfile" + destfile=$func_stripname_result + ;; + esac + ;; + esac + func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?' + $opt_dry_run || if test -n "$outputname"; then + ${RM}r "$tmpdir" + fi + ;; + esac + done + + for file in $staticlibs; do + func_basename "$file" + name=$func_basename_result + + # Set up the ranlib parameters. + oldlib=$destdir/$name + func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 + tool_oldlib=$func_to_tool_file_result + + func_show_eval "$install_prog \$file \$oldlib" 'exit $?' + + if test -n "$stripme" && test -n "$old_striplib"; then + func_show_eval "$old_striplib $tool_oldlib" 'exit $?' + fi + + # Do each command in the postinstall commands. + func_execute_cmds "$old_postinstall_cmds" 'exit $?' + done + + test -n "$future_libdirs" && \ + func_warning "remember to run '$progname --finish$future_libdirs'" + + if test -n "$current_libdirs"; then + # Maybe just do a dry run. + $opt_dry_run && current_libdirs=" -n$current_libdirs" + exec_cmd='$SHELL "$progpath" $preserve_args --finish$current_libdirs' + else + exit $EXIT_SUCCESS + fi +} + +test install = "$opt_mode" && func_mode_install ${1+"$@"} + + +# func_generate_dlsyms outputname originator pic_p +# Extract symbols from dlprefiles and create ${outputname}S.o with +# a dlpreopen symbol table. +func_generate_dlsyms () +{ + $debug_cmd + + my_outputname=$1 + my_originator=$2 + my_pic_p=${3-false} + my_prefix=`$ECHO "$my_originator" | $SED 's%[^a-zA-Z0-9]%_%g'` + my_dlsyms= + + if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then + if test -n "$NM" && test -n "$global_symbol_pipe"; then + my_dlsyms=${my_outputname}S.c + else + func_error "not configured to extract global symbols from dlpreopened files" + fi + fi + + if test -n "$my_dlsyms"; then + case $my_dlsyms in + "") ;; + *.c) + # Discover the nlist of each of the dlfiles. + nlist=$output_objdir/$my_outputname.nm + + func_show_eval "$RM $nlist ${nlist}S ${nlist}T" + + # Parse the name list into a source file. + func_verbose "creating $output_objdir/$my_dlsyms" + + $opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\ +/* $my_dlsyms - symbol resolution table for '$my_outputname' dlsym emulation. */ +/* Generated by $PROGRAM (GNU $PACKAGE) $VERSION */ + +#ifdef __cplusplus +extern \"C\" { +#endif + +#if defined __GNUC__ && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4)) +#pragma GCC diagnostic ignored \"-Wstrict-prototypes\" +#endif + +/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ +#if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE +/* DATA imports from DLLs on WIN32 can't be const, because runtime + relocations are performed -- see ld's documentation on pseudo-relocs. */ +# define LT_DLSYM_CONST +#elif defined __osf__ +/* This system does not cope well with relocations in const data. */ +# define LT_DLSYM_CONST +#else +# define LT_DLSYM_CONST const +#endif + +#define STREQ(s1, s2) (strcmp ((s1), (s2)) == 0) + +/* External symbol declarations for the compiler. */\ +" + + if test yes = "$dlself"; then + func_verbose "generating symbol list for '$output'" + + $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist" + + # Add our own program objects to the symbol list. + progfiles=`$ECHO "$objs$old_deplibs" | $SP2NL | $SED "$lo2o" | $NL2SP` + for progfile in $progfiles; do + func_to_tool_file "$progfile" func_convert_file_msys_to_w32 + func_verbose "extracting global C symbols from '$func_to_tool_file_result'" + $opt_dry_run || eval "$NM $func_to_tool_file_result | $global_symbol_pipe >> '$nlist'" + done + + if test -n "$exclude_expsyms"; then + $opt_dry_run || { + eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' + eval '$MV "$nlist"T "$nlist"' + } + fi + + if test -n "$export_symbols_regex"; then + $opt_dry_run || { + eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T' + eval '$MV "$nlist"T "$nlist"' + } + fi + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + export_symbols=$output_objdir/$outputname.exp + $opt_dry_run || { + $RM $export_symbols + eval "$SED -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' + case $host in + *cygwin* | *mingw* | *cegcc* ) + eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' + eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"' + ;; + esac + } + else + $opt_dry_run || { + eval "$SED -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"' + eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T' + eval '$MV "$nlist"T "$nlist"' + case $host in + *cygwin* | *mingw* | *cegcc* ) + eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' + eval 'cat "$nlist" >> "$output_objdir/$outputname.def"' + ;; + esac + } + fi + fi + + for dlprefile in $dlprefiles; do + func_verbose "extracting global C symbols from '$dlprefile'" + func_basename "$dlprefile" + name=$func_basename_result + case $host in + *cygwin* | *mingw* | *cegcc* ) + # if an import library, we need to obtain dlname + if func_win32_import_lib_p "$dlprefile"; then + func_tr_sh "$dlprefile" + eval "curr_lafile=\$libfile_$func_tr_sh_result" + dlprefile_dlbasename= + if test -n "$curr_lafile" && func_lalib_p "$curr_lafile"; then + # Use subshell, to avoid clobbering current variable values + dlprefile_dlname=`source "$curr_lafile" && echo "$dlname"` + if test -n "$dlprefile_dlname"; then + func_basename "$dlprefile_dlname" + dlprefile_dlbasename=$func_basename_result + else + # no lafile. user explicitly requested -dlpreopen . + $sharedlib_from_linklib_cmd "$dlprefile" + dlprefile_dlbasename=$sharedlib_from_linklib_result + fi + fi + $opt_dry_run || { + if test -n "$dlprefile_dlbasename"; then + eval '$ECHO ": $dlprefile_dlbasename" >> "$nlist"' + else + func_warning "Could not compute DLL name from $name" + eval '$ECHO ": $name " >> "$nlist"' + fi + func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 + eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe | + $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/_nm__//' >> '$nlist'" + } + else # not an import lib + $opt_dry_run || { + eval '$ECHO ": $name " >> "$nlist"' + func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 + eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" + } + fi + ;; + *) + $opt_dry_run || { + eval '$ECHO ": $name " >> "$nlist"' + func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 + eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" + } + ;; + esac + done + + $opt_dry_run || { + # Make sure we have at least an empty file. + test -f "$nlist" || : > "$nlist" + + if test -n "$exclude_expsyms"; then + $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T + $MV "$nlist"T "$nlist" + fi + + # Try sorting and uniquifying the output. + if $GREP -v "^: " < "$nlist" | + if sort -k 3 /dev/null 2>&1; then + sort -k 3 + else + sort +2 + fi | + uniq > "$nlist"S; then + : + else + $GREP -v "^: " < "$nlist" > "$nlist"S + fi + + if test -f "$nlist"S; then + eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"' + else + echo '/* NONE */' >> "$output_objdir/$my_dlsyms" + fi + + func_show_eval '$RM "${nlist}I"' + if test -n "$global_symbol_to_import"; then + eval "$global_symbol_to_import"' < "$nlist"S > "$nlist"I' + fi + + echo >> "$output_objdir/$my_dlsyms" "\ + +/* The mapping between symbol names and symbols. */ +typedef struct { + const char *name; + void *address; +} lt_dlsymlist; +extern LT_DLSYM_CONST lt_dlsymlist +lt_${my_prefix}_LTX_preloaded_symbols[];\ +" + + if test -s "$nlist"I; then + echo >> "$output_objdir/$my_dlsyms" "\ +static void lt_syminit(void) +{ + LT_DLSYM_CONST lt_dlsymlist *symbol = lt_${my_prefix}_LTX_preloaded_symbols; + for (; symbol->name; ++symbol) + {" + $SED 's/.*/ if (STREQ (symbol->name, \"&\")) symbol->address = (void *) \&&;/' < "$nlist"I >> "$output_objdir/$my_dlsyms" + echo >> "$output_objdir/$my_dlsyms" "\ + } +}" + fi + echo >> "$output_objdir/$my_dlsyms" "\ +LT_DLSYM_CONST lt_dlsymlist +lt_${my_prefix}_LTX_preloaded_symbols[] = +{ {\"$my_originator\", (void *) 0}," + + if test -s "$nlist"I; then + echo >> "$output_objdir/$my_dlsyms" "\ + {\"@INIT@\", (void *) <_syminit}," + fi + + case $need_lib_prefix in + no) + eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms" + ;; + *) + eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms" + ;; + esac + echo >> "$output_objdir/$my_dlsyms" "\ + {0, (void *) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt_${my_prefix}_LTX_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif\ +" + } # !$opt_dry_run + + pic_flag_for_symtable= + case "$compile_command " in + *" -static "*) ;; + *) + case $host in + # compiling the symbol table file with pic_flag works around + # a FreeBSD bug that causes programs to crash when -lm is + # linked before any other PIC object. But we must not use + # pic_flag when linking with -static. The problem exists in + # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. + *-*-freebsd2.*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) + pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;; + *-*-hpux*) + pic_flag_for_symtable=" $pic_flag" ;; + *) + $my_pic_p && pic_flag_for_symtable=" $pic_flag" + ;; + esac + ;; + esac + symtab_cflags= + for arg in $LTCFLAGS; do + case $arg in + -pie | -fpie | -fPIE) ;; + *) func_append symtab_cflags " $arg" ;; + esac + done + + # Now compile the dynamic symbol file. + func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?' + + # Clean up the generated files. + func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T" "${nlist}I"' + + # Transform the symbol file into the correct name. + symfileobj=$output_objdir/${my_outputname}S.$objext + case $host in + *cygwin* | *mingw* | *cegcc* ) + if test -f "$output_objdir/$my_outputname.def"; then + compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` + finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` + else + compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` + finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` + fi + ;; + *) + compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` + finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` + ;; + esac + ;; + *) + func_fatal_error "unknown suffix for '$my_dlsyms'" + ;; + esac + else + # We keep going just in case the user didn't refer to + # lt_preloaded_symbols. The linker will fail if global_symbol_pipe + # really was required. + + # Nullify the symbol file. + compile_command=`$ECHO "$compile_command" | $SED "s% @SYMFILE@%%"` + finalize_command=`$ECHO "$finalize_command" | $SED "s% @SYMFILE@%%"` + fi +} + +# func_cygming_gnu_implib_p ARG +# This predicate returns with zero status (TRUE) if +# ARG is a GNU/binutils-style import library. Returns +# with nonzero status (FALSE) otherwise. +func_cygming_gnu_implib_p () +{ + $debug_cmd + + func_to_tool_file "$1" func_convert_file_msys_to_w32 + func_cygming_gnu_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $EGREP ' (_head_[A-Za-z0-9_]+_[ad]l*|[A-Za-z0-9_]+_[ad]l*_iname)$'` + test -n "$func_cygming_gnu_implib_tmp" +} + +# func_cygming_ms_implib_p ARG +# This predicate returns with zero status (TRUE) if +# ARG is an MS-style import library. Returns +# with nonzero status (FALSE) otherwise. +func_cygming_ms_implib_p () +{ + $debug_cmd + + func_to_tool_file "$1" func_convert_file_msys_to_w32 + func_cygming_ms_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $GREP '_NULL_IMPORT_DESCRIPTOR'` + test -n "$func_cygming_ms_implib_tmp" +} + +# func_win32_libid arg +# return the library type of file 'arg' +# +# Need a lot of goo to handle *both* DLLs and import libs +# Has to be a shell function in order to 'eat' the argument +# that is supplied when $file_magic_command is called. +# Despite the name, also deal with 64 bit binaries. +func_win32_libid () +{ + $debug_cmd + + win32_libid_type=unknown + win32_fileres=`file -L $1 2>/dev/null` + case $win32_fileres in + *ar\ archive\ import\ library*) # definitely import + win32_libid_type="x86 archive import" + ;; + *ar\ archive*) # could be an import, or static + # Keep the egrep pattern in sync with the one in _LT_CHECK_MAGIC_METHOD. + if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | + $EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' >/dev/null; then + case $nm_interface in + "MS dumpbin") + if func_cygming_ms_implib_p "$1" || + func_cygming_gnu_implib_p "$1" + then + win32_nmres=import + else + win32_nmres= + fi + ;; + *) + func_to_tool_file "$1" func_convert_file_msys_to_w32 + win32_nmres=`eval $NM -f posix -A \"$func_to_tool_file_result\" | + $SED -n -e ' + 1,100{ + / I /{ + s|.*|import| + p + q + } + }'` + ;; + esac + case $win32_nmres in + import*) win32_libid_type="x86 archive import";; + *) win32_libid_type="x86 archive static";; + esac + fi + ;; + *DLL*) + win32_libid_type="x86 DLL" + ;; + *executable*) # but shell scripts are "executable" too... + case $win32_fileres in + *MS\ Windows\ PE\ Intel*) + win32_libid_type="x86 DLL" + ;; + esac + ;; + esac + $ECHO "$win32_libid_type" +} + +# func_cygming_dll_for_implib ARG +# +# Platform-specific function to extract the +# name of the DLL associated with the specified +# import library ARG. +# Invoked by eval'ing the libtool variable +# $sharedlib_from_linklib_cmd +# Result is available in the variable +# $sharedlib_from_linklib_result +func_cygming_dll_for_implib () +{ + $debug_cmd + + sharedlib_from_linklib_result=`$DLLTOOL --identify-strict --identify "$1"` +} + +# func_cygming_dll_for_implib_fallback_core SECTION_NAME LIBNAMEs +# +# The is the core of a fallback implementation of a +# platform-specific function to extract the name of the +# DLL associated with the specified import library LIBNAME. +# +# SECTION_NAME is either .idata$6 or .idata$7, depending +# on the platform and compiler that created the implib. +# +# Echos the name of the DLL associated with the +# specified import library. +func_cygming_dll_for_implib_fallback_core () +{ + $debug_cmd + + match_literal=`$ECHO "$1" | $SED "$sed_make_literal_regex"` + $OBJDUMP -s --section "$1" "$2" 2>/dev/null | + $SED '/^Contents of section '"$match_literal"':/{ + # Place marker at beginning of archive member dllname section + s/.*/====MARK====/ + p + d + } + # These lines can sometimes be longer than 43 characters, but + # are always uninteresting + /:[ ]*file format pe[i]\{,1\}-/d + /^In archive [^:]*:/d + # Ensure marker is printed + /^====MARK====/p + # Remove all lines with less than 43 characters + /^.\{43\}/!d + # From remaining lines, remove first 43 characters + s/^.\{43\}//' | + $SED -n ' + # Join marker and all lines until next marker into a single line + /^====MARK====/ b para + H + $ b para + b + :para + x + s/\n//g + # Remove the marker + s/^====MARK====// + # Remove trailing dots and whitespace + s/[\. \t]*$// + # Print + /./p' | + # we now have a list, one entry per line, of the stringified + # contents of the appropriate section of all members of the + # archive that possess that section. Heuristic: eliminate + # all those that have a first or second character that is + # a '.' (that is, objdump's representation of an unprintable + # character.) This should work for all archives with less than + # 0x302f exports -- but will fail for DLLs whose name actually + # begins with a literal '.' or a single character followed by + # a '.'. + # + # Of those that remain, print the first one. + $SED -e '/^\./d;/^.\./d;q' +} + +# func_cygming_dll_for_implib_fallback ARG +# Platform-specific function to extract the +# name of the DLL associated with the specified +# import library ARG. +# +# This fallback implementation is for use when $DLLTOOL +# does not support the --identify-strict option. +# Invoked by eval'ing the libtool variable +# $sharedlib_from_linklib_cmd +# Result is available in the variable +# $sharedlib_from_linklib_result +func_cygming_dll_for_implib_fallback () +{ + $debug_cmd + + if func_cygming_gnu_implib_p "$1"; then + # binutils import library + sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$7' "$1"` + elif func_cygming_ms_implib_p "$1"; then + # ms-generated import library + sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$6' "$1"` + else + # unknown + sharedlib_from_linklib_result= + fi +} + + +# func_extract_an_archive dir oldlib +func_extract_an_archive () +{ + $debug_cmd + + f_ex_an_ar_dir=$1; shift + f_ex_an_ar_oldlib=$1 + if test yes = "$lock_old_archive_extraction"; then + lockfile=$f_ex_an_ar_oldlib.lock + until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do + func_echo "Waiting for $lockfile to be removed" + sleep 2 + done + fi + func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" \ + 'stat=$?; rm -f "$lockfile"; exit $stat' + if test yes = "$lock_old_archive_extraction"; then + $opt_dry_run || rm -f "$lockfile" + fi + if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then + : + else + func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib" + fi +} + + +# func_extract_archives gentop oldlib ... +func_extract_archives () +{ + $debug_cmd + + my_gentop=$1; shift + my_oldlibs=${1+"$@"} + my_oldobjs= + my_xlib= + my_xabs= + my_xdir= + + for my_xlib in $my_oldlibs; do + # Extract the objects. + case $my_xlib in + [\\/]* | [A-Za-z]:[\\/]*) my_xabs=$my_xlib ;; + *) my_xabs=`pwd`"/$my_xlib" ;; + esac + func_basename "$my_xlib" + my_xlib=$func_basename_result + my_xlib_u=$my_xlib + while :; do + case " $extracted_archives " in + *" $my_xlib_u "*) + func_arith $extracted_serial + 1 + extracted_serial=$func_arith_result + my_xlib_u=lt$extracted_serial-$my_xlib ;; + *) break ;; + esac + done + extracted_archives="$extracted_archives $my_xlib_u" + my_xdir=$my_gentop/$my_xlib_u + + func_mkdir_p "$my_xdir" + + case $host in + *-darwin*) + func_verbose "Extracting $my_xabs" + # Do not bother doing anything if just a dry run + $opt_dry_run || { + darwin_orig_dir=`pwd` + cd $my_xdir || exit $? + darwin_archive=$my_xabs + darwin_curdir=`pwd` + func_basename "$darwin_archive" + darwin_base_archive=$func_basename_result + darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true` + if test -n "$darwin_arches"; then + darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'` + darwin_arch= + func_verbose "$darwin_base_archive has multiple architectures $darwin_arches" + for darwin_arch in $darwin_arches; do + func_mkdir_p "unfat-$$/$darwin_base_archive-$darwin_arch" + $LIPO -thin $darwin_arch -output "unfat-$$/$darwin_base_archive-$darwin_arch/$darwin_base_archive" "$darwin_archive" + cd "unfat-$$/$darwin_base_archive-$darwin_arch" + func_extract_an_archive "`pwd`" "$darwin_base_archive" + cd "$darwin_curdir" + $RM "unfat-$$/$darwin_base_archive-$darwin_arch/$darwin_base_archive" + done # $darwin_arches + ## Okay now we've a bunch of thin objects, gotta fatten them up :) + darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$sed_basename" | sort -u` + darwin_file= + darwin_files= + for darwin_file in $darwin_filelist; do + darwin_files=`find unfat-$$ -name $darwin_file -print | sort | $NL2SP` + $LIPO -create -output "$darwin_file" $darwin_files + done # $darwin_filelist + $RM -rf unfat-$$ + cd "$darwin_orig_dir" + else + cd $darwin_orig_dir + func_extract_an_archive "$my_xdir" "$my_xabs" + fi # $darwin_arches + } # !$opt_dry_run + ;; + *) + func_extract_an_archive "$my_xdir" "$my_xabs" + ;; + esac + my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | sort | $NL2SP` + done + + func_extract_archives_result=$my_oldobjs +} + + +# func_emit_wrapper [arg=no] +# +# Emit a libtool wrapper script on stdout. +# Don't directly open a file because we may want to +# incorporate the script contents within a cygwin/mingw +# wrapper executable. Must ONLY be called from within +# func_mode_link because it depends on a number of variables +# set therein. +# +# ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR +# variable will take. If 'yes', then the emitted script +# will assume that the directory where it is stored is +# the $objdir directory. This is a cygwin/mingw-specific +# behavior. +func_emit_wrapper () +{ + func_emit_wrapper_arg1=${1-no} + + $ECHO "\ +#! $SHELL + +# $output - temporary wrapper script for $objdir/$outputname +# Generated by $PROGRAM (GNU $PACKAGE) $VERSION +# +# The $output program cannot be directly executed until all the libtool +# libraries that it depends on are installed. +# +# This wrapper script should never be moved out of the build directory. +# If it is, it will not operate correctly. + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +sed_quote_subst='$sed_quote_subst' + +# Be Bourne compatible +if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else + case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac +fi +BIN_SH=xpg4; export BIN_SH # for Tru64 +DUALCASE=1; export DUALCASE # for MKS sh + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +relink_command=\"$relink_command\" + +# This environment variable determines our operation mode. +if test \"\$libtool_install_magic\" = \"$magic\"; then + # install mode needs the following variables: + generated_by_libtool_version='$macro_version' + notinst_deplibs='$notinst_deplibs' +else + # When we are sourced in execute mode, \$file and \$ECHO are already set. + if test \"\$libtool_execute_magic\" != \"$magic\"; then + file=\"\$0\"" + + qECHO=`$ECHO "$ECHO" | $SED "$sed_quote_subst"` + $ECHO "\ + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +\$1 +_LTECHO_EOF' +} + ECHO=\"$qECHO\" + fi + +# Very basic option parsing. These options are (a) specific to +# the libtool wrapper, (b) are identical between the wrapper +# /script/ and the wrapper /executable/ that is used only on +# windows platforms, and (c) all begin with the string "--lt-" +# (application programs are unlikely to have options that match +# this pattern). +# +# There are only two supported options: --lt-debug and +# --lt-dump-script. There is, deliberately, no --lt-help. +# +# The first argument to this parsing function should be the +# script's $0 value, followed by "$@". +lt_option_debug= +func_parse_lt_options () +{ + lt_script_arg0=\$0 + shift + for lt_opt + do + case \"\$lt_opt\" in + --lt-debug) lt_option_debug=1 ;; + --lt-dump-script) + lt_dump_D=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%/[^/]*$%%'\` + test \"X\$lt_dump_D\" = \"X\$lt_script_arg0\" && lt_dump_D=. + lt_dump_F=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%^.*/%%'\` + cat \"\$lt_dump_D/\$lt_dump_F\" + exit 0 + ;; + --lt-*) + \$ECHO \"Unrecognized --lt- option: '\$lt_opt'\" 1>&2 + exit 1 + ;; + esac + done + + # Print the debug banner immediately: + if test -n \"\$lt_option_debug\"; then + echo \"$outputname:$output:\$LINENO: libtool wrapper (GNU $PACKAGE) $VERSION\" 1>&2 + fi +} + +# Used when --lt-debug. Prints its arguments to stdout +# (redirection is the responsibility of the caller) +func_lt_dump_args () +{ + lt_dump_args_N=1; + for lt_arg + do + \$ECHO \"$outputname:$output:\$LINENO: newargv[\$lt_dump_args_N]: \$lt_arg\" + lt_dump_args_N=\`expr \$lt_dump_args_N + 1\` + done +} + +# Core function for launching the target application +func_exec_program_core () +{ +" + case $host in + # Backslashes separate directories on plain windows + *-*-mingw | *-*-os2* | *-cegcc*) + $ECHO "\ + if test -n \"\$lt_option_debug\"; then + \$ECHO \"$outputname:$output:\$LINENO: newargv[0]: \$progdir\\\\\$program\" 1>&2 + func_lt_dump_args \${1+\"\$@\"} 1>&2 + fi + exec \"\$progdir\\\\\$program\" \${1+\"\$@\"} +" + ;; + + *) + $ECHO "\ + if test -n \"\$lt_option_debug\"; then + \$ECHO \"$outputname:$output:\$LINENO: newargv[0]: \$progdir/\$program\" 1>&2 + func_lt_dump_args \${1+\"\$@\"} 1>&2 + fi + exec \"\$progdir/\$program\" \${1+\"\$@\"} +" + ;; + esac + $ECHO "\ + \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2 + exit 1 +} + +# A function to encapsulate launching the target application +# Strips options in the --lt-* namespace from \$@ and +# launches target application with the remaining arguments. +func_exec_program () +{ + case \" \$* \" in + *\\ --lt-*) + for lt_wr_arg + do + case \$lt_wr_arg in + --lt-*) ;; + *) set x \"\$@\" \"\$lt_wr_arg\"; shift;; + esac + shift + done ;; + esac + func_exec_program_core \${1+\"\$@\"} +} + + # Parse options + func_parse_lt_options \"\$0\" \${1+\"\$@\"} + + # Find the directory that this script lives in. + thisdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*$%%'\` + test \"x\$thisdir\" = \"x\$file\" && thisdir=. + + # Follow symbolic links until we get to the real thisdir. + file=\`ls -ld \"\$file\" | $SED -n 's/.*-> //p'\` + while test -n \"\$file\"; do + destdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*\$%%'\` + + # If there was a directory component, then change thisdir. + if test \"x\$destdir\" != \"x\$file\"; then + case \"\$destdir\" in + [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;; + *) thisdir=\"\$thisdir/\$destdir\" ;; + esac + fi + + file=\`\$ECHO \"\$file\" | $SED 's%^.*/%%'\` + file=\`ls -ld \"\$thisdir/\$file\" | $SED -n 's/.*-> //p'\` + done + + # Usually 'no', except on cygwin/mingw when embedded into + # the cwrapper. + WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_arg1 + if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then + # special case for '.' + if test \"\$thisdir\" = \".\"; then + thisdir=\`pwd\` + fi + # remove .libs from thisdir + case \"\$thisdir\" in + *[\\\\/]$objdir ) thisdir=\`\$ECHO \"\$thisdir\" | $SED 's%[\\\\/][^\\\\/]*$%%'\` ;; + $objdir ) thisdir=. ;; + esac + fi + + # Try to get the absolute directory name. + absdir=\`cd \"\$thisdir\" && pwd\` + test -n \"\$absdir\" && thisdir=\"\$absdir\" +" + + if test yes = "$fast_install"; then + $ECHO "\ + program=lt-'$outputname'$exeext + progdir=\"\$thisdir/$objdir\" + + if test ! -f \"\$progdir/\$program\" || + { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | $SED 1q\`; \\ + test \"X\$file\" != \"X\$progdir/\$program\"; }; then + + file=\"\$\$-\$program\" + + if test ! -d \"\$progdir\"; then + $MKDIR \"\$progdir\" + else + $RM \"\$progdir/\$file\" + fi" + + $ECHO "\ + + # relink executable if necessary + if test -n \"\$relink_command\"; then + if relink_command_output=\`eval \$relink_command 2>&1\`; then : + else + \$ECHO \"\$relink_command_output\" >&2 + $RM \"\$progdir/\$file\" + exit 1 + fi + fi + + $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || + { $RM \"\$progdir/\$program\"; + $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; } + $RM \"\$progdir/\$file\" + fi" + else + $ECHO "\ + program='$outputname' + progdir=\"\$thisdir/$objdir\" +" + fi + + $ECHO "\ + + if test -f \"\$progdir/\$program\"; then" + + # fixup the dll searchpath if we need to. + # + # Fix the DLL searchpath if we need to. Do this before prepending + # to shlibpath, because on Windows, both are PATH and uninstalled + # libraries must come first. + if test -n "$dllsearchpath"; then + $ECHO "\ + # Add the dll search path components to the executable PATH + PATH=$dllsearchpath:\$PATH +" + fi + + # Export our shlibpath_var if we have one. + if test yes = "$shlibpath_overrides_runpath" && test -n "$shlibpath_var" && test -n "$temp_rpath"; then + $ECHO "\ + # Add our own library path to $shlibpath_var + $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" + + # Some systems cannot cope with colon-terminated $shlibpath_var + # The second colon is a workaround for a bug in BeOS R4 sed + $shlibpath_var=\`\$ECHO \"\$$shlibpath_var\" | $SED 's/::*\$//'\` + + export $shlibpath_var +" + fi + + $ECHO "\ + if test \"\$libtool_execute_magic\" != \"$magic\"; then + # Run the actual program with our arguments. + func_exec_program \${1+\"\$@\"} + fi + else + # The program doesn't exist. + \$ECHO \"\$0: error: '\$progdir/\$program' does not exist\" 1>&2 + \$ECHO \"This script is just a wrapper for \$program.\" 1>&2 + \$ECHO \"See the $PACKAGE documentation for more information.\" 1>&2 + exit 1 + fi +fi\ +" +} + + +# func_emit_cwrapperexe_src +# emit the source code for a wrapper executable on stdout +# Must ONLY be called from within func_mode_link because +# it depends on a number of variable set therein. +func_emit_cwrapperexe_src () +{ + cat < +#include +#ifdef _MSC_VER +# include +# include +# include +#else +# include +# include +# ifdef __CYGWIN__ +# include +# endif +#endif +#include +#include +#include +#include +#include +#include +#include +#include + +#define STREQ(s1, s2) (strcmp ((s1), (s2)) == 0) + +/* declarations of non-ANSI functions */ +#if defined __MINGW32__ +# ifdef __STRICT_ANSI__ +int _putenv (const char *); +# endif +#elif defined __CYGWIN__ +# ifdef __STRICT_ANSI__ +char *realpath (const char *, char *); +int putenv (char *); +int setenv (const char *, const char *, int); +# endif +/* #elif defined other_platform || defined ... */ +#endif + +/* portability defines, excluding path handling macros */ +#if defined _MSC_VER +# define setmode _setmode +# define stat _stat +# define chmod _chmod +# define getcwd _getcwd +# define putenv _putenv +# define S_IXUSR _S_IEXEC +#elif defined __MINGW32__ +# define setmode _setmode +# define stat _stat +# define chmod _chmod +# define getcwd _getcwd +# define putenv _putenv +#elif defined __CYGWIN__ +# define HAVE_SETENV +# define FOPEN_WB "wb" +/* #elif defined other platforms ... */ +#endif + +#if defined PATH_MAX +# define LT_PATHMAX PATH_MAX +#elif defined MAXPATHLEN +# define LT_PATHMAX MAXPATHLEN +#else +# define LT_PATHMAX 1024 +#endif + +#ifndef S_IXOTH +# define S_IXOTH 0 +#endif +#ifndef S_IXGRP +# define S_IXGRP 0 +#endif + +/* path handling portability macros */ +#ifndef DIR_SEPARATOR +# define DIR_SEPARATOR '/' +# define PATH_SEPARATOR ':' +#endif + +#if defined _WIN32 || defined __MSDOS__ || defined __DJGPP__ || \ + defined __OS2__ +# define HAVE_DOS_BASED_FILE_SYSTEM +# define FOPEN_WB "wb" +# ifndef DIR_SEPARATOR_2 +# define DIR_SEPARATOR_2 '\\' +# endif +# ifndef PATH_SEPARATOR_2 +# define PATH_SEPARATOR_2 ';' +# endif +#endif + +#ifndef DIR_SEPARATOR_2 +# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR) +#else /* DIR_SEPARATOR_2 */ +# define IS_DIR_SEPARATOR(ch) \ + (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2)) +#endif /* DIR_SEPARATOR_2 */ + +#ifndef PATH_SEPARATOR_2 +# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR) +#else /* PATH_SEPARATOR_2 */ +# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2) +#endif /* PATH_SEPARATOR_2 */ + +#ifndef FOPEN_WB +# define FOPEN_WB "w" +#endif +#ifndef _O_BINARY +# define _O_BINARY 0 +#endif + +#define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type))) +#define XFREE(stale) do { \ + if (stale) { free (stale); stale = 0; } \ +} while (0) + +#if defined LT_DEBUGWRAPPER +static int lt_debug = 1; +#else +static int lt_debug = 0; +#endif + +const char *program_name = "libtool-wrapper"; /* in case xstrdup fails */ + +void *xmalloc (size_t num); +char *xstrdup (const char *string); +const char *base_name (const char *name); +char *find_executable (const char *wrapper); +char *chase_symlinks (const char *pathspec); +int make_executable (const char *path); +int check_executable (const char *path); +char *strendzap (char *str, const char *pat); +void lt_debugprintf (const char *file, int line, const char *fmt, ...); +void lt_fatal (const char *file, int line, const char *message, ...); +static const char *nonnull (const char *s); +static const char *nonempty (const char *s); +void lt_setenv (const char *name, const char *value); +char *lt_extend_str (const char *orig_value, const char *add, int to_end); +void lt_update_exe_path (const char *name, const char *value); +void lt_update_lib_path (const char *name, const char *value); +char **prepare_spawn (char **argv); +void lt_dump_script (FILE *f); +EOF + + cat <= 0) + && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) + return 1; + else + return 0; +} + +int +make_executable (const char *path) +{ + int rval = 0; + struct stat st; + + lt_debugprintf (__FILE__, __LINE__, "(make_executable): %s\n", + nonempty (path)); + if ((!path) || (!*path)) + return 0; + + if (stat (path, &st) >= 0) + { + rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR); + } + return rval; +} + +/* Searches for the full path of the wrapper. Returns + newly allocated full path name if found, NULL otherwise + Does not chase symlinks, even on platforms that support them. +*/ +char * +find_executable (const char *wrapper) +{ + int has_slash = 0; + const char *p; + const char *p_next; + /* static buffer for getcwd */ + char tmp[LT_PATHMAX + 1]; + size_t tmp_len; + char *concat_name; + + lt_debugprintf (__FILE__, __LINE__, "(find_executable): %s\n", + nonempty (wrapper)); + + if ((wrapper == NULL) || (*wrapper == '\0')) + return NULL; + + /* Absolute path? */ +#if defined HAVE_DOS_BASED_FILE_SYSTEM + if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':') + { + concat_name = xstrdup (wrapper); + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + } + else + { +#endif + if (IS_DIR_SEPARATOR (wrapper[0])) + { + concat_name = xstrdup (wrapper); + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + } +#if defined HAVE_DOS_BASED_FILE_SYSTEM + } +#endif + + for (p = wrapper; *p; p++) + if (*p == '/') + { + has_slash = 1; + break; + } + if (!has_slash) + { + /* no slashes; search PATH */ + const char *path = getenv ("PATH"); + if (path != NULL) + { + for (p = path; *p; p = p_next) + { + const char *q; + size_t p_len; + for (q = p; *q; q++) + if (IS_PATH_SEPARATOR (*q)) + break; + p_len = (size_t) (q - p); + p_next = (*q == '\0' ? q : q + 1); + if (p_len == 0) + { + /* empty path: current directory */ + if (getcwd (tmp, LT_PATHMAX) == NULL) + lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", + nonnull (strerror (errno))); + tmp_len = strlen (tmp); + concat_name = + XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); + memcpy (concat_name, tmp, tmp_len); + concat_name[tmp_len] = '/'; + strcpy (concat_name + tmp_len + 1, wrapper); + } + else + { + concat_name = + XMALLOC (char, p_len + 1 + strlen (wrapper) + 1); + memcpy (concat_name, p, p_len); + concat_name[p_len] = '/'; + strcpy (concat_name + p_len + 1, wrapper); + } + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + } + } + /* not found in PATH; assume curdir */ + } + /* Relative path | not found in path: prepend cwd */ + if (getcwd (tmp, LT_PATHMAX) == NULL) + lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", + nonnull (strerror (errno))); + tmp_len = strlen (tmp); + concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); + memcpy (concat_name, tmp, tmp_len); + concat_name[tmp_len] = '/'; + strcpy (concat_name + tmp_len + 1, wrapper); + + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + return NULL; +} + +char * +chase_symlinks (const char *pathspec) +{ +#ifndef S_ISLNK + return xstrdup (pathspec); +#else + char buf[LT_PATHMAX]; + struct stat s; + char *tmp_pathspec = xstrdup (pathspec); + char *p; + int has_symlinks = 0; + while (strlen (tmp_pathspec) && !has_symlinks) + { + lt_debugprintf (__FILE__, __LINE__, + "checking path component for symlinks: %s\n", + tmp_pathspec); + if (lstat (tmp_pathspec, &s) == 0) + { + if (S_ISLNK (s.st_mode) != 0) + { + has_symlinks = 1; + break; + } + + /* search backwards for last DIR_SEPARATOR */ + p = tmp_pathspec + strlen (tmp_pathspec) - 1; + while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) + p--; + if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) + { + /* no more DIR_SEPARATORS left */ + break; + } + *p = '\0'; + } + else + { + lt_fatal (__FILE__, __LINE__, + "error accessing file \"%s\": %s", + tmp_pathspec, nonnull (strerror (errno))); + } + } + XFREE (tmp_pathspec); + + if (!has_symlinks) + { + return xstrdup (pathspec); + } + + tmp_pathspec = realpath (pathspec, buf); + if (tmp_pathspec == 0) + { + lt_fatal (__FILE__, __LINE__, + "could not follow symlinks for %s", pathspec); + } + return xstrdup (tmp_pathspec); +#endif +} + +char * +strendzap (char *str, const char *pat) +{ + size_t len, patlen; + + assert (str != NULL); + assert (pat != NULL); + + len = strlen (str); + patlen = strlen (pat); + + if (patlen <= len) + { + str += len - patlen; + if (STREQ (str, pat)) + *str = '\0'; + } + return str; +} + +void +lt_debugprintf (const char *file, int line, const char *fmt, ...) +{ + va_list args; + if (lt_debug) + { + (void) fprintf (stderr, "%s:%s:%d: ", program_name, file, line); + va_start (args, fmt); + (void) vfprintf (stderr, fmt, args); + va_end (args); + } +} + +static void +lt_error_core (int exit_status, const char *file, + int line, const char *mode, + const char *message, va_list ap) +{ + fprintf (stderr, "%s:%s:%d: %s: ", program_name, file, line, mode); + vfprintf (stderr, message, ap); + fprintf (stderr, ".\n"); + + if (exit_status >= 0) + exit (exit_status); +} + +void +lt_fatal (const char *file, int line, const char *message, ...) +{ + va_list ap; + va_start (ap, message); + lt_error_core (EXIT_FAILURE, file, line, "FATAL", message, ap); + va_end (ap); +} + +static const char * +nonnull (const char *s) +{ + return s ? s : "(null)"; +} + +static const char * +nonempty (const char *s) +{ + return (s && !*s) ? "(empty)" : nonnull (s); +} + +void +lt_setenv (const char *name, const char *value) +{ + lt_debugprintf (__FILE__, __LINE__, + "(lt_setenv) setting '%s' to '%s'\n", + nonnull (name), nonnull (value)); + { +#ifdef HAVE_SETENV + /* always make a copy, for consistency with !HAVE_SETENV */ + char *str = xstrdup (value); + setenv (name, str, 1); +#else + size_t len = strlen (name) + 1 + strlen (value) + 1; + char *str = XMALLOC (char, len); + sprintf (str, "%s=%s", name, value); + if (putenv (str) != EXIT_SUCCESS) + { + XFREE (str); + } +#endif + } +} + +char * +lt_extend_str (const char *orig_value, const char *add, int to_end) +{ + char *new_value; + if (orig_value && *orig_value) + { + size_t orig_value_len = strlen (orig_value); + size_t add_len = strlen (add); + new_value = XMALLOC (char, add_len + orig_value_len + 1); + if (to_end) + { + strcpy (new_value, orig_value); + strcpy (new_value + orig_value_len, add); + } + else + { + strcpy (new_value, add); + strcpy (new_value + add_len, orig_value); + } + } + else + { + new_value = xstrdup (add); + } + return new_value; +} + +void +lt_update_exe_path (const char *name, const char *value) +{ + lt_debugprintf (__FILE__, __LINE__, + "(lt_update_exe_path) modifying '%s' by prepending '%s'\n", + nonnull (name), nonnull (value)); + + if (name && *name && value && *value) + { + char *new_value = lt_extend_str (getenv (name), value, 0); + /* some systems can't cope with a ':'-terminated path #' */ + size_t len = strlen (new_value); + while ((len > 0) && IS_PATH_SEPARATOR (new_value[len-1])) + { + new_value[--len] = '\0'; + } + lt_setenv (name, new_value); + XFREE (new_value); + } +} + +void +lt_update_lib_path (const char *name, const char *value) +{ + lt_debugprintf (__FILE__, __LINE__, + "(lt_update_lib_path) modifying '%s' by prepending '%s'\n", + nonnull (name), nonnull (value)); + + if (name && *name && value && *value) + { + char *new_value = lt_extend_str (getenv (name), value, 0); + lt_setenv (name, new_value); + XFREE (new_value); + } +} + +EOF + case $host_os in + mingw*) + cat <<"EOF" + +/* Prepares an argument vector before calling spawn(). + Note that spawn() does not by itself call the command interpreter + (getenv ("COMSPEC") != NULL ? getenv ("COMSPEC") : + ({ OSVERSIONINFO v; v.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + GetVersionEx(&v); + v.dwPlatformId == VER_PLATFORM_WIN32_NT; + }) ? "cmd.exe" : "command.com"). + Instead it simply concatenates the arguments, separated by ' ', and calls + CreateProcess(). We must quote the arguments since Win32 CreateProcess() + interprets characters like ' ', '\t', '\\', '"' (but not '<' and '>') in a + special way: + - Space and tab are interpreted as delimiters. They are not treated as + delimiters if they are surrounded by double quotes: "...". + - Unescaped double quotes are removed from the input. Their only effect is + that within double quotes, space and tab are treated like normal + characters. + - Backslashes not followed by double quotes are not special. + - But 2*n+1 backslashes followed by a double quote become + n backslashes followed by a double quote (n >= 0): + \" -> " + \\\" -> \" + \\\\\" -> \\" + */ +#define SHELL_SPECIAL_CHARS "\"\\ \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" +#define SHELL_SPACE_CHARS " \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" +char ** +prepare_spawn (char **argv) +{ + size_t argc; + char **new_argv; + size_t i; + + /* Count number of arguments. */ + for (argc = 0; argv[argc] != NULL; argc++) + ; + + /* Allocate new argument vector. */ + new_argv = XMALLOC (char *, argc + 1); + + /* Put quoted arguments into the new argument vector. */ + for (i = 0; i < argc; i++) + { + const char *string = argv[i]; + + if (string[0] == '\0') + new_argv[i] = xstrdup ("\"\""); + else if (strpbrk (string, SHELL_SPECIAL_CHARS) != NULL) + { + int quote_around = (strpbrk (string, SHELL_SPACE_CHARS) != NULL); + size_t length; + unsigned int backslashes; + const char *s; + char *quoted_string; + char *p; + + length = 0; + backslashes = 0; + if (quote_around) + length++; + for (s = string; *s != '\0'; s++) + { + char c = *s; + if (c == '"') + length += backslashes + 1; + length++; + if (c == '\\') + backslashes++; + else + backslashes = 0; + } + if (quote_around) + length += backslashes + 1; + + quoted_string = XMALLOC (char, length + 1); + + p = quoted_string; + backslashes = 0; + if (quote_around) + *p++ = '"'; + for (s = string; *s != '\0'; s++) + { + char c = *s; + if (c == '"') + { + unsigned int j; + for (j = backslashes + 1; j > 0; j--) + *p++ = '\\'; + } + *p++ = c; + if (c == '\\') + backslashes++; + else + backslashes = 0; + } + if (quote_around) + { + unsigned int j; + for (j = backslashes; j > 0; j--) + *p++ = '\\'; + *p++ = '"'; + } + *p = '\0'; + + new_argv[i] = quoted_string; + } + else + new_argv[i] = (char *) string; + } + new_argv[argc] = NULL; + + return new_argv; +} +EOF + ;; + esac + + cat <<"EOF" +void lt_dump_script (FILE* f) +{ +EOF + func_emit_wrapper yes | + $SED -n -e ' +s/^\(.\{79\}\)\(..*\)/\1\ +\2/ +h +s/\([\\"]\)/\\\1/g +s/$/\\n/ +s/\([^\n]*\).*/ fputs ("\1", f);/p +g +D' + cat <<"EOF" +} +EOF +} +# end: func_emit_cwrapperexe_src + +# func_win32_import_lib_p ARG +# True if ARG is an import lib, as indicated by $file_magic_cmd +func_win32_import_lib_p () +{ + $debug_cmd + + case `eval $file_magic_cmd \"\$1\" 2>/dev/null | $SED -e 10q` in + *import*) : ;; + *) false ;; + esac +} + +# func_suncc_cstd_abi +# !!ONLY CALL THIS FOR SUN CC AFTER $compile_command IS FULLY EXPANDED!! +# Several compiler flags select an ABI that is incompatible with the +# Cstd library. Avoid specifying it if any are in CXXFLAGS. +func_suncc_cstd_abi () +{ + $debug_cmd + + case " $compile_command " in + *" -compat=g "*|*\ -std=c++[0-9][0-9]\ *|*" -library=stdcxx4 "*|*" -library=stlport4 "*) + suncc_use_cstd_abi=no + ;; + *) + suncc_use_cstd_abi=yes + ;; + esac +} + +# func_mode_link arg... +func_mode_link () +{ + $debug_cmd + + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + # It is impossible to link a dll without this setting, and + # we shouldn't force the makefile maintainer to figure out + # what system we are compiling for in order to pass an extra + # flag for every libtool invocation. + # allow_undefined=no + + # FIXME: Unfortunately, there are problems with the above when trying + # to make a dll that has undefined symbols, in which case not + # even a static library is built. For now, we need to specify + # -no-undefined on the libtool link line when we can be certain + # that all symbols are satisfied, otherwise we get a static library. + allow_undefined=yes + ;; + *) + allow_undefined=yes + ;; + esac + libtool_args=$nonopt + base_compile="$nonopt $@" + compile_command=$nonopt + finalize_command=$nonopt + + compile_rpath= + finalize_rpath= + compile_shlibpath= + finalize_shlibpath= + convenience= + old_convenience= + deplibs= + old_deplibs= + compiler_flags= + linker_flags= + dllsearchpath= + lib_search_path=`pwd` + inst_prefix_dir= + new_inherited_linker_flags= + + avoid_version=no + bindir= + dlfiles= + dlprefiles= + dlself=no + export_dynamic=no + export_symbols= + export_symbols_regex= + generated= + libobjs= + ltlibs= + module=no + no_install=no + objs= + os2dllname= + non_pic_objects= + precious_files_regex= + prefer_static_libs=no + preload=false + prev= + prevarg= + release= + rpath= + xrpath= + perm_rpath= + temp_rpath= + thread_safe=no + vinfo= + vinfo_number=no + weak_libs= + single_module=$wl-single_module + func_infer_tag $base_compile + + # We need to know -static, to get the right output filenames. + for arg + do + case $arg in + -shared) + test yes != "$build_libtool_libs" \ + && func_fatal_configuration "cannot build a shared library" + build_old_libs=no + break + ;; + -all-static | -static | -static-libtool-libs) + case $arg in + -all-static) + if test yes = "$build_libtool_libs" && test -z "$link_static_flag"; then + func_warning "complete static linking is impossible in this configuration" + fi + if test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=yes + ;; + -static) + if test -z "$pic_flag" && test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=built + ;; + -static-libtool-libs) + if test -z "$pic_flag" && test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=yes + ;; + esac + build_libtool_libs=no + build_old_libs=yes + break + ;; + esac + done + + # See if our shared archives depend on static archives. + test -n "$old_archive_from_new_cmds" && build_old_libs=yes + + # Go through the arguments, transforming them on the way. + while test "$#" -gt 0; do + arg=$1 + shift + func_quote_for_eval "$arg" + qarg=$func_quote_for_eval_unquoted_result + func_append libtool_args " $func_quote_for_eval_result" + + # If the previous option needs an argument, assign it. + if test -n "$prev"; then + case $prev in + output) + func_append compile_command " @OUTPUT@" + func_append finalize_command " @OUTPUT@" + ;; + esac + + case $prev in + bindir) + bindir=$arg + prev= + continue + ;; + dlfiles|dlprefiles) + $preload || { + # Add the symbol object into the linking commands. + func_append compile_command " @SYMFILE@" + func_append finalize_command " @SYMFILE@" + preload=: + } + case $arg in + *.la | *.lo) ;; # We handle these cases below. + force) + if test no = "$dlself"; then + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + self) + if test dlprefiles = "$prev"; then + dlself=yes + elif test dlfiles = "$prev" && test yes != "$dlopen_self"; then + dlself=yes + else + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + *) + if test dlfiles = "$prev"; then + func_append dlfiles " $arg" + else + func_append dlprefiles " $arg" + fi + prev= + continue + ;; + esac + ;; + expsyms) + export_symbols=$arg + test -f "$arg" \ + || func_fatal_error "symbol file '$arg' does not exist" + prev= + continue + ;; + expsyms_regex) + export_symbols_regex=$arg + prev= + continue + ;; + framework) + case $host in + *-*-darwin*) + case "$deplibs " in + *" $qarg.ltframework "*) ;; + *) func_append deplibs " $qarg.ltframework" # this is fixed later + ;; + esac + ;; + esac + prev= + continue + ;; + inst_prefix) + inst_prefix_dir=$arg + prev= + continue + ;; + mllvm) + # Clang does not use LLVM to link, so we can simply discard any + # '-mllvm $arg' options when doing the link step. + prev= + continue + ;; + objectlist) + if test -f "$arg"; then + save_arg=$arg + moreargs= + for fil in `cat "$save_arg"` + do +# func_append moreargs " $fil" + arg=$fil + # A libtool-controlled object. + + # Check to see that this really is a libtool object. + if func_lalib_unsafe_p "$arg"; then + pic_object= + non_pic_object= + + # Read the .lo file + func_source "$arg" + + if test -z "$pic_object" || + test -z "$non_pic_object" || + test none = "$pic_object" && + test none = "$non_pic_object"; then + func_fatal_error "cannot find name of object for '$arg'" + fi + + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir=$func_dirname_result + + if test none != "$pic_object"; then + # Prepend the subdirectory the object is found in. + pic_object=$xdir$pic_object + + if test dlfiles = "$prev"; then + if test yes = "$build_libtool_libs" && test yes = "$dlopen_support"; then + func_append dlfiles " $pic_object" + prev= + continue + else + # If libtool objects are unsupported, then we need to preload. + prev=dlprefiles + fi + fi + + # CHECK ME: I think I busted this. -Ossama + if test dlprefiles = "$prev"; then + # Preload the old-style object. + func_append dlprefiles " $pic_object" + prev= + fi + + # A PIC object. + func_append libobjs " $pic_object" + arg=$pic_object + fi + + # Non-PIC object. + if test none != "$non_pic_object"; then + # Prepend the subdirectory the object is found in. + non_pic_object=$xdir$non_pic_object + + # A standard non-PIC object + func_append non_pic_objects " $non_pic_object" + if test -z "$pic_object" || test none = "$pic_object"; then + arg=$non_pic_object + fi + else + # If the PIC object exists, use it instead. + # $xdir was prepended to $pic_object above. + non_pic_object=$pic_object + func_append non_pic_objects " $non_pic_object" + fi + else + # Only an error if not doing a dry-run. + if $opt_dry_run; then + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir=$func_dirname_result + + func_lo2o "$arg" + pic_object=$xdir$objdir/$func_lo2o_result + non_pic_object=$xdir$func_lo2o_result + func_append libobjs " $pic_object" + func_append non_pic_objects " $non_pic_object" + else + func_fatal_error "'$arg' is not a valid libtool object" + fi + fi + done + else + func_fatal_error "link input file '$arg' does not exist" + fi + arg=$save_arg + prev= + continue + ;; + os2dllname) + os2dllname=$arg + prev= + continue + ;; + precious_regex) + precious_files_regex=$arg + prev= + continue + ;; + release) + release=-$arg + prev= + continue + ;; + rpath | xrpath) + # We need an absolute path. + case $arg in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + func_fatal_error "only absolute run-paths are allowed" + ;; + esac + if test rpath = "$prev"; then + case "$rpath " in + *" $arg "*) ;; + *) func_append rpath " $arg" ;; + esac + else + case "$xrpath " in + *" $arg "*) ;; + *) func_append xrpath " $arg" ;; + esac + fi + prev= + continue + ;; + shrext) + shrext_cmds=$arg + prev= + continue + ;; + weak) + func_append weak_libs " $arg" + prev= + continue + ;; + xcclinker) + func_append linker_flags " $qarg" + func_append compiler_flags " $qarg" + prev= + func_append compile_command " $qarg" + func_append finalize_command " $qarg" + continue + ;; + xcompiler) + func_append compiler_flags " $qarg" + prev= + func_append compile_command " $qarg" + func_append finalize_command " $qarg" + continue + ;; + xlinker) + func_append linker_flags " $qarg" + func_append compiler_flags " $wl$qarg" + prev= + func_append compile_command " $wl$qarg" + func_append finalize_command " $wl$qarg" + continue + ;; + *) + eval "$prev=\"\$arg\"" + prev= + continue + ;; + esac + fi # test -n "$prev" + + prevarg=$arg + + case $arg in + -all-static) + if test -n "$link_static_flag"; then + # See comment for -static flag below, for more details. + func_append compile_command " $link_static_flag" + func_append finalize_command " $link_static_flag" + fi + continue + ;; + + -allow-undefined) + # FIXME: remove this flag sometime in the future. + func_fatal_error "'-allow-undefined' must not be used because it is the default" + ;; + + -avoid-version) + avoid_version=yes + continue + ;; + + -bindir) + prev=bindir + continue + ;; + + -dlopen) + prev=dlfiles + continue + ;; + + -dlpreopen) + prev=dlprefiles + continue + ;; + + -export-dynamic) + export_dynamic=yes + continue + ;; + + -export-symbols | -export-symbols-regex) + if test -n "$export_symbols" || test -n "$export_symbols_regex"; then + func_fatal_error "more than one -exported-symbols argument is not allowed" + fi + if test X-export-symbols = "X$arg"; then + prev=expsyms + else + prev=expsyms_regex + fi + continue + ;; + + -framework) + prev=framework + continue + ;; + + -inst-prefix-dir) + prev=inst_prefix + continue + ;; + + # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* + # so, if we see these flags be careful not to treat them like -L + -L[A-Z][A-Z]*:*) + case $with_gcc/$host in + no/*-*-irix* | /*-*-irix*) + func_append compile_command " $arg" + func_append finalize_command " $arg" + ;; + esac + continue + ;; + + -L*) + func_stripname "-L" '' "$arg" + if test -z "$func_stripname_result"; then + if test "$#" -gt 0; then + func_fatal_error "require no space between '-L' and '$1'" + else + func_fatal_error "need path for '-L' option" + fi + fi + func_resolve_sysroot "$func_stripname_result" + dir=$func_resolve_sysroot_result + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + absdir=`cd "$dir" && pwd` + test -z "$absdir" && \ + func_fatal_error "cannot determine absolute directory name of '$dir'" + dir=$absdir + ;; + esac + case "$deplibs " in + *" -L$dir "* | *" $arg "*) + # Will only happen for absolute or sysroot arguments + ;; + *) + # Preserve sysroot, but never include relative directories + case $dir in + [\\/]* | [A-Za-z]:[\\/]* | =*) func_append deplibs " $arg" ;; + *) func_append deplibs " -L$dir" ;; + esac + func_append lib_search_path " $dir" + ;; + esac + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + testbindir=`$ECHO "$dir" | $SED 's*/lib$*/bin*'` + case :$dllsearchpath: in + *":$dir:"*) ;; + ::) dllsearchpath=$dir;; + *) func_append dllsearchpath ":$dir";; + esac + case :$dllsearchpath: in + *":$testbindir:"*) ;; + ::) dllsearchpath=$testbindir;; + *) func_append dllsearchpath ":$testbindir";; + esac + ;; + esac + continue + ;; + + -l*) + if test X-lc = "X$arg" || test X-lm = "X$arg"; then + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*) + # These systems don't actually have a C or math library (as such) + continue + ;; + *-*-os2*) + # These systems don't actually have a C library (as such) + test X-lc = "X$arg" && continue + ;; + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig*) + # Do not include libc due to us having libc/libc_r. + test X-lc = "X$arg" && continue + ;; + *-*-rhapsody* | *-*-darwin1.[012]) + # Rhapsody C and math libraries are in the System framework + func_append deplibs " System.ltframework" + continue + ;; + *-*-sco3.2v5* | *-*-sco5v6*) + # Causes problems with __ctype + test X-lc = "X$arg" && continue + ;; + *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) + # Compiler inserts libc in the correct place for threads to work + test X-lc = "X$arg" && continue + ;; + esac + elif test X-lc_r = "X$arg"; then + case $host in + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig*) + # Do not include libc_r directly, use -pthread flag. + continue + ;; + esac + fi + func_append deplibs " $arg" + continue + ;; + + -mllvm) + prev=mllvm + continue + ;; + + -module) + module=yes + continue + ;; + + # Tru64 UNIX uses -model [arg] to determine the layout of C++ + # classes, name mangling, and exception handling. + # Darwin uses the -arch flag to determine output architecture. + -model|-arch|-isysroot|--sysroot) + func_append compiler_flags " $arg" + func_append compile_command " $arg" + func_append finalize_command " $arg" + prev=xcompiler + continue + ;; + + -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ + |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) + func_append compiler_flags " $arg" + func_append compile_command " $arg" + func_append finalize_command " $arg" + case "$new_inherited_linker_flags " in + *" $arg "*) ;; + * ) func_append new_inherited_linker_flags " $arg" ;; + esac + continue + ;; + + -multi_module) + single_module=$wl-multi_module + continue + ;; + + -no-fast-install) + fast_install=no + continue + ;; + + -no-install) + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*) + # The PATH hackery in wrapper scripts is required on Windows + # and Darwin in order for the loader to find any dlls it needs. + func_warning "'-no-install' is ignored for $host" + func_warning "assuming '-no-fast-install' instead" + fast_install=no + ;; + *) no_install=yes ;; + esac + continue + ;; + + -no-undefined) + allow_undefined=no + continue + ;; + + -objectlist) + prev=objectlist + continue + ;; + + -os2dllname) + prev=os2dllname + continue + ;; + + -o) prev=output ;; + + -precious-files-regex) + prev=precious_regex + continue + ;; + + -release) + prev=release + continue + ;; + + -rpath) + prev=rpath + continue + ;; + + -R) + prev=xrpath + continue + ;; + + -R*) + func_stripname '-R' '' "$arg" + dir=$func_stripname_result + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + =*) + func_stripname '=' '' "$dir" + dir=$lt_sysroot$func_stripname_result + ;; + *) + func_fatal_error "only absolute run-paths are allowed" + ;; + esac + case "$xrpath " in + *" $dir "*) ;; + *) func_append xrpath " $dir" ;; + esac + continue + ;; + + -shared) + # The effects of -shared are defined in a previous loop. + continue + ;; + + -shrext) + prev=shrext + continue + ;; + + -static | -static-libtool-libs) + # The effects of -static are defined in a previous loop. + # We used to do the same as -all-static on platforms that + # didn't have a PIC flag, but the assumption that the effects + # would be equivalent was wrong. It would break on at least + # Digital Unix and AIX. + continue + ;; + + -thread-safe) + thread_safe=yes + continue + ;; + + -version-info) + prev=vinfo + continue + ;; + + -version-number) + prev=vinfo + vinfo_number=yes + continue + ;; + + -weak) + prev=weak + continue + ;; + + -Wc,*) + func_stripname '-Wc,' '' "$arg" + args=$func_stripname_result + arg= + save_ifs=$IFS; IFS=, + for flag in $args; do + IFS=$save_ifs + func_quote_for_eval "$flag" + func_append arg " $func_quote_for_eval_result" + func_append compiler_flags " $func_quote_for_eval_result" + done + IFS=$save_ifs + func_stripname ' ' '' "$arg" + arg=$func_stripname_result + ;; + + -Wl,*) + func_stripname '-Wl,' '' "$arg" + args=$func_stripname_result + arg= + save_ifs=$IFS; IFS=, + for flag in $args; do + IFS=$save_ifs + func_quote_for_eval "$flag" + func_append arg " $wl$func_quote_for_eval_result" + func_append compiler_flags " $wl$func_quote_for_eval_result" + func_append linker_flags " $func_quote_for_eval_result" + done + IFS=$save_ifs + func_stripname ' ' '' "$arg" + arg=$func_stripname_result + ;; + + -Xcompiler) + prev=xcompiler + continue + ;; + + -Xlinker) + prev=xlinker + continue + ;; + + -XCClinker) + prev=xcclinker + continue + ;; + + # -msg_* for osf cc + -msg_*) + func_quote_for_eval "$arg" + arg=$func_quote_for_eval_result + ;; + + # Flags to be passed through unchanged, with rationale: + # -64, -mips[0-9] enable 64-bit mode for the SGI compiler + # -r[0-9][0-9]* specify processor for the SGI compiler + # -xarch=*, -xtarget=* enable 64-bit mode for the Sun compiler + # +DA*, +DD* enable 64-bit mode for the HP compiler + # -q* compiler args for the IBM compiler + # -m*, -t[45]*, -txscale* architecture-specific flags for GCC + # -F/path path to uninstalled frameworks, gcc on darwin + # -p, -pg, --coverage, -fprofile-* profiling flags for GCC + # -fstack-protector* stack protector flags for GCC + # @file GCC response files + # -tp=* Portland pgcc target processor selection + # --sysroot=* for sysroot support + # -O*, -g*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization + # -specs=* GCC specs files + # -stdlib=* select c++ std lib with clang + # -fsanitize=* Clang/GCC memory and address sanitizer + # -fuse-ld=* Linker select flags for GCC + # -static-* direct GCC to link specific libraries statically + # -fcilkplus Cilk Plus language extension features for C/C++ + -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \ + -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \ + -O*|-g*|-flto*|-fwhopr*|-fuse-linker-plugin|-fstack-protector*|-stdlib=*| \ + -specs=*|-fsanitize=*|-fuse-ld=*|-static-*|-fcilkplus) + func_quote_for_eval "$arg" + arg=$func_quote_for_eval_result + func_append compile_command " $arg" + func_append finalize_command " $arg" + func_append compiler_flags " $arg" + continue + ;; + + -Z*) + if test os2 = "`expr $host : '.*\(os2\)'`"; then + # OS/2 uses -Zxxx to specify OS/2-specific options + compiler_flags="$compiler_flags $arg" + func_append compile_command " $arg" + func_append finalize_command " $arg" + case $arg in + -Zlinker | -Zstack) + prev=xcompiler + ;; + esac + continue + else + # Otherwise treat like 'Some other compiler flag' below + func_quote_for_eval "$arg" + arg=$func_quote_for_eval_result + fi + ;; + + # Some other compiler flag. + -* | +*) + func_quote_for_eval "$arg" + arg=$func_quote_for_eval_result + ;; + + *.$objext) + # A standard object. + func_append objs " $arg" + ;; + + *.lo) + # A libtool-controlled object. + + # Check to see that this really is a libtool object. + if func_lalib_unsafe_p "$arg"; then + pic_object= + non_pic_object= + + # Read the .lo file + func_source "$arg" + + if test -z "$pic_object" || + test -z "$non_pic_object" || + test none = "$pic_object" && + test none = "$non_pic_object"; then + func_fatal_error "cannot find name of object for '$arg'" + fi + + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir=$func_dirname_result + + test none = "$pic_object" || { + # Prepend the subdirectory the object is found in. + pic_object=$xdir$pic_object + + if test dlfiles = "$prev"; then + if test yes = "$build_libtool_libs" && test yes = "$dlopen_support"; then + func_append dlfiles " $pic_object" + prev= + continue + else + # If libtool objects are unsupported, then we need to preload. + prev=dlprefiles + fi + fi + + # CHECK ME: I think I busted this. -Ossama + if test dlprefiles = "$prev"; then + # Preload the old-style object. + func_append dlprefiles " $pic_object" + prev= + fi + + # A PIC object. + func_append libobjs " $pic_object" + arg=$pic_object + } + + # Non-PIC object. + if test none != "$non_pic_object"; then + # Prepend the subdirectory the object is found in. + non_pic_object=$xdir$non_pic_object + + # A standard non-PIC object + func_append non_pic_objects " $non_pic_object" + if test -z "$pic_object" || test none = "$pic_object"; then + arg=$non_pic_object + fi + else + # If the PIC object exists, use it instead. + # $xdir was prepended to $pic_object above. + non_pic_object=$pic_object + func_append non_pic_objects " $non_pic_object" + fi + else + # Only an error if not doing a dry-run. + if $opt_dry_run; then + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir=$func_dirname_result + + func_lo2o "$arg" + pic_object=$xdir$objdir/$func_lo2o_result + non_pic_object=$xdir$func_lo2o_result + func_append libobjs " $pic_object" + func_append non_pic_objects " $non_pic_object" + else + func_fatal_error "'$arg' is not a valid libtool object" + fi + fi + ;; + + *.$libext) + # An archive. + func_append deplibs " $arg" + func_append old_deplibs " $arg" + continue + ;; + + *.la) + # A libtool-controlled library. + + func_resolve_sysroot "$arg" + if test dlfiles = "$prev"; then + # This library was specified with -dlopen. + func_append dlfiles " $func_resolve_sysroot_result" + prev= + elif test dlprefiles = "$prev"; then + # The library was specified with -dlpreopen. + func_append dlprefiles " $func_resolve_sysroot_result" + prev= + else + func_append deplibs " $func_resolve_sysroot_result" + fi + continue + ;; + + # Some other compiler argument. + *) + # Unknown arguments in both finalize_command and compile_command need + # to be aesthetically quoted because they are evaled later. + func_quote_for_eval "$arg" + arg=$func_quote_for_eval_result + ;; + esac # arg + + # Now actually substitute the argument into the commands. + if test -n "$arg"; then + func_append compile_command " $arg" + func_append finalize_command " $arg" + fi + done # argument parsing loop + + test -n "$prev" && \ + func_fatal_help "the '$prevarg' option requires an argument" + + if test yes = "$export_dynamic" && test -n "$export_dynamic_flag_spec"; then + eval arg=\"$export_dynamic_flag_spec\" + func_append compile_command " $arg" + func_append finalize_command " $arg" + fi + + oldlibs= + # calculate the name of the file, without its directory + func_basename "$output" + outputname=$func_basename_result + libobjs_save=$libobjs + + if test -n "$shlibpath_var"; then + # get the directories listed in $shlibpath_var + eval shlib_search_path=\`\$ECHO \"\$$shlibpath_var\" \| \$SED \'s/:/ /g\'\` + else + shlib_search_path= + fi + eval sys_lib_search_path=\"$sys_lib_search_path_spec\" + eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" + + # Definition is injected by LT_CONFIG during libtool generation. + func_munge_path_list sys_lib_dlsearch_path "$LT_SYS_LIBRARY_PATH" + + func_dirname "$output" "/" "" + output_objdir=$func_dirname_result$objdir + func_to_tool_file "$output_objdir/" + tool_output_objdir=$func_to_tool_file_result + # Create the object directory. + func_mkdir_p "$output_objdir" + + # Determine the type of output + case $output in + "") + func_fatal_help "you must specify an output file" + ;; + *.$libext) linkmode=oldlib ;; + *.lo | *.$objext) linkmode=obj ;; + *.la) linkmode=lib ;; + *) linkmode=prog ;; # Anything else should be a program. + esac + + specialdeplibs= + + libs= + # Find all interdependent deplibs by searching for libraries + # that are linked more than once (e.g. -la -lb -la) + for deplib in $deplibs; do + if $opt_preserve_dup_deps; then + case "$libs " in + *" $deplib "*) func_append specialdeplibs " $deplib" ;; + esac + fi + func_append libs " $deplib" + done + + if test lib = "$linkmode"; then + libs="$predeps $libs $compiler_lib_search_path $postdeps" + + # Compute libraries that are listed more than once in $predeps + # $postdeps and mark them as special (i.e., whose duplicates are + # not to be eliminated). + pre_post_deps= + if $opt_duplicate_compiler_generated_deps; then + for pre_post_dep in $predeps $postdeps; do + case "$pre_post_deps " in + *" $pre_post_dep "*) func_append specialdeplibs " $pre_post_deps" ;; + esac + func_append pre_post_deps " $pre_post_dep" + done + fi + pre_post_deps= + fi + + deplibs= + newdependency_libs= + newlib_search_path= + need_relink=no # whether we're linking any uninstalled libtool libraries + notinst_deplibs= # not-installed libtool libraries + notinst_path= # paths that contain not-installed libtool libraries + + case $linkmode in + lib) + passes="conv dlpreopen link" + for file in $dlfiles $dlprefiles; do + case $file in + *.la) ;; + *) + func_fatal_help "libraries can '-dlopen' only libtool libraries: $file" + ;; + esac + done + ;; + prog) + compile_deplibs= + finalize_deplibs= + alldeplibs=false + newdlfiles= + newdlprefiles= + passes="conv scan dlopen dlpreopen link" + ;; + *) passes="conv" + ;; + esac + + for pass in $passes; do + # The preopen pass in lib mode reverses $deplibs; put it back here + # so that -L comes before libs that need it for instance... + if test lib,link = "$linkmode,$pass"; then + ## FIXME: Find the place where the list is rebuilt in the wrong + ## order, and fix it there properly + tmp_deplibs= + for deplib in $deplibs; do + tmp_deplibs="$deplib $tmp_deplibs" + done + deplibs=$tmp_deplibs + fi + + if test lib,link = "$linkmode,$pass" || + test prog,scan = "$linkmode,$pass"; then + libs=$deplibs + deplibs= + fi + if test prog = "$linkmode"; then + case $pass in + dlopen) libs=$dlfiles ;; + dlpreopen) libs=$dlprefiles ;; + link) + libs="$deplibs %DEPLIBS%" + test "X$link_all_deplibs" != Xno && libs="$libs $dependency_libs" + ;; + esac + fi + if test lib,dlpreopen = "$linkmode,$pass"; then + # Collect and forward deplibs of preopened libtool libs + for lib in $dlprefiles; do + # Ignore non-libtool-libs + dependency_libs= + func_resolve_sysroot "$lib" + case $lib in + *.la) func_source "$func_resolve_sysroot_result" ;; + esac + + # Collect preopened libtool deplibs, except any this library + # has declared as weak libs + for deplib in $dependency_libs; do + func_basename "$deplib" + deplib_base=$func_basename_result + case " $weak_libs " in + *" $deplib_base "*) ;; + *) func_append deplibs " $deplib" ;; + esac + done + done + libs=$dlprefiles + fi + if test dlopen = "$pass"; then + # Collect dlpreopened libraries + save_deplibs=$deplibs + deplibs= + fi + + for deplib in $libs; do + lib= + found=false + case $deplib in + -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ + |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) + if test prog,link = "$linkmode,$pass"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + func_append compiler_flags " $deplib" + if test lib = "$linkmode"; then + case "$new_inherited_linker_flags " in + *" $deplib "*) ;; + * ) func_append new_inherited_linker_flags " $deplib" ;; + esac + fi + fi + continue + ;; + -l*) + if test lib != "$linkmode" && test prog != "$linkmode"; then + func_warning "'-l' is ignored for archives/objects" + continue + fi + func_stripname '-l' '' "$deplib" + name=$func_stripname_result + if test lib = "$linkmode"; then + searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path" + else + searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path" + fi + for searchdir in $searchdirs; do + for search_ext in .la $std_shrext .so .a; do + # Search the libtool library + lib=$searchdir/lib$name$search_ext + if test -f "$lib"; then + if test .la = "$search_ext"; then + found=: + else + found=false + fi + break 2 + fi + done + done + if $found; then + # deplib is a libtool library + # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib, + # We need to do some special things here, and not later. + if test yes = "$allow_libtool_libs_with_static_runtimes"; then + case " $predeps $postdeps " in + *" $deplib "*) + if func_lalib_p "$lib"; then + library_names= + old_library= + func_source "$lib" + for l in $old_library $library_names; do + ll=$l + done + if test "X$ll" = "X$old_library"; then # only static version available + found=false + func_dirname "$lib" "" "." + ladir=$func_dirname_result + lib=$ladir/$old_library + if test prog,link = "$linkmode,$pass"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + test lib = "$linkmode" && newdependency_libs="$deplib $newdependency_libs" + fi + continue + fi + fi + ;; + *) ;; + esac + fi + else + # deplib doesn't seem to be a libtool library + if test prog,link = "$linkmode,$pass"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + test lib = "$linkmode" && newdependency_libs="$deplib $newdependency_libs" + fi + continue + fi + ;; # -l + *.ltframework) + if test prog,link = "$linkmode,$pass"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + if test lib = "$linkmode"; then + case "$new_inherited_linker_flags " in + *" $deplib "*) ;; + * ) func_append new_inherited_linker_flags " $deplib" ;; + esac + fi + fi + continue + ;; + -L*) + case $linkmode in + lib) + deplibs="$deplib $deplibs" + test conv = "$pass" && continue + newdependency_libs="$deplib $newdependency_libs" + func_stripname '-L' '' "$deplib" + func_resolve_sysroot "$func_stripname_result" + func_append newlib_search_path " $func_resolve_sysroot_result" + ;; + prog) + if test conv = "$pass"; then + deplibs="$deplib $deplibs" + continue + fi + if test scan = "$pass"; then + deplibs="$deplib $deplibs" + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + func_stripname '-L' '' "$deplib" + func_resolve_sysroot "$func_stripname_result" + func_append newlib_search_path " $func_resolve_sysroot_result" + ;; + *) + func_warning "'-L' is ignored for archives/objects" + ;; + esac # linkmode + continue + ;; # -L + -R*) + if test link = "$pass"; then + func_stripname '-R' '' "$deplib" + func_resolve_sysroot "$func_stripname_result" + dir=$func_resolve_sysroot_result + # Make sure the xrpath contains only unique directories. + case "$xrpath " in + *" $dir "*) ;; + *) func_append xrpath " $dir" ;; + esac + fi + deplibs="$deplib $deplibs" + continue + ;; + *.la) + func_resolve_sysroot "$deplib" + lib=$func_resolve_sysroot_result + ;; + *.$libext) + if test conv = "$pass"; then + deplibs="$deplib $deplibs" + continue + fi + case $linkmode in + lib) + # Linking convenience modules into shared libraries is allowed, + # but linking other static libraries is non-portable. + case " $dlpreconveniencelibs " in + *" $deplib "*) ;; + *) + valid_a_lib=false + case $deplibs_check_method in + match_pattern*) + set dummy $deplibs_check_method; shift + match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` + if eval "\$ECHO \"$deplib\"" 2>/dev/null | $SED 10q \ + | $EGREP "$match_pattern_regex" > /dev/null; then + valid_a_lib=: + fi + ;; + pass_all) + valid_a_lib=: + ;; + esac + if $valid_a_lib; then + echo + $ECHO "*** Warning: Linking the shared library $output against the" + $ECHO "*** static library $deplib is not portable!" + deplibs="$deplib $deplibs" + else + echo + $ECHO "*** Warning: Trying to link with static lib archive $deplib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have" + echo "*** because the file extensions .$libext of this argument makes me believe" + echo "*** that it is just a static archive that I should not use here." + fi + ;; + esac + continue + ;; + prog) + if test link != "$pass"; then + deplibs="$deplib $deplibs" + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + continue + ;; + esac # linkmode + ;; # *.$libext + *.lo | *.$objext) + if test conv = "$pass"; then + deplibs="$deplib $deplibs" + elif test prog = "$linkmode"; then + if test dlpreopen = "$pass" || test yes != "$dlopen_support" || test no = "$build_libtool_libs"; then + # If there is no dlopen support or we're linking statically, + # we need to preload. + func_append newdlprefiles " $deplib" + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + func_append newdlfiles " $deplib" + fi + fi + continue + ;; + %DEPLIBS%) + alldeplibs=: + continue + ;; + esac # case $deplib + + $found || test -f "$lib" \ + || func_fatal_error "cannot find the library '$lib' or unhandled argument '$deplib'" + + # Check to see that this really is a libtool archive. + func_lalib_unsafe_p "$lib" \ + || func_fatal_error "'$lib' is not a valid libtool archive" + + func_dirname "$lib" "" "." + ladir=$func_dirname_result + + dlname= + dlopen= + dlpreopen= + libdir= + library_names= + old_library= + inherited_linker_flags= + # If the library was installed with an old release of libtool, + # it will not redefine variables installed, or shouldnotlink + installed=yes + shouldnotlink=no + avoidtemprpath= + + + # Read the .la file + func_source "$lib" + + # Convert "-framework foo" to "foo.ltframework" + if test -n "$inherited_linker_flags"; then + tmp_inherited_linker_flags=`$ECHO "$inherited_linker_flags" | $SED 's/-framework \([^ $]*\)/\1.ltframework/g'` + for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do + case " $new_inherited_linker_flags " in + *" $tmp_inherited_linker_flag "*) ;; + *) func_append new_inherited_linker_flags " $tmp_inherited_linker_flag";; + esac + done + fi + dependency_libs=`$ECHO " $dependency_libs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + if test lib,link = "$linkmode,$pass" || + test prog,scan = "$linkmode,$pass" || + { test prog != "$linkmode" && test lib != "$linkmode"; }; then + test -n "$dlopen" && func_append dlfiles " $dlopen" + test -n "$dlpreopen" && func_append dlprefiles " $dlpreopen" + fi + + if test conv = "$pass"; then + # Only check for convenience libraries + deplibs="$lib $deplibs" + if test -z "$libdir"; then + if test -z "$old_library"; then + func_fatal_error "cannot find name of link library for '$lib'" + fi + # It is a libtool convenience library, so add in its objects. + func_append convenience " $ladir/$objdir/$old_library" + func_append old_convenience " $ladir/$objdir/$old_library" + tmp_libs= + for deplib in $dependency_libs; do + deplibs="$deplib $deplibs" + if $opt_preserve_dup_deps; then + case "$tmp_libs " in + *" $deplib "*) func_append specialdeplibs " $deplib" ;; + esac + fi + func_append tmp_libs " $deplib" + done + elif test prog != "$linkmode" && test lib != "$linkmode"; then + func_fatal_error "'$lib' is not a convenience library" + fi + continue + fi # $pass = conv + + + # Get the name of the library we link against. + linklib= + if test -n "$old_library" && + { test yes = "$prefer_static_libs" || + test built,no = "$prefer_static_libs,$installed"; }; then + linklib=$old_library + else + for l in $old_library $library_names; do + linklib=$l + done + fi + if test -z "$linklib"; then + func_fatal_error "cannot find name of link library for '$lib'" + fi + + # This library was specified with -dlopen. + if test dlopen = "$pass"; then + test -z "$libdir" \ + && func_fatal_error "cannot -dlopen a convenience library: '$lib'" + if test -z "$dlname" || + test yes != "$dlopen_support" || + test no = "$build_libtool_libs" + then + # If there is no dlname, no dlopen support or we're linking + # statically, we need to preload. We also need to preload any + # dependent libraries so libltdl's deplib preloader doesn't + # bomb out in the load deplibs phase. + func_append dlprefiles " $lib $dependency_libs" + else + func_append newdlfiles " $lib" + fi + continue + fi # $pass = dlopen + + # We need an absolute path. + case $ladir in + [\\/]* | [A-Za-z]:[\\/]*) abs_ladir=$ladir ;; + *) + abs_ladir=`cd "$ladir" && pwd` + if test -z "$abs_ladir"; then + func_warning "cannot determine absolute directory name of '$ladir'" + func_warning "passing it literally to the linker, although it might fail" + abs_ladir=$ladir + fi + ;; + esac + func_basename "$lib" + laname=$func_basename_result + + # Find the relevant object directory and library name. + if test yes = "$installed"; then + if test ! -f "$lt_sysroot$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then + func_warning "library '$lib' was moved." + dir=$ladir + absdir=$abs_ladir + libdir=$abs_ladir + else + dir=$lt_sysroot$libdir + absdir=$lt_sysroot$libdir + fi + test yes = "$hardcode_automatic" && avoidtemprpath=yes + else + if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then + dir=$ladir + absdir=$abs_ladir + # Remove this search path later + func_append notinst_path " $abs_ladir" + else + dir=$ladir/$objdir + absdir=$abs_ladir/$objdir + # Remove this search path later + func_append notinst_path " $abs_ladir" + fi + fi # $installed = yes + func_stripname 'lib' '.la' "$laname" + name=$func_stripname_result + + # This library was specified with -dlpreopen. + if test dlpreopen = "$pass"; then + if test -z "$libdir" && test prog = "$linkmode"; then + func_fatal_error "only libraries may -dlpreopen a convenience library: '$lib'" + fi + case $host in + # special handling for platforms with PE-DLLs. + *cygwin* | *mingw* | *cegcc* ) + # Linker will automatically link against shared library if both + # static and shared are present. Therefore, ensure we extract + # symbols from the import library if a shared library is present + # (otherwise, the dlopen module name will be incorrect). We do + # this by putting the import library name into $newdlprefiles. + # We recover the dlopen module name by 'saving' the la file + # name in a special purpose variable, and (later) extracting the + # dlname from the la file. + if test -n "$dlname"; then + func_tr_sh "$dir/$linklib" + eval "libfile_$func_tr_sh_result=\$abs_ladir/\$laname" + func_append newdlprefiles " $dir/$linklib" + else + func_append newdlprefiles " $dir/$old_library" + # Keep a list of preopened convenience libraries to check + # that they are being used correctly in the link pass. + test -z "$libdir" && \ + func_append dlpreconveniencelibs " $dir/$old_library" + fi + ;; + * ) + # Prefer using a static library (so that no silly _DYNAMIC symbols + # are required to link). + if test -n "$old_library"; then + func_append newdlprefiles " $dir/$old_library" + # Keep a list of preopened convenience libraries to check + # that they are being used correctly in the link pass. + test -z "$libdir" && \ + func_append dlpreconveniencelibs " $dir/$old_library" + # Otherwise, use the dlname, so that lt_dlopen finds it. + elif test -n "$dlname"; then + func_append newdlprefiles " $dir/$dlname" + else + func_append newdlprefiles " $dir/$linklib" + fi + ;; + esac + fi # $pass = dlpreopen + + if test -z "$libdir"; then + # Link the convenience library + if test lib = "$linkmode"; then + deplibs="$dir/$old_library $deplibs" + elif test prog,link = "$linkmode,$pass"; then + compile_deplibs="$dir/$old_library $compile_deplibs" + finalize_deplibs="$dir/$old_library $finalize_deplibs" + else + deplibs="$lib $deplibs" # used for prog,scan pass + fi + continue + fi + + + if test prog = "$linkmode" && test link != "$pass"; then + func_append newlib_search_path " $ladir" + deplibs="$lib $deplibs" + + linkalldeplibs=false + if test no != "$link_all_deplibs" || test -z "$library_names" || + test no = "$build_libtool_libs"; then + linkalldeplibs=: + fi + + tmp_libs= + for deplib in $dependency_libs; do + case $deplib in + -L*) func_stripname '-L' '' "$deplib" + func_resolve_sysroot "$func_stripname_result" + func_append newlib_search_path " $func_resolve_sysroot_result" + ;; + esac + # Need to link against all dependency_libs? + if $linkalldeplibs; then + deplibs="$deplib $deplibs" + else + # Need to hardcode shared library paths + # or/and link against static libraries + newdependency_libs="$deplib $newdependency_libs" + fi + if $opt_preserve_dup_deps; then + case "$tmp_libs " in + *" $deplib "*) func_append specialdeplibs " $deplib" ;; + esac + fi + func_append tmp_libs " $deplib" + done # for deplib + continue + fi # $linkmode = prog... + + if test prog,link = "$linkmode,$pass"; then + if test -n "$library_names" && + { { test no = "$prefer_static_libs" || + test built,yes = "$prefer_static_libs,$installed"; } || + test -z "$old_library"; }; then + # We need to hardcode the library path + if test -n "$shlibpath_var" && test -z "$avoidtemprpath"; then + # Make sure the rpath contains only unique directories. + case $temp_rpath: in + *"$absdir:"*) ;; + *) func_append temp_rpath "$absdir:" ;; + esac + fi + + # Hardcode the library path. + # Skip directories that are in the system default run-time + # search path. + case " $sys_lib_dlsearch_path " in + *" $absdir "*) ;; + *) + case "$compile_rpath " in + *" $absdir "*) ;; + *) func_append compile_rpath " $absdir" ;; + esac + ;; + esac + case " $sys_lib_dlsearch_path " in + *" $libdir "*) ;; + *) + case "$finalize_rpath " in + *" $libdir "*) ;; + *) func_append finalize_rpath " $libdir" ;; + esac + ;; + esac + fi # $linkmode,$pass = prog,link... + + if $alldeplibs && + { test pass_all = "$deplibs_check_method" || + { test yes = "$build_libtool_libs" && + test -n "$library_names"; }; }; then + # We only need to search for static libraries + continue + fi + fi + + link_static=no # Whether the deplib will be linked statically + use_static_libs=$prefer_static_libs + if test built = "$use_static_libs" && test yes = "$installed"; then + use_static_libs=no + fi + if test -n "$library_names" && + { test no = "$use_static_libs" || test -z "$old_library"; }; then + case $host in + *cygwin* | *mingw* | *cegcc* | *os2*) + # No point in relinking DLLs because paths are not encoded + func_append notinst_deplibs " $lib" + need_relink=no + ;; + *) + if test no = "$installed"; then + func_append notinst_deplibs " $lib" + need_relink=yes + fi + ;; + esac + # This is a shared library + + # Warn about portability, can't link against -module's on some + # systems (darwin). Don't bleat about dlopened modules though! + dlopenmodule= + for dlpremoduletest in $dlprefiles; do + if test "X$dlpremoduletest" = "X$lib"; then + dlopenmodule=$dlpremoduletest + break + fi + done + if test -z "$dlopenmodule" && test yes = "$shouldnotlink" && test link = "$pass"; then + echo + if test prog = "$linkmode"; then + $ECHO "*** Warning: Linking the executable $output against the loadable module" + else + $ECHO "*** Warning: Linking the shared library $output against the loadable module" + fi + $ECHO "*** $linklib is not portable!" + fi + if test lib = "$linkmode" && + test yes = "$hardcode_into_libs"; then + # Hardcode the library path. + # Skip directories that are in the system default run-time + # search path. + case " $sys_lib_dlsearch_path " in + *" $absdir "*) ;; + *) + case "$compile_rpath " in + *" $absdir "*) ;; + *) func_append compile_rpath " $absdir" ;; + esac + ;; + esac + case " $sys_lib_dlsearch_path " in + *" $libdir "*) ;; + *) + case "$finalize_rpath " in + *" $libdir "*) ;; + *) func_append finalize_rpath " $libdir" ;; + esac + ;; + esac + fi + + if test -n "$old_archive_from_expsyms_cmds"; then + # figure out the soname + set dummy $library_names + shift + realname=$1 + shift + libname=`eval "\\$ECHO \"$libname_spec\""` + # use dlname if we got it. it's perfectly good, no? + if test -n "$dlname"; then + soname=$dlname + elif test -n "$soname_spec"; then + # bleh windows + case $host in + *cygwin* | mingw* | *cegcc* | *os2*) + func_arith $current - $age + major=$func_arith_result + versuffix=-$major + ;; + esac + eval soname=\"$soname_spec\" + else + soname=$realname + fi + + # Make a new name for the extract_expsyms_cmds to use + soroot=$soname + func_basename "$soroot" + soname=$func_basename_result + func_stripname 'lib' '.dll' "$soname" + newlib=libimp-$func_stripname_result.a + + # If the library has no export list, then create one now + if test -f "$output_objdir/$soname-def"; then : + else + func_verbose "extracting exported symbol list from '$soname'" + func_execute_cmds "$extract_expsyms_cmds" 'exit $?' + fi + + # Create $newlib + if test -f "$output_objdir/$newlib"; then :; else + func_verbose "generating import library for '$soname'" + func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?' + fi + # make sure the library variables are pointing to the new library + dir=$output_objdir + linklib=$newlib + fi # test -n "$old_archive_from_expsyms_cmds" + + if test prog = "$linkmode" || test relink != "$opt_mode"; then + add_shlibpath= + add_dir= + add= + lib_linked=yes + case $hardcode_action in + immediate | unsupported) + if test no = "$hardcode_direct"; then + add=$dir/$linklib + case $host in + *-*-sco3.2v5.0.[024]*) add_dir=-L$dir ;; + *-*-sysv4*uw2*) add_dir=-L$dir ;; + *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \ + *-*-unixware7*) add_dir=-L$dir ;; + *-*-darwin* ) + # if the lib is a (non-dlopened) module then we cannot + # link against it, someone is ignoring the earlier warnings + if /usr/bin/file -L $add 2> /dev/null | + $GREP ": [^:]* bundle" >/dev/null; then + if test "X$dlopenmodule" != "X$lib"; then + $ECHO "*** Warning: lib $linklib is a module, not a shared library" + if test -z "$old_library"; then + echo + echo "*** And there doesn't seem to be a static archive available" + echo "*** The link will probably fail, sorry" + else + add=$dir/$old_library + fi + elif test -n "$old_library"; then + add=$dir/$old_library + fi + fi + esac + elif test no = "$hardcode_minus_L"; then + case $host in + *-*-sunos*) add_shlibpath=$dir ;; + esac + add_dir=-L$dir + add=-l$name + elif test no = "$hardcode_shlibpath_var"; then + add_shlibpath=$dir + add=-l$name + else + lib_linked=no + fi + ;; + relink) + if test yes = "$hardcode_direct" && + test no = "$hardcode_direct_absolute"; then + add=$dir/$linklib + elif test yes = "$hardcode_minus_L"; then + add_dir=-L$absdir + # Try looking first in the location we're being installed to. + if test -n "$inst_prefix_dir"; then + case $libdir in + [\\/]*) + func_append add_dir " -L$inst_prefix_dir$libdir" + ;; + esac + fi + add=-l$name + elif test yes = "$hardcode_shlibpath_var"; then + add_shlibpath=$dir + add=-l$name + else + lib_linked=no + fi + ;; + *) lib_linked=no ;; + esac + + if test yes != "$lib_linked"; then + func_fatal_configuration "unsupported hardcode properties" + fi + + if test -n "$add_shlibpath"; then + case :$compile_shlibpath: in + *":$add_shlibpath:"*) ;; + *) func_append compile_shlibpath "$add_shlibpath:" ;; + esac + fi + if test prog = "$linkmode"; then + test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" + test -n "$add" && compile_deplibs="$add $compile_deplibs" + else + test -n "$add_dir" && deplibs="$add_dir $deplibs" + test -n "$add" && deplibs="$add $deplibs" + if test yes != "$hardcode_direct" && + test yes != "$hardcode_minus_L" && + test yes = "$hardcode_shlibpath_var"; then + case :$finalize_shlibpath: in + *":$libdir:"*) ;; + *) func_append finalize_shlibpath "$libdir:" ;; + esac + fi + fi + fi + + if test prog = "$linkmode" || test relink = "$opt_mode"; then + add_shlibpath= + add_dir= + add= + # Finalize command for both is simple: just hardcode it. + if test yes = "$hardcode_direct" && + test no = "$hardcode_direct_absolute"; then + add=$libdir/$linklib + elif test yes = "$hardcode_minus_L"; then + add_dir=-L$libdir + add=-l$name + elif test yes = "$hardcode_shlibpath_var"; then + case :$finalize_shlibpath: in + *":$libdir:"*) ;; + *) func_append finalize_shlibpath "$libdir:" ;; + esac + add=-l$name + elif test yes = "$hardcode_automatic"; then + if test -n "$inst_prefix_dir" && + test -f "$inst_prefix_dir$libdir/$linklib"; then + add=$inst_prefix_dir$libdir/$linklib + else + add=$libdir/$linklib + fi + else + # We cannot seem to hardcode it, guess we'll fake it. + add_dir=-L$libdir + # Try looking first in the location we're being installed to. + if test -n "$inst_prefix_dir"; then + case $libdir in + [\\/]*) + func_append add_dir " -L$inst_prefix_dir$libdir" + ;; + esac + fi + add=-l$name + fi + + if test prog = "$linkmode"; then + test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" + test -n "$add" && finalize_deplibs="$add $finalize_deplibs" + else + test -n "$add_dir" && deplibs="$add_dir $deplibs" + test -n "$add" && deplibs="$add $deplibs" + fi + fi + elif test prog = "$linkmode"; then + # Here we assume that one of hardcode_direct or hardcode_minus_L + # is not unsupported. This is valid on all known static and + # shared platforms. + if test unsupported != "$hardcode_direct"; then + test -n "$old_library" && linklib=$old_library + compile_deplibs="$dir/$linklib $compile_deplibs" + finalize_deplibs="$dir/$linklib $finalize_deplibs" + else + compile_deplibs="-l$name -L$dir $compile_deplibs" + finalize_deplibs="-l$name -L$dir $finalize_deplibs" + fi + elif test yes = "$build_libtool_libs"; then + # Not a shared library + if test pass_all != "$deplibs_check_method"; then + # We're trying link a shared library against a static one + # but the system doesn't support it. + + # Just print a warning and add the library to dependency_libs so + # that the program can be linked against the static library. + echo + $ECHO "*** Warning: This system cannot link to static lib archive $lib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have." + if test yes = "$module"; then + echo "*** But as you try to build a module library, libtool will still create " + echo "*** a static module, that should work as long as the dlopening application" + echo "*** is linked with the -dlopen flag to resolve symbols at runtime." + if test -z "$global_symbol_pipe"; then + echo + echo "*** However, this would only work if libtool was able to extract symbol" + echo "*** lists from a program, using 'nm' or equivalent, but libtool could" + echo "*** not find such a program. So, this module is probably useless." + echo "*** 'nm' from GNU binutils and a full rebuild may help." + fi + if test no = "$build_old_libs"; then + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + fi + else + deplibs="$dir/$old_library $deplibs" + link_static=yes + fi + fi # link shared/static library? + + if test lib = "$linkmode"; then + if test -n "$dependency_libs" && + { test yes != "$hardcode_into_libs" || + test yes = "$build_old_libs" || + test yes = "$link_static"; }; then + # Extract -R from dependency_libs + temp_deplibs= + for libdir in $dependency_libs; do + case $libdir in + -R*) func_stripname '-R' '' "$libdir" + temp_xrpath=$func_stripname_result + case " $xrpath " in + *" $temp_xrpath "*) ;; + *) func_append xrpath " $temp_xrpath";; + esac;; + *) func_append temp_deplibs " $libdir";; + esac + done + dependency_libs=$temp_deplibs + fi + + func_append newlib_search_path " $absdir" + # Link against this library + test no = "$link_static" && newdependency_libs="$abs_ladir/$laname $newdependency_libs" + # ... and its dependency_libs + tmp_libs= + for deplib in $dependency_libs; do + newdependency_libs="$deplib $newdependency_libs" + case $deplib in + -L*) func_stripname '-L' '' "$deplib" + func_resolve_sysroot "$func_stripname_result";; + *) func_resolve_sysroot "$deplib" ;; + esac + if $opt_preserve_dup_deps; then + case "$tmp_libs " in + *" $func_resolve_sysroot_result "*) + func_append specialdeplibs " $func_resolve_sysroot_result" ;; + esac + fi + func_append tmp_libs " $func_resolve_sysroot_result" + done + + if test no != "$link_all_deplibs"; then + # Add the search paths of all dependency libraries + for deplib in $dependency_libs; do + path= + case $deplib in + -L*) path=$deplib ;; + *.la) + func_resolve_sysroot "$deplib" + deplib=$func_resolve_sysroot_result + func_dirname "$deplib" "" "." + dir=$func_dirname_result + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) absdir=$dir ;; + *) + absdir=`cd "$dir" && pwd` + if test -z "$absdir"; then + func_warning "cannot determine absolute directory name of '$dir'" + absdir=$dir + fi + ;; + esac + if $GREP "^installed=no" $deplib > /dev/null; then + case $host in + *-*-darwin*) + depdepl= + eval deplibrary_names=`$SED -n -e 's/^library_names=\(.*\)$/\1/p' $deplib` + if test -n "$deplibrary_names"; then + for tmp in $deplibrary_names; do + depdepl=$tmp + done + if test -f "$absdir/$objdir/$depdepl"; then + depdepl=$absdir/$objdir/$depdepl + darwin_install_name=`$OTOOL -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` + if test -z "$darwin_install_name"; then + darwin_install_name=`$OTOOL64 -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` + fi + func_append compiler_flags " $wl-dylib_file $wl$darwin_install_name:$depdepl" + func_append linker_flags " -dylib_file $darwin_install_name:$depdepl" + path= + fi + fi + ;; + *) + path=-L$absdir/$objdir + ;; + esac + else + eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` + test -z "$libdir" && \ + func_fatal_error "'$deplib' is not a valid libtool archive" + test "$absdir" != "$libdir" && \ + func_warning "'$deplib' seems to be moved" + + path=-L$absdir + fi + ;; + esac + case " $deplibs " in + *" $path "*) ;; + *) deplibs="$path $deplibs" ;; + esac + done + fi # link_all_deplibs != no + fi # linkmode = lib + done # for deplib in $libs + if test link = "$pass"; then + if test prog = "$linkmode"; then + compile_deplibs="$new_inherited_linker_flags $compile_deplibs" + finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs" + else + compiler_flags="$compiler_flags "`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + fi + fi + dependency_libs=$newdependency_libs + if test dlpreopen = "$pass"; then + # Link the dlpreopened libraries before other libraries + for deplib in $save_deplibs; do + deplibs="$deplib $deplibs" + done + fi + if test dlopen != "$pass"; then + test conv = "$pass" || { + # Make sure lib_search_path contains only unique directories. + lib_search_path= + for dir in $newlib_search_path; do + case "$lib_search_path " in + *" $dir "*) ;; + *) func_append lib_search_path " $dir" ;; + esac + done + newlib_search_path= + } + + if test prog,link = "$linkmode,$pass"; then + vars="compile_deplibs finalize_deplibs" + else + vars=deplibs + fi + for var in $vars dependency_libs; do + # Add libraries to $var in reverse order + eval tmp_libs=\"\$$var\" + new_libs= + for deplib in $tmp_libs; do + # FIXME: Pedantically, this is the right thing to do, so + # that some nasty dependency loop isn't accidentally + # broken: + #new_libs="$deplib $new_libs" + # Pragmatically, this seems to cause very few problems in + # practice: + case $deplib in + -L*) new_libs="$deplib $new_libs" ;; + -R*) ;; + *) + # And here is the reason: when a library appears more + # than once as an explicit dependence of a library, or + # is implicitly linked in more than once by the + # compiler, it is considered special, and multiple + # occurrences thereof are not removed. Compare this + # with having the same library being listed as a + # dependency of multiple other libraries: in this case, + # we know (pedantically, we assume) the library does not + # need to be listed more than once, so we keep only the + # last copy. This is not always right, but it is rare + # enough that we require users that really mean to play + # such unportable linking tricks to link the library + # using -Wl,-lname, so that libtool does not consider it + # for duplicate removal. + case " $specialdeplibs " in + *" $deplib "*) new_libs="$deplib $new_libs" ;; + *) + case " $new_libs " in + *" $deplib "*) ;; + *) new_libs="$deplib $new_libs" ;; + esac + ;; + esac + ;; + esac + done + tmp_libs= + for deplib in $new_libs; do + case $deplib in + -L*) + case " $tmp_libs " in + *" $deplib "*) ;; + *) func_append tmp_libs " $deplib" ;; + esac + ;; + *) func_append tmp_libs " $deplib" ;; + esac + done + eval $var=\"$tmp_libs\" + done # for var + fi + + # Add Sun CC postdeps if required: + test CXX = "$tagname" && { + case $host_os in + linux*) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) # Sun C++ 5.9 + func_suncc_cstd_abi + + if test no != "$suncc_use_cstd_abi"; then + func_append postdeps ' -library=Cstd -library=Crun' + fi + ;; + esac + ;; + + solaris*) + func_cc_basename "$CC" + case $func_cc_basename_result in + CC* | sunCC*) + func_suncc_cstd_abi + + if test no != "$suncc_use_cstd_abi"; then + func_append postdeps ' -library=Cstd -library=Crun' + fi + ;; + esac + ;; + esac + } + + # Last step: remove runtime libs from dependency_libs + # (they stay in deplibs) + tmp_libs= + for i in $dependency_libs; do + case " $predeps $postdeps $compiler_lib_search_path " in + *" $i "*) + i= + ;; + esac + if test -n "$i"; then + func_append tmp_libs " $i" + fi + done + dependency_libs=$tmp_libs + done # for pass + if test prog = "$linkmode"; then + dlfiles=$newdlfiles + fi + if test prog = "$linkmode" || test lib = "$linkmode"; then + dlprefiles=$newdlprefiles + fi + + case $linkmode in + oldlib) + if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then + func_warning "'-dlopen' is ignored for archives" + fi + + case " $deplibs" in + *\ -l* | *\ -L*) + func_warning "'-l' and '-L' are ignored for archives" ;; + esac + + test -n "$rpath" && \ + func_warning "'-rpath' is ignored for archives" + + test -n "$xrpath" && \ + func_warning "'-R' is ignored for archives" + + test -n "$vinfo" && \ + func_warning "'-version-info/-version-number' is ignored for archives" + + test -n "$release" && \ + func_warning "'-release' is ignored for archives" + + test -n "$export_symbols$export_symbols_regex" && \ + func_warning "'-export-symbols' is ignored for archives" + + # Now set the variables for building old libraries. + build_libtool_libs=no + oldlibs=$output + func_append objs "$old_deplibs" + ;; + + lib) + # Make sure we only generate libraries of the form 'libNAME.la'. + case $outputname in + lib*) + func_stripname 'lib' '.la' "$outputname" + name=$func_stripname_result + eval shared_ext=\"$shrext_cmds\" + eval libname=\"$libname_spec\" + ;; + *) + test no = "$module" \ + && func_fatal_help "libtool library '$output' must begin with 'lib'" + + if test no != "$need_lib_prefix"; then + # Add the "lib" prefix for modules if required + func_stripname '' '.la' "$outputname" + name=$func_stripname_result + eval shared_ext=\"$shrext_cmds\" + eval libname=\"$libname_spec\" + else + func_stripname '' '.la' "$outputname" + libname=$func_stripname_result + fi + ;; + esac + + if test -n "$objs"; then + if test pass_all != "$deplibs_check_method"; then + func_fatal_error "cannot build libtool library '$output' from non-libtool objects on this host:$objs" + else + echo + $ECHO "*** Warning: Linking the shared library $output against the non-libtool" + $ECHO "*** objects $objs is not portable!" + func_append libobjs " $objs" + fi + fi + + test no = "$dlself" \ + || func_warning "'-dlopen self' is ignored for libtool libraries" + + set dummy $rpath + shift + test 1 -lt "$#" \ + && func_warning "ignoring multiple '-rpath's for a libtool library" + + install_libdir=$1 + + oldlibs= + if test -z "$rpath"; then + if test yes = "$build_libtool_libs"; then + # Building a libtool convenience library. + # Some compilers have problems with a '.al' extension so + # convenience libraries should have the same extension an + # archive normally would. + oldlibs="$output_objdir/$libname.$libext $oldlibs" + build_libtool_libs=convenience + build_old_libs=yes + fi + + test -n "$vinfo" && \ + func_warning "'-version-info/-version-number' is ignored for convenience libraries" + + test -n "$release" && \ + func_warning "'-release' is ignored for convenience libraries" + else + + # Parse the version information argument. + save_ifs=$IFS; IFS=: + set dummy $vinfo 0 0 0 + shift + IFS=$save_ifs + + test -n "$7" && \ + func_fatal_help "too many parameters to '-version-info'" + + # convert absolute version numbers to libtool ages + # this retains compatibility with .la files and attempts + # to make the code below a bit more comprehensible + + case $vinfo_number in + yes) + number_major=$1 + number_minor=$2 + number_revision=$3 + # + # There are really only two kinds -- those that + # use the current revision as the major version + # and those that subtract age and use age as + # a minor version. But, then there is irix + # that has an extra 1 added just for fun + # + case $version_type in + # correct linux to gnu/linux during the next big refactor + darwin|freebsd-elf|linux|osf|windows|none) + func_arith $number_major + $number_minor + current=$func_arith_result + age=$number_minor + revision=$number_revision + ;; + freebsd-aout|qnx|sunos) + current=$number_major + revision=$number_minor + age=0 + ;; + irix|nonstopux) + func_arith $number_major + $number_minor + current=$func_arith_result + age=$number_minor + revision=$number_minor + lt_irix_increment=no + ;; + *) + func_fatal_configuration "$modename: unknown library version type '$version_type'" + ;; + esac + ;; + no) + current=$1 + revision=$2 + age=$3 + ;; + esac + + # Check that each of the things are valid numbers. + case $current in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + func_error "CURRENT '$current' must be a nonnegative integer" + func_fatal_error "'$vinfo' is not valid version information" + ;; + esac + + case $revision in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + func_error "REVISION '$revision' must be a nonnegative integer" + func_fatal_error "'$vinfo' is not valid version information" + ;; + esac + + case $age in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + func_error "AGE '$age' must be a nonnegative integer" + func_fatal_error "'$vinfo' is not valid version information" + ;; + esac + + if test "$age" -gt "$current"; then + func_error "AGE '$age' is greater than the current interface number '$current'" + func_fatal_error "'$vinfo' is not valid version information" + fi + + # Calculate the version variables. + major= + versuffix= + verstring= + case $version_type in + none) ;; + + darwin) + # Like Linux, but with the current version available in + # verstring for coding it into the library header + func_arith $current - $age + major=.$func_arith_result + versuffix=$major.$age.$revision + # Darwin ld doesn't like 0 for these options... + func_arith $current + 1 + minor_current=$func_arith_result + xlcverstring="$wl-compatibility_version $wl$minor_current $wl-current_version $wl$minor_current.$revision" + verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" + # On Darwin other compilers + case $CC in + nagfor*) + verstring="$wl-compatibility_version $wl$minor_current $wl-current_version $wl$minor_current.$revision" + ;; + *) + verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" + ;; + esac + ;; + + freebsd-aout) + major=.$current + versuffix=.$current.$revision + ;; + + freebsd-elf) + func_arith $current - $age + major=.$func_arith_result + versuffix=$major.$age.$revision + ;; + + irix | nonstopux) + if test no = "$lt_irix_increment"; then + func_arith $current - $age + else + func_arith $current - $age + 1 + fi + major=$func_arith_result + + case $version_type in + nonstopux) verstring_prefix=nonstopux ;; + *) verstring_prefix=sgi ;; + esac + verstring=$verstring_prefix$major.$revision + + # Add in all the interfaces that we are compatible with. + loop=$revision + while test 0 -ne "$loop"; do + func_arith $revision - $loop + iface=$func_arith_result + func_arith $loop - 1 + loop=$func_arith_result + verstring=$verstring_prefix$major.$iface:$verstring + done + + # Before this point, $major must not contain '.'. + major=.$major + versuffix=$major.$revision + ;; + + linux) # correct to gnu/linux during the next big refactor + func_arith $current - $age + major=.$func_arith_result + versuffix=$major.$age.$revision + ;; + + osf) + func_arith $current - $age + major=.$func_arith_result + versuffix=.$current.$age.$revision + verstring=$current.$age.$revision + + # Add in all the interfaces that we are compatible with. + loop=$age + while test 0 -ne "$loop"; do + func_arith $current - $loop + iface=$func_arith_result + func_arith $loop - 1 + loop=$func_arith_result + verstring=$verstring:$iface.0 + done + + # Make executables depend on our current version. + func_append verstring ":$current.0" + ;; + + qnx) + major=.$current + versuffix=.$current + ;; + + sco) + major=.$current + versuffix=.$current + ;; + + sunos) + major=.$current + versuffix=.$current.$revision + ;; + + windows) + # Use '-' rather than '.', since we only want one + # extension on DOS 8.3 file systems. + func_arith $current - $age + major=$func_arith_result + versuffix=-$major + ;; + + *) + func_fatal_configuration "unknown library version type '$version_type'" + ;; + esac + + # Clear the version info if we defaulted, and they specified a release. + if test -z "$vinfo" && test -n "$release"; then + major= + case $version_type in + darwin) + # we can't check for "0.0" in archive_cmds due to quoting + # problems, so we reset it completely + verstring= + ;; + *) + verstring=0.0 + ;; + esac + if test no = "$need_version"; then + versuffix= + else + versuffix=.0.0 + fi + fi + + # Remove version info from name if versioning should be avoided + if test yes,no = "$avoid_version,$need_version"; then + major= + versuffix= + verstring= + fi + + # Check to see if the archive will have undefined symbols. + if test yes = "$allow_undefined"; then + if test unsupported = "$allow_undefined_flag"; then + if test yes = "$build_old_libs"; then + func_warning "undefined symbols not allowed in $host shared libraries; building static only" + build_libtool_libs=no + else + func_fatal_error "can't build $host shared library unless -no-undefined is specified" + fi + fi + else + # Don't allow undefined symbols. + allow_undefined_flag=$no_undefined_flag + fi + + fi + + func_generate_dlsyms "$libname" "$libname" : + func_append libobjs " $symfileobj" + test " " = "$libobjs" && libobjs= + + if test relink != "$opt_mode"; then + # Remove our outputs, but don't remove object files since they + # may have been created when compiling PIC objects. + removelist= + tempremovelist=`$ECHO "$output_objdir/*"` + for p in $tempremovelist; do + case $p in + *.$objext | *.gcno) + ;; + $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/$libname$release.*) + if test -n "$precious_files_regex"; then + if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1 + then + continue + fi + fi + func_append removelist " $p" + ;; + *) ;; + esac + done + test -n "$removelist" && \ + func_show_eval "${RM}r \$removelist" + fi + + # Now set the variables for building old libraries. + if test yes = "$build_old_libs" && test convenience != "$build_libtool_libs"; then + func_append oldlibs " $output_objdir/$libname.$libext" + + # Transform .lo files to .o files. + oldobjs="$objs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.$libext$/d; $lo2o" | $NL2SP` + fi + + # Eliminate all temporary directories. + #for path in $notinst_path; do + # lib_search_path=`$ECHO "$lib_search_path " | $SED "s% $path % %g"` + # deplibs=`$ECHO "$deplibs " | $SED "s% -L$path % %g"` + # dependency_libs=`$ECHO "$dependency_libs " | $SED "s% -L$path % %g"` + #done + + if test -n "$xrpath"; then + # If the user specified any rpath flags, then add them. + temp_xrpath= + for libdir in $xrpath; do + func_replace_sysroot "$libdir" + func_append temp_xrpath " -R$func_replace_sysroot_result" + case "$finalize_rpath " in + *" $libdir "*) ;; + *) func_append finalize_rpath " $libdir" ;; + esac + done + if test yes != "$hardcode_into_libs" || test yes = "$build_old_libs"; then + dependency_libs="$temp_xrpath $dependency_libs" + fi + fi + + # Make sure dlfiles contains only unique files that won't be dlpreopened + old_dlfiles=$dlfiles + dlfiles= + for lib in $old_dlfiles; do + case " $dlprefiles $dlfiles " in + *" $lib "*) ;; + *) func_append dlfiles " $lib" ;; + esac + done + + # Make sure dlprefiles contains only unique files + old_dlprefiles=$dlprefiles + dlprefiles= + for lib in $old_dlprefiles; do + case "$dlprefiles " in + *" $lib "*) ;; + *) func_append dlprefiles " $lib" ;; + esac + done + + if test yes = "$build_libtool_libs"; then + if test -n "$rpath"; then + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc* | *-*-haiku*) + # these systems don't actually have a c library (as such)! + ;; + *-*-rhapsody* | *-*-darwin1.[012]) + # Rhapsody C library is in the System framework + func_append deplibs " System.ltframework" + ;; + *-*-netbsd*) + # Don't link with libc until the a.out ld.so is fixed. + ;; + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + # Do not include libc due to us having libc/libc_r. + ;; + *-*-sco3.2v5* | *-*-sco5v6*) + # Causes problems with __ctype + ;; + *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) + # Compiler inserts libc in the correct place for threads to work + ;; + *) + # Add libc to deplibs on all other systems if necessary. + if test yes = "$build_libtool_need_lc"; then + func_append deplibs " -lc" + fi + ;; + esac + fi + + # Transform deplibs into only deplibs that can be linked in shared. + name_save=$name + libname_save=$libname + release_save=$release + versuffix_save=$versuffix + major_save=$major + # I'm not sure if I'm treating the release correctly. I think + # release should show up in the -l (ie -lgmp5) so we don't want to + # add it in twice. Is that correct? + release= + versuffix= + major= + newdeplibs= + droppeddeps=no + case $deplibs_check_method in + pass_all) + # Don't check for shared/static. Everything works. + # This might be a little naive. We might want to check + # whether the library exists or not. But this is on + # osf3 & osf4 and I'm not really sure... Just + # implementing what was already the behavior. + newdeplibs=$deplibs + ;; + test_compile) + # This code stresses the "libraries are programs" paradigm to its + # limits. Maybe even breaks it. We compile a program, linking it + # against the deplibs as a proxy for the library. Then we can check + # whether they linked in statically or dynamically with ldd. + $opt_dry_run || $RM conftest.c + cat > conftest.c </dev/null` + $nocaseglob + else + potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null` + fi + for potent_lib in $potential_libs; do + # Follow soft links. + if ls -lLd "$potent_lib" 2>/dev/null | + $GREP " -> " >/dev/null; then + continue + fi + # The statement above tries to avoid entering an + # endless loop below, in case of cyclic links. + # We might still enter an endless loop, since a link + # loop can be closed while we follow links, + # but so what? + potlib=$potent_lib + while test -h "$potlib" 2>/dev/null; do + potliblink=`ls -ld $potlib | $SED 's/.* -> //'` + case $potliblink in + [\\/]* | [A-Za-z]:[\\/]*) potlib=$potliblink;; + *) potlib=`$ECHO "$potlib" | $SED 's|[^/]*$||'`"$potliblink";; + esac + done + if eval $file_magic_cmd \"\$potlib\" 2>/dev/null | + $SED -e 10q | + $EGREP "$file_magic_regex" > /dev/null; then + func_append newdeplibs " $a_deplib" + a_deplib= + break 2 + fi + done + done + fi + if test -n "$a_deplib"; then + droppeddeps=yes + echo + $ECHO "*** Warning: linker path does not have real file for library $a_deplib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have" + echo "*** because I did check the linker path looking for a file starting" + if test -z "$potlib"; then + $ECHO "*** with $libname but no candidates were found. (...for file magic test)" + else + $ECHO "*** with $libname and none of the candidates passed a file format test" + $ECHO "*** using a file magic. Last file checked: $potlib" + fi + fi + ;; + *) + # Add a -L argument. + func_append newdeplibs " $a_deplib" + ;; + esac + done # Gone through all deplibs. + ;; + match_pattern*) + set dummy $deplibs_check_method; shift + match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` + for a_deplib in $deplibs; do + case $a_deplib in + -l*) + func_stripname -l '' "$a_deplib" + name=$func_stripname_result + if test yes = "$allow_libtool_libs_with_static_runtimes"; then + case " $predeps $postdeps " in + *" $a_deplib "*) + func_append newdeplibs " $a_deplib" + a_deplib= + ;; + esac + fi + if test -n "$a_deplib"; then + libname=`eval "\\$ECHO \"$libname_spec\""` + for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do + potential_libs=`ls $i/$libname[.-]* 2>/dev/null` + for potent_lib in $potential_libs; do + potlib=$potent_lib # see symlink-check above in file_magic test + if eval "\$ECHO \"$potent_lib\"" 2>/dev/null | $SED 10q | \ + $EGREP "$match_pattern_regex" > /dev/null; then + func_append newdeplibs " $a_deplib" + a_deplib= + break 2 + fi + done + done + fi + if test -n "$a_deplib"; then + droppeddeps=yes + echo + $ECHO "*** Warning: linker path does not have real file for library $a_deplib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have" + echo "*** because I did check the linker path looking for a file starting" + if test -z "$potlib"; then + $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)" + else + $ECHO "*** with $libname and none of the candidates passed a file format test" + $ECHO "*** using a regex pattern. Last file checked: $potlib" + fi + fi + ;; + *) + # Add a -L argument. + func_append newdeplibs " $a_deplib" + ;; + esac + done # Gone through all deplibs. + ;; + none | unknown | *) + newdeplibs= + tmp_deplibs=`$ECHO " $deplibs" | $SED 's/ -lc$//; s/ -[LR][^ ]*//g'` + if test yes = "$allow_libtool_libs_with_static_runtimes"; then + for i in $predeps $postdeps; do + # can't use Xsed below, because $i might contain '/' + tmp_deplibs=`$ECHO " $tmp_deplibs" | $SED "s|$i||"` + done + fi + case $tmp_deplibs in + *[!\ \ ]*) + echo + if test none = "$deplibs_check_method"; then + echo "*** Warning: inter-library dependencies are not supported in this platform." + else + echo "*** Warning: inter-library dependencies are not known to be supported." + fi + echo "*** All declared inter-library dependencies are being dropped." + droppeddeps=yes + ;; + esac + ;; + esac + versuffix=$versuffix_save + major=$major_save + release=$release_save + libname=$libname_save + name=$name_save + + case $host in + *-*-rhapsody* | *-*-darwin1.[012]) + # On Rhapsody replace the C library with the System framework + newdeplibs=`$ECHO " $newdeplibs" | $SED 's/ -lc / System.ltframework /'` + ;; + esac + + if test yes = "$droppeddeps"; then + if test yes = "$module"; then + echo + echo "*** Warning: libtool could not satisfy all declared inter-library" + $ECHO "*** dependencies of module $libname. Therefore, libtool will create" + echo "*** a static module, that should work as long as the dlopening" + echo "*** application is linked with the -dlopen flag." + if test -z "$global_symbol_pipe"; then + echo + echo "*** However, this would only work if libtool was able to extract symbol" + echo "*** lists from a program, using 'nm' or equivalent, but libtool could" + echo "*** not find such a program. So, this module is probably useless." + echo "*** 'nm' from GNU binutils and a full rebuild may help." + fi + if test no = "$build_old_libs"; then + oldlibs=$output_objdir/$libname.$libext + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + else + echo "*** The inter-library dependencies that have been dropped here will be" + echo "*** automatically added whenever a program is linked with this library" + echo "*** or is declared to -dlopen it." + + if test no = "$allow_undefined"; then + echo + echo "*** Since this library must not contain undefined symbols," + echo "*** because either the platform does not support them or" + echo "*** it was explicitly requested with -no-undefined," + echo "*** libtool will only create a static version of it." + if test no = "$build_old_libs"; then + oldlibs=$output_objdir/$libname.$libext + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + fi + fi + fi + # Done checking deplibs! + deplibs=$newdeplibs + fi + # Time to change all our "foo.ltframework" stuff back to "-framework foo" + case $host in + *-*-darwin*) + newdeplibs=`$ECHO " $newdeplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + new_inherited_linker_flags=`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + deplibs=`$ECHO " $deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + ;; + esac + + # move library search paths that coincide with paths to not yet + # installed libraries to the beginning of the library search list + new_libs= + for path in $notinst_path; do + case " $new_libs " in + *" -L$path/$objdir "*) ;; + *) + case " $deplibs " in + *" -L$path/$objdir "*) + func_append new_libs " -L$path/$objdir" ;; + esac + ;; + esac + done + for deplib in $deplibs; do + case $deplib in + -L*) + case " $new_libs " in + *" $deplib "*) ;; + *) func_append new_libs " $deplib" ;; + esac + ;; + *) func_append new_libs " $deplib" ;; + esac + done + deplibs=$new_libs + + # All the library-specific variables (install_libdir is set above). + library_names= + old_library= + dlname= + + # Test again, we may have decided not to build it any more + if test yes = "$build_libtool_libs"; then + # Remove $wl instances when linking with ld. + # FIXME: should test the right _cmds variable. + case $archive_cmds in + *\$LD\ *) wl= ;; + esac + if test yes = "$hardcode_into_libs"; then + # Hardcode the library paths + hardcode_libdirs= + dep_rpath= + rpath=$finalize_rpath + test relink = "$opt_mode" || rpath=$compile_rpath$rpath + for libdir in $rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + func_replace_sysroot "$libdir" + libdir=$func_replace_sysroot_result + if test -z "$hardcode_libdirs"; then + hardcode_libdirs=$libdir + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + func_append dep_rpath " $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) func_append perm_rpath " $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir=$hardcode_libdirs + eval "dep_rpath=\"$hardcode_libdir_flag_spec\"" + fi + if test -n "$runpath_var" && test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + func_append rpath "$dir:" + done + eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" + fi + test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" + fi + + shlibpath=$finalize_shlibpath + test relink = "$opt_mode" || shlibpath=$compile_shlibpath$shlibpath + if test -n "$shlibpath"; then + eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" + fi + + # Get the real and link names of the library. + eval shared_ext=\"$shrext_cmds\" + eval library_names=\"$library_names_spec\" + set dummy $library_names + shift + realname=$1 + shift + + if test -n "$soname_spec"; then + eval soname=\"$soname_spec\" + else + soname=$realname + fi + if test -z "$dlname"; then + dlname=$soname + fi + + lib=$output_objdir/$realname + linknames= + for link + do + func_append linknames " $link" + done + + # Use standard objects if they are pic + test -z "$pic_flag" && libobjs=`$ECHO "$libobjs" | $SP2NL | $SED "$lo2o" | $NL2SP` + test "X$libobjs" = "X " && libobjs= + + delfiles= + if test -n "$export_symbols" && test -n "$include_expsyms"; then + $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp" + export_symbols=$output_objdir/$libname.uexp + func_append delfiles " $export_symbols" + fi + + orig_export_symbols= + case $host_os in + cygwin* | mingw* | cegcc*) + if test -n "$export_symbols" && test -z "$export_symbols_regex"; then + # exporting using user supplied symfile + func_dll_def_p "$export_symbols" || { + # and it's NOT already a .def file. Must figure out + # which of the given symbols are data symbols and tag + # them as such. So, trigger use of export_symbols_cmds. + # export_symbols gets reassigned inside the "prepare + # the list of exported symbols" if statement, so the + # include_expsyms logic still works. + orig_export_symbols=$export_symbols + export_symbols= + always_export_symbols=yes + } + fi + ;; + esac + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + if test yes = "$always_export_symbols" || test -n "$export_symbols_regex"; then + func_verbose "generating symbol list for '$libname.la'" + export_symbols=$output_objdir/$libname.exp + $opt_dry_run || $RM $export_symbols + cmds=$export_symbols_cmds + save_ifs=$IFS; IFS='~' + for cmd1 in $cmds; do + IFS=$save_ifs + # Take the normal branch if the nm_file_list_spec branch + # doesn't work or if tool conversion is not needed. + case $nm_file_list_spec~$to_tool_file_cmd in + *~func_convert_file_noop | *~func_convert_file_msys_to_w32 | ~*) + try_normal_branch=yes + eval cmd=\"$cmd1\" + func_len " $cmd" + len=$func_len_result + ;; + *) + try_normal_branch=no + ;; + esac + if test yes = "$try_normal_branch" \ + && { test "$len" -lt "$max_cmd_len" \ + || test "$max_cmd_len" -le -1; } + then + func_show_eval "$cmd" 'exit $?' + skipped_export=false + elif test -n "$nm_file_list_spec"; then + func_basename "$output" + output_la=$func_basename_result + save_libobjs=$libobjs + save_output=$output + output=$output_objdir/$output_la.nm + func_to_tool_file "$output" + libobjs=$nm_file_list_spec$func_to_tool_file_result + func_append delfiles " $output" + func_verbose "creating $NM input file list: $output" + for obj in $save_libobjs; do + func_to_tool_file "$obj" + $ECHO "$func_to_tool_file_result" + done > "$output" + eval cmd=\"$cmd1\" + func_show_eval "$cmd" 'exit $?' + output=$save_output + libobjs=$save_libobjs + skipped_export=false + else + # The command line is too long to execute in one step. + func_verbose "using reloadable object file for export list..." + skipped_export=: + # Break out early, otherwise skipped_export may be + # set to false by a later but shorter cmd. + break + fi + done + IFS=$save_ifs + if test -n "$export_symbols_regex" && test : != "$skipped_export"; then + func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' + func_show_eval '$MV "${export_symbols}T" "$export_symbols"' + fi + fi + fi + + if test -n "$export_symbols" && test -n "$include_expsyms"; then + tmp_export_symbols=$export_symbols + test -n "$orig_export_symbols" && tmp_export_symbols=$orig_export_symbols + $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' + fi + + if test : != "$skipped_export" && test -n "$orig_export_symbols"; then + # The given exports_symbols file has to be filtered, so filter it. + func_verbose "filter symbol list for '$libname.la' to tag DATA exports" + # FIXME: $output_objdir/$libname.filter potentially contains lots of + # 's' commands, which not all seds can handle. GNU sed should be fine + # though. Also, the filter scales superlinearly with the number of + # global variables. join(1) would be nice here, but unfortunately + # isn't a blessed tool. + $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter + func_append delfiles " $export_symbols $output_objdir/$libname.filter" + export_symbols=$output_objdir/$libname.def + $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols + fi + + tmp_deplibs= + for test_deplib in $deplibs; do + case " $convenience " in + *" $test_deplib "*) ;; + *) + func_append tmp_deplibs " $test_deplib" + ;; + esac + done + deplibs=$tmp_deplibs + + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec" && + test yes = "$compiler_needs_object" && + test -z "$libobjs"; then + # extract the archives, so we have objects to list. + # TODO: could optimize this to just extract one archive. + whole_archive_flag_spec= + fi + if test -n "$whole_archive_flag_spec"; then + save_libobjs=$libobjs + eval libobjs=\"\$libobjs $whole_archive_flag_spec\" + test "X$libobjs" = "X " && libobjs= + else + gentop=$output_objdir/${outputname}x + func_append generated " $gentop" + + func_extract_archives $gentop $convenience + func_append libobjs " $func_extract_archives_result" + test "X$libobjs" = "X " && libobjs= + fi + fi + + if test yes = "$thread_safe" && test -n "$thread_safe_flag_spec"; then + eval flag=\"$thread_safe_flag_spec\" + func_append linker_flags " $flag" + fi + + # Make a backup of the uninstalled library when relinking + if test relink = "$opt_mode"; then + $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $? + fi + + # Do each of the archive commands. + if test yes = "$module" && test -n "$module_cmds"; then + if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then + eval test_cmds=\"$module_expsym_cmds\" + cmds=$module_expsym_cmds + else + eval test_cmds=\"$module_cmds\" + cmds=$module_cmds + fi + else + if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then + eval test_cmds=\"$archive_expsym_cmds\" + cmds=$archive_expsym_cmds + else + eval test_cmds=\"$archive_cmds\" + cmds=$archive_cmds + fi + fi + + if test : != "$skipped_export" && + func_len " $test_cmds" && + len=$func_len_result && + test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then + : + else + # The command line is too long to link in one step, link piecewise + # or, if using GNU ld and skipped_export is not :, use a linker + # script. + + # Save the value of $output and $libobjs because we want to + # use them later. If we have whole_archive_flag_spec, we + # want to use save_libobjs as it was before + # whole_archive_flag_spec was expanded, because we can't + # assume the linker understands whole_archive_flag_spec. + # This may have to be revisited, in case too many + # convenience libraries get linked in and end up exceeding + # the spec. + if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then + save_libobjs=$libobjs + fi + save_output=$output + func_basename "$output" + output_la=$func_basename_result + + # Clear the reloadable object creation command queue and + # initialize k to one. + test_cmds= + concat_cmds= + objlist= + last_robj= + k=1 + + if test -n "$save_libobjs" && test : != "$skipped_export" && test yes = "$with_gnu_ld"; then + output=$output_objdir/$output_la.lnkscript + func_verbose "creating GNU ld script: $output" + echo 'INPUT (' > $output + for obj in $save_libobjs + do + func_to_tool_file "$obj" + $ECHO "$func_to_tool_file_result" >> $output + done + echo ')' >> $output + func_append delfiles " $output" + func_to_tool_file "$output" + output=$func_to_tool_file_result + elif test -n "$save_libobjs" && test : != "$skipped_export" && test -n "$file_list_spec"; then + output=$output_objdir/$output_la.lnk + func_verbose "creating linker input file list: $output" + : > $output + set x $save_libobjs + shift + firstobj= + if test yes = "$compiler_needs_object"; then + firstobj="$1 " + shift + fi + for obj + do + func_to_tool_file "$obj" + $ECHO "$func_to_tool_file_result" >> $output + done + func_append delfiles " $output" + func_to_tool_file "$output" + output=$firstobj\"$file_list_spec$func_to_tool_file_result\" + else + if test -n "$save_libobjs"; then + func_verbose "creating reloadable object files..." + output=$output_objdir/$output_la-$k.$objext + eval test_cmds=\"$reload_cmds\" + func_len " $test_cmds" + len0=$func_len_result + len=$len0 + + # Loop over the list of objects to be linked. + for obj in $save_libobjs + do + func_len " $obj" + func_arith $len + $func_len_result + len=$func_arith_result + if test -z "$objlist" || + test "$len" -lt "$max_cmd_len"; then + func_append objlist " $obj" + else + # The command $test_cmds is almost too long, add a + # command to the queue. + if test 1 -eq "$k"; then + # The first file doesn't have a previous command to add. + reload_objs=$objlist + eval concat_cmds=\"$reload_cmds\" + else + # All subsequent reloadable object files will link in + # the last one created. + reload_objs="$objlist $last_robj" + eval concat_cmds=\"\$concat_cmds~$reload_cmds~\$RM $last_robj\" + fi + last_robj=$output_objdir/$output_la-$k.$objext + func_arith $k + 1 + k=$func_arith_result + output=$output_objdir/$output_la-$k.$objext + objlist=" $obj" + func_len " $last_robj" + func_arith $len0 + $func_len_result + len=$func_arith_result + fi + done + # Handle the remaining objects by creating one last + # reloadable object file. All subsequent reloadable object + # files will link in the last one created. + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + reload_objs="$objlist $last_robj" + eval concat_cmds=\"\$concat_cmds$reload_cmds\" + if test -n "$last_robj"; then + eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\" + fi + func_append delfiles " $output" + + else + output= + fi + + ${skipped_export-false} && { + func_verbose "generating symbol list for '$libname.la'" + export_symbols=$output_objdir/$libname.exp + $opt_dry_run || $RM $export_symbols + libobjs=$output + # Append the command to create the export file. + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\" + if test -n "$last_robj"; then + eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\" + fi + } + + test -n "$save_libobjs" && + func_verbose "creating a temporary reloadable object file: $output" + + # Loop through the commands generated above and execute them. + save_ifs=$IFS; IFS='~' + for cmd in $concat_cmds; do + IFS=$save_ifs + $opt_quiet || { + func_quote_for_expand "$cmd" + eval "func_echo $func_quote_for_expand_result" + } + $opt_dry_run || eval "$cmd" || { + lt_exit=$? + + # Restore the uninstalled library and exit + if test relink = "$opt_mode"; then + ( cd "$output_objdir" && \ + $RM "${realname}T" && \ + $MV "${realname}U" "$realname" ) + fi + + exit $lt_exit + } + done + IFS=$save_ifs + + if test -n "$export_symbols_regex" && ${skipped_export-false}; then + func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' + func_show_eval '$MV "${export_symbols}T" "$export_symbols"' + fi + fi + + ${skipped_export-false} && { + if test -n "$export_symbols" && test -n "$include_expsyms"; then + tmp_export_symbols=$export_symbols + test -n "$orig_export_symbols" && tmp_export_symbols=$orig_export_symbols + $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' + fi + + if test -n "$orig_export_symbols"; then + # The given exports_symbols file has to be filtered, so filter it. + func_verbose "filter symbol list for '$libname.la' to tag DATA exports" + # FIXME: $output_objdir/$libname.filter potentially contains lots of + # 's' commands, which not all seds can handle. GNU sed should be fine + # though. Also, the filter scales superlinearly with the number of + # global variables. join(1) would be nice here, but unfortunately + # isn't a blessed tool. + $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter + func_append delfiles " $export_symbols $output_objdir/$libname.filter" + export_symbols=$output_objdir/$libname.def + $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols + fi + } + + libobjs=$output + # Restore the value of output. + output=$save_output + + if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then + eval libobjs=\"\$libobjs $whole_archive_flag_spec\" + test "X$libobjs" = "X " && libobjs= + fi + # Expand the library linking commands again to reset the + # value of $libobjs for piecewise linking. + + # Do each of the archive commands. + if test yes = "$module" && test -n "$module_cmds"; then + if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then + cmds=$module_expsym_cmds + else + cmds=$module_cmds + fi + else + if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then + cmds=$archive_expsym_cmds + else + cmds=$archive_cmds + fi + fi + fi + + if test -n "$delfiles"; then + # Append the command to remove temporary files to $cmds. + eval cmds=\"\$cmds~\$RM $delfiles\" + fi + + # Add any objects from preloaded convenience libraries + if test -n "$dlprefiles"; then + gentop=$output_objdir/${outputname}x + func_append generated " $gentop" + + func_extract_archives $gentop $dlprefiles + func_append libobjs " $func_extract_archives_result" + test "X$libobjs" = "X " && libobjs= + fi + + save_ifs=$IFS; IFS='~' + for cmd in $cmds; do + IFS=$sp$nl + eval cmd=\"$cmd\" + IFS=$save_ifs + $opt_quiet || { + func_quote_for_expand "$cmd" + eval "func_echo $func_quote_for_expand_result" + } + $opt_dry_run || eval "$cmd" || { + lt_exit=$? + + # Restore the uninstalled library and exit + if test relink = "$opt_mode"; then + ( cd "$output_objdir" && \ + $RM "${realname}T" && \ + $MV "${realname}U" "$realname" ) + fi + + exit $lt_exit + } + done + IFS=$save_ifs + + # Restore the uninstalled library and exit + if test relink = "$opt_mode"; then + $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $? + + if test -n "$convenience"; then + if test -z "$whole_archive_flag_spec"; then + func_show_eval '${RM}r "$gentop"' + fi + fi + + exit $EXIT_SUCCESS + fi + + # Create links to the real library. + for linkname in $linknames; do + if test "$realname" != "$linkname"; then + func_show_eval '(cd "$output_objdir" && $RM "$linkname" && $LN_S "$realname" "$linkname")' 'exit $?' + fi + done + + # If -module or -export-dynamic was specified, set the dlname. + if test yes = "$module" || test yes = "$export_dynamic"; then + # On all known operating systems, these are identical. + dlname=$soname + fi + fi + ;; + + obj) + if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then + func_warning "'-dlopen' is ignored for objects" + fi + + case " $deplibs" in + *\ -l* | *\ -L*) + func_warning "'-l' and '-L' are ignored for objects" ;; + esac + + test -n "$rpath" && \ + func_warning "'-rpath' is ignored for objects" + + test -n "$xrpath" && \ + func_warning "'-R' is ignored for objects" + + test -n "$vinfo" && \ + func_warning "'-version-info' is ignored for objects" + + test -n "$release" && \ + func_warning "'-release' is ignored for objects" + + case $output in + *.lo) + test -n "$objs$old_deplibs" && \ + func_fatal_error "cannot build library object '$output' from non-libtool objects" + + libobj=$output + func_lo2o "$libobj" + obj=$func_lo2o_result + ;; + *) + libobj= + obj=$output + ;; + esac + + # Delete the old objects. + $opt_dry_run || $RM $obj $libobj + + # Objects from convenience libraries. This assumes + # single-version convenience libraries. Whenever we create + # different ones for PIC/non-PIC, this we'll have to duplicate + # the extraction. + reload_conv_objs= + gentop= + # if reload_cmds runs $LD directly, get rid of -Wl from + # whole_archive_flag_spec and hope we can get by with turning comma + # into space. + case $reload_cmds in + *\$LD[\ \$]*) wl= ;; + esac + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec"; then + eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\" + test -n "$wl" || tmp_whole_archive_flags=`$ECHO "$tmp_whole_archive_flags" | $SED 's|,| |g'` + reload_conv_objs=$reload_objs\ $tmp_whole_archive_flags + else + gentop=$output_objdir/${obj}x + func_append generated " $gentop" + + func_extract_archives $gentop $convenience + reload_conv_objs="$reload_objs $func_extract_archives_result" + fi + fi + + # If we're not building shared, we need to use non_pic_objs + test yes = "$build_libtool_libs" || libobjs=$non_pic_objects + + # Create the old-style object. + reload_objs=$objs$old_deplibs' '`$ECHO "$libobjs" | $SP2NL | $SED "/\.$libext$/d; /\.lib$/d; $lo2o" | $NL2SP`' '$reload_conv_objs + + output=$obj + func_execute_cmds "$reload_cmds" 'exit $?' + + # Exit if we aren't doing a library object file. + if test -z "$libobj"; then + if test -n "$gentop"; then + func_show_eval '${RM}r "$gentop"' + fi + + exit $EXIT_SUCCESS + fi + + test yes = "$build_libtool_libs" || { + if test -n "$gentop"; then + func_show_eval '${RM}r "$gentop"' + fi + + # Create an invalid libtool object if no PIC, so that we don't + # accidentally link it into a program. + # $show "echo timestamp > $libobj" + # $opt_dry_run || eval "echo timestamp > $libobj" || exit $? + exit $EXIT_SUCCESS + } + + if test -n "$pic_flag" || test default != "$pic_mode"; then + # Only do commands if we really have different PIC objects. + reload_objs="$libobjs $reload_conv_objs" + output=$libobj + func_execute_cmds "$reload_cmds" 'exit $?' + fi + + if test -n "$gentop"; then + func_show_eval '${RM}r "$gentop"' + fi + + exit $EXIT_SUCCESS + ;; + + prog) + case $host in + *cygwin*) func_stripname '' '.exe' "$output" + output=$func_stripname_result.exe;; + esac + test -n "$vinfo" && \ + func_warning "'-version-info' is ignored for programs" + + test -n "$release" && \ + func_warning "'-release' is ignored for programs" + + $preload \ + && test unknown,unknown,unknown = "$dlopen_support,$dlopen_self,$dlopen_self_static" \ + && func_warning "'LT_INIT([dlopen])' not used. Assuming no dlopen support." + + case $host in + *-*-rhapsody* | *-*-darwin1.[012]) + # On Rhapsody replace the C library is the System framework + compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's/ -lc / System.ltframework /'` + finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's/ -lc / System.ltframework /'` + ;; + esac + + case $host in + *-*-darwin*) + # Don't allow lazy linking, it breaks C++ global constructors + # But is supposedly fixed on 10.4 or later (yay!). + if test CXX = "$tagname"; then + case ${MACOSX_DEPLOYMENT_TARGET-10.0} in + 10.[0123]) + func_append compile_command " $wl-bind_at_load" + func_append finalize_command " $wl-bind_at_load" + ;; + esac + fi + # Time to change all our "foo.ltframework" stuff back to "-framework foo" + compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + ;; + esac + + + # move library search paths that coincide with paths to not yet + # installed libraries to the beginning of the library search list + new_libs= + for path in $notinst_path; do + case " $new_libs " in + *" -L$path/$objdir "*) ;; + *) + case " $compile_deplibs " in + *" -L$path/$objdir "*) + func_append new_libs " -L$path/$objdir" ;; + esac + ;; + esac + done + for deplib in $compile_deplibs; do + case $deplib in + -L*) + case " $new_libs " in + *" $deplib "*) ;; + *) func_append new_libs " $deplib" ;; + esac + ;; + *) func_append new_libs " $deplib" ;; + esac + done + compile_deplibs=$new_libs + + + func_append compile_command " $compile_deplibs" + func_append finalize_command " $finalize_deplibs" + + if test -n "$rpath$xrpath"; then + # If the user specified any rpath flags, then add them. + for libdir in $rpath $xrpath; do + # This is the magic to use -rpath. + case "$finalize_rpath " in + *" $libdir "*) ;; + *) func_append finalize_rpath " $libdir" ;; + esac + done + fi + + # Now hardcode the library paths + rpath= + hardcode_libdirs= + for libdir in $compile_rpath $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs=$libdir + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + func_append rpath " $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) func_append perm_rpath " $libdir" ;; + esac + fi + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + testbindir=`$ECHO "$libdir" | $SED -e 's*/lib$*/bin*'` + case :$dllsearchpath: in + *":$libdir:"*) ;; + ::) dllsearchpath=$libdir;; + *) func_append dllsearchpath ":$libdir";; + esac + case :$dllsearchpath: in + *":$testbindir:"*) ;; + ::) dllsearchpath=$testbindir;; + *) func_append dllsearchpath ":$testbindir";; + esac + ;; + esac + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir=$hardcode_libdirs + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + compile_rpath=$rpath + + rpath= + hardcode_libdirs= + for libdir in $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs=$libdir + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + func_append rpath " $flag" + fi + elif test -n "$runpath_var"; then + case "$finalize_perm_rpath " in + *" $libdir "*) ;; + *) func_append finalize_perm_rpath " $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir=$hardcode_libdirs + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + finalize_rpath=$rpath + + if test -n "$libobjs" && test yes = "$build_old_libs"; then + # Transform all the library objects into standard objects. + compile_command=`$ECHO "$compile_command" | $SP2NL | $SED "$lo2o" | $NL2SP` + finalize_command=`$ECHO "$finalize_command" | $SP2NL | $SED "$lo2o" | $NL2SP` + fi + + func_generate_dlsyms "$outputname" "@PROGRAM@" false + + # template prelinking step + if test -n "$prelink_cmds"; then + func_execute_cmds "$prelink_cmds" 'exit $?' + fi + + wrappers_required=: + case $host in + *cegcc* | *mingw32ce*) + # Disable wrappers for cegcc and mingw32ce hosts, we are cross compiling anyway. + wrappers_required=false + ;; + *cygwin* | *mingw* ) + test yes = "$build_libtool_libs" || wrappers_required=false + ;; + *) + if test no = "$need_relink" || test yes != "$build_libtool_libs"; then + wrappers_required=false + fi + ;; + esac + $wrappers_required || { + # Replace the output file specification. + compile_command=`$ECHO "$compile_command" | $SED 's%@OUTPUT@%'"$output"'%g'` + link_command=$compile_command$compile_rpath + + # We have no uninstalled library dependencies, so finalize right now. + exit_status=0 + func_show_eval "$link_command" 'exit_status=$?' + + if test -n "$postlink_cmds"; then + func_to_tool_file "$output" + postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` + func_execute_cmds "$postlink_cmds" 'exit $?' + fi + + # Delete the generated files. + if test -f "$output_objdir/${outputname}S.$objext"; then + func_show_eval '$RM "$output_objdir/${outputname}S.$objext"' + fi + + exit $exit_status + } + + if test -n "$compile_shlibpath$finalize_shlibpath"; then + compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" + fi + if test -n "$finalize_shlibpath"; then + finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" + fi + + compile_var= + finalize_var= + if test -n "$runpath_var"; then + if test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + func_append rpath "$dir:" + done + compile_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + if test -n "$finalize_perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $finalize_perm_rpath; do + func_append rpath "$dir:" + done + finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + fi + + if test yes = "$no_install"; then + # We don't need to create a wrapper script. + link_command=$compile_var$compile_command$compile_rpath + # Replace the output file specification. + link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output"'%g'` + # Delete the old output file. + $opt_dry_run || $RM $output + # Link the executable and exit + func_show_eval "$link_command" 'exit $?' + + if test -n "$postlink_cmds"; then + func_to_tool_file "$output" + postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` + func_execute_cmds "$postlink_cmds" 'exit $?' + fi + + exit $EXIT_SUCCESS + fi + + case $hardcode_action,$fast_install in + relink,*) + # Fast installation is not supported + link_command=$compile_var$compile_command$compile_rpath + relink_command=$finalize_var$finalize_command$finalize_rpath + + func_warning "this platform does not like uninstalled shared libraries" + func_warning "'$output' will be relinked during installation" + ;; + *,yes) + link_command=$finalize_var$compile_command$finalize_rpath + relink_command=`$ECHO "$compile_var$compile_command$compile_rpath" | $SED 's%@OUTPUT@%\$progdir/\$file%g'` + ;; + *,no) + link_command=$compile_var$compile_command$compile_rpath + relink_command=$finalize_var$finalize_command$finalize_rpath + ;; + *,needless) + link_command=$finalize_var$compile_command$finalize_rpath + relink_command= + ;; + esac + + # Replace the output file specification. + link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` + + # Delete the old output files. + $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname + + func_show_eval "$link_command" 'exit $?' + + if test -n "$postlink_cmds"; then + func_to_tool_file "$output_objdir/$outputname" + postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` + func_execute_cmds "$postlink_cmds" 'exit $?' + fi + + # Now create the wrapper script. + func_verbose "creating $output" + + # Quote the relink command for shipping. + if test -n "$relink_command"; then + # Preserve any variables that may affect compiler behavior + for var in $variables_saved_for_relink; do + if eval test -z \"\${$var+set}\"; then + relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" + elif eval var_value=\$$var; test -z "$var_value"; then + relink_command="$var=; export $var; $relink_command" + else + func_quote_for_eval "$var_value" + relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" + fi + done + relink_command="(cd `pwd`; $relink_command)" + relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` + fi + + # Only actually do things if not in dry run mode. + $opt_dry_run || { + # win32 will think the script is a binary if it has + # a .exe suffix, so we strip it off here. + case $output in + *.exe) func_stripname '' '.exe' "$output" + output=$func_stripname_result ;; + esac + # test for cygwin because mv fails w/o .exe extensions + case $host in + *cygwin*) + exeext=.exe + func_stripname '' '.exe' "$outputname" + outputname=$func_stripname_result ;; + *) exeext= ;; + esac + case $host in + *cygwin* | *mingw* ) + func_dirname_and_basename "$output" "" "." + output_name=$func_basename_result + output_path=$func_dirname_result + cwrappersource=$output_path/$objdir/lt-$output_name.c + cwrapper=$output_path/$output_name.exe + $RM $cwrappersource $cwrapper + trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15 + + func_emit_cwrapperexe_src > $cwrappersource + + # The wrapper executable is built using the $host compiler, + # because it contains $host paths and files. If cross- + # compiling, it, like the target executable, must be + # executed on the $host or under an emulation environment. + $opt_dry_run || { + $LTCC $LTCFLAGS -o $cwrapper $cwrappersource + $STRIP $cwrapper + } + + # Now, create the wrapper script for func_source use: + func_ltwrapper_scriptname $cwrapper + $RM $func_ltwrapper_scriptname_result + trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15 + $opt_dry_run || { + # note: this script will not be executed, so do not chmod. + if test "x$build" = "x$host"; then + $cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result + else + func_emit_wrapper no > $func_ltwrapper_scriptname_result + fi + } + ;; + * ) + $RM $output + trap "$RM $output; exit $EXIT_FAILURE" 1 2 15 + + func_emit_wrapper no > $output + chmod +x $output + ;; + esac + } + exit $EXIT_SUCCESS + ;; + esac + + # See if we need to build an old-fashioned archive. + for oldlib in $oldlibs; do + + case $build_libtool_libs in + convenience) + oldobjs="$libobjs_save $symfileobj" + addlibs=$convenience + build_libtool_libs=no + ;; + module) + oldobjs=$libobjs_save + addlibs=$old_convenience + build_libtool_libs=no + ;; + *) + oldobjs="$old_deplibs $non_pic_objects" + $preload && test -f "$symfileobj" \ + && func_append oldobjs " $symfileobj" + addlibs=$old_convenience + ;; + esac + + if test -n "$addlibs"; then + gentop=$output_objdir/${outputname}x + func_append generated " $gentop" + + func_extract_archives $gentop $addlibs + func_append oldobjs " $func_extract_archives_result" + fi + + # Do each command in the archive commands. + if test -n "$old_archive_from_new_cmds" && test yes = "$build_libtool_libs"; then + cmds=$old_archive_from_new_cmds + else + + # Add any objects from preloaded convenience libraries + if test -n "$dlprefiles"; then + gentop=$output_objdir/${outputname}x + func_append generated " $gentop" + + func_extract_archives $gentop $dlprefiles + func_append oldobjs " $func_extract_archives_result" + fi + + # POSIX demands no paths to be encoded in archives. We have + # to avoid creating archives with duplicate basenames if we + # might have to extract them afterwards, e.g., when creating a + # static archive out of a convenience library, or when linking + # the entirety of a libtool archive into another (currently + # not supported by libtool). + if (for obj in $oldobjs + do + func_basename "$obj" + $ECHO "$func_basename_result" + done | sort | sort -uc >/dev/null 2>&1); then + : + else + echo "copying selected object files to avoid basename conflicts..." + gentop=$output_objdir/${outputname}x + func_append generated " $gentop" + func_mkdir_p "$gentop" + save_oldobjs=$oldobjs + oldobjs= + counter=1 + for obj in $save_oldobjs + do + func_basename "$obj" + objbase=$func_basename_result + case " $oldobjs " in + " ") oldobjs=$obj ;; + *[\ /]"$objbase "*) + while :; do + # Make sure we don't pick an alternate name that also + # overlaps. + newobj=lt$counter-$objbase + func_arith $counter + 1 + counter=$func_arith_result + case " $oldobjs " in + *[\ /]"$newobj "*) ;; + *) if test ! -f "$gentop/$newobj"; then break; fi ;; + esac + done + func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj" + func_append oldobjs " $gentop/$newobj" + ;; + *) func_append oldobjs " $obj" ;; + esac + done + fi + func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 + tool_oldlib=$func_to_tool_file_result + eval cmds=\"$old_archive_cmds\" + + func_len " $cmds" + len=$func_len_result + if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then + cmds=$old_archive_cmds + elif test -n "$archiver_list_spec"; then + func_verbose "using command file archive linking..." + for obj in $oldobjs + do + func_to_tool_file "$obj" + $ECHO "$func_to_tool_file_result" + done > $output_objdir/$libname.libcmd + func_to_tool_file "$output_objdir/$libname.libcmd" + oldobjs=" $archiver_list_spec$func_to_tool_file_result" + cmds=$old_archive_cmds + else + # the command line is too long to link in one step, link in parts + func_verbose "using piecewise archive linking..." + save_RANLIB=$RANLIB + RANLIB=: + objlist= + concat_cmds= + save_oldobjs=$oldobjs + oldobjs= + # Is there a better way of finding the last object in the list? + for obj in $save_oldobjs + do + last_oldobj=$obj + done + eval test_cmds=\"$old_archive_cmds\" + func_len " $test_cmds" + len0=$func_len_result + len=$len0 + for obj in $save_oldobjs + do + func_len " $obj" + func_arith $len + $func_len_result + len=$func_arith_result + func_append objlist " $obj" + if test "$len" -lt "$max_cmd_len"; then + : + else + # the above command should be used before it gets too long + oldobjs=$objlist + if test "$obj" = "$last_oldobj"; then + RANLIB=$save_RANLIB + fi + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + eval concat_cmds=\"\$concat_cmds$old_archive_cmds\" + objlist= + len=$len0 + fi + done + RANLIB=$save_RANLIB + oldobjs=$objlist + if test -z "$oldobjs"; then + eval cmds=\"\$concat_cmds\" + else + eval cmds=\"\$concat_cmds~\$old_archive_cmds\" + fi + fi + fi + func_execute_cmds "$cmds" 'exit $?' + done + + test -n "$generated" && \ + func_show_eval "${RM}r$generated" + + # Now create the libtool archive. + case $output in + *.la) + old_library= + test yes = "$build_old_libs" && old_library=$libname.$libext + func_verbose "creating $output" + + # Preserve any variables that may affect compiler behavior + for var in $variables_saved_for_relink; do + if eval test -z \"\${$var+set}\"; then + relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" + elif eval var_value=\$$var; test -z "$var_value"; then + relink_command="$var=; export $var; $relink_command" + else + func_quote_for_eval "$var_value" + relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" + fi + done + # Quote the link command for shipping. + relink_command="(cd `pwd`; $SHELL \"$progpath\" $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)" + relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` + if test yes = "$hardcode_automatic"; then + relink_command= + fi + + # Only create the output if not a dry run. + $opt_dry_run || { + for installed in no yes; do + if test yes = "$installed"; then + if test -z "$install_libdir"; then + break + fi + output=$output_objdir/${outputname}i + # Replace all uninstalled libtool libraries with the installed ones + newdependency_libs= + for deplib in $dependency_libs; do + case $deplib in + *.la) + func_basename "$deplib" + name=$func_basename_result + func_resolve_sysroot "$deplib" + eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $func_resolve_sysroot_result` + test -z "$libdir" && \ + func_fatal_error "'$deplib' is not a valid libtool archive" + func_append newdependency_libs " ${lt_sysroot:+=}$libdir/$name" + ;; + -L*) + func_stripname -L '' "$deplib" + func_replace_sysroot "$func_stripname_result" + func_append newdependency_libs " -L$func_replace_sysroot_result" + ;; + -R*) + func_stripname -R '' "$deplib" + func_replace_sysroot "$func_stripname_result" + func_append newdependency_libs " -R$func_replace_sysroot_result" + ;; + *) func_append newdependency_libs " $deplib" ;; + esac + done + dependency_libs=$newdependency_libs + newdlfiles= + + for lib in $dlfiles; do + case $lib in + *.la) + func_basename "$lib" + name=$func_basename_result + eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + test -z "$libdir" && \ + func_fatal_error "'$lib' is not a valid libtool archive" + func_append newdlfiles " ${lt_sysroot:+=}$libdir/$name" + ;; + *) func_append newdlfiles " $lib" ;; + esac + done + dlfiles=$newdlfiles + newdlprefiles= + for lib in $dlprefiles; do + case $lib in + *.la) + # Only pass preopened files to the pseudo-archive (for + # eventual linking with the app. that links it) if we + # didn't already link the preopened objects directly into + # the library: + func_basename "$lib" + name=$func_basename_result + eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + test -z "$libdir" && \ + func_fatal_error "'$lib' is not a valid libtool archive" + func_append newdlprefiles " ${lt_sysroot:+=}$libdir/$name" + ;; + esac + done + dlprefiles=$newdlprefiles + else + newdlfiles= + for lib in $dlfiles; do + case $lib in + [\\/]* | [A-Za-z]:[\\/]*) abs=$lib ;; + *) abs=`pwd`"/$lib" ;; + esac + func_append newdlfiles " $abs" + done + dlfiles=$newdlfiles + newdlprefiles= + for lib in $dlprefiles; do + case $lib in + [\\/]* | [A-Za-z]:[\\/]*) abs=$lib ;; + *) abs=`pwd`"/$lib" ;; + esac + func_append newdlprefiles " $abs" + done + dlprefiles=$newdlprefiles + fi + $RM $output + # place dlname in correct position for cygwin + # In fact, it would be nice if we could use this code for all target + # systems that can't hard-code library paths into their executables + # and that have no shared library path variable independent of PATH, + # but it turns out we can't easily determine that from inspecting + # libtool variables, so we have to hard-code the OSs to which it + # applies here; at the moment, that means platforms that use the PE + # object format with DLL files. See the long comment at the top of + # tests/bindir.at for full details. + tdlname=$dlname + case $host,$output,$installed,$module,$dlname in + *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll) + # If a -bindir argument was supplied, place the dll there. + if test -n "$bindir"; then + func_relative_path "$install_libdir" "$bindir" + tdlname=$func_relative_path_result/$dlname + else + # Otherwise fall back on heuristic. + tdlname=../bin/$dlname + fi + ;; + esac + $ECHO > $output "\ +# $outputname - a libtool library file +# Generated by $PROGRAM (GNU $PACKAGE) $VERSION +# +# Please DO NOT delete this file! +# It is necessary for linking the library. + +# The name that we can dlopen(3). +dlname='$tdlname' + +# Names of this library. +library_names='$library_names' + +# The name of the static archive. +old_library='$old_library' + +# Linker flags that cannot go in dependency_libs. +inherited_linker_flags='$new_inherited_linker_flags' + +# Libraries that this one depends upon. +dependency_libs='$dependency_libs' + +# Names of additional weak libraries provided by this library +weak_library_names='$weak_libs' + +# Version information for $libname. +current=$current +age=$age +revision=$revision + +# Is this an already installed library? +installed=$installed + +# Should we warn about portability when linking against -modules? +shouldnotlink=$module + +# Files to dlopen/dlpreopen +dlopen='$dlfiles' +dlpreopen='$dlprefiles' + +# Directory that this library needs to be installed in: +libdir='$install_libdir'" + if test no,yes = "$installed,$need_relink"; then + $ECHO >> $output "\ +relink_command=\"$relink_command\"" + fi + done + } + + # Do a symbolic link so that the libtool archive can be found in + # LD_LIBRARY_PATH before the program is installed. + func_show_eval '( cd "$output_objdir" && $RM "$outputname" && $LN_S "../$outputname" "$outputname" )' 'exit $?' + ;; + esac + exit $EXIT_SUCCESS +} + +if test link = "$opt_mode" || test relink = "$opt_mode"; then + func_mode_link ${1+"$@"} +fi + + +# func_mode_uninstall arg... +func_mode_uninstall () +{ + $debug_cmd + + RM=$nonopt + files= + rmforce=false + exit_status=0 + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic=$magic + + for arg + do + case $arg in + -f) func_append RM " $arg"; rmforce=: ;; + -*) func_append RM " $arg" ;; + *) func_append files " $arg" ;; + esac + done + + test -z "$RM" && \ + func_fatal_help "you must specify an RM program" + + rmdirs= + + for file in $files; do + func_dirname "$file" "" "." + dir=$func_dirname_result + if test . = "$dir"; then + odir=$objdir + else + odir=$dir/$objdir + fi + func_basename "$file" + name=$func_basename_result + test uninstall = "$opt_mode" && odir=$dir + + # Remember odir for removal later, being careful to avoid duplicates + if test clean = "$opt_mode"; then + case " $rmdirs " in + *" $odir "*) ;; + *) func_append rmdirs " $odir" ;; + esac + fi + + # Don't error if the file doesn't exist and rm -f was used. + if { test -L "$file"; } >/dev/null 2>&1 || + { test -h "$file"; } >/dev/null 2>&1 || + test -f "$file"; then + : + elif test -d "$file"; then + exit_status=1 + continue + elif $rmforce; then + continue + fi + + rmfiles=$file + + case $name in + *.la) + # Possibly a libtool archive, so verify it. + if func_lalib_p "$file"; then + func_source $dir/$name + + # Delete the libtool libraries and symlinks. + for n in $library_names; do + func_append rmfiles " $odir/$n" + done + test -n "$old_library" && func_append rmfiles " $odir/$old_library" + + case $opt_mode in + clean) + case " $library_names " in + *" $dlname "*) ;; + *) test -n "$dlname" && func_append rmfiles " $odir/$dlname" ;; + esac + test -n "$libdir" && func_append rmfiles " $odir/$name $odir/${name}i" + ;; + uninstall) + if test -n "$library_names"; then + # Do each command in the postuninstall commands. + func_execute_cmds "$postuninstall_cmds" '$rmforce || exit_status=1' + fi + + if test -n "$old_library"; then + # Do each command in the old_postuninstall commands. + func_execute_cmds "$old_postuninstall_cmds" '$rmforce || exit_status=1' + fi + # FIXME: should reinstall the best remaining shared library. + ;; + esac + fi + ;; + + *.lo) + # Possibly a libtool object, so verify it. + if func_lalib_p "$file"; then + + # Read the .lo file + func_source $dir/$name + + # Add PIC object to the list of files to remove. + if test -n "$pic_object" && test none != "$pic_object"; then + func_append rmfiles " $dir/$pic_object" + fi + + # Add non-PIC object to the list of files to remove. + if test -n "$non_pic_object" && test none != "$non_pic_object"; then + func_append rmfiles " $dir/$non_pic_object" + fi + fi + ;; + + *) + if test clean = "$opt_mode"; then + noexename=$name + case $file in + *.exe) + func_stripname '' '.exe' "$file" + file=$func_stripname_result + func_stripname '' '.exe' "$name" + noexename=$func_stripname_result + # $file with .exe has already been added to rmfiles, + # add $file without .exe + func_append rmfiles " $file" + ;; + esac + # Do a test to see if this is a libtool program. + if func_ltwrapper_p "$file"; then + if func_ltwrapper_executable_p "$file"; then + func_ltwrapper_scriptname "$file" + relink_command= + func_source $func_ltwrapper_scriptname_result + func_append rmfiles " $func_ltwrapper_scriptname_result" + else + relink_command= + func_source $dir/$noexename + fi + + # note $name still contains .exe if it was in $file originally + # as does the version of $file that was added into $rmfiles + func_append rmfiles " $odir/$name $odir/${name}S.$objext" + if test yes = "$fast_install" && test -n "$relink_command"; then + func_append rmfiles " $odir/lt-$name" + fi + if test "X$noexename" != "X$name"; then + func_append rmfiles " $odir/lt-$noexename.c" + fi + fi + fi + ;; + esac + func_show_eval "$RM $rmfiles" 'exit_status=1' + done + + # Try to remove the $objdir's in the directories where we deleted files + for dir in $rmdirs; do + if test -d "$dir"; then + func_show_eval "rmdir $dir >/dev/null 2>&1" + fi + done + + exit $exit_status +} + +if test uninstall = "$opt_mode" || test clean = "$opt_mode"; then + func_mode_uninstall ${1+"$@"} +fi + +test -z "$opt_mode" && { + help=$generic_help + func_fatal_help "you must specify a MODE" +} + +test -z "$exec_cmd" && \ + func_fatal_help "invalid operation mode '$opt_mode'" + +if test -n "$exec_cmd"; then + eval exec "$exec_cmd" + exit $EXIT_FAILURE +fi + +exit $exit_status + + +# The TAGs below are defined such that we never get into a situation +# where we disable both kinds of libraries. Given conflicting +# choices, we go for a static library, that is the most portable, +# since we can't tell whether shared libraries were disabled because +# the user asked for that or because the platform doesn't support +# them. This is particularly important on AIX, because we don't +# support having both static and shared libraries enabled at the same +# time on that platform, so we default to a shared-only configuration. +# If a disable-shared tag is given, we'll fallback to a static-only +# configuration. But we'll never go from static-only to shared-only. + +# ### BEGIN LIBTOOL TAG CONFIG: disable-shared +build_libtool_libs=no +build_old_libs=yes +# ### END LIBTOOL TAG CONFIG: disable-shared + +# ### BEGIN LIBTOOL TAG CONFIG: disable-static +build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac` +# ### END LIBTOOL TAG CONFIG: disable-static + +# Local Variables: +# mode:shell-script +# sh-indentation:2 +# End: diff --git a/external/mit/isl/dist/m4/ax_c___attribute__.m4 b/external/mit/isl/dist/m4/ax_c___attribute__.m4 new file mode 100644 index 000000000000..cf3d62bbdf4f --- /dev/null +++ b/external/mit/isl/dist/m4/ax_c___attribute__.m4 @@ -0,0 +1,66 @@ +# =========================================================================== +# http://www.gnu.org/software/autoconf-archive/ax_c___attribute__.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_C___ATTRIBUTE__ +# +# DESCRIPTION +# +# Provides a test for the compiler support of __attribute__ extensions. +# Defines HAVE___ATTRIBUTE__ if it is found. +# +# LICENSE +# +# Copyright (c) 2008 Stepan Kasal +# Copyright (c) 2008 Christian Haggstrom +# Copyright (c) 2008 Ryan McCabe +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation; either version 2 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program. If not, see . +# +# As a special exception, the respective Autoconf Macro's copyright owner +# gives unlimited permission to copy, distribute and modify the configure +# scripts that are the output of Autoconf when processing the Macro. You +# need not follow the terms of the GNU General Public License when using +# or distributing such scripts, even though portions of the text of the +# Macro appear in them. The GNU General Public License (GPL) does govern +# all other use of the material that constitutes the Autoconf Macro. +# +# This special exception to the GPL applies to versions of the Autoconf +# Macro released by the Autoconf Archive. When you make and distribute a +# modified version of the Autoconf Macro, you may extend this special +# exception to the GPL to apply to your modified version as well. + +#serial 8 + +AC_DEFUN([AX_C___ATTRIBUTE__], [ + AC_CACHE_CHECK([for __attribute__], [ax_cv___attribute__], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[#include + static void foo(void) __attribute__ ((unused)); + static void + foo(void) { + exit(1); + } + ]], [])], + [ax_cv___attribute__=yes], + [ax_cv___attribute__=no] + ) + ]) + if test "$ax_cv___attribute__" = "yes"; then + AC_DEFINE([HAVE___ATTRIBUTE__], 1, [define if your compiler has __attribute__]) + fi +]) diff --git a/external/mit/isl/dist/m4/ax_cc_maxopt.m4 b/external/mit/isl/dist/m4/ax_cc_maxopt.m4 new file mode 100644 index 000000000000..65a06e9b5566 --- /dev/null +++ b/external/mit/isl/dist/m4/ax_cc_maxopt.m4 @@ -0,0 +1,206 @@ +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_cc_maxopt.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_CC_MAXOPT +# +# DESCRIPTION +# +# Try to turn on "good" C optimization flags for various compilers and +# architectures, for some definition of "good". (In our case, good for +# FFTW and hopefully for other scientific codes. Modify as needed.) +# +# The user can override the flags by setting the CFLAGS environment +# variable. The user can also specify --enable-portable-binary in order to +# disable any optimization flags that might result in a binary that only +# runs on the host architecture. +# +# Note also that the flags assume that ANSI C aliasing rules are followed +# by the code (e.g. for gcc's -fstrict-aliasing), and that floating-point +# computations can be re-ordered as needed. +# +# Requires macros: AX_CHECK_COMPILE_FLAG, AX_COMPILER_VENDOR, +# AX_GCC_ARCHFLAG, AX_GCC_X86_CPUID. +# +# LICENSE +# +# Copyright (c) 2008 Steven G. Johnson +# Copyright (c) 2008 Matteo Frigo +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program. If not, see . +# +# As a special exception, the respective Autoconf Macro's copyright owner +# gives unlimited permission to copy, distribute and modify the configure +# scripts that are the output of Autoconf when processing the Macro. You +# need not follow the terms of the GNU General Public License when using +# or distributing such scripts, even though portions of the text of the +# Macro appear in them. The GNU General Public License (GPL) does govern +# all other use of the material that constitutes the Autoconf Macro. +# +# This special exception to the GPL applies to versions of the Autoconf +# Macro released by the Autoconf Archive. When you make and distribute a +# modified version of the Autoconf Macro, you may extend this special +# exception to the GPL to apply to your modified version as well. + +#serial 23 + +AC_DEFUN([AX_CC_MAXOPT], +[ +AC_REQUIRE([AC_PROG_CC]) +AC_REQUIRE([AX_COMPILER_VENDOR]) +AC_REQUIRE([AC_CANONICAL_HOST]) + +AC_ARG_ENABLE(portable-binary, [AS_HELP_STRING([--enable-portable-binary], [disable compiler optimizations that would produce unportable binaries])], + acx_maxopt_portable=$enableval, acx_maxopt_portable=no) + +# Try to determine "good" native compiler flags if none specified via CFLAGS +if test "x$ac_test_CFLAGS" = "x"; then + case $ax_cv_c_compiler_vendor in + dec) CFLAGS="$CFLAGS -newc -w0 -O5 -ansi_alias -ansi_args -fp_reorder -tune host" + if test "x$acx_maxopt_portable" = xno; then + CFLAGS="$CFLAGS -arch host" + fi;; + + sun) CFLAGS="$CFLAGS -native -fast -xO5 -dalign" + if test "x$acx_maxopt_portable" = xyes; then + CFLAGS="$CFLAGS -xarch=generic" + fi;; + + hp) CFLAGS="$CFLAGS +Oall +Optrs_ansi +DSnative" + if test "x$acx_maxopt_portable" = xyes; then + CFLAGS="$CFLAGS +DAportable" + fi;; + + ibm) if test "x$acx_maxopt_portable" = xno; then + xlc_opt="-qarch=auto -qtune=auto" + else + xlc_opt="-qtune=auto" + fi + AX_CHECK_COMPILE_FLAG($xlc_opt, + CFLAGS="$CFLAGS -O3 -qansialias -w $xlc_opt", + [CFLAGS="$CFLAGS -O3 -qansialias -w" + echo "******************************************************" + echo "* You seem to have the IBM C compiler. It is *" + echo "* recommended for best performance that you use: *" + echo "* *" + echo "* CFLAGS=-O3 -qarch=xxx -qtune=xxx -qansialias -w *" + echo "* ^^^ ^^^ *" + echo "* where xxx is pwr2, pwr3, 604, or whatever kind of *" + echo "* CPU you have. (Set the CFLAGS environment var. *" + echo "* and re-run configure.) For more info, man cc. *" + echo "******************************************************"]) + ;; + + intel) CFLAGS="$CFLAGS -O3 -ansi_alias" + if test "x$acx_maxopt_portable" = xno; then + icc_archflag=unknown + icc_flags="" + case $host_cpu in + i686*|x86_64*) + # icc accepts gcc assembly syntax, so these should work: + AX_GCC_X86_CPUID(0) + AX_GCC_X86_CPUID(1) + case $ax_cv_gcc_x86_cpuid_0 in # see AX_GCC_ARCHFLAG + *:756e6547:6c65746e:49656e69) # Intel + case $ax_cv_gcc_x86_cpuid_1 in + *0?6[[78ab]]?:*:*:*|?6[[78ab]]?:*:*:*|6[[78ab]]?:*:*:*) icc_flags="-xK" ;; + *0?6[[9d]]?:*:*:*|?6[[9d]]?:*:*:*|6[[9d]]?:*:*:*|*1?65?:*:*:*) icc_flags="-xSSE2 -xB -xK" ;; + *0?6e?:*:*:*|?6e?:*:*:*|6e?:*:*:*) icc_flags="-xSSE3 -xP -xO -xB -xK" ;; + *0?6f?:*:*:*|?6f?:*:*:*|6f?:*:*:*|*1?66?:*:*:*) icc_flags="-xSSSE3 -xT -xB -xK" ;; + *1?6[[7d]]?:*:*:*) icc_flags="-xSSE4.1 -xS -xT -xB -xK" ;; + *1?6[[aef]]?:*:*:*|*2?6[[5cef]]?:*:*:*) icc_flags="-xSSE4.2 -xS -xT -xB -xK" ;; + *2?6[[ad]]?:*:*:*) icc_flags="-xAVX -SSE4.2 -xS -xT -xB -xK" ;; + *3?6[[ae]]?:*:*:*) icc_flags="-xCORE-AVX-I -xAVX -SSE4.2 -xS -xT -xB -xK" ;; + *3?6[[cf]]?:*:*:*|*4?6[[56]]?:*:*:*) icc_flags="-xCORE-AVX2 -xCORE-AVX-I -xAVX -SSE4.2 -xS -xT -xB -xK" ;; + *000?f[[346]]?:*:*:*|?f[[346]]?:*:*:*|f[[346]]?:*:*:*) icc_flags="-xSSE3 -xP -xO -xN -xW -xK" ;; + *00??f??:*:*:*|??f??:*:*:*|?f??:*:*:*|f??:*:*:*) icc_flags="-xSSE2 -xN -xW -xK" ;; + esac ;; + esac ;; + esac + if test "x$icc_flags" != x; then + for flag in $icc_flags; do + AX_CHECK_COMPILE_FLAG($flag, [icc_archflag=$flag; break]) + done + fi + AC_MSG_CHECKING([for icc architecture flag]) + AC_MSG_RESULT($icc_archflag) + if test "x$icc_archflag" != xunknown; then + CFLAGS="$CFLAGS $icc_archflag" + fi + fi + ;; + + nvhpc) + # default optimization flags for nvhpc + CFLAGS="$CFLAGS -O3" + ;; + + gnu) + # default optimization flags for gcc on all systems + CFLAGS="$CFLAGS -O3 -fomit-frame-pointer" + + # -malign-double for x86 systems + AX_CHECK_COMPILE_FLAG(-malign-double, CFLAGS="$CFLAGS -malign-double") + + # -fstrict-aliasing for gcc-2.95+ + AX_CHECK_COMPILE_FLAG(-fstrict-aliasing, + CFLAGS="$CFLAGS -fstrict-aliasing") + + # note that we enable "unsafe" fp optimization with other compilers, too + AX_CHECK_COMPILE_FLAG(-ffast-math, CFLAGS="$CFLAGS -ffast-math") + + AX_GCC_ARCHFLAG($acx_maxopt_portable) + + # drop to -O1 for gcc 4.2 + $CC --version | + sed -e 's/.* \(@<:@0-9@:>@@<:@0-9@:>@*\)\.\(@<:@0-9@:>@@<:@0-9@:>@*\).*/\1 \2/' | + (read major minor + if test $major -eq 4 -a $minor -eq 2; then + exit 0 + fi + exit 1 + ) && CFLAGS="-O1" + ;; + + microsoft) + # default optimization flags for MSVC opt builds + CFLAGS="$CFLAGS -O2" + ;; + esac + + if test -z "$CFLAGS"; then + echo "" + echo "********************************************************" + echo "* WARNING: Don't know the best CFLAGS for this system *" + echo "* Use ./configure CFLAGS=... to specify your own flags *" + echo "* (otherwise, a default of CFLAGS=-O3 will be used) *" + echo "********************************************************" + echo "" + CFLAGS="$CFLAGS -O3" + fi + + AX_CHECK_COMPILE_FLAG($CFLAGS, [], [ + echo "" + echo "********************************************************" + echo "* WARNING: The guessed CFLAGS don't seem to work with *" + echo "* your compiler. *" + echo "* Use ./configure CFLAGS=... to specify your own flags *" + echo "********************************************************" + echo "" + ]) + +fi +]) diff --git a/external/mit/isl/dist/m4/ax_check_compile_flag.m4 b/external/mit/isl/dist/m4/ax_check_compile_flag.m4 new file mode 100644 index 000000000000..bd753b34d7dc --- /dev/null +++ b/external/mit/isl/dist/m4/ax_check_compile_flag.m4 @@ -0,0 +1,53 @@ +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_check_compile_flag.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_CHECK_COMPILE_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS], [INPUT]) +# +# DESCRIPTION +# +# Check whether the given FLAG works with the current language's compiler +# or gives an error. (Warnings, however, are ignored) +# +# ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on +# success/failure. +# +# If EXTRA-FLAGS is defined, it is added to the current language's default +# flags (e.g. CFLAGS) when the check is done. The check is thus made with +# the flags: "CFLAGS EXTRA-FLAGS FLAG". This can for example be used to +# force the compiler to issue an error when a bad flag is given. +# +# INPUT gives an alternative input source to AC_COMPILE_IFELSE. +# +# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this +# macro in sync with AX_CHECK_{PREPROC,LINK}_FLAG. +# +# LICENSE +# +# Copyright (c) 2008 Guido U. Draheim +# Copyright (c) 2011 Maarten Bosmans +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 6 + +AC_DEFUN([AX_CHECK_COMPILE_FLAG], +[AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_IF +AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_[]_AC_LANG_ABBREV[]flags_$4_$1])dnl +AC_CACHE_CHECK([whether _AC_LANG compiler accepts $1], CACHEVAR, [ + ax_check_save_flags=$[]_AC_LANG_PREFIX[]FLAGS + _AC_LANG_PREFIX[]FLAGS="$[]_AC_LANG_PREFIX[]FLAGS $4 $1" + AC_COMPILE_IFELSE([m4_default([$5],[AC_LANG_PROGRAM()])], + [AS_VAR_SET(CACHEVAR,[yes])], + [AS_VAR_SET(CACHEVAR,[no])]) + _AC_LANG_PREFIX[]FLAGS=$ax_check_save_flags]) +AS_VAR_IF(CACHEVAR,yes, + [m4_default([$2], :)], + [m4_default([$3], :)]) +AS_VAR_POPDEF([CACHEVAR])dnl +])dnl AX_CHECK_COMPILE_FLAGS diff --git a/external/mit/isl/dist/m4/ax_compiler_vendor.m4 b/external/mit/isl/dist/m4/ax_compiler_vendor.m4 new file mode 100644 index 000000000000..f9d85f6e158e --- /dev/null +++ b/external/mit/isl/dist/m4/ax_compiler_vendor.m4 @@ -0,0 +1,120 @@ +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_compiler_vendor.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_COMPILER_VENDOR +# +# DESCRIPTION +# +# Determine the vendor of the C, C++ or Fortran compiler. The vendor is +# returned in the cache variable $ax_cv_c_compiler_vendor for C, +# $ax_cv_cxx_compiler_vendor for C++ or $ax_cv_fc_compiler_vendor for +# (modern) Fortran. The value is one of "intel", "ibm", "pathscale", +# "clang" (LLVM), "cray", "fujitsu", "sdcc", "sx", "nvhpc" (NVIDIA HPC +# Compiler), "portland" (PGI), "pcc", "gnu" (GCC), "sun" (Oracle Developer +# Studio), "hp", "dec", "borland", "comeau", "kai", "lcc", "sgi", +# "microsoft", "metrowerks", "watcom", "tcc" (Tiny CC) or "unknown" (if +# the compiler cannot be determined). +# +# To check for a Fortran compiler, you must first call AC_FC_PP_SRCEXT +# with an appropriate preprocessor-enabled extension. For example: +# +# AC_LANG_PUSH([Fortran]) +# AC_PROG_FC +# AC_FC_PP_SRCEXT([F]) +# AX_COMPILER_VENDOR +# AC_LANG_POP([Fortran]) +# +# LICENSE +# +# Copyright (c) 2008 Steven G. Johnson +# Copyright (c) 2008 Matteo Frigo +# Copyright (c) 2018-19 John Zaitseff +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program. If not, see . +# +# As a special exception, the respective Autoconf Macro's copyright owner +# gives unlimited permission to copy, distribute and modify the configure +# scripts that are the output of Autoconf when processing the Macro. You +# need not follow the terms of the GNU General Public License when using +# or distributing such scripts, even though portions of the text of the +# Macro appear in them. The GNU General Public License (GPL) does govern +# all other use of the material that constitutes the Autoconf Macro. +# +# This special exception to the GPL applies to versions of the Autoconf +# Macro released by the Autoconf Archive. When you make and distribute a +# modified version of the Autoconf Macro, you may extend this special +# exception to the GPL to apply to your modified version as well. + +#serial 32 + +AC_DEFUN([AX_COMPILER_VENDOR], [dnl + AC_CACHE_CHECK([for _AC_LANG compiler vendor], ax_cv_[]_AC_LANG_ABBREV[]_compiler_vendor, [dnl + dnl If you modify this list of vendors, please add similar support + dnl to ax_compiler_version.m4 if at all possible. + dnl + dnl Note: Do NOT check for GCC first since some other compilers + dnl define __GNUC__ to remain compatible with it. Compilers that + dnl are very slow to start (such as Intel) are listed first. + + vendors=" + intel: __ICC,__ECC,__INTEL_COMPILER + ibm: __xlc__,__xlC__,__IBMC__,__IBMCPP__,__ibmxl__ + pathscale: __PATHCC__,__PATHSCALE__ + clang: __clang__ + cray: _CRAYC + fujitsu: __FUJITSU + sdcc: SDCC,__SDCC + sx: _SX + nvhpc: __NVCOMPILER + portland: __PGI + pcc: __PCC__ + gnu: __GNUC__ + sun: __SUNPRO_C,__SUNPRO_CC,__SUNPRO_F90,__SUNPRO_F95 + hp: __HP_cc,__HP_aCC + dec: __DECC,__DECCXX,__DECC_VER,__DECCXX_VER + borland: __BORLANDC__,__CODEGEARC__,__TURBOC__ + comeau: __COMO__ + kai: __KCC + lcc: __LCC__ + sgi: __sgi,sgi + microsoft: _MSC_VER + metrowerks: __MWERKS__ + watcom: __WATCOMC__ + tcc: __TINYC__ + unknown: UNKNOWN + " + for ventest in $vendors; do + case $ventest in + *:) + vendor=$ventest + continue + ;; + *) + vencpp="defined("`echo $ventest | sed 's/,/) || defined(/g'`")" + ;; + esac + + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [[ +#if !($vencpp) + thisisanerror; +#endif + ]])], [break]) + done + + ax_cv_[]_AC_LANG_ABBREV[]_compiler_vendor=`echo $vendor | cut -d: -f1` + ]) +])dnl diff --git a/external/mit/isl/dist/m4/ax_create_pkgconfig_info.m4 b/external/mit/isl/dist/m4/ax_create_pkgconfig_info.m4 new file mode 100644 index 000000000000..308e64ff8544 --- /dev/null +++ b/external/mit/isl/dist/m4/ax_create_pkgconfig_info.m4 @@ -0,0 +1,351 @@ +# ============================================================================ +# http://www.gnu.org/software/autoconf-archive/ax_create_pkgconfig_info.html +# ============================================================================ +# +# SYNOPSIS +# +# AX_CREATE_PKGCONFIG_INFO [(outputfile, [requires [,libs [,summary [,cflags [, ldflags]]]]])] +# +# DESCRIPTION +# +# Defaults: +# +# $1 = $PACKAGE_NAME.pc +# $2 = (empty) +# $3 = $PACKAGE_LIBS $LIBS (as set at that point in configure.ac) +# $4 = $PACKAGE_SUMMARY (or $1 Library) +# $5 = $PACKAGE_CFLAGS (as set at the point in configure.ac) +# $6 = $PACKAGE_LDFLAGS (as set at the point in configure.ac) +# +# PACKAGE_NAME defaults to $PACKAGE if not set. +# PACKAGE_LIBS defaults to -l$PACKAGE_NAME if not set. +# +# The resulting file is called $PACKAGE.pc.in / $PACKAGE.pc +# +# You will find this macro most useful in conjunction with +# ax_spec_defaults that can read good initializers from the .spec file. In +# consequencd, most of the generatable installable stuff can be made from +# information being updated in a single place for the whole project. +# +# LICENSE +# +# Copyright (c) 2008 Guido U. Draheim +# Copyright (c) 2008 Sven Verdoolaege +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation; either version 3 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program. If not, see . +# +# As a special exception, the respective Autoconf Macro's copyright owner +# gives unlimited permission to copy, distribute and modify the configure +# scripts that are the output of Autoconf when processing the Macro. You +# need not follow the terms of the GNU General Public License when using +# or distributing such scripts, even though portions of the text of the +# Macro appear in them. The GNU General Public License (GPL) does govern +# all other use of the material that constitutes the Autoconf Macro. +# +# This special exception to the GPL applies to versions of the Autoconf +# Macro released by the Autoconf Archive. When you make and distribute a +# modified version of the Autoconf Macro, you may extend this special +# exception to the GPL to apply to your modified version as well. + +#serial 12 + +AC_DEFUN([AX_CREATE_PKGCONFIG_INFO],[dnl +AS_VAR_PUSHDEF([PKGCONFIG_suffix],[ax_create_pkgconfig_suffix])dnl +AS_VAR_PUSHDEF([PKGCONFIG_libdir],[ax_create_pkgconfig_libdir])dnl +AS_VAR_PUSHDEF([PKGCONFIG_libfile],[ax_create_pkgconfig_libfile])dnl +AS_VAR_PUSHDEF([PKGCONFIG_libname],[ax_create_pkgconfig_libname])dnl +AS_VAR_PUSHDEF([PKGCONFIG_version],[ax_create_pkgconfig_version])dnl +AS_VAR_PUSHDEF([PKGCONFIG_description],[ax_create_pkgconfig_description])dnl +AS_VAR_PUSHDEF([PKGCONFIG_requires],[ax_create_pkgconfig_requires])dnl +AS_VAR_PUSHDEF([PKGCONFIG_pkglibs],[ax_create_pkgconfig_pkglibs])dnl +AS_VAR_PUSHDEF([PKGCONFIG_libs],[ax_create_pkgconfig_libs])dnl +AS_VAR_PUSHDEF([PKGCONFIG_ldflags],[ax_create_pkgconfig_ldflags])dnl +AS_VAR_PUSHDEF([PKGCONFIG_cppflags],[ax_create_pkgconfig_cppflags])dnl +AS_VAR_PUSHDEF([PKGCONFIG_generate],[ax_create_pkgconfig_generate])dnl +AS_VAR_PUSHDEF([PKGCONFIG_src_libdir],[ax_create_pkgconfig_src_libdir])dnl +AS_VAR_PUSHDEF([PKGCONFIG_src_headers],[ax_create_pkgconfig_src_headers])dnl + +# we need the expanded forms... +test "x$prefix" = xNONE && prefix=$ac_default_prefix +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +AC_MSG_CHECKING(our pkgconfig libname) +test ".$PKGCONFIG_libname" != "." || \ +PKGCONFIG_libname="ifelse($1,,${PACKAGE_NAME},`basename $1 .pc`)" +test ".$PKGCONFIG_libname" != "." || \ +PKGCONFIG_libname="$PACKAGE" +PKGCONFIG_libname=`eval echo "$PKGCONFIG_libname"` +PKGCONFIG_libname=`eval echo "$PKGCONFIG_libname"` +AC_MSG_RESULT($PKGCONFIG_libname) + +AC_MSG_CHECKING(our pkgconfig version) +test ".$PKGCONFIG_version" != "." || \ +PKGCONFIG_version="${PACKAGE_VERSION}" +test ".$PKGCONFIG_version" != "." || \ +PKGCONFIG_version="$VERSION" +PKGCONFIG_version=`eval echo "$PKGCONFIG_version"` +PKGCONFIG_version=`eval echo "$PKGCONFIG_version"` +AC_MSG_RESULT($PKGCONFIG_version) + +AC_MSG_CHECKING(our pkgconfig_libdir) +test ".$pkgconfig_libdir" = "." && \ +pkgconfig_libdir='${libdir}/pkgconfig' +PKGCONFIG_libdir=`eval echo "$pkgconfig_libdir"` +PKGCONFIG_libdir=`eval echo "$PKGCONFIG_libdir"` +PKGCONFIG_libdir=`eval echo "$PKGCONFIG_libdir"` +AC_MSG_RESULT($pkgconfig_libdir) +test "$pkgconfig_libdir" != "$PKGCONFIG_libdir" && ( +AC_MSG_RESULT(expanded our pkgconfig_libdir... $PKGCONFIG_libdir)) +AC_SUBST([pkgconfig_libdir]) + +AC_MSG_CHECKING(our pkgconfig_libfile) +test ".$pkgconfig_libfile" != "." || \ +pkgconfig_libfile="ifelse($1,,$PKGCONFIG_libname.pc,`basename $1`)" +PKGCONFIG_libfile=`eval echo "$pkgconfig_libfile"` +PKGCONFIG_libfile=`eval echo "$PKGCONFIG_libfile"` +AC_MSG_RESULT($pkgconfig_libfile) +test "$pkgconfig_libfile" != "$PKGCONFIG_libfile" && ( +AC_MSG_RESULT(expanded our pkgconfig_libfile... $PKGCONFIG_libfile)) +AC_SUBST([pkgconfig_libfile]) + +AC_MSG_CHECKING(our package / suffix) +PKGCONFIG_suffix="$program_suffix" +test ".$PKGCONFIG_suffix" != .NONE || PKGCONFIG_suffix="" +AC_MSG_RESULT(${PACKAGE_NAME} / ${PKGCONFIG_suffix}) + +AC_MSG_CHECKING(our pkgconfig description) +PKGCONFIG_description="ifelse($4,,$PACKAGE_SUMMARY,$4)" +test ".$PKGCONFIG_description" != "." || \ +PKGCONFIG_description="$PKGCONFIG_libname Library" +PKGCONFIG_description=`eval echo "$PKGCONFIG_description"` +PKGCONFIG_description=`eval echo "$PKGCONFIG_description"` +AC_MSG_RESULT($PKGCONFIG_description) + +AC_MSG_CHECKING(our pkgconfig requires) +PKGCONFIG_requires="ifelse($2,,$PACKAGE_REQUIRES,$2)" +PKGCONFIG_requires=`eval echo "$PKGCONFIG_requires"` +PKGCONFIG_requires=`eval echo "$PKGCONFIG_requires"` +AC_MSG_RESULT($PKGCONFIG_requires) + +AC_MSG_CHECKING(our pkgconfig ext libs) +PKGCONFIG_pkglibs="$PACKAGE_LIBS" +test ".$PKGCONFIG_pkglibs" != "." || PKGCONFIG_pkglibs="-l$PKGCONFIG_libname" +PKGCONFIG_libs="ifelse($3,,$PKGCONFIG_pkglibs $LIBS,$3)" +PKGCONFIG_libs=`eval echo "$PKGCONFIG_libs"` +PKGCONFIG_libs=`eval echo "$PKGCONFIG_libs"` +AC_MSG_RESULT($PKGCONFIG_libs) + +AC_MSG_CHECKING(our pkgconfig cppflags) +PKGCONFIG_cppflags="ifelse($5,,$PACKAGE_CFLAGS,$5)" +PKGCONFIG_cppflags=`eval echo "$PKGCONFIG_cppflags"` +PKGCONFIG_cppflags=`eval echo "$PKGCONFIG_cppflags"` +AC_MSG_RESULT($PKGCONFIG_cppflags) + +AC_MSG_CHECKING(our pkgconfig ldflags) +PKGCONFIG_ldflags="ifelse($6,,$PACKAGE_LDFLAGS,$5)" +PKGCONFIG_ldflags=`eval echo "$PKGCONFIG_ldflags"` +PKGCONFIG_ldflags=`eval echo "$PKGCONFIG_ldflags"` +AC_MSG_RESULT($PKGCONFIG_ldflags) + +test ".$PKGCONFIG_generate" != "." || \ +PKGCONFIG_generate="ifelse($1,,$PKGCONFIG_libname.pc,$1)" +PKGCONFIG_generate=`eval echo "$PKGCONFIG_generate"` +PKGCONFIG_generate=`eval echo "$PKGCONFIG_generate"` +test "$pkgconfig_libfile" != "$PKGCONFIG_generate" && ( +AC_MSG_RESULT(generate the pkgconfig later... $PKGCONFIG_generate)) + +if test ".$PKGCONFIG_src_libdir" = "." ; then +PKGCONFIG_src_libdir=`pwd` +PKGCONFIG_src_libdir=`AS_DIRNAME("$PKGCONFIG_src_libdir/$PKGCONFIG_generate")` +test ! -d $PKGCONFIG_src_libdir/src || \ +PKGCONFIG_src_libdir="$PKGCONFIG_src_libdir/src" +case ".$objdir" in +*libs) PKGCONFIG_src_libdir="$PKGCONFIG_src_libdir/$objdir" ;; esac +AC_MSG_RESULT(noninstalled pkgconfig -L $PKGCONFIG_src_libdir) +fi + +if test ".$PKGCONFIG_src_headers" = "." ; then +PKGCONFIG_src_headers=`pwd` +v="$ac_top_srcdir" ; +test ".$v" != "." || v="$ax_spec_dir" +test ".$v" != "." || v="$srcdir" +case "$v" in /*) PKGCONFIG_src_headers="" ;; esac +PKGCONFIG_src_headers=`AS_DIRNAME("$PKGCONFIG_src_headers/$v/x")` +test ! -d $PKGCONFIG_src_headers/incl[]ude || \ +PKGCONFIG_src_headers="$PKGCONFIG_src_headers/incl[]ude" +AC_MSG_RESULT(noninstalled pkgconfig -I $PKGCONFIG_src_headers) +fi + + +dnl AC_CONFIG_COMMANDS crap disallows to use $PKGCONFIG_libfile here... +AC_CONFIG_COMMANDS([$ax_create_pkgconfig_generate],[ +pkgconfig_generate="$ax_create_pkgconfig_generate" +if test ! -f "$pkgconfig_generate.in" +then generate="true" +elif grep ' generated by configure ' $pkgconfig_generate.in >/dev/null +then generate="true" +else generate="false"; +fi +if $generate ; then +AC_MSG_NOTICE(creating $pkgconfig_generate.in) +cat > $pkgconfig_generate.in <conftest.sed < $pkgconfig_generate +if test ! -s $pkgconfig_generate ; then + AC_MSG_ERROR([$pkgconfig_generate is empty]) +fi ; rm conftest.sed # DONE generate $pkgconfig_generate +pkgconfig_uninstalled=`echo $pkgconfig_generate |sed 's/.pc$/-uninstalled.pc/'` +AC_MSG_NOTICE(creating $pkgconfig_uninstalled) +cat >conftest.sed < $pkgconfig_uninstalled +if test ! -s $pkgconfig_uninstalled ; then + AC_MSG_ERROR([$pkgconfig_uninstalled is empty]) +fi ; rm conftest.sed # DONE generate $pkgconfig_uninstalled + pkgconfig_requires_add=`echo ${pkgconfig_requires}` +if test ".$pkgconfig_requires_add" != "." ; then + pkgconfig_requires_add="pkg-config $pkgconfig_requires_add" + else pkgconfig_requires_add=":" ; fi +pkgconfig_uninstalled=`echo $pkgconfig_generate |sed 's/.pc$/-uninstalled.sh/'` +AC_MSG_NOTICE(creating $pkgconfig_uninstalled) +cat >conftest.sed <Name:>for option\\; do case \"\$option\" in --list-all|--name) echo > +s>Description: *>\\;\\; --help) pkg-config --help \\; echo Buildscript Of > +s>Version: *>\\;\\; --modversion|--version) echo > +s>Requires:>\\;\\; --requires) echo $pkgconfig_requires_add> +s>Libs: *>\\;\\; --libs) echo > +s>Cflags: *>\\;\\; --cflags) echo > +/--libs)/a\\ + $pkgconfig_requires_add +/--cflags)/a\\ + $pkgconfig_requires_add\\ +;; --variable=*) eval echo '\$'\`echo \$option | sed -e 's/.*=//'\`\\ +;; --uninstalled) exit 0 \\ +;; *) ;; esac done +AXEOF +sed -f conftest.sed $pkgconfig_generate.in > $pkgconfig_uninstalled +if test ! -s $pkgconfig_uninstalled ; then + AC_MSG_ERROR([$pkgconfig_uninstalled is empty]) +fi ; rm conftest.sed # DONE generate $pkgconfig_uninstalled +],[ +dnl AC_CONFIG_COMMANDS crap, the AS_PUSHVAR defines are invalid here... +ax_create_pkgconfig_generate="$ax_create_pkgconfig_generate" +pkgconfig_prefix='$prefix' +pkgconfig_execprefix='$exec_prefix' +pkgconfig_bindir='$bindir' +pkgconfig_libdir='$libdir' +pkgconfig_includedir='$includedir' +pkgconfig_datarootdir='$datarootdir' +pkgconfig_datadir='$datadir' +pkgconfig_sysconfdir='$sysconfdir' +pkgconfig_suffix='$ax_create_pkgconfig_suffix' +pkgconfig_package='$PACKAGE_NAME' +pkgconfig_libname='$ax_create_pkgconfig_libname' +pkgconfig_description='$ax_create_pkgconfig_description' +pkgconfig_version='$ax_create_pkgconfig_version' +pkgconfig_requires='$ax_create_pkgconfig_requires' +pkgconfig_libs='$ax_create_pkgconfig_libs' +pkgconfig_ldflags='$ax_create_pkgconfig_ldflags' +pkgconfig_cppflags='$ax_create_pkgconfig_cppflags' +pkgconfig_src_libdir='$ax_create_pkgconfig_src_libdir' +pkgconfig_src_headers='$ax_create_pkgconfig_src_headers' +])dnl +AS_VAR_POPDEF([PKGCONFIG_suffix])dnl +AS_VAR_POPDEF([PKGCONFIG_libdir])dnl +AS_VAR_POPDEF([PKGCONFIG_libfile])dnl +AS_VAR_POPDEF([PKGCONFIG_libname])dnl +AS_VAR_POPDEF([PKGCONFIG_version])dnl +AS_VAR_POPDEF([PKGCONFIG_description])dnl +AS_VAR_POPDEF([PKGCONFIG_requires])dnl +AS_VAR_POPDEF([PKGCONFIG_pkglibs])dnl +AS_VAR_POPDEF([PKGCONFIG_libs])dnl +AS_VAR_POPDEF([PKGCONFIG_ldflags])dnl +AS_VAR_POPDEF([PKGCONFIG_cppflags])dnl +AS_VAR_POPDEF([PKGCONFIG_generate])dnl +AS_VAR_POPDEF([PKGCONFIG_src_libdir])dnl +AS_VAR_POPDEF([PKGCONFIG_src_headers])dnl +]) diff --git a/external/mit/isl/dist/m4/ax_create_stdint_h.m4 b/external/mit/isl/dist/m4/ax_create_stdint_h.m4 new file mode 100644 index 000000000000..44ec4c7f8ac0 --- /dev/null +++ b/external/mit/isl/dist/m4/ax_create_stdint_h.m4 @@ -0,0 +1,716 @@ +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_create_stdint_h.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_CREATE_STDINT_H [( HEADER-TO-GENERATE [, HEDERS-TO-CHECK])] +# +# DESCRIPTION +# +# the "ISO C9X: 7.18 Integer types " section requires the +# existence of an include file that defines a set of typedefs, +# especially uint8_t,int32_t,uintptr_t. Many older installations will not +# provide this file, but some will have the very same definitions in +# . In other environments we can use the inet-types in +# which would define the typedefs int8_t and u_int8_t +# respectively. +# +# This macros will create a local "_stdint.h" or the headerfile given as +# an argument. In many cases that file will just "#include " or +# "#include ", while in other environments it will provide the +# set of basic 'stdint's definitions/typedefs: +# +# int8_t,uint8_t,int16_t,uint16_t,int32_t,uint32_t,intptr_t,uintptr_t +# int_least32_t.. int_fast32_t.. intmax_t +# +# which may or may not rely on the definitions of other files, or using +# the AC_CHECK_SIZEOF macro to determine the actual sizeof each type. +# +# if your header files require the stdint-types you will want to create an +# installable file mylib-int.h that all your other installable header may +# include. So if you have a library package named "mylib", just use +# +# AX_CREATE_STDINT_H(mylib-int.h) +# +# in configure.ac and go to install that very header file in Makefile.am +# along with the other headers (mylib.h) - and the mylib-specific headers +# can simply use "#include " to obtain the stdint-types. +# +# Remember, if the system already had a valid , the generated +# file will include it directly. No need for fuzzy HAVE_STDINT_H things... +# (oops, GCC 4.2.x has deliberately disabled its stdint.h for non-c99 +# compilation and the c99-mode is not the default. Therefore this macro +# will not use the compiler's stdint.h - please complain to the GCC +# developers). +# +# LICENSE +# +# Copyright (c) 2008 Guido U. Draheim +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 21 + +AC_DEFUN([AX_CHECK_DATA_MODEL],[ + AC_CHECK_SIZEOF(char) + AC_CHECK_SIZEOF(short) + AC_CHECK_SIZEOF(int) + AC_CHECK_SIZEOF(long) + AC_CHECK_SIZEOF(void*) + ac_cv_char_data_model="" + ac_cv_char_data_model="$ac_cv_char_data_model$ac_cv_sizeof_char" + ac_cv_char_data_model="$ac_cv_char_data_model$ac_cv_sizeof_short" + ac_cv_char_data_model="$ac_cv_char_data_model$ac_cv_sizeof_int" + ac_cv_long_data_model="" + ac_cv_long_data_model="$ac_cv_long_data_model$ac_cv_sizeof_int" + ac_cv_long_data_model="$ac_cv_long_data_model$ac_cv_sizeof_long" + ac_cv_long_data_model="$ac_cv_long_data_model$ac_cv_sizeof_voidp" + AC_MSG_CHECKING([data model]) + case "$ac_cv_char_data_model/$ac_cv_long_data_model" in + 122/242) ac_cv_data_model="IP16" ; n="standard 16bit machine" ;; + 122/244) ac_cv_data_model="LP32" ; n="standard 32bit machine" ;; + 122/*) ac_cv_data_model="i16" ; n="unusual int16 model" ;; + 124/444) ac_cv_data_model="ILP32" ; n="standard 32bit unixish" ;; + 124/488) ac_cv_data_model="LP64" ; n="standard 64bit unixish" ;; + 124/448) ac_cv_data_model="LLP64" ; n="unusual 64bit unixish" ;; + 124/*) ac_cv_data_model="i32" ; n="unusual int32 model" ;; + 128/888) ac_cv_data_model="ILP64" ; n="unusual 64bit numeric" ;; + 128/*) ac_cv_data_model="i64" ; n="unusual int64 model" ;; + 222/*2) ac_cv_data_model="DSP16" ; n="strict 16bit dsptype" ;; + 333/*3) ac_cv_data_model="DSP24" ; n="strict 24bit dsptype" ;; + 444/*4) ac_cv_data_model="DSP32" ; n="strict 32bit dsptype" ;; + 666/*6) ac_cv_data_model="DSP48" ; n="strict 48bit dsptype" ;; + 888/*8) ac_cv_data_model="DSP64" ; n="strict 64bit dsptype" ;; + 222/*|333/*|444/*|666/*|888/*) : + ac_cv_data_model="iDSP" ; n="unusual dsptype" ;; + *) ac_cv_data_model="none" ; n="very unusual model" ;; + esac + AC_MSG_RESULT([$ac_cv_data_model ($ac_cv_long_data_model, $n)]) +]) + +dnl AX_CHECK_HEADER_STDINT_X([HEADERLIST][,ACTION-IF]) +AC_DEFUN([AX_CHECK_HEADER_STDINT_X],[ +AC_CACHE_CHECK([for stdint uintptr_t], [ac_cv_header_stdint_x],[ + ac_cv_header_stdint_x="" # the 1997 typedefs (inttypes.h) + AC_MSG_RESULT([(..)]) + for i in m4_ifval([$1],[$1],[stdint.h inttypes.h sys/inttypes.h sys/types.h]) + do + unset ac_cv_type_uintptr_t + unset ac_cv_type_uint64_t + AC_CHECK_TYPE(uintptr_t,[ac_cv_header_stdint_x=$i],continue,[#include <$i>]) + AC_CHECK_TYPE(uint64_t,[and64="/uint64_t"],[and64=""],[#include<$i>]) + m4_ifvaln([$2],[$2]) break + done + AC_MSG_CHECKING([for stdint uintptr_t]) + ]) +]) + +AC_DEFUN([AX_CHECK_HEADER_STDINT_O],[ +AC_CACHE_CHECK([for stdint uint32_t], [ac_cv_header_stdint_o],[ + ac_cv_header_stdint_o="" # the 1995 typedefs (sys/inttypes.h) + AC_MSG_RESULT([(..)]) + for i in m4_ifval([$1],[$1],[inttypes.h sys/inttypes.h sys/types.h stdint.h]) + do + unset ac_cv_type_uint32_t + unset ac_cv_type_uint64_t + AC_CHECK_TYPE(uint32_t,[ac_cv_header_stdint_o=$i],continue,[#include <$i>]) + AC_CHECK_TYPE(uint64_t,[and64="/uint64_t"],[and64=""],[#include<$i>]) + m4_ifvaln([$2],[$2]) break + break; + done + AC_MSG_CHECKING([for stdint uint32_t]) + ]) +]) + +AC_DEFUN([AX_CHECK_HEADER_STDINT_U],[ +AC_CACHE_CHECK([for stdint u_int32_t], [ac_cv_header_stdint_u],[ + ac_cv_header_stdint_u="" # the BSD typedefs (sys/types.h) + AC_MSG_RESULT([(..)]) + for i in m4_ifval([$1],[$1],[sys/types.h inttypes.h sys/inttypes.h]) ; do + unset ac_cv_type_u_int32_t + unset ac_cv_type_u_int64_t + AC_CHECK_TYPE(u_int32_t,[ac_cv_header_stdint_u=$i],continue,[#include <$i>]) + AC_CHECK_TYPE(u_int64_t,[and64="/u_int64_t"],[and64=""],[#include<$i>]) + m4_ifvaln([$2],[$2]) break + break; + done + AC_MSG_CHECKING([for stdint u_int32_t]) + ]) +]) + +AC_DEFUN([AX_CREATE_STDINT_H], +[# ------ AX CREATE STDINT H ------------------------------------- +AC_MSG_CHECKING([for stdint types]) +ac_stdint_h=`echo ifelse($1, , _stdint.h, $1)` +# try to shortcircuit - if the default include path of the compiler +# can find a "stdint.h" header then we assume that all compilers can. +AC_CACHE_VAL([ac_cv_header_stdint_t],[ +old_CXXFLAGS="$CXXFLAGS" ; CXXFLAGS="" +old_CPPFLAGS="$CPPFLAGS" ; CPPFLAGS="" +old_CFLAGS="$CFLAGS" ; CFLAGS="" +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], [[int_least32_t v = 0;]])], +[ac_cv_stdint_result="(assuming C99 compatible system)" + ac_cv_header_stdint_t="stdint.h";], + [ac_cv_header_stdint_t=""]) +if test "$GCC" = "yes" && test ".$ac_cv_header_stdint_t" = "."; then +CFLAGS="-std=c99" +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], [[int_least32_t v = 0;]])], +[AC_MSG_WARN(your GCC compiler has a defunct stdint.h for its default-mode)], []) +fi +CXXFLAGS="$old_CXXFLAGS" +CPPFLAGS="$old_CPPFLAGS" +CFLAGS="$old_CFLAGS" ]) + +v="... $ac_cv_header_stdint_h" +if test "$ac_stdint_h" = "stdint.h" ; then + AC_MSG_RESULT([(are you sure you want them in ./stdint.h?)]) +elif test "$ac_stdint_h" = "inttypes.h" ; then + AC_MSG_RESULT([(are you sure you want them in ./inttypes.h?)]) +elif test "_$ac_cv_header_stdint_t" = "_" ; then + AC_MSG_RESULT([(putting them into $ac_stdint_h)$v]) +else + ac_cv_header_stdint="$ac_cv_header_stdint_t" + AC_MSG_RESULT([$ac_cv_header_stdint (shortcircuit)]) +fi + +if test "_$ac_cv_header_stdint_t" = "_" ; then # cannot shortcircuit.. + +dnl .....intro message done, now do a few system checks..... +dnl btw, all old CHECK_TYPE macros do automatically "DEFINE" a type, +dnl therefore we use the autoconf implementation detail CHECK_TYPE_NEW +dnl instead that is triggered with 3 or more arguments (see types.m4) + +inttype_headers=`echo $2 | sed -e 's/,/ /g'` + +ac_cv_stdint_result="(no helpful system typedefs seen)" +AX_CHECK_HEADER_STDINT_X(dnl + stdint.h inttypes.h sys/inttypes.h $inttype_headers, + ac_cv_stdint_result="(seen uintptr_t$and64 in $i)") + +if test "_$ac_cv_header_stdint_x" = "_" ; then +AX_CHECK_HEADER_STDINT_O(dnl, + inttypes.h sys/inttypes.h stdint.h $inttype_headers, + ac_cv_stdint_result="(seen uint32_t$and64 in $i)") +fi + +if test "_$ac_cv_header_stdint_x" = "_" ; then +if test "_$ac_cv_header_stdint_o" = "_" ; then +AX_CHECK_HEADER_STDINT_U(dnl, + sys/types.h inttypes.h sys/inttypes.h $inttype_headers, + ac_cv_stdint_result="(seen u_int32_t$and64 in $i)") +fi fi + +dnl if there was no good C99 header file, do some typedef checks... +if test "_$ac_cv_header_stdint_x" = "_" ; then + AC_MSG_CHECKING([for stdint datatype model]) + AC_MSG_RESULT([(..)]) + AX_CHECK_DATA_MODEL +fi + +if test "_$ac_cv_header_stdint_x" != "_" ; then + ac_cv_header_stdint="$ac_cv_header_stdint_x" +elif test "_$ac_cv_header_stdint_o" != "_" ; then + ac_cv_header_stdint="$ac_cv_header_stdint_o" +elif test "_$ac_cv_header_stdint_u" != "_" ; then + ac_cv_header_stdint="$ac_cv_header_stdint_u" +else + ac_cv_header_stdint="stddef.h" +fi + +AC_MSG_CHECKING([for extra inttypes in chosen header]) +AC_MSG_RESULT([($ac_cv_header_stdint)]) +dnl see if int_least and int_fast types are present in _this_ header. +unset ac_cv_type_int_least32_t +unset ac_cv_type_int_fast32_t +AC_CHECK_TYPE(int_least32_t,,,[#include <$ac_cv_header_stdint>]) +AC_CHECK_TYPE(int_fast32_t,,,[#include<$ac_cv_header_stdint>]) +AC_CHECK_TYPE(intmax_t,,,[#include <$ac_cv_header_stdint>]) + +fi # shortcircuit to system "stdint.h" +# ------------------ PREPARE VARIABLES ------------------------------ +if test "$GCC" = "yes" ; then +ac_cv_stdint_message="using gnu compiler "`$CC --version | head -1` +else +ac_cv_stdint_message="using $CC" +fi + +AC_MSG_RESULT([make use of $ac_cv_header_stdint in $ac_stdint_h dnl +$ac_cv_stdint_result]) + +dnl ----------------------------------------------------------------- +# ----------------- DONE inttypes.h checks START header ------------- +AC_CONFIG_COMMANDS([$ac_stdint_h],[ +AC_MSG_NOTICE(creating $ac_stdint_h : $_ac_stdint_h) +ac_stdint=$tmp/_stdint.h + +echo "#ifndef" $_ac_stdint_h >$ac_stdint +echo "#define" $_ac_stdint_h "1" >>$ac_stdint +echo "#ifndef" _GENERATED_STDINT_H >>$ac_stdint +echo "#define" _GENERATED_STDINT_H '"'$PACKAGE $VERSION'"' >>$ac_stdint +echo "/* generated $ac_cv_stdint_message */" >>$ac_stdint +if test "_$ac_cv_header_stdint_t" != "_" ; then +echo "#define _STDINT_HAVE_STDINT_H" "1" >>$ac_stdint +echo "#include " >>$ac_stdint +echo "#endif" >>$ac_stdint +echo "#endif" >>$ac_stdint +else + +cat >>$ac_stdint < +#else +#include + +/* .................... configured part ............................ */ + +STDINT_EOF + +echo "/* whether we have a C99 compatible stdint header file */" >>$ac_stdint +if test "_$ac_cv_header_stdint_x" != "_" ; then + ac_header="$ac_cv_header_stdint_x" + echo "#define _STDINT_HEADER_INTPTR" '"'"$ac_header"'"' >>$ac_stdint +else + echo "/* #undef _STDINT_HEADER_INTPTR */" >>$ac_stdint +fi + +echo "/* whether we have a C96 compatible inttypes header file */" >>$ac_stdint +if test "_$ac_cv_header_stdint_o" != "_" ; then + ac_header="$ac_cv_header_stdint_o" + echo "#define _STDINT_HEADER_UINT32" '"'"$ac_header"'"' >>$ac_stdint +else + echo "/* #undef _STDINT_HEADER_UINT32 */" >>$ac_stdint +fi + +echo "/* whether we have a BSD compatible inet types header */" >>$ac_stdint +if test "_$ac_cv_header_stdint_u" != "_" ; then + ac_header="$ac_cv_header_stdint_u" + echo "#define _STDINT_HEADER_U_INT32" '"'"$ac_header"'"' >>$ac_stdint +else + echo "/* #undef _STDINT_HEADER_U_INT32 */" >>$ac_stdint +fi + +echo "" >>$ac_stdint + +if test "_$ac_header" != "_" ; then if test "$ac_header" != "stddef.h" ; then + echo "#include <$ac_header>" >>$ac_stdint + echo "" >>$ac_stdint +fi fi + +echo "/* which 64bit typedef has been found */" >>$ac_stdint +if test "$ac_cv_type_uint64_t" = "yes" ; then +echo "#define _STDINT_HAVE_UINT64_T" "1" >>$ac_stdint +else +echo "/* #undef _STDINT_HAVE_UINT64_T */" >>$ac_stdint +fi +if test "$ac_cv_type_u_int64_t" = "yes" ; then +echo "#define _STDINT_HAVE_U_INT64_T" "1" >>$ac_stdint +else +echo "/* #undef _STDINT_HAVE_U_INT64_T */" >>$ac_stdint +fi +echo "" >>$ac_stdint + +echo "/* which type model has been detected */" >>$ac_stdint +if test "_$ac_cv_char_data_model" != "_" ; then +echo "#define _STDINT_CHAR_MODEL" "$ac_cv_char_data_model" >>$ac_stdint +echo "#define _STDINT_LONG_MODEL" "$ac_cv_long_data_model" >>$ac_stdint +else +echo "/* #undef _STDINT_CHAR_MODEL // skipped */" >>$ac_stdint +echo "/* #undef _STDINT_LONG_MODEL // skipped */" >>$ac_stdint +fi +echo "" >>$ac_stdint + +echo "/* whether int_least types were detected */" >>$ac_stdint +if test "$ac_cv_type_int_least32_t" = "yes"; then +echo "#define _STDINT_HAVE_INT_LEAST32_T" "1" >>$ac_stdint +else +echo "/* #undef _STDINT_HAVE_INT_LEAST32_T */" >>$ac_stdint +fi +echo "/* whether int_fast types were detected */" >>$ac_stdint +if test "$ac_cv_type_int_fast32_t" = "yes"; then +echo "#define _STDINT_HAVE_INT_FAST32_T" "1" >>$ac_stdint +else +echo "/* #undef _STDINT_HAVE_INT_FAST32_T */" >>$ac_stdint +fi +echo "/* whether intmax_t type was detected */" >>$ac_stdint +if test "$ac_cv_type_intmax_t" = "yes"; then +echo "#define _STDINT_HAVE_INTMAX_T" "1" >>$ac_stdint +else +echo "/* #undef _STDINT_HAVE_INTMAX_T */" >>$ac_stdint +fi +echo "" >>$ac_stdint + + cat >>$ac_stdint <= 199901L +#define _HAVE_UINT64_T +#define _HAVE_LONGLONG_UINT64_T +typedef long long int64_t; +typedef unsigned long long uint64_t; + +#elif !defined __STRICT_ANSI__ +#if defined _MSC_VER || defined __WATCOMC__ || defined __BORLANDC__ +#define _HAVE_UINT64_T +typedef __int64 int64_t; +typedef unsigned __int64 uint64_t; + +#elif defined __GNUC__ || defined __MWERKS__ || defined __ELF__ +/* note: all ELF-systems seem to have loff-support which needs 64-bit */ +#if !defined _NO_LONGLONG +#define _HAVE_UINT64_T +#define _HAVE_LONGLONG_UINT64_T +typedef long long int64_t; +typedef unsigned long long uint64_t; +#endif + +#elif defined __alpha || (defined __mips && defined _ABIN32) +#if !defined _NO_LONGLONG +typedef long int64_t; +typedef unsigned long uint64_t; +#endif + /* compiler/cpu type to define int64_t */ +#endif +#endif +#endif + +#if defined _STDINT_HAVE_U_INT_TYPES +/* int8_t int16_t int32_t defined by inet code, redeclare the u_intXX types */ +typedef u_int8_t uint8_t; +typedef u_int16_t uint16_t; +typedef u_int32_t uint32_t; + +/* glibc compatibility */ +#ifndef __int8_t_defined +#define __int8_t_defined +#endif +#endif + +#ifdef _STDINT_NEED_INT_MODEL_T +/* we must guess all the basic types. Apart from byte-addressable system, */ +/* there a few 32-bit-only dsp-systems that we guard with BYTE_MODEL 8-} */ +/* (btw, those nibble-addressable systems are way off, or so we assume) */ + +dnl /* have a look at "64bit and data size neutrality" at */ +dnl /* http://unix.org/version2/whatsnew/login_64bit.html */ +dnl /* (the shorthand "ILP" types always have a "P" part) */ + +#if defined _STDINT_BYTE_MODEL +#if _STDINT_LONG_MODEL+0 == 242 +/* 2:4:2 = IP16 = a normal 16-bit system */ +typedef unsigned char uint8_t; +typedef unsigned short uint16_t; +typedef unsigned long uint32_t; +#ifndef __int8_t_defined +#define __int8_t_defined +typedef char int8_t; +typedef short int16_t; +typedef long int32_t; +#endif +#elif _STDINT_LONG_MODEL+0 == 244 || _STDINT_LONG_MODEL == 444 +/* 2:4:4 = LP32 = a 32-bit system derived from a 16-bit */ +/* 4:4:4 = ILP32 = a normal 32-bit system */ +typedef unsigned char uint8_t; +typedef unsigned short uint16_t; +typedef unsigned int uint32_t; +#ifndef __int8_t_defined +#define __int8_t_defined +typedef char int8_t; +typedef short int16_t; +typedef int int32_t; +#endif +#elif _STDINT_LONG_MODEL+0 == 484 || _STDINT_LONG_MODEL+0 == 488 +/* 4:8:4 = IP32 = a 32-bit system prepared for 64-bit */ +/* 4:8:8 = LP64 = a normal 64-bit system */ +typedef unsigned char uint8_t; +typedef unsigned short uint16_t; +typedef unsigned int uint32_t; +#ifndef __int8_t_defined +#define __int8_t_defined +typedef char int8_t; +typedef short int16_t; +typedef int int32_t; +#endif +/* this system has a "long" of 64bit */ +#ifndef _HAVE_UINT64_T +#define _HAVE_UINT64_T +typedef unsigned long uint64_t; +typedef long int64_t; +#endif +#elif _STDINT_LONG_MODEL+0 == 448 +/* LLP64 a 64-bit system derived from a 32-bit system */ +typedef unsigned char uint8_t; +typedef unsigned short uint16_t; +typedef unsigned int uint32_t; +#ifndef __int8_t_defined +#define __int8_t_defined +typedef char int8_t; +typedef short int16_t; +typedef int int32_t; +#endif +/* assuming the system has a "long long" */ +#ifndef _HAVE_UINT64_T +#define _HAVE_UINT64_T +#define _HAVE_LONGLONG_UINT64_T +typedef unsigned long long uint64_t; +typedef long long int64_t; +#endif +#else +#define _STDINT_NO_INT32_T +#endif +#else +#define _STDINT_NO_INT8_T +#define _STDINT_NO_INT32_T +#endif +#endif + +/* + * quote from SunOS-5.8 sys/inttypes.h: + * Use at your own risk. As of February 1996, the committee is squarely + * behind the fixed sized types; the "least" and "fast" types are still being + * discussed. The probability that the "fast" types may be removed before + * the standard is finalized is high enough that they are not currently + * implemented. + */ + +#if defined _STDINT_NEED_INT_LEAST_T +typedef int8_t int_least8_t; +typedef int16_t int_least16_t; +typedef int32_t int_least32_t; +#ifdef _HAVE_UINT64_T +typedef int64_t int_least64_t; +#endif + +typedef uint8_t uint_least8_t; +typedef uint16_t uint_least16_t; +typedef uint32_t uint_least32_t; +#ifdef _HAVE_UINT64_T +typedef uint64_t uint_least64_t; +#endif + /* least types */ +#endif + +#if defined _STDINT_NEED_INT_FAST_T +typedef int8_t int_fast8_t; +typedef int int_fast16_t; +typedef int32_t int_fast32_t; +#ifdef _HAVE_UINT64_T +typedef int64_t int_fast64_t; +#endif + +typedef uint8_t uint_fast8_t; +typedef unsigned uint_fast16_t; +typedef uint32_t uint_fast32_t; +#ifdef _HAVE_UINT64_T +typedef uint64_t uint_fast64_t; +#endif + /* fast types */ +#endif + +#ifdef _STDINT_NEED_INTMAX_T +#ifdef _HAVE_UINT64_T +typedef int64_t intmax_t; +typedef uint64_t uintmax_t; +#else +typedef long intmax_t; +typedef unsigned long uintmax_t; +#endif +#endif + +#ifdef _STDINT_NEED_INTPTR_T +#ifndef __intptr_t_defined +#define __intptr_t_defined +/* we encourage using "long" to store pointer values, never use "int" ! */ +#if _STDINT_LONG_MODEL+0 == 242 || _STDINT_LONG_MODEL+0 == 484 +typedef unsigned int uintptr_t; +typedef int intptr_t; +#elif _STDINT_LONG_MODEL+0 == 244 || _STDINT_LONG_MODEL+0 == 444 +typedef unsigned long uintptr_t; +typedef long intptr_t; +#elif _STDINT_LONG_MODEL+0 == 448 && defined _HAVE_UINT64_T +typedef uint64_t uintptr_t; +typedef int64_t intptr_t; +#else /* matches typical system types ILP32 and LP64 - but not IP16 or LLP64 */ +typedef unsigned long uintptr_t; +typedef long intptr_t; +#endif +#endif +#endif + +/* The ISO C99 standard specifies that in C++ implementations these + should only be defined if explicitly requested. */ +#if !defined __cplusplus || defined __STDC_CONSTANT_MACROS +#ifndef UINT32_C + +/* Signed. */ +# define INT8_C(c) c +# define INT16_C(c) c +# define INT32_C(c) c +# ifdef _HAVE_LONGLONG_UINT64_T +# define INT64_C(c) c ## L +# else +# define INT64_C(c) c ## LL +# endif + +/* Unsigned. */ +# define UINT8_C(c) c ## U +# define UINT16_C(c) c ## U +# define UINT32_C(c) c ## U +# ifdef _HAVE_LONGLONG_UINT64_T +# define UINT64_C(c) c ## UL +# else +# define UINT64_C(c) c ## ULL +# endif + +/* Maximal type. */ +# ifdef _HAVE_LONGLONG_UINT64_T +# define INTMAX_C(c) c ## L +# define UINTMAX_C(c) c ## UL +# else +# define INTMAX_C(c) c ## LL +# define UINTMAX_C(c) c ## ULL +# endif + + /* literalnumbers */ +#endif +#endif + +/* These limits are merrily those of a two complement byte-oriented system */ + +/* Minimum of signed integral types. */ +# define INT8_MIN (-128) +# define INT16_MIN (-32767-1) +# define INT32_MIN (-2147483647-1) +#ifndef INT64_MIN +# define INT64_MIN (-__INT64_C(9223372036854775807)-1) +#endif +/* Maximum of signed integral types. */ +# define INT8_MAX (127) +# define INT16_MAX (32767) +# define INT32_MAX (2147483647) +#ifndef INT64_MAX +# define INT64_MAX (__INT64_C(9223372036854775807)) +#endif + +/* Maximum of unsigned integral types. */ +#ifndef UINT8_MAX +# define UINT8_MAX (255) +#endif +#ifndef UINT16_MAX +# define UINT16_MAX (65535) +#endif +# define UINT32_MAX (4294967295U) +#ifndef UINT64_MAX +# define UINT64_MAX (__UINT64_C(18446744073709551615)) +#endif + +/* Minimum of signed integral types having a minimum size. */ +# define INT_LEAST8_MIN INT8_MIN +# define INT_LEAST16_MIN INT16_MIN +# define INT_LEAST32_MIN INT32_MIN +# define INT_LEAST64_MIN INT64_MIN +/* Maximum of signed integral types having a minimum size. */ +# define INT_LEAST8_MAX INT8_MAX +# define INT_LEAST16_MAX INT16_MAX +# define INT_LEAST32_MAX INT32_MAX +# define INT_LEAST64_MAX INT64_MAX + +/* Maximum of unsigned integral types having a minimum size. */ +# define UINT_LEAST8_MAX UINT8_MAX +# define UINT_LEAST16_MAX UINT16_MAX +# define UINT_LEAST32_MAX UINT32_MAX +# define UINT_LEAST64_MAX UINT64_MAX + + /* shortcircuit*/ +#endif + /* once */ +#endif +#endif +STDINT_EOF +fi + if cmp -s $ac_stdint_h $ac_stdint 2>/dev/null; then + AC_MSG_NOTICE([$ac_stdint_h is unchanged]) + else + ac_dir=`AS_DIRNAME(["$ac_stdint_h"])` + AS_MKDIR_P(["$ac_dir"]) + rm -f $ac_stdint_h + mv $ac_stdint $ac_stdint_h + fi +],[# variables for create stdint.h replacement +PACKAGE="$PACKAGE" +VERSION="$VERSION" +ac_stdint_h="$ac_stdint_h" +_ac_stdint_h=AS_TR_CPP(_$PACKAGE-$ac_stdint_h) +ac_cv_stdint_message="$ac_cv_stdint_message" +ac_cv_header_stdint_t="$ac_cv_header_stdint_t" +ac_cv_header_stdint_x="$ac_cv_header_stdint_x" +ac_cv_header_stdint_o="$ac_cv_header_stdint_o" +ac_cv_header_stdint_u="$ac_cv_header_stdint_u" +ac_cv_type_uint64_t="$ac_cv_type_uint64_t" +ac_cv_type_u_int64_t="$ac_cv_type_u_int64_t" +ac_cv_char_data_model="$ac_cv_char_data_model" +ac_cv_long_data_model="$ac_cv_long_data_model" +ac_cv_type_int_least32_t="$ac_cv_type_int_least32_t" +ac_cv_type_int_fast32_t="$ac_cv_type_int_fast32_t" +ac_cv_type_intmax_t="$ac_cv_type_intmax_t" +]) +]) diff --git a/external/mit/isl/dist/m4/ax_cxx_compile_stdcxx.m4 b/external/mit/isl/dist/m4/ax_cxx_compile_stdcxx.m4 new file mode 100644 index 000000000000..9413da624d25 --- /dev/null +++ b/external/mit/isl/dist/m4/ax_cxx_compile_stdcxx.m4 @@ -0,0 +1,962 @@ +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_CXX_COMPILE_STDCXX(VERSION, [ext|noext], [mandatory|optional]) +# +# DESCRIPTION +# +# Check for baseline language coverage in the compiler for the specified +# version of the C++ standard. If necessary, add switches to CXX and +# CXXCPP to enable support. VERSION may be '11' (for the C++11 standard) +# or '14' (for the C++14 standard). +# +# The second argument, if specified, indicates whether you insist on an +# extended mode (e.g. -std=gnu++11) or a strict conformance mode (e.g. +# -std=c++11). If neither is specified, you get whatever works, with +# preference for no added switch, and then for an extended mode. +# +# The third argument, if specified 'mandatory' or if left unspecified, +# indicates that baseline support for the specified C++ standard is +# required and that the macro should error out if no mode with that +# support is found. If specified 'optional', then configuration proceeds +# regardless, after defining HAVE_CXX${VERSION} if and only if a +# supporting mode is found. +# +# LICENSE +# +# Copyright (c) 2008 Benjamin Kosnik +# Copyright (c) 2012 Zack Weinberg +# Copyright (c) 2013 Roy Stogner +# Copyright (c) 2014, 2015 Google Inc.; contributed by Alexey Sokolov +# Copyright (c) 2015 Paul Norman +# Copyright (c) 2015 Moritz Klammler +# Copyright (c) 2016, 2018 Krzesimir Nowak +# Copyright (c) 2019 Enji Cooper +# Copyright (c) 2020 Jason Merrill +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 12 + +dnl This macro is based on the code from the AX_CXX_COMPILE_STDCXX_11 macro +dnl (serial version number 13). + +AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl + m4_if([$1], [11], [ax_cxx_compile_alternatives="11 0x"], + [$1], [14], [ax_cxx_compile_alternatives="14 1y"], + [$1], [17], [ax_cxx_compile_alternatives="17 1z"], + [m4_fatal([invalid first argument `$1' to AX_CXX_COMPILE_STDCXX])])dnl + m4_if([$2], [], [], + [$2], [ext], [], + [$2], [noext], [], + [m4_fatal([invalid second argument `$2' to AX_CXX_COMPILE_STDCXX])])dnl + m4_if([$3], [], [ax_cxx_compile_cxx$1_required=true], + [$3], [mandatory], [ax_cxx_compile_cxx$1_required=true], + [$3], [optional], [ax_cxx_compile_cxx$1_required=false], + [m4_fatal([invalid third argument `$3' to AX_CXX_COMPILE_STDCXX])]) + AC_LANG_PUSH([C++])dnl + ac_success=no + + m4_if([$2], [], [dnl + AC_CACHE_CHECK(whether $CXX supports C++$1 features by default, + ax_cv_cxx_compile_cxx$1, + [AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], + [ax_cv_cxx_compile_cxx$1=yes], + [ax_cv_cxx_compile_cxx$1=no])]) + if test x$ax_cv_cxx_compile_cxx$1 = xyes; then + ac_success=yes + fi]) + + m4_if([$2], [noext], [], [dnl + if test x$ac_success = xno; then + for alternative in ${ax_cxx_compile_alternatives}; do + switch="-std=gnu++${alternative}" + cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch]) + AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch, + $cachevar, + [ac_save_CXX="$CXX" + CXX="$CXX $switch" + AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], + [eval $cachevar=yes], + [eval $cachevar=no]) + CXX="$ac_save_CXX"]) + if eval test x\$$cachevar = xyes; then + CXX="$CXX $switch" + if test -n "$CXXCPP" ; then + CXXCPP="$CXXCPP $switch" + fi + ac_success=yes + break + fi + done + fi]) + + m4_if([$2], [ext], [], [dnl + if test x$ac_success = xno; then + dnl HP's aCC needs +std=c++11 according to: + dnl http://h21007.www2.hp.com/portal/download/files/unprot/aCxx/PDF_Release_Notes/769149-001.pdf + dnl Cray's crayCC needs "-h std=c++11" + for alternative in ${ax_cxx_compile_alternatives}; do + for switch in -std=c++${alternative} +std=c++${alternative} "-h std=c++${alternative}"; do + cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch]) + AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch, + $cachevar, + [ac_save_CXX="$CXX" + CXX="$CXX $switch" + AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], + [eval $cachevar=yes], + [eval $cachevar=no]) + CXX="$ac_save_CXX"]) + if eval test x\$$cachevar = xyes; then + CXX="$CXX $switch" + if test -n "$CXXCPP" ; then + CXXCPP="$CXXCPP $switch" + fi + ac_success=yes + break + fi + done + if test x$ac_success = xyes; then + break + fi + done + fi]) + AC_LANG_POP([C++]) + if test x$ax_cxx_compile_cxx$1_required = xtrue; then + if test x$ac_success = xno; then + AC_MSG_ERROR([*** A compiler with support for C++$1 language features is required.]) + fi + fi + if test x$ac_success = xno; then + HAVE_CXX$1=0 + AC_MSG_NOTICE([No compiler with C++$1 support was found]) + else + HAVE_CXX$1=1 + AC_DEFINE(HAVE_CXX$1,1, + [define if the compiler supports basic C++$1 syntax]) + fi + AC_SUBST(HAVE_CXX$1) +]) + + +dnl Test body for checking C++11 support + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_11], + _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 +) + + +dnl Test body for checking C++14 support + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_14], + _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 + _AX_CXX_COMPILE_STDCXX_testbody_new_in_14 +) + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_17], + _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 + _AX_CXX_COMPILE_STDCXX_testbody_new_in_14 + _AX_CXX_COMPILE_STDCXX_testbody_new_in_17 +) + +dnl Tests for new features in C++11 + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_11], [[ + +// If the compiler admits that it is not ready for C++11, why torture it? +// Hopefully, this will speed up the test. + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 201103L + +#error "This is not a C++11 compiler" + +#else + +namespace cxx11 +{ + + namespace test_static_assert + { + + template + struct check + { + static_assert(sizeof(int) <= sizeof(T), "not big enough"); + }; + + } + + namespace test_final_override + { + + struct Base + { + virtual ~Base() {} + virtual void f() {} + }; + + struct Derived : public Base + { + virtual ~Derived() override {} + virtual void f() override {} + }; + + } + + namespace test_double_right_angle_brackets + { + + template < typename T > + struct check {}; + + typedef check single_type; + typedef check> double_type; + typedef check>> triple_type; + typedef check>>> quadruple_type; + + } + + namespace test_decltype + { + + int + f() + { + int a = 1; + decltype(a) b = 2; + return a + b; + } + + } + + namespace test_type_deduction + { + + template < typename T1, typename T2 > + struct is_same + { + static const bool value = false; + }; + + template < typename T > + struct is_same + { + static const bool value = true; + }; + + template < typename T1, typename T2 > + auto + add(T1 a1, T2 a2) -> decltype(a1 + a2) + { + return a1 + a2; + } + + int + test(const int c, volatile int v) + { + static_assert(is_same::value == true, ""); + static_assert(is_same::value == false, ""); + static_assert(is_same::value == false, ""); + auto ac = c; + auto av = v; + auto sumi = ac + av + 'x'; + auto sumf = ac + av + 1.0; + static_assert(is_same::value == true, ""); + static_assert(is_same::value == true, ""); + static_assert(is_same::value == true, ""); + static_assert(is_same::value == false, ""); + static_assert(is_same::value == true, ""); + return (sumf > 0.0) ? sumi : add(c, v); + } + + } + + namespace test_noexcept + { + + int f() { return 0; } + int g() noexcept { return 0; } + + static_assert(noexcept(f()) == false, ""); + static_assert(noexcept(g()) == true, ""); + + } + + namespace test_constexpr + { + + template < typename CharT > + unsigned long constexpr + strlen_c_r(const CharT *const s, const unsigned long acc) noexcept + { + return *s ? strlen_c_r(s + 1, acc + 1) : acc; + } + + template < typename CharT > + unsigned long constexpr + strlen_c(const CharT *const s) noexcept + { + return strlen_c_r(s, 0UL); + } + + static_assert(strlen_c("") == 0UL, ""); + static_assert(strlen_c("1") == 1UL, ""); + static_assert(strlen_c("example") == 7UL, ""); + static_assert(strlen_c("another\0example") == 7UL, ""); + + } + + namespace test_rvalue_references + { + + template < int N > + struct answer + { + static constexpr int value = N; + }; + + answer<1> f(int&) { return answer<1>(); } + answer<2> f(const int&) { return answer<2>(); } + answer<3> f(int&&) { return answer<3>(); } + + void + test() + { + int i = 0; + const int c = 0; + static_assert(decltype(f(i))::value == 1, ""); + static_assert(decltype(f(c))::value == 2, ""); + static_assert(decltype(f(0))::value == 3, ""); + } + + } + + namespace test_uniform_initialization + { + + struct test + { + static const int zero {}; + static const int one {1}; + }; + + static_assert(test::zero == 0, ""); + static_assert(test::one == 1, ""); + + } + + namespace test_lambdas + { + + void + test1() + { + auto lambda1 = [](){}; + auto lambda2 = lambda1; + lambda1(); + lambda2(); + } + + int + test2() + { + auto a = [](int i, int j){ return i + j; }(1, 2); + auto b = []() -> int { return '0'; }(); + auto c = [=](){ return a + b; }(); + auto d = [&](){ return c; }(); + auto e = [a, &b](int x) mutable { + const auto identity = [](int y){ return y; }; + for (auto i = 0; i < a; ++i) + a += b--; + return x + identity(a + b); + }(0); + return a + b + c + d + e; + } + + int + test3() + { + const auto nullary = [](){ return 0; }; + const auto unary = [](int x){ return x; }; + using nullary_t = decltype(nullary); + using unary_t = decltype(unary); + const auto higher1st = [](nullary_t f){ return f(); }; + const auto higher2nd = [unary](nullary_t f1){ + return [unary, f1](unary_t f2){ return f2(unary(f1())); }; + }; + return higher1st(nullary) + higher2nd(nullary)(unary); + } + + } + + namespace test_variadic_templates + { + + template + struct sum; + + template + struct sum + { + static constexpr auto value = N0 + sum::value; + }; + + template <> + struct sum<> + { + static constexpr auto value = 0; + }; + + static_assert(sum<>::value == 0, ""); + static_assert(sum<1>::value == 1, ""); + static_assert(sum<23>::value == 23, ""); + static_assert(sum<1, 2>::value == 3, ""); + static_assert(sum<5, 5, 11>::value == 21, ""); + static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, ""); + + } + + // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae + // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function + // because of this. + namespace test_template_alias_sfinae + { + + struct foo {}; + + template + using member = typename T::member_type; + + template + void func(...) {} + + template + void func(member*) {} + + void test(); + + void test() { func(0); } + + } + +} // namespace cxx11 + +#endif // __cplusplus >= 201103L + +]]) + + +dnl Tests for new features in C++14 + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_14], [[ + +// If the compiler admits that it is not ready for C++14, why torture it? +// Hopefully, this will speed up the test. + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 201402L + +#error "This is not a C++14 compiler" + +#else + +namespace cxx14 +{ + + namespace test_polymorphic_lambdas + { + + int + test() + { + const auto lambda = [](auto&&... args){ + const auto istiny = [](auto x){ + return (sizeof(x) == 1UL) ? 1 : 0; + }; + const int aretiny[] = { istiny(args)... }; + return aretiny[0]; + }; + return lambda(1, 1L, 1.0f, '1'); + } + + } + + namespace test_binary_literals + { + + constexpr auto ivii = 0b0000000000101010; + static_assert(ivii == 42, "wrong value"); + + } + + namespace test_generalized_constexpr + { + + template < typename CharT > + constexpr unsigned long + strlen_c(const CharT *const s) noexcept + { + auto length = 0UL; + for (auto p = s; *p; ++p) + ++length; + return length; + } + + static_assert(strlen_c("") == 0UL, ""); + static_assert(strlen_c("x") == 1UL, ""); + static_assert(strlen_c("test") == 4UL, ""); + static_assert(strlen_c("another\0test") == 7UL, ""); + + } + + namespace test_lambda_init_capture + { + + int + test() + { + auto x = 0; + const auto lambda1 = [a = x](int b){ return a + b; }; + const auto lambda2 = [a = lambda1(x)](){ return a; }; + return lambda2(); + } + + } + + namespace test_digit_separators + { + + constexpr auto ten_million = 100'000'000; + static_assert(ten_million == 100000000, ""); + + } + + namespace test_return_type_deduction + { + + auto f(int& x) { return x; } + decltype(auto) g(int& x) { return x; } + + template < typename T1, typename T2 > + struct is_same + { + static constexpr auto value = false; + }; + + template < typename T > + struct is_same + { + static constexpr auto value = true; + }; + + int + test() + { + auto x = 0; + static_assert(is_same::value, ""); + static_assert(is_same::value, ""); + return x; + } + + } + +} // namespace cxx14 + +#endif // __cplusplus >= 201402L + +]]) + + +dnl Tests for new features in C++17 + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_17], [[ + +// If the compiler admits that it is not ready for C++17, why torture it? +// Hopefully, this will speed up the test. + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 201703L + +#error "This is not a C++17 compiler" + +#else + +#include +#include +#include + +namespace cxx17 +{ + + namespace test_constexpr_lambdas + { + + constexpr int foo = [](){return 42;}(); + + } + + namespace test::nested_namespace::definitions + { + + } + + namespace test_fold_expression + { + + template + int multiply(Args... args) + { + return (args * ... * 1); + } + + template + bool all(Args... args) + { + return (args && ...); + } + + } + + namespace test_extended_static_assert + { + + static_assert (true); + + } + + namespace test_auto_brace_init_list + { + + auto foo = {5}; + auto bar {5}; + + static_assert(std::is_same, decltype(foo)>::value); + static_assert(std::is_same::value); + } + + namespace test_typename_in_template_template_parameter + { + + template typename X> struct D; + + } + + namespace test_fallthrough_nodiscard_maybe_unused_attributes + { + + int f1() + { + return 42; + } + + [[nodiscard]] int f2() + { + [[maybe_unused]] auto unused = f1(); + + switch (f1()) + { + case 17: + f1(); + [[fallthrough]]; + case 42: + f1(); + } + return f1(); + } + + } + + namespace test_extended_aggregate_initialization + { + + struct base1 + { + int b1, b2 = 42; + }; + + struct base2 + { + base2() { + b3 = 42; + } + int b3; + }; + + struct derived : base1, base2 + { + int d; + }; + + derived d1 {{1, 2}, {}, 4}; // full initialization + derived d2 {{}, {}, 4}; // value-initialized bases + + } + + namespace test_general_range_based_for_loop + { + + struct iter + { + int i; + + int& operator* () + { + return i; + } + + const int& operator* () const + { + return i; + } + + iter& operator++() + { + ++i; + return *this; + } + }; + + struct sentinel + { + int i; + }; + + bool operator== (const iter& i, const sentinel& s) + { + return i.i == s.i; + } + + bool operator!= (const iter& i, const sentinel& s) + { + return !(i == s); + } + + struct range + { + iter begin() const + { + return {0}; + } + + sentinel end() const + { + return {5}; + } + }; + + void f() + { + range r {}; + + for (auto i : r) + { + [[maybe_unused]] auto v = i; + } + } + + } + + namespace test_lambda_capture_asterisk_this_by_value + { + + struct t + { + int i; + int foo() + { + return [*this]() + { + return i; + }(); + } + }; + + } + + namespace test_enum_class_construction + { + + enum class byte : unsigned char + {}; + + byte foo {42}; + + } + + namespace test_constexpr_if + { + + template + int f () + { + if constexpr(cond) + { + return 13; + } + else + { + return 42; + } + } + + } + + namespace test_selection_statement_with_initializer + { + + int f() + { + return 13; + } + + int f2() + { + if (auto i = f(); i > 0) + { + return 3; + } + + switch (auto i = f(); i + 4) + { + case 17: + return 2; + + default: + return 1; + } + } + + } + + namespace test_template_argument_deduction_for_class_templates + { + + template + struct pair + { + pair (T1 p1, T2 p2) + : m1 {p1}, + m2 {p2} + {} + + T1 m1; + T2 m2; + }; + + void f() + { + [[maybe_unused]] auto p = pair{13, 42u}; + } + + } + + namespace test_non_type_auto_template_parameters + { + + template + struct B + {}; + + B<5> b1; + B<'a'> b2; + + } + + namespace test_structured_bindings + { + + int arr[2] = { 1, 2 }; + std::pair pr = { 1, 2 }; + + auto f1() -> int(&)[2] + { + return arr; + } + + auto f2() -> std::pair& + { + return pr; + } + + struct S + { + int x1 : 2; + volatile double y1; + }; + + S f3() + { + return {}; + } + + auto [ x1, y1 ] = f1(); + auto& [ xr1, yr1 ] = f1(); + auto [ x2, y2 ] = f2(); + auto& [ xr2, yr2 ] = f2(); + const auto [ x3, y3 ] = f3(); + + } + + namespace test_exception_spec_type_system + { + + struct Good {}; + struct Bad {}; + + void g1() noexcept; + void g2(); + + template + Bad + f(T*, T*); + + template + Good + f(T1*, T2*); + + static_assert (std::is_same_v); + + } + + namespace test_inline_variables + { + + template void f(T) + {} + + template inline T g(T) + { + return T{}; + } + + template<> inline void f<>(int) + {} + + template<> int g<>(int) + { + return 5; + } + + } + +} // namespace cxx17 + +#endif // __cplusplus < 201703L + +]]) diff --git a/external/mit/isl/dist/m4/ax_cxx_compile_stdcxx_11.m4 b/external/mit/isl/dist/m4/ax_cxx_compile_stdcxx_11.m4 new file mode 100644 index 000000000000..0aadeafe78eb --- /dev/null +++ b/external/mit/isl/dist/m4/ax_cxx_compile_stdcxx_11.m4 @@ -0,0 +1,39 @@ +# ============================================================================ +# http://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx_11.html +# ============================================================================ +# +# SYNOPSIS +# +# AX_CXX_COMPILE_STDCXX_11([ext|noext], [mandatory|optional]) +# +# DESCRIPTION +# +# Check for baseline language coverage in the compiler for the C++11 +# standard; if necessary, add switches to CXX and CXXCPP to enable +# support. +# +# This macro is a convenience alias for calling the AX_CXX_COMPILE_STDCXX +# macro with the version set to C++11. The two optional arguments are +# forwarded literally as the second and third argument respectively. +# Please see the documentation for the AX_CXX_COMPILE_STDCXX macro for +# more information. If you want to use this macro, you also need to +# download the ax_cxx_compile_stdcxx.m4 file. +# +# LICENSE +# +# Copyright (c) 2008 Benjamin Kosnik +# Copyright (c) 2012 Zack Weinberg +# Copyright (c) 2013 Roy Stogner +# Copyright (c) 2014, 2015 Google Inc.; contributed by Alexey Sokolov +# Copyright (c) 2015 Paul Norman +# Copyright (c) 2015 Moritz Klammler +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 17 + +AX_REQUIRE_DEFINED([AX_CXX_COMPILE_STDCXX]) +AC_DEFUN([AX_CXX_COMPILE_STDCXX_11], [AX_CXX_COMPILE_STDCXX([11], [$1], [$2])]) diff --git a/external/mit/isl/dist/m4/ax_cxx_compile_stdcxx_11_no_override.m4 b/external/mit/isl/dist/m4/ax_cxx_compile_stdcxx_11_no_override.m4 new file mode 100644 index 000000000000..d8235f735841 --- /dev/null +++ b/external/mit/isl/dist/m4/ax_cxx_compile_stdcxx_11_no_override.m4 @@ -0,0 +1,37 @@ +# Check if $CXX does or can be made to support C++11 by adding switches. +# If $CXX explicitly selects a language standard, then +# refrain from overriding this choice. +AC_DEFUN([AX_CXX_COMPILE_STDCXX_11_NO_OVERRIDE], [dnl + AC_PROG_GREP + echo $CXX | $GREP -e "-std=" > /dev/null 2> /dev/null + if test $? -eq 0; then + _AX_CXX_COMPILE_STDCXX_11_DEFAULT + else + AX_CXX_COMPILE_STDCXX_11([noext], [optional]) + fi +]) + +# Check if $CXX supports C++11 by default (without adding switches). +# This is a trimmed down version of AX_CXX_COMPILE_STDCXX_11 +# that reuses its _AX_CXX_COMPILE_STDCXX_testbody_11. +AC_DEFUN([_AX_CXX_COMPILE_STDCXX_11_DEFAULT], [dnl + AC_LANG_PUSH([C++])dnl + ac_success=no + AC_CACHE_CHECK(whether $CXX supports C++11 features by default, + ax_cv_cxx_compile_cxx11, + [AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_11])], + [ax_cv_cxx_compile_cxx11=yes], + [ax_cv_cxx_compile_cxx11=no])]) + if test x$ax_cv_cxx_compile_cxx11 = xyes; then + ac_success=yes + fi + AC_LANG_POP([C++]) + if test x$ac_success = xno; then + HAVE_CXX11=0 + else + HAVE_CXX11=1 + AC_DEFINE(HAVE_CXX11,1, + [define if the compiler supports basic C++11 syntax]) + fi + AC_SUBST(HAVE_CXX11) +]) diff --git a/external/mit/isl/dist/m4/ax_cxx_compile_stdcxx_17.m4 b/external/mit/isl/dist/m4/ax_cxx_compile_stdcxx_17.m4 new file mode 100644 index 000000000000..a6834171739b --- /dev/null +++ b/external/mit/isl/dist/m4/ax_cxx_compile_stdcxx_17.m4 @@ -0,0 +1,35 @@ +# ============================================================================= +# https://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx_17.html +# ============================================================================= +# +# SYNOPSIS +# +# AX_CXX_COMPILE_STDCXX_17([ext|noext], [mandatory|optional]) +# +# DESCRIPTION +# +# Check for baseline language coverage in the compiler for the C++17 +# standard; if necessary, add switches to CXX and CXXCPP to enable +# support. +# +# This macro is a convenience alias for calling the AX_CXX_COMPILE_STDCXX +# macro with the version set to C++17. The two optional arguments are +# forwarded literally as the second and third argument respectively. +# Please see the documentation for the AX_CXX_COMPILE_STDCXX macro for +# more information. If you want to use this macro, you also need to +# download the ax_cxx_compile_stdcxx.m4 file. +# +# LICENSE +# +# Copyright (c) 2015 Moritz Klammler +# Copyright (c) 2016 Krzesimir Nowak +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 2 + +AX_REQUIRE_DEFINED([AX_CXX_COMPILE_STDCXX]) +AC_DEFUN([AX_CXX_COMPILE_STDCXX_17], [AX_CXX_COMPILE_STDCXX([17], [$1], [$2])]) diff --git a/external/mit/isl/dist/m4/ax_detect_clang.m4 b/external/mit/isl/dist/m4/ax_detect_clang.m4 new file mode 100644 index 000000000000..58af01723a6b --- /dev/null +++ b/external/mit/isl/dist/m4/ax_detect_clang.m4 @@ -0,0 +1,288 @@ +AC_DEFUN([AX_DETECT_CLANG], [ +AC_SUBST(CLANG_CXXFLAGS) +AC_SUBST(CLANG_LDFLAGS) +AC_SUBST(CLANG_RFLAG) +AC_SUBST(CLANG_LIBS) +AC_PROG_GREP +AC_PROG_SED +if test "x$with_clang_prefix" != "x"; then + LLVM_CONFIG="$with_clang_prefix/bin/llvm-config" +fi +AC_PATH_PROG([LLVM_CONFIG], ["llvm-config"]) +if test -z "$LLVM_CONFIG" || test ! -x "$LLVM_CONFIG"; then + AC_MSG_ERROR([llvm-config not found]) +fi +CLANG_CXXFLAGS=`$LLVM_CONFIG --cxxflags | \ + $SED -e 's/-Wcovered-switch-default//;s/-gsplit-dwarf//'` +CLANG_LDFLAGS=`$LLVM_CONFIG --ldflags` +# Construct a -R argument for libtool. +# This is needed in case some of the clang libraries are shared libraries. +CLANG_RFLAG=`echo "$CLANG_LDFLAGS" | $SED -e 's/-L/-R/g'` +targets=`$LLVM_CONFIG --targets-built` +components="$targets asmparser bitreader support mc" +# Link in option and frontendopenmp components when available +# since they may be used by the clang libraries. +for c in option frontendopenmp; do + $LLVM_CONFIG --components | $GREP $c > /dev/null 2> /dev/null + if test $? -eq 0; then + components="$components $c" + fi +done +CLANG_LIBS=`$LLVM_CONFIG --libs $components` +systemlibs=`$LLVM_CONFIG --system-libs 2> /dev/null | tail -1` +if test $? -eq 0; then + CLANG_LIBS="$CLANG_LIBS $systemlibs" +fi +CLANG_PREFIX=`$LLVM_CONFIG --prefix` +AC_DEFINE_UNQUOTED(CLANG_PREFIX, ["$CLANG_PREFIX"], [Clang installation prefix]) + +# If $CLANG_PREFIX/bin/clang cannot find the standard include files, +# then see if setting sysroot to `xcode-select -p`/SDKs/MacOSX.sdk helps. +# This may be required on some versions of OS X since they lack /usr/include. +# If so, set CLANG_SYSROOT accordingly. +SAVE_CC="$CC" +CC="$CLANG_PREFIX/bin/clang" +AC_MSG_CHECKING( + [whether $CLANG_PREFIX/bin/clang can find standard include files]) +found_header=no +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], [[]])], + [found_header=yes]) +AC_MSG_RESULT([$found_header]) +if test "x$found_header" != "xyes"; then + AC_CHECK_PROG(XCODE_SELECT, xcode-select, xcode-select, []) + if test -z "$XCODE_SELECT"; then + AC_MSG_ERROR([Cannot find xcode-select]) + fi + sysroot=`$XCODE_SELECT -p`/SDKs/MacOSX.sdk + SAVE_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS -isysroot $sysroot" + AC_MSG_CHECKING( + [whether standard include files can be found with sysroot set]) + found_header=no + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], [[]])], + [found_header=yes]) + AC_MSG_RESULT([$found_header]) + CPPFLAGS="$SAVE_CPPFLAGS" + if test "x$found_header" != "xyes"; then + AC_MSG_ERROR([Cannot find standard include files]) + else + AC_DEFINE_UNQUOTED([CLANG_SYSROOT], ["$sysroot"], + [Define to sysroot if needed]) + fi +fi +CC="$SAVE_CC" + +AC_LANG_PUSH(C++) + +SAVE_CPPFLAGS="$CPPFLAGS" +SAVE_LDFLAGS="$LDFLAGS" +SAVE_LIBS="$LIBS" + +CPPFLAGS="$CLANG_CXXFLAGS -I$srcdir $CPPFLAGS" +AC_CHECK_HEADER([clang/Basic/SourceLocation.h], [], + [AC_MSG_ERROR([clang header file not found])]) +AC_CHECK_HEADER([llvm/TargetParser/Host.h], + [AC_DEFINE([HAVE_TARGETPARSER_HOST_H], [], + [Define if llvm/TargetParser/Host.h exists])], + [AC_EGREP_HEADER([getDefaultTargetTriple], [llvm/Support/Host.h], [], + [AC_DEFINE([getDefaultTargetTriple], [getHostTriple], + [Define to getHostTriple for older versions of clang])]) + ]) +AC_EGREP_HEADER([getExpansionLineNumber], [clang/Basic/SourceLocation.h], [], + [AC_DEFINE([getExpansionLineNumber], [getInstantiationLineNumber], + [Define to getInstantiationLineNumber for older versions of clang])]) +AC_EGREP_HEADER([getImmediateExpansionRange], [clang/Basic/SourceManager.h], + [], + [AC_DEFINE([getImmediateExpansionRange], + [getImmediateInstantiationRange], + [Define to getImmediateInstantiationRange for older versions of clang])] +) +AC_EGREP_HEADER([DiagnosticsEngine], [clang/Basic/Diagnostic.h], [], + [AC_DEFINE([DiagnosticsEngine], [Diagnostic], + [Define to Diagnostic for older versions of clang])]) +AC_EGREP_HEADER([ArrayRef], [clang/Driver/Driver.h], + [AC_DEFINE([USE_ARRAYREF], [], + [Define if Driver::BuildCompilation takes ArrayRef]) + AC_EGREP_HEADER([ArrayRef.*CommandLineArgs], + [clang/Frontend/CompilerInvocation.h], + [AC_DEFINE([CREATE_FROM_ARGS_TAKES_ARRAYREF], [], + [Define if CompilerInvocation::CreateFromArgs takes + ArrayRef]) + ]) + ]) +AC_EGREP_HEADER([CXXIsProduction], [clang/Driver/Driver.h], + [AC_DEFINE([HAVE_CXXISPRODUCTION], [], + [Define if Driver constructor takes CXXIsProduction argument])]) +AC_EGREP_HEADER([ IsProduction], [clang/Driver/Driver.h], + [AC_DEFINE([HAVE_ISPRODUCTION], [], + [Define if Driver constructor takes IsProduction argument])]) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], [[ + using namespace clang; + DiagnosticsEngine *Diags; + new driver::Driver("", "", "", *Diags); +]])], [AC_DEFINE([DRIVER_CTOR_TAKES_DEFAULTIMAGENAME], [], + [Define if Driver constructor takes default image name])]) +AC_EGREP_HEADER([void HandleTopLevelDecl\(], [clang/AST/ASTConsumer.h], + [AC_DEFINE([HandleTopLevelDeclReturn], [void], + [Return type of HandleTopLevelDeclReturn]) + AC_DEFINE([HandleTopLevelDeclContinue], [], + [Return type of HandleTopLevelDeclReturn])], + [AC_DEFINE([HandleTopLevelDeclReturn], [bool], + [Return type of HandleTopLevelDeclReturn]) + AC_DEFINE([HandleTopLevelDeclContinue], [true], + [Return type of HandleTopLevelDeclReturn])]) +AC_CHECK_HEADER([clang/Basic/DiagnosticOptions.h], + [AC_DEFINE([HAVE_BASIC_DIAGNOSTICOPTIONS_H], [], + [Define if clang/Basic/DiagnosticOptions.h exists])]) +AC_CHECK_HEADER([clang/Lex/PreprocessorOptions.h], + [AC_DEFINE([HAVE_LEX_PREPROCESSOROPTIONS_H], [], + [Define if clang/Lex/PreprocessorOptions.h exists])], [], + [#include ]) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], [[ + using namespace clang; + std::shared_ptr TO; + DiagnosticsEngine *Diags; + TargetInfo::CreateTargetInfo(*Diags, TO); +]])], [AC_DEFINE([CREATETARGETINFO_TAKES_SHARED_PTR], [], + [Define if TargetInfo::CreateTargetInfo takes shared_ptr])]) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], [[ + using namespace clang; + TargetOptions *TO; + DiagnosticsEngine *Diags; + TargetInfo::CreateTargetInfo(*Diags, TO); +]])], [AC_DEFINE([CREATETARGETINFO_TAKES_POINTER], [], + [Define if TargetInfo::CreateTargetInfo takes pointer])]) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM( + [[#include ]], [[ + using namespace clang; + DiagnosticConsumer *client; + CompilerInstance *Clang; + Clang->createDiagnostics(client); +]])], [], [AC_DEFINE([CREATEDIAGNOSTICS_TAKES_ARG], [], + [Define if CompilerInstance::createDiagnostics takes argc and argv])]) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM( + [[#include ]], [[ + using namespace clang; + HeaderSearchOptions HSO; + HSO.AddPath("", frontend::Angled, false, false); +]])], [AC_DEFINE([ADDPATH_TAKES_4_ARGUMENTS], [], + [Define if HeaderSearchOptions::AddPath takes 4 arguments])]) +AC_EGREP_HEADER([getNumParams], + [clang/AST/CanonicalType.h], + [AC_DEFINE([getNumArgs], [getNumParams], + [Define to getNumParams for newer versions of clang]) + AC_DEFINE([getArgType], [getParamType], + [Define to getParamType for newer versions of clang])]) +AC_EGREP_HEADER([getReturnType], + [clang/AST/CanonicalType.h], [], + [AC_DEFINE([getReturnType], [getResultType], + [Define to getResultType for older versions of clang])]) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM( + [[#include ]], [[ + using namespace clang; + CompilerInstance *Clang; + Clang->createPreprocessor(TU_Complete); +]])], [AC_DEFINE([CREATEPREPROCESSOR_TAKES_TUKIND], [], +[Define if CompilerInstance::createPreprocessor takes TranslationUnitKind])]) +AC_EGREP_HEADER([setMainFileID], [clang/Basic/SourceManager.h], + [AC_DEFINE([HAVE_SETMAINFILEID], [], + [Define if SourceManager has a setMainFileID method])]) +AC_CHECK_HEADER([llvm/ADT/OwningPtr.h], + [AC_DEFINE([HAVE_ADT_OWNINGPTR_H], [], + [Define if llvm/ADT/OwningPtr.h exists])]) +AC_EGREP_HEADER([initializeBuiltins], + [clang/Basic/Builtins.h], [], + [AC_DEFINE([initializeBuiltins], [InitializeBuiltins], + [Define to InitializeBuiltins for older versions of clang])]) +AC_EGREP_HEADER([IK_C], [clang/Frontend/FrontendOptions.h], [], + [AC_CHECK_HEADER([clang/Basic/LangStandard.h], + [IK_C=Language::C], [IK_C=InputKind::C]) + AC_DEFINE_UNQUOTED([IK_C], [$IK_C], + [Define to Language::C or InputKind::C for newer versions of clang]) + ]) +# llvmorg-15-init-7544-g93471e65df48 +AC_EGREP_HEADER([setLangDefaults], [clang/Basic/LangOptions.h], + [SETLANGDEFAULTS=LangOptions], + [SETLANGDEFAULTS=CompilerInvocation]) +AC_DEFINE_UNQUOTED([SETLANGDEFAULTS], [$SETLANGDEFAULTS], + [Define to class with setLangDefaults method]) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ + #include + #include + #include + + #include "set_lang_defaults_arg4.h" +]], [[ + using namespace clang; + CompilerInstance *Clang; + TargetOptions TO; + llvm::Triple T(TO.Triple); + PreprocessorOptions PO; + SETLANGDEFAULTS::setLangDefaults(Clang->getLangOpts(), IK_C, + T, setLangDefaultsArg4(PO), + LangStandard::lang_unspecified); +]])], [AC_DEFINE([SETLANGDEFAULTS_TAKES_5_ARGUMENTS], [], + [Define if CompilerInvocation::setLangDefaults takes 5 arguments])]) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ + #include + #include +]], [[ + using namespace clang; + CompilerInvocation *invocation; + CompilerInstance *Clang; + Clang->setInvocation(std::make_shared(*invocation)); +]])], [AC_DEFINE([SETINVOCATION_TAKES_SHARED_PTR], [], + [Defined if CompilerInstance::setInvocation takes a shared_ptr])]) +AC_CHECK_HEADER([llvm/Option/Arg.h], + [AC_DEFINE([HAVE_LLVM_OPTION_ARG_H], [], + [Define if llvm/Option/Arg.h exists])]) + +LDFLAGS="$CLANG_LDFLAGS $LDFLAGS" + +# A test program for checking whether linking against libclang-cpp works. +m4_define([_AX_DETECT_CLANG_PROGRAM], [AC_LANG_PROGRAM( + [[#include ]], + [[ + new clang::CompilerInstance(); + ]])]) + +# Use single libclang-cpp shared library when available. +# Otherwise, use a selection of clang libraries that appears to work. +AC_CHECK_LIB([clang-cpp], [main], [have_lib_clang=yes], [have_lib_clang=no]) +if test "$have_lib_clang" = yes; then + # The LLVM libraries may be linked into libclang-cpp already. + # Linking against them again can cause errors about options + # being registered more than once. + # Check whether linking against libclang-cpp requires + # linking against the LLVM libraries as well. + # Fail if linking fails with or without the LLVM libraries. + AC_MSG_CHECKING([whether libclang-cpp needs LLVM libraries]) + LIBS="-lclang-cpp $SAVE_LIBS" + AC_LINK_IFELSE([_AX_DETECT_CLANG_PROGRAM], [clangcpp_needs_llvm=no], [ + LIBS="-lclang-cpp $CLANG_LIBS $SAVE_LIBS" + AC_LINK_IFELSE([_AX_DETECT_CLANG_PROGRAM], + [clangcpp_needs_llvm=yes], + [clangcpp_needs_llvm=unknown]) + ]) + AC_MSG_RESULT([$clangcpp_needs_llvm]) + AS_IF([test "$clangcpp_needs_llvm" = "no"], + [CLANG_LIBS="-lclang-cpp"], + [test "$clangcpp_needs_llvm" = "yes"], + [CLANG_LIBS="-lclang-cpp $CLANG_LIBS"], + [AC_MSG_FAILURE([unable to link against libclang-cpp])]) +else + CLANG_LIBS="-lclangBasic -lclangDriver $CLANG_LIBS" + CLANG_LIBS="-lclangAnalysis -lclangAST -lclangLex $CLANG_LIBS" + LDFLAGS="$CLANG_LDFLAGS $CLANG_LIBS $SAVE_LDFLAGS" + AC_CHECK_LIB([clangEdit], [main], [LIB_CLANG_EDIT=-lclangEdit], []) + CLANG_LIBS="$LIB_CLANG_EDIT $CLANG_LIBS" + CLANG_LIBS="-lclangParse -lclangSema $CLANG_LIBS" + CLANG_LIBS="-lclangFrontend -lclangSerialization $CLANG_LIBS" +fi + +CPPFLAGS="$SAVE_CPPFLAGS" +LDFLAGS="$SAVE_LDFLAGS" +LIBS="$SAVE_LIBS" + +AC_LANG_POP +]) diff --git a/external/mit/isl/dist/m4/ax_detect_git_head.m4 b/external/mit/isl/dist/m4/ax_detect_git_head.m4 new file mode 100644 index 000000000000..31a6fe32945b --- /dev/null +++ b/external/mit/isl/dist/m4/ax_detect_git_head.m4 @@ -0,0 +1,32 @@ +AC_DEFUN([AX_DETECT_GIT_HEAD], [ + AC_SUBST(GIT_HEAD_ID) + AC_SUBST(GIT_HEAD) + AC_SUBST(GIT_HEAD_VERSION) + if test -f $srcdir/.git; then + gitdir=`GIT_DIR=$srcdir/.git git rev-parse --git-dir` + GIT_HEAD="$gitdir/index" + GIT_REPO="$gitdir" + GIT_HEAD_ID=`GIT_DIR=$GIT_REPO git describe --always` + elif test -f $srcdir/.git/HEAD; then + GIT_HEAD="$srcdir/.git/index" + GIT_REPO="$srcdir/.git" + GIT_HEAD_ID=`GIT_DIR=$GIT_REPO git describe --always` + elif test -f $srcdir/GIT_HEAD_ID; then + GIT_HEAD_ID=`cat $srcdir/GIT_HEAD_ID` + else + mysrcdir=`(cd $srcdir; pwd)` + head=`basename $mysrcdir | sed -e 's/.*-//'` + head2=`echo $head | sed -e 's/[^0-9a-f]//'` + head3=`echo $head2 | sed -e 's/........................................//'` + if test "x$head3" = "x" -a "x$head" = "x$head2"; then + GIT_HEAD_ID="$head" + else + GIT_HEAD_ID="UNKNOWN" + fi + fi + if test -z "$GIT_REPO" ; then + GIT_HEAD_VERSION="$GIT_HEAD_ID" + else + GIT_HEAD_VERSION="\`GIT_DIR=$GIT_REPO git describe --always\`" + fi +]) diff --git a/external/mit/isl/dist/m4/ax_detect_gmp.m4 b/external/mit/isl/dist/m4/ax_detect_gmp.m4 new file mode 100644 index 000000000000..b7b4a1c6869e --- /dev/null +++ b/external/mit/isl/dist/m4/ax_detect_gmp.m4 @@ -0,0 +1,47 @@ +AC_DEFUN([AX_DETECT_GMP], [ +AC_DEFINE([USE_GMP_FOR_MP], [], [use gmp to implement isl_int]) +AX_SUBMODULE(gmp,system|build,system) +case "$with_gmp" in +system) + if test "x$with_gmp_prefix" != "x"; then + MP_CPPFLAGS="-I$with_gmp_prefix/include" + MP_LDFLAGS="-L$with_gmp_prefix/lib" + fi + MP_LIBS=-lgmp + SAVE_CPPFLAGS="$CPPFLAGS" + SAVE_LDFLAGS="$LDFLAGS" + SAVE_LIBS="$LIBS" + CPPFLAGS="$MP_CPPFLAGS $CPPFLAGS" + LDFLAGS="$MP_LDFLAGS $LDFLAGS" + LIBS="$MP_LIBS $LIBS" + AC_CHECK_HEADER([gmp.h], [], [AC_MSG_ERROR([gmp.h header not found])]) + AC_CHECK_LIB([gmp], [main], [], [AC_MSG_ERROR([gmp library not found])]) + AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], [[ + mpz_t n, d; + if (mpz_divisible_p(n, d)) + mpz_divexact_ui(n, n, 4); + ]])], [], [AC_MSG_ERROR([gmp library too old])]) + CPPFLAGS="$SAVE_CPPFLAGS" + LDFLAGS="$SAVE_LDFLAGS" + LIBS="$SAVE_LIBS" + ;; +build) + MP_CPPFLAGS="-I$gmp_srcdir -I$with_gmp_builddir" + MP_LIBS="$with_gmp_builddir/libgmp.la" + ;; +esac +SAVE_CPPFLAGS="$CPPFLAGS" +SAVE_LDFLAGS="$LDFLAGS" +SAVE_LIBS="$LIBS" +CPPFLAGS="$MP_CPPFLAGS $CPPFLAGS" +LDFLAGS="$MP_LDFLAGS $LDFLAGS" +LIBS="$MP_LIBS $LIBS" +need_get_memory_functions=false +AC_CHECK_DECLS(mp_get_memory_functions,[],[ + need_get_memory_functions=true +],[#include ]) +CPPFLAGS="$SAVE_CPPFLAGS" +LDFLAGS="$SAVE_LDFLAGS" +LIBS="$SAVE_LIBS" +AM_CONDITIONAL(NEED_GET_MEMORY_FUNCTIONS, test x$need_get_memory_functions = xtrue) +]) diff --git a/external/mit/isl/dist/m4/ax_detect_imath.m4 b/external/mit/isl/dist/m4/ax_detect_imath.m4 new file mode 100644 index 000000000000..83e34f53de5d --- /dev/null +++ b/external/mit/isl/dist/m4/ax_detect_imath.m4 @@ -0,0 +1,16 @@ +AC_DEFUN([AX_DETECT_IMATH], [ +AC_DEFINE([USE_IMATH_FOR_MP], [], [use imath to implement isl_int]) + +MP_CPPFLAGS="-I$srcdir/imath_wrap" +MP_LDFLAGS="" +MP_LIBS="" + +SAVE_CPPFLAGS="$CPPFLAGS" +CPPFLAGS="$MP_CPPFLAGS $CPPFLAGS" +AC_CHECK_HEADER([imath.h], [], [AC_MSG_ERROR([imath.h header not found])]) +AC_CHECK_HEADER([gmp_compat.h], [], + [AC_MSG_ERROR([gmp_compat.h header not found])]) +CPPFLAGS="$SAVE_CPPFLAGS" + +AM_CONDITIONAL(NEED_GET_MEMORY_FUNCTIONS, test x = xfalse) +]) diff --git a/external/mit/isl/dist/m4/ax_gcc_archflag.m4 b/external/mit/isl/dist/m4/ax_gcc_archflag.m4 new file mode 100644 index 000000000000..c52b9b296e9f --- /dev/null +++ b/external/mit/isl/dist/m4/ax_gcc_archflag.m4 @@ -0,0 +1,267 @@ +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_gcc_archflag.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_GCC_ARCHFLAG([PORTABLE?], [ACTION-SUCCESS], [ACTION-FAILURE]) +# +# DESCRIPTION +# +# This macro tries to guess the "native" arch corresponding to the target +# architecture for use with gcc's -march=arch or -mtune=arch flags. If +# found, the cache variable $ax_cv_gcc_archflag is set to this flag and +# ACTION-SUCCESS is executed; otherwise $ax_cv_gcc_archflag is set to +# "unknown" and ACTION-FAILURE is executed. The default ACTION-SUCCESS is +# to add $ax_cv_gcc_archflag to the end of $CFLAGS. +# +# PORTABLE? should be either [yes] (default) or [no]. In the former case, +# the flag is set to -mtune (or equivalent) so that the architecture is +# only used for tuning, but the instruction set used is still portable. In +# the latter case, the flag is set to -march (or equivalent) so that +# architecture-specific instructions are enabled. +# +# The user can specify --with-gcc-arch= in order to override the +# macro's choice of architecture, or --without-gcc-arch to disable this. +# +# When cross-compiling, or if $CC is not gcc, then ACTION-FAILURE is +# called unless the user specified --with-gcc-arch manually. +# +# Requires macros: AX_CHECK_COMPILE_FLAG, AX_GCC_X86_CPUID +# +# (The main emphasis here is on recent CPUs, on the principle that doing +# high-performance computing on old hardware is uncommon.) +# +# LICENSE +# +# Copyright (c) 2008 Steven G. Johnson +# Copyright (c) 2008 Matteo Frigo +# Copyright (c) 2014 Tsukasa Oi +# Copyright (c) 2017-2018 Alexey Kopytov +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program. If not, see . +# +# As a special exception, the respective Autoconf Macro's copyright owner +# gives unlimited permission to copy, distribute and modify the configure +# scripts that are the output of Autoconf when processing the Macro. You +# need not follow the terms of the GNU General Public License when using +# or distributing such scripts, even though portions of the text of the +# Macro appear in them. The GNU General Public License (GPL) does govern +# all other use of the material that constitutes the Autoconf Macro. +# +# This special exception to the GPL applies to versions of the Autoconf +# Macro released by the Autoconf Archive. When you make and distribute a +# modified version of the Autoconf Macro, you may extend this special +# exception to the GPL to apply to your modified version as well. + +#serial 22 + +AC_DEFUN([AX_GCC_ARCHFLAG], +[AC_REQUIRE([AC_PROG_CC]) +AC_REQUIRE([AC_CANONICAL_HOST]) +AC_REQUIRE([AC_PROG_SED]) +AC_REQUIRE([AX_COMPILER_VENDOR]) + +AC_ARG_WITH(gcc-arch, [AS_HELP_STRING([--with-gcc-arch=], [use architecture for gcc -march/-mtune, instead of guessing])], + ax_gcc_arch=$withval, ax_gcc_arch=yes) + +AC_MSG_CHECKING([for gcc architecture flag]) +AC_MSG_RESULT([]) +AC_CACHE_VAL(ax_cv_gcc_archflag, +[ +ax_cv_gcc_archflag="unknown" + +if test "$GCC" = yes; then + +if test "x$ax_gcc_arch" = xyes; then +ax_gcc_arch="" +if test "$cross_compiling" = no; then +case $host_cpu in + i[[3456]]86*|x86_64*|amd64*) # use cpuid codes + AX_GCC_X86_CPUID(0) + AX_GCC_X86_CPUID(1) + case $ax_cv_gcc_x86_cpuid_0 in + *:756e6547:6c65746e:49656e69) # Intel + case $ax_cv_gcc_x86_cpuid_1 in + *5[[4578]]?:*:*:*) ax_gcc_arch="pentium-mmx pentium" ;; + *5[[123]]?:*:*:*) ax_gcc_arch=pentium ;; + *0?61?:*:*:*|?61?:*:*:*|61?:*:*:*) ax_gcc_arch=pentiumpro ;; + *0?6[[356]]?:*:*:*|?6[[356]]?:*:*:*|6[[356]]?:*:*:*) ax_gcc_arch="pentium2 pentiumpro" ;; + *0?6[[78ab]]?:*:*:*|?6[[78ab]]?:*:*:*|6[[78ab]]?:*:*:*) ax_gcc_arch="pentium3 pentiumpro" ;; + *0?6[[9d]]?:*:*:*|?6[[9d]]?:*:*:*|6[[9d]]?:*:*:*|*1?65?:*:*:*) ax_gcc_arch="pentium-m pentium3 pentiumpro" ;; + *0?6e?:*:*:*|?6e?:*:*:*|6e?:*:*:*) ax_gcc_arch="yonah pentium-m pentium3 pentiumpro" ;; + *0?6f?:*:*:*|?6f?:*:*:*|6f?:*:*:*|*1?66?:*:*:*) ax_gcc_arch="core2 pentium-m pentium3 pentiumpro" ;; + *1?6[[7d]]?:*:*:*) ax_gcc_arch="penryn core2 pentium-m pentium3 pentiumpro" ;; + *1?6[[aef]]?:*:*:*|*2?6e?:*:*:*) ax_gcc_arch="nehalem corei7 core2 pentium-m pentium3 pentiumpro" ;; + *2?6[[5cf]]?:*:*:*) ax_gcc_arch="westmere corei7 core2 pentium-m pentium3 pentiumpro" ;; + *2?6[[ad]]?:*:*:*) ax_gcc_arch="sandybridge corei7-avx corei7 core2 pentium-m pentium3 pentiumpro" ;; + *3?6[[ae]]?:*:*:*) ax_gcc_arch="ivybridge core-avx-i corei7-avx corei7 core2 pentium-m pentium3 pentiumpro" ;; + *3?6[[cf]]?:*:*:*|*4?6[[56]]?:*:*:*) ax_gcc_arch="haswell core-avx2 core-avx-i corei7-avx corei7 core2 pentium-m pentium3 pentiumpro" ;; + *3?6d?:*:*:*|*4?6[[7f]]?:*:*:*|*5?66?:*:*:*) ax_gcc_arch="broadwell core-avx2 core-avx-i corei7-avx corei7 core2 pentium-m pentium3 pentiumpro" ;; + *1?6c?:*:*:*|*2?6[[67]]?:*:*:*|*3?6[[56]]?:*:*:*) ax_gcc_arch="bonnell atom core2 pentium-m pentium3 pentiumpro" ;; + *3?67?:*:*:*|*[[45]]?6[[ad]]?:*:*:*) ax_gcc_arch="silvermont atom core2 pentium-m pentium3 pentiumpro" ;; + *000?f[[012]]?:*:*:*|?f[[012]]?:*:*:*|f[[012]]?:*:*:*) ax_gcc_arch="pentium4 pentiumpro" ;; + *000?f[[346]]?:*:*:*|?f[[346]]?:*:*:*|f[[346]]?:*:*:*) ax_gcc_arch="nocona prescott pentium4 pentiumpro" ;; + # fallback + *5??:*:*:*) ax_gcc_arch=pentium ;; + *??6??:*:*:*) ax_gcc_arch="core2 pentiumpro" ;; + *6??:*:*:*) ax_gcc_arch=pentiumpro ;; + *00??f??:*:*:*|??f??:*:*:*|?f??:*:*:*|f??:*:*:*) ax_gcc_arch="pentium4 pentiumpro" ;; + esac ;; + *:68747541:444d4163:69746e65) # AMD + case $ax_cv_gcc_x86_cpuid_1 in + *5[[67]]?:*:*:*) ax_gcc_arch=k6 ;; + *5[[8]]?:*:*:*) ax_gcc_arch="k6-2 k6" ;; + *5[[9d]]?:*:*:*) ax_gcc_arch="k6-3 k6" ;; + *6[[12]]?:*:*:*) ax_gcc_arch="athlon k7" ;; + *6[[34]]?:*:*:*) ax_gcc_arch="athlon-tbird k7" ;; + *6[[678a]]?:*:*:*) ax_gcc_arch="athlon-xp athlon-4 athlon k7" ;; + *000?f[[4578bcef]]?:*:*:*|?f[[4578bcef]]?:*:*:*|f[[4578bcef]]?:*:*:*|*001?f[[4578bcf]]?:*:*:*|1?f[[4578bcf]]?:*:*:*) ax_gcc_arch="athlon64 k8" ;; + *002?f[[13457bcf]]?:*:*:*|2?f[[13457bcf]]?:*:*:*|*004?f[[138bcf]]?:*:*:*|4?f[[138bcf]]?:*:*:*|*005?f[[df]]?:*:*:*|5?f[[df]]?:*:*:*|*006?f[[8bcf]]?:*:*:*|6?f[[8bcf]]?:*:*:*|*007?f[[cf]]?:*:*:*|7?f[[cf]]?:*:*:*|*00c?f1?:*:*:*|c?f1?:*:*:*|*020?f3?:*:*:*|20?f3?:*:*:*) ax_gcc_arch="athlon64-sse3 k8-sse3 athlon64 k8" ;; + *010?f[[245689a]]?:*:*:*|10?f[[245689a]]?:*:*:*|*030?f1?:*:*:*|30?f1?:*:*:*) ax_gcc_arch="barcelona amdfam10 k8" ;; + *050?f[[12]]?:*:*:*|50?f[[12]]?:*:*:*) ax_gcc_arch="btver1 amdfam10 k8" ;; + *060?f1?:*:*:*|60?f1?:*:*:*) ax_gcc_arch="bdver1 amdfam10 k8" ;; + *060?f2?:*:*:*|60?f2?:*:*:*|*061?f[[03]]?:*:*:*|61?f[[03]]?:*:*:*) ax_gcc_arch="bdver2 bdver1 amdfam10 k8" ;; + *063?f0?:*:*:*|63?f0?:*:*:*) ax_gcc_arch="bdver3 bdver2 bdver1 amdfam10 k8" ;; + *07[[03]]?f0?:*:*:*|7[[03]]?f0?:*:*:*) ax_gcc_arch="btver2 btver1 amdfam10 k8" ;; + # fallback + *0[[13]]??f??:*:*:*|[[13]]??f??:*:*:*) ax_gcc_arch="barcelona amdfam10 k8" ;; + *020?f??:*:*:*|20?f??:*:*:*) ax_gcc_arch="athlon64-sse3 k8-sse3 athlon64 k8" ;; + *05??f??:*:*:*|5??f??:*:*:*) ax_gcc_arch="btver1 amdfam10 k8" ;; + *060?f??:*:*:*|60?f??:*:*:*) ax_gcc_arch="bdver1 amdfam10 k8" ;; + *061?f??:*:*:*|61?f??:*:*:*) ax_gcc_arch="bdver2 bdver1 amdfam10 k8" ;; + *06??f??:*:*:*|6??f??:*:*:*) ax_gcc_arch="bdver3 bdver2 bdver1 amdfam10 k8" ;; + *070?f??:*:*:*|70?f??:*:*:*) ax_gcc_arch="btver2 btver1 amdfam10 k8" ;; + *???f??:*:*:*) ax_gcc_arch="amdfam10 k8" ;; + esac ;; + *:746e6543:736c7561:48727561) # IDT / VIA (Centaur) + case $ax_cv_gcc_x86_cpuid_1 in + *54?:*:*:*) ax_gcc_arch=winchip-c6 ;; + *5[[89]]?:*:*:*) ax_gcc_arch=winchip2 ;; + *66?:*:*:*) ax_gcc_arch=winchip2 ;; + *6[[78]]?:*:*:*) ax_gcc_arch=c3 ;; + *6[[9adf]]?:*:*:*) ax_gcc_arch="c3-2 c3" ;; + esac ;; + esac + if test x"$ax_gcc_arch" = x; then # fallback + case $host_cpu in + i586*) ax_gcc_arch=pentium ;; + i686*) ax_gcc_arch=pentiumpro ;; + esac + fi + ;; + + sparc*) + AC_PATH_PROG([PRTDIAG], [prtdiag], [prtdiag], [$PATH:/usr/platform/`uname -i`/sbin/:/usr/platform/`uname -m`/sbin/]) + cputype=`(((grep cpu /proc/cpuinfo | cut -d: -f2) ; ($PRTDIAG -v |grep -i sparc) ; grep -i cpu /var/run/dmesg.boot ) | head -n 1) 2> /dev/null` + cputype=`echo "$cputype" | tr -d ' -' | $SED 's/SPARCIIi/SPARCII/' |tr $as_cr_LETTERS $as_cr_letters` + case $cputype in + *ultrasparciv*) ax_gcc_arch="ultrasparc4 ultrasparc3 ultrasparc v9" ;; + *ultrasparciii*) ax_gcc_arch="ultrasparc3 ultrasparc v9" ;; + *ultrasparc*) ax_gcc_arch="ultrasparc v9" ;; + *supersparc*|*tms390z5[[05]]*) ax_gcc_arch="supersparc v8" ;; + *hypersparc*|*rt62[[056]]*) ax_gcc_arch="hypersparc v8" ;; + *cypress*) ax_gcc_arch=cypress ;; + esac ;; + + alphaev5) ax_gcc_arch=ev5 ;; + alphaev56) ax_gcc_arch=ev56 ;; + alphapca56) ax_gcc_arch="pca56 ev56" ;; + alphapca57) ax_gcc_arch="pca57 pca56 ev56" ;; + alphaev6) ax_gcc_arch=ev6 ;; + alphaev67) ax_gcc_arch=ev67 ;; + alphaev68) ax_gcc_arch="ev68 ev67" ;; + alphaev69) ax_gcc_arch="ev69 ev68 ev67" ;; + alphaev7) ax_gcc_arch="ev7 ev69 ev68 ev67" ;; + alphaev79) ax_gcc_arch="ev79 ev7 ev69 ev68 ev67" ;; + + powerpc*) + cputype=`((grep cpu /proc/cpuinfo | head -n 1 | cut -d: -f2 | cut -d, -f1 | $SED 's/ //g') ; /usr/bin/machine ; /bin/machine; grep CPU /var/run/dmesg.boot | head -n 1 | cut -d" " -f2) 2> /dev/null` + cputype=`echo $cputype | $SED -e 's/ppc//g;s/ *//g'` + case $cputype in + *750*) ax_gcc_arch="750 G3" ;; + *740[[0-9]]*) ax_gcc_arch="$cputype 7400 G4" ;; + *74[[4-5]][[0-9]]*) ax_gcc_arch="$cputype 7450 G4" ;; + *74[[0-9]][[0-9]]*) ax_gcc_arch="$cputype G4" ;; + *970*) ax_gcc_arch="970 G5 power4";; + *POWER4*|*power4*|*gq*) ax_gcc_arch="power4 970";; + *POWER5*|*power5*|*gr*|*gs*) ax_gcc_arch="power5 power4 970";; + 603ev|8240) ax_gcc_arch="$cputype 603e 603";; + *POWER7*) ax_gcc_arch="power7";; + *POWER8*) ax_gcc_arch="power8";; + *POWER9*) ax_gcc_arch="power9";; + *POWER10*) ax_gcc_arch="power10";; + *) ax_gcc_arch=$cputype ;; + esac + ax_gcc_arch="$ax_gcc_arch powerpc" + ;; + aarch64) + cpuimpl=`grep 'CPU implementer' /proc/cpuinfo 2> /dev/null | cut -d: -f2 | tr -d " " | head -n 1` + cpuarch=`grep 'CPU architecture' /proc/cpuinfo 2> /dev/null | cut -d: -f2 | tr -d " " | head -n 1` + cpuvar=`grep 'CPU variant' /proc/cpuinfo 2> /dev/null | cut -d: -f2 | tr -d " " | head -n 1` + case $cpuimpl in + 0x42) case $cpuarch in + 8) case $cpuvar in + 0x0) ax_gcc_arch="thunderx2t99 vulcan armv8.1-a armv8-a+lse armv8-a native" ;; + esac + ;; + esac + ;; + 0x43) case $cpuarch in + 8) case $cpuvar in + 0x0) ax_gcc_arch="thunderx armv8-a native" ;; + 0x1) ax_gcc_arch="thunderx+lse armv8.1-a armv8-a+lse armv8-a native" ;; + esac + ;; + esac + ;; + esac + ;; +esac +fi # not cross-compiling +fi # guess arch + +if test "x$ax_gcc_arch" != x -a "x$ax_gcc_arch" != xno; then +if test "x[]m4_default([$1],yes)" = xyes; then # if we require portable code + flag_prefixes="-mtune=" + if test "x$ax_cv_[]_AC_LANG_ABBREV[]_compiler_vendor" = xclang; then flag_prefixes="-march="; fi + # -mcpu=$arch and m$arch generate nonportable code on every arch except + # x86. And some other arches (e.g. Alpha) don't accept -mtune. Grrr. + case $host_cpu in i*86|x86_64*|amd64*) flag_prefixes="$flag_prefixes -mcpu= -m";; esac +else + flag_prefixes="-march= -mcpu= -m" +fi +for flag_prefix in $flag_prefixes; do + for arch in $ax_gcc_arch; do + flag="$flag_prefix$arch" + AX_CHECK_COMPILE_FLAG($flag, [if test "x$ax_cv_[]_AC_LANG_ABBREV[]_compiler_vendor" = xclang; then + if test "x[]m4_default([$1],yes)" = xyes; then + if test "x$flag" = "x-march=$arch"; then flag=-mtune=$arch; fi + fi + fi; ax_cv_gcc_archflag=$flag; break]) + done + test "x$ax_cv_gcc_archflag" = xunknown || break +done +fi + +fi # $GCC=yes +]) +AC_MSG_CHECKING([for gcc architecture flag]) +AC_MSG_RESULT($ax_cv_gcc_archflag) +if test "x$ax_cv_gcc_archflag" = xunknown; then + m4_default([$3],:) +else + m4_default([$2], [CFLAGS="$CFLAGS $ax_cv_gcc_archflag"]) +fi +]) diff --git a/external/mit/isl/dist/m4/ax_gcc_warn_unused_result.m4 b/external/mit/isl/dist/m4/ax_gcc_warn_unused_result.m4 new file mode 100644 index 000000000000..9a190e218c23 --- /dev/null +++ b/external/mit/isl/dist/m4/ax_gcc_warn_unused_result.m4 @@ -0,0 +1,37 @@ +# ============================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_gcc_warn_unused_result.html +# ============================================================================== +# +# SYNOPSIS +# +# AX_GCC_WARN_UNUSED_RESULT +# +# DESCRIPTION +# +# The macro will compile a test program to see whether the compiler does +# understand the per-function postfix pragma. +# +# LICENSE +# +# Copyright (c) 2008 Guido U. Draheim +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 10 + +AC_DEFUN([AX_GCC_WARN_UNUSED_RESULT],[dnl +AC_CACHE_CHECK( + [whether the compiler supports function __attribute__((__warn_unused_result__))], + ax_cv_gcc_warn_unused_result,[ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[__attribute__((__warn_unused_result__)) + int f(int i) { return i; }]], + [])], + [ax_cv_gcc_warn_unused_result=yes], [ax_cv_gcc_warn_unused_result=no])]) + if test "$ax_cv_gcc_warn_unused_result" = yes; then + AC_DEFINE([GCC_WARN_UNUSED_RESULT],[__attribute__((__warn_unused_result__))], + [most gcc compilers know a function __attribute__((__warn_unused_result__))]) + fi +]) diff --git a/external/mit/isl/dist/m4/ax_gcc_x86_cpuid.m4 b/external/mit/isl/dist/m4/ax_gcc_x86_cpuid.m4 new file mode 100644 index 000000000000..df954658ee1b --- /dev/null +++ b/external/mit/isl/dist/m4/ax_gcc_x86_cpuid.m4 @@ -0,0 +1,89 @@ +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_gcc_x86_cpuid.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_GCC_X86_CPUID(OP) +# AX_GCC_X86_CPUID_COUNT(OP, COUNT) +# +# DESCRIPTION +# +# On Pentium and later x86 processors, with gcc or a compiler that has a +# compatible syntax for inline assembly instructions, run a small program +# that executes the cpuid instruction with input OP. This can be used to +# detect the CPU type. AX_GCC_X86_CPUID_COUNT takes an additional COUNT +# parameter that gets passed into register ECX before calling cpuid. +# +# On output, the values of the eax, ebx, ecx, and edx registers are stored +# as hexadecimal strings as "eax:ebx:ecx:edx" in the cache variable +# ax_cv_gcc_x86_cpuid_OP. +# +# If the cpuid instruction fails (because you are running a +# cross-compiler, or because you are not using gcc, or because you are on +# a processor that doesn't have this instruction), ax_cv_gcc_x86_cpuid_OP +# is set to the string "unknown". +# +# This macro mainly exists to be used in AX_GCC_ARCHFLAG. +# +# LICENSE +# +# Copyright (c) 2008 Steven G. Johnson +# Copyright (c) 2008 Matteo Frigo +# Copyright (c) 2015 Michael Petch +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program. If not, see . +# +# As a special exception, the respective Autoconf Macro's copyright owner +# gives unlimited permission to copy, distribute and modify the configure +# scripts that are the output of Autoconf when processing the Macro. You +# need not follow the terms of the GNU General Public License when using +# or distributing such scripts, even though portions of the text of the +# Macro appear in them. The GNU General Public License (GPL) does govern +# all other use of the material that constitutes the Autoconf Macro. +# +# This special exception to the GPL applies to versions of the Autoconf +# Macro released by the Autoconf Archive. When you make and distribute a +# modified version of the Autoconf Macro, you may extend this special +# exception to the GPL to apply to your modified version as well. + +#serial 10 + +AC_DEFUN([AX_GCC_X86_CPUID], +[AX_GCC_X86_CPUID_COUNT($1, 0) +]) + +AC_DEFUN([AX_GCC_X86_CPUID_COUNT], +[AC_REQUIRE([AC_PROG_CC]) +AC_LANG_PUSH([C]) +AC_CACHE_CHECK(for x86 cpuid $1 output, ax_cv_gcc_x86_cpuid_$1, + [AC_RUN_IFELSE([AC_LANG_PROGRAM([#include ], [ + int op = $1, level = $2, eax, ebx, ecx, edx; + FILE *f; + __asm__ __volatile__ ("xchg %%ebx, %1\n" + "cpuid\n" + "xchg %%ebx, %1\n" + : "=a" (eax), "=r" (ebx), "=c" (ecx), "=d" (edx) + : "a" (op), "2" (level)); + + f = fopen("conftest_cpuid", "w"); if (!f) return 1; + fprintf(f, "%x:%x:%x:%x\n", eax, ebx, ecx, edx); + fclose(f); + return 0; +])], + [ax_cv_gcc_x86_cpuid_$1=`cat conftest_cpuid`; rm -f conftest_cpuid], + [ax_cv_gcc_x86_cpuid_$1=unknown; rm -f conftest_cpuid], + [ax_cv_gcc_x86_cpuid_$1=unknown])]) +AC_LANG_POP([C]) +]) diff --git a/external/mit/isl/dist/m4/ax_prog_cc_for_build.m4 b/external/mit/isl/dist/m4/ax_prog_cc_for_build.m4 new file mode 100644 index 000000000000..d80efdfc7537 --- /dev/null +++ b/external/mit/isl/dist/m4/ax_prog_cc_for_build.m4 @@ -0,0 +1,187 @@ +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_prog_cc_for_build.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_PROG_CC_FOR_BUILD +# +# DESCRIPTION +# +# This macro searches for a C compiler that generates native executables, +# that is a C compiler that surely is not a cross-compiler. This can be +# useful if you have to generate source code at compile-time like for +# example GCC does. +# +# The macro sets the CC_FOR_BUILD and CPP_FOR_BUILD macros to anything +# needed to compile or link (CC_FOR_BUILD) and preprocess (CPP_FOR_BUILD). +# The value of these variables can be overridden by the user by specifying +# a compiler with an environment variable (like you do for standard CC). +# +# It also sets BUILD_EXEEXT and BUILD_OBJEXT to the executable and object +# file extensions for the build platform, and GCC_FOR_BUILD to `yes' if +# the compiler we found is GCC. All these variables but GCC_FOR_BUILD are +# substituted in the Makefile. +# +# LICENSE +# +# Copyright (c) 2008 Paolo Bonzini +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 21 + +AU_ALIAS([AC_PROG_CC_FOR_BUILD], [AX_PROG_CC_FOR_BUILD]) +AC_DEFUN([AX_PROG_CC_FOR_BUILD], [dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_PROG_CPP])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl + +dnl Use the standard macros, but make them use other variable names +dnl +pushdef([ac_cv_prog_CPP], ac_cv_build_prog_CPP)dnl +pushdef([ac_cv_prog_cc_c89], ac_cv_build_prog_cc_c89)dnl +pushdef([ac_cv_prog_cc_c99], ac_cv_build_prog_cc_c99)dnl +pushdef([ac_cv_prog_cc_c11], ac_cv_build_prog_cc_c11)dnl +pushdef([ac_cv_prog_gcc], ac_cv_build_prog_gcc)dnl +pushdef([ac_cv_prog_cc_works], ac_cv_build_prog_cc_works)dnl +pushdef([ac_cv_prog_cc_cross], ac_cv_build_prog_cc_cross)dnl +pushdef([ac_cv_prog_cc_g], ac_cv_build_prog_cc_g)dnl +pushdef([ac_cv_c_compiler_gnu], ac_cv_build_c_compiler_gnu)dnl +pushdef([ac_cv_exeext], ac_cv_build_exeext)dnl +pushdef([ac_cv_objext], ac_cv_build_objext)dnl +pushdef([ac_exeext], ac_build_exeext)dnl +pushdef([ac_objext], ac_build_objext)dnl +pushdef([CC], CC_FOR_BUILD)dnl +pushdef([CCDEPMODE], CCDEPMODE_FOR_BUILD)dnl +pushdef([CPP], CPP_FOR_BUILD)dnl +pushdef([GCC], GCC_FOR_BUILD)dnl +pushdef([CFLAGS], CFLAGS_FOR_BUILD)dnl +pushdef([CPPFLAGS], CPPFLAGS_FOR_BUILD)dnl +pushdef([EXEEXT], BUILD_EXEEXT)dnl +pushdef([LDFLAGS], LDFLAGS_FOR_BUILD)dnl +pushdef([OBJEXT], BUILD_OBJEXT)dnl +pushdef([host], build)dnl +pushdef([host_alias], build_alias)dnl +pushdef([host_cpu], build_cpu)dnl +pushdef([host_vendor], build_vendor)dnl +pushdef([host_os], build_os)dnl +pushdef([ac_cv_host], ac_cv_build)dnl +pushdef([ac_cv_host_alias], ac_cv_build_alias)dnl +pushdef([ac_cv_host_cpu], ac_cv_build_cpu)dnl +pushdef([ac_cv_host_vendor], ac_cv_build_vendor)dnl +pushdef([ac_cv_host_os], ac_cv_build_os)dnl +pushdef([ac_tool_prefix], ac_build_tool_prefix)dnl +pushdef([am_cv_CC_dependencies_compiler_type], am_cv_build_CC_dependencies_compiler_type)dnl +pushdef([am__fastdepCC_FALSE], am__fastdepCC_build_FALSE)dnl +pushdef([am__fastdepCC_TRUE], am__fastdepCC_build_TRUE)dnl +pushdef([am_cv_prog_cc_c_o], am_cv_build_prog_cc_c_o)dnl +pushdef([cross_compiling], cross_compiling_build)dnl + +cross_compiling_build=no + +ac_build_tool_prefix= +AS_IF([test -n "$build"], [ac_build_tool_prefix="$build-"], + [test -n "$build_alias"],[ac_build_tool_prefix="$build_alias-"]) + +AC_LANG_PUSH([C]) + +dnl The pushdef([ac_cv_c_compiler_gnu], ...) currently does not cover +dnl the use of this variable in _AC_LANG_COMPILER_GNU called by +dnl AC_PROG_CC. Unset this cache variable temporarily as a workaround. +was_set_c_compiler_gnu=${[ac_cv_c_compiler_gnu]+y} +AS_IF([test ${was_set_c_compiler_gnu}], + [saved_c_compiler_gnu=$[ac_cv_c_compiler_gnu] + AS_UNSET([[ac_cv_c_compiler_gnu]])]) + +AC_PROG_CC + +dnl Restore ac_cv_c_compiler_gnu +AS_IF([test ${was_set_c_compiler_gnu}], + [[ac_cv_c_compiler_gnu]=$[saved_c_compiler_gnu]]) + +_AC_COMPILER_EXEEXT +_AC_COMPILER_OBJEXT +AC_PROG_CPP + +dnl Restore the old definitions +dnl +popdef([cross_compiling])dnl +popdef([am_cv_prog_cc_c_o])dnl +popdef([am__fastdepCC_TRUE])dnl +popdef([am__fastdepCC_FALSE])dnl +popdef([am_cv_CC_dependencies_compiler_type])dnl +popdef([ac_tool_prefix])dnl +popdef([ac_cv_host_os])dnl +popdef([ac_cv_host_vendor])dnl +popdef([ac_cv_host_cpu])dnl +popdef([ac_cv_host_alias])dnl +popdef([ac_cv_host])dnl +popdef([host_os])dnl +popdef([host_vendor])dnl +popdef([host_cpu])dnl +popdef([host_alias])dnl +popdef([host])dnl +popdef([OBJEXT])dnl +popdef([LDFLAGS])dnl +popdef([EXEEXT])dnl +popdef([CPPFLAGS])dnl +popdef([CFLAGS])dnl +popdef([GCC])dnl +popdef([CPP])dnl +popdef([CCDEPMODE])dnl +popdef([CC])dnl +popdef([ac_objext])dnl +popdef([ac_exeext])dnl +popdef([ac_cv_objext])dnl +popdef([ac_cv_exeext])dnl +popdef([ac_cv_c_compiler_gnu])dnl +popdef([ac_cv_prog_cc_g])dnl +popdef([ac_cv_prog_cc_cross])dnl +popdef([ac_cv_prog_cc_works])dnl +popdef([ac_cv_prog_cc_c89])dnl +popdef([ac_cv_prog_gcc])dnl +popdef([ac_cv_prog_CPP])dnl + +dnl restore global variables ac_ext, ac_cpp, ac_compile, +dnl ac_link, ac_compiler_gnu (dependant on the current +dnl language after popping): +AC_LANG_POP([C]) + +dnl Finally, set Makefile variables using the ac_cv_build_* variables +dnl +AC_SUBST(BUILD_EXEEXT)dnl +AC_SUBST(BUILD_OBJEXT)dnl +dnl Since autoconf 2.70, the call to AC_SUBST in the following lines +dnl of _AC_COMPILER_EXEEXT +dnl AC_SUBST([EXEEXT], [$ac_cv_exeext])dnl +dnl ac_exeext=$EXEEXT +dnl no longer sets BUILD_EXEEXT, but EXEEXT instead. +dnl This means not only that BUILD_EXEEXT is not getting set, +dnl but also that the original EXEEXT is overwritten +dnl by a possibly different value. Furthermore, ac_build_exeext +dnl is assigned an undefined value. +dnl Restore EXEEXT to the original value and +dnl set BUILD_EXEEXT and ac_build_exeext. +dnl Similarly for _AC_COMPILER_OBJEXT and OBJEXT. +m4_version_prereq([2.70],[dnl +EXEEXT=$ac_cv_exeext +BUILD_EXEEXT=$ac_cv_build_exeext; ac_build_exeext=$ac_cv_build_exeext +OBJEXT=$ac_cv_objext +BUILD_OBJEXT=$ac_cv_build_objext; ac_build_objext=$ac_cv_build_objext],[[]]) +dnl Similarly to _AC_COMPILER_EXEEXT and _AC_COMPILER_OBJEXT, +dnl the line +dnl AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) +dnl of _AM_DEPENDENCIES no longer sets CCDEPMODE_FOR_BUILD, +dnl but overrides CCDEPMODE. +dnl Restore CCDEPMODE and set CCDEPMODE_FOR_BUILD. +AC_SUBST(CCDEPMODE_FOR_BUILD)dnl +CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type +CCDEPMODE_FOR_BUILD=depmode=$am_cv_build_CC_dependencies_compiler_type +AC_SUBST([CFLAGS_FOR_BUILD])dnl +AC_SUBST([CPPFLAGS_FOR_BUILD])dnl +AC_SUBST([LDFLAGS_FOR_BUILD])dnl +]) diff --git a/external/mit/isl/dist/m4/ax_prog_cxx_for_build.m4 b/external/mit/isl/dist/m4/ax_prog_cxx_for_build.m4 new file mode 100644 index 000000000000..17c19a89fd3d --- /dev/null +++ b/external/mit/isl/dist/m4/ax_prog_cxx_for_build.m4 @@ -0,0 +1,110 @@ +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_prog_cxx_for_build.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_PROG_CXX_FOR_BUILD +# +# DESCRIPTION +# +# This macro searches for a C++ compiler that generates native +# executables, that is a C++ compiler that surely is not a cross-compiler. +# This can be useful if you have to generate source code at compile-time +# like for example GCC does. +# +# The macro sets the CXX_FOR_BUILD and CXXCPP_FOR_BUILD macros to anything +# needed to compile or link (CXX_FOR_BUILD) and preprocess +# (CXXCPP_FOR_BUILD). The value of these variables can be overridden by +# the user by specifying a compiler with an environment variable (like you +# do for standard CXX). +# +# LICENSE +# +# Copyright (c) 2008 Paolo Bonzini +# Copyright (c) 2012 Avionic Design GmbH +# +# Based on the AX_PROG_CC_FOR_BUILD macro by Paolo Bonzini. +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 3 + +AU_ALIAS([AC_PROG_CXX_FOR_BUILD], [AX_PROG_CXX_FOR_BUILD]) +AC_DEFUN([AX_PROG_CXX_FOR_BUILD], [dnl +AC_REQUIRE([AX_PROG_CC_FOR_BUILD])dnl +AC_REQUIRE([AC_PROG_CXX])dnl +AC_REQUIRE([AC_PROG_CXXCPP])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl + +dnl Use the standard macros, but make them use other variable names +dnl +pushdef([ac_cv_prog_CXXCPP], ac_cv_build_prog_CXXCPP)dnl +pushdef([ac_cv_prog_gxx], ac_cv_build_prog_gxx)dnl +pushdef([ac_cv_prog_cxx_works], ac_cv_build_prog_cxx_works)dnl +pushdef([ac_cv_prog_cxx_cross], ac_cv_build_prog_cxx_cross)dnl +pushdef([ac_cv_prog_cxx_g], ac_cv_build_prog_cxx_g)dnl +pushdef([CXX], CXX_FOR_BUILD)dnl +pushdef([CXXCPP], CXXCPP_FOR_BUILD)dnl +pushdef([CXXFLAGS], CXXFLAGS_FOR_BUILD)dnl +pushdef([CPPFLAGS], CPPFLAGS_FOR_BUILD)dnl +pushdef([CXXCPPFLAGS], CXXCPPFLAGS_FOR_BUILD)dnl +pushdef([host], build)dnl +pushdef([host_alias], build_alias)dnl +pushdef([host_cpu], build_cpu)dnl +pushdef([host_vendor], build_vendor)dnl +pushdef([host_os], build_os)dnl +pushdef([ac_cv_host], ac_cv_build)dnl +pushdef([ac_cv_host_alias], ac_cv_build_alias)dnl +pushdef([ac_cv_host_cpu], ac_cv_build_cpu)dnl +pushdef([ac_cv_host_vendor], ac_cv_build_vendor)dnl +pushdef([ac_cv_host_os], ac_cv_build_os)dnl +pushdef([ac_cxxcpp], ac_build_cxxcpp)dnl +pushdef([ac_compile], ac_build_compile)dnl +pushdef([ac_link], ac_build_link)dnl + +save_cross_compiling=$cross_compiling +save_ac_tool_prefix=$ac_tool_prefix +cross_compiling=no +ac_tool_prefix= + +AC_PROG_CXX +AC_PROG_CXXCPP + +ac_tool_prefix=$save_ac_tool_prefix +cross_compiling=$save_cross_compiling + +dnl Restore the old definitions +dnl +popdef([ac_link])dnl +popdef([ac_compile])dnl +popdef([ac_cxxcpp])dnl +popdef([ac_cv_host_os])dnl +popdef([ac_cv_host_vendor])dnl +popdef([ac_cv_host_cpu])dnl +popdef([ac_cv_host_alias])dnl +popdef([ac_cv_host])dnl +popdef([host_os])dnl +popdef([host_vendor])dnl +popdef([host_cpu])dnl +popdef([host_alias])dnl +popdef([host])dnl +popdef([CXXCPPFLAGS])dnl +popdef([CPPFLAGS])dnl +popdef([CXXFLAGS])dnl +popdef([CXXCPP])dnl +popdef([CXX])dnl +popdef([ac_cv_prog_cxx_g])dnl +popdef([ac_cv_prog_cxx_cross])dnl +popdef([ac_cv_prog_cxx_works])dnl +popdef([ac_cv_prog_gxx])dnl +popdef([ac_cv_prog_CXXCPP])dnl + +dnl Finally, set Makefile variables +dnl +AC_SUBST([CXXFLAGS_FOR_BUILD])dnl +AC_SUBST([CXXCPPFLAGS_FOR_BUILD])dnl +]) diff --git a/external/mit/isl/dist/m4/ax_set_warning_flags.m4 b/external/mit/isl/dist/m4/ax_set_warning_flags.m4 new file mode 100644 index 000000000000..c64ad7d8478b --- /dev/null +++ b/external/mit/isl/dist/m4/ax_set_warning_flags.m4 @@ -0,0 +1,17 @@ +dnl Add a set of flags to WARNING_FLAGS, that enable compiler warnings for +dnl isl. The warnings that are enabled vary with the compiler and only include +dnl warnings that did not trigger at the time of adding these flags. +AC_DEFUN([AX_SET_WARNING_FLAGS],[dnl + AX_COMPILER_VENDOR + + WARNING_FLAGS="" + + if test "${ax_cv_c_compiler_vendor}" = "clang"; then + dnl isl is at the moment clean of -Wall warnings. If clang adds + dnl new warnings to -Wall which cause false positives, the + dnl specific warning types will be disabled explicitally (by + dnl adding for example -Wno-return-type). To temporarily disable + dnl all warnings run configure with CFLAGS=-Wno-all. + WARNING_FLAGS="-Wall" + fi +]) diff --git a/external/mit/isl/dist/m4/ax_submodule.m4 b/external/mit/isl/dist/m4/ax_submodule.m4 new file mode 100644 index 000000000000..7cf899576d79 --- /dev/null +++ b/external/mit/isl/dist/m4/ax_submodule.m4 @@ -0,0 +1,71 @@ +AC_DEFUN([AX_SUBMODULE], +[ + +m4_if(m4_bregexp($2,|,choice),choice, + [AC_ARG_WITH($1, + [AS_HELP_STRING([--with-$1=$2], + [Which $1 to use [default=$3]])])]) +case "system" in +$2) + AC_ARG_WITH($1_prefix, + [AS_HELP_STRING([--with-$1-prefix=DIR], + [Prefix of $1 installation])]) + AC_ARG_WITH($1_exec_prefix, + [AS_HELP_STRING([--with-$1-exec-prefix=DIR], + [Exec prefix of $1 installation])]) +esac +m4_if(m4_bregexp($2,build,build),build, + [AC_ARG_WITH($1_builddir, + [AS_HELP_STRING([--with-$1-builddir=DIR], + [Location of $1 builddir])])]) +if test "x$with_$1_prefix" != "x" -a "x$with_$1_exec_prefix" = "x"; then + with_$1_exec_prefix=$with_$1_prefix +fi +if test "x$with_$1_prefix" != "x" -o "x$with_$1_exec_prefix" != "x"; then + if test "x$with_$1" != "x" -a "x$with_$1" != "xyes" -a "x$with_$1" != "xsystem"; then + AC_MSG_ERROR([Setting $with_$1_prefix implies use of system $1]) + fi + with_$1="system" +fi +if test "x$with_$1_builddir" != "x"; then + if test "x$with_$1" != "x" -a "x$with_$1" != "xyes" -a "x$with_$1" != "xbuild"; then + AC_MSG_ERROR([Setting $with_$1_builddir implies use of build $1]) + fi + with_$1="build" + $1_srcdir=`echo @abs_srcdir@ | $with_$1_builddir/config.status --file=-` + AC_MSG_NOTICE($1 sources in $$1_srcdir) +fi +if test "x$with_$1_exec_prefix" != "x"; then + export PKG_CONFIG_PATH="$with_$1_exec_prefix/lib/pkgconfig${PKG_CONFIG_PATH+:$PKG_CONFIG_PATH}" +fi +case "$with_$1" in +$2) + ;; +*) + case "$3" in + bundled) + if test -d $srcdir/.git -a \ + -d $srcdir/$1 -a \ + ! -d $srcdir/$1/.git; then + AC_MSG_WARN([git repo detected, but submodule $1 not initialized]) + AC_MSG_WARN([You may want to run]) + AC_MSG_WARN([ git submodule init]) + AC_MSG_WARN([ git submodule update]) + AC_MSG_WARN([ sh autogen.sh]) + fi + if test -f $srcdir/$1/configure; then + with_$1="bundled" + else + with_$1="no" + fi + ;; + *) + with_$1="$3" + ;; + esac + ;; +esac +AC_MSG_CHECKING([which $1 to use]) +AC_MSG_RESULT($with_$1) + +]) diff --git a/external/mit/isl/dist/m4/libtool.m4 b/external/mit/isl/dist/m4/libtool.m4 new file mode 100644 index 000000000000..c4c02946dece --- /dev/null +++ b/external/mit/isl/dist/m4/libtool.m4 @@ -0,0 +1,8394 @@ +# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- +# +# Copyright (C) 1996-2001, 2003-2015 Free Software Foundation, Inc. +# Written by Gordon Matzigkeit, 1996 +# +# 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. + +m4_define([_LT_COPYING], [dnl +# Copyright (C) 2014 Free Software Foundation, Inc. +# This is free software; see the source for copying conditions. There is NO +# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +# GNU Libtool is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of of the License, or +# (at your option) any later version. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program or library that is built +# using GNU Libtool, you may include this file under the same +# distribution terms that you use for the rest of that program. +# +# GNU Libtool is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +]) + +# serial 58 LT_INIT + + +# LT_PREREQ(VERSION) +# ------------------ +# Complain and exit if this libtool version is less that VERSION. +m4_defun([LT_PREREQ], +[m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1, + [m4_default([$3], + [m4_fatal([Libtool version $1 or higher is required], + 63)])], + [$2])]) + + +# _LT_CHECK_BUILDDIR +# ------------------ +# Complain if the absolute build directory name contains unusual characters +m4_defun([_LT_CHECK_BUILDDIR], +[case `pwd` in + *\ * | *\ *) + AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;; +esac +]) + + +# LT_INIT([OPTIONS]) +# ------------------ +AC_DEFUN([LT_INIT], +[AC_PREREQ([2.62])dnl We use AC_PATH_PROGS_FEATURE_CHECK +AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl +AC_BEFORE([$0], [LT_LANG])dnl +AC_BEFORE([$0], [LT_OUTPUT])dnl +AC_BEFORE([$0], [LTDL_INIT])dnl +m4_require([_LT_CHECK_BUILDDIR])dnl + +dnl Autoconf doesn't catch unexpanded LT_ macros by default: +m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl +m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl +dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4 +dnl unless we require an AC_DEFUNed macro: +AC_REQUIRE([LTOPTIONS_VERSION])dnl +AC_REQUIRE([LTSUGAR_VERSION])dnl +AC_REQUIRE([LTVERSION_VERSION])dnl +AC_REQUIRE([LTOBSOLETE_VERSION])dnl +m4_require([_LT_PROG_LTMAIN])dnl + +_LT_SHELL_INIT([SHELL=${CONFIG_SHELL-/bin/sh}]) + +dnl Parse OPTIONS +_LT_SET_OPTIONS([$0], [$1]) + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS=$ltmain + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' +AC_SUBST(LIBTOOL)dnl + +_LT_SETUP + +# Only expand once: +m4_define([LT_INIT]) +])# LT_INIT + +# Old names: +AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT]) +AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_PROG_LIBTOOL], []) +dnl AC_DEFUN([AM_PROG_LIBTOOL], []) + + +# _LT_PREPARE_CC_BASENAME +# ----------------------- +m4_defun([_LT_PREPARE_CC_BASENAME], [ +# Calculate cc_basename. Skip known compiler wrappers and cross-prefix. +func_cc_basename () +{ + for cc_temp in @S|@*""; do + case $cc_temp in + compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;; + distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;; + \-*) ;; + *) break;; + esac + done + func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` +} +])# _LT_PREPARE_CC_BASENAME + + +# _LT_CC_BASENAME(CC) +# ------------------- +# It would be clearer to call AC_REQUIREs from _LT_PREPARE_CC_BASENAME, +# but that macro is also expanded into generated libtool script, which +# arranges for $SED and $ECHO to be set by different means. +m4_defun([_LT_CC_BASENAME], +[m4_require([_LT_PREPARE_CC_BASENAME])dnl +AC_REQUIRE([_LT_DECL_SED])dnl +AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl +func_cc_basename $1 +cc_basename=$func_cc_basename_result +]) + + +# _LT_FILEUTILS_DEFAULTS +# ---------------------- +# It is okay to use these file commands and assume they have been set +# sensibly after 'm4_require([_LT_FILEUTILS_DEFAULTS])'. +m4_defun([_LT_FILEUTILS_DEFAULTS], +[: ${CP="cp -f"} +: ${MV="mv -f"} +: ${RM="rm -f"} +])# _LT_FILEUTILS_DEFAULTS + + +# _LT_SETUP +# --------- +m4_defun([_LT_SETUP], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +AC_REQUIRE([_LT_PREPARE_SED_QUOTE_VARS])dnl +AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl + +_LT_DECL([], [PATH_SEPARATOR], [1], [The PATH separator for the build system])dnl +dnl +_LT_DECL([], [host_alias], [0], [The host system])dnl +_LT_DECL([], [host], [0])dnl +_LT_DECL([], [host_os], [0])dnl +dnl +_LT_DECL([], [build_alias], [0], [The build system])dnl +_LT_DECL([], [build], [0])dnl +_LT_DECL([], [build_os], [0])dnl +dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([LT_PATH_LD])dnl +AC_REQUIRE([LT_PATH_NM])dnl +dnl +AC_REQUIRE([AC_PROG_LN_S])dnl +test -z "$LN_S" && LN_S="ln -s" +_LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl +dnl +AC_REQUIRE([LT_CMD_MAX_LEN])dnl +_LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl +_LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl +dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_CHECK_SHELL_FEATURES])dnl +m4_require([_LT_PATH_CONVERSION_FUNCTIONS])dnl +m4_require([_LT_CMD_RELOAD])dnl +m4_require([_LT_CHECK_MAGIC_METHOD])dnl +m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl +m4_require([_LT_CMD_OLD_ARCHIVE])dnl +m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl +m4_require([_LT_WITH_SYSROOT])dnl +m4_require([_LT_CMD_TRUNCATE])dnl + +_LT_CONFIG_LIBTOOL_INIT([ +# See if we are running on zsh, and set the options that allow our +# commands through without removal of \ escapes INIT. +if test -n "\${ZSH_VERSION+set}"; then + setopt NO_GLOB_SUBST +fi +]) +if test -n "${ZSH_VERSION+set}"; then + setopt NO_GLOB_SUBST +fi + +_LT_CHECK_OBJDIR + +m4_require([_LT_TAG_COMPILER])dnl + +case $host_os in +aix3*) + # AIX sometimes has problems with the GCC collect2 program. For some + # reason, if we set the COLLECT_NAMES environment variable, the problems + # vanish in a puff of smoke. + if test set != "${COLLECT_NAMES+set}"; then + COLLECT_NAMES= + export COLLECT_NAMES + fi + ;; +esac + +# Global variables: +ofile=libtool +can_build_shared=yes + +# All known linkers require a '.a' archive for static linking (except MSVC, +# which needs '.lib'). +libext=a + +with_gnu_ld=$lt_cv_prog_gnu_ld + +old_CC=$CC +old_CFLAGS=$CFLAGS + +# Set sane defaults for various variables +test -z "$CC" && CC=cc +test -z "$LTCC" && LTCC=$CC +test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS +test -z "$LD" && LD=ld +test -z "$ac_objext" && ac_objext=o + +_LT_CC_BASENAME([$compiler]) + +# Only perform the check for file, if the check method requires it +test -z "$MAGIC_CMD" && MAGIC_CMD=file +case $deplibs_check_method in +file_magic*) + if test "$file_magic_cmd" = '$MAGIC_CMD'; then + _LT_PATH_MAGIC + fi + ;; +esac + +# Use C for the default configuration in the libtool script +LT_SUPPORTED_TAG([CC]) +_LT_LANG_C_CONFIG +_LT_LANG_DEFAULT_CONFIG +_LT_CONFIG_COMMANDS +])# _LT_SETUP + + +# _LT_PREPARE_SED_QUOTE_VARS +# -------------------------- +# Define a few sed substitution that help us do robust quoting. +m4_defun([_LT_PREPARE_SED_QUOTE_VARS], +[# Backslashify metacharacters that are still active within +# double-quoted strings. +sed_quote_subst='s/\([["`$\\]]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\([["`\\]]\)/\\\1/g' + +# Sed substitution to delay expansion of an escaped shell variable in a +# double_quote_subst'ed string. +delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' + +# Sed substitution to delay expansion of an escaped single quote. +delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' + +# Sed substitution to avoid accidental globbing in evaled expressions +no_glob_subst='s/\*/\\\*/g' +]) + +# _LT_PROG_LTMAIN +# --------------- +# Note that this code is called both from 'configure', and 'config.status' +# now that we use AC_CONFIG_COMMANDS to generate libtool. Notably, +# 'config.status' has no value for ac_aux_dir unless we are using Automake, +# so we pass a copy along to make sure it has a sensible value anyway. +m4_defun([_LT_PROG_LTMAIN], +[m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl +_LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir']) +ltmain=$ac_aux_dir/ltmain.sh +])# _LT_PROG_LTMAIN + + +## ------------------------------------- ## +## Accumulate code for creating libtool. ## +## ------------------------------------- ## + +# So that we can recreate a full libtool script including additional +# tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS +# in macros and then make a single call at the end using the 'libtool' +# label. + + +# _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS]) +# ---------------------------------------- +# Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later. +m4_define([_LT_CONFIG_LIBTOOL_INIT], +[m4_ifval([$1], + [m4_append([_LT_OUTPUT_LIBTOOL_INIT], + [$1 +])])]) + +# Initialize. +m4_define([_LT_OUTPUT_LIBTOOL_INIT]) + + +# _LT_CONFIG_LIBTOOL([COMMANDS]) +# ------------------------------ +# Register COMMANDS to be passed to AC_CONFIG_COMMANDS later. +m4_define([_LT_CONFIG_LIBTOOL], +[m4_ifval([$1], + [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS], + [$1 +])])]) + +# Initialize. +m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS]) + + +# _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS]) +# ----------------------------------------------------- +m4_defun([_LT_CONFIG_SAVE_COMMANDS], +[_LT_CONFIG_LIBTOOL([$1]) +_LT_CONFIG_LIBTOOL_INIT([$2]) +]) + + +# _LT_FORMAT_COMMENT([COMMENT]) +# ----------------------------- +# Add leading comment marks to the start of each line, and a trailing +# full-stop to the whole comment if one is not present already. +m4_define([_LT_FORMAT_COMMENT], +[m4_ifval([$1], [ +m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])], + [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.]) +)]) + + + +## ------------------------ ## +## FIXME: Eliminate VARNAME ## +## ------------------------ ## + + +# _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?]) +# ------------------------------------------------------------------- +# CONFIGNAME is the name given to the value in the libtool script. +# VARNAME is the (base) name used in the configure script. +# VALUE may be 0, 1 or 2 for a computed quote escaped value based on +# VARNAME. Any other value will be used directly. +m4_define([_LT_DECL], +[lt_if_append_uniq([lt_decl_varnames], [$2], [, ], + [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name], + [m4_ifval([$1], [$1], [$2])]) + lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3]) + m4_ifval([$4], + [lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])]) + lt_dict_add_subkey([lt_decl_dict], [$2], + [tagged?], [m4_ifval([$5], [yes], [no])])]) +]) + + +# _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION]) +# -------------------------------------------------------- +m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])]) + + +# lt_decl_tag_varnames([SEPARATOR], [VARNAME1...]) +# ------------------------------------------------ +m4_define([lt_decl_tag_varnames], +[_lt_decl_filter([tagged?], [yes], $@)]) + + +# _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..]) +# --------------------------------------------------------- +m4_define([_lt_decl_filter], +[m4_case([$#], + [0], [m4_fatal([$0: too few arguments: $#])], + [1], [m4_fatal([$0: too few arguments: $#: $1])], + [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)], + [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)], + [lt_dict_filter([lt_decl_dict], $@)])[]dnl +]) + + +# lt_decl_quote_varnames([SEPARATOR], [VARNAME1...]) +# -------------------------------------------------- +m4_define([lt_decl_quote_varnames], +[_lt_decl_filter([value], [1], $@)]) + + +# lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...]) +# --------------------------------------------------- +m4_define([lt_decl_dquote_varnames], +[_lt_decl_filter([value], [2], $@)]) + + +# lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...]) +# --------------------------------------------------- +m4_define([lt_decl_varnames_tagged], +[m4_assert([$# <= 2])dnl +_$0(m4_quote(m4_default([$1], [[, ]])), + m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]), + m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))]) +m4_define([_lt_decl_varnames_tagged], +[m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])]) + + +# lt_decl_all_varnames([SEPARATOR], [VARNAME1...]) +# ------------------------------------------------ +m4_define([lt_decl_all_varnames], +[_$0(m4_quote(m4_default([$1], [[, ]])), + m4_if([$2], [], + m4_quote(lt_decl_varnames), + m4_quote(m4_shift($@))))[]dnl +]) +m4_define([_lt_decl_all_varnames], +[lt_join($@, lt_decl_varnames_tagged([$1], + lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl +]) + + +# _LT_CONFIG_STATUS_DECLARE([VARNAME]) +# ------------------------------------ +# Quote a variable value, and forward it to 'config.status' so that its +# declaration there will have the same value as in 'configure'. VARNAME +# must have a single quote delimited value for this to work. +m4_define([_LT_CONFIG_STATUS_DECLARE], +[$1='`$ECHO "$][$1" | $SED "$delay_single_quote_subst"`']) + + +# _LT_CONFIG_STATUS_DECLARATIONS +# ------------------------------ +# We delimit libtool config variables with single quotes, so when +# we write them to config.status, we have to be sure to quote all +# embedded single quotes properly. In configure, this macro expands +# each variable declared with _LT_DECL (and _LT_TAGDECL) into: +# +# ='`$ECHO "$" | $SED "$delay_single_quote_subst"`' +m4_defun([_LT_CONFIG_STATUS_DECLARATIONS], +[m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames), + [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])]) + + +# _LT_LIBTOOL_TAGS +# ---------------- +# Output comment and list of tags supported by the script +m4_defun([_LT_LIBTOOL_TAGS], +[_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl +available_tags='_LT_TAGS'dnl +]) + + +# _LT_LIBTOOL_DECLARE(VARNAME, [TAG]) +# ----------------------------------- +# Extract the dictionary values for VARNAME (optionally with TAG) and +# expand to a commented shell variable setting: +# +# # Some comment about what VAR is for. +# visible_name=$lt_internal_name +m4_define([_LT_LIBTOOL_DECLARE], +[_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], + [description])))[]dnl +m4_pushdef([_libtool_name], + m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl +m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])), + [0], [_libtool_name=[$]$1], + [1], [_libtool_name=$lt_[]$1], + [2], [_libtool_name=$lt_[]$1], + [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl +m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl +]) + + +# _LT_LIBTOOL_CONFIG_VARS +# ----------------------- +# Produce commented declarations of non-tagged libtool config variables +# suitable for insertion in the LIBTOOL CONFIG section of the 'libtool' +# script. Tagged libtool config variables (even for the LIBTOOL CONFIG +# section) are produced by _LT_LIBTOOL_TAG_VARS. +m4_defun([_LT_LIBTOOL_CONFIG_VARS], +[m4_foreach([_lt_var], + m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)), + [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])]) + + +# _LT_LIBTOOL_TAG_VARS(TAG) +# ------------------------- +m4_define([_LT_LIBTOOL_TAG_VARS], +[m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames), + [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])]) + + +# _LT_TAGVAR(VARNAME, [TAGNAME]) +# ------------------------------ +m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])]) + + +# _LT_CONFIG_COMMANDS +# ------------------- +# Send accumulated output to $CONFIG_STATUS. Thanks to the lists of +# variables for single and double quote escaping we saved from calls +# to _LT_DECL, we can put quote escaped variables declarations +# into 'config.status', and then the shell code to quote escape them in +# for loops in 'config.status'. Finally, any additional code accumulated +# from calls to _LT_CONFIG_LIBTOOL_INIT is expanded. +m4_defun([_LT_CONFIG_COMMANDS], +[AC_PROVIDE_IFELSE([LT_OUTPUT], + dnl If the libtool generation code has been placed in $CONFIG_LT, + dnl instead of duplicating it all over again into config.status, + dnl then we will have config.status run $CONFIG_LT later, so it + dnl needs to know what name is stored there: + [AC_CONFIG_COMMANDS([libtool], + [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])], + dnl If the libtool generation code is destined for config.status, + dnl expand the accumulated commands and init code now: + [AC_CONFIG_COMMANDS([libtool], + [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])]) +])#_LT_CONFIG_COMMANDS + + +# Initialize. +m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT], +[ + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +sed_quote_subst='$sed_quote_subst' +double_quote_subst='$double_quote_subst' +delay_variable_subst='$delay_variable_subst' +_LT_CONFIG_STATUS_DECLARATIONS +LTCC='$LTCC' +LTCFLAGS='$LTCFLAGS' +compiler='$compiler_DEFAULT' + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +\$[]1 +_LTECHO_EOF' +} + +# Quote evaled strings. +for var in lt_decl_all_varnames([[ \ +]], lt_decl_quote_varnames); do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[[\\\\\\\`\\"\\\$]]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +# Double-quote double-evaled strings. +for var in lt_decl_all_varnames([[ \ +]], lt_decl_dquote_varnames); do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[[\\\\\\\`\\"\\\$]]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +_LT_OUTPUT_LIBTOOL_INIT +]) + +# _LT_GENERATED_FILE_INIT(FILE, [COMMENT]) +# ------------------------------------ +# Generate a child script FILE with all initialization necessary to +# reuse the environment learned by the parent script, and make the +# file executable. If COMMENT is supplied, it is inserted after the +# '#!' sequence but before initialization text begins. After this +# macro, additional text can be appended to FILE to form the body of +# the child script. The macro ends with non-zero status if the +# file could not be fully written (such as if the disk is full). +m4_ifdef([AS_INIT_GENERATED], +[m4_defun([_LT_GENERATED_FILE_INIT],[AS_INIT_GENERATED($@)])], +[m4_defun([_LT_GENERATED_FILE_INIT], +[m4_require([AS_PREPARE])]dnl +[m4_pushdef([AS_MESSAGE_LOG_FD])]dnl +[lt_write_fail=0 +cat >$1 <<_ASEOF || lt_write_fail=1 +#! $SHELL +# Generated by $as_me. +$2 +SHELL=\${CONFIG_SHELL-$SHELL} +export SHELL +_ASEOF +cat >>$1 <<\_ASEOF || lt_write_fail=1 +AS_SHELL_SANITIZE +_AS_PREPARE +exec AS_MESSAGE_FD>&1 +_ASEOF +test 0 = "$lt_write_fail" && chmod +x $1[]dnl +m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT + +# LT_OUTPUT +# --------- +# This macro allows early generation of the libtool script (before +# AC_OUTPUT is called), incase it is used in configure for compilation +# tests. +AC_DEFUN([LT_OUTPUT], +[: ${CONFIG_LT=./config.lt} +AC_MSG_NOTICE([creating $CONFIG_LT]) +_LT_GENERATED_FILE_INIT(["$CONFIG_LT"], +[# Run this file to recreate a libtool stub with the current configuration.]) + +cat >>"$CONFIG_LT" <<\_LTEOF +lt_cl_silent=false +exec AS_MESSAGE_LOG_FD>>config.log +{ + echo + AS_BOX([Running $as_me.]) +} >&AS_MESSAGE_LOG_FD + +lt_cl_help="\ +'$as_me' creates a local libtool stub from the current configuration, +for use in further configure time tests before the real libtool is +generated. + +Usage: $[0] [[OPTIONS]] + + -h, --help print this help, then exit + -V, --version print version number, then exit + -q, --quiet do not print progress messages + -d, --debug don't remove temporary files + +Report bugs to ." + +lt_cl_version="\ +m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl +m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION]) +configured by $[0], generated by m4_PACKAGE_STRING. + +Copyright (C) 2011 Free Software Foundation, Inc. +This config.lt script is free software; the Free Software Foundation +gives unlimited permision to copy, distribute and modify it." + +while test 0 != $[#] +do + case $[1] in + --version | --v* | -V ) + echo "$lt_cl_version"; exit 0 ;; + --help | --h* | -h ) + echo "$lt_cl_help"; exit 0 ;; + --debug | --d* | -d ) + debug=: ;; + --quiet | --q* | --silent | --s* | -q ) + lt_cl_silent=: ;; + + -*) AC_MSG_ERROR([unrecognized option: $[1] +Try '$[0] --help' for more information.]) ;; + + *) AC_MSG_ERROR([unrecognized argument: $[1] +Try '$[0] --help' for more information.]) ;; + esac + shift +done + +if $lt_cl_silent; then + exec AS_MESSAGE_FD>/dev/null +fi +_LTEOF + +cat >>"$CONFIG_LT" <<_LTEOF +_LT_OUTPUT_LIBTOOL_COMMANDS_INIT +_LTEOF + +cat >>"$CONFIG_LT" <<\_LTEOF +AC_MSG_NOTICE([creating $ofile]) +_LT_OUTPUT_LIBTOOL_COMMANDS +AS_EXIT(0) +_LTEOF +chmod +x "$CONFIG_LT" + +# configure is writing to config.log, but config.lt does its own redirection, +# appending to config.log, which fails on DOS, as config.log is still kept +# open by configure. Here we exec the FD to /dev/null, effectively closing +# config.log, so it can be properly (re)opened and appended to by config.lt. +lt_cl_success=: +test yes = "$silent" && + lt_config_lt_args="$lt_config_lt_args --quiet" +exec AS_MESSAGE_LOG_FD>/dev/null +$SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false +exec AS_MESSAGE_LOG_FD>>config.log +$lt_cl_success || AS_EXIT(1) +])# LT_OUTPUT + + +# _LT_CONFIG(TAG) +# --------------- +# If TAG is the built-in tag, create an initial libtool script with a +# default configuration from the untagged config vars. Otherwise add code +# to config.status for appending the configuration named by TAG from the +# matching tagged config vars. +m4_defun([_LT_CONFIG], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +_LT_CONFIG_SAVE_COMMANDS([ + m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl + m4_if(_LT_TAG, [C], [ + # See if we are running on zsh, and set the options that allow our + # commands through without removal of \ escapes. + if test -n "${ZSH_VERSION+set}"; then + setopt NO_GLOB_SUBST + fi + + cfgfile=${ofile}T + trap "$RM \"$cfgfile\"; exit 1" 1 2 15 + $RM "$cfgfile" + + cat <<_LT_EOF >> "$cfgfile" +#! $SHELL +# Generated automatically by $as_me ($PACKAGE) $VERSION +# NOTE: Changes made to this file will be lost: look at ltmain.sh. + +# Provide generalized library-building support services. +# Written by Gordon Matzigkeit, 1996 + +_LT_COPYING +_LT_LIBTOOL_TAGS + +# Configured defaults for sys_lib_dlsearch_path munging. +: \${LT_SYS_LIBRARY_PATH="$configure_time_lt_sys_library_path"} + +# ### BEGIN LIBTOOL CONFIG +_LT_LIBTOOL_CONFIG_VARS +_LT_LIBTOOL_TAG_VARS +# ### END LIBTOOL CONFIG + +_LT_EOF + + cat <<'_LT_EOF' >> "$cfgfile" + +# ### BEGIN FUNCTIONS SHARED WITH CONFIGURE + +_LT_PREPARE_MUNGE_PATH_LIST +_LT_PREPARE_CC_BASENAME + +# ### END FUNCTIONS SHARED WITH CONFIGURE + +_LT_EOF + + case $host_os in + aix3*) + cat <<\_LT_EOF >> "$cfgfile" +# AIX sometimes has problems with the GCC collect2 program. For some +# reason, if we set the COLLECT_NAMES environment variable, the problems +# vanish in a puff of smoke. +if test set != "${COLLECT_NAMES+set}"; then + COLLECT_NAMES= + export COLLECT_NAMES +fi +_LT_EOF + ;; + esac + + _LT_PROG_LTMAIN + + # We use sed instead of cat because bash on DJGPP gets confused if + # if finds mixed CR/LF and LF-only lines. Since sed operates in + # text mode, it properly converts lines to CR/LF. This bash problem + # is reportedly fixed, but why not run on old versions too? + sed '$q' "$ltmain" >> "$cfgfile" \ + || (rm -f "$cfgfile"; exit 1) + + mv -f "$cfgfile" "$ofile" || + (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") + chmod +x "$ofile" +], +[cat <<_LT_EOF >> "$ofile" + +dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded +dnl in a comment (ie after a #). +# ### BEGIN LIBTOOL TAG CONFIG: $1 +_LT_LIBTOOL_TAG_VARS(_LT_TAG) +# ### END LIBTOOL TAG CONFIG: $1 +_LT_EOF +])dnl /m4_if +], +[m4_if([$1], [], [ + PACKAGE='$PACKAGE' + VERSION='$VERSION' + RM='$RM' + ofile='$ofile'], []) +])dnl /_LT_CONFIG_SAVE_COMMANDS +])# _LT_CONFIG + + +# LT_SUPPORTED_TAG(TAG) +# --------------------- +# Trace this macro to discover what tags are supported by the libtool +# --tag option, using: +# autoconf --trace 'LT_SUPPORTED_TAG:$1' +AC_DEFUN([LT_SUPPORTED_TAG], []) + + +# C support is built-in for now +m4_define([_LT_LANG_C_enabled], []) +m4_define([_LT_TAGS], []) + + +# LT_LANG(LANG) +# ------------- +# Enable libtool support for the given language if not already enabled. +AC_DEFUN([LT_LANG], +[AC_BEFORE([$0], [LT_OUTPUT])dnl +m4_case([$1], + [C], [_LT_LANG(C)], + [C++], [_LT_LANG(CXX)], + [Go], [_LT_LANG(GO)], + [Java], [_LT_LANG(GCJ)], + [Fortran 77], [_LT_LANG(F77)], + [Fortran], [_LT_LANG(FC)], + [Windows Resource], [_LT_LANG(RC)], + [m4_ifdef([_LT_LANG_]$1[_CONFIG], + [_LT_LANG($1)], + [m4_fatal([$0: unsupported language: "$1"])])])dnl +])# LT_LANG + + +# _LT_LANG(LANGNAME) +# ------------------ +m4_defun([_LT_LANG], +[m4_ifdef([_LT_LANG_]$1[_enabled], [], + [LT_SUPPORTED_TAG([$1])dnl + m4_append([_LT_TAGS], [$1 ])dnl + m4_define([_LT_LANG_]$1[_enabled], [])dnl + _LT_LANG_$1_CONFIG($1)])dnl +])# _LT_LANG + + +m4_ifndef([AC_PROG_GO], [ +############################################################ +# NOTE: This macro has been submitted for inclusion into # +# GNU Autoconf as AC_PROG_GO. When it is available in # +# a released version of Autoconf we should remove this # +# macro and use it instead. # +############################################################ +m4_defun([AC_PROG_GO], +[AC_LANG_PUSH(Go)dnl +AC_ARG_VAR([GOC], [Go compiler command])dnl +AC_ARG_VAR([GOFLAGS], [Go compiler flags])dnl +_AC_ARG_VAR_LDFLAGS()dnl +AC_CHECK_TOOL(GOC, gccgo) +if test -z "$GOC"; then + if test -n "$ac_tool_prefix"; then + AC_CHECK_PROG(GOC, [${ac_tool_prefix}gccgo], [${ac_tool_prefix}gccgo]) + fi +fi +if test -z "$GOC"; then + AC_CHECK_PROG(GOC, gccgo, gccgo, false) +fi +])#m4_defun +])#m4_ifndef + + +# _LT_LANG_DEFAULT_CONFIG +# ----------------------- +m4_defun([_LT_LANG_DEFAULT_CONFIG], +[AC_PROVIDE_IFELSE([AC_PROG_CXX], + [LT_LANG(CXX)], + [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])]) + +AC_PROVIDE_IFELSE([AC_PROG_F77], + [LT_LANG(F77)], + [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])]) + +AC_PROVIDE_IFELSE([AC_PROG_FC], + [LT_LANG(FC)], + [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])]) + +dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal +dnl pulling things in needlessly. +AC_PROVIDE_IFELSE([AC_PROG_GCJ], + [LT_LANG(GCJ)], + [AC_PROVIDE_IFELSE([A][M_PROG_GCJ], + [LT_LANG(GCJ)], + [AC_PROVIDE_IFELSE([LT_PROG_GCJ], + [LT_LANG(GCJ)], + [m4_ifdef([AC_PROG_GCJ], + [m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])]) + m4_ifdef([A][M_PROG_GCJ], + [m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])]) + m4_ifdef([LT_PROG_GCJ], + [m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])]) + +AC_PROVIDE_IFELSE([AC_PROG_GO], + [LT_LANG(GO)], + [m4_define([AC_PROG_GO], defn([AC_PROG_GO])[LT_LANG(GO)])]) + +AC_PROVIDE_IFELSE([LT_PROG_RC], + [LT_LANG(RC)], + [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])]) +])# _LT_LANG_DEFAULT_CONFIG + +# Obsolete macros: +AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)]) +AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)]) +AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)]) +AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)]) +AU_DEFUN([AC_LIBTOOL_RC], [LT_LANG(Windows Resource)]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_CXX], []) +dnl AC_DEFUN([AC_LIBTOOL_F77], []) +dnl AC_DEFUN([AC_LIBTOOL_FC], []) +dnl AC_DEFUN([AC_LIBTOOL_GCJ], []) +dnl AC_DEFUN([AC_LIBTOOL_RC], []) + + +# _LT_TAG_COMPILER +# ---------------- +m4_defun([_LT_TAG_COMPILER], +[AC_REQUIRE([AC_PROG_CC])dnl + +_LT_DECL([LTCC], [CC], [1], [A C compiler])dnl +_LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl +_LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl +_LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC +])# _LT_TAG_COMPILER + + +# _LT_COMPILER_BOILERPLATE +# ------------------------ +# Check for compiler boilerplate output or warnings with +# the simple compiler test code. +m4_defun([_LT_COMPILER_BOILERPLATE], +[m4_require([_LT_DECL_SED])dnl +ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$RM conftest* +])# _LT_COMPILER_BOILERPLATE + + +# _LT_LINKER_BOILERPLATE +# ---------------------- +# Check for linker boilerplate output or warnings with +# the simple link test code. +m4_defun([_LT_LINKER_BOILERPLATE], +[m4_require([_LT_DECL_SED])dnl +ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$RM -r conftest* +])# _LT_LINKER_BOILERPLATE + +# _LT_REQUIRED_DARWIN_CHECKS +# ------------------------- +m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ + case $host_os in + rhapsody* | darwin*) + AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:]) + AC_CHECK_TOOL([NMEDIT], [nmedit], [:]) + AC_CHECK_TOOL([LIPO], [lipo], [:]) + AC_CHECK_TOOL([OTOOL], [otool], [:]) + AC_CHECK_TOOL([OTOOL64], [otool64], [:]) + _LT_DECL([], [DSYMUTIL], [1], + [Tool to manipulate archived DWARF debug symbol files on Mac OS X]) + _LT_DECL([], [NMEDIT], [1], + [Tool to change global to local symbols on Mac OS X]) + _LT_DECL([], [LIPO], [1], + [Tool to manipulate fat objects and archives on Mac OS X]) + _LT_DECL([], [OTOOL], [1], + [ldd/readelf like tool for Mach-O binaries on Mac OS X]) + _LT_DECL([], [OTOOL64], [1], + [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4]) + + AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod], + [lt_cv_apple_cc_single_mod=no + if test -z "$LT_MULTI_MODULE"; then + # By default we will add the -single_module flag. You can override + # by either setting the environment variable LT_MULTI_MODULE + # non-empty at configure time, or by adding -multi_module to the + # link flags. + rm -rf libconftest.dylib* + echo "int foo(void){return 1;}" > conftest.c + echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ +-dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD + $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ + -dynamiclib -Wl,-single_module conftest.c 2>conftest.err + _lt_result=$? + # If there is a non-empty error log, and "single_module" + # appears in it, assume the flag caused a linker warning + if test -s conftest.err && $GREP single_module conftest.err; then + cat conftest.err >&AS_MESSAGE_LOG_FD + # Otherwise, if the output was created with a 0 exit code from + # the compiler, it worked. + elif test -f libconftest.dylib && test 0 = "$_lt_result"; then + lt_cv_apple_cc_single_mod=yes + else + cat conftest.err >&AS_MESSAGE_LOG_FD + fi + rm -rf libconftest.dylib* + rm -f conftest.* + fi]) + + AC_CACHE_CHECK([for -exported_symbols_list linker flag], + [lt_cv_ld_exported_symbols_list], + [lt_cv_ld_exported_symbols_list=no + save_LDFLAGS=$LDFLAGS + echo "_main" > conftest.sym + LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" + AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], + [lt_cv_ld_exported_symbols_list=yes], + [lt_cv_ld_exported_symbols_list=no]) + LDFLAGS=$save_LDFLAGS + ]) + + AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load], + [lt_cv_ld_force_load=no + cat > conftest.c << _LT_EOF +int forced_loaded() { return 2;} +_LT_EOF + echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD + $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD + echo "$AR cr libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD + $AR cr libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD + echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD + $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD + cat > conftest.c << _LT_EOF +int main() { return 0;} +_LT_EOF + echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&AS_MESSAGE_LOG_FD + $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err + _lt_result=$? + if test -s conftest.err && $GREP force_load conftest.err; then + cat conftest.err >&AS_MESSAGE_LOG_FD + elif test -f conftest && test 0 = "$_lt_result" && $GREP forced_load conftest >/dev/null 2>&1; then + lt_cv_ld_force_load=yes + else + cat conftest.err >&AS_MESSAGE_LOG_FD + fi + rm -f conftest.err libconftest.a conftest conftest.c + rm -rf conftest.dSYM + ]) + case $host_os in + rhapsody* | darwin1.[[012]]) + _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;; + darwin1.*) + _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; + darwin*) # darwin 5.x on + # if running on 10.5 or later, the deployment target defaults + # to the OS version, if on x86, and 10.4, the deployment + # target defaults to 10.4. Don't you love it? + case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in + 10.0,*86*-darwin8*|10.0,*-darwin[[912]]*) + _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; + 10.[[012]][[,.]]*) + _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; + 10.*|11.*) + _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; + esac + ;; + esac + if test yes = "$lt_cv_apple_cc_single_mod"; then + _lt_dar_single_mod='$single_module' + fi + if test yes = "$lt_cv_ld_exported_symbols_list"; then + _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym' + else + _lt_dar_export_syms='~$NMEDIT -s $output_objdir/$libname-symbols.expsym $lib' + fi + if test : != "$DSYMUTIL" && test no = "$lt_cv_ld_force_load"; then + _lt_dsymutil='~$DSYMUTIL $lib || :' + else + _lt_dsymutil= + fi + ;; + esac +]) + + +# _LT_DARWIN_LINKER_FEATURES([TAG]) +# --------------------------------- +# Checks for linker and compiler features on darwin +m4_defun([_LT_DARWIN_LINKER_FEATURES], +[ + m4_require([_LT_REQUIRED_DARWIN_CHECKS]) + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_automatic, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported + if test yes = "$lt_cv_ld_force_load"; then + _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' + m4_case([$1], [F77], [_LT_TAGVAR(compiler_needs_object, $1)=yes], + [FC], [_LT_TAGVAR(compiler_needs_object, $1)=yes]) + else + _LT_TAGVAR(whole_archive_flag_spec, $1)='' + fi + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(allow_undefined_flag, $1)=$_lt_dar_allow_undefined + case $cc_basename in + ifort*|nagfor*) _lt_dar_can_shared=yes ;; + *) _lt_dar_can_shared=$GCC ;; + esac + if test yes = "$_lt_dar_can_shared"; then + output_verbose_link_cmd=func_echo_all + _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil" + _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil" + _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" + _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" + m4_if([$1], [CXX], +[ if test yes != "$lt_cv_apple_cc_single_mod"; then + _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dsymutil" + _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dar_export_syms$_lt_dsymutil" + fi +],[]) + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi +]) + +# _LT_SYS_MODULE_PATH_AIX([TAGNAME]) +# ---------------------------------- +# Links a minimal program and checks the executable +# for the system default hardcoded library path. In most cases, +# this is /usr/lib:/lib, but when the MPI compilers are used +# the location of the communication and MPI libs are included too. +# If we don't find anything, use the default library path according +# to the aix ld manual. +# Store the results from the different compilers for each TAGNAME. +# Allow to override them for all tags through lt_cv_aix_libpath. +m4_defun([_LT_SYS_MODULE_PATH_AIX], +[m4_require([_LT_DECL_SED])dnl +if test set = "${lt_cv_aix_libpath+set}"; then + aix_libpath=$lt_cv_aix_libpath +else + AC_CACHE_VAL([_LT_TAGVAR([lt_cv_aix_libpath_], [$1])], + [AC_LINK_IFELSE([AC_LANG_PROGRAM],[ + lt_aix_libpath_sed='[ + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }]' + _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then + _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi],[]) + if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then + _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=/usr/lib:/lib + fi + ]) + aix_libpath=$_LT_TAGVAR([lt_cv_aix_libpath_], [$1]) +fi +])# _LT_SYS_MODULE_PATH_AIX + + +# _LT_SHELL_INIT(ARG) +# ------------------- +m4_define([_LT_SHELL_INIT], +[m4_divert_text([M4SH-INIT], [$1 +])])# _LT_SHELL_INIT + + + +# _LT_PROG_ECHO_BACKSLASH +# ----------------------- +# Find how we can fake an echo command that does not interpret backslash. +# In particular, with Autoconf 2.60 or later we add some code to the start +# of the generated configure script that will find a shell with a builtin +# printf (that we can use as an echo command). +m4_defun([_LT_PROG_ECHO_BACKSLASH], +[ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO + +AC_MSG_CHECKING([how to print strings]) +# Test print first, because it will be a builtin if present. +if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ + test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='print -r --' +elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='printf %s\n' +else + # Use this function as a fallback that always works. + func_fallback_echo () + { + eval 'cat <<_LTECHO_EOF +$[]1 +_LTECHO_EOF' + } + ECHO='func_fallback_echo' +fi + +# func_echo_all arg... +# Invoke $ECHO with all args, space-separated. +func_echo_all () +{ + $ECHO "$*" +} + +case $ECHO in + printf*) AC_MSG_RESULT([printf]) ;; + print*) AC_MSG_RESULT([print -r]) ;; + *) AC_MSG_RESULT([cat]) ;; +esac + +m4_ifdef([_AS_DETECT_SUGGESTED], +[_AS_DETECT_SUGGESTED([ + test -n "${ZSH_VERSION+set}${BASH_VERSION+set}" || ( + ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' + ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO + ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO + PATH=/empty FPATH=/empty; export PATH FPATH + test "X`printf %s $ECHO`" = "X$ECHO" \ + || test "X`print -r -- $ECHO`" = "X$ECHO" )])]) + +_LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts]) +_LT_DECL([], [ECHO], [1], [An echo program that protects backslashes]) +])# _LT_PROG_ECHO_BACKSLASH + + +# _LT_WITH_SYSROOT +# ---------------- +AC_DEFUN([_LT_WITH_SYSROOT], +[AC_MSG_CHECKING([for sysroot]) +AC_ARG_WITH([sysroot], +[AS_HELP_STRING([--with-sysroot@<:@=DIR@:>@], + [Search for dependent libraries within DIR (or the compiler's sysroot + if not specified).])], +[], [with_sysroot=no]) + +dnl lt_sysroot will always be passed unquoted. We quote it here +dnl in case the user passed a directory name. +lt_sysroot= +case $with_sysroot in #( + yes) + if test yes = "$GCC"; then + lt_sysroot=`$CC --print-sysroot 2>/dev/null` + fi + ;; #( + /*) + lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` + ;; #( + no|'') + ;; #( + *) + AC_MSG_RESULT([$with_sysroot]) + AC_MSG_ERROR([The sysroot must be an absolute path.]) + ;; +esac + + AC_MSG_RESULT([${lt_sysroot:-no}]) +_LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl +[dependent libraries, and where our libraries should be installed.])]) + +# _LT_ENABLE_LOCK +# --------------- +m4_defun([_LT_ENABLE_LOCK], +[AC_ARG_ENABLE([libtool-lock], + [AS_HELP_STRING([--disable-libtool-lock], + [avoid locking (might break parallel builds)])]) +test no = "$enable_libtool_lock" || enable_libtool_lock=yes + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case $host in +ia64-*-hpux*) + # Find out what ABI is being produced by ac_compile, and set mode + # options accordingly. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.$ac_objext` in + *ELF-32*) + HPUX_IA64_MODE=32 + ;; + *ELF-64*) + HPUX_IA64_MODE=64 + ;; + esac + fi + rm -rf conftest* + ;; +*-*-irix6*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. + echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + if test yes = "$lt_cv_prog_gnu_ld"; then + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -melf32bsmip" + ;; + *N32*) + LD="${LD-ld} -melf32bmipn32" + ;; + *64-bit*) + LD="${LD-ld} -melf64bmip" + ;; + esac + else + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + fi + rm -rf conftest* + ;; + +mips64*-*linux*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. + echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + emul=elf + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + emul="${emul}32" + ;; + *64-bit*) + emul="${emul}64" + ;; + esac + case `/usr/bin/file conftest.$ac_objext` in + *MSB*) + emul="${emul}btsmip" + ;; + *LSB*) + emul="${emul}ltsmip" + ;; + esac + case `/usr/bin/file conftest.$ac_objext` in + *N32*) + emul="${emul}n32" + ;; + esac + LD="${LD-ld} -m $emul" + fi + rm -rf conftest* + ;; + +x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ +s390*-*linux*|s390*-*tpf*|sparc*-*linux*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. Note that the listed cases only cover the + # situations where additional linker options are needed (such as when + # doing 32-bit compilation for a host where ld defaults to 64-bit, or + # vice versa); the common cases where no linker options are needed do + # not appear in the list. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.o` in + *32-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_i386_fbsd" + ;; + x86_64-*linux*) + case `/usr/bin/file conftest.o` in + *x86-64*) + LD="${LD-ld} -m elf32_x86_64" + ;; + *) + LD="${LD-ld} -m elf_i386" + ;; + esac + ;; + powerpc64le-*linux*) + LD="${LD-ld} -m elf32lppclinux" + ;; + powerpc64-*linux*) + LD="${LD-ld} -m elf32ppclinux" + ;; + s390x-*linux*) + LD="${LD-ld} -m elf_s390" + ;; + sparc64-*linux*) + LD="${LD-ld} -m elf32_sparc" + ;; + esac + ;; + *64-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_x86_64_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_x86_64" + ;; + powerpcle-*linux*) + LD="${LD-ld} -m elf64lppc" + ;; + powerpc-*linux*) + LD="${LD-ld} -m elf64ppc" + ;; + s390*-*linux*|s390*-*tpf*) + LD="${LD-ld} -m elf64_s390" + ;; + sparc*-*linux*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS=$CFLAGS + CFLAGS="$CFLAGS -belf" + AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, + [AC_LANG_PUSH(C) + AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) + AC_LANG_POP]) + if test yes != "$lt_cv_cc_needs_belf"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS=$SAVE_CFLAGS + fi + ;; +*-*solaris*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.o` in + *64-bit*) + case $lt_cv_prog_gnu_ld in + yes*) + case $host in + i?86-*-solaris*|x86_64-*-solaris*) + LD="${LD-ld} -m elf_x86_64" + ;; + sparc*-*-solaris*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + # GNU ld 2.21 introduced _sol2 emulations. Use them if available. + if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then + LD=${LD-ld}_sol2 + fi + ;; + *) + if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then + LD="${LD-ld} -64" + fi + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; +esac + +need_locks=$enable_libtool_lock +])# _LT_ENABLE_LOCK + + +# _LT_PROG_AR +# ----------- +m4_defun([_LT_PROG_AR], +[AC_CHECK_TOOLS(AR, [ar], false) +: ${AR=ar} +: ${AR_FLAGS=cr} +_LT_DECL([], [AR], [1], [The archiver]) +_LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive]) + +AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file], + [lt_cv_ar_at_file=no + AC_COMPILE_IFELSE([AC_LANG_PROGRAM], + [echo conftest.$ac_objext > conftest.lst + lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&AS_MESSAGE_LOG_FD' + AC_TRY_EVAL([lt_ar_try]) + if test 0 -eq "$ac_status"; then + # Ensure the archiver fails upon bogus file names. + rm -f conftest.$ac_objext libconftest.a + AC_TRY_EVAL([lt_ar_try]) + if test 0 -ne "$ac_status"; then + lt_cv_ar_at_file=@ + fi + fi + rm -f conftest.* libconftest.a + ]) + ]) + +if test no = "$lt_cv_ar_at_file"; then + archiver_list_spec= +else + archiver_list_spec=$lt_cv_ar_at_file +fi +_LT_DECL([], [archiver_list_spec], [1], + [How to feed a file listing to the archiver]) +])# _LT_PROG_AR + + +# _LT_CMD_OLD_ARCHIVE +# ------------------- +m4_defun([_LT_CMD_OLD_ARCHIVE], +[_LT_PROG_AR + +AC_CHECK_TOOL(STRIP, strip, :) +test -z "$STRIP" && STRIP=: +_LT_DECL([], [STRIP], [1], [A symbol stripping program]) + +AC_CHECK_TOOL(RANLIB, ranlib, :) +test -z "$RANLIB" && RANLIB=: +_LT_DECL([], [RANLIB], [1], + [Commands used to install an old-style archive]) + +# Determine commands to create old-style static archives. +old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' +old_postinstall_cmds='chmod 644 $oldlib' +old_postuninstall_cmds= + +if test -n "$RANLIB"; then + case $host_os in + bitrig* | openbsd*) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" + ;; + *) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" + ;; + esac + old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" +fi + +case $host_os in + darwin*) + lock_old_archive_extraction=yes ;; + *) + lock_old_archive_extraction=no ;; +esac +_LT_DECL([], [old_postinstall_cmds], [2]) +_LT_DECL([], [old_postuninstall_cmds], [2]) +_LT_TAGDECL([], [old_archive_cmds], [2], + [Commands used to build an old-style archive]) +_LT_DECL([], [lock_old_archive_extraction], [0], + [Whether to use a lock for old archive extraction]) +])# _LT_CMD_OLD_ARCHIVE + + +# _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, +# [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE]) +# ---------------------------------------------------------------- +# Check whether the given compiler option works +AC_DEFUN([_LT_COMPILER_OPTION], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_SED])dnl +AC_CACHE_CHECK([$1], [$2], + [$2=no + m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$3" ## exclude from sc_useless_quotes_in_assignment + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&AS_MESSAGE_LOG_FD + echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + $2=yes + fi + fi + $RM conftest* +]) + +if test yes = "[$]$2"; then + m4_if([$5], , :, [$5]) +else + m4_if([$6], , :, [$6]) +fi +])# _LT_COMPILER_OPTION + +# Old name: +AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], []) + + +# _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, +# [ACTION-SUCCESS], [ACTION-FAILURE]) +# ---------------------------------------------------- +# Check whether the given linker option works +AC_DEFUN([_LT_LINKER_OPTION], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_SED])dnl +AC_CACHE_CHECK([$1], [$2], + [$2=no + save_LDFLAGS=$LDFLAGS + LDFLAGS="$LDFLAGS $3" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&AS_MESSAGE_LOG_FD + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + $2=yes + fi + else + $2=yes + fi + fi + $RM -r conftest* + LDFLAGS=$save_LDFLAGS +]) + +if test yes = "[$]$2"; then + m4_if([$4], , :, [$4]) +else + m4_if([$5], , :, [$5]) +fi +])# _LT_LINKER_OPTION + +# Old name: +AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], []) + + +# LT_CMD_MAX_LEN +#--------------- +AC_DEFUN([LT_CMD_MAX_LEN], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +# find the maximum length of command line arguments +AC_MSG_CHECKING([the maximum length of command line arguments]) +AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl + i=0 + teststring=ABCD + + case $build_os in + msdosdjgpp*) + # On DJGPP, this test can blow up pretty badly due to problems in libc + # (any single argument exceeding 2000 bytes causes a buffer overrun + # during glob expansion). Even if it were fixed, the result of this + # check would be larger than it should be. + lt_cv_sys_max_cmd_len=12288; # 12K is about right + ;; + + gnu*) + # Under GNU Hurd, this test is not required because there is + # no limit to the length of command line arguments. + # Libtool will interpret -1 as no limit whatsoever + lt_cv_sys_max_cmd_len=-1; + ;; + + cygwin* | mingw* | cegcc*) + # On Win9x/ME, this test blows up -- it succeeds, but takes + # about 5 minutes as the teststring grows exponentially. + # Worse, since 9x/ME are not pre-emptively multitasking, + # you end up with a "frozen" computer, even though with patience + # the test eventually succeeds (with a max line length of 256k). + # Instead, let's just punt: use the minimum linelength reported by + # all of the supported platforms: 8192 (on NT/2K/XP). + lt_cv_sys_max_cmd_len=8192; + ;; + + mint*) + # On MiNT this can take a long time and run out of memory. + lt_cv_sys_max_cmd_len=8192; + ;; + + amigaos*) + # On AmigaOS with pdksh, this test takes hours, literally. + # So we just punt and use a minimum line length of 8192. + lt_cv_sys_max_cmd_len=8192; + ;; + + bitrig* | darwin* | dragonfly* | freebsd* | netbsd* | openbsd*) + # This has been around since 386BSD, at least. Likely further. + if test -x /sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` + elif test -x /usr/sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` + else + lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs + fi + # And add a safety zone + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + ;; + + interix*) + # We know the value 262144 and hardcode it with a safety zone (like BSD) + lt_cv_sys_max_cmd_len=196608 + ;; + + os2*) + # The test takes a long time on OS/2. + lt_cv_sys_max_cmd_len=8192 + ;; + + osf*) + # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure + # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not + # nice to cause kernel panics so lets avoid the loop below. + # First set a reasonable default. + lt_cv_sys_max_cmd_len=16384 + # + if test -x /sbin/sysconfig; then + case `/sbin/sysconfig -q proc exec_disable_arg_limit` in + *1*) lt_cv_sys_max_cmd_len=-1 ;; + esac + fi + ;; + sco3.2v5*) + lt_cv_sys_max_cmd_len=102400 + ;; + sysv5* | sco5v6* | sysv4.2uw2*) + kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` + if test -n "$kargmax"; then + lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'` + else + lt_cv_sys_max_cmd_len=32768 + fi + ;; + *) + lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` + if test -n "$lt_cv_sys_max_cmd_len" && \ + test undefined != "$lt_cv_sys_max_cmd_len"; then + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + else + # Make teststring a little bigger before we do anything with it. + # a 1K string should be a reasonable start. + for i in 1 2 3 4 5 6 7 8; do + teststring=$teststring$teststring + done + SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} + # If test is not a shell built-in, we'll probably end up computing a + # maximum length that is only half of the actual maximum length, but + # we can't tell. + while { test X`env echo "$teststring$teststring" 2>/dev/null` \ + = "X$teststring$teststring"; } >/dev/null 2>&1 && + test 17 != "$i" # 1/2 MB should be enough + do + i=`expr $i + 1` + teststring=$teststring$teststring + done + # Only check the string length outside the loop. + lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` + teststring= + # Add a significant safety factor because C++ compilers can tack on + # massive amounts of additional arguments before passing them to the + # linker. It appears as though 1/2 is a usable value. + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` + fi + ;; + esac +]) +if test -n "$lt_cv_sys_max_cmd_len"; then + AC_MSG_RESULT($lt_cv_sys_max_cmd_len) +else + AC_MSG_RESULT(none) +fi +max_cmd_len=$lt_cv_sys_max_cmd_len +_LT_DECL([], [max_cmd_len], [0], + [What is the maximum length of a command?]) +])# LT_CMD_MAX_LEN + +# Old name: +AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], []) + + +# _LT_HEADER_DLFCN +# ---------------- +m4_defun([_LT_HEADER_DLFCN], +[AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl +])# _LT_HEADER_DLFCN + + +# _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, +# ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) +# ---------------------------------------------------------------- +m4_defun([_LT_TRY_DLOPEN_SELF], +[m4_require([_LT_HEADER_DLFCN])dnl +if test yes = "$cross_compiling"; then : + [$4] +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +[#line $LINENO "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +/* When -fvisibility=hidden is used, assume the code has been annotated + correspondingly for the symbols needed. */ +#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +int fnord () __attribute__((visibility("default"))); +#endif + +int fnord () { return 42; } +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else + { + if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + else puts (dlerror ()); + } + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +}] +_LT_EOF + if AC_TRY_EVAL(ac_link) && test -s "conftest$ac_exeext" 2>/dev/null; then + (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) $1 ;; + x$lt_dlneed_uscore) $2 ;; + x$lt_dlunknown|x*) $3 ;; + esac + else : + # compilation failed + $3 + fi +fi +rm -fr conftest* +])# _LT_TRY_DLOPEN_SELF + + +# LT_SYS_DLOPEN_SELF +# ------------------ +AC_DEFUN([LT_SYS_DLOPEN_SELF], +[m4_require([_LT_HEADER_DLFCN])dnl +if test yes != "$enable_dlopen"; then + enable_dlopen=unknown + enable_dlopen_self=unknown + enable_dlopen_self_static=unknown +else + lt_cv_dlopen=no + lt_cv_dlopen_libs= + + case $host_os in + beos*) + lt_cv_dlopen=load_add_on + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ;; + + mingw* | pw32* | cegcc*) + lt_cv_dlopen=LoadLibrary + lt_cv_dlopen_libs= + ;; + + cygwin*) + lt_cv_dlopen=dlopen + lt_cv_dlopen_libs= + ;; + + darwin*) + # if libdl is installed we need to link against it + AC_CHECK_LIB([dl], [dlopen], + [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl],[ + lt_cv_dlopen=dyld + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ]) + ;; + + tpf*) + # Don't try to run any link tests for TPF. We know it's impossible + # because TPF is a cross-compiler, and we know how we open DSOs. + lt_cv_dlopen=dlopen + lt_cv_dlopen_libs= + lt_cv_dlopen_self=no + ;; + + *) + AC_CHECK_FUNC([shl_load], + [lt_cv_dlopen=shl_load], + [AC_CHECK_LIB([dld], [shl_load], + [lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld], + [AC_CHECK_FUNC([dlopen], + [lt_cv_dlopen=dlopen], + [AC_CHECK_LIB([dl], [dlopen], + [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl], + [AC_CHECK_LIB([svld], [dlopen], + [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld], + [AC_CHECK_LIB([dld], [dld_link], + [lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld]) + ]) + ]) + ]) + ]) + ]) + ;; + esac + + if test no = "$lt_cv_dlopen"; then + enable_dlopen=no + else + enable_dlopen=yes + fi + + case $lt_cv_dlopen in + dlopen) + save_CPPFLAGS=$CPPFLAGS + test yes = "$ac_cv_header_dlfcn_h" && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + + save_LDFLAGS=$LDFLAGS + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + + save_LIBS=$LIBS + LIBS="$lt_cv_dlopen_libs $LIBS" + + AC_CACHE_CHECK([whether a program can dlopen itself], + lt_cv_dlopen_self, [dnl + _LT_TRY_DLOPEN_SELF( + lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, + lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) + ]) + + if test yes = "$lt_cv_dlopen_self"; then + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" + AC_CACHE_CHECK([whether a statically linked program can dlopen itself], + lt_cv_dlopen_self_static, [dnl + _LT_TRY_DLOPEN_SELF( + lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, + lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) + ]) + fi + + CPPFLAGS=$save_CPPFLAGS + LDFLAGS=$save_LDFLAGS + LIBS=$save_LIBS + ;; + esac + + case $lt_cv_dlopen_self in + yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; + *) enable_dlopen_self=unknown ;; + esac + + case $lt_cv_dlopen_self_static in + yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; + *) enable_dlopen_self_static=unknown ;; + esac +fi +_LT_DECL([dlopen_support], [enable_dlopen], [0], + [Whether dlopen is supported]) +_LT_DECL([dlopen_self], [enable_dlopen_self], [0], + [Whether dlopen of programs is supported]) +_LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0], + [Whether dlopen of statically linked programs is supported]) +])# LT_SYS_DLOPEN_SELF + +# Old name: +AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], []) + + +# _LT_COMPILER_C_O([TAGNAME]) +# --------------------------- +# Check to see if options -c and -o are simultaneously supported by compiler. +# This macro does not hard code the compiler like AC_PROG_CC_C_O. +m4_defun([_LT_COMPILER_C_O], +[m4_require([_LT_DECL_SED])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_TAG_COMPILER])dnl +AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], + [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)], + [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&AS_MESSAGE_LOG_FD + echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes + fi + fi + chmod u+w . 2>&AS_MESSAGE_LOG_FD + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* +]) +_LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1], + [Does compiler simultaneously support -c and -o options?]) +])# _LT_COMPILER_C_O + + +# _LT_COMPILER_FILE_LOCKS([TAGNAME]) +# ---------------------------------- +# Check to see if we can do hard links to lock some files if needed +m4_defun([_LT_COMPILER_FILE_LOCKS], +[m4_require([_LT_ENABLE_LOCK])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +_LT_COMPILER_C_O([$1]) + +hard_links=nottested +if test no = "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" && test no != "$need_locks"; then + # do not overwrite the value of need_locks provided by the user + AC_MSG_CHECKING([if we can lock with hard links]) + hard_links=yes + $RM conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + AC_MSG_RESULT([$hard_links]) + if test no = "$hard_links"; then + AC_MSG_WARN(['$CC' does not support '-c -o', so 'make -j' may be unsafe]) + need_locks=warn + fi +else + need_locks=no +fi +_LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?]) +])# _LT_COMPILER_FILE_LOCKS + + +# _LT_CHECK_OBJDIR +# ---------------- +m4_defun([_LT_CHECK_OBJDIR], +[AC_CACHE_CHECK([for objdir], [lt_cv_objdir], +[rm -f .libs 2>/dev/null +mkdir .libs 2>/dev/null +if test -d .libs; then + lt_cv_objdir=.libs +else + # MS-DOS does not allow filenames that begin with a dot. + lt_cv_objdir=_libs +fi +rmdir .libs 2>/dev/null]) +objdir=$lt_cv_objdir +_LT_DECL([], [objdir], [0], + [The name of the directory that contains temporary libtool files])dnl +m4_pattern_allow([LT_OBJDIR])dnl +AC_DEFINE_UNQUOTED([LT_OBJDIR], "$lt_cv_objdir/", + [Define to the sub-directory where libtool stores uninstalled libraries.]) +])# _LT_CHECK_OBJDIR + + +# _LT_LINKER_HARDCODE_LIBPATH([TAGNAME]) +# -------------------------------------- +# Check hardcoding attributes. +m4_defun([_LT_LINKER_HARDCODE_LIBPATH], +[AC_MSG_CHECKING([how to hardcode library paths into programs]) +_LT_TAGVAR(hardcode_action, $1)= +if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" || + test -n "$_LT_TAGVAR(runpath_var, $1)" || + test yes = "$_LT_TAGVAR(hardcode_automatic, $1)"; then + + # We can hardcode non-existent directories. + if test no != "$_LT_TAGVAR(hardcode_direct, $1)" && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" && + test no != "$_LT_TAGVAR(hardcode_minus_L, $1)"; then + # Linking always hardcodes the temporary library directory. + _LT_TAGVAR(hardcode_action, $1)=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + _LT_TAGVAR(hardcode_action, $1)=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + _LT_TAGVAR(hardcode_action, $1)=unsupported +fi +AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)]) + +if test relink = "$_LT_TAGVAR(hardcode_action, $1)" || + test yes = "$_LT_TAGVAR(inherit_rpath, $1)"; then + # Fast installation is not supported + enable_fast_install=no +elif test yes = "$shlibpath_overrides_runpath" || + test no = "$enable_shared"; then + # Fast installation is not necessary + enable_fast_install=needless +fi +_LT_TAGDECL([], [hardcode_action], [0], + [How to hardcode a shared library path into an executable]) +])# _LT_LINKER_HARDCODE_LIBPATH + + +# _LT_CMD_STRIPLIB +# ---------------- +m4_defun([_LT_CMD_STRIPLIB], +[m4_require([_LT_DECL_EGREP]) +striplib= +old_striplib= +AC_MSG_CHECKING([whether stripping libraries is possible]) +if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then + test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" + test -z "$striplib" && striplib="$STRIP --strip-unneeded" + AC_MSG_RESULT([yes]) +else +# FIXME - insert some real tests, host_os isn't really good enough + case $host_os in + darwin*) + if test -n "$STRIP"; then + striplib="$STRIP -x" + old_striplib="$STRIP -S" + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + fi + ;; + *) + AC_MSG_RESULT([no]) + ;; + esac +fi +_LT_DECL([], [old_striplib], [1], [Commands to strip libraries]) +_LT_DECL([], [striplib], [1]) +])# _LT_CMD_STRIPLIB + + +# _LT_PREPARE_MUNGE_PATH_LIST +# --------------------------- +# Make sure func_munge_path_list() is defined correctly. +m4_defun([_LT_PREPARE_MUNGE_PATH_LIST], +[[# func_munge_path_list VARIABLE PATH +# ----------------------------------- +# VARIABLE is name of variable containing _space_ separated list of +# directories to be munged by the contents of PATH, which is string +# having a format: +# "DIR[:DIR]:" +# string "DIR[ DIR]" will be prepended to VARIABLE +# ":DIR[:DIR]" +# string "DIR[ DIR]" will be appended to VARIABLE +# "DIRP[:DIRP]::[DIRA:]DIRA" +# string "DIRP[ DIRP]" will be prepended to VARIABLE and string +# "DIRA[ DIRA]" will be appended to VARIABLE +# "DIR[:DIR]" +# VARIABLE will be replaced by "DIR[ DIR]" +func_munge_path_list () +{ + case x@S|@2 in + x) + ;; + *:) + eval @S|@1=\"`$ECHO @S|@2 | $SED 's/:/ /g'` \@S|@@S|@1\" + ;; + x:*) + eval @S|@1=\"\@S|@@S|@1 `$ECHO @S|@2 | $SED 's/:/ /g'`\" + ;; + *::*) + eval @S|@1=\"\@S|@@S|@1\ `$ECHO @S|@2 | $SED -e 's/.*:://' -e 's/:/ /g'`\" + eval @S|@1=\"`$ECHO @S|@2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \@S|@@S|@1\" + ;; + *) + eval @S|@1=\"`$ECHO @S|@2 | $SED 's/:/ /g'`\" + ;; + esac +} +]])# _LT_PREPARE_PATH_LIST + + +# _LT_SYS_DYNAMIC_LINKER([TAG]) +# ----------------------------- +# PORTME Fill in your ld.so characteristics +m4_defun([_LT_SYS_DYNAMIC_LINKER], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_OBJDUMP])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_CHECK_SHELL_FEATURES])dnl +m4_require([_LT_PREPARE_MUNGE_PATH_LIST])dnl +AC_MSG_CHECKING([dynamic linker characteristics]) +m4_if([$1], + [], [ +if test yes = "$GCC"; then + case $host_os in + darwin*) lt_awk_arg='/^libraries:/,/LR/' ;; + *) lt_awk_arg='/^libraries:/' ;; + esac + case $host_os in + mingw* | cegcc*) lt_sed_strip_eq='s|=\([[A-Za-z]]:\)|\1|g' ;; + *) lt_sed_strip_eq='s|=/|/|g' ;; + esac + lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` + case $lt_search_path_spec in + *\;*) + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` + ;; + *) + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` + ;; + esac + # Ok, now we have the path, separated by spaces, we can step through it + # and add multilib dir if necessary... + lt_tmp_lt_search_path_spec= + lt_multi_os_dir=/`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` + # ...but if some path component already ends with the multilib dir we assume + # that all is fine and trust -print-search-dirs as is (GCC 4.2? or newer). + case "$lt_multi_os_dir; $lt_search_path_spec " in + "/; "* | "/.; "* | "/./; "* | *"$lt_multi_os_dir "* | *"$lt_multi_os_dir/ "*) + lt_multi_os_dir= + ;; + esac + for lt_sys_path in $lt_search_path_spec; do + if test -d "$lt_sys_path$lt_multi_os_dir"; then + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path$lt_multi_os_dir" + elif test -n "$lt_multi_os_dir"; then + test -d "$lt_sys_path" && \ + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" + fi + done + lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' +BEGIN {RS = " "; FS = "/|\n";} { + lt_foo = ""; + lt_count = 0; + for (lt_i = NF; lt_i > 0; lt_i--) { + if ($lt_i != "" && $lt_i != ".") { + if ($lt_i == "..") { + lt_count++; + } else { + if (lt_count == 0) { + lt_foo = "/" $lt_i lt_foo; + } else { + lt_count--; + } + } + } + } + if (lt_foo != "") { lt_freq[[lt_foo]]++; } + if (lt_freq[[lt_foo]] == 1) { print lt_foo; } +}'` + # AWK program above erroneously prepends '/' to C:/dos/paths + # for these hosts. + case $host_os in + mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ + $SED 's|/\([[A-Za-z]]:\)|\1|g'` ;; + esac + sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` +else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" +fi]) +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=.so +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +AC_ARG_VAR([LT_SYS_LIBRARY_PATH], +[User-defined run-time library search path.]) + +case $host_os in +aix3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='$libname$release$shared_ext$major' + ;; + +aix[[4-9]]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test ia64 = "$host_cpu"; then + # AIX 5 supports IA64 + library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line '#! .'. This would cause the generated library to + # depend on '.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[[01]] | aix4.[[01]].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # Using Import Files as archive members, it is possible to support + # filename-based versioning of shared library archives on AIX. While + # this would work for both with and without runtime linking, it will + # prevent static linking of such archives. So we do filename-based + # shared library versioning with .so extension only, which is used + # when both runtime linking and shared linking is enabled. + # Unfortunately, runtime linking may impact performance, so we do + # not want this to be the default eventually. Also, we use the + # versioned .so libs for executables only if there is the -brtl + # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only. + # To allow for filename-based versioning support, we need to create + # libNAME.so.V as an archive file, containing: + # *) an Import File, referring to the versioned filename of the + # archive as well as the shared archive member, telling the + # bitwidth (32 or 64) of that shared object, and providing the + # list of exported symbols of that shared object, eventually + # decorated with the 'weak' keyword + # *) the shared object with the F_LOADONLY flag set, to really avoid + # it being seen by the linker. + # At run time we better use the real file rather than another symlink, + # but for link time we create the symlink libNAME.so -> libNAME.so.V + + case $with_aix_soname,$aix_use_runtimelinking in + # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + aix,yes) # traditional libtool + dynamic_linker='AIX unversionable lib.so' + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + ;; + aix,no) # traditional AIX only + dynamic_linker='AIX lib.a[(]lib.so.V[)]' + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='$libname$release.a $libname.a' + soname_spec='$libname$release$shared_ext$major' + ;; + svr4,*) # full svr4 only + dynamic_linker="AIX lib.so.V[(]$shared_archive_member_spec.o[)]" + library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' + # We do not specify a path in Import Files, so LIBPATH fires. + shlibpath_overrides_runpath=yes + ;; + *,yes) # both, prefer svr4 + dynamic_linker="AIX lib.so.V[(]$shared_archive_member_spec.o[)], lib.a[(]lib.so.V[)]" + library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' + # unpreferred sharedlib libNAME.a needs extra handling + postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"' + postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"' + # We do not specify a path in Import Files, so LIBPATH fires. + shlibpath_overrides_runpath=yes + ;; + *,no) # both, prefer aix + dynamic_linker="AIX lib.a[(]lib.so.V[)], lib.so.V[(]$shared_archive_member_spec.o[)]" + library_names_spec='$libname$release.a $libname.a' + soname_spec='$libname$release$shared_ext$major' + # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling + postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)' + postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"' + ;; + esac + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + case $host_cpu in + powerpc) + # Since July 2007 AmigaOS4 officially supports .so libraries. + # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + ;; + m68k) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + esac + ;; + +beos*) + library_names_spec='$libname$shared_ext' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[[45]]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32* | cegcc*) + version_type=windows + shrext_cmds=.dll + need_version=no + need_lib_prefix=no + + case $GCC,$cc_basename in + yes,*) + # gcc + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' +m4_if([$1], [],[ + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"]) + ;; + mingw* | cegcc*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' + ;; + esac + dynamic_linker='Win32 ld.exe' + ;; + + *,cl*) + # Native MSVC + libname_spec='$name' + soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' + library_names_spec='$libname.dll.lib' + + case $build_os in + mingw*) + sys_lib_search_path_spec= + lt_save_ifs=$IFS + IFS=';' + for lt_path in $LIB + do + IFS=$lt_save_ifs + # Let DOS variable expansion print the short 8.3 style file name. + lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` + sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" + done + IFS=$lt_save_ifs + # Convert to MSYS style. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'` + ;; + cygwin*) + # Convert to unix form, then to dos form, then back to unix form + # but this time dos style (no spaces!) so that the unix form looks + # like /cygdrive/c/PROGRA~1:/cygdr... + sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` + sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` + sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + ;; + *) + sys_lib_search_path_spec=$LIB + if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then + # It is most probably a Windows format PATH. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + # FIXME: find the short name or the path components, as spaces are + # common. (e.g. "Program Files" -> "PROGRA~1") + ;; + esac + + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + dynamic_linker='Win32 link.exe' + ;; + + *) + # Assume MSVC wrapper + library_names_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext $libname.lib' + dynamic_linker='Win32 ld.exe' + ;; + esac + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$major$shared_ext $libname$shared_ext' + soname_spec='$libname$release$major$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' +m4_if([$1], [],[ + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"]) + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[[23]].*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2.*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[[01]]* | freebsdelf3.[[01]]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \ + freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +haiku*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + dynamic_linker="$host_os runtime_loader" + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LIBRARY_PATH + shlibpath_overrides_runpath=no + sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + if test 32 = "$HPUX_IA64_MODE"; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + sys_lib_dlsearch_path_spec=/usr/lib/hpux32 + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + sys_lib_dlsearch_path_spec=/usr/lib/hpux64 + fi + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555, ... + postinstall_cmds='chmod 555 $lib' + # or fails outright, so override atomically: + install_override_mode=555 + ;; + +interix[[3-9]]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test yes = "$lt_cv_prog_gnu_ld"; then + version_type=linux # correct to gnu/linux during the next big refactor + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='$libname$release$shared_ext$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff" + sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +linux*android*) + version_type=none # Android doesn't support versioned libraries. + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext' + soname_spec='$libname$release$shared_ext' + finish_cmds= + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + dynamic_linker='Android linker' + # Don't embed -rpath directories since the linker doesn't support them. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + + # Some binutils ld are patched to set DT_RUNPATH + AC_CACHE_VAL([lt_cv_shlibpath_overrides_runpath], + [lt_cv_shlibpath_overrides_runpath=no + save_LDFLAGS=$LDFLAGS + save_libdir=$libdir + eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \ + LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\"" + AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], + [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null], + [lt_cv_shlibpath_overrides_runpath=yes])]) + LDFLAGS=$save_LDFLAGS + libdir=$save_libdir + ]) + shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Ideally, we could use ldconfig to report *all* directores which are + # searched for libraries, however this is still not possible. Aside from not + # being certain /sbin/ldconfig is available, command + # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64, + # even though it is searched at run-time. Try to do the best guess by + # appending ld.so.conf contents (and includes) to the search path. + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsdelf*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='NetBSD ld.elf_so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +*nto* | *qnx*) + version_type=qnx + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='ldqnx.so' + ;; + +openbsd* | bitrig*) + version_type=sunos + sys_lib_dlsearch_path_spec=/usr/lib + need_lib_prefix=no + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then + need_version=no + else + need_version=yes + fi + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +os2*) + libname_spec='$name' + version_type=windows + shrext_cmds=.dll + need_version=no + need_lib_prefix=no + # OS/2 can only load a DLL with a base name of 8 characters or less. + soname_spec='`test -n "$os2dllname" && libname="$os2dllname"; + v=$($ECHO $release$versuffix | tr -d .-); + n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _); + $ECHO $n$v`$shared_ext' + library_names_spec='${libname}_dll.$libext' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=BEGINLIBPATH + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='$libname$release$shared_ext$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + +rdos*) + dynamic_linker=no + ;; + +solaris*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test yes = "$with_gnu_ld"; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec; then + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext' + soname_spec='$libname$shared_ext.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=sco + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + if test yes = "$with_gnu_ld"; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +tpf*) + # TPF is a cross-target only. Preferred cross-host = GNU/Linux. + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +uts4*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +AC_MSG_RESULT([$dynamic_linker]) +test no = "$dynamic_linker" && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test yes = "$GCC"; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then + sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec +fi + +if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then + sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec +fi + +# remember unaugmented sys_lib_dlsearch_path content for libtool script decls... +configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec + +# ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code +func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH" + +# to be used as default LT_SYS_LIBRARY_PATH value in generated libtool +configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH + +_LT_DECL([], [variables_saved_for_relink], [1], + [Variables whose values should be saved in libtool wrapper scripts and + restored at link time]) +_LT_DECL([], [need_lib_prefix], [0], + [Do we need the "lib" prefix for modules?]) +_LT_DECL([], [need_version], [0], [Do we need a version for libraries?]) +_LT_DECL([], [version_type], [0], [Library versioning type]) +_LT_DECL([], [runpath_var], [0], [Shared library runtime path variable]) +_LT_DECL([], [shlibpath_var], [0],[Shared library path variable]) +_LT_DECL([], [shlibpath_overrides_runpath], [0], + [Is shlibpath searched before the hard-coded library search path?]) +_LT_DECL([], [libname_spec], [1], [Format of library name prefix]) +_LT_DECL([], [library_names_spec], [1], + [[List of archive names. First name is the real one, the rest are links. + The last name is the one that the linker finds with -lNAME]]) +_LT_DECL([], [soname_spec], [1], + [[The coded name of the library, if different from the real name]]) +_LT_DECL([], [install_override_mode], [1], + [Permission mode override for installation of shared libraries]) +_LT_DECL([], [postinstall_cmds], [2], + [Command to use after installation of a shared archive]) +_LT_DECL([], [postuninstall_cmds], [2], + [Command to use after uninstallation of a shared archive]) +_LT_DECL([], [finish_cmds], [2], + [Commands used to finish a libtool library installation in a directory]) +_LT_DECL([], [finish_eval], [1], + [[As "finish_cmds", except a single script fragment to be evaled but + not shown]]) +_LT_DECL([], [hardcode_into_libs], [0], + [Whether we should hardcode library paths into libraries]) +_LT_DECL([], [sys_lib_search_path_spec], [2], + [Compile-time system search path for libraries]) +_LT_DECL([sys_lib_dlsearch_path_spec], [configure_time_dlsearch_path], [2], + [Detected run-time system search path for libraries]) +_LT_DECL([], [configure_time_lt_sys_library_path], [2], + [Explicit LT_SYS_LIBRARY_PATH set during ./configure time]) +])# _LT_SYS_DYNAMIC_LINKER + + +# _LT_PATH_TOOL_PREFIX(TOOL) +# -------------------------- +# find a file program that can recognize shared library +AC_DEFUN([_LT_PATH_TOOL_PREFIX], +[m4_require([_LT_DECL_EGREP])dnl +AC_MSG_CHECKING([for $1]) +AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, +[case $MAGIC_CMD in +[[\\/*] | ?:[\\/]*]) + lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD=$MAGIC_CMD + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR +dnl $ac_dummy forces splitting on constant user-supplied paths. +dnl POSIX.2 word splitting is done only on the output of word expansions, +dnl not every word. This closes a longstanding sh security hole. + ac_dummy="m4_if([$2], , $PATH, [$2])" + for ac_dir in $ac_dummy; do + IFS=$lt_save_ifs + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$1"; then + lt_cv_path_MAGIC_CMD=$ac_dir/"$1" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD=$lt_cv_path_MAGIC_CMD + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS=$lt_save_ifs + MAGIC_CMD=$lt_save_MAGIC_CMD + ;; +esac]) +MAGIC_CMD=$lt_cv_path_MAGIC_CMD +if test -n "$MAGIC_CMD"; then + AC_MSG_RESULT($MAGIC_CMD) +else + AC_MSG_RESULT(no) +fi +_LT_DECL([], [MAGIC_CMD], [0], + [Used to examine libraries when file_magic_cmd begins with "file"])dnl +])# _LT_PATH_TOOL_PREFIX + +# Old name: +AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], []) + + +# _LT_PATH_MAGIC +# -------------- +# find a file program that can recognize a shared library +m4_defun([_LT_PATH_MAGIC], +[_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH) +if test -z "$lt_cv_path_MAGIC_CMD"; then + if test -n "$ac_tool_prefix"; then + _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH) + else + MAGIC_CMD=: + fi +fi +])# _LT_PATH_MAGIC + + +# LT_PATH_LD +# ---------- +# find the pathname to the GNU or non-GNU linker +AC_DEFUN([LT_PATH_LD], +[AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_PROG_ECHO_BACKSLASH])dnl + +AC_ARG_WITH([gnu-ld], + [AS_HELP_STRING([--with-gnu-ld], + [assume the C compiler uses GNU ld @<:@default=no@:>@])], + [test no = "$withval" || with_gnu_ld=yes], + [with_gnu_ld=no])dnl + +ac_prog=ld +if test yes = "$GCC"; then + # Check if gcc -print-prog-name=ld gives a path. + AC_MSG_CHECKING([for ld used by $CC]) + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return, which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [[\\/]]* | ?:[[\\/]]*) + re_direlt='/[[^/]][[^/]]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` + while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do + ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD=$ac_prog + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test yes = "$with_gnu_ld"; then + AC_MSG_CHECKING([for GNU ld]) +else + AC_MSG_CHECKING([for non-GNU ld]) +fi +AC_CACHE_VAL(lt_cv_path_LD, +[if test -z "$LD"; then + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS=$lt_save_ifs + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD=$ac_dir/$ac_prog + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 &1 conftest.i +cat conftest.i conftest.i >conftest2.i +: ${lt_DD:=$DD} +AC_PATH_PROGS_FEATURE_CHECK([lt_DD], [dd], +[if "$ac_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then + cmp -s conftest.i conftest.out \ + && ac_cv_path_lt_DD="$ac_path_lt_DD" ac_path_lt_DD_found=: +fi]) +rm -f conftest.i conftest2.i conftest.out]) +])# _LT_PATH_DD + + +# _LT_CMD_TRUNCATE +# ---------------- +# find command to truncate a binary pipe +m4_defun([_LT_CMD_TRUNCATE], +[m4_require([_LT_PATH_DD]) +AC_CACHE_CHECK([how to truncate binary pipes], [lt_cv_truncate_bin], +[printf 0123456789abcdef0123456789abcdef >conftest.i +cat conftest.i conftest.i >conftest2.i +lt_cv_truncate_bin= +if "$ac_cv_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then + cmp -s conftest.i conftest.out \ + && lt_cv_truncate_bin="$ac_cv_path_lt_DD bs=4096 count=1" +fi +rm -f conftest.i conftest2.i conftest.out +test -z "$lt_cv_truncate_bin" && lt_cv_truncate_bin="$SED -e 4q"]) +_LT_DECL([lt_truncate_bin], [lt_cv_truncate_bin], [1], + [Command to truncate a binary pipe]) +])# _LT_CMD_TRUNCATE + + +# _LT_CHECK_MAGIC_METHOD +# ---------------------- +# how to check for library dependencies +# -- PORTME fill in with the dynamic library characteristics +m4_defun([_LT_CHECK_MAGIC_METHOD], +[m4_require([_LT_DECL_EGREP]) +m4_require([_LT_DECL_OBJDUMP]) +AC_CACHE_CHECK([how to recognize dependent libraries], +lt_cv_deplibs_check_method, +[lt_cv_file_magic_cmd='$MAGIC_CMD' +lt_cv_file_magic_test_file= +lt_cv_deplibs_check_method='unknown' +# Need to set the preceding variable on all platforms that support +# interlibrary dependencies. +# 'none' -- dependencies not supported. +# 'unknown' -- same as none, but documents that we really don't know. +# 'pass_all' -- all dependencies passed with no checks. +# 'test_compile' -- check by making test program. +# 'file_magic [[regex]]' -- check by looking for files in library path +# that responds to the $file_magic_cmd with a given extended regex. +# If you have 'file' or equivalent on your system and you're not sure +# whether 'pass_all' will *always* work, you probably want this one. + +case $host_os in +aix[[4-9]]*) + lt_cv_deplibs_check_method=pass_all + ;; + +beos*) + lt_cv_deplibs_check_method=pass_all + ;; + +bsdi[[45]]*) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib)' + lt_cv_file_magic_cmd='/usr/bin/file -L' + lt_cv_file_magic_test_file=/shlib/libc.so + ;; + +cygwin*) + # func_win32_libid is a shell function defined in ltmain.sh + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + ;; + +mingw* | pw32*) + # Base MSYS/MinGW do not provide the 'file' command needed by + # func_win32_libid shell function, so use a weaker test based on 'objdump', + # unless we find 'file', for example because we are cross-compiling. + if ( file / ) >/dev/null 2>&1; then + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + else + # Keep this pattern in sync with the one in func_win32_libid. + lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' + lt_cv_file_magic_cmd='$OBJDUMP -f' + fi + ;; + +cegcc*) + # use the weaker test based on 'objdump'. See mingw*. + lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + ;; + +darwin* | rhapsody*) + lt_cv_deplibs_check_method=pass_all + ;; + +freebsd* | dragonfly*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + case $host_cpu in + i*86 ) + # Not sure whether the presence of OpenBSD here was a mistake. + # Let's accept both of them until this is cleared up. + lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + ;; + esac + else + lt_cv_deplibs_check_method=pass_all + fi + ;; + +haiku*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20* | hpux11*) + lt_cv_file_magic_cmd=/usr/bin/file + case $host_cpu in + ia64*) + lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' + lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so + ;; + hppa*64*) + [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]'] + lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl + ;; + *) + lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]]\.[[0-9]]) shared library' + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + esac + ;; + +interix[[3-9]]*) + # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$' + ;; + +irix5* | irix6* | nonstopux*) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$' + fi + ;; + +newos6*) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +*nto* | *qnx*) + lt_cv_deplibs_check_method=pass_all + ;; + +openbsd* | bitrig*) + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' + fi + ;; + +osf3* | osf4* | osf5*) + lt_cv_deplibs_check_method=pass_all + ;; + +rdos*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv4 | sysv4.3*) + case $host_vendor in + motorola) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]' + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + ncr) + lt_cv_deplibs_check_method=pass_all + ;; + sequent) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' + ;; + sni) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib" + lt_cv_file_magic_test_file=/lib/libc.so + ;; + siemens) + lt_cv_deplibs_check_method=pass_all + ;; + pc) + lt_cv_deplibs_check_method=pass_all + ;; + esac + ;; + +tpf*) + lt_cv_deplibs_check_method=pass_all + ;; +os2*) + lt_cv_deplibs_check_method=pass_all + ;; +esac +]) + +file_magic_glob= +want_nocaseglob=no +if test "$build" = "$host"; then + case $host_os in + mingw* | pw32*) + if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then + want_nocaseglob=yes + else + file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[[\1]]\/[[\1]]\/g;/g"` + fi + ;; + esac +fi + +file_magic_cmd=$lt_cv_file_magic_cmd +deplibs_check_method=$lt_cv_deplibs_check_method +test -z "$deplibs_check_method" && deplibs_check_method=unknown + +_LT_DECL([], [deplibs_check_method], [1], + [Method to check whether dependent libraries are shared objects]) +_LT_DECL([], [file_magic_cmd], [1], + [Command to use when deplibs_check_method = "file_magic"]) +_LT_DECL([], [file_magic_glob], [1], + [How to find potential files when deplibs_check_method = "file_magic"]) +_LT_DECL([], [want_nocaseglob], [1], + [Find potential files using nocaseglob when deplibs_check_method = "file_magic"]) +])# _LT_CHECK_MAGIC_METHOD + + +# LT_PATH_NM +# ---------- +# find the pathname to a BSD- or MS-compatible name lister +AC_DEFUN([LT_PATH_NM], +[AC_REQUIRE([AC_PROG_CC])dnl +AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM, +[if test -n "$NM"; then + # Let the user override the test. + lt_cv_path_NM=$NM +else + lt_nm_to_check=${ac_tool_prefix}nm + if test -n "$ac_tool_prefix" && test "$build" = "$host"; then + lt_nm_to_check="$lt_nm_to_check nm" + fi + for lt_tmp_nm in $lt_nm_to_check; do + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR + for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do + IFS=$lt_save_ifs + test -z "$ac_dir" && ac_dir=. + tmp_nm=$ac_dir/$lt_tmp_nm + if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext"; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the 'sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + # Tru64's nm complains that /dev/null is an invalid object file + # MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty + case $build_os in + mingw*) lt_bad_file=conftest.nm/nofile ;; + *) lt_bad_file=/dev/null ;; + esac + case `"$tmp_nm" -B $lt_bad_file 2>&1 | sed '1q'` in + *$lt_bad_file* | *'Invalid file or object type'*) + lt_cv_path_NM="$tmp_nm -B" + break 2 + ;; + *) + case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in + */dev/null*) + lt_cv_path_NM="$tmp_nm -p" + break 2 + ;; + *) + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + ;; + esac + ;; + esac + fi + done + IFS=$lt_save_ifs + done + : ${lt_cv_path_NM=no} +fi]) +if test no != "$lt_cv_path_NM"; then + NM=$lt_cv_path_NM +else + # Didn't find any BSD compatible name lister, look for dumpbin. + if test -n "$DUMPBIN"; then : + # Let the user override the test. + else + AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :) + case `$DUMPBIN -symbols -headers /dev/null 2>&1 | sed '1q'` in + *COFF*) + DUMPBIN="$DUMPBIN -symbols -headers" + ;; + *) + DUMPBIN=: + ;; + esac + fi + AC_SUBST([DUMPBIN]) + if test : != "$DUMPBIN"; then + NM=$DUMPBIN + fi +fi +test -z "$NM" && NM=nm +AC_SUBST([NM]) +_LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl + +AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface], + [lt_cv_nm_interface="BSD nm" + echo "int some_variable = 0;" > conftest.$ac_ext + (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$ac_compile" 2>conftest.err) + cat conftest.err >&AS_MESSAGE_LOG_FD + (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD) + (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) + cat conftest.err >&AS_MESSAGE_LOG_FD + (eval echo "\"\$as_me:$LINENO: output\"" >&AS_MESSAGE_LOG_FD) + cat conftest.out >&AS_MESSAGE_LOG_FD + if $GREP 'External.*some_variable' conftest.out > /dev/null; then + lt_cv_nm_interface="MS dumpbin" + fi + rm -f conftest*]) +])# LT_PATH_NM + +# Old names: +AU_ALIAS([AM_PROG_NM], [LT_PATH_NM]) +AU_ALIAS([AC_PROG_NM], [LT_PATH_NM]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AM_PROG_NM], []) +dnl AC_DEFUN([AC_PROG_NM], []) + +# _LT_CHECK_SHAREDLIB_FROM_LINKLIB +# -------------------------------- +# how to determine the name of the shared library +# associated with a specific link library. +# -- PORTME fill in with the dynamic library characteristics +m4_defun([_LT_CHECK_SHAREDLIB_FROM_LINKLIB], +[m4_require([_LT_DECL_EGREP]) +m4_require([_LT_DECL_OBJDUMP]) +m4_require([_LT_DECL_DLLTOOL]) +AC_CACHE_CHECK([how to associate runtime and link libraries], +lt_cv_sharedlib_from_linklib_cmd, +[lt_cv_sharedlib_from_linklib_cmd='unknown' + +case $host_os in +cygwin* | mingw* | pw32* | cegcc*) + # two different shell functions defined in ltmain.sh; + # decide which one to use based on capabilities of $DLLTOOL + case `$DLLTOOL --help 2>&1` in + *--identify-strict*) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib + ;; + *) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback + ;; + esac + ;; +*) + # fallback: assume linklib IS sharedlib + lt_cv_sharedlib_from_linklib_cmd=$ECHO + ;; +esac +]) +sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd +test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO + +_LT_DECL([], [sharedlib_from_linklib_cmd], [1], + [Command to associate shared and link libraries]) +])# _LT_CHECK_SHAREDLIB_FROM_LINKLIB + + +# _LT_PATH_MANIFEST_TOOL +# ---------------------- +# locate the manifest tool +m4_defun([_LT_PATH_MANIFEST_TOOL], +[AC_CHECK_TOOL(MANIFEST_TOOL, mt, :) +test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt +AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool], + [lt_cv_path_mainfest_tool=no + echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&AS_MESSAGE_LOG_FD + $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out + cat conftest.err >&AS_MESSAGE_LOG_FD + if $GREP 'Manifest Tool' conftest.out > /dev/null; then + lt_cv_path_mainfest_tool=yes + fi + rm -f conftest*]) +if test yes != "$lt_cv_path_mainfest_tool"; then + MANIFEST_TOOL=: +fi +_LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl +])# _LT_PATH_MANIFEST_TOOL + + +# _LT_DLL_DEF_P([FILE]) +# --------------------- +# True iff FILE is a Windows DLL '.def' file. +# Keep in sync with func_dll_def_p in the libtool script +AC_DEFUN([_LT_DLL_DEF_P], +[dnl + test DEF = "`$SED -n dnl + -e '\''s/^[[ ]]*//'\'' dnl Strip leading whitespace + -e '\''/^\(;.*\)*$/d'\'' dnl Delete empty lines and comments + -e '\''s/^\(EXPORTS\|LIBRARY\)\([[ ]].*\)*$/DEF/p'\'' dnl + -e q dnl Only consider the first "real" line + $1`" dnl +])# _LT_DLL_DEF_P + + +# LT_LIB_M +# -------- +# check for math library +AC_DEFUN([LT_LIB_M], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +LIBM= +case $host in +*-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*) + # These system don't have libm, or don't need it + ;; +*-ncr-sysv4.3*) + AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM=-lmw) + AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm") + ;; +*) + AC_CHECK_LIB(m, cos, LIBM=-lm) + ;; +esac +AC_SUBST([LIBM]) +])# LT_LIB_M + +# Old name: +AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_CHECK_LIBM], []) + + +# _LT_COMPILER_NO_RTTI([TAGNAME]) +# ------------------------------- +m4_defun([_LT_COMPILER_NO_RTTI], +[m4_require([_LT_TAG_COMPILER])dnl + +_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= + +if test yes = "$GCC"; then + case $cc_basename in + nvcc*) + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -Xcompiler -fno-builtin' ;; + *) + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' ;; + esac + + _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions], + lt_cv_prog_compiler_rtti_exceptions, + [-fno-rtti -fno-exceptions], [], + [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"]) +fi +_LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1], + [Compiler flag to turn off builtin functions]) +])# _LT_COMPILER_NO_RTTI + + +# _LT_CMD_GLOBAL_SYMBOLS +# ---------------------- +m4_defun([_LT_CMD_GLOBAL_SYMBOLS], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_PROG_AWK])dnl +AC_REQUIRE([LT_PATH_NM])dnl +AC_REQUIRE([LT_PATH_LD])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_TAG_COMPILER])dnl + +# Check for command to grab the raw symbol name followed by C symbol from nm. +AC_MSG_CHECKING([command to parse $NM output from $compiler object]) +AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], +[ +# These are sane defaults that work on at least a few old systems. +# [They come from Ultrix. What could be older than Ultrix?!! ;)] + +# Character class describing NM global symbol codes. +symcode='[[BCDEGRST]]' + +# Regexp to match symbols that can be accessed directly from C. +sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)' + +# Define system-specific variables. +case $host_os in +aix*) + symcode='[[BCDT]]' + ;; +cygwin* | mingw* | pw32* | cegcc*) + symcode='[[ABCDGISTW]]' + ;; +hpux*) + if test ia64 = "$host_cpu"; then + symcode='[[ABCDEGRST]]' + fi + ;; +irix* | nonstopux*) + symcode='[[BCDEGRST]]' + ;; +osf*) + symcode='[[BCDEGQRST]]' + ;; +solaris*) + symcode='[[BDRT]]' + ;; +sco3.2v5*) + symcode='[[DT]]' + ;; +sysv4.2uw2*) + symcode='[[DT]]' + ;; +sysv5* | sco5v6* | unixware* | OpenUNIX*) + symcode='[[ABDT]]' + ;; +sysv4) + symcode='[[DFNSTU]]' + ;; +esac + +# If we're using GNU nm, then use its standard symbol codes. +case `$NM -V 2>&1` in +*GNU* | *'with BFD'*) + symcode='[[ABCDGIRSTW]]' ;; +esac + +if test "$lt_cv_nm_interface" = "MS dumpbin"; then + # Gets list of data symbols to import. + lt_cv_sys_global_symbol_to_import="sed -n -e 's/^I .* \(.*\)$/\1/p'" + # Adjust the below global symbol transforms to fixup imported variables. + lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'" + lt_c_name_hook=" -e 's/^I .* \(.*\)$/ {\"\1\", (void *) 0},/p'" + lt_c_name_lib_hook="\ + -e 's/^I .* \(lib.*\)$/ {\"\1\", (void *) 0},/p'\ + -e 's/^I .* \(.*\)$/ {\"lib\1\", (void *) 0},/p'" +else + # Disable hooks by default. + lt_cv_sys_global_symbol_to_import= + lt_cdecl_hook= + lt_c_name_hook= + lt_c_name_lib_hook= +fi + +# Transform an extracted symbol line into a proper C declaration. +# Some systems (esp. on ia64) link data and code symbols differently, +# so use this general approach. +lt_cv_sys_global_symbol_to_cdecl="sed -n"\ +$lt_cdecl_hook\ +" -e 's/^T .* \(.*\)$/extern int \1();/p'"\ +" -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'" + +# Transform an extracted symbol line into symbol name and symbol address +lt_cv_sys_global_symbol_to_c_name_address="sed -n"\ +$lt_c_name_hook\ +" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ +" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/p'" + +# Transform an extracted symbol line into symbol name with lib prefix and +# symbol address. +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n"\ +$lt_c_name_lib_hook\ +" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ +" -e 's/^$symcode$symcode* .* \(lib.*\)$/ {\"\1\", (void *) \&\1},/p'"\ +" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"lib\1\", (void *) \&\1},/p'" + +# Handle CRLF in mingw tool chain +opt_cr= +case $build_os in +mingw*) + opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp + ;; +esac + +# Try without a prefix underscore, then with it. +for ac_symprfx in "" "_"; do + + # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. + symxfrm="\\1 $ac_symprfx\\2 \\2" + + # Write the raw and C identifiers. + if test "$lt_cv_nm_interface" = "MS dumpbin"; then + # Fake it for dumpbin and say T for any non-static function, + # D for any global variable and I for any imported variable. + # Also find C++ and __fastcall symbols from MSVC++, + # which start with @ or ?. + lt_cv_sys_global_symbol_pipe="$AWK ['"\ +" {last_section=section; section=\$ 3};"\ +" /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ +" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ +" /^ *Symbol name *: /{split(\$ 0,sn,\":\"); si=substr(sn[2],2)};"\ +" /^ *Type *: code/{print \"T\",si,substr(si,length(prfx))};"\ +" /^ *Type *: data/{print \"I\",si,substr(si,length(prfx))};"\ +" \$ 0!~/External *\|/{next};"\ +" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ +" {if(hide[section]) next};"\ +" {f=\"D\"}; \$ 0~/\(\).*\|/{f=\"T\"};"\ +" {split(\$ 0,a,/\||\r/); split(a[2],s)};"\ +" s[1]~/^[@?]/{print f,s[1],s[1]; next};"\ +" s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\ +" ' prfx=^$ac_symprfx]" + else + lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" + fi + lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" + + # Check to see that the pipe works correctly. + pipe_works=no + + rm -f conftest* + cat > conftest.$ac_ext <<_LT_EOF +#ifdef __cplusplus +extern "C" { +#endif +char nm_test_var; +void nm_test_func(void); +void nm_test_func(void){} +#ifdef __cplusplus +} +#endif +int main(){nm_test_var='a';nm_test_func();return(0);} +_LT_EOF + + if AC_TRY_EVAL(ac_compile); then + # Now try to grab the symbols. + nlist=conftest.nm + $ECHO "$as_me:$LINENO: $NM conftest.$ac_objext | $lt_cv_sys_global_symbol_pipe > $nlist" >&AS_MESSAGE_LOG_FD + if eval "$NM" conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist 2>&AS_MESSAGE_LOG_FD && test -s "$nlist"; then + # Try sorting and uniquifying the output. + if sort "$nlist" | uniq > "$nlist"T; then + mv -f "$nlist"T "$nlist" + else + rm -f "$nlist"T + fi + + # Make sure that we snagged all the symbols we need. + if $GREP ' nm_test_var$' "$nlist" >/dev/null; then + if $GREP ' nm_test_func$' "$nlist" >/dev/null; then + cat <<_LT_EOF > conftest.$ac_ext +/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ +#if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE +/* DATA imports from DLLs on WIN32 can't be const, because runtime + relocations are performed -- see ld's documentation on pseudo-relocs. */ +# define LT@&t@_DLSYM_CONST +#elif defined __osf__ +/* This system does not cope well with relocations in const data. */ +# define LT@&t@_DLSYM_CONST +#else +# define LT@&t@_DLSYM_CONST const +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +_LT_EOF + # Now generate the symbol file. + eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' + + cat <<_LT_EOF >> conftest.$ac_ext + +/* The mapping between symbol names and symbols. */ +LT@&t@_DLSYM_CONST struct { + const char *name; + void *address; +} +lt__PROGRAM__LTX_preloaded_symbols[[]] = +{ + { "@PROGRAM@", (void *) 0 }, +_LT_EOF + $SED "s/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext + cat <<\_LT_EOF >> conftest.$ac_ext + {0, (void *) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt__PROGRAM__LTX_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif +_LT_EOF + # Now try linking the two files. + mv conftest.$ac_objext conftstm.$ac_objext + lt_globsym_save_LIBS=$LIBS + lt_globsym_save_CFLAGS=$CFLAGS + LIBS=conftstm.$ac_objext + CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)" + if AC_TRY_EVAL(ac_link) && test -s conftest$ac_exeext; then + pipe_works=yes + fi + LIBS=$lt_globsym_save_LIBS + CFLAGS=$lt_globsym_save_CFLAGS + else + echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD + fi + else + echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD + fi + else + echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD + fi + else + echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD + cat conftest.$ac_ext >&5 + fi + rm -rf conftest* conftst* + + # Do not use the global_symbol_pipe unless it works. + if test yes = "$pipe_works"; then + break + else + lt_cv_sys_global_symbol_pipe= + fi +done +]) +if test -z "$lt_cv_sys_global_symbol_pipe"; then + lt_cv_sys_global_symbol_to_cdecl= +fi +if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then + AC_MSG_RESULT(failed) +else + AC_MSG_RESULT(ok) +fi + +# Response file support. +if test "$lt_cv_nm_interface" = "MS dumpbin"; then + nm_file_list_spec='@' +elif $NM --help 2>/dev/null | grep '[[@]]FILE' >/dev/null; then + nm_file_list_spec='@' +fi + +_LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1], + [Take the output of nm and produce a listing of raw symbols and C names]) +_LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1], + [Transform the output of nm in a proper C declaration]) +_LT_DECL([global_symbol_to_import], [lt_cv_sys_global_symbol_to_import], [1], + [Transform the output of nm into a list of symbols to manually relocate]) +_LT_DECL([global_symbol_to_c_name_address], + [lt_cv_sys_global_symbol_to_c_name_address], [1], + [Transform the output of nm in a C name address pair]) +_LT_DECL([global_symbol_to_c_name_address_lib_prefix], + [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1], + [Transform the output of nm in a C name address pair when lib prefix is needed]) +_LT_DECL([nm_interface], [lt_cv_nm_interface], [1], + [The name lister interface]) +_LT_DECL([], [nm_file_list_spec], [1], + [Specify filename containing input files for $NM]) +]) # _LT_CMD_GLOBAL_SYMBOLS + + +# _LT_COMPILER_PIC([TAGNAME]) +# --------------------------- +m4_defun([_LT_COMPILER_PIC], +[m4_require([_LT_TAG_COMPILER])dnl +_LT_TAGVAR(lt_prog_compiler_wl, $1)= +_LT_TAGVAR(lt_prog_compiler_pic, $1)= +_LT_TAGVAR(lt_prog_compiler_static, $1)= + +m4_if([$1], [CXX], [ + # C++ specific cases for pic, static, wl, etc. + if test yes = "$GXX"; then + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test ia64 = "$host_cpu"; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the '-m68020' flag to GCC prevents building anything better, + # like '-m68040'. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + mingw* | cygwin* | os2* | pw32* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + case $host_os in + os2*) + _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static' + ;; + esac + ;; + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' + ;; + *djgpp*) + # DJGPP does not support shared libraries at all + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + ;; + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + _LT_TAGVAR(lt_prog_compiler_static, $1)= + ;; + interix[[3-9]]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic + fi + ;; + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + else + case $host_os in + aix[[4-9]]*) + # All AIX code is PIC. + if test ia64 = "$host_cpu"; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + else + _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' + fi + ;; + chorus*) + case $cc_basename in + cxch68*) + # Green Hills C++ Compiler + # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" + ;; + esac + ;; + mingw* | cygwin* | os2* | pw32* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + ;; + dgux*) + case $cc_basename in + ec++*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + ;; + ghcx*) + # Green Hills C++ Compiler + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + *) + ;; + esac + ;; + freebsd* | dragonfly*) + # FreeBSD uses GNU C++ + ;; + hpux9* | hpux10* | hpux11*) + case $cc_basename in + CC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive' + if test ia64 != "$host_cpu"; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + fi + ;; + aCC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive' + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + ;; + esac + ;; + *) + ;; + esac + ;; + interix*) + # This is c89, which is MS Visual C++ (no shared libs) + # Anyone wants to do a port? + ;; + irix5* | irix6* | nonstopux*) + case $cc_basename in + CC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + # CC pic flag -KPIC is the default. + ;; + *) + ;; + esac + ;; + linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + case $cc_basename in + KCC*) + # KAI C++ Compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + ecpc* ) + # old Intel C++ for x86_64, which still supported -KPIC. + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + icpc* ) + # Intel C++, used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + cxx*) + # Compaq C++ + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + xlc* | xlC* | bgxl[[cC]]* | mpixl[[cC]]*) + # IBM XL 8.0, 9.0 on PPC and BlueGene + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + ;; + esac + ;; + esac + ;; + lynxos*) + ;; + m88k*) + ;; + mvs*) + case $cc_basename in + cxx*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall' + ;; + *) + ;; + esac + ;; + netbsd* | netbsdelf*-gnu) + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' + ;; + RCC*) + # Rational C++ 2.4.1 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + cxx*) + # Digital/Compaq C++ + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + *) + ;; + esac + ;; + psos*) + ;; + solaris*) + case $cc_basename in + CC* | sunCC*) + # Sun C++ 4.2, 5.x and Centerline C++ + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + ;; + gcx*) + # Green Hills C++ Compiler + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + ;; + *) + ;; + esac + ;; + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + lcc*) + # Lucid + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + *) + ;; + esac + ;; + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + case $cc_basename in + CC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + esac + ;; + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + ;; + *) + ;; + esac + ;; + vxworks*) + ;; + *) + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + esac + fi +], +[ + if test yes = "$GCC"; then + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test ia64 = "$host_cpu"; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the '-m68020' flag to GCC prevents building anything better, + # like '-m68040'. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + case $host_os in + os2*) + _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static' + ;; + esac + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' + ;; + + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + _LT_TAGVAR(lt_prog_compiler_static, $1)= + ;; + + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + # +Z the default + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + ;; + + interix[[3-9]]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + + msdosdjgpp*) + # Just because we use GCC doesn't mean we suddenly get shared libraries + # on systems that don't support them. + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + enable_shared=no + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic + fi + ;; + + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + + case $cc_basename in + nvcc*) # Cuda Compiler Driver 2.2 + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Xlinker ' + if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)="-Xcompiler $_LT_TAGVAR(lt_prog_compiler_pic, $1)" + fi + ;; + esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in + aix*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + if test ia64 = "$host_cpu"; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + else + _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' + fi + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' + case $cc_basename in + nagfor*) + # NAG Fortran compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + esac + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + case $host_os in + os2*) + _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static' + ;; + esac + ;; + + hpux9* | hpux10* | hpux11*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + ;; + esac + # Is there a better lt_prog_compiler_static that works with the bundled CC? + _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive' + ;; + + irix5* | irix6* | nonstopux*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # PIC (with -KPIC) is the default. + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + case $cc_basename in + # old Intel for x86_64, which still supported -KPIC. + ecc*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + # flang / f18. f95 an alias for gfortran or flang on Debian + flang* | f18* | f95*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + # icc used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + icc* | ifort*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + # Lahey Fortran 8.1. + lf95*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared' + _LT_TAGVAR(lt_prog_compiler_static, $1)='--static' + ;; + nagfor*) + # NAG Fortran compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + tcc*) + # Fabrice Bellard et al's Tiny C Compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group compilers (*not* the Pentium gcc compiler, + # which looks to be a dead project) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + ccc*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # All Alpha code is PIC. + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + xl* | bgxl* | bgf* | mpixl*) + # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [[1-7]].* | *Sun*Fortran*\ 8.[[0-3]]*) + # Sun Fortran 8.3 passes all unrecognized flags to the linker + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='' + ;; + *Sun\ F* | *Sun*Fortran*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + ;; + *Sun\ C*) + # Sun C 5.9 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + ;; + *Intel*\ [[CF]]*Compiler*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + *Portland\ Group*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + esac + ;; + esac + ;; + + newsos6) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + + osf3* | osf4* | osf5*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # All OSF/1 code is PIC. + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + rdos*) + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + solaris*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + case $cc_basename in + f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';; + *) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';; + esac + ;; + + sunos4*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + unicos*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + + uts4*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + *) + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + esac + fi +]) +case $host_os in + # For platforms that do not support PIC, -DPIC is meaningless: + *djgpp*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])" + ;; +esac + +AC_CACHE_CHECK([for $compiler option to produce PIC], + [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)], + [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_prog_compiler_pic, $1)]) +_LT_TAGVAR(lt_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_cv_prog_compiler_pic, $1) + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then + _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works], + [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)], + [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [], + [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in + "" | " "*) ;; + *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;; + esac], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no]) +fi +_LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1], + [Additional compiler flags for building library objects]) + +_LT_TAGDECL([wl], [lt_prog_compiler_wl], [1], + [How to pass a linker flag through the compiler]) +# +# Check to make sure the static flag actually works. +# +wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\" +_LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works], + _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1), + $lt_tmp_static_flag, + [], + [_LT_TAGVAR(lt_prog_compiler_static, $1)=]) +_LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1], + [Compiler flag to prevent dynamic linking]) +])# _LT_COMPILER_PIC + + +# _LT_LINKER_SHLIBS([TAGNAME]) +# ---------------------------- +# See if the linker supports building shared libraries. +m4_defun([_LT_LINKER_SHLIBS], +[AC_REQUIRE([LT_PATH_LD])dnl +AC_REQUIRE([LT_PATH_NM])dnl +m4_require([_LT_PATH_MANIFEST_TOOL])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl +m4_require([_LT_TAG_COMPILER])dnl +AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) +m4_if([$1], [CXX], [ + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] + case $host_os in + aix[[4-9]]*) + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to GNU nm, but means don't demangle to AIX nm. + # Without the "-l" option, or with the "-B" option, AIX nm treats + # weak defined symbols like other global defined symbols, whereas + # GNU nm marks them as "W". + # While the 'weak' keyword is ignored in the Export File, we need + # it in the Import File for the 'aix-soname' feature, so we have + # to replace the "-B" option with "-P" for AIX nm. + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' + else + _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' + fi + ;; + pw32*) + _LT_TAGVAR(export_symbols_cmds, $1)=$ltdll_cmds + ;; + cygwin* | mingw* | cegcc*) + case $cc_basename in + cl*) + _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' + ;; + *) + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] + ;; + esac + ;; + linux* | k*bsd*-gnu | gnu*) + _LT_TAGVAR(link_all_deplibs, $1)=no + ;; + *) + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + ;; + esac +], [ + runpath_var= + _LT_TAGVAR(allow_undefined_flag, $1)= + _LT_TAGVAR(always_export_symbols, $1)=no + _LT_TAGVAR(archive_cmds, $1)= + _LT_TAGVAR(archive_expsym_cmds, $1)= + _LT_TAGVAR(compiler_needs_object, $1)=no + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + _LT_TAGVAR(export_dynamic_flag_spec, $1)= + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(hardcode_automatic, $1)=no + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= + _LT_TAGVAR(hardcode_libdir_separator, $1)= + _LT_TAGVAR(hardcode_minus_L, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported + _LT_TAGVAR(inherit_rpath, $1)=no + _LT_TAGVAR(link_all_deplibs, $1)=unknown + _LT_TAGVAR(module_cmds, $1)= + _LT_TAGVAR(module_expsym_cmds, $1)= + _LT_TAGVAR(old_archive_from_new_cmds, $1)= + _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)= + _LT_TAGVAR(thread_safe_flag_spec, $1)= + _LT_TAGVAR(whole_archive_flag_spec, $1)= + # include_expsyms should be a list of space-separated symbols to be *always* + # included in the symbol list + _LT_TAGVAR(include_expsyms, $1)= + # exclude_expsyms can be an extended regexp of symbols to exclude + # it will be wrapped by ' (' and ')$', so one must not match beginning or + # end of line. Example: 'a|bc|.*d.*' will exclude the symbols 'a' and 'bc', + # as well as any symbol that contains 'd'. + _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] + # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out + # platforms (ab)use it in PIC code, but their linkers get confused if + # the symbol is explicitly referenced. Since portable code cannot + # rely on this symbol name, it's probably fine to never include it in + # preloaded symbol tables. + # Exclude shared library initialization/finalization symbols. +dnl Note also adjust exclude_expsyms for C++ above. + extract_expsyms_cmds= + + case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test yes != "$GCC"; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd* | bitrig*) + with_gnu_ld=no + ;; + linux* | k*bsd*-gnu | gnu*) + _LT_TAGVAR(link_all_deplibs, $1)=no + ;; + esac + + _LT_TAGVAR(ld_shlibs, $1)=yes + + # On some targets, GNU ld is compatible enough with the native linker + # that we're better off using the native interface for both. + lt_use_gnu_ld_interface=no + if test yes = "$with_gnu_ld"; then + case $host_os in + aix*) + # The AIX port of GNU ld has always aspired to compatibility + # with the native linker. However, as the warning in the GNU ld + # block says, versions before 2.19.5* couldn't really create working + # shared libraries, regardless of the interface used. + case `$LD -v 2>&1` in + *\ \(GNU\ Binutils\)\ 2.19.5*) ;; + *\ \(GNU\ Binutils\)\ 2.[[2-9]]*) ;; + *\ \(GNU\ Binutils\)\ [[3-9]]*) ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + fi + + if test yes = "$lt_use_gnu_ld_interface"; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='$wl' + + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + runpath_var=LD_RUN_PATH + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then + _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' + else + _LT_TAGVAR(whole_archive_flag_spec, $1)= + fi + supports_anon_versioning=no + case `$LD -v | $SED -e 's/([^)]\+)\s\+//' 2>&1` in + *GNU\ gold*) supports_anon_versioning=yes ;; + *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 + *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... + *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... + *\ 2.11.*) ;; # other 2.11 versions + *) supports_anon_versioning=yes ;; + esac + + # See if GNU ld supports shared libraries. + case $host_os in + aix[[3-9]]*) + # On AIX/PPC, the GNU linker is very broken + if test ia64 != "$host_cpu"; then + _LT_TAGVAR(ld_shlibs, $1)=no + cat <<_LT_EOF 1>&2 + +*** Warning: the GNU linker, at least up to release 2.19, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to install binutils +*** 2.20 or above, or modify your PATH so that a non-GNU linker is found. +*** You will then need to restart the configuration process. + +_LT_EOF + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='' + ;; + m68k) + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, + # as there is no search path for DLLs. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-all-symbols' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=no + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file, use it as + # is; otherwise, prepend EXPORTS... + _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + haiku*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + os2*) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + shrext_cmds=.dll + _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + prefix_cmds="$SED"~ + if test EXPORTS = "`$SED 1q $export_symbols`"; then + prefix_cmds="$prefix_cmds -e 1d"; + fi~ + prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ + cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + ;; + + interix[[3-9]]*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + + gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) + tmp_diet=no + if test linux-dietlibc = "$host_os"; then + case $cc_basename in + diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) + esac + fi + if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ + && test no = "$tmp_diet" + then + tmp_addflag=' $pic_flag' + tmp_sharedflag='-shared' + case $cc_basename,$host_cpu in + pgcc*) # Portland Group C compiler + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + tmp_addflag=' $pic_flag' + ;; + pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group f77 and f90 compilers + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; + efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 + tmp_addflag=' -i_dynamic -nofor_main' ;; + ifc* | ifort*) # Intel Fortran compiler + tmp_addflag=' -nofor_main' ;; + lf95*) # Lahey Fortran 8.1 + _LT_TAGVAR(whole_archive_flag_spec, $1)= + tmp_sharedflag='--shared' ;; + nagfor*) # NAGFOR 5.3 + tmp_sharedflag='-Wl,-shared' ;; + xl[[cC]]* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below) + tmp_sharedflag='-qmkshrobj' + tmp_addflag= ;; + nvcc*) # Cuda Compiler Driver 2.2 + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + _LT_TAGVAR(compiler_needs_object, $1)=yes + ;; + esac + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) # Sun C 5.9 + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + _LT_TAGVAR(compiler_needs_object, $1)=yes + tmp_sharedflag='-G' ;; + *Sun\ F*) # Sun Fortran 8.3 + tmp_sharedflag='-G' ;; + esac + _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + + if test yes = "$supports_anon_versioning"; then + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' + fi + + case $cc_basename in + tcc*) + _LT_TAGVAR(export_dynamic_flag_spec, $1)='-rdynamic' + ;; + xlf* | bgf* | bgxlf* | mpixlf*) + # IBM XL Fortran 10.1 on PPC cannot create shared libs itself + _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' + if test yes = "$supports_anon_versioning"; then + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' + fi + ;; + esac + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris*) + if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then + _LT_TAGVAR(ld_shlibs, $1)=no + cat <<_LT_EOF 1>&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*) + _LT_TAGVAR(ld_shlibs, $1)=no + cat <<_LT_EOF 1>&2 + +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 cannot +*** reliably create shared libraries on SCO systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.16.91.0.3 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + ;; + *) + # For security reasons, it is highly recommended that you always + # use absolute paths for naming shared libraries, and exclude the + # DT_RUNPATH tag from executables and libraries. But doing so + # requires that you compile everything twice, which is a pain. + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + sunos4*) + _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + + if test no = "$_LT_TAGVAR(ld_shlibs, $1)"; then + runpath_var= + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= + _LT_TAGVAR(export_dynamic_flag_spec, $1)= + _LT_TAGVAR(whole_archive_flag_spec, $1)= + fi + else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=yes + _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + if test yes = "$GCC" && test -z "$lt_prog_compiler_static"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + _LT_TAGVAR(hardcode_direct, $1)=unsupported + fi + ;; + + aix[[4-9]]*) + if test ia64 = "$host_cpu"; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag= + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to GNU nm, but means don't demangle to AIX nm. + # Without the "-l" option, or with the "-B" option, AIX nm treats + # weak defined symbols like other global defined symbols, whereas + # GNU nm marks them as "W". + # While the 'weak' keyword is ignored in the Export File, we need + # it in the Import File for the 'aix-soname' feature, so we have + # to replace the "-B" option with "-P" for AIX nm. + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' + else + _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' + fi + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # have runtime linking enabled, and use it for executables. + # For shared libraries, we enable/disable runtime linking + # depending on the kind of the shared library created - + # when "with_aix_soname,aix_use_runtimelinking" is: + # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables + # "aix,yes" lib.so shared, rtl:yes, for executables + # lib.a static archive + # "both,no" lib.so.V(shr.o) shared, rtl:yes + # lib.a(lib.so.V) shared, rtl:no, for executables + # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables + # lib.a(lib.so.V) shared, rtl:no + # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables + # lib.a static archive + case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) + for ld_flag in $LDFLAGS; do + if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then + aix_use_runtimelinking=yes + break + fi + done + if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then + # With aix-soname=svr4, we create the lib.so.V shared archives only, + # so we don't have lib.a shared libs to link our executables. + # We have to force runtime linking in this case. + aix_use_runtimelinking=yes + LDFLAGS="$LDFLAGS -Wl,-brtl" + fi + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + _LT_TAGVAR(archive_cmds, $1)='' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='$wl-f,' + case $with_aix_soname,$aix_use_runtimelinking in + aix,*) ;; # traditional, no import file + svr4,* | *,yes) # use import file + # The Import File defines what to hardcode. + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=no + ;; + esac + + if test yes = "$GCC"; then + case $host_os in aix4.[[012]]|aix4.[[012]].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`$CC -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + _LT_TAGVAR(hardcode_direct, $1)=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)= + fi + ;; + esac + shared_flag='-shared' + if test yes = "$aix_use_runtimelinking"; then + shared_flag="$shared_flag "'$wl-G' + fi + # Need to ensure runtime linking is disabled for the traditional + # shared library, or the linker may eventually find shared libraries + # /with/ Import File - we do not want to mix them. + shared_flag_aix='-shared' + shared_flag_svr4='-shared $wl-G' + else + # not using gcc + if test ia64 = "$host_cpu"; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test yes = "$aix_use_runtimelinking"; then + shared_flag='$wl-G' + else + shared_flag='$wl-bM:SRE' + fi + shared_flag_aix='$wl-bM:SRE' + shared_flag_svr4='$wl-G' + fi + fi + + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + _LT_TAGVAR(always_export_symbols, $1)=yes + if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(allow_undefined_flag, $1)='-berok' + # Determine the default libpath from the value encoded in an + # empty executable. + _LT_SYS_MODULE_PATH_AIX([$1]) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag + else + if test ia64 = "$host_cpu"; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $libdir:/usr/lib:/lib' + _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + _LT_SYS_MODULE_PATH_AIX([$1]) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(no_undefined_flag, $1)=' $wl-bernotok' + _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-berok' + if test yes = "$with_gnu_ld"; then + # We only use this code for GNU lds that support --whole-archive. + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)=yes + _LT_TAGVAR(archive_expsym_cmds, $1)='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' + # -brtl affects multiple linker settings, -berok does not and is overridden later + compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([[, ]]\\)%-berok\\1%g"`' + if test svr4 != "$with_aix_soname"; then + # This is similar to how AIX traditionally builds its shared libraries. + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' + fi + if test aix != "$with_aix_soname"; then + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' + else + # used by -dlpreopen to get the symbols + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$MV $output_objdir/$realname.d/$soname $output_objdir' + fi + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$RM -r $output_objdir/$realname.d' + fi + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='' + ;; + m68k) + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + ;; + + bsdi[[45]]*) + _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + case $cc_basename in + cl*) + # Native MSVC + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='@' + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=.dll + # FIXME: Setting linknames here is a bad hack. + _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' + _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then + cp "$export_symbols" "$output_objdir/$soname.def"; + echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; + else + $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' + # The linker will not automatically build a static lib if we build a DLL. + # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1,DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols' + # Don't use ranlib + _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' + _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile=$lt_outputfile.exe + lt_tool_outputfile=$lt_tool_outputfile.exe + ;; + esac~ + if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' + ;; + *) + # Assume MSVC wrapper + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=.dll + # FIXME: Setting linknames here is a bad hack. + _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' + # FIXME: Should let the user specify the lib program. + _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + ;; + esac + ;; + + darwin* | rhapsody*) + _LT_DARWIN_LINKER_FEATURES($1) + ;; + + dgux*) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2.*) + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd* | dragonfly*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + hpux9*) + if test yes = "$GCC"; then + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' + else + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(hardcode_direct, $1)=yes + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + ;; + + hpux10*) + if test yes,no = "$GCC,$with_gnu_ld"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + fi + if test no = "$with_gnu_ld"; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + fi + ;; + + hpux11*) + if test yes,no = "$GCC,$with_gnu_ld"; then + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + else + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + m4_if($1, [], [ + # Older versions of the 11.00 compiler do not understand -b yet + # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) + _LT_LINKER_OPTION([if $CC understands -b], + _LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b], + [_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'], + [_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'])], + [_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags']) + ;; + esac + fi + if test no = "$with_gnu_ld"; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + case $host_cpu in + hppa*64*|ia64*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + *) + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + fi + ;; + + irix5* | irix6* | nonstopux*) + if test yes = "$GCC"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + # Try to use the -exported_symbol ld option, if it does not + # work, assume that -exports_file does not work either and + # implicitly export all symbols. + # This should be the same for all languages, so no per-tag cache variable. + AC_CACHE_CHECK([whether the $host_os linker accepts -exported_symbol], + [lt_cv_irix_exported_symbol], + [save_LDFLAGS=$LDFLAGS + LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null" + AC_LINK_IFELSE( + [AC_LANG_SOURCE( + [AC_LANG_CASE([C], [[int foo (void) { return 0; }]], + [C++], [[int foo (void) { return 0; }]], + [Fortran 77], [[ + subroutine foo + end]], + [Fortran], [[ + subroutine foo + end]])])], + [lt_cv_irix_exported_symbol=yes], + [lt_cv_irix_exported_symbol=no]) + LDFLAGS=$save_LDFLAGS]) + if test yes = "$lt_cv_irix_exported_symbol"; then + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib' + fi + _LT_TAGVAR(link_all_deplibs, $1)=no + else + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)='no' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(inherit_rpath, $1)=yes + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + linux*) + case $cc_basename in + tcc*) + # Fabrice Bellard et al's Tiny C Compiler + _LT_TAGVAR(ld_shlibs, $1)=yes + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + _LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + newsos6) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *nto* | *qnx*) + ;; + + openbsd* | bitrig*) + if test -f /usr/libexec/ld.so; then + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $wl-retain-symbols-file,$export_symbols' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + else + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + fi + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + os2*) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + shrext_cmds=.dll + _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + prefix_cmds="$SED"~ + if test EXPORTS = "`$SED 1q $export_symbols`"; then + prefix_cmds="$prefix_cmds -e 1d"; + fi~ + prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ + cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + ;; + + osf3*) + if test yes = "$GCC"; then + _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + else + _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)='no' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test yes = "$GCC"; then + _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + else + _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $wl-input $wl$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~$RM $lib.exp' + + # Both c and cxx compiler support -rpath directly + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)='no' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + ;; + + solaris*) + _LT_TAGVAR(no_undefined_flag, $1)=' -z defs' + if test yes = "$GCC"; then + wlarc='$wl' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl-z ${wl}text $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared $pic_flag $wl-z ${wl}text $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + else + case `$CC -V 2>&1` in + *"Compilers 5.0"*) + wlarc='' + _LT_TAGVAR(archive_cmds, $1)='$LD -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $LD -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' + ;; + *) + wlarc='$wl' + _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + ;; + esac + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands '-z linker_flag'. GCC discards it without '$wl', + # but is careful enough not to reorder. + # Supported since Solaris 2.6 (maybe 2.5.1?) + if test yes = "$GCC"; then + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' + else + _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' + fi + ;; + esac + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + sunos4*) + if test sequent = "$host_vendor"; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + sysv4) + case $host_vendor in + sni) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs' + _LT_TAGVAR(hardcode_direct, $1)=no + ;; + motorola) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + sysv4.3*) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + _LT_TAGVAR(ld_shlibs, $1)=yes + fi + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) + _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var='LD_RUN_PATH' + + if test yes = "$GCC"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We CANNOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' + _LT_TAGVAR(allow_undefined_flag, $1)='$wl-z,nodefs' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R,$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Bexport' + runpath_var='LD_RUN_PATH' + + if test yes = "$GCC"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + uts4*) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *) + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + + if test sni = "$host_vendor"; then + case $host in + sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Blargedynsym' + ;; + esac + fi + fi +]) +AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) +test no = "$_LT_TAGVAR(ld_shlibs, $1)" && can_build_shared=no + +_LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld + +_LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl +_LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl +_LT_DECL([], [extract_expsyms_cmds], [2], + [The commands to extract the exported symbol list from a shared archive]) + +# +# Do we need to explicitly link libc? +# +case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in +x|xyes) + # Assume -lc should be added + _LT_TAGVAR(archive_cmds_need_lc, $1)=yes + + if test yes,yes = "$GCC,$enable_shared"; then + case $_LT_TAGVAR(archive_cmds, $1) in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + AC_CACHE_CHECK([whether -lc should be explicitly linked in], + [lt_cv_]_LT_TAGVAR(archive_cmds_need_lc, $1), + [$RM conftest* + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + if AC_TRY_EVAL(ac_compile) 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) + pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1) + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1) + _LT_TAGVAR(allow_undefined_flag, $1)= + if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) + then + lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=no + else + lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=yes + fi + _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $RM conftest* + ]) + _LT_TAGVAR(archive_cmds_need_lc, $1)=$lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1) + ;; + esac + fi + ;; +esac + +_LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0], + [Whether or not to add -lc for building shared libraries]) +_LT_TAGDECL([allow_libtool_libs_with_static_runtimes], + [enable_shared_with_static_runtimes], [0], + [Whether or not to disallow shared libs when runtime libs are static]) +_LT_TAGDECL([], [export_dynamic_flag_spec], [1], + [Compiler flag to allow reflexive dlopens]) +_LT_TAGDECL([], [whole_archive_flag_spec], [1], + [Compiler flag to generate shared objects directly from archives]) +_LT_TAGDECL([], [compiler_needs_object], [1], + [Whether the compiler copes with passing no objects directly]) +_LT_TAGDECL([], [old_archive_from_new_cmds], [2], + [Create an old-style archive from a shared archive]) +_LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2], + [Create a temporary old-style archive to link instead of a shared archive]) +_LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive]) +_LT_TAGDECL([], [archive_expsym_cmds], [2]) +_LT_TAGDECL([], [module_cmds], [2], + [Commands used to build a loadable module if different from building + a shared archive.]) +_LT_TAGDECL([], [module_expsym_cmds], [2]) +_LT_TAGDECL([], [with_gnu_ld], [1], + [Whether we are building with GNU ld or not]) +_LT_TAGDECL([], [allow_undefined_flag], [1], + [Flag that allows shared libraries with undefined symbols to be built]) +_LT_TAGDECL([], [no_undefined_flag], [1], + [Flag that enforces no undefined symbols]) +_LT_TAGDECL([], [hardcode_libdir_flag_spec], [1], + [Flag to hardcode $libdir into a binary during linking. + This must work even if $libdir does not exist]) +_LT_TAGDECL([], [hardcode_libdir_separator], [1], + [Whether we need a single "-rpath" flag with a separated argument]) +_LT_TAGDECL([], [hardcode_direct], [0], + [Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes + DIR into the resulting binary]) +_LT_TAGDECL([], [hardcode_direct_absolute], [0], + [Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes + DIR into the resulting binary and the resulting library dependency is + "absolute", i.e impossible to change by setting $shlibpath_var if the + library is relocated]) +_LT_TAGDECL([], [hardcode_minus_L], [0], + [Set to "yes" if using the -LDIR flag during linking hardcodes DIR + into the resulting binary]) +_LT_TAGDECL([], [hardcode_shlibpath_var], [0], + [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR + into the resulting binary]) +_LT_TAGDECL([], [hardcode_automatic], [0], + [Set to "yes" if building a shared library automatically hardcodes DIR + into the library and all subsequent libraries and executables linked + against it]) +_LT_TAGDECL([], [inherit_rpath], [0], + [Set to yes if linker adds runtime paths of dependent libraries + to runtime path list]) +_LT_TAGDECL([], [link_all_deplibs], [0], + [Whether libtool must link a program against all its dependency libraries]) +_LT_TAGDECL([], [always_export_symbols], [0], + [Set to "yes" if exported symbols are required]) +_LT_TAGDECL([], [export_symbols_cmds], [2], + [The commands to list exported symbols]) +_LT_TAGDECL([], [exclude_expsyms], [1], + [Symbols that should not be listed in the preloaded symbols]) +_LT_TAGDECL([], [include_expsyms], [1], + [Symbols that must always be exported]) +_LT_TAGDECL([], [prelink_cmds], [2], + [Commands necessary for linking programs (against libraries) with templates]) +_LT_TAGDECL([], [postlink_cmds], [2], + [Commands necessary for finishing linking programs]) +_LT_TAGDECL([], [file_list_spec], [1], + [Specify filename containing input files]) +dnl FIXME: Not yet implemented +dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1], +dnl [Compiler flag to generate thread safe objects]) +])# _LT_LINKER_SHLIBS + + +# _LT_LANG_C_CONFIG([TAG]) +# ------------------------ +# Ensure that the configuration variables for a C compiler are suitably +# defined. These variables are subsequently used by _LT_CONFIG to write +# the compiler configuration to 'libtool'. +m4_defun([_LT_LANG_C_CONFIG], +[m4_require([_LT_DECL_EGREP])dnl +lt_save_CC=$CC +AC_LANG_PUSH(C) + +# Source file extension for C test sources. +ac_ext=c + +# Object file extension for compiled C test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(){return(0);}' + +_LT_TAG_COMPILER +# Save the default compiler, since it gets overwritten when the other +# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. +compiler_DEFAULT=$CC + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... +if test -n "$compiler"; then + _LT_COMPILER_NO_RTTI($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + LT_SYS_DLOPEN_SELF + _LT_CMD_STRIPLIB + + # Report what library types will actually be built + AC_MSG_CHECKING([if libtool supports shared libraries]) + AC_MSG_RESULT([$can_build_shared]) + + AC_MSG_CHECKING([whether to build shared libraries]) + test no = "$can_build_shared" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test yes = "$enable_shared" && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + + aix[[4-9]]*) + if test ia64 != "$host_cpu"; then + case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in + yes,aix,yes) ;; # shared object as lib.so file only + yes,svr4,*) ;; # shared object as lib.so archive member only + yes,*) enable_static=no ;; # shared object in lib.a archive as well + esac + fi + ;; + esac + AC_MSG_RESULT([$enable_shared]) + + AC_MSG_CHECKING([whether to build static libraries]) + # Make sure either enable_shared or enable_static is yes. + test yes = "$enable_shared" || enable_static=yes + AC_MSG_RESULT([$enable_static]) + + _LT_CONFIG($1) +fi +AC_LANG_POP +CC=$lt_save_CC +])# _LT_LANG_C_CONFIG + + +# _LT_LANG_CXX_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for a C++ compiler are suitably +# defined. These variables are subsequently used by _LT_CONFIG to write +# the compiler configuration to 'libtool'. +m4_defun([_LT_LANG_CXX_CONFIG], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_PATH_MANIFEST_TOOL])dnl +if test -n "$CXX" && ( test no != "$CXX" && + ( (test g++ = "$CXX" && `g++ -v >/dev/null 2>&1` ) || + (test g++ != "$CXX"))); then + AC_PROG_CXXCPP +else + _lt_caught_CXX_error=yes +fi + +AC_LANG_PUSH(C++) +_LT_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_TAGVAR(allow_undefined_flag, $1)= +_LT_TAGVAR(always_export_symbols, $1)=no +_LT_TAGVAR(archive_expsym_cmds, $1)= +_LT_TAGVAR(compiler_needs_object, $1)=no +_LT_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_TAGVAR(hardcode_direct, $1)=no +_LT_TAGVAR(hardcode_direct_absolute, $1)=no +_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_TAGVAR(hardcode_libdir_separator, $1)= +_LT_TAGVAR(hardcode_minus_L, $1)=no +_LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported +_LT_TAGVAR(hardcode_automatic, $1)=no +_LT_TAGVAR(inherit_rpath, $1)=no +_LT_TAGVAR(module_cmds, $1)= +_LT_TAGVAR(module_expsym_cmds, $1)= +_LT_TAGVAR(link_all_deplibs, $1)=unknown +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds +_LT_TAGVAR(no_undefined_flag, $1)= +_LT_TAGVAR(whole_archive_flag_spec, $1)= +_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Source file extension for C++ test sources. +ac_ext=cpp + +# Object file extension for compiled C++ test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# No sense in running all these tests if we already determined that +# the CXX compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test yes != "$_lt_caught_CXX_error"; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="int some_variable = 0;" + + # Code to be used in simple link tests + lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }' + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + _LT_TAG_COMPILER + + # save warnings/boilerplate of simple test code + _LT_COMPILER_BOILERPLATE + _LT_LINKER_BOILERPLATE + + # Allow CC to be a program name with arguments. + lt_save_CC=$CC + lt_save_CFLAGS=$CFLAGS + lt_save_LD=$LD + lt_save_GCC=$GCC + GCC=$GXX + lt_save_with_gnu_ld=$with_gnu_ld + lt_save_path_LD=$lt_cv_path_LD + if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then + lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx + else + $as_unset lt_cv_prog_gnu_ld + fi + if test -n "${lt_cv_path_LDCXX+set}"; then + lt_cv_path_LD=$lt_cv_path_LDCXX + else + $as_unset lt_cv_path_LD + fi + test -z "${LDCXX+set}" || LD=$LDCXX + CC=${CXX-"c++"} + CFLAGS=$CXXFLAGS + compiler=$CC + _LT_TAGVAR(compiler, $1)=$CC + _LT_CC_BASENAME([$compiler]) + + if test -n "$compiler"; then + # We don't want -fno-exception when compiling C++ code, so set the + # no_builtin_flag separately + if test yes = "$GXX"; then + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' + else + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= + fi + + if test yes = "$GXX"; then + # Set up default GNU C++ configuration + + LT_PATH_LD + + # Check if GNU C++ uses GNU ld as the underlying linker, since the + # archiving commands below assume that GNU ld is being used. + if test yes = "$with_gnu_ld"; then + _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' + + # If archive_cmds runs LD, not CC, wlarc should be empty + # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to + # investigate it a little bit more. (MM) + wlarc='$wl' + + # ancient GNU ld didn't support --whole-archive et. al. + if eval "`$CC -print-prog-name=ld` --help 2>&1" | + $GREP 'no-whole-archive' > /dev/null; then + _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' + else + _LT_TAGVAR(whole_archive_flag_spec, $1)= + fi + else + with_gnu_ld=no + wlarc= + + # A generic and very simple default shared library creation + # command for GNU C++ for the case where it uses the native + # linker, instead of GNU ld. If possible, this setting should + # overridden to take advantage of the native linker features on + # the platform it is being used on. + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + fi + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' + + else + GXX=no + with_gnu_ld=no + wlarc= + fi + + # PORTME: fill in a description of your system's C++ link characteristics + AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) + _LT_TAGVAR(ld_shlibs, $1)=yes + case $host_os in + aix3*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + aix[[4-9]]*) + if test ia64 = "$host_cpu"; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag= + else + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # have runtime linking enabled, and use it for executables. + # For shared libraries, we enable/disable runtime linking + # depending on the kind of the shared library created - + # when "with_aix_soname,aix_use_runtimelinking" is: + # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables + # "aix,yes" lib.so shared, rtl:yes, for executables + # lib.a static archive + # "both,no" lib.so.V(shr.o) shared, rtl:yes + # lib.a(lib.so.V) shared, rtl:no, for executables + # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables + # lib.a(lib.so.V) shared, rtl:no + # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables + # lib.a static archive + case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) + for ld_flag in $LDFLAGS; do + case $ld_flag in + *-brtl*) + aix_use_runtimelinking=yes + break + ;; + esac + done + if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then + # With aix-soname=svr4, we create the lib.so.V shared archives only, + # so we don't have lib.a shared libs to link our executables. + # We have to force runtime linking in this case. + aix_use_runtimelinking=yes + LDFLAGS="$LDFLAGS -Wl,-brtl" + fi + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + _LT_TAGVAR(archive_cmds, $1)='' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='$wl-f,' + case $with_aix_soname,$aix_use_runtimelinking in + aix,*) ;; # no import file + svr4,* | *,yes) # use import file + # The Import File defines what to hardcode. + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=no + ;; + esac + + if test yes = "$GXX"; then + case $host_os in aix4.[[012]]|aix4.[[012]].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`$CC -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + _LT_TAGVAR(hardcode_direct, $1)=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)= + fi + esac + shared_flag='-shared' + if test yes = "$aix_use_runtimelinking"; then + shared_flag=$shared_flag' $wl-G' + fi + # Need to ensure runtime linking is disabled for the traditional + # shared library, or the linker may eventually find shared libraries + # /with/ Import File - we do not want to mix them. + shared_flag_aix='-shared' + shared_flag_svr4='-shared $wl-G' + else + # not using gcc + if test ia64 = "$host_cpu"; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test yes = "$aix_use_runtimelinking"; then + shared_flag='$wl-G' + else + shared_flag='$wl-bM:SRE' + fi + shared_flag_aix='$wl-bM:SRE' + shared_flag_svr4='$wl-G' + fi + fi + + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to + # export. + _LT_TAGVAR(always_export_symbols, $1)=yes + if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + # The "-G" linker flag allows undefined symbols. + _LT_TAGVAR(no_undefined_flag, $1)='-bernotok' + # Determine the default libpath from the value encoded in an empty + # executable. + _LT_SYS_MODULE_PATH_AIX([$1]) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" + + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag + else + if test ia64 = "$host_cpu"; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $libdir:/usr/lib:/lib' + _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + _LT_SYS_MODULE_PATH_AIX([$1]) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(no_undefined_flag, $1)=' $wl-bernotok' + _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-berok' + if test yes = "$with_gnu_ld"; then + # We only use this code for GNU lds that support --whole-archive. + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)=yes + _LT_TAGVAR(archive_expsym_cmds, $1)='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' + # -brtl affects multiple linker settings, -berok does not and is overridden later + compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([[, ]]\\)%-berok\\1%g"`' + if test svr4 != "$with_aix_soname"; then + # This is similar to how AIX traditionally builds its shared + # libraries. Need -bnortl late, we may have -brtl in LDFLAGS. + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' + fi + if test aix != "$with_aix_soname"; then + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' + else + # used by -dlpreopen to get the symbols + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$MV $output_objdir/$realname.d/$soname $output_objdir' + fi + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$RM -r $output_objdir/$realname.d' + fi + fi + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + chorus*) + case $cc_basename in + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + cygwin* | mingw* | pw32* | cegcc*) + case $GXX,$cc_basename in + ,cl* | no,cl*) + # Native MSVC + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='@' + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=.dll + # FIXME: Setting linknames here is a bad hack. + _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' + _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then + cp "$export_symbols" "$output_objdir/$soname.def"; + echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; + else + $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' + # The linker will not automatically build a static lib if we build a DLL. + # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + # Don't use ranlib + _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' + _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile=$lt_outputfile.exe + lt_tool_outputfile=$lt_tool_outputfile.exe + ;; + esac~ + func_to_tool_file "$lt_outputfile"~ + if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' + ;; + *) + # g++ + # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, + # as there is no search path for DLLs. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-all-symbols' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=no + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file, use it as + # is; otherwise, prepend EXPORTS... + _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + darwin* | rhapsody*) + _LT_DARWIN_LINKER_FEATURES($1) + ;; + + os2*) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + shrext_cmds=.dll + _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + prefix_cmds="$SED"~ + if test EXPORTS = "`$SED 1q $export_symbols`"; then + prefix_cmds="$prefix_cmds -e 1d"; + fi~ + prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ + cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + ;; + + dgux*) + case $cc_basename in + ec++*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + ghcx*) + # Green Hills C++ Compiler + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + freebsd2.*) + # C++ shared libraries reported to be fairly broken before + # switch to ELF + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + freebsd-elf*) + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + ;; + + freebsd* | dragonfly*) + # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF + # conventions + _LT_TAGVAR(ld_shlibs, $1)=yes + ;; + + haiku*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + hpux9*) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, + # but as the default + # location of the library. + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + aCC*) + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP " \-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test yes = "$GXX"; then + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' + else + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + hpux10*|hpux11*) + if test no = "$with_gnu_ld"; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + case $host_cpu in + hppa*64*|ia64*) + ;; + *) + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + ;; + esac + fi + case $host_cpu in + hppa*64*|ia64*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + *) + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, + # but as the default + # location of the library. + ;; + esac + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + aCC*) + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP " \-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test yes = "$GXX"; then + if test no = "$with_gnu_ld"; then + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + fi + else + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + interix[[3-9]]*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + irix5* | irix6*) + case $cc_basename in + CC*) + # SGI C++ + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + + # Archives containing C++ object files must be created using + # "CC -ar", where "CC" is the IRIX C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs' + ;; + *) + if test yes = "$GXX"; then + if test no = "$with_gnu_ld"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + else + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` -o $lib' + fi + fi + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + esac + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(inherit_rpath, $1)=yes + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib $wl-retain-symbols-file,$export_symbols; mv \$templib $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' + + # Archives containing C++ object files must be created using + # "CC -Bstatic", where "CC" is the KAI C++ compiler. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' + ;; + icpc* | ecpc* ) + # Intel C++ + with_gnu_ld=yes + # version 8.0 and above of icpc choke on multiply defined symbols + # if we add $predep_objects and $postdep_objects, however 7.1 and + # earlier do not add the objects themselves. + case `$CC -V 2>&1` in + *"Version 7."*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + ;; + *) # Version 8.0 or newer + tmp_idyn= + case $host_cpu in + ia64*) tmp_idyn=' -i_dynamic';; + esac + _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + ;; + esac + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + case `$CC -V` in + *pgCC\ [[1-5]].* | *pgcpp\ [[1-5]].*) + _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ + compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' + _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ + $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ + $RANLIB $oldlib' + _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + ;; + *) # Version 6 and above use weak symbols + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + ;; + esac + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl--rpath $wl$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + ;; + cxx*) + # Compaq C++ + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib $wl-retain-symbols-file $wl$export_symbols' + + runpath_var=LD_RUN_PATH + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' + ;; + xl* | mpixl* | bgxl*) + # IBM XL 8.0 on PPC, with GNU ld + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' + _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + if test yes = "$supports_anon_versioning"; then + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' + fi + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' + _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file $wl$export_symbols' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + _LT_TAGVAR(compiler_needs_object, $1)=yes + + # Not sure whether something based on + # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 + # would be better. + output_verbose_link_cmd='func_echo_all' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' + ;; + esac + ;; + esac + ;; + + lynxos*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + m88k*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + mvs*) + case $cc_basename in + cxx*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' + wlarc= + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + fi + # Workaround some broken pre-1.5 toolchains + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' + ;; + + *nto* | *qnx*) + _LT_TAGVAR(ld_shlibs, $1)=yes + ;; + + openbsd* | bitrig*) + if test -f /usr/libexec/ld.so; then + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`"; then + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file,$export_symbols -o $lib' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' + fi + output_verbose_link_cmd=func_echo_all + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Archives containing C++ object files must be created using + # the KAI C++ compiler. + case $host in + osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; + *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;; + esac + ;; + RCC*) + # Rational C++ 2.4.1 + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + cxx*) + case $host in + osf3*) + _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $soname `test -n "$verstring" && func_echo_all "$wl-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + ;; + *) + _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ + echo "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname $wl-input $wl$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~ + $RM $lib.exp' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + ;; + esac + + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test yes,no = "$GXX,$with_gnu_ld"; then + _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' + case $host in + osf3*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + ;; + esac + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' + + else + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + psos*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + lcc*) + # Lucid + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + solaris*) + case $cc_basename in + CC* | sunCC*) + # Sun C++ 4.2, 5.x and Centerline C++ + _LT_TAGVAR(archive_cmds_need_lc,$1)=yes + _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' + _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G$allow_undefined_flag $wl-M $wl$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands '-z linker_flag'. + # Supported since Solaris 2.6 (maybe 2.5.1?) + _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' + ;; + esac + _LT_TAGVAR(link_all_deplibs, $1)=yes + + output_verbose_link_cmd='func_echo_all' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' + ;; + gcx*) + # Green Hills C++ Compiler + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' + + # The C++ compiler must be used to create the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs' + ;; + *) + # GNU C++ compiler with Solaris linker + if test yes,no = "$GXX,$with_gnu_ld"; then + _LT_TAGVAR(no_undefined_flag, $1)=' $wl-z ${wl}defs' + if $CC --version | $GREP -v '^2\.7' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared $pic_flag -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' + else + # g++ 2.7 appears to require '-G' NOT '-shared' on this + # platform. + _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' + fi + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $wl$libdir' + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' + ;; + esac + fi + ;; + esac + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) + _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We CANNOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' + _LT_TAGVAR(allow_undefined_flag, $1)='$wl-z,nodefs' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R,$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Bexport' + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(old_archive_cmds, $1)='$CC -Tprelink_objects $oldobjs~ + '"$_LT_TAGVAR(old_archive_cmds, $1)" + _LT_TAGVAR(reload_cmds, $1)='$CC -Tprelink_objects $reload_objs~ + '"$_LT_TAGVAR(reload_cmds, $1)" + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + vxworks*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + + AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) + test no = "$_LT_TAGVAR(ld_shlibs, $1)" && can_build_shared=no + + _LT_TAGVAR(GCC, $1)=$GXX + _LT_TAGVAR(LD, $1)=$LD + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + _LT_SYS_HIDDEN_LIBDEPS($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) + fi # test -n "$compiler" + + CC=$lt_save_CC + CFLAGS=$lt_save_CFLAGS + LDCXX=$LD + LD=$lt_save_LD + GCC=$lt_save_GCC + with_gnu_ld=$lt_save_with_gnu_ld + lt_cv_path_LDCXX=$lt_cv_path_LD + lt_cv_path_LD=$lt_save_path_LD + lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld + lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld +fi # test yes != "$_lt_caught_CXX_error" + +AC_LANG_POP +])# _LT_LANG_CXX_CONFIG + + +# _LT_FUNC_STRIPNAME_CNF +# ---------------------- +# func_stripname_cnf prefix suffix name +# strip PREFIX and SUFFIX off of NAME. +# PREFIX and SUFFIX must not contain globbing or regex special +# characters, hashes, percent signs, but SUFFIX may contain a leading +# dot (in which case that matches only a dot). +# +# This function is identical to the (non-XSI) version of func_stripname, +# except this one can be used by m4 code that may be executed by configure, +# rather than the libtool script. +m4_defun([_LT_FUNC_STRIPNAME_CNF],[dnl +AC_REQUIRE([_LT_DECL_SED]) +AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH]) +func_stripname_cnf () +{ + case @S|@2 in + .*) func_stripname_result=`$ECHO "@S|@3" | $SED "s%^@S|@1%%; s%\\\\@S|@2\$%%"`;; + *) func_stripname_result=`$ECHO "@S|@3" | $SED "s%^@S|@1%%; s%@S|@2\$%%"`;; + esac +} # func_stripname_cnf +])# _LT_FUNC_STRIPNAME_CNF + + +# _LT_SYS_HIDDEN_LIBDEPS([TAGNAME]) +# --------------------------------- +# Figure out "hidden" library dependencies from verbose +# compiler output when linking a shared library. +# Parse the compiler output and extract the necessary +# objects, libraries and library flags. +m4_defun([_LT_SYS_HIDDEN_LIBDEPS], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +AC_REQUIRE([_LT_FUNC_STRIPNAME_CNF])dnl +# Dependencies to place before and after the object being linked: +_LT_TAGVAR(predep_objects, $1)= +_LT_TAGVAR(postdep_objects, $1)= +_LT_TAGVAR(predeps, $1)= +_LT_TAGVAR(postdeps, $1)= +_LT_TAGVAR(compiler_lib_search_path, $1)= + +dnl we can't use the lt_simple_compile_test_code here, +dnl because it contains code intended for an executable, +dnl not a library. It's possible we should let each +dnl tag define a new lt_????_link_test_code variable, +dnl but it's only used here... +m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF +int a; +void foo (void) { a = 0; } +_LT_EOF +], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF +class Foo +{ +public: + Foo (void) { a = 0; } +private: + int a; +}; +_LT_EOF +], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF + subroutine foo + implicit none + integer*4 a + a=0 + return + end +_LT_EOF +], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF + subroutine foo + implicit none + integer a + a=0 + return + end +_LT_EOF +], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF +public class foo { + private int a; + public void bar (void) { + a = 0; + } +}; +_LT_EOF +], [$1], [GO], [cat > conftest.$ac_ext <<_LT_EOF +package foo +func foo() { +} +_LT_EOF +]) + +_lt_libdeps_save_CFLAGS=$CFLAGS +case "$CC $CFLAGS " in #( +*\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; +*\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; +*\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;; +esac + +dnl Parse the compiler output and extract the necessary +dnl objects, libraries and library flags. +if AC_TRY_EVAL(ac_compile); then + # Parse the compiler output and extract the necessary + # objects, libraries and library flags. + + # Sentinel used to keep track of whether or not we are before + # the conftest object file. + pre_test_object_deps_done=no + + for p in `eval "$output_verbose_link_cmd"`; do + case $prev$p in + + -L* | -R* | -l*) + # Some compilers place space between "-{L,R}" and the path. + # Remove the space. + if test x-L = "$p" || + test x-R = "$p"; then + prev=$p + continue + fi + + # Expand the sysroot to ease extracting the directories later. + if test -z "$prev"; then + case $p in + -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;; + -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;; + -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;; + esac + fi + case $p in + =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; + esac + if test no = "$pre_test_object_deps_done"; then + case $prev in + -L | -R) + # Internal compiler library paths should come after those + # provided the user. The postdeps already come after the + # user supplied libs so there is no need to process them. + if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then + _LT_TAGVAR(compiler_lib_search_path, $1)=$prev$p + else + _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} $prev$p" + fi + ;; + # The "-l" case would never come before the object being + # linked, so don't bother handling this case. + esac + else + if test -z "$_LT_TAGVAR(postdeps, $1)"; then + _LT_TAGVAR(postdeps, $1)=$prev$p + else + _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} $prev$p" + fi + fi + prev= + ;; + + *.lto.$objext) ;; # Ignore GCC LTO objects + *.$objext) + # This assumes that the test object file only shows up + # once in the compiler output. + if test "$p" = "conftest.$objext"; then + pre_test_object_deps_done=yes + continue + fi + + if test no = "$pre_test_object_deps_done"; then + if test -z "$_LT_TAGVAR(predep_objects, $1)"; then + _LT_TAGVAR(predep_objects, $1)=$p + else + _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p" + fi + else + if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then + _LT_TAGVAR(postdep_objects, $1)=$p + else + _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p" + fi + fi + ;; + + *) ;; # Ignore the rest. + + esac + done + + # Clean up. + rm -f a.out a.exe +else + echo "libtool.m4: error: problem compiling $1 test program" +fi + +$RM -f confest.$objext +CFLAGS=$_lt_libdeps_save_CFLAGS + +# PORTME: override above test on systems where it is broken +m4_if([$1], [CXX], +[case $host_os in +interix[[3-9]]*) + # Interix 3.5 installs completely hosed .la files for C++, so rather than + # hack all around it, let's just trust "g++" to DTRT. + _LT_TAGVAR(predep_objects,$1)= + _LT_TAGVAR(postdep_objects,$1)= + _LT_TAGVAR(postdeps,$1)= + ;; +esac +]) + +case " $_LT_TAGVAR(postdeps, $1) " in +*" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; +esac + _LT_TAGVAR(compiler_lib_search_dirs, $1)= +if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then + _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | $SED -e 's! -L! !g' -e 's!^ !!'` +fi +_LT_TAGDECL([], [compiler_lib_search_dirs], [1], + [The directories searched by this compiler when creating a shared library]) +_LT_TAGDECL([], [predep_objects], [1], + [Dependencies to place before and after the objects being linked to + create a shared library]) +_LT_TAGDECL([], [postdep_objects], [1]) +_LT_TAGDECL([], [predeps], [1]) +_LT_TAGDECL([], [postdeps], [1]) +_LT_TAGDECL([], [compiler_lib_search_path], [1], + [The library search path used internally by the compiler when linking + a shared library]) +])# _LT_SYS_HIDDEN_LIBDEPS + + +# _LT_LANG_F77_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for a Fortran 77 compiler are +# suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to 'libtool'. +m4_defun([_LT_LANG_F77_CONFIG], +[AC_LANG_PUSH(Fortran 77) +if test -z "$F77" || test no = "$F77"; then + _lt_disable_F77=yes +fi + +_LT_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_TAGVAR(allow_undefined_flag, $1)= +_LT_TAGVAR(always_export_symbols, $1)=no +_LT_TAGVAR(archive_expsym_cmds, $1)= +_LT_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_TAGVAR(hardcode_direct, $1)=no +_LT_TAGVAR(hardcode_direct_absolute, $1)=no +_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_TAGVAR(hardcode_libdir_separator, $1)= +_LT_TAGVAR(hardcode_minus_L, $1)=no +_LT_TAGVAR(hardcode_automatic, $1)=no +_LT_TAGVAR(inherit_rpath, $1)=no +_LT_TAGVAR(module_cmds, $1)= +_LT_TAGVAR(module_expsym_cmds, $1)= +_LT_TAGVAR(link_all_deplibs, $1)=unknown +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds +_LT_TAGVAR(no_undefined_flag, $1)= +_LT_TAGVAR(whole_archive_flag_spec, $1)= +_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Source file extension for f77 test sources. +ac_ext=f + +# Object file extension for compiled f77 test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# No sense in running all these tests if we already determined that +# the F77 compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test yes != "$_lt_disable_F77"; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="\ + subroutine t + return + end +" + + # Code to be used in simple link tests + lt_simple_link_test_code="\ + program t + end +" + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + _LT_TAG_COMPILER + + # save warnings/boilerplate of simple test code + _LT_COMPILER_BOILERPLATE + _LT_LINKER_BOILERPLATE + + # Allow CC to be a program name with arguments. + lt_save_CC=$CC + lt_save_GCC=$GCC + lt_save_CFLAGS=$CFLAGS + CC=${F77-"f77"} + CFLAGS=$FFLAGS + compiler=$CC + _LT_TAGVAR(compiler, $1)=$CC + _LT_CC_BASENAME([$compiler]) + GCC=$G77 + if test -n "$compiler"; then + AC_MSG_CHECKING([if libtool supports shared libraries]) + AC_MSG_RESULT([$can_build_shared]) + + AC_MSG_CHECKING([whether to build shared libraries]) + test no = "$can_build_shared" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test yes = "$enable_shared" && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + aix[[4-9]]*) + if test ia64 != "$host_cpu"; then + case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in + yes,aix,yes) ;; # shared object as lib.so file only + yes,svr4,*) ;; # shared object as lib.so archive member only + yes,*) enable_static=no ;; # shared object in lib.a archive as well + esac + fi + ;; + esac + AC_MSG_RESULT([$enable_shared]) + + AC_MSG_CHECKING([whether to build static libraries]) + # Make sure either enable_shared or enable_static is yes. + test yes = "$enable_shared" || enable_static=yes + AC_MSG_RESULT([$enable_static]) + + _LT_TAGVAR(GCC, $1)=$G77 + _LT_TAGVAR(LD, $1)=$LD + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) + fi # test -n "$compiler" + + GCC=$lt_save_GCC + CC=$lt_save_CC + CFLAGS=$lt_save_CFLAGS +fi # test yes != "$_lt_disable_F77" + +AC_LANG_POP +])# _LT_LANG_F77_CONFIG + + +# _LT_LANG_FC_CONFIG([TAG]) +# ------------------------- +# Ensure that the configuration variables for a Fortran compiler are +# suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to 'libtool'. +m4_defun([_LT_LANG_FC_CONFIG], +[AC_LANG_PUSH(Fortran) + +if test -z "$FC" || test no = "$FC"; then + _lt_disable_FC=yes +fi + +_LT_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_TAGVAR(allow_undefined_flag, $1)= +_LT_TAGVAR(always_export_symbols, $1)=no +_LT_TAGVAR(archive_expsym_cmds, $1)= +_LT_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_TAGVAR(hardcode_direct, $1)=no +_LT_TAGVAR(hardcode_direct_absolute, $1)=no +_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_TAGVAR(hardcode_libdir_separator, $1)= +_LT_TAGVAR(hardcode_minus_L, $1)=no +_LT_TAGVAR(hardcode_automatic, $1)=no +_LT_TAGVAR(inherit_rpath, $1)=no +_LT_TAGVAR(module_cmds, $1)= +_LT_TAGVAR(module_expsym_cmds, $1)= +_LT_TAGVAR(link_all_deplibs, $1)=unknown +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds +_LT_TAGVAR(no_undefined_flag, $1)= +_LT_TAGVAR(whole_archive_flag_spec, $1)= +_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Source file extension for fc test sources. +ac_ext=${ac_fc_srcext-f} + +# Object file extension for compiled fc test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# No sense in running all these tests if we already determined that +# the FC compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test yes != "$_lt_disable_FC"; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="\ + subroutine t + return + end +" + + # Code to be used in simple link tests + lt_simple_link_test_code="\ + program t + end +" + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + _LT_TAG_COMPILER + + # save warnings/boilerplate of simple test code + _LT_COMPILER_BOILERPLATE + _LT_LINKER_BOILERPLATE + + # Allow CC to be a program name with arguments. + lt_save_CC=$CC + lt_save_GCC=$GCC + lt_save_CFLAGS=$CFLAGS + CC=${FC-"f95"} + CFLAGS=$FCFLAGS + compiler=$CC + GCC=$ac_cv_fc_compiler_gnu + + _LT_TAGVAR(compiler, $1)=$CC + _LT_CC_BASENAME([$compiler]) + + if test -n "$compiler"; then + AC_MSG_CHECKING([if libtool supports shared libraries]) + AC_MSG_RESULT([$can_build_shared]) + + AC_MSG_CHECKING([whether to build shared libraries]) + test no = "$can_build_shared" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test yes = "$enable_shared" && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + aix[[4-9]]*) + if test ia64 != "$host_cpu"; then + case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in + yes,aix,yes) ;; # shared object as lib.so file only + yes,svr4,*) ;; # shared object as lib.so archive member only + yes,*) enable_static=no ;; # shared object in lib.a archive as well + esac + fi + ;; + esac + AC_MSG_RESULT([$enable_shared]) + + AC_MSG_CHECKING([whether to build static libraries]) + # Make sure either enable_shared or enable_static is yes. + test yes = "$enable_shared" || enable_static=yes + AC_MSG_RESULT([$enable_static]) + + _LT_TAGVAR(GCC, $1)=$ac_cv_fc_compiler_gnu + _LT_TAGVAR(LD, $1)=$LD + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + _LT_SYS_HIDDEN_LIBDEPS($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) + fi # test -n "$compiler" + + GCC=$lt_save_GCC + CC=$lt_save_CC + CFLAGS=$lt_save_CFLAGS +fi # test yes != "$_lt_disable_FC" + +AC_LANG_POP +])# _LT_LANG_FC_CONFIG + + +# _LT_LANG_GCJ_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for the GNU Java Compiler compiler +# are suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to 'libtool'. +m4_defun([_LT_LANG_GCJ_CONFIG], +[AC_REQUIRE([LT_PROG_GCJ])dnl +AC_LANG_SAVE + +# Source file extension for Java test sources. +ac_ext=java + +# Object file extension for compiled Java test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="class foo {}" + +# Code to be used in simple link tests +lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }' + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_TAG_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC=$CC +lt_save_CFLAGS=$CFLAGS +lt_save_GCC=$GCC +GCC=yes +CC=${GCJ-"gcj"} +CFLAGS=$GCJFLAGS +compiler=$CC +_LT_TAGVAR(compiler, $1)=$CC +_LT_TAGVAR(LD, $1)=$LD +_LT_CC_BASENAME([$compiler]) + +# GCJ did not exist at the time GCC didn't implicitly link libc in. +_LT_TAGVAR(archive_cmds_need_lc, $1)=no + +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... +if test -n "$compiler"; then + _LT_COMPILER_NO_RTTI($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) +fi + +AC_LANG_RESTORE + +GCC=$lt_save_GCC +CC=$lt_save_CC +CFLAGS=$lt_save_CFLAGS +])# _LT_LANG_GCJ_CONFIG + + +# _LT_LANG_GO_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for the GNU Go compiler +# are suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to 'libtool'. +m4_defun([_LT_LANG_GO_CONFIG], +[AC_REQUIRE([LT_PROG_GO])dnl +AC_LANG_SAVE + +# Source file extension for Go test sources. +ac_ext=go + +# Object file extension for compiled Go test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="package main; func main() { }" + +# Code to be used in simple link tests +lt_simple_link_test_code='package main; func main() { }' + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_TAG_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC=$CC +lt_save_CFLAGS=$CFLAGS +lt_save_GCC=$GCC +GCC=yes +CC=${GOC-"gccgo"} +CFLAGS=$GOFLAGS +compiler=$CC +_LT_TAGVAR(compiler, $1)=$CC +_LT_TAGVAR(LD, $1)=$LD +_LT_CC_BASENAME([$compiler]) + +# Go did not exist at the time GCC didn't implicitly link libc in. +_LT_TAGVAR(archive_cmds_need_lc, $1)=no + +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... +if test -n "$compiler"; then + _LT_COMPILER_NO_RTTI($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) +fi + +AC_LANG_RESTORE + +GCC=$lt_save_GCC +CC=$lt_save_CC +CFLAGS=$lt_save_CFLAGS +])# _LT_LANG_GO_CONFIG + + +# _LT_LANG_RC_CONFIG([TAG]) +# ------------------------- +# Ensure that the configuration variables for the Windows resource compiler +# are suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to 'libtool'. +m4_defun([_LT_LANG_RC_CONFIG], +[AC_REQUIRE([LT_PROG_RC])dnl +AC_LANG_SAVE + +# Source file extension for RC test sources. +ac_ext=rc + +# Object file extension for compiled RC test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }' + +# Code to be used in simple link tests +lt_simple_link_test_code=$lt_simple_compile_test_code + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_TAG_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC=$CC +lt_save_CFLAGS=$CFLAGS +lt_save_GCC=$GCC +GCC= +CC=${RC-"windres"} +CFLAGS= +compiler=$CC +_LT_TAGVAR(compiler, $1)=$CC +_LT_CC_BASENAME([$compiler]) +_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes + +if test -n "$compiler"; then + : + _LT_CONFIG($1) +fi + +GCC=$lt_save_GCC +AC_LANG_RESTORE +CC=$lt_save_CC +CFLAGS=$lt_save_CFLAGS +])# _LT_LANG_RC_CONFIG + + +# LT_PROG_GCJ +# ----------- +AC_DEFUN([LT_PROG_GCJ], +[m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ], + [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ], + [AC_CHECK_TOOL(GCJ, gcj,) + test set = "${GCJFLAGS+set}" || GCJFLAGS="-g -O2" + AC_SUBST(GCJFLAGS)])])[]dnl +]) + +# Old name: +AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([LT_AC_PROG_GCJ], []) + + +# LT_PROG_GO +# ---------- +AC_DEFUN([LT_PROG_GO], +[AC_CHECK_TOOL(GOC, gccgo,) +]) + + +# LT_PROG_RC +# ---------- +AC_DEFUN([LT_PROG_RC], +[AC_CHECK_TOOL(RC, windres,) +]) + +# Old name: +AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([LT_AC_PROG_RC], []) + + +# _LT_DECL_EGREP +# -------------- +# If we don't have a new enough Autoconf to choose the best grep +# available, choose the one first in the user's PATH. +m4_defun([_LT_DECL_EGREP], +[AC_REQUIRE([AC_PROG_EGREP])dnl +AC_REQUIRE([AC_PROG_FGREP])dnl +test -z "$GREP" && GREP=grep +_LT_DECL([], [GREP], [1], [A grep program that handles long lines]) +_LT_DECL([], [EGREP], [1], [An ERE matcher]) +_LT_DECL([], [FGREP], [1], [A literal string matcher]) +dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too +AC_SUBST([GREP]) +]) + + +# _LT_DECL_OBJDUMP +# -------------- +# If we don't have a new enough Autoconf to choose the best objdump +# available, choose the one first in the user's PATH. +m4_defun([_LT_DECL_OBJDUMP], +[AC_CHECK_TOOL(OBJDUMP, objdump, false) +test -z "$OBJDUMP" && OBJDUMP=objdump +_LT_DECL([], [OBJDUMP], [1], [An object symbol dumper]) +AC_SUBST([OBJDUMP]) +]) + +# _LT_DECL_DLLTOOL +# ---------------- +# Ensure DLLTOOL variable is set. +m4_defun([_LT_DECL_DLLTOOL], +[AC_CHECK_TOOL(DLLTOOL, dlltool, false) +test -z "$DLLTOOL" && DLLTOOL=dlltool +_LT_DECL([], [DLLTOOL], [1], [DLL creation program]) +AC_SUBST([DLLTOOL]) +]) + +# _LT_DECL_SED +# ------------ +# Check for a fully-functional sed program, that truncates +# as few characters as possible. Prefer GNU sed if found. +m4_defun([_LT_DECL_SED], +[AC_PROG_SED +test -z "$SED" && SED=sed +Xsed="$SED -e 1s/^X//" +_LT_DECL([], [SED], [1], [A sed program that does not truncate output]) +_LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"], + [Sed that helps us avoid accidentally triggering echo(1) options like -n]) +])# _LT_DECL_SED + +m4_ifndef([AC_PROG_SED], [ +############################################################ +# NOTE: This macro has been submitted for inclusion into # +# GNU Autoconf as AC_PROG_SED. When it is available in # +# a released version of Autoconf we should remove this # +# macro and use it instead. # +############################################################ + +m4_defun([AC_PROG_SED], +[AC_MSG_CHECKING([for a sed that does not truncate output]) +AC_CACHE_VAL(lt_cv_path_SED, +[# Loop through the user's path and test for sed and gsed. +# Then use that list of sed's as ones to test for truncation. +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for lt_ac_prog in sed gsed; do + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then + lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" + fi + done + done +done +IFS=$as_save_IFS +lt_ac_max=0 +lt_ac_count=0 +# Add /usr/xpg4/bin/sed as it is typically found on Solaris +# along with /bin/sed that truncates output. +for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do + test ! -f "$lt_ac_sed" && continue + cat /dev/null > conftest.in + lt_ac_count=0 + echo $ECHO_N "0123456789$ECHO_C" >conftest.in + # Check for GNU sed and select it if it is found. + if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then + lt_cv_path_SED=$lt_ac_sed + break + fi + while true; do + cat conftest.in conftest.in >conftest.tmp + mv conftest.tmp conftest.in + cp conftest.in conftest.nl + echo >>conftest.nl + $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break + cmp -s conftest.out conftest.nl || break + # 10000 chars as input seems more than enough + test 10 -lt "$lt_ac_count" && break + lt_ac_count=`expr $lt_ac_count + 1` + if test "$lt_ac_count" -gt "$lt_ac_max"; then + lt_ac_max=$lt_ac_count + lt_cv_path_SED=$lt_ac_sed + fi + done +done +]) +SED=$lt_cv_path_SED +AC_SUBST([SED]) +AC_MSG_RESULT([$SED]) +])#AC_PROG_SED +])#m4_ifndef + +# Old name: +AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([LT_AC_PROG_SED], []) + + +# _LT_CHECK_SHELL_FEATURES +# ------------------------ +# Find out whether the shell is Bourne or XSI compatible, +# or has some other useful features. +m4_defun([_LT_CHECK_SHELL_FEATURES], +[if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + lt_unset=unset +else + lt_unset=false +fi +_LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl + +# test EBCDIC or ASCII +case `echo X|tr X '\101'` in + A) # ASCII based system + # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr + lt_SP2NL='tr \040 \012' + lt_NL2SP='tr \015\012 \040\040' + ;; + *) # EBCDIC based system + lt_SP2NL='tr \100 \n' + lt_NL2SP='tr \r\n \100\100' + ;; +esac +_LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl +_LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl +])# _LT_CHECK_SHELL_FEATURES + + +# _LT_PATH_CONVERSION_FUNCTIONS +# ----------------------------- +# Determine what file name conversion functions should be used by +# func_to_host_file (and, implicitly, by func_to_host_path). These are needed +# for certain cross-compile configurations and native mingw. +m4_defun([_LT_PATH_CONVERSION_FUNCTIONS], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +AC_MSG_CHECKING([how to convert $build file names to $host format]) +AC_CACHE_VAL(lt_cv_to_host_file_cmd, +[case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 + ;; + esac + ;; + *-*-cygwin* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin + ;; + esac + ;; + * ) # unhandled hosts (and "normal" native builds) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; +esac +]) +to_host_file_cmd=$lt_cv_to_host_file_cmd +AC_MSG_RESULT([$lt_cv_to_host_file_cmd]) +_LT_DECL([to_host_file_cmd], [lt_cv_to_host_file_cmd], + [0], [convert $build file names to $host format])dnl + +AC_MSG_CHECKING([how to convert $build file names to toolchain format]) +AC_CACHE_VAL(lt_cv_to_tool_file_cmd, +[#assume ordinary cross tools, or native build. +lt_cv_to_tool_file_cmd=func_convert_file_noop +case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 + ;; + esac + ;; +esac +]) +to_tool_file_cmd=$lt_cv_to_tool_file_cmd +AC_MSG_RESULT([$lt_cv_to_tool_file_cmd]) +_LT_DECL([to_tool_file_cmd], [lt_cv_to_tool_file_cmd], + [0], [convert $build files to toolchain format])dnl +])# _LT_PATH_CONVERSION_FUNCTIONS diff --git a/external/mit/isl/dist/m4/ltoptions.m4 b/external/mit/isl/dist/m4/ltoptions.m4 new file mode 100644 index 000000000000..94b082976667 --- /dev/null +++ b/external/mit/isl/dist/m4/ltoptions.m4 @@ -0,0 +1,437 @@ +# Helper functions for option handling. -*- Autoconf -*- +# +# Copyright (C) 2004-2005, 2007-2009, 2011-2015 Free Software +# Foundation, Inc. +# Written by Gary V. Vaughan, 2004 +# +# 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. + +# serial 8 ltoptions.m4 + +# This is to help aclocal find these macros, as it can't see m4_define. +AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])]) + + +# _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME) +# ------------------------------------------ +m4_define([_LT_MANGLE_OPTION], +[[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])]) + + +# _LT_SET_OPTION(MACRO-NAME, OPTION-NAME) +# --------------------------------------- +# Set option OPTION-NAME for macro MACRO-NAME, and if there is a +# matching handler defined, dispatch to it. Other OPTION-NAMEs are +# saved as a flag. +m4_define([_LT_SET_OPTION], +[m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl +m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]), + _LT_MANGLE_DEFUN([$1], [$2]), + [m4_warning([Unknown $1 option '$2'])])[]dnl +]) + + +# _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET]) +# ------------------------------------------------------------ +# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. +m4_define([_LT_IF_OPTION], +[m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])]) + + +# _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET) +# ------------------------------------------------------- +# Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME +# are set. +m4_define([_LT_UNLESS_OPTIONS], +[m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), + [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option), + [m4_define([$0_found])])])[]dnl +m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3 +])[]dnl +]) + + +# _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST) +# ---------------------------------------- +# OPTION-LIST is a space-separated list of Libtool options associated +# with MACRO-NAME. If any OPTION has a matching handler declared with +# LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about +# the unknown option and exit. +m4_defun([_LT_SET_OPTIONS], +[# Set options +m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), + [_LT_SET_OPTION([$1], _LT_Option)]) + +m4_if([$1],[LT_INIT],[ + dnl + dnl Simply set some default values (i.e off) if boolean options were not + dnl specified: + _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no + ]) + _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no + ]) + dnl + dnl If no reference was made to various pairs of opposing options, then + dnl we run the default mode handler for the pair. For example, if neither + dnl 'shared' nor 'disable-shared' was passed, we enable building of shared + dnl archives by default: + _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED]) + _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC]) + _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC]) + _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install], + [_LT_ENABLE_FAST_INSTALL]) + _LT_UNLESS_OPTIONS([LT_INIT], [aix-soname=aix aix-soname=both aix-soname=svr4], + [_LT_WITH_AIX_SONAME([aix])]) + ]) +])# _LT_SET_OPTIONS + + +## --------------------------------- ## +## Macros to handle LT_INIT options. ## +## --------------------------------- ## + +# _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME) +# ----------------------------------------- +m4_define([_LT_MANGLE_DEFUN], +[[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])]) + + +# LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE) +# ----------------------------------------------- +m4_define([LT_OPTION_DEFINE], +[m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl +])# LT_OPTION_DEFINE + + +# dlopen +# ------ +LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes +]) + +AU_DEFUN([AC_LIBTOOL_DLOPEN], +[_LT_SET_OPTION([LT_INIT], [dlopen]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you +put the 'dlopen' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], []) + + +# win32-dll +# --------- +# Declare package support for building win32 dll's. +LT_OPTION_DEFINE([LT_INIT], [win32-dll], +[enable_win32_dll=yes + +case $host in +*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) + AC_CHECK_TOOL(AS, as, false) + AC_CHECK_TOOL(DLLTOOL, dlltool, false) + AC_CHECK_TOOL(OBJDUMP, objdump, false) + ;; +esac + +test -z "$AS" && AS=as +_LT_DECL([], [AS], [1], [Assembler program])dnl + +test -z "$DLLTOOL" && DLLTOOL=dlltool +_LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl + +test -z "$OBJDUMP" && OBJDUMP=objdump +_LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl +])# win32-dll + +AU_DEFUN([AC_LIBTOOL_WIN32_DLL], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +_LT_SET_OPTION([LT_INIT], [win32-dll]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you +put the 'win32-dll' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], []) + + +# _LT_ENABLE_SHARED([DEFAULT]) +# ---------------------------- +# implement the --enable-shared flag, and supports the 'shared' and +# 'disable-shared' LT_INIT options. +# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. +m4_define([_LT_ENABLE_SHARED], +[m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl +AC_ARG_ENABLE([shared], + [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@], + [build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_shared=yes ;; + no) enable_shared=no ;; + *) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for pkg in $enableval; do + IFS=$lt_save_ifs + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS=$lt_save_ifs + ;; + esac], + [enable_shared=]_LT_ENABLE_SHARED_DEFAULT) + + _LT_DECL([build_libtool_libs], [enable_shared], [0], + [Whether or not to build shared libraries]) +])# _LT_ENABLE_SHARED + +LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])]) +LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])]) + +# Old names: +AC_DEFUN([AC_ENABLE_SHARED], +[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared]) +]) + +AC_DEFUN([AC_DISABLE_SHARED], +[_LT_SET_OPTION([LT_INIT], [disable-shared]) +]) + +AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) +AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AM_ENABLE_SHARED], []) +dnl AC_DEFUN([AM_DISABLE_SHARED], []) + + + +# _LT_ENABLE_STATIC([DEFAULT]) +# ---------------------------- +# implement the --enable-static flag, and support the 'static' and +# 'disable-static' LT_INIT options. +# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. +m4_define([_LT_ENABLE_STATIC], +[m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl +AC_ARG_ENABLE([static], + [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@], + [build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_static=yes ;; + no) enable_static=no ;; + *) + enable_static=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for pkg in $enableval; do + IFS=$lt_save_ifs + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS=$lt_save_ifs + ;; + esac], + [enable_static=]_LT_ENABLE_STATIC_DEFAULT) + + _LT_DECL([build_old_libs], [enable_static], [0], + [Whether or not to build static libraries]) +])# _LT_ENABLE_STATIC + +LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])]) +LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])]) + +# Old names: +AC_DEFUN([AC_ENABLE_STATIC], +[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static]) +]) + +AC_DEFUN([AC_DISABLE_STATIC], +[_LT_SET_OPTION([LT_INIT], [disable-static]) +]) + +AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) +AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AM_ENABLE_STATIC], []) +dnl AC_DEFUN([AM_DISABLE_STATIC], []) + + + +# _LT_ENABLE_FAST_INSTALL([DEFAULT]) +# ---------------------------------- +# implement the --enable-fast-install flag, and support the 'fast-install' +# and 'disable-fast-install' LT_INIT options. +# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. +m4_define([_LT_ENABLE_FAST_INSTALL], +[m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl +AC_ARG_ENABLE([fast-install], + [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], + [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_fast_install=yes ;; + no) enable_fast_install=no ;; + *) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for pkg in $enableval; do + IFS=$lt_save_ifs + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS=$lt_save_ifs + ;; + esac], + [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT) + +_LT_DECL([fast_install], [enable_fast_install], [0], + [Whether or not to optimize for fast installation])dnl +])# _LT_ENABLE_FAST_INSTALL + +LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])]) +LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])]) + +# Old names: +AU_DEFUN([AC_ENABLE_FAST_INSTALL], +[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you put +the 'fast-install' option into LT_INIT's first parameter.]) +]) + +AU_DEFUN([AC_DISABLE_FAST_INSTALL], +[_LT_SET_OPTION([LT_INIT], [disable-fast-install]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you put +the 'disable-fast-install' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], []) +dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], []) + + +# _LT_WITH_AIX_SONAME([DEFAULT]) +# ---------------------------------- +# implement the --with-aix-soname flag, and support the `aix-soname=aix' +# and `aix-soname=both' and `aix-soname=svr4' LT_INIT options. DEFAULT +# is either `aix', `both' or `svr4'. If omitted, it defaults to `aix'. +m4_define([_LT_WITH_AIX_SONAME], +[m4_define([_LT_WITH_AIX_SONAME_DEFAULT], [m4_if($1, svr4, svr4, m4_if($1, both, both, aix))])dnl +shared_archive_member_spec= +case $host,$enable_shared in +power*-*-aix[[5-9]]*,yes) + AC_MSG_CHECKING([which variant of shared library versioning to provide]) + AC_ARG_WITH([aix-soname], + [AS_HELP_STRING([--with-aix-soname=aix|svr4|both], + [shared library versioning (aka "SONAME") variant to provide on AIX, @<:@default=]_LT_WITH_AIX_SONAME_DEFAULT[@:>@.])], + [case $withval in + aix|svr4|both) + ;; + *) + AC_MSG_ERROR([Unknown argument to --with-aix-soname]) + ;; + esac + lt_cv_with_aix_soname=$with_aix_soname], + [AC_CACHE_VAL([lt_cv_with_aix_soname], + [lt_cv_with_aix_soname=]_LT_WITH_AIX_SONAME_DEFAULT) + with_aix_soname=$lt_cv_with_aix_soname]) + AC_MSG_RESULT([$with_aix_soname]) + if test aix != "$with_aix_soname"; then + # For the AIX way of multilib, we name the shared archive member + # based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o', + # and 'shr.imp' or 'shr_64.imp', respectively, for the Import File. + # Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag, + # the AIX toolchain works better with OBJECT_MODE set (default 32). + if test 64 = "${OBJECT_MODE-32}"; then + shared_archive_member_spec=shr_64 + else + shared_archive_member_spec=shr + fi + fi + ;; +*) + with_aix_soname=aix + ;; +esac + +_LT_DECL([], [shared_archive_member_spec], [0], + [Shared archive member basename, for filename based shared library versioning on AIX])dnl +])# _LT_WITH_AIX_SONAME + +LT_OPTION_DEFINE([LT_INIT], [aix-soname=aix], [_LT_WITH_AIX_SONAME([aix])]) +LT_OPTION_DEFINE([LT_INIT], [aix-soname=both], [_LT_WITH_AIX_SONAME([both])]) +LT_OPTION_DEFINE([LT_INIT], [aix-soname=svr4], [_LT_WITH_AIX_SONAME([svr4])]) + + +# _LT_WITH_PIC([MODE]) +# -------------------- +# implement the --with-pic flag, and support the 'pic-only' and 'no-pic' +# LT_INIT options. +# MODE is either 'yes' or 'no'. If omitted, it defaults to 'both'. +m4_define([_LT_WITH_PIC], +[AC_ARG_WITH([pic], + [AS_HELP_STRING([--with-pic@<:@=PKGS@:>@], + [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], + [lt_p=${PACKAGE-default} + case $withval in + yes|no) pic_mode=$withval ;; + *) + pic_mode=default + # Look at the argument we got. We use all the common list separators. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for lt_pkg in $withval; do + IFS=$lt_save_ifs + if test "X$lt_pkg" = "X$lt_p"; then + pic_mode=yes + fi + done + IFS=$lt_save_ifs + ;; + esac], + [pic_mode=m4_default([$1], [default])]) + +_LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl +])# _LT_WITH_PIC + +LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])]) +LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])]) + +# Old name: +AU_DEFUN([AC_LIBTOOL_PICMODE], +[_LT_SET_OPTION([LT_INIT], [pic-only]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you +put the 'pic-only' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_PICMODE], []) + +## ----------------- ## +## LTDL_INIT Options ## +## ----------------- ## + +m4_define([_LTDL_MODE], []) +LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive], + [m4_define([_LTDL_MODE], [nonrecursive])]) +LT_OPTION_DEFINE([LTDL_INIT], [recursive], + [m4_define([_LTDL_MODE], [recursive])]) +LT_OPTION_DEFINE([LTDL_INIT], [subproject], + [m4_define([_LTDL_MODE], [subproject])]) + +m4_define([_LTDL_TYPE], []) +LT_OPTION_DEFINE([LTDL_INIT], [installable], + [m4_define([_LTDL_TYPE], [installable])]) +LT_OPTION_DEFINE([LTDL_INIT], [convenience], + [m4_define([_LTDL_TYPE], [convenience])]) diff --git a/external/mit/isl/dist/m4/ltsugar.m4 b/external/mit/isl/dist/m4/ltsugar.m4 new file mode 100644 index 000000000000..48bc9344a4d6 --- /dev/null +++ b/external/mit/isl/dist/m4/ltsugar.m4 @@ -0,0 +1,124 @@ +# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*- +# +# Copyright (C) 2004-2005, 2007-2008, 2011-2015 Free Software +# Foundation, Inc. +# Written by Gary V. Vaughan, 2004 +# +# 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. + +# serial 6 ltsugar.m4 + +# This is to help aclocal find these macros, as it can't see m4_define. +AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])]) + + +# lt_join(SEP, ARG1, [ARG2...]) +# ----------------------------- +# Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their +# associated separator. +# Needed until we can rely on m4_join from Autoconf 2.62, since all earlier +# versions in m4sugar had bugs. +m4_define([lt_join], +[m4_if([$#], [1], [], + [$#], [2], [[$2]], + [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])]) +m4_define([_lt_join], +[m4_if([$#$2], [2], [], + [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])]) + + +# lt_car(LIST) +# lt_cdr(LIST) +# ------------ +# Manipulate m4 lists. +# These macros are necessary as long as will still need to support +# Autoconf-2.59, which quotes differently. +m4_define([lt_car], [[$1]]) +m4_define([lt_cdr], +[m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])], + [$#], 1, [], + [m4_dquote(m4_shift($@))])]) +m4_define([lt_unquote], $1) + + +# lt_append(MACRO-NAME, STRING, [SEPARATOR]) +# ------------------------------------------ +# Redefine MACRO-NAME to hold its former content plus 'SEPARATOR''STRING'. +# Note that neither SEPARATOR nor STRING are expanded; they are appended +# to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked). +# No SEPARATOR is output if MACRO-NAME was previously undefined (different +# than defined and empty). +# +# This macro is needed until we can rely on Autoconf 2.62, since earlier +# versions of m4sugar mistakenly expanded SEPARATOR but not STRING. +m4_define([lt_append], +[m4_define([$1], + m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])]) + + + +# lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...]) +# ---------------------------------------------------------- +# Produce a SEP delimited list of all paired combinations of elements of +# PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list +# has the form PREFIXmINFIXSUFFIXn. +# Needed until we can rely on m4_combine added in Autoconf 2.62. +m4_define([lt_combine], +[m4_if(m4_eval([$# > 3]), [1], + [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl +[[m4_foreach([_Lt_prefix], [$2], + [m4_foreach([_Lt_suffix], + ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[, + [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])]) + + +# lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ]) +# ----------------------------------------------------------------------- +# Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited +# by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ. +m4_define([lt_if_append_uniq], +[m4_ifdef([$1], + [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1], + [lt_append([$1], [$2], [$3])$4], + [$5])], + [lt_append([$1], [$2], [$3])$4])]) + + +# lt_dict_add(DICT, KEY, VALUE) +# ----------------------------- +m4_define([lt_dict_add], +[m4_define([$1($2)], [$3])]) + + +# lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE) +# -------------------------------------------- +m4_define([lt_dict_add_subkey], +[m4_define([$1($2:$3)], [$4])]) + + +# lt_dict_fetch(DICT, KEY, [SUBKEY]) +# ---------------------------------- +m4_define([lt_dict_fetch], +[m4_ifval([$3], + m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]), + m4_ifdef([$1($2)], [m4_defn([$1($2)])]))]) + + +# lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE]) +# ----------------------------------------------------------------- +m4_define([lt_if_dict_fetch], +[m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4], + [$5], + [$6])]) + + +# lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...]) +# -------------------------------------------------------------- +m4_define([lt_dict_filter], +[m4_if([$5], [], [], + [lt_join(m4_quote(m4_default([$4], [[, ]])), + lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]), + [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl +]) diff --git a/external/mit/isl/dist/m4/ltversion.m4 b/external/mit/isl/dist/m4/ltversion.m4 new file mode 100644 index 000000000000..fa04b52a3bf8 --- /dev/null +++ b/external/mit/isl/dist/m4/ltversion.m4 @@ -0,0 +1,23 @@ +# ltversion.m4 -- version numbers -*- Autoconf -*- +# +# Copyright (C) 2004, 2011-2015 Free Software Foundation, Inc. +# Written by Scott James Remnant, 2004 +# +# 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. + +# @configure_input@ + +# serial 4179 ltversion.m4 +# This file is part of GNU Libtool + +m4_define([LT_PACKAGE_VERSION], [2.4.6]) +m4_define([LT_PACKAGE_REVISION], [2.4.6]) + +AC_DEFUN([LTVERSION_VERSION], +[macro_version='2.4.6' +macro_revision='2.4.6' +_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) +_LT_DECL(, macro_revision, 0) +]) diff --git a/external/mit/isl/dist/m4/lt~obsolete.m4 b/external/mit/isl/dist/m4/lt~obsolete.m4 new file mode 100644 index 000000000000..c6b26f88f6c3 --- /dev/null +++ b/external/mit/isl/dist/m4/lt~obsolete.m4 @@ -0,0 +1,99 @@ +# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*- +# +# Copyright (C) 2004-2005, 2007, 2009, 2011-2015 Free Software +# Foundation, Inc. +# Written by Scott James Remnant, 2004. +# +# 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. + +# serial 5 lt~obsolete.m4 + +# These exist entirely to fool aclocal when bootstrapping libtool. +# +# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN), +# which have later been changed to m4_define as they aren't part of the +# exported API, or moved to Autoconf or Automake where they belong. +# +# The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN +# in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us +# using a macro with the same name in our local m4/libtool.m4 it'll +# pull the old libtool.m4 in (it doesn't see our shiny new m4_define +# and doesn't know about Autoconf macros at all.) +# +# So we provide this file, which has a silly filename so it's always +# included after everything else. This provides aclocal with the +# AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything +# because those macros already exist, or will be overwritten later. +# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. +# +# Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here. +# Yes, that means every name once taken will need to remain here until +# we give up compatibility with versions before 1.7, at which point +# we need to keep only those names which we still refer to. + +# This is to help aclocal find these macros, as it can't see m4_define. +AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])]) + +m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])]) +m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])]) +m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])]) +m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])]) +m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])]) +m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])]) +m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])]) +m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])]) +m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])]) +m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])]) +m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])]) +m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])]) +m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])]) +m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])]) +m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])]) +m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])]) +m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])]) +m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])]) +m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])]) +m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])]) +m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])]) +m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])]) +m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])]) +m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])]) +m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])]) +m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])]) +m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])]) +m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])]) +m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])]) +m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])]) +m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])]) +m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])]) +m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])]) +m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])]) +m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])]) +m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])]) +m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])]) +m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])]) +m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])]) +m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])]) +m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])]) +m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])]) +m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])]) +m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])]) +m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])]) +m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])]) +m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])]) +m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])]) +m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])]) +m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])]) +m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])]) +m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])]) +m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])]) +m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])]) +m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])]) +m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])]) +m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])]) diff --git a/external/mit/isl/dist/missing b/external/mit/isl/dist/missing new file mode 100755 index 000000000000..1fe1611f1851 --- /dev/null +++ b/external/mit/isl/dist/missing @@ -0,0 +1,215 @@ +#! /bin/sh +# Common wrapper for a few potentially missing GNU programs. + +scriptversion=2018-03-07.03; # UTC + +# Copyright (C) 1996-2021 Free Software Foundation, Inc. +# Originally written by Fran,cois Pinard , 1996. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +if test $# -eq 0; then + echo 1>&2 "Try '$0 --help' for more information" + exit 1 +fi + +case $1 in + + --is-lightweight) + # Used by our autoconf macros to check whether the available missing + # script is modern enough. + exit 0 + ;; + + --run) + # Back-compat with the calling convention used by older automake. + shift + ;; + + -h|--h|--he|--hel|--help) + echo "\ +$0 [OPTION]... PROGRAM [ARGUMENT]... + +Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due +to PROGRAM being missing or too old. + +Options: + -h, --help display this help and exit + -v, --version output version information and exit + +Supported PROGRAM values: + aclocal autoconf autoheader autom4te automake makeinfo + bison yacc flex lex help2man + +Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and +'g' are ignored when checking the name. + +Send bug reports to ." + exit $? + ;; + + -v|--v|--ve|--ver|--vers|--versi|--versio|--version) + echo "missing $scriptversion (GNU Automake)" + exit $? + ;; + + -*) + echo 1>&2 "$0: unknown '$1' option" + echo 1>&2 "Try '$0 --help' for more information" + exit 1 + ;; + +esac + +# Run the given program, remember its exit status. +"$@"; st=$? + +# If it succeeded, we are done. +test $st -eq 0 && exit 0 + +# Also exit now if we it failed (or wasn't found), and '--version' was +# passed; such an option is passed most likely to detect whether the +# program is present and works. +case $2 in --version|--help) exit $st;; esac + +# Exit code 63 means version mismatch. This often happens when the user +# tries to use an ancient version of a tool on a file that requires a +# minimum version. +if test $st -eq 63; then + msg="probably too old" +elif test $st -eq 127; then + # Program was missing. + msg="missing on your system" +else + # Program was found and executed, but failed. Give up. + exit $st +fi + +perl_URL=https://www.perl.org/ +flex_URL=https://github.com/westes/flex +gnu_software_URL=https://www.gnu.org/software + +program_details () +{ + case $1 in + aclocal|automake) + echo "The '$1' program is part of the GNU Automake package:" + echo "<$gnu_software_URL/automake>" + echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:" + echo "<$gnu_software_URL/autoconf>" + echo "<$gnu_software_URL/m4/>" + echo "<$perl_URL>" + ;; + autoconf|autom4te|autoheader) + echo "The '$1' program is part of the GNU Autoconf package:" + echo "<$gnu_software_URL/autoconf/>" + echo "It also requires GNU m4 and Perl in order to run:" + echo "<$gnu_software_URL/m4/>" + echo "<$perl_URL>" + ;; + esac +} + +give_advice () +{ + # Normalize program name to check for. + normalized_program=`echo "$1" | sed ' + s/^gnu-//; t + s/^gnu//; t + s/^g//; t'` + + printf '%s\n' "'$1' is $msg." + + configure_deps="'configure.ac' or m4 files included by 'configure.ac'" + case $normalized_program in + autoconf*) + echo "You should only need it if you modified 'configure.ac'," + echo "or m4 files included by it." + program_details 'autoconf' + ;; + autoheader*) + echo "You should only need it if you modified 'acconfig.h' or" + echo "$configure_deps." + program_details 'autoheader' + ;; + automake*) + echo "You should only need it if you modified 'Makefile.am' or" + echo "$configure_deps." + program_details 'automake' + ;; + aclocal*) + echo "You should only need it if you modified 'acinclude.m4' or" + echo "$configure_deps." + program_details 'aclocal' + ;; + autom4te*) + echo "You might have modified some maintainer files that require" + echo "the 'autom4te' program to be rebuilt." + program_details 'autom4te' + ;; + bison*|yacc*) + echo "You should only need it if you modified a '.y' file." + echo "You may want to install the GNU Bison package:" + echo "<$gnu_software_URL/bison/>" + ;; + lex*|flex*) + echo "You should only need it if you modified a '.l' file." + echo "You may want to install the Fast Lexical Analyzer package:" + echo "<$flex_URL>" + ;; + help2man*) + echo "You should only need it if you modified a dependency" \ + "of a man page." + echo "You may want to install the GNU Help2man package:" + echo "<$gnu_software_URL/help2man/>" + ;; + makeinfo*) + echo "You should only need it if you modified a '.texi' file, or" + echo "any other file indirectly affecting the aspect of the manual." + echo "You might want to install the Texinfo package:" + echo "<$gnu_software_URL/texinfo/>" + echo "The spurious makeinfo call might also be the consequence of" + echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might" + echo "want to install GNU make:" + echo "<$gnu_software_URL/make/>" + ;; + *) + echo "You might have modified some files without having the proper" + echo "tools for further handling them. Check the 'README' file, it" + echo "often tells you about the needed prerequisites for installing" + echo "this package. You may also peek at any GNU archive site, in" + echo "case some other package contains this missing '$1' program." + ;; + esac +} + +give_advice "$1" | sed -e '1s/^/WARNING: /' \ + -e '2,$s/^/ /' >&2 + +# Propagate the correct exit status (expected to be 127 for a program +# not found, 63 for a program that failed due to version mismatch). +exit $st + +# Local variables: +# eval: (add-hook 'before-save-hook 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC0" +# time-stamp-end: "; # UTC" +# End: diff --git a/external/mit/isl/dist/mp_get_memory_functions.c b/external/mit/isl/dist/mp_get_memory_functions.c new file mode 100644 index 000000000000..e14e336ceb68 --- /dev/null +++ b/external/mit/isl/dist/mp_get_memory_functions.c @@ -0,0 +1,14 @@ +#include + +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)) +{ + if (alloc_func_ptr) + *alloc_func_ptr = __gmp_allocate_func; + if (realloc_func_ptr) + *realloc_func_ptr = __gmp_reallocate_func; + if (free_func_ptr) + *free_func_ptr = __gmp_free_func; +} diff --git a/external/mit/isl/dist/opt_type.h b/external/mit/isl/dist/opt_type.h new file mode 100644 index 000000000000..9505e72c20bf --- /dev/null +++ b/external/mit/isl/dist/opt_type.h @@ -0,0 +1,16 @@ +#define NO_LOC +#ifdef HAS_TYPE +#define OPT_TYPE_PARAM , enum isl_fold type +#define OPT_TYPE_PARAM_FIRST enum isl_fold type, +#define OPT_TYPE_ARG(loc) , loc type +#define OPT_TYPE_ARG_FIRST(loc) loc type, +#define OPT_SET_TYPE(loc,val) loc type = (val); +#define OPT_EQUAL_TYPES(loc1, loc2) ((loc1 type) == (loc2 type)) +#else +#define OPT_TYPE_PARAM +#define OPT_TYPE_PARAM_FIRST +#define OPT_TYPE_ARG(loc) +#define OPT_TYPE_ARG_FIRST(loc) +#define OPT_SET_TYPE(loc,val) +#define OPT_EQUAL_TYPES(loc1, loc2) 1 +#endif diff --git a/external/mit/isl/dist/pip.c b/external/mit/isl/dist/pip.c new file mode 100644 index 000000000000..e968ca71dd67 --- /dev/null +++ b/external/mit/isl/dist/pip.c @@ -0,0 +1,432 @@ +/* + * 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 + */ + +#include +#include +#include +#include +#include +#include "isl_sample.h" +#include "isl_scan.h" +#include +#include +#include +#include +#include +#include +#include + +/* The input of this program is the same as that of the "example" program + * from the PipLib distribution, except that the "big parameter column" + * should always be -1. + * + * Context constraints in PolyLib format + * -1 + * Problem constraints in PolyLib format + * Optional list of options + * + * The options are + * Maximize compute maximum instead of minimum + * Rational compute rational optimum instead of integer optimum + * Urs_parms don't assume parameters are non-negative + * Urs_unknowns don't assume unknowns are non-negative + */ + +struct options { + struct isl_options *isl; + unsigned verify; + unsigned format; +}; + +#define FORMAT_SET 0 +#define FORMAT_AFF 1 + +struct isl_arg_choice pip_format[] = { + {"set", FORMAT_SET}, + {"affine", FORMAT_AFF}, + {0} +}; + +ISL_ARGS_START(struct options, options_args) +ISL_ARG_CHILD(struct options, isl, "isl", &isl_options_args, "isl options") +ISL_ARG_BOOL(struct options, verify, 'T', "verify", 0, NULL) +ISL_ARG_CHOICE(struct options, format, 0, "format", + pip_format, FORMAT_SET, "output format") +ISL_ARGS_END + +ISL_ARG_DEF(options, struct options, options_args) + +static __isl_give isl_basic_set *set_bounds(__isl_take isl_basic_set *bset) +{ + isl_size nparam; + int i, r; + isl_point *pt, *pt2; + isl_basic_set *box; + + nparam = isl_basic_set_dim(bset, isl_dim_param); + if (nparam < 0) + return isl_basic_set_free(bset); + r = nparam >= 8 ? 4 : nparam >= 5 ? 6 : 30; + + pt = isl_basic_set_sample_point(isl_basic_set_copy(bset)); + pt2 = isl_point_copy(pt); + + for (i = 0; i < nparam; ++i) { + pt = isl_point_add_ui(pt, isl_dim_param, i, r); + pt2 = isl_point_sub_ui(pt2, isl_dim_param, i, r); + } + + box = isl_basic_set_box_from_points(pt, pt2); + + return isl_basic_set_intersect(bset, box); +} + +static __isl_give isl_basic_set *to_parameter_domain( + __isl_take isl_basic_set *context) +{ + isl_size dim; + + dim = isl_basic_set_dim(context, isl_dim_set); + if (dim < 0) + return isl_basic_set_free(context); + context = isl_basic_set_move_dims(context, isl_dim_param, 0, + isl_dim_set, 0, dim); + context = isl_basic_set_params(context); + return context; +} + +/* If "context" has more parameters than "bset", then reinterpret + * the last dimensions of "bset" as parameters. + */ +static __isl_give isl_basic_set *move_parameters(__isl_take isl_basic_set *bset, + __isl_keep isl_basic_set *context) +{ + isl_size nparam, nparam_bset, dim; + + nparam = isl_basic_set_dim(context, isl_dim_param); + nparam_bset = isl_basic_set_dim(bset, isl_dim_param); + if (nparam < 0 || nparam_bset < 0) + return isl_basic_set_free(bset); + if (nparam == nparam_bset) + return bset; + dim = isl_basic_set_dim(bset, isl_dim_set); + if (dim < 0) + return isl_basic_set_free(bset); + bset = isl_basic_set_move_dims(bset, isl_dim_param, 0, + isl_dim_set, dim - nparam, nparam); + return bset; +} + +/* Plug in the initial values of "params" for the parameters in "bset" and + * return the result. The remaining entries in "params", if any, + * correspond to the existentially quantified variables in the description + * of the original context and can be ignored. + */ +static __isl_give isl_basic_set *plug_in_parameters( + __isl_take isl_basic_set *bset, __isl_take isl_vec *params) +{ + int i; + isl_size n; + + n = isl_basic_set_dim(bset, isl_dim_param); + if (n < 0) + bset = isl_basic_set_free(bset); + for (i = 0; i < n; ++i) + bset = isl_basic_set_fix(bset, + isl_dim_param, i, params->el[1 + i]); + + bset = isl_basic_set_remove_dims(bset, isl_dim_param, 0, n); + + isl_vec_free(params); + + return bset; +} + +/* Plug in the initial values of "params" for the parameters in "set" and + * return the result. The remaining entries in "params", if any, + * correspond to the existentially quantified variables in the description + * of the original context and can be ignored. + */ +static __isl_give isl_set *set_plug_in_parameters(__isl_take isl_set *set, + __isl_take isl_vec *params) +{ + int i; + isl_size n; + + n = isl_set_dim(set, isl_dim_param); + if (n < 0) + set = isl_set_free(set); + for (i = 0; i < n; ++i) + set = isl_set_fix(set, isl_dim_param, i, params->el[1 + i]); + + set = isl_set_remove_dims(set, isl_dim_param, 0, n); + + isl_vec_free(params); + + return set; +} + +/* Compute the lexicographically minimal (or maximal if max is set) + * element of bset for the given values of the parameters, by + * successively solving an ilp problem in each direction. + */ +static __isl_give isl_vec *opt_at(__isl_take isl_basic_set *bset, + __isl_take isl_vec *params, int max) +{ + isl_size dim; + isl_ctx *ctx; + struct isl_vec *opt; + struct isl_vec *obj; + int i; + + dim = isl_basic_set_dim(bset, isl_dim_set); + if (dim < 0) + goto error; + + bset = plug_in_parameters(bset, params); + + ctx = isl_basic_set_get_ctx(bset); + if (isl_basic_set_plain_is_empty(bset)) { + opt = isl_vec_alloc(ctx, 0); + isl_basic_set_free(bset); + return opt; + } + + opt = isl_vec_alloc(ctx, 1 + dim); + assert(opt); + + obj = isl_vec_alloc(ctx, 1 + dim); + assert(obj); + + isl_int_set_si(opt->el[0], 1); + isl_int_set_si(obj->el[0], 0); + + for (i = 0; i < dim; ++i) { + enum isl_lp_result res; + + isl_seq_clr(obj->el + 1, dim); + isl_int_set_si(obj->el[1 + i], 1); + res = isl_basic_set_solve_ilp(bset, max, obj->el, + &opt->el[1 + i], NULL); + if (res == isl_lp_empty) + goto empty; + assert(res == isl_lp_ok); + bset = isl_basic_set_fix(bset, isl_dim_set, i, opt->el[1 + i]); + } + + isl_basic_set_free(bset); + isl_vec_free(obj); + + return opt; +error: + isl_basic_set_free(bset); + isl_vec_free(params); + return NULL; +empty: + isl_vec_free(opt); + opt = isl_vec_alloc(ctx, 0); + isl_basic_set_free(bset); + isl_vec_free(obj); + + return opt; +} + +struct isl_scan_pip { + struct isl_scan_callback callback; + isl_basic_set *bset; + isl_set *sol; + isl_set *empty; + int stride; + int n; + int max; +}; + +/* Check if the "manually" computed optimum of bset at the "sample" + * values of the parameters agrees with the solution of pilp problem + * represented by the pair (sol, empty). + * In particular, if there is no solution for this value of the parameters, + * then it should be an element of the parameter domain "empty". + * Otherwise, the optimal solution, should be equal to the result of + * plugging in the value of the parameters in "sol". + */ +static isl_stat scan_one(struct isl_scan_callback *callback, + __isl_take isl_vec *sample) +{ + struct isl_scan_pip *sp = (struct isl_scan_pip *)callback; + struct isl_vec *opt; + + sp->n--; + + opt = opt_at(isl_basic_set_copy(sp->bset), isl_vec_copy(sample), sp->max); + assert(opt); + + if (opt->size == 0) { + isl_point *sample_pnt; + sample_pnt = isl_point_alloc(isl_set_get_space(sp->empty), sample); + assert(isl_set_contains_point(sp->empty, sample_pnt)); + isl_point_free(sample_pnt); + isl_vec_free(opt); + } else { + isl_set *sol; + isl_set *opt_set; + opt_set = isl_set_from_basic_set(isl_basic_set_from_vec(opt)); + sol = set_plug_in_parameters(isl_set_copy(sp->sol), sample); + assert(isl_set_is_equal(opt_set, sol)); + isl_set_free(sol); + isl_set_free(opt_set); + } + + if (!(sp->n % sp->stride)) { + printf("o"); + fflush(stdout); + } + + return sp->n >= 1 ? isl_stat_ok : isl_stat_error; +} + +static void check_solution(isl_basic_set *bset, isl_basic_set *context, + isl_set *sol, isl_set *empty, int max) +{ + struct isl_scan_pip sp; + isl_int count, count_max; + int i, n; + int r; + + context = set_bounds(context); + context = isl_basic_set_underlying_set(context); + + isl_int_init(count); + isl_int_init(count_max); + + isl_int_set_si(count_max, 2000); + r = isl_basic_set_count_upto(context, count_max, &count); + assert(r >= 0); + n = isl_int_get_si(count); + + isl_int_clear(count_max); + isl_int_clear(count); + + sp.callback.add = scan_one; + sp.bset = bset; + sp.sol = sol; + sp.empty = empty; + sp.n = n; + sp.stride = n > 70 ? 1 + (n + 1)/70 : 1; + sp.max = max; + + for (i = 0; i < n; i += sp.stride) + printf("."); + printf("\r"); + fflush(stdout); + + isl_basic_set_scan(context, &sp.callback); + + printf("\n"); + + isl_basic_set_free(bset); +} + +int main(int argc, char **argv) +{ + struct isl_ctx *ctx; + struct isl_basic_set *context, *bset, *copy, *context_copy; + struct isl_set *set = NULL; + struct isl_set *empty; + isl_pw_multi_aff *pma = NULL; + int neg_one; + char s[1024]; + int urs_parms = 0; + int urs_unknowns = 0; + int max = 0; + int rational = 0; + int n; + struct options *options; + + options = options_new_with_defaults(); + assert(options); + argc = options_parse(options, argc, argv, ISL_ARG_ALL); + + ctx = isl_ctx_alloc_with_options(&options_args, options); + + context = isl_basic_set_read_from_file(ctx, stdin); + assert(context); + n = fscanf(stdin, "%d", &neg_one); + assert(n == 1); + assert(neg_one == -1); + bset = isl_basic_set_read_from_file(ctx, stdin); + + while (fgets(s, sizeof(s), stdin)) { + if (strncasecmp(s, "Maximize", 8) == 0) + max = 1; + if (strncasecmp(s, "Rational", 8) == 0) { + rational = 1; + bset = isl_basic_set_set_rational(bset); + } + if (strncasecmp(s, "Urs_parms", 9) == 0) + urs_parms = 1; + if (strncasecmp(s, "Urs_unknowns", 12) == 0) + urs_unknowns = 1; + } + if (!urs_parms) + context = isl_basic_set_intersect(context, + isl_basic_set_positive_orthant(isl_basic_set_get_space(context))); + context = to_parameter_domain(context); + bset = move_parameters(bset, context); + if (!urs_unknowns) + bset = isl_basic_set_intersect(bset, + isl_basic_set_positive_orthant(isl_basic_set_get_space(bset))); + + if (options->verify) { + copy = isl_basic_set_copy(bset); + context_copy = isl_basic_set_copy(context); + } + + if (options->format == FORMAT_AFF) { + if (max) + pma = isl_basic_set_partial_lexmax_pw_multi_aff(bset, + context, &empty); + else + pma = isl_basic_set_partial_lexmin_pw_multi_aff(bset, + context, &empty); + } else { + if (max) + set = isl_basic_set_partial_lexmax(bset, + context, &empty); + else + set = isl_basic_set_partial_lexmin(bset, + context, &empty); + } + + if (options->verify) { + assert(!rational); + if (options->format == FORMAT_AFF) + set = isl_set_from_pw_multi_aff(pma); + check_solution(copy, context_copy, set, empty, max); + isl_set_free(set); + } else { + isl_printer *p; + p = isl_printer_to_file(ctx, stdout); + if (options->format == FORMAT_AFF) + p = isl_printer_print_pw_multi_aff(p, pma); + else + p = isl_printer_print_set(p, set); + p = isl_printer_end_line(p); + p = isl_printer_print_str(p, "no solution: "); + p = isl_printer_print_set(p, empty); + p = isl_printer_end_line(p); + isl_printer_free(p); + isl_set_free(set); + isl_pw_multi_aff_free(pma); + } + + isl_set_free(empty); + isl_ctx_free(ctx); + + return 0; +} diff --git a/external/mit/isl/dist/pip_test.sh.in b/external/mit/isl/dist/pip_test.sh.in new file mode 100755 index 000000000000..5f36b776f963 --- /dev/null +++ b/external/mit/isl/dist/pip_test.sh.in @@ -0,0 +1,31 @@ +#!/bin/sh + +EXEEXT=@EXEEXT@ +srcdir=@srcdir@ + +PIP_TESTS="\ + boulet.pip \ + brisebarre.pip \ + cg1.pip \ + esced.pip \ + ex2.pip \ + ex.pip \ + exist.pip \ + exist2.pip \ + fimmel.pip \ + max.pip \ + negative.pip \ + seghir-vd.pip \ + small.pip \ + sor1d.pip \ + square.pip \ + sven.pip \ + tobi.pip" + +for i in $PIP_TESTS; do + echo $i; + ./isl_pip$EXEEXT --format=set --context=gbr -T < $srcdir/test_inputs/$i || exit + ./isl_pip$EXEEXT --format=set --context=lexmin -T < $srcdir/test_inputs/$i || exit + ./isl_pip$EXEEXT --format=affine --context=gbr -T < $srcdir/test_inputs/$i || exit + ./isl_pip$EXEEXT --format=affine --context=lexmin -T < $srcdir/test_inputs/$i || exit +done diff --git a/external/mit/isl/dist/polyhedron_detect_equalities.c b/external/mit/isl/dist/polyhedron_detect_equalities.c new file mode 100644 index 000000000000..c3dcec5712d4 --- /dev/null +++ b/external/mit/isl/dist/polyhedron_detect_equalities.c @@ -0,0 +1,30 @@ +/* + * 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 + */ + +#include + +int main(int argc, char **argv) +{ + struct isl_ctx *ctx = isl_ctx_alloc(); + struct isl_basic_set *bset; + isl_printer *p; + + bset = isl_basic_set_read_from_file(ctx, stdin); + bset = isl_basic_set_detect_equalities(bset); + + p = isl_printer_to_file(ctx, stdout); + p = isl_printer_set_output_format(p, ISL_FORMAT_POLYLIB); + p = isl_printer_print_basic_set(p, bset); + isl_printer_free(p); + + isl_basic_set_free(bset); + isl_ctx_free(ctx); + + return 0; +} diff --git a/external/mit/isl/dist/polyhedron_minimize.c b/external/mit/isl/dist/polyhedron_minimize.c new file mode 100644 index 000000000000..55eaf040b8bf --- /dev/null +++ b/external/mit/isl/dist/polyhedron_minimize.c @@ -0,0 +1,105 @@ +/* + * 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 + */ + +#include +#include +#include +#include +#include +#include + +/* The input of this program is the same as that of the "polytope_minimize" + * program from the barvinok distribution. + * + * Constraints of set is PolyLib format. + * Linear or affine objective function in PolyLib format. + */ + +static __isl_give isl_vec *isl_vec_lin_to_aff(__isl_take isl_vec *vec) +{ + struct isl_vec *aff; + + if (!vec) + return NULL; + aff = isl_vec_alloc(vec->ctx, 1 + vec->size); + if (!aff) + goto error; + isl_int_set_si(aff->el[0], 0); + isl_seq_cpy(aff->el + 1, vec->el, vec->size); + isl_vec_free(vec); + return aff; +error: + isl_vec_free(vec); + return NULL; +} + +/* Rotate elements of vector right. + * In particular, move the constant term from the end of the + * vector to the start of the vector. + */ +static __isl_give isl_vec *vec_ror(__isl_take isl_vec *vec) +{ + int i; + + if (!vec) + return NULL; + for (i = vec->size - 2; i >= 0; --i) + isl_int_swap(vec->el[i], vec->el[i + 1]); + return vec; +} + +int main(int argc, char **argv) +{ + struct isl_ctx *ctx = isl_ctx_alloc(); + struct isl_basic_set *bset; + struct isl_vec *obj; + struct isl_vec *sol; + isl_int opt; + isl_size dim; + enum isl_lp_result res; + isl_printer *p; + + isl_int_init(opt); + bset = isl_basic_set_read_from_file(ctx, stdin); + dim = isl_basic_set_dim(bset, isl_dim_all); + assert(dim >= 0); + obj = isl_vec_read_from_file(ctx, stdin); + assert(obj); + assert(obj->size >= dim && obj->size <= dim + 1); + if (obj->size != dim + 1) + obj = isl_vec_lin_to_aff(obj); + else + obj = vec_ror(obj); + res = isl_basic_set_solve_ilp(bset, 0, obj->el, &opt, &sol); + switch (res) { + case isl_lp_error: + fprintf(stderr, "error\n"); + return -1; + case isl_lp_empty: + fprintf(stdout, "empty\n"); + break; + case isl_lp_unbounded: + fprintf(stdout, "unbounded\n"); + break; + case isl_lp_ok: + p = isl_printer_to_file(ctx, stdout); + p = isl_printer_print_vec(p, sol); + p = isl_printer_end_line(p); + p = isl_printer_print_isl_int(p, opt); + p = isl_printer_end_line(p); + isl_printer_free(p); + } + isl_basic_set_free(bset); + isl_vec_free(obj); + isl_vec_free(sol); + isl_ctx_free(ctx); + isl_int_clear(opt); + + return 0; +} diff --git a/external/mit/isl/dist/polyhedron_remove_redundant_equalities.c b/external/mit/isl/dist/polyhedron_remove_redundant_equalities.c new file mode 100644 index 000000000000..2de47acdc206 --- /dev/null +++ b/external/mit/isl/dist/polyhedron_remove_redundant_equalities.c @@ -0,0 +1,45 @@ +/* + * Copyright 2016 Sven Verdoolaege + * + * Use of this software is governed by the MIT license + * + * Written by Sven Verdoolaege. + */ + +/* This program takes a (possibly parametric) polyhedron as input and + * prints print a full-dimensional polyhedron with the same number + * of integer points. + */ + +#include +#include +#include + +#include "isl_morph.h" + +int main(int argc, char **argv) +{ + isl_ctx *ctx; + isl_printer *p; + isl_basic_set *bset; + isl_morph *morph; + struct isl_options *options; + + options = isl_options_new_with_defaults(); + argc = isl_options_parse(options, argc, argv, ISL_ARG_ALL); + ctx = isl_ctx_alloc_with_options(&isl_options_args, options); + + bset = isl_basic_set_read_from_file(ctx, stdin); + + morph = isl_basic_set_variable_compression(bset, isl_dim_set); + bset = isl_morph_basic_set(morph, bset); + + p = isl_printer_to_file(ctx, stdout); + p = isl_printer_print_basic_set(p, bset); + p = isl_printer_end_line(p); + isl_printer_free(p); + + isl_basic_set_free(bset); + isl_ctx_free(ctx); + return 0; +} diff --git a/external/mit/isl/dist/polyhedron_sample.c b/external/mit/isl/dist/polyhedron_sample.c new file mode 100644 index 000000000000..3fc442f29998 --- /dev/null +++ b/external/mit/isl/dist/polyhedron_sample.c @@ -0,0 +1,36 @@ +/* + * 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 + */ + +#include +#include +#include "isl_sample.h" +#include + +int main(int argc, char **argv) +{ + struct isl_ctx *ctx = isl_ctx_alloc(); + struct isl_basic_set *bset; + struct isl_vec *sample; + isl_printer *p; + + bset = isl_basic_set_read_from_file(ctx, stdin); + sample = isl_basic_set_sample_vec(isl_basic_set_copy(bset)); + p = isl_printer_to_file(ctx, stdout); + p = isl_printer_print_vec(p, sample); + p = isl_printer_end_line(p); + isl_printer_free(p); + assert(sample); + if (isl_vec_size(sample) > 0) + assert(isl_basic_set_contains(bset, sample)); + isl_basic_set_free(bset); + isl_vec_free(sample); + isl_ctx_free(ctx); + + return 0; +} diff --git a/external/mit/isl/dist/polytope_scan.c b/external/mit/isl/dist/polytope_scan.c new file mode 100644 index 000000000000..ae7ee77d37eb --- /dev/null +++ b/external/mit/isl/dist/polytope_scan.c @@ -0,0 +1,107 @@ +/* + * 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 + */ + +#include +#include +#include "isl_equalities.h" +#include +#include "isl_scan.h" +#include +#include + +/* The input of this program is the same as that of the "polytope_scan" + * program from the barvinok distribution. + * + * Constraints of set is PolyLib format. + * + * The input set is assumed to be bounded. + */ + +struct scan_samples { + struct isl_scan_callback callback; + struct isl_mat *samples; +}; + +static isl_stat scan_samples_add_sample(struct isl_scan_callback *cb, + __isl_take isl_vec *sample) +{ + struct scan_samples *ss = (struct scan_samples *)cb; + + ss->samples = isl_mat_extend(ss->samples, ss->samples->n_row + 1, + ss->samples->n_col); + if (!ss->samples) + goto error; + + isl_seq_cpy(ss->samples->row[ss->samples->n_row - 1], + sample->el, sample->size); + + isl_vec_free(sample); + return isl_stat_ok; +error: + isl_vec_free(sample); + return isl_stat_error; +} + +static __isl_give isl_mat *isl_basic_set_scan_samples( + __isl_take isl_basic_set *bset) +{ + isl_ctx *ctx; + isl_size dim; + struct scan_samples ss; + + ctx = isl_basic_set_get_ctx(bset); + dim = isl_basic_set_dim(bset, isl_dim_all); + if (dim < 0) + goto error; + ss.callback.add = scan_samples_add_sample; + ss.samples = isl_mat_alloc(ctx, 0, 1 + dim); + if (!ss.samples) + goto error; + + if (isl_basic_set_scan(bset, &ss.callback) < 0) { + isl_mat_free(ss.samples); + return NULL; + } + + return ss.samples; +error: + isl_basic_set_free(bset); + return NULL; +} + +static __isl_give isl_mat *isl_basic_set_samples(__isl_take isl_basic_set *bset) +{ + struct isl_mat *T; + struct isl_mat *samples; + + if (!bset) + return NULL; + + if (bset->n_eq == 0) + return isl_basic_set_scan_samples(bset); + + bset = isl_basic_set_remove_equalities(bset, &T, NULL); + samples = isl_basic_set_scan_samples(bset); + return isl_mat_product(samples, isl_mat_transpose(T)); +} + +int main(int argc, char **argv) +{ + struct isl_ctx *ctx = isl_ctx_alloc(); + struct isl_basic_set *bset; + struct isl_mat *samples; + + bset = isl_basic_set_read_from_file(ctx, stdin); + samples = isl_basic_set_samples(bset); + isl_mat_print_internal(samples, stdout, 0); + isl_mat_free(samples); + isl_ctx_free(ctx); + + return 0; +} diff --git a/external/mit/isl/dist/print.c b/external/mit/isl/dist/print.c new file mode 100644 index 000000000000..a87f9221a379 --- /dev/null +++ b/external/mit/isl/dist/print.c @@ -0,0 +1,105 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#undef BASE +#define BASE id +#include +#undef BASE +#define BASE multi_id +#include +#undef BASE +#define BASE val +#include +#undef BASE +#define BASE multi_val +#include +#undef BASE +#define BASE space +#include +#undef BASE +#define BASE local_space +#include +#undef BASE +#define BASE basic_set +#include +#undef BASE +#define BASE basic_map +#include +#undef BASE +#define BASE set +#include +#undef BASE +#define BASE map +#include +#undef BASE +#define BASE union_set +#include +#undef BASE +#define BASE union_map +#include +#undef BASE +#define BASE qpolynomial +#include +#undef BASE +#define BASE qpolynomial_fold +#include +#undef BASE +#define BASE pw_qpolynomial +#include +#undef BASE +#define BASE pw_qpolynomial_fold +#include +#undef BASE +#define BASE union_pw_qpolynomial +#include +#undef BASE +#define BASE union_pw_qpolynomial_fold +#include +#undef BASE +#define BASE constraint +#include +#undef BASE +#define BASE aff +#include +#undef BASE +#define BASE pw_aff +#include +#undef BASE +#define BASE multi_aff +#include +#undef BASE +#define BASE pw_multi_aff +#include +#undef BASE +#define BASE union_pw_multi_aff +#include +#undef BASE +#define BASE multi_pw_aff +#include +#undef BASE +#define BASE union_pw_aff +#include +#undef BASE +#define BASE multi_union_pw_aff +#include +#undef BASE +#define BASE point +#include +#undef BASE +#define BASE ast_expr +#include +#undef BASE +#define BASE ast_node +#include diff --git a/external/mit/isl/dist/print_templ.c b/external/mit/isl/dist/print_templ.c new file mode 100644 index 000000000000..9ed93f143853 --- /dev/null +++ b/external/mit/isl/dist/print_templ.c @@ -0,0 +1,42 @@ +#include + +#define xCAT(A,B) A ## B +#define CAT(A,B) xCAT(A,B) +#undef TYPE +#define TYPE CAT(isl_,BASE) +#define xFN(TYPE,NAME) TYPE ## _ ## NAME +#define FN(TYPE,NAME) xFN(TYPE,NAME) + +#ifndef PRINT_DUMP_DEFAULT +#define PRINT_DUMP_DEFAULT 1 +#endif + +void FN(TYPE,dump)(__isl_keep TYPE *obj) +{ + isl_printer *p; + + if (!obj) + return; + p = isl_printer_to_file(FN(TYPE,get_ctx)(obj), stderr); + p = isl_printer_set_dump(p, PRINT_DUMP_DEFAULT); + p = FN(isl_printer_print,BASE)(p, obj); + p = isl_printer_end_line(p); + isl_printer_free(p); +} + +#undef PRINT_DUMP_DEFAULT + +__isl_give char *FN(TYPE,to_str)(__isl_keep TYPE *obj) +{ + isl_printer *p; + char *s; + + if (!obj) + return NULL; + p = isl_printer_to_str(FN(TYPE,get_ctx)(obj)); + p = FN(isl_printer_print,BASE)(p, obj); + s = isl_printer_get_str(p); + isl_printer_free(p); + + return s; +} diff --git a/external/mit/isl/dist/print_templ_yaml.c b/external/mit/isl/dist/print_templ_yaml.c new file mode 100644 index 000000000000..50f7f1f04872 --- /dev/null +++ b/external/mit/isl/dist/print_templ_yaml.c @@ -0,0 +1,39 @@ +#define xCAT(A,B) A ## B +#define CAT(A,B) xCAT(A,B) +#undef TYPE +#define TYPE CAT(isl_,BASE) +#define xFN(TYPE,NAME) TYPE ## _ ## NAME +#define FN(TYPE,NAME) xFN(TYPE,NAME) + +void FN(TYPE,dump)(__isl_keep TYPE *obj) +{ + isl_printer *p; + + if (!obj) + return; + + p = isl_printer_to_file(FN(TYPE,get_ctx)(obj), stderr); + p = isl_printer_set_yaml_style(p, ISL_YAML_STYLE_BLOCK); + p = FN(isl_printer_print,BASE)(p, obj); + isl_printer_free(p); +} + +/* Return a string representation of "obj". + * Print the object in flow format. + */ +__isl_give char *FN(TYPE,to_str)(__isl_keep TYPE *obj) +{ + isl_printer *p; + char *s; + + if (!obj) + return NULL; + + p = isl_printer_to_str(FN(TYPE,get_ctx)(obj)); + p = isl_printer_set_yaml_style(p, ISL_YAML_STYLE_FLOW); + p = FN(isl_printer_print,BASE)(p, obj); + s = isl_printer_get_str(p); + isl_printer_free(p); + + return s; +} diff --git a/external/mit/isl/dist/print_yaml_field_templ.c b/external/mit/isl/dist/print_yaml_field_templ.c new file mode 100644 index 000000000000..088e701d9694 --- /dev/null +++ b/external/mit/isl/dist/print_yaml_field_templ.c @@ -0,0 +1,22 @@ +#define xCAT(A,B) A ## B +#define CAT(A,B) xCAT(A,B) +#undef TYPE +#define TYPE CAT(isl_,BASE) +#define xFN(TYPE,NAME) TYPE ## _ ## NAME +#define FN(TYPE,NAME) xFN(TYPE,NAME) + +/* Print a key-value pair of a YAML mapping to "p", + * with key "name" and value "val". + */ +static __isl_give isl_printer *FN(print_yaml_field,BASE)( + __isl_take isl_printer *p, const char *name, __isl_keep TYPE *val) +{ + p = isl_printer_print_str(p, name); + p = isl_printer_yaml_next(p); + p = isl_printer_print_str(p, "\""); + p = FN(isl_printer_print,BASE)(p, val); + p = isl_printer_print_str(p, "\""); + p = isl_printer_yaml_next(p); + + return p; +} diff --git a/external/mit/isl/dist/py-compile b/external/mit/isl/dist/py-compile new file mode 100755 index 000000000000..81b122b0a546 --- /dev/null +++ b/external/mit/isl/dist/py-compile @@ -0,0 +1,189 @@ +#!/bin/sh +# py-compile - Compile a Python program + +scriptversion=2021-02-27.01; # UTC + +# Copyright (C) 2000-2021 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# This file is maintained in Automake, please report +# bugs to or send patches to +# . + +if test -z "$PYTHON"; then + PYTHON=python +fi + +me=py-compile + +usage_error () +{ + echo "$me: $*" >&2 + echo "Try '$me --help' for more information." >&2 + exit 1 +} + +basedir= +destdir= +while test $# -ne 0; do + case "$1" in + --basedir) + if test $# -lt 2; then + usage_error "option '--basedir' requires an argument" + else + basedir=$2 + fi + shift + ;; + --destdir) + if test $# -lt 2; then + usage_error "option '--destdir' requires an argument" + else + destdir=$2 + fi + shift + ;; + -h|--help) + cat <<\EOF +Usage: py-compile [--help] [--version] [--basedir DIR] [--destdir DIR] FILES..." + +Byte compile some python scripts FILES. Use --destdir to specify any +leading directory path to the FILES that you don't want to include in the +byte compiled file. Specify --basedir for any additional path information you +do want to be shown in the byte compiled file. + +Example: + py-compile --destdir /tmp/pkg-root --basedir /usr/share/test test.py test2.py + +Report bugs to . +EOF + exit $? + ;; + -v|--version) + echo "$me $scriptversion" + exit $? + ;; + --) + shift + break + ;; + -*) + usage_error "unrecognized option '$1'" + ;; + *) + break + ;; + esac + shift +done + +files=$* +if test -z "$files"; then + usage_error "no files given" +fi + +# if basedir was given, then it should be prepended to filenames before +# byte compilation. +if test -z "$basedir"; then + pathtrans="path = file" +else + pathtrans="path = os.path.join('$basedir', file)" +fi + +# if destdir was given, then it needs to be prepended to the filename to +# byte compile but not go into the compiled file. +if test -z "$destdir"; then + filetrans="filepath = path" +else + filetrans="filepath = os.path.normpath('$destdir' + os.sep + path)" +fi + +python_major=`$PYTHON -V 2>&1 | sed -e 's/.* //;s/\..*$//;1q'` +if test -z "$python_major"; then + echo "$me: could not determine $PYTHON major version, guessing 3" >&2 + python_major=3 +fi + +# The old way to import libraries was deprecated. +if test "$python_major" -le 2; then + import_lib=imp + import_test="hasattr(imp, 'get_tag')" + import_call=imp.cache_from_source + import_arg2=', False' # needed in one call and not the other +else + import_lib=importlib + import_test="hasattr(sys.implementation, 'cache_tag')" + import_call=importlib.util.cache_from_source + import_arg2= +fi + +$PYTHON -c " +import sys, os, py_compile, $import_lib + +files = '''$files''' + +sys.stdout.write('Byte-compiling python modules...\n') +for file in files.split(): + $pathtrans + $filetrans + if not os.path.exists(filepath) or not (len(filepath) >= 3 + and filepath[-3:] == '.py'): + continue + sys.stdout.write(file) + sys.stdout.flush() + if $import_test: + py_compile.compile(filepath, $import_call(filepath), path) + else: + py_compile.compile(filepath, filepath + 'c', path) +sys.stdout.write('\n')" || exit $? + +# this will fail for python < 1.5, but that doesn't matter ... +$PYTHON -O -c " +import sys, os, py_compile, $import_lib + +# pypy does not use .pyo optimization +if hasattr(sys, 'pypy_translation_info'): + sys.exit(0) + +files = '''$files''' +sys.stdout.write('Byte-compiling python modules (optimized versions) ...\n') +for file in files.split(): + $pathtrans + $filetrans + if not os.path.exists(filepath) or not (len(filepath) >= 3 + and filepath[-3:] == '.py'): + continue + sys.stdout.write(file) + sys.stdout.flush() + if $import_test: + py_compile.compile(filepath, $import_call(filepath$import_arg2), path) + else: + py_compile.compile(filepath, filepath + 'o', path) +sys.stdout.write('\n')" 2>/dev/null || exit $? + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'before-save-hook 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC0" +# time-stamp-end: "; # UTC" +# End: diff --git a/external/mit/isl/dist/python/isl.py.top b/external/mit/isl/dist/python/isl.py.top new file mode 100644 index 000000000000..d041315d4e11 --- /dev/null +++ b/external/mit/isl/dist/python/isl.py.top @@ -0,0 +1,49 @@ +import os +from ctypes import * +from ctypes.util import find_library + +isl_dyld_library_path = os.environ.get('ISL_DYLD_LIBRARY_PATH') +if isl_dyld_library_path != None: + os.environ['DYLD_LIBRARY_PATH'] = isl_dyld_library_path +try: + isl = cdll.LoadLibrary(isl_dlname) +except: + isl = cdll.LoadLibrary(find_library("isl")) +libc = cdll.LoadLibrary(find_library("c")) + +class Error(Exception): + pass + +class Context: + defaultInstance = None + + def __init__(self): + ptr = isl.isl_ctx_alloc() + self.ptr = ptr + + def __del__(self): + isl.isl_ctx_free(self) + + def from_param(self): + return c_void_p(self.ptr) + + @staticmethod + def getDefaultInstance(): + if Context.defaultInstance == None: + Context.defaultInstance = Context() + return Context.defaultInstance + + @CFUNCTYPE(None, py_object) + def free_user(user): + pythonapi.Py_DecRef(py_object(user)) + +isl.isl_ctx_alloc.restype = c_void_p +isl.isl_ctx_free.argtypes = [Context] +isl.isl_id_alloc.restype = c_void_p +isl.isl_id_alloc.argtypes = [Context, c_char_p, py_object] +isl.isl_id_set_free_user.restype = c_void_p +isl.isl_id_set_free_user.argtypes = [c_void_p, c_void_p] +isl.isl_id_get_free_user.restype = c_void_p +isl.isl_id_get_free_user.argtypes = [c_void_p] +isl.isl_id_get_user.restype = py_object +isl.isl_id_get_user.argtypes = [c_void_p] diff --git a/external/mit/isl/dist/read_in_string_templ.c b/external/mit/isl/dist/read_in_string_templ.c new file mode 100644 index 000000000000..3dc630ee0368 --- /dev/null +++ b/external/mit/isl/dist/read_in_string_templ.c @@ -0,0 +1,38 @@ +#include + +#define xCAT(A,B) A ## B +#define CAT(A,B) xCAT(A,B) +#undef TYPE +#define TYPE CAT(isl_,BASE) +#define xFN(TYPE,NAME) TYPE ## _ ## NAME +#define FN(TYPE,NAME) xFN(TYPE,NAME) + +/* Read an object of type TYPE from "s", where the object may + * either be specified directly or as a string. + * + * First check if the next token in "s" is a string. If so, try and + * extract the object from the string. + * Otherwise, try and read the object directly from "s". + */ +static __isl_give TYPE *FN(read,BASE)(__isl_keep isl_stream *s) +{ + struct isl_token *tok; + int type; + + tok = isl_stream_next_token(s); + type = isl_token_get_type(tok); + if (type == ISL_TOKEN_STRING) { + char *str; + isl_ctx *ctx; + TYPE *res; + + ctx = isl_stream_get_ctx(s); + str = isl_token_get_str(ctx, tok); + res = FN(TYPE,read_from_str)(ctx, str); + free(str); + isl_token_free(tok); + return res; + } + isl_stream_push_token(s, tok); + return FN(isl_stream_read,BASE)(s); +} diff --git a/external/mit/isl/dist/schedule.c b/external/mit/isl/dist/schedule.c new file mode 100644 index 000000000000..8dd58f13e1f3 --- /dev/null +++ b/external/mit/isl/dist/schedule.c @@ -0,0 +1,43 @@ +/* + * Copyright 2016 Sven Verdoolaege + * + * Use of this software is governed by the MIT license + * + * Written by Sven Verdoolaege. + */ + +/* This program takes an isl_schedule_constraints object as input and + * prints a schedule that satisfies those constraints. + */ + +#include +#include +#include +#include + +int main(int argc, char **argv) +{ + isl_ctx *ctx; + isl_printer *p; + isl_schedule_constraints *sc; + isl_schedule *schedule; + struct isl_options *options; + + options = isl_options_new_with_defaults(); + argc = isl_options_parse(options, argc, argv, ISL_ARG_ALL); + ctx = isl_ctx_alloc_with_options(&isl_options_args, options); + + sc = isl_schedule_constraints_read_from_file(ctx, stdin); + schedule = isl_schedule_constraints_compute_schedule(sc); + + p = isl_printer_to_file(ctx, stdout); + p = isl_printer_set_yaml_style(p, ISL_YAML_STYLE_BLOCK); + p = isl_printer_print_schedule(p, schedule); + isl_printer_free(p); + + isl_schedule_free(schedule); + + isl_ctx_free(ctx); + + return p ? EXIT_SUCCESS : EXIT_FAILURE; +} diff --git a/external/mit/isl/dist/schedule_cmp.c b/external/mit/isl/dist/schedule_cmp.c new file mode 100644 index 000000000000..8bf02ea403b4 --- /dev/null +++ b/external/mit/isl/dist/schedule_cmp.c @@ -0,0 +1,85 @@ +/* + * Copyright 2017 Sven Verdoolaege + * + * Use of this software is governed by the MIT license + * + * Written by Sven Verdoolaege. + */ + +#include + +#include +#include +#include + +struct options { + struct isl_options *isl; + char *schedule1; + char *schedule2; +}; + +ISL_ARGS_START(struct options, options_args) +ISL_ARG_CHILD(struct options, isl, "isl", &isl_options_args, "isl options") +ISL_ARG_ARG(struct options, schedule1, "schedule1", NULL) +ISL_ARG_ARG(struct options, schedule2, "schedule2", NULL) +ISL_ARGS_END + +ISL_ARG_DEF(options, struct options, options_args) + +static void die(const char *msg) +{ + fprintf(stderr, "%s\n", msg); + exit(EXIT_FAILURE); +} + +static FILE *open_or_die(const char *filename) +{ + FILE *file; + + file = fopen(filename, "r"); + if (!file) { + fprintf(stderr, "Unable to open %s\n", filename); + exit(EXIT_FAILURE); + } + return file; +} + +/* Given two YAML descriptions of isl_schedule objects, check whether + * they are equivalent. + * Return EXIT_SUCCESS if they are and EXIT_FAILURE if they are not + * or if anything else went wrong. + */ +int main(int argc, char **argv) +{ + isl_ctx *ctx; + struct options *options; + FILE *input1, *input2; + isl_bool equal; + isl_schedule *s1, *s2; + + options = options_new_with_defaults(); + if (!options) + return EXIT_FAILURE; + + ctx = isl_ctx_alloc_with_options(&options_args, options); + argc = options_parse(options, argc, argv, ISL_ARG_ALL); + + input1 = open_or_die(options->schedule1); + input2 = open_or_die(options->schedule2); + s1 = isl_schedule_read_from_file(ctx, input1); + s2 = isl_schedule_read_from_file(ctx, input2); + + equal = isl_schedule_plain_is_equal(s1, s2); + if (equal < 0) + return EXIT_FAILURE; + if (!equal) + die("schedules differ"); + + isl_schedule_free(s1); + isl_schedule_free(s2); + fclose(input1); + fclose(input2); + isl_ctx_free(ctx); + + return EXIT_SUCCESS; +} diff --git a/external/mit/isl/dist/schedule_test.sh.in b/external/mit/isl/dist/schedule_test.sh.in new file mode 100644 index 000000000000..16ae02019f4e --- /dev/null +++ b/external/mit/isl/dist/schedule_test.sh.in @@ -0,0 +1,27 @@ +#!/bin/sh + +EXEEXT=@EXEEXT@ +GREP=@GREP@ +SED=@SED@ +srcdir=@srcdir@ + +failed=0 + +for i in $srcdir/test_inputs/schedule/*.sc; do + echo $i; + base=`basename $i .sc` + test=test-$base.st + dir=`dirname $i` + ref=$dir/$base.st + options=`$GREP 'OPTIONS:' $i | $SED 's/.*://'` + for o in --schedule-whole-component --no-schedule-whole-component; do + ./isl_schedule$EXEEXT $o $options < $i > $test && + ./isl_schedule_cmp$EXEEXT $ref $test && rm $test + if [ $? -ne 0 ]; then + echo $o $options + failed=1 + fi + done +done + +test $failed -eq 0 || exit diff --git a/external/mit/isl/dist/set_from_map.c b/external/mit/isl/dist/set_from_map.c new file mode 100644 index 000000000000..cf6f8148a9b4 --- /dev/null +++ b/external/mit/isl/dist/set_from_map.c @@ -0,0 +1,8 @@ +#include + +/* Return the set that was treated as the map "map". + */ +static __isl_give isl_set *set_from_map(__isl_take isl_map *map) +{ + return (isl_set *) map; +} diff --git a/external/mit/isl/dist/set_list_from_map_list_inl.c b/external/mit/isl/dist/set_list_from_map_list_inl.c new file mode 100644 index 000000000000..108c53476ff3 --- /dev/null +++ b/external/mit/isl/dist/set_list_from_map_list_inl.c @@ -0,0 +1,9 @@ +#include + +/* Return the set list that was treated as the map list "list". + */ +static __isl_give isl_set_list *set_list_from_map_list( + __isl_take isl_map_list *list) +{ + return (isl_set_list *) list; +} diff --git a/external/mit/isl/dist/set_to_map.c b/external/mit/isl/dist/set_to_map.c new file mode 100644 index 000000000000..dc67ed24babd --- /dev/null +++ b/external/mit/isl/dist/set_to_map.c @@ -0,0 +1,10 @@ +#include + +/* Treat "set" as a map. + * Internally, isl_set is defined to isl_map, so in practice, + * this function performs a redundant cast. + */ +static __isl_give isl_map *set_to_map(__isl_take isl_set *set) +{ + return (isl_map *) set; +} diff --git a/external/mit/isl/dist/test-driver b/external/mit/isl/dist/test-driver new file mode 100755 index 000000000000..be73b80adf95 --- /dev/null +++ b/external/mit/isl/dist/test-driver @@ -0,0 +1,153 @@ +#! /bin/sh +# test-driver - basic testsuite driver script. + +scriptversion=2018-03-07.03; # UTC + +# Copyright (C) 2011-2021 Free Software Foundation, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# This file is maintained in Automake, please report +# bugs to or send patches to +# . + +# Make unconditional expansion of undefined variables an error. This +# helps a lot in preventing typo-related bugs. +set -u + +usage_error () +{ + echo "$0: $*" >&2 + print_usage >&2 + exit 2 +} + +print_usage () +{ + cat <"$log_file" +"$@" >>"$log_file" 2>&1 +estatus=$? + +if test $enable_hard_errors = no && test $estatus -eq 99; then + tweaked_estatus=1 +else + tweaked_estatus=$estatus +fi + +case $tweaked_estatus:$expect_failure in + 0:yes) col=$red res=XPASS recheck=yes gcopy=yes;; + 0:*) col=$grn res=PASS recheck=no gcopy=no;; + 77:*) col=$blu res=SKIP recheck=no gcopy=yes;; + 99:*) col=$mgn res=ERROR recheck=yes gcopy=yes;; + *:yes) col=$lgn res=XFAIL recheck=no gcopy=yes;; + *:*) col=$red res=FAIL recheck=yes gcopy=yes;; +esac + +# Report the test outcome and exit status in the logs, so that one can +# know whether the test passed or failed simply by looking at the '.log' +# file, without the need of also peaking into the corresponding '.trs' +# file (automake bug#11814). +echo "$res $test_name (exit status: $estatus)" >>"$log_file" + +# Report outcome to console. +echo "${col}${res}${std}: $test_name" + +# Register the test result, and other relevant metadata. +echo ":test-result: $res" > $trs_file +echo ":global-test-result: $res" >> $trs_file +echo ":recheck: $recheck" >> $trs_file +echo ":copy-in-global-log: $gcopy" >> $trs_file + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'before-save-hook 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC0" +# time-stamp-end: "; # UTC" +# End: diff --git a/external/mit/isl/dist/test_inputs/affine.polylib b/external/mit/isl/dist/test_inputs/affine.polylib new file mode 100644 index 000000000000..f14720c0a0ad --- /dev/null +++ b/external/mit/isl/dist/test_inputs/affine.polylib @@ -0,0 +1,9 @@ +# the affine hull of {[a,b] : a=b && 1 <= a <= 163} ... +3 4 +0 1 -1 0 +1 1 0 -1 +1 -1 0 163 + +# ... is {[a,b] : a=b} (and not {[In_1,In_2]}, as Omega 1.2 claims) +1 4 +0 1 -1 0 diff --git a/external/mit/isl/dist/test_inputs/affine2.polylib b/external/mit/isl/dist/test_inputs/affine2.polylib new file mode 100644 index 000000000000..c67db77bb6ee --- /dev/null +++ b/external/mit/isl/dist/test_inputs/affine2.polylib @@ -0,0 +1,9 @@ +5 5 +1 -2 0 1 0 +1 2 0 -1 1 +1 0 -2 1 0 +1 0 2 -1 1 +1 0 0 1 -1 + +1 5 +0 1 -1 0 0 diff --git a/external/mit/isl/dist/test_inputs/affine3.polylib b/external/mit/isl/dist/test_inputs/affine3.polylib new file mode 100644 index 000000000000..f2bc9a2db2fd --- /dev/null +++ b/external/mit/isl/dist/test_inputs/affine3.polylib @@ -0,0 +1,7 @@ +3 4 +1 1 0 0 +1 -7 4 2 +1 5 -4 2 + +1 4 +0 3 -2 0 diff --git a/external/mit/isl/dist/test_inputs/application.omega b/external/mit/isl/dist/test_inputs/application.omega new file mode 100644 index 000000000000..8f4fd1db39a0 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/application.omega @@ -0,0 +1,3 @@ +{[x]} +{[x] -> [y] : y = 2x} +{[y]: Exists ( alpha : 2alpha = y)} diff --git a/external/mit/isl/dist/test_inputs/application2.omega b/external/mit/isl/dist/test_inputs/application2.omega new file mode 100644 index 000000000000..f2af1e869580 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/application2.omega @@ -0,0 +1,3 @@ +{[x] : x >= 0 && x <= 20 } +{[x] -> [y] : y = 2x} +{[y]: Exists ( alpha : 2alpha = y && 0 <= y && y <= 40)} diff --git a/external/mit/isl/dist/test_inputs/basicLinear.pwqp b/external/mit/isl/dist/test_inputs/basicLinear.pwqp new file mode 100644 index 000000000000..0af7fabb53f0 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/basicLinear.pwqp @@ -0,0 +1 @@ +[P, Q] -> { [n, m] -> n : n >= 1 and m >= n and m <= P and m <= Q } diff --git a/external/mit/isl/dist/test_inputs/basicLinear2.pwqp b/external/mit/isl/dist/test_inputs/basicLinear2.pwqp new file mode 100644 index 000000000000..d411a369158c --- /dev/null +++ b/external/mit/isl/dist/test_inputs/basicLinear2.pwqp @@ -0,0 +1 @@ +[P, Q] -> { [n, m] -> n : n >= 1 and m >= n and m <= P and n >= -1 + Q } diff --git a/external/mit/isl/dist/test_inputs/basicTest.pwqp b/external/mit/isl/dist/test_inputs/basicTest.pwqp new file mode 100644 index 000000000000..52e7fc8e697d --- /dev/null +++ b/external/mit/isl/dist/test_inputs/basicTest.pwqp @@ -0,0 +1 @@ +[p] -> { [n, m] -> (n + n^2) : n >= 1 and m >= n and m <= p } diff --git a/external/mit/isl/dist/test_inputs/basicTestParameterPosNeg.pwqp b/external/mit/isl/dist/test_inputs/basicTestParameterPosNeg.pwqp new file mode 100644 index 000000000000..6cb4490215cf --- /dev/null +++ b/external/mit/isl/dist/test_inputs/basicTestParameterPosNeg.pwqp @@ -0,0 +1 @@ +[p] -> { [n, m] -> (n + n^3) : n >= -1 and m >= n and m <= p } diff --git a/external/mit/isl/dist/test_inputs/boulet.pip b/external/mit/isl/dist/test_inputs/boulet.pip new file mode 100644 index 000000000000..78e90ddf58b5 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/boulet.pip @@ -0,0 +1,13 @@ +0 3 + +-1 + +5 6 +1 1 -1 2 0 0 +1 0 1 1 4 20 +1 0 -1 -1 0 0 +1 0 1 -1 2 10 +1 0 -1 1 2 10 + +Urs_parms +Urs_unknowns diff --git a/external/mit/isl/dist/test_inputs/brisebarre.pip b/external/mit/isl/dist/test_inputs/brisebarre.pip new file mode 100644 index 000000000000..f3decadfd27e --- /dev/null +++ b/external/mit/isl/dist/test_inputs/brisebarre.pip @@ -0,0 +1,34 @@ +# ---------------------- CONTEXT ---------------------- +1 2 +1 0 + +-1 + +# ----------------------- DOMAIN ---------------------- +26 6 +1 3 0 0 0 -98300 +1 -3 0 0 0 98308 +1 432 36 6 1 -14757611 +1 -432 -36 -6 -1 14758510 +1 54 9 3 1 -1923190 +1 -54 -9 -3 -1 1923303 +1 48 12 6 3 -1782238 +1 -48 -12 -6 -3 1782339 +1 27 9 6 4 -1045164 +1 -27 -9 -6 -4 1045221 +1 432 180 150 125 -17434139 +1 -432 -180 -150 -125 17435038 +1 6 3 3 3 -252443 +1 -6 -3 -3 -3 252456 +1 432 252 294 343 -18949275 +1 -432 -252 -294 -343 18950174 +1 27 18 24 32 -1234720 +1 -27 -18 -24 -32 1234777 +1 48 36 54 81 -2288453 +1 -48 -36 -54 -81 2288554 +1 54 45 75 125 -2684050 +1 -54 -45 -75 -125 2684163 +1 432 396 726 1331 -22386005 +1 -432 -396 -726 -1331 22386904 +1 3 3 6 12 -162072 +1 -3 -3 -6 -12 162080 diff --git a/external/mit/isl/dist/test_inputs/cg1.pip b/external/mit/isl/dist/test_inputs/cg1.pip new file mode 100644 index 000000000000..78e31f187b1d --- /dev/null +++ b/external/mit/isl/dist/test_inputs/cg1.pip @@ -0,0 +1,15 @@ +2 4 + 1 1 0 -1 + 1 -1 1 0 + +-1 + +8 7 + 1 0 1 0 -1 0 0 + 1 0 -1 0 1 0 0 + 1 1 0 0 0 -1 0 + 1 -1 0 0 0 1 0 + 1 0 1 0 0 0 -1 + 1 0 -1 0 0 1 0 + 1 0 -1 1 0 0 -1 + 1 0 0 -1 0 1 0 diff --git a/external/mit/isl/dist/test_inputs/codegen/atomic.c b/external/mit/isl/dist/test_inputs/codegen/atomic.c new file mode 100644 index 000000000000..0b7027989fea --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/atomic.c @@ -0,0 +1,6 @@ +for (int c0 = 0; c0 <= 10; c0 += 1) { + if (c0 <= 9) + a(c0); + if (c0 >= 1) + b(c0 - 1); +} diff --git a/external/mit/isl/dist/test_inputs/codegen/atomic.in b/external/mit/isl/dist/test_inputs/codegen/atomic.in new file mode 100644 index 000000000000..6d8f81886eaf --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/atomic.in @@ -0,0 +1,3 @@ +{ a[i] -> [i, 0] : 0 <= i < 10; b[i] -> [i+1, 1] : 0 <= i < 10 } +{ : } +{ [i, d] -> atomic[x] } diff --git a/external/mit/isl/dist/test_inputs/codegen/atomic.st b/external/mit/isl/dist/test_inputs/codegen/atomic.st new file mode 100644 index 000000000000..7591b05b81ad --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/atomic.st @@ -0,0 +1,8 @@ +domain: "{ a[i] : 0 <= i < 10; b[i] : 0 <= i < 10 }" +child: + schedule: "[{ a[i] -> [i]; b[i] -> [i+1] }]" + options: "{ atomic[x] }" + child: + sequence: + - filter: "{ a[i] }" + - filter: "{ b[i] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/atomic2.c b/external/mit/isl/dist/test_inputs/codegen/atomic2.c new file mode 100644 index 000000000000..9c4a57e3e5a4 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/atomic2.c @@ -0,0 +1,2 @@ +for (int c0 = ((b0 + 32767) % 32768) + 1; c0 <= 65534; c0 += 32768) + A(c0); diff --git a/external/mit/isl/dist/test_inputs/codegen/atomic2.in b/external/mit/isl/dist/test_inputs/codegen/atomic2.in new file mode 100644 index 000000000000..99901d0e191f --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/atomic2.in @@ -0,0 +1,4 @@ +# Check that isl properly handles atomic domains that are unions. +[nn, b0] -> { A[a] -> [a, 0, b0] : exists (e0 = [(b0 - a)/32768]: 32768e0 = b0 - a and a >= 1 and b0 >= 0 and b0 <= 32767 and a <= 65534) } +[nn, b0] -> { : b0 >= 0 and b0 <= 32767 } +[nn, b0] -> { [a, b, c] -> atomic[2] : c >= 1; [a, 0, c] -> atomic[2] } diff --git a/external/mit/isl/dist/test_inputs/codegen/atomic3.c b/external/mit/isl/dist/test_inputs/codegen/atomic3.c new file mode 100644 index 000000000000..c6deb761eaeb --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/atomic3.c @@ -0,0 +1,9 @@ +for (int c0 = 0; c0 <= 64; c0 += 1) { + if (c0 >= 63) { + sync(); + } else if (c0 >= 1) { + sync(); + } else { + sync(); + } +} diff --git a/external/mit/isl/dist/test_inputs/codegen/atomic3.in b/external/mit/isl/dist/test_inputs/codegen/atomic3.in new file mode 100644 index 000000000000..4d0c4953107d --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/atomic3.in @@ -0,0 +1,5 @@ +# Check that isl is not confused by inconsistent +# separation_class and atomic options. +{ sync[] -> [i, 0] : 0 <= i <= 64 } +{ : } +{ [i, 0] -> separation_class[[1] -> [0]] : 1 <= i <= 62; [i, 0] -> atomic[1]} diff --git a/external/mit/isl/dist/test_inputs/codegen/atomic4.c b/external/mit/isl/dist/test_inputs/codegen/atomic4.c new file mode 100644 index 000000000000..624c2af1d255 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/atomic4.c @@ -0,0 +1,2 @@ +for (int c0 = 0; c0 <= 64; c0 += 1) + sync(); diff --git a/external/mit/isl/dist/test_inputs/codegen/atomic4.in b/external/mit/isl/dist/test_inputs/codegen/atomic4.in new file mode 100644 index 000000000000..c5dab102c6a0 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/atomic4.in @@ -0,0 +1,4 @@ +# Check that isl is not confused by inconsistent separate and atomic options. +{ sync[] -> [i, 0] : 0 <= i <= 64 } +{ : } +{ [i, 0] -> separate[1] : 1 <= i <= 62; [i, 0] -> atomic[1] : i <= 10 or i >= 20 } diff --git a/external/mit/isl/dist/test_inputs/codegen/bilinear.c b/external/mit/isl/dist/test_inputs/codegen/bilinear.c new file mode 100644 index 000000000000..8b123e1c1d00 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/bilinear.c @@ -0,0 +1,9 @@ +if (d <= -1) { + for (int c0 = 0; c0 < -(-d % 2) - d + w; c0 += 1) { + A(c0); + B(c0); + } +} else { + for (int c0 = 0; c0 < (d % 2) - d + w; c0 += 1) + A(c0); +} diff --git a/external/mit/isl/dist/test_inputs/codegen/bilinear.st b/external/mit/isl/dist/test_inputs/codegen/bilinear.st new file mode 100644 index 000000000000..00704b5e92dc --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/bilinear.st @@ -0,0 +1,9 @@ +# Check that the generated code does not contain a loop upper bound +# that depends on the loop iterator. +domain: "[d, w] -> { A[i0] : i0 >= 0 and ((d < 0 and 2*floor((1 + d)/2) < w - i0) or (d >= 0 and 2*floor((d)/2) < w - i0)); B[i0] : i0 >= 0 and d < 0 and 2*floor((d)/2) > 2d - w + i0 }" +child: + schedule: "[d, w] -> [{ A[i0] -> [(i0)]; B[i0] -> [(i0)] }]" + child: + sequence: + - filter: "{ A[x] }" + - filter: "{ B[x] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cholesky.c b/external/mit/isl/dist/test_inputs/codegen/cholesky.c new file mode 100644 index 000000000000..7e6f2152f4f8 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cholesky.c @@ -0,0 +1,4 @@ +for (int c0 = 3993; c0 <= 63893; c0 += 1) + if (2 * c0 - 3993 * ((3 * c0 + 5990) / 5990) >= 0) + for (int c4 = -c0 + 1997 * ((3 * c0 + 5990) / 5990) + 1; c4 <= 12; c4 += 1) + S_3(c4, -c0 + 1997 * ((3 * c0 + 5990) / 5990), 2 * c0 - 3993 * ((3 * c0 + 5990) / 5990)); diff --git a/external/mit/isl/dist/test_inputs/codegen/cholesky.st b/external/mit/isl/dist/test_inputs/codegen/cholesky.st new file mode 100644 index 000000000000..2dd62b9b4a78 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cholesky.st @@ -0,0 +1,9 @@ +# Earlier versions of isl would fail to produce an AST for this input +# due to a simplification bug. +domain: "{ S_3[i, j, k] : 0 <= i <= 12 and 0 <= j < i and 0 <= k < j }" +child: + schedule: "[{ S_3[i, j, k] -> [(3993j + 1997k)] }]" + child: + schedule: "[{ S_3[i, j, k] -> [(32*floor((2j + k)/32))] }, { S_3[i, j, k] -> [(32*floor((i)/32))] }]" + child: + schedule: "[{ S_3[i, j, k] -> [(2j + k - 32*floor((2j + k)/32))] }, { S_3[i, j, k] -> [(i)] }]" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/0D-1.c b/external/mit/isl/dist/test_inputs/codegen/cloog/0D-1.c new file mode 100644 index 000000000000..7f22e2e417ed --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/0D-1.c @@ -0,0 +1 @@ +S1(); diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/0D-1.st b/external/mit/isl/dist/test_inputs/codegen/cloog/0D-1.st new file mode 100644 index 000000000000..d718258801b9 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/0D-1.st @@ -0,0 +1,3 @@ +domain: "{ S1[] }" +child: + context: "{ [] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/0D-2.c b/external/mit/isl/dist/test_inputs/codegen/cloog/0D-2.c new file mode 100644 index 000000000000..b87b57eacfbc --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/0D-2.c @@ -0,0 +1,2 @@ +if (M >= 0) + S1(); diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/0D-2.st b/external/mit/isl/dist/test_inputs/codegen/cloog/0D-2.st new file mode 100644 index 000000000000..3ee60f687db9 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/0D-2.st @@ -0,0 +1,3 @@ +domain: "[M] -> { S1[] : M >= 0 }" +child: + context: "[M] -> { [] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/0D-3.c b/external/mit/isl/dist/test_inputs/codegen/cloog/0D-3.c new file mode 100644 index 000000000000..7f22e2e417ed --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/0D-3.c @@ -0,0 +1 @@ +S1(); diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/0D-3.st b/external/mit/isl/dist/test_inputs/codegen/cloog/0D-3.st new file mode 100644 index 000000000000..97cd37ea47fb --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/0D-3.st @@ -0,0 +1,3 @@ +domain: "[M] -> { S1[] : M >= 0 }" +child: + context: "[M] -> { [] : M >= 0 }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/1point-1.c b/external/mit/isl/dist/test_inputs/codegen/cloog/1point-1.c new file mode 100644 index 000000000000..53dd8931e6fc --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/1point-1.c @@ -0,0 +1 @@ +S1(2 * M, M); diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/1point-1.st b/external/mit/isl/dist/test_inputs/codegen/cloog/1point-1.st new file mode 100644 index 000000000000..619487890025 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/1point-1.st @@ -0,0 +1,6 @@ +domain: "[M] -> { S1[2M, M] }" +child: + context: "[M] -> { [] }" + child: + schedule: "[M] -> [{ S1[i0, i1] -> [(i0)] }, { S1[i0, i1] -> [(i1)] }]" + options: "[M] -> { separate[i0] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/1point-2.c b/external/mit/isl/dist/test_inputs/codegen/cloog/1point-2.c new file mode 100644 index 000000000000..0a8cbe37d2f8 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/1point-2.c @@ -0,0 +1 @@ +S1(2 * M, N + 2); diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/1point-2.st b/external/mit/isl/dist/test_inputs/codegen/cloog/1point-2.st new file mode 100644 index 000000000000..9e7adfa0309c --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/1point-2.st @@ -0,0 +1,6 @@ +domain: "[M, N] -> { S1[2M, 2 + N] }" +child: + context: "[M, N] -> { [] }" + child: + schedule: "[M, N] -> [{ S1[i0, i1] -> [(i0)] }, { S1[i0, i1] -> [(i1)] }]" + options: "[M, N] -> { separate[i0] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/4-param.c b/external/mit/isl/dist/test_inputs/codegen/cloog/4-param.c new file mode 100644 index 000000000000..9a5135bbe1a3 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/4-param.c @@ -0,0 +1,12 @@ +for (int c0 = p; c0 <= min(m - 1, q); c0 += 1) + S2(c0); +for (int c0 = m; c0 <= min(n, p - 1); c0 += 1) + S1(c0); +for (int c0 = max(m, p); c0 <= min(n, q); c0 += 1) { + S1(c0); + S2(c0); +} +for (int c0 = max(max(m, n + 1), p); c0 <= q; c0 += 1) + S2(c0); +for (int c0 = max(max(m, p), q + 1); c0 <= n; c0 += 1) + S1(c0); diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/4-param.st b/external/mit/isl/dist/test_inputs/codegen/cloog/4-param.st new file mode 100644 index 000000000000..24335954184c --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/4-param.st @@ -0,0 +1,10 @@ +domain: "[m, n, p, q] -> { S1[i0] : i0 >= m and i0 <= n; S2[i0] : i0 >= p and i0 <= q }" +child: + context: "[m, n, p, q] -> { [] }" + child: + schedule: "[m, n, p, q] -> [{ S2[i0] -> [(i0)]; S1[i0] -> [(i0)] }]" + options: "[m, n, p, q] -> { separate[i0] }" + child: + sequence: + - filter: "[m, n, p, q] -> { S1[i0] }" + - filter: "[m, n, p, q] -> { S2[i0] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/README b/external/mit/isl/dist/test_inputs/codegen/cloog/README new file mode 100644 index 000000000000..9250f11e161d --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/README @@ -0,0 +1,2 @@ +The tests in this directory have been adapted from the corresponding CLooG +test cases. diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/backtrack.c b/external/mit/isl/dist/test_inputs/codegen/cloog/backtrack.c new file mode 100644 index 000000000000..df0407a437eb --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/backtrack.c @@ -0,0 +1 @@ +S1(0); diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/backtrack.st b/external/mit/isl/dist/test_inputs/codegen/cloog/backtrack.st new file mode 100644 index 000000000000..23fb152c8f66 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/backtrack.st @@ -0,0 +1,6 @@ +domain: "{ S1[0] }" +child: + context: "{ [] }" + child: + schedule: "[{ S1[i0] -> [(i0)] }]" + options: "{ separate[i0] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/basic-bounds-1.c b/external/mit/isl/dist/test_inputs/codegen/cloog/basic-bounds-1.c new file mode 100644 index 000000000000..95eb5f716e3d --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/basic-bounds-1.c @@ -0,0 +1,2 @@ +for (int c0 = 0; c0 <= 2; c0 += 1) + S1(c0); diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/basic-bounds-1.st b/external/mit/isl/dist/test_inputs/codegen/cloog/basic-bounds-1.st new file mode 100644 index 000000000000..7c599e8dd16b --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/basic-bounds-1.st @@ -0,0 +1,6 @@ +domain: "{ S1[i0] : i0 >= 0 and i0 <= 2 }" +child: + context: "{ [] }" + child: + schedule: "[{ S1[i0] -> [(i0)] }]" + options: "{ separate[i0] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/basic-bounds-2.c b/external/mit/isl/dist/test_inputs/codegen/cloog/basic-bounds-2.c new file mode 100644 index 000000000000..df0407a437eb --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/basic-bounds-2.c @@ -0,0 +1 @@ +S1(0); diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/basic-bounds-2.st b/external/mit/isl/dist/test_inputs/codegen/cloog/basic-bounds-2.st new file mode 100644 index 000000000000..23fb152c8f66 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/basic-bounds-2.st @@ -0,0 +1,6 @@ +domain: "{ S1[0] }" +child: + context: "{ [] }" + child: + schedule: "[{ S1[i0] -> [(i0)] }]" + options: "{ separate[i0] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/basic-bounds-3.c b/external/mit/isl/dist/test_inputs/codegen/cloog/basic-bounds-3.c new file mode 100644 index 000000000000..d0dd54bd0894 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/basic-bounds-3.c @@ -0,0 +1,2 @@ +for (int c0 = 0; c0 <= M; c0 += 1) + S1(c0); diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/basic-bounds-3.st b/external/mit/isl/dist/test_inputs/codegen/cloog/basic-bounds-3.st new file mode 100644 index 000000000000..437f566f0c79 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/basic-bounds-3.st @@ -0,0 +1,6 @@ +domain: "[M] -> { S1[i0] : i0 >= 0 and i0 <= M }" +child: + context: "[M] -> { [] : M >= 0 }" + child: + schedule: "[M] -> [{ S1[i0] -> [(i0)] }]" + options: "[M] -> { separate[i0] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/basic-bounds-4.c b/external/mit/isl/dist/test_inputs/codegen/cloog/basic-bounds-4.c new file mode 100644 index 000000000000..0ebb7ccbb43e --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/basic-bounds-4.c @@ -0,0 +1,2 @@ +for (int c0 = 0; c0 <= M + 1; c0 += 1) + S1(c0); diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/basic-bounds-4.st b/external/mit/isl/dist/test_inputs/codegen/cloog/basic-bounds-4.st new file mode 100644 index 000000000000..a5a0b1a06b3b --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/basic-bounds-4.st @@ -0,0 +1,6 @@ +domain: "[M] -> { S1[i0] : i0 >= 0 and i0 <= 1 + M }" +child: + context: "[M] -> { [] : M >= 0 }" + child: + schedule: "[M] -> [{ S1[i0] -> [(i0)] }]" + options: "[M] -> { separate[i0] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/basic-bounds-5.c b/external/mit/isl/dist/test_inputs/codegen/cloog/basic-bounds-5.c new file mode 100644 index 000000000000..09e8c4221689 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/basic-bounds-5.c @@ -0,0 +1 @@ +S1(1, floord(M + 1, 2)); diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/basic-bounds-5.st b/external/mit/isl/dist/test_inputs/codegen/cloog/basic-bounds-5.st new file mode 100644 index 000000000000..e0bc58fbc2c0 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/basic-bounds-5.st @@ -0,0 +1,6 @@ +domain: "[M] -> { S1[1, i1] : 2i1 >= M and 2i1 <= 1 + M }" +child: + context: "[M] -> { [] }" + child: + schedule: "[M] -> [{ S1[i0, i1] -> [(i0)] }, { S1[i0, i1] -> [(i1)] }]" + options: "[M] -> { separate[i0] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/basic-bounds-6.c b/external/mit/isl/dist/test_inputs/codegen/cloog/basic-bounds-6.c new file mode 100644 index 000000000000..da8a3fbcf9b6 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/basic-bounds-6.c @@ -0,0 +1 @@ +S1(-1); diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/basic-bounds-6.st b/external/mit/isl/dist/test_inputs/codegen/cloog/basic-bounds-6.st new file mode 100644 index 000000000000..a65f0880cfa2 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/basic-bounds-6.st @@ -0,0 +1,6 @@ +domain: "{ S1[-1] }" +child: + context: "{ [] }" + child: + schedule: "[{ S1[i0] -> [(i0)] }]" + options: "{ separate[i0] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/block.c b/external/mit/isl/dist/test_inputs/codegen/cloog/block.c new file mode 100644 index 000000000000..9aadfdfb27c4 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/block.c @@ -0,0 +1,4 @@ +S1(); +S3(0); +S2(); +S3(1); diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/block.st b/external/mit/isl/dist/test_inputs/codegen/cloog/block.st new file mode 100644 index 000000000000..0ab2d8854b18 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/block.st @@ -0,0 +1,10 @@ +domain: "{ S1[]; S3[i0] : i0 >= 0 and i0 <= 1; S2[] }" +child: + context: "{ [] }" + child: + schedule: "[{ S2[] -> [(1)]; S3[i0] -> [(i0)]; S1[] -> [(0)] }]" + options: "{ separate[i0] }" + child: + sequence: + - filter: "{ S1[]; S2[] }" + - filter: "{ S3[i0] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/block2.c b/external/mit/isl/dist/test_inputs/codegen/cloog/block2.c new file mode 100644 index 000000000000..d3fbbd7802ae --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/block2.c @@ -0,0 +1,5 @@ +for (int c0 = 0; c0 <= 9; c0 += 1) { + S1(c0, 1); + S3(c0, 1); + S2(c0, 1); +} diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/block2.st b/external/mit/isl/dist/test_inputs/codegen/cloog/block2.st new file mode 100644 index 000000000000..b18ce927ea89 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/block2.st @@ -0,0 +1,11 @@ +domain: "{ S2[i0, 1] : i0 >= 0 and i0 <= 9; S1[i0, 1] : i0 >= 0 and i0 <= 9; S3[i0, 1] : i0 >= 0 and i0 <= 9 }" +child: + context: "{ [] }" + child: + schedule: "[{ S3[i0, i1] -> [(i0)]; S1[i0, i1] -> [(i0)]; S2[i0, i1] -> [(i0)] }, { S3[i0, i1] -> [(i1)]; S1[i0, i1] -> [(i1)]; S2[i0, i1] -> [(i1)] }]" + options: "{ separate[i0] }" + child: + sequence: + - filter: "{ S1[i0, i1] }" + - filter: "{ S3[i0, i1] }" + - filter: "{ S2[i0, i1] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/block3.c b/external/mit/isl/dist/test_inputs/codegen/cloog/block3.c new file mode 100644 index 000000000000..98ccf57e2f6a --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/block3.c @@ -0,0 +1,4 @@ +S1(); +for (int c0 = 0; c0 <= 1; c0 += 1) + S3(c0); +S2(); diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/block3.st b/external/mit/isl/dist/test_inputs/codegen/cloog/block3.st new file mode 100644 index 000000000000..85f197f33189 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/block3.st @@ -0,0 +1,6 @@ +domain: "{ S1[]; S3[i0] : i0 >= 0 and i0 <= 1; S2[] }" +child: + context: "{ [] }" + child: + schedule: "[{ S2[] -> [(1)]; S3[i0] -> [(i0)]; S1[] -> [(0)] }]" + options: "{ separate[i0] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/byu98-1-2-3.c b/external/mit/isl/dist/test_inputs/codegen/cloog/byu98-1-2-3.c new file mode 100644 index 000000000000..c94f848f043f --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/byu98-1-2-3.c @@ -0,0 +1,16 @@ +for (int c0 = 2; c0 <= 3; c0 += 1) + for (int c1 = -c0 + 6; c1 <= 6; c1 += 1) + S1(c0, c1); +for (int c0 = 4; c0 <= 8; c0 += 1) { + if (c0 == 4) + for (int c1 = 3; c1 <= 4; c1 += 1) + S1(4, c1); + if (c0 <= 5) { + S1(c0, -c0 + 9); + S2(c0, -c0 + 9); + } else { + S2(c0, -c0 + 9); + } + for (int c1 = max(c0 - 1, -c0 + 10); c1 <= 6; c1 += 1) + S1(c0, c1); +} diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/byu98-1-2-3.st b/external/mit/isl/dist/test_inputs/codegen/cloog/byu98-1-2-3.st new file mode 100644 index 000000000000..84d3791d33ad --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/byu98-1-2-3.st @@ -0,0 +1,10 @@ +domain: "{ S2[i0, 9 - i0] : i0 <= 8 and i0 >= 4; S1[i0, i1] : i1 >= 6 - i0 and i0 >= 2 and i1 >= 3 and i1 <= 6 and i1 >= -1 + i0 }" +child: + context: "{ [] }" + child: + schedule: "[{ S1[i0, i1] -> [(i0)]; S2[i0, i1] -> [(i0)] }, { S1[i0, i1] -> [(i1)]; S2[i0, i1] -> [(i1)] }]" + options: "{ separate[i0] }" + child: + sequence: + - filter: "{ S1[i0, i1] }" + - filter: "{ S2[i0, i1] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/cholesky.c b/external/mit/isl/dist/test_inputs/codegen/cloog/cholesky.c new file mode 100644 index 000000000000..1cf61c20eff1 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/cholesky.c @@ -0,0 +1,12 @@ +for (int c0 = 1; c0 <= n; c0 += 1) { + S1(c0); + for (int c1 = 1; c1 < c0; c1 += 1) + S2(c0, c1); + S3(c0); + for (int c1 = c0 + 1; c1 <= n; c1 += 1) { + S4(c0, c1); + for (int c2 = 1; c2 < c0; c2 += 1) + S5(c0, c1, c2); + S6(c0, c1); + } +} diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/cholesky.st b/external/mit/isl/dist/test_inputs/codegen/cloog/cholesky.st new file mode 100644 index 000000000000..a6e910a53867 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/cholesky.st @@ -0,0 +1,26 @@ +domain: "[n] -> { S2[i0, i1] : i0 >= 1 and i0 <= n and i1 >= 1 and i1 <= -1 + i0; S1[i0] : i0 >= 1 and i0 <= n; S4[i0, i1] : i0 >= 1 and i0 <= n and i1 >= 1 + i0 and i1 <= n; S5[i0, i1, i2] : i0 >= 1 and i0 <= n and i1 >= 1 + i0 and i1 <= n and i2 >= 1 and i2 <= -1 + i0; S6[i0, i1] : i0 >= 1 and i0 <= n and i1 >= 1 + i0 and i1 <= n; S3[i0] : i0 >= 1 and i0 <= n }" +child: + context: "[n] -> { [] }" + child: + schedule: "[n] -> [{ S1[i0] -> [(i0)]; S4[i0, i1] -> [(i0)]; S6[i0, i1] -> [(i0)]; S3[i0] -> [(i0)]; S5[i0, i1, i2] -> [(i0)]; S2[i0, i1] -> [(i0)] }]" + options: "[n] -> { separate[i0] }" + child: + sequence: + - filter: "[n] -> { S1[i0] }" + - filter: "[n] -> { S2[i0, i1] }" + child: + schedule: "[n] -> [{ S2[i0, i1] -> [(i1)] }]" + options: "[n] -> { separate[i0] }" + - filter: "[n] -> { S3[i0] }" + - filter: "[n] -> { S4[i0, i1]; S5[i0, i1, i2]; S6[i0, i1] }" + child: + schedule: "[n] -> [{ S4[i0, i1] -> [(i1)]; S6[i0, i1] -> [(i1)]; S5[i0, i1, i2] -> [(i1)] }]" + options: "[n] -> { separate[i0] }" + child: + sequence: + - filter: "[n] -> { S4[i0, i1] }" + - filter: "[n] -> { S5[i0, i1, i2] }" + child: + schedule: "[n] -> [{ S5[i0, i1, i2] -> [(i2)] }]" + options: "[n] -> { separate[i0] }" + - filter: "[n] -> { S6[i0, i1] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/cholesky2.c b/external/mit/isl/dist/test_inputs/codegen/cloog/cholesky2.c new file mode 100644 index 000000000000..2b0cb6e5e996 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/cholesky2.c @@ -0,0 +1,15 @@ +for (int c1 = 1; c1 <= M; c1 += 1) { + S1(c1); + for (int c2 = c1 + 1; c2 <= M; c2 += 1) + S4(c1, c2); +} +for (int c0 = 1; c0 < 3 * M - 1; c0 += 3) { + S3((c0 + 2) / 3); + for (int c1 = (c0 + 5) / 3; c1 <= M; c1 += 1) { + S6((c0 + 2) / 3, c1); + for (int c4 = (c0 + 5) / 3; c4 < c1; c4 += 1) + S5(c4, c1, (c0 + 2) / 3); + } + for (int c1 = (c0 + 5) / 3; c1 <= M; c1 += 1) + S2(c1, (c0 + 2) / 3); +} diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/cholesky2.st b/external/mit/isl/dist/test_inputs/codegen/cloog/cholesky2.st new file mode 100644 index 000000000000..d49ff85865aa --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/cholesky2.st @@ -0,0 +1,6 @@ +domain: "[M] -> { S4[i0, i1] : i0 >= 1 and i0 <= M and i1 >= 1 + i0 and i1 <= M; S5[i0, i1, i2] : i0 >= 1 and i0 <= M and i1 >= 1 + i0 and i1 <= M and i2 >= 1 and i2 <= -1 + i0; S6[i0, i1] : i0 >= 1 and i0 <= M and i1 >= 1 + i0 and i1 <= M; S3[i0] : i0 >= 1 and i0 <= M; S2[i0, i1] : i0 >= 1 and i0 <= M and i1 >= 1 and i1 <= -1 + i0; S1[i0] : i0 >= 1 and i0 <= M }" +child: + context: "[M] -> { [] }" + child: + schedule: "[M] -> [{ S1[i0] -> [(0)]; S3[i0] -> [(-2 + 3i0)]; S4[i0, i1] -> [(0)]; S5[i0, i1, i2] -> [(-1 + 3i2)]; S2[i0, i1] -> [(3i1)]; S6[i0, i1] -> [(-1 + 3i0)] }, { S1[i0] -> [(i0)]; S3[i0] -> [(0)]; S4[i0, i1] -> [(i0)]; S5[i0, i1, i2] -> [(i1)]; S2[i0, i1] -> [(i0)]; S6[i0, i1] -> [(i1)] }, { S1[i0] -> [(0)]; S3[i0] -> [(0)]; S4[i0, i1] -> [(i1)]; S5[i0, i1, i2] -> [(i2)]; S2[i0, i1] -> [(0)]; S6[i0, i1] -> [(0)] }]" + options: "[M] -> { separate[i0] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/christian.c b/external/mit/isl/dist/test_inputs/codegen/cloog/christian.c new file mode 100644 index 000000000000..113249a124ff --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/christian.c @@ -0,0 +1,6 @@ +for (int c0 = -N + 1; c0 <= N; c0 += 1) { + for (int c1 = max(0, c0); c1 < min(N, N + c0); c1 += 1) + S1(c1, -c0 + c1); + for (int c1 = max(0, c0 - 1); c1 < min(N, N + c0 - 1); c1 += 1) + S2(c1, -c0 + c1 + 1); +} diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/christian.st b/external/mit/isl/dist/test_inputs/codegen/cloog/christian.st new file mode 100644 index 000000000000..b4517743fd98 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/christian.st @@ -0,0 +1,6 @@ +domain: "[N] -> { S1[i0, i1] : i0 >= 0 and i0 <= -1 + N and i1 >= 0 and i1 <= -1 + N; S2[i0, i1] : i0 >= 0 and i0 <= -1 + N and i1 >= 0 and i1 <= -1 + N }" +child: + context: "[N] -> { [] }" + child: + schedule: "[N] -> [{ S1[i0, i1] -> [(i0 - i1)]; S2[i0, i1] -> [(1 + i0 - i1)] }]" + options: "[N] -> { separate[i0] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/classen.c b/external/mit/isl/dist/test_inputs/codegen/cloog/classen.c new file mode 100644 index 000000000000..ec6daad20a55 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/classen.c @@ -0,0 +1,63 @@ +if (m >= 1) { + S1(0, 1, 1, 1); + if (m >= 2) { + S4(0, 1, 2, 2, 1, 1, 2, 2); + S3(0, 1, 1, 2, 1, 1, 1, 2); + S2(0, 1, 1, 1, 1, 1, 2, 1); + } + S8(0, 1); + for (int c0 = 1; c0 < 2 * m - 1; c0 += 1) { + if (2 * m >= c0 + 3) { + if (c0 + 1 == m) { + S5(m - 2, 1, m - 1, 1, m - 1, 1, m, 1); + S1(m - 1, 1, m, 1); + S3(m - 1, 1, m, 2, m, 1, m, 2); + } else if (c0 >= m) { + S5(c0 - 1, -m + c0 + 2, c0, -m + c0 + 2, m - 1, -m + c0 + 2, m, -m + c0 + 2); + S6(c0 - 1, -m + c0 + 1, c0, -m + c0 + 2, m, -m + c0 + 1, m, -m + c0 + 2); + S1(c0, -m + c0 + 2, m, -m + c0 + 2); + S3(c0, -m + c0 + 2, c0 + 1, -m + c0 + 3, m, -m + c0 + 2, m, -m + c0 + 3); + } else { + S5(c0 - 1, 1, c0, 1, c0, 1, c0 + 1, 1); + S1(c0, 1, c0 + 1, 1); + S3(c0, 1, c0 + 1, 2, c0 + 1, 1, c0 + 1, 2); + S4(c0, 1, c0 + 2, 2, c0 + 1, 1, c0 + 2, 2); + S2(c0, 1, c0 + 1, 1, c0 + 1, 1, c0 + 2, 1); + } + for (int c1 = max(2, -m + c0 + 3); c1 <= min(m - 1, c0); c1 += 1) { + S5(c0 - 1, c1, c0, c1, c0 - c1 + 1, c1, c0 - c1 + 2, c1); + S6(c0 - 1, c1 - 1, c0, c1, c0 - c1 + 2, c1 - 1, c0 - c1 + 2, c1); + S7(c0 - 1, c1 - 1, c0 + 1, c1, c0 - c1 + 2, c1 - 1, c0 - c1 + 3, c1); + S1(c0, c1, c0 - c1 + 2, c1); + S3(c0, c1, c0 + 1, c1 + 1, c0 - c1 + 2, c1, c0 - c1 + 2, c1 + 1); + S4(c0, c1, c0 + 2, c1 + 1, c0 - c1 + 2, c1, c0 - c1 + 3, c1 + 1); + S2(c0, c1, c0 + 1, c1, c0 - c1 + 2, c1, c0 - c1 + 3, c1); + } + if (c0 + 1 == m) { + S6(m - 2, m - 1, m - 1, m, 1, m - 1, 1, m); + S7(m - 2, m - 1, m, m, 1, m - 1, 2, m); + S1(m - 1, m, 1, m); + S2(m - 1, m, m, m, 1, m, 2, m); + } else if (c0 >= m) { + S5(c0 - 1, m, c0, m, -m + c0 + 1, m, -m + c0 + 2, m); + S6(c0 - 1, m - 1, c0, m, -m + c0 + 2, m - 1, -m + c0 + 2, m); + S7(c0 - 1, m - 1, c0 + 1, m, -m + c0 + 2, m - 1, -m + c0 + 3, m); + S1(c0, m, -m + c0 + 2, m); + S2(c0, m, c0 + 1, m, -m + c0 + 2, m, -m + c0 + 3, m); + } else { + S6(c0 - 1, c0, c0, c0 + 1, 1, c0, 1, c0 + 1); + S7(c0 - 1, c0, c0 + 1, c0 + 1, 1, c0, 2, c0 + 1); + S1(c0, c0 + 1, 1, c0 + 1); + S3(c0, c0 + 1, c0 + 1, c0 + 2, 1, c0 + 1, 1, c0 + 2); + S4(c0, c0 + 1, c0 + 2, c0 + 2, 1, c0 + 1, 2, c0 + 2); + S2(c0, c0 + 1, c0 + 1, c0 + 1, 1, c0 + 1, 2, c0 + 1); + } + } else { + S5(2 * m - 3, m, 2 * m - 2, m, m - 1, m, m, m); + S6(2 * m - 3, m - 1, 2 * m - 2, m, m, m - 1, m, m); + S1(2 * m - 2, m, m, m); + } + for (int c2 = max(1, -m + c0 + 2); c2 <= min(m, c0 + 1); c2 += 1) + S8(c0, c2); + } +} diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/classen.st b/external/mit/isl/dist/test_inputs/codegen/cloog/classen.st new file mode 100644 index 000000000000..e9d3baf611f1 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/classen.st @@ -0,0 +1,24 @@ +domain: "[m] -> { S2[coordT1, coordP1, 1 + coordT1, coordP1, 2 + coordT1 - coordP1, coordP1, 3 + coordT1 - coordP1, coordP1] : m >= 1 and coordT1 <= -3 + 2m and coordT1 >= 0 and coordP1 <= 1 + coordT1 and coordP1 <= m and coordP1 >= 3 - m + coordT1 and coordP1 >= 1; S4[coordT1, coordP1, 2 + coordT1, 1 + coordP1, 2 + coordT1 - coordP1, coordP1, 3 + coordT1 - coordP1, 1 + coordP1] : m >= 1 and coordT1 <= -4 + 2m and coordT1 >= 0 and coordP1 <= 1 + coordT1 and coordP1 <= -1 + m and coordP1 >= 3 - m + coordT1 and coordP1 >= 1; S6[coordT1, coordP1, 1 + coordT1, 1 + coordP1, 2 + coordT1 - coordP1, coordP1, 2 + coordT1 - coordP1, 1 + coordP1] : m >= 1 and coordT1 <= -3 + 2m and coordT1 >= 0 and coordP1 <= 1 + coordT1 and coordP1 <= -1 + m and coordP1 >= 2 - m + coordT1 and coordP1 >= 1; S1[coordT1, coordP1, 2 + coordT1 - coordP1, coordP1] : m >= 1 and coordP1 >= 2 - m + coordT1 and coordP1 <= 1 + coordT1 and coordP1 <= m and coordP1 >= 1; S8[coordT1, coordP1] : coordT1 <= -2 + 2m and coordT1 >= 0 and coordP1 <= 1 + coordT1 and coordP1 <= m and coordP1 >= 2 - m + coordT1 and coordP1 >= 1; S5[coordT1, coordP1, 1 + coordT1, coordP1, 2 + coordT1 - coordP1, coordP1, 3 + coordT1 - coordP1, coordP1] : m >= 1 and coordT1 <= -3 + 2m and coordT1 >= 0 and coordP1 <= 1 + coordT1 and coordP1 <= m and coordP1 >= 3 - m + coordT1 and coordP1 >= 1; S7[coordT1, coordP1, 2 + coordT1, 1 + coordP1, 2 + coordT1 - coordP1, coordP1, 3 + coordT1 - coordP1, 1 + coordP1] : m >= 1 and coordT1 <= -4 + 2m and coordT1 >= 0 and coordP1 <= 1 + coordT1 and coordP1 <= -1 + m and coordP1 >= 3 - m + coordT1 and coordP1 >= 1; S3[coordT1, coordP1, 1 + coordT1, 1 + coordP1, 2 + coordT1 - coordP1, coordP1, 2 + coordT1 - coordP1, 1 + coordP1] : m >= 1 and coordT1 <= -3 + 2m and coordT1 >= 0 and coordP1 <= 1 + coordT1 and coordP1 <= -1 + m and coordP1 >= 2 - m + coordT1 and coordP1 >= 1 }" +child: + context: "[m] -> { [] : m >= 0 }" + child: + schedule: "[m] -> [{ S7[i0, i1, i2, i3, i4, i5, i6, i7] -> [(1 + i0)]; S4[i0, i1, i2, i3, i4, i5, i6, i7] -> [(i0)]; S8[i0, i1] -> [(i0)]; S3[i0, i1, i2, i3, i4, i5, i6, i7] -> [(i0)]; S1[i0, i1, i2, i3] -> [(i0)]; S2[i0, i1, i2, i3, i4, i5, i6, i7] -> [(i0)]; S5[i0, i1, i2, i3, i4, i5, i6, i7] -> [(1 + i0)]; S6[i0, i1, i2, i3, i4, i5, i6, i7] -> [(1 + i0)] }]" + options: "[m] -> { separate[i0] }" + child: + sequence: + - filter: "[m] -> { S2[i0, i1, i2, i3, i4, i5, i6, i7]; S6[i0, i1, i2, i3, i4, i5, i6, i7]; S4[i0, i1, i2, i3, i4, i5, i6, i7]; S1[i0, i1, i2, i3]; S7[i0, i1, i2, i3, i4, i5, i6, i7]; S5[i0, i1, i2, i3, i4, i5, i6, i7]; S3[i0, i1, i2, i3, i4, i5, i6, i7] }" + child: + schedule: "[m] -> [{ S7[i0, i1, i2, i3, i4, i5, i6, i7] -> [(i3)]; S4[i0, i1, i2, i3, i4, i5, i6, i7] -> [(i1)]; S3[i0, i1, i2, i3, i4, i5, i6, i7] -> [(i1)]; S1[i0, i1, i2, i3] -> [(i1)]; S2[i0, i1, i2, i3, i4, i5, i6, i7] -> [(i1)]; S5[i0, i1, i2, i3, i4, i5, i6, i7] -> [(i3)]; S6[i0, i1, i2, i3, i4, i5, i6, i7] -> [(i3)] }]" + options: "[m] -> { separate[i0] }" + child: + sequence: + - filter: "[m] -> { S6[i0, i1, i2, i3, i4, i5, i6, i7]; S5[i0, i1, i2, i3, i4, i5, i6, i7]; S7[i0, i1, i2, i3, i4, i5, i6, i7] }" + child: + schedule: "[m] -> [{ S7[i0, i1, i2, i3, i4, i5, i6, i7] -> [(i4)]; S5[i0, i1, i2, i3, i4, i5, i6, i7] -> [(i4)]; S6[i0, i1, i2, i3, i4, i5, i6, i7] -> [(i4)] }, { S7[i0, i1, i2, i3, i4, i5, i6, i7] -> [(i5)]; S5[i0, i1, i2, i3, i4, i5, i6, i7] -> [(i5)]; S6[i0, i1, i2, i3, i4, i5, i6, i7] -> [(i5)] }]" + options: "[m] -> { separate[i0] }" + - filter: "[m] -> { S1[i0, i1, i2, i3] }" + - filter: "[m] -> { S2[i0, i1, i2, i3, i4, i5, i6, i7]; S4[i0, i1, i2, i3, i4, i5, i6, i7]; S3[i0, i1, i2, i3, i4, i5, i6, i7] }" + child: + schedule: "[m] -> [{ S4[i0, i1, i2, i3, i4, i5, i6, i7] -> [(i4)]; S3[i0, i1, i2, i3, i4, i5, i6, i7] -> [(i4)]; S2[i0, i1, i2, i3, i4, i5, i6, i7] -> [(i4)] }, { S4[i0, i1, i2, i3, i4, i5, i6, i7] -> [(i5)]; S3[i0, i1, i2, i3, i4, i5, i6, i7] -> [(i5)]; S2[i0, i1, i2, i3, i4, i5, i6, i7] -> [(i5)] }]" + options: "[m] -> { separate[i0] }" + - filter: "[m] -> { S8[i0, i1] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/classen2.c b/external/mit/isl/dist/test_inputs/codegen/cloog/classen2.c new file mode 100644 index 000000000000..a737d2d4b1a2 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/classen2.c @@ -0,0 +1,4 @@ +for (int c0 = max(max(max(max(max(max(4, 5 * outerTimeTileScatter), 5 * outerProcTileScatter1), 5 * outerProcTileScatter2 + 1), 5 * outerProcTileScatter1 + 5 * outerProcTileScatter2 - N), 10 * outerProcTileScatter2 - N + 1), 10 * outerProcTileScatter1 - 2 * N + 2); c0 <= min(min(min(min(min(min(5 * outerTimeTileScatter + 4, 10 * outerProcTileScatter1 + 4), 5 * outerProcTileScatter1 + 5 * outerProcTileScatter2 + 5), 5 * outerProcTileScatter1 + M + 2), 2 * M + 2 * N - 6), 5 * outerProcTileScatter2 + M + N), 10 * outerProcTileScatter2 + N + 3); c0 += 1) + for (int c1 = max(max(max(max(5 * outerProcTileScatter1, 5 * outerProcTileScatter2 + 1), -5 * outerProcTileScatter2 + c0 - 1), -M + c0 + 2), (c0 + 1) / 2 + 2); c1 <= min(min(min(min(5 * outerProcTileScatter1 + 4, 5 * outerProcTileScatter2 + N + 2), -5 * outerProcTileScatter2 + N + c0), c0), N + c0 / 2 - 1); c1 += 1) + for (int c2 = max(max(5 * outerProcTileScatter2, -N + c1 + 2), c0 - c1 + 3); c2 <= min(min(5 * outerProcTileScatter2 + 4, c1 - 1), N + c0 - c1); c2 += 1) + S1(c0 - c1 + 1, -c0 + c1 + c2 - 2, c1 - c2, c0, c1, c2); diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/classen2.st b/external/mit/isl/dist/test_inputs/codegen/cloog/classen2.st new file mode 100644 index 000000000000..f7115ca6a4d9 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/classen2.st @@ -0,0 +1,6 @@ +domain: "[outerTimeTileScatter, outerProcTileScatter1, outerProcTileScatter2, M, N] -> { S1[compIter1, compIter2, compIter3, 2compIter1 + compIter2 + compIter3, 1 + compIter1 + compIter2 + compIter3, 1 + compIter1 + compIter2] : N >= 3 and compIter3 <= 3 + 5outerProcTileScatter1 - compIter1 - compIter2 and compIter2 >= -1 + 5outerProcTileScatter2 - compIter1 and M >= 2 and compIter3 <= 4 + 5outerTimeTileScatter - 2compIter1 - compIter2 and compIter2 <= 3 + 5outerProcTileScatter2 - compIter1 and compIter3 >= 1 and compIter3 <= -2 + N and compIter2 >= 1 and compIter2 <= -2 + N and compIter1 >= 1 and compIter1 <= -1 + M and compIter3 >= 5outerTimeTileScatter - 2compIter1 - compIter2 and compIter3 >= -1 + 5outerProcTileScatter1 - compIter1 - compIter2 }" +child: + context: "[outerTimeTileScatter, outerProcTileScatter1, outerProcTileScatter2, M, N] -> { [] }" + child: + schedule: "[outerTimeTileScatter, outerProcTileScatter1, outerProcTileScatter2, M, N] -> [{ S1[i0, i1, i2, i3, i4, i5] -> [(i3)] }, { S1[i0, i1, i2, i3, i4, i5] -> [(i4)] }, { S1[i0, i1, i2, i3, i4, i5] -> [(i5)] }]" + options: "[outerTimeTileScatter, outerProcTileScatter1, outerProcTileScatter2, M, N] -> { separate[i0] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/constant.c b/external/mit/isl/dist/test_inputs/codegen/cloog/constant.c new file mode 100644 index 000000000000..a32c7e795031 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/constant.c @@ -0,0 +1,16 @@ +for (int c1 = 0; c1 <= min(1023, M + 1024); c1 += 1) { + S1(c1); + S3(c1); +} +for (int c1 = max(0, M + 1025); c1 <= 1023; c1 += 1) { + S2(c1); + S3(c1); +} +for (int c0 = 0; c0 <= min(1023, M + 1024); c0 += 1) { + S4(c0); + S6(c0); +} +for (int c0 = max(0, M + 1025); c0 <= 1023; c0 += 1) { + S5(c0); + S6(c0); +} diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/constant.st b/external/mit/isl/dist/test_inputs/codegen/cloog/constant.st new file mode 100644 index 000000000000..f4f85f742c1f --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/constant.st @@ -0,0 +1,11 @@ +domain: "[M] -> { S4[i0] : i0 >= 0 and i0 <= 1023 and i0 <= 1024 + M; S5[i0] : i0 >= 0 and i0 <= 1023 and i0 >= 1025 + M; S3[i0] : i0 >= 0 and i0 <= 1023; S2[i0] : i0 >= 0 and i0 <= 1023 and i0 >= 1025 + M; S1[i0] : i0 >= 0 and i0 <= 1023 and i0 <= 1024 + M; S6[i0] : i0 >= 0 and i0 <= 1023 }" +child: + context: "[M] -> { [] }" + child: + schedule: "[M] -> [{ S2[i0] -> [(-1)]; S4[i0] -> [(i0)]; S1[i0] -> [(-1)]; S3[i0] -> [(-1)]; S6[i0] -> [(i0)]; S5[i0] -> [(i0)] }, { S2[i0] -> [(i0)]; S4[i0] -> [(0)]; S1[i0] -> [(i0)]; S3[i0] -> [(i0)]; S6[i0] -> [(0)]; S5[i0] -> [(0)] }]" + options: "[M] -> { separate[i0] }" + child: + sequence: + - filter: "[M] -> { S4[i0]; S1[i0] }" + - filter: "[M] -> { S5[i0]; S2[i0] }" + - filter: "[M] -> { S3[i0]; S6[i0] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/constbound.c b/external/mit/isl/dist/test_inputs/codegen/cloog/constbound.c new file mode 100644 index 000000000000..7fbebe016da1 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/constbound.c @@ -0,0 +1,8 @@ +for (int c0 = 0; c0 <= 199; c0 += 1) { + for (int c1 = 50 * c0; c1 <= 50 * c0 + 24; c1 += 1) + for (int c2 = 0; c2 <= c1; c2 += 1) + S1(c0, c1, c2); + for (int c1 = 50 * c0 + 25; c1 <= 50 * c0 + 49; c1 += 1) + for (int c2 = 0; c2 <= c1; c2 += 1) + S2(c0, c1, c2); +} diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/constbound.st b/external/mit/isl/dist/test_inputs/codegen/cloog/constbound.st new file mode 100644 index 000000000000..1f6789e32e2d --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/constbound.st @@ -0,0 +1,16 @@ +domain: "{ S2[i0, i1, i2] : i1 >= 0 and i1 <= 9999 and i2 >= 0 and i2 <= i1 and i1 >= 25 + 50i0 and i1 <= 49 + 50i0; S1[i0, i1, i2] : i1 >= 0 and i1 <= 9999 and i2 >= 0 and i2 <= i1 and i1 >= 50i0 and i1 <= 24 + 50i0 }" +child: + context: "{ [] }" + child: + schedule: "[{ S1[i0, i1, i2] -> [(i0)]; S2[i0, i1, i2] -> [(i0)] }]" + options: "{ separate[i0] }" + child: + sequence: + - filter: "{ S1[i0, i1, i2] }" + child: + schedule: "[{ S1[i0, i1, i2] -> [(i1)] }, { S1[i0, i1, i2] -> [(i2)] }]" + options: "{ separate[i0] }" + - filter: "{ S2[i0, i1, i2] }" + child: + schedule: "[{ S2[i0, i1, i2] -> [(i1)] }, { S2[i0, i1, i2] -> [(i2)] }]" + options: "{ separate[i0] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/darte.c b/external/mit/isl/dist/test_inputs/codegen/cloog/darte.c new file mode 100644 index 000000000000..acb63714ed28 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/darte.c @@ -0,0 +1,14 @@ +for (int c0 = -n + 1; c0 <= n; c0 += 1) { + if (c0 <= 0) + for (int c2 = -c0 + 4; c2 <= 2 * n - c0 + 2; c2 += 2) + S1(1, -c0 + 1, ((c0 + c2) / 2) - 1); + for (int c1 = max(c0 + 2, -c0 + 4); c1 <= min(2 * n - c0, 2 * n + c0); c1 += 2) { + for (int c2 = c1 + 2; c2 <= 2 * n + c1; c2 += 2) + S1((c0 + c1) / 2, (-c0 + c1) / 2, (-c1 + c2) / 2); + for (int c2 = 1; c2 <= n; c2 += 1) + S2(((c0 + c1) / 2) - 1, (-c0 + c1) / 2, c2); + } + if (c0 >= 1) + for (int c2 = 1; c2 <= n; c2 += 1) + S2(n, n - c0 + 1, c2); +} diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/darte.st b/external/mit/isl/dist/test_inputs/codegen/cloog/darte.st new file mode 100644 index 000000000000..33e9386bf898 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/darte.st @@ -0,0 +1,6 @@ +domain: "[n] -> { S1[i0, i1, i2] : i0 >= 1 and i0 <= n and i1 >= 1 and i1 <= n and i2 >= 1 and i2 <= n; S2[i0, i1, i2] : i0 >= 1 and i0 <= n and i1 >= 1 and i1 <= n and i2 >= 1 and i2 <= n }" +child: + context: "[n] -> { [] }" + child: + schedule: "[n] -> [{ S1[i0, i1, i2] -> [(i0 - i1)]; S2[i0, i1, i2] -> [(1 + i0 - i1)] }, { S1[i0, i1, i2] -> [(i0 + i1)]; S2[i0, i1, i2] -> [(2 + i0 + i1)] }, { S1[i0, i1, i2] -> [(i0 + i1 + 2i2)]; S2[i0, i1, i2] -> [(i2)] }]" + options: "[n] -> { separate[i0] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/dealII.c b/external/mit/isl/dist/test_inputs/codegen/cloog/dealII.c new file mode 100644 index 000000000000..2151d999c213 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/dealII.c @@ -0,0 +1,16 @@ +for (int c0 = 0; c0 <= min(min(T_2 - 1, T_67 - 1), T_66); c0 += 1) { + S1(c0); + S2(c0); +} +for (int c0 = T_2; c0 <= min(T_67 - 1, T_66); c0 += 1) + S2(c0); +for (int c0 = max(0, T_66 + 1); c0 < min(T_2, T_67); c0 += 1) + S1(c0); +for (int c0 = T_67; c0 <= min(T_2 - 1, T_66); c0 += 1) { + S1(c0); + S2(c0); +} +for (int c0 = max(T_67, T_66 + 1); c0 < T_2; c0 += 1) + S1(c0); +if (T_2 == 0 && T_67 == 0) + S1(0); diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/dealII.st b/external/mit/isl/dist/test_inputs/codegen/cloog/dealII.st new file mode 100644 index 000000000000..586e8fb166d4 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/dealII.st @@ -0,0 +1,10 @@ +domain: "[T_2, T_67, T_66] -> { S1[scat_0] : (scat_0 >= 0 and scat_0 <= -1 + T_2) or (scat_0 <= -T_67 and scat_0 >= 0); S2[scat_0] : (scat_0 >= 0 and scat_0 <= T_66 and scat_0 <= -1 + T_2) or (scat_0 >= 0 and scat_0 <= T_66 and scat_0 <= -1 + T_67) }" +child: + context: "[T_2, T_67, T_66] -> { [] : T_2 <= 4 and T_2 >= 0 and T_67 <= 4 and T_67 >= 0 }" + child: + schedule: "[T_2, T_67, T_66] -> [{ S2[scat_0] -> [(scat_0)]; S1[scat_0] -> [(scat_0)] }]" + options: "[T_2, T_67, T_66] -> { separate[i0] }" + child: + sequence: + - filter: "[T_2, T_67, T_66] -> { S1[scat_0] }" + - filter: "[T_2, T_67, T_66] -> { S2[scat_0] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/donotsimp.c b/external/mit/isl/dist/test_inputs/codegen/cloog/donotsimp.c new file mode 100644 index 000000000000..6e2cfce802c2 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/donotsimp.c @@ -0,0 +1,6 @@ +for (int c0 = 1; c0 <= 10; c0 += 1) { + for (int c1 = 1; c1 <= c0; c1 += 1) + S1(c0, c1); + for (int c1 = 11; c1 <= M; c1 += 1) + S2(c0, c1); +} diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/donotsimp.st b/external/mit/isl/dist/test_inputs/codegen/cloog/donotsimp.st new file mode 100644 index 000000000000..1dd72f41335f --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/donotsimp.st @@ -0,0 +1,9 @@ +domain: "[M] -> { S1[i0, i1] : i0 >= 1 and i0 <= 10 and i1 >= 1 and i1 <= i0; S2[i0, i1] : i0 >= 1 and i0 <= 10 and i1 >= 11 and i1 <= M }" +child: + context: "[M] -> { [] : M >= 20 }" + child: + schedule: "[M] -> [{ S1[i0, i1] -> [(i0)]; S2[i0, i1] -> [(i0)] }]" + options: "[M] -> { separate[i0] }" + child: + schedule: "[M] -> [{ S1[i0, i1] -> [(i1)]; S2[i0, i1] -> [(i1)] }]" + options: "[M] -> { separate[i0] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/dot.c b/external/mit/isl/dist/test_inputs/codegen/cloog/dot.c new file mode 100644 index 000000000000..f9c115ff950e --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/dot.c @@ -0,0 +1,5 @@ +for (int c1 = 1; c1 <= M; c1 += 1) + S1(0, c1); +for (int c0 = 1; c0 <= N; c0 += 1) + for (int c1 = 1; c1 <= M; c1 += 1) + S2(c0, c1); diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/dot.st b/external/mit/isl/dist/test_inputs/codegen/cloog/dot.st new file mode 100644 index 000000000000..a9ca44a3044c --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/dot.st @@ -0,0 +1,10 @@ +domain: "[M, N] -> { S1[0, i1] : i1 <= M and N >= 0 and i1 >= 1; S2[i0, i1] : i0 >= 1 and i1 <= M and i0 <= N and i1 >= 1 }" +child: + context: "[M, N] -> { [] : M >= 1 and N >= 1 }" + child: + schedule: "[M, N] -> [{ S1[i0, i1] -> [(i0)]; S2[i0, i1] -> [(i0)] }, { S1[i0, i1] -> [(i1)]; S2[i0, i1] -> [(i1)] }]" + options: "[M, N] -> { separate[i0] }" + child: + sequence: + - filter: "[M, N] -> { S1[i0, i1] }" + - filter: "[M, N] -> { S2[i0, i1] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/dot2.c b/external/mit/isl/dist/test_inputs/codegen/cloog/dot2.c new file mode 100644 index 000000000000..12faa6d48fd3 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/dot2.c @@ -0,0 +1,10 @@ +for (int c0 = 1; c0 <= min(M, N); c0 += 1) { + S1(c0); + for (int c1 = 1; c1 <= M; c1 += 1) + S2(c0, c1); +} +for (int c0 = N + 1; c0 <= M; c0 += 1) + S1(c0); +for (int c0 = M + 1; c0 <= N; c0 += 1) + for (int c1 = 1; c1 <= M; c1 += 1) + S2(c0, c1); diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/dot2.st b/external/mit/isl/dist/test_inputs/codegen/cloog/dot2.st new file mode 100644 index 000000000000..192d23c34710 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/dot2.st @@ -0,0 +1,10 @@ +domain: "[M, N] -> { S1[i0] : i0 >= 1 and i0 <= M; S2[i0, i1] : i0 >= 1 and i0 <= N and i1 >= 1 and i1 <= M }" +child: + context: "[M, N] -> { [] : M >= 1 and N >= 1 }" + child: + schedule: "[M, N] -> [{ S2[i0, i1] -> [(i0)]; S1[i0] -> [(i0)] }, { S2[i0, i1] -> [(i1)]; S1[i0] -> [(0)] }]" + options: "[M, N] -> { separate[i0] }" + child: + sequence: + - filter: "[M, N] -> { S1[i0] }" + - filter: "[M, N] -> { S2[i0, i1] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/durbin_e_s.c b/external/mit/isl/dist/test_inputs/codegen/cloog/durbin_e_s.c new file mode 100644 index 000000000000..626015d3e8b9 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/durbin_e_s.c @@ -0,0 +1,21 @@ +S4(1, 0, 0); +S7(1, 0, 0); +S8(1, 0, 3); +for (int c0 = 2; c0 <= 9; c0 += 1) { + S2(c0, -7, 0); + for (int c1 = -7; c1 < c0 - 8; c1 += 1) + S3(c0, c1, 1); + S6(c0, c0 - 9, 2); + S8(c0, 0, 3); + for (int c1 = 1; c1 < c0; c1 += 1) + S5(c0, c1, 3); +} +S2(10, -7, 0); +for (int c1 = -7; c1 <= 1; c1 += 1) + S3(10, c1, 1); +S6(10, 1, 2); +for (int c1 = 1; c1 <= 9; c1 += 1) { + S5(10, c1, 3); + S1(10, c1, 4); +} +S1(10, 10, 4); diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/durbin_e_s.st b/external/mit/isl/dist/test_inputs/codegen/cloog/durbin_e_s.st new file mode 100644 index 000000000000..8b08767070e9 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/durbin_e_s.st @@ -0,0 +1,16 @@ +domain: "{ S2[i0, -7, 0] : i0 >= 2 and i0 <= 10; S4[1, 0, 0]; S6[i0, -9 + i0, 2] : i0 >= 2 and i0 <= 10; S1[10, i1, 4] : i1 >= 1 and i1 <= 10; S5[i0, i1, 3] : i1 <= -1 + i0 and i0 <= 10 and i1 >= 1; S7[1, 0, 0]; S8[i0, 0, 3] : i0 >= 1 and i0 <= 9; S3[i0, i1, 1] : i1 >= -7 and i0 <= 10 and i1 <= -9 + i0 }" +child: + context: "{ [] }" + child: + schedule: "[{ S6[i0, i1, i2] -> [(i0)]; S8[i0, i1, i2] -> [(i0)]; S5[i0, i1, i2] -> [(i0)]; S4[i0, i1, i2] -> [(i0)]; S7[i0, i1, i2] -> [(i0)]; S3[i0, i1, i2] -> [(i0)]; S1[i0, i1, i2] -> [(i0)]; S2[i0, i1, i2] -> [(i0)] }, { S6[i0, i1, i2] -> [(i1)]; S8[i0, i1, i2] -> [(i1)]; S5[i0, i1, i2] -> [(i1)]; S4[i0, i1, i2] -> [(i1)]; S7[i0, i1, i2] -> [(i1)]; S3[i0, i1, i2] -> [(i1)]; S1[i0, i1, i2] -> [(i1)]; S2[i0, i1, i2] -> [(i1)] }, { S6[i0, i1, i2] -> [(i2)]; S8[i0, i1, i2] -> [(i2)]; S5[i0, i1, i2] -> [(i2)]; S4[i0, i1, i2] -> [(i2)]; S7[i0, i1, i2] -> [(i2)]; S3[i0, i1, i2] -> [(i2)]; S1[i0, i1, i2] -> [(i2)]; S2[i0, i1, i2] -> [(i2)] }]" + options: "{ separate[i0] }" + child: + sequence: + - filter: "{ S1[i0, i1, i2] }" + - filter: "{ S2[i0, i1, i2] }" + - filter: "{ S3[i0, i1, i2] }" + - filter: "{ S4[i0, i1, i2] }" + - filter: "{ S5[i0, i1, i2] }" + - filter: "{ S6[i0, i1, i2] }" + - filter: "{ S7[i0, i1, i2] }" + - filter: "{ S8[i0, i1, i2] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/emploi.c b/external/mit/isl/dist/test_inputs/codegen/cloog/emploi.c new file mode 100644 index 000000000000..80ee37d5921d --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/emploi.c @@ -0,0 +1,5 @@ +for (int c0 = 1; c0 <= n; c0 += 1) { + S1(c0); + for (int c1 = 1; c1 <= m; c1 += 1) + S2(c0, c1); +} diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/emploi.st b/external/mit/isl/dist/test_inputs/codegen/cloog/emploi.st new file mode 100644 index 000000000000..a7f4c265f32d --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/emploi.st @@ -0,0 +1,10 @@ +domain: "[m, n] -> { S1[i0] : (i0 >= 1 and i0 <= n and i0 <= 2m) or (i0 >= m and i0 >= 1 and i0 <= n); S2[i0, i1] : i0 >= 1 and i0 <= n and i1 >= 1 and i1 <= m }" +child: + context: "[m, n] -> { [] }" + child: + schedule: "[m, n] -> [{ S1[i0] -> [(i0)]; S2[i0, i1] -> [(i0)] }, { S1[i0] -> [(0)]; S2[i0, i1] -> [(i1)] }]" + options: "[m, n] -> { separate[i0] }" + child: + sequence: + - filter: "[m, n] -> { S1[i0] }" + - filter: "[m, n] -> { S2[i0, i1] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/equality.c b/external/mit/isl/dist/test_inputs/codegen/cloog/equality.c new file mode 100644 index 000000000000..fa6ff75f0a5c --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/equality.c @@ -0,0 +1,7 @@ +for (int c0 = 0; c0 <= 5; c0 += 1) + for (int c1 = min(4, 2 * c0); c1 <= max(4, 2 * c0); c1 += 1) { + if (c1 == 2 * c0) + S1(c0, 2 * c0); + if (c1 == 4) + S2(c0, 4); + } diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/equality.st b/external/mit/isl/dist/test_inputs/codegen/cloog/equality.st new file mode 100644 index 000000000000..084689c1e758 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/equality.st @@ -0,0 +1,10 @@ +domain: "{ S2[i0, 4] : i0 >= 0 and i0 <= 5; S1[i0, 2i0] : i0 >= 0 and i0 <= 5 }" +child: + context: "{ [] }" + child: + schedule: "[{ S1[i0, i1] -> [(i0)]; S2[i0, i1] -> [(i0)] }, { S1[i0, i1] -> [(i1)]; S2[i0, i1] -> [(i1)] }]" + options: "{ atomic[i0] }" + child: + sequence: + - filter: "{ S1[i0, i1] }" + - filter: "{ S2[i0, i1] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/equality2.c b/external/mit/isl/dist/test_inputs/codegen/cloog/equality2.c new file mode 100644 index 000000000000..be22da28be44 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/equality2.c @@ -0,0 +1,8 @@ +for (int c0 = 1; c0 <= 10000; c0 += 1) + for (int c1 = 1000; c1 <= 1016; c1 += 1) + for (int c2 = 1; c2 < 2 * c1 - 1998; c2 += 1) { + if (c1 <= 1008 && c2 + 1999 == 2 * c1) + S2(c0, c1, 2 * c1 - 1999, 1, c0, 2 * c1 - 1000, 1, 2, c0, c1 - 499, 2 * c1 - 1999, c0, 2 * c1 - 1999, c1 - 999, c1 - 999); + if (c2 == 1 && c1 % 2 == 0) + S1(c0, c1, 1, 2, c0, (c1 / 2) + 1, c1 - 999, c0, c1 - 999, (c1 / 2) - 499, (c1 / 2) - 499); + } diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/equality2.st b/external/mit/isl/dist/test_inputs/codegen/cloog/equality2.st new file mode 100644 index 000000000000..bbcb3381e89e --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/equality2.st @@ -0,0 +1,10 @@ +domain: "{ S1[i0, i1, 1, 2, i0, i5, -999 + i1, i0, -999 + i1, i9, i10] : 2i5 = 2 + i1 and 2i9 = -998 + i1 and 2i10 = -998 + i1 and i0 >= 1 and i0 <= 10000 and i1 >= 1000 and i1 <= 1016; S2[i0, i1, -1999 + 2i1, 1, i0, -1000 + 2i1, 1, 2, i0, -499 + i1, -1999 + 2i1, i0, -1999 + 2i1, -999 + i1, -999 + i1] : i0 >= 1 and i0 <= 10000 and i1 >= 1000 and i1 <= 1008 }" +child: + context: "{ [] }" + child: + schedule: "[{ S1[i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10] -> [(i0)]; S2[i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12, i13, i14] -> [(i0)] }, { S1[i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10] -> [(i1)]; S2[i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12, i13, i14] -> [(i1)] }, { S1[i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10] -> [(i2)]; S2[i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12, i13, i14] -> [(i2)] }, { S1[i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10] -> [(i3)]; S2[i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12, i13, i14] -> [(i3)] }, { S1[i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10] -> [(i4)]; S2[i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12, i13, i14] -> [(i4)] }, { S1[i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10] -> [(i5)]; S2[i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12, i13, i14] -> [(i5)] }, { S1[i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10] -> [(i6)]; S2[i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12, i13, i14] -> [(i6)] }, { S1[i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10] -> [(i7)]; S2[i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12, i13, i14] -> [(i7)] }, { S1[i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10] -> [(i8)]; S2[i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12, i13, i14] -> [(i8)] }, { S1[i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10] -> [(i9)]; S2[i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12, i13, i14] -> [(i9)] }, { S1[i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10] -> [(i10)]; S2[i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12, i13, i14] -> [(i10)] }, { S1[i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10] -> [(0)]; S2[i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12, i13, i14] -> [(i11)] }, { S1[i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10] -> [(0)]; S2[i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12, i13, i14] -> [(i12)] }, { S1[i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10] -> [(0)]; S2[i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12, i13, i14] -> [(i13)] }, { S1[i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10] -> [(0)]; S2[i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12, i13, i14] -> [(i14)] }]" + options: "{ atomic[i0] }" + child: + sequence: + - filter: "{ S1[i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10] }" + - filter: "{ S2[i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12, i13, i14] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/esced.c b/external/mit/isl/dist/test_inputs/codegen/cloog/esced.c new file mode 100644 index 000000000000..f7c7ee0678c7 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/esced.c @@ -0,0 +1,5 @@ +for (int c0 = 1; c0 <= m; c0 += 1) { + S1(c0); + for (int c1 = 1; c1 <= n; c1 += 1) + S2(c0, c1); +} diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/esced.st b/external/mit/isl/dist/test_inputs/codegen/cloog/esced.st new file mode 100644 index 000000000000..f48ccf6a2954 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/esced.st @@ -0,0 +1,10 @@ +domain: "[n, m] -> { S1[i0] : i0 >= 1 and i0 <= m; S2[i0, i1] : i0 >= 1 and i0 <= m and i1 >= 1 and i1 <= n }" +child: + context: "[n, m] -> { [] }" + child: + schedule: "[n, m] -> [{ S2[i0, i1] -> [(i0)]; S1[i0] -> [(i0)] }, { S2[i0, i1] -> [(i1)]; S1[i0] -> [(0)] }]" + options: "[n, m] -> { separate[i0] }" + child: + sequence: + - filter: "[n, m] -> { S1[i0] }" + - filter: "[n, m] -> { S2[i0, i1] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/ex1.c b/external/mit/isl/dist/test_inputs/codegen/cloog/ex1.c new file mode 100644 index 000000000000..9f7aeae97514 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/ex1.c @@ -0,0 +1,13 @@ +for (int c0 = 0; c0 <= 14; c0 += 1) + for (int c1 = 0; c1 < n - 14; c1 += 1) + S1(c0, c1); +for (int c0 = 15; c0 <= n; c0 += 1) { + for (int c1 = 0; c1 <= 9; c1 += 1) + S1(c0, c1); + for (int c1 = 10; c1 < n - 14; c1 += 1) { + S1(c0, c1); + S2(c0, c1); + } + for (int c1 = n - 14; c1 <= n; c1 += 1) + S2(c0, c1); +} diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/ex1.st b/external/mit/isl/dist/test_inputs/codegen/cloog/ex1.st new file mode 100644 index 000000000000..ea0253881a12 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/ex1.st @@ -0,0 +1,10 @@ +domain: "[n] -> { S1[i0, i1] : i0 >= 0 and i0 <= n and i1 >= 0 and i1 <= -15 + n; S2[i0, i1] : i0 >= 15 and i0 <= n and i1 >= 10 and i1 <= n }" +child: + context: "[n] -> { [] : n >= 25 }" + child: + schedule: "[n] -> [{ S2[i0, i1] -> [(i0)]; S1[i0, i1] -> [(i0)] }, { S2[i0, i1] -> [(i1)]; S1[i0, i1] -> [(i1)] }]" + options: "[n] -> { separate[i0] }" + child: + sequence: + - filter: "[n] -> { S1[i0, i1] }" + - filter: "[n] -> { S2[i0, i1] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/faber.c b/external/mit/isl/dist/test_inputs/codegen/cloog/faber.c new file mode 100644 index 000000000000..a0ed89b1b9e3 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/faber.c @@ -0,0 +1,147 @@ +for (int c0 = 0; c0 <= 36; c0 += 1) { + for (int c1 = -6; c1 < c0 / 14 - 5; c1 += 1) { + for (int c2 = -((-2 * c1 + 3) / 5) + 9; c2 <= c1 + 12; c2 += 1) + S6(c0, c1, c2); + for (int c2 = c1 + 24; c2 <= -2 * c1 + 24; c2 += 1) + S2(c0, c1, c2); + for (int c2 = -2 * c1 + 30; c2 <= c1 + 48; c2 += 1) + S1(c0, c1, c2); + } + for (int c1 = c0 / 14 - 5; c1 < 0; c1 += 1) { + if (c1 >= -3 && 2 * c0 >= 7 * c1 + 42) + S7(c0, c1, 6); + for (int c2 = max(c1 - (6 * c0 + 77) / 77 + 13, -((-2 * c1 + 3) / 5) + 9); c2 <= c1 + 12; c2 += 1) + S6(c0, c1, c2); + for (int c2 = c1 - (3 * c0 + 14) / 14 + 49; c2 <= c1 + 48; c2 += 1) + S1(c0, c1, c2); + } + S3(c0, 0, 0); + S10(c0, 0, 0); + for (int c2 = 1; c2 <= 5; c2 += 1) + S3(c0, 0, c2); + for (int c2 = 6; c2 <= 2 * c0 / 21 + 4; c2 += 1) { + S3(c0, 0, c2); + S7(c0, 0, c2); + } + for (int c2 = max(6, 2 * c0 / 21 + 5); c2 <= -((6 * c0 + 77) / 77) + 12; c2 += 1) + S3(c0, 0, c2); + for (int c2 = -((6 * c0 + 77) / 77) + 13; c2 <= 12; c2 += 1) { + S3(c0, 0, c2); + S6(c0, 0, c2); + } + for (int c2 = 13; c2 <= 24; c2 += 1) + S3(c0, 0, c2); + for (int c2 = -((3 * c0 + 14) / 14) + 49; c2 <= 48; c2 += 1) + S1(c0, 0, c2); + for (int c1 = 1; c1 <= 18; c1 += 1) { + for (int c2 = -8 * c1; c2 <= min(6, -8 * c1 + 24); c2 += 1) + S3(c0, c1, c2); + if (c0 <= 34 && c1 == 1) { + S3(c0, 1, 7); + } else if (c1 == 2) { + S3(c0, 2, 7); + } else if (c0 >= 35 && c1 == 1) { + S3(c0, 1, 7); + S7(c0, 1, 7); + } + for (int c2 = 8; c2 <= min(-8 * c1 + 24, c1 - (6 * c0 + 77) / 77 + 12); c2 += 1) + S3(c0, c1, c2); + if (c1 == 1) { + for (int c2 = -((6 * c0 + 77) / 77) + 14; c2 <= 13; c2 += 1) { + S3(c0, 1, c2); + S6(c0, 1, c2); + } + for (int c2 = 14; c2 <= 16; c2 += 1) + S3(c0, 1, c2); + } + for (int c2 = max(-8 * c1 + 25, c1 - (6 * c0 + 77) / 77 + 13); c2 <= c1 + 12; c2 += 1) + S6(c0, c1, c2); + for (int c2 = c1 - (3 * c0 + 14) / 14 + 49; c2 <= c1 + 48; c2 += 1) + S1(c0, c1, c2); + } + for (int c1 = 19; c1 <= 24; c1 += 1) { + for (int c2 = -8 * c1; c2 <= -8 * c1 + 24; c2 += 1) + S3(c0, c1, c2); + for (int c2 = c1 - (6 * c0 + 77) / 77 + 13; c2 <= 30; c2 += 1) + S6(c0, c1, c2); + } +} +for (int c0 = 37; c0 <= 218; c0 += 1) { + for (int c1 = (c0 + 5) / 14 - 8; c1 < min(0, c0 / 14 - 5); c1 += 1) { + if (c0 <= 46 && c1 == -3) + S7(c0, -3, 6); + if (77 * c1 + 77 * ((-2 * c1 - 2) / 5) + 524 >= 6 * c0) + S6(c0, c1, -((-2 * c1 + 3) / 5) + 9); + for (int c2 = c1 + 24; c2 <= -2 * c1 + 24; c2 += 1) + S2(c0, c1, c2); + for (int c2 = -2 * c1 + 30; c2 <= c1 - (3 * c0 + 17) / 14 + 56; c2 += 1) + S1(c0, c1, c2); + } + if (c0 <= 148) + for (int c1 = max(0, (c0 + 5) / 14 - 8); c1 < c0 / 14 - 5; c1 += 1) { + if (c1 == 0) + S2(c0, 0, 24); + for (int c2 = max(c1 + 24, -2 * c1 + 30); c2 <= c1 - (3 * c0 + 17) / 14 + 56; c2 += 1) + S1(c0, c1, c2); + } + if (c0 >= 70 && c0 % 14 >= 9) + for (int c2 = max((c0 + 5) / 14 + 18, -((3 * c0 + 14) / 14) + c0 / 14 + 44); c2 <= -((3 * c0 + 17) / 14) + c0 / 14 + 51; c2 += 1) + S1(c0, c0 / 14 - 5, c2); + for (int c1 = c0 / 14 - 5; c1 < 0; c1 += 1) { + if (7 * c1 + 114 >= 2 * c0) + S7(c0, c1, 6); + for (int c2 = max(8, c1 - (6 * c0 + 77) / 77 + 13); c2 <= c1 - (6 * c0 + 91) / 77 + 15; c2 += 1) + S6(c0, c1, c2); + for (int c2 = c1 - (3 * c0 + 14) / 14 + 49; c2 <= c1 - (3 * c0 + 17) / 14 + 56; c2 += 1) + S1(c0, c1, c2); + } + for (int c1 = max(0, (c0 + 5) / 14 - 5); c1 < c0 / 14 - 2; c1 += 1) { + for (int c2 = max(c1, -2 * c1 + 6); c2 <= min(c1 + 5, -2 * c1 + 24); c2 += 1) + S9(c0, c1, c2); + for (int c2 = c1 + 6; c2 <= min((2 * c1 + 1) / 5 + 7, (2 * c0 - 7 * c1 - 10) / 21 + 1); c2 += 1) + S9(c0, c1, c2); + for (int c2 = max(c1 + 6, (2 * c0 - 7 * c1 - 10) / 21 + 2); c2 <= (2 * c1 + 1) / 5 + 7; c2 += 1) { + S7(c0, c1, c2); + S9(c0, c1, c2); + } + if (c1 <= 3) + S9(c0, c1, (2 * c1 + 1) / 5 + 8); + for (int c2 = (2 * c1 + 1) / 5 + 9; c2 <= c1 - (6 * c0 + 91) / 77 + 15; c2 += 1) { + S6(c0, c1, c2); + S9(c0, c1, c2); + } + for (int c2 = max(max(c1 + 6, c1 - (6 * c0 + 91) / 77 + 16), (2 * c1 + 1) / 5 + 9); c2 <= -2 * c1 + 24; c2 += 1) + S9(c0, c1, c2); + for (int c2 = max(c1, -2 * c1 + 30); c2 <= min(c1 + 24, c1 - (3 * c0 + 17) / 14 + 47); c2 += 1) + S8(c0, c1, c2); + for (int c2 = max(c1 + 24, c1 - (3 * c0 + 14) / 14 + 49); c2 <= c1 - (3 * c0 + 17) / 14 + 56; c2 += 1) + S1(c0, c1, c2); + } + for (int c1 = c0 / 14 - 2; c1 <= 18; c1 += 1) { + for (int c2 = max(6, (c0 + 5) / 14 + 1); c2 <= min(min(c1, c0 / 14 + 3), -c1 + c1 / 2 + 18); c2 += 1) + S5(c0, c1, c2); + for (int c2 = max(c1 + (3 * c0 + 3) / 14 - 40, -c1 + (c1 + 1) / 2 + 21); c2 <= min(c1, c1 + 3 * c0 / 14 - 33); c2 += 1) + S4(c0, c1, c2); + for (int c2 = c1 + 6; c2 <= min((2 * c1 + 1) / 5 + 7, (2 * c0 - 7 * c1 + 63) / 21 + 1); c2 += 1) + S7(c0, c1, c2); + for (int c2 = max(max(c1 + 6, c1 - (6 * c0 + 77) / 77 + 13), (2 * c1 + 1) / 5 + 9); c2 <= c1 - (6 * c0 + 91) / 77 + 15; c2 += 1) + S6(c0, c1, c2); + for (int c2 = max(c1, c1 - (3 * c0 + 14) / 14 + 40); c2 <= min(c1 + 24, c1 - (3 * c0 + 17) / 14 + 47); c2 += 1) + S8(c0, c1, c2); + for (int c2 = max(c1 + 24, c1 - (3 * c0 + 14) / 14 + 49); c2 <= c1 - (3 * c0 + 17) / 14 + 56; c2 += 1) + S1(c0, c1, c2); + } + for (int c1 = 19; c1 <= 24; c1 += 1) { + for (int c2 = max(c1 - 12, (c0 + 5) / 14 + 1); c2 <= min(c0 / 14 + 3, -c1 + c1 / 2 + 18); c2 += 1) + S5(c0, c1, c2); + for (int c2 = max(max(c1 - 12, c1 + (3 * c0 + 3) / 14 - 40), -c1 + (c1 + 1) / 2 + 21); c2 <= min(c1, c1 + 3 * c0 / 14 - 33); c2 += 1) + S4(c0, c1, c2); + for (int c2 = max(c1 + 6, c1 - (6 * c0 + 77) / 77 + 13); c2 <= min(30, c1 - (6 * c0 + 91) / 77 + 15); c2 += 1) + S6(c0, c1, c2); + for (int c2 = max(c1, c1 - (3 * c0 + 14) / 14 + 40); c2 <= min(c1 + 24, c1 - (3 * c0 + 17) / 14 + 47); c2 += 1) + S8(c0, c1, c2); + } + for (int c1 = 25; c1 <= min(42, -((3 * c0 + 17) / 14) + 71); c1 += 1) + for (int c2 = max(c1 - 12, c1 + (3 * c0 + 3) / 14 - 40); c2 <= min(min(30, c1), c1 + 3 * c0 / 14 - 33); c2 += 1) + S4(c0, c1, c2); +} diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/faber.st b/external/mit/isl/dist/test_inputs/codegen/cloog/faber.st new file mode 100644 index 000000000000..f80089464920 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/faber.st @@ -0,0 +1,18 @@ +domain: "{ S2[idx4, idx5, idx6] : 14idx5 <= -84 + idx4 and 14idx5 >= -120 + idx4 and idx6 >= 24 + idx5 and idx6 <= 48 + idx5 and idx5 >= -6 and idx5 <= 18 and idx6 <= 24 - 2idx5; S4[idx4, idx5, idx6] : 14idx6 <= -462 + 3idx4 + 14idx5 and 14idx6 >= -570 + 3idx4 + 14idx5 and idx6 <= idx5 and idx6 >= -12 + idx5 and idx6 >= 6 and idx6 <= 30 and 2idx6 >= 42 - idx5; S6[idx4, idx5, idx6] : 77idx6 >= 924 - 6idx4 + 77idx5 and 77idx6 <= 1140 - 6idx4 + 77idx5 and idx6 <= 12 + idx5 and idx6 >= 6 + idx5 and idx6 >= 6 and idx6 <= 30 and 5idx6 >= 42 + 2idx5; S1[idx4, idx5, idx6] : 14idx6 >= 672 - 3idx4 + 14idx5 and 14idx6 <= 780 - 3idx4 + 14idx5 and idx6 >= 24 + idx5 and idx6 <= 48 + idx5 and idx5 >= -6 and idx5 <= 18 and idx6 >= 30 - 2idx5; S5[idx4, idx5, idx6] : 14idx6 <= 42 + idx4 and 14idx6 >= 6 + idx4 and idx6 <= idx5 and idx6 >= -12 + idx5 and idx6 >= 6 and idx6 <= 30 and 2idx6 <= 36 - idx5; S7[idx4, idx5, idx6] : 21idx6 <= 84 + 2idx4 - 7idx5 and 21idx6 >= 12 + 2idx4 - 7idx5 and idx6 <= 12 + idx5 and idx6 >= 6 + idx5 and idx6 >= 6 and idx6 <= 30 and 5idx6 <= 36 + 2idx5; S8[idx4, idx5, idx6] : 14idx6 >= 546 - 3idx4 + 14idx5 and 14idx6 <= 654 - 3idx4 + 14idx5 and idx6 >= idx5 and idx6 <= 24 + idx5 and idx5 >= 0 and idx5 <= 24 and idx6 >= 30 - 2idx5; S3[idx4, idx5, idx6] : idx4 >= 0 and idx4 <= 36 and idx6 >= -8idx5 and idx6 <= 24 - 8idx5 and idx5 >= 0 and idx5 <= 24; S9[idx4, idx5, idx6] : 14idx5 <= -42 + idx4 and 14idx5 >= -78 + idx4 and idx6 >= idx5 and idx6 <= 24 + idx5 and idx5 >= 0 and idx5 <= 24 and idx6 <= 24 - 2idx5 and idx6 >= 6 - 2idx5; S10[idx4, idx5, idx6] : 7idx6 <= idx4 - 28idx5 and 7idx6 >= -36 + idx4 - 28idx5 and idx6 >= idx5 and idx6 <= 24 + idx5 and idx5 >= 0 and idx5 <= 24 and idx6 <= -2idx5 }" +child: + context: "{ [] }" + child: + schedule: "[{ S6[idx4, idx5, idx6] -> [(idx4)]; S8[idx4, idx5, idx6] -> [(idx4)]; S5[idx4, idx5, idx6] -> [(idx4)]; S9[idx4, idx5, idx6] -> [(idx4)]; S4[idx4, idx5, idx6] -> [(idx4)]; S10[idx4, idx5, idx6] -> [(idx4)]; S7[idx4, idx5, idx6] -> [(idx4)]; S3[idx4, idx5, idx6] -> [(idx4)]; S1[idx4, idx5, idx6] -> [(idx4)]; S2[idx4, idx5, idx6] -> [(idx4)] }, { S6[idx4, idx5, idx6] -> [(idx5)]; S8[idx4, idx5, idx6] -> [(idx5)]; S5[idx4, idx5, idx6] -> [(idx5)]; S9[idx4, idx5, idx6] -> [(idx5)]; S4[idx4, idx5, idx6] -> [(idx5)]; S10[idx4, idx5, idx6] -> [(idx5)]; S7[idx4, idx5, idx6] -> [(idx5)]; S3[idx4, idx5, idx6] -> [(idx5)]; S1[idx4, idx5, idx6] -> [(idx5)]; S2[idx4, idx5, idx6] -> [(idx5)] }, { S6[idx4, idx5, idx6] -> [(idx6)]; S8[idx4, idx5, idx6] -> [(idx6)]; S5[idx4, idx5, idx6] -> [(idx6)]; S9[idx4, idx5, idx6] -> [(idx6)]; S4[idx4, idx5, idx6] -> [(idx6)]; S10[idx4, idx5, idx6] -> [(idx6)]; S7[idx4, idx5, idx6] -> [(idx6)]; S3[idx4, idx5, idx6] -> [(idx6)]; S1[idx4, idx5, idx6] -> [(idx6)]; S2[idx4, idx5, idx6] -> [(idx6)] }]" + options: "{ separate[i0] }" + child: + sequence: + - filter: "{ S1[idx4, idx5, idx6] }" + - filter: "{ S2[idx4, idx5, idx6] }" + - filter: "{ S3[idx4, idx5, idx6] }" + - filter: "{ S4[idx4, idx5, idx6] }" + - filter: "{ S5[idx4, idx5, idx6] }" + - filter: "{ S6[idx4, idx5, idx6] }" + - filter: "{ S7[idx4, idx5, idx6] }" + - filter: "{ S8[idx4, idx5, idx6] }" + - filter: "{ S9[idx4, idx5, idx6] }" + - filter: "{ S10[idx4, idx5, idx6] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/forwardsub-1-1-2.c b/external/mit/isl/dist/test_inputs/codegen/cloog/forwardsub-1-1-2.c new file mode 100644 index 000000000000..f3fa9f8ac60c --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/forwardsub-1-1-2.c @@ -0,0 +1,7 @@ +S3(1, 1); +for (int c0 = 2; c0 <= M; c0 += 1) { + S1(c0, 1); + for (int c1 = 2; c1 < c0; c1 += 1) + S2(c0, c1); + S4(c0, c0); +} diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/forwardsub-1-1-2.st b/external/mit/isl/dist/test_inputs/codegen/cloog/forwardsub-1-1-2.st new file mode 100644 index 000000000000..152e6b00a7e6 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/forwardsub-1-1-2.st @@ -0,0 +1,12 @@ +domain: "[M] -> { S4[i0, i0] : M >= 3 and i0 <= M and i0 >= 2; S1[i0, 1] : M >= 3 and i0 <= M and i0 >= 2; S3[1, 1] : M >= 3; S2[i0, i1] : i1 <= -1 + i0 and i1 >= 2 and i0 <= M }" +child: + context: "[M] -> { [] : M >= 3 }" + child: + schedule: "[M] -> [{ S1[i0, i1] -> [(i0)]; S4[i0, i1] -> [(i0)]; S3[i0, i1] -> [(i0)]; S2[i0, i1] -> [(i0)] }, { S1[i0, i1] -> [(i1)]; S4[i0, i1] -> [(i1)]; S3[i0, i1] -> [(i1)]; S2[i0, i1] -> [(i1)] }]" + options: "[M] -> { separate[i0] }" + child: + sequence: + - filter: "[M] -> { S1[i0, i1] }" + - filter: "[M] -> { S2[i0, i1] }" + - filter: "[M] -> { S3[i0, i1] }" + - filter: "[M] -> { S4[i0, i1] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/forwardsub-2-1-2-3.c b/external/mit/isl/dist/test_inputs/codegen/cloog/forwardsub-2-1-2-3.c new file mode 100644 index 000000000000..d6ee40e56c4e --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/forwardsub-2-1-2-3.c @@ -0,0 +1,8 @@ +S3(1, 0); +for (int c2 = 2; c2 <= M; c2 += 1) + S1(1, 1, c2); +for (int c0 = 2; c0 <= M; c0 += 1) { + S4(c0, 0); + for (int c2 = c0 + 1; c2 <= M; c2 += 1) + S2(c0, 1, c2); +} diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/forwardsub-2-1-2-3.st b/external/mit/isl/dist/test_inputs/codegen/cloog/forwardsub-2-1-2-3.st new file mode 100644 index 000000000000..76f08315cbac --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/forwardsub-2-1-2-3.st @@ -0,0 +1,12 @@ +domain: "[M] -> { S4[i0, 0] : i0 >= 2 and M >= 3 and i0 <= M; S3[1, 0] : M >= 3; S2[i0, 1, i2] : i2 >= 1 + i0 and i0 >= 2 and i2 <= M; S1[1, 1, i2] : M >= 3 and i2 <= M and i2 >= 2 }" +child: + context: "[M] -> { [] : M >= 3 }" + child: + schedule: "[M] -> [{ S1[i0, i1, i2] -> [(i0)]; S4[i0, i1] -> [(i0)]; S3[i0, i1] -> [(i0)]; S2[i0, i1, i2] -> [(i0)] }, { S1[i0, i1, i2] -> [(i1)]; S4[i0, i1] -> [(i1)]; S3[i0, i1] -> [(i1)]; S2[i0, i1, i2] -> [(i1)] }, { S1[i0, i1, i2] -> [(i2)]; S4[i0, i1] -> [(0)]; S3[i0, i1] -> [(0)]; S2[i0, i1, i2] -> [(i2)] }]" + options: "[M] -> { separate[i0] }" + child: + sequence: + - filter: "[M] -> { S1[i0, i1, i2] }" + - filter: "[M] -> { S2[i0, i1, i2] }" + - filter: "[M] -> { S3[i0, i1] }" + - filter: "[M] -> { S4[i0, i1] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/forwardsub-3-1-2.c b/external/mit/isl/dist/test_inputs/codegen/cloog/forwardsub-3-1-2.c new file mode 100644 index 000000000000..898f6de4c2bc --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/forwardsub-3-1-2.c @@ -0,0 +1,15 @@ +S3(2, 1); +S1(3, 1); +for (int c0 = 4; c0 <= M + 1; c0 += 1) { + S1(c0, 1); + for (int c1 = 2; c1 < (c0 + 1) / 2; c1 += 1) + S2(c0, c1); + if (c0 % 2 == 0) + S4(c0, c0 / 2); +} +for (int c0 = M + 2; c0 <= 2 * M; c0 += 1) { + for (int c1 = -M + c0; c1 < (c0 + 1) / 2; c1 += 1) + S2(c0, c1); + if (c0 % 2 == 0) + S4(c0, c0 / 2); +} diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/forwardsub-3-1-2.st b/external/mit/isl/dist/test_inputs/codegen/cloog/forwardsub-3-1-2.st new file mode 100644 index 000000000000..35677b4e64fe --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/forwardsub-3-1-2.st @@ -0,0 +1,12 @@ +domain: "[M] -> { S4[i0, i1] : 2i1 = i0 and M >= 3 and i0 <= 2M and i0 >= 4; S1[i0, 1] : M >= 3 and i0 <= 1 + M and i0 >= 3; S3[2, 1] : M >= 3; S2[i0, i1] : 2i1 <= -1 + i0 and i1 >= 2 and i1 >= -M + i0 }" +child: + context: "[M] -> { [] : M >= 3 }" + child: + schedule: "[M] -> [{ S1[i0, i1] -> [(i0)]; S4[i0, i1] -> [(i0)]; S3[i0, i1] -> [(i0)]; S2[i0, i1] -> [(i0)] }, { S1[i0, i1] -> [(i1)]; S4[i0, i1] -> [(i1)]; S3[i0, i1] -> [(i1)]; S2[i0, i1] -> [(i1)] }]" + options: "[M] -> { separate[i0] }" + child: + sequence: + - filter: "[M] -> { S1[i0, i1] }" + - filter: "[M] -> { S2[i0, i1] }" + - filter: "[M] -> { S3[i0, i1] }" + - filter: "[M] -> { S4[i0, i1] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/gauss.c b/external/mit/isl/dist/test_inputs/codegen/cloog/gauss.c new file mode 100644 index 000000000000..4bbe42cb500a --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/gauss.c @@ -0,0 +1,7 @@ +for (int c0 = 1; c0 < M; c0 += 1) + for (int c1 = c0 + 1; c1 <= M; c1 += 1) { + for (int c3 = 1; c3 < c0; c3 += 1) + S1(c0, c3, c1); + for (int c3 = c0 + 1; c3 <= M; c3 += 1) + S2(c0, c3, c1); + } diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/gauss.st b/external/mit/isl/dist/test_inputs/codegen/cloog/gauss.st new file mode 100644 index 000000000000..7173a4cdded3 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/gauss.st @@ -0,0 +1,6 @@ +domain: "[M] -> { S2[i0, i1, i2] : i0 >= 1 and i0 <= M and i1 >= 1 + i0 and i1 <= M and i2 >= 1 + i0 and i2 <= M; S1[i0, i1, i2] : i0 >= 1 and i0 <= M and i1 >= 1 and i1 <= -1 + i0 and i2 >= 1 + i0 and i2 <= M }" +child: + context: "[M] -> { [] }" + child: + schedule: "[M] -> [{ S1[i0, i1, i2] -> [(i0)]; S2[i0, i1, i2] -> [(i0)] }, { S1[i0, i1, i2] -> [(i2)]; S2[i0, i1, i2] -> [(i2)] }]" + options: "[M] -> { separate[i0] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/gesced.c b/external/mit/isl/dist/test_inputs/codegen/cloog/gesced.c new file mode 100644 index 000000000000..2eb44edf77b8 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/gesced.c @@ -0,0 +1,14 @@ +for (int c0 = 1; c0 <= N; c0 += 1) + S1(c0); +for (int c0 = N + 1; c0 <= 2 * N; c0 += 1) + for (int c1 = 1; c1 <= N; c1 += 1) + S2(c1, -N + c0); +for (int c0 = 2 * N + 1; c0 <= M + N; c0 += 1) { + for (int c1 = 1; c1 <= N; c1 += 1) + S3(c1, -2 * N + c0); + for (int c1 = 1; c1 <= N; c1 += 1) + S2(c1, -N + c0); +} +for (int c0 = M + N + 1; c0 <= M + 2 * N; c0 += 1) + for (int c1 = 1; c1 <= N; c1 += 1) + S3(c1, -2 * N + c0); diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/gesced.st b/external/mit/isl/dist/test_inputs/codegen/cloog/gesced.st new file mode 100644 index 000000000000..3534f754bc2b --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/gesced.st @@ -0,0 +1,6 @@ +domain: "[M, N] -> { S3[i0, i1] : i0 >= 1 and i0 <= N and i1 >= 1 and i1 <= M; S1[i0] : i0 >= 1 and i0 <= N; S2[i0, i1] : i0 >= 1 and i0 <= N and i1 >= 1 and i1 <= M }" +child: + context: "[M, N] -> { [] : N <= M and M >= 2 and N >= 2 }" + child: + schedule: "[M, N] -> [{ S2[i0, i1] -> [(N + i1)]; S3[i0, i1] -> [(2N + i1)]; S1[i0] -> [(i0)] }]" + options: "[M, N] -> { separate[i0] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/gesced2.c b/external/mit/isl/dist/test_inputs/codegen/cloog/gesced2.c new file mode 100644 index 000000000000..fea430752199 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/gesced2.c @@ -0,0 +1,18 @@ +for (int c0 = 1; c0 <= 4; c0 += 1) + for (int c1 = 5; c1 < M - 9; c1 += 1) + S1(c0, c1); +for (int c0 = 5; c0 < M - 9; c0 += 1) { + for (int c1 = -c0 + 1; c1 <= 4; c1 += 1) + S2(c0 + c1, c0); + for (int c1 = 5; c1 <= min(M - 10, M - c0); c1 += 1) { + S2(c0 + c1, c0); + S1(c0, c1); + } + for (int c1 = M - c0 + 1; c1 < M - 9; c1 += 1) + S1(c0, c1); + for (int c1 = M - 9; c1 <= M - c0; c1 += 1) + S2(c0 + c1, c0); +} +for (int c0 = M - 9; c0 <= M; c0 += 1) + for (int c1 = 5; c1 < M - 9; c1 += 1) + S1(c0, c1); diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/gesced2.st b/external/mit/isl/dist/test_inputs/codegen/cloog/gesced2.st new file mode 100644 index 000000000000..c5f41bf14347 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/gesced2.st @@ -0,0 +1,6 @@ +domain: "[M] -> { S1[i0, i1] : i0 >= 1 and i0 <= M and i1 >= 5 and i1 <= -10 + M; S2[i0, i1] : i0 >= 1 and i0 <= M and i1 >= 5 and i1 <= -10 + M }" +child: + context: "[M] -> { [] : M >= 16 }" + child: + schedule: "[M] -> [{ S1[i0, i1] -> [(i0)]; S2[i0, i1] -> [(i1)] }, { S1[i0, i1] -> [(i1)]; S2[i0, i1] -> [(i0 - i1)] }]" + options: "[M] -> { separate[i0] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/gesced3.c b/external/mit/isl/dist/test_inputs/codegen/cloog/gesced3.c new file mode 100644 index 000000000000..86e4a5e2d44c --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/gesced3.c @@ -0,0 +1,8 @@ +for (int c0 = M + 1; c0 <= 2 * M; c0 += 1) + S1(-M + c0); +for (int c0 = 2 * M + 1; c0 <= M + N; c0 += 1) { + S1(-M + c0); + S2(-2 * M + c0); +} +for (int c0 = M + N + 1; c0 <= 2 * M + N; c0 += 1) + S2(-2 * M + c0); diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/gesced3.st b/external/mit/isl/dist/test_inputs/codegen/cloog/gesced3.st new file mode 100644 index 000000000000..cb0a28531f11 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/gesced3.st @@ -0,0 +1,6 @@ +domain: "[M, N] -> { S1[i0] : i0 >= 1 and i0 <= N; S2[i0] : i0 >= 1 and i0 <= N }" +child: + context: "[M, N] -> { [] : N >= M and M >= 2 }" + child: + schedule: "[M, N] -> [{ S2[i0] -> [(2M + i0)]; S1[i0] -> [(M + i0)] }]" + options: "[M, N] -> { separate[i0] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/guide.c b/external/mit/isl/dist/test_inputs/codegen/cloog/guide.c new file mode 100644 index 000000000000..688c7d6b90d7 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/guide.c @@ -0,0 +1,4 @@ +for (int c0 = 1; c0 <= N; c0 += 1) + S1(c0); +for (int c0 = N + 1; c0 <= 2 * N; c0 += 1) + S2(c0); diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/guide.st b/external/mit/isl/dist/test_inputs/codegen/cloog/guide.st new file mode 100644 index 000000000000..3ca5c6eca272 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/guide.st @@ -0,0 +1,10 @@ +domain: "[M, N] -> { S1[i0] : (i0 >= 1 and i0 <= N and i0 <= 2M) or (i0 >= M and i0 >= 1 and i0 <= N); S2[i0] : i0 >= 1 + N and i0 <= 2N }" +child: + context: "[M, N] -> { [] }" + child: + schedule: "[M, N] -> [{ S2[i0] -> [(i0)]; S1[i0] -> [(i0)] }]" + options: "[M, N] -> { separate[i0] }" + child: + sequence: + - filter: "[M, N] -> { S1[i0] }" + - filter: "[M, N] -> { S2[i0] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/iftest.c b/external/mit/isl/dist/test_inputs/codegen/cloog/iftest.c new file mode 100644 index 000000000000..0f41fb7902a4 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/iftest.c @@ -0,0 +1,2 @@ +for (int c0 = 1; c0 <= n; c0 += 1) + S1(c0); diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/iftest.st b/external/mit/isl/dist/test_inputs/codegen/cloog/iftest.st new file mode 100644 index 000000000000..cd26fab47b3e --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/iftest.st @@ -0,0 +1,6 @@ +domain: "[m, n] -> { S1[i0] : (i0 >= m and i0 >= 1 and i0 <= n) or (i0 >= 1 and i0 <= n and i0 <= 2m) }" +child: + context: "[m, n] -> { [] }" + child: + schedule: "[m, n] -> [{ S1[i0] -> [(i0)] }]" + options: "[m, n] -> { separate[i0] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/iftest2.c b/external/mit/isl/dist/test_inputs/codegen/cloog/iftest2.c new file mode 100644 index 000000000000..8e3e4c1b90bb --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/iftest2.c @@ -0,0 +1,3 @@ +for (int c0 = 1; c0 <= N; c0 += 1) + for (int c1 = 1; c1 <= M; c1 += 1) + S1(c0, c1); diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/iftest2.st b/external/mit/isl/dist/test_inputs/codegen/cloog/iftest2.st new file mode 100644 index 000000000000..f073f5cf5f49 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/iftest2.st @@ -0,0 +1,6 @@ +domain: "[M, N] -> { S1[i0, i1] : (i0 >= M and i0 <= N and i1 >= 1 and i1 <= M) or (i0 >= 1 and i0 <= N and i0 <= 2M and i1 >= 1 and i1 <= M) }" +child: + context: "[M, N] -> { [] }" + child: + schedule: "[M, N] -> [{ S1[i0, i1] -> [(i0)] }, { S1[i0, i1] -> [(i1)] }]" + options: "[M, N] -> { separate[i0] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/infinite2.c b/external/mit/isl/dist/test_inputs/codegen/cloog/infinite2.c new file mode 100644 index 000000000000..8850909a9ae1 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/infinite2.c @@ -0,0 +1,7 @@ +for (int c0 = 1; c0 <= N; c0 += 1) { + S1(c0); + for (int c1 = 1; c1 <= M; c1 += 1) + S2(c0, c1); +} +for (int c0 = N + 1; 1; c0 += 1) + S1(c0); diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/infinite2.st b/external/mit/isl/dist/test_inputs/codegen/cloog/infinite2.st new file mode 100644 index 000000000000..7bd85d37770d --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/infinite2.st @@ -0,0 +1,10 @@ +domain: "[M, N] -> { S1[i0] : i0 >= 1; S2[i0, i1] : i0 >= 1 and i0 <= N and i1 >= 1 and i1 <= M }" +child: + context: "[M, N] -> { [] : M >= 1 and N >= 1 }" + child: + schedule: "[M, N] -> [{ S2[i0, i1] -> [(i0)]; S1[i0] -> [(i0)] }, { S2[i0, i1] -> [(i1)]; S1[i0] -> [(0)] }]" + options: "[M, N] -> { separate[i0] }" + child: + sequence: + - filter: "[M, N] -> { S1[i0] }" + - filter: "[M, N] -> { S2[i0, i1] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/jacobi-shared.c b/external/mit/isl/dist/test_inputs/codegen/cloog/jacobi-shared.c new file mode 100644 index 000000000000..bf7093297424 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/jacobi-shared.c @@ -0,0 +1,3 @@ +if (((t1 + 31) % 32) + g2 >= 2 && N >= ((t1 + 31) % 32) + g2 + 2 && (h0 + 1) % 2 == 0) + for (int c0 = max(((t0 + 15) % 16) + 1, ((g1 + t0 + 13) % 16) - g1 + 3); c0 <= min(32, N - g1 - 1); c0 += 16) + S1(g1 + c0 - 1, -((g2 - t1 + 32) % 32) + g2 + 31); diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/jacobi-shared.st b/external/mit/isl/dist/test_inputs/codegen/cloog/jacobi-shared.st new file mode 100644 index 000000000000..73f5dd8730ef --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/jacobi-shared.st @@ -0,0 +1,6 @@ +domain: "[T, N, h0, b0, b1, g0, g1, g2, g3, g4, t0, t1] -> { S1[i0, i1] : exists (e0 = floor((-1 + h0)/2), e1 = floor((-32b0 + g1)/2048), e2 = floor((-32b1 + g2)/1024), e3 = floor((-15 - t0 + i0)/16), e4 = floor((-31 - t1 + i1)/32): g0 = h0 and 2e0 = -1 + h0 and 2048e1 = -32b0 + g1 and 1024e2 = -32b1 + g2 and 16e3 = -15 - t0 + i0 and 32e4 = -31 - t1 + i1 and h0 >= 1 and h0 <= -1 + 2T and i0 >= 2 and i0 <= -2 + N and i1 >= 2 and i1 <= -2 + N and b1 <= 31 and b1 >= 0 and b0 <= 63 and b0 >= 0 and i1 <= 31 + g2 and i1 >= g2 and N >= 4 and i0 >= g1 and i0 <= 31 + g1 and g2 <= -2 + N and g2 >= -29 and g1 <= -2 + N and g1 >= -29 and g1 >= 32b0 and g2 >= 32b1 and 32b0 <= -2 + N and 32b1 <= -2 + N and t0 >= 0 and t0 <= 15 and t1 >= 0 and t1 <= 31) }" +child: + context: "[T, N, h0, b0, b1, g0, g1, g2, g3, g4, t0, t1] -> { [] : exists (e0 = floor((-32b0 + g1)/2048), e1 = floor((-32b1 + g2)/1024): g0 = h0 and 2048e0 = -32b0 + g1 and 1024e1 = -32b1 + g2 and g2 <= -2 + N and g2 >= -29 and g1 <= -2 + N and g1 >= -29 and b1 >= 0 and b1 <= 31 and b0 <= 63 and 32b1 <= -2 + N and 32b0 <= -2 + N and b0 >= 0 and N >= 4 and h0 >= 0 and h0 <= -1 + 2T and g2 >= 32b1 and g1 >= 32b0 and t0 >= 0 and t0 <= 15 and t1 >= 0 and t1 <= 31) }" + child: + schedule: "[T, N, h0, b0, b1, g0, g1, g2, g3, g4, t0, t1] -> [{ S1[i0, i1] -> [(1 - g1 + i0)] }, { S1[i0, i1] -> [(1 - g2 + i1)] }, { S1[i0, i1] -> [(t0)] }, { S1[i0, i1] -> [(t1)] }]" + options: "[T, N, h0, b0, b1, g0, g1, g2, g3, g4, t0, t1] -> { separate[x] : x >= 3 }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/largeur.c b/external/mit/isl/dist/test_inputs/codegen/cloog/largeur.c new file mode 100644 index 000000000000..faced0a55735 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/largeur.c @@ -0,0 +1,3 @@ +for (int c0 = 1; c0 <= M; c0 += 1) + for (int c1 = 1; c1 <= c0; c1 += 1) + S1(c1, c0); diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/largeur.st b/external/mit/isl/dist/test_inputs/codegen/cloog/largeur.st new file mode 100644 index 000000000000..bb29f2186aa2 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/largeur.st @@ -0,0 +1,6 @@ +domain: "[M] -> { S1[i0, i1] : i0 >= 1 and i0 <= M and i1 >= i0 and i1 <= M }" +child: + context: "[M] -> { [] : M >= 0 }" + child: + schedule: "[M] -> [{ S1[i0, i1] -> [(i1)] }, { S1[i0, i1] -> [(i0)] }]" + options: "[M] -> { separate[i0] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/levenshtein-1-2-3.c b/external/mit/isl/dist/test_inputs/codegen/cloog/levenshtein-1-2-3.c new file mode 100644 index 000000000000..0b645877109d --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/levenshtein-1-2-3.c @@ -0,0 +1,30 @@ +S1(0, 0); +for (int c0 = 1; c0 <= N; c0 += 1) { + S2(c0, 0); + for (int c1 = 1; c1 < c0; c1 += 1) + S6(c0, c1); + S3(c0, c0); +} +S7(N + 1, 0); +for (int c1 = 1; c1 <= N; c1 += 1) { + S6(N + 1, c1); + S8(N + 1, c1); +} +for (int c0 = N + 2; c0 < 2 * M - N - 1; c0 += 1) { + S7(c0, -N + (N + c0 + 1) / 2 - 1); + if ((N + c0) % 2 == 0) { + S5(c0, (-N + c0) / 2); + S8(c0, (-N + c0) / 2); + } + for (int c1 = -N + (N + c0) / 2 + 1; c1 < (N + c0 + 1) / 2; c1 += 1) { + S6(c0, c1); + S8(c0, c1); + } + if ((N + c0) % 2 == 0) { + S4(c0, (N + c0) / 2); + S8(c0, (N + c0) / 2); + } +} +for (int c0 = 2 * M - N - 1; c0 < 2 * M - 1; c0 += 1) + for (int c1 = -M + c0 + 1; c1 < M; c1 += 1) + S6(c0, c1); diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/levenshtein-1-2-3.st b/external/mit/isl/dist/test_inputs/codegen/cloog/levenshtein-1-2-3.st new file mode 100644 index 000000000000..9b1d7cbe6374 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/levenshtein-1-2-3.st @@ -0,0 +1,16 @@ +domain: "[M, N] -> { S5[i0, i1] : 2i1 = -N + i0 and i0 >= 2 + N and i0 <= -2 + 2M - N and N >= 1; S3[i0, i0] : i0 >= 1 and i0 <= N and N <= -2 + M; S7[i0, i1] : i0 >= 1 + N and 2i1 <= -1 - N + i0 and i0 <= -2 + 2M - N and 2i1 >= -2 - N + i0 and N <= -2 + M and N >= 1; S6[i0, i1] : 2i1 <= -1 + N + i0 and i1 <= -1 + i0 and i1 >= 1 - M + i0 and 2i1 >= 1 - N + i0 and i1 >= 1 and i1 <= -1 + M and N <= -2 + M; S1[0, 0] : N <= -2 + M and N >= 1; S2[i0, 0] : i0 >= 1 and i0 <= N and N <= -2 + M; S4[i0, i1] : 2i1 = N + i0 and i0 >= 2 + N and i0 <= -2 + 2M - N and N >= 1; S8[i0, i1] : i0 >= 1 + N and 2i1 <= N + i0 and 2i1 >= -N + i0 and i0 <= -2 + 2M - N and N <= -2 + M and N >= 1 }" +child: + context: "[M, N] -> { [] : N <= -2 + M and N >= 1 }" + child: + schedule: "[M, N] -> [{ S7[i0, i1] -> [(i0)]; S5[i0, i1] -> [(i0)]; S1[i0, i1] -> [(i0)]; S3[i0, i1] -> [(i0)]; S2[i0, i1] -> [(i0)]; S4[i0, i1] -> [(i0)]; S8[i0, i1] -> [(i0)]; S6[i0, i1] -> [(i0)] }, { S7[i0, i1] -> [(i1)]; S5[i0, i1] -> [(i1)]; S1[i0, i1] -> [(i1)]; S3[i0, i1] -> [(i1)]; S2[i0, i1] -> [(i1)]; S4[i0, i1] -> [(i1)]; S8[i0, i1] -> [(i1)]; S6[i0, i1] -> [(i1)] }]" + options: "[M, N] -> { separate[i0] }" + child: + sequence: + - filter: "[M, N] -> { S1[i0, i1] }" + - filter: "[M, N] -> { S2[i0, i1] }" + - filter: "[M, N] -> { S3[i0, i1] }" + - filter: "[M, N] -> { S4[i0, i1] }" + - filter: "[M, N] -> { S5[i0, i1] }" + - filter: "[M, N] -> { S6[i0, i1] }" + - filter: "[M, N] -> { S7[i0, i1] }" + - filter: "[M, N] -> { S8[i0, i1] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/lex.c b/external/mit/isl/dist/test_inputs/codegen/cloog/lex.c new file mode 100644 index 000000000000..e81e97e75a98 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/lex.c @@ -0,0 +1,4 @@ +for (int c0 = 0; c0 <= 10; c0 += 1) { + S2(c0); + S1(c0); +} diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/lex.st b/external/mit/isl/dist/test_inputs/codegen/cloog/lex.st new file mode 100644 index 000000000000..2d4d58df41ed --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/lex.st @@ -0,0 +1,10 @@ +domain: "{ S1[i0] : i0 >= 0 and i0 <= 10; S2[i0] : i0 >= 0 and i0 <= 10 }" +child: + context: "{ [] }" + child: + schedule: "[{ S2[i0] -> [(i0)]; S1[i0] -> [(i0)] }]" + options: "{ separate[i0] }" + child: + sequence: + - filter: "{ S2[i0] }" + - filter: "{ S1[i0] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/lineality-1-2.c b/external/mit/isl/dist/test_inputs/codegen/cloog/lineality-1-2.c new file mode 100644 index 000000000000..bb1e0718719f --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/lineality-1-2.c @@ -0,0 +1,8 @@ +for (int c0 = 1; c0 <= M; c0 += 1) { + for (int c1 = 1; c1 < c0; c1 += 1) + S1(c0, c1); + S1(c0, c0); + S2(c0, c0); + for (int c1 = c0 + 1; c1 <= M; c1 += 1) + S1(c0, c1); +} diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/lineality-1-2.st b/external/mit/isl/dist/test_inputs/codegen/cloog/lineality-1-2.st new file mode 100644 index 000000000000..0d079b5e8ff7 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/lineality-1-2.st @@ -0,0 +1,10 @@ +domain: "[M] -> { S1[i0, i1] : i0 >= 1 and i1 >= 1 and i0 <= M and i1 <= M; S2[i0, i0] : i0 >= 1 and i0 <= M }" +child: + context: "[M] -> { [] : M >= 2 }" + child: + schedule: "[M] -> [{ S1[i0, i1] -> [(i0)]; S2[i0, i1] -> [(i0)] }, { S1[i0, i1] -> [(i1)]; S2[i0, i1] -> [(i1)] }]" + options: "[M] -> { separate[i0] }" + child: + sequence: + - filter: "[M] -> { S1[i0, i1] }" + - filter: "[M] -> { S2[i0, i1] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/lineality-2-1-2.c b/external/mit/isl/dist/test_inputs/codegen/cloog/lineality-2-1-2.c new file mode 100644 index 000000000000..97a4b0452412 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/lineality-2-1-2.c @@ -0,0 +1,12 @@ +for (int c0 = 1; c0 <= M; c0 += 1) { + for (int c1 = 1; c1 <= min(M, c0 + 1); c1 += 1) + S1(c0, c1); + if (M >= c0 + 2) { + S1(c0, c0 + 2); + S2(c0, c0 + 2); + } + for (int c1 = c0 + 3; c1 <= M; c1 += 1) + S1(c0, c1); + if (c0 + 1 >= M) + S2(c0, c0 + 2); +} diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/lineality-2-1-2.st b/external/mit/isl/dist/test_inputs/codegen/cloog/lineality-2-1-2.st new file mode 100644 index 000000000000..dbadca75cee7 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/lineality-2-1-2.st @@ -0,0 +1,10 @@ +domain: "[M] -> { S1[i0, i1] : i0 >= 1 and i1 >= 1 and i0 <= M and i1 <= M; S2[i0, 2 + i0] : i0 >= 1 and i0 <= M }" +child: + context: "[M] -> { [] : M >= 2 }" + child: + schedule: "[M] -> [{ S1[i0, i1] -> [(i0)]; S2[i0, i1] -> [(i0)] }, { S1[i0, i1] -> [(i1)]; S2[i0, i1] -> [(i1)] }]" + options: "[M] -> { separate[i0] }" + child: + sequence: + - filter: "[M] -> { S1[i0, i1] }" + - filter: "[M] -> { S2[i0, i1] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/logo.c b/external/mit/isl/dist/test_inputs/codegen/cloog/logo.c new file mode 100644 index 000000000000..84e4a523965a --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/logo.c @@ -0,0 +1,15 @@ +for (int c1 = 0; c1 <= 7; c1 += 1) + S1(1, c1); +for (int c0 = 2; c0 <= 6; c0 += 1) { + for (int c1 = 0; c1 < c0 - 1; c1 += 1) + S2(c0, c1); + for (int c1 = c0 - 1; c1 <= 4; c1 += 1) { + S1(c0, c1); + S2(c0, c1); + } + for (int c1 = 5; c1 <= 7; c1 += 1) + S1(c0, c1); +} +for (int c0 = 7; c0 <= 8; c0 += 1) + for (int c1 = c0 - 1; c1 <= 7; c1 += 1) + S1(c0, c1); diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/logo.st b/external/mit/isl/dist/test_inputs/codegen/cloog/logo.st new file mode 100644 index 000000000000..89fe64953ab2 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/logo.st @@ -0,0 +1,10 @@ +domain: "[M] -> { S1[i0, i1] : i0 >= 1 and i1 <= 7 and i1 >= -1 + i0; S2[i0, i1] : i0 >= 2 and i0 <= 6 and i1 >= 0 and i1 <= 4 }" +child: + context: "[M] -> { [] }" + child: + schedule: "[M] -> [{ S1[i0, i1] -> [(i0)]; S2[i0, i1] -> [(i0)] }, { S1[i0, i1] -> [(i1)]; S2[i0, i1] -> [(i1)] }]" + options: "[M] -> { separate[i0] }" + child: + sequence: + - filter: "[M] -> { S1[i0, i1] }" + - filter: "[M] -> { S2[i0, i1] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/logopar.c b/external/mit/isl/dist/test_inputs/codegen/cloog/logopar.c new file mode 100644 index 000000000000..8a3160bb5c7e --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/logopar.c @@ -0,0 +1,15 @@ +for (int c1 = 0; c1 <= m; c1 += 1) + S1(1, c1); +for (int c0 = 2; c0 <= n; c0 += 1) { + for (int c1 = 0; c1 < c0 - 1; c1 += 1) + S2(c0, c1); + for (int c1 = c0 - 1; c1 <= n; c1 += 1) { + S1(c0, c1); + S2(c0, c1); + } + for (int c1 = n + 1; c1 <= m; c1 += 1) + S1(c0, c1); +} +for (int c0 = n + 1; c0 <= m + 1; c0 += 1) + for (int c1 = c0 - 1; c1 <= m; c1 += 1) + S1(c0, c1); diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/logopar.st b/external/mit/isl/dist/test_inputs/codegen/cloog/logopar.st new file mode 100644 index 000000000000..8ed609b4ae62 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/logopar.st @@ -0,0 +1,10 @@ +domain: "[m, n] -> { S1[i0, i1] : i0 >= 1 and i1 <= m and i1 >= -1 + i0; S2[i0, i1] : i0 >= 2 and i0 <= n and i1 >= 0 and i1 <= n }" +child: + context: "[m, n] -> { [] : n <= m and m >= 0 and n >= 2 }" + child: + schedule: "[m, n] -> [{ S2[i0, i1] -> [(i0)]; S1[i0, i1] -> [(i0)] }, { S2[i0, i1] -> [(i1)]; S1[i0, i1] -> [(i1)] }]" + options: "[m, n] -> { separate[i0] }" + child: + sequence: + - filter: "[m, n] -> { S1[i0, i1] }" + - filter: "[m, n] -> { S2[i0, i1] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/lu.c b/external/mit/isl/dist/test_inputs/codegen/cloog/lu.c new file mode 100644 index 000000000000..a7fe2b36eedd --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/lu.c @@ -0,0 +1,7 @@ +for (int c0 = 1; c0 <= n; c0 += 1) { + for (int c1 = 2; c1 <= n; c1 += 1) + for (int c2 = 1; c2 < min(c0, c1); c2 += 1) + S2(c2, c1, c0); + for (int c3 = c0 + 1; c3 <= n; c3 += 1) + S1(c0, c3); +} diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/lu.st b/external/mit/isl/dist/test_inputs/codegen/cloog/lu.st new file mode 100644 index 000000000000..6f9320c96da0 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/lu.st @@ -0,0 +1,6 @@ +domain: "[n] -> { S1[i0, i1] : i0 >= 1 and i0 <= n and i1 >= 1 + i0 and i1 <= n; S2[i0, i1, i2] : i0 >= 1 and i0 <= n and i1 >= 1 + i0 and i1 <= n and i2 >= 1 + i0 and i2 <= n }" +child: + context: "[n] -> { [] }" + child: + schedule: "[n] -> [{ S2[i0, i1, i2] -> [(i2)]; S1[i0, i1] -> [(i0)] }, { S2[i0, i1, i2] -> [(i1)]; S1[i0, i1] -> [(n)] }]" + options: "[n] -> { separate[i0] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/lu2.c b/external/mit/isl/dist/test_inputs/codegen/cloog/lu2.c new file mode 100644 index 000000000000..d5cc912359c8 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/lu2.c @@ -0,0 +1,7 @@ +for (int c0 = 1; c0 <= n; c0 += 1) { + for (int c1 = 2; c1 <= n; c1 += 1) + for (int c2 = 1; c2 < min(c0, c1); c2 += 1) + S2(c0, c1, c2, c1, c0); + for (int c3 = c0 + 1; c3 <= n; c3 += 1) + S1(c0, n, c0, c3); +} diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/lu2.st b/external/mit/isl/dist/test_inputs/codegen/cloog/lu2.st new file mode 100644 index 000000000000..eb0ab21f758b --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/lu2.st @@ -0,0 +1,10 @@ +domain: "[n] -> { S2[i0, i1, i2, i1, i0] : i2 >= 1 and i2 <= n and i2 <= -1 + i1 and i1 <= n and i2 <= -1 + i0 and i0 <= n; S1[i0, n, i0, i3] : i0 >= 1 and i0 <= n and i3 >= 1 + i0 and i3 <= n }" +child: + context: "[n] -> { [] }" + child: + schedule: "[n] -> [{ S2[i0, i1, i2, i3, i4] -> [(i0)]; S1[i0, i1, i2, i3] -> [(i0)] }, { S2[i0, i1, i2, i3, i4] -> [(i1)]; S1[i0, i1, i2, i3] -> [(i1)] }, { S2[i0, i1, i2, i3, i4] -> [(i2)]; S1[i0, i1, i2, i3] -> [(i2)] }, { S2[i0, i1, i2, i3, i4] -> [(i3)]; S1[i0, i1, i2, i3] -> [(i3)] }, { S2[i0, i1, i2, i3, i4] -> [(i4)]; S1[i0, i1, i2, i3] -> [(0)] }]" + options: "[n] -> { separate[i0] }" + child: + sequence: + - filter: "[n] -> { S1[i0, i1, i2, i3] }" + - filter: "[n] -> { S2[i0, i1, i2, i3, i4] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/lux.c b/external/mit/isl/dist/test_inputs/codegen/cloog/lux.c new file mode 100644 index 000000000000..3b33025e2277 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/lux.c @@ -0,0 +1,7 @@ +for (int c0 = 1; c0 <= M; c0 += 1) { + for (int c1 = 1; c1 < c0; c1 += 1) + for (int c2 = c1 + 1; c2 <= M; c2 += 1) + S2(c0, c1, c2, c2, c0); + for (int c3 = c0 + 1; c3 <= M; c3 += 1) + S1(c0, c0, M, c3); +} diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/lux.st b/external/mit/isl/dist/test_inputs/codegen/cloog/lux.st new file mode 100644 index 000000000000..8c5bdb612202 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/lux.st @@ -0,0 +1,10 @@ +domain: "[M] -> { S1[i0, i0, M, i3] : i0 >= 1 and i0 <= M and i3 >= 1 + i0 and i3 <= M; S2[i0, i1, i2, i2, i0] : i1 >= 1 and i1 <= M and i2 >= 1 + i1 and i2 <= M and i1 <= -1 + i0 and i0 <= M }" +child: + context: "[M] -> { [] }" + child: + schedule: "[M] -> [{ S1[i0, i1, i2, i3] -> [(i0)]; S2[i0, i1, i2, i3, i4] -> [(i0)] }, { S1[i0, i1, i2, i3] -> [(i1)]; S2[i0, i1, i2, i3, i4] -> [(i1)] }, { S1[i0, i1, i2, i3] -> [(i2)]; S2[i0, i1, i2, i3, i4] -> [(i2)] }, { S1[i0, i1, i2, i3] -> [(i3)]; S2[i0, i1, i2, i3, i4] -> [(i3)] }, { S1[i0, i1, i2, i3] -> [(0)]; S2[i0, i1, i2, i3, i4] -> [(i4)] }]" + options: "[M] -> { separate[i0] }" + child: + sequence: + - filter: "[M] -> { S1[i0, i1, i2, i3] }" + - filter: "[M] -> { S2[i0, i1, i2, i3, i4] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/merge.c b/external/mit/isl/dist/test_inputs/codegen/cloog/merge.c new file mode 100644 index 000000000000..7b56a6441412 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/merge.c @@ -0,0 +1,6 @@ +S1(0); +for (int c0 = 0; c0 <= 10; c0 += 1) { + if (c0 >= 2) + S2(c0); + S3(c0); +} diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/merge.st b/external/mit/isl/dist/test_inputs/codegen/cloog/merge.st new file mode 100644 index 000000000000..d451317251fe --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/merge.st @@ -0,0 +1,11 @@ +domain: "{ S3[i0] : i0 >= 0 and i0 <= 10; S1[0]; S2[i0] : i0 >= 2 and i0 <= 10 }" +child: + context: "{ [] }" + child: + schedule: "[{ S2[i0] -> [(i0)]; S3[i0] -> [(i0)]; S1[i0] -> [(i0)] }]" + options: "{ atomic[i0] }" + child: + sequence: + - filter: "{ S1[i0] }" + - filter: "{ S2[i0] }" + - filter: "{ S3[i0] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/min-1-1.c b/external/mit/isl/dist/test_inputs/codegen/cloog/min-1-1.c new file mode 100644 index 000000000000..b869e1b8b402 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/min-1-1.c @@ -0,0 +1,3 @@ +for (int c0 = 1; c0 <= N; c0 += 1) + for (int c1 = 0; c1 <= min(min(M, c0), N - c0); c1 += 1) + S1(c0, c1); diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/min-1-1.st b/external/mit/isl/dist/test_inputs/codegen/cloog/min-1-1.st new file mode 100644 index 000000000000..cf3dc12dfe75 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/min-1-1.st @@ -0,0 +1,6 @@ +domain: "[M, N] -> { S1[i0, i1] : i0 >= 1 and i1 >= 0 and i1 <= M and i1 <= i0 and i1 <= N - i0 }" +child: + context: "[M, N] -> { [] }" + child: + schedule: "[M, N] -> [{ S1[i0, i1] -> [(i0)] }, { S1[i0, i1] -> [(i1)] }]" + options: "[M, N] -> { separate[i0] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/min-2-1.c b/external/mit/isl/dist/test_inputs/codegen/cloog/min-2-1.c new file mode 100644 index 000000000000..8e6fabf7d288 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/min-2-1.c @@ -0,0 +1,4 @@ +for (int c0 = 1; c0 <= N; c0 += 1) + for (int c1 = 0; c1 <= min(min(M, c0), N - c0); c1 += 1) + for (int c2 = 0; c2 <= min(min(M, c0), N - c0); c2 += 1) + S1(c0, c1, c2); diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/min-2-1.st b/external/mit/isl/dist/test_inputs/codegen/cloog/min-2-1.st new file mode 100644 index 000000000000..c2a48521cc02 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/min-2-1.st @@ -0,0 +1,6 @@ +domain: "[M, N] -> { S1[i0, i1, i2] : i0 >= 1 and i1 >= 0 and i1 <= M and i1 <= i0 and i1 <= N - i0 and i2 >= 0 and i2 <= M and i2 <= i0 and i2 <= N - i0 }" +child: + context: "[M, N] -> { [] }" + child: + schedule: "[M, N] -> [{ S1[i0, i1, i2] -> [(i0)] }, { S1[i0, i1, i2] -> [(i1)] }, { S1[i0, i1, i2] -> [(i2)] }]" + options: "[M, N] -> { separate[i0] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/min-3-1.c b/external/mit/isl/dist/test_inputs/codegen/cloog/min-3-1.c new file mode 100644 index 000000000000..8d11d76d568f --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/min-3-1.c @@ -0,0 +1,3 @@ +for (int c0 = 0; c0 <= min(10, M); c0 += 1) + for (int c1 = 0; c1 <= min(10, M); c1 += 1) + S1(c0, c1); diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/min-3-1.st b/external/mit/isl/dist/test_inputs/codegen/cloog/min-3-1.st new file mode 100644 index 000000000000..30dec04baf16 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/min-3-1.st @@ -0,0 +1,6 @@ +domain: "[M] -> { S1[i0, i1] : i0 >= 0 and i0 <= M and i0 <= 10 and i1 >= 0 and i1 <= M and i1 <= 10 }" +child: + context: "[M] -> { [] : M >= 0 }" + child: + schedule: "[M] -> [{ S1[i0, i1] -> [(i0)] }, { S1[i0, i1] -> [(i1)] }]" + options: "[M] -> { separate[i0] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/min-4-1.c b/external/mit/isl/dist/test_inputs/codegen/cloog/min-4-1.c new file mode 100644 index 000000000000..da272fc291fa --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/min-4-1.c @@ -0,0 +1,2 @@ +for (int c0 = max(-M, -N); c0 <= min(N, O); c0 += 1) + S1(c0); diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/min-4-1.st b/external/mit/isl/dist/test_inputs/codegen/cloog/min-4-1.st new file mode 100644 index 000000000000..8c0fd8697306 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/min-4-1.st @@ -0,0 +1,6 @@ +domain: "[M, N, O] -> { S1[i0] : i0 >= -M and i0 >= -N and i0 <= N and i0 <= O }" +child: + context: "[M, N, O] -> { [] }" + child: + schedule: "[M, N, O] -> [{ S1[i0] -> [(i0)] }]" + options: "[M, N, O] -> { separate[i0] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/mod.c b/external/mit/isl/dist/test_inputs/codegen/cloog/mod.c new file mode 100644 index 000000000000..cafe0b85ddbe --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/mod.c @@ -0,0 +1,3 @@ +for (int c0 = 0; c0 <= 3; c0 += 1) + if ((c0 + 1) % 3 >= 1) + S1(c0); diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/mod.st b/external/mit/isl/dist/test_inputs/codegen/cloog/mod.st new file mode 100644 index 000000000000..cecdef112e07 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/mod.st @@ -0,0 +1,6 @@ +domain: "{ S1[i0] : exists (e0 = floor((1 + i0)/3): 3e0 <= i0 and 3e0 >= -1 + i0 and i0 >= 0 and i0 <= 3) }" +child: + context: "{ [] }" + child: + schedule: "[{ S1[i0] -> [(i0)] }]" + options: "{ separate[i0] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/mod2.c b/external/mit/isl/dist/test_inputs/codegen/cloog/mod2.c new file mode 100644 index 000000000000..cafe0b85ddbe --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/mod2.c @@ -0,0 +1,3 @@ +for (int c0 = 0; c0 <= 3; c0 += 1) + if ((c0 + 1) % 3 >= 1) + S1(c0); diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/mod2.st b/external/mit/isl/dist/test_inputs/codegen/cloog/mod2.st new file mode 100644 index 000000000000..3097bb7289aa --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/mod2.st @@ -0,0 +1,6 @@ +domain: "{ S1[i] : exists (e0 = floor((1 + i)/3): 3e0 <= i and 3e0 >= -1 + i and i >= 0 and i <= 3) }" +child: + context: "{ [] }" + child: + schedule: "[{ S1[i] -> [(i)] }]" + options: "{ separate[i0] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/mod3.c b/external/mit/isl/dist/test_inputs/codegen/cloog/mod3.c new file mode 100644 index 000000000000..f8d879ce1ae9 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/mod3.c @@ -0,0 +1,4 @@ +for (int c0 = max(0, 32 * h0 - 1991); c0 <= min(999, 32 * h0 + 31); c0 += 1) + if ((32 * h0 - c0 + 32) % 64 >= 1) + for (int c1 = 0; c1 <= 999; c1 += 1) + S1(c0, c1); diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/mod3.st b/external/mit/isl/dist/test_inputs/codegen/cloog/mod3.st new file mode 100644 index 000000000000..eaad1706cfa7 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/mod3.st @@ -0,0 +1,6 @@ +domain: "[h0] -> { S1[i0, i1] : exists (e0 = floor((32 + 32h0 - i0)/64): 64e0 <= 31 + 32h0 - i0 and 64e0 >= -31 + 32h0 - i0 and i0 >= 0 and i0 <= 999 and i0 >= -2015 + 32h0 and 32e0 >= -999 + 32h0 - i0 and i1 >= 0 and i1 <= 999 and i0 <= 32 + 32h0) }" +child: + context: "[h0] -> { [] : h0 <= 93 and h0 >= 0 }" + child: + schedule: "[h0] -> [{ S1[i0, i1] -> [(i0)] }, { S1[i0, i1] -> [(i1)] }]" + options: "[h0] -> { separate[i0] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/mod4.c b/external/mit/isl/dist/test_inputs/codegen/cloog/mod4.c new file mode 100644 index 000000000000..a5dca247b967 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/mod4.c @@ -0,0 +1,5 @@ +for (int c0 = 2; c0 <= 10; c0 += 3) { + S1(c0, (c0 + 1) / 3, (c0 + 1) / 3, 2, (c0 - 2) / 3); + S2(c0, (c0 + 1) / 3, (c0 + 1) / 3, 2, (c0 - 2) / 3); + S3(c0, (c0 + 1) / 3, (c0 + 1) / 3, 2, (c0 - 2) / 3); +} diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/mod4.st b/external/mit/isl/dist/test_inputs/codegen/cloog/mod4.st new file mode 100644 index 000000000000..99501a88e9af --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/mod4.st @@ -0,0 +1,11 @@ +domain: "{ S1[j, div41, div42, 2, mod6_a] : 3mod6_a = -2 + j and j >= 1 and j <= 10 and 3div41 >= j and 3div42 >= -1 + j and 3div42 <= 1 + j and 3div41 <= 2 + j; S2[j, div41, div42, 2, mod6_a] : 3div42 = 1 + j and 3mod6_a = -2 + j and 3div41 >= 1 + j and 3div41 <= 2 + j and j >= 1 and j <= 10; S3[j, div41, div42, 2, mod6_a] : 3mod6_a = -2 + j and j >= 1 and j <= 10 and 3div41 >= j and 3div42 >= -1 + j and 3div42 <= 1 + j and 3div41 <= 2 + j }" +child: + context: "{ [] }" + child: + schedule: "[{ S1[j, div41, div42, mod6, mod6_a] -> [(j)]; S3[j, div41, div42, mod6, mod6_a] -> [(j)]; S2[j, div41, div42, mod6, mod6_a] -> [(j)] }, { S1[j, div41, div42, mod6, mod6_a] -> [(div41)]; S3[j, div41, div42, mod6, mod6_a] -> [(div41)]; S2[j, div41, div42, mod6, mod6_a] -> [(div41)] }, { S1[j, div41, div42, mod6, mod6_a] -> [(div42)]; S3[j, div41, div42, mod6, mod6_a] -> [(div42)]; S2[j, div41, div42, mod6, mod6_a] -> [(div42)] }, { S1[j, div41, div42, mod6, mod6_a] -> [(mod6)]; S3[j, div41, div42, mod6, mod6_a] -> [(mod6)]; S2[j, div41, div42, mod6, mod6_a] -> [(mod6)] }, { S1[j, div41, div42, mod6, mod6_a] -> [(mod6_a)]; S3[j, div41, div42, mod6, mod6_a] -> [(mod6_a)]; S2[j, div41, div42, mod6, mod6_a] -> [(mod6_a)] }]" + options: "{ separate[i0] }" + child: + sequence: + - filter: "{ S1[j, div41, div42, mod6, mod6_a] }" + - filter: "{ S2[j, div41, div42, mod6, mod6_a] }" + - filter: "{ S3[j, div41, div42, mod6, mod6_a] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/mode.c b/external/mit/isl/dist/test_inputs/codegen/cloog/mode.c new file mode 100644 index 000000000000..bcfd31839bbe --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/mode.c @@ -0,0 +1,10 @@ +for (int c0 = 0; c0 <= M; c0 += 1) { + for (int c1 = 0; c1 <= min(N, c0); c1 += 1) { + S1(c0, c1); + S2(c0, c1); + } + for (int c1 = max(0, N + 1); c1 <= c0; c1 += 1) + S1(c0, c1); + for (int c1 = c0 + 1; c1 <= N; c1 += 1) + S2(c0, c1); +} diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/mode.st b/external/mit/isl/dist/test_inputs/codegen/cloog/mode.st new file mode 100644 index 000000000000..68ece148affa --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/mode.st @@ -0,0 +1,10 @@ +domain: "[M, N] -> { S1[i0, i1] : i0 >= 0 and i0 <= M and i1 >= 0 and i1 <= i0; S2[i0, i1] : i0 >= 0 and i0 <= M and i1 >= 0 and i1 <= N }" +child: + context: "[M, N] -> { [] }" + child: + schedule: "[M, N] -> [{ S1[i0, i1] -> [(i0)]; S2[i0, i1] -> [(i0)] }, { S1[i0, i1] -> [(i1)]; S2[i0, i1] -> [(i1)] }]" + options: "[M, N] -> { separate[i0] }" + child: + sequence: + - filter: "[M, N] -> { S1[i0, i1] }" + - filter: "[M, N] -> { S2[i0, i1] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/multi-mm-1.c b/external/mit/isl/dist/test_inputs/codegen/cloog/multi-mm-1.c new file mode 100644 index 000000000000..271d863f0083 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/multi-mm-1.c @@ -0,0 +1,8 @@ +for (int c0 = 0; c0 <= M; c0 += 1) { + for (int c1 = 0; c1 <= min(N, c0); c1 += 1) { + S1(c0, c1); + S2(c0, c1); + } + for (int c1 = N + 1; c1 <= c0; c1 += 1) + S1(c0, c1); +} diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/multi-mm-1.st b/external/mit/isl/dist/test_inputs/codegen/cloog/multi-mm-1.st new file mode 100644 index 000000000000..de96851fa328 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/multi-mm-1.st @@ -0,0 +1,10 @@ +domain: "[M, N] -> { S1[i0, i1] : i1 >= 0 and i1 <= i0 and i0 <= M; S2[i0, i1] : i1 >= 0 and i1 <= i0 and i0 <= M and i1 <= N }" +child: + context: "[M, N] -> { [] : N <= M and N >= 1 }" + child: + schedule: "[M, N] -> [{ S1[i0, i1] -> [(i0)]; S2[i0, i1] -> [(i0)] }, { S1[i0, i1] -> [(i1)]; S2[i0, i1] -> [(i1)] }]" + options: "[M, N] -> { separate[i0] }" + child: + sequence: + - filter: "[M, N] -> { S1[i0, i1] }" + - filter: "[M, N] -> { S2[i0, i1] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/multi-stride.c b/external/mit/isl/dist/test_inputs/codegen/cloog/multi-stride.c new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/multi-stride.st b/external/mit/isl/dist/test_inputs/codegen/cloog/multi-stride.st new file mode 100644 index 000000000000..2c7788b6bf2c --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/multi-stride.st @@ -0,0 +1,6 @@ +domain: "{ S1[i0, i1, i2] : 2i1 = -1 + i0 and 6i2 = -2 + i0 and i0 >= 0 and i0 <= 100 }" +child: + context: "{ [] }" + child: + schedule: "[{ S1[i0, i1, i2] -> [(i0)] }, { S1[i0, i1, i2] -> [(i1)] }, { S1[i0, i1, i2] -> [(i2)] }]" + options: "{ separate[i0] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/multi-stride2.c b/external/mit/isl/dist/test_inputs/codegen/cloog/multi-stride2.c new file mode 100644 index 000000000000..14f80506e0bc --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/multi-stride2.c @@ -0,0 +1,2 @@ +for (int c0 = 5; c0 <= 100; c0 += 6) + S1(c0, (c0 - 1) / 2, (c0 - 2) / 3); diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/multi-stride2.st b/external/mit/isl/dist/test_inputs/codegen/cloog/multi-stride2.st new file mode 100644 index 000000000000..e3fc0bc73123 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/multi-stride2.st @@ -0,0 +1,6 @@ +domain: "{ S1[i0, i1, i2] : 2i1 = -1 + i0 and 3i2 = -2 + i0 and i0 >= 0 and i0 <= 100 }" +child: + context: "{ [] }" + child: + schedule: "[{ S1[i0, i1, i2] -> [(i0)] }, { S1[i0, i1, i2] -> [(i1)] }, { S1[i0, i1, i2] -> [(i2)] }]" + options: "{ separate[i0] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/mxm-shared.c b/external/mit/isl/dist/test_inputs/codegen/cloog/mxm-shared.c new file mode 100644 index 000000000000..4308a9c90437 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/mxm-shared.c @@ -0,0 +1,3 @@ +if (N >= g0 + t1 + 1 && t1 <= 7 && g4 % 4 == 0) + for (int c0 = t0; c0 <= min(127, N - g1 - 1); c0 += 16) + S1(g0 + t1, g1 + c0); diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/mxm-shared.st b/external/mit/isl/dist/test_inputs/codegen/cloog/mxm-shared.st new file mode 100644 index 000000000000..c86ed9c5f493 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/mxm-shared.st @@ -0,0 +1,6 @@ +domain: "[N, b0, b1, g0, g1, g2, g3, g4, t0, t1] -> { S1[g0 + t1, i1] : (exists (e0 = floor((g1)/128), e1 = floor((128b1 - g1)/4096), e2 = floor((-8b0 + g0)/128), e3 = floor((-t0 + i1)/16): g3 = 128b1 and g4 = 0 and g2 = 8b0 and 128e0 = g1 and 4096e1 = 128b1 - g1 and 128e2 = -8b0 + g0 and 16e3 = -t0 + i1 and b0 <= 15 and b0 >= 0 and b1 <= 31 and b1 >= 0 and g0 >= 8b0 and g1 >= 128b1 and t0 <= 15 and t0 >= 0 and t1 <= 7 and t1 >= 0 and t1 <= -1 + N - g0 and i1 >= g1 and i1 <= 127 + g1 and i1 <= -1 + N)) or (exists (e0 = floor((g1)/128), e1 = floor((128b1 - g1)/4096), e2 = floor((g4)/4), e3 = floor((-8b0 + g0)/128), e4 = floor((-t0 + i1)/16): g3 = 128b1 and g2 = 8b0 and 128e0 = g1 and 4096e1 = 128b1 - g1 and 4e2 = g4 and 128e3 = -8b0 + g0 and 16e4 = -t0 + i1 and b0 <= 15 and b0 >= 0 and b1 <= 31 and b1 >= 0 and g0 >= 8b0 and g1 >= 128b1 and g4 >= 0 and g4 <= -1 + N and t0 <= 15 and t0 >= 0 and t1 <= 7 and t1 >= 0 and t1 <= -1 + N - g0 and i1 >= g1 and i1 <= 127 + g1 and i1 <= -1 + N)) }" +child: + context: "[N, b0, b1, g0, g1, g2, g3, g4, t0, t1] -> { [] : exists (e0 = floor((g0)/8), e1 = floor((-128b1 + g1)/4096), e2 = floor((8b0 - g0)/128): g2 = 8b0 and g3 = 128b1 and 8e0 = g0 and 4096e1 = -128b1 + g1 and 128e2 = 8b0 - g0 and b0 >= 0 and g4 <= -1 + N and b0 <= 15 and g1 <= -1 + N and g4 >= 0 and b1 <= 31 and g0 <= -1 + N and g1 >= 128b1 and b1 >= 0 and g0 >= 8b0 and t0 >= 0 and t0 <= 15 and t1 >= 0 and t1 <= 15) }" + child: + schedule: "[N, b0, b1, g0, g1, g2, g3, g4, t0, t1] -> [{ S1[i0, i1] -> [(-g1 + i1)] }, { S1[i0, i1] -> [(t1)] }, { S1[i0, i1] -> [(t0)] }, { S1[i0, i1] -> [(t1)] }]" + options: "[N, b0, b1, g0, g1, g2, g3, g4, t0, t1] -> { separate[i0] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/no_lindep.c b/external/mit/isl/dist/test_inputs/codegen/cloog/no_lindep.c new file mode 100644 index 000000000000..1432b5e4e3cd --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/no_lindep.c @@ -0,0 +1 @@ +S1(N + 2); diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/no_lindep.st b/external/mit/isl/dist/test_inputs/codegen/cloog/no_lindep.st new file mode 100644 index 000000000000..da06c8dc0ff2 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/no_lindep.st @@ -0,0 +1,6 @@ +domain: "[M, N] -> { S1[2 + N] }" +child: + context: "[M, N] -> { [] }" + child: + schedule: "[M, N] -> [{ S1[i0] -> [(1 + M)] }, { S1[i0] -> [(N)] }]" + options: "[M, N] -> { separate[i0] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/nul_basic1.c b/external/mit/isl/dist/test_inputs/codegen/cloog/nul_basic1.c new file mode 100644 index 000000000000..9293aef92c70 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/nul_basic1.c @@ -0,0 +1,2 @@ +for (int c0 = 0; c0 <= M; c0 += 2) + S1(c0, c0 / 2); diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/nul_basic1.st b/external/mit/isl/dist/test_inputs/codegen/cloog/nul_basic1.st new file mode 100644 index 000000000000..d8a3201f47fa --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/nul_basic1.st @@ -0,0 +1,6 @@ +domain: "[M] -> { S1[i0, i1] : 2i1 = i0 and i0 >= 0 and i0 <= M }" +child: + context: "[M] -> { [] }" + child: + schedule: "[M] -> [{ S1[i0, i1] -> [(i0)] }, { S1[i0, i1] -> [(i1)] }]" + options: "[M] -> { separate[i0] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/nul_basic2.c b/external/mit/isl/dist/test_inputs/codegen/cloog/nul_basic2.c new file mode 100644 index 000000000000..2b7bb4d22c61 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/nul_basic2.c @@ -0,0 +1,5 @@ +for (int c0 = 2; c0 <= n; c0 += 2) { + if (c0 % 4 == 0) + S2(c0, c0 / 4); + S1(c0, c0 / 2); +} diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/nul_basic2.st b/external/mit/isl/dist/test_inputs/codegen/cloog/nul_basic2.st new file mode 100644 index 000000000000..3258c6708810 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/nul_basic2.st @@ -0,0 +1,10 @@ +domain: "[n] -> { S1[i0, i1] : 2i1 = i0 and i0 >= 1 and i0 <= n; S2[i0, i1] : 4i1 = i0 and i0 >= 1 and i0 <= n }" +child: + context: "[n] -> { [] : n >= 2 }" + child: + schedule: "[n] -> [{ S2[i0, i1] -> [(i0)]; S1[i0, i1] -> [(i0)] }, { S2[i0, i1] -> [(i1)]; S1[i0, i1] -> [(i1)] }]" + options: "[n] -> { separate[i0] }" + child: + sequence: + - filter: "[n] -> { S1[i0, i1] }" + - filter: "[n] -> { S2[i0, i1] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/nul_complex1.c b/external/mit/isl/dist/test_inputs/codegen/cloog/nul_complex1.c new file mode 100644 index 000000000000..067e7515aa7c --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/nul_complex1.c @@ -0,0 +1,3 @@ +for (int c0 = 0; c0 <= 5 * n; c0 += 1) + for (int c1 = max(-((5 * n - c0 + 1) % 2) - n + c0 + 1, 2 * ((c0 + 2) / 3)); c1 <= min(c0, n + c0 - (n + c0 + 2) / 3); c1 += 2) + S1((3 * c1 / 2) - c0, c0 - c1); diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/nul_complex1.st b/external/mit/isl/dist/test_inputs/codegen/cloog/nul_complex1.st new file mode 100644 index 000000000000..93e3329fcade --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/nul_complex1.st @@ -0,0 +1,6 @@ +domain: "[n] -> { S1[i0, i1] : i0 >= 0 and i0 <= n and i1 >= 0 and i1 <= n }" +child: + context: "[n] -> { [] }" + child: + schedule: "[n] -> [{ S1[i0, i1] -> [(2i0 + 3i1)] }, { S1[i0, i1] -> [(2i0 + 2i1)] }]" + options: "[n] -> { separate[i0] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/nul_lcpc.c b/external/mit/isl/dist/test_inputs/codegen/cloog/nul_lcpc.c new file mode 100644 index 000000000000..410d59d03eeb --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/nul_lcpc.c @@ -0,0 +1,11 @@ +for (int c0 = 1; c0 <= 6; c0 += 2) { + for (int c2 = 1; c2 <= c0; c2 += 1) { + S1(c0, (c0 - 1) / 2, c2); + S2(c0, (c0 - 1) / 2, c2); + } + for (int c2 = c0 + 1; c2 <= p; c2 += 1) + S1(c0, (c0 - 1) / 2, c2); +} +for (int c0 = 7; c0 <= m; c0 += 2) + for (int c2 = 1; c2 <= p; c2 += 1) + S1(c0, (c0 - 1) / 2, c2); diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/nul_lcpc.st b/external/mit/isl/dist/test_inputs/codegen/cloog/nul_lcpc.st new file mode 100644 index 000000000000..4571d7846f39 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/nul_lcpc.st @@ -0,0 +1,10 @@ +domain: "[m, n, p] -> { S1[i, k, j] : 2k = -1 + i and i >= 1 and i <= m and j >= 1 and j <= p; S2[i, k, j] : 2k = -1 + i and i >= 1 and i <= n and j >= 1 and j <= i }" +child: + context: "[m, n, p] -> { [] : n = 6 and m >= 7 and p >= 7 }" + child: + schedule: "[m, n, p] -> [{ S1[i, k, j] -> [(i)]; S2[i, k, j] -> [(i)] }, { S1[i, k, j] -> [(k)]; S2[i, k, j] -> [(k)] }, { S1[i, k, j] -> [(j)]; S2[i, k, j] -> [(j)] }]" + options: "[m, n, p] -> { separate[i0] }" + child: + sequence: + - filter: "[m, n, p] -> { S1[i, k, j] }" + - filter: "[m, n, p] -> { S2[i, k, j] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/orc.c b/external/mit/isl/dist/test_inputs/codegen/cloog/orc.c new file mode 100644 index 000000000000..770b9808e65c --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/orc.c @@ -0,0 +1,14 @@ +for (int c0 = 0; c0 <= 2; c0 += 1) { + S1(c0); + for (int c1 = 0; c1 <= -c0 + 11; c1 += 1) { + S2(c0, c1); + S3(c0, c1); + } + S4(c0); +} +for (int c0 = 0; c0 <= 14; c0 += 1) { + S5(c0); + for (int c1 = 0; c1 <= 9; c1 += 1) + S6(c0, c1); + S7(c0); +} diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/orc.st b/external/mit/isl/dist/test_inputs/codegen/cloog/orc.st new file mode 100644 index 000000000000..a67a8801fdee --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/orc.st @@ -0,0 +1,13 @@ +domain: "{ S5[i] : i >= 0 and i <= 14; S6[i, j] : i >= 0 and i <= 14 and j >= 0 and j <= 9; S7[i] : i >= 0 and i <= 14; S4[i] : i >= 0 and i <= 2; S2[i, j] : i >= 0 and i <= 2 and j >= 0 and j <= 11 - i; S1[i] : i >= 0 and i <= 2; S3[i, j] : i >= 0 and i <= 2 and j >= 0 and j <= 11 - i }" +child: + context: "{ [] }" + child: + sequence: + - filter: "{ S4[i0]; S2[i0, i1]; S1[i0]; S3[i0, i1] }" + child: + schedule: "[{ S3[i0, i1] -> [(1 + 3i0)]; S2[i0, i1] -> [(1 + 3i0)]; S1[i0] -> [(3i0)]; S4[i0] -> [(2 + 3i0)] }, { S3[i0, i1] -> [(1 + 2i1)]; S2[i0, i1] -> [(2i1)]; S1[i0] -> [(0)]; S4[i0] -> [(0)] }]" + options: "{ separate[i0] }" + - filter: "{ S5[i0]; S6[i0, i1]; S7[i0] }" + child: + schedule: "[{ S6[i0, i1] -> [(1 + 3i0)]; S7[i0] -> [(2 + 3i0)]; S5[i0] -> [(3i0)] }, { S6[i0, i1] -> [(i1)]; S7[i0] -> [(0)]; S5[i0] -> [(0)] }]" + options: "{ separate[i0] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/otl.c b/external/mit/isl/dist/test_inputs/codegen/cloog/otl.c new file mode 100644 index 000000000000..793733447eef --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/otl.c @@ -0,0 +1,7 @@ +if (M >= 3 && N >= 4) + for (int c0 = 1; c0 < (2 * M + 2 * N - 2) / 5; c0 += 1) + for (int c1 = max(c0 - (M + 2) / 5, (c0 + 1) / 2); c1 <= min(min(c0, (M + 2 * N) / 5 - 1), (2 * N + 5 * c0 + 1) / 10); c1 += 1) + for (int c2 = max(max(max(max(0, c0 - c1 - 1), c1 - (N + 6) / 5 + 1), c0 - (M + N + 4) / 5 + 1), floord(-N + 5 * c0 - 3, 10) + 1); c2 <= min(min(min(c1, (M + N - 2) / 5), c0 - c1 + (N - 1) / 5 + 1), (N + 5 * c0 + 3) / 10); c2 += 1) + for (int c3 = max(max(max(c0, 2 * c1 - (2 * N + 5) / 5 + 1), c1 + c2 - (N + 3) / 5), 2 * c2 - (N + 2) / 5); c3 <= min(min(min(min(min(c0 + 1, c1 + c2 + 1), c1 + (M - 2) / 5 + 1), 2 * c2 + (N - 2) / 5 + 1), (2 * M + 2 * N - 1) / 5 - 1), c2 + (M + N) / 5); c3 += 1) + for (int c4 = max(max(max(max(c1, c0 - c2), c0 - (M + 6) / 5 + 1), c3 - (M + 2) / 5), (c3 + 1) / 2); c4 <= min(min(min(min(min(min(min(c0, c1 + 1), -c2 + c3 + (N - 1) / 5 + 1), c0 - c2 + N / 5 + 1), (M + 2 * N + 1) / 5 - 1), c2 + (N + 2) / 5), (2 * N + 5 * c0 + 3) / 10), (2 * N + 5 * c3 + 2) / 10); c4 += 1) + S1(c0, c1, c2, c3, c4, c2); diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/otl.st b/external/mit/isl/dist/test_inputs/codegen/cloog/otl.st new file mode 100644 index 000000000000..da706835052f --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/otl.st @@ -0,0 +1,6 @@ +domain: "[M, N] -> { S1[outerTimeTileIter, outerProcTileIter1, outerProcTileIter2, innerTimeTileIter, innerProcTileIter1, outerProcTileIter2] : 5outerTimeTileIter <= -7 + 2M + 2N and innerProcTileIter1 >= outerTimeTileIter - outerProcTileIter2 and 10outerProcTileIter2 >= -2 - N + 5outerTimeTileIter and outerProcTileIter2 >= -1 + outerTimeTileIter - outerProcTileIter1 and 2innerProcTileIter1 >= outerTimeTileIter and outerTimeTileIter >= 1 and outerProcTileIter1 >= 1 and 2outerProcTileIter1 >= outerTimeTileIter and outerProcTileIter2 >= 0 and 5outerProcTileIter2 >= 1 - M - N + 5outerTimeTileIter and 5innerProcTileIter1 >= -1 - M + 5outerTimeTileIter and innerTimeTileIter >= outerTimeTileIter and 5outerProcTileIter1 >= -2 - M + 5outerTimeTileIter and innerTimeTileIter >= 1 and 5innerTimeTileIter >= -3 - N + 5outerProcTileIter1 + 5outerProcTileIter2 and 5outerProcTileIter2 <= 4 + N + 5outerTimeTileIter - 5outerProcTileIter1 and innerProcTileIter1 >= 1 and outerProcTileIter2 <= outerTimeTileIter and 5innerTimeTileIter >= -2N + 10outerProcTileIter1 and 5outerProcTileIter1 <= -5 + M + 2N and 10outerProcTileIter1 <= 1 + 2N + 5outerTimeTileIter and 5outerProcTileIter2 >= -1 - N + 5outerProcTileIter1 and innerProcTileIter1 >= outerProcTileIter1 and innerTimeTileIter >= outerProcTileIter1 and outerProcTileIter2 <= outerProcTileIter1 and outerProcTileIter1 <= outerTimeTileIter and 5innerProcTileIter1 <= 4 + N - 5outerProcTileIter2 + 5innerTimeTileIter and 5innerProcTileIter1 <= 5 + N + 5outerTimeTileIter - 5outerProcTileIter2 and 5innerTimeTileIter >= -2 - N + 10outerProcTileIter2 and 5outerProcTileIter2 <= -2 + M + N and 10outerProcTileIter2 <= 3 + N + 5outerTimeTileIter and N >= 4 and innerProcTileIter1 >= outerProcTileIter2 and innerTimeTileIter >= outerProcTileIter2 and M >= 3 and innerProcTileIter1 <= outerTimeTileIter and 5innerTimeTileIter <= -6 + 2M + 2N and innerProcTileIter1 >= -1 - outerProcTileIter2 + innerTimeTileIter and 5innerTimeTileIter <= 3 + N + 10outerProcTileIter2 and innerTimeTileIter <= 1 + outerProcTileIter1 + outerProcTileIter2 and innerProcTileIter1 <= 1 + outerProcTileIter1 and 2innerProcTileIter1 >= innerTimeTileIter and 5innerProcTileIter1 <= 2 + N + 5outerProcTileIter2 and innerTimeTileIter <= 1 + 2outerProcTileIter1 and innerProcTileIter1 <= innerTimeTileIter and 5innerTimeTileIter <= M + N + 5outerProcTileIter2 and 5innerProcTileIter1 >= -2 - M + 5innerTimeTileIter and 10innerProcTileIter1 <= 3 + 2N + 5outerTimeTileIter and innerTimeTileIter <= 1 + outerTimeTileIter and 5innerTimeTileIter <= 3 + M + 5outerProcTileIter1 and 5innerProcTileIter1 <= -4 + M + 2N and 10innerProcTileIter1 <= 2 + 2N + 5innerTimeTileIter }" +child: + context: "[M, N] -> { [] : M >= 1 and N >= 1 }" + child: + schedule: "[M, N] -> [{ S1[i0, i1, i2, i3, i4, i5] -> [(i0)] }, { S1[i0, i1, i2, i3, i4, i5] -> [(i1)] }, { S1[i0, i1, i2, i3, i4, i5] -> [(i2)] }, { S1[i0, i1, i2, i3, i4, i5] -> [(i3)] }, { S1[i0, i1, i2, i3, i4, i5] -> [(i4)] }, { S1[i0, i1, i2, i3, i4, i5] -> [(i5)] }]" + options: "[M, N] -> { separate[i0] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/param-split.c b/external/mit/isl/dist/test_inputs/codegen/cloog/param-split.c new file mode 100644 index 000000000000..a9d97124b52b --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/param-split.c @@ -0,0 +1,6 @@ +for (int c0 = 0; c0 <= max(0, M); c0 += 1) { + if (M >= c0) + S1(c0); + if (c0 == 0) + S2(0); +} diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/param-split.st b/external/mit/isl/dist/test_inputs/codegen/cloog/param-split.st new file mode 100644 index 000000000000..371372f28e51 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/param-split.st @@ -0,0 +1,10 @@ +domain: "[M] -> { S2[0]; S1[i0] : i0 >= 0 and i0 <= M }" +child: + context: "[M] -> { [] }" + child: + schedule: "[M] -> [{ S2[i0] -> [(i0)]; S1[i0] -> [(i0)] }]" + options: "[M] -> { atomic[i0] }" + child: + sequence: + - filter: "[M] -> { S1[i0] }" + - filter: "[M] -> { S2[i0] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/pouchet.c b/external/mit/isl/dist/test_inputs/codegen/cloog/pouchet.c new file mode 100644 index 000000000000..97974bbc3eea --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/pouchet.c @@ -0,0 +1,12 @@ +for (int c0 = 1; c0 <= floord(Ny, 2) + 2; c0 += 1) + for (int c1 = max(c0 - 1, c0 / 2 + 1); c1 <= min(c0, (Ny + 2 * c0) / 4); c1 += 1) { + if (Ny + 2 * c0 >= 4 * c1 + 1) { + for (int c2 = 1; c2 <= 2; c2 += 1) { + S1(c0 - c1, c1, 2 * c0 - 2 * c1, -2 * c0 + 4 * c1, c2); + S2(c0 - c1, c1, 2 * c0 - 2 * c1, -2 * c0 + 4 * c1 - 1, c2); + } + } else { + for (int c2 = 1; c2 <= 2; c2 += 1) + S2((-Ny + 2 * c0) / 4, (Ny + 2 * c0) / 4, (-Ny / 2) + c0, Ny - 1, c2); + } + } diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/pouchet.st b/external/mit/isl/dist/test_inputs/codegen/cloog/pouchet.st new file mode 100644 index 000000000000..8ba092889ec4 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/pouchet.st @@ -0,0 +1,6 @@ +domain: "[Ny] -> { S1[i0, i1, 2i0, -2i0 + 2i1, i4] : i0 >= 0 and i0 <= 1 and i1 >= 1 + i0 and 2i1 <= -1 + Ny + 2i0 and i4 >= 1 and i4 <= 2; S2[i0, i1, 2i0, -1 - 2i0 + 2i1, i4] : i0 >= 0 and i0 <= 1 and i1 >= 1 + i0 and 2i1 <= Ny + 2i0 and i4 >= 1 and i4 <= 2 }" +child: + context: "[Ny] -> { [] }" + child: + schedule: "[Ny] -> [{ S1[i0, i1, i2, i3, i4] -> [(i0 + i1)]; S2[i0, i1, i2, i3, i4] -> [(i0 + i1)] }, { S1[i0, i1, i2, i3, i4] -> [(i1)]; S2[i0, i1, i2, i3, i4] -> [(i1)] }, { S1[i0, i1, i2, i3, i4] -> [(i4)]; S2[i0, i1, i2, i3, i4] -> [(i4)] }, { S1[i0, i1, i2, i3, i4] -> [(i2)]; S2[i0, i1, i2, i3, i4] -> [(i2)] }, { S1[i0, i1, i2, i3, i4] -> [(i3)]; S2[i0, i1, i2, i3, i4] -> [(1 + i3)] }, { S1[i0, i1, i2, i3, i4] -> [(i4)]; S2[i0, i1, i2, i3, i4] -> [(1 + i4)] }]" + options: "[Ny] -> { separate[x] : x >= 2 }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/rectangle.c b/external/mit/isl/dist/test_inputs/codegen/cloog/rectangle.c new file mode 100644 index 000000000000..10d1f76c19d2 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/rectangle.c @@ -0,0 +1,3 @@ +for (int c0 = 0; c0 <= 2 * n; c0 += 1) + for (int c1 = max(0, -n + c0); c1 <= min(n, c0); c1 += 1) + S1(c1, c0 - c1); diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/rectangle.st b/external/mit/isl/dist/test_inputs/codegen/cloog/rectangle.st new file mode 100644 index 000000000000..a4a9e51f4445 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/rectangle.st @@ -0,0 +1,6 @@ +domain: "[n] -> { S1[i0, i1] : i0 >= 0 and i0 <= n and i1 >= 0 and i1 <= n }" +child: + context: "[n] -> { [] : n >= 0 }" + child: + schedule: "[n] -> [{ S1[i0, i1] -> [(i0 + i1)] }]" + options: "[n] -> { separate[i0] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-QR.c b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-QR.c new file mode 100644 index 000000000000..fee61aa66738 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-QR.c @@ -0,0 +1,54 @@ +if (N >= 1) { + S1(0); + if (N == 1) { + for (int c1 = 0; c1 < M; c1 += 1) + S2(0, c1); + S3(0); + for (int c1 = 0; c1 < M; c1 += 1) + S4(0, c1); + S10(0); + S5(0); + } else { + for (int c1 = 0; c1 < M; c1 += 1) + S2(0, c1); + S3(0); + for (int c1 = 0; c1 < M; c1 += 1) + S4(0, c1); + S10(0); + S1(1); + S5(0); + } + for (int c0 = 2; c0 < N; c0 += 1) { + for (int c1 = c0 - 1; c1 < N; c1 += 1) { + S6(c0 - 2, c1); + for (int c2 = c0 - 2; c2 < M; c2 += 1) + S7(c0 - 2, c1, c2); + S8(c0 - 2, c1); + for (int c2 = c0 - 2; c2 < M; c2 += 1) + S9(c0 - 2, c1, c2); + } + for (int c1 = c0 - 1; c1 < M; c1 += 1) + S2(c0 - 1, c1); + S3(c0 - 1); + for (int c1 = c0 - 1; c1 < M; c1 += 1) + S4(c0 - 1, c1); + S10(c0 - 1); + S1(c0); + S5(c0 - 1); + } + if (N >= 2) { + S6(N - 2, N - 1); + for (int c2 = N - 2; c2 < M; c2 += 1) + S7(N - 2, N - 1, c2); + S8(N - 2, N - 1); + for (int c2 = N - 2; c2 < M; c2 += 1) + S9(N - 2, N - 1, c2); + for (int c1 = N - 1; c1 < M; c1 += 1) + S2(N - 1, c1); + S3(N - 1); + for (int c1 = N - 1; c1 < M; c1 += 1) + S4(N - 1, c1); + S10(N - 1); + S5(N - 1); + } +} diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-QR.st b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-QR.st new file mode 100644 index 000000000000..8be6a039a1e9 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-QR.st @@ -0,0 +1,36 @@ +domain: "[M, N] -> { S5[i0] : i0 >= 0 and i0 <= -1 + N; S1[i0] : i0 >= 0 and i0 <= -1 + N; S3[i0] : i0 >= 0 and i0 <= -1 + N; S2[i0, i1] : i0 >= 0 and i0 <= -1 + N and i1 >= i0 and i1 <= -1 + M; S6[i0, i1] : i0 >= 0 and i1 >= 1 + i0 and i1 <= -1 + N; S9[i0, i1, i2] : i0 >= 0 and i1 >= 1 + i0 and i1 <= -1 + N and i2 >= i0 and i2 <= -1 + M; S4[i0, i1] : i0 >= 0 and i0 <= -1 + N and i1 >= i0 and i1 <= -1 + M; S8[i0, i1] : i0 >= 0 and i1 >= 1 + i0 and i1 <= -1 + N; S10[i0] : i0 >= 0 and i0 <= -1 + N; S7[i0, i1, i2] : i0 >= 0 and i1 >= 1 + i0 and i1 <= -1 + N and i2 >= i0 and i2 <= -1 + M }" +child: + context: "[M, N] -> { [] }" + child: + schedule: "[M, N] -> [{ S3[i0] -> [(1 + i0)]; S10[i0] -> [(1 + i0)]; S5[i0] -> [(1 + i0)]; S7[i0, i1, i2] -> [(2 + i0)]; S9[i0, i1, i2] -> [(2 + i0)]; S2[i0, i1] -> [(1 + i0)]; S4[i0, i1] -> [(1 + i0)]; S8[i0, i1] -> [(2 + i0)]; S1[i0] -> [(i0)]; S6[i0, i1] -> [(2 + i0)] }]" + options: "[M, N] -> { separate[i0] }" + child: + sequence: + - filter: "[M, N] -> { S6[i0, i1]; S9[i0, i1, i2]; S8[i0, i1]; S7[i0, i1, i2] }" + child: + schedule: "[M, N] -> [{ S7[i0, i1, i2] -> [(i1)]; S9[i0, i1, i2] -> [(i1)]; S8[i0, i1] -> [(i1)]; S6[i0, i1] -> [(i1)] }]" + options: "[M, N] -> { separate[i0] }" + child: + sequence: + - filter: "[M, N] -> { S6[i0, i1] }" + - filter: "[M, N] -> { S7[i0, i1, i2] }" + child: + schedule: "[M, N] -> [{ S7[i0, i1, i2] -> [(i2)] }]" + options: "[M, N] -> { separate[i0] }" + - filter: "[M, N] -> { S8[i0, i1] }" + - filter: "[M, N] -> { S9[i0, i1, i2] }" + child: + schedule: "[M, N] -> [{ S9[i0, i1, i2] -> [(i2)] }]" + options: "[M, N] -> { separate[i0] }" + - filter: "[M, N] -> { S2[i0, i1] }" + child: + schedule: "[M, N] -> [{ S2[i0, i1] -> [(i1)] }]" + options: "[M, N] -> { separate[i0] }" + - filter: "[M, N] -> { S3[i0] }" + - filter: "[M, N] -> { S4[i0, i1] }" + child: + schedule: "[M, N] -> [{ S4[i0, i1] -> [(i1)] }]" + options: "[M, N] -> { separate[i0] }" + - filter: "[M, N] -> { S10[i0] }" + - filter: "[M, N] -> { S1[i0] }" + - filter: "[M, N] -> { S5[i0] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-bastoul3.c b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-bastoul3.c new file mode 100644 index 000000000000..6d82ce4a89b5 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-bastoul3.c @@ -0,0 +1,3 @@ +for (int c0 = 3; c0 <= 9; c0 += 1) + for (int c1 = max(c0 - 6, -(c0 % 2) + 2); c1 <= min(3, c0 - 2); c1 += 2) + S1(c0, c1, (c0 - c1) / 2); diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-bastoul3.st b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-bastoul3.st new file mode 100644 index 000000000000..66fe7a33d312 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-bastoul3.st @@ -0,0 +1,6 @@ +domain: "{ S1[i0, i1, i2] : 2i2 = i0 - i1 and i1 >= 1 and i1 <= 3 and i1 <= -2 + i0 and i1 >= -6 + i0 }" +child: + context: "{ [] }" + child: + schedule: "[{ S1[i0, i1, i2] -> [(i0)] }, { S1[i0, i1, i2] -> [(i1)] }, { S1[i0, i1, i2] -> [(i2)] }]" + options: "{ separate[i0] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-cholesky2.c b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-cholesky2.c new file mode 100644 index 000000000000..73f7790c4c64 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-cholesky2.c @@ -0,0 +1,9 @@ +for (int c0 = 2; c0 < 3 * M; c0 += 1) { + if ((c0 + 1) % 3 == 0) + S1((c0 + 1) / 3); + for (int c1 = (c0 + 1) / 3 + 1; c1 <= min(M, c0 - 2); c1 += 1) + for (int c2 = -c1 + (c0 + c1 + 1) / 2 + 1; c2 <= min(c1, c0 - c1); c2 += 1) + S3(c0 - c1 - c2 + 1, c1, c2); + for (int c1 = -c0 + 2 * ((2 * c0 + 1) / 3) + 2; c1 <= min(M, c0); c1 += 2) + S2(((c0 - c1) / 2) + 1, c1); +} diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-cholesky2.st b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-cholesky2.st new file mode 100644 index 000000000000..4ae03d71f62e --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-cholesky2.st @@ -0,0 +1,20 @@ +domain: "[M] -> { S3[i0, i1, i2] : i0 >= 1 and i1 <= M and i2 >= 1 + i0 and i2 <= i1; S2[i0, i1] : i0 >= 1 and i1 >= 1 + i0 and i1 <= M; S1[i0] : i0 >= 1 and i0 <= M }" +child: + context: "[M] -> { [] }" + child: + schedule: "[M] -> [{ S1[i0] -> [(-1 + 3i0)]; S3[i0, i1, i2] -> [(-1 + i0 + i1 + i2)]; S2[i0, i1] -> [(-2 + 2i0 + i1)] }]" + options: "[M] -> { separate[i0] }" + child: + sequence: + - filter: "[M] -> { S1[i0] }" + - filter: "[M] -> { S3[i0, i1, i2] }" + child: + schedule: "[M] -> [{ S3[i0, i1, i2] -> [(i1)] }]" + options: "[M] -> { separate[i0] }" + child: + schedule: "[M] -> [{ S3[i0, i1, i2] -> [(i2)] }]" + options: "[M] -> { separate[i0] }" + - filter: "[M] -> { S2[i0, i1] }" + child: + schedule: "[M] -> [{ S2[i0, i1] -> [(i1)] }]" + options: "[M] -> { separate[i0] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-fusion1.c b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-fusion1.c new file mode 100644 index 000000000000..2296fdc03a1e --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-fusion1.c @@ -0,0 +1,6 @@ +for (int c0 = 0; c0 <= M; c0 += 1) + S1(c0); +for (int c0 = 1; c0 <= M; c0 += 1) + S2(c0); +for (int c0 = 0; c0 <= M; c0 += 1) + S3(c0); diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-fusion1.st b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-fusion1.st new file mode 100644 index 000000000000..25c0cfd07400 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-fusion1.st @@ -0,0 +1,17 @@ +domain: "[M] -> { S3[i0] : i0 >= 0 and i0 <= M; S2[i0] : i0 >= 1 and i0 <= M; S1[i0] : i0 >= 0 and i0 <= M }" +child: + context: "[M] -> { [] : M >= 1 }" + child: + sequence: + - filter: "[M] -> { S1[i0] }" + child: + schedule: "[M] -> [{ S1[i0] -> [(i0)] }]" + options: "[M] -> { separate[i0] }" + - filter: "[M] -> { S2[i0] }" + child: + schedule: "[M] -> [{ S2[i0] -> [(i0)] }]" + options: "[M] -> { separate[i0] }" + - filter: "[M] -> { S3[i0] }" + child: + schedule: "[M] -> [{ S3[i0] -> [(i0)] }]" + options: "[M] -> { separate[i0] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-fusion2.c b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-fusion2.c new file mode 100644 index 000000000000..e31aaec1ced6 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-fusion2.c @@ -0,0 +1,12 @@ +if (N >= 1) { + for (int c1 = 1; c1 <= M; c1 += 1) + S1(1, c1); + for (int c0 = 2; c0 <= N; c0 += 1) { + for (int c1 = 1; c1 <= M; c1 += 1) + S2(c0 - 1, c1); + for (int c1 = 1; c1 <= M; c1 += 1) + S1(c0, c1); + } + for (int c1 = 1; c1 <= M; c1 += 1) + S2(N, c1); +} diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-fusion2.st b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-fusion2.st new file mode 100644 index 000000000000..ee654244ae06 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-fusion2.st @@ -0,0 +1,16 @@ +domain: "[M, N] -> { S1[i0, i1] : i0 >= 1 and i0 <= N and i1 >= 1 and i1 <= M; S2[i0, i1] : i0 >= 1 and i0 <= N and i1 >= 1 and i1 <= M }" +child: + context: "[M, N] -> { [] }" + child: + schedule: "[M, N] -> [{ S1[i0, i1] -> [(i0)]; S2[i0, i1] -> [(1 + i0)] }]" + options: "[M, N] -> { separate[i0] }" + child: + sequence: + - filter: "[M, N] -> { S2[i0, i1] }" + child: + schedule: "[M, N] -> [{ S2[i0, i1] -> [(i1)] }]" + options: "[M, N] -> { separate[i0] }" + - filter: "[M, N] -> { S1[i0, i1] }" + child: + schedule: "[M, N] -> [{ S1[i0, i1] -> [(i1)] }]" + options: "[M, N] -> { separate[i0] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-jacobi2.c b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-jacobi2.c new file mode 100644 index 000000000000..6a04045d13fa --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-jacobi2.c @@ -0,0 +1,3 @@ +for (int c0 = 0; c0 < M; c0 += 1) + for (int c1 = 0; c1 < M; c1 += 1) + S1(c0, c1); diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-jacobi2.st b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-jacobi2.st new file mode 100644 index 000000000000..fe1230dbd384 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-jacobi2.st @@ -0,0 +1,9 @@ +domain: "[M] -> { S1[i0, i1] : i0 >= 0 and i0 <= -1 + M and i1 >= 0 and i1 <= -1 + M }" +child: + context: "[M] -> { [] : M >= 1 }" + child: + schedule: "[M] -> [{ S1[i0, i1] -> [(i0)] }]" + options: "[M] -> { separate[i0] }" + child: + schedule: "[M] -> [{ S1[i0, i1] -> [(i1)] }]" + options: "[M] -> { separate[i0] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-jacobi3.c b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-jacobi3.c new file mode 100644 index 000000000000..725357566a07 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-jacobi3.c @@ -0,0 +1,8 @@ +for (int c0 = 1; c0 <= M; c0 += 1) { + for (int c2 = 2; c2 < N; c2 += 1) + for (int c3 = 2; c3 < N; c3 += 1) + S1(c0, c2, c3); + for (int c2 = 2; c2 < N; c2 += 1) + for (int c3 = 2; c3 < N; c3 += 1) + S2(c0, c2, c3); +} diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-jacobi3.st b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-jacobi3.st new file mode 100644 index 000000000000..815ffe27c3c6 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-jacobi3.st @@ -0,0 +1,22 @@ +domain: "[M, N] -> { S2[i0, i1, i2] : i0 >= 1 and i0 <= M and i1 >= 2 and i1 <= -1 + N and i2 >= 2 and i2 <= -1 + N; S1[i0, i1, i2] : i0 >= 1 and i0 <= M and i1 >= 2 and i1 <= -1 + N and i2 >= 2 and i2 <= -1 + N }" +child: + context: "[M, N] -> { [] }" + child: + schedule: "[M, N] -> [{ S1[i0, i1, i2] -> [(2i0)]; S2[i0, i1, i2] -> [(1 + 2i0)] }]" + options: "[M, N] -> { separate[i0] }" + child: + sequence: + - filter: "[M, N] -> { S1[i0, i1, i2] }" + child: + schedule: "[M, N] -> [{ S1[i0, i1, i2] -> [(i1)] }]" + options: "[M, N] -> { separate[i0] }" + child: + schedule: "[M, N] -> [{ S1[i0, i1, i2] -> [(i2)] }]" + options: "[M, N] -> { separate[i0] }" + - filter: "[M, N] -> { S2[i0, i1, i2] }" + child: + schedule: "[M, N] -> [{ S2[i0, i1, i2] -> [(i1)] }]" + options: "[M, N] -> { separate[i0] }" + child: + schedule: "[M, N] -> [{ S2[i0, i1, i2] -> [(i2)] }]" + options: "[M, N] -> { separate[i0] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-lim-lam1.c b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-lim-lam1.c new file mode 100644 index 000000000000..e326941a3011 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-lim-lam1.c @@ -0,0 +1,10 @@ +for (int c0 = -99; c0 <= 100; c0 += 1) { + if (c0 <= 0) + S1(1, -c0 + 1); + for (int c1 = max(1, -2 * c0 + 3); c1 <= min(199, -2 * c0 + 199); c1 += 2) { + S2(((c1 - 1) / 2) + c0, (c1 + 1) / 2); + S1(((c1 + 1) / 2) + c0, (c1 + 1) / 2); + } + if (c0 >= 1) + S2(100, -c0 + 101); +} diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-lim-lam1.st b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-lim-lam1.st new file mode 100644 index 000000000000..cf7efee1552d --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-lim-lam1.st @@ -0,0 +1,13 @@ +domain: "{ S2[i0, i1] : i0 >= 1 and i0 <= 100 and i1 >= 1 and i1 <= 100; S1[i0, i1] : i0 >= 1 and i0 <= 100 and i1 >= 1 and i1 <= 100 }" +child: + context: "{ [] }" + child: + schedule: "[{ S1[i0, i1] -> [(i0 - i1)]; S2[i0, i1] -> [(1 + i0 - i1)] }]" + options: "{ separate[i0] }" + child: + schedule: "[{ S1[i0, i1] -> [(2i1)]; S2[i0, i1] -> [(-1 + 2i1)] }]" + options: "{ separate[i0] }" + child: + sequence: + - filter: "{ S1[i0, i1] }" + - filter: "{ S2[i0, i1] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-lim-lam2.c b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-lim-lam2.c new file mode 100644 index 000000000000..1f7eb4f07c0a --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-lim-lam2.c @@ -0,0 +1,8 @@ +for (int c0 = 1; c0 <= M; c0 += 1) + S1(c0); +for (int c0 = 1; c0 <= M; c0 += 1) + for (int c1 = 2; c1 <= N; c1 += 1) + S2(c0, c1); +for (int c0 = 1; c0 <= M; c0 += 1) + for (int c1 = 1; c1 < N; c1 += 1) + S3(c0, c1); diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-lim-lam2.st b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-lim-lam2.st new file mode 100644 index 000000000000..b53558fe0db3 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-lim-lam2.st @@ -0,0 +1,23 @@ +domain: "[M, N] -> { S3[i0, i1] : i0 >= 1 and i0 <= M and i1 >= 1 and i1 <= -1 + N; S1[i0] : i0 >= 1 and i0 <= M; S2[i0, i1] : i0 >= 1 and i0 <= M and i1 >= 2 and i1 <= N }" +child: + context: "[M, N] -> { [] : M >= 1 and N >= 1 }" + child: + sequence: + - filter: "[M, N] -> { S1[i0] }" + child: + schedule: "[M, N] -> [{ S1[i0] -> [(i0)] }]" + options: "[M, N] -> { separate[i0] }" + - filter: "[M, N] -> { S2[i0, i1] }" + child: + schedule: "[M, N] -> [{ S2[i0, i1] -> [(i0)] }]" + options: "[M, N] -> { separate[i0] }" + child: + schedule: "[M, N] -> [{ S2[i0, i1] -> [(i1)] }]" + options: "[M, N] -> { separate[i0] }" + - filter: "[M, N] -> { S3[i0, i1] }" + child: + schedule: "[M, N] -> [{ S3[i0, i1] -> [(i0)] }]" + options: "[M, N] -> { separate[i0] }" + child: + schedule: "[M, N] -> [{ S3[i0, i1] -> [(i1)] }]" + options: "[M, N] -> { separate[i0] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-lim-lam3.c b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-lim-lam3.c new file mode 100644 index 000000000000..9d290b514f30 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-lim-lam3.c @@ -0,0 +1,11 @@ +for (int c0 = 5; c0 <= 5 * M; c0 += 1) { + for (int c1 = max(2, floord(-M + c0, 4)); c1 < min(-((5 * M - c0 + 1) % 2) + M, (c0 + 1) / 3 - 2); c1 += 1) + for (int c2 = max(1, -M - c1 + (M + c0) / 2 - 2); c2 < min(c1, -2 * c1 + (c0 + c1) / 2 - 2); c2 += 1) + S1(c0 - 2 * c1 - 2 * c2 - 5, c1, c2); + for (int c1 = max(1, floord(-M + c0, 4)); c1 < (c0 + 1) / 5; c1 += 1) + S2(c0 - 4 * c1 - 3, c1); + if (c0 % 5 == 0) + S4(c0 / 5); + for (int c1 = max(-3 * M - c0 + 3 * ((M + c0) / 2) + 1, -((c0 - 1) % 3) + 3); c1 < (c0 + 1) / 5; c1 += 3) + S3((c0 - 2 * c1 - 1) / 3, c1); +} diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-lim-lam3.st b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-lim-lam3.st new file mode 100644 index 000000000000..cedd5e5da759 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-lim-lam3.st @@ -0,0 +1,23 @@ +domain: "[M] -> { S4[i0] : i0 >= 1 and i0 <= M; S3[i0, i1] : i0 <= M and i1 >= 1 and i1 <= -1 + i0; S2[i0, i1] : i0 <= M and i1 >= 1 and i1 <= -1 + i0; S1[i0, i1, i2] : i0 <= M and i1 <= -1 + i0 and i2 >= 1 and i2 <= -1 + i1 }" +child: + context: "[M] -> { [] : M >= 1 }" + child: + schedule: "[M] -> [{ S4[i0] -> [(5i0)]; S1[i0, i1, i2] -> [(5 + i0 + 2i1 + 2i2)]; S3[i0, i1] -> [(1 + 3i0 + 2i1)]; S2[i0, i1] -> [(3 + i0 + 4i1)] }]" + options: "[M] -> { separate[i0] }" + child: + sequence: + - filter: "[M] -> { S1[i0, i1, i2] }" + child: + schedule: "[M] -> [{ S1[i0, i1, i2] -> [(i1)] }]" + options: "[M] -> { separate[i0] }" + child: + schedule: "[M] -> [{ S1[i0, i1, i2] -> [(i2)] }]" + options: "[M] -> { separate[i0] }" + - filter: "[M] -> { S2[i0, i1] }" + child: + schedule: "[M] -> [{ S2[i0, i1] -> [(i1)] }]" + options: "[M] -> { separate[i0] }" + - filter: "[M] -> { S4[i0]; S3[i0, i1] }" + child: + schedule: "[M] -> [{ S4[i0] -> [(0)]; S3[i0, i1] -> [(i1)] }]" + options: "[M] -> { separate[i0] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-lim-lam4.c b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-lim-lam4.c new file mode 100644 index 000000000000..ed00e9977290 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-lim-lam4.c @@ -0,0 +1,10 @@ +for (int c0 = 1; c0 < 2 * M - 1; c0 += 1) { + for (int c1 = max(-M + 1, -c0 + 1); c1 < 0; c1 += 1) { + for (int c3 = max(1, -M + c0 + 1); c3 <= min(M - 1, c0 + c1); c3 += 1) + S1(c3, c0 + c1 - c3, -c1); + for (int c2 = max(-M + c0 + 1, -c1); c2 < min(M, c0); c2 += 1) + S2(c0 - c2, c1 + c2, c2); + } + for (int c3 = max(1, -M + c0 + 1); c3 <= min(M - 1, c0); c3 += 1) + S1(c3, c0 - c3, 0); +} diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-lim-lam4.st b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-lim-lam4.st new file mode 100644 index 000000000000..14b0052e55d8 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-lim-lam4.st @@ -0,0 +1,19 @@ +domain: "[M] -> { S2[i0, i1, i2] : i0 >= 1 and i0 <= -1 + M and i1 >= 0 and i2 >= 1 + i1 and i2 <= -1 + M; S1[i0, i1, i2] : i0 >= 1 and i0 <= -1 + M and i1 >= 0 and i2 >= 0 and i2 <= -1 + M - i1 }" +child: + context: "[M] -> { [] }" + child: + schedule: "[M] -> [{ S1[i0, i1, i2] -> [(i0 + i1 + i2)]; S2[i0, i1, i2] -> [(i0 + i2)] }]" + options: "[M] -> { separate[i0] }" + child: + schedule: "[M] -> [{ S1[i0, i1, i2] -> [(-i2)]; S2[i0, i1, i2] -> [(i1 - i2)] }]" + options: "[M] -> { separate[i0] }" + child: + sequence: + - filter: "[M] -> { S1[i0, i1, i2] }" + child: + schedule: "[M] -> [{ S1[i0, i1, i2] -> [(i2)] }]" + options: "[M] -> { separate[i0] }" + - filter: "[M] -> { S2[i0, i1, i2] }" + child: + schedule: "[M] -> [{ S2[i0, i1, i2] -> [(i2)] }]" + options: "[M] -> { separate[i0] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-lim-lam5.c b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-lim-lam5.c new file mode 100644 index 000000000000..08cae75e6ba1 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-lim-lam5.c @@ -0,0 +1,9 @@ +for (int c0 = 1; c0 <= M; c0 += 1) + for (int c1 = 1; c1 <= M; c1 += 1) + S1(c0, c1); +for (int c0 = 1; c0 <= M; c0 += 1) + for (int c1 = 1; c1 <= M; c1 += 1) + S2(c0, c1); +for (int c0 = 1; c0 <= M; c0 += 1) + for (int c1 = 1; c1 <= M; c1 += 1) + S3(c0, c1); diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-lim-lam5.st b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-lim-lam5.st new file mode 100644 index 000000000000..5684455278c1 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-lim-lam5.st @@ -0,0 +1,26 @@ +domain: "[M] -> { S1[i0, i1] : i0 >= 1 and i0 <= M and i1 >= 1 and i1 <= M; S3[i0, i1] : i0 >= 1 and i0 <= M and i1 >= 1 and i1 <= M; S2[i0, i1] : i0 >= 1 and i0 <= M and i1 >= 1 and i1 <= M }" +child: + context: "[M] -> { [] }" + child: + sequence: + - filter: "[M] -> { S1[i0, i1] }" + child: + schedule: "[M] -> [{ S1[i0, i1] -> [(i0)] }]" + options: "[M] -> { separate[i0] }" + child: + schedule: "[M] -> [{ S1[i0, i1] -> [(i1)] }]" + options: "[M] -> { separate[i0] }" + - filter: "[M] -> { S2[i0, i1] }" + child: + schedule: "[M] -> [{ S2[i0, i1] -> [(i0)] }]" + options: "[M] -> { separate[i0] }" + child: + schedule: "[M] -> [{ S2[i0, i1] -> [(i1)] }]" + options: "[M] -> { separate[i0] }" + - filter: "[M] -> { S3[i0, i1] }" + child: + schedule: "[M] -> [{ S3[i0, i1] -> [(i0)] }]" + options: "[M] -> { separate[i0] }" + child: + schedule: "[M] -> [{ S3[i0, i1] -> [(i1)] }]" + options: "[M] -> { separate[i0] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-lim-lam6.c b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-lim-lam6.c new file mode 100644 index 000000000000..08abc407623c --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-lim-lam6.c @@ -0,0 +1,6 @@ +for (int c0 = 0; c0 <= M; c0 += 1) + for (int c1 = 1; c1 <= M; c1 += 1) + S1(c0, c1); +for (int c0 = 0; c0 <= M; c0 += 1) + for (int c1 = 1; c1 <= M; c1 += 1) + S2(c1, c0); diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-lim-lam6.st b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-lim-lam6.st new file mode 100644 index 000000000000..3119ef13fa89 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-lim-lam6.st @@ -0,0 +1,19 @@ +domain: "[M] -> { S1[i0, i1] : i0 >= 0 and i0 <= M and i1 >= 1 and i1 <= M; S2[i0, i1] : i0 >= 1 and i0 <= M and i1 >= 0 and i1 <= M }" +child: + context: "[M] -> { [] }" + child: + sequence: + - filter: "[M] -> { S1[i0, i1] }" + child: + schedule: "[M] -> [{ S1[i0, i1] -> [(i0)] }]" + options: "[M] -> { separate[i0] }" + child: + schedule: "[M] -> [{ S1[i0, i1] -> [(i1)] }]" + options: "[M] -> { separate[i0] }" + - filter: "[M] -> { S2[i0, i1] }" + child: + schedule: "[M] -> [{ S2[i0, i1] -> [(i1)] }]" + options: "[M] -> { separate[i0] }" + child: + schedule: "[M] -> [{ S2[i0, i1] -> [(i0)] }]" + options: "[M] -> { separate[i0] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-liu-zhuge1.c b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-liu-zhuge1.c new file mode 100644 index 000000000000..3de60e1350d5 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-liu-zhuge1.c @@ -0,0 +1,19 @@ +if (M >= 0 && N >= 0) + for (int c0 = -4; c0 <= 3 * M + N; c0 += 1) { + if (3 * M >= c0 + 4 && (c0 + 1) % 3 == 0) { + S1((c0 + 4) / 3, 0); + } else if (c0 >= 3 * M) { + S2(M, -3 * M + c0); + } + for (int c1 = max(-3 * M + c0 + 3, (c0 + 6) % 3); c1 <= min(N - 1, c0); c1 += 3) { + S2((c0 - c1) / 3, c1); + S1(((c0 - c1) / 3) + 1, c1 + 1); + } + if (N >= c0 + 4 && c0 >= -3) { + S1(0, c0 + 4); + } else if (3 * M + N >= c0 + 3 && c0 >= N && (N - c0) % 3 == 0) { + S2((-N + c0) / 3, N); + } + for (int c1 = max(-3 * M + c0, (c0 + 6) % 3); c1 <= min(N, c0); c1 += 3) + S3((c0 - c1) / 3, c1); + } diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-liu-zhuge1.st b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-liu-zhuge1.st new file mode 100644 index 000000000000..e915285f5721 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-liu-zhuge1.st @@ -0,0 +1,16 @@ +domain: "[M, N] -> { S3[i0, i1] : i0 >= 0 and i0 <= M and i1 >= 0 and i1 <= N; S1[i0, i1] : i0 >= 0 and i0 <= M and i1 >= 0 and i1 <= N; S2[i0, i1] : i0 >= 0 and i0 <= M and i1 >= 0 and i1 <= N }" +child: + context: "[M, N] -> { [] }" + child: + schedule: "[M, N] -> [{ S1[i0, i1] -> [(-4 + 3i0 + i1)]; S2[i0, i1] -> [(3i0 + i1)]; S3[i0, i1] -> [(3i0 + i1)] }]" + options: "[M, N] -> { separate[i0] }" + child: + sequence: + - filter: "[M, N] -> { S1[i0, i1]; S2[i0, i1] }" + child: + schedule: "[M, N] -> [{ S1[i0, i1] -> [(i1)]; S2[i0, i1] -> [(i1)] }]" + options: "[M, N] -> { separate[i0] }" + - filter: "[M, N] -> { S3[i0, i1] }" + child: + schedule: "[M, N] -> [{ S3[i0, i1] -> [(i1)] }]" + options: "[M, N] -> { separate[i0] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-loechner3.c b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-loechner3.c new file mode 100644 index 000000000000..a164372c8130 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-loechner3.c @@ -0,0 +1,4 @@ +for (int c0 = 1; c0 <= M; c0 += 1) + for (int c1 = 2; c1 <= M + c0; c1 += 1) + for (int c2 = max(1, -c0 + c1); c2 <= min(M, c1 - 1); c2 += 1) + S1(c0, c2, c1 - c2); diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-loechner3.st b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-loechner3.st new file mode 100644 index 000000000000..90b561a7b9d8 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-loechner3.st @@ -0,0 +1,12 @@ +domain: "[M] -> { S1[i0, i1, i2] : i0 <= M and i1 >= 1 and i1 <= M and i2 >= 1 and i2 <= i0 }" +child: + context: "[M] -> { [] }" + child: + schedule: "[M] -> [{ S1[i0, i1, i2] -> [(i0)] }]" + options: "[M] -> { separate[i0] }" + child: + schedule: "[M] -> [{ S1[i0, i1, i2] -> [(i1 + i2)] }]" + options: "[M] -> { separate[i0] }" + child: + schedule: "[M] -> [{ S1[i0, i1, i2] -> [(i1)] }]" + options: "[M] -> { separate[i0] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-loechner4.c b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-loechner4.c new file mode 100644 index 000000000000..cf9c7642e3f0 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-loechner4.c @@ -0,0 +1,5 @@ +for (int c0 = 2; c0 <= 2 * M; c0 += 1) + for (int c1 = 1; c1 <= M; c1 += 1) + for (int c2 = 1; c2 <= M; c2 += 1) + for (int c3 = max(1, -M + c0); c3 <= min(M, c0 - 1); c3 += 1) + S1(c2, c1, c3, c0 - c3); diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-loechner4.st b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-loechner4.st new file mode 100644 index 000000000000..516da7ea8684 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-loechner4.st @@ -0,0 +1,15 @@ +domain: "[M] -> { S1[i0, i1, i2, i3] : i0 >= 1 and i0 <= M and i1 >= 1 and i1 <= M and i2 >= 1 and i2 <= M and i3 >= 1 and i3 <= M }" +child: + context: "[M] -> { [] }" + child: + schedule: "[M] -> [{ S1[i0, i1, i2, i3] -> [(i2 + i3)] }]" + options: "[M] -> { separate[i0] }" + child: + schedule: "[M] -> [{ S1[i0, i1, i2, i3] -> [(i1)] }]" + options: "[M] -> { separate[i0] }" + child: + schedule: "[M] -> [{ S1[i0, i1, i2, i3] -> [(i0)] }]" + options: "[M] -> { separate[i0] }" + child: + schedule: "[M] -> [{ S1[i0, i1, i2, i3] -> [(i2)] }]" + options: "[M] -> { separate[i0] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-loechner5.c b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-loechner5.c new file mode 100644 index 000000000000..6193503d8d05 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-loechner5.c @@ -0,0 +1,5 @@ +for (int c0 = 1; c0 <= M; c0 += 1) + for (int c1 = 1; c1 <= M; c1 += 1) + for (int c2 = 1; c2 <= M; c2 += 1) + for (int c3 = 1; c3 <= M; c3 += 1) + S1(c1, c2, c0, c3); diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-loechner5.st b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-loechner5.st new file mode 100644 index 000000000000..691d924c5f44 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-loechner5.st @@ -0,0 +1,15 @@ +domain: "[M] -> { S1[i0, i1, i2, i3] : i0 >= 1 and i0 <= M and i1 >= 1 and i1 <= M and i2 >= 1 and i2 <= M and i3 >= 1 and i3 <= M }" +child: + context: "[M] -> { [] }" + child: + schedule: "[M] -> [{ S1[i0, i1, i2, i3] -> [(i2)] }]" + options: "[M] -> { separate[i0] }" + child: + schedule: "[M] -> [{ S1[i0, i1, i2, i3] -> [(i0)] }]" + options: "[M] -> { separate[i0] }" + child: + schedule: "[M] -> [{ S1[i0, i1, i2, i3] -> [(i1)] }]" + options: "[M] -> { separate[i0] }" + child: + schedule: "[M] -> [{ S1[i0, i1, i2, i3] -> [(i3)] }]" + options: "[M] -> { separate[i0] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-long.c b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-long.c new file mode 100644 index 000000000000..e929c56428cc --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-long.c @@ -0,0 +1,14 @@ +for (int c0 = 1; c0 < O; c0 += 1) { + for (int c1 = Q; c1 < N; c1 += 1) { + for (int c2 = P; c2 < M; c2 += 1) + S1(c0, c1, c2); + for (int c2 = 1; c2 < M; c2 += 1) + S2(c0, c1, c2); + } + for (int c1 = 1; c1 < N; c1 += 1) { + for (int c2 = P; c2 < M; c2 += 1) + S3(c0, c1, c2); + for (int c2 = 1; c2 < M; c2 += 1) + S4(c0, c1, c2); + } +} diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-long.st b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-long.st new file mode 100644 index 000000000000..5a292abdbe26 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-long.st @@ -0,0 +1,36 @@ +domain: "[M, N, O, P, Q, R, S, T, U] -> { S1[i0, i1, i2] : i0 >= 1 and i0 <= -1 + O and i1 >= Q and i1 <= -1 + N and i2 >= P and i2 <= -1 + M; S3[i0, i1, i2] : i0 >= 1 and i0 <= -1 + O and i1 >= 1 and i1 <= -1 + N and i2 >= P and i2 <= -1 + M; S4[i0, i1, i2] : i0 >= 1 and i0 <= -1 + O and i1 >= 1 and i1 <= -1 + N and i2 >= 1 and i2 <= -1 + M; S2[i0, i1, i2] : i0 >= 1 and i0 <= -1 + O and i1 >= Q and i1 <= -1 + N and i2 >= 1 and i2 <= -1 + M }" +child: + context: "[M, N, O, P, Q, R, S, T, U] -> { [] : M >= 10 and N >= 10 and O >= 10 and P >= 1 and P <= 2 and Q >= 1 and Q <= 2 and R >= 1 and R <= 2 and S >= 0 and S <= 1 and T >= 0 and T <= 1 and U >= 0 and U <= 1 }" + child: + schedule: "[M, N, O, P, Q, R, S, T, U] -> [{ S4[i0, i1, i2] -> [(i0)]; S2[i0, i1, i2] -> [(i0)]; S1[i0, i1, i2] -> [(i0)]; S3[i0, i1, i2] -> [(i0)] }]" + options: "[M, N, O, P, Q, R, S, T, U] -> { separate[i0] }" + child: + sequence: + - filter: "[M, N, O, P, Q, R, S, T, U] -> { S1[i0, i1, i2]; S2[i0, i1, i2] }" + child: + schedule: "[M, N, O, P, Q, R, S, T, U] -> [{ S2[i0, i1, i2] -> [(i1)]; S1[i0, i1, i2] -> [(i1)] }]" + options: "[M, N, O, P, Q, R, S, T, U] -> { separate[i0] }" + child: + sequence: + - filter: "[M, N, O, P, Q, R, S, T, U] -> { S1[i0, i1, i2] }" + child: + schedule: "[M, N, O, P, Q, R, S, T, U] -> [{ S1[i0, i1, i2] -> [(i2)] }]" + options: "[M, N, O, P, Q, R, S, T, U] -> { separate[i0] }" + - filter: "[M, N, O, P, Q, R, S, T, U] -> { S2[i0, i1, i2] }" + child: + schedule: "[M, N, O, P, Q, R, S, T, U] -> [{ S2[i0, i1, i2] -> [(i2)] }]" + options: "[M, N, O, P, Q, R, S, T, U] -> { separate[i0] }" + - filter: "[M, N, O, P, Q, R, S, T, U] -> { S3[i0, i1, i2]; S4[i0, i1, i2] }" + child: + schedule: "[M, N, O, P, Q, R, S, T, U] -> [{ S4[i0, i1, i2] -> [(i1)]; S3[i0, i1, i2] -> [(i1)] }]" + options: "[M, N, O, P, Q, R, S, T, U] -> { separate[i0] }" + child: + sequence: + - filter: "[M, N, O, P, Q, R, S, T, U] -> { S3[i0, i1, i2] }" + child: + schedule: "[M, N, O, P, Q, R, S, T, U] -> [{ S3[i0, i1, i2] -> [(i2)] }]" + options: "[M, N, O, P, Q, R, S, T, U] -> { separate[i0] }" + - filter: "[M, N, O, P, Q, R, S, T, U] -> { S4[i0, i1, i2] }" + child: + schedule: "[M, N, O, P, Q, R, S, T, U] -> [{ S4[i0, i1, i2] -> [(i2)] }]" + options: "[M, N, O, P, Q, R, S, T, U] -> { separate[i0] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-mg-interp.c b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-mg-interp.c new file mode 100644 index 000000000000..a0bd219ac9c5 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-mg-interp.c @@ -0,0 +1,83 @@ +if (N >= 2) + for (int c0 = 1; c0 < O; c0 += 1) { + for (int c3 = 1; c3 <= M; c3 += 1) + S1(c0, 1, c3); + for (int c3 = 1; c3 < M; c3 += 1) { + S6(c0, 1, c3); + S7(c0, 1, c3); + } + if (N >= 3) { + for (int c3 = 1; c3 <= M; c3 += 1) + S3(c0, 1, c3); + for (int c3 = 1; c3 <= M; c3 += 1) + S1(c0, 2, c3); + for (int c3 = 1; c3 < M; c3 += 1) { + S6(c0, 2, c3); + S7(c0, 2, c3); + } + for (int c3 = 1; c3 < M; c3 += 1) + S11(c0, 1, c3); + } else { + for (int c3 = 1; c3 <= M; c3 += 1) + S3(c0, 1, c3); + for (int c3 = 1; c3 < M; c3 += 1) + S11(c0, 1, c3); + } + for (int c1 = 3; c1 < 2 * N - 4; c1 += 2) { + for (int c3 = 1; c3 < M; c3 += 1) + S10(c0, (c1 - 1) / 2, c3); + for (int c3 = 1; c3 <= M; c3 += 1) + S3(c0, (c1 + 1) / 2, c3); + for (int c3 = 1; c3 <= M; c3 += 1) + S1(c0, (c1 + 3) / 2, c3); + for (int c3 = 1; c3 < M; c3 += 1) { + S6(c0, (c1 + 3) / 2, c3); + S7(c0, (c1 + 3) / 2, c3); + } + for (int c3 = 1; c3 < M; c3 += 1) + S11(c0, (c1 + 1) / 2, c3); + } + if (N >= 3) { + for (int c3 = 1; c3 < M; c3 += 1) + S10(c0, N - 2, c3); + for (int c3 = 1; c3 <= M; c3 += 1) + S3(c0, N - 1, c3); + for (int c3 = 1; c3 < M; c3 += 1) + S11(c0, N - 1, c3); + } + for (int c3 = 1; c3 < M; c3 += 1) + S10(c0, N - 1, c3); + } +for (int c0 = 1; c0 < O; c0 += 1) + for (int c1 = 1; c1 < N; c1 += 1) { + for (int c3 = 1; c3 <= M; c3 += 1) + S2(c0, c1, c3); + for (int c3 = 1; c3 < M; c3 += 1) + S8(c0, c1, c3); + for (int c3 = 1; c3 < M; c3 += 1) + S9(c0, c1, c3); + } +for (int c0 = 1; c0 < O; c0 += 1) + for (int c1 = 1; c1 < N; c1 += 1) + for (int c2 = 1; c2 < M; c2 += 1) + S4(c0, c1, c2); +for (int c0 = 1; c0 < O; c0 += 1) + for (int c1 = 1; c1 < N; c1 += 1) + for (int c2 = 1; c2 < M; c2 += 1) + S5(c0, c1, c2); +for (int c0 = R; c0 < O; c0 += 1) + for (int c1 = Q; c1 < N; c1 += 1) + for (int c2 = P; c2 < M; c2 += 1) + S12(c0, c1, c2); +for (int c0 = R; c0 < O; c0 += 1) + for (int c1 = Q; c1 < N; c1 += 1) + for (int c2 = 1; c2 < M; c2 += 1) + S13(c0, c1, c2); +for (int c0 = R; c0 < O; c0 += 1) + for (int c1 = 1; c1 < N; c1 += 1) + for (int c2 = P; c2 < M; c2 += 1) + S14(c0, c1, c2); +for (int c0 = R; c0 < O; c0 += 1) + for (int c1 = 1; c1 < N; c1 += 1) + for (int c2 = 1; c2 < M; c2 += 1) + S15(c0, c1, c2); diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-mg-interp.st b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-mg-interp.st new file mode 100644 index 000000000000..2d6301506f28 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-mg-interp.st @@ -0,0 +1,115 @@ +domain: "[M, N, O, P, Q, R, S, T, U] -> { S8[i0, i1, i2] : i0 >= 1 and i0 <= -1 + O and i1 >= 1 and i1 <= -1 + N and i2 >= 1 and i2 <= -1 + M; S12[i0, i1, i2] : i0 >= R and i0 <= -1 + O and i1 >= Q and i1 <= -1 + N and i2 >= P and i2 <= -1 + M; S5[i0, i1, i2] : i0 >= 1 and i0 <= -1 + O and i1 >= 1 and i1 <= -1 + N and i2 >= 1 and i2 <= -1 + M; S10[i0, i1, i2] : i0 >= 1 and i0 <= -1 + O and i1 >= 1 and i1 <= -1 + N and i2 >= 1 and i2 <= -1 + M; S6[i0, i1, i2] : i0 >= 1 and i0 <= -1 + O and i1 >= 1 and i1 <= -1 + N and i2 >= 1 and i2 <= -1 + M; S1[i0, i1, i2] : i0 >= 1 and i0 <= -1 + O and i1 >= 1 and i1 <= -1 + N and i2 >= 1 and i2 <= M; S3[i0, i1, i2] : i0 >= 1 and i0 <= -1 + O and i1 >= 1 and i1 <= -1 + N and i2 >= 1 and i2 <= M; S4[i0, i1, i2] : i0 >= 1 and i0 <= -1 + O and i1 >= 1 and i1 <= -1 + N and i2 >= 1 and i2 <= -1 + M; S15[i0, i1, i2] : i0 >= R and i0 <= -1 + O and i1 >= 1 and i1 <= -1 + N and i2 >= 1 and i2 <= -1 + M; S11[i0, i1, i2] : i0 >= 1 and i0 <= -1 + O and i1 >= 1 and i1 <= -1 + N and i2 >= 1 and i2 <= -1 + M; S2[i0, i1, i2] : i0 >= 1 and i0 <= -1 + O and i1 >= 1 and i1 <= -1 + N and i2 >= 1 and i2 <= M; S7[i0, i1, i2] : i0 >= 1 and i0 <= -1 + O and i1 >= 1 and i1 <= -1 + N and i2 >= 1 and i2 <= -1 + M; S9[i0, i1, i2] : i0 >= 1 and i0 <= -1 + O and i1 >= 1 and i1 <= -1 + N and i2 >= 1 and i2 <= -1 + M; S14[i0, i1, i2] : i0 >= R and i0 <= -1 + O and i1 >= 1 and i1 <= -1 + N and i2 >= P and i2 <= -1 + M; S13[i0, i1, i2] : i0 >= R and i0 <= -1 + O and i1 >= Q and i1 <= -1 + N and i2 >= 1 and i2 <= -1 + M }" +child: + context: "[M, N, O, P, Q, R, S, T, U] -> { [] }" + child: + sequence: + - filter: "[M, N, O, P, Q, R, S, T, U] -> { S10[i0, i1, i2]; S6[i0, i1, i2]; S3[i0, i1, i2]; S1[i0, i1, i2]; S11[i0, i1, i2]; S7[i0, i1, i2] }" + child: + schedule: "[M, N, O, P, Q, R, S, T, U] -> [{ S11[i0, i1, i2] -> [(i0)]; S1[i0, i1, i2] -> [(i0)]; S6[i0, i1, i2] -> [(i0)]; S10[i0, i1, i2] -> [(i0)]; S3[i0, i1, i2] -> [(i0)]; S7[i0, i1, i2] -> [(i0)] }]" + options: "[M, N, O, P, Q, R, S, T, U] -> { separate[i0] }" + child: + schedule: "[M, N, O, P, Q, R, S, T, U] -> [{ S11[i0, i1, i2] -> [(2i1)]; S1[i0, i1, i2] -> [(-3 + 2i1)]; S6[i0, i1, i2] -> [(-2 + 2i1)]; S10[i0, i1, i2] -> [(1 + 2i1)]; S3[i0, i1, i2] -> [(-1 + 2i1)]; S7[i0, i1, i2] -> [(-2 + 2i1)] }]" + options: "[M, N, O, P, Q, R, S, T, U] -> { separate[i0] }" + child: + sequence: + - filter: "[M, N, O, P, Q, R, S, T, U] -> { S10[i0, i1, i2] }" + child: + schedule: "[M, N, O, P, Q, R, S, T, U] -> [{ S10[i0, i1, i2] -> [(i2)] }]" + options: "[M, N, O, P, Q, R, S, T, U] -> { separate[i0] }" + - filter: "[M, N, O, P, Q, R, S, T, U] -> { S3[i0, i1, i2] }" + child: + schedule: "[M, N, O, P, Q, R, S, T, U] -> [{ S3[i0, i1, i2] -> [(i2)] }]" + options: "[M, N, O, P, Q, R, S, T, U] -> { separate[i0] }" + - filter: "[M, N, O, P, Q, R, S, T, U] -> { S6[i0, i1, i2]; S1[i0, i1, i2]; S7[i0, i1, i2] }" + child: + schedule: "[M, N, O, P, Q, R, S, T, U] -> [{ S1[i0, i1, i2] -> [(i2)]; S6[i0, i1, i2] -> [(i2)]; S7[i0, i1, i2] -> [(i2)] }]" + options: "[M, N, O, P, Q, R, S, T, U] -> { separate[i0] }" + child: + sequence: + - filter: "[M, N, O, P, Q, R, S, T, U] -> { S6[i0, i1, i2]; S1[i0, i1, i2] }" + - filter: "[M, N, O, P, Q, R, S, T, U] -> { S7[i0, i1, i2] }" + - filter: "[M, N, O, P, Q, R, S, T, U] -> { S11[i0, i1, i2] }" + child: + schedule: "[M, N, O, P, Q, R, S, T, U] -> [{ S11[i0, i1, i2] -> [(i2)] }]" + options: "[M, N, O, P, Q, R, S, T, U] -> { separate[i0] }" + - filter: "[M, N, O, P, Q, R, S, T, U] -> { S2[i0, i1, i2]; S9[i0, i1, i2]; S8[i0, i1, i2] }" + child: + schedule: "[M, N, O, P, Q, R, S, T, U] -> [{ S2[i0, i1, i2] -> [(i0)]; S8[i0, i1, i2] -> [(i0)]; S9[i0, i1, i2] -> [(i0)] }]" + options: "[M, N, O, P, Q, R, S, T, U] -> { separate[i0] }" + child: + schedule: "[M, N, O, P, Q, R, S, T, U] -> [{ S2[i0, i1, i2] -> [(2i1)]; S8[i0, i1, i2] -> [(2i1)]; S9[i0, i1, i2] -> [(1 + 2i1)] }]" + options: "[M, N, O, P, Q, R, S, T, U] -> { separate[i0] }" + child: + sequence: + - filter: "[M, N, O, P, Q, R, S, T, U] -> { S2[i0, i1, i2] }" + child: + schedule: "[M, N, O, P, Q, R, S, T, U] -> [{ S2[i0, i1, i2] -> [(i2)] }]" + options: "[M, N, O, P, Q, R, S, T, U] -> { separate[i0] }" + - filter: "[M, N, O, P, Q, R, S, T, U] -> { S8[i0, i1, i2] }" + child: + schedule: "[M, N, O, P, Q, R, S, T, U] -> [{ S8[i0, i1, i2] -> [(i2)] }]" + options: "[M, N, O, P, Q, R, S, T, U] -> { separate[i0] }" + - filter: "[M, N, O, P, Q, R, S, T, U] -> { S9[i0, i1, i2] }" + child: + schedule: "[M, N, O, P, Q, R, S, T, U] -> [{ S9[i0, i1, i2] -> [(i2)] }]" + options: "[M, N, O, P, Q, R, S, T, U] -> { separate[i0] }" + - filter: "[M, N, O, P, Q, R, S, T, U] -> { S4[i0, i1, i2] }" + child: + schedule: "[M, N, O, P, Q, R, S, T, U] -> [{ S4[i0, i1, i2] -> [(i0)] }]" + options: "[M, N, O, P, Q, R, S, T, U] -> { separate[i0] }" + child: + schedule: "[M, N, O, P, Q, R, S, T, U] -> [{ S4[i0, i1, i2] -> [(i1)] }]" + options: "[M, N, O, P, Q, R, S, T, U] -> { separate[i0] }" + child: + schedule: "[M, N, O, P, Q, R, S, T, U] -> [{ S4[i0, i1, i2] -> [(i2)] }]" + options: "[M, N, O, P, Q, R, S, T, U] -> { separate[i0] }" + - filter: "[M, N, O, P, Q, R, S, T, U] -> { S5[i0, i1, i2] }" + child: + schedule: "[M, N, O, P, Q, R, S, T, U] -> [{ S5[i0, i1, i2] -> [(i0)] }]" + options: "[M, N, O, P, Q, R, S, T, U] -> { separate[i0] }" + child: + schedule: "[M, N, O, P, Q, R, S, T, U] -> [{ S5[i0, i1, i2] -> [(i1)] }]" + options: "[M, N, O, P, Q, R, S, T, U] -> { separate[i0] }" + child: + schedule: "[M, N, O, P, Q, R, S, T, U] -> [{ S5[i0, i1, i2] -> [(i2)] }]" + options: "[M, N, O, P, Q, R, S, T, U] -> { separate[i0] }" + - filter: "[M, N, O, P, Q, R, S, T, U] -> { S12[i0, i1, i2] }" + child: + schedule: "[M, N, O, P, Q, R, S, T, U] -> [{ S12[i0, i1, i2] -> [(i0)] }]" + options: "[M, N, O, P, Q, R, S, T, U] -> { separate[i0] }" + child: + schedule: "[M, N, O, P, Q, R, S, T, U] -> [{ S12[i0, i1, i2] -> [(i1)] }]" + options: "[M, N, O, P, Q, R, S, T, U] -> { separate[i0] }" + child: + schedule: "[M, N, O, P, Q, R, S, T, U] -> [{ S12[i0, i1, i2] -> [(i2)] }]" + options: "[M, N, O, P, Q, R, S, T, U] -> { separate[i0] }" + - filter: "[M, N, O, P, Q, R, S, T, U] -> { S13[i0, i1, i2] }" + child: + schedule: "[M, N, O, P, Q, R, S, T, U] -> [{ S13[i0, i1, i2] -> [(i0)] }]" + options: "[M, N, O, P, Q, R, S, T, U] -> { separate[i0] }" + child: + schedule: "[M, N, O, P, Q, R, S, T, U] -> [{ S13[i0, i1, i2] -> [(i1)] }]" + options: "[M, N, O, P, Q, R, S, T, U] -> { separate[i0] }" + child: + schedule: "[M, N, O, P, Q, R, S, T, U] -> [{ S13[i0, i1, i2] -> [(i2)] }]" + options: "[M, N, O, P, Q, R, S, T, U] -> { separate[i0] }" + - filter: "[M, N, O, P, Q, R, S, T, U] -> { S14[i0, i1, i2] }" + child: + schedule: "[M, N, O, P, Q, R, S, T, U] -> [{ S14[i0, i1, i2] -> [(i0)] }]" + options: "[M, N, O, P, Q, R, S, T, U] -> { separate[i0] }" + child: + schedule: "[M, N, O, P, Q, R, S, T, U] -> [{ S14[i0, i1, i2] -> [(i1)] }]" + options: "[M, N, O, P, Q, R, S, T, U] -> { separate[i0] }" + child: + schedule: "[M, N, O, P, Q, R, S, T, U] -> [{ S14[i0, i1, i2] -> [(i2)] }]" + options: "[M, N, O, P, Q, R, S, T, U] -> { separate[i0] }" + - filter: "[M, N, O, P, Q, R, S, T, U] -> { S15[i0, i1, i2] }" + child: + schedule: "[M, N, O, P, Q, R, S, T, U] -> [{ S15[i0, i1, i2] -> [(i0)] }]" + options: "[M, N, O, P, Q, R, S, T, U] -> { separate[i0] }" + child: + schedule: "[M, N, O, P, Q, R, S, T, U] -> [{ S15[i0, i1, i2] -> [(i1)] }]" + options: "[M, N, O, P, Q, R, S, T, U] -> { separate[i0] }" + child: + schedule: "[M, N, O, P, Q, R, S, T, U] -> [{ S15[i0, i1, i2] -> [(i2)] }]" + options: "[M, N, O, P, Q, R, S, T, U] -> { separate[i0] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-mg-interp2.c b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-mg-interp2.c new file mode 100644 index 000000000000..4b329e67fe52 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-mg-interp2.c @@ -0,0 +1,16 @@ +for (int c0 = 1; c0 < O; c0 += 1) + for (int c1 = Q; c1 < N; c1 += 1) + for (int c2 = P; c2 < M; c2 += 1) + S1(c0, c1, c2); +for (int c0 = 1; c0 < O; c0 += 1) + for (int c1 = Q; c1 < N; c1 += 1) + for (int c2 = 1; c2 < M; c2 += 1) + S2(c0, c1, c2); +for (int c0 = 1; c0 < O; c0 += 1) + for (int c1 = 1; c1 < N; c1 += 1) + for (int c2 = P; c2 < M; c2 += 1) + S3(c0, c1, c2); +for (int c0 = 1; c0 < O; c0 += 1) + for (int c1 = 1; c1 < N; c1 += 1) + for (int c2 = 1; c2 < M; c2 += 1) + S4(c0, c1, c2); diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-mg-interp2.st b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-mg-interp2.st new file mode 100644 index 000000000000..a2ea2b35eaf9 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-mg-interp2.st @@ -0,0 +1,45 @@ +domain: "[M, N, O, P, Q, R, S, T, U] -> { S1[i0, i1, i2] : i0 >= 1 and i0 <= -1 + O and i1 >= Q and i1 <= -1 + N and i2 >= P and i2 <= -1 + M; S3[i0, i1, i2] : i0 >= 1 and i0 <= -1 + O and i1 >= 1 and i1 <= -1 + N and i2 >= P and i2 <= -1 + M; S4[i0, i1, i2] : i0 >= 1 and i0 <= -1 + O and i1 >= 1 and i1 <= -1 + N and i2 >= 1 and i2 <= -1 + M; S2[i0, i1, i2] : i0 >= 1 and i0 <= -1 + O and i1 >= Q and i1 <= -1 + N and i2 >= 1 and i2 <= -1 + M }" +child: + context: "[M, N, O, P, Q, R, S, T, U] -> { [] }" + child: + sequence: + - filter: "[M, N, O, P, Q, R, S, T, U] -> { S1[i0, i1, i2] }" + child: + schedule: "[M, N, O, P, Q, R, S, T, U] -> [{ S1[i0, i1, i2] -> [(i0)] }]" + options: "[M, N, O, P, Q, R, S, T, U] -> { separate[i0] }" + child: + schedule: "[M, N, O, P, Q, R, S, T, U] -> [{ S1[i0, i1, i2] -> [(i1)] }]" + options: "[M, N, O, P, Q, R, S, T, U] -> { separate[i0] }" + child: + schedule: "[M, N, O, P, Q, R, S, T, U] -> [{ S1[i0, i1, i2] -> [(i2)] }]" + options: "[M, N, O, P, Q, R, S, T, U] -> { separate[i0] }" + - filter: "[M, N, O, P, Q, R, S, T, U] -> { S2[i0, i1, i2] }" + child: + schedule: "[M, N, O, P, Q, R, S, T, U] -> [{ S2[i0, i1, i2] -> [(i0)] }]" + options: "[M, N, O, P, Q, R, S, T, U] -> { separate[i0] }" + child: + schedule: "[M, N, O, P, Q, R, S, T, U] -> [{ S2[i0, i1, i2] -> [(i1)] }]" + options: "[M, N, O, P, Q, R, S, T, U] -> { separate[i0] }" + child: + schedule: "[M, N, O, P, Q, R, S, T, U] -> [{ S2[i0, i1, i2] -> [(i2)] }]" + options: "[M, N, O, P, Q, R, S, T, U] -> { separate[i0] }" + - filter: "[M, N, O, P, Q, R, S, T, U] -> { S3[i0, i1, i2] }" + child: + schedule: "[M, N, O, P, Q, R, S, T, U] -> [{ S3[i0, i1, i2] -> [(i0)] }]" + options: "[M, N, O, P, Q, R, S, T, U] -> { separate[i0] }" + child: + schedule: "[M, N, O, P, Q, R, S, T, U] -> [{ S3[i0, i1, i2] -> [(i1)] }]" + options: "[M, N, O, P, Q, R, S, T, U] -> { separate[i0] }" + child: + schedule: "[M, N, O, P, Q, R, S, T, U] -> [{ S3[i0, i1, i2] -> [(i2)] }]" + options: "[M, N, O, P, Q, R, S, T, U] -> { separate[i0] }" + - filter: "[M, N, O, P, Q, R, S, T, U] -> { S4[i0, i1, i2] }" + child: + schedule: "[M, N, O, P, Q, R, S, T, U] -> [{ S4[i0, i1, i2] -> [(i0)] }]" + options: "[M, N, O, P, Q, R, S, T, U] -> { separate[i0] }" + child: + schedule: "[M, N, O, P, Q, R, S, T, U] -> [{ S4[i0, i1, i2] -> [(i1)] }]" + options: "[M, N, O, P, Q, R, S, T, U] -> { separate[i0] }" + child: + schedule: "[M, N, O, P, Q, R, S, T, U] -> [{ S4[i0, i1, i2] -> [(i2)] }]" + options: "[M, N, O, P, Q, R, S, T, U] -> { separate[i0] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-mg-psinv.c b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-mg-psinv.c new file mode 100644 index 000000000000..cfb4045b270a --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-mg-psinv.c @@ -0,0 +1,9 @@ +for (int c0 = 2; c0 < O; c0 += 1) + for (int c1 = 3; c1 < 2 * N - 2; c1 += 2) { + for (int c3 = 1; c3 <= M; c3 += 1) { + S1(c0, (c1 + 1) / 2, c3); + S2(c0, (c1 + 1) / 2, c3); + } + for (int c3 = 2; c3 < M; c3 += 1) + S3(c0, (c1 + 1) / 2, c3); + } diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-mg-psinv.st b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-mg-psinv.st new file mode 100644 index 000000000000..c64638b4ea38 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-mg-psinv.st @@ -0,0 +1,23 @@ +domain: "[M, N, O] -> { S3[i0, i1, i2] : i0 >= 2 and i0 <= -1 + O and i1 >= 2 and i1 <= -1 + N and i2 >= 2 and i2 <= -1 + M; S2[i0, i1, i2] : i0 >= 2 and i0 <= -1 + O and i1 >= 2 and i1 <= -1 + N and i2 >= 1 and i2 <= M; S1[i0, i1, i2] : i0 >= 2 and i0 <= -1 + O and i1 >= 2 and i1 <= -1 + N and i2 >= 1 and i2 <= M }" +child: + context: "[M, N, O] -> { [] }" + child: + schedule: "[M, N, O] -> [{ S3[i0, i1, i2] -> [(i0)]; S2[i0, i1, i2] -> [(i0)]; S1[i0, i1, i2] -> [(i0)] }]" + options: "[M, N, O] -> { separate[i0] }" + child: + schedule: "[M, N, O] -> [{ S3[i0, i1, i2] -> [(2i1)]; S2[i0, i1, i2] -> [(-1 + 2i1)]; S1[i0, i1, i2] -> [(-1 + 2i1)] }]" + options: "[M, N, O] -> { separate[i0] }" + child: + sequence: + - filter: "[M, N, O] -> { S2[i0, i1, i2]; S1[i0, i1, i2] }" + child: + schedule: "[M, N, O] -> [{ S2[i0, i1, i2] -> [(i2)]; S1[i0, i1, i2] -> [(i2)] }]" + options: "[M, N, O] -> { separate[i0] }" + child: + sequence: + - filter: "[M, N, O] -> { S1[i0, i1, i2] }" + - filter: "[M, N, O] -> { S2[i0, i1, i2] }" + - filter: "[M, N, O] -> { S3[i0, i1, i2] }" + child: + schedule: "[M, N, O] -> [{ S3[i0, i1, i2] -> [(i2)] }]" + options: "[M, N, O] -> { separate[i0] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-mg-resid.c b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-mg-resid.c new file mode 100644 index 000000000000..cfb4045b270a --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-mg-resid.c @@ -0,0 +1,9 @@ +for (int c0 = 2; c0 < O; c0 += 1) + for (int c1 = 3; c1 < 2 * N - 2; c1 += 2) { + for (int c3 = 1; c3 <= M; c3 += 1) { + S1(c0, (c1 + 1) / 2, c3); + S2(c0, (c1 + 1) / 2, c3); + } + for (int c3 = 2; c3 < M; c3 += 1) + S3(c0, (c1 + 1) / 2, c3); + } diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-mg-resid.st b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-mg-resid.st new file mode 100644 index 000000000000..c64638b4ea38 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-mg-resid.st @@ -0,0 +1,23 @@ +domain: "[M, N, O] -> { S3[i0, i1, i2] : i0 >= 2 and i0 <= -1 + O and i1 >= 2 and i1 <= -1 + N and i2 >= 2 and i2 <= -1 + M; S2[i0, i1, i2] : i0 >= 2 and i0 <= -1 + O and i1 >= 2 and i1 <= -1 + N and i2 >= 1 and i2 <= M; S1[i0, i1, i2] : i0 >= 2 and i0 <= -1 + O and i1 >= 2 and i1 <= -1 + N and i2 >= 1 and i2 <= M }" +child: + context: "[M, N, O] -> { [] }" + child: + schedule: "[M, N, O] -> [{ S3[i0, i1, i2] -> [(i0)]; S2[i0, i1, i2] -> [(i0)]; S1[i0, i1, i2] -> [(i0)] }]" + options: "[M, N, O] -> { separate[i0] }" + child: + schedule: "[M, N, O] -> [{ S3[i0, i1, i2] -> [(2i1)]; S2[i0, i1, i2] -> [(-1 + 2i1)]; S1[i0, i1, i2] -> [(-1 + 2i1)] }]" + options: "[M, N, O] -> { separate[i0] }" + child: + sequence: + - filter: "[M, N, O] -> { S2[i0, i1, i2]; S1[i0, i1, i2] }" + child: + schedule: "[M, N, O] -> [{ S2[i0, i1, i2] -> [(i2)]; S1[i0, i1, i2] -> [(i2)] }]" + options: "[M, N, O] -> { separate[i0] }" + child: + sequence: + - filter: "[M, N, O] -> { S1[i0, i1, i2] }" + - filter: "[M, N, O] -> { S2[i0, i1, i2] }" + - filter: "[M, N, O] -> { S3[i0, i1, i2] }" + child: + schedule: "[M, N, O] -> [{ S3[i0, i1, i2] -> [(i2)] }]" + options: "[M, N, O] -> { separate[i0] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-mg-rprj3.c b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-mg-rprj3.c new file mode 100644 index 000000000000..e73ba5de5a56 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-mg-rprj3.c @@ -0,0 +1,35 @@ +if (M >= 2 && N >= 3) + for (int c0 = 2; c0 < O; c0 += 1) { + for (int c2 = 2; c2 <= M; c2 += 1) + S1(c0, 2, c2); + for (int c1 = 3; c1 < N; c1 += 1) { + for (int c2 = 2; c2 <= M; c2 += 1) + S2(c0, c1 - 1, c2); + if (M >= 3) + S4(c0, c1 - 1, 2); + for (int c2 = 2; c2 < M - 1; c2 += 1) { + S3(c0, c1 - 1, c2); + S5(c0, c1 - 1, c2); + S4(c0, c1 - 1, c2 + 1); + } + if (M >= 3) { + S3(c0, c1 - 1, M - 1); + S5(c0, c1 - 1, M - 1); + } + for (int c2 = 2; c2 <= M; c2 += 1) + S1(c0, c1, c2); + } + for (int c2 = 2; c2 <= M; c2 += 1) + S2(c0, N - 1, c2); + if (M >= 3) + S4(c0, N - 1, 2); + for (int c2 = 2; c2 < M - 1; c2 += 1) { + S3(c0, N - 1, c2); + S5(c0, N - 1, c2); + S4(c0, N - 1, c2 + 1); + } + if (M >= 3) { + S3(c0, N - 1, M - 1); + S5(c0, N - 1, M - 1); + } + } diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-mg-rprj3.st b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-mg-rprj3.st new file mode 100644 index 000000000000..d330a83f5a63 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-mg-rprj3.st @@ -0,0 +1,28 @@ +domain: "[M, N, O, P, Q, R] -> { S2[i0, i1, i2] : i0 >= 2 and i0 <= -1 + O and i1 >= 2 and i1 <= -1 + N and i2 >= 2 and i2 <= M; S4[i0, i1, i2] : i0 >= 2 and i0 <= -1 + O and i1 >= 2 and i1 <= -1 + N and i2 >= 2 and i2 <= -1 + M; S1[i0, i1, i2] : i0 >= 2 and i0 <= -1 + O and i1 >= 2 and i1 <= -1 + N and i2 >= 2 and i2 <= M; S5[i0, i1, i2] : i0 >= 2 and i0 <= -1 + O and i1 >= 2 and i1 <= -1 + N and i2 >= 2 and i2 <= -1 + M; S3[i0, i1, i2] : i0 >= 2 and i0 <= -1 + O and i1 >= 2 and i1 <= -1 + N and i2 >= 2 and i2 <= -1 + M }" +child: + context: "[M, N, O, P, Q, R] -> { [] }" + child: + schedule: "[M, N, O, P, Q, R] -> [{ S5[i0, i1, i2] -> [(i0)]; S3[i0, i1, i2] -> [(i0)]; S4[i0, i1, i2] -> [(i0)]; S1[i0, i1, i2] -> [(i0)]; S2[i0, i1, i2] -> [(i0)] }]" + options: "[M, N, O, P, Q, R] -> { separate[i0] }" + child: + schedule: "[M, N, O, P, Q, R] -> [{ S5[i0, i1, i2] -> [(1 + i1)]; S3[i0, i1, i2] -> [(1 + i1)]; S4[i0, i1, i2] -> [(1 + i1)]; S1[i0, i1, i2] -> [(i1)]; S2[i0, i1, i2] -> [(1 + i1)] }]" + options: "[M, N, O, P, Q, R] -> { separate[i0] }" + child: + sequence: + - filter: "[M, N, O, P, Q, R] -> { S2[i0, i1, i2] }" + child: + schedule: "[M, N, O, P, Q, R] -> [{ S2[i0, i1, i2] -> [(i2)] }]" + options: "[M, N, O, P, Q, R] -> { separate[i0] }" + - filter: "[M, N, O, P, Q, R] -> { S4[i0, i1, i2]; S5[i0, i1, i2]; S3[i0, i1, i2] }" + child: + schedule: "[M, N, O, P, Q, R] -> [{ S5[i0, i1, i2] -> [(i2)]; S3[i0, i1, i2] -> [(i2)]; S4[i0, i1, i2] -> [(-1 + i2)] }]" + options: "[M, N, O, P, Q, R] -> { separate[i0] }" + child: + sequence: + - filter: "[M, N, O, P, Q, R] -> { S3[i0, i1, i2] }" + - filter: "[M, N, O, P, Q, R] -> { S5[i0, i1, i2] }" + - filter: "[M, N, O, P, Q, R] -> { S4[i0, i1, i2] }" + - filter: "[M, N, O, P, Q, R] -> { S1[i0, i1, i2] }" + child: + schedule: "[M, N, O, P, Q, R] -> [{ S1[i0, i1, i2] -> [(i2)] }]" + options: "[M, N, O, P, Q, R] -> { separate[i0] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-pingali1.c b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-pingali1.c new file mode 100644 index 000000000000..43c6ef022643 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-pingali1.c @@ -0,0 +1,7 @@ +for (int c0 = 1; c0 <= M; c0 += 1) + for (int c1 = 1; c1 < 2 * N; c1 += 1) { + for (int c2 = max(1, -N + c1); c2 < (c1 + 1) / 2; c2 += 1) + S1(c0, c1 - c2, c2); + if ((c1 + 1) % 2 == 0) + S2(c0, (c1 + 1) / 2); + } diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-pingali1.st b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-pingali1.st new file mode 100644 index 000000000000..4ab2a651c556 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-pingali1.st @@ -0,0 +1,16 @@ +domain: "[M, N] -> { S2[i0, i1] : i0 >= 1 and i0 <= M and i1 >= 1 and i1 <= N; S1[i0, i1, i2] : i0 >= 1 and i0 <= M and i1 <= N and i2 >= 1 and i2 <= -1 + i1 }" +child: + context: "[M, N] -> { [] }" + child: + schedule: "[M, N] -> [{ S2[i0, i1] -> [(i0)]; S1[i0, i1, i2] -> [(i0)] }]" + options: "[M, N] -> { separate[i0] }" + child: + schedule: "[M, N] -> [{ S2[i0, i1] -> [(-1 + 2i1)]; S1[i0, i1, i2] -> [(i1 + i2)] }]" + options: "[M, N] -> { separate[i0] }" + child: + sequence: + - filter: "[M, N] -> { S1[i0, i1, i2] }" + child: + schedule: "[M, N] -> [{ S1[i0, i1, i2] -> [(i2)] }]" + options: "[M, N] -> { separate[i0] }" + - filter: "[M, N] -> { S2[i0, i1] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-pingali2.c b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-pingali2.c new file mode 100644 index 000000000000..6b066dee9383 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-pingali2.c @@ -0,0 +1,6 @@ +for (int c0 = 1; c0 <= M; c0 += 1) + for (int c1 = 1; c1 <= M; c1 += 1) + S1(c0, c1); +for (int c0 = 1; c0 <= M; c0 += 1) + for (int c1 = 1; c1 <= M; c1 += 1) + S2(c0, c1); diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-pingali2.st b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-pingali2.st new file mode 100644 index 000000000000..ff7603493502 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-pingali2.st @@ -0,0 +1,19 @@ +domain: "[M] -> { S1[i0, i1] : i0 >= 1 and i0 <= M and i1 >= 1 and i1 <= M; S2[i0, i1] : i0 >= 1 and i0 <= M and i1 >= 1 and i1 <= M }" +child: + context: "[M] -> { [] }" + child: + sequence: + - filter: "[M] -> { S1[i0, i1] }" + child: + schedule: "[M] -> [{ S1[i0, i1] -> [(i0)] }]" + options: "[M] -> { separate[i0] }" + child: + schedule: "[M] -> [{ S1[i0, i1] -> [(i1)] }]" + options: "[M] -> { separate[i0] }" + - filter: "[M] -> { S2[i0, i1] }" + child: + schedule: "[M] -> [{ S2[i0, i1] -> [(i0)] }]" + options: "[M] -> { separate[i0] }" + child: + schedule: "[M] -> [{ S2[i0, i1] -> [(i1)] }]" + options: "[M] -> { separate[i0] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-pingali3.c b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-pingali3.c new file mode 100644 index 000000000000..2148d6700c3c --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-pingali3.c @@ -0,0 +1,7 @@ +for (int c0 = 1; c0 <= M; c0 += 1) + for (int c1 = 1; c1 <= M; c1 += 1) + S1(c0, c1); +for (int c0 = 1; c0 <= M; c0 += 1) + for (int c1 = 1; c1 <= M; c1 += 1) + for (int c2 = 1; c2 <= M; c2 += 1) + S2(c0, c1, c2); diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-pingali3.st b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-pingali3.st new file mode 100644 index 000000000000..c3065a1e4606 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-pingali3.st @@ -0,0 +1,22 @@ +domain: "[M] -> { S1[i0, i1] : i0 >= 1 and i0 <= M and i1 >= 1 and i1 <= M; S2[i0, i1, i2] : i0 >= 1 and i0 <= M and i1 >= 1 and i1 <= M and i2 >= 1 and i2 <= M }" +child: + context: "[M] -> { [] }" + child: + sequence: + - filter: "[M] -> { S1[i0, i1] }" + child: + schedule: "[M] -> [{ S1[i0, i1] -> [(i0)] }]" + options: "[M] -> { separate[i0] }" + child: + schedule: "[M] -> [{ S1[i0, i1] -> [(i1)] }]" + options: "[M] -> { separate[i0] }" + - filter: "[M] -> { S2[i0, i1, i2] }" + child: + schedule: "[M] -> [{ S2[i0, i1, i2] -> [(i0)] }]" + options: "[M] -> { separate[i0] }" + child: + schedule: "[M] -> [{ S2[i0, i1, i2] -> [(i1)] }]" + options: "[M] -> { separate[i0] }" + child: + schedule: "[M] -> [{ S2[i0, i1, i2] -> [(i2)] }]" + options: "[M] -> { separate[i0] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-pingali4.c b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-pingali4.c new file mode 100644 index 000000000000..6b066dee9383 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-pingali4.c @@ -0,0 +1,6 @@ +for (int c0 = 1; c0 <= M; c0 += 1) + for (int c1 = 1; c1 <= M; c1 += 1) + S1(c0, c1); +for (int c0 = 1; c0 <= M; c0 += 1) + for (int c1 = 1; c1 <= M; c1 += 1) + S2(c0, c1); diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-pingali4.st b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-pingali4.st new file mode 100644 index 000000000000..0d724e9d28b7 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-pingali4.st @@ -0,0 +1,19 @@ +domain: "[M] -> { S1[i0, i1] : i0 >= 1 and i0 <= M and i1 >= 1 and i1 <= M; S2[i0, i1] : i0 >= 1 and i0 <= M and i1 >= 1 and i1 <= M }" +child: + context: "[M] -> { [] : M >= 2 }" + child: + sequence: + - filter: "[M] -> { S1[i0, i1] }" + child: + schedule: "[M] -> [{ S1[i0, i1] -> [(i0)] }]" + options: "[M] -> { separate[i0] }" + child: + schedule: "[M] -> [{ S1[i0, i1] -> [(i1)] }]" + options: "[M] -> { separate[i0] }" + - filter: "[M] -> { S2[i0, i1] }" + child: + schedule: "[M] -> [{ S2[i0, i1] -> [(i0)] }]" + options: "[M] -> { separate[i0] }" + child: + schedule: "[M] -> [{ S2[i0, i1] -> [(i1)] }]" + options: "[M] -> { separate[i0] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-pingali5.c b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-pingali5.c new file mode 100644 index 000000000000..0e9bcf43235f --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-pingali5.c @@ -0,0 +1,10 @@ +for (int c0 = 3; c0 < 2 * M; c0 += 1) { + for (int c1 = c0 / 2 + 2; c1 <= M; c1 += 1) + for (int c3 = c0 / 2 + 1; c3 < min(c0, c1); c3 += 1) + S1(c3, c0 - c3, c1); + for (int c1 = max(1, -M + c0); c1 < (c0 + 1) / 2; c1 += 1) + S2(c0 - c1, c1); + for (int c1 = c0 / 2 + 2; c1 <= M; c1 += 1) + for (int c3 = c0 / 2 + 1; c3 < min(c0, c1); c3 += 1) + S3(c3, c0 - c3, c1); +} diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-pingali5.st b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-pingali5.st new file mode 100644 index 000000000000..d83eb55ece0d --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-pingali5.st @@ -0,0 +1,26 @@ +domain: "[M] -> { S3[i0, i1, i2] : i1 >= 1 and i1 <= -1 + i0 and i2 >= 1 + i0 and i2 <= M; S2[i0, i1] : i0 <= M and i1 >= 1 and i1 <= -1 + i0; S1[i0, i1, i2] : i1 >= 1 and i1 <= -1 + i0 and i2 >= 1 + i0 and i2 <= M }" +child: + context: "[M] -> { [] }" + child: + schedule: "[M] -> [{ S1[i0, i1, i2] -> [(i0 + i1)]; S3[i0, i1, i2] -> [(i0 + i1)]; S2[i0, i1] -> [(i0 + i1)] }]" + options: "[M] -> { separate[i0] }" + child: + sequence: + - filter: "[M] -> { S1[i0, i1, i2] }" + child: + schedule: "[M] -> [{ S1[i0, i1, i2] -> [(i2)] }]" + options: "[M] -> { separate[i0] }" + child: + schedule: "[M] -> [{ S1[i0, i1, i2] -> [(i2)] }]" + options: "[M] -> { separate[i0] }" + - filter: "[M] -> { S2[i0, i1] }" + child: + schedule: "[M] -> [{ S2[i0, i1] -> [(i1)] }]" + options: "[M] -> { separate[i0] }" + - filter: "[M] -> { S3[i0, i1, i2] }" + child: + schedule: "[M] -> [{ S3[i0, i1, i2] -> [(i2)] }]" + options: "[M] -> { separate[i0] }" + child: + schedule: "[M] -> [{ S3[i0, i1, i2] -> [(i2)] }]" + options: "[M] -> { separate[i0] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-pingali6.c b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-pingali6.c new file mode 100644 index 000000000000..725357566a07 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-pingali6.c @@ -0,0 +1,8 @@ +for (int c0 = 1; c0 <= M; c0 += 1) { + for (int c2 = 2; c2 < N; c2 += 1) + for (int c3 = 2; c3 < N; c3 += 1) + S1(c0, c2, c3); + for (int c2 = 2; c2 < N; c2 += 1) + for (int c3 = 2; c3 < N; c3 += 1) + S2(c0, c2, c3); +} diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-pingali6.st b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-pingali6.st new file mode 100644 index 000000000000..3cf78bff8595 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-pingali6.st @@ -0,0 +1,22 @@ +domain: "[M, N] -> { S2[i0, i1, i2] : i0 >= 1 and i0 <= M and i1 >= 2 and i1 <= -1 + N and i2 >= 2 and i2 <= -1 + N; S1[i0, i1, i2] : i0 >= 1 and i0 <= M and i1 >= 2 and i1 <= -1 + N and i2 >= 2 and i2 <= -1 + N }" +child: + context: "[M, N] -> { [] : M >= 1 and N >= 1 }" + child: + schedule: "[M, N] -> [{ S1[i0, i1, i2] -> [(2i0)]; S2[i0, i1, i2] -> [(1 + 2i0)] }]" + options: "[M, N] -> { separate[i0] }" + child: + sequence: + - filter: "[M, N] -> { S1[i0, i1, i2] }" + child: + schedule: "[M, N] -> [{ S1[i0, i1, i2] -> [(i1)] }]" + options: "[M, N] -> { separate[i0] }" + child: + schedule: "[M, N] -> [{ S1[i0, i1, i2] -> [(i2)] }]" + options: "[M, N] -> { separate[i0] }" + - filter: "[M, N] -> { S2[i0, i1, i2] }" + child: + schedule: "[M, N] -> [{ S2[i0, i1, i2] -> [(i1)] }]" + options: "[M, N] -> { separate[i0] }" + child: + schedule: "[M, N] -> [{ S2[i0, i1, i2] -> [(i2)] }]" + options: "[M, N] -> { separate[i0] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-stride.c b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-stride.c new file mode 100644 index 000000000000..6a970d48be77 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-stride.c @@ -0,0 +1,2 @@ +for (int c0 = 2; c0 <= M; c0 += 7) + S1(c0, (c0 - 2) / 7); diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-stride.st b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-stride.st new file mode 100644 index 000000000000..135c90cdee7d --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-stride.st @@ -0,0 +1,6 @@ +domain: "[M] -> { S1[i0, i1] : 7i1 = -2 + i0 and i0 >= 2 and i0 <= M }" +child: + context: "[M] -> { [] }" + child: + schedule: "[M] -> [{ S1[i0, i1] -> [(i0)] }]" + options: "[M] -> { separate[i0] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-stride2.c b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-stride2.c new file mode 100644 index 000000000000..6a970d48be77 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-stride2.c @@ -0,0 +1,2 @@ +for (int c0 = 2; c0 <= M; c0 += 7) + S1(c0, (c0 - 2) / 7); diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-stride2.st b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-stride2.st new file mode 100644 index 000000000000..0600029d186c --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-stride2.st @@ -0,0 +1,6 @@ +domain: "[M] -> { S1[i0, i1] : 7i1 = -2 + i0 and i0 >= 0 and i0 <= M }" +child: + context: "[M] -> { [] }" + child: + schedule: "[M] -> [{ S1[i0, i1] -> [(i0)] }]" + options: "[M] -> { separate[i0] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-tang-xue1.c b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-tang-xue1.c new file mode 100644 index 000000000000..2a0f8759f379 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-tang-xue1.c @@ -0,0 +1,5 @@ +for (int c0 = 0; c0 <= 9; c0 += 2) + for (int c1 = 0; c1 <= min(4, c0 + 3); c1 += 2) + for (int c2 = max(1, c0); c2 <= min(c0 + 1, c0 - c1 + 4); c2 += 1) + for (int c3 = max(1, -c0 + c1 + c2); c3 <= min(4, -c0 + c1 + c2 + 1); c3 += 1) + S1(c0 / 2, (-c0 + c1) / 2, -c0 + c2, -c1 + c3); diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-tang-xue1.st b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-tang-xue1.st new file mode 100644 index 000000000000..89d8b72515b7 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-tang-xue1.st @@ -0,0 +1,15 @@ +domain: "{ S1[i0, i1, i2, i3] : i3 <= 4 - 2i0 - 2i1 and i3 >= i2 and i2 <= 9 - 2i0 and i2 >= 0 and i2 >= 1 - 2i0 and i3 <= 1 + i2 and i2 <= 1 and i3 >= 1 - 2i0 - 2i1 }" +child: + context: "{ [] }" + child: + schedule: "[{ S1[i0, i1, i2, i3] -> [(2i0)] }]" + options: "{ separate[i0] }" + child: + schedule: "[{ S1[i0, i1, i2, i3] -> [(2i0 + 2i1)] }]" + options: "{ separate[i0] }" + child: + schedule: "[{ S1[i0, i1, i2, i3] -> [(2i0 + i2)] }]" + options: "{ separate[i0] }" + child: + schedule: "[{ S1[i0, i1, i2, i3] -> [(2i0 + 2i1 + i3)] }]" + options: "{ separate[i0] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-two.c b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-two.c new file mode 100644 index 000000000000..3946c423f15b --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-two.c @@ -0,0 +1 @@ +S1(1, 1, 5); diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-two.st b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-two.st new file mode 100644 index 000000000000..c780ca22a994 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/reservoir-two.st @@ -0,0 +1,6 @@ +domain: "{ S1[i0, i1, i2] : 2i1 = 3 - i0 and 2i2 = 9 + i0 and i0 >= 0 and i0 <= 1 }" +child: + context: "{ [] }" + child: + schedule: "[{ S1[i0, i1, i2] -> [(i0)] }, { S1[i0, i1, i2] -> [(i1)] }, { S1[i0, i1, i2] -> [(i2)] }]" + options: "{ separate[i0] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/singleton.c b/external/mit/isl/dist/test_inputs/codegen/cloog/singleton.c new file mode 100644 index 000000000000..0cf8d1613e2d --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/singleton.c @@ -0,0 +1,2 @@ +S2(); +S1(); diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/singleton.st b/external/mit/isl/dist/test_inputs/codegen/cloog/singleton.st new file mode 100644 index 000000000000..a38487be53a5 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/singleton.st @@ -0,0 +1,7 @@ +domain: "{ S1[]; S2[] }" +child: + context: "{ [] }" + child: + sequence: + - filter: "{ S2[] }" + - filter: "{ S1[] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/sor1d.c b/external/mit/isl/dist/test_inputs/codegen/cloog/sor1d.c new file mode 100644 index 000000000000..92c6b33aa6dc --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/sor1d.c @@ -0,0 +1,13 @@ +if (M >= 1 && N >= 3) + for (int c0 = -1; c0 <= (3 * M + N - 5) / 100; c0 += 1) { + for (int c1 = max(max(0, c0 - (2 * M + N + 95) / 100 + 1), floord(-N + 100 * c0 + 106, 300)); c1 <= min(min(c0, M / 100), (c0 + 1) / 3); c1 += 1) + for (int c2 = max(200 * c1 - 3, 100 * c0 - 100 * c1); c2 <= min(min(2 * M + N - 5, 100 * c0 - 100 * c1 + 99), N + 200 * c1 + 193); c2 += 1) { + if (c1 >= 1 && N + 200 * c1 >= c2 + 7) + S3(c0 - c1, c1 - 1, c1, 100 * c1 - 1, -200 * c1 + c2 + 6); + for (int c3 = max(max(1, 100 * c1), -N + (N + c2) / 2 + 3); c3 <= min(min(M, 100 * c1 + 99), c2 / 2 + 1); c3 += 1) + S1(c0 - c1, c1, c3, c2 - 2 * c3 + 4); + if (M >= 100 * c1 + 100 && c2 >= 200 * c1 + 197) + S2(c0 - c1, c1, c1 + 1, 100 * c1 + 99, -200 * c1 + c2 - 194); + } + S4(c0); + } diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/sor1d.st b/external/mit/isl/dist/test_inputs/codegen/cloog/sor1d.st new file mode 100644 index 000000000000..bdde2e51f3a8 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/sor1d.st @@ -0,0 +1,24 @@ +domain: "[M, N] -> { S2[i0, i1, 1 + i1, 99 + 100i1, i4] : i4 >= 3 and i4 >= -193 - 200i1 and i4 >= -194 + 100i0 - 200i1 and 100i0 >= -284 - 3N and i4 <= -1 + N and i4 <= -201 + 2M + N - 200i1 and i4 <= -95 + 100i0 - 200i1 and 100i0 >= -94 - N and 50i0 >= -45 - N and 3N >= -134 - M and i1 >= 0 and N >= 4 and 200i1 >= -192 - N and 200i1 >= -193 - N + 100i0 and 100i0 <= -7 + 2M + N and 7N >= -463 - 2M and 100i1 <= -100 + M and i0 >= 0 and 200i1 <= -204 + 2M + N and 2i1 <= -1 + i0 and 5N >= -75 - 2M and N >= 8 - 2M and 50i0 <= -6 + M + N and 50i0 <= 89 + M + 2N and 100i0 <= -15 + 2M + 3N and M >= 2 and 100i1 <= -5 + M + N and 2N >= -39 - M and 200i1 <= 96 + N + 100i0 and 3N >= 16 - 2M and 100i1 >= -94 - N + 50i0 and N >= 6 - M and 100i1 >= -94 - N; S3[i0, i1, 1 + i1, 99 + 100i1, i4] : i4 >= 3 and i4 >= -193 - 200i1 and i4 >= -194 + 100i0 - 200i1 and 100i0 >= -284 - 3N and i4 <= -1 + N and i4 <= -201 + 2M + N - 200i1 and i4 <= -95 + 100i0 - 200i1 and 100i0 >= -94 - N and 50i0 >= -45 - N and 3N >= -134 - M and i1 >= 0 and N >= 4 and 200i1 >= -192 - N and 200i1 >= -193 - N + 100i0 and 100i0 <= -7 + 2M + N and 7N >= -463 - 2M and 100i1 <= -100 + M and i0 >= 0 and 200i1 <= -204 + 2M + N and 2i1 <= -1 + i0 and 5N >= -75 - 2M and N >= 8 - 2M and 50i0 <= -6 + M + N and 50i0 <= 89 + M + 2N and 100i0 <= -15 + 2M + 3N and M >= 2 and 100i1 <= -5 + M + N and 2N >= -39 - M and 200i1 <= 96 + N + 100i0 and 3N >= 16 - 2M and 100i1 >= -94 - N + 50i0 and N >= 6 - M and 100i1 >= -94 - N; S4[i0] : 200i0 >= -781 - 3N and 200i0 >= -391 - N and 50i0 >= -268 - N and 100i0 >= -392 - N and i0 >= -1 and 200i0 <= 377 + 6M + 5N and 100i0 <= 335 + 3M + 3N and 100i0 <= 190 + 3M + 2N and 200i0 <= -13 + 6M + 3N and 100i0 <= -5 + 3M + N and 3N >= -484 - 2M and N >= -95 - M and N >= -192 - 3M and 5N >= -873 - 3M and 2N >= -189 - 3M and 7N >= -1062 - 6M and 5N >= -771 - 6M and 4N >= -579 - 3M and N >= 3 and N >= 5 - 2M and M >= 1; S1[i0, i1, i2, i3] : i3 >= 4 + 100i0 - 2i2 and i3 >= 2 and i3 <= 103 + 100i0 - 2i2 and i3 <= -1 + N and i2 >= 1 and i2 >= 100i1 and 2i2 >= 5 - N + 100i0 and i2 <= M and i2 <= 99 + 100i1 and i2 <= 50 + 50i0 and i1 >= 0 and 200i1 >= -193 - N + 100i0 and 100i1 <= M and 2i1 <= 1 + i0 and i0 >= 0 and 100i0 <= -5 + 2M + N and N >= 3 and N >= -94 - 2M and M >= 1 }" +child: + context: "[M, N] -> { [] : M >= 0 and N >= 0 }" + child: + schedule: "[M, N] -> [{ S2[i0, i1, i2, i3, i4] -> [(i0 + i1)]; S1[i0, i1, i2, i3] -> [(i0 + i1)]; S3[i0, i1, i2, i3, i4] -> [(1 + i0 + i1)]; S4[i0] -> [(i0)] }]" + options: "[M, N] -> { atomic[i0] }" + child: + sequence: + - filter: "[M, N] -> { S2[i0, i1, i2, i3, i4]; S3[i0, i1, i2, i3, i4]; S1[i0, i1, i2, i3] }" + child: + schedule: "[M, N] -> [{ S2[i0, i1, i2, i3, i4] -> [(i1)]; S1[i0, i1, i2, i3] -> [(i1)]; S3[i0, i1, i2, i3, i4] -> [(i2)] }, { S2[i0, i1, i2, i3, i4] -> [(-4 + 2i3 + i4)]; S1[i0, i1, i2, i3] -> [(-4 + 2i2 + i3)]; S3[i0, i1, i2, i3, i4] -> [(-4 + 2i3 + i4)] }, { S2[i0, i1, i2, i3, i4] -> [(i3)]; S1[i0, i1, i2, i3] -> [(i2)]; S3[i0, i1, i2, i3, i4] -> [(i3)] }]" + options: "[M, N] -> { atomic[i0] }" + child: + sequence: + - filter: "[M, N] -> { S3[i0, i1, i2, i3, i4] }" + child: + schedule: "[M, N] -> [{ S3[i0, i1, i2, i3, i4] -> [(i1)] }, { S3[i0, i1, i2, i3, i4] -> [(i4)] }]" + options: "[M, N] -> { atomic[i0] }" + - filter: "[M, N] -> { S1[i0, i1, i2, i3] }" + - filter: "[M, N] -> { S2[i0, i1, i2, i3, i4] }" + child: + schedule: "[M, N] -> [{ S2[i0, i1, i2, i3, i4] -> [(i2)] }, { S2[i0, i1, i2, i3, i4] -> [(i4)] }]" + options: "[M, N] -> { atomic[i0] }" + - filter: "[M, N] -> { S4[i0] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/square+triangle-1-1-2-3.c b/external/mit/isl/dist/test_inputs/codegen/cloog/square+triangle-1-1-2-3.c new file mode 100644 index 000000000000..316213f18f1e --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/square+triangle-1-1-2-3.c @@ -0,0 +1,9 @@ +for (int c0 = 1; c0 <= M; c0 += 1) { + S1(c0, 1); + for (int c1 = 2; c1 <= c0; c1 += 1) { + S1(c0, c1); + S2(c0, c1); + } + for (int c1 = c0 + 1; c1 <= M; c1 += 1) + S1(c0, c1); +} diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/square+triangle-1-1-2-3.st b/external/mit/isl/dist/test_inputs/codegen/cloog/square+triangle-1-1-2-3.st new file mode 100644 index 000000000000..bff294dbda9d --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/square+triangle-1-1-2-3.st @@ -0,0 +1,10 @@ +domain: "[M] -> { S1[i0, i1] : i0 >= 1 and i0 <= M and i1 >= 1 and i1 <= M; S2[i0, i1] : i1 >= 2 and i1 <= i0 and i0 <= M }" +child: + context: "[M] -> { [] : M >= 1 }" + child: + schedule: "[M] -> [{ S1[i0, i1] -> [(i0)]; S2[i0, i1] -> [(i0)] }, { S1[i0, i1] -> [(i1)]; S2[i0, i1] -> [(i1)] }]" + options: "[M] -> { separate[i0] }" + child: + sequence: + - filter: "[M] -> { S1[i0, i1] }" + - filter: "[M] -> { S2[i0, i1] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/stride.c b/external/mit/isl/dist/test_inputs/codegen/cloog/stride.c new file mode 100644 index 000000000000..ccacebcd51e3 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/stride.c @@ -0,0 +1,5 @@ +for (int c0 = 3; c0 <= 24; c0 += 3) + S2(c0, c0 / 3); +S1(25); +for (int c0 = 27; c0 <= 100; c0 += 3) + S2(c0, c0 / 3); diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/stride.st b/external/mit/isl/dist/test_inputs/codegen/cloog/stride.st new file mode 100644 index 000000000000..d83f97938d90 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/stride.st @@ -0,0 +1,6 @@ +domain: "{ S2[i0, i1] : 3i1 = i0 and i0 >= 3 and i0 <= 100; S1[25] }" +child: + context: "{ [] }" + child: + schedule: "[{ S2[i0, i1] -> [(i0)]; S1[i0] -> [(i0)] }, { S2[i0, i1] -> [(i1)]; S1[i0] -> [(0)] }]" + options: "{ separate[i0] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/stride2.c b/external/mit/isl/dist/test_inputs/codegen/cloog/stride2.c new file mode 100644 index 000000000000..8eab0d7994b7 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/stride2.c @@ -0,0 +1,6 @@ +for (int c0 = 3; c0 <= 26; c0 += 3) + S2(c0, c0 / 3); +S1(27); +S2(27, 9); +for (int c0 = 30; c0 <= 100; c0 += 3) + S2(c0, c0 / 3); diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/stride2.st b/external/mit/isl/dist/test_inputs/codegen/cloog/stride2.st new file mode 100644 index 000000000000..d2e34207b908 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/stride2.st @@ -0,0 +1,6 @@ +domain: "{ S2[i0, i1] : 3i1 = i0 and i0 >= 3 and i0 <= 100; S1[27] }" +child: + context: "{ [] }" + child: + schedule: "[{ S2[i0, i1] -> [(i0)]; S1[i0] -> [(i0)] }, { S2[i0, i1] -> [(i1)]; S1[i0] -> [(0)] }]" + options: "{ separate[i0] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/stride3.c b/external/mit/isl/dist/test_inputs/codegen/cloog/stride3.c new file mode 100644 index 000000000000..d145938b663a --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/stride3.c @@ -0,0 +1,2 @@ +for (int c0 = max(1, m); c0 <= n; c0 += 1) + S1(c0); diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/stride3.st b/external/mit/isl/dist/test_inputs/codegen/cloog/stride3.st new file mode 100644 index 000000000000..f970d2c3cf77 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/stride3.st @@ -0,0 +1,6 @@ +domain: "[m, n] -> { S1[i] : i >= 1 and i <= n and i >= m }" +child: + context: "[m, n] -> { [] }" + child: + schedule: "[m, n] -> [{ S1[i0] -> [(50i0)] }]" + options: "[m, n] -> { separate[i0] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/stride4.c b/external/mit/isl/dist/test_inputs/codegen/cloog/stride4.c new file mode 100644 index 000000000000..03908e60c07c --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/stride4.c @@ -0,0 +1,3 @@ +if (t >= 0 && t <= 15) + for (int c0 = t; c0 <= 99; c0 += 16) + S1(c0, t); diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/stride4.st b/external/mit/isl/dist/test_inputs/codegen/cloog/stride4.st new file mode 100644 index 000000000000..9ffa62a90a76 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/stride4.st @@ -0,0 +1,6 @@ +domain: "[t] -> { S1[i0, t] : exists (e0 = floor((t - i0)/16): 16e0 = t - i0 and i0 >= 0 and i0 <= 99 and t >= 0 and t <= 15) }" +child: + context: "[t] -> { [] }" + child: + schedule: "[t] -> [{ S1[i0, i1] -> [(i0)] }, { S1[i0, i1] -> [(i1)] }]" + options: "[t] -> { separate[i0] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/swim.c b/external/mit/isl/dist/test_inputs/codegen/cloog/swim.c new file mode 100644 index 000000000000..14f651489652 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/swim.c @@ -0,0 +1,159 @@ +if (M == 1) { + S1(); + S2(); + S3(); + S4(); + S5(); + S6(); + S7(); + S8(); + S9(); + S10(); + S11(); + S12(); + S13(); + S14(); + S15(); + S16(); + S17(); + S18(); + S19(); + S20(); + S21(); + S22(); + S23(); + S24(); + S25(); + S26(); + S27(); + for (int c0 = 1; c0 <= N; c0 += 1) { + for (int c1 = 1; c1 <= N; c1 += 1) { + S28(c0, c1); + S29(c0, c1); + S30(c0, c1); + } + S31(c0); + } + S32(); + S33(); + S34(); + if (O <= 1) + S35(); + S36(); + S37(); + for (int c0 = 2; c0 <= P; c0 += 1) { + S38(c0); + S39(c0); + for (int c1 = 1; c1 <= Q; c1 += 1) + for (int c2 = 1; c2 <= R; c2 += 1) { + S40(c0, c1, c2); + S41(c0, c1, c2); + S42(c0, c1, c2); + S43(c0, c1, c2); + } + for (int c1 = 1; c1 <= Q; c1 += 1) { + S44(c0, c1); + S45(c0, c1); + S46(c0, c1); + S47(c0, c1); + } + for (int c1 = 1; c1 <= R; c1 += 1) { + S48(c0, c1); + S49(c0, c1); + S50(c0, c1); + S51(c0, c1); + } + S52(c0); + S53(c0); + S54(c0); + S55(c0); + S56(c0); + S57(c0); + S58(c0); + for (int c1 = 1; c1 <= Q; c1 += 1) + for (int c2 = 1; c2 <= R; c2 += 1) { + S59(c0, c1, c2); + S60(c0, c1, c2); + S61(c0, c1, c2); + } + for (int c1 = 1; c1 <= Q; c1 += 1) { + S62(c0, c1); + S63(c0, c1); + S64(c0, c1); + } + for (int c1 = 1; c1 <= R; c1 += 1) { + S65(c0, c1); + S66(c0, c1); + S67(c0, c1); + } + S68(c0); + S69(c0); + S70(c0); + S71(c0); + S72(c0); + S73(c0); + S74(c0); + S75(c0); + S76(c0); + S77(c0); + S78(c0); + S79(c0); + S80(c0); + S81(c0); + S82(c0); + S83(c0); + S84(c0); + S85(c0); + S86(c0); + S87(c0); + S88(c0); + S89(c0); + S90(c0); + S91(c0); + S92(c0); + S93(c0); + S94(c0); + for (int c1 = 1; c1 <= N; c1 += 1) { + for (int c2 = 1; c2 <= N; c2 += 1) { + S95(c0, c1, c2); + S96(c0, c1, c2); + S97(c0, c1, c2); + } + S98(c0, c1); + } + S99(c0); + S100(c0); + S101(c0); + for (int c1 = 1; c1 <= Q; c1 += 1) + for (int c2 = 1; c2 <= R; c2 += 1) { + S102(c0, c1, c2); + S103(c0, c1, c2); + S104(c0, c1, c2); + S105(c0, c1, c2); + S106(c0, c1, c2); + S107(c0, c1, c2); + } + for (int c1 = 1; c1 <= Q; c1 += 1) { + S108(c0, c1); + S109(c0, c1); + S110(c0, c1); + S111(c0, c1); + S112(c0, c1); + S113(c0, c1); + } + for (int c1 = 1; c1 <= R; c1 += 1) { + S114(c0, c1); + S115(c0, c1); + S116(c0, c1); + S117(c0, c1); + S118(c0, c1); + S119(c0, c1); + } + S120(c0); + S121(c0); + S122(c0); + S123(c0); + S124(c0); + S125(c0); + } +} diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/swim.st b/external/mit/isl/dist/test_inputs/codegen/cloog/swim.st new file mode 100644 index 000000000000..ff08bb12dcf4 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/swim.st @@ -0,0 +1,223 @@ +domain: "[M, N, O, P, Q, R] -> { S40[i0, i1, i2] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= Q and i2 >= 1 and i2 <= R; S106[i0, i1, i2] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= Q and i2 >= 1 and i2 <= R; S99[i0] : M = 1 and i0 >= 2 and i0 <= P; S83[i0] : M = 1 and i0 >= 2 and i0 <= P; S86[i0] : M = 1 and i0 >= 2 and i0 <= P; S56[i0] : M = 1 and i0 >= 2 and i0 <= P; S124[i0] : M = 1 and i0 >= 2 and i0 <= P; S66[i0, i1] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= R; S46[i0, i1] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= Q; S64[i0, i1] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= Q; S22[] : M = 1; S15[] : M = 1; S30[i0, i1] : M = 1 and i0 >= 1 and i0 <= N and i1 >= 1 and i1 <= N; S14[] : M = 1; S12[] : M = 1; S87[i0] : M = 1 and i0 >= 2 and i0 <= P; S110[i0, i1] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= Q; S73[i0] : M = 1 and i0 >= 2 and i0 <= P; S44[i0, i1] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= Q; S31[i0] : M = 1 and i0 >= 1 and i0 <= N; S118[i0, i1] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= R; S8[] : M = 1; S125[i0] : M = 1 and i0 >= 2 and i0 <= P; S63[i0, i1] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= Q; S25[] : M = 1; S51[i0, i1] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= R; S91[i0] : M = 1 and i0 >= 2 and i0 <= P; S84[i0] : M = 1 and i0 >= 2 and i0 <= P; S35[] : M = 1 and O <= 1; S97[i0, i1, i2] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= N and i2 >= 1 and i2 <= N; S75[i0] : M = 1 and i0 >= 2 and i0 <= P; S19[] : M = 1; S50[i0, i1] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= R; S114[i0, i1] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= R; S13[] : M = 1; S72[i0] : M = 1 and i0 >= 2 and i0 <= P; S78[i0] : M = 1 and i0 >= 2 and i0 <= P; S39[i0] : M = 1 and i0 >= 2 and i0 <= P; S102[i0, i1, i2] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= Q and i2 >= 1 and i2 <= R; S107[i0, i1, i2] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= Q and i2 >= 1 and i2 <= R; S68[i0] : M = 1 and i0 >= 2 and i0 <= P; S32[] : M = 1; S41[i0, i1, i2] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= Q and i2 >= 1 and i2 <= R; S69[i0] : M = 1 and i0 >= 2 and i0 <= P; S3[] : M = 1; S100[i0] : M = 1 and i0 >= 2 and i0 <= P; S11[] : M = 1; S76[i0] : M = 1 and i0 >= 2 and i0 <= P; S88[i0] : M = 1 and i0 >= 2 and i0 <= P; S49[i0, i1] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= R; S45[i0, i1] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= Q; S10[] : M = 1; S80[i0] : M = 1 and i0 >= 2 and i0 <= P; S61[i0, i1, i2] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= Q and i2 >= 1 and i2 <= R; S67[i0, i1] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= R; S70[i0] : M = 1 and i0 >= 2 and i0 <= P; S29[i0, i1] : M = 1 and i0 >= 1 and i0 <= N and i1 >= 1 and i1 <= N; S60[i0, i1, i2] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= Q and i2 >= 1 and i2 <= R; S21[] : M = 1; S92[i0] : M = 1 and i0 >= 2 and i0 <= P; S47[i0, i1] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= Q; S24[] : M = 1; S16[] : M = 1; S105[i0, i1, i2] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= Q and i2 >= 1 and i2 <= R; S18[] : M = 1; S48[i0, i1] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= R; S5[] : M = 1; S113[i0, i1] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= Q; S7[] : M = 1; S38[i0] : M = 1 and i0 >= 2 and i0 <= P; S54[i0] : M = 1 and i0 >= 2 and i0 <= P; S109[i0, i1] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= Q; S23[] : M = 1; S82[i0] : M = 1 and i0 >= 2 and i0 <= P; S59[i0, i1, i2] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= Q and i2 >= 1 and i2 <= R; S77[i0] : M = 1 and i0 >= 2 and i0 <= P; S101[i0] : M = 1 and i0 >= 2 and i0 <= P; S37[] : M = 1; S71[i0] : M = 1 and i0 >= 2 and i0 <= P; S121[i0] : M = 1 and i0 >= 2 and i0 <= P; S115[i0, i1] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= R; S104[i0, i1, i2] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= Q and i2 >= 1 and i2 <= R; S94[i0] : M = 1 and i0 >= 2 and i0 <= P; S6[] : M = 1; S43[i0, i1, i2] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= Q and i2 >= 1 and i2 <= R; S1[] : M = 1; S98[i0, i1] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= N; S55[i0] : M = 1 and i0 >= 2 and i0 <= P; S58[i0] : M = 1 and i0 >= 2 and i0 <= P; S42[i0, i1, i2] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= Q and i2 >= 1 and i2 <= R; S89[i0] : M = 1 and i0 >= 2 and i0 <= P; S53[i0] : M = 1 and i0 >= 2 and i0 <= P; S111[i0, i1] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= Q; S52[i0] : M = 1 and i0 >= 2 and i0 <= P; S85[i0] : M = 1 and i0 >= 2 and i0 <= P; S26[] : M = 1; S79[i0] : M = 1 and i0 >= 2 and i0 <= P; S81[i0] : M = 1 and i0 >= 2 and i0 <= P; S57[i0] : M = 1 and i0 >= 2 and i0 <= P; S4[] : M = 1; S123[i0] : M = 1 and i0 >= 2 and i0 <= P; S36[] : M = 1; S65[i0, i1] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= R; S34[] : M = 1; S119[i0, i1] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= R; S9[] : M = 1; S28[i0, i1] : M = 1 and i0 >= 1 and i0 <= N and i1 >= 1 and i1 <= N; S20[] : M = 1; S117[i0, i1] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= R; S112[i0, i1] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= Q; S103[i0, i1, i2] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= Q and i2 >= 1 and i2 <= R; S17[] : M = 1; S96[i0, i1, i2] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= N and i2 >= 1 and i2 <= N; S95[i0, i1, i2] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= N and i2 >= 1 and i2 <= N; S62[i0, i1] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= Q; S90[i0] : M = 1 and i0 >= 2 and i0 <= P; S120[i0] : M = 1 and i0 >= 2 and i0 <= P; S116[i0, i1] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= R; S108[i0, i1] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= Q; S74[i0] : M = 1 and i0 >= 2 and i0 <= P; S93[i0] : M = 1 and i0 >= 2 and i0 <= P; S2[] : M = 1; S27[] : M = 1; S122[i0] : M = 1 and i0 >= 2 and i0 <= P; S33[] : M = 1 }" +child: + context: "[M, N, O, P, Q, R] -> { [] }" + child: + sequence: + - filter: "[M, N, O, P, Q, R] -> { S1[] }" + - filter: "[M, N, O, P, Q, R] -> { S2[] }" + - filter: "[M, N, O, P, Q, R] -> { S3[] }" + - filter: "[M, N, O, P, Q, R] -> { S4[] }" + - filter: "[M, N, O, P, Q, R] -> { S5[] }" + - filter: "[M, N, O, P, Q, R] -> { S6[] }" + - filter: "[M, N, O, P, Q, R] -> { S7[] }" + - filter: "[M, N, O, P, Q, R] -> { S8[] }" + - filter: "[M, N, O, P, Q, R] -> { S9[] }" + - filter: "[M, N, O, P, Q, R] -> { S10[] }" + - filter: "[M, N, O, P, Q, R] -> { S11[] }" + - filter: "[M, N, O, P, Q, R] -> { S12[] }" + - filter: "[M, N, O, P, Q, R] -> { S13[] }" + - filter: "[M, N, O, P, Q, R] -> { S14[] }" + - filter: "[M, N, O, P, Q, R] -> { S15[] }" + - filter: "[M, N, O, P, Q, R] -> { S16[] }" + - filter: "[M, N, O, P, Q, R] -> { S17[] }" + - filter: "[M, N, O, P, Q, R] -> { S18[] }" + - filter: "[M, N, O, P, Q, R] -> { S19[] }" + - filter: "[M, N, O, P, Q, R] -> { S20[] }" + - filter: "[M, N, O, P, Q, R] -> { S21[] }" + - filter: "[M, N, O, P, Q, R] -> { S22[] }" + - filter: "[M, N, O, P, Q, R] -> { S23[] }" + - filter: "[M, N, O, P, Q, R] -> { S24[] }" + - filter: "[M, N, O, P, Q, R] -> { S25[] }" + - filter: "[M, N, O, P, Q, R] -> { S26[] }" + - filter: "[M, N, O, P, Q, R] -> { S27[] }" + - filter: "[M, N, O, P, Q, R] -> { S30[i0, i1]; S28[i0, i1]; S31[i0]; S29[i0, i1] }" + child: + schedule: "[M, N, O, P, Q, R] -> [{ S31[i0] -> [(i0)]; S29[i0, i1] -> [(i0)]; S30[i0, i1] -> [(i0)]; S28[i0, i1] -> [(i0)] }]" + options: "[M, N, O, P, Q, R] -> { separate[i0] }" + child: + sequence: + - filter: "[M, N, O, P, Q, R] -> { S30[i0, i1]; S28[i0, i1]; S29[i0, i1] }" + child: + schedule: "[M, N, O, P, Q, R] -> [{ S29[i0, i1] -> [(i1)]; S30[i0, i1] -> [(i1)]; S28[i0, i1] -> [(i1)] }]" + options: "[M, N, O, P, Q, R] -> { separate[i0] }" + child: + sequence: + - filter: "[M, N, O, P, Q, R] -> { S28[i0, i1] }" + - filter: "[M, N, O, P, Q, R] -> { S29[i0, i1] }" + - filter: "[M, N, O, P, Q, R] -> { S30[i0, i1] }" + - filter: "[M, N, O, P, Q, R] -> { S31[i0] }" + - filter: "[M, N, O, P, Q, R] -> { S32[] }" + - filter: "[M, N, O, P, Q, R] -> { S33[] }" + - filter: "[M, N, O, P, Q, R] -> { S34[] }" + - filter: "[M, N, O, P, Q, R] -> { S35[] }" + - filter: "[M, N, O, P, Q, R] -> { S36[] }" + - filter: "[M, N, O, P, Q, R] -> { S37[] }" + - filter: "[M, N, O, P, Q, R] -> { S58[i0]; S116[i0, i1]; S120[i0]; S106[i0, i1, i2]; S102[i0, i1, i2]; S114[i0, i1]; S113[i0, i1]; S122[i0]; S83[i0]; S103[i0, i1, i2]; S71[i0]; S50[i0, i1]; S98[i0, i1]; S65[i0, i1]; S82[i0]; S109[i0, i1]; S51[i0, i1]; S60[i0, i1, i2]; S91[i0]; S78[i0]; S101[i0]; S123[i0]; S111[i0, i1]; S97[i0, i1, i2]; S67[i0, i1]; S117[i0, i1]; S88[i0]; S79[i0]; S46[i0, i1]; S56[i0]; S45[i0, i1]; S74[i0]; S49[i0, i1]; S75[i0]; S115[i0, i1]; S119[i0, i1]; S42[i0, i1, i2]; S57[i0]; S62[i0, i1]; S99[i0]; S107[i0, i1, i2]; S100[i0]; S104[i0, i1, i2]; S70[i0]; S89[i0]; S125[i0]; S44[i0, i1]; S93[i0]; S90[i0]; S84[i0]; S105[i0, i1, i2]; S95[i0, i1, i2]; S66[i0, i1]; S77[i0]; S38[i0]; S41[i0, i1, i2]; S92[i0]; S87[i0]; S47[i0, i1]; S108[i0, i1]; S54[i0]; S76[i0]; S112[i0, i1]; S80[i0]; S55[i0]; S39[i0]; S59[i0, i1, i2]; S121[i0]; S86[i0]; S110[i0, i1]; S48[i0, i1]; S68[i0]; S53[i0]; S72[i0]; S85[i0]; S52[i0]; S69[i0]; S61[i0, i1, i2]; S43[i0, i1, i2]; S124[i0]; S73[i0]; S81[i0]; S63[i0, i1]; S118[i0, i1]; S96[i0, i1, i2]; S40[i0, i1, i2]; S94[i0]; S64[i0, i1] }" + child: + schedule: "[M, N, O, P, Q, R] -> [{ S99[i0] -> [(i0)]; S97[i0, i1, i2] -> [(i0)]; S53[i0] -> [(i0)]; S101[i0] -> [(i0)]; S60[i0, i1, i2] -> [(i0)]; S40[i0, i1, i2] -> [(i0)]; S103[i0, i1, i2] -> [(i0)]; S55[i0] -> [(i0)]; S89[i0] -> [(i0)]; S56[i0] -> [(i0)]; S87[i0] -> [(i0)]; S115[i0, i1] -> [(i0)]; S123[i0] -> [(i0)]; S88[i0] -> [(i0)]; S70[i0] -> [(i0)]; S59[i0, i1, i2] -> [(i0)]; S52[i0] -> [(i0)]; S54[i0] -> [(i0)]; S63[i0, i1] -> [(i0)]; S92[i0] -> [(i0)]; S93[i0] -> [(i0)]; S119[i0, i1] -> [(i0)]; S76[i0] -> [(i0)]; S57[i0] -> [(i0)]; S44[i0, i1] -> [(i0)]; S79[i0] -> [(i0)]; S61[i0, i1, i2] -> [(i0)]; S69[i0] -> [(i0)]; S117[i0, i1] -> [(i0)]; S121[i0] -> [(i0)]; S84[i0] -> [(i0)]; S83[i0] -> [(i0)]; S43[i0, i1, i2] -> [(i0)]; S98[i0, i1] -> [(i0)]; S78[i0] -> [(i0)]; S114[i0, i1] -> [(i0)]; S66[i0, i1] -> [(i0)]; S77[i0] -> [(i0)]; S109[i0, i1] -> [(i0)]; S42[i0, i1, i2] -> [(i0)]; S58[i0] -> [(i0)]; S71[i0] -> [(i0)]; S68[i0] -> [(i0)]; S116[i0, i1] -> [(i0)]; S81[i0] -> [(i0)]; S125[i0] -> [(i0)]; S80[i0] -> [(i0)]; S73[i0] -> [(i0)]; S110[i0, i1] -> [(i0)]; S72[i0] -> [(i0)]; S51[i0, i1] -> [(i0)]; S122[i0] -> [(i0)]; S38[i0] -> [(i0)]; S39[i0] -> [(i0)]; S90[i0] -> [(i0)]; S113[i0, i1] -> [(i0)]; S46[i0, i1] -> [(i0)]; S47[i0, i1] -> [(i0)]; S96[i0, i1, i2] -> [(i0)]; S45[i0, i1] -> [(i0)]; S49[i0, i1] -> [(i0)]; S118[i0, i1] -> [(i0)]; S50[i0, i1] -> [(i0)]; S102[i0, i1, i2] -> [(i0)]; S112[i0, i1] -> [(i0)]; S86[i0] -> [(i0)]; S124[i0] -> [(i0)]; S41[i0, i1, i2] -> [(i0)]; S100[i0] -> [(i0)]; S104[i0, i1, i2] -> [(i0)]; S75[i0] -> [(i0)]; S62[i0, i1] -> [(i0)]; S85[i0] -> [(i0)]; S105[i0, i1, i2] -> [(i0)]; S82[i0] -> [(i0)]; S111[i0, i1] -> [(i0)]; S48[i0, i1] -> [(i0)]; S65[i0, i1] -> [(i0)]; S120[i0] -> [(i0)]; S107[i0, i1, i2] -> [(i0)]; S106[i0, i1, i2] -> [(i0)]; S95[i0, i1, i2] -> [(i0)]; S108[i0, i1] -> [(i0)]; S91[i0] -> [(i0)]; S67[i0, i1] -> [(i0)]; S74[i0] -> [(i0)]; S64[i0, i1] -> [(i0)]; S94[i0] -> [(i0)] }]" + options: "[M, N, O, P, Q, R] -> { separate[i0] }" + child: + sequence: + - filter: "[M, N, O, P, Q, R] -> { S38[i0] }" + - filter: "[M, N, O, P, Q, R] -> { S39[i0] }" + - filter: "[M, N, O, P, Q, R] -> { S40[i0, i1, i2]; S41[i0, i1, i2]; S43[i0, i1, i2]; S42[i0, i1, i2] }" + child: + schedule: "[M, N, O, P, Q, R] -> [{ S43[i0, i1, i2] -> [(i1)]; S41[i0, i1, i2] -> [(i1)]; S40[i0, i1, i2] -> [(i1)]; S42[i0, i1, i2] -> [(i1)] }]" + options: "[M, N, O, P, Q, R] -> { separate[i0] }" + child: + schedule: "[M, N, O, P, Q, R] -> [{ S43[i0, i1, i2] -> [(i2)]; S41[i0, i1, i2] -> [(i2)]; S40[i0, i1, i2] -> [(i2)]; S42[i0, i1, i2] -> [(i2)] }]" + options: "[M, N, O, P, Q, R] -> { separate[i0] }" + child: + sequence: + - filter: "[M, N, O, P, Q, R] -> { S40[i0, i1, i2] }" + - filter: "[M, N, O, P, Q, R] -> { S41[i0, i1, i2] }" + - filter: "[M, N, O, P, Q, R] -> { S42[i0, i1, i2] }" + - filter: "[M, N, O, P, Q, R] -> { S43[i0, i1, i2] }" + - filter: "[M, N, O, P, Q, R] -> { S46[i0, i1]; S45[i0, i1]; S44[i0, i1]; S47[i0, i1] }" + child: + schedule: "[M, N, O, P, Q, R] -> [{ S47[i0, i1] -> [(i1)]; S46[i0, i1] -> [(i1)]; S44[i0, i1] -> [(i1)]; S45[i0, i1] -> [(i1)] }]" + options: "[M, N, O, P, Q, R] -> { separate[i0] }" + child: + sequence: + - filter: "[M, N, O, P, Q, R] -> { S44[i0, i1] }" + - filter: "[M, N, O, P, Q, R] -> { S45[i0, i1] }" + - filter: "[M, N, O, P, Q, R] -> { S46[i0, i1] }" + - filter: "[M, N, O, P, Q, R] -> { S47[i0, i1] }" + - filter: "[M, N, O, P, Q, R] -> { S51[i0, i1]; S49[i0, i1]; S50[i0, i1]; S48[i0, i1] }" + child: + schedule: "[M, N, O, P, Q, R] -> [{ S51[i0, i1] -> [(i1)]; S49[i0, i1] -> [(i1)]; S48[i0, i1] -> [(i1)]; S50[i0, i1] -> [(i1)] }]" + options: "[M, N, O, P, Q, R] -> { separate[i0] }" + child: + sequence: + - filter: "[M, N, O, P, Q, R] -> { S48[i0, i1] }" + - filter: "[M, N, O, P, Q, R] -> { S49[i0, i1] }" + - filter: "[M, N, O, P, Q, R] -> { S50[i0, i1] }" + - filter: "[M, N, O, P, Q, R] -> { S51[i0, i1] }" + - filter: "[M, N, O, P, Q, R] -> { S52[i0] }" + - filter: "[M, N, O, P, Q, R] -> { S53[i0] }" + - filter: "[M, N, O, P, Q, R] -> { S54[i0] }" + - filter: "[M, N, O, P, Q, R] -> { S55[i0] }" + - filter: "[M, N, O, P, Q, R] -> { S56[i0] }" + - filter: "[M, N, O, P, Q, R] -> { S57[i0] }" + - filter: "[M, N, O, P, Q, R] -> { S58[i0] }" + - filter: "[M, N, O, P, Q, R] -> { S60[i0, i1, i2]; S59[i0, i1, i2]; S61[i0, i1, i2] }" + child: + schedule: "[M, N, O, P, Q, R] -> [{ S61[i0, i1, i2] -> [(i1)]; S59[i0, i1, i2] -> [(i1)]; S60[i0, i1, i2] -> [(i1)] }]" + options: "[M, N, O, P, Q, R] -> { separate[i0] }" + child: + schedule: "[M, N, O, P, Q, R] -> [{ S61[i0, i1, i2] -> [(i2)]; S59[i0, i1, i2] -> [(i2)]; S60[i0, i1, i2] -> [(i2)] }]" + options: "[M, N, O, P, Q, R] -> { separate[i0] }" + child: + sequence: + - filter: "[M, N, O, P, Q, R] -> { S59[i0, i1, i2] }" + - filter: "[M, N, O, P, Q, R] -> { S60[i0, i1, i2] }" + - filter: "[M, N, O, P, Q, R] -> { S61[i0, i1, i2] }" + - filter: "[M, N, O, P, Q, R] -> { S62[i0, i1]; S63[i0, i1]; S64[i0, i1] }" + child: + schedule: "[M, N, O, P, Q, R] -> [{ S64[i0, i1] -> [(i1)]; S62[i0, i1] -> [(i1)]; S63[i0, i1] -> [(i1)] }]" + options: "[M, N, O, P, Q, R] -> { separate[i0] }" + child: + sequence: + - filter: "[M, N, O, P, Q, R] -> { S62[i0, i1] }" + - filter: "[M, N, O, P, Q, R] -> { S63[i0, i1] }" + - filter: "[M, N, O, P, Q, R] -> { S64[i0, i1] }" + - filter: "[M, N, O, P, Q, R] -> { S65[i0, i1]; S66[i0, i1]; S67[i0, i1] }" + child: + schedule: "[M, N, O, P, Q, R] -> [{ S66[i0, i1] -> [(i1)]; S65[i0, i1] -> [(i1)]; S67[i0, i1] -> [(i1)] }]" + options: "[M, N, O, P, Q, R] -> { separate[i0] }" + child: + sequence: + - filter: "[M, N, O, P, Q, R] -> { S65[i0, i1] }" + - filter: "[M, N, O, P, Q, R] -> { S66[i0, i1] }" + - filter: "[M, N, O, P, Q, R] -> { S67[i0, i1] }" + - filter: "[M, N, O, P, Q, R] -> { S68[i0] }" + - filter: "[M, N, O, P, Q, R] -> { S69[i0] }" + - filter: "[M, N, O, P, Q, R] -> { S70[i0] }" + - filter: "[M, N, O, P, Q, R] -> { S71[i0] }" + - filter: "[M, N, O, P, Q, R] -> { S72[i0] }" + - filter: "[M, N, O, P, Q, R] -> { S73[i0] }" + - filter: "[M, N, O, P, Q, R] -> { S74[i0] }" + - filter: "[M, N, O, P, Q, R] -> { S75[i0] }" + - filter: "[M, N, O, P, Q, R] -> { S76[i0] }" + - filter: "[M, N, O, P, Q, R] -> { S77[i0] }" + - filter: "[M, N, O, P, Q, R] -> { S78[i0] }" + - filter: "[M, N, O, P, Q, R] -> { S79[i0] }" + - filter: "[M, N, O, P, Q, R] -> { S80[i0] }" + - filter: "[M, N, O, P, Q, R] -> { S81[i0] }" + - filter: "[M, N, O, P, Q, R] -> { S82[i0] }" + - filter: "[M, N, O, P, Q, R] -> { S83[i0] }" + - filter: "[M, N, O, P, Q, R] -> { S84[i0] }" + - filter: "[M, N, O, P, Q, R] -> { S85[i0] }" + - filter: "[M, N, O, P, Q, R] -> { S86[i0] }" + - filter: "[M, N, O, P, Q, R] -> { S87[i0] }" + - filter: "[M, N, O, P, Q, R] -> { S88[i0] }" + - filter: "[M, N, O, P, Q, R] -> { S89[i0] }" + - filter: "[M, N, O, P, Q, R] -> { S90[i0] }" + - filter: "[M, N, O, P, Q, R] -> { S91[i0] }" + - filter: "[M, N, O, P, Q, R] -> { S92[i0] }" + - filter: "[M, N, O, P, Q, R] -> { S93[i0] }" + - filter: "[M, N, O, P, Q, R] -> { S94[i0] }" + - filter: "[M, N, O, P, Q, R] -> { S96[i0, i1, i2]; S98[i0, i1]; S97[i0, i1, i2]; S95[i0, i1, i2] }" + child: + schedule: "[M, N, O, P, Q, R] -> [{ S98[i0, i1] -> [(i1)]; S95[i0, i1, i2] -> [(i1)]; S96[i0, i1, i2] -> [(i1)]; S97[i0, i1, i2] -> [(i1)] }]" + options: "[M, N, O, P, Q, R] -> { separate[i0] }" + child: + sequence: + - filter: "[M, N, O, P, Q, R] -> { S96[i0, i1, i2]; S97[i0, i1, i2]; S95[i0, i1, i2] }" + child: + schedule: "[M, N, O, P, Q, R] -> [{ S95[i0, i1, i2] -> [(i2)]; S96[i0, i1, i2] -> [(i2)]; S97[i0, i1, i2] -> [(i2)] }]" + options: "[M, N, O, P, Q, R] -> { separate[i0] }" + child: + sequence: + - filter: "[M, N, O, P, Q, R] -> { S95[i0, i1, i2] }" + - filter: "[M, N, O, P, Q, R] -> { S96[i0, i1, i2] }" + - filter: "[M, N, O, P, Q, R] -> { S97[i0, i1, i2] }" + - filter: "[M, N, O, P, Q, R] -> { S98[i0, i1] }" + - filter: "[M, N, O, P, Q, R] -> { S99[i0] }" + - filter: "[M, N, O, P, Q, R] -> { S100[i0] }" + - filter: "[M, N, O, P, Q, R] -> { S101[i0] }" + - filter: "[M, N, O, P, Q, R] -> { S107[i0, i1, i2]; S105[i0, i1, i2]; S102[i0, i1, i2]; S104[i0, i1, i2]; S106[i0, i1, i2]; S103[i0, i1, i2] }" + child: + schedule: "[M, N, O, P, Q, R] -> [{ S102[i0, i1, i2] -> [(i1)]; S103[i0, i1, i2] -> [(i1)]; S104[i0, i1, i2] -> [(i1)]; S107[i0, i1, i2] -> [(i1)]; S106[i0, i1, i2] -> [(i1)]; S105[i0, i1, i2] -> [(i1)] }]" + options: "[M, N, O, P, Q, R] -> { separate[i0] }" + child: + schedule: "[M, N, O, P, Q, R] -> [{ S102[i0, i1, i2] -> [(i2)]; S103[i0, i1, i2] -> [(i2)]; S104[i0, i1, i2] -> [(i2)]; S107[i0, i1, i2] -> [(i2)]; S106[i0, i1, i2] -> [(i2)]; S105[i0, i1, i2] -> [(i2)] }]" + options: "[M, N, O, P, Q, R] -> { separate[i0] }" + child: + sequence: + - filter: "[M, N, O, P, Q, R] -> { S102[i0, i1, i2] }" + - filter: "[M, N, O, P, Q, R] -> { S103[i0, i1, i2] }" + - filter: "[M, N, O, P, Q, R] -> { S104[i0, i1, i2] }" + - filter: "[M, N, O, P, Q, R] -> { S105[i0, i1, i2] }" + - filter: "[M, N, O, P, Q, R] -> { S106[i0, i1, i2] }" + - filter: "[M, N, O, P, Q, R] -> { S107[i0, i1, i2] }" + - filter: "[M, N, O, P, Q, R] -> { S113[i0, i1]; S112[i0, i1]; S108[i0, i1]; S111[i0, i1]; S110[i0, i1]; S109[i0, i1] }" + child: + schedule: "[M, N, O, P, Q, R] -> [{ S110[i0, i1] -> [(i1)]; S112[i0, i1] -> [(i1)]; S111[i0, i1] -> [(i1)]; S113[i0, i1] -> [(i1)]; S109[i0, i1] -> [(i1)]; S108[i0, i1] -> [(i1)] }]" + options: "[M, N, O, P, Q, R] -> { separate[i0] }" + child: + sequence: + - filter: "[M, N, O, P, Q, R] -> { S108[i0, i1] }" + - filter: "[M, N, O, P, Q, R] -> { S109[i0, i1] }" + - filter: "[M, N, O, P, Q, R] -> { S110[i0, i1] }" + - filter: "[M, N, O, P, Q, R] -> { S111[i0, i1] }" + - filter: "[M, N, O, P, Q, R] -> { S112[i0, i1] }" + - filter: "[M, N, O, P, Q, R] -> { S113[i0, i1] }" + - filter: "[M, N, O, P, Q, R] -> { S119[i0, i1]; S114[i0, i1]; S117[i0, i1]; S115[i0, i1]; S118[i0, i1]; S116[i0, i1] }" + child: + schedule: "[M, N, O, P, Q, R] -> [{ S115[i0, i1] -> [(i1)]; S116[i0, i1] -> [(i1)]; S118[i0, i1] -> [(i1)]; S117[i0, i1] -> [(i1)]; S119[i0, i1] -> [(i1)]; S114[i0, i1] -> [(i1)] }]" + options: "[M, N, O, P, Q, R] -> { separate[i0] }" + child: + sequence: + - filter: "[M, N, O, P, Q, R] -> { S114[i0, i1] }" + - filter: "[M, N, O, P, Q, R] -> { S115[i0, i1] }" + - filter: "[M, N, O, P, Q, R] -> { S116[i0, i1] }" + - filter: "[M, N, O, P, Q, R] -> { S117[i0, i1] }" + - filter: "[M, N, O, P, Q, R] -> { S118[i0, i1] }" + - filter: "[M, N, O, P, Q, R] -> { S119[i0, i1] }" + - filter: "[M, N, O, P, Q, R] -> { S120[i0] }" + - filter: "[M, N, O, P, Q, R] -> { S121[i0] }" + - filter: "[M, N, O, P, Q, R] -> { S122[i0] }" + - filter: "[M, N, O, P, Q, R] -> { S123[i0] }" + - filter: "[M, N, O, P, Q, R] -> { S124[i0] }" + - filter: "[M, N, O, P, Q, R] -> { S125[i0] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/test.c b/external/mit/isl/dist/test_inputs/codegen/cloog/test.c new file mode 100644 index 000000000000..1abafb0f4890 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/test.c @@ -0,0 +1,15 @@ +for (int c0 = 1; c0 <= 2; c0 += 1) + for (int c1 = 1; c1 <= M; c1 += 1) + S1(c0, c1); +for (int c0 = 3; c0 <= N; c0 += 1) { + for (int c1 = 1; c1 <= min(M, c0 - 1); c1 += 1) + S1(c0, c1); + if (M >= c0) { + S1(c0, c0); + S2(c0, c0); + } + for (int c1 = c0 + 1; c1 <= M; c1 += 1) + S1(c0, c1); + if (c0 >= M + 1) + S2(c0, c0); +} diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/test.st b/external/mit/isl/dist/test_inputs/codegen/cloog/test.st new file mode 100644 index 000000000000..97a290ed5013 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/test.st @@ -0,0 +1,10 @@ +domain: "[M, N] -> { S1[i0, i1] : i0 >= 1 and i0 <= N and i1 >= 1 and i1 <= M; S2[i0, i0] : i0 >= 3 and i0 <= N }" +child: + context: "[M, N] -> { [] : N >= M and M >= 4 }" + child: + schedule: "[M, N] -> [{ S1[i0, i1] -> [(i0)]; S2[i0, i1] -> [(i0)] }, { S1[i0, i1] -> [(i1)]; S2[i0, i1] -> [(i1)] }]" + options: "[M, N] -> { separate[i0] }" + child: + sequence: + - filter: "[M, N] -> { S1[i0, i1] }" + - filter: "[M, N] -> { S2[i0, i1] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/thomasset.c b/external/mit/isl/dist/test_inputs/codegen/cloog/thomasset.c new file mode 100644 index 000000000000..f52de94add66 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/thomasset.c @@ -0,0 +1,7 @@ +for (int c0 = 0; c0 <= floord(n - 1, 3); c0 += 1) + for (int c2 = 3 * c0 + 1; c2 <= min(n, 3 * c0 + 3); c2 += 1) + S1(c2, c0); +for (int c0 = floord(n, 3); c0 <= 2 * floord(n, 3); c0 += 1) + for (int c1 = 0; c1 < n; c1 += 1) + for (int c3 = max(1, (n % 3) - n + 3 * c0); c3 <= min(n, (n % 3) - n + 3 * c0 + 2); c3 += 1) + S2(c1 + 1, c3, 0, n / 3, c0 - n / 3); diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/thomasset.st b/external/mit/isl/dist/test_inputs/codegen/cloog/thomasset.st new file mode 100644 index 000000000000..612b650545b1 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/thomasset.st @@ -0,0 +1,6 @@ +domain: "[n] -> { S1[i, j] : i <= n and i >= 1 and 3j <= -1 + i and 3j >= -3 + i; S2[i, j, 0, p, q] : i <= n and j <= n and j >= 1 and i >= 1 and 3q <= j and 3q >= -2 + j and 3p <= n and 3p >= -2 + n }" +child: + context: "[n] -> { [] }" + child: + schedule: "[n] -> [{ S2[i0, i1, i2, i3, i4] -> [(i2 + i3 + i4)]; S1[i0, i1] -> [(i1)] }, { S2[i0, i1, i2, i3, i4] -> [(-1 + i0)]; S1[i0, i1] -> [(0)] }]" + options: "[n] -> { separate[i0] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/tiling.c b/external/mit/isl/dist/test_inputs/codegen/cloog/tiling.c new file mode 100644 index 000000000000..971b988a578d --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/tiling.c @@ -0,0 +1,3 @@ +for (int c0 = 0; c0 <= n / 10; c0 += 1) + for (int c1 = 10 * c0; c1 <= min(n, 10 * c0 + 9); c1 += 1) + S1(c0, c1); diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/tiling.st b/external/mit/isl/dist/test_inputs/codegen/cloog/tiling.st new file mode 100644 index 000000000000..5e8f0af7662e --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/tiling.st @@ -0,0 +1,6 @@ +domain: "[n] -> { S1[ii, i] : i >= 0 and i <= n and i <= 9 + 10ii and i >= 10ii }" +child: + context: "[n] -> { [] : n >= 0 }" + child: + schedule: "[n] -> [{ S1[ii, i] -> [(ii)] }, { S1[ii, i] -> [(i)] }]" + options: "[n] -> { separate[i0] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/uday_scalars.c b/external/mit/isl/dist/test_inputs/codegen/cloog/uday_scalars.c new file mode 100644 index 000000000000..904dc24df568 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/uday_scalars.c @@ -0,0 +1,4 @@ +for (int c0 = 0; c0 <= n; c0 += 1) + S1(c0, 0, 0); +for (int c0 = 0; c0 <= n; c0 += 1) + S2(0, c0, 0); diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/uday_scalars.st b/external/mit/isl/dist/test_inputs/codegen/cloog/uday_scalars.st new file mode 100644 index 000000000000..1501e8321a39 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/uday_scalars.st @@ -0,0 +1,13 @@ +domain: "[n] -> { S1[j, 0, 0] : j >= 0 and j <= n; S2[0, l, 0] : l >= 0 and l <= n }" +child: + context: "[n] -> { [] }" + child: + sequence: + - filter: "[n] -> { S1[i0, i1, i2] }" + child: + schedule: "[n] -> [{ S1[i0, i1, i2] -> [(i0)] }]" + options: "[n] -> { separate[i0] }" + - filter: "[n] -> { S2[i0, i1, i2] }" + child: + schedule: "[n] -> [{ S2[i0, i1, i2] -> [(i1)] }]" + options: "[n] -> { separate[i0] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/union.c b/external/mit/isl/dist/test_inputs/codegen/cloog/union.c new file mode 100644 index 000000000000..b9daaf95a8a2 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/union.c @@ -0,0 +1,7 @@ +if (M >= 11) { + for (int c0 = -100; c0 <= 0; c0 += 1) + S1(-c0); +} else { + for (int c0 = 0; c0 <= 100; c0 += 1) + S1(c0); +} diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/union.st b/external/mit/isl/dist/test_inputs/codegen/cloog/union.st new file mode 100644 index 000000000000..c2622dc8690d --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/union.st @@ -0,0 +1,6 @@ +domain: "[M] -> { S1[i0] : i0 >= 0 and i0 <= 100 }" +child: + context: "[M] -> { [] : M >= 1 or M <= -1 }" + child: + schedule: "[M] -> [{ S1[i0] -> [(i0)] : M <= 10; S1[i0] -> [(-i0)] : M >= 11 }]" + options: "[M] -> { separate[i0] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/unroll.c b/external/mit/isl/dist/test_inputs/codegen/cloog/unroll.c new file mode 100644 index 000000000000..8dee4f883715 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/unroll.c @@ -0,0 +1,11 @@ +S1(0); +S1(1); +S1(2); +S1(3); +S1(4); +S1(5); +S1(6); +S1(7); +S1(8); +S1(9); +S1(10); diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/unroll.st b/external/mit/isl/dist/test_inputs/codegen/cloog/unroll.st new file mode 100644 index 000000000000..8780a633fcdf --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/unroll.st @@ -0,0 +1,6 @@ +domain: "[n] -> { S1[i] : i >= 0 and i <= 10 }" +child: + context: "[n] -> { [] }" + child: + schedule: "[n] -> [{ S1[i] -> [(i)] }]" + options: "[n] -> { unroll[i0] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/unroll2.c b/external/mit/isl/dist/test_inputs/codegen/cloog/unroll2.c new file mode 100644 index 000000000000..58f2705c8522 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/unroll2.c @@ -0,0 +1,5 @@ +if (n >= -1 && n <= 9) { + if (n >= 0) + S1(n); + S1(n + 1); +} diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/unroll2.st b/external/mit/isl/dist/test_inputs/codegen/cloog/unroll2.st new file mode 100644 index 000000000000..32cbb8cb3829 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/unroll2.st @@ -0,0 +1,6 @@ +domain: "[n] -> { S1[i] : i >= n and i <= 1 + n and n <= 9 and i >= 0 }" +child: + context: "[n] -> { [] }" + child: + schedule: "[n] -> [{ S1[i] -> [(i)] }]" + options: "[n] -> { unroll[i0] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/usvd_e_t.c b/external/mit/isl/dist/test_inputs/codegen/cloog/usvd_e_t.c new file mode 100644 index 000000000000..ed92b95bf7db --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/usvd_e_t.c @@ -0,0 +1,346 @@ +for (int c0 = 0; c0 <= 2; c0 += 1) { + S1(c0, 0, 0); + for (int c1 = 0; c1 <= 4; c1 += 1) + S2(c0, c1, 0); +} +S1(3, 0, 0); +for (int c1 = 0; c1 <= 4; c1 += 1) + S2(3, c1, 0); +for (int c1 = 7; c1 <= 11; c1 += 1) + S8(3, c1, 0); +S1(4, 0, 0); +S2(4, 0, 0); +S3(4, 0, 0); +S5(4, 0, 0); +for (int c1 = 1; c1 <= 4; c1 += 1) { + S2(4, c1, 0); + S5(4, c1, 0); +} +for (int c1 = 7; c1 <= 11; c1 += 1) + S8(4, c1, 0); +for (int c0 = 5; c0 <= 6; c0 += 1) { + for (int c1 = -4; c1 < c0 - 8; c1 += 1) + S6(c0, c1, 0); + for (int c1 = c0 - 9; c1 < 0; c1 += 1) + S7(c0, c1, 0); + S3(c0, 0, 0); + S7(c0, 0, 0); + for (int c1 = 1; c1 < c0 - 3; c1 += 1) + S4(c0, c1, -1); + for (int c1 = c0 - 4; c1 <= 4; c1 += 1) + S5(c0, c1, 0); + for (int c1 = 7; c1 <= 11; c1 += 1) + S8(c0, c1, 0); +} +for (int c1 = -4; c1 < -1; c1 += 1) + S6(7, c1, 0); +for (int c1 = -2; c1 < 0; c1 += 1) + S7(7, c1, 0); +S3(7, 0, 0); +S7(7, 0, 0); +for (int c1 = 1; c1 <= 3; c1 += 1) + S4(7, c1, -1); +for (int c1 = 3; c1 <= 4; c1 += 1) + S5(7, c1, 0); +S9(7, 4, 0); +S10(7, 4, 0); +S11(7, 4, 0); +S21(7, 4, 0); +S23(7, 4, 0); +S11(7, 4, 1); +S16(7, 4, 1); +S17(7, 4, 1); +for (int c2 = 2; c2 <= 4; c2 += 1) + S11(7, 4, c2); +S12(7, 5, 0); +S21(7, 5, 0); +S22(7, 5, 0); +S23(7, 5, 0); +S12(7, 5, 1); +S16(7, 5, 1); +S17(7, 5, 1); +for (int c2 = 2; c2 <= 4; c2 += 1) + S12(7, 5, c2); +S21(7, 6, 0); +S22(7, 6, 0); +S23(7, 6, 0); +for (int c1 = 7; c1 <= 8; c1 += 1) { + S8(7, c1, 0); + S21(7, c1, 0); + S22(7, c1, 0); + S23(7, c1, 0); +} +S8(7, 9, 0); +S22(7, 9, 0); +for (int c1 = 10; c1 <= 11; c1 += 1) + S8(7, c1, 0); +for (int c1 = -4; c1 < 0; c1 += 1) + S6(8, c1, 0); +S7(8, -1, 0); +S3(8, 0, 0); +S7(8, 0, 0); +S19(8, 1, -2); +S4(8, 1, -1); +S19(8, 1, -1); +S19(8, 1, 0); +S15(8, 1, 4); +S18(8, 1, 4); +for (int c2 = -4; c2 < -2; c2 += 1) { + S14(8, 2, c2); + S20(8, 2, c2); +} +S14(8, 2, -2); +S19(8, 2, -2); +S20(8, 2, -2); +S4(8, 2, -1); +S14(8, 2, -1); +S19(8, 2, -1); +S20(8, 2, -1); +S14(8, 2, 0); +S19(8, 2, 0); +S20(8, 2, 0); +S15(8, 2, 4); +S18(8, 2, 4); +for (int c2 = -4; c2 < -1; c2 += 1) { + S14(8, 3, c2); + S20(8, 3, c2); +} +S4(8, 3, -1); +S14(8, 3, -1); +S20(8, 3, -1); +S14(8, 3, 0); +S20(8, 3, 0); +S15(8, 3, 4); +S18(8, 3, 4); +for (int c2 = -4; c2 < -1; c2 += 1) { + S14(8, 4, c2); + S20(8, 4, c2); +} +S4(8, 4, -1); +S14(8, 4, -1); +S20(8, 4, -1); +S5(8, 4, 0); +S9(8, 4, 0); +S10(8, 4, 0); +S14(8, 4, 0); +S20(8, 4, 0); +S23(8, 4, 0); +S13(8, 4, 1); +S21(8, 4, 1); +S23(8, 4, 1); +S24(8, 4, 1); +S13(8, 4, 2); +S16(8, 4, 2); +S17(8, 4, 2); +S24(8, 4, 2); +S13(8, 4, 3); +S24(8, 4, 3); +S13(8, 4, 4); +S15(8, 4, 4); +S23(8, 5, 0); +S11(8, 5, 1); +S21(8, 5, 1); +S22(8, 5, 1); +S23(8, 5, 1); +S24(8, 5, 1); +S11(8, 5, 2); +S16(8, 5, 2); +S17(8, 5, 2); +S24(8, 5, 2); +S11(8, 5, 3); +S24(8, 5, 3); +S11(8, 5, 4); +S15(8, 5, 4); +S23(8, 6, 0); +S12(8, 6, 1); +S21(8, 6, 1); +S22(8, 6, 1); +S23(8, 6, 1); +S24(8, 6, 1); +S12(8, 6, 2); +S16(8, 6, 2); +S17(8, 6, 2); +S24(8, 6, 2); +S12(8, 6, 3); +S24(8, 6, 3); +S12(8, 6, 4); +for (int c1 = 7; c1 <= 8; c1 += 1) { + S23(8, c1, 0); + S21(8, c1, 1); + S22(8, c1, 1); + S23(8, c1, 1); + for (int c2 = 1; c2 <= 3; c2 += 1) + S24(8, c1, c2); +} +S22(8, 9, 1); +S7(9, 0, 0); +for (int c1 = 1; c1 <= 2; c1 += 1) { + for (int c2 = -1; c2 <= 0; c2 += 1) + S19(9, c1, c2); + for (int c2 = 4; c2 <= 5; c2 += 1) { + S15(9, c1, c2); + S18(9, c1, c2); + } +} +S20(9, 3, -4); +for (int c2 = -3; c2 < -1; c2 += 1) { + S14(9, 3, c2); + S20(9, 3, c2); +} +for (int c2 = -1; c2 <= 0; c2 += 1) { + S14(9, 3, c2); + S19(9, 3, c2); + S20(9, 3, c2); +} +for (int c2 = 4; c2 <= 5; c2 += 1) { + S15(9, 3, c2); + S18(9, 3, c2); +} +S20(9, 4, -4); +for (int c2 = -3; c2 < 0; c2 += 1) { + S14(9, 4, c2); + S20(9, 4, c2); +} +S9(9, 4, 0); +S10(9, 4, 0); +S14(9, 4, 0); +S20(9, 4, 0); +for (int c2 = 0; c2 <= 1; c2 += 1) + S23(9, 4, c2); +S13(9, 4, 2); +S21(9, 4, 2); +S23(9, 4, 2); +S24(9, 4, 2); +S13(9, 4, 3); +S16(9, 4, 3); +S17(9, 4, 3); +S24(9, 4, 3); +S13(9, 4, 4); +for (int c2 = 4; c2 <= 5; c2 += 1) { + S15(9, 4, c2); + S18(9, 4, c2); +} +for (int c2 = 0; c2 <= 1; c2 += 1) + S23(9, 5, c2); +S13(9, 5, 2); +S21(9, 5, 2); +S22(9, 5, 2); +S23(9, 5, 2); +S24(9, 5, 2); +S13(9, 5, 3); +S16(9, 5, 3); +S17(9, 5, 3); +S24(9, 5, 3); +S13(9, 5, 4); +for (int c2 = 4; c2 <= 5; c2 += 1) + S15(9, 5, c2); +for (int c2 = 0; c2 <= 1; c2 += 1) + S23(9, 6, c2); +S11(9, 6, 2); +S21(9, 6, 2); +S22(9, 6, 2); +S23(9, 6, 2); +S24(9, 6, 2); +S11(9, 6, 3); +S16(9, 6, 3); +S17(9, 6, 3); +S24(9, 6, 3); +S11(9, 6, 4); +for (int c2 = 0; c2 <= 1; c2 += 1) + S23(9, 7, c2); +S12(9, 7, 2); +S21(9, 7, 2); +S22(9, 7, 2); +S23(9, 7, 2); +S24(9, 7, 2); +S12(9, 7, 3); +S16(9, 7, 3); +S17(9, 7, 3); +S24(9, 7, 3); +S12(9, 7, 4); +for (int c2 = 0; c2 <= 1; c2 += 1) + S23(9, 8, c2); +S21(9, 8, 2); +S22(9, 8, 2); +S23(9, 8, 2); +for (int c2 = 2; c2 <= 3; c2 += 1) + S24(9, 8, c2); +S22(9, 9, 2); +for (int c1 = 1; c1 <= 3; c1 += 1) { + S19(10, c1, 0); + S26(10, c1, 3); + S15(10, c1, 4); + S18(10, c1, 4); + S25(10, c1, 4); + for (int c2 = 5; c2 <= 6; c2 += 1) { + S15(10, c1, c2); + S18(10, c1, c2); + } +} +for (int c2 = -4; c2 < -2; c2 += 1) + S20(10, 4, c2); +for (int c2 = -2; c2 < 0; c2 += 1) { + S14(10, 4, c2); + S20(10, 4, c2); +} +S9(10, 4, 0); +S10(10, 4, 0); +S14(10, 4, 0); +S19(10, 4, 0); +S20(10, 4, 0); +S13(10, 4, 3); +S21(10, 4, 3); +S24(10, 4, 3); +S26(10, 4, 3); +S13(10, 4, 4); +S15(10, 4, 4); +S16(10, 4, 4); +S17(10, 4, 4); +S18(10, 4, 4); +S25(10, 4, 4); +for (int c2 = 5; c2 <= 6; c2 += 1) { + S15(10, 4, c2); + S18(10, 4, c2); +} +S13(10, 5, 3); +S21(10, 5, 3); +S22(10, 5, 3); +S24(10, 5, 3); +S26(10, 5, 3); +S13(10, 5, 4); +S15(10, 5, 4); +S16(10, 5, 4); +S17(10, 5, 4); +S18(10, 5, 4); +S25(10, 5, 4); +for (int c2 = 5; c2 <= 6; c2 += 1) { + S15(10, 5, c2); + S18(10, 5, c2); +} +S13(10, 6, 3); +S21(10, 6, 3); +S22(10, 6, 3); +S24(10, 6, 3); +S13(10, 6, 4); +S16(10, 6, 4); +S17(10, 6, 4); +S11(10, 7, 3); +S21(10, 7, 3); +S22(10, 7, 3); +S24(10, 7, 3); +S11(10, 7, 4); +S16(10, 7, 4); +S17(10, 7, 4); +S12(10, 8, 3); +S21(10, 8, 3); +S22(10, 8, 3); +S24(10, 8, 3); +S12(10, 8, 4); +S16(10, 8, 4); +S17(10, 8, 4); +S22(10, 9, 3); +for (int c0 = 11; c0 <= 14; c0 += 1) + for (int c1 = 1; c1 <= 5; c1 += 1) { + S26(c0, c1, 3); + S25(c0, c1, 4); + } diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/usvd_e_t.st b/external/mit/isl/dist/test_inputs/codegen/cloog/usvd_e_t.st new file mode 100644 index 000000000000..649416598721 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/usvd_e_t.st @@ -0,0 +1,34 @@ +domain: "{ S22[i0, i1, -7 + i0] : i0 >= 7 and i1 >= 5 and i1 <= 9 and i0 <= 10; S21[i0, i1, -7 + i0] : i0 <= 10 and i1 >= 4 and i1 <= 8 and i0 >= 7; S4[i0, i1, -1] : i0 <= 8 and i1 >= 1 and i1 <= -4 + i0; S8[i0, i1, 0] : i0 >= 3 and i0 <= 7 and i1 >= 7 and i1 <= 11; S25[i0, i1, 4] : i0 >= 10 and i0 <= 14 and i1 >= 1 and i1 <= 5; S15[i0, i1, i2] : i0 <= 10 and i1 >= 1 and i1 <= 5 and i2 >= 4 and i2 <= -4 + i0; S6[i0, i1, 0] : i0 <= 8 and i1 >= -4 and i1 <= -9 + i0; S16[i0, i1, -6 + i0] : i0 <= 10 and i1 >= 4 and i0 >= 7 and i1 <= -2 + i0; S7[i0, i1, 0] : i0 >= 5 and i1 <= 0 and i1 >= -9 + i0; S1[i0, 0, 0] : i0 >= 0 and i0 <= 4; S2[i0, i1, 0] : i0 >= 0 and i0 <= 4 and i1 >= 0 and i1 <= 4; S26[i0, i1, 3] : i0 >= 10 and i0 <= 14 and i1 >= 1 and i1 <= 5; S10[i0, 4, 0] : i0 >= 7 and i0 <= 10; S12[i0, -2 + i0, i2] : i0 >= 7 and i0 <= 10 and i2 <= 4 and i2 >= -7 + i0; S23[i0, i1, i2] : i0 <= 9 and i1 >= 4 and i1 <= 8 and i2 >= 0 and i2 <= -7 + i0; S13[i0, i1, i2] : i0 <= 10 and i1 >= 4 and i2 <= 4 and i2 >= -7 + i0 and i1 <= -4 + i0; S20[i0, i1, i2] : i0 >= 8 and i1 <= 4 and i2 >= -4 and i2 <= 0 and i1 >= -6 + i0; S24[i0, i1, i2] : i0 >= 8 and i1 >= 4 and i1 <= 8 and i2 <= 3 and i2 >= -7 + i0; S19[i0, i1, i2] : i0 >= 8 and i1 >= 1 and i2 <= 0 and i2 >= -10 + i0 and i1 <= -6 + i0; S11[i0, -3 + i0, i2] : i0 <= 10 and i0 >= 7 and i2 <= 4 and i2 >= -7 + i0; S14[i0, i1, i2] : i0 >= 8 and i1 <= 4 and i2 <= 0 and i2 >= -12 + i0 and i1 >= -6 + i0; S3[i0, 0, 0] : i0 >= 4 and i0 <= 8; S9[i0, 4, 0] : i0 >= 7 and i0 <= 10; S18[i0, i1, i2] : i0 <= 10 and i1 >= 1 and i2 >= 4 and i2 <= -4 + i0 and i1 <= -5 + i0; S5[i0, i1, 0] : i0 >= 4 and i1 <= 4 and i1 >= -4 + i0; S17[i0, i1, -6 + i0] : i0 >= 7 and i1 >= 4 and i0 <= 10 and i1 <= -2 + i0 }" +child: + context: "{ [] }" + child: + schedule: "[{ S8[i0, i1, i2] -> [(i0)]; S21[i0, i1, i2] -> [(i0)]; S9[i0, i1, i2] -> [(i0)]; S10[i0, i1, i2] -> [(i0)]; S24[i0, i1, i2] -> [(i0)]; S15[i0, i1, i2] -> [(i0)]; S12[i0, i1, i2] -> [(i0)]; S7[i0, i1, i2] -> [(i0)]; S6[i0, i1, i2] -> [(i0)]; S23[i0, i1, i2] -> [(i0)]; S22[i0, i1, i2] -> [(i0)]; S16[i0, i1, i2] -> [(i0)]; S17[i0, i1, i2] -> [(i0)]; S25[i0, i1, i2] -> [(i0)]; S18[i0, i1, i2] -> [(i0)]; S26[i0, i1, i2] -> [(i0)]; S5[i0, i1, i2] -> [(i0)]; S2[i0, i1, i2] -> [(i0)]; S4[i0, i1, i2] -> [(i0)]; S13[i0, i1, i2] -> [(i0)]; S3[i0, i1, i2] -> [(i0)]; S14[i0, i1, i2] -> [(i0)]; S19[i0, i1, i2] -> [(i0)]; S20[i0, i1, i2] -> [(i0)]; S11[i0, i1, i2] -> [(i0)]; S1[i0, i1, i2] -> [(i0)] }, { S8[i0, i1, i2] -> [(i1)]; S21[i0, i1, i2] -> [(i1)]; S9[i0, i1, i2] -> [(i1)]; S10[i0, i1, i2] -> [(i1)]; S24[i0, i1, i2] -> [(i1)]; S15[i0, i1, i2] -> [(i1)]; S12[i0, i1, i2] -> [(i1)]; S7[i0, i1, i2] -> [(i1)]; S6[i0, i1, i2] -> [(i1)]; S23[i0, i1, i2] -> [(i1)]; S22[i0, i1, i2] -> [(i1)]; S16[i0, i1, i2] -> [(i1)]; S17[i0, i1, i2] -> [(i1)]; S25[i0, i1, i2] -> [(i1)]; S18[i0, i1, i2] -> [(i1)]; S26[i0, i1, i2] -> [(i1)]; S5[i0, i1, i2] -> [(i1)]; S2[i0, i1, i2] -> [(i1)]; S4[i0, i1, i2] -> [(i1)]; S13[i0, i1, i2] -> [(i1)]; S3[i0, i1, i2] -> [(i1)]; S14[i0, i1, i2] -> [(i1)]; S19[i0, i1, i2] -> [(i1)]; S20[i0, i1, i2] -> [(i1)]; S11[i0, i1, i2] -> [(i1)]; S1[i0, i1, i2] -> [(i1)] }, { S8[i0, i1, i2] -> [(i2)]; S21[i0, i1, i2] -> [(i2)]; S9[i0, i1, i2] -> [(i2)]; S10[i0, i1, i2] -> [(i2)]; S24[i0, i1, i2] -> [(i2)]; S15[i0, i1, i2] -> [(i2)]; S12[i0, i1, i2] -> [(i2)]; S7[i0, i1, i2] -> [(i2)]; S6[i0, i1, i2] -> [(i2)]; S23[i0, i1, i2] -> [(i2)]; S22[i0, i1, i2] -> [(i2)]; S16[i0, i1, i2] -> [(i2)]; S17[i0, i1, i2] -> [(i2)]; S25[i0, i1, i2] -> [(i2)]; S18[i0, i1, i2] -> [(i2)]; S26[i0, i1, i2] -> [(i2)]; S5[i0, i1, i2] -> [(i2)]; S2[i0, i1, i2] -> [(i2)]; S4[i0, i1, i2] -> [(i2)]; S13[i0, i1, i2] -> [(i2)]; S3[i0, i1, i2] -> [(i2)]; S14[i0, i1, i2] -> [(i2)]; S19[i0, i1, i2] -> [(i2)]; S20[i0, i1, i2] -> [(i2)]; S11[i0, i1, i2] -> [(i2)]; S1[i0, i1, i2] -> [(i2)] }]" + options: "{ separate[i0] }" + child: + sequence: + - filter: "{ S1[i0, i1, i2] }" + - filter: "{ S2[i0, i1, i2] }" + - filter: "{ S3[i0, i1, i2] }" + - filter: "{ S4[i0, i1, i2] }" + - filter: "{ S5[i0, i1, i2] }" + - filter: "{ S6[i0, i1, i2] }" + - filter: "{ S7[i0, i1, i2] }" + - filter: "{ S8[i0, i1, i2] }" + - filter: "{ S9[i0, i1, i2] }" + - filter: "{ S10[i0, i1, i2] }" + - filter: "{ S11[i0, i1, i2] }" + - filter: "{ S12[i0, i1, i2] }" + - filter: "{ S13[i0, i1, i2] }" + - filter: "{ S14[i0, i1, i2] }" + - filter: "{ S15[i0, i1, i2] }" + - filter: "{ S16[i0, i1, i2] }" + - filter: "{ S17[i0, i1, i2] }" + - filter: "{ S18[i0, i1, i2] }" + - filter: "{ S19[i0, i1, i2] }" + - filter: "{ S20[i0, i1, i2] }" + - filter: "{ S21[i0, i1, i2] }" + - filter: "{ S22[i0, i1, i2] }" + - filter: "{ S23[i0, i1, i2] }" + - filter: "{ S24[i0, i1, i2] }" + - filter: "{ S25[i0, i1, i2] }" + - filter: "{ S26[i0, i1, i2] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/vasilache.c b/external/mit/isl/dist/test_inputs/codegen/cloog/vasilache.c new file mode 100644 index 000000000000..e7978f2bcdda --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/vasilache.c @@ -0,0 +1,22 @@ +S1(); +S2(); +for (int c0 = 0; c0 < N; c0 += 1) + for (int c1 = 0; c1 < N; c1 += 1) { + S4(c0, c1); + S5(c0, c1); + } +for (int c0 = 0; c0 < N; c0 += 1) + for (int c1 = 0; c1 < N; c1 += 1) + for (int c2 = 0; c2 <= (N - 1) / 32; c2 += 1) { + S7(c0, c1, c2, 32 * c2); + for (int c3 = 32 * c2 + 1; c3 <= min(N - 1, 32 * c2 + 31); c3 += 1) { + S6(c0, c1, c2, c3 - 1); + S7(c0, c1, c2, c3); + } + if (32 * c2 + 31 >= N) { + S6(c0, c1, c2, N - 1); + } else { + S6(c0, c1, c2, 32 * c2 + 31); + } + } +S8(); diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/vasilache.st b/external/mit/isl/dist/test_inputs/codegen/cloog/vasilache.st new file mode 100644 index 000000000000..f0cd320bbe89 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/vasilache.st @@ -0,0 +1,37 @@ +domain: "[M, N] -> { S5[i0, i1] : i0 >= 0 and i0 <= -1 + N and i1 >= 0 and i1 <= -1 + N; S8[]; S2[]; S7[i0, i1, i2, i3] : i0 >= 0 and i0 <= -1 + N and i1 >= 0 and i1 <= -1 + N and i3 >= 0 and i3 <= -1 + N and i3 >= 32i2 and i3 <= 31 + 32i2; S4[i0, i1] : i0 >= 0 and i0 <= -1 + N and i1 >= 0 and i1 <= -1 + N; S1[]; S3[] : M >= 79; S6[i0, i1, i2, i3] : i0 >= 0 and i0 <= -1 + N and i1 >= 0 and i1 <= -1 + N and i3 >= 0 and i3 <= -1 + N and i3 >= 32i2 and i3 <= 31 + 32i2 }" +child: + context: "[M, N] -> { [] : M <= 3 and N >= 100 }" + child: + sequence: + - filter: "[M, N] -> { S1[] }" + - filter: "[M, N] -> { S2[] }" + - filter: "[M, N] -> { S3[] }" + - filter: "[M, N] -> { S5[i0, i1]; S4[i0, i1] }" + child: + schedule: "[M, N] -> [{ S5[i0, i1] -> [(i0)]; S4[i0, i1] -> [(i0)] }]" + options: "[M, N] -> { separate[i0] }" + child: + schedule: "[M, N] -> [{ S5[i0, i1] -> [(i1)]; S4[i0, i1] -> [(i1)] }]" + options: "[M, N] -> { separate[i0] }" + child: + sequence: + - filter: "[M, N] -> { S4[i0, i1] }" + - filter: "[M, N] -> { S5[i0, i1] }" + - filter: "[M, N] -> { S7[i0, i1, i2, i3]; S6[i0, i1, i2, i3] }" + child: + schedule: "[M, N] -> [{ S7[i0, i1, i2, i3] -> [(i0)]; S6[i0, i1, i2, i3] -> [(i0)] }]" + options: "[M, N] -> { separate[i0] }" + child: + schedule: "[M, N] -> [{ S7[i0, i1, i2, i3] -> [(i1)]; S6[i0, i1, i2, i3] -> [(i1)] }]" + options: "[M, N] -> { separate[i0] }" + child: + schedule: "[M, N] -> [{ S7[i0, i1, i2, i3] -> [(i2)]; S6[i0, i1, i2, i3] -> [(i2)] }]" + options: "[M, N] -> { separate[i0] }" + child: + schedule: "[M, N] -> [{ S7[i0, i1, i2, i3] -> [(i3)]; S6[i0, i1, i2, i3] -> [(1 + i3)] }]" + options: "[M, N] -> { separate[i0] }" + child: + sequence: + - filter: "[M, N] -> { S6[i0, i1, i2, i3] }" + - filter: "[M, N] -> { S7[i0, i1, i2, i3] }" + - filter: "[M, N] -> { S8[] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/vivien.c b/external/mit/isl/dist/test_inputs/codegen/cloog/vivien.c new file mode 100644 index 000000000000..a41c8867043d --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/vivien.c @@ -0,0 +1,85 @@ +for (int c0 = -27 * n + 2; c0 <= 1; c0 += 1) + S1(c0 - 1); +for (int c0 = 2; c0 <= min(2 * n, n + 29); c0 += 1) { + if (c0 >= 3) { + if (2 * n >= c0 + 1) { + S4(c0 - c0 / 2 - 1, c0 / 2 + 1); + if (c0 + 2 >= 2 * n) { + for (int c2 = 1; c2 < -n + c0; c2 += 1) + S5(-n + c0, n, c2); + } else if (c0 >= 5) { + S4(c0 - c0 / 2 - 2, c0 / 2 + 2); + for (int c2 = 1; c2 < c0 - c0 / 2 - 1; c2 += 1) + S5(c0 - c0 / 2 - 1, c0 / 2 + 1, c2); + } + } + for (int c1 = -c0 + c0 / 2 + 3; c1 <= min(-1, n - c0); c1 += 1) { + S4(-c1, c0 + c1); + S6(-c1 + 2, c0 + c1 - 2); + for (int c2 = 1; c2 <= -c1; c2 += 1) + S5(-c1 + 1, c0 + c1 - 1, c2); + } + if (2 * n >= c0 + 3 && c0 >= n + 2) { + S6(-n + c0 + 1, n - 1); + for (int c2 = 1; c2 < -n + c0; c2 += 1) + S5(-n + c0, n, c2); + } + if (c0 >= n + 3 && 2 * n >= c0 + 1) + S6(-n + c0, n); + if (c0 >= n + 3) { + S1(c0 - 1); + } else { + if (n + 1 >= c0 && c0 <= 4) { + S1(c0 - 1); + } else if (c0 >= 5 && n + 1 >= c0) { + S1(c0 - 1); + S6(2, c0 - 2); + } + if (n + 1 >= c0) { + S6(1, c0 - 1); + } else if (n >= 3) { + S1(n + 1); + S6(2, n); + } + } + if (n == 2 && c0 == 4) + S1(3); + } else { + S1(1); + } + if (c0 % 2 == 0) + S3(c0 / 2); + for (int c1 = max(1, -n + c0); c1 < (c0 + 1) / 2; c1 += 1) + S2(c0 - c1, c1); +} +for (int c0 = max(2 * n + 1, -27 * n + 2); c0 <= n + 29; c0 += 1) + S1(c0 - 1); +for (int c0 = n + 30; c0 <= 2 * n; c0 += 1) { + if (2 * n >= c0 + 1) { + S4(c0 - c0 / 2 - 1, c0 / 2 + 1); + if (c0 + 2 >= 2 * n) { + for (int c2 = 1; c2 < -n + c0; c2 += 1) + S5(-n + c0, n, c2); + } else { + S4(c0 - c0 / 2 - 2, c0 / 2 + 2); + for (int c2 = 1; c2 < c0 - c0 / 2 - 1; c2 += 1) + S5(c0 - c0 / 2 - 1, c0 / 2 + 1, c2); + } + for (int c1 = -c0 + c0 / 2 + 3; c1 <= n - c0; c1 += 1) { + S4(-c1, c0 + c1); + S6(-c1 + 2, c0 + c1 - 2); + for (int c2 = 1; c2 <= -c1; c2 += 1) + S5(-c1 + 1, c0 + c1 - 1, c2); + } + if (2 * n >= c0 + 3) { + S6(-n + c0 + 1, n - 1); + for (int c2 = 1; c2 < -n + c0; c2 += 1) + S5(-n + c0, n, c2); + } + S6(-n + c0, n); + } + if (c0 % 2 == 0) + S3(c0 / 2); + for (int c1 = -n + c0; c1 < (c0 + 1) / 2; c1 += 1) + S2(c0 - c1, c1); +} diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/vivien.st b/external/mit/isl/dist/test_inputs/codegen/cloog/vivien.st new file mode 100644 index 000000000000..681b170cbc18 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/vivien.st @@ -0,0 +1,6 @@ +domain: "[n] -> { S2[i, j] : 29j >= 1 - i and i <= n and j >= 1 and j <= -1 + i; S1[i] : i >= 1 - 27n and i <= 28 + n; S4[i, j] : i >= 1 and i <= n and j >= 1 + i and j <= n; S5[i, j, k] : i >= 1 and i <= n and j >= 1 + i and j <= n and k >= 1 and k <= -1 + i; S6[i, j] : i >= 1 and i <= n and j >= 1 + i and j <= n; S3[i] : i >= 1 and i <= n }" +child: + context: "[n] -> { [] }" + child: + schedule: "[n] -> [{ S1[i0] -> [(2 + 2i0)]; S4[i0, i1] -> [(2i0 + 2i1)]; S6[i0, i1] -> [(2i0 + 2i1)]; S3[i0] -> [(1 + 4i0)]; S5[i0, i1, i2] -> [(2i0 + 2i1)]; S2[i0, i1] -> [(1 + 2i0 + 2i1)] }, { S1[i0] -> [(0)]; S4[i0, i1] -> [(-i0)]; S6[i0, i1] -> [(2 - i0)]; S3[i0] -> [(0)]; S5[i0, i1, i2] -> [(1 - i0)]; S2[i0, i1] -> [(i1)] }, { S1[i0] -> [(0)]; S4[i0, i1] -> [(0)]; S6[i0, i1] -> [(0)]; S3[i0] -> [(0)]; S5[i0, i1, i2] -> [(i2)]; S2[i0, i1] -> [(0)] }]" + options: "[n] -> { separate[i0] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/vivien2.c b/external/mit/isl/dist/test_inputs/codegen/cloog/vivien2.c new file mode 100644 index 000000000000..bfe1dc12cf30 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/vivien2.c @@ -0,0 +1,76 @@ +for (int c0 = -27 * n + 2; c0 <= 1; c0 += 1) + S1(c0 - 1); +for (int c0 = 2; c0 <= n + 29; c0 += 1) { + if (c0 >= 3) { + S4(c0 - c0 / 2 - 1, c0 / 2 + 1); + if (c0 <= 4) { + S1(c0 - 1); + } else if (c0 + 2 >= 2 * n) { + for (int c2 = 1; c2 < -n + c0; c2 += 1) + S5(-n + c0, n, c2); + } else { + S4(c0 - c0 / 2 - 2, c0 / 2 + 2); + for (int c2 = 1; c2 < c0 - c0 / 2 - 1; c2 += 1) + S5(c0 - c0 / 2 - 1, c0 / 2 + 1, c2); + } + for (int c1 = -c0 + c0 / 2 + 3; c1 <= min(-1, n - c0); c1 += 1) { + S4(-c1, c0 + c1); + S6(-c1 + 2, c0 + c1 - 2); + for (int c2 = 1; c2 <= -c1; c2 += 1) + S5(-c1 + 1, c0 + c1 - 1, c2); + } + if (2 * n >= c0 + 3 && c0 >= n + 2) { + S6(-n + c0 + 1, n - 1); + for (int c2 = 1; c2 < -n + c0; c2 += 1) + S5(-n + c0, n, c2); + } + if (c0 >= n + 3) { + S6(-n + c0, n); + S1(c0 - 1); + } else if (c0 == n + 2) { + S1(n + 1); + S6(2, n); + } else { + if (c0 >= 5) { + S1(c0 - 1); + S6(2, c0 - 2); + } + S6(1, c0 - 1); + } + } else { + S1(1); + } + if (c0 % 2 == 0) + S3(c0 / 2); + for (int c1 = max(1, -n + c0); c1 < (c0 + 1) / 2; c1 += 1) + S2(c0 - c1, c1); +} +for (int c0 = n + 30; c0 <= 2 * n; c0 += 1) { + if (2 * n >= c0 + 1) { + S4(c0 - c0 / 2 - 1, c0 / 2 + 1); + if (c0 + 2 >= 2 * n) { + for (int c2 = 1; c2 < -n + c0; c2 += 1) + S5(-n + c0, n, c2); + } else { + S4(c0 - c0 / 2 - 2, c0 / 2 + 2); + for (int c2 = 1; c2 < c0 - c0 / 2 - 1; c2 += 1) + S5(c0 - c0 / 2 - 1, c0 / 2 + 1, c2); + } + for (int c1 = -c0 + c0 / 2 + 3; c1 <= n - c0; c1 += 1) { + S4(-c1, c0 + c1); + S6(-c1 + 2, c0 + c1 - 2); + for (int c2 = 1; c2 <= -c1; c2 += 1) + S5(-c1 + 1, c0 + c1 - 1, c2); + } + if (2 * n >= c0 + 3) { + S6(-n + c0 + 1, n - 1); + for (int c2 = 1; c2 < -n + c0; c2 += 1) + S5(-n + c0, n, c2); + } + S6(-n + c0, n); + } + if (c0 % 2 == 0) + S3(c0 / 2); + for (int c1 = -n + c0; c1 < (c0 + 1) / 2; c1 += 1) + S2(c0 - c1, c1); +} diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/vivien2.st b/external/mit/isl/dist/test_inputs/codegen/cloog/vivien2.st new file mode 100644 index 000000000000..932fbc2ba2a2 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/vivien2.st @@ -0,0 +1,6 @@ +domain: "[n] -> { S2[i, j] : 29j >= 1 - i and i <= n and j >= 1 and j <= -1 + i; S1[i] : i >= 1 - 27n and i <= 28 + n; S4[i, j] : i >= 1 and i <= n and j >= 1 + i and j <= n; S5[i, j, k] : i >= 1 and i <= n and j >= 1 + i and j <= n and k >= 1 and k <= -1 + i; S6[i, j] : i >= 1 and i <= n and j >= 1 + i and j <= n; S3[i] : i >= 1 and i <= n }" +child: + context: "[n] -> { [] : n >= 30 }" + child: + schedule: "[n] -> [{ S1[i0] -> [(2 + 2i0)]; S4[i0, i1] -> [(2i0 + 2i1)]; S6[i0, i1] -> [(2i0 + 2i1)]; S3[i0] -> [(1 + 4i0)]; S5[i0, i1, i2] -> [(2i0 + 2i1)]; S2[i0, i1] -> [(1 + 2i0 + 2i1)] }, { S1[i0] -> [(0)]; S4[i0, i1] -> [(-i0)]; S6[i0, i1] -> [(2 - i0)]; S3[i0] -> [(0)]; S5[i0, i1, i2] -> [(1 - i0)]; S2[i0, i1] -> [(i1)] }, { S1[i0] -> [(0)]; S4[i0, i1] -> [(0)]; S6[i0, i1] -> [(0)]; S3[i0] -> [(0)]; S5[i0, i1, i2] -> [(i2)]; S2[i0, i1] -> [(0)] }]" + options: "[n] -> { separate[i0] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/walters.c b/external/mit/isl/dist/test_inputs/codegen/cloog/walters.c new file mode 100644 index 000000000000..9edd1294297b --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/walters.c @@ -0,0 +1,14 @@ +S2(1, 0, 1, 0); +S4(1, 0, 1, 0); +S3(2, 0, 1, 1); +S4(2, 0, 1, 1); +for (int c0 = 3; c0 <= 10; c0 += 1) { + if ((c0 + 1) % 3 == 0) { + S3(c0, (c0 - 2) / 3, (c0 + 1) / 3, (c0 + 1) / 3); + } else if (c0 % 3 == 0) { + S1(c0, c0 / 3, c0 / 3, c0 / 3); + } else { + S2(c0, (c0 - 1) / 3, (c0 + 2) / 3, (c0 - 1) / 3); + } + S4(c0, c0 / 3, (c0 - 1) / 3 + 1, c0 - (c0 - 1) / 3 - c0 / 3 - 1); +} diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/walters.st b/external/mit/isl/dist/test_inputs/codegen/cloog/walters.st new file mode 100644 index 000000000000..f168c99615ed --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/walters.st @@ -0,0 +1,12 @@ +domain: "{ S2[i, div36, div37, div38] : 3div37 = 2 + i and i >= 1 and i <= 10 and 3div36 >= -2 + i and 3div38 <= 1 + i and 3div38 >= -1 + i and 3div36 <= i; S4[i, div36, div37, div38] : i >= 1 and i <= 10 and 3div36 <= i and 3div36 >= -2 + i and 3div37 <= 2 + i and 3div37 >= i and 3div38 <= 1 + i and 3div38 >= -1 + i; S1[i, div36, div37, div38] : 3div36 = i and i >= 3 and i <= 10 and 3div37 >= i and 3div38 <= 1 + i and 3div37 <= 2 + i and 3div38 >= -1 + i; S3[i, div36, div37, div38] : 3div38 = 1 + i and i <= 10 and i >= 2 and 3div36 >= -2 + i and 3div37 <= 2 + i and 3div36 <= i and 3div37 >= i }" +child: + context: "{ [] }" + child: + schedule: "[{ S1[i, div36, div37, div38] -> [(i)]; S4[i, div36, div37, div38] -> [(i)]; S3[i, div36, div37, div38] -> [(i)]; S2[i, div36, div37, div38] -> [(i)] }, { S1[i, div36, div37, div38] -> [(div36)]; S4[i, div36, div37, div38] -> [(div36)]; S3[i, div36, div37, div38] -> [(div36)]; S2[i, div36, div37, div38] -> [(div36)] }, { S1[i, div36, div37, div38] -> [(div37)]; S4[i, div36, div37, div38] -> [(div37)]; S3[i, div36, div37, div38] -> [(div37)]; S2[i, div36, div37, div38] -> [(div37)] }, { S1[i, div36, div37, div38] -> [(div38)]; S4[i, div36, div37, div38] -> [(div38)]; S3[i, div36, div37, div38] -> [(div38)]; S2[i, div36, div37, div38] -> [(div38)] }]" + options: "{ separate[i0] }" + child: + sequence: + - filter: "{ S1[i, div36, div37, div38] }" + - filter: "{ S2[i, div36, div37, div38] }" + - filter: "{ S3[i, div36, div37, div38] }" + - filter: "{ S4[i, div36, div37, div38] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/walters2.c b/external/mit/isl/dist/test_inputs/codegen/cloog/walters2.c new file mode 100644 index 000000000000..ddfd2e5defc7 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/walters2.c @@ -0,0 +1,10 @@ +for (int c1 = 0; c1 <= 51; c1 += 1) + S2(0, c1); +for (int c0 = 1; c0 <= 24; c0 += 1) { + S2(c0, 0); + for (int c1 = 1; c1 <= 50; c1 += 1) + S1(c0, c1); + S2(c0, 51); +} +for (int c1 = 0; c1 <= 51; c1 += 1) + S2(25, c1); diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/walters2.st b/external/mit/isl/dist/test_inputs/codegen/cloog/walters2.st new file mode 100644 index 000000000000..5caba80ab20d --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/walters2.st @@ -0,0 +1,10 @@ +domain: "{ S2[j, 51] : j <= 24 and j >= 1; S2[25, i] : i <= 51 and i >= 1; S2[j, 0] : j <= 25 and j >= 1; S2[0, i] : i <= 51 and i >= 0; S1[j, i] : j >= 1 and j <= 24 and i >= 1 and i <= 50 }" +child: + context: "{ [] }" + child: + schedule: "[{ S1[j, i] -> [(j)]; S2[j, i] -> [(j)] }, { S1[j, i] -> [(i)]; S2[j, i] -> [(i)] }]" + options: "{ separate[i0] }" + child: + sequence: + - filter: "{ S1[j, i] }" + - filter: "{ S2[j, i] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/walters3.c b/external/mit/isl/dist/test_inputs/codegen/cloog/walters3.c new file mode 100644 index 000000000000..93f8a48da654 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/walters3.c @@ -0,0 +1,5 @@ +for (int c0 = 2; c0 <= 8; c0 += 2) { + S1(c0, c0 / 2, c0 / 2); + S2(c0, c0 / 2, c0 / 2); +} +S2(10, 5, 5); diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/walters3.st b/external/mit/isl/dist/test_inputs/codegen/cloog/walters3.st new file mode 100644 index 000000000000..1a1427351dfa --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/walters3.st @@ -0,0 +1,10 @@ +domain: "{ S2[j, a, b] : 2a = j and j >= 1 and j <= 10 and 2b <= j and 2b >= -1 + j; S1[j, a, b] : 2a = j and 2b = j and j <= 8 and j >= 2 }" +child: + context: "{ [] }" + child: + schedule: "[{ S1[j, a, b] -> [(j)]; S2[j, a, b] -> [(j)] }, { S1[j, a, b] -> [(a)]; S2[j, a, b] -> [(a)] }, { S1[j, a, b] -> [(b)]; S2[j, a, b] -> [(b)] }]" + options: "{ separate[i0] }" + child: + sequence: + - filter: "{ S1[j, a, b] }" + - filter: "{ S2[j, a, b] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/wavefront.c b/external/mit/isl/dist/test_inputs/codegen/cloog/wavefront.c new file mode 100644 index 000000000000..7db0788fc68d --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/wavefront.c @@ -0,0 +1,3 @@ +for (int c0 = 2; c0 <= n + m; c0 += 1) + for (int c1 = max(1, -m + c0); c1 <= min(n, c0 - 1); c1 += 1) + S1(c1, c0 - c1); diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/wavefront.st b/external/mit/isl/dist/test_inputs/codegen/cloog/wavefront.st new file mode 100644 index 000000000000..b31e0de4a348 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/wavefront.st @@ -0,0 +1,6 @@ +domain: "[n, m] -> { S1[i0, i1] : i0 >= 1 and i0 <= n and i1 >= 1 and i1 <= m }" +child: + context: "[n, m] -> { [] }" + child: + schedule: "[n, m] -> [{ S1[i0, i1] -> [(i0 + i1)] }, { S1[i0, i1] -> [(i0)] }]" + options: "[n, m] -> { separate[i0] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/yosr.c b/external/mit/isl/dist/test_inputs/codegen/cloog/yosr.c new file mode 100644 index 000000000000..563701e2202e --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/yosr.c @@ -0,0 +1,10 @@ +for (int c0 = 1; c0 < n; c0 += 1) { + for (int c1 = 1; c1 < c0; c1 += 1) + for (int c2 = c1 + 1; c2 <= n; c2 += 1) + S2(c1, c2, c0); + for (int c2 = c0 + 1; c2 <= n; c2 += 1) + S1(c0, c2); +} +for (int c1 = 1; c1 < n; c1 += 1) + for (int c2 = c1 + 1; c2 <= n; c2 += 1) + S2(c1, c2, n); diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/yosr.st b/external/mit/isl/dist/test_inputs/codegen/cloog/yosr.st new file mode 100644 index 000000000000..3ad429747bef --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/yosr.st @@ -0,0 +1,6 @@ +domain: "[n] -> { S1[i0, i1] : i0 >= 1 and i0 <= -1 + n and i1 >= 1 + i0 and i1 <= n; S2[i0, i1, i2] : i0 >= 1 and i0 <= -1 + n and i1 >= 1 + i0 and i1 <= n and i2 >= 1 + i0 and i2 <= n }" +child: + context: "[n] -> { [] }" + child: + schedule: "[n] -> [{ S2[i0, i1, i2] -> [(i2)]; S1[i0, i1] -> [(i0)] }]" + options: "[n] -> { separate[i0] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/yosr2.c b/external/mit/isl/dist/test_inputs/codegen/cloog/yosr2.c new file mode 100644 index 000000000000..a414b431cc0d --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/yosr2.c @@ -0,0 +1,11 @@ +for (int c1 = 1; c1 <= M; c1 += 1) + S2(c1); +for (int c0 = 2; c0 <= M; c0 += 1) { + for (int c2 = 1; c2 < c0; c2 += 1) + S1(c0, c2); + for (int c2 = c0 + 1; c2 <= M; c2 += 1) + for (int c3 = 1; c3 < c0; c3 += 1) + S3(c0, c2, c3); + for (int c1 = 1; c1 < c0; c1 += 1) + S4(c1, c0); +} diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/yosr2.st b/external/mit/isl/dist/test_inputs/codegen/cloog/yosr2.st new file mode 100644 index 000000000000..eb1ab41653f1 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/yosr2.st @@ -0,0 +1,6 @@ +domain: "[M] -> { S4[i0, i1] : i0 >= 1 and i0 <= M and i1 >= 1 + i0 and i1 <= M; S3[i0, i1, i2] : i0 >= 1 and i0 <= M and i1 >= 1 + i0 and i1 <= M and i2 >= 1 and i2 <= -1 + i0; S1[i0, i1] : i0 >= 1 and i0 <= M and i1 >= 1 and i1 <= -1 + i0; S2[i0] : i0 >= 1 and i0 <= M }" +child: + context: "[M] -> { [] : M >= 2 }" + child: + schedule: "[M] -> [{ S2[i0] -> [(0)]; S1[i0, i1] -> [(i0)]; S4[i0, i1] -> [(i1)]; S3[i0, i1, i2] -> [(i0)] }]" + options: "[M] -> { separate[i0] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/youcef.c b/external/mit/isl/dist/test_inputs/codegen/cloog/youcef.c new file mode 100644 index 000000000000..1bc7ffd0524a --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/youcef.c @@ -0,0 +1,6 @@ +for (int c0 = 0; c0 <= 5; c0 += 1) { + S1(c0, c0); + for (int c1 = c0; c1 <= 5; c1 += 1) + S2(c0, c1); + S3(c0, 5); +} diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/youcef.st b/external/mit/isl/dist/test_inputs/codegen/cloog/youcef.st new file mode 100644 index 000000000000..fa7cbda5a3e6 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/youcef.st @@ -0,0 +1,11 @@ +domain: "{ S2[i0, i1] : i0 >= 0 and i0 <= 5 and i1 >= i0 and i1 <= 5; S1[i0, i0] : i0 >= 0 and i0 <= 5; S3[i0, 5] : i0 >= 0 and i0 <= 5 }" +child: + context: "{ [] }" + child: + schedule: "[{ S3[i0, i1] -> [(i0)]; S1[i0, i1] -> [(i0)]; S2[i0, i1] -> [(i0)] }, { S3[i0, i1] -> [(i1)]; S1[i0, i1] -> [(i1)]; S2[i0, i1] -> [(i1)] }]" + options: "{ separate[i0] }" + child: + sequence: + - filter: "{ S1[i0, i1] }" + - filter: "{ S2[i0, i1] }" + - filter: "{ S3[i0, i1] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/youcefn.c b/external/mit/isl/dist/test_inputs/codegen/cloog/youcefn.c new file mode 100644 index 000000000000..456c688c9bab --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/youcefn.c @@ -0,0 +1,8 @@ +for (int c0 = 1; c0 <= n; c0 += 1) { + S1(c0, c0); + for (int c1 = c0; c1 <= n; c1 += 1) + S2(c0, c1); + S3(c0, n); +} +for (int c0 = n + 1; c0 <= m; c0 += 1) + S3(c0, n); diff --git a/external/mit/isl/dist/test_inputs/codegen/cloog/youcefn.st b/external/mit/isl/dist/test_inputs/codegen/cloog/youcefn.st new file mode 100644 index 000000000000..9405c6556394 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/cloog/youcefn.st @@ -0,0 +1,11 @@ +domain: "[n, m] -> { S1[i0, i0] : i0 >= 1 and i0 <= n; S3[i0, n] : i0 >= 1 and i0 <= m; S2[i0, i1] : i0 >= 1 and i0 <= n and i1 >= i0 and i1 <= n }" +child: + context: "[n, m] -> { [] : n >= 2 and m >= n }" + child: + schedule: "[n, m] -> [{ S1[i0, i1] -> [(i0)]; S2[i0, i1] -> [(i0)]; S3[i0, i1] -> [(i0)] }, { S1[i0, i1] -> [(i1)]; S2[i0, i1] -> [(i1)]; S3[i0, i1] -> [(i1)] }]" + options: "[n, m] -> { separate[i0] }" + child: + sequence: + - filter: "[n, m] -> { S1[i0, i1] }" + - filter: "[n, m] -> { S2[i0, i1] }" + - filter: "[n, m] -> { S3[i0, i1] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/component0.c b/external/mit/isl/dist/test_inputs/codegen/component0.c new file mode 100644 index 000000000000..a5f0e6004e0f --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/component0.c @@ -0,0 +1,3 @@ +A(); +for (int c0 = 0; c0 <= 9; c0 += 1) + B(c0); diff --git a/external/mit/isl/dist/test_inputs/codegen/component0.st b/external/mit/isl/dist/test_inputs/codegen/component0.st new file mode 100644 index 000000000000..3483af042b90 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/component0.st @@ -0,0 +1,3 @@ +domain: "{ A[]; B[i] : 0 <= i < 10 }" +child: + schedule: "[{ A[] -> [0]; B[i] -> [i] }]" diff --git a/external/mit/isl/dist/test_inputs/codegen/component1.c b/external/mit/isl/dist/test_inputs/codegen/component1.c new file mode 100644 index 000000000000..a5f0e6004e0f --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/component1.c @@ -0,0 +1,3 @@ +A(); +for (int c0 = 0; c0 <= 9; c0 += 1) + B(c0); diff --git a/external/mit/isl/dist/test_inputs/codegen/component1.st b/external/mit/isl/dist/test_inputs/codegen/component1.st new file mode 100644 index 000000000000..87c5eeb18d8a --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/component1.st @@ -0,0 +1,7 @@ +domain: "{ A[]; B[i] : 0 <= i < 10 }" +child: + schedule: "[{ A[] -> [0]; B[i] -> [i] }]" + child: + sequence: + - filter: "{ A[] }" + - filter: "{ B[i] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/component2.c b/external/mit/isl/dist/test_inputs/codegen/component2.c new file mode 100644 index 000000000000..c963c7ae9931 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/component2.c @@ -0,0 +1,5 @@ +for (int c0 = 0; c0 <= 9; c0 += 1) { + B(c0); + if (c0 == 0) + A(); +} diff --git a/external/mit/isl/dist/test_inputs/codegen/component2.st b/external/mit/isl/dist/test_inputs/codegen/component2.st new file mode 100644 index 000000000000..70acba4e0c70 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/component2.st @@ -0,0 +1,7 @@ +domain: "{ A[]; B[i] : 0 <= i < 10 }" +child: + schedule: "[{ A[] -> [0]; B[i] -> [i] }]" + child: + sequence: + - filter: "{ B[i] }" + - filter: "{ A[] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/component3.c b/external/mit/isl/dist/test_inputs/codegen/component3.c new file mode 100644 index 000000000000..a5f0e6004e0f --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/component3.c @@ -0,0 +1,3 @@ +A(); +for (int c0 = 0; c0 <= 9; c0 += 1) + B(c0); diff --git a/external/mit/isl/dist/test_inputs/codegen/component3.st b/external/mit/isl/dist/test_inputs/codegen/component3.st new file mode 100644 index 000000000000..c0bb65b04aa8 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/component3.st @@ -0,0 +1,7 @@ +domain: "{ A[]; B[i] : 0 <= i < 10 }" +child: + schedule: "[{ A[] -> [0]; B[i] -> [i] }]" + child: + set: + - filter: "{ B[i] }" + - filter: "{ A[] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/component4.c b/external/mit/isl/dist/test_inputs/codegen/component4.c new file mode 100644 index 000000000000..4b9229c098a1 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/component4.c @@ -0,0 +1,5 @@ +for (int c1 = 0; c1 <= 9; c1 += 1) + A(c1); +for (int c0 = 0; c0 <= 9; c0 += 1) + for (int c2 = 0; c2 <= 9; c2 += 1) + B(c0, c2); diff --git a/external/mit/isl/dist/test_inputs/codegen/component4.st b/external/mit/isl/dist/test_inputs/codegen/component4.st new file mode 100644 index 000000000000..c9e400bf6096 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/component4.st @@ -0,0 +1,7 @@ +domain: "{ A[i] : 0 <= i < 10; B[i,j] : 0 <= i,j < 10 }" +child: + schedule: "[{ A[i] -> [0]; B[i,j] -> [i] }]" + child: + sequence: + - filter: "{ A[i] }" + - filter: "{ B[i,j] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/component5.c b/external/mit/isl/dist/test_inputs/codegen/component5.c new file mode 100644 index 000000000000..072f2eaba2cf --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/component5.c @@ -0,0 +1,6 @@ +for (int c0 = 0; c0 <= 9; c0 += 1) + for (int c1 = 0; c1 <= 9; c1 += 1) { + if (c0 == 0) + A(c1); + B(c0, c1); + } diff --git a/external/mit/isl/dist/test_inputs/codegen/component5.st b/external/mit/isl/dist/test_inputs/codegen/component5.st new file mode 100644 index 000000000000..1d228982dfa3 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/component5.st @@ -0,0 +1,9 @@ +domain: "{ A[i] : 0 <= i < 10; B[i,j] : 0 <= i,j < 10 }" +child: + schedule: "[{ A[i] -> [0]; B[i,j] -> [i] }]" + child: + schedule: "[{ A[i] -> [i]; B[i,j] -> [j] }]" + child: + sequence: + - filter: "{ A[i] }" + - filter: "{ B[i,j] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/component6.c b/external/mit/isl/dist/test_inputs/codegen/component6.c new file mode 100644 index 000000000000..a5f0e6004e0f --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/component6.c @@ -0,0 +1,3 @@ +A(); +for (int c0 = 0; c0 <= 9; c0 += 1) + B(c0); diff --git a/external/mit/isl/dist/test_inputs/codegen/component6.st b/external/mit/isl/dist/test_inputs/codegen/component6.st new file mode 100644 index 000000000000..d13e8bfcacf3 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/component6.st @@ -0,0 +1,10 @@ +# Check that components are still detected in presence of nested context node +domain: "{ A[]; B[i] : 0 <= i < 10 }" +child: + schedule: "[{ A[] -> [0]; B[i] -> [i] }]" + child: + context: "[n] -> { [i] : 0 <= n <= i }" + child: + sequence: + - filter: "{ A[] }" + - filter: "{ B[i] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/component7.c b/external/mit/isl/dist/test_inputs/codegen/component7.c new file mode 100644 index 000000000000..04218f9e440f --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/component7.c @@ -0,0 +1,4 @@ +S(); +for (int c0 = 0; c0 < K; c0 += 32) + for (int c1 = c0; c1 <= min(K - 1, c0 + 31); c1 += 1) + T(c1); diff --git a/external/mit/isl/dist/test_inputs/codegen/component7.st b/external/mit/isl/dist/test_inputs/codegen/component7.st new file mode 100644 index 000000000000..c692567b2629 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/component7.st @@ -0,0 +1,11 @@ +# Check that component detection is not confused by values +# of the schedule dimension that do not correspond to any statement instances. +domain: "[K] -> { S[]; T[i] : 0 <= i < K }" +child: + context: "[K] -> { [] : K > 0 }" + child: + schedule: "[K] -> [{ S[] -> [(0)]; T[i] -> [(32*floor((i)/32))] }]" + child: + sequence: + - filter: "[K] -> { S[] }" + - filter: "[K] -> { T[i] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/correlation.c b/external/mit/isl/dist/test_inputs/codegen/correlation.c new file mode 100644 index 000000000000..8a5bc75444cf --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/correlation.c @@ -0,0 +1,55 @@ +for (int c0 = 0; c0 < m; c0 += 32) + for (int c1 = (n >= 32 && m >= c0 + 2) || (m == 1 && c0 == 0) ? 0 : 32 * n - 32 * floord(31 * n + 31, 32); c1 <= ((n <= 0 && c0 == 0) || (m == 1 && n >= 1 && c0 == 0) ? max(0, n - 1) : n); c1 += 32) + for (int c2 = c0; c2 <= (m >= 2 && c0 + 31 >= m && n >= c1 && c1 + 31 >= n ? 2 * m - 3 : (m >= 2 * c0 + 63 && c1 <= -32 && n >= c1 && c1 + 31 >= n) || (m >= c0 + 32 && 2 * c0 + 62 >= m && n >= c1 && c1 + 31 >= n) || (n >= 0 && c0 >= 32 && m >= 2 * c0 + 63 && c1 == n) || (m >= 63 && n >= 32 && c0 == 0 && c1 == n) ? 2 * c0 + 61 : m - 1); c2 += 32) { + if (m >= 2) { + if (n <= 0 && c0 == 0 && c1 == 0) + for (int c5 = 0; c5 <= min(31, m - c2 - 1); c5 += 1) + S_14(c2 + c5); + if (n >= 0 && c1 == n) { + for (int c3 = max(0, (c2 / 2) - c0 + 1); c3 <= min(31, m - c0 - 2); c3 += 1) + for (int c5 = max(0, c0 - c2 + c3); c5 <= min(31, 2 * c0 - c2 + 2 * c3 - 1); c5 += 1) + S_29(-c0 + c2 - c3 + c5, c0 + c3); + } else if (n >= c1 + 1 && c1 >= 0 && c1 + 31 >= n && c2 >= m) { + for (int c3 = max(0, (c2 / 2) - c0 + 1); c3 <= min(31, m - c0 - 2); c3 += 1) + for (int c5 = 0; c5 <= min(31, 2 * c0 - c2 + 2 * c3 - 1); c5 += 1) + S_29(-c0 + c2 - c3 + c5, c0 + c3); + } else if (c1 <= -32 && n >= c1 && c1 + 31 >= n) { + for (int c3 = max(0, (c2 / 2) - c0 + 1); c3 <= min(31, m - c0 - 2); c3 += 1) + for (int c5 = max(0, c0 - c2 + c3); c5 <= min(31, 2 * c0 - c2 + 2 * c3 - 1); c5 += 1) + S_29(-c0 + c2 - c3 + c5, c0 + c3); + } else if (n >= c1 + 1 && c1 >= 0 && m >= c2 + 1) { + for (int c3 = 0; c3 <= min(min(31, m - c0 - 2), -c0 + c2 + 30); c3 += 1) { + for (int c4 = 0; c4 <= min(31, n - c1 - 1); c4 += 1) { + if (c0 == 0 && c2 == 0 && c3 == 0) { + if (c1 == 0 && c4 == 0) + S_14(0); + S_19(c1 + c4, 0); + } + for (int c5 = max(0, c0 - c2 + c3 + 1); c5 <= min(31, m - c2 - 1); c5 += 1) { + if (c0 == 0 && c1 == 0 && c3 == 0 && c4 == 0) + S_14(c2 + c5); + if (c0 == 0 && c3 == 0) + S_19(c1 + c4, c2 + c5); + S_27(c0 + c3, c2 + c5, c1 + c4); + } + } + if (c1 + 31 >= n) + for (int c5 = max(0, c0 - c2 + c3); c5 <= min(31, 2 * c0 - c2 + 2 * c3 - 1); c5 += 1) + S_29(-c0 + c2 - c3 + c5, c0 + c3); + } + } + if (c0 + 32 >= m && n >= c1 && c1 + 31 >= n) { + for (int c5 = max(0, m - c2 - 1); c5 <= min(31, 2 * m - c2 - 3); c5 += 1) + S_29(-m + c2 + c5 + 1, m - 1); + } else if (m >= c0 + 33 && n >= c1 + 1 && c1 >= 0 && c1 + 31 >= n && c2 == c0) { + S_29(0, c0 + 31); + } + } else if (c1 >= 32 && c2 == 0) { + for (int c4 = 0; c4 <= min(31, n - c1 - 1); c4 += 1) + S_19(c1 + c4, 0); + } else if (c1 == 0 && c2 == 0) { + S_14(0); + for (int c4 = 0; c4 <= min(31, n - 1); c4 += 1) + S_19(c4, 0); + } + } diff --git a/external/mit/isl/dist/test_inputs/codegen/correlation.st b/external/mit/isl/dist/test_inputs/codegen/correlation.st new file mode 100644 index 000000000000..bba5a09d8ef7 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/correlation.st @@ -0,0 +1,18 @@ +domain: "[m, n] -> { S_14[j] : 0 <= j < m; S_19[i, j] : 0 <= i < n and 0 <= j < m; S_27[i, j, k] : i >= 0 and i < j < m and 0 <= k < n; S_29[i, j] : i >= 0 and i < j < m }" +child: + context: "[m, n] -> { [] : 0 < m <= 2147483647 and -2147483648 <= n <= 2147483647 }" + child: + schedule: "[m, n] -> [{ S_19[i, j] -> [(0)]; S_29[i, j] -> [(32*floor((j)/32))]; S_27[i, j, k] -> [(32*floor((i)/32))]; S_14[j] -> [(0)] }, { S_19[i, j] -> [(32*floor((i)/32))]; S_29[i, j] -> [(32*floor((n)/32))]; S_27[i, j, k] -> [(32*floor((k)/32))]; S_14[j] -> [(0)] }, { S_19[i, j] -> [(32*floor((j)/32))]; S_29[i, j] -> [(32*floor((i + j)/32))]; S_27[i, j, k] -> [(32*floor((j)/32))]; S_14[j] -> [(32*floor((j)/32))] }]" + permutable: 1 + coincident: [ 1, 1, 1 ] + options: "{ atomic[i0] : 0 <= i0 <= 2 }" + child: + schedule: "[m, n] -> [{ S_19[i, j] -> [(0)]; S_29[i, j] -> [(j - 32*floor((j)/32))]; S_27[i, j, k] -> [(i - 32*floor((i)/32))]; S_14[j] -> [(0)] }, { S_19[i, j] -> [(i - 32*floor((i)/32))]; S_29[i, j] -> [(n - 32*floor((n)/32))]; S_27[i, j, k] -> [(k - 32*floor((k)/32))]; S_14[j] -> [(0)] }, { S_19[i, j] -> [(j - 32*floor((j)/32))]; S_29[i, j] -> [(i + j - 32*floor((i + j)/32))]; S_27[i, j, k] -> [(j - 32*floor((j)/32))]; S_14[j] -> [(j - 32*floor((j)/32))] }]" + permutable: 1 + coincident: [ 1, 1, 1 ] + child: + sequence: + - filter: "[m, n] -> { S_29[i, j] }" + - filter: "[m, n] -> { S_14[j] }" + - filter: "[m, n] -> { S_19[i, j] }" + - filter: "[m, n] -> { S_27[i, j, k] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/disjuncts.c b/external/mit/isl/dist/test_inputs/codegen/disjuncts.c new file mode 100644 index 000000000000..207e33778355 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/disjuncts.c @@ -0,0 +1,10 @@ +for (int c0 = 0; c0 <= n; c0 += 1) + for (int c1 = 0; c1 <= n; c1 += 1) + if (c1 == n || c0 == n || c1 == 0 || c0 == 0) { + for (int c3 = 0; c3 <= n; c3 += 1) + for (int c4 = 0; c4 <= n; c4 += 1) + a(c0, c1, c3, c4); + for (int c3 = 0; c3 <= n; c3 += 1) + for (int c4 = 0; c4 <= n; c4 += 1) + b(c0, c1, c3, c4); + } diff --git a/external/mit/isl/dist/test_inputs/codegen/disjuncts.in b/external/mit/isl/dist/test_inputs/codegen/disjuncts.in new file mode 100644 index 000000000000..01386701c698 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/disjuncts.in @@ -0,0 +1,7 @@ +# Check that conditions are hoisted up from the innermost loop +[n] -> { a[i,j,k,l] -> [i,j,0,k,l] : + 0 <= i,j,k,l <= n and (i = 0 or j = 0 or i = n or j = n); + b[i,j,k,l] -> [i,j,1,k,l] : + 0 <= i,j,k,l <= n and (i = 0 or j = 0 or i = n or j = n) } +{ : } +{ [i,j,t,k,l] -> atomic[x] } diff --git a/external/mit/isl/dist/test_inputs/codegen/disjuncts2.c b/external/mit/isl/dist/test_inputs/codegen/disjuncts2.c new file mode 100644 index 000000000000..6011a3b0d404 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/disjuncts2.c @@ -0,0 +1,3 @@ +if (P >= Q + 1 || Q >= P + 1) + for (int c0 = 0; c0 < N; c0 += 1) + S(c0); diff --git a/external/mit/isl/dist/test_inputs/codegen/disjuncts2.st b/external/mit/isl/dist/test_inputs/codegen/disjuncts2.st new file mode 100644 index 000000000000..d0170a685259 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/disjuncts2.st @@ -0,0 +1,4 @@ +# Check that the loop is generated only once with an outer disjunctive condition +domain: "[N, Q, P] -> { S[i0] : 0 <= i0 < N and (P > Q or P < Q) }" +child: + schedule: "[N, Q, P] -> [{ S[i0] -> [(i0)] }]" diff --git a/external/mit/isl/dist/test_inputs/codegen/dwt.c b/external/mit/isl/dist/test_inputs/codegen/dwt.c new file mode 100644 index 000000000000..a4de6714a087 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/dwt.c @@ -0,0 +1,9 @@ +for (int c0 = 0; c0 < Ncl; c0 += 1) { + if (Ncl >= c0 + 2 && c0 >= 1) { + S(c0, 28); + } else if (c0 == 0) { + S(0, 26); + } else { + S(Ncl - 1, 27); + } +} diff --git a/external/mit/isl/dist/test_inputs/codegen/dwt.in b/external/mit/isl/dist/test_inputs/codegen/dwt.in new file mode 100644 index 000000000000..424b0f3fd095 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/dwt.in @@ -0,0 +1,3 @@ +[Ncl] -> { S[j, 28] -> [j] : j <= -2 + Ncl and Ncl <= 256 and Ncl >= 40 and j >= 1; S[0, 26] -> [0] : Ncl <= 256 and Ncl >= 40; S[-1 + Ncl, 27] -> [-1 + Ncl] : Ncl <= 256 and Ncl >= 40 } +[Ncl] -> { : Ncl >= 40 and Ncl <= 256 } +{ } diff --git a/external/mit/isl/dist/test_inputs/codegen/empty.c b/external/mit/isl/dist/test_inputs/codegen/empty.c new file mode 100644 index 000000000000..58f7b7b295b2 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/empty.c @@ -0,0 +1,6 @@ +for (int c0 = 0; c0 <= 10; c0 += 1) { + S0(c0); + if (c0 == 5) + S2(); + S1(c0); +} diff --git a/external/mit/isl/dist/test_inputs/codegen/empty.in b/external/mit/isl/dist/test_inputs/codegen/empty.in new file mode 100644 index 000000000000..17febea4be65 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/empty.in @@ -0,0 +1,5 @@ +# Earlier versions of isl would end up with an empty partial +# executed relation and fail to detect this emptiness. +[M] -> { S0[i] -> [i, -M] : 0 <= i <= 10; S1[i] -> [i, 0] : 0 <= i <= 10; S2[] -> [5, 0] } +[M] -> { : M >= 1 } +{ } diff --git a/external/mit/isl/dist/test_inputs/codegen/filter.c b/external/mit/isl/dist/test_inputs/codegen/filter.c new file mode 100644 index 000000000000..c326fa875d03 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/filter.c @@ -0,0 +1,9 @@ +if (n >= m + 1) { + for (int c0 = 0; c0 < n; c0 += 1) + for (int c2 = 0; c2 < n; c2 += 1) + A(c0, c2); +} else { + for (int c0 = 0; c0 < n; c0 += 1) + for (int c2 = 0; c2 < n; c2 += 1) + A(c0, c2); +} diff --git a/external/mit/isl/dist/test_inputs/codegen/filter.st b/external/mit/isl/dist/test_inputs/codegen/filter.st new file mode 100644 index 000000000000..719fb7ed9ab1 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/filter.st @@ -0,0 +1,18 @@ +# Check proper handling of filters that turn out to be empty on their paths +domain: "[n,m] -> { A[i,j] : 0 <= i,j < n }" +child: + set: + - filter: "[n,m] -> { A[i,j] : m < n }" + child: + schedule: "[{ A[i,j] -> [i] }]" + child: + set: + - filter: "[n,m] -> { A[i,j] : m < n }" + - filter: "[n,m] -> { A[i,j] : m >= n }" + - filter: "[n,m] -> { A[i,j] : m >= n }" + child: + schedule: "[{ A[i,j] -> [i] }]" + child: + set: + - filter: "[n,m] -> { A[i,j] : m < n }" + - filter: "[n,m] -> { A[i,j] : m >= n }" diff --git a/external/mit/isl/dist/test_inputs/codegen/gemm.c b/external/mit/isl/dist/test_inputs/codegen/gemm.c new file mode 100644 index 000000000000..d309b23dd8d8 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/gemm.c @@ -0,0 +1,6 @@ +for (int c0 = 0; c0 < ni; c0 += 1) + for (int c1 = 0; c1 < nj; c1 += 1) { + S_2(c0, c1); + for (int c2 = 0; c2 < nk; c2 += 1) + S_4(c0, c1, c2); + } diff --git a/external/mit/isl/dist/test_inputs/codegen/gemm.st b/external/mit/isl/dist/test_inputs/codegen/gemm.st new file mode 100644 index 000000000000..31df19dc3e50 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/gemm.st @@ -0,0 +1,12 @@ +domain: "[ni, nj, nk] -> { S_4[i, j, k] : k <= -1 + nk and k >= 0 and j <= -1 + nj and j >= 0 and i <= -1 + ni and i >= 0; S_2[i, j] : j <= -1 + nj and j >= 0 and i <= -1 + ni and i >= 0 }" +child: + set: + - filter: "[ni, nj, nk] -> { S_4[i, j, k]; S_2[i, j] }" + child: + schedule: "[ni, nj, nk] -> [{ S_4[i, j, k] -> [(i)]; S_2[i, j] -> [(i)] }, { S_4[i, j, k] -> [(j)]; S_2[i, j] -> [(j)] }, { S_4[i, j, k] -> [(k)]; S_2[i, j] -> [(0)] }]" + permutable: 1 + coincident: [ 1, 1, 0 ] + child: + sequence: + - filter: "[ni, nj, nk] -> { S_2[i, j] }" + - filter: "[ni, nj, nk] -> { S_4[i, j, k] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/group.c b/external/mit/isl/dist/test_inputs/codegen/group.c new file mode 100644 index 000000000000..3e521e25956f --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/group.c @@ -0,0 +1,5 @@ +if (N == 0) { + A(); + C(); +} +B(); diff --git a/external/mit/isl/dist/test_inputs/codegen/group.st b/external/mit/isl/dist/test_inputs/codegen/group.st new file mode 100644 index 000000000000..04d8ad7e6a7d --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/group.st @@ -0,0 +1,2 @@ +# Check that the condition "N == 0" is only generated once. +domain: "[N] -> { A[] : N = 0; B[]; C[] : N = 0 }" diff --git a/external/mit/isl/dist/test_inputs/codegen/hoist.c b/external/mit/isl/dist/test_inputs/codegen/hoist.c new file mode 100644 index 000000000000..7ba854f8e2f3 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/hoist.c @@ -0,0 +1,45 @@ +if (ni >= t0 + 1 && nj >= t1 + 1) + for (int c2 = 0; c2 <= min(15, nk - 1); c2 += 1) { + S_1(t0, t1, c2); + if (nj >= t1 + 17) { + S_1(t0, t1 + 16, c2); + if (nj >= t1 + 33) { + S_1(t0, t1 + 32, c2); + if (nj >= t1 + 49) + S_1(t0, t1 + 48, c2); + } + } + if (ni >= t0 + 17) { + S_1(t0 + 16, t1, c2); + if (nj >= t1 + 17) { + S_1(t0 + 16, t1 + 16, c2); + if (nj >= t1 + 33) { + S_1(t0 + 16, t1 + 32, c2); + if (nj >= t1 + 49) + S_1(t0 + 16, t1 + 48, c2); + } + } + if (ni >= t0 + 33) { + S_1(t0 + 32, t1, c2); + if (nj >= t1 + 17) { + S_1(t0 + 32, t1 + 16, c2); + if (nj >= t1 + 33) { + S_1(t0 + 32, t1 + 32, c2); + if (nj >= t1 + 49) + S_1(t0 + 32, t1 + 48, c2); + } + } + if (ni >= t0 + 49) { + S_1(t0 + 48, t1, c2); + if (nj >= t1 + 17) { + S_1(t0 + 48, t1 + 16, c2); + if (nj >= t1 + 33) { + S_1(t0 + 48, t1 + 32, c2); + if (nj >= t1 + 49) + S_1(t0 + 48, t1 + 48, c2); + } + } + } + } + } + } diff --git a/external/mit/isl/dist/test_inputs/codegen/hoist.in b/external/mit/isl/dist/test_inputs/codegen/hoist.in new file mode 100644 index 000000000000..80a905200e43 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/hoist.in @@ -0,0 +1,10 @@ +# check that the shared conditions ni >= t0 + 1 and nj >= t1 + 1 +# are hoisted out of the loop +[ni, nj, nk, t0, t1] -> { S_1[i, j, k] -> [t0, t1, k, i, j] : + exists (e0 = [(-t0 + i)/16], e1 = [(-t1 + j)/16]: + 16e0 = -t0 + i and 16e1 = -t1 + j and k >= 0 and j >= 0 and + j <= -1 + nj and i >= 0 and i <= -1 + ni and k <= -1 + nk and + ni >= 1 and nj >= 1 and nk >= 1 and j <= 63 and t1 >= 0 and + i <= 63 and k <= 15 and t0 >= 0 and t1 <= 15 and t0 <= 15) } +[t0, t1] -> { : 0 <= t0, t1 <= 15 } +{ [t0, t1, i5, i6, i7] -> unroll[x] : x >= 3} diff --git a/external/mit/isl/dist/test_inputs/codegen/hoist2.c b/external/mit/isl/dist/test_inputs/codegen/hoist2.c new file mode 100644 index 000000000000..907652fa9558 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/hoist2.c @@ -0,0 +1,5 @@ +for (int c0 = 1; c0 <= 5; c0 += 1) + if (c0 <= 3 || (b == 1 && t1 + c0 >= 10) || (t1 == 5 && b == 1 && c0 == 4)) + for (int c1 = t1 - 64 * b + 64; c1 <= min(70, -c0 + 73); c1 += 64) + if (c0 <= 3 || (t1 + c0 >= 10 && c1 == t1) || c1 == 5) + A(c0, 64 * b + c1 - 8); diff --git a/external/mit/isl/dist/test_inputs/codegen/hoist2.in b/external/mit/isl/dist/test_inputs/codegen/hoist2.in new file mode 100644 index 000000000000..6a29a026f201 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/hoist2.in @@ -0,0 +1,5 @@ +# Check that the constraints hoisted from the inner loop +# do not end up involving the inner loop iterator. +[t1, b] -> { A[i1, i2] -> [i1, 8 - 64b + i2] : exists (e0, e1 = [(-8 + t1 - i2)/64]: 64e1 = -8 + t1 - i2 and i2 >= 1 and i2 <= 127 and 2e0 >= -3 + i1 and 2e0 >= -1 - i1 and 2e0 <= 8 - i1 and 2e0 <= 6 + i1 and 2e0 >= -65 - 64b + i2 and 2e0 >= -1 + 64b - i2 and e0 <= 1 and e0 >= 0 and 2e0 <= 62 + 64b - i2 and b <= 1 and b >= 0 and i1 >= 1 and i1 <= 2046 and t1 >= 5 and t1 <= 8) } +[t1, b] -> { : b >= 0 and b <= 1 and t1 >= 5 and t1 <= 8 } +[t1] -> { [i0, i1, i5, a] -> atomic[x]} diff --git a/external/mit/isl/dist/test_inputs/codegen/isolate1.c b/external/mit/isl/dist/test_inputs/codegen/isolate1.c new file mode 100644 index 000000000000..8bbc0c0664b6 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/isolate1.c @@ -0,0 +1,6 @@ +for (int c0 = 0; c0 <= 3; c0 += 1) + A(c0); +for (int c0 = 4; c0 <= 6; c0 += 1) + A(c0); +for (int c0 = 7; c0 <= 99; c0 += 1) + A(c0); diff --git a/external/mit/isl/dist/test_inputs/codegen/isolate1.st b/external/mit/isl/dist/test_inputs/codegen/isolate1.st new file mode 100644 index 000000000000..037dda1880bd --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/isolate1.st @@ -0,0 +1,5 @@ +# Check that the isolate option is adjusted by schedule space scaling +domain: "{ A[i] : 0 <= i < 100 }" +child: + schedule: "[{ A[i] -> [3i] }]" + options: "{ isolate[[] -> [x]] : 10 <= x <= 20 }" diff --git a/external/mit/isl/dist/test_inputs/codegen/isolate2.c b/external/mit/isl/dist/test_inputs/codegen/isolate2.c new file mode 100644 index 000000000000..28a78bc26534 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/isolate2.c @@ -0,0 +1,9 @@ +for (int c0 = 0; c0 <= 99; c0 += 1) { + if (c0 >= 4 && c0 <= 6) { + for (int c1 = 0; c1 <= 99; c1 += 1) + A(c0, c1); + } else { + for (int c1 = 0; c1 <= 99; c1 += 1) + A(c0, c1); + } +} diff --git a/external/mit/isl/dist/test_inputs/codegen/isolate2.st b/external/mit/isl/dist/test_inputs/codegen/isolate2.st new file mode 100644 index 000000000000..a9478f338b83 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/isolate2.st @@ -0,0 +1,7 @@ +# Check that the isolate option is adjusted by schedule space scaling +domain: "{ A[i,j] : 0 <= i,j < 100 }" +child: + schedule: "[{ A[i,j] -> [3i] }]" + child: + schedule: "[{ A[i,j] -> [3j] }]" + options: "{ isolate[[x] -> [y]] : 10 <= x <= 20 }" diff --git a/external/mit/isl/dist/test_inputs/codegen/isolate3.c b/external/mit/isl/dist/test_inputs/codegen/isolate3.c new file mode 100644 index 000000000000..7955efa0ee2d --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/isolate3.c @@ -0,0 +1,15 @@ +for (int c0 = 0; c0 <= 9; c0 += 1) + A(c0); +A(10); +A(11); +A(12); +A(13); +A(14); +A(15); +A(16); +A(17); +A(18); +A(19); +A(20); +for (int c0 = 21; c0 <= 99; c0 += 1) + A(c0); diff --git a/external/mit/isl/dist/test_inputs/codegen/isolate3.st b/external/mit/isl/dist/test_inputs/codegen/isolate3.st new file mode 100644 index 000000000000..bce38a844d98 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/isolate3.st @@ -0,0 +1,5 @@ +# Check use of options specific to isolated part +domain: "{ A[i] : 0 <= i < 100 }" +child: + schedule: "[{ A[i] -> [i] }]" + options: "{ isolate[[] -> [x]] : 10 <= x <= 20; [isolate[] -> unroll[x]] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/isolate4.c b/external/mit/isl/dist/test_inputs/codegen/isolate4.c new file mode 100644 index 000000000000..870848e21683 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/isolate4.c @@ -0,0 +1,11 @@ +A(0); +A(1); +A(2); +A(3); +A(4); +for (int c0 = 5; c0 <= 15; c0 += 1) + A(c0); +A(16); +A(17); +A(18); +A(19); diff --git a/external/mit/isl/dist/test_inputs/codegen/isolate4.st b/external/mit/isl/dist/test_inputs/codegen/isolate4.st new file mode 100644 index 000000000000..58b5168c6b67 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/isolate4.st @@ -0,0 +1,5 @@ +# Check that generic options are not applied to isolated part +domain: "{ A[i] : 0 <= i < 20 }" +child: + schedule: "[{ A[i] -> [i] }]" + options: "{ isolate[[] -> [x]] : 5 <= x <= 15; unroll[x] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/isolate5.c b/external/mit/isl/dist/test_inputs/codegen/isolate5.c new file mode 100644 index 000000000000..f14a4888c492 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/isolate5.c @@ -0,0 +1,27 @@ +for (int c0 = 0; c0 <= 9; c0 += 1) { + if ((c0 + 1) % 2 == 0) { + for (int c1 = 0; c1 <= 1; c1 += 1) + B((c0 - 1) / 2, c1); + } else { + for (int c1 = 0; c1 <= 1; c1 += 1) + A(c0 / 2, c1); + } +} +for (int c0 = 10; c0 <= 89; c0 += 1) { + if ((c0 + 1) % 2 == 0) { + for (int c1 = 0; c1 <= 1; c1 += 1) + B((c0 - 1) / 2, c1); + } else { + for (int c1 = 0; c1 <= 1; c1 += 1) + A(c0 / 2, c1); + } +} +for (int c0 = 90; c0 <= 199; c0 += 1) { + if ((c0 + 1) % 2 == 0) { + for (int c1 = 0; c1 <= 1; c1 += 1) + B((c0 - 1) / 2, c1); + } else { + for (int c1 = 0; c1 <= 1; c1 += 1) + A(c0 / 2, c1); + } +} diff --git a/external/mit/isl/dist/test_inputs/codegen/isolate5.st b/external/mit/isl/dist/test_inputs/codegen/isolate5.st new file mode 100644 index 000000000000..86b0dd160ffe --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/isolate5.st @@ -0,0 +1,5 @@ +# Check that use of isolate option prevents shifted stride detection +domain: "{ A[i,j] : 0 <= i < 100 and 0 <= j < 2; B[i,j] : 0 <= i < 100 and 0 <= j < 2 }" +child: + schedule: "[{ A[i,j] -> [2i]; B[i,j] -> [2i+1] }, { A[i,j] -> [j]; B[i,j] -> [j]}]" + options: "{ isolate[[] -> [x, y]] : 10 <= x < 90 }" diff --git a/external/mit/isl/dist/test_inputs/codegen/isolate6.c b/external/mit/isl/dist/test_inputs/codegen/isolate6.c new file mode 100644 index 000000000000..db7980414e8f --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/isolate6.c @@ -0,0 +1,24 @@ +for (int c0 = 0; c0 <= 8; c0 += 1) { + for (int c1 = 0; c1 <= -c0 + 8; c1 += 1) + for (int c2 = 10 * c0; c2 <= 10 * c0 + 9; c2 += 1) { + A(c2, 10 * c1); + A(c2, 10 * c1 + 1); + A(c2, 10 * c1 + 2); + A(c2, 10 * c1 + 3); + A(c2, 10 * c1 + 4); + A(c2, 10 * c1 + 5); + A(c2, 10 * c1 + 6); + A(c2, 10 * c1 + 7); + A(c2, 10 * c1 + 8); + A(c2, 10 * c1 + 9); + } + for (int c1 = -c0 + 9; c1 <= -c0 + 10; c1 += 1) + for (int c2 = 10 * c0; c2 <= min(10 * c0 + 9, -10 * c1 + 100); c2 += 1) + for (int c3 = 10 * c1; c3 <= min(10 * c1 + 9, -c2 + 100); c3 += 1) + A(c2, c3); +} +for (int c0 = 9; c0 <= 10; c0 += 1) + for (int c1 = 0; c1 <= -c0 + 10; c1 += 1) + for (int c2 = 10 * c0; c2 <= min(10 * c0 + 9, -10 * c1 + 100); c2 += 1) + for (int c3 = 10 * c1; c3 <= min(10 * c1 + 9, -c2 + 100); c3 += 1) + A(c2, c3); diff --git a/external/mit/isl/dist/test_inputs/codegen/isolate6.st b/external/mit/isl/dist/test_inputs/codegen/isolate6.st new file mode 100644 index 000000000000..1342223aec21 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/isolate6.st @@ -0,0 +1,8 @@ +# Example from the manual +domain: "{ A[i,j] : 0 <= i,j and i + j <= 100 }" +child: + schedule: "[{ A[i,j] -> [floor(i/10)] }, \ + { A[i,j] -> [floor(j/10)] }, \ + { A[i,j] -> [i] }, { A[i,j] -> [j] }]" + options: "{ isolate[[] -> [a,b,c,d]] : 0 <= 10a,10b and \ + 10a+9+10b+9 <= 100; [isolate[] -> unroll[3]] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/isolate7.c b/external/mit/isl/dist/test_inputs/codegen/isolate7.c new file mode 100644 index 000000000000..aac1337a6b58 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/isolate7.c @@ -0,0 +1,27 @@ +for (int c0 = 0; c0 < n - 31; c0 += 32) + for (int c1 = 0; c1 <= n; c1 += 32) { + if (n >= c1 + 32) { + for (int c2 = 0; c2 <= 31; c2 += 1) + for (int c3 = 0; c3 <= 31; c3 += 1) + S_1(c0 + c2, c1 + c3); + } else { + for (int c2 = 0; c2 <= 31; c2 += 1) { + for (int c3 = 0; c3 < n - c1; c3 += 1) + S_1(c0 + c2, c1 + c3); + S_2(c0 + c2); + } + } + } +for (int c1 = 0; c1 < n; c1 += 32) { + if (n >= c1 + 32) { + for (int c2 = 0; c2 < (n + 32) % 32; c2 += 1) + for (int c3 = 0; c3 <= 31; c3 += 1) + S_1(-((n + 32) % 32) + n + c2, c1 + c3); + } else { + for (int c2 = 0; c2 < n - c1; c2 += 1) { + for (int c3 = 0; c3 < n - c1; c3 += 1) + S_1(c1 + c2, c1 + c3); + S_2(c1 + c2); + } + } +} diff --git a/external/mit/isl/dist/test_inputs/codegen/isolate7.st b/external/mit/isl/dist/test_inputs/codegen/isolate7.st new file mode 100644 index 000000000000..673eb08b5b88 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/isolate7.st @@ -0,0 +1,16 @@ +# Check that no expressions of the form ((-n + 2147483648) % 32) are produced. +domain: "[n] -> { S_2[i] : i >= 0 and i <= -1 + n; S_1[i, j] : j >= 0 and j <= -1 + n and i >= 0 and i <= -1 + n }" +child: + context: "[n] -> { [] : n <= 2147483647 and n >= 0 }" + child: + schedule: "[n] -> [{ S_1[i, j] -> [(32*floor((i)/32))]; S_2[i] -> [(32*floor((i)/32))] }, { S_1[i, j] -> [(32*floor((j)/32))]; S_2[i] -> [(32*floor((n)/32))] }]" + permutable: 1 + options: "[n] -> { atomic[i0] : i0 >= 0 and i0 <= 1; isolate[[] -> [i0, i1]] : (exists (e0 = floor((i0)/32), e1 = floor((i1)/32): 32e0 = i0 and 32e1 = i1 and i0 >= 0 and i0 <= -32 + n and i1 >= 0 and i1 <= n)) or (exists (e0 = floor((i0)/32), e1 = floor((i1)/32): 32e0 = i0 and 32e1 = i1 and i0 >= 0 and i0 <= -32 + n and i1 >= -31 + n and i1 <= -31 + 2n)) }" + child: + schedule: "[n] -> [{ S_1[i, j] -> [(i - 32*floor((i)/32))]; S_2[i] -> [(i - 32*floor((i)/32))] }, { S_1[i, j] -> [(j - 32*floor((j)/32))]; S_2[i] -> [(n - 32*floor((n)/32))] }]" + permutable: 1 + options: "{ separate[i0] : i0 >= 0 and i0 <= 1 }" + child: + sequence: + - filter: "[n] -> { S_1[i, j] }" + - filter: "[n] -> { S_2[i] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/jacobi_kernel4.c b/external/mit/isl/dist/test_inputs/codegen/jacobi_kernel4.c new file mode 100644 index 000000000000..97b45448ae1c --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/jacobi_kernel4.c @@ -0,0 +1,2 @@ +if (8 * a + 64 * b >= t0 + 2 * t + 512 * floord(-t0 - 8 * a + 64 * b + 2 * t - 1, 512) + 512 && t0 + 512 * floord(-t0 - 8 * a + 64 * b + 2 * t - 1, 512) >= -511 && t0 + 512 * floord(-t0 - 8 * a + 64 * b + 2 * t - 1, 512) <= 1310206) + S_0(t, -((-t0 - 8 * a + 64 * b + 2 * t + 511) % 512) - 8 * a + 64 * b + 2 * t + 511); diff --git a/external/mit/isl/dist/test_inputs/codegen/jacobi_kernel4.in b/external/mit/isl/dist/test_inputs/codegen/jacobi_kernel4.in new file mode 100644 index 000000000000..9eadc1ba4f86 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/jacobi_kernel4.in @@ -0,0 +1,4 @@ +# Check that an affine value is extracted for the final dimension +[t0,a,b,t] -> { S_0[t, i] -> [i, t0] : exists (e0 = [(t0 - i)/512]: 512e0 = t0 - i and 64b >= 2t + i - 8a and 64b <= -2t + i + 8a and 4a <= 3 + t and 4a >= t and t >= 0 and t <= 1999 and i >= 1 and i <= 1310718 and a >= 0 and a <= 500 and 8b <= 163839 + a and b <= 20480 and 8b >= 1 - a and b >= 0 and 32b <= 655359 - t + 4a and 32b >= 1 + t - 4a and t0 >= 0 and t0 <= 511) } +[t0,a,b,t] -> { : t <= -1 + 4a + 32b and t >= 0 and t <= 4a and t >= -3 + 4a and t <= 1999 and t <= 655359 + 4a - 32b and t0 >= 0 and t0 <= 511 } +[t0] -> { } diff --git a/external/mit/isl/dist/test_inputs/codegen/lu.c b/external/mit/isl/dist/test_inputs/codegen/lu.c new file mode 100644 index 000000000000..022d6f230ff7 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/lu.c @@ -0,0 +1,18 @@ +for (int c0 = 0; c0 < n - 1; c0 += 32) + for (int c1 = c0; c1 < n; c1 += 32) + for (int c2 = c0; c2 < n; c2 += 32) { + if (c1 >= c0 + 32) { + for (int c3 = c0; c3 <= min(c0 + 31, c2 + 30); c3 += 1) + for (int c4 = c1; c4 <= min(n - 1, c1 + 31); c4 += 1) + for (int c5 = max(c2, c3 + 1); c5 <= min(n - 1, c2 + 31); c5 += 1) + S_6(c3, c4, c5); + } else { + for (int c3 = c0; c3 <= min(min(n - 2, c0 + 31), c2 + 30); c3 += 1) { + for (int c5 = max(c2, c3 + 1); c5 <= min(n - 1, c2 + 31); c5 += 1) + S_2(c3, c5); + for (int c4 = c3 + 1; c4 <= min(n - 1, c0 + 31); c4 += 1) + for (int c5 = max(c2, c3 + 1); c5 <= min(n - 1, c2 + 31); c5 += 1) + S_6(c3, c4, c5); + } + } + } diff --git a/external/mit/isl/dist/test_inputs/codegen/lu.in b/external/mit/isl/dist/test_inputs/codegen/lu.in new file mode 100644 index 000000000000..ea884f59d60d --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/lu.in @@ -0,0 +1,4 @@ +# Check that the stride of the second loop is properly detected +[n] -> { S_2[k, j] -> [o0, o0, o2, k, k, j, 1] : exists (e0 = floor((o2)/32), e1 = floor((o0)/32): 32e0 = o2 and 32e1 = o0 and o0 <= k and o0 >= -31 + k and k >= 0 and j <= -1 + n and o2 <= j and o2 >= -31 + j and j >= 1 + k); S_6[k, i, j] -> [o0, o1, o2, k, i, j, 0] : exists (e0 = floor((o0)/32), e1 = floor((o1)/32), e2 = floor((o2)/32): 32e0 = o0 and 32e1 = o1 and 32e2 = o2 and o0 <= k and o0 >= -31 + k and o1 <= i and o1 >= -31 + i and o2 <= j and o2 >= -31 + j and k >= 0 and i >= 1 + k and j <= -1 + n and j >= 1 + k and i <= -1 + n) } +{ : } +{ [a,b,c,d,e,f,g] -> atomic[x] : x < 3; [a,b,c,d,e,f,g] -> separate[x] : x >= 3 } diff --git a/external/mit/isl/dist/test_inputs/codegen/mod.c b/external/mit/isl/dist/test_inputs/codegen/mod.c new file mode 100644 index 000000000000..dcd8319f4ca7 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/mod.c @@ -0,0 +1,2 @@ +if (2 * (n % 100) == 3 * (m % 200)) + A(); diff --git a/external/mit/isl/dist/test_inputs/codegen/mod.in b/external/mit/isl/dist/test_inputs/codegen/mod.in new file mode 100644 index 000000000000..7a04c5a4158b --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/mod.in @@ -0,0 +1,4 @@ +# check that modulo constraint is generated correctly +[n, m] -> { A[] -> [] : 2 * (n % 100) = 3 * (m % 200) } +[n, m] -> { : m, n >= 0 } +{} diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/README b/external/mit/isl/dist/test_inputs/codegen/omega/README new file mode 100644 index 000000000000..80e27fd462d4 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/README @@ -0,0 +1,5 @@ +The tests in this directory have been adapted from the corresponding omega+ +test cases. +The options have been derived semi-automatically and may not always +correspond to the intended meaning of the specified "effort" in the omega+ +test cases. diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/basics-0.c b/external/mit/isl/dist/test_inputs/codegen/omega/basics-0.c new file mode 100644 index 000000000000..1391c3160bf7 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/basics-0.c @@ -0,0 +1,6 @@ +for (int c0 = 5; c0 <= 8; c0 += 1) + s0(c0); +for (int c0 = 10; c0 <= 16; c0 += 2) + s0(c0); +for (int c0 = 20; c0 <= 25; c0 += 1) + s0(c0); diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/basics-0.in b/external/mit/isl/dist/test_inputs/codegen/omega/basics-0.in new file mode 100644 index 000000000000..025da3d30d62 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/basics-0.in @@ -0,0 +1,3 @@ +{ s0[In_1] -> [In_1] : (In_1 >= 5 and In_1 <= 8) or (exists (e0 = [(In_1)/2]: 2e0 = In_1 and In_1 >= 10 and In_1 <= 16)) or (In_1 >= 20 and In_1 <= 25) } +{ : } +{ [i0] -> separate[o0] : o0 >= 0; [i0] -> atomic[o0] : o0 <= -1 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/basics-1.c b/external/mit/isl/dist/test_inputs/codegen/omega/basics-1.c new file mode 100644 index 000000000000..d3d697041659 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/basics-1.c @@ -0,0 +1,3 @@ +for (int c0 = -9; c0 <= 9; c0 += 1) + for (int c1 = max(1, -c0 + 1); c1 <= min(10, -c0 + 10); c1 += 1) + s0(c0, c1); diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/basics-1.in b/external/mit/isl/dist/test_inputs/codegen/omega/basics-1.in new file mode 100644 index 000000000000..82e109311bc6 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/basics-1.in @@ -0,0 +1,3 @@ +{ s0[In_1, In_2] -> [In_1, In_2] : In_2 >= 1 - In_1 and In_2 >= 1 and In_2 <= 10 - In_1 and In_2 <= 10 } +{ : } +{ [i0, i1] -> atomic[o0] : o0 <= 0; [i0, i1] -> separate[o0] : o0 >= 1 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/chosol-0.c b/external/mit/isl/dist/test_inputs/codegen/omega/chosol-0.c new file mode 100644 index 000000000000..4317a0fcffc6 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/chosol-0.c @@ -0,0 +1,7 @@ +for (int c1 = 2; c1 <= n; c1 += 1) + s0(c1); +for (int c1 = 1; c1 < n; c1 += 1) { + for (int c3 = c1 + 1; c3 <= n; c3 += 1) + s1(c3, c1); + s2(c1 + 1); +} diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/chosol-0.in b/external/mit/isl/dist/test_inputs/codegen/omega/chosol-0.in new file mode 100644 index 000000000000..81fde503f745 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/chosol-0.in @@ -0,0 +1,3 @@ +[n] -> { s0[i] -> [0, i, 0, 0] : i >= 2 and i <= n; s1[i, j] -> [1, j, 0, i] : j >= 1 and j <= -1 + i and i <= n; s2[i] -> [1, -1 + i, 1, 0] : i >= 2 and i <= n } +{ : } +[n] -> { [i0, i1, i2, i3] -> atomic[o0] : o0 <= 2; [i0, i1, i2, i3] -> separate[o0] : o0 >= 3 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/chosol-1.c b/external/mit/isl/dist/test_inputs/codegen/omega/chosol-1.c new file mode 100644 index 000000000000..4317a0fcffc6 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/chosol-1.c @@ -0,0 +1,7 @@ +for (int c1 = 2; c1 <= n; c1 += 1) + s0(c1); +for (int c1 = 1; c1 < n; c1 += 1) { + for (int c3 = c1 + 1; c3 <= n; c3 += 1) + s1(c3, c1); + s2(c1 + 1); +} diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/chosol-1.in b/external/mit/isl/dist/test_inputs/codegen/omega/chosol-1.in new file mode 100644 index 000000000000..b5abf2917e8b --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/chosol-1.in @@ -0,0 +1,3 @@ +[n] -> { s0[i] -> [0, i, 0, 0] : i >= 2 and i <= n; s1[i, j] -> [1, j, 0, i] : j >= 1 and j <= -1 + i and i <= n; s2[i] -> [1, -1 + i, 1, 0] : i >= 2 and i <= n } +{ : } +[n] -> { [i0, i1, i2, i3] -> atomic[o0] : o0 <= 1; [i0, i1, i2, i3] -> separate[o0] : o0 >= 2 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/code_gen-0.c b/external/mit/isl/dist/test_inputs/codegen/omega/code_gen-0.c new file mode 100644 index 000000000000..6340134fcdba --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/code_gen-0.c @@ -0,0 +1,7 @@ +for (int c0 = 1; c0 <= 8; c0 += 1) + for (int c1 = 0; c1 <= 7; c1 += 1) { + if (c0 >= 2 && c0 <= 6 && c1 <= 4) + s1(c0, c1); + if (c1 + 1 >= c0) + s0(c0, c1); + } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/code_gen-0.in b/external/mit/isl/dist/test_inputs/codegen/omega/code_gen-0.in new file mode 100644 index 000000000000..a3fa3b1652dc --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/code_gen-0.in @@ -0,0 +1,3 @@ +{ s1[In_1, In_2] -> [In_1, In_2] : In_1 >= 2 and In_1 <= 6 and In_2 >= 0 and In_2 <= 4; s0[In_1, In_2] -> [In_1, In_2] : In_1 >= 1 and In_2 >= -1 + In_1 and In_2 <= 7 } +{ : } +{ [i0, i1] -> atomic[o0] : o0 <= 1; [i0, i1] -> separate[o0] : o0 >= 2 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/code_gen-1.c b/external/mit/isl/dist/test_inputs/codegen/omega/code_gen-1.c new file mode 100644 index 000000000000..1c554dcef976 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/code_gen-1.c @@ -0,0 +1,16 @@ +for (int c0 = 1; c0 <= 8; c0 += 1) { + if (c0 >= 2) { + if (c0 <= 6) + for (int c1 = 0; c1 < c0 - 1; c1 += 1) + s1(c0, c1); + for (int c1 = c0 - 1; c1 <= 4; c1 += 1) { + s1(c0, c1); + s0(c0, c1); + } + for (int c1 = max(5, c0 - 1); c1 <= 7; c1 += 1) + s0(c0, c1); + } else { + for (int c1 = 0; c1 <= 7; c1 += 1) + s0(1, c1); + } +} diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/code_gen-1.in b/external/mit/isl/dist/test_inputs/codegen/omega/code_gen-1.in new file mode 100644 index 000000000000..c6f7fa54a91e --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/code_gen-1.in @@ -0,0 +1,3 @@ +{ s1[In_1, In_2] -> [In_1, In_2] : In_1 >= 2 and In_1 <= 6 and In_2 >= 0 and In_2 <= 4; s0[In_1, In_2] -> [In_1, In_2] : In_1 >= 1 and In_2 >= -1 + In_1 and In_2 <= 7 } +{ : } +{ [i0, i1] -> atomic[o0] : o0 <= 0; [i0, i1] -> separate[o0] : o0 >= 1 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/code_gen-2.c b/external/mit/isl/dist/test_inputs/codegen/omega/code_gen-2.c new file mode 100644 index 000000000000..fa128c1ee775 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/code_gen-2.c @@ -0,0 +1,15 @@ +for (int c1 = 0; c1 <= 7; c1 += 1) + s0(1, c1); +for (int c0 = 2; c0 <= 6; c0 += 1) { + for (int c1 = 0; c1 < c0 - 1; c1 += 1) + s1(c0, c1); + for (int c1 = c0 - 1; c1 <= 4; c1 += 1) { + s1(c0, c1); + s0(c0, c1); + } + for (int c1 = 5; c1 <= 7; c1 += 1) + s0(c0, c1); +} +for (int c0 = 7; c0 <= 8; c0 += 1) + for (int c1 = c0 - 1; c1 <= 7; c1 += 1) + s0(c0, c1); diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/code_gen-2.in b/external/mit/isl/dist/test_inputs/codegen/omega/code_gen-2.in new file mode 100644 index 000000000000..03a7b5df3a30 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/code_gen-2.in @@ -0,0 +1,3 @@ +{ s1[In_1, In_2] -> [In_1, In_2] : In_1 >= 2 and In_1 <= 6 and In_2 >= 0 and In_2 <= 4; s0[In_1, In_2] -> [In_1, In_2] : In_1 >= 1 and In_2 >= -1 + In_1 and In_2 <= 7 } +{ : } +{ [i0, i1] -> atomic[o0] : o0 <= -1; [i0, i1] -> separate[o0] : o0 >= 0 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/collard-0.c b/external/mit/isl/dist/test_inputs/codegen/omega/collard-0.c new file mode 100644 index 000000000000..ca71cfac2d2e --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/collard-0.c @@ -0,0 +1,14 @@ +for (int c4 = 1; c4 <= n; c4 += 1) + s2(c4); +for (int c1 = 1; c1 < n; c1 += 1) { + for (int c4 = 0; c4 < n - c1; c4 += 1) + s0(c1, n - c4); + for (int c3 = 0; c3 < n - c1; c3 += 1) + for (int c4 = c1 + 1; c4 <= n; c4 += 1) + s1(c1, n - c3, c4); +} +for (int c1 = 1; c1 <= n; c1 += 1) { + s4(c1); + for (int c3 = c1 + 1; c3 <= n; c3 += 1) + s3(c3, c1); +} diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/collard-0.in b/external/mit/isl/dist/test_inputs/codegen/omega/collard-0.in new file mode 100644 index 000000000000..d803da7574c8 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/collard-0.in @@ -0,0 +1,3 @@ +[n] -> { s1[i, j, k] -> [1, i, 1, n - j, k] : j >= 1 + i and k >= 1 + i and i >= 1 and j <= n and k <= n; s2[i] -> [0, 0, 0, 0, i] : i >= 1 and i <= n; s4[i] -> [2, i, 0, 0, 0] : i >= 1 and i <= n; s0[i, j] -> [1, i, 0, n - i, n - j] : i >= 1 and j >= 1 + i and j <= n; s3[i, j] -> [2, j, 1, i, j] : j >= 1 and j <= -1 + i and i <= n } +{ : } +[n] -> { [i0, i1, i2, i3, i4] -> separate[o0] : o0 >= 4; [i0, i1, i2, i3, i4] -> atomic[o0] : o0 <= 3 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/dagstuhl1-0.c b/external/mit/isl/dist/test_inputs/codegen/omega/dagstuhl1-0.c new file mode 100644 index 000000000000..3e403ddcd339 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/dagstuhl1-0.c @@ -0,0 +1,2 @@ +for (int c0 = 0; c0 <= 99; c0 += 1) + s0(c0 % 10, c0 / 10); diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/dagstuhl1-0.in b/external/mit/isl/dist/test_inputs/codegen/omega/dagstuhl1-0.in new file mode 100644 index 000000000000..0c2b107517a5 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/dagstuhl1-0.in @@ -0,0 +1,3 @@ +{ s0[i, j] -> [i + 10j] : i >= 0 and i <= 9 and j >= 0 and j <= 9 } +{ : } +{ [i0] -> separate[o0] : o0 >= 0; [i0] -> atomic[o0] : o0 <= -1 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/dagstuhl1-1.c b/external/mit/isl/dist/test_inputs/codegen/omega/dagstuhl1-1.c new file mode 100644 index 000000000000..98953fbde271 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/dagstuhl1-1.c @@ -0,0 +1,2 @@ +for (int c0 = 0; c0 <= 99; c0 += 1) + s0(c0, c0 % 10, c0 / 10); diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/dagstuhl1-1.in b/external/mit/isl/dist/test_inputs/codegen/omega/dagstuhl1-1.in new file mode 100644 index 000000000000..e0c727397369 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/dagstuhl1-1.in @@ -0,0 +1,3 @@ +{s0[p,i,j] -> [p,i,j] : 0 <= i,j <= 9 && p = i+10j} +{ : } +{ [p,i,j] -> separate[o0] : o0 >= 2; [p,i,j] -> atomic[o0] : o0 <= 1 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/fc1-0.c b/external/mit/isl/dist/test_inputs/codegen/omega/fc1-0.c new file mode 100644 index 000000000000..fbec13a719bf --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/fc1-0.c @@ -0,0 +1,7 @@ +for (int c0 = 0; c0 < n - 1; c0 += 1) { + for (int c3 = 0; c3 < n - c0 - 1; c3 += 1) + s0(c0 + 1, n - c3); + for (int c3 = 0; c3 < n - c0 - 1; c3 += 1) + for (int c6 = c0 + 2; c6 <= n; c6 += 1) + s1(c0 + 1, n - c3, c6); +} diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/fc1-0.in b/external/mit/isl/dist/test_inputs/codegen/omega/fc1-0.in new file mode 100644 index 000000000000..688f9580d9bc --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/fc1-0.in @@ -0,0 +1,3 @@ +[n] -> { s0[i, j] -> [-1 + i, 0, n - i, n - j] : i >= 1 and j >= 1 + i and j <= n; s1[i, j, k] -> [-1 + i, 1, n - i, n - j] : j >= 1 + i and k >= 1 + i and i >= 1 and j <= n and k <= n } +{ : } +[n] -> { [i0, i1, i2, i3] -> atomic[o0] : o0 <= 2; [i0, i1, i2, i3] -> separate[o0] : o0 >= 3 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/fc1-1.c b/external/mit/isl/dist/test_inputs/codegen/omega/fc1-1.c new file mode 100644 index 000000000000..14420335587e --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/fc1-1.c @@ -0,0 +1,15 @@ +for (int c3 = 1; c3 <= n; c3 += 1) + s2(c3); +for (int c0 = 0; c0 < n - 1; c0 += 1) { + for (int c3 = 0; c3 < n - c0 - 1; c3 += 1) + s0(c0 + 1, n - c3); + for (int c3 = 0; c3 < n - c0 - 1; c3 += 1) + for (int c6 = c0 + 2; c6 <= n; c6 += 1) + s1(c0 + 1, n - c3, c6); +} +for (int c0 = n - 1; c0 < 2 * n - 1; c0 += 1) { + if (c0 >= n) + for (int c2 = -n + c0 + 2; c2 <= n; c2 += 1) + s3(c2, -n + c0 + 1); + s4(-n + c0 + 2); +} diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/fc1-1.in b/external/mit/isl/dist/test_inputs/codegen/omega/fc1-1.in new file mode 100644 index 000000000000..c9135fff76c4 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/fc1-1.in @@ -0,0 +1,3 @@ +[n] -> { s1[i, j, k] -> [-1 + i, 1, n - i, n - j] : j >= 1 + i and k >= 1 + i and i >= 1 and j <= n and k <= n; s3[i, j] -> [-1 + n + j, 0, i, j] : j >= 1 and j <= -1 + i and i <= n; s4[i] -> [-2 + n + i, 1, 0, 0] : i >= 1 and i <= n; s0[i, j] -> [-1 + i, 0, n - i, n - j] : i >= 1 and j >= 1 + i and j <= n; s2[i] -> [0, 0, 0, i] : i >= 1 and i <= n } +{ : } +[n] -> { [i0, i1, i2, i3] -> atomic[o0] : o0 <= 2; [i0, i1, i2, i3] -> separate[o0] : o0 >= 3 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/fc1-2.c b/external/mit/isl/dist/test_inputs/codegen/omega/fc1-2.c new file mode 100644 index 000000000000..14420335587e --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/fc1-2.c @@ -0,0 +1,15 @@ +for (int c3 = 1; c3 <= n; c3 += 1) + s2(c3); +for (int c0 = 0; c0 < n - 1; c0 += 1) { + for (int c3 = 0; c3 < n - c0 - 1; c3 += 1) + s0(c0 + 1, n - c3); + for (int c3 = 0; c3 < n - c0 - 1; c3 += 1) + for (int c6 = c0 + 2; c6 <= n; c6 += 1) + s1(c0 + 1, n - c3, c6); +} +for (int c0 = n - 1; c0 < 2 * n - 1; c0 += 1) { + if (c0 >= n) + for (int c2 = -n + c0 + 2; c2 <= n; c2 += 1) + s3(c2, -n + c0 + 1); + s4(-n + c0 + 2); +} diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/fc1-2.in b/external/mit/isl/dist/test_inputs/codegen/omega/fc1-2.in new file mode 100644 index 000000000000..6d9a1626a5b8 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/fc1-2.in @@ -0,0 +1,3 @@ +[n] -> { s1[i, j, k] -> [-1 + i, 1, n - i, n - j] : j >= 1 + i and k >= 1 + i and i >= 1 and j <= n and k <= n; s3[i, j] -> [-1 + n + j, 0, i, j] : j >= 1 and j <= -1 + i and i <= n; s4[i] -> [-2 + n + i, 1, 0, 0] : i >= 1 and i <= n; s0[i, j] -> [-1 + i, 0, n - i, n - j] : i >= 1 and j >= 1 + i and j <= n; s2[i] -> [0, 0, 0, i] : i >= 1 and i <= n } +{ : } +[n] -> { [i0, i1, i2, i3] -> atomic[o0] : o0 <= 1; [i0, i1, i2, i3] -> separate[o0] : o0 >= 2 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/fc2-0.c b/external/mit/isl/dist/test_inputs/codegen/omega/fc2-0.c new file mode 100644 index 000000000000..fbec13a719bf --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/fc2-0.c @@ -0,0 +1,7 @@ +for (int c0 = 0; c0 < n - 1; c0 += 1) { + for (int c3 = 0; c3 < n - c0 - 1; c3 += 1) + s0(c0 + 1, n - c3); + for (int c3 = 0; c3 < n - c0 - 1; c3 += 1) + for (int c6 = c0 + 2; c6 <= n; c6 += 1) + s1(c0 + 1, n - c3, c6); +} diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/fc2-0.in b/external/mit/isl/dist/test_inputs/codegen/omega/fc2-0.in new file mode 100644 index 000000000000..688f9580d9bc --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/fc2-0.in @@ -0,0 +1,3 @@ +[n] -> { s0[i, j] -> [-1 + i, 0, n - i, n - j] : i >= 1 and j >= 1 + i and j <= n; s1[i, j, k] -> [-1 + i, 1, n - i, n - j] : j >= 1 + i and k >= 1 + i and i >= 1 and j <= n and k <= n } +{ : } +[n] -> { [i0, i1, i2, i3] -> atomic[o0] : o0 <= 2; [i0, i1, i2, i3] -> separate[o0] : o0 >= 3 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/fc2-1.c b/external/mit/isl/dist/test_inputs/codegen/omega/fc2-1.c new file mode 100644 index 000000000000..14420335587e --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/fc2-1.c @@ -0,0 +1,15 @@ +for (int c3 = 1; c3 <= n; c3 += 1) + s2(c3); +for (int c0 = 0; c0 < n - 1; c0 += 1) { + for (int c3 = 0; c3 < n - c0 - 1; c3 += 1) + s0(c0 + 1, n - c3); + for (int c3 = 0; c3 < n - c0 - 1; c3 += 1) + for (int c6 = c0 + 2; c6 <= n; c6 += 1) + s1(c0 + 1, n - c3, c6); +} +for (int c0 = n - 1; c0 < 2 * n - 1; c0 += 1) { + if (c0 >= n) + for (int c2 = -n + c0 + 2; c2 <= n; c2 += 1) + s3(c2, -n + c0 + 1); + s4(-n + c0 + 2); +} diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/fc2-1.in b/external/mit/isl/dist/test_inputs/codegen/omega/fc2-1.in new file mode 100644 index 000000000000..c9135fff76c4 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/fc2-1.in @@ -0,0 +1,3 @@ +[n] -> { s1[i, j, k] -> [-1 + i, 1, n - i, n - j] : j >= 1 + i and k >= 1 + i and i >= 1 and j <= n and k <= n; s3[i, j] -> [-1 + n + j, 0, i, j] : j >= 1 and j <= -1 + i and i <= n; s4[i] -> [-2 + n + i, 1, 0, 0] : i >= 1 and i <= n; s0[i, j] -> [-1 + i, 0, n - i, n - j] : i >= 1 and j >= 1 + i and j <= n; s2[i] -> [0, 0, 0, i] : i >= 1 and i <= n } +{ : } +[n] -> { [i0, i1, i2, i3] -> atomic[o0] : o0 <= 2; [i0, i1, i2, i3] -> separate[o0] : o0 >= 3 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/floor_bound-0.c b/external/mit/isl/dist/test_inputs/codegen/omega/floor_bound-0.c new file mode 100644 index 000000000000..db7f43707c30 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/floor_bound-0.c @@ -0,0 +1,2 @@ +for (int c0 = 4 * floord(m - 1, 12) + 4; c0 <= floord(n, 3); c0 += 4) + s0(c0); diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/floor_bound-0.in b/external/mit/isl/dist/test_inputs/codegen/omega/floor_bound-0.in new file mode 100644 index 000000000000..45faa57c37d8 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/floor_bound-0.in @@ -0,0 +1,3 @@ +[m, n] -> { s0[In_1] -> [In_1] : exists (e0 = [(In_1)/4]: 4e0 = In_1 and 3In_1 >= m and 3In_1 <= n) } +{ : } +[m, n] -> { [i0] -> separate[o0] : o0 >= 0; [i0] -> atomic[o0] : o0 <= -1 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/floor_bound-1.c b/external/mit/isl/dist/test_inputs/codegen/omega/floor_bound-1.c new file mode 100644 index 000000000000..bc879829073c --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/floor_bound-1.c @@ -0,0 +1,2 @@ +for (int c0 = floord(m, 4); c0 <= n; c0 += 1) + s0(c0); diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/floor_bound-1.in b/external/mit/isl/dist/test_inputs/codegen/omega/floor_bound-1.in new file mode 100644 index 000000000000..7ae72abb93e7 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/floor_bound-1.in @@ -0,0 +1,3 @@ +[m, n] -> { s0[In_1] -> [In_1] : 4In_1 >= -3 + m and In_1 <= n } +{ : } +[m, n] -> { [i0] -> separate[o0] : o0 >= 0; [i0] -> atomic[o0] : o0 <= -1 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/floor_bound-2.c b/external/mit/isl/dist/test_inputs/codegen/omega/floor_bound-2.c new file mode 100644 index 000000000000..ff5f3c337453 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/floor_bound-2.c @@ -0,0 +1,2 @@ +for (int c0 = 4 * floord(m, 4); c0 <= n; c0 += 1) + s0(c0); diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/floor_bound-2.in b/external/mit/isl/dist/test_inputs/codegen/omega/floor_bound-2.in new file mode 100644 index 000000000000..73e1b8eb554f --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/floor_bound-2.in @@ -0,0 +1,3 @@ +[m, n] -> { s0[In_1] -> [In_1] : exists (e0 = [(m)/4]: 4e0 <= m and 4e0 >= -3 + m and 4e0 <= In_1 and In_1 <= n) } +{ : } +[m, n] -> { [i0] -> separate[o0] : o0 >= 0; [i0] -> atomic[o0] : o0 <= -1 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/floor_bound-3.c b/external/mit/isl/dist/test_inputs/codegen/omega/floor_bound-3.c new file mode 100644 index 000000000000..e3c9728de91b --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/floor_bound-3.c @@ -0,0 +1,2 @@ +for (int c0 = 3 * floord(m, 3) + 4 * floord(m, 4); c0 <= n; c0 += 1) + s0(c0); diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/floor_bound-3.in b/external/mit/isl/dist/test_inputs/codegen/omega/floor_bound-3.in new file mode 100644 index 000000000000..1ff7e2c38619 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/floor_bound-3.in @@ -0,0 +1,3 @@ +[m, n] -> { s0[In_1] -> [In_1] : exists (e0 = [(m)/3], e1 = [(m)/4]: 4e1 <= m and 3e0 <= m and 4e1 >= -3 + m and 3e0 >= -2 + m and In_1 <= n and 4e1 <= In_1 - 3e0) } +{ : } +[m, n] -> { [i0] -> separate[o0] : o0 >= 0; [i0] -> atomic[o0] : o0 <= -1 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/floor_bound-4.c b/external/mit/isl/dist/test_inputs/codegen/omega/floor_bound-4.c new file mode 100644 index 000000000000..dc6ba0ae9416 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/floor_bound-4.c @@ -0,0 +1,3 @@ +if (n >= 3 * floord(n + 1, 3)) + for (int c0 = m; c0 <= 5 * floord(n + 1, 3); c0 += 1) + s0(c0); diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/floor_bound-4.in b/external/mit/isl/dist/test_inputs/codegen/omega/floor_bound-4.in new file mode 100644 index 000000000000..7a726c39379c --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/floor_bound-4.in @@ -0,0 +1,3 @@ +[n, m] -> { s0[In_1] -> [In_1] : exists (e0 = [(1 + n)/3]: In_1 >= m and 5e0 >= In_1 and 3e0 <= n and 3e0 >= -1 + n) } +{ : } +[n, m] -> { [i0] -> atomic[o0] : o0 <= -1; [i0] -> separate[o0] : o0 >= 0 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/floor_bound-5.c b/external/mit/isl/dist/test_inputs/codegen/omega/floor_bound-5.c new file mode 100644 index 000000000000..3e9f47d4ccc3 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/floor_bound-5.c @@ -0,0 +1,2 @@ +for (int c0 = 4 * floord(m, 32); c0 <= n; c0 += 1) + s0(c0); diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/floor_bound-5.in b/external/mit/isl/dist/test_inputs/codegen/omega/floor_bound-5.in new file mode 100644 index 000000000000..cc24250ddaa9 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/floor_bound-5.in @@ -0,0 +1,3 @@ +[m, n] -> { s0[In_1] -> [In_1] : exists (e0 = [(m)/32]: 32e0 <= m and 32e0 >= -31 + m and 4e0 <= In_1 and In_1 <= n) } +{ : } +[m, n] -> { [i0] -> separate[o0] : o0 >= 0; [i0] -> atomic[o0] : o0 <= -1 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/floor_bound-6.c b/external/mit/isl/dist/test_inputs/codegen/omega/floor_bound-6.c new file mode 100644 index 000000000000..743b0c938c5b --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/floor_bound-6.c @@ -0,0 +1,3 @@ +if (m >= 8 * floord(m + 1, 8)) + for (int c0 = 4 * floord(m + 1, 32); c0 <= n; c0 += 1) + s0(c0); diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/floor_bound-6.in b/external/mit/isl/dist/test_inputs/codegen/omega/floor_bound-6.in new file mode 100644 index 000000000000..78d2be97e2ab --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/floor_bound-6.in @@ -0,0 +1,3 @@ +[m, n] -> { s0[In_1] -> [In_1] : exists (e0 = [(1 + m)/8], e1 = [(e0)/4]: 8e0 <= m and 8e0 >= -6 + m and 4e1 <= In_1 and In_1 <= n and 32e1 <= 1 + m and 32e1 >= -30 + m) } +{ : } +[m, n] -> { [i0] -> separate[o0] : o0 >= 0; [i0] -> atomic[o0] : o0 <= -1 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/gc-0.c b/external/mit/isl/dist/test_inputs/codegen/omega/gc-0.c new file mode 100644 index 000000000000..d8234a378cec --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/gc-0.c @@ -0,0 +1,2 @@ +for (int c0 = 2; c0 <= 8; c0 += 2) + s0(c0); diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/gc-0.in b/external/mit/isl/dist/test_inputs/codegen/omega/gc-0.in new file mode 100644 index 000000000000..063e35361f12 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/gc-0.in @@ -0,0 +1,3 @@ +{ s0[In_1] -> [In_1] : exists (e0 = [(In_1)/2]: 2e0 = In_1 and In_1 >= 2 and In_1 <= 8) } +{ : } +{ [i0] -> separate[o0] : o0 >= 0; [i0] -> atomic[o0] : o0 <= -1 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/ge-0.c b/external/mit/isl/dist/test_inputs/codegen/omega/ge-0.c new file mode 100644 index 000000000000..1c22a5d9b0ae --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/ge-0.c @@ -0,0 +1,7 @@ +for (int c0 = 2; c0 <= n; c0 += 1) + for (int c1 = 1; c1 <= n; c1 += 1) { + for (int c3 = 1; c3 < min(c0, c1); c3 += 1) + s1(c3, c0, c1); + if (c0 >= c1 + 1) + s0(c1, c0); + } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/ge-0.in b/external/mit/isl/dist/test_inputs/codegen/omega/ge-0.in new file mode 100644 index 000000000000..edd7c36ee61d --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/ge-0.in @@ -0,0 +1,3 @@ +[n] -> { s0[k, i] -> [i, k, 1, 0] : k >= 1 and i >= 1 + k and i <= n; s1[k, i, j] -> [i, j, 0, k] : i >= 1 + k and j >= 1 + k and k >= 1 and i <= n and j <= n } +{ : } +[n] -> { [i0, i1, i2, i3] -> atomic[o0] : o0 <= 2; [i0, i1, i2, i3] -> separate[o0] : o0 >= 3 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/ge-1.c b/external/mit/isl/dist/test_inputs/codegen/omega/ge-1.c new file mode 100644 index 000000000000..1c22a5d9b0ae --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/ge-1.c @@ -0,0 +1,7 @@ +for (int c0 = 2; c0 <= n; c0 += 1) + for (int c1 = 1; c1 <= n; c1 += 1) { + for (int c3 = 1; c3 < min(c0, c1); c3 += 1) + s1(c3, c0, c1); + if (c0 >= c1 + 1) + s0(c1, c0); + } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/ge-1.in b/external/mit/isl/dist/test_inputs/codegen/omega/ge-1.in new file mode 100644 index 000000000000..4a08142d5061 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/ge-1.in @@ -0,0 +1,3 @@ +[n] -> { s0[k, i] -> [i, k, 1, 0] : k >= 1 and i >= 1 + k and i <= n; s1[k, i, j] -> [i, j, 0, k] : i >= 1 + k and j >= 1 + k and k >= 1 and i <= n and j <= n } +{ : } +[n] -> { [i0, i1, i2, i3] -> atomic[o0] : o0 <= 1; [i0, i1, i2, i3] -> separate[o0] : o0 >= 2 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/gist-0.c b/external/mit/isl/dist/test_inputs/codegen/omega/gist-0.c new file mode 100644 index 000000000000..4608d61d8dbf --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/gist-0.c @@ -0,0 +1,3 @@ +for (int c0 = 1; c0 <= n; c0 += 4) + for (int c1 = c0; c1 <= n; c1 += 3) + s0(c0, c1); diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/gist-0.in b/external/mit/isl/dist/test_inputs/codegen/omega/gist-0.in new file mode 100644 index 000000000000..b2f3366f8d3f --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/gist-0.in @@ -0,0 +1,3 @@ +[n] -> { s0[In_1, In_2] -> [In_1, In_2] : exists (e0 = [(-1 + In_1)/4], e1 = [(-3 - In_1 + 4In_2)/12]: 4e0 = -1 + In_1 and 12e1 = -3 - In_1 + 4In_2 and In_1 >= 1 and In_2 >= In_1 and In_2 <= n) } +{ : } +[n] -> { [i0, i1] -> atomic[o0] : o0 <= 0; [i0, i1] -> separate[o0] : o0 >= 1 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/gist-1.c b/external/mit/isl/dist/test_inputs/codegen/omega/gist-1.c new file mode 100644 index 000000000000..8f1c692c8ea4 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/gist-1.c @@ -0,0 +1,3 @@ +for (int c0 = 1; c0 <= n; c0 += 4) + for (int c1 = c0; c1 <= n; c1 += 8) + s0(c0, c1); diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/gist-1.in b/external/mit/isl/dist/test_inputs/codegen/omega/gist-1.in new file mode 100644 index 000000000000..ecbf8e7b06ea --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/gist-1.in @@ -0,0 +1,3 @@ +[n] -> { s0[In_1, In_2] -> [In_1, In_2] : exists (e0 = [(-1 + In_1)/4], e1 = [(-In_1 + In_2)/8]: 4e0 = -1 + In_1 and 8e1 = -In_1 + In_2 and In_1 >= 1 and In_2 >= In_1 and In_2 <= n) } +{ : } +[n] -> { [i0, i1] -> atomic[o0] : o0 <= 0; [i0, i1] -> separate[o0] : o0 >= 1 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/gist-2.c b/external/mit/isl/dist/test_inputs/codegen/omega/gist-2.c new file mode 100644 index 000000000000..317498782d44 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/gist-2.c @@ -0,0 +1,3 @@ +for (int c0 = 1; c0 <= n; c0 += 256) + for (int c1 = c0; c1 <= n; c1 += 8) + s0(c0, c1); diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/gist-2.in b/external/mit/isl/dist/test_inputs/codegen/omega/gist-2.in new file mode 100644 index 000000000000..63edb52b5f7e --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/gist-2.in @@ -0,0 +1,3 @@ +[n] -> { s0[In_1, In_2] -> [In_1, In_2] : exists (e0 = [(-1 + In_1)/256], e1 = [(-1 + In_2)/8]: 256e0 = -1 + In_1 and 8e1 = -1 + In_2 and In_1 >= 1 and In_2 >= In_1 and In_2 <= n) } +{ : } +[n] -> { [i0, i1] -> atomic[o0] : o0 <= 0; [i0, i1] -> separate[o0] : o0 >= 1 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/gist-3.c b/external/mit/isl/dist/test_inputs/codegen/omega/gist-3.c new file mode 100644 index 000000000000..513f385c3c58 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/gist-3.c @@ -0,0 +1,3 @@ +for (int c0 = 1; c0 < n; c0 += 4) + for (int c1 = c0 + 1; c1 <= n; c1 += 6) + s0(c0, c1); diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/gist-3.in b/external/mit/isl/dist/test_inputs/codegen/omega/gist-3.in new file mode 100644 index 000000000000..43cac1243b8e --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/gist-3.in @@ -0,0 +1,3 @@ +[n] -> { s0[In_1, In_2] -> [In_1, In_2] : exists (e0 = [(-1 + In_1)/4], e1 = [(-1 - In_1 + In_2)/6]: 4e0 = -1 + In_1 and 6e1 = -1 - In_1 + In_2 and In_1 >= 1 and In_2 >= 1 + In_1 and In_2 <= n) } +{ : } +[n] -> { [i0, i1] -> atomic[o0] : o0 <= 0; [i0, i1] -> separate[o0] : o0 >= 1 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/gist-4.c b/external/mit/isl/dist/test_inputs/codegen/omega/gist-4.c new file mode 100644 index 000000000000..a6f6fd001b08 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/gist-4.c @@ -0,0 +1,3 @@ +for (int c0 = 1; c0 <= n; c0 += 6) + for (int c1 = c0; c1 <= n; c1 += 4) + s0(c0, c1); diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/gist-4.in b/external/mit/isl/dist/test_inputs/codegen/omega/gist-4.in new file mode 100644 index 000000000000..f67f837d5988 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/gist-4.in @@ -0,0 +1,3 @@ +[n] -> { s0[In_1, In_2] -> [In_1, In_2] : exists (e0 = [(-1 + In_1)/6], e1 = [(-2 - In_1 + 3In_2)/12]: 6e0 = -1 + In_1 and 12e1 = -2 - In_1 + 3In_2 and In_1 >= 1 and In_2 >= In_1 and In_2 <= n) } +{ : } +[n] -> { [i0, i1] -> atomic[o0] : o0 <= 0; [i0, i1] -> separate[o0] : o0 >= 1 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/gist-5.c b/external/mit/isl/dist/test_inputs/codegen/omega/gist-5.c new file mode 100644 index 000000000000..c2df61fb4e12 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/gist-5.c @@ -0,0 +1,3 @@ +for (int c0 = 1; c0 <= n; c0 += 12) + for (int c1 = c0; c1 <= n; c1 += 8) + s0(c0, c1); diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/gist-5.in b/external/mit/isl/dist/test_inputs/codegen/omega/gist-5.in new file mode 100644 index 000000000000..8b192c132fdd --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/gist-5.in @@ -0,0 +1,3 @@ +[n] -> { s0[In_1, In_2] -> [In_1, In_2] : exists (e0 = [(-1 + In_1)/12], e1 = [(-2 - In_1 + 3In_2)/24]: 12e0 = -1 + In_1 and 24e1 = -2 - In_1 + 3In_2 and In_1 >= 1 and In_2 >= In_1 and In_2 <= n) } +{ : } +[n] -> { [i0, i1] -> atomic[o0] : o0 <= 0; [i0, i1] -> separate[o0] : o0 >= 1 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/guard1-0.c b/external/mit/isl/dist/test_inputs/codegen/omega/guard1-0.c new file mode 100644 index 000000000000..e430f2b5c8c6 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/guard1-0.c @@ -0,0 +1,2 @@ +if ((n - m - 1) % 3 == 0) + s0(n, m); diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/guard1-0.in b/external/mit/isl/dist/test_inputs/codegen/omega/guard1-0.in new file mode 100644 index 000000000000..52964e264890 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/guard1-0.in @@ -0,0 +1,3 @@ +[n, m] -> { s0[n, m] -> [n, m] : exists (e0 = [(-2 - n + m)/3]: 3e0 = -2 - n + m) } +{ : } +[n, m] -> { [i0, i1] -> atomic[o0] : o0 <= 0; [i0, i1] -> separate[o0] : o0 >= 1 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/guard1-1.c b/external/mit/isl/dist/test_inputs/codegen/omega/guard1-1.c new file mode 100644 index 000000000000..3994a6122e75 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/guard1-1.c @@ -0,0 +1,2 @@ +if ((n + m + 1) % 2 == 0) + s0(n, m); diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/guard1-1.in b/external/mit/isl/dist/test_inputs/codegen/omega/guard1-1.in new file mode 100644 index 000000000000..141f585d3589 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/guard1-1.in @@ -0,0 +1,3 @@ +[n, m] -> { s0[n, m] -> [n, m] : exists (e0 = [(-1 - n + m)/2]: 2e0 = -1 - n + m) } +{ : } +[n, m] -> { [i0, i1] -> atomic[o0] : o0 <= 0; [i0, i1] -> separate[o0] : o0 >= 1 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/hpf-0.c b/external/mit/isl/dist/test_inputs/codegen/omega/hpf-0.c new file mode 100644 index 000000000000..c676558941fb --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/hpf-0.c @@ -0,0 +1,4 @@ +if (P2 >= 0 && P2 <= 3 && P1 == P2) + for (int c0 = 0; c0 <= min(2, -P2 + 4); c0 += 1) + for (int c2 = (-P2 - c0 + 6) % 3; c2 <= 3; c2 += 3) + s0(c0, c0, c2, c2); diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/hpf-0.in b/external/mit/isl/dist/test_inputs/codegen/omega/hpf-0.in new file mode 100644 index 000000000000..e697792ea669 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/hpf-0.in @@ -0,0 +1,3 @@ +[P1, P2] -> { s0[In_1, In_1, In_3, In_3] -> [In_1, In_1, In_3, In_3] : exists (e0 = [(-2P2 - 2In_1 + In_3)/3]: P1 = P2 and 3e0 = -2P2 - 2In_1 + In_3 and P2 >= 0 and P2 <= 3 and In_1 <= 4 - P2 and In_1 >= 0 and In_1 <= 2 and In_3 >= 0 and In_3 <= 3) } +{ : } +[P2, P1] -> { [i0, i1, i2, i3] -> separate[o0] : o0 >= 3; [i0, i1, i2, i3] -> atomic[o0] : o0 <= 2 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/if_then-0.c b/external/mit/isl/dist/test_inputs/codegen/omega/if_then-0.c new file mode 100644 index 000000000000..d2e100b44021 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/if_then-0.c @@ -0,0 +1,13 @@ +if (m <= 1) { + for (int c0 = 1; c0 <= n; c0 += 1) + for (int c1 = 1; c1 <= n; c1 += 1) + s2(c0, c1); +} else if (n >= m + 1) { + for (int c0 = 1; c0 <= n; c0 += 1) + for (int c1 = 1; c1 <= n; c1 += 1) + s0(c0, c1); +} else { + for (int c0 = 1; c0 <= n; c0 += 1) + for (int c1 = 1; c1 <= n; c1 += 1) + s1(c0, c1); +} diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/if_then-0.in b/external/mit/isl/dist/test_inputs/codegen/omega/if_then-0.in new file mode 100644 index 000000000000..93f3f7c2bc89 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/if_then-0.in @@ -0,0 +1,3 @@ +[n, m] -> { s2[In_1, In_2] -> [In_1, In_2] : In_1 >= 1 and In_1 <= n and In_2 >= 1 and In_2 <= n and m <= 1; s0[In_1, In_2] -> [In_1, In_2] : m >= 2 and m <= -1 + n and In_1 >= 1 and In_1 <= n and In_2 >= 1 and In_2 <= n; s1[In_1, In_2] -> [In_1, In_2] : In_1 <= n and In_2 <= n and m >= n and In_1 >= 1 and In_2 >= 1 and m >= 2 } +{ : } +[n, m] -> { [i0, i1] -> atomic[o0] : o0 <= 1; [i0, i1] -> separate[o0] : o0 >= 2 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/if_then-1.c b/external/mit/isl/dist/test_inputs/codegen/omega/if_then-1.c new file mode 100644 index 000000000000..18ca37021869 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/if_then-1.c @@ -0,0 +1,9 @@ +for (int c0 = 1; c0 <= 100; c0 += 1) { + if (n >= 2) + s0(c0); + for (int c1 = 1; c1 <= 100; c1 += 1) { + if (n >= 2) + s1(c0, c1); + s2(c0, c1); + } +} diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/if_then-1.in b/external/mit/isl/dist/test_inputs/codegen/omega/if_then-1.in new file mode 100644 index 000000000000..0258439fff73 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/if_then-1.in @@ -0,0 +1,3 @@ +[n] -> { s0[In_1] -> [In_1,0] : In_1 >= 1 and In_1 <= 100 and n >= 2; s1[In_1, In_2] -> [In_1, In_2] : In_1 >= 1 and In_1 <= 100 and In_2 >= 1 and In_2 <= 100 and n >= 2; s2[In_1, In_2] -> [In_1, In_2] : In_1 >= 1 and In_1 <= 100 and In_2 >= 1 and In_2 <= 100 } +{ : } +[n] -> { [i0,i1] -> separate[o0] : o0 >= 2; [i0,i1] -> atomic[o0] : o0 <= 1 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/if_then-2.c b/external/mit/isl/dist/test_inputs/codegen/omega/if_then-2.c new file mode 100644 index 000000000000..158b0782ffdc --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/if_then-2.c @@ -0,0 +1,12 @@ +for (int c0 = 1; c0 <= 100; c0 += 1) { + if (n >= 2) { + s0(c0); + for (int c1 = 1; c1 <= 100; c1 += 1) { + s1(c0, c1); + s2(c0, c1); + } + } else { + for (int c1 = 1; c1 <= 100; c1 += 1) + s2(c0, c1); + } +} diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/if_then-2.in b/external/mit/isl/dist/test_inputs/codegen/omega/if_then-2.in new file mode 100644 index 000000000000..0a220ee3a54e --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/if_then-2.in @@ -0,0 +1,3 @@ +[n] -> { s0[In_1] -> [In_1,0] : In_1 >= 1 and In_1 <= 100 and n >= 2; s1[In_1, In_2] -> [In_1, In_2] : In_1 >= 1 and In_1 <= 100 and In_2 >= 1 and In_2 <= 100 and n >= 2; s2[In_1, In_2] -> [In_1, In_2] : In_1 >= 1 and In_1 <= 100 and In_2 >= 1 and In_2 <= 100 } +{ : } +[n] -> { [i0,i1] -> separate[o0] : o0 >= 1; [i0,i1] -> atomic[o0] : o0 <= 0 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/if_then-3.c b/external/mit/isl/dist/test_inputs/codegen/omega/if_then-3.c new file mode 100644 index 000000000000..bae078e4662f --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/if_then-3.c @@ -0,0 +1,13 @@ +if (n >= 2) { + for (int c0 = 1; c0 <= 100; c0 += 1) { + s0(c0); + for (int c1 = 1; c1 <= 100; c1 += 1) { + s1(c0, c1); + s2(c0, c1); + } + } +} else { + for (int c0 = 1; c0 <= 100; c0 += 1) + for (int c1 = 1; c1 <= 100; c1 += 1) + s2(c0, c1); +} diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/if_then-3.in b/external/mit/isl/dist/test_inputs/codegen/omega/if_then-3.in new file mode 100644 index 000000000000..a0315f1a7b19 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/if_then-3.in @@ -0,0 +1,3 @@ +[n] -> { s0[In_1] -> [In_1,0] : In_1 >= 1 and In_1 <= 100 and n >= 2; s1[In_1, In_2] -> [In_1, In_2] : In_1 >= 1 and In_1 <= 100 and In_2 >= 1 and In_2 <= 100 and n >= 2; s2[In_1, In_2] -> [In_1, In_2] : In_1 >= 1 and In_1 <= 100 and In_2 >= 1 and In_2 <= 100 } +{ : } +[n] -> { [i0,i1] -> separate[o0] : o0 >= 0; [i0,i1] -> atomic[o0] : o0 <= -1 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/if_then-4.c b/external/mit/isl/dist/test_inputs/codegen/omega/if_then-4.c new file mode 100644 index 000000000000..fa81628ade8c --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/if_then-4.c @@ -0,0 +1,7 @@ +for (int c0 = 4; c0 <= 100; c0 += 4) { + for (int c1 = 1; c1 <= 100; c1 += 1) + s0(c0, c1); + if (c0 >= 8 && c0 <= 96) + for (int c1 = 10; c1 <= 100; c1 += 1) + s1(c0 + 2, c1); +} diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/if_then-4.in b/external/mit/isl/dist/test_inputs/codegen/omega/if_then-4.in new file mode 100644 index 000000000000..30dc8dc24d25 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/if_then-4.in @@ -0,0 +1,3 @@ +{ s1[In_1, In_2] -> [In_1, In_2] : exists (e0 = [(-2 + In_1)/4]: 4e0 = -2 + In_1 and In_1 >= 10 and In_1 <= 98 and In_2 >= 10 and In_2 <= 100); s0[In_1, In_2] -> [In_1, In_2] : exists (e0 = [(In_1)/4]: 4e0 = In_1 and In_1 >= 4 and In_1 <= 100 and In_2 >= 1 and In_2 <= 100) } +{ : } +{ [i0, i1] -> atomic[o0] : o0 <= 1; [i0, i1] -> separate[o0] : o0 >= 2 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/if_then-5.c b/external/mit/isl/dist/test_inputs/codegen/omega/if_then-5.c new file mode 100644 index 000000000000..fa81628ade8c --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/if_then-5.c @@ -0,0 +1,7 @@ +for (int c0 = 4; c0 <= 100; c0 += 4) { + for (int c1 = 1; c1 <= 100; c1 += 1) + s0(c0, c1); + if (c0 >= 8 && c0 <= 96) + for (int c1 = 10; c1 <= 100; c1 += 1) + s1(c0 + 2, c1); +} diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/if_then-5.in b/external/mit/isl/dist/test_inputs/codegen/omega/if_then-5.in new file mode 100644 index 000000000000..87a40f4733a3 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/if_then-5.in @@ -0,0 +1,3 @@ +{ s1[In_1, In_2] -> [In_1, In_2] : exists (e0 = [(-2 + In_1)/4]: 4e0 = -2 + In_1 and In_1 >= 10 and In_1 <= 98 and In_2 >= 10 and In_2 <= 100); s0[In_1, In_2] -> [In_1, In_2] : exists (e0 = [(In_1)/4]: 4e0 = In_1 and In_1 >= 4 and In_1 <= 100 and In_2 >= 1 and In_2 <= 100) } +{ : } +{ [i0, i1] -> atomic[o0] : o0 <= 0; [i0, i1] -> separate[o0] : o0 >= 1 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/iter1-0.c b/external/mit/isl/dist/test_inputs/codegen/omega/iter1-0.c new file mode 100644 index 000000000000..c15c86b2f6b5 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/iter1-0.c @@ -0,0 +1,2 @@ +for (int c0 = 2; c0 <= 9; c0 += 1) + s0(c0); diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/iter1-0.in b/external/mit/isl/dist/test_inputs/codegen/omega/iter1-0.in new file mode 100644 index 000000000000..8b8767860279 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/iter1-0.in @@ -0,0 +1,3 @@ +{ s0[In_1] -> [In_1] : In_1 >= 2 and In_1 <= 9 } +{ : } +{ [i0] -> separate[o0] : o0 >= 0; [i0] -> atomic[o0] : o0 <= -1 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/iter2-0.c b/external/mit/isl/dist/test_inputs/codegen/omega/iter2-0.c new file mode 100644 index 000000000000..5506929a1063 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/iter2-0.c @@ -0,0 +1,3 @@ +for (int c0 = 1; c0 <= 10; c0 += 1) + for (int c1 = 10; c1 <= 100; c1 += 1) + s0(c0, c1); diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/iter2-0.in b/external/mit/isl/dist/test_inputs/codegen/omega/iter2-0.in new file mode 100644 index 000000000000..16ea0df1805f --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/iter2-0.in @@ -0,0 +1,3 @@ +{ s0[In_1, In_2] -> [In_1, In_2] : In_1 >= 1 and In_1 <= 10 and In_2 >= 10 and In_2 <= 100 } +{ : } +{ [i0, i1] -> atomic[o0] : o0 <= 0; [i0, i1] -> separate[o0] : o0 >= 1 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/iter3-0.c b/external/mit/isl/dist/test_inputs/codegen/omega/iter3-0.c new file mode 100644 index 000000000000..43b6e3aa0f61 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/iter3-0.c @@ -0,0 +1,3 @@ +for (int c0 = 2; c0 <= 8; c0 += 1) + for (int c1 = c0 + 1; c1 <= 9; c1 += 1) + s0(c0, c1); diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/iter3-0.in b/external/mit/isl/dist/test_inputs/codegen/omega/iter3-0.in new file mode 100644 index 000000000000..fc26493e28ed --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/iter3-0.in @@ -0,0 +1,3 @@ +{ s0[In_1, In_2] -> [In_1, In_2] : In_1 >= 2 and In_2 >= 1 + In_1 and In_2 <= 9 } +{ : } +{ [i0, i1] -> atomic[o0] : o0 <= 0; [i0, i1] -> separate[o0] : o0 >= 1 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/iter4-0.c b/external/mit/isl/dist/test_inputs/codegen/omega/iter4-0.c new file mode 100644 index 000000000000..65e37023ff3d --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/iter4-0.c @@ -0,0 +1,3 @@ +for (int c0 = 2; c0 <= 9; c0 += 1) + for (int c1 = c0 + 1; c1 <= 2 * c0; c1 += 1) + s0(c0, c1); diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/iter4-0.in b/external/mit/isl/dist/test_inputs/codegen/omega/iter4-0.in new file mode 100644 index 000000000000..94001d5251dd --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/iter4-0.in @@ -0,0 +1,3 @@ +{ s0[In_1, In_2] -> [In_1, In_2] : In_1 >= 2 and In_2 >= 1 + In_1 and In_2 <= 2In_1 and In_1 <= 9 } +{ : } +{ [i0, i1] -> atomic[o0] : o0 <= 0; [i0, i1] -> separate[o0] : o0 >= 1 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/iter5-0.c b/external/mit/isl/dist/test_inputs/codegen/omega/iter5-0.c new file mode 100644 index 000000000000..66c7c0971f8d --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/iter5-0.c @@ -0,0 +1,3 @@ +for (int c0 = 2; c0 <= 9; c0 += 1) + for (int c1 = c0 + 1; c1 <= min(16, 2 * c0); c1 += 1) + s0(c0, c1); diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/iter5-0.in b/external/mit/isl/dist/test_inputs/codegen/omega/iter5-0.in new file mode 100644 index 000000000000..1e4f739447ec --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/iter5-0.in @@ -0,0 +1,3 @@ +{ s0[In_1, In_2] -> [In_1, In_2] : In_1 >= 2 and In_2 >= 1 + In_1 and In_2 <= 2In_1 and In_2 <= 16 and In_1 <= 9 } +{ : } +{ [i0, i1] -> atomic[o0] : o0 <= 0; [i0, i1] -> separate[o0] : o0 >= 1 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/iter6-0.c b/external/mit/isl/dist/test_inputs/codegen/omega/iter6-0.c new file mode 100644 index 000000000000..a0346b69cdd7 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/iter6-0.c @@ -0,0 +1,3 @@ +for (int c0 = 1; c0 <= 5; c0 += 1) + for (int c1 = 12; c1 <= 17; c1 += 1) + s0(c0, c1); diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/iter6-0.in b/external/mit/isl/dist/test_inputs/codegen/omega/iter6-0.in new file mode 100644 index 000000000000..1b8ed2b3c04a --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/iter6-0.in @@ -0,0 +1,3 @@ +{ s0[In_1, In_2] -> [In_1, In_2] : In_1 >= 1 and In_1 <= 5 and In_2 >= 12 and In_2 <= 17 } +{ : } +{ [i0, i1] -> atomic[o0] : o0 <= 0; [i0, i1] -> separate[o0] : o0 >= 1 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/iter6-1.c b/external/mit/isl/dist/test_inputs/codegen/omega/iter6-1.c new file mode 100644 index 000000000000..daccd39be7a1 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/iter6-1.c @@ -0,0 +1,2 @@ +for (int c0 = 46; c0 <= 70; c0 += 12) + s0(c0, (17 * c0 - 170) / 12); diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/iter6-1.in b/external/mit/isl/dist/test_inputs/codegen/omega/iter6-1.in new file mode 100644 index 000000000000..4ee2ad6608d8 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/iter6-1.in @@ -0,0 +1,3 @@ +{ s0[In_1, In_2] -> [In_1, o1] : 12In_2 = -170 + 17In_1 and 12o1 = -170 + 17In_1 and In_1 >= 46 and In_1 <= 70 } +{ : } +{ [i0, i1] -> atomic[o0] : o0 <= 0; [i0, i1] -> separate[o0] : o0 >= 1 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/iter7-0.c b/external/mit/isl/dist/test_inputs/codegen/omega/iter7-0.c new file mode 100644 index 000000000000..2606890886ed --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/iter7-0.c @@ -0,0 +1,2 @@ +for (int c0 = 1; c0 <= 3; c0 += 2) + s0(c0, (-3 * c0 + 15) / 2); diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/iter7-0.in b/external/mit/isl/dist/test_inputs/codegen/omega/iter7-0.in new file mode 100644 index 000000000000..90d3efb7de01 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/iter7-0.in @@ -0,0 +1,3 @@ +{ s0[In_1, In_2] -> [In_1, o1] : 2In_2 = 15 - 3In_1 and 2o1 = 15 - 3In_1 and In_1 <= 3 and In_1 >= 1 } +{ : } +{ [i0, i1] -> atomic[o0] : o0 <= 0; [i0, i1] -> separate[o0] : o0 >= 1 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/iter8-0.c b/external/mit/isl/dist/test_inputs/codegen/omega/iter8-0.c new file mode 100644 index 000000000000..a33fc49b76ab --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/iter8-0.c @@ -0,0 +1,2 @@ +for (int c0 = max(exprVar2 + 1, exprVar2 + 8 * floord(-exprVar2 + exprVar1 - 1, 8) + 9); c0 <= 16; c0 += 8) + s0(c0); diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/iter8-0.in b/external/mit/isl/dist/test_inputs/codegen/omega/iter8-0.in new file mode 100644 index 000000000000..682928048dfe --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/iter8-0.in @@ -0,0 +1,3 @@ +[exprVar2, exprVar3, exprVar1] -> { s0[In_1] -> [In_1] : exists (e0 = [(-1 - exprVar2 + In_1)/8]: exprVar3 = 0 and 8e0 = -1 - exprVar2 + In_1 and exprVar1 >= 1 and In_1 >= 1 + exprVar1 and In_1 <= 16 and In_1 >= 1 + exprVar2) } +[exprVar3, exprVar2, exprVar1] -> { : exists (e0: exprVar3 = 0 and 8e0 >= -15 + exprVar2 and exprVar2 <= 15 and exprVar1 >= 1 and 8e0 <= exprVar2 - exprVar1) } +[exprVar2, exprVar3, exprVar1] -> { [i0] -> separate[o0] : o0 >= 0; [i0] -> atomic[o0] : o0 <= -1 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/iter9-0.c b/external/mit/isl/dist/test_inputs/codegen/omega/iter9-0.c new file mode 100644 index 000000000000..e0b957f53b15 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/iter9-0.c @@ -0,0 +1,11 @@ +for (int c0 = 1; c0 <= 15; c0 += 1) { + if (((-exprVar1 + 15) % 8) + c0 <= 15) { + s2(c0); + s0(c0); + s4(c0); + s3(c0); + s1(c0); + } + if (((-exprVar1 + 15) % 8) + c0 <= 15 || (exprVar1 - c0 + 1) % 8 == 0) + s5(c0); +} diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/iter9-0.in b/external/mit/isl/dist/test_inputs/codegen/omega/iter9-0.in new file mode 100644 index 000000000000..9596d73727cd --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/iter9-0.in @@ -0,0 +1,3 @@ +[exprVar2, exprVar1] -> { s3[In_1] -> [In_1] : exists (e0: exprVar2 = 0 and 8e0 >= -15 + exprVar1 and exprVar1 <= 15 and In_1 >= 1 and 8e0 <= exprVar1 - In_1); s4[In_1] -> [In_1] : exists (e0: exprVar2 = 0 and 8e0 >= -15 + exprVar1 and exprVar1 <= 15 and In_1 >= 1 and 8e0 <= exprVar1 - In_1); s1[In_1] -> [In_1] : exists (e0: exprVar2 = 0 and 8e0 >= -15 + exprVar1 and exprVar1 <= 15 and In_1 >= 1 and 8e0 <= exprVar1 - In_1); s5[In_1] -> [In_1] : (exists (e0: exprVar2 = 0 and 8e0 >= -15 + exprVar1 and exprVar1 <= 15 and In_1 >= 1 and 8e0 <= exprVar1 - In_1)) or (exists (e0 = [(-1 - exprVar1 + In_1)/8]: exprVar2 = 0 and 8e0 = -1 - exprVar1 + In_1 and In_1 >= 1 + exprVar1 and In_1 >= 1 and In_1 <= 15)); s0[In_1] -> [In_1] : exists (e0: exprVar2 = 0 and 8e0 >= -15 + exprVar1 and exprVar1 <= 15 and In_1 >= 1 and 8e0 <= exprVar1 - In_1); s2[In_1] -> [In_1] : exists (e0: exprVar2 = 0 and 8e0 >= -15 + exprVar1 and exprVar1 <= 15 and In_1 >= 1 and 8e0 <= exprVar1 - In_1) } +[exprVar2, exprVar1] -> { : exprVar2 = 0 and exprVar1 <= 15 } +[exprVar2, exprVar1] -> { [i0] -> separate[o0] : o0 >= 0; [i0] -> atomic[o0] : o0 <= -1 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/lefur00-0.c b/external/mit/isl/dist/test_inputs/codegen/omega/lefur00-0.c new file mode 100644 index 000000000000..559424437106 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/lefur00-0.c @@ -0,0 +1,5 @@ +for (int c0 = 0; c0 <= 15; c0 += 1) + for (int c1 = max(2 * c0 - 15, c0 / 2); c1 <= min(15, c0 + 1); c1 += 1) + for (int c2 = max(max(max(1, 67 * c0 - (c0 + 1) / 3), 67 * c1 - (c1 + 2) / 3), 133 * c0 - 67 * c1 + (c0 + c1 + 1) / 3 - 66); c2 <= min(min(1000, 100 * c0 + 99), 133 * c0 - 67 * c1 + (c0 + c1 + 2) / 3 + 132); c2 += 1) + for (int c3 = max(max(c2, 200 * c0 - c2), 100 * c1 + (c2 + 1) / 2); c3 <= min(min(2 * c2 + 1, 200 * c0 - c2 + 199), 100 * c1 + (c2 + 1) / 2 + 99); c3 += 1) + s0(c0, c1, c2, c3); diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/lefur00-0.in b/external/mit/isl/dist/test_inputs/codegen/omega/lefur00-0.in new file mode 100644 index 000000000000..cf99c811b7e6 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/lefur00-0.in @@ -0,0 +1,3 @@ +{ s0[In_1, In_2, In_3, In_4] -> [In_1, In_2, In_3, In_4] : In_3 >= 1 and In_4 >= In_3 and In_4 <= 1 + 2In_3 and In_3 <= 1000 and In_4 >= 200In_1 - In_3 and In_4 <= 199 + 200In_1 - In_3 and 2In_4 >= 200In_2 + In_3 and 2In_4 <= 199 + 200In_2 + In_3 } +{ : } +{ [i0, i1, i2, i3] -> atomic[o0] : o0 <= 2; [i0, i1, i2, i3] -> separate[o0] : o0 >= 3 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/lefur01-0.c b/external/mit/isl/dist/test_inputs/codegen/omega/lefur01-0.c new file mode 100644 index 000000000000..559424437106 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/lefur01-0.c @@ -0,0 +1,5 @@ +for (int c0 = 0; c0 <= 15; c0 += 1) + for (int c1 = max(2 * c0 - 15, c0 / 2); c1 <= min(15, c0 + 1); c1 += 1) + for (int c2 = max(max(max(1, 67 * c0 - (c0 + 1) / 3), 67 * c1 - (c1 + 2) / 3), 133 * c0 - 67 * c1 + (c0 + c1 + 1) / 3 - 66); c2 <= min(min(1000, 100 * c0 + 99), 133 * c0 - 67 * c1 + (c0 + c1 + 2) / 3 + 132); c2 += 1) + for (int c3 = max(max(c2, 200 * c0 - c2), 100 * c1 + (c2 + 1) / 2); c3 <= min(min(2 * c2 + 1, 200 * c0 - c2 + 199), 100 * c1 + (c2 + 1) / 2 + 99); c3 += 1) + s0(c0, c1, c2, c3); diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/lefur01-0.in b/external/mit/isl/dist/test_inputs/codegen/omega/lefur01-0.in new file mode 100644 index 000000000000..cf99c811b7e6 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/lefur01-0.in @@ -0,0 +1,3 @@ +{ s0[In_1, In_2, In_3, In_4] -> [In_1, In_2, In_3, In_4] : In_3 >= 1 and In_4 >= In_3 and In_4 <= 1 + 2In_3 and In_3 <= 1000 and In_4 >= 200In_1 - In_3 and In_4 <= 199 + 200In_1 - In_3 and 2In_4 >= 200In_2 + In_3 and 2In_4 <= 199 + 200In_2 + In_3 } +{ : } +{ [i0, i1, i2, i3] -> atomic[o0] : o0 <= 2; [i0, i1, i2, i3] -> separate[o0] : o0 >= 3 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/lefur01-1.c b/external/mit/isl/dist/test_inputs/codegen/omega/lefur01-1.c new file mode 100644 index 000000000000..559424437106 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/lefur01-1.c @@ -0,0 +1,5 @@ +for (int c0 = 0; c0 <= 15; c0 += 1) + for (int c1 = max(2 * c0 - 15, c0 / 2); c1 <= min(15, c0 + 1); c1 += 1) + for (int c2 = max(max(max(1, 67 * c0 - (c0 + 1) / 3), 67 * c1 - (c1 + 2) / 3), 133 * c0 - 67 * c1 + (c0 + c1 + 1) / 3 - 66); c2 <= min(min(1000, 100 * c0 + 99), 133 * c0 - 67 * c1 + (c0 + c1 + 2) / 3 + 132); c2 += 1) + for (int c3 = max(max(c2, 200 * c0 - c2), 100 * c1 + (c2 + 1) / 2); c3 <= min(min(2 * c2 + 1, 200 * c0 - c2 + 199), 100 * c1 + (c2 + 1) / 2 + 99); c3 += 1) + s0(c0, c1, c2, c3); diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/lefur01-1.in b/external/mit/isl/dist/test_inputs/codegen/omega/lefur01-1.in new file mode 100644 index 000000000000..bc9611db4696 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/lefur01-1.in @@ -0,0 +1,3 @@ +{ s0[In_1, In_2, In_3, In_4] -> [In_1, In_2, In_3, In_4] : In_3 >= 1 and In_4 >= In_3 and In_4 <= 1 + 2In_3 and In_3 <= 1000 and In_4 >= 200In_1 - In_3 and In_4 <= 199 + 200In_1 - In_3 and 2In_4 >= 200In_2 + In_3 and 2In_4 <= 199 + 200In_2 + In_3 } +{ : } +{ [i0, i1, i2, i3] -> atomic[o0] : o0 <= 1; [i0, i1, i2, i3] -> separate[o0] : o0 >= 2 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/lefur03-0.c b/external/mit/isl/dist/test_inputs/codegen/omega/lefur03-0.c new file mode 100644 index 000000000000..8b61d263af4c --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/lefur03-0.c @@ -0,0 +1,7 @@ +for (int c0 = 0; c0 <= 3; c0 += 1) + for (int c1 = max(0, 2 * c0 - 3); c1 <= min(3, c0 + 1); c1 += 1) + for (int c2 = c0; c2 <= min(min(3, 2 * c0 - c1 + 1), 3 * c1 + 2); c2 += 1) + for (int c3 = max(max(max(0, c1 - (-c1 + 3) / 3), c0 - (-c2 + 3) / 3), c2 + floord(3 * c1 - c2 - 1, 6)); c3 <= min(3, c0 + 1); c3 += 1) + for (int c4 = max(max(max(max(-200 * c1 + 400 * c3 - 199, 250 * c3 + 1), 667 * c0 - 333 * c1 - (c0 + c1 + 3) / 3 - 332), 333 * c1 + c1 / 3), 333 * c2 + (c2 + 1) / 3); c4 <= min(min(min(min(1000, 500 * c0 + 499), -200 * c1 + 400 * c3 + 400), 333 * c2 - (-c2 + 3) / 3 + 333), 333 * c3 - (-c3 + 3) / 3 + 334); c4 += 1) + for (int c5 = max(max(max(c4, 1000 * c0 - c4), 1000 * c3 - 2 * c4 + 2), 500 * c1 + (c4 + 1) / 2); c5 <= min(min(min(2 * c4 + 1, 1000 * c0 - c4 + 999), 1000 * c3 - 2 * c4 + 1001), 500 * c1 + (c4 + 1) / 2 + 499); c5 += 1) + s0(c0, c1, c2, c3, c4, c5); diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/lefur03-0.in b/external/mit/isl/dist/test_inputs/codegen/omega/lefur03-0.in new file mode 100644 index 000000000000..890f413e7431 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/lefur03-0.in @@ -0,0 +1,3 @@ +{ s0[In_1, In_2, In_3, In_4, In_5, In_6] -> [In_1, In_2, In_3, In_4, In_5, In_6] : In_6 >= In_5 and In_6 <= 1 + 2In_5 and In_5 <= 1000 and In_6 >= 1000In_1 - In_5 and In_6 <= 999 + 1000In_1 - In_5 and In_6 >= 2 + 1000In_4 - 2In_5 and In_6 <= 1001 + 1000In_4 - 2In_5 and In_4 >= 0 and 2In_6 >= 1000In_2 + In_5 and 2In_6 <= 999 + 1000In_2 + In_5 and 3In_5 >= -1 + 1000In_3 and 3In_5 <= 998 + 1000In_3 } +{ : } +{ [i0, i1, i2, i3, i4, i5] -> separate[o0] : o0 >= 5; [i0, i1, i2, i3, i4, i5] -> atomic[o0] : o0 <= 4 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/lefur04-0.c b/external/mit/isl/dist/test_inputs/codegen/omega/lefur04-0.c new file mode 100644 index 000000000000..d0046d928f4b --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/lefur04-0.c @@ -0,0 +1,8 @@ +for (int c0 = 0; c0 <= 3; c0 += 1) + for (int c1 = max(0, 2 * c0 - 3); c1 <= min(c0 + 1, -c0 + 6); c1 += 1) + for (int c2 = c0; c2 <= min(min(3, 2 * c0 - c1 + 1), 3 * c1 + 2); c2 += 1) + for (int c3 = max(max(max(0, c1 - (-c1 + 3) / 3), c0 - (-c2 + 3) / 3), c2 + floord(3 * c1 - c2 - 1, 6)); c3 <= min(3, c0 + 1); c3 += 1) + for (int c5 = max(max(max(max(0, 2 * c3 - 4), c1 - (-c1 + 3) / 3), c2 - (c2 + 3) / 3), c3 - (c3 + 3) / 3); c5 <= min(min(c1 + 1, c3), -c2 + 2 * c3 - (c2 + 3) / 3 + 2); c5 += 1) + for (int c6 = max(max(max(max(max(-200 * c1 + 400 * c3 - 199, 250 * c3 + 1), 1000 * c0 - 500 * c5 - 501), 667 * c0 - 333 * c1 - (c0 + c1 + 3) / 3 - 332), 333 * c1 + c1 / 3), 333 * c2 + (c2 + 1) / 3); c6 <= min(min(min(min(min(min(1000, 500 * c0 + 499), -200 * c1 + 400 * c3 + 400), 500 * c5 + 501), 1000 * c0 - 500 * c5 + 997), 333 * c2 - (-c2 + 3) / 3 + 333), 333 * c3 - (-c3 + 3) / 3 + 334); c6 += 1) + for (int c7 = max(max(max(max(500 * c5 + 2, c6), 1000 * c0 - c6), 1000 * c3 - 2 * c6 + 2), 500 * c1 + (c6 + 1) / 2); c7 <= min(min(min(min(500 * c5 + 501, 2 * c6 + 1), 1000 * c0 - c6 + 999), 1000 * c3 - 2 * c6 + 1001), 500 * c1 + (c6 + 1) / 2 + 499); c7 += 1) + s0(c0, c1, c2, c3, c2 / 3, c5, c6, c7); diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/lefur04-0.in b/external/mit/isl/dist/test_inputs/codegen/omega/lefur04-0.in new file mode 100644 index 000000000000..c50a0da4c510 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/lefur04-0.in @@ -0,0 +1,3 @@ +{ s0[In_1, In_2, In_3, In_4, In_5, In_6, In_7, In_8] -> [In_1, In_2, In_3, In_4, In_5, In_6, In_7, In_8] : In_7 >= 1000In_5 and In_8 >= In_7 and In_8 <= 501 + 500In_6 and In_8 <= 1 + 2In_7 and In_7 <= 999 + 1000In_5 and In_7 <= 1000 and In_8 >= 1000In_1 - In_7 and In_8 <= 999 + 1000In_1 - In_7 and 2In_8 >= 1000In_2 + In_7 and 2In_8 <= 999 + 1000In_2 + In_7 and 3In_7 >= -1 + 1000In_3 and 3In_7 <= 998 + 1000In_3 and In_8 >= 2 + 500In_6 and In_6 >= 0 and In_8 >= 2 + 1000In_4 - 2In_7 and In_8 <= 1001 + 1000In_4 - 2In_7 } +{ : } +{ [i0, i1, i2, i3, i4, i5, i6, i7] -> atomic[o0] : o0 <= 6; [i0, i1, i2, i3, i4, i5, i6, i7] -> separate[o0] : o0 >= 7 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/lift1-0.c b/external/mit/isl/dist/test_inputs/codegen/omega/lift1-0.c new file mode 100644 index 000000000000..f7b1ae9ae7b8 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/lift1-0.c @@ -0,0 +1,9 @@ +for (int c0 = 1; c0 <= 100; c0 += 1) + for (int c1 = 1; c1 <= 100; c1 += 1) + for (int c2 = 1; c2 <= 100; c2 += 1) + for (int c3 = 1; c3 <= 100; c3 += 1) + for (int c4 = 1; c4 <= 100; c4 += 1) { + s1(c0, c1, c2, c3, c4); + if (c0 <= 60) + s0(c0, c1, c2, c3, c4); + } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/lift1-0.in b/external/mit/isl/dist/test_inputs/codegen/omega/lift1-0.in new file mode 100644 index 000000000000..31ae11ad5334 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/lift1-0.in @@ -0,0 +1,3 @@ +{ s0[In_1, In_2, In_3, In_4, In_5] -> [In_1, In_2, In_3, In_4, In_5] : In_1 >= 1 and In_1 <= 60 and In_2 >= 1 and In_2 <= 100 and In_3 >= 1 and In_3 <= 100 and In_4 >= 1 and In_4 <= 100 and In_5 >= 1 and In_5 <= 100; s1[In_1, In_2, In_3, In_4, In_5] -> [In_1, In_2, In_3, In_4, In_5] : In_1 >= 1 and In_1 <= 100 and In_2 >= 1 and In_2 <= 100 and In_3 >= 1 and In_3 <= 100 and In_4 >= 1 and In_4 <= 100 and In_5 >= 1 and In_5 <= 100 } +{ : } +{ [i0, i1, i2, i3, i4] -> separate[o0] : o0 >= 5; [i0, i1, i2, i3, i4] -> atomic[o0] : o0 <= 4 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/lift1-1.c b/external/mit/isl/dist/test_inputs/codegen/omega/lift1-1.c new file mode 100644 index 000000000000..b522fd9b4a57 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/lift1-1.c @@ -0,0 +1,14 @@ +for (int c0 = 1; c0 <= 100; c0 += 1) + for (int c1 = 1; c1 <= 100; c1 += 1) + for (int c2 = 1; c2 <= 100; c2 += 1) + for (int c3 = 1; c3 <= 100; c3 += 1) { + if (c0 >= 61) { + for (int c4 = 1; c4 <= 100; c4 += 1) + s1(c0, c1, c2, c3, c4); + } else { + for (int c4 = 1; c4 <= 100; c4 += 1) { + s1(c0, c1, c2, c3, c4); + s0(c0, c1, c2, c3, c4); + } + } + } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/lift1-1.in b/external/mit/isl/dist/test_inputs/codegen/omega/lift1-1.in new file mode 100644 index 000000000000..44de4acbb94d --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/lift1-1.in @@ -0,0 +1,3 @@ +{ s0[In_1, In_2, In_3, In_4, In_5] -> [In_1, In_2, In_3, In_4, In_5] : In_1 >= 1 and In_1 <= 60 and In_2 >= 1 and In_2 <= 100 and In_3 >= 1 and In_3 <= 100 and In_4 >= 1 and In_4 <= 100 and In_5 >= 1 and In_5 <= 100; s1[In_1, In_2, In_3, In_4, In_5] -> [In_1, In_2, In_3, In_4, In_5] : In_1 >= 1 and In_1 <= 100 and In_2 >= 1 and In_2 <= 100 and In_3 >= 1 and In_3 <= 100 and In_4 >= 1 and In_4 <= 100 and In_5 >= 1 and In_5 <= 100 } +{ : } +{ [i0, i1, i2, i3, i4] -> separate[o0] : o0 >= 4; [i0, i1, i2, i3, i4] -> atomic[o0] : o0 <= 3 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/lift1-2.c b/external/mit/isl/dist/test_inputs/codegen/omega/lift1-2.c new file mode 100644 index 000000000000..00e7b16697f1 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/lift1-2.c @@ -0,0 +1,15 @@ +for (int c0 = 1; c0 <= 100; c0 += 1) + for (int c1 = 1; c1 <= 100; c1 += 1) + for (int c2 = 1; c2 <= 100; c2 += 1) { + if (c0 >= 61) { + for (int c3 = 1; c3 <= 100; c3 += 1) + for (int c4 = 1; c4 <= 100; c4 += 1) + s1(c0, c1, c2, c3, c4); + } else { + for (int c3 = 1; c3 <= 100; c3 += 1) + for (int c4 = 1; c4 <= 100; c4 += 1) { + s1(c0, c1, c2, c3, c4); + s0(c0, c1, c2, c3, c4); + } + } + } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/lift1-2.in b/external/mit/isl/dist/test_inputs/codegen/omega/lift1-2.in new file mode 100644 index 000000000000..241fbb96293e --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/lift1-2.in @@ -0,0 +1,3 @@ +{ s0[In_1, In_2, In_3, In_4, In_5] -> [In_1, In_2, In_3, In_4, In_5] : In_1 >= 1 and In_1 <= 60 and In_2 >= 1 and In_2 <= 100 and In_3 >= 1 and In_3 <= 100 and In_4 >= 1 and In_4 <= 100 and In_5 >= 1 and In_5 <= 100; s1[In_1, In_2, In_3, In_4, In_5] -> [In_1, In_2, In_3, In_4, In_5] : In_1 >= 1 and In_1 <= 100 and In_2 >= 1 and In_2 <= 100 and In_3 >= 1 and In_3 <= 100 and In_4 >= 1 and In_4 <= 100 and In_5 >= 1 and In_5 <= 100 } +{ : } +{ [i0, i1, i2, i3, i4] -> separate[o0] : o0 >= 3; [i0, i1, i2, i3, i4] -> atomic[o0] : o0 <= 2 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/lift1-3.c b/external/mit/isl/dist/test_inputs/codegen/omega/lift1-3.c new file mode 100644 index 000000000000..6249150e66b7 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/lift1-3.c @@ -0,0 +1,16 @@ +for (int c0 = 1; c0 <= 100; c0 += 1) + for (int c1 = 1; c1 <= 100; c1 += 1) { + if (c0 >= 61) { + for (int c2 = 1; c2 <= 100; c2 += 1) + for (int c3 = 1; c3 <= 100; c3 += 1) + for (int c4 = 1; c4 <= 100; c4 += 1) + s1(c0, c1, c2, c3, c4); + } else { + for (int c2 = 1; c2 <= 100; c2 += 1) + for (int c3 = 1; c3 <= 100; c3 += 1) + for (int c4 = 1; c4 <= 100; c4 += 1) { + s1(c0, c1, c2, c3, c4); + s0(c0, c1, c2, c3, c4); + } + } + } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/lift1-3.in b/external/mit/isl/dist/test_inputs/codegen/omega/lift1-3.in new file mode 100644 index 000000000000..a50a9ece72cd --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/lift1-3.in @@ -0,0 +1,3 @@ +{ s0[In_1, In_2, In_3, In_4, In_5] -> [In_1, In_2, In_3, In_4, In_5] : In_1 >= 1 and In_1 <= 60 and In_2 >= 1 and In_2 <= 100 and In_3 >= 1 and In_3 <= 100 and In_4 >= 1 and In_4 <= 100 and In_5 >= 1 and In_5 <= 100; s1[In_1, In_2, In_3, In_4, In_5] -> [In_1, In_2, In_3, In_4, In_5] : In_1 >= 1 and In_1 <= 100 and In_2 >= 1 and In_2 <= 100 and In_3 >= 1 and In_3 <= 100 and In_4 >= 1 and In_4 <= 100 and In_5 >= 1 and In_5 <= 100 } +{ : } +{ [i0, i1, i2, i3, i4] -> separate[o0] : o0 >= 2; [i0, i1, i2, i3, i4] -> atomic[o0] : o0 <= 1 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/lift1-4.c b/external/mit/isl/dist/test_inputs/codegen/omega/lift1-4.c new file mode 100644 index 000000000000..b981ad873f8a --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/lift1-4.c @@ -0,0 +1,17 @@ +for (int c0 = 1; c0 <= 100; c0 += 1) { + if (c0 >= 61) { + for (int c1 = 1; c1 <= 100; c1 += 1) + for (int c2 = 1; c2 <= 100; c2 += 1) + for (int c3 = 1; c3 <= 100; c3 += 1) + for (int c4 = 1; c4 <= 100; c4 += 1) + s1(c0, c1, c2, c3, c4); + } else { + for (int c1 = 1; c1 <= 100; c1 += 1) + for (int c2 = 1; c2 <= 100; c2 += 1) + for (int c3 = 1; c3 <= 100; c3 += 1) + for (int c4 = 1; c4 <= 100; c4 += 1) { + s1(c0, c1, c2, c3, c4); + s0(c0, c1, c2, c3, c4); + } + } +} diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/lift1-4.in b/external/mit/isl/dist/test_inputs/codegen/omega/lift1-4.in new file mode 100644 index 000000000000..db7d85c8eed3 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/lift1-4.in @@ -0,0 +1,3 @@ +{ s0[In_1, In_2, In_3, In_4, In_5] -> [In_1, In_2, In_3, In_4, In_5] : In_1 >= 1 and In_1 <= 60 and In_2 >= 1 and In_2 <= 100 and In_3 >= 1 and In_3 <= 100 and In_4 >= 1 and In_4 <= 100 and In_5 >= 1 and In_5 <= 100; s1[In_1, In_2, In_3, In_4, In_5] -> [In_1, In_2, In_3, In_4, In_5] : In_1 >= 1 and In_1 <= 100 and In_2 >= 1 and In_2 <= 100 and In_3 >= 1 and In_3 <= 100 and In_4 >= 1 and In_4 <= 100 and In_5 >= 1 and In_5 <= 100 } +{ : } +{ [i0, i1, i2, i3, i4] -> separate[o0] : o0 >= 1; [i0, i1, i2, i3, i4] -> atomic[o0] : o0 <= 0 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/lift1-5.c b/external/mit/isl/dist/test_inputs/codegen/omega/lift1-5.c new file mode 100644 index 000000000000..9ef20eff8c22 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/lift1-5.c @@ -0,0 +1,14 @@ +for (int c0 = 1; c0 <= 60; c0 += 1) + for (int c1 = 1; c1 <= 100; c1 += 1) + for (int c2 = 1; c2 <= 100; c2 += 1) + for (int c3 = 1; c3 <= 100; c3 += 1) + for (int c4 = 1; c4 <= 100; c4 += 1) { + s1(c0, c1, c2, c3, c4); + s0(c0, c1, c2, c3, c4); + } +for (int c0 = 61; c0 <= 100; c0 += 1) + for (int c1 = 1; c1 <= 100; c1 += 1) + for (int c2 = 1; c2 <= 100; c2 += 1) + for (int c3 = 1; c3 <= 100; c3 += 1) + for (int c4 = 1; c4 <= 100; c4 += 1) + s1(c0, c1, c2, c3, c4); diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/lift1-5.in b/external/mit/isl/dist/test_inputs/codegen/omega/lift1-5.in new file mode 100644 index 000000000000..2f9d57865690 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/lift1-5.in @@ -0,0 +1,3 @@ +{ s0[In_1, In_2, In_3, In_4, In_5] -> [In_1, In_2, In_3, In_4, In_5] : In_1 >= 1 and In_1 <= 60 and In_2 >= 1 and In_2 <= 100 and In_3 >= 1 and In_3 <= 100 and In_4 >= 1 and In_4 <= 100 and In_5 >= 1 and In_5 <= 100; s1[In_1, In_2, In_3, In_4, In_5] -> [In_1, In_2, In_3, In_4, In_5] : In_1 >= 1 and In_1 <= 100 and In_2 >= 1 and In_2 <= 100 and In_3 >= 1 and In_3 <= 100 and In_4 >= 1 and In_4 <= 100 and In_5 >= 1 and In_5 <= 100 } +{ : } +{ [i0, i1, i2, i3, i4] -> separate[o0] : o0 >= 0; [i0, i1, i2, i3, i4] -> atomic[o0] : o0 <= -1 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/lift2-0.c b/external/mit/isl/dist/test_inputs/codegen/omega/lift2-0.c new file mode 100644 index 000000000000..181d6e58fc3c --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/lift2-0.c @@ -0,0 +1,9 @@ +for (int c0 = 1; c0 <= 100; c0 += 1) + for (int c1 = 1; c1 <= 100; c1 += 1) + for (int c2 = 1; c2 <= 100; c2 += 1) + for (int c3 = 1; c3 <= 100; c3 += 1) + for (int c4 = 1; c4 <= 100; c4 += 1) { + s1(c0, c1, c2, c3, c4); + if (c0 >= 5 && c0 <= 60) + s0(c0, c1, c2, c3, c4); + } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/lift2-0.in b/external/mit/isl/dist/test_inputs/codegen/omega/lift2-0.in new file mode 100644 index 000000000000..5df0444130ec --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/lift2-0.in @@ -0,0 +1,3 @@ +{ s0[In_1, In_2, In_3, In_4, In_5] -> [In_1, In_2, In_3, In_4, In_5] : In_1 >= 5 and In_1 <= 60 and In_2 >= 1 and In_2 <= 100 and In_3 >= 1 and In_3 <= 100 and In_4 >= 1 and In_4 <= 100 and In_5 >= 1 and In_5 <= 100; s1[In_1, In_2, In_3, In_4, In_5] -> [In_1, In_2, In_3, In_4, In_5] : In_1 >= 1 and In_1 <= 100 and In_2 >= 1 and In_2 <= 100 and In_3 >= 1 and In_3 <= 100 and In_4 >= 1 and In_4 <= 100 and In_5 >= 1 and In_5 <= 100 } +{ : } +{ [i0, i1, i2, i3, i4] -> separate[o0] : o0 >= 5; [i0, i1, i2, i3, i4] -> atomic[o0] : o0 <= 4 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/lift2-1.c b/external/mit/isl/dist/test_inputs/codegen/omega/lift2-1.c new file mode 100644 index 000000000000..625c7347b11b --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/lift2-1.c @@ -0,0 +1,17 @@ +for (int c0 = 1; c0 <= 100; c0 += 1) + for (int c1 = 1; c1 <= 100; c1 += 1) + for (int c2 = 1; c2 <= 100; c2 += 1) + for (int c3 = 1; c3 <= 100; c3 += 1) { + if (c0 >= 61) { + for (int c4 = 1; c4 <= 100; c4 += 1) + s1(c0, c1, c2, c3, c4); + } else if (c0 <= 4) { + for (int c4 = 1; c4 <= 100; c4 += 1) + s1(c0, c1, c2, c3, c4); + } else { + for (int c4 = 1; c4 <= 100; c4 += 1) { + s1(c0, c1, c2, c3, c4); + s0(c0, c1, c2, c3, c4); + } + } + } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/lift2-1.in b/external/mit/isl/dist/test_inputs/codegen/omega/lift2-1.in new file mode 100644 index 000000000000..7ef2a8d9a9e1 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/lift2-1.in @@ -0,0 +1,3 @@ +{ s0[In_1, In_2, In_3, In_4, In_5] -> [In_1, In_2, In_3, In_4, In_5] : In_1 >= 5 and In_1 <= 60 and In_2 >= 1 and In_2 <= 100 and In_3 >= 1 and In_3 <= 100 and In_4 >= 1 and In_4 <= 100 and In_5 >= 1 and In_5 <= 100; s1[In_1, In_2, In_3, In_4, In_5] -> [In_1, In_2, In_3, In_4, In_5] : In_1 >= 1 and In_1 <= 100 and In_2 >= 1 and In_2 <= 100 and In_3 >= 1 and In_3 <= 100 and In_4 >= 1 and In_4 <= 100 and In_5 >= 1 and In_5 <= 100 } +{ : } +{ [i0, i1, i2, i3, i4] -> separate[o0] : o0 >= 4; [i0, i1, i2, i3, i4] -> atomic[o0] : o0 <= 3 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/lift2-2.c b/external/mit/isl/dist/test_inputs/codegen/omega/lift2-2.c new file mode 100644 index 000000000000..63e897c7a357 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/lift2-2.c @@ -0,0 +1,19 @@ +for (int c0 = 1; c0 <= 100; c0 += 1) + for (int c1 = 1; c1 <= 100; c1 += 1) + for (int c2 = 1; c2 <= 100; c2 += 1) { + if (c0 >= 61) { + for (int c3 = 1; c3 <= 100; c3 += 1) + for (int c4 = 1; c4 <= 100; c4 += 1) + s1(c0, c1, c2, c3, c4); + } else if (c0 <= 4) { + for (int c3 = 1; c3 <= 100; c3 += 1) + for (int c4 = 1; c4 <= 100; c4 += 1) + s1(c0, c1, c2, c3, c4); + } else { + for (int c3 = 1; c3 <= 100; c3 += 1) + for (int c4 = 1; c4 <= 100; c4 += 1) { + s1(c0, c1, c2, c3, c4); + s0(c0, c1, c2, c3, c4); + } + } + } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/lift2-2.in b/external/mit/isl/dist/test_inputs/codegen/omega/lift2-2.in new file mode 100644 index 000000000000..3e9a97824601 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/lift2-2.in @@ -0,0 +1,3 @@ +{ s0[In_1, In_2, In_3, In_4, In_5] -> [In_1, In_2, In_3, In_4, In_5] : In_1 >= 5 and In_1 <= 60 and In_2 >= 1 and In_2 <= 100 and In_3 >= 1 and In_3 <= 100 and In_4 >= 1 and In_4 <= 100 and In_5 >= 1 and In_5 <= 100; s1[In_1, In_2, In_3, In_4, In_5] -> [In_1, In_2, In_3, In_4, In_5] : In_1 >= 1 and In_1 <= 100 and In_2 >= 1 and In_2 <= 100 and In_3 >= 1 and In_3 <= 100 and In_4 >= 1 and In_4 <= 100 and In_5 >= 1 and In_5 <= 100 } +{ : } +{ [i0, i1, i2, i3, i4] -> separate[o0] : o0 >= 3; [i0, i1, i2, i3, i4] -> atomic[o0] : o0 <= 2 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/lift2-3.c b/external/mit/isl/dist/test_inputs/codegen/omega/lift2-3.c new file mode 100644 index 000000000000..f87f1971b17a --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/lift2-3.c @@ -0,0 +1,21 @@ +for (int c0 = 1; c0 <= 100; c0 += 1) + for (int c1 = 1; c1 <= 100; c1 += 1) { + if (c0 >= 61) { + for (int c2 = 1; c2 <= 100; c2 += 1) + for (int c3 = 1; c3 <= 100; c3 += 1) + for (int c4 = 1; c4 <= 100; c4 += 1) + s1(c0, c1, c2, c3, c4); + } else if (c0 <= 4) { + for (int c2 = 1; c2 <= 100; c2 += 1) + for (int c3 = 1; c3 <= 100; c3 += 1) + for (int c4 = 1; c4 <= 100; c4 += 1) + s1(c0, c1, c2, c3, c4); + } else { + for (int c2 = 1; c2 <= 100; c2 += 1) + for (int c3 = 1; c3 <= 100; c3 += 1) + for (int c4 = 1; c4 <= 100; c4 += 1) { + s1(c0, c1, c2, c3, c4); + s0(c0, c1, c2, c3, c4); + } + } + } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/lift2-3.in b/external/mit/isl/dist/test_inputs/codegen/omega/lift2-3.in new file mode 100644 index 000000000000..0580f079dbc0 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/lift2-3.in @@ -0,0 +1,3 @@ +{ s0[In_1, In_2, In_3, In_4, In_5] -> [In_1, In_2, In_3, In_4, In_5] : In_1 >= 5 and In_1 <= 60 and In_2 >= 1 and In_2 <= 100 and In_3 >= 1 and In_3 <= 100 and In_4 >= 1 and In_4 <= 100 and In_5 >= 1 and In_5 <= 100; s1[In_1, In_2, In_3, In_4, In_5] -> [In_1, In_2, In_3, In_4, In_5] : In_1 >= 1 and In_1 <= 100 and In_2 >= 1 and In_2 <= 100 and In_3 >= 1 and In_3 <= 100 and In_4 >= 1 and In_4 <= 100 and In_5 >= 1 and In_5 <= 100 } +{ : } +{ [i0, i1, i2, i3, i4] -> separate[o0] : o0 >= 2; [i0, i1, i2, i3, i4] -> atomic[o0] : o0 <= 1 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/lift2-4.c b/external/mit/isl/dist/test_inputs/codegen/omega/lift2-4.c new file mode 100644 index 000000000000..65ae7ae0b14c --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/lift2-4.c @@ -0,0 +1,23 @@ +for (int c0 = 1; c0 <= 100; c0 += 1) { + if (c0 >= 61) { + for (int c1 = 1; c1 <= 100; c1 += 1) + for (int c2 = 1; c2 <= 100; c2 += 1) + for (int c3 = 1; c3 <= 100; c3 += 1) + for (int c4 = 1; c4 <= 100; c4 += 1) + s1(c0, c1, c2, c3, c4); + } else if (c0 <= 4) { + for (int c1 = 1; c1 <= 100; c1 += 1) + for (int c2 = 1; c2 <= 100; c2 += 1) + for (int c3 = 1; c3 <= 100; c3 += 1) + for (int c4 = 1; c4 <= 100; c4 += 1) + s1(c0, c1, c2, c3, c4); + } else { + for (int c1 = 1; c1 <= 100; c1 += 1) + for (int c2 = 1; c2 <= 100; c2 += 1) + for (int c3 = 1; c3 <= 100; c3 += 1) + for (int c4 = 1; c4 <= 100; c4 += 1) { + s1(c0, c1, c2, c3, c4); + s0(c0, c1, c2, c3, c4); + } + } +} diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/lift2-4.in b/external/mit/isl/dist/test_inputs/codegen/omega/lift2-4.in new file mode 100644 index 000000000000..d64462ae11bb --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/lift2-4.in @@ -0,0 +1,3 @@ +{ s0[In_1, In_2, In_3, In_4, In_5] -> [In_1, In_2, In_3, In_4, In_5] : In_1 >= 5 and In_1 <= 60 and In_2 >= 1 and In_2 <= 100 and In_3 >= 1 and In_3 <= 100 and In_4 >= 1 and In_4 <= 100 and In_5 >= 1 and In_5 <= 100; s1[In_1, In_2, In_3, In_4, In_5] -> [In_1, In_2, In_3, In_4, In_5] : In_1 >= 1 and In_1 <= 100 and In_2 >= 1 and In_2 <= 100 and In_3 >= 1 and In_3 <= 100 and In_4 >= 1 and In_4 <= 100 and In_5 >= 1 and In_5 <= 100 } +{ : } +{ [i0, i1, i2, i3, i4] -> separate[o0] : o0 >= 1; [i0, i1, i2, i3, i4] -> atomic[o0] : o0 <= 0 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/lift2-5.c b/external/mit/isl/dist/test_inputs/codegen/omega/lift2-5.c new file mode 100644 index 000000000000..3c10b8ad7785 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/lift2-5.c @@ -0,0 +1,20 @@ +for (int c0 = 1; c0 <= 4; c0 += 1) + for (int c1 = 1; c1 <= 100; c1 += 1) + for (int c2 = 1; c2 <= 100; c2 += 1) + for (int c3 = 1; c3 <= 100; c3 += 1) + for (int c4 = 1; c4 <= 100; c4 += 1) + s1(c0, c1, c2, c3, c4); +for (int c0 = 5; c0 <= 60; c0 += 1) + for (int c1 = 1; c1 <= 100; c1 += 1) + for (int c2 = 1; c2 <= 100; c2 += 1) + for (int c3 = 1; c3 <= 100; c3 += 1) + for (int c4 = 1; c4 <= 100; c4 += 1) { + s1(c0, c1, c2, c3, c4); + s0(c0, c1, c2, c3, c4); + } +for (int c0 = 61; c0 <= 100; c0 += 1) + for (int c1 = 1; c1 <= 100; c1 += 1) + for (int c2 = 1; c2 <= 100; c2 += 1) + for (int c3 = 1; c3 <= 100; c3 += 1) + for (int c4 = 1; c4 <= 100; c4 += 1) + s1(c0, c1, c2, c3, c4); diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/lift2-5.in b/external/mit/isl/dist/test_inputs/codegen/omega/lift2-5.in new file mode 100644 index 000000000000..37a57befecd1 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/lift2-5.in @@ -0,0 +1,3 @@ +{ s0[In_1, In_2, In_3, In_4, In_5] -> [In_1, In_2, In_3, In_4, In_5] : In_1 >= 5 and In_1 <= 60 and In_2 >= 1 and In_2 <= 100 and In_3 >= 1 and In_3 <= 100 and In_4 >= 1 and In_4 <= 100 and In_5 >= 1 and In_5 <= 100; s1[In_1, In_2, In_3, In_4, In_5] -> [In_1, In_2, In_3, In_4, In_5] : In_1 >= 1 and In_1 <= 100 and In_2 >= 1 and In_2 <= 100 and In_3 >= 1 and In_3 <= 100 and In_4 >= 1 and In_4 <= 100 and In_5 >= 1 and In_5 <= 100 } +{ : } +{ [i0, i1, i2, i3, i4] -> separate[o0] : o0 >= 0; [i0, i1, i2, i3, i4] -> atomic[o0] : o0 <= -1 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/lu-0.c b/external/mit/isl/dist/test_inputs/codegen/omega/lu-0.c new file mode 100644 index 000000000000..e71f47bbd58c --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/lu-0.c @@ -0,0 +1,10 @@ +for (int c0 = 1; c0 < n; c0 += 64) + for (int c1 = c0 - 1; c1 <= n; c1 += 64) + for (int c2 = c0; c2 <= n; c2 += 1) { + for (int c3 = c0; c3 <= min(min(c0 + 63, c1 + 62), c2 - 1); c3 += 1) + for (int c4 = max(c1, c3 + 1); c4 <= min(n, c1 + 63); c4 += 1) + s1(c3, c4, c2); + if (c0 + 63 >= c2) + for (int c4 = max(c1, c2 + 1); c4 <= min(n, c1 + 63); c4 += 1) + s0(c2, c4); + } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/lu-0.in b/external/mit/isl/dist/test_inputs/codegen/omega/lu-0.in new file mode 100644 index 000000000000..510d677c350e --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/lu-0.in @@ -0,0 +1,3 @@ +[n] -> { s1[k, i, j] -> [t1, t2, j, k, i] : exists (e0 = [(-1 + t1)/64], e1 = [(t2)/64]: 64e0 = -1 + t1 and 64e1 = t2 and t1 >= -63 + k and t1 <= k and t2 >= -63 + i and t2 <= i and i >= 1 + k and j >= 1 + k and k >= 1 and i <= n and j <= n); s0[k, i] -> [t1, t2, k, k, i] : exists (e0 = [(-1 + t1)/64], e1 = [(t2)/64]: 64e0 = -1 + t1 and 64e1 = t2 and t1 >= -63 + k and t1 <= k and t2 >= -63 + i and t2 <= i and k >= 1 and i >= 1 + k and i <= n) } +{ : } +[n] -> { [t1, t2, i2, i3, i4] -> separate[o0] : o0 >= 5; [t1, t2, i2, i3, i4] -> atomic[o0] : o0 <= 4 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/lu-1.c b/external/mit/isl/dist/test_inputs/codegen/omega/lu-1.c new file mode 100644 index 000000000000..e71f47bbd58c --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/lu-1.c @@ -0,0 +1,10 @@ +for (int c0 = 1; c0 < n; c0 += 64) + for (int c1 = c0 - 1; c1 <= n; c1 += 64) + for (int c2 = c0; c2 <= n; c2 += 1) { + for (int c3 = c0; c3 <= min(min(c0 + 63, c1 + 62), c2 - 1); c3 += 1) + for (int c4 = max(c1, c3 + 1); c4 <= min(n, c1 + 63); c4 += 1) + s1(c3, c4, c2); + if (c0 + 63 >= c2) + for (int c4 = max(c1, c2 + 1); c4 <= min(n, c1 + 63); c4 += 1) + s0(c2, c4); + } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/lu-1.in b/external/mit/isl/dist/test_inputs/codegen/omega/lu-1.in new file mode 100644 index 000000000000..2e8f7efa5359 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/lu-1.in @@ -0,0 +1,3 @@ +[n] -> { s1[k, i, j] -> [t1, t2, j, k, i] : exists (e0 = [(-1 + t1)/64], e1 = [(t2)/64]: 64e0 = -1 + t1 and 64e1 = t2 and t1 >= -63 + k and t1 <= k and t2 >= -63 + i and t2 <= i and i >= 1 + k and j >= 1 + k and k >= 1 and i <= n and j <= n); s0[k, i] -> [t1, t2, k, k, i] : exists (e0 = [(-1 + t1)/64], e1 = [(t2)/64]: 64e0 = -1 + t1 and 64e1 = t2 and t1 >= -63 + k and t1 <= k and t2 >= -63 + i and t2 <= i and k >= 1 and i >= 1 + k and i <= n) } +{ : } +[n] -> { [t1, t2, i2, i3, i4] -> separate[o0] : o0 >= 4; [t1, t2, i2, i3, i4] -> atomic[o0] : o0 <= 3 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/lu-2.c b/external/mit/isl/dist/test_inputs/codegen/omega/lu-2.c new file mode 100644 index 000000000000..e71f47bbd58c --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/lu-2.c @@ -0,0 +1,10 @@ +for (int c0 = 1; c0 < n; c0 += 64) + for (int c1 = c0 - 1; c1 <= n; c1 += 64) + for (int c2 = c0; c2 <= n; c2 += 1) { + for (int c3 = c0; c3 <= min(min(c0 + 63, c1 + 62), c2 - 1); c3 += 1) + for (int c4 = max(c1, c3 + 1); c4 <= min(n, c1 + 63); c4 += 1) + s1(c3, c4, c2); + if (c0 + 63 >= c2) + for (int c4 = max(c1, c2 + 1); c4 <= min(n, c1 + 63); c4 += 1) + s0(c2, c4); + } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/lu-2.in b/external/mit/isl/dist/test_inputs/codegen/omega/lu-2.in new file mode 100644 index 000000000000..ab2ec412b06e --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/lu-2.in @@ -0,0 +1,3 @@ +[n] -> { s1[k, i, j] -> [t1, t2, j, k, i] : exists (e0 = [(-1 + t1)/64], e1 = [(t2)/64]: 64e0 = -1 + t1 and 64e1 = t2 and t1 >= -63 + k and t1 <= k and t2 >= -63 + i and t2 <= i and i >= 1 + k and j >= 1 + k and k >= 1 and i <= n and j <= n); s0[k, i] -> [t1, t2, k, k, i] : exists (e0 = [(-1 + t1)/64], e1 = [(t2)/64]: 64e0 = -1 + t1 and 64e1 = t2 and t1 >= -63 + k and t1 <= k and t2 >= -63 + i and t2 <= i and k >= 1 and i >= 1 + k and i <= n) } +{ : } +[n] -> { [t1, t2, i2, i3, i4] -> separate[o0] : o0 >= 3; [t1, t2, i2, i3, i4] -> atomic[o0] : o0 <= 2 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/lu-3.c b/external/mit/isl/dist/test_inputs/codegen/omega/lu-3.c new file mode 100644 index 000000000000..3fd0d4eb5433 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/lu-3.c @@ -0,0 +1,14 @@ +for (int c0 = 1; c0 < n; c0 += 64) + for (int c1 = c0 - 1; c1 <= n; c1 += 64) { + for (int c2 = c0; c2 <= min(n, c0 + 63); c2 += 1) { + for (int c3 = c0; c3 <= min(c1 + 62, c2 - 1); c3 += 1) + for (int c4 = max(c1, c3 + 1); c4 <= min(n, c1 + 63); c4 += 1) + s1(c3, c4, c2); + for (int c4 = max(c1, c2 + 1); c4 <= min(n, c1 + 63); c4 += 1) + s0(c2, c4); + } + for (int c2 = c0 + 64; c2 <= n; c2 += 1) + for (int c3 = c0; c3 <= min(c0 + 63, c1 + 62); c3 += 1) + for (int c4 = max(c1, c3 + 1); c4 <= min(n, c1 + 63); c4 += 1) + s1(c3, c4, c2); + } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/lu-3.in b/external/mit/isl/dist/test_inputs/codegen/omega/lu-3.in new file mode 100644 index 000000000000..817db46120ad --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/lu-3.in @@ -0,0 +1,3 @@ +[n] -> { s1[k, i, j] -> [t1, t2, j, k, i] : exists (e0 = [(-1 + t1)/64], e1 = [(t2)/64]: 64e0 = -1 + t1 and 64e1 = t2 and t1 >= -63 + k and t1 <= k and t2 >= -63 + i and t2 <= i and i >= 1 + k and j >= 1 + k and k >= 1 and i <= n and j <= n); s0[k, i] -> [t1, t2, k, k, i] : exists (e0 = [(-1 + t1)/64], e1 = [(t2)/64]: 64e0 = -1 + t1 and 64e1 = t2 and t1 >= -63 + k and t1 <= k and t2 >= -63 + i and t2 <= i and k >= 1 and i >= 1 + k and i <= n) } +{ : } +[n] -> { [t1, t2, i2, i3, i4] -> separate[o0] : o0 >= 2; [t1, t2, i2, i3, i4] -> atomic[o0] : o0 <= 1 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/lu_ijk-0.c b/external/mit/isl/dist/test_inputs/codegen/omega/lu_ijk-0.c new file mode 100644 index 000000000000..da2571ac5300 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/lu_ijk-0.c @@ -0,0 +1,7 @@ +for (int c0 = 1; c0 <= n; c0 += 1) + for (int c1 = 2; c1 <= n; c1 += 1) { + for (int c3 = 1; c3 < min(c0, c1); c3 += 1) + s1(c3, c1, c0); + if (c1 >= c0 + 1) + s0(c0, c1); + } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/lu_ijk-0.in b/external/mit/isl/dist/test_inputs/codegen/omega/lu_ijk-0.in new file mode 100644 index 000000000000..5aae58cfb57d --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/lu_ijk-0.in @@ -0,0 +1,3 @@ +[n] -> { s0[k, j] -> [k, j, 1, 0] : k >= 1 and j >= 1 + k and j <= n; s1[k, j, i] -> [i, j, 0, k] : j >= 1 + k and i >= 1 + k and k >= 1 and j <= n and i <= n } +{ : } +[n] -> { [i0, i1, i2, i3] -> atomic[o0] : o0 <= 2; [i0, i1, i2, i3] -> separate[o0] : o0 >= 3 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/lu_ijk-1.c b/external/mit/isl/dist/test_inputs/codegen/omega/lu_ijk-1.c new file mode 100644 index 000000000000..da2571ac5300 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/lu_ijk-1.c @@ -0,0 +1,7 @@ +for (int c0 = 1; c0 <= n; c0 += 1) + for (int c1 = 2; c1 <= n; c1 += 1) { + for (int c3 = 1; c3 < min(c0, c1); c3 += 1) + s1(c3, c1, c0); + if (c1 >= c0 + 1) + s0(c0, c1); + } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/lu_ijk-1.in b/external/mit/isl/dist/test_inputs/codegen/omega/lu_ijk-1.in new file mode 100644 index 000000000000..06a860c43fe7 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/lu_ijk-1.in @@ -0,0 +1,3 @@ +[n] -> { s0[k, j] -> [k, j, 1, 0] : k >= 1 and j >= 1 + k and j <= n; s1[k, j, i] -> [i, j, 0, k] : j >= 1 + k and i >= 1 + k and k >= 1 and j <= n and i <= n } +{ : } +[n] -> { [i0, i1, i2, i3] -> atomic[o0] : o0 <= 1; [i0, i1, i2, i3] -> separate[o0] : o0 >= 2 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/lu_ijk-2.c b/external/mit/isl/dist/test_inputs/codegen/omega/lu_ijk-2.c new file mode 100644 index 000000000000..561ae1104b56 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/lu_ijk-2.c @@ -0,0 +1,11 @@ +if (n >= 2) + for (int c0 = 1; c0 <= n; c0 += 1) { + for (int c1 = 2; c1 <= c0; c1 += 1) + for (int c3 = 1; c3 < c1; c3 += 1) + s1(c3, c1, c0); + for (int c1 = c0 + 1; c1 <= n; c1 += 1) { + for (int c3 = 1; c3 < c0; c3 += 1) + s1(c3, c1, c0); + s0(c0, c1); + } + } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/lu_ijk-2.in b/external/mit/isl/dist/test_inputs/codegen/omega/lu_ijk-2.in new file mode 100644 index 000000000000..6ad8a4497e47 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/lu_ijk-2.in @@ -0,0 +1,3 @@ +[n] -> { s0[k, j] -> [k, j, 1, 0] : k >= 1 and j >= 1 + k and j <= n; s1[k, j, i] -> [i, j, 0, k] : j >= 1 + k and i >= 1 + k and k >= 1 and j <= n and i <= n } +{ : } +[n] -> { [i0, i1, i2, i3] -> atomic[o0] : o0 <= 0; [i0, i1, i2, i3] -> separate[o0] : o0 >= 1 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/lu_spmd-0.c b/external/mit/isl/dist/test_inputs/codegen/omega/lu_spmd-0.c new file mode 100644 index 000000000000..330945436c60 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/lu_spmd-0.c @@ -0,0 +1,13 @@ +if (ub >= lb) + for (int c0 = 1; c0 <= ub; c0 += 1) + for (int c1 = c0; c1 <= n; c1 += 1) { + if (c0 >= lb && c1 >= c0 + 1) { + s0(c0, c1); + if (n >= ub + 1) + s2(c0, c1); + } else if (lb >= c0 + 1) { + s3(c0, c1, lb, c0, c1); + } + for (int c3 = max(lb, c0); c3 <= ub; c3 += 1) + s1(c0, c1, c3); + } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/lu_spmd-0.in b/external/mit/isl/dist/test_inputs/codegen/omega/lu_spmd-0.in new file mode 100644 index 000000000000..0dd09538192d --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/lu_spmd-0.in @@ -0,0 +1,3 @@ +[n, lb, ub] -> { s1[k, i, j] -> [k, i, 1, j, 0, 0, 0, 0] : k >= 1 and j >= k and j <= n and j <= ub and i >= k and i <= n and j >= lb; s3[k, i, lb, k, i] -> [k, i, 1, lb, -1, k, i, 0] : k >= 1 and k <= -1 + lb and lb <= n and ub >= lb and i >= k and i <= n; s0[k, i] -> [k, i, 0, 0, 0, 0, 0, 0] : k >= 1 and k >= lb and i >= 1 + k and i <= n and k <= ub; s2[k, i] -> [k, i, 0, 0, 1, 0, 0, 0] : k >= 1 and k >= lb and k <= ub and ub <= -1 + n and i >= 1 + k and i <= n } +[lb, n, ub] -> { : ub <= n and lb >= 1 } +[n, lb, ub] -> { [i0, i1, i2, i3, i4, i5, i6, i7] -> atomic[o0] : o0 <= 7; [i0, i1, i2, i3, i4, i5, i6, i7] -> separate[o0] : o0 >= 8 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/lu_spmd-1.c b/external/mit/isl/dist/test_inputs/codegen/omega/lu_spmd-1.c new file mode 100644 index 000000000000..330945436c60 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/lu_spmd-1.c @@ -0,0 +1,13 @@ +if (ub >= lb) + for (int c0 = 1; c0 <= ub; c0 += 1) + for (int c1 = c0; c1 <= n; c1 += 1) { + if (c0 >= lb && c1 >= c0 + 1) { + s0(c0, c1); + if (n >= ub + 1) + s2(c0, c1); + } else if (lb >= c0 + 1) { + s3(c0, c1, lb, c0, c1); + } + for (int c3 = max(lb, c0); c3 <= ub; c3 += 1) + s1(c0, c1, c3); + } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/lu_spmd-1.in b/external/mit/isl/dist/test_inputs/codegen/omega/lu_spmd-1.in new file mode 100644 index 000000000000..5d628befe3e5 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/lu_spmd-1.in @@ -0,0 +1,3 @@ +[n, lb, ub] -> { s1[k, i, j] -> [k, i, 1, j, 0, 0, 0, 0] : k >= 1 and j >= k and j <= n and j <= ub and i >= k and i <= n and j >= lb; s3[k, i, lb, k, i] -> [k, i, 1, lb, -1, k, i, 0] : k >= 1 and k <= -1 + lb and lb <= n and ub >= lb and i >= k and i <= n; s0[k, i] -> [k, i, 0, 0, 0, 0, 0, 0] : k >= 1 and k >= lb and i >= 1 + k and i <= n and k <= ub; s2[k, i] -> [k, i, 0, 0, 1, 0, 0, 0] : k >= 1 and k >= lb and k <= ub and ub <= -1 + n and i >= 1 + k and i <= n } +[lb, n, ub] -> { : ub <= n and lb >= 1 } +[n, lb, ub] -> { [i0, i1, i2, i3, i4, i5, i6, i7] -> atomic[o0] : o0 <= 6; [i0, i1, i2, i3, i4, i5, i6, i7] -> separate[o0] : o0 >= 7 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/m1-0.c b/external/mit/isl/dist/test_inputs/codegen/omega/m1-0.c new file mode 100644 index 000000000000..bb149359f93e --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/m1-0.c @@ -0,0 +1,6 @@ +for (int c0 = 1; c0 <= 9; c0 += 1) + for (int c1 = 1; c1 <= 9; c1 += 1) { + s0(c0, c1); + if (c0 == 5) + s1(5, c1); + } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/m1-0.in b/external/mit/isl/dist/test_inputs/codegen/omega/m1-0.in new file mode 100644 index 000000000000..ca2b8a9b2c0a --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/m1-0.in @@ -0,0 +1,3 @@ +{ s0[i, j] -> [i, j, 0] : i >= 1 and i <= 9 and j >= 1 and j <= 9; s1[5, j] -> [5, j, 1] : j >= 1 and j <= 9 } +{ : } +{ [i0, i1, i2] -> separate[o0] : o0 >= 2; [i0, i1, i2] -> atomic[o0] : o0 <= 1 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/m1-1.c b/external/mit/isl/dist/test_inputs/codegen/omega/m1-1.c new file mode 100644 index 000000000000..580c5afa0c73 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/m1-1.c @@ -0,0 +1,14 @@ +for (int c0 = 1; c0 <= 9; c0 += 1) { + if (c0 >= 6) { + for (int c1 = 1; c1 <= 9; c1 += 1) + s0(c0, c1); + } else if (c0 <= 4) { + for (int c1 = 1; c1 <= 9; c1 += 1) + s0(c0, c1); + } else { + for (int c1 = 1; c1 <= 9; c1 += 1) { + s0(5, c1); + s1(5, c1); + } + } +} diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/m1-1.in b/external/mit/isl/dist/test_inputs/codegen/omega/m1-1.in new file mode 100644 index 000000000000..08dbf45ed10b --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/m1-1.in @@ -0,0 +1,3 @@ +{ s0[i, j] -> [i, j, 0] : i >= 1 and i <= 9 and j >= 1 and j <= 9; s1[5, j] -> [5, j, 1] : j >= 1 and j <= 9 } +{ : } +{ [i0, i1, i2] -> separate[o0] : o0 >= 1; [i0, i1, i2] -> atomic[o0] : o0 <= 0 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/m10-0.c b/external/mit/isl/dist/test_inputs/codegen/omega/m10-0.c new file mode 100644 index 000000000000..2b51c7b91060 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/m10-0.c @@ -0,0 +1,7 @@ +for (int c0 = 1; c0 <= 18; c0 += 1) + for (int c1 = 1; c1 <= 9; c1 += 1) { + if (c0 % 2 == 0) + s0(c1, c0 / 2); + if (c0 <= 9) + s1(c1, c0); + } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/m10-0.in b/external/mit/isl/dist/test_inputs/codegen/omega/m10-0.in new file mode 100644 index 000000000000..3046811e7434 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/m10-0.in @@ -0,0 +1,3 @@ +{ s0[i, j] -> [4j, i, 0] : i >= 1 and i <= 9 and j >= 1 and j <= 9; s1[i, j] -> [2j, i, 1] : i >= 1 and i <= 9 and j >= 1 and j <= 9 } +{ : } +{ [i0, i1, i2] -> separate[o0] : o0 >= 2; [i0, i1, i2] -> atomic[o0] : o0 <= 1 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/m10-1.c b/external/mit/isl/dist/test_inputs/codegen/omega/m10-1.c new file mode 100644 index 000000000000..227545710dd0 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/m10-1.c @@ -0,0 +1,15 @@ +for (int c0 = 1; c0 <= 18; c0 += 1) { + if (c0 >= 2 && c0 <= 9) { + for (int c1 = 1; c1 <= 9; c1 += 1) { + if (c0 % 2 == 0) + s0(c1, c0 / 2); + s1(c1, c0); + } + } else if (c0 == 1) { + for (int c1 = 1; c1 <= 9; c1 += 1) + s1(c1, 1); + } else if (c0 % 2 == 0) { + for (int c1 = 1; c1 <= 9; c1 += 1) + s0(c1, c0 / 2); + } +} diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/m10-1.in b/external/mit/isl/dist/test_inputs/codegen/omega/m10-1.in new file mode 100644 index 000000000000..81dfc3bbdea8 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/m10-1.in @@ -0,0 +1,3 @@ +{ s0[i, j] -> [4j, i, 0] : i >= 1 and i <= 9 and j >= 1 and j <= 9; s1[i, j] -> [2j, i, 1] : i >= 1 and i <= 9 and j >= 1 and j <= 9 } +{ : } +{ [i0, i1, i2] -> separate[o0] : o0 >= 1; [i0, i1, i2] -> atomic[o0] : o0 <= 0 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/m11-0.c b/external/mit/isl/dist/test_inputs/codegen/omega/m11-0.c new file mode 100644 index 000000000000..bf727b35395a --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/m11-0.c @@ -0,0 +1,6 @@ +for (int c0 = 1; c0 <= min(4, floord(2 * m - 1, 17) + 1); c0 += 1) + for (int c1 = 1; c1 <= min(2, -2 * c0 + (2 * m + 3 * c0 - 4) / 10 + 3); c1 += 1) + for (int c2 = 0; c2 <= min(2, -c0 - c1 + (2 * m + 3 * c0 + 10 * c1 + 6) / 20 + 1); c2 += 1) + for (int c3 = 8 * c0 + (c0 + 1) / 2 - 8; c3 <= min(min(30, m - 5 * c1 - 10 * c2 + 5), 8 * c0 + c0 / 2); c3 += 1) + for (int c4 = 5 * c1 + 10 * c2 - 4; c4 <= min(5 * c1 + 10 * c2, m - c3 + 1); c4 += 1) + s0(c0, c1, c2, c3, c4, -9 * c0 + c3 + c0 / 2 + 9, -5 * c1 - 5 * c2 + c4 + 5); diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/m11-0.in b/external/mit/isl/dist/test_inputs/codegen/omega/m11-0.in new file mode 100644 index 000000000000..d85fcf2734b4 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/m11-0.in @@ -0,0 +1,3 @@ +[m] -> { s0[In_1, In_2, In_3, In_4, In_5, In_6, 5 - 5In_2 - 5In_3 + In_5] -> [In_1, In_2, In_3, In_4, In_5, In_6, 5 - 5In_2 - 5In_3 + In_5] : In_2 >= 1 and 2In_3 >= 1 - In_2 and In_2 <= 2 and 2In_3 <= 6 - In_2 and In_4 <= 30 and In_1 >= 1 and 2In_6 <= 18 - 17In_1 + 2In_4 and 2In_6 >= 17 - 17In_1 + 2In_4 and In_5 <= 5In_2 + 10In_3 and In_5 >= -4 + 5In_2 + 10In_3 and 2In_4 <= 17In_1 and 2In_4 >= -16 + 17In_1 and In_5 <= 1 + m - In_4 } +{ : } +[m] -> { [i0, i1, i2, i3, i4, i5, i6] -> atomic[o0] : o0 <= 5; [i0, i1, i2, i3, i4, i5, i6] -> separate[o0] : o0 >= 6 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/m12-0.c b/external/mit/isl/dist/test_inputs/codegen/omega/m12-0.c new file mode 100644 index 000000000000..2dc6ab1fea6c --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/m12-0.c @@ -0,0 +1,3 @@ +for (int c1 = 1; c1 <= n; c1 += 1) + for (int c2 = 1; c2 <= m; c2 += 1) + s0(1, c1, c2, 0); diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/m12-0.in b/external/mit/isl/dist/test_inputs/codegen/omega/m12-0.in new file mode 100644 index 000000000000..0c988ab110c2 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/m12-0.in @@ -0,0 +1,3 @@ +[m, n] -> { s0[1, In_2, In_3, 0] -> [1, In_2, In_3, 0] : In_3 >= 1 and In_3 <= m and In_2 >= 1 and In_2 <= n } +{ : } +[m, n] -> { [i0, i1, i2, i3] -> separate[o0] : o0 >= 3; [i0, i1, i2, i3] -> atomic[o0] : o0 <= 2 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/m12-1.c b/external/mit/isl/dist/test_inputs/codegen/omega/m12-1.c new file mode 100644 index 000000000000..ca1821f2a80d --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/m12-1.c @@ -0,0 +1,23 @@ +for (int c1 = 1; c1 <= n; c1 += 1) + for (int c2 = 1; c2 <= m; c2 += 1) { + s0(1, c1, c2, 0); + s1(1, c1, c2, 0); + } +for (int c1 = 1; c1 <= n; c1 += 1) { + s2(2, c1, 0, 0); + s3(2, c1, 0, 0); +} +for (int c1 = 1; c1 <= m; c1 += 1) { + for (int c3 = 1; c3 <= n; c3 += 1) { + s4(3, c1, 1, c3); + s5(3, c1, 1, c3); + } + for (int c3 = 1; c3 <= n; c3 += 1) { + s6(3, c1, 2, c3); + s7(3, c1, 2, c3); + } +} +for (int c1 = 1; c1 <= m; c1 += 1) { + s8(4, c1, 0, 0); + s9(4, c1, 0, 0); +} diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/m12-1.in b/external/mit/isl/dist/test_inputs/codegen/omega/m12-1.in new file mode 100644 index 000000000000..355075faf683 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/m12-1.in @@ -0,0 +1,3 @@ +[m, n] -> { s1[1, In_2, In_3, 0] -> [1, In_2, In_3, 0] : In_3 >= 1 and In_3 <= m and In_2 >= 1 and In_2 <= n; s2[2, In_2, 0, 0] -> [2, In_2, 0, 0] : In_2 >= 1 and In_2 <= n; s3[2, In_2, 0, 0] -> [2, In_2, 0, 0] : In_2 >= 1 and In_2 <= n; s8[4, In_2, 0, 0] -> [4, In_2, 0, 0] : In_2 >= 1 and In_2 <= m; s0[1, In_2, In_3, 0] -> [1, In_2, In_3, 0] : In_3 >= 1 and In_3 <= m and In_2 >= 1 and In_2 <= n; s7[3, In_2, 2, In_4] -> [3, In_2, 2, In_4] : In_4 >= 1 and In_4 <= n and In_2 >= 1 and In_2 <= m; s4[3, In_2, 1, In_4] -> [3, In_2, 1, In_4] : In_4 >= 1 and In_4 <= n and In_2 >= 1 and In_2 <= m; s6[3, In_2, 2, In_4] -> [3, In_2, 2, In_4] : In_4 >= 1 and In_4 <= n and In_2 >= 1 and In_2 <= m; s9[4, In_2, 0, 0] -> [4, In_2, 0, 0] : In_2 >= 1 and In_2 <= m; s5[3, In_2, 1, In_4] -> [3, In_2, 1, In_4] : In_4 >= 1 and In_4 <= n and In_2 >= 1 and In_2 <= m } +{ : } +[m, n] -> { [i0, i1, i2, i3] -> separate[o0] : o0 >= 3; [i0, i1, i2, i3] -> atomic[o0] : o0 <= 2 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/m2-0.c b/external/mit/isl/dist/test_inputs/codegen/omega/m2-0.c new file mode 100644 index 000000000000..08ee8dce6e66 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/m2-0.c @@ -0,0 +1,12 @@ +for (int c0 = 2; c0 <= 9; c0 += 1) { + if (c0 >= 5) { + s1(c0, 1); + for (int c1 = 2; c1 <= 9; c1 += 1) { + s1(c0, c1); + s0(c0, c1); + } + } else { + for (int c1 = 2; c1 <= 9; c1 += 1) + s0(c0, c1); + } +} diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/m2-0.in b/external/mit/isl/dist/test_inputs/codegen/omega/m2-0.in new file mode 100644 index 000000000000..ae7780e04036 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/m2-0.in @@ -0,0 +1,3 @@ +{ s1[In_1, In_2] -> [In_1, In_2] : In_1 >= 5 and In_1 <= 9 and In_2 >= 1 and In_2 <= 9; s0[In_1, In_2] -> [In_1, In_2] : In_1 >= 2 and In_1 <= 9 and In_2 >= 2 and In_2 <= 9 } +{ : } +{ [i0, i1] -> atomic[o0] : o0 <= 0; [i0, i1] -> separate[o0] : o0 >= 1 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/m2-1.c b/external/mit/isl/dist/test_inputs/codegen/omega/m2-1.c new file mode 100644 index 000000000000..b7468358cf91 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/m2-1.c @@ -0,0 +1,10 @@ +for (int c0 = 2; c0 <= 4; c0 += 1) + for (int c1 = 2; c1 <= 9; c1 += 1) + s0(c0, c1); +for (int c0 = 5; c0 <= 9; c0 += 1) { + s1(c0, 1); + for (int c1 = 2; c1 <= 9; c1 += 1) { + s1(c0, c1); + s0(c0, c1); + } +} diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/m2-1.in b/external/mit/isl/dist/test_inputs/codegen/omega/m2-1.in new file mode 100644 index 000000000000..32302bb11e68 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/m2-1.in @@ -0,0 +1,3 @@ +{ s1[In_1, In_2] -> [In_1, In_2] : In_1 >= 5 and In_1 <= 9 and In_2 >= 1 and In_2 <= 9; s0[In_1, In_2] -> [In_1, In_2] : In_1 >= 2 and In_1 <= 9 and In_2 >= 2 and In_2 <= 9 } +{ : } +{ [i0, i1] -> atomic[o0] : o0 <= -1; [i0, i1] -> separate[o0] : o0 >= 0 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/m3-0.c b/external/mit/isl/dist/test_inputs/codegen/omega/m3-0.c new file mode 100644 index 000000000000..d3d697041659 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/m3-0.c @@ -0,0 +1,3 @@ +for (int c0 = -9; c0 <= 9; c0 += 1) + for (int c1 = max(1, -c0 + 1); c1 <= min(10, -c0 + 10); c1 += 1) + s0(c0, c1); diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/m3-0.in b/external/mit/isl/dist/test_inputs/codegen/omega/m3-0.in new file mode 100644 index 000000000000..82e109311bc6 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/m3-0.in @@ -0,0 +1,3 @@ +{ s0[In_1, In_2] -> [In_1, In_2] : In_2 >= 1 - In_1 and In_2 >= 1 and In_2 <= 10 - In_1 and In_2 <= 10 } +{ : } +{ [i0, i1] -> atomic[o0] : o0 <= 0; [i0, i1] -> separate[o0] : o0 >= 1 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/m4-0.c b/external/mit/isl/dist/test_inputs/codegen/omega/m4-0.c new file mode 100644 index 000000000000..a5280732a465 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/m4-0.c @@ -0,0 +1,5 @@ +for (int c0 = 1; c0 <= 9; c0 += 1) + for (int c1 = 1; c1 <= 9; c1 += 1) { + s0(c1, c0); + s1(c1, c0); + } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/m4-0.in b/external/mit/isl/dist/test_inputs/codegen/omega/m4-0.in new file mode 100644 index 000000000000..b7912a306b68 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/m4-0.in @@ -0,0 +1,3 @@ +{ s0[i, j] -> [j, i, 0] : i >= 1 and i <= 9 and j >= 1 and j <= 9; s1[i, j] -> [j, i, 1] : i >= 1 and i <= 9 and j >= 1 and j <= 9 } +{ : } +{ [i0, i1, i2] -> separate[o0] : o0 >= 2; [i0, i1, i2] -> atomic[o0] : o0 <= 1 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/m4-1.c b/external/mit/isl/dist/test_inputs/codegen/omega/m4-1.c new file mode 100644 index 000000000000..a5280732a465 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/m4-1.c @@ -0,0 +1,5 @@ +for (int c0 = 1; c0 <= 9; c0 += 1) + for (int c1 = 1; c1 <= 9; c1 += 1) { + s0(c1, c0); + s1(c1, c0); + } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/m4-1.in b/external/mit/isl/dist/test_inputs/codegen/omega/m4-1.in new file mode 100644 index 000000000000..c9e17d93466d --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/m4-1.in @@ -0,0 +1,3 @@ +{ s0[i, j] -> [j, i, 0] : i >= 1 and i <= 9 and j >= 1 and j <= 9; s1[i, j] -> [j, i, 1] : i >= 1 and i <= 9 and j >= 1 and j <= 9 } +{ : } +{ [i0, i1, i2] -> separate[o0] : o0 >= 1; [i0, i1, i2] -> atomic[o0] : o0 <= 0 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/m7-0.c b/external/mit/isl/dist/test_inputs/codegen/omega/m7-0.c new file mode 100644 index 000000000000..d9f93d96fcda --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/m7-0.c @@ -0,0 +1,6 @@ +for (int c0 = 1; c0 <= 9; c0 += 1) + for (int c1 = 1; c1 <= 9; c1 += 1) { + s0(c1, c0); + if (c0 % 2 == 0) + s1(c1, c0); + } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/m7-0.in b/external/mit/isl/dist/test_inputs/codegen/omega/m7-0.in new file mode 100644 index 000000000000..45a185043bce --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/m7-0.in @@ -0,0 +1,3 @@ +{ s0[i, j] -> [j, i, 0] : i >= 1 and i <= 9 and j >= 1 and j <= 9; s1[i, j] -> [j, i, 1] : exists (e0 = [(j)/2]: 2e0 = j and i >= 1 and i <= 9 and j >= 2 and j <= 8) } +{ : } +{ [i0, i1, i2] -> separate[o0] : o0 >= 2; [i0, i1, i2] -> atomic[o0] : o0 <= 1 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/m7-1.c b/external/mit/isl/dist/test_inputs/codegen/omega/m7-1.c new file mode 100644 index 000000000000..d33abe9d46f7 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/m7-1.c @@ -0,0 +1,11 @@ +for (int c0 = 1; c0 <= 9; c0 += 1) { + if ((c0 + 1) % 2 == 0) { + for (int c1 = 1; c1 <= 9; c1 += 1) + s0(c1, c0); + } else { + for (int c1 = 1; c1 <= 9; c1 += 1) { + s0(c1, c0); + s1(c1, c0); + } + } +} diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/m7-1.in b/external/mit/isl/dist/test_inputs/codegen/omega/m7-1.in new file mode 100644 index 000000000000..f4b6f6ffce82 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/m7-1.in @@ -0,0 +1,3 @@ +{ s0[i, j] -> [j, i, 0] : i >= 1 and i <= 9 and j >= 1 and j <= 9; s1[i, j] -> [j, i, 1] : exists (e0 = [(j)/2]: 2e0 = j and i >= 1 and i <= 9 and j >= 2 and j <= 8) } +{ : } +{ [i0, i1, i2] -> separate[o0] : o0 >= 1; [i0, i1, i2] -> atomic[o0] : o0 <= 0 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/m8-0.c b/external/mit/isl/dist/test_inputs/codegen/omega/m8-0.c new file mode 100644 index 000000000000..9aaed9e96364 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/m8-0.c @@ -0,0 +1,6 @@ +for (int c0 = 2; c0 <= 8; c0 += 2) + for (int c1 = 1; c1 <= 9; c1 += 1) { + if (c0 % 4 == 0) + s0(c1, c0); + s1(c1, c0); + } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/m8-0.in b/external/mit/isl/dist/test_inputs/codegen/omega/m8-0.in new file mode 100644 index 000000000000..e9a0e39646b2 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/m8-0.in @@ -0,0 +1,3 @@ +{ s0[i, j] -> [j, i, 0] : exists (e0 = [(j)/4]: 4e0 = j and i >= 1 and i <= 9 and j >= 4 and j <= 8); s1[i, j] -> [j, i, 1] : exists (e0 = [(j)/2]: 2e0 = j and i >= 1 and i <= 9 and j >= 2 and j <= 8) } +{ : } +{ [i0, i1, i2] -> separate[o0] : o0 >= 2; [i0, i1, i2] -> atomic[o0] : o0 <= 1 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/m8-1.c b/external/mit/isl/dist/test_inputs/codegen/omega/m8-1.c new file mode 100644 index 000000000000..4f8a00f04280 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/m8-1.c @@ -0,0 +1,11 @@ +for (int c0 = 2; c0 <= 8; c0 += 2) { + if ((c0 + 2) % 4 == 0) { + for (int c1 = 1; c1 <= 9; c1 += 1) + s1(c1, c0); + } else { + for (int c1 = 1; c1 <= 9; c1 += 1) { + s0(c1, c0); + s1(c1, c0); + } + } +} diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/m8-1.in b/external/mit/isl/dist/test_inputs/codegen/omega/m8-1.in new file mode 100644 index 000000000000..80e57e499db5 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/m8-1.in @@ -0,0 +1,3 @@ +{ s0[i, j] -> [j, i, 0] : exists (e0 = [(j)/4]: 4e0 = j and i >= 1 and i <= 9 and j >= 4 and j <= 8); s1[i, j] -> [j, i, 1] : exists (e0 = [(j)/2]: 2e0 = j and i >= 1 and i <= 9 and j >= 2 and j <= 8) } +{ : } +{ [i0, i1, i2] -> separate[o0] : o0 >= 1; [i0, i1, i2] -> atomic[o0] : o0 <= 0 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/m9-0.c b/external/mit/isl/dist/test_inputs/codegen/omega/m9-0.c new file mode 100644 index 000000000000..a5280732a465 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/m9-0.c @@ -0,0 +1,5 @@ +for (int c0 = 1; c0 <= 9; c0 += 1) + for (int c1 = 1; c1 <= 9; c1 += 1) { + s0(c1, c0); + s1(c1, c0); + } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/m9-0.in b/external/mit/isl/dist/test_inputs/codegen/omega/m9-0.in new file mode 100644 index 000000000000..fc38bf2e486d --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/m9-0.in @@ -0,0 +1,3 @@ +{ s0[i, j] -> [2j, i, 0] : i >= 1 and i <= 9 and j >= 1 and j <= 9; s1[i, j] -> [2j, i, 1] : i >= 1 and i <= 9 and j >= 1 and j <= 9 } +{ : } +{ [i0, i1, i2] -> separate[o0] : o0 >= 2; [i0, i1, i2] -> atomic[o0] : o0 <= 1 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/m9-1.c b/external/mit/isl/dist/test_inputs/codegen/omega/m9-1.c new file mode 100644 index 000000000000..a5280732a465 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/m9-1.c @@ -0,0 +1,5 @@ +for (int c0 = 1; c0 <= 9; c0 += 1) + for (int c1 = 1; c1 <= 9; c1 += 1) { + s0(c1, c0); + s1(c1, c0); + } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/m9-1.in b/external/mit/isl/dist/test_inputs/codegen/omega/m9-1.in new file mode 100644 index 000000000000..398e3260abf1 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/m9-1.in @@ -0,0 +1,3 @@ +{ s0[i, j] -> [2j, i, 0] : i >= 1 and i <= 9 and j >= 1 and j <= 9; s1[i, j] -> [2j, i, 1] : i >= 1 and i <= 9 and j >= 1 and j <= 9 } +{ : } +{ [i0, i1, i2] -> separate[o0] : o0 >= 1; [i0, i1, i2] -> atomic[o0] : o0 <= 0 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/olda-0.c b/external/mit/isl/dist/test_inputs/codegen/omega/olda-0.c new file mode 100644 index 000000000000..b05f991ad1ff --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/olda-0.c @@ -0,0 +1,8 @@ +for (int c0 = 1; c0 <= morb; c0 += 1) + for (int c1 = 1; c1 <= np; c1 += 1) + for (int c2 = 1; c2 <= np; c2 += 1) { + if (c2 >= c1) + s0(c2, c1, c0); + if (c1 >= c2) + s1(c1, c2, c0); + } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/olda-0.in b/external/mit/isl/dist/test_inputs/codegen/omega/olda-0.in new file mode 100644 index 000000000000..88f86f558c5f --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/olda-0.in @@ -0,0 +1,3 @@ +[np, morb] -> { s0[mp, mq, mi] -> [mi, mq, mp, 0] : mq >= 1 and mq <= mp and mp <= np and mi >= 1 and mi <= morb; s1[mp, mq, mi] -> [mi, mp, mq, 1] : mq >= 1 and mq <= mp and mp <= np and mi >= 1 and mi <= morb } +{ : } +[np, morb] -> { [i0, i1, i2, i3] -> atomic[o0] : o0 <= 2; [i0, i1, i2, i3] -> separate[o0] : o0 >= 3 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/olda-1.c b/external/mit/isl/dist/test_inputs/codegen/omega/olda-1.c new file mode 100644 index 000000000000..4b3098068e43 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/olda-1.c @@ -0,0 +1,9 @@ +for (int c0 = 1; c0 <= morb; c0 += 1) + for (int c1 = 1; c1 <= np; c1 += 1) { + for (int c2 = 1; c2 < c1; c2 += 1) + s1(c1, c2, c0); + s0(c1, c1, c0); + s1(c1, c1, c0); + for (int c2 = c1 + 1; c2 <= np; c2 += 1) + s0(c2, c1, c0); + } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/olda-1.in b/external/mit/isl/dist/test_inputs/codegen/omega/olda-1.in new file mode 100644 index 000000000000..a3a387fbac48 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/olda-1.in @@ -0,0 +1,3 @@ +[np, morb] -> { s0[mp, mq, mi] -> [mi, mq, mp, 0] : mq >= 1 and mq <= mp and mp <= np and mi >= 1 and mi <= morb; s1[mp, mq, mi] -> [mi, mp, mq, 1] : mq >= 1 and mq <= mp and mp <= np and mi >= 1 and mi <= morb } +{ : } +[np, morb] -> { [i0, i1, i2, i3] -> atomic[o0] : o0 <= 1; [i0, i1, i2, i3] -> separate[o0] : o0 >= 2 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/p.delft-0.c b/external/mit/isl/dist/test_inputs/codegen/omega/p.delft-0.c new file mode 100644 index 000000000000..c676558941fb --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/p.delft-0.c @@ -0,0 +1,4 @@ +if (P2 >= 0 && P2 <= 3 && P1 == P2) + for (int c0 = 0; c0 <= min(2, -P2 + 4); c0 += 1) + for (int c2 = (-P2 - c0 + 6) % 3; c2 <= 3; c2 += 3) + s0(c0, c0, c2, c2); diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/p.delft-0.in b/external/mit/isl/dist/test_inputs/codegen/omega/p.delft-0.in new file mode 100644 index 000000000000..5b277a12d784 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/p.delft-0.in @@ -0,0 +1,3 @@ +[P2, P1] -> { s0[In_1, In_1, In_3, In_3] -> [In_1, In_1, In_3, In_3] : exists (e0 = [(-2P2 - 2In_1 + In_3)/3]: P1 = P2 and 3e0 = -2P2 - 2In_1 + In_3 and P2 >= 0 and P2 <= 3 and In_1 <= 4 - P2 and In_1 >= 0 and In_1 <= 2 and In_3 >= 0 and In_3 <= 3) } +{ : } +[P2, P1] -> { [i0, i1, i2, i3] -> separate[o0] : o0 >= 3; [i0, i1, i2, i3] -> atomic[o0] : o0 <= 2 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/p.delft2-0.c b/external/mit/isl/dist/test_inputs/codegen/omega/p.delft2-0.c new file mode 100644 index 000000000000..ab1bc728e03b --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/p.delft2-0.c @@ -0,0 +1,11 @@ +if (P1 >= 0 && P1 <= 3 && P2 >= 0 && P2 <= 3) + for (int c0 = P1 - 1; c0 <= 3; c0 += 1) + for (int c2 = 0; c2 <= 7; c2 += 1) + for (int c3 = 0; c3 <= 7; c3 += 1) + if (4 * P2 >= 2 * c3 + 9 * floord(4 * P2 - 2 * c3 - 1, 9) + 6) { + if (P1 >= 1 && c0 + 1 == P1 && 4 * P1 >= 2 * c2 + 9 * floord(4 * P1 - 2 * c2 - 1, 9) + 7) { + s0(P1 - 1, P2, c2, c3, ((-4 * P1 + 2 * c2 + 9) % 9) + 1, -4 * P2 + 2 * c3 - 9 * floord(-4 * P2 + 2 * c3, 9)); + } else if (P1 == 0 && c0 == 3 && c2 % 4 == 0) { + s0(3, P2, c2, c3, (-c2 / 4) + 3, -4 * P2 + 2 * c3 - 9 * floord(-4 * P2 + 2 * c3, 9)); + } + } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/p.delft2-0.in b/external/mit/isl/dist/test_inputs/codegen/omega/p.delft2-0.in new file mode 100644 index 000000000000..f44b9bfdaa9d --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/p.delft2-0.in @@ -0,0 +1,3 @@ +[P1, P2] -> { s0[In_1, P2, In_3, In_4, In_5, In_6] -> [In_1, P2, In_3, In_4, In_5, In_6] : (exists (e0 = [(8 + 4In_1 + 16In_3 + In_5)/9], e1 = [(12 - 4P1 + 9e0)/16], e2 = [(-2In_1 - 2In_3 + In_5)/3], e3 = [(-5P2 - 2In_4 + In_6)/9]: 3e2 = -2In_1 - 2In_3 + In_5 and 9e3 = -5P2 - 2In_4 + In_6 and P1 >= 0 and In_1 >= 1 + P1 and In_1 <= 3 and P2 >= 0 and P2 <= 3 and In_6 >= 0 and In_6 <= 3 and In_5 >= 0 and In_5 <= 3 and In_5 >= 1 - 4In_1 - 16In_3 and In_5 <= 126 - 4In_1 - 16In_3 and In_6 <= 126 - 4P2 - 16In_4 and 16e1 <= -4P1 + 9e0 and 2In_6 <= P2 + 4In_4 and 9e0 <= 3 + 4In_1 + 16In_3 + In_5 and 9e0 >= 4In_1 + 16In_3 + In_5 and 16e1 >= -3 - 4P1 + 9e0)) or (exists (e0 = [(8 + 4In_1 + 16In_3 + In_5)/9], e1 = [(12 - 4P1 + 9e0)/16], e2 = [(-2In_1 - 2In_3 + In_5)/3], e3 = [(-5P2 - 2In_4 + In_6)/9]: 3e2 = -2In_1 - 2In_3 + In_5 and 9e3 = -5P2 - 2In_4 + In_6 and In_1 >= 0 and In_1 <= -1 + P1 and P1 <= 3 and In_6 >= 0 and In_6 <= 3 and In_6 <= 1 + 2In_4 and P2 >= 0 and P2 <= 3 and In_5 >= 0 and In_5 <= 3 and In_5 >= 1 - 4In_1 - 16In_3 and In_5 <= 126 - 4In_1 - 16In_3 and In_6 <= 126 - 4P2 - 16In_4 and 16e1 <= -4P1 + 9e0 and 9e0 <= 3 + 4In_1 + 16In_3 + In_5 and 9e0 >= 4In_1 + 16In_3 + In_5 and 16e1 >= -3 - 4P1 + 9e0)) } +{ : } +[P1, P2] -> { [i0, i1, i2, i3, i4, i5] -> atomic[o0] : o0 <= 4; [i0, i1, i2, i3, i4, i5] -> separate[o0] : o0 >= 5 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/p6-0.c b/external/mit/isl/dist/test_inputs/codegen/omega/p6-0.c new file mode 100644 index 000000000000..1391c3160bf7 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/p6-0.c @@ -0,0 +1,6 @@ +for (int c0 = 5; c0 <= 8; c0 += 1) + s0(c0); +for (int c0 = 10; c0 <= 16; c0 += 2) + s0(c0); +for (int c0 = 20; c0 <= 25; c0 += 1) + s0(c0); diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/p6-0.in b/external/mit/isl/dist/test_inputs/codegen/omega/p6-0.in new file mode 100644 index 000000000000..025da3d30d62 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/p6-0.in @@ -0,0 +1,3 @@ +{ s0[In_1] -> [In_1] : (In_1 >= 5 and In_1 <= 8) or (exists (e0 = [(In_1)/2]: 2e0 = In_1 and In_1 >= 10 and In_1 <= 16)) or (In_1 >= 20 and In_1 <= 25) } +{ : } +{ [i0] -> separate[o0] : o0 >= 0; [i0] -> atomic[o0] : o0 <= -1 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/p6-1.c b/external/mit/isl/dist/test_inputs/codegen/omega/p6-1.c new file mode 100644 index 000000000000..d3d697041659 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/p6-1.c @@ -0,0 +1,3 @@ +for (int c0 = -9; c0 <= 9; c0 += 1) + for (int c1 = max(1, -c0 + 1); c1 <= min(10, -c0 + 10); c1 += 1) + s0(c0, c1); diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/p6-1.in b/external/mit/isl/dist/test_inputs/codegen/omega/p6-1.in new file mode 100644 index 000000000000..82e109311bc6 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/p6-1.in @@ -0,0 +1,3 @@ +{ s0[In_1, In_2] -> [In_1, In_2] : In_2 >= 1 - In_1 and In_2 >= 1 and In_2 <= 10 - In_1 and In_2 <= 10 } +{ : } +{ [i0, i1] -> atomic[o0] : o0 <= 0; [i0, i1] -> separate[o0] : o0 >= 1 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/stride1-0.c b/external/mit/isl/dist/test_inputs/codegen/omega/stride1-0.c new file mode 100644 index 000000000000..c65c2e39fbc5 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/stride1-0.c @@ -0,0 +1,2 @@ +for (int c0 = 3; c0 <= 9; c0 += 3) + s0(c0); diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/stride1-0.in b/external/mit/isl/dist/test_inputs/codegen/omega/stride1-0.in new file mode 100644 index 000000000000..e09908713f1d --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/stride1-0.in @@ -0,0 +1,3 @@ +{ s0[In_1] -> [In_1] : exists (e0 = [(In_1)/3]: 3e0 = In_1 and In_1 >= 3 and In_1 <= 9) } +{ : } +{ [i0] -> separate[o0] : o0 >= 0; [i0] -> atomic[o0] : o0 <= -1 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/stride2-0.c b/external/mit/isl/dist/test_inputs/codegen/omega/stride2-0.c new file mode 100644 index 000000000000..0a7e8e7464dc --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/stride2-0.c @@ -0,0 +1,3 @@ +for (int c0 = 0; c0 <= n; c0 += 32) + for (int c1 = c0; c1 <= min(n, c0 + 31); c1 += 1) + s0(c0, c1); diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/stride2-0.in b/external/mit/isl/dist/test_inputs/codegen/omega/stride2-0.in new file mode 100644 index 000000000000..73dc13d60e45 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/stride2-0.in @@ -0,0 +1,3 @@ +[n] -> { s0[In_1, In_2] -> [In_1, In_2] : exists (e0 = [(In_1)/32]: 32e0 = In_1 and In_2 <= 31 + In_1 and In_1 >= 0 and In_2 >= In_1 and In_2 <= n) } +{ : } +[n] -> { [i0, i1] -> atomic[o0] : o0 <= 0; [i0, i1] -> separate[o0] : o0 >= 1 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/stride3-0.c b/external/mit/isl/dist/test_inputs/codegen/omega/stride3-0.c new file mode 100644 index 000000000000..8913c802cc02 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/stride3-0.c @@ -0,0 +1,3 @@ +for (int c0 = 3; c0 <= n; c0 += 32) + for (int c1 = c0; c1 <= min(n, c0 + 31); c1 += 1) + s0(c0, c1); diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/stride3-0.in b/external/mit/isl/dist/test_inputs/codegen/omega/stride3-0.in new file mode 100644 index 000000000000..360d7d01de1d --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/stride3-0.in @@ -0,0 +1,3 @@ +[n] -> { s0[In_1, In_2] -> [In_1, In_2] : exists (e0 = [(-3 + In_1)/32]: 32e0 = -3 + In_1 and In_2 <= 31 + In_1 and In_1 >= 3 and In_2 >= In_1 and In_2 <= n) } +{ : } +[n] -> { [i0, i1] -> atomic[o0] : o0 <= 0; [i0, i1] -> separate[o0] : o0 >= 1 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/stride4-0.c b/external/mit/isl/dist/test_inputs/codegen/omega/stride4-0.c new file mode 100644 index 000000000000..ed62b592ee2e --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/stride4-0.c @@ -0,0 +1,2 @@ +for (int c0 = 18; c0 <= 98; c0 += 5) + s0(c0); diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/stride4-0.in b/external/mit/isl/dist/test_inputs/codegen/omega/stride4-0.in new file mode 100644 index 000000000000..8779c3ceffa0 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/stride4-0.in @@ -0,0 +1,3 @@ +{ s0[In_1] -> [In_1] : exists (e0 = [(-3 + In_1)/5]: 5e0 = -3 + In_1 and In_1 >= 18 and In_1 <= 98) } +{ : } +{ [i0] -> separate[o0] : o0 >= 0; [i0] -> atomic[o0] : o0 <= -1 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/stride5-0.c b/external/mit/isl/dist/test_inputs/codegen/omega/stride5-0.c new file mode 100644 index 000000000000..2eeeb5a7b546 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/stride5-0.c @@ -0,0 +1,3 @@ +for (int c0 = 2; c0 <= min(100, -2 * n + 400); c0 += 2) + for (int c1 = 2 * n + c0; c1 <= 400; c1 += 2) + s0(c0, c1); diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/stride5-0.in b/external/mit/isl/dist/test_inputs/codegen/omega/stride5-0.in new file mode 100644 index 000000000000..c26c5476b3c9 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/stride5-0.in @@ -0,0 +1,3 @@ +[n] -> { s0[In_1, In_2] -> [In_1, In_2] : exists (e0 = [(In_1)/2], e1 = [(In_2)/2]: 2e0 = In_1 and 2e1 = In_2 and In_1 >= 2 and In_1 <= 100 and In_2 <= 400 and In_2 >= 2n + In_1) } +{ : } +[n] -> { [i0, i1] -> atomic[o0] : o0 <= 0; [i0, i1] -> separate[o0] : o0 >= 1 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/stride6-0.c b/external/mit/isl/dist/test_inputs/codegen/omega/stride6-0.c new file mode 100644 index 000000000000..d6bd4d41368a --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/stride6-0.c @@ -0,0 +1,3 @@ +for (int c0 = 1; c0 <= 101; c0 += 1) + for (int c1 = (c0 % 2) + c0; c1 <= 400; c1 += 2) + s0(c0, c1); diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/stride6-0.in b/external/mit/isl/dist/test_inputs/codegen/omega/stride6-0.in new file mode 100644 index 000000000000..16fda7442494 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/stride6-0.in @@ -0,0 +1,3 @@ +{ s0[In_1, In_2] -> [In_1, In_2] : exists (e0 = [(In_2)/2]: 2e0 = In_2 and In_1 >= 1 and In_2 >= In_1 and In_2 <= 400 and In_1 <= 101) } +{ : } +{ [i0, i1] -> atomic[o0] : o0 <= 0; [i0, i1] -> separate[o0] : o0 >= 1 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/stride6-1.c b/external/mit/isl/dist/test_inputs/codegen/omega/stride6-1.c new file mode 100644 index 000000000000..070028f05046 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/stride6-1.c @@ -0,0 +1,3 @@ +for (int c0 = 2; c0 <= 100; c0 += 2) + for (int c1 = c0; c1 <= 400; c1 += 2) + s0(c0, c1); diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/stride6-1.in b/external/mit/isl/dist/test_inputs/codegen/omega/stride6-1.in new file mode 100644 index 000000000000..91eaab26a320 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/stride6-1.in @@ -0,0 +1,3 @@ +{ s0[In_1, In_2] -> [In_1, In_2] : exists (e0 = [(In_1)/2], e1 = [(In_2)/2]: 2e0 = In_1 and 2e1 = In_2 and In_1 >= 2 and In_2 >= In_1 and In_2 <= 400 and In_1 <= 100) } +{ : } +{ [i0, i1] -> atomic[o0] : o0 <= 0; [i0, i1] -> separate[o0] : o0 >= 1 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/stride6-2.c b/external/mit/isl/dist/test_inputs/codegen/omega/stride6-2.c new file mode 100644 index 000000000000..070028f05046 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/stride6-2.c @@ -0,0 +1,3 @@ +for (int c0 = 2; c0 <= 100; c0 += 2) + for (int c1 = c0; c1 <= 400; c1 += 2) + s0(c0, c1); diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/stride6-2.in b/external/mit/isl/dist/test_inputs/codegen/omega/stride6-2.in new file mode 100644 index 000000000000..91eaab26a320 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/stride6-2.in @@ -0,0 +1,3 @@ +{ s0[In_1, In_2] -> [In_1, In_2] : exists (e0 = [(In_1)/2], e1 = [(In_2)/2]: 2e0 = In_1 and 2e1 = In_2 and In_1 >= 2 and In_2 >= In_1 and In_2 <= 400 and In_1 <= 100) } +{ : } +{ [i0, i1] -> atomic[o0] : o0 <= 0; [i0, i1] -> separate[o0] : o0 >= 1 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/stride7-0.c b/external/mit/isl/dist/test_inputs/codegen/omega/stride7-0.c new file mode 100644 index 000000000000..a1f7a1805e7c --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/stride7-0.c @@ -0,0 +1,15 @@ +for (int c0 = 1; c0 <= 36; c0 += 1) { + if (c0 <= 3) { + for (int c1 = 1; c1 <= 9; c1 += 1) + s1(c1, c0); + } else if (c0 <= 9) { + for (int c1 = 1; c1 <= 9; c1 += 1) { + if (c0 % 4 == 0) + s0(c1, c0 / 4); + s1(c1, c0); + } + } else if (c0 % 4 == 0) { + for (int c1 = 1; c1 <= 9; c1 += 1) + s0(c1, c0 / 4); + } +} diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/stride7-0.in b/external/mit/isl/dist/test_inputs/codegen/omega/stride7-0.in new file mode 100644 index 000000000000..b84f2045fdec --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/stride7-0.in @@ -0,0 +1,3 @@ +{ s0[i, j] -> [4j, i, 0] : i >= 1 and i <= 9 and j >= 1 and j <= 9; s1[i, j] -> [j, i, 1] : i >= 1 and i <= 9 and j >= 1 and j <= 9 } +{ : } +{ [i0, i1, i2] -> separate[o0] : o0 >= 1; [i0, i1, i2] -> atomic[o0] : o0 <= 0 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/stride7-1.c b/external/mit/isl/dist/test_inputs/codegen/omega/stride7-1.c new file mode 100644 index 000000000000..b8379dfa49f4 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/stride7-1.c @@ -0,0 +1,12 @@ +for (int c0 = 1; c0 <= 3; c0 += 1) + for (int c1 = 1; c1 <= 9; c1 += 1) + s1(c1, c0); +for (int c0 = 4; c0 <= 9; c0 += 1) + for (int c1 = 1; c1 <= 9; c1 += 1) { + if (c0 % 4 == 0) + s0(c1, c0 / 4); + s1(c1, c0); + } +for (int c0 = 3; c0 <= 9; c0 += 1) + for (int c1 = 1; c1 <= 9; c1 += 1) + s0(c1, c0); diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/stride7-1.in b/external/mit/isl/dist/test_inputs/codegen/omega/stride7-1.in new file mode 100644 index 000000000000..3ec82b9c39a9 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/stride7-1.in @@ -0,0 +1,3 @@ +{ s0[i, j] -> [4j, i, 0] : i >= 1 and i <= 9 and j >= 1 and j <= 9; s1[i, j] -> [j, i, 1] : i >= 1 and i <= 9 and j >= 1 and j <= 9 } +{ : } +{ [i0, i1, i2] -> separate[o0] : o0 >= 0; [i0, i1, i2] -> atomic[o0] : o0 <= -1 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/substitution-0.c b/external/mit/isl/dist/test_inputs/codegen/omega/substitution-0.c new file mode 100644 index 000000000000..b12c07d37519 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/substitution-0.c @@ -0,0 +1,3 @@ +for (int c0 = 0; c0 <= 10; c0 += 1) + for (int c1 = max(2 * c0 - 4, c0); c1 <= min(2 * c0, c0 + 6); c1 += 1) + s0(2 * c0 - c1, -c0 + c1); diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/substitution-0.in b/external/mit/isl/dist/test_inputs/codegen/omega/substitution-0.in new file mode 100644 index 000000000000..f4af71649b67 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/substitution-0.in @@ -0,0 +1,3 @@ +{ s0[i, j] -> [i + j, i + 2j] : i >= 0 and i <= 4 and j >= 0 and j <= 6 } +{ : } +{ [i0, i1] -> atomic[o0] : o0 <= 0; [i0, i1] -> separate[o0] : o0 >= 1 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/substitution-1.c b/external/mit/isl/dist/test_inputs/codegen/omega/substitution-1.c new file mode 100644 index 000000000000..51ab952e273e --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/substitution-1.c @@ -0,0 +1,3 @@ +for (int c0 = 0; c0 <= 14; c0 += 1) + for (int c1 = max(2 * c0 - 12, -c0 + 3 * ((c0 + 1) / 2)); c1 <= min(2 * c0, c0 / 2 + 9); c1 += 3) + s0((2 * c0 - c1) / 3, (-c0 + 2 * c1) / 3); diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/substitution-1.in b/external/mit/isl/dist/test_inputs/codegen/omega/substitution-1.in new file mode 100644 index 000000000000..504b220fbef9 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/substitution-1.in @@ -0,0 +1,3 @@ +{ s0[i, j] -> [2i + j, i + 2j] : i >= 0 and i <= 4 and j >= 0 and j <= 6 } +{ : } +{ [i0, i1] -> atomic[o0] : o0 <= 0; [i0, i1] -> separate[o0] : o0 >= 1 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/substitution-2.c b/external/mit/isl/dist/test_inputs/codegen/omega/substitution-2.c new file mode 100644 index 000000000000..9748950ae529 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/substitution-2.c @@ -0,0 +1,2 @@ +for (int c0 = -3; c0 <= 96; c0 += 1) + s0(c0, c0 + 4); diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/substitution-2.in b/external/mit/isl/dist/test_inputs/codegen/omega/substitution-2.in new file mode 100644 index 000000000000..bc9af0c00630 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/substitution-2.in @@ -0,0 +1,3 @@ +{ s0[i, 4 + i] -> [i, 4 + i] : i >= -3 and i <= 96 } +{ : } +{ [i0, i1] -> atomic[o0] : o0 <= 0; [i0, i1] -> separate[o0] : o0 >= 1 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/substitution-3.c b/external/mit/isl/dist/test_inputs/codegen/omega/substitution-3.c new file mode 100644 index 000000000000..86c197f7a95c --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/substitution-3.c @@ -0,0 +1 @@ +s0(n + 19); diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/substitution-3.in b/external/mit/isl/dist/test_inputs/codegen/omega/substitution-3.in new file mode 100644 index 000000000000..ea1ac1ab9146 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/substitution-3.in @@ -0,0 +1,3 @@ +[n] -> { s0[19 + n] -> [19 + n] } +{ : } +[n] -> { [i0] -> separate[o0] : o0 >= 0; [i0] -> atomic[o0] : o0 <= -1 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/substitution-4.c b/external/mit/isl/dist/test_inputs/codegen/omega/substitution-4.c new file mode 100644 index 000000000000..27b3199c0c3d --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/substitution-4.c @@ -0,0 +1 @@ +s0(n + 1); diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/substitution-4.in b/external/mit/isl/dist/test_inputs/codegen/omega/substitution-4.in new file mode 100644 index 000000000000..ecb07cd85bd3 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/substitution-4.in @@ -0,0 +1,3 @@ +[n] -> { s0[i] -> [i] : exists (e0 = [(-1 - n + i)/18]: 18e0 = -1 - n + i and i <= 16 + n and i >= 1 + n) } +{ : } +[n] -> { [i0] -> separate[o0] : o0 >= 0; [i0] -> atomic[o0] : o0 <= -1 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/syr2k-0.c b/external/mit/isl/dist/test_inputs/codegen/omega/syr2k-0.c new file mode 100644 index 000000000000..bb3ef7fa252b --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/syr2k-0.c @@ -0,0 +1,4 @@ +for (int c0 = 1; c0 <= min(n, 2 * b - 1); c0 += 1) + for (int c1 = max(-n + 1, -b + 1); c1 <= min(b - c0, n - c0); c1 += 1) + for (int c2 = max(1, c0 + c1); c2 <= min(n, n + c1); c2 += 1) + s0(-c0 - c1 + c2 + 1, -c1 + c2, c2); diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/syr2k-0.in b/external/mit/isl/dist/test_inputs/codegen/omega/syr2k-0.in new file mode 100644 index 000000000000..28a7deb1f054 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/syr2k-0.in @@ -0,0 +1,3 @@ +[n, b] -> { s0[i, j, k] -> [1 - i + j, -j + k, k] : i >= 1 and j >= i and j <= n and k >= 1 and k <= n and k <= -1 + b + i and k >= 1 - b + j } +{ : } +[n, b] -> { [i0, i1, i2] -> separate[o0] : o0 >= 2; [i0, i1, i2] -> atomic[o0] : o0 <= 1 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/syr2k-1.c b/external/mit/isl/dist/test_inputs/codegen/omega/syr2k-1.c new file mode 100644 index 000000000000..22ec83ec7ee9 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/syr2k-1.c @@ -0,0 +1,4 @@ +for (int c0 = 1; c0 <= min(n, 2 * b - 1); c0 += 1) + for (int c1 = -b + 1; c1 <= b - c0; c1 += 1) + for (int c2 = max(1, c0 + c1); c2 <= min(n, n + c1); c2 += 1) + s0(-c0 - c1 + c2 + 1, -c1 + c2, c2); diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/syr2k-1.in b/external/mit/isl/dist/test_inputs/codegen/omega/syr2k-1.in new file mode 100644 index 000000000000..496aebe2e8f4 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/syr2k-1.in @@ -0,0 +1,3 @@ +[n, b] -> { s0[i, j, k] -> [1 - i + j, -j + k, k] : i >= 1 and j >= i and j <= n and k >= 1 and k <= n and k <= -1 + b + i and k >= 1 - b + j } +[b, n] -> { : b >= 1 and n >= b } +[n, b] -> { [i0, i1, i2] -> separate[o0] : o0 >= 2; [i0, i1, i2] -> atomic[o0] : o0 <= 1 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/syr2k-2.c b/external/mit/isl/dist/test_inputs/codegen/omega/syr2k-2.c new file mode 100644 index 000000000000..bb3ef7fa252b --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/syr2k-2.c @@ -0,0 +1,4 @@ +for (int c0 = 1; c0 <= min(n, 2 * b - 1); c0 += 1) + for (int c1 = max(-n + 1, -b + 1); c1 <= min(b - c0, n - c0); c1 += 1) + for (int c2 = max(1, c0 + c1); c2 <= min(n, n + c1); c2 += 1) + s0(-c0 - c1 + c2 + 1, -c1 + c2, c2); diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/syr2k-2.in b/external/mit/isl/dist/test_inputs/codegen/omega/syr2k-2.in new file mode 100644 index 000000000000..28a7deb1f054 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/syr2k-2.in @@ -0,0 +1,3 @@ +[n, b] -> { s0[i, j, k] -> [1 - i + j, -j + k, k] : i >= 1 and j >= i and j <= n and k >= 1 and k <= n and k <= -1 + b + i and k >= 1 - b + j } +{ : } +[n, b] -> { [i0, i1, i2] -> separate[o0] : o0 >= 2; [i0, i1, i2] -> atomic[o0] : o0 <= 1 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/syr2k-3.c b/external/mit/isl/dist/test_inputs/codegen/omega/syr2k-3.c new file mode 100644 index 000000000000..22ec83ec7ee9 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/syr2k-3.c @@ -0,0 +1,4 @@ +for (int c0 = 1; c0 <= min(n, 2 * b - 1); c0 += 1) + for (int c1 = -b + 1; c1 <= b - c0; c1 += 1) + for (int c2 = max(1, c0 + c1); c2 <= min(n, n + c1); c2 += 1) + s0(-c0 - c1 + c2 + 1, -c1 + c2, c2); diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/syr2k-3.in b/external/mit/isl/dist/test_inputs/codegen/omega/syr2k-3.in new file mode 100644 index 000000000000..496aebe2e8f4 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/syr2k-3.in @@ -0,0 +1,3 @@ +[n, b] -> { s0[i, j, k] -> [1 - i + j, -j + k, k] : i >= 1 and j >= i and j <= n and k >= 1 and k <= n and k <= -1 + b + i and k >= 1 - b + j } +[b, n] -> { : b >= 1 and n >= b } +[n, b] -> { [i0, i1, i2] -> separate[o0] : o0 >= 2; [i0, i1, i2] -> atomic[o0] : o0 <= 1 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/ts1d-check-sblock-0.c b/external/mit/isl/dist/test_inputs/codegen/omega/ts1d-check-sblock-0.c new file mode 100644 index 000000000000..42fc844d10b2 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/ts1d-check-sblock-0.c @@ -0,0 +1,13 @@ +for (int c1 = 0; c1 <= 1; c1 += 1) { + if (c1 == 1) { + s0(1, 1, 1, 0, 0); + s0(1, 1, 1, N - 1, 0); + } else { + for (int c3 = 0; c3 < N; c3 += 1) + s0(1, 0, 1, c3, 0); + } +} +for (int c1 = 0; c1 <= floord(T - 1, 1000); c1 += 1) + for (int c2 = 1000 * c1 + 1; c2 <= min(N + T - 3, N + 1000 * c1 + 997); c2 += 1) + for (int c3 = max(0, -N - 1000 * c1 + c2 + 2); c3 <= min(min(999, T - 1000 * c1 - 1), -1000 * c1 + c2 - 1); c3 += 1) + s1(2, 1000 * c1 + c3, 1, -1000 * c1 + c2 - c3, 1); diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/ts1d-check-sblock-0.in b/external/mit/isl/dist/test_inputs/codegen/omega/ts1d-check-sblock-0.in new file mode 100644 index 000000000000..b1f92ea71a76 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/ts1d-check-sblock-0.in @@ -0,0 +1,3 @@ +[T, N] -> { s1[2, t, 1, i, 1] -> [2, tb, t + i, t - 1000tb, 0] : 1000tb <= t and 1000tb >= -999 + t and i >= 1 and i <= -2 + N and t >= 0 and t <= -1 + T; s0[1, 0, 1, In_4, 0] -> [1, 0, 1, In_4, 0] : In_4 >= 0 and In_4 <= -1 + N; s0[1, 1, 1, 0, 0] -> [1, 1, 1, 0, 0]; s0[1, 1, 1, -1 + N, 0] -> [1, 1, 1, -1 + N, 0] } +[T, N] -> { : T >= 0 and N >= 4 } +[N] -> { [i0, i1, i2, i3, i4] -> separate[o0] : o0 >= 3; [i0, i1, i2, i3, i4] -> atomic[o0] : o0 <= 2 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/ts1d-check0-0.c b/external/mit/isl/dist/test_inputs/codegen/omega/ts1d-check0-0.c new file mode 100644 index 000000000000..29c72599ca2a --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/ts1d-check0-0.c @@ -0,0 +1,11 @@ +for (int c1 = 0; c1 < N; c1 += 1) + s0(1, c1, 1, 0, 0); +for (int c1 = 0; c1 <= floord(T - 1, 500); c1 += 1) + for (int c2 = 1000 * c1; c2 <= min(N + 2 * T - 3, N + 1000 * c1 + 997); c2 += 1) { + for (int c3 = max(0, -((N + c2) % 2) - N - 1000 * c1 + c2 + 2); c3 <= min(min(998, 2 * T - 1000 * c1 - 2), -1000 * c1 + c2 - 2); c3 += 2) { + s1(2, 1000 * c1 + c3, 0, -1000 * c1 + c2 - c3, 1); + s2(2, 1000 * c1 + c3 + 1, 0, -1000 * c1 + c2 - c3 - 1, 1); + } + if (2 * T >= c2 + 1 && 1000 * c1 + 999 >= c2) + s1(2, ((c2 + 1) % 2) + c2 - 1, 0, -((c2 + 1) % 2) + 1, 1); + } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/ts1d-check0-0.in b/external/mit/isl/dist/test_inputs/codegen/omega/ts1d-check0-0.in new file mode 100644 index 000000000000..ce585b0836ce --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/ts1d-check0-0.in @@ -0,0 +1,3 @@ +[T, N] -> { s1[2, t, 0, i, 1] -> [2, tb, t + i, t - 1000tb, 1] : exists (e0 = [(t - 1000tb)/2]: 2e0 = t - 1000tb and 1000tb <= t and 1000tb >= -999 + t and i >= 0 and i <= -1 + N and t >= 0 and t <= -2 + 2T); s0[1, In_2, 1, 0, 0] -> [1, In_2, 1, 0, 0] : In_2 >= 0 and In_2 <= -1 + N; s2[2, t, 0, i, 1] -> [2, tb, t + i, t - 1000tb, 1] : exists (e0 = [(-1 + t - 1000tb)/2]: 2e0 = -1 + t - 1000tb and 1000tb <= t and 1000tb >= -999 + t and i >= 1 and i <= -2 + N and t >= 1 and t <= -1 + 2T) } +[T, N] -> { : T >= 0 and N >= 4 } +[N] -> { [i0, i1, i2, i3, i4] -> separate[o0] : o0 >= 3; [i0, i1, i2, i3, i4] -> atomic[o0] : o0 <= 2 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/ts1d-mp-i_ts-m_b-0.c b/external/mit/isl/dist/test_inputs/codegen/omega/ts1d-mp-i_ts-m_b-0.c new file mode 100644 index 000000000000..b793bf565a80 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/ts1d-mp-i_ts-m_b-0.c @@ -0,0 +1,34 @@ +for (int c1 = -1; c1 < T; c1 += 1) + for (int c2 = 0; c2 < N; c2 += 1) { + if (c1 == -1) { + s0(1, -1, c2, 0, 0); + } else if (c2 == 0) { + s0(1, c1, 0, 0, 0); + } else if (c2 + 1 == N) { + s0(1, c1, N - 1, 0, 0); + } + } +for (int c1 = 0; c1 <= floord(T - 1, 500); c1 += 1) { + for (int c3 = -((c1 + 9) / 8) + 2; c3 <= floord(N - 500 * c1 - 3, 4000) + 1; c3 += 1) + for (int c4 = max(500 * c1 + 1, 1000 * c1 + 4000 * c3 - 3999); c4 <= min(min(N + T - 3, 1000 * c1 + 4000 * c3 - 3000), 2 * N - 4000 * c3 + 3995); c4 += 1) + for (int c5 = max(0, -N - 500 * c1 + c4 + 2); c5 <= min(min(T - 500 * c1 - 1, -500 * c1 + c4 - 1), -500 * c1 - 2000 * c3 + (c4 + 1) / 2 + 1999); c5 += 1) + s1(2, 500 * c1 + c5, 1, -500 * c1 + c4 - c5, 1); + for (int c3 = max(-((T + 4000) / 4000) + 2, -((c1 + 9) / 8) + 2); c3 <= floord(N - 500 * c1 - 3, 4000) + 1; c3 += 1) + for (int c4 = max(1000 * c1 + 4000 * c3 - 3999, -4000 * c3 + 4000); c4 <= min(min(2 * T + 4000 * c3 - 4000, 1000 * c1 + 4000 * c3 - 3000), 2 * N - 4000 * c3 + 3995); c4 += 1) + s2(2, -2000 * c3 + (c4 + 1) / 2 + 1999, 1, 2000 * c3 + c4 - (c4 + 1) / 2 - 1999, 1); + for (int c3 = -((c1 + 7) / 8) + 1; c3 <= min(floord(N + T - 1000 * c1 - 1004, 4000) + 1, floord(N - 500 * c1 - 504, 4000) + 1); c3 += 1) + for (int c4 = max(500 * c1 + 1, 1000 * c1 + 4000 * c3 - 2999); c4 <= min(min(N + T - 3, N + 500 * c1 + 497), 1000 * c1 + 4000 * c3); c4 += 1) + for (int c5 = max(0, -N - 500 * c1 + c4 + 2); c5 <= min(min(499, T - 500 * c1 - 1), -500 * c1 + c4 - 1); c5 += 1) + s3(2, 500 * c1 + c5, 1, -500 * c1 + c4 - c5, 1); + for (int c3 = max(-((T + 4000) / 4000) + 1, -((c1 + 9) / 8) + 1); c3 <= floord(N - 500 * c1 - 3, 4000); c3 += 1) + for (int c4 = max(-4000 * c3, 1000 * c1 + 4000 * c3 + 1); c4 <= min(min(2 * N - 4000 * c3 - 5, 2 * T + 4000 * c3), 1000 * c1 + 4000 * c3 + 1000); c4 += 1) + s4(2, -2000 * c3 + (c4 + 1) / 2 - 1, 1, 2000 * c3 + c4 - (c4 + 1) / 2 + 1, 1); + for (int c3 = -((c1 + 8) / 8) + 1; c3 <= min(floord(N + T - 1000 * c1 - 4, 4000), floord(N - 500 * c1 + 496, 4000)); c3 += 1) + for (int c4 = max(1000 * c1 + 4000 * c3 + 1, -4000 * c3 + 2); c4 <= min(min(min(N + T - 3, N + 500 * c1 + 497), 2 * T + 4000 * c3 - 2), 1000 * c1 + 4000 * c3 + 998); c4 += 1) + for (int c5 = max(-N - 500 * c1 + c4 + 2, -500 * c1 - 2000 * c3 + (c4 + 1) / 2); c5 <= min(min(499, T - 500 * c1 - 1), -500 * c1 + c4 - 1); c5 += 1) + s5(2, 500 * c1 + c5, 1, -500 * c1 + c4 - c5, 1); +} +if (T >= 1) + for (int c3 = -((T + 3998) / 4000) + 1; c3 <= floord(N - T - 2, 4000) + 1; c3 += 1) + for (int c4 = max(T, 2 * T + 4000 * c3 - 4001); c4 < min(N + T - 2, 2 * T + 4000 * c3 - 1); c4 += 1) + s6(2, T - 1, 1, -T + c4 + 1, 1); diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/ts1d-mp-i_ts-m_b-0.in b/external/mit/isl/dist/test_inputs/codegen/omega/ts1d-mp-i_ts-m_b-0.in new file mode 100644 index 000000000000..0f86a1c38b97 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/ts1d-mp-i_ts-m_b-0.in @@ -0,0 +1,3 @@ +[T, N] -> { s1[2, t, 1, i, 1] -> [2, tb, 1, proc, t + i, t - 500tb, 0] : 4000proc >= 3000 + t + i - 1000tb and 500tb <= t and 4000proc <= 3999 - t + i and i >= 1 and i <= -2 + N and t >= 0 and t <= -1 + T; s0[1, -1, c, 0, 0] -> [1, -1, c, 0, 0, 0, 0] : c >= 0 and c <= -1 + N; s0[1, b, 0, 0, 0] -> [1, b, 0, 0, 0, 0, 0] : b >= 0 and b <= -1 + T; s0[1, b, -1 + N, 0, 0] -> [1, b, -1 + N, 0, 0, 0, 0] : b >= 0 and b <= -1 + T; s6[2, -1 + T, 1, i, 1] -> [3, tb, 7, proc, -1 + T + i, -1 + T - 500tb, 0] : 500tb <= -1 + T and 500tb >= -500 + T and 4000proc >= 1 - T + i and 4000proc <= 4000 - T + i and i >= 1 and i <= -2 + N and T >= 1; s3[2, t, 1, i, 1] -> [2, tb, 3, proc, t + i, t - 500tb, 0] : 500tb <= t and 500tb >= -499 + t and 4000proc <= 2999 + t + i - 1000tb and 4000proc >= t + i - 1000tb and i >= 1 and i <= -2 + N and t >= 0 and t <= -1 + T; s2[2, t, 1, i, 1] -> [2, tb, 2, proc, t + i, t - 500tb, 0] : 500tb <= t and 500tb >= -499 + t and 4000proc <= 3999 - t + i and 4000proc >= 3998 - t + i and i >= 1 and i <= -2 + N and t >= 0 and t <= -1 + T; s4[2, t, 1, i, 1] -> [2, tb, 4, Out_4, t + i, t - 500tb, 0] : 500tb <= t and 500tb >= -499 + t and 4000Out_4 <= -1 - t + i and 4000Out_4 >= -2 - t + i and i >= 1 and i <= -2 + N and t >= 0 and t <= -1 + T; s5[2, t, 1, i, 1] -> [2, tb, 5, proc, t + i, t - 500tb, 0] : 500tb >= -499 + t and 4000proc <= -1 + t + i - 1000tb and 4000proc >= -t + i and i >= 1 and i <= -2 + N and t >= 0 and t <= -1 + T } +[T, N] -> { : T >= 0 and N >= 4 } +[N, T] -> { [i0, i1, i2, i3, i4, i5, i6] -> atomic[o0] : o0 <= 5; [i0, i1, i2, i3, i4, i5, i6] -> separate[o0] : o0 >= 6 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/ts1d-orig0-0.c b/external/mit/isl/dist/test_inputs/codegen/omega/ts1d-orig0-0.c new file mode 100644 index 000000000000..72e3b2edfa28 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/ts1d-orig0-0.c @@ -0,0 +1,8 @@ +for (int c1 = 0; c1 < N; c1 += 1) + s0(1, c1, 1, 0, 0); +for (int c1 = 0; c1 < T; c1 += 1) { + for (int c3 = 0; c3 < N; c3 += 1) + s1(2, c1, 0, c3, 1); + for (int c3 = 1; c3 < N - 1; c3 += 1) + s2(2, c1, 1, c3, 1); +} diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/ts1d-orig0-0.in b/external/mit/isl/dist/test_inputs/codegen/omega/ts1d-orig0-0.in new file mode 100644 index 000000000000..153ba7e9bfee --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/ts1d-orig0-0.in @@ -0,0 +1,3 @@ +[T, N] -> { s1[2, In_2, 0, In_4, 1] -> [2, In_2, 0, In_4, 1] : In_4 >= 0 and In_4 <= -1 + N and In_2 >= 0 and In_2 <= -1 + T; s0[1, In_2, 1, 0, 0] -> [1, In_2, 1, 0, 0] : In_2 >= 0 and In_2 <= -1 + N; s2[2, In_2, 1, In_4, 1] -> [2, In_2, 1, In_4, 1] : In_4 >= 1 and In_4 <= -2 + N and In_2 >= 0 and In_2 <= -1 + T } +[T, N] -> { : T >= 0 and N >= 4 } +[N] -> { [i0, i1, i2, i3, i4] -> separate[o0] : o0 >= 4; [i0, i1, i2, i3, i4] -> atomic[o0] : o0 <= 3 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/wak1-0.c b/external/mit/isl/dist/test_inputs/codegen/omega/wak1-0.c new file mode 100644 index 000000000000..49024c5f5dc4 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/wak1-0.c @@ -0,0 +1,25 @@ +for (int c0 = a1; c0 <= min(min(b1, a3 - 1), a2 - 1); c0 += 1) + s0(c0); +for (int c0 = a2; c0 <= min(a3 - 1, b2); c0 += 1) { + if (c0 >= a1 && b1 >= c0) + s0(c0); + s1(c0); +} +for (int c0 = max(max(a1, a2), b2 + 1); c0 <= min(b1, a3 - 1); c0 += 1) + s0(c0); +for (int c0 = a3; c0 <= b3; c0 += 1) { + if (c0 >= a1 && b1 >= c0) + s0(c0); + if (c0 >= a2 && b2 >= c0) + s1(c0); + s2(c0); +} +for (int c0 = max(max(a1, a3), b3 + 1); c0 <= min(b1, a2 - 1); c0 += 1) + s0(c0); +for (int c0 = max(max(a3, b3 + 1), a2); c0 <= b2; c0 += 1) { + if (c0 >= a1 && b1 >= c0) + s0(c0); + s1(c0); +} +for (int c0 = max(max(max(max(a1, a3), b3 + 1), a2), b2 + 1); c0 <= b1; c0 += 1) + s0(c0); diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/wak1-0.in b/external/mit/isl/dist/test_inputs/codegen/omega/wak1-0.in new file mode 100644 index 000000000000..4cf37cb3192e --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/wak1-0.in @@ -0,0 +1,3 @@ +[a3, b3, a2, b2, a1, b1] -> { s2[i] -> [i, 2] : i >= a3 and i <= b3; s0[i] -> [i, 0] : i >= a1 and i <= b1; s1[i] -> [i, 1] : i >= a2 and i <= b2 } +{ : } +[a1, b1] -> { [i0, i1] -> separate[o0] : o0 >= 2 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/wak1-1.c b/external/mit/isl/dist/test_inputs/codegen/omega/wak1-1.c new file mode 100644 index 000000000000..5ecd174f611d --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/wak1-1.c @@ -0,0 +1,53 @@ +for (int c0 = a2; c0 <= min(min(a1 - 1, a3 - 1), b2); c0 += 1) + s1(c0); +for (int c0 = a3; c0 <= min(min(a1 - 1, b3), a2 - 1); c0 += 1) + s2(c0); +for (int c0 = max(a3, a2); c0 <= min(min(a1 - 1, b3), b2); c0 += 1) { + s1(c0); + s2(c0); +} +for (int c0 = max(max(a3, b3 + 1), a2); c0 <= min(a1 - 1, b2); c0 += 1) + s1(c0); +for (int c0 = a1; c0 <= min(min(b1, a3 - 1), a2 - 1); c0 += 1) + s0(c0); +for (int c0 = max(a1, a2); c0 <= min(min(b1, a3 - 1), b2); c0 += 1) { + s0(c0); + s1(c0); +} +for (int c0 = max(a1, a3); c0 <= min(min(b1, b3), a2 - 1); c0 += 1) { + s0(c0); + s2(c0); +} +for (int c0 = max(max(a1, a3), b3 + 1); c0 <= min(b1, a2 - 1); c0 += 1) + s0(c0); +for (int c0 = max(max(a1, a3), a2); c0 <= min(min(b1, b3), b2); c0 += 1) { + s0(c0); + s1(c0); + s2(c0); +} +for (int c0 = max(max(max(a1, a3), b3 + 1), a2); c0 <= min(b1, b2); c0 += 1) { + s0(c0); + s1(c0); +} +for (int c0 = max(max(a1, a2), b2 + 1); c0 <= min(b1, a3 - 1); c0 += 1) + s0(c0); +for (int c0 = max(max(a3, a2), b2 + 1); c0 <= min(a1 - 1, b3); c0 += 1) + s2(c0); +for (int c0 = max(max(max(a1, a3), a2), b2 + 1); c0 <= min(b1, b3); c0 += 1) { + s0(c0); + s2(c0); +} +for (int c0 = max(max(max(max(a1, a3), b3 + 1), a2), b2 + 1); c0 <= b1; c0 += 1) + s0(c0); +for (int c0 = max(max(a1, b1 + 1), a2); c0 <= min(a3 - 1, b2); c0 += 1) + s1(c0); +for (int c0 = max(max(a1, b1 + 1), a3); c0 <= min(b3, a2 - 1); c0 += 1) + s2(c0); +for (int c0 = max(max(max(a1, b1 + 1), a3), a2); c0 <= min(b3, b2); c0 += 1) { + s1(c0); + s2(c0); +} +for (int c0 = max(max(max(max(a1, b1 + 1), a3), b3 + 1), a2); c0 <= b2; c0 += 1) + s1(c0); +for (int c0 = max(max(max(max(a1, b1 + 1), a3), a2), b2 + 1); c0 <= b3; c0 += 1) + s2(c0); diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/wak1-1.in b/external/mit/isl/dist/test_inputs/codegen/omega/wak1-1.in new file mode 100644 index 000000000000..75c96d498955 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/wak1-1.in @@ -0,0 +1,3 @@ +[a3, b3, a2, b2, a1, b1] -> { s2[i] -> [i, 2] : i >= a3 and i <= b3; s0[i] -> [i, 0] : i >= a1 and i <= b1; s1[i] -> [i, 1] : i >= a2 and i <= b2 } +{ : } +[a1, b1] -> { [i0, i1] -> separate[o0] : o0 >= 0 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/wak2-0.c b/external/mit/isl/dist/test_inputs/codegen/omega/wak2-0.c new file mode 100644 index 000000000000..96e9f194616e --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/wak2-0.c @@ -0,0 +1,25 @@ +if (c2 >= d2 + 1) { + for (int c0 = a1; c0 <= b1; c0 += 1) + for (int c1_0 = c1; c1_0 <= d1; c1_0 += 1) + s0(c0, c1_0); +} else { + for (int c0 = a1; c0 <= min(b1, a2 - 1); c0 += 1) + for (int c1_0 = c1; c1_0 <= d1; c1_0 += 1) + s0(c0, c1_0); + for (int c0 = a2; c0 <= b2; c0 += 1) { + if (c0 >= a1 && b1 >= c0) + for (int c1_0 = c1; c1_0 <= min(d1, c2 - 1); c1_0 += 1) + s0(c0, c1_0); + for (int c1_0 = c2; c1_0 <= d2; c1_0 += 1) { + if (c0 >= a1 && b1 >= c0 && c1_0 >= c1 && d1 >= c1_0) + s0(c0, c1_0); + s1(c0, c1_0); + } + if (c0 >= a1 && b1 >= c0) + for (int c1_0 = max(c1, d2 + 1); c1_0 <= d1; c1_0 += 1) + s0(c0, c1_0); + } + for (int c0 = max(max(a1, a2), b2 + 1); c0 <= b1; c0 += 1) + for (int c1_0 = c1; c1_0 <= d1; c1_0 += 1) + s0(c0, c1_0); +} diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/wak2-0.in b/external/mit/isl/dist/test_inputs/codegen/omega/wak2-0.in new file mode 100644 index 000000000000..da7a6953bf3a --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/wak2-0.in @@ -0,0 +1,3 @@ +[a2, b2, c2, d2, a1, b1, c1, d1] -> { s0[i, j] -> [i, j, 0] : i >= a1 and i <= b1 and j >= c1 and j <= d1; s1[i, j] -> [i, j, 1] : i >= a2 and i <= b2 and j >= c2 and j <= d2 } +{ : } +[a1, b1, c1, d1] -> { [i0, i1, i2] -> separate[o0] : o0 >= 2 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/wak2-1.c b/external/mit/isl/dist/test_inputs/codegen/omega/wak2-1.c new file mode 100644 index 000000000000..58c29711c002 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/wak2-1.c @@ -0,0 +1,34 @@ +if (c2 >= d2 + 1) { + for (int c0 = a1; c0 <= b1; c0 += 1) + for (int c1_0 = c1; c1_0 <= d1; c1_0 += 1) + s0(c0, c1_0); +} else { + for (int c0 = a1; c0 <= min(b1, a2 - 1); c0 += 1) + for (int c1_0 = c1; c1_0 <= d1; c1_0 += 1) + s0(c0, c1_0); + for (int c0 = a2; c0 <= b2; c0 += 1) { + if (a1 >= c0 + 1) { + for (int c1_0 = c2; c1_0 <= d2; c1_0 += 1) + s1(c0, c1_0); + } else if (c0 >= b1 + 1) { + for (int c1_0 = c2; c1_0 <= d2; c1_0 += 1) + s1(c0, c1_0); + } else { + for (int c1_0 = c2; c1_0 <= min(c1 - 1, d2); c1_0 += 1) + s1(c0, c1_0); + for (int c1_0 = c1; c1_0 <= min(d1, c2 - 1); c1_0 += 1) + s0(c0, c1_0); + for (int c1_0 = max(c1, c2); c1_0 <= min(d1, d2); c1_0 += 1) { + s0(c0, c1_0); + s1(c0, c1_0); + } + for (int c1_0 = max(max(c1, d1 + 1), c2); c1_0 <= d2; c1_0 += 1) + s1(c0, c1_0); + for (int c1_0 = max(c1, d2 + 1); c1_0 <= d1; c1_0 += 1) + s0(c0, c1_0); + } + } + for (int c0 = max(max(a1, a2), b2 + 1); c0 <= b1; c0 += 1) + for (int c1_0 = c1; c1_0 <= d1; c1_0 += 1) + s0(c0, c1_0); +} diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/wak2-1.in b/external/mit/isl/dist/test_inputs/codegen/omega/wak2-1.in new file mode 100644 index 000000000000..c92ac3c82c83 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/wak2-1.in @@ -0,0 +1,3 @@ +[a2, b2, c2, d2, a1, b1, c1, d1] -> { s0[i, j] -> [i, j, 0] : i >= a1 and i <= b1 and j >= c1 and j <= d1; s1[i, j] -> [i, j, 1] : i >= a2 and i <= b2 and j >= c2 and j <= d2 } +{ : } +[a1, b1, c1, d1] -> { [i0, i1, i2] -> separate[o0] : o0 >= 1 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/wak3-0.c b/external/mit/isl/dist/test_inputs/codegen/omega/wak3-0.c new file mode 100644 index 000000000000..06be04aae784 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/wak3-0.c @@ -0,0 +1,8 @@ +for (int c0 = a; c0 <= b + 20; c0 += 1) { + if (b >= c0) + s0(c0); + if (c0 >= a + 10 && b + 10 >= c0) + s1(c0); + if (c0 >= a + 20) + s2(c0); +} diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/wak3-0.in b/external/mit/isl/dist/test_inputs/codegen/omega/wak3-0.in new file mode 100644 index 000000000000..a4c4de9c88c6 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/wak3-0.in @@ -0,0 +1,3 @@ +[a, b] -> { s2[i] -> [i, 2] : i >= 20 + a and i <= 20 + b; s0[i] -> [i, 0] : i >= a and i <= b; s1[i] -> [i, 1] : i >= 10 + a and i <= 10 + b } +{ : } +[a, b] -> { [i0, i1] -> atomic[o0] : o0 <= 0; [i0, i1] -> separate[o0] : o0 >= 1 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/wak3-1.c b/external/mit/isl/dist/test_inputs/codegen/omega/wak3-1.c new file mode 100644 index 000000000000..ef2c580d4402 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/wak3-1.c @@ -0,0 +1,19 @@ +for (int c0 = a; c0 <= min(a + 9, b); c0 += 1) + s0(c0); +for (int c0 = a + 10; c0 <= min(a + 19, b); c0 += 1) { + s0(c0); + s1(c0); +} +for (int c0 = max(a + 10, b + 1); c0 <= min(a + 19, b + 10); c0 += 1) + s1(c0); +for (int c0 = a + 20; c0 <= b; c0 += 1) { + s0(c0); + s1(c0); + s2(c0); +} +for (int c0 = max(a + 20, b + 1); c0 <= b + 10; c0 += 1) { + s1(c0); + s2(c0); +} +for (int c0 = max(a + 20, b + 11); c0 <= b + 20; c0 += 1) + s2(c0); diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/wak3-1.in b/external/mit/isl/dist/test_inputs/codegen/omega/wak3-1.in new file mode 100644 index 000000000000..ae319e5ddebb --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/wak3-1.in @@ -0,0 +1,3 @@ +[a, b] -> { s2[i] -> [i, 2] : i >= 20 + a and i <= 20 + b; s0[i] -> [i, 0] : i >= a and i <= b; s1[i] -> [i, 1] : i >= 10 + a and i <= 10 + b } +{ : } +[a, b] -> { [i0, i1] -> atomic[o0] : o0 <= -1; [i0, i1] -> separate[o0] : o0 >= 0 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/wak4-0.c b/external/mit/isl/dist/test_inputs/codegen/omega/wak4-0.c new file mode 100644 index 000000000000..5cefe4be4d38 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/wak4-0.c @@ -0,0 +1,4 @@ +for (int c0 = max(max(max(max(a1, a2), a3), a4), a5); c0 <= min(min(min(min(b1, b2), b3), b4), b5); c0 += 1) { + s0(c0); + s1(c0); +} diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/wak4-0.in b/external/mit/isl/dist/test_inputs/codegen/omega/wak4-0.in new file mode 100644 index 000000000000..9862df214583 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/wak4-0.in @@ -0,0 +1,3 @@ +[a1, a2, a3, a4, a5, b1, b2, b3, b4, b5] -> { s0[i] -> [i, 0] : i >= a1 and i >= a2 and i >= a3 and i >= a4 and i >= a5 and i <= b1 and i <= b2 and i <= b3 and i <= b4 and i <= b5; s1[i] -> [i, 1] : i >= a1 and i >= a2 and i >= a3 and i >= a4 and i >= a5 and i <= b1 and i <= b2 and i <= b3 and i <= b4 and i <= b5 } +{ : } +[a1, a2, a3, a4, a5, b1, b2, b3, b4, b5] -> { [i0, i1] -> separate[o0] : o0 >= 1; [i0, i1] -> atomic[o0] : o0 <= 0 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/wak4-1.c b/external/mit/isl/dist/test_inputs/codegen/omega/wak4-1.c new file mode 100644 index 000000000000..5cefe4be4d38 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/wak4-1.c @@ -0,0 +1,4 @@ +for (int c0 = max(max(max(max(a1, a2), a3), a4), a5); c0 <= min(min(min(min(b1, b2), b3), b4), b5); c0 += 1) { + s0(c0); + s1(c0); +} diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/wak4-1.in b/external/mit/isl/dist/test_inputs/codegen/omega/wak4-1.in new file mode 100644 index 000000000000..076cdd1f48a9 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/wak4-1.in @@ -0,0 +1,3 @@ +[a1, a2, a3, a4, a5, b1, b2, b3, b4, b5] -> { s0[i] -> [i, 0] : i >= a1 and i >= a2 and i >= a3 and i >= a4 and i >= a5 and i <= b1 and i <= b2 and i <= b3 and i <= b4 and i <= b5; s1[i] -> [i, 1] : i >= a1 and i >= a2 and i >= a3 and i >= a4 and i >= a5 and i <= b1 and i <= b2 and i <= b3 and i <= b4 and i <= b5 } +{ : } +[a1, a2, a3, a4, a5, b1, b2, b3, b4, b5] -> { [i0, i1] -> separate[o0] : o0 >= 0; [i0, i1] -> atomic[o0] : o0 <= -1 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/x-0.c b/external/mit/isl/dist/test_inputs/codegen/omega/x-0.c new file mode 100644 index 000000000000..f890920d709a --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/x-0.c @@ -0,0 +1,14 @@ +for (int c0 = 1; c0 <= 11; c0 += 1) { + for (int c1 = max(1, c0 - 3); c1 <= min(c0, -c0 + 8); c1 += 1) + s1(c1, c0 - c1 + 1); + for (int c1 = max(1, -c0 + 9); c1 <= min(c0 - 4, -c0 + 12); c1 += 1) + s0(c1, c0 + c1 - 8); + for (int c1 = max(c0 - 3, -c0 + 9); c1 <= min(c0, -c0 + 12); c1 += 1) { + s0(c1, c0 + c1 - 8); + s1(c1, c0 - c1 + 1); + } + for (int c1 = max(c0 - 3, -c0 + 13); c1 <= min(8, c0); c1 += 1) + s1(c1, c0 - c1 + 1); + for (int c1 = max(c0 + 1, -c0 + 9); c1 <= min(8, -c0 + 12); c1 += 1) + s0(c1, c0 + c1 - 8); +} diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/x-0.in b/external/mit/isl/dist/test_inputs/codegen/omega/x-0.in new file mode 100644 index 000000000000..24340efe4d84 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/x-0.in @@ -0,0 +1,3 @@ +{ s0[i, j] -> [8 - i + j, i, 0] : i >= 1 and i <= 8 and j >= 1 and j <= 4; s1[i, j] -> [-1 + i + j, i, 1] : i >= 1 and i <= 8 and j >= 1 and j <= 4 } +{ : } +{ [i0, i1, i2] -> separate[o0] : o0 >= 1; [i0, i1, i2] -> atomic[o0] : o0 <= 0 } diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/x-1.c b/external/mit/isl/dist/test_inputs/codegen/omega/x-1.c new file mode 100644 index 000000000000..f890920d709a --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/x-1.c @@ -0,0 +1,14 @@ +for (int c0 = 1; c0 <= 11; c0 += 1) { + for (int c1 = max(1, c0 - 3); c1 <= min(c0, -c0 + 8); c1 += 1) + s1(c1, c0 - c1 + 1); + for (int c1 = max(1, -c0 + 9); c1 <= min(c0 - 4, -c0 + 12); c1 += 1) + s0(c1, c0 + c1 - 8); + for (int c1 = max(c0 - 3, -c0 + 9); c1 <= min(c0, -c0 + 12); c1 += 1) { + s0(c1, c0 + c1 - 8); + s1(c1, c0 - c1 + 1); + } + for (int c1 = max(c0 - 3, -c0 + 13); c1 <= min(8, c0); c1 += 1) + s1(c1, c0 - c1 + 1); + for (int c1 = max(c0 + 1, -c0 + 9); c1 <= min(8, -c0 + 12); c1 += 1) + s0(c1, c0 + c1 - 8); +} diff --git a/external/mit/isl/dist/test_inputs/codegen/omega/x-1.in b/external/mit/isl/dist/test_inputs/codegen/omega/x-1.in new file mode 100644 index 000000000000..24340efe4d84 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/omega/x-1.in @@ -0,0 +1,3 @@ +{ s0[i, j] -> [8 - i + j, i, 0] : i >= 1 and i <= 8 and j >= 1 and j <= 4; s1[i, j] -> [-1 + i + j, i, 1] : i >= 1 and i <= 8 and j >= 1 and j <= 4 } +{ : } +{ [i0, i1, i2] -> separate[o0] : o0 >= 1; [i0, i1, i2] -> atomic[o0] : o0 <= 0 } diff --git a/external/mit/isl/dist/test_inputs/codegen/pldi2012/README b/external/mit/isl/dist/test_inputs/codegen/pldi2012/README new file mode 100644 index 000000000000..316e8387782b --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/pldi2012/README @@ -0,0 +1,2 @@ +These examples are taken from the "Polyhedra Scanning Revisited" paper +by Chun Chen. diff --git a/external/mit/isl/dist/test_inputs/codegen/pldi2012/figure7_b.c b/external/mit/isl/dist/test_inputs/codegen/pldi2012/figure7_b.c new file mode 100644 index 000000000000..18ca37021869 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/pldi2012/figure7_b.c @@ -0,0 +1,9 @@ +for (int c0 = 1; c0 <= 100; c0 += 1) { + if (n >= 2) + s0(c0); + for (int c1 = 1; c1 <= 100; c1 += 1) { + if (n >= 2) + s1(c0, c1); + s2(c0, c1); + } +} diff --git a/external/mit/isl/dist/test_inputs/codegen/pldi2012/figure7_b.in b/external/mit/isl/dist/test_inputs/codegen/pldi2012/figure7_b.in new file mode 100644 index 000000000000..93149176bc4b --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/pldi2012/figure7_b.in @@ -0,0 +1,5 @@ +[n] -> { s0[i] -> [i,0] : 1 <= i <= 100 and n > 1; + s1[i,j] -> [i,j] : 1 <= i,j <= 100 and n > 1; + s2[i,j] -> [i,j] : 1 <= i,j <= 100 } +[n] -> { : } +[n] -> { [i,j] -> separate[x] : x >= 2 } diff --git a/external/mit/isl/dist/test_inputs/codegen/pldi2012/figure7_c.c b/external/mit/isl/dist/test_inputs/codegen/pldi2012/figure7_c.c new file mode 100644 index 000000000000..158b0782ffdc --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/pldi2012/figure7_c.c @@ -0,0 +1,12 @@ +for (int c0 = 1; c0 <= 100; c0 += 1) { + if (n >= 2) { + s0(c0); + for (int c1 = 1; c1 <= 100; c1 += 1) { + s1(c0, c1); + s2(c0, c1); + } + } else { + for (int c1 = 1; c1 <= 100; c1 += 1) + s2(c0, c1); + } +} diff --git a/external/mit/isl/dist/test_inputs/codegen/pldi2012/figure7_c.in b/external/mit/isl/dist/test_inputs/codegen/pldi2012/figure7_c.in new file mode 100644 index 000000000000..06a32663ec8e --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/pldi2012/figure7_c.in @@ -0,0 +1,5 @@ +[n] -> { s0[i] -> [i,0] : 1 <= i <= 100 and n > 1; + s1[i,j] -> [i,j] : 1 <= i,j <= 100 and n > 1; + s2[i,j] -> [i,j] : 1 <= i,j <= 100 } +[n] -> { : } +[n] -> { [i,j] -> separate[x] : x >= 1 } diff --git a/external/mit/isl/dist/test_inputs/codegen/pldi2012/figure7_d.c b/external/mit/isl/dist/test_inputs/codegen/pldi2012/figure7_d.c new file mode 100644 index 000000000000..bae078e4662f --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/pldi2012/figure7_d.c @@ -0,0 +1,13 @@ +if (n >= 2) { + for (int c0 = 1; c0 <= 100; c0 += 1) { + s0(c0); + for (int c1 = 1; c1 <= 100; c1 += 1) { + s1(c0, c1); + s2(c0, c1); + } + } +} else { + for (int c0 = 1; c0 <= 100; c0 += 1) + for (int c1 = 1; c1 <= 100; c1 += 1) + s2(c0, c1); +} diff --git a/external/mit/isl/dist/test_inputs/codegen/pldi2012/figure7_d.in b/external/mit/isl/dist/test_inputs/codegen/pldi2012/figure7_d.in new file mode 100644 index 000000000000..339e39d8ceee --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/pldi2012/figure7_d.in @@ -0,0 +1,5 @@ +[n] -> { s0[i] -> [i,0] : 1 <= i <= 100 and n > 1; + s1[i,j] -> [i,j] : 1 <= i,j <= 100 and n > 1; + s2[i,j] -> [i,j] : 1 <= i,j <= 100 } +[n] -> { : } +[n] -> { [i,j] -> separate[x] : x >= 0 } diff --git a/external/mit/isl/dist/test_inputs/codegen/pldi2012/figure8_a.c b/external/mit/isl/dist/test_inputs/codegen/pldi2012/figure8_a.c new file mode 100644 index 000000000000..4608d61d8dbf --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/pldi2012/figure8_a.c @@ -0,0 +1,3 @@ +for (int c0 = 1; c0 <= n; c0 += 4) + for (int c1 = c0; c1 <= n; c1 += 3) + s0(c0, c1); diff --git a/external/mit/isl/dist/test_inputs/codegen/pldi2012/figure8_a.in b/external/mit/isl/dist/test_inputs/codegen/pldi2012/figure8_a.in new file mode 100644 index 000000000000..df6543cce226 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/pldi2012/figure8_a.in @@ -0,0 +1,4 @@ +[n] -> { s0[i,j] -> [i,j] : exists alpha, beta: 1 <= i <= n and i <= j <= n and + i = 1 + 4 alpha and j = i + 3 beta} +[n] -> { : } +[n] -> {} diff --git a/external/mit/isl/dist/test_inputs/codegen/pldi2012/figure8_b.c b/external/mit/isl/dist/test_inputs/codegen/pldi2012/figure8_b.c new file mode 100644 index 000000000000..95098f23c217 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/pldi2012/figure8_b.c @@ -0,0 +1,6 @@ +for (int c0 = 2; c0 < n - 1; c0 += 4) { + s1(c0); + s0(c0 + 2); +} +if (n >= 1 && n % 4 >= 2) + s1(-(n % 4) + n + 2); diff --git a/external/mit/isl/dist/test_inputs/codegen/pldi2012/figure8_b.in b/external/mit/isl/dist/test_inputs/codegen/pldi2012/figure8_b.in new file mode 100644 index 000000000000..d375c4d9e399 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/pldi2012/figure8_b.in @@ -0,0 +1,4 @@ +[n] -> { s0[i] -> [i] : exists alpha: 1 <= i <= n and i = 4 alpha; + s1[i] -> [i] : exists alpha: 1 <= i <= n and i = 4 alpha + 2 } +[n] -> { : } +[n] -> { [*] -> separate[x] : x >= 0 } diff --git a/external/mit/isl/dist/test_inputs/codegen/redundant.c b/external/mit/isl/dist/test_inputs/codegen/redundant.c new file mode 100644 index 000000000000..057416e88ba8 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/redundant.c @@ -0,0 +1,11 @@ +for (int c0 = 0; c0 <= 2; c0 += 1) + for (int c1 = max(0, b0 - 4 * c0 - 1); c1 <= 1; c1 += 1) { + if (b0 >= 1 && 4 * c0 + c1 >= 1) + for (int c2 = 1; c2 <= 2; c2 += 1) + for (int c3 = 1; c3 <= 14; c3 += 1) + write(c0, c1, 8 * b0 + c2 - 5, c3); + for (int c2 = max(max(3, -8 * b0 + 6), 8 * c0 - 12); c2 <= min(min(7, -8 * b0 + 17), 8 * c0 + 6); c2 += 1) + if (4 * c0 + c1 + 1 >= 2 * ((2 * c1 + c2 - 1) / 4) && 2 * ((2 * c1 + c2 - 1) / 4) + 7 >= 4 * c0 + c1 && (2 * c1 + c2 - 1) % 4 >= 1 && ((2 * c1 + c2 - 1) % 4) + 11 >= 2 * c2) + for (int c3 = 1; c3 <= 14; c3 += 1) + write(c0, c1, 8 * b0 + c2 - 5, c3); + } diff --git a/external/mit/isl/dist/test_inputs/codegen/redundant.st b/external/mit/isl/dist/test_inputs/codegen/redundant.st new file mode 100644 index 000000000000..e766f740c9f1 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/redundant.st @@ -0,0 +1,6 @@ +# Check that b1 >= 1 is not dropped by mistake in 4 * c0 + c1 >= 1 part +domain: "[b0] -> { write[i0, o1, o2, o3] : ((exists (e0 = floor((4 + o2)/8), e1 = floor((5 + o2)/8), e2 = floor((4 + o2)/262144), e3, e4: o1 <= 1 and o1 >= 0 and o2 <= 12 and o2 >= 1 and o3 <= 14 and o3 >= 1 and 8e0 <= 4 + o2 and 8e1 <= 5 + o2 and 262144e2 <= 4 - 8b0 + o2 and 262144e2 >= -262139 + o2 and 262144e2 <= 4 + o2 and 262144e2 >= -3 - 8b0 + o2 and 4e4 <= 1 - 8i0 + 2o1 - o2 + 8e0 and 4e4 <= 4 - 8i0 + 2o1 + o2 - 8e0 and 4e4 >= 2o1 + o2 - 8e1 - 8e3 and 4e4 >= -3 + 2o1 + o2 - 8e0 - 8e3 and 4e4 >= -6 + 2o1 - o2 + 8e0 - 8e3 and 2e4 >= -9 + o1 and 2e4 <= -1 + o1 and 4e4 <= -6 + 2o1 - o2 + 8e1 - 8e3 and 4e4 >= -3 - 8i0 + 2o1 + o2 - 8e0 and 4e4 >= -6 - 8i0 + 2o1 - o2 + 8e0)) or (exists (e0 = floor((4 + o2)/8), e1 = floor((5 + o2)/8), e2 = floor((4 + o2)/262144), e3, e4: o1 <= 1 and o1 >= 0 and o2 <= 12 and o2 >= 1 and o3 <= 14 and o3 >= 1 and 8e0 <= 4 + o2 and 8e1 >= -2 + o2 and 262144e2 <= 4 - 8b0 + o2 and 262144e2 >= -262139 + o2 and 262144e2 <= 4 + o2 and 262144e2 >= -3 - 8b0 + o2 and 4e4 <= 1 - 8i0 + 2o1 - o2 + 8e0 and 4e4 <= 4 - 8i0 + 2o1 + o2 - 8e0 and 4e4 >= -3 + 2o1 + o2 - 8e0 - 8e3 and 4e4 >= -6 + 2o1 - o2 + 8e0 - 8e3 and 2e4 >= -9 + o1 and 2e4 <= -1 + o1 and 4e4 <= 1 + 2o1 - o2 + 8e0 - 8e3 and 4e4 <= 4 + 2o1 + o2 - 8e0 - 8e3 and 4e4 <= -1 + 2o1 + o2 - 8e1 - 8e3 and 4e4 >= -3 - 8i0 + 2o1 + o2 - 8e0 and 4e4 >= -6 - 8i0 + 2o1 - o2 + 8e0)) or (exists (e0 = floor((2 + o2)/8), e1 = floor((4 + o2)/8), e2 = floor((4 + o2)/262144), e3, e4: o1 <= 1 and o1 >= 0 and o2 <= 13 and o2 >= 3 and o3 <= 14 and o3 >= 1 and 8e0 >= -5 + o2 and 8e1 <= 4 + o2 and 262144e2 <= 4 - 8b0 + o2 and 262144e2 >= -262139 + o2 and 262144e2 <= 4 + o2 and 262144e2 >= -3 - 8b0 + o2 and 4e4 <= 1 - 8i0 + 2o1 - o2 + 8e1 and 4e4 <= 4 - 8i0 + 2o1 + o2 - 8e1 and 4e4 >= -3 + 2o1 + o2 - 8e1 - 8e3 and 4e4 >= -6 + 2o1 - o2 + 8e1 - 8e3 and 2e4 >= -9 + o1 and 2e4 <= -1 + o1 and 4e4 <= 1 + 2o1 - o2 + 8e1 - 8e3 and 4e4 <= -4 + 2o1 + o2 - 8e0 - 8e3 and 4e4 <= 4 + 2o1 + o2 - 8e1 - 8e3 and 4e4 >= -3 - 8i0 + 2o1 + o2 - 8e1 and 4e4 >= -6 - 8i0 + 2o1 - o2 + 8e1))) and b0 >= 0 and i0 <= 2 and i0 >= 0 and b0 <= 2 }" +child: + context: "[b0] -> { [] : b0 <= 2 and b0 >= 0 }" + child: + schedule: "[b0] -> [{ write[i0, o1, o2, o3] -> [i0] }, { write[i0, i1, i2, i3] -> [(i1)] }, { write[i0, i1, i2, i3] -> [(5 - 8b0 + i2)] }, { write[i0,i1, i2, i3] -> [(i3)] }]" diff --git a/external/mit/isl/dist/test_inputs/codegen/roman.c b/external/mit/isl/dist/test_inputs/codegen/roman.c new file mode 100644 index 000000000000..62f02327e2dc --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/roman.c @@ -0,0 +1,30 @@ +for (int c1 = 0; c1 <= min(np1 - i, -i + 1); c1 += 1) { + S_9(c1); + S_12(c1); +} +for (int c1 = max(0, -i + 2); c1 <= -((-np1 + i + 4294967295) % 4294967296) + 4294967295; c1 += 1) { + S_9(c1); + S_10(c1); + for (int c3 = 0; c3 <= min(19, i + c1 - 3); c3 += 1) { + S_15(c1, c3); + for (int c5 = 0; c5 < c3; c5 += 1) { + S_16(c1, c3, c5); + S_17(c1, c3, c5); + } + S_16(c1, c3, c3); + S_18(c1, c3); + S_24(c1, c3); + S_19(c1, c3); + } + if (i + c1 <= 21) { + S_15(c1, i + c1 - 2); + for (int c5 = 0; c5 < i + c1 - 2; c5 += 1) { + S_16(c1, i + c1 - 2, c5); + S_17(c1, i + c1 - 2, c5); + } + S_16(c1, i + c1 - 2, i + c1 - 2); + S_18(c1, i + c1 - 2); + S_24(c1, i + c1 - 2); + } + S_12(c1); +} diff --git a/external/mit/isl/dist/test_inputs/codegen/roman.in b/external/mit/isl/dist/test_inputs/codegen/roman.in new file mode 100644 index 000000000000..55182a6efdb5 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/roman.in @@ -0,0 +1,5 @@ +# Older versions of isl would get confused on this input due to disappearing +# div constraints. +[np1, i] -> { S_17[i0, i1, i2] -> [0, i0, 2, i1, 1, i2, 1] : exists (e0 = [(np1 - i)/4294967296], e1 = [(-2 + i + i0)/4294967296], e2 = [(i1)/4294967296]: i0 >= 0 and 4294967296e0 <= np1 - i and 4294967296e0 >= -4294967295 + np1 - i and 4294967296e0 <= np1 - i - i0 and i0 <= 20 and i1 >= 0 and 4294967296e1 <= -2 + i + i0 and 4294967296e1 >= -4294967297 + i + i0 and 4294967296e1 <= -2 + i + i0 - i1 and i1 <= 19 and i2 >= 0 and 4294967296e2 <= i1 and 4294967296e2 >= -4294967295 + i1 and 4294967296e2 <= i1 - i2 and i2 <= 19 and i0 >= 2 - i and i2 <= -1 + i1); S_18[i0, i1] -> [0, i0, 2, i1, 2, 0, 0] : exists (e0 = [(np1 - i)/4294967296], e1 = [(-2 + i + i0)/4294967296]: i0 >= 0 and 4294967296e0 <= np1 - i and 4294967296e0 >= -4294967295 + np1 - i and 4294967296e0 <= np1 - i - i0 and i0 <= 20 and i1 >= 0 and 4294967296e1 <= -2 + i + i0 and 4294967296e1 >= -4294967297 + i + i0 and 4294967296e1 <= -2 + i + i0 - i1 and i1 <= 19 and i0 >= 2 - i); S_24[i0, i1] -> [0, i0, 2, i1, 3, 0, 0] : exists (e0 = [(np1 - i)/4294967296], e1 = [(-2 + i + i0)/4294967296]: i0 >= 0 and 4294967296e0 <= np1 - i and 4294967296e0 >= -4294967295 + np1 - i and 4294967296e0 <= np1 - i - i0 and i0 <= 20 and i1 >= 0 and 4294967296e1 <= -2 + i + i0 and 4294967296e1 >= -4294967297 + i + i0 and 4294967296e1 <= -2 + i + i0 - i1 and i1 <= 19 and i0 >= 2 - i); S_15[i0, i1] -> [0, i0, 2, i1, 0, 0, 0] : exists (e0 = [(np1 - i)/4294967296], e1 = [(-2 + i + i0)/4294967296]: i0 >= 0 and 4294967296e0 <= np1 - i and 4294967296e0 >= -4294967295 + np1 - i and 4294967296e0 <= np1 - i - i0 and i0 <= 20 and i1 >= 0 and 4294967296e1 <= -2 + i + i0 and 4294967296e1 >= -4294967297 + i + i0 and 4294967296e1 <= -2 + i + i0 - i1 and i1 <= 19 and i0 >= 2 - i); S_9[i0] -> [0, i0, 0, 0, 0, 0, 0] : exists (e0 = [(np1 - i)/4294967296]: i0 >= 0 and 4294967296e0 <= np1 - i and 4294967296e0 >= -4294967295 + np1 - i and 4294967296e0 <= np1 - i - i0 and i0 <= 20); S_10[i0] -> [0, i0, 1, 0, 0, 0, 0] : exists (e0 = [(np1 - i)/4294967296]: i0 >= 0 and 4294967296e0 <= np1 - i and 4294967296e0 >= -4294967295 + np1 - i and 4294967296e0 <= np1 - i - i0 and i0 <= 20 and i0 >= 2 - i); S_19[i0, i1] -> [0, i0, 2, i1, 4, 0, 0] : exists (e0 = [(np1 - i)/4294967296], e1 = [(-2 + i + i0)/4294967296]: i0 >= 0 and 4294967296e0 <= np1 - i and 4294967296e0 >= -4294967295 + np1 - i and 4294967296e0 <= np1 - i - i0 and i0 <= 20 and i1 >= 0 and 4294967296e1 <= -2 + i + i0 and 4294967296e1 >= -4294967297 + i + i0 and 4294967296e1 <= -2 + i + i0 - i1 and i1 <= 19 and i0 >= 2 - i and i1 <= -3 + i + i0); S_12[i0] -> [0, i0, 3, 0, 0, 0, 0] : exists (e0 = [(np1 - i)/4294967296]: i0 >= 0 and 4294967296e0 <= np1 - i and 4294967296e0 >= -4294967295 + np1 - i and 4294967296e0 <= np1 - i - i0 and i0 <= 20); S_16[i0, i1, i2] -> [0, i0, 2, i1, 1, i2, 0] : exists (e0 = [(np1 - i)/4294967296], e1 = [(-2 + i + i0)/4294967296], e2 = [(i1)/4294967296]: i0 >= 0 and 4294967296e0 <= np1 - i and 4294967296e0 >= -4294967295 + np1 - i and 4294967296e0 <= np1 - i - i0 and i0 <= 20 and i1 >= 0 and 4294967296e1 <= -2 + i + i0 and 4294967296e1 >= -4294967297 + i + i0 and 4294967296e1 <= -2 + i + i0 - i1 and i1 <= 19 and i2 >= 0 and 4294967296e2 <= i1 and 4294967296e2 >= -4294967295 + i1 and 4294967296e2 <= i1 - i2 and i2 <= 19 and i0 >= 2 - i) } +[np1, i] -> { : exists (e0 = [(np1 - i)/4294967296]: 4294967296e0 <= np1 - i and 4294967296e0 >= -20 + np1 - i and np1 >= -2147483648 and np1 <= 2147483647 and i >= -2147483648 and i <= 2147483647) } +[np1, i] -> { [i0, i1, i2, i3, i4, i5, i6] -> separate[o0] } diff --git a/external/mit/isl/dist/test_inputs/codegen/separate.c b/external/mit/isl/dist/test_inputs/codegen/separate.c new file mode 100644 index 000000000000..d368d7147ed2 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/separate.c @@ -0,0 +1,6 @@ +a(0); +for (int c0 = 1; c0 <= 9; c0 += 1) { + a(c0); + b(c0 - 1); +} +b(9); diff --git a/external/mit/isl/dist/test_inputs/codegen/separate.in b/external/mit/isl/dist/test_inputs/codegen/separate.in new file mode 100644 index 000000000000..07ea4aab3115 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/separate.in @@ -0,0 +1,3 @@ +{ a[i] -> [i, 0] : 0 <= i < 10; b[i] -> [i+1, 1] : 0 <= i < 10 } +{ : } +{ [i, d] -> separate[x] } diff --git a/external/mit/isl/dist/test_inputs/codegen/separate.st b/external/mit/isl/dist/test_inputs/codegen/separate.st new file mode 100644 index 000000000000..2eed716e1c24 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/separate.st @@ -0,0 +1,8 @@ +domain: "{ a[i] : 0 <= i < 10; b[i] : 0 <= i < 10 }" +child: + schedule: "[{ a[i] -> [i]; b[i] -> [i+1] }]" + options: "{ separate[x] }" + child: + sequence: + - filter: "{ a[i] }" + - filter: "{ b[i] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/separate2.c b/external/mit/isl/dist/test_inputs/codegen/separate2.c new file mode 100644 index 000000000000..76ee58d96e62 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/separate2.c @@ -0,0 +1,8 @@ +for (int c0 = 0; c0 <= 1; c0 += 1) + for (int c5 = 0; c5 <= 31; c5 += 1) + for (int c6 = max(0, 2 * (length % 16) + 2 * c5 - 62); c6 <= 30; c6 += 1) { + if (2 * length + c6 >= 2 * (length % 16) + 2 && c6 + 62 >= 2 * (length % 16) + 2 * c5 && 2 * (length % 16) >= c6 + 2 && 2 * (length % 16) + 2 * c5 >= c6 && 2 * (length % 32) + c6 == 2 * (length % 16) + 2 * c5 && (2 * c5 - c6) % 32 == 0) + S_3(c0, 0, (c6 / 2) - (length % 16) + length); + if (length <= 15 && length >= c5 + 1 && c6 >= 1 && length >= c6) + S_0(c0, c5, c6 - 1); + } diff --git a/external/mit/isl/dist/test_inputs/codegen/separate2.in b/external/mit/isl/dist/test_inputs/codegen/separate2.in new file mode 100644 index 000000000000..8f4ebf1a5b9b --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/separate2.in @@ -0,0 +1,4 @@ +# Check that rational affine expressions are printer properly. +[tsteps, length] -> { S_0[iter, i, j] -> [iter, 0, o2, o3, 0, o5, o6, 4] : exists (e0 = [(o2)/32], e1 = [(o3)/32], e2 = [(-i + o5)/32], e3 = [(-31 + j - o6)/32]: tsteps = 2 and 32e0 = o2 and 32e1 = o3 and 32e2 = -i + o5 and 32e3 = -31 + j - o6 and o2 <= i and o2 >= -31 + i and o3 <= 1 + j and o3 >= -30 + j and o5 >= 0 and o5 <= 31 and o6 >= 0 and o6 <= 31 and i <= -1 + length and i >= 0 and iter >= 0 and iter <= 1 and j <= -1 + length and j >= 0 and o2 >= -31 + length and o3 >= -30 + 2length); S_3[iter, 0, j] -> [iter, 0, o2, o3, o4, o5, o6, 2] : exists (e0 = [(o2)/32], e1 = [(o3)/32], e2 = [(o4)/32], e3 = [(-2o5 + o6)/32], e4 = [(j - o5)/32]: tsteps = 2 and 32e0 = o2 and 32e1 = o3 and 32e2 = o4 and 32e3 = -2o5 + o6 and 32e4 = j - o5 and iter <= 1 and j <= -1 + length and o2 <= j and o2 >= -31 + j and o3 <= 2j and o3 >= -30 + 2j and o4 >= 0 and o4 <= 31 and o5 >= 0 and o5 <= 31 and o6 >= 0 and o6 <= 30 and j >= 1 and iter >= 0 and o2 >= -31 + length and o3 >= -30 + 2length) } +[tsteps, length] -> { : length >= 1 and length <= 1024 and tsteps = 2 } +{ [o0,o1,o2,o3,o4,o5,o6,o7] -> separate[x] } diff --git a/external/mit/isl/dist/test_inputs/codegen/separation_class.c b/external/mit/isl/dist/test_inputs/codegen/separation_class.c new file mode 100644 index 000000000000..6cc43631b34f --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/separation_class.c @@ -0,0 +1,15 @@ +for (int c0 = 0; c0 <= 8; c0 += 1) { + for (int c1 = 0; c1 <= -c0 + 8; c1 += 1) + for (int c2 = 10 * c0; c2 <= 10 * c0 + 9; c2 += 1) + for (int c3 = 10 * c1; c3 <= 10 * c1 + 9; c3 += 1) + A(c2, c3); + for (int c1 = -c0 + 9; c1 <= -c0 + 10; c1 += 1) + for (int c2 = 10 * c0; c2 <= min(10 * c0 + 9, -10 * c1 + 100); c2 += 1) + for (int c3 = 10 * c1; c3 <= min(10 * c1 + 9, -c2 + 100); c3 += 1) + A(c2, c3); +} +for (int c0 = 9; c0 <= 10; c0 += 1) + for (int c1 = 0; c1 <= -c0 + 10; c1 += 1) + for (int c2 = 10 * c0; c2 <= min(10 * c0 + 9, -10 * c1 + 100); c2 += 1) + for (int c3 = 10 * c1; c3 <= min(10 * c1 + 9, -c2 + 100); c3 += 1) + A(c2, c3); diff --git a/external/mit/isl/dist/test_inputs/codegen/separation_class.in b/external/mit/isl/dist/test_inputs/codegen/separation_class.in new file mode 100644 index 000000000000..f42ea27fa565 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/separation_class.in @@ -0,0 +1,6 @@ +{ A[i,j] -> [([i/10]),[j/10],i,j] : 0 <= i,j and i + j <= 100 } +{ : } +{ [a,b,c,d] -> separation_class[[0]->[0]] : + exists b': 0 <= 10a,10b' and 10a+9+10b'+9 <= 100; + [a,b,c,d] -> separation_class[[1]->[0]] : + 0 <= 10a,10b and 10a+9+10b+9 <= 100 } diff --git a/external/mit/isl/dist/test_inputs/codegen/separation_class2.c b/external/mit/isl/dist/test_inputs/codegen/separation_class2.c new file mode 100644 index 000000000000..67b9a9b92759 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/separation_class2.c @@ -0,0 +1,13 @@ +for (int c0 = 0; c0 < -(n % 8) + n; c0 += 8) { + for (int c1 = 0; c1 < -(n % 8) + n; c1 += 8) + for (int c2 = 0; c2 <= 7; c2 += 1) + for (int c3 = 0; c3 <= 7; c3 += 1) + A(c0 + c2, c1 + c3); + for (int c2 = 0; c2 <= 7; c2 += 1) + for (int c3 = 0; c3 < n % 8; c3 += 1) + A(c0 + c2, -(n % 8) + n + c3); +} +for (int c1 = 0; c1 < n; c1 += 8) + for (int c2 = 0; c2 < n % 8; c2 += 1) + for (int c3 = 0; c3 <= min(7, n - c1 - 1); c3 += 1) + A(-(n % 8) + n + c2, c1 + c3); diff --git a/external/mit/isl/dist/test_inputs/codegen/separation_class2.in b/external/mit/isl/dist/test_inputs/codegen/separation_class2.in new file mode 100644 index 000000000000..5469626ae7ef --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/separation_class2.in @@ -0,0 +1,3 @@ +[n] -> { A[i,j] -> [it,jt, ip, jp] : 0 <= i,j < n and ip = i % 8 and it = i - ip and jp = j % 8 and jt = j - jp} +[n] -> { : n >= 10} +[n] -> { [it, jt, ip, jp] -> separation_class[[x]->[1]]: (exists id, jd: 0 <= x <= 3 and it < n - id and jt < n - jd and id = n %8 and jd = n %8)} diff --git a/external/mit/isl/dist/test_inputs/codegen/separation_class3.c b/external/mit/isl/dist/test_inputs/codegen/separation_class3.c new file mode 100644 index 000000000000..cea4e04d84a8 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/separation_class3.c @@ -0,0 +1,31 @@ +for (int c0 = 0; c0 <= 4; c0 += 1) { + if (c0 == 0) { + S_0(0, 4); + } else { + S_0(2 * c0 - 1, 1); + if (c0 == 4) { + for (int c6 = 3; c6 <= 5; c6 += 1) + S_0(7, c6); + } else { + for (int c4 = 2 * c0 - 1; c4 <= 2 * c0; c4 += 1) + for (int c6 = -2 * c0 + c4 + 4; c6 <= 2 * c0 - c4 + 4; c6 += 1) + S_0(c4, c6); + } + } + for (int c4 = max(0, 2 * c0 - 1); c4 <= min(7, 2 * c0); c4 += 1) + for (int c6 = -2 * c0 + c4 + 8; c6 <= 8; c6 += 1) + S_0(c4, c6); + if (c0 >= 1 && c0 <= 3) { + for (int c2 = 0; c2 <= 1; c2 += 1) + for (int c4 = 2 * c0 - 1; c4 <= 2 * c0; c4 += 1) + for (int c6 = 2 * c0 + 4 * c2 - c4 + 1; c6 <= -2 * c0 + 4 * c2 + c4 + 3; c6 += 1) + S_0(c4, c6); + } else if (c0 == 4) { + for (int c2 = 0; c2 <= 1; c2 += 1) + S_0(7, 4 * c2 + 2); + } else { + for (int c2 = 0; c2 <= 1; c2 += 1) + for (int c6 = 4 * c2 + 1; c6 <= 4 * c2 + 3; c6 += 1) + S_0(0, c6); + } +} diff --git a/external/mit/isl/dist/test_inputs/codegen/separation_class3.in b/external/mit/isl/dist/test_inputs/codegen/separation_class3.in new file mode 100644 index 000000000000..1aaf2517c18c --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/separation_class3.in @@ -0,0 +1,4 @@ +{ S_0[t, i] -> [o0, 1, o2, 0, t, 0, i] : 4o2 >= -4 + t + i - 2o0 and 4o2 >= -3 - t + i + 2o0 and 2o0 <= 1 + t and 2o0 >= t and 4o2 <= -1 + t + i - 2o0 and t >= 0 and t <= 7 and i >= 1 and i <= 8; S_0[t, i] -> [o0, 0, o2, 0, t, 0, i] : 4o2 >= t + i - 2o0 and 4o2 <= -t + i + 2o0 and 2o0 <= 1 + t and 2o0 >= t and t >= 0 and t <= 7 and i >= 1 and i <= 8 } +{:} +{ [i0, 1, i2, i3, i4, i5, i6] -> separation_class[[2] -> [0]] : i2 <= 1 and i2 >= 0 and i0 <= 3 and i0 >= 1; [i0, 0, 1, i3, i4, i5, i6] -> separation_class[[2] -> [0]] : i0 <= 3 and i0 >= 1; [i0, i1, i2, i3, i4, i5, i6] -> unroll[1] } + diff --git a/external/mit/isl/dist/test_inputs/codegen/separation_class4.c b/external/mit/isl/dist/test_inputs/codegen/separation_class4.c new file mode 100644 index 000000000000..6d877d67a6a1 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/separation_class4.c @@ -0,0 +1,22 @@ +for (int c0 = 0; c0 <= 128; c0 += 1) { + if (c0 <= 127) { + if (c0 == 0) { + for (int c3 = 0; c3 <= 1; c3 += 1) + for (int c5 = c3 + 58; c5 <= -c3 + 61; c5 += 1) + S_0(c3, c5); + } else { + for (int c2 = 1; c2 <= 2; c2 += 1) + for (int c3 = max(4 * c0 - 2, 4 * c0 + 6 * c2 - 12); c3 <= min(4 * c0 + 1, 4 * c0 + 6 * c2 - 7); c3 += 1) + for (int c5 = max(4 * c0 - c3 + 57, -4 * c0 + c3 + 58); c5 <= min(4 * c0 - c3 + 61, -4 * c0 + c3 + 62); c5 += 1) + S_0(c3, c5); + } + for (int c2 = 1; c2 <= 2; c2 += 1) + for (int c3 = max(4 * c0, 4 * c0 + 6 * c2 - 10); c3 <= min(4 * c0 + 3, 4 * c0 + 6 * c2 - 5); c3 += 1) + for (int c5 = max(-4 * c0 + c3 + 59, 4 * c0 - c3 + 62); c5 <= min(-4 * c0 + c3 + 63, 4 * c0 - c3 + 66); c5 += 1) + S_0(c3, c5); + } else { + for (int c3 = 510; c3 <= 511; c3 += 1) + for (int c5 = -c3 + 569; c5 < c3 - 449; c5 += 1) + S_0(c3, c5); + } +} diff --git a/external/mit/isl/dist/test_inputs/codegen/separation_class4.in b/external/mit/isl/dist/test_inputs/codegen/separation_class4.in new file mode 100644 index 000000000000..c04dd79bf23e --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/separation_class4.in @@ -0,0 +1,10 @@ +# Check that isl is not confused by the combination of separation classes +# and unroll. +{ S_0[t, i] -> [o0, 1, o9, t] : 4o0 >= -3 + t and 4o0 <= t and i >= 60 and i <= 65 and 6o9 >= 5 + t - 4o0 and 6o9 <= 10 + t - 4o0 and 4o0 <= -62 + t + i and 4o0 >= 59 + t - i and o0 >= 0 and o0 <= 127 and t <= 511 and t >= 0 and 4o0 >= -66 + t + i and 4o0 <= 63 + t - i; +S_0[t, i] -> [o0, 0, o9, t] : 4o0 >= -1 + t and 4o0 <= 2 + t and i >= 57 and i <= 62 and 6o9 >= 7 + t - 4o0 and 6o9 <= 12 + t - 4o0 and t >= 0 and t <= 511 and 4o0 <= -57 + t + i and 4o0 >= 58 + t - i and o0 >= 0 and o0 <= 128 and 4o0 >= -61 + t + i and 4o0 <= 62 + t - i } +{ : } +{ [i0, i1, i2, t] -> unroll[1]; +[i0, 1, i2, t] -> separation_class[[1] -> [0]] + : 0 <= i0 <= 127; +[i0, 0, i2, t] -> separation_class[[1] -> [0]] + : 1 <= i0 <= 127} diff --git a/external/mit/isl/dist/test_inputs/codegen/shift.c b/external/mit/isl/dist/test_inputs/codegen/shift.c new file mode 100644 index 000000000000..f4156bca99bf --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/shift.c @@ -0,0 +1,4 @@ +for (int c0 = 0; c0 <= 9; c0 += 1) { + A(c0); + B(c0); +} diff --git a/external/mit/isl/dist/test_inputs/codegen/shift.in b/external/mit/isl/dist/test_inputs/codegen/shift.in new file mode 100644 index 000000000000..702c52756214 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/shift.in @@ -0,0 +1,3 @@ +{ A[i] -> [2i]: 0 <= i < 10; B[i] -> [2i+1] : 0 <= i < 10 } +{ : } +{ } diff --git a/external/mit/isl/dist/test_inputs/codegen/shift2.c b/external/mit/isl/dist/test_inputs/codegen/shift2.c new file mode 100644 index 000000000000..9d07c2742b27 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/shift2.c @@ -0,0 +1,51 @@ +for (int c0 = 0; c0 <= 1; c0 += 1) { + for (int c2 = 0; c2 <= length; c2 += 32) { + if (length >= c2 + 1) { + for (int c3 = 0; c3 <= length; c3 += 32) { + if (c2 == 0) + for (int c6 = max(0, -c3 + 1); c6 <= min(31, length - c3); c6 += 1) + S_0(c0, 0, c3 + c6 - 1); + for (int c5 = max(0, -c2 + 1); c5 <= min(31, (c3 / 2) - c2 - 1); c5 += 1) + for (int c6 = 0; c6 <= min(31, length - c3); c6 += 1) + S_0(c0, c2 + c5, c3 + c6 - 1); + for (int c5 = max(max(0, -c2 + 1), (c3 / 2) - c2); c5 <= min(min(31, length - c2 - 1), (c3 / 2) - c2 + 15); c5 += 1) { + for (int c6 = max(0, -c3 + 1); c6 <= min(length - c3, 2 * c2 - c3 + 2 * c5 - 1); c6 += 1) + S_0(c0, c2 + c5, c3 + c6 - 1); + S_3(c0, 0, c2 + c5); + if (length >= 2 * c2 + 2 * c5) + S_0(c0, c2 + c5, 2 * c2 + 2 * c5 - 1); + for (int c6 = 2 * c2 - c3 + 2 * c5 + 1; c6 <= min(31, length - c3); c6 += 1) + S_0(c0, c2 + c5, c3 + c6 - 1); + } + for (int c5 = max(0, (c3 / 2) - c2 + 16); c5 <= min(31, length - c2 - 1); c5 += 1) + for (int c6 = max(0, -c3 + 1); c6 <= min(31, length - c3); c6 += 1) + S_0(c0, c2 + c5, c3 + c6 - 1); + if (length <= 15 && c2 == 0 && c3 == 0) + S_4(c0); + if (c3 >= 2 * c2 && 2 * c2 + 32 >= c3) + for (int c4 = 1; c4 <= min(min(31, length - 2), (c3 / 2) + 14); c4 += 1) + for (int c5 = max((c3 / 2) - c2, -c2 + c4 + 1); c5 <= min(length - c2 - 1, (c3 / 2) - c2 + 15); c5 += 1) + S_3(c0, c4, c2 + c5); + } + for (int c3 = max(2 * c2, -(length % 32) + length + 32); c3 <= min(2 * length - 2, 2 * c2 + 62); c3 += 32) + for (int c4 = 0; c4 <= min(31, length - 2); c4 += 1) { + for (int c5 = max((c3 / 2) - c2, -c2 + c4 + 1); c5 <= min(length - c2 - 1, (c3 / 2) - c2 + 15); c5 += 1) + S_3(c0, c4, c2 + c5); + if (c3 + 30 >= 2 * length && c4 == 0) + S_4(c0); + } + if (c2 + 16 == length) + S_4(c0); + } else if (length >= 32) { + S_4(c0); + } else { + S_4(c0); + } + } + for (int c1 = 32; c1 < length - 1; c1 += 32) + for (int c2 = c1; c2 < length; c2 += 32) + for (int c3 = c2; c3 <= min(length - 1, c2 + 31); c3 += 16) + for (int c4 = 0; c4 <= min(min(31, length - c1 - 2), -c1 + c3 + 14); c4 += 1) + for (int c5 = max(-c2 + c3, c1 - c2 + c4 + 1); c5 <= min(length - c2 - 1, -c2 + c3 + 15); c5 += 1) + S_3(c0, c1 + c4, c2 + c5); +} diff --git a/external/mit/isl/dist/test_inputs/codegen/shift2.in b/external/mit/isl/dist/test_inputs/codegen/shift2.in new file mode 100644 index 000000000000..3c05fac3687a --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/shift2.in @@ -0,0 +1,5 @@ +# Check that the shifting code is not confused by domains that +# have a non-obviously fixed value. +[tsteps, length] -> { S_4[iter] -> [iter, 0, o2, o3, 0, o5, o6, 3] : exists (e0 = [(o2)/32], e1 = [(o3)/32], e2 = [(-length + o5)/32], e3 = [(-2length + o6)/32]: tsteps = 2 and 32e0 = o2 and 32e1 = o3 and 32e2 = -length + o5 and 32e3 = -2length + o6 and o2 <= length and o2 >= -31 + length and o3 <= 2length and o3 >= -30 + 2length and o5 >= 0 and o5 <= 31 and o6 >= 0 and o6 <= 30 and iter <= 1 and iter >= 0); S_3[iter, i, j] -> [iter, o1, o2, o3, o4, o5, o6, 2] : exists (e0 = [(o1)/32], e1 = [(o2)/32], e2 = [(o3)/32], e3 = [(-i + o4)/32], e4 = [(-j + o5)/32], e5 = [(-2j + o6)/32]: tsteps = 2 and 32e0 = o1 and 32e1 = o2 and 32e2 = o3 and 32e3 = -i + o4 and 32e4 = -j + o5 and 32e5 = -2j + o6 and o1 <= i and o1 >= -31 + i and o2 <= j and o2 >= -31 + j and o3 <= 2j and o3 >= -30 + 2j and o4 >= 0 and o4 <= 31 and o5 >= 0 and o5 <= 31 and o6 >= 0 and o6 <= 30 and j >= 1 + i and i >= 0 and iter <= 1 and iter >= 0 and j <= -1 + length); S_0[iter, i, j] -> [iter, 0, o2, o3, 0, o5, o6, 4] : exists (e0 = [(o2)/32], e1 = [(o3)/32], e2 = [(-i + o5)/32], e3 = [(-31 + j - o6)/32]: tsteps = 2 and 32e0 = o2 and 32e1 = o3 and 32e2 = -i + o5 and 32e3 = -31 + j - o6 and o2 <= i and o2 >= -31 + i and o3 <= 1 + j and o3 >= -30 + j and o5 >= 0 and o5 <= 31 and o6 >= 0 and o6 <= 31 and i <= -1 + length and i >= 0 and iter >= 0 and iter <= 1 and j <= -1 + length and j >= 0) } +[tsteps, length] -> { : length >= 0 and length <= 1024 and tsteps = 2 } +{ } diff --git a/external/mit/isl/dist/test_inputs/codegen/shift_unroll.c b/external/mit/isl/dist/test_inputs/codegen/shift_unroll.c new file mode 100644 index 000000000000..2a38286272cd --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/shift_unroll.c @@ -0,0 +1,14 @@ +for (int c0 = 0; c0 <= 9; c0 += 1) { + A(c0, 0); + A(c0, 1); + A(c0, 2); + A(c0, 3); + A(c0, 4); + A(c0, 5); + A(c0, 6); + A(c0, 7); + A(c0, 8); + A(c0, 9); + for (int c2 = 0; c2 <= 9; c2 += 1) + B(c0, c2); +} diff --git a/external/mit/isl/dist/test_inputs/codegen/shift_unroll.in b/external/mit/isl/dist/test_inputs/codegen/shift_unroll.in new file mode 100644 index 000000000000..4b773c27ac31 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/shift_unroll.in @@ -0,0 +1,3 @@ +{ A[i,j] -> [2i,0,j]: 0 <= i,j < 10; B[i,j] -> [2i+1,1,j] : 0 <= i,j < 10 } +{ : } +{ [i,0,j] -> unroll[2] } diff --git a/external/mit/isl/dist/test_inputs/codegen/single_valued.c b/external/mit/isl/dist/test_inputs/codegen/single_valued.c new file mode 100644 index 000000000000..e071002b79d3 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/single_valued.c @@ -0,0 +1,2 @@ +if (2 * ((t1 - 1) % 64) + 8 >= t1) + S(-(2 * ((t1 - 1) % 64)) + t1 + 126); diff --git a/external/mit/isl/dist/test_inputs/codegen/single_valued.in b/external/mit/isl/dist/test_inputs/codegen/single_valued.in new file mode 100644 index 000000000000..d729942077e2 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/single_valued.in @@ -0,0 +1,5 @@ +# Check that isl recognizes that the inverse schedule is single-valued +# and does not end up in an infinite recursion. +[t1] -> {S[c2] -> [c2]: t1 <= c2 <= 134 and (c2+t1) % 128 = 0 and c2 > 0} +[t1] -> {: t1 > 0} +[t1] -> {} diff --git a/external/mit/isl/dist/test_inputs/codegen/sor1d-part.c b/external/mit/isl/dist/test_inputs/codegen/sor1d-part.c new file mode 100644 index 000000000000..096d34d11200 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/sor1d-part.c @@ -0,0 +1,3 @@ +for (int c0 = 1; c0 < max((6 * M + 3 * N + 188) / 200 - 2, (N + 93) / 100 + 3 * ((2 * M + N - 4) / 200) - 1); c0 += 1) + for (int c1 = max(0, floord(-N + 100 * c0 + 106, 300)); c1 <= min((2 * M + N - 4) / 200 - 1, (c0 - 1) / 3); c1 += 1) + S2(c0 - c1, c1); diff --git a/external/mit/isl/dist/test_inputs/codegen/sor1d-part.st b/external/mit/isl/dist/test_inputs/codegen/sor1d-part.st new file mode 100644 index 000000000000..9bbf3d32639f --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/sor1d-part.st @@ -0,0 +1,10 @@ +# Check that a proper upper bound is generated for the outer loop. +# Earlier versions of isl would generate an incorrect bound. +domain: "[M, N] -> { S2[i0, i1] : i1 >= 0 and 200i1 >= -193 - N + 100i0 and i0 >= 0 and 200i1 <= -204 + 2M + N and 2i1 <= -1 + i0 and 100i1 >= -94 - N + 50i0 and 100i1 >= -94 - N }" +child: + context: "[M, N] -> { [] : M >= 0 and N >= 4 }" + child: + schedule: "[M, N] -> [{ S2[i0, i1] -> [(i0 + i1)]}]" + options: "[M, N] -> { separate[i0] }" + child: + schedule: "[M, N] -> [{ S2[i0, i1] -> [(i1)]}]" diff --git a/external/mit/isl/dist/test_inputs/codegen/stride.c b/external/mit/isl/dist/test_inputs/codegen/stride.c new file mode 100644 index 000000000000..5b688292cc51 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/stride.c @@ -0,0 +1,6 @@ +for (int c0 = 0; c0 <= 100; c0 += 2) { + for (int c3 = 0; c3 <= 100; c3 += 1) + A(c0, c3); + for (int c2 = 0; c2 <= 100; c2 += 1) + B(c0, c2); +} diff --git a/external/mit/isl/dist/test_inputs/codegen/stride.in b/external/mit/isl/dist/test_inputs/codegen/stride.in new file mode 100644 index 000000000000..b01c56617d7b --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/stride.in @@ -0,0 +1,6 @@ +# Check that we find a common stride on the first dimension +# even if it is imposed by different inner dimensions +{ A[i,k] -> [i,0,j,k] : 0 <= i,k <= 100 and i = 2 j; + B[i,k] -> [i,1,k,j] : 0 <= i,k <= 100 and i = 2 j } +{ : } +{ } diff --git a/external/mit/isl/dist/test_inputs/codegen/stride5.c b/external/mit/isl/dist/test_inputs/codegen/stride5.c new file mode 100644 index 000000000000..5954439dd364 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/stride5.c @@ -0,0 +1,3 @@ +if (n % 2 == 0) + for (int c0 = (-n / 2) + 2 * floord(n - 1, 4) + 2; c0 <= 100; c0 += 2) + S(c0); diff --git a/external/mit/isl/dist/test_inputs/codegen/stride5.in b/external/mit/isl/dist/test_inputs/codegen/stride5.in new file mode 100644 index 000000000000..a67a80276e4f --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/stride5.in @@ -0,0 +1,3 @@ +[n] -> { S[t] -> [t] : exists e : 2 t - n = 4e and 0 <= t <= 100 } +[n] -> { : } +{ } diff --git a/external/mit/isl/dist/test_inputs/codegen/stride6.c b/external/mit/isl/dist/test_inputs/codegen/stride6.c new file mode 100644 index 000000000000..c09e8b5441fc --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/stride6.c @@ -0,0 +1,4 @@ +for (int c1 = -1024; c1 <= 0; c1 += 32) + for (int c2 = max(-((niter - 1) % 32) + niter - 1, -((niter - c1) % 32) + niter - c1 - 32); c2 <= min(niter + 1022, niter - c1 - 1); c2 += 32) + for (int c5 = max(max(0, -c1 - 1023), niter - c1 - c2 - 32); c5 <= min(min(31, -c1), niter - c1 - c2 - 1); c5 += 1) + S_4(niter - 1, -c1 - c5); diff --git a/external/mit/isl/dist/test_inputs/codegen/stride6.in b/external/mit/isl/dist/test_inputs/codegen/stride6.in new file mode 100644 index 000000000000..86ca54a92c6b --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/stride6.in @@ -0,0 +1,3 @@ +[niter] -> { S_4[-1 + niter, i] -> [o0, o1, o2, o3, o4, o5, o6, o7, 4] : exists (e0 = [(o0)/32], e1 = [(o1)/32], e2 = [(o2)/32], e3 = [(o3)/32], e4 = [(-31i + o5)/32], e5 = [(-i - o4 + o6)/32], e6 = [(-o4 + o7)/32], e7 = [(-1 + niter - o4)/32]: 32e0 = o0 and 32e1 = o1 and 32e2 = o2 and 32e3 = o3 and 32e4 = -31i + o5 and 32e5 = -i - o4 + o6 and 32e6 = -o4 + o7 and 32e7 = -1 + niter - o4 and o0 <= -1 + niter and o0 >= -32 + niter and o1 <= -i and o1 >= -31 - i and o2 <= -1 + niter + i and o2 >= -32 + niter + i and o3 <= 1023 + niter and o3 >= 992 + niter and o4 >= 0 and o4 <= 31 and o5 >= 0 and o5 <= 31 and o6 >= 0 and o6 <= 31 and o7 >= 0 and o7 <= 31 and i <= 1023 and i >= 0 and niter >= 1) } +[niter] -> { : niter <= 8192 and niter >= 1 } +[niter] -> { } diff --git a/external/mit/isl/dist/test_inputs/codegen/stride7.c b/external/mit/isl/dist/test_inputs/codegen/stride7.c new file mode 100644 index 000000000000..16fb2160e13b --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/stride7.c @@ -0,0 +1,6 @@ +for (int c0 = 2; c0 <= 100; c0 += 64) + for (int c2 = c0 - 1; c2 <= 120; c2 += 1) + s2(c0, c2); +for (int c0 = 66; c0 <= 200; c0 += 64) + for (int c2 = 122; c2 <= c0 + 62; c2 += 1) + s4(c0, c2); diff --git a/external/mit/isl/dist/test_inputs/codegen/stride7.in b/external/mit/isl/dist/test_inputs/codegen/stride7.in new file mode 100644 index 000000000000..cac9caca480f --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/stride7.in @@ -0,0 +1,7 @@ +# Check that no redundant guards are introduced +{ s4[a, b] -> [a, 2, b] : exists (e0 = floor((-2 + a)/64): + 64e0 = -2 + a and a <= 200 and b <= 62 + a and b >= 122); + s2[a, b] -> [a, 2, b] : exists (e0 = floor((-2 + a)/64): + 64e0 = -2 + a and a >= 2 and b <= 120 and b >= -1 + a and a <= 100) } +{ : } +{ } diff --git a/external/mit/isl/dist/test_inputs/codegen/unroll.c b/external/mit/isl/dist/test_inputs/codegen/unroll.c new file mode 100644 index 000000000000..73db38d67cd0 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/unroll.c @@ -0,0 +1,3 @@ +A(0); +A(100000000); +A(200000000); diff --git a/external/mit/isl/dist/test_inputs/codegen/unroll.in b/external/mit/isl/dist/test_inputs/codegen/unroll.in new file mode 100644 index 000000000000..65561e2b8de2 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/unroll.in @@ -0,0 +1,5 @@ +# Test that unrolling takes into account stride constraints. +# If it didn't, it would run essentially forever on this example. +[n] -> { A[i] -> [i] : exists a : i = 100000000 a and 0 <= a <= 2 } +{:} +{ [i] -> unroll[0] } diff --git a/external/mit/isl/dist/test_inputs/codegen/unroll10.c b/external/mit/isl/dist/test_inputs/codegen/unroll10.c new file mode 100644 index 000000000000..061954ef628b --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/unroll10.c @@ -0,0 +1,29 @@ +if (m >= 1 && n >= 1) { + A(0); + if (m >= 2 && n >= 2) { + A(1); + if (m >= 3 && n >= 3) { + A(2); + if (m >= 4 && n >= 4) { + A(3); + if (m >= 5 && n >= 5) { + A(4); + if (m >= 6 && n >= 6) { + A(5); + if (m >= 7 && n >= 7) { + A(6); + if (m >= 8 && n >= 8) { + A(7); + if (m >= 9 && n >= 9) { + A(8); + if (m >= 10 && n >= 10) + A(9); + } + } + } + } + } + } + } + } +} diff --git a/external/mit/isl/dist/test_inputs/codegen/unroll10.in b/external/mit/isl/dist/test_inputs/codegen/unroll10.in new file mode 100644 index 000000000000..5890c4eaaa05 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/unroll10.in @@ -0,0 +1,4 @@ +# Check that all information is taken into account while trying to unroll +[m,n] -> { A[i] -> [i] : 0 <= i < n,m } +[m,n] -> { : m <= 10 or n <= 10 } +{ [i] -> unroll[x] } diff --git a/external/mit/isl/dist/test_inputs/codegen/unroll10.st b/external/mit/isl/dist/test_inputs/codegen/unroll10.st new file mode 100644 index 000000000000..77c5b19f27df --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/unroll10.st @@ -0,0 +1,7 @@ +# Check that all information is taken into account while trying to unroll +domain: "[m,n] -> { A[i] : 0 <= i < n,m }" +child: + context: "[m,n] -> { [] : m <= 10 or n <= 10 }" + child: + schedule: "[{ A[i] -> [i] }]" + options: "{ unroll[x] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/unroll11.c b/external/mit/isl/dist/test_inputs/codegen/unroll11.c new file mode 100644 index 000000000000..05e47395d19d --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/unroll11.c @@ -0,0 +1,6 @@ +if (t1 >= 126) + S(0, t1 - 384); +S(0, t1 - 256); +if (t1 >= 126) + S(1, t1 - 384); +S(1, t1 - 256); diff --git a/external/mit/isl/dist/test_inputs/codegen/unroll11.in b/external/mit/isl/dist/test_inputs/codegen/unroll11.in new file mode 100644 index 000000000000..79445e20dce0 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/unroll11.in @@ -0,0 +1,10 @@ +# Check that the most appropriate lower bound is selected +[t1,t2]->{ S[i,j] -> [i,j] : exists (alpha, beta : + 0 <= i <= 1 && + t1 = j+128alpha && + 0 <= j+2beta < 128 && + 510 <= t2+2beta <= 514 && + 0 <= 2beta - t2 <= 5 +)} +[t1,t2] -> {: 125 <= t1 <= 127 and 254 <= t2 < 257} +{[i,j] -> unroll[x]} diff --git a/external/mit/isl/dist/test_inputs/codegen/unroll2.c b/external/mit/isl/dist/test_inputs/codegen/unroll2.c new file mode 100644 index 000000000000..0e0ff1f6b36a --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/unroll2.c @@ -0,0 +1,9 @@ +A(0); +A(1); +A(2); +A(3); +for (int c0 = 4; c0 <= 99996; c0 += 1) + A(c0); +A(99997); +A(99998); +A(99999); diff --git a/external/mit/isl/dist/test_inputs/codegen/unroll2.in b/external/mit/isl/dist/test_inputs/codegen/unroll2.in new file mode 100644 index 000000000000..0fb36ab06dc1 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/unroll2.in @@ -0,0 +1,5 @@ +# Check that the different disjuncts in the unroll option +# are handled separately. +{ A[i] -> [i] : 0 <= i < 100000 } +{ : } +{ [i] -> unroll[0] : i < 4 or i > 99996 } diff --git a/external/mit/isl/dist/test_inputs/codegen/unroll3.c b/external/mit/isl/dist/test_inputs/codegen/unroll3.c new file mode 100644 index 000000000000..f6f390d3dd22 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/unroll3.c @@ -0,0 +1,2 @@ +if ((t1 + 121) % 128 <= 123) + write_shared_A(((t1 + 121) % 128) + 1); diff --git a/external/mit/isl/dist/test_inputs/codegen/unroll3.in b/external/mit/isl/dist/test_inputs/codegen/unroll3.in new file mode 100644 index 000000000000..098e5010577c --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/unroll3.in @@ -0,0 +1,6 @@ +# Check that the entire schedule is completely unrolled and +# in particular that no spurious loop is introduced. +[t1] -> { write_shared_A[i2] -> [1, 3, 6 + i2, 0, t1] : (exists (e0 = [(-6 + t1 - i2)/128]: 128e0 = -6 + t1 - i2 and i2 <= 122 and i2 >= 1 and t1 >= 0 and t1 <= 127)) or (exists (e0 = [(-6 + t1 - i2)/128]: 128e0 = -6 + t1 - i2 and i2 >= 123 and i2 <= 124 and t1 <= 127 and t1 >= 0 )) } +[t1] -> { : t1 >= 0 and t1 <= 127 } +[t1] -> { [i0, i1, i2, i3, i4] -> unroll[o0] } + diff --git a/external/mit/isl/dist/test_inputs/codegen/unroll4.c b/external/mit/isl/dist/test_inputs/codegen/unroll4.c new file mode 100644 index 000000000000..582fde37c890 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/unroll4.c @@ -0,0 +1,14 @@ +write_shared_A(3, ((t1 + 3) % 4) + 1, ((t2 + 31) % 32) + 1); +if (t2 >= 1 && t2 <= 2 && t1 % 3 == 0) + write_shared_A(3, (-t1 / 3) + 4, t2 + 32); +if (((t1 + 3) % 4) + 1 >= t2 || t2 >= ((t1 + 3) % 4) + ((t2 + 1) % 2) + 2) + write_shared_A(3, ((t1 + 3) % 4) + 5, -((((t1 + 3) % 4) - t2 + 33) % 32) + t1 + 4 * ((-t1 + 4) / 4) + 32); +if (t1 >= 1 && t2 >= t1 + 1 && t2 <= 4) + write_shared_A(3, t1 + 4, t2 + 32); +write_shared_A(4, ((t1 + 3) % 4) + 1, ((t2 + 31) % 32) + 1); +if (t2 >= 1 && t2 <= 2 && t1 % 3 == 0) + write_shared_A(4, (-t1 / 3) + 4, t2 + 32); +if (((t1 + 3) % 4) + 1 >= t2 || t2 >= ((t1 + 3) % 4) + ((t2 + 1) % 2) + 2) + write_shared_A(4, ((t1 + 3) % 4) + 5, -((((t1 + 3) % 4) - t2 + 33) % 32) + t1 + 4 * ((-t1 + 4) / 4) + 32); +if (t1 >= 1 && t2 >= t1 + 1 && t2 <= 4) + write_shared_A(4, t1 + 4, t2 + 32); diff --git a/external/mit/isl/dist/test_inputs/codegen/unroll4.in b/external/mit/isl/dist/test_inputs/codegen/unroll4.in new file mode 100644 index 000000000000..d8be866f9484 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/unroll4.in @@ -0,0 +1,5 @@ +# Check that the generated code does not contain two declarations +# of the same variable in the same scope. +[t1, t2, g] -> { write_shared_A[a, b, c] -> [0, a, b, c] : exists (e0, e1 = [(-t1 + b)/4], e2 = [(-t2 + c)/32]: 4e1 = -t1 + b and 32e2 = -t2 + c and e0 <= 2 + 3g and e0 >= 3g and a <= 4 and a >= 3 and t2 >= 0 and t1 <= 3 and 2e0 >= 5 - c + 6g and 2e0 <= 36 - c + 6g and 2e0 >= 5 - b + 6g and 2e0 <= 8 - b + 6g and 2e0 <= 638 - c and 2e0 <= 638 - b and 2e0 >= 2 - a + 6g and 2e0 >= -8 + a + 6g and 2e0 <= 1 + a + 6g and 2e0 <= 11 - a + 6g and e0 >= 0 and e0 <= 254 and t1 >= 0 and t2 <= 31 and b >= 1 and b <= 126 and c >= 1 and c <= 126 and g <= 3 and g >= 0) } +[t1, t2, g] -> { : g <= 3 and g >= 0 and t1 >= 0 and t1 <= 3 and t2 >= 0 and t2 <= 5 } +[t1, t2] -> { [i0, i1, i2, i3] -> unroll[x] } diff --git a/external/mit/isl/dist/test_inputs/codegen/unroll6.c b/external/mit/isl/dist/test_inputs/codegen/unroll6.c new file mode 100644 index 000000000000..97563c6d233a --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/unroll6.c @@ -0,0 +1,6 @@ +if (g >= 0 && nn >= 128 * g + 6 && nn >= ((t1 + 127) % 128) + 128 * g + 3) + for (int c1 = 393214; c1 < nn - 1; c1 += 393216) + A(c1, ((t1 + 127) % 128) + 128 * g + 1, ((t1 + 127) % 128) + 1); +if (t1 >= 1 && t1 <= 2 && nn >= t1 + 128 * g + 130 && t1 + 128 * g >= -127) + for (int c1 = 393214; c1 < nn - 1; c1 += 393216) + A(c1, t1 + 128 * g + 128, t1 + 128); diff --git a/external/mit/isl/dist/test_inputs/codegen/unroll6.in b/external/mit/isl/dist/test_inputs/codegen/unroll6.in new file mode 100644 index 000000000000..b4338e331f98 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/unroll6.in @@ -0,0 +1,7 @@ +# Check that the right lower bound is chosen for unrolling. +# Older versions of isl would pick a lower bound that resulted +# in a number of slices that exceeds the maximal value of an integer +# and then only generated code for a truncated number (zero) of slices. +[nn, t1, g] -> { A[a, b, c] -> [c] : exists (e0 = [(2 + a)/393216], e1 = [(t1 - c)/128]: 128g = b - c and 393216e0 = 2 + a and 128e1 = t1 - c and c <= 130 and c >= 6 - nn + b and c <= 128 + b and nn >= 137 and t1 >= 0 and c >= 1 and a <= -2 + nn and a >= 1 and nn <= 9223372036854775807 and b >= 1 and b <= -2 + nn and t1 <= 127) } +[nn, t1, g] -> { : nn <= 9223372036854775807 and nn >= 137 and t1 >= 0 and t1 <= 127 } +{ [c] -> unroll[x] } diff --git a/external/mit/isl/dist/test_inputs/codegen/unroll7.c b/external/mit/isl/dist/test_inputs/codegen/unroll7.c new file mode 100644 index 000000000000..a7b4441ec2ca --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/unroll7.c @@ -0,0 +1,8 @@ +S(0, 0); +S(0, 3); +S(0, 4); +S(1, 1); +S(1, 4); +S(2, 2); +S(3, 3); +S(4, 4); diff --git a/external/mit/isl/dist/test_inputs/codegen/unroll7.in b/external/mit/isl/dist/test_inputs/codegen/unroll7.in new file mode 100644 index 000000000000..494e5975564b --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/unroll7.in @@ -0,0 +1,5 @@ +# Check that some code is generated. +# Older versions of isl would abort on unknown divs. +{ S[i,j] -> [i,j]: exists (alpha, beta: j=i+4alpha +3beta and 0 <= alpha < 24 and 0 <= beta and 0 <= i,j < 5) } +{ : } +{ [i,j] -> unroll[x] } diff --git a/external/mit/isl/dist/test_inputs/codegen/unroll8.c b/external/mit/isl/dist/test_inputs/codegen/unroll8.c new file mode 100644 index 000000000000..b3ca142d944c --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/unroll8.c @@ -0,0 +1,6 @@ +for (int c0 = 0; c0 <= 99; c0 += 1) { + A(c0, 0); + A(c0, 1); + B(c0, 0); + B(c0, 1); +} diff --git a/external/mit/isl/dist/test_inputs/codegen/unroll8.st b/external/mit/isl/dist/test_inputs/codegen/unroll8.st new file mode 100644 index 000000000000..94fb49ea1e7b --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/unroll8.st @@ -0,0 +1,5 @@ +# Check that options are adjusted by shifted stride detection +domain: "{ A[i,j] : 0 <= i < 100 and 0 <= j < 2; B[i,j] : 0 <= i < 100 and 0 <= j < 2 }" +child: + schedule: "[{ A[i,j] -> [2i]; B[i,j] -> [2i+1] }, { A[i,j] -> [j]; B[i,j] -> [j]}]" + options: "{ unroll[1] }" diff --git a/external/mit/isl/dist/test_inputs/codegen/unroll9.c b/external/mit/isl/dist/test_inputs/codegen/unroll9.c new file mode 100644 index 000000000000..b00ea41d44e2 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/unroll9.c @@ -0,0 +1,7 @@ +for (int c0 = 0; c0 <= 99; c0 += 1) + for (int c1 = 0; c1 <= 99; c1 += 1) { + A(c1, 0, c0); + A(c1, 1, c0); + B(c1, 0, c0); + B(c1, 1, c0); + } diff --git a/external/mit/isl/dist/test_inputs/codegen/unroll9.st b/external/mit/isl/dist/test_inputs/codegen/unroll9.st new file mode 100644 index 000000000000..653da415eb73 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/codegen/unroll9.st @@ -0,0 +1,7 @@ +# Check that options are interpreted locally +domain: "{ A[i,j,k] : 0 <= i,k < 100 and 0 <= j < 2; B[i,j,k] : 0 <= i,k < 100 and 0 <= j < 2 }" +child: + schedule: "[{ A[i,j,k] -> [k]; B[i,j,k] -> [k] }]" + child: + schedule: "[{ A[i,j,k] -> [2i]; B[i,j,k] -> [2i+1] }, { A[i,j,k] -> [j]; B[i,j,k] -> [j]}]" + options: "{ unroll[1] }" diff --git a/external/mit/isl/dist/test_inputs/convex0.polylib b/external/mit/isl/dist/test_inputs/convex0.polylib new file mode 100644 index 000000000000..cbc4d3b6cebe --- /dev/null +++ b/external/mit/isl/dist/test_inputs/convex0.polylib @@ -0,0 +1,11 @@ +2 3 +1 1 0 +1 -1 1 + +2 3 +1 1 -1 +1 -1 2 + +2 3 +1 1 0 +1 -1 2 diff --git a/external/mit/isl/dist/test_inputs/convex1.polylib b/external/mit/isl/dist/test_inputs/convex1.polylib new file mode 100644 index 000000000000..b563d8de7fff --- /dev/null +++ b/external/mit/isl/dist/test_inputs/convex1.polylib @@ -0,0 +1,17 @@ +# {j,N | 0<=j<=N-1; 2<=N} +4 4 +1 1 0 0 +1 -1 1 -1 +1 0 1 -2 +1 0 0 1 +# {j, N | 1<=j<=N; 1<=N} +4 4 +1 1 0 -1 +1 -1 1 0 +1 0 1 -1 +1 0 0 1 +# {j,N | 0<=j<=N; 2<=j+N} +3 4 + 1 1 1 -2 + 1 1 0 0 + 1 -1 1 0 diff --git a/external/mit/isl/dist/test_inputs/convex10.polylib b/external/mit/isl/dist/test_inputs/convex10.polylib new file mode 100644 index 000000000000..3d58cbf70e13 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/convex10.polylib @@ -0,0 +1,17 @@ +3 4 +1 54 1 -4 +1 2 -1 58 +1 0 -1 6 + +4 4 +1 54 1 -4 +1 2 -1 58 +1 0 1 -7 +1 -4 1 0 + +4 4 +1 54 1 -4 +1 2 -1 58 +1 0 -1 116 +1 0 0 1 + diff --git a/external/mit/isl/dist/test_inputs/convex11.polylib b/external/mit/isl/dist/test_inputs/convex11.polylib new file mode 100644 index 000000000000..f664114d0487 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/convex11.polylib @@ -0,0 +1,14 @@ +3 4 +1 0 -1 6 +1 -1 1 1 +1 1 1 -10 + +3 4 +1 1 0 -4 +1 -1 -1 8 +1 -1 1 1 + +3 4 +1 0 -1 6 +1 1 0 -4 +1 -1 1 1 diff --git a/external/mit/isl/dist/test_inputs/convex12.polylib b/external/mit/isl/dist/test_inputs/convex12.polylib new file mode 100644 index 000000000000..e4766307477b --- /dev/null +++ b/external/mit/isl/dist/test_inputs/convex12.polylib @@ -0,0 +1,12 @@ +3 5 +1 0 0 1 1 +1 0 1 0 1 +1 -1 -1 0 -2 + +3 5 +1 0 0 1 2 +1 1 -1 0 0 +1 1 0 0 -1 + +1 5 +1 0 0 1 2 diff --git a/external/mit/isl/dist/test_inputs/convex13.polylib b/external/mit/isl/dist/test_inputs/convex13.polylib new file mode 100644 index 000000000000..1b3591200f80 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/convex13.polylib @@ -0,0 +1,17 @@ +3 5 +1 0 0 -1 3 +1 0 -1 0 2 +1 1 1 1 -4 + +3 5 +1 0 0 1 0 +1 1 0 0 -1 +1 1 2 0 1 + +6 5 +1 3 2 0 -1 +1 3 0 2 -3 +1 1 0 1 -1 +1 1 1 1 0 +1 1 1 0 0 +1 1 0 0 1 diff --git a/external/mit/isl/dist/test_inputs/convex14.polylib b/external/mit/isl/dist/test_inputs/convex14.polylib new file mode 100644 index 000000000000..caaa8f5d3169 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/convex14.polylib @@ -0,0 +1,14 @@ +3 4 +0 1 0 2 +1 0 1 0 +1 0 -1 2 + +3 4 +1 1 0 0 +1 0 1 0 +1 0 -1 2 + +3 4 +1 1 0 2 +1 0 1 0 +1 0 -1 2 diff --git a/external/mit/isl/dist/test_inputs/convex15.polylib b/external/mit/isl/dist/test_inputs/convex15.polylib new file mode 100644 index 000000000000..0118fa861dbf --- /dev/null +++ b/external/mit/isl/dist/test_inputs/convex15.polylib @@ -0,0 +1,66 @@ +17 8 +1 -1 -8 0 16 0 0 37 +1 1 0 -48 0 2 0 -3 +1 0 -16 -32 16 1 0 14 +1 -1 24 0 0 1 0 18 +1 -1 8 16 0 0 1 21 +1 0 0 -16 0 1 1 -2 +1 1 32 16 -32 0 0 -1 +1 -1 16 16 0 0 0 28 +1 1 -8 -32 0 1 0 -1 +1 0 0 0 0 1 0 -1 +1 0 16 16 -16 0 1 -1 +1 1 8 0 -16 0 0 0 +1 0 3 2 -2 0 0 0 +1 0 1 2 -1 0 0 0 +1 0 -1 -1 1 0 0 0 +1 -1 8 0 0 1 2 4 +1 -1 -24 -32 32 1 0 36 + +13 8 +1 -1 0 0 0 1 3 -4 +1 1 0 -48 0 2 0 -2 +1 0 0 0 0 1 0 -1 +1 0 -8 0 0 0 1 -1 +1 0 3 2 -2 0 0 0 +1 1 -16 -16 0 0 0 0 +1 1 -24 0 0 0 0 0 +1 0 1 0 0 0 0 0 +1 0 -3 -2 2 0 0 1 +1 -1 0 16 0 0 2 13 +1 -1 24 0 0 1 0 20 +1 -1 16 16 0 0 0 29 +1 -1 0 48 0 0 0 45 + +31 8 + 1 0 1 0 0 0 0 0 + 1 0 0 -16 0 1 1 -2 + 1 0 0 0 0 1 0 -1 + 1 -1 8 0 0 1 2 4 + 1 0 3 2 -2 0 0 0 + 1 -1 24 0 0 1 0 20 + 1 1 0 -48 0 2 0 -2 + 1 -1 -24 -32 32 1 0 36 + 1 0 0 0 0 0 1 -1 + 1 -1 24 64 -16 0 0 45 + 1 -15 120 112 0 15 38 52 + 1 1 24 32 -32 0 0 0 + 1 0 -2 -2 2 0 0 1 + 1 -1 8 16 0 0 1 21 + 1 -15 120 352 0 0 23 307 + 1 1 -8 -32 0 1 0 -1 + 1 1 -8 0 0 0 0 0 + 1 1 -8 -16 0 0 0 0 + 1 0 16 16 -16 0 1 -1 + 1 -1 16 16 0 0 0 29 + 1 -1 -8 0 16 0 0 37 + 1 -1 8 32 0 0 0 37 + 1 1 8 0 -16 0 0 0 + 1 -15 360 592 -240 0 23 307 + 1 -1 -6 2 14 0 2 20 + 1 -15 360 352 -240 15 38 52 + 1 -1 8 48 0 0 0 45 + 1 0 -16 -32 16 1 0 14 + 1 -1 -6 -14 14 1 3 3 + 1 1 -38 -78 30 2 0 13 + 1 1 -3 -50 2 2 0 -1 diff --git a/external/mit/isl/dist/test_inputs/convex2.polylib b/external/mit/isl/dist/test_inputs/convex2.polylib new file mode 100644 index 000000000000..0bfd737291c9 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/convex2.polylib @@ -0,0 +1,24 @@ +# {i,j,N | 1<=i<=N; 0<=j<=N-1; 2<=N} +6 5 +1 1 0 0 -1 +1 -1 0 1 0 +1 0 1 0 0 +1 0 -1 1 -1 +1 0 0 1 -2 +1 0 0 0 1 +# {i,j,N | 1<=i<=N; 1<=j<=N; 2<=N} +6 5 +1 1 0 0 -1 +1 -1 0 1 0 +1 0 1 0 -1 +1 0 -1 1 0 +1 0 0 1 -2 +1 0 0 0 1 +# {i,j,N | 1<=i<=N; 0<=j<=N; 2<=N} +6 5 + 1 0 0 1 -2 + 1 -1 0 1 0 + 1 0 -1 1 0 + 1 1 0 0 -1 + 1 0 1 0 0 + 1 0 0 0 1 diff --git a/external/mit/isl/dist/test_inputs/convex3.polylib b/external/mit/isl/dist/test_inputs/convex3.polylib new file mode 100644 index 000000000000..ea612c6b81f8 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/convex3.polylib @@ -0,0 +1,10 @@ +1 4 +1 1 1 -6 + +3 4 +1 1 1 -3 +1 1 0 -5 +1 -1 0 10 + +1 4 +1 1 1 -3 diff --git a/external/mit/isl/dist/test_inputs/convex4.polylib b/external/mit/isl/dist/test_inputs/convex4.polylib new file mode 100644 index 000000000000..0c086538a66d --- /dev/null +++ b/external/mit/isl/dist/test_inputs/convex4.polylib @@ -0,0 +1,9 @@ +1 4 +1 1 1 -6 + +2 4 +0 1 0 -1 +0 0 1 -4 + +1 4 +1 1 1 -5 diff --git a/external/mit/isl/dist/test_inputs/convex5.polylib b/external/mit/isl/dist/test_inputs/convex5.polylib new file mode 100644 index 000000000000..3aae7c26bcfc --- /dev/null +++ b/external/mit/isl/dist/test_inputs/convex5.polylib @@ -0,0 +1,12 @@ +2 4 +0 1 0 -2 +0 0 1 -6 + +2 4 +0 1 0 -1 +0 0 1 -4 + +3 4 +0 -2 1 -2 +1 1 0 -1 +1 -1 0 2 diff --git a/external/mit/isl/dist/test_inputs/convex6.polylib b/external/mit/isl/dist/test_inputs/convex6.polylib new file mode 100644 index 000000000000..1bdb4e1c9dd2 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/convex6.polylib @@ -0,0 +1,17 @@ +3 4 +1 1 1 -2 +1 -1 1 2 +1 0 -1 2 + +3 4 +1 0 1 -1 +1 1 -1 1 +1 -1 -1 5 + +6 4 +1 -1 0 4 +1 1 0 0 +1 1 2 -2 +1 -1 2 2 +1 1 -2 4 +1 -1 -2 8 diff --git a/external/mit/isl/dist/test_inputs/convex7.polylib b/external/mit/isl/dist/test_inputs/convex7.polylib new file mode 100644 index 000000000000..70eb483175bc --- /dev/null +++ b/external/mit/isl/dist/test_inputs/convex7.polylib @@ -0,0 +1,9 @@ +1 4 +0 0 1 0 + +2 4 +1 1 -1 1 +1 -1 -1 1 + +1 4 +1 0 -1 1 diff --git a/external/mit/isl/dist/test_inputs/convex8.polylib b/external/mit/isl/dist/test_inputs/convex8.polylib new file mode 100644 index 000000000000..ea1b757108c4 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/convex8.polylib @@ -0,0 +1,24 @@ +4 5 +1 1 1 1 0 +1 0 -1 0 0 +1 -1 0 0 2 +1 1 1 -1 0 + +4 5 +1 -1 1 0 2 +1 1 -2 -2 -1 +1 -1 0 2 3 +1 1 0 0 -1 + +10 5 +1 1 0 1 0 +1 1 1 0 0 +1 0 1 1 2 +1 -3 1 -1 8 +1 -3 1 1 8 +1 0 1 -1 2 +1 1 0 -1 0 +1 1 -2 -1 0 +1 -1 -3 2 6 +1 1 -5 -2 2 + diff --git a/external/mit/isl/dist/test_inputs/convex9.polylib b/external/mit/isl/dist/test_inputs/convex9.polylib new file mode 100644 index 000000000000..f68fca097a9a --- /dev/null +++ b/external/mit/isl/dist/test_inputs/convex9.polylib @@ -0,0 +1,14 @@ +4 4 +1 1 0 0 +1 -1 0 1 +1 0 1 0 +1 0 -1 10 + +2 4 +1 1 0 -10 +0 0 -1 5 + +3 4 +1 1 0 0 +1 0 1 0 +1 0 -1 10 diff --git a/external/mit/isl/dist/test_inputs/devos.pwqp b/external/mit/isl/dist/test_inputs/devos.pwqp new file mode 100644 index 000000000000..b4525446904b --- /dev/null +++ b/external/mit/isl/dist/test_inputs/devos.pwqp @@ -0,0 +1 @@ +[U] -> { [i0] -> ((1/3 * U + 2/3 * i0) - [(U + 2i0)/3]) : 2i0 >= -3 - U and 2i0 <= -U and U >= 0 and U <= 10 } diff --git a/external/mit/isl/dist/test_inputs/equality1.pwqp b/external/mit/isl/dist/test_inputs/equality1.pwqp new file mode 100644 index 000000000000..eb16a4ba7b85 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/equality1.pwqp @@ -0,0 +1 @@ +[n] -> { [x] -> 1 + [(x+1)/3] : exists a : x = 3a +1 && 0 <= x <= n } diff --git a/external/mit/isl/dist/test_inputs/equality2.pwqp b/external/mit/isl/dist/test_inputs/equality2.pwqp new file mode 100644 index 000000000000..1629a6549ea9 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/equality2.pwqp @@ -0,0 +1 @@ +[n] -> { [x,y] -> x^2 * y : n = 2x + 4y and 0 <= x,y <= 10 } diff --git a/external/mit/isl/dist/test_inputs/equality3.pwqp b/external/mit/isl/dist/test_inputs/equality3.pwqp new file mode 100644 index 000000000000..c6f8c3acf19b --- /dev/null +++ b/external/mit/isl/dist/test_inputs/equality3.pwqp @@ -0,0 +1 @@ +[m,n] -> { [x,y] -> x^2 * y : n = 2x + 4y and 0 <= x,y <= 10 and 3 n = 5 m } diff --git a/external/mit/isl/dist/test_inputs/equality4.pwqp b/external/mit/isl/dist/test_inputs/equality4.pwqp new file mode 100644 index 000000000000..49da2e7eff63 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/equality4.pwqp @@ -0,0 +1 @@ +[m,n] -> { [x,y] -> x^2 * y + m + 13 * n: n = 2x + 4y and 0 <= x,y <= 10 and 3 n = 5 m } diff --git a/external/mit/isl/dist/test_inputs/equality5.pwqp b/external/mit/isl/dist/test_inputs/equality5.pwqp new file mode 100644 index 000000000000..09cb7520113f --- /dev/null +++ b/external/mit/isl/dist/test_inputs/equality5.pwqp @@ -0,0 +1 @@ +[m,n] -> { [x,y,z] -> x^2 * y + z + m + 13 * n: n = 2x + 4y and 0 <= x,y <= 10 and 3 n = 5 m and z = x + y } diff --git a/external/mit/isl/dist/test_inputs/esced.pip b/external/mit/isl/dist/test_inputs/esced.pip new file mode 100644 index 000000000000..dbf56ffa0fd6 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/esced.pip @@ -0,0 +1,27 @@ +0 2 + +-1 + +16 18 +1 0 0 0 0 0 0 0 0 -1 0 0 1 0 0 0 0 0 +1 0 0 0 0 0 0 0 0 0 -1 0 0 1 0 0 0 0 +1 0 0 0 0 0 0 0 0 0 0 -1 0 0 1 0 0 0 +1 0 0 0 0 0 0 0 0 0 0 0 0 1 -1 0 0 0 +1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 +1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 + + +0 0 0 0 -1 0 0 0 0 1 -1 0 0 0 0 0 0 0 +0 0 0 0 0 -1 0 0 0 0 0 1 0 0 0 0 0 0 + +0 -1 0 0 0 0 0 0 0 0 1 -1 0 0 0 0 0 0 + +0 0 0 0 0 0 -1 0 0 0 0 0 1 -1 0 -1 0 0 +0 0 0 0 0 0 0 -1 0 0 0 0 0 0 1 0 0 0 +0 0 0 0 0 0 0 0 -1 0 0 0 0 0 0 0 1 0 + +0 0 0 0 0 0 0 0 0 0 0 0 0 1 -1 0 0 0 +0 0 -1 0 0 0 0 0 0 0 0 0 0 0 0 1 -1 0 + +1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -1 +1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 -1 diff --git a/external/mit/isl/dist/test_inputs/ex.pip b/external/mit/isl/dist/test_inputs/ex.pip new file mode 100644 index 000000000000..a405450b2ade --- /dev/null +++ b/external/mit/isl/dist/test_inputs/ex.pip @@ -0,0 +1,9 @@ +1 5 +1 -1 1 1 0 + +-1 + +3 7 +1 0 -1 0 1 0 0 +1 -1 0 0 0 1 0 +1 1 1 -1 0 0 0 diff --git a/external/mit/isl/dist/test_inputs/ex2.pip b/external/mit/isl/dist/test_inputs/ex2.pip new file mode 100644 index 000000000000..bb59848c8f29 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/ex2.pip @@ -0,0 +1,9 @@ +1 5 +1 -1 1 1 0 + +-1 + +3 7 +1 0 -1 0 1 0 0 +1 -1 0 0 0 1 0 +1 1 1 -1 0 0 0 diff --git a/external/mit/isl/dist/test_inputs/exist.pip b/external/mit/isl/dist/test_inputs/exist.pip new file mode 100644 index 000000000000..3e026e5b8fc0 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/exist.pip @@ -0,0 +1,5 @@ +[n] -> { : n mod 2 = 0 } + +-1 + +[n] -> { [i] : n <= i } diff --git a/external/mit/isl/dist/test_inputs/exist2.pip b/external/mit/isl/dist/test_inputs/exist2.pip new file mode 100644 index 000000000000..441190a0937a --- /dev/null +++ b/external/mit/isl/dist/test_inputs/exist2.pip @@ -0,0 +1,5 @@ +[n, a, b] -> { : exists e : 1 <= a <= 7e and 9e <= b <= n } + +-1 + +[n, a, b] -> { [i] : n <= 2i } diff --git a/external/mit/isl/dist/test_inputs/faddeev.pwqp b/external/mit/isl/dist/test_inputs/faddeev.pwqp new file mode 100644 index 000000000000..e7db61d1bc5a --- /dev/null +++ b/external/mit/isl/dist/test_inputs/faddeev.pwqp @@ -0,0 +1 @@ +[N] -> { [i, j, k] -> (((4 + 6 * N + 2 * N^2) + (-2 - 2 * N) * j) + ((-2 - N) + j) * k) : j = 1 + i and k = 1 + i and i >= 3 and N <= 100 and i <= N and N >= 10 } diff --git a/external/mit/isl/dist/test_inputs/fimmel.pip b/external/mit/isl/dist/test_inputs/fimmel.pip new file mode 100644 index 000000000000..a6dee417c02d --- /dev/null +++ b/external/mit/isl/dist/test_inputs/fimmel.pip @@ -0,0 +1,12 @@ +0 4 + +-1 + +7 6 +1 2 6 0 0 -9 +1 5 -3 0 0 0 +1 2 -10 0 0 15 +1 -2 6 0 0 -3 +1 -2 -6 0 0 17 +1 0 1 -1 0 0 +1 1 0 0 -1 0 diff --git a/external/mit/isl/dist/test_inputs/flow/kill_loop-tree.ai b/external/mit/isl/dist/test_inputs/flow/kill_loop-tree.ai new file mode 100644 index 000000000000..835e1c05163d --- /dev/null +++ b/external/mit/isl/dist/test_inputs/flow/kill_loop-tree.ai @@ -0,0 +1,11 @@ +sink: "{ S[] -> a[] }" +must_source: "{ T[i] -> a[] : 0 <= i <= 9 }" +kill: "{ T[9] -> a[] }" +schedule: + domain: "{ T[i]; S[] }" + child: + sequence: + - filter: "{ T[i] }" + child: + schedule: "[{ T[i] -> [(i)] }]" + - filter: "{ S[] }" diff --git a/external/mit/isl/dist/test_inputs/flow/kill_loop-tree.flow b/external/mit/isl/dist/test_inputs/flow/kill_loop-tree.flow new file mode 100644 index 000000000000..ef089e543db9 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/flow/kill_loop-tree.flow @@ -0,0 +1,4 @@ +must_dependence: "{ T[i = 9] -> [S[] -> a[]] }" +may_dependence: "{ T[i = 9] -> [S[] -> a[]] }" +must_no_source: "{ }" +may_no_source: "{ }" diff --git a/external/mit/isl/dist/test_inputs/flow/kill_loop.ai b/external/mit/isl/dist/test_inputs/flow/kill_loop.ai new file mode 100644 index 000000000000..619028f2ebdd --- /dev/null +++ b/external/mit/isl/dist/test_inputs/flow/kill_loop.ai @@ -0,0 +1,4 @@ +sink: { S[] -> a[] } +must_source: { T[i] -> a[] : 0 <= i < 10 } +kill: { T[9] -> a[] } +schedule_map: { T[i] -> [0,i]; S[] -> [1,0] } diff --git a/external/mit/isl/dist/test_inputs/flow/kill_loop.flow b/external/mit/isl/dist/test_inputs/flow/kill_loop.flow new file mode 100644 index 000000000000..ef089e543db9 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/flow/kill_loop.flow @@ -0,0 +1,4 @@ +must_dependence: "{ T[i = 9] -> [S[] -> a[]] }" +may_dependence: "{ T[i = 9] -> [S[] -> a[]] }" +must_no_source: "{ }" +may_no_source: "{ }" diff --git a/external/mit/isl/dist/test_inputs/flow/kill_loop2-tree.ai b/external/mit/isl/dist/test_inputs/flow/kill_loop2-tree.ai new file mode 100644 index 000000000000..19d5ff6b4722 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/flow/kill_loop2-tree.ai @@ -0,0 +1,11 @@ +sink: "{ S[] -> a[] }" +must_source: "{ T[i] -> a[] : 0 <= i <= 9 }" +kill: "{ K[] -> a[] }" +schedule: + domain: "{ T[i]; S[]; K[] }" + child: + sequence: + - filter: "{ T[i]; K[] }" + child: + schedule: "[{ T[i] -> [(i)]; K[] -> [(10)] }]" + - filter: "{ S[] }" diff --git a/external/mit/isl/dist/test_inputs/flow/kill_loop2-tree.flow b/external/mit/isl/dist/test_inputs/flow/kill_loop2-tree.flow new file mode 100644 index 000000000000..ec75edb7bf7d --- /dev/null +++ b/external/mit/isl/dist/test_inputs/flow/kill_loop2-tree.flow @@ -0,0 +1,4 @@ +must_dependence: "{ }" +may_dependence: "{ }" +must_no_source: "{ }" +may_no_source: "{ }" diff --git a/external/mit/isl/dist/test_inputs/flow/kill_loop2.ai b/external/mit/isl/dist/test_inputs/flow/kill_loop2.ai new file mode 100644 index 000000000000..622bc2121116 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/flow/kill_loop2.ai @@ -0,0 +1,4 @@ +sink: { S[] -> a[] } +must_source: { T[i] -> a[] : 0 <= i < 10 } +kill: { K[] -> a[] } +schedule_map: { T[i] -> [0,i]; K[] -> [0,10]; S[] -> [1,0] } diff --git a/external/mit/isl/dist/test_inputs/flow/kill_loop2.flow b/external/mit/isl/dist/test_inputs/flow/kill_loop2.flow new file mode 100644 index 000000000000..ec75edb7bf7d --- /dev/null +++ b/external/mit/isl/dist/test_inputs/flow/kill_loop2.flow @@ -0,0 +1,4 @@ +must_dependence: "{ }" +may_dependence: "{ }" +must_no_source: "{ }" +may_no_source: "{ }" diff --git a/external/mit/isl/dist/test_inputs/flow/kill_loop3-tree.ai b/external/mit/isl/dist/test_inputs/flow/kill_loop3-tree.ai new file mode 100644 index 000000000000..b14325b907f1 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/flow/kill_loop3-tree.ai @@ -0,0 +1,11 @@ +sink: "{ S[] -> a[] }" +must_source: "{ T[i] -> a[] : 0 <= i <= 9 }" +kill: "{ K[] -> a[] }" +schedule: + domain: "{ T[i]; S[]; K[] }" + child: + sequence: + - filter: "{ T[i]; K[] }" + child: + schedule: "[{ T[i] -> [(i)]; K[] -> [(9)] }]" + - filter: "{ S[] }" diff --git a/external/mit/isl/dist/test_inputs/flow/kill_loop3-tree.flow b/external/mit/isl/dist/test_inputs/flow/kill_loop3-tree.flow new file mode 100644 index 000000000000..51d2e2aa5bf4 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/flow/kill_loop3-tree.flow @@ -0,0 +1,4 @@ +must_dependence: "{ }" +may_dependence: "{ T[i = 9] -> [S[] -> a[]] }" +must_no_source: "{ }" +may_no_source: "{ }" diff --git a/external/mit/isl/dist/test_inputs/flow/kill_loop3.ai b/external/mit/isl/dist/test_inputs/flow/kill_loop3.ai new file mode 100644 index 000000000000..436e13c79f82 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/flow/kill_loop3.ai @@ -0,0 +1,4 @@ +sink: { S[] -> a[] } +must_source: { T[i] -> a[] : 0 <= i < 10 } +kill: { K[] -> a[] } +schedule_map: { T[i] -> [0,i]; K[] -> [0,9]; S[] -> [1,0] } diff --git a/external/mit/isl/dist/test_inputs/flow/kill_loop3.flow b/external/mit/isl/dist/test_inputs/flow/kill_loop3.flow new file mode 100644 index 000000000000..51d2e2aa5bf4 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/flow/kill_loop3.flow @@ -0,0 +1,4 @@ +must_dependence: "{ }" +may_dependence: "{ T[i = 9] -> [S[] -> a[]] }" +must_no_source: "{ }" +may_no_source: "{ }" diff --git a/external/mit/isl/dist/test_inputs/flow/kill_may_loop-tree.ai b/external/mit/isl/dist/test_inputs/flow/kill_may_loop-tree.ai new file mode 100644 index 000000000000..9159e47aae91 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/flow/kill_may_loop-tree.ai @@ -0,0 +1,11 @@ +sink: "{ S[] -> a[] }" +may_source: "{ T[i] -> a[] : 0 <= i <= 9 }" +kill: "{ T[4] -> a[] }" +schedule: + domain: "{ T[i]; S[] }" + child: + sequence: + - filter: "{ T[i] }" + child: + schedule: "[{ T[i] -> [(i)] }]" + - filter: "{ S[] }" diff --git a/external/mit/isl/dist/test_inputs/flow/kill_may_loop-tree.flow b/external/mit/isl/dist/test_inputs/flow/kill_may_loop-tree.flow new file mode 100644 index 000000000000..7a89b0dca4dc --- /dev/null +++ b/external/mit/isl/dist/test_inputs/flow/kill_may_loop-tree.flow @@ -0,0 +1,4 @@ +must_dependence: "{ }" +may_dependence: "{ T[i] -> [S[] -> a[]] : 4 <= i <= 9 }" +must_no_source: "{ }" +may_no_source: "{ }" diff --git a/external/mit/isl/dist/test_inputs/flow/kill_may_loop.ai b/external/mit/isl/dist/test_inputs/flow/kill_may_loop.ai new file mode 100644 index 000000000000..5d197f6fc924 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/flow/kill_may_loop.ai @@ -0,0 +1,4 @@ +sink: { S[] -> a[] } +may_source: { T[i] -> a[] : 0 <= i < 10 } +kill: { T[4] -> a[] } +schedule_map: { T[i] -> [0,i]; S[] -> [1,0] } diff --git a/external/mit/isl/dist/test_inputs/flow/kill_may_loop.flow b/external/mit/isl/dist/test_inputs/flow/kill_may_loop.flow new file mode 100644 index 000000000000..7a89b0dca4dc --- /dev/null +++ b/external/mit/isl/dist/test_inputs/flow/kill_may_loop.flow @@ -0,0 +1,4 @@ +must_dependence: "{ }" +may_dependence: "{ T[i] -> [S[] -> a[]] : 4 <= i <= 9 }" +must_no_source: "{ }" +may_no_source: "{ }" diff --git a/external/mit/isl/dist/test_inputs/flow/kill_may_loop2-tree.ai b/external/mit/isl/dist/test_inputs/flow/kill_may_loop2-tree.ai new file mode 100644 index 000000000000..fb5d88fa43e6 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/flow/kill_may_loop2-tree.ai @@ -0,0 +1,11 @@ +sink: "{ S[] -> a[] }" +may_source: "{ T[i] -> a[] : 0 <= i <= 9 }" +kill: "{ T[9] -> a[] }" +schedule: + domain: "{ T[i]; S[] }" + child: + sequence: + - filter: "{ T[i] }" + child: + schedule: "[{ T[i] -> [(i)] }]" + - filter: "{ S[] }" diff --git a/external/mit/isl/dist/test_inputs/flow/kill_may_loop2-tree.flow b/external/mit/isl/dist/test_inputs/flow/kill_may_loop2-tree.flow new file mode 100644 index 000000000000..51d2e2aa5bf4 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/flow/kill_may_loop2-tree.flow @@ -0,0 +1,4 @@ +must_dependence: "{ }" +may_dependence: "{ T[i = 9] -> [S[] -> a[]] }" +must_no_source: "{ }" +may_no_source: "{ }" diff --git a/external/mit/isl/dist/test_inputs/flow/kill_may_loop2.ai b/external/mit/isl/dist/test_inputs/flow/kill_may_loop2.ai new file mode 100644 index 000000000000..09aaf70a76a2 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/flow/kill_may_loop2.ai @@ -0,0 +1,4 @@ +sink: { S[] -> a[] } +may_source: { T[i] -> a[] : 0 <= i < 10 } +kill: { T[9] -> a[] } +schedule_map: { T[i] -> [0,i]; S[] -> [1,0] } diff --git a/external/mit/isl/dist/test_inputs/flow/kill_may_loop2.flow b/external/mit/isl/dist/test_inputs/flow/kill_may_loop2.flow new file mode 100644 index 000000000000..51d2e2aa5bf4 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/flow/kill_may_loop2.flow @@ -0,0 +1,4 @@ +must_dependence: "{ }" +may_dependence: "{ T[i = 9] -> [S[] -> a[]] }" +must_no_source: "{ }" +may_no_source: "{ }" diff --git a/external/mit/isl/dist/test_inputs/flow/kill_may_loop3-tree.ai b/external/mit/isl/dist/test_inputs/flow/kill_may_loop3-tree.ai new file mode 100644 index 000000000000..809769566ead --- /dev/null +++ b/external/mit/isl/dist/test_inputs/flow/kill_may_loop3-tree.ai @@ -0,0 +1,11 @@ +sink: "{ S[] -> a[] }" +may_source: "{ T[i] -> a[] : 0 <= i <= 9 }" +kill: "{ K[] -> a[] }" +schedule: + domain: "{ T[i]; S[]; K[] }" + child: + sequence: + - filter: "{ T[i]; K[] }" + child: + schedule: "[{ T[i] -> [(i)]; K[] -> [(4)] }]" + - filter: "{ S[] }" diff --git a/external/mit/isl/dist/test_inputs/flow/kill_may_loop3-tree.flow b/external/mit/isl/dist/test_inputs/flow/kill_may_loop3-tree.flow new file mode 100644 index 000000000000..7a89b0dca4dc --- /dev/null +++ b/external/mit/isl/dist/test_inputs/flow/kill_may_loop3-tree.flow @@ -0,0 +1,4 @@ +must_dependence: "{ }" +may_dependence: "{ T[i] -> [S[] -> a[]] : 4 <= i <= 9 }" +must_no_source: "{ }" +may_no_source: "{ }" diff --git a/external/mit/isl/dist/test_inputs/flow/kill_may_loop3.ai b/external/mit/isl/dist/test_inputs/flow/kill_may_loop3.ai new file mode 100644 index 000000000000..b1d2d6c3f9fc --- /dev/null +++ b/external/mit/isl/dist/test_inputs/flow/kill_may_loop3.ai @@ -0,0 +1,4 @@ +sink: { S[] -> a[] } +may_source: { T[i] -> a[] : 0 <= i < 10 } +kill: { K[] -> a[] } +schedule_map: { T[i] -> [0,i]; K[] -> [0,4]; S[] -> [1,0] } diff --git a/external/mit/isl/dist/test_inputs/flow/kill_may_loop3.flow b/external/mit/isl/dist/test_inputs/flow/kill_may_loop3.flow new file mode 100644 index 000000000000..7a89b0dca4dc --- /dev/null +++ b/external/mit/isl/dist/test_inputs/flow/kill_may_loop3.flow @@ -0,0 +1,4 @@ +must_dependence: "{ }" +may_dependence: "{ T[i] -> [S[] -> a[]] : 4 <= i <= 9 }" +must_no_source: "{ }" +may_no_source: "{ }" diff --git a/external/mit/isl/dist/test_inputs/flow/loop-tree.ai b/external/mit/isl/dist/test_inputs/flow/loop-tree.ai new file mode 100644 index 000000000000..e7fa351fedc7 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/flow/loop-tree.ai @@ -0,0 +1,10 @@ +sink: "{ S[] -> a[] }" +must_source: "{ T[i] -> a[] : 0 <= i <= 9 }" +schedule: + domain: "{ T[i]; S[] }" + child: + sequence: + - filter: "{ T[i] }" + child: + schedule: "[{ T[i] -> [(i)] }]" + - filter: "{ S[] }" diff --git a/external/mit/isl/dist/test_inputs/flow/loop-tree.flow b/external/mit/isl/dist/test_inputs/flow/loop-tree.flow new file mode 100644 index 000000000000..ef089e543db9 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/flow/loop-tree.flow @@ -0,0 +1,4 @@ +must_dependence: "{ T[i = 9] -> [S[] -> a[]] }" +may_dependence: "{ T[i = 9] -> [S[] -> a[]] }" +must_no_source: "{ }" +may_no_source: "{ }" diff --git a/external/mit/isl/dist/test_inputs/flow/loop.ai b/external/mit/isl/dist/test_inputs/flow/loop.ai new file mode 100644 index 000000000000..88c6efaf38be --- /dev/null +++ b/external/mit/isl/dist/test_inputs/flow/loop.ai @@ -0,0 +1,3 @@ +sink: { S[] -> a[] } +must_source: { T[i] -> a[] : 0 <= i < 10 } +schedule_map: { T[i] -> [0,i]; S[] -> [1,0] } diff --git a/external/mit/isl/dist/test_inputs/flow/loop.flow b/external/mit/isl/dist/test_inputs/flow/loop.flow new file mode 100644 index 000000000000..ef089e543db9 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/flow/loop.flow @@ -0,0 +1,4 @@ +must_dependence: "{ T[i = 9] -> [S[] -> a[]] }" +may_dependence: "{ T[i = 9] -> [S[] -> a[]] }" +must_no_source: "{ }" +may_no_source: "{ }" diff --git a/external/mit/isl/dist/test_inputs/flow/may_loop-tree.ai b/external/mit/isl/dist/test_inputs/flow/may_loop-tree.ai new file mode 100644 index 000000000000..de44645d69b8 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/flow/may_loop-tree.ai @@ -0,0 +1,10 @@ +sink: "{ S[] -> a[] }" +may_source: "{ T[i] -> a[] : 0 <= i <= 9 }" +schedule: + domain: "{ T[i]; S[] }" + child: + sequence: + - filter: "{ T[i] }" + child: + schedule: "[{ T[i] -> [(i)] }]" + - filter: "{ S[] }" diff --git a/external/mit/isl/dist/test_inputs/flow/may_loop-tree.flow b/external/mit/isl/dist/test_inputs/flow/may_loop-tree.flow new file mode 100644 index 000000000000..f944ee251bdb --- /dev/null +++ b/external/mit/isl/dist/test_inputs/flow/may_loop-tree.flow @@ -0,0 +1,4 @@ +must_dependence: "{ }" +may_dependence: "{ T[i] -> [S[] -> a[]] : 0 <= i <= 9 }" +must_no_source: "{ }" +may_no_source: "{ S[] -> a[] }" diff --git a/external/mit/isl/dist/test_inputs/flow/may_loop.ai b/external/mit/isl/dist/test_inputs/flow/may_loop.ai new file mode 100644 index 000000000000..0a52ce58dacb --- /dev/null +++ b/external/mit/isl/dist/test_inputs/flow/may_loop.ai @@ -0,0 +1,3 @@ +sink: { S[] -> a[] } +may_source: { T[i] -> a[] : 0 <= i < 10 } +schedule_map: { T[i] -> [0,i]; S[] -> [1,0] } diff --git a/external/mit/isl/dist/test_inputs/flow/may_loop.flow b/external/mit/isl/dist/test_inputs/flow/may_loop.flow new file mode 100644 index 000000000000..f944ee251bdb --- /dev/null +++ b/external/mit/isl/dist/test_inputs/flow/may_loop.flow @@ -0,0 +1,4 @@ +must_dependence: "{ }" +may_dependence: "{ T[i] -> [S[] -> a[]] : 0 <= i <= 9 }" +must_no_source: "{ }" +may_no_source: "{ S[] -> a[] }" diff --git a/external/mit/isl/dist/test_inputs/flow/mixed_loop-tree.ai b/external/mit/isl/dist/test_inputs/flow/mixed_loop-tree.ai new file mode 100644 index 000000000000..960bafb9ca89 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/flow/mixed_loop-tree.ai @@ -0,0 +1,11 @@ +sink: "{ S[] -> a[] }" +must_source: "{ T[i] -> a[] : 2*floor((i)/2) = i and 0 <= i <= 9 }" +may_source: "{ T[i] -> a[] : 2*floor((1 + i)/2) = 1 + i and 0 <= i <= 9 }" +schedule: + domain: "{ T[i]; S[] }" + child: + sequence: + - filter: "{ T[i] }" + child: + schedule: "[{ T[i] -> [(i)] }]" + - filter: "{ S[] }" diff --git a/external/mit/isl/dist/test_inputs/flow/mixed_loop-tree.flow b/external/mit/isl/dist/test_inputs/flow/mixed_loop-tree.flow new file mode 100644 index 000000000000..76033be5c5f0 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/flow/mixed_loop-tree.flow @@ -0,0 +1,4 @@ +must_dependence: "{ }" +may_dependence: "{ T[i = 9] -> [S[] -> a[]]; T[i = 8] -> [S[] -> a[]] }" +must_no_source: "{ }" +may_no_source: "{ }" diff --git a/external/mit/isl/dist/test_inputs/flow/mixed_loop.ai b/external/mit/isl/dist/test_inputs/flow/mixed_loop.ai new file mode 100644 index 000000000000..c79782039d31 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/flow/mixed_loop.ai @@ -0,0 +1,4 @@ +sink: { S[] -> a[] } +must_source: { T[i] -> a[] : 0 <= i < 10 and i mod 2 = 0 } +may_source: { T[i] -> a[] : 0 <= i < 10 and i mod 2 = 1 } +schedule_map: { T[i] -> [0,i]; S[] -> [1,0] } diff --git a/external/mit/isl/dist/test_inputs/flow/mixed_loop.flow b/external/mit/isl/dist/test_inputs/flow/mixed_loop.flow new file mode 100644 index 000000000000..76033be5c5f0 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/flow/mixed_loop.flow @@ -0,0 +1,4 @@ +must_dependence: "{ }" +may_dependence: "{ T[i = 9] -> [S[] -> a[]]; T[i = 8] -> [S[] -> a[]] }" +must_no_source: "{ }" +may_no_source: "{ }" diff --git a/external/mit/isl/dist/test_inputs/flow/multi.ai b/external/mit/isl/dist/test_inputs/flow/multi.ai new file mode 100644 index 000000000000..c76ed66cf2c4 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/flow/multi.ai @@ -0,0 +1,10 @@ +sink: "{ [S_2[] -> __pet_ref_4[]] -> a[] }" +must_source: "{ [S_0[] -> __pet_ref_0[]] -> a[]; [S_2[] -> __pet_ref_3[]] -> b[]; [S_1[] -> __pet_ref_1[]] -> a[]; [S_1[] -> __pet_ref_2[]] -> a[] }" +may_source: "{ [S_1[] -> __pet_ref_2[]] -> a[]; [S_1[] -> __pet_ref_1[]] -> a[]; [S_2[] -> __pet_ref_3[]] -> b[]; [S_0[] -> __pet_ref_0[]] -> a[] }" +schedule: + domain: "{ [S_1[] -> __pet_ref_1[]]; [S_1[] -> __pet_ref_2[]]; [S_2[] -> __pet_ref_3[]]; [S_0[] -> __pet_ref_0[]]; [S_2[] -> __pet_ref_4[]] }" + child: + sequence: + - filter: "{ [S_0[] -> __pet_ref_0[]] }" + - filter: "{ [S_1[] -> __pet_ref_1[]]; [S_1[] -> __pet_ref_2[]] }" + - filter: "{ [S_2[] -> __pet_ref_3[]]; [S_2[] -> __pet_ref_4[]] }" diff --git a/external/mit/isl/dist/test_inputs/flow/multi.flow b/external/mit/isl/dist/test_inputs/flow/multi.flow new file mode 100644 index 000000000000..da6b0a1ce212 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/flow/multi.flow @@ -0,0 +1,4 @@ +must_dependence: "{ }" +may_dependence: "{ [S_1[] -> __pet_ref_2[]] -> [[S_2[] -> __pet_ref_4[]] -> a[]]; [S_1[] -> __pet_ref_1[]] -> [[S_2[] -> __pet_ref_4[]] -> a[]] }" +must_no_source: "{ }" +may_no_source: "{ }" diff --git a/external/mit/isl/dist/test_inputs/flow/multi_source-tree.ai b/external/mit/isl/dist/test_inputs/flow/multi_source-tree.ai new file mode 100644 index 000000000000..cf5826e30816 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/flow/multi_source-tree.ai @@ -0,0 +1,8 @@ +sink: "{ S[] -> a[] }" +must_source: "{ T[] -> a[]; U[] -> a[] }" +schedule: + domain: "{ U[]; S[]; T[] }" + child: + sequence: + - filter: "{ T[]; U[] }" + - filter: "{ S[] }" diff --git a/external/mit/isl/dist/test_inputs/flow/multi_source-tree.flow b/external/mit/isl/dist/test_inputs/flow/multi_source-tree.flow new file mode 100644 index 000000000000..e8f953aaf2b6 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/flow/multi_source-tree.flow @@ -0,0 +1,4 @@ +must_dependence: "{ }" +may_dependence: "{ T[] -> [S[] -> a[]]; U[] -> [S[] -> a[]] }" +must_no_source: "{ }" +may_no_source: "{ }" diff --git a/external/mit/isl/dist/test_inputs/flow/multi_source.ai b/external/mit/isl/dist/test_inputs/flow/multi_source.ai new file mode 100644 index 000000000000..1ce368975cf2 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/flow/multi_source.ai @@ -0,0 +1,3 @@ +sink: { S[] -> a[] } +must_source: { T[] -> a[]; U[] -> a[] } +schedule_map: { T[] -> [0]; U[] -> [0]; S[] -> [1] } diff --git a/external/mit/isl/dist/test_inputs/flow/multi_source.flow b/external/mit/isl/dist/test_inputs/flow/multi_source.flow new file mode 100644 index 000000000000..e8f953aaf2b6 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/flow/multi_source.flow @@ -0,0 +1,4 @@ +must_dependence: "{ }" +may_dependence: "{ T[] -> [S[] -> a[]]; U[] -> [S[] -> a[]] }" +must_no_source: "{ }" +may_no_source: "{ }" diff --git a/external/mit/isl/dist/test_inputs/flow/multi_source2-tree.ai b/external/mit/isl/dist/test_inputs/flow/multi_source2-tree.ai new file mode 100644 index 000000000000..d88d96b1b64b --- /dev/null +++ b/external/mit/isl/dist/test_inputs/flow/multi_source2-tree.ai @@ -0,0 +1,9 @@ +sink: "{ S[] -> a[] }" +must_source: "{ T[] -> a[] }" +may_source: "{ U[] -> a[] }" +schedule: + domain: "{ U[]; S[]; T[] }" + child: + sequence: + - filter: "{ T[]; U[] }" + - filter: "{ S[] }" diff --git a/external/mit/isl/dist/test_inputs/flow/multi_source2-tree.flow b/external/mit/isl/dist/test_inputs/flow/multi_source2-tree.flow new file mode 100644 index 000000000000..e8f953aaf2b6 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/flow/multi_source2-tree.flow @@ -0,0 +1,4 @@ +must_dependence: "{ }" +may_dependence: "{ T[] -> [S[] -> a[]]; U[] -> [S[] -> a[]] }" +must_no_source: "{ }" +may_no_source: "{ }" diff --git a/external/mit/isl/dist/test_inputs/flow/multi_source2.ai b/external/mit/isl/dist/test_inputs/flow/multi_source2.ai new file mode 100644 index 000000000000..ba9f46e47e82 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/flow/multi_source2.ai @@ -0,0 +1,4 @@ +sink: { S[] -> a[] } +must_source: { T[] -> a[] } +may_source: { U[] -> a[] } +schedule_map: { T[] -> [0]; U[] -> [0]; S[] -> [1] } diff --git a/external/mit/isl/dist/test_inputs/flow/multi_source2.flow b/external/mit/isl/dist/test_inputs/flow/multi_source2.flow new file mode 100644 index 000000000000..e8f953aaf2b6 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/flow/multi_source2.flow @@ -0,0 +1,4 @@ +must_dependence: "{ }" +may_dependence: "{ T[] -> [S[] -> a[]]; U[] -> [S[] -> a[]] }" +must_no_source: "{ }" +may_no_source: "{ }" diff --git a/external/mit/isl/dist/test_inputs/flow/multi_source3-tree.ai b/external/mit/isl/dist/test_inputs/flow/multi_source3-tree.ai new file mode 100644 index 000000000000..7cd246579ac3 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/flow/multi_source3-tree.ai @@ -0,0 +1,13 @@ +sink: "{ S[] -> a[] }" +must_source: "{ T[] -> a[]; U[] -> a[] }" +may_source: "{ V[] -> a[] }" +schedule: + domain: "{ S[]; U[]; T[]; V[] }" + child: + sequence: + - filter: "{ U[]; T[]; V[] }" + child: + sequence: + - filter: "{ T[]; U[] }" + - filter: "{ V[] }" + - filter: "{ S[] }" diff --git a/external/mit/isl/dist/test_inputs/flow/multi_source3-tree.flow b/external/mit/isl/dist/test_inputs/flow/multi_source3-tree.flow new file mode 100644 index 000000000000..b037575e6600 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/flow/multi_source3-tree.flow @@ -0,0 +1,4 @@ +must_dependence: "{ }" +may_dependence: "{ T[] -> [S[] -> a[]]; U[] -> [S[] -> a[]]; V[] -> [S[] -> a[]] }" +must_no_source: "{ }" +may_no_source: "{ }" diff --git a/external/mit/isl/dist/test_inputs/flow/multi_source3.ai b/external/mit/isl/dist/test_inputs/flow/multi_source3.ai new file mode 100644 index 000000000000..e2e3d476e6b9 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/flow/multi_source3.ai @@ -0,0 +1,4 @@ +sink: { S[] -> a[] } +must_source: { T[] -> a[]; U[] -> a[] } +may_source: { V[] -> a[] } +schedule_map: { T[] -> [0,0]; U[] -> [0,0]; V[] -> [0,1]; S[] -> [1,0] } diff --git a/external/mit/isl/dist/test_inputs/flow/multi_source3.flow b/external/mit/isl/dist/test_inputs/flow/multi_source3.flow new file mode 100644 index 000000000000..b037575e6600 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/flow/multi_source3.flow @@ -0,0 +1,4 @@ +must_dependence: "{ }" +may_dependence: "{ T[] -> [S[] -> a[]]; U[] -> [S[] -> a[]]; V[] -> [S[] -> a[]] }" +must_no_source: "{ }" +may_no_source: "{ }" diff --git a/external/mit/isl/dist/test_inputs/flow/multi_source4-tree.ai b/external/mit/isl/dist/test_inputs/flow/multi_source4-tree.ai new file mode 100644 index 000000000000..431ac76d29b1 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/flow/multi_source4-tree.ai @@ -0,0 +1,13 @@ +sink: "{ S[] -> a[] }" +must_source: "{ T[] -> a[]; U[] -> a[] }" +may_source: "{ V[] -> a[] }" +schedule: + domain: "{ S[]; U[]; T[]; V[] }" + child: + sequence: + - filter: "{ U[]; T[]; V[] }" + child: + sequence: + - filter: "{ U[] }" + - filter: "{ V[]; T[] }" + - filter: "{ S[] }" diff --git a/external/mit/isl/dist/test_inputs/flow/multi_source4-tree.flow b/external/mit/isl/dist/test_inputs/flow/multi_source4-tree.flow new file mode 100644 index 000000000000..8bf4111f50a2 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/flow/multi_source4-tree.flow @@ -0,0 +1,4 @@ +must_dependence: "{ }" +may_dependence: "{ T[] -> [S[] -> a[]]; V[] -> [S[] -> a[]] }" +must_no_source: "{ }" +may_no_source: "{ }" diff --git a/external/mit/isl/dist/test_inputs/flow/multi_source4.ai b/external/mit/isl/dist/test_inputs/flow/multi_source4.ai new file mode 100644 index 000000000000..8ce0ebe103e2 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/flow/multi_source4.ai @@ -0,0 +1,4 @@ +sink: { S[] -> a[] } +must_source: { T[] -> a[]; U[] -> a[] } +may_source: { V[] -> a[] } +schedule_map: { T[] -> [0,1]; U[] -> [0,0]; V[] -> [0,1]; S[] -> [1,0] } diff --git a/external/mit/isl/dist/test_inputs/flow/multi_source4.flow b/external/mit/isl/dist/test_inputs/flow/multi_source4.flow new file mode 100644 index 000000000000..8bf4111f50a2 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/flow/multi_source4.flow @@ -0,0 +1,4 @@ +must_dependence: "{ }" +may_dependence: "{ T[] -> [S[] -> a[]]; V[] -> [S[] -> a[]] }" +must_no_source: "{ }" +may_no_source: "{ }" diff --git a/external/mit/isl/dist/test_inputs/flow/no_source-tree.ai b/external/mit/isl/dist/test_inputs/flow/no_source-tree.ai new file mode 100644 index 000000000000..e3eea6d911d6 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/flow/no_source-tree.ai @@ -0,0 +1,3 @@ +sink: "{ S[] -> a[] }" +schedule: + domain: "{ S[] }" diff --git a/external/mit/isl/dist/test_inputs/flow/no_source-tree.flow b/external/mit/isl/dist/test_inputs/flow/no_source-tree.flow new file mode 100644 index 000000000000..2ed34cd9c519 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/flow/no_source-tree.flow @@ -0,0 +1,4 @@ +must_dependence: "{ }" +may_dependence: "{ }" +must_no_source: "{ S[] -> a[] }" +may_no_source: "{ S[] -> a[] }" diff --git a/external/mit/isl/dist/test_inputs/flow/no_source.ai b/external/mit/isl/dist/test_inputs/flow/no_source.ai new file mode 100644 index 000000000000..52b07d6880dc --- /dev/null +++ b/external/mit/isl/dist/test_inputs/flow/no_source.ai @@ -0,0 +1,2 @@ +sink: { S[] -> a[] } +schedule_map: { S[] -> [] } diff --git a/external/mit/isl/dist/test_inputs/flow/no_source.flow b/external/mit/isl/dist/test_inputs/flow/no_source.flow new file mode 100644 index 000000000000..2ed34cd9c519 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/flow/no_source.flow @@ -0,0 +1,4 @@ +must_dependence: "{ }" +may_dependence: "{ }" +must_no_source: "{ S[] -> a[] }" +may_no_source: "{ S[] -> a[] }" diff --git a/external/mit/isl/dist/test_inputs/flow/no_source2-tree.ai b/external/mit/isl/dist/test_inputs/flow/no_source2-tree.ai new file mode 100644 index 000000000000..1ef6e5277318 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/flow/no_source2-tree.ai @@ -0,0 +1,8 @@ +sink: "{ S[] -> a[] }" +must_source: "{ T[] -> a[] }" +schedule: + domain: "{ S[]; T[] }" + child: + sequence: + - filter: "{ S[] }" + - filter: "{ T[] }" diff --git a/external/mit/isl/dist/test_inputs/flow/no_source2-tree.flow b/external/mit/isl/dist/test_inputs/flow/no_source2-tree.flow new file mode 100644 index 000000000000..2ed34cd9c519 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/flow/no_source2-tree.flow @@ -0,0 +1,4 @@ +must_dependence: "{ }" +may_dependence: "{ }" +must_no_source: "{ S[] -> a[] }" +may_no_source: "{ S[] -> a[] }" diff --git a/external/mit/isl/dist/test_inputs/flow/no_source2.ai b/external/mit/isl/dist/test_inputs/flow/no_source2.ai new file mode 100644 index 000000000000..b13e79828b0b --- /dev/null +++ b/external/mit/isl/dist/test_inputs/flow/no_source2.ai @@ -0,0 +1,3 @@ +sink: { S[] -> a[] } +must_source: { T[] -> a[] } +schedule_map: { T[] -> [1]; S[] -> [0] } diff --git a/external/mit/isl/dist/test_inputs/flow/no_source2.flow b/external/mit/isl/dist/test_inputs/flow/no_source2.flow new file mode 100644 index 000000000000..2ed34cd9c519 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/flow/no_source2.flow @@ -0,0 +1,4 @@ +must_dependence: "{ }" +may_dependence: "{ }" +must_no_source: "{ S[] -> a[] }" +may_no_source: "{ S[] -> a[] }" diff --git a/external/mit/isl/dist/test_inputs/flow/single_may_source-tree.ai b/external/mit/isl/dist/test_inputs/flow/single_may_source-tree.ai new file mode 100644 index 000000000000..f05980a8790f --- /dev/null +++ b/external/mit/isl/dist/test_inputs/flow/single_may_source-tree.ai @@ -0,0 +1,8 @@ +sink: "{ S[] -> a[] }" +may_source: "{ T[] -> a[] }" +schedule: + domain: "{ S[]; T[] }" + child: + sequence: + - filter: "{ T[] }" + - filter: "{ S[] }" diff --git a/external/mit/isl/dist/test_inputs/flow/single_may_source-tree.flow b/external/mit/isl/dist/test_inputs/flow/single_may_source-tree.flow new file mode 100644 index 000000000000..3034b85d625f --- /dev/null +++ b/external/mit/isl/dist/test_inputs/flow/single_may_source-tree.flow @@ -0,0 +1,4 @@ +must_dependence: "{ }" +may_dependence: "{ T[] -> [S[] -> a[]] }" +must_no_source: "{ }" +may_no_source: "{ S[] -> a[] }" diff --git a/external/mit/isl/dist/test_inputs/flow/single_may_source.ai b/external/mit/isl/dist/test_inputs/flow/single_may_source.ai new file mode 100644 index 000000000000..58d0a7f157ea --- /dev/null +++ b/external/mit/isl/dist/test_inputs/flow/single_may_source.ai @@ -0,0 +1,3 @@ +sink: { S[] -> a[] } +may_source: { T[] -> a[] } +schedule_map: { T[] -> [0]; S[] -> [1] } diff --git a/external/mit/isl/dist/test_inputs/flow/single_may_source.flow b/external/mit/isl/dist/test_inputs/flow/single_may_source.flow new file mode 100644 index 000000000000..3034b85d625f --- /dev/null +++ b/external/mit/isl/dist/test_inputs/flow/single_may_source.flow @@ -0,0 +1,4 @@ +must_dependence: "{ }" +may_dependence: "{ T[] -> [S[] -> a[]] }" +must_no_source: "{ }" +may_no_source: "{ S[] -> a[] }" diff --git a/external/mit/isl/dist/test_inputs/flow/single_source-tree.ai b/external/mit/isl/dist/test_inputs/flow/single_source-tree.ai new file mode 100644 index 000000000000..3af5f2f0d95c --- /dev/null +++ b/external/mit/isl/dist/test_inputs/flow/single_source-tree.ai @@ -0,0 +1,8 @@ +sink: "{ S[] -> a[] }" +must_source: "{ T[] -> a[] }" +schedule: + domain: "{ S[]; T[] }" + child: + sequence: + - filter: "{ T[] }" + - filter: "{ S[] }" diff --git a/external/mit/isl/dist/test_inputs/flow/single_source-tree.flow b/external/mit/isl/dist/test_inputs/flow/single_source-tree.flow new file mode 100644 index 000000000000..e72b8d72e404 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/flow/single_source-tree.flow @@ -0,0 +1,4 @@ +must_dependence: "{ T[] -> [S[] -> a[]] }" +may_dependence: "{ T[] -> [S[] -> a[]] }" +must_no_source: "{ }" +may_no_source: "{ }" diff --git a/external/mit/isl/dist/test_inputs/flow/single_source.ai b/external/mit/isl/dist/test_inputs/flow/single_source.ai new file mode 100644 index 000000000000..0a00e5b0f93f --- /dev/null +++ b/external/mit/isl/dist/test_inputs/flow/single_source.ai @@ -0,0 +1,3 @@ +sink: { S[] -> a[] } +must_source: { T[] -> a[] } +schedule_map: { T[] -> [0]; S[] -> [1] } diff --git a/external/mit/isl/dist/test_inputs/flow/single_source.flow b/external/mit/isl/dist/test_inputs/flow/single_source.flow new file mode 100644 index 000000000000..e72b8d72e404 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/flow/single_source.flow @@ -0,0 +1,4 @@ +must_dependence: "{ T[] -> [S[] -> a[]] }" +may_dependence: "{ T[] -> [S[] -> a[]] }" +must_no_source: "{ }" +may_no_source: "{ }" diff --git a/external/mit/isl/dist/test_inputs/linearExample.pwqp b/external/mit/isl/dist/test_inputs/linearExample.pwqp new file mode 100644 index 000000000000..24c53946a0b8 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/linearExample.pwqp @@ -0,0 +1 @@ +[N, M, L] -> { [i, j, k] -> ((1/2 * i + 5 * j) + 1/7 * k) : i >= 0 and k >= -N + i and k >= -M - j and j <= L + i and L >= 0 and L >= -M } diff --git a/external/mit/isl/dist/test_inputs/max.pip b/external/mit/isl/dist/test_inputs/max.pip new file mode 100644 index 000000000000..e8af57b9f518 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/max.pip @@ -0,0 +1,9 @@ +0 3 + +-1 + +4 5 +1 -1 0 1 0 +1 0 -1 1 0 +1 -1 3 -2 12 +1 2 -1 -1 3 diff --git a/external/mit/isl/dist/test_inputs/neg.pwqp b/external/mit/isl/dist/test_inputs/neg.pwqp new file mode 100644 index 000000000000..596a7d77d091 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/neg.pwqp @@ -0,0 +1 @@ +[n] -> { [i0] -> i0^2 : i0 >= -20 - n and i0 <= n and i0 <= -1 and n >= 0 } diff --git a/external/mit/isl/dist/test_inputs/negative.pip b/external/mit/isl/dist/test_inputs/negative.pip new file mode 100644 index 000000000000..45090a59230f --- /dev/null +++ b/external/mit/isl/dist/test_inputs/negative.pip @@ -0,0 +1,9 @@ +1 3 +# n 1 +1 1 -1 # n >= 1 +-1 + +2 4 +# i n 1 +1 1 0 1 # i >= -1 +1 -1 1 0 # i <= n diff --git a/external/mit/isl/dist/test_inputs/philippe.pwqp b/external/mit/isl/dist/test_inputs/philippe.pwqp new file mode 100644 index 000000000000..1c56e7af7077 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/philippe.pwqp @@ -0,0 +1 @@ +[N] -> { [i, j] -> ((1/2 * i + 1/2 * i^2) + j) : i <= N and j >= 0 and j <= i } diff --git a/external/mit/isl/dist/test_inputs/philippe3vars.pwqp b/external/mit/isl/dist/test_inputs/philippe3vars.pwqp new file mode 100644 index 000000000000..8d074962578d --- /dev/null +++ b/external/mit/isl/dist/test_inputs/philippe3vars.pwqp @@ -0,0 +1 @@ +[N] -> { [i, j, k] -> (((1/2 * i + 1/2 * i^2) + j) + k^3) : i >= 0 and k >= -N + i and k >= -j and j <= i } diff --git a/external/mit/isl/dist/test_inputs/philippe3vars3pars.pwqp b/external/mit/isl/dist/test_inputs/philippe3vars3pars.pwqp new file mode 100644 index 000000000000..f81b8cc5a68f --- /dev/null +++ b/external/mit/isl/dist/test_inputs/philippe3vars3pars.pwqp @@ -0,0 +1 @@ +[N, M, L] -> { [i, j, k] -> (((1/2 * i + 1/2 * i^2) + j) + k^3) : i >= 0 and k >= -N + i and k >= -M - j and j <= L + i and L >= 0 and L >= -M } diff --git a/external/mit/isl/dist/test_inputs/philippeNeg.pwqp b/external/mit/isl/dist/test_inputs/philippeNeg.pwqp new file mode 100644 index 000000000000..24dc805ed18a --- /dev/null +++ b/external/mit/isl/dist/test_inputs/philippeNeg.pwqp @@ -0,0 +1 @@ +[N] -> { [i, j] -> ((1/2 * i + 1/2 * i^2) + j) : i <= N and j >= -1 and j <= i } diff --git a/external/mit/isl/dist/test_inputs/philippePolynomialCoeff.pwqp b/external/mit/isl/dist/test_inputs/philippePolynomialCoeff.pwqp new file mode 100644 index 000000000000..e6327c78f355 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/philippePolynomialCoeff.pwqp @@ -0,0 +1 @@ +[N, M] -> { [i, j] -> ((N * i + (1/5 * N + N^2) * i^2) + 5 * j) : i <= N and j >= 0 and j <= i and M >= 0 } diff --git a/external/mit/isl/dist/test_inputs/philippePolynomialCoeff1P.pwqp b/external/mit/isl/dist/test_inputs/philippePolynomialCoeff1P.pwqp new file mode 100644 index 000000000000..ae01d2fcb874 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/philippePolynomialCoeff1P.pwqp @@ -0,0 +1 @@ +[N] -> { [i, j] -> ((N * i + (1/5 * N + N^2) * i^2) + 5 * j) : i <= N and j >= 0 and j <= i } diff --git a/external/mit/isl/dist/test_inputs/product.pwqp b/external/mit/isl/dist/test_inputs/product.pwqp new file mode 100644 index 000000000000..ee48b859ee3a --- /dev/null +++ b/external/mit/isl/dist/test_inputs/product.pwqp @@ -0,0 +1 @@ +[N] -> { [i0, i1, i2] -> (i0^3 * i1^2 + N * i1 * i2) : i0 >= 0 and i0 <= N and i1 >= 0 and i1 <= N and i2 >= 0 and i2 <= N } diff --git a/external/mit/isl/dist/test_inputs/schedule/bounded_coefficients.sc b/external/mit/isl/dist/test_inputs/schedule/bounded_coefficients.sc new file mode 100644 index 000000000000..dd839e97d826 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/schedule/bounded_coefficients.sc @@ -0,0 +1,12 @@ +# Check that the bounds on the coefficients are respected. +# This function checks for a particular output schedule, +# but the exact output is not important, only that it does +# not contain any coefficients greater than 4. +# It is, however, easier to check for a particular output. +# This test uses the whole component scheduler +# because the incremental scheduler has no reason to fuse anything. +# OPTIONS: --schedule-whole-component --schedule-max-coefficient=4 --schedule-max-constant-term=10 +domain: { S_4[i, j, k] : 0 <= i < j <= 10 and 0 <= k <= 100; + S_2[i, j] : 0 <= i < j <= 10; S_6[i, j] : 0 <= i < j <= 10 } +validity: { S_2[0, j] -> S_4[0, j, 0] : 0 < j <= 10; + S_4[0, j, 100] -> S_6[0, j] : 0 < j <= 10 } diff --git a/external/mit/isl/dist/test_inputs/schedule/bounded_coefficients.st b/external/mit/isl/dist/test_inputs/schedule/bounded_coefficients.st new file mode 100644 index 000000000000..6ce339c1bc31 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/schedule/bounded_coefficients.st @@ -0,0 +1,5 @@ +domain: "{ S_6[i, j] : i >= 0 and i < j <= 10; S_4[i, j, k] : i >= 0 and i < j <= 10 and 0 <= k <= 100; S_2[i, j] : i >= 0 and i < j <= 10 }" +child: + schedule: "[{ S_6[i, j] -> [(0)]; S_4[i, j, k] -> [(i)]; S_2[i, j] -> [(0)] }, { S_6[i, j] -> [(10 + i)]; S_4[i, j, k] -> [(j)]; S_2[i, j] -> [(i)] }, { S_6[i, j] -> [(j)]; S_4[i, j, k] -> [(10 - k)]; S_2[i, j] -> [(j)] }]" + permutable: 1 + coincident: [ 1, 1, 1 ] diff --git a/external/mit/isl/dist/test_inputs/schedule/carry_bounded_coefficients.sc b/external/mit/isl/dist/test_inputs/schedule/carry_bounded_coefficients.sc new file mode 100644 index 000000000000..70037c0f5b19 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/schedule/carry_bounded_coefficients.sc @@ -0,0 +1,19 @@ +# Check that the dependence carrying step is not confused by +# a bound on the coefficient size. +# In particular, force the scheduler to move to a dependence carrying +# step by demanding outer coincidence and bound the size of +# the coefficients. Earlier versions of isl would take this +# bound into account while carrying dependences, breaking +# fundamental assumptions. +# On the other hand, the dependence carrying step now tries +# to prevent loop coalescing by default, so check that indeed +# no loop coalescing occurs by comparing the computed schedule +# to the expected non-coalescing schedule. +# OPTIONS: --schedule-outer-coincidence --schedule-max-coefficient=20 +domain: { C[i0, i1] : 2 <= i0 <= 3999 and 0 <= i1 <= -1 + i0 } +validity: { C[i0, i1] -> C[i0, 1 + i1] : i0 <= 3999 and i1 >= 0 and + i1 <= -2 + i0; + C[i0, -1 + i0] -> C[1 + i0, 0] : i0 <= 3998 and i0 >= 1 } +coincidence: { C[i0, i1] -> C[i0, 1 + i1] : i0 <= 3999 and i1 >= 0 and + i1 <= -2 + i0; + C[i0, -1 + i0] -> C[1 + i0, 0] : i0 <= 3998 and i0 >= 1 } diff --git a/external/mit/isl/dist/test_inputs/schedule/carry_bounded_coefficients.st b/external/mit/isl/dist/test_inputs/schedule/carry_bounded_coefficients.st new file mode 100644 index 000000000000..cdcf12c43157 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/schedule/carry_bounded_coefficients.st @@ -0,0 +1,5 @@ +domain: "{ C[i0, i1] : 2 <= i0 <= 3999 and 0 <= i1 < i0 }" +child: + schedule: "[{ C[i0, i1] -> [(i0)] }]" + child: + schedule: "[{ C[i0, i1] -> [(i1)] }]" diff --git a/external/mit/isl/dist/test_inputs/schedule/disjunctive_domain.sc b/external/mit/isl/dist/test_inputs/schedule/disjunctive_domain.sc new file mode 100644 index 000000000000..47eedb24cbd0 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/schedule/disjunctive_domain.sc @@ -0,0 +1,4 @@ +# Check that the size computation used for loop coalescing avoidance +# does not get confused by disjunctive domains. +domain: [N] -> { S_9[k, i, j = k] : 0 < k <= -3 + N and k < i < N; S_9[k, k, j] : 0 < k <= -3 + N and k <= j < N; S_9[-2 + N, i, j] : N >= 3 and -2 + N <= i < N and -2 + N <= j < N } +validity: [N] -> { S_9[k, 1 + N, j] -> S_9[1 + k, -1 + N, j'] : 0 < k <= -3 + N and j < N and j' > k and -1 + j <= j' <= j; S_9[-2 + N, i, -2 + N] -> S_9[-2 + N, i, -1 + N] : N >= 3 and -2 + N <= i < N} diff --git a/external/mit/isl/dist/test_inputs/schedule/disjunctive_domain.st b/external/mit/isl/dist/test_inputs/schedule/disjunctive_domain.st new file mode 100644 index 000000000000..05d0b89c7d0e --- /dev/null +++ b/external/mit/isl/dist/test_inputs/schedule/disjunctive_domain.st @@ -0,0 +1,5 @@ +domain: "[N] -> { S_9[k, i, j = k] : 0 < k <= -3 + N and k < i < N; S_9[k, i = k, j] : 0 < k <= -3 + N and k <= j < N; S_9[k = -2 + N, i, j] : N >= 3 and -2 + N <= i < N and -2 + N <= j < N }" +child: + schedule: "[N] -> [{ S_9[k, i, j] -> [(k)] }, { S_9[k, i, j] -> [(2k + i)] }, { S_9[k, i, j] -> [(k + j)] }]" + permutable: 1 + coincident: [ 1, 1, 1 ] diff --git a/external/mit/isl/dist/test_inputs/schedule/feautrier_compressed.sc b/external/mit/isl/dist/test_inputs/schedule/feautrier_compressed.sc new file mode 100644 index 000000000000..f90bd883d77a --- /dev/null +++ b/external/mit/isl/dist/test_inputs/schedule/feautrier_compressed.sc @@ -0,0 +1,5 @@ +# Check that the Feautrier schedule is not confused by +# compressed nodes in a subgraph of the original dependence graph. +# OPTIONS: --schedule-algorithm=feautrier +domain: { A[]; B[0]; C[] } +validity: { A[] -> B[0] } diff --git a/external/mit/isl/dist/test_inputs/schedule/feautrier_compressed.st b/external/mit/isl/dist/test_inputs/schedule/feautrier_compressed.st new file mode 100644 index 000000000000..fb2a4257cd24 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/schedule/feautrier_compressed.st @@ -0,0 +1,7 @@ +domain: "{ B[0]; C[]; A[] }" +child: + set: + - filter: "{ B[i0]; A[] }" + child: + schedule: "[{ B[i0] -> [(1)]; A[] -> [(0)] }]" + - filter: "{ C[] }" diff --git a/external/mit/isl/dist/test_inputs/schedule/flat1.sc b/external/mit/isl/dist/test_inputs/schedule/flat1.sc new file mode 100644 index 000000000000..f3cb57f1f68a --- /dev/null +++ b/external/mit/isl/dist/test_inputs/schedule/flat1.sc @@ -0,0 +1,3 @@ +# Check that a fixed value of one dimension in terms of the others +# does not cause loop coalescing avoidance to break down. +domain: [M] -> { S[a, b] : 0 <= a <= 99 and M <= 2b <= 1 + M } diff --git a/external/mit/isl/dist/test_inputs/schedule/flat1.st b/external/mit/isl/dist/test_inputs/schedule/flat1.st new file mode 100644 index 000000000000..6b0b54f263c9 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/schedule/flat1.st @@ -0,0 +1,5 @@ +domain: "[M] -> { S[a, b] : 0 <= a <= 99 and M <= 2b <= 1 + M }" +child: + schedule: "[M] -> [{ S[a, b] -> [(a)] }]" + permutable: 1 + coincident: [ 1 ] diff --git a/external/mit/isl/dist/test_inputs/schedule/flat2.sc b/external/mit/isl/dist/test_inputs/schedule/flat2.sc new file mode 100644 index 000000000000..bf5042cfb4e2 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/schedule/flat2.sc @@ -0,0 +1,3 @@ +# Check that a fixed value of one dimension in terms of the others +# does not cause loop coalescing avoidance to break down. +domain: { S[a, floor(a/2)] : 0 <= a <= 9 } diff --git a/external/mit/isl/dist/test_inputs/schedule/flat2.st b/external/mit/isl/dist/test_inputs/schedule/flat2.st new file mode 100644 index 000000000000..83f0838d44a4 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/schedule/flat2.st @@ -0,0 +1,5 @@ +domain: "{ S[a, i1] : 0 <= a <= 9 and -1 + a <= 2i1 <= a }" +child: + schedule: "[{ S[a, i1] -> [(a)] }]" + permutable: 1 + coincident: [ 1 ] diff --git a/external/mit/isl/dist/test_inputs/schedule/flat3.sc b/external/mit/isl/dist/test_inputs/schedule/flat3.sc new file mode 100644 index 000000000000..86e296ef7863 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/schedule/flat3.sc @@ -0,0 +1,3 @@ +# Check that a fixed value of one dimension in terms of the others +# does not cause loop coalescing avoidance to break down. +domain: { S[a, floor(a/2), floor(a/4)] : 0 <= a <= 9 } diff --git a/external/mit/isl/dist/test_inputs/schedule/flat3.st b/external/mit/isl/dist/test_inputs/schedule/flat3.st new file mode 100644 index 000000000000..eea2ea4dc017 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/schedule/flat3.st @@ -0,0 +1,5 @@ +domain: "{ S[a, i1, i2] : 0 <= a <= 9 and -1 + a <= 2i1 <= a and -3 + a <= 4i2 <= a }" +child: + schedule: "[{ S[a, i1, i2] -> [(a)] }]" + permutable: 1 + coincident: [ 1 ] diff --git a/external/mit/isl/dist/test_inputs/schedule/flat4.sc b/external/mit/isl/dist/test_inputs/schedule/flat4.sc new file mode 100644 index 000000000000..3c094b06b4e2 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/schedule/flat4.sc @@ -0,0 +1,3 @@ +# Check that a fixed value of one dimension in terms of the others +# does not cause loop coalescing avoidance to break down. +domain: { S[0, a, floor(a/2), floor(a/4)] : 0 <= a <= 9 } diff --git a/external/mit/isl/dist/test_inputs/schedule/flat4.st b/external/mit/isl/dist/test_inputs/schedule/flat4.st new file mode 100644 index 000000000000..bef33ca20058 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/schedule/flat4.st @@ -0,0 +1,5 @@ +domain: "{ S[0, a, i2, i3] : 0 <= a <= 9 and -1 + a <= 2i2 <= a and -3 + a <= 4i3 <= a }" +child: + schedule: "[{ S[i0, a, i2, i3] -> [(a)] }]" + permutable: 1 + coincident: [ 1 ] diff --git a/external/mit/isl/dist/test_inputs/schedule/flat5.sc b/external/mit/isl/dist/test_inputs/schedule/flat5.sc new file mode 100644 index 000000000000..fdee69a46d72 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/schedule/flat5.sc @@ -0,0 +1,3 @@ +# Check that a fixed value of one dimension in terms of the others +# does not cause loop coalescing avoidance to break down. +domain: { S[a, b] : b >= 0 and a -10b >= 0 and -a + b + 9 >= 0 } diff --git a/external/mit/isl/dist/test_inputs/schedule/flat5.st b/external/mit/isl/dist/test_inputs/schedule/flat5.st new file mode 100644 index 000000000000..de01551c3ed1 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/schedule/flat5.st @@ -0,0 +1,5 @@ +domain: "{ S[a, b] : b >= -9 + a and b >= 0 and 10b <= a }" +child: + schedule: "[{ S[a, b] -> [(a)] }]" + permutable: 1 + coincident: [ 1 ] diff --git a/external/mit/isl/dist/test_inputs/schedule/flat6.sc b/external/mit/isl/dist/test_inputs/schedule/flat6.sc new file mode 100644 index 000000000000..c78919c7f02a --- /dev/null +++ b/external/mit/isl/dist/test_inputs/schedule/flat6.sc @@ -0,0 +1,3 @@ +# Check that a fixed value of one dimension in terms of the others +# does not cause loop coalescing avoidance to break down. +domain: { S[a, b] : -b >= 0 and a + 10b >= 0 and -a - b + 9 >= 0 } diff --git a/external/mit/isl/dist/test_inputs/schedule/flat6.st b/external/mit/isl/dist/test_inputs/schedule/flat6.st new file mode 100644 index 000000000000..9ee10273ca6b --- /dev/null +++ b/external/mit/isl/dist/test_inputs/schedule/flat6.st @@ -0,0 +1,5 @@ +domain: "{ S[a, b] : b <= 9 - a and b <= 0 and 10b >= -a }" +child: + schedule: "[{ S[a, b] -> [(a)] }]" + permutable: 1 + coincident: [ 1 ] diff --git a/external/mit/isl/dist/test_inputs/schedule/fork1.sc b/external/mit/isl/dist/test_inputs/schedule/fork1.sc new file mode 100644 index 000000000000..8ae3240c93b2 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/schedule/fork1.sc @@ -0,0 +1,5 @@ +# Check the decomposition of the topological sort. +# This decomposition is only performed by the incremental scheduler. +# OPTIONS: --no-schedule-whole-component +domain: { A[]; B[]; C[] } +validity: { A[] -> C[]; B[] -> C[] } diff --git a/external/mit/isl/dist/test_inputs/schedule/fork1.st b/external/mit/isl/dist/test_inputs/schedule/fork1.st new file mode 100644 index 000000000000..00f0b7462b58 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/schedule/fork1.st @@ -0,0 +1,9 @@ +domain: "{ B[]; C[]; A[] }" +child: + sequence: + - filter: "{ B[]; A[] }" + child: + set: + - filter: "{ A[] }" + - filter: "{ B[] }" + - filter: "{ C[] }" diff --git a/external/mit/isl/dist/test_inputs/schedule/fork2.sc b/external/mit/isl/dist/test_inputs/schedule/fork2.sc new file mode 100644 index 000000000000..2c7d8d02a3f8 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/schedule/fork2.sc @@ -0,0 +1,5 @@ +# Check the decomposition of the topological sort. +# This decomposition is only performed by the incremental scheduler. +# OPTIONS: --no-schedule-whole-component +domain: { A[]; B[]; C[] } +validity: { A[] -> B[]; B[] -> C[] } diff --git a/external/mit/isl/dist/test_inputs/schedule/fork2.st b/external/mit/isl/dist/test_inputs/schedule/fork2.st new file mode 100644 index 000000000000..884fa8ce3209 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/schedule/fork2.st @@ -0,0 +1,6 @@ +domain: "{ C[]; A[]; B[] }" +child: + sequence: + - filter: "{ A[] }" + - filter: "{ B[] }" + - filter: "{ C[] }" diff --git a/external/mit/isl/dist/test_inputs/schedule/fork3.sc b/external/mit/isl/dist/test_inputs/schedule/fork3.sc new file mode 100644 index 000000000000..5d164584e599 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/schedule/fork3.sc @@ -0,0 +1,7 @@ +# Check the decomposition of the topological sort. +# This decomposition is only performed by the incremental scheduler. +# OPTIONS: --no-schedule-whole-component +domain: { A[]; B[]; C[]; D[]; E[]; F[]; G[] } +validity: + { A[] -> C[]; B[] -> C[]; C[] -> E[]; D[] -> E[]; E[] -> F[]; E[] -> G[]; + A[] -> G[]; B[] -> E[] } diff --git a/external/mit/isl/dist/test_inputs/schedule/fork3.st b/external/mit/isl/dist/test_inputs/schedule/fork3.st new file mode 100644 index 000000000000..784e07bf5872 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/schedule/fork3.st @@ -0,0 +1,22 @@ +domain: "{ E[]; G[]; F[]; D[]; B[]; C[]; A[] }" +child: + sequence: + - filter: "{ D[]; B[]; C[]; A[] }" + child: + set: + - filter: "{ B[]; C[]; A[] }" + child: + sequence: + - filter: "{ B[]; A[] }" + child: + set: + - filter: "{ A[] }" + - filter: "{ B[] }" + - filter: "{ C[] }" + - filter: "{ D[] }" + - filter: "{ E[] }" + - filter: "{ G[]; F[] }" + child: + set: + - filter: "{ F[] }" + - filter: "{ G[] }" diff --git a/external/mit/isl/dist/test_inputs/schedule/leyin1.sc b/external/mit/isl/dist/test_inputs/schedule/leyin1.sc new file mode 100644 index 000000000000..ba5ec5760e93 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/schedule/leyin1.sc @@ -0,0 +1,5 @@ +# This is a specialized version of leyin2?.sc (for N = 32), +# showing that a single band is computed. +domain: { A[]; B[0:31]; C[] } +validity: { A[] -> B[0]; B[31] -> C[] } +proximity: { A[] -> B[0]; B[31] -> C[] } diff --git a/external/mit/isl/dist/test_inputs/schedule/leyin1.st b/external/mit/isl/dist/test_inputs/schedule/leyin1.st new file mode 100644 index 000000000000..84a8991fa3a0 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/schedule/leyin1.st @@ -0,0 +1,10 @@ +domain: "{ B[i0] : 0 <= i0 <= 31; C[]; A[] }" +child: + schedule: "[{ B[i0] -> [(i0)]; C[] -> [(31)]; A[] -> [(0)] }]" + permutable: 1 + coincident: [ 1 ] + child: + sequence: + - filter: "{ A[] }" + - filter: "{ B[i0] }" + - filter: "{ C[] }" diff --git a/external/mit/isl/dist/test_inputs/schedule/leyin2a.sc b/external/mit/isl/dist/test_inputs/schedule/leyin2a.sc new file mode 100644 index 000000000000..6e43b589bb46 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/schedule/leyin2a.sc @@ -0,0 +1,14 @@ +# This is a generalized version of leyin1.sc, +# with an extra dependence that simplifies away when N = 32. +# However, since N is known to be non-negative, this should still +# produce a similar schedule (with a single band). +# The exact form of the schedule depends on whether the whole-component or +# the incremental scheduler is used. +# This is the incremental scheduler version. +# OPTIONS: --no-schedule-whole-component +domain: [N] -> { A[]; B[0:N-1]; C[] } +context: [N] -> { : N >= 0 } +validity: [N] -> { A[] -> C[] : N <= 0; + A[] -> B[0] : N >= 1; B[N-1] -> C[] : N >= 1 } +proximity: [N] -> { A[] -> C[] : N <= 0; + A[] -> B[0] : N >= 1; B[N-1] -> C[] : N >= 1 } diff --git a/external/mit/isl/dist/test_inputs/schedule/leyin2a.st b/external/mit/isl/dist/test_inputs/schedule/leyin2a.st new file mode 100644 index 000000000000..1eb05c91efe2 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/schedule/leyin2a.st @@ -0,0 +1,13 @@ +domain: "[N] -> { B[i0] : 0 <= i0 < N; C[]; A[] }" +child: + schedule: "[N] -> [{ B[i0] -> [(1 + i0)]; C[] -> [(N)]; A[] -> [(0)] }]" + permutable: 1 + coincident: [ 1 ] + child: + sequence: + - filter: "[N] -> { A[]; B[i0] }" + child: + set: + - filter: "[N] -> { A[] }" + - filter: "[N] -> { B[i0] }" + - filter: "[N] -> { C[] }" diff --git a/external/mit/isl/dist/test_inputs/schedule/leyin2b.sc b/external/mit/isl/dist/test_inputs/schedule/leyin2b.sc new file mode 100644 index 000000000000..9f98d440b7a7 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/schedule/leyin2b.sc @@ -0,0 +1,14 @@ +# This is a generalized version of leyin1.sc, +# with an extra dependence that simplifies away when N = 32. +# However, since N is known to be non-negative, this should still +# produce a similar schedule (with a single band). +# The exact form of the schedule depends on whether the whole-component or +# the incremental scheduler is used. +# This is the whole-component scheduler version. +# OPTIONS: --schedule-whole-component +domain: [N] -> { A[]; B[0:N-1]; C[] } +context: [N] -> { : N >= 0 } +validity: [N] -> { A[] -> C[] : N <= 0; + A[] -> B[0] : N >= 1; B[N-1] -> C[] : N >= 1 } +proximity: [N] -> { A[] -> C[] : N <= 0; + A[] -> B[0] : N >= 1; B[N-1] -> C[] : N >= 1 } diff --git a/external/mit/isl/dist/test_inputs/schedule/leyin2b.st b/external/mit/isl/dist/test_inputs/schedule/leyin2b.st new file mode 100644 index 000000000000..826aa0eee1ae --- /dev/null +++ b/external/mit/isl/dist/test_inputs/schedule/leyin2b.st @@ -0,0 +1,10 @@ +domain: "[N] -> { B[i0] : 0 <= i0 < N; C[]; A[] }" +child: + schedule: "[N] -> [{ B[i0] -> [(i0)]; C[] -> [(N)]; A[] -> [(0)] }]" + permutable: 1 + coincident: [ 1 ] + child: + sequence: + - filter: "[N] -> { A[] }" + - filter: "[N] -> { C[] }" + - filter: "[N] -> { B[i0] }" diff --git a/external/mit/isl/dist/test_inputs/schedule/max_coincidence.sc b/external/mit/isl/dist/test_inputs/schedule/max_coincidence.sc new file mode 100644 index 000000000000..cabe9b4e5df3 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/schedule/max_coincidence.sc @@ -0,0 +1,7 @@ +# Check that nodes are not fused when maximizing coincidence. +# This option is only effective for the incremental scheduler. +# OPTIONS: --no-schedule-whole-component --schedule-maximize-coincidence +domain: [n] -> { A[i,j,k] : 0 <= i,j,k < n; B[i,j,k] : 0 <= i,j,k < n } +validity: { A[i,j,k] -> B[i,k,j] } +proximity: { A[i,j,k] -> B[i,k,j] } +coincidence: { A[i,j,k] -> A[i,j,k+1]; B[i,j,k] -> B[i,j,k+1] } diff --git a/external/mit/isl/dist/test_inputs/schedule/max_coincidence.st b/external/mit/isl/dist/test_inputs/schedule/max_coincidence.st new file mode 100644 index 000000000000..2b29baf7a9ab --- /dev/null +++ b/external/mit/isl/dist/test_inputs/schedule/max_coincidence.st @@ -0,0 +1,13 @@ +domain: "[n] -> { A[i, j, k] : 0 <= i < n and 0 <= j < n and 0 <= k < n; B[i, j, k] : 0 <= i < n and 0 <= j < n and 0 <= k < n }" +child: + sequence: + - filter: "[n] -> { A[i, j, k] }" + child: + schedule: "[n] -> [{ A[i, j, k] -> [(i)] }, { A[i, j, k] -> [(j)] }, { A[i, j, k] -> [(k)] }]" + permutable: 1 + coincident: [ 1, 1, 0 ] + - filter: "[n] -> { B[i, j, k] }" + child: + schedule: "[n] -> [{ B[i, j, k] -> [(i)] }, { B[i, j, k] -> [(j)] }, { B[i, j, k] -> [(k)] }]" + permutable: 1 + coincident: [ 1, 1, 0 ] diff --git a/external/mit/isl/dist/test_inputs/schedule/nana.sc b/external/mit/isl/dist/test_inputs/schedule/nana.sc new file mode 100644 index 000000000000..b2ffa29ad754 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/schedule/nana.sc @@ -0,0 +1,9 @@ +# Check the decomposition of the topological sort. +# This decomposition is only performed by the incremental scheduler. +# OPTIONS: --no-schedule-whole-component +# +# This test case was contributed by Nana CK <1429802329@qq.com>. +domain: { sync[0:64, 0:32]; stB[0:64, 0:64]; stC[0:64, 0:64] } +validity: { stC[j = 0:64, 0:64] -> sync[j, 0]; stB[j = 0:64, 0:64] -> sync[j, 0] } +proximity: { stC[j = 0:64, 0:64] -> sync[j, 0]; stB[j = 0:64, 0:64] -> sync[j, 0] } +coincidence: { stC[j = 0:64, 0:64] -> sync[j, 0]; stB[j = 0:64, 0:64] -> sync[j, 0] } diff --git a/external/mit/isl/dist/test_inputs/schedule/nana.st b/external/mit/isl/dist/test_inputs/schedule/nana.st new file mode 100644 index 000000000000..2275dd6d790f --- /dev/null +++ b/external/mit/isl/dist/test_inputs/schedule/nana.st @@ -0,0 +1,13 @@ +domain: "{ sync[i0, i1] : 0 <= i0 <= 64 and 0 <= i1 <= 32; stB[i0, i1] : 0 <= i0 <= 64 and 0 <= i1 <= 64; stC[i0, i1] : 0 <= i0 <= 64 and 0 <= i1 <= 64 }" +child: + schedule: "[{ sync[i0, i1] -> [(i0)]; stB[i0, i1] -> [(i0)]; stC[i0, i1] -> [(i0)] }, { sync[i0, i1] -> [(64 + i1)]; stB[i0, i1] -> [(i1)]; stC[i0, i1] -> [(i1)] }]" + permutable: 1 + coincident: [ 1, 0 ] + child: + sequence: + - filter: "{ stB[i0, i1]; stC[i0, i1] }" + child: + set: + - filter: "{ stC[i0, i1] }" + - filter: "{ stB[i0, i1] }" + - filter: "{ sync[i0, i1] }" diff --git a/external/mit/isl/dist/test_inputs/schedule/niewang.sc b/external/mit/isl/dist/test_inputs/schedule/niewang.sc new file mode 100644 index 000000000000..816cd234c748 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/schedule/niewang.sc @@ -0,0 +1,29 @@ +# In earlier versions of isl, this test case would take an inordinate +# amount of time (in the order of 30s versus 0.1s in later versions) +# due to a call to isl_basic_set_coefficients. +# Check that this no longer happens in the sense that this test case +# would stand out if it were to take that long again. +# The actual schedule that is produced is not that important, +# but it is different depending on whether the whole-component scheduler +# is being used, so pick a particular setting. +# OPTIONS: --no-schedule-whole-component +domain: { S_3[0:223, 0:223, 0:15, 0:3, 0:6, 0:6, 0:15]; group0[0:3, +0:223, 0:223, 0:15] } +validity: { group0[i0 = 0:3, i1 = 0:223, i2 = 0:223, i3 = 0:15] +-> S_3[h = 0:223, w = 0:223, c0 = 0:15, kc1 = i0, kh = 3 + i1 - h, +kw = 3 + i2 - w, kc0 = i3] : -3 + i1 <= h <= 3 + i1 and -3 + i2 <= +w <= 3 + i2; group0[i0 = 0:3, i1 = 0:223, i2 = 0:223, i3 = 0:15] -> +group0[i0, i1, i2, i3] : (i1) mod 2 = 0 and (i2) mod 2 = 0; S_3[h = +0:223, w = 0:223, c0 = 0:15, kc1 = 0:3, kh = 0:6, kw = 0:6, kc0 = 0:14] +-> S_3[h' = h, w' = w, c0' = c0, kc1' = kc1, kh' = kh, kw' = kw, kc0' += 1 + kc0]; S_3[h = 0:223, w = 0:223, c0 = 0:15, kc1 = 0:3, kh = 0:6, +kw = 0:5, kc0 = 15] -> S_3[h' = h, w' = w, c0' = c0, kc1' = kc1, kh' += kh, kw' = 1 + kw, kc0' = 0]; S_3[h = 0:223, w = 0:223, c0 = 0:15, +kc1 = 0:3, kh = 0:5, kw = 6, kc0 = 15] -> S_3[h' = h, w' = w, c0' = +c0, kc1' = kc1, kh' = 1 + kh, kw' = 0, kc0' = 0]; S_3[h = 0:223, w = +0:223, c0 = 0:15, kc1 = 0:2, kh = 6, kw = 6, kc0 = 15] -> S_3[h' = +h, w' = w, c0' = c0, kc1' = 1 + kc1, kh' = 0, kw' = 0, kc0' = 0] } +proximity: { group0[i0 = 0:3, i1 = 0:223, i2 = 0:223, i3 = 0:15] -> +S_3[h = 0:223, w = 0:223, c0 = 0:15, kc1 = i0, kh = 3 + i1 - h, kw = +3 + i2 - w, kc0 = i3] : -3 + i1 <= h <= 3 + i1 and -3 + i2 <= w <= +3 + i2 } diff --git a/external/mit/isl/dist/test_inputs/schedule/niewang.st b/external/mit/isl/dist/test_inputs/schedule/niewang.st new file mode 100644 index 000000000000..741ed9c5de20 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/schedule/niewang.st @@ -0,0 +1,25 @@ +domain: "{ S_3[i0, i1, i2, i3, i4, i5, i6] : 0 <= i0 <= 223 and 0 <= i1 <= 223 and 0 <= i2 <= 15 and 0 <= i3 <= 3 and 0 <= i4 <= 6 and 0 <= i5 <= 6 and 0 <= i6 <= 15; group0[i0, i1, i2, i3] : 0 <= i0 <= 3 and 0 <= i1 <= 223 and 0 <= i2 <= 223 and 0 <= i3 <= 15 }" +child: + sequence: + - filter: "{ group0[i0, i1, i2, i3] }" + child: + schedule: "[{ group0[i0, i1, i2, i3] -> [(i0)] }, { group0[i0, i1, i2, i3] -> [(i1)] }, { group0[i0, i1, i2, i3] -> [(i2)] }, { group0[i0, i1, i2, i3] -> [(i3)] }]" + permutable: 1 + coincident: [ 1, 1, 1, 1 ] + - filter: "{ S_3[i0, i1, i2, i3, i4, i5, i6] }" + child: + schedule: "[{ S_3[i0, i1, i2, i3, i4, i5, i6] -> [(i0)] }, { S_3[i0, i1, i2, i3, i4, i5, i6] -> [(i1)] }, { S_3[i0, i1, i2, i3, i4, i5, i6] -> [(i2)] }, { S_3[i0, i1, i2, i3, i4, i5, i6] -> [(i3)] }]" + permutable: 1 + coincident: [ 1, 1, 1, 1 ] + child: + schedule: "[{ S_3[i0, i1, i2, i3, i4, i5, i6] -> [(i4)] }]" + permutable: 1 + coincident: [ 1 ] + child: + schedule: "[{ S_3[i0, i1, i2, i3, i4, i5, i6] -> [(i5)] }]" + permutable: 1 + coincident: [ 1 ] + child: + schedule: "[{ S_3[i0, i1, i2, i3, i4, i5, i6] -> [(i6)] }]" + permutable: 1 + coincident: [ 1 ] diff --git a/external/mit/isl/dist/test_inputs/schedule/nomax_coincidence.sc b/external/mit/isl/dist/test_inputs/schedule/nomax_coincidence.sc new file mode 100644 index 000000000000..c37ad5ba7ddb --- /dev/null +++ b/external/mit/isl/dist/test_inputs/schedule/nomax_coincidence.sc @@ -0,0 +1,7 @@ +# Check that nodes are fused when not maximizing coincidence. +# This option is only effective for the incremental scheduler. +# OPTIONS: --no-schedule-whole-component --no-schedule-maximize-coincidence +domain: [n] -> { A[i,j,k] : 0 <= i,j,k < n; B[i,j,k] : 0 <= i,j,k < n } +validity: { A[i,j,k] -> B[i,k,j] } +proximity: { A[i,j,k] -> A[i,j,k+1]; A[i,j,k] -> B[i,k,j] } +coincidence: { A[i,j,k] -> A[i,j,k+1]; B[i,j,k] -> B[i,j,k+1] } diff --git a/external/mit/isl/dist/test_inputs/schedule/nomax_coincidence.st b/external/mit/isl/dist/test_inputs/schedule/nomax_coincidence.st new file mode 100644 index 000000000000..3d3af702d52e --- /dev/null +++ b/external/mit/isl/dist/test_inputs/schedule/nomax_coincidence.st @@ -0,0 +1,9 @@ +domain: "[n] -> { A[i, j, k] : 0 <= i < n and 0 <= j < n and 0 <= k < n; B[i, j, k] : 0 <= i < n and 0 <= j < n and 0 <= k < n }" +child: + schedule: "[n] -> [{ A[i, j, k] -> [(i)]; B[i, j, k] -> [(i)] }, { A[i, j, k] -> [(j)]; B[i, j, k] -> [(k)] }, { A[i, j, k] -> [(k)]; B[i, j, k] -> [(j)] }]" + permutable: 1 + coincident: [ 1, 0, 0 ] + child: + sequence: + - filter: "[n] -> { A[i, j, k] }" + - filter: "[n] -> { B[i, j, k] }" diff --git a/external/mit/isl/dist/test_inputs/schedule/poliwoda.sc b/external/mit/isl/dist/test_inputs/schedule/poliwoda.sc new file mode 100644 index 000000000000..cd669fa247d1 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/schedule/poliwoda.sc @@ -0,0 +1,47 @@ +# In earlier versions of isl, this test case would cause +# the loop coalescing avoidance to break down because one of the dimensions +# (Id2 in S_1) has a fixed value in terms of the other dimensions. +# Check that this no longer happens. +# The actual schedule that is produced is not that important, +# but it is different depending on whether the whole-component scheduler +# is being used, so pick a particular setting. +# OPTIONS: --schedule-whole-component +domain: [_PB_M, _PB_N] -> { S_0[Id1, Id2, Id3] : _PB_M >= 2 and Id1 >= +0 and 4Id1 < _PB_N and 2Id2 >= -_PB_M and 4Id2 <= -_PB_M and Id3 <= +0 and 4Id3 >= -3 + _PB_M + 4Id2 and 4Id3 >= -1 - _PB_M; S_1[Id1, Id2, +Id3] : _PB_M >= 2 and Id1 >= 0 and 4Id1 < _PB_N and -_PB_M <= 2Id2 <= +1 - _PB_M and Id3 <= 0 and 4Id3 >= -1 - _PB_M } +validity: [_PB_M, _PB_N] -> { S_0[Id1, Id2, Id3] -> S_0[Id1' = Id1, Id2', +Id3'] : Id1 >= 0 and 4Id1 < _PB_N and Id3 <= 0 and 4Id3 >= -3 + _PB_M + +4Id2 and Id2' <= Id2 and 2Id2' >= -_PB_M and Id3' < 0 and Id3' <= Id3 +and Id3' < Id2 + Id3 - Id2' and 4Id3' >= -4 + _PB_M + 4Id2 and 4Id3' >= +-3 + _PB_M + 3Id2 + Id2' and -1 - _PB_M <= 4Id3' <= 2 + _PB_M + 4Id2; +S_0[Id1, Id2, Id3] -> S_0[Id1' = Id1, Id2', Id3' = Id3] : Id1 >= 0 and +4Id1 < _PB_N and 4Id2 <= -_PB_M and Id3 <= 0 and 4Id3 >= -3 + _PB_M + +4Id2 and Id2' < Id2 and 2Id2' >= -_PB_M; S_0[Id1, Id2, Id3] -> S_1[Id1' += Id1, Id2', Id3'] : Id1 >= 0 and 4Id1 < _PB_N and Id3 <= 0 and 4Id3 >= +-3 + _PB_M + 4Id2 and Id2' < Id2 and -_PB_M <= 2Id2' <= 1 - _PB_M and +Id3' < 0 and Id3' <= Id3 and -4 + _PB_M + 4Id2 <= 4Id3' <= 2 + _PB_M + +4Id2; S_0[Id1, Id2, Id3] -> S_1[Id1' = Id1, Id2' = Id2, Id3'] : Id1 >= +0 and 4Id1 < _PB_N and -_PB_M <= 2Id2 <= 1 - _PB_M and Id3 <= 0 and Id3' +< Id3 and -1 - _PB_M <= 4Id3' <= 2 + _PB_M + 4Id2; S_0[Id1, Id2, Id3] +-> S_1[Id1' = Id1, Id2', Id3' = Id3] : Id1 >= 0 and 4Id1 < _PB_N and +4Id2 <= -_PB_M and Id3 <= 0 and 4Id3 >= -3 + _PB_M + 4Id2 and Id2' < +Id2 and -_PB_M <= 2Id2' <= 1 - _PB_M } +proximity: [_PB_M, _PB_N] -> { S_0[Id1, Id2, Id3] -> S_0[Id1' = Id1, Id2', +Id3'] : Id1 >= 0 and 4Id1 < _PB_N and Id3 <= 0 and 4Id3 >= -3 + _PB_M + +4Id2 and Id2' <= Id2 and 2Id2' >= -_PB_M and Id3' < 0 and Id3' <= Id3 +and Id3' < Id2 + Id3 - Id2' and 4Id3' >= -4 + _PB_M + 4Id2 and 4Id3' >= +-3 + _PB_M + 3Id2 + Id2' and -1 - _PB_M <= 4Id3' <= 2 + _PB_M + 4Id2; +S_0[Id1, Id2, Id3] -> S_0[Id1' = Id1, Id2', Id3' = Id3] : Id1 >= 0 and +4Id1 < _PB_N and 4Id2 <= -_PB_M and Id3 <= 0 and 4Id3 >= -3 + _PB_M + +4Id2 and Id2' < Id2 and 2Id2' >= -_PB_M; S_0[Id1, Id2, Id3] -> S_1[Id1' += Id1, Id2', Id3'] : Id1 >= 0 and 4Id1 < _PB_N and Id3 <= 0 and 4Id3 >= +-3 + _PB_M + 4Id2 and Id2' < Id2 and -_PB_M <= 2Id2' <= 1 - _PB_M and +Id3' < 0 and Id3' <= Id3 and -4 + _PB_M + 4Id2 <= 4Id3' <= 2 + _PB_M + +4Id2; S_0[Id1, Id2, Id3] -> S_1[Id1' = Id1, Id2' = Id2, Id3'] : Id1 >= +0 and 4Id1 < _PB_N and -_PB_M <= 2Id2 <= 1 - _PB_M and Id3 <= 0 and Id3' +< Id3 and -1 - _PB_M <= 4Id3' <= 2 + _PB_M + 4Id2; S_0[Id1, Id2, Id3] +-> S_1[Id1' = Id1, Id2', Id3' = Id3] : Id1 >= 0 and 4Id1 < _PB_N and +4Id2 <= -_PB_M and Id3 <= 0 and 4Id3 >= -3 + _PB_M + 4Id2 and Id2' < +Id2 and -_PB_M <= 2Id2' <= 1 - _PB_M } diff --git a/external/mit/isl/dist/test_inputs/schedule/poliwoda.st b/external/mit/isl/dist/test_inputs/schedule/poliwoda.st new file mode 100644 index 000000000000..d9a07a61e167 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/schedule/poliwoda.st @@ -0,0 +1,5 @@ +domain: "[_PB_M, _PB_N] -> { S_0[Id1, Id2, Id3] : _PB_M >= 2 and Id1 >= 0 and 4Id1 < _PB_N and 2Id2 >= -_PB_M and 4Id2 <= -_PB_M and Id3 <= 0 and 4Id3 >= -3 + _PB_M + 4Id2 and 4Id3 >= -1 - _PB_M; S_1[Id1, Id2, Id3] : _PB_M >= 2 and Id1 >= 0 and 4Id1 < _PB_N and -_PB_M <= 2Id2 <= 1 - _PB_M and Id3 <= 0 and 4Id3 >= -1 - _PB_M }" +child: + schedule: "[_PB_M, _PB_N] -> [{ S_0[Id1, Id2, Id3] -> [(Id1)]; S_1[Id1, Id2, Id3] -> [(Id1)] }, { S_0[Id1, Id2, Id3] -> [(-Id2)]; S_1[Id1, Id2, Id3] -> [(_PB_M)] }, { S_0[Id1, Id2, Id3] -> [(-Id3)]; S_1[Id1, Id2, Id3] -> [(-Id3)] }]" + permutable: 1 + coincident: [ 1, 1, 1 ] diff --git a/external/mit/isl/dist/test_inputs/seghir-vd.pip b/external/mit/isl/dist/test_inputs/seghir-vd.pip new file mode 100644 index 000000000000..b5395fbdb383 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/seghir-vd.pip @@ -0,0 +1,17 @@ +0 6 + +-1 + +9 8 + 0 0 0 1 1 0 0 2 + 1 2 1 0 0 1 0 0 + 1 0 1 0 -1 0 0 -1 + 1 -2 -1 0 0 0 0 -1 + 1 7 3 0 0 0 0 -1 + 1 -6 -4 0 1 0 3 1 + 1 -7 -3 0 0 1 6 4 + 1 0 0 0 0 0 1 0 + 1 0 0 0 0 0 0 1 + +Urs_parms +Urs_unknowns diff --git a/external/mit/isl/dist/test_inputs/set.omega b/external/mit/isl/dist/test_inputs/set.omega new file mode 100644 index 000000000000..ac8485fb9a4e --- /dev/null +++ b/external/mit/isl/dist/test_inputs/set.omega @@ -0,0 +1 @@ +{[y]: Exists ( alpha : 2alpha = y)} diff --git a/external/mit/isl/dist/test_inputs/small.pip b/external/mit/isl/dist/test_inputs/small.pip new file mode 100644 index 000000000000..59557d262bd3 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/small.pip @@ -0,0 +1,9 @@ +0 2 + +-1 + +4 4 +1 1 0 0 +1 0 1 0 +1 1 -3 12 +1 -2 1 3 diff --git a/external/mit/isl/dist/test_inputs/sor1d.pip b/external/mit/isl/dist/test_inputs/sor1d.pip new file mode 100644 index 000000000000..1bef89e5bf1f --- /dev/null +++ b/external/mit/isl/dist/test_inputs/sor1d.pip @@ -0,0 +1,28 @@ +2 4 + 1 1 0 0 + 1 0 1 0 + +-1 + +20 8 + + 0 -1 0 0 0 0 0 2 + 0 0 -1 0 0 0 0 1 + 0 0 0 -1 0 0 0 2 + 0 0 0 0 -1 0 0 4 + 1 0 0 0 1 0 0 -2 + 1 -2 0 2 1 0 0 -4 + 1 0 0 0 -1 0 1 -1 + 1 2 0 -2 -1 0 0 5 + 1 0 0 1 0 0 0 -1 + 1 0 -2 1 0 0 0 0 + 1 -2 0 2 0 0 1 -5 + 1 0 0 -1 0 1 0 0 + 1 0 2 -1 0 0 0 1 + 1 2 0 -2 0 0 0 3 + 1 0 1 0 0 0 0 0 + 1 -2 4 0 0 0 1 -3 + 1 0 -2 0 0 1 0 0 + 1 2 -4 0 0 0 0 3 + 1 2 0 0 0 0 0 1 + 1 -2 0 0 0 2 1 -5 diff --git a/external/mit/isl/dist/test_inputs/split.pwqp b/external/mit/isl/dist/test_inputs/split.pwqp new file mode 100644 index 000000000000..1804563600ce --- /dev/null +++ b/external/mit/isl/dist/test_inputs/split.pwqp @@ -0,0 +1 @@ +[n] -> { [x] -> -1 + [(x+5)/7] : -n - 20 <= x <= n } diff --git a/external/mit/isl/dist/test_inputs/square.pip b/external/mit/isl/dist/test_inputs/square.pip new file mode 100644 index 000000000000..7bb3f0c90b50 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/square.pip @@ -0,0 +1,9 @@ +0 3 + +-1 + +4 5 +1 1 0 0 0 +1 -1 0 1 0 +1 0 1 0 0 +1 0 -1 1 0 diff --git a/external/mit/isl/dist/test_inputs/sven.pip b/external/mit/isl/dist/test_inputs/sven.pip new file mode 100644 index 000000000000..86027691036a --- /dev/null +++ b/external/mit/isl/dist/test_inputs/sven.pip @@ -0,0 +1,7 @@ +0 3 + +-1 + +2 3 +1 1 -4 +1 -1 10 diff --git a/external/mit/isl/dist/test_inputs/test3Deg3Var.pwqp b/external/mit/isl/dist/test_inputs/test3Deg3Var.pwqp new file mode 100644 index 000000000000..d9a9ea9da01d --- /dev/null +++ b/external/mit/isl/dist/test_inputs/test3Deg3Var.pwqp @@ -0,0 +1 @@ +[p] -> { [n, m] -> (n + n^3) : n >= 1 and m >= n and m <= p } diff --git a/external/mit/isl/dist/test_inputs/tobi.pip b/external/mit/isl/dist/test_inputs/tobi.pip new file mode 100644 index 000000000000..c31beae1b0f2 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/tobi.pip @@ -0,0 +1,15 @@ +2 3 +1 1 -281 +1 -1 14000 + +-1 + +6 6 +0 -392 0 8 -1 0 +0 392 8 0 1 0 +1 -1 0 0 0 0 +1 1 0 0 0 35 +1 392 0 0 1 0 +1 -392 0 0 -1 280 + +Urs_unknowns diff --git a/external/mit/isl/dist/test_inputs/toplas.pwqp b/external/mit/isl/dist/test_inputs/toplas.pwqp new file mode 100644 index 000000000000..9c0999540b2e --- /dev/null +++ b/external/mit/isl/dist/test_inputs/toplas.pwqp @@ -0,0 +1 @@ +[n] -> { [i0, i1] -> (((4 * n - n^2) + (-3/2 + 2 * n) * i0 - 1/2 * i0^2) - i1) : i1 >= -1 + 3n - i0 and i1 >= -1 + 2n - i0 and i0 >= 0 and i1 <= -2 + 4n - i0 and i0 <= -2 + 4n and i0 <= -1 + 3n and i1 >= 0 and i1 <= -1 + n } diff --git a/external/mit/isl/dist/test_inputs/unexpanded.pwqp b/external/mit/isl/dist/test_inputs/unexpanded.pwqp new file mode 100644 index 000000000000..5626d3baa418 --- /dev/null +++ b/external/mit/isl/dist/test_inputs/unexpanded.pwqp @@ -0,0 +1 @@ +{ [x, y] -> ((x - x^2) * y + (-x + x^2) * y^2) : x >= 0 and x <= 2 and y >= 0 and y <= 2 } diff --git a/external/mit/isl/dist/uset_from_umap.c b/external/mit/isl/dist/uset_from_umap.c new file mode 100644 index 000000000000..cad606007465 --- /dev/null +++ b/external/mit/isl/dist/uset_from_umap.c @@ -0,0 +1,8 @@ +#include + +/* Return the union set that was treated as the union map "umap". + */ +static __isl_give isl_union_set *uset_from_umap(__isl_take isl_union_map *umap) +{ + return (isl_union_set *) umap; +} diff --git a/external/mit/isl/dist/uset_to_umap.c b/external/mit/isl/dist/uset_to_umap.c new file mode 100644 index 000000000000..68dcd01c9571 --- /dev/null +++ b/external/mit/isl/dist/uset_to_umap.c @@ -0,0 +1,10 @@ +#include + +/* Treat "uset" as a union map. + * Internally, isl_union_set is defined to isl_union_map, so in practice, + * this function performs a redundant cast. + */ +static __isl_give isl_union_map *uset_to_umap(__isl_take isl_union_set *uset) +{ + return (isl_union_map *) uset; +}